[
  {
    "path": ".annotaterb.yml",
    "content": "---\n:position: before\n:position_in_additional_file_patterns: before\n:position_in_class: before\n:position_in_factory: before\n:position_in_fixture: before\n:position_in_routes: before\n:position_in_serializer: before\n:position_in_test: before\n:classified_sort: true\n:exclude_controllers: true\n:exclude_factories: false\n:exclude_fixtures: false\n:exclude_helpers: true\n:exclude_scaffolds: true\n:exclude_serializers: false\n:exclude_sti_subclasses: false\n:exclude_tests: true\n:force: false\n:format_markdown: false\n:format_rdoc: false\n:format_yard: false\n:frozen: false\n:ignore_model_sub_dir: false\n:ignore_unknown_models: false\n:include_version: false\n:show_check_constraints: false\n:show_complete_foreign_keys: false\n:show_foreign_keys: true\n:show_indexes: true\n:simple_indexes: true\n:sort: true\n:timestamp: false\n:trace: false\n:with_comment: true\n:with_column_comments: true\n:with_table_comments: true\n:active_admin: false\n:command:\n:debug: false\n:hide_default_column_types: \"\"\n:hide_limit_column_types: \"\"\n:ignore_columns:\n:ignore_routes:\n:models: true\n:routes: false\n:skip_on_db_migrate: false\n:target_action: :do_annotations\n:wrapper:\n:wrapper_close:\n:wrapper_open:\n:classes_default_to_s: []\n:additional_file_patterns: []\n:model_dir:\n  - app/models\n:require: []\n:root_dir:\n  - \"\"\n"
  },
  {
    "path": ".cursor/commands/plan_commands.md",
    "content": "The user will provide a feature description. Your job is to:\n\n1. Create a technical plan that concisely describes the feature the user wants to build.\n2. Research the files and functions that need to be changed to implement the feature\n3. Avoid any product manager style sections (no success criteria, timeline, migration, etc)\n4. Avoid writing any actual code in the plan.\n5. Include specific and verbatim details from the user's prompt to ensure the plan is accurate.\n\nThis is strictly a technical requirements document that should:\n\n1. Include a brief description to set context at the top\n2. Point to all the relevant files and functions that need to be changed or created\n3. Explain any algorithms that are used step-by-step\n4. If necessary, breaks up the work into logical phases. Ideally this should be done in a way that has an initial \"data layer\" phase that defines the types and db changes that need to run, followed by N phases that can be done in parallel (eg. Phase 2A - routes, Phase 2B - UI, etc). Only include phases if it's a REALLY big feature.\n\nIf the user's requirements are unclear, especially after researching the relevant files, you may ask up to 5 clarifying questions before writing the plan. If you do so, incorporate the user's answers into the plan.\n\nPrioritize being concise and precise. Make the plan as tight as possible without losing any of the critical details from the user's requirements.\n\nWrite the plan into an <N>\\_PLAN.md file with the next available feature number\n"
  },
  {
    "path": ".cursor/rules/cursorrules.mdc",
    "content": "---\nalwaysApply: true\n---\n\n# RubyVideo Rails 8 Project - Cursor Rules\n\nYou are working on RubyVideo, a modern Ruby on Rails 8 application that aggregates and curates Ruby conference videos. This is a sophisticated video platform with AI-powered features, search, analytics, and social features.\n\n## Project Overview\n\n**Tech Stack:**\n\n- Rails 8.0 with SQLite database\n- Frontend: Vite + Tailwind CSS + daisyUI + Stimulus controllers\n- Background Jobs: Solid Queue\n- Caching: Solid Cache\n- Authentication: Custom session-based auth with GitHub OAuth\n- Admin: Avo admin panel\n- Deployment: Kamal on Hetzner VPS\n- Analytics: Ahoy for page tracking\n- AI Features: OpenAI integration for summarization and topic extraction\n\n**Architecture:**\n\n- ViewComponent pattern for reusable UI components\n- Concerns for shared model behavior\n- Associated Objects pattern using `active_record-associated_object`\n- Slug-based routing for SEO\n- Background jobs for data processing\n- YAML-based conference data structure\n\n## Development Standards\n\n### Ruby/Rails Code\n\n**General Rails Conventions:**\n\n- Follow Rails 8 conventions and modern Rails patterns\n- Use `standardrb` for Ruby formatting (never `rubocop`)\n- Models include concerns: `Suggestable`, `Sluggable`, `Rollupable`, `Searchable`, `Watchable`\n- Prefer `belongs_to` with `optional: true` when appropriate\n- Use `has_many` with `dependent: :destroy` for cascade deletes\n\n**Model Patterns:**\n\n```ruby\nclass Talk < ApplicationRecord\n  include Rollupable\n  include Sluggable\n  include Suggestable\n  include Searchable\n  include Watchable\n  configure_slug(attribute: :title, auto_suffix_on_collision: true)\n\n  belongs_to :event, optional: true, counter_cache: :talks_count, touch: true\n  has_many :speaker_talks, dependent: :destroy\n  has_many :speakers, through: :speaker_talks\n\n  validates :title, presence: true\n  enum :kind, [\"talk\", \"keynote\", \"panel\"].index_by(&:itself), default: \"talk\"\n\n  scope :watchable, -> { where(external_player: false) }\n  scope :canonical, -> { where(canonical_id: nil) }\nend\n```\n\n**Controller Patterns:**\n\n- Inherit from `ApplicationController` which includes:\n  - `Authenticable` - session-based authentication\n  - `Metadata` - SEO meta tags\n  - `Analytics` - page view tracking\n- Use `skip_before_action :authenticate_user!` for public pages\n- Follow RESTful routing patterns\n- Use `Current.user` for current user access\n- Implement pagination with `pagy` gem\n\n```ruby\nclass TalksController < ApplicationController\n  skip_before_action :authenticate_user!, only: [:index, :show]\n\n  def show\n    @talk = Talk.includes(:speakers, :topics).find_by(slug: params[:slug])\n    return redirect_to(root_path, status: :moved_permanently) unless @talk\n\n    @pagy, @related_talks = pagy(@talk.related_talks, limit: 6)\n  end\nend\n```\n\n**Authentication Patterns:**\n\n- Session-based authentication, not JWT\n- Use `Current.user` to access current user\n- GitHub OAuth integration available\n- Admin users have `admin: true` boolean\n- Route constraints use `Authenticator` module\n\n### ViewComponent Architecture\n\n> **Detailed UI Component Rules**: See [viewcomponents.mdc](./viewcomponents.mdc) for comprehensive UI component guidelines.\n\n**Component Structure:**\n\n- All components inherit from `ApplicationComponent`\n- Components located in `app/components/`\n- UI components in `app/components/ui/` namespace\n\n```ruby\nclass Ui::ButtonComponent < ApplicationComponent\n  option :kind, type: Dry::Types[\"coercible.symbol\"].enum(:primary, :secondary), default: proc { :primary }\n  option :size, type: Dry::Types[\"coercible.symbol\"].enum(:sm, :md, :lg), default: proc { :md }\n\n  private\n\n  def component_classes\n    class_names(\n      \"btn\",\n      KIND_MAPPING[kind],\n      SIZE_MAPPING[size]\n    )\n  end\nend\n```\n\n**Component Conventions:**\n\n- Use mapping constants for CSS class variants\n- Implement `component_classes` method for dynamic styling\n- Use `class_names` helper for conditional classes\n- Support both `param` and `option` for parameters\n- Include `display` option for conditional rendering\n\n### Frontend Development\n\n**Stimulus Controllers:**\n\n- Located in `app/javascript/controllers/`\n- Follow Stimulus conventions with kebab-case names\n- Use Stimulus actions for interactive components\n\n**CSS/Styling:**\n\n- Tailwind CSS with daisyUI components\n- Follow utility-first approach\n- Use CSS variables for theming\n- Responsive design with mobile-first approach\n\n**Assets:**\n\n- Vite for asset bundling\n- Images in `app/assets/images/`\n- Use WebP format for optimized images\n\n### Database & Models\n\n**Schema Patterns:**\n\n- Use `annotaterb` gem for model annotations\n- SQLite database with proper indexing\n- Use foreign key constraints\n- Counter cache patterns: `counter_cache: :talks_count`\n\n**Data Validation:**\n\n- Validate presence of required fields\n- Use Rails enum for status fields\n- Normalize data with `normalizes` callback\n- Encrypt sensitive data: `encrypts :email, deterministic: true`\n\n**Associations:**\n\n- Use `inverse_of` for bidirectional associations\n- `strict_loading: false` where needed for performance\n- Scoped associations: `has_many :approved_topics, -> { approved }`\n\n### Background Jobs & Processing\n\n**Job Patterns:**\n\n- Use Solid Queue for background processing\n- Jobs in `app/jobs/` directory\n- Process video metadata, transcripts, AI summaries\n- Handle external API calls asynchronously\n\n**Queue Configuration:**\n\n```ruby\nconfig.active_job.queue_adapter = :solid_queue\nconfig.solid_queue.connects_to = {database: {writing: :queue}}\n```\n\n### Search & Data\n\n**Data Structure:**\n\n- Conference data stored in YAML files under `data/`\n- Organizations, speakers, events, and videos defined in YAML\n- Rake tasks process and import data\n\n### Testing Standards\n\n**Test Structure:**\n\n- Use Minitest (not RSpec)\n- Parallel test execution enabled\n- VCR for API mocking\n- Fixtures for test data\n- System tests with Capybara + Selenium\n\n**Test Patterns:**\n\n```ruby\nclass TalkTest < ActiveSupport::TestCase\n  test \"creates slug from title\" do\n    talk = talks(:ruby_conf_talk)\n    assert_equal \"awesome-ruby-talk\", talk.slug\n  end\n\n  test \"belongs to event\" do\n    talk = talks(:ruby_conf_talk)\n    assert_equal events(:ruby_conf_2023), talk.event\n  end\nend\n```\n\n**Test Helper Setup:**\n\n- Search reindexing in setup\n- Sign in helper: `sign_in_as(user)`\n- VCR cassettes for external API calls\n\n### API & Integrations\n\n**External APIs:**\n\n- YouTube API for video metadata\n- GitHub API for user authentication\n- OpenAI API for AI features\n- All API clients in `app/clients/` directory\n\n**AI Features:**\n\n- Transcript enhancement\n- Topic extraction\n- Talk summarization\n- All AI prompts stored in `app/models/prompts/`\n\n### Development Commands\n\n**Common Commands:**\n\n- `bin/setup` - Full setup including Docker and database seeding\n- `bin/dev` - Start Rails server, jobs, and Vite\n- `bin/lint` - Run all linters and formatters\n- `bin/rails test` - Run full test suite\n- `bundle exec standardrb --fix` - Fix Ruby formatting\n- `yarn format` - Fix JavaScript formatting\n\n**Data Management:**\n\n- `bin/rails db:seed:all` - Seed database from YAML files\n- YAML files define conference structure and video metadata\n\n### Deployment & Production\n\n**Kamal Deployment:**\n\n- Use Kamal for containerized deployment\n- Dockerfile included for production builds\n- Environment-specific configurations\n\n**Monitoring:**\n\n- AppSignal for error tracking and performance monitoring\n- Ahoy for user analytics\n- Mission Control for job monitoring\n\n## Code Quality Standards\n\n1. **Always run `standardrb --fix` for Ruby formatting**\n2. **Use `yarn format` for JavaScript formatting**\n3. **Include tests for new functionality**\n4. **Follow Rails naming conventions**\n5. **Use ViewComponents for reusable UI elements**\n6. **Implement proper error handling**\n7. **Add appropriate database indexes**\n8. **Use background jobs for long-running tasks**\n9. **Follow security best practices**\n10. **Write clear, descriptive commit messages**\n\n## Common Patterns to Follow\n\n- Models use concerns for shared behavior\n- Controllers are slim with business logic in models/services\n- ViewComponents for reusable UI with design system consistency\n- Background jobs for external API calls and heavy processing\n- Proper caching strategies with Solid Cache\n- SEO-friendly URLs with slugs\n- Responsive design with Tailwind CSS\n- Session-based authentication\n- Comprehensive test coverage\n\nWhen implementing features, always consider performance, security, accessibility, and maintainability. Follow Rails conventions and this project's established patterns.\n"
  },
  {
    "path": ".cursor/rules/viewcomponents.mdc",
    "content": "---\nalwaysApply: false\n---\n\n# RubyVideo ViewComponents - UI Component Rules\n\n> **Main Project Rules**: See [cursorrules.mdc](./cursorrules.mdc) for complete RubyVideo project guidelines.\n\n## UI Component Architecture\n\nThis document defines specific rules for creating and maintaining UI components in the `Ui::` namespace within RubyVideo's ViewComponent architecture.\n\n## Component Structure & Inheritance\n\n### Base Component Pattern\n\nAll UI components MUST inherit from `ApplicationComponent`:\n\n```ruby\nclass Ui::ComponentNameComponent < ApplicationComponent\n  # Component implementation\nend\n```\n\n### ApplicationComponent Features\n\nThe base `ApplicationComponent` provides:\n\n- `Dry::Initializer` integration for type-safe parameters\n- Automatic `attributes` handling for HTML attributes\n- `display` option for conditional rendering\n- `render?` method that respects the `display` option\n\n## UI Component Conventions\n\n### 1. Component Naming\n\n- **File naming**: `snake_case_component.rb` (e.g., `button_component.rb`)\n- **Class naming**: `Ui::PascalCaseComponent` (e.g., `Ui::ButtonComponent`)\n- **Template naming**: `snake_case_component.html.erb` (e.g., `button_component.html.erb`)\n\n### 2. Parameter Definition\n\nUse `Dry::Types` for type-safe parameters with proper defaults:\n\n```ruby\nclass Ui::ButtonComponent < ApplicationComponent\n  # Required parameter\n  param :text, default: proc {}\n\n  # Optional parameter with type constraint\n  option :url, Dry::Types[\"coercible.string\"], optional: true\n\n  # Enum parameter with default\n  option :kind, type: Dry::Types[\"coercible.symbol\"].enum(:primary, :secondary), default: proc { :primary }\n\n  # Boolean parameter\n  option :disabled, type: Dry::Types[\"strict.bool\"], default: proc { false }\nend\n```\n\n### 3. CSS Class Management\n\n#### Mapping Constants Pattern\n\nDefine mapping constants for CSS class variants:\n\n```ruby\nclass Ui::ButtonComponent < ApplicationComponent\n  KIND_MAPPING = {\n    primary: \"btn-primary\",\n    secondary: \"btn-secondary\",\n    neutral: \"btn-neutral btn-outline\",\n    ghost: \"btn-ghost\"\n  }.freeze\n\n  SIZE_MAPPING = {\n    sm: \"btn-sm\",\n    md: \"\",\n    lg: \"btn-lg\"\n  }.freeze\nend\n```\n\n#### Component Classes Method\n\nImplement `component_classes` method for dynamic styling:\n\n```ruby\nprivate\n\ndef component_classes\n  class_names(\n    \"btn\",                    # Base class\n    KIND_MAPPING[kind],       # Variant class\n    SIZE_MAPPING[size],       # Size class\n    \"btn-outline\": outline,   # Conditional class\n    \"btn-disabled\": disabled  # State class\n  )\nend\n```\n\n#### Final Classes Method\n\nCombine component classes with user-provided classes:\n\n```ruby\nprivate\n\ndef classes\n  [component_classes, attributes[:class]].join(\" \")\nend\n```\n\n### 4. Content Handling\n\n#### Content Method Pattern\n\nHandle both parameter content and block content:\n\n```ruby\nprivate\n\ndef content\n  text.presence || super  # Use param if provided, otherwise use block content\nend\n```\n\n#### Call Method for Complex Rendering\n\nUse `call` method for complex rendering logic:\n\n```ruby\ndef call\n  case button_kind\n  when :link\n    link_to(url, class: classes, **attributes.except(:class)) { content }\n  when :button\n    tag.button(type: type, class: classes, **attributes.except(:class)) { content }\n  end\nend\n```\n\n### 5. Stimulus Integration\n\n#### Before Render Hook\n\nUse `before_render` for Stimulus controller setup:\n\n```ruby\ndef before_render\n  attributes[:data] = {\n    controller: \"modal\",\n    modal_open_value: open,\n    action: \"keydown.esc->modal#close\"\n  }.merge(attributes[:data] || {})\nend\n```\n\n#### Data Attributes\n\nPass Stimulus values through data attributes:\n\n```ruby\nattributes[:data] = {\n  controller: \"dropdown\",\n  dropdown_open_value: open,\n  action: \"click->dropdown#toggle\"\n}\n```\n\n## Common UI Component Patterns\n\n### Button Component\n\n```ruby\nclass Ui::ButtonComponent < ApplicationComponent\n  KIND_MAPPING = {\n    primary: \"btn-primary\",\n    secondary: \"btn-secondary\",\n    ghost: \"btn-ghost\"\n  }.freeze\n\n  SIZE_MAPPING = {\n    sm: \"btn-sm\",\n    md: \"\",\n    lg: \"btn-lg\"\n  }.freeze\n\n  param :text, default: proc {}\n  option :url, Dry::Types[\"coercible.string\"], optional: true\n  option :kind, type: Dry::Types[\"coercible.symbol\"].enum(*KIND_MAPPING.keys), default: proc { :primary }\n  option :size, type: Dry::Types[\"coercible.symbol\"].enum(*SIZE_MAPPING.keys), default: proc { :md }\n  option :disabled, type: Dry::Types[\"strict.bool\"], default: proc { false }\n\n  def call\n    if url.present?\n      link_to(url, class: classes, **attributes.except(:class)) { content }\n    else\n      tag.button(type: :button, class: classes, **attributes.except(:class)) { content }\n    end\n  end\n\n  private\n\n  def classes\n    [component_classes, attributes[:class]].join(\" \")\n  end\n\n  def component_classes\n    class_names(\n      \"btn\",\n      KIND_MAPPING[kind],\n      SIZE_MAPPING[size],\n      \"btn-disabled\": disabled\n    )\n  end\n\n  def content\n    text.presence || super\n  end\nend\n```\n\n### Badge Component\n\n```ruby\nclass Ui::BadgeComponent < ApplicationComponent\n  KIND_MAPPING = {\n    primary: \"badge-primary\",\n    secondary: \"badge-secondary\",\n    neutral: \"badge-neutral\"\n  }.freeze\n\n  SIZE_MAPPING = {\n    xs: \"badge-xs\",\n    sm: \"badge-sm\",\n    md: \"badge-md\",\n    lg: \"badge-lg\"\n  }.freeze\n\n  param :text, optional: true\n  option :kind, type: Dry::Types[\"coercible.symbol\"].enum(*KIND_MAPPING.keys), default: proc { :primary }\n  option :size, type: Dry::Types[\"coercible.symbol\"].enum(*SIZE_MAPPING.keys), default: proc { :md }\n\n  def call\n    content_tag(:span, class: classes, **attributes.except(:class)) do\n      content\n    end\n  end\n\n  private\n\n  def classes\n    [component_classes, attributes[:class]].join(\" \")\n  end\n\n  def component_classes\n    class_names(\n      \"badge\",\n      KIND_MAPPING[kind],\n      SIZE_MAPPING[size]\n    )\n  end\n\n  def content\n    text.presence || super\n  end\nend\n```\n\n### Modal Component\n\n```ruby\nclass Ui::ModalComponent < ApplicationComponent\n  POSITION_MAPPING = {\n    top: \"modal-top\",\n    middle: \"modal-middle\",\n    bottom: \"modal-bottom\",\n    responsive: \"modal-bottom sm:modal-middle\"\n  }.freeze\n\n  SIZE_MAPPING = {\n    md: \"\",\n    lg: \"!max-w-[800px]\"\n  }.freeze\n\n  option :open, type: Dry::Types[\"strict.bool\"], default: proc { false }\n  option :position, type: Dry::Types[\"coercible.symbol\"].enum(*POSITION_MAPPING.keys), default: proc { :responsive }\n  option :size, type: Dry::Types[\"coercible.symbol\"].enum(*SIZE_MAPPING.keys), default: proc { :md }\n\n  def before_render\n    attributes[:data] = {\n      controller: \"modal\",\n      modal_open_value: open,\n      action: \"keydown.esc->modal#close\"\n    }.merge(attributes[:data] || {})\n  end\n\n  private\n\n  def classes\n    [component_classes, attributes.delete(:class)].compact_blank.join(\" \")\n  end\n\n  def component_classes\n    class_names(\n      \"modal\",\n      POSITION_MAPPING[position]\n    )\n  end\n\n  def size_class\n    SIZE_MAPPING[size]\n  end\nend\n```\n\n## Template Patterns\n\n### Basic Template Structure\n\n```erb\n<!-- button_component.html.erb -->\n<%= call %>\n```\n\n### Complex Template with Slots\n\n```erb\n<!-- modal_component.html.erb -->\n<div class=\"<%= classes %>\" <%= tag.attributes(attributes) %>>\n  <div class=\"modal-box <%= size_class %>\">\n    <% if close_button %>\n      <form method=\"dialog\">\n        <button class=\"btn btn-sm btn-circle btn-ghost absolute right-2 top-2\">✕</button>\n      </form>\n    <% end %>\n    <%= content %>\n  </div>\n  <form method=\"dialog\" class=\"modal-backdrop\">\n    <button>close</button>\n  </form>\n</div>\n```\n\n## Testing UI Components\n\n### Component Test Structure\n\n```ruby\nclass Ui::ButtonComponentTest < ViewComponent::TestCase\n  test \"renders primary button\" do\n    render_inline(Ui::ButtonComponent.new(\"Click me\", kind: :primary))\n\n    assert_selector(\"button.btn.btn-primary\", text: \"Click me\")\n  end\n\n  test \"renders as link when url provided\" do\n    render_inline(Ui::ButtonComponent.new(\"Click me\", url: \"/test\"))\n\n    assert_selector(\"a.btn\", text: \"Click me\", href: \"/test\")\n  end\n\n  test \"applies custom classes\" do\n    render_inline(Ui::ButtonComponent.new(\"Click me\", class: \"custom-class\"))\n\n    assert_selector(\"button.custom-class\")\n  end\nend\n```\n\n## Best Practices\n\n### 1. Type Safety\n\n- Always use `Dry::Types` for parameter validation\n- Define enum constraints for variant options\n- Use `optional: true` for non-required parameters\n\n### 2. CSS Architecture\n\n- Use mapping constants for variant classes\n- Implement `component_classes` method for dynamic styling\n- Support custom classes through `attributes[:class]`\n\n### 3. Content Flexibility\n\n- Support both parameter content and block content\n- Use `content` method to handle both cases\n- Implement `call` method for complex rendering logic\n\n### 4. Stimulus Integration\n\n- Use `before_render` for controller setup\n- Pass values through data attributes\n- Support custom actions and controllers\n\n### 5. Accessibility\n\n- Include proper ARIA attributes\n- Support keyboard navigation\n- Ensure proper semantic HTML\n\n### 6. Performance\n\n- Use `freeze` on mapping constants\n- Minimize method calls in templates\n- Cache computed values when appropriate\n\n## Common Mistakes to Avoid\n\n1. **Don't** hardcode CSS classes in templates\n2. **Don't** forget to handle both parameter and block content\n3. **Don't** skip type validation for parameters\n4. **Don't** forget to merge custom attributes\n5. **Don't** ignore accessibility requirements\n6. **Don't** create components without proper mapping constants\n\n## Component Checklist\n\nWhen creating a new UI component, ensure:\n\n- [ ] Inherits from `ApplicationComponent`\n- [ ] Uses proper naming convention (`Ui::NameComponent`)\n- [ ] Defines mapping constants for variants\n- [ ] Implements `component_classes` method\n- [ ] Handles both parameter and block content\n- [ ] Supports custom CSS classes\n- [ ] Includes proper type validation\n- [ ] Has corresponding template file\n- [ ] Includes comprehensive tests\n- [ ] Follows accessibility guidelines\n- [ ] Documents all options and parameters\n\nThis ensures consistency across all UI components and maintains the design system's integrity.\n"
  },
  {
    "path": ".devcontainer/Dockerfile",
    "content": "ARG RUBY_VERSION=4.0.1\nFROM docker.io/library/ruby:$RUBY_VERSION\n\n# Rails app lives here\nWORKDIR /rails\n\n# Install base packages\nRUN apt-get update -qq && \\\n    apt-get install --no-install-recommends -y \\\n    build-essential \\\n    # curl \\\n    # git \\\n    # imagemagick \\ # Generate Assets\n    libjemalloc2 \\\n    libvips \\\n    # libyaml-dev \\\n    node-gyp \\\n    pkg-config \\\n    python-is-python3 \\\n    # sqlite3 \\\n    chromium chromium-driver \\\n    && rm -rf /var/lib/apt/lists /var/cache/apt/archives\n\n# Copy lockfiles and setup script\n# COPY Gemfile Gemfile.lock package.json .env.sample .ruby-version ./\n# COPY bin ./bin\n\n# Copy the whole application so we don't stumble on setting up the database\nCOPY . ./\n\n# Install JavaScript dependencies\nARG NODE_VERSION=22.15.1\nARG YARN_VERSION=1.22.22\nENV PATH=/usr/local/node/bin:$PATH\nRUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \\\n    /tmp/node-build-master/bin/node-build \"${NODE_VERSION}\" /usr/local/node && \\\n    npm install -g yarn@$YARN_VERSION && \\\n    rm -rf /tmp/node-build-master\n\n# Setup dependencies\nRUN bin/setup --skip-server\n\n# Default command\nCMD [\"sleep\", \"infinity\"]\n"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "content": "{\n  \"name\": \"RubyEvents Dev\",\n  \"dockerComposeFile\": \"./docker-compose.yml\",\n  \"service\": \"rails-app\",\n  \"workspaceFolder\": \"/rails\",\n  \"overrideCommand\": true,\n  \"customizations\": {\n    \"vscode\": {\n      \"settings\": {\n        \"git.terminalGitEditor\": true\n      },\n      \"extensions\": [\n        \"dbaeumer.vscode-eslint\",\n        \"esbenp.prettier-vscode\",\n        \"bradlc.vscode-tailwindcss\",\n        \"testdouble.vscode-standard-ruby\",\n        \"marcoroth.herb-lsp\",\n        \"redhat.vscode-yaml\"\n      ]\n    }\n  },\n  \"features\": {\n    \"ghcr.io/devcontainers/features/git:1\": {},\n    \"ghcr.io/devcontainers/features/github-cli:1\": {},\n    \"ghcr.io/devcontainers/features/sshd:1\": {}\n  },\n  \"portsAttributes\": {\n    \"3000\": {\n      \"label\": \"Ruby Events Rails Server\",\n      \"onAutoForward\": \"notify\"\n    },\n    \"3036\": {\n      \"label\": \"Vite Server\",\n      \"onAutoForward\": \"silent\"\n    }\n  },\n  \"mounts\": [\n    \"source=${localEnv:HOME}/.ssh,target=/home/vscode/.ssh,type=bind,consistency=cached\"\n  ]\n}"
  },
  {
    "path": ".devcontainer/docker-compose.yml",
    "content": "name: \"RubyEvents\"\n\nservices:\n  rails-app:\n    build:\n      context: ..\n      dockerfile: .devcontainer/Dockerfile\n    command: sleep infinity\n    depends_on:\n      - typesense\n    environment:\n      - RAILS_ENV=development\n      - NODE_ENV=development\n      - TYPESENSE_HOST=typesense\n      - TYPESENSE_PORT=8108\n    ports:\n      - \"3000:3000\"\n    volumes:\n      - ..:/rails:cached # Mounts the local project directory\n      - node_modules:/rails/node_modules # Prevents overwriting node_modules so yarn install works correctly\n    stdin_open: true\n    tty: true\n\n  typesense:\n    image: typesense/typesense:29.0\n    container_name: rubyevents-typesense\n    restart: unless-stopped\n    ports:\n      - \"8108:8108\"\n    volumes:\n      - typesense-data:/data\n    environment:\n      - TYPESENSE_DATA_DIR=/data\n      - TYPESENSE_ENABLE_CORS=true\n    command: [\"--data-dir\", \"/data\", \"--api-key\", \"xyz\", \"--enable-cors\", \"true\"]\n    healthcheck:\n      test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8108/health\"]\n      interval: 30s\n      timeout: 10s\n      retries: 3\n      start_period: 10s\n\nvolumes:\n  node_modules:\n  typesense-data:\n    driver: local\n"
  },
  {
    "path": ".dockerignore",
    "content": "# See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files.\n\n# Ignore git directory.\n/.git/\n\n# Ignore bundler config.\n/.bundle\n\n# Ignore all default key files.\n/config/master.key\n/config/credentials/*.key\n\n# Ignore all environment files.\n/.env*\n!/.env.sample\n\n# Ignore all logfiles and tempfiles.\n/log/*\n/tmp/*\n!/log/.keep\n!/tmp/.keep\n\n# Ignore pidfiles, but keep the directory.\n/tmp/pids/*\n!/tmp/pids/\n!/tmp/pids/.keep\n\n# Ignore storage (uploaded files in development and any SQLite databases).\n/storage/*\n!/storage/.keep\n/tmp/storage/*\n!/tmp/storage/\n!/tmp/storage/.keep\n\n# Ignore assets.\n/node_modules/\n/app/assets/builds/*\n!/app/assets/builds/.keep\n/public/assets\n/scripts/*\n\n/docs/*\n/load_testing/*\n/test/*\n"
  },
  {
    "path": ".erb_lint.yml",
    "content": "---\nEnableDefaultLinters: true\nglob: \"**/*.{html}{+*,}.erb\"\nexclude:\n  - vendor/bundle/**/*\n  - node_modules/**/*\n  - tmp/**/*\n  - log/**/*\n  - app/views/profiles/wrapped/**/*\n\nlinters:\n  ErbSafety:\n    enabled: true\n  PartialInstanceVariable:\n    enabled: true\n    exclude:\n      - app/views/contributions/_events_without_dates.html.erb\n      - app/views/contributions/_events_without_location.html.erb\n      - app/views/contributions/_events_without_videos.html.erb\n      - app/views/contributions/_missing_videos_cue.html.erb\n      - app/views/contributions/_speakers_without_github.html.erb\n      - app/views/contributions/_talks_dates_out_of_bounds.html.erb\n      - app/views/contributions/_talks_without_slides.html.erb\n      - app/views/events/_my_attendance_day.html.erb\n      - app/views/profiles/wrapped/_share.html.erb\n\n  Rubocop:\n    enabled: true\n    rubocop_config:\n      require: standard\n      inherit_gem:\n        standard: config/base.yml\n      Layout/InitialIndentation:\n        Enabled: false\n      Layout/TrailingEmptyLines:\n        Enabled: false\n      Lint/UselessAssignment:\n        Enabled: false\n      Lint/ItWithoutArgumentsInBlock:\n        Enabled: false\n"
  },
  {
    "path": ".eslintignore",
    "content": "app/javascript/controllers/index.js\n"
  },
  {
    "path": ".eslintrc",
    "content": "{ \"extends\": \"standard\" }\n"
  },
  {
    "path": ".gitattributes",
    "content": "# See https://git-scm.com/docs/gitattributes for more about git attribute files.\n\n# Mark the database schema as having been generated.\ndb/schema.rb linguist-generated\n\n# Mark any vendored files as having been vendored.\nvendor/* linguist-vendored\nconfig/credentials/*.yml.enc diff=rails_credentials\nconfig/credentials.yml.enc diff=rails_credentials\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "## Description\n<!-- Please describe your changes. -->\n\n## Screenshots\n<!-- Add screenshots or GIFs if applicable. -->\n\n## Testing Steps\n<!-- List steps to test your changes. -->\n<!-- If this is a content PR, link to the affected pages -->\n\n## References\n<!-- Link to related issues, discussions, other PRs, or references you used to write the PR. -->\n- closes #<!-- issue number -->\n"
  },
  {
    "path": ".github/skills/event-data/SKILL.md",
    "content": "---\nname: event-data\ndescription: Guide for handling event data. Use when asked to update event data such as CFPs, Talks, Schedule, Sponsors, Involvements, or Videos. Use when updating any file in the /data/ directory.\n---\n\n# Important Notes\nIf something is unclear, use the AskUserTool to ask for clarification.\n**Always use the generators if possible.**\nThe generators will create a file with the correct structure, and will help you avoid formatting errors.\nIf you do not have a paramter for the generator, do not pass it as a parameter.\nThe generaator will create a reasonable fault or TODO for someone else to fill out later.\n`bin/lint` must be called before commiting any changes to confirm the structure of the file is correct.\n\n# Adding a talk\n\nReview documentation in docs/ADDING_UNPUBLISHED_TALKS.md.\n\nReview the available parameters for the TalkGenerator.\n\n```bash\nbin/rails g talk --help\n```\n\nCreate a command to reproduce the talk.\n\nFor example, if the user says \"Create a lightning talk from Chris Hasiński, the title is Doom, and it's for the Ruby Community Conference\".\n\n```bash\nbin/rails g talk --event ruby-community-conference-winter-edition-2026 --speaker \"Chris Hasiński\" --title \"Doom\" --kind lightning_talk\n```\n\nExclude any missing parameters, and let the generator create TODOs for someone else to fill out later.\n\nIf the rubyevents MCP is available, and the user did not provide an event series slug and event, use the EventLookupTool to find the correct event.\n\nCall the generator once per talk, and do not attempt to create multiple talks in one command.\n\nRun `bin/lint` once all talks are added to confirm the structure.\n\n# Generating a Schedule\n\nLoad Documentation from docs/ADDING_SCHEDULES.md into context.\n\nCall the help command and review the available parameters for the ScheduleGenerator.\n\n```bash\nbin/rails g schedule --help\n```\n\nCreate a command to approximate the schedule provided by the user.\n\nModify the yaml file to match the schedule exactly.\n\nRun `bin/lint` to confirm the schedule structure.\n\n# Generating a Sponsors file\n\nLoad Documentation from docs/ADDING_SPONSORS.md into context.\n\nReview the available parameters for the SponsorGenerator.\n\n```bash\nbin/rails g sponsor --help\n```\n\nGenerate the sponsor file with appropriate tiers and sponsor names. \n\n# Speakers\n\nWhen updating speakers.yml, the structure is:\n\n```yaml\n- name: \"Speaker Name\"\n  github: \"github_handle\"\n  slug: \"speaker-slug\"\n```\n\nOther fields are permitted, but these are the fields I want you to focus on.\nThe GitHub handle is how we deduplicate speakers, and populate their profile, so the key should always be present.\nThese speakers are used for talks and involvements, so if a speaker is missing, you need to create a new record for them here.\n\nIf the GitHub is unknown:\n\n```yaml\n- name: \"Speaker Name\"\n  github: \"\"\n  slug: \"speaker-slug\"\n```\n\nIf the speaker has multiple aliases, they'll be included as aliases.\n\n```yaml\n- name: \"Speaker Name\"\n  github: \"github_handle\"\n  slug: \"speaker-slug\"\n  aliases:\n    - name: \"Other Name\"\n      slug: \"other-slug\"\n```"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non:\n  pull_request:\n    branches: [\"*\"]\n  push:\n    branches: [main]\n\nconcurrency:\n  group: ci-${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    timeout-minutes: 5\n    env:\n      RAILS_ENV: test\n      RUBOCOP_CACHE_ROOT: tmp/rubocop\n    steps:\n      - uses: actions/checkout@v5\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n\n      - name: Setup Node\n        uses: actions/setup-node@v6\n        with:\n          node-version-file: \".node-version\"\n          cache: yarn\n\n      - name: Install dependencies\n        run: yarn install --frozen-lockfile\n\n      - name: Prepare RuboCop cache\n        uses: actions/cache@v4\n        env:\n          DEPENDENCIES_HASH: ${{ hashFiles('**/.rubocop.yml', 'Gemfile.lock') }}\n        with:\n          path: ${{ env.RUBOCOP_CACHE_ROOT }}\n          key: rubocop-${{ runner.os }}-${{ env.RUBY_VERSION }}-${{ env.DEPENDENCIES_HASH }}-${{ github.ref_name == github.event.repository.default_branch && github.run_id || 'default' }}\n          restore-keys: |\n            rubocop-${{ runner.os }}-${{ env.RUBY_VERSION }}-${{ env.DEPENDENCIES_HASH }}-\n\n      - name: StandardRB Check\n        run: bundle exec standardrb --format github --format \"Standard::Formatter\"\n\n      - name: StandardJS Check\n        run: yarn lint\n\n      - name: Lint YAML data files\n        run: yarn lint:yml\n\n      - name: Validate YAML data schemas\n        run: bin/rails validate:all\n\n      - name: erb-lint Check\n        run: bundle exec erb_lint --lint-all\n\n      - name: Herb Linter Check\n        run: npx @herb-tools/linter\n\n      - name: Herb Analyze (parse/compile)\n        run: bundle exec herb analyze app/\n\n  test:\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n    env:\n      RAILS_ENV: test\n    steps:\n      - uses: actions/checkout@v5\n\n      - name: Install ImageMagick\n        run: sudo apt-get update && sudo apt-get install -y imagemagick\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n\n      - name: Setup Node\n        uses: actions/setup-node@v6\n        with:\n          node-version-file: \".node-version\"\n          cache: yarn\n\n      - name: Install dependencies\n        run: yarn install --frozen-lockfile\n\n      - name: Build assets\n        run: bin/vite build --clear --mode=test\n\n      - name: Prepare database\n        run: |\n          bin/rails db:create\n          bin/rails db:schema:load\n\n      - name: Run tests\n        run: |\n          bin/rails test\n          bin/rails test:system\n\n  seed_smoke_test:\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n    env:\n      RAILS_ENV: test\n      SEED_SMOKE_TEST: true\n    steps:\n      - uses: actions/checkout@v5\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n\n      - name: Setup Node\n        uses: actions/setup-node@v6\n        with:\n          node-version-file: \".node-version\"\n          cache: yarn\n\n      - name: Install dependencies\n        run: yarn install --frozen-lockfile\n\n      - name: Build assets\n        run: bin/vite build --clear --mode=test\n\n      - name: Prepare database\n        run: |\n          bin/rails db:create\n          bin/rails db:schema:load\n\n      - name: Run Seed Smoke Test\n        run: bin/rails test test/tasks/seed_test.rb\n\n      - name: Verify all thumbnails for child talks are present\n        run: bin/rails verify_thumbnails\n\n      - name: Validate no duplicated speakers in database\n        run: bin/rails validate:speaker_duplicates\n\n  build:\n    name: Build Docker Image\n    runs-on: ubuntu-24.04-arm\n\n    permissions:\n      contents: read\n      packages: write\n      attestations: write\n      id-token: write\n    timeout-minutes: 20\n\n    env:\n      DOCKER_BUILDKIT: 1\n      RAILS_ENV: production\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n\n      - name: Set up Docker Buildx for cache\n        uses: docker/setup-buildx-action@v3\n\n      - name: Expose GitHub Runtime for cache\n        uses: crazy-max/ghaction-github-runtime@v3\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n\n      - name: Log in to GHCR\n        uses: docker/login-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Build Docker image (PR)\n        if: ${{ github.event_name == 'pull_request' }}\n        run: docker build .\n        env:\n          DOCKER_BUILDKIT: 1\n\n      - name: Build and push Docker image\n        if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}\n        run: bundle exec kamal build push\n        env:\n          KAMAL_RAILS_MASTER_KEY: ${{ secrets.KAMAL_RAILS_MASTER_KEY }}\n          KAMAL_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}\n\n  deploy:\n    needs: [lint, test, seed_smoke_test, build]\n    name: Deploy\n    if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}\n    runs-on: ubuntu-latest\n    timeout-minutes: 20\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n\n      - name: Setup SSH\n        uses: webfactory/ssh-agent@v0.9.0\n        with:\n          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n\n      - name: Deploy with Kamal\n        run: bundle exec kamal deploy --skip-push\n        env:\n          KAMAL_RAILS_MASTER_KEY: ${{ secrets.KAMAL_RAILS_MASTER_KEY }}\n          KAMAL_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}\n          GEOLOCATE_API_KEY: ${{ secrets.GEOLOCATE_API_KEY }}\n          MAPBOX_ACCESS_TOKEN: ${{ secrets.MAPBOX_ACCESS_TOKEN }}\n          TYPESENSE_API_KEY: ${{ secrets.TYPESENSE_API_KEY }}\n          TYPESENSE_NODES: ${{ secrets.TYPESENSE_NODES }}\n          TYPESENSE_NEAREST_NODE: ${{ secrets.TYPESENSE_NEAREST_NODE }}\n\n      - name: Cleanup on cancellation\n        if: always() && steps.deploy.conclusion == 'cancelled'\n        run: bundle exec kamal lock release\n"
  },
  {
    "path": ".github/workflows/copilot-setup-steps.yml",
    "content": "name: Setup Development Environment for GitHub Copilot\n\n\n# Automatically run the setup steps when they are changed to allow for easy validation, and\n# allow manual testing through the repository's \"Actions\" tab\non:\n  workflow_dispatch:\n  push:\n    paths:\n      - .github/workflows/copilot-setup-steps.yml\n  pull_request:\n    paths:\n      - .github/workflows/copilot-setup-steps.yml\n\njobs:\n  # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.\n  copilot-setup-steps:\n    runs-on: ubuntu-latest\n\n    # Only let github read the repository contents\n    permissions:\n      contents: read\n\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v5\n        with:\n          fetch-depth: 30 # Fetch past 30 commits, so reasonable amount of commit context is included\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n      \n      - name: Run bin/setup\n        run: bin/setup --skip-server\n\n      - name: Validate setup\n        run: |\n          echo \"Testing database connectivity...\"\n          bundle exec rails runner \\\n            \"puts 'Database connection: OK'; \\\n            puts 'User count: ' + User.count.to_s\"\n\n          echo \"Running code style validation...\"\n          bundle exec standardrb\n"
  },
  {
    "path": ".github/workflows/deploy-staging.yml",
    "content": "name: Deploy to Staging\n\non: workflow_dispatch\n\njobs:\n  deploy-staging:\n    name: Deploy to Staging\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      packages: write\n    timeout-minutes: 20\n    env:\n      DOCKER_BUILDKIT: 1\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n\n      - name: Set up Docker Buildx\n        uses: docker/setup-buildx-action@v3\n\n      - name: Setup SSH\n        uses: webfactory/ssh-agent@v0.9.0\n        with:\n          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n\n      - name: Log in to GHCR\n        uses: docker/login-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Deploy to Staging\n        env:\n          VERSION: ${{ github.sha }}\n          KAMAL_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}\n          KAMAL_RAILS_MASTER_KEY: ${{ secrets.KAMAL_RAILS_MASTER_KEY }}\n          GEOLOCATE_API_KEY: ${{ secrets.GEOLOCATE_API_KEY }}\n          MAPBOX_ACCESS_TOKEN: ${{ secrets.MAPBOX_ACCESS_TOKEN }}\n        run: bundle exec kamal deploy -d staging\n\n      - name: Cleanup on cancellation\n        if: always() && steps.deploy.conclusion == 'cancelled'\n        run: bundle exec kamal lock release\n"
  },
  {
    "path": ".github/workflows/migrate-production.yml",
    "content": "name: Migrate Production\n\non: workflow_dispatch\n\njobs:\n  migrate-production:\n    name: Migrate Production\n    runs-on: ubuntu-latest\n    timeout-minutes: 5\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n\n      - name: Setup SSH\n        uses: webfactory/ssh-agent@v0.9.0\n        with:\n          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n\n      - name: Run db:migrate on Production\n        run: bundle exec kamal app exec --reuse \"bin/rails db:migrate\"\n"
  },
  {
    "path": ".github/workflows/migrate-staging.yml",
    "content": "name: Migrate Staging\n\non: workflow_dispatch\n\njobs:\n  migrate-staging:\n    name: Migrate Staging\n    runs-on: ubuntu-latest\n    timeout-minutes: 5\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n\n      - name: Setup SSH\n        uses: webfactory/ssh-agent@v0.9.0\n        with:\n          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n\n      - name: Run db:migrate on Staging\n        run: bundle exec kamal app exec --reuse \"bin/rails db:migrate\" -d staging\n"
  },
  {
    "path": ".github/workflows/release-lock-production.yml",
    "content": "name: Release Lock Production\n\non: workflow_dispatch\n\njobs:\n  release-lock-production:\n    name: Release Lock Production\n    runs-on: ubuntu-latest\n    timeout-minutes: 2\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n      - name: Setup SSH\n        uses: webfactory/ssh-agent@v0.9.0\n        with:\n          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n      - name: Deploy to Production\n        run: bundle exec kamal lock release\n"
  },
  {
    "path": ".github/workflows/release-lock-staging.yml",
    "content": "name: Release Lock Staging\n\non: workflow_dispatch\n\njobs:\n  release-lock-staging:\n    name: Release Lock Staging\n    runs-on: ubuntu-latest\n    timeout-minutes: 2\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n      - name: Setup SSH\n        uses: webfactory/ssh-agent@v0.9.0\n        with:\n          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n      - name: Release lock in staging\n        run: bundle exec kamal lock release -d staging\n"
  },
  {
    "path": ".github/workflows/seed-production.yml",
    "content": "name: Seed Production\n\non: workflow_dispatch\n\njobs:\n  seed-production:\n    name: Seed Production\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n\n      - name: Setup SSH\n        uses: webfactory/ssh-agent@v0.9.0\n        with:\n          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n\n      - name: Run db:seed:all on Production\n        run: bundle exec kamal app exec --reuse \"bin/rails db:seed:all\"\n"
  },
  {
    "path": ".github/workflows/seed-staging.yml",
    "content": "name: Seed Staging\n\non: workflow_dispatch\n\njobs:\n  seed-staging:\n    name: Seed Staging\n    runs-on: ubuntu-latest\n    timeout-minutes: 5\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v5\n\n      - name: Setup SSH\n        uses: webfactory/ssh-agent@v0.9.0\n        with:\n          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}\n\n      - name: Setup Ruby\n        uses: ruby/setup-ruby@v1\n        with:\n          bundler-cache: true\n\n      - name: Run db:seed:all on Staging\n        run: bundle exec kamal app exec --reuse \"bin/rails db:seed:all\" -d staging\n"
  },
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files for more about ignoring files.\n#\n# If you find yourself ignoring temporary files generated by your text editor\n# or operating system, you probably want to add a global ignore instead:\n#   git config --global core.excludesfile '~/.gitignore_global'\n\n# Ignore bundler config and cache\n/.bundle\nvendor/bundle/\n\n# Ignore all logfiles and tempfiles.\n/log/*\n/tmp/*\n!/log/.keep\n!/tmp/.keep\n\n# Ignore pidfiles, but keep the directory.\n/tmp/pids/*\n!/tmp/pids/\n!/tmp/pids/.keep\n\n# Ignore storage (uploaded files in development and any SQLite databases).\n/storage/*\n!/storage/.keep\n/tmp/storage/*\n!/tmp/storage/\n!/tmp/storage/.keep\n\n/public/assets\n\n# Ignore master key for decrypting credentials and more.\n/config/master.key\n/config/credentials/production.key\n/config/credentials/staging.key\n\n\n/app/assets/builds/*\n!/app/assets/builds/.keep\n\n/node_modules\n\n/script_tmp\n.env\n.byebug_history\n\n# Vite Ruby\n/public/vite*\n# Vite uses dotenv and suggests to ignore local-only env files. See\n# https://vitejs.dev/guide/env-and-mode.html#env-files\n*.local\n\n/data.ms*\n/data_tmp\ndata/talks_slugs.yml\n\n/config/credentials/production.key\n/config/credentials/staging.key\n\ntest-run-report*\n\n# Ignore SQLite databases create by Litestack for action cable to be removed once we are able to move them to storage\ndb/*.db\ndb/*.db-*\n\n# Vite Ruby\n/public/vite*\nnode_modules\n# Vite uses dotenv and suggests to ignore local-only env files. See\n# https://vitejs.dev/guide/env-and-mode.html#env-files\n*.local\n\n# ignore doc folder\ndoc/*\n\nservice_account.json\n/.cache\n\n# asdf\n.tool-versions\n\n.DS_Store\n\n.ssh-keys/\n\n# IDE files\n/.idea\n"
  },
  {
    "path": ".herb.yml",
    "content": "# This file configures Herb for your project and team.\n# Settings here take precedence over individual editor preferences.\n#\n# Herb is a suite of tools for HTML+ERB templates including:\n# - Linter: Validates templates and enforces best practices\n# - Formatter: Auto-formats templates with intelligent indentation\n# - Language Server: Provides IDE support (VS Code, Zed, Neovim, etc.)\n#\n# Website: https://herb-tools.dev\n# Configuration: https://herb-tools.dev/configuration\n# GitHub Repo: https://github.com/marcoroth/herb\n#\n\nversion: 0.9.2\n\nlinter:\n  enabled: true\n\n  rules:\n    erb-no-interpolated-class-names:\n      enabled: false\n\n\nformatter:\n  enabled: false\n"
  },
  {
    "path": ".kamal/hooks/docker-setup.sample",
    "content": "#!/bin/sh\n\necho \"Docker set up on $KAMAL_HOSTS...\"\n"
  },
  {
    "path": ".kamal/hooks/post-deploy.sample",
    "content": "#!/bin/sh\n\n# A sample post-deploy hook\n#\n# These environment variables are available:\n# KAMAL_RECORDED_AT\n# KAMAL_PERFORMER\n# KAMAL_VERSION\n# KAMAL_HOSTS\n# KAMAL_ROLE (if set)\n# KAMAL_DESTINATION (if set)\n# KAMAL_RUNTIME\n\necho \"$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds\"\n"
  },
  {
    "path": ".kamal/hooks/post-proxy-reboot.sample",
    "content": "#!/bin/sh\n\necho \"Rebooted kamal-proxy on $KAMAL_HOSTS\"\n"
  },
  {
    "path": ".kamal/hooks/pre-build.sample",
    "content": "#!/bin/sh\n\n# A sample pre-build hook\n#\n# Checks:\n# 1. We have a clean checkout\n# 2. A remote is configured\n# 3. The branch has been pushed to the remote\n# 4. The version we are deploying matches the remote\n#\n# These environment variables are available:\n# KAMAL_RECORDED_AT\n# KAMAL_PERFORMER\n# KAMAL_VERSION\n# KAMAL_HOSTS\n# KAMAL_ROLE (if set)\n# KAMAL_DESTINATION (if set)\n\nif [ -n \"$(git status --porcelain)\" ]; then\n  echo \"Git checkout is not clean, aborting...\" >&2\n  git status --porcelain >&2\n  exit 1\nfi\n\nfirst_remote=$(git remote)\n\nif [ -z \"$first_remote\" ]; then\n  echo \"No git remote set, aborting...\" >&2\n  exit 1\nfi\n\ncurrent_branch=$(git branch --show-current)\n\nif [ -z \"$current_branch\" ]; then\n  echo \"Not on a git branch, aborting...\" >&2\n  exit 1\nfi\n\nremote_head=$(git ls-remote $first_remote --tags $current_branch | cut -f1)\n\nif [ -z \"$remote_head\" ]; then\n  echo \"Branch not pushed to remote, aborting...\" >&2\n  exit 1\nfi\n\nif [ \"$KAMAL_VERSION\" != \"$remote_head\" ]; then\n  echo \"Version ($KAMAL_VERSION) does not match remote HEAD ($remote_head), aborting...\" >&2\n  exit 1\nfi\n\nexit 0\n"
  },
  {
    "path": ".kamal/hooks/pre-connect.sample",
    "content": "#!/usr/bin/env ruby\n\n# A sample pre-connect check\n#\n# Warms DNS before connecting to hosts in parallel\n#\n# These environment variables are available:\n# KAMAL_RECORDED_AT\n# KAMAL_PERFORMER\n# KAMAL_VERSION\n# KAMAL_HOSTS\n# KAMAL_ROLE (if set)\n# KAMAL_DESTINATION (if set)\n# KAMAL_RUNTIME\n\nhosts = ENV[\"KAMAL_HOSTS\"].split(\",\")\nresults = nil\nmax = 3\n\nelapsed = Benchmark.realtime do\n  results = hosts.map do |host|\n    Thread.new do\n      tries = 1\n\n      begin\n        Socket.getaddrinfo(host, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME)\n      rescue SocketError\n        if tries < max\n          puts \"Retrying DNS warmup: #{host}\"\n          tries += 1\n          sleep rand\n          retry\n        else\n          puts \"DNS warmup failed: #{host}\"\n          host\n        end\n      end\n\n      tries\n    end\n  end.map(&:value)\nend\n\nretries = results.sum - hosts.size\nnopes = results.count { |r| r == max }\n\nputs \"Prewarmed %d DNS lookups in %.2f sec: %d retries, %d failures\" % [ hosts.size, elapsed, retries, nopes ]\n"
  },
  {
    "path": ".kamal/hooks/pre-deploy.sample",
    "content": "#!/usr/bin/env ruby\n\n# A sample pre-deploy hook\n#\n# Checks the Github status of the build, waiting for a pending build to complete for up to 720 seconds.\n#\n# Fails unless the combined status is \"success\"\n#\n# These environment variables are available:\n# KAMAL_RECORDED_AT\n# KAMAL_PERFORMER\n# KAMAL_VERSION\n# KAMAL_HOSTS\n# KAMAL_COMMAND\n# KAMAL_SUBCOMMAND\n# KAMAL_ROLE (if set)\n# KAMAL_DESTINATION (if set)\n\n# Only check the build status for production deployments\nif ENV[\"KAMAL_COMMAND\"] == \"rollback\" || ENV[\"KAMAL_DESTINATION\"] != \"production\"\n  exit 0\nend\n\nrequire \"bundler/inline\"\n\n# true = install gems so this is fast on repeat invocations\ngemfile(true, quiet: true) do\n  source \"https://rubygems.org\"\n\n  gem \"octokit\"\n  gem \"faraday-retry\"\nend\n\nMAX_ATTEMPTS = 72\nATTEMPTS_GAP = 10\n\ndef exit_with_error(message)\n  $stderr.puts message\n  exit 1\nend\n\nclass GithubStatusChecks\n  attr_reader :remote_url, :git_sha, :github_client, :combined_status\n\n  def initialize\n    @remote_url = `git config --get remote.origin.url`.strip.delete_prefix(\"https://github.com/\")\n    @git_sha = `git rev-parse HEAD`.strip\n    @github_client = Octokit::Client.new(access_token: ENV[\"GITHUB_TOKEN\"])\n    refresh!\n  end\n\n  def refresh!\n    @combined_status = github_client.combined_status(remote_url, git_sha)\n  end\n\n  def state\n    combined_status[:state]\n  end\n\n  def first_status_url\n    first_status = combined_status[:statuses].find { |status| status[:state] == state }\n    first_status && first_status[:target_url]\n  end\n\n  def complete_count\n    combined_status[:statuses].count { |status| status[:state] != \"pending\"}\n  end\n\n  def total_count\n    combined_status[:statuses].count\n  end\n\n  def current_status\n    if total_count > 0\n      \"Completed #{complete_count}/#{total_count} checks, see #{first_status_url} ...\"\n    else\n      \"Build not started...\"\n    end\n  end\nend\n\n\n$stdout.sync = true\n\nputs \"Checking build status...\"\nattempts = 0\nchecks = GithubStatusChecks.new\n\nbegin\n  loop do\n    case checks.state\n    when \"success\"\n      puts \"Checks passed, see #{checks.first_status_url}\"\n      exit 0\n    when \"failure\"\n      exit_with_error \"Checks failed, see #{checks.first_status_url}\"\n    when \"pending\"\n      attempts += 1\n    end\n\n    exit_with_error \"Checks are still pending, gave up after #{MAX_ATTEMPTS * ATTEMPTS_GAP} seconds\" if attempts == MAX_ATTEMPTS\n\n    puts checks.current_status\n    sleep(ATTEMPTS_GAP)\n    checks.refresh!\n  end\nrescue Octokit::NotFound\n  exit_with_error \"Build status could not be found\"\nend\n"
  },
  {
    "path": ".kamal/hooks/pre-proxy-reboot.sample",
    "content": "#!/bin/sh\n\necho \"Rebooting kamal-proxy on $KAMAL_HOSTS...\"\n"
  },
  {
    "path": ".kamal/secrets",
    "content": "# Secrets defined here are available for reference under registry/password, env/secret, builder/secrets,\n# and accessories/*/env/secret in config/deploy.yml. All secrets should be pulled from either\n# password manager, ENV, or a file. DO NOT ENTER RAW CREDENTIALS HERE! This file needs to be safe for git.\n\n# Option 1: Read secrets from the environment\nKAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD\nRAILS_MASTER_KEY=$KAMAL_RAILS_MASTER_KEY\n\nLITESTREAM_ACCESS_KEY_ID=$LITESTREAM_ACCESS_KEY_ID\nLITESTREAM_SECRET_ACCESS_KEY=$LITESTREAM_SECRET_ACCESS_KEY\nLITESTREAM_ENDPOINT=$LITESTREAM_ENDPOINT\nGEOLOCATE_API_KEY=$GEOLOCATE_API_KEY\nMAPBOX_ACCESS_TOKEN=$MAPBOX_ACCESS_TOKEN\n\nTYPESENSE_HOST=$TYPESENSE_HOST\nTYPESENSE_PORT=$TYPESENSE_PORT\nTYPESENSE_PROTOCOL=$TYPESENSE_PROTOCOL\nTYPESENSE_API_KEY=$TYPESENSE_API_KEY\nTYPESENSE_NODES=$TYPESENSE_NODES\nTYPESENSE_NEAREST_NODE=$TYPESENSE_NEAREST_NODE\n\n# Option 2: Read secrets via a command\n# RAILS_MASTER_KEY=$(cat config/master.key)\n\n# Option 3: Read secrets via kamal secrets helpers\n# These will handle logging in and fetching the secrets in as few calls as possible\n# There are adapters for 1Password, LastPass + Bitwarden\n#\n"
  },
  {
    "path": ".kamal/secrets.staging",
    "content": "# Secrets defined here are available for reference under registry/password, env/secret, builder/secrets,\n# and accessories/*/env/secret in config/deploy.yml. All secrets should be pulled from either\n# password manager, ENV, or a file. DO NOT ENTER RAW CREDENTIALS HERE! This file needs to be safe for git.\n\n# Option 1: Read secrets from the environment\nKAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD\nRAILS_MASTER_KEY=$KAMAL_RAILS_MASTER_KEY\n\nLITESTREAM_ACCESS_KEY_ID=$LITESTREAM_ACCESS_KEY_ID\nLITESTREAM_SECRET_ACCESS_KEY=$LITESTREAM_SECRET_ACCESS_KEY\nLITESTREAM_ENDPOINT=$LITESTREAM_ENDPOINT\nGEOLOCATE_API_KEY=$GEOLOCATE_API_KEY\nMAPBOX_ACCESS_TOKEN=$MAPBOX_ACCESS_TOKEN\n\nTYPESENSE_HOST=$TYPESENSE_HOST\nTYPESENSE_PORT=$TYPESENSE_PORT\nTYPESENSE_PROTOCOL=$TYPESENSE_PROTOCOL\nTYPESENSE_API_KEY=$TYPESENSE_API_KEY\n\n# Option 2: Read secrets via a command\n# RAILS_MASTER_KEY=$(cat config/master.key)\n\n# Option 3: Read secrets via kamal secrets helpers\n# These will handle logging in and fetching the secrets in as few calls as possible\n# There are adapters for 1Password, LastPass + Bitwarden\n#\n"
  },
  {
    "path": ".mcp.json",
    "content": "{\n  \"mcpServers\": {\n    \"rubyevents\": {\n      \"command\": \"bin/mcp_server\",\n      \"args\": [],\n      \"tools\": [\"*\"]\n    }\n  }\n}\n"
  },
  {
    "path": ".node-version",
    "content": "22.15.1\n"
  },
  {
    "path": ".prettierignore",
    "content": "transcripts.yml\n"
  },
  {
    "path": ".ruby-version",
    "content": "4.0.1\n"
  },
  {
    "path": ".standard.yml",
    "content": ""
  },
  {
    "path": ".vscode/extensions.json",
    "content": "{\n  \"recommendations\": [\n    \"dbaeumer.vscode-eslint\",\n    \"esbenp.prettier-vscode\",\n    \"bradlc.vscode-tailwindcss\",\n    \"testdouble.vscode-standard-ruby\",\n    \"marcoroth.herb-lsp\",\n    \"redhat.vscode-yaml\"\n  ]\n}"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"editor.detectIndentation\": false,\n  \"editor.formatOnPaste\": true,\n  \"editor.formatOnSave\": true,\n  \"editor.minimap.enabled\": false,\n  \"editor.multiCursorModifier\": \"ctrlCmd\",\n  \"editor.insertSpaces\": true,\n  \"editor.tabSize\": 2,\n  \"editor.rulers\": [\n    80,\n    120\n  ],\n  \"editor.renderControlCharacters\": true,\n  \"editor.snippetSuggestions\": \"top\",\n  \"editor.trimAutoWhitespace\": true,\n  \"editor.useTabStops\": true,\n  \"editor.scrollBeyondLastLine\": true,\n  \"editor.showFoldingControls\": \"always\",\n  \"emmet.triggerExpansionOnTab\": true,\n  \"emmet.includeLanguages\": {\n    \"html.erb\": \"html\",\n    \"erb\": \"html\"\n  },\n  \"files.associations\": {\n    \"*.html.erb\": \"erb\"\n  },\n  \"[ruby]\": {\n    \"editor.defaultFormatter\": \"Shopify.ruby-lsp\"\n  },\n  \"rubyLsp.enabledFeatures\": {\n    \"diagnostics\": false\n  },\n  \"[javascript]\": {\n    \"editor.defaultFormatter\": \"dbaeumer.vscode-eslint\",\n    \"editor.codeActionsOnSave\": {\n      \"source.fixAll.eslint\": \"explicit\"\n    }\n  },\n  \"tailwindCSS.includeLanguages\": {\n    \"erb\": \"html\"\n  },\n  \"tailwindCSS.emmetCompletions\": true,\n  \"tailwindCSS.validate\": true,\n  \"yaml.schemas\": {\n    \"lib/schemas/cfps_schema.json\": \"data/**/cfp.yml\",\n    \"lib/schemas/event_schema.json\": \"data/**/event.yml\",\n    \"lib/schemas/schedule_schema.json\": \"data/**/schedule.yml\",\n    \"lib/schemas/tiers_sponsors_schema.json\": \"data/**/sponsors.yml\",\n    \"lib/schemas/venue_schema.json\": \"data/**/venue.yml\",\n    \"lib/schemas/videos_schema.json\": \"**/videos.yml\",\n  }\n}"
  },
  {
    "path": "CLAUDE.md",
    "content": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Common Development Commands\n\n### Setup & Development\n\n- `bin/setup` - Full setup including database seeding via docker-compose\n- `bin/dev` - Start Rails server, SolidQueue jobs, and Vite (for CSS/JS)\n- `bin/lint` - Run all formatters and linters (StandardRB, JS Standard, ERB lint, YAML prettier)\n- `bin/rails db:seed` - Seed database with conference data manually\n- `bin/rails db:seed:all` - Seed database with all conference data manually\n\n### Testing\n\n- `bin/rails test` - Run the full test suite (uses Minitest)\n- `bin/rails test test/system/` - Run system tests\n- `bin/rails test test/models/speaker_test.rb` - Run specific test file\n\n### Linting & Formatting\n\n- `bundle exec standardrb --fix` - Fix Ruby formatting issues\n- `yarn format` - Fix JavaScript formatting\n- `bundle exec erb_lint --lint-all --autocorrect` - Fix ERB templates\n- `yarn format:yml` - Format YAML files in data/ directory\n\n### Jobs & Search\n\n- `bin/jobs` - Start SolidQueue job worker\n- Search reindexing happens automatically in test setup\n\n## Architecture Overview\n\n### Core Models & Relationships\n\n- **Event**: Ruby conferences/meetups (belongs_to EventSeries)\n- **Talk**: Conference presentations (belongs_to Event, has_many SpeakerTalks)\n- **Speaker**: Presenters (has_many SpeakerTalks, has social media fields)\n- **EventSeries**: Conference series/organizers (has_many Events)\n- **Topic**: AI-extracted talk topics (has_many TalkTopics)\n- **WatchList**: User-curated lists (belongs_to User, has_many WatchListTalks)\n\n### Data Structure\n\nConference data is stored in YAML files under `/data/`:\n\n- `data/speakers.yml` - Global speaker database\n- `data/{series-slug}/series.yml` - Event series metadata (conference organizers/series)\n- `data/{series-slug}/{event-name}/event.yml` - Event metadata (dates, location, colors, etc.)\n- `data/{series-slug}/{event-name}/videos.yml` - Individual talk data\n- `data/{series-slug}/{event-name}/schedule.yml` - Event schedules\n\n### Technology Stack\n\n- **Backend**: Rails 8.0, SQLite, Solid Queue, Solid Cache\n- **Frontend**: Vite, Tailwind CSS, daisyUI, Stimulus\n- **Admin**: Avo admin panel at `/admin`\n- **Authentication**: Custom session-based auth with GitHub OAuth\n- **Deployment**: Kamal on Hetzner VPS\n\n### Key Components\n\n- **View Components**: Located in `app/components/`, follows ViewComponent pattern\n- **Clients**: API clients for YouTube, GitHub, BlueSky in `app/clients/`\n- **Search**: Full-text search for Talks and Speakers using Sqlite virtual tables\n- **Jobs**: Background processing for video statistics, transcripts, AI summarization\n- **Analytics**: Page view tracking with Ahoy\n\n### Authentication & Authorization\n\n- Custom `Authenticator` module provides role-based route constraints\n- Admin access required for Avo admin panel and Mission Control Jobs\n- GitHub OAuth integration for user registration\n- Session-based authentication (not JWT)\n\n### Notable Conventions\n\n- Uses slug-based routing for SEO-friendly URLs\n- Talks support multiple video providers (YouTube, Vimeo, etc.)\n- AI-powered features: transcript enhancement, topic extraction, summarization\n- Responsive design with mobile-first approach\n- Canonical references to deduplicate speakers/events/topics\n\n### Testing Setup\n\n- Uses Minitest (not RSpec)\n- VCR for API mocking\n- Parallel test execution\n- Search indexes are reset in test setup\n- System tests use Capybara with Selenium\n\n### Data Import Flow\n\n1. YAML files define conference structure\n2. Rake tasks process video metadata\n3. Background jobs fetch additional data (transcripts, statistics)\n4. AI services enhance content (summaries, topics)\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Welcome to RubyEvents.org!\n\nWelcome to RubyEvents.org, and thank you for contributing your time and energy to improving the platform.\nWe're on a mission to index all ruby events and video talks, and we need your help to do it!\n\nA great way to get started is adding new events and content.\nWe have a page on the deployed site that has up-to-date information with the remaining known TODOs.\nCheck out the [\"Getting Started: Ways to Contribute\" page on RubyEvents.org](https://www.rubyevents.org/contributions) and feel free to start working on any of the remaining TODOs.\nAny help is greatly appreciated.\n\nAll contributors are expected to abide by the [Code of Conduct](/CODE_OF_CONDUCT.md).\n\n## Getting Started\n\nWe have tried to make the setup process as simple as possible so that in a few commands you can have the project with real data running locally.\n\n### Devcontainers\n\nIn addition to the local development flow described below, we support [devcontainers](https://containers.dev) and [codespaces](https://github.com/features/codespaces).\nIf you open this project in VS Code and you have the [dev containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) installed, it will prompt you and ask if you want to reopen in a dev container.\nThis will set up the dev environment for you in docker, and reopen your editor from within the context of the rails container, so you can run commands and work with the project as if it was local.\nAll file changes will be present locally when you close the container.\n\n- Clone RubyEvents with https, it tends to behave better, and new `gh auth login` commands won't generate new ssh keys.\n- If you cannot fetch or push, use `gh auth login` to auth with GitHub.\n- After the container is set up, run `bin/dev` in the terminal to start the development server. The application will be forwarded to [localhost:3000](localhost:3000).\n- To run system tests, use `HEADLESS=true bin/rails test`. The HEADLESS=true environment variable ensures Chrome runs in headless mode, which is required in the container environment.\n\nIf the ruby version is updated, or you start running into issues, feel free to toss and rebuild the container.\n\n### Local Dev Setup\n\n#### Requirements\n\n- Ruby 4.0.1\n- Node.js 22.15.1\n\n#### Setup\n\nTo install dependencies and prepare the database run:\n\n```\nbin/setup\n```\n\nThis will seed the database with all speakers, meetups, the last 6 months of events, and all future events.\n\nTo load all historical data, run:\n\n```\nbin/rails db:seed:all\n```\n\n### Environment Variables\n\nYou can use the `.env.sample` file as a guide for the environment variables required for the project.\nHowever, there are currently no environment variables necessary for simple app exploration.\n\n### Starting the Application\n\nThe following command will start Rails, SolidQueue and Vite (for CSS and JS).\n\n```\nbin/dev\n```\n\n## Linter\n\nThe CI performs these checks:\n\n- erblint\n- standardrb\n- standard (js)\n- prettier (yaml)\n\nBefore committing your code you can run `bin/lint` to detect and potentially autocorrect lint errors and validate schemas.\n\nTo follow Tailwind CSS's recommended order of classes, you can use [Prettier](https://prettier.io/) along with the [prettier-plugin-tailwindcss](https://github.com/tailwindlabs/prettier-plugin-tailwindcss), both of which are included as devDependencies. This formatting is not yet enforced by the CI.\n\n### Typesense (Optional)\n\nThe application uses [Typesense](https://typesense.org/) for enhanced search functionality (spotlight search). Typesense is **optional** for local development. The app works without it, falling back to SQLite FTS5 for search.\n\n**Devcontainers / Docker Compose:** Typesense is included and starts automatically.\n\n**Local development:** Run Typesense with Docker:\n\n```bash\ndocker compose -f docker-compose.typesense.yml up -d\n```\n\nCheck the status of the search backends and if you can connect.\n\n```bash\nbundle exec rake search:status\n```\n\nOnce running, you can reindex the data:\n\n```bash\nbin/rails search:reindex\n```\n\nUseful search commands:\n\n```bash\nbin/rails search:status       # Show status of all search backends\nbin/rails typesense:health    # Check if Typesense is running\nbin/rails typesense:stats     # Show Typesense index statistics\nbin/rails typesense:reindex   # Full reindex of Typesense collections\nbin/rails sqlite_fts:reindex  # Rebuild SQLite FTS indexes\n```\n\n#### Environment Variables\n\nConfigure Typesense via environment variables in your `.env` file:\n\n**Local development (single node):**\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `TYPESENSE_HOST` | `localhost` | Typesense server host |\n| `TYPESENSE_PORT` | `8108` | Typesense server port |\n| `TYPESENSE_PROTOCOL` | `http` | Protocol to use |\n| `TYPESENSE_API_KEY` | `xyz` | Your Typesense API key |\n\n**Typesense Cloud with Search Delivery Network (SDN):**\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `TYPESENSE_NODES` | - | Comma-separated list of node hosts (e.g., `xxx-1.a1.typesense.net,xxx-2.a1.typesense.net,xxx-3.a1.typesense.net`) |\n| `TYPESENSE_NEAREST_NODE` | - | SDN nearest node hostname (e.g., `xxx.a1.typesense.net`) |\n| `TYPESENSE_PORT` | `443` | Typesense server port |\n| `TYPESENSE_PROTOCOL` | `https` | Protocol to use |\n| `TYPESENSE_API_KEY` | - | Your Typesense Admin API key |\n\n**Other options:**\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `SEARCH_INDEX_ON_IMPORT` | `true` | Whether to update search indexes when importing data from YAML files. Set to `false` to skip indexing during imports (useful for bulk imports followed by a full reindex) |\n\nFor local development with Docker, the defaults work out of the box. For production with Typesense Cloud, set `TYPESENSE_NODES` and `TYPESENSE_NEAREST_NODE` to enable the SDN configuration.\n\n## Running the Database Seeds\n\nAfter adding or modifying data, seed the database to see your changes.\nIf you are running the dev server, Guard will attempt to import for you on modification.\nBut if you are not running the dev server, or run into issues - use the seeds.\n\nThis will seed the last 6 months of conferences, and all future events and meetups.\n\n```bash\nbin/rails db:seed\n```\n\nThis will seed all data and is what we use in production.\n\n```bash\nbin/rails db:seed:all\n```\n\nImport one event series and all included events.\n\n```bash\nbin/rails db:seed:event_series[blue-ridge-ruby]\n```\n\nYou can also seed one event series with a script.\nThis will let you search and select the series.\n\n```bash\nrails runner scripts/import_event.rb blue-ridge-ruby\n# Search for a series\nrails runner scripts/import_event.rb\n```\n\nImport all events and event data (but not the series or anything else).\nThis one is good if you're updating a lot of events at once and backfilling data.\nFor example, adding coordinates, venues, involvements, sponsors, etc.\nIt will error if there's a new series (or old one because you haven't run `db:seed:all` yet).\n\n```bash\nbin/rails db:seed:events\n```\n\nImport all speakers. Great for testing profile changes.\n\n```bash\nbin/rails db:seed:speakers\n```\n\n### Troubleshooting\n\nIf you encounter a ** Process memory map: ** error, close the dev server, run seeds, and restart.\n\n## Running Tests\n\nWe use minitest for all our testing.\n\nRun the full test suite with:\n\n```bash\nrails test\n```\n\nRun just one test using:\n\n```bash\nrails test test/models/talk_test.rb\n```\n\nRun just one example using:\n\n```bash\nrails test test/models/talk_test.rb:6\n```\n\n## UI\n\nFor the front-end, we use [Vite](https://vite.dev/), [Tailwind CSS](https://tailwindcss.com/) with [Daisyui](https://daisyui.com/) components, [Hotwire](https://hotwired.dev/), and [Stimulus](https://stimulus.hotwired.dev/).\n\nYou can find existing RubyEvents components in our [component library](https://www.rubyevents.org/components).\n\n## Queue\n\nWe use SolidQueue!\n\nOpen the rails console and run the following to clear the queue.\n\n```\nSolidQueue::Queue.new(\"default\").clear\n```\n\nGet a count of enqueued jobs.\n\n```\nSolidQueue::Queue.new(\"default\").size\n```\n\n## Contributing new events\n\nDiscovering and documenting new Ruby events is an ongoing effort, and a fantastic way to get familiar with the codebase!\n\nAll conference data is stored in the `/data` folder with the following structure:\n\n```\ndata/\n├── speakers.yml                    # Global speaker database\n├── railsconf/                      # Series folder\n│   ├── series.yml                  # Series metadata\n│   ├── railsconf-2023/             # Event folder\n│   │   ├── event.yml               # Event metadata\n│   │   ├── videos.yml              # Talk data\n│   │   ├── schedule.yml            # Optional schedule\n│   │   ├── sponsors.yml            # Optional sponsors data\n│   │   └── venue.yml               # Optional venue\n│   └── railsconf-2024/\n│       ├── event.yml\n│       └── videos.yml\n└── rubyconf/\n    ├── series.yml\n    └── ...\n```\n\nA conference series (`series.yml`) describes a series of events.\nEach folder represents a different instance of that event, and must contain an `event.yml`.\n\nThe schema for each file is located in `/app/schemas`.\n\nIf the YouTube videos for an event are available, you can [create events with a script](docs/ADDING_VIDEOS.md).\nOtherwise, you can [create the event or event series manually](docs/ADDING_EVENTS.md).\n\nThere are additional guides for adding optional information:\n\n- [visual assets](/docs/ADDING_VISUAL_ASSETS.md)\n- [videos](/docs/ADDING_VIDEOS.md)\n- [schedules](/docs/ADDING_SCHEDULES.md)\n- [sponsors](/docs/ADDING_SPONSORS.md)\n- [venues](/docs/ADDING_VENUES.md)\n\nIf you have questions about contributing events:\n\n- Open an issue on GitHub\n- Check existing event files for examples\n- Reference this documentation\n\nYour contributions help make RubyEvents a comprehensive resource for the Ruby community!\n"
  },
  {
    "path": "Dockerfile",
    "content": "# syntax=docker/dockerfile:1\n# check=error=true\n\n# This Dockerfile is designed for production, not development. Use with Kamal or build'n'run by hand:\n# docker build -t rubyevents .\n# docker run -d -p 80:80 -e RAILS_MASTER_KEY=<value from config/master.key> --name rubyevents rubyevents\n\n# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html\n\n# Make sure RUBY_VERSION matches the Ruby version in .ruby-version\nARG RUBY_VERSION=4.0.1\nFROM docker.io/library/ruby:$RUBY_VERSION-slim AS base\n\n# Rails app lives here\nWORKDIR /rails\n\n# Install base packages\nRUN apt-get update -qq && \\\n    apt-get install --no-install-recommends -y curl imagemagick libjemalloc2 libvips sqlite3 && \\\n    rm -rf /var/lib/apt/lists /var/cache/apt/archives\n\n# Set production environment\nENV RAILS_ENV=\"production\" \\\n    BUNDLE_DEPLOYMENT=\"1\" \\\n    BUNDLE_PATH=\"/usr/local/bundle\" \\\n    BUNDLE_WITHOUT=\"development\"\n\n# Throw-away build stage to reduce size of final image\nFROM base AS build\n\n# Install packages needed to build gems and node modules\nRUN apt-get update -qq && \\\n    apt-get install --no-install-recommends -y build-essential git node-gyp pkg-config libyaml-dev python-is-python3 && \\\n    rm -rf /var/lib/apt/lists /var/cache/apt/archives\n\n# Install JavaScript dependencies\nARG NODE_VERSION=22.15.1\nARG YARN_VERSION=1.22.22\nENV PATH=/usr/local/node/bin:$PATH\nRUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \\\n    /tmp/node-build-master/bin/node-build \"${NODE_VERSION}\" /usr/local/node && \\\n    npm install -g yarn@$YARN_VERSION && \\\n    rm -rf /tmp/node-build-master\n\n# Install application gems\nCOPY Gemfile Gemfile.lock .ruby-version ./\nRUN bundle install && \\\n    rm -rf ~/.bundle/ \"${BUNDLE_PATH}\"/ruby/*/cache \"${BUNDLE_PATH}\"/ruby/*/bundler/gems/*/.git && \\\n    bundle exec bootsnap precompile --gemfile\n\n# Install node modules\nCOPY package.json yarn.lock ./\nRUN yarn install --frozen-lockfile\n\n# Copy application code\nCOPY . .\n\n# Precompile bootsnap code for faster boot times\nRUN bundle exec bootsnap precompile app/ lib/\n\n# Precompiling assets for production without requiring secret RAILS_MASTER_KEY\nRUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile\n\n\nRUN rm -rf node_modules\n\n\n# Final stage for app image\nFROM base\n\n# Copy built artifacts: gems, application\nCOPY --from=build \"${BUNDLE_PATH}\" \"${BUNDLE_PATH}\"\nCOPY --from=build /rails /rails\n\n# Run and own only the runtime files as a non-root user for security\nRUN groupadd --system --gid 1000 rails && \\\n    useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \\\n    chown -R rails:rails db log storage tmp\nUSER 1000:1000\n\n# Entrypoint prepares the database.\nENTRYPOINT [\"/rails/bin/docker-entrypoint\"]\n\n# Start server via Thruster by default, this can be overwritten at runtime\nEXPOSE 80\nCMD [\"./bin/thrust\", \"./bin/rails\", \"server\"]\n"
  },
  {
    "path": "Gemfile",
    "content": "source \"https://rubygems.org\"\ngit_source(:github) { |repo| \"https://github.com/#{repo}.git\" }\n\nruby file: \".ruby-version\"\n\n# Use Rails edge\ngem \"rails\", github: \"rails/rails\"\n\n# The modern asset pipeline for Rails [https://github.com/rails/propshaft]\ngem \"propshaft\"\n\n# Use sqlite3 as the database for Active Record\ngem \"sqlite3\", \">= 2.1.0\"\n\n# Use the Puma web server [https://github.com/puma/puma]\ngem \"puma\"\n\n# use jbuilder for the api\ngem \"jbuilder\"\n\n# Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails]\n# gem \"jsbundling-rails\"\n\n# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]\ngem \"turbo-rails\"\n\n# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev]\n# gem \"stimulus-rails\"\n\n# Bundle and process CSS [https://github.com/rails/cssbundling-rails]\n# gem \"cssbundling-rails\"\n\n# Use Redis adapter to run Action Cable in production\n# gem \"redis\", \">= 4.0.1\"\n\n# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]\n# gem \"kredis\"\n\n# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]\ngem \"bcrypt\", \"~> 3.1.7\"\n\n# Windows does not include zoneinfo files, so bundle the tzinfo-data gem\ngem \"tzinfo-data\", platforms: %i[windows jruby]\n\n# Reduces boot times through caching; required in config/boot.rb\ngem \"bootsnap\", require: false\n\n# Deploy this application anywhere as a Docker container [https://kamal-deploy.org]\ngem \"kamal\", \"2.7.0\", require: false\n\n# Add HTTP asset caching/compression and X-Sendfile acceleration to Puma [https://github.com/basecamp/thruster/]\ngem \"thruster\", require: false\n\n# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]\ngem \"image_processing\", \"~> 1.2\"\n\n# Image processing for event asset generation\ngem \"mini_magick\"\n\n# All sorts of useful information about every country packaged as convenient little country objects\ngem \"countries\"\n\n# ISO 639-1 and ISO 639-2 language code entries and convenience methods\ngem \"iso-639\"\n\n# A minimal client of Bluesky/ATProto API\ngem \"minisky\", \"~> 0.4.0\"\n\n# Extract Collaborator Objects from your Active Records, a new concept called Associated Objects\ngem \"active_record-associated_object\"\n\n# Headless Chrome driver for Capybara\ngem \"cuprite\"\n\n# Reusable modules for tasks like data extraction, scoring, and ranking\ngem \"active_genie\"\n\n# A single delightful Ruby way to work with AI.\ngem \"ruby_llm\", \"~> 1.9.1\"\n\n# A simple and clean Ruby DSL for creating JSON schemas.\ngem \"ruby_llm-schema\"\n\n# JSON Schema validator\ngem \"json_schemer\"\n\n# YouTube V3 API client.\ngem \"yt\"\n\n# Family of libraries that support various formats of XML \"feeds\".\ngem \"rss\", \"~> 0.3.1\"\n\n# Powerful and seamless HTML-aware ERB parsing and tooling.\ngem \"herb\", \"~> 0.9\"\n\n# An ActionView-compatible ERB engine with modern DX - re-imagined with Herb.\ngem \"reactionview\", \"~> 0.3\"\n\n# Agnostic pagination in plain ruby.\ngem \"pagy\"\n\n# gem \"activerecord-enhancedsqlite3-adapter\"\ngem \"solid_cache\"\n\n# Database-backed Active Job backend.\ngem \"solid_queue\", github: \"joshleblanc/solid_queue\", branch: \"async-mode\"\n\n# Operational controls for Active Job\ngem \"mission_control-jobs\"\n\n# Simple, powerful, first-party analytics for Rails\ngem \"ahoy_matey\"\n\n# The simplest way to group temporal data\ngem \"groupdate\"\n\n# Create beautiful JavaScript charts with one line of Ruby\ngem \"chartkick\", \"~> 5.0\"\n\n# Use Vite in Rails and bring joy to your JavaScript experience\ngem \"vite_rails\"\n\n# Collection of SEO helpers for Ruby on Rails.\ngem \"meta-tags\"\n\n# Logs performance and exception data from your app to appsignal.com\ngem \"appsignal\"\n\n# Autoload dotenv in Rails.\ngem \"dotenv-rails\"\n\n# Automatic generation of html links in texts\ngem \"rails_autolink\", \"~> 1.1\"\n\n# Easily generate XML Sitemaps\ngem \"sitemap_generator\", \"~> 6.3\"\n\n# A framework for building reusable, testable & encapsulated view components\ngem \"view_component\"\n\n# Adds ActiveRecord-specific methods to Dry::Initializer\ngem \"dry-initializer-rails\"\n\n# Type system for Ruby supporting coercions, constraints and complex types\ngem \"dry-types\", \"~> 1.7\"\n\n# Protocol Buffers are Google's data interchange format.\ngem \"google-protobuf\", require: false\n\n# ActiveJob::Performs adds the `performs` macro to set up jobs by convention.\ngem \"active_job-performs\"\n\n# Use the OpenAI API with Ruby!\ngem \"ruby-openai\"\n\n# Repairs broken JSON strings.\ngem \"json-repair\", \"~> 0.2.0\"\n\n# Markdown that smells nice\ngem \"redcarpet\", \"~> 3.6\"\n\n# Syntax highlighting\ngem \"rouge\", \"~> 4.4\"\n\n# Country Select Plugin\ngem \"country_select\"\n\n# Admin panel framework and Content Management System for Ruby on Rails.\ngem \"avo\"\n\ngroup :avo, optional: true do\n  gem \"avo-pro\", source: \"https://packager.dev/avo-hq/\"\nend\n\n# Marksmith is a GitHub-style markdown editor for Ruby on Rails applications.\ngem \"marksmith\"\n\n# A fast, safe, extensible parser for CommonMark. This wraps the comrak Rust crate.\ngem \"commonmarker\", \">= 2.6.1\"\n\n# ActiveRecord like interface to read only access and query static YAML files\ngem \"frozen_record\", \"~> 0.27.2\"\n\n# A convenient way to diff string in ruby\ngem \"diffy\"\n\n# ActiveRecord soft-deletes done right\ngem \"discard\"\n\n# Makes consuming restful web services dead easy.\ngem \"httparty\"\n\n# Use OmniAuth to support multi-provider authentication [https://github.com/omniauth/omniauth]\ngem \"omniauth\"\n\n# Official OmniAuth strategy for GitHub.\ngem \"omniauth-github\"\n\n# Provides a mitigation against CVE-2015-9284 [https://github.com/cookpad/omniauth-rails_csrf_protection]\ngem \"omniauth-rails_csrf_protection\"\n\n# An accessible autocomplete for Ruby on Rails apps using Hotwire.\ngem \"hotwire_combobox\", \"~> 0.4.0\"\n\n# Common locale data and translations for Rails i18n.\ngem \"rails-i18n\", \"~> 8.0\"\n\n# Ruby standards gems\ngem \"openssl\" # https://github.com/ruby/openssl/issues/949\n\n# Class to build custom data structures, similar to a Hash.\ngem \"ostruct\"\n\n# Complete geocoding solution for Ruby.\ngem \"geocoder\", github: \"alexreisner/geocoder\" # Use latest geocoder with Nominatim improvements until next release\n\n# RubyGems.org API wrapper for gem information\ngem \"gems\"\n\n# A glamorous CLI toolkit for Ruby\ngem \"gum\", \"~> 0.3.1\"\n\n# Regex pattern searching in files\ngem \"grepfruit\"\n\n# Create beautiful JavaScript maps with one line of Ruby\ngem \"mapkick-rb\", \"~> 0.2.0\"\n\n# Typesense Ruby client\ngem \"typesense\", \"~> 4.1\"\n\n# Typesense integration to your favorite ORM\ngem \"typesense-rails\", \"~> 1.0.0.rc4\"\n\ngroup :development, :test do\n  # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem\n  gem \"bundler-audit\", require: false\n  gem \"debug\", platforms: %i[mri windows]\n  gem \"byebug\"\n  gem \"minitest-difftastic\", \"~> 0.2\"\nend\n\ngroup :development do\n  # A gem for generating annotations for Rails projects.\n  gem \"annotaterb\"\n\n  # Use console on exceptions pages [https://github.com/rails/web-console]\n  gem \"web-console\"\n\n  # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler]\n  gem \"rack-mini-profiler\"\n\n  # For call-stack profiling flamegraphs\n  gem \"stackprof\"\n\n  # Speed up commands on slow machines / big apps [https://github.com/rails/spring]\n  # gem \"spring\"\n\n  # Use listen to watch files for changes [https://github.com/guard/listen]\n  gem \"listen\", \"~> 3.5\"\n\n  # Guard for watching file changes and auto-importing [https://github.com/guard/guard]\n  gem \"guard\"\n\n  gem \"ruby-lsp-rails\", require: false\n  gem \"standardrb\", \"~> 1.0\", require: false\n  gem \"erb_lint\", require: false\n  gem \"authentication-zero\", require: false\nend\n\ngroup :test do\n  # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]\n  gem \"capybara\"\n  gem \"rails-controller-testing\"\n  gem \"selenium-webdriver\"\n  gem \"vcr\", \"~> 6.1\"\n  gem \"webmock\"\nend\n"
  },
  {
    "path": "Guardfile",
    "content": "# Guardfile for watching YAML files in data/ and auto-importing them\n\nrequire_relative \"lib/guard/data_import\"\n\nguard :data_import, wait_for_delay: 2 do\n  watch(%r{^data/speakers\\.yml$})\n  watch(%r{^data/topics\\.yml$})\n  watch(%r{^data/featured_cities\\.yml$})\n  watch(%r{^data/[^/]+/series\\.yml$})\n  watch(%r{^data/[^/]+/[^/]+/event\\.yml$})\n  watch(%r{^data/[^/]+/[^/]+/videos\\.yml$})\n  watch(%r{^data/[^/]+/[^/]+/cfp\\.yml$})\n  watch(%r{^data/[^/]+/[^/]+/sponsors\\.yml$})\n  watch(%r{^data/[^/]+/[^/]+/schedule\\.yml$})\nend\n"
  },
  {
    "path": "Procfile.dev",
    "content": "web: bin/rails server -b 0.0.0.0\nvite: bin/vite dev\njobs: bin/jobs\n# guard: bundle exec guard --no-interactions\n"
  },
  {
    "path": "README.md",
    "content": "# RubyEvents.org (formerly RubyVideo.dev)\n\n[RubyEvents.org](https://www.rubyevents.org) (formerly RubyVideo.dev), inspired by [pyvideo.org](https://pyvideo.org/), is designed to index all Ruby-related events and videos from conferences and meetups around the world. At the time of writing, the project has 6000+ videos indexed from 200+ events and 3000+ speakers.\n\nTechnically the project is built using the latest [Ruby](https://www.ruby-lang.org/) and [Rails](https://rubyonrails.org/) goodies such as [Hotwire](https://hotwired.dev/), [Solid Queue](https://github.com/rails/solid_queue), [Solid Cache](https://github.com/rails/solid_cache).\n\nFor the front end part we use [Vite](https://vite.dev/), [Tailwind](https://tailwindcss.com/) with [daisyUI](https://daisyUI.com/) components and [Stimulus](https://stimulus.hotwire.dev/).\n\nIt is deployed on an [Hetzner](https://hetzner.cloud/?ref=gyPLk7XJthjg) VPS with [Kamal](https://kamal-deploy.org/) using [SQLite](https://www.sqlite.org/) as the main database.\n\nFor compatible browsers it tries to demonstrate some of the possibilities of [Page View Transition API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API).\n\n## Contributing\n\nThis project is open source, and contributions are greatly appreciated. One of the most direct ways to contribute at this time is by adding more content.\n\nWe also have a page on the deployed site that has up-to-date information with the remaining known TODOs. Check out the [\"Getting Started: Ways to Contribute\" page on RubyEvents.org](https://www.rubyevents.org/contributions) and feel free to start working on any of the remaining TODOs. Any help is greatly appreciated.\n\nFor more information on contributing, see the [Contributing Guide](/CONTRIBUTING.md).\n\n## Code of Conduct\n\nPlease note that this project is released with a Contributor Code of Conduct. By participating in this project, you agree to abide by its terms. More details can be found in the [Code of Conduct](/CODE_OF_CONDUCT.md) document.\n\n## Credits\n\nThank you [AppSignal](https://appsignal.com/r/eeab047472) for providing the APM tool that helps us monitor the application.\n\nThank you [Typesense](https://typesense.org/) for sponsoring our [Typesense Cloud](https://cloud.typesense.org/) instance that powers the search functionality.\n\n## License\n\nRubyEvents.org is open source and available under the MIT License. For more information, please see the [License](/LICENSE.md) file.\n"
  },
  {
    "path": "Rakefile",
    "content": "# Add your own tasks in files placed in lib/tasks ending in .rake,\n# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.\n\nrequire_relative \"config/application\"\n\nRails.application.load_tasks\n"
  },
  {
    "path": "app/assets/builds/.keep",
    "content": ""
  },
  {
    "path": "app/assets/stylesheets/application.css",
    "content": "@import \"tailwindcss/base\";\n@import \"tailwindcss/components\";\n@import \"tailwindcss/utilities\";\n\n@import \"components/button.css\";\n@import \"components/diff.css\";\n@import \"components/dropdown.css\";\n@import \"components/event.css\";\n@import \"components/form.css\";\n@import \"components/hotwire-combobox.css\";\n@import \"components/markdown.css\";\n@import \"components/modal.css\";\n@import \"components/nav.css\";\n@import \"components/pagination.css\";\n@import \"components/tabs.css\";\n@import \"components/skeleton.css\";\n@import \"components/spotlight.css\";\n@import \"components/transition.css\";\n@import \"components/typography.css\";\n@import \"components/video.css\";\n@import \"components/iframe.css\";\n\n@import \"vlitejs/vlite.css\";\n\n@import \"bridge/components\";\n@import \"flag-icons/css/flag-icons.min.css\";\n\nturbo-frame[id^=\"browse-\"][complete] {\n  display: contents;\n}\n"
  },
  {
    "path": "app/assets/stylesheets/bridge/components.css",
    "content": "html[data-bridge-platform] {\n  user-select: none;\n}\n\n[data-bridge-components~=\"button\"] [data-controller~=\"bridge--button\"] {\n  display: none;\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/button.css",
    "content": "@layer components {\n  .btn {\n    @apply fill-current;\n  }\n\n  .btn:not(.btn-sm) {\n    height: 2.5rem;\n    min-height: 2.5rem;\n  }\n\n  .btn-rounded {\n    @apply btn-outline rounded-full border border-gray-400 bg-white hover:border-gray-500 hover:bg-gray-100 hover:text-base-content/80;\n  }\n\n  .btn-circle {\n    @apply btn-rounded;\n    @apply h-10 w-10;\n  }\n\n  /* for the toolbar buttons */\n  .btn.btn-pill {\n    @apply btn-rounded btn-outline;\n    @apply flex-nowrap whitespace-nowrap;\n\n    /* for the watched button */\n    &.active {\n      @apply border-primary bg-primary text-primary-content;\n    }\n\n    &.btn-sm {\n      @apply text-sm font-normal;\n    }\n  }\n\n  .btn.btn-secondary {\n    @apply whitespace-nowrap border-primary bg-white fill-primary text-primary hover:bg-gray-100 hover:text-primary/90;\n  }\n\n  .btn.btn-neutral {\n    @apply bg-white hover:fill-neutral/80 hover:text-neutral/80;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/diff.css",
    "content": "@layer components {\n  .diff {\n    del {\n      @apply text-error;\n    }\n\n    ins {\n      @apply text-success;\n    }\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/dropdown.css",
    "content": "@layer components {\n  details > summary {\n    list-style: none;\n  }\n\n  /* fix the dropdown button to links, by default daisyui adds padding to the form element */\n  /* therefore the inner button does not fill the dropdown item */\n  /* and only the text of the button is clickable */\n  .menu li form.button_to {\n    padding: 0;\n    display: block;\n  }\n\n  .menu li form.button_to button {\n    display: block;\n    width: 100%;\n    text-align: start;\n    padding: 0.5rem 1rem;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/event.css",
    "content": "@layer components {\n  .event-card.cancelled,\n  .card.cancelled {\n    opacity: 0.5;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/form.css",
    "content": "@layer components {\n  label {\n    @apply font-semibold;\n  }\n\n  /* because setting --rounded-btn to 1.9rem makes also all input field fully rounded  */\n  /* we override this behaviour */\n  .input,\n  .textarea {\n    @apply rounded-lg border border-gray-200 bg-white;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/hotwire-combobox.css",
    "content": "@layer components {\n  .hw-combobox__main__wrapper {\n    @apply min-h-12;\n  }\n\n  .hw-combobox__main__wrapper:has(input:focus) {\n    box-shadow: none;\n    border-color: var(--fallback-bc, oklch(var(--bc)/0.2));\n    outline-style: solid;\n    outline-width: 2px;\n    outline-offset: 2px;\n    outline-color: var(--fallback-bc, oklch(var(--bc)/0.2));\n  }\n\n  .hw-combobox__main__wrapper input:focus {\n    box-shadow: none;\n    border-color: none;\n    outline-style: none;\n    outline-color: none;\n  }\n\n  :root {\n    --hw-focus-color: rgb(var(--fallback-bc));\n    --hw-combobox-width: 100%;\n    --hw-combobox-width--multiple: 100%;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/iframe.css",
    "content": "@layer components {\n  .responsive-iframe-container iframe {\n    width: 100%;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/markdown.css",
    "content": "@layer components {\n  .markdown {\n    p {\n      @apply mb-2;\n    }\n\n    h1,\n    h2,\n    h3,\n    h4,\n    h5,\n    h6 {\n      @apply mb-4 mt-8;\n    }\n\n    h1,\n    h2,\n    h3 {\n      @apply text-primary;\n    }\n\n    ul {\n      @apply mb-4;\n      li {\n        @apply ml-6 list-disc;\n      }\n    }\n\n    ol {\n      @apply mb-4;\n      li {\n        @apply ml-6 list-decimal;\n      }\n    }\n\n    a {\n      @apply text-primary;\n    }\n\n    /* Tables */\n    table {\n      @apply w-full border-collapse mb-4;\n    }\n\n    th,\n    td {\n      @apply border border-base-300 px-4 py-2 text-left;\n    }\n\n    th {\n      @apply bg-base-200 font-semibold;\n    }\n\n    tr:nth-child(even) {\n      @apply bg-base-200/50;\n    }\n\n    /* Code blocks - override prose styles */\n    pre {\n      @apply rounded-sm p-4 mb-4 overflow-x-auto text-base bg-base-200;\n      color: #24292e !important;\n    }\n\n    pre.highlight {\n      @apply bg-base-200;\n    }\n\n    pre code {\n      @apply text-sm;\n      color: inherit !important;\n      background: transparent !important;\n    }\n\n    /* Inline code */\n    :not(pre) > code {\n      @apply bg-base-200 px-1.5 py-0.5 rounded text-sm;\n      color: #24292e !important;\n    }\n\n    /* Rouge syntax highlighting - GitHub-like theme */\n    .highlight {\n      .c,\n      .c1,\n      .cm {\n        color: #6a737d;\n        font-style: italic;\n      } /* Comments */\n      .k,\n      .kd,\n      .kn,\n      .kp,\n      .kr,\n      .kt {\n        color: #d73a49;\n      } /* Keywords */\n      .s,\n      .s1,\n      .s2,\n      .sb,\n      .sc,\n      .sd,\n      .se,\n      .sh,\n      .si,\n      .sx {\n        color: #032f62;\n      } /* Strings */\n      .n,\n      .na,\n      .nb,\n      .nc,\n      .nd,\n      .ne,\n      .nf,\n      .ni,\n      .nl,\n      .nn,\n      .no,\n      .nt,\n      .nv {\n        color: #6f42c1;\n      } /* Names */\n      .mi,\n      .mf,\n      .mh,\n      .mo,\n      .il {\n        color: #005cc5;\n      } /* Numbers */\n      .o,\n      .ow {\n        color: #d73a49;\n      } /* Operators */\n      .p {\n        color: #24292e;\n      } /* Punctuation */\n      .cp {\n        color: #d73a49;\n      } /* Preprocessor */\n      .err {\n        color: #b31d28;\n        background-color: #ffeef0;\n      } /* Errors */\n    }\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/modal.css",
    "content": "@layer components {\n  .modal-box {\n    @apply bg-white;\n  }\n\n  .modal-top.spotlight {\n    .modal-box {\n      @apply absolute left-0 right-0 top-4 mx-4 w-auto rounded-lg lg:top-8 lg:mx-8;\n    }\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/nav.css",
    "content": "@layer components {\n  .desktop-menu {\n    @apply hidden gap-6 md:flex;\n\n    li,\n    title {\n      @apply m-0 inline-block;\n      div {\n        @apply invisible h-0.5 bg-primary;\n      }\n      &.active {\n        @apply relative;\n        & > div {\n          view-transition-name: navbar-active;\n          @apply visible absolute bottom-0 w-full font-bold;\n        }\n      }\n    }\n  }\n\n  .mobile-menu {\n    @apply flex md:hidden;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/pagination.css",
    "content": "@layer components {\n  nav.pagy.nav {\n    @apply mx-auto flex justify-normal gap-4 bg-transparent text-base-content sm:gap-8;\n\n    .current {\n      @apply font-semibold text-primary;\n    }\n\n    .page.disabled {\n      @apply text-base-300;\n    }\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/skeleton.css",
    "content": "@layer components {\n  .skeleton {\n    border-radius: inherit;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/spotlight.css",
    "content": "@layer components {\n  .modal-box.spotlight {\n    @apply max-w-full;\n  }\n\n  [role=\"option\"][aria-selected=\"true\"] {\n    @apply font-bold;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/tabs.css",
    "content": "@layer components {\n  /* https://github.com/saadeghi/daisyui/issues/2988 */\n  .tabs {\n    display: flex;\n    flex-wrap: wrap;\n  }\n  .tab {\n    order: 0;\n  }\n  .tab-content {\n    order: 1;\n    width: 100%;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/transition.css",
    "content": "@layer components {\n  ::view-transition-group(root) {\n    animation: none;\n    mix-blend-mode: normal;\n  }\n\n  .navbar {\n    view-transition-name: navbar;\n    contain: layout;\n  }\n\n  .banner-img .v-vlite {\n    contain: layout;\n  }\n\n  .card-horizontal-img img {\n    contain: layout;\n  }\n\n  .gallery img {\n    contain: layout;\n  }\n\n  @keyframes fade-in {\n    from {\n      opacity: 0;\n    }\n    to {\n      opacity: 1;\n    }\n  }\n\n  @keyframes fade-out {\n    from {\n      opacity: 1;\n    }\n    to {\n      opacity: 0;\n    }\n  }\n\n  ::view-transition-old(card-horizontal-img),\n  ::view-transition-new(card-horizontal-img) {\n    animation: none;\n    mix-blend-mode: normal;\n  }\n\n  ::view-transition-image-pair(card-horizontal-img) {\n    isolation: none;\n  }\n\n  ::view-transition-old(banner-img),\n  ::view-transition-new(banner-img) {\n    animation: none;\n    mix-blend-mode: normal;\n  }\n\n  ::view-transition-image-pair(banner-img) {\n    isolation: none;\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/typography.css",
    "content": "@import url(\"https://fonts.googleapis.com/css2?family=Nunito:wght@200..1000&display=swap\");\n\n:root {\n  font-family: Inter, sans-serif;\n  font-feature-settings: \"liga\" 1, \"calt\" 1; /* fix for Chrome */\n}\n@supports (font-variation-settings: normal) {\n  :root {\n    font-family: InterVariable, sans-serif;\n  }\n}\n\n@layer components {\n  body {\n    @apply bg-base-100 leading-relaxed text-base-content;\n  }\n\n  h1,\n  .h1 {\n    @apply font-serif text-3xl font-bold text-primary;\n  }\n\n  h2,\n  .h2 {\n    @apply font-serif text-xl  font-bold;\n  }\n\n  p.secondary {\n    @apply text-neutral-content;\n  }\n\n  a.link-ghost {\n    @apply hover:underline;\n    text-decoration: none;\n  }\n\n  mark {\n    /* search results highlight */\n    background-color: rgb(242, 255, 140);\n  }\n}\n"
  },
  {
    "path": "app/assets/stylesheets/components/video.css",
    "content": "@layer components {\n  .banner-img .v-vlite {\n    --vlite-controlsColor: #ffffff;\n    --vlite-controlsOpacity: 1;\n    --vlite-controlBarBackground: linear-gradient(0deg, #000 -50%, #fff);\n  }\n\n  .v-playbackRateSelect.v-controlButton {\n    color: var(--vlite-controlsColor);\n    text-align: center;\n  }\n\n  .v-loader {\n    display: none !important;\n  }\n\n  .v-bigPlay,\n  .v-overlay,\n  .v-poster {\n    display: none !important;\n  }\n\n  .v-openInYouTube.v-controlButton svg {\n    width: 65%;\n    fill: var(--vlite-controlsColor);\n  }\n\n  /* Picture in picture styling */\n  .picture-in-picture .picture-in-picture-container {\n    @apply sm:fixed sm:bottom-4 sm:right-4 sm:z-10 sm:h-auto sm:w-full sm:max-w-sm sm:rounded-xl xl:max-w-lg;\n    .v-video {\n      @apply rounded-xl;\n    }\n  }\n}\n"
  },
  {
    "path": "app/avo/actions/approve_topic.rb",
    "content": "class Avo::Actions::ApproveTopic < Avo::BaseAction\n  self.name = \"Publish Topic\"\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |record|\n      record.approved!\n    end\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/assign_canonical_event.rb",
    "content": "class Avo::Actions::AssignCanonicalEvent < Avo::BaseAction\n  self.name = \"Assign Canonical Event\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  def fields\n    field :event_id, as: :select, name: \"Canonical event\",\n      help: \"The name of the event to be set as canonical\",\n      options: -> { Event.order(:name).pluck(:name, :id) }\n  end\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    canonical_event = Event.find(fields[:event_id])\n\n    query.each do |record|\n      record.assign_canonical_event!(canonical_event: canonical_event)\n    end\n\n    succeed \"Assigning canonical event #{canonical_event.name} to #{query.count} events\"\n    redirect_to avo.resources_event_path(canonical_event)\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/assign_canonical_speaker.rb",
    "content": "class Avo::Actions::AssignCanonicalSpeaker < Avo::BaseAction\n  self.name = \"Assign Canonical Speaker\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  def fields\n    field :speaker_id, as: :select, name: \"Canonical speaker\",\n      help: \"The name of the speaker to be set as canonical\",\n      options: -> { User.speakers.order(:name).pluck(:name, :id) }\n  end\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    canonical_speaker = User.find(fields[:speaker_id])\n\n    query.each do |record|\n      record.assign_canonical_speaker!(canonical_speaker: canonical_speaker)\n    end\n\n    succeed \"Assigning canonical speaker #{canonical_speaker.name} to #{query.count} speakers\"\n    redirect_to avo.resources_user_path(canonical_speaker), status: :permanent_redirect\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/assign_canonical_topic.rb",
    "content": "class Avo::Actions::AssignCanonicalTopic < Avo::BaseAction\n  self.name = \"Assign Canonical Topic\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  def fields\n    field :topic_id, as: :select, name: \"Canonical topic\",\n      help: \"The name of the topic to be set as canonical\",\n      options: -> { Topic.approved.order(:name).pluck(:name, :id) }\n  end\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    canonical_topic = Topic.find(fields[:topic_id])\n\n    query.each do |record|\n      record.assign_canonical_topic!(canonical_topic: canonical_topic)\n    end\n\n    succeed \"Assigning canonical topic #{canonical_topic.name} to #{query.count} topics\"\n    redirect_to avo.resources_topic_path(canonical_topic)\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/assign_canonical_user.rb",
    "content": "class Avo::Actions::AssignCanonicalUser < Avo::BaseAction\n  self.name = \"Assign Canonical User\"\n\n  def fields\n    field :user_id, as: :select, name: \"Canonical user\",\n      help: \"The name of the speaker to be set as canonical\",\n      options: -> { User.order(:name).pluck(:name, :id) }\n  end\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    canonical_user = User.find(fields[:user_id])\n\n    query.each do |record|\n      record.assign_canonical_user!(canonical_user: canonical_user)\n    end\n\n    succeed \"Assigning canonical user #{canonical_user.name} to #{query.count} users\"\n    redirect_to avo.resources_user_path(canonical_user), status: :permanent_redirect\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/clear_user.rb",
    "content": "class Avo::Actions::ClearUser < Avo::BaseAction\n  self.name = \"Clear Suspicion\"\n  self.message = \"Mark this user as manually reviewed and not suspicious.\"\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |user|\n      user.clear_suspicion!\n    end\n\n    succeed \"Cleared suspicion for #{query.count} user(s).\"\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/enhance_transcript.rb",
    "content": "class Avo::Actions::EnhanceTranscript < Avo::BaseAction\n  self.name = \"Enhance Transcript\"\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |item|\n      talk = item.is_a?(Talk::Transcript) ? item.talk : item\n      talk.agents.improve_transcript_later\n    end\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/extract_topics.rb",
    "content": "class Avo::Actions::ExtractTopics < Avo::BaseAction\n  self.name = \"Extract Topics\"\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |talk|\n      talk.agents.analyze_topics_later\n    end\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/fetch_duration.rb",
    "content": "class Avo::Actions::FetchDuration < Avo::BaseAction\n  self.name = \"Fetch duration\"\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |record|\n      record.fetch_duration_from_youtube_later!\n    end\n\n    succeed \"Fetching the duration in the background\"\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/find_topic_talks.rb",
    "content": "class Avo::Actions::FindTopicTalks < Avo::BaseAction\n  self.name = \"Find Talks\"\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |topic|\n      topic.agents.find_talks_later\n    end\n\n    succeed \"Enqueued job to find talks for #{query.count} topic(s)\"\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/geocode_record.rb",
    "content": "class Avo::Actions::GeocodeRecord < Avo::BaseAction\n  self.name = \"Geocode location\"\n\n  def handle(query:, fields:, current_user:, resource:, records:, **args)\n    items = records.presence || query.to_a\n    perform_in_background = items.size >= 10\n    processed = 0\n    skipped = 0\n\n    model_name = items.first&.model_name&.human&.downcase || \"record\"\n\n    items.each do |record|\n      unless record.geocodeable?\n        skipped += 1\n        next\n      end\n\n      if perform_in_background\n        GeocodeRecordJob.perform_later(record)\n      else\n        GeocodeRecordJob.perform_now(record)\n      end\n\n      processed += 1\n    end\n\n    message = \"Geocoding #{perform_in_background ? \"enqueued\" : \"completed\"} for #{processed} #{model_name.pluralize(processed)}\"\n    message += \" (#{skipped} skipped without location)\" if skipped > 0\n    succeed message\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/reject_topic.rb",
    "content": "class Avo::Actions::RejectTopic < Avo::BaseAction\n  self.name = \"Reject Topic\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  # def fields\n  #   # Add Action fields here\n  # end\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |record|\n      record.rejected!\n    end\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/summarize.rb",
    "content": "class Avo::Actions::Summarize < Avo::BaseAction\n  self.name = \"Summarize\"\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |talk|\n      talk.agents.summarize_later\n    end\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/talk_index.rb",
    "content": "class Avo::Actions::TalkIndex < Avo::BaseAction\n  self.name = \"Talk Reindex\"\n  self.standalone = true\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    if query.empty?\n      Talk.all.in_batches.each(&:update_fts_record_later_bulk)\n\n      succeed \"All Talks reindexed\"\n    else\n      query.in_batches.each(&:update_fts_record_later_bulk)\n\n      succeed \"Selected talks are added to the index\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/talk_ingest.rb",
    "content": "class Avo::Actions::TalkIngest < Avo::BaseAction\n  self.name = \"Ingest talk (fetch transcript, enhance transcript, summarize, extract topics)\"\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |record|\n      record.agents.ingest_later\n    end\n\n    succeed \"Ingesting the talks in the background\"\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/transcript.rb",
    "content": "class Avo::Actions::Transcript < Avo::BaseAction\n  self.name = \"Fetch raw transcript\"\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |record|\n      record.fetch_and_update_raw_transcript_later!\n    end\n\n    succeed \"Fetching the transcript in the background\"\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/update_from_yml.rb",
    "content": "class Avo::Actions::UpdateFromYml < Avo::BaseAction\n  self.name = \"Update talk from yml metadata\"\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    query.each do |record|\n      record.update_from_yml_metadata_later!\n    end\n\n    succeed \"Updating talk from yml metadata\"\n  end\nend\n"
  },
  {
    "path": "app/avo/actions/user_fetch_github.rb",
    "content": "class Avo::Actions::UserFetchGitHub < Avo::BaseAction\n  self.name = \"Fetch GitHub profile\"\n\n  def handle(query:, fields:, current_user:, resource:, **args)\n    perform_in_background = !(query.count < 10)\n    query.each do |user|\n      perform_in_background ? user.profiles.enhance_with_github_later : user.profiles.enhance_with_github\n    end\n  end\nend\n"
  },
  {
    "path": "app/avo/cards/duplicates_summary.rb",
    "content": "class Avo::Cards::DuplicatesSummary < Avo::Cards::PartialCard\n  self.id = \"duplicates_summary\"\n  self.label = \"Duplicate Users\"\n  self.description = \"Users with potential reversed name duplicates\"\n  self.cols = 1\n  self.rows = 1\n  self.partial = \"avo/cards/duplicates_summary\"\nend\n"
  },
  {
    "path": "app/avo/cards/reversed_name_duplicates_list.rb",
    "content": "class Avo::Cards::ReversedNameDuplicatesList < Avo::Cards::PartialCard\n  self.id = \"reversed_name_duplicates_list\"\n  self.label = \"Duplicate Pairs\"\n  self.description = \"Users with reversed name matches\"\n  self.cols = 3\n  self.rows = 4\n  self.partial = \"avo/cards/reversed_name_duplicates_list\"\nend\n"
  },
  {
    "path": "app/avo/cards/reversed_name_duplicates_metric.rb",
    "content": "class Avo::Cards::ReversedNameDuplicatesMetric < Avo::Cards::MetricCard\n  self.id = \"reversed_name_duplicates_metric\"\n  self.label = \"Reversed Name Duplicates\"\n  self.description = \"Number of users with potential duplicate profiles (name parts reversed)\"\n  self.cols = 1\n\n  def query\n    result User.with_reversed_name_duplicate.count\n  end\nend\n"
  },
  {
    "path": "app/avo/cards/same_name_duplicates_list.rb",
    "content": "class Avo::Cards::SameNameDuplicatesList < Avo::Cards::PartialCard\n  self.id = \"same_name_duplicates_list\"\n  self.label = \"Same Name Duplicates\"\n  self.description = \"Users with identical names (case-insensitive)\"\n  self.cols = 3\n  self.rows = 2\n  self.partial = \"avo/cards/same_name_duplicates_list\"\nend\n"
  },
  {
    "path": "app/avo/cards/same_name_duplicates_metric.rb",
    "content": "class Avo::Cards::SameNameDuplicatesMetric < Avo::Cards::MetricCard\n  self.id = \"same_name_duplicates_metric\"\n  self.label = \"Same Name Duplicates\"\n  self.description = \"Users with identical names\"\n  self.cols = 1\n\n  def query\n    result User::DuplicateDetector.same_name_duplicate_ids.count\n  end\nend\n"
  },
  {
    "path": "app/avo/cards/suspicious_signals_breakdown.rb",
    "content": "class Avo::Cards::SuspiciousSignalsBreakdown < Avo::Cards::PartialCard\n  self.id = \"suspicious_signals_breakdown\"\n  self.label = \"Signal Breakdown\"\n  self.description = \"Breakdown of suspicious signals across flagged users\"\n  self.cols = 2\n  self.rows = 2\n  self.partial = \"avo/cards/suspicious_signals_breakdown\"\nend\n"
  },
  {
    "path": "app/avo/cards/suspicious_summary.rb",
    "content": "class Avo::Cards::SuspiciousSummary < Avo::Cards::PartialCard\n  self.id = \"suspicious_summary\"\n  self.label = \"Suspicious Users\"\n  self.description = \"Users flagged with suspicious signals\"\n  self.cols = 1\n  self.rows = 1\n  self.partial = \"avo/cards/suspicious_summary\"\nend\n"
  },
  {
    "path": "app/avo/cards/suspicious_users_list.rb",
    "content": "class Avo::Cards::SuspiciousUsersList < Avo::Cards::PartialCard\n  self.id = \"suspicious_users_list\"\n  self.label = \"Suspicious Users\"\n  self.description = \"Users flagged as suspicious based on signal detection\"\n  self.cols = 3\n  self.rows = 4\n  self.partial = \"avo/cards/suspicious_users_list\"\nend\n"
  },
  {
    "path": "app/avo/cards/suspicious_users_metric.rb",
    "content": "class Avo::Cards::SuspiciousUsersMetric < Avo::Cards::MetricCard\n  self.id = \"suspicious_users_metric\"\n  self.label = \"Suspicious Users\"\n  self.description = \"Number of users flagged as suspicious\"\n  self.cols = 1\n\n  def query\n    result User.suspicious.count\n  end\nend\n"
  },
  {
    "path": "app/avo/cards/unavailable_videos_by_event.rb",
    "content": "class Avo::Cards::UnavailableVideosByEvent < Avo::Cards::PartialCard\n  self.id = \"unavailable_videos_by_event\"\n  self.label = \"By Event\"\n  self.description = \"Unavailable videos grouped by event\"\n  self.cols = 2\n  self.rows = 2\n  self.partial = \"avo/cards/unavailable_videos_by_event\"\nend\n"
  },
  {
    "path": "app/avo/cards/unavailable_videos_list.rb",
    "content": "class Avo::Cards::UnavailableVideosList < Avo::Cards::PartialCard\n  self.id = \"unavailable_videos_list\"\n  self.label = \"Unavailable Videos\"\n  self.description = \"Talks with videos that are no longer available\"\n  self.cols = 3\n  self.rows = 4\n  self.partial = \"avo/cards/unavailable_videos_list\"\nend\n"
  },
  {
    "path": "app/avo/cards/unavailable_videos_metric.rb",
    "content": "class Avo::Cards::UnavailableVideosMetric < Avo::Cards::MetricCard\n  self.id = \"unavailable_videos_metric\"\n  self.label = \"Unavailable Videos\"\n  self.description = \"Number of talks with unavailable videos\"\n  self.cols = 1\n\n  def query\n    result Talk.video_unavailable.count\n  end\nend\n"
  },
  {
    "path": "app/avo/cards/unavailable_videos_summary.rb",
    "content": "class Avo::Cards::UnavailableVideosSummary < Avo::Cards::PartialCard\n  self.id = \"unavailable_videos_summary\"\n  self.label = \"Unavailable Videos\"\n  self.description = \"Talks with videos no longer available\"\n  self.cols = 1\n  self.rows = 1\n  self.partial = \"avo/cards/unavailable_videos_summary\"\nend\n"
  },
  {
    "path": "app/avo/dashboards/default.rb",
    "content": "class Avo::Dashboards::Default < Avo::Dashboards::BaseDashboard\n  self.id = \"default\"\n  self.name = \"Dashboard\"\n  self.description = \"Overview of key metrics and alerts\"\n  self.grid_cols = 3\n\n  def cards\n    card Avo::Cards::DuplicatesSummary\n    card Avo::Cards::SuspiciousSummary\n    card Avo::Cards::UnavailableVideosSummary\n  end\nend\n"
  },
  {
    "path": "app/avo/dashboards/duplicates.rb",
    "content": "class Avo::Dashboards::Duplicates < Avo::Dashboards::BaseDashboard\n  self.id = \"duplicates\"\n  self.name = \"Duplicate Detection\"\n  self.description = \"Find potential duplicate user profiles\"\n  self.grid_cols = 3\n\n  def cards\n    card Avo::Cards::SameNameDuplicatesMetric\n    card Avo::Cards::ReversedNameDuplicatesMetric\n    card Avo::Cards::SameNameDuplicatesList\n    card Avo::Cards::ReversedNameDuplicatesList\n  end\nend\n"
  },
  {
    "path": "app/avo/dashboards/suspicious.rb",
    "content": "class Avo::Dashboards::Suspicious < Avo::Dashboards::BaseDashboard\n  self.id = \"suspicious\"\n  self.name = \"Suspicious Users\"\n  self.description = \"Monitor and manage suspicious user accounts\"\n  self.grid_cols = 3\n\n  def cards\n    card Avo::Cards::SuspiciousUsersMetric\n    card Avo::Cards::SuspiciousSignalsBreakdown\n    card Avo::Cards::SuspiciousUsersList\n  end\nend\n"
  },
  {
    "path": "app/avo/dashboards/unavailable_videos.rb",
    "content": "class Avo::Dashboards::UnavailableVideos < Avo::Dashboards::BaseDashboard\n  self.id = \"unavailable_videos\"\n  self.name = \"Unavailable Videos\"\n  self.description = \"Monitor talks with videos that are no longer available\"\n  self.grid_cols = 3\n\n  def cards\n    card Avo::Cards::UnavailableVideosMetric\n    card Avo::Cards::UnavailableVideosByEvent\n    card Avo::Cards::UnavailableVideosList\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/aliasable_type.rb",
    "content": "class Avo::Filters::AliasableType < Avo::Filters::SelectFilter\n  self.name = \"Aliasable Type\"\n\n  def apply(request, query, type)\n    if type\n      query.where(aliasable_type: type)\n    else\n      query\n    end\n  end\n\n  def options\n    {\n      \"User\" => \"User\",\n      \"EventSeries\" => \"EventSeries\",\n      \"Organization\" => \"Organization\",\n      \"Talk\" => \"Talk\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/attended_as.rb",
    "content": "class Avo::Filters::AttendedAs < Avo::Filters::SelectFilter\n  self.name = \"Attended as\"\n\n  def apply(request, query, attended_as)\n    if attended_as\n      query.where(\"attended_as is ?\", attended_as)\n    else\n      query\n    end\n  end\n\n  def options\n    EventParticipation.attended_as\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/bio.rb",
    "content": "class Avo::Filters::Bio < Avo::Filters::TextFilter\n  self.name = \"Bio\"\n  self.button_label = \"Filter by bio (contains)\"\n\n  def apply(request, query, value)\n    query.where(\"bio LIKE ?\", \"%#{value}%\")\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/bio_presence.rb",
    "content": "class Avo::Filters::BioPresence < Avo::Filters::BooleanFilter\n  self.name = \"Bio presence\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  def apply(request, query, values)\n    return query unless values[\"no_bio\"]\n\n    query.where(bio: [nil, \"\"])\n  end\n\n  def options\n    {\n      no_bio: \"Without bio\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/canonical.rb",
    "content": "class Avo::Filters::Canonical < Avo::Filters::BooleanFilter\n  self.name = \"Canonical\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  def apply(request, query, values)\n    return query if values[\"canonical\"] && values[\"not_canonical\"]\n    if values[\"canonical\"]\n      query = query.canonical\n    elsif values[\"not_canonical\"]\n      query = query.not_canonical\n    end\n    query\n  end\n\n  def options\n    {\n      canonical: \"Has canonical\",\n      not_canonical: \"Without canonical\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/enhanced_transcript.rb",
    "content": "class Avo::Filters::EnhancedTranscript < Avo::Filters::BooleanFilter\n  self.name = \"Enhanced transcript\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  def apply(request, query, values)\n    return query if values[\"has_enhanced_transcript\"] && values[\"no_enhanced_transcript\"]\n\n    if values[\"has_enhanced_transcript\"]\n      query = query.with_enhanced_transcript\n    elsif values[\"no_enhanced_transcript\"]\n      query = query.without_enhanced_transcript\n    end\n\n    query\n  end\n\n  def options\n    {\n      has_enhanced_transcript: \"With enhanced transcript\",\n      no_enhanced_transcript: \"Without enhanced transcript\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/geocoded_presence.rb",
    "content": "class Avo::Filters::GeocodedPresence < Avo::Filters::BooleanFilter\n  self.name = \"Geocoded\"\n\n  def apply(request, query, values)\n    return query if values[\"geocoded\"] && values[\"not_geocoded\"]\n\n    if values[\"geocoded\"]\n      query.geocoded\n    elsif values[\"not_geocoded\"]\n      query.not_geocoded\n    else\n      query\n    end\n  end\n\n  def options\n    {\n      geocoded: \"Geocoded\",\n      not_geocoded: \"Not geocoded\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/github.rb",
    "content": "class Avo::Filters::GitHub < Avo::Filters::BooleanFilter\n  self.name = \"GitHub handle\"\n\n  def apply(request, query, values)\n    return query if values[\"has_github\"] && values[\"no_github\"]\n    if values[\"has_github\"]\n      query = query.where.not(github: [\"\", nil])\n    elsif values[\"no_github\"]\n      query = query.where(github: [\"\", nil])\n    end\n\n    query\n  end\n\n  def options\n    {\n      has_github: \"With GitHub handle\",\n      no_github: \"Without GitHub handle\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/github_handle.rb",
    "content": "class Avo::Filters::GitHubHandle < Avo::Filters::TextFilter\n  self.name = \"GitHub handle (contains)\"\n\n  def apply(request, query, value)\n    query.where(\"lower(github_handle) LIKE ?\", \"%#{value.downcase}%\")\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/github_handle_presence.rb",
    "content": "class Avo::Filters::GitHubHandlePresence < Avo::Filters::BooleanFilter\n  self.name = \"GitHub handle presence\"\n\n  def apply(request, query, values)\n    return query if values[\"has_github\"] && values[\"no_github\"]\n    if values[\"has_github\"]\n      query = query.where.not(github_handle: [\"\", nil])\n    elsif values[\"no_github\"]\n      query = query.where(github_handle: [\"\", nil])\n    end\n\n    query\n  end\n\n  def options\n    {\n      has_github: \"With GitHub handle\",\n      no_github: \"Without GitHub handle\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/has_duplicate.rb",
    "content": "class Avo::Filters::HasDuplicate < Avo::Filters::BooleanFilter\n  self.name = \"Has duplicate\"\n\n  def apply(request, query, values)\n    if values[\"has_any_duplicate\"]\n      query.with_any_duplicate\n    elsif values[\"has_reversed_name_duplicate\"]\n      query.with_reversed_name_duplicate\n    elsif values[\"has_same_name_duplicate\"]\n      query.with_same_name_duplicate\n    else\n      query\n    end\n  end\n\n  def options\n    {\n      has_any_duplicate: \"Has any duplicate\",\n      has_reversed_name_duplicate: \"Has reversed name duplicate\",\n      has_same_name_duplicate: \"Has same name duplicate\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/involvement_role.rb",
    "content": "class Avo::Filters::InvolvementRole < Avo::Filters::SelectFilter\n  self.name = \"Role\"\n\n  def apply(request, query, role)\n    if role\n      query.where(role: role)\n    else\n      query\n    end\n  end\n\n  def options\n    EventInvolvement.distinct.pluck(:role).compact.sort.index_by(&:itself)\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/language.rb",
    "content": "class Avo::Filters::Language < Avo::Filters::SelectFilter\n  self.name = \"Language\"\n\n  # self.visible = -> do\n  #   true\n  # end\n\n  def apply(request, query, language)\n    if language\n      query.where(\"language is ?\", language)\n    else\n      query\n    end\n  end\n\n  def options\n    Language.used\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/location_presence.rb",
    "content": "class Avo::Filters::LocationPresence < Avo::Filters::BooleanFilter\n  self.name = \"Location presence\"\n\n  def apply(request, query, values)\n    return query if values[\"has_location\"] && values[\"no_location\"]\n\n    if values[\"has_location\"]\n      query = query.where.not(location: [\"\", nil])\n    elsif values[\"no_location\"]\n      query = query.where(location: [\"\", nil])\n    end\n\n    query\n  end\n\n  def options\n    {\n      has_location: \"With location\",\n      no_location: \"Without location\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/name.rb",
    "content": "class Avo::Filters::Name < Avo::Filters::TextFilter\n  self.name = \"Name\"\n  self.button_label = \"Filter by name (contains)\"\n\n  def apply(request, query, value)\n    query.where(\"name LIKE ?\", \"%#{value}%\")\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/provider.rb",
    "content": "class Avo::Filters::Provider < Avo::Filters::SelectFilter\n  self.name = \"Provider\"\n\n  def apply(request, query, provider)\n    if provider\n      query.where(\"provider is ?\", provider)\n    else\n      query\n    end\n  end\n\n  def options\n    ConnectedAccount.providers\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/published.rb",
    "content": "class Avo::Filters::Published < Avo::Filters::BooleanFilter\n  self.name = \"Approved Status\"\n\n  def apply(request, query, values)\n    selected_statuses = values.select { |k, v| v }.keys\n\n    if selected_statuses.any?\n      query = query.where(status: selected_statuses)\n    end\n\n    query\n  end\n\n  def options\n    {\n      pending: \"Pending\",\n      approved: \"Approved\",\n      rejected: \"Rejected\",\n      duplicate: \"Duplicate\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/raw_transcript.rb",
    "content": "class Avo::Filters::RawTranscript < Avo::Filters::BooleanFilter\n  self.name = \"Raw transcript\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  def apply(request, query, values)\n    return query if values[\"has_transcript\"] && values[\"no_transcript\"]\n\n    if values[\"has_transcript\"]\n      query = query.with_raw_transcript\n    elsif values[\"no_transcript\"]\n      query = query.without_raw_transcript\n    end\n\n    query\n  end\n\n  def options\n    {\n      has_transcript: \"With raw transcript\",\n      no_transcript: \"Without raw transcript\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/slug.rb",
    "content": "class Avo::Filters::Slug < Avo::Filters::TextFilter\n  self.name = \"Slug\"\n  self.button_label = \"Filter by slug (contains)\"\n\n  def apply(request, query, value)\n    query.where(\"slug LIKE ?\", \"%#{value}%\")\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/summary.rb",
    "content": "class Avo::Filters::Summary < Avo::Filters::BooleanFilter\n  self.name = \"Summary\"\n\n  def apply(request, query, values)\n    return query if values[\"has_summary\"] && values[\"no_summary\"]\n\n    if values[\"has_summary\"]\n      query = query.with_summary\n    elsif values[\"no_summary\"]\n      query = query.without_summary\n    end\n\n    query\n  end\n\n  def options\n    {\n      has_summary: \"With summary\",\n      no_summary: \"Without summary\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/suspicious.rb",
    "content": "class Avo::Filters::Suspicious < Avo::Filters::BooleanFilter\n  self.name = \"Suspicious\"\n\n  def apply(request, query, values)\n    return query unless values[\"suspicious\"]\n\n    query.suspicious\n  end\n\n  def options\n    {\n      suspicious: \"Suspicious users\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/talk_event.rb",
    "content": "class Avo::Filters::TalkEvent < Avo::Filters::SelectFilter\n  self.name = \"Talk event\"\n\n  def apply(request, query, values)\n    query.where(event_id: values) if values\n  end\n\n  def options\n    Event.all.map { |event| [event.id, event.name] }.sort_by { |_, name| name }.to_h\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/title.rb",
    "content": "class Avo::Filters::Title < Avo::Filters::TextFilter\n  self.name = \"Title\"\n  self.button_label = \"Filter by title (contains)\"\n\n  def apply(request, query, value)\n    query.where(\"title LIKE ?\", \"%#{value}%\")\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/topic_talks.rb",
    "content": "class Avo::Filters::TopicTalks < Avo::Filters::BooleanFilter\n  self.name = \"Topic talks\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  def apply(request, query, values)\n    return query if values[\"has_talks\"] && values[\"no_talks\"] && values[\"one_talk\"] && values[\"two_talks\"]\n\n    if values[\"has_talks\"]\n      query = query.with_talks\n    elsif values[\"no_talks\"]\n      query = query.without_talks\n    elsif values[\"one_talk\"]\n      query = query.with_n_talk(1)\n    elsif values[\"two_talks\"]\n      query = query.with_n_talk(2)\n    end\n\n    query\n  end\n\n  def options\n    {\n      has_talks: \"With talk topics\",\n      no_talks: \"Without talk topics\",\n      one_talk: \"One talk\",\n      two_talks: \"Two talks\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/topics.rb",
    "content": "class Avo::Filters::Topics < Avo::Filters::BooleanFilter\n  self.name = \"Topics\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  def apply(request, query, values)\n    return query if values[\"has_topics\"] && values[\"no_topics\"]\n\n    if values[\"has_topics\"]\n      query = query.with_topics\n    elsif values[\"no_topics\"]\n      query = query.without_topics\n    end\n\n    query\n  end\n\n  def options\n    {\n      has_topics: \"With topics\",\n      no_topics: \"Without topics\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/video_availability.rb",
    "content": "class Avo::Filters::VideoAvailability < Avo::Filters::BooleanFilter\n  self.name = \"Video Availability\"\n\n  def apply(request, query, values)\n    if values[\"available\"]\n      query = query.video_available\n    end\n\n    if values[\"unavailable\"]\n      query = query.video_unavailable\n    end\n\n    if values[\"watchable\"]\n      query = query.watchable\n    end\n\n    if values[\"marked_unavailable\"]\n      query = query.where.not(video_unavailable_at: nil)\n    end\n\n    query\n  end\n\n  def options\n    {\n      available: \"Watchable & Available\",\n      unavailable: \"Watchable & Unavailable\",\n      watchable: \"Watchable\",\n      marked_unavailable: \"Marked Unavailable\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/video_provider.rb",
    "content": "class Avo::Filters::VideoProvider < Avo::Filters::SelectFilter\n  self.name = \"Video Provider\"\n\n  # self.visible = -> do\n  #   true\n  # end\n\n  def apply(request, query, provider)\n    if provider\n      query.where(video_provider: provider)\n    else\n      query\n    end\n  end\n\n  def options\n    Talk.video_providers\n  end\nend\n"
  },
  {
    "path": "app/avo/filters/without_talks.rb",
    "content": "class Avo::Filters::WithoutTalks < Avo::Filters::BooleanFilter\n  self.name = \"Without talks\"\n  # self.visible = -> do\n  #   true\n  # end\n\n  def apply(request, query, values)\n    if values[\"no_talks\"]\n      query = query.without_talks\n    end\n\n    query\n  end\n\n  def options\n    {\n      no_talks: \"Without talks\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/alias.rb",
    "content": "class Avo::Resources::Alias < Avo::BaseResource\n  self.includes = [:aliasable]\n  self.search = {\n    query: -> { query.where(\"name LIKE ? OR slug LIKE ?\", \"%#{params[:q]}%\", \"%#{params[:q]}%\") }\n  }\n  self.external_link = -> {\n    Avo::Resources::Alias.aliasable_link(main_app, record)\n  }\n\n  def filters\n    filter Avo::Filters::AliasableType\n  end\n\n  def fields\n    field :id, as: :id\n    field :aliasable, as: :belongs_to, polymorphic_as: :aliasable, types: [::User, ::Event, ::EventSeries, ::Organization, ::City]\n    field :aliasable_type, as: :text, readonly: true, only_on: :show\n    field :aliasable_id, as: :id, readonly: true, only_on: :show\n    field :name, as: :text, required: true\n    field :slug, as: :text, required: true\n    field :external_url,\n      as: :text,\n      hide_on: [:edit, :new],\n      format_using: -> { view_context.link_to(value, value, target: \"_blank\") if value.present? } do\n      Avo::Resources::Alias.aliasable_link(main_app, record)\n    end\n    field :created_at, as: :date_time, readonly: true\n    field :updated_at, as: :date_time, readonly: true\n  end\n\n  def self.aliasable_link(app, record)\n    case record.aliasable_type\n    when \"User\"\n      app.profile_path(record.aliasable.slug)\n    when \"Event\"\n      app.event_path(record.aliasable.slug)\n    when \"EventSeries\"\n      app.series_path(record.aliasable.slug)\n    when \"Talk\"\n      app.talk_path(record.aliasable.slug)\n    when \"Organization\"\n      app.organization_path(record.aliasable.slug)\n    when \"City\"\n      app.city_path(record.aliasable.slug)\n    else\n      raise \"Unknown aliasable type: #{record.aliasable_type}\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/city.rb",
    "content": "class Avo::Resources::City < Avo::BaseResource\n  self.model_class = ::City\n  self.title = :name\n  self.includes = []\n  self.find_record_method = -> {\n    if id.is_a?(Array)\n      query.where(slug: id)\n    else\n      query.find_by(slug: id)\n    end\n  }\n  self.search = {\n    query: -> { query.where(\"name LIKE ?\", \"%#{params[:q]}%\") }\n  }\n  self.external_link = -> {\n    main_app.city_path(record)\n  }\n  self.map_view = {\n    mapkick_options: {\n      controls: true\n    },\n    record_marker: -> {\n      {\n        latitude: record.latitude,\n        longitude: record.longitude,\n        tooltip: record.name\n      }\n    },\n    table: {\n      visible: true\n    }\n  }\n\n  def fields\n    field :id, as: :id\n    field :name, as: :text, link_to_record: true, sortable: true\n    field :slug, as: :text, sortable: true\n    field :state_code, as: :text\n    field :country_code, as: :select, options: country_options, include_blank: true\n    field :featured, as: :boolean, sortable: true\n    field :latitude, as: :number, hide_on: :index\n    field :longitude, as: :number, hide_on: :index\n    field :geocode_metadata, as: :code, language: :json, hide_on: :index\n    field :created_at, as: :date_time, hide_on: :forms, sortable: true\n    field :updated_at, as: :date_time, hide_on: :forms, sortable: true\n  end\n\n  def filters\n    filter Avo::Filters::Name\n  end\n\n  def country_options\n    Country.select_options\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/connected_account.rb",
    "content": "# id           :integer\n# uid          :string\n# provider     :string\n# username     :string\n# user_id      :integer\n# access_token :string\n# expires_at   :datetime\n# created_at   :datetime\n# updated_at   :datetime\n\nclass Avo::Resources::ConnectedAccount < Avo::BaseResource\n  # self.includes = []\n  # self.attachments = []\n  self.search = {\n    query: -> { query.ransack(id_eq: params[:q], uid_cont: params[:q], m: \"or\").result(distinct: false) }\n  }\n\n  def fields\n    field :id, as: :id\n    field :uid, as: :text\n    field :provider, as: :text, sortable: true\n    field :username, as: :text, sortable: true\n    field :user, as: :belongs_to, sortable: true\n    field :user_id, as: :text, sortable: true, hide_on: [:index]\n    field :access_token, as: :text, hide_on: [:index]\n    field :expires_at, as: :date_time, hide_on: [:index]\n    field :created_at, as: :date_time, hide_on: [:index]\n    field :updated_at, as: :date_time, hide_on: [:index]\n  end\n\n  def filters\n    filter Avo::Filters::Provider\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/contributor.rb",
    "content": "class Avo::Resources::Contributor < Avo::BaseResource\n  # self.includes = []\n  # self.attachments = []\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: q, m: \"or\").result(distinct: false) }\n  # }\n\n  def fields\n    field :id, as: :id\n    field :login, as: :text\n    field :name, as: :text\n    field :avatar_url, as: :text\n    field :html_url, as: :text\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/event.rb",
    "content": "class Avo::Resources::Event < Avo::BaseResource\n  self.includes = []\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: params[:q], m: \"or\").result(distinct: false) }\n  # }\n  self.find_record_method = -> {\n    if id.is_a?(Array)\n      query.where(slug: id)\n    else\n      query.find_by(slug: id)\n    end\n  }\n  self.external_link = -> {\n    main_app.event_path(record)\n  }\n\n  def fields\n    field :id, as: :id\n    field :name, as: :text, link_to_record: true, sortable: true\n    field :date, as: :date, hide_on: :index\n    field :date_precision, as: :select, options: ::Event.date_precisions, hide_on: :index\n    field :start_date, as: :date, hide_on: :index\n    field :end_date, as: :date, hide_on: :index\n    field :location, as: :text, hide_on: :index\n    field :city, as: :text, hide_on: :index\n    field :state_code, as: :text, hide_on: :index\n    field :country_code, as: :select, options: country_options, include_blank: true\n    field :latitude, as: :number, hide_on: :index\n    field :longitude, as: :number, hide_on: :index\n    field :geocode_metadata, as: :code, hide_on: :index\n    field :kind, hide_on: :index\n    field :slug, as: :text\n    field :updated_at, as: :date, sortable: true\n    # field :suggestions, as: :has_many\n    field :series, as: :belongs_to\n    field :talks, as: :has_many\n    field :speakers, as: :has_many, through: :talks, class_name: \"User\"\n    field :participants, as: :has_many, through: :event_participations, class_name: \"User\"\n    field :event_involvements, as: :has_many\n    field :topics, as: :has_many\n    field :sponsors, as: :has_many\n  end\n\n  def actions\n    action Avo::Actions::AssignCanonicalEvent\n    action Avo::Actions::GeocodeRecord\n  end\n\n  def filters\n    filter Avo::Filters::Name\n    filter Avo::Filters::WithoutTalks\n    filter Avo::Filters::Canonical\n    filter Avo::Filters::LocationPresence\n    filter Avo::Filters::GeocodedPresence\n  end\n\n  def country_options\n    Country.select_options\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/event_involvement.rb",
    "content": "class Avo::Resources::EventInvolvement < Avo::BaseResource\n  self.includes = [:involvementable, :event]\n\n  self.search = {\n    query: -> {\n      query\n        .left_joins(\"LEFT JOIN users ON users.id = event_involvements.involvementable_id AND event_involvements.involvementable_type = 'User'\")\n        .left_joins(\"LEFT JOIN event_series ON event_series.id = event_involvements.involvementable_id AND event_involvements.involvementable_type = 'EventSeries'\")\n        .where(\"users.name LIKE ? OR event_series.name LIKE ? OR event_involvements.role LIKE ?\", \"%#{params[:q]}%\", \"%#{params[:q]}%\", \"%#{params[:q]}%\")\n    }\n  }\n\n  def fields\n    field :id, as: :id\n    field :involvementable, as: :belongs_to, polymorphic_as: :involvementable, types: [::User, ::EventSeries], searchable: true\n    field :event, as: :belongs_to, searchable: true, attach_scope: -> { query.order(name: :asc) }\n    field :role, as: :text\n    field :created_at, as: :date_time\n    field :updated_at, as: :date_time\n  end\n\n  def filters\n    filter Avo::Filters::InvolvementRole\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/event_participation.rb",
    "content": "class Avo::Resources::EventParticipation < Avo::BaseResource\n  self.includes = [:user, :event]\n  # self.attachments = []\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: q, m: \"or\").result(distinct: false) }\n  # }\n  self.search = {\n    query: -> { query.joins(:user).where(\"users.name LIKE ?\", \"%#{params[:q]}%\") }\n  }\n\n  def fields\n    field :id, as: :id\n    field :attended_as, as: :select, enum: ::EventParticipation.attended_as\n    field :user, as: :belongs_to, searchable: true\n    field :event, as: :belongs_to, searchable: true, attach_scope: -> { query.order(name: :asc) }\n  end\n\n  def filters\n    filter Avo::Filters::AttendedAs\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/event_series.rb",
    "content": "class Avo::Resources::EventSeries < Avo::BaseResource\n  self.single_includes = [:events]\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: params[:q], m: \"or\").result(distinct: false) }\n  # }\n  self.find_record_method = -> {\n    if id.is_a?(Array)\n      query.where(slug: id)\n    else\n      query.find_by(slug: id)\n    end\n  }\n  self.external_link = -> {\n    main_app.series_path(record)\n  }\n\n  def fields\n    field :id, as: :id\n    field :name, as: :text, link_to_record: true\n    field :description, as: :text, hide_on: [:index, :forms]\n    field :website, as: :text\n    field :language, as: :text\n    field :kind, as: :select, enum: ::EventSeries.kinds\n    field :frequency, as: :select, enum: ::EventSeries.frequencies, hide_on: :index\n    field :youtube_channel_id, as: :text, hide_on: :index\n    field :youtube_channel_name, as: :text, hide_on: :index\n    field :slug, as: :text, hide_on: :index\n    field :twitter, as: :text, hide_on: :index\n    # field :suggestions, as: :has_many\n    field :events, as: :has_many\n    field :talks, as: :has_many, through: :events\n  end\n\n  def filters\n    filter Avo::Filters::Name\n    filter Avo::Filters::Slug\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/favorite_user.rb",
    "content": "class Avo::Resources::FavoriteUser < Avo::BaseResource\n  # self.includes = []\n  # self.attachments = []\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: q, m: \"or\").result(distinct: false) }\n  # }\n\n  def fields\n    field :id, as: :id\n    field :user, as: :belongs_to\n    field :favorite_user, as: :belongs_to\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/geocode_result.rb",
    "content": "class Avo::Resources::GeocodeResult < Avo::BaseResource\n  self.model_class = ::GeocodeResult\n  self.title = :query\n  self.includes = []\n  self.search = {\n    query: -> { query.where(\"query LIKE ?\", \"%#{params[:q]}%\") }\n  }\n\n  def fields\n    field :id, as: :id\n    field :query, as: :text, link_to_record: true, sortable: true\n    field :response_body, as: :code, language: \"json\", hide_on: :index\n    field :created_at, as: :date_time, hide_on: :forms, sortable: true\n    field :updated_at, as: :date_time, hide_on: :forms, sortable: true\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/organization.rb",
    "content": "class Avo::Resources::Organization < Avo::BaseResource\n  # self.includes = []\n  # self.attachments = []\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: params[:q], m: \"or\").result(distinct: false) }\n  # }\n  self.find_record_method = -> {\n    if id.is_a?(Array)\n      query.where(slug: id)\n    else\n      query.find_by(slug: id)\n    end\n  }\n\n  self.search = {\n    query: -> { query.where(\"lower(name) LIKE ?\", \"%#{params[:q]&.downcase}%\") }\n  }\n\n  def fields\n    field :id, as: :id\n    field :name, as: :text\n    field :kind, as: :select, enum: ::Organization.kinds\n    field :website, as: :text\n    field :slug, as: :text\n    field :description, as: :textarea\n    field :main_location, as: :text\n    field :sponsors, as: :has_many\n    field :event_involvements, as: :has_many\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/session.rb",
    "content": "class Avo::Resources::Session < Avo::BaseResource\n  self.includes = []\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: params[:q], m: \"or\").result(distinct: false) }\n  # }\n\n  def fields\n    field :id, as: :id, link_to_record: true\n    field :user_agent, as: :text, format_using: -> { value.truncate(50) }, only_on: :index\n    field :user_agent, as: :text, hide_on: :index\n    field :ip_address, as: :text\n    field :user, as: :belongs_to, use_resource: Avo::Resources::User, link_to_record: true, hide_on: :index\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/sponsor.rb",
    "content": "class Avo::Resources::Sponsor < Avo::BaseResource\n  # self.includes = []\n  # self.attachments = []\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: params[:q], m: \"or\").result(distinct: false) }\n  # }\n\n  def fields\n    field :id, as: :id\n    field :event, as: :belongs_to\n    field :organization, as: :belongs_to\n    field :tier, as: :text\n    field :badge, as: :text\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/suggestion.rb",
    "content": "class Avo::Resources::Suggestion < Avo::BaseResource\n  # self.includes = []\n  # self.attachments = []\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: params[:q], m: \"or\").result(distinct: false) }\n  # }\n\n  def fields\n    field :id, as: :idlo\n    field :content, as: :text, only_on: :index do\n      record.content.map { |key, value| \"#{key}: #{value}\" }.to_sentence.truncate(50)\n    end\n    field :content, as: :key_value, hide_on: :index\n    field :status, as: :status, loading_when: [:pending], success_when: [:approved], link_to_record: true, hide_on: [:forms]\n    field :suggestable, as: :belongs_to, polymorphic_as: :suggestable\n    field :approved_by, as: :belongs_to\n    field :suggested_by, as: :belongs_to\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/talk.rb",
    "content": "class Avo::Resources::Talk < Avo::BaseResource\n  self.includes = [:event, :speakers, :topics]\n  self.find_record_method = -> {\n    if id.is_a?(Array)\n      query.where(slug: id)\n    else\n      query.find_by(slug: id)\n    end\n  }\n  self.keep_filters_panel_open = true\n\n  self.search = {\n    query: -> { query.where(id: Talk.search(params[:q]).map(&:id)) }\n  }\n  self.external_link = -> {\n    main_app.talk_path(record)\n  }\n\n  def fields\n    field :id, as: :id\n    field :title, as: :text, link_to_record: true, sortable: true\n    field :event, as: :belongs_to\n\n    field :speaker_tags, for_attribute: :speakers, name: \"Speakers\", through: :speaker_talks, as: :tags, hide_on: [:show, :forms] do\n      record.speakers.map(&:name)\n    end\n\n    field :topics, as: :tags, hide_on: [:index, :forms] do\n      record.topics.map(&:name)\n    end\n    field :updated_at, as: :date, sortable: true\n    field :slides_url, as: :text, hide_on: :index\n    field :summary, as: :easy_mde, hide_on: :index\n    field :has_raw_transcript, name: \"Raw Transcript\", as: :boolean do\n      record.raw_transcript.present?\n    end\n    field :has_enhanced_transcript, hide_on: :index, name: \"Enhanced Transcript\", as: :boolean do\n      record.enhanced_transcript.present?\n    end\n    field :raw_transcript_length, name: \"Raw Transcript length\", as: :number do\n      record.raw_transcript&.to_text&.length\n    end\n    field :enhanced_transcript_length, name: \"Enhanced Transcript length\", as: :number do\n      record.enhanced_transcript&.to_text&.length\n    end\n    field :has_duration, name: \"Duration\", as: :boolean do\n      record.duration_in_seconds.present?\n    end\n    field :has_summary, name: \"Summary\", as: :boolean do\n      record.summary.present?\n    end\n    field :has_topics, name: \"Topics\", as: :boolean do\n      record.topics.any?\n    end\n    field :language, hide_on: :index\n    field :slug, as: :text, hide_on: :index\n    field :year, as: :number, hide_on: :index\n    field :video_id, as: :text, hide_on: :index\n    field :video_provider, as: :text, hide_on: :index\n    field :video_available, name: \"Video Available\", as: :boolean do\n      record.video_available?\n    end\n    field :video_unavailable_at, as: :date_time, hide_on: :index\n    field :external_player, as: :boolean, hide_on: :index\n    field :date, as: :date, hide_on: :index\n    field :like_count, as: :number, hide_on: :index\n    field :view_count, as: :number, hide_on: :index\n    field :duration_in_seconds, as: :number, hide_on: [:index, :edit], format_using: -> { Duration.seconds_to_formatted_duration(value, raise: false) }, name: \"Duration\", readonly: true\n    field :duration_in_seconds, as: :number, hide_on: :index, show_on: [:edit], name: \"Duration in seconds\"\n    field :created_at, as: :date, hide_on: :index\n    field :updated_at, as: :date, sortable: true, filterable: true\n    field :description, as: :textarea, hide_on: :index\n\n    field :thumbnail_xs, as: :external_image, hide_on: :index\n    field :thumbnail_sm, as: :external_image, hide_on: :index\n    field :thumbnail_md, as: :external_image, hide_on: :index\n    field :thumbnail_lg, as: :external_image, hide_on: :index\n    field :thumbnail_xl, as: :external_image, hide_on: :index\n    # field :speaker_talks, as: :has_many, attach_scope: -> { query.order(name: :asc) }\n    field :speakers, as: :has_many\n    field :raw_transcript, as: :textarea, hide_on: :index, format_using: -> { value&.to_text }, readonly: true\n    field :enhanced_transcript, as: :textarea, hide_on: :index, format_using: -> { value&.to_text }, readonly: true\n    # field :suggestions, as: :has_many\n  end\n\n  def actions\n    action Avo::Actions::TalkIngest\n    action Avo::Actions::UpdateFromYml\n    action Avo::Actions::TalkIndex\n    action Avo::Actions::FetchDuration\n  end\n\n  def filters\n    filter Avo::Filters::TalkEvent\n    filter Avo::Filters::RawTranscript\n    filter Avo::Filters::EnhancedTranscript\n    filter Avo::Filters::Summary\n    filter Avo::Filters::Topics\n    filter Avo::Filters::Title\n    filter Avo::Filters::Slug\n    filter Avo::Filters::Language\n    filter Avo::Filters::VideoProvider\n    filter Avo::Filters::VideoAvailability\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/talk_topic.rb",
    "content": "class Avo::Resources::TalkTopic < Avo::BaseResource\n  self.includes = [:talk, :topic]\n  # self.attachments = []\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: params[:q], m: \"or\").result(distinct: false) }\n  # }\n\n  def fields\n    field :id, as: :id\n    field :talk_title, as: :text do\n      record.talk.title\n    end\n    field :topic_name, as: :text do\n      record.topic.name\n    end\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/talk_transcript.rb",
    "content": "class Avo::Resources::TalkTranscript < Avo::BaseResource\n  # self.includes = []\n  # self.attachments = []\n  self.model_class = ::Talk::Transcript\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: params[:q], m: \"or\").result(distinct: false) }\n  # }\n\n  def fields\n    field :id, as: :id\n    field :talk, as: :belongs_to\n    field :raw_transcript, as: :textarea, hide_on: [:index], format_using: -> { value&.to_text }\n    field :enhanced_transcript, as: :textarea, hide_on: [:index], format_using: -> { value&.to_text }\n    field :created_at, as: :date_time, sortable: true, hide_on: [:index]\n    field :updated_at, as: :date_time, sortable: true\n  end\n\n  def actions\n    action Avo::Actions::EnhanceTranscript\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/topic.rb",
    "content": "class Avo::Resources::Topic < Avo::BaseResource\n  # self.includes = []\n  # self.attachments = []\n  self.search = {\n    query: -> { query.where(\"name LIKE ?\", \"%#{params[:q]}%\") }\n  }\n  self.find_record_method = -> {\n    if id.is_a?(Array)\n      query.where(slug: id)\n    else\n      query.find_by(slug: id)\n    end\n  }\n  self.keep_filters_panel_open = true\n  self.external_link = -> {\n    main_app.topic_path(record)\n  }\n\n  def fields\n    field :id, as: :id\n    field :name, as: :text, link_to_record: true\n    field :talks_count, as: :number, hide_on: :forms, sortable: true\n    field :canonical, as: :belongs_to, use_resource: \"Topic\", hide_on: :index\n    field :description, as: :markdown, hide_on: :index\n    field :status, as: :status, loading_when: \"pending\", success_when: \"approved\", failed_when: \"rejected\", hide_on: :forms\n    field :status, as: :select, enum: ::Topic.statuses, only_on: :forms\n    field :gem_names, as: :text, hide_on: :forms do\n      record.topic_gems.pluck(:gem_name).join(\", \")\n    end\n    field :talks, as: :has_many\n    field :topic_gems, as: :has_many\n  end\n\n  def actions\n    action Avo::Actions::ApproveTopic\n    action Avo::Actions::RejectTopic\n    action Avo::Actions::AssignCanonicalTopic\n    action Avo::Actions::FindTopicTalks\n  end\n\n  def filters\n    filter Avo::Filters::Name\n    filter Avo::Filters::Published\n    filter Avo::Filters::TopicTalks\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/topic_gem.rb",
    "content": "class Avo::Resources::TopicGem < Avo::BaseResource\n  self.title = :gem_name\n  self.search = {\n    query: -> { query.where(\"gem_name LIKE ?\", \"%#{params[:q]}%\") }\n  }\n  self.external_link = -> {\n    record.rubygems_url\n  }\n\n  def self.name\n    \"Gem\"\n  end\n\n  def fields\n    field :id, as: :id\n    field :gem_name, as: :text, link_to_record: true, help: \"Exact gem name from RubyGems.org (e.g., 'sidekiq', 'activerecord')\"\n    field :topic, as: :belongs_to, link_to_record: true\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/user.rb",
    "content": "class Avo::Resources::User < Avo::BaseResource\n  self.title = :name\n  self.includes = []\n  self.find_record_method = -> {\n    if id.is_a?(Array)\n      if id.first.to_i == 0\n        query.where(slug: id).or(query.where(github_handle: id))\n      else\n        query.where(id: id)\n      end\n    else\n      (id.to_i == 0) ? (query.find_by_slug_or_alias(id) || query.find_by_github_handle(id)) : query.find(id)\n    end\n  }\n  self.search = {\n    query: -> { query.where(\"lower(name) LIKE ? OR email LIKE ?\", \"%#{params[:q]&.downcase}%\", \"%#{params[:q]}%\") }\n  }\n  self.external_link = -> {\n    main_app.profile_path(record)\n  }\n\n  def fields\n    field :id, as: :id, link_to_record: true\n    field :name, as: :text, link_to_record: true\n    field :email, as: :text, link_to_record: true, format_using: -> { value&.truncate(30) }, only_on: :index\n    field :email, as: :text, link_to_record: true, hide_on: :index\n    field :github_handle, as: :text, link_to_record: true\n    field :admin, as: :boolean\n    field :marked_for_deletion, as: :boolean, hide_on: :index\n    field :suspicion_marked_at, as: :date_time, hide_on: :index\n    field :suspicion_cleared_at, as: :date_time, hide_on: :index\n\n    field :slug, as: :text, hide_on: :index\n    field :bio, as: :textarea, hide_on: :index\n    field :website, as: :text, hide_on: :index\n    field :twitter, as: :text, hide_on: :index\n    field :bsky, as: :text, hide_on: :index\n    field :linkedin, as: :text, hide_on: :index\n    field :mastodon, as: :text, hide_on: :index\n    field :speakerdeck, as: :text, hide_on: :index\n    field :pronouns, as: :text, hide_on: :index\n    field :pronouns_type, as: :text, hide_on: :index\n    field :location, as: :text, hide_on: :index\n    field :city, as: :text, hide_on: :index, readonly: true\n    field :state_code, as: :text, hide_on: :index, readonly: true\n    field :country_code, as: :text, hide_on: :index, readonly: true\n    field :latitude, as: :number, hide_on: :index, readonly: true\n    field :longitude, as: :number, hide_on: :index, readonly: true\n    field :geocode_metadata, as: :code, hide_on: :index, readonly: true\n    field :talks_count, as: :number, sortable: true\n\n    field :aliases, as: :has_many, hide_on: :index\n    field :talks, as: :has_many, hide_on: :index\n    field :user_talks, as: :has_many, hide_on: :index\n    field :connected_accounts, as: :has_many\n    field :sessions, as: :has_many\n    field :event_participations, as: :has_many, hide_on: :index, use_resource: Avo::Resources::EventParticipation\n    field :participated_events, as: :has_many, hide_on: :index, use_resource: Avo::Resources::Event\n    field :event_involvements, as: :has_many, hide_on: :index\n  end\n\n  def filters\n    filter Avo::Filters::Name\n    filter Avo::Filters::Slug\n    filter Avo::Filters::GitHubHandle\n    filter Avo::Filters::GitHubHandlePresence\n    filter Avo::Filters::BioPresence\n    filter Avo::Filters::LocationPresence\n    filter Avo::Filters::GeocodedPresence\n    filter Avo::Filters::Suspicious\n    filter Avo::Filters::HasDuplicate\n  end\n\n  def actions\n    action Avo::Actions::UserFetchGitHub\n    action Avo::Actions::GeocodeRecord\n    action Avo::Actions::ClearUser\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/user_talk.rb",
    "content": "class Avo::Resources::UserTalk < Avo::BaseResource\n  # self.includes = []\n  # self.attachments = []\n  # self.search = {\n  #   query: -> { query.ransack(id_eq: q, m: \"or\").result(distinct: false) }\n  # }\n\n  def fields\n    field :id, as: :id\n    field :user, as: :belongs_to\n    field :talk, as: :belongs_to\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/watch_list.rb",
    "content": "class Avo::Resources::WatchList < Avo::BaseResource\n  self.title = :name\n  self.includes = []\n\n  def fields\n    field :id, as: :id\n    field :name, as: :text\n    field :description, as: :textarea\n    field :user, as: :belongs_to\n    field :talks, as: :has_many, through: :watch_list_talks\n  end\nend\n"
  },
  {
    "path": "app/avo/resources/watch_list_talk.rb",
    "content": "class Avo::Resources::WatchListTalk < Avo::BaseResource\n  self.includes = [:talk, :watch_list]\n\n  def fields\n    field :id, as: :id\n    field :talk, as: :belongs_to\n    field :watch_list, as: :belongs_to\n    field :created_at, as: :date_time\n  end\nend\n"
  },
  {
    "path": "app/channels/application_cable/channel.rb",
    "content": "module ApplicationCable\n  class Channel < ActionCable::Channel::Base\n  end\nend\n"
  },
  {
    "path": "app/channels/application_cable/connection.rb",
    "content": "module ApplicationCable\n  class Connection < ActionCable::Connection::Base\n  end\nend\n"
  },
  {
    "path": "app/clients/application_client.rb",
    "content": "class ApplicationClient\n  class Error < StandardError; end\n\n  class Forbidden < Error; end\n\n  class Unauthorized < Error; end\n\n  class RateLimit < Error; end\n\n  class NotFound < Error; end\n\n  class InternalError < Error; end\n\n  BASE_URI = \"https://example.org\"\n  NET_HTTP_ERRORS = [Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError]\n\n  def initialize(token: nil)\n    @token = token\n  end\n\n  def default_headers\n    {\n      \"Accept\" => content_type,\n      \"Content-Type\" => content_type\n    }.merge(authorization_header)\n  end\n\n  def content_type\n    \"application/json\"\n  end\n\n  def authorization_header\n    token ? {\"Authorization\" => \"Bearer #{token}\"} : {}\n  end\n\n  def default_query_params\n    {}\n  end\n\n  def get(path, headers: {}, query: nil)\n    make_request(klass: Net::HTTP::Get, path: path, headers: headers, query: query)\n  end\n\n  def post(path, headers: {}, query: nil, body: nil, form_data: nil)\n    make_request(\n      klass: Net::HTTP::Post,\n      path: path,\n      headers: headers,\n      query: query,\n      body: body,\n      form_data: form_data\n    )\n  end\n\n  def patch(path, headers: {}, query: nil, body: nil, form_data: nil)\n    make_request(\n      klass: Net::HTTP::Patch,\n      path: path,\n      headers: headers,\n      query: query,\n      body: body,\n      form_data: form_data\n    )\n  end\n\n  def put(path, headers: {}, query: nil, body: nil, form_data: nil)\n    make_request(\n      klass: Net::HTTP::Put,\n      path: path,\n      headers: headers,\n      query: query,\n      body: body,\n      form_data: form_data\n    )\n  end\n\n  def delete(path, headers: {}, query: nil, body: nil)\n    make_request(klass: Net::HTTP::Delete, path: path, headers: headers, query: query, body: body)\n  end\n\n  def base_uri\n    self.class::BASE_URI\n  end\n\n  attr_reader :token\n\n  def make_request(klass:, path:, headers: {}, body: nil, query: nil, form_data: nil)\n    raise ArgumentError, \"Cannot pass both body and form_data\" if body.present? && form_data.present?\n\n    uri = URI(\"#{base_uri}#{path}\")\n    existing_params = Rack::Utils.parse_query(uri.query).with_defaults(default_query_params)\n    query_params = existing_params.merge(query || {})\n    uri.query = Rack::Utils.build_query(query_params) if query_params.present?\n\n    Rails.logger.debug(\"#{klass.name.split(\"::\").last.upcase}: #{uri}\")\n\n    http = Net::HTTP.new(uri.host, uri.port)\n    http.use_ssl = true if uri.instance_of? URI::HTTPS\n\n    all_headers = default_headers.merge(headers)\n    all_headers.delete(\"Content-Type\") if klass == Net::HTTP::Get\n\n    request = klass.new(uri.request_uri, all_headers)\n\n    if body.present?\n      request.body = build_body(body)\n    elsif form_data.present?\n      request.set_form(form_data, \"multipart/form-data\")\n    end\n\n    handle_response Response.new(http.request(request))\n  end\n\n  def handle_response(response)\n    case response.code\n    when \"200\", \"201\", \"202\", \"203\", \"204\"\n      response\n    when \"401\"\n      raise Unauthorized, response.body\n    when \"403\"\n      raise Forbidden, response.body\n    when \"404\"\n      raise NotFound, response.body\n    when \"429\"\n      raise RateLimit, response.body\n    when \"500\"\n      raise InternalError, response.body\n    else\n      raise Error, \"#{response.code} - #{response.body}\"\n    end\n  end\n\n  def build_body(body)\n    case body\n    when String\n      body\n    else\n      body.to_json\n    end\n  end\n\n  class Response\n    JSON_OBJECT_CLASS = OpenStruct\n    PARSER = {\n      \"application/json\" => ->(response) { JSON.parse(response.body, object_class: JSON_OBJECT_CLASS) },\n      \"application/xml\" => ->(response) { Nokogiri::XML(response.body) }\n    }\n    FALLBACK_PARSER = ->(response) { response.body }\n\n    attr_reader :original_response\n\n    delegate :code, :body, to: :original_response\n    delegate_missing_to :parsed_body\n\n    def initialize(original_response)\n      @original_response = original_response\n    end\n\n    def headers\n      @headers ||= original_response.each_header.to_h.transform_keys { |k| k.underscore.to_sym }\n    end\n\n    def content_type\n      headers[:content_type].split(\";\").first\n    end\n\n    def parsed_body\n      @parsed_body ||= PARSER.fetch(content_type, FALLBACK_PARSER).call(self)\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/blue_sky.rb",
    "content": "# frozen_string_literal: true\n\nBlueSky = DelegateClass(Minisky) do\n  alias_method :client, :__getobj__\n\n  singleton_class.attr_reader :host\n  @host = \"api.bsky.app\"\n\n  def self.build(host = self.host, **options)\n    new Minisky.new(host, nil, options)\n  end\n\n  # client = BlueSky.build(\"other.pds.host\", id:, pass:) # Allow creating ad-hoc authenticated clients.\n  # client = BlueSky.new FakeMinisky.new(\"example.com\")  # Allow injecting a stubbed Minisky for testing.\n  delegate :new, :build, to: :class\n\n  def profile_metadata(handle)\n    get_request(\"app.bsky.actor.getProfile\", {actor: handle})\n  end\nend.build\n"
  },
  {
    "path": "app/clients/github/client.rb",
    "content": "module GitHub\n  class Client < ApplicationClient\n    BASE_URI = \"https://api.github.com\"\n\n    def initialize\n      super\n    end\n\n    private\n\n    def authorization_header\n      token ? {\"Authorization\" => \"Bearer #{token}\"} : {}\n    end\n\n    def content_type\n      \"application/vnd.github+json\"\n    end\n\n    def token\n      Rails.application.credentials.github&.dig(:token) || ENV[\"RUBYVIDEO_GITHUB_TOKEN\"]\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/github/contributors_client.rb",
    "content": "module GitHub\n  class ContributorsClient < Client\n    OWNER = \"rubyevents\"\n    REPO = \"rubyevents\"\n\n    def fetch_all\n      contributors = fetch_contributors\n      enrich_with_user_data(contributors)\n    end\n\n    private\n\n    def fetch_contributors\n      contributors = []\n      page = 1\n      per_page = 100\n\n      loop do\n        response = get(\"/repos/#{OWNER}/#{REPO}/contributors\", query: {page: page, per_page: per_page})\n        batch = response.parsed_body\n\n        break if batch.empty?\n\n        contributors.concat(batch.reject { |c| c.login.include?(\"[bot]\") })\n        page += 1\n      end\n\n      contributors\n    end\n\n    def enrich_with_user_data(contributors)\n      query_fields = contributors.map.with_index do |contributor, index|\n        %{user#{index}: user(login: \"#{contributor.login}\") { login name avatarUrl url }}\n      end.join(\"\\n\")\n\n      graphql_query = \"{ #{query_fields} }\"\n\n      response = post(\"/graphql\", body: {query: graphql_query})\n      users = response.parsed_body.data.to_h.values.compact\n\n      users_by_login = users.index_by { |u| u.login }\n\n      contributors.map do |contributor|\n        user = users_by_login[contributor.login]\n        {\n          login: contributor.login,\n          name: user&.name,\n          avatar_url: user&.avatarUrl || contributor.avatar_url,\n          html_url: user&.url || contributor.html_url\n        }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/github/user_client.rb",
    "content": "module GitHub\n  class UserClient < GitHub::Client\n    def profile(username)\n      get(\"/users/#{username}\")\n    end\n\n    def social_accounts(username)\n      get(\"/users/#{username}/social_accounts\")\n    end\n\n    def search(q, per_page: 10, page: 1)\n      get(\"/search/users\", query: {q: q, per_page: per_page, page: page})\n    end\n\n    def emails\n      get(\"/user/emails\")\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/ruby_conferences/client.rb",
    "content": "module RubyConferences\n  class Client < ApplicationClient\n    BASE_URI = \"https://raw.githubusercontent.com/ruby-conferences/ruby-conferences.github.io/refs/heads/main\"\n\n    def conferences\n      YAML.load(get(\"/_data/conferences.yml\").body, permitted_classes: [Date])\n    end\n\n    def conferences_cached\n      Rails.cache.fetch(\"ruby-conferences/_data/conferences.yml\", expires_in: 1.day) do\n        conferences\n      end\n    end\n\n    private\n\n    def content_type\n      \"text/yaml\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/speakerdeck/client.rb",
    "content": "# frozen_string_literal: true\n\nmodule Speakerdeck\n  class Client < ApplicationClient\n    BASE_URI = \"https://speakerdeck.com\"\n\n    def oembed(url)\n      deck_url = normalize_url(url)\n      get(\"/oembed.json\", query: {url: deck_url})\n    end\n\n    private\n\n    def normalize_url(url)\n      if url.start_with?(\"http://\", \"https://\")\n        url\n      else\n        \"#{BASE_URI}/#{url}\"\n      end\n    end\n\n    def authorization_header\n      {}\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/youtube/channels.rb",
    "content": "require \"open-uri\"\n\nmodule YouTube\n  class Channels < YouTube::Client\n    def id_by_name(channel_name:)\n      response = get(\"/channels\", query: {forUsername: \"\\\"#{channel_name}\\\"\", key: token, part: \"snippet,contentDetails,statistics\"})\n      response.try(:items)&.first&.id || fallback_using_scrapping(channel_name: channel_name)\n    end\n\n    private\n\n    def default_headers\n      {\n        \"Content-Type\" => \"application/json\"\n      }\n    end\n\n    def fallback_using_scrapping(channel_name:)\n      # for some reason I was unable to get the channel id for paris-rb\n      # this is a fallback solution using a scrapping approach\n      html = URI.open(\"https://www.youtube.com/@#{channel_name}\")\n      doc = Nokogiri::HTML(html)\n\n      meta_tag = doc.at_css('meta[itemprop=\"identifier\"]')\n      meta_tag[\"content\"]\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/youtube/client.rb",
    "content": "module YouTube\n  class Client < ApplicationClient\n    BASE_URI = \"https://youtube.googleapis.com/youtube/v3\"\n\n    private\n\n    def all_items(path, query: {})\n      response = get(path, query: query.merge({key: token, maxResults: 50}))\n      all_items = response.items\n\n      loop do\n        next_page_token = response.try(:nextPageToken)\n        break if next_page_token.nil?\n        response = get(path, query: query.merge({key: token, maxResults: 50, pageToken: next_page_token}))\n        all_items += response.items\n      end\n      all_items\n    end\n\n    def default_headers\n      {\n        \"Content-Type\" => \"application/json\"\n      }\n    end\n\n    def token\n      Rails.application.credentials.youtube&.dig(:api_key) || ENV[\"YOUTUBE_API_KEY\"]\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/youtube/playlist_items.rb",
    "content": "module YouTube\n  class PlaylistItems < YouTube::Client\n    def all(playlist_id:)\n      all_items(\"/playlistItems\", query: {playlistId: playlist_id, part: \"snippet,contentDetails\"}).map do |metadata|\n        OpenStruct.new({\n          id: metadata.id,\n          title: metadata.snippet.title,\n          description: metadata.snippet.description,\n          published_at: DateTime.parse(metadata.snippet.publishedAt).to_date.to_s,\n          channel_id: metadata.snippet.channelId,\n          year: metadata.snippet.title.match(/\\d{4}/).to_s.presence || DateTime.parse(metadata.snippet.publishedAt).year,\n          slug: metadata.snippet.title.parameterize,\n          thumbnail_xs: metadata.snippet.thumbnails.default&.url,\n          thumbnail_sm: metadata.snippet.thumbnails.medium&.url,\n          thumbnail_md: metadata.snippet.thumbnails.high&.url,\n          thumbnail_lg: metadata.snippet.thumbnails.standard&.url,\n          thumbnail_xl: metadata.snippet.thumbnails.maxres&.url,\n          video_provider: \"youtube\",\n          video_id: metadata.contentDetails.videoId\n        })\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/youtube/playlists.rb",
    "content": "module YouTube\n  class Playlists < YouTube::Client\n    DEFAULT_METADATA_PARSER = \"YouTube::VideoMetadata\"\n\n    def all(channel_id:, title_matcher: nil)\n      items = all_items(\"/playlists\", query: {channelId: channel_id, part: \"snippet,contentDetails\"}).map do |metadata|\n        year = metadata.snippet.title.match(/\\d{4}/).to_s.presence || DateTime.parse(metadata.snippet.publishedAt).year\n\n        OpenStruct.new({\n          id: metadata.id,\n          title: metadata.snippet.title,\n          kind: \"conference\",\n          location: \"Earth\",\n          description: metadata.snippet.description,\n          published_at: DateTime.parse(metadata.snippet.publishedAt).to_date.to_s,\n          start_date: \"#{year}-xx-xx\",\n          end_date: \"#{year}-xx-xx\",\n          channel_id: metadata.snippet.channelId,\n          year: year.to_i,\n          videos_count: metadata.contentDetails.itemCount,\n          metadata_parser: DEFAULT_METADATA_PARSER,\n          slug: metadata.snippet.title.parameterize,\n          banner_background: \"#081625\",\n          featured_background: \"#000000\",\n          featured_color: \"#FFFFFF\"\n        })\n      end\n      items = items.select { |item| item.title.match?(string_to_regex(title_matcher)) } if title_matcher\n      items\n    end\n\n    private\n\n    def string_to_regex(str)\n      Regexp.new(str, \"i\")\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/youtube/thumbnail.rb",
    "content": "# frozen_string_literal: true\n\nmodule YouTube\n  class Thumbnail\n    SIZES = %w[maxresdefault sddefault hqdefault mqdefault default].freeze\n    DEFAULT_MAX_SIZE = 5000\n    EXPECTED_ASPECT_RATIO = 16.0 / 9.0\n    ASPECT_RATIO_TOLERANCE = 0.1\n\n    SIZE_MAPPING = {\n      thumbnail_xl: \"maxresdefault\",\n      thumbnail_lg: \"sddefault\",\n      thumbnail_md: \"hqdefault\",\n      thumbnail_sm: \"mqdefault\",\n      thumbnail_xs: \"default\"\n    }.freeze\n\n    def initialize(video_id)\n      @video_id = video_id\n    end\n\n    def best_url\n      best_url_from(\"maxresdefault\")\n    end\n\n    def best_url_for(talk_size)\n      starting_size = SIZE_MAPPING[talk_size.to_sym]\n      return nil unless starting_size\n\n      best_url_from(starting_size)\n    end\n\n    def best_url_from(starting_size)\n      start_index = SIZES.index(starting_size) || 0\n      candidate_sizes = SIZES[start_index..]\n\n      candidate_sizes.each do |size|\n        url = url_for(size)\n\n        next if default?(url)\n        next unless valid_aspect_ratio?(url)\n\n        return url\n      end\n\n      candidate_sizes.each do |size|\n        url = url_for(size)\n\n        return url unless default?(url)\n      end\n\n      nil\n    end\n\n    def url_for(size)\n      \"https://i.ytimg.com/vi/#{@video_id}/#{size}.jpg\"\n    end\n\n    def default?(url)\n      content_length(url) < DEFAULT_MAX_SIZE\n    rescue => e\n      Rails.logger.error(\"Error checking YouTube thumbnail #{url}: #{e.message}\")\n      false\n    end\n\n    def valid_aspect_ratio?(url)\n      uri = URI.parse(url)\n\n      response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n        http.open_timeout = 5\n        http.read_timeout = 5\n        http.request_get(uri.path)\n      end\n\n      image = MiniMagick::Image.read(response.body)\n      aspect_ratio = image.width.to_f / image.height\n\n      (aspect_ratio - EXPECTED_ASPECT_RATIO).abs < ASPECT_RATIO_TOLERANCE\n    rescue => e\n      Rails.logger.error(\"Error checking aspect ratio for #{url}: #{e.message}\")\n      false\n    end\n\n    private\n\n    def content_length(url)\n      uri = URI.parse(url)\n\n      response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|\n        http.open_timeout = 5\n        http.read_timeout = 5\n        http.request_head(uri.path)\n      end\n\n      response[\"Content-Length\"].to_i\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/youtube/transcript.rb",
    "content": "require \"protobuf/message_type\"\n\nmodule YouTube\n  class Transcript\n    attr_reader :response\n\n    def get(video_id)\n      message = {one: \"asr\", two: \"en\"}\n      typedef = MessageType\n      two = get_base64_protobuf(message, typedef)\n\n      message = {one: video_id, two: two}\n      params = get_base64_protobuf(message, typedef)\n\n      url = \"https://www.youtube.com/youtubei/v1/get_transcript\"\n      headers = {\"Content-Type\" => \"application/json\"}\n      body = {\n        context: {\n          client: {\n            clientName: \"WEB\",\n            clientVersion: \"2.20240313\"\n          }\n        },\n        params: params\n      }\n\n      @response = HTTParty.post(url, headers: headers, body: body.to_json)\n      JSON.parse(@response.body)\n    end\n\n    def self.get(video_id)\n      new.get(video_id)\n    end\n\n    private\n\n    def encode_message(message, typedef)\n      encoded_message = typedef.new(message)\n      encoded_message.to_proto\n    end\n\n    def get_base64_protobuf(message, typedef)\n      encoded_data = encode_message(message, typedef)\n      Base64.encode64(encoded_data).delete(\"\\n\")\n    end\n  end\nend\n"
  },
  {
    "path": "app/clients/youtube/video.rb",
    "content": "module YouTube\n  class Video < Client\n    def available?(video_id)\n      path = \"/videos\"\n      query = {\n        part: \"status\",\n        id: video_id\n      }\n\n      response = all_items(path, query: query)\n      response.present?\n    end\n\n    def get_statistics(video_id)\n      path = \"/videos\"\n      query = {\n        part: \"statistics\",\n        id: video_id\n      }\n\n      response = all_items(path, query: query)\n\n      return unless response.present?\n\n      response.each_with_object({}) do |item, hash|\n        hash[item[\"id\"]] = {\n          view_count: item[\"statistics\"][\"viewCount\"],\n          like_count: item[\"statistics\"][\"likeCount\"]\n        }\n      end\n    end\n\n    def duration(video_id)\n      path = \"/videos\"\n      query = {\n        part: \"contentDetails\",\n        id: video_id\n      }\n\n      response = all_items(path, query: query)\n\n      duration_str = response&.first&.dig(\"contentDetails\", \"duration\")\n\n      return nil unless duration_str\n\n      # Convert ISO 8601 duration (PT1H1M17S) to seconds\n      ActiveSupport::Duration.parse(duration_str).to_i\n    end\n  end\nend\n"
  },
  {
    "path": "app/components/application_component.rb",
    "content": "# frozen_string_literal: true\n\nclass ApplicationComponent < ViewComponent::Base\n  extend Dry::Initializer\n\n  attr_accessor :attributes\n  option :display, default: proc { true }\n\n  def initialize(*, **options)\n    super\n    defined_option_keys = self.class.dry_initializer.options.map(&:source)\n    self.attributes = options.except(*defined_option_keys)\n  end\n\n  def render?\n    display\n  end\nend\n"
  },
  {
    "path": "app/components/events/upcoming_event_banner_component.html.erb",
    "content": "<a href=\"<%= helpers.event_tickets_path(upcoming_event) %>\" data-turbo-frame=\"_top\" class=\"rounded-xl group border hover:opacity-95 transition-opacity duration-300 ease-in-out w-full flex flex-row px-6 py-6 gap-8 mt-4 overflow-hidden\" style=\"background: <%= background_style %>; color: <%= text_color %>;\">\n  <div class=\"aspect-video hidden md:block\">\n    <%= image_tag helpers.image_path(upcoming_event.featured_image_path), alt: upcoming_event.name, class: \"h-24 aspect-video rounded-xl group-hover:scale-105 transition ease-in-out duration-300\" %>\n  </div>\n\n  <div class=\"flex flex-col w-full flex-1 self-center\">\n    <span class=\"text-lg font-semibold sm:text-md\">\n      <%= upcoming_event.name %> is coming up!\n    </span>\n\n    <span class=\"opacity-80 text-sm mt-1\">\n      <%= upcoming_event.location %> &bull; <%= upcoming_event.formatted_dates %>\n    </span>\n\n    <div class=\"mt-3\">\n      <span class=\"btn btn-sm border-0\" style=\"background: <%= text_color %>; color: <%= background_color %>;\">\n        Get Tickets\n      </span>\n    </div>\n  </div>\n</a>\n"
  },
  {
    "path": "app/components/events/upcoming_event_banner_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Events::UpcomingEventBannerComponent < ApplicationComponent\n  option :event, optional: true\n  option :event_series, optional: true\n\n  def render?\n    upcoming_event.present? && should_show_banner?\n  end\n\n  def upcoming_event\n    @upcoming_event ||= if event.present?\n      event.next_upcoming_event_with_tickets\n    elsif event_series.present?\n      event_series.next_upcoming_event_with_tickets\n    end\n  end\n\n  def background_style\n    bg = upcoming_event.static_metadata.featured_background\n    return bg unless bg.start_with?(\"data:\")\n\n    \"url('#{bg}'); background-repeat: no-repeat; background-size: cover\"\n  end\n\n  def background_color\n    bg = upcoming_event.static_metadata.featured_background\n    bg.start_with?(\"data:\") ? \"#000000\" : bg\n  end\n\n  def text_color\n    upcoming_event.static_metadata.featured_color\n  end\n\n  private\n\n  def should_show_banner?\n    if event.present?\n      event.past?\n    else\n      true\n    end\n  end\nend\n"
  },
  {
    "path": "app/components/hover_card/base_component.html.erb",
    "content": "<div class=\"absolute left-1/2 -translate-x-1/2 bottom-full mb-2 w-80 opacity-0 invisible group-hover/card:opacity-100 group-hover/card:visible transition-opacity duration-150 z-50\" data-hover-card-target=\"card\" hidden>\n  <%= turbo_frame_tag frame_id, src: hover_card_url, loading: \"lazy\", target: \"_top\" %>\n</div>\n"
  },
  {
    "path": "app/components/hover_card/base_component.rb",
    "content": "# frozen_string_literal: true\n\nclass HoverCard::BaseComponent < ViewComponent::Base\n  include Turbo::FramesHelper\n\n  attr_reader :record, :avatar_size\n\n  def initialize(record:, avatar_size: :sm)\n    @record = record\n    @avatar_size = avatar_size\n  end\n\n  def frame_id\n    dom_id(record, :hover_card)\n  end\n\n  def hover_card_url\n    raise NotImplementedError, \"Subclasses must implement #hover_card_url\"\n  end\n\n  def render?\n    record.present?\n  end\nend\n"
  },
  {
    "path": "app/components/hover_card/event_component.rb",
    "content": "# frozen_string_literal: true\n\nclass HoverCard::EventComponent < HoverCard::BaseComponent\n  def hover_card_url\n    Router.hover_cards_event_path(slug: record.slug)\n  end\nend\n"
  },
  {
    "path": "app/components/hover_card/user_component.rb",
    "content": "# frozen_string_literal: true\n\nclass HoverCard::UserComponent < HoverCard::BaseComponent\n  def hover_card_url\n    Router.hover_cards_user_path(slug: record.slug, avatar_size: avatar_size)\n  end\n\n  def render?\n    super && !record.suspicious?\n  end\nend\n"
  },
  {
    "path": "app/components/tito/button_component.html.erb",
    "content": "<%= link_to label, helpers.event_tickets_path(event), class: classes %>\n"
  },
  {
    "path": "app/components/tito/button_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Tito::ButtonComponent < ApplicationComponent\n  option :event\n  option :label, default: -> { \"Tickets\" }\n\n  def render?\n    display && event.tickets.available?\n  end\n\n  def classes\n    \"btn btn-primary btn-sm w-full no-animation\"\n  end\nend\n"
  },
  {
    "path": "app/components/tito/widget_component.html.erb",
    "content": "<% content_for :head do %>\n  <script src=\"https://js.tito.io/v2\" async></script>\n<% end %>\n\n<% if wrapper %>\n  <div class=\"mt-6 p-4 bg-gray-100 rounded-lg max-w-[700px]\">\n    <h3 class=\"font-bold text-lg mb-2\">Register</h3>\n    <tito-widget event=\"<%= event_slug %>\"></tito-widget>\n  </div>\n<% else %>\n  <tito-widget event=\"<%= event_slug %>\"></tito-widget>\n<% end %>\n"
  },
  {
    "path": "app/components/tito/widget_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Tito::WidgetComponent < ApplicationComponent\n  option :event\n  option :wrapper, default: -> { true }\n\n  def render?\n    display && event.tickets.tito? && event.upcoming?\n  end\n\n  def event_slug\n    event.tickets.tito_event_slug\n  end\nend\n"
  },
  {
    "path": "app/components/ui/avatar_component.html.erb",
    "content": "<% avatar_markup = capture do %>\n  <div class=\"avatar placeholder\">\n    <div class=\"<%= avatar_classes %>\">\n      <% if content %>\n        <%= content %>\n      <% else %>\n        <span class=\"<%= text_size %> <%= \"hidden\" if show_custom_avatar? %>\"><%= initials %></span>\n        <% if show_custom_avatar? %>\n          <%= image_tag avatar_url_for_size, loading: \"lazy\", onerror: \"this.previousElementSibling.classList.remove('hidden'); this.remove()\" %>\n        <% end %>\n      <% end %>\n    </div>\n  </div>\n<% end %>\n\n<% if show_hover_card? %>\n  <div class=\"relative group/card\" data-controller=\"hover-card\" data-action=\"mouseenter->hover-card#reveal\">\n    <% if show_link? %>\n      <%= link_to link_path do %><%= avatar_markup %><% end %>\n    <% else %>\n      <%= avatar_markup %>\n    <% end %>\n    <%= render HoverCard::UserComponent.new(record: avatarable, avatar_size: size) %>\n  </div>\n<% elsif show_link? %>\n  <%= link_to link_path do %><%= avatar_markup %><% end %>\n<% else %>\n  <%= avatar_markup %>\n<% end %>\n"
  },
  {
    "path": "app/components/ui/avatar_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Ui::AvatarComponent < ApplicationComponent\n  SIZE_MAPPING = {\n    xs: {\n      size_class: \"w-6\",\n      image_size: 32,\n      text_size: \"text-xs\"\n    },\n    sm: {\n      size_class: \"w-8\",\n      image_size: 48,\n      text_size: \"text-xs\"\n    },\n    md: {\n      size_class: \"w-12\",\n      image_size: 96,\n      text_size: \"text-lg\"\n    },\n    lg: {\n      size_class: \"w-40\",\n      image_size: 200,\n      text_size: \"text-6xl\"\n    }\n  }.freeze\n\n  KIND_MAPPING = {\n    primary: \"bg-primary\",\n    neutral: \"bg-neutral\"\n  }.freeze\n\n  param :avatarable\n  option :size, Dry::Types[\"coercible.symbol\"].enum(*SIZE_MAPPING.keys), default: proc { :md }\n  option :size_class, Dry::Types[\"coercible.string\"], default: proc { SIZE_MAPPING[size][:size_class] }\n  option :outline, type: Dry::Types[\"strict.bool\"], default: proc { false }\n  option :kind, Dry::Types[\"coercible.symbol\"].enum(*KIND_MAPPING.keys), default: proc { :primary }\n  option :hover_card, type: Dry::Types[\"strict.bool\"], default: proc { false }\n  option :linked, type: Dry::Types[\"strict.bool\"], default: proc { false }\n\n  def show_hover_card?\n    hover_card && avatarable.is_a?(User)\n  end\n\n  def show_link?\n    linked && avatarable.present?\n  end\n\n  def link_path\n    return nil unless avatarable.present?\n\n    if avatarable.is_a?(User)\n      helpers.profile_path(avatarable)\n    elsif avatarable.respond_to?(:slug)\n      helpers.speaker_path(avatarable)\n    end\n  end\n\n  def avatar_classes\n    [\n      size_class,\n      \"rounded-full\",\n      kind_class,\n      \"text-neutral-content\",\n      (outline ? \"outline outline-2\" : nil)\n    ].compact.join(\" \")\n  end\n\n  def initials\n    return \"\" unless avatarable&.name.present?\n    avatarable.name.split(\" \").map(&:first).join\n  end\n\n  def has_custom_avatar?\n    avatarable&.respond_to?(:custom_avatar?) && avatarable.custom_avatar?\n  end\n\n  def avatar_url_for_size\n    avatarable.avatar_url(size: image_size)\n  end\n\n  private\n\n  def image_size\n    SIZE_MAPPING[size][:image_size]\n  end\n\n  def text_size\n    SIZE_MAPPING[size][:text_size]\n  end\n\n  def kind_class\n    KIND_MAPPING[kind]\n  end\n\n  def suspicious?\n    avatarable&.respond_to?(:suspicious?) && avatarable.suspicious?\n  end\n\n  def show_custom_avatar?\n    avatarable&.custom_avatar? && !suspicious?\n  end\nend\n"
  },
  {
    "path": "app/components/ui/avatar_group_component.html.erb",
    "content": "<div class=\"avatar-group <%= overlap %> rtl:space-x-reverse\">\n  <% visible_avatarables.each do |avatarable| %>\n    <%= render Ui::AvatarComponent.new(avatarable, size: size, hover_card: hover_card, linked: linked) %>\n  <% end %>\n\n  <% if remaining_count > 0 %>\n    <%= render Ui::AvatarComponent.new(nil, size: size) do %>\n      <span>+<%= remaining_count %></span>\n    <% end %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/components/ui/avatar_group_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Ui::AvatarGroupComponent < ApplicationComponent\n  SIZE_MAPPING = {\n    sm: \"w-8\",\n    md: \"w-12\",\n    lg: \"w-16\"\n  }.freeze\n\n  param :avatarables, Dry::Types[\"strict.array\"]\n  option :size, Dry::Types[\"coercible.symbol\"].enum(*SIZE_MAPPING.keys), default: proc { :md }\n  option :max, Dry::Types[\"coercible.integer\"], default: proc { 8 }\n  option :overlap, Dry::Types[\"coercible.string\"], default: proc { \"-space-x-3\" }\n  option :hover_card, type: Dry::Types[\"strict.bool\"], default: proc { false }\n  option :linked, type: Dry::Types[\"strict.bool\"], default: proc { false }\n\n  private\n\n  def visible_avatarables\n    avatarables.first(max)\n  end\n\n  def remaining_count\n    [avatarables.size - max, 0].max\n  end\n\n  def size_class\n    SIZE_MAPPING[size]\n  end\nend\n"
  },
  {
    "path": "app/components/ui/badge_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Ui::BadgeComponent < ApplicationComponent\n  KIND_MAPPING = {\n    neutral: \"badge-neutral\",\n    primary: \"badge-primary\",\n    secondary: \"badge-secondary\",\n    accent: \"badge-accent\",\n    info: \"badge-info\",\n    success: \"badge-success\",\n    warning: \"badge-warning\",\n    error: \"badge-error\",\n    ghost: \"badge-ghost\"\n  }\n\n  SIZE_MAPPING = {\n    xs: \"badge-xs\",\n    sm: \"badge-sm\",\n    md: \"badge-md\",\n    lg: \"badge-lg\"\n  }\n\n  param :text, optional: true\n  option :kind, type: Dry::Types[\"coercible.symbol\"].enum(*KIND_MAPPING.keys), default: proc { :primary }\n  option :size, type: Dry::Types[\"coercible.symbol\"].enum(*SIZE_MAPPING.keys), default: proc { :md }\n  option :outline, type: Dry::Types[\"strict.bool\"], default: proc { false }\n\n  def call\n    content_tag(:span, class: classes, **attributes.except(:class)) do\n      concat content\n    end\n  end\n\n  private\n\n  def classes\n    [component_classes, attributes[:class]].join(\" \")\n  end\n\n  def component_classes\n    class_names(\n      \"badge\",\n      KIND_MAPPING[kind],\n      SIZE_MAPPING[size],\n      \"badge-outline\": outline\n    )\n  end\n\n  def content\n    text.presence || super\n  end\nend\n"
  },
  {
    "path": "app/components/ui/button_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Ui::ButtonComponent < ApplicationComponent\n  KIND_MAPPING = {\n    primary: \"btn-primary\",\n    secondary: \"btn-secondary\",\n    neutral: \"btn-neutral btn-outline\",\n    rounded: \"btn btn-rounded\",\n    pill: \"btn btn-pill btn-sm\",\n    circle: \"btn btn-circle\",\n    ghost: \"btn-ghost\",\n    link: \"btn-link\",\n    none: \"\"\n  }\n\n  SIZE_MAPPING = {\n    sm: \"btn-sm\",\n    md: \"\",\n    lg: \"btn-lg\"\n  }\n\n  param :text, default: proc {}\n  option :url, Dry::Types[\"coercible.string\"], optional: true\n  option :method, Dry::Types[\"coercible.symbol\"].enum(:get, :post, :patch, :put, :delete), optional: true\n  option :kind, type: Dry::Types[\"coercible.symbol\"].enum(*KIND_MAPPING.keys), default: proc { :primary }\n  option :size, type: Dry::Types[\"coercible.symbol\"].enum(*SIZE_MAPPING.keys), default: proc { :md }\n  option :type, type: Dry::Types[\"coercible.symbol\"].enum(:button, :submit, :input), default: proc { :button }\n  option :disabled, type: Dry::Types[\"strict.bool\"], default: proc { false }\n  option :outline, type: Dry::Types[\"strict.bool\"], default: proc { false }\n  option :animation, type: Dry::Types[\"strict.bool\"], default: proc { false }\n\n  def call\n    case button_kind\n    when :link\n      link_to(url, disabled: disabled, class: classes, **attributes.except(:class, :type)) { content }\n    when :button_to\n      button_to(url, disabled: disabled, method: method, class: classes, **attributes.except(:class, :type)) { content }\n    when :button\n      tag.button(type: type, disabled: disabled, class: classes, **attributes.except(:class, :type)) { content }\n    end\n  end\n\n  private\n\n  def classes\n    [component_classes, attributes[:class]].join(\" \")\n  end\n\n  def component_classes\n    class_names(\n      \"btn\",\n      KIND_MAPPING[kind],\n      SIZE_MAPPING[size],\n      \"btn-outline\": outline,\n      \"btn-disabled\": disabled,\n      \"no-animation\": !animation # animation is disabled by default, I don't really like the effect when you enter the page\n    )\n  end\n\n  def content\n    text.presence || super\n  end\n\n  def button_kind\n    return :link if url.present? && default_method?\n    return :button_to if url.present? && !default_method?\n\n    :button\n  end\n\n  def default_method?\n    method.blank? || method == :get\n  end\nend\n"
  },
  {
    "path": "app/components/ui/divider_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Ui::DividerComponent < ApplicationComponent\n  KIND_MAPPING = {\n    horizontal: \"divider-horizontal\",\n    vertical: \"divider-vertical\"\n  }\n\n  param :text, optional: true\n  option :kind, type: Dry::Types[\"coercible.symbol\"].enum(*KIND_MAPPING.keys), optional: true\n\n  def call\n    content_tag(:div, class: classes, **attributes.except(:class)) do\n      concat content\n    end\n  end\n\n  private\n\n  def classes\n    [component_classes, attributes[:class]].join(\" \")\n  end\n\n  def component_classes\n    class_names(\n      \"divider\",\n      KIND_MAPPING[kind]\n    )\n  end\n\n  def content\n    text.presence || super\n  end\nend\n"
  },
  {
    "path": "app/components/ui/dropdown_component.html.erb",
    "content": "<%= content_tag :details, class: classes, **attributes do %>\n  <summary class=\"flex after:hidden\">\n    <% if toggle_open? && toggle_close? %>\n      <div class=\"swap\" data-dropdown-target=\"swap\">\n        <div class=\"swap-on\"><%= toggle_open %></div>\n        <div class=\"swap-off\"><%= toggle_close %></div>\n      </div>\n    <% else %>\n      <%= content %>\n    <% end %>\n  </summary>\n  <%= content_tag :ul, class: content_classes do %>\n    <% menu_items.each do |menu_item| %>\n      <%= menu_item %>\n    <% end %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/components/ui/dropdown_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Ui::DropdownComponent < ApplicationComponent\n  renders_many :menu_items, types: {\n    divider: lambda { render Ui::DividerComponent.new(class: \"my-2\") },\n    link_to: lambda { |*args, **attributes, &block|\n      content_tag :li do\n        attributes[:class] = class_names(\"!whitespace-nowrap\", attributes[:class])\n        concat link_to(*args, **attributes, &block)\n      end\n    },\n    button_to: lambda { |*args, **attributes|\n      content_tag :li do\n        attributes[:class] = class_names(\"!whitespace-nowrap\", attributes[:class])\n        concat button_to(*args, **attributes)\n      end\n    }\n  }\n\n  renders_one :toggle_open\n  renders_one :toggle_close\n\n  OPEN_FROM_MAPPING = {\n    left: \"dropdown-left\",\n    right: \"dropdown-right\",\n    top: \"dropdown-top\",\n    bottom: \"dropdown-bottom\"\n  }\n\n  ALIGN_MAPPING = {\n    end: \"dropdown-end\"\n  }\n\n  option :open, type: Dry::Types[\"strict.bool\"], default: proc { false }\n  option :hover, type: Dry::Types[\"strict.bool\"], default: proc { false }\n  option :align, type: Dry::Types[\"coercible.symbol\"].enum(*ALIGN_MAPPING.keys), optional: true\n  option :open_from, type: Dry::Types[\"coercible.symbol\"].enum(*OPEN_FROM_MAPPING.keys), optional: true\n\n  private\n\n  def before_render\n    attributes[:data] = {controller: \"dropdown\"}\n  end\n\n  def classes\n    [component_classes, attributes.delete(:class)].compact_blank.join(\" \")\n  end\n\n  def component_classes\n    class_names(\n      \"dropdown\",\n      OPEN_FROM_MAPPING[open_from],\n      ALIGN_MAPPING[align],\n      \"dropdown-hover\": hover,\n      \"dropdown-open\": open\n    )\n  end\n\n  def content_classes\n    class_names(\"dropdown-content menu menu-smp-2 mt-4 w-max z-30 rounded-lg shadow-2xl bg-white text-neutral\", attributes.delete(:content_classes))\n  end\nend\n"
  },
  {
    "path": "app/components/ui/modal_component.html.erb",
    "content": "<%= content_tag :dialog, role: :dialog, aria: {modal: true}, class: classes, **attributes do %>\n  <div class=\"modal-box <%= size_class %>\" data-modal-target=\"modalBox\">\n    <% if close_button %>\n      <button\n        class=\"btn btn-sm btn-circle btn-ghost absolute right-2 top-2\"\n        data-action=\"click->modal#close\">\n        <%= helpers.fa :xmark %>\n      </button>\n    <% end %>\n    <%= content %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/components/ui/modal_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Ui::ModalComponent < ApplicationComponent\n  POSITION_MAPPING = {\n    top: \"modal-top\",\n    bottom: \"modal-bottom\",\n    middle: \"modal-middle\",\n    responsive: \"modal-bottom sm:modal-middle\"\n  }\n\n  SIZE_MAPPING = {\n    md: \"\",\n    lg: \"!max-w-[800px]\",\n    xl: \"!max-w-[1200px]\",\n    full: \"!max-w-[95vw] !w-[95vw] !max-h-[90vh]\"\n  }\n\n  option :open, type: Dry::Types[\"strict.bool\"], default: proc { false }\n  option :close_button, type: Dry::Types[\"strict.bool\"], default: proc { true }\n  option :position, type: Dry::Types[\"coercible.symbol\"].enum(*POSITION_MAPPING.keys), optional: true, default: proc { :responsive }\n  option :size, type: Dry::Types[\"coercible.symbol\"].enum(*SIZE_MAPPING.keys), optional: true, default: proc { :md }\n\n  private\n\n  def before_render\n    default_action = \"keydown.esc->modal#close\"\n    custom_action = attributes[:data]&.delete(:action)\n    combined_action = [default_action, custom_action].compact.join(\" \")\n\n    attributes[:data] = {\n      controller: \"modal\",\n      modal_open_value: open,\n      action: combined_action\n    }.merge(attributes[:data] || {})\n  end\n\n  def classes\n    [component_classes, attributes.delete(:class)].compact_blank.join(\" \")\n  end\n\n  def component_classes\n    class_names(\n      \"modal\",\n      POSITION_MAPPING[position]\n    )\n  end\n\n  def size_class\n    SIZE_MAPPING[size]\n  end\n\n  def content_classes\n    class_names(\"dropdown-content menu menu-sm p-2 mt-4 w-max z-[1] rounded-lg shadow-2xl bg-white text-neutral\", attributes.delete(:content_classes))\n  end\nend\n"
  },
  {
    "path": "app/components/ui/stamp_component.html.erb",
    "content": "<% if interactive && clickable? %>\n  <%= link_to(url, **link_attributes.deep_merge(data: {turbo_frame: \"_top\"})) do %>\n    <%= image_tag(stamp.asset_path,\n          alt: \"#{stamp.name} passport stamp\",\n          class: classes,\n          style: image_style,\n          loading: \"lazy\") %>\n  <% end %>\n<% else %>\n  <%= image_tag(stamp.asset_path,\n        alt: \"#{stamp.name} passport stamp\",\n        class: classes,\n        style: image_style,\n        loading: \"lazy\") %>\n<% end %>\n"
  },
  {
    "path": "app/components/ui/stamp_component.rb",
    "content": "# frozen_string_literal: true\n\nclass Ui::StampComponent < ApplicationComponent\n  SIZE_MAPPING = {\n    unset: \"\",\n    full: \"w-full h-full\",\n    sm: \"w-12 h-12\",\n    md: \"w-16 h-16\",\n    lg: \"w-20 h-20\",\n    xl: \"w-32 h-32\"\n  }\n\n  param :stamp\n  option :size, type: Dry::Types[\"coercible.symbol\"].enum(*SIZE_MAPPING.keys), default: proc { :full }\n  option :interactive, type: Dry::Types[\"strict.bool\"], default: proc { true }\n  option :rotate, type: Dry::Types[\"strict.bool\"], default: proc { false }\n  option :zoom_effect, type: Dry::Types[\"strict.bool\"], default: proc { false }\n\n  def kind\n    if stamp.has_country?\n      :country\n    elsif stamp.has_event?\n      :event\n    elsif stamp.code == \"RUBYEVENTS-CONTRIBUTOR\"\n      :contributor\n    else\n      :other\n    end\n  end\n\n  def clickable?\n    [:country, :event, :contributor].include?(kind)\n  end\n\n  def url\n    case kind\n    when :country\n      stamp.country.path\n    when :event\n      stamp.event ? event_path(stamp.event) : nil\n    when :contributor\n      contributors_path\n    when :other\n      nil\n    end\n  end\n\n  def link_attributes\n    attributes.except(:class)\n  end\n\n  def classes\n    [component_classes, attributes[:class]].join(\" \")\n  end\n\n  def image_style\n    transform = []\n\n    transform << \"rotate(#{rand(-15..15)}deg)\" if rotate\n    transform << \"scale(#{rand(0.92..0.97)})\" if zoom_effect\n    \"transform: #{transform.join(\" \")};\"\n  end\n\n  def component_classes\n    class_names(\n      \"aspect-square flex items-center justify-center\",\n      SIZE_MAPPING[size],\n      attributes.delete(:class),\n      \"transition-transform duration-300 lg:hover:!scale-110 lg:hover:!rotate-0\": zoom_effect\n    )\n  end\nend\n"
  },
  {
    "path": "app/controllers/admin/suggestions_controller.rb",
    "content": "module Admin\n  class SuggestionsController < ApplicationController\n    include Pagy::Backend\n\n    def index\n      @pagy, @suggestions = pagy(Suggestion.pending.order(created_at: :asc))\n    end\n\n    def update\n      @suggestion = Suggestion.find(params[:id])\n      @suggestion.approved!(approver: Current.user)\n      redirect_to admin_suggestions_path\n    end\n\n    def destroy\n      @suggestion = Suggestion.find(params[:id])\n      @suggestion.rejected!\n      redirect_to admin_suggestions_path\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/analytics/dashboards_controller.rb",
    "content": "class Analytics::DashboardsController < ApplicationController\n  skip_before_action :authenticate_user!\n  before_action :admin_required, only: %i[top_referrers top_landing_pages top_searches]\n\n  def daily_visits\n    @daily_visits = Rollup.where(time: 60.days.ago.to_date..Date.yesterday.end_of_day).series(\"ahoy_visits\", interval: :day)\n  end\n\n  def daily_page_views\n    @daily_page_views = Rollup.where(time: 60.days.ago.to_date..Date.yesterday.end_of_day).series(\"ahoy_events\", interval: :day)\n  end\n\n  def monthly_visits\n    @monthly_visits = Rollup.where(time: 12.months.ago.to_date.beginning_of_month..Date.yesterday.end_of_day).series(\"ahoy_visits\", interval: :month)\n  end\n\n  def monthly_page_views\n    @monthly_page_views = Rollup.where(time: 12.months.ago.to_date.beginning_of_month..Date.yesterday.end_of_day).series(\"ahoy_events\", interval: :month)\n  end\n\n  def yearly_conferences\n    # 1. Might be inefficient, but it's a first step. Note that Rollup class doesn't seem to contain\n    #   conferences at the moment. To optimize this code, we probably want to add yearly info to the Rollup class.\n    # 2. Note that some years are integers and some are strings. We should probably convert them all to either format in import.\n    #   (to reproduce, remove the `.to_s` in the map below)\n    @yearly_conferences = Event.all.select(&:conference?).select { |event| event.start_date.present? || event.static_metadata.year.present? }.group_by { |event| event.start_date&.year || event.static_metadata.year.to_i }.map { |year, events| [year.to_s, events.count] }.sort\n  end\n\n  def yearly_talks\n    @yearly_talks = Rollup.series(\"talks\", interval: :year).map { |date, count| [date.year.to_s, count] }.sort\n  end\n\n  def top_referrers\n    @top_referrers = Rails.cache.fetch(\"top_referrers\", expires_at: Time.current.end_of_day) do\n      Ahoy::Visit\n        .where(\"date(started_at) BETWEEN ? AND ?\", 60.days.ago.to_date, Date.yesterday)\n        .where.not(referring_domain: [nil, \"\", \"rubyvideo.dev\", \"www.rubyvideo.dev\", \"rubyevents.org\", \"www.rubyevents.org\"])\n        .group(:referring_domain)\n        .order(Arel.sql(\"COUNT(*) DESC\"))\n        .limit(10)\n        .count\n    end\n  end\n\n  def top_landing_pages\n    @top_landing_pages = Rails.cache.fetch(\"top_landing_pages\", expires_at: Time.current.end_of_day) do\n      Ahoy::Visit\n        .where(\"date(started_at) BETWEEN ? AND ?\", 60.days.ago.to_date, Date.yesterday)\n        .where.not(landing_page: [nil, \"\"])\n        .group(:landing_page)\n        .order(Arel.sql(\"COUNT(*) DESC\"))\n        .limit(20)\n        .count\n        .map do |landing_page, count|\n          uri = URI.parse(landing_page)\n          [uri.path, count]\n      end\n        .group_by { |path, _| path }\n        .transform_values { |entries| entries.sum { |_, count| count } }\n        .to_a\n        .sort_by { |_, count| -count }\n        .first(10)\n    end\n  end\n\n  def top_searches\n    @top_searches = Rails.cache.fetch(\"top_searches\", expires_at: Time.current.end_of_day) do\n      Ahoy::Event\n        .where(\"date(time) BETWEEN ? AND ?\", 60.days.ago.to_date, Time.current)\n        .where(name: \"talks#index\")\n        .where(\"json_extract(properties, '$.s') IS NOT NULL\")   # Filter out NULL values in SQL\n        .where(\"trim(json_extract(properties, '$.s')) != ''\")   # Filter out empty strings in SQL\n        .group(\"json_extract(properties, '$.s')\")               # Group by the search term\n        .order(Arel.sql(\"COUNT(*) DESC\"))                       # Order by count\n        .limit(10)\n        .pluck(Arel.sql(\"json_extract(properties, '$.s'), COUNT(*)\"))  # Get search term and count\n        .to_h\n    end\n  end\n\n  private\n\n  def admin_required\n    redirect_to analytics_dashboards_path unless Current.user&.admin?\n  end\nend\n"
  },
  {
    "path": "app/controllers/announcements_controller.rb",
    "content": "class AnnouncementsController < ApplicationController\n  include Pagy::Backend\n\n  skip_before_action :authenticate_user!\n\n  def index\n    @current_tag = params[:tag]\n    filtered_announcements = announcements\n    filtered_announcements = filtered_announcements.by_tag(@current_tag) if @current_tag.present?\n\n    @pagy, @announcements = pagy_array(filtered_announcements, limit: 10, page: page_number)\n  end\n\n  def show\n    @announcement = announcements.find_by_slug!(params[:slug])\n\n    unless @announcement.published? || can_view_draft_articles?\n      raise ActiveRecord::RecordNotFound\n    end\n\n    set_announcement_meta_tags\n  end\n\n  def feed\n    @current_tag = params[:tag]\n    @announcements = Announcement.published\n    @announcements = @announcements.by_tag(@current_tag) if @current_tag.present?\n    @announcements = @announcements.first(20)\n\n    respond_to do |format|\n      format.rss { render layout: false }\n    end\n  end\n\n  private\n\n  def announcements\n    @announcements ||= can_view_draft_articles? ? Announcement.all : Announcement.published\n  end\n\n  def page_number\n    [params[:page]&.to_i, 1].compact.max\n  end\n\n  def can_view_draft_articles?\n    Current.user&.admin? || Rails.env.development? || params[:preview] == \"true\"\n  end\n\n  helper_method :permitted_params\n  def permitted_params\n    {preview: can_view_draft_articles? ? \"true\" : nil}.compact\n  end\n\n  def set_announcement_meta_tags\n    title = @announcement.title\n    description = @announcement.excerpt\n\n    meta = {\n      title: title,\n      description: description,\n      og: {\n        title: title,\n        description: description,\n        type: \"article\",\n        url: announcement_url(@announcement)\n      },\n      twitter: {\n        title: title,\n        description: description\n      }\n    }\n\n    if @announcement.featured_image.present?\n      image_url = if @announcement.featured_image.start_with?(\"http\")\n        @announcement.featured_image\n      else\n        view_context.image_url(@announcement.featured_image)\n      end\n\n      meta[:og][:image] = image_url\n      meta[:twitter][:image] = image_url\n      meta[:twitter][:card] = \"summary_large_image\"\n    else\n      meta[:twitter][:card] = \"summary\"\n    end\n\n    set_meta_tags(meta)\n  end\nend\n"
  },
  {
    "path": "app/controllers/api/v1/embed/base_controller.rb",
    "content": "# frozen_string_literal: true\n\nmodule Api\n  module V1\n    module Embed\n      class BaseController < ActionController::API\n        before_action :set_cors_headers\n\n        rescue_from ActiveRecord::RecordNotFound, with: :not_found\n        rescue_from StandardError, with: :internal_error\n\n        def preflight\n          head :ok\n        end\n\n        private\n\n        def set_cors_headers\n          headers[\"Access-Control-Allow-Origin\"] = \"*\"\n          headers[\"Access-Control-Allow-Methods\"] = \"GET, HEAD, OPTIONS\"\n          headers[\"Access-Control-Allow-Headers\"] = \"Content-Type, Accept, Origin, X-Requested-With\"\n          headers[\"Access-Control-Max-Age\"] = \"86400\"\n        end\n\n        def not_found\n          render json: {error: \"Not found\"}, status: :not_found\n        end\n\n        def internal_error(exception)\n          Rails.logger.error(\"Embed API Error: #{exception.message}\")\n          Rails.logger.error(exception.backtrace.first(10).join(\"\\n\"))\n          render json: {error: \"Internal server error\"}, status: :internal_server_error\n        end\n\n        def build_url(path)\n          \"#{request.base_url}#{path}\"\n        end\n\n        def avatar_url(user)\n          return nil unless user\n\n          if user.respond_to?(:avatar_url)\n            user.avatar_url(size: 200)\n          elsif user.github_handle.present?\n            \"https://avatars.githubusercontent.com/#{user.github_handle}?s=200\"\n          end\n        end\n\n        def full_url(path)\n          return path if path.blank? || path.start_with?(\"http\")\n\n          \"#{request.base_url}#{path}\"\n        end\n\n        def event_avatar_url(event)\n          return nil unless event&.avatar_image_path\n\n          Router.image_path(event.avatar_image_path, host: request.base_url)\n        rescue\n          nil\n        end\n\n        def event_banner_url(event)\n          return nil unless event&.banner_image_path\n\n          Router.image_path(event.banner_image_path, host: request.base_url)\n        rescue\n          nil\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/api/v1/embed/events_controller.rb",
    "content": "# frozen_string_literal: true\n\nmodule Api\n  module V1\n    module Embed\n      class EventsController < BaseController\n        def index\n          events = Event.includes(:series)\n\n          events = case params[:filter]\n          when \"upcoming\"\n            events.upcoming.order(start_date: :asc)\n          when \"past\"\n            events.past.order(start_date: :desc)\n          else\n            events.order(start_date: :desc)\n          end\n\n          events = events.limit(params[:limit]&.to_i || 20)\n\n          if params[:slugs_only] == \"true\"\n            render json: {slugs: events.pluck(:slug)}\n          else\n            render json: {\n              events: events.map { |event| event_summary_json(event) }\n            }\n          end\n        end\n\n        def show\n          event = Event.find_by!(slug: params[:slug])\n\n          keynote_speakers = event.keynote_speaker_participants.limit(20).to_a\n          speakers = (event.speaker_participants.limit(30).to_a - keynote_speakers).first(20)\n          attendees = event.visitor_participants.limit(20).to_a\n\n          render json: {\n            name: event.name,\n            slug: event.slug,\n            description: event.description,\n            location: event.location,\n            city: event.city,\n            country_code: event.country_code,\n            start_date: event.start_date&.iso8601,\n            end_date: event.end_date&.iso8601,\n            kind: event.kind,\n            website: event.website,\n            url: Router.event_url(event, host: request.base_url),\n            avatar_url: event_avatar_url(event),\n            banner_url: event_banner_url(event),\n            featured_background: event.static_metadata&.featured_background,\n            featured_color: event.static_metadata&.featured_color,\n            talks_count: event.talks_count,\n            speakers_count: event.speakers.count,\n            series: event.series ? {\n              name: event.series.name,\n              slug: event.series.slug\n            } : nil,\n            participants: {\n              keynote_speakers: keynote_speakers.map { |user| participant_json(user) },\n              speakers: speakers.map { |user| participant_json(user) },\n              attendees: attendees.map { |user| participant_json(user) }\n            },\n            counts: {\n              keynote_speakers: event.keynote_speaker_participants.count,\n              speakers: event.speaker_participants.count,\n              attendees: event.visitor_participants.count,\n              total: event.participants.count\n            }\n          }\n        end\n\n        def participants\n          event = Event.find_by!(slug: params[:slug])\n\n          keynote_speakers = event.keynote_speaker_participants.to_a\n          speakers = event.speaker_participants.to_a - keynote_speakers\n          attendees = event.visitor_participants.to_a\n\n          render json: {\n            event: {\n              name: event.name,\n              slug: event.slug,\n              url: build_url(\"/events/#{event.slug}\")\n            },\n            participants: {\n              keynote_speakers: keynote_speakers.map { |user| participant_json(user) },\n              speakers: speakers.map { |user| participant_json(user) },\n              attendees: attendees.map { |user| participant_json(user) }\n            },\n            counts: {\n              keynote_speakers: keynote_speakers.size,\n              speakers: speakers.size,\n              attendees: attendees.size,\n              total: keynote_speakers.size + speakers.size + attendees.size\n            }\n          }\n        end\n\n        private\n\n        def participant_json(user)\n          {\n            name: user.name,\n            slug: user.slug,\n            avatar_url: avatar_url(user)\n          }\n        end\n\n        def event_summary_json(event)\n          {\n            name: event.name,\n            slug: event.slug,\n            location: event.location,\n            start_date: event.start_date&.iso8601,\n            end_date: event.end_date&.iso8601,\n            url: Router.event_url(event, host: request.base_url),\n            avatar_url: event_avatar_url(event),\n            banner_url: event_banner_url(event),\n            featured_background: event.static_metadata&.featured_background,\n            featured_color: event.static_metadata&.featured_color\n          }\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/api/v1/embed/profiles_controller.rb",
    "content": "# frozen_string_literal: true\n\nmodule Api\n  module V1\n    module Embed\n      class ProfilesController < BaseController\n        def index\n          slugs = User.joins(:event_participations)\n            .distinct\n            .order(updated_at: :desc)\n            .limit(params[:limit]&.to_i || 20)\n            .pluck(:slug)\n\n          render json: {slugs: slugs}\n        end\n\n        def show\n          user = User.find_by_slug_or_alias(params[:slug])\n          user ||= User.find_by_github_handle(params[:slug])\n          raise ActiveRecord::RecordNotFound, \"User not found\" unless user\n\n          upcoming_events_scope = user.event_participations\n            .includes(:event)\n            .joins(:event)\n            .where(\"events.start_date >= ?\", Date.current)\n            .order(\"events.start_date ASC\")\n\n          upcoming_events = upcoming_events_scope.limit(10)\n\n          render json: {\n            name: user.name,\n            slug: user.slug,\n            bio: user.bio,\n            avatar_url: avatar_url(user),\n            url: Router.profile_url(user, host: request.base_url),\n            location: user.location,\n            twitter: user.twitter,\n            github: user.github_handle,\n            website: user.website,\n            upcoming_events_count: upcoming_events_scope.count,\n            upcoming_events: upcoming_events.map { |participation|\n              event = participation.event\n              {\n                name: event.name,\n                slug: event.slug,\n                date: event.start_date&.iso8601,\n                end_date: event.end_date&.iso8601,\n                location: event.location,\n                attended_as: participation.attended_as,\n                avatar_url: event_avatar_url(event),\n                featured_background: event.static_metadata&.featured_background\n              }\n            }\n          }\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/api/v1/embed/speakers_controller.rb",
    "content": "# frozen_string_literal: true\n\nmodule Api\n  module V1\n    module Embed\n      class SpeakersController < BaseController\n        def index\n          slugs = User.with_talks\n            .order(talks_count: :desc)\n            .limit(params[:limit]&.to_i || 20)\n            .pluck(:slug)\n\n          render json: {slugs: slugs}\n        end\n\n        def show\n          speaker = User.includes(:talks).find_by_slug_or_alias(params[:slug])\n          speaker = User.includes(:talks).find_by_github_handle(params[:slug]) unless speaker.present?\n\n          unless speaker.present?\n            return render json: {error: \"Not found\"}, status: :not_found\n          end\n\n          render json: {\n            name: speaker.name,\n            slug: speaker.slug,\n            bio: speaker.bio,\n            avatar_url: avatar_url(speaker),\n            url: Router.speaker_url(speaker, host: request.base_url),\n            twitter: speaker.twitter,\n            github: speaker.github_handle,\n            website: speaker.website,\n            talks_count: speaker.talks_count,\n            events_count: speaker.events.distinct.count,\n            talks: speaker.talks.includes(:event).order(date: :desc).limit(10).map { |talk|\n              {\n                title: talk.title,\n                slug: talk.slug,\n                thumbnail_url: full_url(talk.thumbnail_sm),\n                event_name: talk.event&.name,\n                date: talk.date&.iso8601\n              }\n            },\n            events: speaker.events.distinct.order(start_date: :desc).limit(10).map { |event|\n              {\n                name: event.name,\n                slug: event.slug,\n                date: event.start_date&.iso8601,\n                location: event.location,\n                avatar_url: event_avatar_url(event),\n                featured_background: event.static_metadata&.featured_background\n              }\n            }\n          }\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/api/v1/embed/stamps_controller.rb",
    "content": "# frozen_string_literal: true\n\nmodule Api\n  module V1\n    module Embed\n      class StampsController < BaseController\n        def show\n          user = User.find_by_slug_or_alias(params[:slug])\n          user ||= User.find_by_github_handle(params[:slug])\n          raise ActiveRecord::RecordNotFound, \"User not found\" unless user\n\n          stamps = Stamp.for_user(user)\n\n          render json: {\n            user: {\n              name: user.name,\n              slug: user.slug,\n              url: build_url(\"/profiles/#{user.slug}\")\n            },\n            stamps: stamps.map { |stamp| stamp_json(stamp) },\n            count: stamps.size,\n            grouped: grouped_stamps(stamps)\n          }\n        end\n\n        private\n\n        def stamp_json(stamp)\n          {\n            code: stamp.code,\n            name: stamp.name,\n            image_url: stamp_image_url(stamp),\n            has_country: stamp.has_country?,\n            has_event: stamp.has_event?,\n            country: if stamp.has_country? && stamp.country\n                       {\n                         name: stamp.country.respond_to?(:name) ? stamp.country.name : stamp.country.to_s,\n                         code: stamp.code\n                       }\n                     end,\n            event: (stamp.has_event? && stamp.event) ? {\n              name: stamp.event.name,\n              slug: stamp.event.slug\n            } : nil\n          }\n        end\n\n        def grouped_stamps(stamps)\n          country_stamps = stamps.select(&:has_country?)\n          event_stamps = stamps.select(&:has_event?)\n          achievement_stamps = stamps.reject { |s| s.has_country? || s.has_event? }\n\n          {\n            countries: country_stamps.map { |s| stamp_json(s) },\n            events: event_stamps.map { |s| stamp_json(s) },\n            achievements: achievement_stamps.map { |s| stamp_json(s) }\n          }\n        end\n\n        def stamp_image_url(stamp)\n          return nil unless stamp.file_path.present?\n\n          if stamp.file_path.include?(\"/\")\n            Router.image_path(stamp.file_path, host: request.base_url)\n          else\n            Router.image_path(\"stamps/#{stamp.file_path}\", host: request.base_url)\n          end\n        rescue\n          nil\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/api/v1/embed/stickers_controller.rb",
    "content": "# frozen_string_literal: true\n\nmodule Api\n  module V1\n    module Embed\n      class StickersController < BaseController\n        def show\n          user = User.find_by_slug_or_alias(params[:slug])\n          user ||= User.find_by_github_handle(params[:slug])\n          raise ActiveRecord::RecordNotFound, \"User not found\" unless user\n\n          events = user.participated_events.includes(:series).select(&:sticker?)\n\n          stickers = events.flat_map { |event|\n            Sticker.for_event(event).map { |sticker|\n              {\n                code: sticker.code,\n                name: sticker.name,\n                image_url: sticker_image_url(sticker),\n                event: event ? {\n                  name: event.name,\n                  slug: event.slug\n                } : nil\n              }\n            }\n          }.uniq { |s| s[:code] }\n\n          render json: {\n            user: {\n              name: user.name,\n              slug: user.slug,\n              url: build_url(\"/profiles/#{user.slug}\")\n            },\n            stickers: stickers,\n            count: stickers.size\n          }\n        end\n\n        private\n\n        def sticker_image_url(sticker)\n          return nil unless sticker.file_path.present?\n\n          Router.image_path(sticker.file_path, host: request.base_url)\n        rescue\n          nil\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/api/v1/embed/talks_controller.rb",
    "content": "# frozen_string_literal: true\n\nmodule Api\n  module V1\n    module Embed\n      class TalksController < BaseController\n        def index\n          slugs = Talk.watchable\n            .order(date: :desc)\n            .limit(params[:limit]&.to_i || 20)\n            .pluck(:slug)\n\n          render json: {slugs: slugs}\n        end\n\n        def show\n          talk = Talk.includes(:event, :users).find_by!(slug: params[:slug])\n\n          render json: {\n            slug: talk.slug,\n            title: talk.title,\n            description: talk.description,\n            thumbnail_url: full_url(talk.thumbnail_md),\n            duration_in_seconds: talk.duration_in_seconds,\n            video_provider: talk.video_provider,\n            date: talk.date&.iso8601,\n            url: build_url(\"/talks/#{talk.slug}\"),\n            speakers: talk.users.map { |speaker|\n              {\n                name: speaker.name,\n                slug: speaker.slug,\n                avatar_url: avatar_url(speaker)\n              }\n            },\n            event: talk.event ? {\n              name: talk.event.name,\n              slug: talk.event.slug,\n              location: talk.event.location\n            } : nil\n          }\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/api/v1/embed/topics_controller.rb",
    "content": "# frozen_string_literal: true\n\nmodule Api\n  module V1\n    module Embed\n      class TopicsController < BaseController\n        def show\n          topic = Topic.approved.find_by!(slug: params[:slug])\n\n          talks = topic.talks\n            .includes(:event, :users)\n            .order(date: :desc)\n            .limit(params[:limit]&.to_i || 10)\n\n          render json: {\n            name: topic.name,\n            slug: topic.slug,\n            description: topic.description,\n            url: build_url(\"/topics/#{topic.slug}\"),\n            talks_count: topic.talks_count || 0,\n            talks: talks.map { |talk|\n              {\n                title: talk.title,\n                slug: talk.slug,\n                thumbnail_url: full_url(talk.thumbnail_md),\n                duration_in_seconds: talk.duration_in_seconds,\n                date: talk.date&.iso8601,\n                url: build_url(\"/talks/#{talk.slug}\"),\n                speakers: talk.users.map { |speaker|\n                  {\n                    name: speaker.name,\n                    slug: speaker.slug,\n                    avatar_url: avatar_url(speaker)\n                  }\n                },\n                event: talk.event ? {\n                  name: talk.event.name,\n                  slug: talk.event.slug\n                } : nil\n              }\n            }\n          }\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/application_controller.rb",
    "content": "class ApplicationController < ActionController::Base\n  include Authenticable\n  include Metadata\n  include Analytics\n\n  prepend_before_action :redirect_to_ruby_events\n\n  helper_method :default_watch_list\n\n  def default_watch_list\n    @default_watch_list ||= Current.user&.default_watch_list\n  end\n\n  private\n\n  def redirect_to_ruby_events\n    return if Rails.env.local?\n    return if hotwire_native_app?\n    return if request.url.match?(/rubyevents\\.org/)\n\n    path = request.path\n    query_string = request.query_parameters.present? ? \"?#{request.query_parameters.to_query}\" : \"\"\n    ruby_events_url = Rails.env.production? ? \"https://www.rubyevents.org#{path}#{query_string}\" : \"https://staging.rubyevents.org#{path}#{query_string}\"\n    redirect_to ruby_events_url, status: :moved_permanently, allow_other_host: true\n  end\n\n  def sign_in(user)\n    user.sessions.create!.tap do |session|\n      cookies.signed.permanent[:session_token] = {value: session.id, httponly: true}\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/avo/aliases_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::AliasesController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/cities_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::CitiesController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/connected_accounts_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::ConnectedAccountsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/contributors_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::ContributorsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/event_involvements_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::EventInvolvementsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/event_participations_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::EventParticipationsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/event_series_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/2.0/controllers.html\nclass Avo::EventSeriesController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/events_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/2.0/controllers.html\nclass Avo::EventsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/favorite_users_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::FavoriteUsersController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/geocode_results_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::GeocodeResultsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/organizations_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::OrganizationsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/sessions_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/2.0/controllers.html\nclass Avo::SessionsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/speaker_talks_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/2.0/controllers.html\nclass Avo::SpeakerTalksController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/speakers_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/2.0/controllers.html\nclass Avo::SpeakersController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/sponsors_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::SponsorsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/suggestions_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::SuggestionsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/talk_topics_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::TalkTopicsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/talk_transcripts_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::TalkTranscriptsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/talks_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/2.0/controllers.html\nclass Avo::TalksController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/topic_gems_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::TopicGemsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/topics_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::TopicsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/user_talks_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/3.0/controllers.html\nclass Avo::UserTalksController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/users_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/2.0/controllers.html\nclass Avo::UsersController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/watch_list_talks_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/2.0/controllers.html\nclass Avo::WatchListTalksController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/avo/watch_lists_controller.rb",
    "content": "# This controller has been generated to enable Rails' resource routes.\n# More information on https://docs.avohq.io/2.0/controllers.html\nclass Avo::WatchListsController < Avo::ResourcesController\nend\n"
  },
  {
    "path": "app/controllers/browse_controller.rb",
    "content": "class BrowseController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  CACHE_VERSION = \"v1\"\n  CACHE_EXPIRY = 15.minutes\n\n  SECTIONS = %w[\n    featured_events continue_watching event_rows newest_talks recently_published\n    trending for_you from_bookmarks favorite_rubyists events_attended\n    unwatched_attended favorite_speakers popular popular_youtube most_bookmarked\n    quick_watches deep_dives hidden_gems evergreen beginner_friendly mind_blowing\n    inspiring most_liked recommended_community popular_topics talk_kinds topic_rows\n    language_rows\n  ].freeze\n\n  def index\n    load_featured_events\n    load_continue_watching\n    load_event_rows\n  end\n\n  def show\n    section_name = params[:id]\n    return head :not_found unless SECTIONS.include?(section_name)\n\n    send(\"load_#{section_name}\")\n    render partial: \"browse/sections/#{section_name}\", locals: instance_variables_for_section(section_name)\n  end\n\n  private\n\n  def instance_variables_for_section(section_name)\n    case section_name\n    when \"featured_events\" then {events: @featured_events}\n    when \"continue_watching\" then {continue_watching: @continue_watching}\n    when \"event_rows\" then {event_rows: @event_rows}\n    when \"newest_talks\" then {talks: @newest_talks}\n    when \"recently_published\" then {talks: @recently_published}\n    when \"trending\" then {talks: @trending_talks}\n    when \"for_you\" then {talks: @recommended_talks}\n    when \"from_bookmarks\" then {talks: @from_your_bookmarks}\n    when \"favorite_rubyists\" then {talks: @favorite_rubyists_talks}\n    when \"events_attended\" then {talks: @from_events_attended}\n    when \"unwatched_attended\" then {talks: @unwatched_from_attended}\n    when \"favorite_speakers\" then {talks: @from_favorite_speakers}\n    when \"popular\" then {talks: @popular_talks}\n    when \"popular_youtube\" then {talks: @popular_on_youtube}\n    when \"most_bookmarked\" then {talks: @most_bookmarked}\n    when \"quick_watches\" then {talks: @quick_watches}\n    when \"deep_dives\" then {talks: @deep_dives}\n    when \"hidden_gems\" then {talks: @hidden_gems}\n    when \"evergreen\" then {talks: @evergreen_talks}\n    when \"beginner_friendly\" then {talks: @beginner_friendly}\n    when \"mind_blowing\" then {talks: @mind_blowing}\n    when \"inspiring\" then {talks: @inspiring_talks}\n    when \"most_liked\" then {talks: @most_liked}\n    when \"recommended_community\" then {talks: @recommended_by_community}\n    when \"popular_topics\" then {topics: @popular_topics}\n    when \"talk_kinds\" then {talk_kinds: @talk_kinds}\n    when \"topic_rows\" then {topic_rows: @topic_rows}\n    when \"language_rows\" then {language_rows: @language_rows}\n    else {}\n    end\n  end\n\n  def cache_key(name)\n    \"browse/#{name}/#{CACHE_VERSION}\"\n  end\n\n  def load_featured_events\n    ids = Rails.cache.fetch(cache_key(\"featured_events\"), expires_in: CACHE_EXPIRY) do\n      featured_events_query.pluck(:id)\n    end\n\n    @featured_events = Event.includes(:series, :keynote_speakers, :speakers).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_event_rows\n    sections = Rails.cache.fetch(cache_key(\"event_rows\"), expires_in: CACHE_EXPIRY) do\n      build_event_sections\n    end\n\n    event_ids = sections.map { |section| section[:event_id] }.compact.uniq\n    events_by_id = Event.includes(:series).where(id: event_ids).index_by(&:id)\n\n    @event_rows = sections.map do |section|\n      {\n        event: events_by_id[section[:event_id]],\n        talks: Talk.includes(:speakers, event: :series)\n          .where(id: section[:talk_ids])\n          .in_order_of(:id, section[:talk_ids])\n      }\n    end.select { |row| row[:event].present? }\n  end\n\n  def load_continue_watching\n    return unless Current.user\n\n    @continue_watching = Current.user.watched_talks\n      .in_progress\n      .includes(talk: [:speakers, event: :series])\n      .order(updated_at: :desc)\n      .limit(12)\n  end\n\n  def load_newest_talks\n    ids = Rails.cache.fetch(cache_key(\"newest_talks\"), expires_in: CACHE_EXPIRY) do\n      newest_talks_query.pluck(:id)\n    end\n\n    @newest_talks = Talk.includes(:speakers, event: :series)\n      .where(id: ids)\n      .in_order_of(:id, ids)\n  end\n\n  def load_recently_published\n    ids = Rails.cache.fetch(cache_key(\"recently_published\"), expires_in: CACHE_EXPIRY) do\n      recently_published_query.pluck(:id)\n    end\n\n    @recently_published = Talk.includes(:speakers, event: :series)\n      .where(id: ids)\n      .in_order_of(:id, ids)\n  end\n\n  def load_trending\n    ids = Rails.cache.fetch(cache_key(\"trending\"), expires_in: CACHE_EXPIRY) do\n      trending_talks_query.pluck(:id)\n    end\n\n    @trending_talks = Talk.includes(:speakers, event: :series)\n      .where(id: ids)\n      .in_order_of(:id, ids)\n  end\n\n  def load_for_you\n    return unless Current.user\n\n    @recommended_talks = Current.user.talk_recommender.talks(limit: 12)\n  end\n\n  def load_from_bookmarks\n    return unless Current.user\n\n    @from_your_bookmarks = Current.user.default_watch_list.talks\n      .watchable\n      .includes(:speakers, event: :series)\n      .order(Arel.sql(\"RANDOM()\"))\n      .limit(15)\n  end\n\n  def load_favorite_rubyists\n    return unless Current.user\n\n    favorite_user_ids = FavoriteUser.where(user: Current.user).pluck(:favorite_user_id)\n    return unless favorite_user_ids.any?\n\n    @favorite_rubyists_talks = Talk.watchable\n      .joins(:user_talks)\n      .where(user_talks: {user_id: favorite_user_ids})\n      .includes(:speakers, event: :series)\n      .order(date: :desc)\n      .limit(15)\n  end\n\n  def load_events_attended\n    return unless Current.user\n\n    attended_event_ids = Current.user.participated_events.pluck(:id)\n    return unless attended_event_ids.any?\n\n    @from_events_attended = Talk.watchable\n      .where(event_id: attended_event_ids)\n      .includes(:speakers, event: :series)\n      .order(date: :desc)\n      .limit(15)\n  end\n\n  def load_unwatched_attended\n    return unless Current.user\n\n    attended_event_ids = Current.user.participated_events.pluck(:id)\n    return unless attended_event_ids.any?\n\n    watched_talk_ids = Current.user.watched_talks.pluck(:talk_id)\n\n    @unwatched_from_attended = Talk.watchable\n      .where(event_id: attended_event_ids)\n      .where.not(id: watched_talk_ids)\n      .includes(:speakers, event: :series)\n      .order(Arel.sql(\"RANDOM()\"))\n      .limit(15)\n  end\n\n  def load_favorite_speakers\n    return unless Current.user\n\n    watched_talk_ids = Current.user.watched_talks.pluck(:talk_id)\n    return unless watched_talk_ids.any?\n\n    top_speaker_ids = UserTalk\n      .where(talk_id: watched_talk_ids)\n      .group(:user_id)\n      .order(Arel.sql(\"COUNT(*) DESC\"))\n      .limit(10)\n      .pluck(:user_id)\n    return unless top_speaker_ids.any?\n\n    @from_favorite_speakers = Talk.watchable\n      .joins(:user_talks)\n      .where(user_talks: {user_id: top_speaker_ids})\n      .where.not(id: watched_talk_ids)\n      .includes(:speakers, event: :series)\n      .order(Arel.sql(\"RANDOM()\"))\n      .limit(15)\n  end\n\n  def load_popular\n    ids = Rails.cache.fetch(cache_key(\"popular\"), expires_in: CACHE_EXPIRY) do\n      popular_talks_query.pluck(:id)\n    end\n\n    @popular_talks = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_popular_youtube\n    ids = Rails.cache.fetch(cache_key(\"popular_youtube\"), expires_in: CACHE_EXPIRY) do\n      popular_on_youtube_query.pluck(:id)\n    end\n\n    @popular_on_youtube = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_most_bookmarked\n    ids = Rails.cache.fetch(cache_key(\"most_bookmarked\"), expires_in: CACHE_EXPIRY) do\n      most_bookmarked_query.pluck(:id)\n    end\n\n    @most_bookmarked = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_quick_watches\n    ids = Rails.cache.fetch(cache_key(\"quick_watches\"), expires_in: CACHE_EXPIRY) do\n      quick_watches_query.pluck(:id)\n    end\n\n    @quick_watches = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_deep_dives\n    ids = Rails.cache.fetch(cache_key(\"deep_dives\"), expires_in: CACHE_EXPIRY) do\n      deep_dives_query.pluck(:id)\n    end\n\n    @deep_dives = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_hidden_gems\n    ids = Rails.cache.fetch(cache_key(\"hidden_gems\"), expires_in: CACHE_EXPIRY) do\n      hidden_gems_query.pluck(:id)\n    end\n\n    @hidden_gems = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_evergreen\n    ids = Rails.cache.fetch(cache_key(\"evergreen\"), expires_in: CACHE_EXPIRY) do\n      evergreen_talks_query.pluck(:id)\n    end\n\n    @evergreen_talks = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_beginner_friendly\n    ids = Rails.cache.fetch(cache_key(\"beginner_friendly\"), expires_in: CACHE_EXPIRY) do\n      beginner_friendly_query.pluck(:id)\n    end\n\n    @beginner_friendly = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_mind_blowing\n    ids = Rails.cache.fetch(cache_key(\"mind_blowing\"), expires_in: CACHE_EXPIRY) do\n      mind_blowing_query.pluck(:id)\n    end\n\n    @mind_blowing = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_inspiring\n    ids = Rails.cache.fetch(cache_key(\"inspiring\"), expires_in: CACHE_EXPIRY) do\n      inspiring_talks_query.pluck(:id)\n    end\n\n    @inspiring_talks = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_most_liked\n    ids = Rails.cache.fetch(cache_key(\"most_liked\"), expires_in: CACHE_EXPIRY) do\n      most_liked_query.pluck(:id)\n    end\n\n    @most_liked = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_recommended_community\n    ids = Rails.cache.fetch(cache_key(\"recommended_community\"), expires_in: CACHE_EXPIRY) do\n      recommended_by_community_query.pluck(:id)\n    end\n\n    @recommended_by_community = Talk.includes(:speakers, event: :series).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_popular_topics\n    ids = Rails.cache.fetch(cache_key(\"popular_topics\"), expires_in: CACHE_EXPIRY) do\n      popular_topics_query.pluck(:id)\n    end\n\n    @popular_topics = Topic.includes(:topic_gems).where(id: ids).in_order_of(:id, ids)\n  end\n\n  def load_talk_kinds\n    @talk_kinds = Rails.cache.fetch(cache_key(\"talk_kinds\"), expires_in: CACHE_EXPIRY) do\n      talk_kinds_query\n    end\n  end\n\n  def load_topic_rows\n    sections = Rails.cache.fetch(cache_key(\"topic_rows\"), expires_in: CACHE_EXPIRY) do\n      build_topic_sections\n    end\n\n    topic_ids = sections.map { |section| section[:topic_id] }.compact.uniq\n    topics_by_id = Topic.where(id: topic_ids).index_by(&:id)\n\n    @topic_rows = sections.map do |section|\n      {\n        topic: topics_by_id[section[:topic_id]],\n        talks: Talk.includes(:speakers, event: :series)\n          .where(id: section[:talk_ids])\n          .in_order_of(:id, section[:talk_ids])\n      }\n    end.select { |row| row[:topic].present? }\n  end\n\n  def load_language_rows\n    return @language_rows = [] unless Current.user\n\n    watched_talk_ids = Current.user.watched_talks.pluck(:talk_id)\n    return @language_rows = [] unless watched_talk_ids.any?\n\n    watched_languages = Talk.where(id: watched_talk_ids)\n      .where.not(language: [\"en\", nil])\n      .distinct\n      .pluck(:language)\n\n    return @language_rows = [] unless watched_languages.any?\n\n    @language_rows = watched_languages.map do |lang_code|\n      language_name = Language.by_code(lang_code)\n      talks = Talk.watchable\n        .where(language: lang_code)\n        .where.not(id: watched_talk_ids)\n        .includes(:speakers, event: :series)\n        .order(date: :desc)\n        .limit(15)\n\n      next if talks.empty?\n\n      {\n        language_code: lang_code,\n        language_name: language_name || lang_code.upcase,\n        talks: talks\n      }\n    end.compact\n  end\n\n  def featured_events_query\n    imported_slugs = Event.not_meetup.with_watchable_talks.pluck(:slug)\n    featurable_slugs = Static::Event.where.not(featured_background: nil).pluck(:slug)\n    slug_candidates = imported_slugs & featurable_slugs\n\n    featured_slugs = Static::Event.all\n      .select { |event| slug_candidates.include?(event.slug) }\n      .select(&:home_sort_date)\n      .sort_by(&:home_sort_date)\n      .reverse\n      .take(5)\n      .map(&:slug)\n\n    Event.where(slug: featured_slugs).in_order_of(:slug, featured_slugs)\n  end\n\n  def recently_published_query\n    Talk.watchable\n      .where.not(published_at: nil)\n      .order(published_at: :desc)\n      .limit(15)\n  end\n\n  def newest_talks_query\n    Talk.watchable\n      .where(\"date <= ?\", Date.current)\n      .order(date: :desc)\n      .limit(15)\n  end\n\n  def trending_talks_query\n    Talk.watchable\n      .joins(:watched_talks)\n      .where(watched_talks: {watched_at: 30.days.ago..})\n      .group(:id)\n      .order(Arel.sql(\"COUNT(watched_talks.id) DESC\"))\n      .limit(15)\n  end\n\n  def popular_talks_query\n    Talk.watchable\n      .joins(:watched_talks)\n      .group(:id)\n      .order(Arel.sql(\"COUNT(watched_talks.id) DESC\"))\n      .limit(15)\n  end\n\n  def popular_on_youtube_query\n    Talk.watchable\n      .where(\"view_count > 0\")\n      .order(view_count: :desc)\n      .limit(15)\n  end\n\n  def most_bookmarked_query\n    Talk.watchable\n      .joins(:watch_list_talks)\n      .group(:id)\n      .order(Arel.sql(\"COUNT(watch_list_talks.id) DESC\"))\n      .limit(15)\n  end\n\n  def quick_watches_query\n    Talk.watchable\n      .where(\"duration_in_seconds > 0 AND duration_in_seconds <= ?\", 15 * 60)\n      .order(Arel.sql(\"RANDOM()\"))\n      .limit(15)\n  end\n\n  def deep_dives_query\n    Talk.watchable\n      .where(\"duration_in_seconds >= ?\", 45 * 60)\n      .order(Arel.sql(\"RANDOM()\"))\n      .limit(15)\n  end\n\n  def hidden_gems_query\n    Talk.watchable\n      .joins(:watched_talks)\n      .where(\"view_count < 5000 OR view_count IS NULL\")\n      .group(:id)\n      .having(\"COUNT(watched_talks.id) >= 3\")\n      .order(Arel.sql(\"COUNT(watched_talks.id) DESC\"))\n      .limit(15)\n  end\n\n  def evergreen_talks_query\n    Talk.watchable\n      .joins(:watched_talks)\n      .where(\"json_extract(watched_talks.feedback, '$.content_freshness') = ?\", \"evergreen\")\n      .group(:id)\n      .having(\"COUNT(watched_talks.id) >= 2\")\n      .order(Arel.sql(\"COUNT(watched_talks.id) DESC\"))\n      .limit(15)\n  end\n\n  def beginner_friendly_query\n    Talk.watchable\n      .joins(:watched_talks)\n      .where(\"json_extract(watched_talks.feedback, '$.experience_level') = ?\", \"beginner\")\n      .group(:id)\n      .having(\"COUNT(watched_talks.id) >= 2\")\n      .order(Arel.sql(\"COUNT(watched_talks.id) DESC\"))\n      .limit(15)\n  end\n\n  def mind_blowing_query\n    Talk.watchable\n      .joins(:watched_talks)\n      .where(\"json_extract(watched_talks.feedback, '$.feeling') = ?\", \"mind_blown\")\n      .group(:id)\n      .having(\"COUNT(watched_talks.id) >= 2\")\n      .order(Arel.sql(\"COUNT(watched_talks.id) DESC\"))\n      .limit(15)\n  end\n\n  def inspiring_talks_query\n    Talk.watchable\n      .joins(:watched_talks)\n      .where(\"json_extract(watched_talks.feedback, '$.feeling') IN (?, ?)\", \"inspired\", \"exciting\")\n      .or(Talk.watchable.joins(:watched_talks).where(\"json_extract(watched_talks.feedback, '$.inspiring') = ?\", true))\n      .group(:id)\n      .having(\"COUNT(watched_talks.id) >= 2\")\n      .order(Arel.sql(\"COUNT(watched_talks.id) DESC\"))\n      .limit(15)\n  end\n\n  def most_liked_query\n    Talk.watchable\n      .joins(:watched_talks)\n      .where(\"json_extract(watched_talks.feedback, '$.liked') = ?\", true)\n      .group(:id)\n      .having(\"COUNT(watched_talks.id) >= 2\")\n      .order(Arel.sql(\"COUNT(watched_talks.id) DESC\"))\n      .limit(15)\n  end\n\n  def recommended_by_community_query\n    Talk.watchable\n      .joins(:watched_talks)\n      .where(\"json_extract(watched_talks.feedback, '$.would_recommend') = ?\", true)\n      .group(:id)\n      .having(\"COUNT(watched_talks.id) >= 2\")\n      .order(Arel.sql(\"COUNT(watched_talks.id) DESC\"))\n      .limit(15)\n  end\n\n  def popular_topics_query\n    Topic.approved\n      .joins(:talks)\n      .where(talks: {video_provider: Talk::WATCHABLE_PROVIDERS})\n      .group(\"topics.id\")\n      .order(Arel.sql(\"COUNT(talks.id) DESC\"))\n      .limit(12)\n  end\n\n  def talk_kinds_query\n    Talk.watchable\n      .group(:kind)\n      .order(Arel.sql(\"COUNT(*) DESC\"))\n      .count\n  end\n\n  def build_topic_sections\n    Topic.approved\n      .joins(:talks)\n      .where(talks: {video_provider: Talk::WATCHABLE_PROVIDERS})\n      .group(\"topics.id\")\n      .having(\"COUNT(talks.id) >= 5\")\n      .order(Arel.sql(\"COUNT(talks.id) DESC\"))\n      .limit(4)\n      .map do |topic|\n        {\n          topic_id: topic.id,\n          talk_ids: topic.talks.watchable.order(date: :desc).limit(15).pluck(:id)\n        }\n      end\n  end\n\n  def build_event_sections\n    Event.joins(:talks)\n      .where(talks: {video_provider: Talk::WATCHABLE_PROVIDERS})\n      .where(\"talks.published_at > ?\", 12.months.ago)\n      .group(\"events.id\")\n      .having(\"COUNT(talks.id) >= 3\")\n      .order(Arel.sql(\"MAX(talks.published_at) DESC\"))\n      .limit(6)\n      .map do |event|\n        {\n          event_id: event.id,\n          talk_ids: event.talks.watchable.order(date: :desc).limit(15).pluck(:id)\n        }\n      end\n  end\nend\n"
  },
  {
    "path": "app/controllers/cfp_controller.rb",
    "content": "class CFPController < ApplicationController\n  skip_before_action :authenticate_user!, only: :index\n\n  # GET /cfp\n  def index\n    cfps = CFP.includes(:event).open.order(cfps: {close_date: :asc})\n\n    if params[:kind].present? && params[:kind] != \"all\"\n      cfps = cfps.joins(:event).where(events: {kind: params[:kind]})\n    end\n\n    @events = cfps.map(&:event).group_by(&:kind).values.flatten\n  end\nend\n"
  },
  {
    "path": "app/controllers/cities_controller.rb",
    "content": "class CitiesController < ApplicationController\n  include EventMapMarkers\n  include GeoMapLayers\n\n  skip_before_action :authenticate_user!, only: %i[index show show_by_country show_with_state]\n\n  def index\n    @cities = City.includes(:users, :events).all\n  end\n\n  def show\n    @city = City.find_by(slug: params[:slug])\n\n    if @city.blank?\n      redirect_to cities_path\n      return\n    end\n\n    load_city_data\n  end\n\n  def show_by_country\n    @country = Country.find_by(country_code: params[:alpha2].upcase)\n\n    if @country.blank?\n      redirect_to countries_path\n      return\n    end\n\n    @city_slug = params[:city]\n    @city_name = @city_slug.tr(\"-\", \" \").titleize\n\n    @city = City.find_by(slug: @city_slug)\n    @city ||= City.find_for(city: @city_name, country_code: @country.alpha2)\n\n    if @city.present?\n      redirect_to city_path(@city.slug), status: :moved_permanently\n    else\n      redirect_to country_path(@country)\n    end\n  end\n\n  def show_with_state\n    @country = Country.find_by(country_code: params[:alpha2].upcase)\n\n    if @country.blank?\n      redirect_to countries_path\n      return\n    end\n\n    @state = State.find(country: @country, term: params[:state])\n\n    if @state.blank?\n      redirect_to country_path(@country)\n      return\n    end\n\n    @city_slug = params[:city]\n    @city_name = @city_slug.tr(\"-\", \" \").titleize\n\n    @city = City.find_by(slug: @city_slug)\n    @city ||= City.find_for(city: @city_name, country_code: @country.alpha2, state_code: @state.code)\n\n    if @city.present?\n      redirect_to city_path(@city.slug), status: :moved_permanently\n    else\n      redirect_to state_path(state_alpha2: @country.code, state_slug: @state.slug)\n    end\n  end\n\n  private\n\n  def load_city_data\n    @events = @city.events.includes(:series).order(start_date: :desc)\n    @users = @city.users\n    @stamps = @city.stamps\n\n    upcoming_events = @events.upcoming.to_a\n\n    if @city.geocoded?\n      @nearby_users = @city.nearby_users(exclude_ids: @users.pluck(:id))\n      @nearby_events = @city.nearby_events(exclude_ids: @events.pluck(:id))\n    end\n\n    nearby_event_ids = (@nearby_events || []).map { |n| n[:event].id }\n    exclude_ids = @events.pluck(:id) + nearby_event_ids\n\n    @country_events = Event.includes(:series)\n      .where(country_code: @city.country_code)\n      .where.not(city: @city.name)\n      .where.not(id: exclude_ids)\n      .upcoming\n\n    @country = @city.country\n    @continent = @country&.continent\n\n    if @country_events.empty? && @continent.present?\n      @continent_events = continent_upcoming_events(exclude_country_codes: [@city.country_code])\n    end\n\n    @location = @city\n    @state = @city.state_code.present? ? State.find(country: @country, term: @city.state_code) : nil\n\n    if @state.present?\n      city_user_ids = @users.pluck(:id)\n      nearby_user_ids = (@nearby_users || []).map { |n| n.is_a?(Hash) ? n[:user].id : n.id }\n      exclude_ids = city_user_ids + nearby_user_ids\n      @state_users = @state.users.where.not(id: exclude_ids).limit(24)\n    end\n\n    all_events_for_map = upcoming_events.select(&:geocoded?)\n\n    all_events_for_map += (@nearby_events || []).select { |n| n[:event].upcoming? }.map { |n| n[:event] }.select(&:geocoded?)\n    all_events_for_map += @country_events.geocoded.to_a\n    all_events_for_map += (@continent_events || []).to_a.select(&:geocoded?)\n\n    @event_map_markers = event_map_markers(all_events_for_map)\n    @geo_layers = build_sidebar_geo_layers(upcoming_events)\n  end\n\n  def filter_events_by_time(events)\n    events.select(&:upcoming?)\n  end\n\n  def continent_upcoming_events(exclude_country_codes: [])\n    return [] unless @continent.present?\n\n    continent_country_codes = @continent.countries.map(&:alpha2) - exclude_country_codes\n\n    Event.includes(:series)\n      .where(country_code: continent_country_codes)\n      .upcoming\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/analytics.rb",
    "content": "module Analytics\n  extend ActiveSupport::Concern\n\n  included do\n    after_action :track_action, unless: :analytics_disabled?\n  end\n\n  class_methods do\n    def disable_analytics\n      @analytics_disabled = true\n    end\n  end\n\n  private\n\n  def analytics_disabled?\n    self.class.instance_variable_get(:@analytics_disabled)\n  end\n\n  def track_action\n    ahoy.track \"#{controller_path}##{action_name}\", request.params\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/authenticable.rb",
    "content": "module Authenticable\n  extend ActiveSupport::Concern\n\n  included do\n    before_action :set_current_request_details\n    before_action :authenticate_user!\n\n    helper_method :signed_in?, :signed_in, :signed_out\n  end\n\n  def signed_in?\n    Current.user.present?\n  end\n\n  def signed_in(&block)\n    yield if block && signed_in?\n  end\n\n  def signed_out(&block)\n    yield if block && !signed_in?\n  end\n\n  private\n\n  def authenticate_user!\n    redirect_to new_session_path unless Current.user\n  end\n\n  def set_current_request_details\n    Current.user_agent = request.user_agent\n    Current.ip_address = request.ip\n    Current.session = Session.find_by_id(cookies.signed[:session_token]) if cookies.signed[:session_token]\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/event_data.rb",
    "content": "module EventData\n  extend ActiveSupport::Concern\n\n  include FavoriteUsers\n\n  def set_event\n    @event = Event.includes(:event_participations).find_by(slug: params[:event_slug])\n    redirect_to root_path, status: :moved_permanently unless @event\n  end\n\n  def set_event_meta_tags\n    set_meta_tags(@event)\n  end\n\n  def set_participation\n    @participation ||= Current.user&.main_participation_to(@event)\n  end\n\n  def set_participants\n    participants = @event.participants.preloaded.order(:name).distinct\n    if Current.user\n      @participants = {\n        \"Ruby Friends\" => [],\n        \"Favorites\" => [],\n        \"Known Participants\" => []\n      }\n      participants.each do |participant|\n        fav_user = @favorite_users[participant.id]\n        if fav_user&.ruby_friend?\n          @participants[\"Ruby Friends\"] << participant\n        elsif fav_user&.persisted?\n          @participants[\"Favorites\"] << participant\n        else\n          @participants[\"Known Participants\"] << participant\n        end\n      end\n    else\n      @participants = {\"Known Participants\" => participants}\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/event_map_markers.rb",
    "content": "# frozen_string_literal: true\n\nmodule EventMapMarkers\n  extend ActiveSupport::Concern\n\n  private\n\n  def event_map_markers(events = Event.includes(:series).geocoded)\n    events\n      .select { |event| event.latitude.present? && event.longitude.present? }\n      .group_by(&:to_coordinates)\n      .map do |(latitude, longitude), grouped_events|\n        {\n          latitude: latitude,\n          longitude: longitude,\n          events: grouped_events\n            .sort_by { |e| e.start_date || Time.at(0) }\n            .reverse\n            .map { |event| event_marker_data(event) }\n        }\n      end\n  end\n\n  def event_marker_data(event)\n    {\n      name: event.name,\n      url: Router.event_path(event),\n      avatar: Router.image_path(event.avatar_image_path),\n      location: event.location,\n      upcoming: event.start_date.present? && event.start_date >= Date.today\n    }\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/favorite_users.rb",
    "content": "module FavoriteUsers\n  extend ActiveSupport::Concern\n\n  def set_favorite_users\n    @favorite_users = {}\n    return unless Current.user\n    @favorite_users = Current.user.favorite_users\n      .includes(:mutual_favorite_user)\n      .to_h { [it.favorite_user_id, it] }\n    @favorite_users.default_proc = proc { |hash, key| FavoriteUser.new(user: Current.user, favorite_user_id: key) }\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/geo_map_layers.rb",
    "content": "# frozen_string_literal: true\n\nmodule GeoMapLayers\n  extend ActiveSupport::Concern\n\n  private\n\n  def build_sidebar_geo_layers(events, include_broader_scope: true)\n    layers = []\n    city_pin = build_city_pin(@location)\n\n    layers << build_layer(\n      id: \"geo-location\",\n      label: @location.name,\n      emoji: \"📍\",\n      events: events,\n      bounds: @location.bounds,\n      city_pin: city_pin,\n      always_visible: true\n    )\n\n    return layers unless include_broader_scope\n\n    add_broader_layers(layers, events)\n    set_first_visible_layer(layers)\n\n    layers\n  end\n\n  def add_broader_layers(layers, current_events)\n    case @location\n    when City\n      add_nearby_layer(layers, current_events)\n      add_state_layer(layers)\n      add_country_layer(layers)\n      add_continent_layer(layers)\n    when State\n      add_country_layer(layers)\n      add_continent_layer(layers)\n    when Country, UKNation\n      add_continent_layer(layers)\n    end\n  end\n\n  def add_nearby_layer(layers, city_events)\n    return unless @city.respond_to?(:nearby_events) && @city.geocoded?\n\n    nearby_event_data = @city.nearby_events(radius_km: 250, limit: 50, exclude_ids: city_events.map(&:id))\n    nearby_events_list = filter_events_by_time(nearby_event_data.map { |d| d[:event] })\n\n    maybe_add_layer(layers, id: \"geo-nearby\", label: \"Nearby\", emoji: \"📍🔄\", events: city_events + nearby_events_list)\n  end\n\n  def add_state_layer(layers)\n    return unless @state.present? && @country.present? && @country&.states?\n\n    maybe_add_layer(layers, id: \"geo-state\", label: @state.name, emoji: \"🗺️\", events: @state.events.includes(:series))\n  end\n\n  def add_country_layer(layers)\n    return unless @country.present?\n\n    maybe_add_layer(layers, id: \"geo-country\", label: @country.name, emoji: @country.emoji_flag, bounds: @country.bounds, events: @country.events.includes(:series))\n  end\n\n  def add_continent_layer(layers)\n    return unless @continent.present?\n\n    maybe_add_layer(layers, id: \"geo-continent\", label: @continent.name, emoji: @continent.emoji_flag, bounds: @continent.bounds, events: @continent.events.includes(:series))\n  end\n\n  def maybe_add_layer(layers, id:, label:, emoji:, events:, bounds: nil)\n    current_marker_count = layers.last&.dig(:markers)&.size || 0\n    markers = event_map_markers(filter_events_by_time(events.to_a).select(&:geocoded?))\n\n    return unless markers.any? && markers.size > current_marker_count\n\n    layers << build_layer(id: id, label: label, emoji: emoji, markers: markers, bounds: bounds)\n  end\n\n  def build_layer(id:, label:, emoji:, events: nil, markers: nil, bounds: nil, city_pin: nil, always_visible: false)\n    {\n      id: id,\n      label: label,\n      emoji: emoji,\n      markers: markers || event_map_markers(events.to_a.select(&:geocoded?)),\n      bounds: bounds,\n      cityPin: city_pin,\n      visible: false,\n      alwaysVisible: always_visible.presence,\n      group: \"geo\"\n    }.compact\n  end\n\n  def build_city_pin(location)\n    return unless location.respond_to?(:geocoded?) && location.geocoded?\n\n    {type: \"city\", name: location.name, longitude: location.longitude, latitude: location.latitude}\n  end\n\n  def set_first_visible_layer(layers)\n    first_with_markers = layers.find { |l| l[:markers].any? }\n\n    if first_with_markers\n      first_with_markers[:visible] = true\n    elsif layers.any?\n      layers.first[:visible] = true\n    end\n  end\n\n  def filter_events_by_time(events)\n    events\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/location_events.rb",
    "content": "# frozen_string_literal: true\n\nmodule LocationEvents\n  extend ActiveSupport::Concern\n\n  private\n\n  def location_events\n    @location_events ||= @location.events.includes(:series).order(start_date: :desc)\n  end\n\n  def upcoming_events\n    @upcoming_events ||= location_events.upcoming.reorder(start_date: :asc)\n  end\n\n  def past_events\n    @past_events ||= location_events.past.reorder(end_date: :desc)\n  end\n\n  def country_upcoming_events(exclude_ids: [])\n    return [] unless @country.present?\n\n    scope = @country.events.includes(:series).upcoming\n    scope = scope.where.not(city: @location.name) if @location.is_a?(City)\n    scope = scope.where.not(id: exclude_ids) if exclude_ids.any?\n    scope\n  end\n\n  def continent_upcoming_events(exclude_country_codes: [])\n    return [] unless @continent.present?\n\n    country_codes = @continent.country_codes - exclude_country_codes\n\n    Event.includes(:series).where(country_code: country_codes).upcoming\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/metadata.rb",
    "content": "# frozen_string_literal: true\n\nmodule Metadata\n  extend ActiveSupport::Concern\n\n  SITE_NAME = \"RubyEvents.org\"\n  DEFAULT_TITLE = \"#{SITE_NAME} - On a mission to index all Ruby events\"\n  DEFAULT_DESC = \"On a mission to index all Ruby events. Your go-to place for talks and events about Ruby.\"\n  DEFAULT_KEYWORDS = %w[ruby events conferences meetups]\n\n  included do\n    before_action :set_default_meta_tags\n  end\n\n  private\n\n  def set_default_meta_tags\n    set_meta_tags({\n      title: DEFAULT_TITLE,\n      canonical: request.original_url,\n      description: DEFAULT_DESC,\n      og: {\n        title: DEFAULT_TITLE,\n        url: request.original_url,\n        description: DEFAULT_DESC,\n        site_name: SITE_NAME,\n        type: \"website\",\n        image: view_context.image_url(\"logo_og_image.png\")\n      },\n      twitter: {\n        title: DEFAULT_TITLE,\n        description: DEFAULT_DESC,\n        card: \"summary_large_image\",\n        image: view_context.image_url(\"logo_og_image.png\")\n      }\n    })\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/profile_data.rb",
    "content": "module ProfileData\n  extend ActiveSupport::Concern\n\n  included do\n    skip_before_action :authenticate_user!\n    before_action :set_user\n    before_action :set_favorite_user\n    before_action :set_user_favorites\n    before_action :set_mutual_events\n    before_action :load_common_data\n    include WatchedTalks\n\n    helper_method :user_kind\n  end\n\n  def load_common_data\n    @talks = @user.kept_talks\n    @events = @user.participated_events\n    @stamps = Stamp.for_user(@user)\n    @events_with_stickers = @events.select(&:sticker?)\n    @involvements_by_role = @user.event_involvements.group_by(&:role).transform_values(&:any?)\n    @countries_with_events = @events.group_by(&:country_code).any? ? [true] : []\n    @topics = @user.topics.approved.tally.sort_by(&:last).reverse.map(&:first)\n    @aliases = Current.user&.admin? ? @user.aliases : []\n    @back_path = speakers_path\n  end\n\n  private\n\n  def set_user\n    @user = User.includes(:talks, :passports).find_by_slug_or_alias(params[:profile_slug])\n    @user = User.includes(:talks).find_by_github_handle(params[:profile_slug]) unless @user.present?\n\n    if @user.blank?\n      redirect_to speakers_path, status: :moved_permanently, notice: \"User not found\"\n      return\n    end\n\n    if @user.canonical.present?\n      redirect_to profile_path(@user.canonical), status: :moved_permanently\n      return\n    end\n\n    if params[:profile_slug] != @user.to_param\n      redirect_to polymorphic_path([:profile, controller_name.to_sym, :index], profile_slug: @user.to_param), status: :moved_permanently\n    end\n  end\n\n  def set_favorite_user\n    @favorite_user = FavoriteUser.find_by(user: Current.user, favorite_user: @user)\n  end\n\n  def set_mutual_events\n    @mutual_events = if Current.user\n      @user.participated_events.where(id: Current.user.participated_events).distinct.order(start_date: :desc)\n    else\n      Event.none\n    end\n  end\n\n  def set_user_favorites\n    return unless Current.user\n\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\n\n  def user_kind\n    return params[:user_kind] if params[:user_kind].present? && Rails.env.development?\n    return :admin if Current.user&.admin?\n    return :owner if @user.managed_by?(Current.user)\n    return :signed_in if Current.user.present?\n\n    :anonymous\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/remote_modal.rb",
    "content": "module RemoteModal\n  extend ActiveSupport::Concern\n  include Turbo::ForceResponse\n\n  included do\n    layout :define_layout\n    helper_method :modal_options\n  end\n\n  class_methods do\n    def respond_with_remote_modal(options = {})\n      before_action :enable_remote_modal, **options\n      force_frame_response(**options)\n    end\n  end\n\n  private\n\n  def enable_remote_modal\n    @remote_modal = true\n  end\n\n  def modal_options\n    @modal_options ||= {}\n  end\n\n  def set_modal_options(options)\n    @modal_options = options\n  end\n\n  def define_layout\n    return \"modal\" if turbo_frame_request_id == \"modal\" && @remote_modal\n\n    \"application\"\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/spotlight_search.rb",
    "content": "# frozen_string_literal: true\n\nmodule SpotlightSearch\n  extend ActiveSupport::Concern\n\n  included do\n    helper_method :search_backend\n  end\n\n  private\n\n  def search_backend_class\n    @search_backend_class ||= begin\n      preferred = Rails.env.development? ? params[:search_backend] : nil\n      Search::Backend.resolve(preferred)\n    end\n  end\n\n  def search_backend\n    return nil unless search_query.present?\n    search_backend_class.name\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/turbo/force_response.rb",
    "content": "# frozen_string_literal: true\n\nmodule Turbo\n  module ForceResponse\n    extend ActiveSupport::Concern\n\n    class_methods do\n      def force_frame_response(options = {})\n        before_action :force_frame_response, **options\n      end\n\n      def force_stream_response(options = {})\n        before_action :force_stream_response, **options\n      end\n    end\n\n    def force_frame_response\n      return if turbo_frame_request?\n\n      redirect_back(fallback_location: root_path)\n    end\n\n    def force_stream_response\n      return if request.format.turbo_stream?\n\n      redirect_back(fallback_location: root_path)\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/concerns/watched_talks.rb",
    "content": "module WatchedTalks\n  extend ActiveSupport::Concern\n\n  included do\n    helper_method :user_watched_talks\n  end\n\n  private\n\n  def user_watched_talks\n    @user_watched_talks ||= Current.user&.watched_talks || WatchedTalk.none\n  end\nend\n"
  },
  {
    "path": "app/controllers/continents/base_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass Continents::BaseController < ApplicationController\n  include EventMapMarkers\n\n  skip_before_action :authenticate_user!\n\n  before_action :set_continent\n\n  private\n\n  def set_continent\n    @continent = Continent.find(params[:continent_continent])\n\n    redirect_to(continents_path) and return unless @continent.present?\n  end\n\n  def continent_events\n    @continent_events ||= @continent.events.includes(:series).order(start_date: :desc)\n  end\n\n  def upcoming_events\n    @upcoming_events ||= continent_events.upcoming.reorder(start_date: :asc)\n  end\n\n  def past_events\n    @past_events ||= continent_events.past.reorder(end_date: :desc)\n  end\nend\n"
  },
  {
    "path": "app/controllers/continents/countries_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass Continents::CountriesController < Continents::BaseController\n  def index\n    @countries = @continent.countries.sort_by(&:name)\n\n    @events_by_country = @continent.events\n      .select { |event| event.country_code.present? }\n      .group_by { |event| Country.find_by(country_code: event.country_code) }\n      .compact\n      .sort_by { |country, _| country&.name.to_s }\n      .to_h\n\n    @users_by_country = @continent.users.geocoded\n      .group(:country_code)\n      .count\n      .transform_keys { |code| Country.find_by(country_code: code) }\n      .compact\n  end\nend\n"
  },
  {
    "path": "app/controllers/continents_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass ContinentsController < ApplicationController\n  include EventMapMarkers\n  include GeoMapLayers\n\n  skip_before_action :authenticate_user!, only: %i[index show]\n\n  def index\n    @continents = Continent.all.sort_by(&:name)\n\n    @events_by_continent = Event.includes(:series)\n      .where.not(country_code: [nil, \"\"])\n      .group_by(&:country)\n      .transform_keys(&:continent)\n      .compact\n\n    @users_by_continent = User.indexable.geocoded\n      .group(:country_code)\n      .count\n      .group_by { |code, _| Country.find_by(country_code: code)&.continent }\n      .transform_values { |codes| codes.sum { |_, count| count } }\n      .compact\n\n    @event_map_markers = event_map_markers\n  end\n\n  def show\n    @continent = Continent.find(params[:continent])\n    redirect_to(continents_path) and return if @continent.blank?\n\n    @events = @continent.events.includes(:series).order(start_date: :desc)\n    @countries = @continent.countries.sort_by(&:name)\n    @users = @continent.users\n    @stamps = @continent.stamps\n    @location = @continent\n\n    upcoming_events = @events.upcoming.to_a\n    @events_by_country = upcoming_events.group_by(&:country).compact.sort_by { |country, _| country&.name.to_s }.to_h\n    @event_map_markers = event_map_markers(upcoming_events.select(&:geocoded?))\n    @geo_layers = build_sidebar_geo_layers(upcoming_events)\n  end\nend\n"
  },
  {
    "path": "app/controllers/contributions_controller.rb",
    "content": "class ContributionsController < ApplicationController\n  include Turbo::ForceResponse\n\n  force_frame_response only: %i[show]\n  skip_before_action :authenticate_user!, only: %i[index show]\n\n  STEPS = %i[speakers_without_github talks_without_slides events_without_videos\n    events_without_location events_without_dates talks_dates_out_of_bounds missing_videos_cue].freeze\n\n  def index\n    # Overdue scheduled talks\n\n    @overdue_scheduled_talks = Talk.where(video_provider: \"scheduled\").where(\"date < ?\", Date.today).order(date: :asc)\n    @overdue_scheduled_talks_count = @overdue_scheduled_talks.count\n\n    # Not published talks\n\n    @not_published_talks = Talk.where(video_provider: \"not_published\").order(date: :desc)\n    @not_published_talks_count = @not_published_talks.count\n\n    # Talks without speakers\n\n    @talks_without_speakers = User.find_by(name: \"TODO\").talks + User.find_by(name: \"TBD\").talks\n    @talks_without_speakers_count = @talks_without_speakers.count\n\n    # Missing events\n\n    event_names = Event.all.pluck(:name)\n    event_alias_names = Alias.where(aliasable_type: \"Event\").pluck(:name)\n    conference_names = (event_names + event_alias_names).to_set\n    @upstream_conferences = begin\n      RubyConferences::Client.new.conferences_cached.reverse\n    rescue\n      []\n    end\n    @pending_conferences = @upstream_conferences.reject { |conference| conference[\"name\"].in?(conference_names) }\n\n    @with_video_link, @without_video_link = @pending_conferences.partition { |conference| conference[\"video_link\"].present? }\n\n    @conferences_to_index = @with_video_link.count + @without_video_link.count\n    @already_index_conferences = @upstream_conferences.count - @conferences_to_index\n\n    # Conferences with missing schedules\n    @conferences_with_missing_schedule = Event.joins(:series).where(series: {kind: :conference}).reject { |event| event.schedule.exist? }.group_by(&:series)\n    @conferences_with_missing_schedule_count = @conferences_with_missing_schedule.flat_map(&:last).count\n  end\n\n  def show\n    @step = params[:step].to_sym.presence_in(STEPS)\n\n    if @step\n      send(@step)\n    else\n      raise StandardError, \"missing step\"\n    end\n  end\n\n  def speakers_without_github\n    speaker_ids_with_pending_github_suggestions = Suggestion.pending.where(\"json_extract(content, '$.github') IS NOT NULL\").where(suggestable_type: \"Speaker\").pluck(:suggestable_id)\n    @speakers_without_github = User.speakers.canonical.without_github.order(talks_count: :desc).where.not(id: speaker_ids_with_pending_github_suggestions)\n  end\n\n  def talks_without_slides\n    speakers_with_speakerdeck = User.speakers.where.not(speakerdeck: \"\")\n    @talks_without_slides = Talk.past.preload(:speakers).joins(:users).where(slides_url: nil).where(users: {id: speakers_with_speakerdeck}).order(date: :desc)\n  end\n\n  def events_without_videos\n    @events_without_videos = Event.past.not_retreat.includes(:series).left_joins(:talks).where(talks_count: 0).reject { |e| e.static_metadata.cancelled? }.group_by(&:series)\n\n    @events_without_location = Static::Event.where(location: nil).group_by(&:__file_path)\n\n    @events_without_dates = Static::Event.where(start_date: nil).reject(&:meetup?).group_by(&:__file_path)\n  end\n\n  def events_without_location\n    @events_without_location = Static::Event.where(location: nil).group_by(&:__file_path)\n  end\n\n  def events_without_dates\n    @events_without_dates = Static::Event.where(start_date: nil).reject(&:meetup?).group_by(&:__file_path)\n  end\n\n  def talks_dates_out_of_bounds\n    events_with_start_date = Static::Event.all.pluck(:title, :start_date, :end_date).select { |_, start_date| start_date.present? }\n    events_without_start_date = Static::Event.all.pluck(:title, :year, :start_date).select { |_, _, start_date, _| start_date.blank? }\n\n    ranges_for_events_with_dates = events_with_start_date.map { |name, start_date, end_date| [name, Date.parse(start_date)..Date.parse(end_date)] }\n    ranges_for_events_without_dates = events_without_start_date.map { |title, year, _| [title, Date.parse(\"#{year}-01-01\").all_year] }\n\n    @dates_by_event_name = ranges_for_events_with_dates.union(ranges_for_events_without_dates).to_h\n\n    talks_by_event_name = Talk.preload(:event).to_a.select { |talk| talk.event.name.in?(@dates_by_event_name.keys) }.group_by(&:event)\n\n    @out_of_bound_talks = talks_by_event_name.map { |event, talks| [event, talks.reject { |talk| @dates_by_event_name[event.name].cover?(talk.date) }] }\n  end\n\n  def missing_videos_cue\n    videos_with_missing_cues = Static::Video.all.select { |video| video.talks.any? { |t| t.start_cue == \"TODO\" || t.end_cue == \"TODO\" } }\n    videos_with_missing_cues_ids = videos_with_missing_cues.map(&:video_id)\n    @missing_videos_cue = Talk.includes(:child_talks, :event).where(video_id: videos_with_missing_cues_ids).group_by(&:event)&.select { |_event, talks| talks.any? } || []\n    @missing_videos_cue_count = videos_with_missing_cues.count\n  end\nend\n"
  },
  {
    "path": "app/controllers/coordinates_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass CoordinatesController < ApplicationController\n  include EventMapMarkers\n\n  skip_before_action :authenticate_user!\n\n  def index\n    return if params[:q].blank?\n\n    result = Geocoder.search(params[:q]).first\n    lat = result&.latitude\n    lon = result&.longitude\n\n    if lat.present? && lon.present?\n      redirect_to coordinates_path(coordinates: \"#{lat},#{lon}\")\n    else\n      flash.now[:alert] = \"Could not find location: #{params[:q]}\"\n    end\n  end\n\n  def show\n    @location = CoordinateLocation.from_param(params[:coordinates])\n\n    if @location.blank?\n      redirect_to root_path\n      return\n    end\n\n    load_location_data\n  end\n\n  private\n\n  def load_location_data\n    @events = @location.events.includes(:series).order(start_date: :desc)\n    @users = @location.users\n\n    @nearby_users = @location.nearby_users(exclude_ids: @users.pluck(:id))\n    @nearby_events = @location.nearby_events(exclude_ids: @events.pluck(:id))\n\n    @country = @location.country\n    @continent = @location.continent\n\n    all_events_for_map = @events.select(&:upcoming?).select(&:geocoded?)\n    all_events_for_map += @nearby_events.select { |n| n[:event].upcoming? }.map { |n| n[:event] }.select(&:geocoded?)\n\n    @event_map_markers = event_map_markers(all_events_for_map)\n    @geo_layers = build_geo_layers(all_events_for_map)\n  end\n\n  def build_geo_layers(events)\n    coordinate_pin = {\n      type: \"coordinate\",\n      name: @location.name,\n      longitude: @location.longitude,\n      latitude: @location.latitude\n    }\n\n    [{\n      id: \"geo-coordinate\",\n      label: @location.name,\n      emoji: \"📍\",\n      markers: event_map_markers(events),\n      cityPin: coordinate_pin,\n      alwaysVisible: true,\n      visible: true,\n      group: \"geo\"\n    }]\n  end\nend\n"
  },
  {
    "path": "app/controllers/countries/base_controller.rb",
    "content": "class Countries::BaseController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  before_action :set_country\n\n  private\n\n  def set_country\n    @country = Country.find(params[:country_country])\n    redirect_to(countries_path) and return unless @country.present?\n  end\n\n  def country_events\n    @country_events ||= @country.events.includes(:series).sort_by { |e| event_sort_date(e) }.reverse\n  end\n\n  def event_sort_date(event)\n    event.static_metadata&.home_sort_date || Time.at(0).to_date\n  end\nend\n"
  },
  {
    "path": "app/controllers/countries/cities_controller.rb",
    "content": "class Countries::CitiesController < Countries::BaseController\n  def index\n    @cities = City.for_country(@country.alpha2)\n    @sort = params[:sort].presence || \"events\"\n    @show_states = @country&.states?\n\n    @cities = case @sort\n    when \"name\"\n      @cities.sort_by(&:name)\n    else\n      @cities.sort_by { |c| -c.events_count }\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/countries_controller.rb",
    "content": "class CountriesController < ApplicationController\n  include EventMapMarkers\n  include GeoMapLayers\n\n  skip_before_action :authenticate_user!, only: %i[index show]\n\n  def index\n    @countries_by_continent = Event.distinct\n      .where.not(country_code: [nil, \"\"])\n      .pluck(:country_code)\n      .filter_map { |code| Country.find_by(country_code: code) }\n      .group_by(&:continent)\n      .sort_by { |continent, _| continent&.name || \"ZZ\" }\n      .to_h\n\n    @events_by_country = Event.includes(:series)\n      .where.not(country_code: [nil, \"\"])\n      .grouped_by_country\n      .to_h\n\n    @users_by_country = User.indexable.geocoded\n      .group(:country_code)\n      .count\n      .transform_keys { |code| Country.find_by(country_code: code) }\n      .compact\n\n    @event_map_markers = event_map_markers\n  end\n\n  def show\n    @country = Country.find(params[:country])\n\n    if @country.blank?\n      redirect_to countries_path\n      return\n    end\n\n    @events = @country.events.includes(:series).order(start_date: :desc)\n    @cities = @country.cities.order(:name)\n\n    @users = @country.users\n    @stamps = @country.stamps\n    @continent = @country.continent\n    @location = @country\n\n    upcoming_events = @events.upcoming.to_a\n\n    if @country.uk_nation?\n      @parent_country = @country.parent_country\n      nation_event_ids = @events.pluck(:id)\n      @country_events = @parent_country.events.includes(:series).where.not(id: nation_event_ids).upcoming\n    end\n\n    if upcoming_events.empty? && @continent.present?\n      exclude_codes = [@country.alpha2]\n      exclude_codes << @parent_country&.alpha2 if @parent_country.present?\n      @continent_events = continent_upcoming_events(exclude_country_codes: exclude_codes.compact)\n    end\n\n    all_events_for_map = upcoming_events.select(&:geocoded?)\n    all_events_for_map += (@country_events || []).to_a.select(&:geocoded?)\n    all_events_for_map += (@continent_events || []).to_a.select(&:geocoded?)\n\n    @event_map_markers = event_map_markers(all_events_for_map)\n    @geo_layers = build_sidebar_geo_layers(upcoming_events)\n  end\n\n  def filter_events_by_time(events)\n    events.select(&:upcoming?)\n  end\n\n  def find_nearby_users(country)\n    return [] unless country.respond_to?(:alpha2)\n\n    events_with_coords = Event.where(country_code: country.alpha2)\n      .where.not(latitude: nil, longitude: nil)\n      .limit(10)\n\n    return [] if events_with_coords.empty?\n\n    avg_lat = events_with_coords.average(:latitude)\n    avg_lng = events_with_coords.average(:longitude)\n\n    return [] unless avg_lat && avg_lng\n\n    User.indexable\n      .where.not(country_code: country.alpha2)\n      .where.not(latitude: nil)\n      .near([avg_lat, avg_lng], 500, units: :km)\n      .limit(20)\n      .to_a\n  rescue => e\n    Rails.logger.warn \"Error finding nearby users for #{country.name}: #{e.message}\"\n    []\n  end\n\n  private\n\n  def continent_upcoming_events(exclude_country_codes: [])\n    return [] unless @continent.present?\n\n    continent_country_codes = @continent.countries.map(&:alpha2) - exclude_country_codes\n\n    Event.includes(:series)\n      .where(country_code: continent_country_codes)\n      .upcoming\n  end\nend\n"
  },
  {
    "path": "app/controllers/event_participations_controller.rb",
    "content": "class EventParticipationsController < ApplicationController\n  include EventData\n\n  before_action :set_event\n  before_action :set_participation, only: [:destroy]\n  before_action :set_favorite_users\n  before_action :set_participants\n\n  # POST /events/:event_slug/event_participations\n  def create\n    @participation = @event.event_participations.build(participation_params)\n    @participation.user = Current.user\n\n    if @participation.save\n      set_participants\n      respond_to do |format|\n        format.html { redirect_to event_path(@event), notice: \"Participation recorded!\" }\n        format.turbo_stream\n      end\n    else\n      respond_to do |format|\n        format.turbo_stream { render turbo_stream: turbo_stream.replace_all(\".participation_button\", partial: \"events/participation_button\", locals: {event: @event, participation: nil, errors: @participation.errors}) }\n        format.html { redirect_to event_path(@event), alert: \"Failed to record participation.\" }\n      end\n    end\n  end\n\n  # DELETE /events/:event_slug/event_participations/:id\n  def destroy\n    redirect_to event_path(@event), alert: \"Participation not found.\" unless @participation\n    @participation.destroy\n    @participation = Current.user&.main_participation_to(@event)\n    set_participants\n\n    respond_to do |format|\n      format.turbo_stream\n      format.html { redirect_to event_path(@event), notice: \"Participation removed.\" }\n    end\n  end\n\n  private\n\n  def participation_params\n    params.permit(:attended_as)\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/archive_controller.rb",
    "content": "class Events::ArchiveController < ApplicationController\n  skip_before_action :authenticate_user!, only: %i[index]\n\n  def index\n    @events = Event.canonical.joins(:series).includes(:series).order(\"LOWER(event_series.name) ASC, events.start_date ASC\")\n    @events = @events.where(\"lower(events.name) LIKE ?\", \"#{params[:letter].downcase}%\") if params[:letter].present?\n    @events = @events.ft_search(params[:s]) if params[:s].present?\n    @events = @events.where(kind: params[:kind]) if params[:kind].present? && params[:kind] != \"all\"\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/attendances_controller.rb",
    "content": "class Events::AttendancesController < ApplicationController\n  include WatchedTalks\n\n  before_action :set_event, only: [:show]\n\n  def index\n    @events = Current.user.participated_events\n      .includes(:series, :talks)\n      .where.not(end_date: nil)\n      .where(end_date: ..Date.today)\n      .distinct\n      .order(start_date: :desc)\n\n    @events_by_year = @events.group_by { |event| event.start_date&.year || \"Unknown\" }\n\n    event_ids = @events.pluck(:id)\n    watched_talks = Current.user.watched_talks.joins(:talk).where(talks: {event_id: event_ids}).pluck(\"talks.event_id\", :watched_on)\n\n    @attendance_stats = Hash.new { |h, k| h[k] = {in_person: 0, online: 0} }\n\n    watched_talks.each do |event_id, watched_on|\n      if watched_on == \"in_person\"\n        @attendance_stats[event_id][:in_person] += 1\n      else\n        @attendance_stats[event_id][:online] += 1\n      end\n    end\n  end\n\n  def show\n    event_is_past = @event.end_date.present? && @event.end_date < Date.today\n    @participation = Current.user.main_participation_to(@event)\n\n    unless @participation.present? && event_is_past && @event.talks.any?\n      redirect_to event_path(@event), alert: \"You can only mark attendance for past events you participated in\"\n      return\n    end\n\n    user_watched_talks = Current.user.watched_talks.where(talk: @event.talks)\n    watched_talks_data = user_watched_talks.pluck(:talk_id, :watched_on)\n    @user_in_person_talk_ids = watched_talks_data.select { |_, on| on == \"in_person\" }.map(&:first).to_set\n    @user_online_talk_ids = watched_talks_data.reject { |_, on| on == \"in_person\" }.map(&:first).to_set\n    @user_feedback_talk_ids = user_watched_talks.select(&:has_rating_feedback?).map(&:talk_id).to_set\n    @attendance_days = @event.schedule.exist? ? @event.schedule.days : []\n    @attendance_tracks = @event.schedule.exist? ? @event.schedule.tracks : []\n    @attendance_talks = @event.talks_in_running_order(child_talks: false).includes(:speakers).to_a\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(:series).find_by(slug: params[:event_slug])\n    redirect_to events_attendances_path, alert: \"Event not found\" unless @event\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/cfp_controller.rb",
    "content": "class Events::CFPController < ApplicationController\n  skip_before_action :authenticate_user!, only: %i[index]\n  before_action :set_event\n\n  def index\n    set_meta_tags(@event)\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(:series).find_by(slug: params[:event_slug])\n    return redirect_to(root_path, status: :moved_permanently) unless @event\n\n    redirect_to event_path(@event.canonical), status: :moved_permanently if @event.canonical.present?\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/collectibles_controller.rb",
    "content": "class Events::CollectiblesController < ApplicationController\n  skip_before_action :authenticate_user!\n  before_action :set_event\n\n  # GET /events/:event_slug/collectibles\n  def index\n    @stamps = Stamp.for_event(@event)\n    @stickers = @event.stickers\n  end\n\n  private\n\n  def set_event\n    @event = Event.find_by(slug: params[:event_slug])\n\n    redirect_to events_path, status: :moved_permanently, notice: \"Event not found\" if @event.blank?\n    set_meta_tags(@event)\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/events_controller.rb",
    "content": "class Events::EventsController < ApplicationController\n  skip_before_action :authenticate_user!, only: %i[index show]\n  before_action :set_event, only: %i[index]\n\n  def index\n    @talks = @event.talks_in_running_order.where(meta_talk: true).includes(:speakers, :parent_talk, child_talks: :speakers).reverse\n  end\n\n  def show\n    @talk = Talk.find_by(slug: params[:id])\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(:series, talks: :speakers).find_by(slug: params[:event_slug])\n    set_meta_tags(@event)\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/involvements_controller.rb",
    "content": "class Events::InvolvementsController < ApplicationController\n  skip_before_action :authenticate_user!, only: %i[index]\n\n  def index\n    @event = Event.includes(:event_involvements).find_by(slug: params[:event_slug])\n    set_meta_tags(@event) if @event\n    involvements = @event.event_involvements.includes(:involvementable).order(:position).to_a\n    @involvements_by_role = involvements.group_by(&:role)\n    @participation = Current.user&.main_participation_to(@event)\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/meetups_controller.rb",
    "content": "class Events::MeetupsController < ApplicationController\n  skip_before_action :authenticate_user!, only: :index\n\n  # GET /events/meetups\n  def index\n    @meetups = Event.where(kind: :meetup)\n      .left_joins(:talks)\n      .distinct\n      .includes(:series)\n      .group(\"events.id\")\n      .order(\"max(talks.date) DESC\")\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/participants_controller.rb",
    "content": "class Events::ParticipantsController < ApplicationController\n  include EventData\n\n  skip_before_action :authenticate_user!, only: %i[index]\n  before_action :set_event\n  before_action :set_event_meta_tags\n  before_action :set_favorite_users, only: %i[index]\n  before_action :set_participation, only: %i[index]\n  before_action :set_participants, only: %i[index]\n\n  def index\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/past_controller.rb",
    "content": "class Events::PastController < ApplicationController\n  skip_before_action :authenticate_user!, only: %i[index]\n\n  def index\n    @events = Event.includes(:series, :keynote_speakers)\n      .where(end_date: ...Date.today)\n      .order(start_date: :desc)\n      .limit(50)\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/related_talks_controller.rb",
    "content": "class Events::RelatedTalksController < ApplicationController\n  include WatchedTalks\n\n  skip_before_action :authenticate_user!, only: %i[index]\n  before_action :set_event, only: %i[index]\n  before_action :set_user_favorites, only: %i[index]\n\n  def index\n    @talks = @event.talks_in_running_order.includes(:speakers, :parent_talk, child_talks: :speakers)\n    @active_talk = Talk.find_by(slug: params[:active_talk])\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(:series, talks: :speakers).find_by(slug: params[:event_slug])\n    set_meta_tags(@event)\n  end\n\n  def set_user_favorites\n    return unless Current.user\n\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/schedules_controller.rb",
    "content": "class Events::SchedulesController < ApplicationController\n  skip_before_action :authenticate_user!, only: %i[index show]\n  before_action :set_event, only: %i[index show]\n\n  def index\n    unless @event.schedule.exist?\n      render :missing_schedule\n      return\n    end\n\n    @day = @days.first\n    set_talks(@day)\n  end\n\n  def show\n    @day = @days.find { |day| day[\"date\"] == params[:date] }\n\n    set_talks(@day)\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(series: :events).find_by(slug: params[:event_slug])\n    return redirect_to(root_path, status: :moved_permanently) unless @event\n\n    set_meta_tags(@event)\n\n    redirect_to schedule_event_path(@event.canonical), status: :moved_permanently if @event.canonical.present?\n\n    if @event.schedule.exist?\n      @days = @event.schedule.days\n      @tracks = @event.schedule.tracks\n    end\n  end\n\n  def set_talks(day)\n    raise \"day blank with #{params[:date]}\" if day.blank?\n\n    index = @days.index(day)\n\n    talk_count = @event.schedule.talk_offsets[index]\n    talk_offset = @event.schedule.talk_offsets.first(index).sum\n\n    @talks = @event.talks_in_running_order(child_talks: false).includes(:speakers).to_a.from(talk_offset).first(talk_count)\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/series_controller.rb",
    "content": "class Events::SeriesController < ApplicationController\n  include Pagy::Backend\n\n  skip_before_action :authenticate_user!, only: %i[index show]\n  before_action :set_event_series, only: %i[show reimport reindex]\n  before_action :require_admin!, only: %i[reimport reindex]\n\n  # GET /events/series\n  def index\n    @event_series = EventSeries.includes(:events).order(:name)\n  end\n\n  # GET /events/series/:slug\n  def show\n    set_meta_tags(@event_series)\n\n    @events = @event_series.events.sort_by { |event|\n      begin\n        event.start_date || Date.today\n      rescue\n        Date.today\n      end\n    }.reverse\n\n    @todos = @event_series.todos\n  end\n\n  # POST /events/series/:slug/reimport\n  def reimport\n    static_series = Static::EventSeries.find_by_slug(@event_series.slug)\n\n    if static_series\n      static_series.import!\n      redirect_to series_path(@event_series), notice: \"Event series reimported successfully.\"\n    else\n      redirect_to series_path(@event_series), alert: \"Static event series not found.\"\n    end\n  end\n\n  # POST /events/series/:slug/reindex\n  def reindex\n    Search::Backend.index(@event_series)\n\n    @event_series.events.find_each do |event|\n      Search::Backend.index(event)\n\n      event.talks.find_each { |talk| Search::Backend.index(talk) }\n    end\n\n    redirect_to series_path(@event_series), notice: \"Event series reindexed successfully.\"\n  end\n\n  private\n\n  # Use callbacks to share common setup or constraints between actions.\n  def set_event_series\n    @event_series = EventSeries.includes(:events).find_by(slug: params[:slug])\n    @event_series ||= EventSeries.find_by_slug_or_alias(params[:slug])\n\n    return redirect_to(root_path, status: :moved_permanently) unless @event_series\n\n    redirect_to series_path(@event_series), status: :moved_permanently if @event_series.slug != params[:slug]\n  end\n\n  def require_admin!\n    redirect_to series_path(@event_series), alert: \"Not authorized\" unless Current.user&.admin?\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/speakers_controller.rb",
    "content": "class Events::SpeakersController < ApplicationController\n  skip_before_action :authenticate_user!, only: %i[index]\n  before_action :set_event, only: %i[index]\n\n  def index\n    if @event.meetup?\n      # For meetups, get speakers with their talk counts at this specific meetup\n      # and sort by number of talks (descending)\n      speaker_ids = @event.talks.joins(:user_talks).pluck(\"user_talks.user_id\")\n      speaker_counts = speaker_ids.tally\n\n      @speakers_with_counts = User\n        .preloaded\n        .where(id: speaker_counts.keys)\n        .where(\"talks_count > 0\")\n        .map do |speaker|\n          # Add the meetup-specific talk count\n          speaker.define_singleton_method(:meetup_talks_count) { speaker_counts[speaker.id] }\n          speaker\n        end\n        .sort_by { |s| [-s.meetup_talks_count, s.name] }\n    end\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(:series, talks: {speakers: :connected_accounts}).find_by(slug: params[:event_slug])\n    return redirect_to(root_path, status: :moved_permanently) unless @event\n\n    set_meta_tags(@event)\n\n    redirect_to schedule_event_path(@event.canonical), status: :moved_permanently if @event.canonical.present?\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/sponsors_controller.rb",
    "content": "class Events::SponsorsController < ApplicationController\n  skip_before_action :authenticate_user!\n  before_action :set_event\n\n  # GET /events/:event_slug/sponsors\n  def index\n    @sponsors_by_tier = @event.sponsors.includes(:organization).order(:level).group_by(&:tier)\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(sponsors: :organization).find_by(slug: params[:event_slug])\n    redirect_to events_path, status: :moved_permanently, notice: \"Event not found\" if @event.blank?\n    set_meta_tags(@event)\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/talks_controller.rb",
    "content": "class Events::TalksController < ApplicationController\n  include WatchedTalks\n\n  skip_before_action :authenticate_user!, only: %i[index]\n  before_action :set_event, only: %i[index]\n  before_action :set_user_favorites, only: %i[index]\n\n  def index\n    @talks = @event.talks_in_running_order.where(meta_talk: false).includes(:speakers, :parent_talk, child_talks: :speakers).order(date: :desc)\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(:series, talks: :speakers).find_by(slug: params[:event_slug])\n    return redirect_to(root_path, status: :moved_permanently) unless @event\n\n    set_meta_tags(@event)\n  end\n\n  def set_user_favorites\n    return unless Current.user\n\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/tickets_controller.rb",
    "content": "class Events::TicketsController < ApplicationController\n  skip_before_action :authenticate_user!, only: [:show]\n  before_action :set_event\n\n  def show\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(series: :events).find_by(slug: params[:event_slug])\n    return redirect_to(root_path, status: :moved_permanently) unless @event\n\n    set_meta_tags(@event)\n\n    redirect_to event_tickets_path(@event.canonical), status: :moved_permanently if @event.canonical.present?\n    redirect_to event_path(@event) unless @event.tickets?\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/todos_controller.rb",
    "content": "class Events::TodosController < ApplicationController\n  skip_before_action :authenticate_user!, only: %i[index]\n  before_action :set_event, only: %i[index]\n\n  def index\n    @todos = @event.todos\n\n    redirect_to event_path(@event), status: :moved_permanently if @todos.empty?\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(:series).find_by(slug: params[:event_slug])\n    return redirect_to(root_path, status: :moved_permanently) unless @event\n\n    set_meta_tags(@event)\n\n    redirect_to event_todos_path(@event.canonical), status: :moved_permanently if @event.canonical.present?\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/upcoming_controller.rb",
    "content": "class Events::UpcomingController < ApplicationController\n  skip_before_action :authenticate_user!, only: %i[index]\n\n  def index\n    @events = Event.includes(:series)\n      .where.not(end_date: nil)\n      .where(end_date: Date.today..)\n      .sort_by(&:start_date)\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/venues_controller.rb",
    "content": "class Events::VenuesController < ApplicationController\n  skip_before_action :authenticate_user!, only: [:show]\n  before_action :set_event\n\n  def show\n    unless @event.venue.exist?\n      render :missing_venue\n      return\n    end\n\n    @venue = @event.venue\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(series: :events).find_by(slug: params[:event_slug])\n    return redirect_to(root_path, status: :moved_permanently) unless @event\n\n    set_meta_tags(@event)\n\n    redirect_to event_venue_path(@event.canonical), status: :moved_permanently if @event.canonical.present?\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/videos_controller.rb",
    "content": "class Events::VideosController < ApplicationController\n  include WatchedTalks\n\n  skip_before_action :authenticate_user!, only: %i[index]\n  before_action :set_event, only: %i[index]\n  before_action :set_user_favorites, only: %i[index]\n\n  def index\n    @talks = @event.talks_in_running_order.watchable.includes(:speakers, :parent_talk, child_talks: :speakers).reverse\n    @active_talk = Talk.find_by(slug: params[:active_talk])\n  end\n\n  private\n\n  def set_event\n    @event = Event.includes(:series, talks: :speakers).find_by(slug: params[:event_slug])\n    set_meta_tags(@event)\n  end\n\n  def set_user_favorites\n    return unless Current.user\n\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\nend\n"
  },
  {
    "path": "app/controllers/events/years_controller.rb",
    "content": "module Events\n  class YearsController < ApplicationController\n    skip_before_action :authenticate_user!, only: %i[index]\n\n    def index\n      @year = params[:year].to_i\n\n      base_scope = Event.not_meetup.canonical\n      first_year = base_scope.minimum(:start_date)&.year || Date.today.year\n      last_year = base_scope.maximum(:start_date)&.year || Date.today.year\n\n      if @year < first_year || @year > last_year\n        redirect_to events_path, alert: \"Invalid year\" and return\n      end\n\n      @events = Event.includes(:series, :keynote_speakers)\n        .not_meetup\n        .canonical\n        .where(start_date: Date.new(@year).all_year)\n        .order(start_date: :asc)\n\n      @monthly_events = @events.reject { |e| e.date_precision == \"year\" }\n      @yearly_events = @events.select { |e| e.date_precision == \"year\" }\n      @events_by_month = @monthly_events.group_by { |e| e.start_date&.month }\n\n      @has_previous_year = @year > first_year\n      @has_next_year = @year < last_year\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/events_controller.rb",
    "content": "class EventsController < ApplicationController\n  include WatchedTalks\n  include Pagy::Backend\n\n  skip_before_action :authenticate_user!, only: %i[index show update]\n  before_action :set_event, only: %i[show edit update reimport reindex]\n  before_action :set_user_favorites, only: %i[show]\n  before_action :require_admin!, only: %i[reimport reindex]\n\n  # GET /events\n  def index\n    @events = Event.includes(:series, :keynote_speakers)\n      .where(end_date: Date.today..)\n      .order(start_date: :asc)\n  end\n\n  # GET /events/1\n  def show\n    set_meta_tags(@event)\n\n    if @event.meetup?\n      all_meetup_events = @event.talks.where(meta_talk: true).includes(:speakers, :parent_talk, child_talks: :speakers)\n      @upcoming_meetup_events = all_meetup_events.where(\"date >= ?\", Date.today).order(date: :asc).limit(4)\n      @recent_meetup_events = all_meetup_events.where(\"date < ?\", Date.today).order(date: :desc).limit(4)\n      @recent_talks = @event.talks.where(meta_talk: false).includes(:speakers, :parent_talk, child_talks: :speakers).order(date: :desc).to_a.sample(8)\n      @featured_speakers = @event.speakers.joins(:talks).distinct.to_a.sample(8)\n    else\n      @keynotes = @event.talks.joins(:speakers).where(kind: \"keynote\").includes(:speakers, event: :series)\n      @recent_talks = @event.talks.watchable.includes(:speakers, event: :series).limit(8).shuffle\n      keynote_speakers = @event.speakers.joins(:talks).where(talks: {kind: \"keynote\"}).distinct\n      other_speakers = @event.speakers.joins(:talks).where.not(talks: {kind: \"keynote\"}).distinct.limit(8)\n      @featured_speakers = (keynote_speakers + other_speakers.first(8 - keynote_speakers.size)).uniq.shuffle\n    end\n\n    @sponsors = @event.sponsors.includes(:organization).joins(:organization).order(level: :asc)\n\n    @participation = Current.user&.main_participation_to(@event)\n  end\n\n  # GET /events/1/edit\n  def edit\n  end\n\n  # PATCH/PUT /events/1\n  def update\n    suggestion = @event.create_suggestion_from(params: event_params, user: Current.user)\n\n    if suggestion.persisted?\n      redirect_to event_path(@event), notice: suggestion.notice\n    else\n      render :edit, status: :unprocessable_entity\n    end\n  end\n\n  # POST /events/:slug/reimport\n  def reimport\n    static_event = Static::Event.find_by_slug(@event.slug)\n\n    if static_event\n      static_event.import!\n      redirect_to event_path(@event), notice: \"Event reimported successfully.\"\n    else\n      redirect_to event_path(@event), alert: \"Static event not found.\"\n    end\n  end\n\n  # POST /events/:slug/reindex\n  def reindex\n    Search::Backend.index(@event)\n\n    @event.talks.find_each { |talk| Search::Backend.index(talk) }\n    @event.speakers.find_each { |speaker| Search::Backend.index(speaker) }\n\n    redirect_to event_path(@event), notice: \"Event reindexed successfully.\"\n  end\n\n  private\n\n  # Use callbacks to share common setup or constraints between actions.\n  def set_event\n    @event = Event.includes(:series).find_by(slug: params[:slug])\n    @event ||= Event.find_by_slug_or_alias(params[:slug])\n\n    return redirect_to(root_path, status: :moved_permanently) unless @event\n\n    return redirect_to event_path(@event), status: :moved_permanently if @event.slug != params[:slug]\n\n    redirect_to event_path(@event.canonical), status: :moved_permanently if @event.canonical.present?\n  end\n\n  # Only allow a list of trusted parameters through.\n  def event_params\n    params.require(:event).permit(:name, :city, :country_code)\n  end\n\n  def set_user_favorites\n    return unless Current.user\n\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\n\n  def require_admin!\n    redirect_to event_path(@event), alert: \"Not authorized\" unless Current.user&.admin?\n  end\nend\n"
  },
  {
    "path": "app/controllers/favorite_users_controller.rb",
    "content": "class FavoriteUsersController < ApplicationController\n  before_action :set_favorite_user, only: %i[destroy update]\n\n  # GET /favorite_users or /favorite_users.json\n  def index\n    @ruby_friends = FavoriteUser.where(user: Current.user).includes(:favorite_user, :mutual_favorite_user).where.associated(:mutual_favorite_user).order(favorite_user: {name: :asc})\n    @favorite_rubyists = FavoriteUser.where(user: Current.user).includes(:favorite_user, :mutual_favorite_user).where.missing(:mutual_favorite_user).order(favorite_user: {name: :asc})\n    @recommendations = FavoriteUser.recommendations_for(Current.user) if @favorite_rubyists.empty? && @ruby_friends.empty?\n  end\n\n  # POST /favorite_users or /favorite_users.json\n  def create\n    @favorite_user = FavoriteUser.new(favorite_user_params)\n    @favorite_user.user = Current.user\n\n    respond_to do |format|\n      if @favorite_user.save\n        format.html { redirect_back_or_to favorite_users_path, notice: \"You favorited #{@favorite_user.favorite_user.name}!\" }\n      else\n        format.html { redirect_back_or_to favorite_users_path, notice: \"Favorite was unsuccessful.\" }\n      end\n    end\n  end\n\n  # PATCH/PUT /favorite_users/1 or /favorite_users/1.json\n  def update\n    respond_to do |format|\n      if @favorite_user.update(favorite_user_params)\n        format.html do\n          if params[:redirect_to].present?\n            redirect_to params[:redirect_to]\n          else\n            redirect_back_or_to favorite_users_path\n          end\n        end\n      else\n        format.html { redirect_back_or_to favorite_users_path, alert: \"Failed to update.\" }\n      end\n    end\n  end\n\n  # DELETE /favorite_users/1 or /favorite_users/1.json\n  def destroy\n    @favorite_user.destroy!\n\n    respond_to do |format|\n      format.html { redirect_back_or_to favorite_users_path, status: :see_other }\n    end\n  end\n\n  private\n\n  # Use callbacks to share common setup or constraints between actions.\n  def set_favorite_user\n    @favorite_user = FavoriteUser.find(params.expect(:id))\n  end\n\n  # Only allow a list of trusted parameters through.\n  def favorite_user_params\n    params.expect(favorite_user: [:favorite_user_id, :notes])\n  end\nend\n"
  },
  {
    "path": "app/controllers/gems_controller.rb",
    "content": "class GemsController < ApplicationController\n  include Pagy::Backend\n  include WatchedTalks\n\n  skip_before_action :authenticate_user!\n  before_action :set_gem, only: [:show, :talks]\n  before_action :set_user_favorites, only: [:show, :talks]\n\n  def index\n    @gems = TopicGem\n      .joins(:topic)\n      .where(topics: {status: :approved})\n      .select(\"topic_gems.*, topics.talks_count as talks_count\")\n      .order(\"topics.talks_count DESC\")\n\n    @gems = @gems.where(\"lower(gem_name) LIKE ?\", \"#{params[:letter].downcase}%\") if params[:letter].present?\n    @pagy, @gems = pagy(@gems, limit: 50, page: page_number)\n\n    set_meta_tags(\n      title: \"Ruby Gems\",\n      description: \"Browse Ruby gems featured in conference talks\"\n    )\n  end\n\n  def show\n    @talks = @topic.talks.includes(:speakers, event: :series).order(date: :desc).limit(8)\n\n    set_meta_tags(\n      title: @gem.gem_name,\n      description: \"Watch #{@topic.talks_count} conference talks about #{@gem.gem_name}\"\n    )\n  end\n\n  def talks\n    @pagy, @talks = pagy_countless(\n      @topic.talks.includes(:speakers, event: :series).order(date: :desc),\n      limit: 24,\n      page: page_number\n    )\n\n    set_meta_tags(\n      title: \"Talks about #{@gem.gem_name}\",\n      description: \"Watch #{@topic.talks_count} conference talks about #{@gem.gem_name}\"\n    )\n  end\n\n  private\n\n  def set_gem\n    @gem = TopicGem.find_by!(gem_name: params[:gem_name])\n    @topic = @gem.topic\n  end\n\n  def set_user_favorites\n    return unless Current.user\n\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\n\n  def page_number\n    [params[:page]&.to_i, 1].compact.max\n  end\nend\n"
  },
  {
    "path": "app/controllers/hotwire/native/v1/android/path_configurations_controller.rb",
    "content": "class Hotwire::Native::V1::Android::PathConfigurationsController < ActionController::Base\n  def show\n    render json: {\n      settings: {},\n      rules: [\n        {\n          patterns: [\n            \".*\"\n          ],\n          properties: {\n            context: \"default\",\n            uri: \"hotwire://fragment/web\",\n            fallback_uri: \"hotwire://fragment/web\",\n            pull_to_refresh_enabled: true\n          }\n        }\n      ]\n    }\n  end\nend\n"
  },
  {
    "path": "app/controllers/hotwire/native/v1/ios/path_configurations_controller.rb",
    "content": "class Hotwire::Native::V1::IOS::PathConfigurationsController < ActionController::Base\n  def show\n    render json: {\n      settings: {},\n      rules: [\n        {\n          patterns: [\n            \"^$\",\n            \"^/$\",\n            \"^/home$\"\n          ],\n          properties: {\n            view_controller: \"home\"\n          }\n        },\n        # {\n        #   \"patterns\": [\n        #     \"^/speakers$\",\n        #     \"^/events$\",\n        #     \"^/talks$\"\n        #   ],\n        #   \"properties\": {\n        #     \"large_title\": true\n        #   }\n        # },\n        {\n          patterns: [\n            \"/player$\"\n          ],\n          properties: {\n            view_controller: \"player\"\n          }\n        },\n        {\n          patterns: [\n            \"/new$\",\n            \"/edit$\"\n          ],\n          properties: {\n            context: \"modal\"\n          }\n        }\n      ]\n    }\n  end\nend\n"
  },
  {
    "path": "app/controllers/hover_cards/events_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass HoverCards::EventsController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  def show\n    @event = Event.includes(:series).find_by(slug: params[:slug])\n\n    if @event.blank?\n      head :not_found\n      return\n    end\n\n    return redirect_to event_path(@event) unless turbo_frame_request?\n\n    render layout: false\n  end\nend\n"
  },
  {
    "path": "app/controllers/hover_cards/users_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass HoverCards::UsersController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  ALLOWED_AVATAR_SIZES = %w[sm md lg].freeze\n\n  def show\n    @user = User.find_by_slug_or_alias(params[:slug])\n    @user ||= User.find_by_github_handle(params[:slug])\n\n    if @user.blank? || @user.suspicious?\n      head :not_found\n      return\n    end\n\n    return redirect_to profile_path(@user) unless turbo_frame_request?\n\n    @avatar_size = ALLOWED_AVATAR_SIZES.include?(params[:avatar_size]) ? params[:avatar_size].to_sym : :sm\n\n    render layout: false\n  end\nend\n"
  },
  {
    "path": "app/controllers/leaderboard_controller.rb",
    "content": "class LeaderboardController < ApplicationController\n  skip_before_action :authenticate_user!, only: %i[index]\n\n  def index\n    @filter = params[:filter] || \"all_time\"\n    @ranked_speakers = User.speakers\n      .left_joins(:talks)\n      .group(:id)\n      .order(\"COUNT(talks.id) DESC\")\n      .select(\"users.*, COUNT(talks.id) as talks_count_in_range\")\n      .where(\"users.name is not 'TODO'\")\n\n    if @filter == \"last_12_months\"\n      @ranked_speakers = @ranked_speakers.where(\"talks.date >= ?\", 12.months.ago.to_date)\n    end\n    @ranked_speakers = @ranked_speakers.limit(100)\n  end\nend\n"
  },
  {
    "path": "app/controllers/locations/base_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass Locations::BaseController < ApplicationController\n  include EventMapMarkers\n\n  skip_before_action :authenticate_user!\n\n  before_action :set_location\n\n  private\n\n  def set_location\n    if params[:online].present?\n      set_online\n    elsif params[:coordinates].present?\n      set_coordinates\n    elsif params[:continent_continent].present?\n      set_continent\n    elsif params[:country_country].present?\n      set_country\n    elsif params[:state_alpha2].present? && params[:state_slug].present?\n      set_state\n    elsif params[:slug].present?\n      set_featured_city\n    elsif params[:state].present?\n      set_city_with_state\n    elsif params[:alpha2].present?\n      set_city_by_country\n    else\n      redirect_to root_path\n    end\n  end\n\n  def set_online\n    @location = OnlineLocation.instance\n  end\n\n  def set_coordinates\n    @location = CoordinateLocation.from_param(params[:coordinates])\n    redirect_to(root_path) and return unless @location.present?\n\n    @country = @location.country\n    @continent = @location.continent\n  end\n\n  def set_continent\n    @location = @continent = Continent.find(params[:continent_continent])\n\n    redirect_to(continents_path) and return unless @continent.present?\n  end\n\n  def set_country\n    @location = @country = Country.find(params[:country_country])\n    redirect_to(countries_path) and return unless @country.present?\n\n    @continent = @country.continent\n  end\n\n  def set_state\n    @country = Country.find_by(country_code: params[:state_alpha2].upcase)\n    redirect_to(countries_path) and return unless @country.present?\n\n    @location = @state = State.find(country: @country, term: params[:state_slug])\n    redirect_to(country_path(@country)) and return unless @state.present?\n\n    @continent = @country.continent\n  end\n\n  def set_featured_city\n    @location = @city = City.find_by(slug: params[:slug])\n    redirect_to(cities_path) and return unless @city.present?\n\n    @country = Country.find_by(country_code: @city.country_code)\n    @continent = @country&.continent\n\n    if @city.state_code.present? && @country.present? && @country&.states?\n      @state = State.find(country: @country, term: @city.state_code)\n    end\n  end\n\n  def set_city_by_country\n    @country = Country.find_by(country_code: params[:alpha2].upcase)\n    redirect_to(countries_path) and return unless @country.present?\n\n    @continent = @country.continent\n\n    @city_slug = params[:city]\n    @city_name = @city_slug.tr(\"-\", \" \").titleize\n\n    featured = City.find_by(slug: @city_slug)\n    featured ||= City.find_for(city: @city_name, country_code: @country.alpha2)\n\n    if featured.present?\n      redirect_to send(redirect_path_helper, featured.slug), status: :moved_permanently\n      return\n    end\n\n    @location = @city = City.new(\n      name: @city_name,\n      slug: @city_slug,\n      country_code: @country.alpha2,\n      state_code: nil\n    ).with_coordinates\n  end\n\n  def set_city_with_state\n    @country = Country.find_by(country_code: params[:alpha2].upcase)\n    redirect_to(countries_path) and return unless @country.present?\n\n    @state = State.find(country: @country, term: params[:state])\n    redirect_to(country_path(@country)) and return unless @state.present?\n\n    @city_slug = params[:city]\n    @city_name = @city_slug.tr(\"-\", \" \").titleize\n\n    featured = City.find_by(slug: @city_slug)\n\n    featured ||= City.find_for(\n      city: @city_name,\n      country_code: @country.alpha2,\n      state_code: @state.code\n    )\n\n    if featured.present?\n      redirect_to send(redirect_path_helper, featured.slug), status: :moved_permanently\n      return\n    end\n\n    @continent = @country.continent\n\n    @location = @city = City.new(\n      name: @city_name,\n      slug: @city_slug,\n      country_code: @country.alpha2,\n      state_code: @state.code\n    ).with_coordinates\n  end\n\n  def redirect_path_helper\n    :city_path\n  end\n\n  def location_events\n    @location_events ||= @location.events.includes(:series).order(start_date: :desc)\n  end\n\n  def upcoming_events\n    @upcoming_events ||= location_events.upcoming.reorder(start_date: :asc)\n  end\n\n  def past_events\n    @past_events ||= location_events.past.reorder(end_date: :desc)\n  end\n\n  def location_users\n    @location_users ||= if city? || state? || coordinate?\n      @location.users.geocoded.preloaded\n    else\n      @location.users.canonical.preloaded\n    end\n  end\n\n  def load_nearby_data\n    if coordinate?\n      @nearby_users = @location.nearby_users(exclude_ids: location_users.pluck(:id))\n    elsif city? && @city.geocoded?\n      @nearby_users = @city.nearby_users(exclude_ids: location_users.pluck(:id))\n    end\n  end\n\n  def load_cities\n    return unless country? || state?\n\n    @cities = if state?\n      @state.cities.order(:name)\n    else\n      @location.cities.order(:name)\n    end\n  end\n\n  def load_nearby_events\n    if coordinate? && upcoming_events.empty?\n      @nearby_events = @location.nearby_events(exclude_ids: [])\n        .select { |n| n[:event].upcoming? }\n    elsif city? && @city.geocoded? && upcoming_events.empty?\n      @nearby_events = @city.nearby_events(exclude_ids: [])\n        .select { |n| n[:event].upcoming? }\n    end\n  end\n\n  def country_upcoming_events(exclude_ids: [])\n    return [] unless city?\n\n    Event.includes(:series)\n      .where(country_code: @city.country_code)\n      .where.not(city: @city.name)\n      .where.not(id: exclude_ids)\n      .upcoming\n  end\n\n  def continent_upcoming_events(exclude_country_codes: [])\n    return [] unless @continent.present?\n\n    continent_country_codes = @continent.countries.map(&:alpha2) - exclude_country_codes\n\n    Event.includes(:series)\n      .where(country_code: continent_country_codes)\n      .upcoming\n  end\n\n  def online?\n    @location.is_a?(OnlineLocation)\n  end\n\n  def coordinate?\n    @location.is_a?(CoordinateLocation)\n  end\n\n  def city?\n    @location.is_a?(City)\n  end\n\n  def state?\n    @location.is_a?(State)\n  end\n\n  def country?\n    @location.is_a?(Country) || @location.is_a?(UKNation)\n  end\n\n  def continent?\n    @location.is_a?(Continent)\n  end\n\n  def location_view_prefix\n    case @location\n    when OnlineLocation then \"online\"\n    when CoordinateLocation then \"coordinates\"\n    when Continent then \"continents\"\n    when Country, UKNation then \"countries\"\n    when State then \"states\"\n    else \"cities\"\n    end\n  end\n\n  def render_location_view(action)\n    return redirect_to(root_path) unless @location.present?\n\n    render \"#{location_view_prefix}/#{action}/index\"\n  end\nend\n"
  },
  {
    "path": "app/controllers/locations/map_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass Locations::MapController < Locations::BaseController\n  def index\n    @geo_layers = build_geographic_layers\n    @time_layers = build_time_filter_options\n    @layers = @geo_layers\n    @online_events = fetch_online_events\n\n    render_location_view(\"map\")\n  end\n\n  private\n\n  def build_time_filter_options\n    has_upcoming = @geo_layers.any? { |l| l[:markers].any? { |m| m[:events].any? { |e| e[:upcoming] } } }\n    has_past = @geo_layers.any? { |l| l[:markers].any? { |m| m[:events].any? { |e| !e[:upcoming] } } }\n\n    options = []\n\n    options << {id: \"upcoming\", label: \"Upcoming\", visible: true} if has_upcoming\n    options << {id: \"past\", label: \"Past\", visible: !has_upcoming} if has_past\n    options << {id: \"all\", label: \"All Events\", visible: false} if has_upcoming && has_past\n\n    options\n  end\n\n  def build_geographic_layers\n    layers = case @location\n    when Continent\n      build_continent_geo_layers\n    when Country, UKNation\n      build_country_geo_layers\n    when State\n      build_state_geo_layers\n    when City\n      build_city_geo_layers\n    when CoordinateLocation\n      build_coordinate_geo_layers\n    else\n      raise \"#{@location.class} unexpected\"\n    end\n\n    select_default_visible_layer(layers)\n  end\n\n  def select_default_visible_layer(layers)\n    return layers if layers.empty?\n\n    layers.each { |layer| layer[:visible] = false }\n\n    layer_with_upcoming = layers.find do |layer|\n      layer[:markers].any? { |marker| marker[:events].any? { |event| event[:upcoming] } }\n    end\n\n    if layer_with_upcoming\n      layer_with_upcoming[:visible] = true\n    else\n      first_with_events = layers.find { |layer| layer[:markers].any? }\n\n      if first_with_events\n        first_with_events[:visible] = true\n      else\n        layers.first[:visible] = true\n      end\n    end\n\n    layers\n  end\n\n  def build_continent_geo_layers\n    layers = []\n\n    events_by_country = @continent.events.includes(:series).group_by(&:country_code)\n\n    events_by_country.each do |country_code, events|\n      country = Country.find_by(country_code: country_code)\n      next unless country\n\n      markers = event_map_markers(events)\n      next if markers.empty?\n\n      layers << {\n        id: \"geo-#{country_code.downcase}\",\n        label: country.name,\n        markers: markers,\n        visible: false,\n        group: \"geo\"\n      }\n    end\n\n    layers.sort_by { |l| -l[:markers].size }\n  end\n\n  def build_country_geo_layers\n    layers = []\n\n    country_events = @location.events.includes(:series).to_a\n    country_markers = event_map_markers(country_events)\n\n    if country_markers.any?\n      layers << {\n        id: \"geo-country\",\n        label: @location.name,\n        markers: country_markers,\n        visible: false,\n        group: \"geo\"\n      }\n    end\n\n    if @continent.present?\n      continent_country_codes = @continent.countries.map(&:alpha2)\n      continent_events = Event.includes(:series).where(country_code: continent_country_codes).to_a\n      continent_markers = event_map_markers(continent_events)\n\n      if continent_markers.any? && continent_markers.size > country_markers.size\n        layers << {\n          id: \"geo-continent\",\n          label: @continent.name,\n          markers: continent_markers,\n          visible: false,\n          group: \"geo\"\n        }\n      end\n    end\n\n    layers\n  end\n\n  def build_state_geo_layers\n    layers = []\n\n    state_events = @state.events.includes(:series).to_a\n    state_markers = event_map_markers(state_events)\n\n    if state_markers.any?\n      layers << {\n        id: \"geo-state\",\n        label: @state.name,\n        markers: state_markers,\n        visible: false,\n        group: \"geo\"\n      }\n    end\n\n    country_events = Event.includes(:series).where(country_code: @country.alpha2).to_a\n    country_markers = event_map_markers(country_events)\n\n    if country_markers.any? && country_markers.size > state_markers.size\n      layers << {\n        id: \"geo-country\",\n        label: @country.name,\n        markers: country_markers,\n        visible: false,\n        group: \"geo\"\n      }\n    end\n\n    if @continent.present?\n      continent_country_codes = @continent.countries.map(&:alpha2)\n      continent_events = Event.includes(:series).where(country_code: continent_country_codes).to_a\n      continent_markers = event_map_markers(continent_events)\n\n      if continent_markers.any? && continent_markers.size > country_markers.size\n        layers << {\n          id: \"geo-continent\",\n          label: @continent.name,\n          markers: continent_markers,\n          visible: false,\n          group: \"geo\"\n        }\n      end\n    end\n\n    layers\n  end\n\n  def build_city_geo_layers\n    layers = []\n\n    city_events = location_events.to_a\n    city_markers = event_map_markers(city_events)\n    city_pin = nil\n\n    if @city.geocoded?\n      city_pin = {\n        type: \"city\",\n        name: @city.name,\n        longitude: @city.longitude,\n        latitude: @city.latitude\n      }\n    end\n\n    layers << {\n      id: \"geo-city\",\n      label: @city.name,\n      emoji: \"📍\",\n      markers: city_markers,\n      cityPin: city_pin,\n      alwaysVisible: true,\n      visible: false,\n      group: \"geo\"\n    }\n\n    if @city.respond_to?(:nearby_events) && @city.geocoded?\n      nearby_event_data = @city.nearby_events(radius_km: 250, limit: 50, exclude_ids: city_events.map(&:id))\n      nearby_events_list = nearby_event_data.map { |d| d[:event] }\n\n      city_plus_nearby = city_events + nearby_events_list\n      nearby_markers = event_map_markers(city_plus_nearby)\n\n      if nearby_markers.any? && nearby_markers.size > city_markers.size\n        layers << {\n          id: \"geo-nearby\",\n          label: \"Nearby\",\n          emoji: \"📍🔄\",\n          markers: nearby_markers,\n          visible: false,\n          group: \"geo\"\n        }\n      end\n    end\n\n    if @state.present? && @country.present? && @country&.states?\n      state_events = Event.includes(:series)\n        .where(country_code: @country.alpha2, state_code: @state.code)\n        .to_a\n      state_markers = event_map_markers(state_events)\n\n      if state_markers.any? && state_markers.size > (layers.last&.dig(:markers)&.size || 0)\n        layers << {\n          id: \"geo-state\",\n          label: @state.name,\n          emoji: \"🗺️\",\n          markers: state_markers,\n          visible: false,\n          group: \"geo\"\n        }\n      end\n    end\n\n    if @country.present?\n      country_events = Event.includes(:series).where(country_code: @country.alpha2).to_a\n      country_markers = event_map_markers(country_events)\n\n      if country_markers.any? && country_markers.size > (layers.last&.dig(:markers)&.size || 0)\n        layers << {\n          id: \"geo-country\",\n          label: @country.name,\n          emoji: @country.emoji_flag,\n          markers: country_markers,\n          visible: false,\n          group: \"geo\"\n        }\n      end\n    end\n\n    if @continent.present?\n      continent_country_codes = @continent.countries.map(&:alpha2)\n      continent_events = Event.includes(:series).where(country_code: continent_country_codes).to_a\n      continent_markers = event_map_markers(continent_events)\n\n      if continent_markers.any? && continent_markers.size > (layers.last&.dig(:markers)&.size || 0)\n        layers << {\n          id: \"geo-continent\",\n          label: @continent.name,\n          emoji: @continent.emoji_flag,\n          markers: continent_markers,\n          visible: false,\n          group: \"geo\"\n        }\n      end\n    end\n\n    layers\n  end\n\n  def build_coordinate_geo_layers\n    layers = []\n\n    coordinate_events = location_events.to_a\n    coordinate_markers = event_map_markers(coordinate_events)\n    coordinate_pin = nil\n\n    if @location.geocoded?\n      coordinate_pin = {\n        type: \"coordinate\",\n        name: @location.name,\n        longitude: @location.longitude,\n        latitude: @location.latitude\n      }\n    end\n\n    layers << {\n      id: \"geo-coordinate\",\n      label: @location.name,\n      emoji: \"📍\",\n      markers: coordinate_markers,\n      cityPin: coordinate_pin,\n      alwaysVisible: true,\n      visible: false,\n      group: \"geo\"\n    }\n\n    nearby_event_data = @location.nearby_events(radius_km: 250, limit: 50, exclude_ids: coordinate_events.map(&:id))\n    nearby_events_list = nearby_event_data.map { |d| d[:event] }\n\n    coordinate_plus_nearby = coordinate_events + nearby_events_list\n    nearby_markers = event_map_markers(coordinate_plus_nearby)\n\n    if nearby_markers.any? && nearby_markers.size > coordinate_markers.size\n      layers << {\n        id: \"geo-nearby\",\n        label: \"Nearby\",\n        emoji: \"📍🔄\",\n        markers: nearby_markers,\n        visible: false,\n        group: \"geo\"\n      }\n    end\n\n    if @country.present?\n      country_events = Event.includes(:series).where(country_code: @country.alpha2).to_a\n      country_markers = event_map_markers(country_events)\n\n      if country_markers.any? && country_markers.size > (layers.last&.dig(:markers)&.size || 0)\n        layers << {\n          id: \"geo-country\",\n          label: @country.name,\n          emoji: @country.emoji_flag,\n          markers: country_markers,\n          visible: false,\n          group: \"geo\"\n        }\n      end\n    end\n\n    if @continent.present?\n      continent_country_codes = @continent.countries.map(&:alpha2)\n      continent_events = Event.includes(:series).where(country_code: continent_country_codes).to_a\n      continent_markers = event_map_markers(continent_events)\n\n      if continent_markers.any? && continent_markers.size > (layers.last&.dig(:markers)&.size || 0)\n        layers << {\n          id: \"geo-continent\",\n          label: @continent.name,\n          emoji: @continent.emoji_flag,\n          markers: continent_markers,\n          visible: false,\n          group: \"geo\"\n        }\n      end\n    end\n\n    layers\n  end\n\n  def fetch_online_events\n    base_scope = Event.includes(:series).not_geocoded.upcoming\n\n    case @location\n    when Continent\n      base_scope.where(country_code: @continent.countries.map(&:alpha2))\n    when Country, UKNation\n      country_code = @location.respond_to?(:alpha2) ? @location.alpha2 : @location.country_code\n      base_scope.where(country_code: country_code)\n    when State\n      base_scope.where(country_code: @country.alpha2, state_code: @state.code)\n    when CoordinateLocation\n      base_scope.none\n    else # City\n      base_scope.where(city: @city.name)\n    end\n  end\n\n  def redirect_path_helper\n    :city_map_index_path\n  end\nend\n"
  },
  {
    "path": "app/controllers/locations/meetups_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass Locations::MeetupsController < Locations::BaseController\n  def index\n    @meetups = @location.events\n      .joins(:series)\n      .where(event_series: {kind: :meetup})\n      .includes(:series)\n      .order(\"event_series.name\", start_date: :desc)\n\n    render_location_view(\"meetups\")\n  end\n\n  private\n\n  def redirect_path_helper\n    :city_meetups_path\n  end\nend\n"
  },
  {
    "path": "app/controllers/locations/past_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass Locations::PastController < Locations::BaseController\n  include GeoMapLayers\n\n  def index\n    @events = past_events\n    @users = location_users\n    @event_map_markers = event_map_markers(@events.geocoded)\n\n    load_nearby_data if city?\n    load_cities if country? || state?\n\n    @geo_layers = build_sidebar_geo_layers(@events)\n\n    render_location_view(\"past\")\n  end\n\n  private\n\n  def filter_events_by_time(events)\n    events.select(&:past?)\n  end\n\n  def redirect_path_helper\n    :city_past_index_path\n  end\nend\n"
  },
  {
    "path": "app/controllers/locations/stamps_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass Locations::StampsController < Locations::BaseController\n  def index\n    @stamps = @location.stamps\n\n    render_location_view(\"stamps\")\n  end\n\n  private\n\n  def redirect_path_helper\n    :city_stamps_path\n  end\nend\n"
  },
  {
    "path": "app/controllers/locations/users_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass Locations::UsersController < Locations::BaseController\n  def index\n    @users = location_users\n\n    if city?\n      load_nearby_users\n      load_state_users\n    elsif coordinate?\n      load_coordinate_nearby_users\n      load_country_users\n    end\n\n    render_location_view(\"users\")\n  end\n\n  private\n\n  def load_nearby_users\n    return unless @city.geocoded?\n\n    @nearby_users = @city.nearby_users(\n      radius_km: 250,\n      limit: 100,\n      exclude_ids: @users.pluck(:id)\n    )\n  end\n\n  def load_state_users\n    return unless @state.present?\n\n    city_user_ids = @users.pluck(:id)\n    nearby_user_ids = (@nearby_users || []).map { |n| n.is_a?(Hash) ? n[:user].id : n.id }\n    exclude_ids = city_user_ids + nearby_user_ids\n    @state_users = @state.users.geocoded.preloaded.where.not(id: exclude_ids)\n  end\n\n  def load_coordinate_nearby_users\n    @nearby_users = @location.nearby_users(\n      radius_km: 250,\n      limit: 100,\n      exclude_ids: []\n    )\n  end\n\n  def load_country_users\n    return unless @country.present?\n\n    nearby_user_ids = (@nearby_users || []).map { |n| n.is_a?(Hash) ? n[:user].id : n.id }\n    @country_users = @country.users.geocoded.preloaded.where.not(id: nearby_user_ids)\n  end\n\n  def redirect_path_helper\n    :city_users_path\n  end\nend\n"
  },
  {
    "path": "app/controllers/online_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass OnlineController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  def show\n    @location = OnlineLocation.instance\n    @events = @location.events.upcoming.order(start_date: :asc)\n  end\nend\n"
  },
  {
    "path": "app/controllers/organizations/logos_controller.rb",
    "content": "class Organizations::LogosController < ApplicationController\n  before_action :set_organization\n  before_action :ensure_admin!\n\n  def show\n    @back_path = organization_path(@organization)\n  end\n\n  def update\n    if @organization.update(organization_params)\n      redirect_to organization_logos_path(@organization), notice: \"Updated successfully.\"\n    else\n      redirect_to organization_logos_path(@organization), alert: \"Failed to update.\"\n    end\n  end\n\n  private\n\n  def set_organization\n    @organization = Organization.find_by_slug_or_alias(params[:organization_slug])\n    redirect_to organizations_path, status: :moved_permanently, notice: \"Organization not found\" if @organization.blank?\n  end\n\n  def ensure_admin!\n    redirect_to organizations_path, status: :unauthorized unless Current.user&.admin?\n  end\n\n  def organization_params\n    params.require(:organization).permit(:logo_url, :logo_background)\n  end\nend\n"
  },
  {
    "path": "app/controllers/organizations/wrapped_controller.rb",
    "content": "class Organizations::WrappedController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  YEAR = 2025\n\n  before_action :set_organization\n\n  def index\n    @year = YEAR\n    year_range = Date.new(@year, 1, 1)..Date.new(@year, 12, 31)\n\n    @sponsored_events = @organization.events\n      .where(start_date: year_range)\n      .includes(:series)\n      .order(start_date: :asc)\n\n    @total_events_sponsored = @sponsored_events.count\n\n    @talks_at_sponsored_events = Talk\n      .joins(:event)\n      .where(events: {id: @sponsored_events.pluck(:id)})\n      .count\n\n    @speakers_at_sponsored_events = User\n      .joins(:talks)\n      .where(talks: {event_id: @sponsored_events.pluck(:id)})\n      .distinct\n      .count\n\n    @countries_sponsored = @sponsored_events\n      .map(&:country)\n      .compact\n      .uniq\n\n    @sponsor_tiers = Sponsor\n      .where(organization: @organization)\n      .joins(:event)\n      .where(events: {start_date: year_range})\n      .group(:tier)\n      .count\n      .sort_by { |_, count| -count }\n\n    @involved_events = @organization.involved_events\n      .where(start_date: year_range)\n      .includes(:series)\n      .order(start_date: :asc)\n\n    @involvements = @organization.event_involvements\n      .joins(:event)\n      .where(events: {start_date: year_range})\n      .includes(:event)\n\n    @involvements_by_role = @involvements.group_by(&:role)\n\n    @share_url = organization_wrapped_index_url(organization_slug: @organization.slug)\n\n    first_year = @organization.events.minimum(:start_date)&.year\n    @years_supporting = first_year ? (@year - first_year + 1) : 1\n\n    set_wrapped_meta_tags\n  end\n\n  def og_image\n    ensure_card_generated\n\n    if @organization.wrapped_card_horizontal.attached?\n      disposition = params[:download].present? ? \"attachment\" : \"inline\"\n      redirect_to rails_blob_url(@organization.wrapped_card_horizontal, disposition: disposition), allow_other_host: true\n    else\n      head :internal_server_error\n    end\n  end\n\n  private\n\n  def set_organization\n    @organization = Organization.find_by!(slug: params[:organization_slug])\n  end\n\n  def set_wrapped_meta_tags\n    description = \"See #{@organization.name}'s #{@year} Ruby Events Wrapped!\"\n    title = \"#{@organization.name}'s #{@year} Wrapped - RubyEvents.org\"\n    image_url = og_image_organization_wrapped_index_url(organization_slug: @organization.slug)\n\n    set_meta_tags(\n      title: title,\n      description: description,\n      og: {\n        title: title,\n        description: description,\n        image: image_url,\n        type: \"website\",\n        url: @share_url\n      },\n      twitter: {\n        title: title,\n        description: description,\n        image: image_url,\n        card: \"summary_large_image\"\n      }\n    )\n  end\n\n  def ensure_card_generated\n    return if @organization.wrapped_card_horizontal.attached?\n\n    @year = YEAR\n    year_range = Date.new(@year, 1, 1)..Date.new(@year, 12, 31)\n\n    @sponsored_events = @organization.events.where(start_date: year_range)\n    @total_events_sponsored = @sponsored_events.count\n    @countries_sponsored = @sponsored_events.map(&:country).compact.uniq\n\n    @talks_at_sponsored_events = Talk\n      .joins(:event)\n      .where(events: {id: @sponsored_events.pluck(:id)})\n      .count\n\n    @speakers_at_sponsored_events = User\n      .joins(:talks)\n      .where(talks: {event_id: @sponsored_events.pluck(:id)})\n      .distinct\n      .count\n\n    @share_url = organization_wrapped_index_url(organization_slug: @organization.slug)\n\n    first_year = @organization.events.minimum(:start_date)&.year\n    @years_supporting = first_year ? (@year - first_year + 1) : 1\n\n    generator = Organization::WrappedScreenshotGenerator.new(@organization)\n    generator.save_to_storage(wrapped_locals)\n    @organization.reload\n  end\n\n  def wrapped_locals\n    {\n      organization: @organization,\n      year: @year,\n      sponsored_events: @sponsored_events,\n      total_events_sponsored: @total_events_sponsored,\n      countries_sponsored: @countries_sponsored,\n      talks_at_sponsored_events: @talks_at_sponsored_events,\n      speakers_at_sponsored_events: @speakers_at_sponsored_events,\n      share_url: @share_url,\n      years_supporting: @years_supporting\n    }\n  end\nend\n"
  },
  {
    "path": "app/controllers/organizations_controller.rb",
    "content": "class OrganizationsController < ApplicationController\n  skip_before_action :authenticate_user!\n  before_action :set_organization, only: %i[show]\n\n  # GET /organizations\n  def index\n    @organizations = Organization.includes(:event_involvements, :events).order(\"LOWER(organizations.name)\")\n    @organizations = @organizations.where(\"lower(name) LIKE ?\", \"#{params[:letter].downcase}%\") if params[:letter].present?\n    @featured_organizations = Organization.joins(:sponsors).group(\"organizations.id\").order(\"COUNT(sponsors.id) DESC\").limit(25).includes(:events)\n  end\n\n  # GET /organizations/1\n  def show\n    @back_path = organizations_path\n    @events = @organization.events.includes(:series, :talks).order(start_date: :desc)\n    @events_by_year = @events.group_by { |event| event.start_date&.year || \"Unknown\" }\n\n    @countries_with_events = @events.grouped_by_country\n\n    involvements = @organization.event_involvements.joins(:event).order(\n      Arel.sql(\"COALESCE(events.start_date, events.created_at) ASC\")\n    )\n    @involvements_by_role = involvements.group_by(&:role)\n    @involved_events = @organization.involved_events.includes(:series).distinct.order(start_date: :desc)\n\n    @statistics = prepare_organization_statistics\n  end\n\n  private\n\n  def prepare_organization_statistics\n    sponsors = @organization.sponsors.includes(event: [:talks, :series])\n\n    {\n      total_events: @events.size,\n      total_countries: @countries_with_events.size,\n      total_continents: @countries_with_events.map { |country, _| country.continent_name }.uniq.size,\n      total_series: @events.map(&:series).uniq.size,\n      total_talks: @events.joins(:talks).size,\n      years_active: @events_by_year.keys.reject { |y| y == \"Unknown\" }.sort,\n      first_sponsorship: @events.minimum(:start_date),\n      latest_sponsorship: @events.maximum(:start_date),\n      sponsorship_tiers: sponsors.group(:tier).count.sort_by { |_, count| -count },\n      events_by_series: @events.group_by(&:series).transform_values(&:count).sort_by { |_, count| -count }.first(5),\n      badges_with_events: sponsors.includes(:event).map { |s| [s.badge, s.event] if s.badge.present? }.compact,\n      events_by_size: @events.includes(:talks).group_by { |event| classify_event_size(event) }.transform_values(&:count)\n    }\n  end\n\n  def classify_event_size(event)\n    return \"Retreat\" if event.retreat?\n    talk_count = event.talks.size\n\n    if talk_count == 0\n      if event.start_date && event.start_date > Date.today\n        return \"Upcoming Event\"\n      else\n        return \"Event Awaiting Content\"\n      end\n    end\n\n    case talk_count\n    when 1..5\n      \"Community Gathering\"\n    when 6..20\n      \"Regional Conference\"\n    when 21..50\n      \"Major Conference\"\n    else\n      \"Flagship Event\"\n    end\n  end\n\n  def set_organization\n    @organization = Organization.find_by_slug_or_alias(params[:slug])\n\n    redirect_to organizations_path, status: :moved_permanently, notice: \"Organization not found\" if @organization.blank?\n  end\nend\n"
  },
  {
    "path": "app/controllers/page_controller.rb",
    "content": "class PageController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  def home\n    home_page_cached_data = Rails.cache.fetch(\"home_page_content\", expires_in: 1.hour) do\n      latest_talks = Talk.watchable.with_speakers.order(published_at: :desc).limit(10)\n      {\n        talks_count: Talk.count,\n        speakers_count: User.speakers.count,\n        events_count: Event.count,\n        latest_talk_ids: latest_talks.pluck(:id),\n        upcoming_talk_ids: Talk.with_speakers.where(date: Date.today..).order(date: :asc).limit(15).pluck(:id),\n        latest_event_ids: Event.order(date: :desc).limit(10).pluck(:id).sample(4),\n        featured_speaker_ids: User.with_github\n          .joins(:talks)\n          .where(talks: {date: 12.months.ago..})\n          .order(Arel.sql(\"RANDOM()\"))\n          .limit(40)\n          .pluck(:id)\n      }\n    end\n\n    @talks_count = home_page_cached_data[:talks_count]\n    @speakers_count = home_page_cached_data[:speakers_count]\n    @events_count = home_page_cached_data[:events_count]\n    @latest_talks = Talk.includes(event: :series).where(id: home_page_cached_data[:latest_talk_ids])\n    @upcoming_talks = Talk.includes(event: :series).where(id: home_page_cached_data[:upcoming_talk_ids])\n    @latest_events = Event.includes(:series).where(id: home_page_cached_data[:latest_event_ids])\n    @featured_speakers = User.where(id: home_page_cached_data[:featured_speaker_ids]).sample(10)\n    @featured_organizations = Organization.joins(:sponsors).includes(:events).group(\"organizations.id\").order(\"COUNT(sponsors.id) DESC\").limit(10)\n    @recommended_talks = Current.user.talk_recommender.talks(limit: 4) if Current.user\n\n    imported_slugs = Event.not_meetup.with_watchable_talks.pluck(:slug)\n    today_slugs = Event.not_meetup.with_talks.where(start_date: ..Date.today, end_date: Date.today..).pluck(:slug)\n    featurable_slugs = Static::Event.where.not(featured_background: nil).pluck(:slug)\n    slug_candidates = (imported_slugs | today_slugs) & featurable_slugs\n\n    featured_slugs = Static::Event.all\n      .select { |event| slug_candidates.include?(event.slug) }\n      .select(&:home_sort_date)\n      .sort_by(&:home_sort_date)\n      .reverse\n      .take(15)\n      .map(&:slug)\n\n    @featured_events = Event.distinct\n      .includes(:series, :keynote_speakers, :speakers)\n      .where(slug: featured_slugs)\n      .in_order_of(:slug, featured_slugs)\n\n    respond_to do |format|\n      format.html\n      format.json {\n        render json: {\n          featured: @featured_events.map { |event| event.to_mobile_json(request) },\n          talks: [\n            {\n              name: \"Latest Recordings\",\n              items: @latest_talks.map { |talk| talk.to_mobile_json(request) },\n              url: talks_url\n            },\n            {\n              name: \"Upcoming Talks\",\n              items: @upcoming_talks.map { |talk| talk.to_mobile_json(request) },\n              url: talks_url\n            }\n          ],\n          speakers: [\n            {\n              name: \"Active Speakers\",\n              items: @featured_speakers.map { |speaker| speaker.to_mobile_json(request) },\n              url: speakers_url\n            }\n          ],\n          events: [\n            {\n              name: \"Upcoming Events\",\n              items: Event.upcoming.limit(10).map { |event| event.to_mobile_json(request) },\n              url: events_url\n            },\n            {\n              name: \"Recent Events\",\n              items: Event.past.limit(10).map { |event| event.to_mobile_json(request) },\n              url: past_events_url\n            }\n          ]\n        }\n      }\n    end\n  end\n\n  def featured\n  end\n\n  def components\n  end\n\n  def uses\n  end\n\n  def privacy\n  end\n\n  def about\n  end\n\n  def stickers\n    @events = Event.all.select(&:sticker?)\n  end\n\n  def contributors\n    @contributors = Contributor.includes(:user).order(:name, :login)\n  end\n\n  def assets\n    @events = Event.includes(:series).order(\"event_series.name, events.name\")\n\n    @asset_types = {\n      \"avatar\" => {width: 256, height: 256, name: \"Avatar\"},\n      \"banner\" => {width: 1300, height: 350, name: \"Banner\"},\n      \"card\" => {width: 600, height: 350, name: \"Card\"},\n      \"featured\" => {width: 615, height: 350, name: \"Featured\"},\n      \"poster\" => {width: 600, height: 350, name: \"Poster\"},\n      \"sticker\" => {width: 350, height: 350, name: \"Sticker\"},\n      \"stamp\" => {width: 512, height: 512, name: \"Stamp\"}\n    }\n\n    @events_with_assets = @events.map do |event|\n      assets = {}\n      @asset_types.except(\"sticker\", \"stamp\").each do |type, _|\n        asset_path = event.event_image_for(\"#{type}.webp\")\n        assets[type] = asset_path.present?\n      end\n\n      sticker_paths = event.sticker_image_paths\n      stamp_paths = event.stamp_image_paths\n\n      {\n        event: event,\n        assets: assets,\n        has_any_assets: assets.values.any?,\n        missing_assets: assets.select { |_, exists| !exists }.keys,\n        sticker_paths: sticker_paths,\n        stamp_paths: stamp_paths\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/aliases_controller.rb",
    "content": "class Profiles::AliasesController < ApplicationController\n  include ProfileData\n\n  before_action :require_admin!\n\n  def index\n    @aliases = @user.aliases\n  end\n\n  private\n\n  def require_admin!\n    redirect_to profile_path(@user), alert: \"Not authorized\" unless Current.user&.admin?\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/claims_controller.rb",
    "content": "class Profiles::ClaimsController < ApplicationController\n  def create\n    connected_account = Current.user.connected_accounts.find_or_create_by(uid: params[:id], provider: \"passport\")\n\n    flash[:notice] = connected_account.previously_new_record? ? \"Profile claimed successfully\" : \"Profile already claimed\"\n    redirect_to profile_path(Current.user)\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/connect_controller.rb",
    "content": "class Profiles::ConnectController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  def index\n    redirect_to root_path, notice: \"No profile here\"\n  end\n\n  def show\n    @connect_id = params[:id]\n    @found_account = ConnectedAccount.find_by(uid: @connect_id, provider: \"passport\")\n    @found_user = @found_account&.user\n\n    if current_user_passport?\n      # The user landed on their own connect page\n      redirect_to profile_path(Current.user), notice: \"You did it. You landed on your profile page 🙌\"\n    elsif passport_already_claimed?\n      redirect_to profile_path(@found_user)\n    end\n  end\n\n  private\n\n  def current_user_passport?\n    return false unless @connect_id.present?\n\n    Current.user&.passports&.pluck(:uid)&.include?(@connect_id)\n  end\n\n  def passport_already_claimed?\n    return false unless @connect_id.present?\n\n    ConnectedAccount.passport.exists?(uid: @connect_id)\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/enhance_controller.rb",
    "content": "class Profiles::EnhanceController < ApplicationController\n  def update\n    @user = User.find_by_slug_or_alias(params[:slug])\n    @user ||= User.find_by_github_handle(params[:slug])\n\n    @user.profiles.enhance_all_later\n\n    flash.now[:notice] = \"Profile will be updated soon.\"\n\n    respond_to do |format|\n      format.turbo_stream\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/events_controller.rb",
    "content": "class Profiles::EventsController < ApplicationController\n  include ProfileData\n\n  def index\n    @events = @user.participated_events.includes(:series).distinct.in_order_of(:attended_as, EventParticipation.attended_as.keys)\n    event_participations = @user.event_participations.includes(:event).where(event: @events)\n    @participations = event_participations.index_by(&:event_id)\n    @events_by_year = @events.group_by { |event| event.start_date&.year || \"Unknown\" }\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/involvements_controller.rb",
    "content": "class Profiles::InvolvementsController < ApplicationController\n  include ProfileData\n\n  def index\n    event_involvements = @user.event_involvements.includes(:event)\n    @involvements_by_role = event_involvements.group_by(&:role)\n      .each do |role, involvements|\n        involvements.map!(&:event)\n          .sort_by!(&:sort_date)\n          .reverse!\n      end\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/map_controller.rb",
    "content": "class Profiles::MapController < ApplicationController\n  include ProfileData\n  include EventMapMarkers\n\n  def index\n    @events = @user.participated_events.includes(:series)\n    @countries_with_events = @events.grouped_by_country\n    @event_map_markers = event_map_markers(@events)\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/mutual_events_controller.rb",
    "content": "class Profiles::MutualEventsController < ApplicationController\n  include ProfileData\n\n  def index\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/notes_controller.rb",
    "content": "# frozen_string_literal: true\n\n# Controller for showing notes about a user on the profile\nclass Profiles::NotesController < ApplicationController\n  include ProfileData\n\n  before_action :check_favorite_user_persisted?\n\n  def edit\n  end\n\n  def show\n  end\n\n  private\n\n  def check_favorite_user_persisted?\n    unless @favorite_user&.persisted?\n      redirect_to profile_path(@user), alert: \"You can only take notes on your favorites.\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/stamps_controller.rb",
    "content": "class Profiles::StampsController < ApplicationController\n  include ProfileData\n\n  def index\n    @stamps = Stamp.for_user(@user)\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/stickers_controller.rb",
    "content": "class Profiles::StickersController < ApplicationController\n  include ProfileData\n\n  def index\n    @events = @user.participated_events.includes(:series)\n    @events_with_stickers = @events.select(&:sticker?)\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/talks_controller.rb",
    "content": "class Profiles::TalksController < ApplicationController\n  include ProfileData\n\n  def index\n    @talks = @user.kept_talks.includes(:speakers, event: :series, child_talks: :speakers).order(date: :desc)\n    @talks_by_kind = @talks.group_by(&:kind)\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles/wrapped_controller.rb",
    "content": "class Profiles::WrappedController < ApplicationController\n  include ProfileData\n  include EventMapMarkers\n\n  YEAR = 2025\n\n  before_action :check_wrapped_access, only: [:index, :card, :og_image]\n  before_action :require_owner, only: [:toggle_visibility, :generate_card]\n\n  def index\n    @year = YEAR\n    @is_owner = @user == Current.user\n    year_range = Date.new(@year, 1, 1)..Date.new(@year, 12, 31)\n\n    @watched_talks_in_year = @user.watched_talks\n      .includes(talk: [:event, :speakers, :approved_topics])\n      .where(watched_at: year_range)\n      .order(watched_at: :asc)\n\n    @total_talks_watched = @watched_talks_in_year.count\n    @total_watch_time_seconds = @watched_talks_in_year.sum(&:progress_seconds)\n    @total_watch_time_hours = (@total_watch_time_seconds / 3600.0).round(1)\n\n    @first_watched = @watched_talks_in_year.first\n    @last_watched = @watched_talks_in_year.last\n\n    talks_with_duration = @watched_talks_in_year.select { |wt| wt.talk.duration_in_seconds.to_i.positive? }\n    @longest_watched = talks_with_duration.max_by { |wt| wt.talk.duration_in_seconds }\n    @shortest_watched = talks_with_duration.min_by { |wt| wt.talk.duration_in_seconds }\n\n    @top_topics = @watched_talks_in_year\n      .flat_map { |wt| wt.talk.approved_topics }\n      .compact\n      .reject { |topic| topic.name.downcase.in?([\"ruby\", \"ruby on rails\"]) }\n      .tally\n      .sort_by { |_, count| -count }\n      .first(5)\n\n    @top_speakers = @watched_talks_in_year\n      .flat_map { |wt| wt.talk.speakers }\n      .compact\n      .reject { |speaker| speaker.id == @user.id }\n      .tally\n      .sort_by { |_, count| -count }\n      .first(5)\n\n    @favorite_speaker = @top_speakers.first&.first\n\n    @top_events = @watched_talks_in_year\n      .map { |wt| wt.talk.event }\n      .compact\n      .tally\n      .sort_by { |_, count| -count }\n      .first(5)\n\n    @countries_watched = @watched_talks_in_year\n      .map { |wt| wt.talk.event&.country }\n      .compact\n      .uniq\n      .sort_by(&:name)\n\n    @languages_watched = @watched_talks_in_year\n      .map { |wt| wt.talk.language }\n      .compact\n      .tally\n      .sort_by { |_, count| -count }\n      .first(5)\n      .map { |code, count| [Language.by_code(code) || code, count] }\n\n    @monthly_breakdown = @watched_talks_in_year\n      .group_by { |wt| wt.watched_at.month }\n      .transform_values(&:count)\n\n    @weekday_breakdown = @watched_talks_in_year\n      .group_by { |wt| wt.watched_at.wday }\n      .transform_values(&:count)\n\n    @most_active_month = @monthly_breakdown.max_by { |_, count| count }&.first\n    @most_active_weekday = @weekday_breakdown.max_by { |_, count| count }&.first\n\n    @talk_kinds = @watched_talks_in_year\n      .map { |wt| wt.talk.kind }\n      .compact\n      .tally\n      .sort_by { |_, count| -count }\n\n    @bookmarks_in_year = WatchListTalk\n      .joins(:watch_list)\n      .where(watch_lists: {user_id: @user.id})\n      .count\n\n    @events_attended_in_year = @user.participated_events\n      .where(start_date: year_range)\n      .includes(:series)\n      .order(start_date: :asc)\n\n    @events_as_speaker = @user.event_participations\n      .where(attended_as: [:speaker, :keynote_speaker])\n      .joins(:event)\n      .where(events: {start_date: year_range})\n      .count\n\n    @events_as_visitor = @user.event_participations\n      .where(attended_as: :visitor)\n      .joins(:event)\n      .where(events: {start_date: year_range})\n      .count\n\n    @countries_visited = @events_attended_in_year\n      .map(&:country)\n      .compact\n      .uniq\n      .sort_by(&:name)\n\n    @talks_given_in_year = @user.kept_talks\n      .includes(:event)\n      .where(date: year_range)\n      .order(date: :asc)\n\n    @total_views_on_talks = @talks_given_in_year.sum(:view_count)\n    @total_likes_on_talks = @talks_given_in_year.sum(:like_count)\n\n    regular_duration = @talks_given_in_year.where.not(video_provider: \"parent\").sum(:duration_in_seconds)\n    subtalks_duration = @talks_given_in_year\n      .where(video_provider: \"parent\")\n      .where.not(start_seconds: nil)\n      .where.not(end_seconds: nil)\n      .sum(\"end_seconds - start_seconds\")\n\n    @total_speaking_minutes = ((regular_duration + subtalks_duration) / 60.0).round\n\n    if @talks_given_in_year.any?\n      talk_ids = @talks_given_in_year.pluck(:id)\n\n      @talk_watchers_count = User\n        .joins(:watched_talks)\n        .where(watched_talks: {talk_id: talk_ids})\n        .where.not(id: @user.id)\n        .where.not(\"LOWER(users.name) IN (?)\", [\"tbd\", \"todo\", \"tba\", \"speaker tbd\", \"speaker tba\"])\n        .distinct\n        .count\n\n      @top_talk_watchers = User\n        .joins(:watched_talks)\n        .where(watched_talks: {talk_id: talk_ids})\n        .where.not(id: @user.id)\n        .where.not(\"LOWER(users.name) IN (?)\", [\"tbd\", \"todo\", \"tba\", \"speaker tbd\", \"speaker tba\"])\n        .group(\"users.id\")\n        .select(\"users.*, COUNT(DISTINCT watched_talks.talk_id) as watched_count\")\n        .order(\"watched_count DESC\")\n        .limit(3)\n    else\n      @talk_watchers_count = 0\n      @top_talk_watchers = []\n    end\n\n    all_stamps = Stamp.for(events: @events_attended_in_year)\n    event_stamps = @events_attended_in_year.flat_map { |event| Stamp.for_event(event) }\n    all_stamps = (all_stamps + event_stamps).uniq(&:code)\n\n    @country_stamps = all_stamps.select(&:has_country?)\n    @event_stamps = all_stamps.select(&:has_event?)\n    @achievement_stamps = []\n\n    if @events_as_speaker.positive? && Stamp.conference_speaker_stamp\n      @achievement_stamps << Stamp.conference_speaker_stamp\n    end\n\n    if @user.event_participations.joins(:event).where(attended_as: [:speaker, :keynote_speaker], events: {kind: :meetup, start_date: year_range}).exists? && Stamp.meetup_speaker_stamp\n      @achievement_stamps << Stamp.meetup_speaker_stamp\n    end\n\n    if @events_attended_in_year.any? && Stamp.attend_one_event_stamp\n      @achievement_stamps << Stamp.attend_one_event_stamp\n    end\n\n    @stamps_earned = (@country_stamps + @event_stamps + @achievement_stamps).uniq(&:code)\n    @stickers_earned = @events_attended_in_year.flat_map { |event| Sticker.for_event(event) }.uniq(&:code)\n\n    @event_map_markers = event_map_markers(@events_attended_in_year)\n\n    @conference_buddies = find_conference_buddies\n    @watch_twin = find_watch_twin\n    @personality = determine_personality\n\n    @speakers_discovered = @watched_talks_in_year\n      .flat_map { |wt| wt.talk.speakers }\n      .compact\n      .uniq\n      .count\n\n    @events_discovered = @watched_talks_in_year\n      .map { |wt| wt.talk.event }\n      .compact\n      .uniq\n      .count\n\n    completed_talks_count = @watched_talks_in_year.count(&:watched?)\n    @completion_rate = @total_talks_watched.positive? ? ((completed_talks_count.to_f / @total_talks_watched) * 100).round : 0\n    @longest_streak = calculate_longest_streak\n\n    @ruby_friends_met = User\n      .joins(:event_participations)\n      .where(event_participations: {event_id: @events_attended_in_year.pluck(:id)})\n      .where.not(id: @user.id)\n      .where.not(\"LOWER(users.name) IN (?)\", [\"tbd\", \"todo\", \"tba\", \"speaker tbd\", \"speaker tba\"])\n      .distinct\n      .count\n\n    @is_contributor = @user.contributor?\n    @contributor = @user.contributor\n    @has_passport = @user.ruby_passport_claimed?\n    @passports = @user.passports\n\n    @involvements_in_year = @user.event_involvements\n      .joins(:event)\n      .where(events: {start_date: year_range})\n      .includes(:event)\n    @involvements_by_role = @involvements_in_year.group_by(&:role)\n\n    @share_url = profile_wrapped_index_url(profile_slug: @user.to_param)\n\n    unless @user.wrapped_card.attached? && @user.wrapped_card_horizontal.attached?\n      GenerateWrappedScreenshotJob.perform_later(@user)\n    end\n\n    @wrapped_locals = wrapped_locals\n\n    set_wrapped_meta_tags\n\n    render layout: \"wrapped\"\n  end\n\n  def card\n    @year = YEAR\n    year_range = Date.new(@year, 1, 1)..Date.new(@year, 12, 31)\n\n    @watched_talks_in_year = @user.watched_talks.where(watched_at: year_range)\n    @total_talks_watched = @watched_talks_in_year.count\n    @total_watch_time_seconds = @watched_talks_in_year.sum(&:progress_seconds)\n    @total_watch_time_hours = (@total_watch_time_seconds / 3600.0).round(1)\n\n    @events_attended_in_year = @user.participated_events.where(start_date: year_range)\n    @talks_given_in_year = @user.kept_talks.where(date: year_range)\n    @countries_visited = @events_attended_in_year.map(&:country).compact.uniq\n\n    @top_topics = @watched_talks_in_year\n      .includes(talk: :approved_topics)\n      .flat_map { |wt| wt.talk.approved_topics }\n      .compact\n      .tally\n      .sort_by { |_, count| -count }\n      .first(3)\n\n    @personality = determine_personality\n    @share_url = profile_wrapped_index_url(profile_slug: @user.to_param)\n\n    render layout: \"wrapped\"\n  end\n\n  def toggle_visibility\n    @user.update!(wrapped_public: !@user.wrapped_public?)\n\n    @year = YEAR\n    @is_owner = true\n    year_range = Date.new(@year, 1, 1)..Date.new(@year, 12, 31)\n\n    @watched_talks_in_year = @user.watched_talks.where(watched_at: year_range)\n    @total_talks_watched = @watched_talks_in_year.count\n    @events_attended_in_year = @user.participated_events.where(start_date: year_range)\n    @talks_given_in_year = @user.kept_talks.where(date: year_range)\n    @countries_visited = @events_attended_in_year.map(&:country).compact.uniq\n    @share_url = profile_wrapped_index_url(profile_slug: @user.to_param)\n\n    respond_to do |format|\n      format.html { redirect_to profile_wrapped_index_path(profile_slug: @user.slug) }\n      format.turbo_stream { render turbo_stream: turbo_stream.replace(\"wrapped-share\", partial: \"profiles/wrapped/share\", locals: wrapped_locals) }\n    end\n  end\n\n  def og_image\n    unless @user.wrapped_card_horizontal.attached?\n      generator = User::WrappedScreenshotGenerator.new(@user, orientation: :horizontal)\n      generator.save_to_storage\n    end\n\n    if @user.wrapped_card_horizontal.attached?\n      redirect_to rails_blob_url(@user.wrapped_card_horizontal), allow_other_host: true\n    else\n      head :internal_server_error\n    end\n  end\n\n  def generate_card\n    orientation = params[:orientation]&.to_sym || :vertical\n    attachment = (orientation == :horizontal) ? @user.wrapped_card_horizontal : @user.wrapped_card\n\n    unless attachment.attached?\n      generator = User::WrappedScreenshotGenerator.new(@user, orientation: orientation)\n      generator.save_to_storage\n      attachment.reload\n    end\n\n    if attachment.attached?\n      redirect_to rails_blob_path(attachment, disposition: \"attachment\")\n    else\n      redirect_to profile_wrapped_index_path(profile_slug: @user.to_param), alert: \"Failed to generate card. Please try again.\"\n    end\n  end\n\n  private\n\n  def set_wrapped_meta_tags\n    description = \"See #{@user.name}'s #{@year} Ruby Events Wrapped!\"\n    title = \"#{@user.name}'s #{@year} Wrapped - RubyEvents.org\"\n    image_url = og_image_profile_wrapped_index_url(profile_slug: @user.to_param)\n    page_url = profile_wrapped_index_url(profile_slug: @user.to_param)\n\n    set_meta_tags(\n      title: title,\n      description: description,\n      og: {\n        title: title,\n        description: description,\n        image: image_url,\n        type: \"website\",\n        url: page_url\n      },\n      twitter: {\n        title: title,\n        description: description,\n        image: image_url,\n        card: \"summary_large_image\"\n      }\n    )\n  end\n\n  def calculate_longest_streak\n    return 0 if @watched_talks_in_year.empty?\n\n    watch_dates = @watched_talks_in_year.map { |wt| wt.watched_at.to_date }.uniq.sort\n    return 1 if watch_dates.size == 1\n\n    max_streak = 1\n    current_streak = 1\n\n    watch_dates.each_cons(2) do |prev_date, curr_date|\n      if curr_date - prev_date == 1\n        current_streak += 1\n        max_streak = [max_streak, current_streak].max\n      else\n        current_streak = 1\n      end\n    end\n\n    max_streak\n  end\n\n  def determine_personality\n    return \"Ruby Explorer\" if @top_topics.empty?\n\n    all_topic_names = @top_topics.map { |topic, _| topic.name.downcase }\n\n    personality_matches = {\n      \"Hotwire Hero\" => %w[hotwire turbo stimulus turbo-native],\n      \"Frontend Artisan\" => %w[javascript css frontend ui vue react angular viewcomponent],\n      \"Testing Guru\" => %w[testing test-driven rspec minitest capybara vcr],\n      \"Performance Optimizer\" => %w[performance optimization caching benchmarking memory profiling],\n      \"Security Champion\" => %w[security authentication authorization encryption vulnerability],\n      \"Data Architect\" => %w[postgresql database sql activerecord mysql sqlite redis elasticsearch],\n      \"API Artisan\" => %w[api graphql rest grpc json],\n      \"DevOps Pioneer\" => %w[devops deployment docker kubernetes aws heroku kamal ci/cd],\n      \"Architecture Astronaut\" => %w[architecture microservices monolith modular design-patterns solid],\n      \"Ruby Internist\" => %w[ruby-vm ruby-internals yjit garbage-collection jruby truffleruby mruby parser ast],\n      \"Concurrency Connoisseur\" => %w[concurrency async threading ractor fiber sidekiq background],\n      \"AI Adventurer\" => %w[machine-learning artificial-intelligence ai llm openai langchain],\n      \"Community Champion\" => %w[open-source community mentorship diversity inclusion],\n      \"Growth Mindset\" => %w[career-development personal-development leadership team-building mentorship],\n      \"Code Craftsperson\" => %w[refactoring code-quality clean-code debugging error-handling]\n    }\n\n    personality_matches.each do |personality, keywords|\n      if all_topic_names.any? { |topic| keywords.any? { |keyword| topic.include?(keyword) } }\n        return personality\n      end\n    end\n\n    top_topic = @top_topics.first&.first&.name&.downcase\n\n    case top_topic\n    when /rails/\n      \"Rails Enthusiast\"\n    when /developer.?experience|dx/\n      \"DX Advocate\"\n    when /web/\n      \"Web Developer\"\n    when /software/\n      \"Software Craftsperson\"\n    when /gem/\n      \"Gem Hunter\"\n    when /debug/\n      \"Bug Squasher\"\n    when /learn|education|teach/\n      \"Eternal Learner\"\n    when /startup|entrepreneur|business/\n      \"Ruby Entrepreneur\"\n    when /legacy|maintain/\n      \"Legacy Whisperer\"\n    when /mobile|ios|android/\n      \"Mobile Maverick\"\n    when /real.?time|websocket|action.?cable/\n      \"Real-Time Ranger\"\n    when /background|job|queue|sidekiq/\n      \"Background Boss\"\n    when /monolith|majestic/\n      \"Monolith Master\"\n    else\n      \"Rubyist\"\n    end\n  end\n\n  def find_conference_buddies\n    return [] if @events_attended_in_year.empty?\n\n    event_ids = @events_attended_in_year.pluck(:id)\n\n    User\n      .joins(:event_participations)\n      .where(event_participations: {event_id: event_ids})\n      .where.not(id: @user.id)\n      .where.not(\"LOWER(users.name) IN (?)\", [\"tbd\", \"todo\", \"tba\", \"speaker tbd\", \"speaker tba\"])\n      .group(\"users.id\")\n      .select(\"users.*, COUNT(event_participations.id) as shared_events_count\")\n      .order(\"shared_events_count DESC\")\n      .limit(10)\n      .map do |buddy|\n        shared_events = @events_attended_in_year.where(\n          id: buddy.event_participations.where(event_id: event_ids).pluck(:event_id)\n        )\n        OpenStruct.new(\n          user: buddy,\n          shared_count: buddy.shared_events_count,\n          shared_events: shared_events\n        )\n      end\n  end\n\n  def find_watch_twin\n    return nil if @watched_talks_in_year.empty?\n\n    talk_ids = @watched_talks_in_year.map { |wt| wt.talk_id }\n\n    twin = User\n      .joins(:watched_talks)\n      .where(watched_talks: {talk_id: talk_ids})\n      .where.not(id: @user.id)\n      .where.not(\"LOWER(users.name) IN (?)\", [\"tbd\", \"todo\", \"tba\", \"speaker tbd\", \"speaker tba\"])\n      .group(\"users.id\")\n      .select(\"users.*, COUNT(DISTINCT watched_talks.talk_id) as shared_talks_count\")\n      .order(\"shared_talks_count DESC\")\n      .first\n\n    return nil unless twin && twin.shared_talks_count >= 3\n\n    OpenStruct.new(\n      user: twin,\n      shared_count: twin.shared_talks_count,\n      percentage: ((twin.shared_talks_count.to_f / talk_ids.size) * 100).round\n    )\n  end\n\n  def check_wrapped_access\n    is_owner = @user == Current.user\n    is_admin = Current.user&.admin?\n\n    unless is_owner || is_admin || @user.wrapped_public?\n      render \"private\", layout: \"wrapped\"\n    end\n  end\n\n  def require_owner\n    unless @user == Current.user || Current.user&.admin?\n      redirect_to profile_path(@user), alert: \"You can only change your own wrapped visibility\"\n    end\n  end\n\n  def wrapped_locals\n    {\n      user: @user,\n      year: @year,\n      is_owner: @is_owner,\n      total_talks_watched: @total_talks_watched,\n      total_watch_time_hours: @total_watch_time_hours,\n      total_watch_time_seconds: @total_watch_time_seconds,\n      events_attended_in_year: @events_attended_in_year,\n      talks_given_in_year: @talks_given_in_year,\n      countries_visited: @countries_visited,\n      top_topics: @top_topics,\n      top_speakers: @top_speakers,\n      favorite_speaker: @favorite_speaker,\n      top_events: @top_events,\n      countries_watched: @countries_watched,\n      languages_watched: @languages_watched,\n      monthly_breakdown: @monthly_breakdown,\n      weekday_breakdown: @weekday_breakdown,\n      most_active_month: @most_active_month,\n      most_active_weekday: @most_active_weekday,\n      talk_kinds: @talk_kinds,\n      bookmarks_in_year: @bookmarks_in_year,\n      events_as_speaker: @events_as_speaker,\n      events_as_visitor: @events_as_visitor,\n      total_views_on_talks: @total_views_on_talks,\n      total_likes_on_talks: @total_likes_on_talks,\n      total_speaking_minutes: @total_speaking_minutes,\n      talk_watchers_count: @talk_watchers_count,\n      top_talk_watchers: @top_talk_watchers,\n      country_stamps: @country_stamps,\n      event_stamps: @event_stamps,\n      achievement_stamps: @achievement_stamps,\n      stamps_earned: @stamps_earned,\n      stickers_earned: @stickers_earned,\n      event_map_markers: @event_map_markers,\n      conference_buddies: @conference_buddies,\n      watch_twin: @watch_twin,\n      personality: @personality,\n      speakers_discovered: @speakers_discovered,\n      events_discovered: @events_discovered,\n      completion_rate: @completion_rate,\n      longest_streak: @longest_streak,\n      ruby_friends_met: @ruby_friends_met,\n      is_contributor: @is_contributor,\n      contributor: @contributor,\n      has_passport: @has_passport,\n      passports: @passports,\n      involvements_in_year: @involvements_in_year,\n      involvements_by_role: @involvements_by_role,\n      share_url: @share_url,\n      first_watched: @first_watched,\n      last_watched: @last_watched,\n      longest_watched: @longest_watched,\n      shortest_watched: @shortest_watched\n    }\n  end\nend\n"
  },
  {
    "path": "app/controllers/profiles_controller.rb",
    "content": "class ProfilesController < ApplicationController\n  skip_before_action :authenticate_user!\n  before_action :set_user, only: %i[show edit update reindex]\n  before_action :set_favorite_user, only: %i[show]\n  before_action :set_user_favorites, only: %i[show]\n  before_action :set_mutual_events, only: %i[show]\n  before_action :require_admin!, only: %i[reindex]\n\n  include Pagy::Backend\n  include RemoteModal\n  include WatchedTalks\n\n  respond_with_remote_modal only: [:edit]\n\n  # GET /profiles/:slug\n  def show\n    load_profile_data_for_show\n\n    if @user.suspicious?\n      set_meta_tags(robots: \"noindex, nofollow\")\n    else\n      set_meta_tags(@user)\n    end\n  end\n\n  # GET /profiles/:slug/edit\n  def edit\n    set_modal_options(size: :lg)\n  end\n\n  # PATCH/PUT /profiles/:slug\n  def update\n    suggestion = @user.create_suggestion_from(params: user_params, user: Current.user)\n    if suggestion.persisted?\n      redirect_to profile_path(@user), notice: suggestion.notice\n    else\n      render :edit, status: :unprocessable_entity\n    end\n  end\n\n  # POST /profiles/:slug/reindex\n  def reindex\n    Search::Backend.index(@user)\n    @user.talks.find_each { |talk| Search::Backend.index(talk) }\n\n    redirect_to profile_path(@user), notice: \"Profile reindexed successfully.\"\n  end\n\n  private\n\n  def require_admin!\n    redirect_to profile_path(@user), alert: \"Not authorized\" unless Current.user&.admin?\n  end\n\n  def load_profile_data_for_show\n    @talks = @user.kept_talks.includes(:speakers, event: :series, child_talks: :speakers).order(date: :desc)\n    @talks_by_kind = @talks.group_by(&:kind)\n    @topics = @user.topics.approved.tally.sort_by(&:last).reverse.map(&:first)\n    # Load participated events (from event_participations)\n    @events = @user.participated_events.includes(:series).distinct.in_order_of(:attended_as, EventParticipation.attended_as.keys)\n    @events_with_stickers = @events.select(&:sticker?)\n\n    event_participations = @user.event_participations.includes(:event).where(event: @events)\n    @participations = event_participations.index_by(&:event_id)\n\n    @events_by_year = @events.group_by { |event| event.start_date&.year || \"Unknown\" }\n\n    # Group events by country for the map tab\n    @countries_with_events = @events.grouped_by_country\n\n    @involved_events = @user.involved_events.includes(:series).distinct.order(start_date: :desc)\n    event_involvements = @user.event_involvements.includes(:event).where(event: @involved_events)\n    involvement_lookup = event_involvements.group_by(&:event_id)\n\n    @involvements_by_role = {}\n    @involved_events.each do |event|\n      involvements = involvement_lookup[event.id] || []\n      involvements.each do |involvement|\n        @involvements_by_role[involvement.role] ||= []\n        @involvements_by_role[involvement.role] << event\n      end\n    end\n\n    @stamps = Stamp.for_user(@user)\n    @aliases = Current.user&.admin? ? @user.aliases : []\n\n    @back_path = speakers_path\n  end\n\n  helper_method :user_kind\n  def user_kind\n    return params[:user_kind] if params[:user_kind].present? && Rails.env.development?\n    return :admin if Current.user&.admin?\n    return :owner if @user.managed_by?(Current.user)\n    return :signed_in if Current.user.present?\n\n    :anonymous\n  end\n\n  def set_user\n    @user = User.preloaded.includes(:talks).find_by_slug_or_alias(params[:slug])\n    @user = User.preloaded.includes(:talks).find_by_github_handle(params[:slug]) unless @user.present?\n\n    if @user.blank?\n      redirect_to speakers_path, status: :moved_permanently, notice: \"User not found\"\n      return\n    end\n\n    if @user.canonical.present?\n      redirect_to profile_path(@user.canonical), status: :moved_permanently\n      return\n    end\n\n    if params[:slug] != @user.to_param\n      redirect_to profile_path(@user), status: :moved_permanently\n    end\n  end\n\n  def user_params\n    params.require(:user).permit(\n      :github_handle,\n      :twitter,\n      :bsky,\n      :linkedin,\n      :mastodon,\n      :bio,\n      :website,\n      :location,\n      :speakerdeck,\n      :pronouns_type,\n      :pronouns,\n      :slug\n    )\n  end\n\n  def set_favorite_user\n    @favorite_user = Current.user ? @user.favorited_by.find_or_initialize_by(user: Current.user) : nil\n  end\n\n  def set_mutual_events\n    @mutual_events = if Current.user\n      @user.participated_events.where(id: Current.user.participated_events).distinct.order(start_date: :desc)\n    else\n      Event.none\n    end\n  end\n\n  def set_user_favorites\n    return unless Current.user\n\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\nend\n"
  },
  {
    "path": "app/controllers/recommendations_controller.rb",
    "content": "class RecommendationsController < ApplicationController\n  include WatchedTalks\n\n  def index\n    @recommended_talks = Current.user.talk_recommender.talks(limit: 64) if Current.user\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\nend\n"
  },
  {
    "path": "app/controllers/sessions/omniauth_controller.rb",
    "content": "class Sessions::OmniauthController < ApplicationController\n  skip_before_action :verify_request_for_forgery_protection\n  skip_before_action :authenticate_user!\n\n  def create\n    # This needs to be refactored to be more robust when we have more states\n    if state.present?\n      key, value = state.split(\":\")\n      connect_id = (key == \"connect_id\") ? value : nil\n      connect_to = (key == \"connect_to\") ? value : nil\n    end\n\n    connected_account = ConnectedAccount.find_or_initialize_by(provider: omniauth.provider, username: omniauth_username&.downcase)\n\n    if connected_account.new_record?\n      @user = User.find_by_github_handle(omniauth_username)\n      @user ||= initialize_user\n      connected_account.user = @user\n      connected_account.access_token = token\n      connected_account.username = omniauth_username\n      connected_account.save!\n    else\n      @user = connected_account.user\n    end\n\n    if @user.previously_new_record?\n      @user.profiles.enhance_with_github_later\n    end\n\n    # If the user connected through a passport connection URL, we need to create a connected account for it\n    if connect_id.present?\n      @user.connected_accounts.find_or_create_by!(provider: \"passport\", uid: connect_id)\n    end\n\n    if connect_to.present?\n      # TODO: Create connection\n      # new_friend = User.find_by(connect_id: connect_to)\n    end\n\n    if @user.persisted?\n      @user.update(name: omniauth_params[:name]) if omniauth_params[:name].present?\n      @user.watched_talk_seeder.seed_development_data if Rails.env.development?\n\n      sign_in @user\n\n      if connect_id.present?\n        redirect_to profile_path(@user), notice: \"🙌 Congrats you claimed your passport\"\n      else\n        redirect_to redirect_to_path, notice: \"Signed in successfully\"\n      end\n    else\n      redirect_to new_session_path, alert: \"Authentication failed\"\n    end\n  end\n\n  def failure\n    redirect_to new_session_path, alert: params[:message]\n  end\n\n  private\n\n  def omniauth_username\n    omniauth_params[:username]\n  end\n\n  def initialize_user\n    User.new(github_handle: omniauth_username) do |user|\n      user.password = SecureRandom.base58\n      user.name = omniauth_params[:name]\n      user.slug = omniauth_params[:username]\n      user.email = omniauth_params[:email]\n      user.verified = true\n    end\n  end\n\n  def email\n    if omniauth.provider == \"developer\"\n      \"#{username}@rubyevents.org\"\n    else\n      github_email\n    end\n  end\n\n  def github_email\n    @github_email ||= omniauth.info.email || fetch_github_email(token)\n  end\n\n  def token\n    @token ||= omniauth.credentials&.token\n  end\n\n  def redirect_to_path\n    query_params[\"redirect_to\"].presence || root_path\n  end\n\n  def username\n    omniauth.info.try(:nickname) || omniauth.info.try(:github_handle)\n  end\n\n  def omniauth_params\n    {\n      provider: omniauth.provider,\n      uid: omniauth.uid,\n      username: username,\n      name: omniauth.info.try(:name),\n      email: email\n    }.compact_blank\n  end\n\n  def omniauth\n    request.env[\"omniauth.auth\"]\n  end\n\n  def query_params\n    request.env[\"omniauth.params\"]\n  end\n\n  def state\n    @state ||= query_params.dig(\"state\")\n  end\n\n  def fetch_github_email(oauth_token)\n    return unless oauth_token\n    response = GitHub::UserClient.new(token: oauth_token).emails\n\n    emails = response.parsed_body\n    primary_email = emails.find { |email| email.primary && email.verified }\n    primary_email&.email\n  rescue => e\n    # had the case of a user where this method would fail this will need to be investigated in details\n    Rails.error.report(e)\n    nil\n  end\nend\n"
  },
  {
    "path": "app/controllers/sessions_controller.rb",
    "content": "class SessionsController < ApplicationController\n  include RemoteModal\n\n  respond_with_remote_modal only: [:new]\n\n  skip_before_action :authenticate_user!, only: %i[new create]\n\n  def new\n    @user = User.new\n    # Add connect_id or connect_to to state if present\n    @state = \"connect_id:#{params[:connect_id]}\" if params[:connect_id].present?\n    @state = \"connect_to:#{params[:connect_to]}\" if params[:connect_to].present?\n  end\n\n  def create\n    user = User.authenticate_by(params.permit(:email, :password))\n\n    if user\n      sign_in user\n      redirect_to root_path, notice: \"Signed in successfully\"\n    else\n      redirect_to new_session_path(email_hint: params[:email]), alert: \"That email or password is incorrect\"\n    end\n  end\n\n  def destroy\n    Current.user.sessions.destroy_by(id: params[:id])\n    redirect_to root_path, notice: \"That session has been logged out\"\n  end\nend\n"
  },
  {
    "path": "app/controllers/settings_controller.rb",
    "content": "class SettingsController < ApplicationController\n  before_action :authenticate_user!\n\n  def show\n  end\n\n  def update\n    if Current.user.update(settings_params)\n      redirect_to settings_path, notice: \"Settings saved successfully.\"\n    else\n      render :show, status: :unprocessable_entity\n    end\n  end\n\n  private\n\n  def settings_params\n    params.require(:user).permit(:feedback_enabled, :wrapped_public, :searchable)\n  end\nend\n"
  },
  {
    "path": "app/controllers/sitemaps_controller.rb",
    "content": "class SitemapsController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  def show\n    render xml: generate_sitemap_string, content_type: \"application/xml\"\n  end\n\n  private\n\n  def generate_sitemap_string\n    Rails.cache.fetch([\"sitemap\", Talk.all, Event.all, User.speakers, Topic.approved], expires_in: 24.hours) do\n      adapter = SitemapStringAdapter.new\n\n      SitemapGenerator::Sitemap.default_host = \"https://www.rubyevents.org\"\n\n      SitemapGenerator::Sitemap.create(adapter: adapter) do\n        add talks_path, priority: 0.9, changefreq: \"weekly\"\n\n        Talk.pluck(:slug, :updated_at).each do |talk_slug, updated_at|\n          add talk_path(talk_slug), priority: 0.9, lastmod: updated_at\n        end\n\n        add speakers_path, priority: 0.7, changefreq: \"weekly\"\n\n        User.speakers.canonical.pluck(:slug, :updated_at).each do |speaker_slug, updated_at|\n          add profile_path(speaker_slug), priority: 0.9, lastmod: updated_at\n        end\n\n        add events_path, priority: 0.7, changefreq: \"weekly\"\n\n        Event.canonical.pluck(:slug, :updated_at) do |event_slug, updated_at|\n          add event_path(event_slug), priority: 0.9, lastmod: updated_at\n        end\n\n        add topics_path, priority: 0.7, changefreq: \"weekly\"\n\n        Topic.approved.pluck(:slug, :updated_at).each do |topic_slug, updated_at|\n          add topic_path(topic_slug), priority: 0.9, lastmod: updated_at\n        end\n      end\n      adapter.sitemap_content\n    end\n  end\n\n  class SitemapStringAdapter\n    attr_reader :sitemap_content\n\n    def write(location, raw_data)\n      @sitemap_content ||= \"\"\n      @sitemap_content << raw_data\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/speakers_controller.rb",
    "content": "class SpeakersController < ApplicationController\n  skip_before_action :authenticate_user!\n  include Pagy::Backend\n\n  # GET /speakers\n  def index\n    @speakers = User.speakers.order(\"LOWER(users.name)\")\n    @speakers = @speakers.where(\"lower(users.name) LIKE ?\", \"#{params[:letter].downcase}%\") if params[:letter].present?\n    @speakers = @speakers.ft_search(params[:s]).with_snippets.ranked if params[:s].present?\n    @pagy, @speakers = pagy(@speakers, gearbox_extra: true, gearbox_limit: [200, 300, 600], page: params[:page])\n\n    respond_to do |format|\n      format.html\n      format.turbo_stream\n      format.json\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/sponsors/missing_controller.rb",
    "content": "class Sponsors::MissingController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  # GET /sponsors/missing\n  def index\n    @back_path = organizations_path\n    @events_without_sponsors = Event.not_meetup\n      .left_joins(:sponsors)\n      .where(sponsors: {id: nil})\n      .past\n      .includes(:series)\n      .order(start_date: :desc)\n    @events_by_year = @events_without_sponsors.group_by { |event| event.start_date&.year || \"Unknown\" }\n  end\nend\n"
  },
  {
    "path": "app/controllers/spotlight/events_controller.rb",
    "content": "class Spotlight::EventsController < ApplicationController\n  include SpotlightSearch\n\n  LIMIT = 15\n\n  disable_analytics\n  skip_before_action :authenticate_user!\n\n  def index\n    if search_query.present?\n      @events, @total_count = search_backend_class.search_events(search_query, limit: LIMIT)\n    else\n      @events = Event.includes(:series).canonical.past.order(start_date: :desc).limit(LIMIT)\n      @total_count = nil\n    end\n\n    respond_to do |format|\n      format.turbo_stream\n    end\n  end\n\n  private\n\n  helper_method :search_query\n  def search_query\n    params[:s]\n  end\n\n  helper_method :total_count\n  attr_reader :total_count\nend\n"
  },
  {
    "path": "app/controllers/spotlight/kinds_controller.rb",
    "content": "class Spotlight::KindsController < ApplicationController\n  include SpotlightSearch\n\n  LIMIT = 10\n\n  disable_analytics\n  skip_before_action :authenticate_user!\n\n  def index\n    if search_query.present?\n      @kinds, @total_count = search_backend.search_kinds(search_query, limit: LIMIT)\n    else\n      @kinds = []\n      @total_count = 0\n    end\n\n    respond_to do |format|\n      format.turbo_stream\n    end\n  end\n\n  private\n\n  def search_backend\n    @search_backend ||= Search::Backend.resolve(params[:search_backend])\n  end\n\n  helper_method :search_query\n  def search_query\n    params[:s].presence\n  end\n\n  helper_method :total_count\n  attr_reader :total_count\nend\n"
  },
  {
    "path": "app/controllers/spotlight/languages_controller.rb",
    "content": "class Spotlight::LanguagesController < ApplicationController\n  include SpotlightSearch\n\n  LIMIT = 10\n\n  disable_analytics\n  skip_before_action :authenticate_user!\n\n  def index\n    if search_query.present?\n      @languages, @total_count = search_backend_class.search_languages(search_query, limit: LIMIT)\n    else\n      @languages = []\n      @total_count = nil\n    end\n\n    respond_to do |format|\n      format.turbo_stream\n    end\n  end\n\n  private\n\n  helper_method :search_query\n  def search_query\n    params[:s].presence\n  end\n\n  helper_method :total_count\n  attr_reader :total_count\nend\n"
  },
  {
    "path": "app/controllers/spotlight/locations_controller.rb",
    "content": "class Spotlight::LocationsController < ApplicationController\n  include SpotlightSearch\n\n  LIMIT = 10\n\n  disable_analytics\n  skip_before_action :authenticate_user!\n\n  def index\n    if search_query.present?\n      @locations, @total_count = search_backend_class.search_locations(search_query, limit: LIMIT)\n\n      if @locations.empty?\n        @geocoded_locations = geocode_query(search_query)\n      end\n    else\n      @locations = []\n      @total_count = nil\n    end\n\n    respond_to do |format|\n      format.turbo_stream\n    end\n  end\n\n  private\n\n  def geocode_query(query)\n    results = Geocoder.search(query).first(5)\n    return [] if results.empty?\n\n    results.filter_map do |result|\n      next unless result.latitude && result.longitude\n\n      {\n        name: result.city || result.state || result.country || query,\n        latitude: result.latitude,\n        longitude: result.longitude,\n        country: result.country,\n        type: result.city.present? ? :city : :region\n      }\n    end\n  end\n\n  helper_method :search_query\n  def search_query\n    params[:s].presence\n  end\n\n  helper_method :total_count\n  attr_reader :total_count\nend\n"
  },
  {
    "path": "app/controllers/spotlight/organizations_controller.rb",
    "content": "class Spotlight::OrganizationsController < ApplicationController\n  include SpotlightSearch\n\n  LIMIT = 8\n\n  disable_analytics\n  skip_before_action :authenticate_user!\n\n  def index\n    if search_query.present?\n      @organizations, @total_count = search_backend_class.search_organizations(search_query, limit: LIMIT)\n    else\n      @organizations = Organization.joins(:sponsors).distinct.order(name: :asc).limit(LIMIT)\n      @total_count = nil\n    end\n\n    respond_to do |format|\n      format.turbo_stream\n    end\n  end\n\n  private\n\n  helper_method :search_query\n  def search_query\n    params[:s].presence\n  end\n\n  helper_method :total_count\n  attr_reader :total_count\nend\n"
  },
  {
    "path": "app/controllers/spotlight/series_controller.rb",
    "content": "class Spotlight::SeriesController < ApplicationController\n  include SpotlightSearch\n\n  LIMIT = 8\n\n  disable_analytics\n  skip_before_action :authenticate_user!\n\n  def index\n    if search_query.present?\n      @series, @total_count = search_backend_class.search_series(search_query, limit: LIMIT)\n    else\n      @series = EventSeries.joins(:events).distinct.order(name: :asc).limit(LIMIT)\n      @total_count = nil\n    end\n\n    respond_to do |format|\n      format.turbo_stream\n    end\n  end\n\n  private\n\n  helper_method :search_query\n  def search_query\n    params[:s].presence\n  end\n\n  helper_method :total_count\n  attr_reader :total_count\nend\n"
  },
  {
    "path": "app/controllers/spotlight/speakers_controller.rb",
    "content": "class Spotlight::SpeakersController < ApplicationController\n  include SpotlightSearch\n\n  LIMIT = 15\n\n  disable_analytics\n  skip_before_action :authenticate_user!\n\n  def index\n    if search_query.present?\n      @speakers, @total_count = search_backend_class.search_speakers(search_query, limit: LIMIT)\n    else\n      @speakers = User.speakers.canonical\n        .where.not(\"LOWER(name) IN (?)\", %w[todo tbd tba])\n        .order(talks_count: :desc)\n        .limit(LIMIT)\n      @total_count = nil\n    end\n\n    respond_to do |format|\n      format.turbo_stream\n    end\n  end\n\n  private\n\n  helper_method :search_query\n  def search_query\n    params[:s].presence\n  end\n\n  helper_method :total_count\n  attr_reader :total_count\nend\n"
  },
  {
    "path": "app/controllers/spotlight/talks_controller.rb",
    "content": "class Spotlight::TalksController < ApplicationController\n  include SpotlightSearch\n\n  LIMIT = 10\n\n  disable_analytics\n  skip_before_action :authenticate_user!\n\n  def index\n    if search_query.present?\n      @talks, @total_count = search_backend_class.search_talks(search_query, limit: LIMIT)\n    else\n      @talks = Talk.watchable.includes(:speakers, event: :series).order(date: :desc).limit(LIMIT)\n      @total_count = nil\n    end\n\n    respond_to do |format|\n      format.turbo_stream do\n        response.headers[\"X-Search-Backend\"] = search_backend.to_s if Rails.env.development? && search_backend\n      end\n    end\n  end\n\n  private\n\n  helper_method :search_query\n  def search_query\n    params[:s]\n  end\n\n  helper_method :total_count\n  attr_reader :total_count\nend\n"
  },
  {
    "path": "app/controllers/spotlight/topics_controller.rb",
    "content": "class Spotlight::TopicsController < ApplicationController\n  include SpotlightSearch\n\n  LIMIT = 10\n\n  disable_analytics\n  skip_before_action :authenticate_user!\n\n  def index\n    if search_query.present?\n      @topics, @total_count = search_backend_class.search_topics(search_query, limit: LIMIT)\n    else\n      @topics = Topic.approved.canonical.with_talks.order(talks_count: :desc).limit(LIMIT)\n      @total_count = nil\n    end\n\n    respond_to do |format|\n      format.turbo_stream\n    end\n  end\n\n  private\n\n  helper_method :search_query\n  def search_query\n    params[:s].presence\n  end\n\n  helper_method :total_count\n  attr_reader :total_count\nend\n"
  },
  {
    "path": "app/controllers/stamps_controller.rb",
    "content": "class StampsController < ApplicationController\n  skip_before_action :authenticate_user!, only: [:index]\n\n  def index\n    @stamps = Stamp.all\n    @event_stamps = Stamp.event_stamps.sort_by(&:name)\n    @stamps_by_continent = Stamp.grouped_by_continent\n    @missing_stamp_countries = Stamp.missing_for_events\n  end\nend\n"
  },
  {
    "path": "app/controllers/states/base_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass States::BaseController < ApplicationController\n  skip_before_action :authenticate_user!\n\n  before_action :set_state\n\n  private\n\n  def set_state\n    @country = Country.find_by(country_code: params[:state_alpha2].upcase)\n    redirect_to(countries_path) and return unless @country.present?\n\n    @state = State.find(country: @country, term: params[:state_slug])\n    redirect_to(country_path(@country)) and return unless @state.present?\n  end\nend\n"
  },
  {
    "path": "app/controllers/states/cities_controller.rb",
    "content": "# frozen_string_literal: true\n\nclass States::CitiesController < States::BaseController\n  def index\n    @cities = @state.cities\n    @sort = params[:sort].presence || \"events\"\n\n    @cities = case @sort\n    when \"name\"\n      @cities.sort_by(&:name)\n    else\n      @cities.sort_by { |c| -c.events_count }\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/states_controller.rb",
    "content": "class StatesController < ApplicationController\n  include EventMapMarkers\n  include GeoMapLayers\n\n  skip_before_action :authenticate_user!, only: %i[index country_index show]\n\n  def index\n    @countries_with_states = State::SUPPORTED_COUNTRIES.map do |code|\n      Country.find_by(country_code: code)\n    end.compact\n  end\n\n  def country_index\n    @country = Country.find_by(country_code: params[:alpha2].upcase)\n\n    if @country.blank?\n      redirect_to states_path\n      return\n    end\n\n    @states = @country.states\n  end\n\n  def show\n    @country = Country.find_by(country_code: params[:state_alpha2].upcase)\n\n    if @country.blank?\n      redirect_to states_path\n      return\n    end\n\n    @state = State.find(country: @country, term: params[:state_slug])\n\n    if @state.blank?\n      redirect_to country_states_path(alpha2: @country.code)\n      return\n    end\n\n    @continent = @country.continent\n\n    @events = @state.events.includes(:series).order(start_date: :desc)\n    @cities = @state.cities.order(:name)\n\n    @users = @state.users\n    @stamps = @state.stamps\n\n    @country_events = Event.includes(:series)\n      .where(country_code: @country.alpha2)\n      .where.not(state_code: [@state.code, @state.name])\n      .upcoming\n      .limit(8)\n\n    continent_country_codes = @continent&.countries&.map(&:alpha2) || []\n    @continent_events = Event.includes(:series)\n      .where(country_code: continent_country_codes - [@country.alpha2])\n      .upcoming\n      .limit(8)\n\n    @location = @state\n    @event_map_markers = event_map_markers(@events)\n\n    upcoming_events = @events.upcoming.to_a\n\n    @geo_layers = build_sidebar_geo_layers(upcoming_events)\n  end\n\n  private\n\n  def filter_events_by_time(events)\n    events.select(&:upcoming?)\n  end\nend\n"
  },
  {
    "path": "app/controllers/talks/recommendations_controller.rb",
    "content": "class Talks::RecommendationsController < ApplicationController\n  include WatchedTalks\n\n  skip_before_action :authenticate_user!\n  before_action :set_talk, only: %i[index]\n\n  def index\n    redirect_to talk_path(@talk) unless turbo_frame_request?\n    @talks = @talk&.related_talks || []\n    fresh_when(@talks)\n  end\n\n  private\n\n  def set_talk\n    @talk = Talk.find_by(slug: params[:talk_slug])\n  end\nend\n"
  },
  {
    "path": "app/controllers/talks/slides_controller.rb",
    "content": "class Talks::SlidesController < ApplicationController\n  include Turbo::ForceResponse\n\n  force_frame_response\n\n  skip_before_action :authenticate_user!\n\n  def show\n    @talk = Talk.find_by(slug: params[:talk_slug])\n  end\nend\n"
  },
  {
    "path": "app/controllers/talks/watched_talks_controller.rb",
    "content": "class Talks::WatchedTalksController < ApplicationController\n  include ActionView::RecordIdentifier\n  include WatchedTalks\n  include RemoteModal\n\n  respond_with_remote_modal only: [:new]\n\n  before_action :set_talk\n  after_action :broadcast_update_to_event_talks, only: [:create, :destroy, :update]\n\n  def new\n    @watched_talk = @talk.watched_talks.find_or_initialize_by(user: Current.user)\n    set_modal_options(size: :lg)\n  end\n\n  def create\n    @watched_talk = @talk.watched_talks.find_or_initialize_by(user: Current.user)\n    @watched_talk.assign_attributes(watched_talk_params.merge(watched: true))\n    @watched_talk.save!\n\n    respond_to do |format|\n      format.html { redirect_back fallback_location: @talk }\n      format.turbo_stream\n    end\n  end\n\n  def destroy\n    @talk.unmark_as_watched!\n\n    respond_to do |format|\n      format.html { redirect_back fallback_location: @talk }\n      format.turbo_stream\n    end\n  end\n\n  def toggle_attendance\n    @watched_talk = @talk.watched_talks.find_by(user: Current.user)\n    @watched_online = false\n\n    if @watched_talk&.watched_on == \"in_person\"\n      @watched_talk.destroy!\n      @attended = false\n    else\n      @watched_talk&.destroy!\n\n      @talk.watched_talks.create!(\n        user: Current.user,\n        watched: true,\n        watched_on: \"in_person\",\n        watched_at: @talk.date\n      )\n\n      @attended = true\n    end\n\n    respond_to do |format|\n      format.html { redirect_back fallback_location: event_path(@talk.event) }\n      format.turbo_stream\n    end\n  end\n\n  def toggle_online\n    @watched_talk = @talk.watched_talks.find_by(user: Current.user)\n\n    if @watched_talk.present? && @watched_talk.watched_on != \"in_person\"\n      @watched_talk.destroy!\n      @attended = false\n      @watched_online = false\n    else\n      @watched_talk&.destroy!\n\n      @talk.watched_talks.create!(\n        user: Current.user,\n        watched: true,\n        watched_on: \"rubyevents\",\n        watched_at: Time.current\n      )\n\n      @attended = false\n      @watched_online = true\n    end\n\n    respond_to do |format|\n      format.html { redirect_back fallback_location: event_path(@talk.event) }\n      format.turbo_stream { render :toggle_attendance }\n    end\n  end\n\n  def update\n    @watched_talk = @talk.watched_talks.find_or_create_by!(user: Current.user)\n    @auto_marked = false\n\n    updates = watched_talk_params\n    is_feedback_update = updates.keys.any? { |k| k.in?(%w[feeling experience_level content_freshness] + WatchedTalk::FEEDBACK_QUESTIONS.keys.map(&:to_s)) }\n    is_watched_on_update = updates.key?(:watched_on)\n\n    if is_feedback_update\n      updates = updates.merge(watched: true, feedback_shared_at: Time.current)\n    end\n\n    if !@watched_talk.watched? && should_auto_mark?(updates[:progress_seconds])\n      updates = updates.merge(watched: true, watched_on: \"rubyevents\")\n      @auto_marked = true\n    end\n\n    @watched_talk.update!(updates)\n    @form_open = is_feedback_update\n    @should_stream = @auto_marked || is_feedback_update || is_watched_on_update\n\n    respond_to do |format|\n      format.html { redirect_back fallback_location: @talk }\n      format.turbo_stream do\n        if @should_stream\n          render :update\n        else\n          head :no_content\n        end\n      end\n    end\n  end\n\n  private\n\n  def watched_talk_params\n    params.fetch(:watched_talk, {}).permit(\n      :progress_seconds,\n      :watched_on,\n      :watched_at,\n      :feeling,\n      :experience_level,\n      :content_freshness,\n      *WatchedTalk::FEEDBACK_QUESTIONS.keys\n    )\n  end\n\n  def set_talk\n    @talk = Talk.includes(event: :series).find_by(slug: params[:talk_slug])\n  end\n\n  def should_auto_mark?(progress_seconds)\n    return false unless progress_seconds.present?\n    return false unless @talk.duration_in_seconds.to_i > 0\n\n    progress_percentage = (progress_seconds.to_f / @talk.duration_in_seconds) * 100\n    progress_percentage >= 90\n  end\n\n  def broadcast_update_to_event_talks\n    Turbo::StreamsChannel.broadcast_replace_to [@talk.event, :talks],\n      target: dom_id(@talk, :card_horizontal),\n      partial: \"talks/card_horizontal\",\n      method: :replace,\n      locals: {compact: true,\n               talk: @talk,\n               current_talk: @talk,\n               turbo_frame: \"talk\",\n               user_watched_talks: user_watched_talks}\n  end\nend\n"
  },
  {
    "path": "app/controllers/talks_controller.rb",
    "content": "class TalksController < ApplicationController\n  include FavoriteUsers\n  include RemoteModal\n  include Pagy::Backend\n  include WatchedTalks\n\n  skip_before_action :authenticate_user!\n\n  respond_with_remote_modal only: [:edit]\n\n  before_action :set_talk, only: %i[show edit update]\n  before_action :set_favorite_users, only: %i[show]\n  before_action :set_user_favorites, only: %i[index show]\n\n  # GET /talks\n  def index\n    @pagy, @talks = search_backend.search_talks_with_pagy(\n      params[:s],\n      pagy_backend: self,\n      **search_options\n    )\n  end\n\n  # GET /talks/1\n  def show\n    set_meta_tags(@talk)\n  end\n\n  # GET /talks/1/edit\n  def edit\n    set_modal_options(size: :lg)\n  end\n\n  # PATCH/PUT /talks/1\n  def update\n    suggestion = @talk.create_suggestion_from(params: talk_params, user: Current.user)\n    if suggestion.persisted?\n      redirect_to @talk, notice: suggestion.notice\n    else\n      render :edit, status: :unprocessable_entity\n    end\n  end\n\n  private\n\n  def search_backend\n    @search_backend ||= Search::Backend.resolve(params[:search_backend])\n  end\n\n  def search_options\n    {\n      per_page: params[:limit]&.to_i || 20,\n      page: params[:page]&.to_i || 1,\n      sort: sort_key,\n      topic_slug: params[:topic],\n      event_slug: params[:event],\n      speaker_slug: params[:speaker],\n      kind: talk_kind,\n      language: params[:language],\n      created_after: created_after,\n      status: params[:status],\n      include_unwatchable: params[:status] == \"all\"\n    }.compact_blank\n  end\n\n  def sort_key\n    if params[:s].present? && !explicit_ordering_requested?\n      \"relevance\"\n    else\n      params[:order_by].presence || \"date_desc\"\n    end\n  end\n\n  helper_method :order_by_key\n  def order_by_key\n    if params[:s].present? && !explicit_ordering_requested?\n      return \"ranked\"\n    end\n\n    params[:order_by].presence || \"date_desc\"\n  end\n\n  helper_method :filtered_search?\n  def filtered_search?\n    params[:s].present?\n  end\n\n  def explicit_ordering_requested?\n    params[:order_by].present? && params[:order_by] != \"ranked\"\n  end\n\n  def created_after\n    Date.parse(params[:created_after]) if params[:created_after].present?\n  rescue ArgumentError\n    nil\n  end\n\n  def talk_kind\n    @talk_kind ||= params[:kind].presence_in(Talk.kinds.keys)\n  end\n\n  # Use callbacks to share common setup or constraints between actions.\n  def set_talk\n    @talk = Talk.includes(:approved_topics, :speakers, event: :series, watched_talks: :user).find_by(slug: params[:slug])\n    @talk ||= Talk.find_by_slug_or_alias(params[:slug])\n\n    return redirect_to talks_path, status: :moved_permanently if @talk.blank?\n\n    return redirect_to talk_path(@talk), status: :moved_permanently if @talk.slug != params[:slug]\n    @speakers = @talk.speakers.preloaded\n  end\n\n  # Only allow a list of trusted parameters through.\n  def talk_params\n    params.require(:talk).permit(:title, :description, :summarized_using_ai, :summary, :date, :slides_url)\n  end\n\n  helper_method :search_params\n  def search_params\n    params.permit(:s, :topic, :event, :speaker, :kind, :created_after, :all, :order_by, :status, :language)\n  end\n\n  def set_user_favorites\n    return unless Current.user\n\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\nend\n"
  },
  {
    "path": "app/controllers/templates_controller.rb",
    "content": "class TemplatesController < ApplicationController\n  include Turbo::ForceResponse\n\n  skip_before_action :authenticate_user!\n  force_frame_response only: [:new_child, :delete_child]\n  force_stream_response only: [:speakers_search]\n\n  def new\n    @talk = Template.new\n  end\n\n  def create\n    @talk = Template.new(talk_params)\n    if @talk.valid?\n      @yaml = @talk.to_yaml\n      render :new\n    else\n      render :new, status: :unprocessable_entity\n    end\n  end\n\n  def new_child\n    @index = Time.now.to_i\n  end\n\n  def delete_child\n  end\n\n  def speakers_search\n    @speakers = User.speakers.canonical\n    @speakers = @speakers.ft_search(search_query) if search_query\n    @speakers = @speakers.limit(100)\n  end\n\n  def speakers_search_chips\n    @speakers = params[:combobox_values].split(\",\").map do |value|\n      User.speakers.find_by(id: value) || OpenStruct.new(to_combobox_display: value, id: value)\n    end\n    render turbo_stream: helpers.combobox_selection_chips_for(@speakers)\n  end\n\n  private\n\n  helper_method :search_query\n\n  def search_query\n    params[:q].presence\n  end\n\n  def talk_params\n    params.require(:template).permit(\n      :title, :raw_title, :description, :event_name, :date, :published_at, :announced_at,\n      :video_provider, :video_id, :language, :track, :slides_url,\n      :thumbnail_xs, :thumbnail_sm, :thumbnail_md, :thumbnail_lg,\n      :external_player, :external_player_url, :start_cue, :end_cue,\n      :speakers,\n      children_attributes: [\n        :title, :event_name, :date, :description, :video_id, :video_provider, :slides_url,\n        :published_at, :speakers, :start_cue, :end_cue\n      ]\n    )\n  end\nend\n"
  },
  {
    "path": "app/controllers/todos_controller.rb",
    "content": "class TodosController < ApplicationController\n  include Pagy::Backend\n\n  skip_before_action :authenticate_user!\n\n  def index\n    @view = params[:view].presence || \"by_type\"\n    @todos = Todo.all\n\n    case @view\n    when \"by_type\"\n      @todos_by_type = group_by_type(@todos)\n      @pagy, @todos_by_type = pagy_array(@todos_by_type, limit: 25)\n    else\n      @series_with_todos = group_by_series(@todos)\n      @series_with_todos = @series_with_todos.sort_by do |series_data|\n        [-series_data[:total_count], series_data[:series]&.name || \"zzz\"]\n      end\n      @pagy, @series_with_todos = pagy_array(@series_with_todos, limit: 25)\n    end\n  end\n\n  private\n\n  def group_by_type(matches)\n    grouped = matches.group_by(&:normalized_content)\n\n    grouped.map do |normalized_content, type_matches|\n      {\n        normalized_content: normalized_content.presence || \"TODO\",\n        example_content: type_matches.first.content,\n        matches: type_matches.sort_by(&:file),\n        count: type_matches.size\n      }\n    end.sort_by { |t| -t[:count] }\n  end\n\n  def group_by_series(todos)\n    grouped = todos.group_by(&:series_slug)\n\n    grouped.map do |series_slug, series_todos|\n      series = Static::EventSeries.find_by_slug(series_slug)\n\n      events = series_todos.group_by(&:event_slug)\n\n      events_data = events.map do |event_slug, event_todos|\n        event = event_slug ? Static::Event.find_by_slug(event_slug) : nil\n        files = event_todos.group_by(&:file)\n\n        {\n          event_slug: event_slug,\n          event: event,\n          files: files,\n          total_count: event_todos.size\n        }\n      end.sort_by do |e|\n        [\n          e[:event]&.end_date ? 0 : 1,\n          e[:event]&.end_date ? -e[:event].end_date.to_time.to_i : 0\n        ]\n      end\n\n      {\n        series_slug: series_slug,\n        series: series,\n        events: events_data,\n        total_count: series_todos.size\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/topics_controller.rb",
    "content": "class TopicsController < ApplicationController\n  include Pagy::Backend\n  include WatchedTalks\n\n  skip_before_action :authenticate_user!\n  before_action :set_user_favorites, only: %i[show]\n\n  def index\n    @topics = Topic.approved.with_talks.includes(:topic_gems).order(name: :asc)\n    @topics = @topics.where(\"lower(name) LIKE ?\", \"#{params[:letter].downcase}%\") if params[:letter].present?\n    @pagy, @topics = pagy(@topics, limit: 100, page: page_number)\n  end\n\n  def show\n    @topic = Topic.find_by(slug: params[:slug])\n    return redirect_to(root_path, status: :moved_permanently) unless @topic\n\n    @pagy, @talks = pagy_countless(\n      @topic.talks.includes(:speakers, event: :series, child_talks: :speakers).order(date: :desc),\n      gearbox_extra: true,\n      gearbox_limit: [12, 24, 48, 96],\n      overflow: :empty_page,\n      page: page_number\n    )\n    set_meta_tags(@topic)\n  end\n\n  def set_user_favorites\n    return unless Current.user\n\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\n\n  private\n\n  def page_number\n    [params[:page]&.to_i, 1].compact.max\n  end\nend\n"
  },
  {
    "path": "app/controllers/watch_list_talks_controller.rb",
    "content": "class WatchListTalksController < ApplicationController\n  before_action :authenticate_user!\n  before_action :set_watch_list\n\n  def create\n    @talk = Talk.find(params[:talk_id])\n    @watch_list.talks << @talk\n    redirect_back fallback_location: @watch_list\n  end\n\n  def destroy\n    @talk = @watch_list.talks.find(params[:id])\n    WatchListTalk.find_by(talk_id: @talk.id, watch_list_id: @watch_list.id).destroy\n    redirect_back fallback_location: @watch_list\n  end\n\n  private\n\n  def set_watch_list\n    @watch_list = Current.user.watch_lists.find(params[:watch_list_id])\n  end\nend\n"
  },
  {
    "path": "app/controllers/watch_lists_controller.rb",
    "content": "class WatchListsController < ApplicationController\n  include WatchedTalks\n\n  before_action :authenticate_user!\n  before_action :set_watch_list, only: [:show, :edit, :update, :destroy]\n\n  def index\n    @watch_lists = Current.user.watch_lists\n    @watch_list = Current.user.default_watch_list\n  end\n\n  def show\n  end\n\n  def new\n    @watch_list = Current.user.watch_lists.new\n  end\n\n  def create\n    @watch_list = Current.user.watch_lists.new(watch_list_params)\n    if @watch_list.save\n      redirect_to @watch_list, notice: \"WatchList was successfully created.\"\n    else\n      render :new\n    end\n  end\n\n  def edit\n  end\n\n  def update\n    if @watch_list.update(watch_list_params)\n      redirect_to @watch_list, notice: \"WatchList was successfully updated.\"\n    else\n      render :edit\n    end\n  end\n\n  def destroy\n    @watch_list.destroy\n    redirect_to watch_lists_url, notice: \"WatchList was successfully destroyed.\"\n  end\n\n  private\n\n  def set_watch_list\n    @watch_list = Current.user.watch_lists.find(params[:id])\n  end\n\n  def watch_list_params\n    params.require(:watch_list).permit(:name, :description)\n  end\nend\n"
  },
  {
    "path": "app/controllers/watched_talks_controller.rb",
    "content": "class WatchedTalksController < ApplicationController\n  include ActionView::RecordIdentifier\n  include WatchedTalks\n\n  def index\n    @in_progress_talks = Current.user.watched_talks\n      .in_progress\n      .includes(talk: [:speakers, {event: :series}, {child_talks: :speakers}])\n      .order(updated_at: :desc)\n      .limit(20)\n\n    watched_talks = Current.user.watched_talks\n      .watched\n      .includes(talk: [:speakers, {event: :series}, {child_talks: :speakers}])\n      .order(watched_at: :desc)\n\n    @watched_talks_by_date = watched_talks.group_by { |wt| (wt.watched_at || wt.created_at).to_date }\n    @user_favorite_talks_ids = Current.user.default_watch_list.talks.ids\n  end\n\n  def destroy\n    @watched_talk = Current.user.watched_talks.find(params[:id])\n    @watched_talk.delete\n\n    respond_to do |format|\n      format.turbo_stream do\n        render turbo_stream: turbo_stream.remove(dom_id(@watched_talk.talk, :card_horizontal))\n      end\n      format.html { redirect_to watched_talks_path, notice: \"Video removed from watched list\" }\n    end\n  end\nend\n"
  },
  {
    "path": "app/controllers/wrapped_controller.rb",
    "content": "class WrappedController < ApplicationController\n  skip_before_action :authenticate_user!\n  layout \"application\"\n\n  YEAR = 2025\n\n  def index\n    @year = YEAR\n    @year_range = Date.new(@year, 1, 1)..Date.new(@year, 12, 31)\n\n    @next_year = @year + 1\n    @next_year_range = Date.new(@next_year, 1, 1)..Date.new(@next_year, 12, 31)\n\n    @wrapped_cached_data = Rails.cache.fetch(\"wrapped:#{@year}:data\", expires_in: 12.hours) do\n      {\n        talks_held: Talk.where(date: @year_range).distinct.count,\n        talks_published: Talk.where(published_at: @year_range).distinct.count,\n        total_conferences: Event.where(start_date: @year_range, kind: :conference).count,\n        total_speakers: User.joins(:talks).where(talks: {date: @year_range}).distinct.count,\n        total_hours: (Talk.where(published_at: @year_range).sum(:duration_in_seconds) / 3600.0).round,\n        talks_with_slides: Talk.where(date: @year_range).where.not(slides_url: [nil, \"\"]).count,\n        top_topics_slugs: top_topics_slugs,\n        most_watched_events_slugs: most_watched_events.pluck(:slug),\n        events_by_sessions_slugs: events_by_sessions.pluck(:slug),\n        events_by_attendees_slugs: events_by_attendees.pluck(:slug),\n        country_codes_with_events: country_codes_with_events,\n        most_watched_talks_slugs: most_watched_talks_slugs,\n        new_speakers: new_speakers,\n        languages: languages,\n        passports_issued: ConnectedAccount.passport.where(created_at: @year_range).count,\n        unique_sponsors: unique_sponsors,\n        event_participations: EventParticipation.joins(:event).where(events: {start_date: @year_range}).count,\n        people_involved: people_involved,\n        total_talks_watched: WatchedTalk.where(watched_at: @year_range).count,\n        new_users: ConnectedAccount.github.where(created_at: @year_range).count,\n        total_rubyists: User.count,\n        rubyist_countries: rubyist_countries,\n        total_visits: total_visits,\n        total_page_views: total_page_views,\n        next_year_conferences: Event.where(start_date: @next_year_range, kind: :conference).count,\n        next_year_talks: Talk.where(date: @next_year_range).count,\n        open_cfps: open_cfps,\n        top_organizations_slugs: top_organizations_slugs\n      }\n    end\n\n    # Leave this uncached, so users can make theirs public and see it on the /wrapped page immediately\n    @public_users = User\n      .with_public_wrapped\n      .where.not(\"LOWER(users.name) IN (?)\", [\"tbd\", \"todo\", \"tba\", \"speaker tbd\", \"speaker tba\"])\n      .order(updated_at: :desc)\n      .limit(100)\n      .sample(35)\n\n    @talks_held = @wrapped_cached_data[:talks_held]\n    @talks_published = @wrapped_cached_data[:talks_published]\n    @total_conferences = @wrapped_cached_data[:total_conferences]\n    @total_speakers = @wrapped_cached_data[:total_speakers]\n    @total_hours = @wrapped_cached_data[:total_hours]\n    @talks_with_slides = @wrapped_cached_data[:talks_with_slides]\n\n    @top_topics = Topic\n      .where(slug: @wrapped_cached_data[:top_topics_slugs])\n      .sort_by { |topic| @wrapped_cached_data[:top_topics_slugs].index(topic.slug) }\n\n    @most_watched_events = Event\n      .where(slug: @wrapped_cached_data[:most_watched_events_slugs])\n      .sort_by { |event| @wrapped_cached_data[:most_watched_events_slugs].index(event.slug) }\n\n    @events_by_sessions = events_by_sessions\n\n    @events_by_attendees = events_by_attendees\n\n    @countries_with_events = @wrapped_cached_data[:country_codes_with_events]\n      .filter_map { |code| Country.find_by(country_code: code) }\n\n    @most_watched_talks = Talk\n      .where(slug: @wrapped_cached_data[:most_watched_talks_slugs])\n      .includes(:speakers, :event)\n      .sort_by { |talk| @wrapped_cached_data[:most_watched_talks_slugs].index(talk.slug) }\n\n    @new_speakers = @wrapped_cached_data[:new_speakers]\n\n    @languages = @wrapped_cached_data[:languages]\n\n    @passports_issued = @wrapped_cached_data[:passports_issued]\n\n    @unique_sponsors = @wrapped_cached_data[:unique_sponsors]\n\n    @event_participations = @wrapped_cached_data[:event_participations]\n\n    # @event_involvements = EventInvolvement\n    # .joins(:event)\n    # .where(events: {start_date: @year_range})\n    # .count\n\n    @people_involved = @wrapped_cached_data[:people_involved]\n\n    @total_talks_watched = @wrapped_cached_data[:total_talks_watched]\n\n    @new_users = @wrapped_cached_data[:new_users]\n\n    @total_rubyists = @wrapped_cached_data[:total_rubyists]\n    @github_contributors = 83\n\n    @rubyist_countries = @wrapped_cached_data[:rubyist_countries]\n\n    # @monthly_visits = Rollup\n    #   .where(time: @year_range, interval: \"month\")\n    #   .where(name: \"ahoy_visits\")\n    #   .order(:time)\n    #   .pluck(:time, :value)\n    #   .map { |time, value| [time.strftime(\"%b\"), value] }\n\n    @total_visits = @wrapped_cached_data[:total_visits]\n\n    @total_page_views = @wrapped_cached_data[:total_page_views]\n\n    # next_year_events = Event.where(start_date: @next_year_range).count\n    @next_year_conferences = @wrapped_cached_data[:next_year_conferences]\n    @next_year_talks = @wrapped_cached_data[:next_year_talks]\n\n    @open_cfps = @wrapped_cached_data[:open_cfps]\n\n    @top_organizations = Organization.where(slug: @wrapped_cached_data[:top_organizations_slugs])\n      .sort_by { |org| @wrapped_cached_data[:top_organizations_slugs].index(org.slug) }\n\n    set_wrapped_meta_tags\n  end\n\n  private\n\n  def set_wrapped_meta_tags\n    title = \"RubyEvents.org #{@year} Wrapped\"\n    description = \"#{@year} in review. Explore the Ruby community's year!\"\n    image_url = view_context.image_url(\"og/wrapped-#{@year}.png\")\n\n    set_meta_tags(\n      title: title,\n      description: description,\n      og: {\n        title: title,\n        description: description,\n        image: image_url,\n        type: \"website\",\n        url: wrapped_url\n      },\n      twitter: {\n        title: title,\n        description: description,\n        image: image_url,\n        card: \"summary_large_image\"\n      }\n    )\n  end\n\n  def find_country_from_location(location_string)\n    return nil if location_string.blank?\n\n    country = Country.find(location_string)\n    return country if country.present?\n\n    location_string.split(\",\").each do |part|\n      country = Country.find(part.strip)\n      return country if country.present?\n    end\n\n    nil\n  end\n\n  def country_codes_with_events\n    Event\n      .where(start_date: @year_range)\n      .where.not(country_code: nil)\n      .distinct\n      .pluck(:country_code)\n  end\n\n  def events_by_attendees\n    events_by_attendees_source = @wrapped_cached_data&.dig(:events_by_attendees_slugs) ? Event.where(slug: @wrapped_cached_data[:events_by_attendees_slugs]) : Event\n    @events_by_attendees = events_by_attendees_source\n      .where(start_date: @year_range)\n      .joins(:event_participations)\n      .group(:id)\n      .select(\"events.*, COUNT(event_participations.id) as attendees_count\")\n      .order(\"COUNT(event_participations.id) DESC\")\n      .limit(5)\n  end\n\n  def events_by_sessions\n    events_by_sessions_source = @wrapped_cached_data&.dig(:events_by_sessions_slugs) ? Event.where(slug: @wrapped_cached_data[:events_by_sessions_slugs]) : Event\n    @events_by_sessions = events_by_sessions_source\n      .where(start_date: @year_range)\n      .joins(:talks)\n      .group(:id)\n      .select(\"events.*, COUNT(talks.id) as talks_count\")\n      .order(\"COUNT(talks.id) DESC\")\n      .limit(5)\n  end\n\n  def languages\n    Talk\n      .where(date: @year_range)\n      .where.not(language: nil)\n      .group(:language)\n      .count\n      .sort_by { |_, count| -count }\n      .map { |code, count| [Language.by_code(code) || code, count] }\n  end\n\n  def most_watched_events\n    Event\n      .where(start_date: @year_range)\n      .joins(talks: :watched_talks)\n      .group(:id)\n      .order(\"COUNT(watched_talks.id) DESC\")\n      .limit(5)\n  end\n\n  def most_watched_talks_slugs\n    Talk\n      .joins(:watched_talks)\n      .where(date: @year_range)\n      .group(:id)\n      .order(\"COUNT(watched_talks.id) DESC\")\n      .includes(:speakers, :event)\n      .limit(10)\n      .pluck(:slug)\n  end\n\n  def new_speakers\n    User\n      .joins(:talks)\n      .where(talks: {date: @year_range})\n      .where.not(id: User.joins(:talks).where(talks: {date: ...Date.new(@year, 1, 1)}).select(:id))\n      .distinct\n      .count\n  end\n\n  def open_cfps\n    CFP\n      .joins(:event)\n      .where(events: {start_date: @next_year_range})\n      .where(\"cfps.close_date IS NULL OR cfps.close_date >= ?\", Date.new(@next_year, 1, 1))\n      .where(\"cfps.open_date IS NULL OR cfps.open_date <= ?\", Date.new(@next_year, 1, 1))\n      .count\n  end\n\n  def people_involved\n    EventInvolvement\n      .joins(:event)\n      .where(events: {start_date: @year_range})\n      .where(involvementable_type: \"User\")\n      .distinct\n      .count(:involvementable_id)\n  end\n\n  def rubyist_countries\n    User\n      .where.not(location: [nil, \"\"])\n      .distinct\n      .pluck(:location)\n      .filter_map { |location| find_country_from_location(location)&.alpha2 }\n      .uniq\n      .count\n  end\n\n  def top_organizations_slugs\n    Organization\n      .joins(:sponsors)\n      .joins(\"INNER JOIN events ON sponsors.event_id = events.id\")\n      .where(events: {start_date: @year_range})\n      .group(\"organizations.id\")\n      .order(Arel.sql(\"COUNT(DISTINCT events.id) DESC\"))\n      .limit(35)\n      .pluck(:slug)\n  end\n\n  def top_topics_slugs\n    Topic.approved\n      .joins(:talks)\n      .where(talks: {date: @year_range})\n      .where.not(\"LOWER(topics.name) IN (?)\", [\"ruby\", \"ruby on rails\", \"lightning talks\"])\n      .group(:id)\n      .order(\"COUNT(talks.id) DESC\")\n      .limit(5)\n      .pluck(:slug)\n  end\n\n  def total_page_views\n    Rollup\n      .where(time: @year_range, interval: \"month\")\n      .where(name: \"ahoy_events\")\n      .sum(:value)\n      .to_i\n  end\n\n  def total_visits\n    Rollup\n      .where(time: @year_range, interval: \"month\")\n      .where(name: \"ahoy_visits\")\n      .sum(:value)\n      .to_i\n  end\n\n  def unique_sponsors\n    Organization\n      .joins(:sponsors)\n      .joins(\"INNER JOIN events ON sponsors.event_id = events.id\")\n      .where(events: {start_date: @year_range})\n      .distinct\n      .count\n  end\nend\n"
  },
  {
    "path": "app/helpers/application_helper.rb",
    "content": "module ApplicationHelper\n  include Pagy::Frontend\n\n  def back_path\n    @back_path || root_path\n  end\n\n  def back_to_from_request\n    # remove the back_to params from the query string to avoid creating recusive redirects\n    uri = URI.parse(request.fullpath)\n    uri.query = uri.query&.split(\"&\")&.reject { |param| param.start_with?(\"back_to=\") }&.join(\"&\")\n    uri.to_s\n  end\n\n  def active_link_to(text = nil, path = nil, active_class: \"\", **options, &)\n    path ||= text\n\n    classes = active_class.presence || \"active\"\n    options[:class] = class_names(options[:class], classes) if current_page?(path)\n\n    return link_to(path, options, &) if block_given?\n\n    link_to text, path, options\n  end\n\n  def footer_credits\n    maintainers = [\n      link_to(\"@adrienpoly\", \"https://www.rubyevents.org/profiles/adrienpoly\", class: \"link\", alt: \"Adrien Poly\"),\n      link_to(\"@chaelcodes\", \"https://www.rubyevents.org/profiles/chaelcodes\", class: \"link\", alt: \"Rachael Wright-Munn\"),\n      link_to(\"@marcoroth\", \"https://www.rubyevents.org/profiles/marcoroth\", class: \"link\", alt: \"Marco Roth\")\n    ].shuffle.join(\", \")\n\n    output = [\"Made with\"]\n    output << fa(:heart, size: :sm, class: \"fill-red-700 inline\")\n    output << \"for the Ruby community by\"\n    output << \"#{maintainers}, and wonderful\"\n    output << link_to(\"contributors\", contributors_path, class: \"link\")\n    output << \"using an\"\n    output << link_to(\"edge stack.\", uses_path, class: \"link\")\n    sanitize(output.join(\" \"), tags: %w[a span svg path], attributes: %w[href target class alt d xmlns viewBox fill])\n  end\n\n  def canonical_url\n    content_for?(:canonical_url) ? content_for(:canonical_url) : \"https://www.rubyevents.org#{request.path}\"\n  end\n\n  def sanitize_url(url, fallback: \"\")\n    if Rails::HTML::Sanitizer.allowed_uri?(url)\n      url\n    else\n      fallback\n    end\n  end\nend\n"
  },
  {
    "path": "app/helpers/events/talks_helper.rb",
    "content": "module Events::TalksHelper\nend\n"
  },
  {
    "path": "app/helpers/events_helper.rb",
    "content": "module EventsHelper\n  def event_date_display(event, day_name: false)\n    return \"Date TBD\" unless event.start_date.present?\n\n    case event.date_precision\n    when \"year\"\n      \"Sometime in #{event.start_date.year}\"\n    when \"month\"\n      event.start_date.strftime(\"%B %Y\")\n    else\n      if day_name\n        \"#{event.start_date.strftime(\"%b %-d\")} #{event.start_date.strftime(\"%A\")}\"\n      else\n        event.start_date.strftime(\"%b %-d\")\n      end\n    end\n  end\n\n  def event_date_group_key(event)\n    return nil unless event.start_date.present?\n\n    case event.date_precision\n    when \"year\"\n      \"year-#{event.start_date.year}\"\n    when \"month\"\n      \"month-#{event.start_date.strftime(\"%Y-%m\")}\"\n    else\n      \"day-#{event.start_date.to_date}\"\n    end\n  end\n\n  def group_events_by_date(events)\n    events.group_by { |e| event_date_group_key(e) }\n      .sort_by { |key, _| key || \"zzz\" }\n      .map do |key, group_events|\n        first_event = group_events.first\n\n        display_info = {\n          date: first_event.start_date,\n          precision: first_event.date_precision,\n          display: event_date_display(first_event, day_name: true)\n        }\n\n        [display_info, group_events]\n      end\n  end\n\n  def home_updated_text(event)\n    if event.static_metadata.published_date\n      return \"Talks recordings were published #{time_ago_in_words(event.static_metadata.published_date)} ago.\"\n    end\n\n    if event.today?\n      return \"Takes place today.\"\n    end\n\n    if event.end_date&.past?\n      return \"Took place #{time_ago_in_words(event.end_date)} ago.\"\n    end\n\n    if event.start_date&.future?\n      return \"Takes place in #{time_ago_in_words(event.start_date)}.\"\n    end\n\n    if event.start_date&.future?\n      \"Takes place in #{time_ago_in_words(event.start_date)}.\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/helpers/icon_helper.rb",
    "content": "# frozen_string_literal: true\n\nmodule IconHelper\n  SIZE_CLASSES = {\n    xs: \"h-4 w-4\",\n    sm: \"h-5 w-5\",\n    md: \"h-6 w-6\",\n    lg: \"h-8 w-8\",\n    xl: \"h-10 w-10\"\n  }\n\n  # Add a class-level cache\n  @svg_cache = {}\n\n  class << self\n    attr_reader :svg_cache\n\n    def clear_cache\n      @svg_cache.clear\n    end\n  end\n\n  def cached_inline_svg(path, **options)\n    cache_key = [path, options].hash\n\n    IconHelper.svg_cache[cache_key] ||= begin\n      full_path = Rails.root.join(\"app\", \"assets\", \"images\", path)\n\n      unless File.exist?(full_path)\n        basename = File.basename(path, \".svg\")\n        match = basename.match(/^(.+?)(?:-(brands))?-(solid|regular|light)$/)\n\n        if match\n          icon_name, type, style = match.captures\n          folder = type || style\n          search_url = \"https://fontawesome.com/search?q=#{CGI.escape(icon_name)}\"\n          github_url = \"https://raw.githubusercontent.com/FortAwesome/Font-Awesome/7.x/svgs-full/#{folder}/#{icon_name}.svg\"\n          curl_command = \"curl -f -o #{full_path} \\\"#{github_url}\\\"\"\n\n          raise ArgumentError, \"Icon not found. Download from\\n#{search_url}\\nand save to\\n#{full_path}\\n\\nOr run the following curl command (only works for free icons, not Pro):\\n#{curl_command}\"\n        else\n          raise ArgumentError, \"Icon not found: #{path}\"\n        end\n      end\n\n      svg_content = File.read(full_path)\n\n      if options.present?\n        # Extract existing attributes from the SVG tag\n        svg_tag = svg_content[/<svg[^>]*>/]\n\n        existing_attributes = {}\n        svg_tag.scan(/([^\\s=]+)=\"([^\"]*)\"/).each do |name, value|\n          existing_attributes[name] = value\n        end.to_h\n\n        new_attributes = tag.attributes(existing_attributes.merge(options))\n\n        # Replace the opening SVG tag with our modified version\n        new_svg_tag = \"<svg #{new_attributes}>\"\n        svg_content.sub!(/<svg[^>]*>/, new_svg_tag)\n      end\n\n      svg_content.html_safe\n    end\n  end\n\n  def fontawesome(icon_name, size: :md, type: nil, style: :solid, **options)\n    classes = class_names(SIZE_CLASSES[size], options[:class])\n    cached_inline_svg \"icons/fontawesome/#{[icon_name, type, style].compact.join(\"-\")}.svg\", class: classes, **options.except(:class)\n  end\n\n  def fab(icon_name, **options)\n    fontawesome(icon_name, type: :brands, **options.except(:type))\n  end\n\n  def fa(icon_name, **options)\n    fontawesome(icon_name, **options.except(:type))\n  end\n\n  def icon(icon_name, size: :md, **options)\n    classes = class_names(SIZE_CLASSES[size], options.delete(:class))\n    cached_inline_svg(\"icons/icn-#{icon_name}.svg\", class: classes, **options)\n  end\nend\n"
  },
  {
    "path": "app/helpers/language_helper.rb",
    "content": "module LanguageHelper\n  LANGUAGE_TO_EMOJI = {\n    \"afrikaans\" => \"🇿🇦\",\n    \"amharic\" => \"🇪🇹\",\n    \"arabic\" => \"🇸🇦\",\n    \"armenian\" => \"🇦🇲\",\n    \"azerbaijani\" => \"🇦🇿\",\n    \"basque\" => \"🇪🇸\",\n    \"belarusian\" => \"🇧🇾\",\n    \"bengali\" => \"🇧🇩\",\n    \"bosnian\" => \"🇧🇦\",\n    \"bulgarian\" => \"🇧🇬\",\n    \"burmese\" => \"🇲🇲\",\n    \"catalan\" => \"🇪🇸\",\n    \"chinese\" => \"🇨🇳\",\n    \"croatian\" => \"🇭🇷\",\n    \"czech\" => \"🇨🇿\",\n    \"danish\" => \"🇩🇰\",\n    \"dutch\" => \"🇳🇱\",\n    \"english\" => \"\",\n    \"esperanto\" => \"🏳️\",\n    \"estonian\" => \"🇪🇪\",\n    \"fijian\" => \"🇫🇯\",\n    \"filipino\" => \"🇵🇭\",\n    \"finnish\" => \"🇫🇮\",\n    \"french\" => \"🇫🇷\",\n    \"galician\" => \"🇪🇸\",\n    \"georgian\" => \"🇬🇪\",\n    \"german\" => \"🇩🇪\",\n    \"greek\" => \"🇬🇷\",\n    \"greenlandic\" => \"🇬🇱\",\n    \"gujarati\" => \"🇮🇳\",\n    \"haitian_creole\" => \"🇭🇹\",\n    \"hausa\" => \"🇳🇬\",\n    \"hawaiian\" => \"🇺🇸\",\n    \"hebrew\" => \"🇮🇱\",\n    \"hindi\" => \"🇮🇳\",\n    \"hungarian\" => \"🇭🇺\",\n    \"icelandic\" => \"🇮🇸\",\n    \"indonesian\" => \"🇮🇩\",\n    \"irish\" => \"🇮🇪\",\n    \"italian\" => \"🇮🇹\",\n    \"japanese\" => \"🇯🇵\",\n    \"javanese\" => \"🇮🇩\",\n    \"kannada\" => \"🇮🇳\",\n    \"kazakh\" => \"🇰🇿\",\n    \"khalkha\" => \"🇲🇳\",\n    \"khmer\" => \"🇰🇭\",\n    \"korean\" => \"🇰🇷\",\n    \"kurdish\" => \"🏳️\",\n    \"kyrgyz\" => \"🇰🇬\",\n    \"lao\" => \"🇱🇦\",\n    \"laothian\" => \"🇱🇦\",\n    \"latvian\" => \"🇱🇻\",\n    \"lithuanian\" => \"🇱🇹\",\n    \"luxembourgish\" => \"🇱🇺\",\n    \"macedonian\" => \"🇲🇰\",\n    \"malagasy\" => \"🇲🇬\",\n    \"malay\" => \"🇲🇾\",\n    \"maltese\" => \"🇲🇹\",\n    \"maori\" => \"🇳🇿\",\n    \"marathi\" => \"🇮🇳\",\n    \"mongolian\" => \"🇲🇳\",\n    \"myanmar\" => \"🇲🇲\",\n    \"nepali\" => \"🇳🇵\",\n    \"norwegian\" => \"🇳🇴\",\n    \"oriya\" => \"🇮🇳\",\n    \"pashto\" => \"🇦🇫\",\n    \"persian\" => \"🇮🇷\",\n    \"polish\" => \"🇵🇱\",\n    \"portuguese\" => \"🇵🇹\",\n    \"punjabi\" => \"🇮🇳\",\n    \"quechua\" => \"🇵🇪\",\n    \"romanian\" => \"🇷🇴\",\n    \"russian\" => \"🇷🇺\",\n    \"samoan\" => \"🇼🇸\",\n    \"serbian\" => \"🇷🇸\",\n    \"sesotho\" => \"🇱🇸\",\n    \"shona\" => \"🇿🇼\",\n    \"sindhi\" => \"🇵🇰\",\n    \"sinhala\" => \"🇱🇰\",\n    \"slovak\" => \"🇸🇰\",\n    \"slovenian\" => \"🇸🇮\",\n    \"somali\" => \"🇸🇴\",\n    \"spanish\" => \"🇪🇸\",\n    \"sundanese\" => \"🇮🇩\",\n    \"swahili\" => \"🇰🇪\",\n    \"swedish\" => \"🇸🇪\",\n    \"tagalog\" => \"🇵🇭\",\n    \"tajik\" => \"🇹🇯\",\n    \"tamil\" => \"🇮🇳\",\n    \"telugu\" => \"🇮🇳\",\n    \"thai\" => \"🇹🇭\",\n    \"tigrinya\" => \"🇪🇷\",\n    \"tsonga\" => \"🇿🇦\",\n    \"tswana\" => \"🇧🇼\",\n    \"turkish\" => \"🇹🇷\",\n    \"ukrainian\" => \"🇺🇦\",\n    \"urdu\" => \"🇵🇰\",\n    \"uzbek\" => \"🇺🇿\",\n    \"venda\" => \"🇿🇦\",\n    \"vietnamese\" => \"🇻🇳\",\n    \"welsh\" => \"🏴󠁧󠁢󠁷󠁬󠁳󠁿\",\n    \"xhosa\" => \"🇿🇦\",\n    \"yoruba\" => \"🇳🇬\",\n    \"zulu\" => \"🇿🇦\"\n  }.freeze\n\n  NATIVE_NAMES = {\n    \"de\" => \"deutsch\",\n    \"es\" => \"español\",\n    \"fr\" => \"français\",\n    \"it\" => \"italiano\",\n    \"pt\" => \"português\",\n    \"ja\" => \"日本語\",\n    \"ko\" => \"한국어\",\n    \"zh\" => \"中文\",\n    \"ru\" => \"русский\",\n    \"nl\" => \"nederlands\",\n    \"pl\" => \"polski\",\n    \"sv\" => \"svenska\",\n    \"da\" => \"dansk\",\n    \"no\" => \"norsk\",\n    \"fi\" => \"suomi\",\n    \"cs\" => \"čeština\",\n    \"hu\" => \"magyar\",\n    \"ro\" => \"română\",\n    \"uk\" => \"українська\",\n    \"el\" => \"ελληνικά\",\n    \"tr\" => \"türkçe\",\n    \"ar\" => \"العربية\",\n    \"he\" => \"עברית\",\n    \"hi\" => \"हिन्दी\",\n    \"th\" => \"ไทย\",\n    \"vi\" => \"tiếng việt\",\n    \"id\" => \"bahasa indonesia\"\n  }.freeze\n\n  def language_to_emoji(language)\n    LANGUAGE_TO_EMOJI[language.downcase] || \"🏳️\"\n  end\nend\n"
  },
  {
    "path": "app/helpers/location_helper.rb",
    "content": "# frozen_string_literal: true\n\nmodule LocationHelper\n  def location_path(location)\n    location.path\n  end\n\n  def location_past_path(location)\n    location.past_path\n  end\n\n  def location_users_path(location)\n    location.users_path\n  end\n\n  def location_meetups_path(location)\n    location.try(:meetups_path)\n  end\n\n  def location_countries_path(location)\n    location.try(:countries_path)\n  end\n\n  def location_cities_path(location)\n    location.try(:cities_path)\n  end\n\n  def location_stamps_path(location)\n    location.stamps_path\n  end\n\n  def location_map_path(location)\n    location.map_path\n  end\n\n  def location_has_routes?(location)\n    location.has_routes?\n  end\nend\n"
  },
  {
    "path": "app/helpers/markdown_helper.rb",
    "content": "module MarkdownHelper\n  # Custom renderer with Rouge syntax highlighting\n  class SyntaxHighlightedRenderer < Redcarpet::Render::HTML\n    def block_code(code, language)\n      language ||= \"text\"\n      lexer = Rouge::Lexer.find_fancy(language, code) || Rouge::Lexers::PlainText.new\n      formatter = Rouge::Formatters::HTML.new\n      highlighted = formatter.format(lexer.lex(code))\n      %(<pre class=\"highlight\"><code class=\"language-#{language}\">#{highlighted}</code></pre>)\n    end\n  end\n\n  def markdown_to_html(markdown_content)\n    renderer = Redcarpet::Render::HTML.new(hard_wrap: true)\n    markdown = Redcarpet::Markdown.new(renderer)\n    markdown.render(markdown_content).html_safe\n  end\n\n  def announcement_markdown_to_html(markdown_content)\n    renderer = SyntaxHighlightedRenderer.new(\n      hard_wrap: true,\n      link_attributes: {target: \"_blank\", rel: \"noopener noreferrer\"}\n    )\n    markdown = Redcarpet::Markdown.new(\n      renderer,\n      autolink: true,\n      tables: true,\n      fenced_code_blocks: true\n    )\n    html = markdown.render(markdown_content)\n\n    html = process_mentions(html)\n    html = process_topics(html)\n\n    html.html_safe\n  end\n\n  private\n\n  def process_mentions(html)\n    html.gsub(/@(\\w+)/) do |match|\n      username = $1\n      user = User.find_by_github_handle(username)\n\n      if user\n        link_to(\"@#{username}\", profile_path(user), class: \"text-primary hover:underline\")\n      else\n        match\n      end\n    end\n  end\n\n  # Topics can be added to the content with the wiki-link syntax\n  # [[topic-slug]] - supports hyphenated slugs\n  def process_topics(html)\n    html.gsub(/\\[\\[([\\w-]+)\\]\\]/) do |match|\n      slug = $1\n      topic = Topic.find_by(slug: slug) || Topic.find_by(name: slug)\n\n      if topic\n        link_to(topic.name, topic_path(topic), class: \"text-primary hover:underline\")\n      else\n        match\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/helpers/page_helper.rb",
    "content": "module PageHelper\nend\n"
  },
  {
    "path": "app/helpers/speakers/enhance_helper.rb",
    "content": "module Speakers::EnhanceHelper\nend\n"
  },
  {
    "path": "app/helpers/speakers_helper.rb",
    "content": "module SpeakersHelper\n  def form_title_for_user_kind(user_kind)\n    case user_kind\n    when :owner, :admin\n      \"Editing speaker\"\n    when :signed_in, :anonymous\n      \"Suggesting a modification\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/helpers/spotlight_helper.rb",
    "content": "module SpotlightHelper\n  def spotlight_resources\n    %w[talks speakers events]\n  end\n\n  def spotlight_main_resource\n    request.path.split(\"/\").last.presence_in(%w[talks speakers events topics]) || \"talks\"\n  end\n\n  def spotlight_main_resource_path\n    {\n      \"talks\" => talks_path,\n      \"speakers\" => speakers_path,\n      \"events\" => archive_events_path,\n      \"topics\" => topics_path\n    }.fetch(spotlight_main_resource, spotlight_talks_path)\n  end\n\n  def spotlight_search_backend\n    @spotlight_search_backend ||= Search::Backend.resolve.name\n  end\n\n  def spotlight_can_search_locations?\n    spotlight_search_backend != :sqlite_fts\n  end\n\n  def spotlight_can_search_languages?\n    spotlight_search_backend != :sqlite_fts\n  end\n\n  def spotlight_can_search_series?\n    spotlight_search_backend != :sqlite_fts\n  end\nend\n"
  },
  {
    "path": "app/helpers/suggestions_helper.rb",
    "content": "module SuggestionsHelper\nend\n"
  },
  {
    "path": "app/helpers/talks_helper.rb",
    "content": "module TalksHelper\n  def seconds_to_formatted_duration(seconds)\n    Duration.seconds_to_formatted_duration(seconds, raise: false)\n  end\n\n  def ordering_title\n    case order_by_key\n    when \"date_desc\"\n      \"Newest first\"\n    when \"date_asc\"\n      \"Oldest first\"\n    when \"ranked\"\n      \"Relevance\"\n    end\n  end\n\n  def resource_icon(resource)\n    case resource[\"type\"]\n    when \"write-up\", \"blog\", \"article\" then \"pen-to-square\"\n    when \"source-code\", \"code\", \"repo\" then \"code\"\n    when \"github\" then \"github\"\n    when \"documentation\", \"docs\" then \"book\"\n    when \"slides\", \"presentation\" then \"presentation-screen\"\n    when \"video\" then \"video\"\n    when \"podcast\", \"audio\" then \"podcast\"\n    when \"gem\", \"library\" then \"gem\"\n    when \"transcript\" then \"file-lines\"\n    when \"handout\" then \"file-pdf\"\n    when \"notes\" then \"note-sticky\"\n    when \"photos\" then \"images\"\n    when \"book\" then \"book\"\n    else \"link\"\n    end\n  end\n\n  def resource_display_title(resource)\n    resource[\"title\"].presence || resource[\"name\"]\n  end\n\n  def resource_domain(resource)\n    URI.parse(resource[\"url\"]).host\n  rescue URI::InvalidURIError\n    resource[\"url\"]\n  end\nend\n"
  },
  {
    "path": "app/helpers/view_component_helper.rb",
    "content": "module ViewComponentHelper\n  UI_HELPERS = {\n    avatar: \"Ui::AvatarComponent\",\n    badge: \"Ui::BadgeComponent\",\n    button: \"Ui::ButtonComponent\",\n    divider: \"Ui::DividerComponent\",\n    dropdown: \"Ui::DropdownComponent\",\n    modal: \"Ui::ModalComponent\",\n    stamp: \"Ui::StampComponent\"\n  }.freeze\n\n  UI_HELPERS.each do |name, component|\n    define_method :\"ui_#{name}\" do |*args, **kwargs, &block|\n      render component.constantize.new(*args, **kwargs), &block\n    end\n  end\n\n  def ui_tooltip(text, **kwargs, &block)\n    tag.div data: {controller: \"tooltip\", tooltip_content_value: text}, **kwargs do\n      yield\n    end\n  end\n\n  def external_link_to(text, url = nil, **attributes, &)\n    if block_given?\n      url = text\n      text = capture(&)\n    end\n\n    classes = class_names(\"link inline-flex items-center gap-2 flex-nowrap\", attributes.delete(:class))\n    link_to url, class: classes, target: \"_blank\", rel: \"noopener noreferrer\", **attributes do\n      concat(content_tag(:span) { text }).concat(fa(\"arrow-up-right-from-square\", size: :xs))\n    end\n  end\nend\n"
  },
  {
    "path": "app/javascript/controllers/application.js",
    "content": "import { Application } from '@hotwired/stimulus'\nimport { appsignal } from '~/support/appsignal'\n\nimport HwComboboxController from '@josefarias/hotwire_combobox'\n\nconst application = Application.start()\n\n// Configure Stimulus development experience\napplication.debug = false\nwindow.Stimulus = application\n\n// Error handling\nconst defaultErrorHandler = application.handleError.bind(application)\n\n// create a ne composed error handler with Appsignal\nconst appsignalErrorHandler = (error, message, detail = {}) => {\n  defaultErrorHandler(error, message, detail)\n  appsignal.sendError(error, (span) => { span.setTags({ message }) })\n}\n\n// overwrite the default handler with our new composed handler\napplication.handleError = appsignalErrorHandler\n\napplication.register('hw-combobox', HwComboboxController)\n\nexport { application }\n"
  },
  {
    "path": "app/javascript/controllers/auto-click_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport { useIntersection } from 'stimulus-use'\n\n// Connects to data-controller=\"auto-click\"\nexport default class extends Controller {\n  static values = {\n    rootMargin: { type: String, default: '400px 0px 0px 0px' }\n  }\n\n  initialize () {\n    useIntersection(this, { rootMargin: this.rootMarginValue })\n  }\n\n  appear () {\n    this.element.click()\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/auto_submit_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport { useDebounce } from 'stimulus-use'\n\nexport default class extends Controller {\n  static debounces = ['submit']\n\n  initialize () {\n    useDebounce(this)\n\n    this.element.addEventListener('keydown', () => this.submit())\n    this.element.addEventListener('search', () => this.submit())\n  }\n\n  disconnect () {\n    this.element.removeEventListener('keydown', () => this.submit())\n    this.element.removeEventListener('search', () => this.submit())\n  }\n\n  submit () {\n    this.element.requestSubmit()\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/bridge/button_controller.js",
    "content": "import { BridgeComponent } from '@hotwired/hotwire-native-bridge'\n\nexport default class extends BridgeComponent {\n  static component = 'button'\n  static targets = ['element']\n\n  connect () {\n    super.connect()\n\n    this.send('connect', { title: this.title }, () => {\n      this.targetElement.click()\n    })\n  }\n\n  get targetElement () {\n    if (this.hasElementTarget) {\n      return this.elementTarget\n    }\n\n    return this.element\n  }\n\n  get title () {\n    return this.bridgeElement.bridgeAttribute('title')\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/collapsible_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['content']\n  static values = {\n    open: { type: Boolean, default: false }\n  }\n\n  connect () {\n    this.updateVisibility()\n  }\n\n  toggle () {\n    this.openValue = !this.openValue\n  }\n\n  close () {\n    this.openValue = false\n  }\n\n  open () {\n    this.openValue = true\n  }\n\n  openValueChanged () {\n    this.updateVisibility()\n\n    if (this.openValue && this.hasContentTarget) {\n      requestAnimationFrame(() => {\n        this.contentTarget.scrollIntoView({ behavior: 'smooth', block: 'nearest' })\n      })\n    }\n  }\n\n  updateVisibility () {\n    if (this.hasContentTarget) {\n      this.contentTarget.classList.toggle('hidden', !this.openValue)\n    }\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/content_row_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['container', 'track', 'prevButton', 'nextButton', 'gradient']\n\n  connect () {\n    this.updateButtonVisibility()\n  }\n\n  scrollLeft () {\n    const scrollAmount = this.cardWidth * 3\n    this.containerTarget.scrollBy({ left: -scrollAmount, behavior: 'smooth' })\n  }\n\n  scrollRight () {\n    const scrollAmount = this.cardWidth * 3\n    this.containerTarget.scrollBy({ left: scrollAmount, behavior: 'smooth' })\n  }\n\n  handleScroll () {\n    this.updateButtonVisibility()\n  }\n\n  updateButtonVisibility () {\n    const { scrollLeft, scrollWidth, clientWidth } = this.containerTarget\n    const isAtStart = scrollLeft <= 10\n    const isAtEnd = scrollLeft + clientWidth >= scrollWidth - 10\n\n    if (this.hasPrevButtonTarget) {\n      this.prevButtonTarget.disabled = isAtStart\n      this.prevButtonTarget.classList.toggle('!opacity-0', isAtStart)\n    }\n\n    if (this.hasNextButtonTarget) {\n      this.nextButtonTarget.disabled = isAtEnd\n      this.nextButtonTarget.classList.toggle('!opacity-0', isAtEnd)\n    }\n\n    if (this.hasGradientTarget) {\n      this.gradientTarget.classList.toggle('sm:opacity-0', isAtEnd)\n    }\n  }\n\n  get cardWidth () {\n    const firstCard = this.trackTarget.querySelector(':scope > div')\n    return firstCard ? firstCard.offsetWidth + 16 : 320 // 16 = gap-4\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/copy_to_clipboard_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['button', 'source']\n  static values = {\n    successMessage: { type: String, default: 'Copied!' },\n    successDuration: { type: Number, default: 2000 }\n  }\n\n  static classes = ['success']\n\n  async copy (event) {\n    event.preventDefault()\n\n    const text = this.sourceTarget.innerText\n\n    try {\n      if (navigator.clipboard) {\n        await navigator.clipboard.writeText(text)\n      } else {\n        this.fallbackCopy(text)\n      }\n      this.copied()\n    } catch (error) {\n      this.fallbackCopy(text)\n      this.copied()\n    }\n  }\n\n  fallbackCopy (text) {\n    const temporaryInput = document.createElement('textarea')\n    temporaryInput.value = text\n    document.body.appendChild(temporaryInput)\n    temporaryInput.select()\n    document.execCommand('copy')\n    document.body.removeChild(temporaryInput)\n  }\n\n  copied () {\n    if (!this.hasButtonTarget) return\n\n    if (this.timeout) {\n      clearTimeout(this.timeout)\n    }\n\n    const successClass = this.successClass\n    if (successClass) {\n      this.buttonTarget.classList.add(successClass)\n    }\n    const message = this.successMessageValue\n    const originalText = this.buttonTarget.innerHTML\n    if (message) {\n      this.buttonTarget.innerHTML = message\n    }\n\n    this.timeout = setTimeout(() => {\n      this.buttonTarget.classList.remove(successClass)\n      this.buttonTarget.innerHTML = originalText\n    }, this.successDurationValue)\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/dropdown_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport { useClickOutside } from 'stimulus-use'\n\nexport default class extends Controller {\n  static targets = ['summary', 'swap']\n\n  connect () {\n    useClickOutside(this)\n    this.element.addEventListener('toggle', this.toggle.bind(this))\n  }\n\n  disconnect () {\n    this.#close()\n    this.element.removeEventListener('toggle', this.toggle)\n  }\n\n  clickOutside (event) {\n    this.#close(event)\n  }\n\n  // Private\n\n  toggle (event) {\n    if (this.element.open) {\n      this.element.setAttribute('aria-expanded', true)\n      this.swapTarget.classList.add('swap-active')\n    } else {\n      this.element.setAttribute('aria-expanded', false)\n      this.swapTarget.classList.remove('swap-active')\n    }\n  }\n\n  #close (event) {\n    this.element.open = false\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/event_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\n// Connects to data-controller=\"event\"\nexport default class extends Controller {\n  static values = {\n    name: String\n  }\n\n  dispatchEvent (e) {\n    this.dispatch(this.nameValue, { prefix: false })\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/event_list_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['item', 'poster', 'list', 'topGradient', 'bottomGradient']\n\n  connect () {\n    const firstEvent = this.itemTargets[0]\n\n    this.posterTargetFor(firstEvent.dataset.eventId)?.classList.remove('hidden')\n    this.updateGradients()\n  }\n\n  reveal (event) {\n    const eventId = event.target.closest('.event-item').dataset.eventId\n\n    this.hidePosters()\n    this.posterTargetFor(eventId)?.classList.remove('hidden')\n  }\n\n  hidePosters () {\n    this.posterTargets.forEach(poster => poster.classList.add('hidden'))\n  }\n\n  posterTargetFor (eventId) {\n    return this.posterTargets.find(poster => poster.dataset.eventId === eventId)\n  }\n\n  updateGradients () {\n    if (!this.hasListTarget) return\n\n    const list = this.listTarget\n    const scrollTop = list.scrollTop\n    const scrollHeight = list.scrollHeight\n    const clientHeight = list.clientHeight\n    const threshold = 10\n\n    const atTop = scrollTop <= threshold\n    const atBottom = scrollTop + clientHeight >= scrollHeight - threshold\n\n    if (this.hasTopGradientTarget) {\n      this.topGradientTarget.classList.toggle('md:hidden', atTop)\n    }\n\n    if (this.hasBottomGradientTarget) {\n      this.bottomGradientTarget.classList.toggle('md:hidden', atBottom)\n    }\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/events_filter_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['button', 'event', 'group']\n  static values = { current: { type: String, default: 'all' } }\n\n  filter (event) {\n    this.currentValue = event.currentTarget.dataset.kind\n  }\n\n  currentValueChanged () {\n    this.updateButtons()\n    this.filterEvents()\n    this.updateGroups()\n  }\n\n  updateButtons () {\n    this.buttonTargets.forEach(button => {\n      const isActive = button.dataset.kind === this.currentValue\n      button.classList.toggle('tab-active', isActive)\n    })\n  }\n\n  filterEvents () {\n    this.eventTargets.forEach(event => {\n      const eventKind = event.dataset.kind\n      const shouldShow = this.currentValue === 'all' || eventKind === this.currentValue\n      event.classList.toggle('hidden', !shouldShow)\n    })\n  }\n\n  updateGroups () {\n    this.groupTargets.forEach(group => {\n      const visibleEvents = group.querySelectorAll('[data-events-filter-target=\"event\"]:not(.hidden)')\n      group.classList.toggle('hidden', visibleEvents.length === 0)\n    })\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/events_view_switcher_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['previewView', 'listView', 'previewButton', 'listButton']\n  static values = { storageKey: { type: String, default: 'events-view-preference' } }\n\n  connect () {\n    const savedView = window.localStorage.getItem(this.storageKeyValue) || 'preview'\n    this.switchTo(savedView)\n  }\n\n  showPreview () {\n    this.switchTo('preview')\n  }\n\n  showList () {\n    this.switchTo('list')\n  }\n\n  switchTo (view) {\n    window.localStorage.setItem(this.storageKeyValue, view)\n\n    if (view === 'preview') {\n      this.previewViewTarget.classList.remove('hidden')\n      this.listViewTarget.classList.add('hidden')\n      this.previewButtonTarget.classList.add('tab-active')\n      this.listButtonTarget.classList.remove('tab-active')\n    } else {\n      this.previewViewTarget.classList.add('hidden')\n      this.listViewTarget.classList.remove('hidden')\n      this.previewButtonTarget.classList.remove('tab-active')\n      this.listButtonTarget.classList.add('tab-active')\n    }\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/geolocation_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['button', 'text', 'status']\n\n  locate () {\n    if (!navigator.geolocation) {\n      this.showStatus('Geolocation is not supported by your browser')\n      return\n    }\n\n    this.showStatus('Locating...')\n    this.buttonTarget.disabled = true\n    this.textTarget.textContent = 'Locating...'\n\n    navigator.geolocation.getCurrentPosition(\n      (position) => this.success(position),\n      (error) => this.error(error),\n      {\n        enableHighAccuracy: true,\n        timeout: 10000,\n        maximumAge: 300000\n      }\n    )\n  }\n\n  success (position) {\n    const { latitude, longitude } = position.coords\n    const coordinates = `${latitude},${longitude}`\n\n    this.showStatus('Found your location! Redirecting...')\n\n    window.location.href = `/locations/@${coordinates}`\n  }\n\n  error (error) {\n    this.buttonTarget.disabled = false\n    this.textTarget.textContent = 'Use My Location'\n\n    switch (error.code) {\n      case error.PERMISSION_DENIED:\n        this.showStatus('Location access was denied. Please enable location permissions in your browser settings.')\n        break\n      case error.POSITION_UNAVAILABLE:\n        this.showStatus('Location information is unavailable.')\n        break\n      case error.TIMEOUT:\n        this.showStatus('The request to get your location timed out.')\n        break\n      default:\n        this.showStatus('An unknown error occurred.')\n        break\n    }\n  }\n\n  showStatus (message) {\n    if (this.hasStatusTarget) {\n      this.statusTarget.textContent = message\n    }\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/hover_card_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport { useResize } from 'stimulus-use'\n\n// Connects to data-controller=\"hover-card\"\nexport default class extends Controller {\n  static targets = ['card']\n\n  connect () {\n    useResize(this, { element: document.body })\n  }\n\n  reveal () {\n    if (!this.hasCardTarget) return\n    if (this.revealed) return\n\n    this.revealed = true\n    this.cardTarget.hidden = false\n    this.scheduleAdjustPosition()\n  }\n\n  resize () {\n    if (this.revealed) {\n      this.cardTarget.style.transform = ''\n      this.scheduleAdjustPosition()\n    }\n  }\n\n  scheduleAdjustPosition () {\n    requestAnimationFrame(() => this.adjustPosition())\n  }\n\n  adjustPosition () {\n    const card = this.cardTarget\n    const rect = card.getBoundingClientRect()\n    const viewportWidth = window.innerWidth\n    const margin = 16\n\n    if (rect.left < margin) {\n      const offset = margin - rect.left\n      card.style.transform = `translateX(calc(-50% + ${offset}px))`\n    } else if (rect.right > viewportWidth - margin) {\n      const offset = rect.right - (viewportWidth - margin)\n      card.style.transform = `translateX(calc(-50% - ${offset}px))`\n    }\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/index.js",
    "content": "// This file is auto-generated by ./bin/rails stimulus:manifest:update\n// Run that command whenever you add a new controller or create them with\n// ./bin/rails generate stimulus controllerName\n\nimport { application } from \"./application\"\n\nimport AutoClickController from \"./auto-click_controller\"\napplication.register(\"auto-click\", AutoClickController)\n\nimport CollapsibleController from \"./collapsible_controller\"\napplication.register(\"collapsible\", CollapsibleController)\napplication.register(\"collapsible-feedback\", CollapsibleController)\n\nimport AutoSubmitController from \"./auto_submit_controller\"\napplication.register(\"auto-submit\", AutoSubmitController)\n\nimport Bridge__ButtonController from \"./bridge/button_controller\"\napplication.register(\"bridge--button\", Bridge__ButtonController)\n\nimport CopyToClipboardController from \"./copy_to_clipboard_controller\"\napplication.register(\"copy-to-clipboard\", CopyToClipboardController)\n\nimport DropdownController from \"./dropdown_controller\"\napplication.register(\"dropdown\", DropdownController)\n\nimport EventController from \"./event_controller\"\napplication.register(\"event\", EventController)\n\nimport HoverCardController from \"./hover_card_controller\"\napplication.register(\"hover-card\", HoverCardController)\n\nimport EventListController from \"./event_list_controller\"\napplication.register(\"event-list\", EventListController)\n\nimport EventsFilterController from \"./events_filter_controller\"\napplication.register(\"events-filter\", EventsFilterController)\n\nimport EventsViewSwitcherController from \"./events_view_switcher_controller\"\napplication.register(\"events-view-switcher\", EventsViewSwitcherController)\n\nimport GeolocationController from \"./geolocation_controller\"\napplication.register(\"geolocation\", GeolocationController)\n\nimport LazyLoadingController from \"./lazy_loading_controller\"\napplication.register(\"lazy-loading\", LazyLoadingController)\n\nimport MapController from \"./map_controller\"\napplication.register(\"map\", MapController)\n\nimport ModalController from \"./modal_controller\"\napplication.register(\"modal\", ModalController)\n\nimport PreserveScrollController from \"./preserve_scroll_controller\"\napplication.register(\"preserve-scroll\", PreserveScrollController)\n\nimport PronounsSelectController from \"./pronouns_select_controller\"\napplication.register(\"pronouns-select\", PronounsSelectController)\n\nimport ContentRowController from \"./content_row_controller\"\napplication.register(\"content-row\", ContentRowController)\n\nimport ScrollController from \"./scroll_controller\"\napplication.register(\"scroll\", ScrollController)\n\nimport ScrollIntoViewController from \"./scroll_into_view_controller\"\napplication.register(\"scroll-into-view\", ScrollIntoViewController)\n\nimport SplideController from \"./splide_controller\"\napplication.register(\"splide\", SplideController)\n\nimport SpotlightSearchController from \"./spotlight_search_controller\"\napplication.register(\"spotlight-search\", SpotlightSearchController)\n\nimport TabsController from \"./tabs_controller\"\napplication.register(\"tabs\", TabsController)\n\nimport TalksFilterController from \"./talks_filter_controller\"\napplication.register(\"talks-filter\", TalksFilterController)\n\nimport TalksFilterPillController from \"./talks_filter_pill_controller\"\napplication.register(\"talks-filter-pill\", TalksFilterPillController)\n\nimport TalksNavigationController from \"./talks_navigation_controller\"\napplication.register(\"talks-navigation\", TalksNavigationController)\n\nimport ToggableController from \"./toggable_controller\"\napplication.register(\"toggable\", ToggableController)\n\nimport TooltipController from \"./tooltip_controller\"\napplication.register(\"tooltip\", TooltipController)\n\nimport TopBannerController from \"./top_banner_controller\"\napplication.register(\"top-banner\", TopBannerController)\n\nimport TransitionController from \"./transition_controller\"\napplication.register(\"transition\", TransitionController)\n\nimport VideoPlayerController from \"./video_player_controller\"\napplication.register(\"video-player\", VideoPlayerController)\n\nimport WatchedTalkFormController from \"./watched_talk_form_controller\"\napplication.register(\"watched-talk-form\", WatchedTalkFormController)\n\nimport WrappedStoriesController from \"./wrapped_stories_controller\"\napplication.register(\"wrapped-stories\", WrappedStoriesController)\n"
  },
  {
    "path": "app/javascript/controllers/lazy_loading_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport { useIntersection } from 'stimulus-use'\n\n// Connects to data-controller=\"lazy-loading\"\nexport default class extends Controller {\n  static values = {\n    src: String,\n    rootMargin: { type: String, default: '300px 0px 0px 0px' }\n  }\n\n  initialize () {\n    useIntersection(this, { rootMargin: this.rootMarginValue })\n  }\n\n  appear () {\n    this.element.setAttribute('src', this.srcValue)\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/map_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport maplibregl from 'maplibre-gl'\nimport 'maplibre-gl/dist/maplibre-gl.css'\n\nexport default class extends Controller {\n  static targets = ['container', 'controls', 'timeFilter']\n\n  static values = {\n    markers: Array,\n    layers: Array,\n    selection: { type: String, default: 'checkbox' },\n    mode: { type: String, default: 'events' },\n    center: Array,\n    zoom: { type: Number, default: 0 },\n    bounds: Object\n  }\n\n  connect () {\n    const hasCenter = this.hasCenterValue && this.centerValue.length === 2\n    const hasZoom = this.hasZoomValue && this.zoomValue > 0\n\n    this.markersByLayer = {}\n    this.layerGroups = {}\n    this.markerDataMap = new Map()\n    this.layerVisibility = {}\n    this.alwaysVisibleLayers = {}\n    this.currentTimeFilter = 'all'\n    this.initialLoadComplete = false\n\n    const mapContainer = this.hasContainerTarget ? this.containerTarget : this.element\n\n    this.map = new maplibregl.Map({\n      container: mapContainer,\n      style: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',\n      center: hasCenter ? this.centerValue : [0, 20],\n      zoom: hasZoom ? this.zoomValue : 1.5\n    })\n\n    this.map.on('load', () => {\n      this.#fitToBounds()\n\n      if (this.hasLayersValue && this.layersValue.length > 0) {\n        this.#loadLayers()\n        this.#initTimeFilter()\n      } else {\n        this.#loadMarkers()\n      }\n    })\n  }\n\n  #initTimeFilter () {\n    if (this.hasTimeFilterTarget) {\n      const checkedInput = this.timeFilterTarget.querySelector('input:checked')\n\n      if (checkedInput) {\n        this.currentTimeFilter = checkedInput.dataset.timeFilter || 'all'\n      }\n    }\n\n    this.#applyTimeFilter()\n    this.initialLoadComplete = true\n  }\n\n  toggleLayer (event) {\n    const layerId = event.target.dataset.layerId\n    const visible = event.target.checked\n\n    this.layerVisibility[layerId] = visible\n\n    this.#applyTimeFilter()\n    this.#updateButtonState(event.target)\n  }\n\n  filterByTime (event) {\n    const filter = event.target.dataset.timeFilter\n    this.currentTimeFilter = filter\n\n    this.#applyTimeFilter()\n\n    const controls = event.target.closest('[data-map-target=\"timeFilter\"]')\n\n    if (controls) {\n      controls.querySelectorAll('input[type=\"radio\"]').forEach((input) => {\n        this.#updateButtonState(input)\n      })\n    }\n  }\n\n  #applyTimeFilter () {\n    const filter = this.currentTimeFilter || 'all'\n    const visibleBounds = new maplibregl.LngLatBounds()\n    const layerFilteredCounts = {}\n\n    let hasVisibleMarkers = false\n\n    Object.entries(this.markersByLayer).forEach(([layerId, markers]) => {\n      layerFilteredCounts[layerId] = 0\n\n      const layerData = this.layersValue.find((l) => l.id === layerId)\n      const layerVisible = this.layerVisibility[layerId] !== false\n      const alwaysVisible = layerData?.alwaysVisible === true\n\n      markers.forEach((marker) => {\n        const markerData = this.markerDataMap.get(marker)\n        if (!markerData) return\n\n        const filteredEvents = this.#filterEventsByTime(markerData.events, filter)\n        const isVisible = (layerVisible || alwaysVisible) && filteredEvents.length > 0\n\n        layerFilteredCounts[layerId] += filteredEvents.length\n\n        const element = marker.getElement()\n        element.style.display = isVisible ? '' : 'none'\n\n        if (markerData.popup && filteredEvents.length > 0) {\n          markerData.popup.setDOMContent(this.#html`${this.#popupTemplate(filteredEvents)}`)\n        }\n\n        if (isVisible) {\n          const newElement = this.#createMarkerElement(filteredEvents)\n          element.innerHTML = newElement.innerHTML\n\n          if (layerVisible) {\n            visibleBounds.extend([markerData.longitude, markerData.latitude])\n            hasVisibleMarkers = true\n          }\n        }\n      })\n    })\n\n    this.#updateLayerBadgeCounts(layerFilteredCounts)\n\n    const skipFitOnInit = !this.initialLoadComplete && this.hasBoundsValue\n    if (hasVisibleMarkers && !skipFitOnInit) {\n      this.#fitToVisibleBounds(visibleBounds)\n    }\n  }\n\n  #updateLayerBadgeCounts (counts) {\n    if (this.hasControlsTarget) {\n      this.controlsTarget.querySelectorAll('input[data-layer-id]').forEach((input) => {\n        const layerId = input.dataset.layerId\n        const count = counts[layerId] || 0\n        const badge = input.closest('label')?.querySelector('.badge')\n\n        if (badge) {\n          badge.textContent = count\n        }\n      })\n    }\n  }\n\n  #filterEventsByTime (events, filter) {\n    if (filter === 'all') return events\n    if (filter === 'upcoming') return events.filter((e) => e.upcoming)\n    if (filter === 'past') return events.filter((e) => !e.upcoming)\n\n    return events\n  }\n\n  #fitToVisibleBounds (bounds) {\n    if (!bounds.isEmpty()) {\n      const sw = bounds.getSouthWest()\n      const ne = bounds.getNorthEast()\n\n      if (sw.lng === ne.lng && sw.lat === ne.lat) {\n        this.map.easeTo({\n          center: [sw.lng, sw.lat],\n          zoom: 5,\n          duration: 500\n        })\n      } else {\n        this.map.fitBounds(bounds, {\n          padding: 50,\n          maxZoom: 10,\n          duration: 500\n        })\n      }\n    }\n  }\n\n  selectLayer (event) {\n    const selectedLayerId = event.target.dataset.layerId\n    const selectedGroup = this.layerGroups[selectedLayerId]\n\n    Object.keys(this.markersByLayer).forEach((layerId) => {\n      const layerGroup = this.layerGroups[layerId]\n\n      if (layerGroup === selectedGroup) {\n        this.layerVisibility[layerId] = layerId === selectedLayerId\n      }\n    })\n\n    this.#applyTimeFilter()\n\n    const selectedLayer = this.layersValue.find((layer) => layer.id === selectedLayerId)\n\n    if (selectedLayer?.bounds) {\n      this.#fitToLayerBounds(selectedLayer.bounds)\n    } else if (selectedLayer?.cityPin) {\n      this.map.easeTo({\n        center: [selectedLayer.cityPin.longitude, selectedLayer.cityPin.latitude],\n        zoom: 10,\n        duration: 500\n      })\n    }\n\n    const controls = event.target.closest('[data-map-target=\"controls\"]')\n\n    if (controls) {\n      controls.querySelectorAll('input[type=\"radio\"]').forEach((input) => {\n        this.#updateButtonState(input)\n      })\n    }\n  }\n\n  #fitToLayerBounds (bounds) {\n    if (!bounds?.southwest || !bounds?.northeast) return\n\n    this.map.fitBounds(\n      [bounds.southwest, bounds.northeast],\n      { padding: 20, duration: 500 }\n    )\n  }\n\n  #updateLayerVisibility (layerId, visible) {\n    const markers = this.markersByLayer[layerId] || []\n\n    markers.forEach((marker) => {\n      const element = marker.getElement()\n\n      element.style.display = visible ? '' : 'none'\n    })\n  }\n\n  #updateButtonState (input) {\n    const label = input.closest('label')\n    if (!label) return\n\n    const badge = label.querySelector('.badge')\n\n    if (input.checked) {\n      label.classList.add('btn-primary', 'text-primary-content')\n      label.classList.remove('btn-ghost')\n\n      if (badge) {\n        badge.classList.add('bg-white', 'text-primary')\n        badge.classList.remove('badge-ghost')\n      }\n    } else {\n      label.classList.remove('btn-primary', 'text-primary-content')\n      label.classList.add('btn-ghost')\n\n      if (badge) {\n        badge.classList.remove('bg-white', 'text-primary')\n        badge.classList.add('badge-ghost')\n      }\n    }\n  }\n\n  #loadLayers () {\n    const hasCenter = this.hasCenterValue && this.centerValue.length === 2\n    const hasZoom = this.hasZoomValue && this.zoomValue > 0\n    const hasBounds = this.hasBoundsValue && this.boundsValue.southwest && this.boundsValue.northeast\n    const visibleBounds = new maplibregl.LngLatBounds()\n\n    let visibleMarkerCount = 0\n    let visibleLayerWithBounds = null\n\n    this.alwaysVisibleLayers = {}\n    this.cityPinMarker = null\n\n    this.layersValue.forEach((layer) => {\n      const layerId = layer.id\n      const visible = layer.visible !== false\n      const alwaysVisible = layer.alwaysVisible === true\n\n      this.markersByLayer[layerId] = []\n      this.layerGroups[layerId] = layer.group || null\n      this.layerVisibility[layerId] = visible\n      this.alwaysVisibleLayers[layerId] = alwaysVisible\n\n      if (visible && layer.bounds) {\n        visibleLayerWithBounds = layer.bounds\n      }\n\n      if (layer.cityPin) {\n        const { longitude, latitude, name } = layer.cityPin\n        const element = this.#createCityPinElement(name)\n        const popup = this.#createCityPinPopup(name)\n\n        this.cityPinMarker = new maplibregl.Marker({ element, anchor: 'bottom' })\n          .setLngLat([longitude, latitude])\n          .setPopup(popup)\n          .addTo(this.map)\n      }\n\n      layer.markers.forEach(({ longitude, latitude, events }) => {\n        const element = this.#createMarkerElement(events)\n        const popup = this.#createPopup(events)\n\n        if (!visible && !alwaysVisible) {\n          element.style.display = 'none'\n        }\n\n        const marker = new maplibregl.Marker({ element, anchor: 'center' })\n          .setLngLat([longitude, latitude])\n          .setPopup(popup)\n          .addTo(this.map)\n\n        this.markersByLayer[layerId].push(marker)\n        this.markerDataMap.set(marker, { events, longitude, latitude, popup })\n\n        if (visible) {\n          visibleBounds.extend([longitude, latitude])\n          visibleMarkerCount++\n        }\n      })\n    })\n\n    if (hasBounds || (hasCenter && hasZoom)) return\n\n    const cityPinLayer = this.layersValue.find((l) => l.cityPin)\n    const cityPin = cityPinLayer?.cityPin\n\n    if (visibleMarkerCount === 1) {\n      const visibleLayer = this.layersValue.find((l) => l.visible !== false && l.markers.length > 0)\n\n      if (visibleLayer) {\n        const firstMarker = visibleLayer.markers[0]\n        this.map.setCenter([firstMarker.longitude, firstMarker.latitude])\n        this.map.setZoom(5)\n      }\n    } else if (visibleMarkerCount > 1) {\n      this.map.fitBounds(visibleBounds, {\n        padding: 50,\n        maxZoom: 10\n      })\n    } else if (visibleMarkerCount === 0 && cityPin) {\n      this.map.setCenter([cityPin.longitude, cityPin.latitude])\n      this.map.setZoom(10)\n    } else if (visibleMarkerCount === 0 && visibleLayerWithBounds) {\n      this.#fitToLayerBounds(visibleLayerWithBounds)\n    }\n  }\n\n  #fitToBounds () {\n    // When we have layers, use the visible layer's bounds instead of top-level bounds\n    if (this.hasLayersValue && this.layersValue.length > 0) {\n      const visibleLayer = this.layersValue.find((l) => l.visible !== false && l.bounds)\n      if (visibleLayer?.bounds) {\n        this.#fitToLayerBounds(visibleLayer.bounds)\n        return\n      }\n    }\n\n    if (!this.hasBoundsValue || !this.boundsValue.southwest || !this.boundsValue.northeast) return\n\n    this.map.fitBounds(\n      [this.boundsValue.southwest, this.boundsValue.northeast],\n      { padding: 20, animate: false }\n    )\n  }\n\n  #loadMarkers () {\n    if (this.markersValue.length === 0) return\n\n    if (this.modeValue === 'venue') {\n      this.#loadVenueMarkers()\n    } else {\n      this.#loadEventMarkers()\n    }\n  }\n\n  #loadEventMarkers () {\n    const hasCenter = this.hasCenterValue && this.centerValue.length === 2\n    const hasZoom = this.hasZoomValue && this.zoomValue > 0\n    const hasBounds = this.hasBoundsValue && this.boundsValue.southwest && this.boundsValue.northeast\n\n    this.markersValue.forEach(({ longitude, latitude, events }) => {\n      const element = this.#createMarkerElement(events)\n      const popup = this.#createPopup(events)\n\n      new maplibregl.Marker({ element, anchor: 'center' })\n        .setLngLat([longitude, latitude])\n        .setPopup(popup)\n        .addTo(this.map)\n    })\n\n    if (hasBounds || (hasCenter && hasZoom)) return\n\n    const bounds = new maplibregl.LngLatBounds()\n\n    this.markersValue.forEach(({ longitude, latitude }) => {\n      bounds.extend([longitude, latitude])\n    })\n\n    if (this.markersValue.length === 1) {\n      this.map.setCenter([this.markersValue[0].longitude, this.markersValue[0].latitude])\n      this.map.setZoom(5)\n    } else {\n      this.map.fitBounds(bounds, {\n        padding: 50,\n        maxZoom: 10\n      })\n    }\n  }\n\n  #loadVenueMarkers () {\n    const bounds = new maplibregl.LngLatBounds()\n\n    this.markersValue.forEach((marker) => {\n      const element = this.#createVenueMarkerElement(marker)\n      const popup = this.#createVenuePopup(marker)\n\n      new maplibregl.Marker({ element, anchor: 'bottom' })\n        .setLngLat([marker.longitude, marker.latitude])\n        .setPopup(popup)\n        .addTo(this.map)\n\n      bounds.extend([marker.longitude, marker.latitude])\n    })\n\n    if (this.markersValue.length === 1) {\n      this.map.setCenter([this.markersValue[0].longitude, this.markersValue[0].latitude])\n      this.map.setZoom(15)\n    } else {\n      this.map.fitBounds(bounds, {\n        padding: 50,\n        maxZoom: 15\n      })\n    }\n  }\n\n  disconnect () {\n    if (this.map) {\n      this.map.remove()\n    }\n  }\n\n  #createMarkerElement (events) {\n    return events.length === 1\n      ? this.#html`${this.#singleMarkerTemplate(events[0])}`\n      : this.#html`${this.#groupMarkerTemplate(events)}`\n  }\n\n  #createPopup (events) {\n    return new maplibregl.Popup({\n      offset: 25,\n      closeButton: false\n    }).setDOMContent(this.#html`${this.#popupTemplate(events)}`)\n  }\n\n  #html (strings, ...values) {\n    const template = document.createElement('template')\n    template.innerHTML = String.raw(strings, ...values).trim()\n    return template.content.firstElementChild\n  }\n\n  #singleMarkerTemplate (event) {\n    return `\n      <div class=\"event-marker cursor-pointer\">\n        <div class=\"avatar\">\n          <div class=\"w-8 rounded-full ring ring-base-100\">\n            <img src=\"${event.avatar}\" alt=\"${event.name}\" />\n          </div>\n        </div>\n      </div>\n    `\n  }\n\n  #groupMarkerTemplate (events) {\n    const displayEvents = events.slice(0, 3)\n    const remaining = events.length - 3\n\n    return `\n      <div class=\"event-marker cursor-pointer\">\n        <div class=\"avatar-group -space-x-4 rtl:space-x-reverse\">\n          ${displayEvents\n        .map(\n          (event) => `\n            <div class=\"avatar\">\n              <div class=\"w-6 rounded-full ring ring-base-100\">\n                <img src=\"${event.avatar}\" alt=\"${event.name}\" />\n              </div>\n            </div>\n          `\n        )\n        .join('')}\n          ${remaining > 0\n        ? `\n            <div class=\"avatar placeholder\">\n              <div class=\"bg-neutral text-neutral-content w-6 rounded-full ring ring-base-100\">\n                <span class=\"text-xs\">+${remaining}</span>\n              </div>\n            </div>\n          `\n        : ''\n      }\n        </div>\n      </div>\n    `\n  }\n\n  #popupTemplate (events) {\n    const location = events[0]?.location\n\n    return `\n      <div class=\"flex flex-col max-h-48 overflow-y-auto pr-2 gap-2\">\n        ${location ? `<div class=\"text-xs text-gray-500 font-medium\">${location}</div>` : ''}\n        ${events\n        .map(\n          (event) => `\n          <a href=\"${event.url}\" data-turbo-frame=\"_top\" class=\"flex items-center gap-2 hover:underline\">\n            <img src=\"${event.avatar}\" alt=\"${event.name}\" class=\"w-6 h-6 rounded-full\" />\n            <span class=\"font-semibold\">${event.name}</span>\n          </a>\n        `\n        )\n        .join('')}\n      </div>\n    `\n  }\n\n  #createCityPinElement (name) {\n    return this.#html`\n      <div class=\"city-pin cursor-pointer flex flex-col items-center\">\n        <svg width=\"24\" height=\"36\" viewBox=\"0 0 24 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" class=\"drop-shadow-lg\">\n          <path d=\"M12 0C5.373 0 0 5.373 0 12c0 9 12 24 12 24s12-15 12-24c0-6.627-5.373-12-12-12z\" fill=\"#DC2626\"/>\n          <circle cx=\"12\" cy=\"12\" r=\"5\" fill=\"white\"/>\n        </svg>\n      </div>\n    `\n  }\n\n  #createCityPinPopup (name) {\n    return new maplibregl.Popup({\n      offset: 25,\n      closeButton: false\n    }).setDOMContent(this.#html`\n      <div class=\"flex flex-col gap-1 p-1\">\n        <div class=\"font-semibold\">${name}</div>\n      </div>\n    `)\n  }\n\n  #createVenueMarkerElement (marker) {\n    const colors = {\n      venue: { bg: 'bg-primary', text: 'text-primary-content' },\n      hotel: { bg: 'bg-secondary', text: 'text-secondary-content' },\n      location: { bg: 'bg-accent', text: 'text-accent-content' }\n    }\n    const icons = {\n      venue: '📍',\n      hotel: '🏨',\n      location: '📌'\n    }\n    const { bg, text } = colors[marker.kind] || colors.location\n    const icon = icons[marker.kind] || '📌'\n\n    return this.#html`\n      <div class=\"venue-marker cursor-pointer flex flex-col items-center\">\n        <div class=\"w-8 h-8 ${bg} ${text} rounded-full flex items-center justify-center shadow-lg border-2 border-white text-base\">\n          ${icon}\n        </div>\n      </div>\n    `\n  }\n\n  #createVenuePopup (marker) {\n    return new maplibregl.Popup({\n      offset: 25,\n      closeButton: false\n    }).setDOMContent(this.#html`${this.#venuePopupTemplate(marker)}`)\n  }\n\n  #venuePopupTemplate (marker) {\n    const kindLabel = marker.location_kind || (marker.kind === 'venue' ? 'Venue' : marker.kind === 'hotel' ? 'Hotel' : 'Location')\n\n    return `\n      <div class=\"flex flex-col gap-1 p-1\">\n        <div class=\"text-xs text-gray-500 font-medium uppercase\">${kindLabel}</div>\n        <div class=\"font-semibold\">${marker.name}</div>\n        ${marker.address ? `<div class=\"text-sm text-gray-600\">${marker.address}</div>` : ''}\n        ${marker.distance ? `<div class=\"text-xs text-gray-500\">${marker.distance}</div>` : ''}\n      </div>\n    `\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/modal_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport { useClickOutside } from 'stimulus-use'\n\n// Connects to data-controller=\"modal\"\nexport default class extends Controller {\n  static values = {\n    open: Boolean\n  }\n\n  static targets = ['modalBox']\n\n  initialize () {\n    useClickOutside(this, { element: this.modalBoxTarget })\n    if (this.toggle) {\n      this.toggle.addEventListener('click', () => {\n        this.open()\n      })\n    }\n  }\n\n  connect () {\n    if (this.openValue) {\n      this.open()\n    }\n  }\n\n  disconnect () {\n    this.close()\n  }\n\n  clickOutside (event) {\n    this.close()\n  }\n\n  open () {\n    this.element.showModal()\n    this.dispatch('open')\n  }\n\n  close (e) {\n    e?.preventDefault()\n\n    this.element.close()\n  }\n\n  // getters\n  get toggle () {\n    return document.querySelector(`[data-toggle=\"modal\"][data-target=\"${this.element.id}\"]`)\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/preserve_scroll_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport { nextFrame } from '../helpers/timing_helpers'\n\n// Connects to data-controller=\"preserve-scroll\"\nexport default class extends Controller {\n  async connect () {\n    if (this.scrollTop) {\n      await nextFrame() // we need to wait for the next frame to ensure the scroll position is set\n      window.scrollTo(0, this.scrollTop)\n\n      // remove the scrollTop from the url params\n      const url = new URL(window.location)\n      url.searchParams.delete('scroll_top')\n      window.Turbo.navigator.history.replace(url)\n    }\n  }\n\n  updateLinkBackToWithScrollPosition (e) {\n    // usually invoked on an hover event, it will rewrite the back_to url with the current scroll position\n    const link = e.currentTarget.href\n    if (!link) return\n\n    const url = new URL(link)\n    const urlParams = url.searchParams\n    const backTo = urlParams.get('back_to')\n    if (!backTo) return\n\n    // Get current scroll position\n    const scrollY = parseInt(window.scrollY)\n\n    // Create a URL object to handle the backTo path's parameters\n    const backToUrl = new URL(backTo, window.location.origin)\n\n    // Set or update the scroll_top parameter\n    backToUrl.searchParams.set('scroll_top', scrollY)\n\n    // Update the back_to parameter with the modified path + query\n    urlParams.set('back_to', backToUrl.pathname + backToUrl.search)\n\n    // Update the href with the modified URL\n    e.currentTarget.href = url.toString()\n  }\n\n  get scrollTop () {\n    // from url params scroll_top\n    const urlParams = new URLSearchParams(window.location.search)\n    return urlParams.get('scroll_top')\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/pronouns_select_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = [\n    'type',\n    'input'\n  ]\n\n  connect () {\n    this.updateInputVisibility()\n  }\n\n  change () {\n    if (this.typeTarget.value === 'custom') {\n      this.inputTarget.value = ''\n    } else {\n      this.inputTarget.value = this.typeTarget.selectedOptions[0]?.textContent || ''\n    }\n\n    this.updateInputVisibility()\n  }\n\n  updateInputVisibility () {\n    if (this.typeTarget.value === 'custom') {\n      this.inputTarget.classList.remove('hidden')\n    } else {\n      this.inputTarget.classList.add('hidden')\n    }\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/scroll_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['container', 'gradient', 'card']\n\n  connect () {\n    this.checkScroll()\n  }\n\n  checkScroll () {\n    if (this.isAtEnd) {\n      this.gradientTarget.classList.add('hidden')\n    } else {\n      this.gradientTarget.classList.remove('hidden')\n    }\n  }\n\n  get isAtEnd () {\n    return this.containerTarget.scrollLeft + this.containerTarget.offsetWidth >= this.containerTarget.scrollWidth - 1\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/scroll_into_view_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\n// this controller is used to scroll into the center to the active target\n// if no active target is found, it will scroll into the center of the element\n// Connects to data-controller=\"scroll-into-view\"\nexport default class extends Controller {\n  static targets = ['active']\n\n  connect () {\n    this.elementToScroll.scrollIntoView({ block: 'center' })\n  }\n\n  get elementToScroll () {\n    return this.hasActiveTarget ? this.activeTarget : this.element\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/splide_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nimport '@splidejs/splide/css'\nimport { Splide } from '@splidejs/splide'\n\nexport default class extends Controller {\n  connect () {\n    this.#reset()\n\n    if (!this.splide) {\n      this.splide = new Splide(this.element, this.splideOptions)\n      this.splide.mount()\n\n      if (this.#shouldUpdateNavbar()) {\n        this.splide.on('moved', () => {\n          this.#updateNavbarColors()\n        })\n\n        this.#updateNavbarColors()\n      }\n    }\n\n    this.hiddenSlides.forEach(slide =>\n      slide.classList.remove('hidden')\n    )\n  }\n\n  disconnect () {\n    this.splide.destroy(true)\n    this.splide = undefined\n  }\n\n  #reset () {\n    this.element.querySelectorAll('.splide__pagination').forEach(slide => slide.remove())\n  }\n\n  #shouldUpdateNavbar () {\n    return document.body.classList.contains('home-page')\n  }\n\n  #updateNavbarColors () {\n    const activeSlide = this.element.querySelector('.splide__slide.is-active')\n    if (!activeSlide) return\n\n    const featuredColor = activeSlide.dataset.featuredColor\n    const featuredBackground = activeSlide.dataset.featuredBackground\n\n    if (!featuredColor || !featuredBackground) return\n\n    document.documentElement.style.setProperty('--featured-color', featuredColor)\n    document.documentElement.style.setProperty('--featured-background', featuredBackground)\n\n    const themeColorMeta = document.querySelector('meta[name=\"theme-color\"][data-featured-theme-color]')\n\n    if (themeColorMeta) {\n      themeColorMeta.setAttribute('content', featuredBackground)\n    }\n  }\n\n  get splideOptions () {\n    return {\n      type: 'fade',\n      rewind: true,\n      perPage: 1,\n      autoplay: true,\n      speed: 0\n    }\n  }\n\n  get hiddenSlides () {\n    return Array.from(\n      this.element.querySelectorAll('.splide__slide > .hidden')\n    )\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/spotlight_search_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport { useDebounce } from 'stimulus-use'\nimport Combobox from '@github/combobox-nav'\nimport { get } from '@rails/request.js'\n\n// Connects to data-controller=\"spotlight-search\"\nexport default class extends Controller {\n  static targets = ['searchInput', 'form', 'searchResults', 'talksSearchResults',\n    'speakersSearchResults', 'eventsSearchResults', 'topicsSearchResults', 'seriesSearchResults',\n    'organizationsSearchResults', 'locationsSearchResults', 'languagesSearchResults', 'kindsSearchResults', 'allSearchResults', 'searchQuery', 'loading', 'clear', 'searchBackendBadge', 'backendToggle', 'sqliteBadge', 'typesenseBadge']\n\n  static debounces = ['search']\n  static values = {\n    urlSpotlightTalks: String,\n    urlSpotlightSpeakers: String,\n    urlSpotlightEvents: String,\n    urlSpotlightTopics: String,\n    urlSpotlightSeries: String,\n    urlSpotlightOrganizations: String,\n    urlSpotlightLocations: String,\n    urlSpotlightLanguages: String,\n    urlSpotlightKinds: String,\n    mainResourcePath: String,\n    defaultBackend: String\n  }\n\n  // lifecycle\n  initialize () {\n    useDebounce(this, { wait: 100 })\n    this.dialog.addEventListener('modal:open', this.appear.bind(this))\n    this.combobox = new Combobox(this.searchInputTarget, this.searchResultsTarget)\n    this.combobox.start()\n    this.defaultsLoaded = false\n    this.#initBackendToggle()\n  }\n\n  connect () {}\n\n  disconnect () {\n    this.dialog.removeEventListener('modal:open', this.appear.bind(this))\n    this.combobox.stop()\n  }\n\n  // actions\n\n  async search () {\n    const query = this.searchInputTarget.value\n\n    if (query.length === 0) {\n      this.#clearResults()\n      this.#loadDefaults()\n      this.#toggleClearing()\n      return\n    }\n\n    if (this.defaultsAbortController) {\n      this.defaultsAbortController.abort()\n    }\n\n    this.allSearchResultsTarget.classList.remove('hidden')\n    this.searchQueryTarget.innerHTML = query\n    this.loadingTarget.classList.remove('hidden')\n    this.clearTarget.classList.add('hidden')\n\n    const searchPromises = []\n\n    // search talks and abort previous requests\n    if (this.hasUrlSpotlightTalksValue) {\n      if (this.talksAbortController) {\n        this.talksAbortController.abort()\n      }\n      this.talksAbortController = new AbortController()\n      searchPromises.push(this.#handleSearch(this.urlSpotlightTalksValue, query, this.talksAbortController))\n    }\n\n    // search speakers and abort previous requests\n    if (this.hasUrlSpotlightSpeakersValue) {\n      if (this.speakersAbortController) {\n        this.speakersAbortController.abort()\n      }\n      this.speakersAbortController = new AbortController()\n      searchPromises.push(this.#handleSearch(this.urlSpotlightSpeakersValue, query, this.speakersAbortController))\n    }\n\n    // search events and abort previous requests\n    if (this.hasUrlSpotlightEventsValue) {\n      if (this.eventsAbortController) {\n        this.eventsAbortController.abort()\n      }\n      this.eventsAbortController = new AbortController()\n      searchPromises.push(this.#handleSearch(this.urlSpotlightEventsValue, query, this.eventsAbortController))\n    }\n\n    // search topics and abort previous requests\n    if (this.hasUrlSpotlightTopicsValue) {\n      if (this.topicsAbortController) {\n        this.topicsAbortController.abort()\n      }\n      this.topicsAbortController = new AbortController()\n      searchPromises.push(this.#handleSearch(this.urlSpotlightTopicsValue, query, this.topicsAbortController))\n    }\n\n    // search series and abort previous requests\n    if (this.hasUrlSpotlightSeriesValue) {\n      if (this.seriesAbortController) {\n        this.seriesAbortController.abort()\n      }\n      this.seriesAbortController = new AbortController()\n      searchPromises.push(this.#handleSearch(this.urlSpotlightSeriesValue, query, this.seriesAbortController))\n    }\n\n    // search organizations and abort previous requests\n    if (this.hasUrlSpotlightOrganizationsValue) {\n      if (this.organizationsAbortController) {\n        this.organizationsAbortController.abort()\n      }\n      this.organizationsAbortController = new AbortController()\n      searchPromises.push(this.#handleSearch(this.urlSpotlightOrganizationsValue, query, this.organizationsAbortController))\n    }\n\n    // search locations and abort previous requests\n    if (this.hasUrlSpotlightLocationsValue) {\n      if (this.locationsAbortController) {\n        this.locationsAbortController.abort()\n      }\n      this.locationsAbortController = new AbortController()\n      searchPromises.push(this.#handleSearch(this.urlSpotlightLocationsValue, query, this.locationsAbortController))\n    }\n\n    // search languages and abort previous requests\n    if (this.hasUrlSpotlightLanguagesValue) {\n      if (this.languagesAbortController) {\n        this.languagesAbortController.abort()\n      }\n      this.languagesAbortController = new AbortController()\n      searchPromises.push(this.#handleSearch(this.urlSpotlightLanguagesValue, query, this.languagesAbortController))\n    }\n\n    // search kinds and abort previous requests\n    if (this.hasUrlSpotlightKindsValue) {\n      if (this.kindsAbortController) {\n        this.kindsAbortController.abort()\n      }\n      this.kindsAbortController = new AbortController()\n      searchPromises.push(this.#handleSearch(this.urlSpotlightKindsValue, query, this.kindsAbortController))\n    }\n\n    try {\n      await Promise.all(searchPromises)\n    } finally {\n      this.loadingTarget.classList.add('hidden')\n      this.#toggleClearing()\n    }\n  }\n\n  navigate () {\n    if (this.selectedOption?.matches('a, [href]')) {\n      this.selectedOption.click()\n    } else {\n      requestAnimationFrame(() => {\n        const url = new URL(this.mainResourcePathValue, window.location.origin)\n        url.searchParams.set('s', this.searchInputTarget.value)\n        window.location.href = url.toString()\n      })\n    }\n  }\n\n  clear () {\n    this.searchInputTarget.value = ''\n    this.#clearResults()\n    this.#loadDefaults()\n    this.#toggleClearing()\n    this.searchInputTarget.focus()\n  }\n\n  setBackend (event) {\n    const backend = event.currentTarget.dataset.backend\n    this.searchBackend = backend\n\n    this.#updateBackendBadges(backend)\n    this.#clearResults()\n    this.#loadDefaults()\n\n    if (this.searchInputTarget.value.length > 0) {\n      this.search()\n    }\n  }\n\n  // callbacks\n  appear () {\n    this.searchInputTarget.focus()\n    this.#loadDefaults()\n  }\n\n  // private\n  async #loadDefaults () {\n    if (this.defaultsAbortController) {\n      this.defaultsAbortController.abort()\n    }\n\n    this.defaultsAbortController = new AbortController()\n    this.allSearchResultsTarget.classList.add('hidden')\n\n    const defaultPromises = []\n\n    if (this.hasUrlSpotlightTalksValue) {\n      defaultPromises.push(get(this.urlSpotlightTalksValue, {\n        responseKind: 'turbo-stream',\n        signal: this.defaultsAbortController.signal\n      }).catch(() => {}))\n    }\n\n    if (this.hasUrlSpotlightSpeakersValue) {\n      defaultPromises.push(get(this.urlSpotlightSpeakersValue, {\n        responseKind: 'turbo-stream',\n        signal: this.defaultsAbortController.signal\n      }).catch(() => {}))\n    }\n\n    if (this.hasUrlSpotlightEventsValue) {\n      defaultPromises.push(get(this.urlSpotlightEventsValue, {\n        responseKind: 'turbo-stream',\n        signal: this.defaultsAbortController.signal\n      }).catch(() => {}))\n    }\n\n    await Promise.all(defaultPromises)\n    this.defaultsLoaded = true\n  }\n\n  #handleSearch (url, query, abortController) {\n    const params = { s: query }\n    if (this.searchBackend) {\n      params.search_backend = this.searchBackend\n    }\n\n    return get(url, {\n      query: params,\n      responseKind: 'turbo-stream',\n      headers: {\n        'Turbo-Frame': 'talks_search_results'\n      },\n      signal: abortController.signal\n    }).then(response => {\n      if (this.hasSearchBackendBadgeTarget) {\n        const backend = response.headers.get('X-Search-Backend')\n\n        if (backend === 'sqlite_fts') {\n          this.searchBackendBadgeTarget.classList.remove('hidden')\n        } else {\n          this.searchBackendBadgeTarget.classList.add('hidden')\n        }\n      }\n    }).catch(error => {\n      if (error.name !== 'AbortError') {\n        throw error\n      }\n    })\n  }\n\n  #clearResults () {\n    if (this.defaultsAbortController) {\n      this.defaultsAbortController.abort()\n    }\n\n    if (this.talksAbortController) {\n      this.talksAbortController.abort()\n    }\n\n    if (this.speakersAbortController) {\n      this.speakersAbortController.abort()\n    }\n\n    if (this.eventsAbortController) {\n      this.eventsAbortController.abort()\n    }\n\n    if (this.topicsAbortController) {\n      this.topicsAbortController.abort()\n    }\n\n    if (this.seriesAbortController) {\n      this.seriesAbortController.abort()\n    }\n\n    if (this.organizationsAbortController) {\n      this.organizationsAbortController.abort()\n    }\n\n    if (this.locationsAbortController) {\n      this.locationsAbortController.abort()\n    }\n\n    if (this.languagesAbortController) {\n      this.languagesAbortController.abort()\n    }\n\n    if (this.kindsAbortController) {\n      this.kindsAbortController.abort()\n    }\n\n    this.talksSearchResultsTarget.innerHTML = ''\n    this.speakersSearchResultsTarget.innerHTML = ''\n    this.eventsSearchResultsTarget.innerHTML = ''\n\n    if (this.hasTopicsSearchResultsTarget) {\n      this.topicsSearchResultsTarget.innerHTML = ''\n      this.topicsSearchResultsTarget.classList.add('hidden')\n    }\n\n    if (this.hasSeriesSearchResultsTarget) {\n      this.seriesSearchResultsTarget.innerHTML = ''\n      this.seriesSearchResultsTarget.classList.add('hidden')\n    }\n\n    if (this.hasOrganizationsSearchResultsTarget) {\n      this.organizationsSearchResultsTarget.innerHTML = ''\n      this.organizationsSearchResultsTarget.classList.add('hidden')\n    }\n\n    if (this.hasLocationsSearchResultsTarget) {\n      this.locationsSearchResultsTarget.innerHTML = ''\n      this.locationsSearchResultsTarget.classList.add('hidden')\n    }\n\n    if (this.hasLanguagesSearchResultsTarget) {\n      this.languagesSearchResultsTarget.innerHTML = ''\n      this.languagesSearchResultsTarget.classList.add('hidden')\n    }\n\n    if (this.hasKindsSearchResultsTarget) {\n      this.kindsSearchResultsTarget.innerHTML = ''\n      this.kindsSearchResultsTarget.classList.add('hidden')\n    }\n\n    this.allSearchResultsTarget.classList.add('hidden')\n\n    if (this.hasSearchBackendBadgeTarget) {\n      this.searchBackendBadgeTarget.classList.add('hidden')\n    }\n  }\n\n  #toggleClearing () {\n    const query = this.searchInputTarget.value\n    if (query.length === 0) {\n      this.clearTarget.classList.add('hidden')\n    } else {\n      this.clearTarget.classList.remove('hidden')\n    }\n  }\n\n  #initBackendToggle () {\n    if (!this.hasSqliteBadgeTarget) return\n\n    this.searchBackend = this.defaultBackendValue || null\n  }\n\n  #updateBackendBadges (backend) {\n    if (!this.hasSqliteBadgeTarget) return\n\n    if (backend === 'sqlite_fts') {\n      this.sqliteBadgeTarget.classList.add('badge-warning')\n      this.sqliteBadgeTarget.classList.remove('badge-ghost')\n      this.typesenseBadgeTarget.classList.remove('badge-primary')\n      this.typesenseBadgeTarget.classList.add('badge-ghost')\n    } else if (backend === 'typesense') {\n      this.typesenseBadgeTarget.classList.add('badge-primary')\n      this.typesenseBadgeTarget.classList.remove('badge-ghost')\n      this.sqliteBadgeTarget.classList.remove('badge-warning')\n      this.sqliteBadgeTarget.classList.add('badge-ghost')\n    } else {\n      this.sqliteBadgeTarget.classList.remove('badge-warning')\n      this.sqliteBadgeTarget.classList.add('badge-ghost')\n      this.typesenseBadgeTarget.classList.remove('badge-primary')\n      this.typesenseBadgeTarget.classList.add('badge-ghost')\n    }\n  }\n\n  // getters\n  get dialog () {\n    return this.element.closest('dialog')\n  }\n\n  get selectedOption () {\n    return this.searchResultsTarget.querySelector('[aria-selected=\"true\"]')\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/tabs_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\n// Connects to data-controller=\"tabs\"\nexport default class extends Controller {\n  static values = { activeIndex: { type: Number, default: 0 } }\n\n  initialize () {\n    if (!this.hasActiveIndexValue) {\n      const index = Array.from(this.tabs).findIndex(tab => tab.getAttribute('aria-selected') === 'true' || tab.classList.contains('tab-active'))\n      this.activeIndexValue = index\n    }\n  }\n\n  showPanel (e) {\n    const index = Array.from(this.tabs).indexOf(e.currentTarget)\n    this.activeIndexValue = index\n  }\n\n  activeIndexValueChanged () {\n    this.#togglePanel()\n  }\n\n  // private\n\n  #togglePanel () {\n    this.tabs.forEach(tab => {\n      const isSelected = tab === this.activeTab\n      tab.setAttribute('aria-selected', isSelected)\n      document.startViewTransition(() => {\n        tab.classList.toggle('tab-active', isSelected)\n      })\n    })\n  }\n\n  get tabPanels () {\n    return this.element.querySelectorAll('[role=\"tabpanel\"]')\n  }\n\n  get tabs () {\n    return this.element.querySelectorAll('[role=\"tab\"]')\n  }\n\n  get activeTab () {\n    return this.tabs[this.activeIndexValue]\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/talks_filter_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['toggle', 'count']\n  static values = {\n    hideWatched: { type: Boolean, default: false }\n  }\n\n  connect () {\n    this.updateVisibility()\n  }\n\n  toggle () {\n    this.hideWatchedValue = !this.hideWatchedValue\n  }\n\n  hideWatchedValueChanged () {\n    this.updateVisibility()\n  }\n\n  get talks () {\n    return this.element.querySelectorAll('[data-watched]')\n  }\n\n  updateVisibility () {\n    let hiddenCount = 0\n\n    this.talks.forEach((talk) => {\n      const isWatched = talk.dataset.watched === 'true'\n\n      if (this.hideWatchedValue && isWatched) {\n        talk.classList.add('hidden')\n        hiddenCount++\n      } else {\n        talk.classList.remove('hidden')\n      }\n    })\n\n    if (this.hasCountTarget) {\n      this.countTarget.textContent = hiddenCount\n      this.countTarget.parentElement.classList.toggle('hidden', hiddenCount === 0)\n    }\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/talks_filter_pill_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['button', 'none']\n  static classes = ['active']\n  static values = {\n    kind: {\n      type: String,\n      default: 'all'\n    },\n    language: {\n      type: String,\n      default: 'all'\n    }\n  }\n\n  selectKind (event) {\n    const target = (event.target.dataset.kindValue) ? event.target : event.target.closest('[data-kind-value]')\n\n    if (!target) return\n\n    const value = target.dataset.kindValue\n    this.kindValue = (this.kindValue === value) ? 'all' : value\n  }\n\n  selectLanguage (event) {\n    const target = (event.target.dataset.languageValue) ? event.target : event.target.closest('[data-language-value]')\n\n    if (!target) return\n\n    const value = target.dataset.languageValue\n    this.languageValue = (this.languageValue === value) ? 'all' : value\n  }\n\n  kindValueChanged () {\n    this.updateFilterResult()\n  }\n\n  languageValueChanged () {\n    this.updateFilterResult()\n  }\n\n  updateFilterResult () {\n    this.buttonTargets.forEach(button => button.classList.remove(...this.activeClasses))\n    this.buttonTargets.find(button => button.dataset.languageValue === this.languageValue)?.classList.add(...this.activeClasses)\n    this.buttonTargets.find(button => button.dataset.kindValue === this.kindValue)?.classList.add(...this.activeClasses)\n\n    document.querySelectorAll('.talk-all').forEach(talk => talk.classList.add('hidden'))\n    this.element.querySelectorAll('.count').forEach(talk => talk.classList.add('hidden'))\n\n    this.element.querySelectorAll(`.count-kind.count-language-${this.languageValue}`).forEach(talk => talk.classList.remove('hidden'))\n    this.element.querySelectorAll(`.count-language.count-kind-${this.kindValue}`).forEach(talk => talk.classList.remove('hidden'))\n\n    const matchingTalks = document.querySelectorAll(`.talk-kind-${this.kindValue}.talk-language-${this.languageValue}`)\n    matchingTalks.forEach(talk => talk.classList.remove('hidden'))\n\n    if (matchingTalks.length === 0) {\n      this.noneTarget.classList.remove('hidden')\n    } else {\n      this.noneTarget.classList.add('hidden')\n    }\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/talks_navigation_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\n// Connects to data-controller=\"talks-navigation\"\nexport default class extends Controller {\n  static targets = ['card']\n\n  connect () {\n    this.elementToScroll.scrollIntoView({ block: 'center' })\n  }\n\n  setActive (e) {\n    this.cardTargets.forEach(card => {\n      card.classList.remove('active')\n    })\n    e.currentTarget.classList.add('active')\n  }\n\n  get elementToScroll () {\n    return this.hasActiveTarget ? this.activeTarget : this.element\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/toggable_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['toggable', 'toggle']\n\n  static values = {\n    hideText: {\n      type: String,\n      default: 'hide'\n    }\n  }\n\n  connect () {\n    if (this.hasToggleTarget) {\n      this.toggleText = this.toggleTarget.textContent\n    }\n  }\n\n  toggle () {\n    this.toggleTarget.textContent = this.nextToggleText\n    this.toggableTargets.forEach(toggable => toggable.classList.toggle('hidden'))\n  }\n\n  get nextToggleText () {\n    return (this.toggleTarget.textContent === this.toggleText)\n      ? this.hideTextValue\n      : this.toggleText\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/tooltip_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nimport tippy from 'tippy.js'\nimport 'tippy.js/dist/tippy.css'\n\n// Connects to data-controller=\"tooltip\"\nexport default class extends Controller {\n  static values = {\n    content: String\n  }\n\n  connect () {\n    tippy(this.element, { content: this.contentValue })\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/top_banner_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\n// Connects to data-controller=\"top-banner\"\n\nconst ONE_MONTH = 30 * 24 * 60 * 60 * 1000 // 30 days in milliseconds\nconst COOKIE_NAME = 'top_banner_dismissed'\n\nexport default class extends Controller {\n  connect () {\n    if (!this.isDismissed) {\n      this.element.classList.remove('hidden')\n    }\n  }\n\n  dismiss () {\n    this.element.classList.add('hidden')\n    this.#setCookie(COOKIE_NAME, 'true', 1)\n  }\n\n  #setCookie (name, value, days) {\n    const expires = new Date()\n    expires.setTime(expires.getTime() + days * ONE_MONTH)\n    document.cookie =\n      name +\n      '=' +\n      encodeURIComponent(value) +\n      ';expires=' +\n      expires.toUTCString() +\n      ';path=/'\n  }\n\n  get isDismissed () {\n    return document.cookie.includes(`${COOKIE_NAME}=true`)\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/transition_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport { useTransition } from 'stimulus-use'\n\nexport default class extends Controller {\n  static values = {\n    enterActive: { type: String, default: 'transition ease-in duration-300' },\n    enterFrom: { type: String, default: 'transform opacity-0' },\n    enterTo: { type: String, default: 'transform opacity-100' },\n    leaveActive: { type: String, default: 'transition ease-in duration-300' },\n    leaveFrom: { type: String, default: 'transform opacity-100' },\n    leaveTo: { type: String, default: 'transform opacity-0' },\n    hiddenClass: { type: String, default: 'hidden' },\n    transitioned: { type: Boolean, default: false },\n    removeToClasses: { type: Boolean, default: false },\n    enterAfter: { type: Number, default: -1 },\n    leaveAfter: Number\n  }\n\n  static targets = ['content']\n\n  connect () {\n    if (this.isPreview) return\n\n    useTransition(this, {\n      element: this.elementToTransition,\n      enterActive: this.enterActiveValue,\n      enterFrom: this.enterFromValue,\n      enterTo: this.enterToValue,\n      leaveActive: this.leaveActiveValue,\n      leaveFrom: this.leaveFromValue,\n      leaveTo: this.leaveToValue,\n      hiddenClass: this.hiddenClassValue,\n      transitioned: this.transitionedValue,\n      leaveAfter: this.leaveAfterValue\n    })\n\n    if (this.enterAfterValue >= 0) {\n      setTimeout(() => {\n        this.enter()\n      }, this.enterAfterValue)\n    }\n  }\n\n  // getters\n\n  get elementToTransition () {\n    return this.hasContentTarget ? this.contentTarget : this.element\n  }\n\n  get isPreview () {\n    return document.documentElement.hasAttribute('data-turbo-preview')\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/video_player_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\nimport { useIntersection } from 'stimulus-use'\nimport Vlitejs from 'vlitejs'\nimport YouTube from 'vlitejs/providers/youtube.js'\nimport Vimeo from 'vlitejs/providers/vimeo.js'\nimport { patch } from '@rails/request.js'\n\nVlitejs.registerProvider('youtube', YouTube)\nVlitejs.registerProvider('vimeo', Vimeo)\n\nexport default class extends Controller {\n  static values = {\n    poster: String,\n    src: String,\n    provider: String,\n    startSeconds: Number,\n    endSeconds: Number,\n    durationSeconds: Number,\n    watchedTalkPath: String,\n    currentUserPresent: { default: false, type: Boolean },\n    progressSeconds: { default: 0, type: Number },\n    watched: { default: false, type: Boolean }\n  }\n\n  static targets = ['player', 'playerWrapper', 'watchedOverlay', 'resumeOverlay', 'playOverlay']\n  playbackRateOptions = [1, 1.25, 1.5, 1.75, 2]\n\n  initialize () {\n    useIntersection(this, { element: this.playerWrapperTarget, threshold: 0.5, visibleAttribute: null })\n  }\n\n  connect () {\n    this.init()\n  }\n\n  // methods\n\n  init () {\n    if (this.isPreview) return\n    if (!this.hasPlayerTarget) return\n    if (this.watchedValue) return\n    if (this.hasResumeOverlayTarget || this.hasPlayOverlayTarget) return\n\n    this.player = new Vlitejs(this.playerTarget, this.options)\n  }\n\n  dismissWatchedOverlay () {\n    this.showLoadingState(this.watchedOverlayTarget)\n    this.watchedValue = false\n    this.autoplay = true\n    this.player = new Vlitejs(this.playerTarget, this.options)\n  }\n\n  resumePlayback () {\n    this.showLoadingState(this.resumeOverlayTarget)\n    this.autoplay = true\n    this.player = new Vlitejs(this.playerTarget, this.options)\n  }\n\n  startPlayback () {\n    this.showLoadingState(this.playOverlayTarget)\n    this.autoplay = true\n    this.player = new Vlitejs(this.playerTarget, this.options)\n  }\n\n  showLoadingState (overlay) {\n    if (!overlay) return\n\n    const content = overlay.querySelector('.flex.flex-col')\n    if (content) {\n      content.innerHTML = `\n        <div class=\"p-4 bg-white/20 backdrop-blur-sm rounded-full\">\n          <svg class=\"animate-spin h-8 w-8 text-white\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n            <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n            <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n          </svg>\n        </div>\n        <div class=\"text-sm text-white/80\">Loading...</div>\n      `\n    }\n  }\n\n  removeOverlays () {\n    if (this.hasWatchedOverlayTarget) this.watchedOverlayTarget.remove()\n    if (this.hasResumeOverlayTarget) this.resumeOverlayTarget.remove()\n    if (this.hasPlayOverlayTarget) this.playOverlayTarget.remove()\n  }\n\n  get options () {\n    const providerOptions = {}\n    const providerParams = {}\n    // Youtube videos have their own controls, so we need to hide the Vlitejs controls\n    let controls = true\n\n    // Hide the Vlitejs controls if the video is a Youtube video\n    providerParams.controls = !controls\n\n    if (this.hasProviderValue && this.providerValue === 'youtube') {\n      // Set YT rel to 0 to show related videos from the respective channel\n      providerOptions.rel = 0\n      providerOptions.autohide = 0\n      // Show YT controls\n      providerOptions.controls = 1\n      // Ensure not muted on autoplay (user clicked overlay, so gesture is present)\n      providerParams.mute = 0\n      // Hide the Vlitejs controls\n      controls = false\n    }\n    if (this.hasProviderValue && this.providerValue !== 'mp4') {\n      providerOptions.provider = this.providerValue\n    }\n\n    if (this.hasStartSecondsValue) {\n      providerParams.start = this.startSecondsValue\n      providerParams.start_time = this.startSecondsValue\n    }\n\n    if (this.hasEndSecondsValue) {\n      providerParams.end = this.endSecondsValue\n      providerParams.end_time = this.endSecondsValue\n    }\n\n    return {\n      ...providerOptions,\n      options: {\n        providerParams,\n        poster: this.posterValue,\n        controls\n      },\n      onReady: this.handlePlayerReady.bind(this)\n    }\n  }\n\n  // callbacks\n\n  appear () {\n    if (!this.ready) return\n    this.#togglePictureInPicturePlayer(false)\n  }\n\n  disappear () {\n    if (!this.ready) return\n    this.#togglePictureInPicturePlayer(true)\n  }\n\n  handlePlayerReady (player) {\n    this.ready = true\n    // for seekTo to work we need to store again the player instance\n    this.player = player\n\n    const controlBar = player.elements.container.querySelector('.v-controlBar')\n\n    if (controlBar) {\n      const volumeButton = player.elements.container.querySelector('.v-volumeButton')\n      const playbackRateSelect = this.createPlaybackRateSelect(this.playbackRateOptions, player)\n      volumeButton.parentNode.insertBefore(playbackRateSelect, volumeButton.nextSibling)\n    }\n\n    if (this.providerValue === 'youtube') {\n      // The overlay is messing with the hover state of he player\n      player.elements.container.querySelector('.v-overlay').remove()\n\n      this.setupYouTubeEventLogging(player)\n    }\n\n    if (this.providerValue === 'vimeo') {\n      player.instance.on('ended', () => {\n        this.handleVideoEnded()\n      })\n\n      player.instance.on('pause', () => {\n        this.handleVideoPaused()\n      })\n\n      player.instance.on('play', () => {\n        this.startProgressTracking()\n      })\n    }\n\n    if (this.hasProgressSecondsValue && this.progressSecondsValue > 0 && !this.isFullyWatched()) {\n      this.player.seekTo(this.progressSecondsValue)\n    }\n\n    if (this.autoplay) {\n      this.autoplay = false\n      this.player.play()\n\n      if (this.player.unMute) {\n        this.player.unMute()\n      }\n\n      this.removeOverlays()\n    }\n  }\n\n  setupYouTubeEventLogging (player) {\n    if (!player.instance) {\n      console.log('YouTube API not available for event logging')\n      return\n    }\n\n    const ytPlayer = player.instance\n\n    ytPlayer.addEventListener('onStateChange', (event) => {\n      const YOUTUBE_STATES = {\n        ENDED: 0,\n        PLAYING: 1,\n        PAUSED: 2\n      }\n\n      if (event.data === YOUTUBE_STATES.PLAYING && this.currentUserPresentValue) {\n        this.startProgressTracking()\n      } else if (event.data === YOUTUBE_STATES.PAUSED) {\n        this.handleVideoPaused()\n      } else if (event.data === YOUTUBE_STATES.ENDED) {\n        this.handleVideoEnded()\n      }\n    })\n  }\n\n  async startProgressTracking () {\n    if (this.progressInterval) return\n    if (!this.currentUserPresentValue) return\n\n    const currentTime = await this.getCurrentTime()\n    this.progressSecondsValue = Math.floor(currentTime)\n\n    this.updateWatchedProgress(this.progressSecondsValue)\n\n    this.progressInterval = setInterval(async () => {\n      if (this.hasWatchedTalkPathValue) {\n        const currentTime = await this.getCurrentTime()\n        this.progressSecondsValue = Math.floor(currentTime)\n\n        this.updateWatchedProgress(this.progressSecondsValue)\n      }\n    }, 5000)\n  }\n\n  stopProgressTracking () {\n    if (this.progressInterval) {\n      clearInterval(this.progressInterval)\n      this.progressInterval = null\n    }\n  }\n\n  async handleVideoPaused () {\n    this.stopProgressTracking()\n\n    const currentTime = await this.getCurrentTime()\n    this.progressSecondsValue = Math.floor(currentTime)\n    this.updateWatchedProgress(this.progressSecondsValue)\n  }\n\n  async handleVideoEnded () {\n    this.stopProgressTracking()\n\n    if (this.hasDurationSecondsValue && this.durationSecondsValue > 0) {\n      this.progressSecondsValue = this.durationSecondsValue\n      this.updateWatchedProgress(this.durationSecondsValue)\n    }\n  }\n\n  isFullyWatched () {\n    if (!this.hasDurationSecondsValue || this.durationSecondsValue <= 0) return false\n\n    return this.progressSecondsValue >= this.durationSecondsValue - 5\n  }\n\n  updateWatchedProgress (progressSeconds) {\n    if (!this.hasWatchedTalkPathValue) return\n    if (!this.currentUserPresentValue) return\n\n    patch(this.watchedTalkPathValue, {\n      body: {\n        watched_talk: {\n          progress_seconds: progressSeconds\n        }\n      },\n      responseKind: 'turbo-stream'\n    }).catch(error => {\n      console.error('Error updating watch progress:', error)\n    })\n  }\n\n  createPlaybackRateSelect (options, player) {\n    const playbackRateSelect = document.createElement('select')\n    playbackRateSelect.className = 'v-playbackRateSelect v-controlButton'\n    options.forEach(rate => {\n      const option = document.createElement('option')\n      option.value = rate\n      option.textContent = rate + 'x'\n      playbackRateSelect.appendChild(option)\n    })\n\n    playbackRateSelect.addEventListener('change', () => {\n      player.instance.setPlaybackRate(parseFloat(playbackRateSelect.value))\n    })\n\n    return playbackRateSelect\n  }\n\n  seekTo (event) {\n    if (!this.ready) return\n\n    const { time } = event.params\n\n    if (time) {\n      this.player.seekTo(time)\n    }\n  }\n\n  pause () {\n    if (!this.ready) return\n\n    this.player.pause()\n  }\n\n  disconnect () {\n    this.stopProgressTracking()\n  }\n\n  #togglePictureInPicturePlayer (enabled) {\n    const toggleClasses = () => {\n      if (enabled && this.isPlaying) {\n        this.playerWrapperTarget.classList.add('picture-in-picture')\n        this.playerWrapperTarget.querySelector('.v-controlBar').classList.add('v-hidden')\n      } else {\n        this.playerWrapperTarget.classList.remove('picture-in-picture')\n        this.playerWrapperTarget.querySelector('.v-controlBar').classList.remove('v-hidden')\n      }\n    }\n\n    // Check if View Transition API is supported\n    if (document.startViewTransition && typeof document.startViewTransition === 'function') {\n      document.startViewTransition(toggleClasses)\n    } else {\n      // Fallback for browsers without View Transition API support\n      toggleClasses()\n    }\n  }\n\n  get isPlaying () {\n    // Vlitejs doesn't have a method to check if the video is playing\n    // there is a method to check if the video is paused\n    if (this.player.isPaused === undefined || this.player.isPaused === null) {\n      return false\n    }\n\n    return !this.player.isPaused\n  }\n\n  get isPreview () {\n    return document.documentElement.hasAttribute('data-turbo-preview')\n  }\n\n  async getCurrentTime () {\n    try {\n      return await this.player.instance.getCurrentTime()\n    } catch (error) {\n      console.error('Error getting current time:', error)\n      return 0\n    }\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/watched_talk_form_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['watchedAt', 'submitButton']\n  static values = {\n    talkDate: String,\n    autoSubmit: { type: Boolean, default: false }\n  }\n\n  selectWatchedOn (event) {\n    const selectedValue = event.target.value\n\n    if (selectedValue === 'in_person' && this.hasTalkDateValue && this.talkDateValue) {\n      this.watchedAtTarget.value = this.talkDateValue\n    }\n\n    this.autoSubmit()\n  }\n\n  select () {\n    this.autoSubmit()\n  }\n\n  autoSubmit () {\n    if (this.autoSubmitValue) {\n      this.element.requestSubmit()\n    }\n  }\n}\n"
  },
  {
    "path": "app/javascript/controllers/wrapped_stories_controller.js",
    "content": "import { Controller } from '@hotwired/stimulus'\n\nexport default class extends Controller {\n  static targets = ['page', 'progress', 'container', 'scrollView', 'storiesView', 'modeLabel', 'counter']\n  static values = { index: { type: Number, default: 0 }, mode: { type: String, default: 'scroll' } }\n\n  connect () {\n    this.updateMode()\n    this.handleInitialHash()\n    window.addEventListener('hashchange', this.handleHashChange.bind(this))\n  }\n\n  disconnect () {\n    window.removeEventListener('hashchange', this.handleHashChange.bind(this))\n  }\n\n  handleInitialHash () {\n    const hash = window.location.hash.slice(1)\n    if (hash) {\n      const index = this.findPageIndexByName(hash)\n      if (index !== -1) {\n        this.indexValue = index\n        if (this.modeValue === 'stories') {\n          this.showPage()\n        }\n      }\n    }\n  }\n\n  handleHashChange () {\n    const hash = window.location.hash.slice(1)\n    if (hash) {\n      const index = this.findPageIndexByName(hash)\n      if (index !== -1 && index !== this.indexValue) {\n        this.indexValue = index\n        if (this.modeValue === 'stories') {\n          this.showPage()\n        }\n      }\n    }\n  }\n\n  findPageIndexByName (name) {\n    return this.pageTargets.findIndex(page => page.dataset.pageName === name)\n  }\n\n  updateHash () {\n    const currentPage = this.pageTargets[this.indexValue]\n    if (currentPage && currentPage.dataset.pageName) {\n      const newHash = `#${currentPage.dataset.pageName}`\n      if (window.location.hash !== newHash) {\n        window.history.replaceState(null, null, newHash)\n      }\n    }\n  }\n\n  toggleMode () {\n    this.modeValue = this.modeValue === 'scroll' ? 'stories' : 'scroll'\n    this.updateMode()\n  }\n\n  updateMode () {\n    if (this.modeValue === 'stories') {\n      this.scrollViewTarget.classList.add('hidden')\n      this.storiesViewTarget.classList.remove('hidden')\n      this.modeLabelTarget.textContent = 'View as Scroll'\n      document.body.style.overflow = 'hidden'\n      this.showPage()\n    } else {\n      this.scrollViewTarget.classList.remove('hidden')\n      this.storiesViewTarget.classList.add('hidden')\n      this.modeLabelTarget.textContent = 'View as Stories'\n      document.body.style.overflow = ''\n\n      if (window.location.hash) {\n        window.history.replaceState(null, null, window.location.pathname + window.location.search)\n      }\n    }\n  }\n\n  next () {\n    if (this.indexValue < this.pageTargets.length - 1) {\n      this.indexValue++\n      this.showPage()\n    }\n  }\n\n  previous () {\n    if (this.indexValue > 0) {\n      this.indexValue--\n      this.showPage()\n    }\n  }\n\n  goToPage (event) {\n    const index = parseInt(event.currentTarget.dataset.index, 10)\n    if (!isNaN(index)) {\n      this.indexValue = index\n      this.showPage()\n    }\n  }\n\n  handleClick (event) {\n    if (event.target.closest('button, a, [data-action]')) return\n\n    const rect = this.containerTarget.getBoundingClientRect()\n    const clickX = event.clientX - rect.left\n    const width = rect.width\n\n    if (clickX < width / 3) {\n      this.previous()\n    } else {\n      this.next()\n    }\n  }\n\n  handleKeydown (event) {\n    if (this.modeValue !== 'stories') return\n\n    if (event.key === 'ArrowRight' || event.key === ' ') {\n      event.preventDefault()\n      this.next()\n    } else if (event.key === 'ArrowLeft') {\n      event.preventDefault()\n      this.previous()\n    } else if (event.key === 'Escape') {\n      this.toggleMode()\n    }\n  }\n\n  showPage () {\n    this.pageTargets.forEach((page, index) => {\n      if (index === this.indexValue) {\n        page.classList.add('active')\n      } else {\n        page.classList.remove('active')\n      }\n    })\n\n    this.progressTargets.forEach((bar, index) => {\n      if (index <= this.indexValue) {\n        bar.classList.add('active')\n      } else {\n        bar.classList.remove('active')\n      }\n    })\n\n    if (this.hasCounterTarget) {\n      this.counterTarget.textContent = `${this.indexValue + 1} / ${this.pageTargets.length}`\n    }\n\n    this.updateHash()\n  }\n}\n"
  },
  {
    "path": "app/javascript/entrypoints/application.css",
    "content": "@import \"../../assets/stylesheets/application.css\";\n"
  },
  {
    "path": "app/javascript/entrypoints/application.js",
    "content": "// Example: Load Rails libraries in Vite.\n//\nimport '@hotwired/turbo-rails'\n\n// import ActiveStorage from \"@rails/activestorage\";\n// ActiveStorage.start();\n//\n// // Import all channels.\n// const channels = import.meta.globEager('./**/*_channel.js')\n\nimport '~/controllers'\n"
  },
  {
    "path": "app/javascript/entrypoints/chartkick.js",
    "content": "import 'chartkick/chart.js'\n"
  },
  {
    "path": "app/javascript/helpers/timing_helpers.js",
    "content": "export function nextEventLoopTick () {\n  return delay(0)\n}\n\nexport function onNextEventLoopTick (callback) {\n  setTimeout(callback, 0)\n}\n\nexport function nextFrame () {\n  return new Promise(requestAnimationFrame)\n}\n\nexport function nextEventNamed (eventName, element = window) {\n  return new Promise(resolve => element.addEventListener(eventName, resolve, { once: true }))\n}\n\nexport function delay (ms) {\n  return new Promise(resolve => setTimeout(resolve, ms))\n}\n"
  },
  {
    "path": "app/javascript/support/appsignal.js",
    "content": "import Appsignal from '@appsignal/javascript'\n\nconst key = import.meta.env.PROD ? '4425c854-a76a-4131-992e-171f7bf653ba' : '10b1f5e6-62a2-4bd8-9431-7698de53c68a'\n\nexport const appsignal = new Appsignal({ key })\n"
  },
  {
    "path": "app/jobs/application_job.rb",
    "content": "class ApplicationJob < ActiveJob::Base\n  queue_as :low # Most of our jobs aren't time-critical; prefer the ones that are to mark that.\n\n  # Automatically retry jobs that encountered a deadlock\n  # retry_on ActiveRecord::Deadlocked\n\n  # Most jobs are safe to ignore if the underlying records are no longer available\n  # discard_on ActiveJob::DeserializationError\n\n  # Apply a catch-all fallback that retries on most exceptions.\n  def self.retries(attempts, wait: :polynomially_longer)\n    retry_on StandardError, attempts:, wait:\n  end\nend\n"
  },
  {
    "path": "app/jobs/generate_wrapped_screenshot_job.rb",
    "content": "class GenerateWrappedScreenshotJob < ApplicationJob\n  queue_as :default\n  limits_concurrency to: 1, key: \"generate_wrapped_screenshot\", duration: 5.minutes\n\n  def perform(user)\n    User::WrappedScreenshotGenerator.generate_all(user)\n  end\nend\n"
  },
  {
    "path": "app/jobs/geocode_record_job.rb",
    "content": "# frozen_string_literal: true\n\nclass GeocodeRecordJob < ApplicationJob\n  queue_as :default\n\n  limits_concurrency to: 1, key: ->(record) { geocode_concurrency_key(record) }, duration: 1.second\n\n  def perform(record)\n    return unless record.geocodeable?\n\n    record.geocode\n    record.save!\n  end\n\n  def geocode_concurrency_key(record)\n    if Geocoder.config.lookup == :nominatim\n      \"geocoding\"\n    else\n      \"geocoding:#{record.class.name}:#{record.id}\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/jobs/recurring/fetch_contributors_job.rb",
    "content": "class Recurring::FetchContributorsJob < ApplicationJob\n  queue_as :low\n\n  def perform\n    return if ENV[\"SEED_SMOKE_TEST\"]\n\n    Rails.logger.info \"Fetching contributors from GitHub...\"\n    contributors_data = GitHub::ContributorsClient.new.fetch_all\n\n    Rails.logger.info \"Fetched #{contributors_data.count} contributors\"\n\n    Contributor.transaction do\n      Contributor.destroy_all\n\n      contributors_data.each do |contributor_data|\n        user = User.find_by(\"LOWER(github_handle) = LOWER(?)\", contributor_data[:login])\n\n        Contributor.create!(\n          login: contributor_data[:login],\n          name: contributor_data[:name],\n          avatar_url: contributor_data[:avatar_url],\n          html_url: contributor_data[:html_url],\n          user: user\n        )\n\n        Rails.logger.info \"Updated #{contributor_data[:login]} with contributor data.\"\n      end\n\n      Rails.logger.info \"Successfully synced #{contributors_data.count} contributors\"\n    end\n  rescue => e\n    Rails.logger.error \"Failed to fetch contributors: #{e.message}\"\n    raise\n  end\nend\n"
  },
  {
    "path": "app/jobs/recurring/mark_suspicious_users_job.rb",
    "content": "class Recurring::MarkSuspiciousUsersJob < ApplicationJob\n  queue_as :default\n\n  def perform\n    User.verified.not_suspicious.suspicion_not_cleared.find_each do |user|\n      refresh_github_metadata(user)\n\n      if user.mark_suspicious!\n        Rails.logger.info(\"[MarkSuspiciousUsersJob] Marked user ##{user.id} (#{user.name}) as suspicious\")\n      end\n    end\n  end\n\n  private\n\n  def refresh_github_metadata(user)\n    return if user.github_metadata.present?\n\n    user.profiles.enhance_with_github\n    user.reload\n  rescue => e\n    Rails.logger.warn(\"[MarkSuspiciousUsersJob] Failed to fetch GitHub metadata for user ##{user.id}: #{e.message}\")\n  end\nend\n"
  },
  {
    "path": "app/jobs/recurring/rollup_job.rb",
    "content": "class Recurring::RollupJob < ApplicationJob\n  queue_as :low\n\n  BATCH_SIZE = 500\n  VISIT_THRESHOLD = 50\n\n  def perform(*args)\n    # first we remove suspicious visits in batches to avoid long locks\n    cleanup_suspicious_recent_visits\n\n    # then we rollup the visits and events\n    Ahoy::Visit.rollup(\"ahoy_visits\", interval: :day)\n    Ahoy::Visit.rollup(\"ahoy_visits\", interval: :month)\n    Ahoy::Event.rollup(\"ahoy_events\", interval: :day)\n    Ahoy::Event.rollup(\"ahoy_events\", interval: :month)\n    Talk.rollup(\"talks\", interval: :year, column: :date)\n  end\n\n  def cleanup_suspicious_recent_visits\n    # Find IPs with more than threshold visits in the last 3 days\n    # Process one IP at a time to keep transactions short\n    suspicious_ips = find_suspicious_ips\n\n    suspicious_ips.each do |ip|\n      delete_visits_for_ip_in_batches(ip)\n    end\n  end\n\n  private\n\n  def find_suspicious_ips\n    # Use a more efficient query that leverages the index on started_at\n    Ahoy::Visit\n      .where(started_at: 3.days.ago..)\n      .where.not(ip: nil)\n      .group(:ip)\n      .having(\"COUNT(*) > ?\", VISIT_THRESHOLD)\n      .pluck(:ip)\n  end\n\n  def delete_visits_for_ip_in_batches(ip)\n    loop do\n      # Find a batch of visit IDs for this IP\n      visit_ids = Ahoy::Visit\n        .where(ip: ip)\n        .limit(BATCH_SIZE)\n        .pluck(:id)\n\n      break if visit_ids.empty?\n\n      # Delete events first (foreign key dependency)\n      Ahoy::Event.where(visit_id: visit_ids).delete_all\n\n      # Then delete visits\n      Ahoy::Visit.where(id: visit_ids).delete_all\n\n      # Allow other queries to run between batches\n      sleep(0.1) if visit_ids.size == BATCH_SIZE\n    end\n  end\nend\n"
  },
  {
    "path": "app/jobs/recurring/youtube_thumbnail_validation_job.rb",
    "content": "# frozen_string_literal: true\n\nclass Recurring::YouTubeThumbnailValidationJob < ApplicationJob\n  include ActiveJob::Continuable\n\n  queue_as :low\n\n  RECHECK_INTERVAL = 3.months\n\n  def perform\n    step(:validate_thumbnails) do |step|\n      talks_to_check.find_each(start: step.cursor) do |talk|\n        validate_thumbnail(talk)\n        step.advance! from: talk.id\n      rescue => e\n        Rails.logger.error(\"Error validating thumbnail for talk #{talk.id}: #{e.message}\")\n        step.advance! from: talk.id\n      end\n    end\n  end\n\n  private\n\n  def talks_to_check\n    Talk.youtube.where(\n      \"youtube_thumbnail_checked_at IS NULL OR youtube_thumbnail_checked_at < ?\",\n      RECHECK_INTERVAL.ago\n    )\n  end\n\n  def validate_thumbnail(talk)\n    thumbnail = YouTube::Thumbnail.new(talk.video_id)\n\n    updates = {youtube_thumbnail_checked_at: Time.current}\n\n    if (xl_url = thumbnail.best_url_for(:thumbnail_xl))\n      updates[:thumbnail_xl] = xl_url\n    end\n\n    if (lg_url = thumbnail.best_url_for(:thumbnail_lg))\n      updates[:thumbnail_lg] = lg_url\n    end\n\n    talk.update_columns(updates)\n  end\nend\n"
  },
  {
    "path": "app/jobs/recurring/youtube_video_availability_job.rb",
    "content": "# frozen_string_literal: true\n\nclass Recurring::YouTubeVideoAvailabilityJob < ApplicationJob\n  include ActiveJob::Continuable\n\n  queue_as :low\n\n  RECHECK_INTERVAL = 1.month\n\n  def perform\n    step(:check_availability) do |step|\n      talks_to_check.find_each(start: step.cursor) do |talk|\n        talk.check_video_availability!\n        step.advance! from: talk.id\n      rescue => e\n        Rails.logger.error(\"Error checking availability for talk #{talk.id}: #{e.message}\")\n        step.advance! from: talk.id\n      end\n    end\n  end\n\n  private\n\n  def talks_to_check\n    Talk.youtube.where(\n      \"video_availability_checked_at IS NULL OR video_availability_checked_at < ?\",\n      RECHECK_INTERVAL.ago\n    )\n  end\nend\n"
  },
  {
    "path": "app/jobs/recurring/youtube_video_duration_job.rb",
    "content": "class Recurring::YouTubeVideoDurationJob < ApplicationJob\n  queue_as :low\n\n  def perform\n    Talk.youtube.without_duration.find_each do |talk|\n      talk.fetch_duration_from_youtube_later!\n    end\n  end\nend\n"
  },
  {
    "path": "app/jobs/recurring/youtube_video_statistics_job.rb",
    "content": "class Recurring::YouTubeVideoStatisticsJob < ApplicationJob\n  queue_as :low\n\n  def perform\n    Talk.youtube.in_batches(of: 50) do |talks|\n      stats = YouTube::Video.new.get_statistics(talks.pluck(:video_id))\n      talks.each do |talk|\n        if stats[talk.video_id]\n          talk.update!(view_count: stats[talk.video_id][:view_count], like_count: stats[talk.video_id][:like_count])\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/jobs/typesense_index_job.rb",
    "content": "# frozen_string_literal: true\n\nclass TypesenseIndexJob < ApplicationJob\n  queue_as :default\n\n  def perform(record, method)\n    return unless record.present?\n    return unless record.respond_to?(method)\n    return unless Search::Backend::Typesense.available?\n\n    record.send(method)\n  rescue Typesense::Error::ObjectNotFound => e\n    Rails.logger.warn(\"TypesenseIndexJob: Object not found - #{e.message}\")\n  rescue Typesense::Error::RequestMalformed => e\n    Rails.logger.error(\"TypesenseIndexJob: Request malformed - #{e.message}\")\n  rescue Typesense::Error::ServerError => e\n    Rails.logger.error(\"TypesenseIndexJob: Server error - #{e.message}\")\n\n    raise\n  end\nend\n"
  },
  {
    "path": "app/lib/command.rb",
    "content": "class Command\n  def self.run(command)\n    puts command\n    output = `#{command}`\n\n    puts output\n\n    output\n  end\nend\n"
  },
  {
    "path": "app/lib/download_sponsors.rb",
    "content": "require \"yaml\"\nrequire \"uri\"\nrequire \"capybara\"\nrequire \"capybara/cuprite\"\n\nclass DownloadSponsors\n  def initialize\n    Capybara.register_driver(:cuprite_scraper) do |app|\n      Capybara::Cuprite::Driver.new(\n        app,\n        window_size: [1200, 800],\n        timeout: 30,\n        process_timeout: 30,\n        headless: true\n      )\n    end\n    @session = Capybara::Session.new(:cuprite_scraper)\n  end\n\n  attr_reader :session\n\n  def download_sponsors(save_file:, base_url: nil, sponsors_url: nil, html: nil)\n    provided_args = [base_url, sponsors_url, html].compact\n\n    raise ArgumentError, \"Exactly one of base_url, sponsors_url, or html must be provided\" if provided_args.length != 1\n\n    if base_url\n      sponsor_page = find_sponsor_page(base_url)\n      p \"Page found: #{sponsor_page}\"\n      sponsor_page = sponsor_page.blank? ? base_url : sponsor_page\n      download_sponsors_data(sponsor_page, save_file:)\n    elsif sponsors_url\n      download_sponsors_data(sponsors_url, save_file:)\n    elsif html\n      download_sponsors_data_from_html(html, save_file:)\n    end\n  end\n\n  def find_sponsor_page(url)\n    session.visit(url)\n    session.driver.wait_for_network_idle\n\n    # Heuristic: look for links with 'sponsor' in href or text, but not logo/image links\n    sponsor_link = session.all(\"a[href]\").find do |a|\n      original_href = a[:href].to_s\n      href = original_href.downcase\n      text = a.text.downcase\n\n      # Check if this is a fragment link by looking at the URI fragment\n      uri = URI.parse(original_href)\n      base_uri = URI.parse(url)\n\n      # A fragment link has a fragment and points to the same page (same host and path)\n      is_fragment = uri.fragment &&\n        uri.host == base_uri.host &&\n        (uri.path == \"/\" || uri.path == base_uri.path)\n\n      # Must contain 'sponsor' and not be a fragment or empty\n      (href.include?(\"sponsor\") || text.include?(\"sponsor\")) &&\n        !original_href.strip.empty? &&\n        !is_fragment &&\n        # Avoid links that are just logo images\n        !a.first(\"img\", minimum: 0)\n    end\n    sponsor_link ? URI.join(url, sponsor_link[:href]).to_s : nil\n  end\n\n  # Finds and returns all sponsor page links (hrefs) for a given URL using Capybara + Cuprite\n  # Returns an array of unique links (absolute URLs)\n  def download_sponsors_data(url, save_file:)\n    session.visit(url)\n    session.driver.wait_for_network_idle\n    extract_and_save_sponsors_data(session.html, save_file, url)\n  ensure\n    session&.driver&.quit\n  end\n\n  def download_sponsors_data_from_html(html_content, save_file:)\n    extract_and_save_sponsors_data(html_content, save_file)\n  end\n\n  private\n\n  def extract_and_save_sponsors_data(html_content, save_file, url = nil)\n    sponsor_schema = {\n      type: \"object\",\n      properties: {\n        name: {\n          type: \"string\",\n          description: \"Official company or organization name as displayed on the website. Extract the exact name without abbreviations unless that's how it's presented.\"\n        },\n        badge: {\n          type: \"string\",\n          description: \"Special sponsorship role or additional service beyond the tier level. Common examples include: 'Drinkup Sponsor', 'Climbing Sponsor', 'Hack Space Sponsor', 'Nursery Sponsor', 'Party Sponsor', 'Lightning Talks Sponsor', 'Coffee Sponsor', 'Lunch Sponsor', 'Breakfast Sponsor', 'Networking Sponsor', 'Swag Sponsor', 'Livestream Sponsor', 'Accessibility Sponsor', 'Diversity Sponsor', 'Travel Sponsor', 'Venue Sponsor', 'WiFi Sponsor', 'Welcome Reception Sponsor'. Leave empty string if no special badge is mentioned.\"\n        },\n        website: {\n          type: \"string\",\n          description: \"Complete URL to the sponsor's main website. Must be a valid HTTP/HTTPS URL. If only a domain is provided, prepend with 'https://'. Do not include tracking parameters or fragments.\"\n        },\n        slug: {\n          type: \"string\",\n          description: \"URL-safe identifier derived from the company name. Convert to lowercase, replace spaces and special characters with hyphens, remove consecutive hyphens. Examples: 'Evil Martians' -> 'evil-martians', 'AppSignal' -> 'appsignal', '84codes' -> '84codes'\"\n        },\n        logo_url: {\n          type: \"string\",\n          description: url ? \"Complete URL path to the sponsor's logo image. If the logo path is relative (starts with / or ./ or just a filename), prepend with '#{URI(url).origin}'. Ensure the URL points to an actual image file (png, jpg, jpeg, svg, webp). Avoid placeholder or broken image URLs.\" : \"Complete URL path to the sponsor's logo image. Must be a valid HTTP/HTTPS URL pointing to an image file.\"\n        }\n      },\n      required: [\"name\", \"badge\", \"website\", \"logo_url\", \"slug\"],\n      additionalProperties: false\n    }\n\n    tier_schema = {\n      type: \"object\",\n      properties: {\n        name: {\n          type: \"string\",\n          description: \"Exact name of the sponsorship tier as displayed on the website. Common tier names include: 'Platinum', 'Gold', 'Silver', 'Bronze', 'Diamond', 'Ruby', 'Emerald', 'Sapphire', 'Premier', 'Principal', 'Supporting', 'Community', 'Partner', 'Friend', 'Startup', 'Individual', 'Media Partner', 'Travel Sponsor', 'Diversity Sponsor'.\"\n        },\n        description: {\n          type: \"string\",\n          description: \"Official description of this sponsorship tier as written on the website. Include benefits, perks, or explanatory text if provided. If no specific description exists for this tier, provide an empty string. Do not invent descriptions.\"\n        },\n        level: {\n          type: \"integer\",\n          description: \"Numeric hierarchy level where 1 is the highest/most premium tier. Assign based on visual prominence, price indicators, or explicit hierarchy. Common patterns: Platinum/Diamond=1, Gold=2, Silver=3, Bronze=4, Community/Supporting=higher numbers. If unclear, estimate based on sponsor logos size and placement.\"\n        },\n        sponsors: {\n          type: \"array\",\n          items: sponsor_schema,\n          description: \"Array of all sponsors in this tier. Each sponsor should be a complete object with all required fields.\"\n        }\n      },\n      required: [\"name\", \"sponsors\", \"level\", \"description\"],\n      additionalProperties: false\n    }\n\n    schema = {\n      type: \"object\",\n      properties: {\n        tiers: {\n          type: \"array\",\n          items: tier_schema,\n          description: \"Complete list of all sponsorship tiers found on the page, ordered by hierarchy level (1=highest). Look for sponsor sections, partner sections, and supporter sections. Include all visible sponsor information.\"\n        }\n      },\n      required: [\"tiers\"],\n      additionalProperties: false\n    }\n\n    result = ActiveGenie::DataExtractor.call(html_content, schema)\n    File.write(save_file, [result.stringify_keys].to_yaml)\n  end\nend\n"
  },
  {
    "path": "app/lib/duration.rb",
    "content": "class Duration\n  def self.seconds_to_formatted_duration(seconds, raise: true)\n    if seconds.is_a?(Integer)\n      parts = ActiveSupport::Duration.build(seconds).parts\n    elsif seconds.is_a?(ActiveSupport::Duration)\n      parts = seconds.parts\n    else\n      raise \"seconds (`#{seconds.inspect}`) is not an Integer or ActiveSupport::Duration\" if raise\n      return \"??:??\"\n    end\n\n    values = [\n      parts.fetch(:hours, nil),\n      parts.fetch(:minutes, 0),\n      parts.fetch(:seconds, 0)\n    ].compact\n\n    return \"??:??\" if values.any?(&:negative?)\n\n    values.map { |value| value.to_s.rjust(2, \"0\") }.join(\":\")\n  end\nend\n"
  },
  {
    "path": "app/lib/router.rb",
    "content": "module Router\n  class << self\n    include Rails.application.routes.url_helpers\n\n    def image_path(...)\n      ActionController::Base.helpers.image_path(...)\n    end\n\n    def image_url(...)\n      ActionController::Base.helpers.image_url(...)\n    end\n  end\nend\n"
  },
  {
    "path": "app/mailers/application_mailer.rb",
    "content": "class ApplicationMailer < ActionMailer::Base\n  default from: \"from@example.com\"\n  layout \"mailer\"\nend\n"
  },
  {
    "path": "app/models/active_record/sqlite/index.rb",
    "content": "module ActiveRecord::SQLite::Index\n  extend ActiveSupport::Concern\n\n  included do\n    self.ignored_columns = [table_name.to_sym, :rank] # Rails parses our virtual table with these extra non-attributes.\n\n    attribute :rowid, :integer\n    alias_attribute :id, :rowid\n    self.primary_key = :rowid\n\n    # Active Record doesn't pick up the `rowid` primary key column.\n    # So we have have explicitly declare this scope to have `rowid` populated in the result set.\n    default_scope { select(\"#{table_name}.rowid, #{table_name}.*\") }\n  end\n\n  private\n\n  def attributes_for_create(attribute_names)\n    # Prevent `super` filtering out the primary key because it isn't in `self.class.column_names`.\n    [self.class.primary_key, *super]\n  end\nend\n"
  },
  {
    "path": "app/models/ahoy/event.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: ahoy_events\n# Database name: primary\n#\n#  id         :integer          not null, primary key\n#  name       :string           indexed => [time]\n#  properties :text\n#  time       :datetime         indexed => [name]\n#  user_id    :integer          indexed\n#  visit_id   :integer          indexed\n#\n# Indexes\n#\n#  index_ahoy_events_on_name_and_time  (name,time)\n#  index_ahoy_events_on_user_id        (user_id)\n#  index_ahoy_events_on_visit_id       (visit_id)\n#\n# rubocop:enable Layout/LineLength\nclass Ahoy::Event < ApplicationRecord\n  include Ahoy::QueryMethods\n\n  self.table_name = \"ahoy_events\"\n  include Rollupable\n\n  rollup_default_column :time\n\n  belongs_to :visit\n  belongs_to :user, optional: true\n\n  serialize :properties, coder: JSON\nend\n"
  },
  {
    "path": "app/models/ahoy/visit.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: ahoy_visits\n# Database name: primary\n#\n#  id               :integer          not null, primary key\n#  app_version      :string\n#  browser          :string\n#  city             :string\n#  country          :string\n#  device_type      :string\n#  ip               :string           indexed, indexed => [started_at]\n#  landing_page     :text\n#  latitude         :float\n#  longitude        :float\n#  os               :string\n#  os_version       :string\n#  platform         :string\n#  referrer         :text\n#  referring_domain :string\n#  region           :string\n#  started_at       :datetime         indexed => [ip]\n#  user_agent       :text\n#  utm_campaign     :string\n#  utm_content      :string\n#  utm_medium       :string\n#  utm_source       :string\n#  utm_term         :string\n#  visit_token      :string           uniquely indexed\n#  visitor_token    :string\n#  user_id          :integer          indexed\n#\n# Indexes\n#\n#  index_ahoy_visits_on_ip                 (ip)\n#  index_ahoy_visits_on_started_at_and_ip  (started_at,ip)\n#  index_ahoy_visits_on_user_id            (user_id)\n#  index_ahoy_visits_on_visit_token        (visit_token) UNIQUE\n#\n# rubocop:enable Layout/LineLength\nclass Ahoy::Visit < ApplicationRecord\n  self.table_name = \"ahoy_visits\"\n\n  include Rollupable\n\n  rollup_default_column :started_at\n\n  has_many :events, class_name: \"Ahoy::Event\", dependent: :destroy\n  belongs_to :user, optional: true\nend\n"
  },
  {
    "path": "app/models/alias.rb",
    "content": "# == Schema Information\n#\n# Table name: aliases\n# Database name: primary\n#\n#  id             :integer          not null, primary key\n#  aliasable_type :string           not null, indexed => [aliasable_id], uniquely indexed => [name]\n#  name           :string           not null, uniquely indexed => [aliasable_type]\n#  slug           :string           indexed\n#  created_at     :datetime         not null\n#  updated_at     :datetime         not null\n#  aliasable_id   :integer          not null, indexed => [aliasable_type]\n#\n# Indexes\n#\n#  index_aliases_on_aliasable                (aliasable_type,aliasable_id)\n#  index_aliases_on_aliasable_type_and_name  (aliasable_type,name) UNIQUE\n#  index_aliases_on_slug                     (slug)\n#\nclass Alias < ApplicationRecord\n  belongs_to :aliasable, polymorphic: true\n\n  validates :name, presence: true, uniqueness: {scope: :aliasable_type}\n  validate :slug_globally_unique_except_same_aliasable\n\n  after_save_commit :reindex\n  after_destroy_commit :reindex\n\n  private\n\n  def slug_globally_unique_except_same_aliasable\n    return if slug.blank?\n\n    conflicting = self.class.where(slug: slug).where.not(aliasable_type: aliasable_type, aliasable_id: aliasable_id)\n    conflicting = conflicting.where.not(id: id) if persisted?\n\n    errors.add(:slug, :taken) if conflicting.exists?\n  end\n\n  def reindex\n    return if Search::Backend.skip_indexing\n\n    Search::Backend.index(aliasable)\n  end\nend\n"
  },
  {
    "path": "app/models/announcement.rb",
    "content": "class Announcement\n  CONTENT_PATH = Rails.root.join(\"content\", \"announcements\")\n\n  # Collection class for chainable filtering\n  class Collection < Array\n    def published\n      Collection.new(select(&:published?))\n    end\n\n    def by_tag(tag)\n      Collection.new(select { |a| a.tags.map(&:downcase).include?(tag.downcase) })\n    end\n\n    def all_tags\n      flat_map(&:tags).uniq.sort\n    end\n\n    def find_by_slug(slug)\n      find { |a| a.slug == slug }\n    end\n\n    def find_by_slug!(slug)\n      find_by_slug(slug) || raise(ActiveRecord::RecordNotFound, \"Announcement not found: #{slug}\")\n    end\n  end\n\n  attr_reader :title, :slug, :date, :author, :published, :excerpt, :tags, :featured_image, :content, :file_path\n\n  def initialize(attributes = {})\n    @title = attributes[:title]\n    @slug = attributes[:slug]\n    @date = attributes[:date]\n    @author = attributes[:author]\n    @published = attributes[:published] != false\n    @excerpt = attributes[:excerpt]\n    @tags = attributes[:tags] || []\n    @featured_image = attributes[:featured_image]\n    @content = attributes[:content]\n    @file_path = attributes[:file_path]\n  end\n\n  class << self\n    def all\n      return load_all if Rails.env.local?\n\n      @all ||= load_all\n    end\n\n    def published\n      all.published\n    end\n\n    def by_tag(tag)\n      all.by_tag(tag)\n    end\n\n    def all_tags\n      all.all_tags\n    end\n\n    def find_by_slug(slug)\n      all.find { |a| a.slug == slug }\n    end\n\n    def find_by_slug!(slug)\n      find_by_slug(slug) || raise(ActiveRecord::RecordNotFound, \"Announcement not found: #{slug}\")\n    end\n\n    def reload!\n      @all = nil\n      all\n    end\n\n    private\n\n    def load_all\n      return Collection.new unless CONTENT_PATH.exist?\n\n      announcements = Dir.glob(CONTENT_PATH.join(\"*.md\")).map do |file_path|\n        parse_file(file_path)\n      end.compact.sort_by(&:date).reverse\n\n      Collection.new(announcements)\n    end\n\n    def parse_file(file_path)\n      content = File.read(file_path)\n      frontmatter, body = extract_frontmatter(content)\n\n      return nil if frontmatter.nil?\n\n      new(\n        title: frontmatter[\"title\"],\n        slug: frontmatter[\"slug\"] || slug_from_filename(file_path),\n        date: parse_date(frontmatter[\"date\"]),\n        author: frontmatter[\"author\"],\n        published: frontmatter[\"published\"],\n        excerpt: frontmatter[\"excerpt\"],\n        tags: Array(frontmatter[\"tags\"]),\n        featured_image: frontmatter[\"featured_image\"],\n        content: body.strip,\n        file_path: file_path\n      )\n    end\n\n    def extract_frontmatter(content)\n      return [nil, content] unless content.start_with?(\"---\")\n\n      parts = content.split(/^---\\s*$/, 3)\n      return [nil, content] if parts.length < 3\n\n      frontmatter = YAML.safe_load(parts[1], permitted_classes: [Date, Time])\n      body = parts[2]\n\n      [frontmatter, body]\n    end\n\n    def slug_from_filename(file_path)\n      filename = File.basename(file_path, \".md\")\n      filename.sub(/^\\d{4}-\\d{2}-\\d{2}-/, \"\")\n    end\n\n    def parse_date(date)\n      case date\n      when Date, Time\n        date.to_date\n      when String\n        Date.parse(date)\n      else\n        Date.today\n      end\n    end\n  end\n\n  def published?\n    @published\n  end\n\n  def author_user\n    return nil if author.blank?\n\n    @author_user ||= User.find_by_github_handle(author)\n  end\n\n  def to_param\n    slug\n  end\nend\n"
  },
  {
    "path": "app/models/application_record.rb",
    "content": "class ApplicationRecord < ActiveRecord::Base\n  primary_abstract_class\nend\n"
  },
  {
    "path": "app/models/cfp.rb",
    "content": "# == Schema Information\n#\n# Table name: cfps\n# Database name: primary\n#\n#  id         :integer          not null, primary key\n#  close_date :date\n#  link       :string\n#  name       :string\n#  open_date  :date\n#  created_at :datetime         not null\n#  updated_at :datetime         not null\n#  event_id   :integer          not null, indexed\n#\n# Indexes\n#\n#  index_cfps_on_event_id  (event_id)\n#\n# Foreign Keys\n#\n#  event_id  (event_id => events.id)\n#\nclass CFP < ApplicationRecord\n  belongs_to :event\n\n  scope :open, -> { where(\"close_date IS NULL OR close_date >= ?\", Date.today) }\n  scope :closed, -> { where(\"close_date < ?\", Date.today) }\n\n  def open?\n    return false if closed?\n    return false if future?\n\n    open_ended? || close_date.present?\n  end\n\n  def open_ended?\n    close_date.blank?\n  end\n\n  def closed?\n    close_date.present? && Date.today > close_date\n  end\n\n  def future?\n    open_date.present? && Date.today < open_date\n  end\n\n  def past?\n    closed?\n  end\n\n  def status\n    if future?\n      :pending\n    elsif open?\n      :open\n    else\n      :closed\n    end\n  end\n\n  def days_remaining\n    return nil if close_date.blank?\n    return nil if closed?\n\n    (close_date - Date.today).to_i\n  end\n\n  def days_until_open\n    return nil if open_date.blank?\n    return nil if open?\n    return nil if past?\n\n    (open_date - Date.today).to_i\n  end\n\n  def days_since_close\n    return nil if close_date.blank?\n    return nil if future?\n    return nil if open?\n\n    (Date.current - close_date).to_i\n  end\n\n  def present?\n    link.present?\n  end\n\n  def formatted_open_date\n    I18n.l(open_date, default: \"unknown\")\n  end\n\n  def formatted_close_date\n    I18n.l(close_date, default: \"unknown\")\n  end\nend\n"
  },
  {
    "path": "app/models/city.rb",
    "content": "# frozen_string_literal: true\n\n# == Schema Information\n#\n# Table name: cities\n# Database name: primary\n#\n#  id               :integer          not null, primary key\n#  country_code     :string           not null, indexed => [name, state_code]\n#  featured         :boolean          default(FALSE), not null, indexed\n#  geocode_metadata :json             not null\n#  latitude         :decimal(10, 6)\n#  longitude        :decimal(10, 6)\n#  name             :string           not null, indexed => [country_code, state_code]\n#  slug             :string           not null, uniquely indexed\n#  state_code       :string           indexed => [name, country_code]\n#  created_at       :datetime         not null\n#  updated_at       :datetime         not null\n#\n# Indexes\n#\n#  index_cities_on_featured                              (featured)\n#  index_cities_on_name_and_country_code_and_state_code  (name,country_code,state_code)\n#  index_cities_on_slug                                  (slug) UNIQUE\n#\nclass City < ApplicationRecord\n  include Locatable\n  include Sluggable\n\n  configure_slug(attribute: :name, auto_suffix_on_collision: true)\n\n  geocoded_by :geocode_query do |record, results|\n    if (result = results.first)\n      record.latitude = result.latitude\n      record.longitude = result.longitude\n      record.geocode_metadata = result.data.merge(\n        \"geocoded_at\" => Time.current.iso8601,\n        \"geocoder_city\" => result.city\n      )\n    end\n  end\n\n  has_many :aliases, as: :aliasable, dependent: :destroy, primary_key: :id\n  has_many :events, primary_key: [:name, :country_code, :state_code], foreign_key: [:city, :country_code, :state_code], inverse_of: false\n  has_many :users, -> { indexable.geocoded }, class_name: \"User\", primary_key: [:name, :country_code, :state_code], foreign_key: [:city, :country_code, :state_code], inverse_of: false\n\n  before_validation :geocode, on: :create, if: :needs_geocoding?\n  before_validation :clear_unsupported_state_code\n\n  after_commit :index_in_search, on: [:create, :update]\n  after_commit :remove_from_search, on: :destroy\n\n  validates :name, presence: true, uniqueness: {scope: [:country_code, :state_code]}\n  validates :slug, presence: true, uniqueness: true\n  validates :country_code, presence: true\n  validate :geocoded_as_city\n\n  scope :featured, -> { where(featured: true) }\n  scope :for_country, ->(country_code) { where(country_code: country_code.upcase) }\n  scope :for_state, ->(state) { where(country_code: state.country.alpha2, state_code: state.code) }\n\n  def country\n    @country ||= Country.find_by(country_code: country_code)\n  end\n\n  def state\n    return nil unless state_code.present? && country&.states?\n\n    @state ||= State.find_by_code(state_code, country: country)\n  end\n\n  def path\n    if featured?\n      Router.city_path(slug)\n    elsif state_code.present? && state.present?\n      Router.city_with_state_path(country.code, state.slug, slug)\n    else\n      Router.city_by_country_path(country.code, slug)\n    end\n  end\n\n  def past_path\n    if featured?\n      Router.city_past_index_path(self)\n    elsif state_code.present? && state.present?\n      Router.city_with_state_past_index_path(alpha2: country.code, state: state.slug, city: slug)\n    else\n      Router.city_by_country_past_index_path(alpha2: country.code, city: slug)\n    end\n  end\n\n  def users_path\n    if featured?\n      Router.city_users_path(self)\n    elsif state_code.present? && state.present?\n      Router.city_with_state_users_path(alpha2: country.code, state: state.slug, city: slug)\n    else\n      Router.city_by_country_users_path(alpha2: country.code, city: slug)\n    end\n  end\n\n  def meetups_path\n    if featured?\n      Router.city_meetups_path(self)\n    elsif state_code.present? && state.present?\n      Router.city_with_state_meetups_path(alpha2: country.code, state: state.slug, city: slug)\n    else\n      Router.city_by_country_meetups_path(alpha2: country.code, city: slug)\n    end\n  end\n\n  def stamps_path\n    if featured?\n      Router.city_stamps_path(self)\n    elsif state_code.present? && state.present?\n      Router.city_with_state_stamps_path(alpha2: country.code, state: state.slug, city: slug)\n    else\n      Router.city_by_country_stamps_path(alpha2: country.code, city: slug)\n    end\n  end\n\n  def map_path\n    if featured?\n      Router.city_map_index_path(self)\n    elsif state_code.present? && state.present?\n      Router.city_with_state_map_index_path(alpha2: country.code, state: state.slug, city: slug)\n    else\n      Router.city_by_country_map_index_path(alpha2: country.code, city: slug)\n    end\n  end\n\n  def to_param\n    slug\n  end\n\n  def geocoded?\n    latitude.present? && longitude.present?\n  end\n\n  def geocodeable?\n    name.present?\n  end\n\n  def needs_geocoding?\n    geocodeable? && !geocoded?\n  end\n\n  def geocode_query\n    [name, state&.name, country&.name].compact.join(\", \")\n  end\n\n  def coordinates\n    return nil unless geocoded?\n\n    [latitude, longitude]\n  end\n\n  def location_string\n    if country&.alpha2 == \"US\" && state_code.present?\n      \"#{name}, #{state_code}\"\n    else\n      \"#{name}, #{country&.name}\"\n    end\n  end\n\n  def to_location\n    Location.new(city: name, state_code: state_code, country_code: country_code)\n  end\n\n  def alpha2\n    country_code\n  end\n\n  def continent\n    country&.continent\n  end\n\n  def bounds\n    return nil unless geocoded?\n\n    offset = 0.5\n\n    {\n      southwest: [longitude.to_f - offset, latitude.to_f - offset],\n      northeast: [longitude.to_f + offset, latitude.to_f + offset]\n    }\n  end\n\n  def stamps\n    @stamps ||= begin\n      event_stamps = events.flat_map { |event| Stamp.for_event(event) }\n      country_stamps = Stamp.for(country_code: country_code, state_code: state_code)\n\n      (event_stamps + country_stamps).uniq { |s| s.code }\n    end\n  end\n\n  def nearby_users(radius_km: 100, limit: 12, exclude_ids: [])\n    return [] unless coordinates.present?\n\n    User.geocoded\n      .near(coordinates, radius_km, units: :km)\n      .where.not(id: exclude_ids)\n      .limit(limit)\n      .map do |user|\n        distance = Geocoder::Calculations.distance_between(\n          coordinates,\n          [user.latitude, user.longitude],\n          units: :km\n        )\n        {user: user, distance_km: distance.round}\n      end\n      .sort_by { |u| u[:distance_km] }\n  end\n\n  def nearby_events(radius_km: 250, limit: 12, exclude_ids: [])\n    return [] unless coordinates.present?\n\n    scope = Event.includes(:series, :participants)\n      .where.not(latitude: nil, longitude: nil)\n      .where.not(city: name)\n\n    scope = scope.where.not(id: exclude_ids) if exclude_ids.any?\n\n    scope.map do |event|\n      distance = Geocoder::Calculations.distance_between(\n        coordinates,\n        [event.latitude, event.longitude],\n        units: :km\n      )\n      {event: event, distance_km: distance.round} if distance <= radius_km\n    end\n      .compact\n      .sort_by { |e| e[:event].start_date || Time.at(0).to_date }\n      .last(limit)\n      .reverse\n  end\n\n  def with_coordinates\n    self\n  end\n\n  def events_count\n    @events_count ||= events.size\n  end\n\n  def users_count\n    @users_count ||= users.size\n  end\n\n  def feature!\n    update!(featured: true)\n  end\n\n  def unfeature!\n    update!(featured: false)\n  end\n\n  def sync_aliases_from_list(alias_names)\n    Array.wrap(alias_names).each do |alias_name|\n      slug = alias_name.parameterize\n\n      existing_own = ::Alias.find_by(aliasable_type: \"City\", aliasable_id: id, name: alias_name) ||\n        ::Alias.find_by(aliasable_type: \"City\", aliasable_id: id, slug: slug)\n      if existing_own\n        existing_own.update(name: alias_name) if existing_own.name != alias_name\n        next\n      end\n\n      existing_global = ::Alias.find_by(aliasable_type: \"City\", name: alias_name) || ::Alias.find_by(aliasable_type: \"City\", slug: slug)\n\n      next if existing_global\n\n      ::Alias.insert({\n        aliasable_type: \"City\",\n        aliasable_id: id,\n        name: alias_name,\n        slug: slug,\n        created_at: Time.current,\n        updated_at: Time.current\n      })\n    end\n  end\n\n  private\n\n  def clear_unsupported_state_code\n    self.state_code = nil unless country&.states?\n  end\n\n  CITY_STATE_COUNTRIES = %w[HK SG MC VA].freeze\n\n  def geocoded_as_city\n    return if CITY_STATE_COUNTRIES.include?(country_code)\n    return if geocode_metadata.blank?\n    return if geocode_metadata[\"geocoder_city\"].present?\n\n    errors.add(:name, \"is not a valid city\")\n  end\n\n  class << self\n    def find_for(city:, country_code:, state_code: nil)\n      scope = where(name: city, country_code: country_code)\n      scope = scope.where(state_code: state_code) if state_code.present?\n      scope.first || find_by_alias(city, country_code: country_code)\n    end\n\n    def find_or_create_for(city:, country_code:, state_code: nil, latitude: nil, longitude: nil)\n      return nil if city.blank? || country_code.blank?\n\n      record = find_by(name: city, state_code: state_code, country_code: country_code)\n\n      return record if record\n\n      record = find_by_alias(city, country_code: country_code)\n\n      return record if record\n\n      new_record = new(\n        name: city,\n        country_code: country_code.upcase,\n        state_code: state_code,\n        latitude: latitude,\n        longitude: longitude,\n        featured: false\n      )\n\n      new_record.save ? new_record : nil\n    end\n\n    def find_by_alias(name, country_code:)\n      return nil if name.blank? || country_code.blank?\n\n      city_alias = ::Alias\n        .where(aliasable_type: \"City\")\n        .where(\"LOWER(name) = ? OR slug = ?\", name.downcase, name.parameterize)\n        .first\n\n      return nil unless city_alias\n\n      city = find_by(id: city_alias.aliasable_id)\n\n      return city if city&.country_code&.upcase == country_code.upcase\n\n      nil\n    end\n\n    def featured_slugs\n      @featured_slugs ||= featured.pluck(:slug).to_set\n    end\n\n    def clear_cache!\n      @featured_slugs = nil\n    end\n  end\n\n  private\n\n  def index_in_search\n    Search::Backend.index(self)\n  end\n\n  def remove_from_search\n    Search::Backend.remove(self)\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/appsignal/admin_namespace.rb",
    "content": "module Appsignal::AdminNamespace\n  extend ActiveSupport::Concern\n\n  included do\n    before_action :set_appsignal_admin_namspace\n  end\n\n  def set_appsignal_admin_namspace\n    return unless defined?(Appsignal)\n\n    Appsignal.set_namespace(\"admin\")\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/geocodeable.rb",
    "content": "# frozen_string_literal: true\n\nmodule Geocodeable\n  extend ActiveSupport::Concern\n\n  class_methods do\n    attr_reader :geocode_attribute\n\n    def geocodeable(attribute = :location)\n      @geocode_attribute = attribute\n\n      geocoded_by attribute do |record, results|\n        if (result = results.first)\n          record.city = result.city\n          record.latitude = result.latitude\n          record.longitude = result.longitude\n          record.state_code = result.state_code\n          record.country_code = result.country_code&.upcase\n          record.geocode_metadata = result.data.merge(\"geocoded_at\" => Time.current.iso8601)\n\n          if result.city.present? && record.country_code.present?\n            city_record = City.find_or_create_for(\n              city: record.city,\n              state_code: record.state_code,\n              country_code: record.country_code\n            )\n            record.city = city_record&.name\n          else\n            record.city = nil\n          end\n        end\n      end\n\n      after_commit :geocode_later, if: :\"#{attribute}_previously_changed?\"\n\n      scope :with_coordinates, -> { where.not(latitude: nil).where.not(longitude: nil) }\n      scope :without_coordinates, -> { where(latitude: nil).or(where(longitude: nil)) }\n    end\n  end\n\n  def geocodeable?\n    send(self.class.geocode_attribute).present?\n  end\n\n  def clear_geocode\n    self.latitude = nil\n    self.longitude = nil\n    self.city = nil\n    self.state_code = nil\n    self.country_code = nil\n    self.geocode_metadata = {}\n  end\n\n  def regeocode\n    clear_geocode\n    geocode\n  end\n\n  def geocode!\n    geocode\n    save!\n  end\n\n  def clear_geocode!\n    clear_geocode\n    save!\n  end\n\n  def regeocode!\n    regeocode\n    save!\n  end\n\n  private\n\n  def geocode_later\n    GeocodeRecordJob.perform_later(self)\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/locatable.rb",
    "content": "# frozen_string_literal: true\n\nmodule Locatable\n  extend ActiveSupport::Concern\n\n  def location_type\n    self.class.name.underscore.to_sym\n  end\n\n  def continent?\n    is_a?(Continent)\n  end\n\n  def country?\n    is_a?(Country)\n  end\n\n  def city?\n    is_a?(City)\n  end\n\n  def state?\n    is_a?(State)\n  end\n\n  def has_sub_locations?\n    continent? || country? || state?\n  end\n\n  def sub_location_label\n    return \"Countries\" if continent?\n    return \"Cities\" if country? || state?\n    nil\n  end\n\n  def to_location\n    @to_location ||= Location.from_record(self)\n  end\n\n  def has_routes?\n    true\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/rollupable.rb",
    "content": "module Rollupable\n  extend ActiveSupport::Concern\n\n  class_methods do\n    attr_reader :rollup_column\n\n    def rollup_default_column(column)\n      @rollup_column = column\n    end\n\n    def rollup(*args, **options, &block)\n      Rollup::Aggregator.new(self).rollup(*args, **options, &block)\n      nil\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/sluggable.rb",
    "content": "module Sluggable\n  extend ActiveSupport::Concern\n\n  included do\n    before_validation :set_slug, on: :create\n    validates :slug, presence: true\n    validates :slug, uniqueness: true\n  end\n\n  def to_param\n    slug\n  end\n\n  private\n\n  def set_slug\n    source_value = send(slug_source)\n    return if source_value.blank?\n\n    self.slug = slug.presence || I18n.transliterate(source_value.downcase).parameterize\n\n    # if slug is already taken, add a random string to the end\n    if self.class.exists?(slug: slug) && self.class.auto_suffix_on_collision\n      self.slug = \"#{slug}-#{SecureRandom.hex(4)}\"\n    end\n  end\n\n  def slug_source\n    self.class.slug_source\n  end\n\n  class_methods do\n    attr_reader :slug_source, :auto_suffix_on_collision\n\n    def configure_slug(attribute:, auto_suffix_on_collision: false)\n      @auto_suffix_on_collision = auto_suffix_on_collision\n      @slug_source = attribute.to_sym\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/suggestable.rb",
    "content": "module Suggestable\n  extend ActiveSupport::Concern\n\n  included do\n    has_many :suggestions, as: :suggestable, dependent: :destroy\n  end\n\n  def create_suggestion_from(params:, user: Current.user)\n    suggestions.create(content: select_differences_for(params), suggested_by_id: user&.id).tap do |suggestion|\n      suggestion.approved!(approver: user) if managed_by?(user)\n    end\n  end\n\n  private\n\n  def managed_by?(visiting_user)\n    # this should be overitten in the model where the concern is included\n    raise NotImplementedError, \"This method should be implemented in the model where the concern is included\"\n  end\n\n  def select_differences_for(params)\n    params.reject do |key, value|\n      self[key] == value\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/todoable.rb",
    "content": "module Todoable\n  extend ActiveSupport::Concern\n\n  def todos\n    Todo.for_path(todos_data_path, prefix: todos_file_prefix)\n  end\n\n  def todos_count\n    todos.size\n  end\n\n  private\n\n  def todos_data_path\n    raise NotImplementedError, \"Subclasses must implement #todos_data_path\"\n  end\n\n  def todos_file_prefix\n    raise NotImplementedError, \"Subclasses must implement #todos_file_prefix\"\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/url_normalizable.rb",
    "content": "# frozen_string_literal: true\n\nmodule UrlNormalizable\n  extend ActiveSupport::Concern\n\n  def self.normalize_url_string(url)\n    return \"\" if url.blank?\n\n    value = url.strip\n    value = \"https://#{value}\" unless value.start_with?(\"http://\", \"https://\")\n\n    begin\n      uri = URI.parse(value)\n      # Strip query params and fragment identifiers\n      uri.query = nil\n      uri.fragment = nil\n      uri.to_s\n    rescue URI::InvalidURIError\n      value\n    end\n  end\n\n  class_methods do\n    def normalize_url(field)\n      normalizes field, with: ->(url) {\n        UrlNormalizable.normalize_url_string(url)\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/watchable.rb",
    "content": "module Watchable\n  extend ActiveSupport::Concern\n\n  included do\n    has_many :watched_talks, dependent: :destroy\n  end\n\n  def mark_as_watched!\n    watched_talks.find_or_create_by!(user: Current.user)\n  end\n\n  def unmark_as_watched!\n    watched_talks.find_by(user: Current.user)&.destroy!\n  end\n\n  def watched?(user = Current.user)\n    watched_talks.exists?(user: user)\n  end\nend\n"
  },
  {
    "path": "app/models/concerns/yaml_file.rb",
    "content": "# frozen_string_literal: true\n\nmodule YAMLFile\n  extend ActiveSupport::Concern\n\n  class_methods do\n    def yaml_file(filename, data_method: :file)\n      define_method(:file_name) { filename }\n      define_method(:data_method_name) { data_method }\n    end\n  end\n\n  def file_path\n    record.data_folder.join(file_name)\n  end\n\n  def exist?\n    file_path.exist?\n  end\n\n  def file\n    return {} unless exist?\n\n    @file ||= YAML.load_file(file_path) || {}\n  end\n\n  def entries\n    return [] unless exist?\n\n    @entries ||= YAML.load_file(file_path) || []\n  end\n\n  def reload\n    @file = nil\n    @entries = nil\n\n    self\n  end\nend\n"
  },
  {
    "path": "app/models/connected_account.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: connected_accounts\n# Database name: primary\n#\n#  id           :integer          not null, primary key\n#  access_token :string\n#  expires_at   :datetime\n#  provider     :string           uniquely indexed => [uid], uniquely indexed => [username]\n#  uid          :string           uniquely indexed => [provider]\n#  username     :string           uniquely indexed => [provider]\n#  created_at   :datetime         not null\n#  updated_at   :datetime         not null\n#  user_id      :integer          not null, indexed\n#\n# Indexes\n#\n#  index_connected_accounts_on_provider_and_uid       (provider,uid) UNIQUE\n#  index_connected_accounts_on_provider_and_username  (provider,username) UNIQUE\n#  index_connected_accounts_on_user_id                (user_id)\n#\n# Foreign Keys\n#\n#  user_id  (user_id => users.id)\n#\n# rubocop:enable Layout/LineLength\nclass ConnectedAccount < ApplicationRecord\n  belongs_to :user\n\n  encrypts :access_token\n\n  normalizes :username, with: ->(value) { value.strip.downcase }\n\n  enum :provider, [\"developer\", \"github\", \"passport\"].index_by(&:itself)\nend\n"
  },
  {
    "path": "app/models/continent.rb",
    "content": "# frozen_string_literal: true\n\nclass Continent\n  include Locatable\n\n  CONTINENT_DATA = {\n    \"africa\" => {name: \"Africa\", alpha2: \"AF\", emoji: \"🌍\"},\n    \"antarctica\" => {name: \"Antarctica\", alpha2: \"AN\", emoji: \"🌎\"},\n    \"asia\" => {name: \"Asia\", alpha2: \"AS\", emoji: \"🌏\"},\n    \"australia\" => {name: \"Australia\", alpha2: \"OC\", emoji: \"🌏\"},\n    \"europe\" => {name: \"Europe\", alpha2: \"EU\", emoji: \"🌍\"},\n    \"north-america\" => {name: \"North America\", alpha2: \"NA\", emoji: \"🌎\"},\n    \"south-america\" => {name: \"South America\", alpha2: \"SA\", emoji: \"🌎\"}\n  }.freeze\n\n  BOUNDS = {\n    \"africa\" => {southwest: [-25.0, -35.0], northeast: [60.0, 40.0]},\n    \"antarctica\" => {southwest: [-180.0, -90.0], northeast: [180.0, -60.0]},\n    \"asia\" => {southwest: [25.0, -10.0], northeast: [180.0, 80.0]},\n    \"australia\" => {southwest: [110.0, -50.0], northeast: [180.0, 0.0]},\n    \"europe\" => {southwest: [-25.0, 35.0], northeast: [60.0, 72.0]},\n    \"north-america\" => {southwest: [-170.0, 7.0], northeast: [-50.0, 85.0]},\n    \"south-america\" => {southwest: [-82.0, -56.0], northeast: [-34.0, 13.0]}\n  }.freeze\n\n  attr_reader :slug\n\n  def initialize(slug)\n    @slug = slug.to_s.parameterize\n  end\n\n  def name\n    data[:name]\n  end\n\n  def alpha2\n    data[:alpha2]\n  end\n\n  def emoji_flag\n    data[:emoji]\n  end\n\n  def path\n    Router.continent_path(self)\n  end\n\n  def past_path\n    Router.continent_past_index_path(self)\n  end\n\n  def users_path\n    Router.continent_users_path(self)\n  end\n\n  def countries_path\n    Router.continent_countries_path(self)\n  end\n\n  def stamps_path\n    Router.continent_stamps_path(self)\n  end\n\n  def map_path\n    Router.continent_map_index_path(self)\n  end\n\n  def to_param\n    slug\n  end\n\n  def bounds\n    BOUNDS[slug]\n  end\n\n  def latitude\n    return nil unless bounds\n\n    (bounds[:southwest][1] + bounds[:northeast][1]) / 2.0\n  end\n\n  def longitude\n    return nil unless bounds\n\n    (bounds[:southwest][0] + bounds[:northeast][0]) / 2.0\n  end\n\n  def coordinates\n    return nil unless latitude && longitude\n\n    [longitude, latitude]\n  end\n\n  def countries\n    @countries ||= Country.all.select { |country| country.continent_name == name }\n  end\n\n  def country_codes\n    countries.map(&:alpha2)\n  end\n\n  def events\n    Event.where(country_code: country_codes)\n  end\n\n  def users\n    User.indexable.geocoded.where(country_code: country_codes)\n  end\n\n  def stamps\n    Stamp.all.select { |stamp| stamp.has_country? && country_codes.include?(stamp.country&.alpha2) }\n  end\n\n  def ==(other)\n    other.is_a?(Continent) && slug == other.slug\n  end\n\n  def eql?(other)\n    self == other\n  end\n\n  def hash\n    slug.hash\n  end\n\n  def to_location\n    Location.new(raw_location: name)\n  end\n\n  class << self\n    def all\n      @all ||= CONTINENT_DATA.keys.map { |slug| new(slug) }\n    end\n\n    def find(term)\n      return nil if term.blank?\n\n      slug = term.to_s.parameterize\n      return nil unless CONTINENT_DATA.key?(slug)\n\n      new(slug)\n    end\n\n    def find_by_name(name)\n      return nil if name.blank?\n\n      slug = CONTINENT_DATA.find { |_, data| data[:name] == name }&.first\n      return nil unless slug\n\n      new(slug)\n    end\n\n    def slugs\n      CONTINENT_DATA.keys\n    end\n\n    def africa = new(\"africa\")\n    def antarctica = new(\"antarctica\")\n    def asia = new(\"asia\")\n    def australia = new(\"australia\")\n    def europe = new(\"europe\")\n    def north_america = new(\"north-america\")\n    def south_america = new(\"south-america\")\n  end\n\n  private\n\n  def data\n    CONTINENT_DATA[slug] || {}\n  end\nend\n"
  },
  {
    "path": "app/models/contributor.rb",
    "content": "# == Schema Information\n#\n# Table name: contributors\n# Database name: primary\n#\n#  id         :integer          not null, primary key\n#  avatar_url :string\n#  html_url   :string\n#  login      :string           not null, uniquely indexed\n#  name       :string\n#  created_at :datetime         not null\n#  updated_at :datetime         not null\n#  user_id    :integer          indexed\n#\n# Indexes\n#\n#  index_contributors_on_login    (login) UNIQUE\n#  index_contributors_on_user_id  (user_id)\n#\n# Foreign Keys\n#\n#  user_id  (user_id => users.id)\n#\nclass Contributor < ApplicationRecord\n  belongs_to :user, optional: true\n\n  validates :login, presence: true, uniqueness: true\n\n  def name\n    return super if user_id.blank?\n\n    user.name || super\n  end\nend\n"
  },
  {
    "path": "app/models/coordinate_location.rb",
    "content": "# frozen_string_literal: true\n\nclass CoordinateLocation\n  include ActiveModel::Model\n  include ActiveModel::Attributes\n\n  attribute :latitude, :decimal\n  attribute :longitude, :decimal\n\n  def initialize(latitude:, longitude:)\n    super(latitude: latitude.to_d, longitude: longitude.to_d)\n\n    @reverse_geocoded = false\n  end\n\n  def name\n    @name ||= reverse_geocode_display_name\n  end\n\n  def full_name\n    @full_name ||= reverse_geocode_full_name\n  end\n\n  def slug\n    coordinates_param\n  end\n\n  def emoji_flag\n    country&.emoji_flag || \"📍\"\n  end\n\n  def path\n    Router.coordinates_path(coordinates: coordinates_param)\n  end\n\n  def past_path\n    Router.coordinates_past_index_path(coordinates: coordinates_param)\n  end\n\n  def users_path\n    Router.coordinates_users_path(coordinates: coordinates_param)\n  end\n\n  def cities_path\n    nil\n  end\n\n  def stamps_path\n    nil\n  end\n\n  def map_path\n    Router.coordinates_map_index_path(coordinates: coordinates_param)\n  end\n\n  def has_routes?\n    true\n  end\n\n  def events\n    @events ||= nearby_events_query\n  end\n\n  def users\n    @users ||= nearby_users_query\n  end\n\n  def stamps\n    []\n  end\n\n  def events_count\n    events.count\n  end\n\n  def users_count\n    users.count\n  end\n\n  def geocoded?\n    latitude.present? && longitude.present?\n  end\n\n  def coordinates\n    return nil unless geocoded?\n\n    [latitude, longitude]\n  end\n\n  def to_coordinates\n    coordinates\n  end\n\n  def bounds\n    return nil unless geocoded?\n\n    offset = 1.0\n\n    {\n      southwest: [longitude.to_f - offset, latitude.to_f - offset],\n      northeast: [longitude.to_f + offset, latitude.to_f + offset]\n    }\n  end\n\n  def to_location\n    Location.new(\n      city: reverse_geocode_city,\n      state_code: reverse_geocode_state,\n      country_code: country_code,\n      latitude: latitude,\n      longitude: longitude,\n      raw_location: full_name\n    )\n  end\n\n  def alpha2\n    country_code\n  end\n\n  def country_code\n    @country_code ||= reverse_geocode_data&.country_code\n  end\n\n  def country\n    return nil unless country_code.present?\n\n    @country ||= Country.find_by(country_code: country_code)\n  end\n\n  def continent\n    country&.continent\n  end\n\n  def nearby_users(radius_km: 100, limit: 12, exclude_ids: [])\n    return [] unless coordinates.present?\n\n    User.geocoded\n      .near(coordinates, radius_km, units: :km)\n      .where.not(id: exclude_ids)\n      .limit(limit)\n      .map do |user|\n        distance = Geocoder::Calculations.distance_between(\n          coordinates,\n          [user.latitude, user.longitude],\n          units: :km\n        )\n\n        {user: user, distance_km: distance.round}\n      end\n      .sort_by { |u| u[:distance_km] }\n  end\n\n  def nearby_events(radius_km: 250, limit: 12, exclude_ids: [])\n    return [] unless coordinates.present?\n\n    scope = Event.includes(:series, :participants).where.not(latitude: nil, longitude: nil)\n    scope = scope.where.not(id: exclude_ids) if exclude_ids.any?\n\n    scope.map do |event|\n      distance = Geocoder::Calculations.distance_between(\n        coordinates,\n        [event.latitude, event.longitude],\n        units: :km\n      )\n\n      {event: event, distance_km: distance.round} if distance <= radius_km\n    end\n      .compact\n      .sort_by { |e| e[:event].start_date || Time.at(0).to_date }\n      .last(limit)\n      .reverse\n  end\n\n  private\n\n  def coordinates_param\n    \"#{latitude},#{longitude}\"\n  end\n\n  def reverse_geocode_data\n    return @reverse_geocode_data if @reverse_geocoded\n\n    @reverse_geocoded = true\n\n    @reverse_geocode_data = Geocoder.search(coordinates).first\n  end\n\n  def reverse_geocode_display_name\n    data = reverse_geocode_data\n\n    return \"#{latitude}, #{longitude}\" unless data\n\n    data.city.presence || data.state.presence || data.country.presence || \"#{latitude}, #{longitude}\"\n  end\n\n  def reverse_geocode_full_name\n    data = reverse_geocode_data\n\n    return \"#{latitude}, #{longitude}\" unless data\n\n    parts = [data.city, data.state, data.country].compact.reject(&:blank?)\n\n    parts.any? ? parts.join(\", \") : \"#{latitude}, #{longitude}\"\n  end\n\n  def reverse_geocode_city\n    reverse_geocode_data&.city\n  end\n\n  def reverse_geocode_state\n    reverse_geocode_data&.state\n  end\n\n  def nearby_events_query\n    return Event.none unless coordinates.present?\n\n    lat_range, lon_range = bounding_box_for_radius(250)\n\n    Event.includes(:series)\n      .where(latitude: lat_range, longitude: lon_range)\n      .order(start_date: :desc)\n  end\n\n  def nearby_users_query\n    return User.none unless coordinates.present?\n\n    lat_range, lon_range = bounding_box_for_radius(100)\n\n    User.indexable\n      .geocoded\n      .where(latitude: lat_range, longitude: lon_range)\n  end\n\n  def bounding_box_for_radius(radius_km)\n    lat_delta = radius_km / 111.0\n    lon_delta = radius_km / (111.0 * Math.cos(latitude.to_f * Math::PI / 180))\n\n    lat_range = (latitude.to_f - lat_delta)..(latitude.to_f + lat_delta)\n    lon_range = (longitude.to_f - lon_delta)..(longitude.to_f + lon_delta)\n\n    [lat_range, lon_range]\n  end\n\n  class << self\n    def from_param(param)\n      return nil unless param.present?\n\n      lat, lon = param.split(\",\").map(&:to_f)\n\n      return nil unless lat.present? && lon.present?\n      return nil unless lat.between?(-90, 90) && lon.between?(-180, 180)\n\n      new(latitude: lat, longitude: lon)\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/country.rb",
    "content": "class Country\n  include Locatable\n\n  UK_NATIONS = {\n    \"england\" => {code: \"ENG\", name: \"England\"},\n    \"scotland\" => {code: \"SCT\", name: \"Scotland\"},\n    \"wales\" => {code: \"WLS\", name: \"Wales\"},\n    \"northern-ireland\" => {code: \"NIR\", name: \"Northern Ireland\"}\n  }.freeze\n\n  attr_reader :record\n\n  delegate :alpha2, :alpha3, :emoji_flag, :subdivisions, :iso_short_name, :common_name, :translations, to: :record\n\n  def continent_name\n    record.continent\n  end\n\n  def continent\n    @continent ||= Continent.find_by_name(continent_name)\n  end\n\n  def initialize(record)\n    @record = record\n  end\n\n  def name\n    record.translations[\"en\"] || record.common_name || record.iso_short_name\n  end\n\n  def slug\n    name.unicode_normalize(:nfkd).parameterize\n  end\n\n  def path\n    Router.country_path(slug)\n  end\n\n  def past_path\n    Router.country_past_index_path(self)\n  end\n\n  def users_path\n    Router.country_users_path(self)\n  end\n\n  def meetups_path\n    Router.country_meetups_path(self)\n  end\n\n  def cities_path\n    Router.country_cities_path(self)\n  end\n\n  def stamps_path\n    Router.country_stamps_path(self)\n  end\n\n  def map_path\n    Router.country_map_index_path(self)\n  end\n\n  def to_location\n    Location.new(country_code: alpha2, raw_location: \"#{name}, #{continent_name}\")\n  end\n\n  def code\n    alpha2.downcase\n  end\n\n  def latitude\n    record.geo&.dig(\"latitude\")\n  end\n\n  def longitude\n    record.geo&.dig(\"longitude\")\n  end\n\n  def coordinates\n    return nil unless latitude && longitude\n    [longitude, latitude]\n  end\n\n  def bounds\n    geo_bounds = record.geo&.dig(\"bounds\")\n    return nil unless geo_bounds\n\n    {\n      southwest: [geo_bounds.dig(\"southwest\", \"lng\"), geo_bounds.dig(\"southwest\", \"lat\")],\n      northeast: [geo_bounds.dig(\"northeast\", \"lng\"), geo_bounds.dig(\"northeast\", \"lat\")]\n    }\n  end\n\n  def to_param\n    slug\n  end\n\n  def ==(other)\n    other.is_a?(Country) && alpha2 == other.alpha2\n  end\n\n  def eql?(other)\n    self == other\n  end\n\n  def hash\n    alpha2.hash\n  end\n\n  def events\n    Event.where(country_code: alpha2)\n  end\n\n  def users\n    User.indexable.geocoded.where(country_code: alpha2)\n  end\n\n  def cities\n    City.where(country_code: alpha2)\n  end\n\n  def states\n    State.for_country(self)\n  end\n\n  def states?\n    subdivisions.any? && !alpha2.in?(State::EXCLUDED_COUNTRIES)\n  end\n\n  def stamps\n    stamps = Stamp.all.select { |stamp| stamp.has_country? && stamp.country&.alpha2 == alpha2 }\n\n    if alpha2 == \"GB\"\n      uk_nation_stamps = Stamp.all.select { |stamp| stamp.has_country? && stamp.country.is_a?(UKNation) }\n      stamps = (stamps + uk_nation_stamps).uniq { |s| s.code }\n    end\n\n    stamps\n  end\n\n  def held_in_sentence\n    if name.starts_with?(\"United\")\n      \" held in the #{name}\"\n    else\n      \" held in #{name}\"\n    end\n  end\n\n  def uk_nation?\n    false\n  end\n\n  class << self\n    def find(term)\n      term = term.to_s.tr(\"-\", \" \")\n      term_slug = term.parameterize\n\n      return nil if term.blank?\n      return nil if term.downcase.in?(%w[online earth unknown])\n\n      if UK_NATIONS.key?(term_slug)\n        return UKNation.new(term_slug)\n      end\n\n      iso_record = find_iso_record(term)\n      return new(iso_record) if iso_record\n\n      # Fallback: match against country name slugs and diacritics-stripped slugs\n      match = all.find { |country|\n        country.slug == term_slug ||\n          country.name.unicode_normalize(:nfkd).gsub(/\\p{Mn}/, \"\").parameterize == term_slug\n      }\n      match ? new(match.record) : nil\n    end\n\n    def find_by(country_code:)\n      return nil if country_code.blank?\n\n      iso_record = ISO3166::Country.new(country_code.upcase)\n      iso_record&.alpha2 ? new(iso_record) : nil\n    end\n\n    def all\n      @all ||= ISO3166::Country.all.map { |iso_record| new(iso_record) }\n    end\n\n    def all_with_uk_nations\n      @all_with_uk_nations ||= all + uk_nations\n    end\n\n    def uk_nations\n      UK_NATIONS.keys.map { |slug| UKNation.new(slug) }\n    end\n\n    def valid_country_codes\n      @valid_country_codes ||= ISO3166::Country.codes\n    end\n\n    def all_by_slug\n      @all_by_slug ||= all.index_by(&:slug)\n    end\n\n    def slugs\n      all.map(&:slug)\n    end\n\n    def select_options\n      all.map { |country| [country.name, country.alpha2] }.sort_by(&:first)\n    end\n\n    def search(query)\n      return nil if query.blank?\n\n      results = Geocoder.search(query)\n      return nil if results.empty?\n\n      country_code = results.first.country_code\n      return nil if country_code.blank?\n\n      find_by(country_code: country_code)\n    end\n\n    private\n\n    def find_iso_record(term)\n      return ISO3166::Country.new(\"GB\") if term == \"UK\"\n\n      if term.length == 2\n        country = ISO3166::Country.new(term.upcase)\n        return country if country&.alpha2\n      end\n\n      result = ISO3166::Country.find_country_by_iso_short_name(term) ||\n        ISO3166::Country.find_country_by_unofficial_names(term) ||\n        ISO3166::Country.search(term)\n\n      return result if result\n\n      return ISO3166::Country.new(\"US\") if ISO3166::Country.new(\"US\").subdivisions.key?(term)\n\n      nil\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/cue.rb",
    "content": "class Cue\n  attr_reader :start_time, :end_time, :text\n\n  def initialize(start_time:, end_time:, text:)\n    @start_time = start_time\n    @end_time = end_time\n    @text = text || \"\"\n  end\n\n  def to_s\n    \"#{start_time} --> #{end_time}\\n#{text}\"\n  end\n\n  def to_h\n    {\n      start_time: start_time,\n      end_time: end_time,\n      text: text\n    }\n  end\n\n  def start_time_in_seconds\n    time_string_to_seconds(start_time)\n  end\n\n  def time_string_to_seconds(time_string)\n    parts = time_string.split(\":\").map(&:to_f)\n    hours = parts[0] * 3600\n    minutes = parts[1] * 60\n    seconds = parts[2]\n    (hours + minutes + seconds).to_i\n  rescue\n    0\n  end\n\n  def sound_descriptor?\n    text&.match?(/\\[(music|sound|audio|applause|laughter|speech|voice|speeches|voices)\\]/i)\n  end\nend\n"
  },
  {
    "path": "app/models/current.rb",
    "content": "class Current < ActiveSupport::CurrentAttributes\n  attribute :session, :user\n  attribute :user_agent, :ip_address\n\n  def session=(session)\n    super\n    self.user = session&.user\n  end\nend\n"
  },
  {
    "path": "app/models/email_verification_token.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: email_verification_tokens\n# Database name: primary\n#\n#  id      :integer          not null, primary key\n#  user_id :integer          not null, indexed\n#\n# Indexes\n#\n#  index_email_verification_tokens_on_user_id  (user_id)\n#\n# Foreign Keys\n#\n#  user_id  (user_id => users.id)\n#\n# rubocop:enable Layout/LineLength\nclass EmailVerificationToken < ApplicationRecord\n  belongs_to :user\nend\n"
  },
  {
    "path": "app/models/event/assets.rb",
    "content": "# -*- SkipSchemaAnnotations\n\nclass Event::Assets < ActiveRecord::AssociatedObject\n  IMAGES_BASE_PATH = Rails.root.join(\"app\", \"assets\", \"images\")\n\n  extension do\n    delegate :stickers, :sticker?, :stamp?, to: :assets\n\n    def event_image_path = assets.base_path\n    def event_image_for(filename) = assets.image_path_if_exists(filename)\n    def banner_image_path = assets.banner_path\n    def card_image_path = assets.card_path\n    def avatar_image_path = assets.avatar_path\n    def featured_image_path = assets.featured_path\n    def poster_image_path = assets.poster_path\n    def sticker_image_paths = assets.sticker_paths\n    def sticker_image_path = assets.sticker_path\n    def stamp_image_paths = assets.stamp_paths\n    def stamp_image_path = assets.stamp_path\n\n    def avatar_url\n      return nil unless avatar_image_path\n\n      Router.image_url(avatar_image_path)\n    end\n\n    def banner_url\n      return nil unless banner_image_path\n\n      Router.image_url(banner_image_path)\n    end\n  end\n\n  def base_path\n    [\"events\", event.series.slug, event.slug].join(\"/\")\n  end\n\n  def default_path\n    [\"events\", \"default\"].join(\"/\")\n  end\n\n  def default_series_path\n    [\"events\", event.series.slug, \"default\"].join(\"/\")\n  end\n\n  def image_path_for(filename)\n    event_path = [base_path, filename].join(\"/\")\n    series_default_path = [default_series_path, filename].join(\"/\")\n    global_default_path = [default_path, filename].join(\"/\")\n\n    return event_path if (IMAGES_BASE_PATH / event_path).exist?\n    return series_default_path if (IMAGES_BASE_PATH / series_default_path).exist?\n\n    global_default_path\n  end\n\n  def image_path_if_exists(filename)\n    event_path = [base_path, filename].join(\"/\")\n\n    (IMAGES_BASE_PATH / event_path).exist? ? event_path : nil\n  end\n\n  def banner_path\n    image_path_for(\"banner.webp\")\n  end\n\n  def card_path\n    image_path_for(\"card.webp\")\n  end\n\n  def avatar_path\n    image_path_for(\"avatar.webp\")\n  end\n\n  def featured_path\n    image_path_for(\"featured.webp\")\n  end\n\n  def poster_path\n    image_path_for(\"poster.webp\")\n  end\n\n  def stickers\n    Sticker.for_event(event)\n  end\n\n  def sticker_paths\n    stickers.map(&:file_path)\n  end\n\n  def sticker_path\n    sticker_paths.first\n  end\n\n  def sticker?\n    sticker_paths.any?\n  end\n\n  def stamp_paths\n    Dir.glob(IMAGES_BASE_PATH.join(base_path, \"stamp*.webp\")).map { |path|\n      Pathname.new(path).relative_path_from(IMAGES_BASE_PATH).to_s\n    }.sort\n  end\n\n  def stamp_path\n    stamp_paths.first\n  end\n\n  def stamp?\n    stamp_paths.any?\n  end\nend\n"
  },
  {
    "path": "app/models/event/cfp_file.rb",
    "content": "# -*- SkipSchemaAnnotations\n\nclass Event::CFPFile < ActiveRecord::AssociatedObject\n  include YAMLFile\n\n  yaml_file \"cfp.yml\"\n\n  def find_by_link(link)\n    entries.find { |cfp| cfp[\"link\"] == link }\n  end\n\n  def add(link:, open_date: nil, close_date: nil, name: nil)\n    return {error: \"A CFP with this link already exists\"} if find_by_link(link)\n\n    new_entry = build_entry(link: link, open_date: open_date, close_date: close_date, name: name)\n    write(entries + [new_entry])\n\n    new_entry\n  end\n\n  def update(link:, open_date: nil, close_date: nil, name: nil)\n    existing = find_by_link(link)\n    return {error: \"No CFP found with this link\"} unless existing\n\n    updated_entries = entries.map do |cfp|\n      next cfp unless cfp[\"link\"] == link\n\n      cfp[\"name\"] = name if name.present?\n      cfp[\"open_date\"] = open_date if open_date.present?\n      cfp[\"close_date\"] = close_date if close_date.present?\n\n      cfp\n    end\n\n    write(updated_entries)\n\n    find_by_link(link)\n  end\n\n  def write(cfps)\n    File.write(file_path, cfps.to_yaml)\n  end\n\n  private\n\n  def build_entry(link:, open_date:, close_date:, name:)\n    entry = {}\n\n    entry[\"name\"] = name if name.present?\n    entry[\"link\"] = link\n    entry[\"open_date\"] = open_date if open_date.present?\n    entry[\"close_date\"] = close_date if close_date.present?\n\n    entry\n  end\nend\n"
  },
  {
    "path": "app/models/event/involvements_file.rb",
    "content": "# -*- SkipSchemaAnnotations\n\nclass Event::InvolvementsFile < ActiveRecord::AssociatedObject\n  include YAMLFile\n\n  yaml_file \"involvements.yml\"\n\n  def roles\n    entries.map { |entry| entry[\"name\"] }\n  end\n\n  def users_for_role(role)\n    entry = entries.find { |e| e[\"name\"] == role }\n    return [] unless entry\n\n    Array.wrap(entry[\"users\"]).compact\n  end\n\n  def organisations_for_role(role)\n    entry = entries.find { |e| e[\"name\"] == role }\n    return [] unless entry\n\n    Array.wrap(entry[\"organisations\"]).compact\n  end\n\n  def all_users\n    entries.flat_map { |entry| Array.wrap(entry[\"users\"]) }.compact\n  end\n\n  def all_organisations\n    entries.flat_map { |entry| Array.wrap(entry[\"organisations\"]) }.compact\n  end\nend\n"
  },
  {
    "path": "app/models/event/schedule.rb",
    "content": "class Event::Schedule < ActiveRecord::AssociatedObject\n  include YAMLFile\n\n  yaml_file \"schedule.yml\"\n\n  def days\n    file.fetch(\"days\", [])\n  end\n\n  def tracks\n    file.fetch(\"tracks\", [])\n  end\n\n  def talk_offsets\n    days.map { |day|\n      grid = day.fetch(\"grid\", [])\n\n      grid.sum { |item| item.fetch(\"items\", []).any? ? 0 : item[\"slots\"] }\n    }\n  end\nend\n"
  },
  {
    "path": "app/models/event/sponsors_file.rb",
    "content": "# -*- SkipSchemaAnnotations\nclass Event::SponsorsFile < ActiveRecord::AssociatedObject\n  include YAMLFile\n\n  yaml_file \"sponsors.yml\"\n\n  def tier_names\n    tiers = file[:tiers] || file[\"tiers\"] || []\n\n    tiers.map { |tier| tier[:name] || tier[\"name\"] }\n  end\n\n  def sponsors\n    tiers = file[:tiers] || file[\"tiers\"] || []\n\n    tiers.flat_map { |tier| tier[:sponsors] || tier[\"sponsors\"] || [] }\n  end\n\n  # Option 1: Use event website as base URL\n  #   event.sponsors_file.download\n  #\n  # Option 2: Specify a different base URL\n  #   event.sponsors_file.download(base_url: \"https://example.com/conference\")\n  #\n  # Option 3: Direct sponsors URL\n  #   event.sponsors_file.download(sponsors_url: \"https://example.com/sponsors\")\n  #\n  # Option 4: Raw HTML content\n  #   event.sponsors_file.download(html: \"<html>...</html>\")\n  #\n  def download(base_url: nil, sponsors_url: nil, html: nil)\n    # Default to event website as base_url if no arguments provided\n    if [base_url, sponsors_url, html].compact.empty?\n      base_url = event.website\n    end\n\n    # Log which input method is being used\n    if html\n      puts \"Using HTML content: #{html.length} characters\"\n    elsif sponsors_url\n      puts \"Using sponsors URL: #{sponsors_url}\"\n    elsif base_url\n      puts \"Using base URL: #{base_url}\"\n    end\n\n    DownloadSponsors.new.download_sponsors(\n      base_url: base_url,\n      sponsors_url: sponsors_url,\n      html: html,\n      save_file: event.data_folder.join(FILE_NAME)\n    )\n  end\nend\n"
  },
  {
    "path": "app/models/event/static_metadata.rb",
    "content": "class Event::StaticMetadata < ActiveRecord::AssociatedObject\n  extension do\n    def featured_metadata? = static_metadata.featured_background?\n  end\n\n  delegate :published_date, :home_sort_date, to: :static_repository, allow_nil: true\n\n  def kind\n    return static_repository.kind if static_repository&.kind\n    return \"conference\" if event.series&.conference?\n    return \"meetup\" if event.series&.meetup?\n\n    \"event\"\n  end\n\n  def conference?\n    kind == \"conference\"\n  end\n\n  def meetup?\n    kind == \"meetup\"\n  end\n\n  def retreat?\n    kind == \"retreat\"\n  end\n\n  def hackathon?\n    kind == \"hackathon\"\n  end\n\n  def frequency\n    static_repository&.frequency || event.series.frequency\n  end\n\n  def start_date\n    @start_date ||= static_repository.start_date.present? ? static_repository.start_date : event.talks.minimum(:date)\n  rescue => _e\n    event.talks.minimum(:date)\n  end\n\n  def end_date\n    @end_date ||= static_repository.end_date.present? ? static_repository.end_date : event.talks.map(&:date).max\n  rescue => _e\n    event.talks.map(&:date).max\n  end\n\n  def date_precision\n    static_repository.date_precision || \"day\"\n  end\n\n  def year\n    static_repository.year.present? ? static_repository.year : event.talks.first.try(:date).try(:year)\n  rescue => _e\n    event.talks.first.try(:date).try(:year)\n  end\n\n  def featured_background?\n    return false unless static_repository\n\n    static_repository.featured_background.present? || static_repository.featured_color.present?\n  end\n\n  def featured_background\n    return static_repository.featured_background if static_repository.featured_background.present?\n\n    \"black\"\n  rescue => e\n    raise \"No featured background found for #{event.name} :  #{e.message}. You might have to restart your Rails server.\" if Rails.env.local?\n    \"black\"\n  end\n\n  def featured_color\n    static_repository.featured_color.present? ? static_repository.featured_color : \"white\"\n  rescue => e\n    raise \"No featured color found for #{event.name} :  #{e.message}. You might have to restart your Rails server.\" if Rails.env.local?\n    \"white\"\n  end\n\n  def banner_background\n    static_repository.banner_background.present? ? static_repository.banner_background : \"#081625\"\n  rescue => e\n    raise \"No featured background found for #{event.name} :  #{e.message}. You might have to restart your Rails server.\" if Rails.env.local?\n    \"#081625\"\n  end\n\n  def location\n    static_repository&.location&.presence || \"Earth\"\n  end\n\n  def coordinates\n    static_repository&.coordinates\n  end\n\n  def country\n    return nil if location.blank?\n\n    Country.find(location.to_s.split(\",\").last&.strip)\n  end\n\n  def last_edition?\n    static_repository&.last_edition || false\n  end\n\n  def hybrid?\n    !!static_repository.try(:hybrid) || false\n  end\n\n  def cancelled?\n    static_repository&.status == \"cancelled\"\n  end\n\n  def playlist\n    static_repository&.playlist\n  end\n\n  private\n\n  def static_repository\n    @static_repository ||= Static::Event.find_by_slug(event.slug)\n  end\nend\n"
  },
  {
    "path": "app/models/event/tickets.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"uri\"\n\nclass Event::Tickets < ActiveRecord::AssociatedObject\n  PROVIDERS = {\n    \"Tito\" => [\"ti.to\", \"tito.io\"],\n    \"Luma\" => [\"lu.ma\", \"luma.com\"],\n    \"Meetup\" => [\"meetup.com\"],\n    \"Connpass\" => [\"connpass.com\"],\n    \"Pretix\" => [\"pretix.eu\"],\n    \"Eventpop\" => [\"eventpop.me\"],\n    \"Eventbrite\" => [\"eventbrite.com\", \"eventbrite.co.uk\"],\n    \"TicketTailor\" => [\"tickettailor.com\"],\n    \"Sympla\" => [\"sympla.com.br\"]\n  }.freeze\n\n  extension do\n    def tickets?\n      tickets.exist?\n    end\n\n    def next_upcoming_event_with_tickets\n      return nil if series.nil?\n\n      series.events\n        .upcoming\n        .select(&:tickets?)\n        .reject { |e| e.id == id }\n        .first\n    end\n  end\n\n  def url\n    static_repository&.attributes&.dig(\"tickets_url\")\n  end\n\n  def exist?\n    url.present?\n  end\n\n  def available?\n    exist? && event.upcoming?\n  end\n\n  def tito_event_slug\n    return nil unless tito?\n\n    match = url&.match(%r{(?:ti\\.to|tito\\.io)/(.+?)/?$})\n    match&.captures&.first\n  end\n\n  def provider\n    @provider ||= ActiveSupport::StringInquirer.new(provider_name.to_s.downcase)\n  end\n\n  def provider_name\n    PROVIDERS.find { |_, domains| host_is?(*domains) }&.first\n  end\n\n  def tito? = provider.tito?\n  def luma? = provider.luma?\n  def meetup? = provider.meetup?\n\n  private\n\n  def ticket_url_host\n    return nil if url.blank?\n\n    URI.parse(url).host&.downcase\n  rescue URI::InvalidURIError\n    nil\n  end\n\n  def host_is?(*domains)\n    host = ticket_url_host&.delete_prefix(\"www.\")\n    return false if host.nil?\n\n    domains.any? { |domain| host == domain.downcase }\n  end\n\n  def static_repository\n    @static_repository ||= Static::Event.find_by_slug(event.slug)\n  end\nend\n"
  },
  {
    "path": "app/models/event/transcripts_file.rb",
    "content": "# -*- SkipSchemaAnnotations\n\nclass Event::TranscriptsFile < ActiveRecord::AssociatedObject\n  include YAMLFile\n\n  yaml_file \"transcripts.yml\"\n\n  def video_ids\n    entries.map { |entry| entry[\"video_id\"] }.compact\n  end\n\n  def find_by_video_id(video_id)\n    entries.find { |entry| entry[\"video_id\"] == video_id }\n  end\n\n  def cues_for_video(video_id)\n    entry = find_by_video_id(video_id)\n    return [] unless entry\n\n    Array.wrap(entry[\"cues\"])\n  end\nend\n"
  },
  {
    "path": "app/models/event/typesense_searchable.rb",
    "content": "# frozen_string_literal: true\n\nmodule Event::TypesenseSearchable\n  extend ActiveSupport::Concern\n\n  included do\n    include ::Typesense\n\n    typesense enqueue: :trigger_typesense_job, if: :should_index?, disable_indexing: -> { Search::Backend.skip_indexing } do\n      attributes :name, :slug, :kind, :website\n\n      attribute :start_date_timestamp do\n        start_date&.to_time&.to_i || 0\n      end\n\n      attribute :end_date_timestamp do\n        end_date&.to_time&.to_i || 0\n      end\n\n      attribute :year do\n        start_date&.year\n      end\n\n      attribute :formatted_dates\n      attributes :city, :country_code\n      attribute :country_code\n\n      attribute :location do\n        [city, country_code].compact.join(\", \")\n      end\n\n      attribute :coordinates do\n        if latitude.present? && longitude.present?\n          [latitude.to_f, longitude.to_f]\n        end\n      end\n\n      attribute :series do\n        {\n          id: series.id,\n          name: series.name,\n          slug: series.slug\n        }\n      end\n\n      attribute :series_name do\n        series.name\n      end\n\n      attribute :series_slug do\n        series.slug\n      end\n\n      attribute :talks_count\n\n      attribute :speakers_count do\n        speakers.count\n      end\n\n      # Images\n      attribute :card_image_path\n      attribute :avatar_image_path\n\n      attribute :alias_names do\n        slug_aliases.pluck(:name)\n      end\n\n      attribute :alias_slugs do\n        slug_aliases.pluck(:slug)\n      end\n\n      attribute :series_alias_names do\n        series&.aliases&.pluck(:name) || []\n      end\n\n      attribute :series_alias_slugs do\n        series&.aliases&.pluck(:slug) || []\n      end\n\n      attribute :keynote_speaker_names do\n        keynote_speakers.pluck(:name)\n      end\n\n      attribute :topic_names do\n        topics.approved.distinct.pluck(:name)\n      end\n\n      attribute :talk_languages do\n        talks.where.not(language: [nil, \"\"]).distinct.pluck(:language)\n      end\n\n      attribute :talk_language_names do\n        talks.where.not(language: [nil, \"\"]).distinct.pluck(:language).map { |code| Language.by_code(code) }.compact\n      end\n\n      attribute :description\n\n      predefined_fields [\n        {\"name\" => \"name\", \"type\" => \"string\"},\n        {\"name\" => \"description\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"series_name\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"alias_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"series_alias_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"series_alias_slugs\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"keynote_speaker_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"topic_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"talk_languages\", \"type\" => \"string[]\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"talk_language_names\", \"type\" => \"string[]\", \"optional\" => true},\n\n        {\"name\" => \"kind\", \"type\" => \"string\", \"facet\" => true},\n        {\"name\" => \"year\", \"type\" => \"int32\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"country_code\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"country_name\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"city\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"series_slug\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n\n        {\"name\" => \"start_date_timestamp\", \"type\" => \"int64\"},\n        {\"name\" => \"end_date_timestamp\", \"type\" => \"int64\"},\n        {\"name\" => \"talks_count\", \"type\" => \"int32\"},\n        {\"name\" => \"speakers_count\", \"type\" => \"int32\"},\n\n        {\"name\" => \"slug\", \"type\" => \"string\"},\n        {\"name\" => \"website\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"location\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"formatted_dates\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"card_image_path\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"avatar_image_path\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"alias_slugs\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"series\", \"type\" => \"object\", \"optional\" => true},\n\n        {\"name\" => \"coordinates\", \"type\" => \"geopoint\", \"optional\" => true}\n      ]\n\n      default_sorting_field \"start_date_timestamp\"\n\n      enable_nested_fields true\n\n      multi_way_synonyms [\n        {\"conference-synonym\" => %w[conference conf conferences]},\n        {\"meetup-synonym\" => %w[meetup meetups meet-up usergroup user-group]},\n        {\"workshop-synonym\" => %w[workshop workshops hands-on training]},\n        {\"retreat-synonym\" => %w[retreat retreats unconference unconf]},\n        {\"hackathon-synonym\" => %w[hackathon hackathons hack-day hackday]},\n        {\"rubyconf-synonym\" => %w[rubyconf ruby-conf ruby-conference]},\n        {\"railsconf-synonym\" => %w[railsconf rails-conf rails-conference]}\n      ]\n    end\n  end\n\n  class_methods do\n    def trigger_typesense_job(record, remove)\n      TypesenseIndexJob.perform_later(record, remove ? \"typesense_remove_from_index!\" : \"typesense_index!\")\n    end\n\n    def typesense_search_events(query, options = {})\n      query_by_fields = \"name,description,series_name,series_slug,alias_names,alias_slugs,series_alias_names,series_alias_slugs,keynote_speaker_names,topic_names,talk_language_names,kind,city,country_name\"\n\n      search_options = {\n        query_by_weights: \"10,3,8,7,5,5,6,6,4,3,3,3,2,2\",\n        per_page: options[:per_page] || 20,\n        page: options[:page] || 1\n      }\n\n      filters = []\n      filters << \"kind:=#{options[:kind]}\" if options[:kind].present?\n      filters << \"year:=#{options[:year]}\" if options[:year].present?\n      filters << \"country_code:=#{options[:country_code]}\" if options[:country_code].present?\n      filters << \"series_slug:=#{options[:series_slug]}\" if options[:series_slug].present?\n\n      if options[:upcoming]\n        filters << \"start_date_timestamp:>=#{Time.current.to_i}\"\n      end\n\n      if options[:past]\n        filters << \"end_date_timestamp:<#{Time.current.to_i}\"\n      end\n\n      search_options[:filter_by] = filters.join(\" && \") if filters.any?\n\n      sort_options = {\n        \"date\" => \"start_date_timestamp:desc\",\n        \"date_asc\" => \"start_date_timestamp:asc\",\n        \"talks\" => \"talks_count:desc\",\n        \"relevance\" => \"_text_match:desc,start_date_timestamp:desc\"\n      }\n      search_options[:sort_by] = sort_options[options[:sort]] || sort_options[\"date\"]\n\n      if options[:facets]\n        search_options[:facet_by] = options[:facets].join(\",\")\n      end\n\n      search(query.presence || \"*\", query_by_fields, search_options)\n    end\n  end\n\n  private\n\n  def should_index?\n    canonical_id.nil?\n  end\nend\n"
  },
  {
    "path": "app/models/event/venue.rb",
    "content": "class Event::Venue < ActiveRecord::AssociatedObject\n  include YAMLFile\n\n  yaml_file \"venue.yml\"\n\n  extension do\n    def geocode\n      super\n\n      if venue.exist? && venue.coordinates.present?\n        coords = venue.coordinates\n        self.latitude = coords[\"latitude\"]\n        self.longitude = coords[\"longitude\"]\n      end\n    end\n  end\n\n  def name\n    file[\"name\"]\n  end\n\n  def slug\n    file[\"slug\"]\n  end\n\n  def description\n    file[\"description\"]\n  end\n\n  def address\n    file[\"address\"] || {}\n  end\n\n  def display_address\n    address[\"display\"]\n  end\n\n  def street\n    address[\"street\"]\n  end\n\n  def city\n    address[\"city\"]\n  end\n\n  def region\n    address[\"region\"]\n  end\n\n  def postal_code\n    address[\"postal_code\"]\n  end\n\n  def country\n    address[\"country\"]\n  end\n\n  def country_code\n    address[\"country_code\"]\n  end\n\n  def coordinates\n    file[\"coordinates\"] || {}\n  end\n\n  def latitude\n    coordinates[\"latitude\"]\n  end\n\n  def longitude\n    coordinates[\"longitude\"]\n  end\n\n  def maps\n    file[\"maps\"] || {}\n  end\n\n  def google_maps_url\n    maps[\"google\"]\n  end\n\n  def apple_maps_url\n    maps[\"apple\"]\n  end\n\n  def openstreetmap_url\n    maps[\"openstreetmap\"]\n  end\n\n  def instructions\n    file[\"instructions\"]\n  end\n\n  def url\n    file[\"url\"]\n  end\n\n  def accessibility\n    file[\"accessibility\"] || {}\n  end\n\n  def rooms\n    file[\"rooms\"] || []\n  end\n\n  def spaces\n    file[\"spaces\"] || []\n  end\n\n  def nearby\n    file[\"nearby\"] || {}\n  end\n\n  def hotels\n    file[\"hotels\"] || []\n  end\n\n  def locations\n    file[\"locations\"] || []\n  end\n\n  def map_markers\n    markers = []\n\n    if latitude.present? && longitude.present?\n      markers << {\n        latitude: latitude,\n        longitude: longitude,\n        kind: \"venue\",\n        name: name,\n        address: display_address\n      }\n    end\n\n    hotels.each do |hotel|\n      coords = hotel[\"coordinates\"]\n      next unless coords&.dig(\"latitude\").present? && coords&.dig(\"longitude\").present?\n\n      markers << {\n        latitude: coords[\"latitude\"],\n        longitude: coords[\"longitude\"],\n        kind: \"hotel\",\n        name: hotel[\"name\"],\n        address: hotel.dig(\"address\", \"display\"),\n        distance: hotel[\"distance\"]\n      }\n    end\n\n    locations.each do |location|\n      coords = location[\"coordinates\"]\n      next unless coords&.dig(\"latitude\").present? && coords&.dig(\"longitude\").present?\n\n      markers << {\n        latitude: coords[\"latitude\"],\n        longitude: coords[\"longitude\"],\n        kind: \"location\",\n        name: location[\"name\"],\n        location_kind: location[\"kind\"],\n        address: location.dig(\"address\", \"display\"),\n        distance: location[\"distance\"]\n      }\n    end\n\n    markers\n  end\nend\n"
  },
  {
    "path": "app/models/event/videos_file.rb",
    "content": "# -*- SkipSchemaAnnotations\n\nclass Event::VideosFile < ActiveRecord::AssociatedObject\n  include YAMLFile\n\n  yaml_file \"videos.yml\"\n\n  extension do\n    def talks_in_running_order(child_talks: true)\n      talks.in_order_of(:static_id, videos_file.ids(child_talks: child_talks))\n    end\n  end\n\n  def ids(child_talks: true)\n    return [] unless exist?\n\n    if child_talks\n      entries.flat_map { |talk|\n        [talk.dig(\"id\"), *talk[\"talks\"]&.map { |child_talk|\n          child_talk.dig(\"id\")\n        }]\n      }\n    else\n      entries.map { |talk| talk.dig(\"id\") }\n    end\n  end\n\n  def find_by_id(id)\n    entries.find { |talk| talk[\"id\"] == id }\n  end\n\n  def count\n    entries.size\n  end\nend\n"
  },
  {
    "path": "app/models/event.rb",
    "content": "# == Schema Information\n#\n# Table name: events\n# Database name: primary\n#\n#  id               :integer          not null, primary key\n#  city             :string\n#  country_code     :string           indexed => [state_code]\n#  date             :date\n#  date_precision   :string           default(\"day\"), not null\n#  end_date         :date\n#  geocode_metadata :json             not null\n#  kind             :string           default(\"event\"), not null, indexed\n#  latitude         :decimal(10, 6)\n#  location         :string\n#  longitude        :decimal(10, 6)\n#  name             :string           default(\"\"), not null, indexed\n#  slug             :string           default(\"\"), not null, indexed\n#  start_date       :date\n#  state_code       :string           indexed => [country_code]\n#  talks_count      :integer          default(0), not null\n#  website          :string           default(\"\")\n#  created_at       :datetime         not null\n#  updated_at       :datetime         not null\n#  canonical_id     :integer          indexed\n#  event_series_id  :integer          not null, indexed\n#\n# Indexes\n#\n#  index_events_on_canonical_id                 (canonical_id)\n#  index_events_on_country_code_and_state_code  (country_code,state_code)\n#  index_events_on_event_series_id              (event_series_id)\n#  index_events_on_kind                         (kind)\n#  index_events_on_name                         (name)\n#  index_events_on_slug                         (slug)\n#\n# Foreign Keys\n#\n#  canonical_id     (canonical_id => events.id)\n#  event_series_id  (event_series_id => event_series.id)\n#\nclass Event < ApplicationRecord\n  include Geocodeable\n  include Suggestable\n  include Sluggable\n  include Todoable\n  include Event::TypesenseSearchable\n\n  geocodeable :location_and_country_code\n  configure_slug(attribute: :name, auto_suffix_on_collision: false)\n\n  # associations\n  belongs_to :series, class_name: \"EventSeries\", foreign_key: :event_series_id, strict_loading: false\n  has_many :talks, dependent: :destroy, inverse_of: :event, foreign_key: :event_id\n  has_many :watchable_talks, -> { watchable }, class_name: \"Talk\"\n  has_many :speakers, -> { distinct }, through: :talks, class_name: \"User\"\n  has_many :keynote_speakers, -> { joins(:talks).where(talks: {kind: \"keynote\"}).distinct },\n    through: :talks, source: :speakers\n  has_many :topics, -> { distinct }, through: :talks\n  has_many :sponsors, dependent: :destroy\n  has_many :organizations, through: :sponsors\n  belongs_to :canonical, class_name: \"Event\", optional: true\n  has_many :aliases, class_name: \"Event\", foreign_key: \"canonical_id\"\n  has_many :slug_aliases, as: :aliasable, class_name: \"Alias\", dependent: :destroy\n  has_many :cfps, dependent: :destroy\n  belongs_to :city_record, class_name: \"City\", optional: true, foreign_key: [:city, :country_code, :state_code], primary_key: [:name, :country_code, :state_code]\n\n  # Event participation associations\n  has_many :event_participations, dependent: :destroy\n  has_many :participants, through: :event_participations, source: :user\n  has_many :speaker_participants, -> { where(event_participations: {attended_as: :speaker}) },\n    through: :event_participations, source: :user\n  has_many :keynote_speaker_participants, -> { where(event_participations: {attended_as: :keynote_speaker}) },\n    through: :event_participations, source: :user\n  has_many :visitor_participants, -> { where(event_participations: {attended_as: :visitor}) },\n    through: :event_participations, source: :user\n\n  # Event involvement associations\n  has_many :event_involvements, dependent: :destroy\n  has_many :involved_users, -> { where(event_involvements: {involvementable_type: \"User\"}) },\n    through: :event_involvements, source: :involvementable, source_type: \"User\"\n  has_many :involved_event_series, -> { where(event_involvements: {involvementable_type: \"EventSeries\"}) },\n    through: :event_involvements, source: :involvementable, source_type: \"EventSeries\"\n\n  accepts_nested_attributes_for :event_involvements, allow_destroy: true, reject_if: :all_blank\n\n  has_object :assets\n  has_object :schedule\n  has_object :static_metadata\n  has_object :tickets\n  has_object :sponsors_file\n  has_object :cfp_file\n  has_object :involvements_file\n  has_object :transcripts_file\n  has_object :venue\n  has_object :videos_file\n\n  # validations\n  validates :name, presence: true\n  validates :kind, presence: true\n  validates :country_code, inclusion: {in: Country.valid_country_codes}, allow_nil: true\n  validates :canonical, exclusion: {in: ->(event) { [event] }, message: \"can't be itself\"}\n  validates :date_precision, presence: true\n\n  # scopes\n  scope :without_talks, -> { where.missing(:talks) }\n  scope :with_talks, -> { where.associated(:talks) }\n  scope :with_watchable_talks, -> { where.associated(:watchable_talks) }\n  scope :canonical, -> { where(canonical_id: nil) }\n  scope :not_canonical, -> { where.not(canonical_id: nil) }\n  scope :ft_search, ->(query) {\n    joins(<<~SQL.squish)\n      LEFT OUTER JOIN aliases AS event_aliases\n        ON event_aliases.aliasable_type = 'Event'\n        AND event_aliases.aliasable_id = events.id\n    SQL\n      .joins(\"LEFT OUTER JOIN event_series AS search_series ON search_series.id = events.event_series_id\")\n      .joins(<<~SQL.squish)\n        LEFT OUTER JOIN aliases AS series_aliases\n          ON series_aliases.aliasable_type = 'EventSeries'\n          AND series_aliases.aliasable_id = search_series.id\n      SQL\n      .where(\n        \"lower(events.name) LIKE :query OR lower(event_aliases.name) LIKE :query \" \\\n        \"OR lower(search_series.name) LIKE :query OR lower(series_aliases.name) LIKE :query\",\n        query: \"%#{query.downcase}%\"\n      )\n      .distinct\n  }\n  scope :past, -> { where(end_date: ..Date.today).order(end_date: :desc) }\n  scope :upcoming, -> { where(start_date: Date.today..).order(start_date: :asc) }\n\n  scope :past_meetups, -> {\n    joins(:talks).where(kind: :meetup, talks: {date: ..Date.today}).distinct\n  }\n\n  scope :upcoming_meetups, -> {\n    joins(:talks).where(kind: :meetup, talks: {date: Date.today..}).distinct\n  }\n\n  def upcoming?\n    start_date.present? && start_date >= Date.today\n  end\n\n  def past?\n    end_date.present? && end_date < Date.today\n  end\n\n  def self.find_by_name_or_alias(name)\n    return nil if name.blank?\n\n    event = find_by(name: name)\n    return event if event\n\n    alias_record = ::Alias.find_by(aliasable_type: \"Event\", name: name)\n    alias_record&.aliasable\n  end\n\n  def self.find_by_slug_or_alias(slug)\n    return nil if slug.blank?\n\n    event = find_by(slug: slug)\n    return event if event\n\n    alias_record = ::Alias.find_by(aliasable_type: \"Event\", slug: slug)\n    alias_record&.aliasable\n  end\n\n  def self.grouped_by_country\n    all.group_by(&:country_code)\n      .map { |code, evts| [Country.find_by(country_code: code), evts] }\n      .reject { |country, _| country.nil? }\n      .sort_by { |country, _| country.name }\n  end\n\n  def sync_aliases_from_list(alias_names)\n    Array.wrap(alias_names).each do |alias_name|\n      slug = alias_name.parameterize\n\n      existing_own = slug_aliases.find_by(name: alias_name) || slug_aliases.find_by(slug: slug)\n\n      if existing_own\n        existing_own.update(name: alias_name) if existing_own.name != alias_name\n        next\n      end\n\n      existing_global = ::Alias.find_by(aliasable_type: \"Event\", name: alias_name)\n      existing_global ||= ::Alias.find_by(aliasable_type: \"Event\", slug: slug)\n\n      next if existing_global\n\n      slug_aliases.create!(name: alias_name, slug: slug)\n    end\n  end\n\n  attribute :kind, :string\n  attribute :date_precision, :string\n\n  # enums\n  enum :kind, [\"event\", \"conference\", \"meetup\", \"retreat\", \"hackathon\", \"workshop\"].index_by(&:itself), default: \"event\"\n  enum :date_precision, [\"day\", \"month\", \"year\"].index_by(&:itself), default: \"day\"\n\n  def assign_canonical_event!(canonical_event:)\n    ActiveRecord::Base.transaction do\n      self.canonical = canonical_event\n      save!\n\n      talks.update_all(event_id: canonical_event.id)\n      Event.reset_counters(canonical_event.id, :talks)\n    end\n  end\n\n  def managed_by?(user)\n    Current.user&.admin?\n  end\n\n  def data_folder\n    Rails.root.join(\"data\", series.slug, slug)\n  end\n\n  def suggestion_summary\n    <<~HEREDOC\n      Event: #{name}\n      #{description}\n      #{city}\n      #{country_code}\n      #{series.name}\n      #{date}\n    HEREDOC\n  end\n\n  def location_and_country_code\n    default_country = series&.static_metadata&.default_country_code\n\n    [location, default_country].compact.join(\", \")\n  end\n\n  def location_and_country_code_previously_changed?\n    location_previously_changed?\n  end\n\n  def today?\n    return talks.where(date: Date.today).exists? if meetup?\n\n    (start_date..end_date).cover?(Date.today)\n  rescue => _e\n    false\n  end\n\n  def formatted_dates\n    return \"Recurring\" if meetup?\n    case date_precision\n    when \"year\"\n      start_date.strftime(\"%Y\")\n    when \"month\"\n      start_date.strftime(\"%B %Y\")\n    when \"day\"\n      return I18n.l(start_date, default: \"unknown\") if start_date == end_date\n\n      if start_date.strftime(\"%Y-%m\") == end_date.strftime(\"%Y-%m\")\n        return \"#{start_date.strftime(\"%B %d\")}-#{end_date.strftime(\"%d, %Y\")}\"\n      end\n\n      if start_date.strftime(\"%Y\") == end_date.strftime(\"%Y\")\n        return \"#{I18n.l(start_date, format: :month_day, default: \"unknown\")} - #{I18n.l(end_date, default: \"unknown\")}\"\n      end\n\n      \"#{I18n.l(start_date, format: :medium,\n        default: \"unknown\")} - #{I18n.l(end_date, format: :medium, default: \"unknown\")}\"\n    end\n  end\n\n  def held_in_sentence\n    country&.held_in_sentence || \"\"\n  end\n\n  def to_location\n    @to_location ||= Location.from_record(self)\n  end\n\n  delegate :country, :state, :city_object, to: :to_location\n\n  def description\n    return @description if @description.present?\n\n    event_name = series.organisation? ? name : series.name\n\n    @description = <<~DESCRIPTION\n      #{event_name} is a #{static_metadata.frequency} #{kind}#{held_in_sentence}#{talks_text}#{keynote_speakers_text}.\n    DESCRIPTION\n  end\n\n  def keynote_speakers_text\n    keynote_speakers.size.positive? ? %(, including keynotes by #{keynote_speakers.map(&:name).to_sentence}) : \"\"\n  end\n\n  def talks_text\n    talks.size.positive? ? \" and features #{talks.size} #{\"talk\".pluralize(talks.size)} from various speakers\" : \"\"\n  end\n\n  def to_meta_tags\n    {\n      title: name,\n      description: description,\n      og: {\n        title: name,\n        type: :website,\n        image: {\n          _: Router.image_path(card_image_path),\n          alt: name\n        },\n        description: description,\n        site_name: \"RubyEvents.org\"\n      },\n      twitter: {\n        card: \"summary_large_image\",\n        site: \"@rubyevents_org\",\n        title: name,\n        description: description,\n        image: {\n          src: Router.image_path(card_image_path)\n        }\n      }\n    }\n  end\n\n  def sort_date\n    start_date || end_date || Time.at(0)\n  end\n\n  def watchable_talks?\n    talks.where.not(video_provider: [\"scheduled\", \"not_published\", \"not_recorded\"]).exists?\n  end\n\n  def featurable?\n    featured_metadata? && watchable_talks?\n  end\n\n  def website\n    self[:website].presence || series.website\n  end\n\n  def to_mobile_json(request)\n    {\n      id: id,\n      name: name,\n      slug: slug,\n      location: location,\n      start_date: start_date&.to_s,\n      end_date: end_date&.to_s,\n      card_image_url: Router.image_path(card_image_path, host: \"#{request.protocol}#{request.host}:#{request.port}\"),\n      featured_image_url: Router.image_path(featured_image_path,\n        host: \"#{request.protocol}#{request.host}:#{request.port}\"),\n      featured_background: static_metadata.featured_background,\n      featured_color: static_metadata.featured_color,\n      url: Router.event_url(self, host: \"#{request.protocol}#{request.host}:#{request.port}\")\n    }\n  end\n\n  private\n\n  def todos_data_path\n    Rails.root.join(\"data\", series.slug, slug)\n  end\n\n  def todos_file_prefix\n    \"#{series.slug}/#{slug}\"\n  end\nend\n"
  },
  {
    "path": "app/models/event_involvement.rb",
    "content": "# == Schema Information\n#\n# Table name: event_involvements\n# Database name: primary\n#\n#  id                   :integer          not null, primary key\n#  involvementable_type :string           not null, uniquely indexed => [involvementable_id, event_id, role], indexed => [involvementable_id]\n#  position             :integer          default(0)\n#  role                 :string           not null, uniquely indexed => [involvementable_type, involvementable_id, event_id], indexed\n#  created_at           :datetime         not null\n#  updated_at           :datetime         not null\n#  event_id             :integer          not null, uniquely indexed => [involvementable_type, involvementable_id, role], indexed\n#  involvementable_id   :integer          not null, uniquely indexed => [involvementable_type, event_id, role], indexed => [involvementable_type]\n#\n# Indexes\n#\n#  idx_involvements_on_involvementable_and_event_and_role  (involvementable_type,involvementable_id,event_id,role) UNIQUE\n#  index_event_involvements_on_event_id                    (event_id)\n#  index_event_involvements_on_involvementable             (involvementable_type,involvementable_id)\n#  index_event_involvements_on_role                        (role)\n#\n# Foreign Keys\n#\n#  event_id  (event_id => events.id)\n#\nclass EventInvolvement < ApplicationRecord\n  # associations\n  belongs_to :involvementable, polymorphic: true\n  belongs_to :event\n\n  # validations\n  validates :involvementable_type, uniqueness: {scope: [:involvementable_id, :event_id, :role]}\n  validates :role, presence: true\n\n  def name\n    \"#{involvementable.name} - #{event.name} - #{role}\"\n  end\nend\n"
  },
  {
    "path": "app/models/event_participation.rb",
    "content": "# == Schema Information\n#\n# Table name: event_participations\n# Database name: primary\n#\n#  id          :integer          not null, primary key\n#  attended_as :string           not null, uniquely indexed => [user_id, event_id], indexed\n#  created_at  :datetime         not null\n#  updated_at  :datetime         not null\n#  event_id    :integer          not null, uniquely indexed => [user_id, attended_as], indexed\n#  user_id     :integer          not null, uniquely indexed => [event_id, attended_as], indexed\n#\n# Indexes\n#\n#  idx_on_user_id_event_id_attended_as_ca0a2916e2  (user_id,event_id,attended_as) UNIQUE\n#  index_event_participations_on_attended_as       (attended_as)\n#  index_event_participations_on_event_id          (event_id)\n#  index_event_participations_on_user_id           (user_id)\n#\n# Foreign Keys\n#\n#  event_id  (event_id => events.id)\n#  user_id   (user_id => users.id)\n#\nclass EventParticipation < ApplicationRecord\n  # associations\n  belongs_to :user\n  belongs_to :event\n\n  # validations\n  validates :user_id, uniqueness: {scope: [:event_id, :attended_as]}\n\n  # enums\n  enum :attended_as, %w[keynote_speaker speaker visitor].index_by(&:itself), prefix: true\n\n  def name\n    \"#{user.name} - #{event.name} - #{attended_as}\"\n  end\nend\n"
  },
  {
    "path": "app/models/event_series/static_metadata.rb",
    "content": "class EventSeries::StaticMetadata < ActiveRecord::AssociatedObject\n  def ended?\n    static_repository.try(:ended) || false\n  end\n\n  def default_country_code\n    static_repository.try(:default_country_code) || nil\n  end\n\n  private\n\n  def static_repository\n    @static_repository ||= Static::EventSeries.find_by_slug(event_series.slug)\n  end\nend\n"
  },
  {
    "path": "app/models/event_series/typesense_searchable.rb",
    "content": "# frozen_string_literal: true\n\nmodule EventSeries::TypesenseSearchable\n  extend ActiveSupport::Concern\n\n  included do\n    include ::Typesense\n\n    typesense enqueue: :trigger_typesense_job, if: :should_index?, disable_indexing: -> { Search::Backend.skip_indexing } do\n      attributes :name, :slug, :website, :twitter\n\n      attribute :description_text do\n        read_attribute(:description)\n      end\n\n      attribute :kind\n      attribute :frequency\n\n      attribute :events_count do\n        Event.where(event_series_id: id).count\n      end\n\n      attribute :talks_count do\n        Event.where(event_series_id: id).sum(:talks_count)\n      end\n\n      attribute :avatar_path do\n        Event.where(event_series_id: id).order(date: :desc).first&.avatar_image_path\n      end\n\n      attribute :start_year do\n        Event.where(event_series_id: id).minimum(:date)&.year\n      end\n\n      attribute :end_year do\n        Event.where(event_series_id: id).maximum(:date)&.year\n      end\n\n      attribute :alias_names do\n        ::Alias.where(aliasable_type: \"EventSeries\", aliasable_id: id).pluck(:name)\n      end\n\n      attribute :alias_slugs do\n        ::Alias.where(aliasable_type: \"EventSeries\", aliasable_id: id).pluck(:slug)\n      end\n\n      predefined_fields [\n        {\"name\" => \"name\", \"type\" => \"string\"},\n        {\"name\" => \"description_text\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"slug\", \"type\" => \"string\"},\n\n        {\"name\" => \"kind\", \"type\" => \"string\", \"facet\" => true},\n        {\"name\" => \"frequency\", \"type\" => \"string\", \"facet\" => true},\n        {\"name\" => \"website\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"twitter\", \"type\" => \"string\", \"optional\" => true},\n\n        {\"name\" => \"events_count\", \"type\" => \"int32\"},\n        {\"name\" => \"talks_count\", \"type\" => \"int32\"},\n\n        {\"name\" => \"avatar_path\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"start_year\", \"type\" => \"int32\", \"optional\" => true},\n        {\"name\" => \"end_year\", \"type\" => \"int32\", \"optional\" => true},\n\n        {\"name\" => \"alias_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"alias_slugs\", \"type\" => \"string[]\", \"optional\" => true}\n      ]\n\n      default_sorting_field \"talks_count\"\n\n      multi_way_synonyms [\n        {\"railsconf-synonym\" => %w[railsconf rails-conf]},\n        {\"rubyconf-synonym\" => %w[rubyconf ruby-conf]},\n        {\"euruko-synonym\" => %w[euruko european-ruby-konferenz]},\n        {\"rubykaigi-synonym\" => %w[rubykaigi ruby-kaigi]}\n      ]\n\n      token_separators %w[- _]\n    end\n  end\n\n  class_methods do\n    def trigger_typesense_job(record, remove)\n      TypesenseIndexJob.perform_later(record, remove ? \"typesense_remove_from_index!\" : \"typesense_index!\")\n    end\n\n    def typesense_search_series(query, options = {})\n      query_by_fields = \"name,slug,description_text,alias_names,alias_slugs\"\n\n      search_options = {\n        query_by_weights: \"10,9,3,8,7\",\n        per_page: options[:per_page] || 20,\n        page: options[:page] || 1,\n        highlight_full_fields: \"name\",\n        highlight_affix_num_tokens: 10\n      }\n\n      filters = []\n      filters << \"kind:=#{options[:kind]}\" if options[:kind].present?\n      filters << \"frequency:=#{options[:frequency]}\" if options[:frequency].present?\n\n      search_options[:filter_by] = filters.join(\" && \") if filters.any?\n\n      sort_options = {\n        \"talks\" => \"talks_count:desc\",\n        \"events\" => \"events_count:desc\",\n        \"name\" => \"name:asc\",\n        \"relevance\" => \"_text_match:desc,talks_count:desc\"\n      }\n\n      search_options[:sort_by] = sort_options[options[:sort]] || sort_options[\"relevance\"]\n\n      search(query.presence || \"*\", query_by_fields, search_options)\n    end\n  end\n\n  private\n\n  def should_index?\n    Event.where(event_series_id: id).exists?\n  end\nend\n"
  },
  {
    "path": "app/models/event_series.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: event_series\n# Database name: primary\n#\n#  id                   :integer          not null, primary key\n#  description          :text             default(\"\"), not null\n#  frequency            :integer          default(\"unknown\"), not null, indexed\n#  kind                 :integer          default(\"conference\"), not null, indexed\n#  language             :string           default(\"\"), not null\n#  name                 :string           default(\"\"), not null, indexed\n#  slug                 :string           default(\"\"), not null, indexed\n#  twitter              :string           default(\"\"), not null\n#  website              :string           default(\"\"), not null\n#  youtube_channel_name :string           default(\"\")\n#  created_at           :datetime         not null\n#  updated_at           :datetime         not null\n#  youtube_channel_id   :string           default(\"\")\n#\n# Indexes\n#\n#  index_event_series_on_frequency  (frequency)\n#  index_event_series_on_kind       (kind)\n#  index_event_series_on_name       (name)\n#  index_event_series_on_slug       (slug)\n#\n# rubocop:enable Layout/LineLength\nclass EventSeries < ApplicationRecord\n  include Sluggable\n  include Suggestable\n  include Todoable\n  include EventSeries::TypesenseSearchable\n\n  include ActionView::Helpers::TextHelper\n\n  configure_slug(attribute: :name, auto_suffix_on_collision: false)\n\n  # associations\n  has_many :events, dependent: :destroy, inverse_of: :series, foreign_key: :event_series_id, strict_loading: true\n  has_many :talks, through: :events\n  has_many :aliases, as: :aliasable, class_name: \"Alias\", dependent: :destroy\n  has_object :static_metadata\n\n  # validations\n  validates :name, presence: true\n\n  # enums\n  enum :kind, {conference: 0, meetup: 1, organisation: 2, retreat: 3, hackathon: 4, event: 5, workshop: 6}\n  enum :frequency, {unknown: 0, yearly: 1, monthly: 2, biyearly: 3, quarterly: 4, irregular: 5, weekly: 6, biweekly: 7}\n\n  def self.find_by_name_or_alias(name)\n    return nil if name.blank?\n\n    series = find_by(name: name)\n    return series if series\n\n    alias_record = ::Alias.find_by(aliasable_type: \"EventSeries\", name: name)\n    alias_record&.aliasable\n  end\n\n  def self.find_by_slug_or_alias(slug)\n    return nil if slug.blank?\n\n    series = find_by(slug: slug)\n    return series if series\n\n    alias_record = ::Alias.find_by(aliasable_type: \"EventSeries\", slug: slug)\n    alias_record&.aliasable\n  end\n\n  def sync_aliases_from_list(alias_names)\n    Array.wrap(alias_names).each do |alias_name|\n      slug = alias_name.parameterize\n\n      # Check if this alias already belongs to us\n      existing_own = aliases.find_by(name: alias_name) || aliases.find_by(slug: slug)\n      if existing_own\n        existing_own.update(name: alias_name) if existing_own.name != alias_name\n        next\n      end\n\n      # Check if alias exists globally for another EventSeries\n      existing_global = ::Alias.find_by(aliasable_type: \"EventSeries\", name: alias_name) ||\n        ::Alias.find_by(aliasable_type: \"EventSeries\", slug: slug)\n      next if existing_global # Skip if it belongs to another series\n\n      aliases.create!(name: alias_name, slug: slug)\n    end\n  end\n\n  def title\n    %(All #{name} #{kind.pluralize})\n  end\n\n  def next_upcoming_event_with_tickets\n    events.upcoming.find(&:tickets?)\n  end\n\n  def description\n    non_cancelled = events.reject { |e| e.static_metadata.cancelled? }\n\n    event_years = non_cancelled.filter_map { |e| (e.date || e.start_date || e.end_date)&.year }\n    start_year = event_years.min\n    end_year = event_years.max\n\n    time_range = if start_year && start_year == end_year\n      %( in #{start_year})\n    elsif start_year && end_year\n      %( between #{start_year} and #{end_year})\n    else\n      \"\"\n    end\n\n    event_type = pluralize(non_cancelled.size, meetup? ? \"event-series\" : \"event\")\n    frequency_text = (kind == \"organisation\") ? \"\" : \" is a #{frequency} #{kind} and \"\n\n    <<~DESCRIPTION\n      #{name} #{frequency_text}hosted #{event_type}#{time_range}. We have currently indexed #{pluralize(non_cancelled.sum(&:talks_count), \"#{name} talk\")}.\n    DESCRIPTION\n  end\n\n  def to_meta_tags\n    event = events.order(date: :desc).first\n\n    {\n      title: title,\n      description: description,\n      og: {\n        title: title,\n        type: :website,\n        image: {\n          _: event ? Router.image_path(event.card_image_path) : nil,\n          alt: title\n        },\n        description: description,\n        site_name: \"RubyEvents.org\"\n      },\n      twitter: {\n        card: \"summary_large_image\",\n        site: \"@rubyevents_org\",\n        title: title,\n        description: description,\n        image: {\n          src: event ? Router.image_path(event.card_image_path) : nil\n        }\n      }\n    }\n  end\n\n  private\n\n  def todos_data_path\n    Rails.root.join(\"data\", slug)\n  end\n\n  def todos_file_prefix\n    slug\n  end\nend\n"
  },
  {
    "path": "app/models/favorite_user.rb",
    "content": "# == Schema Information\n#\n# Table name: favorite_users\n# Database name: primary\n#\n#  id               :integer          not null, primary key\n#  notes            :text\n#  created_at       :datetime         not null\n#  updated_at       :datetime         not null\n#  favorite_user_id :integer          not null, indexed\n#  user_id          :integer          not null, indexed\n#\n# Indexes\n#\n#  index_favorite_users_on_favorite_user_id  (favorite_user_id)\n#  index_favorite_users_on_user_id           (user_id)\n#\n# Foreign Keys\n#\n#  favorite_user_id  (favorite_user_id => users.id)\n#  user_id           (user_id => users.id)\n#\nclass FavoriteUser < ApplicationRecord\n  belongs_to :user\n  belongs_to :favorite_user, class_name: \"User\"\n\n  validates :user, comparison: {other_than: :favorite_user}\n  validates :favorite_user_id, uniqueness: {scope: :user_id}\n\n  has_one :mutual_favorite_user, class_name: \"FavoriteUser\", primary_key: [:user_id, :favorite_user_id], foreign_key: [:favorite_user_id, :user_id]\n\n  def ruby_friend?\n    persisted? && mutual_favorite_user&.persisted?\n  end\n\n  # Suggest favorite users based on talks the user has watched\n  # No check for existing favorite users\n  def self.recommendations_for(user)\n    recommended_user_ids = user\n      .watched_talks.joins(talk: :speakers)\n      .where.not(users: {id: user.id})\n      .distinct\n      .limit(6)\n      .pluck(\"users.id\")\n\n    recommended_users = User.where(id: recommended_user_ids)\n    recommended_users\n      .map do |recommended_user|\n        FavoriteUser.new(user: user, favorite_user: recommended_user)\n      end\n  end\nend\n"
  },
  {
    "path": "app/models/geocode_result.rb",
    "content": "# == Schema Information\n#\n# Table name: geocode_results\n# Database name: primary\n#\n#  id            :integer          not null, primary key\n#  query         :string           not null, uniquely indexed\n#  response_body :text             not null\n#  created_at    :datetime         not null\n#  updated_at    :datetime         not null\n#\n# Indexes\n#\n#  index_geocode_results_on_query  (query) UNIQUE\n#\nclass GeocodeResult < ApplicationRecord\n  validates :query, presence: true, uniqueness: true\nend\n"
  },
  {
    "path": "app/models/language.rb",
    "content": "class Language\n  DEFAULT = \"en\".freeze\n  ALL_ALPHA2_CODES = ISO_639::ISO_639_1.map(&:alpha2).freeze\n  ALL_ENGLISH_NAMES = ISO_639::ISO_639_1.map { |language| language.english_name.split(\";\").first }.freeze\n  ALL_LANGUAGES = ALL_ALPHA2_CODES.zip(ALL_ENGLISH_NAMES).to_h.freeze\n\n  def self.find(term)\n    ISO_639\n      .search(term)\n      .reject { |result| result.alpha2.blank? }\n      .first\n  end\n\n  def self.find_by_code(code)\n    ISO_639.find_by_code(code)\n  end\n\n  def self.alpha2_codes\n    ALL_ALPHA2_CODES\n  end\n\n  def self.english_names\n    ALL_ENGLISH_NAMES\n  end\n\n  def self.all\n    ALL_LANGUAGES\n  end\n\n  def self.by_code(code)\n    ALL_LANGUAGES[code]\n  end\n\n  def self.used\n    assigned_languages = Talk.distinct.pluck(:language)\n\n    Language.all.dup.keep_if { |key, value| assigned_languages.include?(key) }\n  end\n\n  def self.talks(code)\n    Talk.where(language: code)\n  end\n\n  def self.talks_count(code)\n    Talk.where(language: code).count\n  end\n\n  def self.native_name(code)\n    LanguageHelper::NATIVE_NAMES[code]\n  end\n\n  def self.emoji_flag(code)\n    name = by_code(code)\n    return \"🏳️\" unless name\n\n    LanguageHelper::LANGUAGE_TO_EMOJI[name.downcase] || \"🏳️\"\n  end\n\n  def self.synonyms_for(code)\n    record = find_by_code(code)\n    return [] unless record\n\n    synonyms = []\n\n    synonyms << record.alpha3_bibliographic if record.alpha3_bibliographic.present?\n    synonyms << record.alpha3 if record.alpha3.present? && record.alpha3 != record.alpha3_bibliographic\n\n    if record.english_name.present?\n      record.english_name.split(\";\").each do |name|\n        synonyms << name.strip.downcase\n      end\n    end\n\n    if record.french_name.present?\n      record.french_name.split(\";\").each do |name|\n        synonyms << name.strip.downcase\n      end\n    end\n\n    synonyms << LanguageHelper::NATIVE_NAMES[code] if LanguageHelper::NATIVE_NAMES[code].present?\n\n    synonyms.uniq\n  end\n\n  def self.all_synonyms\n    used.keys.each_with_object({}) do |code, hash|\n      synonyms = synonyms_for(code)\n      next if synonyms.empty?\n\n      all_terms = [code] + synonyms\n\n      hash[\"#{code}-language-synonym\"] = {\"synonyms\" => all_terms.uniq}\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/llm/client.rb",
    "content": "class LLM::Client\n  def initialize(provider_client = OpenAI::Client.new)\n    @provider_client = provider_client\n  end\n\n  def chat(parameters:, resource:, task_name:)\n    LLM::Request.find_or_create_by_request!(parameters, resource: resource, task_name: task_name) do\n      @provider_client.chat(parameters: parameters)\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/llm/request.rb",
    "content": "# == Schema Information\n#\n# Table name: llm_requests\n# Database name: primary\n#\n#  id            :integer          not null, primary key\n#  duration      :float            not null\n#  raw_response  :json             not null\n#  request_hash  :string           not null, uniquely indexed\n#  resource_type :string           not null, indexed => [resource_id]\n#  success       :boolean          default(FALSE), not null\n#  task_name     :string           default(\"\"), not null, indexed\n#  created_at    :datetime         not null\n#  updated_at    :datetime         not null\n#  resource_id   :integer          not null, indexed => [resource_type]\n#\n# Indexes\n#\n#  index_llm_requests_on_request_hash  (request_hash) UNIQUE\n#  index_llm_requests_on_resource      (resource_type,resource_id)\n#  index_llm_requests_on_task_name     (task_name)\n#\nclass LLM::Request < ApplicationRecord\n  self.table_name = \"llm_requests\"\n\n  belongs_to :resource, polymorphic: true\n\n  validates :request_hash, presence: true, uniqueness: true\n  validates :raw_response, presence: true\n  validates :duration, presence: true\n  validates :success, inclusion: {in: [true, false]}\n\n  class << self\n    def find_or_create_by_request!(request_params, resource:, task_name:, &block)\n      request_hash = Digest::SHA256.hexdigest(request_params.to_json)\n\n      if (cached_request = find_by(request_hash: request_hash, success: true))\n        return cached_request.raw_response\n      end\n\n      start_time = Time.current\n      response = yield\n      duration = Time.current - start_time\n\n      create!(\n        request_hash: request_hash,\n        raw_response: response,\n        duration: duration,\n        resource: resource,\n        success: true # if there is an error the llm api call raise an error and we don't save the request\n      ).raw_response\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/location.rb",
    "content": "# frozen_string_literal: true\n\nclass Location\n  include ActionView::Helpers::TagHelper\n  include ActionView::Helpers::UrlHelper\n  include ActionView::Context\n\n  ONLINE_LOCATIONS = %w[online virtual remote].freeze\n\n  attr_reader :city, :state_code, :country_code, :latitude, :longitude, :raw_location, :hybrid\n\n  def initialize(city: nil, state_code: nil, country_code: nil, latitude: nil, longitude: nil, raw_location: nil, hybrid: false)\n    @city = city\n    @state_code = state_code\n    @country_code = country_code\n    @latitude = latitude\n    @longitude = longitude\n    @raw_location = raw_location\n    @hybrid = hybrid\n  end\n\n  def self.from_record(record)\n    new(\n      city: record.try(:city),\n      state_code: record.try(:state_code),\n      country_code: record.try(:country_code) || record.try(:alpha2),\n      latitude: record.try(:latitude),\n      longitude: record.try(:longitude),\n      raw_location: record.try(:location),\n      hybrid: record.try(:static_metadata)&.try(:hybrid?) || false\n    )\n  end\n\n  def self.from_string(location_string)\n    new(raw_location: location_string)\n  end\n\n  def self.online\n    new(raw_location: \"online\")\n  end\n\n  def city_object\n    return nil if city.blank? || country.blank?\n\n    @city_object ||= City.find_for(city: city, country_code: country.alpha2, state_code: state&.code) ||\n      City.new(name: city, slug: city.parameterize, country_code: country.alpha2, state_code: state&.code)\n  end\n\n  def state\n    return nil unless country&.states? && state_code.present?\n\n    @state ||= State.find_by_code(state_code, country: country) || State.find_by_name(state_code, country: country)\n  end\n\n  def country\n    return nil if country_code.blank?\n\n    @country ||= Country.find_by(country_code: country_code)\n  end\n\n  def city_path\n    city_object&.path\n  end\n\n  def state_path\n    state&.path\n  end\n\n  def country_path\n    country&.path\n  end\n\n  def continent\n    country&.continent\n  end\n\n  def continent_name\n    continent&.name\n  end\n\n  def continent_path\n    continent&.path\n  end\n\n  def online_location\n    @online_location ||= OnlineLocation.instance\n  end\n\n  def online_path\n    online_location.path\n  end\n\n  def online?\n    return false if geocoded?\n\n    raw_location.to_s.downcase.in?(ONLINE_LOCATIONS)\n  end\n\n  def hybrid?\n    !!hybrid\n  end\n\n  def state_display_name\n    state&.display_name || state_code\n  end\n\n  def display_city\n    base = city.presence&.strip\n\n    return state_display_name if base.blank? && state\n    return base unless country&.states? && state_code.present?\n    return state_display_name if base&.downcase == state_display_name&.downcase\n\n    \"#{base}, #{state_display_name}\"\n  end\n\n  def geocoded?\n    latitude.present? && longitude.present?\n  end\n\n  def present?\n    raw_location.present? || city.present? || country_code.present?\n  end\n\n  def blank?\n    !present?\n  end\n\n  def has_state?\n    state_path.present?\n  end\n\n  def has_city?\n    city.present? && country.present?\n  end\n\n  def to_s\n    raw_location || [display_city, country&.name].compact.join(\", \")\n  end\n\n  # Renders location as HTML with optional links\n  #\n  # Examples:\n  #   to_html                              # => \"Portland, OR, United States\" with links\n  #   to_html(show_links: false)           # => \"Portland, OR, United States\" as text\n  #   to_html(upto: :city)                 # => \"Portland, OR\" with link\n  #   to_html(upto: :continent)            # => \"Portland, OR, United States, North America\"\n  def to_html(show_links: true, link_class: \"link\", upto: :country)\n    return \"\".html_safe if blank?\n    return render_online(show_links: show_links, link_class: link_class) if online?\n    return content_tag(:span, to_s) unless geocoded?\n\n    result = render_upto(upto: upto, show_links: show_links, link_class: link_class)\n    result = append_hybrid_html(result, show_links: show_links, link_class: link_class) if hybrid?\n    result\n  end\n\n  def to_text(upto: :country)\n    return \"\" if blank?\n    return online_location.name if online?\n\n    result = text_upto(upto)\n    result = raw_location if result.blank? && raw_location.present?\n    result = \"#{result} & online\" if hybrid? && result.present?\n\n    result.to_s\n  end\n\n  private\n\n  LEVEL_ORDER = [:city, :state, :country, :continent].freeze\n\n  def text_upto(upto)\n    location_parts(upto: upto).map { |part| part[:text] }.compact.join(\", \")\n  end\n\n  def render_online(show_links:, link_class:)\n    link_or_text(online_location.name, online_path, show_links: show_links, link_class: link_class)\n  end\n\n  def render_upto(upto:, show_links:, link_class:)\n    parts = location_parts(upto: upto).map do |part|\n      link_or_text(part[:text], part[:path], show_links: show_links, link_class: link_class)\n    end\n\n    join_parts(parts, \", \")\n  end\n\n  def location_parts(upto:)\n    includes = ->(level) { LEVEL_ORDER.index(upto).to_i >= LEVEL_ORDER.index(level) }\n    parts = []\n\n    if includes[:state] && has_state?\n      parts << {text: city, path: city_path} if city.present?\n      parts << {text: state_display_name, path: state_path}\n    elsif display_city.present?\n      parts << {text: display_city, path: city_path}\n    end\n\n    parts << {text: country.name, path: country_path} if includes[:country] && country.present?\n    parts << {text: continent_name, path: continent_path} if includes[:continent] && continent.present?\n\n    parts\n  end\n\n  def append_hybrid_html(result, show_links:, link_class:)\n    online_part = link_or_text(\"online\", online_path, show_links: show_links, link_class: link_class)\n\n    \"#{result} & #{online_part}\".html_safe\n  end\n\n  def link_or_text(text, path, show_links:, link_class:)\n    return content_tag(:span, text) if text.blank?\n\n    if show_links && path\n      link_to(text, path, class: link_class)\n    else\n      content_tag(:span, text)\n    end\n  end\n\n  def join_parts(parts, separator)\n    parts.compact.map(&:to_s).join(separator).html_safe\n  end\nend\n"
  },
  {
    "path": "app/models/online_location.rb",
    "content": "# frozen_string_literal: true\n\nclass OnlineLocation\n  include ActiveModel::Model\n  include ActiveModel::Attributes\n\n  def name\n    \"online\"\n  end\n\n  def slug\n    \"online\"\n  end\n\n  def emoji_flag\n    \"🌐\"\n  end\n\n  def path\n    Router.online_path\n  end\n\n  def past_path\n    Router.online_past_index_path\n  end\n\n  def users_path\n    nil\n  end\n\n  def cities_path\n    nil\n  end\n\n  def stamps_path\n    nil\n  end\n\n  def map_path\n    nil\n  end\n\n  def has_routes?\n    true\n  end\n\n  def events\n    Event.not_geocoded.includes(:series)\n  end\n\n  def users\n    User.none\n  end\n\n  def stamps\n    []\n  end\n\n  def events_count\n    events.count\n  end\n\n  def users_count\n    0\n  end\n\n  def geocoded?\n    false\n  end\n\n  def coordinates\n    nil\n  end\n\n  def to_coordinates\n    nil\n  end\n\n  def bounds\n    nil\n  end\n\n  def to_location\n    Location.online\n  end\n\n  class << self\n    def instance\n      @instance ||= new\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/organization/typesense_searchable.rb",
    "content": "# frozen_string_literal: true\n\nmodule Organization::TypesenseSearchable\n  extend ActiveSupport::Concern\n\n  included do\n    include ::Typesense\n\n    typesense enqueue: :trigger_typesense_job, if: :should_index?, disable_indexing: -> { Search::Backend.skip_indexing } do\n      attributes :name, :slug, :description, :website, :main_location\n\n      attribute :kind\n\n      attribute :events_count do\n        events.distinct.count\n      end\n\n      attribute :sponsorships_count do\n        sponsors.count\n      end\n\n      attribute :avatar_path do\n        avatar_image_path\n      end\n\n      attribute :has_logo do\n        has_logo_image?\n      end\n\n      predefined_fields [\n        {\"name\" => \"name\", \"type\" => \"string\"},\n        {\"name\" => \"description\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"slug\", \"type\" => \"string\"},\n\n        {\"name\" => \"kind\", \"type\" => \"string\", \"facet\" => true},\n        {\"name\" => \"website\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"main_location\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n\n        {\"name\" => \"events_count\", \"type\" => \"int32\"},\n        {\"name\" => \"sponsorships_count\", \"type\" => \"int32\"},\n\n        {\"name\" => \"avatar_path\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"has_logo\", \"type\" => \"bool\"}\n      ]\n\n      default_sorting_field \"events_count\"\n\n      token_separators %w[- _]\n    end\n  end\n\n  class_methods do\n    def trigger_typesense_job(record, remove)\n      TypesenseIndexJob.perform_later(record, remove ? \"typesense_remove_from_index!\" : \"typesense_index!\")\n    end\n\n    def typesense_search_organizations(query, options = {})\n      query_by_fields = \"name,description\"\n\n      search_options = {\n        query_by_weights: \"10,3\",\n        per_page: options[:per_page] || 20,\n        page: options[:page] || 1,\n        highlight_full_fields: \"name\",\n        highlight_affix_num_tokens: 10\n      }\n\n      filters = []\n      filters << \"kind:=#{options[:kind]}\" if options[:kind].present?\n      filters << \"events_count:>0\" unless options[:include_without_events]\n\n      search_options[:filter_by] = filters.join(\" && \") if filters.any?\n\n      sort_options = {\n        \"events\" => \"events_count:desc\",\n        \"sponsorships\" => \"sponsorships_count:desc\",\n        \"name\" => \"name:asc\",\n        \"relevance\" => \"_text_match:desc,events_count:desc\"\n      }\n\n      search_options[:sort_by] = sort_options[options[:sort]] || sort_options[\"relevance\"]\n\n      search(query.presence || \"*\", query_by_fields, search_options)\n    end\n  end\n\n  private\n\n  def should_index?\n    events.any? || sponsors.any?\n  end\nend\n"
  },
  {
    "path": "app/models/organization/wrapped_screenshot_generator.rb",
    "content": "require \"ferrum\"\n\nclass Organization::WrappedScreenshotGenerator\n  YEAR = 2025\n  SCALE = 2\n\n  DIMENSIONS = {\n    horizontal: {width: 800 * SCALE, height: 420 * SCALE}\n  }.freeze\n\n  attr_reader :organization\n\n  def initialize(organization)\n    @organization = organization\n  end\n\n  def save_to_storage(locals)\n    png_data = generate_horizontal_card(locals)\n    return false unless png_data\n\n    organization.wrapped_card_horizontal.attach(\n      io: StringIO.new(png_data),\n      filename: \"#{organization.slug}-#{YEAR}-wrapped.png\",\n      content_type: \"image/png\"\n    )\n\n    true\n  rescue => e\n    Rails.logger.error(\"Organization::WrappedScreenshotGenerator#save_to_storage failed: #{e.message}\")\n    false\n  end\n\n  def generate_horizontal_card(locals)\n    html_content = render_card_html(locals)\n    return nil unless html_content\n\n    dimensions = DIMENSIONS[:horizontal]\n    browser = Ferrum::Browser.new(**browser_options(dimensions))\n\n    begin\n      # Use data URI to inject HTML directly (works with remote Chrome)\n      data_uri = \"data:text/html;base64,#{Base64.strict_encode64(html_content)}\"\n      browser.go_to(data_uri)\n      sleep 1\n      screenshot_data = browser.screenshot(format: :png, full: true)\n      Base64.decode64(screenshot_data)\n    ensure\n      browser.quit\n    end\n  rescue => e\n    Rails.logger.error(\"Organization::WrappedScreenshotGenerator failed: #{e.message}\")\n    Rails.logger.error(e.backtrace.first(10).join(\"\\n\"))\n    nil\n  end\n\n  private\n\n  def browser_options(dimensions)\n    options = {\n      headless: true,\n      window_size: [dimensions[:width], dimensions[:height]],\n      timeout: 30\n    }\n\n    if chrome_ws_url\n      # Connect to remote browserless Chrome service\n      options[:url] = chrome_ws_url\n    else\n      # Local Chrome with sandbox options\n      options[:browser_options] = {\n        \"no-sandbox\": true,\n        \"disable-gpu\": true,\n        \"disable-dev-shm-usage\": true\n      }\n    end\n\n    options\n  end\n\n  def chrome_ws_url\n    # Use CHROME_WS_URL env var if set, otherwise derive from environment\n    # In development/test, use local Chrome (return nil)\n    return ENV[\"CHROME_WS_URL\"] if ENV[\"CHROME_WS_URL\"].present?\n    return nil if Rails.env.local?\n\n    # Kamal names accessories as <service>-<accessory>\n    # Production: rubyvideo-chrome, Staging: rubyvideo_staging-chrome\n    service_name = Rails.env.staging? ? \"rubyvideo_staging\" : \"rubyvideo\"\n    \"ws://#{service_name}-chrome:3000\"\n  end\n\n  def render_card_html(locals)\n    partial_html = ApplicationController.render(\n      partial: \"organizations/wrapped/pages/summary_card_horizontal\",\n      locals: locals\n    )\n\n    wrap_in_html_document(partial_html, locals)\n  end\n\n  def wrap_in_html_document(partial_html, locals)\n    if organization.logo_url.present?\n      partial_html = partial_html.gsub(\n        /src=\"#{Regexp.escape(organization.logo_url)}\"/,\n        \"src=\\\"#{organization.logo_url}\\\"\"\n      )\n    end\n\n    logo_path = Rails.root.join(\"app/assets/images/logo.png\")\n    logo_data_uri = if File.exist?(logo_path)\n      \"data:image/png;base64,#{Base64.strict_encode64(File.binread(logo_path))}\"\n    else\n      \"\"\n    end\n    partial_html = partial_html.gsub(/src=\"[^\"]*logo[^\"]*\\.png\"/, \"src=\\\"#{logo_data_uri}\\\"\")\n\n    dimensions = DIMENSIONS[:horizontal]\n    s = SCALE\n\n    <<~HTML\n      <!DOCTYPE html>\n      <html>\n      <head>\n        <meta charset=\"utf-8\">\n        <style>\n          * { margin: 0; padding: 0; box-sizing: border-box; }\n\n          html, body {\n            width: #{dimensions[:width]}px;\n            height: #{dimensions[:height]}px;\n            max-height: #{dimensions[:height]}px;\n          }\n\n          body {\n            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n            background: linear-gradient(135deg, #991b1b 0%, #450a0a 50%, #081625 100%);\n            color: white;\n            display: flex;\n            flex-direction: column;\n            overflow: hidden;\n          }\n\n          .flex { display: flex; }\n          .flex-col { flex-direction: column; }\n          .flex-1 { flex: 1; min-height: 0; }\n          .items-center { align-items: center; }\n          .justify-center { justify-content: center; }\n          .text-center { text-align: center; }\n\n          .gap-3 { gap: #{0.75 * s}rem; }\n          .gap-4 { gap: #{1 * s}rem; }\n          .gap-6 { gap: #{1.5 * s}rem; }\n          .gap-12 { gap: #{3 * s}rem; }\n          .mb-6 { margin-bottom: #{1.5 * s}rem; }\n          .mt-1 { margin-top: #{0.25 * s}rem; }\n          .mt-2 { margin-top: #{0.5 * s}rem; }\n          .mt-4 { margin-top: #{1 * s}rem; }\n          .mt-auto { margin-top: auto; }\n          .p-3 { padding: #{0.75 * s}rem; }\n          .p-8 { padding: #{2 * s}rem; }\n          .py-3 { padding-top: #{0.75 * s}rem; padding-bottom: #{0.75 * s}rem; }\n          .py-4 { padding-top: #{1 * s}rem; padding-bottom: #{1 * s}rem; }\n          .px-6 { padding-left: #{1.5 * s}rem; padding-right: #{1.5 * s}rem; }\n          .px-8 { padding-left: #{2 * s}rem; padding-right: #{2 * s}rem; }\n          .px-12 { padding-left: #{3 * s}rem; padding-right: #{3 * s}rem; }\n          .pt-8 { padding-top: #{2 * s}rem; }\n          .pb-4 { padding-bottom: #{1 * s}rem; }\n\n          .w-6 { width: #{1.5 * s}rem; }\n          .h-6 { height: #{1.5 * s}rem; }\n          .w-8 { width: #{2 * s}rem; }\n          .h-8 { height: #{2 * s}rem; }\n          .w-32 { width: #{8 * s}rem; }\n          .h-32 { height: #{8 * s}rem; }\n          .w-full { width: 100%; }\n          .h-full { height: 100%; }\n\n          .rounded-2xl { border-radius: #{1 * s}rem; }\n          .rounded-full { border-radius: 9999px; }\n          .overflow-hidden { overflow: hidden; }\n          .object-contain { object-fit: contain; }\n          .object-cover { object-fit: cover; }\n\n          .border-4 { border-width: #{4 * s}px; border-style: solid; }\n          .border-white { border-color: white; }\n\n          .bg-white { background: white; }\n          .bg-white\\\\/5 { background: rgba(255,255,255,0.05); }\n          .bg-white\\\\/10 { background: rgba(255,255,255,0.1); }\n          .bg-white\\\\/20 { background: rgba(255,255,255,0.2); }\n          .backdrop-blur { backdrop-filter: blur(10px); }\n\n          .grid { display: grid; }\n          .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n\n          .text-6xl { font-size: #{3.75 * s}rem; line-height: 1; }\n          .text-5xl { font-size: #{3 * s}rem; line-height: 1; }\n          .text-3xl { font-size: #{1.875 * s}rem; }\n          .text-lg { font-size: #{1.125 * s}rem; }\n          .text-sm { font-size: #{0.875 * s}rem; }\n          .font-black { font-weight: 900; }\n          .font-bold { font-weight: 700; }\n          .text-white { color: white; }\n          .text-red-200 { color: #FECACA; }\n          .text-red-300 { color: #FCA5A5; }\n          .text-red-300\\\\/60 { color: rgba(252,165,165,0.6); }\n          .text-red-300\\\\/80 { color: rgba(252,165,165,0.8); }\n\n          img { max-width: 100%; height: auto; }\n        </style>\n      </head>\n      <body>\n        #{partial_html}\n      </body>\n      </html>\n    HTML\n  end\nend\n"
  },
  {
    "path": "app/models/organization.rb",
    "content": "# == Schema Information\n#\n# Table name: organizations\n# Database name: primary\n#\n#  id              :integer          not null, primary key\n#  description     :text\n#  domain          :string\n#  kind            :integer          default(\"unknown\"), not null, indexed\n#  logo_background :string           default(\"white\")\n#  logo_url        :string\n#  logo_urls       :json\n#  main_location   :string\n#  name            :string\n#  slug            :string           indexed\n#  website         :string\n#  created_at      :datetime         not null\n#  updated_at      :datetime         not null\n#\n# Indexes\n#\n#  index_organizations_on_kind  (kind)\n#  index_organizations_on_slug  (slug)\n#\nclass Organization < ApplicationRecord\n  include Sluggable\n  include UrlNormalizable\n  include Organization::TypesenseSearchable\n\n  configure_slug(attribute: :name, auto_suffix_on_collision: false)\n\n  # enums\n  enum :kind, {unknown: 0, company: 1, community: 2, foundation: 3, non_profit: 4, organisation: 5}\n\n  # attachments\n  has_one_attached :wrapped_card_horizontal\n\n  # associations\n  has_many :aliases, as: :aliasable, dependent: :destroy\n  has_many :sponsors, dependent: :destroy\n  has_many :events, through: :sponsors\n  has_many :event_involvements, as: :involvementable, dependent: :destroy\n  has_many :involved_events, through: :event_involvements, source: :event\n\n  validates :name, presence: true, uniqueness: true\n\n  before_save :ensure_unique_logo_urls\n\n  def self.find_by_name_or_alias(name)\n    return nil if name.blank?\n\n    organization = find_by(name: name)\n    return organization if organization\n\n    alias_record = ::Alias.find_by(aliasable_type: \"Organization\", name: name)\n    alias_record&.aliasable\n  end\n\n  def self.find_by_slug_or_alias(slug)\n    return nil if slug.blank?\n\n    organization = find_by(slug: slug)\n    return organization if organization\n\n    alias_record = ::Alias.find_by(aliasable_type: \"Organization\", slug: slug)\n    alias_record&.aliasable\n  end\n\n  normalize_url :website\n\n  def organization_image_path\n    [\"organizations\", slug].join(\"/\")\n  end\n\n  def default_organization_image_path\n    [\"organizations\", \"default\"].join(\"/\")\n  end\n\n  def organization_image_or_default_for(filename)\n    org_path = [organization_image_path, filename].join(\"/\")\n    default_path = [default_organization_image_path, filename].join(\"/\")\n\n    base = Rails.root.join(\"app\", \"assets\", \"images\")\n\n    return org_path if (base / org_path).exist?\n\n    default_path\n  end\n\n  def organization_image_for(filename)\n    org_path = [organization_image_path, filename].join(\"/\")\n\n    Rails.root.join(\"app\", \"assets\", \"images\", organization_image_path, filename).exist? ? org_path : nil\n  end\n\n  def avatar_image_path\n    organization_image_or_default_for(\"avatar.webp\")\n  end\n\n  def banner_image_path\n    organization_image_or_default_for(\"banner.webp\")\n  end\n\n  def logo_image_path\n    # First try local asset, then fallback to logo_url\n    if organization_image_for(\"logo.webp\")\n      organization_image_or_default_for(\"logo.webp\")\n    elsif logo_url.present?\n      logo_url\n    else\n      organization_image_or_default_for(\"logo.webp\")\n    end\n  end\n\n  def has_logo_image?\n    organization_image_for(\"logo.webp\").present? || logo_url.present?\n  end\n\n  def logo_background_class\n    case logo_background\n    when \"black\"\n      \"bg-black\"\n    when \"transparent\"\n      \"bg-transparent\"\n    else\n      \"bg-white\"\n    end\n  end\n\n  def logo_border_class\n    case logo_background\n    when \"black\"\n      \"border-gray-600\"\n    when \"transparent\"\n      \"border-gray-300\"\n    else\n      \"border-gray-200\"\n    end\n  end\n\n  def add_logo_url(url)\n    return if url.blank?\n\n    self.logo_urls ||= []\n    self.logo_urls << url unless logo_urls.include?(url)\n\n    logo_urls.uniq!\n  end\n\n  private\n\n  def ensure_unique_logo_urls\n    self.logo_urls = (logo_urls || []).uniq.reject(&:blank?)\n  end\nend\n"
  },
  {
    "path": "app/models/password_reset_token.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: password_reset_tokens\n# Database name: primary\n#\n#  id      :integer          not null, primary key\n#  user_id :integer          not null, indexed\n#\n# Indexes\n#\n#  index_password_reset_tokens_on_user_id  (user_id)\n#\n# Foreign Keys\n#\n#  user_id  (user_id => users.id)\n#\n# rubocop:enable Layout/LineLength\nclass PasswordResetToken < ApplicationRecord\n  belongs_to :user\nend\n"
  },
  {
    "path": "app/models/prompts/base.rb",
    "content": "module Prompts\n  class Base\n    MODEL = \"gpt-5-mini\"\n\n    def to_params\n      {\n        model: model,\n        response_format: response_format,\n        messages: messages,\n        service_tier: service_tier\n      }\n    end\n\n    private\n\n    def model\n      self.class::MODEL\n    end\n\n    def response_format\n      {type: \"json_object\"}\n    end\n\n    def messages\n      [\n        {role: \"system\", content: system_message},\n        {role: \"user\", content: prompt}\n      ]\n    end\n\n    def system_message\n      raise NotImplementedError, \"Subclass #{self.class.name} must implement #system_message\"\n    end\n\n    def prompt\n      raise NotImplementedError, \"Subclass #{self.class.name} must implement #prompt\"\n    end\n\n    def service_tier\n      \"default\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/prompts/talk/enhance_transcript.rb",
    "content": "module Prompts\n  module Talk\n    class EnhanceTranscript < Prompts::Base\n      MODEL = \"gpt-5-mini\"\n\n      def initialize(talk:)\n        @talk = talk\n      end\n\n      private\n\n      attr_reader :talk\n      delegate :title, :description, :speakers, :event_name, :raw_transcript, to: :talk\n\n      def system_message\n        \"You are a helpful assistant skilled in processing and summarizing transcripts.\"\n      end\n\n      def prompt\n        <<~PROMPT\n          You are tasked with improving and formatting a raw VTT transcript. Your goal is to correct and enhance the text, organize it into paragraphs, and format it into a specific JSON structure. Follow these instructions carefully to complete the task.\n\n          First, here is the metadata for the transcript:\n            - title: #{title}\n            - description: #{description}\n            - speaker name: #{speakers.map(&:name).to_sentence}\n            - event name: #{event_name}\n\n          Now, let's process the raw VTT transcript. Here's what you need to do:\n\n          1. Read through the entire raw transcript carefully.\n\n          2. Correct any spelling, grammar, or punctuation errors you find in the text.\n\n          3. Improve the overall readability and coherence of the text without changing its meaning.\n\n          4. Group related sentences into paragraphs. Each paragraph should contain a complete thought or topic.\n\n          5. For each paragraph, use the start time of its first sentence as the paragraph's start time, and the end time of its last sentence as the paragraph's end time.\n\n          6. Format the improved transcript into a JSON structure using this schema:\n          {\"transcript\": [{start_time: \"00:00:00\", end_time: \"00:00:05\", text: \"Hello, world!\"},...]}\n\n          Here is the raw VTT transcript to process:\n\n          <raw_transcript>\n          #{raw_transcript.to_vtt}\n          </raw_transcript>\n\n          To complete this task, follow these steps:\n\n          1. Read through the entire raw transcript.\n          2. Make necessary corrections to spelling, grammar, and punctuation.\n          3. Improve the text for clarity and coherence.\n          4. Group related sentences into paragraphs.\n          5. Determine the start and end times for each paragraph.\n          6. Format the improved transcript into the specified JSON structure.\n          7. Aggregate the timestamps for the paragraphs and write them in the format \"00:00:00\". Don't include the milliseconds.\n\n          Remember to preserve the original meaning of the content while making improvements. Ensure that each JSON object in the array represents a paragraph with its corresponding start time, end time, and improved text.\n\n          Very important :\n          - improve the entire transcript don't stop in the middle of the transcript.\n          - do not add any other text than the transcript.\n          - respect the original timestamps and aggregate correctly the timestamps for the paragraphs.\n        PROMPT\n      end\n\n      def response_format\n        {\n          type: \"json_schema\",\n          json_schema: {\n            # strict: true,\n            name: \"talk_transcript\",\n            schema: {\n              type: \"object\",\n              properties: {\n                transcript: {\n                  type: \"array\",\n                  items: {\n                    type: \"object\",\n                    properties: {\n                      start_time: {type: \"string\"},\n                      end_time: {type: \"string\"},\n                      text: {type: \"string\"}\n                    }\n                  }\n                }\n              },\n              required: [\"transcript\"],\n              additionalProperties: false\n            }\n          }\n        }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/prompts/talk/summary.rb",
    "content": "module Prompts\n  module Talk\n    class Summary < Prompts::Base\n      MODEL = \"gpt-5\"\n\n      def initialize(talk:)\n        @talk = talk\n      end\n\n      private\n\n      attr_reader :talk\n      delegate :title, :description, :speakers, :event_name, :transcript, to: :talk\n\n      def system_message\n        \"You are a helpful assistant skilled in processing and summarizing transcripts.\"\n      end\n\n      def prompt\n        <<~PROMPT\n          You are tasked with creating a summary of a video based on its transcript and metadata. Follow these steps carefully:\n\n          1. First, review the metadata of the video:\n          <metadata>\n            - title: #{title}\n            - description: #{description}\n            - speaker name: #{speakers.map(&:name).to_sentence}\n            - event name: #{event_name}\n          </metadata>\n\n          2. Next, carefully read through the entire transcript:\n          <transcript>\n          #{transcript.to_text}\n          </transcript>\n\n          3. To summarize the video:\n            a) Identify the main topic or theme of the video.\n            b) Determine the key points discussed throughout the video.\n            c) Note any significant examples, case studies, or anecdotes used to illustrate points.\n            d) Capture any important conclusions or takeaways presented.\n            e) Keep in mind the context provided by the metadata (title, description, speaker(s), and event).\n\n          4. Create a summary that:\n            - Introduces the main topic\n            - Outlines the key points in a logical order\n            - Includes relevant examples or illustrations if they are crucial to understanding the content\n            - Concludes with the main takeaways or conclusions from the video\n            - Is between 400-500 words in length\n            - format it using markdown\n            - use bullets for the key points\n\n          5. exctract keywords\n            - create a list of keywords to describe this video\n            - 5 to 10 keywords\n            - mostly teachnical keywords\n\n          6. Format your summary as a JSON object with the following schema:\n            {\n              \"summary\": \"Your summary text here using markdown\",\n              \"keywords\": [\"keyword1\", \"keyword2\", \"keyword3\"]\n            }\n\n          7. Ensure that your summary is:\n            - Objective and factual, based solely on the content of the transcript and metadata\n            - Written in clear, concise language\n            - Free of personal opinions or external information not present in the provided content\n\n          8. Output your JSON object containing the summary, ensuring it is properly formatted and enclosed in <answer> tags.\n\n          9. Uses markdown for the summary to make it more readable define clear sections and uses bullets for the key points. do not use level 1 headings only start from level 2 (##).\n        PROMPT\n      end\n\n      def response_format\n        {\n          type: \"json_schema\",\n          json_schema: {\n            strict: true,\n            name: \"talk_summary\",\n            schema: {\n              type: \"object\",\n              additionalProperties: false,\n              required: [\"summary\", \"keywords\"],\n              properties: {\n                summary: {type: \"string\"},\n                keywords: {\n                  type: \"array\",\n                  items: {type: \"string\"}\n                }\n              }\n            }\n          }\n        }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/prompts/talk/topics.rb",
    "content": "module Prompts\n  module Talk\n    class Topics < Prompts::Base\n      MODEL = \"gpt-5-mini\"\n\n      def initialize(talk:)\n        @talk = talk\n      end\n\n      private\n\n      attr_reader :talk\n      delegate :title, :description, :speakers, :event_name, :transcript, to: :talk\n\n      def system_message\n        \"You are a helpful assistant skilled in assigned a list of predefined topics to a transcript.\"\n      end\n\n      def prompt\n        <<~PROMPT\n          You are tasked with figuring out of the list of provided topics matches a transcript based on the transcript and its metadata. Follow these steps carefully:\n\n          1. First, review the metadata of the video:\n          <metadata>\n            - title: #{title}\n            - description: #{description}\n            - speaker name: #{speakers.map(&:name).to_sentence}\n            - event name: #{event_name}\n          </metadata>\n\n          2. Next, carefully read through the entire transcript:\n          Note: The transcript is not perfect, it's a transcription of the video, so it might have some errors.\n          <transcript>\n          #{transcript.to_text}\n          </transcript>\n\n          3. Read through the entire list of exisiting topics for other talks.\n          <topics>\n            #{::Topic.approved.pluck(:name).join(\", \")}\n          </topics>\n\n          3 bis. Read through the entire list of topics that we have already rejected for other talks.\n          <rejected_topics>\n            #{::Topic.rejected.pluck(:name).join(\", \")}\n          </rejected_topics>\n\n          4. Pick 5 to 7 topics that would describe the talk best.\n            You can pick any topic from the list of exisiting topics or create a new one.\n\n            If you create a new topic, please ensure that it is relevant to the content of the transcript and match the recommended topics kind.\n            Also for new topics please ensure they are not a synonym of an existing topic.\n              - Make sure it fits the overall theme of this website, it's a website for Ruby related videos, so it should have something to do with Ruby, Web, Programming, Teams, People or Tech.\n              - Ruby framework names (examples: Rails, Sinatra, Hanami, Ruby on Rails, ...)\n              - Ruby gem names\n              - Design patterns names (examples: MVC, MVP, Singleton, Observer, Strategy, Command, Decorator, Composite, Facade, Proxy, Mediator, Memento, Observer, State, Template Method, Visitor, ...)\n              - Database names (examples: PostgreSQL, MySQL, MongoDB, Redis, Elasticsearch, Cassandra, CouchDB, SQLite, ...)\n              - front end frameworks names (examples: React, Vue, Angular, Ember, Svelte, Stimulus, Preact, Hyperapp, Inferno, Solid, Mithril, Riot, Polymer, Web Components, Hotwire, Turbo, StimulusReflex, Strada ...)\n              - front end CSS libraries and framework names (examples: Tailwind, Bootstrap, Bulma, Material UI, Foundation, ...)\n              - front end JavaScript libraries names (examples: jQuery, D3, Chart.js, Lodash, Moment.js, ...)\n\n            Topics are typically one or two words long, with some exceptions such as \"Ruby on Rails\"\n\n          5. Format your topics you picked as a JSON object with the following schema:\n            {\n              \"topics\": [\"topic1\", \"topic2\", \"topic3\"]\n            }\n\n          6. Ensure that your summary is:\n            - relevant to the content of the transcript and match the recommended topics kind\n            - Free of personal opinions or external information not present in the provided content\n\n          7. Output your JSON object containing the list of topics in the JSON format.\n        PROMPT\n      end\n\n      def response_format\n        {\n          type: \"json_schema\",\n          json_schema: {\n            name: \"talk_topics\",\n            schema: {\n              type: \"object\",\n              strict: true,\n              properties: {\n                topics: {\n                  type: \"array\",\n                  description: \"A list of topics related to the \",\n                  items: {\n                    type: \"string\",\n                    description: \"A single topic.\"\n                  }\n                }\n              },\n              required: [\"topics\"],\n              additionalProperties: false\n            }\n          }\n        }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/prompts/topic/match_talks.rb",
    "content": "module Prompts\n  module Topic\n    class MatchTalks < Prompts::Base\n      MODEL = \"gpt-4.1\"\n\n      def initialize(topic:, talks:)\n        @topic = topic\n        @talks = talks\n      end\n\n      private\n\n      attr_reader :topic, :talks\n\n      def system_message\n        <<~SYSTEM\n          You are a helpful assistant that determines whether Ruby conference talks are relevant to a specific topic.\n          You have deep knowledge of the Ruby ecosystem, programming concepts, and software development.\n        SYSTEM\n      end\n\n      def prompt\n        <<~PROMPT\n          You are tasked with determining which talks from a list are actually about or significantly related to a specific topic.\n\n          The topic is: \"#{topic.name}\"\n          #{\"Topic description: #{topic.description}\" if topic.description.present?}\n\n          Here are the candidate talks to evaluate:\n\n          <talks>\n          #{talks_info}\n          </talks>\n\n          For each talk, determine if it is actually about or significantly discusses the topic \"#{topic.name}\".\n\n          IMPORTANT RULES:\n          1. A talk matches if the topic is a PRIMARY subject of the talk, not just a passing mention\n          2. Consider the title, description, summary, and speaker context\n          3. Be VERY strict - only mark as matching with \"high\" confidence if you're absolutely certain the talk substantially covers the topic\n          4. False positives are worse than false negatives - when in doubt, mark as not matching or use \"low\" confidence\n          5. Consider synonyms and related terms (e.g., \"Ruby on Rails\" matches \"Rails\")\n          6. Only talks with \"high\" confidence will be assigned to the topic, so be conservative\n\n          Return a JSON object with the following schema:\n          {\n            \"matches\": [\n              {\n                \"talk_id\": <integer>,\n                \"matches\": true | false,\n                \"confidence\": \"high\" | \"medium\" | \"low\",\n                \"reasoning\": \"brief explanation\"\n              }\n            ]\n          }\n        PROMPT\n      end\n\n      def talks_info\n        talks.map do |talk|\n          <<~TALK\n            - ID: #{talk.id}\n              Title: #{talk.title}\n              Description: #{talk.description.presence || \"N/A\"}\n              Summary: #{talk.summary.presence || \"N/A\"}\n              Speakers: #{talk.speakers.map(&:name).join(\", \").presence || \"N/A\"}\n              Event: #{talk.event&.name || \"N/A\"}\n          TALK\n        end.join(\"\\n\")\n      end\n\n      def response_format\n        {\n          type: \"json_schema\",\n          json_schema: {\n            name: \"talk_matches\",\n            schema: {\n              type: \"object\",\n              strict: true,\n              properties: {\n                matches: {\n                  type: \"array\",\n                  items: {\n                    type: \"object\",\n                    properties: {\n                      talk_id: {type: \"integer\"},\n                      matches: {type: \"boolean\"},\n                      confidence: {\n                        type: \"string\",\n                        enum: [\"high\", \"medium\", \"low\"]\n                      },\n                      reasoning: {type: \"string\"}\n                    },\n                    required: [\"talk_id\", \"matches\", \"confidence\", \"reasoning\"],\n                    additionalProperties: false\n                  }\n                }\n              },\n              required: [\"matches\"],\n              additionalProperties: false\n            }\n          }\n        }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/prompts/topic/suggest_gems.rb",
    "content": "module Prompts\n  module Topic\n    class SuggestGems < Prompts::Base\n      MODEL = \"gpt-4o-mini\"\n\n      def initialize(topics:)\n        @topics = topics\n      end\n\n      private\n\n      attr_reader :topics\n\n      def system_message\n        <<~SYSTEM\n          You are a helpful assistant that maps Ruby conference talk topics to RubyGems.\n          You have deep knowledge of the Ruby ecosystem, including popular gems, Rails components, and Ruby libraries.\n        SYSTEM\n      end\n\n      def prompt\n        <<~PROMPT\n          You are tasked with mapping Ruby conference talk topics to their corresponding RubyGems packages.\n\n          Here is a list of topics from Ruby conference talks, along with the number of talks for each topic:\n\n          <topics>\n          #{topics.map { |t| \"- #{t.name} (#{t.talks_count} talks)\" }.join(\"\\n\")}\n          </topics>\n\n          For each topic, determine if it DIRECTLY corresponds to one or more RubyGems packages.\n\n          CRITICAL RULES:\n          1. Only map a topic to a gem if the topic name IS the gem or a direct reference to it\n          2. DO NOT map general/abstract concepts to gems, even if gems exist in that space:\n             - \"Testing\" -> [] (NOT rspec, minitest, etc. - \"Testing\" is a concept, not a gem)\n             - \"Performance\" -> [] (concept, not a gem)\n             - \"Security\" -> [] (concept, not a gem)\n             - \"Debugging\" -> [] (concept, not a gem)\n             - \"Refactoring\" -> [] (concept, not a gem)\n             - \"API\" -> [] (concept, not a gem)\n             - \"Database\" -> [] (concept, not a gem)\n             - \"Caching\" -> [] (concept, not a gem)\n             - \"Background Jobs\" -> [] (concept, not a gem)\n             - \"Authentication\" -> [] (concept, not a gem)\n             - \"Authorization\" -> [] (concept, not a gem)\n          3. Only suggest gems when the topic name matches or directly references the gem:\n             - \"RSpec\" -> [\"rspec\"] (topic IS the gem name)\n             - \"Sidekiq\" -> [\"sidekiq\"] (topic IS the gem name)\n             - \"Rails\" or \"Ruby on Rails\" -> [\"rails\"] (direct reference)\n             - \"ActiveRecord\" or \"Active Record\" -> [\"activerecord\"] (direct reference)\n             - \"Hotwire\" -> [\"turbo-rails\", \"stimulus-rails\"] (Hotwire is the umbrella name for these gems)\n             - \"Turbo\" -> [\"turbo-rails\"] (direct reference)\n             - \"Stimulus\" -> [\"stimulus-rails\"] (direct reference)\n          4. Use the exact gem name as it appears on RubyGems.org\n          5. A topic can map to multiple gems only if it's an umbrella term for those specific gems\n          6. When in doubt, return an empty array - it's better to miss a mapping than to incorrectly map a general concept\n\n          Return a JSON object with the following schema:\n          {\n            \"suggestions\": [\n              {\n                \"topic_name\": \"the exact topic name from the input\",\n                \"gem_names\": [\"gem1\", \"gem2\"] or [] if no gems apply,\n                \"confidence\": \"high\" | \"medium\" | \"low\",\n                \"reasoning\": \"brief explanation of why these gems were chosen or why no gems apply\"\n              }\n            ]\n          }\n        PROMPT\n      end\n\n      def response_format\n        {\n          type: \"json_schema\",\n          json_schema: {\n            name: \"gem_suggestions\",\n            schema: {\n              type: \"object\",\n              strict: true,\n              properties: {\n                suggestions: {\n                  type: \"array\",\n                  items: {\n                    type: \"object\",\n                    properties: {\n                      topic_name: {type: \"string\"},\n                      gem_names: {\n                        type: \"array\",\n                        items: {type: \"string\"}\n                      },\n                      confidence: {\n                        type: \"string\",\n                        enum: [\"high\", \"medium\", \"low\"]\n                      },\n                      reasoning: {type: \"string\"}\n                    },\n                    required: [\"topic_name\", \"gem_names\", \"confidence\", \"reasoning\"],\n                    additionalProperties: false\n                  }\n                }\n              },\n              required: [\"suggestions\"],\n              additionalProperties: false\n            }\n          }\n        }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/rollup.rb",
    "content": "# == Schema Information\n#\n# Table name: rollups\n# Database name: primary\n#\n#  id         :integer          not null, primary key\n#  dimensions :json             not null, uniquely indexed => [name, interval, time]\n#  interval   :string           not null, uniquely indexed => [name, time, dimensions]\n#  name       :string           not null, uniquely indexed => [interval, time, dimensions]\n#  time       :datetime         not null, uniquely indexed => [name, interval, dimensions]\n#  value      :float\n#\n# Indexes\n#\n#  index_rollups_on_name_and_interval_and_time_and_dimensions  (name,interval,time,dimensions) UNIQUE\n#\nclass Rollup < ApplicationRecord\n  # this Rollup model is heavily inspired from ankane/rollup gem but adapted so that we can\n  # use Sqlite\n  #\n  validates :name, presence: true\n  validates :interval, presence: true\n  validates :time, presence: true\n\n  scope :with_dimensions, ->(dimensions) do\n    relation = self\n    dimensions.each do |k, v|\n      relation = if v.nil?\n        relation.where(\"json_extract(dimensions, ?) IS NULL\", \"$.#{k}\")\n      elsif v.is_a?(Array)\n        relation.where(\"json_extract(dimensions, ?) IN (?)\", \"$.#{k}\", v.map { |vi| vi.as_json.to_s })\n      else\n        relation.where(\"json_extract(dimensions, ?) = ?\", \"$.#{k}\", v.as_json.to_s)\n      end\n    end\n    relation\n  end\n\n  class << self\n    attr_accessor :week_start\n    attr_writer :time_zone\n  end\n  self.week_start = :monday\n\n  class << self\n    # do not memoize so Time.zone can change\n    def time_zone\n      (defined?(@time_zone) && @time_zone) || Time.zone || ActiveSupport::TimeZone[\"Etc/UTC\"]\n    end\n\n    def series(name, interval: \"day\", dimensions: {})\n      relation = where(name: name, interval: interval)\n      relation = relation.where(dimensions: dimensions) if dimensions.any?\n\n      # use select_all due to incorrect casting with pluck\n      sql = relation.order(:time).select(Utils.time_sql(interval), :value).to_sql\n      result = connection_pool.with_connection { |c| c.select_all(sql) }.rows\n\n      make_series(result, interval)\n    end\n\n    def list\n      select(:name, :interval).distinct.order(:name, :interval).map do |r|\n        {name: r.name, interval: r.interval}\n      end\n    end\n\n    # TODO maybe use in_batches\n    def rename(old_name, new_name)\n      where(name: old_name).update_all(name: new_name)\n    end\n\n    private\n\n    def make_series(result, interval)\n      series = {}\n      if Utils.date_interval?(interval)\n        result.each do |row|\n          series[row[0].to_date] = (series[row[0].to_date] || 0) + row[1]\n        end\n      else\n        time_zone = Rollup.time_zone\n        if result.any? && result[0][0].is_a?(Time)\n          result.each do |row|\n            series[row[0].in_time_zone(time_zone)] = (series[row[0].in_time_zone(time_zone)] || 0) + row[1]\n          end\n        else\n          utc = ActiveSupport::TimeZone[\"Etc/UTC\"]\n          result.each do |row|\n            # row can be time or string\n            series[utc.parse(row[0]).in_time_zone(time_zone)] = (series[utc.parse(row[0]).in_time_zone(time_zone)] || 0) + row[1]\n          end\n        end\n      end\n      series\n    end\n  end\n\n  # feels cleaner than overriding _read_attribute\n  def inspect\n    if Utils.date_interval?(interval)\n      super.sub(/time: \"[^\"]+\"/, \"time: \\\"#{time.to_formatted_s(:db)}\\\"\")\n    else\n      super\n    end\n  end\n\n  def time\n    if Utils.date_interval?(interval) && !time_before_type_cast.nil?\n      if time_before_type_cast.is_a?(Time)\n        time_before_type_cast.utc.to_date\n      else\n        Date.parse(time_before_type_cast.to_s)\n      end\n    else\n      super\n    end\n  end\n\n  class Aggregator\n    def initialize(klass)\n      @klass = klass # or relation\n    end\n\n    def rollup(name, column: nil, interval: \"day\", dimension_names: nil, time_zone: nil, current: nil, last: nil, clear: false, range: nil, &block)\n      raise \"Name can't be blank\" if name.blank?\n\n      column ||= @klass.rollup_column || :created_at\n      # Groupdate 6+ validates, but keep this for now for additional safety\n      # no need to quote/resolve column here, as Groupdate handles it\n      column = validate_column(column)\n\n      relation = perform_group(name, column: column, interval: interval, time_zone: time_zone, current: current, last: last, clear: clear, range: range)\n      result = perform_calculation(relation, &block)\n\n      dimension_names = set_dimension_names(dimension_names, relation)\n      records = prepare_result(result, name, dimension_names, interval)\n\n      maybe_clear(clear, name, interval) do\n        save_records(records) if records.any?\n      end\n    end\n\n    # basic version of Active Record disallow_raw_sql!\n    # symbol = column (safe), Arel node = SQL (safe), other = untrusted\n    # matches table.column and column\n    def validate_column(column)\n      unless column.is_a?(Symbol) || column.is_a?(Arel::Nodes::SqlLiteral)\n        column = column.to_s\n        unless /\\A\\w+(\\.\\w+)?\\z/i.match?(column)\n          raise ActiveRecord::UnknownAttributeReference, \"Query method called with non-attribute argument(s): #{column.inspect}. Use Arel.sql() for known-safe values.\"\n        end\n      end\n      column\n    end\n\n    def perform_group(name, column:, interval:, time_zone:, current:, last:, clear:, range:)\n      raise ArgumentError, \"Cannot use last and range together\" if last && range\n      raise ArgumentError, \"Cannot use last and clear together\" if last && clear\n      raise ArgumentError, \"Cannot use range and clear together\" if range && clear\n      raise ArgumentError, \"Cannot use range and current together\" if range && !current.nil?\n\n      current = true if current.nil?\n      time_zone = Rollup.time_zone if time_zone.nil?\n\n      gd_options = {\n        current: current\n      }\n\n      # make sure Groupdate global options aren't applied\n      gd_options[:time_zone] = time_zone\n      gd_options[:week_start] = Rollup.week_start if interval.to_s == \"week\"\n      gd_options[:day_start] = 0 if Utils.date_interval?(interval)\n\n      if last\n        gd_options[:last] = last\n      elsif range\n        gd_options[:range] = range\n        gd_options[:expand_range] = true\n        gd_options.delete(:current)\n      elsif !clear\n        # if no rollups, compute all intervals\n        # if rollups, recompute last interval\n        max_time = Rollup.unscoped.where(name: name, interval: interval).maximum(Utils.time_sql(interval))\n        if max_time\n          # for MySQL on Ubuntu 18.04 (and likely other platforms)\n          if max_time.is_a?(String)\n            utc = ActiveSupport::TimeZone[\"Etc/UTC\"]\n            max_time =\n              if Utils.date_interval?(interval)\n                max_time.to_date\n              else\n                t = utc.parse(max_time)\n                t = t.in_time_zone(time_zone) if time_zone\n                t\n              end\n          end\n\n          # aligns perfectly if time zone doesn't change\n          # if time zone does change, there are other problems besides this\n          gd_options[:range] = max_time..\n        end\n      end\n\n      # intervals are stored as given\n      # we don't normalize intervals (i.e. change 60s -> 1m)\n      case interval.to_s\n      when \"hour\", \"day\", \"week\", \"month\", \"quarter\", \"year\"\n        @klass.group_by_period(interval, column, **gd_options)\n      when /\\A\\d+s\\z/\n        @klass.group_by_second(column, n: interval.to_i, **gd_options)\n      when /\\A\\d+m\\z/\n        @klass.group_by_minute(column, n: interval.to_i, **gd_options)\n      else\n        raise ArgumentError, \"Invalid interval: #{interval}\"\n      end\n    end\n\n    def set_dimension_names(dimension_names, relation)\n      groups = relation.group_values[0..-2]\n\n      if dimension_names\n        if dimension_names.size != groups.size\n          raise ArgumentError, \"Expected dimension_names to be size #{groups.size}, not #{dimension_names.size}\"\n        end\n        dimension_names\n      else\n        groups.map { |group| determine_dimension_name(group) }\n      end\n    end\n\n    def determine_dimension_name(group)\n      # split by ., ->>, and -> and remove whitespace\n      value = group.to_s.split(/\\s*((\\.)|(->>)|(->))\\s*/).last\n\n      # removing starting and ending quotes\n      # for simplicity, they don't need to be the same\n      value = value[1..-2] if value.match?(/\\A[\"'`].+[\"'`]\\z/)\n\n      unless value.match?(/\\A\\w+\\z/)\n        raise \"Cannot determine dimension name: #{group}. Use the dimension_names option\"\n      end\n\n      value\n    end\n\n    # calculation can mutate relation, but that's fine\n    def perform_calculation(relation, &block)\n      if block_given?\n        yield(relation)\n      else\n        relation.count\n      end\n    end\n\n    def prepare_result(result, name, dimension_names, interval)\n      raise \"Expected calculation to return Hash, not #{result.class.name}\" unless result.is_a?(Hash)\n\n      time_class = Utils.date_interval?(interval) ? Date : Time\n      expected_key_size = dimension_names.size + 1\n\n      result.map do |key, value|\n        dimensions = {}\n        if dimension_names.any?\n          unless key.is_a?(Array) && key.size == expected_key_size\n            raise \"Expected result key to be Array with size #{expected_key_size}\"\n          end\n          time = key[-1]\n          # may be able to support dimensions in SQLite by sorting dimension names\n          dimension_names.each_with_index do |dn, i|\n            dimensions[dn] = key[i]\n          end\n        else\n          time = key\n        end\n\n        raise \"Expected time to be #{time_class.name}, not #{time.class.name}\" unless time.is_a?(time_class)\n        raise \"Expected value to be Numeric or nil, not #{value.class.name}\" unless value.is_a?(Numeric) || value.nil?\n\n        record = {\n          name: name,\n          interval: interval,\n          time: time,\n          value: value\n        }\n        record[:dimensions] = dimensions\n        record\n      end\n    end\n\n    def maybe_clear(clear, name, interval)\n      if clear\n        Rollup.transaction do\n          Rollup.unscoped.where(name: name, interval: interval).delete_all\n          yield\n        end\n      else\n        yield\n      end\n    end\n\n    def save_records(records)\n      # order must match unique index\n      # consider using index name instead\n      conflict_target = [:name, :interval, :time, :dimensions]\n      options = {unique_by: conflict_target}\n\n      utc = ActiveSupport::TimeZone[\"Etc/UTC\"]\n      records.each do |v|\n        v[:time] = v[:time].in_time_zone(utc) if v[:time].is_a?(Date)\n      end\n\n      Rollup.unscoped.upsert_all(records, **options)\n    end\n  end\n\n  module Utils\n    DATE_INTERVALS = %w[day week month quarter year]\n\n    class << self\n      def time_sql(interval)\n        if date_interval?(interval)\n          \"date(rollups.time)\"\n        else\n          :time\n        end\n      end\n\n      def date_interval?(interval)\n        DATE_INTERVALS.include?(interval.to_s)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/search/backend/sqlite_fts/indexer.rb",
    "content": "# frozen_string_literal: true\n\nclass Search::Backend::SQLiteFTS\n  class Indexer\n    class << self\n      def index(record)\n        case record\n        when Talk\n          index_talk(record)\n        when User\n          index_user(record)\n        when Event\n          index_event(record)\n        end\n      end\n\n      def remove(record)\n        case record\n        when Talk\n          remove_talk(record)\n        when User\n          remove_user(record)\n        when Event\n          remove_event(record)\n        end\n      end\n\n      def reindex_all\n        reindex_talks\n        reindex_users\n        reindex_events\n      end\n\n      def reindex_talks\n        Talk::Index.delete_all\n        Talk.watchable.find_each do |talk|\n          index_talk(talk)\n        end\n      end\n\n      def reindex_users\n        User::Index.delete_all\n        User.indexable.find_each do |user|\n          index_user(user)\n        end\n      end\n\n      def reindex_events\n        Event::Index.delete_all if defined?(Event::Index)\n        # Event indexing if Event::Index exists\n      end\n\n      private\n\n      def index_talk(talk)\n        return unless talk.video_provider.in?(Talk::WATCHABLE_PROVIDERS)\n\n        talk.fts_index.reindex\n      rescue ActiveRecord::RecordNotUnique\n        # Already indexed\n      end\n\n      def remove_talk(talk)\n        Talk::Index.where(rowid: talk.id).delete_all\n      end\n\n      def index_user(user)\n        return unless user.canonical_id.nil? && user.talks_count.to_i > 0\n\n        user.fts_index.reindex\n      rescue ActiveRecord::RecordNotUnique\n        # Already indexed\n      end\n\n      def remove_user(user)\n        User::Index.where(rowid: user.id).delete_all\n      end\n\n      def index_event(event)\n        # Implement when Event::Index exists\n      end\n\n      def remove_event(event)\n        # Implement when Event::Index exists\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/search/backend/sqlite_fts.rb",
    "content": "# frozen_string_literal: true\n\nclass Search::Backend::SQLiteFTS\n  class << self\n    def search_talks(query, limit:, **options)\n      talks = Talk.includes(:speakers, event: :series)\n      talks = talks.ft_search(query).with_snippets if query.present?\n      talks = talks.for_topic(options[:topic_slug]) if options[:topic_slug].present?\n      talks = talks.for_event(options[:event_slug]) if options[:event_slug].present?\n      talks = talks.for_speaker(options[:speaker_slug]) if options[:speaker_slug].present?\n      talks = talks.where(kind: options[:kind]) if options[:kind].present?\n      talks = talks.where(language: options[:language]) if options[:language].present?\n\n      case options[:status]\n      when \"scheduled\"\n        talks = talks.scheduled\n      when \"all\"\n        # Show all talks\n      else\n        talks = talks.ft_watchable unless options[:include_unwatchable]\n      end\n\n      total_count = talks.except(:select).count\n\n      [talks.limit(limit), total_count]\n    end\n\n    def search_talks_with_pagy(query, pagy_backend:, **options)\n      talks = Talk.includes(:speakers, event: :series, child_talks: :speakers)\n      talks = talks.ft_search(query).with_snippets if query.present?\n      talks = talks.for_topic(options[:topic_slug]) if options[:topic_slug].present?\n      talks = talks.for_event(options[:event_slug]) if options[:event_slug].present?\n      talks = talks.for_speaker(options[:speaker_slug]) if options[:speaker_slug].present?\n      talks = talks.where(kind: options[:kind]) if options[:kind].present?\n      talks = talks.where(language: options[:language]) if options[:language].present?\n      talks = talks.where(\"created_at >= ?\", options[:created_after]) if options[:created_after].present?\n\n      case options[:status]\n      when \"scheduled\"\n        talks = talks.scheduled\n      when \"all\"\n        # Show all talks\n      else\n        talks = talks.ft_watchable unless options[:include_unwatchable]\n      end\n\n      talks = apply_sort(talks, query, options[:sort])\n\n      pagy_options = {\n        limit: options[:per_page] || 20,\n        page: options[:page] || 1\n      }.compact_blank\n\n      pagy_backend.send(:pagy, talks, **pagy_options)\n    end\n\n    def search_speakers(query, limit:)\n      speakers = User.speakers.ft_search(query).with_snippets.ranked\n      total_count = speakers.except(:select).count\n\n      [speakers.limit(limit), total_count]\n    end\n\n    def search_events(query, limit:)\n      events = Event.includes(:series).canonical.ft_search(query)\n      total_count = events.except(:select).count\n\n      [events.limit(limit), total_count]\n    end\n\n    def search_topics(query, limit:)\n      topics = Topic.approved.canonical.with_talks.order(talks_count: :desc)\n      topics = topics.where(\"name LIKE ?\", \"%#{query}%\")\n      total_count = topics.count\n\n      [topics.limit(limit), total_count]\n    end\n\n    def search_series(query, limit:)\n      series = EventSeries.joins(:events).distinct.order(name: :asc)\n      series = series.where(\"event_series.name LIKE ?\", \"%#{query}%\")\n      total_count = series.count\n\n      [series.limit(limit), total_count]\n    end\n\n    def search_organizations(query, limit:)\n      organizations = Organization.joins(:sponsors).distinct.order(name: :asc)\n      organizations = organizations.where(\"organizations.name LIKE ?\", \"%#{query}%\")\n      total_count = organizations.count\n\n      [organizations.limit(limit), total_count]\n    end\n\n    def search_languages(query, limit:)\n      return [[], 0] if query.blank?\n\n      results = []\n      query_downcase = query.downcase\n\n      languages_with_talks.each do |language_code, talk_count|\n        language_name = Language.by_code(language_code)\n        next unless language_name\n\n        if language_name.downcase.include?(query_downcase) ||\n            language_code.downcase.include?(query_downcase)\n          results << {\n            code: language_code,\n            name: language_name,\n            talk_count: talk_count\n          }\n        end\n      end\n\n      sorted = results.sort_by do |r|\n        exact_match = (r[:name].downcase == query_downcase) ? 0 : 1\n        starts_with = r[:name].downcase.start_with?(query_downcase) ? 0 : 1\n\n        [exact_match, starts_with, -r[:talk_count]]\n      end.first(limit)\n\n      [sorted, sorted.size]\n    end\n\n    def search_locations(query, limit:)\n      [[], 0]\n    end\n\n    def search_continents(query, limit:)\n      [[], 0]\n    end\n\n    def search_countries(query, limit:)\n      [[], 0]\n    end\n\n    def search_states(query, limit:)\n      [[], 0]\n    end\n\n    def search_cities(query, limit:)\n      [[], 0]\n    end\n\n    def search_kinds(query, limit:)\n      [[], 0]\n    end\n\n    def available?\n      true\n    end\n\n    def name\n      :sqlite_fts\n    end\n\n    def indexer\n      Indexer\n    end\n\n    def reset_cache!\n      @languages_with_talks = nil\n    end\n\n    private\n\n    SORT_OPTIONS = {\n      \"date\" => \"talks.date DESC\",\n      \"date_desc\" => \"talks.date DESC\",\n      \"date_asc\" => \"talks.date ASC\",\n      \"created_at_desc\" => \"talks.created_at DESC\",\n      \"created_at_asc\" => \"talks.created_at ASC\"\n    }.freeze\n\n    def apply_sort(talks, query, sort)\n      case sort\n      when \"relevance\", \"ranked\"\n        query.present? ? talks.ranked : talks.order(\"talks.date DESC\")\n      when *SORT_OPTIONS.keys\n        talks.order(SORT_OPTIONS[sort])\n      else\n        talks.order(\"talks.date DESC\")\n      end\n    end\n\n    def languages_with_talks\n      @languages_with_talks ||= Talk.where.not(language: [nil, \"\", \"en\"])\n        .group(:language)\n        .count\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/search/backend/typesense/circuit_breaker.rb",
    "content": "# frozen_string_literal: true\n\nclass Search::Backend::Typesense\n  class CircuitBreaker\n    def initialize(ttl:)\n      @ttl = ttl\n      @state = :closed\n      @last_failure_at = nil\n      @last_success_at = nil\n      @mutex = Mutex.new\n    end\n\n    def call\n      @mutex.synchronize do\n        if @state == :open && @last_failure_at && (Time.now - @last_failure_at) < @ttl\n          return false\n        end\n\n        if @state == :closed && @last_success_at && (Time.now - @last_success_at) < @ttl\n          return true\n        end\n      end\n\n      result = yield\n\n      @mutex.synchronize do\n        @state = :closed\n        @last_success_at = Time.now\n      end\n\n      result\n    rescue\n      @mutex.synchronize do\n        @state = :open\n        @last_failure_at = Time.now\n      end\n\n      false\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/search/backend/typesense/indexer.rb",
    "content": "# frozen_string_literal: true\n\nclass Search::Backend::Typesense\n  class Indexer\n    class << self\n      def index(record)\n        return unless should_index?(record)\n\n        if record.is_a?(City)\n          LocationIndexer.index_city(record)\n        else\n          record.typesense_index!\n        end\n      end\n\n      def remove(record)\n        if record.is_a?(City)\n          LocationIndexer.remove_city(record)\n        else\n          record.typesense_remove_from_index!\n        end\n      rescue ::Typesense::Error::ObjectNotFound\n        # Already removed\n      end\n\n      def reindex_all\n        reindex_talks\n        reindex_users\n        reindex_events\n        reindex_topics\n        reindex_series\n        reindex_organizations\n        reindex_languages\n        reindex_locations\n        reindex_kinds\n      end\n\n      def reindex_talks\n        Talk.typesense_reindex!\n      end\n\n      def reindex_users\n        User.typesense_reindex!\n      end\n\n      def reindex_events\n        Event.typesense_reindex!\n      end\n\n      def reindex_topics\n        Topic.typesense_reindex!\n      end\n\n      def reindex_series\n        EventSeries.typesense_reindex!\n      end\n\n      def reindex_organizations\n        Organization.typesense_reindex!\n      end\n\n      def reindex_languages\n        LanguageIndexer.reindex_all\n      end\n\n      def reindex_locations\n        LocationIndexer.reindex_all\n      end\n\n      def reindex_kinds\n        KindIndexer.reindex_all\n      end\n\n      private\n\n      def should_index?(record)\n        return true if record.is_a?(City)\n        return false unless record.respond_to?(:typesense_index!)\n\n        record.respond_to?(:should_index?) ? record.should_index? : true\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/search/backend/typesense/kind_indexer.rb",
    "content": "# frozen_string_literal: true\n\nclass Search::Backend::Typesense\n  class KindIndexer\n    COLLECTION_NAME = \"kinds\"\n\n    TALK_KINDS = {\n      \"keynote\" => {name: \"Keynotes\", icon: \"star\", category: \"talk\"},\n      \"talk\" => {name: \"Talks\", icon: \"microphone\", category: \"talk\"},\n      \"lightning_talk\" => {name: \"Lightning Talks\", icon: \"bolt\", category: \"talk\"},\n      \"workshop\" => {name: \"Workshops\", icon: \"wrench\", category: \"talk\"},\n      \"panel\" => {name: \"Panels\", icon: \"users\", category: \"talk\"},\n      \"interview\" => {name: \"Interviews\", icon: \"comments\", category: \"talk\"},\n      \"fireside_chat\" => {name: \"Fireside Chats\", icon: \"fire\", category: \"talk\"},\n      \"demo\" => {name: \"Demos\", icon: \"desktop\", category: \"talk\"},\n      \"q_and_a\" => {name: \"Q&A Sessions\", icon: \"question-circle\", category: \"talk\"},\n      \"discussion\" => {name: \"Discussions\", icon: \"comment-dots\", category: \"talk\"},\n      \"podcast\" => {name: \"Podcasts\", icon: \"podcast\", category: \"talk\"},\n      \"gameshow\" => {name: \"Gameshows\", icon: \"gamepad\", category: \"talk\"},\n      \"award\" => {name: \"Awards\", icon: \"award\", category: \"talk\"}\n    }.freeze\n\n    EVENT_KINDS = {\n      \"conference\" => {name: \"Conferences\", icon: \"building\", category: \"event\"},\n      \"meetup\" => {name: \"Meetups\", icon: \"users\", category: \"event\"},\n      \"workshop\" => {name: \"Workshops\", icon: \"wrench\", category: \"event\"},\n      \"retreat\" => {name: \"Retreats\", icon: \"mountain\", category: \"event\"},\n      \"hackathon\" => {name: \"Hackathons\", icon: \"code\", category: \"event\"},\n      \"event\" => {name: \"Events\", icon: \"calendar\", category: \"event\"}\n    }.freeze\n\n    class << self\n      def collection_schema\n        {\n          \"name\" => COLLECTION_NAME,\n          \"fields\" => [\n            {\"name\" => \"id\", \"type\" => \"string\"},\n            {\"name\" => \"slug\", \"type\" => \"string\"},\n            {\"name\" => \"name\", \"type\" => \"string\"},\n            {\"name\" => \"category\", \"type\" => \"string\", \"facet\" => true},\n            {\"name\" => \"icon\", \"type\" => \"string\", \"optional\" => true},\n            {\"name\" => \"count\", \"type\" => \"int32\"}\n          ],\n          \"default_sorting_field\" => \"count\",\n          \"token_separators\" => [\"-\", \"_\"]\n        }\n      end\n\n      def client\n        ::Typesense::Client.new(::Typesense.configuration)\n      end\n\n      def collection\n        client.collections[COLLECTION_NAME]\n      end\n\n      def ensure_collection!\n        collection.retrieve\n      rescue ::Typesense::Error::ObjectNotFound\n        client.collections.create(collection_schema)\n      end\n\n      def reindex_all\n        drop_collection!\n        ensure_collection!\n\n        index_talk_kinds\n        index_event_kinds\n\n        Rails.logger.info \"Typesense: Indexed all kinds\"\n      end\n\n      def drop_collection!\n        collection.delete\n      rescue ::Typesense::Error::ObjectNotFound\n        # Collection doesn't exist, nothing to delete\n      end\n\n      def index_talk_kinds\n        documents = build_talk_kind_documents\n        return if documents.empty?\n\n        collection.documents.import(documents, action: \"upsert\")\n        Rails.logger.info \"Typesense: Indexed #{documents.size} talk kinds\"\n      end\n\n      def index_event_kinds\n        documents = build_event_kind_documents\n        return if documents.empty?\n\n        collection.documents.import(documents, action: \"upsert\")\n        Rails.logger.info \"Typesense: Indexed #{documents.size} event kinds\"\n      end\n\n      def search(query, category: nil, limit: 10)\n        ensure_collection!\n\n        search_params = {\n          q: query.presence || \"*\",\n          query_by: \"name,slug\",\n          per_page: limit,\n          sort_by: \"_text_match:desc,count:desc\"\n        }\n\n        search_params[:filter_by] = \"category:=#{category}\" if category.present?\n\n        result = collection.documents.search(search_params)\n\n        documents = result[\"hits\"].map { |hit| hit[\"document\"].symbolize_keys }\n        total = result[\"found\"]\n\n        [documents, total]\n      end\n\n      private\n\n      def build_talk_kind_documents\n        talk_counts = Talk.group(:kind).count\n\n        TALK_KINDS.map do |slug, data|\n          count = talk_counts[slug] || 0\n\n          {\n            id: \"talk_kind_#{slug}\",\n            slug: slug,\n            name: data[:name],\n            category: \"talk\",\n            icon: data[:icon],\n            count: count\n          }\n        end\n      end\n\n      def build_event_kind_documents\n        event_counts = Event.group(:kind).count\n\n        EVENT_KINDS.map do |slug, data|\n          count = event_counts[slug] || 0\n\n          {\n            id: \"event_kind_#{slug}\",\n            slug: slug,\n            name: data[:name],\n            category: \"event\",\n            icon: data[:icon],\n            count: count\n          }\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/search/backend/typesense/language_indexer.rb",
    "content": "# frozen_string_literal: true\n\nclass Search::Backend::Typesense\n  class LanguageIndexer\n    COLLECTION_NAME = \"languages\"\n\n    class << self\n      def collection_schema\n        {\n          \"name\" => COLLECTION_NAME,\n          \"fields\" => [\n            {\"name\" => \"id\", \"type\" => \"string\"},\n            {\"name\" => \"code\", \"type\" => \"string\"},\n            {\"name\" => \"name\", \"type\" => \"string\"},\n            {\"name\" => \"emoji_flag\", \"type\" => \"string\"},\n            {\"name\" => \"talk_count\", \"type\" => \"int32\"}\n          ],\n          \"default_sorting_field\" => \"talk_count\",\n          \"token_separators\" => [\"-\", \"_\"],\n          \"enable_nested_fields\" => false\n        }\n      end\n\n      def client\n        ::Typesense::Client.new(::Typesense.configuration)\n      end\n\n      def collection\n        client.collections[COLLECTION_NAME]\n      end\n\n      def ensure_collection!\n        collection.retrieve\n      rescue ::Typesense::Error::ObjectNotFound\n        client.collections.create(collection_schema)\n      end\n\n      def reindex_all\n        drop_collection!\n        ensure_collection!\n        create_synonyms!\n        index_languages\n\n        Rails.logger.info \"Typesense: Indexed all languages\"\n      end\n\n      def create_synonyms!\n        synonyms = Language.all_synonyms\n\n        synonyms.each do |id, config|\n          collection.synonyms.upsert(id, config)\n        end\n\n        Rails.logger.info \"Typesense: Created #{synonyms.size} language synonyms\"\n      rescue => e\n        Rails.logger.warn \"Typesense: Failed to create language synonyms: #{e.message}\"\n      end\n\n      def drop_collection!\n        collection.delete\n      rescue ::Typesense::Error::ObjectNotFound\n        # Collection doesn't exist, nothing to delete\n      end\n\n      def index_languages\n        documents = build_language_documents\n        return if documents.empty?\n\n        collection.documents.import(documents, action: \"upsert\")\n        Rails.logger.info \"Typesense: Indexed #{documents.size} languages\"\n      end\n\n      def search(query, limit: 10)\n        ensure_collection!\n\n        search_params = {\n          q: query.presence || \"*\",\n          query_by: \"name,code\",\n          per_page: limit,\n          sort_by: \"_text_match:desc,talk_count:desc\"\n        }\n\n        result = collection.documents.search(search_params)\n\n        documents = result[\"hits\"].map { |hit| hit[\"document\"].symbolize_keys }\n        total = result[\"found\"]\n\n        [documents, total]\n      end\n\n      private\n\n      def build_language_documents\n        languages_with_talks.map do |language_code, talk_count|\n          language_name = Language.by_code(language_code)\n          next unless language_name\n\n          {\n            id: \"language_#{language_code}\",\n            code: language_code,\n            name: language_name,\n            emoji_flag: Language.emoji_flag(language_code),\n            talk_count: talk_count\n          }\n        end.compact\n      end\n\n      def languages_with_talks\n        @languages_with_talks ||= Talk.where.not(language: [nil, \"\"])\n          .group(:language)\n          .count\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/search/backend/typesense/location_indexer.rb",
    "content": "# frozen_string_literal: true\n\nclass Search::Backend::Typesense\n  class LocationIndexer\n    COLLECTION_NAME = \"locations\"\n\n    class << self\n      def collection_schema\n        {\n          \"name\" => COLLECTION_NAME,\n          \"fields\" => [\n            {\"name\" => \"id\", \"type\" => \"string\"},\n            {\"name\" => \"type\", \"type\" => \"string\", \"facet\" => true},\n            {\"name\" => \"name\", \"type\" => \"string\"},\n            {\"name\" => \"slug\", \"type\" => \"string\"},\n            {\"name\" => \"code\", \"type\" => \"string\", \"optional\" => true},\n            {\"name\" => \"country_code\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n            {\"name\" => \"country_name\", \"type\" => \"string\", \"optional\" => true},\n            {\"name\" => \"continent\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n            {\"name\" => \"emoji_flag\", \"type\" => \"string\", \"optional\" => true},\n            {\"name\" => \"event_count\", \"type\" => \"int32\"},\n            {\"name\" => \"user_count\", \"type\" => \"int32\", \"optional\" => true},\n            {\"name\" => \"coordinates\", \"type\" => \"geopoint\", \"optional\" => true}\n          ],\n          \"default_sorting_field\" => \"event_count\",\n          \"token_separators\" => [\"-\", \"_\"],\n          \"enable_nested_fields\" => false\n        }\n      end\n\n      def client\n        ::Typesense::Client.new(::Typesense.configuration)\n      end\n\n      def collection\n        client.collections[COLLECTION_NAME]\n      end\n\n      def ensure_collection!\n        collection.retrieve\n      rescue ::Typesense::Error::ObjectNotFound\n        client.collections.create(collection_schema)\n      end\n\n      def reindex_all\n        drop_collection!\n        ensure_collection!\n        create_synonyms!\n\n        index_online\n        index_continents\n        index_countries\n        index_states\n        index_uk_nations\n        index_cities\n\n        Rails.logger.info \"Typesense: Indexed all locations\"\n      end\n\n      def create_synonyms!\n        all_synonyms = city_synonyms.merge(online_synonyms)\n\n        all_synonyms.each do |id, config|\n          collection.synonyms.upsert(id, config)\n        end\n\n        Rails.logger.info \"Typesense: Created #{all_synonyms.size} location synonyms\"\n      rescue => e\n        Rails.logger.warn \"Typesense: Failed to create synonyms: #{e.message}\"\n      end\n\n      def city_synonyms\n        Static::City.all.each_with_object({}) do |city, synonyms|\n          next if city.aliases.blank?\n\n          all_names = [city.name.downcase, city.slug] + Array(city.aliases).map(&:downcase)\n          synonyms[\"#{city.slug}-synonym\"] = {\"synonyms\" => all_names.uniq}\n        end\n      end\n\n      def online_synonyms\n        {\n          \"online-synonym\" => {\n            \"synonyms\" => %w[online virtual remote]\n          }\n        }\n      end\n\n      def drop_collection!\n        collection.delete\n      rescue ::Typesense::Error::ObjectNotFound\n        # Collection doesn't exist, nothing to delete\n      end\n\n      def index_continents = index_documents(\"continents\", build_continent_documents)\n      def index_countries = index_documents(\"countries\", build_country_documents)\n      def index_states = index_documents(\"states\", build_state_documents)\n      def index_uk_nations = index_documents(\"UK nations\", build_uk_nation_documents)\n      def index_cities = index_documents(\"cities\", build_city_documents)\n      def index_online = index_documents(\"online location\", [build_online_document].compact)\n\n      def index_city(city)\n        ensure_collection!\n        document = build_city_document(city)\n        return unless document\n\n        collection.documents.upsert(document)\n        Rails.logger.info \"Typesense: Indexed city #{city.name}\"\n      rescue => e\n        Rails.logger.error \"Typesense: Failed to index city #{city.name}: #{e.message}\"\n      end\n\n      def remove_city(city)\n        document_id = \"city_#{city.country_code}_#{city.slug}\"\n        collection.documents[document_id].delete\n        Rails.logger.info \"Typesense: Removed city #{city.name}\"\n      rescue ::Typesense::Error::ObjectNotFound\n        # Already removed\n      rescue => e\n        Rails.logger.error \"Typesense: Failed to remove city #{city.name}: #{e.message}\"\n      end\n\n      def index_documents(name, documents)\n        return if documents.empty?\n\n        collection.documents.import(documents, action: \"upsert\")\n        Rails.logger.info \"Typesense: Indexed #{documents.size} #{name}\"\n      end\n\n      def search(query, type: nil, limit: 10)\n        ensure_collection!\n\n        search_params = {\n          q: query.presence || \"*\",\n          query_by: \"name,slug,code,country_name\",\n          per_page: limit,\n          sort_by: \"_text_match:desc,event_count:desc\"\n        }\n\n        search_params[:filter_by] = \"type:=#{type}\" if type.present?\n\n        result = collection.documents.search(search_params)\n\n        documents = result[\"hits\"].map { |hit| hit[\"document\"].symbolize_keys }\n        total = result[\"found\"]\n\n        [documents, total]\n      end\n\n      private\n\n      def build_online_document\n        event_count = Event.not_geocoded.count\n\n        return nil if event_count.zero?\n\n        {\n          id: \"online\",\n          type: \"online\",\n          name: \"Online\",\n          slug: \"online\",\n          emoji_flag: \"🌐\",\n          event_count: event_count\n        }\n      end\n\n      def build_continent_documents\n        continent_counts = Hash.new(0)\n\n        countries_with_events.each do |country_code, event_count|\n          country = Country.find_by(country_code: country_code)\n          next unless country\n\n          continent = country.continent\n          next unless continent\n\n          continent_counts[continent.slug] += event_count\n        end\n\n        continent_counts.map do |slug, event_count|\n          continent = Continent.find(slug)\n          next unless continent\n\n          {\n            id: \"continent_#{slug}\",\n            type: \"continent\",\n            name: continent.name,\n            slug: continent.slug,\n            emoji_flag: continent.emoji_flag,\n            event_count: event_count,\n            coordinates: normalize_coordinates(continent.respond_to?(:to_coordinates) ? continent.to_coordinates : nil)\n          }.compact\n        end.compact\n      end\n\n      def build_country_documents\n        countries_with_events.map do |country_code, event_count|\n          country = Country.find_by(country_code: country_code)\n          next unless country\n\n          country_name = country.common_name || country.iso_short_name\n\n          {\n            id: \"country_#{country_code}\",\n            type: \"country\",\n            name: country_name,\n            slug: country.slug,\n            code: country_code,\n            country_code: country_code,\n            continent: country.continent_name,\n            emoji_flag: country.emoji_flag,\n            event_count: event_count,\n            coordinates: normalize_coordinates(country.respond_to?(:to_coordinates) ? country.to_coordinates : nil)\n          }.compact\n        end.compact\n      end\n\n      def build_state_documents\n        documents = []\n        event_counts = states_with_events\n        user_counts = states_with_users\n\n        State::SUPPORTED_COUNTRIES.each do |country_code|\n          country = Country.find_by(country_code: country_code)\n          next unless country\n          next if country_code == \"GB\" # UK nations handled separately\n\n          State.for_country(country).each do |state|\n            event_count = event_counts[[country_code, state.code]] || 0\n            user_count = user_counts[[country_code, state.code]] || 0\n\n            next if event_count.zero? && user_count.zero?\n\n            documents << {\n              id: \"state_#{country_code}_#{state.code}\",\n              type: \"state\",\n              name: state.name,\n              slug: state.slug,\n              code: state.code,\n              country_code: country_code,\n              country_name: country.common_name || country.iso_short_name,\n              emoji_flag: country.emoji_flag,\n              event_count: event_count,\n              user_count: user_count,\n              coordinates: coordinates_for_state(country_code, state.code)\n            }.compact\n          end\n        end\n\n        documents\n      end\n\n      def build_uk_nation_documents\n        Country::UK_NATIONS.keys.map do |slug|\n          nation = UKNation.new(slug)\n\n          {\n            id: \"uk_nation_#{nation.state_code}\",\n            type: \"uk_nation\",\n            name: nation.name,\n            slug: slug,\n            code: nation.state_code,\n            country_code: \"GB\",\n            country_name: \"United Kingdom\",\n            emoji_flag: nation.emoji_flag,\n            event_count: nation.events.count,\n            user_count: nation.users.count,\n            coordinates: coordinates_for_location(nation.events)\n          }.compact\n        end\n      end\n\n      def build_city_documents\n        City.all.map { |city| build_city_document(city) }\n      end\n\n      def build_city_document(city)\n        country = city.country\n        country_name = country&.common_name || country&.iso_short_name || city.country_code\n\n        {\n          id: \"city_#{city.country_code}_#{city.slug}\",\n          type: \"city\",\n          name: city.name,\n          slug: city.slug,\n          code: city.state_code,\n          country_code: city.country_code,\n          country_name: country_name,\n          emoji_flag: country&.emoji_flag,\n          event_count: city.events_count,\n          user_count: city.users_count,\n          coordinates: normalize_coordinates(city.coordinates)\n        }.compact\n      end\n\n      def normalize_coordinates(coords)\n        return nil if coords.blank?\n        return nil unless coords.is_a?(Array) && coords.size == 2\n\n        [coords[0].to_f, coords[1].to_f]\n      end\n\n      def countries_with_events\n        @countries_with_events ||= Event.where.not(country_code: [nil, \"\"])\n          .group(:country_code)\n          .count\n      end\n\n      def states_with_events\n        @states_with_events ||= Event\n          .where.not(state_code: [nil, \"\"])\n          .where.not(country_code: [nil, \"\"])\n          .where(country_code: State::SUPPORTED_COUNTRIES)\n          .group(:country_code, :state_code)\n          .count\n      end\n\n      def states_with_users\n        @states_with_users ||= User.indexable.geocoded\n          .where.not(state_code: [nil, \"\"])\n          .where.not(country_code: [nil, \"\"])\n          .where(country_code: State::SUPPORTED_COUNTRIES)\n          .group(:country_code, :state_code)\n          .count\n      end\n\n      def coordinates_for_state(country_code, state_code)\n        coordinates_for_location(Event.where(country_code: country_code, state_code: state_code))\n      end\n\n      def coordinates_for_location(events_scope)\n        event = events_scope.geocoded.first\n        return normalize_coordinates(event.to_coordinates) if event\n\n        nil\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/search/backend/typesense.rb",
    "content": "# frozen_string_literal: true\n\nclass Search::Backend::Typesense\n  HEALTH_CHECK_TIMEOUT = 1.second\n  CIRCUIT_BREAKER_TTL = Rails.env.production? ? 5.minutes : 10.seconds\n\n  class << self\n    def search_talks(query, limit:, **options)\n      search_options = {per_page: limit}.merge(options)\n      pagy, talks = Talk.typesense_search_talks(query, search_options)\n\n      [talks, pagy.count]\n    end\n\n    def search_talks_with_pagy(query, pagy_backend: nil, **options)\n      Talk.typesense_search_talks(query, options)\n    end\n\n    def search_speakers(query, limit:)\n      pagy, speakers = User.typesense_search_speakers(query, per_page: limit)\n\n      [speakers, pagy.count]\n    end\n\n    def search_events(query, limit:)\n      pagy, events = Event.typesense_search_events(query, per_page: limit)\n\n      [events, pagy.count]\n    end\n\n    def search_topics(query, limit:)\n      pagy, topics = Topic.typesense_search_topics(query, per_page: limit)\n\n      [topics, pagy.count]\n    end\n\n    def search_series(query, limit:)\n      pagy, series = EventSeries.typesense_search_series(query, per_page: limit)\n\n      [series, pagy.count]\n    end\n\n    def search_organizations(query, limit:)\n      pagy, organizations = Organization.typesense_search_organizations(query, per_page: limit)\n\n      [organizations, pagy.count]\n    end\n\n    def search_languages(query, limit:)\n      perform_search(:language, query) do\n        LanguageIndexer.search(query, limit: limit)\n      end\n    end\n\n    def search_locations(query, limit:)\n      perform_search(:location, query) do\n        LocationIndexer.search(query, limit: limit)\n      end\n    end\n\n    def search_continents(query, limit:)\n      perform_search(:continent, query) do\n        LocationIndexer.search(query, type: \"continent\", limit: limit)\n      end\n    end\n\n    def search_countries(query, limit:)\n      perform_search(:country, query) do\n        LocationIndexer.search(query, type: \"country\", limit: limit)\n      end\n    end\n\n    def search_states(query, limit:)\n      perform_search(:state, query) do\n        LocationIndexer.search(query, type: \"state\", limit: limit)\n      end\n    end\n\n    def search_cities(query, limit:)\n      perform_search(:city, query) do\n        LocationIndexer.search(query, type: \"city\", limit: limit)\n      end\n    end\n\n    def search_kinds(query, limit:)\n      perform_search(:kind, query) do\n        KindIndexer.search(query, limit: limit)\n      end\n    end\n\n    def available?\n      return false if Rails.env.test?\n\n      circuit_breaker.call do\n        Timeout.timeout(HEALTH_CHECK_TIMEOUT) do\n          ::Typesense.client.health.retrieve.present?\n        end\n      end\n    end\n\n    def name\n      :typesense\n    end\n\n    def indexer\n      Indexer\n    end\n\n    private\n\n    def perform_search(type, query)\n      return [[], 0] if query.blank?\n\n      yield\n    rescue ::Typesense::Error, Faraday::Error => e\n      Rails.logger.warn(\"Typesense #{type} search failed: #{e.message}\")\n\n      [[], 0]\n    end\n\n    def circuit_breaker\n      @circuit_breaker ||= CircuitBreaker.new(ttl: CIRCUIT_BREAKER_TTL)\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/search/backend.rb",
    "content": "# frozen_string_literal: true\n\nmodule Search::Backend\n  mattr_accessor :skip_indexing, default: false\n\n  class << self\n    attr_writer :default_backend_key\n\n    def without_indexing(&block)\n      original = skip_indexing\n      self.skip_indexing = true\n      yield\n    ensure\n      self.skip_indexing = original\n    end\n\n    def backends\n      @backends ||= {\n        sqlite_fts: Search::Backend::SQLiteFTS,\n        typesense: Search::Backend::Typesense\n      }.freeze\n    end\n\n    def available_backends\n      backends.select { |_key, klass| klass.available? }.keys\n    end\n\n    def resolve(preferred = nil)\n      if preferred && backends.key?(preferred.to_sym)\n        backend = backends[preferred.to_sym]\n        return backend if backend.available?\n      end\n\n      default_backend\n    end\n\n    def default_backend\n      resolve(default_backend_key)\n    end\n\n    def default_backend_key\n      return @default_backend_key if @default_backend_key\n\n      if Search::Backend::Typesense.available?\n        :typesense\n      else\n        :sqlite_fts\n      end\n    end\n\n    def index(record)\n      return if skip_indexing\n\n      backends.each_value do |backend|\n        backend.indexer.index(record) if backend.available?\n      rescue => e\n        Rails.logger.error(\"Failed to index #{record.class}##{record.id} in #{backend.name}: #{e.message}\")\n      end\n    end\n\n    def remove(record)\n      backends.each_value do |backend|\n        backend.indexer.remove(record) if backend.available?\n      rescue => e\n        Rails.logger.error(\"Failed to remove #{record.class}##{record.id} from #{backend.name}: #{e.message}\")\n      end\n    end\n\n    def reindex_all\n      backends.each_value do |backend|\n        backend.indexer.reindex_all if backend.available?\n      rescue => e\n        Rails.logger.error(\"Failed to reindex all in #{backend.name}: #{e.message}\")\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/session.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: sessions\n# Database name: primary\n#\n#  id         :integer          not null, primary key\n#  ip_address :string\n#  user_agent :string\n#  created_at :datetime         not null\n#  updated_at :datetime         not null\n#  user_id    :integer          not null, indexed\n#\n# Indexes\n#\n#  index_sessions_on_user_id  (user_id)\n#\n# Foreign Keys\n#\n#  user_id  (user_id => users.id)\n#\n# rubocop:enable Layout/LineLength\nclass Session < ApplicationRecord\n  belongs_to :user, inverse_of: :sessions\n\n  before_create do\n    self.user_agent = Current.user_agent\n    self.ip_address = Current.ip_address\n  end\n\n  def sign_out_siblings!\n    user.sessions.without(self).delete_all\n  end\nend\n"
  },
  {
    "path": "app/models/speaker.rb",
    "content": "# == Schema Information\n#\n# Table name: speakers\n# Database name: primary\n#\n#  id              :integer          not null, primary key\n#  bio             :text             default(\"\"), not null\n#  bsky            :string           default(\"\"), not null\n#  bsky_metadata   :json             not null\n#  github          :string           default(\"\"), not null, uniquely indexed\n#  github_metadata :json             not null\n#  linkedin        :string           default(\"\"), not null\n#  mastodon        :string           default(\"\"), not null\n#  name            :string           default(\"\"), not null, indexed\n#  pronouns        :string           default(\"\"), not null\n#  pronouns_type   :string           default(\"not_specified\"), not null\n#  slug            :string           default(\"\"), not null, uniquely indexed\n#  speakerdeck     :string           default(\"\"), not null\n#  talks_count     :integer          default(0), not null\n#  twitter         :string           default(\"\"), not null\n#  website         :string           default(\"\"), not null\n#  created_at      :datetime         not null\n#  updated_at      :datetime         not null\n#  canonical_id    :integer          indexed\n#\n# Indexes\n#\n#  index_speakers_on_canonical_id  (canonical_id)\n#  index_speakers_on_github        (github) UNIQUE WHERE github IS NOT NULL AND github != ''\n#  index_speakers_on_name          (name)\n#  index_speakers_on_slug          (slug) UNIQUE\n#\n# Foreign Keys\n#\n#  canonical_id  (canonical_id => speakers.id)\n#\n# This is a legacy model that should be removed\nclass Speaker < ApplicationRecord\n  def title\n    name\n  end\nend\n"
  },
  {
    "path": "app/models/sponsor.rb",
    "content": "# == Schema Information\n#\n# Table name: sponsors\n# Database name: primary\n#\n#  id              :integer          not null, primary key\n#  badge           :string\n#  level           :integer\n#  tier            :string           uniquely indexed => [event_id, organization_id]\n#  created_at      :datetime         not null\n#  updated_at      :datetime         not null\n#  event_id        :integer          not null, indexed, uniquely indexed => [organization_id, tier]\n#  organization_id :integer          not null, uniquely indexed => [event_id, tier], indexed\n#\n# Indexes\n#\n#  index_sponsors_on_event_id                        (event_id)\n#  index_sponsors_on_event_organization_tier_unique  (event_id,organization_id,tier) UNIQUE\n#  index_sponsors_on_organization_id                 (organization_id)\n#\n# Foreign Keys\n#\n#  event_id         (event_id => events.id)\n#  organization_id  (organization_id => organizations.id)\n#\nclass Sponsor < ApplicationRecord\n  belongs_to :event\n  belongs_to :organization\n\n  validates :organization_id, uniqueness: {scope: [:event_id, :tier], message: \"is already associated with this event for the same tier\"}\n\n  before_validation :normalize_tier\n\n  private\n\n  def normalize_tier\n    self.tier = nil if tier.blank?\n  end\nend\n"
  },
  {
    "path": "app/models/stamp.rb",
    "content": "class Stamp\n  include ActiveModel::Model\n  include ActiveModel::Attributes\n\n  attribute :code, :string\n  attribute :name, :string\n  attribute :file_path, :string\n  attribute :country\n  attribute :has_country, :boolean, default: false\n  attribute :has_event, :boolean, default: false\n  attribute :event\n  attribute :event_slug, :string\n\n  class << self\n    def all\n      @all_stamps ||= load_stamps_from_filesystem\n    end\n\n    def country_stamps\n      @country_stamps ||= all.select(&:has_country?)\n    end\n\n    def event_stamps\n      @event_stamps ||= all.select(&:has_event?)\n    end\n\n    def contributor_stamp\n      @contributor_stamp ||= all.find { |s| s.code == \"RUBYEVENTS-CONTRIBUTOR\" }\n    end\n\n    def passport_stamp\n      @passport_stamp ||= all.find { |s| s.code == \"RUBY-PASSPORT\" }\n    end\n\n    def triathlon_2025_stamp\n      @triathlon_2025_stamp ||= all.find { |s| s.code == \"RUBY-TRIATHLON-2025\" }\n    end\n\n    def conference_speaker_stamp\n      @conference_speaker_stamp ||= all.find { |s| s.code == \"SPEAK-AT-A-CONFERENCE\" }\n    end\n\n    def meetup_speaker_stamp\n      @meetup_speaker_stamp ||= all.find { |s| s.code == \"SPEAK-AT-A-MEETUP\" }\n    end\n\n    def attend_one_event_stamp\n      @attend_one_event_stamp ||= all.find { |s| s.code == \"ATTEND-ONE-EVENT\" }\n    end\n\n    def ruby_30th_anniversary\n      @ruby_30th_anniversary ||= all.find { |s| s.code == \"RUBY-30TH-ANNIVERSARY\" }\n    end\n\n    def online_stamp\n      @online_stamp ||= all.find { |s| s.code == \"ONLINE\" }\n    end\n\n    def for(country_code: nil, state_code: nil, events: nil)\n      if events\n        stamps = []\n\n        events.each do |event|\n          next unless event.country\n\n          country_stamp = country_stamps.find { |s| s.code == event.country_code }\n          stamps << country_stamp if country_stamp\n\n          if event.country_code == \"GB\" && event.state_code.present?\n            uk_nation = UKNation.find_by_code(event.state_code)\n            stamps.concat(uk_nation.stamps) if uk_nation\n          end\n        end\n\n        return stamps.uniq { |s| s.code }\n      end\n\n      stamps = []\n      country_stamp = country_stamps.find { |s| s.code == country_code }\n      stamps << country_stamp if country_stamp\n\n      if country_code == \"GB\" && state_code.present?\n        uk_nation = UKNation.find_by_code(state_code)\n        stamps.concat(uk_nation.stamps) if uk_nation\n      end\n\n      stamps\n    end\n\n    def for_user(user)\n      user_events = user.participated_events\n      stamps = self.for(events: user_events).to_a\n\n      event_stamps_for_user = user_events.flat_map { |event| for_event(event) }\n      stamps = (stamps + event_stamps_for_user).uniq { |stamp| stamp.code }\n\n      if user.contributor? && contributor_stamp\n        stamps << contributor_stamp\n      end\n\n      if user.ruby_passport_claimed? && passport_stamp\n        stamps << passport_stamp\n      end\n\n      if user_attended_triathlon_2025?(user) && triathlon_2025_stamp\n        stamps << triathlon_2025_stamp\n      end\n\n      if user_spoke_at_conference?(user) && conference_speaker_stamp\n        stamps << conference_speaker_stamp\n      end\n\n      if user_spoke_at_meetup?(user) && meetup_speaker_stamp\n        stamps << meetup_speaker_stamp\n      end\n\n      if user_attended_conference?(user) && attend_one_event_stamp\n        stamps << attend_one_event_stamp\n      end\n\n      if user_attended_online_event?(user) && online_stamp\n        stamps << online_stamp\n      end\n\n      stamps\n    end\n\n    def for_event(event)\n      return [] unless event&.slug\n\n      prefix = \"#{event.event_image_path}/\"\n\n      event_stamps.select { |stamp|\n        (stamp.event_slug.present? && stamp.event_slug == event.slug) ||\n          stamp.file_path.start_with?(prefix)\n      }\n    end\n\n    def user_attended_triathlon_2025?(user)\n      required_event_slugs = [\"rails-world-2025\", \"friendly-rb-2025\", \"euruko-2025\"]\n      attended_event_slugs = user.participated_events.pluck(:slug)\n\n      required_event_slugs.all? { |slug| attended_event_slugs.include?(slug) }\n    end\n\n    def user_spoke_at_conference?(user)\n      user.speaker_events.where(kind: :conference).exists?\n    end\n\n    def user_spoke_at_meetup?(user)\n      user.speaker_events.where(kind: :meetup).exists?\n    end\n\n    def user_attended_conference?(user)\n      user.participated_events.where(kind: :conference).exists?\n    end\n\n    def user_attended_online_event?(user)\n      user.participated_events.any? { |event| event.location == \"Online\" }\n    end\n\n    def grouped_by_continent\n      stamps_by_continent = all.select(&:has_country?).group_by { |stamp| stamp.country&.continent_name }\n      custom_stamps = all.reject(&:has_country?).reject(&:has_event?)\n\n      stamps_by_continent[\"Custom\"] = custom_stamps if custom_stamps.any?\n\n      stamps_by_continent\n    end\n\n    def missing_for_events\n      event_countries = Event.all.map(&:country).compact.uniq\n      stamp_countries = all.select(&:has_country?).map(&:country).compact.uniq\n      gb_country = Country.find_by(country_code: \"GB\")\n\n      event_countries.reject { |event_country|\n        stamp_countries.any? { |sc| sc.alpha2 == event_country.alpha2 } ||\n          (event_country.alpha2 == gb_country&.alpha2 && uk_subdivisions_covered?)\n      }.sort_by(&:name)\n    end\n  end\n\n  def asset_path\n    relative_path = file_path.to_s\n\n    if relative_path.include?(File::SEPARATOR) || (File::ALT_SEPARATOR && relative_path.include?(File::ALT_SEPARATOR))\n      ActionController::Base.helpers.asset_path(relative_path)\n    else\n      ActionController::Base.helpers.asset_path(\"stamps/#{relative_path}\")\n    end\n  end\n\n  def has_country?\n    has_country\n  end\n\n  def has_event?\n    has_event\n  end\n\n  def event\n    return @event if defined?(@event)\n\n    @event = Event.find_by(slug: event_slug) if event_slug.present?\n  end\n\n  def self.load_stamps_from_filesystem\n    images_directory = Rails.root.join(\"app\", \"assets\", \"images\")\n    stamps_directory = images_directory.join(\"stamps\")\n\n    static_stamps =\n      if File.directory?(stamps_directory)\n        Dir.glob(stamps_directory.join(\"*.webp\")).map { |file| File.basename(file, \".webp\") }\n      else\n        []\n      end\n\n    event_stamp_files = Dir.glob(images_directory.join(\"events\", \"**\", \"stamp*.webp\"))\n\n    (static_stamps.map { |stamp_code| create_stamp_from_code(stamp_code) } +\n      event_stamp_files.map { |file| create_stamp_from_event_file(file, images_directory) })\n      .compact\n      .uniq { |stamp| stamp.code }\n      .sort_by(&:name)\n  end\n\n  def self.create_stamp_from_code(stamp_code)\n    stamp_upper = stamp_code.upcase\n    file_path = \"#{stamp_code}.webp\"\n    country = Country.find_by(country_code: stamp_upper)\n    uk_nation = UKNation.find_by_code(stamp_upper) unless country\n\n    if country\n      new(\n        code: stamp_upper,\n        name: country.name,\n        file_path: file_path,\n        country: country,\n        has_country: true\n      )\n    elsif uk_nation\n      new(\n        code: stamp_upper,\n        name: uk_nation.name,\n        file_path: file_path,\n        country: uk_nation,\n        has_country: true\n      )\n    else\n      new(\n        code: stamp_upper,\n        name: stamp_code.titleize,\n        file_path: file_path,\n        country: nil,\n        has_country: false\n      )\n    end\n  end\n\n  def self.create_stamp_from_event_file(file, images_directory)\n    relative_path = Pathname.new(file).relative_path_from(images_directory)\n    path_parts = relative_path.each_filename.to_a\n    event_slug = path_parts[-2]\n    basename = Pathname.new(file).basename(\".webp\").to_s\n\n    return nil unless event_slug.present? && basename.present?\n\n    event = Event.find_by(slug: event_slug)\n\n    variant_suffix = basename.sub(/^stamp[_-]?/i, \"\")\n    code_parts = [event&.slug || event_slug, basename].compact\n    code = code_parts.join(\"-\").upcase\n\n    display_name = event&.name || event_slug.titleize\n    variant_label = variant_suffix.present? ? \"Stamp #{variant_suffix.titleize}\" : \"Stamp\"\n    name = \"#{display_name} (#{variant_label})\"\n\n    new(\n      code: code,\n      name: name,\n      file_path: relative_path.to_s,\n      country: event&.country,\n      has_country: false,\n      has_event: true,\n      event: event,\n      event_slug: event_slug\n    )\n  end\n\n  def self.uk_subdivisions_covered?\n    uk_subdivision_codes = [\"SCT\", \"ENG\", \"NIR\", \"WLS\"]\n\n    all.any? { |stamp| uk_subdivision_codes.include?(stamp.code) }\n  end\nend\n"
  },
  {
    "path": "app/models/state.rb",
    "content": "class State\n  EXCLUDED_COUNTRIES = [\"PL\"]\n  SUPPORTED_COUNTRIES = (Country.all.select { |country| country.subdivisions.any? }.map(&:alpha2) - EXCLUDED_COUNTRIES).freeze\n  UK_NATIONS = %w[ENG SCT WLS NIR].freeze\n\n  attr_reader :country, :record\n\n  def initialize(country:, record:)\n    @country = country\n    @record = record\n  end\n\n  def name\n    record.translations.dig(:en) || record.name\n  end\n\n  def code\n    record.code\n  end\n\n  def slug\n    name.parameterize\n  end\n\n  def abbreviation\n    code\n  end\n\n  def display_name\n    if country.alpha2 == \"GB\" || code.match?(/^\\d+$/)\n      name\n    else\n      abbreviation\n    end\n  end\n\n  def path\n    if country.alpha2 == \"GB\"\n      Router.country_path(slug)\n    else\n      Router.state_path(country.code, slug)\n    end\n  end\n\n  def past_path\n    Router.state_past_index_path(state_alpha2: country.code, state_slug: slug)\n  end\n\n  def users_path\n    Router.state_users_path(state_alpha2: country.code, state_slug: slug)\n  end\n\n  def meetups_path\n    Router.state_meetups_path(state_alpha2: country.code, state_slug: slug)\n  end\n\n  def cities_path\n    Router.state_cities_path(state_alpha2: country.code, state_slug: slug)\n  end\n\n  def stamps_path\n    Router.state_stamps_path(state_alpha2: country.code, state_slug: slug)\n  end\n\n  def map_path\n    Router.state_map_index_path(state_alpha2: country.code, state_slug: slug)\n  end\n\n  def has_routes?\n    true\n  end\n\n  def to_param\n    slug\n  end\n\n  def ==(other)\n    other.is_a?(State) && code == other.code && country.alpha2 == other.country.alpha2\n  end\n\n  def eql?(other)\n    self == other\n  end\n\n  def hash\n    [code, country.alpha2].hash\n  end\n\n  def events\n    Event.where(country_code: country.alpha2, state_code: [code, name])\n  end\n\n  def users\n    User.indexable.geocoded.where(country_code: country.alpha2, state_code: [code, name])\n  end\n\n  def cities\n    City.for_state(self)\n  end\n\n  def stamps\n    state_events = events.to_a\n    Stamp.all.select { |stamp| stamp.has_event? && state_events.include?(stamp.event) }\n  end\n\n  def alpha2\n    country.alpha2\n  end\n\n  def country_code\n    country.alpha2\n  end\n\n  def geocoded?\n    false\n  end\n\n  def bounds\n    nil\n  end\n\n  def to_location\n    Location.new(state_code: code, country_code: country_code, raw_location: \"#{name}, #{country.name}\")\n  end\n\n  class << self\n    def supported_country?(country)\n      return false if country.blank?\n\n      SUPPORTED_COUNTRIES.include?(country.alpha2)\n    end\n\n    def find(country:, term:)\n      return nil if term.blank? || country.blank?\n      return nil unless supported_country?(country)\n\n      term_slug = term.to_s.parameterize\n      term_upper = term.to_s.upcase\n      term_downcase = term.to_s.downcase\n\n      for_country(country).find do |state|\n        state.slug == term_slug ||\n          state.code.upcase == term_upper ||\n          state.name.downcase == term_downcase\n      end\n    end\n\n    def find_by_slug(slug)\n      return nil if slug.blank?\n\n      us_states.find { |state| state.slug == slug.to_s.parameterize }\n    end\n\n    def find_by_code(code, country: nil)\n      return nil if code.blank?\n\n      if country\n        for_country(country).find { |state| state.code.upcase == code.upcase }\n      else\n        SUPPORTED_COUNTRIES.each do |country_code|\n          country = Country.find(country_code)\n          state = for_country(country).find { |s| s.code.upcase == code.upcase }\n\n          return state if state\n        end\n        nil\n      end\n    end\n\n    def find_by_name(name, country: nil)\n      return nil if name.blank?\n\n      if country\n        for_country(country).find { |state| state.name.downcase == name.downcase }\n      else\n        SUPPORTED_COUNTRIES.each do |country_code|\n          country = Country.find(country_code)\n          state = for_country(country).find { |s| s.name.downcase == name.downcase }\n\n          return state if state\n        end\n        nil\n      end\n    end\n\n    def all\n      @all ||= SUPPORTED_COUNTRIES.flat_map { |code| for_country(Country.find(code)) }\n    end\n\n    def for_country(country)\n      return [] if country.blank?\n\n      country.subdivisions.map { |_, record|\n        new(country: country, record: record)\n      }\n    end\n\n    def select_options(country: nil)\n      for_country(country).map { |state| [state.name, state.code] }\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/static/backends/array_backend.rb",
    "content": "module Static::Backends\n  class ArrayBackend < FileBackend\n    def load(...)\n      super.map { |item| {\"item\" => item} }\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/static/backends/file_backend.rb",
    "content": "module Static::Backends\n  class FileBackend\n    def initialize(file_path, backend: FrozenRecord::Backends::Yaml)\n      @file_path = file_path\n      @backend = backend\n    end\n\n    def filename(_model_name = nil)\n      @file_path\n    end\n\n    def load(file_path = @file_path)\n      @backend.load(file_path)\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/static/backends/multi_file_backend.rb",
    "content": "module Static::Backends\n  class MultiFileBackend\n    def initialize(glob, backend: FrozenRecord::Backends::Yaml)\n      @glob = glob\n      @backend = backend\n    end\n\n    def filename(_model_name = nil)\n      @glob\n    end\n\n    def load(file_path = @glob)\n      Dir.glob(file_path).flat_map { |file|\n        begin\n          data = @backend.load(file)\n          items = data.is_a?(Array) ? data : [data]\n\n          items.map { |item|\n            {\n              **item,\n              \"__file_path\" => Pathname.new(file).relative_path_from(Rails.root).to_s\n            }.freeze\n          }\n        rescue Psych::SyntaxError => e\n          puts \"#{e.message} in #{file}\"\n          raise e\n        end\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/static/city.rb",
    "content": "# frozen_string_literal: true\n\nmodule Static\n  class City < FrozenRecord::Base\n    self.backend = Backends::FileBackend.new(\"featured_cities.yml\")\n    self.base_path = Rails.root.join(\"data\")\n\n    SEARCH_INDEX_ON_IMPORT_DEFAULT = ENV.fetch(\"SEARCH_INDEX_ON_IMPORT\", \"true\") == \"true\"\n\n    def self.import_all!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      all.map { |city| city.import!(index: index) }\n    end\n\n    def import!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      city_record = ::City.find_by(slug: slug)\n      city_record ||= ::City.find_by(name: name, state_code: state_code, country_code: country_code)\n      city_record ||= find_by_yaml_aliases\n      city_record ||= ::City.new\n\n      city_record.assign_attributes(\n        name: name,\n        state_code: state_code,\n        country_code: country_code,\n        latitude: latitude,\n        longitude: longitude,\n        featured: true,\n        slug: slug\n      )\n\n      begin\n        city_record.save!\n      rescue ActiveRecord::RecordInvalid => e\n        Rails.logger.error(\"Failed to import city #{name} (#{slug}): #{e.message}\")\n        raise e\n      end\n\n      city_record.sync_aliases_from_list(aliases) if aliases.present?\n\n      Search::Backend.index(city_record) if index\n\n      city_record\n    end\n\n    private\n\n    def find_by_yaml_aliases\n      return nil if aliases.blank?\n\n      aliases.each do |alias_name|\n        city = ::City.where(country_code: country_code).where(\"LOWER(name) = ?\", alias_name.downcase).first\n\n        return city if city\n\n        city = ::City.find_by_alias(alias_name, country_code: country_code)\n\n        return city if city\n      end\n\n      nil\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/static/event.rb",
    "content": "module Static\n  class Event < FrozenRecord::Base\n    include ActionView::Helpers::DateHelper\n\n    self.backend = Backends::MultiFileBackend.new(\"**/**/event.yml\")\n    self.base_path = Rails.root.join(\"data\")\n\n    SEARCH_INDEX_ON_IMPORT_DEFAULT = ENV.fetch(\"SEARCH_INDEX_ON_IMPORT\", \"true\") == \"true\"\n\n    class << self\n      def find_by_slug(slug)\n        @slug_index ||= all.index_by(&:slug)\n        @slug_index[slug]\n      end\n\n      def import_all!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n        all.each { |event| event.import!(index: index) }\n      end\n\n      def import_meetups!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n        all.select { |event| event.meetup? }.each { |event| event.import!(index: index) }\n      end\n\n      def import_recent!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n        import_cutoff = 6.months.ago\n        all.select { |event| event.end_date && event.end_date >= import_cutoff }.each { |event| event.import!(index: index) }\n      end\n\n      def create(\n        series_slug:,\n        title:,\n        kind:,\n        id: nil,\n        slug: nil,\n        description: nil,\n        aliases: nil,\n        hybrid: nil,\n        status: nil,\n        last_edition: nil,\n        start_date: nil,\n        end_date: nil,\n        published_at: nil,\n        announced_on: nil,\n        year: nil,\n        date_precision: nil,\n        frequency: nil,\n        location: nil,\n        venue: nil,\n        channel_id: nil,\n        playlist: nil,\n        website: nil,\n        original_website: nil,\n        twitter: nil,\n        mastodon: nil,\n        github: nil,\n        meetup: nil,\n        luma: nil,\n        youtube: nil,\n        banner_background: nil,\n        featured_background: nil,\n        featured_color: nil\n      )\n        series = Static::EventSeries.find_by_slug(series_slug)\n        raise ArgumentError, \"Event series '#{series_slug}' not found\" unless series\n\n        slug ||= title.parameterize\n\n        series_dir = base_path.join(series_slug)\n        event_dir = series_dir.join(slug)\n        event_file = event_dir.join(\"event.yml\")\n\n        if event_file.exist?\n          raise ArgumentError, \"Event '#{slug}' already exists at #{event_file}\"\n        end\n\n        data = {\"title\" => title, \"kind\" => kind}\n\n        data[\"id\"] = id if id.present?\n        data[\"description\"] = description if description.present?\n        data[\"aliases\"] = Array(aliases) if aliases.present?\n        data[\"hybrid\"] = hybrid unless hybrid.nil?\n        data[\"status\"] = status if status.present?\n        data[\"last_edition\"] = last_edition unless last_edition.nil?\n        data[\"start_date\"] = start_date if start_date.present?\n        data[\"end_date\"] = end_date if end_date.present?\n        data[\"published_at\"] = published_at if published_at.present?\n        data[\"announced_on\"] = announced_on if announced_on.present?\n        data[\"year\"] = year if year.present?\n        data[\"date_precision\"] = date_precision if date_precision.present?\n        data[\"frequency\"] = frequency if frequency.present?\n        data[\"location\"] = location if location.present?\n        data[\"venue\"] = venue if venue.present?\n        data[\"channel_id\"] = channel_id if channel_id.present?\n        data[\"playlist\"] = playlist if playlist.present?\n        data[\"website\"] = website if website.present?\n        data[\"original_website\"] = original_website if original_website.present?\n        data[\"twitter\"] = twitter if twitter.present?\n        data[\"mastodon\"] = mastodon if mastodon.present?\n        data[\"github\"] = github if github.present?\n        data[\"meetup\"] = meetup if meetup.present?\n        data[\"luma\"] = luma if luma.present?\n        data[\"youtube\"] = youtube if youtube.present?\n        data[\"banner_background\"] = banner_background if banner_background.present?\n        data[\"featured_background\"] = featured_background if featured_background.present?\n        data[\"featured_color\"] = featured_color if featured_color.present?\n\n        schema = JSON.parse(EventSchema.new.to_json_schema[:schema].to_json)\n        schemer = JSONSchemer.schema(schema)\n        errors = schemer.validate(data).to_a\n\n        if errors.any?\n          error_messages = errors.map { |e| \"#{e[\"error\"]} at #{e[\"data_pointer\"]}\" }\n          raise ArgumentError, \"Validation failed: #{error_messages.join(\", \")}\"\n        end\n\n        FileUtils.mkdir_p(event_dir)\n        File.write(event_file, data.to_yaml)\n\n        videos_file = event_dir.join(\"videos.yml\")\n        File.write(videos_file, \"[]\\n\") unless videos_file.exist?\n\n        @slug_index = nil\n        unload!\n\n        find_by_slug(slug)\n      end\n    end\n\n    def featured?\n      within_next_days? || today? || past?\n    end\n\n    def today?\n      if start_date.present?\n        return start_date.today?\n      end\n\n      if end_date.present?\n        return end_date.today?\n      end\n\n      if event_record.present? && event_record.start_date\n        return event_record.start_date.today?\n      end\n\n      if event_record.present? && event_record.end_date\n        return event_record.end_date.today?\n      end\n\n      false\n    end\n\n    def within_next_days?\n      period = 4.days\n\n      if end_date.present?\n        return ((end_date - period)..end_date).cover?(Date.today)\n      end\n\n      if start_date.present?\n        return ((start_date - period)..start_date).cover?(Date.today)\n      end\n\n      if event_record.present? && event_record.start_date\n        return ((event_record.start_date - period)..event_record.start_date).cover?(Date.today)\n      end\n\n      if event_record.present? && event_record.end_date\n        return ((event_record.end_date - period)..event_record.end_date).cover?(Date.today)\n      end\n\n      false\n    end\n\n    def past?\n      if end_date.present?\n        end_date.past?\n      elsif event_record.present? && event_record.end_date.present?\n        event_record.end_date.past?\n      else\n        false\n      end\n    end\n\n    def conference?\n      kind == \"conference\"\n    end\n\n    def meetup?\n      kind == \"meetup\"\n    end\n\n    def retreat?\n      kind == \"retreat\"\n    end\n\n    def hackathon?\n      kind == \"hackathon\"\n    end\n\n    def slug\n      @slug ||= begin\n        return attributes[\"slug\"] if attributes[\"slug\"].present?\n\n        File.basename(File.dirname(__file_path))\n      end\n    end\n\n    def imported?\n      ::Event.exists?(slug: slug)\n    end\n\n    def event_record\n      @event_record ||= ::Event.find_by(slug: slug) || import!\n    end\n\n    def start_date\n      Date.parse(super)\n    rescue TypeError, Date::Error\n      super\n    end\n\n    def end_date\n      Date.parse(super)\n    rescue TypeError, Date::Error\n      super\n    end\n\n    def published_date\n      Date.parse(published_at)\n    rescue TypeError, Date::Error\n      nil\n    end\n\n    def country\n      return nil if location.blank?\n\n      Country.find(location.to_s.split(\",\").last&.strip)\n    end\n\n    def city\n      return nil if location.blank?\n\n      parts = location.to_s.split(\",\").map(&:strip)\n      parts.first if parts.size >= 2\n    end\n\n    def home_sort_date(event_record: nil)\n      event_record ||= self.event_record\n\n      if published_date\n        return published_date\n      end\n\n      if conference? && end_date.present?\n        return end_date\n      end\n\n      if meetup? && event_record.present?\n        return event_record.end_date\n      end\n\n      if conference? && start_date.present?\n        return start_date\n      end\n\n      if event_record.present?\n        return event_record.start_date\n      end\n\n      Time.at(0)\n    end\n\n    def static_series\n      @static_series ||= Static::EventSeries.find_by_slug(series_slug)\n    end\n\n    def import!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      return if Rails.env.test? && !ENV[\"SEED_SMOKE_TEST\"] # this method slowdown a lot of the test suite\n\n      event = import_event!\n\n      import_cfps!(event)\n      import_videos!(event, index: index)\n      import_sponsors!(event)\n      import_involvements!(event)\n      import_transcripts!(event)\n\n      Search::Backend.index(event) if index\n\n      event\n    end\n\n    def import_event!\n      event = ::Event.find_or_create_by(slug: slug)\n\n      event.update!(\n        name: title,\n        date: attributes[\"date\"] || published_at,\n        date_precision: date_precision || \"day\",\n        series: static_series.event_series_record,\n        website: website,\n        country_code: country&.alpha2,\n        city: city,\n        location: location,\n        start_date: start_date,\n        end_date: end_date,\n        kind: kind\n      )\n\n      if event.venue.exist?\n        event.update!(\n          latitude: event.venue.latitude,\n          longitude: event.venue.longitude\n        )\n      else\n        event.update!(\n          latitude: coordinates.is_a?(Hash) ? coordinates.dig(\"latitude\") : nil,\n          longitude: coordinates.is_a?(Hash) ? coordinates.dig(\"longitude\") : nil\n        )\n      end\n\n      event.sync_aliases_from_list(aliases) if aliases.present?\n\n      puts event.slug unless Rails.env.test?\n\n      event\n    rescue ActiveRecord::RecordInvalid => e\n      error_location = ActiveSupport::BacktraceCleaner.new.clean_locations(e.backtrace_locations).first\n      puts \"::error file=#{error_location&.path},line=#{error_location&.lineno}::#{e.record.class} (#{e.record&.to_param}) - #{e.detailed_message}\"\n      raise e\n    end\n\n    def import_cfps!(event)\n      cfp_file_path = Rails.root.join(\"data\", series_slug, slug, \"cfp.yml\")\n\n      return unless File.exist?(cfp_file_path)\n\n      cfps = YAML.load_file(cfp_file_path)\n\n      cfps.each do |cfp_data|\n        event.cfps.find_or_create_by(\n          link: cfp_data[\"link\"],\n          open_date: cfp_data[\"open_date\"]\n        ).update(\n          name: cfp_data[\"name\"],\n          close_date: cfp_data[\"close_date\"]\n        )\n      end\n    end\n\n    def import_videos!(event, index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      return unless imported?\n      return unless event.videos_file.exist?\n\n      event.videos_file.entries.each do |talk_data|\n        talk = ::Talk.find_or_initialize_by(static_id: talk_data[\"id\"])\n        talk.update_from_yml_metadata!(event: event)\n        Search::Backend.index(talk) if index\n\n        child_talks = talk_data[\"talks\"]\n\n        next unless child_talks\n\n        Array.wrap(child_talks).each do |child_talk_data|\n          child_talk = ::Talk.find_or_initialize_by(static_id: child_talk_data[\"id\"])\n          child_talk.parent_talk = talk\n          child_talk.update_from_yml_metadata!(event: event)\n          Search::Backend.index(child_talk) if index\n        end\n      rescue ActiveRecord::RecordInvalid => e\n        puts \"Couldn't save: #{talk_data[\"title\"]} (#{talk_data[\"id\"]}), error: #{e.message}\"\n      end\n    end\n\n    def import_sponsors!(event)\n      return unless imported?\n      return unless event.sponsors_file.exist?\n\n      require \"public_suffix\"\n\n      organisation_ids = []\n      event.sponsors_file.file.each do |sponsors|\n        sponsors[\"tiers\"].each do |tier|\n          tier[\"sponsors\"].each do |sponsor|\n            s = nil\n            domain = nil\n\n            if sponsor[\"website\"].present?\n              begin\n                uri = URI.parse(sponsor[\"website\"])\n                host = uri.host || sponsor[\"website\"]\n                parsed = PublicSuffix.parse(host)\n                domain = parsed.domain\n\n                s = ::Organization.find_by(domain: domain) if domain.present?\n              rescue PublicSuffix::Error, URI::InvalidURIError\n                # If parsing fails, continue with other matching methods\n              end\n            end\n\n            s ||= ::Organization.find_by_name_or_alias(sponsor[\"name\"]) || ::Organization.find_by_slug_or_alias(sponsor[\"slug\"]&.downcase)\n            s ||= ::Organization.find_or_initialize_by(name: sponsor[\"name\"])\n\n            s.update(\n              website: sponsor[\"website\"],\n              description: sponsor[\"description\"],\n              domain: domain\n            )\n\n            s.add_logo_url(sponsor[\"logo_url\"]) if sponsor[\"logo_url\"].present?\n            s.logo_url = sponsor[\"logo_url\"] if sponsor[\"logo_url\"].present? && s.logo_url.blank?\n\n            s = ::Organization.find_by_slug_or_alias(s.slug) || ::Organization.find_by_name_or_alias(s.name) unless s.persisted?\n\n            s.save!\n\n            organisation_ids << s.id\n\n            event.sponsors.find_or_create_by!(organization: s, event: event).update!(tier: tier[\"name\"], badge: sponsor[\"badge\"], level: tier[\"level\"])\n          end\n        end\n      end\n      event.sponsors.where.not(organization_id: organisation_ids).destroy_all\n    end\n\n    def import_involvements!(event)\n      return unless imported?\n      return unless event.involvements_file.exist?\n\n      event_involvements = event.event_involvements\n\n      # Mark existing involvements for destruction\n      event_involvements_attributes = event_involvements.map { it.attributes.merge(_destroy: true) }\n\n      involvements = event.involvements_file.entries\n\n      involvements.each do |involvement_data|\n        role = involvement_data[\"name\"]\n\n        Array.wrap(involvement_data[\"users\"]).each_with_index do |user_name, index|\n          next if user_name.blank?\n\n          user = ::User.find_by_name_or_alias(user_name)\n\n          unless user\n            # raise \"User '#{user_name}' not found in speakers.yml\" if Rails.env.development?\n            puts \"Creating user: #{user_name}\" unless Rails.env.test?\n            user = ::User.create!(name: user_name)\n          end\n\n          # Get index if involvement already exists in the attributes array\n          attributes_index = event_involvements_attributes.index do |attrs|\n            attrs[\"role\"] == role && attrs[\"involvementable_type\"] == \"User\" &&\n              attrs[\"involvementable_id\"] == user.id\n          end\n\n          if attributes_index.present?\n            # Replace the involvement attributes to avoid destroying it (update position if necessary)\n            event_involvements_attributes[attributes_index].update(position: index, _destroy: false)\n          else\n            # Add new involvement\n            event_involvements_attributes << {\n              role: role,\n              involvementable: user,\n              position: index\n            }\n          end\n        end\n\n        user_count = involvement_data[\"users\"]&.compact&.size || 0\n\n        Array.wrap(involvement_data[\"organisations\"]).each_with_index do |org_name, index|\n          next if org_name.blank?\n\n          organization = ::Organization.find_by_name_or_alias(org_name) || ::Organization.find_by_slug_or_alias(org_name.parameterize)\n\n          unless organization\n            # raise \"Organization '#{org_name}' not found\" if Rails.env.development?\n            puts \"Creating organization: #{org_name}\" unless Rails.env.test?\n            organization = ::Organization.create!(name: org_name)\n          end\n\n          # Get index if involvement already exists in the attributes array\n          attributes_index = event_involvements_attributes.index do |attrs|\n            attrs[\"role\"] == role && attrs[\"involvementable_type\"] == \"Organization\" &&\n              attrs[\"involvementable_id\"] == organization.id\n          end\n\n          if attributes_index.present?\n            # Replace the involvement attributes to avoid destroying it (update position if necessary)\n            event_involvements_attributes[attributes_index].update(position: index + user_count, _destroy: false)\n          else\n            # Add new involvement\n            event_involvements_attributes << {\n              role: role,\n              involvementable: organization,\n              position: index + user_count\n            }\n          end\n        end\n      end\n      event.update!(event_involvements_attributes: event_involvements_attributes)\n    end\n\n    def import_transcripts!(event)\n      return unless imported?\n      return unless event.transcripts_file.exist?\n\n      transcripts = event.transcripts_file.entries\n      return if transcripts.blank?\n\n      transcripts.each do |transcript_data|\n        video_id = transcript_data[\"video_id\"]\n        cues = transcript_data[\"cues\"]\n\n        next if video_id.blank? || cues.blank?\n\n        talk = event.talks.find_by(video_id: video_id)\n        next unless talk\n\n        transcript = ::Transcript.new\n        cues.each do |cue_data|\n          transcript.add_cue(\n            Cue.new(\n              start_time: cue_data[\"start_time\"],\n              end_time: cue_data[\"end_time\"],\n              text: cue_data[\"text\"]\n            )\n          )\n        end\n\n        transcript_record = talk.talk_transcript || ::Talk::Transcript.new(talk: talk)\n        transcript_record.update!(raw_transcript: transcript)\n      end\n    end\n\n    def series_slug\n      @series_slug ||= __file_path.split(\"/\")[-3]\n    end\n\n    def __file_path\n      attributes[\"__file_path\"]\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/static/event_series.rb",
    "content": "module Static\n  class EventSeries < FrozenRecord::Base\n    self.backend = Backends::MultiFileBackend.new(\"*/series.yml\")\n    self.base_path = Rails.root.join(\"data\")\n\n    SEARCH_INDEX_ON_IMPORT_DEFAULT = ENV.fetch(\"SEARCH_INDEX_ON_IMPORT\", \"true\") == \"true\"\n\n    class << self\n      def find_by_slug(slug)\n        @slug_index ||= all.index_by(&:slug)\n        @slug_index[slug]\n      end\n\n      def import_all!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n        all.each { |series| series.import!(index: index) }\n      end\n\n      def import_all_series!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n        all.each { |series| series.import_series!(index: index) }\n      end\n\n      def create(\n        name:,\n        slug: nil,\n        description: nil,\n        kind: nil,\n        frequency: nil,\n        ended: nil,\n        default_country_code: nil,\n        language: nil,\n        website: nil,\n        original_website: nil,\n        twitter: nil,\n        mastodon: nil,\n        bsky: nil,\n        github: nil,\n        linkedin: nil,\n        meetup: nil,\n        luma: nil,\n        guild: nil,\n        vimeo: nil,\n        youtube_channel_id: nil,\n        youtube_channel_name: nil,\n        playlist_matcher: nil,\n        aliases: nil\n      )\n        slug ||= name.parameterize\n\n        series_dir = base_path.join(slug)\n        series_file = series_dir.join(\"series.yml\")\n\n        if series_file.exist?\n          raise ArgumentError, \"Event series '#{slug}' already exists at #{series_file}\"\n        end\n\n        data = {\"name\" => name}\n\n        data[\"description\"] = description if description.present?\n        data[\"kind\"] = kind if kind.present?\n        data[\"frequency\"] = frequency if frequency.present?\n        data[\"ended\"] = ended unless ended.nil?\n        data[\"default_country_code\"] = default_country_code if default_country_code.present?\n        data[\"language\"] = language if language.present?\n        data[\"website\"] = website if website.present?\n        data[\"original_website\"] = original_website if original_website.present?\n        data[\"twitter\"] = twitter if twitter.present?\n        data[\"mastodon\"] = mastodon if mastodon.present?\n        data[\"bsky\"] = bsky if bsky.present?\n        data[\"github\"] = github if github.present?\n        data[\"linkedin\"] = linkedin if linkedin.present?\n        data[\"meetup\"] = meetup if meetup.present?\n        data[\"luma\"] = luma if luma.present?\n        data[\"guild\"] = guild if guild.present?\n        data[\"vimeo\"] = vimeo if vimeo.present?\n        data[\"youtube_channel_id\"] = youtube_channel_id if youtube_channel_id.present?\n        data[\"youtube_channel_name\"] = youtube_channel_name if youtube_channel_name.present?\n        data[\"playlist_matcher\"] = playlist_matcher if playlist_matcher.present?\n        data[\"aliases\"] = Array(aliases) if aliases.present?\n\n        schema = JSON.parse(SeriesSchema.new.to_json_schema[:schema].to_json)\n        schemer = JSONSchemer.schema(schema)\n        errors = schemer.validate(data).to_a\n\n        if errors.any?\n          error_messages = errors.map { |e| \"#{e[\"error\"]} at #{e[\"data_pointer\"]}\" }\n          raise ArgumentError, \"Validation failed: #{error_messages.join(\", \")}\"\n        end\n\n        FileUtils.mkdir_p(series_dir)\n        File.write(series_file, data.to_yaml)\n\n        @slug_index = nil\n        unload!\n\n        find_by_slug(slug)\n      end\n    end\n\n    def slug\n      @slug ||= File.basename(File.dirname(__file_path))\n    end\n\n    def event_series_record\n      @event_series_record ||= ::EventSeries.find_by(slug: slug) || import_series!\n    end\n\n    def import_series!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      event_series = ::EventSeries.find_or_initialize_by(slug: slug)\n\n      event_series.update!(\n        name: name,\n        website: website || \"\",\n        twitter: twitter || \"\",\n        youtube_channel_name: youtube_channel_name,\n        kind: kind,\n        frequency: frequency,\n        youtube_channel_id: youtube_channel_id,\n        slug: slug,\n        language: language || \"\"\n      )\n\n      event_series.sync_aliases_from_list(aliases) if aliases.present?\n\n      Search::Backend.index(event_series) if index\n\n      event_series\n    end\n\n    def import!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      import_series!(index: index)\n      events.each { |event| event.import!(index: index) }\n      event_series_record\n    end\n\n    def events\n      @events ||= Static::Event.all.select { |event| event.series_slug == slug }\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/static/speaker.rb",
    "content": "# frozen_string_literal: true\n\nmodule Static\n  class Speaker < FrozenRecord::Base\n    self.backend = Backends::FileBackend.new(\"speakers.yml\")\n    self.base_path = Rails.root.join(\"data\")\n\n    SEARCH_INDEX_ON_IMPORT_DEFAULT = ENV.fetch(\"SEARCH_INDEX_ON_IMPORT\", \"true\") == \"true\"\n\n    def self.import_all!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      imported_users = []\n      speakers = all.to_a\n\n      puts \"Importing #{speakers.count} speakers...\"\n\n      ::User.transaction do\n        speakers.each do |speaker|\n          user = speaker.import!(index: false)\n          imported_users << user if user\n        end\n      end\n\n      imported_users.each { |user| Search::Backend.index(user) } if imported_users.any? && index\n    end\n\n    def import!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      user = ::User.find_by_github_handle(github) ||\n        ::User.find_by(slug: slug) ||\n        ::User.find_by_name_or_alias(name) ||\n        ::User.find_by(slug: name.parameterize) ||\n        ::User.new\n\n      user.name = name\n      user.twitter = twitter if twitter.present?\n      user.github_handle = github if github.present?\n      user.website = website if website.present?\n\n      user_changed = user.changed? || user.new_record?\n      user.save! if user_changed\n\n      Array(aliases).each do |alias_data|\n        next if alias_data.blank?\n\n        alias_name = alias_data[\"name\"]\n        alias_slug = alias_data[\"slug\"]\n\n        raise format(\"No name provided for alias: %s and user: %s\", alias_data.inspect, user.inspect) if alias_name.blank?\n        raise format(\"No slug provided for alias: %s and user: %s\", alias_data.inspect, user.inspect) if alias_slug.blank?\n\n        ::Alias.find_or_create_by!(aliasable: user, name: alias_name, slug: alias_slug)\n      end\n\n      Search::Backend.index(user) if index && user_changed\n\n      user_changed ? user : nil\n    rescue ActiveRecord::RecordInvalid => e\n      puts \"Couldn't save: #{name} (#{github}), error: #{e.message}\"\n      nil\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/static/sponsor.rb",
    "content": "module Static\n  class Sponsor < FrozenRecord::Base\n    self.backend = Backends::MultiFileBackend.new(\"**/**/sponsors.yml\")\n    self.base_path = Rails.root.join(\"data\")\n  end\nend\n"
  },
  {
    "path": "app/models/static/topic.rb",
    "content": "module Static\n  class Topic < FrozenRecord::Base\n    self.backend = Backends::ArrayBackend.new(\"topics.yml\")\n    self.base_path = Rails.root.join(\"data\")\n\n    SEARCH_INDEX_ON_IMPORT_DEFAULT = ENV.fetch(\"SEARCH_INDEX_ON_IMPORT\", \"true\") == \"true\"\n\n    def self.import_all!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      topics = ::Topic.create_from_list(all.map(&:name), status: :approved)\n      topics.each { |topic| Search::Backend.index(topic) } if index\n      topics\n    end\n\n    def name\n      item\n    end\n\n    def import!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      slug = name.parameterize\n      topic = ::Topic.find_by(slug: slug)&.primary_topic || ::Topic.find_or_create_by(name: name, status: :approved)\n      Search::Backend.index(topic) if index\n      topic\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/static/transcript.rb",
    "content": "module Static\n  class Transcript < FrozenRecord::Base\n    self.backend = Backends::MultiFileBackend.new(\"**/**/transcripts.yml\")\n    self.base_path = Rails.root.join(\"data\")\n\n    SEARCH_INDEX_ON_IMPORT_DEFAULT = ENV.fetch(\"SEARCH_INDEX_ON_IMPORT\", \"true\") == \"true\"\n\n    class << self\n      def find_by_video_id(video_id)\n        @video_id_index ||= all.index_by { |t| t[\"video_id\"] }\n        @video_id_index[video_id]\n      end\n\n      def import_all!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n        all.each { |transcript| transcript.import!(index: index) }\n      end\n    end\n\n    def video_id\n      self[\"video_id\"]\n    end\n\n    def cues\n      self[\"cues\"] || []\n    end\n\n    def to_transcript\n      transcript = ::Transcript.new\n      cues.each do |cue_data|\n        transcript.add_cue(\n          Cue.new(\n            start_time: cue_data[\"start_time\"],\n            end_time: cue_data[\"end_time\"],\n            text: cue_data[\"text\"]\n          )\n        )\n      end\n      transcript\n    end\n\n    def import!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      talk = ::Talk.find_by(video_id: video_id)\n      return unless talk\n\n      transcript_record = talk.talk_transcript || ::Talk::Transcript.new(talk: talk)\n      transcript_record.update!(raw_transcript: to_transcript)\n\n      Search::Backend.index(talk) if index\n\n      transcript_record\n    end\n\n    def event_slug\n      return nil unless __file_path\n\n      __file_path.split(\"/\")[-2]\n    end\n\n    def series_slug\n      return nil unless __file_path\n\n      __file_path.split(\"/\")[-3]\n    end\n\n    def __file_path\n      attributes[\"__file_path\"]\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/static/video.rb",
    "content": "module Static\n  class Video < FrozenRecord::Base\n    self.backend = Backends::MultiFileBackend.new(\"**/**/videos.yml\")\n    self.base_path = Rails.root.join(\"data\")\n\n    SEARCH_INDEX_ON_IMPORT_DEFAULT = ENV.fetch(\"SEARCH_INDEX_ON_IMPORT\", \"true\") == \"true\"\n\n    def self.child_talks\n      @child_talks ||= Static::Video.all.flat_map(&:talks).compact\n    end\n\n    def self.child_talks_map\n      @child_talks_map ||= child_talks.to_h { |talk| [talk.id, talk] }\n    end\n\n    def self.all_talks\n      @all_talks ||= Static::Video.all + child_talks\n    end\n\n    def self.all_talks_map\n      @child_talks_map ||= all_talks.to_h { |talk| [talk.id, talk] }\n    end\n\n    def self.find_child_talk_by_id(id)\n      child_talks_map[id]\n    end\n\n    def self.find_by_static_id(id)\n      all_talks_map[id]\n    end\n\n    def self.where_event_slug(event_slug)\n      all.select { |video| video.__file_path&.include?(\"/#{event_slug}/\") }\n    end\n\n    def self.import_all!(index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      all.each { |video| video.import!(index: index) }\n    end\n\n    def raw_title\n      super || title\n    end\n\n    def description\n      super || \"\"\n    end\n\n    def start_cue\n      self[\"start_cue\"]\n    end\n\n    def end_cue\n      self[\"end_cue\"]\n    end\n\n    def thumbnail_cue\n      duration_to_formatted_cue(ActiveSupport::Duration.build(thumbnail_cue_in_seconds))\n    end\n\n    def duration_fs\n      duration_to_formatted_cue(duration)\n    end\n\n    def duration_to_formatted_cue(duration)\n      Duration.seconds_to_formatted_duration(duration)\n    end\n\n    def duration\n      ActiveSupport::Duration.build(duration_in_seconds)\n    end\n\n    def duration_in_seconds\n      end_cue_in_seconds - start_cue_in_seconds\n    end\n\n    def start_cue_in_seconds\n      convert_cue_to_seconds(start_cue)\n    end\n\n    def end_cue_in_seconds\n      convert_cue_to_seconds(end_cue)\n    end\n\n    def thumbnail_cue_in_seconds\n      (self[\"thumbnail_cue\"] && self[\"thumbnail_cue\"] != \"TODO\") ? convert_cue_to_seconds(self[\"thumbnail_cue\"]) : (start_cue_in_seconds + 5)\n    end\n\n    def convert_cue_to_seconds(cue)\n      return nil if cue.blank?\n\n      cue.split(\":\").map(&:to_i).reverse.each_with_index.reduce(0) do |sum, (value, index)|\n        sum + value * 60**index\n      end\n    end\n\n    def speakers\n      return [] if self[\"speakers\"].blank?\n\n      super\n    end\n\n    def talks\n      @talks ||= begin\n        return [] if self[\"talks\"].blank?\n\n        super.map { |talk| Static::Video.new(talk) }\n      end\n    end\n\n    def meta_talk?\n      attributes.key?(\"talks\")\n    end\n\n    def import!(event: nil, parent_talk: nil, index: SEARCH_INDEX_ON_IMPORT_DEFAULT)\n      if title.blank?\n        puts \"Ignored video: #{raw_title}\"\n        return nil\n      end\n\n      event ||= find_event\n\n      raise \"Event not found for video #{id}\" unless event\n\n      talk = ::Talk.find_or_initialize_by(static_id: id)\n      talk.parent_talk = parent_talk if parent_talk\n      talk.update_from_yml_metadata!(event: event)\n\n      Search::Backend.index(talk) if index\n\n      talks.each do |child_video|\n        child_video.import!(event: event, parent_talk: talk, index: index)\n      end\n\n      talk\n    rescue ActiveRecord::RecordInvalid => e\n      puts \"Couldn't save: #{title} (#{id}), error: #{e.message}\"\n      nil\n    end\n\n    def find_event\n      return nil unless __file_path\n\n      event_slug = __file_path.split(\"/\")[-2]\n      ::Event.find_by(slug: event_slug)\n    end\n\n    def __file_path\n      attributes[\"__file_path\"]\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/sticker.rb",
    "content": "class Sticker\n  include ActiveModel::Model\n  include ActiveModel::Attributes\n\n  attribute :code, :string\n  attribute :name, :string\n  attribute :file_path, :string\n  attribute :event\n  attribute :event_slug, :string\n\n  def self.all\n    @all_stickers ||= load_stickers_from_filesystem\n  end\n\n  def self.for_event(event)\n    return [] unless event&.slug\n\n    prefix = \"#{event.event_image_path}/\"\n\n    all.select { |sticker|\n      (sticker.event_slug.present? && sticker.event_slug == event.slug) ||\n        sticker.file_path.start_with?(prefix)\n    }\n  end\n\n  def asset_path\n    ActionController::Base.helpers.asset_path(file_path)\n  end\n\n  def event\n    return @event if defined?(@event)\n\n    @event = Event.find_by(slug: event_slug) if event_slug.present?\n  end\n\n  def self.load_stickers_from_filesystem\n    images_directory = Rails.root.join(\"app\", \"assets\", \"images\")\n    event_sticker_files = Dir.glob(images_directory.join(\"events\", \"**\", \"sticker*.webp\"))\n\n    event_sticker_files.map { |file| create_sticker_from_event_file(file, images_directory) }\n      .compact\n      .uniq { |sticker| sticker.code }\n      .sort_by(&:name)\n  end\n\n  def self.create_sticker_from_event_file(file, images_directory)\n    relative_path = Pathname.new(file).relative_path_from(images_directory)\n    path_parts = relative_path.each_filename.to_a\n    event_slug = path_parts[-2]\n    basename = Pathname.new(file).basename(\".webp\").to_s\n\n    return nil unless event_slug.present? && basename.present?\n\n    event = Event.find_by(slug: event_slug)\n\n    variant_suffix = basename.sub(/^sticker[_-]?/i, \"\")\n    code_parts = [event&.slug || event_slug, basename].compact\n    code = code_parts.join(\"-\").upcase\n\n    display_name = event&.name || event_slug.titleize\n    variant_label = variant_suffix.present? ? \"Sticker #{variant_suffix.titleize}\" : \"Sticker\"\n    name = \"#{display_name} (#{variant_label})\"\n\n    new(\n      code: code,\n      name: name,\n      file_path: relative_path.to_s,\n      event: event,\n      event_slug: event_slug\n    )\n  end\nend\n"
  },
  {
    "path": "app/models/suggestion.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: suggestions\n# Database name: primary\n#\n#  id               :integer          not null, primary key\n#  content          :text\n#  status           :integer          default(\"pending\"), not null, indexed\n#  suggestable_type :string           not null, indexed => [suggestable_id]\n#  created_at       :datetime         not null\n#  updated_at       :datetime         not null\n#  approved_by_id   :integer          indexed\n#  suggestable_id   :integer          not null, indexed => [suggestable_type]\n#  suggested_by_id  :integer          indexed\n#\n# Indexes\n#\n#  index_suggestions_on_approved_by_id   (approved_by_id)\n#  index_suggestions_on_status           (status)\n#  index_suggestions_on_suggestable      (suggestable_type,suggestable_id)\n#  index_suggestions_on_suggested_by_id  (suggested_by_id)\n#\n# Foreign Keys\n#\n#  approved_by_id   (approved_by_id => users.id)\n#  suggested_by_id  (suggested_by_id => users.id)\n#\n# rubocop:enable Layout/LineLength\nclass Suggestion < ApplicationRecord\n  # associations\n  belongs_to :suggestable, polymorphic: true\n  belongs_to :approved_by, class_name: \"User\", optional: true\n  belongs_to :suggested_by, class_name: \"User\", optional: true\n\n  # attributes\n  serialize :content, coder: JSON\n\n  # callbacks\n\n  # enums\n  enum :status, {pending: 0, approved: 1, rejected: 2}\n\n  # validations\n  validates :approved_by, presence: true, if: :approved?\n\n  def approved!(approver:)\n    ActiveRecord::Base.transaction do\n      suggestable.update!(content)\n      update!(status: :approved, approved_by_id: approver.id)\n    end\n  end\n\n  def notice\n    if approved?\n      \"Modification approved!\"\n    elsif rejected?\n      \"Suggestion rejected!\"\n    else\n      \"Your suggestion was successfully created and will be reviewed soon.\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/talk/agents.rb",
    "content": "class Talk::Agents < ActiveRecord::AssociatedObject\n  # Now that we use the tier flex option we perform limited retries as our request can be rejected if OpenAI is busy\n  performs retries: 2 do\n    # this is to comply to the rate limit of openai 60 000 tokens per minute\n    limits_concurrency to: 4, key: \"openai_api\", duration: 1.hour\n  end\n\n  performs def improve_transcript\n    return if talk.raw_transcript.blank?\n\n    response = client.chat(\n      parameters: Prompts::Talk::EnhanceTranscript.new(talk: talk).to_params,\n      resource: talk,\n      task_name: \"enhance_transcript\"\n    )\n    raw_response = JSON.repair(response.dig(\"choices\", 0, \"message\", \"content\"))\n    enhanced_json_transcript = JSON.parse(raw_response).dig(\"transcript\")\n    transcript = talk.talk_transcript || Talk::Transcript.new\n    transcript.update!(enhanced_transcript: ::Transcript.create_from_json(enhanced_json_transcript))\n  end\n\n  performs def summarize\n    return unless talk.raw_transcript.present?\n\n    response = client.chat(\n      parameters: Prompts::Talk::Summary.new(talk: talk).to_params,\n      resource: talk,\n      task_name: \"summarize\"\n    )\n\n    raw_response = JSON.repair(response.dig(\"choices\", 0, \"message\", \"content\"))\n    summary = JSON.parse(raw_response).dig(\"summary\")\n    talk.update!(summary: summary)\n  end\n\n  performs def analyze_topics\n    return if talk.raw_transcript.blank?\n\n    response = client.chat(\n      parameters: Prompts::Talk::Topics.new(talk: talk).to_params,\n      resource: talk,\n      task_name: \"analyze_topics\"\n    )\n\n    raw_response = JSON.repair(response.dig(\"choices\", 0, \"message\", \"content\"))\n    topics = begin\n      JSON.parse(raw_response)[\"topics\"]\n    rescue\n      []\n    end\n\n    talk.topics = Topic.create_from_list(topics)\n    talk.save!\n\n    talk\n  end\n\n  performs def ingest\n    talk.fetch_and_update_raw_transcript! unless talk.raw_transcript.present?\n    talk.agents.improve_transcript unless talk.enhanced_transcript.present?\n    talk.agents.summarize unless talk.summary.present?\n    talk.agents.analyze_topics unless talk.topics.present?\n  end\n\n  private\n\n  def client\n    @client ||= LLM::Client.new\n  end\nend\n"
  },
  {
    "path": "app/models/talk/downloader.rb",
    "content": "class Talk::Downloader < ActiveRecord::AssociatedObject\n  def bin\n    ENV.fetch(\"YTDLP_BIN\", \"yt-dlp\")\n  end\n\n  def download_path\n    Rails.root / \"tmp\" / \"videos\" / talk.video_provider / \"#{talk.video_id}.mp4\"\n  end\n\n  def downloaded?\n    download_path.exist?\n  end\n\n  def downloadable?\n    talk.youtube? || talk.mp4?\n  end\n\n  def download!\n    if !downloadable?\n      puts \"Talk #{talk.video_id} is not a YouTube or mp4 video\"\n\n      return\n    end\n\n    if downloaded?\n      puts \"#{talk.video_id} exists, skipping...\"\n\n      return\n    end\n\n    puts \"#{talk.video_id} downloading...\"\n\n    Command.run(%(#{bin} --output \"#{download_path}\" --format \"bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]\" \"#{talk.provider_url}\"))\n  end\nend\n"
  },
  {
    "path": "app/models/talk/index.rb",
    "content": "class Talk::Index < ApplicationRecord\n  self.table_name = :talks_search_index\n\n  include ActiveRecord::SQLite::Index # Depends on `table_name` being assigned.\n\n  class_attribute :index_columns, default: {title: 0, summary: 1, speaker_names: 2, event_names: 3}\n\n  belongs_to :talk, foreign_key: :rowid\n\n  def self.search(query)\n    query = remove_invalid_search_characters(query) || \"\" # remove non-word characters\n    query = remove_unbalanced_quotes(query)\n    query = query.split.map { |word| \"#{word}*\" }.join(\" \") # wildcard search\n    query = query.strip.presence\n\n    return all if query.blank?\n\n    where(\"#{table_name} match ?\", query)\n  end\n\n  def self.snippets(**)\n    index_columns.each_key.reduce(all) { |relation, column| relation.snippet(column, **) }\n  end\n\n  def self.snippet(column, tag: \"mark\", omission: \"…\", limit: 32)\n    offset = index_columns.fetch(column)\n    select(\"snippet(#{table_name}, #{offset}, '<#{tag}>', '</#{tag}>', '#{omission}', #{limit}) AS #{column}_snippet\")\n  end\n\n  def reindex\n    update!(id: talk.id,\n      title: talk.title,\n      summary: talk.summary,\n      speaker_names: talk.speaker_names,\n      event_names: talk.event_names,\n      video_provider: talk.video_provider)\n  end\n\n  def self.remove_invalid_search_characters(query)\n    query.gsub(/[^\\w\"]/, \" \")\n  end\n\n  def self.remove_unbalanced_quotes(query)\n    if query.count(\"\\\"\").even?\n      query\n    else\n      query.tr(\"\\\"\", \" \")\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/talk/similar_recommender.rb",
    "content": "class Talk::SimilarRecommender < ActiveRecord::AssociatedObject\n  def talks(limit: 12)\n    return Talk.none if topic_ids.empty?\n\n    similar_talk_ids = Talk.joins(:approved_topics)\n      .where(topics: {id: topic_ids})\n      .where.not(id: talk.id)\n      .watchable\n      .group(:id)\n      .order(Arel.sql(\"COUNT(topics.id) DESC\"), date: :desc)\n      .limit(limit)\n      .pluck(:id)\n\n    Talk.where(id: similar_talk_ids)\n      .includes(:speakers, :event)\n      .in_order_of(:id, similar_talk_ids)\n  end\n\n  def topic_ids\n    @topic_ids ||= talk.approved_topics.pluck(:id)\n  end\n\n  def topics\n    talk.approved_topics\n  end\nend\n"
  },
  {
    "path": "app/models/talk/sqlite_fts_searchable.rb",
    "content": "# frozen_string_literal: true\n\nmodule Talk::SQLiteFTSSearchable\n  extend ActiveSupport::Concern\n\n  DATE_WEIGHT = 0.000000001\n\n  included do\n    has_one :fts_index, foreign_key: :rowid, inverse_of: :talk, dependent: :destroy, class_name: \"Talk::Index\"\n\n    scope :ft_search, ->(query) { select(\"talks.*\").joins(:fts_index).merge(Talk::Index.search(query)) }\n\n    scope :with_snippets, ->(**options) do\n      select(\"talks.*\").merge(Talk::Index.snippets(**options))\n    end\n\n    scope :ranked, -> do\n      select(\"talks.*,\n          bm25(talks_search_index, 10.0, 1.0, 5.0) +\n          (strftime('%s', 'now') - strftime('%s', talks.date)) * #{DATE_WEIGHT} AS combined_score\")\n        .order(combined_score: :asc)\n    end\n\n    # Filter on FTS table directly for better performance with search\n    # This allows FTS5 to optimize the query when combined with MATCH\n    scope :ft_watchable, -> do\n      joins(:fts_index).where(\"talks_search_index.video_provider IN (?)\", Talk::WATCHABLE_PROVIDERS)\n    end\n\n    after_save_commit :reindex_fts\n  end\n\n  def title_with_snippet\n    try(:title_snippet) || title\n  end\n\n  def fts_index\n    super || build_fts_index\n  end\n\n  def reindex_fts\n    return if Search::Backend.skip_indexing\n\n    fts_index.reindex\n  end\nend\n"
  },
  {
    "path": "app/models/talk/thumbnails.rb",
    "content": "class Talk::Thumbnails < ActiveRecord::AssociatedObject\n  def path\n    directory / \"#{talk.video_id}.webp\"\n  end\n\n  def extractable?\n    talk.meta_talk? && talk.static_metadata&.talks&.any? && !start_cues.include?(\"TODO\")\n  end\n\n  def start_cues\n    talk.static_metadata.talks.map { |talk| talk.start_cue || \"TODO\" }\n  end\n\n  def extracted?\n    talk.child_talks.map { |child_talk| child_talk.thumbnails.path.exist? }.reduce(:&)\n  end\n\n  def extract!(force: false, download: false)\n    if !extractable?\n      puts \"Talk #{talk.video_id} is not extractable. Skipping...\"\n\n      return\n    end\n\n    if extracted? && !force\n      puts \"All thumbnails for child_talks of #{talk.video_id} are extracted already. Skipping...\"\n\n      return\n    end\n\n    if !talk.downloader.downloaded?\n      if download\n        puts \"#{talk.video_id} is not downloaded. Downloading...\"\n\n        talk.downloader.download!\n      else\n        puts \"#{talk.video_id} is not downloaded. Skipping...\"\n\n        return\n      end\n    end\n\n    talk.child_talks.each do |child_talk|\n      if child_talk.static_metadata&.start_cue == \"TODO\"\n        puts \"start_cue of #{child_talk.video_id} is TODO. Skipping...\"\n        next\n      end\n\n      if child_talk.static_metadata.blank?\n        puts \"static_metadata of #{child_talk.video_id} is missing. Skipping...\"\n        next\n      end\n\n      extract_thumbnail(child_talk.static_metadata.thumbnail_cue, talk.downloader.download_path, child_talk.thumbnails.path)\n    end\n  end\n\n  def extract_thumbnail(timestamp, input_file, output_file)\n    Command.run(%(ffmpeg -y -ss #{timestamp} -i \"#{input_file}\" -map 0:v:0 -frames:v 1 -q:v 50 -vf scale=1080:-1 \"#{output_file}\"))\n  end\n\n  private\n\n  def directory\n    Rails.root.join(\"app/assets/images/thumbnails\").tap(&:mkpath)\n  end\nend\n"
  },
  {
    "path": "app/models/talk/transcript.rb",
    "content": "# == Schema Information\n#\n# Table name: talk_transcripts\n# Database name: primary\n#\n#  id                  :integer          not null, primary key\n#  enhanced_transcript :text\n#  raw_transcript      :text\n#  created_at          :datetime         not null\n#  updated_at          :datetime         not null\n#  talk_id             :integer          not null, indexed\n#\n# Indexes\n#\n#  index_talk_transcripts_on_talk_id  (talk_id)\n#\n# Foreign Keys\n#\n#  talk_id  (talk_id => talks.id)\n#\nclass Talk::Transcript < ApplicationRecord\n  belongs_to :talk, touch: true\n\n  serialize :enhanced_transcript, coder: TranscriptSerializer\n  serialize :raw_transcript, coder: TranscriptSerializer\n\n  scope :empty, -> { where(\"raw_transcript IS NULL OR raw_transcript = '[]'\") }\n\n  def transcript\n    enhanced_transcript.presence || raw_transcript\n  end\nend\n"
  },
  {
    "path": "app/models/talk/typesense_searchable.rb",
    "content": "# frozen_string_literal: true\n\nmodule Talk::TypesenseSearchable\n  extend ActiveSupport::Concern\n\n  included do\n    include ::Typesense\n\n    typesense enqueue: :trigger_typesense_job, if: :should_index?, disable_indexing: -> { Search::Backend.skip_indexing } do\n      attributes :title, :description, :summary, :slug, :language, :kind\n\n      attribute :date_timestamp do\n        date&.to_time&.to_i || 0\n      end\n\n      attribute :published_at_timestamp do\n        published_at&.to_i || 0\n      end\n\n      attribute :year do\n        date&.year\n      end\n\n      # Recency score for boosting recent talks (higher = more recent)\n      # Calculated as days since epoch, so recent talks have higher scores\n      # Days since 2020-01-01, capped to ensure older talks still have some score\n      attribute :recency_score do\n        return 0 unless date\n\n        days_since_2020 = (date.to_date - Date.new(2020, 1, 1)).to_i\n\n        [days_since_2020, 0].max\n      end\n\n      attribute :video_provider\n      attribute :video_id\n      attribute :duration_in_seconds\n      attribute :view_count\n      attribute :like_count\n\n      attribute :thumbnail_url do\n        thumbnail_md\n      end\n\n      attribute :speakers do\n        speakers.map do |speaker|\n          {\n            id: speaker.id,\n            name: speaker.name,\n            slug: speaker.slug,\n            github: speaker.github_handle,\n            twitter: speaker.twitter\n          }\n        end\n      end\n\n      attribute :speaker_names do\n        speakers.pluck(:name).join(\", \")\n      end\n\n      attribute :speaker_slugs do\n        speakers.pluck(:slug)\n      end\n\n      attribute :speaker_github_handles do\n        speakers.pluck(:github_handle).compact\n      end\n\n      attribute :speaker_twitter_handles do\n        speakers.pluck(:twitter).compact\n      end\n\n      attribute :speaker_alias_names do\n        speakers.flat_map { |s| s.aliases.pluck(:name) }.compact\n      end\n\n      attribute :speaker_alias_slugs do\n        speakers.flat_map { |s| s.aliases.pluck(:slug) }.compact\n      end\n\n      attribute :event do\n        next nil unless event\n\n        {\n          id: event.id,\n          name: event.name,\n          slug: event.slug,\n          kind: event.kind,\n          city: event.city,\n          country_code: event.country_code\n        }\n      end\n\n      attribute :event_name do\n        event&.name\n      end\n\n      attribute :event_slug do\n        event&.slug\n      end\n\n      attribute :series_name do\n        event&.series&.name\n      end\n\n      attribute :series_slug do\n        event&.series&.slug\n      end\n\n      attribute :event_alias_names do\n        event&.slug_aliases&.pluck(:name) || []\n      end\n\n      attribute :series_alias_names do\n        event&.series&.aliases&.pluck(:name) || []\n      end\n\n      attribute :country_code do\n        event&.country_code\n      end\n\n      attribute :country_name do\n        event&.country&.common_name || event&.country&.iso_short_name\n      end\n\n      attribute :state do\n        event&.state_code\n      end\n\n      attribute :state_name do\n        event&.state&.name\n      end\n\n      attribute :city do\n        event&.city\n      end\n\n      attribute :continent do\n        event&.country&.continent_name\n      end\n\n      attribute :location do\n        location\n      end\n\n      attribute :topics do\n        approved_topics.map do |topic|\n          {\n            id: topic.id,\n            name: topic.name,\n            slug: topic.slug\n          }\n        end\n      end\n\n      attribute :topic_names do\n        approved_topics.pluck(:name)\n      end\n\n      attribute :topic_slugs do\n        approved_topics.pluck(:slug)\n      end\n\n      attribute :transcript_text do\n        talk_transcript&.transcript&.to_text&.truncate(100_000)\n      end\n\n      attribute :has_slides do\n        slides_url.present?\n      end\n\n      attribute :slides_url\n\n      attribute :has_transcript do\n        talk_transcript&.raw_transcript.present?\n      end\n\n      attribute :resource_names do\n        (additional_resources || []).map { |r| r[\"name\"] }.compact\n      end\n\n      attribute :resource_urls do\n        (additional_resources || []).map { |r| r[\"url\"] }.compact\n      end\n\n      attribute :resource_types do\n        (additional_resources || []).map { |r| r[\"type\"] }.compact.uniq\n      end\n\n      attribute :alias_slugs do\n        aliases.pluck(:slug)\n      end\n\n      predefined_fields [\n        {\"name\" => \"title\", \"type\" => \"string\"},\n        {\"name\" => \"description\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"summary\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"transcript_text\", \"type\" => \"string\", \"optional\" => true},\n\n        {\"name\" => \"speaker_names\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"speaker_slugs\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"speaker_github_handles\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"speaker_twitter_handles\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"speaker_alias_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"speaker_alias_slugs\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"speakers\", \"type\" => \"object[]\", \"optional\" => true},\n\n        {\"name\" => \"event_name\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"event_slug\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"event_alias_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"series_name\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"series_slug\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"series_alias_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"event\", \"type\" => \"object\", \"optional\" => true},\n\n        {\"name\" => \"topic_names\", \"type\" => \"string[]\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"topic_slugs\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"topics\", \"type\" => \"object[]\", \"optional\" => true},\n\n        {\"name\" => \"kind\", \"type\" => \"string\", \"facet\" => true},\n        {\"name\" => \"language\", \"type\" => \"string\", \"facet\" => true},\n        {\"name\" => \"year\", \"type\" => \"int32\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"video_provider\", \"type\" => \"string\", \"facet\" => true},\n        {\"name\" => \"country_code\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"country_name\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"state\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"state_name\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"city\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"continent\", \"type\" => \"string\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"location\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"has_slides\", \"type\" => \"bool\"},\n        {\"name\" => \"has_transcript\", \"type\" => \"bool\"},\n\n        {\"name\" => \"date_timestamp\", \"type\" => \"int64\"},\n        {\"name\" => \"published_at_timestamp\", \"type\" => \"int64\"},\n        {\"name\" => \"recency_score\", \"type\" => \"int32\"},\n        {\"name\" => \"view_count\", \"type\" => \"int32\", \"optional\" => true},\n        {\"name\" => \"like_count\", \"type\" => \"int32\", \"optional\" => true},\n        {\"name\" => \"duration_in_seconds\", \"type\" => \"int32\", \"optional\" => true},\n\n        {\"name\" => \"slug\", \"type\" => \"string\"},\n        {\"name\" => \"video_id\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"thumbnail_url\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"slides_url\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"alias_slugs\", \"type\" => \"string[]\", \"optional\" => true},\n\n        {\"name\" => \"resource_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"resource_urls\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"resource_types\", \"type\" => \"string[]\", \"optional\" => true, \"facet\" => true}\n      ]\n\n      default_sorting_field \"date_timestamp\"\n\n      enable_nested_fields true\n\n      multi_way_synonyms [\n        {\"rails-synonym\" => %w[rails ruby-on-rails rubyonrails ror]},\n        {\"rspec-synonym\" => %w[rspec r-spec]},\n        {\"activerecord-synonym\" => %w[activerecord active-record ar]},\n        {\"actioncable-synonym\" => %w[actioncable action-cable websockets]},\n        {\"hotwire-synonym\" => %w[hotwire turbo stimulus]},\n        {\"testing-synonym\" => %w[testing tests test tdd bdd]},\n        {\"performance-synonym\" => %w[performance optimization speed fast]},\n        {\"security-synonym\" => %w[security secure authentication authorization]},\n        {\"api-synonym\" => %w[api apis rest restful graphql]},\n        {\"database-synonym\" => %w[database db databases sql postgresql postgres mysql sqlite]},\n        {\"docker-synonym\" => %w[docker containers containerization kubernetes k8s]},\n        {\"ci-synonym\" => %w[ci cd continuous-integration continuous-deployment github-actions circleci]},\n        {\"aws-synonym\" => %w[aws amazon-web-services cloud heroku digitalocean]},\n        {\"frontend-synonym\" => %w[frontend front-end javascript js typescript ts react vue angular]},\n\n        {\"keynote-synonym\" => %w[keynote keynotes opening-keynote closing-keynote]},\n        {\"lightning-talk-synonym\" => %w[lightning_talk lightning-talk lightning talks short-talk]},\n        {\"workshop-synonym\" => %w[workshop workshops hands-on tutorial]},\n        {\"panel-synonym\" => %w[panel panels discussion roundtable]},\n        {\"interview-synonym\" => %w[interview interviews fireside_chat fireside chat conversation]},\n        {\"demo-synonym\" => %w[demo demos demonstration live-coding livecoding]}\n      ]\n\n      one_way_synonyms Talk.typesense_synonyms_from_aliases\n\n      symbols_to_index %w[# @ $]\n\n      token_separators %w[- _]\n    end\n  end\n\n  class_methods do\n    def typesense_synonyms_from_aliases\n      ::Alias.where(aliasable_type: \"User\")\n        .includes(:aliasable)\n        .group_by(&:aliasable)\n        .filter_map do |user, aliases|\n          next unless user\n\n          canonical_slug = user.name.parameterize\n          alias_slugs = aliases.map { |a| a.name.parameterize }.uniq - [canonical_slug]\n\n          next if alias_slugs.empty?\n\n          {\"#{canonical_slug}-synonym\" => {\"root\" => canonical_slug, \"synonyms\" => alias_slugs}}\n        end\n    rescue ActiveRecord::StatementInvalid\n      []\n    end\n\n    def trigger_typesense_job(record, remove)\n      TypesenseIndexJob.perform_later(record, remove ? \"typesense_remove_from_index!\" : \"typesense_index!\")\n    end\n\n    def typesense_search_talks(query, options = {})\n      query_by_fields = \"title,slug,summary,description,kind,speaker_names,speaker_alias_names,speaker_github_handles,speaker_twitter_handles,event_name,event_alias_names,series_name,series_alias_names,topic_names,resource_names,city,country_name,state_name,continent,location,transcript_text\"\n\n      search_options = {\n        query_by_weights: \"10,9,5,3,3,8,7,9,9,4,4,4,4,6,7,3,3,2,2,2,1\",\n        per_page: options[:per_page] || 20,\n        page: options[:page] || 1,\n        highlight_full_fields: \"title,summary\",\n        highlight_affix_num_tokens: 10\n      }\n\n      filters = []\n      filters << \"kind:=#{options[:kind]}\" if options[:kind].present?\n      filters << \"language:=#{options[:language]}\" if options[:language].present?\n      filters << \"year:=#{options[:year]}\" if options[:year].present?\n      filters << \"event_slug:=#{options[:event_slug]}\" if options[:event_slug].present?\n      filters << \"series_slug:=#{options[:series_slug]}\" if options[:series_slug].present?\n      filters << \"topic_slugs:=#{options[:topic_slug]}\" if options[:topic_slug].present?\n      filters << \"speaker_slugs:=#{options[:speaker_slug]}\" if options[:speaker_slug].present?\n      filters << \"has_transcript:=true\" if options[:has_transcript]\n      filters << \"has_slides:=true\" if options[:has_slides]\n      filters << \"country_code:=#{options[:country_code]}\" if options[:country_code].present?\n      filters << \"state:=#{options[:state]}\" if options[:state].present?\n      filters << \"city:=#{options[:city]}\" if options[:city].present?\n      filters << \"continent:=#{options[:continent]}\" if options[:continent].present?\n\n      case options[:status]\n      when \"scheduled\"\n        filters << \"video_provider:=scheduled\"\n      when \"all\"\n        # Show all talks\n      else\n        filters << \"video_provider:=[youtube,mp4,vimeo]\" unless options[:include_unwatchable]\n      end\n\n      search_options[:filter_by] = filters.join(\" && \") if filters.any?\n\n      sort_options = {\n        \"date\" => \"date_timestamp:desc\",\n        \"date_desc\" => \"date_timestamp:desc\",\n        \"date_asc\" => \"date_timestamp:asc\",\n        \"created_at_desc\" => \"date_timestamp:desc\",\n        \"created_at_asc\" => \"date_timestamp:asc\",\n        \"views\" => \"view_count:desc\",\n        \"duration\" => \"duration_in_seconds:desc\",\n        \"relevance\" => \"_text_match:desc,recency_score:desc,date_timestamp:desc\"\n      }\n\n      search_options[:sort_by] = sort_options[options[:sort]] || sort_options[\"relevance\"]\n\n      if options[:facets]\n        search_options[:facet_by] = options[:facets].join(\",\")\n        search_options[:max_facet_values] = options[:max_facet_values] || 10\n      end\n\n      search(query.presence || \"*\", query_by_fields, search_options)\n    end\n  end\n\n  private\n\n  def should_index?\n    true\n  end\nend\n"
  },
  {
    "path": "app/models/talk.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: talks\n# Database name: primary\n#\n#  id                            :integer          not null, primary key\n#  additional_resources          :json             not null\n#  announced_at                  :datetime\n#  date                          :date             indexed, indexed => [video_provider]\n#  description                   :text             default(\"\"), not null\n#  duration_in_seconds           :integer\n#  end_seconds                   :integer\n#  external_player               :boolean          default(FALSE), not null\n#  external_player_url           :string           default(\"\"), not null\n#  kind                          :string           default(\"talk\"), not null, indexed\n#  language                      :string           default(\"en\"), not null\n#  like_count                    :integer          default(0)\n#  meta_talk                     :boolean          default(FALSE), not null\n#  original_title                :string           default(\"\"), not null\n#  published_at                  :datetime\n#  slides_url                    :string\n#  slug                          :string           default(\"\"), not null, indexed\n#  start_seconds                 :integer\n#  summarized_using_ai           :boolean          default(TRUE), not null\n#  summary                       :text             default(\"\"), not null\n#  thumbnail_lg                  :string           default(\"\"), not null\n#  thumbnail_md                  :string           default(\"\"), not null\n#  thumbnail_sm                  :string           default(\"\"), not null\n#  thumbnail_xl                  :string           default(\"\"), not null\n#  thumbnail_xs                  :string           default(\"\"), not null\n#  title                         :string           default(\"\"), not null, indexed\n#  video_availability_checked_at :datetime\n#  video_provider                :string           default(\"youtube\"), not null, indexed => [date]\n#  video_unavailable_at          :datetime\n#  view_count                    :integer          default(0)\n#  youtube_thumbnail_checked_at  :datetime\n#  created_at                    :datetime         not null\n#  updated_at                    :datetime         not null, indexed\n#  event_id                      :integer          indexed\n#  parent_talk_id                :integer          indexed\n#  static_id                     :string           not null, uniquely indexed\n#  video_id                      :string           default(\"\"), not null\n#\n# Indexes\n#\n#  index_talks_on_date                     (date)\n#  index_talks_on_event_id                 (event_id)\n#  index_talks_on_kind                     (kind)\n#  index_talks_on_parent_talk_id           (parent_talk_id)\n#  index_talks_on_slug                     (slug)\n#  index_talks_on_static_id                (static_id) UNIQUE\n#  index_talks_on_title                    (title)\n#  index_talks_on_updated_at               (updated_at)\n#  index_talks_on_video_provider_and_date  (video_provider,date)\n#\n# Foreign Keys\n#\n#  event_id        (event_id => events.id)\n#  parent_talk_id  (parent_talk_id => talks.id)\n#\n# rubocop:enable Layout/LineLength\nclass Talk < ApplicationRecord\n  include Rollupable\n  include Sluggable\n  include Suggestable\n  include Watchable\n\n  include Talk::SQLiteFTSSearchable\n  include Talk::TypesenseSearchable\n\n  configure_slug(attribute: :title, auto_suffix_on_collision: true)\n\n  # associations\n  belongs_to :event, optional: true, counter_cache: :talks_count, touch: true\n  belongs_to :parent_talk, optional: true, class_name: \"Talk\", foreign_key: :parent_talk_id\n\n  has_many :child_talks, class_name: \"Talk\", foreign_key: :parent_talk_id, dependent: :destroy\n  has_many :child_talks_speakers, -> { distinct }, through: :child_talks, source: :users, class_name: \"User\"\n  has_many :kept_child_talks_speakers, -> { distinct }, through: :child_talks, source: :kept_speakers,\n    class_name: \"User\"\n  # User associations (for merged Speaker functionality)\n  has_many :user_talks, dependent: :destroy, inverse_of: :talk, foreign_key: :talk_id\n  has_many :kept_user_talks, -> { kept }, dependent: :destroy, inverse_of: :talk, foreign_key: :talk_id,\n    class_name: \"UserTalk\"\n  has_many :users, through: :user_talks, inverse_of: :talks\n  has_many :speakers, -> { where(\"users.talks_count > 0\") }, through: :user_talks, inverse_of: :talks, source: :user\n  has_many :kept_speakers, -> { where(\"users.talks_count > 0\") }, through: :kept_user_talks, inverse_of: :talks,\n    class_name: \"User\", source: :user\n\n  has_many :talk_topics, dependent: :destroy\n  has_many :topics, through: :talk_topics\n  has_many :approved_topics, -> { approved }, through: :talk_topics, source: :topic, inverse_of: :talks\n\n  has_many :watch_list_talks, dependent: :destroy\n  has_many :watch_lists, through: :watch_list_talks\n\n  has_many :aliases, as: :aliasable, dependent: :destroy\n\n  has_one :talk_transcript, class_name: \"Talk::Transcript\", dependent: :destroy\n  accepts_nested_attributes_for :talk_transcript\n  delegate :transcript, :raw_transcript, :enhanced_transcript, to: :talk_transcript, allow_nil: true\n\n  # associated objects\n  has_object :agents\n  has_object :downloader\n  has_object :thumbnails\n  has_object :similar_recommender\n\n  # validations\n  validates :title, presence: true\n  validates :language, presence: true,\n    inclusion: {in: Language.alpha2_codes, message: \"%{value} is not a valid IS0-639 alpha2 code\"}\n\n  validates :date, presence: true\n  # validates :published_at, presence: true, if: :published? # TODO: enable\n  validate :parent_talk_id_cannot_be_self\n\n  # delegates\n  delegate :name, to: :event, prefix: true, allow_nil: true\n\n  # callbacks\n  before_validation :set_kind, if: -> { !kind_changed? }\n\n  WATCHABLE_PROVIDERS = [\"youtube\", \"mp4\", \"vimeo\"]\n\n  KIND_LABELS = {\n    \"keynote\" => \"Keynote\",\n    \"talk\" => \"Talk\",\n    \"lightning_talk\" => \"Lightning Talk\",\n    \"panel\" => \"Panel\",\n    \"workshop\" => \"Workshop\",\n    \"gameshow\" => \"Gameshow\",\n    \"podcast\" => \"Podcast\",\n    \"q_and_a\" => \"Q&A\",\n    \"discussion\" => \"Discussion\",\n    \"fireside_chat\" => \"Fireside Chat\",\n    \"interview\" => \"Interview\",\n    \"award\" => \"Award\",\n    \"demo\" => \"Demo\"\n  }.freeze\n\n  # enums\n  enum :video_provider, %w[youtube mp4 vimeo scheduled not_published not_recorded parent children].index_by(&:itself)\n\n  attribute :kind, :string\n  enum :kind,\n    %w[keynote talk lightning_talk panel workshop gameshow podcast q_and_a discussion fireside_chat\n      interview award demo].index_by(&:itself)\n\n  def self.speaker_role_titles\n    {\n      keynote: \"Keynote Speaker\",\n      talk: \"Speaker\",\n      lightning_talk: \"Lightning Talk Speaker\",\n      panel: \"Panelist\",\n      discussion: \"Panelist\",\n      gameshow: \"Game Show Host\",\n      workshop: \"Workshop Instructor\",\n      podcast: \"Podcast Host/Participant\",\n      q_and_a: \"Q&A Host/Participant\",\n      fireside_chat: \"Fireside Chat Host/Participant\",\n      interview: \"Interviewer/Interviewee\",\n      award: \"Award Presenter/Winner\",\n      demo: \"Demo Speaker\"\n    }\n  end\n\n  def self.find_by_slug_or_alias(slug)\n    return nil if slug.blank?\n\n    talk = find_by(slug: slug)\n    return talk if talk\n\n    alias_record = ::Alias.find_by(aliasable_type: \"Talk\", slug: slug)\n    alias_record&.aliasable\n  end\n\n  def formatted_kind\n    KIND_LABELS[kind] || raise(\"`#{kind}` not defined in `Talk::KIND_LABELS`\")\n  end\n\n  # attributes\n  attribute :video_provider, default: :youtube\n\n  # jobs\n  performs :update_from_yml_metadata!\n  performs :fetch_and_update_raw_transcript!, retries: 3\n  performs :fetch_duration_from_youtube!\n\n  # normalization\n  normalizes :language, apply_to_nil: true, with: ->(language) do\n    language.present? ? Language.find(language)&.alpha2 : Language::DEFAULT\n  end\n\n  # ensure that during the reindex process the associated records are eager loaded\n  scope :without_raw_transcript, -> {\n    joins(:talk_transcript)\n      .where(%(\n        talk_transcripts.raw_transcript IS NULL\n        OR talk_transcripts.raw_transcript = ''\n        OR talk_transcripts.raw_transcript = '[]'\n      ))\n  }\n  scope :with_raw_transcript, -> {\n    joins(:talk_transcript)\n      .where(%(\n        talk_transcripts.raw_transcript IS NOT NULL\n        AND talk_transcripts.raw_transcript != '[]'\n      ))\n  }\n  scope :without_enhanced_transcript,\n    -> {\n      joins(:talk_transcript)\n        .where(%(\n          talk_transcripts.enhanced_transcript IS NULL\n          OR talk_transcripts.enhanced_transcript = ''\n          OR talk_transcripts.enhanced_transcript = '[]'\n        ))\n    }\n  scope :with_enhanced_transcript, -> {\n    joins(:talk_transcript)\n      .where(%(\n        talk_transcripts.enhanced_transcript IS NOT NULL\n        AND talk_transcripts.enhanced_transcript != '[]'\n      ))\n  }\n  scope :with_summary, -> { where(\"summary IS NOT NULL AND summary != ''\") }\n  scope :without_summary, -> { where(\"summary IS NULL OR summary = ''\") }\n  scope :with_duration, -> { where.not(duration_in_seconds: nil) }\n  scope :without_duration, -> { where(duration_in_seconds: nil) }\n  scope :without_topics, -> { where.missing(:talk_topics) }\n  scope :with_topics, -> { joins(:talk_topics) }\n  scope :with_speakers, -> { joins(:user_talks).distinct }\n  scope :for_topic, ->(topic_slug) { joins(:topics).where(topics: {slug: topic_slug}) }\n  scope :for_speaker, ->(speaker_slug) { joins(:users).where(users: {slug: speaker_slug}) }\n  scope :for_event, ->(event_slug) { joins(:event).where(events: {slug: event_slug}) }\n  scope :scheduled, -> { where(video_provider: \"scheduled\") }\n  scope :watchable, -> { where(video_provider: WATCHABLE_PROVIDERS) }\n  scope :youtube, -> { where(video_provider: \"youtube\") }\n  scope :video_available, -> { watchable.where(video_unavailable_at: nil) }\n  scope :video_unavailable, -> { watchable.where.not(video_unavailable_at: nil) }\n  scope :upcoming, -> { where(date: Date.today...) }\n  scope :today, -> { where(date: Date.today) }\n  scope :past, -> { where(date: ...Date.today) }\n\n  def managed_by?(visiting_user)\n    return false unless visiting_user.present?\n    return true if visiting_user.admin?\n\n    users.exists?(id: visiting_user.id)\n  end\n\n  def published?\n    video_provider.in?(WATCHABLE_PROVIDERS) || parent_talk&.published?\n  end\n\n  def video_available?\n    published? && video_unavailable_at.blank?\n  end\n\n  def video_unavailable?\n    published? && video_unavailable_at.present?\n  end\n\n  def check_video_availability!\n    return unless youtube?\n\n    available = YouTube::Video.new.available?(video_id)\n\n    if available\n      update_columns(\n        video_unavailable_at: nil,\n        video_availability_checked_at: Time.current,\n        updated_at: Time.current\n      )\n    else\n      update_columns(\n        video_unavailable_at: video_unavailable_at || Time.current,\n        video_availability_checked_at: Time.current,\n        updated_at: Time.current\n      )\n    end\n\n    available\n  end\n\n  def validate_thumbnail!\n    return unless youtube?\n\n    thumbnail = YouTube::Thumbnail.new(video_id)\n    updates = {youtube_thumbnail_checked_at: Time.current}\n\n    if (xl_url = thumbnail.best_url_for(:thumbnail_xl))\n      updates[:thumbnail_xl] = xl_url\n    end\n\n    if (lg_url = thumbnail.best_url_for(:thumbnail_lg))\n      updates[:thumbnail_lg] = lg_url\n    end\n\n    update!(updates)\n  end\n\n  def to_meta_tags\n    {\n      title: title,\n      description: description,\n      og: {\n        title: title,\n        type: :website,\n        image: {\n          _: thumbnail_xl,\n          alt: title\n        },\n        description: description,\n        site_name: \"RubyEvents.org\"\n      },\n      twitter: {\n        card: \"summary_large_image\",\n        site: \"@rubyevents_org\",\n        title: title,\n        description: description,\n        image: {\n          src: thumbnail_xl\n        }\n      }\n    }\n  end\n\n  def thumbnail_xs\n    thumbnail(:thumbnail_xs)\n  end\n\n  def thumbnail_sm\n    thumbnail(:thumbnail_sm)\n  end\n\n  def thumbnail_md\n    thumbnail(:thumbnail_md)\n  end\n\n  def thumbnail_lg\n    thumbnail(:thumbnail_lg)\n  end\n\n  def thumbnail_xl\n    thumbnail(:thumbnail_xl)\n  end\n\n  def thumbnail_classes\n    static_metadata.try(:[], \"thumbnail_classes\") || \"\"\n  end\n\n  def fallback_thumbnail\n    Router.image_path(\"events/default/poster.webp\")\n  end\n\n  def thumbnail_url(size:, request:)\n    url = thumbnail(size)\n\n    if url.starts_with?(\"http\")\n      return url\n    end\n\n    \"#{request.protocol}#{request.host}:#{request.port}/#{url}\"\n  end\n\n  def thumbnail(size = :thumbnail_lg)\n    if self[size].present?\n      return self[size] if self[size].start_with?(\"https://\")\n\n      if Rails.application.assets.load_path.find(self[size])\n        return Router.image_path(self[size])\n      end\n    end\n\n    if Rails.application.assets.load_path.find(\"thumbnails/#{video_id}.webp\")\n      return Router.image_path(\"thumbnails/#{video_id}.webp\")\n    end\n\n    if vimeo?\n      vimeo = {\n        thumbnail_xs: \"_small\",\n        thumbnail_sm: \"_small\",\n        thumbnail_md: \"_medium\",\n        thumbnail_lg: \"_large\",\n        thumbnail_xl: \"_large\"\n      }\n\n      return \"https://vumbnail.com/#{video_id}#{vimeo[size]}.jpg\"\n    end\n\n    if youtube? && video_available?\n      youtube = {\n        thumbnail_xs: \"default\",\n        thumbnail_sm: \"mqdefault\",\n        thumbnail_md: \"hqdefault\",\n        thumbnail_lg: \"sddefault\",\n        thumbnail_xl: \"maxresdefault\"\n      }\n\n      return \"https://i.ytimg.com/vi/#{video_id}/#{youtube[size]}.jpg\"\n    end\n\n    if video_provider == \"parent\" && parent_talk.present?\n      return parent_talk.thumbnail(size)\n    end\n\n    if event && Rails.application.assets.load_path.find(event.poster_image_path)\n      return Router.image_path(event.poster_image_path)\n    end\n\n    fallback_thumbnail\n  end\n\n  def external_player_utm_params\n    {\n      utm_source: \"rubyevents.org\",\n      utm_medium: \"referral\",\n      utm_campaign: event.slug,\n      utm_content: slug\n    }\n  end\n\n  def external_player_url\n    uri = URI.parse(self[:external_player_url].presence || provider_url)\n\n    existing_params = URI.decode_www_form(uri.query || \"\").to_h\n    updated_params = existing_params.merge(external_player_utm_params)\n\n    uri.query = URI.encode_www_form(updated_params)\n\n    uri.to_s\n  end\n\n  def provider_url\n    case video_provider\n    when \"youtube\"\n      \"https://www.youtube.com/watch?v=#{video_id}\"\n    when \"mp4\"\n      video_id\n    when \"vimeo\"\n      \"https://vimeo.com/video/#{video_id}\"\n    when \"parent\"\n      timestamp = \"\"\n\n      if parent_talk.video_provider == \"vimeo\"\n        timestamp = start_seconds ? \"#t=#{start_seconds}\" : \"\"\n      elsif parent_talk.video_provider == \"youtube\"\n        timestamp = start_seconds ? \"&t=#{start_seconds}\" : \"\"\n      end\n\n      \"#{parent_talk.provider_url}#{timestamp}\"\n    else\n      \"#\"\n    end\n  end\n\n  def related_talks(limit: 6)\n    ids = Rails.cache.fetch([\"talk_recommendations\", id, limit], expires_in: 1.week) do\n      Talk.order(\"RANDOM()\").excluding(self).limit(limit).ids\n    end\n\n    Talk.includes(event: :series).where(id: ids)\n  end\n\n  def formatted_date\n    I18n.l(date, default: \"unknown\")\n  end\n\n  def formatted_duration\n    Duration.seconds_to_formatted_duration(duration)\n  end\n\n  def duration\n    return nil if start_seconds.blank? || end_seconds.blank?\n\n    ActiveSupport::Duration.build(end_seconds - start_seconds)\n  end\n\n  def speakers\n    return super unless meta_talk\n\n    child_talks_speakers\n  end\n\n  def feedback_allowed?\n    speakers.all?(&:feedback_enabled?)\n  end\n\n  def feedback_allowed_for?(user)\n    return false unless feedback_allowed?\n    return true if user.blank?\n\n    !speaker?(user)\n  end\n\n  def speaker?(user)\n    return false if user.blank?\n\n    speakers.exists?(id: user.id)\n  end\n\n  def speaker_names\n    speakers.pluck(:name).join(\" \")\n  end\n\n  def event_names\n    return \"\" unless event\n\n    names = [event.name]\n    names += event.slug_aliases.pluck(:name)\n\n    if event.series\n      names << event.series.name\n      names += event.series.aliases.pluck(:name)\n    end\n\n    names.compact.uniq.join(\" \")\n  end\n\n  def language_name\n    Language.by_code(language)\n  end\n\n  def location\n    static_metadata.try(:location) || event&.location\n  end\n\n  def to_location\n    @to_location ||= if static_metadata&.location.present?\n      Location.from_string(static_metadata.location)\n    else\n      event&.to_location || Location.new\n    end\n  end\n\n  def slug_candidates\n    @slug_candidates ||= [\n      static_metadata.slug&.parameterize,\n      title.parameterize,\n      [title.parameterize, event&.name&.parameterize].compact.reject(&:blank?).join(\"-\"),\n      [title.parameterize, language&.parameterize].compact.reject(&:blank?).join(\"-\"),\n      [title.parameterize, event&.name&.parameterize, language&.parameterize].compact.reject(&:blank?).join(\"-\"),\n      [date.to_s.parameterize, title.parameterize].compact.reject(&:blank?).join(\"-\"),\n      [title.parameterize, *speakers.map(&:slug)].compact.reject(&:blank?).join(\"-\"),\n      [static_metadata.raw_title.parameterize].compact.reject(&:blank?).join(\"-\"),\n      [date.to_s.parameterize, static_metadata.raw_title.parameterize].compact.reject(&:blank?).join(\"-\")\n    ].reject(&:blank?).uniq\n  end\n\n  def unused_slugs\n    used_slugs = Talk.excluding(self).where(slug: slug_candidates).pluck(:slug)\n    used_alias_slugs = ::Alias.where(aliasable_type: \"Talk\", slug: slug_candidates)\n      .where.not(aliasable_id: id)\n      .pluck(:slug)\n    slug_candidates - used_slugs - used_alias_slugs\n  end\n\n  def event_name\n    return event.name unless event.meetup?\n\n    static_metadata.try(\"event_name\") || event.name\n  end\n\n  def fetch_and_update_raw_transcript!\n    youtube_transcript = YouTube::Transcript.get(video_id)\n    transcript = talk_transcript || Talk::Transcript.new(talk: self)\n\n    if youtube_transcript.present?\n      transcript.update!(raw_transcript: ::Transcript.create_from_youtube_transcript(youtube_transcript))\n    end\n  end\n\n  def fetch_duration_from_youtube!\n    return unless youtube?\n\n    duration_seconds = YouTube::Video.new.duration(video_id)\n    update duration_in_seconds: duration_seconds\n  end\n\n  def update_from_yml_metadata!(event: nil)\n    if event.blank?\n      event = Event.find_by(name: static_metadata.event_name)\n\n      if event.nil?\n        puts \"No event found! Video ID: #{video_id}, Event: #{static_metadata.event_name}\"\n        return\n      end\n    end\n\n    no_speakers = Array.wrap(static_metadata.speakers).none?\n    no_talks = Array.wrap(static_metadata.talks).none?\n    meta_talk = static_metadata.meta_talk?\n\n    if static_metadata.blank? || (no_speakers && no_talks && !meta_talk)\n      puts \"No speakers for Video ID: #{video_id}\"\n      return\n    end\n\n    assign_attributes(\n      event: event,\n      static_id: static_metadata.id,\n      title: static_metadata.title,\n      original_title: static_metadata.original_title || \"\",\n      description: static_metadata.description,\n      date: static_metadata.try(:date) || parent_talk&.static_metadata.try(:date),\n      published_at: static_metadata.try(:published_at) || parent_talk&.static_metadata.try(:published_at),\n      announced_at: static_metadata.try(:announced_at) || parent_talk&.static_metadata.try(:announced_at),\n      thumbnail_xs: static_metadata[\"thumbnail_xs\"] || \"\",\n      thumbnail_sm: static_metadata[\"thumbnail_sm\"] || \"\",\n      thumbnail_md: static_metadata[\"thumbnail_md\"] || \"\",\n      thumbnail_lg: static_metadata[\"thumbnail_lg\"] || \"\",\n      thumbnail_xl: static_metadata[\"thumbnail_xl\"] || \"\",\n      language: static_metadata.language || Language::DEFAULT,\n      slides_url: static_metadata.slides_url,\n      additional_resources: static_metadata[\"additional_resources\"] || [],\n      video_id: static_metadata.video_id,\n      video_provider: static_metadata.video_provider,\n      external_player: static_metadata.external_player || false,\n      external_player_url: static_metadata.external_player_url || \"\",\n      meta_talk: static_metadata.meta_talk?,\n      start_seconds: static_metadata.start_cue_in_seconds,\n      end_seconds: static_metadata.end_cue_in_seconds\n    )\n\n    self.kind = static_metadata.kind if static_metadata.try(:kind).present?\n\n    self.speakers = Array.wrap(static_metadata.speakers).reject(&:blank?).map { |speaker_name|\n      User.find_by_name_or_alias(speaker_name.strip) ||\n        User.find_by(slug: speaker_name.parameterize) ||\n        User.find_or_create_by(name: speaker_name.strip)\n    }\n\n    new_slug = unused_slugs.first\n\n    if slug.present? && slug != new_slug\n      aliases.find_or_create_by!(name: title, slug: slug)\n    end\n\n    self.slug = new_slug\n\n    save!\n  end\n\n  def static_metadata\n    @static_metadata ||= Static::Video.find_by_static_id(static_id)\n  end\n\n  def suggestion_summary\n    <<~HEREDOC\n      Talk: #{title} (#{date})\n      by #{speakers.map(&:name).to_sentence}\n      at #{event.name}\n    HEREDOC\n  end\n\n  def set_kind\n    if static_metadata && static_metadata.kind.present?\n      unless static_metadata.kind.in?(Talk.kinds.keys)\n        puts %(WARN: \"#{title}\" has an unknown talk kind defined in #{static_metadata.__file_path})\n      end\n\n      self.kind = static_metadata.kind\n      return\n    end\n\n    self.kind = case title\n    when /^(keynote:|keynote|opening\\ keynote:|opening\\ keynote|closing\\ keynote:|closing\\ keynote).*/i\n      :keynote\n    when /^(lightning\\ talk:|lightning\\ talk|lightning\\ talks|micro\\ talk:|micro\\ talk).*/i\n      :lightning_talk\n    when /.*(panel:|panel).*/i\n      :panel\n    when /^(workshop:|workshop).*/i\n      :workshop\n    when /^(gameshow|game\\ show|gameshow:|game\\ show:).*/i\n      :gameshow\n    when /^(podcast:|podcast\\ recording:|live\\ podcast:).*/i\n      :podcast\n    when /.*(q&a|q&a:|q&a\\ with|ruby\\ committers\\ vs\\ the\\ world|ruby\\ committers\\ and\\ the\\ world).*/i,\n        /.*(AMA)$/,\n        /^(AMA:)/\n      :q_and_a\n    when /^(fishbowl:|fishbowl\\ discussion:|discussion:|discussion).*/i\n      :discussion\n    when /^(fireside\\ chat:|fireside\\ chat).*/i\n      :fireside_chat\n    when /^(award:|award\\ show|ruby\\ heroes\\ awards|ruby\\ heroes\\ award|rails\\ luminary).*/i\n      :award\n    when /^(interview:|interview\\ with).*/i\n      :interview\n    when /^(demo:|demo\\ |Startup\\ Demo:).*/i, /.*(demo)$/i\n      :demo\n    else\n      :talk\n    end\n  end\n\n  def to_mobile_json(request)\n    {\n      id: id,\n      title: title,\n      duration_in_seconds: duration_in_seconds,\n      slug: slug,\n      event_name: event_name,\n      thumbnail_url: thumbnail_url(size: :thumbnail_sm, request: request),\n      speakers: speakers.map { |speaker| speaker.to_mobile_json(request) },\n      url: Router.talk_url(self, host: \"#{request.protocol}#{request.host}:#{request.port}\")\n    }\n  end\n\n  private\n\n  def parent_talk_id_cannot_be_self\n    return if parent_talk_id.nil?\n\n    if parent_talk_id == id\n      errors.add(:parent_talk_id, \"cannot be the same as the talk itself\")\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/talk_topic.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: talk_topics\n# Database name: primary\n#\n#  id         :integer          not null, primary key\n#  created_at :datetime         not null\n#  updated_at :datetime         not null\n#  talk_id    :integer          not null, indexed, uniquely indexed => [topic_id]\n#  topic_id   :integer          not null, indexed, uniquely indexed => [talk_id]\n#\n# Indexes\n#\n#  index_talk_topics_on_talk_id               (talk_id)\n#  index_talk_topics_on_topic_id              (topic_id)\n#  index_talk_topics_on_topic_id_and_talk_id  (topic_id,talk_id) UNIQUE\n#\n# Foreign Keys\n#\n#  talk_id   (talk_id => talks.id)\n#  topic_id  (topic_id => topics.id)\n#\n# rubocop:enable Layout/LineLength\nclass TalkTopic < ApplicationRecord\n  belongs_to :talk\n  belongs_to :topic, counter_cache: :talks_count\n\n  validates :talk_id, uniqueness: {scope: :topic_id}\n\n  def reset_topic_counter_cache\n    Topic.reset_counters(topic_id, :talks)\n  end\nend\n"
  },
  {
    "path": "app/models/template.rb",
    "content": "class Template\n  include ActiveModel::Model\n  include ActiveModel::Attributes\n  include ActiveModel::Validations\n\n  VIDEO_PROVIDERS = [\n    \"YouTube\", \"Vimeo, MP4\", \"Not Published\", \"Not Recorded\", \"Scheduled\"\n  ]\n\n  attribute :title, :string\n  attribute :raw_title, :string\n  attribute :event_name, :string\n  attribute :date, :date, default: Date.current\n  attribute :announced_at, :date\n  attribute :published_at, :date\n  attribute :speakers, default: \"\"\n  attribute :video_id, :string\n  attribute :video_provider, :string, default: \"youtube\"\n  attribute :language, :string, default: \"english\"\n  attribute :track, :string\n  attribute :slides_url, :string\n\n  attribute :thumbnail_xs, :string\n  attribute :thumbnail_sm, :string\n  attribute :thumbnail_md, :string\n  attribute :thumbnail_lg, :string\n  attribute :external_player, :boolean, default: false\n  attribute :external_player_url, :string\n\n  attribute :start_cue, :time\n  attribute :end_cue, :time\n  attribute :description, :string\n\n  attr_accessor :children\n\n  validates :title, presence: true\n  validates :event_name, presence: true\n  validates :date, presence: true\n\n  def initialize(attributes = {})\n    @children = []\n    super\n  end\n\n  def persisted?\n    false\n  end\n\n  def to_param\n    event_name\n  end\n\n  def children_attributes=(attributes)\n    attributes.each do |i, child_params|\n      @children.push(Template.new(child_params))\n    end\n  end\n\n  def valid?\n    parent_valid = super\n    children_valid = children.map(&:valid?).all?\n    children.each do |ol|\n      ol.errors.each do |attribute, error|\n        errors.add(:children_attributes, error)\n      end\n    end\n    errors[:children_attributes].uniq!\n    parent_valid && children_valid\n  end\n\n  def has_children?\n    children.any?\n  end\n\n  def to_hash\n    hash = attributes.dup\n    hash[\"talks\"] = children.map(&:to_hash) if children.any?\n    transform_attributes(hash)\n  end\n\n  def transform_attributes(hash)\n    %w[date announced_at published_at].each do |date_field|\n      hash[date_field] = hash[date_field]&.strftime(\"%Y-%m-%d\")\n    end\n    hash[\"video_provider\"] = has_children? ? \"children\" : hash[\"video_provider\"]\n    hash[\"start_cue\"] = time_to_cue(hash[\"start_cue\"])\n    hash[\"end_cue\"] = time_to_cue(hash[\"end_cue\"])\n    hash[\"speakers\"] = parse_speakers(hash[\"speakers\"])\n    hash.compact_blank\n  end\n\n  def to_yaml\n    Array.wrap(to_hash).to_yaml.sub(\"---\\n\", \"\")\n  end\n\n  private\n\n  def time_to_cue(time)\n    return nil if time.blank?\n\n    time.strftime(\"%H:%M:%S\")\n  end\n\n  def parse_speakers(data)\n    speakers.split(\",\").map(&:strip).reject(&:blank?) if speakers.present?\n  end\nend\n"
  },
  {
    "path": "app/models/todo.rb",
    "content": "# frozen_string_literal: true\n\nclass Todo < Data.define(:file, :line, :column, :content)\n  GITHUB_REPO = \"https://github.com/rubyevents/rubyevents\"\n\n  def self.all\n    for_path(Rails.root.join(\"data\"))\n  end\n\n  def self.for_path(path, prefix: nil)\n    result = Grepfruit.search(\n      regex: /TODO|FIXME/,\n      path: path.to_s,\n      include: [\"*.yml\", \"*.yaml\"],\n      truncate: 200\n    )\n\n    Array.wrap(result[:matches]).map do |match|\n      file = prefix ? \"#{prefix}/#{match[:file]}\" : match[:file]\n\n      new(\n        file: file,\n        line: match[:line],\n        column: match[:column],\n        content: match[:content]\n      )\n    end\n  rescue\n    # Ignore errors we don't want to raise if the directory is not found\n    []\n  end\n\n  def url\n    if Rails.env.development? && ActiveSupport::Editor.current\n      local_url\n    else\n      github_url\n    end\n  end\n\n  def git_ref\n    Rails.app.revision || \"main\"\n  end\n\n  def github_url\n    result = \"#{GITHUB_REPO}/blob/#{git_ref}/data/#{file}\"\n    result += \"#L#{line}\" if line\n\n    result\n  end\n\n  def local_url\n    path = Rails.root.join(\"data\", file).to_s\n\n    ActiveSupport::Editor.current.url_for(path, line || 1)\n  end\n\n  def normalized_content\n    content\n      .to_s\n      .gsub(/^#\\s*(TODO|FIXME):?\\s*/i, \"\")\n      .gsub(/^(TODO|FIXME):?\\s*/i, \"\")\n      .strip\n  end\n\n  def series_slug\n    file.split(\"/\").first\n  end\n\n  def event_slug\n    parts = file.split(\"/\")\n\n    (parts.size >= 2) ? parts[1] : nil\n  end\nend\n"
  },
  {
    "path": "app/models/topic/agents.rb",
    "content": "class Topic::Agents < ActiveRecord::AssociatedObject\n  performs retries: 2 do\n    limits_concurrency to: 4, key: \"openai_api\", duration: 1.hour\n  end\n\n  performs def find_talks\n    candidate_talks = find_candidate_talks\n    existing_talk_ids = topic.talk_ids\n\n    new_candidates = candidate_talks.reject { |talk| existing_talk_ids.include?(talk.id) }\n\n    return if new_candidates.empty?\n\n    confirmed_talks = filter_with_ai(new_candidates)\n\n    return if confirmed_talks.empty?\n\n    topic.talks << confirmed_talks\n\n    Rails.logger.info \"[Topic::Agents] Assigned #{confirmed_talks.size} talks to topic '#{topic.name}'\"\n\n    confirmed_talks\n  end\n\n  private\n\n  def find_candidate_talks\n    variants = name_variants\n    talk_ids = Set.new\n\n    variants.each do |variant|\n      Talk.ft_search(variant).pluck(:id).each { |id| talk_ids << id }\n    end\n\n    Talk.where(id: talk_ids.to_a)\n  end\n\n  def name_variants\n    name = topic.name\n\n    variants = [\n      name,\n      name.delete(\" \"),\n      name.tr(\" \", \"-\"),\n      name.tr(\" \", \"_\"),\n      name.tr(\"-\", \" \"),\n      name.delete(\"-\"),\n      name.tr(\"-\", \"_\"),\n      name.tr(\"_\", \" \"),\n      name.tr(\"_\", \"-\"),\n      name.delete(\"_\")\n    ]\n\n    variants.map(&:downcase).uniq\n  end\n\n  def filter_with_ai(candidates)\n    return [] if candidates.empty?\n\n    response = client.chat(\n      parameters: Prompts::Topic::MatchTalks.new(topic: topic, talks: candidates).to_params,\n      resource: topic,\n      task_name: \"match_talks\"\n    )\n\n    raw_response = JSON.repair(response.dig(\"choices\", 0, \"message\", \"content\"))\n    result = JSON.parse(raw_response)\n\n    matching_talk_ids = result[\"matches\"]\n      .select { |m| m[\"matches\"] && m[\"confidence\"] == \"high\" }\n      .map { |m| m[\"talk_id\"] }\n\n    candidates.select { |talk| matching_talk_ids.include?(talk.id) }\n  rescue => e\n    Rails.logger.error \"[Topic::Agents] AI filtering failed for topic '#{topic.name}': #{e.message}\"\n    []\n  end\n\n  def client\n    @client ||= LLM::Client.new\n  end\nend\n"
  },
  {
    "path": "app/models/topic/gem_info.rb",
    "content": "class Topic::GemInfo < ActiveRecord::AssociatedObject\n  def gems\n    topic.topic_gems\n  end\n\n  def gem?\n    gems.any?\n  end\n\n  def primary_gem\n    gems.first\n  end\nend\n"
  },
  {
    "path": "app/models/topic/typesense_searchable.rb",
    "content": "# frozen_string_literal: true\n\nmodule Topic::TypesenseSearchable\n  extend ActiveSupport::Concern\n\n  included do\n    include ::Typesense\n\n    typesense enqueue: :trigger_typesense_job, if: :should_index?, disable_indexing: -> { Search::Backend.skip_indexing } do\n      attributes :name, :description, :slug\n      attribute :status\n\n      attribute :talks_count\n\n      attribute :published\n\n      attribute :talk_titles do\n        talks.limit(10).pluck(:title)\n      end\n\n      attribute :talk_slugs do\n        talks.limit(50).pluck(:slug)\n      end\n\n      predefined_fields [\n        {\"name\" => \"name\", \"type\" => \"string\"},\n        {\"name\" => \"description\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"slug\", \"type\" => \"string\"},\n\n        {\"name\" => \"status\", \"type\" => \"string\", \"facet\" => true},\n        {\"name\" => \"published\", \"type\" => \"bool\"},\n        {\"name\" => \"talks_count\", \"type\" => \"int32\"},\n\n        {\"name\" => \"talk_titles\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"talk_slugs\", \"type\" => \"string[]\", \"optional\" => true}\n      ]\n\n      default_sorting_field \"talks_count\"\n\n      multi_way_synonyms [\n        {\"rails-synonym\" => %w[rails ruby-on-rails rubyonrails ror]},\n        {\"hotwire-synonym\" => %w[hotwire turbo stimulus turbolinks]},\n        {\"testing-synonym\" => %w[testing tests test tdd bdd rspec minitest]},\n        {\"performance-synonym\" => %w[performance optimization speed fast profiling]},\n        {\"security-synonym\" => %w[security secure authentication authorization oauth]},\n        {\"api-synonym\" => %w[api apis rest restful graphql json]},\n        {\"database-synonym\" => %w[database db databases sql postgresql postgres mysql sqlite activerecord]},\n        {\"frontend-synonym\" => %w[frontend front-end javascript js typescript css html]},\n        {\"devops-synonym\" => %w[devops deployment deploy docker kubernetes ci cd]},\n        {\"gem-synonym\" => %w[gem gems rubygems library libraries]}\n      ]\n\n      token_separators %w[- _]\n    end\n  end\n\n  class_methods do\n    def trigger_typesense_job(record, remove)\n      TypesenseIndexJob.perform_later(record, remove ? \"typesense_remove_from_index!\" : \"typesense_index!\")\n    end\n\n    def typesense_search_topics(query, options = {})\n      query_by_fields = \"name,description\"\n\n      search_options = {\n        query_by_weights: \"10,3\",\n        per_page: options[:per_page] || 20,\n        page: options[:page] || 1,\n        highlight_full_fields: \"name\",\n        highlight_affix_num_tokens: 10\n      }\n\n      filters = []\n      filters << \"status:=approved\" unless options[:include_all_statuses]\n      filters << \"talks_count:>0\" unless options[:include_empty]\n\n      search_options[:filter_by] = filters.join(\" && \") if filters.any?\n\n      sort_options = {\n        \"talks\" => \"talks_count:desc\",\n        \"name\" => \"name:asc\",\n        \"relevance\" => \"_text_match:desc,talks_count:desc\"\n      }\n\n      search_options[:sort_by] = sort_options[options[:sort]] || sort_options[\"relevance\"]\n\n      search(query.presence || \"*\", query_by_fields, search_options)\n    end\n  end\n\n  private\n\n  def should_index?\n    approved? && (talks_count || 0) > 0 && canonical_id.nil?\n  end\nend\n"
  },
  {
    "path": "app/models/topic.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: topics\n# Database name: primary\n#\n#  id           :integer          not null, primary key\n#  description  :text\n#  name         :string           uniquely indexed\n#  published    :boolean          default(FALSE)\n#  slug         :string           default(\"\"), not null, indexed\n#  status       :string           default(\"pending\"), not null, indexed\n#  talks_count  :integer\n#  created_at   :datetime         not null\n#  updated_at   :datetime         not null\n#  canonical_id :integer          indexed\n#\n# Indexes\n#\n#  index_topics_on_canonical_id  (canonical_id)\n#  index_topics_on_name          (name) UNIQUE\n#  index_topics_on_slug          (slug)\n#  index_topics_on_status        (status)\n#\n# Foreign Keys\n#\n#  canonical_id  (canonical_id => topics.id)\n#\n# rubocop:enable Layout/LineLength\nclass Topic < ApplicationRecord\n  include Sluggable\n  include Topic::TypesenseSearchable\n\n  has_object :agents\n  has_object :gem_info\n\n  configure_slug(attribute: :name, auto_suffix_on_collision: false)\n\n  has_many :talk_topics\n  has_many :talks, through: :talk_topics\n  has_many :topic_gems, dependent: :destroy\n  belongs_to :canonical, class_name: \"Topic\", optional: true\n  has_many :aliases, class_name: \"Topic\", foreign_key: \"canonical_id\"\n\n  # validations\n  validates :name, presence: true, uniqueness: true\n  validates :canonical, exclusion: {in: ->(topic) { [topic] }, message: \"can't be itself\"}\n\n  # normalize attributes\n  normalizes :name, with: ->(name) { name.squish }\n\n  # scopes\n  scope :with_talks, -> { where(\"talks_count >= 1\") }\n  scope :without_talks, -> { where(talks_count: 0) }\n  scope :with_n_talk, ->(n) { where(\"talks_count = ?\", n) }\n\n  scope :canonical, -> { where(canonical_id: nil) }\n  scope :not_canonical, -> { where.not(canonical_id: nil) }\n\n  # enums\n  enum :status, %w[pending approved rejected duplicate].index_by(&:itself)\n\n  def self.create_from_list(topics, status: :pending)\n    topics.map { |topic|\n      slug = topic.parameterize\n      Topic.find_by(slug: slug)&.primary_topic || Topic.find_or_create_by(name: topic.squish) { |t| t.status = status }\n    }.uniq\n  end\n\n  def assign_canonical_topic!(canonical_topic:)\n    ActiveRecord::Base.transaction do\n      self.canonical = canonical_topic\n      save!\n\n      talk_topics.each do |talk_topic|\n        talk_topic.update(topic: canonical_topic)\n      end\n\n      # We need to destroy the remaining topics. They can be remaining topics given the unicity constraint\n      # on the talk_topics table. the update above swallows the error if the talk_topic duet exists already\n      TalkTopic.where(topic_id: id).destroy_all\n      duplicate!\n    end\n  end\n\n  def primary_topic\n    canonical || self\n  end\n\n  def to_meta_tags\n    {\n      title: name,\n      description: description,\n      og: {\n        title: name,\n        type: :website,\n        description: description,\n        site_name: \"RubyEvents.org\"\n      },\n      twitter: {\n        card: \"summary\",\n        title: name,\n        description: description\n      }\n    }\n  end\n\n  # enums state machine\n\n  def rejected!\n    ActiveRecord::Base.transaction do\n      update!(status: :rejected)\n      TalkTopic.where(topic_id: id).destroy_all\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/topic_gem.rb",
    "content": "# == Schema Information\n#\n# Table name: topic_gems\n# Database name: primary\n#\n#  id         :integer          not null, primary key\n#  gem_name   :string           not null, uniquely indexed => [topic_id]\n#  created_at :datetime         not null\n#  updated_at :datetime         not null\n#  topic_id   :integer          not null, indexed, uniquely indexed => [gem_name]\n#\n# Indexes\n#\n#  index_topic_gems_on_topic_id               (topic_id)\n#  index_topic_gems_on_topic_id_and_gem_name  (topic_id,gem_name) UNIQUE\n#\n# Foreign Keys\n#\n#  topic_id  (topic_id => topics.id)\n#\nclass TopicGem < ApplicationRecord\n  belongs_to :topic\n\n  validates :gem_name, presence: true, uniqueness: {scope: :topic_id}\n\n  def info\n    @info ||= Rails.cache.fetch(cache_key, expires_in: 7.days) do\n      fetch_gem_info\n    end\n  end\n\n  def downloads\n    info&.dig(\"downloads\")\n  end\n\n  def version\n    info&.dig(\"version\")\n  end\n\n  def version_created_at\n    date = info&.dig(\"version_created_at\")\n    Time.parse(date) if date.present?\n  rescue\n    nil\n  end\n\n  def authors\n    info&.dig(\"authors\")\n  end\n\n  def author_names\n    return [] unless authors.present?\n\n    authors.split(/,\\s*/)\n  end\n\n  def author_users\n    return {} unless author_names.any?\n\n    User.where(name: author_names).index_by(&:name)\n  end\n\n  def owners\n    @owners ||= Rails.cache.fetch(owners_cache_key, expires_in: 7.days) do\n      fetch_owners\n    end\n  end\n\n  def owner_handles\n    owners&.map { |o| o[\"handle\"] }&.compact || []\n  end\n\n  def owner_users\n    return [] unless owner_handles.any?\n\n    User.canonical.where(github_handle: owner_handles).order(talks_count: :desc)\n  end\n\n  def maintainers\n    # Combine owners (by github handle) and authors (by name), deduplicated\n    (owner_users.to_a + author_users.values).uniq.sort_by { |u| -u.talks_count }\n  end\n\n  def summary\n    info&.dig(\"info\")\n  end\n\n  def licenses\n    info&.dig(\"licenses\") || []\n  end\n\n  def license\n    licenses.first\n  end\n\n  def homepage_url\n    info&.dig(\"homepage_uri\")\n  end\n\n  def source_code_url\n    info&.dig(\"source_code_uri\")\n  end\n\n  def documentation_url\n    info&.dig(\"documentation_uri\")\n  end\n\n  def changelog_url\n    info&.dig(\"changelog_uri\")\n  end\n\n  def bug_tracker_url\n    info&.dig(\"bug_tracker_uri\")\n  end\n\n  def mailing_list_url\n    info&.dig(\"mailing_list_uri\")\n  end\n\n  def wiki_url\n    info&.dig(\"wiki_uri\")\n  end\n\n  def funding_url\n    info&.dig(\"funding_uri\")\n  end\n\n  def runtime_dependencies\n    info&.dig(\"dependencies\", \"runtime\") || []\n  end\n\n  def development_dependencies\n    info&.dig(\"dependencies\", \"development\") || []\n  end\n\n  def rubygems_url\n    \"https://rubygems.org/gems/#{gem_name}\"\n  end\n\n  def github_repo\n    url = source_code_url.presence || homepage_url\n    return nil unless url.present?\n\n    match = url.match(%r{github\\.com/([^/]+/[^/]+)})\n    match[1].sub(/\\.git$/, \"\").split(\"/tree/\").first if match\n  end\n\n  def github_url\n    return nil unless github_repo.present?\n\n    \"https://github.com/#{github_repo}\"\n  end\n\n  private\n\n  def fetch_gem_info\n    Gems.info(gem_name)\n  rescue => e\n    Rails.logger.error(\"Failed to fetch gem info for #{gem_name}: #{e.message}\")\n    nil\n  end\n\n  def fetch_owners\n    Gems.owners(gem_name)\n  rescue => e\n    Rails.logger.error(\"Failed to fetch owners for #{gem_name}: #{e.message}\")\n    []\n  end\n\n  def cache_key\n    \"topic_gem_info:#{id}:#{gem_name}\"\n  end\n\n  def owners_cache_key\n    \"topic_gem_owners:#{id}:#{gem_name}\"\n  end\nend\n"
  },
  {
    "path": "app/models/transcript.rb",
    "content": "class Transcript\n  include Enumerable\n\n  attr_reader :cues\n\n  def initialize(cues: [])\n    @cues = cues\n  end\n\n  def add_cue(cue)\n    @cues << cue\n  end\n\n  def to_h\n    @cues.map { |cue| cue.to_h }\n  end\n\n  def to_json\n    to_h.to_json\n  end\n\n  def to_text\n    @cues.map { |cue| cue.text }.join(\"\\n\\n\")\n  end\n\n  def to_vtt\n    vtt_content = \"WEBVTT\\n\\n\"\n    @cues.each_with_index do |cue, index|\n      vtt_content += \"#{index + 1}\\n\"\n      vtt_content += \"#{cue}\\n\\n\"\n    end\n    vtt_content\n  end\n\n  def presence\n    @cues.any? ? self : nil\n  end\n\n  def present?\n    @cues.any?\n  end\n\n  def each(&)\n    @cues.each(&)\n  end\n\n  class << self\n    def create_from_vtt(vtt_content)\n      transcript = Transcript.new\n      return transcript if vtt_content.blank?\n\n      # Remove WEBVTT header and any metadata lines\n      lines = vtt_content.lines.map(&:strip)\n\n      # Skip header lines (WEBVTT, Kind:, Language:, NOTE, etc.)\n      content_started = false\n      current_cue = nil\n      cue_lines = []\n\n      lines.each do |line|\n        # Skip empty lines at the beginning or between cues\n        if line.empty?\n          if current_cue && cue_lines.any?\n            text = cue_lines.join(\" \").gsub(/<[^>]*>/, \"\").strip # Remove HTML tags\n            transcript.add_cue(Cue.new(start_time: current_cue[:start], end_time: current_cue[:end], text: text))\n            current_cue = nil\n            cue_lines = []\n          end\n          next\n        end\n\n        # Skip WEBVTT header and metadata\n        next if line.start_with?(\"WEBVTT\")\n        next if line.start_with?(\"Kind:\")\n        next if line.start_with?(\"Language:\")\n        next if line.start_with?(\"NOTE\")\n        next if line.match?(/^\\d+$/) # Skip cue numbers\n\n        content_started = true\n\n        # Parse timestamp line (00:00:00.000 --> 00:00:05.000)\n        if line.include?(\"-->\")\n          # Extract timestamps, ignoring any position/alignment info after\n          match = line.match(/(\\d{2}:\\d{2}:\\d{2}[.,]\\d{3})\\s*-->\\s*(\\d{2}:\\d{2}:\\d{2}[.,]\\d{3})/)\n          if match\n            current_cue = {\n              start: match[1].tr(\",\", \".\"),\n              end: match[2].tr(\",\", \".\")\n            }\n          end\n        elsif current_cue\n          # This is a text line\n          cue_lines << line\n        end\n      end\n\n      # Add the last cue if present\n      if current_cue && cue_lines.any?\n        text = cue_lines.join(\" \").gsub(/<[^>]*>/, \"\").strip\n        transcript.add_cue(Cue.new(start_time: current_cue[:start], end_time: current_cue[:end], text: text))\n      end\n\n      transcript\n    end\n\n    def create_from_youtube_transcript(youtube_transcript)\n      transcript = Transcript.new\n      events = youtube_transcript.dig(\"actions\", 0, \"updateEngagementPanelAction\", \"content\", \"transcriptRenderer\", \"content\", \"transcriptSearchPanelRenderer\", \"body\", \"transcriptSegmentListRenderer\", \"initialSegments\") || []\n      events.each do |event|\n        segment = event[\"transcriptSegmentRenderer\"]\n        start_time = format_time(segment[\"startMs\"].to_i)\n        end_time = format_time(segment[\"endMs\"].to_i)\n        text = segment.dig(\"snippet\", \"runs\")&.map { |run| run[\"text\"] }&.join || \"\"\n        transcript.add_cue(Cue.new(start_time: start_time, end_time: end_time, text: text))\n      end\n      transcript\n    end\n\n    def create_from_json(json)\n      transcript = Transcript.new\n      json.map(&:symbolize_keys!)\n      json.each do |cue_hash|\n        transcript.add_cue(Cue.new(start_time: cue_hash[:start_time], end_time: cue_hash[:end_time], text: cue_hash[:text]))\n      end\n      transcript\n    end\n\n    def format_time(ms)\n      hours = ms / (1000 * 60 * 60)\n      minutes = (ms % (1000 * 60 * 60)) / (1000 * 60)\n      seconds = (ms % (1000 * 60)) / 1000\n      milliseconds = ms % 1000\n      format(\"%02d:%02d:%02d.%03d\", hours, minutes, seconds, milliseconds)\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/uk_nation.rb",
    "content": "class UKNation\n  attr_reader :slug, :state_code, :nation_name\n\n  def initialize(slug)\n    @slug = slug\n    data = Country::UK_NATIONS[slug]\n    @state_code = data[:code]\n    @nation_name = data[:name]\n  end\n\n  def self.find_by_code(code)\n    return nil if code.blank?\n\n    code_upper = code.upcase\n\n    nation_code = if code_upper.start_with?(\"GB-\")\n      code_upper.sub(\"GB-\", \"\")\n    else\n      code_upper\n    end\n\n    slug = Country::UK_NATIONS.find { |_, data| data[:code] == nation_code }&.first\n    slug ||= Country::UK_NATIONS.find { |_, data| data[:name].upcase == nation_code }&.first\n\n    slug ? new(slug) : nil\n  end\n\n  def name\n    nation_name\n  end\n\n  def alpha2\n    \"GB-#{state_code}\"\n  end\n\n  def alpha3\n    nil\n  end\n\n  def continent\n    @continent ||= Continent.europe\n  end\n\n  def continent_name\n    continent.name\n  end\n\n  def emoji_flag\n    \"\\u{1F1EC}\\u{1F1E7}\"\n  end\n\n  def path\n    Router.country_path(slug)\n  end\n\n  def past_path\n    Router.country_past_index_path(self)\n  end\n\n  def users_path\n    Router.country_users_path(self)\n  end\n\n  def meetups_path\n    Router.country_meetups_path(self)\n  end\n\n  def cities_path\n    Router.country_cities_path(self)\n  end\n\n  def stamps_path\n    Router.country_stamps_path(self)\n  end\n\n  def map_path\n    Router.country_map_index_path(self)\n  end\n\n  def has_routes?\n    true\n  end\n\n  def code\n    \"gb\"\n  end\n\n  def country_code\n    \"GB\"\n  end\n\n  def to_param\n    slug\n  end\n\n  def ==(other)\n    other.is_a?(UKNation) && slug == other.slug\n  end\n\n  def eql?(other)\n    self == other\n  end\n\n  def hash\n    slug.hash\n  end\n\n  def events\n    Event.where(country_code: \"GB\", state_code: [state_code, nation_name])\n  end\n\n  def users\n    User.indexable.geocoded.where(country_code: \"GB\", state_code: [state_code, nation_name])\n  end\n\n  def cities\n    City.where(country_code: \"GB\", state_code: state_code)\n  end\n\n  def stamps\n    Stamp.all.select { |stamp| stamp.code == alpha2 }\n  end\n\n  def bounds\n    nil\n  end\n\n  def held_in_sentence\n    \" held in #{name}\"\n  end\n\n  def uk_nation?\n    true\n  end\n\n  def states?\n    false\n  end\n\n  def parent_country\n    Country.find(\"GB\")\n  end\n\n  def to_location\n    Location.new(state_code: state_code, country_code: \"GB\", raw_location: \"#{name}, Europe\")\n  end\nend\n"
  },
  {
    "path": "app/models/user/duplicate_detector.rb",
    "content": "class User::DuplicateDetector < ActiveRecord::AssociatedObject\n  extension do\n    def reversed_name_duplicates\n      return User.none unless name&.include?(\" \")\n\n      User\n        .where(canonical_id: nil, marked_for_deletion: false)\n        .where.not(id: id)\n        .where(\n          \"LOWER(name) = LOWER(SUBSTR(:name, INSTR(:name, ' ') + 1) || ' ' || SUBSTR(:name, 1, INSTR(:name, ' ') - 1))\",\n          name: name\n        )\n    end\n\n    def same_name_duplicates\n      return User.none if name.blank?\n\n      User\n        .where(canonical_id: nil, marked_for_deletion: false)\n        .where.not(id: id)\n        .where(\"LOWER(name) = LOWER(?)\", name)\n    end\n\n    scope :with_reversed_name_duplicate, -> {\n      where(id: User::DuplicateDetector.reversed_name_duplicate_ids)\n    }\n\n    scope :with_same_name_duplicate, -> {\n      where(id: User::DuplicateDetector.same_name_duplicate_ids)\n    }\n\n    scope :with_any_duplicate, -> {\n      where(id: User::DuplicateDetector.all_duplicate_ids)\n    }\n  end\n\n  def reversed_name\n    return nil if user.name.blank?\n\n    user.name.split(\" \").reverse.join(\" \")\n  end\n\n  def normalized_name\n    return nil if user.name.blank?\n\n    user.name.split(\" \").sort.join(\" \").downcase\n  end\n\n  def potential_duplicates_by_reversed_name\n    user.reversed_name_duplicates\n  end\n\n  def potential_duplicates_by_normalized_name\n    return User.none if user.name.blank?\n\n    User\n      .where.not(id: user.id)\n      .where.not(name: [nil, \"\"])\n      .where(canonical_id: nil)\n      .where(marked_for_deletion: false)\n      .select { |u| u.duplicate_detector.normalized_name == normalized_name }\n  end\n\n  def has_reversed_name_duplicate?\n    potential_duplicates_by_reversed_name.exists?\n  end\n\n  def has_same_name_duplicate?\n    user.same_name_duplicates.exists?\n  end\n\n  def has_any_duplicate?\n    has_reversed_name_duplicate? || has_same_name_duplicate?\n  end\n\n  REVERSED_NAME_DUPLICATE_IDS_SQL = <<~SQL.squish\n    SELECT DISTINCT id FROM (\n      SELECT\n        u1.id\n\n      FROM\n        users u1\n\n      INNER JOIN users u2\n        ON LOWER(SUBSTR(u1.name, INSTR(u1.name, ' ') + 1) || ' ' || SUBSTR(u1.name, 1, INSTR(u1.name, ' ') - 1)) = LOWER(u2.name)\n\n      WHERE u1.id < u2.id\n        AND u1.canonical_id IS NULL\n        AND u2.canonical_id IS NULL\n        AND u1.marked_for_deletion = 0\n        AND u2.marked_for_deletion = 0\n        AND INSTR(u1.name, ' ') > 0\n\n      UNION ALL\n\n      SELECT\n        u2.id\n\n      FROM\n        users u1\n\n      INNER JOIN users u2\n        ON LOWER(SUBSTR(u1.name, INSTR(u1.name, ' ') + 1) || ' ' || SUBSTR(u1.name, 1, INSTR(u1.name, ' ') - 1)) = LOWER(u2.name)\n\n      WHERE u1.id < u2.id\n        AND u1.canonical_id IS NULL\n        AND u2.canonical_id IS NULL\n        AND u1.marked_for_deletion = 0\n        AND u2.marked_for_deletion = 0\n        AND INSTR(u1.name, ' ') > 0\n    )\n  SQL\n\n  def self.reversed_name_duplicate_ids\n    ActiveRecord::Base.connection.execute(REVERSED_NAME_DUPLICATE_IDS_SQL).map { |row| row[\"id\"] }\n  end\n\n  SAME_NAME_DUPLICATE_IDS_SQL = <<~SQL.squish\n    SELECT DISTINCT id FROM (\n      SELECT\n        u1.id\n\n      FROM\n        users u1\n\n      INNER JOIN users u2\n        ON LOWER(u1.name) = LOWER(u2.name)\n\n      WHERE u1.id < u2.id\n        AND u1.canonical_id IS NULL\n        AND u2.canonical_id IS NULL\n        AND u1.marked_for_deletion = 0\n        AND u2.marked_for_deletion = 0\n        AND u1.name IS NOT NULL\n        AND u1.name != ''\n\n      UNION ALL\n\n      SELECT\n        u2.id\n\n      FROM\n        users u1\n\n      INNER JOIN users u2\n        ON LOWER(u1.name) = LOWER(u2.name)\n\n      WHERE u1.id < u2.id\n        AND u1.canonical_id IS NULL\n        AND u2.canonical_id IS NULL\n        AND u1.marked_for_deletion = 0\n        AND u2.marked_for_deletion = 0\n        AND u1.name IS NOT NULL\n        AND u1.name != ''\n    )\n  SQL\n\n  def self.same_name_duplicate_ids\n    ActiveRecord::Base.connection.execute(SAME_NAME_DUPLICATE_IDS_SQL).map { |row| row[\"id\"] }\n  end\n\n  def self.all_duplicate_ids\n    (reversed_name_duplicate_ids + same_name_duplicate_ids).uniq\n  end\n\n  REVERSED_NAME_DUPLICATES_SQL = <<~SQL.squish\n    SELECT\n      u1.id AS user1_id, u2.id AS user2_id\n\n    FROM\n      users u1\n\n    INNER JOIN users u2\n      ON LOWER(SUBSTR(u1.name, INSTR(u1.name, ' ') + 1) || ' ' || SUBSTR(u1.name, 1, INSTR(u1.name, ' ') - 1)) = LOWER(u2.name)\n\n    WHERE u1.id < u2.id\n      AND u1.canonical_id IS NULL\n      AND u2.canonical_id IS NULL\n      AND u1.marked_for_deletion = 0\n      AND u2.marked_for_deletion = 0\n      AND INSTR(u1.name, ' ') > 0\n  SQL\n\n  def self.find_all_reversed_name_duplicates\n    pairs = ActiveRecord::Base.connection.execute(REVERSED_NAME_DUPLICATES_SQL)\n    user_ids = pairs.flat_map { |row| [row[\"user1_id\"], row[\"user2_id\"]] }.uniq\n    users_by_id = User.where(id: user_ids).index_by(&:id)\n\n    pairs.map { |row| [users_by_id[row[\"user1_id\"]], users_by_id[row[\"user2_id\"]]] }\n  end\n\n  SAME_NAME_DUPLICATES_SQL = <<~SQL.squish\n    SELECT\n      u1.id AS user1_id, u2.id AS user2_id\n\n    FROM\n      users u1\n\n    INNER JOIN users u2\n      ON LOWER(u1.name) = LOWER(u2.name)\n\n    WHERE u1.id < u2.id\n      AND u1.canonical_id IS NULL\n      AND u2.canonical_id IS NULL\n      AND u1.marked_for_deletion = 0\n      AND u2.marked_for_deletion = 0\n      AND u1.name IS NOT NULL\n      AND u1.name != ''\n  SQL\n\n  def self.find_all_same_name_duplicates\n    pairs = ActiveRecord::Base.connection.execute(SAME_NAME_DUPLICATES_SQL)\n    user_ids = pairs.flat_map { |row| [row[\"user1_id\"], row[\"user2_id\"]] }.uniq\n    users_by_id = User.where(id: user_ids).index_by(&:id)\n\n    pairs.map { |row| [users_by_id[row[\"user1_id\"]], users_by_id[row[\"user2_id\"]]] }\n  end\n\n  def self.report\n    reversed_duplicates = find_all_reversed_name_duplicates\n    same_name_duplicates = find_all_same_name_duplicates\n\n    if reversed_duplicates.empty? && same_name_duplicates.empty?\n      return \"No duplicates found.\"\n    end\n\n    lines = []\n\n    if same_name_duplicates.any?\n      lines << \"=== Same Name Duplicates (#{same_name_duplicates.count} pairs) ===\\n\"\n\n      same_name_duplicates.each_with_index do |(user1, user2), index|\n        lines << \"#{index + 1}. \\\"#{user1.name}\\\" (ID: #{user1.id}) == \\\"#{user2.name}\\\" (ID: #{user2.id})\"\n        lines << \"   User 1: talks=#{user1.talks_count}, github=#{user1.github_handle.presence || \"none\"}\"\n        lines << \"   User 2: talks=#{user2.talks_count}, github=#{user2.github_handle.presence || \"none\"}\"\n        lines << \"\"\n      end\n    end\n\n    if reversed_duplicates.any?\n      lines << \"=== Reversed Name Duplicates (#{reversed_duplicates.count} pairs) ===\\n\"\n\n      reversed_duplicates.each_with_index do |(user1, user2), index|\n        lines << \"#{index + 1}. \\\"#{user1.name}\\\" (ID: #{user1.id}) <-> \\\"#{user2.name}\\\" (ID: #{user2.id})\"\n        lines << \"   User 1: talks=#{user1.talks_count}, github=#{user1.github_handle.presence || \"none\"}\"\n        lines << \"   User 2: talks=#{user2.talks_count}, github=#{user2.github_handle.presence || \"none\"}\"\n        lines << \"\"\n      end\n    end\n\n    lines.join(\"\\n\")\n  end\nend\n"
  },
  {
    "path": "app/models/user/index.rb",
    "content": "class User::Index < ApplicationRecord\n  self.table_name = :users_search_index\n\n  include ActiveRecord::SQLite::Index # Depends on `table_name` being assigned.\n\n  class_attribute :index_columns, default: {name: 0, github_handle: 1}\n\n  belongs_to :user, foreign_key: :rowid\n\n  def self.search(query)\n    query = remove_invalid_search_characters(query) || \"\" # remove non-word characters\n    query = remove_unbalanced_quotes(query)\n    query = query.split.map { |word| \"#{word}*\" }.join(\" \") # wildcard search\n    query = query.strip.presence\n\n    return all if query.blank?\n\n    where(\"#{table_name} match ?\", query)\n  end\n\n  def self.snippets(**)\n    index_columns.each_key.reduce(all) { |relation, column| relation.snippet(column, **) }\n  end\n\n  def self.snippet(column, tag: \"mark\", omission: \"…\", limit: 32)\n    offset = index_columns.fetch(column)\n    select(\"snippet(#{table_name}, #{offset}, '<#{tag}>', '</#{tag}>', '#{omission}', #{limit}) AS #{column}_snippet\")\n  end\n\n  def reindex\n    update! id: user.id, name: user.name, github_handle: user.github_handle\n  end\n\n  def self.remove_invalid_search_characters(query)\n    query.gsub(/[^\\w\"]/, \" \")\n  end\n\n  def self.remove_unbalanced_quotes(query)\n    if query.count(\"\\\"\").even?\n      query\n    else\n      query.tr(\"\\\"\", \" \")\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/user/profiles.rb",
    "content": "class User::Profiles < ActiveRecord::AssociatedObject\n  performs(retries: 3) { limits_concurrency key: -> { it.id } }\n\n  def enhance_all_later\n    enhance_with_github_later\n    enhance_with_bsky_later\n  end\n\n  performs def enhance_with_github\n    return unless user.github_handle?\n\n    profile = github_client.profile(user.github_handle)\n    socials = github_client.social_accounts(user.github_handle)\n    links = socials.pluck(:provider, :url).to_h\n\n    user.update!(\n      twitter: user.twitter.presence || links[\"twitter\"] || \"\",\n      mastodon: user.mastodon.presence || links[\"mastodon\"] || \"\",\n      bsky: user.bsky.presence || links[\"bluesky\"] || \"\",\n      linkedin: user.linkedin.presence || links[\"linkedin\"] || \"\",\n      bio: user.bio.presence || profile.bio || \"\",\n      website: user.website.presence || profile.blog || \"\",\n      location: user.location.presence || profile.location || \"\",\n      github_metadata: {\n        profile: JSON.parse(profile.body),\n        socials: JSON.parse(socials.body)\n      }\n    )\n\n    user.broadcast_header\n  end\n\n  performs def enhance_with_bsky(force: false)\n    return unless user.bsky?\n    return if user.verified? && !force\n\n    user.update!(bsky_metadata: BlueSky.profile_metadata(user.bsky))\n  end\n\n  private\n\n  def github_client\n    @github_client ||= GitHub::UserClient.new\n  end\nend\n"
  },
  {
    "path": "app/models/user/speakerdeck_feed.rb",
    "content": "require \"rss\"\nrequire \"httparty\"\n\nclass User::SpeakerdeckFeed < ActiveRecord::AssociatedObject\n  def username\n    user.speakerdeck\n  end\n\n  def has_feed?\n    username.present?\n  end\n\n  def feed\n    return nil unless has_feed?\n\n    @feed ||= FeedData.new(username)\n  end\n\n  def decks\n    return [] unless feed\n\n    feed.decks\n  end\n\n  def unused_decks\n    return [] unless feed\n\n    feed.find_unused_decks\n  end\n\n  private\n\n  class FeedData\n    attr_reader :username\n\n    def initialize(username)\n      @username = username\n      @decks = []\n      @feed_fetched = false\n    end\n\n    def fetch!\n      return self if @feed_fetched\n\n      rss_url = \"https://speakerdeck.com/#{@username}.rss\"\n      response = HTTParty.get(rss_url)\n      rss = RSS::Parser.parse(response.body, false)\n\n      if rss&.items\n        @decks = rss.items.map { |item| Deck.new(item) }\n      end\n\n      @feed_fetched = true\n      self\n    rescue HTTParty::Error, Net::HTTPError, SocketError, Timeout::Error => e\n      Rails.logger.error \"Failed to fetch Speakerdeck feed for #{username}: #{e.message}\"\n      @decks = []\n      @feed_fetched = true\n      self\n    rescue RSS::NotWellFormedError => e\n      Rails.logger.error \"Invalid RSS feed format for #{username}: #{e.message}\"\n      @decks = []\n      @feed_fetched = true\n      self\n    end\n\n    def decks\n      fetch! unless @feed_fetched\n\n      @decks\n    end\n\n    def decks_count\n      fetch! unless @feed_fetched\n\n      @decks.size\n    end\n\n    def find_unused_decks\n      fetch! unless @feed_fetched\n\n      used_urls = Talk.where.not(slides_url: [nil, \"\"]).pluck(:slides_url)\n\n      @decks.reject { |deck| used_urls.include?(deck.url) }\n    end\n  end\n\n  class Deck\n    attr_reader :title, :url, :description, :published_at, :item\n\n    def initialize(rss_item)\n      @item = rss_item\n      @title = rss_item.title\n      @url = rss_item.link\n      @description = rss_item.description\n      @published_at = rss_item.pubDate\n    end\n\n    def to_h\n      {\n        item: item,\n        title: title,\n        url: url,\n        description: description,\n        published_at: published_at\n      }\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/user/sqlite_fts_searchable.rb",
    "content": "# frozen_string_literal: true\n\nmodule User::SQLiteFTSSearchable\n  extend ActiveSupport::Concern\n\n  included do\n    has_one :fts_index, foreign_key: :rowid, inverse_of: :user, dependent: :destroy, class_name: \"User::Index\"\n\n    scope :ft_search, ->(query) { select(\"users.*\").joins(:fts_index).merge(User::Index.search(query)) }\n\n    scope :with_snippets, ->(**options) do\n      select(\"users.*\").merge(User::Index.snippets(**options))\n    end\n\n    scope :ranked, -> do\n      select(\"users.*,\n          bm25(users_search_index, 2, 1) AS combined_score\")\n        .order(combined_score: :asc)\n    end\n\n    after_save_commit :reindex_fts\n  end\n\n  def name_with_snippet\n    try(:name_snippet) || name\n  end\n\n  def fts_index\n    super || build_fts_index\n  end\n\n  def reindex_fts\n    return if Search::Backend.skip_indexing\n\n    fts_index.reindex\n  end\nend\n"
  },
  {
    "path": "app/models/user/suspicion_detector.rb",
    "content": "class User::SuspicionDetector < ActiveRecord::AssociatedObject\n  SIGNAL_THRESHOLD = 3\n  GITHUB_ACCOUNT_AGE_THRESHOLD = 6.months\n\n  extension do\n    scope :verified, -> {\n      joins(:connected_accounts).where(connected_accounts: {provider: \"github\"}).distinct\n    }\n\n    scope :with_github_account_older_than, ->(duration) {\n      with_github.where(\"json_extract(github_metadata, '$.profile.created_at') < ?\", duration.ago.iso8601)\n    }\n\n    scope :with_github_account_newer_than, ->(duration) {\n      with_github.where(\"json_extract(github_metadata, '$.profile.created_at') >= ?\", duration.ago.iso8601)\n    }\n\n    scope :suspicion_cleared, -> { where.not(suspicion_cleared_at: nil) }\n    scope :suspicion_not_cleared, -> { where(suspicion_cleared_at: nil) }\n    scope :suspicion_marked, -> { where.not(suspicion_marked_at: nil) }\n    scope :suspicion_not_marked, -> { where(suspicion_marked_at: nil) }\n\n    scope :suspicious, -> { suspicion_marked.suspicion_not_cleared }\n    scope :not_suspicious, -> { suspicion_not_marked.or(suspicion_cleared) }\n\n    def suspicious?\n      suspicion_marked_at.present? && suspicion_cleared_at.blank?\n    end\n\n    def suspicion_cleared?\n      suspicion_cleared_at.present?\n    end\n\n    def mark_suspicious!\n      return false unless suspicion_detector.calculate_suspicious?\n\n      update_column(:suspicion_marked_at, Time.current)\n      true\n    end\n\n    def clear_suspicion!\n      update!(suspicion_cleared_at: Time.current, suspicion_marked_at: nil)\n    end\n\n    def unclear_suspicion!\n      update!(suspicion_cleared_at: nil)\n    end\n\n    def github_account_newer_than?(duration)\n      return false if github_metadata.blank?\n\n      created_at = github_metadata.dig(\"profile\", \"created_at\")\n      return false if created_at.blank?\n\n      Time.parse(created_at) > duration.ago\n    end\n  end\n\n  def calculate_suspicious?\n    return false unless user.verified?\n    return false if user.suspicion_cleared?\n    return false if user.ruby_passport_claimed?\n\n    signals.count(true) >= SIGNAL_THRESHOLD\n  end\n\n  def signals\n    [\n      github_account_new?,\n      no_talks?,\n      no_watched_talks?,\n      bio_contains_url?,\n      github_account_empty?\n    ]\n  end\n\n  def signal_count\n    signals.count(true)\n  end\n\n  def github_account_new?\n    return false if user.github_metadata.blank?\n\n    created_at = user.github_metadata.dig(\"profile\", \"created_at\")\n    return false if created_at.blank?\n\n    Time.parse(created_at) > GITHUB_ACCOUNT_AGE_THRESHOLD.ago\n  end\n\n  def no_talks?\n    user.talks_count.zero?\n  end\n\n  def no_watched_talks?\n    user.watched_talks_count.zero?\n  end\n\n  def bio_contains_url?\n    return false if user.bio.blank?\n\n    user.bio.match?(URI::DEFAULT_PARSER.make_regexp(%w[http https]))\n  end\n\n  def github_account_empty?\n    return false if user.github_metadata.blank?\n\n    profile = user.github_metadata[\"profile\"]\n    return false if profile.blank?\n\n    profile[\"public_repos\"].to_i.zero? &&\n      profile[\"followers\"].to_i.zero? &&\n      profile[\"following\"].to_i.zero?\n  end\nend\n"
  },
  {
    "path": "app/models/user/talk_recommender.rb",
    "content": "class User::TalkRecommender < ActiveRecord::AssociatedObject\n  def talks(limit: 4)\n    return Talk.none if user.watched_talks.watched.empty?\n\n    (collaborative_filtering_recommendations(limit: limit) + content_based_recommendations(limit: limit))\n      .uniq\n      .sample(limit)\n  end\n\n  private\n\n  def watched_talk_ids\n    user.watched_talks.watched.select(:talk_id)\n  end\n\n  def collaborative_filtering_recommendations(limit:)\n    similar_user_ids = WatchedTalk.watched\n      .where(talk_id: watched_talk_ids)\n      .where.not(user_id: user.id)\n      .group(:user_id)\n      .having(\"COUNT(*) >= ?\", 2)\n      .order(Arel.sql(\"COUNT(*) DESC\"))\n      .limit(50)\n      .pluck(:user_id)\n\n    Talk.joins(:watched_talks)\n      .where(watched_talks: {user_id: similar_user_ids})\n      .where.not(id: watched_talk_ids)\n      .where(video_provider: Talk::WATCHABLE_PROVIDERS)\n      .group(:id)\n      .order(Arel.sql(\"COUNT(watched_talks.id) DESC\"))\n      .limit(limit)\n  end\n\n  def content_based_recommendations(limit:)\n    watched_topic_ids = user.watched_talks.watched\n      .joins(talk: :approved_topics)\n      .distinct\n      .pluck(\"topics.id\")\n\n    Talk.joins(:approved_topics)\n      .where(topics: {id: watched_topic_ids})\n      .where.not(id: watched_talk_ids)\n      .where(video_provider: Talk::WATCHABLE_PROVIDERS)\n      .order(\"created_at DESC\")\n      .limit(limit)\n  end\nend\n"
  },
  {
    "path": "app/models/user/typesense_searchable.rb",
    "content": "# frozen_string_literal: true\n\nmodule User::TypesenseSearchable\n  extend ActiveSupport::Concern\n\n  included do\n    include ::Typesense\n\n    typesense enqueue: :trigger_typesense_job, if: :should_index?, disable_indexing: -> { Search::Backend.skip_indexing } do\n      attributes :name, :slug, :bio, :location\n\n      attributes :github_handle, :twitter, :bsky, :mastodon, :linkedin, :speakerdeck, :website\n\n      attribute :pronouns_display do\n        case pronouns_type\n        when \"custom\"\n          pronouns\n        when \"not_specified\", \"dont_specify\"\n          nil\n        else\n          pronouns_type&.tr(\"_\", \"/\")\n        end\n      end\n\n      attribute :talks_count\n\n      attribute :events_count do\n        events.count\n      end\n\n      attribute :avatar_url do\n        github_metadata&.dig(\"avatar_url\")\n      end\n\n      attribute :alias_names do\n        aliases.pluck(:name)\n      end\n\n      attribute :alias_slugs do\n        aliases.pluck(:slug)\n      end\n\n      attribute :topic_names do\n        topics.approved.distinct.pluck(:name)\n      end\n\n      attribute :topic_slugs do\n        topics.approved.distinct.pluck(:slug)\n      end\n\n      attribute :event_names do\n        events.distinct.pluck(:name)\n      end\n\n      attribute :event_series_names do\n        events.joins(:series).distinct.pluck(\"event_series.name\")\n      end\n\n      attribute :recent_talk_titles do\n        talks.order(date: :desc).limit(10).pluck(:title)\n      end\n\n      attribute :countries_presented do\n        events.distinct.where.not(country_code: nil).pluck(:country_code)\n      end\n\n      attribute :verified\n\n      predefined_fields [\n        {\"name\" => \"name\", \"type\" => \"string\"},\n        {\"name\" => \"bio\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"location\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"alias_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"topic_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"event_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"event_series_names\", \"type\" => \"string[]\", \"optional\" => true},\n        {\"name\" => \"recent_talk_titles\", \"type\" => \"string[]\", \"optional\" => true},\n\n        {\"name\" => \"github_handle\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"twitter\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"bsky\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"mastodon\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"linkedin\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"speakerdeck\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"website\", \"type\" => \"string\", \"optional\" => true},\n\n        {\"name\" => \"topic_slugs\", \"type\" => \"string[]\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"countries_presented\", \"type\" => \"string[]\", \"optional\" => true, \"facet\" => true},\n        {\"name\" => \"verified\", \"type\" => \"bool\", \"facet\" => true},\n\n        {\"name\" => \"talks_count\", \"type\" => \"int32\"},\n        {\"name\" => \"events_count\", \"type\" => \"int32\"},\n\n        {\"name\" => \"slug\", \"type\" => \"string\"},\n        {\"name\" => \"pronouns_display\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"avatar_url\", \"type\" => \"string\", \"optional\" => true},\n        {\"name\" => \"alias_slugs\", \"type\" => \"string[]\", \"optional\" => true}\n      ]\n\n      default_sorting_field \"talks_count\"\n\n      one_way_synonyms User.typesense_synonyms_from_aliases\n    end\n  end\n\n  class_methods do\n    def typesense_synonyms_from_aliases\n      ::Alias.where(aliasable_type: \"User\")\n        .includes(:aliasable)\n        .group_by(&:aliasable)\n        .filter_map do |user, aliases|\n          next unless user\n\n          canonical_slug = user.name.parameterize\n          alias_slugs = aliases.map { |a| a.name.parameterize }.uniq - [canonical_slug]\n\n          next if alias_slugs.empty?\n\n          {\"#{canonical_slug}-synonym\" => {\"root\" => canonical_slug, \"synonyms\" => alias_slugs}}\n        end\n    rescue ActiveRecord::StatementInvalid\n      []\n    end\n\n    def trigger_typesense_job(record, remove)\n      TypesenseIndexJob.perform_later(record, remove ? \"typesense_remove_from_index!\" : \"typesense_index!\")\n    end\n\n    def typesense_search_speakers(query, options = {})\n      query_by_fields = \"name,slug,bio,location,alias_names,alias_slugs,github_handle,twitter,topic_names,event_names,recent_talk_titles\"\n\n      search_options = {\n        query_by_weights: \"10,9,3,4,8,7,5,5,4,3,2\",\n        per_page: options[:per_page] || 20,\n        page: options[:page] || 1\n      }\n\n      filters = []\n      filters << \"topic_slugs:=#{options[:topic_slug]}\" if options[:topic_slug].present?\n      filters << \"countries_presented:=#{options[:country_code]}\" if options[:country_code].present?\n      filters << \"verified:=true\" if options[:verified]\n      filters << \"talks_count:>0\" unless options[:include_non_speakers]\n\n      search_options[:filter_by] = filters.join(\" && \") if filters.any?\n\n      sort_options = {\n        \"talks\" => \"talks_count:desc\",\n        \"events\" => \"events_count:desc\",\n        \"name\" => \"name:asc\",\n        \"relevance\" => \"_text_match:desc,talks_count:desc\"\n      }\n\n      search_options[:sort_by] = sort_options[options[:sort]] || sort_options[\"relevance\"]\n\n      if options[:facets]\n        search_options[:facet_by] = options[:facets].join(\",\")\n      end\n\n      search(query.presence || \"*\", query_by_fields, search_options)\n    end\n  end\n\n  private\n\n  def should_index?\n    indexable?\n  end\nend\n"
  },
  {
    "path": "app/models/user/watched_talk_seeder.rb",
    "content": "class User::WatchedTalkSeeder < ActiveRecord::AssociatedObject\n  def seed_development_data\n    return unless Rails.env.development?\n\n    watchable_talks = Talk.youtube.order(date: :desc).limit(100)\n\n    return if watchable_talks.empty?\n\n    existing_users = User.joins(:watched_talks).limit(10)\n\n    seed_overlapping_patterns(watchable_talks, existing_users)\n  end\n\n  private\n\n  def seed_overlapping_patterns(watchable_talks, existing_users)\n    core_topics = Topic.approved.pluck(:name)\n\n    core_shared_talks = watchable_talks.select do |talk|\n      talk.approved_topics.any? { |topic| core_topics.include?(topic.name) }\n    end.sample(3)\n\n    sample_users = existing_users.sample(2)\n    shared_talks = []\n\n    sample_users.each do |existing_user|\n      user_talks = existing_user.watched_talks.joins(:talk)\n        .where(talk: watchable_talks)\n        .includes(:talk)\n        .sample(rand(1..2))\n      shared_talks += user_talks.map(&:talk)\n    end\n\n    similar_topic_ids = (core_shared_talks + shared_talks).flat_map do |talk|\n      talk.approved_topics.pluck(:id)\n    end.uniq\n\n    similar_talks = watchable_talks.joins(:approved_topics)\n      .where(topics: {id: similar_topic_ids})\n      .sample(4)\n\n    used_talks = core_shared_talks + shared_talks + similar_talks\n    random_talks = (watchable_talks - used_talks).sample(rand(2..4))\n\n    all_talks = (core_shared_talks + shared_talks + similar_talks + random_talks)\n      .uniq\n      .sample(rand(10..15))\n\n    all_talks.each do |talk|\n      WatchedTalk.find_or_create_by(user: user, talk: talk) do |watched_talk|\n        watched_talk.progress_seconds = rand(0..talk.duration_in_seconds || 1000)\n        watched_talk.created_at = rand(6.months.ago..Time.current)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/user/wrapped_image_generator.rb",
    "content": "require \"ferrum\"\nrequire \"tempfile\"\n\nclass User::WrappedImageGenerator\n  YEAR = 2025\n  WIDTH = 1200\n  HEIGHT = 630\n\n  attr_reader :user\n\n  def initialize(user)\n    @user = user\n  end\n\n  def generate\n    html_content = render_html\n    return nil unless html_content\n\n    html_file = Tempfile.new([\"wrapped-og\", \".html\"])\n    html_file.write(html_content)\n    html_file.close\n\n    browser = Ferrum::Browser.new(\n      headless: true,\n      window_size: [WIDTH, HEIGHT],\n      timeout: 30,\n      browser_options: {\n        \"no-sandbox\": true,\n        \"disable-gpu\": true,\n        \"disable-dev-shm-usage\": true\n      }\n    )\n\n    begin\n      browser.go_to(\"file://#{html_file.path}\")\n      sleep 1\n      screenshot_data = browser.screenshot(format: :png, full: true)\n      screenshot_data\n    ensure\n      browser.quit\n      html_file.unlink\n    end\n  rescue => e\n    Rails.logger.error(\"WrappedImageGenerator failed: #{e.message}\")\n    Rails.logger.error(e.backtrace.first(10).join(\"\\n\"))\n    nil\n  end\n\n  def save_to_storage\n    screenshot_data = generate\n    return nil unless screenshot_data\n\n    decoded_data = Base64.decode64(screenshot_data)\n    filename = \"wrapped-og-#{YEAR}-#{user.slug}.png\"\n\n    user.wrapped_og_image.attach(\n      io: StringIO.new(decoded_data),\n      filename: filename,\n      content_type: \"image/png\"\n    )\n\n    user.wrapped_og_image\n  end\n\n  def exists?\n    user.wrapped_og_image.attached?\n  end\n\n  private\n\n  def render_html\n    partial_html = ApplicationController.render(\n      partial: \"profiles/wrapped/pages/og_image\",\n      assigns: {user: user, year: YEAR}\n    )\n\n    wrap_in_html_document(partial_html)\n  end\n\n  def wrap_in_html_document(partial_html)\n    logo_path = Rails.root.join(\"app/assets/images/logo.png\")\n    logo_data_uri = if File.exist?(logo_path)\n      \"data:image/png;base64,#{Base64.strict_encode64(File.binread(logo_path))}\"\n    else\n      \"\"\n    end\n\n    partial_html = partial_html.gsub(/src=\"[^\"]*logo[^\"]*\\.png\"/, \"src=\\\"#{logo_data_uri}\\\"\")\n\n    <<~HTML\n      <!DOCTYPE html>\n      <html>\n      <head>\n        <meta charset=\"utf-8\">\n        <style>\n          * { margin: 0; padding: 0; box-sizing: border-box; }\n\n          body {\n            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n            width: #{WIDTH}px;\n            height: #{HEIGHT}px;\n            background: linear-gradient(135deg, #DC2626 0%, #991B1B 100%);\n            color: white;\n            display: flex;\n            flex-direction: column;\n            padding: 2.5rem;\n          }\n\n          .flex-1 { flex: 1; }\n          .flex { display: flex; }\n          .flex-col { flex-direction: column; }\n          .items-center { align-items: center; }\n          .justify-center { justify-content: center; }\n\n          .gap-3 { gap: 0.75rem; }\n\n          .w-full { width: 100%; }\n          .w-28 { width: 7rem; }\n          .w-8 { width: 2rem; }\n          .h-28 { height: 7rem; }\n          .h-8 { height: 2rem; }\n\n          .mt-auto { margin-top: auto; }\n          .mb-1 { margin-bottom: 0.25rem; }\n          .mb-3 { margin-bottom: 0.75rem; }\n          .mb-4 { margin-bottom: 1rem; }\n          .mb-6 { margin-bottom: 1.5rem; }\n          .mb-8 { margin-bottom: 2rem; }\n\n          .rounded-full { border-radius: 9999px; }\n          .overflow-hidden { overflow: hidden; }\n\n          .border-4 { border-width: 4px; border-style: solid; }\n          .border-white { border-color: white; }\n\n          .bg-white\\\\/20 { background: rgba(255,255,255,0.2); }\n\n          .text-7xl { font-size: 4.5rem; line-height: 1; }\n          .text-4xl { font-size: 2.25rem; }\n          .text-3xl { font-size: 1.875rem; }\n          .text-2xl { font-size: 1.5rem; }\n          .text-xl { font-size: 1.25rem; }\n          .text-lg { font-size: 1.125rem; }\n          .font-black { font-weight: 900; }\n          .font-bold { font-weight: 700; }\n          .text-red-200 { color: #FECACA; }\n          .text-white { color: white; }\n\n          .object-cover { object-fit: cover; }\n\n          img { max-width: 100%; height: auto; }\n        </style>\n      </head>\n      <body>\n        #{partial_html}\n      </body>\n      </html>\n    HTML\n  end\nend\n"
  },
  {
    "path": "app/models/user/wrapped_screenshot_generator.rb",
    "content": "require \"ferrum\"\n\nclass User::WrappedScreenshotGenerator\n  YEAR = 2025\n  SCALE = 2\n\n  DIMENSIONS = {\n    vertical: {width: 400 * SCALE, height: 700 * SCALE},\n    horizontal: {width: 800 * SCALE, height: 420 * SCALE}\n  }.freeze\n\n  attr_reader :user, :orientation\n\n  def initialize(user, orientation: :vertical)\n    @user = user\n    @orientation = orientation.to_sym\n  end\n\n  def generate\n    html_content = render_card_html\n    return nil unless html_content\n\n    dimensions = DIMENSIONS[orientation]\n    browser = Ferrum::Browser.new(**browser_options(dimensions))\n\n    begin\n      # Use data URI to inject HTML directly (works with remote Chrome)\n      data_uri = \"data:text/html;base64,#{Base64.strict_encode64(html_content)}\"\n      browser.go_to(data_uri)\n      sleep 1\n      screenshot_data = browser.screenshot(format: :png, full: true)\n      screenshot_data\n    ensure\n      browser.quit\n    end\n  rescue => e\n    Rails.logger.error(\"WrappedScreenshotGenerator failed: #{e.message}\")\n    Rails.logger.error(e.backtrace.first(10).join(\"\\n\"))\n    nil\n  end\n\n  def save_to_storage\n    screenshot_data = generate\n    return nil unless screenshot_data\n\n    decoded_data = Base64.decode64(screenshot_data)\n    filename = \"wrapped-#{orientation}-#{YEAR}-#{user.slug}.png\"\n\n    attachment = (orientation == :horizontal) ? user.wrapped_card_horizontal : user.wrapped_card\n\n    attachment.attach(\n      io: StringIO.new(decoded_data),\n      filename: filename,\n      content_type: \"image/png\"\n    )\n\n    attachment\n  end\n\n  def exists?\n    if orientation == :horizontal\n      user.wrapped_card_horizontal.attached?\n    else\n      user.wrapped_card.attached?\n    end\n  end\n\n  def self.generate_all(user)\n    vertical = new(user, orientation: :vertical)\n    horizontal = new(user, orientation: :horizontal)\n\n    vertical.save_to_storage\n    horizontal.save_to_storage\n  end\n\n  private\n\n  def render_card_html\n    assigns = build_assigns\n    partial_name = (orientation == :horizontal) ? \"summary_card_horizontal\" : \"summary_card\"\n    partial_html = render_partial(partial_name, assigns)\n\n    wrap_in_html_document(partial_html)\n  end\n\n  def build_assigns\n    year_range = Date.new(YEAR, 1, 1)..Date.new(YEAR, 12, 31)\n\n    watched_talks_in_year = user.watched_talks\n      .includes(talk: [:event, :speakers, :approved_topics])\n      .where(created_at: year_range)\n\n    total_talks_watched = watched_talks_in_year.count\n    total_watch_time_seconds = watched_talks_in_year.sum(&:progress_seconds)\n    total_watch_time_hours = (total_watch_time_seconds / 3600.0).round(1)\n\n    events_attended_in_year = user.participated_events.where(start_date: year_range)\n    talks_given_in_year = user.kept_talks.where(date: year_range)\n    countries_visited = events_attended_in_year.map(&:country).compact.uniq\n\n    top_topics = watched_talks_in_year\n      .flat_map { |wt| wt.talk.approved_topics }\n      .compact\n      .reject { |topic| topic.name.downcase.in?([\"ruby\", \"ruby on rails\"]) }\n      .tally\n      .sort_by { |_, count| -count }\n      .first(5)\n\n    top_speakers = watched_talks_in_year\n      .flat_map { |wt| wt.talk.speakers }\n      .compact\n      .reject { |speaker| speaker.id == user.id }\n      .tally\n      .sort_by { |_, count| -count }\n      .first(5)\n\n    favorite_speaker = top_speakers.first&.first\n\n    total_views_on_talks = talks_given_in_year.sum(:view_count)\n\n    involvements_in_year = user.event_involvements\n      .joins(:event)\n      .where(events: {start_date: year_range})\n\n    personality = determine_personality(top_topics)\n\n    {\n      user: user,\n      year: YEAR,\n      total_talks_watched: total_talks_watched,\n      total_watch_time_hours: total_watch_time_hours,\n      events_attended_in_year: events_attended_in_year,\n      talks_given_in_year: talks_given_in_year,\n      countries_visited: countries_visited,\n      top_topics: top_topics,\n      top_speakers: top_speakers,\n      favorite_speaker: favorite_speaker,\n      total_views_on_talks: total_views_on_talks,\n      involvements_in_year: involvements_in_year,\n      personality: personality\n    }\n  end\n\n  def render_partial(partial_name, locals)\n    ApplicationController.render(\n      partial: \"profiles/wrapped/pages/#{partial_name}\",\n      locals: locals\n    )\n  end\n\n  def wrap_in_html_document(partial_html)\n    logo_path = Rails.root.join(\"app/assets/images/logo.png\")\n    logo_data_uri = if File.exist?(logo_path)\n      \"data:image/png;base64,#{Base64.strict_encode64(File.binread(logo_path))}\"\n    else\n      \"\"\n    end\n\n    partial_html = partial_html.gsub(/src=\"[^\"]*logo[^\"]*\\.png\"/, \"src=\\\"#{logo_data_uri}\\\"\")\n\n    if orientation == :horizontal\n      wrap_horizontal_html_document(partial_html)\n    else\n      wrap_vertical_html_document(partial_html)\n    end\n  end\n\n  def wrap_horizontal_html_document(partial_html)\n    dimensions = DIMENSIONS[:horizontal]\n    s = SCALE\n\n    <<~HTML\n      <!DOCTYPE html>\n      <html>\n      <head>\n        <meta charset=\"utf-8\">\n        <style>\n          * { margin: 0; padding: 0; box-sizing: border-box; }\n\n          html, body {\n            width: #{dimensions[:width]}px;\n            height: #{dimensions[:height]}px;\n            max-height: #{dimensions[:height]}px;\n          }\n\n          body {\n            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n            background: linear-gradient(135deg, #991b1b 0%, #450a0a 50%, #081625 100%);\n            color: white;\n            display: flex;\n            flex-direction: column;\n            overflow: hidden;\n          }\n\n          .flex { display: flex; }\n          .flex-col { flex-direction: column; }\n          .flex-1 { flex: 1; min-height: 0; }\n          .items-center { align-items: center; }\n          .justify-center { justify-content: center; }\n          .text-center { text-align: center; }\n\n          .gap-3 { gap: #{0.75 * s}rem; }\n          .gap-4 { gap: #{1 * s}rem; }\n          .gap-6 { gap: #{1.5 * s}rem; }\n          .gap-12 { gap: #{3 * s}rem; }\n          .mb-6 { margin-bottom: #{1.5 * s}rem; }\n          .mt-1 { margin-top: #{0.25 * s}rem; }\n          .mt-2 { margin-top: #{0.5 * s}rem; }\n          .mt-4 { margin-top: #{1 * s}rem; }\n          .mt-auto { margin-top: auto; }\n          .p-3 { padding: #{0.75 * s}rem; }\n          .p-8 { padding: #{2 * s}rem; }\n          .p-12 { padding: #{3 * s}rem; }\n          .py-3 { padding-top: #{0.75 * s}rem; padding-bottom: #{0.75 * s}rem; }\n          .py-4 { padding-top: #{1 * s}rem; padding-bottom: #{1 * s}rem; }\n          .px-6 { padding-left: #{1.5 * s}rem; padding-right: #{1.5 * s}rem; }\n          .px-8 { padding-left: #{2 * s}rem; padding-right: #{2 * s}rem; }\n          .px-12 { padding-left: #{3 * s}rem; padding-right: #{3 * s}rem; }\n          .pt-8 { padding-top: #{2 * s}rem; }\n          .pb-4 { padding-bottom: #{1 * s}rem; }\n\n          .w-6 { width: #{1.5 * s}rem; }\n          .h-6 { height: #{1.5 * s}rem; }\n          .w-8 { width: #{2 * s}rem; }\n          .h-8 { height: #{2 * s}rem; }\n          .w-32 { width: #{8 * s}rem; }\n          .h-32 { height: #{8 * s}rem; }\n          .w-full { width: 100%; }\n          .h-full { height: 100%; }\n\n          .rounded-full { border-radius: 9999px; }\n          .rounded-2xl { border-radius: #{1 * s}rem; }\n          .rounded-3xl { border-radius: #{1.5 * s}rem; }\n          .overflow-hidden { overflow: hidden; }\n          .object-cover { object-fit: cover; }\n          .object-contain { object-fit: contain; }\n\n          .border-4 { border-width: #{4 * s}px; border-style: solid; }\n          .border-white { border-color: white; }\n          .border-white\\\\/20 { border-color: rgba(255,255,255,0.2); }\n\n          .bg-white { background: white; }\n          .bg-white\\\\/5 { background: rgba(255,255,255,0.05); }\n          .bg-white\\\\/10 { background: rgba(255,255,255,0.1); }\n          .bg-white\\\\/20 { background: rgba(255,255,255,0.2); }\n          .backdrop-blur { backdrop-filter: blur(10px); }\n\n          .grid { display: grid; }\n          .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n\n          .text-6xl { font-size: #{3.75 * s}rem; line-height: 1; }\n          .text-5xl { font-size: #{3 * s}rem; line-height: 1; }\n          .text-3xl { font-size: #{1.875 * s}rem; }\n          .text-lg { font-size: #{1.125 * s}rem; }\n          .text-sm { font-size: #{0.875 * s}rem; }\n          .font-black { font-weight: 900; }\n          .font-bold { font-weight: 700; }\n          .text-white { color: white; }\n          .text-red-200 { color: #FECACA; }\n          .text-red-300 { color: #FCA5A5; }\n          .text-red-300\\\\/60 { color: rgba(252,165,165,0.6); }\n          .text-red-300\\\\/80 { color: rgba(252,165,165,0.8); }\n\n          img { max-width: 100%; height: auto; }\n        </style>\n      </head>\n      <body>\n        #{partial_html}\n      </body>\n      </html>\n    HTML\n  end\n\n  def wrap_vertical_html_document(partial_html)\n    dimensions = DIMENSIONS[:vertical]\n    s = SCALE\n\n    <<~HTML\n      <!DOCTYPE html>\n      <html>\n      <head>\n        <meta charset=\"utf-8\">\n        <style>\n          * { margin: 0; padding: 0; box-sizing: border-box; }\n\n          body {\n            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n            width: #{dimensions[:width]}px;\n            height: #{dimensions[:height]}px;\n            background: linear-gradient(135deg, #991b1b 0%, #450a0a 50%, #081625 100%);\n            color: white;\n            display: flex;\n            flex-direction: column;\n            padding: #{2 * s}rem;\n          }\n\n          .flex-1 { flex: 1; }\n          .flex { display: flex; }\n          .flex-col { flex-direction: column; }\n          .flex-wrap { flex-wrap: wrap; }\n          .items-center { align-items: center; }\n          .items-end { align-items: flex-end; }\n          .justify-center { justify-content: center; }\n          .text-center { text-align: center; }\n\n          .w-full { width: 100%; }\n          .w-24 { width: #{6 * s}rem; }\n          .w-20 { width: #{5 * s}rem; }\n          .w-8 { width: #{2 * s}rem; }\n          .w-6 { width: #{1.5 * s}rem; }\n          .h-24 { height: #{6 * s}rem; }\n          .h-20 { height: #{5 * s}rem; }\n          .h-8 { height: #{2 * s}rem; }\n          .h-6 { height: #{1.5 * s}rem; }\n          .max-w-xs { max-width: #{20 * s}rem; }\n\n          .mx-auto { margin-left: auto; margin-right: auto; }\n          .mt-auto { margin-top: auto; }\n          .mt-3 { margin-top: #{0.75 * s}rem; }\n          .mb-0 { margin-bottom: 0; }\n          .mb-1 { margin-bottom: #{0.25 * s}rem; }\n          .mb-2 { margin-bottom: #{0.5 * s}rem; }\n          .mb-3 { margin-bottom: #{0.75 * s}rem; }\n          .mb-4 { margin-bottom: #{1 * s}rem; }\n          .mb-6 { margin-bottom: #{1.5 * s}rem; }\n          .pt-2 { padding-top: #{0.5 * s}rem; }\n          .pt-4 { padding-top: #{1 * s}rem; }\n          .pb-1 { padding-bottom: #{0.25 * s}rem; }\n          .p-2 { padding: #{0.5 * s}rem; }\n          .px-2 { padding-left: #{0.5 * s}rem; padding-right: #{0.5 * s}rem; }\n          .px-3 { padding-left: #{0.75 * s}rem; padding-right: #{0.75 * s}rem; }\n          .px-4 { padding-left: #{1 * s}rem; padding-right: #{1 * s}rem; }\n          .py-1 { padding-top: #{0.25 * s}rem; padding-bottom: #{0.25 * s}rem; }\n          .py-2 { padding-top: #{0.5 * s}rem; padding-bottom: #{0.5 * s}rem; }\n          .gap-1 { gap: #{0.25 * s}rem; }\n          .gap-2 { gap: #{0.5 * s}rem; }\n          .gap-3 { gap: #{0.75 * s}rem; }\n          .gap-12 { gap: #{3 * s}rem; }\n          .-space-x-2 > * + * { margin-left: #{-0.5 * s}rem; }\n\n          .rounded-full { border-radius: 9999px; }\n          .rounded-lg { border-radius: #{0.5 * s}rem; }\n          .rounded { border-radius: #{0.25 * s}rem; }\n          .overflow-hidden { overflow: hidden; }\n\n          .border-2 { border-width: #{2 * s}px; border-style: solid; }\n          .border-3 { border-width: #{3 * s}px; border-style: solid; }\n          .border-4 { border-width: #{4 * s}px; border-style: solid; }\n          .border-white { border-color: white; }\n          .border-red-600 { border-color: #DC2626; }\n\n          .bg-white\\\\/10 { background: rgba(255,255,255,0.1); }\n          .bg-white\\\\/20 { background: rgba(255,255,255,0.2); }\n          .bg-purple-500\\\\/30 { background: rgba(168,85,247,0.3); }\n\n          .text-3xl { font-size: #{1.875 * s}rem; }\n          .text-2xl { font-size: #{1.5 * s}rem; }\n          .text-xl { font-size: #{1.25 * s}rem; }\n          .text-lg { font-size: #{1.125 * s}rem; }\n          .text-sm { font-size: #{0.875 * s}rem; }\n          .text-xs { font-size: #{0.75 * s}rem; }\n          .text-\\\\[10px\\\\] { font-size: #{10 * s}px; }\n          .font-bold { font-weight: 700; }\n          .text-red-200 { color: #FECACA; }\n          .text-white { color: white; }\n\n          .grid { display: grid; }\n          .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }\n          .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n          .grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }\n\n          .object-cover { object-fit: cover; }\n          .flex-shrink-0 { flex-shrink: 0; }\n          .text-left { text-align: left; }\n          .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n          .w-10 { width: #{2.5 * s}rem; }\n          .h-10 { height: #{2.5 * s}rem; }\n\n          .personality-badge {\n            background: linear-gradient(135deg, #DC2626 0%, #B91C1C 100%);\n            color: white;\n            padding: #{0.5 * s}rem #{1 * s}rem;\n            border-radius: 9999px;\n            font-weight: 700;\n            font-size: #{0.875 * s}rem;\n            display: inline-block;\n            box-shadow: 0 #{4 * s}px #{14 * s}px rgba(220, 38, 38, 0.4);\n          }\n\n          img { max-width: 100%; height: auto; }\n        </style>\n      </head>\n      <body>\n        #{partial_html}\n      </body>\n      </html>\n    HTML\n  end\n\n  def browser_options(dimensions)\n    options = {\n      headless: true,\n      window_size: [dimensions[:width], dimensions[:height]],\n      timeout: 30\n    }\n\n    if chrome_ws_url\n      # Connect to remote browserless Chrome service\n      options[:url] = chrome_ws_url\n    else\n      # Local Chrome with sandbox options\n      options[:browser_options] = {\n        \"no-sandbox\": true,\n        \"disable-gpu\": true,\n        \"disable-dev-shm-usage\": true\n      }\n    end\n\n    options\n  end\n\n  def chrome_ws_url\n    # Use CHROME_WS_URL env var if set, otherwise derive from environment\n    # In development/test, use local Chrome (return nil)\n    return ENV[\"CHROME_WS_URL\"] if ENV[\"CHROME_WS_URL\"].present?\n    return nil if Rails.env.local?\n\n    # Kamal names accessories as <service>-<accessory>\n    # Production: rubyvideo-chrome, Staging: rubyvideo_staging-chrome\n    service_name = Rails.env.staging? ? \"rubyvideo_staging\" : \"rubyvideo\"\n    \"ws://#{service_name}-chrome:3000\"\n  end\n\n  def determine_personality(top_topics)\n    return \"Ruby Explorer\" if top_topics.empty?\n\n    all_topic_names = top_topics.map { |topic, _| topic.name.downcase }\n\n    personality_matches = {\n      \"Hotwire Hero\" => %w[hotwire turbo stimulus turbo-native],\n      \"Frontend Artisan\" => %w[javascript css frontend ui vue react angular viewcomponent],\n      \"Testing Guru\" => %w[testing test-driven rspec minitest capybara vcr],\n      \"Performance Optimizer\" => %w[performance optimization caching benchmarking memory profiling],\n      \"Security Champion\" => %w[security authentication authorization encryption vulnerability],\n      \"Data Architect\" => %w[postgresql database sql activerecord mysql sqlite redis elasticsearch],\n      \"API Artisan\" => %w[api graphql rest grpc json],\n      \"DevOps Pioneer\" => %w[devops deployment docker kubernetes aws heroku kamal ci/cd],\n      \"Architecture Astronaut\" => %w[architecture microservices monolith modular design-patterns solid],\n      \"Ruby Internist\" => %w[ruby-vm ruby-internals yjit garbage-collection jruby truffleruby mruby parser ast],\n      \"Concurrency Connoisseur\" => %w[concurrency async threading ractor fiber sidekiq background],\n      \"AI Adventurer\" => %w[machine-learning artificial-intelligence ai llm openai langchain],\n      \"Community Champion\" => %w[open-source community mentorship diversity inclusion],\n      \"Growth Mindset\" => %w[career-development personal-development leadership team-building mentorship],\n      \"Code Craftsperson\" => %w[refactoring code-quality clean-code debugging error-handling]\n    }\n\n    personality_matches.each do |personality, keywords|\n      if all_topic_names.any? { |topic| keywords.any? { |keyword| topic.include?(keyword) } }\n        return personality\n      end\n    end\n\n    top_topic = top_topics.first&.first&.name&.downcase\n\n    case top_topic\n    when /rails/\n      \"Rails Enthusiast\"\n    when /developer.?experience|dx/\n      \"DX Advocate\"\n    when /web/\n      \"Web Developer\"\n    when /software/\n      \"Software Craftsperson\"\n    when /gem/\n      \"Gem Hunter\"\n    when /debug/\n      \"Bug Squasher\"\n    when /learn|education|teach/\n      \"Eternal Learner\"\n    when /startup|entrepreneur|business/\n      \"Ruby Entrepreneur\"\n    when /legacy|maintain/\n      \"Legacy Whisperer\"\n    when /mobile|ios|android/\n      \"Mobile Maverick\"\n    when /real.?time|websocket|action.?cable/\n      \"Real-Time Ranger\"\n    when /background|job|queue|sidekiq/\n      \"Background Boss\"\n    when /monolith|majestic/\n      \"Monolith Master\"\n    else\n      \"Rubyist\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/user.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: users\n# Database name: primary\n#\n#  id                   :integer          not null, primary key\n#  admin                :boolean          default(FALSE), not null\n#  bio                  :text             default(\"\"), not null\n#  bsky                 :string           default(\"\"), not null\n#  bsky_metadata        :json             not null\n#  city                 :string\n#  country_code         :string\n#  email                :string           indexed\n#  geocode_metadata     :json             not null\n#  github_handle        :string\n#  github_metadata      :json             not null\n#  latitude             :decimal(10, 6)\n#  linkedin             :string           default(\"\"), not null\n#  location             :string           default(\"\")\n#  longitude            :decimal(10, 6)\n#  marked_for_deletion  :boolean          default(FALSE), not null, indexed\n#  mastodon             :string           default(\"\"), not null\n#  name                 :string           indexed\n#  password_digest      :string\n#  pronouns             :string           default(\"\"), not null\n#  pronouns_type        :string           default(\"not_specified\"), not null\n#  settings             :json             not null\n#  slug                 :string           default(\"\"), not null, uniquely indexed\n#  speakerdeck          :string           default(\"\"), not null\n#  state_code           :string\n#  suspicion_cleared_at :datetime\n#  suspicion_marked_at  :datetime\n#  talks_count          :integer          default(0), not null\n#  twitter              :string           default(\"\"), not null\n#  verified             :boolean          default(FALSE), not null\n#  watched_talks_count  :integer          default(0), not null\n#  website              :string           default(\"\"), not null\n#  created_at           :datetime         not null\n#  updated_at           :datetime         not null\n#  canonical_id         :integer          indexed\n#\n# Indexes\n#\n#  index_users_on_canonical_id         (canonical_id)\n#  index_users_on_email                (email)\n#  index_users_on_lower_github_handle  (lower(github_handle)) UNIQUE WHERE github_handle IS NOT NULL AND github_handle != ''\n#  index_users_on_marked_for_deletion  (marked_for_deletion)\n#  index_users_on_name                 (name)\n#  index_users_on_slug                 (slug) UNIQUE WHERE slug IS NOT NULL AND slug != ''\n#\n# rubocop:enable Layout/LineLength\nclass User < ApplicationRecord\n  include ActionView::RecordIdentifier\n  include Geocodeable\n  include Sluggable\n  include Suggestable\n\n  include User::SQLiteFTSSearchable\n  include User::TypesenseSearchable\n\n  geocodeable :location\n  configure_slug(attribute: :name, auto_suffix_on_collision: true)\n\n  has_delegated_json :settings,\n    feedback_enabled: true,\n    wrapped_public: false,\n    searchable: true\n\n  GITHUB_URL_PATTERN = %r{\\A(https?://)?(www\\.)?github\\.com/}i\n\n  PRONOUNS = {\n    \"Not specified\": :not_specified,\n    \"Don't specify\": :dont_specify,\n    \"they/them\": :they_them,\n    \"she/her\": :she_her,\n    \"he/him\": :he_him,\n    Custom: :custom\n  }.freeze\n\n  POSSESSIVE_PRONOUNS = {\n    \"she_her\" => \"her\",\n    \"he_him\" => \"his\",\n    \"they_them\" => \"their\"\n  }.freeze\n\n  has_secure_password validations: false\n\n  has_one_attached :wrapped_card\n  has_one_attached :wrapped_card_horizontal\n  has_one_attached :wrapped_og_image\n\n  # Authentication and user-specific associations\n  has_many :sessions, dependent: :destroy, inverse_of: :user\n  has_many :connected_accounts, dependent: :destroy\n  has_many :passports, -> { passport }, class_name: \"ConnectedAccount\"\n  has_many :watch_lists, dependent: :destroy\n  has_many :watched_talks, dependent: :destroy\n\n  # Speaker functionality associations\n  has_many :user_talks, dependent: :destroy, inverse_of: :user\n  has_many :talks, through: :user_talks, inverse_of: :speakers\n  has_many :kept_talks, -> { joins(:user_talks).where(user_talks: {discarded_at: nil}).distinct },\n    through: :user_talks, inverse_of: :speakers, class_name: \"Talk\", source: :talk\n  has_many :events, -> { distinct }, through: :talks, inverse_of: :speakers\n  has_many :canonical_aliases, class_name: \"User\", foreign_key: \"canonical_id\"\n  has_many :aliases, as: :aliasable, dependent: :destroy\n  has_many :topics, through: :talks\n\n  # Event participation associations\n  has_many :event_participations, dependent: :destroy\n  has_many :participated_events, through: :event_participations, source: :event\n  has_many :speaker_events, -> { where(event_participations: {attended_as: :speaker}) },\n    through: :event_participations, source: :event\n  has_many :keynote_speaker_events, -> { where(event_participations: {attended_as: :keynote_speaker}) },\n    through: :event_participations, source: :event\n  has_many :visitor_events, -> { where(event_participations: {attended_as: :visitor}) },\n    through: :event_participations, source: :event\n\n  has_many :event_involvements, as: :involvementable, dependent: :destroy\n  has_many :involved_events, through: :event_involvements, source: :event\n\n  # Favorite user associations\n  has_many :favorite_users, dependent: :destroy, inverse_of: :user\n  has_many :favorited_by, class_name: \"FavoriteUser\", foreign_key: \"favorite_user_id\", inverse_of: :favorite_user\n\n  belongs_to :canonical, class_name: \"User\", optional: true\n  belongs_to :city_record, class_name: \"City\", optional: true, inverse_of: false,\n    foreign_key: [:city, :country_code, :state_code], primary_key: [:name, :country_code, :state_code]\n  has_one :contributor, dependent: :nullify\n\n  has_object :profiles\n  has_object :talk_recommender\n  has_object :watched_talk_seeder\n  has_object :speakerdeck_feed\n  has_object :suspicion_detector\n  has_object :duplicate_detector\n\n  validates :email, format: {with: URI::MailTo::EMAIL_REGEXP}, allow_blank: true\n  validates :github_handle, presence: true, uniqueness: true, allow_blank: true\n  validates :canonical, exclusion: {in: ->(user) { [user] }, message: \"can't be itself\"}\n\n  normalizes :github_handle, with: ->(value) { normalize_github_handle(value) }\n\n  # Speaker-specific normalizations\n  normalizes :twitter, with: ->(value) { value.gsub(%r{https?://(?:www\\.)?(?:x\\.com|twitter\\.com)/}, \"\").gsub(/@/, \"\") }\n  normalizes :bsky, with: ->(value) {\n    value.gsub(%r{https?://(?:www\\.)?(?:x\\.com|bsky\\.app/profile)/}, \"\").gsub(/@/, \"\")\n  }\n  normalizes :linkedin, with: ->(value) { value.gsub(%r{https?://(?:www\\.)?(?:linkedin\\.com/in)/}, \"\") }\n\n  normalizes :mastodon, with: ->(value) {\n    return value if value&.match?(URI::DEFAULT_PARSER.make_regexp)\n    return \"\" unless value.count(\"@\") == 2\n\n    _, handle, instance = value.split(\"@\")\n\n    \"https://#{instance}/@#{handle}\"\n  }\n\n  normalizes :website, with: ->(website) {\n    return \"\" if website.blank?\n\n    # if it already starts with https://, return as is\n    return website if website.start_with?(\"https://\")\n\n    # if it starts with http://, return as is\n    return website if website.start_with?(\"http://\")\n\n    # otherwise, prepend https://\n    \"https://#{website}\"\n  }\n\n  encrypts :email, deterministic: true\n\n  before_validation if: -> { email.present? } do\n    self.email = email&.downcase&.strip\n  end\n\n  before_validation if: :email_changed?, on: :update do\n    self.verified = false\n  end\n\n  after_save :create_alias_for_previous_name, if: :saved_change_to_name?\n\n  # Speaker scopes\n  scope :with_talks, -> { where.not(talks_count: 0) }\n  scope :speakers, -> { where(\"talks_count > 0\") }\n  scope :with_github, -> { where.not(github_handle: [nil, \"\"]) }\n  scope :without_github, -> { where(github_handle: [nil, \"\"]) }\n  scope :canonical, -> { where(canonical_id: nil) }\n  scope :not_canonical, -> { where.not(canonical_id: nil) }\n  scope :marked_for_deletion, -> { where(marked_for_deletion: true) }\n  scope :not_marked_for_deletion, -> { where(marked_for_deletion: false) }\n  scope :with_public_wrapped, -> { where(\"json_extract(settings, '$.wrapped_public') = ?\", true) }\n  scope :with_feedback_enabled, -> { where(\"json_extract(settings, '$.feedback_enabled') = ?\", true) }\n  scope :searchable, -> { where(\"json_extract(settings, '$.searchable') = ?\", true) }\n  scope :indexable, -> {\n    canonical.not_marked_for_deletion.where(\"talks_count > 0 OR json_extract(settings, '$.searchable') = ?\", true)\n  }\n  scope :with_location, -> { where.not(location: [nil, \"\"]) }\n  scope :without_location, -> { where(location: [nil, \"\"]) }\n  scope :preloaded, -> { includes(:connected_accounts) }\n\n  def self.normalize_github_handle(value)\n    value\n      .gsub(GITHUB_URL_PATTERN, \"\")\n      .delete(\"@\")\n      .strip\n  end\n\n  def self.reset_talks_counts\n    find_each do |user|\n      user.update_column(:talks_count, user.talks.count)\n    end\n  end\n\n  def self.find_by_github_handle(handle)\n    return nil if handle.blank?\n    where(\"lower(github_handle) = ?\", handle.downcase).first\n  end\n\n  def self.find_by_name_or_alias(name)\n    return nil if name.blank?\n\n    user = find_by(name: name, marked_for_deletion: false)\n    return user if user\n\n    alias_record = ::Alias.find_by(aliasable_type: \"User\", name: name)\n    alias_record&.aliasable\n  end\n\n  def self.find_by_slug_or_alias(slug)\n    return nil if slug.blank?\n\n    user = find_by(slug: slug, marked_for_deletion: false)\n    return user if user\n\n    alias_record = ::Alias.find_by(aliasable_type: \"User\", slug: slug)\n    alias_record&.aliasable\n  end\n\n  # User-specific methods\n  def default_watch_list\n    @default_watch_list ||= watch_lists.first || watch_lists.create(name: \"Bookmarks\")\n  end\n\n  def main_participation_to(event)\n    event_participations.in_order_of(:attended_as, EventParticipation.attended_as.keys).where(event: event).first\n  end\n\n  # Speaker-specific methods (adapted from Speaker model)\n  def title\n    name\n  end\n\n  def country\n    return nil if country_code.blank?\n\n    Country.find_by(country_code: country_code)\n  end\n\n  def to_location\n    @to_location ||= Location.from_record(self)\n  end\n\n  def canonical_slug\n    canonical&.slug\n  end\n\n  def verified?\n    !suspicious? && connected_accounts.any? { |account| account.provider == \"github\" }\n  end\n\n  def indexable?\n    return false if canonical_id.present? || marked_for_deletion?\n    return true if talks_count > 0 # speakers are always searchable\n\n    searchable?\n  end\n\n  def ruby_passport_claimed?\n    connected_accounts.any? { |account| account.provider == \"passport\" }\n  end\n\n  def possessive_pronoun\n    POSSESSIVE_PRONOUNS[pronouns_type] || \"their\"\n  end\n\n  def contributor?\n    contributor.present?\n  end\n\n  def managed_by?(visiting_user)\n    return false unless visiting_user.present?\n    return true if visiting_user.admin?\n\n    self == visiting_user\n  end\n\n  def avatar_url(...)\n    bsky_avatar_url(...) || github_avatar_url(...) || fallback_avatar_url(...)\n  end\n\n  def avatar_rank\n    return 1 if bsky_avatar_url.present?\n    return 2 if github_avatar_url.present?\n\n    3\n  end\n\n  def custom_avatar?\n    bsky_avatar_url.present? || github_avatar_url.present?\n  end\n\n  def bsky_avatar_url(...)\n    bsky_metadata.dig(\"avatar\")\n  end\n\n  def github_avatar_url(size: 200)\n    return nil if github_handle.blank?\n\n    metadata_avatar_url = github_metadata.dig(\"profile\", \"avatar_url\")\n\n    return \"#{metadata_avatar_url}&size=#{size}\" if metadata_avatar_url.present?\n\n    \"https://github.com/#{github_handle}.png?size=#{size}\"\n  end\n\n  def fallback_avatar_url(size: 200)\n    url_safe_initials = name.split(\" \").map(&:first).join(\"+\")\n\n    \"https://ui-avatars.com/api/?name=#{url_safe_initials}&size=#{size}&background=DC133C&color=fff\"\n  end\n\n  def broadcast_header\n    broadcast_update target: dom_id(self, :header_content), partial: \"profiles/header_content\", locals: {user: self}\n  end\n\n  def to_meta_tags\n    {\n      title: name,\n      description: meta_description,\n      og: {\n        title: name,\n        type: :website,\n        image: {\n          _: github_avatar_url,\n          alt: name\n        },\n        description: meta_description,\n        site_name: \"RubyEvents.org\"\n      },\n      twitter: {\n        card: \"summary\",\n        site: \"@#{twitter}\",\n        title: name,\n        description: meta_description,\n        image: {\n          src: github_avatar_url\n        }\n      }\n    }\n  end\n\n  def to_combobox_display\n    name\n  end\n\n  def meta_description\n    return \"#{name}'s profile on RubyEvents.org\" if talks_count.zero?\n\n    top_topics = topics.group(:id).order(Arel.sql(\"COUNT(*) DESC\"), :name).limit(3).pluck(:name)\n\n    topic_text = if top_topics.any?\n      top_topics.to_sentence\n    else\n      \"Ruby language and Ruby Frameworks such as Rails, Hanami and others\"\n    end\n\n    \"Discover all the talks given by #{name} on subjects related to #{topic_text}.\"\n  end\n\n  def assign_canonical_speaker!(canonical_speaker:)\n    assign_canonical_user!(canonical_user: canonical_speaker)\n  end\n\n  def primary_speaker\n    canonical || self\n  end\n\n  def suggestion_summary\n    <<~HEREDOC\n      Speaker: #{name}\n      github_handle: #{github_handle}\n      twitter: #{twitter}\n      website: #{website}\n      bio: #{bio}\n    HEREDOC\n  end\n\n  def to_mobile_json(request)\n    {\n      id: id,\n      name: name,\n      slug: slug,\n      avatar_url: avatar_url,\n      url: Router.profile_url(self, host: \"#{request.protocol}#{request.host}:#{request.port}\")\n    }\n  end\n\n  def assign_canonical_user!(canonical_user:)\n    ActiveRecord::Base.transaction do\n      if name.present? && slug.present?\n        canonical_user.aliases.find_or_create_by!(name: name, slug: slug)\n      end\n\n      user_talks.each do |user_talk|\n        duplicated = user_talk.dup\n        duplicated.user = canonical_user\n        duplicated.save\n      end\n\n      event_participations.each do |participation|\n        duplicated = participation.dup\n        duplicated.user = canonical_user\n        duplicated.save\n      end\n\n      event_involvements.each do |involvement|\n        duplicated = involvement.dup\n        duplicated.involvementable = canonical_user\n        duplicated.save\n      end\n\n      user_talks.destroy_all\n      event_participations.destroy_all\n      event_involvements.destroy_all\n\n      update_columns(\n        canonical_id: canonical_user.id,\n        github_handle: nil,\n        slug: \"\",\n        marked_for_deletion: true\n      )\n    end\n  end\n\n  def set_slug\n    self.slug = slug.presence || github_handle.presence&.downcase\n    super\n  end\n\n  def create_alias_for_previous_name\n    previous_name, _current_name = saved_change_to_name\n\n    return if previous_name.blank?\n    return if connected_accounts.github.none?\n\n    previous_slug = previous_name.parameterize\n\n    return if aliases.exists?(name: previous_name)\n\n    aliases.create(name: previous_name, slug: previous_slug)\n  end\n\n  def speakerdeck_user_from_slides_url\n    handles = talks\n      .map(&:static_metadata).compact\n      .map(&:slides_url).compact\n      .select { |url| url.include?(\"speakerdeck.com\") }\n      .map { |url| url.split(\"/\")[3] }.uniq\n\n    (handles.count == 1) ? handles.first : nil\n  end\n\n  def to_param\n    github_handle.presence || slug\n  end\nend\n"
  },
  {
    "path": "app/models/user_talk.rb",
    "content": "# == Schema Information\n#\n# Table name: user_talks\n# Database name: primary\n#\n#  id           :integer          not null, primary key\n#  discarded_at :datetime\n#  created_at   :datetime         not null\n#  updated_at   :datetime         not null\n#  talk_id      :integer          not null, indexed, uniquely indexed => [user_id]\n#  user_id      :integer          not null, indexed, uniquely indexed => [talk_id]\n#\n# Indexes\n#\n#  index_user_talks_on_talk_id              (talk_id)\n#  index_user_talks_on_user_id              (user_id)\n#  index_user_talks_on_user_id_and_talk_id  (user_id,talk_id) UNIQUE\n#\n# Foreign Keys\n#\n#  talk_id  (talk_id => talks.id)\n#  user_id  (user_id => users.id)\n#\nclass UserTalk < ApplicationRecord\n  # mixins\n  include Discard::Model\n\n  # associations\n  belongs_to :user\n  belongs_to :talk, touch: true\n\n  validates :user_id, uniqueness: {scope: :talk_id}\n\n  # callbacks\n  after_commit :update_user_talks_count\n\n  private\n\n  def update_user_talks_count\n    user.update_column(:talks_count, user.kept_talks.count)\n  end\nend\n"
  },
  {
    "path": "app/models/watch_list.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: watch_lists\n# Database name: primary\n#\n#  id          :integer          not null, primary key\n#  description :text\n#  name        :string           not null\n#  talks_count :integer          default(0)\n#  created_at  :datetime         not null\n#  updated_at  :datetime         not null\n#  user_id     :integer          not null, indexed\n#\n# Indexes\n#\n#  index_watch_lists_on_user_id  (user_id)\n#\n# rubocop:enable Layout/LineLength\nclass WatchList < ApplicationRecord\n  belongs_to :user\n  has_many :watch_list_talks, dependent: :destroy\n  has_many :talks, through: :watch_list_talks\n\n  validates :name, presence: true\nend\n"
  },
  {
    "path": "app/models/watch_list_talk.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: watch_list_talks\n# Database name: primary\n#\n#  id            :integer          not null, primary key\n#  created_at    :datetime         not null\n#  updated_at    :datetime         not null\n#  talk_id       :integer          not null, indexed, uniquely indexed => [watch_list_id]\n#  watch_list_id :integer          not null, indexed, uniquely indexed => [talk_id]\n#\n# Indexes\n#\n#  index_watch_list_talks_on_talk_id                    (talk_id)\n#  index_watch_list_talks_on_watch_list_id              (watch_list_id)\n#  index_watch_list_talks_on_watch_list_id_and_talk_id  (watch_list_id,talk_id) UNIQUE\n#\n# Foreign Keys\n#\n#  talk_id        (talk_id => talks.id)\n#  watch_list_id  (watch_list_id => watch_lists.id)\n#\n# rubocop:enable Layout/LineLength\nclass WatchListTalk < ApplicationRecord\n  belongs_to :watch_list, counter_cache: :talks_count\n  belongs_to :talk\n  has_one :user, through: :watch_list, touch: true\n\n  validates :watch_list_id, uniqueness: {scope: :talk_id}\n\n  def reset_watch_list_counter_cache\n    WatchList.reset_counters(watch_list_id, :talks)\n  end\nend\n"
  },
  {
    "path": "app/models/watched_talk.rb",
    "content": "# == Schema Information\n#\n# Table name: watched_talks\n# Database name: primary\n#\n#  id                 :integer          not null, primary key\n#  feedback           :json\n#  feedback_shared_at :datetime\n#  progress_seconds   :integer          default(0), not null\n#  watched            :boolean          default(FALSE), not null\n#  watched_at         :datetime         not null\n#  watched_on         :string\n#  created_at         :datetime         not null\n#  updated_at         :datetime         not null\n#  talk_id            :integer          not null, indexed, uniquely indexed => [user_id]\n#  user_id            :integer          not null, uniquely indexed => [talk_id], indexed\n#\n# Indexes\n#\n#  index_watched_talks_on_talk_id              (talk_id)\n#  index_watched_talks_on_talk_id_and_user_id  (talk_id,user_id) UNIQUE\n#  index_watched_talks_on_user_id              (user_id)\n#\nclass WatchedTalk < ApplicationRecord\n  WATCHED_ON_OPTIONS = {\n    \"in_person\" => {label: \"In-person\", icon: \"users\"},\n    \"rubyevents\" => {label: \"RubyEvents.org\", icon: \"globe\"},\n    \"youtube\" => {label: \"YouTube\", icon: \"youtube-brands\"},\n    \"vimeo\" => {label: \"Vimeo\", icon: \"vimeo-v-brands\"},\n    \"mp4\" => {label: \"Direct video\", icon: \"video\"},\n    \"another_version\" => {label: \"Another version of this talk\", icon: \"clone\"},\n    \"other\" => {label: \"Other\", icon: \"ellipsis\"}\n  }.freeze\n\n  # These are designed to be constructive feedback for speakers\n  FEEDBACK_QUESTIONS = {\n    \"liked\" => {label: \"Did you enjoy this talk?\", icon: \"heart\"},\n    \"would_recommend\" => {label: \"Would you recommend it to a friend?\", icon: \"thumbs-up\"},\n    \"learned_something\" => {label: \"Did you learn something new?\", icon: \"lightbulb\"},\n    \"clear_delivery\" => {label: \"Was it easy to follow?\", icon: \"comment-check\"},\n    \"inspiring\" => {label: \"Did it inspire you to learn more?\", icon: \"rocket\"},\n    \"slides_readable\" => {label: \"Were the slides easy to read?\", icon: \"presentation-screen\"},\n    \"content_relevant\" => {label: \"Was the content relevant to you?\", icon: \"bullseye-arrow\"},\n    \"speaker_engaging\" => {label: \"Was the speaker engaging?\", icon: \"microphone\"}\n  }.freeze\n\n  EXPERIENCE_LEVELS = {\n    \"beginner\" => {label: \"Beginner\", icon: \"seedling\", description: \"New to the topic\"},\n    \"intermediate\" => {label: \"Intermediate\", icon: \"code\", description: \"Some experience needed\"},\n    \"advanced\" => {label: \"Advanced\", icon: \"graduation-cap\", description: \"Deep knowledge required\"}\n  }.freeze\n\n  CONTENT_FRESHNESS = {\n    \"evergreen\" => {label: \"Evergreen\", icon: \"tree\", description: \"Timeless concepts\"},\n    \"evolving\" => {label: \"Evolving\", icon: \"leaf\", description: \"Core ideas persist, details change\"},\n    \"time_sensitive\" => {label: \"Time-Sensitive\", icon: \"clock\", description: \"Fast-moving topic or specific versions\"}\n  }.freeze\n\n  FEELING_OPTIONS = {\n    \"enjoyed\" => {emoji: \"face-smile\", label: \"Enjoyed\", selected_class: \"border-green-500 bg-green-500 text-white hover:bg-green-600\"},\n    \"excited\" => {emoji: \"party-horn\", label: \"Excited\", selected_class: \"border-orange-500 bg-orange-500 text-white hover:bg-orange-600\"},\n    \"inspired\" => {emoji: \"lightbulb\", label: \"Inspired\", selected_class: \"border-yellow-500 bg-yellow-500 text-white hover:bg-yellow-600\"},\n    \"surprised\" => {emoji: \"face-surprise\", label: \"Surprised\", selected_class: \"border-pink-500 bg-pink-500 text-white hover:bg-pink-600\"},\n    \"mind_blown\" => {emoji: \"face-explode\", label: \"Mind-blown\", selected_class: \"border-purple-500 bg-purple-500 text-white hover:bg-purple-600\"},\n    \"reflective\" => {emoji: \"face-thinking\", label: \"Reflective\", selected_class: \"border-blue-500 bg-blue-500 text-white hover:bg-blue-600\"},\n    \"neutral\" => {emoji: \"face-meh\", label: \"Neutral\", selected_class: \"border-gray-400 bg-gray-400 text-white hover:bg-gray-500\"},\n    \"not_for_me\" => {emoji: \"face-meh-blank\", label: \"Not for me\", selected_class: \"border-gray-500 bg-gray-500 text-white hover:bg-gray-600\"}\n  }.freeze\n\n  belongs_to :user, default: -> { Current.user }, touch: true, counter_cache: :watched_talks_count\n  belongs_to :talk\n\n  scope :watched, -> { where(watched: true) }\n  scope :in_progress, -> { where(watched: false).where(\"progress_seconds > 0\") }\n\n  has_delegated_json :feedback,\n    **FEEDBACK_QUESTIONS.keys.to_h { |k| [k.to_sym, :boolean] },\n    feeling: :string,\n    experience_level: :string,\n    content_freshness: :string\n\n  before_create :set_default_watched_at\n\n  private\n\n  def set_default_watched_at\n    self.watched_at ||= Time.current\n  end\n\n  public\n\n  def progress_percentage\n    return 0.0 unless progress_seconds && talk.duration_in_seconds\n    return 0.0 if talk.duration_in_seconds.zero?\n\n    (progress_seconds.to_f / talk.duration_in_seconds * 100).round(2)\n  end\n\n  def has_feedback?\n    watched_on.present? || has_rating_feedback?\n  end\n\n  def has_rating_feedback?\n    feeling.present? ||\n      experience_level.present? ||\n      FEEDBACK_QUESTIONS.keys.any? { |key| send(key).present? }\n  end\n\n  def in_progress?\n    !watched? && progress_seconds.positive?\n  end\n\n  def self.watched_on_options_for(talk)\n    provider = talk.video_provider\n    video_providers = %w[youtube vimeo mp4]\n\n    options = WATCHED_ON_OPTIONS.reject do |key, _|\n      key.in?(video_providers) && key != provider\n    end\n\n    if provider.in?(Talk::WATCHABLE_PROVIDERS) && !options.key?(provider)\n      options[provider] = {label: provider.titleize, icon: \"video\"}\n    end\n\n    options\n  end\nend\n"
  },
  {
    "path": "app/models/youtube/null_parser.rb",
    "content": "# This class is used to keep the raw metadata when you want to feed them to chat GPT\n# for post processing\nmodule YouTube\n  class NullParser\n    def initialize(metadata:, event_name:, options: {})\n      @metadata = metadata\n      @event_name = event_name\n    end\n\n    def cleaned\n      OpenStruct.new(\n        {\n          title: @metadata.title,\n          event_name: @event_name,\n          description: @metadata.description,\n          raw_title: @metadata.title,\n          published_at: @metadata.published_at,\n          video_provider: \"youtube\",\n          video_id: @metadata.video_id\n        }\n      )\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/youtube/video_metadata.rb",
    "content": "# require \"active_support/core_ext/hash/keys\"\n\n# This class is used to extract the metadata from a youtube video\n# it will try to:\n# - extract the speakers from the title\n# - remove the event_name from the title to make less redondant\n# - remove leading separators from the title\nmodule YouTube\n  class VideoMetadata\n    SPEAKERS_SECTION_SEPARATOR = \" by \"\n    SEPARATOR_IN_BETWEEN_SPEAKERS = / & |, | and /\n\n    def initialize(metadata:, event_name:, options: {})\n      @metadata = metadata\n      @event_name = event_name\n    end\n\n    def cleaned\n      OpenStruct.new(\n        {\n          title: title,\n          raw_title: raw_title,\n          speakers: speakers,\n          date: \"TODO\",\n          event_name: @event_name,\n          published_at: @metadata.published_at,\n          announced_at: \"TODO\",\n          description: description,\n          video_provider: \"youtube\",\n          video_id: @metadata.video_id\n        }\n      )\n    end\n\n    def keynote?\n      title_without_event_name.match(/keynote/i)\n    end\n\n    def lighting?\n      title_without_event_name.match(/lightning talks/i)\n    end\n\n    private\n\n    def extract_info_from_title\n      title_parts = title_without_event_name.split(SPEAKERS_SECTION_SEPARATOR)\n      speakers = title_parts.last.split(SEPARATOR_IN_BETWEEN_SPEAKERS).map(&:strip)\n      title = title_parts[0..-2].join(SPEAKERS_SECTION_SEPARATOR).gsub(/^\\s*-/, \"\").strip\n\n      {\n        title: keynote? ? remove_leading_and_trailing_separators_from(title_without_event_name) : remove_leading_and_trailing_separators_from(title),\n        speakers: speakers\n      }\n    end\n\n    def speakers\n      return [] if lighting?\n\n      title_parts = title_without_event_name.split(SPEAKERS_SECTION_SEPARATOR)\n      title_parts.last.split(SEPARATOR_IN_BETWEEN_SPEAKERS).map(&:strip)\n    end\n\n    def raw_title\n      @metadata.title\n    end\n\n    def title_without_event_name\n      # RubyConf AU 2013: From Stubbies to Longnecks by Geoffrey Giesemann\n      # will return \"From Stubbies to Longnecks by Geoffrey Giesemann\"\n      remove_leading_and_trailing_separators_from(raw_title.gsub(@event_name, \"\").gsub(/\\s+/, \" \"))\n    end\n\n    ## remove : - and other separators from the title\n    def remove_leading_and_trailing_separators_from(title)\n      title.gsub(/^[-:]?/, \"\").strip.then do |title|\n        title.gsub(/[-:,]$/, \"\").strip\n      end\n    end\n\n    def title\n      if keynote? || lighting?\n        # when it is a keynote or lighting, usually we want to keep the full title without the event name\n        remove_leading_and_trailing_separators_from(title_without_event_name)\n      else\n        title_parts = title_without_event_name.split(SPEAKERS_SECTION_SEPARATOR)\n        title = title_parts[0..-2].join(SPEAKERS_SECTION_SEPARATOR).gsub(/^\\s*-/, \"\").strip\n        remove_leading_and_trailing_separators_from(title)\n      end\n    end\n\n    def description\n      @metadata.description\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/youtube/video_metadata_baltic_ruby_2024.rb",
    "content": "module YouTube\n  class VideoMetadataBalticRuby2024\n    SPEAKERS_SECTION_SEPARATOR = \" - \"\n    SEPARATOR_IN_BETWEEN_SPEAKERS = / & |, | and /\n\n    def initialize(metadata:, event_name:, options: {})\n      @metadata = metadata\n      @event_name = event_name\n    end\n\n    def cleaned\n      OpenStruct.new(\n        {\n          title: title,\n          raw_title: raw_title,\n          speakers: speakers,\n          event_name: @event_name,\n          published_at: @metadata.published_at,\n          description: description_without_speaker,\n          video_provider: :youtube,\n          video_id: @metadata.video_id\n        }\n      )\n    end\n\n    def keynote?\n      raw_description.match(/keynote/i)\n    end\n\n    private\n\n    def speakers\n      speaker_line = raw_description.split(\"\\n\").find { |line| line.downcase.include?(\"speaker\") }\n\n      _, names = speaker_line.split(\":\")\n\n      return [] if speaker_line.blank?\n\n      raw_speakers = names.split(SEPARATOR_IN_BETWEEN_SPEAKERS)\n\n      raw_speakers.map { |speaker|\n        remove_leading_and_trailing_separators_from(speaker).split(\" \").map { |name| name.capitalize }.join(\" \")\n      }\n    end\n\n    def raw_title\n      @metadata.title\n    end\n\n    def title_without_event_name\n      remove_leading_and_trailing_separators_from(raw_title.gsub(@event_name, \"\").gsub(/\\s+/, \" \"))\n    end\n\n    def remove_leading_and_trailing_separators_from(title)\n      return title if title.blank?\n\n      title.gsub(/^[-:]?/, \"\").strip.then do |title|\n        title.gsub(/[-:,.]$/, \"\").strip\n      end\n    end\n\n    def title\n      t = remove_leading_and_trailing_separators_from(title_without_event_name).to_s.delete('\"')\n\n      keynote? ? \"Keynote: #{t}\" : t\n    end\n\n    def raw_description\n      @metadata.description\n    end\n\n    def description_without_speaker\n      @metadata.description.split(\"\\n\").reject { |line| line.downcase.include?(\"speaker\") }.join(\"\\n\").strip\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/youtube/video_metadata_kaigi_on_rails.rb",
    "content": "module YouTube\n  class VideoMetadataKaigiOnRails < VideoMetadata\n    # TODO: `SPEAKERS_SECTION_SEPARATOR` should be a method so that chldren classes can override it\n    def title\n      if keynote? || lighting?\n        # when it is a keynote or lighting, usually we want to keep the full title without the event name\n        remove_leading_and_trailing_separators_from(title_without_event_name)\n      else\n        title = title_parts[0..-2].join(SPEAKERS_SECTION_SEPARATOR).gsub(/^\\s*-/, \"\").strip\n        remove_leading_and_trailing_separators_from(title)\n      end\n    end\n\n    def speakers\n      title_parts.last.split(SEPARATOR_IN_BETWEEN_SPEAKERS).map(&:strip)\n    end\n\n    private\n\n    def title_parts\n      title_without_event_name.split(\" / \")\n    end\n  end\nend\n"
  },
  {
    "path": "app/models/youtube/video_metadata_rails_world.rb",
    "content": "# require \"active_support/core_ext/hash/keys\"\n\n# This class is used to extract the metadata from a youtube video\n# it will try to:\n# - extract the speakers from the title\n# - remove the event_name from the title to make less redondant\n# - remove leading separators from the title\nmodule YouTube\n  class VideoMetadataRailsWorld\n    SPEAKERS_SECTION_SEPARATOR = \" - \"\n    SEPARATOR_IN_BETWEEN_SPEAKERS = / & |, | and /\n\n    def initialize(metadata:, event_name:, options: {})\n      @metadata = metadata\n      @event_name = event_name\n    end\n\n    def cleaned\n      OpenStruct.new(\n        {\n          title: title,\n          raw_title: raw_title,\n          speakers: speakers,\n          event_name: @event_name,\n          published_at: @metadata.published_at,\n          description: description,\n          video_provider: :youtube,\n          video_id: @metadata.video_id\n        }\n      )\n    end\n\n    def keynote?\n      title_without_event_name.match(/keynote/i)\n    end\n\n    private\n\n    def extract_info_from_title\n      title_parts = title_without_event_name.split(SPEAKERS_SECTION_SEPARATOR)\n      speakers = title_parts.last.split(SEPARATOR_IN_BETWEEN_SPEAKERS).map(&:strip)\n      title = title_parts[0..-2].join(SPEAKERS_SECTION_SEPARATOR).gsub(/^\\s*-/, \"\").strip\n\n      {\n        title: keynote? ? remove_leading_and_trailing_separators_from(title_without_event_name) : remove_leading_and_trailing_separators_from(title),\n        speakers: speakers\n      }\n    end\n\n    def speakers\n      raw_title_parts.first.split(SEPARATOR_IN_BETWEEN_SPEAKERS).map(&:strip)\n    end\n\n    def raw_title\n      @metadata.title\n    end\n\n    def title_without_event_name\n      # RubyConf AU 2013: From Stubbies to Longnecks by Geoffrey Giesemann\n      # will return \"From Stubbies to Longnecks by Geoffrey Giesemann\"\n      remove_leading_and_trailing_separators_from(raw_title.gsub(@event_name, \"\").gsub(/\\s+/, \" \"))\n    end\n\n    ## remove : - and other separators from the title\n    def remove_leading_and_trailing_separators_from(title)\n      return title if title.blank?\n\n      title.gsub(/^[-:]?/, \"\").strip.then do |title|\n        title.gsub(/[-:,]$/, \"\").strip\n      end\n    end\n\n    def title\n      remove_leading_and_trailing_separators_from(raw_title_parts[1])\n    end\n\n    def description\n      @metadata.description\n    end\n\n    def raw_title_parts\n      title_without_event_name.split(SPEAKERS_SECTION_SEPARATOR)\n    end\n  end\nend\n"
  },
  {
    "path": "app/schemas/address_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass AddressSchema < RubyLLM::Schema\n  string :street, description: \"Street address\"\n  string :city, description: \"City name\"\n  string :region, description: \"State/Province/Region\", required: false\n  string :postal_code, description: \"Postal/ZIP code\", required: false\n  string :country, description: \"Country name\"\n  string :country_code, description: \"ISO country code (e.g., 'US', 'CA', 'JP')\"\n  string :display, description: \"Full formatted address for display\"\nend\n"
  },
  {
    "path": "app/schemas/cfp_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass CFPSchema < RubyLLM::Schema\n  string :link, description: \"CFP link\", required: true\n  string :name, description: 'Name for the CFP (default: \"Call for Proposals\")', required: false\n  string :open_date, description: \"CFP open date (YYYY-MM-DD format)\", required: false\n  string :close_date, description: \"CFP close date (YYYY-MM-DD format)\", required: false\nend\n"
  },
  {
    "path": "app/schemas/coordinates_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass CoordinatesSchema < RubyLLM::Schema\n  number :latitude, description: \"Latitude coordinate\"\n  number :longitude, description: \"Longitude coordinate\"\nend\n"
  },
  {
    "path": "app/schemas/event_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass EventSchema < RubyLLM::Schema\n  string :id, description: \"Unique identifier for the event (YouTube playlist ID or custom slug)\"\n\n  string :title, description: \"Full name of the event (e.g., 'RailsConf 2024')\"\n  string :description, description: \"Description of the event\", required: false\n  array :aliases, of: :string, description: \"Alternative names for the event\", required: false\n\n  string :kind, description: \"Type of event\", enum: [\"conference\", \"meetup\", \"retreat\", \"hackathon\", \"event\", \"workshop\"], required: true\n  boolean :hybrid, description: \"Whether the event has both in-person and online attendance\", required: false\n  string :status,\n    description: \"Event status\",\n    enum: [\"cancelled\", \"postponed\", \"scheduled\"],\n    required: false\n  boolean :last_edition, description: \"Whether this is the last edition of the event\", required: false\n\n  string :start_date, description: \"Start date of the event (YYYY-MM-DD format)\", required: false\n  string :end_date, description: \"End date of the event (YYYY-MM-DD format)\", required: false\n  string :published_at, description: \"Date when videos were published (YYYY-MM-DD format)\", required: false\n  string :announced_on, description: \"Date when the event was announced (YYYY-MM-DD format)\", required: false\n  integer :year, description: \"Year of the event\", required: false\n  string :date_precision,\n    description: \"Precision of the date (when exact dates are unknown)\",\n    enum: [\"year\", \"month\", \"day\"],\n    required: false\n  string :frequency, description: \"How often the event occurs (for recurring meetups)\", required: false\n\n  string :location, description: \"Location in 'City, Country' format (e.g., 'Detroit, MI' or 'Tokyo, Japan')\"\n  string :venue, description: \"Name of the venue\", required: false\n\n  string :channel_id, description: \"YouTube channel ID (starts with UC...)\", required: false\n  string :playlist, description: \"YouTube playlist/Vimeo showcase link\", required: false\n\n  string :website, description: \"Official event website URL\", required: false\n  string :original_website, description: \"Original/archived website URL\", required: false\n  string :twitter, description: \"Twitter/X handle (without @)\", required: false\n  string :mastodon, description: \"Full Mastodon profile URL\", required: false\n  string :github, description: \"GitHub organization or repository URL\", required: false\n  string :meetup, description: \"Meetup.com group URL\", required: false\n  string :luma, description: \"Luma event URL\", required: false\n  string :youtube, description: \"YouTube channel or video URL\", required: false\n  string :tickets_url, description: \"URL to purchase tickets (e.g., Tito, Eventbrite, Luma)\", required: false\n\n  string :banner_background,\n    description: \"CSS background value for the banner (color or gradient)\",\n    required: false\n  string :featured_background,\n    description: \"CSS background color for featured cards\",\n    required: false\n  string :featured_color,\n    description: \"CSS text color for featured cards\",\n    required: false\n\n  any_of :coordinates, description: \"Geographic coordinates (use 'coordinates: false' for online events)\" do\n    object do\n      number :latitude, description: \"Latitude coordinate\"\n      number :longitude, description: \"Longitude coordinate\"\n    end\n\n    boolean\n  end\nend\n"
  },
  {
    "path": "app/schemas/featured_city_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass FeaturedCitySchema < RubyLLM::Schema\n  string :name, description: \"Full city name\"\n  string :slug, description: \"URL-friendly slug for the city\"\n  string :state_code, description: \"State or province code\", required: false\n  string :country_code, description: \"ISO 3166-1 alpha-2 country code\"\n  number :latitude, description: \"Geographic latitude\"\n  number :longitude, description: \"Geographic longitude\"\n  array :aliases, of: :string, description: \"Alternative names or abbreviations\", required: false\n\n  def to_json_schema\n    result = super\n    result[:schema][:properties][:state_code][:type] = [\"string\", \"null\"]\n    result\n  end\nend\n"
  },
  {
    "path": "app/schemas/hotel_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass HotelSchema < RubyLLM::Schema\n  string :name, description: \"Hotel name\"\n  string :kind, description: \"Type of hotel (e.g., 'Speaker Hotel')\", required: false\n  string :description, description: \"Hotel description\", required: false\n  object :address, of: AddressSchema, description: \"Hotel address\"\n  string :url, description: \"Hotel website URL\", required: false\n  string :distance, description: \"Distance from venue\", required: false\n  object :coordinates, of: CoordinatesSchema\n  object :maps, of: MapsSchema, required: false\nend\n"
  },
  {
    "path": "app/schemas/involvement_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass InvolvementSchema < RubyLLM::Schema\n  string :name, description: \"Role or involvement type (e.g., 'Organizer', 'Program Committee member')\"\n  array :users, of: :string, description: \"Person names involved in this role\", required: false\n  array :organisations, of: :string, description: \"Organization names involved in this role\", required: false\nend\n"
  },
  {
    "path": "app/schemas/location_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass LocationSchema < RubyLLM::Schema\n  string :name, description: \"Location name\"\n  string :kind, description: \"Type of location (e.g., 'After Party Location')\"\n  string :description, description: \"Location description\", required: false\n  object :address, of: AddressSchema, description: \"Location address\", required: false\n  string :distance, description: \"Distance from main venue\", required: false\n  string :url, description: \"Location website URL\", required: false\n  object :coordinates, of: CoordinatesSchema\n  object :maps, of: MapsSchema, required: false\nend\n"
  },
  {
    "path": "app/schemas/maps_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass MapsSchema < RubyLLM::Schema\n  string :google, description: \"Google Maps URL\", required: false\n  string :apple, description: \"Apple Maps URL\", required: false\n  string :openstreetmap, description: \"OpenStreetMap URL\", required: false\nend\n"
  },
  {
    "path": "app/schemas/schedule_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass ScheduleSchema < RubyLLM::Schema\n  array :days, description: \"List of conference days\" do\n    object do\n      string :name, description: \"Name of the day (e.g., 'Day 1', 'Workshop Day')\"\n      string :date, description: \"Date of the day (YYYY-MM-DD format)\"\n\n      array :grid, description: \"Time slots for the day\", required: false do\n        object do\n          string :start_time, description: \"Start time (HH:MM format)\"\n          string :end_time, description: \"End time (HH:MM format)\"\n          integer :slots, description: \"Number of parallel tracks/slots\", required: false\n          string :description, description: \"Description of the time slot\", required: false\n\n          array :items, description: \"Items in this time slot\", required: false do\n            any_of do\n              string description: \"Simple item name (e.g., 'Lunch', 'Break')\"\n\n              object do\n                string :title, description: \"Title of the session\"\n                string :description, description: \"Description of the session\", required: false\n                array :speakers, of: :string, description: \"List of speaker names\", required: false\n                string :track, description: \"Track name\", required: false\n                string :room, description: \"Room name/number\", required: false\n              end\n            end\n          end\n        end\n      end\n    end\n  end\n\n  array :tracks, description: \"Track definitions for the schedule\", required: false do\n    object do\n      string :name, description: \"Track name\"\n      string :color, description: \"Track color (hex)\", required: false\n      string :text_color, description: \"Text color for the track (hex)\", required: false\n    end\n  end\nend\n"
  },
  {
    "path": "app/schemas/series_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass SeriesSchema < RubyLLM::Schema\n  string :name, description: \"Name of the event series (e.g., 'RailsConf')\"\n  string :description, description: \"Description of the event series\", required: false\n\n  string :kind,\n    description: \"Type of event series\",\n    enum: [\"conference\", \"meetup\", \"retreat\", \"hackathon\", \"event\", \"podcast\", \"online\", \"organisation\", \"workshop\"],\n    required: false\n  string :frequency,\n    description: \"How often the event occurs\",\n    enum: [\"yearly\", \"monthly\", \"weekly\", \"irregular\", \"biweekly\", \"biyearly\", \"quarterly\"],\n    required: false\n  boolean :ended, description: \"Whether the event series has ended\", required: false\n\n  string :default_country_code, description: \"Default ISO country code (e.g., 'US', 'JP')\", required: false\n\n  string :language, description: \"Primary language of the event (e.g., 'english', 'japanese')\", required: false\n\n  string :website, description: \"Official website URL\", required: false\n  string :original_website, description: \"Original/archived website URL\", required: false\n  string :twitter, description: \"Twitter/X handle (without @)\", required: false\n  string :mastodon, description: \"Full Mastodon profile URL\", required: false\n  string :bsky, description: \"Bluesky handle\", required: false\n  string :github, description: \"GitHub organization or repository\", required: false\n  string :linkedin, description: \"LinkedIn page URL\", required: false\n  string :meetup, description: \"Meetup.com group URL\", required: false\n  string :luma, description: \"Luma event URL\", required: false\n  string :guild, description: \"Guild.host URL\", required: false\n  string :vimeo, description: \"Vimeo channel URL\", required: false\n\n  string :youtube_channel_id, description: \"YouTube channel ID (starts with UC...)\", required: false\n  string :youtube_channel_name, description: \"YouTube channel name\", required: false\n  string :playlist_matcher, description: \"Pattern to match playlists for this series\", required: false\n\n  array :aliases, of: :string, description: \"Alternative names for the series\", required: false\nend\n"
  },
  {
    "path": "app/schemas/speaker_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass SpeakerSchema < RubyLLM::Schema\n  string :name, description: \"Full name of the speaker\", required: true\n  string :slug, description: \"URL-friendly slug for the speaker\", required: true\n  string :github, description: \"GitHub username\", required: true\n\n  string :twitter, description: \"Twitter/X handle (without @)\", required: false\n  string :website, description: \"Personal website URL\", required: false\n  string :mastodon, description: \"Full Mastodon profile URL\", required: false\n  string :bluesky, description: \"Bluesky handle\", required: false\n  string :linkedin, description: \"LinkedIn profile URL\", required: false\n  string :speakerdeck, description: \"Speakerdeck profile URL\", required: false\n\n  array :aliases, description: \"Alternative names for the speaker\", required: false do\n    object do\n      string :name, required: true\n      string :slug, required: true\n    end\n  end\n\n  string :canonical_slug, description: \"Slug of the canonical speaker profile (for deduplication)\", required: false\nend\n"
  },
  {
    "path": "app/schemas/sponsors_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass SponsorsSchema < RubyLLM::Schema\n  array :tiers, description: \"List of sponsorship tiers\", required: true do\n    object do\n      string :name, description: \"Sponsorship Tier Name\", required: false\n      string :description, description: \"Description of the sponsorship tier\", required: false\n      integer :level, description: \"Sponsorship level (lower number indicates higher level)\", required: false\n      array :sponsors, description: \"List of sponsors in this tier\", required: true do\n        object do\n          string :name, description: \"Sponsor Name\", required: true\n          string :slug, description: \"Sponsor identifier slug\", required: true\n          string :website, description: \"Sponsor's website URL\", required: true\n          string :description, description: \"Description of the sponsor\", required: false\n          string :logo_url, description: \"URL to the sponsor's logo image\", required: false\n          string :badge, description: \"Sponsor badge text\", required: false\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/schemas/transcript_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass TranscriptSchema < RubyLLM::Schema\n  string :video_id, description: \"Video ID on the provider platform\"\n  array :cues, description: \"Transcript cues\" do\n    object do\n      string :start_time, description: \"Start timestamp (HH:MM:SS.mmm)\"\n      string :end_time, description: \"End timestamp (HH:MM:SS.mmm)\"\n      string :text, description: \"Transcript text for this cue\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/schemas/venue_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass VenueSchema < RubyLLM::Schema\n  string :name, description: \"Name of the venue\"\n  string :description, description: \"Description of the venue\", required: false\n  string :instructions, description: \"Instructions for getting to the venue\", required: false\n  string :url, description: \"Venue website URL\", required: false\n\n  object :address, of: AddressSchema, description: \"Physical address of the venue\"\n  object :coordinates, of: CoordinatesSchema, description: \"Geographic coordinates\"\n  object :maps, of: MapsSchema, description: \"Links to various map services\", required: false\n\n  array :locations, of: LocationSchema, description: \"Additional event locations\", required: false\n  array :hotels, of: HotelSchema, description: \"Recommended hotels near the venue\", required: false\n\n  array :rooms, description: \"Rooms within the venue\", required: false do\n    object do\n      string :name, description: \"Room name\"\n      string :floor, description: \"Floor location\", required: false\n      integer :capacity, description: \"Room capacity\", required: false\n      string :instructions, description: \"Instructions for finding the room\", required: false\n    end\n  end\n\n  array :spaces, description: \"Other spaces within the venue\", required: false do\n    object do\n      string :name, description: \"Space name\"\n      string :floor, description: \"Floor location\", required: false\n      string :instructions, description: \"Instructions for finding the space\", required: false\n    end\n  end\n\n  object :accessibility, description: \"Accessibility information\", required: false do\n    boolean :wheelchair, description: \"Wheelchair accessible\", required: false\n    boolean :elevators, description: \"Elevators available\", required: false\n    boolean :accessible_restrooms, description: \"Accessible restrooms available\", required: false\n    string :notes, description: \"Additional accessibility notes\", required: false\n  end\n\n  object :nearby, description: \"Nearby amenities and transportation\", required: false do\n    string :public_transport, description: \"Public transportation options\", required: false\n    string :parking, description: \"Parking information\", required: false\n  end\nend\n"
  },
  {
    "path": "app/schemas/video_schema.rb",
    "content": "# frozen_string_literal: true\n\nclass VideoSchema < RubyLLM::Schema\n  string :id, description: \"Unique identifier for the video\", required: true\n  string :title, description: \"Title of the talk\"\n  string :raw_title, description: \"Original/raw title from the video source\", required: false\n  string :original_title, description: \"Original title in native language\", required: false\n  string :description, description: \"Description of the talk\"\n  string :slug, description: \"URL-friendly slug\", required: false\n  string :kind, description: \"Type of video (e.g., 'keynote', 'lightning')\", required: false\n  string :status, description: \"Status of the video\", required: false\n\n  array :speakers, of: :string, description: \"List of speaker names\", required: false\n\n  array :talks, description: \"Sub-talks for panel discussions\", required: false do\n    object do\n      string :id, required: true\n      string :title, required: false\n      string :raw_title, required: false\n      string :description, required: false\n      array :speakers, of: :string, required: false\n      string :event_name, required: false\n      string :date, required: false\n      string :published_at, required: false\n      string :announced_at, required: false\n      string :video_provider, description: \"Use 'parent' if there is one video\", required: true\n      string :video_id, required: true\n      string :language, required: false\n      string :track, required: false\n      string :location, description: \"Location within the venue\", required: false\n      string :start_cue, description: \"Start time cue in video\", required: false\n      string :end_cue, description: \"End time cue in video\", required: false\n      string :thumbnail_cue, description: \"Thumbnail time cue\", required: false\n      string :slides_url, required: false\n      array :additional_resources, required: false do\n        object do\n          string :name, required: true\n          string :url, required: true\n          string :type, enum: [\"write-up\", \"blog\", \"article\", \"source-code\", \"code\", \"repo\", \"github\", \"documentation\", \"docs\", \"presentation\", \"video\", \"podcast\", \"audio\", \"gem\", \"library\", \"transcript\", \"handout\", \"notes\", \"photos\", \"link\"], required: true\n          string :title, required: false\n        end\n      end\n      string :thumbnail_xs, required: false\n      string :thumbnail_sm, required: false\n      string :thumbnail_md, required: false\n      string :thumbnail_lg, required: false\n      string :thumbnail_xl, required: false\n      string :thumbnail_classes, required: false\n      array :alternative_recordings, required: false do\n        object do\n          string :title, required: false\n          string :raw_title, required: false\n          string :published_at, required: false\n          array :speakers, of: :string, required: false\n          string :video_provider, required: false\n          string :video_id, required: false\n          string :url, required: false\n        end\n      end\n    end\n  end\n\n  string :event_name, description: \"Name of the event (e.g., 'RailsConf 2024')\", required: false\n  string :date, description: \"Date of the talk (YYYY-MM-DD format)\", required: true\n  string :time, description: \"Time of the talk\", required: false\n  string :published_at, description: \"Date when the video was published (YYYY-MM-DD format)\", required: false\n  string :announced_at, description: \"Date when the talk was announced\", required: false\n  string :location, description: \"Location within the venue\", required: false\n\n  string :video_provider,\n    description: \"Video hosting provider\",\n    enum: [\"youtube\", \"vimeo\", \"not_recorded\", \"scheduled\", \"mp4\", \"parent\", \"children\", \"not_published\"]\n  string :video_id, description: \"Video ID on the provider platform\"\n\n  boolean :external_player, description: \"Whether to use external player\", required: false\n  string :external_player_url, description: \"URL for external player\", required: false\n\n  array :alternative_recordings, description: \"Alternative video recordings\", required: false do\n    object do\n      string :title, required: false\n      string :raw_title, required: false\n      string :language, required: false\n      string :date, required: false\n      string :description, required: false\n      string :published_at, required: false\n      string :event_name, required: false\n      array :speakers, of: :string, required: false\n      string :video_provider, required: false\n      string :video_id, required: false\n      string :external_url, required: false\n    end\n  end\n\n  string :track, description: \"Conference track (e.g., 'Main Stage', 'Workshop')\", required: false\n  string :language, description: \"Language of the talk\", required: false\n\n  string :slides_url, description: \"URL to the slides\", required: false\n\n  array :additional_resources, description: \"Additional resources related to the talk\", required: false do\n    object do\n      string :name, description: \"Display name for the resource\", required: true\n      string :url, description: \"URL to the resource\", required: true\n      string :type, description: \"Type of resource\", enum: [\"write-up\", \"blog\", \"article\", \"source-code\", \"code\", \"repo\", \"github\", \"documentation\", \"docs\", \"presentation\", \"video\", \"podcast\", \"audio\", \"gem\", \"library\", \"transcript\", \"handout\", \"notes\", \"photos\", \"link\", \"book\"], required: true\n      string :title, description: \"Full title of the resource\", required: false\n    end\n  end\n\n  string :thumbnail_xs, description: \"Extra small thumbnail URL\", required: false\n  string :thumbnail_sm, description: \"Small thumbnail URL\", required: false\n  string :thumbnail_md, description: \"Medium thumbnail URL\", required: false\n  string :thumbnail_lg, description: \"Large thumbnail URL\", required: false\n  string :thumbnail_xl, description: \"Extra large thumbnail URL\", required: false\n  string :thumbnail_classes, description: \"CSS classes for thumbnail\", required: false\nend\n"
  },
  {
    "path": "app/serializers/transcript_serializer.rb",
    "content": "class TranscriptSerializer\n  def self.dump(transcript)\n    raise \"Transcript is not a valid object\" unless transcript.is_a?(Transcript)\n\n    transcript.to_json\n  end\n\n  def self.load(transcript_json)\n    transcript = Transcript.new\n    return transcript if transcript_json.nil? || transcript_json.empty?\n\n    cues_array = JSON.parse(transcript_json, symbolize_names: true)\n    cues_array.each do |cue_hash|\n      transcript.add_cue(Cue.new(start_time: cue_hash[:start_time], end_time: cue_hash[:end_time], text: cue_hash[:text]))\n    end\n    transcript\n  end\nend\n"
  },
  {
    "path": "app/tools/cfp_create_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass CFPCreateTool < RubyLLM::Tool\n  description \"Create a CFP (Call for Proposals) for an event. Writes to the event's cfp.yml file.\"\n\n  param :event_query, desc: \"Event slug or name to find (e.g., 'tropical-on-rails-2026' or 'Tropical on Rails 2026')\"\n  param :link, desc: \"URL to the CFP submission page (e.g., 'https://cfp.example.com')\"\n  param :open_date, desc: \"Date when CFP opens (YYYY-MM-DD format)\", required: false\n  param :close_date, desc: \"Date when CFP closes (YYYY-MM-DD format)\", required: false\n  param :name, desc: \"Optional name for this CFP (e.g., 'Lightning Talks CFP'). Only needed if the event has multiple CFPs.\", required: false\n\n  def execute(event_query:, link:, open_date: nil, close_date: nil, name: \"Call for Proposals\")\n    event = find_event(event_query)\n    return {error: \"Event not found for query: #{event_query}\"} if event.nil?\n\n    result = event.cfp_file.add(\n      link: link,\n      open_date: open_date,\n      close_date: close_date,\n      name: name\n    )\n\n    return result if result.is_a?(Hash) && result[:error]\n\n    {\n      success: true,\n      event: event.name,\n      cfp_file: event.cfp_file.file_path.to_s.sub(Rails.root.to_s + \"/\", \"\"),\n      cfp: result\n    }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def find_event(query)\n    Event.find_by(slug: query) ||\n      Event.find_by(slug: query.parameterize) ||\n      Event.find_by(name: query) ||\n      Event.ft_search(query).first\n  end\nend\n"
  },
  {
    "path": "app/tools/cfp_info_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass CFPInfoTool < RubyLLM::Tool\n  description \"Get CFP (Call for Proposals) information for an event. Returns all CFPs with their links, dates, and status.\"\n\n  param :event_query, desc: \"Event slug or name to find (e.g., 'tropical-on-rails-2026' or 'Tropical on Rails 2026')\"\n\n  def execute(event_query:)\n    event = find_event(event_query)\n    return {error: \"Event not found for query: #{event_query}\"} if event.nil?\n\n    cfps = event.cfp_file.entries\n\n    return {event: event.name, cfps: [], message: \"No CFPs found for this event\"} if cfps.empty?\n\n    {\n      event: event.name,\n      cfp_file: event.cfp_file.file_path.to_s.sub(Rails.root.to_s + \"/\", \"\"),\n      cfps: cfps.map { |cfp| format_cfp(cfp) }\n    }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def find_event(query)\n    Event.find_by(slug: query) ||\n      Event.find_by(slug: query.parameterize) ||\n      Event.find_by(name: query) ||\n      Event.ft_search(query).first\n  end\n\n  def format_cfp(cfp)\n    {\n      name: cfp[\"name\"],\n      link: cfp[\"link\"],\n      open_date: cfp[\"open_date\"],\n      close_date: cfp[\"close_date\"],\n      status: cfp_status(cfp)\n    }\n  end\n\n  def cfp_status(cfp)\n    today = Date.current\n    open_date = cfp[\"open_date\"] ? Date.parse(cfp[\"open_date\"]) : nil\n    close_date = cfp[\"close_date\"] ? Date.parse(cfp[\"close_date\"]) : nil\n\n    if close_date && today > close_date\n      \"closed\"\n    elsif open_date && today < open_date\n      \"upcoming\"\n    elsif open_date && (close_date.nil? || today <= close_date)\n      \"open\"\n    else\n      \"unknown\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/tools/cfp_update_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass CFPUpdateTool < RubyLLM::Tool\n  description \"Update an existing CFP (Call for Proposals) for an event. Use this to add or modify dates on an existing CFP.\"\n\n  param :event_query, desc: \"Event slug or name to find (e.g., 'tropical-on-rails-2026' or 'Tropical on Rails 2026')\"\n  param :link, desc: \"URL of the existing CFP to update\"\n  param :open_date, desc: \"Date when CFP opens (YYYY-MM-DD format)\", required: false\n  param :close_date, desc: \"Date when CFP closes (YYYY-MM-DD format)\", required: false\n  param :name, desc: \"Name for this CFP (e.g., 'Lightning Talks CFP')\", required: false\n\n  def execute(event_query:, link:, open_date: nil, close_date: nil, name: nil)\n    event = find_event(event_query)\n    return {error: \"Event not found for query: #{event_query}\"} if event.nil?\n\n    result = event.cfp_file.update(\n      link: link,\n      open_date: open_date,\n      close_date: close_date,\n      name: name\n    )\n\n    return result if result.is_a?(Hash) && result[:error]\n\n    {\n      success: true,\n      event: event.name,\n      cfp_file: event.cfp_file.file_path.to_s.sub(Rails.root.to_s + \"/\", \"\"),\n      cfp: result\n    }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def find_event(query)\n    Event.find_by(slug: query) ||\n      Event.find_by(slug: query.parameterize) ||\n      Event.find_by(name: query) ||\n      Event.ft_search(query).first\n  end\nend\n"
  },
  {
    "path": "app/tools/event_create_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass EventCreateTool < RubyLLM::Tool\n  description \"Create a new event within an event series. Creates the directory and event.yml file in the data/ folder.\"\n\n  param :series_slug, desc: \"Slug of the event series this event belongs to (e.g., 'rails-world', 'euruko')\"\n  param :slug, desc: \"URL-friendly slug for the event (e.g., 'rails-world-2024'). Will be auto-generated from title if not provided.\", required: false\n\n  SCHEMA_DATA = EventSchema.new.to_json_schema[:schema].freeze\n\n  SCHEMA_DATA[:properties].each do |name, config|\n    required = SCHEMA_DATA[:required]&.include?(name)\n\n    desc = config[:description] || \"\"\n    desc += \" (#{config[:enum].join(\", \")})\" if config[:enum]\n\n    param name, desc: desc, required: required\n  end\n\n  def execute(**params)\n    series_slug = params.delete(:series_slug)\n    slug = params.delete(:slug)\n\n    if params[:aliases].is_a?(String)\n      params[:aliases] = params[:aliases].split(\",\").map(&:strip).reject(&:blank?)\n    end\n\n    event = Static::Event.create(series_slug: series_slug, slug: slug, **params)\n\n    {\n      success: true,\n      slug: event.slug,\n      title: event.title,\n      series_slug: event.series_slug,\n      data_path: \"data/#{event.series_slug}/#{event.slug}/event.yml\"\n    }\n  rescue ArgumentError => e\n    {error: e.message}\n  rescue => e\n    {error: e.message}\n  end\nend\n"
  },
  {
    "path": "app/tools/event_lookup_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass EventLookupTool < RubyLLM::Tool\n  description \"Search for events by name, slug, location. Returns matching events with their file paths for easy data updates.\"\n  param :query, desc: \"Search query (matches against title, slug, location). Case-insensitive.\"\n\n  def execute(query:)\n    events = Static::Event.all\n\n    if query.present?\n      query_downcase = query.downcase\n      events = events.select { |event|\n        event.title&.downcase&.include?(query_downcase) ||\n          event.slug&.downcase&.include?(query_downcase) ||\n          event.location&.downcase&.include?(query_downcase)\n      }\n    end\n\n    events.map { |event| event_to_hash(event) }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def event_to_hash(event)\n    base_path = File.dirname(event.send(:__file_path))\n\n    {\n      slug: event.slug,\n      title: event.title,\n      kind: event.kind,\n      year: event.year,\n      location: event.location,\n      start_date: event.start_date&.to_s,\n      end_date: event.end_date&.to_s,\n      website: event.website,\n      data_path: base_path.sub(Rails.root.to_s + \"/\", \"\"),\n      videos_file: \"#{base_path.sub(Rails.root.to_s + \"/\", \"\")}/videos.yml\"\n    }\n  end\nend\n"
  },
  {
    "path": "app/tools/event_series_create_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass EventSeriesCreateTool < RubyLLM::Tool\n  description \"Create a new event series (conference, meetup, etc.). Creates the directory and series.yml file in the data/ folder.\"\n\n  param :slug, desc: \"URL-friendly slug for the series (e.g., 'railsconf', 'ruby-meetup-nyc'). Will be used as directory name.\", required: false\n\n  SCHEMA_DATA = SeriesSchema.new.to_json_schema[:schema].freeze\n\n  SCHEMA_DATA[:properties].each do |name, config|\n    required = SCHEMA_DATA[:required]&.include?(name)\n\n    desc = config[:description] || \"\"\n    desc += \" (#{config[:enum].join(\", \")})\" if config[:enum]\n\n    param name, desc: desc, required: required\n  end\n\n  def execute(**params)\n    slug = params.delete(:slug)\n\n    if params[:aliases].is_a?(String)\n      params[:aliases] = params[:aliases].split(\",\").map(&:strip).reject(&:blank?)\n    end\n\n    series = Static::EventSeries.create(slug: slug, **params)\n\n    {\n      success: true,\n      slug: series.slug,\n      name: series.name,\n      data_path: series.__file_path\n    }\n  rescue ArgumentError => e\n    {error: e.message}\n  rescue => e\n    {error: e.message}\n  end\nend\n"
  },
  {
    "path": "app/tools/event_series_events_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass EventSeriesEventsTool < RubyLLM::Tool\n  description \"Get all events from an event series by name or slug. Returns the list of events within a conference series or meetup group.\"\n  param :query, desc: \"Event series slug (e.g., 'rails-world') or name (e.g., 'Rails World')\"\n\n  def execute(query:)\n    series = Static::EventSeries.find_by_slug(query)\n    series ||= Static::EventSeries.all.detect { |s| s.name&.downcase&.include?(query.downcase) }\n\n    return {error: \"Event series not found for '#{query}'\"} if series.nil?\n\n    events = series.events.sort_by { |e| e.start_date || Date.new(1900) }.reverse\n\n    {\n      series_slug: series.slug,\n      series_name: series.name,\n      kind: series.kind,\n      frequency: series.frequency,\n      website: series.website,\n      data_path: \"data/#{series.slug}/series.yml\",\n      events_count: events.size,\n      events: events.map { |event| event_to_hash(event, series) }\n    }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def event_to_hash(event, series)\n    base_path = \"data/#{series.slug}/#{event.slug}\"\n\n    {\n      slug: event.slug,\n      title: event.title,\n      kind: event.kind,\n      year: event.year,\n      location: event.location,\n      start_date: event.start_date&.to_s,\n      end_date: event.end_date&.to_s,\n      website: event.website,\n      data_path: base_path,\n      videos_file: \"#{base_path}/videos.yml\"\n    }.compact\n  end\nend\n"
  },
  {
    "path": "app/tools/event_series_lookup_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass EventSeriesLookupTool < RubyLLM::Tool\n  description \"Search for event series (conference organizers/recurring events) by name, slug, or kind. Returns matching series with their file paths for easy data updates.\"\n  param :query, desc: \"Search query (matches against name, slug, kind). Case-insensitive.\"\n\n  def execute(query:)\n    series = Static::EventSeries.all\n\n    if query.present?\n      query_downcase = query.downcase\n      series = series.select { |s|\n        s.name&.downcase&.include?(query_downcase) ||\n          s.slug&.downcase&.include?(query_downcase) ||\n          s.kind&.downcase&.include?(query_downcase)\n      }\n    end\n\n    series.map { |s| series_to_hash(s) }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def series_to_hash(series)\n    {\n      slug: series.slug,\n      name: series.name,\n      kind: series.kind,\n      frequency: series.frequency,\n      website: series.website,\n      twitter: series.twitter,\n      language: series.language,\n      youtube_channel_id: series.youtube_channel_id,\n      youtube_channel_name: series.youtube_channel_name,\n      events_count: series.events.size,\n      data_path: \"data/#{series.slug}/series.yml\"\n    }.compact\n  end\nend\n"
  },
  {
    "path": "app/tools/event_talks_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass EventTalksTool < RubyLLM::Tool\n  description \"Get all talks/videos from an event using the Static::Video model. Search by event slug or name.\"\n  param :query, desc: \"Event slug (e.g., 'railsconf-2024') or event name (e.g., 'RailsConf 2024')\"\n\n  def execute(query:)\n    event = Static::Event.find_by_slug(query)\n    event ||= Static::Event.all.detect { |e| e.title&.downcase&.include?(query.downcase) }\n\n    return {error: \"Event not found for '#{query}'\"} if event.nil?\n\n    event_path = File.dirname(event.send(:__file_path))\n    videos_file = File.join(event_path, \"videos.yml\")\n\n    unless File.exist?(videos_file)\n      return {error: \"No videos.yml found for event '#{event.title}'\"}\n    end\n\n    videos = Static::Video.all.select do |video|\n      video.send(:__file_path) == videos_file\n    end\n\n    {\n      event_slug: event.slug,\n      event_title: event.title,\n      event_date: event.start_date&.to_s,\n      videos_file: videos_file.sub(Rails.root.to_s + \"/\", \"\"),\n      talks_count: videos.size,\n      talks: videos.map { |video| video_to_hash(video) }\n    }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def video_to_hash(video)\n    {\n      title: video.title,\n      speakers: video.speakers,\n      date: video.date,\n      video_provider: video.video_provider,\n      video_id: video.video_id,\n      published_at: video.published_at,\n      description: video.description&.truncate(200)\n    }.compact\n  end\nend\n"
  },
  {
    "path": "app/tools/geocode_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass GeocodeTool < RubyLLM::Tool\n  description \"Geocode a location string (address, city, venue name) to get coordinates and address details using Google Maps.\"\n  param :location, desc: \"Location to geocode (e.g., 'Rimini, Italy', 'Hotel Ambasciatori, Rimini', 'Viale Vespucci 22, 47921 Rimini')\"\n\n  def execute(location:)\n    return {error: \"Location is required\"} if location.blank?\n\n    results = Geocoder.search(location)\n\n    if results.empty?\n      return {error: \"No results found for '#{location}'\"}\n    end\n\n    result = results.first\n\n    {\n      coordinates: {\n        latitude: result.latitude,\n        longitude: result.longitude\n      },\n      address: {\n        formatted: result.formatted_address,\n        street: result.street_address,\n        city: result.city,\n        state: result.state,\n        postal_code: result.postal_code,\n        country: result.country,\n        country_code: result.country_code\n      },\n      place_id: result.place_id,\n      types: result.types,\n      maps: {\n        google: \"https://www.google.com/maps/search/?api=1&query=#{result.latitude},#{result.longitude}\",\n        openstreetmap: \"https://www.openstreetmap.org/?mlat=#{result.latitude}&mlon=#{result.longitude}&zoom=17\"\n      }\n    }\n  rescue => e\n    {error: e.message}\n  end\nend\n"
  },
  {
    "path": "app/tools/github_profile_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass GitHubProfileTool < RubyLLM::Tool\n  description \"Fetch GitHub profile information by username/handle\"\n  param :username, desc: \"GitHub username/handle (without @)\"\n\n  def execute(username:)\n    handle = username.delete_prefix(\"@\")\n    profile = client.profile(handle)\n\n    return {error: \"User not found\"} unless profile\n\n    profile.to_h\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def client\n    @client ||= GitHub::UserClient.new\n  end\nend\n"
  },
  {
    "path": "app/tools/speaker_lookup_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass SpeakerLookupTool < RubyLLM::Tool\n  description \"Search for speakers in the database by name, slug, alias, github, or twitter handle. Returns matching speakers with their info.\"\n  param :query, desc: \"Search query (matches against name, slug, github, twitter). Case-insensitive.\"\n\n  def execute(query:)\n    pattern = \"%#{query}%\"\n\n    direct_matches = User.where(\n      \"name LIKE :q OR slug LIKE :q OR github_handle LIKE :q OR twitter LIKE :q\",\n      q: pattern\n    )\n\n    alias_user_ids = Alias.where(aliasable_type: \"User\")\n      .where(\"name LIKE :q OR slug LIKE :q\", q: pattern)\n      .pluck(:aliasable_id)\n\n    users = User.where(id: direct_matches.select(:id))\n      .or(User.where(id: alias_user_ids))\n      .distinct\n      .limit(25)\n\n    users.map { |user| user_to_hash(user) }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def user_to_hash(user)\n    {\n      id: user.id,\n      name: user.name,\n      slug: user.slug,\n      github: user.github_handle.presence,\n      twitter: user.twitter.presence,\n      speakerdeck: user.speakerdeck.presence,\n      website: user.website.presence,\n      bio: user.bio.presence&.truncate(200),\n      talks_count: user.talks_count\n    }.compact\n  end\nend\n"
  },
  {
    "path": "app/tools/speaker_talks_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass SpeakerTalksTool < RubyLLM::Tool\n  description \"Get all talks from a speaker by their name, slug, or ID.\"\n  param :name, desc: \"Speaker name or slug to lookup (e.g., 'Aaron Patterson' or 'tenderlove')\", required: false\n  param :id, desc: \"Speaker ID in the database\", required: false\n\n  def execute(name: nil, id: nil)\n    user = find_user(name: name, id: id)\n\n    return {error: \"User not found\"} if user.nil?\n\n    talks = user.talks.includes(:event).order(date: :desc)\n\n    {\n      user_id: user.id,\n      user_name: user.name,\n      user_slug: user.slug,\n      talks_count: talks.size,\n      talks: talks.map { |talk| talk_to_hash(talk) }\n    }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def find_user(name:, id:)\n    return User.find_by(id: id) if id.present?\n\n    return nil if name.blank?\n\n    User.find_by(name: name) ||\n      User.find_by(slug: name) ||\n      User.find_by(slug: name.parameterize)\n  end\n\n  def talk_to_hash(talk)\n    {\n      id: talk.id,\n      title: talk.title,\n      slug: talk.slug,\n      date: talk.date&.to_s,\n      event_name: talk.event&.name,\n      video_provider: talk.video_provider,\n      video_id: talk.video_id,\n      slides_url: talk.slides_url.presence\n    }.compact\n  end\nend\n"
  },
  {
    "path": "app/tools/speakerdeck_deck_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass SpeakerdeckDeckTool < RubyLLM::Tool\n  description \"Fetch SpeakerDeck slide deck metadata by URL or username/slug using the oEmbed API\"\n  param :url, desc: \"Full SpeakerDeck URL (e.g., 'https://speakerdeck.com/username/slug') or path as 'username/slug'\"\n\n  def execute(url:)\n    normalized_url = normalize_url(url)\n    response = client.oembed(normalized_url)\n\n    {\n      url: normalized_url,\n      title: response.title,\n      author_name: response.author_name,\n      author_url: response.author_url,\n      provider_name: response.provider_name,\n      provider_url: response.provider_url,\n      width: response.width,\n      height: response.height,\n      ratio: response.ratio,\n      html: response.html\n    }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def client\n    @client ||= Speakerdeck::Client.new\n  end\n\n  def normalize_url(url)\n    if url.start_with?(\"http://\", \"https://\")\n      url\n    else\n      \"https://speakerdeck.com/#{url}\"\n    end\n  end\nend\n"
  },
  {
    "path": "app/tools/speakerdeck_user_decks_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass SpeakerdeckUserDecksTool < RubyLLM::Tool\n  description \"Fetch all slide decks from a speaker's SpeakerDeck profile. Lookup by user name or slug.\"\n  param :name, desc: \"User name or slug to lookup in the database (e.g., 'Aaron Patterson' or 'tenderlove')\"\n\n  def execute(name:)\n    user = User.find_by(name: name) ||\n      User.find_by(slug: name) ||\n      User.find_by(slug: name.parameterize)\n\n    return {error: \"User '#{name}' not found in database\"} if user.nil?\n\n    unless user.speakerdeck_feed.has_feed?\n      return {error: \"User '#{user.name}' has no SpeakerDeck username configured\"}\n    end\n\n    decks = user.speakerdeck_feed.decks\n\n    {\n      user_id: user.id,\n      user_name: user.name,\n      username: user.speakerdeck_feed.username,\n      profile_url: \"https://speakerdeck.com/#{user.speakerdeck_feed.username}\",\n      deck_count: decks.size,\n      decks: decks.map { |deck| deck_to_hash(deck) }\n    }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def deck_to_hash(deck)\n    {\n      title: deck.title,\n      url: deck.url,\n      description: deck.description&.strip,\n      published_at: deck.published_at&.to_s\n    }\n  end\nend\n"
  },
  {
    "path": "app/tools/venue_create_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass VenueCreateTool < RubyLLM::Tool\n  description \"Create a venue.yml file for an event by geocoding a venue name/address. Creates the file with coordinates and map links.\"\n\n  param :event_query, desc: \"Event slug or name to find (e.g., 'tropical-on-rails-2026' or 'Tropical on Rails 2026')\"\n  param :venue_name, desc: \"Name of the venue (e.g., 'Convention Center City', 'Hotel Ambasciatori')\"\n  param :address, desc: \"Full address or location (e.g., 'Viale Vespucci 22, 47921 Rimini, Italy')\", required: false\n  param :source_url, desc: \"URL where the venue information was found\", required: false\n\n  def execute(event_query:, venue_name:, address: nil, source_url: nil)\n    event = find_event(event_query)\n    return {error: \"Event not found for query: #{event_query}\"} if event.nil?\n\n    if event.venue.exist?\n      return {\n        warning: \"Venue file already exists\",\n        event: event.name,\n        venue_file: event.venue.file_path.to_s.sub(Rails.root.to_s + \"/\", \"\"),\n        existing_venue: event.venue.name\n      }\n    end\n\n    search_string = [venue_name, address].compact.join(\", \")\n    geocode_results = Geocoder.search(search_string)\n\n    if geocode_results.empty?\n      return {error: \"Could not geocode address: #{search_string}\"}\n    end\n\n    geo = geocode_results.first\n\n    venue_data = {\n      \"name\" => venue_name,\n      \"address\" => {\n        \"street\" => geo.street_address,\n        \"city\" => geo.city,\n        \"region\" => geo.state,\n        \"postal_code\" => geo.postal_code,\n        \"country\" => geo.country,\n        \"country_code\" => geo.country_code,\n        \"display\" => geo.formatted_address\n      }.compact,\n      \"coordinates\" => {\n        \"latitude\" => geo.latitude,\n        \"longitude\" => geo.longitude\n      },\n      \"maps\" => {\n        \"google\" => \"https://maps.google.com/?q=#{venue_name.tr(\" \", \"+\")},#{geo.latitude},#{geo.longitude}\",\n        \"apple\" => \"https://maps.apple.com/?q=#{venue_name.tr(\" \", \"+\")}&ll=#{geo.latitude},#{geo.longitude}\",\n        \"openstreetmap\" => \"https://www.openstreetmap.org/?mlat=#{geo.latitude}&mlon=#{geo.longitude}\"\n      }\n    }\n\n    source = \"# #{source_url}\\n\\n\" if source_url.present?\n\n    file_content = <<~YAML\n      #{source}\n      #{venue_data.to_yaml}\n    YAML\n\n    File.write(event.venue.file_path, file_content)\n\n    {\n      success: true,\n      event: event.name,\n      venue_file: event.venue.file_path.to_s.sub(Rails.root.to_s + \"/\", \"\"),\n      venue: venue_data\n    }\n  rescue => e\n    {error: e.message, backtrace: e.backtrace.first(5)}\n  end\n\n  private\n\n  def find_event(query)\n    Event.find_by(slug: query) ||\n      Event.find_by(slug: query.parameterize) ||\n      Event.find_by(name: query) ||\n      Event.ft_search(query).first\n  end\nend\n"
  },
  {
    "path": "app/tools/vimeo_video_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass VimeoVideoTool < RubyLLM::Tool\n  description \"Fetch Vimeo video metadata by video ID using the oEmbed API\"\n  param :id, desc: \"Vimeo video ID\"\n\n  OEMBED_URL = \"https://vimeo.com/api/oembed.json\"\n\n  def execute(id:)\n    video_url = \"https://vimeo.com/#{id}\"\n    uri = URI(\"#{OEMBED_URL}?url=#{CGI.escape(video_url)}\")\n\n    response = Net::HTTP.get_response(uri)\n\n    unless response.is_a?(Net::HTTPSuccess)\n      return {error: \"Failed to fetch video: #{response.code} #{response.message}\"}\n    end\n\n    data = JSON.parse(response.body)\n\n    {\n      id: id,\n      title: data[\"title\"],\n      description: data[\"description\"],\n      duration: data[\"duration\"],\n      length: format_duration(data[\"duration\"]),\n      thumbnail_url: data[\"thumbnail_url\"],\n      author_name: data[\"author_name\"],\n      author_url: data[\"author_url\"],\n      upload_date: data[\"upload_date\"],\n      html: data[\"html\"]\n    }\n  rescue => e\n    {error: e.message}\n  end\n\n  private\n\n  def format_duration(seconds)\n    return nil unless seconds\n\n    hours = seconds / 3600\n    minutes = (seconds % 3600) / 60\n    secs = seconds % 60\n\n    if hours > 0\n      format(\"%02d:%02d:%02d\", hours, minutes, secs)\n    else\n      format(\"%02d:%02d\", minutes, secs)\n    end\n  end\nend\n"
  },
  {
    "path": "app/tools/youtube_channel_videos_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass YouTubeChannelVideosTool < RubyLLM::Tool\n  description \"Fetch recent videos from a YouTube channel by channel ID. Useful for finding new conference uploads.\"\n  param :channel_id, desc: \"YouTube channel ID (starts with UC...)\"\n  param :limit, desc: \"Maximum number of videos to return (default: 25)\", required: false\n\n  def execute(channel_id:, limit: 25)\n    channel = Yt::Channel.new(id: channel_id)\n\n    videos = channel.videos.take(limit.to_i).map do |video|\n      YouTubeVideoTool.video_to_hash(video)\n    end\n\n    {\n      channel_id: channel.id,\n      channel_title: channel.title,\n      video_count: videos.size,\n      videos: videos\n    }\n  rescue => e\n    {error: e.message}\n  end\nend\n"
  },
  {
    "path": "app/tools/youtube_playlist_items_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass YouTubePlaylistItemsTool < RubyLLM::Tool\n  description \"Fetch YouTube playlist items by playlist ID\"\n  param :id, desc: \"YouTube playlist id\"\n\n  def execute(id:)\n    playlist = Yt::Playlist.new(id: id)\n\n    playlist.playlist_items.map { |item| YouTubeVideoTool.new.execute(id: item.snippet.resource_id.try(:[], \"videoId\")) }\n  rescue => e\n    {error: e.message}\n  end\nend\n"
  },
  {
    "path": "app/tools/youtube_playlist_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass YouTubePlaylistTool < RubyLLM::Tool\n  description \"Fetch YouTube playlist metadata by playlist ID\"\n  param :id, desc: \"YouTube playlist id\"\n\n  def execute(id:)\n    playlist = Yt::Playlist.new(id: id)\n\n    {\n      title: playlist.title,\n      description: playlist.description,\n      channel_id: playlist.channel_id,\n      channel_title: playlist.channel_title,\n      published_at: playlist.published_at&.to_s,\n      items_count: playlist.playlist_items.count\n    }\n  rescue => e\n    {error: e.message}\n  end\nend\n"
  },
  {
    "path": "app/tools/youtube_video_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass YouTubeVideoTool < RubyLLM::Tool\n  description \"Fetch YouTube video metadata by video ID\"\n  param :id, desc: \"YouTube video id\"\n\n  def execute(id:)\n    video = Yt::Video.new(id: id)\n\n    self.class.video_to_hash(video)\n  rescue => e\n    {error: e.message}\n  end\n\n  def self.video_to_hash(video)\n    {\n      id: video.id,\n      title: video.title,\n      description: video.description,\n      published_at: video.published_at&.to_s,\n      channel_id: video.channel_id,\n      channel_title: video.channel_title,\n      thumbnails: video.thumbnail_url,\n      length: video.length,\n      duration: video.duration,\n      tags: video.tags\n    }\n  end\nend\n"
  },
  {
    "path": "app/tools/youtube_videos_tool.rb",
    "content": "# frozen_string_literal: true\n\nclass YouTubeVideosTool < RubyLLM::Tool\n  description \"Fetch YouTube video metadata for multiple videos by their IDs (up to 50 at a time)\"\n  param :ids, desc: \"Comma-separated YouTube video IDs (e.g., 'abc123,def456,ghi789')\"\n\n  def execute(ids:)\n    video_ids = ids.split(\",\").map(&:strip).reject(&:empty?).first(50)\n\n    return {error: \"No valid video IDs provided\"} if video_ids.empty?\n\n    videos = Yt::Collections::Videos.new.where(id: video_ids.join(\",\"))\n    videos.map { |video| YouTubeVideoTool.video_to_hash(video) }\n  rescue => e\n    {error: e.message}\n  end\nend\n"
  },
  {
    "path": "app/views/admin/suggestions/_suggestion.html.erb",
    "content": "<div class=\"card card-bordered\">\n  <div class=\"card-body\">\n    <div class=\"flex flex-col gap-4\">\n      <% title = suggestion.suggestable.try(:suggestion_summary) || \"#{suggestion.suggestable.class} : #{suggestion.suggestable.title}\" %>\n      <% if suggestion.suggestable.is_a?(User) %>\n        <%= link_to profile_path(suggestion.suggestable), target: \"_blank\", class: \"\" do %>\n          <%= simple_format title %>\n        <% end %>\n      <% else %>\n        <%= link_to suggestion.suggestable, target: \"_blank\", class: \"\" do %>\n          <%= simple_format title %>\n        <% end %>\n      <% end %>\n\n      <div class=\"font-semibold\">Changes:</div>\n      <div class=\"grid grid-cols-2 gap-4\">\n        <% suggestion.content.keys.each do |key| %>\n          <span><%= key %></span>\n          <span>\n            <%= sanitize Diffy::Diff.new(suggestion.suggestable[key].to_s, suggestion.content[key].to_s, include_plus_and_minus_in_html: true).to_s(:html) %>\n          </span>\n        <% end %>\n      </div>\n\n      <div class=\"flex items-center gap-4\">\n        <%= button_to \"Reject\", admin_suggestion_path(suggestion), method: :delete, class: \"btn btn-outline btn-sm\" %>\n        <%= button_to \"Approve\", admin_suggestion_path(suggestion), method: :patch, class: \"btn btn-success btn-sm\" %>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/admin/suggestions/index.html.erb",
    "content": "<div class=\"container py-8\">\n  <h1 class=\"mb-4\">Suggestions</h1>\n  <div class=\"flex flex-col gap-4\">\n    <%= render partial: \"admin/suggestions/suggestion\", collection: @suggestions, as: :suggestion %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/analytics/dashboards/daily_page_views.html.erb",
    "content": "<%= turbo_frame_tag \"daily_page_views\" do %>\n  <h2 class=\"text-center mb-4\">Daily page views</h2>\n  <%= area_chart @daily_page_views, id: :daily_page_views_chart, points: false, library: {showLine: false} %>\n<% end %>\n"
  },
  {
    "path": "app/views/analytics/dashboards/daily_visits.html.erb",
    "content": "<%= turbo_frame_tag \"daily_visits\" do %>\n  <h2 class=\"text-center mb-4\">Daily visits</h2>\n  <%= area_chart @daily_visits, id: :daily_visits_chart, points: false, library: {showLine: false} %>\n<% end %>\n"
  },
  {
    "path": "app/views/analytics/dashboards/monthly_page_views.html.erb",
    "content": "<%= turbo_frame_tag \"monthly_page_views\" do %>\n  <h2 class=\"text-center mb-4\">Monthly page views</h2>\n  <%= column_chart @monthly_page_views, id: :monthly_page_views_chart %>\n<% end %>\n"
  },
  {
    "path": "app/views/analytics/dashboards/monthly_visits.html.erb",
    "content": "<%= turbo_frame_tag \"monthly_visits\" do %>\n  <h2 class=\"text-center mb-4\">Monthly visits</h2>\n  <%= column_chart @monthly_visits, id: :monthly_visits_chart %>\n<% end %>\n"
  },
  {
    "path": "app/views/analytics/dashboards/show.html.erb",
    "content": "\n<% content_for :head do %>\n  <%= vite_javascript_tag \"chartkick\" %>\n<% end %>\n\n<div class=\"container flex flex-col w-full gap-4 my-8\">\n  <h1 class=\"text-center mb-8\">Open analytics</h1>\n\n  <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-8\">\n    <%= turbo_frame_tag \"daily_visits\", src: daily_visits_analytics_dashboards_path, lazy: true do %>\n      <h2 class=\"text-center mb-4\">Daily visits</h2>\n      <div class=\"bg-gray-300 rounded-lg animate-pulse h-[300px]\"></div>\n    <% end %>\n    <%= turbo_frame_tag \"daily_page_views\", src: daily_page_views_analytics_dashboards_path, lazy: true do %>\n      <h2 class=\"text-center mb-4\">Daily page views</h2>\n      <div class=\"bg-gray-300 rounded-lg animate-pulse h-[300px]\"></div>\n    <% end %>\n    <%= turbo_frame_tag \"monthly_visits\", src: monthly_visits_analytics_dashboards_path, lazy: true do %>\n      <h2 class=\"text-center mb-4\">Monthly visits</h2>\n      <div class=\"bg-gray-300 rounded-lg animate-pulse h-[300px]\"></div>\n    <% end %>\n    <%= turbo_frame_tag \"monthly_page_views\", src: monthly_page_views_analytics_dashboards_path, lazy: true do %>\n      <h2 class=\"text-center mb-4\">Monthly page views</h2>\n      <div class=\"bg-gray-300 rounded-lg animate-pulse h-[300px]\"></div>\n    <% end %>\n\n    <%# TODO convert those metrics to Rollup to re enable them %>\n    <% if Current.user&.admin? && false %>\n      <%= turbo_frame_tag \"top_referrers\", src: top_referrers_analytics_dashboards_path, lazy: true do %>\n        <h2 class=\"text-center mb-4\">Top referrers</h2>\n        <div class=\"bg-gray-300 rounded-lg animate-pulse h-[300px]\"></div>\n      <% end %>\n      <%= turbo_frame_tag \"top_landing_pages\", src: top_landing_pages_analytics_dashboards_path, lazy: true do %>\n        <h2 class=\"text-center mb-4\">Top landing pages</h2>\n        <div class=\"bg-gray-300 rounded-lg animate-pulse h-[300px]\"></div>\n      <% end %>\n      <%= turbo_frame_tag \"top_searches\", src: top_searches_analytics_dashboards_path, lazy: true do %>\n        <h2 class=\"text-center mb-4\">Top searches</h2>\n        <div class=\"bg-gray-300 rounded-lg animate-pulse h-[300px]\"></div>\n      <% end %>\n    <% end %>\n\n    <%= turbo_frame_tag \"yearly_talks\", src: yearly_talks_analytics_dashboards_path, lazy: true do %>\n      <h2 class=\"text-center mb-4\">Yearly talks</h2>\n      <div class=\"bg-gray-300 rounded-lg animate-pulse h-[300px]\"></div>\n    <% end %>\n\n    <%= turbo_frame_tag \"yearly_conferences\", src: yearly_conferences_analytics_dashboards_path, lazy: true do %>\n      <h2 class=\"text-center mb-4\">Yearly Conferencess</h2>\n      <div class=\"bg-gray-300 rounded-lg animate-pulse h-[300px]\"></div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/analytics/dashboards/top_landing_pages.html.erb",
    "content": "<%= turbo_frame_tag \"top_landing_pages\" do %>\n  <h2 class=\"text-center mb-4\">Top landing pages</h2>\n  <%= bar_chart @top_landing_pages, id: :top_landing_pages_chart %>\n<% end %>\n"
  },
  {
    "path": "app/views/analytics/dashboards/top_referrers.html.erb",
    "content": "<%= turbo_frame_tag \"top_referrers\" do %>\n  <h2 class=\"text-center mb-4\">Top referrers</h2>\n  <%= bar_chart @top_referrers, id: :top_referrers_chart %>\n<% end %>\n"
  },
  {
    "path": "app/views/analytics/dashboards/top_searches.html.erb",
    "content": "<%= turbo_frame_tag \"top_searches\" do %>\n  <h2 class=\"text-center mb-4\">Top searches</h2>\n  <%= bar_chart @top_searches, id: :top_searches_chart %>\n<% end %>\n"
  },
  {
    "path": "app/views/analytics/dashboards/yearly_conferences.html.erb",
    "content": "<%= turbo_frame_tag \"yearly_conferences\" do %>\n  <h2 class=\"text-center mb-4 flex items-center justify-center\">\n    Ruby conferences by year\n    <span class=\"ml-2\">\n      <%= ui_tooltip \"Note the last year might be incomplete until the year is over\" do %>\n        <%= fa(\"question-circle\") %>\n      <% end %>\n    </span>\n  </h2>\n  <%= column_chart @yearly_conferences, id: :yearly_conferences_chart, xtitle: \"Year\", ytitle: \"# Confs\" %>\n<% end %>\n"
  },
  {
    "path": "app/views/analytics/dashboards/yearly_talks.html.erb",
    "content": "<%= turbo_frame_tag \"yearly_talks\" do %>\n  <h2 class=\"text-center mb-4 flex items-center justify-center\">\n    Yearly talks from Ruby conferences\n    <span class=\"ml-2\">\n      <%= ui_tooltip \"including talks scheduled for the current year and future years\" do %>\n        <%= fa(\"question-circle\") %>\n      <% end %>\n    </span>\n  </h2>\n  <%= column_chart @yearly_talks, id: :yearly_talks_chart %>\n<% end %>\n"
  },
  {
    "path": "app/views/announcements/feed.rss.builder",
    "content": "xml.instruct! :xml, version: \"1.0\"\nxml.rss :version => \"2.0\", \"xmlns:atom\" => \"http://www.w3.org/2005/Atom\" do\n  xml.channel do\n    if @current_tag.present?\n      xml.title \"RubyEvents.org Announcements - #{@current_tag}\"\n      xml.description \"News and updates from RubyEvents.org tagged with #{@current_tag}\"\n      xml.link announcements_url(tag: @current_tag)\n      xml.tag! \"atom:link\", href: feed_announcements_url(format: :rss, tag: @current_tag), rel: \"self\", type: \"application/rss+xml\"\n    else\n      xml.title \"RubyEvents.org Announcements\"\n      xml.description \"News and updates from RubyEvents.org\"\n      xml.link announcements_url\n      xml.tag! \"atom:link\", href: feed_announcements_url(format: :rss), rel: \"self\", type: \"application/rss+xml\"\n    end\n    xml.language \"en\"\n\n    @announcements.each do |announcement|\n      xml.item do\n        xml.title announcement.title\n        xml.description announcement.excerpt\n        xml.pubDate announcement.date.to_time.rfc822\n        xml.link announcement_url(announcement)\n        xml.guid announcement_url(announcement), isPermaLink: true\n\n        if announcement.author.present?\n          xml.author announcement.author\n        end\n\n        announcement.tags.each do |tag|\n          xml.category tag\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "app/views/announcements/index.html.erb",
    "content": "<% content_for :head do %>\n  <% if @current_tag.present? %>\n    <%= auto_discovery_link_tag :rss, feed_announcements_url(format: :rss, tag: @current_tag), title: \"RubyEvents.org Announcements - #{@current_tag}\" %>\n  <% else %>\n    <%= auto_discovery_link_tag :rss, feed_announcements_url(format: :rss), title: \"RubyEvents.org Announcements\" %>\n  <% end %>\n<% end %>\n\n<div class=\"container py-8\">\n  <div class=\"flex items-center justify-between mb-8\">\n    <h1 class=\"title text-primary\">Announcements</h1>\n    <%= link_to feed_announcements_path(format: :rss, tag: @current_tag.presence), class: \"btn btn-ghost btn-sm gap-2\", title: \"RSS Feed\", target: \"_blank\" do %>\n      <%= fa(\"rss\", size: :sm) %>\n    <% end %>\n  </div>\n\n  <% if @current_tag.present? %>\n    <div class=\"flex items-center gap-2 mb-6\">\n      <span class=\"text-gray-500\">Filtered by:</span>\n      <span class=\"badge badge-primary gap-1\">\n        <%= @current_tag %>\n        <%= link_to announcements_path(**permitted_params) do %>\n          <%= fa(\"xmark\", size: :xs, class: \"fill-white\") %>\n        <% end %>\n      </span>\n    </div>\n  <% end %>\n\n  <div class=\"flex flex-col gap-8\">\n    <% @announcements.each do |announcement| %>\n      <article class=\"card bg-base-100 shadow-sm border border-base-200\">\n        <div class=\"card-body\">\n          <div class=\"flex flex-col gap-2\">\n            <div class=\"flex items-center gap-2 text-sm text-gray-500\">\n              <time datetime=\"<%= announcement.date.iso8601 %>\"><%= I18n.l(announcement.date, default: \"\") %></time>\n              <% if announcement.author_user %>\n                <span>•</span>\n                <%= link_to profile_path(announcement.author_user), class: \"hover:underline\" do %>\n                  @<%= announcement.author %>\n                <% end %>\n              <% elsif announcement.author.present? %>\n                <span>•</span>\n                <span><%= announcement.author %></span>\n              <% end %>\n              <% if !announcement.published? %>\n                <span class=\"badge badge-warning\">Draft</span>\n              <% end %>\n            </div>\n\n            <h2 class=\"card-title\">\n              <%= link_to announcement.title, announcement_path(announcement, **permitted_params), class: \"hover:underline\" %>\n            </h2>\n\n            <% if announcement.excerpt.present? %>\n              <p class=\"text-gray-600\"><%= announcement.excerpt %></p>\n            <% end %>\n\n            <% if announcement.tags.any? %>\n              <div class=\"flex flex-wrap gap-2 mt-2\">\n                <% announcement.tags.each do |tag| %>\n                  <%= link_to announcements_path(tag: tag, **permitted_params), class: \"badge badge-ghost hover:badge-primary px-2 py-3 text-xs transition-colors\" do %>\n                    <%= tag %>\n                  <% end %>\n                <% end %>\n              </div>\n            <% end %>\n          </div>\n\n          <div class=\"card-actions justify-end mt-4\">\n            <%= link_to \"Read more →\", announcement_path(announcement, **permitted_params), class: \"text-primary hover:underline\" %>\n          </div>\n        </div>\n      </article>\n    <% end %>\n  </div>\n\n  <% if @announcements.empty? %>\n    <div class=\"text-center py-12 text-gray-500\">\n      No announcements yet.\n    </div>\n  <% end %>\n\n  <% if @pagy.pages > 1 %>\n    <div class=\"flex w-full mt-8 justify-center\">\n      <%== pagy_nav(@pagy) %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/announcements/show.html.erb",
    "content": "<% content_for :head do %>\n  <!-- TODO ADD Rubyevents webcomponents script here -->\n<% end %>\n\n<div class=\"container my-8\">\n  <div class=\"max-w-3xl mx-auto\">\n    <div class=\"mb-8\">\n      <%= link_to \"← Back to Announcements\", announcements_path(**permitted_params), class: \"text-primary hover:underline\" %>\n    </div>\n\n    <article>\n      <header class=\"mb-8\">\n        <h1 class=\"text-4xl font-bold text-primary mb-4\"><%= @announcement.title %></h1>\n\n        <div class=\"flex flex-wrap items-center gap-4 text-gray-500\">\n          <time datetime=\"<%= @announcement.date.iso8601 %>\"><%= I18n.l(@announcement.date, default: \"\") %></time>\n\n          <% if @announcement.author_user %>\n            <div class=\"flex items-center gap-2\">\n              <span>By</span>\n              <%= link_to profile_path(@announcement.author_user), class: \"flex items-center gap-2 hover:underline\" do %>\n                <% if @announcement.author_user.github_handle.present? %>\n                  <%= ui_avatar(@announcement.author_user, size: :xs) %>\n                <% end %>\n                <span>@<%= @announcement.author %></span>\n              <% end %>\n            </div>\n          <% elsif @announcement.author.present? %>\n            <div>By <%= @announcement.author %></div>\n          <% end %>\n          <% if !@announcement.published? %>\n            <span class=\"badge badge-warning\">Draft</span>\n          <% end %>\n        </div>\n\n        <% if @announcement.tags.any? %>\n          <div class=\"flex flex-wrap gap-2 mt-4\">\n            <% @announcement.tags.each do |tag| %>\n              <%= link_to announcements_path(tag: tag, **permitted_params), class: \"badge badge-ghost hover:badge-primary px-2 py-3 text-xs transition-colors\" do %>\n                <%= tag %>\n              <% end %>\n            <% end %>\n          </div>\n        <% end %>\n      </header>\n\n      <% if @announcement.featured_image.present? %>\n        <div class=\"mb-8\">\n          <%= image_tag @announcement.featured_image, class: \"w-full rounded-lg\", alt: @announcement.title %>\n        </div>\n      <% end %>\n\n      <div class=\"markdown prose max-w-none\">\n        <%= announcement_markdown_to_html(@announcement.content) %>\n      </div>\n    </article>\n\n    <div class=\"mt-12 pt-8 border-t border-base-200\">\n      <%= link_to \"← Back to Announcements\", announcements_path(**permitted_params), class: \"text-primary hover:underline\" %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/avo/cards/_duplicates_summary.html.erb",
    "content": "<% count = User::DuplicateDetector.all_duplicate_ids.count %>\n\n<div class=\"p-6 h-full flex flex-col justify-between\">\n  <div class=\"text-center\">\n    <div class=\"text-4xl font-bold <%= (count > 0) ? \"text-yellow-600\" : \"text-green-600\" %>\">\n      <%= count %>\n    </div>\n    <div class=\"text-sm text-gray-500 mt-1\">users with potential duplicates</div>\n  </div>\n\n  <div class=\"mt-4 text-center\">\n    <%= link_to \"View Details →\",\n          avo_dashboards.dashboard_path(:duplicates),\n          class: \"text-sm text-blue-600 hover:text-blue-800 hover:underline font-medium\",\n          data: {turbo_frame: \"_top\"} %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/avo/cards/_reversed_name_duplicates_list.html.erb",
    "content": "<% duplicates = User::DuplicateDetector.find_all_reversed_name_duplicates %>\n\n<div class=\"p-4 overflow-y-auto h-full\">\n  <% if duplicates.empty? %>\n    <p class=\"text-gray-500 text-center py-8\">No reversed name duplicates found.</p>\n  <% else %>\n    <table class=\"min-w-full divide-y divide-gray-200\">\n      <thead>\n        <tr>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">User 1</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">User 2</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Talks</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Actions</th>\n        </tr>\n      </thead>\n      <tbody class=\"divide-y divide-gray-200\">\n        <% duplicates.each do |(user1, user2)| %>\n          <tr>\n            <td class=\"px-3 py-2 text-sm\">\n              <%= link_to user1.name, avo.resources_user_path(user1), class: \"text-blue-600 hover:underline\", data: {turbo_frame: \"_top\"} %>\n              <% if user1.github_handle.present? %>\n                <span class=\"text-gray-400 text-xs\">(<%= user1.github_handle %>)</span>\n              <% end %>\n            </td>\n            <td class=\"px-3 py-2 text-sm\">\n              <%= link_to user2.name, avo.resources_user_path(user2), class: \"text-blue-600 hover:underline\", data: {turbo_frame: \"_top\"} %>\n              <% if user2.github_handle.present? %>\n                <span class=\"text-gray-400 text-xs\">(<%= user2.github_handle %>)</span>\n              <% end %>\n            </td>\n            <td class=\"px-3 py-2 text-sm text-gray-600\">\n              <%= user1.talks_count %> / <%= user2.talks_count %>\n            </td>\n            <td class=\"px-3 py-2 text-sm space-x-2\">\n              <%= link_to \"View 1\", avo.resources_user_path(user1), class: \"text-blue-600 hover:underline text-xs\", target: \"_blank\" %>\n              <%= link_to \"View 2\", avo.resources_user_path(user2), class: \"text-blue-600 hover:underline text-xs\", target: \"_blank\" %>\n            </td>\n          </tr>\n        <% end %>\n      </tbody>\n    </table>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/avo/cards/_same_name_duplicates_list.html.erb",
    "content": "<% duplicates = User::DuplicateDetector.find_all_same_name_duplicates %>\n\n<div class=\"p-4 overflow-y-auto h-full\">\n  <% if duplicates.empty? %>\n    <p class=\"text-gray-500 text-center py-8\">No same name duplicates found.</p>\n  <% else %>\n    <table class=\"min-w-full divide-y divide-gray-200\">\n      <thead>\n        <tr>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">User 1</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">User 2</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Talks</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Actions</th>\n        </tr>\n      </thead>\n      <tbody class=\"divide-y divide-gray-200\">\n        <% duplicates.each do |(user1, user2)| %>\n          <tr>\n            <td class=\"px-3 py-2 text-sm\">\n              <%= link_to user1.name, avo.resources_user_path(user1), class: \"text-blue-600 hover:underline\", data: {turbo_frame: \"_top\"} %>\n              <% if user1.github_handle.present? %>\n                <span class=\"text-gray-400 text-xs\">(<%= user1.github_handle %>)</span>\n              <% end %>\n            </td>\n            <td class=\"px-3 py-2 text-sm\">\n              <%= link_to user2.name, avo.resources_user_path(user2), class: \"text-blue-600 hover:underline\", data: {turbo_frame: \"_top\"} %>\n              <% if user2.github_handle.present? %>\n                <span class=\"text-gray-400 text-xs\">(<%= user2.github_handle %>)</span>\n              <% end %>\n            </td>\n            <td class=\"px-3 py-2 text-sm text-gray-600\">\n              <%= user1.talks_count %> / <%= user2.talks_count %>\n            </td>\n            <td class=\"px-3 py-2 text-sm space-x-2\">\n              <%= link_to \"View 1\", avo.resources_user_path(user1), class: \"text-blue-600 hover:underline text-xs\", target: \"_blank\" %>\n              <%= link_to \"View 2\", avo.resources_user_path(user2), class: \"text-blue-600 hover:underline text-xs\", target: \"_blank\" %>\n            </td>\n          </tr>\n        <% end %>\n      </tbody>\n    </table>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/avo/cards/_suspicious_signals_breakdown.html.erb",
    "content": "<% suspicious_users = User.suspicious.to_a %>\n<% signals = {\n     \"New GitHub Account\" => suspicious_users.count { |u| u.suspicion_detector.github_account_new? },\n     \"No Talks\" => suspicious_users.count { |u| u.suspicion_detector.no_talks? },\n     \"No Watched Talks\" => suspicious_users.count { |u| u.suspicion_detector.no_watched_talks? },\n     \"Bio Contains URL\" => suspicious_users.count { |u| u.suspicion_detector.bio_contains_url? },\n     \"Empty GitHub Profile\" => suspicious_users.count { |u| u.suspicion_detector.github_account_empty? }\n   } %>\n\n<div class=\"p-4\">\n  <% if suspicious_users.empty? %>\n    <p class=\"text-gray-500 text-center py-4\">No suspicious users to analyze.</p>\n  <% else %>\n    <div class=\"space-y-3\">\n      <% signals.each do |signal_name, count| %>\n        <div class=\"flex items-center justify-between\">\n          <span class=\"text-sm text-gray-700\"><%= signal_name %></span>\n          <div class=\"flex items-center\">\n            <div class=\"w-32 bg-gray-200 rounded-full h-2 mr-2\">\n              <% percentage = suspicious_users.any? ? (count.to_f / suspicious_users.count * 100) : 0 %>\n              <div class=\"bg-red-500 h-2 rounded-full\" style=\"width: <%= percentage %>%\"></div>\n            </div>\n            <span class=\"text-sm font-medium text-gray-900 w-12 text-right\"><%= count %></span>\n          </div>\n        </div>\n      <% end %>\n    </div>\n    <div class=\"mt-4 pt-4 border-t border-gray-200\">\n      <p class=\"text-xs text-gray-500\">\n        Total suspicious users: <strong><%= suspicious_users.count %></strong>\n        <br>\n        Threshold: 3+ signals required\n      </p>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/avo/cards/_suspicious_summary.html.erb",
    "content": "<% count = User.suspicious.count %>\n\n<div class=\"p-6 h-full flex flex-col justify-between\">\n  <div class=\"text-center\">\n    <div class=\"text-4xl font-bold <%= (count > 0) ? \"text-orange-600\" : \"text-green-600\" %>\">\n      <%= count %>\n    </div>\n    <div class=\"text-sm text-gray-500 mt-1\">suspicious user profiles</div>\n  </div>\n\n  <div class=\"mt-4 text-center\">\n    <%= link_to \"View Details →\",\n          avo_dashboards.dashboard_path(:suspicious),\n          class: \"text-sm text-blue-600 hover:text-blue-800 hover:underline font-medium\",\n          data: {turbo_frame: \"_top\"} %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/avo/cards/_suspicious_users_list.html.erb",
    "content": "<% suspicious_users = User.suspicious.includes(:connected_accounts).order(suspicion_marked_at: :desc).limit(50) %>\n\n<div class=\"p-4 overflow-y-auto h-full\">\n  <% if suspicious_users.empty? %>\n    <p class=\"text-gray-500 text-center py-8\">No suspicious users found.</p>\n  <% else %>\n    <table class=\"min-w-full divide-y divide-gray-200\">\n      <thead>\n        <tr>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">User</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Signals</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Flagged</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Actions</th>\n        </tr>\n      </thead>\n      <tbody class=\"divide-y divide-gray-200\">\n        <% suspicious_users.each do |user| %>\n          <tr>\n            <td class=\"px-3 py-2 text-sm\">\n              <%= link_to user.name, avo.resources_user_path(user), class: \"text-blue-600 hover:underline\", data: {turbo_frame: \"_top\"} %>\n              <% if user.github_handle.present? %>\n                <br><span class=\"text-gray-400 text-xs\">@<%= user.github_handle %></span>\n              <% end %>\n            </td>\n            <td class=\"px-3 py-2 text-sm\">\n              <span class=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium <%= (user.suspicion_detector.signal_count >= 4) ? \"bg-red-100 text-red-800\" : \"bg-yellow-100 text-yellow-800\" %>\">\n                <%= user.suspicion_detector.signal_count %> / 5\n              </span>\n            </td>\n            <td class=\"px-3 py-2 text-sm text-gray-500\">\n              <%= time_ago_in_words(user.suspicion_marked_at) %> ago\n            </td>\n            <td class=\"px-3 py-2 text-sm space-x-2\">\n              <%= link_to \"View\", avo.resources_user_path(user), class: \"text-blue-600 hover:underline text-xs\", data: {turbo_frame: \"_top\"} %>\n            </td>\n          </tr>\n        <% end %>\n      </tbody>\n    </table>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/avo/cards/_unavailable_videos_by_event.html.erb",
    "content": "<% events_with_unavailable = Talk.video_unavailable\n     .joins(:event)\n     .group(\"events.id\", \"events.name\")\n     .order(Arel.sql(\"COUNT(*) DESC\"))\n     .limit(10)\n     .pluck(\"events.id\", \"events.name\", Arel.sql(\"COUNT(*)\")) %>\n\n<div class=\"p-4 overflow-y-auto h-full\">\n  <% if events_with_unavailable.empty? %>\n    <p class=\"text-gray-500 text-center py-4\">No events with unavailable videos.</p>\n  <% else %>\n    <div class=\"space-y-2\">\n      <% events_with_unavailable.each do |event_id, event_name, count| %>\n        <div class=\"flex items-center justify-between py-1\">\n          <%= link_to event_name.truncate(30), avo.resources_event_path(event_id), class: \"text-sm text-blue-600 hover:underline truncate flex-1\", data: {turbo_frame: \"_top\"} %>\n          <span class=\"ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800\">\n            <%= count %>\n          </span>\n        </div>\n      <% end %>\n    </div>\n    <div class=\"mt-4 pt-4 border-t border-gray-200\">\n      <p class=\"text-xs text-gray-500\">\n        Showing top 10 events with most unavailable videos\n      </p>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/avo/cards/_unavailable_videos_list.html.erb",
    "content": "<% unavailable_talks = Talk.video_unavailable.includes(:event).order(video_unavailable_at: :desc).limit(50) %>\n\n<div class=\"p-4 overflow-y-auto h-full\">\n  <% if unavailable_talks.empty? %>\n    <p class=\"text-gray-500 text-center py-8\">No unavailable videos found.</p>\n  <% else %>\n    <table class=\"min-w-full divide-y divide-gray-200\">\n      <thead>\n        <tr>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Talk</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Event</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Unavailable Since</th>\n          <th class=\"px-3 py-2 text-left text-xs font-medium text-gray-500 uppercase\">Actions</th>\n        </tr>\n      </thead>\n      <tbody class=\"divide-y divide-gray-200\">\n        <% unavailable_talks.each do |talk| %>\n          <tr>\n            <td class=\"px-3 py-2 text-sm\">\n              <%= link_to talk.title.truncate(40), avo.resources_talk_path(talk), class: \"text-blue-600 hover:underline\", data: {turbo_frame: \"_top\"} %>\n              <% if talk.video_provider.present? %>\n                <br><span class=\"text-gray-400 text-xs\"><%= talk.video_provider %></span>\n              <% end %>\n            </td>\n            <td class=\"px-3 py-2 text-sm text-gray-600\">\n              <% if talk.event %>\n                <%= link_to talk.event.name.truncate(25), avo.resources_event_path(talk.event), class: \"text-blue-600 hover:underline\", data: {turbo_frame: \"_top\"} %>\n              <% else %>\n                <span class=\"text-gray-400\">-</span>\n              <% end %>\n            </td>\n            <td class=\"px-3 py-2 text-sm text-gray-500\">\n              <%= time_ago_in_words(talk.video_unavailable_at) %> ago\n            </td>\n            <td class=\"px-3 py-2 text-sm space-x-2\">\n              <% if talk.video_id.present? %>\n                <%= link_to \"YouTube\", \"https://youtube.com/watch?v=#{talk.video_id}\", target: \"_blank\", class: \"text-blue-600 hover:underline text-xs\", data: {turbo_frame: \"_top\"} %>\n              <% end %>\n              <%= link_to \"Edit\", avo.resources_talk_path(talk), class: \"text-blue-600 hover:underline text-xs\", data: {turbo_frame: \"_top\"} %>\n            </td>\n          </tr>\n        <% end %>\n      </tbody>\n    </table>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/avo/cards/_unavailable_videos_summary.html.erb",
    "content": "<% count = Talk.video_unavailable.count %>\n\n<div class=\"p-6 h-full flex flex-col justify-between\">\n  <div class=\"text-center\">\n    <div class=\"text-4xl font-bold <%= (count > 0) ? \"text-red-600\" : \"text-green-600\" %>\">\n      <%= count %>\n    </div>\n    <div class=\"text-sm text-gray-500 mt-1\">videos unavailable</div>\n  </div>\n\n  <div class=\"mt-4 text-center\">\n    <%= link_to \"View Details →\",\n          avo_dashboards.dashboard_path(:unavailable_videos),\n          class: \"text-sm text-blue-600 hover:text-blue-800 hover:underline font-medium\",\n          data: {turbo_frame: \"_top\"} %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/browse/_content_row.html.erb",
    "content": "<%# locals: (title:, talks:, view_all_path: nil, subtitle: nil, watched_talks: [], data_section: nil) %>\n\n<% frame_id = \"browse-#{data_section}\" if data_section %>\n\n<% content = capture do %>\n  <% if talks.present? %>\n    <section class=\"flex flex-col gap-4 group/row\" data-section=\"<%= data_section %>\">\n      <div class=\"flex items-end justify-between\">\n        <div>\n          <h2 class=\"text-xl font-bold\"><%= title %></h2>\n          <% if subtitle.present? %>\n            <p class=\"text-sm text-gray-500\"><%= subtitle %></p>\n          <% end %>\n        </div>\n\n        <% if view_all_path.present? %>\n          <%= link_to view_all_path, class: \"link text-sm shrink-0 flex items-center gap-1 hover:gap-2 transition-all\", data: {turbo_frame: \"_top\"} do %>\n            View All\n            <%= fa(\"arrow-right-long\", size: :sm) %>\n          <% end %>\n        <% end %>\n      </div>\n\n      <div class=\"relative\" data-controller=\"content-row\">\n        <button\n          class=\"hidden lg:flex absolute -left-4 top-1/2 -translate-y-1/2 z-10 p-2 rounded-full bg-white shadow-lg hover:bg-gray-100 transition-all opacity-0 group-hover/row:opacity-100 disabled:opacity-0\"\n          data-content-row-target=\"prevButton\"\n          data-action=\"click->content-row#scrollLeft\">\n\n          <%= fa(\"chevron-left\", size: :md, class: \"text-gray-700\") %>\n        </button>\n\n        <div\n          class=\"overflow-x-auto scroll-smooth snap-x snap-mandatory\"\n          style=\"-ms-overflow-style: none; scrollbar-width: none;\"\n          data-content-row-target=\"container\"\n          data-action=\"scroll->content-row#handleScroll\">\n          <div class=\"flex gap-4 sm:pb-2\" data-content-row-target=\"track\">\n            <% talks.each do |talk| %>\n              <% watched_talk = watched_talks.find { |wt| wt.talk_id == talk.id } if watched_talks.present? %>\n              <div class=\"snap-start shrink-0 w-[200px] sm:w-[300px] lg:w-[320px]\">\n                <%= render \"talks/card_thumbnail\",\n                      talk: talk,\n                      watched_talk: watched_talk %>\n              </div>\n            <% end %>\n          </div>\n        </div>\n\n        <button\n          class=\"hidden lg:flex absolute -right-4 top-1/2 -translate-y-1/2 z-10 p-2 rounded-full bg-white shadow-lg hover:bg-gray-100 transition-all opacity-0 group-hover/row:opacity-100 disabled:opacity-0\"\n          data-content-row-target=\"nextButton\"\n          data-action=\"click->content-row#scrollRight\">\n          <%= fa(\"chevron-right\", size: :md, class: \"text-gray-700\") %>\n        </button>\n\n        <div\n          class=\"absolute right-0 top-0 bottom-2 w-64 pointer-events-none opacity-0 sm:opacity-50 transition-opacity\"\n          style=\"background: linear-gradient(to left, var(--fallback-b1,oklch(var(--b1)/1)), transparent);\"\n          data-content-row-target=\"gradient\"></div>\n      </div>\n    </section>\n  <% end %>\n<% end %>\n\n<% if frame_id %>\n  <%= turbo_frame_tag frame_id do %>\n    <%= content %>\n  <% end %>\n<% else %>\n  <%= content %>\n<% end %>\n"
  },
  {
    "path": "app/views/browse/_content_row_skeleton.html.erb",
    "content": "<%# locals: () %>\n\n<section class=\"flex flex-col gap-4 animate-pulse\">\n  <div class=\"flex items-end justify-between\">\n    <div>\n      <div class=\"h-6 w-48 bg-base-300 rounded\"></div>\n      <div class=\"h-4 w-32 bg-base-300 rounded mt-2\"></div>\n    </div>\n  </div>\n\n  <div class=\"flex gap-4 overflow-hidden\">\n    <% 5.times do %>\n      <div class=\"shrink-0 w-[200px] sm:w-[300px] lg:w-[320px]\">\n        <div class=\"aspect-video bg-base-300 rounded-lg\"></div>\n      </div>\n    <% end %>\n  </div>\n</section>\n"
  },
  {
    "path": "app/views/browse/_featured_events.html.erb",
    "content": "<%# locals: (events:) %>\n\n<section class=\"mb-4 hidden md:block\">\n  <h2 class=\"text-xl font-bold mb-4\">Recently Published</h2>\n\n  <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4\">\n    <% events.each do |event| %>\n      <%= link_to event_path(event), class: \"group relative rounded-xl overflow-hidden aspect-[3/2]\" do %>\n        <div class=\"absolute inset-0\" style=\"background: <%= event.static_metadata&.featured_background || \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\" %>;\"></div>\n        <div class=\"absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent\"></div>\n\n        <div class=\"absolute inset-x-0 top-0 p-4 pt-8 flex items-center justify-center\">\n          <%= image_tag event.featured_image_path, alt: event.name, class: \"max-h-16 object-contain\", loading: \"lazy\" %>\n        </div>\n\n        <div class=\"absolute inset-x-0 bottom-0 p-4 flex flex-col items-center\">\n          <h3 class=\"font-bold text-white text-lg leading-tight text-center group-hover:underline line-clamp-1\">\n            <%= event.name %>\n          </h3>\n\n          <p class=\"text-white/80 text-sm mt-1\"><%= event.location %></p>\n\n          <p class=\"text-white/60 text-xs mt-1\">\n            <%= event.talks_count %> talks\n\n            <% if (published_date = event.static_metadata&.published_date) %>\n              <span class=\"mx-1\">&middot;</span>\n              <%= time_ago_in_words(published_date) %> ago\n            <% end %>\n          </p>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n</section>\n"
  },
  {
    "path": "app/views/browse/_kind_row.html.erb",
    "content": "<%# locals: (talk_kinds:) %>\n\n<section class=\"flex flex-col gap-4\" data-section=\"talk-kinds\">\n  <div class=\"flex items-end justify-between\">\n    <div>\n      <h2 class=\"text-xl font-bold\">Browse by Format</h2>\n      <p class=\"text-sm text-gray-500\">Explore different talk formats</p>\n    </div>\n  </div>\n\n  <div class=\"flex flex-wrap gap-3\">\n    <% talk_kinds.each do |kind, count| %>\n      <%= link_to talks_path(kind: kind, status: \"all\"), class: \"btn btn-outline btn-sm gap-2 hover:btn-primary\", data: {turbo_frame: \"_top\"} do %>\n        <%= Talk::KIND_LABELS[kind] || kind.titleize %>\n\n        <span class=\"badge badge-ghost badge-sm\"><%= count %></span>\n      <% end %>\n    <% end %>\n  </div>\n</section>\n"
  },
  {
    "path": "app/views/browse/_topic_row.html.erb",
    "content": "<%# locals: (topics:) %>\n\n<section class=\"flex flex-col gap-4\" data-section=\"talk-kinds\">\n  <div class=\"flex items-end justify-between\">\n    <div>\n      <h2 class=\"text-xl font-bold\">Popular Topics</h2>\n      <p class=\"text-sm text-gray-500\">Browse talks by topic</p>\n    </div>\n\n    <%= link_to topics_path, class: \"link text-sm shrink-0 flex items-center gap-1 hover:gap-2 transition-all\", data: {turbo_frame: \"_top\"} do %>\n      View All\n\n      <%= fa(\"arrow-right-long\", size: :sm) %>\n    <% end %>\n  </div>\n\n  <div class=\"flex flex-wrap gap-3\">\n    <% topics.each do |topic| %>\n      <%= link_to topic_path(topic), class: \"btn btn-outline btn-sm gap-2 hover:btn-primary\", data: {turbo_frame: \"_top\"} do %>\n        <% if topic.topic_gems.any? %>\n          <%= fa(\"gem\", size: :xs, class: \"fill-primary\") %>\n        <% end %>\n\n        <%= topic.name %>\n\n        <span class=\"badge badge-ghost badge-sm\"><%= topic.talks_count %></span>\n      <% end %>\n    <% end %>\n  </div>\n</section>\n"
  },
  {
    "path": "app/views/browse/index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<div class=\"container flex flex-col gap-8 my-8 hotwire-native:my-0 hotwire-native:mb-8\">\n  <h1 class=\"title text-primary hotwire-native:hidden\">Browse</h1>\n\n  <% if @featured_events.any? %>\n    <%= render \"browse/featured_events\", events: @featured_events %>\n  <% end %>\n\n  <% if @continue_watching&.any? %>\n    <%= render \"browse/content_row\",\n          title: \"Continue Watching\",\n          talks: @continue_watching.map(&:talk),\n          watched_talks: @continue_watching,\n          view_all_path: watched_talks_path,\n          data_section: \"continue-watching\" %>\n  <% end %>\n\n  <% @event_rows.each do |row| %>\n    <%= render \"browse/content_row\",\n          title: \"From #{row[:event].name}\",\n          talks: row[:talks],\n          view_all_path: event_path(row[:event]),\n          data_section: \"event-#{row[:event].slug}\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-newest-talks\", src: browse_path(\"newest_talks\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-recently-published\", src: browse_path(\"recently_published\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-trending\", src: browse_path(\"trending\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <% if Current.user %>\n    <%= turbo_frame_tag \"browse-for-you\", src: browse_path(\"for_you\"), loading: :lazy do %>\n      <%= render \"browse/content_row_skeleton\" %>\n    <% end %>\n\n    <%= turbo_frame_tag \"browse-from-bookmarks\", src: browse_path(\"from_bookmarks\"), loading: :lazy do %>\n      <%= render \"browse/content_row_skeleton\" %>\n    <% end %>\n\n    <%= turbo_frame_tag \"browse-favorite-rubyists\", src: browse_path(\"favorite_rubyists\"), loading: :lazy do %>\n      <%= render \"browse/content_row_skeleton\" %>\n    <% end %>\n\n    <%= turbo_frame_tag \"browse-events-attended\", src: browse_path(\"events_attended\"), loading: :lazy do %>\n      <%= render \"browse/content_row_skeleton\" %>\n    <% end %>\n\n    <%= turbo_frame_tag \"browse-unwatched-attended\", src: browse_path(\"unwatched_attended\"), loading: :lazy do %>\n      <%= render \"browse/content_row_skeleton\" %>\n    <% end %>\n\n    <%= turbo_frame_tag \"browse-favorite-speakers\", src: browse_path(\"favorite_speakers\"), loading: :lazy do %>\n      <%= render \"browse/content_row_skeleton\" %>\n    <% end %>\n\n    <%= turbo_frame_tag \"browse-language-rows\", src: browse_path(\"language_rows\"), loading: :lazy do %>\n      <%= render \"browse/content_row_skeleton\" %>\n    <% end %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-popular\", src: browse_path(\"popular\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-popular-youtube\", src: browse_path(\"popular_youtube\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-most-bookmarked\", src: browse_path(\"most_bookmarked\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-quick-watches\", src: browse_path(\"quick_watches\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-deep-dives\", src: browse_path(\"deep_dives\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-hidden-gems\", src: browse_path(\"hidden_gems\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-evergreen\", src: browse_path(\"evergreen\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-beginner-friendly\", src: browse_path(\"beginner_friendly\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-mind-blowing\", src: browse_path(\"mind_blowing\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-inspiring\", src: browse_path(\"inspiring\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-most-liked\", src: browse_path(\"most_liked\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-recommended-community\", src: browse_path(\"recommended_community\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-popular-topics\", src: browse_path(\"popular_topics\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-talk-kinds\", src: browse_path(\"talk_kinds\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <%= turbo_frame_tag \"browse-topic-rows\", src: browse_path(\"topic_rows\"), loading: :lazy do %>\n    <%= render \"browse/content_row_skeleton\" %>\n  <% end %>\n\n  <div class=\"flex justify-center mt-4\">\n    <%= link_to talks_path(status: \"all\"), class: \"btn btn-primary btn-lg\" do %>\n      <%= fa(\"video\", class: \"mr-2\") %>\n\n      Browse All Talks\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/browse/sections/_beginner_friendly.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Beginner Friendly\",\n      subtitle: \"Great starting points for newcomers\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"beginner-friendly\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_continue_watching.html.erb",
    "content": "<%# locals: (continue_watching:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Continue Watching\",\n      talks: continue_watching&.map(&:talk) || [],\n      watched_talks: continue_watching || [],\n      view_all_path: watched_talks_path,\n      data_section: \"continue-watching\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_deep_dives.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Deep Dives\",\n      subtitle: \"45+ minutes of in-depth content\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"deep-dives\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_event_rows.html.erb",
    "content": "<%# locals: (event_rows:) %>\n\n<%= turbo_frame_tag \"browse-event-rows\" do %>\n  <% event_rows&.each do |row| %>\n    <%= render \"browse/content_row\",\n          title: \"From #{row[:event].name}\",\n          talks: row[:talks],\n          view_all_path: event_path(row[:event]),\n          data_section: \"event-#{row[:event].slug}\" %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/browse/sections/_events_attended.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"From Events You Attended\",\n      subtitle: \"Talks from conferences you've been to\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"events-attended\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_evergreen.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Evergreen Talks\",\n      subtitle: \"Timeless content that stays relevant\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"evergreen\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_favorite_rubyists.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"From Your Favorite Rubyists\",\n      subtitle: \"Latest talks from speakers you follow\",\n      talks: talks,\n      view_all_path: favorite_users_path,\n      data_section: \"favorite-rubyists\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_favorite_speakers.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"More From Speakers You Watch\",\n      subtitle: \"Other talks from your most watched speakers\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"favorite-speakers\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_featured_events.html.erb",
    "content": "<%# locals: (events:) %>\n\n<%= turbo_frame_tag \"browse-featured-events\" do %>\n  <% if events&.any? %>\n    <%= render \"browse/featured_events\", events: events %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/browse/sections/_for_you.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"For You\",\n      subtitle: \"Based on your watch history\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"for-you\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_from_bookmarks.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"From Your Bookmarks\",\n      subtitle: \"Picks from your saved talks\",\n      talks: talks,\n      view_all_path: watch_lists_path,\n      data_section: \"from-bookmarks\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_hidden_gems.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Hidden Gems\",\n      subtitle: \"Underrated talks loved by our community\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"hidden-gems\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_inspiring.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Inspiring Talks\",\n      subtitle: \"Talks that spark new ideas\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"inspiring\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_language_rows.html.erb",
    "content": "<%# locals: (language_rows:) %>\n\n<%= turbo_frame_tag \"browse-language-rows\" do %>\n  <% language_rows&.each do |row| %>\n    <%= render \"browse/content_row\",\n          title: \"More Talks in #{row[:language_name]}\",\n          subtitle: \"Based on your watch history\",\n          talks: row[:talks],\n          view_all_path: talks_path(language: row[:language_code]),\n          data_section: \"language-#{row[:language_code]}\" %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/browse/sections/_mind_blowing.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Mind-Blowing\",\n      subtitle: \"Talks that changed how people think\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"mind-blowing\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_most_bookmarked.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Most Bookmarked\",\n      subtitle: \"Saved by the community\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"most-bookmarked\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_most_liked.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Most Liked\",\n      subtitle: \"Community favorites\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"most-liked\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_newest_talks.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Newest Talks\",\n      subtitle: \"Most recently held\",\n      talks: talks,\n      view_all_path: talks_path(order_by: \"date_desc\"),\n      data_section: \"newest-talks\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_popular.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Popular Talks\",\n      subtitle: \"Most watched on RubyEvents\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"popular\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_popular_topics.html.erb",
    "content": "<%# locals: (topics:) %>\n\n<%= turbo_frame_tag \"browse-popular-topics\" do %>\n  <% if topics&.any? %>\n    <%= render \"browse/topic_row\", topics: topics %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/browse/sections/_popular_youtube.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Popular on YouTube\",\n      subtitle: \"Most viewed on YouTube\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"popular-youtube\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_quick_watches.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Quick Watches\",\n      subtitle: \"Under 15 minutes\",\n      talks: talks,\n      view_all_path: talks_path(kind: \"lightning_talk\"),\n      data_section: \"quick-watches\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_recently_published.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Recently Published\",\n      subtitle: \"Latest uploads\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"recently-published\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_recommended_community.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Recommended by Community\",\n      subtitle: \"Viewers would recommend to a friend\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"recommended-community\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_talk_kinds.html.erb",
    "content": "<%# locals: (talk_kinds:) %>\n\n<%= turbo_frame_tag \"browse-talk-kinds\" do %>\n  <% if talk_kinds&.any? %>\n    <%= render \"browse/kind_row\", talk_kinds: talk_kinds %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/browse/sections/_topic_rows.html.erb",
    "content": "<%# locals: (topic_rows:) %>\n\n<%= turbo_frame_tag \"browse-topic-rows\" do %>\n  <% topic_rows&.each do |row| %>\n    <%= render \"browse/content_row\",\n          title: row[:topic].name,\n          talks: row[:talks],\n          view_all_path: topic_path(row[:topic]),\n          data_section: \"topic-#{row[:topic].slug}\" %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/browse/sections/_trending.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Trending on RubyEvents\",\n      subtitle: \"Most watched in the last 30 days\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"trending\" %>\n"
  },
  {
    "path": "app/views/browse/sections/_unwatched_attended.html.erb",
    "content": "<%# locals: (talks:) %>\n\n<%= render \"browse/content_row\",\n      title: \"Catch Up On Events You Attended\",\n      subtitle: \"Talks you haven't watched yet\",\n      talks: talks,\n      view_all_path: nil,\n      data_section: \"unwatched-attended\" %>\n"
  },
  {
    "path": "app/views/cfp/_event_list.html.erb",
    "content": "<div id=\"event-list\" class=\"relative group rounded-xl flex flex-col gap-2\">\n  <% events.each do |event| %>\n    <%= link_to event_cfp_index_path(event), class: \"call-for-papers-item flex gap-4 group p-2 hover:bg-gray-200 rounded-md\" do %>\n      <div class=\"flex flex-col lg:flex-row gap-8 items-center lg:justify-right text-center lg:text-left flex-shrink-0\">\n        <%= image_tag image_path(event.avatar_image_path),\n              class: \"rounded-xl border border-[#D9DFE3] size-16\",\n              alt: event.name.to_s,\n              loading: :lazy %>\n      </div>\n\n      <div class=\"flex-col flex justify-center relative overflow-hidden\">\n        <div class=\"text-black group-hover:text-inherit font-bold text-xl\">\n          <%= event.name %>\n        </div>\n\n        <div class=\"text-[#636B74] group-hover:text-inherit\">\n          <% if event.formatted_dates != \"unknown\" %><%= event.formatted_dates %> • <% end %>\n          <%= event.to_location.to_html(show_links: false) %>\n        </div>\n\n        <% event.cfps.open.each do |cfp| %>\n          <div class=\"text-[#636B74] group-hover:text-inherit font-bold\">\n            <%= cfp.name.presence || \"Call for Proposals\" %>\n            <% if cfp.close_date.present? && (cfp.open_date.blank? || cfp.open_date.past?) %>\n              - closes on\n              <%= cfp.formatted_close_date %>\n            <% elsif cfp.open_date.present? && cfp.open_date.future? %>\n              - opens on\n              <%= cfp.formatted_open_date %>\n            <% elsif cfp.open_ended? %>\n              - always open\n            <% end %>\n          </div>\n        <% end %>\n      </div>\n\n      <div class=\"hidden sm:flex gap-2 absolute right-2\">\n        <%= render \"shared/cfp_countdown_badge\", event: event %>\n        <%= render \"shared/event_countdown_badge\", event: event %>\n      </div>\n    <% end %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/cfp/index.html.erb",
    "content": "<div class=\"container flex flex-col w-full gap-4 my-8 hotwire-native:my-0 hotwire-native:mb-8\">\n  <div class=\"block md:flex items-center justify-between gap-2\">\n    <h1 class=\"title hotwire-native:hidden\">\n      <%= title \"Open Call for Proposals\" %>\n    </h1>\n\n    <div class=\"tabs tabs-boxed mt-4 md:mt-0\">\n      <%= link_to \"All\", cfp_index_path(kind: \"all\"), class: \"tab #{\"tab-active\" if params[:kind].blank? || params[:kind] == \"all\"}\" %>\n      <%= link_to \"Conferences\", cfp_index_path(kind: \"conference\"), class: \"tab #{\"tab-active\" if params[:kind] == \"conference\"}\" %>\n      <%= link_to \"Meetups\", cfp_index_path(kind: \"meetup\"), class: \"tab #{\"tab-active\" if params[:kind] == \"meetup\"}\" %>\n    </div>\n  </div>\n\n  <div class=\"mt-6 block md:grid gap-8 overflow-scroll\">\n    <%= render partial: \"cfp/event_list\", locals: {events: @events} %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/cities/index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<div class=\"container py-8\">\n  <div class=\"flex items-center justify-between w-full hotwire-native:hidden\">\n    <h1 class=\"title\">\n      <%= title \"All Cities\" %>\n    </h1>\n\n    <div class=\"flex flex-col gap-3 place-items-center\">\n      <%= ui_button \"View all countries\", url: countries_path, kind: :secondary, size: :sm %>\n    </div>\n  </div>\n\n  <p class=\"mt-3 md:mt-9 mb-6 text-[#636B74] max-w-[700px]\">\n    Browse all cities with Ruby events or community members. <%= @cities.count %> cities found.\n  </p>\n\n  <div class=\"mt-6\">\n    <% @cities.group_by { |c| c.country&.name || \"Unknown\" }.sort_by { |name, _| name }.each do |country_name, cities| %>\n      <h2 class=\"mt-8 first:mt-0 text-xl font-bold\"><%= country_name %></h2>\n\n      <div class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-8 lg:gap-x-12 gap-y-2 min-w-full pt-4 pb-8\">\n        <% cities.sort_by(&:name).each do |city| %>\n          <% link_class = \"event flex justify-between items-center\" %>\n          <% link_class += \" bg-green-50 rounded px-2 -mx-2\" if city.featured? %>\n\n          <%= link_to city.path, id: \"city-#{city.slug}\", class: link_class do %>\n            <div class=\"flex items-center gap-2\">\n              <span class=\"event-name\"><%= city.name %></span>\n\n              <% if city.state_code.present? %>\n                <span class=\"text-gray-400 text-sm\"><%= city.state_code %></span>\n              <% end %>\n\n              <% if city.featured? %>\n                <span class=\"text-xs bg-green-100 text-green-800 px-1.5 py-0.5 rounded-full\">Featured</span>\n              <% end %>\n            </div>\n\n            <div class=\"flex gap-1\">\n              <% if city.events_count > 0 %>\n                <%= ui_badge(city.events_count, kind: :secondary, outline: true, size: :lg, class: \"min-w-10\") %>\n              <% end %>\n\n              <% if city.users_count > 0 %>\n                <%= ui_badge(\"#{city.users_count} \\u{1F464}\", kind: :primary, outline: true, size: :lg, class: \"min-w-10\") %>\n              <% end %>\n            </div>\n          <% end %>\n        <% end %>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/cities/map/index.html.erb",
    "content": "<%= render \"shared/location_map\",\n      location: @city,\n      layers: @layers || [],\n      time_layers: @time_layers || [],\n      geo_layers: @geo_layers || [],\n      online_events: @online_events || [] %>\n"
  },
  {
    "path": "app/views/cities/meetups/index.html.erb",
    "content": "<%= render \"shared/location_meetups\", location: @location, meetups: @meetups %>\n"
  },
  {
    "path": "app/views/cities/past/index.html.erb",
    "content": "<%= render \"shared/location_past\",\n      location: @city,\n      events: @events,\n      users: @users,\n      event_map_markers: @event_map_markers,\n      geo_layers: @geo_layers || [],\n      nearby_users: @nearby_users || [] %>\n"
  },
  {
    "path": "app/views/cities/show.html.erb",
    "content": "<%= render \"shared/location_show\",\n      location: @city,\n      events: @events,\n      users: @users,\n      stamps: @stamps || [],\n      event_map_markers: @event_map_markers || [],\n      geo_layers: @geo_layers || [],\n      nearby_users: @nearby_users || [],\n      nearby_events: @nearby_events || [],\n      country_events: @country_events || [],\n      country: @country,\n      state: @state,\n      state_users: @state_users || [],\n      continent_events: @continent_events || [],\n      continent: @continent %>\n"
  },
  {
    "path": "app/views/cities/stamps/index.html.erb",
    "content": "<%= render \"shared/location_stamps\",\n      location: @city,\n      stamps: @stamps %>\n"
  },
  {
    "path": "app/views/cities/users/index.html.erb",
    "content": "<%= render \"shared/location_users\",\n      location: @city,\n      users: @users,\n      nearby_users: @nearby_users || [],\n      state: @state,\n      state_users: @state_users || [] %>\n"
  },
  {
    "path": "app/views/continents/countries/index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% title \"Countries in #{@continent.name}\" %>\n\n<%= render \"shared/location_header\",\n      name: @continent.name,\n      subtitle: @continent.to_location.to_text,\n      emoji: @continent.emoji_flag,\n      stats: \"#{pluralize(@countries.count, \"country\")} in #{@continent.name}\",\n      location: @continent %>\n\n<%= render \"shared/location_navigation\",\n      location: @continent,\n      current_tab: \"countries\",\n      show_cities: false,\n      show_countries: true,\n      show_stamps: @continent.stamps.any? %>\n\n<div class=\"container py-8\">\n  <div class=\"flex items-center justify-between mb-6\">\n    <h2 class=\"text-xl font-bold text-gray-900\">Countries in <%= @continent.name %></h2>\n    <%= ui_badge(@countries.count, kind: :secondary, outline: true) %>\n  </div>\n\n  <% if @countries.any? %>\n    <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n      <% @countries.each do |country| %>\n        <% events_count = @events_by_country[country]&.count || 0 %>\n        <% users_count = @users_by_country[country] || 0 %>\n\n        <%= link_to country_path(country),\n              class: \"block bg-white rounded-lg border p-4 hover:border-gray-400 transition-colors\" do %>\n          <div class=\"flex items-center gap-3 mb-2\">\n            <span class=\"fi fi-<%= country.alpha2.downcase %> text-2xl\"></span>\n            <span class=\"font-semibold text-gray-900\"><%= country.name %></span>\n          </div>\n\n          <div class=\"flex gap-4 text-sm text-gray-600\">\n            <% if events_count > 0 %>\n              <span class=\"flex items-center gap-1\">\n                <%= fa(\"calendar\", size: :xs, class: \"text-gray-400\") %>\n                <%= pluralize(events_count, \"event\") %>\n              </span>\n            <% end %>\n\n            <% if users_count > 0 %>\n              <span class=\"flex items-center gap-1\">\n                <%= fa(\"users\", size: :xs, class: \"text-gray-400\") %>\n                <%= pluralize(users_count, \"Rubyist\") %>\n              </span>\n            <% end %>\n          </div>\n        <% end %>\n      <% end %>\n    </div>\n  <% else %>\n    <p class=\"text-gray-500 py-8 text-center\">No countries with Ruby events in <%= @continent.name %> yet.</p>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/continents/index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% title \"Continents\" %>\n\n<div class=\"container py-8\">\n  <h1 class=\"text-3xl font-bold mb-8\">Ruby Communities by Continent</h1>\n\n  <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n    <% @continents.each do |continent| %>\n      <% events_count = @events_by_continent[continent]&.count || 0 %>\n      <% users_count = @users_by_continent[continent] || 0 %>\n\n      <%= link_to continent_path(continent),\n            class: \"block bg-white rounded-xl border p-6 hover:border-gray-400 transition-colors\" do %>\n        <div class=\"flex items-center gap-4 mb-4\">\n          <span class=\"text-4xl\"><%= continent.emoji_flag %></span>\n          <h2 class=\"text-xl font-bold text-gray-900\"><%= continent.name %></h2>\n        </div>\n\n        <div class=\"flex gap-4 text-sm text-gray-600\">\n          <span class=\"flex items-center gap-1\">\n            <%= fa(\"calendar\", size: :sm, class: \"text-gray-400\") %>\n            <%= pluralize(events_count, \"event\") %>\n          </span>\n          <span class=\"flex items-center gap-1\">\n            <%= fa(\"users\", size: :sm, class: \"text-gray-400\") %>\n            <%= pluralize(users_count, \"Rubyist\") %>\n          </span>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/continents/map/index.html.erb",
    "content": "<%= render \"shared/location_map\",\n      location: @continent,\n      layers: @layers || [],\n      time_layers: @time_layers || [],\n      geo_layers: @geo_layers || [],\n      online_events: @online_events || [] %>\n"
  },
  {
    "path": "app/views/continents/past/index.html.erb",
    "content": "<%= render \"shared/location_past\",\n      location: @continent,\n      events: @events,\n      users: @users,\n      event_map_markers: @event_map_markers,\n      geo_layers: @geo_layers || [] %>\n"
  },
  {
    "path": "app/views/continents/show.html.erb",
    "content": "<%= render \"shared/location_show\",\n      location: @continent,\n      events: @events,\n      users: @users,\n      stamps: @stamps,\n      event_map_markers: @event_map_markers,\n      geo_layers: @geo_layers || [],\n      events_by_country: @events_by_country,\n      emoji: @continent.emoji_flag %>\n"
  },
  {
    "path": "app/views/continents/stamps/index.html.erb",
    "content": "<%= render \"shared/location_stamps\",\n      location: @continent,\n      stamps: @stamps %>\n"
  },
  {
    "path": "app/views/continents/users/index.html.erb",
    "content": "<%= render \"shared/location_users\",\n      location: @continent,\n      users: @users %>\n"
  },
  {
    "path": "app/views/contributions/_events_without_dates.html.erb",
    "content": "<%# locals: (events_without_dates:) %>\n\n<%= turbo_frame_tag \"events_without_dates\" do %>\n  <h2 class=\"mb-4\">Events without conference dates (<%= events_without_dates.flat_map(&:last).count %>)</h2>\n\n  <article class=\"prose mb-6\">This section lists events that are missing conference dates. Adding conference dates allows us to show when this event took place, so we could show them in a calendar or similar.</article>\n\n  <div id=\"events-without-dates\" class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-4 min-w-full mb-6\">\n    <% events_without_dates.each do |file_path, events| %>\n      <%= link_to \"https://github.com/rubyevents/rubyevents/edit/main/#{file_path}\", id: \"event-#{file_path}\", class: \"hover:bg-gray-100 p-4 rounded-lg border bg-white\", target: :_blank do %>\n        <div class=\"flex flex-col\">\n          <h3 class=\"line-clamp-1\"><pre>Data File: <%= file_path %></pre></h3>\n\n          <b class=\"mt-4 mb-2\">Events missing dates:</b>\n\n          <% events.each do |event| %>\n            <span><%= event.title %></span>\n          <% end %>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/contributions/_events_without_location.html.erb",
    "content": "<%# locals: (events_without_location:) %>\n\n<%= turbo_frame_tag \"events_without_location\" do %>\n  <h2 class=\"mb-4\">Events without locations (<%= events_without_location.flat_map(&:last).count %>)</h2>\n\n  <article class=\"prose mb-6\">This section lists events that are missing location information. By adding a location, we can show in which city/country this event took place.</article>\n\n  <div id=\"events-without-locations\" class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-4 min-w-full mb-6\">\n    <% events_without_location.each do |file_path, events| %>\n      <%= link_to \"https://github.com/rubyevents/rubyevents/edit/main/#{file_path}\", id: \"event-#{file_path}\", class: \"hover:bg-gray-100 p-4 rounded-lg border bg-white\", target: :_blank do %>\n        <div class=\"flex flex-col\">\n          <h3 class=\"line-clamp-1\"><pre>Data File: <%= file_path %></pre></h3>\n\n          <b class=\"mt-4 mb-2\">Events missing locations:</b>\n\n          <% events.each do |event| %>\n            <span><%= event.title %></span>\n          <% end %>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/contributions/_events_without_videos.html.erb",
    "content": "<%# locals: (events_without_videos:) %>\n\n<%= turbo_frame_tag \"events_without_videos\" do %>\n  <h2 class=\"mb-4\">Events without videos (<%= events_without_videos.flat_map(&:last).count %>)</h2>\n\n  <article class=\"prose mb-6\">This section highlights events that do not have associated videos available. Explore these events to see if the talks weren't recorded or just not yet added the site.</article>\n\n  <div id=\"events-without-locations\" class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-4 min-w-full mb-6\">\n    <% events_without_videos.each do |series, events| %>\n      <%= content_tag :div, id: dom_id(series, \"without-videos\"), class: \"p-4 rounded-lg border bg-white\", target: :_blank do %>\n        <div class=\"flex flex-col\">\n          <h3 class=\"line-clamp-1\"><p>Event Series: <%= link_to series.name, series_path(series), class: \"hover:underline\" %></p></h3>\n\n          <b class=\"mt-4 mb-2\">Events without videos:</b>\n\n          <% events.each do |event| %>\n            <span>\n              <%= link_to event.name, event, class: \"hover:underline\", data: {turbo_frame: \"_top\"} %>\n              <% if event.static_metadata.playlist.present? %>\n                (<%= link_to \"playlist\", event.static_metadata.playlist, target: \"_blank\", rel: \"noopener\" %>)\n              <% end %>\n            </span>\n          <% end %>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/contributions/_introduction.html.erb",
    "content": "<article class=\"prose\">\n  <h2>Welcome to RubyEvents.org! 🌟</h2>\n\n  <p>We are thrilled to have you here and appreciate your interest in making this resource the best it can be for the community. If you would like to lend a hand, there are various ways you can contribute.</p>\n\n  <p>This page serves as a friendly starting point for anyone looking to get involved but unsure where to begin. Here are some ways you can help:</p>\n\n  <ul>\n    <li>Assist in adding missing GitHub handles to speakers</li>\n    <li>Help identify speakers based on conference screenshots</li>\n    <li>Contribute by adding last names to speakers</li>\n    <li>Attach Slides to talks</li>\n    <li>Review the date when the talk was given</li>\n    <li>Add location information to conferences</li>\n    <li>Add event dates to conferences</li>\n    <li>Add data for new conferences</li>\n  </ul>\n</article>\n"
  },
  {
    "path": "app/views/contributions/_missing_videos_cue.html.erb",
    "content": "<%# locals: (missing_videos_cue:, missing_videos_cue_count:) %>\n\n<%= turbo_frame_tag \"missing_videos_cue\" do %>\n  <h2 class=\"mb-4\">Missing Video Cues (<%= missing_videos_cue_count %>)</h2>\n\n  <article class=\"prose mb-6\">\n    This section highlights talks that have child talks but are missing video cues. You can help by adding video cues to these talks so we can let users play the the talk from the exact time it starts.\n  </article>\n\n  <div id=\"talks-dates-out-of-bounds\" class=\"grid sm:grid-cols-1 lg:grid-cols-2 xl:grid-cols-2 gap-4 min-w-full mb-6\">\n    <% missing_videos_cue.each do |event, talks| %>\n      <%= content_tag :div, id: dom_id(event), class: \"p-4 rounded-lg border bg-white\", target: :_blank do %>\n        <article class=\"prose\">\n          <h3 class=\"line-clamp-1\">Event: <%= event.name %></h3>\n\n          <b class=\"mt-4 mb-2\">Recording doesn't have cues for it's child talks:</b>\n\n          <ul>\n            <% talks.each do |talk| %>\n              <li><%= link_to talk.title, talk %> (<%= link_to pluralize(talk.child_talks.size, \"talk\"), talk %>) [<%= link_to \"Data File\", \"https://github.com/rubyevents/rubyevents/edit/main/#{talk.static_metadata.__file_path}\", target: :_blank %>]</li>\n            <% end %>\n          </ul>\n        </article>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/contributions/_speakers_without_github.html.erb",
    "content": "<%# locals: (speakers_without_github:) %>\n\n<%= turbo_frame_tag \"speakers_without_github\" do %>\n  <h2 class=\"mb-4\">Speakers without GitHub handles (<%= speakers_without_github.count %>)</h2>\n\n  <article class=\"prose mb-6\">These speakers are currently missing a GitHub handle. By adding a GitHub handle to their profile, we can enhance their speaker profiles with an avatar and automatically retrieve additional information.</article>\n\n  <div id=\"speakers\" class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 min-w-full mb-6\">\n    <% speakers_without_github.each do |speaker| %>\n      <%= content_tag :div, id: dom_id(speaker), class: \"flex justify-between p-4 rounded-lg border bg-white\" do %>\n        <span><%= link_to speaker.name, edit_profile_path(speaker), class: \"underline link\", data: {turbo_frame: \"modal\"} %></span>\n        <span>\n          <%= link_to \"https://github.com/search?q=#{speaker.name}&type=users\", target: \"_blank\", class: \"underline link\" do %>\n            <%= fa(\"magnifying-glass\", style: :regular) %>\n          <% end %>\n        </span>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/contributions/_talks_dates_out_of_bounds.html.erb",
    "content": "<%# locals: (out_of_bound_talks:, dates_by_event_name:) %>\n\n<%= turbo_frame_tag \"talks_dates_out_of_bounds\" do %>\n  <h2 class=\"mb-4\">Review Talk Dates (<%= out_of_bound_talks.flat_map(&:last).count %>)</h2>\n\n  <article class=\"prose mb-6\">This section shows talks with dates that don't quite match the event dates. Sometimes we only have the year for certain events, so we use that as a reference.</article>\n\n  <div id=\"talks-dates-out-of-bounds\" class=\"grid sm:grid-cols-1 lg:grid-cols-2 xl:grid-cols-2 gap-4 min-w-full mb-6\">\n    <% out_of_bound_talks.select { |_event, talks| talks.any? }.each do |event, talks| %>\n      <%= content_tag :div, id: dom_id(event), class: \"p-4 rounded-lg border bg-white\", target: :_blank do %>\n        <article class=\"prose\">\n          <h3 class=\"line-clamp-1\">Event: <%= event.name %></h3>\n\n          <b class=\"mt-4 mb-2\">Talk date is outside event dates:</b>\n\n          <p class=\"mb-2\">Event Dates: <%= dates_by_event_name[event.name].inspect %></p>\n\n          <ul>\n            <% talks.each do |talk| %>\n              <li><%= link_to talk.title, talk %> (<%= link_to talk.date.to_fs(:long), talk %>)</li>\n            <% end %>\n          </ul>\n        </article>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/contributions/_talks_without_slides.html.erb",
    "content": "<%# locals: (talks_without_slides:) %>\n\n<%= turbo_frame_tag \"talks_without_slides\" do %>\n  <h2 class=\"mb-4\">Talks without slides (<%= talks_without_slides.count %>)</h2>\n\n  <article class=\"prose mb-6\">These talks currently do not have slides attached. However, we know that the speaker has an account on Speakerdeck where they usually upload their slides. Feel free to explore if these talks have associated slidedecks on Speakerdeck.com.</article>\n\n  <div id=\"speakers\" class=\"grid sm:grid-cols-1 lg:grid-cols-2 xl:grid-cols-2 gap-4 min-w-full mb-6\">\n    <% talks_without_slides.each do |talk| %>\n      <%= link_to edit_talk_path(talk), id: dom_id(talk), class: \"hover:bg-gray-100 p-4 rounded-lg border bg-white\" do %>\n        <div class=\"flex flex-col\">\n          <span class=\"font-bold\"><%= talk.title %></span>\n          <span><%= talk.speakers.first.name %></span>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/contributions/index.html.erb",
    "content": "\n<div class=\"container py-8\">\n  <h1 class=\"title\">\n    <span class=\"title\">Getting Started: Ways to Contribute</span>\n  </h1>\n\n  <div role=\"tablist\" class=\"tabs tabs-bordered mt-6\">\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Introduction\" checked style=\"width: 125px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <%= render \"contributions/introduction\" %>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Speakers without GitHub handles\" style=\"width: 300px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <%= turbo_frame_tag \"speakers_without_github\", src: contribution_path(:speakers_without_github), loading: :lazy %>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Talks without slides\" style=\"width: 225px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <%= turbo_frame_tag \"talks_without_slides\", src: contribution_path(:talks_without_slides), loading: :lazy %>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Events without videos\" style=\"width: 225px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <%= turbo_frame_tag \"events_without_videos\", src: contribution_path(:events_without_videos), loading: :lazy %>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Events without locations\" style=\"width: 225px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <%= turbo_frame_tag \"events_without_location\", src: contribution_path(:events_without_location), loading: :lazy %>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Events without conference dates\" style=\"width: 300px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <%= turbo_frame_tag \"events_without_dates\", src: contribution_path(:events_without_dates), loading: :lazy %>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Review Talk Dates\" style=\"width: 200px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <%= turbo_frame_tag \"talks_dates_out_of_bounds\", src: contribution_path(:talks_dates_out_of_bounds), loading: :lazy %>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Missing Video Cues\" style=\"width: 200px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <%= turbo_frame_tag \"missing_videos_cue\", src: contribution_path(:missing_videos_cue), loading: :lazy %>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Overdue scheduled talks (<%= @overdue_scheduled_talks_count %>)\" style=\"width: 250px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <div>\n        <h2 class=\"mb-4\">Overdue scheduled talks (<%= @overdue_scheduled_talks_count %>)</h2>\n\n        <article class=\"prose mb-6\">\n          These talks were scheduled and have been held now. If you have any information about these talks, please update the status.<br><br>\n\n          If the scheduled talk was recorded and the recording is already available, you can change the <code>video_provider</code> from <code>scheduled</code> to <code>youtube</code> (or any other video provider we support) and provide the <code>video_id</code> so we can embed it.<br><br>\n\n          If the scheduled talk was recorded but the recording is not available yet, you can change the <code>video_provider</code> from <code>scheduled</code> to <code>not_published</code>.<br><br>\n\n          If the scheduled talk was not recorded, you can change the <code>video_provider</code> from <code>scheduled</code> to <code>not_recorded</code>.<br><br>\n\n          In either case, you can provide the <code>slides_url</code> so we can at least show the slides for the talk.\n        </article>\n\n        <div id=\"overdue-scheduled-talks\" class=\"grid sm:grid-cols-1 lg:grid-cols-2 xl:grid-cols-2 gap-4 min-w-full mb-6\">\n          <% @overdue_scheduled_talks.group_by(&:event).each do |event, talks| %>\n            <%= content_tag :div, id: dom_id(event), class: \"p-4 rounded-lg border bg-white\", target: :_blank do %>\n              <article class=\"prose\">\n                <h3 class=\"line-clamp-1\">Event: <%= event.name %></h3>\n\n                <ul>\n                  <% talks.each do |talk| %>\n                    <li><%= link_to talk.title, \"https://github.com/rubyevents/rubyevents/edit/main/#{talk.static_metadata.__file_path}\", target: \"_blank\" if talk.static_metadata %> (<%= link_to talk.date.to_fs(:long), talk %>, <%= time_ago_in_words(talk.date) %> ago)</li>\n                  <% end %>\n                </ul>\n              </article>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Talks without speakers (<%= @talks_without_speakers_count %>)\" style=\"width: 225px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <div>\n        <h2 class=\"mb-4\">Talks without speakers (<%= @talks_without_speakers_count %>)</h2>\n\n        <article class=\"prose mb-6\">\n          These talks currently don't have speakers assigned.\n        </article>\n\n        <div id=\"talks-without-speakers\" class=\"grid sm:grid-cols-1 lg:grid-cols-2 xl:grid-cols-2 gap-4 min-w-full mb-6\">\n\n          <% @talks_without_speakers.group_by(&:event).sort_by { |_event, talks| talks.minimum(:date) }.each do |event, talks| %>\n            <%= content_tag :div, id: dom_id(event), class: \"p-4 rounded-lg border bg-white\", target: :_blank do %>\n              <article>\n                <div class=\"prose\">\n                  <h3 class=\"line-clamp-1\">Event: <%= event.name %></h3>\n                </div>\n\n                <h3 class=\"line-clamp-1 mt-3 mb-6\"><pre>Data File: <%= talks.first.static_metadata&.__file_path.inspect %></pre></h3>\n\n                <div class=\"prose\">\n                  <ul>\n                    <% talks.each do |talk| %>\n                      <li><%= link_to talk.title, \"https://github.com/rubyevents/rubyevents/edit/main/#{talk.static_metadata.__file_path}\", target: \"_blank\" if talk.static_metadata %> (<%= link_to talk.date.to_fs(:long), talk %>)</li>\n                    <% end %>\n                  </ul>\n                </div>\n              </article>\n            <% end %>\n          <% end %>\n\n        </div>\n      </div>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Not published talks (<%= @not_published_talks_count %>)\" style=\"width: 200px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <div>\n        <h2 class=\"mb-4\">Not published talks (<%= @not_published_talks_count %>)</h2>\n\n        <article class=\"prose mb-6\">\n          These talks have been held, were recorded, but have not been published yet. Or maybe they are already published but haven't been added to rubyevents.org yet.<br><br>\n\n          If the talk recording is available, you can change the <code>video_provider</code> from <code>not_published</code> to <code>youtube</code> (or any other video provider we support) and provide the <code>video_id</code> so we can embed it.<br><br>\n\n          If available, you can also provide the <code>slides_url</code> so we can show the slides next to the talk.\n        </article>\n\n        <div id=\"not-published-talks\" class=\"grid sm:grid-cols-1 lg:grid-cols-2 xl:grid-cols-2 gap-4 min-w-full mb-6\">\n          <% @not_published_talks.group_by(&:event).sort_by { |_event, talks| talks.minimum(:date) }.each do |event, talks| %>\n            <%= content_tag :div, id: dom_id(event), class: \"p-4 rounded-lg border bg-white\", target: :_blank do %>\n              <article class=\"prose\">\n                <h3 class=\"line-clamp-1\">Event: <%= event.name %></h3>\n\n                <ul>\n                  <% talks.each do |talk| %>\n                    <li><%= link_to talk.title, \"https://github.com/rubyevents/rubyevents/edit/main/#{talk.static_metadata.__file_path}\", target: \"_blank\" if talk.static_metadata %> (<%= link_to talk.date.to_fs(:long), talk %>, <%= time_ago_in_words(talk.date) %> ago)</li>\n                  <% end %>\n                </ul>\n              </article>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Add missing events (<%= @conferences_to_index %>)\" style=\"width: 225px\">\n    <div role=\"tabpanel\" class=\"tab-content py-6\">\n      <div>\n        <h2 class=\"mb-4\">Add missing events (<%= @conferences_to_index %>)</h2>\n\n        <article class=\"prose mb-6\">\n          <p>If you know of an event that's not yet on rubyevents.org, please feel free to add it. This includes events in the future, events with unrecorded talks, or events with talks not yet uploaded online.</p>\n\n          <p>We are checking against <a href=\"https://rubyconferences.org\" target=\"_blank\">rubyconferences.org</a> to identify missing events. Below, we will list conferences with video links first, followed by those without a video link.</p>\n\n          <p>If you would like to contribute data for any of the events listed below, please refer to <a href=\"https://github.com/rubyevents/rubyevents/blob/main/docs/ADDING_EVENTS.md\" target=\"_blank\">this guide</a> to add the event to the site.</p>\n        </article>\n\n        <h3 class=\"font-bold mb-3\">Conferences from RubyConferences.org we already indexed</h3>\n\n        <article class=\"prose mb-6\">\n          <p>We already indexed <%= pluralize(@already_index_conferences, \"conference\") %> out of the <%= pluralize(@upstream_conferences.count, \"conference\") %> listed on RubyConferences.org.</p>\n\n          <p>There are <%= pluralize(@conferences_to_index, \"more conference\") %> from RubyConferences.org to be added to rubyevents.org.</p>\n        </article>\n\n        <h3 class=\"font-bold mb-3\">Conferences from RubyConferences.org with a video link (<%= pluralize(@with_video_link.count, \"event\") %>)</h3>\n        <div id=\"missing-conferences-with-link\" class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-4 min-w-full mb-6\">\n          <% @with_video_link.each do |event| %>\n            <%= link_to event[\"video_link\"], id: \"#{event[\"name\"]}-pending\", class: \"hover:bg-gray-100 p-4 rounded-lg border bg-white\", target: :_blank do %>\n              <div class=\"flex flex-col\">\n                <h3 class=\"line-clamp-1 font-semibold\"><%= event[\"name\"] %></h3>\n\n                Videos: <%= URI.parse(event[\"video_link\"]).host %>\n              </div>\n            <% end %>\n          <% end %>\n        </div>\n\n        <h3 class=\"font-bold mb-3\">Conferences from RubyConferences.org without a video link (<%= pluralize(@without_video_link.count, \"event\") %>)</h3>\n        <div id=\"missing-conferences-without-link\" class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-4 min-w-full mb-6\">\n          <% @without_video_link.each do |event| %>\n            <%= link_to event[\"url\"], id: \"#{event[\"name\"]}-pending\", class: \"hover:bg-gray-100 p-4 rounded-lg border bg-white\", target: :_blank do %>\n              <div class=\"flex flex-col\">\n                <h3 class=\"line-clamp-1 font-semibold\"><%= event[\"name\"] %></h3>\n\n                <% if event[\"url\"].present? %>\n                  Website: <%= URI.parse(event[\"url\"]).host %>\n                <% else %>\n                  Website: -\n                <% end %>\n              </div>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Events without schedule (<%= @conferences_with_missing_schedule_count %>)\" style=\"width: 250px\">\n    <div role=\"tabpanel\" class=\"tab-content bg-base-100 border-base-300 rounded-box p-6\">\n      <div>\n        <h2 class=\"mb-4\">Events without schedule (<%= @conferences_with_missing_schedule_count %>)</h2>\n\n        <article class=\"prose mb-6\">\n          <p>These events are missing schedule information. If you have access to the schedule, please consider adding it to the event page by adding a <code>schedule.yml</code> to the data folder.</p>\n        </article>\n\n        <div id=\"events-without-schedule\" class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-4 min-w-full mb-6\">\n          <% @conferences_with_missing_schedule.each do |series, events| %>\n            <%= content_tag :div, id: dom_id(series, \"without-schedule\"), class: \"p-4 rounded-lg border bg-white\", target: :_blank do %>\n              <div class=\"flex flex-col\">\n                <h3 class=\"line-clamp-1\"><p>Event Series: <%= link_to series.name, series_path(series), class: \"hover:underline\" %></p></h3>\n\n                <b class=\"mt-4 mb-2\">Events without schedule:</b>\n\n                <% events.each do |event| %>\n                  <span><%= link_to event.name, event, class: \"hover:underline\" %></span>\n                <% end %>\n              </div>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    </div>\n\n    <input type=\"radio\" name=\"contribution-tabs\" role=\"tab\" class=\"tab\" aria-label=\"Event Assets\" style=\"width: 250px\">\n    <div role=\"tabpanel\" class=\"tab-content bg-base-100 border-base-300 rounded-box p-6\">\n      <div>\n        <h2 class=\"mb-4\">Event Assets</h2>\n\n        <article class=\"prose mb-6\">\n          <p>We have a dedicated page for reviewing event assets like logos, posters, cards, and other event assets that need to be added or updated.</p>\n          <p>Please visit the <%= link_to \"Event Assets Page\", pages_assets_path, class: \"underline\" %> to see the list of events and their assets.</p>\n        </article>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/contributions/show.html.erb",
    "content": "<% case @step %>\n<% when :speakers_without_github %>\n  <%= render \"contributions/speakers_without_github\", locals: {speakers_without_github: @speakers_without_github} %>\n<% when :talks_without_slides %>\n  <%= render \"contributions/talks_without_slides\", locals: {talks_without_slides: @talks_without_slides} %>\n<% when :events_without_videos %>\n  <%= render \"contributions/events_without_videos\", locals: {events_without_videos: @events_without_videos} %>\n<% when :events_without_location %>\n  <%= render \"contributions/events_without_location\", locals: {events_without_location: @events_without_location} %>\n<% when :events_without_dates %>\n  <%= render \"contributions/events_without_dates\", locals: {events_without_dates: @events_without_dates} %>\n<% when :talks_dates_out_of_bounds %>\n  <%= render \"contributions/talks_dates_out_of_bounds\", locals: {out_of_bound_talks: @out_of_bound_talks, dates_by_event_name: @dates_by_event_name} %>\n<% when :missing_videos_cue %>\n  <%= render \"contributions/missing_videos_cue\", locals: {missing_videos_cue: @missing_videos_cue, missing_videos_cue_count: @missing_videos_cue_count} %>\n<% end %>\n"
  },
  {
    "path": "app/views/coordinates/index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% title \"Explore Ruby Communities\" %>\n\n<div class=\"container py-16\">\n  <div class=\"max-w-2xl mx-auto text-center\">\n    <h1 class=\"text-4xl font-bold text-gray-900 mb-4\">\n      Explore Ruby Communities\n    </h1>\n\n    <p class=\"text-lg text-gray-600 mb-12\">\n      Find Ruby events and Rubyists near any location in the world\n    </p>\n\n    <div class=\"space-y-6\" data-controller=\"geolocation\">\n      <%= form_tag locations_search_path, method: :get, class: \"flex gap-2\" do %>\n        <div class=\"flex-1\">\n          <%= text_field_tag :q, params[:q], placeholder: \"Search for a city, address, or place...\", class: \"input input-bordered w-full h-10\", autofocus: true, autocomplete: \"off\" %>\n        </div>\n\n        <%= submit_tag \"Search\", class: \"btn btn-primary\" %>\n      <% end %>\n\n      <div class=\"divider\">OR</div>\n\n      <button\n        type=\"button\"\n        class=\"btn btn-outline btn-lg gap-2\"\n        data-action=\"click->geolocation#locate\"\n        data-geolocation-target=\"button\">\n        <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n          <path fill-rule=\"evenodd\" d=\"M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z\" clip-rule=\"evenodd\" />\n        </svg>\n        <span data-geolocation-target=\"text\">Use My Location</span>\n      </button>\n\n      <p class=\"text-sm text-gray-500\" data-geolocation-target=\"status\"></p>\n    </div>\n\n    <div class=\"mt-16\">\n      <h2 class=\"text-xl font-semibold text-gray-900 mb-6\">Or browse by</h2>\n\n      <div class=\"flex flex-wrap justify-center gap-4\">\n        <%= link_to continents_path, class: \"btn btn-ghost gap-2\" do %>\n          <span class=\"text-xl\">🌍</span>\n          Continents\n        <% end %>\n\n        <%= link_to countries_path, class: \"btn btn-ghost gap-2\" do %>\n          <span class=\"text-xl\">🏳️</span>\n          Countries\n        <% end %>\n\n        <%= link_to cities_path, class: \"btn btn-ghost gap-2\" do %>\n          <span class=\"text-xl\">🏙️</span>\n          Cities\n        <% end %>\n\n        <%= link_to online_path, class: \"btn btn-ghost gap-2\" do %>\n          <span class=\"text-xl\">🌐</span>\n          Online\n        <% end %>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/coordinates/map/index.html.erb",
    "content": "<%= render \"shared/location_map\",\n      location: @location,\n      layers: @layers || [],\n      time_layers: @time_layers || [],\n      geo_layers: @geo_layers || [],\n      online_events: @online_events || [] %>\n"
  },
  {
    "path": "app/views/coordinates/past/index.html.erb",
    "content": "<%= render \"shared/location_past\",\n      location: @location,\n      events: @events,\n      users: @users,\n      event_map_markers: @event_map_markers || [],\n      geo_layers: @geo_layers || [],\n      nearby_users: @nearby_users || [] %>\n"
  },
  {
    "path": "app/views/coordinates/show.html.erb",
    "content": "<%= render \"shared/location_show\",\n      location: @location,\n      events: @events,\n      users: @users,\n      stamps: [],\n      event_map_markers: @event_map_markers || [],\n      geo_layers: @geo_layers || [],\n      nearby_users: @nearby_users || [],\n      nearby_events: @nearby_events || [],\n      country_events: [],\n      country: @country,\n      state: nil,\n      state_users: [],\n      continent_events: [],\n      continent: @continent,\n      emoji: @location.country_code.blank? ? \"📍\" : nil %>\n"
  },
  {
    "path": "app/views/coordinates/users/index.html.erb",
    "content": "<%= render \"shared/location_users\",\n      location: @location,\n      users: @users,\n      nearby_users: @nearby_users || [],\n      state: nil,\n      state_users: [],\n      country: @country,\n      country_users: @country_users || [] %>\n"
  },
  {
    "path": "app/views/countries/cities/index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% title \"Cities in #{@country.name}\" %>\n\n<%= render \"shared/location_header\",\n      name: @country.name,\n      subtitle: @country.to_location.to_text,\n      flag_code: @country.alpha2,\n      stats: \"#{pluralize(@cities.size, \"city\")} with Ruby events in #{@country.name}\",\n      location: @country %>\n\n<%= render \"shared/location_navigation\",\n      location: @country,\n      current_tab: \"cities\",\n      show_cities: true,\n      show_states: @country&.states?,\n      show_stamps: true %>\n\n<div class=\"container py-8\">\n  <div class=\"flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6\">\n    <div class=\"flex items-center gap-3\">\n      <h2 class=\"text-xl font-bold text-gray-900\">Cities in <%= @country.name %></h2>\n      <%= ui_badge(@cities.size, kind: :secondary, outline: true) %>\n    </div>\n\n    <div class=\"flex items-center gap-2\">\n      <span class=\"text-sm text-gray-500\">Sort:</span>\n      <%= link_to \"Events\", country_cities_path(@country, sort: \"events\"),\n            class: \"btn btn-sm #{(@sort == \"events\") ? \"btn-primary\" : \"btn-ghost\"}\" %>\n      <%= link_to \"A-Z\", country_cities_path(@country, sort: \"name\"),\n            class: \"btn btn-sm #{(@sort == \"name\") ? \"btn-primary\" : \"btn-ghost\"}\" %>\n    </div>\n  </div>\n\n  <% if @cities.any? %>\n    <div class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4\">\n      <% @cities.each do |city| %>\n        <%= link_to city.path,\n              class: \"flex flex-col p-4 bg-white rounded-xl border hover:border-gray-400 transition-colors\" do %>\n          <div class=\"flex items-center justify-between mb-2\">\n            <div class=\"flex items-center gap-2\">\n              <span class=\"font-semibold text-gray-900\"><%= city.name %></span>\n              <% if @show_states && city.state_code.present? %>\n                <span class=\"text-sm text-gray-400\"><%= city.state_code %></span>\n              <% end %>\n            </div>\n            <%= ui_badge(city.events_count, kind: :secondary, outline: true, size: :sm) %>\n          </div>\n\n          <div class=\"text-sm text-gray-500\">\n            <%= pluralize(city.events_count, \"event\") %>\n          </div>\n\n          <% if city.events.any? %>\n            <div class=\"flex -space-x-2 mt-3\">\n              <% city.events.first(4).each do |event| %>\n                <% if event.avatar_image_path %>\n                  <div class=\"w-8 h-8 rounded overflow-hidden ring-2 ring-white\">\n                    <%= image_tag event.avatar_image_path, alt: event.name, class: \"w-full h-full object-cover\", loading: \"lazy\" %>\n                  </div>\n                <% end %>\n              <% end %>\n            </div>\n          <% end %>\n        <% end %>\n      <% end %>\n    </div>\n  <% else %>\n    <p class=\"text-gray-500 py-8 text-center\">No cities with events found in <%= @country.name %> yet.</p>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/countries/index.html.erb",
    "content": "<div class=\"container py-8\">\n  <div class=\"flex items-center justify-between w-full hotwire-native:hidden\">\n    <h1 class=\"title\">\n      <%= title \"Countries\" %>\n    </h1>\n  </div>\n\n  <p class=\"mt-3 md:mt-6 mb-6 text-[#636B74] max-w-[700px]\">\n    Explore Ruby events and Rubyists from around the world by country.\n  </p>\n\n  <div\n    id=\"map\"\n    class=\"w-full h-96 mt-6 rounded-lg\"\n    data-controller=\"map\"\n    data-map-markers-value=\"<%= @event_map_markers.to_json %>\"></div>\n\n  <div class=\"mt-6\">\n    <% @countries_by_continent.each do |continent, countries| %>\n      <% if countries.any? %>\n        <h2 class=\"mt-3\"><%= link_to continent.name, continent_path(continent), class: \"hover:underline\" %></h2>\n\n        <div\n          id=\"events-<%= continent.name %>\"\n          class=\"\n            grid sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-x-8 lg:gap-x-12 gap-y-2\n            min-w-full pt-4 pb-8\n          \">\n          <% countries.sort_by(&:iso_short_name).each do |country| %>\n            <% events = @events_by_country[country] %>\n            <% users_count = @users_by_country[country] || 0 %>\n            <% next if events.nil? %>\n\n            <%= link_to country_path(country.slug), id: \"country-#{country.alpha2}\", class: \"event flex justify-between items-center\" do %>\n              <div class=\"flex items-center gap-2\">\n                <span class=\"event-name\"><%= country.emoji_flag %>\n                  <%= country.name %></span>\n              </div>\n              <div class=\"flex gap-2 items-center\">\n                <% if users_count > 0 %>\n                  <%= ui_badge(\n                        \"#{users_count} #{\"Rubyist\".pluralize(users_count)}\",\n                        kind: :primary,\n                        outline: true,\n                        size: :md,\n                        class: \"whitespace-nowrap\"\n                      ) %>\n                <% end %>\n                <%= ui_badge(\n                      events.count,\n                      kind: :secondary,\n                      outline: true,\n                      size: :lg,\n                      class: \"min-w-10\"\n                    ) %>\n              </div>\n            <% end %>\n          <% end %>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/countries/map/index.html.erb",
    "content": "<%= render \"shared/location_map\",\n      location: @country,\n      layers: @layers || [],\n      time_layers: @time_layers || [],\n      geo_layers: @geo_layers || [],\n      online_events: @online_events || [] %>\n"
  },
  {
    "path": "app/views/countries/meetups/index.html.erb",
    "content": "<%= render \"shared/location_meetups\", location: @location, meetups: @meetups %>\n"
  },
  {
    "path": "app/views/countries/past/index.html.erb",
    "content": "<%= render \"shared/location_past\",\n      location: @country,\n      events: @events,\n      users: @users,\n      event_map_markers: @event_map_markers,\n      geo_layers: @geo_layers || [],\n      cities: @cities || [] %>\n"
  },
  {
    "path": "app/views/countries/show.html.erb",
    "content": "<%= render \"shared/location_show\",\n      location: @country,\n      events: @events,\n      users: @users,\n      stamps: @stamps,\n      event_map_markers: @event_map_markers || [],\n      geo_layers: @geo_layers || [],\n      nearby_users: @nearby_users || [],\n      cities: @cities || [],\n      country_events: @country_events || [],\n      country: @parent_country,\n      continent_events: @continent_events || [],\n      continent: @continent %>\n"
  },
  {
    "path": "app/views/countries/stamps/index.html.erb",
    "content": "<%= render \"shared/location_stamps\",\n      location: @country,\n      stamps: @stamps %>\n"
  },
  {
    "path": "app/views/countries/state.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<div class=\"container py-8\">\n  <div class=\"block lg:flex gap-8 align-center justify-between\">\n    <div class=\"flex flex-col lg:flex-row gap-8 items-center lg:justify-right text-center lg:text-left mb-6 lg:mb-0\">\n      <span class=\"fi fi-<%= @country.alpha2.downcase %> border rounded w-36 text-[80pt]\"></span>\n      <div class=\"flex-col flex justify-center\">\n        <h1 class=\"mb-2 text-black font-bold\">\n          <%= title \"Ruby Community in #{@state.name}\" %>\n        </h1>\n\n        <h3 class=\"hidden md:block text-[#636B74]\">\n          <%= link_to @country.name, country_path(@country), class: \"hover:underline\" %>\n        </h3>\n      </div>\n    </div>\n\n    <div class=\"flex flex-col gap-3 place-items-center\">\n      <%= ui_button \"View all events in #{@country.name}\", url: country_path(@country), kind: :secondary, size: :sm, class: \"w-full\" %>\n    </div>\n  </div>\n\n  <p class=\"mt-3 md:mt-9 mb-6 text-[#636B74] max-w-[700px]\">\n    We have indexed <%= pluralize(@users.count, \"Rubyist\") %> and <%= pluralize(@events.count, \"event\") %> in <%= @state.name %>.\n  </p>\n\n  <% if @users.any? %>\n    <div id=\"rubyists\" class=\"mt-12\">\n      <section class=\"flex flex-col w-full gap-4\">\n        <div class=\"flex items-center justify-between w-full\">\n          <h2 class=\"text-primary shrink-0\">Rubyists in <%= @state.name %></h2>\n        </div>\n\n        <div class=\"grid min-w-full grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n          <% @users.each do |user| %>\n            <%= render partial: \"users/card\", locals: {user: user, content: user.to_location.to_text} %>\n          <% end %>\n        </div>\n      </section>\n    </div>\n  <% end %>\n\n  <% if (groups = @events.group_by(&:kind)).any? %>\n    <% groups.each do |kind, events| %>\n      <div id=\"events\" class=\"mt-12\">\n        <section class=\"flex flex-col w-full gap-4\">\n          <div class=\"flex items-center justify-between w-full\">\n            <h2 class=\"text-primary shrink-0\"><%= kind.humanize.pluralize %></h2>\n          </div>\n\n          <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n            <%= cache events do %>\n              <%= render partial: \"events/card\", collection: events, as: :event, cached: true %>\n            <% end %>\n          </div>\n        </section>\n      </div>\n    <% end %>\n  <% end %>\n\n  <% if @cities.any? %>\n    <div id=\"cities\" class=\"mt-12\">\n      <section class=\"flex flex-col w-full gap-4\">\n        <div class=\"flex items-center justify-between w-full\">\n          <h2 class=\"text-primary shrink-0\">Cities</h2>\n        </div>\n\n        <div class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-8 lg:gap-x-12 gap-y-2 min-w-full\">\n          <% @cities.each do |city| %>\n            <%= link_to city.path, id: \"city-#{city.slug}\", class: \"event flex justify-between items-center\" do %>\n              <div class=\"flex items-center gap-2\">\n                <span class=\"event-name\"><%= city.name %></span>\n              </div>\n\n              <%= ui_badge(city.events_count, kind: :secondary, outline: true, size: :lg, class: \"min-w-10\") %>\n            <% end %>\n          <% end %>\n        </div>\n      </section>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/countries/users/index.html.erb",
    "content": "<%= render \"shared/location_users\",\n      location: @country,\n      users: @users %>\n"
  },
  {
    "path": "app/views/event_participations/create.turbo_stream.erb",
    "content": "<%= turbo_stream.replace_all(\".participation_button\", partial: \"events/participation_button\", locals: {event: @event, participation: @participation}) %>\n<%= turbo_stream.replace(\"participants_list\", partial: \"events/participants/list\", locals: {event: @event, participants: @participants, participation: @participation, favorite_users: @favorite_users}) %>\n"
  },
  {
    "path": "app/views/event_participations/destroy.turbo_stream.erb",
    "content": "<%= turbo_stream.replace_all(\".participation_button\", partial: \"events/participation_button\", locals: {event: @event, participation: @participation}) %>\n<%= turbo_stream.replace(\"participants_list\", partial: \"events/participants/list\", locals: {event: @event, participants: @participants, participation: @participation, favorite_users: @favorite_users}) %>\n"
  },
  {
    "path": "app/views/events/_card.html.erb",
    "content": "<%# locals: (event:, participation: nil) %>\n\n<%= link_to event_path(event), class: \"flex w-full\", data: {turbo_frame: \"_top\"} do %>\n  <div class=\"card card-compact bg-white border w-full <%= \"cancelled\" if event.static_metadata.cancelled? %>\">\n    <%= image_tag image_path(event.card_image_path), class: \"w-full object-cover rounded-t-xl border-b\", alt: event.name, width: 300, height: 175 %>\n    <div class=\"card-body flex flex-col items-center justify-center min-h-[130px]\">\n      <div class=\"text-xl font-semibold text-center line-clamp-1\"><%= event.name %></div>\n      <div class=\"text-gray-500 flex flex-col text-center items-center\">\n        <span><%= event.to_location.to_html(show_links: false) %></span>\n        <span class=\"mt-1\"><%= event.formatted_dates %></span>\n\n        <% if participation.present? %>\n          <%= ui_badge(participation.attended_as.humanize, size: :sm, class: \"mt-2 bg-blue-700 border-blue-700\") %>\n        <% end %>\n\n        <% if event.static_metadata.last_edition? %>\n          <div class=\"flex items-center justify-center mt-2 text-gray-400\">\n            <%= fa \"box-archive\", size: :xs, style: :regular, class: \"fill-gray-400\" %>\n            <span class=\"text-sm mt-0.5 ml-1\">Final Edition</span>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/_event.html.erb",
    "content": "<%= link_to event_path(event), id: dom_id(event), class: \"event flex justify-between items-center\" do %>\n  <div class=\"flex items-center gap-2\">\n    <%= image_tag image_path(event.avatar_image_path), style: \"view-transition-name: #{dom_id(event, :logo)}\", class: \"size-8 rounded-full\", loading: \"lazy\" %>\n    <span class=\"event-name\"><%= event.name %></span>\n  </div>\n  <%= ui_badge(event.talks_count, kind: :secondary, outline: true, size: :lg, class: \"min-w-10\") %>\n<% end %>\n"
  },
  {
    "path": "app/views/events/_event_list.html.erb",
    "content": "<div class=\"relative group\">\n  <div class=\"absolute md:hidden top-0 left-0 w-full h-24 bg-gradient-to-b from-base-100 to-transparent pointer-events-none rounded-t-xl z-10\"\n       data-event-list-target=\"topGradient\"></div>\n  <div id=\"event-list\"\n       class=\"border border-transparent md:hover:border-gray-200 rounded-xl flex flex-col gap-2 md:h-[75vh] md:overflow-scroll\"\n       data-event-list-target=\"list\"\n       data-action=\"scroll->event-list#updateGradients\">\n    <% events.each do |event| %>\n      <%= link_to event, class: \"event-item flex gap-4 group p-2 hover:bg-gray-200 rounded-md relative\", data: {action: \"mouseover->event-list#reveal\", event_list_target: \"item\", event_id: event.slug} do %>\n        <div class=\"flex flex-col lg:flex-row gap-8 items-center lg:justify-right text-center lg:text-left flex-shrink-0\">\n          <%= image_tag image_path(event.avatar_image_path),\n                class: \"rounded-xl border border-[#D9DFE3] size-16\",\n                alt: event.name.to_s,\n                style: \"view-transition-name: #{dom_id(event, :logo)}\",\n                loading: :lazy %>\n        </div>\n\n        <div class=\"flex-col flex justify-center relative overflow-hidden\">\n          <div class=\"text-black group-hover:text-inherit font-bold text-xl\"><%= event.name %></div>\n          <div class=\"text-[#636B74] group-hover:text-inherit\"><%= event.formatted_dates %> • <%= event.to_location.to_html(show_links: false) %></div>\n        </div>\n\n        <div class=\"absolute hidden gap-2 md:flex right-2\">\n          <%= render \"shared/cfp_countdown_badge\", event: event %>\n          <%= render \"shared/event_countdown_badge\", event: event %>\n        </div>\n\n      <% end %>\n    <% end %>\n  </div>\n  <div class=\"absolute md:block bottom-0 left-0 w-full h-64 bg-gradient-to-t from-base-100 to-transparent pointer-events-none rounded-b-xl\"\n       data-event-list-target=\"bottomGradient\"></div>\n</div>\n"
  },
  {
    "path": "app/views/events/_featured.html.erb",
    "content": "<div\n  class=\"w-full lg:h-92 p-4 lg:p-16 border rounded-[25px] lg:rounded-[50px] text-center lg:text-left\"\n  style=\"\n    color: <%= event.static_metadata.featured_color %>;\n    <% if event.static_metadata.featured_background.start_with?(\"data:\") %>\n      background: url('<%= event.static_metadata.featured_background %>');\n      background-repeat: no-repeat;\n      background-size: cover;\n    <% else %>\n      background: <%= event.static_metadata.featured_background %>;\n    <% end %>\n  \">\n  <a href=\"<%= event_path(event) %>\">\n    <div class=\"lg:grid grid-cols-[1fr_2fr]\">\n      <div>\n        <div class=\"flex justify-center mb-9\">\n          <%= image_tag event.featured_image_path, class: \"w-1/2 max-h-none lg:w-full\", loading: \"lazy\", width: 615, height: 350, alt: event.name %>\n        </div>\n\n        <div class=\"flex flex-col gap-3 lg:h-48 lg:max-h-48 overflow-hidden items-center lg:items-start\">\n          <h1 class=\"text-inherit font-bold text-xl line-clamp-1 lg:line-clamp-2\"><%= event.name %></h1>\n          <h2 class=\"text-inherit opacity-60 text-sm line-clamp-1\"><%= event.to_location.to_html(show_links: false) %> • <%= event.formatted_dates %></h2>\n          <h2 class=\"text-inherit font-medium text-sm line-clamp-3 hidden lg:block\">\n            <%= event.description %>\n\n            <%= home_updated_text(event) %>\n          </h2>\n        </div>\n\n        <%= ui_button kind: :rounded, class: \"btn-sm lg:btn-md my-4\" do %>\n          <span>Explore Talks</span>\n        <% end %>\n      </div>\n\n      <div class=\"hidden lg:flex flex-col justify-center items-center\">\n        <div>\n          <div class=\"avatar-group -space-x-6 rtl:space-x-reverse\">\n            <% shown_speakers = [] %>\n\n            <% all_speakers = event.speakers.to_a %>\n            <% speakers_with_avatars = all_speakers.select { |speaker| speaker.avatar_url.present? }.sort_by(&:avatar_rank) %>\n\n            <% event.keynote_speakers.each do |keynote_speaker| %>\n              <% shown_speakers << keynote_speaker %>\n\n              <%= ui_avatar(keynote_speaker, size: :lg, size_class: \"w-12 lg:w-28 xl:w-40\") %>\n            <% end %>\n\n            <% if event.keynote_speakers.none? %>\n              <% speakers_with_avatars.first(4).each do |speaker| %>\n                <% shown_speakers << speaker %>\n\n                <%= ui_avatar(speaker, size: :lg, size_class: \"w-12 lg:w-28 xl:w-40\") %>\n              <% end %>\n\n              <% if speakers_with_avatars.none? %>\n                <% event.participants.first(4).each do |participant| %>\n                  <% shown_speakers << participant %>\n\n                  <%= ui_avatar(participant, size: :lg, size_class: \"w-12 lg:w-28 xl:w-40\") %>\n                <% end %>\n              <% end %>\n            <% end %>\n          </div>\n        </div>\n\n        <div class=\"mt-12\">\n          <div class=\"avatar-group -space-x-6 lg:-space-x-3 rtl:space-x-reverse\">\n            <% remaining_speakers = speakers_with_avatars - shown_speakers %>\n            <% remaining_participants = event.participants - shown_speakers %>\n\n            <% if remaining_speakers.any? %>\n              <% remaining_speakers.first(10).each do |speaker| %>\n                <% shown_speakers << speaker %>\n\n                <%= ui_avatar(speaker) %>\n              <% end %>\n            <% elsif remaining_participants.any? %>\n              <% remaining_participants.first(10).each do |speaker| %>\n                <% shown_speakers << speaker %>\n\n                <%= ui_avatar(speaker) %>\n              <% end %>\n            <% end %>\n\n            <% more_speakers_count = all_speakers.count - shown_speakers.count %>\n\n            <% if more_speakers_count.positive? %>\n              <%= ui_avatar(nil, kind: :neutral) do %>\n                <span>+<%= more_speakers_count %></span>\n              <% end %>\n            <% end %>\n          </div>\n        </div>\n      </div>\n\n    </div>\n  </a>\n</div>\n"
  },
  {
    "path": "app/views/events/_featured_card.html.erb",
    "content": "<div\n  data-event-list-target=\"poster\" data-event-id=\"<%= event.slug %>\"\n  class=\"hidden w-full lg:h-92 p-4 lg:p-16 border rounded-[25px] lg:rounded-[50px] text-center lg:text-left\"\n  style=\"\n    color: <%= event.static_metadata.featured_color %>;\n    <% if event.static_metadata.featured_background.start_with?(\"data:\") %>\n      background: url('<%= event.static_metadata.featured_background %>');\n      background-repeat: no-repeat;\n      background-size: cover;\n    <% else %>\n      background: <%= event.static_metadata.featured_background %>;\n    <% end %>\n  \">\n  <a href=\"<%= event_path(event) %>\">\n    <div class=\"grid-cols-[1fr_2fr]\">\n      <div>\n        <div class=\"flex justify-center mb-9\">\n          <%= image_tag event.featured_image_path, class: \"w-[200px] max-h-none lg:w-full\", loading: \"lazy\", width: 615, height: 350, alt: event.name %>\n        </div>\n\n        <div class=\"flex flex-col gap-3 lg:h-48 lg:max-h-48 overflow-hidden items-center lg:items-start\">\n          <h1 class=\"text-inherit font-bold text-xl line-clamp-1 lg:line-clamp-2\"><%= event.name %></h1>\n          <h2 class=\"text-inherit opacity-60 text-sm line-clamp-1\"><%= event.to_location.to_html(show_links: false) %> • <%= event.formatted_dates %></h2>\n          <h2 class=\"text-inherit font-medium text-sm line-clamp-3 hidden lg:block\">\n            <%= event.description %>\n            <%= home_updated_text(event) %>\n          </h2>\n        </div>\n      </div>\n    </div>\n  </a>\n</div>\n"
  },
  {
    "path": "app/views/events/_featured_card_list.html.erb",
    "content": "<div class=\"block gap-8 mt-6 overflow-scroll md:grid xl:grid-cols-2\" data-controller=\"event-list\">\n  <%= render partial: \"events/event_list\", locals: {events: events} %>\n\n  <div class=\"hidden md:block\">\n    <% events.each do |event| %>\n      <%= render partial: \"events/featured_card\", locals: {event: event} %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/events/_featured_home.html.erb",
    "content": "<%# locals: (event:) %>\n\n<div\n  class=\"w-full pt-4 lg:pt-6 pb-4 lg:pb-12 lg:min-h-[600px]\"\n  style=\"\n    color: <%= event.static_metadata.featured_color %>;\n    <% if event.static_metadata.featured_background.start_with?(\"data:\") %>\n      background: url('<%= event.static_metadata.featured_background %>');\n      background-repeat: no-repeat;\n      background-size: cover;\n    <% else %>\n      background: <%= event.static_metadata.featured_background %>;\n    <% end %>\n  \">\n  <a href=\"<%= event_path(event) %>\" class=\"block h-full\">\n    <div class=\"container h-full\">\n      <div class=\"grid grid-cols-1 lg:grid-cols-[1fr_2fr] gap-6 lg:gap-12 items-center h-full\">\n        <div class=\"flex flex-col gap-4\">\n          <div class=\"flex justify-center lg:justify-start mb-4\">\n            <%= image_tag event.featured_image_path, class: \"w-1/2 lg:w-full\", loading: \"lazy\", alt: event.name %>\n          </div>\n\n          <div class=\"flex flex-col gap-3 text-center lg:text-left\">\n            <h1 class=\"text-inherit font-bold text-xl line-clamp-1 lg:line-clamp-2\"><%= event.name %></h1>\n            <h2 class=\"text-inherit opacity-60 text-sm line-clamp-1\"><%= event.to_location.to_html(show_links: false) %> • <%= event.formatted_dates %></h2>\n            <h2 class=\"text-inherit font-medium text-sm line-clamp-3 hidden lg:block\">\n              <%= event.description %>\n            </h2>\n          </div>\n\n          <%= ui_button kind: :rounded, class: \"btn-sm lg:btn-md mx-auto lg:mx-0 mt-4\" do %>\n            <span><%= (event.talks_count > 0) ? \"Explore #{pluralize(event.talks_count, \"Talk\")}\" : \"Explore Event\" %></span>\n          <% end %>\n        </div>\n\n        <div class=\"hidden lg:flex flex-col justify-end items-end gap-6\">\n          <div class=\"flex flex-col gap-6 items-center px-12\">\n            <div class=\"avatar-group -space-x-6 rtl:space-x-reverse\">\n              <% shown_speakers = [] %>\n              <% all_speakers = event.speakers.to_a %>\n              <% speakers_with_avatars = all_speakers.select { |speaker| speaker.avatar_url.present? }.sort_by(&:avatar_rank) %>\n\n              <% event.keynote_speakers.each do |keynote_speaker| %>\n                <% shown_speakers << keynote_speaker %>\n                <%= ui_avatar(keynote_speaker, size: :lg, size_class: \"w-12 lg:w-28 xl:w-40\") %>\n              <% end %>\n\n              <% if event.keynote_speakers.none? %>\n                <% speakers_with_avatars.first(4).each do |speaker| %>\n                  <% shown_speakers << speaker %>\n                  <%= ui_avatar(speaker, size: :lg, size_class: \"w-12 lg:w-28 xl:w-40\") %>\n                <% end %>\n\n                <% if speakers_with_avatars.none? %>\n                  <% event.participants.first(4).each do |participant| %>\n                    <% shown_speakers << participant %>\n                    <%= ui_avatar(participant, size: :lg, size_class: \"w-12 lg:w-28 xl:w-40\") %>\n                  <% end %>\n                <% end %>\n              <% end %>\n            </div>\n\n            <div class=\"avatar-group -space-x-6 lg:-space-x-3 rtl:space-x-reverse\">\n              <% remaining_speakers = speakers_with_avatars - shown_speakers %>\n              <% remaining_participants = event.participants - shown_speakers %>\n\n              <% if remaining_speakers.any? %>\n                <% remaining_speakers.first(10).each do |speaker| %>\n                  <% shown_speakers << speaker %>\n                  <%= ui_avatar(speaker) %>\n                <% end %>\n              <% elsif remaining_participants.any? %>\n                <% remaining_participants.first(10).each do |speaker| %>\n                  <% shown_speakers << speaker %>\n                  <%= ui_avatar(speaker) %>\n                <% end %>\n              <% end %>\n\n              <% more_speakers_count = all_speakers.count - shown_speakers.count %>\n\n              <% if more_speakers_count.positive? %>\n                <%= ui_avatar(nil, kind: :neutral) do %>\n                  <span>+<%= more_speakers_count %></span>\n                <% end %>\n              <% end %>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </a>\n</div>\n"
  },
  {
    "path": "app/views/events/_form.html.erb",
    "content": "<%= form_with(model: event, class: \"contents\") do |form| %>\n  <% if event.errors.any? %>\n    <div id=\"error_explanation\" class=\"bg-red-50 text-red-500 px-3 py-2 font-medium rounded-lg mt-3\">\n      <h2><%= pluralize(event.errors.count, \"error\") %> prohibited this event from being saved:</h2>\n\n      <ul>\n        <% event.errors.each do |error| %>\n          <li><%= error.full_message %></li>\n        <% end %>\n      </ul>\n    </div>\n  <% end %>\n\n  <div class=\"my-5\">\n    <%= form.label :name %>\n    <%= form.text_field :name, class: \"input input-bordered w-full\" %>\n  </div>\n\n  <div class=\"my-5\">\n    <%= form.label :description %>\n    <%= form.text_area :description, rows: 4, class: \"textarea textarea-bordered w-full\" %>\n  </div>\n\n  <div class=\"my-5\">\n    <%= form.label :website %>\n    <%= form.text_field :website, class: \"input input-bordered w-full\" %>\n  </div>\n\n  <div class=\"inline\">\n    <%= ui_button \"Suggest modifications\", type: :submit %>\n    <%= ui_button \"Cancel\", url: event_path(event), outline: true, role: :button %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/_header.html.erb",
    "content": "<%# locals: (event:, participation: nil) %>\n<div\n  class=\"w-full md:h-[198px] lg:h-[267px] xl:h-[336px] 2xl:h-[405px] justify-center align-center flex mt-3 border-t border-b hotwire-native:hidden\"\n  style=\"\n    view-transition-name: hero;\n    <% if event.static_metadata.banner_background.start_with?(\"data:\") %>\n      background: url('<%= event.static_metadata.banner_background %>');\n      background-repeat: no-repeat;\n      background-size: cover;\n    <% else %>\n      background: <%= event.static_metadata.banner_background %>;\n    <% end %>\n  \">\n  <%= image_tag image_path(event.banner_image_path), class: \"w-full md:container\" %>\n</div>\n\n<div class=\"container py-8\">\n  <div class=\"block lg:flex gap-8 align-center justify-between\">\n    <div class=\"flex flex-col lg:flex-row gap-8 items-center lg:justify-right text-center lg:text-left mb-6 lg:mb-0\">\n      <%= image_tag image_path(event.avatar_image_path),\n            class: \"rounded-full border border-[#D9DFE3] size-24 md:size-36\",\n            alt: event.name.to_s,\n            style: \"view-transition-name: #{dom_id(event, :logo)}\",\n            loading: :lazy %>\n\n      <div class=\"flex-col flex justify-center\">\n        <h1 class=\"mb-2 text-black font-bold\"><%= title event.name %></h1>\n        <h3 class=\"text-[#636B74]\">\n          <%= event.to_location.to_html %>\n          • <%= event.formatted_dates %>\n        </h3>\n        <%= external_link_to event.website.gsub(%r{^https?://}, \"\").gsub(%r{/$}, \"\"), event.website, class: \"break-all\" %>\n      </div>\n    </div>\n\n    <div class=\"flex flex-col gap-2\">\n      <%= ui_button \"View all #{event.series.name} events\", url: series_path(event.series), kind: :secondary, size: :sm, class: \"w-full\" %>\n      <%= render \"events/participation_button\", event: event, participation: participation %>\n      <%= render Tito::ButtonComponent.new(event: event) %>\n\n      <% if Current.user&.admin? %>\n        <div class=\"flex items-center gap-2 mt-4 pt-4 border-t border-gray-200\">\n          <span class=\"text-xs text-gray-400 uppercase tracking-wide\">Admin</span>\n          <%= ui_tooltip \"Reimport Event\" do %>\n            <%= ui_button url: reimport_event_path(event), method: :post, kind: :neutral, size: :sm do %>\n              <%= fa \"download\", size: :sm %>\n            <% end %>\n          <% end %>\n          <%= ui_tooltip \"Reindex Event\" do %>\n            <%= ui_button url: reindex_event_path(event), method: :post, kind: :neutral, size: :sm do %>\n              <%= fa \"arrows-rotate\", size: :sm %>\n            <% end %>\n          <% end %>\n          <%= ui_tooltip \"Open in Avo\" do %>\n            <%= ui_button url: avo.resources_event_path(event), target: :_blank, kind: :neutral, size: :sm do %>\n              <%= fa :avocado, size: :sm %>\n            <% end %>\n          <% end %>\n        </div>\n      <% end %>\n    </div>\n  </div>\n\n  <p class=\"mt-6 text-[#636B74] max-w-[700px]\">\n    <%= event.description %>\n  </p>\n\n  <% event.cfps.each do |cfp| %>\n    <% if event.start_date && event.start_date > Date.today %>\n      <div class=\"mt-6 p-4 bg-gray-100 rounded-lg max-w-[700px]\">\n        <h3 class=\"font-bold text-lg mb-2\"><%= cfp.name.presence || \"Call for Proposals\" %></h3>\n\n        <p class=\"text-[#636B74] mb-3\">\n          <% if cfp.future? %>\n            The CFP opens on <%= cfp.formatted_open_date %><% if cfp.close_date.present? %> and closes on <%= cfp.formatted_close_date %><% end %>.\n          <% elsif cfp.open? %>\n            The CFP is currently open and closes on <%= cfp.formatted_close_date %>.\n          <% elsif cfp.closed? %>\n            The CFP closed on <%= cfp.formatted_close_date %>.\n          <% else %>\n            Call for Proposals information is available.\n          <% end %>\n        </p>\n\n        <% if cfp.close_date.blank? || cfp.open? %>\n          <%= external_link_to \"Submit your proposal\", cfp.link, class: \"btn btn-primary btn-sm\" %>\n        <% else %>\n          <%= external_link_to \"View CFP details\", cfp.link, class: \"btn btn-secondary btn-sm\" %>\n        <% end %>\n      </div>\n    <% end %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/_my_attendance.html.erb",
    "content": "<%# locals: (event:, days:, tracks:, talks:, in_person_talk_ids:, online_talk_ids:, feedback_talk_ids:) %>\n\n<% total_talks = talks.size %>\n<% attended_count = in_person_talk_ids.size %>\n<% has_schedule = days.present? && days.any? %>\n\n<section id=\"my-attendance\" class=\"bg-white rounded-lg border p-4 shadow-sm\">\n  <div class=\"flex items-center justify-between mb-3\">\n    <div>\n      <h2 class=\"text-lg font-bold text-primary\">My Attendance</h2>\n      <p class=\"text-xs text-gray-500\">Tap talks you attended in person</p>\n    </div>\n    <div id=\"attendance-counter\" class=\"text-right\">\n      <div class=\"text-xl font-bold text-primary\"><%= attended_count %>/<%= total_talks %></div>\n      <div class=\"text-xs text-gray-500\">in-person</div>\n    </div>\n  </div>\n\n  <div id=\"attendance-schedule\">\n    <% if has_schedule %>\n      <% if days.size > 1 %>\n        <div id=\"attendance-navigation\" class=\"flex gap-1 justify-center flex-wrap mb-2\">\n          <% days.each_with_index do |day, index| %>\n            <% date_string = Date.parse(day.dig(\"date\")).strftime(\"%a %d\") %>\n            <a href=\"#attendance-day-<%= index %>\" class=\"btn btn-xs btn-outline\">\n              <%= day.dig(\"name\") || date_string %>\n            </a>\n          <% end %>\n        </div>\n      <% end %>\n\n      <% talk_offset = 0 %>\n      <% days.each_with_index do |day, day_index| %>\n        <% day_talk_count = event.schedule.talk_offsets[day_index] %>\n        <% day_talks = talks.from(talk_offset).first(day_talk_count) %>\n\n        <%= render \"events/my_attendance_day\",\n              event: event,\n              day: day,\n              day_index: day_index,\n              tracks: tracks,\n              talks: day_talks,\n              in_person_talk_ids: in_person_talk_ids,\n              online_talk_ids: online_talk_ids,\n              feedback_talk_ids: feedback_talk_ids %>\n\n        <% talk_offset += day_talk_count %>\n      <% end %>\n    <% else %>\n      <div class=\"grid gap-2\">\n        <% talks.each do |talk| %>\n          <%= render \"events/my_attendance_talk\",\n                talk: talk,\n                track: nil,\n                attended_in_person: in_person_talk_ids.include?(talk.id),\n                watched_online: online_talk_ids.include?(talk.id),\n                has_feedback: feedback_talk_ids.include?(talk.id) %>\n        <% end %>\n      </div>\n    <% end %>\n  </div>\n</section>\n"
  },
  {
    "path": "app/views/events/_my_attendance_day.html.erb",
    "content": "<%# locals: (event:, day:, day_index:, tracks:, talks:, in_person_talk_ids:, online_talk_ids:, feedback_talk_ids:) %>\n\n<% talk_count = 0 %>\n<% date_string = Date.parse(day.dig(\"date\")).strftime(\"%a %b %d\") %>\n<% day_string = day.dig(\"name\") ? \"#{day.dig(\"name\")} - #{date_string}\" : date_string %>\n<% unique_slot_counts = day.dig(\"grid\").map { |grid| grid[\"slots\"] }.uniq %>\n\n<div id=\"attendance-day-<%= day_index %>\" class=\"mt-4\">\n  <h3 class=\"mb-2 text-center font-semibold text-sm text-gray-700\"><%= day_string %></h3>\n\n  <style>\n    <% unique_slot_counts.each do |slot_count| %>\n      @media (min-width: 768px) {\n        #attendance-day-<%= day_index %> [data-slots=\"<%= slot_count %>\"] {\n          grid-template-columns: repeat(<%= slot_count %>, minmax(0, 1fr));\n        }\n      }\n    <% end %>\n  </style>\n\n  <div class=\"border rounded overflow-hidden divide-y\">\n    <% day.dig(\"grid\").each do |grid| %>\n      <% start_time = grid[\"start_time\"] %>\n      <% end_time = grid[\"end_time\"] %>\n      <% slots = grid[\"slots\"] %>\n      <% items = grid.fetch(\"items\", []) %>\n\n      <div class=\"flex flex-col md:flex-row\">\n        <div class=\"w-full md:w-14 shrink-0 bg-gray-50 text-xs p-1 md:p-1.5 text-gray-500 text-center flex items-center justify-center border-b md:border-b-0 md:border-r\">\n          <span class=\"md:hidden\"><%= start_time %><%= \" - #{end_time}\" if end_time %></span>\n          <span class=\"hidden md:inline\"><%= start_time %></span>\n        </div>\n\n        <div class=\"flex-1 grid grid-cols-1 md:divide-x\" data-slots=\"<%= slots %>\">\n          <% slots.times do |i| %>\n            <% talk = items.any? ? nil : talks[talk_count] %>\n\n            <% if items.any? %>\n              <% item = items[i] %>\n              <div class=\"bg-gray-50 text-gray-400 text-xs p-1.5 flex items-center justify-center border-b md:border-b-0 last:border-b-0\">\n                <%= item.is_a?(String) ? item : item&.fetch(\"title\", \"-\") %>\n              </div>\n            <% elsif talk %>\n              <% talk_track = talk.static_metadata&.track %>\n              <% track = talk_track && tracks.find { |t| t[\"name\"] == talk_track } %>\n\n              <div class=\"border-b md:border-b-0 last:border-b-0\">\n                <%= render \"events/my_attendance_talk\",\n                      talk: talk,\n                      track: track,\n                      attended_in_person: in_person_talk_ids.include?(talk.id),\n                      watched_online: online_talk_ids.include?(talk.id),\n                      has_feedback: feedback_talk_ids.include?(talk.id) %>\n              </div>\n\n              <% talk_count += 1 %>\n            <% else %>\n              <div class=\"bg-gray-50 text-gray-400 text-xs p-1.5 flex items-center justify-center border-b md:border-b-0 last:border-b-0\">-</div>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/events/_my_attendance_talk.html.erb",
    "content": "<%# locals: (talk:, track:, attended_in_person:, watched_online:, has_feedback:) %>\n<% bg_class, text_class = if attended_in_person\n     [\"bg-green-50\", \"text-green-800\"]\n   elsif watched_online\n     [\"bg-blue-50\", \"text-blue-800\"]\n   else\n     [\"bg-white\", \"text-gray-900\"]\n   end\n\n   in_person_confirm = if attended_in_person && has_feedback\n     \"Remove in-person attendance? Your feedback will be deleted.\"\n   elsif watched_online\n     \"Switch from watched online to attended in-person?\"\n   end\n\n   online_confirm = if watched_online && has_feedback\n     \"Remove watched online status? Your feedback will be deleted.\"\n   elsif attended_in_person\n     \"Switch from attended in-person to watched online?\"\n   end %>\n\n<%= turbo_frame_tag dom_id(talk, :attendance), style: \"display: contents\" do %>\n  <div class=\"flex items-center gap-1 p-1 <%= bg_class %>\">\n    <%= ui_tooltip attended_in_person ? \"Remove in-person attendance\" : \"Mark as attended in-person\" do %>\n      <%= button_to toggle_attendance_talk_watched_talk_path(talk),\n            method: :post,\n            class: \"shrink-0 p-1 rounded hover:bg-gray-100 transition-colors cursor-pointer\",\n            data: {turbo_frame: dom_id(talk, :attendance), turbo_confirm: in_person_confirm}.compact do %>\n        <% if attended_in_person %>\n          <%= fa(\"circle-check\", size: :sm, style: :solid, class: \"fill-green-600\") %>\n        <% else %>\n          <%= fa(\"circle\", size: :sm, style: :regular, class: \"text-gray-300 hover:text-green-500\") %>\n        <% end %>\n      <% end %>\n    <% end %>\n\n    <% if talk.video_provider.in?(Talk::WATCHABLE_PROVIDERS) %>\n      <%= ui_tooltip watched_online ? \"Remove watched online status\" : \"Mark as watched online\" do %>\n        <%= button_to toggle_online_talk_watched_talk_path(talk),\n              method: :post,\n              class: \"shrink-0 p-1 rounded hover:bg-gray-100 transition-colors cursor-pointer\",\n              data: {turbo_frame: dom_id(talk, :attendance), turbo_confirm: online_confirm}.compact do %>\n          <% if watched_online %>\n            <%= fa(\"video\", size: :sm, style: :solid, class: \"fill-blue-600\") %>\n          <% else %>\n            <%= fa(\"video\", size: :sm, style: :regular, class: \"text-gray-300 hover:text-blue-500\") %>\n          <% end %>\n        <% end %>\n      <% end %>\n    <% else %>\n      <%= ui_tooltip \"Recording not available\" do %>\n        <div class=\"shrink-0 p-1 rounded cursor-not-allowed opacity-40\">\n          <%= fa(\"video-slash\", size: :sm, style: :regular, class: \"text-gray-300\") %>\n        </div>\n      <% end %>\n    <% end %>\n\n    <div class=\"flex-1 min-w-0 px-1\">\n      <div class=\"text-xs font-medium <%= text_class %> truncate\">\n        <%= talk.title %>\n      </div>\n      <div class=\"text-xs text-gray-400 truncate\">\n        <%= talk.speakers.map(&:name).join(\", \") %>\n      </div>\n    </div>\n\n    <% if track %>\n      <span class=\"shrink-0 py-0.5 px-1.5 rounded text-[10px]\" style=\"background: <%= track[\"color\"] %>; color: <%= track[\"text_color\"] %>\">\n        <%= track[\"name\"] %>\n      </span>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/_navigation.html.erb",
    "content": "<div role=\"tablist\" class=\"mb-12 tabs tabs-bordered\">\n  <%= active_link_to \"Overview\", event_path(event), class: \"tab\", active_class: \"tab-active\", role: \"tab\" %>\n\n  <% if event.meetup? %>\n    <%= active_link_to \"Events\", event_events_path(event), class: \"tab\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if !event.retreat? || event.talks.any? %>\n    <%= active_link_to event_talks_path(event), class: class_names(\"tab\", {\"text-red-500\" => !event.talks.any?}), active_class: \"tab-active\", role: \"tab\" do %>\n      Talks\n      <% unless event.talks.any? %>\n        <%= fa(\"question-circle\", size: :xs, class: \"ml-1 fill-red-500\") %>\n      <% end %>\n    <% end %>\n  <% end %>\n\n  <% if event.meetup? %>\n    <%= active_link_to \"Videos\", event_videos_path(event), class: \"tab\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if event.speakers.any? %>\n    <%= active_link_to \"Speakers\", event_speakers_path(event), class: \"tab\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <%= active_link_to \"Participants\", event_participants_path(event), class: \"tab\", active_class: \"tab-active\", role: \"tab\" %>\n\n  <% if event.event_involvements.any? %>\n    <%= active_link_to \"Involvements\", event_involvements_path(event), class: \"tab\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if event.conference? || event.schedule.exist? %>\n    <%= active_link_to event_schedules_path(event), class: class_names(\"tab\", {\"text-red-500\" => !event.schedule.exist?}), active_class: \"tab-active\", role: \"tab\" do %>\n      Schedule\n      <% unless event.schedule.exist? %>\n        <%= fa(\"question-circle\", size: :xs, class: \"ml-1 fill-red-500\") %>\n      <% end %>\n    <% end %>\n  <% end %>\n\n  <% if event.conference? || event.venue.exist? %>\n    <%= active_link_to event_venue_path(event), class: class_names(\"tab\", {\"text-red-500\" => !event.venue.exist?}), active_class: \"tab-active\", role: \"tab\" do %>\n      Venue\n      <% unless event.venue.exist? %>\n        <%= fa(\"question-circle\", size: :xs, class: \"ml-1 fill-red-500\") %>\n      <% end %>\n    <% end %>\n  <% end %>\n\n  <% if event.conference? || event.sponsors.exists? %>\n    <%= active_link_to event_sponsors_path(event), class: class_names(\"tab\", {\"text-red-500\" => !event.sponsors.any?}), active_class: \"tab-active\", role: \"tab\" do %>\n      Sponsors\n      <% unless event.sponsors.any? %>\n        <%= fa(\"question-circle\", size: :xs, class: \"ml-1 fill-red-500\") %>\n      <% end %>\n    <% end %>\n  <% end %>\n\n  <% if event.conference? || event.cfps.any? %>\n    <%= active_link_to event_cfp_index_path(event), class: class_names(\"tab\", {\"text-red-500\" => event.cfps.none?}), active_class: \"tab-active\", role: \"tab\" do %>\n      <% if event.cfps.open.any? %>\n        CFP <span class=\"text-green-600 ml-1\"> (open)</span>\n      <% else %>\n        CFP\n      <% end %>\n      <% if event.cfps.none? %>\n        <%= fa(\"question-circle\", size: :xs, class: \"ml-1 fill-red-500\") %>\n      <% end %>\n    <% end %>\n  <% end %>\n\n  <% if event.tickets.available? %>\n    <%= active_link_to \"Tickets\", event_tickets_path(event), class: \"tab\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if event.stickers.any? || Stamp.for_event(event).any? %>\n    <%= active_link_to \"Collectibles\", event_collectibles_path(event), class: \"tab\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if event.todos.any? %>\n    <%= active_link_to \"TODOs\", event_todos_path(event), class: \"tab\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/_participation_button.html.erb",
    "content": "<% tooltip_text = event.start_date&.future? ? \"Add this event to your upcoming events\" : \"Add this event to your list of participations\" %>\n<% event_status = event.start_date&.future? ? \"upcoming\" : \"past\" %>\n\n<div class=\"participation_button mt-4\">\n  <% if Current.user %>\n    <% if participation&.attended_as_visitor? %>\n      <%= ui_tooltip \"Remove your participation to this event\" do %>\n        <%= ui_button url: event_event_participation_path(event, participation), params: {attended_as: \"visitor\"}, method: :delete, kind: :neutral, size: :sm, class: \"w-full\", data: {turbo_frame: \"modal\"} do %>\n          <%= fa(\"circle-check\", size: :xs, style: :solid, class: \"fill-green-700\") %>\n          <span class=\"text-nowrap\">\n            <%= t(\"event_participation.#{event_status}.attended_as.visitor\") %>\n          </span>\n        <% end %>\n      <% end %>\n    <% elsif participation %>\n      <%= ui_button kind: :neutral, size: :sm, class: \"w-full\", disabled: true do %>\n        <%= fa(\"circle-check\", size: :xs, style: :solid, class: \"fill-green-700\") %>\n        <span class=\"text-nowrap\">\n          <% case participation.attended_as %>\n          <% when \"keynote_speaker\" %>\n            <%= t(\"event_participation.#{event_status}.attended_as.keynote_speaker\") %>\n          <% when \"speaker\" %>\n            <%= t(\"event_participation.#{event_status}.attended_as.speaker\") %>\n          <% end %>\n        </span>\n      <% end %>\n\n    <% else %>\n      <%= ui_tooltip tooltip_text do %>\n        <%= ui_button url: event_event_participations_path(event), params: {attended_as: \"visitor\"}, method: :post, outline: true, size: :sm, kind: :neutral, class: \"w-full\", data: {turbo_frame: \"modal\"} do %>\n          <%= fa(\"plus\", style: :solid, size: :sm) %>\n          <span class=\"text-nowrap\">Add to My Events</span>\n        <% end %>\n      <% end %>\n    <% end %>\n\n    <% if defined?(errors) && errors&.any? %>\n      <div class=\"mt-2 text-sm text-red-600\">\n        <% errors.full_messages.each do |message| %>\n          <div><%= message %></div>\n        <% end %>\n      </div>\n    <% end %>\n\n    <% event_is_past = event.end_date.present? && event.end_date < Date.today %>\n\n    <% if participation.present? && event_is_past && event.talks.any? %>\n      <%= link_to attendance_path(event_slug: event.slug), class: \"btn btn-sm btn-outline w-full mt-2\" do %>\n        <%= fa(\"clipboard-check\", size: :sm) %>\n        <span class=\"text-nowrap\">Manage My Attendance</span>\n      <% end %>\n    <% end %>\n  <% else %>\n    <%= ui_tooltip tooltip_text do %>\n      <%= ui_button url: new_session_path(redirect_to: request.fullpath), outline: true, size: :sm, kind: :neutral, class: \"w-full\", data: {turbo_frame: \"modal\"} do %>\n        <%= fa(\"plus\", style: :solid) %>\n        <span class=\"text-nowrap\">Add to My Events</span>\n      <% end %>\n    <% end %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/_plain_list.html.erb",
    "content": "<div id=\"event-plain-list\" class=\"relative group rounded-xl flex flex-col gap-2\">\n  <% events.each do |event| %>\n    <%= link_to event, class: \"event-item flex gap-4 group p-2 hover:bg-gray-200 rounded-md\" do %>\n      <div class=\"flex flex-col lg:flex-row gap-8 items-center lg:justify-right text-center lg:text-left flex-shrink-0\">\n        <%= image_tag image_path(event.avatar_image_path),\n              class: \"rounded-xl border border-[#D9DFE3] size-16\",\n              alt: event.name.to_s,\n              style: \"view-transition-name: #{dom_id(event, :logo)}\",\n              loading: :lazy %>\n      </div>\n\n      <div class=\"flex-col flex justify-center relative overflow-hidden\">\n        <div class=\"text-black group-hover:text-inherit font-bold text-xl\"><%= event.name %></div>\n        <div class=\"text-[#636B74] group-hover:text-inherit\"><%= event.formatted_dates %> • <%= event.to_location.to_html(show_links: false) %></div>\n      </div>\n\n      <div class=\"absolute hidden gap-2 sm:flex right-2\">\n        <%= render \"shared/cfp_countdown_badge\", event: event %>\n        <%= render \"shared/event_countdown_badge\", event: event %>\n      </div>\n    <% end %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/archive/index.html.erb",
    "content": "<div class=\"container py-8 hotwire-native:mb-6\">\n  <div class=\"flex items-center justify-between w-full hotwire-native:hidden\">\n    <h1 class=\"title\">\n      <%= title \"Events Archive\" %>\n      <span class=\"text-base text-gray-500\">\n        (<%= pluralize(@events.includes(:series).where(series: {kind: \"conference\"}).count, \"conference\") %>,\n        <%= pluralize(@events.includes(:series).where(series: {kind: \"meetup\"}).count, \"meetup\") %>,\n        <%= pluralize(@events.includes(:series).where(series: {kind: \"hackathon\"}).count, \"hackathon\") %>,\n        <%= pluralize(@events.includes(:series).where(series: {kind: \"workshop\"}).count, \"workshop\") %>,\n        <%= pluralize(@events.includes(:series).where(series: {kind: \"retreat\"}).count, \"retreat\") %>)\n      </span>\n    </h1>\n\n    <div class=\"flex gap-4 whitespace-nowrap\">\n      <%= link_to \"Upcoming Events\", events_path, class: \"link text-right w-full\" %>\n      <%= link_to \"Past Events\", past_events_path, class: \"link text-right w-full\" %>\n    </div>\n  </div>\n\n  <div class=\"flex flex-wrap w-full justify-end py-2 hotwire-native:hidden gap-1\">\n    <div class=\"block md:flex items-center justify-between gap-2\">\n      <div class=\"tabs tabs-boxed mt-4 md:mt-0\">\n        <%= link_to \"All\", archive_events_path(kind: \"all\", letter: params[:letter]), class: \"tab #{\"tab-active\" if params[:kind].blank? || params[:kind] == \"all\"}\" %>\n        <%= link_to \"Conferences\", archive_events_path(kind: \"conference\", letter: params[:letter]), class: \"tab #{\"tab-active\" if params[:kind] == \"conference\"}\" %>\n        <%= link_to \"Meetups\", archive_events_path(kind: \"meetup\", letter: params[:letter]), class: \"tab #{\"tab-active\" if params[:kind] == \"meetup\"}\" %>\n      </div>\n    </div>\n  </div>\n\n  <div class=\"flex flex-wrap w-full justify-between py-8 hotwire-native:hidden gap-1\">\n    <%= link_to archive_events_path(kind: params[:kind]), class: class_names(\"flex items-center justify-center w-10 text-gray-500 rounded hover:bg-brand-lighter border\", \"bg-brand-lighter\": params[:letter].blank?) do %>\n      all\n    <% end %>\n\n    <% (\"a\"..\"z\").each do |letter| %>\n      <%= link_to archive_events_path(letter: letter, kind: params[:kind]), id: letter, class: class_names(\"flex items-center justify-center w-10 text-gray-500 rounded hover:bg-brand-lighter border\", \"bg-brand-lighter\": letter == params[:letter]) do %>\n        <%= letter.upcase %>\n      <% end %>\n    <% end %>\n  </div>\n\n  <% if params[:letter].present? %>\n    <div class=\"font-medium mb-12\">\n      Events starting with \"<%= params[:letter].upcase %>\"\n    </div>\n  <% end %>\n\n  <% if params[:s].present? %>\n    <div class=\"font-medium mb-12\">\n      search results for \"<%= params[:s] %>\"\n    </div>\n  <% end %>\n\n  <% if @events.any? %>\n    <% @events.group_by(&:series).each do |series, events| %>\n      <h2><%= link_to series.name, series_path(series) %></h2>\n      <div id=\"<%= dom_id(series, \"events\") %>\" class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-8 lg:gap-x-12 gap-y-2 min-w-full pt-4 pb-8\">\n        <%= render partial: \"events/event\", collection: events %>\n      </div>\n    <% end %>\n  <% else %>\n    <p>No events found</p>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/attendances/index.html.erb",
    "content": "<div class=\"container py-8\">\n  <div class=\"mb-8\">\n    <h1 class=\"text-3xl font-bold text-primary mb-2\">My Attendances</h1>\n    <p class=\"text-gray-600\">Track which talks you attended in-person at events you participated in.</p>\n  </div>\n\n  <% if @events.empty? %>\n    <div class=\"text-center py-12 bg-white rounded-lg border\">\n      <div class=\"text-6xl mb-4\">🎟️</div>\n      <h2 class=\"text-xl font-bold text-gray-900 mb-2\">No Past Events</h2>\n      <p class=\"text-gray-600 mb-6\">\n        You haven't participated in any past events yet. Mark your attendance at events to start tracking your conference history.\n      </p>\n      <%= link_to \"Browse Events\", events_path, class: \"btn btn-primary\" %>\n    </div>\n  <% else %>\n    <div class=\"space-y-8\">\n      <% @events_by_year.each do |year, events| %>\n        <section>\n          <h2 class=\"text-xl font-bold text-gray-700 mb-4 border-b pb-2\"><%= year %></h2>\n\n          <div class=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n            <% events.each do |event| %>\n              <% stats = @attendance_stats[event.id] || {in_person: 0, online: 0} %>\n              <% total_talks = event.talks.count %>\n              <% watched_total = stats[:in_person] + stats[:online] %>\n              <% unwatched = [total_talks - watched_total, 0].max %>\n\n              <div class=\"bg-white rounded-lg border shadow-sm overflow-hidden hover:shadow-md transition-shadow\">\n                <div class=\"h-24 flex items-center justify-center overflow-hidden\" style=\"<% if event.static_metadata.banner_background.start_with?('data:') %>background: url('<%= event.static_metadata.banner_background %>'); background-repeat: no-repeat; background-size: cover;<% else %>background: <%= event.static_metadata.banner_background %>;<% end %>\">\n                  <%= image_tag image_path(event.banner_image_path), class: \"h-full w-full object-cover\" %>\n                </div>\n\n                <div class=\"p-4\">\n                  <h3 class=\"font-bold text-lg mb-1\">\n                    <%= link_to event.name, event_path(event), class: \"hover:text-primary\" %>\n                  </h3>\n                  <p class=\"text-sm text-gray-500 mb-3\">\n                    <%= event.formatted_dates %>\n                  </p>\n\n                  <div class=\"flex items-center gap-4 text-sm mb-4\">\n                    <div class=\"flex items-center gap-1\">\n                      <%= fa(\"user-check\", size: :sm, class: \"fill-green-600\") %>\n                      <span class=\"text-green-700 font-medium\"><%= stats[:in_person] %></span>\n                      <span class=\"text-gray-500\">in-person</span>\n                    </div>\n                    <div class=\"flex items-center gap-1\">\n                      <%= fa(\"video\", size: :sm, class: \"fill-blue-600\") %>\n                      <span class=\"text-blue-700 font-medium\"><%= stats[:online] %></span>\n                      <span class=\"text-gray-500\">online</span>\n                    </div>\n                    <div class=\"flex items-center gap-1\">\n                      <%= fa(\"circle\", size: :sm, style: :regular, class: \"text-gray-400\") %>\n                      <span class=\"text-gray-500\"><%= unwatched %></span>\n                      <span class=\"text-gray-400\">left</span>\n                    </div>\n                  </div>\n\n                  <% if total_talks > 0 %>\n                    <div class=\"w-full bg-gray-200 rounded-full h-2 mb-3\">\n                      <% in_person_percent = (stats[:in_person].to_f / total_talks * 100).round %>\n                      <% online_percent = (stats[:online].to_f / total_talks * 100).round %>\n                      <div class=\"flex h-2 rounded-full overflow-hidden\">\n                        <div class=\"bg-green-500\" style=\"width: <%= in_person_percent %>%\"></div>\n                        <div class=\"bg-blue-500\" style=\"width: <%= online_percent %>%\"></div>\n                      </div>\n                    </div>\n                  <% end %>\n\n                  <% if event.talks.any? %>\n                    <%= link_to attendance_path(event_slug: event.slug), class: \"btn btn-sm btn-outline w-full\" do %>\n                      <%= fa(\"pen-to-square\", size: :sm) %>\n                      Manage Attendance\n                    <% end %>\n                  <% else %>\n                    <div class=\"text-xs text-gray-400 text-center py-2\">\n                      No talks available\n                    </div>\n                  <% end %>\n                </div>\n              </div>\n            <% end %>\n          </div>\n        </section>\n      <% end %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/attendances/show.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event, participation: @participation} %>\n\n<div class=\"container py-8\">\n  <div class=\"mb-6\">\n    <%= link_to attendances_path, class: \"link text-sm inline-flex items-center gap-1\" do %>\n      <%= fa(\"arrow-left\", size: :xs) %>\n      <span>Back to My Attendances</span>\n    <% end %>\n  </div>\n\n  <%= render \"events/my_attendance\",\n        event: @event,\n        days: @attendance_days,\n        tracks: @attendance_tracks,\n        talks: @attendance_talks,\n        in_person_talk_ids: @user_in_person_talk_ids,\n        online_talk_ids: @user_online_talk_ids,\n        feedback_talk_ids: @user_feedback_talk_ids %>\n</div>\n"
  },
  {
    "path": "app/views/events/cfp/index.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <div class=\"flex flex-col gap-8 mt-8\">\n      <% if @event.cfps.any? %>\n        <% @event.cfps.each do |cfp| %>\n          <section class=\"bg-white rounded-lg border p-8\">\n            <div class=\"flex items-center gap-4 mb-6\">\n              <div class=\"text-3xl leading-none\">📝</div>\n              <div class=\"flex-1\">\n                <div class=\"flex items-center gap-3 flex-wrap\">\n                  <h2 class=\"text-2xl font-bold text-gray-900\">\n                    <% if cfp.name.present? %>\n                      <%= cfp.name %>\n                    <% else %>\n                      Call for Proposals\n                    <% end %>\n                  </h2>\n                  <% if cfp.open? && cfp.open_ended? %>\n                    <span class=\"inline-block px-3 py-1 text-sm font-medium bg-green-100 text-green-800 rounded-full\">\n                      Always Open\n                    </span>\n                  <% elsif cfp.open? %>\n                    <span class=\"inline-block px-3 py-1 text-sm font-medium bg-green-100 text-green-800 rounded-full\">\n                      Open\n                    </span>\n                  <% elsif cfp.future? %>\n                    <span class=\"inline-block px-3 py-1 text-sm font-medium bg-blue-100 text-blue-800 rounded-full\">\n                      Upcoming\n                    </span>\n                  <% elsif cfp.closed? %>\n                    <span class=\"inline-block px-3 py-1 text-sm font-medium bg-gray-100 text-gray-800 rounded-full\">\n                      Closed\n                    </span>\n                  <% end %>\n                </div>\n              </div>\n            </div>\n\n            <div class=\"grid gap-6 md:grid-cols-2\">\n              <% if cfp.open_date.present? %>\n                <div class=\"flex flex-col\">\n                  <h3 class=\"font-semibold text-gray-700 mb-2\">CFP Opens</h3>\n                  <div class=\"text-lg text-primary\">\n                    <%= cfp.formatted_open_date %>\n                  </div>\n                  <% if cfp.future? && cfp.days_until_open %>\n                    <div class=\"text-sm text-blue-600 mt-1\">\n                      Opens in <%= pluralize(cfp.days_until_open, \"day\") %>\n                    </div>\n                  <% end %>\n                </div>\n              <% end %>\n\n              <% if cfp.close_date.present? %>\n                <div class=\"flex flex-col\">\n                  <h3 class=\"font-semibold text-gray-700 mb-2\">CFP Closes</h3>\n                  <div class=\"text-lg text-primary\">\n                    <%= cfp.formatted_close_date %>\n                  </div>\n                  <% if cfp.open? && cfp.days_remaining %>\n                    <div class=\"text-sm text-green-600 mt-1\">\n                      <%= pluralize(cfp.days_remaining, \"day\") %> remaining\n                    </div>\n                  <% elsif cfp.closed? && cfp.days_since_close %>\n                    <div class=\"text-sm text-gray-600 mt-1\">\n                      Closed <%= pluralize(cfp.days_since_close, \"day\") %> ago\n                    </div>\n                  <% end %>\n                </div>\n              <% elsif cfp.open_ended? %>\n                <div class=\"flex flex-col\">\n                  <h3 class=\"font-semibold text-gray-700 mb-2\">CFP Closes</h3>\n                  <div class=\"text-lg text-green-600\">\n                    No deadline\n                  </div>\n                  <div class=\"text-sm text-gray-600 mt-1\">\n                    Proposals are accepted on a rolling basis\n                  </div>\n                </div>\n              <% end %>\n            </div>\n\n            <% if cfp.link.present? %>\n              <div class=\"mt-8\">\n                <% if cfp.open? %>\n                  <%= link_to \"Submit Your Talk Proposal\",\n                        cfp.link,\n                        class: \"inline-flex items-center px-6 py-3 bg-primary text-white font-semibold rounded-lg hover:bg-primary-dark transition-colors duration-200\",\n                        target: \"_blank\",\n                        rel: \"noopener\" %>\n                <% else %>\n                  <%= link_to \"See CFP Details\",\n                        cfp.link,\n                        class: \"inline-flex items-center px-6 py-3 bg-gray-600 text-white font-semibold rounded-lg hover:bg-gray-700 transition-colors duration-200\",\n                        target: \"_blank\",\n                        rel: \"noopener\" %>\n                <% end %>\n              </div>\n            <% end %>\n          </section>\n        <% end %>\n      <% else %>\n        <div class=\"text-center py-12\">\n          <div class=\"max-w-md mx-auto\">\n            <div class=\"text-6xl mb-4\">📝</div>\n            <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No CFP Information</h2>\n            <p class=\"text-gray-600 mb-6\">\n              We don't have Call for Proposals information for <%= @event.name %> yet.\n            </p>\n            <div class=\"bg-amber-50 border border-amber-200 rounded-lg p-4 text-left\">\n              <h3 class=\"font-semibold text-amber-800 mb-2\">How to contribute:</h3>\n              <ul class=\"text-sm text-amber-700 space-y-1\">\n                <li>• Check the event website for CFP details</li>\n                <li>• Look for CFP announcements on social media</li>\n                <li>• <a href=\"https://github.com/rubyevents/rubyevents/issues/new?title=<%= CGI.escape(\"#{@event.name} CFP Information\") %>&body=<%= CGI.escape(\"<!-- CFP Details Here -->\\n\\nIssue opened from event page: #{event_url(@event)}\") %>\" class=\"underline hover:text-amber-900\" target=\"_blank\">Open an issue on GitHub</a> to report CFP details</li>\n                <li>• <a href=\"https://github.com/rubyevents/rubyevents/blob/main/CONTRIBUTING.md\" class=\"underline hover:text-amber-900\" target=\"_blank\">Submit CFP data via GitHub</a></li>\n              </ul>\n            </div>\n          </div>\n        </div>\n      <% end %>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/collectibles/index.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event, participation: nil} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <div class=\"flex flex-col gap-12 mt-8\">\n      <% if @stamps.any? %>\n        <section class=\"bg-white rounded-lg border p-6 shadow-sm\">\n          <div class=\"mb-6\">\n            <h2 class=\"text-2xl font-bold text-gray-900 mb-2\">Stamps</h2>\n            <p class=\"text-gray-600\">\n              Collect stamps by attending <%= @event.name %>.\n            </p>\n          </div>\n\n          <%= render partial: \"shared/stamps_grid\", locals: {stamps: @stamps, min_rows: 1} %>\n        </section>\n      <% end %>\n\n      <% if @stickers.any? %>\n        <section class=\"bg-gradient-to-b from-gray-400 via-gray-500 to-gray-600 rounded-lg border border-gray-300 p-6 shadow-sm\">\n          <div class=\"mb-6\">\n            <h2 class=\"text-2xl font-bold text-white mb-2\">Stickers</h2>\n            <p class=\"text-gray-200\">\n              Available stickers for <%= @event.name %>.\n            </p>\n          </div>\n\n          <div class=\"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4\">\n            <% @stickers.each do |sticker| %>\n              <div class=\"group relative bg-white/10 backdrop-blur-sm rounded-lg p-4 hover:bg-white/20 transition-colors border border-white/20\">\n                <div class=\"aspect-square flex items-center justify-center mb-2\">\n                  <%= image_tag sticker.asset_path, class: \"max-w-full max-h-full object-contain group-hover:scale-110 transition-transform\" %>\n                </div>\n                <p class=\"text-xs text-white text-center truncate\"><%= sticker.name %></p>\n              </div>\n            <% end %>\n          </div>\n        </section>\n      <% end %>\n\n      <% if @stamps.empty? && @stickers.empty? %>\n        <div class=\"text-center py-12\">\n          <div class=\"max-w-md mx-auto\">\n            <div class=\"text-6xl mb-4\">🎨</div>\n            <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No Collectibles Yet</h2>\n            <p class=\"text-gray-600 mb-6\">\n              There are no stamps or stickers available for <%= @event.name %> yet.\n            </p>\n          </div>\n        </div>\n      <% end %>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/edit.html.erb",
    "content": "<div class=\"mx-auto md:w-2/3 w-full\">\n  <h1 class=\"font-bold text-4xl\">Editing event</h1>\n\n  <%= render \"form\", event: @event %>\n</div>\n"
  },
  {
    "path": "app/views/events/events/index.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <div class=\"w-full\">\n      <div class=\"w-full flex flex-col gap-8\" role=\"tablist\" aria-orientation=\"vertical\">\n        <% @event.talks_in_running_order.where(meta_talk: true).reverse.each do |talk| %>\n          <%= render \"shared/meta_talk_card\", meta_talk: talk %>\n        <% end %>\n\n        <% if @talks.empty? %>\n          <div class=\"flex justify-center border rounded\" style=\"padding-top: 3rem; padding-bottom: 3rem; padding-right: 1rem; padding-left: 1rem\">\n            <div class=\"text-center text-gray-600\">\n              <p>\n                <b>No events found for this meetup.</b>\n              </p>\n              <p class=\"mt-2\">\n                Feel free to contribute events and talks to this meetup if you know how to access the details.\n              </p>\n            </div>\n          </div>\n        <% end %>\n      </div>\n    </div>\n\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/events/show.html.erb",
    "content": "<main class=\"container\">\n  <div class=\"flex w-full flex-col overflow-hidden bg-[#333333] md:min-h-[calc(100dvh-80px)] rounded-xl\" style=\"transform-origin: 0% 0%; transform: none;\">\n    <div class=\"relative bg-[#333333] text-[--featured-color]\" style=\"--featured-color: <%= @talk.event.static_metadata.featured_color %>;\">\n      <div class=\"relative md:h-[calc(100dvh-170px)] w-full md:aspect-video md:h-inherit\">\n        <div class=\"relative flex h-[calc(50dvh-170px)] md:h-[calc(100dvh-170px)] flex-col items-end justify-end pb-1 md:h-inherit\">\n          <div class=\"inset-x-0 bottom-44 z-20 flex w-full flex-col justify-between md:bottom-0 md:flex-row md:items-end md:p-10\">\n            <div class=\"w-full flex-col md:w-1/2 md:max-w-[80%]\">\n              <div class=\"flex justify-center gap-2 pb-4 md:justify-between\">\n                <div class=\"md:flex items-center gap-3 md:gap-2\">\n                  <div class=\"flex flex-wrap gap-2\">\n                    <div class=\"w-fit rounded bg-white/20 p-1 font-mono text-inherit text-sm-uppercases uppercase leading-[100%] backdrop-blur-md md:text-2xs-uppercases\">\n                      <div><%= @talk.formatted_kind %></div>\n                    </div>\n                  </div>\n                </div>\n                <div class=\"hidden font-mono text-inherit text-sm-text-regular uppercase backdrop-blur-none md:flex\">\n                  <div><%= @talk.date.strftime(\"%A, %b %d, %Y\") %></div>\n                </div>\n                <div class=\"hidden font-mono text-sm-text-regular uppercase backdrop-blur-none md:flex\">\n                  <div>from xx:xx</div>\n                </div>\n              </div>\n              <h1 class=\"pb-3 text-inherit text-center text-4xl uppercase leading-[90%] md:-mb-5 md:-ml-1 md:pt-3 md:text-left md:text-9xl-heading\">\n                <span><%= @talk.title %></span>\n              </h1>\n            </div>\n            <div class=\"relative z-40 hidden w-[217px] flex-col gap-1 md:flex\">\n              <a target=\"_blank\" class=\"btn btn-secondary w-full font-mono text-sm-uppercases uppercase backdrop-blur-md md:text-xs-uppercases\" href=\"<%= event_path(@talk.event) %>\">\n                Sign up\n              </a>\n            </div>\n          </div>\n          <div\n            class=\"absolute inset-0 z-0 h-full w-full bg-[--featured-background] text-[--featured-color]\"\n            style=\"--featured-background: <%= @talk.event.static_metadata.featured_background %>; --featured-color: <%= @talk.event.static_metadata.featured_color %>; transform-origin: 0% 0%; transform: none; opacity: 1;\">\n            <div class=\"flex items-center justify-center relative aspect-image-mobile max-h-full w-full overflow-hidden sm:aspect-image-tablet md:aspect-image-desktop lg:aspect-image-desktop-lg xl:aspect-image-desktop-xl 2xl:aspect-image-desktop-2xl h-full \">\n              <%= image_tag @talk.event.featured_image_path, class: \"w-1/2\" %>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"z-40 w-full overflow-hidden bg-[#333333] py-12 text-white md:mx-auto md:pt-10\">\n        <div>\n          <div class=\"relative flex gap-0 px-5 pt-0 md:gap-[10%] md:px-10 flex-col-reverse md:flex-row-reverse md:justify-between\">\n            <div class=\"flex flex-col gap-3 \">\n              <p class=\"font-mono text-[#D9D9D9] text-[.625rem] uppercase\">Description</p>\n\n              <div class=\"relative group\" id=\"descToggle\">\n                <article id=\"descContent\" class=\"max-w-[788px] text-[1.5rem] text-[#D9D9D9] prose max-h-[450px] group-data-[expanded]:max-h-none overflow-y-hidden\">\n                  <%= simple_format auto_link(@talk.description, html: {target: \"_blank\", class: \"link\"}) %>\n                </article>\n                <div id=\"descExpandControls\" class=\"desc-expand-controls\">\n                  <div class=\"absolute bottom-0 left-0 w-full h-56 bg-gradient-to-t from-[#333333]/90 to-transparent group-data-[expanded]:hidden flex justify-center items-end pointer-events-none\"></div>\n                  <button type=\"button\" class=\"btn btn-sm btn-white shadow absolute bottom-4 left-1/2 -translate-x-1/2 group-data-[expanded]:hidden z-20\" onclick=\"descToggle.toggleAttribute('data-expanded')\">\n                    Show more\n                  </button>\n                  <button type=\"button\" class=\"btn btn-sm btn-white shadow absolute bottom-4 left-1/2 -translate-x-1/2 hidden group-data-[expanded]:flex z-20\" onclick=\"descToggle.toggleAttribute('data-expanded')\">\n                    Show less\n                  </button>\n                </div>\n              </div>\n            </div>\n\n            <div class=\"flex gap-7 md:flex-col\">\n              <div class=\"mb-10 flex flex-col md:mb-0\">\n                <p class=\"font-mono text-[#D9D9D9] text-[.625rem] uppercase\"><%= \"Speaker\".pluralize(@talk.speakers.count) %></p>\n\n                <div class=\"my-6\">\n                  <% @talk.speakers.each do |speaker| %>\n                    <div class=\"mb-2\">\n                      <div class=\"flex flex-wrap items-center gap-3\">\n                        <div class=\"flex items-center\">\n                          <%= link_to profile_path(speaker) do %>\n                            <div class=\"flex w-full items-center gap-2\">\n                              <h3 class=\"flex-nowrap text-left text-2xl uppercase text-light-grey-500 md:text-5xl-text-semibold\"><%= speaker.name %></h3>\n                            </div>\n                          <% end %>\n                        </div>\n                      </div>\n                    </div>\n                  <% end %>\n                </div>\n\n                <p class=\"mt-6 font-mono text-[#D9D9D9] text-[.625rem] uppercase\">Details</p>\n\n                <p class=\"mt-3\">\n                  Date:\n                  <% if @talk.date %>\n                    <%= @talk.formatted_date %>\n                  <% else %>\n                    unknown<% end %><br>\n\n                  <span class=\"text-gray-400\">\n                    Published:\n                    <% if @talk.published_at %>\n                      <%= @talk.published_at.strftime(\"%B %d, %Y\") %>\n                    <% elsif @talk.published? %>\n                      unknown\n                    <% else %>\n                      not published\n                    <% end %>\n                    <br>\n\n                    Announced:\n                    <% if @talk.announced_at %>\n                      <%= @talk.announced_at.strftime(\"%B %d, %Y\") %>\n                    <% else %>\n                      unknown\n                    <% end %>\n                  </span>\n                </p>\n              </div>\n            </div>\n          </div>\n\n          <% if @talk.child_talks.any? %>\n            <div class=\"mx-auto mt-5 px-5 md:my-16 md:px-10\">\n              <p class=\"mt-12 font-mono text-[#D9D9D9] text-[.625rem] uppercase\"><%= \"Talk\".pluralize(@talk.child_talks.count) %></p>\n\n              <div class=\"mt-3 flex flex-col gap-4 divide\">\n                <% @talk.child_talks.each do |talk| %>\n                  <%= link_to talk, class: \"flex justify-between p-2 gap-4 bg-[#131313] hover:opacity-85\" do %>\n                    <div class=\"flex gap-6\">\n                      <div class=\"min-w-[150px] w-[150px]\">\n                        <%= image_tag talk.thumbnail_lg, class: \"rounded\" %>\n                      </div>\n\n                      <div class=\"flex flex-col justify-center\">\n                        <div class=\"text-ellipsis line-clamp-1 overflow-hidden\"><%= talk.title %></div>\n                        <div class=\"text-[#d9d9d9]\"><%= talk.speakers.map(&:name).to_sentence %></div>\n                      </div>\n                    </div>\n\n                    <div class=\"flex items-center p-2\">\n                      <% talk.speakers.each do |speaker| %>\n                        <div class=\"flex items-center gap-1\">\n                          <div class=\"avatar placeholder\">\n                            <div class=\"w-14 h-14 rounded-full bg-primary text-neutral-content\">\n                              <% if speaker.custom_avatar? %>\n                                <%= image_tag speaker.avatar_url(size: 48) %>\n                              <% else %>\n                                <span class=\"text-md\"><%= speaker.name.split(\" \").map(&:first).join %></span>\n                              <% end %>\n                            </div>\n                          </div>\n                        </div>\n                      <% end %>\n                    </div>\n                  <% end %>\n                <% end %>\n              </div>\n            </div>\n          <% end %>\n        </div>\n      </div>\n    </div>\n  </div>\n</main>\n\n<script>\n  document.addEventListener('turbo:load', function() {\n    var content = document.getElementById('descContent');\n    var controls = document.getElementById('descExpandControls');\n    if (content && controls) {\n      if (content.scrollHeight <= 450) {\n        controls.style.display = 'none';\n      }\n    }\n  });\n</script>\n"
  },
  {
    "path": "app/views/events/index.html.erb",
    "content": "<div class=\"container py-8 hotwire-native:py-3\" data-controller=\"events-view-switcher\">\n  <div class=\"flex flex-col md:flex-row items-start md:items-center justify-between w-full gap-4 hotwire-native:hidden\">\n    <h1 class=\"title shrink-0\">\n      <%= title \"Upcoming Events\" %>\n    </h1>\n\n    <div class=\"flex flex-col md:flex-row items-start md:items-center gap-4\">\n      <div class=\"tabs tabs-boxed\">\n        <button type=\"button\" class=\"tab tab-active\" data-events-view-switcher-target=\"previewButton\" data-action=\"click->events-view-switcher#showPreview\">\n          Preview\n        </button>\n\n        <button type=\"button\" class=\"tab\" data-events-view-switcher-target=\"listButton\" data-action=\"click->events-view-switcher#showList\">\n          List\n        </button>\n\n        <%= link_to \"Calendar\", year_events_path(year: Date.today.year), class: \"tab\" %>\n      </div>\n\n      <div class=\"flex gap-4 whitespace-nowrap\">\n        <%= link_to \"Past Events\", past_events_path, class: \"link\" %>\n        <%= link_to \"Archive\", archive_events_path, class: \"link\" %>\n        <%= link_to \"Meetups\", meetups_events_path, class: \"link\" %>\n      </div>\n    </div>\n  </div>\n\n  <div data-events-view-switcher-target=\"previewView\">\n    <%= render partial: \"events/featured_card_list\", locals: {events: @events} %>\n  </div>\n\n  <div class=\"hidden mt-6\" data-events-view-switcher-target=\"listView\">\n    <%= render partial: \"events/plain_list\", locals: {events: @events} %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/events/involvements/_list.html.erb",
    "content": "<div id=\"involvements_list\">\n  <% if involvements_by_role.any? %>\n    <% involvements_by_role.each do |role, involvements| %>\n      <div class=\"mb-12\">\n        <h2 class=\"mb-6\"><%= role.pluralize(involvements.count) %></h2>\n        <div class=\"min-w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 h-full\">\n          <% involvements.each do |involvement| %>\n            <% if involvement.involvementable_type == \"User\" %>\n              <div class=\"border rounded-lg bg-white hover:bg-gray-200 transition-bg duration-300 ease-in-out\">\n                <%= render partial: \"users/card\", locals: {user: involvement.involvementable} %>\n              </div>\n            <% elsif involvement.involvementable_type == \"Organization\" %>\n              <div class=\"border rounded-lg bg-white hover:bg-gray-200 transition-bg duration-300 ease-in-out\">\n                <%= render partial: \"organizations/compact_card\", locals: {organization: involvement.involvementable, hide_event_count: true, turbo_frame: true} %>\n              </div>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n  <% else %>\n    <div class=\"text-center py-12\">\n      <div class=\"max-w-md mx-auto\">\n        <div class=\"text-6xl mb-4\">🤝</div>\n        <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No Involvements Yet</h2>\n        <p class=\"text-gray-600\">\n          Event involvements information is not available for <%= event.name %> yet.\n        </p>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/involvements/index.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event, participation: @participation} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n    <div class=\"flex items-start flex-wrap gap-8 sm:flex-nowrap w-full\">\n      <div class=\"w-full\">\n        <%= render partial: \"events/involvements/list\", locals: {event: @event, involvements_by_role: @involvements_by_role} %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/meetups/index.html.erb",
    "content": "<div class=\"container py-8 hotwire-native:py-3\" data-controller=\"events-view-switcher\">\n  <div class=\"flex flex-col md:flex-row items-start md:items-center justify-between w-full gap-4 hotwire-native:hidden\">\n    <h1 class=\"title shrink-0\">\n      <%= title \"Meetups\" %>\n      <span class=\"text-base text-gray-500\">\n        (<%= pluralize(Event.upcoming_meetups.count, \"upcoming meetup\") %>,\n        <%= pluralize(Event.past_meetups.count, \"past meetup\") %>)\n      </span>\n    </h1>\n\n    <div class=\"flex flex-col md:flex-row items-start md:items-center gap-4\">\n      <div class=\"tabs tabs-boxed\">\n        <button type=\"button\" class=\"tab tab-active\" data-events-view-switcher-target=\"previewButton\" data-action=\"click->events-view-switcher#showPreview\">\n          Preview\n        </button>\n\n        <button type=\"button\" class=\"tab\" data-events-view-switcher-target=\"listButton\" data-action=\"click->events-view-switcher#showList\">\n          List\n        </button>\n      </div>\n      <div class=\"flex gap-4 whitespace-nowrap\">\n        <%= link_to \"Upcoming Events\", events_path, class: \"link\" %>\n      </div>\n    </div>\n  </div>\n\n  <div data-events-view-switcher-target=\"previewView\">\n    <%= render partial: \"events/featured_card_list\", locals: {events: @meetups} %>\n  </div>\n\n  <div class=\"hidden mt-6\" data-events-view-switcher-target=\"listView\">\n    <%= render partial: \"events/plain_list\", locals: {events: @meetups} %>\n  </div>\n  <div class=\"bg-amber-50 border border-amber-200 rounded-lg p-4 mb-8 mt-6 hotwire-native:hidden\">\n    <div class=\"flex items-start\">\n      <%= fa(\"question-circle\", size: :sm, class: \"fill-amber-600 mt-0.5 mr-3 flex-shrink-0\") %>\n      <div>\n        <h3 class=\"font-semibold text-amber-800 mb-1\">Meetup data is incomplete</h3>\n        <p class=\"text-sm text-amber-700 mb-2\">\n          We are looking for more meetups to add to the database. If you know of a Ruby meetup that is not listed, please let us know by <%= link_to \"creating an issue\", \"https://github.com/rubyevents/rubyevents/issues/new\", class: \"link\", target: \"_blank\", rel: \"noopener\" %> or contributing the data.\n        </p>\n      <%= link_to \"Documentation on adding a meetup\", \"https://github.com/rubyevents/rubyevents/blob/main/docs/ADDING_MEETUPS.md\", class: \"text-sm font-medium text-amber-800 underline hover:text-amber-900\", target: \"_blank\", rel: \"noopener\" %>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/events/new.html.erb",
    "content": "<div class=\"mx-auto md:w-2/3 w-full\">\n  <h1 class=\"font-bold text-4xl\">New event</h1>\n\n  <%= render \"form\", event: @event %>\n\n  <%= link_to \"Back to events\", events_path, class: \"ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium\" %>\n</div>\n"
  },
  {
    "path": "app/views/events/participants/_list.html.erb",
    "content": "<%# locals: (event:, participants:, participation:, favorite_users:) %>\n\n<% button_text = event.start_date&.future? ? \"Are you going?\" : \"Were you there?\" %>\n\n<div id=\"participants_list\">\n  <% if participants.any? %>\n    <% if Current.user && participation.blank? %>\n      <div class=\"mb-6 border-2 border-dashed border-purple-300 rounded-lg bg-purple-50 p-4\">\n        <div class=\"flex items-center gap-4\">\n          <div class=\"text-3xl\">👋</div>\n          <div class=\"flex-1\">\n            <h3 class=\"text-base font-semibold text-gray-900\"><%= button_text %></h3>\n            <p class=\"text-sm text-gray-600\">Mark yourself as a participant!</p>\n          </div>\n          <div class=\"flex-shrink-0\">\n            <%= render partial: \"events/participation_button\", locals: {event: event, participation: participation} %>\n          </div>\n        </div>\n      </div>\n    <% end %>\n\n    <% participants.each do |key, participants| %>\n      <% unless participants.size.zero? %>\n        <h2 class=\"mb-6\"><%= \"#{key} (#{participants.size})\" %></h2>\n        <div id=\"<%= dom_id(event, key) %>\" class=\"mb-12 min-w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3 h-full\">\n          <% participants.each do |participant| %>\n            <div class=\"border rounded-lg bg-white hover:bg-gray-200 transition-bg duration-300 ease-in-out\">\n              <%= render partial: \"users/card\", locals: {user: participant, favorite_user: favorite_users[participant.id]} %>\n            </div>\n          <% end %>\n        </div>\n      <% end %>\n    <% end %>\n  <% end %>\n\n  <% if participants.empty? %>\n    <div class=\"text-center py-12\">\n      <div class=\"max-w-md mx-auto\">\n        <div class=\"text-6xl mb-4\">👥</div>\n        <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No Participants Yet</h2>\n        <p class=\"text-gray-600 mb-6\">\n          Be the first to mark yourself as a participant of <%= event.name %>!\n        </p>\n\n        <%= render partial: \"events/participation_button\", locals: {event: event, participation: participation} %>\n\n        <div class=\"bg-purple-50 border border-purple-200 rounded-lg p-4 text-left mt-6\">\n          <h3 class=\"font-semibold text-purple-800 mb-2\"><%= button_text %></h3>\n          <p class=\"text-sm text-purple-700 mb-3\">\n            Help build the community memory by marking your participation at this event.\n          </p>\n          <ul class=\"text-sm text-purple-700 space-y-1\">\n            <li>• Connect with fellow participants</li>\n            <li>• Share your experience with the community</li>\n            <li>• Build your conference history</li>\n          </ul>\n        </div>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/participants/index.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event, participation: @participation} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n    <div class=\"flex items-start flex-wrap gap-8 sm:flex-nowrap w-full\">\n      <div class=\"w-full\">\n        <%= render partial: \"events/participants/list\", locals: {event: @event, participants: @participants, participation: @participation, favorite_users: @favorite_users} %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/past/index.html.erb",
    "content": "<div class=\"container py-8 hotwire-native:py-3\">\n  <div class=\"flex items-center justify-between w-full hotwire-native:hidden\">\n    <h1 class=\"title shrink-0\">\n      <%= title \"Past Events\" %>\n    </h1>\n\n    <div class=\"flex gap-4 whitespace-nowrap\">\n      <%= link_to \"Upcoming Events\", events_path, class: \"link text-right w-full\" %>\n      <%= link_to \"Archive\", archive_events_path, class: \"link text-right w-full\" %>\n      <%= link_to \"#{Date.today.year} Calendar\", year_events_path(year: Date.today.year), class: \"link text-right w-full\" %>\n    </div>\n  </div>\n\n  <%= render partial: \"events/featured_card_list\", locals: {events: @events} %>\n</div>\n"
  },
  {
    "path": "app/views/events/related_talks/_list.html.erb",
    "content": "<%# locals: (talks:, active_talk:, user_watched_talks:) %>\n\n<div class=\"relative group border border-transparent hover:border-gray-200 rounded-xl\">\n  <div class=\"flex flex-col gap-2 lg:max-h-[390px] xl:max-h-[480px] 2xl:max-h-[625px] overflow-y-scroll\" data-controller=\"scroll-into-view talks-navigation\">\n    <%= render partial: \"talks/card_horizontal\",\n          collection: talks,\n          as: :talk,\n          locals: {compact: true,\n                   current_talk: active_talk,\n                   turbo_frame: \"talk\",\n                   user_watched_talks: user_watched_talks} %>\n  </div>\n  <div class=\"absolute bottom-0 left-0 w-full h-36 bg-gradient-to-t from-base-100 to-transparent pointer-events-none group-hover:hidden\"></div>\n</div>\n"
  },
  {
    "path": "app/views/events/related_talks/index.html.erb",
    "content": "<%= turbo_frame_tag dom_id(@event, :talks) do %>\n  <%= render \"events/related_talks/list\", talks: @talks, active_talk: @active_talk, user_watched_talks: user_watched_talks %>\n<% end %>\n"
  },
  {
    "path": "app/views/events/schedules/_day.html.erb",
    "content": "<% talk_count ||= 0 %>\n<% date_string = Date.parse(day.dig(\"date\")).strftime(\"%A (%b %d, %Y)\") %>\n<% day_string = \"#{day.dig(\"name\")} - #{date_string}\" %>\n\n<div class=\"mt-6\">\n  <h1 class=\"mb-6 text-center\"><%= day_string %></h1>\n\n  <% date = day.dig(\"date\") %>\n  <% max_cols = day.dig(\"grid\").map { |grid| grid[\"slots\"] }.max %>\n  <% multi_track = max_cols > 1 %>\n\n  <div class=\"text-center\">\n    <% day.dig(\"grid\").each do |grid| %>\n      <% start_time = grid[\"start_time\"] %>\n      <% end_time = grid[\"end_time\"] %>\n      <% description = grid[\"description\"] %>\n      <% slots = grid[\"slots\"] %>\n      <% items = grid.fetch(\"items\", []) %>\n      <% colspan = (slots != max_cols) ? (max_cols / slots) : 1 %>\n\n      <div class=\"mt-6 border bg-white rounded\">\n        <div class=\"border-b\">\n          <div class=\"text-xs p-2\" colspan=\"<%= max_cols %>\">\n            <%= [start_time, end_time].uniq.join(\" - \") %>\n          </div>\n        </div>\n\n        <% if description %>\n          <div class=\"border-b\">\n            <div class=\"text-xs p-2\">\n              <%= description %>\n            </div>\n          </div>\n        <% end %>\n\n        <div class=\"grid grid-cols-<%= slots %> divide-x\">\n          <% slots.times do |i| %>\n            <% talk = items.any? ? nil : talks[talk_count] %>\n            <% talk_tag = items.any? ? :div : :a %>\n            <% href_attrs = talk ? {href: talk_path(talk, back_to: day_event_schedules_path(event, date), back_to_title: \"Schedule: #{day_string}\")} : {href: \"#\"} %>\n            <% css_classes = token_list(\"group bg-white text-black text-xs p-3 content-center\", \"hover:bg-primary hover:text-white\" => items.none?) %>\n\n            <%= content_tag talk_tag, **href_attrs, class: css_classes, data: {turbo_frame: \"_top\"} do %>\n              <% if items.any? %>\n                <% item = items[i] %>\n\n                <div class=\"w-full flex flex-col text-left items-center\">\n                  <% if item.is_a?(String) %>\n                    <span class=\"text-center\"><%= item %></span>\n                  <% else %>\n                    <b class=\"text-center\"><%= item&.fetch(\"title\").presence || \"no title\" %></b>\n                    <div class=\"prose text-sm mt-3\">\n                      <%= markdown_to_html(item&.fetch(\"description\").presence || \"-\") %>\n                    </div>\n                  <% end %>\n                </div>\n              <% elsif talk %>\n                <% talk_track = talk.static_metadata&.track %>\n                <% track = talk_track && tracks.find { |track| track[\"name\"] == talk_track } %>\n\n                <% if track && talk_track %>\n                  <span class=\"py-1 px-2 mb-4 rounded flex-inline justify-center\" style=\"background: <%= track[\"color\"] %>; color: <%= track[\"text_color\"] %>\">\n                    <%= talk_track %>\n                  </span>\n\n                  <% if multi_track %>\n                    <div class=\"h-4\">&nbsp;</div>\n                  <% end %>\n                <% elsif slots == max_cols && multi_track %>\n                  <span class=\"py-1 px-2 mb-4\">&nbsp;</span>\n                  <div class=\"h-4\">&nbsp;</div>\n                <% end %>\n\n                <div class=\"flex-col\">\n                  <div class=\"text-md font-bold\"><%= talk.title %></div><br>\n                  <div class=\"text-gray-500 group-hover:text-white inline-flex flex-wrap gap-2 justify-center\">\n                    <% talk.speakers.each do |speaker| %>\n                      <%= ui_avatar(speaker, outline: true, size: :sm) %>\n                    <% end %>\n                  </div>\n\n                  <div class=\"text-gray-500 group-hover:text-white mt-2\">\n                    <%= talk.speakers.map(&:name).join(\", \") %>\n                  </div>\n                </div>\n\n                <% talk_count += 1 %>\n              <% else %>\n                No talk found\n              <% end %>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/events/schedules/_schedule.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: event} %>\n\n<%= turbo_frame_tag dom_id(event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: event} %>\n\n    <div class=\"flex items-start flex-wrap gap-8 sm:flex-nowrap w-full\">\n      <div class=\"w-full\">\n        <div id=\"schedule\" class=\"min-w-full\">\n          <div id=\"schedule-navigation\" class=\"flex gap-4 justify-center flex-wrap\">\n            <% days.each_with_index do |day, index| %>\n              <% date_string = Date.parse(day.dig(\"date\")).strftime(\"%A (%b %d, %Y)\") %>\n              <% kind = (day == current_day) ? :primary : :none %>\n\n              <%= ui_button date_string, url: day_event_schedules_path(event, day.dig(\"date\")), kind: kind, size: :sm, role: :button %>\n            <% end %>\n          </div>\n\n          <%= render partial: \"day\", locals: {event: event, day: current_day, tracks: tracks, talks: talks} %>\n        </div>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/schedules/index.html.erb",
    "content": "<%= render partial: \"schedule\", locals: {event: @event, days: @days, tracks: @tracks, talks: @talks, current_day: @day} %>\n"
  },
  {
    "path": "app/views/events/schedules/missing_schedule.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <div class=\"text-center py-12\">\n      <div class=\"max-w-md mx-auto\">\n        <div class=\"text-6xl mb-4\">📅</div>\n        <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No Schedule Yet</h2>\n        <p class=\"text-gray-600 mb-6\">\n          Help us make this information complete! Do you have the schedule for <%= @event.name %>?\n        </p>\n        <div class=\"bg-amber-50 border border-amber-200 rounded-lg p-4 text-left\">\n          <h3 class=\"font-semibold text-amber-800 mb-2\">How to contribute:</h3>\n          <ul class=\"text-sm text-amber-700 space-y-1\">\n            <li>• Check the event website or program</li>\n            <li>• Look for official schedules or agendas</li>\n            <li>• <a href=\"https://github.com/rubyevents/rubyevents/blob/main/docs/ADDING_SCHEDULES.md\" class=\"underline hover:text-amber-900\" target=\"_blank\">Submit schedule data via GitHub</a></li>\n          </ul>\n        </div>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/schedules/show.html.erb",
    "content": "<%= render partial: \"schedule\", locals: {event: @event, days: @days, tracks: @tracks, talks: @talks, current_day: @day} %>\n"
  },
  {
    "path": "app/views/events/series/_card.html.erb",
    "content": "<%= link_to series_path(series), class: \"flex w-full\" do %>\n  <div class=\"card border w-full h-full\">\n    <div class=\"card-body flex flex-col items-center justify-center\">\n        <div class=\"text-xl font-semibold text-center\"><%= series.name %></div>\n        <div><%= pluralize(series.events.count, \"event\") %></div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/series/index.html.erb",
    "content": "<div class=\"container py-8\">\n  <h1 class=\"title\">Event Series</h1>\n\n  <section class=\"flex flex-col w-full gap-4 mt-8\">\n    <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n      <%= render partial: \"events/series/card\", collection: @event_series, as: :series %>\n    </div>\n\n    <% if @event_series.none? %>\n      <p>No event series found</p>\n    <% end %>\n  </section>\n</div>\n"
  },
  {
    "path": "app/views/events/series/show.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<div class=\"container py-8\">\n  <div class=\"block lg:flex gap-8 align-center justify-between\">\n    <div class=\"flex flex-col lg:flex-row gap-8 items-center lg:justify-right text-center lg:text-left mb-6 lg:mb-0\">\n      <% if @events.first&.avatar_image_path %>\n        <%= image_tag image_path(@events.first&.avatar_image_path),\n              class: \"rounded-full border border-[#D9DFE3] size-24 md:size-36\",\n              alt: \"#{@event_series.name} Avatar\",\n              loading: :lazy %>\n      <% end %>\n\n      <div class=\"flex-col flex justify-center\">\n        <h1 class=\"mb-2 text-black font-bold\"><%= @event_series.name %></h1>\n        <h3 class=\"hidden md:block text-[#636B74]\"><%= pluralize(@event_series.events.count, \"event\") %>\n          <% if @event_series.youtube_channel_name.present? %>\n            - @<%= @event_series.youtube_channel_name %>\n          <% end %>\n        </h3>\n      </div>\n    </div>\n\n    <% if Current.user&.admin? %>\n      <div class=\"flex items-center gap-2 mt-4 pt-4 border-t border-gray-200\">\n        <span class=\"text-xs text-gray-400 uppercase tracking-wide\">Admin</span>\n        <%= ui_tooltip \"Reimport Series\" do %>\n          <%= ui_button url: reimport_series_path(@event_series), method: :post, kind: :neutral, size: :sm do %>\n            <%= fa \"download\", size: :sm %>\n          <% end %>\n        <% end %>\n        <%= ui_tooltip \"Reindex Series\" do %>\n          <%= ui_button url: reindex_series_path(@event_series), method: :post, kind: :neutral, size: :sm do %>\n            <%= fa \"arrows-rotate\", size: :sm %>\n          <% end %>\n        <% end %>\n        <%= ui_tooltip \"Open in Avo\" do %>\n          <%= ui_button url: avo.resources_event_series_path(@event_series), target: :_blank, kind: :neutral, size: :sm do %>\n            <%= fa :avocado, size: :sm %>\n          <% end %>\n        <% end %>\n      </div>\n    <% end %>\n  </div>\n\n  <p class=\"mt-3 md:mt-9 mb-3 text-[#636B74] max-w-[700px]\">\n    <%= @event_series.description %>\n  </p>\n\n  <% if @event_series.static_metadata&.ended? %>\n    <div class=\"flex -mt-0.5 mb-4 text-gray-400\">\n      <%= fa \"box-archive\", size: :xs, class: \"mt-0.5 fill-gray-400\" %>\n      <span class=\"text-sm mt-0.5 ml-0.5\">This event series is not active anymore.</span>\n    </div>\n  <% end %>\n\n  <% if (featured_event = @events.find { |event| event.featurable? }) %>\n    <div class=\"hidden lg:block\">\n      <%= render partial: \"events/featured\", locals: {event: featured_event} %>\n    </div>\n  <% end %>\n\n  <% if @events.any? %>\n    <div id=\"events\" class=\"mt-12\">\n      <section class=\"flex flex-col w-full gap-4\">\n        <div class=\"flex items-center justify-between w-full\">\n          <h2 class=\"text-primary shrink-0\">Events</h2>\n        </div>\n        <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n          <%= cache @events do %>\n            <%= render partial: \"events/card\", collection: @events, as: :event, cached: true %>\n          <% end %>\n        </div>\n      </section>\n    </div>\n  <% end %>\n\n  <% if @todos.any? %>\n    <div id=\"todos\" class=\"mt-12\">\n      <section class=\"flex flex-col w-full gap-4\">\n        <div class=\"flex items-center justify-between w-full\">\n          <h2 class=\"text-primary shrink-0\">TODOs</h2>\n          <span class=\"badge badge-primary\"><%= @todos.size %></span>\n        </div>\n        <div class=\"card bg-base-200\">\n          <div class=\"card-body p-4\">\n            <table class=\"table table-sm\">\n              <thead>\n                <tr>\n                  <th>Location</th>\n                  <th>Content</th>\n                </tr>\n              </thead>\n              <tbody>\n                <% @todos.first(20).each do |todo| %>\n                  <tr>\n                    <td class=\"font-mono text-xs\">\n                      <%= link_to todo.url, target: \"_blank\", class: \"link link-primary\" do %>\n                        <%= todo.file.split(\"/\").last(2).join(\"/\") %>:<%= todo.line %>\n                      <% end %>\n                    </td>\n                    <td><code class=\"text-xs break-all\"><%= todo.content %></code></td>\n                  </tr>\n                <% end %>\n              </tbody>\n            </table>\n            <% if @todos.size > 20 %>\n              <p class=\"text-sm text-base-content/70 mt-2\">\n                ... and <%= @todos.size - 20 %> more. <%= link_to \"View all TODOs\", todos_path(view: \"by_event\"), class: \"link link-primary\" %>\n              </p>\n            <% end %>\n          </div>\n        </div>\n      </section>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/show.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event, participation: @participation} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n    <%= render Events::UpcomingEventBannerComponent.new(event: @event) %>\n\n    <div class=\"flex flex-col gap-12 mt-8\">\n      <section class=\"bg-white rounded-lg border p-6 shadow-sm\">\n        <div class=\"grid gap-6 items-center <%= (@event.start_date.present? && @event.start_date > Date.today && @event.date_precision == \"day\" || (@event.today? && !@event.meetup?)) ? \"grid-cols-2 sm:grid-cols-4\" : \"grid-cols-3\" %>\">\n          <div class=\"text-center\">\n            <% if @event.retreat? %>\n              <% duration = (@event.end_date - @event.start_date).to_i %>\n\n              <div class=\"text-3xl font-bold text-primary mb-1\"><%= duration %></div>\n              <div class=\"text-sm font-medium text-gray-600\"><%= \"Day\".pluralize(duration) %></div>\n            <% else %>\n              <div class=\"text-3xl font-bold text-primary mb-1\"><%= @event.talks.count %></div>\n              <div class=\"text-sm font-medium text-gray-600\">Talks</div>\n            <% end %>\n          </div>\n          <div class=\"text-center\">\n            <% if @event.retreat? %>\n              <div class=\"text-3xl font-bold text-primary mb-1\"><%= @event.participants.count %></div>\n              <div class=\"text-sm font-medium text-gray-600\">Known Participants</div>\n            <% else %>\n              <div class=\"text-3xl font-bold text-primary mb-1\"><%= @event.speakers.count %></div>\n              <div class=\"text-sm font-medium text-gray-600\">Speakers</div>\n            <% end %>\n          </div>\n          <div class=\"text-center\">\n            <% if @event.meetup? %>\n              <div class=\"text-3xl font-bold text-primary mb-1\"><%= @event.talks.where(meta_talk: true).count %></div>\n              <div class=\"text-sm font-medium text-gray-600\">Events</div>\n            <% else %>\n              <div class=\"text-3xl font-bold text-primary mb-1\"><%= @event.sponsors.count %></div>\n              <div class=\"text-sm font-medium text-gray-600\">Sponsors</div>\n            <% end %>\n          </div>\n\n          <% if @event.start_date.present? && @event.start_date > Date.today && @event.date_precision == \"day\" %>\n            <% days_until = (@event.start_date - Date.today).to_i %>\n            <div class=\"text-center\">\n              <div class=\"flex justify-center gap-1 mb-2\">\n                <% days_str = days_until.to_s.rjust(2, \"0\") %>\n                <% days_str.chars.each do |digit| %>\n                  <div class=\"relative bg-gray-900 rounded w-8 h-12 flex items-center justify-center font-mono\">\n                    <div class=\"absolute inset-0 overflow-hidden rounded-t\" style=\"clip-path: inset(0 0 50% 0);\">\n                      <div class=\"text-xl font-bold text-white flex items-center justify-center h-full\">\n                        <%= digit %>\n                      </div>\n                    </div>\n\n                    <div class=\"absolute inset-0 overflow-hidden rounded-b\" style=\"clip-path: inset(50% 0 0 0);\">\n                      <div class=\"text-xl font-bold text-white flex items-center justify-center h-full\">\n                        <%= digit %>\n                      </div>\n                    </div>\n\n                    <div class=\"absolute inset-x-0 top-1/2 h-px bg-black shadow-sm transform -translate-y-px z-10\"></div>\n                  </div>\n                <% end %>\n              </div>\n              <div class=\"text-sm font-medium text-gray-600\">Days Until</div>\n            </div>\n          <% elsif @event.today? && !@event.meetup? %>\n            <div class=\"text-center\">\n              <div class=\"text-2xl font-bold text-green-600 mb-1 animate-pulse\">\n                LIVE\n              </div>\n              <div class=\"text-sm font-medium text-gray-600\">Happening Now</div>\n            </div>\n          <% end %>\n        </div>\n      </section>\n\n      <% if @event.meetup? && (@upcoming_meetup_events&.any? || @recent_meetup_events&.any?) %>\n\n        <% if @upcoming_meetup_events&.any? %>\n          <section class=\"flex flex-col w-full gap-4\">\n            <div class=\"flex items-center justify-between w-full\">\n              <h2 class=\"text-primary shrink-0\">Upcoming Events</h2>\n              <%= link_to \"see all events\", event_events_path(@event), class: \"link text-right w-full\" %>\n            </div>\n            <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n              <% @upcoming_meetup_events.each do |meta_talk| %>\n                <%= render \"shared/meta_talk_card\", meta_talk: meta_talk, compact_speakers: true, hide_date_sidebar: true %>\n              <% end %>\n            </div>\n          </section>\n        <% end %>\n\n        <% if @recent_meetup_events&.any? %>\n          <section class=\"flex flex-col w-full gap-4\">\n            <div class=\"flex items-center justify-between w-full\">\n              <h2 class=\"text-primary shrink-0\">Recent Events</h2>\n              <%= link_to \"see all events\", event_events_path(@event), class: \"link text-right w-full\" %>\n            </div>\n            <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n              <% @recent_meetup_events.each do |meta_talk| %>\n                <%= render \"shared/meta_talk_card\", meta_talk: meta_talk, compact_speakers: true, hide_date_sidebar: true %>\n              <% end %>\n            </div>\n          </section>\n        <% end %>\n      <% elsif @keynotes&.any? %>\n        <section class=\"flex flex-col w-full gap-4\">\n          <div class=\"flex items-center justify-between w-full\">\n            <h2 class=\"text-primary shrink-0\">Keynotes</h2>\n            <%= link_to \"see all talks\", event_talks_path(@event), class: \"link text-right w-full\" %>\n          </div>\n          <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3\">\n            <%= render partial: \"talks/card\",\n                  collection: @keynotes,\n                  as: :talk,\n                  locals: {\n                    favoritable: true,\n                    user_favorite_talks_ids: @user_favorite_talks_ids,\n                    user_watched_talks: user_watched_talks,\n                    back_to: event_path(@event),\n                    back_to_title: @event.name\n                  } %>\n          </div>\n        </section>\n      <% end %>\n\n      <% if @recent_talks.any? %>\n        <section class=\"flex flex-col w-full gap-4\">\n          <div class=\"flex items-center justify-between w-full\">\n            <h2 class=\"text-primary shrink-0\">Talks</h2>\n            <%= link_to \"see all talks\", event_talks_path(@event), class: \"link text-right w-full\" %>\n          </div>\n          <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n            <%= render partial: \"talks/card\",\n                  collection: @recent_talks,\n                  as: :talk,\n                  locals: {\n                    favoritable: true,\n                    user_favorite_talks_ids: @user_favorite_talks_ids,\n                    user_watched_talks: user_watched_talks,\n                    back_to: event_path(@event),\n                    back_to_title: @event.name\n                  } %>\n          </div>\n        </section>\n      <% end %>\n\n      <% if @featured_speakers.any? %>\n        <section class=\"flex flex-col w-full gap-4\">\n          <div class=\"flex items-center justify-between w-full\">\n            <h2 class=\"text-primary shrink-0\">Speakers</h2>\n            <%= link_to \"see all speakers\", event_speakers_path(@event), class: \"link text-right w-full\" %>\n          </div>\n          <div class=\"relative\" data-controller=\"scroll\">\n            <div class=\"overflow-x-auto scroll-smooth snap-x snap-mandatory\"\n                 data-scroll-target=\"container\"\n                 data-action=\"scroll->scroll#checkScroll\">\n              <div class=\"flex pb-4 gap-4\">\n                <% @featured_speakers.each do |speaker| %>\n                  <div class=\"snap-start\" data-scroll-target=\"card\">\n                    <%= render partial: \"speakers/card\", locals: {speaker: speaker} %>\n                  </div>\n                <% end %>\n              </div>\n            </div>\n            <div class=\"absolute right-0 top-0 h-full w-24 bg-gradient-to-l from-white to-transparent pointer-events-none\"\n                 data-scroll-target=\"gradient\"></div>\n          </div>\n        </section>\n      <% end %>\n\n      <% if @sponsors.any? %>\n        <section class=\"flex flex-col w-full gap-4\">\n          <div class=\"flex items-center justify-between w-full\">\n            <h2 class=\"text-primary shrink-0\">Sponsors</h2>\n            <%= link_to \"see all sponsors\", event_sponsors_path(@event), class: \"link text-right w-full\" %>\n          </div>\n          <div class=\"relative\" data-controller=\"scroll\">\n            <div class=\"overflow-x-auto scroll-smooth snap-x snap-mandatory\"\n                 data-scroll-target=\"container\"\n                 data-action=\"scroll->scroll#checkScroll\">\n              <div class=\"flex pb-4 gap-4\">\n                <% @sponsors.each do |sponsor| %>\n                  <div class=\"snap-start\" data-scroll-target=\"card\">\n                    <%= render partial: \"organizations/card\", locals: {\n                          organization: sponsor.organization,\n                          sponsor: sponsor,\n                          turbo_frame: true,\n                          hide_event_count: true\n                        } %>\n                  </div>\n                <% end %>\n              </div>\n            </div>\n            <div class=\"absolute right-0 top-0 h-full w-24 bg-gradient-to-l from-white to-transparent pointer-events-none\"\n                 data-scroll-target=\"gradient\"></div>\n          </div>\n        </section>\n      <% end %>\n\n      <% if @event.talks.empty? && @event.speakers.empty? && @sponsors.empty? %>\n        <div class=\"text-center py-12\">\n          <div class=\"max-w-md mx-auto\">\n            <div class=\"text-6xl mb-4\">🎤</div>\n            <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">Coming Soon</h2>\n            <p class=\"text-gray-600 mb-6\">\n              Help us make this event complete! Do you have recordings, speaker info, or sponsor details for <%= @event.name %>?\n            </p>\n            <div class=\"bg-amber-50 border border-amber-200 rounded-lg p-4 text-left\">\n              <h3 class=\"font-semibold text-amber-800 mb-2\">How to contribute:</h3>\n              <ul class=\"text-sm text-amber-700 space-y-1\">\n                <li>• Check the event website or program</li>\n                <li>• Look for recordings or speaker information</li>\n                <li>• <a href=\"https://github.com/rubyevents/rubyevents/issues/new?title=<%= CGI.escape(\"#{@event.name} Content\") %>&body=<%= CGI.escape(\"<!-- Your Content Here -->\\n\\nIssue opened from event page: #{event_url(@event)}\") %>\" class=\"underline hover:text-amber-900\" target=\"_blank\">Open an issue on GitHub</a></li>\n                <li>• <a href=\"https://github.com/rubyevents/rubyevents/blob/main/CONTRIBUTING.md\" class=\"underline hover:text-amber-900\" target=\"_blank\">Submit data via GitHub</a></li>\n              </ul>\n            </div>\n          </div>\n        </div>\n      <% end %>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/speakers/index.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event, participation: @participation} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <div class=\"flex items-start flex-wrap gap-8 sm:flex-nowrap w-full\">\n      <div class=\"w-full\">\n        <% if @event.meetup? && @speakers_with_counts %>\n          <h2 class=\"mb-6\">Speakers (<%= @speakers_with_counts.size %>)</h2>\n\n          <div class=\"mb-12 min-w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 h-full\">\n            <% @speakers_with_counts.each do |speaker| %>\n              <div class=\"border rounded-lg bg-white hover:bg-gray-200 transition-bg duration-300 ease-in-out relative\">\n                <% if speaker.meetup_talks_count > 1 %>\n                  <div class=\"absolute top-2 right-2 bg-primary text-white text-xs font-semibold px-2 py-1 rounded-full\">\n                    <%= speaker.meetup_talks_count %> talks\n                  </div>\n                <% end %>\n                <%= render partial: \"users/card\", locals: {user: speaker} %>\n              </div>\n            <% end %>\n          </div>\n        <% else %>\n          <% titles = Talk.speaker_role_titles %>\n\n          <% grouped = @event.talks.flat_map { |talk| talk.speakers.map { |speaker| [talk.kind, speaker] } }.group_by(&:first).transform_values(&:uniq).sort_by { |kind, _speakers| Talk.kinds.values.index(kind) } %>\n\n          <% grouped.each do |kind, speakers| %>\n            <h2 class=\"mb-6\"><%= titles[kind.to_sym].pluralize(speakers.count) %></h2>\n\n            <div id=\"keynote-speakers\" class=\"mb-12 min-w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 h-full\">\n              <% speakers.each do |kind, speaker| %>\n                <div class=\"border rounded-lg bg-white hover:bg-gray-200 transition-bg duration-300 ease-in-out\">\n                  <%= render partial: \"users/card\", locals: {user: speaker} %>\n                </div>\n              <% end %>\n            </div>\n          <% end %>\n        <% end %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/sponsors/index.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <% if @sponsors_by_tier.any? %>\n      <% @sponsors_by_tier.each do |tier, sponsors| %>\n        <div>\n          <h2 class=\"mb-6 capitalize\">\n            <%= tier %>\n          </h2>\n\n          <div class=\"mb-12 grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-6\">\n            <% sponsors.each do |sponsor| %>\n              <%= render \"organizations/card\", organization: sponsor.organization, sponsor: sponsor, turbo_frame: true, grid_layout: true, hide_event_count: true %>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    <% else %>\n      <div class=\"text-center py-12\">\n        <div class=\"max-w-md mx-auto\">\n          <div class=\"text-6xl mb-4\">🤝</div>\n          <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No Sponsors Yet</h2>\n          <p class=\"text-gray-600 mb-6\">\n            Help us make this information complete! Do you know who sponsored <%= @event.name %>?\n          </p>\n          <div class=\"bg-amber-50 border border-amber-200 rounded-lg p-4 text-left\">\n            <h3 class=\"font-semibold text-amber-800 mb-2\">How to contribute:</h3>\n            <ul class=\"text-sm text-amber-700 space-y-1\">\n              <li>• Check the event website or program</li>\n              <li>• Look for sponsor logos in videos or photos</li>\n              <li>• <a href=\"https://github.com/rubyevents/rubyevents/blob/main/docs/ADDING_SPONSORS.md\" class=\"underline hover:text-amber-900\" target=\"_blank\">Submit sponsor data via GitHub</a></li>\n            </ul>\n          </div>\n        </div>\n      </div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/talks/index.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\" data-controller=\"talks-filter\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n    <%= render partial: \"talks/talk_filter\", locals: {talks: @talks} %>\n\n    <div class=\"flex items-start flex-wrap gap-8 sm:flex-nowrap w-full\">\n      <div class=\"w-full\">\n        <% if @talks.any? %>\n          <div class=\"flex items-center justify-between mb-6 flex-wrap gap-4\">\n            <h2>Talks (<%= @talks.size %>)</h2>\n\n            <% if Current.user %>\n              <label class=\"flex items-center gap-2 cursor-pointer\">\n                <input type=\"checkbox\" class=\"checkbox checkbox-sm\" data-action=\"change->talks-filter#toggle\" data-talks-filter-target=\"toggle\">\n                <span class=\"text-sm\">Hide watched</span>\n                <span class=\"text-sm text-gray-500 hidden\">(<span data-talks-filter-target=\"count\">0</span> hidden)</span>\n              </label>\n            <% end %>\n          </div>\n        <% end %>\n\n        <div id=\"talks\" class=\"min-w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 h-full\">\n          <%= render partial: \"talks/card\",\n                collection: @talks,\n                locals: {\n                  favoritable: true,\n                  user_favorite_talks_ids: @user_favorite_talks_ids,\n                  user_watched_talks: user_watched_talks,\n                  back_to: back_to_from_request,\n                  back_to_title: @event.name\n                },\n                as: :talk %>\n        </div>\n\n        <% if @talks.empty? %>\n          <div class=\"text-center py-12\">\n            <div class=\"max-w-md mx-auto\">\n              <div class=\"text-6xl mb-4\">🎤</div>\n              <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No Talks Yet</h2>\n              <p class=\"text-gray-600 mb-6\">\n                Help us make this information complete! Do you have recordings or information about talks from <%= @event.name %>?\n              </p>\n              <div class=\"bg-amber-50 border border-amber-200 rounded-lg p-4 text-left\">\n                <h3 class=\"font-semibold text-amber-800 mb-2\">How to contribute:</h3>\n                <ul class=\"text-sm text-amber-700 space-y-1\">\n                  <li>• Check if recordings are available online</li>\n                  <li>• Look for talk abstracts and speaker information</li>\n                  <li>• <a href=\"https://github.com/rubyevents/rubyevents/issues/new?title=<%= CGI.escape(\"#{@event.name} Recordings\") %>&body=<%= CGI.escape(\"<!-- Your Content Here -->\\n\\nIssue opened from event page: #{event_url(@event)}\") %>\" class=\"underline hover:text-amber-900\" target=\"_blank\">Open an issue on GitHub</a> to report available recordings</li>\n                  <li>• <a href=\"https://github.com/rubyevents/rubyevents/blob/main/docs/ADDING_VIDEOS.md\" class=\"underline hover:text-amber-900\" target=\"_blank\">Submit talk data via GitHub</a></li>\n                </ul>\n              </div>\n            </div>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/tickets/show.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <div class=\"flex flex-col gap-8 mt-8\">\n      <section class=\"bg-white rounded-lg border p-6 shadow-sm\">\n        <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">Tickets</h2>\n\n        <p class=\"text-gray-600 mb-6\">\n          Tickets for <%= @event.name %> are sold directly by the event organizer<% if @event.tickets.provider_name %> via <%= link_to @event.tickets.provider_name, @event.tickets.url, target: \"_blank\", rel: \"noopener\", class: \"link\" %><% end %>.\n          RubyEvents is not responsible for ticket sales, refunds, or any issues related to your purchase.\n          For more information, check out the <%= link_to \"ticket details\", @event.tickets.url, target: \"_blank\", rel: \"noopener\", class: \"link\" %><% if @event.website.present? %> or the <%= link_to \"conference website\", @event.website, target: \"_blank\", rel: \"noopener\", class: \"link\" %><% end %>.\n        </p>\n\n        <% if @event.tickets.tito? %>\n          <%= render Tito::WidgetComponent.new(event: @event, wrapper: false) %>\n        <% end %>\n\n        <p class=\"<% if @event.tickets.tito? %> mt-6 <% end %>\">\n          <%= link_to @event.tickets.url, target: \"_blank\", rel: \"noopener\", class: \"btn btn-primary\" do %>\n            <%= @event.tickets.provider_name ? \"Open on #{@event.tickets.provider_name}\" : \"Buy Tickets\" %>\n            <%= fa(\"square-arrow-up-right\", size: :xs, style: :solid, class: \"ml-1\") %>\n          <% end %>\n        </p>\n      </section>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/todos/index.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event, participation: @participation} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <div class=\"flex flex-col gap-4\">\n      <div class=\"flex items-center gap-2 mb-4\">\n        <span class=\"badge badge-primary badge-lg\"><%= @todos.size %></span>\n        <span class=\"text-lg font-medium\">TODOs for this event</span>\n      </div>\n\n      <div class=\"card bg-base-200\">\n        <div class=\"card-body p-4\">\n          <table class=\"table table-sm\">\n            <thead>\n              <tr>\n                <th>Location</th>\n                <th>Content</th>\n              </tr>\n            </thead>\n            <tbody>\n              <% @todos.each do |todo| %>\n                <tr>\n                  <td class=\"font-mono text-xs\">\n                    <%= link_to todo.url, target: \"_blank\", class: \"link link-primary\" do %>\n                      <%= File.basename(todo.file) %>:<%= todo.line %>\n                    <% end %>\n                  </td>\n                  <td><code class=\"text-xs break-all\"><%= todo.content %></code></td>\n                </tr>\n              <% end %>\n            </tbody>\n          </table>\n        </div>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/venues/missing_venue.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <div class=\"text-center py-12\">\n      <div class=\"max-w-md mx-auto\">\n        <div class=\"text-6xl mb-4\">📍</div>\n        <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No Venue Information Yet</h2>\n        <p class=\"text-gray-600 mb-6\">\n          Help us make this information complete! Do you know the venue details for <%= @event.name %>?\n        </p>\n        <div class=\"bg-amber-50 border border-amber-200 rounded-lg p-4 text-left\">\n          <h3 class=\"font-semibold text-amber-800 mb-2\">How to contribute:</h3>\n          <ul class=\"text-sm text-amber-700 space-y-1\">\n            <li>• Check the event website for venue information</li>\n            <li>• Look for address, directions, and room details</li>\n            <li>• <a href=\"https://github.com/rubyevents/rubyevents/issues/new?title=<%= CGI.escape(\"#{@event.name} Venue Information\") %>&body=<%= CGI.escape(\"Venue Name: \\nAddress: \\nWebsite: \\n\\nIssue opened from event page: #{event_url(@event)}\") %>\" class=\"underline hover:text-amber-900\" target=\"_blank\">Open an issue on GitHub</a></li>\n            <li>• <a href=\"https://github.com/rubyevents/rubyevents/blob/main/docs/ADDING_VENUES.md\" class=\"underline hover:text-amber-900\" target=\"_blank\">Submit data via GitHub</a></li>\n          </ul>\n        </div>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/venues/show.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <div class=\"flex flex-col gap-8 mt-8\">\n      <section class=\"bg-white rounded-lg border p-6 shadow-sm\">\n        <div class=\"flex flex-col md:flex-row gap-6\">\n          <div class=\"flex-1\">\n            <h2 class=\"text-2xl font-bold text-gray-900 mb-2\"><%= @venue.name %></h2>\n\n            <% if @venue.display_address.present? %>\n              <p class=\"text-gray-600 mb-2\"><%= @venue.display_address %></p>\n            <% end %>\n\n            <% if @venue.description.present? %>\n              <p class=\"text-gray-600 mb-4 whitespace-pre-line\"><%= @venue.description %></p>\n            <% end %>\n\n            <% if @venue.instructions.present? %>\n              <div class=\"mt-4\">\n                <h3 class=\"font-semibold text-gray-800 mb-2\">Getting There</h3>\n                <p class=\"text-gray-600 whitespace-pre-line\"><%= @venue.instructions %></p>\n              </div>\n            <% end %>\n\n            <% if @venue.maps.any? || @venue.url.present? %>\n              <div class=\"flex flex-wrap gap-2 mt-4\">\n                <% if @venue.url.present? %>\n                  <%= link_to @venue.url, target: \"_blank\", rel: \"noopener\", class: \"btn btn-sm btn-outline gap-2\" do %>\n                    <%= fa(\"square-arrow-up-right\", size: :sm, style: :solid) %>\n                    Website\n                  <% end %>\n                <% end %>\n\n                <% if @venue.google_maps_url.present? %>\n                  <%= link_to @venue.google_maps_url, target: \"_blank\", rel: \"noopener\", class: \"btn btn-sm btn-outline gap-2\" do %>\n                    <%= fa(\"map-location\", size: :sm, style: :solid) %>\n                    Google Maps\n                  <% end %>\n                <% end %>\n\n                <% if @venue.apple_maps_url.present? %>\n                  <%= link_to @venue.apple_maps_url, target: \"_blank\", rel: \"noopener\", class: \"btn btn-sm btn-outline gap-2\" do %>\n                    <%= fa(\"map-location\", size: :sm, style: :solid) %>\n                    Apple Maps\n                  <% end %>\n                <% end %>\n\n                <% if @venue.openstreetmap_url.present? %>\n                  <%= link_to @venue.openstreetmap_url, target: \"_blank\", rel: \"noopener\", class: \"btn btn-sm btn-outline gap-2\" do %>\n                    <%= fa(\"map-location\", size: :sm, style: :solid) %>\n                    OpenStreetMap\n                  <% end %>\n                <% end %>\n              </div>\n            <% end %>\n          </div>\n        </div>\n      </section>\n\n      <% if @venue.map_markers.any? %>\n        <section class=\"bg-white rounded-lg border shadow-sm overflow-hidden\">\n          <div\n            id=\"venue-map\"\n            class=\"w-full h-[400px] md:h-[500px]\"\n            data-controller=\"map\"\n            data-map-mode-value=\"venue\"\n            data-map-markers-value=\"<%= @venue.map_markers.to_json %>\"></div>\n        </section>\n      <% end %>\n\n      <% if @venue.rooms.any? %>\n        <section class=\"bg-white rounded-lg border p-6 shadow-sm\">\n          <h3 class=\"text-xl font-bold text-gray-900 mb-4\">Rooms</h3>\n          <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n            <% @venue.rooms.each do |room| %>\n              <div class=\"border rounded-lg p-4\">\n                <h4 class=\"font-semibold text-gray-900\"><%= room[\"name\"] %></h4>\n                <% if room[\"floor\"].present? %>\n                  <p class=\"text-sm text-gray-500\"><%= room[\"floor\"] %></p>\n                <% end %>\n                <% if room[\"capacity\"].present? %>\n                  <p class=\"text-sm text-gray-500\">Capacity: <%= room[\"capacity\"] %></p>\n                <% end %>\n                <% if room[\"instructions\"].present? %>\n                  <p class=\"text-sm text-gray-600 mt-2\"><%= room[\"instructions\"] %></p>\n                <% end %>\n              </div>\n            <% end %>\n          </div>\n        </section>\n      <% end %>\n\n      <% if @venue.spaces.any? %>\n        <section class=\"bg-white rounded-lg border p-6 shadow-sm\">\n          <h3 class=\"text-xl font-bold text-gray-900 mb-4\">Other Spaces</h3>\n          <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n            <% @venue.spaces.each do |space| %>\n              <div class=\"border rounded-lg p-4\">\n                <h4 class=\"font-semibold text-gray-900\"><%= space[\"name\"] %></h4>\n                <% if space[\"floor\"].present? %>\n                  <p class=\"text-sm text-gray-500\"><%= space[\"floor\"] %></p>\n                <% end %>\n                <% if space[\"instructions\"].present? %>\n                  <p class=\"text-sm text-gray-600 mt-2\"><%= space[\"instructions\"] %></p>\n                <% end %>\n              </div>\n            <% end %>\n          </div>\n        </section>\n      <% end %>\n\n      <% if @venue.accessibility.any? %>\n        <section class=\"bg-white rounded-lg border p-6 shadow-sm\">\n          <h3 class=\"text-xl font-bold text-gray-900 mb-4\">Accessibility</h3>\n          <div class=\"flex flex-wrap gap-3\">\n            <% if @venue.accessibility[\"wheelchair\"] %>\n              <span class=\"badge badge-lg badge-success gap-2\">\n                <%= fa(\"circle-check\", size: :xs, style: :solid, class: \"fill-green-700\") %>\n                Wheelchair Accessible\n              </span>\n            <% end %>\n            <% if @venue.accessibility[\"elevators\"] %>\n              <span class=\"badge badge-lg badge-success gap-2\">\n                <%= fa(\"circle-check\", size: :xs, style: :solid, class: \"fill-green-700\") %>\n                Elevators\n              </span>\n            <% end %>\n            <% if @venue.accessibility[\"accessible_restrooms\"] %>\n              <span class=\"badge badge-lg badge-success gap-2\">\n                <%= fa(\"circle-check\", size: :xs, style: :solid, class: \"fill-green-700\") %>\n                Accessible Restrooms\n              </span>\n            <% end %>\n          </div>\n          <% if @venue.accessibility[\"notes\"].present? %>\n            <p class=\"text-gray-600 mt-4\"><%= @venue.accessibility[\"notes\"] %></p>\n          <% end %>\n        </section>\n      <% end %>\n\n      <% if @venue.nearby.any? %>\n        <section class=\"bg-white rounded-lg border p-6 shadow-sm\">\n          <h3 class=\"text-xl font-bold text-gray-900 mb-4\">Nearby</h3>\n          <dl class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n            <% if @venue.nearby[\"public_transport\"].present? %>\n              <div>\n                <dt class=\"font-semibold text-gray-700\">Public Transport</dt>\n                <dd class=\"text-gray-600\"><%= @venue.nearby[\"public_transport\"] %></dd>\n              </div>\n            <% end %>\n            <% if @venue.nearby[\"parking\"].present? %>\n              <div>\n                <dt class=\"font-semibold text-gray-700\">Parking</dt>\n                <dd class=\"text-gray-600\"><%= @venue.nearby[\"parking\"] %></dd>\n              </div>\n            <% end %>\n          </dl>\n        </section>\n      <% end %>\n\n      <% if @venue.locations.any? %>\n        <section class=\"bg-white rounded-lg border p-6 shadow-sm\">\n          <h3 class=\"text-xl font-bold text-gray-900 mb-4\">Other Locations</h3>\n          <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n            <% @venue.locations.each do |location| %>\n              <div class=\"border rounded-lg p-4\">\n                <div class=\"flex items-start justify-between gap-2\">\n                  <h4 class=\"font-semibold text-gray-900\"><%= location[\"name\"] %></h4>\n                  <% if location[\"kind\"].present? %>\n                    <span class=\"badge badge-sm badge-primary shrink-0\"><%= location[\"kind\"] %></span>\n                  <% end %>\n                </div>\n                <% if location.dig(\"address\", \"display\").present? %>\n                  <p class=\"text-sm text-gray-500 mt-1\"><%= location.dig(\"address\", \"display\") %></p>\n                <% end %>\n                <% if location[\"description\"].present? %>\n                  <p class=\"text-sm text-gray-600 mt-2\"><%= location[\"description\"] %></p>\n                <% end %>\n                <% if location[\"distance\"].present? %>\n                  <p class=\"text-xs text-gray-500 mt-2\"><%= location[\"distance\"] %></p>\n                <% end %>\n                <div class=\"flex flex-wrap gap-2 mt-3\">\n                  <% if location.dig(\"maps\", \"google\").present? %>\n                    <%= link_to location.dig(\"maps\", \"google\"), target: \"_blank\", rel: \"noopener\", class: \"btn btn-xs btn-outline\" do %>\n                      <%= fa(\"map-location\", size: :xs, style: :solid) %>\n                      Google\n                    <% end %>\n                  <% end %>\n                  <% if location.dig(\"maps\", \"apple\").present? %>\n                    <%= link_to location.dig(\"maps\", \"apple\"), target: \"_blank\", rel: \"noopener\", class: \"btn btn-xs btn-outline\" do %>\n                      <%= fa(\"map-location\", size: :xs, style: :solid) %>\n                      Apple\n                    <% end %>\n                  <% end %>\n                  <% if location[\"url\"].present? %>\n                    <%= link_to location[\"url\"], target: \"_blank\", rel: \"noopener\", class: \"btn btn-xs btn-outline\" do %>\n                      <%= fa(\"square-arrow-up-right\", size: :xs, style: :solid) %>\n                      Website\n                    <% end %>\n                  <% end %>\n                </div>\n              </div>\n            <% end %>\n          </div>\n        </section>\n      <% end %>\n\n      <% if @venue.hotels.any? %>\n        <section class=\"bg-white rounded-lg border p-6 shadow-sm\">\n          <h3 class=\"text-xl font-bold text-gray-900 mb-4\">Recommended Hotels</h3>\n          <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n            <% @venue.hotels.each do |hotel| %>\n              <div class=\"border rounded-lg p-4\">\n                <div class=\"flex items-start justify-between gap-2\">\n                  <h4 class=\"font-semibold text-gray-900\"><%= hotel[\"name\"] %></h4>\n                  <% if hotel[\"kind\"].present? %>\n                    <span class=\"badge badge-sm badge-outline shrink-0\"><%= hotel[\"kind\"] %></span>\n                  <% end %>\n                </div>\n                <% if hotel.dig(\"address\", \"display\").present? %>\n                  <p class=\"text-sm text-gray-500 mt-1\"><%= hotel.dig(\"address\", \"display\") %></p>\n                <% end %>\n                <% if hotel[\"description\"].present? %>\n                  <p class=\"text-sm text-gray-600 mt-2\"><%= hotel[\"description\"] %></p>\n                <% end %>\n                <% if hotel[\"distance\"].present? %>\n                  <p class=\"text-xs text-gray-500 mt-2\"><%= hotel[\"distance\"] %></p>\n                <% end %>\n                <div class=\"flex flex-wrap gap-2 mt-3\">\n                  <% if hotel.dig(\"maps\", \"google\").present? %>\n                    <%= link_to hotel.dig(\"maps\", \"google\"), target: \"_blank\", rel: \"noopener\", class: \"btn btn-xs btn-outline\" do %>\n                      <%= fa(\"map-location\", size: :xs, style: :solid) %>\n                      Google\n                    <% end %>\n                  <% end %>\n                  <% if hotel.dig(\"maps\", \"apple\").present? %>\n                    <%= link_to hotel.dig(\"maps\", \"apple\"), target: \"_blank\", rel: \"noopener\", class: \"btn btn-xs btn-outline\" do %>\n                      <%= fa(\"map-location\", size: :xs, style: :solid) %>\n                      Apple\n                    <% end %>\n                  <% end %>\n                  <% if hotel[\"url\"].present? %>\n                    <%= link_to hotel[\"url\"], target: \"_blank\", rel: \"noopener\", class: \"btn btn-xs btn-outline\" do %>\n                      <%= fa(\"square-arrow-up-right\", size: :xs, style: :solid) %>\n                      Website\n                    <% end %>\n                  <% end %>\n                </div>\n              </div>\n            <% end %>\n          </div>\n        </section>\n      <% end %>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/videos/index.html.erb",
    "content": "<%= render partial: \"events/header\", locals: {event: @event} %>\n\n<%= turbo_frame_tag dom_id(@event), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <%= render partial: \"events/navigation\", locals: {event: @event} %>\n\n    <div class=\"flex items-start flex-wrap gap-8 sm:flex-nowrap w-full\">\n      <div class=\"w-full\">\n        <div id=\"talks\" class=\"min-w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 h-full\">\n          <%= render partial: \"talks/card\",\n                collection: @talks,\n                locals: {\n                  favoritable: true,\n                  user_favorite_talks_ids: @user_favorite_talks_ids,\n                  user_watched_talks: user_watched_talks,\n                  back_to: back_to_from_request,\n                  back_to_title: @event.name\n                },\n                as: :talk %>\n        </div>\n\n        <% if @talks.empty? %>\n          <div class=\"flex justify-center border rounded\" style=\"padding-top: 3rem; padding-bottom: 3rem; padding-right: 1rem; padding-left: 1rem\">\n            <div class=\"text-center text-gray-600\">\n              <p>\n                <b>No talks found for this event.</b>\n              </p>\n              <p class=\"mt-2\">\n                Please\n                <a href=\"https://github.com/rubyevents/rubyevents/issues/new?title=<%= CGI.escape(\"#{@event.name} Recordings\") %>&body=<%= CGI.escape(\"<!-- Your Content Here -->\\n\\nIssue opened from event page: #{event_url(@event)}\") %>\" class=\"text-primary\" target=\"_blank\">open an issue on GitHub</a>\n                if you know how to get access to the recordings of this event. Thank you!\n              </p>\n            </div>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/events/years/_desktop_calendar.html.erb",
    "content": "<% current_month = (year == Date.today.year) ? Date.today.month : nil %>\n\n<div class=\"hidden md:grid md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-px bg-gray-200 rounded-2xl shadow-sm relative z-0\">\n  <% (1..12).each do |month| %>\n    <% month_events = events_by_month[month] || [] %>\n    <% is_current_month = month == current_month %>\n\n    <% corner_classes = case month\n       when 1 then \"rounded-tl-2xl md:rounded-tl-2xl\"\n       when 2 then \"md:rounded-tr-2xl lg:rounded-tr-none\"\n       when 3 then \"lg:rounded-tr-2xl xl:rounded-tr-none\"\n       when 4 then \"xl:rounded-tr-2xl\"\n       when 9 then \"xl:rounded-bl-2xl\"\n       when 10 then \"lg:rounded-bl-2xl xl:rounded-bl-none\"\n       when 11 then \"md:rounded-bl-2xl lg:rounded-bl-none\"\n       when 12 then \"rounded-br-2xl md:rounded-br-2xl\"\n       else \"\"\n       end %>\n\n    <div class=\"<%= is_current_month ? \"bg-red-50 ring-2 ring-inset ring-red-200\" : \"bg-white\" %> p-6 relative <%= corner_classes %>\">\n      <div class=\"flex items-baseline justify-between mb-5\">\n        <h2 class=\"text-xl font-bold <%= is_current_month ? \"text-red-600\" : \"text-gray-900\" %>\"><%= Date::MONTHNAMES[month] %></h2>\n\n        <% if month_events.any? %>\n          <span class=\"text-xs font-semibold px-2.5 py-1 rounded-full <%= is_current_month ? \"bg-red-500 text-white\" : \"text-gray-500 bg-gray-100\" %>\">\n            <%= month_events.count %>\n          </span>\n        <% end %>\n      </div>\n\n      <div class=\"min-h-[180px]\">\n        <% if month_events.any? %>\n          <div class=\"flex flex-wrap gap-3\">\n            <% month_events.each do |event| %>\n              <% featured_bg = event.static_metadata.featured_background.presence || \"#1f2937\" %>\n\n              <div class=\"relative group/card\" data-controller=\"hover-card\" data-action=\"mouseenter->hover-card#reveal\">\n                <%= link_to event_path(event) do %>\n                  <div class=\"w-20 h-20 rounded-xl overflow-hidden ring-2 ring-gray-100 group-hover/card:ring-4 group-hover/card:ring-[--brand-color] transition-all duration-200 transform group-hover/card:scale-105 shadow-sm\" style=\"--brand-color: <%= featured_bg %>;\">\n                    <%= image_tag event.avatar_image_path, alt: event.name, class: \"w-full h-full object-cover\", loading: \"lazy\" %>\n                  </div>\n                <% end %>\n                <%= render HoverCard::EventComponent.new(record: event) %>\n              </div>\n            <% end %>\n          </div>\n        <% else %>\n          <div class=\"flex items-center justify-center h-full\">\n            <span class=\"text-gray-300 text-sm\">—</span>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/years/_event_hover_card.html.erb",
    "content": "<%# locals: (event:) %>\n<% featured_bg = event.static_metadata.featured_background.presence || \"#1f2937\" %>\n<% featured_color = event.static_metadata.featured_color.presence || \"#ffffff\" %>\n\n<div class=\"absolute left-1/2 -translate-x-1/2 bottom-full mb-3 w-80 rounded-2xl overflow-hidden opacity-0 group-hover/card:opacity-100 transition-all duration-200 pointer-events-none z-20 shadow-2xl scale-95 group-hover/card:scale-100\" style=\"background: <%= featured_bg %>; color: <%= featured_color %>;\">\n  <div class=\"p-6 pb-0\">\n    <div class=\"aspect-[615/350] overflow-hidden rounded-xl\">\n      <%= image_tag event.featured_image_path, alt: event.name, class: \"w-full h-full object-cover\", loading: \"lazy\" %>\n    </div>\n  </div>\n\n  <div class=\"p-5 pt-4\">\n    <div>\n      <p class=\"font-bold text-sm leading-tight line-clamp-2\"><%= event.name %></p>\n      <p class=\"text-xs opacity-75 mt-1\"><%= event.formatted_dates %></p>\n    </div>\n\n    <div class=\"mt-3 pt-3 border-t flex items-center justify-between\" style=\"border-color: <%= featured_color %>20;\">\n      <div class=\"flex items-center gap-1.5 text-xs min-w-0 flex-1\">\n        <%= fa \"location-dot\", class: \"text-[10px] shrink-0\" %>\n        <span class=\"truncate\"><%= event.to_location.to_html(show_links: false) %></span>\n      </div>\n\n      <% if event.keynote_speakers.any? %>\n        <div class=\"flex gap-1\">\n          <% event.keynote_speakers.first(4).each do |speaker| %>\n            <% if speaker.github_handle.present? %>\n              <div class=\"w-6 h-6 rounded-full overflow-hidden ring-2 ring-current/20\">\n                <%= image_tag \"https://avatars.githubusercontent.com/#{speaker.github_handle}?s=48\", alt: speaker.name, class: \"w-full h-full object-cover\", loading: \"lazy\" %>\n              </div>\n            <% end %>\n          <% end %>\n        </div>\n      <% end %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/events/years/_header.html.erb",
    "content": "<header class=\"mb-8 md:mb-12\">\n  <div class=\"flex items-center gap-2 text-gray-400 text-sm mb-4 md:mb-6 hotwire-native:hidden\">\n    <%= link_to \"Events\", events_path, class: \"hover:text-gray-900 transition-colors\" %>\n\n    <span class=\"text-gray-300\">/</span>\n    <span class=\"text-gray-600\"><%= year %></span>\n  </div>\n\n  <div class=\"flex flex-col md:flex-row md:items-end justify-between gap-4 md:gap-6\">\n    <div>\n      <h1 class=\"text-5xl md:text-8xl font-black text-gray-900 tracking-tight\">\n        <%= title year.to_s %>\n      </h1>\n\n      <p class=\"text-gray-500 mt-1 md:mt-2 text-base md:text-lg\">\n        Ruby Events Calendar •\n\n        <span class=\"text-gray-400\">\n          <%= events.count %> events\n\n          <% if monthly_events.any? %>\n            across <%= events_by_month.keys.count %> months\n          <% end %>\n        </span>\n      </p>\n    </div>\n\n    <nav class=\"flex flex-col items-end gap-2 hotwire-native:hidden\">\n      <% if year != Date.today.year %>\n        <%= link_to year_events_path(year: Date.today.year), class: \"px-3 md:px-4 py-1.5 rounded-full bg-red-500 text-white text-sm font-medium hover:bg-red-600 transition-all\" do %>\n          Today\n        <% end %>\n      <% end %>\n\n      <div class=\"flex items-center gap-2\">\n        <% if has_previous_year %>\n          <%= link_to year_events_path(year: year - 1), class: \"flex items-center gap-2 px-3 md:px-4 py-2 rounded-full border border-gray-200 text-gray-500 hover:border-gray-900 hover:text-gray-900 transition-all text-sm md:text-base\" do %>\n            <%= fa \"arrow-left\", class: \"text-xs md:text-sm\" %>\n            <span class=\"font-medium\"><%= year - 1 %></span>\n          <% end %>\n        <% end %>\n\n        <% if has_next_year %>\n          <%= link_to year_events_path(year: year + 1), class: \"flex items-center gap-2 px-3 md:px-4 py-2 rounded-full border border-gray-200 text-gray-500 hover:border-gray-900 hover:text-gray-900 transition-all text-sm md:text-base\" do %>\n            <span class=\"font-medium\"><%= year + 1 %></span>\n            <%= fa \"arrow-right\", class: \"text-xs md:text-sm\" %>\n          <% end %>\n        <% end %>\n      </div>\n    </nav>\n  </div>\n</header>\n"
  },
  {
    "path": "app/views/events/years/_mobile_calendar.html.erb",
    "content": "<% current_month = (year == Date.today.year) ? Date.today.month : nil %>\n\n<div class=\"md:hidden flex flex-col divide-y divide-gray-100 bg-white rounded-xl shadow-sm border border-gray-100\">\n  <% (1..12).each do |month| %>\n    <% month_events = events_by_month[month] || [] %>\n    <% is_current_month = month == current_month %>\n    <div class=\"flex gap-4 p-3 <%= \"bg-red-50\" if is_current_month %>\">\n      <div class=\"w-8 shrink-0 pt-1\">\n        <span class=\"text-sm font-bold <%= is_current_month ? \"text-red-600\" : \"text-gray-900\" %>\"><%= Date::ABBR_MONTHNAMES[month] %></span>\n      </div>\n\n      <div class=\"flex-1 flex flex-wrap gap-2\">\n        <% if month_events.any? %>\n          <% month_events.each do |event| %>\n            <%= link_to event_path(event) do %>\n              <div class=\"w-10 h-10 rounded-lg overflow-hidden ring-2 ring-gray-100 shadow-sm\">\n                <%= image_tag event.avatar_image_path, alt: event.name, class: \"w-full h-full object-cover\", loading: \"lazy\" %>\n              </div>\n            <% end %>\n          <% end %>\n        <% else %>\n          <span class=\"text-gray-300 text-sm\">—</span>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/events/years/_yearly_events.html.erb",
    "content": "<div class=\"mt-8 md:mt-12\">\n  <div class=\"flex flex-col md:flex-row md:items-baseline justify-between gap-1 md:gap-0 mb-4 md:mb-6\">\n    <h2 class=\"text-xl md:text-2xl font-bold text-gray-900\">Sometime in <%= year %></h2>\n    <span class=\"text-xs md:text-sm text-gray-400\"><%= events.count %> events with unconfirmed dates</span>\n  </div>\n\n  <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 md:gap-4\">\n    <% events.each do |event| %>\n      <%= link_to event_path(event), class: \"group flex items-center gap-3 md:gap-4 p-3 md:p-4 bg-white rounded-xl border border-gray-100 hover:border-gray-300 hover:shadow-sm transition-all\" do %>\n        <div class=\"w-14 h-14 md:w-20 md:h-20 rounded-lg md:rounded-xl overflow-hidden ring-2 ring-gray-100 group-hover:ring-red-500 transition-all shadow-sm shrink-0\">\n          <%= image_tag event.avatar_image_path, alt: event.name, class: \"w-full h-full object-cover\", loading: \"lazy\" %>\n        </div>\n\n        <div class=\"min-w-0\">\n          <p class=\"font-semibold text-gray-900 group-hover:text-red-600 transition-colors truncate\"><%= event.name %></p>\n          <p class=\"text-sm text-gray-500 truncate\"><%= event.to_location.to_html(show_links: false) %></p>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/events/years/index.html.erb",
    "content": "<div class=\"container py-6 md:py-12 hotwire-native:py-3\">\n  <%= render partial: \"header\", locals: {\n        year: @year,\n        events: @events,\n        monthly_events: @monthly_events,\n        events_by_month: @events_by_month,\n        has_previous_year: @has_previous_year,\n        has_next_year: @has_next_year\n      } %>\n\n  <%= render partial: \"mobile_calendar\", locals: {events_by_month: @events_by_month, year: @year} %>\n  <%= render partial: \"desktop_calendar\", locals: {events_by_month: @events_by_month, year: @year} %>\n\n  <% if @yearly_events.any? %>\n    <%= render partial: \"yearly_events\", locals: {year: @year, events: @yearly_events} %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/favorite_users/_favorite_user.html.erb",
    "content": "<%# locals: (favorite_user:) %>\n\n<% if Current.user && favorite_user %>\n  <div id=\"<%= dom_id favorite_user %>\">\n    <% if favorite_user.persisted? && favorite_user.mutual_favorite_user&.persisted? %>\n      <%= ui_tooltip \"Remove from your list of Ruby Friends\" do %>\n          <%= button_to favorite_user_path(favorite_user), method: :delete, form_class: \"mt-1\" do %>\n            <%= fa(\"star\", size: :sm, style: :solid, class: \"fill-red-600\") %>\n          <% end %>\n      <% end %>\n    <% elsif favorite_user.persisted? %>\n      <%= ui_tooltip \"Remove from your list of Favorite Rubyists and delete notes.\" do %>\n          <%= button_to favorite_user_path(favorite_user), method: :delete, form_class: \"mt-1\" do %>\n            <%= fa(\"star\", size: :sm, style: :solid, class: \"fill-yellow-400\") %>\n          <% end %>\n      <% end %>\n    <% elsif favorite_user.favorite_user_id != Current.user.id %>\n      <%= ui_tooltip \"Add to your list of Favorite Rubyists\" do %>\n          <%= button_to favorite_users_path, method: :post, params: {favorite_user: {favorite_user_id: favorite_user.favorite_user_id}}, form_class: \"mt-1\" do %>\n            <%= fa(\"star\", size: :sm, style: :regular, class: \"hover:fill-yellow-400\") %>\n          <% end %>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/favorite_users/_form.html.erb",
    "content": "<%# locals: (favorite_user:, redirect_to: \"\") %>\n\n<%= form_with(model: favorite_user, local: true) do |form| %>\n  <%= form.hidden_field :favorite_user_id %>\n  <%= hidden_field_tag(:redirect_to, redirect_to) if redirect_to.present? %>\n\n  <div class=\"field\">\n    <%= form.label :notes %>\n    <%= form.text_area :notes, rows: 3, class: \"textarea textarea-bordered w-full\" %>\n  </div>\n\n  <div class=\"actions mt-2\">\n    <%= form.submit \"Save\", class: \"btn btn-primary\" %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/favorite_users/_list.html.erb",
    "content": "<%# locals: (favorite_users:) %>\n\n<div class=\"min-w-full grid sm:grid-cols-2 lg:grid-cols-3 gap-4 mt-2\">\n  <% favorite_users.each do |favorite_user| %>\n    <div class=\"border rounded-lg flex justify-between items-center bg-white hover:bg-gray-200 transition-bg duration-300 ease-in-out\">\n      <%= render partial: \"users/card\", locals: {user: favorite_user.favorite_user, favorite_user: favorite_user} %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/favorite_users/_no_favorites.html.erb",
    "content": "<div class=\"text-center py-12\">\n  <div class=\"max-w-md mx-auto\">\n    <div class=\"text-6xl mb-4\">👥</div>\n    <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No Favorite Rubyists Yet</h2>\n    <p class=\"text-gray-600 mb-6\">\n      Below a list of speakers recommended for you.\n    </p>\n  </div>\n</div>\n\n<div id=\"favorite_users\" class=\"min-w-full grid sm:grid-cols-2 lg:grid-cols-3 gap-4 mt-2\">\n<% recommendations.each do |favorite_user| %>\n  <div id=\"<%= dom_id favorite_user %>\">\n    <div class=\"border rounded-lg flex justify-between items-center bg-white hover:bg-gray-200 transition-bg duration-300 ease-in-out\">\n      <%= render partial: \"users/card\", locals: {user: favorite_user.favorite_user, favorite_user: favorite_user} %>\n    </div>\n  </div>\n<% end %>\n</div>\n"
  },
  {
    "path": "app/views/favorite_users/index.html.erb",
    "content": "<div class=\"container flex flex-col gap-6\">\n  <% if @favorite_rubyists.empty? && @ruby_friends.empty? %>\n    <%= render partial: \"favorite_users/no_favorites\", locals: {recommendations: @recommendations} %>\n  <% else %>\n    <% if @ruby_friends.any? %>\n      <div id=\"ruby-friends\">\n        <h2 class=\"mb-4\">\n          <%= fa(\"star\", size: :sm, style: :solid, class: \"fill-red-600 inline\") %>\n          Ruby Friends\n        </h2>\n        <%= render partial: \"favorite_users/list\", locals: {favorite_users: @ruby_friends} %>\n      </div>\n    <% end %>\n    <% if @favorite_rubyists.any? %>\n      <div id=\"favorite-rubyists\">\n        <h2>\n          <%= fa(\"star\", size: :sm, style: :solid, class: \"fill-yellow-400 inline\") %>\n          Favorite Rubyists\n        </h2>\n        <%= render partial: \"favorite_users/list\", locals: {favorite_users: @favorite_rubyists} %>\n      </div>\n    <% end %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/gems/_gem_card.html.erb",
    "content": "<%= link_to gem_path(gem_name: topic_gem.gem_name), class: \"flex flex-col gap-3 p-4 bg-base-100 rounded-lg border hover:border-primary hover:shadow-sm transition-all\" do %>\n  <div class=\"flex items-center justify-between\">\n    <div class=\"flex items-center gap-2\">\n      <%= fa(\"gem\", size: :sm, class: \"fill-primary\") %>\n      <code class=\"font-semibold text-lg font-mono\"><%= topic_gem.gem_name %></code>\n    </div>\n    <% if topic_gem.version.present? %>\n      <span class=\"badge badge-sm badge-primary badge-outline\">v<%= topic_gem.version %></span>\n    <% end %>\n  </div>\n\n  <% if topic_gem.summary.present? %>\n    <p class=\"text-sm text-gray-600 line-clamp-2\"><%= topic_gem.summary %></p>\n  <% end %>\n\n  <div class=\"flex flex-wrap items-center gap-3 text-xs text-gray-500 mt-auto pt-1\">\n    <div class=\"flex items-center gap-1\">\n      <%= fa(\"video\", size: :xs) %>\n      <span><%= pluralize(topic_gem.talks_count, \"talk\") %></span>\n    </div>\n\n    <% if topic_gem.downloads.present? %>\n      <div class=\"flex items-center gap-1\">\n        <%= fa(\"download\", size: :xs) %>\n        <span><%= number_to_human(topic_gem.downloads) %></span>\n      </div>\n    <% end %>\n\n    <% if topic_gem.license.present? %>\n      <div class=\"flex items-center gap-1\">\n        <%= fa(\"scale-balanced\", size: :xs) %>\n        <span><%= topic_gem.license %></span>\n      </div>\n    <% end %>\n\n    <% if topic_gem.github_repo.present? %>\n      <div class=\"flex items-center gap-1\">\n        <%= fab(\"github\", size: :xs) %>\n        <span><%= topic_gem.github_repo.split(\"/\").last %></span>\n      </div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/gems/index.html.erb",
    "content": "<div class=\"container py-8\">\n  <div class=\"flex items-center gap-2 title text-primary\">\n    <h1 class=\"flex items-center gap-2\">\n      <%= fa(\"gem\", size: :md, class: \"fill-primary\") %>\n      Ruby Gems\n    </h1>\n  </div>\n\n  <p class=\"text-gray-600 mt-2 mb-6\">\n    Browse Ruby gems featured in <%= pluralize(TopicGem.joins(:topic).sum(\"topics.talks_count\"), \"conference talk\") %>.\n  </p>\n\n  <div class=\"flex flex-wrap w-full justify-between hotwire-native:hidden py-4 gap-1\">\n    <% (\"a\"..\"z\").each do |letter| %>\n      <%= link_to gems_path(letter: letter), class: class_names(\"flex items-center justify-center w-10 text-gray-500 rounded hover:bg-brand-lighter border\", \"bg-brand-lighter\": letter == params[:letter]) do %>\n        <%= letter.upcase %>\n      <% end %>\n    <% end %>\n    <%= link_to gems_path, class: class_names(\"flex items-center justify-center w-10 text-gray-500 rounded hover:bg-brand-lighter border\", \"bg-brand-lighter\": params[:letter].blank?) do %>\n      all\n    <% end %>\n  </div>\n\n  <div id=\"gems\" class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 min-w-full\">\n    <% @gems.each do |topic_gem| %>\n      <%= render partial: \"gem_card\", locals: {topic_gem: topic_gem} %>\n    <% end %>\n  </div>\n\n  <% if @pagy.next.present? %>\n    <%= turbo_frame_tag :pagination,\n          data: {\n            controller: \"lazy-loading\",\n            lazy_loading_src_value: gems_path(letter: params[:letter], page: @pagy.next, format: :turbo_stream)\n          } %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/gems/index.turbo_stream.erb",
    "content": "<%= turbo_stream.append \"gems\" do %>\n  <% @gems.each do |topic_gem| %>\n    <%= render partial: \"gem_card\", locals: { topic_gem: topic_gem } %>\n  <% end %>\n<% end %>\n\n<% if @pagy.next.present? %>\n  <%= turbo_stream.replace :pagination do %>\n    <%= turbo_frame_tag :pagination,\n          data: {\n            controller: \"lazy-loading\",\n            lazy_loading_src_value: gems_path(letter: params[:letter], page: @pagy.next, format: :turbo_stream)\n          } %>\n  <% end %>\n<% else %>\n  <%= turbo_stream.remove :pagination %>\n<% end %>\n"
  },
  {
    "path": "app/views/gems/show.html.erb",
    "content": "<div class=\"container flex flex-col w-full gap-4 my-8\">\n  <%= link_to gems_path, class: \"hotwire-native:hidden\" do %>\n    <div class=\"flex items-center gap-2 title text-primary\">\n      <%= fa(\"arrow-left-long\", class: \"transition-arrow fill-primary\", size: :xs) %>\n      <div>Gems</div>\n    </div>\n  <% end %>\n\n  <div class=\"flex flex-col gap-4 hotwire-native:hidden\">\n    <div class=\"flex flex-wrap items-center gap-3 title text-primary\">\n      <h1 class=\"flex items-center gap-2\">\n        <%= fa(\"gem\", size: :md, class: \"fill-primary\") %>\n        <code class=\"font-mono\"><%= @gem.gem_name %></code>\n      </h1>\n\n      <% if @gem.version.present? %>\n        <span class=\"badge badge-primary badge-outline\">v<%= @gem.version %></span>\n      <% end %>\n    </div>\n\n    <div class=\"flex flex-col gap-4 p-5 bg-base-200 rounded-lg max-w-3xl\">\n      <% if @gem.summary.present? %>\n        <p class=\"text-gray-700\"><%= @gem.summary %></p>\n      <% end %>\n\n      <div class=\"flex flex-wrap items-center gap-4 text-sm text-gray-600\">\n        <% if @gem.downloads.present? %>\n          <div class=\"flex items-center gap-1.5\" title=\"Total downloads\">\n            <%= fa(\"download\", size: :xs) %>\n            <span><%= number_to_human(@gem.downloads) %> downloads</span>\n          </div>\n        <% end %>\n\n        <div class=\"flex items-center gap-1.5\" title=\"Conference talks\">\n          <%= fa(\"video\", size: :xs) %>\n          <span><%= pluralize(@topic.talks_count, \"talk\") %></span>\n        </div>\n\n        <% if @gem.version_created_at.present? %>\n          <div class=\"flex items-center gap-1.5\" title=\"Latest release\">\n            <%= fa(\"calendar\", size: :xs) %>\n            <span>Released <%= time_ago_in_words(@gem.version_created_at) %> ago</span>\n          </div>\n        <% end %>\n\n        <% if @gem.license.present? %>\n          <div class=\"flex items-center gap-1.5\" title=\"License\">\n            <%= fa(\"scale-balanced\", size: :xs) %>\n            <span><%= @gem.license %></span>\n          </div>\n        <% end %>\n      </div>\n\n      <% if @gem.github_repo.present? %>\n        <div class=\"flex items-center gap-2 text-sm\">\n          <%= fab(\"github\", size: :sm) %>\n          <%= external_link_to @gem.github_repo, @gem.github_url, class: \"link\" %>\n        </div>\n      <% end %>\n\n      <div class=\"flex flex-wrap gap-2\">\n        <%= external_link_to \"RubyGems\", @gem.rubygems_url, class: \"btn btn-sm btn-outline\" %>\n\n        <% if @gem.github_url.present? %>\n          <%= external_link_to \"GitHub\", @gem.github_url, class: \"btn btn-sm btn-outline\" %>\n        <% end %>\n\n        <% if @gem.documentation_url.present? %>\n          <%= external_link_to \"Documentation\", @gem.documentation_url, class: \"btn btn-sm btn-outline\" %>\n        <% end %>\n\n        <% if @gem.changelog_url.present? %>\n          <%= external_link_to \"Changelog\", @gem.changelog_url, class: \"btn btn-sm btn-outline\" %>\n        <% end %>\n\n        <% if @gem.bug_tracker_url.present? %>\n          <%= external_link_to \"Issues\", @gem.bug_tracker_url, class: \"btn btn-sm btn-outline\" %>\n        <% end %>\n\n        <% if @gem.homepage_url.present? && @gem.homepage_url != @gem.source_code_url && @gem.homepage_url != @gem.github_url %>\n          <%= external_link_to \"Homepage\", @gem.homepage_url, class: \"btn btn-sm btn-outline\" %>\n        <% end %>\n\n        <% if @gem.funding_url.present? %>\n          <%= external_link_to \"Sponsor\", @gem.funding_url, class: \"btn btn-sm btn-outline\" %>\n        <% end %>\n\n        <%= link_to topic_path(@topic), class: \"btn btn-sm btn-primary btn-outline\" do %>\n          View Topic: <%= @topic.name %>\n        <% end %>\n      </div>\n\n      <% if @gem.runtime_dependencies.any? %>\n        <details class=\"text-sm\">\n          <summary class=\"cursor-pointer text-gray-600 hover:text-gray-800\">\n            <%= pluralize(@gem.runtime_dependencies.size, \"runtime dependency\") %>\n          </summary>\n\n          <div class=\"mt-2 flex flex-wrap gap-1\">\n            <% @gem.runtime_dependencies.each do |dep| %>\n              <span class=\"badge badge-ghost badge-sm\"><%= dep[\"name\"] %></span>\n            <% end %>\n          </div>\n        </details>\n      <% end %>\n    </div>\n  </div>\n\n  <% maintainers = @gem.maintainers %>\n\n  <% if maintainers.any? %>\n    <section class=\"flex flex-col w-full gap-4 mt-4\">\n      <h2 class=\"text-xl font-semibold\">Gem Authors on RubyEvents.org</h2>\n\n      <div class=\"flex flex-wrap gap-4\">\n        <% maintainers.each do |user| %>\n          <%= link_to profile_path(user), class: \"w-48 sm:w-64 flex relative bg-white rounded-xl border h-full hover:border-primary hover:shadow-sm transition-all\", data: {turbo_frame: \"_top\"} do %>\n            <div class=\"card card-compact w-full pt-6\">\n              <figure class=\"flex justify-center\">\n                <%= ui_avatar(user, size_class: \"w-32 sm:w-40\", size: :lg) %>\n              </figure>\n\n              <div class=\"card-body items-center text-center pt-4 px-0 justify-center\">\n                <h3 class=\"text-xl font-semibold text-slate-700\"><%= user.name %></h3>\n                <div class=\"text-slate-600\"><%= pluralize(user.talks_count, \"talk\") %></div>\n              </div>\n            </div>\n          <% end %>\n        <% end %>\n      </div>\n    </section>\n  <% end %>\n\n  <div class=\"flex items-center justify-between mt-4\">\n    <h2 class=\"text-xl font-semibold\">Latest talks about <code class=\"font-mono bg-base-200 px-1.5 py-0.5 rounded text-lg\"><%= @gem.gem_name %></code></h2>\n\n    <% if @topic.talks_count.to_i > 8 %>\n      <%= link_to talks_gem_path(gem_name: @gem.gem_name), class: \"link text-primary flex items-center gap-1\" do %>\n        View all <%= @topic.talks_count %> talks\n        <%= fa(\"arrow-right\", size: :xs) %>\n      <% end %>\n    <% end %>\n  </div>\n\n  <div\n    id=\"gem-talks\"\n    class=\"grid min-w-full grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4 gallery\">\n    <%= render partial: \"talks/card\",\n          collection: @talks,\n          as: :talk,\n          locals: {\n            favoritable: true,\n            user_favorite_talks_ids: @user_favorite_talks_ids,\n            user_watched_talks: user_watched_talks,\n            back_to: gem_path(gem_name: @gem.gem_name),\n            back_to_title: @gem.gem_name\n          } %>\n  </div>\n\n  <% if @topic.talks_count.to_i > 8 %>\n    <div class=\"flex justify-center mt-4\">\n      <%= link_to talks_gem_path(gem_name: @gem.gem_name), class: \"btn btn-primary btn-outline\" do %>\n        View all <%= @topic.talks_count %> talks about <code class=\"font-mono\"><%= @gem.gem_name %></code>\n      <% end %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/gems/talks.html.erb",
    "content": "<div class=\"container flex flex-col w-full gap-4 my-8\">\n  <%= link_to gem_path(gem_name: @gem.gem_name), class: \"hotwire-native:hidden\" do %>\n    <div class=\"flex items-center gap-2 title text-primary\">\n      <%= fa(\"arrow-left-long\", class: \"transition-arrow fill-primary\", size: :xs) %>\n      <code class=\"font-mono\"><%= @gem.gem_name %></code>\n    </div>\n  <% end %>\n\n  <div class=\"flex items-center gap-3 title text-primary hotwire-native:hidden\">\n    <h1 class=\"flex items-center gap-2\">\n      <%= fa(\"gem\", size: :md, class: \"fill-primary\") %>\n      Talks about the <code class=\"font-mono bg-base-200 px-1.5 py-0.5 rounded\"><%= @gem.gem_name %></code> gem\n    </h1>\n    <span class=\"badge badge-ghost\"><%= @topic.talks_count %></span>\n  </div>\n\n  <div\n    id=\"gem-talks\"\n    class=\"grid min-w-full grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4 gallery\">\n    <%= render partial: \"talks/card\",\n          collection: @talks,\n          as: :talk,\n          locals: {\n            favoritable: true,\n            user_favorite_talks_ids: @user_favorite_talks_ids,\n            user_watched_talks: user_watched_talks,\n            back_to: talks_gem_path(gem_name: @gem.gem_name),\n            back_to_title: @gem.gem_name\n          } %>\n  </div>\n\n  <% if @pagy.next.present? %>\n    <%= turbo_frame_tag :pagination,\n          data: {\n            controller: \"lazy-loading\",\n            lazy_loading_src_value: talks_gem_path(gem_name: @gem.gem_name, page: @pagy.next, format: :turbo_stream)\n          } %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/gems/talks.turbo_stream.erb",
    "content": "<%= turbo_stream.append \"gem-talks\" do %>\n  <%= render partial: \"talks/card\",\n        collection: @talks,\n        as: :talk,\n        locals: {\n          favoritable: true,\n          user_favorite_talks_ids: @user_favorite_talks_ids,\n          user_watched_talks: user_watched_talks,\n          back_to: talks_gem_path(gem_name: @gem.gem_name),\n          back_to_title: @gem.gem_name\n        } %>\n<% end %>\n\n<% if @pagy.next.present? %>\n  <%= turbo_stream.replace :pagination do %>\n    <%= turbo_frame_tag :pagination,\n          data: {\n            controller: \"lazy-loading\",\n            lazy_loading_src_value: talks_gem_path(gem_name: @gem.gem_name, page: @pagy.next, format: :turbo_stream)\n          } %>\n  <% end %>\n<% else %>\n  <%= turbo_stream.remove :pagination %>\n<% end %>\n"
  },
  {
    "path": "app/views/home/index.html.erb",
    "content": "<p style=\"color: green\"><%= notice %></p>\n\n<p>Signed as <%= Current.user.email %></p>\n\n<h2>Login and verification</h2>\n\n<div>\n  <%= link_to \"Change password\", edit_password_path %>\n</div>\n\n<div>\n  <%= link_to \"Change email address\", edit_identity_email_path %>\n</div>\n\n<h2>Access history</h2>\n\n<div>\n  <%= link_to \"Devices & Sessions\", sessions_path %>\n</div>\n\n<br>\n\n<%= button_to \"Log out\", Current.session, method: :delete %>\n"
  },
  {
    "path": "app/views/hover_cards/events/_content.html.erb",
    "content": "<%# locals: (event:) %>\n<% featured_bg = event.static_metadata.featured_background.presence || \"#1f2937\" %>\n<% featured_color = event.static_metadata.featured_color.presence || \"#ffffff\" %>\n\n<div class=\"rounded-2xl overflow-hidden\" style=\"background: <%= featured_bg %>; color: <%= featured_color %>;\">\n  <div class=\"p-6 pb-0\">\n    <div class=\"aspect-[615/350] overflow-hidden rounded-xl\">\n      <%= image_tag event.featured_image_path, alt: event.name, class: \"w-full h-full object-cover\", loading: \"lazy\" %>\n    </div>\n  </div>\n\n  <div class=\"p-5 pt-4\">\n    <div>\n      <p class=\"font-bold text-sm leading-tight line-clamp-2\"><%= event.name %></p>\n      <p class=\"text-xs opacity-75 mt-1\"><%= event.formatted_dates %></p>\n    </div>\n\n    <div class=\"mt-3 pt-3 border-t flex items-center justify-between\" style=\"border-color: <%= featured_color %>20;\">\n      <div class=\"flex items-center gap-1.5 text-xs min-w-0 flex-1\">\n        <%= fa \"location-dot\", class: \"text-[10px] shrink-0\" %>\n        <span class=\"truncate\"><%= event.to_location.to_html(show_links: false) %></span>\n      </div>\n\n      <% if event.keynote_speakers.any? %>\n        <div class=\"flex gap-1\">\n          <% event.keynote_speakers.first(4).each do |speaker| %>\n            <% if speaker.github_handle.present? %>\n              <div class=\"w-6 h-6 rounded-full overflow-hidden ring-2 ring-current/20\">\n                <%= image_tag \"https://avatars.githubusercontent.com/#{speaker.github_handle}?s=48\", alt: speaker.name, class: \"w-full h-full object-cover\", loading: \"lazy\" %>\n              </div>\n            <% end %>\n          <% end %>\n        </div>\n      <% end %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/hover_cards/events/show.html.erb",
    "content": "<%= turbo_frame_tag dom_id(@event, :hover_card) do %>\n  <div class=\"w-80 rounded-2xl overflow-hidden shadow-2xl\">\n    <%= render \"content\", event: @event %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/hover_cards/users/_content.html.erb",
    "content": "<%# locals: (user:, avatar_size: :sm) %>\n\n<div class=\"p-5\">\n  <div class=\"flex items-start gap-3\">\n    <%= link_to profile_path(user) do %>\n      <%= ui_avatar(user, size: avatar_size) %>\n    <% end %>\n\n    <div class=\"min-w-0 flex-1\">\n      <%= link_to profile_path(user), class: \"font-bold text-gray-900 leading-tight line-clamp-1 flex items-center gap-1.5 hover:underline\" do %>\n        <span class=\"truncate\"><%= user.name %></span>\n\n        <% if user.verified? %>\n          <%= fa(\"badge-check\", class: \"fill-blue-500 shrink-0\", size: :xs) %>\n        <% end %>\n\n        <% if user.ruby_passport_claimed? %>\n          <%= fa(\"passport\", class: \"fill-orange-800 shrink-0\", size: :xs) %>\n        <% end %>\n      <% end %>\n\n      <div class=\"text-sm text-gray-500 truncate\">\n        <% if user.github_handle.present? %>\n          @<%= user.github_handle %>\n        <% elsif user.bsky.present? %>\n          @<%= user.bsky %>\n        <% else %>\n          @<%= user.slug %>\n        <% end %>\n      </div>\n\n      <% if user.to_location.present? %>\n        <div class=\"flex items-center gap-1 text-xs text-gray-500 mt-1\">\n          <%= fa \"location-dot\", size: :xs, class: \"text-gray-400\" %>\n          <span><%= user.to_location.to_html %></span>\n        </div>\n      <% end %>\n    </div>\n  </div>\n\n  <% if user.bio.present? %>\n    <p class=\"text-xs text-gray-600 mt-3 line-clamp-2\"><%= user.bio %></p>\n  <% end %>\n\n  <% if user.talks_count > 0 || user.events.any? %>\n    <div class=\"mt-3 pt-3 border-t border-gray-100 flex items-center justify-between\">\n      <div class=\"flex items-center gap-3 text-xs text-gray-500\">\n        <% if user.talks_count > 0 %>\n          <span class=\"flex items-center gap-1\">\n            <%= fa \"video\", size: :xs, class: \"text-gray-400\" %>\n            <%= pluralize(user.talks_count, \"talk\") %>\n          </span>\n        <% elsif user.events.any? %>\n          <span class=\"flex items-center gap-1\">\n            <%= fa \"calendar\", size: :xs, class: \"text-gray-400\" %>\n            <%= pluralize(user.events.count, \"event\") %> attended\n          </span>\n        <% end %>\n      </div>\n\n      <% if user.events.any? %>\n        <div class=\"flex -space-x-1\">\n          <% user.events.limit(3).each do |event| %>\n            <% if event.avatar_image_path %>\n              <%= link_to event_path(event), class: \"block w-5 h-5 rounded overflow-hidden ring-2 ring-white hover:ring-primary transition-all\", data: {controller: \"tooltip\", tooltip_content_value: event.name} do %>\n                <%= image_tag event.avatar_image_path, alt: event.name, class: \"w-full h-full object-cover\", loading: \"lazy\" %>\n              <% end %>\n            <% end %>\n          <% end %>\n        </div>\n      <% end %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/hover_cards/users/show.html.erb",
    "content": "<%= turbo_frame_tag dom_id(@user, :hover_card) do %>\n  <div class=\"w-80 rounded-2xl shadow-2xl bg-white border border-gray-200\">\n    <%= render \"content\", user: @user, avatar_size: @avatar_size %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/identity/emails/edit.html.erb",
    "content": "<p style=\"color: red\"><%= alert %></p>\n\n<% if Current.user.verified? %>\n  <h1>Change your email</h1>\n<% else %>\n  <h1>Verify your email</h1>\n  <p>We sent a verification email to the address below. Check that email and follow those instructions to confirm it's your email address.</p>\n  <p><%= button_to \"Re-send verification email\", identity_email_verification_path %></p>\n<% end %>\n\n<%= form_with(url: identity_email_path, method: :patch) do |form| %>\n  <% if @user.errors.any? %>\n    <div style=\"color: red\">\n      <h2><%= pluralize(@user.errors.count, \"error\") %> prohibited this user from being saved:</h2>\n\n      <ul>\n        <% @user.errors.each do |error| %>\n          <li><%= error.full_message %></li>\n        <% end %>\n      </ul>\n    </div>\n  <% end %>\n\n  <div>\n    <%= form.label :email, \"New email\", style: \"display: block\" %>\n    <%= form.email_field :email, required: true, autofocus: true %>\n  </div>\n\n  <div>\n    <%= form.label :password_challenge, style: \"display: block\" %>\n    <%= form.password_field :password_challenge, required: true, autocomplete: \"current-password\" %>\n  </div>\n\n  <div>\n    <%= form.submit \"Save changes\" %>\n  </div>\n<% end %>\n\n<br>\n\n<div>\n  <%= link_to \"Back\", root_path %>\n</div>\n"
  },
  {
    "path": "app/views/identity/password_resets/edit.html.erb",
    "content": "<h1>Reset your password</h1>\n\n<%= form_with(url: identity_password_reset_path, method: :patch) do |form| %>\n  <% if @user.errors.any? %>\n    <div style=\"color: red\">\n      <h2><%= pluralize(@user.errors.count, \"error\") %> prohibited this user from being saved:</h2>\n\n      <ul>\n        <% @user.errors.each do |error| %>\n          <li><%= error.full_message %></li>\n        <% end %>\n      </ul>\n    </div>\n  <% end %>\n\n  <%= form.hidden_field :sid, value: params[:sid] %>\n\n  <div>\n    <%= form.label :password, \"New password\", style: \"display: block\" %>\n    <%= form.password_field :password, required: true, autofocus: true, autocomplete: \"new-password\" %>\n    <div>12 characters minimum.</div>\n  </div>\n\n  <div>\n    <%= form.label :password_confirmation, \"Confirm new password\", style: \"display: block\" %>\n    <%= form.password_field :password_confirmation, required: true, autocomplete: \"new-password\" %>\n  </div>\n\n  <div>\n    <%= form.submit \"Save changes\" %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/identity/password_resets/new.html.erb",
    "content": "<p style=\"color: red\"><%= alert %></p>\n\n<h1>Forgot your password?</h1>\n\n<%= form_with(url: identity_password_reset_path) do |form| %>\n  <div>\n    <%= form.label :email, style: \"display: block\" %>\n    <%= form.email_field :email, required: true, autofocus: true %>\n  </div>\n\n  <div>\n    <%= form.submit \"Send password reset email\" %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/layouts/application.html.erb",
    "content": "<!DOCTYPE html>\n<html lang=\"en\" <% if hotwire_native_app? %> data-hotwire-native-app <% end %>>\n  <head>\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1<%= \",maximum-scale=1,user-scalable=0\" if hotwire_native_app? %>\">\n\n    <% if Rails.env.production? || Rails.env.staging? %>\n      <link rel=\"canonical\" href=\"<%= canonical_url %>\">\n    <% end %>\n\n    <% if Rails.env.staging? %>\n      <meta name=\"robots\" content=\"noindex, nofollow\">\n    <% end %>\n\n    <%= csrf_meta_tags %>\n    <%= csp_meta_tag %>\n\n    <%= display_meta_tags site: \"\" %>\n\n    <%= vite_client_tag %>\n    <%= combobox_style_tag %>\n    <%= vite_javascript_tag \"application\", media: \"all\", \"data-turbo-track\": \"reload\" %>\n    <%= vite_stylesheet_tag \"application.css\", media: \"all\", \"data-turbo-track\": \"reload\" %>\n\n    <% unless hotwire_native_app? %>\n      <meta name=\"view-transition\" content=\"same-origin\">\n    <% end %>\n\n    <%= favicon_link_tag \"favicon/favicon.ico\", rel: \"icon\", type: \"image/x-icon\" %>\n    <%= favicon_link_tag \"favicon/favicon-16x16.png\", rel: \"icon\", sizes: \"16x16\", type: \"image/png\" %>\n    <%= favicon_link_tag \"favicon/favicon-32x32.png\", rel: \"icon\", sizes: \"32x32\", type: \"image/png\" %>\n    <%= favicon_link_tag \"favicon/apple-touch-icon.png\", rel: \"apple-touch-icon\", type: \"image/png\" %>\n\n    <link rel=\"preconnect\" href=\"https://rsms.me/\">\n    <link rel=\"stylesheet\" href=\"https://rsms.me/inter/inter.css\">\n    <%= yield :head %>\n  </head>\n\n  <body data-controller=\"preserve-scroll\" class=\"<%= yield(:body_class) %>\">\n    <div class=\"hotwire-native:hidden\">\n      <%= render \"shared/navbar\" %>\n    </div>\n\n    <div class=\"min-h-screen\">\n      <%= yield %>\n    </div>\n\n    <%= render \"shared/footer\" %>\n    <%= render \"shared/breakpoints\" %>\n    <%= turbo_frame_tag \"modal\", target: \"_top\" %>\n    <%= render \"shared/flashes\" %>\n  </body>\n</html>\n"
  },
  {
    "path": "app/views/layouts/application.turbo_stream.erb",
    "content": "<%= turbo_stream.prepend \"flashes\", partial: \"shared/flashes\" %>\n<%= yield %>\n"
  },
  {
    "path": "app/views/layouts/mailer.html.erb",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <style>\n      /* Email styles need to be inline */\n    </style>\n  </head>\n\n  <body>\n    <%= yield %>\n  </body>\n</html>\n"
  },
  {
    "path": "app/views/layouts/mailer.text.erb",
    "content": "<%= yield %>\n"
  },
  {
    "path": "app/views/layouts/modal.html.erb",
    "content": "<%= turbo_frame_tag \"modal\" do %>\n  <%= ui_modal open: true, position: :responsive, **modal_options do %>\n    <%= yield %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/layouts/turbo_rails/frame.turbo_stream.erb",
    "content": "<%= turbo_stream.prepend \"flashes\", partial: \"shared/flashes\" %>\n<%= yield %>\n"
  },
  {
    "path": "app/views/layouts/wrapped.html.erb",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n\n    <%= csrf_meta_tags %>\n    <%= csp_meta_tag %>\n    <%= display_meta_tags site: \"\" %>\n\n    <%= vite_stylesheet_tag \"application.css\", media: \"all\" %>\n    <%= vite_javascript_tag \"application\" %>\n\n    <style>\n      .wrapped-page {\n        width: 100%;\n        max-width: 400px;\n        min-height: 600px;\n        margin: 0 auto 2rem;\n        padding: 2rem;\n        background: white;\n        border: 2px solid #ddd;\n        border-radius: 8px;\n        box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n        page-break-after: always;\n        display: flex;\n        flex-direction: column;\n        overflow: hidden;\n      }\n\n      .wrapped-cover {\n        align-items: center;\n        justify-content: center;\n        text-align: center;\n        background: linear-gradient(135deg, #DC2626 0%, #991B1B 100%) !important;\n        border-color: #DC2626 !important;\n        color: white !important;\n      }\n\n      .wrapped-cover h1,\n      .wrapped-cover p {\n        color: white !important;\n      }\n\n      .stat-card {\n        background: linear-gradient(135deg, #FEF2F2 0%, #FEE2E2 100%);\n        border-radius: 12px;\n        padding: 1.5rem;\n        text-align: center;\n      }\n\n      .stat-number {\n        font-size: 3rem;\n        font-weight: 800;\n        color: #DC2626;\n        line-height: 1;\n      }\n\n      .stat-label {\n        font-size: 0.875rem;\n        color: #6B7280;\n        margin-top: 0.5rem;\n      }\n\n      .rank-list {\n        counter-reset: rank;\n      }\n\n      .rank-item {\n        display: flex;\n        align-items: center;\n        gap: 0.75rem;\n        padding: 0.5rem 0;\n        border-bottom: 1px solid #E5E7EB;\n      }\n\n      .rank-item:last-child {\n        border-bottom: none;\n      }\n\n      .rank-item::before {\n        counter-increment: rank;\n        content: \"#\" counter(rank);\n        font-weight: 700;\n        color: #DC2626;\n        min-width: 2rem;\n      }\n\n      .month-bar {\n        height: 8px;\n        background: #DC2626;\n        border-radius: 4px;\n        transition: width 0.3s ease;\n      }\n\n      .personality-badge {\n        background: linear-gradient(135deg, #DC2626 0%, #B91C1C 100%);\n        color: white;\n        padding: 1rem 2rem;\n        border-radius: 9999px;\n        font-weight: 700;\n        font-size: 1.25rem;\n        display: inline-block;\n        box-shadow: 0 4px 14px rgba(220, 38, 38, 0.4);\n      }\n\n      .highlight-box {\n        background: #FEF2F2;\n        border-left: 4px solid #DC2626;\n        padding: 1rem;\n        border-radius: 0 8px 8px 0;\n      }\n\n      .stamp-grid {\n        display: grid;\n        grid-template-columns: repeat(3, 1fr);\n        gap: 0.5rem;\n        width: 100%;\n        max-width: 100%;\n      }\n\n      .stamp-item {\n        aspect-ratio: 1;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        border: 2px dashed #E5E7EB;\n        border-radius: 8px;\n        padding: 0.25rem;\n        overflow: hidden;\n        min-width: 0;\n      }\n\n      .stamp-item img {\n        max-width: 100%;\n        max-height: 100%;\n        object-fit: contain;\n      }\n\n      @media screen {\n        body {\n          background: linear-gradient(to bottom, #991b1b 0%, #450a0a 30%, #081625 70%, #081625 100%);\n          padding: 2rem 1rem;\n          min-height: 100vh;\n        }\n      }\n\n      @media print {\n        .wrapped-page {\n          box-shadow: none;\n          border: 1px solid #ddd;\n        }\n        .no-print {\n          display: none !important;\n        }\n      }\n\n      .stories-container {\n        position: fixed;\n        inset: 0;\n        background: black;\n        z-index: 50;\n        display: flex;\n        flex-direction: column;\n      }\n\n      .stories-progress {\n        display: flex;\n        gap: 4px;\n        padding: 12px 16px;\n        background: linear-gradient(to bottom, rgba(0,0,0,0.5), transparent);\n      }\n\n      .stories-progress-bar {\n        flex: 1;\n        height: 3px;\n        background: rgba(255,255,255,0.3);\n        border-radius: 2px;\n        overflow: hidden;\n      }\n\n      .stories-progress-bar.active {\n        background: white;\n      }\n\n      .stories-content {\n        flex: 1;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        padding: 0 16px;\n        overflow: hidden;\n        position: relative;\n      }\n\n      .stories-page {\n        position: absolute;\n        width: calc(100% - 32px);\n        max-width: 400px;\n        height: calc(100% - 32px);\n        max-height: 700px;\n        background: white;\n        border-radius: 16px;\n        padding: 2rem;\n        display: flex;\n        flex-direction: column;\n        overflow: hidden;\n        visibility: hidden;\n        opacity: 0;\n        pointer-events: none;\n      }\n\n      .stories-page.active {\n        visibility: visible;\n        opacity: 1;\n        pointer-events: auto;\n      }\n\n      .stories-page.stories-cover {\n        align-items: center;\n        justify-content: center;\n        text-align: center;\n        background: linear-gradient(135deg, #DC2626 0%, #991B1B 100%) !important;\n        color: white !important;\n      }\n\n      .stories-page.stories-cover h1,\n      .stories-page.stories-cover h2,\n      .stories-page.stories-cover p {\n        color: white !important;\n      }\n\n      .stories-nav {\n        position: absolute;\n        top: 60px;\n        bottom: 80px;\n        width: 33%;\n        cursor: pointer;\n        z-index: 10;\n      }\n\n      .stories-nav-left {\n        left: 0;\n      }\n\n      .stories-nav-right {\n        right: 0;\n      }\n\n      .stories-close {\n        position: absolute;\n        top: 16px;\n        right: 16px;\n        z-index: 20;\n        color: white;\n        background: rgba(0,0,0,0.5);\n        border-radius: 50%;\n        width: 36px;\n        height: 36px;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n        cursor: pointer;\n      }\n\n      .stories-counter {\n        position: absolute;\n        bottom: 20px;\n        left: 50%;\n        transform: translateX(-50%);\n        color: white;\n        font-size: 14px;\n        background: rgba(0,0,0,0.5);\n        padding: 4px 12px;\n        border-radius: 20px;\n      }\n    </style>\n  </head>\n\n  <body>\n    <div class=\"container mx-auto\">\n      <%= yield %>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "app/views/leaderboard/_speaker.html.erb",
    "content": "<tr>\n  <td class=\"font-bold\"><%= speaker_counter + 1 %></td>\n  <td style=\"view-transition-name: <%= dom_id(speaker, :Leaderboard) if speaker_counter < 10 %>\">\n    <%= link_to profile_path(speaker) do %>\n      <div class=\"flex items-center gap-4\">\n        <%= ui_avatar(speaker) %>\n        <span class=\"link link-hover\"><%= speaker.name %></span>\n      </div>\n    <% end %>\n  </td>\n  <td style=\"view-transition-name: <%= dom_id(speaker, :Leaderboard_count) if speaker_counter < 10 %>\">\n    <%= ui_badge(speaker.talks_count_in_range, kind: :secondary, outline: true, size: :lg, class: \"min-w-10\") %>\n  </td>\n</tr>\n"
  },
  {
    "path": "app/views/leaderboard/index.html.erb",
    "content": "<div class=\"container mx-auto px-4 py-8\">\n  <h1 class=\"text-3xl font-bold mb-6\">Speaker Leaderboard</h1>\n\n  <div class=\"mb-6\">\n    <%= link_to \"All Time\", leaderboard_path(filter: \"all_time\"), class: \"btn btn-sm #{(@filter == \"all_time\") ? \"btn-primary\" : \"btn-outline\"} mr-2\" %>\n    <%= link_to \"Last 12 Months\", leaderboard_path(filter: \"last_12_months\"), class: \"btn btn-sm #{(@filter == \"last_12_months\") ? \"btn-primary\" : \"btn-outline\"}\" %>\n  </div>\n\n  <div class=\"overflow-x-auto\">\n    <table class=\"table w-full table-pin-rows\">\n      <thead>\n        <tr>\n          <th class=\"text-left\">Rank</th>\n          <th class=\"text-left\">Name</th>\n          <th class=\"text-left\">Talks</th>\n        </tr>\n      </thead>\n      <tbody>\n        <% cache [@ranked_speakers, @filter] do %>\n          <%= render partial: \"leaderboard/speaker\", collection: @ranked_speakers, as: :speaker, locals: {filter: @filter} %>\n        <% end %>\n      </tbody>\n    </table>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/online/past/index.html.erb",
    "content": "<%= render \"shared/location_past\",\n      location: @location,\n      events: @events,\n      users: @users || User.none,\n      event_map_markers: @event_map_markers || [],\n      geo_layers: @geo_layers || [],\n      nearby_users: @nearby_users || [] %>\n"
  },
  {
    "path": "app/views/online/show.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% title \"Online Ruby Events\" %>\n\n<%= render \"shared/location_header\",\n      name: @location.name,\n      subtitle: @location.to_location.to_text,\n      emoji: @location.emoji_flag,\n      stats: \"#{pluralize(@events.count, \"upcoming event\")} online\",\n      location: @location %>\n\n<div class=\"container\">\n  <div role=\"tablist\" class=\"tabs tabs-bordered mb-8 overflow-x-auto\">\n    <%= link_to online_path, role: \"tab\", class: \"tab whitespace-nowrap tab-active\" do %>\n      Overview\n    <% end %>\n\n    <%= link_to online_past_index_path, role: \"tab\", class: \"tab whitespace-nowrap\" do %>\n      Past Events\n    <% end %>\n  </div>\n</div>\n\n<div class=\"container py-8\">\n  <div class=\"grid grid-cols-1 lg:grid-cols-3 gap-8\">\n    <div class=\"lg:col-span-2\">\n      <% if @events.any? %>\n        <%= render \"shared/date_grouped_events\", events: @events, empty_message: \"No upcoming online events.\" %>\n      <% else %>\n        <div class=\"text-gray-500 py-8 text-center bg-gray-50 rounded-xl\">\n          <p class=\"mb-2\">No upcoming online events scheduled.</p>\n          <%= link_to \"View past events →\", online_past_index_path, class: \"link text-sm\" %>\n        </div>\n      <% end %>\n    </div>\n\n    <div class=\"lg:col-span-1\">\n      <div class=\"space-y-8\">\n        <div>\n          <h3 class=\"font-bold text-gray-900 mb-4\">About Online Events</h3>\n          <p class=\"text-gray-600 text-sm\">\n            Online events are virtual conferences, meetups, and workshops that you can attend from anywhere in the world.\n          </p>\n        </div>\n\n        <div>\n          <h3 class=\"font-bold text-gray-900 mb-4\">Browse by Location</h3>\n\n          <div class=\"space-y-1\">\n            <%= link_to continents_path, class: \"flex items-center gap-3 py-2 px-3 rounded-lg hover:bg-gray-50 transition-colors\" do %>\n              <span class=\"text-xl\">🌍</span>\n              <span class=\"text-gray-700\">Continents</span>\n            <% end %>\n\n            <%= link_to countries_path, class: \"flex items-center gap-3 py-2 px-3 rounded-lg hover:bg-gray-50 transition-colors\" do %>\n              <span class=\"text-xl\">🏳️</span>\n              <span class=\"text-gray-700\">Countries</span>\n            <% end %>\n\n            <%= link_to cities_path, class: \"flex items-center gap-3 py-2 px-3 rounded-lg hover:bg-gray-50 transition-colors\" do %>\n              <span class=\"text-xl\">🏙️</span>\n              <span class=\"text-gray-700\">Cities</span>\n            <% end %>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/organizations/_card.html.erb",
    "content": "<% grid_layout = defined?(grid_layout) && grid_layout %>\n<% width_class = grid_layout ? \"w-full\" : \"w-48 sm:w-64\" %>\n\n<%= link_to organization_path(organization), class: \"#{width_class} flex relative bg-white rounded-xl border h-full hover:shadow-lg hover:border-gray-300 transition-all duration-200 transform hover:-translate-y-1\", data: {turbo_frame: ((defined?(turbo_frame) && turbo_frame) ? \"_top\" : nil)} do %>\n  <div class=\"card card-compact w-full pt-6\">\n    <figure class=\"flex justify-center px-4\">\n      <% image_size_class = grid_layout ? \"w-24 h-24 sm:w-32 sm:h-32\" : \"w-32 h-32 sm:w-40 sm:h-40\" %>\n\n      <% if organization.has_logo_image? %>\n        <div class=\"<%= organization.logo_background_class %> rounded-lg p-2 border border-gray-200\">\n          <%= image_tag(\n                organization.logo_image_path,\n                alt: \"#{organization.name} logo\",\n                class: \"#{image_size_class} object-contain\",\n                loading: \"lazy\",\n                onerror: \"this.style.display='none'; this.nextElementSibling.style.display='flex';\"\n              ) %>\n\n          <div class=\"<%= image_size_class %> items-center justify-center\" style=\"display: none;\">\n            <span class=\"text-lg font-semibold text-gray-700 text-center line-clamp-3\"><%= organization.name %></span>\n          </div>\n        </div>\n      <% else %>\n        <div class=\"<%= image_size_class %> flex items-center justify-center\">\n          <span class=\"text-lg font-semibold text-gray-700 text-center line-clamp-3\"><%= organization.name %></span>\n        </div>\n      <% end %>\n    </figure>\n\n    <div class=\"card-body items-center text-center pt-4 px-0 justify-center <%= \"pb-6\" if defined?(hide_event_count) && hide_event_count %>\">\n      <h3 class=\"<%= grid_layout ? \"text-sm sm:text-base\" : \"text-xl\" %> font-semibold text-slate-700 line-clamp-1\"><%= organization.name %></h3>\n\n      <% if defined?(sponsor) && sponsor&.badge.present? %>\n        <div class=\"mt-2 mx-4 px-2 py-1 <%= grid_layout ? \"text-xs\" : \"text-sm\" %> bg-blue-600 text-white rounded-full font-medium truncate text-center max-w-full\" aria-label=\"<%= sponsor.badge %>\">\n          <%= sponsor.badge %>\n        </div>\n      <% end %>\n\n      <% unless defined?(hide_event_count) && hide_event_count %>\n        <div class=\"<%= grid_layout ? \"text-xs sm:text-sm\" : \"text-base\" %> text-slate-600\"><%= pluralize(organization.events.size, \"event\") %></div>\n      <% end %>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/organizations/_compact_card.html.erb",
    "content": "<%= link_to organization_path(organization), class: \"flex flex-col gap-4 hover:bg-gray-200 transition-bg duration-300 ease-in-out p-2 px-4 rounded-lg\", data: {turbo_frame: ((defined?(turbo_frame) && turbo_frame) ? \"_top\" : nil)} do %>\n  <div class=\"flex items-center gap-4\">\n    <% if organization.has_logo_image? %>\n      <div class=\"<%= organization.logo_background_class %> rounded-lg p-2 border <%= organization.logo_border_class %> w-12 h-12 flex items-center justify-center flex-shrink-0\">\n        <%= image_tag(\n              organization.logo_image_path,\n              alt: \"#{organization.name} logo\",\n              class: \"w-10 h-10 object-contain\",\n              loading: \"lazy\",\n              onerror: \"this.style.display='none'; this.nextElementSibling.style.display='flex';\"\n            ) %>\n        <div class=\"w-10 h-10 items-center justify-center\" style=\"display: none;\">\n          <span class=\"text-xs font-semibold text-gray-700 text-center line-clamp-2\"><%= organization.name %></span>\n        </div>\n      </div>\n    <% else %>\n      <div class=\"w-12 h-12 flex items-center justify-center flex-shrink-0 bg-gray-100 rounded-lg border border-gray-200\">\n        <span class=\"text-xs font-semibold text-gray-700 text-center line-clamp-2\"><%= organization.name[0..1].upcase %></span>\n      </div>\n    <% end %>\n\n    <div class=\"flex-1 min-w-0\">\n      <div class=\"font-bold text-base line-clamp-1\">\n        <%= organization.name %>\n      </div>\n\n      <div class=\"text-xs text-gray-500 line-clamp-1\">\n        <% if defined?(sponsor) && sponsor&.badge.present? %>\n          <%= sponsor.badge %>\n        <% elsif !defined?(hide_event_count) || !hide_event_count %>\n          <%= pluralize(organization.events.size, \"event\") %>\n        <% else %>\n          <%= organization.website&.gsub(%r{https?://}, \"\")&.gsub(%r{www\\.}, \"\")&.split(\"/\")&.first || \"-\" %>\n        <% end %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/organizations/_header.html.erb",
    "content": "<div\n  class=\"w-full md:h-[198px] lg:h-[267px] xl:h-[336px] 2xl:h-[405px] justify-center align-center flex mt-3 border-t border-b hotwire-native:hidden\"\n  style=\"\n    view-transition-name: hero;\n    <% if organization.organization_image_for(\"banner.webp\") %>\n      background: url('<%= image_path(organization.banner_image_path) %>');\n      background-repeat: no-repeat;\n      background-size: cover;\n    <% else %>\n      background: linear-gradient(135deg, #3B82F6, #10B981, #60A5FA);\n    <% end %>\n  \">\n  <% if organization.organization_image_for(\"banner.webp\") %>\n    <%= image_tag image_path(organization.banner_image_path), class: \"w-full md:container object-cover\" %>\n  <% end %>\n</div>\n\n<div class=\"container py-8\">\n  <div class=\"block lg:flex gap-8 align-center justify-between\">\n    <div class=\"flex flex-col lg:flex-row gap-8 items-center lg:justify-right text-center lg:text-left mb-6 lg:mb-0\">\n      <% if organization.has_logo_image? %>\n        <div class=\"<%= organization.logo_background_class %> rounded-lg border <%= organization.logo_border_class %> size-24 md:size-36 p-2\"\n             style=\"view-transition-name: avatar\">\n          <%= image_tag organization.logo_image_path,\n                class: \"w-full h-full object-contain\",\n                alt: \"#{organization.name} Logo\",\n                loading: :lazy,\n                onerror: \"this.style.display='none'; this.nextElementSibling.style.display='flex';\" %>\n          <div class=\"w-full h-full bg-gray-100 items-center justify-center hidden\">\n            <span class=\"text-4xl md:text-6xl font-bold text-gray-600\"><%= organization.name.first %></span>\n          </div>\n        </div>\n      <% elsif organization.organization_image_for(\"avatar.webp\") %>\n        <%= image_tag image_path(organization.avatar_image_path),\n              class: \"rounded-lg border border-[#D9DFE3] size-24 md:size-36\",\n              alt: \"#{organization.name} Avatar\",\n              style: \"view-transition-name: avatar\",\n              loading: :lazy %>\n      <% else %>\n        <div class=\"rounded-lg border border-[#D9DFE3] size-24 md:size-36 bg-gray-100 flex items-center justify-center\"\n             style=\"view-transition-name: avatar\">\n          <span class=\"text-4xl md:text-6xl font-bold text-gray-600\"><%= organization.name.first %></span>\n        </div>\n      <% end %>\n\n      <div class=\"flex-col flex justify-center break-all\">\n        <div class=\"flex items-center gap-3 mb-2\">\n          <h1 class=\"text-black font-bold\"><%= title organization.name %></h1>\n        </div>\n        <% if organization.main_location.present? %>\n          <h3 class=\"text-[#636B74]\"><%= organization.main_location %></h3>\n        <% end %>\n        <% if organization.website.present? %>\n          <%= external_link_to organization.website.gsub(%r{^https?://}, \"\").gsub(%r{/$}, \"\"), organization.website %>\n        <% end %>\n      </div>\n    </div>\n\n    <div class=\"flex flex-col gap-3 place-items-center\">\n      <%= ui_button \"Back to Organizations\", url: organizations_path, kind: :secondary, size: :sm, class: \"w-full\" %>\n      <% if Current.user&.admin? && organization.logo_urls.present? %>\n        <%= ui_button \"Manage Logos\", url: organization_logos_path(organization), kind: :primary, size: :sm, class: \"w-full\" %>\n      <% end %>\n    </div>\n  </div>\n\n  <% if organization.description.present? %>\n    <p class=\"mt-6 text-[#636B74] max-w-[700px]\">\n      <%= organization.description %>\n    </p>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/organizations/_navigation.html.erb",
    "content": "<div role=\"tablist\" class=\"mb-12 tabs tabs-bordered\">\n  <% if organization.events.any? %>\n    <%= link_to \"Supported Events\", organization_path(organization), role: \"tab\", class: \"tab tab-active\" %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/organizations/_organization.html.erb",
    "content": "<%= link_to organization_path(organization), id: dom_id(organization), class: \"flex justify-between\" do %>\n  <div class=\"flex items-center gap-2\">\n    <% if organization.has_logo_image? %>\n      <div class=\"<%= organization.logo_background_class %> size-8 rounded border border-[#D9DFE3] p-1\">\n        <%= image_tag organization.logo_image_path,\n              class: \"w-full h-full object-contain\",\n              alt: \"#{organization.name} Logo\",\n              loading: \"lazy\",\n              onerror: \"this.style.display='none'; this.nextElementSibling.style.display='flex';\" %>\n        <div class=\"avatar placeholder hidden\">\n          <div class=\"w-full h-full bg-gray-100 text-gray-600 flex items-center justify-center\">\n            <span class=\"text-sm font-bold\"><%= organization.name.split(\" \").map(&:first).join.first(2) %></span>\n          </div>\n        </div>\n      </div>\n    <% elsif organization.organization_image_for(\"avatar.webp\") %>\n      <%= image_tag image_path(organization.avatar_image_path), class: \"size-8 rounded border border-[#D9DFE3]\", loading: \"lazy\" %>\n    <% else %>\n      <div class=\"avatar placeholder\">\n        <div class=\"size-8 rounded bg-gray-100 text-gray-600 border border-[#D9DFE3] flex items-center justify-center\">\n          <span class=\"text-sm font-bold\"><%= organization.name.split(\" \").map(&:first).join.first(2) %></span>\n        </div>\n      </div>\n    <% end %>\n\n    <span class=\"line-clamp-1\"><%= organization.name %></span>\n  </div>\n\n  <%= ui_badge(organization.event_involvements.size + organization.events.size, kind: :secondary, outline: true, size: :lg, class: \"min-w-10\") %>\n<% end %>\n"
  },
  {
    "path": "app/views/organizations/index.html.erb",
    "content": "<div class=\"container py-8 hotwire-native:py-3\">\n  <h1 class=\"title hotwire-native:hidden\">\n    <%= title \"Organizations\" %>\n  </h1>\n\n  <div class=\"bg-amber-50 border border-amber-200 rounded-lg p-4 mb-8 mt-6 hotwire-native:hidden\">\n    <div class=\"flex items-start\">\n      <%= fa(\"question-circle\", size: :sm, class: \"fill-amber-600 mt-0.5 mr-3 flex-shrink-0\") %>\n      <div>\n        <h3 class=\"font-semibold text-amber-800 mb-1\">Organization data is incomplete</h3>\n        <p class=\"text-sm text-amber-700 mb-2\">\n          Many conferences are still missing sponsor information. Help us complete the database!\n        </p>\n        <%= link_to \"View conferences missing sponsor data\", sponsors_missing_index_path, class: \"text-sm font-medium text-amber-800 underline hover:text-amber-900\" %>\n      </div>\n    </div>\n  </div>\n\n  <% if @featured_organizations.present? %>\n    <% cache @featured_organizations do %>\n      <div class=\"my-8 hotwire-native:hidden\">\n        <div class=\"relative\" data-controller=\"scroll\">\n          <div class=\"overflow-x-auto scroll-smooth snap-x snap-mandatory\" data-scroll-target=\"container\" data-action=\"scroll->scroll#checkScroll\">\n            <div class=\"flex pb-4 gap-4\">\n              <% @featured_organizations.each do |organization| %>\n                <div class=\"snap-start\" data-scroll-target=\"card\">\n                  <%= render partial: \"organizations/card\", locals: {organization: organization}, cached: true %>\n                </div>\n              <% end %>\n            </div>\n          </div>\n\n          <div class=\"absolute right-0 top-0 h-full w-24 bg-gradient-to-l from-white to-transparent pointer-events-none\" data-scroll-target=\"gradient\"></div>\n        </div>\n      </div>\n    <% end %>\n  <% end %>\n\n  <div class=\"flex flex-wrap w-full justify-between py-8 hotwire-native:hidden gap-1\">\n    <% (\"a\"..\"z\").each do |letter| %>\n      <%= link_to organizations_path(letter: letter), class: class_names(\"flex items-center justify-center w-10 text-gray-500 rounded hover:bg-brand-lighter border\", \"bg-brand-lighter\": letter == params[:letter]) do %>\n        <%= letter.upcase %>\n      <% end %>\n    <% end %>\n  </div>\n\n  <div id=\"organizations\" class=\"hotwire-native:mt-3 grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-8 lg:gap-x-12 gap-y-2 min-w-full\">\n    <% cache @organizations do %>\n      <%= render partial: \"organizations/organization\", collection: @organizations, as: :organization, cached: true %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/organizations/logos/show.html.erb",
    "content": "<div class=\"container py-8\">\n  <div class=\"mb-8\">\n    <%= ui_button \"Back to #{@organization.name}\", url: @back_path, kind: :secondary, size: :sm %>\n  </div>\n\n  <div class=\"mb-12\">\n    <div class=\"flex justify-between items-center mb-6\">\n      <h1 class=\"text-3xl font-bold text-gray-900\">Manage Logos - <%= @organization.name %></h1>\n      <div class=\"flex items-center gap-6\">\n        <div class=\"flex items-center gap-3\">\n          <span class=\"text-sm text-gray-600\">Preview:</span>\n          <div class=\"<%= @organization.logo_background_class %> rounded-lg border <%= @organization.logo_border_class %> size-24 p-3 flex items-center justify-center\">\n            <% if @organization.has_logo_image? %>\n              <%= image_tag @organization.logo_image_path,\n                    class: \"w-full h-full object-contain\",\n                    alt: \"#{@organization.name} Logo Preview\",\n                    loading: \"lazy\" %>\n            <% else %>\n              <span class=\"text-lg font-bold text-gray-600\"><%= @organization.name.first %></span>\n            <% end %>\n          </div>\n        </div>\n        <div class=\"flex items-center gap-3\">\n          <span class=\"text-sm text-gray-600\">Background:</span>\n          <%= form_with model: @organization, url: organization_logos_path(@organization), method: :patch, local: true, class: \"inline-block\", data: {turbo_action: \"replace\"} do |form| %>\n            <%= form.select :logo_background, [[\"White\", \"white\"], [\"Black\", \"black\"], [\"Transparent\", \"transparent\"]],\n                  {selected: @organization.logo_background || \"white\"},\n                  {class: \"select select-sm select-bordered\", onchange: \"this.form.submit();\"} %>\n          <% end %>\n        </div>\n      </div>\n    </div>\n\n    <% if @organization.logo_urls.present? %>\n      <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\" id=\"logos-grid\">\n        <% @organization.logo_urls.each do |logo_url| %>\n          <div class=\"logo-card bg-gray-50 rounded-lg shadow-md p-4 transition-colors duration-200 <%= \"ring-2 ring-blue-500\" if @organization.logo_url == logo_url %>\">\n            <div class=\"flex justify-center mb-2 h-6\">\n              <% if @organization.logo_url == logo_url %>\n                <span class=\"inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800\">\n                  Selected\n                </span>\n              <% end %>\n            </div>\n            <div class=\"mb-4\">\n              <div class=\"logo-bg border-2 border-gray-200 rounded-lg p-4 transition-colors duration-200 <%= case @organization.logo_background when \"black\" then \"bg-black\" when \"transparent\" then \"bg-transparent\" else \"bg-white\" end %>\">\n                <%= image_tag logo_url, alt: \"#{@organization.name} logo\", class: \"max-w-full h-32 object-contain mx-auto\", loading: \"lazy\", onerror: \"this.style.display='none'; this.nextElementSibling.style.display='block';\" %>\n                <div class=\"text-center text-gray-500 hidden\">\n                  <p>Image failed to load</p>\n                </div>\n              </div>\n            </div>\n            <div class=\"text-sm text-gray-600 break-all logo-url mb-3\">\n              <a href=\"<%= logo_url %>\" target=\"_blank\" class=\"text-blue-600 hover:text-blue-800 underline\">\n                <%= logo_url %>\n              </a>\n            </div>\n            <% if @organization.logo_url == logo_url %>\n              <div class=\"text-center\">\n                <button class=\"btn btn-sm btn-disabled\" disabled>Selected</button>\n              </div>\n            <% else %>\n              <%= form_with model: @organization, url: organization_logos_path(@organization), method: :patch, local: true, class: \"text-center\", data: {turbo_action: \"replace\"} do |form| %>\n                <%= form.hidden_field :logo_url, value: logo_url %>\n                <%= form.submit \"Select Logo\", class: \"btn btn-sm btn-outline btn-primary\" %>\n              <% end %>\n            <% end %>\n          </div>\n        <% end %>\n      </div>\n    <% else %>\n      <div class=\"text-center py-12 text-gray-500\">\n        <p class=\"text-lg\">No logo URLs found.</p>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/organizations/show.html.erb",
    "content": "<%= render partial: \"header\", locals: {organization: @organization} %>\n\n<%= turbo_frame_tag dom_id(@organization), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n  <div class=\"container py-8\">\n    <% if @events_by_year.any? || @involved_events.any? %>\n      <div role=\"tablist\" class=\"tabs tabs-bordered mt-6\">\n        <input type=\"radio\" name=\"organization_tabs\" role=\"tab\" class=\"tab px-6\" aria-label=\"Supported Events (<%= @events.size %>)\" <% if @events.size > 0 %> checked <% end %>>\n\n        <div role=\"tabpanel\" class=\"tab-content mt-6\">\n          <% @events_by_year.each do |year, events| %>\n            <div class=\"mb-12\">\n              <h2 class=\"text-2xl font-bold text-gray-900 mb-6\">\n                <%= year %>\n              </h2>\n              <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6\">\n                <%= cache events do %>\n                  <%= render partial: \"events/card\", collection: events, as: :event, cached: true %>\n                <% end %>\n              </div>\n            </div>\n          <% end %>\n        </div>\n\n        <% if @involvements_by_role.any? %>\n          <input type=\"radio\" name=\"organization_tabs\" role=\"tab\" class=\"tab px-6\" aria-label=\"Involvements (<%= @involved_events.size %>)\" <% if @events.size <= 0 && @involvements_by_role.any? %> checked <% end %>>\n\n          <div role=\"tabpanel\" class=\"tab-content mt-6\">\n            <% @involvements_by_role.each do |role, involvements| %>\n              <div class=\"mb-12\">\n                <h3 class=\"text-xl font-bold text-gray-900 mb-6\"><%= role %></h3>\n                <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6\">\n                  <% involvements.each do |involvement| %>\n                    <%= render partial: \"events/card\", locals: {event: involvement.event} %>\n                  <% end %>\n                </div>\n              </div>\n            <% end %>\n          </div>\n        <% end %>\n\n        <% if @countries_with_events.any? %>\n          <input type=\"radio\" name=\"organization_tabs\" role=\"tab\" class=\"tab px-6\" aria-label=\"Map (<%= @countries_with_events.size %>)\">\n\n          <div role=\"tabpanel\" class=\"tab-content mt-6\">\n            <div class=\"space-y-8\">\n              <% @countries_with_events.group_by { |country, _| country.continent_name }.sort_by(&:first).each do |continent, countries_group| %>\n                <div>\n                  <h3 class=\"text-lg font-semibold mb-4\"><%= continent %></h3>\n                  <div class=\"grid sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n                    <% countries_group.each do |country, events| %>\n                      <%= render \"shared/country_card\", country: country, events: events %>\n                    <% end %>\n                  </div>\n                </div>\n              <% end %>\n            </div>\n          </div>\n        <% end %>\n\n        <input type=\"radio\" name=\"organization_tabs\" role=\"tab\" class=\"tab px-6\" aria-label=\"Statistics\">\n\n        <div role=\"tabpanel\" class=\"tab-content mt-6\">\n          <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6\">\n            <div class=\"stats stats-vertical bg-white border\">\n              <div class=\"stat\">\n                <div class=\"stat-title\">Total Events Sponsored</div>\n                <div class=\"stat-value text-primary\"><%= @statistics[:total_events] %></div>\n                <div class=\"stat-desc\">\n                  <% if @statistics[:first_sponsorship] && @statistics[:latest_sponsorship] %>\n                    <%= @statistics[:first_sponsorship].year %> - <%= @statistics[:latest_sponsorship].year %>\n                  <% end %>\n                </div>\n              </div>\n            </div>\n\n            <div class=\"stats stats-vertical bg-white border\">\n              <div class=\"stat\">\n                <div class=\"stat-title\">Geographic Reach</div>\n                <div class=\"stat-value text-secondary\"><%= @statistics[:total_countries] %></div>\n                <div class=\"stat-desc\"><%= pluralize(@statistics[:total_continents], \"continent\") %></div>\n              </div>\n            </div>\n\n            <div class=\"stats stats-vertical bg-white border\">\n              <div class=\"stat\">\n                <div class=\"stat-title\">Talks at Sponsored Events</div>\n                <div class=\"stat-value\"><%= @statistics[:total_talks] %></div>\n                <div class=\"stat-desc\">Supporting knowledge sharing</div>\n              </div>\n            </div>\n\n            <div class=\"stats stats-vertical bg-white border\">\n              <div class=\"stat\">\n                <div class=\"stat-title\">Event Series</div>\n                <div class=\"stat-value\"><%= @statistics[:total_series] %></div>\n                <div class=\"stat-desc\">Unique partnerships</div>\n              </div>\n            </div>\n\n            <% if @statistics[:years_active].any? %>\n              <div class=\"stats stats-vertical bg-white border\">\n                <div class=\"stat\">\n                  <div class=\"stat-title\">Years Active</div>\n                  <div class=\"stat-value\"><%= @statistics[:years_active].size %></div>\n                  <div class=\"stat-desc\">\n                    <%= @statistics[:years_active].first %> - <%= @statistics[:years_active].last %>\n                  </div>\n                </div>\n              </div>\n            <% end %>\n\n            <% if @statistics[:sponsorship_tiers].any? %>\n              <div class=\"card bg-white border\">\n                <div class=\"card-body\">\n                  <h3 class=\"card-title text-lg\">Sponsorship Tiers</h3>\n                  <div class=\"space-y-2\">\n                    <% @statistics[:sponsorship_tiers].each do |tier, count| %>\n                      <div class=\"flex justify-between items-center\">\n                        <span class=\"capitalize\"><%= tier || \"Standard\" %></span>\n                        <span class=\"badge badge-outline\"><%= count %></span>\n                      </div>\n                    <% end %>\n                  </div>\n                </div>\n              </div>\n            <% end %>\n\n            <% if @statistics[:events_by_size].any? %>\n              <div class=\"card bg-white border\">\n                <div class=\"card-body\">\n                  <h3 class=\"card-title text-lg\">Event Scale</h3>\n                  <div class=\"space-y-2\">\n                    <% [\"Flagship Event\", \"Major Conference\", \"Regional Conference\", \"Community Gathering\", \"Retreat\", \"Upcoming Event\", \"Event Awaiting Content\"].each do |size| %>\n                      <% if @statistics[:events_by_size][size] %>\n                        <div class=\"flex justify-between items-center\">\n                          <div class=\"flex items-center gap-2\">\n                            <span class=\"text-sm\">\n                              <% case size %>\n                              <% when \"Flagship Event\" %>\n                                🏆\n                              <% when \"Major Conference\" %>\n                                🎯\n                              <% when \"Regional Conference\" %>\n                                🌍\n                              <% when \"Community Gathering\" %>\n                                🤝\n                              <% when \"Upcoming Event\" %>\n                                📅\n                              <% when \"Event Awaiting Content\" %>\n                                ⏳\n                              <% end %>\n                            </span>\n                            <span><%= size %></span>\n                          </div>\n                          <span class=\"badge badge-outline\"><%= @statistics[:events_by_size][size] %></span>\n                        </div>\n                      <% end %>\n                    <% end %>\n                  </div>\n                </div>\n              </div>\n            <% end %>\n          </div>\n\n          <% if @statistics[:events_by_series].any? %>\n            <div class=\"mt-6\">\n              <h3 class=\"text-lg font-semibold mb-4\">Top Supported Event Series</h3>\n              <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-4\">\n                <% @statistics[:events_by_series].each do |org, count| %>\n                  <div class=\"card card-compact bg-white border\">\n                    <div class=\"card-body\">\n                      <%= link_to series_path(org), class: \"hover:underline\", data: {turbo_frame: \"_top\"} do %>\n                        <h4 class=\"font-semibold text-sm\"><%= org.name %></h4>\n                      <% end %>\n                      <p class=\"text-sm text-gray-500\"><%= pluralize(count, \"event\") %></p>\n                    </div>\n                  </div>\n                <% end %>\n              </div>\n            </div>\n          <% end %>\n\n          <% if @statistics[:badges_with_events].any? %>\n            <div class=\"mt-6\">\n              <h3 class=\"text-lg font-semibold mb-4\">Additional Sponsorships</h3>\n              <div class=\"space-y-2\">\n                <% @statistics[:badges_with_events].each do |badge, event| %>\n                  <div class=\"flex items-center gap-2\">\n                    <span class=\"badge badge-lg badge-primary\"><%= badge %></span>\n                    <span class=\"text-sm text-gray-600\">at</span>\n                    <%= link_to event.name, event_path(event), class: \"text-sm hover:underline\", data: {turbo_frame: \"_top\"} %>\n                    <span class=\"text-sm text-gray-500\">(<%= event.start_date&.year %>)</span>\n                  </div>\n                <% end %>\n              </div>\n            </div>\n          <% end %>\n        </div>\n      </div>\n    <% else %>\n      <div class=\"text-center py-12 text-gray-500\">\n        <p class=\"text-lg\">No supported events yet.</p>\n      </div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/organizations/wrapped/index.html.erb",
    "content": "<div class=\"min-h-screen bg-[linear-gradient(to_bottom,#991b1b_0%,#450a0a_30%,#081625_70%,#081625_100%)]\">\n  <div class=\"max-w-4xl mx-auto px-4 py-12\">\n    <div class=\"text-center text-white mb-12\">\n      <% if @organization.logo_url.present? %>\n        <%= link_to organization_path(@organization), class: \"block w-24 h-24 mx-auto mb-4 rounded-xl overflow-hidden bg-white p-2 hover:scale-105 transition\" do %>\n          <%= image_tag @organization.logo_url, class: \"w-full h-full object-contain\", alt: @organization.name %>\n        <% end %>\n      <% end %>\n\n      <%= link_to organization_path(@organization), class: \"text-lg text-red-300 hover:text-white transition\" do %>\n        <%= @organization.name %>\n      <% end %>\n      <p class=\"text-red-300/60 text-sm mt-1\" style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">RubyEvents.org</p>\n      <h1 class=\"text-6xl font-black text-white mt-2\" style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\"><%= @year %></h1>\n      <p class=\"text-3xl font-bold text-red-200 mt-1\" style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">Wrapped</p>\n      <p class=\"text-xl text-red-100 max-w-lg mx-auto mt-6\">\n        <% if @years_supporting > 1 %>\n          <%= @years_supporting %> years of supporting the Ruby community\n        <% else %>\n          A year of supporting the Ruby community\n        <% end %>\n      </p>\n    </div>\n\n    <% if @total_events_sponsored.positive? %>\n      <div class=\"grid grid-cols-2 md:grid-cols-4 gap-4 mb-8\">\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center\">\n          <p class=\"text-4xl font-black text-white\"><%= @total_events_sponsored %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Events Supported</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@talks_at_sponsored_events) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Talks Supported</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@speakers_at_sponsored_events) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Speakers Supported</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center\">\n          <p class=\"text-4xl font-black text-white\"><%= @countries_sponsored.count %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Countries Reached</p>\n        </div>\n      </div>\n\n      <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 mb-8\">\n        <h3 class=\"text-lg font-bold text-white mb-4\">🎪 Events Supported</h3>\n        <div class=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4\">\n          <% @sponsored_events.each do |event| %>\n            <%= link_to event_path(event), class: \"group\" do %>\n              <div class=\"aspect-video rounded-lg overflow-hidden mb-2\">\n                <%= image_tag event.card_image_path, class: \"w-full h-full object-cover group-hover:scale-105 transition\", alt: event.name %>\n              </div>\n              <p class=\"text-white font-medium text-sm group-hover:text-red-200 transition truncate\"><%= event.name %></p>\n              <p class=\"text-red-300 text-xs\">\n                <%= event.start_date&.strftime(\"%B\") %>\n                <% if event.country.present? %>\n                  · <%= event.country.emoji_flag %>\n                <% end %>\n              </p>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n\n      <% if @sponsor_tiers.any? %>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 mb-8\">\n          <h3 class=\"text-lg font-bold text-white mb-4\">🏆 Sponsorship Tiers</h3>\n          <div class=\"flex flex-wrap gap-3\">\n            <% @sponsor_tiers.each do |tier, count| %>\n              <span class=\"inline-flex items-center gap-2 px-4 py-2 bg-white/10 rounded-full text-white\">\n                <span class=\"font-medium capitalize\"><%= tier %></span>\n                <span class=\"text-red-300\"><%= count %></span>\n              </span>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n\n      <% if @countries_sponsored.any? %>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 mb-8\">\n          <h3 class=\"text-lg font-bold text-white mb-4\">🌍 Global Reach</h3>\n          <div class=\"flex flex-wrap gap-2\">\n            <% @countries_sponsored.sort_by(&:name).each do |country| %>\n              <%= link_to country.path, class: \"inline-flex items-center gap-1 px-3 py-1 bg-white/10 rounded-full text-sm text-white hover:bg-white/20 transition\" do %>\n                <%= country.emoji_flag %> <%= country.name %>\n              <% end %>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    <% else %>\n      <div class=\"bg-white/10 backdrop-blur rounded-xl p-8 text-center\">\n        <p class=\"text-red-200\">No sponsorship data for <%= @year %> yet.</p>\n      </div>\n    <% end %>\n\n    <% if @involvements.any? %>\n      <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 mb-8\">\n        <h3 class=\"text-lg font-bold text-white mb-4\">🤝 Community Involvement</h3>\n        <div class=\"space-y-4\">\n          <% @involvements_by_role.each do |role, involvements| %>\n            <div>\n              <p class=\"text-red-300 text-sm font-medium mb-2 capitalize\"><%= role %></p>\n              <div class=\"flex flex-wrap gap-2\">\n                <% involvements.each do |involvement| %>\n                  <%= link_to event_path(involvement.event), class: \"inline-flex items-center px-3 py-1 bg-white/10 rounded-full text-sm text-white hover:bg-white/20 transition\" do %>\n                    <%= involvement.event.name %>\n                  <% end %>\n                <% end %>\n              </div>\n            </div>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n\n    <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center\">\n      <h3 class=\"text-lg font-bold text-white mb-4\">Share Your Impact</h3>\n      <div class=\"space-y-3 max-w-xs mx-auto\">\n        <%= link_to og_image_organization_wrapped_index_path(organization_slug: @organization.slug, download: 1),\n              data: {turbo: false},\n              class: \"flex items-center justify-center gap-3 w-full p-3 bg-red-600 text-white rounded-lg hover:bg-red-700 transition cursor-pointer\" do %>\n          <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" /></svg>\n          <span class=\"font-medium\">Download Summary Card</span>\n        <% end %>\n\n        <div data-controller=\"copy-to-clipboard\" data-copy-to-clipboard-success-message-value=\"✓ Copied!\">\n          <span data-copy-to-clipboard-target=\"source\" class=\"hidden\"><%= @share_url %></span>\n          <button data-action=\"copy-to-clipboard#copy\" data-copy-to-clipboard-target=\"button\" class=\"flex items-center justify-center gap-3 w-full p-3 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition\">\n            <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" /></svg>\n            <span class=\"font-medium\">Copy Link</span>\n          </button>\n        </div>\n      </div>\n    </div>\n\n    <div class=\"text-center mt-12\">\n      <p class=\"text-red-200 text-sm mb-4\">\n        Thank you, <%= @organization.name %>, for supporting the Ruby community! 💎\n      </p>\n\n      <%= link_to wrapped_path, class: \"inline-flex items-center gap-2 px-6 py-3 bg-white/10 hover:bg-white/20 text-white rounded-full font-medium transition\" do %>\n        <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\" /></svg>\n\n        View Your <%= @year %> Wrapped\n      <% end %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/organizations/wrapped/pages/_summary_card_horizontal.html.erb",
    "content": "<div class=\"flex-1 flex gap-12 items-center px-12 pt-8 pb-4\">\n  <div class=\"flex flex-col items-center\">\n    <% if organization.logo_url.present? %>\n      <div class=\"w-32 h-32 rounded-2xl overflow-hidden bg-white p-3 mb-6\">\n        <%= image_tag organization.logo_url, class: \"w-full h-full object-contain\", alt: organization.name %>\n      </div>\n    <% end %>\n    <p class=\"text-red-300 text-lg\"><%= organization.name %></p>\n    <h1 class=\"text-6xl font-black text-white mt-2\"><%= year %></h1>\n    <p class=\"text-3xl font-bold text-red-200 mt-1\">Wrapped</p>\n    <p class=\"text-red-300/80 text-sm mt-4\">RubyEvents.org/Wrapped</p>\n  </div>\n\n  <div class=\"flex-1 grid grid-cols-2 gap-6\">\n    <div class=\"bg-white/10 backdrop-blur rounded-2xl p-8 text-center\">\n      <p class=\"text-6xl font-black text-white\"><%= total_events_sponsored %></p>\n      <p class=\"text-red-200 text-lg mt-2\">Events Supported</p>\n    </div>\n    <div class=\"bg-white/10 backdrop-blur rounded-2xl p-8 text-center\">\n      <p class=\"text-6xl font-black text-white\"><%= number_with_delimiter(talks_at_sponsored_events) %></p>\n      <p class=\"text-red-200 text-lg mt-2\">Talks Supported</p>\n    </div>\n    <div class=\"bg-white/10 backdrop-blur rounded-2xl p-8 text-center\">\n      <p class=\"text-6xl font-black text-white\"><%= number_with_delimiter(speakers_at_sponsored_events) %></p>\n      <p class=\"text-red-200 text-lg mt-2\">Speakers Supported</p>\n    </div>\n    <div class=\"bg-white/10 backdrop-blur rounded-2xl p-8 text-center\">\n      <p class=\"text-6xl font-black text-white\"><%= countries_sponsored.count %></p>\n      <p class=\"text-red-200 text-lg mt-2\">Countries Reached</p>\n    </div>\n  </div>\n</div>\n\n<div class=\"w-full bg-white/5 py-3 mt-4 flex items-center justify-center gap-3\">\n  <%= image_tag \"logo.png\", class: \"w-6 h-6\", alt: \"RubyEvents.org\" %>\n  <span class=\"text-white font-bold text-lg\">RubyEvents.org</span>\n  <span class=\"text-red-300/80 text-sm\">On a mission to index all Ruby events</span>\n</div>\n"
  },
  {
    "path": "app/views/page/about.md",
    "content": "# About\n\n**tl;dr:** Originally launched as **RubyVideo.dev**, the project has been rebranded as **RubyEvents.org** to better reflect its expanded mission.\n\n## Mission\n\n**RubyEvents.org** aims to index all Ruby events and video talks, making them searchable, accessible, and easier to discover for the Ruby community.\n\n## RubyVideo (2023-2025)\n\nRubyVideo was [launched in June 2023](https://x.com/adrienpoly/status/1669944383049801730) by [Adrien Poly](https://github.com/adrienpoly) to help Ruby developers easily find and watch Ruby-related videos. The project was initially inspired by [PyVideo.org](https://pyvideo.org/) and featured around 800 videos upon its first release.\n\n## RubyEvents\n\n[Marco Roth](https://github.com/marcoroth), maintainer of [RubyConferences.org](https://rubyconferences.org/), significantly [contributed](https://github.com/adrienpoly/rubyvideo/graphs/contributors) to RubyVideo by providing extensive new content and innovative ideas. Marco's vision revealed the project's potential extended far beyond simply indexing videos, prompting the merger of **RubyConferences.org** and **RubyVideo.dev** into **RubyEvents.org**.\n\nAs of today more than 8000+ talks from 3000+ speakers are indexed.\n\n## Open Source\n\nfrom the very beginning the project has been open source. It aims to showcase some of the Ruby on Rails tech stack and to be a source of inspiration for other Ruby projects.\n\nRubyEvents.org is entirely open-source and distributed under the [MIT License](https://opensource.org/licenses/MIT). Contributions of any kind from adding new events to enhancing documentation are warmly welcomed and highly appreciated.\n\n## Maintainers\n\nRubyEvents.org is jointly maintained by:\n\n* [Adrien Poly](https://www.rubyevents.org/profiles/adrienpoly)\n* [Marco Roth](https://github.com/marcoroth)\n* [Rachael Wright-Munn](https://www.rubyevents.org/profiles/chaelcodes)\n"
  },
  {
    "path": "app/views/page/assets.html.erb",
    "content": "<div style=\"background-color: #F5F5F5;\" class=\"min-h-screen py-8\">\n  <div class=\"container mx-auto px-4\">\n    <div class=\"mb-8\">\n      <h1 class=\"text-4xl font-bold text-gray-900 mb-2\">Event Assets Overview</h1>\n      <p class=\"text-gray-600\">View all event assets with their dimensions, similar to Sketch or Figma artboards</p>\n      <p class=\"text-gray-600 mt-2\">\n        For information on how to add or manage visual assets, see the\n        <%= link_to \"Adding Visual Assets Guide\", \"https://github.com/rubyevents/rubyevents/blob/main/docs/ADDING_VISUAL_ASSETS.md\", class: \"text-blue-600 hover:text-blue-800 underline\", target: \"_blank\", rel: \"noopener\" %>\n      </p>\n    </div>\n\n    <div class=\"grid grid-cols-1 md:grid-cols-4 gap-4 mb-8\">\n      <div class=\"bg-white rounded-lg p-4\" style=\"border: 1px solid #E5E5E5;\">\n        <div class=\"text-gray-600 text-sm mb-1\">Total Events</div>\n        <div class=\"text-2xl font-bold text-gray-900\"><%= @events_with_assets.count %></div>\n      </div>\n      <div class=\"bg-white rounded-lg p-4\" style=\"border: 1px solid #E5E5E5;\">\n        <div class=\"text-gray-600 text-sm mb-1\">With Assets</div>\n        <div class=\"text-2xl font-bold text-green-600\"><%= @events_with_assets.count { |e| e[:has_any_assets] } %></div>\n      </div>\n      <div class=\"bg-white rounded-lg p-4\" style=\"border: 1px solid #E5E5E5;\">\n        <div class=\"text-gray-600 text-sm mb-1\">Without Assets</div>\n        <div class=\"text-2xl font-bold text-red-600\"><%= @events_with_assets.count { |e| !e[:has_any_assets] } %></div>\n      </div>\n      <div class=\"bg-white rounded-lg p-4\" style=\"border: 1px solid #E5E5E5;\">\n        <div class=\"text-gray-600 text-sm mb-1\">Asset Types</div>\n        <div class=\"text-2xl font-bold text-blue-600\"><%= @asset_types.count %></div>\n      </div>\n    </div>\n\n    <div class=\"space-y-8\">\n      <% @events_with_assets.group_by { |e| e[:event].series }.sort_by { |series, _| series.name }.each do |series, series_events| %>\n        <div class=\"bg-white rounded-lg overflow-hidden\" style=\"border: 1px solid #E5E5E5;\">\n          <div class=\"bg-gray-50 px-6 py-4\" style=\"border-bottom: 1px solid #E5E5E5;\">\n            <h2 class=\"text-2xl font-bold text-gray-900\"><%= series.name %></h2>\n            <p class=\"text-gray-600 text-sm mt-1\">\n              <%= series_events.count %> events •\n              <%= series_events.count { |e| e[:has_any_assets] } %> with assets\n            </p>\n          </div>\n\n          <div class=\"p-6 space-y-6\">\n            <% series_events.sort_by { |e| e[:event].end_date || e[:event].start_date || e[:event].date || Date.new(1900, 1, 1) }.reverse.each do |event_data| %>\n              <% event = event_data[:event] %>\n              <% assets = event_data[:assets] %>\n              <% missing_assets = event_data[:missing_assets] %>\n\n              <div class=\"bg-white rounded-lg overflow-hidden\" style=\"border: 1px solid <%= event_data[:has_any_assets] ? \"#E5E5E5\" : \"#E74C3C\" %>;\">\n                <div class=\"px-4 py-3 bg-gray-50 flex items-center justify-between\" style=\"border-bottom: 1px solid #E5E5E5;\">\n                  <div class=\"flex items-center gap-3\">\n                    <h3 class=\"text-lg font-semibold text-gray-900\"><%= event.name %></h3>\n                    <% if !event_data[:has_any_assets] %>\n                      <span class=\"px-2 py-1 text-xs font-medium bg-red-100 text-red-800 rounded\">No Assets</span>\n                    <% elsif missing_assets.any? %>\n                      <span class=\"px-2 py-1 text-xs font-medium bg-yellow-100 text-yellow-800 rounded\">\n                        <%= missing_assets.count %> Missing\n                      </span>\n                    <% else %>\n                      <span class=\"px-2 py-1 text-xs font-medium bg-green-100 text-green-800 rounded\">Complete</span>\n                    <% end %>\n                  </div>\n                  <%= link_to \"View Event →\", event, class: \"text-blue-600 hover:text-blue-800 text-sm\" %>\n                </div>\n\n                <div class=\"p-6\" style=\"background-color: #F5F5F5;\">\n                  <div class=\"space-y-6\">\n                    <% if @asset_types[\"avatar\"] %>\n                      <% specs = @asset_types[\"avatar\"] %>\n                      <% has_asset = assets[\"avatar\"] %>\n                      <div class=\"flex justify-center\">\n                        <div style=\"width: 200px;\">\n                          <div class=\"relative bg-white overflow-hidden\" style=\"border: <%= has_asset ? \"1px solid #E5E5E5\" : \"1px dashed #E5E5E5\" %>;\">\n                            <div style=\"padding-bottom: 100%; position: relative; background-color: #FAFAFA;\">\n                              <div style=\"position: absolute; top: 0; left: 0; right: 0; bottom: 0;\">\n                                <% if has_asset %>\n                                  <%= image_tag event.event_image_for(\"avatar.webp\"),\n                                        style: \"width: 100%; height: 100%; object-fit: contain;\",\n                                        alt: \"#{event.name} - Avatar\",\n                                        loading: \"lazy\" %>\n                                <% else %>\n                                  <div style=\"display: flex; align-items: center; justify-content: center; height: 100%; text-align: center;\">\n                                    <div>\n                                      <svg style=\"width: 2rem; height: 2rem; color: #CCCCCC; margin: 0 auto 0.5rem;\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                                        <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\" />\n                                      </svg>\n                                      <p style=\"font-size: 0.75rem; color: #999999;\">Missing</p>\n                                    </div>\n                                  </div>\n                                <% end %>\n                              </div>\n                            </div>\n                          </div>\n                          <div class=\"mt-2 flex items-center justify-center gap-2\">\n                            <% if has_asset %>\n                              <div class=\"w-2 h-2 rounded-full bg-green-500\"></div>\n                              <span class=\"text-xs text-gray-600\">avatar.webp <%= specs[:width] %>×<%= specs[:height] %></span>\n                            <% else %>\n                              <div class=\"w-2 h-2 rounded-full bg-red-400\"></div>\n                              <span class=\"text-xs text-gray-400\">avatar.webp <%= specs[:width] %>×<%= specs[:height] %></span>\n                            <% end %>\n                          </div>\n                        </div>\n                      </div>\n                    <% end %>\n\n                    <% if @asset_types[\"banner\"] %>\n                      <% specs = @asset_types[\"banner\"] %>\n                      <% has_asset = assets[\"banner\"] %>\n                      <% banner_bg = event.static_metadata.banner_background.presence || \"#FAFAFA\" %>\n                      <div>\n                        <div class=\"relative bg-white overflow-hidden\" style=\"border: <%= has_asset ? \"1px solid #E5E5E5\" : \"1px dashed #E5E5E5\" %>;\">\n                          <div style=\"padding-bottom: <%= (specs[:height].to_f / specs[:width].to_f * 100).round(2) %>%; position: relative; background: <%= banner_bg %>;\">\n                            <div style=\"position: absolute; top: 0; left: 0; right: 0; bottom: 0;\">\n                              <% if has_asset %>\n                                <%= image_tag event.event_image_for(\"banner.webp\"),\n                                      style: \"width: 100%; height: 100%; object-fit: contain;\",\n                                      alt: \"#{event.name} - Banner\",\n                                      loading: \"lazy\" %>\n                              <% else %>\n                                <div style=\"display: flex; align-items: center; justify-content: center; height: 100%; text-align: center;\">\n                                  <div>\n                                    <svg style=\"width: 3rem; height: 3rem; color: #CCCCCC; margin: 0 auto 0.5rem;\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                                      <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\" />\n                                    </svg>\n                                    <p style=\"font-size: 0.75rem; color: #999999;\">Missing</p>\n                                  </div>\n                                </div>\n                              <% end %>\n                            </div>\n                          </div>\n                        </div>\n                        <div class=\"mt-2 flex items-center justify-center gap-2\">\n                          <% if has_asset %>\n                            <div class=\"w-2 h-2 rounded-full bg-green-500\"></div>\n                            <span class=\"text-xs text-gray-600\">banner.webp <%= specs[:width] %>×<%= specs[:height] %></span>\n                          <% else %>\n                            <div class=\"w-2 h-2 rounded-full bg-red-400\"></div>\n                            <span class=\"text-xs text-gray-400\">banner.webp <%= specs[:width] %>×<%= specs[:height] %></span>\n                          <% end %>\n                        </div>\n                      </div>\n                    <% end %>\n\n                    <div class=\"grid grid-cols-1 md:grid-cols-3 gap-6\">\n                      <% [\"card\", \"featured\", \"poster\"].each do |type| %>\n                        <% if @asset_types[type] %>\n                          <% specs = @asset_types[type] %>\n                          <% has_asset = assets[type] %>\n                          <% bg_color = (type == \"featured\" && event.static_metadata.featured_background.present?) ? event.static_metadata.featured_background : \"#FAFAFA\" %>\n                          <div>\n                            <div class=\"relative bg-white overflow-hidden\" style=\"border: <%= has_asset ? \"1px solid #E5E5E5\" : \"1px dashed #E5E5E5\" %>;\">\n                              <div style=\"padding-bottom: <%= (specs[:height].to_f / specs[:width].to_f * 100).round(2) %>%; position: relative; background: <%= bg_color %>;\">\n                                <div style=\"position: absolute; top: 0; left: 0; right: 0; bottom: 0;\">\n                                  <% if has_asset %>\n                                    <%= image_tag event.event_image_for(\"#{type}.webp\"),\n                                          style: \"width: 100%; height: 100%; object-fit: contain;\",\n                                          alt: \"#{event.name} - #{specs[:name]}\",\n                                          loading: \"lazy\" %>\n                                  <% else %>\n                                    <div style=\"display: flex; align-items: center; justify-content: center; height: 100%; text-align: center;\">\n                                      <div>\n                                        <svg style=\"width: 3rem; height: 3rem; color: #CCCCCC; margin: 0 auto 0.5rem;\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                                          <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\" />\n                                        </svg>\n                                        <p style=\"font-size: 0.75rem; color: #999999;\">Missing</p>\n                                      </div>\n                                    </div>\n                                  <% end %>\n                                </div>\n                              </div>\n                            </div>\n                            <div class=\"mt-2 flex items-center justify-center gap-2\">\n                              <% if has_asset %>\n                                <div class=\"w-2 h-2 rounded-full bg-green-500\"></div>\n                                <span class=\"text-xs text-gray-600\"><%= type %>.webp <%= specs[:width] %>×<%= specs[:height] %></span>\n                              <% else %>\n                                <div class=\"w-2 h-2 rounded-full bg-red-400\"></div>\n                                <span class=\"text-xs text-gray-400\"><%= type %>.webp <%= specs[:width] %>×<%= specs[:height] %></span>\n                              <% end %>\n                            </div>\n                          </div>\n                        <% end %>\n                      <% end %>\n                    </div>\n\n                    <div class=\"mt-6 grid grid-cols-1 md:grid-cols-2 gap-6\">\n                      <div>\n                        <h4 class=\"text-sm font-semibold text-gray-700 mb-3\">Stickers</h4>\n                        <div class=\"flex gap-4 flex-wrap\">\n                          <% if event_data[:sticker_paths].any? %>\n                            <% event_data[:sticker_paths].each_with_index do |sticker_path, index| %>\n                              <div>\n                                <div class=\"relative bg-white overflow-hidden\" style=\"border: 1px solid #E5E5E5; width: 150px;\">\n                                  <div style=\"padding-bottom: 100%; position: relative; background-color: #FAFAFA;\">\n                                    <div style=\"position: absolute; top: 0; left: 0; right: 0; bottom: 0;\">\n                                      <%= image_tag sticker_path,\n                                            style: \"width: 100%; height: 100%; object-fit: contain;\",\n                                            alt: \"#{event.name} - Sticker #{index + 1}\",\n                                            loading: \"lazy\" %>\n                                    </div>\n                                  </div>\n                                </div>\n                                <div class=\"mt-2 flex items-center justify-center gap-2\">\n                                  <div class=\"w-2 h-2 rounded-full bg-green-500\"></div>\n                                  <span class=\"text-xs text-gray-600\"><%= File.basename(sticker_path) %> <%= @asset_types[\"sticker\"][:width] %>×<%= @asset_types[\"sticker\"][:height] %></span>\n                                </div>\n                              </div>\n                            <% end %>\n                          <% else %>\n                            <div>\n                              <div class=\"relative bg-white overflow-hidden\" style=\"border: 1px dashed #E5E5E5; width: 150px;\">\n                                <div style=\"padding-bottom: 100%; position: relative; background-color: #FAFAFA;\">\n                                  <div style=\"position: absolute; top: 0; left: 0; right: 0; bottom: 0;\">\n                                    <div style=\"display: flex; align-items: center; justify-content: center; height: 100%; text-align: center;\">\n                                      <div>\n                                        <svg style=\"width: 2rem; height: 2rem; color: #CCCCCC; margin: 0 auto 0.5rem;\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                                          <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\" />\n                                        </svg>\n                                        <p style=\"font-size: 0.75rem; color: #999999;\">Missing</p>\n                                      </div>\n                                    </div>\n                                  </div>\n                                </div>\n                              </div>\n                              <div class=\"mt-2 flex items-center justify-center gap-2\">\n                                <div class=\"w-2 h-2 rounded-full bg-red-400\"></div>\n                                <span class=\"text-xs text-gray-400\">sticker.webp <%= @asset_types[\"sticker\"][:width] %>×<%= @asset_types[\"sticker\"][:height] %></span>\n                              </div>\n                            </div>\n                          <% end %>\n                        </div>\n                      </div>\n\n                      <div>\n                        <h4 class=\"text-sm font-semibold text-gray-700 mb-3\">Stamps</h4>\n                        <div class=\"flex gap-4 flex-wrap\">\n                          <% if event_data[:stamp_paths].any? %>\n                            <% event_data[:stamp_paths].each_with_index do |stamp_path, index| %>\n                              <div>\n                                <div class=\"relative bg-white overflow-hidden\" style=\"border: 1px solid #E5E5E5; width: 150px;\">\n                                  <div style=\"padding-bottom: 100%; position: relative; background-color: #FAFAFA;\">\n                                    <div style=\"position: absolute; top: 0; left: 0; right: 0; bottom: 0;\">\n                                      <%= image_tag stamp_path,\n                                            style: \"width: 100%; height: 100%; object-fit: contain;\",\n                                            alt: \"#{event.name} - Stamp #{index + 1}\",\n                                            loading: \"lazy\" %>\n                                    </div>\n                                  </div>\n                                </div>\n                                <div class=\"mt-2 flex items-center justify-center gap-2\">\n                                  <div class=\"w-2 h-2 rounded-full bg-green-500\"></div>\n                                  <span class=\"text-xs text-gray-600\"><%= File.basename(stamp_path) %> <%= @asset_types[\"stamp\"][:width] %>×<%= @asset_types[\"stamp\"][:height] %></span>\n                                </div>\n                              </div>\n                            <% end %>\n                          <% else %>\n                            <div>\n                              <div class=\"relative bg-white overflow-hidden\" style=\"border: 1px dashed #E5E5E5; width: 150px;\">\n                                <div style=\"padding-bottom: 100%; position: relative; background-color: #FAFAFA;\">\n                                  <div style=\"position: absolute; top: 0; left: 0; right: 0; bottom: 0;\">\n                                    <div style=\"display: flex; align-items: center; justify-content: center; height: 100%; text-align: center;\">\n                                      <div>\n                                        <svg style=\"width: 2rem; height: 2rem; color: #CCCCCC; margin: 0 auto 0.5rem;\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n                                          <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\" />\n                                        </svg>\n                                        <p style=\"font-size: 0.75rem; color: #999999;\">Missing</p>\n                                      </div>\n                                    </div>\n                                  </div>\n                                </div>\n                              </div>\n                              <div class=\"mt-2 flex items-center justify-center gap-2\">\n                                <div class=\"w-2 h-2 rounded-full bg-red-400\"></div>\n                                <span class=\"text-xs text-gray-400\">stamp.webp <%= @asset_types[\"stamp\"][:width] %>×<%= @asset_types[\"stamp\"][:height] %></span>\n                              </div>\n                            </div>\n                          <% end %>\n                        </div>\n                      </div>\n                    </div>\n\n                    <% if event.static_metadata.featured_color.present? || event.static_metadata.featured_background.present? || event.static_metadata.banner_background.present? %>\n                      <div class=\"mt-6 pt-6\" style=\"border-top: 1px solid #E5E5E5;\">\n                        <h4 class=\"text-sm font-semibold text-gray-700 mb-3\">Event Colors</h4>\n                        <div class=\"flex gap-4\">\n                          <% if event.static_metadata.banner_background.present? %>\n                            <div>\n                              <div class=\"w-20 h-20 mb-2\" style=\"background: <%= event.static_metadata.banner_background %>; border: 1px solid #E5E5E5;\"></div>\n                              <div class=\"text-xs text-gray-600\">Banner BG</div>\n                              <div class=\"text-xs font-mono text-gray-500 line-clamp-1\" style=\"width: 80px;\" title=\"<%= event.static_metadata.banner_background %>\"><%= event.static_metadata.banner_background %></div>\n                            </div>\n                          <% end %>\n\n                          <% if event.static_metadata.featured_background.present? %>\n                            <div>\n                              <div class=\"w-20 h-20 mb-2\" style=\"background-color: <%= event.static_metadata.featured_background %>; border: 1px solid #E5E5E5;\"></div>\n                              <div class=\"text-xs text-gray-600\">Featured BG</div>\n                              <div class=\"text-xs font-mono text-gray-500\"><%= event.static_metadata.featured_background %></div>\n                            </div>\n                          <% end %>\n\n                          <% if event.static_metadata.featured_color.present? %>\n                            <div>\n                              <div class=\"w-20 h-20 mb-2\" style=\"background-color: <%= event.static_metadata.featured_color %>; border: 1px solid #E5E5E5;\"></div>\n                              <div class=\"text-xs text-gray-600\">Featured Color</div>\n                              <div class=\"text-xs font-mono text-gray-500\"><%= event.static_metadata.featured_color %></div>\n                            </div>\n                          <% end %>\n                        </div>\n                      </div>\n                    <% end %>\n                  </div>\n                </div>\n              </div>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/page/components/_avatars.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-4\">Avatar</h2>\n\n<% avatarable = User.speakers.first %>\n<div class=\"flex gap-16 w-full\">\n  <div class=\"flex items-center justify-start gap-4 mb-8 flex-wrap\">\n    <% [:primary, :neutral].each do |kind| %>\n      <div class=\"text-center\">\n        <%= ui_avatar avatarable, kind: kind %><br>\n        <%= kind %>\n      </div>\n    <% end %>\n  </div>\n</div>\n<p>Sizes</p>\n<div class=\"flex items-center justify-start gap-4 mt-4 mb-8 flex-wrap\">\n  <% [:sm, :md, :lg].each do |size| %>\n    <div class=\"text-center\">\n      <%= ui_avatar avatarable, size: size %><br>\n      <%= size %>\n    </div>\n  <% end %>\n</div>\n<p>Outline</p>\n<div class=\"flex items-center justify-start gap-4 mt-4 mb-8 flex-wrap bg-gray-500 p-2 w-80\">\n  <% [true, false].each do |value| %>\n    <div class=\"text-center text-white\">\n      <%= ui_avatar avatarable, outline: value %><br>\n      <%= value.to_s %>\n    </div>\n  <% end %>\n</div>\n<p>Custom size class</p>\n<div class=\"flex items-center justify-start gap-4 mt-4 mb-8 flex-wrap\">\n  <% [\"w-10\", \"w-20\"].each do |size_class| %>\n    <div class=\"text-center\">\n      <%= ui_avatar avatarable, size_class: size_class %><br>\n      <%= size_class %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/page/components/_buttons.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-4\">Button</h2>\n<div class=\"flex gap-16 w-full\">\n  <div class=\"flex items-center justify-start gap-4 mb-8 flex-wrap\">\n    <% [:primary, :secondary, :neutral, :rounded, :ghost, :link].each do |kind| %>\n      <%= ui_button kind.to_s.capitalize, kind: kind %>\n    <% end %>\n  </div>\n  <div class=\"flex justify-center\">\n    <div class=\"flex flex-col gap-4 w-36\">\n      <p>Example</p>\n      <%= ui_button \"Preview\", kind: :neutral %>\n      <%= ui_button \"Edit\", kind: :secondary %>\n      <%= ui_button \"Save\", kind: :primary %>\n      <%= ui_button \"Cancel\", kind: :ghost %>\n    </div>\n  </div>\n</div>\n<p>small versions</p>\n<div class=\"flex items-center justify-start gap-4 mt-4 mb-8 flex-wrap\">\n  <% [:primary, :secondary, :neutral, :rounded, :ghost, :link].each do |kind| %>\n    <%= ui_button kind.to_s.capitalize, kind: kind, size: :sm %>\n  <% end %>\n</div>\n<p>Pill buttons for toolbars</p>\n<div class=\"flex items-center justify-start gap-4 mt-4 mb-8 flex-wrap\">\n  <%= ui_button kind: :pill do %>\n    <%= fa(\"pencil\", size: :sm) %>\n    <span>Edit</span>\n  <% end %>\n  <%= ui_button kind: :pill do %>\n    <%= fa(\"share-nodes\", size: :sm) %>\n    <span>Share</span>\n  <% end %>\n  <%= ui_button kind: :pill do %>\n    <%= fa(\"trash-can\", size: :sm) %>\n    <span>Delete</span>\n  <% end %>\n  <%= ui_button kind: :pill do %>\n    <%= fa(\"link\", size: :sm) %>\n    <span>Link</span>\n  <% end %>\n  <%= ui_button kind: :pill do %>\n    <%= fa(\"bookmark\", style: :regular, size: :sm) %>\n    <span>Bookmark</span>\n  <% end %>\n  <%= ui_button kind: :pill do %>\n    <%= fa(\"bookmark\", style: :solid, class: \"text-primary\", size: :sm) %>\n    <span>Bookmark</span>\n  <% end %>\n  <%= ui_button kind: :pill do %>\n    <%= fa(\"circle\", size: :sm, style: :regular) %>\n    <span class=\"text-nowrap\">Watched</span>\n  <% end %>\n  <%= ui_button kind: :pill do %>\n    <%= fa(\"circle-check\", size: :sm, style: :solid, class: \"fill-green-700\") %>\n    <span class=\"text-nowrap\">Watched</span>\n  <% end %>\n</div>\n<p>Pill buttons for filters</p>\n<div class=\"flex items-center justify-start gap-4 mt-4 mb-8 flex-wrap\">\n  <%= ui_button kind: :pill, class: \"active\" do %>\n    <span>Portuguese (5)</span>\n  <% end %>\n  <%= ui_button kind: :pill do %>\n    <span>English (10)</span>\n  <% end %>\n  <%= ui_button kind: :pill do %>\n    <span>French (2)</span>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/page/components/_dropdowns.html.erb",
    "content": "<h2 class=\"text-2xl font-bold\">Dropdown</h2>\n<div class=\"flex items-center justify-start gap-8 py-8\">\n  <%= ui_dropdown id: \"dropdown\" do |c| %>\n    Dropdown\n    <% c.with_menu_item_link_to \"link\", \"#\" %>\n    <% c.with_menu_item_divider %>\n    <% c.with_menu_item_button_to \"button\", \"#\" %>\n  <% end %>\n\n  <%= ui_dropdown id: \"dropdown\" do |c| %>\n    <% c.with_toggle_open do %>\n      <%= fa(\"xmark\", size: :lg) %>\n    <% end %>\n\n    <% c.with_toggle_close do %>\n      <%= fa(\"bars\", size: :lg) %>\n    <% end %>\n\n    <% c.with_menu_item_link_to \"link\", \"#\" %>\n    <% c.with_menu_item_divider %>\n    <% c.with_menu_item_button_to \"button\", \"#\" %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/page/components/_links.html.erb",
    "content": "<h2 class=\"text-2xl font-bold\">Links</h2>\n<div class=\"flex items-center justify-start gap-8 py-8\">\n  <%= external_link_to \"www.ruby-lang.org\", \"https://www.ruby-lang.org/\" %>\n\n  <%= external_link_to \"https://www.ruby-lang.org/\" do %>\n    with block\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/page/components/_modals.html.erb",
    "content": "<h2 class=\"text-2xl font-bold\">Modal</h2>\n<div class=\"flex items-center justify-start gap-8 py-8\">\n  <%= ui_button \"Top position\", \"#\", kind: :pill, data: {toggle: \"modal\", target: \"modal-top\"} %>\n  <%= ui_modal position: :top, id: \"modal-top\" do %>\n    Modal with a top position\n  <% end %>\n\n  <%= ui_button \"Bottom position\", \"#\", kind: :pill, data: {toggle: \"modal\", target: \"modal-bottom\"} %>\n  <%= ui_modal position: :bottom, id: \"modal-bottom\" do %>\n    Modal with a bottom position\n  <% end %>\n\n  <%= ui_button \"Middle position\", \"#\", kind: :pill, data: {toggle: \"modal\", target: \"modal-middle\"} %>\n  <%= ui_modal position: :middle, id: \"modal-middle\" do %>\n    Modal with a middle position\n  <% end %>\n\n  <%= ui_button \"Responsive position\", \"#\", kind: :pill, data: {toggle: \"modal\", target: \"modal-responsive\"} %>\n  <%= ui_modal position: :responsive, id: \"modal-responsive\" do %>\n    Modal with a responsive position\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/page/components/_stamps.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-4\">Stamp</h2>\n\n<% country_stamp = Stamp.country_stamps.sample %>\n\n<% contributor_stamp = Stamp.contributor_stamp %>\n\n<% passport_stamp = Stamp.passport_stamp %>\n\n<% triathlon_2025_stamp = Stamp.triathlon_2025_stamp %>\n\n<% conference_speaker_stamp = Stamp.conference_speaker_stamp %>\n\n<% meetup_speaker_stamp = Stamp.meetup_speaker_stamp %>\n\n<% attend_one_event_stamp = Stamp.attend_one_event_stamp %>\n\n<% online_stamp = Stamp.online_stamp %>\n\n<h3>Types</h3>\n<div class=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-8 mt-4 mb-8\">\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(country_stamp, size: :xl) %>\n    Country Stamp\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(contributor_stamp, size: :xl) %>\n    Contributor Stamp\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(passport_stamp, size: :xl) %>\n    Passport Stamp\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(triathlon_2025_stamp, size: :xl) %>\n    Triathlon 2025 Stamp\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(conference_speaker_stamp, size: :xl) %>\n    Conference Speaker Stamp\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(meetup_speaker_stamp, size: :xl) %>\n    Meetup Speaker Stamp\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(attend_one_event_stamp, size: :xl) %>\n    Attend One Event Stamp\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(online_stamp, size: :xl) %>\n    Online Stamp\n  </div>\n</div>\n\n<h3>Sizes</h3>\n<div class=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-8 mt-4 mb-8\">\n  <% [:sm, :md, :lg, :xl].each do |size| %>\n    <div class=\"flex flex-col gap-2 items-center text-center\">\n      <%= size %>\n      <%= ui_stamp(country_stamp, size: size) %><br>\n    </div>\n  <% end %>\n\n  <% [:sm, :md, :lg, :xl].each do |size| %>\n    <div class=\"flex flex-col gap-2 items-center text-center\">\n      <%= size %> (with rotate and zoom effect)\n      <%= ui_stamp(country_stamp, size: size, rotate: true, zoom_effect: true) %><br>\n    </div>\n  <% end %>\n</div>\n\n<p>Interactive vs Static</p>\n<div class=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-8 mt-4 mb-8\">\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(country_stamp, interactive: true, size: :xl) %><br>\n    Interactive\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(country_stamp, interactive: false, size: :xl) %><br>\n    Static\n  </div>\n</div>\n\n<p>Custom Rotation</p>\n<div class=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-8 mt-4 mb-8\">\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(country_stamp, rotate: true, size: :xl) %><br>\n    Rotated\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(country_stamp, rotate: false, size: :xl) %><br>\n    Straight\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(country_stamp, rotate: true, size: :xl, zoom_effect: true) %><br>\n    Rotated with zoom effect\n  </div>\n  <div class=\"flex flex-col gap-2 items-center text-center\">\n    <%= ui_stamp(country_stamp, rotate: false, size: :xl, zoom_effect: true) %><br>\n    Straight with zoom effect\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/page/components/_tabs.html.erb",
    "content": "<h2 class=\"text-2xl font-bold\">Tabs</h2>\n<div class=\"flex flex-col items-start justify-start gap-8 py-8\">\n  <div>Todo (this is a WIP of the tab component, just the Daisy UI markup and a Stimulus controller)</div>\n\n  <div role=\"tablist\" class=\"tabs tabs-bordered\" data-controller=\"tabs\">\n    <div role=\"tab\" class=\"tab tab-active\" style=\"view-transition-name: tab-1;\" aria-label=\"Tab 1\" data-action=\"click->tabs#showPanel\">Tab 1</div>\n    <div role=\"tabpanel\" class=\"tab-content py-4\" style=\"view-transition-name: tab-content-1;\">\n      Tab content 1\n    </div>\n\n    <div role=\"tab\" class=\"tab\" style=\"view-transition-name: tab-2;\" aria-label=\"Tab 2\" data-action=\"click->tabs#showPanel\">Tab 2</div>\n    <div role=\"tabpanel\" class=\"tab-content py-4\" style=\"view-transition-name: tab-content-2;\">\n      Tab content 2\n    </div>\n\n    <div role=\"tab\" class=\"tab\" style=\"view-transition-name: tab-3;\" aria-label=\"Tab 3\" data-action=\"click->tabs#showPanel\">Tab 3</div>\n    <div role=\"tabpanel\" class=\"tab-content py-4\" style=\"view-transition-name: tab-content-3;\">\n      Tab content 3\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/page/components/_tooltips.html.erb",
    "content": "<h2 class=\"text-2xl font-bold\">Tooltips</h2>\n<div class=\"flex flex-col items-start justify-start gap-8 py-8\">\n\n  <%= ui_tooltip \"basic text in the tooltip\" do %>\n    <div>text with tooltip</div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/page/components.html.erb",
    "content": "<div class=\"container py-8\">\n  <h1 class=\"text-3xl font-bold mb-4\">Components</h1>\n\n  <%= render \"page/components/buttons\" %>\n  <%= render \"page/components/dropdowns\" %>\n  <%= render \"page/components/links\" %>\n  <%= render \"page/components/modals\" %>\n  <%= render \"page/components/tabs\" %>\n  <%= render \"page/components/tooltips\" %>\n  <%= render \"page/components/avatars\" %>\n  <%= render \"page/components/stamps\" %>\n</div>\n"
  },
  {
    "path": "app/views/page/contributors.html.erb",
    "content": "<div class=\"container py-8\">\n  <div class=\"flex justify-between items-center mb-4\">\n    <h1 class=\"text-4xl font-bold\">Contributors</h1>\n\n    <div class=\"flex gap-2\">\n      <button onclick=\"document.getElementById('detailed-view').classList.remove('hidden'); document.getElementById('compact-view').classList.add('hidden'); this.classList.add('btn-primary'); this.classList.remove('btn-outline'); this.nextElementSibling.classList.remove('btn-primary'); this.nextElementSibling.classList.add('btn-outline');\"\n              class=\"btn btn-sm btn-primary\">\n        Detailed\n      </button>\n      <button onclick=\"document.getElementById('compact-view').classList.remove('hidden'); document.getElementById('detailed-view').classList.add('hidden'); this.classList.add('btn-primary'); this.classList.remove('btn-outline'); this.previousElementSibling.classList.remove('btn-primary'); this.previousElementSibling.classList.add('btn-outline');\"\n              class=\"btn btn-sm btn-outline\">\n        Compact\n      </button>\n    </div>\n  </div>\n\n  <article class=\"prose mb-8\">\n    <p>\n      Thank you to all <%= pluralize(@contributors.count, \"contributor\") %> who have helped make RubyEvents.org possible!\n      Every contribution, big or small, helps improve the Ruby community's access to quality educational content.\n    </p>\n  </article>\n\n  <% if @contributors.any? %>\n    <div id=\"detailed-view\" class=\"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-6\">\n      <% @contributors.each do |contributor| %>\n        <%= link_to contributor.user ? profile_path(contributor.user) : contributor.html_url,\n              target: contributor.user ? nil : \"_blank\",\n              rel: contributor.user ? nil : \"noopener noreferrer\",\n              class: \"group flex flex-col items-center justify-center p-4 rounded-lg border bg-white hover:bg-gray-50 transition-colors h-full\" do %>\n          <div class=\"mb-3\">\n            <%= image_tag contributor.avatar_url,\n                  alt: contributor.login,\n                  class: \"w-20 h-20 rounded-full\" %>\n          </div>\n\n          <div class=\"text-center w-full\">\n            <% if contributor.name.present? %>\n              <div class=\"font-semibold text-sm break-words mb-1 flex items-center justify-center gap-1\">\n                <span><%= contributor.name %></span>\n                <% if contributor.user %>\n                  <%= fa(\"circle-user\", class: \"fill-gray-500\", size: :xs, title: \"Has a RubyVideo profile\") %>\n                <% end %>\n              </div>\n              <div class=\"text-xs text-gray-500\">\n                @<%= contributor.login %>\n              </div>\n            <% else %>\n              <div class=\"font-semibold text-sm break-words flex items-center justify-center gap-1\">\n                <span>@<%= contributor.login %></span>\n                <% if contributor.user %>\n                  <%= fa(\"circle-user\", class: \"fill-gray-500\", size: :xs, title: \"Has a RubyVideo profile\") %>\n                <% end %>\n              </div>\n            <% end %>\n          </div>\n        <% end %>\n      <% end %>\n    </div>\n\n    <!-- Compact View (for social media screenshots) -->\n    <div id=\"compact-view\" class=\"hidden\">\n      <div class=\"bg-white border-4 border-red-600 p-8 rounded-xl\">\n        <h2 class=\"text-3xl font-bold text-gray-900 text-center mb-6\">\n          <%= @contributors.count %> Contributors\n        </h2>\n\n        <div class=\"grid grid-cols-10 sm:grid-cols-12 md:grid-cols-16 lg:grid-cols-20 gap-3 mb-6\">\n          <% @contributors.each do |contributor| %>\n            <%= link_to contributor.user ? profile_path(contributor.user) : contributor.html_url,\n                  target: contributor.user ? nil : \"_blank\",\n                  rel: contributor.user ? nil : \"noopener noreferrer\",\n                  title: \"#{contributor.name.present? ? contributor.name : \"@#{contributor.login}\"} (@#{contributor.login})#{\" - Has a RubyVideo profile\" if contributor.user}\",\n                  class: \"group aspect-square\" do %>\n              <div class=\"w-full h-full rounded-full overflow-hidden border-2 border-gray-200 hover:scale-110 transition-transform\">\n                <%= image_tag contributor.avatar_url,\n                      alt: contributor.login,\n                      class: \"w-full h-full object-cover\" %>\n              </div>\n            <% end %>\n          <% end %>\n        </div>\n\n        <p class=\"text-gray-700 text-center text-lg\">\n          Thank you for making RubyEvents.org possible!\n        </p>\n      </div>\n    </div>\n  <% else %>\n    <div class=\"alert alert-info\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" class=\"stroke-current shrink-0 w-6 h-6\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"></path></svg>\n      <span>Unable to load contributors at this time. Please try again later.</span>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/page/featured.html.erb",
    "content": "<main class=\"container\">\n  <% playlists = Static::Event.where.not(featured_background: nil) %>\n  <% events = Event.where(slug: playlists.map(&:slug)).order(date: :desc) %>\n\n  <div>\n    <% events.each do |event| %>\n      <%= render partial: \"events/featured\", locals: {event: event} %>\n    <% end %>\n  </div>\n</main>\n"
  },
  {
    "path": "app/views/page/home.html.erb",
    "content": "<% title hotwire_native_app? ? \"RubyEvents\" : \"RubyEvents.org - On a mission to index all Ruby events\" %>\n<% content_for :body_class, \"home-page\" %>\n\n<% if @featured_events.any? %>\n  <% content_for :head do %>\n    <meta name=\"theme-color\" content=\"<%= @featured_events.first.static_metadata.featured_background %>\" data-featured-theme-color>\n\n    <style>\n      :root {\n        --featured-color: <%= @featured_events.first.static_metadata.featured_color %>;\n        --featured-background: <%= @featured_events.first.static_metadata.featured_background %>;\n      }\n\n      body.home-page .navbar {\n        background: var(--featured-background);\n      }\n\n      body.home-page .navbar .desktop-menu a,\n      body.home-page .navbar > .container a:not(.dropdown-content a) {\n        color: var(--featured-color);\n      }\n\n      body.home-page .navbar .dropdown-content a,\n      body.home-page .navbar .dropdown-content button {\n        color: #000 !important;\n      }\n\n      body.home-page .navbar .btn-primary {\n        background-color: white;\n        color: black !important;\n        border: 1px solid rgb(156 163 175 / var(--tw-border-opacity, 1));\n      }\n\n      body.home-page .navbar .btn-primary:hover {\n        background-color: rgba(255, 255, 255, 0.9);\n      }\n\n      body.home-page .navbar svg {\n        fill: var(--featured-color);\n      }\n\n      .splide__track, .splide__list {\n        background: transparent !important;\n      }\n      body.home-page .splide {\n        background: var(--featured-background);\n        padding-bottom: 3rem;\n        margin-bottom: 3rem !important;\n        border-bottom: 0.5px solid var(--featured-color);\n      }\n      body.home-page .featured-stats {\n        color: var(--featured-color);\n      }\n    </style>\n  <% end %>\n<% end %>\n\n<main class=\"hotwire-native:mt-6\">\n  <% cache @featured_events do %>\n    <% if @featured_events.any? %>\n      <section class=\"splide w-full\" aria-label=\"Featured Events\" data-controller=\"splide\">\n        <div class=\"featured-stats w-full pt-8\">\n          <div class=\"container hotwire-native:hidden flex flex-col items-center text-center\">\n            <h2 class=\"text-2xl font-bold tracking-tight mb-6\">On a mission to index all Ruby events</h2>\n            <div class=\"flex flex-wrap gap-4 justify-center items-center text-sm\">\n              <div class=\"flex flex-wrap justify-center items-center gap-2 mb-12 lg:mb-6\">\n                <span class=\"opacity-80\">We have indexed</span>\n                <%= link_to events_path, class: \"inline-flex items-center px-3 py-1 rounded-full bg-white/20 backdrop-blur-sm font-semibold border hover:bg-white/30 transition-colors\", style: \"border-color: color-mix(in srgb, var(--featured-color) 25%, transparent);\" do %>\n                  <%= @events_count %> events\n                <% end %>\n\n                <span class=\"opacity-80\">and</span>\n\n                <%= link_to talks_path, class: \"inline-flex items-center px-3 py-1 rounded-full bg-white/20 backdrop-blur-sm font-semibold border hover:bg-white/30 transition-colors\", style: \"border-color: color-mix(in srgb, var(--featured-color) 25%, transparent);\" do %>\n                  <%= @talks_count %> talks\n                <% end %>\n\n                <span class=\"opacity-80\">from</span>\n\n                <%= link_to speakers_path, class: \"inline-flex items-center px-3 py-1 rounded-full bg-white/20 backdrop-blur-sm font-semibold border hover:bg-white/30 transition-colors\", style: \"border-color: color-mix(in srgb, var(--featured-color) 25%, transparent);\" do %>\n                  <%= @speakers_count %> speakers\n                <% end %>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <div class=\"splide__track\">\n          <ul class=\"splide__list\">\n            <% @featured_events.each_with_index do |event, index| %>\n              <li\n                class=\"splide__slide\"\n                data-featured-color=\"<%= event.static_metadata.featured_color %>\"\n                data-featured-background=\"<%= event.static_metadata.featured_background %>\">\n                <div class=\"<%= \"hidden\" if Current.user || index != 0 %>\">\n                  <%= render partial: \"events/featured_home\", locals: {event: event} %>\n                </div>\n              </li>\n            <% end %>\n          </ul>\n        </div>\n      </section>\n    <% end %>\n  <% end %>\n\n  <div class=\"container\">\n    <div class=\"flex flex-col gap-12 mt-12\">\n      <section class=\"flex flex-col w-full gap-4\">\n        <div class=\"flex items-center justify-between w-full\">\n          <h2 class=\"text-primary shrink-0\">Latest talks</h2>\n          <%= link_to \"see all talks\", talks_path, class: \"link text-right w-full\" %>\n        </div>\n\n        <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 md:[&>:nth-child(4)]:hidden lg:grid-cols-4 lg:[&>:nth-child(4)]:block\">\n          <%= render partial: \"talks/card\", collection: @latest_talks.first(4), as: :talk, cached: true, locals: {back_to: root_path, back_to_title: \"Home\"} %>\n        </div>\n      </section>\n\n      <section class=\"flex flex-col w-full gap-4\">\n        <div class=\"flex items-center justify-between w-full\">\n          <h2 class=\"text-primary shrink-0\">Featured speakers</h2>\n          <%= link_to \"see all speakers\", speakers_path, class: \"link text-right w-full\" %>\n        </div>\n\n        <div class=\"relative\" data-controller=\"scroll\">\n          <div class=\"overflow-x-auto scroll-smooth snap-x snap-mandatory\"\n               data-scroll-target=\"container\"\n               data-action=\"scroll->scroll#checkScroll\">\n            <div class=\"flex pb-4 gap-4\">\n              <% @featured_speakers.each do |speaker| %>\n                <div class=\"snap-start\" data-scroll-target=\"card\">\n                  <%= render partial: \"speakers/card\", locals: {speaker: speaker} %>\n                </div>\n              <% end %>\n            </div>\n          </div>\n          <div\n            class=\"absolute right-0 top-0 h-full w-24 bg-gradient-to-l from-white to-transparent pointer-events-none\"\n            data-scroll-target=\"gradient\"></div>\n        </div>\n      </section>\n\n      <section class=\"flex flex-col w-full gap-4\">\n        <div class=\"flex items-center justify-between w-full\">\n          <h2 class=\"text-primary shrink-0\">Latest events</h2>\n          <%= link_to \"see all events\", events_path, class: \"link text-right w-full\" %>\n        </div>\n        <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 md:[&>:nth-child(4)]:hidden lg:grid-cols-4 lg:[&>:nth-child(4)]:block\">\n          <%= cache @latest_events do %>\n            <%= render partial: \"events/card\", collection: @latest_events, as: :event, cached: true %>\n          <% end %>\n        </div>\n      </section>\n\n      <% if @recommended_talks.present? %>\n        <section class=\"flex flex-col w-full gap-4\">\n          <div class=\"flex items-center justify-between w-full\">\n            <h2 class=\"text-primary shrink-0\">Recommended for you</h2>\n            <%= link_to \"see all recommendations\", recommendations_path, class: \"link text-right w-full\" %>\n          </div>\n          <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 md:[&>:nth-child(4)]:hidden lg:grid-cols-4 lg:[&>:nth-child(4)]:block\">\n            <%= render partial: \"talks/card\", collection: @recommended_talks, as: :talk, cached: true, locals: {back_to: root_path, back_to_title: \"Home\"} %>\n          </div>\n        </section>\n      <% end %>\n\n      <% if @featured_organizations.present? %>\n        <section class=\"flex flex-col w-full gap-4\">\n          <div class=\"flex items-center justify-between w-full\">\n            <h2 class=\"text-primary shrink-0\">Featured organizations</h2>\n            <%= link_to \"see all organizations\", organizations_path, class: \"link text-right w-full\" %>\n          </div>\n\n          <div class=\"relative\" data-controller=\"scroll\">\n            <div class=\"overflow-x-auto scroll-smooth snap-x snap-mandatory\" data-scroll-target=\"container\" data-action=\"scroll->scroll#checkScroll\">\n              <div class=\"flex pb-4 gap-4\">\n                <% @featured_organizations.each do |organization| %>\n                  <div class=\"snap-start\" data-scroll-target=\"card\">\n                    <%= render partial: \"organizations/card\", locals: {organization: organization} %>\n                  </div>\n                <% end %>\n              </div>\n            </div>\n\n            <div class=\"absolute right-0 top-0 h-full w-24 bg-gradient-to-l from-white to-transparent pointer-events-none\" data-scroll-target=\"gradient\"></div>\n          </div>\n        </section>\n      <% end %>\n    </div>\n  </div>\n</main>\n"
  },
  {
    "path": "app/views/page/privacy.md",
    "content": "# Privacy Policy\n\n**Effective Date: March 31, 2025**\n\nRubyEvents.org respects your privacy. This policy outlines how the iOS app and website handle your data.\n\n## 1. Information We Collect\n\nWe do **not** collect personally identifiable information.\n\nAnonymous usage data may be collected to help us improve the app, such as:\n\n- Device type and OS version\n- App usage patterns (e.g. which features are used most)\n- Crash reports and performance metrics\n\nThese may be gathered via Apple analytics or third-party tools such as AppSignal, and are not tied to your identity.\n\n## 2. How We Use Data\n\nAnonymous data is used to:\n\n- Improve app performance and reliability  \n- Fix bugs and crashes  \n- Understand feature usage trends\n\nWe do **not** sell or share your data with third parties.\n\n## 3. No Account Required\n\nThe RubyEvents.org app does not require you to create an account or log in. You can use all features without sharing personal information.\n\n## 4. Local Storage Only\n\nIf the app stores any user preferences (e.g., recently viewed talks or favorites), they are stored **locally** on your device and are not transmitted elsewhere.\n\n## 5. Third-Party Services\n\nThe app may embed or link to video content hosted on external platforms (such as YouTube or Vimeo). These platforms may collect their own usage data in accordance with their privacy policies.\n\n## 6. Contact Us\n\nIf you have any questions or concerns about this policy, please reach out:\n\n📧 **contact@rubyevents.org**\n\n---\n"
  },
  {
    "path": "app/views/page/stickers.html.erb",
    "content": "<div class=\"bg-black\">\n  <div class=\"container\">\n    <%= render partial: \"shared/stickers_display\", locals: {events: @events} %>\n\n    <div class=\"pb-12\">\n      <h2 class=\"text-3xl font-bold text-center text-white mb-8\">Available Stickers</h2>\n\n      <div class=\"space-y-8\">\n        <% @events.group_by(&:series).sort_by { |org, _| org.name }.each do |series, series_events| %>\n          <div class=\"bg-gray-900 rounded-lg p-6\">\n            <h3 class=\"text-xl font-semibold text-white mb-4\"><%= series.name %></h3>\n\n            <div class=\"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4\">\n              <% series_events.sort_by { |e| e.date || Date.new(1900, 1, 1) }.reverse.each do |event| %>\n                <% event.stickers.each do |sticker| %>\n                  <%= link_to event, class: \"group relative bg-gray-800 rounded-lg p-4 hover:bg-gray-700 transition-colors\" do %>\n                    <div class=\"aspect-square flex items-center justify-center mb-2\">\n                      <%= image_tag sticker.asset_path, class: \"max-w-full max-h-full object-contain group-hover:scale-110 transition-transform\" %>\n                    </div>\n                    <p class=\"text-xs text-gray-300 text-center truncate\"><%= event.name %></p>\n                  <% end %>\n                <% end %>\n              <% end %>\n            </div>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/page/uses.md",
    "content": "# Uses\n\n## Our tech stack\n\nTechnically the project is built using the latest [Ruby](https://www.ruby-lang.org/) and [Rails](https://rubyonrails.org/) goodies such as [Hotwire](https://hotwired.dev/), [SolidQueue](https://github.com/rails/solid_queue), [SolidCache](https://github.com/rails/solid_cache).\n\nFor the front end part, we use [Vite](https://vite.dev/), [Tailwind CSS](https://tailwindcss.com/) with [Daisyui](https://daisyui.com/) components, and [Stimulus](https://stimulus.hotwired.dev/).\n\nIt is deployed on a [Hetzner](https://hetzner.cloud/?ref=gyPLk7XJthjg) VPS with [Kamal](https://kamal-deploy.org/) using [SQLite](https://www.sqlite.org/) as the main database.\n\nFor compatible browsers, it tries to demonstrate some of the possibilities of the [Page View Transition API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API).\n\n## Source code\n\nRubyEvents is open source, the source code is available on [GitHub](https://github.com/rubyevents/rubyevents).\n\nContributions are welcome!\n\n## Credits\n\nThank you [AppSignal](https://appsignal.com/r/eeab047472) for providing the APM tool that helps us monitor the application.\n\nThank you [Typesense](https://typesense.org/) for sponsoring our [Typesense Cloud](https://cloud.typesense.org/) instance that powers the search functionality.\n\nIf you want to try Hetzner, you can use our [referral link](https://hetzner.cloud/?ref=gyPLk7XJthjg) to get a $20 credit.\n"
  },
  {
    "path": "app/views/profiles/_actions.html.erb",
    "content": "<%= render \"profiles/actions/#{user_kind}\", user: user %>\n"
  },
  {
    "path": "app/views/profiles/_aliases.html.erb",
    "content": "<%# locals: (user:, aliases:) %>\n\n<% if aliases.any? %>\n  <div class=\"space-y-8\">\n    <div class=\"mb-6\">\n      <div class=\"mb-4 flex items-center justify-between\">\n        <h3 class=\"text-lg font-semibold text-gray-800\">\n          <%= aliases.size %> Known <%= \"Alias\".pluralize(aliases.size) %>\n        </h3>\n      </div>\n\n      <p class=\"text-[#636B74] mb-6\">\n        These are alternative names and slugs that have been merged into <%= user.name %>'s profile.\n      </p>\n\n      <div class=\"overflow-x-auto\">\n        <table class=\"table table-zebra w-full\">\n          <thead>\n            <tr>\n              <th>Name</th>\n              <th>Slug</th>\n              <th>Created</th>\n            </tr>\n          </thead>\n          <tbody>\n            <% aliases.each do |alias_record| %>\n              <tr>\n                <td><%= alias_record.name %></td>\n                <td><code class=\"text-sm bg-base-200 px-2 py-1 rounded\"><%= alias_record.slug %></code></td>\n                <td><%= alias_record.created_at.strftime(\"%b %d, %Y\") %></td>\n              </tr>\n            <% end %>\n          </tbody>\n        </table>\n      </div>\n    </div>\n  </div>\n<% else %>\n  <div class=\"text-center py-12\">\n    <p class=\"text-[#636B74]\">No known aliases for this user.</p>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/_events.html.erb",
    "content": "<%# Event Participations v1 %>\n\n<% future_events = events.upcoming.sort_by(&:sort_date).reverse %>\n<% past_events = (events.to_a - future_events).sort_by(&:sort_date).reverse %>\n<% event_kinds = events.map(&:kind).uniq.sort %>\n\n<% cache [user, events, Current.user] do %>\n  <div data-controller=\"events-filter\" data-events-filter-current-value=\"all\">\n    <% if events.any? %>\n      <%= render \"shared/filter_buttons\", kinds: event_kinds, current_filter: \"all\" %>\n    <% end %>\n\n    <div class=\"space-y-8\">\n        <% if future_events.any? %>\n          <div>\n            <h3 class=\"text-lg font-semibold mb-4\">Future Events</h3>\n            <div class=\"mb-6\">\n              <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\" data-events-filter-target=\"group\">\n                <% future_events.each do |event| %>\n                  <div data-events-filter-target=\"event\" data-kind=\"<%= event.kind %>\">\n                    <%= cache [event, participations[event.id]] do %>\n                      <%= render partial: \"events/card\", locals: {event: event, participation: participations[event.id]} %>\n                    <% end %>\n                  </div>\n                <% end %>\n              </div>\n            </div>\n          </div>\n        <% end %>\n\n        <% if past_events.any? %>\n          <div>\n            <h3 class=\"text-lg font-semibold mb-4\">Past Events</h3>\n            <div class=\"mb-6\">\n              <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\" data-events-filter-target=\"group\">\n                <% past_events.each do |event| %>\n                  <div data-events-filter-target=\"event\" data-kind=\"<%= event.kind %>\">\n                    <%= cache [event, participations[event.id]] do %>\n                      <%= render partial: \"events/card\", locals: {event: event, participation: participations[event.id]} %>\n                    <% end %>\n                  </div>\n                <% end %>\n              </div>\n            </div>\n          </div>\n        <% end %>\n\n      <div class=\"text-center py-12 hidden only:block\">\n        <div class=\"mb-6\">\n          <h3 class=\"text-lg font-semibold text-gray-900 mb-2\">No participated events yet</h3>\n          <p class=\"text-gray-600 mb-6 max-w-xl mx-auto\">\n            <% if Current.user == user %>\n              You haven't marked your participation in any events yet. Visit <%= link_to \"event pages\", events_path, class: \"link link-primary link-ghost\" %> or search events with <kbd class=\"kbd kbd-sm text-base-content\">⌘ k</kbd> and click \"Add to My Events\" to start building your event history.\n            <% elsif Current.user %>\n              This user hasn't marked their participation in any events yet.\n            <% else %>\n              Sign in to manage your profile and mark your participation in events you've attended.\n            <% end %>\n          </p>\n        </div>\n\n        <% if Current.user && Current.user == user %>\n          <div class=\"space-y-3\">\n            <%= link_to events_path, class: \"btn btn-primary\", data: {turbo_frame: \"_top\"} do %>\n              <%= fa(\"magnifying-glass\", style: :regular) %>\n              Browse Events\n            <% end %>\n          </div>\n        <% elsif !Current.user %>\n          <div class=\"space-y-3\">\n            <%= link_to \"Sign in\", new_session_path(redirect_to: request.fullpath), data: {turbo_frame: \"modal\"}, class: \"btn btn-primary\" %>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/_form.html.erb",
    "content": "<%= form_with(model: user, url: profile_path(user)) do |form| %>\n  <div class=\"grid lg:grid-cols-2 gap-4 mb-8\">\n    <div class=\"col-span-2\">\n      <%= form.label :bio %>\n      <%= form.text_area :bio, rows: 4, class: \"textarea textarea-bordered w-full\" %>\n    </div>\n\n    <div>\n      <%= form.label :name %>\n      <%= form.text_field :name, disabled: true, class: \"input input-bordered w-full\" %>\n    </div>\n\n    <div>\n      <%= form.label :location %>\n      <%= form.text_field :location, class: \"input input-bordered w-full\" %>\n    </div>\n\n    <div>\n      <%= form.label :github_handle, \"GitHub\" %>\n      <%= form.text_field :github_handle, class: \"input input-bordered w-full\" %>\n    </div>\n\n    <div>\n      <%= form.label :twitter, \"Twitter/X (URL or handle)\" %>\n      <%= form.text_field :twitter, class: \"input input-bordered w-full\" %>\n    </div>\n\n    <div>\n      <%= form.label :mastodon, \"Mastodon (Full URL/handle)\" %>\n      <%= form.text_field :mastodon, class: \"input input-bordered w-full\" %>\n    </div>\n\n    <div>\n      <%= form.label :linkedin, \"LinkedIn (URL or slug)\" %>\n      <%= form.text_field :linkedin, class: \"input input-bordered w-full\" %>\n    </div>\n\n    <div>\n      <%= form.label :bsky, \"Bluesky (URL or handle)\" %>\n      <%= form.text_field :bsky, class: \"input input-bordered w-full\" %>\n    </div>\n\n    <div>\n      <%= form.label :speakerdeck, \"Speakerdeck\" %>\n      <%= form.text_field :speakerdeck, class: \"input input-bordered w-full\" %>\n    </div>\n\n    <div>\n      <%= form.label :pronouns %>\n      <div data-controller=\"pronouns-select\">\n        <%= form.select :pronouns_type, User::PRONOUNS, {}, class: \"select select-bordered w-full\", data: {action: \"pronouns-select#change\", pronouns_select_target: \"type\"} %>\n        <%= form.text_field :pronouns, placeholder: \"Custom pronouns\", class: \"hidden mt-3 input input-bordered w-full\", data: {pronouns_select_target: \"input\"} %>\n      </div>\n    </div>\n\n    <div>\n      <%= form.label :website %>\n      <%= form.text_field :website, class: \"input input-bordered w-full\" %>\n    </div>\n  </div>\n\n  <div class=\"flex items-center gap-4 justify-end\">\n    <%= ui_button \"Cancel\", data: {action: \"click->modal#close\"}, role: :button, kind: :ghost %>\n\n    <% if user.managed_by?(Current.user) %>\n      <%= ui_button \"Update profile\", type: :submit %>\n    <% else %>\n      <%= ui_button \"Suggest modifications\", type: :submit %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/_header.html.erb",
    "content": "<%# locals: (user:, favorite_user:) %>\n\n<div class=\"block lg:flex gap-8 align-center justify-between\" id=\"<%= dom_id(user, :header) %>\">\n  <%= render \"profiles/header_content\", user:, favorite_user: %>\n\n  <div class=\"flex flex-col gap-2 items-start lg:max-w-[250px]\">\n    <%= render \"profiles/actions\", user: user %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/_header_content.html.erb",
    "content": "<%# locals: (user:, favorite_user: nil) %>\n\n<div id=\"<%= dom_id(user, :header_content) %>\" class=\"flex flex-col lg:flex-row gap-8 items-center lg:justify-right text-center lg:text-left mb-6 lg:mb-0\">\n  <div class=\"relative w-fit\">\n    <%= ui_avatar(user, size_class: \"size-24 md:size-36\", size: :lg) %>\n  </div>\n\n  <div class=\"flex-col flex gap-2 title justify-center items-center lg:items-start\">\n    <% if user.suspicious? && Current.user&.admin? %>\n      <div class=\"bg-yellow-100 border border-yellow-400 text-yellow-800 px-4 py-2 rounded mb-2 text-sm\">\n        This user has been flagged as suspicious.\n      </div>\n    <% end %>\n\n    <div class=\"flex flex-col lg:flex-row items-center justify-center lg:justify-start text-black font-bold gap-2 flex-nowrap\">\n      <h1 class=\"flex gap-2 items-center\"><%= user.suspicious? ? truncate(user.name, length: 10) : user.name %>\n        <% if user.pronouns.present? && [\"dont_specify\", \"not_specified\"].exclude?(user.pronouns_type) %>\n          <span class=\"text-sm content-center text-[#737373]\">(<%= user.pronouns %>)</span>\n        <% end %>\n\n        <% if user.verified? %>\n          <%= ui_tooltip \"#{user.name} is a verified Rubyist\" do %>\n            <%= fa(\"badge-check\", class: \"fill-blue-500\", size: :sm) %>\n          <% end %>\n        <% end %>\n\n        <% if user.ruby_passport_claimed? %>\n          <%= ui_tooltip \"#{user.name} claimed #{user.possessive_pronoun} Ruby Passport\" do %>\n            <%= fa(\"passport\", class: \"fill-orange-800\") %>\n          <% end %>\n        <% end %>\n\n        <% if user.contributor? %>\n          <%= link_to contributors_path, class: \"inline-flex items-center\" do %>\n            <%= ui_tooltip \"#{user.name} contributed to RubyEvents.org\" do %>\n              <span class=\"flex items-center justify-center size-5 bg-green-500 rounded-full\">\n                <span style=\"transform: scale(0.6);\"><%= fa(\"code-pull-request\", class: \"fill-white\") %></span>\n              </span>\n            <% end %>\n          <% end %>\n        <% end %>\n        <%= render \"favorite_users/favorite_user\", favorite_user: favorite_user %>\n      </h1>\n\n    </div>\n\n    <% if user.bio.present? && !user.suspicious? %>\n      <p class=\"text-[#636B74] max-w-[700px]\">\n        <%= user.bio %>\n      </p>\n    <% end %>\n\n    <% if user.to_location.present? %>\n      <p class=\"max-w-[700px] flex flex-row justify-center items-center gap-2\">\n        <%= fa(\"location-dot\", size: :xs, style: :regular) %>\n        <span><%= user.to_location.to_html %></span>\n      </p>\n    <% end %>\n\n    <% if user.website.present? && !user.suspicious? %>\n      <div class=\"link inline-flex items-center gap-2 flex-nowrap\">\n        <%= fa(\"website-brands\", size: :xs) %>\n        <%= external_link_to user.website.gsub(%r{^https?://}, \"\"), user.website, class: \"link inline-flex items-center gap-2 flex-nowrap\" %>\n      </div>\n    <% end %>\n\n    <% unless user.suspicious? %>\n      <div class=\"mt-2 flex justify-center lg:justify-start\">\n        <%= render \"profiles/socials\", user: user %>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/_involvements.html.erb",
    "content": "<%# locals: (events:, user:, involvements_by_role:) %>\n\n<% cache [user, involvements_by_role, Current.user] do %>\n  <% if involvements_by_role.any? %>\n    <div class=\"space-y-8\">\n        <% if involvements_by_role.any? %>\n          <% involvements_by_role.each do |role, events| %>\n            <div>\n              <h3 class=\"text-lg font-semibold mb-4\">\n                Involved as <%= role %>\n              </h3>\n              <div class=\"mb-6\">\n                <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n                  <%= cache events do %>\n                    <%= render partial: \"events/card\", collection: events, as: :event, cached: true %>\n                  <% end %>\n                </div>\n              </div>\n            </div>\n          <% end %>\n        <% else %>\n          <div class=\"text-center py-12\">\n            <div class=\"mb-6\">\n              <h3 class=\"text-lg font-semibold text-gray-900 mb-2\">No involvements yet</h3>\n              <p class=\"text-gray-600 mb-6 max-w-xl mx-auto\">\n                <% if Current.user == user %>\n                  You don't have any event involvements recorded yet.\n                <% else %>\n                  <%= user.name %> doesn't have any event involvements recorded yet.\n                <% end %>\n              </p>\n            </div>\n          </div>\n        <% end %>\n    </div>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/_map.html.erb",
    "content": "<% if countries_with_events.any? %>\n  <div role=\"tablist\" class=\"tabs tabs-boxed bg-base-100 mt-2\">\n    <input type=\"radio\" name=\"map_view\" role=\"tab\" class=\"tab px-6 !rounded-lg\" aria-label=\"Map\" checked>\n    <div role=\"tabpanel\" class=\"tab-content mt-6\">\n      <div\n        id=\"profile-map\"\n        class=\"w-full h-[600px] md:h-[800px] rounded-lg\"\n        data-controller=\"map\"\n        data-map-markers-value=\"<%= event_map_markers.to_json %>\"></div>\n    </div>\n\n    <input type=\"radio\" name=\"map_view\" role=\"tab\" class=\"tab px-6 !rounded-lg\" aria-label=\"List\">\n    <div role=\"tabpanel\" class=\"tab-content mt-6\">\n      <div class=\"space-y-8\">\n        <% countries_with_events.group_by { |country, _| country.continent_name }.sort_by(&:first).each do |continent, countries_group| %>\n          <div>\n            <h3 class=\"text-lg font-semibold mb-4\"><%= continent %></h3>\n            <div class=\"grid sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n              <% countries_group.each do |country, events| %>\n                <%= render \"shared/country_card\", country: country, events: events %>\n              <% end %>\n            </div>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/_mutual_events.html.erb",
    "content": "<%# locals: (user:, events:) %>\n\n<% if events.any? %>\n  <% cache [user, events, Current.user] do %>\n    <% if Current.user && Current.user != user %>\n      <div class=\"space-y-8\">\n        <div class=\"mb-6\">\n          <% if events.upcoming.any? %>\n            <div>\n              <h3 class=\"text-lg font-semibold mb-4\">Future Events <%= user.name %> and <%= Current.user.name %> are attending</h3>\n              <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n                <%= render partial: \"events/card\", collection: events.upcoming, as: :event, cached: true %>\n              </div>\n            </div>\n          <% end %>\n\n          <% if events.past.any? %>\n            <div>\n              <h3 class=\"text-lg font-semibold mb-4 mt-5\">Past Events <%= user.name %> and <%= Current.user.name %> both attended</h3>\n              <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n                <%= render partial: \"events/card\", collection: events.past, as: :event, cached: true %>\n              </div>\n            </div>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/_navigation.html.erb",
    "content": "<%# locals: (user:, favorite_user:, talks:, events:, mutual_events:, stamps:, events_with_stickers:, involvements_by_role:, countries_with_events:, aliases: []) %>\n\n<div role=\"tablist\" class=\"tabs tabs-bordered\">\n  <% if talks.length.positive? %>\n    <%= active_link_to \"Talks (#{talks.size})\", profile_talks_path(user), class: \"tab px-6\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if events.any? %>\n    <%= active_link_to \"Attended Events (#{events.size})\", profile_events_path(user), class: \"tab px-6\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if mutual_events&.any? && Current.user && Current.user != user %>\n    <%= active_link_to \"Mutual Events (#{mutual_events.size})\", profile_mutual_events_path(user), class: \"tab px-6\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if favorite_user&.persisted? %>\n    <%= active_link_to \"Notes\", profile_notes_path(user), class: \"tab px-6\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if involvements_by_role.any? %>\n    <%= active_link_to \"Involvements\", profile_involvements_path(user), class: \"tab px-6\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if stamps.any? %>\n    <%= active_link_to \"Stamps (#{stamps.size})\", profile_stamps_path(user), class: \"tab px-6\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if events_with_stickers.any? %>\n    <%= active_link_to \"Stickers (#{events_with_stickers.size})\", profile_stickers_path(user), class: \"tab px-6\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if countries_with_events&.any? %>\n    <%= active_link_to \"Map\", profile_map_index_path(user), class: \"tab px-6\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n\n  <% if Current.user&.admin? %>\n    <%= active_link_to \"Aliases (#{aliases.size})\", profile_aliases_path(user), class: \"tab px-6\", active_class: \"tab-active\", role: \"tab\" %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/profiles/_notes.html.erb",
    "content": "<%# locals: (user:, favorite_user:) %>\n\n<% if favorite_user.notes.blank? %>\n  <%= render partial: \"favorite_users/form\", locals: {favorite_user: favorite_user} %>\n<% else %>\n  <h3 class=\"text-lg font-semibold mb-4\">Notes</h3>\n  <p><%= favorite_user.notes %></p>\n  <%= link_to \"Edit\", edit_profile_notes_path(user), class: \"btn btn-secondary mt-4\" %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/_socials.html.erb",
    "content": "<div id=\"<%= dom_id(user, :socials) %>\">\n  <div id=\"socials\" class=\"flex items-center gap-2\">\n    <% if user.github_handle.present? %>\n      <%= ui_button url: \"https://www.github.com/#{user.github_handle}\", kind: :circle, size: :sm, target: \"_blank\", class: \"hover:bg-black hover:fill-white border-base-200\" do %>\n        <%= fab(\"github\", size: :md) %>\n      <% end %>\n    <% end %>\n\n    <% if user.twitter.present? %>\n      <%= ui_button url: \"https://www.x.com/#{user.twitter}\", kind: :circle, size: :sm, target: \"_blank\", class: \"hover:bg-black hover:fill-white border-base-200\" do %>\n        <%= fab(\"x-twitter\", size: :md) %>\n      <% end %>\n    <% end %>\n\n    <% if user.bsky.present? %>\n      <%= ui_button url: \"https://bsky.app/profile/#{user.bsky}\", kind: :circle, size: :sm, target: \"_blank\", class: \"hover:bg-[#0085FF] hover:fill-white border-base-200\" do %>\n        <%= fab(\"bluesky\", size: :md) %>\n      <% end %>\n    <% end %>\n\n    <% if user.mastodon.present? %>\n      <%= ui_button url: user.mastodon, kind: :circle, size: :sm, target: \"_blank\", class: \"hover:bg-[#6364FF] hover:fill-white border-base-200\", data: {tip: user.mastodon} do %>\n        <%= fab(\"mastodon\", size: :md) %>\n      <% end %>\n    <% end %>\n\n    <% if user.linkedin.present? %>\n      <%= ui_button url: \"https://www.linkedin.com/in/#{user.linkedin}\", kind: :circle, size: :sm, target: \"_blank\", class: \"hover:bg-[#0A66C2] hover:fill-white border-base-200\", data: {tip: user.linkedin} do %>\n        <%= fab(\"linkedin\", size: :md) %>\n      <% end %>\n    <% end %>\n\n    <% if user.speakerdeck.present? %>\n      <%= ui_button url: \"https://speakerdeck.com/#{user.speakerdeck}\", kind: :circle, size: :sm, target: \"_blank\", class: \"hover:bg-[#009287] hover:fill-white border-base-200\", data: {tip: user.speakerdeck} do %>\n        <%= fab(\"speaker-deck\", size: :md) %>\n      <% end %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/_stamps.html.erb",
    "content": "<%# locals: (user:, stamps:) %>\n\n<% if stamps.any? %>\n  <div class=\"space-y-8\">\n    <div class=\"mb-6\">\n        <div class=\"mb-4 flex items-center justify-between\">\n          <h3 class=\"text-lg font-semibold text-gray-800\">\n            <%= stamps.size %> <%= \"Stamp\".pluralize(stamps.size) %> Collected\n          </h3>\n          <%= link_to \"View all stamps\", stamps_path, class: \"link text-sm\", data: {turbo_frame: \"_top\"} %>\n        </div>\n\n        <p class=\"text-[#636B74] mb-6\">\n          <%= user.name %> has collected stamps from attending events in <%= pluralize(stamps.map(&:country).compact.uniq.size, \"country\") %>.\n        </p>\n\n        <!-- Stamps Grid -->\n        <%= render partial: \"shared/stamps_grid\", locals: {stamps: stamps} %>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/_stickers.html.erb",
    "content": "<% if events_with_stickers.any? %>\n  <%= render partial: \"shared/stickers_display\", locals: {events: events_with_stickers} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/_tab_layout.html.erb",
    "content": "<%# locals: (user:, topics:, favorite_user:, talks:, events:, mutual_events:, stamps:, events_with_stickers:, involvements_by_role:, countries_with_events:, aliases: []) %>\n\n<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n<%= turbo_stream_from user %>\n\n<div class=\"container py-8\">\n  <%= render partial: \"profiles/header\", locals: {user: user, favorite_user: favorite_user} %>\n  <%= render partial: \"profiles/topics\", locals: {topics: topics, user: user, talks: talks} %>\n\n  <hr class=\"my-6\">\n\n  <%= turbo_frame_tag dom_id(user), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n    <%= render partial: \"profiles/navigation\", locals: {\n          user: user,\n          favorite_user: favorite_user,\n          talks: talks,\n          events: events,\n          mutual_events: mutual_events,\n          stamps: stamps,\n          events_with_stickers: events_with_stickers,\n          involvements_by_role: involvements_by_role,\n          countries_with_events: countries_with_events,\n          aliases: aliases\n        } %>\n\n    <div class=\"mt-6\">\n      <%= yield %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/profiles/_talks.html.erb",
    "content": "<% if talks.length.positive? %>\n  <div role=\"tablist\" class=\"tabs tabs-boxed bg-base-100 mt-2\">\n    <input type=\"radio\" name=\"talk_kinds\" role=\"tab\" class=\"tab px-6 !rounded-lg\" aria-label=\"All\" <% if talks.size.positive? %> checked <% end %>>\n    <div role=\"tabpanel\" class=\"tab-content mt-6\">\n      <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n        <%= render partial: \"talks/card\",\n              collection: talks,\n              as: :talk,\n              locals: {\n                favoritable: true,\n                user_favorite_talks_ids: user_favorite_talks_ids,\n                user_watched_talks: user_watched_talks,\n                back_to: back_to_from_request,\n                back_to_title: user.name\n              } %>\n      </div>\n    </div>\n    <% talks_by_kind.each do |kind, talks| %>\n      <input type=\"radio\" name=\"talk_kinds\" role=\"tab\" class=\"tab px-6 !rounded-lg\" aria-label=\"<%= talks.first.formatted_kind.pluralize %> (<%= talks.size %>)\">\n\n      <div role=\"tabpanel\" class=\"tab-content mt-6\">\n        <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n          <%= render partial: \"talks/card\",\n                collection: talks,\n                as: :talk,\n                locals: {\n                  favoritable: true,\n                  user_favorite_talks_ids: user_favorite_talks_ids,\n                  user_watched_talks: user_watched_talks,\n                  back_to: back_to_from_request,\n                  back_to_title: user.name\n                } %>\n        </div>\n      </div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/_topics.html.erb",
    "content": "<%# locals: (user:, topics: [], talks: []) %>\n\n<% if topics.any? && talks.length.positive? %>\n  <% cache [topics, back_to_from_request, user.name] do %>\n    <div class=\"mt-9 mb-3\">\n      <%= render partial: \"topics/badge_list\", locals: {topics: topics, back_to_url: back_to_from_request, back_to_title: user.name} %>\n    </div>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/actions/_admin.html.erb",
    "content": "<%= ui_button url: edit_profile_path(user), kind: :neutral, size: :sm, data: {turbo_frame: \"modal\"} do %>\n  <%= fa \"pen\", size: :xs %>\n  <span>Update speaker page</span>\n<% end %>\n\n<% if user.github_handle.present? || user.bsky.present? %>\n  <%= ui_button url: profiles_enhance_path(user), method: :put, kind: :neutral, size: :sm do %>\n    <%= fa \"wand-magic-sparkles\", size: :xs %>\n    <span>Enhance Profile</span>\n  <% end %>\n<% end %>\n\n<%= ui_button url: reindex_profile_path(user), method: :post, kind: :neutral, size: :sm do %>\n  <%= fa \"arrows-rotate\", size: :xs %>\n  <span>Reindex Profile</span>\n<% end %>\n\n<%= ui_button url: avo.resources_user_path(user), target: :_blank, kind: :neutral, size: :sm do %>\n  <%= fa :avocado, size: :xs %>\n\n  <span>Open in Avo</span>\n<% end %>\n\n<% if Rails.env.development? %>\n  <%= ui_button url: \"https://rubyevents.org#{profile_path(user)}\", target: :_blank, kind: :neutral, size: :sm do %>\n    <%= fa :browser, size: :xs %>\n    <span>Show on RubyEvents.org</span>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/actions/_anonymous.html.erb",
    "content": "<% if user.github_handle.blank? %>\n  <!-- While merging the speaker and user models we disable the actions for now -->\n  <!-- TODO: Re-enable when the merge is complete and once the user profile is ready -->\n  <%= link_to edit_profile_path(user), class: \"link link-accent link-ghost\", data: {turbo_frame: \"modal\"} do %>\n    Help us improve the speaker profile by adding a GitHub handle\n  <% end %>\n<% else %>\n  <% if !user.verified? %>\n    <div class=\"flex flex-col gap-4 hotwire-native:hidden\">\n      <div class=\"content text-sm\">\n        <span>\n          Are you <strong><%= user.name %></strong>?\n\n          <%= link_to new_session_path(redirect_to: request.fullpath), class: \"link link-neutral font-light\", data: {turbo_frame: \"modal\"} do %>\n            Claim your profile to manage and edit content.\n          <% end %>\n        </span>\n      </div>\n\n      <% if false %>\n        <!-- While merging the speaker and user models we disable the actions for now -->\n        <!-- TODO: Re-enable when the merge is complete and once the user profile is ready -->\n        <%= ui_button url: edit_profile_path(user), kind: :neutral, size: :sm, data: {turbo_frame: \"modal\"} do %>\n          <%= fa :pen, size: :xs %>\n          <span>Suggest improvements</span>\n        <% end %>\n      <% end %>\n    </div>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/actions/_owner.html.erb",
    "content": "<%= ui_button url: edit_profile_path(user), kind: :neutral, size: :sm, data: {turbo_frame: \"modal\"} do %>\n  <%= fa :pen, size: :xs %>\n  <span>Update my profile</span>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/actions/_signed_in.html.erb",
    "content": "<% if false %>\n  <!-- While merging the speaker and user models we disable the actions for now -->\n  <!-- TODO: Re-enable when the merge is complete and once the user profile is ready -->\n  <% if speaker.github_handle.blank? %>\n    <%= link_to edit_profile_path(speaker), class: \"link link-accent link-ghost\", data: {turbo_frame: \"modal\"} do %>\n      Help us improve the speaker profile by adding a GitHub handle\n    <% end %>\n  <% else %>\n    <%= ui_button url: edit_profile_path(speaker), kind: :neutral, size: :sm, data: {turbo_frame: \"modal\"} do %>\n      <%= fa :pen, size: :xs %>\n      <span>Suggest improvements</span>\n    <% end %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/aliases/index.html.erb",
    "content": "<%= render layout: \"profiles/tab_layout\", locals: {\n      user: @user,\n      topics: @topics,\n      talks: @talks,\n      events: @events,\n      mutual_events: @mutual_events,\n      stamps: @stamps,\n      events_with_stickers: @events_with_stickers,\n      involvements_by_role: @involvements_by_role,\n      countries_with_events: @countries_with_events,\n      aliases: @aliases,\n      favorite_user: @favorite_user\n    } do %>\n  <%= render partial: \"profiles/aliases\", locals: {user: @user, aliases: @aliases} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/connect/_claim_profile.html.erb",
    "content": "<div class=\"flex flex-col items-center justify-center text-center space-y-8 py-12 px-6\">\n  <!-- Icon -->\n  <div class=\"text-4xl\">\n    🎉 🎉 🎉\n    <%#= fa \"user-plus\", variant: :solid, class: \"w-10 h-10 text-primary\" %>\n  </div>\n\n  <!-- Heading -->\n  <div class=\"space-y-6\">\n    <h2 class=\"text-2xl font-bold text-base-content\">\n      Passsport <span class=\"text-primary\"><%= connect_id.upcase %></span> is available to Claim!\n    </h2>\n    <p class=\"text-base-content/70 max-w-md\">\n      <% if Current.user %>\n        This Ruby passport is waiting for you! Claim it and start building your Ruby community presence.\n      <% else %>\n        This Ruby passport is waiting for you! Sign in with your GitHub account to claim it and start building your Ruby community presence.\n      <% end %>\n    </p>\n  </div>\n\n  <!-- Features list -->\n  <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-4 max-w-md text-sm\">\n    <div class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa :calendar, variant: :solid, class: \"w-5 h-5 text-success flex-shrink-0\" %>\n      <span>Track your conferences</span>\n    </div>\n    <div class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa :heart, variant: :solid, class: \"w-5 h-5 text-success flex-shrink-0\" %>\n      <span>Collect memories</span>\n    </div>\n    <div class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa :users, variant: :solid, class: \"w-5 h-5 text-success flex-shrink-0\" %>\n      <span>Join the community</span>\n    </div>\n    <div class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa :\"share-nodes\", variant: :solid, class: \"w-5 h-5 text-success flex-shrink-0\" %>\n      <span>Share your experiences</span>\n    </div>\n  </div>\n\n  <!-- CTA Button -->\n  <div class=\"pt-4\">\n    <% if Current.user %>\n      <%= ui_button url: profiles_claims_path(id: params[:id]), kind: :primary, size: :lg, class: \"px-8 shadow-lg\", data: {turbo_method: :post} do %>\n        <%= fa \"arrow-right\", variant: :solid, class: \"w-5 h-5 mr-2\" %>\n        Claim my Passport\n      <% end %>\n    <% else %>\n      <%= ui_button url: new_session_path(connect_id: params[:id]), kind: :primary, size: :lg, class: \"px-8 shadow-lg\", data: {turbo_frame: \"modal\"} do %>\n        <%= fa \"arrow-right\", variant: :solid, class: \"w-5 h-5 mr-2\" %>\n        Claim my Passport\n      <% end %>\n    <% end %>\n  </div>\n\n  <!-- Trust indicator -->\n  <div class=\"text-xs text-base-content/50 flex items-center space-x-1\">\n    <%= fa \"shield-check\", variant: :solid, class: \"w-4 h-4\" %>\n    <span>Secure GitHub authentication</span>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/connect/_friend_prompt.html.erb",
    "content": "<div class=\"flex flex-col items-center justify-center text-center space-y-6 py-12 px-6\">\n  <!-- Icon -->\n  <div class=\"flex items-center justify-center w-20 h-20 bg-success/10 rounded-full\">\n    <% if found_user.present? %>\n      <%= image_tag found_user.avatar_url, class: \"w-full h-full rounded-full\" %>\n    <% else %>\n      <%= fa \"user-group\", variant: :solid, class: \"w-10 h-10 text-success\" %>\n    <% end %>\n  </div>\n\n  <!-- Heading -->\n  <div class=\"space-y-2\">\n    <h2 class=\"text-2xl font-bold text-base-content\">\n      🎉 Awesome! You Discovered a Friend\n    </h2>\n    <p class=\"text-base-content/70 max-w-md\">\n      Connect with <%= found_user.name %> to expand your network and discover new opportunities together.\n    </p>\n  </div>\n\n  <!-- Features list -->\n  <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-4 max-w-md text-sm\">\n    <div class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa \"comments\", variant: :solid, class: \"w-5 h-5 text-success flex-shrink-0\" %>\n      <span>Start conversations</span>\n    </div>\n    <div class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa :calendar, variant: :solid, class: \"w-5 h-5 text-success flex-shrink-0\" %>\n      <span>Share events</span>\n    </div>\n    <div class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa \"graduation-cap\", variant: :solid, class: \"w-5 h-5 text-success flex-shrink-0\" %>\n      <span>Exchange knowledge</span>\n    </div>\n    <div class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa :sparkles, variant: :solid, class: \"w-5 h-5 text-success flex-shrink-0\" %>\n      <span>Collaborate on projects</span>\n    </div>\n  </div>\n\n  <!-- CTA Button -->\n  <div class=\"pt-4\">\n    <% if Current.user.present? %>\n      <% if false # enable this when we have a way to connect to other users %>\n        <%= ui_button url: \"#\", kind: :primary, size: :lg, class: \"px-8 shadow-lg btn-disabled hidden\" do %>\n          <%= fa :plus, variant: :solid, class: \"w-5 h-5 mr-2\" %>\n          Connect\n        <% end %>\n      <% end %>\n    <% else %>\n      <%= ui_button url: new_session_path(connect_to: params[:id]), kind: :primary, size: :lg, class: \"px-8 shadow-lg\", data: {turbo_frame: \"modal\"} do %>\n        <%= fa \"arrow-right\", variant: :solid, class: \"w-5 h-5 mr-2\" %>\n        Sign In and Connect\n      <% end %>\n\n      <!-- Network indicator -->\n      <div class=\"text-xs text-base-content/50 flex items-center space-x-1 pt-4 justify-center\">\n        <%= fa \"globe\", variant: :solid, class: \"w-4 h-4\" %>\n        <span>Join the Ruby community network</span>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/connect/_no_profile_found.html.erb",
    "content": "<div class=\"flex flex-col items-center justify-center text-center space-y-6 py-12 px-6\">\n  <!-- Icon -->\n  <div class=\"flex items-center justify-center w-20 h-20 bg-neutral/10 rounded-full\">\n    <%= fa \"magnifying-glass\", variant: :solid, class: \"w-10 h-10 text-neutral\" %>\n  </div>\n\n  <!-- Heading -->\n  <div class=\"space-y-2\">\n    <h2 class=\"text-2xl font-bold text-base-content\">\n      🤷‍♂️ No Profile Found Here\n    </h2>\n    <p class=\"text-base-content/70 max-w-md\">\n      This page doesn't have an associated profile yet. But don't worry - there's still plenty to explore in the Ruby community!\n    </p>\n  </div>\n\n  <!-- Suggestions list -->\n  <div class=\"grid grid-cols-1 sm:grid-cols-2 gap-4 max-w-md text-sm\">\n    <a href=\"<%= talks_path %>\" class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa \"video\", variant: :solid, class: \"w-5 h-5 text-neutral flex-shrink-0\" %>\n      <span>Browse talks</span>\n    </a>\n    <a href=\"<%= events_path %>\" class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa \"calendar-days\", variant: :solid, class: \"w-5 h-5 text-neutral flex-shrink-0\" %>\n      <span>Discover events</span>\n    </a>\n    <a href=\"<%= speakers_path %>\" class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa :users, variant: :solid, class: \"w-5 h-5 text-neutral flex-shrink-0\" %>\n      <span>Meet speakers</span>\n    </a>\n    <a href=\"<%= topics_path %>\" class=\"flex items-center space-x-2 text-base-content/80\">\n      <%= fa :hashtag, variant: :solid, class: \"w-5 h-5 text-neutral flex-shrink-0\" %>\n      <span>Explore topics</span>\n    </a>\n  </div>\n\n  <!-- CTA Buttons -->\n  <div class=\"flex flex-col sm:flex-row gap-3 pt-4\">\n    <%= ui_button url: talks_path, kind: :primary, size: :lg, class: \"px-6 shadow-lg\" do %>\n      <%= fa :play, variant: :solid, class: \"w-5 h-5 mr-2\" %>\n      Browse Talks\n    <% end %>\n\n    <%= ui_button url: events_path, kind: :secondary, size: :lg, class: \"px-6\" do %>\n      <%= fa :calendar, variant: :solid, class: \"w-5 h-5 mr-2\" %>\n      View Events\n    <% end %>\n  </div>\n\n  <!-- Community indicator -->\n  <div class=\"text-xs text-base-content/50 flex items-center space-x-1\">\n    <%= fa :heart, variant: :solid, class: \"w-4 h-4\" %>\n    <span>Explore the Ruby community</span>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/connect/show.html.erb",
    "content": "<%# for now the user can only claim a profile. The friendship functionnality is not yet built %>\n<%= render partial: \"claim_profile\", locals: {connect_id: @connect_id} %>\n"
  },
  {
    "path": "app/views/profiles/edit.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<div class=\"container py-8\">\n  <div class=\"max-w-2xl mx-auto\">\n    <h1 class=\"text-3xl font-bold mb-8\">Edit Profile</h1>\n\n    <%= render \"form\", user: @user %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/enhance/update.turbo_stream.erb",
    "content": ""
  },
  {
    "path": "app/views/profiles/events/index.html.erb",
    "content": "<%= render layout: \"profiles/tab_layout\", locals: {\n      user: @user,\n      topics: @topics,\n      talks: @talks,\n      events: @events,\n      mutual_events: @mutual_events,\n      stamps: @stamps,\n      events_with_stickers: @events_with_stickers,\n      involvements_by_role: @involvements_by_role,\n      countries_with_events: @countries_with_events,\n      favorite_user: @favorite_user\n    } do %>\n  <%= render partial: \"profiles/events\", locals: {user: @user, events: @events, talks: @talks, participations: @participations} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/involvements/index.html.erb",
    "content": "<%= render layout: \"profiles/tab_layout\", locals: {\n      user: @user,\n      topics: @topics,\n      talks: @talks,\n      events: @events,\n      mutual_events: @mutual_events,\n      stamps: @stamps,\n      events_with_stickers: @events_with_stickers,\n      involvements_by_role: @involvements_by_role,\n      countries_with_events: @countries_with_events,\n      favorite_user: @favorite_user\n    } do %>\n  <%= render partial: \"profiles/involvements\", locals: {user: @user, events: @involved_events, involvements_by_role: @involvements_by_role} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/map/index.html.erb",
    "content": "<%= render layout: \"profiles/tab_layout\", locals: {\n      user: @user,\n      topics: @topics,\n      talks: @talks,\n      events: @events,\n      mutual_events: @mutual_events,\n      stamps: @stamps,\n      events_with_stickers: @events_with_stickers,\n      involvements_by_role: @involvements_by_role,\n      countries_with_events: @countries_with_events,\n      favorite_user: @favorite_user\n    } do %>\n  <%= render partial: \"profiles/map\", locals: {countries_with_events: @countries_with_events, event_map_markers: @event_map_markers} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/mutual_events/index.html.erb",
    "content": "<%= render layout: \"profiles/tab_layout\", locals: {\n      user: @user,\n      topics: @topics,\n      talks: @talks,\n      events: @events,\n      mutual_events: @mutual_events,\n      stamps: @stamps,\n      events_with_stickers: @events_with_stickers,\n      involvements_by_role: @involvements_by_role,\n      countries_with_events: @countries_with_events,\n      favorite_user: @favorite_user\n    } do %>\n  <%= render partial: \"profiles/mutual_events\", locals: {user: @user, events: @mutual_events} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/notes/edit.html.erb",
    "content": "<%= render layout: \"profiles/tab_layout\", locals: {\n      user: @user,\n      topics: @topics,\n      talks: @talks,\n      events: @events,\n      mutual_events: @mutual_events,\n      stamps: @stamps,\n      events_with_stickers: @events_with_stickers,\n      involvements_by_role: @involvements_by_role,\n      countries_with_events: @countries_with_events,\n      favorite_user: @favorite_user\n    } do %>\n  <%= render partial: \"favorite_users/form\", locals: {favorite_user: @favorite_user, redirect_to: profile_notes_path(@user)} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/notes/show.html.erb",
    "content": "<%= render layout: \"profiles/tab_layout\", locals: {\n      user: @user,\n      topics: @topics,\n      talks: @talks,\n      events: @events,\n      mutual_events: @mutual_events,\n      stamps: @stamps,\n      events_with_stickers: @events_with_stickers,\n      involvements_by_role: @involvements_by_role,\n      countries_with_events: @countries_with_events,\n      favorite_user: @favorite_user\n    } do %>\n  <%= render partial: \"profiles/notes\", locals: {user: @user, favorite_user: @favorite_user} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/show.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n<%= turbo_stream_from @user %>\n\n<div class=\"container py-8\">\n  <%= render partial: \"profiles/header\", locals: {user: @user, favorite_user: @favorite_user} %>\n  <%= render partial: \"profiles/topics\", locals: {topics: @topics, user: @user, talks: @talks} %>\n\n  <hr class=\"my-6\">\n\n  <%= turbo_frame_tag dom_id(@user), data: {turbo_action: \"advance\", turbo_frame: \"_top\"} do %>\n    <%= render partial: \"profiles/navigation\", locals: {\n          user: @user,\n          favorite_user: @favorite_user,\n          talks: @talks,\n          events: @events,\n          mutual_events: @mutual_events,\n          stamps: @stamps,\n          events_with_stickers: @events_with_stickers,\n          involvements_by_role: @involvements_by_role,\n          countries_with_events: @countries_with_events,\n          aliases: @aliases\n        } %>\n\n    <div class=\"mt-6\">\n      <% if @talks.any? %>\n        <%= render partial: \"profiles/talks\", locals: {user: @user, talks: @talks, user_favorite_talks_ids: @user_favorite_talks_ids, talks_by_kind: @talks_by_kind} %>\n      <% else %>\n        <%= render partial: \"profiles/events\", locals: {user: @user, events: @events, talks: @talks, participations: @participations} %>\n      <% end %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/profiles/stamps/index.html.erb",
    "content": "<%= render layout: \"profiles/tab_layout\", locals: {\n      user: @user,\n      topics: @topics,\n      talks: @talks,\n      events: @events,\n      mutual_events: @mutual_events,\n      stamps: @stamps,\n      events_with_stickers: @events_with_stickers,\n      involvements_by_role: @involvements_by_role,\n      countries_with_events: @countries_with_events,\n      favorite_user: @favorite_user\n    } do %>\n  <%= render partial: \"profiles/stamps\", locals: {user: @user, stamps: @stamps} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/stickers/index.html.erb",
    "content": "<%= render layout: \"profiles/tab_layout\", locals: {\n      user: @user,\n      topics: @topics,\n      talks: @talks,\n      events: @events,\n      mutual_events: @mutual_events,\n      stamps: @stamps,\n      events_with_stickers: @events_with_stickers,\n      involvements_by_role: @involvements_by_role,\n      countries_with_events: @countries_with_events,\n      favorite_user: @favorite_user\n    } do %>\n  <%= render partial: \"profiles/stickers\", locals: {events_with_stickers: @events_with_stickers} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/talks/index.html.erb",
    "content": "<%= render layout: \"profiles/tab_layout\", locals: {\n      user: @user,\n      topics: @topics,\n      talks: @talks,\n      events: @events,\n      mutual_events: @mutual_events,\n      stamps: @stamps,\n      events_with_stickers: @events_with_stickers,\n      involvements_by_role: @involvements_by_role,\n      countries_with_events: @countries_with_events,\n      favorite_user: @favorite_user\n    } do %>\n  <%= render partial: \"profiles/talks\", locals: {user: @user, talks: @talks, user_favorite_talks_ids: @user_favorite_talks_ids, talks_by_kind: @talks_by_kind} %>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/wrapped/_share.html.erb",
    "content": "<%= turbo_frame_tag \"wrapped-share\" do %>\n  <div class=\"flex-1 flex flex-col items-center justify-center\">\n    <% if is_owner %>\n      <div class=\"w-full max-w-xs mb-6\">\n        <div class=\"p-4 rounded-lg <%= user.wrapped_public? ? \"bg-green-50 border border-green-200\" : \"bg-gray-50 border border-gray-200\" %>\">\n          <div class=\"flex items-center justify-between\">\n            <div>\n              <p class=\"font-semibold <%= user.wrapped_public? ? \"text-green-700\" : \"text-gray-700\" %>\">\n                <%= user.wrapped_public? ? \"🌍 Public\" : \"🔒 Private\" %>\n              </p>\n              <p class=\"text-xs text-gray-500 mt-1\">\n                <%= user.wrapped_public? ? \"Anyone with the link can view\" : \"Only you can see this\" %>\n              </p>\n            </div>\n\n            <%= button_to toggle_visibility_profile_wrapped_index_path(profile_slug: user.to_param),\n                  method: :post,\n                  class: \"px-4 py-2 rounded-lg text-sm font-medium transition #{user.wrapped_public? ? \"bg-gray-200 text-gray-700 hover:bg-gray-300\" : \"bg-green-600 text-white hover:bg-green-700\"}\",\n                  data: {turbo_frame: \"wrapped-share\"} do %>\n              <%= user.wrapped_public? ? \"Make Private\" : \"Make Public\" %>\n            <% end %>\n          </div>\n        </div>\n      </div>\n    <% end %>\n\n    <div class=\"space-y-3 w-full max-w-xs <%= user.wrapped_public? ? \"\" : \"opacity-50 pointer-events-none\" %>\">\n      <% stats_lines = [] %>\n\n      <% stats_lines << \"📺 #{total_talks_watched} talks watched\" if total_talks_watched.positive? %>\n      <% stats_lines << \"🎪 #{events_attended_in_year.count} events attended\" if events_attended_in_year.any? %>\n      <% stats_lines << \"🎤 #{talks_given_in_year.count} talks given\" if talks_given_in_year.any? %>\n      <% stats_lines << \"🌍 #{countries_visited.count} #{(countries_visited.count == 1) ? \"country\" : \"countries\"} visited\" if countries_visited.any? %>\n\n      <% hashtags = \"#ruby #rubyevents\" %>\n      <% x_share_text = ([\"My #{year} @rubyevents_org Wrapped 💎\", \"\"] + stats_lines + [\"\", share_url, \"\", hashtags]).join(\"\\n\") %>\n      <% bluesky_share_text = ([\"My #{year} @rubyevents.org Wrapped 💎\", \"\"] + stats_lines + [\"\", share_url, \"\", hashtags]).join(\"\\n\") %>\n      <% mastodon_share_text = ([\"My #{year} @rubyevents@ruby.social Wrapped 💎\", \"\"] + stats_lines + [\"\", share_url, \"\", hashtags]).join(\"\\n\") %>\n      <% default_share_text = ([\"My #{year} RubyEvents.org Wrapped 💎\", \"\"] + stats_lines + [\"\", share_url, \"\", hashtags]).join(\"\\n\") %>\n\n      <div class=\"group relative w-full\">\n        <div class=\"flex items-center justify-center gap-3 w-full p-3 bg-red-600 text-white rounded-lg cursor-pointer\">\n          <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4\" /></svg>\n          <span class=\"font-medium\">Download Summary Card</span>\n        </div>\n\n        <div class=\"absolute inset-0 hidden group-hover:flex rounded-lg overflow-hidden\">\n          <%= button_to generate_card_profile_wrapped_index_path(profile_slug: user.to_param, orientation: :vertical),\n                method: :post,\n                data: {turbo: false},\n                form: {class: \"flex-1 flex\"},\n                class: \"flex-1 flex items-center justify-center gap-2 bg-red-700 text-white hover:bg-red-800 transition cursor-pointer w-full\" do %>\n            <span class=\"font-medium text-sm\">Vertical</span>\n          <% end %>\n          <%= button_to generate_card_profile_wrapped_index_path(profile_slug: user.to_param, orientation: :horizontal),\n                method: :post,\n                data: {turbo: false},\n                form: {class: \"flex-1 flex border-l border-red-600\"},\n                class: \"flex-1 flex items-center justify-center gap-2 bg-red-700 text-white hover:bg-red-800 transition cursor-pointer w-full\" do %>\n            <span class=\"font-medium text-sm\">Horizontal</span>\n          <% end %>\n        </div>\n      </div>\n\n      <a\n        href=\"https://twitter.com/intent/tweet?text=<%= ERB::Util.url_encode(x_share_text) %>\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        class=\"flex items-center justify-center gap-3 w-full p-3 bg-black text-white rounded-lg hover:bg-gray-800 transition\">\n        <svg class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\" /></svg>\n        <span class=\"font-medium\">Share on X</span>\n      </a>\n\n      <a href=\"https://bsky.app/intent/compose?text=<%= ERB::Util.url_encode(bluesky_share_text) %>\"\n         target=\"_blank\"\n         rel=\"noopener noreferrer\"\n         class=\"flex items-center justify-center gap-3 w-full p-3 bg-sky-500 text-white rounded-lg hover:bg-sky-600 transition\">\n        <svg class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 600 530\"><path d=\"m135.72 44.03c66.496 49.921 138.02 151.14 164.28 205.46 26.262-54.316 97.782-155.54 164.28-205.46 47.98-36.021 125.72-63.892 125.72 24.795 0 17.712-10.155 148.79-16.111 170.07-20.703 73.984-96.144 92.854-163.25 81.433 117.3 19.964 147.14 86.092 82.697 152.22-122.39 125.59-175.91-31.511-189.63-71.766-2.514-7.3797-3.6904-10.832-3.7077-7.8964-0.0174-2.9357-1.1937 0.51669-3.7077 7.8964-13.714 40.255-67.233 197.36-189.63 71.766-64.444-66.128-34.605-132.26 82.697-152.22-67.108 11.421-142.55-7.4491-163.25-81.433-5.9562-21.282-16.111-152.36-16.111-170.07 0-88.687 77.742-60.816 125.72-24.795z\" /></svg>\n        <span class=\"font-medium\">Share on Bluesky</span>\n      </a>\n\n      <a\n        href=\"https://ruby.social/share?text=<%= ERB::Util.url_encode(mastodon_share_text) %>\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        class=\"flex items-center justify-center gap-3 w-full p-3 bg-indigo-500 text-white rounded-lg hover:bg-indigo-600 transition\">\n        <svg class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.668 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z\" /></svg>\n        <span class=\"font-medium\">Share on Ruby.social</span>\n      </a>\n\n      <a\n        href=\"https://www.linkedin.com/sharing/share-offsite/?url=<%= ERB::Util.url_encode(share_url) %>\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        class=\"flex items-center justify-center gap-3 w-full p-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition\">\n        <svg class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" /></svg>\n        <span class=\"font-medium\">Share on LinkedIn</span>\n      </a>\n\n      <div data-controller=\"copy-to-clipboard\" data-copy-to-clipboard-success-message-value=\"✓ Copied!\" data-copy-to-clipboard-success-class=\"!bg-green-100 !text-green-700\">\n        <span data-copy-to-clipboard-target=\"source\" class=\"hidden\"><%= share_url %></span>\n        <button data-action=\"copy-to-clipboard#copy\" data-copy-to-clipboard-target=\"button\" class=\"flex items-center justify-center gap-3 w-full p-3 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-all duration-200\">\n          <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" /></svg>\n          <span class=\"font-medium\">Copy Link</span>\n        </button>\n      </div>\n    </div>\n\n    <% unless user.wrapped_public? %>\n      <p class=\"text-xs text-gray-500 mt-4 text-center\">Make your Wrapped public to share it</p>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/wrapped/card.html.erb",
    "content": "<div class=\"wrapped-page wrapped-cover\" id=\"summary-card\">\n  <div class=\"flex-1 flex flex-col items-center justify-center\">\n    <div class=\"w-20 h-20 mx-auto rounded-full border-3 border-white overflow-hidden bg-white/20 mb-3\">\n      <% if @user.custom_avatar? %>\n        <%= image_tag @user.avatar_url(size: 80), class: \"w-full h-full object-cover\", alt: @user.name %>\n      <% else %>\n        <div class=\"w-full h-full flex items-center justify-center text-2xl font-bold\">\n          <%= @user.name.first.upcase %>\n        </div>\n      <% end %>\n    </div>\n\n    <p class=\"font-bold text-lg mb-0\"><%= @user.name %></p>\n    <p class=\"text-red-200 text-sm mb-4\"><%= @year %> Wrapped</p>\n\n    <div class=\"grid grid-cols-3 gap-2 w-full max-w-xs mb-3\">\n      <div class=\"text-center p-2 bg-white/10 rounded-lg\">\n        <p class=\"text-xl font-bold\"><%= @total_talks_watched %></p>\n        <p class=\"text-[10px] text-red-200\">Talks Watched</p>\n      </div>\n      <div class=\"text-center p-2 bg-white/10 rounded-lg\">\n        <p class=\"text-xl font-bold\"><%= @total_watch_time_hours %>h</p>\n        <p class=\"text-[10px] text-red-200\">Watch Time</p>\n      </div>\n      <div class=\"text-center p-2 bg-white/10 rounded-lg\">\n        <p class=\"text-xl font-bold\"><%= @events_attended_in_year.count %></p>\n        <p class=\"text-[10px] text-red-200\">Events</p>\n      </div>\n    </div>\n\n    <div class=\"grid grid-cols-2 gap-2 w-full max-w-xs mb-3\">\n      <div class=\"text-center p-2 bg-white/10 rounded-lg\">\n        <p class=\"text-xl font-bold\"><%= @countries_visited.count %></p>\n        <p class=\"text-[10px] text-red-200\">Countries Visited</p>\n      </div>\n      <% if @talks_given_in_year.any? %>\n        <div class=\"text-center p-2 bg-white/20 rounded-lg\">\n          <p class=\"text-xl font-bold\"><%= @talks_given_in_year.count %></p>\n          <p class=\"text-[10px] text-red-200\">Talks Given</p>\n        </div>\n      <% else %>\n        <div class=\"text-center p-2 bg-white/10 rounded-lg\">\n          <p class=\"text-xl font-bold\"><%= @top_topics.count %></p>\n          <p class=\"text-[10px] text-red-200\">Topics Explored</p>\n        </div>\n      <% end %>\n    </div>\n\n    <% if @personality.present? %>\n      <div class=\"personality-badge text-sm px-4 py-2 mb-3\">\n        <%= @personality %>\n      </div>\n    <% end %>\n\n    <% if @top_topics.any? %>\n      <div class=\"flex flex-wrap justify-center gap-1 max-w-xs\">\n        <% @top_topics.first(3).each do |topic, _| %>\n          <span class=\"px-2 py-1 bg-white/10 rounded text-xs\"><%= topic.name %></span>\n        <% end %>\n      </div>\n    <% end %>\n  </div>\n\n  <div class=\"mt-auto pt-4 text-center\">\n    <p class=\"text-xs text-red-200 mb-1\">See my full Wrapped at</p>\n    <p class=\"text-sm font-bold\">RubyEvents.org <%= @year %> Wrapped</p>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/index.html.erb",
    "content": "<% pages = [] %>\n\n<% pages << {partial: \"cover\", cover: true} %>\n<% pages << {partial: \"watching_journey\"} %>\n<% pages << {partial: \"top_topics\"} %>\n<% pages << {partial: \"top_speakers\"} %>\n<% pages << {partial: \"top_events\"} %>\n<% pages << {partial: \"watching_calendar\"} %>\n<% pages << {partial: \"content_mix\"} %>\n<% pages << {partial: \"events_attended\"} %>\n\n<% pages << {partial: \"event_map\"} if @event_map_markers.any? %>\n<% pages << {partial: \"conference_buddies\"} if @conference_buddies.any? %>\n<% pages << {partial: \"watch_twin\"} if @watch_twin %>\n<% pages << {partial: \"speaker_journey\"} if @talks_given_in_year.any? %>\n<% pages << {partial: \"speaking_calendar\"} if @talks_given_in_year.any? %>\n<% pages << {partial: \"involvements\"} if @involvements_in_year.any? %>\n<% pages << {partial: \"contributor\"} if @is_contributor %>\n<% pages << {partial: \"passport_holder\"} if @has_passport %>\n<% pages << {partial: \"stamps\"} if @stamps_earned.any? %>\n<% pages << {partial: \"stickers\"} if @stickers_earned.any? %>\n<% pages << {partial: \"bookends\"} if @first_watched && @last_watched %>\n<% pages << {partial: \"fun_facts\"} %>\n<% pages << {partial: \"languages\"} if @languages_watched.any? && @languages_watched.size > 1 %>\n<% pages << {partial: \"summary_card\", cover: true} %>\n<% pages << {partial: \"closing\", cover: true} %>\n\n<div data-controller=\"wrapped-stories\" data-action=\"keydown@window->wrapped-stories#handleKeydown\">\n  <div class=\"flex justify-center gap-3 mb-6 no-print\">\n    <%= link_to wrapped_path, class: \"px-4 py-2 bg-white/10 hover:bg-white/20 text-white rounded-full text-sm font-medium transition flex items-center gap-2\" do %>\n      <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\" />\n      </svg>\n      <%= @year %> Wrapped\n    <% end %>\n\n    <button\n      data-action=\"wrapped-stories#toggleMode\"\n      class=\"px-4 py-2 bg-white/10 hover:bg-white/20 text-white rounded-full text-sm font-medium transition flex items-center gap-2\">\n      <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 6h16M4 12h16M4 18h16\" />\n      </svg>\n      <span data-wrapped-stories-target=\"modeLabel\">View as Stories</span>\n    </button>\n\n    <% if !@is_owner && Current.user %>\n      <%= link_to profile_wrapped_index_path(Current.user), class: \"px-4 py-2 bg-white/10 hover:bg-white/20 text-white rounded-full text-sm font-medium transition flex items-center gap-2\" do %>\n        <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n          <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\" />\n        </svg>\n        See Your Wrapped\n      <% end %>\n    <% end %>\n  </div>\n\n  <div data-wrapped-stories-target=\"scrollView\">\n    <% pages.each do |page| %>\n      <div id=\"<%= page[:partial].dasherize %>\" class=\"wrapped-page <%= \"wrapped-cover\" if page[:cover] %>\">\n        <%= render \"profiles/wrapped/pages/#{page[:partial]}\", **@wrapped_locals %>\n      </div>\n    <% end %>\n\n    <% if @is_owner %>\n      <div class=\"wrapped-page\">\n        <h2 class=\"text-2xl font-bold mb-2 text-center\">Share Your Wrapped</h2>\n        <p class=\"text-gray-500 text-center mb-6\">Let the Ruby community see your year!</p>\n        <%= render \"profiles/wrapped/share\", **@wrapped_locals %>\n      </div>\n    <% end %>\n  </div>\n\n  <div data-wrapped-stories-target=\"storiesView\" class=\"hidden\">\n    <div class=\"stories-container\" data-wrapped-stories-target=\"container\">\n      <div class=\"stories-progress\">\n        <% pages.each do |page| %>\n          <div class=\"stories-progress-bar\" data-wrapped-stories-target=\"progress\"></div>\n        <% end %>\n\n        <% if @is_owner %>\n          <div class=\"stories-progress-bar\" data-wrapped-stories-target=\"progress\"></div>\n        <% end %>\n      </div>\n\n      <div class=\"stories-close\" data-action=\"click->wrapped-stories#toggleMode\">\n        <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n          <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\" />\n        </svg>\n      </div>\n\n      <div class=\"stories-nav stories-nav-left\" data-action=\"click->wrapped-stories#previous\"></div>\n      <div class=\"stories-nav stories-nav-right\" data-action=\"click->wrapped-stories#next\"></div>\n\n      <div class=\"stories-content\">\n        <% pages.each do |page| %>\n          <div class=\"stories-page <%= \"stories-cover\" if page[:cover] %>\" data-wrapped-stories-target=\"page\" data-page-name=\"<%= page[:partial].dasherize %>\">\n            <%= render \"profiles/wrapped/pages/#{page[:partial]}\", **@wrapped_locals %>\n          </div>\n        <% end %>\n\n        <% if @is_owner %>\n          <div class=\"stories-page\" data-wrapped-stories-target=\"page\" data-page-name=\"share\">\n            <h2 class=\"text-2xl font-bold mb-2 text-center\">Share Your Wrapped</h2>\n            <p class=\"text-gray-500 text-center mb-6\">Let the Ruby community see your year!</p>\n            <%= render \"profiles/wrapped/share\", **@wrapped_locals %>\n          </div>\n        <% end %>\n      </div>\n\n      <div class=\"stories-counter\" data-wrapped-stories-target=\"counter\">1 / <%= pages.size + (@is_owner ? 1 : 0) %></div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_bookends.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Bookends of <%= year %></h2>\n<p class=\"text-gray-500 text-center mb-6\">Where your watching journey started and ended</p>\n\n<div class=\"flex-1 space-y-6\">\n  <div>\n    <p class=\"text-sm text-gray-500 mb-2\">🎬 Your first watch of the year:</p>\n    <div class=\"p-4 bg-green-50 border border-green-200 rounded-lg\">\n      <p class=\"font-semibold\"><%= first_watched.talk.title.truncate(60) %></p>\n      <p class=\"text-sm text-gray-600 mt-1\">\n        by <%= first_watched.talk.speakers.map(&:name).join(\", \").truncate(40) %>\n      </p>\n      <p class=\"text-xs text-gray-400 mt-2\">\n        <%= first_watched.created_at.strftime(\"%B %d, %Y\") %>\n      </p>\n    </div>\n  </div>\n\n  <div>\n    <p class=\"text-sm text-gray-500 mb-2\">🏁 Your last watch of the year:</p>\n    <div class=\"p-4 bg-blue-50 border border-blue-200 rounded-lg\">\n      <p class=\"font-semibold\"><%= last_watched.talk.title.truncate(60) %></p>\n      <p class=\"text-sm text-gray-600 mt-1\">\n        by <%= last_watched.talk.speakers.map(&:name).join(\", \").truncate(40) %>\n      </p>\n      <p class=\"text-xs text-gray-400 mt-2\">\n        <%= last_watched.created_at.strftime(\"%B %d, %Y\") %>\n      </p>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_closing.html.erb",
    "content": "<div class=\"flex-1 flex flex-col items-center justify-center text-center\">\n  <div class=\"text-6xl mb-6\">💎</div>\n\n  <h2 class=\"text-3xl font-bold mb-4\">That's a Wrap!</h2>\n\n  <p class=\"text-red-100 mb-6 max-w-xs\">\n    Thank you for being part of the Ruby community and for trusting RubyEvents.org to be your companion throughout <%= year %>.\n  </p>\n\n  <p class=\"text-red-200 text-sm max-w-xs mb-6\">\n    Every talk watched, every event attended, and every connection made helps keep our community strong and growing.\n  </p>\n\n  <p class=\"text-red-100 text-sm max-w-xs\">\n    Here's to more Ruby adventures in <%= year + 1 %>!\n  </p>\n</div>\n\n<div class=\"mt-auto pt-8 flex flex-col items-center\">\n  <%= image_tag \"logo.png\", class: \"w-8 h-8 mb-1\", alt: \"RubyEvents.org\" %>\n  <p class=\"font-bold\">RubyEvents.org</p>\n  <p class=\"text-xs text-red-200\">See you at a Ruby event soon! 🎉</p>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_conference_buddies.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Your Conference Buddies</h2>\n<p class=\"text-gray-500 text-center mb-6\">People you crossed paths with at events</p>\n\n<div class=\"space-y-4 flex-1\">\n  <% conference_buddies.first(6).each do |buddy| %>\n    <div class=\"flex items-center gap-3 p-3 bg-gray-50 rounded-lg\">\n      <div class=\"w-12 h-12 rounded-full overflow-hidden bg-gray-200 flex-shrink-0\">\n        <%= image_tag buddy.user.avatar_url(size: 80), class: \"w-full h-full object-cover\", alt: buddy.user.name %>\n      </div>\n      <div class=\"flex-1 min-w-0\">\n        <p class=\"font-semibold truncate\"><%= buddy.user.name %></p>\n        <p class=\"text-sm text-gray-500\">\n          <%= buddy.shared_count %> <%= \"event\".pluralize(buddy.shared_count) %> together\n        </p>\n      </div>\n      <div class=\"text-2xl\">\n        <% if buddy.shared_count >= 3 %>\n          🤝\n        <% elsif buddy.shared_count >= 2 %>\n          👋\n        <% else %>\n          ✨\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n</div>\n\n<% if conference_buddies.count > 6 %>\n  <div class=\"mt-4 text-center text-sm text-gray-500\">\n    + <%= conference_buddies.count - 6 %> more buddies\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_content_mix.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Content Mix</h2>\n<p class=\"text-gray-500 text-center mb-6\">The types of talks you enjoyed</p>\n\n<% if talk_kinds.any? %>\n  <div class=\"space-y-4 flex-1\">\n    <% talk_kinds.each do |kind, count| %>\n      <% percentage = (total_talks_watched.positive? ? (count.to_f / total_talks_watched * 100).round : 0) %>\n      <div>\n        <div class=\"flex justify-between mb-1\">\n          <span class=\"font-medium\"><%= Talk::KIND_LABELS[kind.to_s] || kind.to_s.humanize %></span>\n          <span class=\"text-gray-500\"><%= count %> (<%= percentage %>%)</span>\n        </div>\n        <div class=\"bg-gray-100 rounded-full h-3\">\n          <div class=\"month-bar h-3\" style=\"width: <%= percentage %>%\"></div>\n        </div>\n      </div>\n    <% end %>\n  </div>\n<% else %>\n  <div class=\"flex-1 flex items-center justify-center\">\n    <p class=\"text-gray-400 text-center\">Watch talks to see your content preferences!</p>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_contributor.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Open Source Hero</h2>\n<p class=\"text-gray-500 text-center mb-6\">You helped build RubyEvents.org!</p>\n\n<div class=\"flex-1 flex flex-col items-center justify-center\">\n  <div class=\"w-32 h-32 mb-6 relative\">\n    <div class=\"absolute inset-0 bg-gradient-to-br from-green-400 to-green-600 rounded-full animate-pulse opacity-30\"></div>\n    <div class=\"absolute inset-2 bg-gradient-to-br from-green-500 to-green-700 rounded-full flex items-center justify-center\">\n      <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"w-16 h-16 text-white\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n        <path d=\"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z\" />\n      </svg>\n    </div>\n  </div>\n\n  <div class=\"text-center mb-6\">\n    <p class=\"text-4xl font-black text-green-500 mb-2\">Contributor</p>\n    <p class=\"text-gray-600\">You're part of the team!</p>\n  </div>\n\n  <div class=\"bg-green-50 rounded-xl p-4 w-full max-w-xs text-center\">\n    <p class=\"text-sm text-gray-600 mb-2\">Contributing as</p>\n    <p class=\"font-bold text-green-700\">@<%= contributor.login %></p>\n  </div>\n\n  <div class=\"mt-6 text-center\">\n    <p class=\"text-sm text-gray-500\">\n      Thank you for helping make Ruby conference videos accessible to everyone!\n    </p>\n  </div>\n</div>\n\n<div class=\"mt-auto pt-4 text-center\">\n  <%= link_to \"View all contributors\", contributors_path, class: \"text-sm text-red-600 hover:underline\", target: \"_blank\" %>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_cover.html.erb",
    "content": "<div class=\"mb-6\">\n  <svg width=\"100\" height=\"100\" viewBox=\"0 0 80 80\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n    <path d=\"M2 25 L16 10 L64 10 L78 25 L40 70 Z\"\n          fill=\"white\" />\n  </svg>\n</div>\n\n<div class=\"mt-4 mb-8\">\n\n  <div class=\"w-24 h-24 mx-auto rounded-full border-4 border-white overflow-hidden bg-white/20\">\n    <% if user.custom_avatar? %>\n      <%= image_tag user.avatar_url(size: 120), class: \"w-full h-full object-cover\", alt: user.name %>\n    <% else %>\n      <div class=\"w-full h-full flex items-center justify-center text-3xl font-bold\">\n        <%= user.name.first.upcase %>\n      </div>\n    <% end %>\n  </div>\n\n  <p class=\"mt-4 font-bold text-xl mb-2\"><%= user.name %></p>\n\n</div>\n\n<p class=\"text-lg text-red-200 mb-2\" style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">RubyEvents.org</p>\n<h1 class=\"text-5xl font-black mb-2\" style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\"><%= year %></h1>\n<p class=\"text-3xl font-bold mb-2\" style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">Wrapped</p>\n\n<div class=\"mt-auto pt-8 flex flex-col items-center\">\n  <%= image_tag \"logo.png\", class: \"w-10 h-10 mb-2\", alt: \"RubyEvents.org\" %>\n  <p class=\"text-sm text-red-200\">Your Year in Ruby Events</p>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_event_map.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Your Event Map</h2>\n<p class=\"text-gray-500 text-center mb-6\">Where Ruby took you in <%= year %></p>\n\n<div class=\"flex-1 flex items-center\">\n  <div\n    id=\"wrapped-map\"\n    class=\"w-full h-[400px] rounded-lg\"\n    data-controller=\"map\"\n    data-map-markers-value=\"<%= event_map_markers.to_json %>\">\n  </div>\n</div>\n\n<div class=\"mt-4 text-center text-sm text-gray-500\">\n  <%= countries_visited.count %> <%= (countries_visited.count == 1) ? \"country\" : \"countries\" %> visited\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_events_attended.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Events You Attended</h2>\n<p class=\"text-gray-500 text-center mb-6\">Your in-person Ruby adventures</p>\n\n<% if events_attended_in_year.any? %>\n  <div class=\"grid grid-cols-2 gap-4 mb-6\">\n    <div class=\"stat-card\">\n      <div class=\"stat-number text-2xl\"><%= events_attended_in_year.count %></div>\n      <div class=\"stat-label\">Conferences</div>\n    </div>\n    <div class=\"stat-card\">\n      <div class=\"stat-number text-2xl\"><%= countries_visited.count %></div>\n      <div class=\"stat-label\">Countries</div>\n    </div>\n  </div>\n\n  <% if events_as_speaker.positive? || events_as_visitor.positive? %>\n    <div class=\"mb-4\">\n      <p class=\"text-sm text-gray-500 mb-2\">How you participated:</p>\n      <div class=\"flex gap-4 flex-wrap\">\n        <% if events_as_speaker.positive? %>\n          <span class=\"px-3 py-1 bg-red-100 text-red-700 rounded-full text-sm\">\n            🎤 Speaker at <%= events_as_speaker %>\n          </span>\n        <% end %>\n        <% if events_as_visitor.positive? %>\n          <span class=\"px-3 py-1 bg-blue-100 text-blue-700 rounded-full text-sm\">\n            👤 Attendee at <%= events_as_visitor %>\n          </span>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n\n  <% events_by_month = events_attended_in_year.group_by { |e| e.start_date&.month }\n     month_names = %w[Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec] %>\n  <div class=\"flex-1\">\n    <div class=\"grid grid-cols-4 gap-2\">\n      <% (1..12).each do |month| %>\n        <div class=\"text-center\">\n          <p class=\"text-xs text-gray-400 mb-1\"><%= month_names[month - 1] %></p>\n          <div class=\"min-h-[48px] bg-gray-50 rounded-lg p-1 flex flex-wrap items-center justify-center gap-1\">\n            <% if events_by_month[month] %>\n              <% events_by_month[month].each do |event| %>\n                <div class=\"tooltip tooltip-top\" data-tip=\"<%= event.name %>\">\n                  <div class=\"w-8 h-8 rounded-md overflow-hidden border border-gray-200\">\n                    <%= image_tag event.avatar_image_path, alt: event.name, class: \"w-full h-full object-cover\" %>\n                  </div>\n                </div>\n              <% end %>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    </div>\n  </div>\n<% else %>\n  <div class=\"flex-1 flex items-center justify-center\">\n    <p class=\"text-gray-400 text-center\">Mark events as attended to track your conference journey!</p>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_fun_facts.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Fun Facts</h2>\n<p class=\"text-gray-500 text-center mb-6\">Some interesting tidbits about your year</p>\n\n<div class=\"space-y-4 flex-1\">\n  <% if longest_streak.positive? %>\n    <div class=\"p-4 bg-orange-50 border border-orange-200 rounded-lg\">\n      <div class=\"flex items-center gap-3\">\n        <span class=\"text-2xl\">🔥</span>\n        <div>\n          <p class=\"font-semibold text-orange-700\"><%= longest_streak %> Day Streak</p>\n          <p class=\"text-sm text-gray-600\">Your longest watching streak</p>\n        </div>\n      </div>\n    </div>\n  <% end %>\n\n  <% if most_active_weekday %>\n    <div class=\"p-4 bg-purple-50 border border-purple-200 rounded-lg\">\n      <div class=\"flex items-center gap-3\">\n        <span class=\"text-2xl\">📅</span>\n        <div>\n          <p class=\"font-semibold text-purple-700\"><%= Date::DAYNAMES[most_active_weekday] %>s</p>\n          <p class=\"text-sm text-gray-600\">Your favorite day to watch talks</p>\n        </div>\n      </div>\n    </div>\n  <% end %>\n\n  <% if most_active_month %>\n    <div class=\"p-4 bg-teal-50 border border-teal-200 rounded-lg\">\n      <div class=\"flex items-center gap-3\">\n        <span class=\"text-2xl\">📆</span>\n        <div>\n          <p class=\"font-semibold text-teal-700\"><%= Date::MONTHNAMES[most_active_month] %></p>\n          <p class=\"text-sm text-gray-600\">Your most active watching month</p>\n        </div>\n      </div>\n    </div>\n  <% end %>\n\n  <% if longest_watched && longest_watched.talk.duration.present? %>\n    <div class=\"p-4 bg-blue-50 border border-blue-200 rounded-lg\">\n      <div class=\"flex items-center gap-3\">\n        <span class=\"text-2xl\">⏱️</span>\n        <div>\n          <p class=\"font-semibold text-blue-700\">Longest Talk: <%= longest_watched.talk.formatted_duration %></p>\n          <p class=\"text-sm text-gray-600 truncate\"><%= longest_watched.talk.title.truncate(35) %></p>\n        </div>\n      </div>\n    </div>\n  <% end %>\n\n  <% if shortest_watched && shortest_watched != longest_watched && shortest_watched.talk.duration.present? %>\n    <div class=\"p-4 bg-green-50 border border-green-200 rounded-lg\">\n      <div class=\"flex items-center gap-3\">\n        <span class=\"text-2xl\">⚡</span>\n        <div>\n          <p class=\"font-semibold text-green-700\">Shortest Talk: <%= shortest_watched.talk.formatted_duration %></p>\n          <p class=\"text-sm text-gray-600 truncate\"><%= shortest_watched.talk.title.truncate(35) %></p>\n        </div>\n      </div>\n    </div>\n  <% end %>\n\n  <% if events_discovered.positive? %>\n    <div class=\"p-4 bg-pink-50 border border-pink-200 rounded-lg\">\n      <div class=\"flex items-center gap-3\">\n        <span class=\"text-2xl\">🌍</span>\n        <div>\n          <p class=\"font-semibold text-pink-700\"><%= events_discovered %> Events Discovered</p>\n          <p class=\"text-sm text-gray-600\">Different conferences you explored</p>\n        </div>\n      </div>\n    </div>\n  <% end %>\n\n  <% if ruby_friends_met.positive? %>\n    <div class=\"p-4 bg-red-50 border border-red-200 rounded-lg\">\n      <div class=\"flex items-center gap-3\">\n        <span class=\"text-2xl\">👋</span>\n        <div>\n          <p class=\"font-semibold text-red-700\"><%= ruby_friends_met %> Ruby Friends</p>\n          <p class=\"text-sm text-gray-600\">Crossed paths with <%= ruby_friends_met %> Rubyists from RubyEvents.org</p>\n        </div>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_involvements.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Community Builder</h2>\n<p class=\"text-gray-500 text-center mb-6\">Thank you for helping make Ruby events happen!</p>\n\n<div class=\"flex-1 flex flex-col items-center justify-center\">\n  <div class=\"w-24 h-24 mb-6 relative\">\n    <div class=\"absolute inset-0 bg-gradient-to-br from-purple-400 to-purple-600 rounded-full animate-pulse opacity-30\"></div>\n    <div class=\"absolute inset-2 bg-gradient-to-br from-purple-500 to-purple-700 rounded-full flex items-center justify-center\">\n      <span class=\"text-4xl\">🙌</span>\n    </div>\n  </div>\n\n  <div class=\"text-center mb-6\">\n    <p class=\"text-5xl font-black text-purple-600 mb-2\"><%= involvements_in_year.count %></p>\n    <p class=\"text-gray-600\"><%= \"event\".pluralize(involvements_in_year.count) %> you helped with</p>\n  </div>\n\n  <div class=\"w-full space-y-3\">\n    <% involvements_by_role.each do |role, involvements| %>\n      <div class=\"bg-purple-50 rounded-xl p-4\">\n        <div class=\"flex items-center justify-between mb-2\">\n          <span class=\"font-semibold text-purple-700 capitalize\"><%= role %></span>\n          <span class=\"text-sm text-purple-500\"><%= involvements.count %> <%= \"event\".pluralize(involvements.count) %></span>\n        </div>\n        <div class=\"flex flex-wrap gap-1\">\n          <% involvements.first(4).each do |involvement| %>\n            <span class=\"text-xs bg-white px-2 py-1 rounded text-gray-600 truncate max-w-[120px]\">\n              <%= involvement.event.name %>\n            </span>\n          <% end %>\n          <% if involvements.count > 4 %>\n            <span class=\"text-xs bg-white px-2 py-1 rounded text-gray-400\">\n              +<%= involvements.count - 4 %> more\n            </span>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n  </div>\n</div>\n\n<div class=\"mt-auto pt-4 text-center\">\n  <p class=\"text-sm text-gray-500\">\n    The Ruby community thrives because of people like you! 💜\n  </p>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_languages.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Languages</h2>\n<p class=\"text-gray-500 text-center mb-6\">The languages of the talks you watched</p>\n\n<div class=\"space-y-4 flex-1\">\n  <% languages_watched.each do |language, count| %>\n    <% percentage = (total_talks_watched.positive? ? (count.to_f / total_talks_watched * 100).round : 0) %>\n    <div>\n      <div class=\"flex justify-between mb-1\">\n        <span class=\"font-medium\"><%= language %></span>\n        <span class=\"text-gray-500\"><%= count %> (<%= percentage %>%)</span>\n      </div>\n      <div class=\"bg-gray-100 rounded-full h-3\">\n        <div class=\"month-bar h-3\" style=\"width: <%= percentage %>%\"></div>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_og_image.html.erb",
    "content": "<div class=\"flex-1 flex flex-col items-center justify-center\">\n  <div class=\"w-28 h-28 rounded-full border-4 border-white overflow-hidden bg-white/20 mb-3\">\n    <% if user.custom_avatar? %>\n      <%= image_tag user.avatar_url(size: 140), class: \"w-full h-full object-cover\", alt: user.name %>\n    <% else %>\n      <div class=\"w-full h-full flex items-center justify-center text-3xl font-bold\">\n        <%= user.name.first.upcase %>\n      </div>\n    <% end %>\n  </div>\n  <p class=\"font-bold text-3xl mb-8\"><%= user.name %></p>\n\n  <p class=\"text-xl text-red-200 mb-1\">RubyEvents.org</p>\n  <h1 class=\"text-7xl font-black mb-1\"><%= year %></h1>\n  <p class=\"text-4xl font-bold\">Wrapped</p>\n</div>\n\n<div class=\"mt-auto flex items-center justify-center gap-3\">\n  <%= image_tag \"logo.png\", class: \"w-8 h-8\", alt: \"RubyEvents.org\" %>\n  <p class=\"text-lg text-red-200\">See <%= user.name.split.first %>'s full Wrapped at <span class=\"text-white font-bold\">RubyEvents.org/Wrapped</span></p>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_passport_holder.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Physical Passport</h2>\n<p class=\"text-gray-500 text-center mb-6\">You have the real thing!</p>\n\n<div class=\"flex-1 flex flex-col items-center justify-center\">\n  <div class=\"relative mb-6\">\n    <div class=\"w-40 h-56 bg-gradient-to-br from-red-700 to-red-900 rounded-lg shadow-xl transform rotate-3 border-4 border-red-800\">\n      <div class=\"absolute inset-4 border border-yellow-500/50 rounded\"></div>\n      <div class=\"absolute inset-0 flex flex-col items-center justify-center text-yellow-400/90\">\n        <svg class=\"w-12 h-12 mb-2\" viewBox=\"0 0 80 80\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n          <path d=\"M2 25 L16 10 L64 10 L78 25 L40 70 Z\" fill=\"currentColor\" />\n        </svg>\n        <p class=\"text-xs font-bold tracking-wider\">RUBY</p>\n        <p class=\"text-[10px] tracking-widest\">PASSPORT</p>\n      </div>\n    </div>\n    <div class=\"absolute -bottom-2 left-1/2 -translate-x-1/2 w-32 h-4 bg-black/20 blur-md rounded-full\"></div>\n  </div>\n\n  <div class=\"text-center mb-4\">\n    <p class=\"text-3xl font-black text-red-600 mb-1\">Passport Holder</p>\n    <p class=\"text-gray-600\">Official Ruby Passport Holder</p>\n  </div>\n\n  <div class=\"bg-red-50 rounded-xl p-4 w-full max-w-xs text-center\">\n    <p class=\"text-sm text-gray-600\">Claimed on</p>\n    <p class=\"font-bold text-red-700\"><%= passports.first.created_at.strftime(\"%B %d, %Y\") %></p>\n  </div>\n\n  <div class=\"mt-6 text-center\">\n    <p class=\"text-sm text-gray-500\">\n      Collect stamps at Ruby events around the world!\n    </p>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_speaker_journey.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Your Speaker Journey</h2>\n<p class=\"text-gray-500 text-center mb-6\">You shared your knowledge with the community!</p>\n\n<div class=\"grid grid-cols-2 gap-3 mb-6\">\n  <div class=\"stat-card\">\n    <div class=\"stat-number text-2xl\"><%= talks_given_in_year.count %></div>\n    <div class=\"stat-label\">Talks Given</div>\n  </div>\n  <div class=\"stat-card\">\n    <div class=\"stat-number text-2xl\"><%= total_speaking_minutes %>m</div>\n    <div class=\"stat-label\">Recorded Stage Time</div>\n  </div>\n  <div class=\"stat-card\">\n    <div class=\"stat-number text-xl\"><%= number_to_human(total_views_on_talks, precision: 2, significant: false, format: \"%n%u\", units: {thousand: \"K\", million: \"M\"}) %></div>\n    <div class=\"stat-label\">Views on YouTube</div>\n  </div>\n  <div class=\"stat-card\">\n    <div class=\"stat-number text-2xl\"><%= talk_watchers_count %></div>\n    <div class=\"stat-label\">Watchers on RubyEvents.org</div>\n  </div>\n</div>\n\n<% if top_talk_watchers.any? %>\n  <div class=\"flex-1 flex flex-col justify-center\">\n    <p class=\"text-sm font-semibold mb-4 text-center\">Biggest Supporters</p>\n    <div class=\"flex justify-center gap-4\">\n      <% top_talk_watchers.each_with_index do |watcher, index| %>\n        <div class=\"text-center\">\n          <div class=\"relative\">\n            <div class=\"w-16 h-16 rounded-full overflow-hidden border-2 border-red-500 mx-auto bg-gray-100\">\n              <% if watcher.custom_avatar? %>\n                <%= image_tag watcher.avatar_url(size: 64), class: \"w-full h-full object-cover\", alt: watcher.name %>\n              <% else %>\n                <div class=\"w-full h-full flex items-center justify-center text-xl font-bold text-gray-600\">\n                  <%= watcher.name.first.upcase %>\n                </div>\n              <% end %>\n            </div>\n            <div class=\"absolute -bottom-1 -right-1 w-6 h-6 bg-red-500 rounded-full flex items-center justify-center text-white text-xs font-bold\">\n              <%= index + 1 %>\n            </div>\n          </div>\n          <p class=\"text-xs mt-2 font-medium truncate max-w-[80px]\"><%= watcher.name.split.first %></p>\n          <p class=\"text-[10px] text-gray-500\"><%= watcher.watched_count %> talks</p>\n        </div>\n      <% end %>\n    </div>\n  </div>\n<% end %>\n\n<div class=\"mt-auto pt-4 text-center\">\n  <p class=\"text-sm text-gray-500\">Thank you for sharing your knowledge! 🙏</p>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_speaking_calendar.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Your Speaking Calendar</h2>\n<p class=\"text-gray-500 text-center mb-6\">When you took the stage in <%= year %></p>\n\n<% talks_by_month = talks_given_in_year.group_by { |t| t.date&.month }\n   month_names = %w[Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec] %>\n\n<div class=\"flex-1\">\n  <div class=\"grid grid-cols-4 gap-2\">\n    <% (1..12).each do |month| %>\n      <div class=\"text-center\">\n        <p class=\"text-xs text-gray-400 mb-1\"><%= month_names[month - 1] %></p>\n        <div class=\"min-h-[48px] bg-gray-50 rounded-lg p-1 flex flex-wrap items-center justify-center gap-1\">\n          <% if talks_by_month[month] %>\n            <% talks_by_month[month].each do |talk| %>\n              <div class=\"tooltip tooltip-top\" data-tip=\"<%= talk.title %>\">\n                <div class=\"w-8 h-8 rounded-md overflow-hidden border border-gray-200\">\n                  <%= image_tag talk.event&.avatar_image_path, alt: talk.event&.name, class: \"w-full h-full object-cover\" %>\n                </div>\n              </div>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n  </div>\n</div>\n\n<div class=\"mt-auto pt-4 text-center\">\n  <p class=\"text-sm text-gray-500\">\n    <%= talks_given_in_year.count %> <%= (talks_given_in_year.count == 1) ? \"talk\" : \"talks\" %> across <%= talks_by_month.keys.count %> <%= (talks_by_month.keys.count == 1) ? \"month\" : \"months\" %>\n  </p>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_stamps.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Stamps Collected</h2>\n<p class=\"text-gray-500 text-center mb-6\">Souvenirs from your <%= year %> adventures</p>\n\n<div class=\"flex-1 space-y-6\">\n  <% if country_stamps.any? %>\n    <div>\n      <p class=\"text-sm font-semibold mb-2 text-gray-600\">🌍 Countries Visited</p>\n      <div class=\"stamp-grid\">\n        <% country_stamps.first(6).each do |stamp| %>\n          <div class=\"stamp-item\">\n            <%= image_tag stamp.asset_path, alt: stamp.name %>\n          </div>\n        <% end %>\n      </div>\n      <% if country_stamps.count > 6 %>\n        <p class=\"text-xs text-gray-500 mt-2 text-center\">+ <%= country_stamps.count - 6 %> more</p>\n      <% end %>\n    </div>\n  <% end %>\n\n  <% if event_stamps.any? %>\n    <div>\n      <p class=\"text-sm font-semibold mb-2 text-gray-600\">🎪 Event Stamps</p>\n      <div class=\"stamp-grid\">\n        <% event_stamps.first(6).each do |stamp| %>\n          <div class=\"stamp-item\">\n            <%= image_tag stamp.asset_path, alt: stamp.name %>\n          </div>\n        <% end %>\n      </div>\n      <% if event_stamps.count > 6 %>\n        <p class=\"text-xs text-gray-500 mt-2 text-center\">+ <%= event_stamps.count - 6 %> more</p>\n      <% end %>\n    </div>\n  <% end %>\n\n  <% if achievement_stamps.any? %>\n    <div>\n      <p class=\"text-sm font-semibold mb-2 text-gray-600\">🏆 Achievements</p>\n      <div class=\"stamp-grid\">\n        <% achievement_stamps.each do |stamp| %>\n          <div class=\"stamp-item\">\n            <%= image_tag stamp.asset_path, alt: stamp.name %>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_stickers.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Stickers Collected</h2>\n<p class=\"text-gray-500 text-center mb-4\">Event stickers from <%= year %></p>\n\n<div class=\"flex-1 w-full overflow-hidden rounded-2xl bg-gradient-to-b from-gray-300 via-gray-600 to-gray-600 p-[3px]\">\n  <div class=\"w-full h-full overflow-hidden rounded-2xl bg-gradient-to-b from-gray-400 via-gray-500 to-gray-600 p-4 flex items-center justify-center\">\n    <div class=\"grid grid-cols-3 gap-3 w-full place-items-center content-center\">\n      <% stickers_earned.shuffle.each do |sticker| %>\n        <% rotation = rand(-15..15)\n           translate_x = rand(-10..10)\n           translate_y = rand(-10..10)\n           scale = rand(90..110) %>\n        <%= link_to sticker.event, class: \"w-16 h-16 md:w-20 md:h-20 transition-transform hover:scale-110 hover:z-10\", style: \"transform: rotate(#{rotation}deg) translateX(#{translate_x}px) translateY(#{translate_y}px) scale(#{scale}%);\", data: {turbo_frame: \"_top\"} do %>\n          <%= image_tag sticker.asset_path, alt: sticker.name, class: \"w-full h-full object-contain drop-shadow-lg\" %>\n        <% end %>\n      <% end %>\n    </div>\n  </div>\n</div>\n\n<div class=\"text-center text-sm text-gray-500 mt-4\">\n  <%= stickers_earned.count %> sticker<%= (stickers_earned.count == 1) ? \"\" : \"s\" %> collected\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_summary_card.html.erb",
    "content": "<div class=\"flex-1 flex flex-col items-center justify-center\">\n  <div class=\"w-20 h-20 mx-auto rounded-full border-3 border-white overflow-hidden bg-white/20 mb-3\">\n    <% if user.custom_avatar? %>\n      <%= image_tag user.avatar_url(size: 80), class: \"w-full h-full object-cover\", alt: user.name %>\n    <% else %>\n      <div class=\"w-full h-full flex items-center justify-center text-2xl font-bold\">\n        <%= user.name.first.upcase %>\n      </div>\n    <% end %>\n  </div>\n\n  <p class=\"font-bold text-lg mb-1\"><%= user.name %></p>\n  <p class=\"text-red-200 text-sm mb-6\">RubyEvents.org <%= year %> Wrapped</p>\n\n  <% if top_speakers.any? %>\n    <div class=\"flex justify-center -space-x-2 mb-1\">\n      <% top_speakers.first(5).each do |speaker, _| %>\n        <div class=\"w-8 h-8 rounded-full border-2 border-red-600 overflow-hidden bg-white/20\">\n          <%= image_tag speaker.avatar_url(size: 40), class: \"w-full h-full object-cover\", alt: speaker.name %>\n        </div>\n      <% end %>\n    </div>\n    <p class=\"text-[10px] text-red-200 mb-6\">Favorite Speakers</p>\n  <% end %>\n\n  <div class=\"grid grid-cols-2 gap-2 w-full max-w-xs mb-2\">\n    <div class=\"text-center p-2 bg-white/10 rounded-lg\">\n      <p class=\"text-xl font-bold\"><%= total_talks_watched %></p>\n      <p class=\"text-[10px] text-red-200\">Talks Watched</p>\n    </div>\n    <div class=\"text-center p-2 bg-white/10 rounded-lg\">\n      <p class=\"text-xl font-bold\"><%= total_watch_time_hours %>h</p>\n      <p class=\"text-[10px] text-red-200\">Watch Time</p>\n    </div>\n  </div>\n\n  <div class=\"grid grid-cols-2 gap-2 w-full max-w-xs mb-2\">\n    <div class=\"text-center p-2 bg-white/10 rounded-lg\">\n      <p class=\"text-xl font-bold\"><%= events_attended_in_year.count %></p>\n      <p class=\"text-[10px] text-red-200\">Events Attended</p>\n    </div>\n    <div class=\"text-center p-2 bg-white/10 rounded-lg\">\n      <p class=\"text-xl font-bold\"><%= countries_visited.count %></p>\n      <p class=\"text-[10px] text-red-200\">Countries Visited</p>\n    </div>\n  </div>\n\n  <% if talks_given_in_year.any? %>\n    <div class=\"grid grid-cols-2 gap-2 w-full max-w-xs mb-6\">\n      <div class=\"text-center p-2 bg-white/20 rounded-lg\">\n        <p class=\"text-xl font-bold\"><%= talks_given_in_year.count %></p>\n        <p class=\"text-[10px] text-red-200\">Talks Given</p>\n      </div>\n      <div class=\"text-center p-2 bg-white/20 rounded-lg\">\n        <p class=\"text-xl font-bold\"><%= number_to_human(total_views_on_talks, units: {thousand: \"K\", million: \"M\"}, format: \"%n%u\") %></p>\n        <p class=\"text-[10px] text-red-200\">Views on YouTube</p>\n      </div>\n    </div>\n  <% end %>\n\n  <% if involvements_in_year.any? %>\n    <div class=\"grid grid-cols-1 gap-2 w-full max-w-xs mb-6\">\n      <div class=\"text-center p-2 bg-purple-500/30 rounded-lg\">\n        <p class=\"text-xl font-bold\"><%= involvements_in_year.count %></p>\n        <p class=\"text-[10px] text-red-200\">Events Helped Organize</p>\n      </div>\n    </div>\n  <% end %>\n\n  <% if personality.present? %>\n    <div class=\"personality-badge text-sm px-4 py-2 mb-6\">\n      <%= personality %>\n    </div>\n  <% end %>\n\n  <% if top_topics.any? %>\n    <div class=\"flex flex-wrap justify-center gap-1 max-w-xs\">\n      <% top_topics.first(3).each do |topic, _| %>\n        <span class=\"px-2 py-1 bg-white/10 rounded text-xs\"><%= topic.name %></span>\n      <% end %>\n    </div>\n  <% end %>\n</div>\n\n<div class=\"mt-auto pt-4 flex flex-col items-center\">\n  <%= image_tag \"logo.png\", class: \"w-8 h-8 mb-1\", alt: \"RubyEvents.org\" %>\n  <p class=\"text-xs text-red-200 font-bold\">RubyEvents.org/Wrapped</p>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_summary_card_horizontal.html.erb",
    "content": "<div class=\"flex-1 flex gap-12 items-center px-12 pt-8 pb-4\">\n  <div class=\"flex flex-col items-center\">\n    <div class=\"w-32 h-32 rounded-full border-4 border-white overflow-hidden bg-white/20 mb-6\">\n      <% if user.custom_avatar? %>\n        <%= image_tag user.avatar_url(size: 256), class: \"w-full h-full object-cover\", alt: user.name %>\n      <% else %>\n        <div class=\"w-full h-full flex items-center justify-center text-5xl font-bold text-white\">\n          <%= user.name.first.upcase %>\n        </div>\n      <% end %>\n    </div>\n    <p class=\"text-red-300 text-lg\"><%= user.name %></p>\n    <h1 class=\"text-6xl font-black text-white mt-2\"><%= year %></h1>\n    <p class=\"text-3xl font-bold text-red-200 mt-1\">Wrapped</p>\n    <p class=\"text-red-300/80 text-sm mt-4\">RubyEvents.org/Wrapped</p>\n  </div>\n\n  <div class=\"flex-1 grid grid-cols-2 gap-6\">\n    <div class=\"bg-white/10 backdrop-blur rounded-2xl p-8 text-center\">\n      <p class=\"text-6xl font-black text-white\"><%= total_talks_watched %></p>\n      <p class=\"text-red-200 text-lg mt-2\">Talks Watched</p>\n    </div>\n    <div class=\"bg-white/10 backdrop-blur rounded-2xl p-8 text-center\">\n      <p class=\"text-6xl font-black text-white\"><%= total_watch_time_hours %>h</p>\n      <p class=\"text-red-200 text-lg mt-2\">Watch Time</p>\n    </div>\n    <div class=\"bg-white/10 backdrop-blur rounded-2xl p-8 text-center\">\n      <p class=\"text-6xl font-black text-white\"><%= events_attended_in_year.count %></p>\n      <p class=\"text-red-200 text-lg mt-2\">Events Attended</p>\n    </div>\n    <div class=\"bg-white/10 backdrop-blur rounded-2xl p-8 text-center\">\n      <p class=\"text-6xl font-black text-white\"><%= countries_visited.count %></p>\n      <p class=\"text-red-200 text-lg mt-2\">Countries Visited</p>\n    </div>\n  </div>\n</div>\n\n<div class=\"w-full bg-white/5 py-3 mt-4 flex items-center justify-center gap-3\">\n  <%= image_tag \"logo.png\", class: \"w-6 h-6\", alt: \"RubyEvents.org\" %>\n  <span class=\"text-white font-bold text-lg\">RubyEvents.org</span>\n  <span class=\"text-red-300/80 text-sm\">On a mission to index all Ruby events</span>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_top_events.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Events You Explored Talks From</h2>\n<p class=\"text-gray-500 text-center mb-6\">Conferences that shared their knowledge with you</p>\n\n<% if top_events.any? %>\n  <div class=\"rank-list flex-1\">\n    <% top_events.each do |event, count| %>\n      <div class=\"rank-item\">\n        <div class=\"flex-1\">\n          <p class=\"font-semibold\"><%= event.name %></p>\n          <p class=\"text-sm text-gray-500\"><%= count %> <%= \"talk\".pluralize(count) %> watched</p>\n        </div>\n      </div>\n    <% end %>\n  </div>\n\n  <% if countries_watched.any? %>\n    <div class=\"mt-auto pt-4\">\n      <p class=\"text-sm text-gray-500 mb-2\">Countries explored through talks:</p>\n      <div class=\"flex flex-wrap gap-2\">\n        <% countries_watched.first(8).each do |country| %>\n          <span class=\"px-2 py-1 bg-red-50 text-red-700 rounded text-xs font-medium\">\n            <%= country.name %>\n          </span>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n<% else %>\n  <div class=\"flex-1 flex items-center justify-center\">\n    <p class=\"text-gray-400 text-center\">Watch talks to explore events from around the world!</p>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_top_speakers.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Your Favorite Speakers</h2>\n<p class=\"text-gray-500 text-center mb-6\">The voices that inspired you this year</p>\n\n<% if top_speakers.any? %>\n  <div class=\"space-y-4 flex-1\">\n    <% top_speakers.each do |speaker, count| %>\n      <div class=\"flex items-center gap-3 p-3 bg-gray-50 rounded-lg\">\n        <div class=\"w-12 h-12 rounded-full overflow-hidden bg-gray-200 flex-shrink-0\">\n          <%= image_tag speaker.avatar_url(size: 80), class: \"w-full h-full object-cover\", alt: speaker.name %>\n        </div>\n        <div class=\"flex-1 min-w-0\">\n          <p class=\"font-semibold truncate\"><%= speaker.name %></p>\n          <p class=\"text-sm text-gray-500\"><%= count %> <%= \"talk\".pluralize(count) %> watched</p>\n        </div>\n        <div class=\"text-2xl\">\n          <% if count >= 5 %>\n            🎤\n          <% elsif count >= 3 %>\n            ⭐\n          <% else %>\n            ✨\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n  </div>\n<% else %>\n  <div class=\"flex-1 flex items-center justify-center\">\n    <p class=\"text-gray-400 text-center\">Watch more talks to discover your favorite speakers!</p>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_top_topics.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Your Top Topics</h2>\n<p class=\"text-gray-500 text-center mb-6\">The subjects that captured your interest</p>\n\n<% if top_topics.any? %>\n  <div class=\"rank-list flex-1\">\n    <% top_topics.each do |topic, count| %>\n      <div class=\"rank-item\">\n        <div class=\"flex-1\">\n          <p class=\"font-semibold\"><%= topic.name %></p>\n          <p class=\"text-sm text-gray-500\"><%= count %> <%= \"talk\".pluralize(count) %></p>\n        </div>\n      </div>\n    <% end %>\n  </div>\n\n  <div class=\"mt-auto pt-6 text-center\">\n    <p class=\"text-sm text-gray-500 mb-2\">Your Ruby Personality</p>\n    <div class=\"personality-badge\"><%= personality %></div>\n  </div>\n<% else %>\n  <div class=\"flex-1 flex items-center justify-center\">\n    <p class=\"text-gray-400 text-center\">Watch some talks to discover your favorite topics!</p>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_watch_twin.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Your Watch Twin</h2>\n<p class=\"text-gray-500 text-center mb-6\">Someone with similar taste in talks</p>\n\n<div class=\"flex-1 flex flex-col items-center justify-center\">\n  <div class=\"w-24 h-24 rounded-full overflow-hidden bg-gray-200 mb-4 ring-4 ring-red-200\">\n    <%= image_tag watch_twin.user.avatar_url(size: 200), class: \"w-full h-full object-cover\", alt: watch_twin.user.name %>\n  </div>\n  <p class=\"text-xl font-bold\"><%= watch_twin.user.name %></p>\n  <p class=\"text-gray-500 mt-2\">watched <span class=\"font-semibold text-red-600\"><%= watch_twin.shared_count %></span> of the same talks</p>\n  <p class=\"text-sm text-gray-400 mt-1\"><%= watch_twin.percentage %>% overlap with your watched talks</p>\n\n  <div class=\"mt-6 p-4 bg-red-50 rounded-lg text-center\">\n    <p class=\"text-2xl mb-2\">👯</p>\n    <p class=\"text-sm text-gray-600\">Great minds watch alike!</p>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_watching_calendar.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Your Watching Calendar</h2>\n<p class=\"text-gray-500 text-center mb-6\">When you tuned in throughout the year</p>\n\n<% if monthly_breakdown.any? %>\n  <% max_count = monthly_breakdown.values.max || 1 %>\n  <div class=\"space-y-3 flex-1\">\n    <% (1..12).each do |month| %>\n      <% count = monthly_breakdown[month] || 0 %>\n      <% width = count.positive? ? (count.to_f / max_count * 100).round : 0 %>\n      <div class=\"flex items-center gap-3\">\n        <span class=\"text-sm text-gray-500 w-8\"><%= Date::ABBR_MONTHNAMES[month] %></span>\n        <div class=\"flex-1 bg-gray-100 rounded-full h-2\">\n          <div class=\"month-bar\" style=\"width: <%= width %>%\"></div>\n        </div>\n        <span class=\"text-sm text-gray-600 w-8 text-right\"><%= count %></span>\n      </div>\n    <% end %>\n  </div>\n\n  <% if most_active_month %>\n    <div class=\"mt-6 pt-4 highlight-box\">\n      <p class=\"font-semibold text-red-700\">\n        <%= Date::MONTHNAMES[most_active_month] %> was your most active month!\n      </p>\n      <p class=\"text-sm text-gray-600\">\n        You watched <%= monthly_breakdown[most_active_month] %> talks\n      </p>\n    </div>\n  <% end %>\n<% else %>\n  <div class=\"flex-1 flex items-center justify-center\">\n    <p class=\"text-gray-400 text-center\">Start watching to build your calendar!</p>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/wrapped/pages/_watching_journey.html.erb",
    "content": "<h2 class=\"text-2xl font-bold mb-2 text-center\">Your Watching Journey</h2>\n<p class=\"text-gray-500 text-center mb-6\">Here's how you explored Ruby content this year</p>\n\n<div class=\"space-y-4 flex-1\">\n  <div class=\"stat-card\">\n    <div class=\"stat-number\"><%= total_talks_watched %></div>\n    <div class=\"stat-label\">Talks Watched</div>\n  </div>\n\n  <div class=\"grid grid-cols-2 gap-4\">\n    <div class=\"stat-card\">\n      <div class=\"stat-number text-2xl\"><%= total_watch_time_hours %></div>\n      <div class=\"stat-label\">Hours of Content</div>\n    </div>\n    <div class=\"stat-card\">\n      <div class=\"stat-number text-2xl\"><%= completion_rate %>%</div>\n      <div class=\"stat-label\">Completion Rate</div>\n    </div>\n  </div>\n\n  <div class=\"grid grid-cols-2 gap-4\">\n    <div class=\"stat-card\">\n      <div class=\"stat-number text-2xl\"><%= speakers_discovered %></div>\n      <div class=\"stat-label\">Speakers Discovered</div>\n    </div>\n    <div class=\"stat-card\">\n      <div class=\"stat-number text-2xl\"><%= bookmarks_in_year %></div>\n      <div class=\"stat-label\">Talks Bookmarked</div>\n    </div>\n  </div>\n</div>\n\n<% if total_talks_watched > 0 %>\n  <div class=\"mt-auto pt-4 text-center text-sm text-gray-500\">\n    That's <%= (total_watch_time_seconds / 60.0).round %> minutes of Ruby knowledge!\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/profiles/wrapped/private.html.erb",
    "content": "<div class=\"wrapped-page wrapped-cover\">\n  <div class=\"mb-6\">\n    <svg width=\"100\" height=\"100\" viewBox=\"0 0 80 80\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n      <path d=\"M2 25 L16 10 L64 10 L78 25 L40 70 Z\" fill=\"white\" opacity=\"0.3\" />\n    </svg>\n  </div>\n\n  <div class=\"w-20 h-20 mx-auto rounded-full border-4 border-white/50 overflow-hidden bg-white/20 mb-4\">\n    <% if @user.custom_avatar? %>\n      <%= image_tag @user.avatar_url(size: 120), class: \"w-full h-full object-cover opacity-50\", alt: @user.name %>\n    <% else %>\n      <div class=\"w-full h-full flex items-center justify-center text-2xl font-bold opacity-50\">\n        <%= @user.name.first.upcase %>\n      </div>\n    <% end %>\n  </div>\n\n  <h1 class=\"text-2xl font-bold mb-2\"><%= @user.name %>'s Wrapped</h1>\n  <p class=\"text-red-200 mb-8\">This wrapped hasn't been shared yet</p>\n\n  <div class=\"w-16 h-16 mb-6 rounded-full bg-white/10 flex items-center justify-center\">\n    <svg class=\"w-8 h-8 text-white/70\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n      <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\" />\n    </svg>\n  </div>\n\n  <p class=\"text-red-100 text-sm max-w-xs text-center mb-8\">\n    <%= @user.name %> hasn't made their 2025 Wrapped public yet. Check back later!\n  </p>\n\n  <div class=\"mt-auto pt-4 space-y-3 w-full max-w-xs\">\n    <%= link_to wrapped_path, class: \"block w-full px-4 py-3 bg-white text-red-700 font-semibold rounded-lg text-center hover:bg-red-50 transition\" do %>\n      Browse Community Wrappeds\n    <% end %>\n\n    <% if Current.user %>\n      <%= link_to profile_wrapped_index_path(Current.user), class: \"block w-full px-4 py-3 bg-white/10 text-white font-semibold rounded-lg text-center hover:bg-white/20 transition\" do %>\n        View Your Own Wrapped\n      <% end %>\n    <% else %>\n      <%= link_to new_session_path, class: \"block w-full px-4 py-3 bg-white/10 text-white font-semibold rounded-lg text-center hover:bg-white/20 transition\" do %>\n        Sign In to See Yours\n      <% end %>\n    <% end %>\n  </div>\n\n  <div class=\"mt-6 flex flex-col items-center\">\n    <%= image_tag \"logo.png\", class: \"w-8 h-8 mb-1 opacity-70\", alt: \"RubyEvents.org\" %>\n    <p class=\"text-xs text-red-200\">RubyEvents.org</p>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/recommendations/index.html.erb",
    "content": "<main class=\"container py-8 hotwire-native:py-3\">\n  <h1 class=\"title hotwire-native:hidden mb-9\">\n    <%= title \"Recommended for you\" %>\n  </h1>\n\n  <% if @recommended_talks.present? %>\n    <div class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n      <%= render partial: \"talks/card\", collection: @recommended_talks, as: :talk, cached: true,\n            locals: {\n              back_to: recommendations_path,\n              back_to_title: \"Recommended for you\",\n              favoritable: true,\n              user_favorite_talks_ids: @user_favorite_talks_ids,\n              user_watched_talks:\n            } %>\n    </div>\n  <% else %>\n    <div class=\"text-center py-12\">\n      <div class=\"max-w-md mx-auto\">\n        <div class=\"text-6xl mb-4\">🎯</div>\n        <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No recommendations yet</h2>\n        <p class=\"text-gray-600 mb-6\">\n          Watch some talks to get personalized recommendations based on your interests and viewing history.\n        </p>\n        <div class=\"bg-purple-50 border border-purple-200 rounded-lg p-4 text-left\">\n          <h3 class=\"font-semibold text-purple-800 mb-2\">How it works:</h3>\n          <ul class=\"text-sm text-purple-700 space-y-1\">\n            <li>• Watch talks or that interest you</li>\n            <li>• Mark talks as \"watched\" you have seen in-person</li>\n            <li>• Get personalized recommendations</li>\n            <li>• Discover new content</li>\n          </ul>\n        </div>\n        <div class=\"mt-6\">\n          <%= link_to talks_path, class: \"btn btn-primary\" do %>\n            <%= fa \"video\", variant: :solid, class: \"w-5 h-5 mr-2\" %>\n            Browse Talks\n          <% end %>\n        </div>\n      </div>\n    </div>\n  <% end %>\n</main>\n"
  },
  {
    "path": "app/views/sessions/new.html.erb",
    "content": "<% redirect_to_path = params.delete(:redirect_to) || request.url %>\n\n<div class=\"flex items-center justify-center sm:py-24 px-4 sm:px-6 lg:px-8\">\n  <div class=\"max-w-md w-full space-y-8\">\n    <div>\n      <div class=\"mt-4 leading-relaxed\"><strong>Sign in</strong> to bookmark talks, create watch lists, mark your speaker page as verified and more to come.</div>\n    </div>\n    <div class=\"mt-8 space-y-6\">\n      <div>\n        <%= ui_button url: \"/auth/github?redirect_to=#{redirect_to_path}&state=#{@state}\", kind: :neutral, class: \"w-full\", method: :post, data: {turbo: false} do %>\n          <%= icon \"github\", size: :sm, class: \"mr-2\" %>\n          Sign in with GitHub\n        <% end %>\n      </div>\n\n      <% if Rails.env.development? %>\n        <div>\n          <%= button_to \"/auth/developer?state=#{@state}\", method: :post, data: {turbo: false}, class: \"btn w-full btn-accent\" do %>\n            Sign in with OmniAuth (Development)\n          <% end %>\n        </div>\n      <% end %>\n      <div class=\"text-base font-light leading-relaxed\"> We collect your email address associated to your GitHub account and name to create your account. All emails are encrypted in our database. We do not share your email address with anyone else.</div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/settings/show.html.erb",
    "content": "<div class=\"container py-8\">\n  <div class=\"max-w-2xl mx-auto\">\n    <h1 class=\"text-3xl font-bold mb-8\">Settings</h1>\n\n    <%= form_with(model: Current.user, url: settings_path, method: :patch) do |form| %>\n      <div class=\"space-y-8\">\n        <% if Current.user.talks_count > 0 %>\n          <div class=\"card bg-base-100 shadow-sm border\">\n            <div class=\"card-body\">\n              <h2 class=\"card-title text-lg\">Speaker Settings</h2>\n              <p class=\"text-sm text-gray-500 mb-4\">Settings for speakers who have given talks at Ruby events.</p>\n\n              <div class=\"form-control\">\n                <label class=\"label cursor-pointer justify-start gap-4\">\n                  <%= form.check_box :feedback_enabled, class: \"toggle toggle-primary\" %>\n                  <div>\n                    <span class=\"label-text font-medium\">Allow feedback on your talks</span>\n                    <p class=\"text-sm text-gray-500\">When enabled, viewers can share feedback about your talks (liked it, would recommend, beginner-friendly, etc.). The \"Where did you watch?\" option will still be available regardless.</p>\n                  </div>\n                </label>\n              </div>\n            </div>\n          </div>\n        <% end %>\n\n        <div class=\"card bg-base-100 shadow-sm border\">\n          <div class=\"card-body\">\n            <h2 class=\"card-title text-lg\">Privacy</h2>\n            <p class=\"text-sm text-gray-500 mb-4\">Control what others can see on your profile.</p>\n\n            <div class=\"form-control\">\n              <label class=\"label cursor-pointer justify-start gap-4\">\n                <%= form.check_box :wrapped_public, class: \"toggle toggle-primary\" %>\n                <div>\n                  <span class=\"label-text font-medium\">Make Wrapped public</span>\n                  <p class=\"text-sm text-gray-500\">Allow others to view your year in review (Wrapped) on your profile.</p>\n                </div>\n              </label>\n            </div>\n\n            <% if Current.user.talks_count > 0 %>\n              <div class=\"form-control opacity-50\">\n                <label class=\"label cursor-not-allowed justify-start gap-4\">\n                  <input type=\"checkbox\" class=\"toggle toggle-primary\" disabled checked>\n                  <div>\n                    <span class=\"label-text font-medium\">Profile shows up in global search</span>\n                    <p class=\"text-sm text-gray-500\">As a speaker, your profile is always searchable.</p>\n                  </div>\n                </label>\n              </div>\n            <% else %>\n              <div class=\"form-control\">\n                <label class=\"label cursor-pointer justify-start gap-4\">\n                  <%= form.check_box :searchable, class: \"toggle toggle-primary\" %>\n                  <div>\n                    <span class=\"label-text font-medium\">Profile shows up in global search</span>\n                    <p class=\"text-sm text-gray-500\">Allow your profile to appear in search results.</p>\n                  </div>\n                </label>\n              </div>\n            <% end %>\n          </div>\n        </div>\n\n        <div class=\"flex justify-end\">\n          <%= ui_button \"Save settings\", type: :submit %>\n        </div>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/shared/_breakpoints.html.erb",
    "content": "<% if Rails.env.development? %>\n  <div class=\"sticky bottom-2 left-2 bg-black/80 bg-blur p-2 rounded-full text-sm text-white h-8 w-8 flex justify-center items-center hotwire-native:hidden\">\n    <p class=\"block sm:hidden\">-</p>\n    <p class=\"hidden sm:block md:hidden\">sm</p>\n    <p class=\"hidden md:block lg:hidden\">md</p>\n    <p class=\"hidden lg:block xl:hidden\">lg</p>\n    <p class=\"hidden xl:block 2xl:hidden\">xl</p>\n    <p class=\"hidden 2xl:block\">2xl</p>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_cfp_countdown_badge.html.erb",
    "content": "<% event.cfps.each do |cfp| %>\n  <% if cfp.future? %>\n    <% cfp_open_days = cfp.days_until_open %>\n\n    <div class=\"flex flex-col justify-center\">\n      <div class=\"self-end w-16 h-16 bg-blue-500 text-white rounded-xl flex flex-col items-center justify-center text-xs leading-none\">\n        <div class=\"text-[10px]\">CFP in</div>\n        <div class=\"text-lg font-bold\"><%= cfp_open_days %></div>\n        <div class=\"text-[10px]\"><%= \"day\".pluralize(cfp_open_days) %></div>\n      </div>\n    </div>\n\n  <% elsif cfp.open? %>\n    <% if cfp.open_ended? %>\n      <div class=\"flex flex-col justify-center\">\n        <div class=\"self-end w-16 h-16 bg-green-500 text-white rounded-xl flex flex-col items-center justify-center text-xs leading-none\">\n          <div class=\"text-lg font-bold\">CFP</div>\n          <div class=\"text-[10px]\">Always</div>\n          <div class=\"text-[10px]\">Open</div>\n        </div>\n      </div>\n    <% else %>\n      <% cfp_days = cfp.days_remaining %>\n\n      <% if cfp_days %>\n        <div class=\"flex flex-col justify-center\">\n          <div class=\"self-end w-16 h-16 bg-green-500 text-white rounded-xl flex flex-col items-center justify-center text-xs leading-none\">\n\n            <% if cfp_days == 0 %>\n              <div class=\"text-lg font-bold\">CFP</div>\n              <div class=\"text-[10px]\">Last day!</div>\n            <% elsif cfp_days == 1 %>\n              <div class=\"text-lg font-bold\">CFP</div>\n              <div class=\"text-[10px]\">Tomorrow</div>\n            <% else %>\n              <div class=\"text-[10px]\">CFP</div>\n              <div class=\"text-lg font-bold\"><%= cfp_days %></div>\n              <div class=\"text-[10px]\"><%= \"day\".pluralize(cfp_days) %></div>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    <% end %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_city_sidebar.html.erb",
    "content": "<%# locals: (city_name:, country:, users:, nearby_users: [], event_map_markers: []) %>\n\n<div class=\"space-y-8\">\n  <% if event_map_markers.present? && event_map_markers.any? %>\n    <div>\n      <h3 class=\"font-bold text-gray-900 mb-4\">Map</h3>\n\n      <div\n        id=\"sidebar-map\"\n        class=\"w-full h-48 rounded-xl overflow-hidden border\"\n        data-controller=\"map\"\n        data-map-markers-value=\"<%= event_map_markers.to_json %>\"></div>\n    </div>\n  <% end %>\n\n  <div class=\"bg-gray-50 rounded-xl p-6 border\">\n    <div class=\"flex items-center gap-3 mb-3\">\n      <div class=\"w-10 h-10 rounded-lg bg-red-100 flex items-center justify-center\">\n        <%= fa(\"city\", class: \"text-red-600\") %>\n      </div>\n\n      <span class=\"font-bold text-lg text-gray-900\"><%= city_name %></span>\n    </div>\n\n    <p class=\"text-gray-600 text-sm\">\n      Discover the hottest Ruby events in <%= city_name %>, and get notified of new events before they sell out.\n    </p>\n  </div>\n\n  <%= render \"shared/rubyists_preview\",\n        users: users.limit(24),\n        title: \"Rubyists in #{city_name}\",\n        total_count: users.count,\n        view_all_path: nil %>\n\n  <% if nearby_users.present? && nearby_users.any? %>\n    <%= render \"shared/rubyists_preview\",\n          users: nearby_users.first(24),\n          title: \"Rubyists near #{city_name}\",\n          total_count: nearby_users.count,\n          view_all_path: nil %>\n  <% end %>\n\n  <% if country.present? %>\n    <div>\n      <h3 class=\"font-bold text-gray-900 mb-4\">Country</h3>\n\n      <%= link_to country.path, class: \"flex items-center gap-3 py-2 px-3 rounded-lg hover:bg-gray-50 transition-colors\" do %>\n        <span class=\"fi fi-<%= country.alpha2.downcase %> border rounded w-8 text-[16pt]\"></span>\n        <span class=\"text-gray-700\"><%= country.name %></span>\n      <% end %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_country_card.html.erb",
    "content": "<div class=\"card card-compact bg-white border\">\n  <div class=\"card-body\">\n    <div class=\"flex items-center justify-between\">\n      <div class=\"flex items-center gap-4\">\n        <span class=\"text-2xl\"><%= country.emoji_flag %></span>\n        <div>\n          <%= link_to country.path, class: \"hover:underline\", data: {turbo_frame: \"_top\"} do %>\n            <h4 class=\"font-semibold\"><%= country.name %></h4>\n          <% end %>\n          <p class=\"text-sm text-gray-500\"><%= pluralize(events.size, \"event\") %></p>\n        </div>\n      </div>\n    </div>\n    <div class=\"mt-3 space-y-1\">\n      <% events.first(3).each do |event| %>\n        <%= link_to event, class: \"block text-sm hover:underline text-gray-700\", data: {turbo_frame: \"_top\"} do %>\n          • <%= event.name %> (<%= event.start_date&.year %>)\n        <% end %>\n      <% end %>\n      <% if events.size > 3 %>\n        <div class=\"collapse collapse-arrow\">\n          <input type=\"checkbox\" class=\"collapse-checkbox\">\n          <div class=\"collapse-title text-sm text-gray-500 italic p-0 min-h-0\">\n            and <%= events.size - 3 %> more...\n          </div>\n          <div class=\"collapse-content space-y-1 p-0\">\n            <% events.drop(3).each do |event| %>\n              <%= link_to event, class: \"block text-sm hover:underline text-gray-700\", data: {turbo_frame: \"_top\"} do %>\n                • <%= event.name %> (<%= event.start_date&.year %>)\n              <% end %>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/shared/_date_grouped_events.html.erb",
    "content": "<%# locals: (events:, empty_message: \"No events found.\") %>\n\n<% if events.any? %>\n  <% grouped_events = group_events_by_date(events) %>\n\n  <% grouped_events.each do |display_info, date_events| %>\n    <div class=\"mb-8\" data-events-filter-target=\"group\">\n      <div class=\"flex items-center gap-2 mb-4\">\n        <span class=\"w-2 h-2 rounded-full bg-gray-400\"></span>\n\n        <span class=\"text-lg font-semibold text-gray-800\">\n          <% if display_info[:precision] == \"day\" && display_info[:date].present? %>\n            <%= display_info[:date].strftime(\"%b %-d\") %>\n\n            <span class=\"font-normal text-gray-500\"><%= display_info[:date].strftime(\"%A\") %></span>\n          <% elsif display_info[:date].present? %>\n            <%= event_date_display(date_events.first, day_name: false) %>\n          <% else %>\n            Date TBD\n          <% end %>\n        </span>\n      </div>\n\n      <div class=\"space-y-3 pl-4\">\n        <% date_events.each do |event| %>\n          <%= render \"shared/event_row\", event: event %>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n<% else %>\n  <div class=\"text-gray-500 py-8 text-center\">\n    <%= empty_message %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_event_countdown_badge.html.erb",
    "content": "<% if event.start_date && event.date_precision == \"day\" %>\n  <% days = (event.start_date - Date.current).to_i %>\n  <% today = (event.start_date..event.end_date).include?(Date.current) %>\n\n  <% if days == 0 || today %>\n    <div class=\"flex flex-col justify-center\">\n      <div class=\"self-end w-16 h-16 bg-[#636B74] text-white rounded-xl flex flex-col items-center justify-center text-xs leading-none\">\n        <div class=\"text-[12px]\">Today</div>\n      </div>\n    </div>\n  <% elsif days == 1 %>\n    <div class=\"flex flex-col justify-center\">\n      <div class=\"self-end w-16 h-16 bg-[#636B74] text-white rounded-xl flex flex-col items-center justify-center text-xs leading-none\">\n        <div class=\"text-[12px]\">Tomorrow</div>\n      </div>\n    </div>\n  <% elsif days >= 0 %>\n    <div class=\"flex flex-col justify-center\">\n      <div class=\"self-end w-16 h-16 bg-[#636B74] text-white rounded-xl flex flex-col items-center justify-center text-xs leading-none\">\n        <div class=\"text-lg font-bold\"><%= days %></div>\n        <div class=\"mt-1 text-[13px]\"><%= \"day\".pluralize(days) %></div>\n      </div>\n    </div>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_event_row.html.erb",
    "content": "<%# locals: (event:) %>\n\n<%= link_to event_path(event),\n      class: \"block bg-white rounded-lg border p-3 sm:p-4 hover:border-gray-400 transition-colors\",\n      data: {events_filter_target: \"event\", kind: event.kind} do %>\n  <div class=\"flex gap-3 sm:gap-4 items-start\">\n    <% if event.avatar_image_path %>\n      <div class=\"w-12 h-12 sm:w-16 sm:h-16 flex-shrink-0 rounded-lg overflow-hidden\">\n        <%= image_tag event.avatar_image_path, class: \"w-full h-full object-cover\" %>\n      </div>\n    <% end %>\n\n    <div class=\"flex-grow min-w-0\">\n      <div class=\"font-semibold text-gray-900 truncate\"><%= event.name %></div>\n\n      <% if event&.venue&.exist? %>\n        <div class=\"text-sm text-gray-600 mt-1 flex items-center gap-1 min-w-0\">\n          <%= fa(\"city\", size: :xs, class: \"text-gray-400 flex-shrink-0\") %>\n          <span class=\"truncate\"><%= event.venue.name %></span>\n        </div>\n      <% end %>\n\n      <% if event.location.present? %>\n        <div class=\"text-sm text-gray-600 mt-1 flex items-center gap-1 min-w-0\">\n          <%= fa(\"map-marker-alt\", size: :xs, class: \"text-gray-400 flex-shrink-0\") %>\n          <span class=\"truncate\"><%= event.location %></span>\n        </div>\n      <% end %>\n\n      <div class=\"text-sm text-gray-600 mt-1 flex items-center gap-1\">\n        <%= fa(\"calendar\", size: :xs, class: \"text-gray-400 flex-shrink-0\") %>\n        <span><%= event.formatted_dates %></span>\n      </div>\n    </div>\n\n    <% if event.participants.any? %>\n      <div class=\"flex-shrink-0 hidden sm:block\">\n        <%= render Ui::AvatarGroupComponent.new(event.participants.to_a, max: 4, size: :md, overlap: \"-space-x-3\") %>\n      </div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_events_section.html.erb",
    "content": "<%# locals: (title:, events:, view_all_path: nil, view_all_count: nil, empty_message: nil, fallback_text: nil, fallback_path: nil, limit: 5, dimmed: false) %>\n\n<div class=\"mb-12 <%= \"opacity-60 hover:opacity-100 transition-opacity\" if dimmed %>\">\n  <div class=\"flex items-center justify-between mb-6\">\n    <h2 class=\"text-xl font-bold text-gray-900\"><%= title %></h2>\n\n    <% if view_all_path.present? && view_all_count.present? && view_all_count > limit %>\n      <%= link_to \"View all #{view_all_count}\", view_all_path, class: \"link text-sm\" %>\n    <% end %>\n  </div>\n\n  <% if events.any? %>\n    <%= render \"shared/date_grouped_events\", events: events.first(limit), empty_message: empty_message || \"No events found.\" %>\n  <% else %>\n    <div class=\"text-gray-500 py-8 text-center border-dashed border rounded-xl\">\n      <p class=\"mb-2\"><%= empty_message || \"No events yet.\" %></p>\n\n      <% if fallback_path.present? && fallback_text.present? %>\n        <%= link_to fallback_text, fallback_path, class: \"link text-sm\" %>\n      <% end %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_filter_buttons.html.erb",
    "content": "<%# locals: (kinds:, current_filter: \"all\") %>\n\n<div role=\"tablist\" class=\"tabs tabs-boxed inline-flex mb-4\">\n  <button type=\"button\" class=\"tab <%= \"tab-active\" if current_filter == \"all\" %>\" data-events-filter-target=\"button\" data-kind=\"all\" data-action=\"click->events-filter#filter\">\n    All\n  </button>\n\n  <% kinds.each do |kind| %>\n    <button type=\"button\" class=\"tab <%= \"tab-active\" if current_filter == kind %>\" data-events-filter-target=\"button\" data-kind=\"<%= kind %>\" data-action=\"click->events-filter#filter\">\n      <%= kind.humanize.pluralize %>\n    </button>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_flashes.html.erb",
    "content": "<%= content_tag :div, id: \"flashes\", class: \"toast\", data: {\"turbo-temporary\": true} do %>\n  <% flash.each_with_index do |(key, content), ind| %>\n      <%= render \"shared/toast\", text: content, type: key %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_footer.html.erb",
    "content": "<footer class=\"hotwire-native:hidden\">\n  <div class=\"flex flex-col justify-center max-w-7xl mx-auto overflow-hidden px-6 py-20 sm:py-24 lg:px-8\">\n    <div class=\"flex justify-center items-center flex-wrap gap-4 sm:gap-8\" aria-label=\"Footer\">\n      <%= link_to \"About\", about_path, class: \"link\" %>\n      <%= link_to \"Uses\", uses_path, class: \"link\" %>\n      <%= link_to \"Contributing\", contributions_path, class: \"link\" %>\n      <%= link_to \"Open analytics\", analytics_dashboards_path, class: \"link\" %>\n      <%= link_to \"Status\", \"https://status.rubyvideo.dev/\", target: \"_blank\", class: \"link\" %>\n    </div>\n    <p class=\"mt-6 text-center text-neutral inline leading-relaxed\">\n      <%= footer_credits %>\n    </p>\n  </div>\n</footer>\n"
  },
  {
    "path": "app/views/shared/_location_header.html.erb",
    "content": "<%# locals: (name:, subtitle:, flag_code: nil, emoji: nil, stats: nil, location: nil) %>\n\n<div class=\"container py-8\">\n  <div class=\"flex flex-col lg:flex-row gap-6 lg:gap-8 items-center lg:items-start\">\n    <% if emoji.present? %>\n      <span class=\"text-[80pt] lg:text-[100pt] leading-none flex-shrink-0\"><%= emoji %></span>\n    <% elsif flag_code.present? %>\n      <span class=\"fi fi-<%= flag_code.to_s.downcase %> border rounded w-28 lg:w-36 text-[60pt] lg:text-[80pt] flex-shrink-0\"></span>\n    <% end %>\n\n    <div class=\"flex flex-col justify-center text-center lg:text-left flex-grow\">\n      <h1 class=\"mb-2 text-black font-bold text-3xl lg:text-4xl\">\n        <% if location.is_a?(OnlineLocation) %>\n          Online Ruby Community\n        <% elsif location.is_a?(CoordinateLocation) %>\n          Ruby Community near <%= name %>\n        <% else %>\n          Ruby Community in <%= name %>\n        <% end %>\n      </h1>\n\n      <h3 class=\"text-[#636B74] text-lg\">\n        <%= subtitle %>\n      </h3>\n\n      <% if stats.present? %>\n        <p class=\"mt-4 text-[#636B74]\">\n          <%= stats %>\n        </p>\n      <% end %>\n    </div>\n\n    <% if location.present? %>\n      <div class=\"flex flex-col gap-2 text-sm text-right flex-shrink-0\">\n        <% case location %>\n        <% when Continent %>\n          <%= link_to continents_path, class: \"link flex items-center gap-1 justify-end\" do %>\n            <%= fa(\"globe\", size: :sm, class: \"text-gray-400\") %>\n            All Continents\n          <% end %>\n        <% when Country %>\n          <% continent = location.continent %>\n\n          <% if continent %>\n            <%= link_to continent_path(continent), class: \"link flex items-center gap-1 justify-end\" do %>\n              <%= fa(\"arrow-up\", size: :sm, class: \"text-gray-400\") %>\n              <%= continent.name %>\n            <% end %>\n          <% end %>\n\n          <%= link_to countries_path, class: \"link flex items-center gap-1 justify-end\" do %>\n            <%= fa(\"globe\", size: :sm, class: \"text-gray-400\") %>\n            All Countries\n          <% end %>\n        <% when UKNation %>\n          <% parent_country = location.parent_country %>\n\n          <%= link_to country_path(parent_country), class: \"link flex items-center gap-1 justify-end\" do %>\n            <%= fa(\"arrow-up\", size: :sm, class: \"text-gray-400\") %>\n            <%= parent_country.name %>\n          <% end %>\n\n          <%= link_to countries_path, class: \"link flex items-center gap-1 justify-end\" do %>\n            <%= fa(\"globe\", size: :sm, class: \"text-gray-400\") %>\n            All Countries\n          <% end %>\n        <% when State %>\n          <% country = location.country %>\n\n          <%= link_to country_path(country), class: \"link flex items-center gap-1 justify-end\" do %>\n            <%= fa(\"arrow-up\", size: :sm, class: \"text-gray-400\") %>\n            <%= country.name %>\n          <% end %>\n\n          <%= link_to country_states_path(alpha2: country.code), class: \"link flex items-center gap-1 justify-end\" do %>\n            <%= fa(\"map\", size: :sm, class: \"text-gray-400\") %>\n            All States in <%= country.name %>\n          <% end %>\n        <% when City %>\n          <% country = Country.find_by(country_code: location.country_code) %>\n          <% state = location.state if country&.states? %>\n\n          <% if state %>\n            <%= link_to state.path, class: \"link flex items-center gap-1 justify-end\" do %>\n              <%= fa(\"arrow-up\", size: :sm, class: \"text-gray-400\") %>\n              <%= state.name %>\n            <% end %>\n          <% elsif country %>\n            <%= link_to country_path(country), class: \"link flex items-center gap-1 justify-end\" do %>\n              <%= fa(\"arrow-up\", size: :sm, class: \"text-gray-400\") %>\n              <%= country.name %>\n            <% end %>\n          <% end %>\n\n          <% if country %>\n            <%= link_to country_cities_path(country), class: \"link flex items-center gap-1 justify-end\" do %>\n              <%= fa(\"city\", size: :sm, class: \"text-gray-400\") %>\n              All Cities in <%= country.name %>\n            <% end %>\n          <% end %>\n\n          <% if Current.user&.admin? %>\n            <div class=\"mt-2 pt-2 border-t border-gray-200\">\n              <% if location.is_a?(City) %>\n                <%= button_to \"Feature this city\",\n                      featured_cities_path(country_code: location.country_code, state_code: location.state_code, city_slug: location.slug),\n                      method: :post,\n                      class: \"btn btn-primary btn-xs\" %>\n              <% else %>\n                <%= button_to \"Unfeature\",\n                      featured_city_path(location.slug),\n                      method: :delete,\n                      class: \"btn btn-secondary btn-xs\",\n                      data: {turbo_confirm: \"Are you sure you want to unfeature #{location.name}?\"} %>\n              <% end %>\n            </div>\n          <% end %>\n        <% when OnlineLocation %>\n          <%= link_to continents_path, class: \"link flex items-center gap-1 justify-end\" do %>\n            <%= fa(\"globe\", size: :sm, class: \"text-gray-400\") %>\n            Browse by Location\n          <% end %>\n\n          <%= link_to cities_path, class: \"link flex items-center gap-1 justify-end\" do %>\n            <%= fa(\"city\", size: :sm, class: \"text-gray-400\") %>\n            All Cities\n          <% end %>\n        <% when CoordinateLocation %>\n          <% country = location.country %>\n          <% if country %>\n            <%= link_to country_path(country), class: \"link flex items-center gap-1 justify-end\" do %>\n              <%= fa(\"arrow-up\", size: :sm, class: \"text-gray-400\") %>\n              <%= country.name %>\n            <% end %>\n          <% end %>\n\n          <%= link_to continents_path, class: \"link flex items-center gap-1 justify-end\" do %>\n            <%= fa(\"globe\", size: :sm, class: \"text-gray-400\") %>\n            Browse by Location\n          <% end %>\n\n          <%= link_to cities_path, class: \"link flex items-center gap-1 justify-end\" do %>\n            <%= fa(\"city\", size: :sm, class: \"text-gray-400\") %>\n            All Cities\n          <% end %>\n        <% end %>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/shared/_location_map.html.erb",
    "content": "<%# locals: (location:, layers: [], time_layers: [], geo_layers: [], online_events: []) %>\n\n<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% if location.is_a?(CoordinateLocation) %>\n  <% title \"Events Map near #{location.name}\" %>\n<% else %>\n  <% title \"Events Map in #{location.name}\" %>\n<% end %>\n\n<% all_layers = layers.presence || geo_layers %>\n<% total_markers = geo_layers.sum { |l| l[:markers]&.count || 0 } %>\n<% has_city_pin = geo_layers.any? { |l| l[:cityPin].present? } %>\n\n<%= render \"shared/location_header\",\n      name: location.name,\n      subtitle: location.to_location.to_text,\n      flag_code: (location.respond_to?(:alpha2) && !location.is_a?(Continent)) ? location.alpha2 : nil,\n      emoji: location.is_a?(Continent) ? location.emoji_flag : nil,\n      stats: \"#{pluralize(total_markers, \"event\")} on the map\",\n      location: location %>\n\n<%= render \"shared/location_navigation\",\n      location: location,\n      current_tab: \"map\",\n      show_cities: location.is_a?(Country) || location.is_a?(UKNation),\n      show_countries: location.is_a?(Continent),\n      show_states: location.is_a?(Country) && location.states?,\n      show_stamps: location.stamps.any? %>\n\n<div class=\"container py-8\">\n  <% if all_layers.any? || has_city_pin %>\n    <div\n      data-controller=\"map\"\n      data-map-layers-value=\"<%= all_layers.to_json %>\"\n      <% if location.bounds.present? %>\n        data-map-bounds-value=\"<%= location.bounds.to_json %>\"\n      <% end %>>\n      <div class=\"flex flex-col gap-4 mb-6\">\n        <div class=\"flex items-center justify-between\">\n          <h2 class=\"text-xl font-bold text-gray-900\">Events Map</h2>\n        </div>\n\n        <div class=\"flex flex-col sm:flex-row gap-4\">\n          <% if time_layers.size > 1 %>\n            <div class=\"flex items-center gap-2\">\n              <span class=\"text-sm font-medium text-gray-600\">Time:</span>\n\n              <%= render \"shared/map_time_filter\", options: time_layers %>\n            </div>\n          <% end %>\n\n          <% if geo_layers.size > 1 %>\n            <div class=\"flex items-center gap-2\">\n              <span class=\"text-sm font-medium text-gray-600\">Location:</span>\n\n              <%= render \"shared/map_layer_controls\", layers: geo_layers, selection: \"radio\", use_emoji: true %>\n            </div>\n          <% end %>\n        </div>\n      </div>\n\n      <div\n        id=\"location-map\"\n        class=\"w-full h-[600px] rounded-xl overflow-hidden border\"\n        data-map-target=\"container\"></div>\n    </div>\n\n    <% if online_events.any? %>\n      <div class=\"mt-8\">\n        <div class=\"flex items-center gap-2 mb-4\">\n          <span class=\"text-xl\">🌐</span>\n          <h3 class=\"text-lg font-semibold text-gray-900\">Upcoming Online Events</h3>\n          <span class=\"badge badge-ghost\"><%= online_events.count %></span>\n        </div>\n\n        <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n          <% online_events.each do |event| %>\n            <%= link_to event_path(event), class: \"flex items-center gap-3 p-3 rounded-lg border hover:bg-gray-50 transition-colors\" do %>\n              <div class=\"avatar\">\n                <div class=\"w-10 h-10 rounded-full\">\n                  <%= image_tag event.avatar_image_path, alt: event.name %>\n                </div>\n              </div>\n\n              <div class=\"flex-1 min-w-0\">\n                <div class=\"font-medium text-gray-900 truncate\"><%= event.name %></div>\n                <% if event.start_date %>\n                  <div class=\"text-sm text-gray-500\"><%= event.start_date.strftime(\"%b %d, %Y\") %></div>\n                <% end %>\n              </div>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n  <% else %>\n    <div class=\"flex items-center justify-between mb-6\">\n      <h2 class=\"text-xl font-bold text-gray-900\">Events Map</h2>\n    </div>\n\n    <p class=\"text-gray-500 py-8 text-center\">No events with location data in <%= location.name %>.</p>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_location_meetups.html.erb",
    "content": "<%# locals: (location:, meetups:) %>\n\n<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% title \"Meetups in #{location.name}\" %>\n\n<%= render \"shared/location_header\",\n      name: location.name,\n      subtitle: location.to_location.to_text,\n      flag_code: (location.respond_to?(:alpha2) && !location.is_a?(Continent)) ? location.alpha2 : nil,\n      emoji: location.is_a?(Continent) ? location.emoji_flag : nil,\n      stats: \"#{pluralize(meetups.size, \"meetup\")} in #{location.name}\",\n      location: location %>\n\n<%= render \"shared/location_navigation\",\n      location: location,\n      current_tab: \"meetups\",\n      show_cities: location.is_a?(Country) || location.is_a?(UKNation) || location.is_a?(State),\n      show_countries: location.is_a?(Continent),\n      show_states: location.is_a?(Country) && location.states?,\n      show_stamps: location.respond_to?(:stamps) && location.stamps.any? %>\n\n<div class=\"container py-8\">\n  <div class=\"flex items-center justify-between mb-6\">\n    <h2 class=\"text-xl font-bold text-gray-900\">Meetups in <%= location.name %></h2>\n\n    <%= ui_badge(meetups.size, kind: :secondary, outline: true) %>\n  </div>\n\n  <% if meetups.any? %>\n    <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n      <%= render partial: \"events/card\", collection: meetups, as: :event %>\n    </div>\n  <% else %>\n    <p class=\"text-gray-500 py-8 text-center\">No known meetups in <%= location.name %> yet.</p>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_location_navigation.html.erb",
    "content": "<%# locals: (location:, current_tab: \"overview\", show_cities: true, show_countries: false, show_states: false, show_stamps: true) %>\n\n<div class=\"container\">\n  <div role=\"tablist\" class=\"tabs tabs-bordered mb-8 overflow-x-auto\">\n    <%= link_to location_path(location), role: \"tab\", class: \"tab whitespace-nowrap #{\"tab-active\" if current_tab == \"overview\"}\" do %>\n      Overview\n    <% end %>\n\n    <%= link_to location_past_path(location), role: \"tab\", class: \"tab whitespace-nowrap #{\"tab-active\" if current_tab == \"past\"}\" do %>\n      Past Events\n    <% end %>\n\n    <% if location_meetups_path(location).present? %>\n      <%= link_to location_meetups_path(location), role: \"tab\", class: \"tab whitespace-nowrap #{\"tab-active\" if current_tab == \"meetups\"}\" do %>\n        Meetups\n      <% end %>\n    <% end %>\n\n    <% if location_users_path(location).present? %>\n      <%= link_to location_users_path(location), role: \"tab\", class: \"tab whitespace-nowrap #{\"tab-active\" if current_tab == \"users\"}\" do %>\n        Rubyists\n      <% end %>\n    <% end %>\n\n    <% if show_countries && location_countries_path(location).present? %>\n      <%= link_to location_countries_path(location), role: \"tab\", class: \"tab whitespace-nowrap #{\"tab-active\" if current_tab == \"countries\"}\" do %>\n        Countries\n      <% end %>\n    <% end %>\n\n    <% if show_states && location.is_a?(Country) && location.states? %>\n      <%= link_to country_states_path(alpha2: location.code), role: \"tab\", class: \"tab whitespace-nowrap #{\"tab-active\" if current_tab == \"states\"}\" do %>\n        States\n      <% end %>\n    <% end %>\n\n    <% if show_cities && location_cities_path(location).present? %>\n      <%= link_to location_cities_path(location), role: \"tab\", class: \"tab whitespace-nowrap #{\"tab-active\" if current_tab == \"cities\"}\" do %>\n        Cities\n      <% end %>\n    <% end %>\n\n    <% if show_stamps %>\n      <%= link_to location_stamps_path(location), role: \"tab\", class: \"tab whitespace-nowrap #{\"tab-active\" if current_tab == \"stamps\"}\" do %>\n        Stamps\n      <% end %>\n    <% end %>\n\n    <% if location_map_path(location).present? %>\n      <%= link_to location_map_path(location), role: \"tab\", class: \"tab whitespace-nowrap #{\"tab-active\" if current_tab == \"map\"}\" do %>\n        Map\n      <% end %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/shared/_location_past.html.erb",
    "content": "<%# locals: (location:, events:, users:, event_map_markers:, geo_layers: [], nearby_users: [], cities: []) %>\n\n<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% if location.is_a?(OnlineLocation) %>\n  <% title \"Past Online Ruby Events\" %>\n<% elsif location.is_a?(CoordinateLocation) %>\n  <% title \"Past Events near #{location.name}\" %>\n<% else %>\n  <% title \"Past Events in #{location.name}\" %>\n<% end %>\n\n<%= render \"shared/location_header\",\n      name: location.name,\n      subtitle: location.to_location.to_text,\n      flag_code: (location.respond_to?(:alpha2) && !location.is_a?(Continent)) ? location.alpha2 : nil,\n      emoji: location.is_a?(Continent) ? location.emoji_flag : nil,\n      stats: location.is_a?(OnlineLocation) ? \"#{pluralize(events.count, \"past event\")} online\" : \"#{pluralize(events.count, \"past event\")} in #{location.name}\",\n      location: location %>\n\n<%= render \"shared/location_navigation\",\n      location: location,\n      current_tab: \"past\",\n      show_cities: location.is_a?(Country),\n      show_countries: location.is_a?(Continent),\n      show_states: location.is_a?(Country) && location.states?,\n      show_stamps: location.stamps.any? %>\n\n<div class=\"container py-8\">\n  <div class=\"grid grid-cols-1 lg:grid-cols-3 gap-8\">\n    <div class=\"lg:col-span-2\">\n      <div class=\"flex items-center justify-between mb-6\">\n        <h2 class=\"text-xl font-bold text-gray-900\">Past Events</h2>\n      </div>\n\n      <%= render \"shared/month_grouped_events\", events: events, empty_message: \"No past events in #{location.name}.\" %>\n    </div>\n\n    <div class=\"lg:col-span-1\">\n      <%= render \"shared/location_sidebar\",\n            location: location,\n            users: users,\n            nearby_users: nearby_users,\n            cities: cities,\n            show_cities: cities.any?,\n            event_map_markers: event_map_markers,\n            geo_layers: geo_layers,\n            map_title: \"Past Events Map\" %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/shared/_location_show.html.erb",
    "content": "<%# locals: (location:, events:, users:, stamps:, event_map_markers:, geo_layers: [], nearby_users: [], nearby_events: [], cities: [], events_by_country: {}, country_events: [], country: nil, state: nil, state_users: [], continent_events: [], continent: nil, emoji: nil) %>\n\n<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% if location.is_a?(OnlineLocation) %>\n  <% title \"Online Ruby Events\" %>\n<% elsif location.is_a?(CoordinateLocation) %>\n  <% title \"Ruby Community near #{location.name}\" %>\n<% else %>\n  <% title \"Ruby Community in #{location.name}\" %>\n<% end %>\n\n<% upcoming_event_count = events.count(&:upcoming?) %>\n<% upcoming_nearby_count = nearby_events.count { |n| n[:event].upcoming? } %>\n<% upcoming_country_count = country_events.present? ? country_events.count : 0 %>\n<% upcoming_continent_count = continent_events.present? ? continent_events.count : 0 %>\n\n<% stats_text = if upcoming_event_count > 0\n     \"#{pluralize(upcoming_event_count, \"upcoming event\")} in #{location.name}\"\n   elsif upcoming_nearby_count > 0\n     \"#{pluralize(upcoming_nearby_count, \"event\")} nearby\"\n   elsif upcoming_country_count > 0 && country.present?\n     \"#{pluralize(upcoming_country_count, \"upcoming event\")} in #{country.name}\"\n   elsif upcoming_continent_count > 0 && continent.present?\n     \"#{pluralize(upcoming_continent_count, \"upcoming event\")} in #{continent.name}\"\n   else\n     \"#{pluralize(events.count, \"event\")} in #{location.name}\"\n   end %>\n\n<%= render \"shared/location_header\",\n      name: location.name,\n      subtitle: location.to_location.to_text,\n      flag_code: (location.respond_to?(:alpha2) && !location.is_a?(Continent)) ? location.alpha2 : nil,\n      emoji: location.is_a?(Continent) ? location.emoji_flag : emoji,\n      stats: stats_text,\n      location: location %>\n\n<%= render \"shared/location_navigation\",\n      location: location,\n      current_tab: \"overview\",\n      show_cities: location.is_a?(Country) || location.is_a?(UKNation) || location.is_a?(State),\n      show_countries: location.is_a?(Continent),\n      show_states: location.is_a?(Country) && location.states?,\n      show_stamps: location.stamps.any? %>\n\n<div class=\"container py-8\">\n  <div class=\"grid grid-cols-1 lg:grid-cols-3 gap-8\">\n    <div class=\"lg:col-span-2\">\n      <% upcoming_events = events.select(&:upcoming?) %>\n      <% past_events = events.select(&:past?) %>\n      <% upcoming_nearby_events = nearby_events.select { |n| n[:event].upcoming? } %>\n\n      <% if upcoming_events.any? %>\n        <%= render \"shared/events_section\",\n              title: \"Upcoming Events\",\n              events: upcoming_events,\n              limit: upcoming_events.size,\n              empty_message: \"No upcoming events.\" %>\n\n      <% elsif upcoming_nearby_events.any? %>\n        <%= render \"shared/events_section\",\n              title: \"Upcoming Events\",\n              events: upcoming_events,\n              empty_message: \"No upcoming events in #{location.name}.\",\n              fallback_text: past_events.any? ? \"View #{pluralize(past_events.count, \"past event\")} in #{location.name} →\" : nil,\n              fallback_path: past_events.any? ? location_past_path(location) : nil %>\n\n      <% else %>\n        <%= render \"shared/events_section\",\n              title: \"Upcoming Events\",\n              events: [],\n              empty_message: \"No upcoming events in #{location.name} yet.\",\n              fallback_text: past_events.any? ? \"View #{pluralize(past_events.count, \"past event\")} →\" : nil,\n              fallback_path: past_events.any? ? location_past_path(location) : nil %>\n\n      <% end %>\n\n      <% if upcoming_nearby_events.any? %>\n        <%= render \"shared/nearby_events_section\",\n              title: \"Upcoming Events Near #{location.name}\",\n              nearby_events: upcoming_nearby_events,\n              dimmed: false %>\n      <% end %>\n\n      <% if country_events.present? && country_events.any? && country.present? %>\n        <%= render \"shared/events_section\",\n              title: \"Upcoming Events in #{country.name}\",\n              events: country_events,\n              view_all_path: country_path(country),\n              view_all_count: country_events.count,\n              empty_message: \"No upcoming events in #{country.name}.\",\n              dimmed: true %>\n      <% end %>\n\n      <% if continent_events.present? && continent_events.any? && continent.present? %>\n        <%= render \"shared/events_section\",\n              title: \"Upcoming Events in #{continent.name}\",\n              events: continent_events,\n              view_all_path: continent_path(continent),\n              view_all_count: continent_events.count,\n              empty_message: \"No upcoming events in #{continent.name}.\",\n              limit: 8,\n              dimmed: true %>\n      <% end %>\n    </div>\n\n    <div class=\"lg:col-span-1\">\n      <%= render \"shared/location_sidebar\",\n            location: location,\n            users: users,\n            nearby_users: nearby_users,\n            nearby_events: nearby_events,\n            cities: cities,\n            countries: events_by_country,\n            show_cities: cities.any?,\n            show_countries: events_by_country.any?,\n            event_map_markers: event_map_markers,\n            geo_layers: geo_layers,\n            country_events: country_events,\n            continent_events: continent_events,\n            state: state,\n            state_users: state_users %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/shared/_location_sidebar.html.erb",
    "content": "<%# locals: (location:, users:, nearby_users: [], nearby_events: [], cities: [], countries: {}, show_cities: true, show_countries: false, event_map_markers: [], geo_layers: [], country_events: [], continent_events: [], state: nil, state_users: [], map_title: \"Upcoming Events Map\") %>\n\n<div class=\"space-y-8\">\n  <% if location.is_a?(OnlineLocation) %>\n    <div>\n      <h3 class=\"font-bold text-gray-900 mb-4\">About Online Events</h3>\n      <p class=\"text-gray-600 text-sm\">\n        Online events are virtual conferences, meetups, and workshops that you can attend from anywhere in the world.\n      </p>\n    </div>\n\n    <div>\n      <h3 class=\"font-bold text-gray-900 mb-4\">Browse by Location</h3>\n\n      <div class=\"space-y-1\">\n        <%= link_to continents_path, class: \"flex items-center gap-3 py-2 px-3 rounded-lg hover:bg-gray-50 transition-colors\" do %>\n          <span class=\"text-xl\">🌍</span>\n          <span class=\"text-gray-700\">Continents</span>\n        <% end %>\n\n        <%= link_to countries_path, class: \"flex items-center gap-3 py-2 px-3 rounded-lg hover:bg-gray-50 transition-colors\" do %>\n          <span class=\"text-xl\">🏳️</span>\n          <span class=\"text-gray-700\">Countries</span>\n        <% end %>\n\n        <%= link_to cities_path, class: \"flex items-center gap-3 py-2 px-3 rounded-lg hover:bg-gray-50 transition-colors\" do %>\n          <span class=\"text-xl\">🏙️</span>\n          <span class=\"text-gray-700\">Cities</span>\n        <% end %>\n      </div>\n    </div>\n  <% elsif geo_layers.any? || event_map_markers.any? || location.bounds.present? %>\n    <div\n      data-controller=\"map\"\n      <% if geo_layers.any? %>\n        data-map-layers-value=\"<%= geo_layers.to_json %>\"\n      <% end %>\n      <% if geo_layers.empty? %>\n        data-map-markers-value=\"<%= event_map_markers.to_json %>\"\n      <% end %>\n      <% if location.bounds.present? %>\n        data-map-bounds-value=\"<%= location.bounds.to_json %>\"\n      <% end %>>\n      <div class=\"flex items-center justify-between mb-4\">\n        <h3 class=\"font-bold text-gray-900\"><%= map_title %></h3>\n      </div>\n\n      <% if geo_layers.size >= 1 %>\n        <div class=\"flex flex-wrap items-center gap-2 mb-4\">\n          <%= render \"shared/map_layer_controls\", layers: geo_layers, selection: \"radio\", use_emoji: true %>\n        </div>\n      <% end %>\n\n      <div\n        id=\"sidebar-map\"\n        class=\"w-full h-96 rounded-xl overflow-hidden border\"\n        data-map-target=\"container\"></div>\n    </div>\n  <% end %>\n\n  <% unless location.is_a?(OnlineLocation) %>\n    <%= render \"shared/rubyists_preview\",\n          users: users.limit(24),\n          title: \"Rubyists in #{location.name}\",\n          total_count: users.count,\n          view_all_path: location_users_path(location) %>\n  <% end %>\n\n  <% if nearby_users.present? && nearby_users.any? %>\n    <div>\n      <div class=\"flex justify-between items-center mb-4\">\n        <h3 class=\"font-bold text-gray-900\">Rubyists near <%= location.name %></h3>\n\n        <%= link_to location_users_path(location), class: \"link text-sm\" do %>\n          View all\n        <% end %>\n      </div>\n\n      <div class=\"grid grid-cols-[repeat(auto-fill,3rem)] gap-2 justify-between\">\n        <% nearby_users.first(24).each do |nearby| %>\n          <% user = nearby.is_a?(Hash) ? nearby[:user] : nearby %>\n          <% distance_km = nearby.is_a?(Hash) ? nearby[:distance_km] : nil %>\n\n          <div class=\"relative group\">\n            <%= render Ui::AvatarComponent.new(user, size: :md, hover_card: true) %>\n\n            <% if distance_km %>\n              <div class=\"absolute -bottom-1 -right-1 bg-gray-700 text-white text-[10px] px-1 rounded-full leading-tight\">\n                <%= distance_km %>km\n              </div>\n            <% end %>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n\n  <% if state.present? && state_users.present? && state_users.any? %>\n    <%= render \"shared/rubyists_preview\",\n          users: state_users.first(24),\n          title: \"Rubyists in #{state.name}\",\n          view_all_path: state_users_path(state_alpha2: state.country.code, state_slug: state.slug) %>\n  <% end %>\n\n  <% if show_countries && countries.present? && countries.any? %>\n    <div id=\"countries\">\n      <div class=\"flex justify-between items-center mb-4\">\n        <h3 class=\"font-bold text-gray-900\">Countries</h3>\n\n        <% if countries.size > 12 %>\n          <%= link_to \"View all countries\", continent_countries_path(location), class: \"link text-sm mt-3 inline-block\" %>\n        <% end %>\n      </div>\n\n      <div class=\"space-y-1\">\n        <% countries.first(12).each do |country, events| %>\n          <% next unless country %>\n\n          <%= link_to country_path(country), class: \"flex justify-between items-center py-2 px-3 rounded-lg hover:bg-gray-50 transition-colors\" do %>\n            <span class=\"text-gray-700 flex items-center gap-2\">\n              <span class=\"fi fi-<%= country.alpha2.downcase %>\"></span>\n              <%= country.name %>\n            </span>\n\n            <%= ui_badge(events.count, kind: :secondary, outline: true, size: :sm) %>\n          <% end %>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n\n  <% if show_cities && cities.present? && cities.any? %>\n    <div id=\"cities\">\n      <div class=\"flex justify-between items-center mb-4\">\n        <h3 class=\"font-bold text-gray-900\">Cities</h3>\n\n        <% if location_cities_path(location).present? %>\n          <%= link_to location_cities_path(location), class: \"link text-sm\" do %>\n            View all\n          <% end %>\n        <% end %>\n      </div>\n\n      <div class=\"space-y-1\">\n        <% cities.first(12).each do |city| %>\n          <%= link_to city.path, class: \"flex justify-between items-center py-0.5 rounded-lg hover:bg-gray-50 transition-colors\" do %>\n            <span class=\"text-gray-700\">\n              <%= city.name %><% if city.state.present? %><span class=\"text-gray-400\">, <%= city.state.code %></span><% end %>\n            </span>\n\n            <%= ui_badge(city.events_count, kind: :secondary, outline: true, size: :sm) %>\n          <% end %>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_location_stamps.html.erb",
    "content": "<%# locals: (location:, stamps:) %>\n\n<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% title \"Stamps in #{location.name}\" %>\n\n<%= render \"shared/location_header\",\n      name: location.name,\n      subtitle: location.to_location.to_text,\n      flag_code: (location.respond_to?(:alpha2) && !location.is_a?(Continent)) ? location.alpha2 : nil,\n      emoji: location.is_a?(Continent) ? location.emoji_flag : nil,\n      stats: \"#{pluralize(stamps.count, \"stamp\")} in #{location.name}\",\n      location: location %>\n\n<%= render \"shared/location_navigation\",\n      location: location,\n      current_tab: \"stamps\",\n      show_cities: location.is_a?(Country),\n      show_countries: location.is_a?(Continent),\n      show_states: location.is_a?(Country) && location.states?,\n      show_stamps: true %>\n\n<div class=\"container py-8\">\n  <div class=\"flex items-center justify-between mb-6\">\n    <h2 class=\"text-xl font-bold text-gray-900\">Stamps from <%= location.name %></h2>\n\n    <%= ui_badge(stamps.count, kind: :secondary, outline: true) %>\n  </div>\n\n  <% if stamps.any? %>\n    <%= render partial: \"shared/stamps_grid\", locals: {stamps: stamps, min_rows: 1} %>\n  <% else %>\n    <p class=\"text-gray-500 py-8 text-center\">No stamps from <%= location.name %> yet.</p>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_location_users.html.erb",
    "content": "<%# locals: (location:, users:, nearby_users: [], state: nil, state_users: [], country: nil, country_users: []) %>\n\n<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% if location.is_a?(CoordinateLocation) %>\n  <% title \"Rubyists near #{location.name}\" %>\n<% else %>\n  <% title \"Rubyists in #{location.name}\" %>\n<% end %>\n\n<% location_preposition = location.is_a?(CoordinateLocation) ? \"near\" : \"in\" %>\n<% stats_count = location.is_a?(CoordinateLocation) ? nearby_users.count : users.count %>\n<%= render \"shared/location_header\",\n      name: location.name,\n      subtitle: location.to_location.to_text,\n      flag_code: (location.respond_to?(:alpha2) && !location.is_a?(Continent)) ? location.alpha2 : nil,\n      emoji: location.is_a?(Continent) ? location.emoji_flag : nil,\n      stats: \"#{pluralize(stats_count, \"Rubyist\")} #{location_preposition} #{location.name}\",\n      location: location %>\n\n<%= render \"shared/location_navigation\",\n      location: location,\n      current_tab: \"users\",\n      show_cities: location.is_a?(Country),\n      show_countries: location.is_a?(Continent),\n      show_states: location.is_a?(Country) && location.states?,\n      show_stamps: location.stamps.any? %>\n\n<div class=\"container py-8\">\n  <% if location.is_a?(CoordinateLocation) %>\n    <%# For coordinates, show nearby users with distances as the primary section %>\n    <div class=\"flex items-center justify-between mb-6\">\n      <h2 class=\"text-xl font-bold text-gray-900\">Rubyists near <%= location.name %></h2>\n      <%= ui_badge(nearby_users.count, kind: :secondary, outline: true) %>\n    </div>\n\n    <% if nearby_users.any? %>\n      <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n        <% nearby_users.each do |nearby| %>\n          <% user = nearby.is_a?(Hash) ? nearby[:user] : nearby %>\n          <% distance_km = nearby.is_a?(Hash) ? nearby[:distance_km] : nil %>\n          <% location_text = user.location.presence || user.city %>\n          <% content_text = distance_km ? \"#{location_text} • #{distance_km} km\" : location_text %>\n\n          <%= render partial: \"users/card\", locals: {user: user, content: content_text} %>\n        <% end %>\n      </div>\n    <% else %>\n      <p class=\"text-gray-500 py-8 text-center\">No Rubyists near <%= location.name %> yet.</p>\n    <% end %>\n\n    <% if country.present? && country_users.present? && country_users.any? %>\n      <div class=\"mt-12\">\n        <div class=\"flex items-center justify-between mb-6\">\n          <h2 class=\"text-xl font-bold text-gray-900\">Rubyists in <%= country.name %></h2>\n          <%= ui_badge(country_users.count, kind: :secondary, outline: true) %>\n        </div>\n\n        <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n          <% country_users.each do |user| %>\n            <%= render partial: \"users/card\", locals: {user: user, content: user.location.presence || user.city} %>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n  <% else %>\n    <%# For other location types, show standard layout %>\n    <div class=\"flex items-center justify-between mb-6\">\n      <h2 class=\"text-xl font-bold text-gray-900\">Rubyists in <%= location.name %></h2>\n      <%= ui_badge(users.count, kind: :secondary, outline: true) %>\n    </div>\n\n    <% if users.any? %>\n      <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n        <% users.each do |user| %>\n          <%= render partial: \"users/card\", locals: {user: user, content: user.location.presence || user.city} %>\n        <% end %>\n      </div>\n    <% else %>\n      <p class=\"text-gray-500 py-8 text-center\">No Rubyists in <%= location.name %> yet.</p>\n    <% end %>\n\n    <% if nearby_users.present? && nearby_users.any? %>\n      <div class=\"mt-12\">\n        <div class=\"flex items-center justify-between mb-6\">\n          <h2 class=\"text-xl font-bold text-gray-900\">Rubyists near <%= location.name %></h2>\n          <%= ui_badge(nearby_users.count, kind: :secondary, outline: true) %>\n        </div>\n\n        <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n          <% nearby_users.each do |nearby| %>\n            <% user = nearby.is_a?(Hash) ? nearby[:user] : nearby %>\n            <% distance_km = nearby.is_a?(Hash) ? nearby[:distance_km] : nil %>\n            <% location_text = user.location.presence || user.city %>\n            <% content_text = distance_km ? \"#{location_text} • #{distance_km} km\" : location_text %>\n\n            <%= render partial: \"users/card\", locals: {user: user, content: content_text} %>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n\n    <% if state.present? && state_users.present? && state_users.any? %>\n      <div class=\"mt-12\">\n        <div class=\"flex items-center justify-between mb-6\">\n          <h2 class=\"text-xl font-bold text-gray-900\">Rubyists in <%= state.name %></h2>\n          <%= ui_badge(state_users.count, kind: :secondary, outline: true) %>\n        </div>\n\n        <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4\">\n          <% state_users.each do |user| %>\n            <%= render partial: \"users/card\", locals: {user: user, content: user.location.presence || user.city} %>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_map_layer_controls.html.erb",
    "content": "<%# locals: (layers:, selection: \"checkbox\", use_emoji: false) %>\n\n<div class=\"flex flex-wrap gap-2\" data-map-target=\"controls\">\n  <% layers.each do |layer| %>\n    <% display_label = (use_emoji && layer[:emoji].present?) ? layer[:emoji] : layer[:label] %>\n\n    <label class=\"btn btn-sm <%= layer[:visible] ? \"btn-primary text-primary-content\" : \"btn-ghost\" %>\" title=\"<%= layer[:label] %>\">\n      <% if selection == \"radio\" %>\n        <input\n          type=\"radio\" name=\"map_layer\" class=\"hidden\"\n          data-action=\"change->map#selectLayer\"\n          data-layer-id=\"<%= layer[:id] %>\"\n          <% if layer[:visible] %> checked <% end %>>\n      <% else %>\n        <input\n          type=\"checkbox\" class=\"hidden\"\n          data-action=\"change->map#toggleLayer\"\n          data-layer-id=\"<%= layer[:id] %>\"\n          <% if layer[:visible] %> checked <% end %>>\n      <% end %>\n\n      <%= display_label %>\n\n      <span class=\"badge badge-sm ml-1 <%= layer[:visible] ? \"bg-white text-primary\" : \"badge-ghost\" %>\">\n        <%= layer[:markers].count %>\n      </span>\n    </label>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_map_time_filter.html.erb",
    "content": "<%# locals: (options:) %>\n\n<div class=\"flex flex-wrap gap-2\" data-map-target=\"timeFilter\">\n  <% options.each do |option| %>\n    <label class=\"btn btn-sm <%= option[:visible] ? \"btn-primary text-primary-content\" : \"btn-ghost\" %>\">\n      <input\n        type=\"radio\" name=\"map_time_filter\"\n        class=\"hidden\"\n        data-action=\"change->map#filterByTime\"\n        data-time-filter=\"<%= option[:id] %>\"\n        <% if option[:visible] %> checked <% end %>>\n\n      <%= option[:label] %>\n    </label>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_meta_talk_card.html.erb",
    "content": "<%= link_to meta_talk, class: \"flex flex-col sm:flex-row gap-4 sm:gap-10 group w-full overflow-hidden\", data: {turbo_frame: \"_top\"} do %>\n  <% unless local_assigns[:hide_date_sidebar] %>\n    <div class=\"w-full sm:w-[10rem] mt-2 flex-shrink-0\">\n      <time datetime=\"<%= meta_talk.date.iso8601 %>\" class=\"text-black font-medium text-lg\">\n        <% if meta_talk.date.year == Date.today.year %>\n          <%= l(meta_talk.date, format: :month_day, default: \"unknown\") %>\n        <% else %>\n          <%= l(meta_talk.date, format: :medium, default: \"unknown\") %>\n        <% end %>\n      </time>\n      <div class=\"text-gray-400 font-normal\">\n        <%= meta_talk.date.strftime(\"%A\") %>\n      </div>\n    </div>\n  <% end %>\n\n  <div class=\"bg-white rounded p-5 w-full border border-gray-200 group-hover:border-gray-400 overflow-x-auto\">\n    <div class=\"grid grid-cols-1 sm:grid-cols-[230px_1fr] gap-4 sm:gap-8\">\n      <div class=\"flex aspect-video overflow-hidden w-full max-w-full\">\n        <%= image_tag(\n              meta_talk.thumbnail_lg,\n              srcset: [\"#{meta_talk.thumbnail_lg} 2x\"],\n              id: dom_id(meta_talk),\n              height: 174,\n              width: 310,\n              loading: \"lazy\",\n              alt: \"talk by #{meta_talk.speakers.map(&:name).join(\", \")}: #{meta_talk.title}\",\n              style: \"view-transition-name: #{dom_id(meta_talk, :image)}\",\n              class: \"w-full object-cover rounded-xl #{meta_talk.thumbnail_classes}\"\n            ) %>\n      </div>\n      <div class=\"min-w-0\">\n        <div class=\"font-mono text-xl font-medium text-black\">\n          <%= meta_talk.title %>\n        </div>\n\n        <div>\n          <%= l(meta_talk.date, default: \"unknown\") %>\n        </div>\n\n        <% unless local_assigns[:hide_speakers] %>\n          <div class=\"mt-3\">\n            <%= \"Speaker\".pluralize(meta_talk.speakers.count) %>:\n            <% if local_assigns[:compact_speakers] %>\n              <div class=\"text-sm text-gray-600 mt-1 line-clamp-1\">\n                <%= meta_talk.speakers.map(&:name).join(\", \") %>\n              </div>\n            <% else %>\n              <div class=\"flex flex-row flex-wrap gap-4 mt-2\">\n                <% meta_talk.speakers.each do |speaker| %>\n                  <div class=\"flex gap-1\">\n                    <div class=\"avatar placeholder\">\n                      <%= ui_avatar(speaker, size: :sm) %>\n                    </div>\n\n                    <div>\n                      <%= speaker.name %>\n                    </div>\n                  </div>\n                <% end %>\n\n                <% if meta_talk.speakers.none? %>\n                  -\n                <% end %>\n              </div>\n            <% end %>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_month_grouped_events.html.erb",
    "content": "<%# locals: (events:, empty_message: \"No events found.\") %>\n\n<% if events.any? %>\n  <% events_by_month = events.group_by { |e| e.start_date&.beginning_of_month }.sort_by { |month, _| month || Date.new(9999) }.reverse %>\n\n  <% events_by_month.each do |month, month_events| %>\n    <div class=\"mb-8\" data-events-filter-target=\"group\">\n      <div class=\"flex items-center gap-2 mb-4\">\n        <span class=\"w-2 h-2 rounded-full bg-gray-400\"></span>\n\n        <span class=\"text-lg font-semibold text-gray-800\">\n          <% if month.present? %>\n            <%= month.strftime(\"%B %Y\") %>\n          <% else %>\n            Date TBD\n          <% end %>\n        </span>\n      </div>\n\n      <div class=\"space-y-3 pl-4\">\n        <% month_events.sort_by { |e| e.start_date || Date.new(9999) }.reverse.each do |event| %>\n          <%= render \"shared/event_row\", event: event %>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n<% else %>\n  <div class=\"text-gray-500 py-8 text-center border border-dashed\">\n    <%= empty_message %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_navbar.html.erb",
    "content": "<div class=\"navbar relative z-50 bg-transparent\">\n  <div class=\"container grid grid-cols-2 lg:grid-cols-[1fr_auto_1fr] justify-between items-center\">\n    <div class=\"items-center gap-6 hidden lg:flex\">\n      <ul class=\"desktop-menu\">\n        <%= render \"shared/navbar/link\", link_title: \"Events\", path: events_path %>\n        <%= render \"shared/navbar/link\", link_title: \"Videos\", path: browse_index_path %>\n        <%= render \"shared/navbar/link\", link_title: \"Speakers\", path: speakers_path %>\n        <%= render \"shared/navbar/link\", link_title: \"Organizations\", path: organizations_path %>\n        <%= render \"shared/navbar/link\", link_title: \"Topics\", path: topics_path %>\n        <%= render \"shared/navbar/link\", link_title: \"CFP\", path: cfp_index_path %>\n      </ul>\n    </div>\n\n    <div class=\"flex justify-start lg:justify-center items-center\">\n      <%= link_to root_path do %>\n        <%= image_tag image_path(\"logo.png\"), class: \"size-10 hover:opacity-80\" %>\n      <% end %>\n    </div>\n\n    <div class=\"flex justify-end items-center\">\n      <ul class=\"hidden lg:flex items-center gap-4 h-full\">\n\n        <div class=\"flex items-center gap-2\">\n          <ul class=\"desktop-menu\">\n            <% signed_in do %>\n              <%= render \"shared/navbar/link\", link_title: \"Favorite Rubyists\", path: favorite_users_path %>\n            <% end %>\n            <%= render \"shared/navbar/link\", link_title: \"Contribute\", path: contributions_path %>\n            <%= render \"shared/navbar/link\", link_title: \"News\", path: announcements_path %>\n          </ul>\n        </div>\n\n        <%= render \"shared/navbar/search_bar\", id: \"magnifying-glass\" %>\n\n        <% signed_in do %>\n          <li class=\"flex items-center\">\n            <%= link_to profile_path(Current.user), class: \"hover:opacity-80 flex items-center\", title: \"My Ruby Events Profile\" do %>\n              <%= render Ui::AvatarComponent.new(Current.user, size: :sm, size_class: \"w-7\", outline: true) %>\n            <% end %>\n          </li>\n          <li class=\"flex items-center\">\n            <%= render \"shared/user_dropdown\" %>\n          </li>\n        <% end %>\n\n        <% signed_out do %>\n          <li class=\"flex items-center\">\n            <%= link_to \"Sign in\", new_session_path(redirect_to: request.fullpath), data: {turbo_frame: \"modal\"}, class: \"btn btn-primary\" %>\n          </li>\n        <% end %>\n      </ul>\n\n      <div class=\"flex lg:hidden gap-2 items-center\">\n        <%= render \"shared/navbar/search_bar\", id: \"magnifying-glass-mobile\" %>\n        <% signed_in do %>\n          <%= link_to profile_path(Current.user), class: \"hover:opacity-80 flex items-center\", title: \"My Ruby Events Profile\" do %>\n            <%= render Ui::AvatarComponent.new(Current.user, size: :sm, size_class: \"w-7\", outline: true) %>\n          <% end %>\n        <% end %>\n        <%= render \"shared/user_mobile_dropdown\" %>\n      </div>\n    </div>\n  </div>\n</div>\n\n<%= render \"shared/spotlight_search\" %>\n"
  },
  {
    "path": "app/views/shared/_nearby_events_section.html.erb",
    "content": "<%# locals: (title:, nearby_events:, fallback_text: nil, fallback_path: nil, limit: 8, dimmed: false) %>\n\n<div class=\"mb-12 <%= \"opacity-60 hover:opacity-100 transition-opacity\" if dimmed %>\">\n  <div class=\"flex items-center justify-between mb-6\">\n    <h2 class=\"text-xl font-bold text-gray-900\"><%= title %></h2>\n  </div>\n\n  <% limited_events = nearby_events.first(limit) %>\n  <% events_by_date = limited_events.group_by { |n| event_date_group_key(n[:event]) }.sort_by { |key, _| key || \"zzz\" } %>\n\n  <% events_by_date.each do |_, date_nearby_events| %>\n    <% first_event = date_nearby_events.first[:event] %>\n    <div class=\"mb-8\">\n      <div class=\"flex items-center gap-2 mb-4\">\n        <span class=\"w-2 h-2 rounded-full bg-gray-400\"></span>\n        <span class=\"text-lg font-semibold text-gray-800\">\n          <% if first_event.date_precision == \"day\" && first_event.start_date.present? %>\n            <%= first_event.start_date.strftime(\"%b %-d\") %>\n            <span class=\"font-normal text-gray-500\"><%= first_event.start_date.strftime(\"%A\") %></span>\n          <% elsif first_event.start_date.present? %>\n            <%= event_date_display(first_event, day_name: false) %>\n          <% else %>\n            Date TBD\n          <% end %>\n        </span>\n      </div>\n\n      <div class=\"space-y-3 pl-4\">\n        <% date_nearby_events.each do |nearby| %>\n          <% event = nearby[:event] %>\n\n          <%= link_to event_path(event), class: \"block bg-white rounded-lg border p-4 hover:border-gray-400 transition-colors\" do %>\n            <div class=\"flex gap-4 items-start\">\n              <% if event.avatar_image_path %>\n                <div class=\"w-16 h-16 flex-shrink-0 rounded-lg overflow-hidden\">\n                  <%= image_tag event.avatar_image_path, class: \"w-full h-full object-cover\" %>\n                </div>\n              <% end %>\n\n              <div class=\"flex-grow min-w-0\">\n                <div class=\"font-semibold text-gray-900 truncate\"><%= event.name %></div>\n\n                <div class=\"text-sm text-gray-600 mt-1\">\n                  <span class=\"inline-flex items-center gap-1\">\n                    <%= fa(\"map-marker-alt\", size: :xs, class: \"text-gray-400\") %>\n                    <%= event.location %>\n\n                    <span class=\"text-gray-400\">• <%= nearby[:distance_km] %> km away</span>\n                  </span>\n                </div>\n              </div>\n\n              <% if event.participants.any? %>\n                <div class=\"flex-shrink-0\">\n                  <%= render Ui::AvatarGroupComponent.new(event.participants.to_a, max: 4, size: :md, overlap: \"-space-x-3\") %>\n                </div>\n              <% end %>\n            </div>\n          <% end %>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n\n  <% if fallback_path.present? && fallback_text.present? %>\n    <div class=\"mt-6 text-center\">\n      <%= link_to fallback_text, fallback_path, class: \"link text-sm\" %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_rubyists_preview.html.erb",
    "content": "<%# locals: (users:, title:, view_all_path: nil, total_count: nil, users_path: nil) %>\n\n<div>\n  <div class=\"flex justify-between items-center mb-4\">\n    <h3 class=\"font-bold text-gray-900\"><%= title %></h3>\n\n    <% if view_all_path.present? %>\n      <%= link_to \"View all\", view_all_path, class: \"link text-sm mt-3 inline-block\" %>\n    <% end %>\n  </div>\n\n  <% if users.any? %>\n    <div class=\"grid grid-cols-[repeat(auto-fill,3rem)] gap-2 justify-between\">\n      <% users.first(24).each do |user| %>\n        <%= render Ui::AvatarComponent.new(user, size: :md, hover_card: true) %>\n      <% end %>\n    </div>\n  <% else %>\n    <p class=\"text-gray-500 text-sm\">No Rubyists found yet.</p>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/shared/_spotlight_search.html.erb",
    "content": "<%= ui_modal position: :top, size: :full, close_button: false, data: {action: \"keydown.meta+k@window->modal#open spotlight@window->modal#open\"}, class: \"spotlight\" do %>\n  <div\n    id=\"spotlight-search\"\n    class=\"flex flex-col h-full\"\n    data-controller=\"spotlight-search\"\n    data-spotlight-search-url-spotlight-talks-value=\"<%= spotlight_talks_path %>\"\n    data-spotlight-search-url-spotlight-speakers-value=\"<%= spotlight_speakers_path %>\"\n    data-spotlight-search-url-spotlight-events-value=\"<%= spotlight_events_path %>\"\n    data-spotlight-search-url-spotlight-topics-value=\"<%= spotlight_topics_path %>\"\n    data-spotlight-search-url-spotlight-series-value=\"<%= spotlight_can_search_series? ? spotlight_series_index_path : nil %>\"\n    data-spotlight-search-url-spotlight-organizations-value=\"<%= spotlight_organizations_path %>\"\n    data-spotlight-search-url-spotlight-locations-value=\"<%= spotlight_can_search_locations? ? spotlight_locations_path : nil %>\"\n    data-spotlight-search-url-spotlight-languages-value=\"<%= spotlight_can_search_languages? ? spotlight_languages_path : nil %>\"\n    data-spotlight-search-url-spotlight-kinds-value=\"<%= spotlight_kinds_path %>\"\n    data-spotlight-search-main-resource-path-value=\"<%= spotlight_main_resource_path %>\"\n    data-spotlight-search-default-backend-value=\"<%= Search::Backend.default_backend_key %>\">\n    <div class=\"flex items-center gap-2 rounded-lg bg-white px-2 relative shrink-0\">\n      <%= fa(\"magnifying-glass\", size: :md, style: :regular) %>\n      <%= tag.input type: \"text\",\n            name: \"query\",\n            autofocus: true,\n            autocomplete: \"off\",\n            placeholder: \"Search talks, speakers, events, topics, locations...\",\n            class: \"w-full p-3 outline-none text-lg\",\n            data: {\n              action:\n                \"spotlight-search#search keydown.enter->spotlight-search#navigate:stop\",\n              spotlight_search_target: \"searchInput\"\n            } %>\n      <% if Rails.env.development? %>\n        <% default_backend = Search::Backend.default_backend_key.to_s %>\n        <% available_backends = Search::Backend.available_backends %>\n        <% sqlite_available = available_backends.include?(:sqlite_fts) %>\n        <% typesense_available = available_backends.include?(:typesense) %>\n        <div class=\"flex items-center gap-1 absolute right-10 top-1/2 -translate-y-1/2\" data-spotlight-search-target=\"backendToggle\">\n          <%= tag.span \"SQLite\",\n                class: \"badge badge-xs #{sqlite_available ? \"cursor-pointer\" : \"opacity-40 cursor-not-allowed\"} #{(default_backend == \"sqlite_fts\") ? \"badge-warning\" : \"badge-ghost\"}\",\n                data: {\n                  action: sqlite_available ? \"click->spotlight-search#setBackend\" : nil,\n                  backend: sqlite_available ? \"sqlite_fts\" : nil,\n                  spotlight_search_target: \"sqliteBadge\"\n                } %>\n          <%= tag.span \"Typesense\",\n                class: \"badge badge-xs #{typesense_available ? \"cursor-pointer\" : \"opacity-40 cursor-not-allowed\"} #{(default_backend == \"typesense\") ? \"badge-primary\" : \"badge-ghost\"}\",\n                data: {\n                  action: typesense_available ? \"click->spotlight-search#setBackend\" : nil,\n                  backend: typesense_available ? \"typesense\" : nil,\n                  spotlight_search_target: \"typesenseBadge\"\n                } %>\n        </div>\n      <% end %>\n      <%= fa(\n            \"xmark\",\n            size: :sm,\n            class: \"absolute right-2 top-1/2 -translate-y-1/2 hidden cursor-pointer\",\n            data: {\n              action: \"click->spotlight-search#clear\",\n              spotlight_search_target: \"clear\"\n            }\n          ) %>\n      <%= fa(\n            \"rotate\",\n            size: :sm,\n            class:\n              \"absolute right-2 top-0 bottom-0 my-auto animate-spin hidden text-gray-600\",\n            data: {\n              spotlight_search_target: \"loading\"\n            }\n          ) %>\n    </div>\n    <div\n      role=\"listbox\"\n      class=\"flex-1 overflow-hidden mt-4\"\n      data-spotlight-search-target=\"searchResults\"\n      aria-live=\"polite\">\n      <div\n        class=\"flex items-center gap-2 border-b pb-4 hidden\"\n        data-spotlight-search-target=\"allSearchResults\">\n        <div role=\"option\">search\n          <%= spotlight_main_resource %>\n          for\n          <strong class=\"text-base-content\" data-spotlight-search-target=\"searchQuery\"></strong></div>\n        <kbd class=\"kbd kbd-sm text-base-content\">⏎</kbd>\n        <% if Rails.env.development? %>\n          <span class=\"badge badge-xs badge-warning hidden\" data-spotlight-search-target=\"searchBackendBadge\">SQLite FTS</span>\n        <% end %>\n      </div>\n\n      <div\n        id=\"topics_search_results\"\n        class=\"pb-4 border-b hidden\"\n        data-spotlight-search-target=\"topicsSearchResults\"></div>\n\n      <div\n        id=\"kinds_search_results\"\n        class=\"pb-4 border-b hidden\"\n        data-spotlight-search-target=\"kindsSearchResults\"></div>\n\n      <div\n        id=\"locations_search_results\"\n        class=\"pb-4 border-b hidden\"\n        data-spotlight-search-target=\"locationsSearchResults\"></div>\n\n      <div\n        id=\"languages_search_results\"\n        class=\"pb-4 border-b hidden\"\n        data-spotlight-search-target=\"languagesSearchResults\"></div>\n\n      <div\n        id=\"series_search_results\"\n        class=\"pb-4 border-b hidden\"\n        data-spotlight-search-target=\"seriesSearchResults\"></div>\n\n      <div\n        id=\"organizations_search_results\"\n        class=\"pb-4 border-b hidden\"\n        data-spotlight-search-target=\"organizationsSearchResults\"></div>\n\n      <div class=\"grid md:grid-cols-3 md:divide-x gap-4 md:gap-0 h-full overflow-hidden pt-4 border-t\">\n        <% spotlight_resources.unshift(spotlight_main_resource) %>\n        <% spotlight_resources.uniq.each_with_index do |resource, index| %>\n          <% padding = {\"0\" => \"md:pr-4\", \"1\" => \"md:px-4\", \"2\" => \"md:pl-4\"}.dig(index.to_s) %>\n          <div\n            id=\"<%= resource %>_search_results\"\n            class=\"<%= padding %> overflow-y-auto\"\n            data-spotlight-search-target=\"<%= resource %>SearchResults\"></div>\n        <% end %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_stamps_grid.html.erb",
    "content": "<%# locals: (stamps:, min_rows: 3) %>\n\n<div class=\"mx-auto w-full overflow-hidden rounded-[40px] bg-gradient-to-b from-gray-600 via-gray-600 to-gray-400 p-[12px]\">\n  <div class=\"grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-4 p-4 rounded-[32px] bg-white auto-rows-fr\">\n    <% stamps.each do |stamp| %>\n      <div class=\"w-full h-full border-4 border-dotted border-gray-300 rounded-xl p-2 bg-white\">\n        <div class=\"w-full h-full rounded-xl flex items-center justify-center relative overflow-hidden lg:p-2\">\n          <%= ui_stamp(stamp, rotate: true, zoom_effect: true, class: \"hover:lg:opacity-70\") %>\n        </div>\n      </div>\n    <% end %>\n\n    <% cols_per_row = 6 %>\n    <% remaining = [min_rows * cols_per_row - stamps.count, (cols_per_row - (stamps.count % cols_per_row)) % cols_per_row].max %>\n    <%# remaining = (cols_per_row - (stamps.count % cols_per_row)) % cols_per_row %>\n\n    <% remaining.times do %>\n      <div class=\"aspect-square flex items-center justify-center\">\n        <div class=\"w-full h-full border-4 border-dotted border-gray-300 rounded-xl p-2 bg-white\">\n          <div class=\"w-full h-full rounded-xl flex items-center justify-center relative overflow-hidden\">\n          </div>\n        </div>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/shared/_stickers_display.html.erb",
    "content": "<div class=\"bg-black rounded-2xl\">\n  <div class=\"flex w-full items-center justify-center bg-black p-2 lg:p-12\">\n    <div class=\"mx-auto w-full overflow-hidden rounded-[40px] bg-gradient-to-b from-gray-300 via-gray-600 to-gray-600 p-[4px]\">\n      <div class=\"back flex overflow-hidden aspect-[16/11] w-full items-center justify-center rounded-[40px] bg-gradient-to-b from-gray-400 via-gray-500 to-gray-600\">\n        <div class=\"grid grid-cols-3 gap-[5vw] w-full h-full p-12\">\n          <% events.shuffle.flat_map(&:stickers).each do |sticker| %>\n            <%= link_to sticker.event, class: \"max-w-[10vw]\", style: \"transform: rotate(#{(-20...20).to_a.sample}deg) translateY(#{(0...5).to_a.sample}vw) translateX(#{(0...5).to_a.sample}vh) scale(#{100 + (-10...10).to_a.sample}%)\", data: {turbo_frame: \"_top\"} do %>\n              <%= image_tag sticker.asset_path, class: \"transition transition-transform hover:scale-105\" %>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/shared/_toast.html.erb",
    "content": "<%= content_tag :div do %>\n  <div\n    aria-live=\"assertive\"\n    class=\"pointer-events-none inset-0 flex items-end sm:items-start\">\n    <div class=\"flex w-full flex-col items-center sm:items-end\">\n      <div\n        data-controller=\"transition\"\n        data-transition-enter-after-value=\"0\"\n        data-transition-enter-from-value=\"translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2 h-0\"\n        data-transition-enter-to-value=\"translate-y-0 opacity-100 sm:translate-x-0\"\n        data-transition-leave-after-value=\"2000\"\n        class=\"\n          pointer-events-auto max-w-sm overflow-hidden rounded-lg bg-white text-neutral\n          shadow-lg ring-1 ring-brand-lighter hidden\n        \">\n        <div class=\"p-2 sm:p-4\">\n          <div class=\"flex items-center gap-3\">\n            <div class=\"flex-shrink-0\">\n              <%= fa(\"check\") %>\n            </div>\n            <div class=\"flex-1 whitespace-normal text-sm\">\n              <%= text %>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_top_banner.html.erb",
    "content": "<% unless hotwire_native_app? %>\n  <div class=\"relative isolate flex items-center gap-x-6 overflow-hidden bg-gray-50 px-6 py-2.5 sm:px-3.5 sm:before:flex-1 hidden\" data-controller=\"top-banner\">\n    <div class=\"absolute left-[max(-7rem,calc(50%-52rem))] top-1/2 -z-10 -translate-y-1/2 transform-gpu blur-2xl\" aria-hidden=\"true\">\n      <div class=\"aspect-[577/310] w-[36.0625rem] bg-gradient-to-r from-[#DC143C] to-[#FBEEEE] opacity-30\" style=\"clip-path: polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)\"></div>\n    </div>\n    <div class=\"absolute left-[max(45rem,calc(50%+8rem))] top-1/2 -z-10 -translate-y-1/2 transform-gpu blur-2xl\" aria-hidden=\"true\">\n      <div class=\"aspect-[577/310] w-[36.0625rem] bg-gradient-to-r from-[#DC143C] to-[#FBEEEE] opacity-30\" style=\"clip-path: polygon(74.8% 41.9%, 97.2% 73.2%, 100% 34.9%, 92.5% 0.4%, 87.5% 0%, 75% 28.6%, 58.5% 54.6%, 50.1% 56.8%, 46.9% 44%, 48.3% 17.4%, 24.7% 53.9%, 0% 27.9%, 11.9% 74.2%, 24.9% 54.1%, 68.6% 100%, 74.8% 41.9%)\"></div>\n    </div>\n    <p class=\"text-sm leading-6\">\n      HERE IS THE TOP BANNER TEXT\n    </p>\n    <div class=\"flex flex-1 justify-end\">\n      <button type=\"button\" class=\"-m-3 p-3 focus-visible:outline-offset-[-4px] tertiary\" data-action=\"click->top-banner#dismiss\">\n        <span class=\"sr-only\">Dismiss</span>\n        <%= fa(\"xmark\") %>\n      </button>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_user_dropdown.html.erb",
    "content": "<%= ui_dropdown align: :end, content_classes: \"mt-5 shadow-xl\", id: \"user_navbar_toggle\" do |c| %>\n  <% c.with_toggle_open do %>\n    <%= fa(\"xmark\", size: :md) %>\n  <% end %>\n\n  <% c.with_toggle_close do %>\n    <%= fa(\"bars\", size: :md) %>\n  <% end %>\n\n  <% c.with_menu_item_link_to \"Leaderboard\", leaderboard_path %>\n  <% c.with_menu_item_link_to \"Countries\", countries_path %>\n  <% if Current.user %>\n    <% c.with_menu_item_divider %>\n\n    <% c.with_menu_item_link_to \"For You\", recommendations_path %>\n\n    <% c.with_menu_item_link_to watched_talks_path do %>\n      <div class=\"flex items-center gap-2\">\n        <span>Recently Watched</span>\n        <% if Current.user.watched_talks_count.positive? %>\n          <div class=\"badge badge-secondary\"><%= Current.user.watched_talks_count %></div>\n        <% end %>\n      </div>\n    <% end %>\n\n    <% c.with_menu_item_link_to watch_lists_path do %>\n      <div class=\"flex items-center gap-2\">\n        <span>Bookmarks</span>\n        <% if Current.user.default_watch_list.talks_count.positive? %>\n          <div class=\"badge badge-secondary\"><%= Current.user.default_watch_list.talks_count %></div>\n        <% end %>\n      </div>\n    <% end %>\n\n    <% c.with_menu_item_divider %>\n    <% c.with_menu_item_link_to \"My Profile\", profile_path(Current.user) %>\n    <% c.with_menu_item_link_to \"Settings\", settings_path %>\n    <% if Current.user&.admin? %>\n      <% c.with_menu_item_link_to \"Suggestions\", admin_suggestions_path %>\n      <% c.with_menu_item_link_to t(\"admin\"), avo_path %>\n      <% c.with_menu_item_divider %>\n    <% end %>\n    <% c.with_menu_item_button_to t(\"sign_out\"),\n         Current.session,\n         method: :delete,\n         id: :sign_out %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/_user_mobile_dropdown.html.erb",
    "content": "<%= ui_dropdown align: :end, content_classes: \"mt-5 shadow-xl min-w-32\", id: \"user_navbar_toggle\" do |c| %>\n  <% c.with_toggle_open do %>\n    <%= fa(\"xmark\", size: :lg) %>\n  <% end %>\n\n  <% c.with_toggle_close do %>\n    <%= fa(\"bars\", size: :lg) %>\n  <% end %>\n\n  <% c.with_menu_item_link_to \"Home\", root_path %>\n  <% c.with_menu_item_link_to \"Videos\", browse_index_path %>\n  <% c.with_menu_item_link_to \"Talks\", talks_path %>\n  <% c.with_menu_item_link_to \"Speakers\", speakers_path %>\n  <% c.with_menu_item_link_to \"Organizations\", organizations_path %>\n  <% c.with_menu_item_link_to \"Events\", events_path %>\n  <% c.with_menu_item_link_to \"CFPs\", cfp_index_path %>\n  <% c.with_menu_item_link_to \"Topics\", topics_path %>\n  <% c.with_menu_item_link_to \"News\", announcements_path %>\n\n  <% c.with_menu_item_divider %>\n\n  <% c.with_menu_item_link_to \"Leaderboard\", leaderboard_path %>\n  <% c.with_menu_item_link_to \"Countries\", countries_path %>\n\n  <% signed_in do %>\n    <% c.with_menu_item_divider %>\n\n    <% c.with_menu_item_link_to \"Favorite Rubyists\", favorite_users_path %>\n    <% c.with_menu_item_link_to \"For You\", recommendations_path %>\n    <% c.with_menu_item_link_to watched_talks_path do %>\n      <div class=\"flex items-center gap-2\">\n        <span>Recently Watched</span>\n        <% if Current.user.watched_talks_count.positive? %>\n          <div class=\"badge badge-secondary\"><%= Current.user.watched_talks_count %></div>\n        <% end %>\n      </div>\n    <% end %>\n\n    <% c.with_menu_item_link_to watch_lists_path do %>\n      <div class=\"flex items-center gap-2\">\n        <span>Bookmarks</span>\n        <% if Current.user.default_watch_list.talks_count.positive? %>\n          <div class=\"badge badge-secondary\"><%= Current.user.default_watch_list.talks_count %></div>\n        <% end %>\n      </div>\n    <% end %>\n  <% end %>\n\n  <% signed_in do %>\n    <% c.with_menu_item_divider %>\n    <% c.with_menu_item_link_to \"My Profile\", profile_path(Current.user) %>\n    <% c.with_menu_item_link_to \"Settings\", settings_path %>\n    <% c.with_menu_item_button_to t(\"sign_out\"), Current.session, method: :delete, id: :sign_out %>\n\n    <% if Current.user&.admin? %>\n      <% c.with_menu_item_link_to \"Suggestions\", admin_suggestions_path %>\n      <% c.with_menu_item_link_to t(\"admin\"), avo_path %>\n    <% end %>\n  <% end %>\n\n  <% signed_out do %>\n    <% c.with_menu_item_divider %>\n    <% c.with_menu_item_link_to \"Sign in\", new_session_path(redirect_to: request.fullpath), data: {turbo_frame: \"modal\"} %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/navbar/_link.html.erb",
    "content": "<% active = current_page?(path) %>\n\n<%= content_tag :li, class: class_names(\"whitespace-nowrap\", active: active) do %>\n  <%= link_to link_title, path %>\n  <%= content_tag :div, \"\" %>\n<% end %>\n"
  },
  {
    "path": "app/views/shared/navbar/_search_bar.html.erb",
    "content": "<div\n  id=\"<%= id %>\"\n  class=\"flex items-center gap-2 cursor-pointer\"\n  data-controller=\"event tooltip\"\n  data-action=\"click->event#dispatchEvent\"\n  data-event-name-value=\"spotlight\"\n  data-tooltip-content-value=\"⌘ k\">\n  <%= fa(\"magnifying-glass\", size: :sm, style: :regular) %>\n  <div class=\"sr-only\">Search</div>\n</div>\n"
  },
  {
    "path": "app/views/speakers/_card.html.erb",
    "content": "<%= link_to profile_path(speaker), class: \"w-48 sm:w-64 flex relative bg-white rounded-xl border h-full\", data: {turbo_frame: \"_top\"} do %>\n  <div class=\"card card-compact w-full pt-6\">\n    <figure class=\"flex justify-center\">\n      <%= ui_avatar(speaker, size_class: \"w-32 sm:w-40\", size: :lg) %>\n    </figure>\n    <div class=\"card-body items-center text-center pt-4 px-0 justify-center\">\n      <h3 class=\"text-xl font-semibold text-slate-700\"><%= speaker.name %></h3>\n      <div class=\"text-slate-600\"><%= pluralize(speaker.talks_count, \"talk\") %></div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/speakers/_speaker.html.erb",
    "content": "<%= link_to profile_path(speaker), id: dom_id(speaker), class: \"flex justify-between items-center\" do %>\n  <div class=\"flex items-center gap-3\">\n    <span><%= sanitize speaker.name_with_snippet %></span>\n  </div>\n\n  <%= ui_badge(speaker.talks_count, kind: :secondary, outline: true, size: :lg, class: \"min-w-10\") %>\n<% end %>\n"
  },
  {
    "path": "app/views/speakers/_speaker.json.jbuilder",
    "content": "json.cache! speaker do\n  json.extract! speaker, :name, :twitter, :github_handle, :bio, :website, :slug, :talks_count, :canonical_slug, :updated_at, :created_at\nend\n"
  },
  {
    "path": "app/views/speakers/index.html.erb",
    "content": "<div class=\"container py-8 hotwire-native:py-3\">\n  <h1 class=\"title hotwire-native:hidden\">\n    <%= title \"Speakers\" %>\n    <% if params[:s].present? %>\n      : search results for \"<%= params[:s] %>\"\n    <% end %>\n  </h1>\n  <div class=\"flex flex-wrap w-full justify-between py-8 hotwire-native:hidden gap-1\">\n    <% (\"a\"..\"z\").each do |letter| %>\n      <%= link_to speakers_path(letter: letter), class: class_names(\"flex items-center justify-center w-10 text-gray-500 rounded hover:bg-brand-lighter border\", \"bg-brand-lighter\": letter == params[:letter]) do %>\n        <%= letter.upcase %>\n      <% end %>\n    <% end %>\n      <%= link_to speakers_path, class: class_names(\"flex items-center justify-center w-10 text-gray-500 rounded hover:bg-brand-lighter border\", \"bg-brand-lighter\": params[:letter].blank?) do %>\n        all\n    <% end %>\n  </div>\n  <div id=\"speakers\" class=\"hotwire-native:mt-3 grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-8 lg:gap-x-12 gap-y-2 min-w-full\">\n    <%# we need special cache key for speakers because @speakers is paginated %>\n    <% cache [@speakers.except(:order).pluck(:id, :updated_at).hash] do %>\n      <%= render partial: \"speakers/speaker\", collection: @speakers, as: :speaker, cached: true %>\n    <% end %>\n  </div>\n  <% if @pagy.next.present? %>\n    <%= turbo_frame_tag :pagination,\n          data: {\n            controller: \"lazy-loading\",\n            lazy_loading_src_value: speakers_path(letter: params[:letter], s: params[:s], page: @pagy.next, format: :turbo_stream)\n          } %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/speakers/index.json.jbuilder",
    "content": "json.speakers do\n  json.array! @speakers do |speaker|\n    json.partial! \"speakers/speaker\", speaker: speaker\n  end\nend\n\njson.pagination do\n  json.current_page @pagy.page\n  json.pages @pagy.pages\n  json.next_page @pagy.next\n  json.prev_page @pagy.prev\n  json.total_items @pagy.count\n  json.items_per_page @pagy.limit\nend\n"
  },
  {
    "path": "app/views/speakers/index.turbo_stream.erb",
    "content": "<%= turbo_stream.append \"speakers\" do %>\n  <% cache @speakers do %>\n    <%= render partial: \"speakers/speaker\", collection: @speakers, as: :speaker, cached: true %>\n  <% end %>\n<% end %>\n\n<% if @pagy.next.present? %>\n  <%= turbo_stream.replace \"pagination\" do %>\n    <%= turbo_frame_tag :pagination,\n                        data: {\n                          controller: \"lazy-loading\",\n                          lazy_loading_src_value: speakers_path(letter: params[:letter], s: params[:s], page: @pagy.next, format: :turbo_stream)\n                        } %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/speakers/show.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<div class=\"container py-8\">\n  <div class=\"flex items-start flex-wrap sm:flex-nowrap gap-8 w-full\">\n    <div class=\"w-full sm:w-1/3\">\n      <h1 class=\"mb-4 flex gap-2\" style=\"view-transition-name: title\">\n        <%= @speaker.name %>\n\n        <% if @speaker.pronouns.present? && [\"dont_specify\", \"not_specified\"].exclude?(@speaker.pronouns_type) %>\n          <span class=\"text-sm content-center text-[#737373]\">(<%= @speaker.pronouns %>)</span>\n        <% end %>\n      </h1>\n\n      <% if @speaker.github.present? %>\n        <div class=\"relative w-fit\">\n          <%= image_tag @speaker.github_avatar_url(size: 200),\n                class: \"rounded-full mb-4\",\n                height: 200,\n                width: 200,\n                alt: \"GitHub picture profile of #{@speaker.github}\",\n                loading: :lazy %>\n\n          <% if @speaker.verified? %>\n            <div class=\"absolute right-0 top-0 badge badge-accent\">Verified</div>\n          <% end %>\n        </div>\n      <% end %>\n      <%= render \"speakers/about\", speaker: @speaker %>\n      <%= render \"speakers/actions\", speaker: @speaker %>\n    </div>\n\n    <div class=\"w-full\">\n      <div id=\"talks\" class=\"min-w-full grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 h-full sm:p-4\">\n        <%= render partial: \"talks/card\",\n              collection: @talks,\n              as: :talk,\n              locals: {\n                favoritable: true,\n                user_favorite_talks_ids: @user_favorite_talks_ids,\n                back_to: request.fullpath,\n                back_to_title: @speaker.name\n              } %>\n      </div>\n    </div>\n  </div>\n\n  <%= turbo_stream_from @speaker %>\n</div>\n"
  },
  {
    "path": "app/views/sponsors/missing/index.html.erb",
    "content": "<div class=\"container py-8\">\n  <div class=\"flex items-center mb-8\">\n    <%= link_to @back_path, class: \"mr-4 text-gray-500 hover:text-gray-700\" do %>\n      <svg class=\"w-6 h-6\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\"></path>\n      </svg>\n    <% end %>\n    <h1 class=\"title\">\n      <%= title \"Conferences Missing Sponsor Data\" %>\n    </h1>\n  </div>\n\n  <div class=\"bg-blue-50 border border-blue-200 rounded-lg p-6 mb-8\">\n    <div class=\"flex items-start\">\n      <%= fa(\"question-circle\", size: :md, class: \"fill-blue-600 mt-0.5 mr-4 flex-shrink-0\") %>\n      <div>\n        <h2 class=\"font-semibold text-blue-800 text-lg mb-2\">Help Complete Our Database</h2>\n        <p class=\"text-blue-700 mb-4\">\n          The conferences listed below are missing sponsor information. If you have knowledge about\n          who sponsored these events, please consider contributing this data to help make RubyEvents.org\n          more complete.\n        </p>\n        <div class=\"bg-white border border-blue-200 rounded p-4\">\n          <h3 class=\"font-semibold text-blue-800 mb-2\">How to contribute sponsor data:</h3>\n          <ul class=\"text-sm text-blue-700 space-y-1\">\n            <li>• Research the event website, program, or recorded videos</li>\n            <li>• Look for sponsor logos and acknowledgments</li>\n            <li>• <a href=\"https://github.com/rubyevents/rubyevents/blob/main/docs/ADDING_SPONSORS.md\" class=\"underline hover:text-blue-900\" target=\"_blank\">Follow our contribution guide</a> to submit the data</li>\n            <li>• Create a pull request with the sponsor information</li>\n          </ul>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <% if @events_by_year.any? %>\n    <div class=\"space-y-8\">\n      <% @events_by_year.each do |year, events| %>\n        <div>\n          <h2 class=\"text-2xl font-bold text-gray-900 mb-4 border-b border-gray-200 pb-2\">\n            <%= year %>\n            <span class=\"text-base font-normal text-gray-500 ml-2\">(<%= pluralize(events.size, \"event\") %>)</span>\n          </h2>\n\n          <div class=\"grid gap-4 md:grid-cols-2 lg:grid-cols-3\">\n            <% events.each do |event| %>\n              <%= link_to event_path(event), class: \"block bg-white border border-gray-200 rounded-lg p-4 hover:shadow-md transition-shadow hover:border-gray-300\" do %>\n                <div class=\"flex items-start justify-between\">\n                  <div class=\"flex-1\">\n                    <h3 class=\"font-semibold text-gray-900 mb-1 hover:text-brand-600\">\n                      <%= event.name %>\n                    </h3>\n                    <p class=\"text-sm text-gray-600 mb-2\"><%= event.series.name %></p>\n                    <div class=\"flex items-center text-xs text-gray-500\">\n                      <%= fa(\"clock\", size: :xs, class: \"fill-gray-400 mr-1\") %>\n                      <%= event.start_date&.strftime(\"%B %Y\") || \"Date unknown\" %>\n                    </div>\n                    <% if event.city.present? %>\n                      <div class=\"flex items-center text-xs text-gray-500 mt-1\">\n                        <svg class=\"w-3 h-3 mr-1 fill-gray-400\" viewBox=\"0 0 24 24\">\n                          <path d=\"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z\" />\n                        </svg>\n                        <%= [event.city, event.country_code].compact.join(\", \") %>\n                      </div>\n                    <% end %>\n                  </div>\n                  <%= fa(\"question-circle\", size: :sm, class: \"fill-red-500 ml-2 flex-shrink-0\") %>\n                </div>\n              <% end %>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    </div>\n\n    <div class=\"mt-12 text-center\">\n      <p class=\"text-gray-600 mb-4\">\n        Total conferences missing sponsor data: <strong><%= @events_without_sponsors.size %></strong>\n      </p>\n      <p class=\"text-sm text-gray-500\">\n        Last updated: <%= Date.current.strftime(\"%B %d, %Y\") %>\n      </p>\n    </div>\n  <% else %>\n    <div class=\"text-center py-12\">\n      <div class=\"text-6xl mb-4\">🎉</div>\n      <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">All Conferences Have Sponsor Data!</h2>\n      <p class=\"text-gray-600\">\n        Great news! All conferences in our database have sponsor information.\n      </p>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/spotlight/events/_event.html.erb",
    "content": "<%= link_to event_path(event), target: \"_top\", id: dom_id(event), role: \"option\", class: \"w-full flex items-center gap-4\", style: \"view-transition-name: #{dom_id(event, :search_result)}\" do %>\n  <div class=\"flex items-center gap-2\">\n    <%= image_tag image_path(event.avatar_image_path), class: \"size-8 rounded-full skeleton\", loading: \"lazy\", height: 200, width: 200 %>\n    <span class=\"event-name\"><%= event.name %></span>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/events/index.turbo_stream.erb",
    "content": "<%= turbo_stream.update \"events_search_results\", method: \"morph\" do %>\n  <div class=\"flex items-center flex-wrap gap-2 py-4\">\n    <h2><%= search_query.present? ? \"Events\" : \"Latest Events\" %></h2>\n    <% if @events.size.positive? && total_count.present? %>\n      <span class=\"text-sm text-gray-500\">(<%= total_count %> <%= \"event\".pluralize(total_count) %>)</span>\n      <%= link_to archive_events_path(s: search_query), class: \"link text-sm text-gray-500\", target: \"_top\" do %>\n        see all\n      <% end %>\n    <% end %>\n    <% if Rails.env.development? && search_backend == :sqlite_fts %>\n      <span class=\"badge badge-xs badge-warning\">SQLite FTS</span>\n    <% elsif Rails.env.development? && search_backend == :typesense %>\n      <span class=\"badge badge-xs badge-primary\">Typesense</span>\n    <% end %>\n  </div>\n\n  <div class=\"flex flex-col gap-2\">\n    <% cache @events do %>\n      <%= render partial: \"spotlight/events/event\", collection: @events, as: :event %>\n    <% end %>\n\n    <% if search_query.present? %>\n      <div class=\"hidden only:block\">No events found for <strong><%= search_query %></strong></div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/kinds/index.turbo_stream.erb",
    "content": "<%= turbo_stream.replace \"kinds_search_results\" do %>\n  <div\n    id=\"kinds_search_results\"\n    class=\"<%= @kinds.any? ? 'pb-4 border-b' : 'hidden' %>\"\n    data-spotlight-search-target=\"kindsSearchResults\">\n\n    <% if @kinds.any? %>\n      <% talk_kinds = @kinds.select { |k| k[:category] == \"talk\" } %>\n      <% event_kinds = @kinds.select { |k| k[:category] == \"event\" } %>\n\n      <% if talk_kinds.any? %>\n        <div class=\"flex items-center flex-wrap gap-2 py-2\">\n          <span class=\"text-sm font-medium text-gray-600\">Talk Types</span>\n          <span class=\"text-xs text-gray-400\">(<%= talk_kinds.size %>)</span>\n        </div>\n\n        <div class=\"flex flex-wrap gap-2 mb-3\">\n          <% talk_kinds.each do |kind| %>\n            <%= link_to talks_path(kind: kind[:slug]), target: \"_top\", class: \"badge badge-ghost hover:bg-gray-200 px-3 py-3 text-sm gap-2\" do %>\n              <span><%= kind[:name] %></span>\n              <span class=\"text-xs text-gray-400\">(<%= pluralize(kind[:count], \"talk\") %>)</span>\n            <% end %>\n          <% end %>\n        </div>\n      <% end %>\n\n      <% if event_kinds.any? %>\n        <div class=\"flex items-center flex-wrap gap-2 py-2\">\n          <span class=\"text-sm font-medium text-gray-600\">Event Types</span>\n          <span class=\"text-xs text-gray-400\">(<%= event_kinds.size %>)</span>\n        </div>\n\n        <div class=\"flex flex-wrap gap-2\">\n          <% event_kinds.each do |kind| %>\n            <%= link_to archive_events_path(kind: kind[:slug]), target: \"_top\", class: \"badge badge-ghost hover:bg-gray-200 px-3 py-3 text-sm gap-2\" do %>\n              <span><%= kind[:name] %></span>\n              <span class=\"text-xs text-gray-400\">(<%= pluralize(kind[:count], \"event\") %>)</span>\n            <% end %>\n          <% end %>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/languages/index.turbo_stream.erb",
    "content": "<%= turbo_stream.replace \"languages_search_results\" do %>\n  <div\n    id=\"languages_search_results\"\n    class=\"<%= @languages.any? ? 'pb-4 border-b' : 'hidden' %>\"\n    data-spotlight-search-target=\"languagesSearchResults\">\n    <% if @languages.any? %>\n      <div class=\"flex items-center flex-wrap gap-2 py-2\">\n        <span class=\"text-sm font-medium text-gray-600\">Languages</span>\n        <span class=\"text-xs text-gray-400\">(<%= total_count %>)</span>\n      </div>\n      <div class=\"flex flex-col gap-1\">\n        <% @languages.each do |language| %>\n          <%= link_to talks_path(language: language[:code]), target: \"_top\", class: \"flex items-center justify-between gap-4 py-2 px-2 rounded hover:bg-gray-100 group\" do %>\n            <div class=\"flex items-center gap-3\">\n              <span class=\"text-lg\"><%= language[:emoji_flag] %></span>\n              <span class=\"font-medium\"><%= language[:name] %></span>\n            </div>\n            <div class=\"flex items-center gap-4 text-sm text-gray-500\">\n              <span class=\"text-xs\">(<%= pluralize(language[:talk_count], \"talk\") %>)</span>\n            </div>\n          <% end %>\n        <% end %>\n      </div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/locations/index.turbo_stream.erb",
    "content": "<%= turbo_stream.replace \"locations_search_results\" do %>\n  <div\n    id=\"locations_search_results\"\n    class=\"<%= (@locations.any? || @geocoded_locations&.any?) ? \"pb-4 border-b\" : \"hidden\" %>\"\n    data-spotlight-search-target=\"locationsSearchResults\">\n    <% if @locations.any? %>\n      <div class=\"flex items-center flex-wrap gap-2 py-2\">\n        <span class=\"text-sm font-medium text-gray-600\">Locations</span>\n        <span class=\"text-xs text-gray-400\">(<%= total_count %>)</span>\n      </div>\n      <div class=\"flex flex-col gap-1\">\n        <% @locations.each do |location| %>\n          <% path = case location[:type].to_sym\n                    when :online then online_path\n                    when :continent then continent_path(location[:slug])\n                    when :country then country_path(location[:slug])\n                    when :state then state_path(state_alpha2: location[:country_code].downcase, state_slug: location[:slug])\n                    when :uk_nation then country_path(location[:slug])\n                    when :city then city_by_country_path(alpha2: location[:country_code].downcase, city: location[:slug])\n                    end\n             type_label = case location[:type].to_sym\n                          when :online then \"Virtual\"\n                          when :continent then \"Continent\"\n                          when :country then \"Country\"\n                          when :state then location[:country_name]\n                          when :uk_nation then \"United Kingdom\"\n                          when :city then location[:country_name]\n                          end\n          %>\n          <%= link_to path, target: \"_top\", class: \"flex items-center justify-between gap-4 py-2 px-2 rounded hover:bg-gray-100 group\" do %>\n            <div class=\"flex items-center gap-3\">\n              <span class=\"text-lg\"><%= location[:emoji_flag] %></span>\n              <span class=\"font-medium\"><%= location[:name] %></span>\n            </div>\n            <div class=\"flex items-center gap-4 text-sm text-gray-500\">\n              <span><%= type_label %></span>\n              <span class=\"text-xs\">(<%= pluralize(location[:event_count], \"event\") %>)</span>\n            </div>\n          <% end %>\n        <% end %>\n      </div>\n    <% elsif @geocoded_locations.present? && @geocoded_locations.any? %>\n      <div class=\"flex items-center flex-wrap gap-2 py-2\">\n        <span class=\"text-sm font-medium text-gray-600\">Locations</span>\n      </div>\n      <div class=\"flex flex-col gap-1\">\n        <% @geocoded_locations.each do |geocoded_location| %>\n          <% location_display = geocoded_location[:country].present? ? \"#{geocoded_location[:name]}, #{geocoded_location[:country]}\" : geocoded_location[:name] %>\n          <%= link_to coordinates_path(coordinates: \"#{geocoded_location[:latitude]},#{geocoded_location[:longitude]}\"),\n                target: \"_top\",\n                class: \"flex items-center justify-between gap-4 py-2 px-2 rounded hover:bg-gray-100 group\" do %>\n            <div class=\"flex items-center gap-3\">\n              <span class=\"text-lg\">📍</span>\n              <span class=\"font-medium\">Explore <%= location_display %></span>\n            </div>\n            <div class=\"flex items-center gap-4 text-sm text-gray-500\">\n              <span>View nearby events</span>\n            </div>\n          <% end %>\n        <% end %>\n      </div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/organizations/index.turbo_stream.erb",
    "content": "<%= turbo_stream.replace \"organizations_search_results\" do %>\n  <div\n    id=\"organizations_search_results\"\n    class=\"<%= @organizations.any? ? 'pb-4 border-b' : 'hidden' %>\"\n    data-spotlight-search-target=\"organizationsSearchResults\">\n    <% if @organizations.any? %>\n      <div class=\"flex items-center flex-wrap gap-2 py-2\">\n        <span class=\"text-sm font-medium text-gray-600\">Organizations</span>\n        <span class=\"text-xs text-gray-400\">(<%= total_count %>)</span>\n      </div>\n      <div class=\"flex flex-wrap gap-2\">\n        <% @organizations.each do |organization| %>\n          <%= link_to organization_path(organization), target: \"_top\", class: \"badge badge-ghost hover:bg-gray-200 px-3 py-3 text-sm gap-1\" do %>\n            <%= organization.name %>\n          <% end %>\n        <% end %>\n      </div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/series/index.turbo_stream.erb",
    "content": "<%= turbo_stream.replace \"series_search_results\" do %>\n  <div\n    id=\"series_search_results\"\n    class=\"<%= @series.any? ? 'pb-4 border-b' : 'hidden' %>\"\n    data-spotlight-search-target=\"seriesSearchResults\">\n    <% if @series.any? %>\n      <div class=\"flex items-center flex-wrap gap-2 py-2\">\n        <span class=\"text-sm font-medium text-gray-600\">Series</span>\n        <span class=\"text-xs text-gray-400\">(<%= total_count %>)</span>\n      </div>\n      <div class=\"flex flex-wrap gap-2\">\n        <% @series.each do |series| %>\n          <%= link_to series_path(series), target: \"_top\", class: \"badge badge-ghost hover:bg-gray-200 px-3 py-3 text-sm gap-1\" do %>\n            <%= series.name %>\n          <% end %>\n        <% end %>\n      </div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/speakers/_speaker.html.erb",
    "content": "<%= link_to profile_path(speaker), target: \"_top\", id: dom_id(speaker), role: \"option\", class: \"w-full flex items-center gap-4\", style: \"view-transition-name: #{dom_id(speaker, :search_result)}\" do %>\n  <div class=\"avatar placeholder\">\n    <%= ui_avatar(speaker, size: :sm) %>\n  </div>\n  <%= speaker.name %>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/speakers/index.turbo_stream.erb",
    "content": "<%= turbo_stream.update \"speakers_search_results\", method: \"morph\" do %>\n  <div class=\"flex items-center flex-wrap gap-2 py-4\">\n    <h2><%= search_query.present? ? \"Speakers\" : \"Top Speakers\" %></h2>\n    <% if @speakers.size.positive? && total_count.present? %>\n      <span class=\"text-sm text-gray-500\">(<%= total_count %> <%= \"speaker\".pluralize(total_count) %>)</span>\n      <%= link_to speakers_path(s: search_query), class: \"link text-sm text-gray-500\", target: \"_top\" do %>\n        see all\n      <% end %>\n    <% end %>\n    <% if Rails.env.development? && search_backend == :sqlite_fts %>\n      <span class=\"badge badge-xs badge-warning\">SQLite FTS</span>\n    <% elsif Rails.env.development? && search_backend == :typesense %>\n      <span class=\"badge badge-xs badge-primary\">Typesense</span>\n    <% end %>\n  </div>\n\n  <div class=\"flex flex-col gap-2\">\n    <% cache @speakers do %>\n      <%= render partial: \"spotlight/speakers/speaker\", collection: @speakers, as: :speaker %>\n    <% end %>\n\n    <% if search_query.present? %>\n      <div class=\"hidden only:block\">No speakers found for <strong><%= search_query %></strong></div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/talks/_talk.html.erb",
    "content": "<%= link_to talk_path(talk), target: \"_top\", id: dom_id(talk), role: \"option\", class: \"w-full flex items-center gap-4\", style: \"view-transition-name: #{dom_id(talk, :search_result)}\" do %>\n  <div class=\"hidden md:flex aspect-video shrink-0 relative w-20\">\n    <%= image_tag talk.thumbnail_sm, srcset: [\"#{talk.thumbnail_sm} 2x\"], id: dom_id(talk), class: \"w-full h-auto object-cover border rounded skeleton\", loading: :lazy, height: 180, width: 320 %>\n  </div>\n\n  <div class=\"flex flex-col gap-1 text-sm\">\n    <%= content_tag :div, class: \"\" do %>\n      <%= content_tag :div, talk.title, class: \"font-regular line-clamp-2\" %>\n    <% end %>\n\n    <div class=\"flex items-start gap-2 font-light\">\n      <div class=\"line-clamp-1 text-gray-500\">\n        <%= talk.speakers.map(&:name).to_sentence %>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/talks/index.turbo_stream.erb",
    "content": "<%= turbo_stream.update \"talks_search_results\", method: \"morph\" do %>\n  <div class=\"flex items-center flex-wrap gap-2 py-4\">\n    <h2><%= search_query.present? ? \"Talks\" : \"Recent Talks\" %></h2>\n    <% if @talks.size.positive? && total_count.present? %>\n      <span class=\"text-sm text-gray-500\">(<%= total_count %> <%= \"talk\".pluralize(total_count) %>)</span>\n      <%= link_to talks_path(s: search_query), class: \"link text-sm text-gray-500\", target: \"_top\" do %>\n        see all\n      <% end %>\n    <% end %>\n\n    <% if Rails.env.development? && search_backend == :sqlite_fts %>\n      <span class=\"badge badge-xs badge-warning\">SQLite FTS</span>\n    <% elsif Rails.env.development? && search_backend == :typesense %>\n      <span class=\"badge badge-xs badge-primary\">Typesense</span>\n    <% end %>\n  </div>\n\n  <div class=\"flex flex-col gap-2\">\n    <% cache @talks do %>\n      <%= render partial: \"spotlight/talks/talk\", collection: @talks, as: :talk %>\n    <% end %>\n\n    <% if search_query.present? %>\n      <div class=\"hidden only:block\">No talks found for <strong><%= search_query %></strong></div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/spotlight/topics/index.turbo_stream.erb",
    "content": "<%= turbo_stream.replace \"topics_search_results\" do %>\n  <div\n    id=\"topics_search_results\"\n    class=\"<%= @topics.any? ? 'pb-4 border-b' : 'hidden' %>\"\n    data-spotlight-search-target=\"topicsSearchResults\">\n    <% if @topics.any? %>\n      <div class=\"flex items-center flex-wrap gap-2 py-2\">\n        <span class=\"text-sm font-medium text-gray-600\">Topics</span>\n        <span class=\"text-xs text-gray-400\">(<%= total_count %>)</span>\n      </div>\n      <div class=\"flex flex-wrap gap-2\">\n        <% @topics.each do |topic| %>\n          <%= link_to topic_path(topic), target: \"_top\", class: \"badge badge-ghost hover:bg-gray-200 px-3 py-3 text-sm gap-1\" do %>\n            #<%= topic.name.parameterize %>\n            <span class=\"text-xs text-gray-400\">(<%= pluralize(topic.talks_count, \"talk\") %>)</span>\n          <% end %>\n        <% end %>\n      </div>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/stamps/index.html.erb",
    "content": "<style>\n  .passport-stamp-card {\n    background: linear-gradient(45deg, #faf8f4 0%, #f5f3ef 100%);\n    position: relative;\n  }\n\n</style>\n\n<div class=\"container mx-auto px-4 py-8\">\n  <div class=\"max-w-7xl mx-auto\">\n    <h1 class=\"text-4xl font-bold mb-8\">Ruby Passport Stamps</h1>\n\n    <% if @stamps.empty? %>\n      <div class=\"alert alert-info\">\n        <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" class=\"stroke-current shrink-0 w-6 h-6\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"></path></svg>\n        <span>No passport stamps available yet. Run <code>rake export_stamps</code> to generate them from the Sketch file.</span>\n      </div>\n    <% else %>\n      <div class=\"mb-8 text-gray-600\">\n        <p>Collect stamps from Ruby conferences around the world! <%= @stamps.size %> stamps available.</p>\n      </div>\n\n      <% if @missing_stamp_countries.present? %>\n        <div class=\"mb-8 p-4 bg-yellow-50 border border-yellow-200 rounded-lg\">\n          <h3 class=\"text-lg font-semibold mb-2 text-yellow-800\">Countries with events but no stamps:</h3>\n          <div class=\"flex flex-wrap gap-2\">\n            <% @missing_stamp_countries.each do |country| %>\n              <div class=\"badge badge-warning badge-outline\">\n                <%= country.name %> (<%= country.alpha2 %>)\n              </div>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n\n      <% if @event_stamps.any? %>\n        <div class=\"mb-12\">\n          <h2 class=\"text-2xl font-semibold mb-6 text-gray-800\">Event Stamps</h2>\n\n          <div class=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-6\">\n            <% @event_stamps.each do |stamp| %>\n              <div class=\"card bg-base-100 border border-gray-200 hover:border-gray-400 transition-colors duration-300 passport-stamp-card\">\n                <%= ui_stamp(stamp, rotate: true, size: :xl, class: \"mx-auto p-4\", zoom_effect: true) %>\n                <div class=\"card-body items-center text-center p-4\">\n                  <h3 class=\"card-title text-sm\">\n                    <%= stamp.name %>\n                  </h3>\n                  <% if stamp.event %>\n                    <div class=\"card-actions mt-2\">\n                      <%= link_to \"View Event\",\n                            event_path(stamp.event),\n                            class: \"btn btn-xs btn-secondary\" %>\n                    </div>\n                  <% end %>\n                </div>\n              </div>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n\n      <% @stamps_by_continent.each do |continent, stamps| %>\n        <div class=\"mb-12\">\n          <h2 class=\"text-2xl font-semibold mb-6 text-gray-800\"><%= continent || \"Unknown\" %></h2>\n\n          <div class=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6 gap-6\">\n            <% stamps.each do |stamp| %>\n              <div class=\"card bg-base-100 border border-gray-200 hover:border-gray-400 transition-colors duration-300 passport-stamp-card\">\n                <%= ui_stamp(stamp, rotate: true, size: :xl, class: \"mx-auto p-4\", zoom_effect: true) %>\n                <div class=\"card-body items-center text-center p-4\">\n                  <h3 class=\"card-title text-sm\">\n                    <%= stamp.name %>\n                  </h3>\n                  <% if stamp.has_country? %>\n                    <div class=\"card-actions mt-2\">\n                      <%= link_to \"View Events\",\n                            stamp.country.path,\n                            class: \"btn btn-xs btn-primary\" %>\n                    </div>\n                  <% end %>\n                </div>\n              </div>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/states/cities/index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% title \"Cities in #{@state.name}\" %>\n\n<%= render \"shared/location_header\",\n      name: @state.name,\n      subtitle: @state.to_location.to_text,\n      flag_code: @country.alpha2,\n      stats: \"#{pluralize(@cities.size, \"city\")} with Ruby events in #{@state.name}\",\n      location: @state %>\n\n<%= render \"shared/location_navigation\", location: @state, current_tab: \"cities\", show_cities: true, show_stamps: true %>\n\n<div class=\"container py-8\">\n  <div class=\"flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6\">\n    <div class=\"flex items-center gap-3\">\n      <h2 class=\"text-xl font-bold text-gray-900\">Cities in <%= @state.name %></h2>\n      <%= ui_badge(@cities.size, kind: :secondary, outline: true) %>\n    </div>\n\n    <div class=\"flex items-center gap-2\">\n      <span class=\"text-sm text-gray-500\">Sort:</span>\n\n      <%= link_to \"Events\", state_cities_path(state_alpha2: @country.code, state_slug: @state.slug, sort: \"events\"), class: \"btn btn-sm #{(@sort == \"events\") ? \"btn-primary\" : \"btn-ghost\"}\" %>\n      <%= link_to \"A-Z\", state_cities_path(state_alpha2: @country.code, state_slug: @state.slug, sort: \"name\"), class: \"btn btn-sm #{(@sort == \"name\") ? \"btn-primary\" : \"btn-ghost\"}\" %>\n    </div>\n  </div>\n\n  <% if @cities.any? %>\n    <div class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4\">\n      <% @cities.each do |city| %>\n        <%= link_to city.path, class: \"flex flex-col p-4 bg-white rounded-xl border hover:border-gray-400 transition-colors\" do %>\n          <div class=\"flex items-center justify-between mb-2\">\n            <div class=\"flex items-center gap-2\">\n              <span class=\"font-semibold text-gray-900\"><%= city.name %></span>\n            </div>\n\n            <%= ui_badge(city.events_count, kind: :secondary, outline: true, size: :sm) %>\n          </div>\n\n          <div class=\"text-sm text-gray-500\">\n            <%= pluralize(city.events_count, \"event\") %>\n          </div>\n\n          <% if city.events.any? %>\n            <div class=\"flex -space-x-2 mt-3\">\n              <% city.events.first(4).each do |event| %>\n                <% if event.avatar_image_path %>\n                  <div class=\"w-8 h-8 rounded overflow-hidden ring-2 ring-white\">\n                    <%= image_tag event.avatar_image_path, alt: event.name, class: \"w-full h-full object-cover\", loading: \"lazy\" %>\n                  </div>\n                <% end %>\n              <% end %>\n            </div>\n          <% end %>\n        <% end %>\n      <% end %>\n    </div>\n  <% else %>\n    <p class=\"text-gray-500 py-8 text-center\">No cities with events found in <%= @state.name %> yet.</p>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/states/country_index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<% title \"States in #{@country.name}\" %>\n\n<%= render \"shared/location_header\",\n      name: @country.name,\n      subtitle: @country.to_location.to_text,\n      flag_code: @country.alpha2,\n      stats: \"#{pluralize(@states.count { |s| s.events.any? || s.users.any? }, \"state\")} with Ruby activity in #{@country.name}\",\n      location: @country %>\n\n<%= render \"shared/location_navigation\", location: @country, current_tab: \"states\", show_cities: true, show_states: true, show_stamps: @country.stamps.any? %>\n\n<div class=\"container py-8\">\n  <div class=\"flex items-center justify-between mb-6\">\n    <h2 class=\"text-xl font-bold text-gray-900\">States in <%= @country.name %></h2>\n    <%= ui_badge(@states.count { |s| s.events.any? || s.users.any? }, kind: :secondary, outline: true) %>\n  </div>\n\n  <div class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4\">\n    <% @states.each do |state| %>\n      <% event_count = state.events.count %>\n      <% user_count = state.users.count %>\n\n      <% next if event_count == 0 && user_count == 0 %>\n\n      <%= link_to state_path(state_alpha2: state.country.code, state_slug: state.slug), class: \"flex flex-col p-4 bg-white rounded-xl border hover:border-gray-400 transition-colors\" do %>\n        <div class=\"flex items-center justify-between mb-2\">\n          <span class=\"font-semibold text-gray-900\"><%= state.name %></span>\n        </div>\n\n        <div class=\"flex gap-4 text-sm text-gray-500\">\n          <% if event_count > 0 %>\n            <span class=\"flex items-center gap-1\">\n              <%= fa(\"calendar\", size: :xs, class: \"text-gray-400\") %>\n              <%= pluralize(event_count, \"event\") %>\n            </span>\n          <% end %>\n\n          <% if user_count > 0 %>\n            <span class=\"flex items-center gap-1\">\n              <%= fa(\"users\", size: :xs, class: \"text-gray-400\") %>\n              <%= pluralize(user_count, \"Rubyist\") %>\n            </span>\n          <% end %>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/states/index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<div class=\"container py-8\">\n  <div class=\"flex items-center justify-between w-full hotwire-native:hidden\">\n    <h1 class=\"title\">\n      <%= title \"States & Territories\" %>\n    </h1>\n\n    <div class=\"flex flex-col gap-3 place-items-center\">\n      <%= ui_button \"View all countries\", url: countries_path, kind: :secondary, size: :sm, class: \"w-full\" %>\n    </div>\n  </div>\n\n  <p class=\"mt-3 md:mt-9 mb-6 text-[#636B74] max-w-[700px]\">\n    Browse Ruby events and community members by state or territory.\n  </p>\n\n  <div class=\"mt-6 grid sm:grid-cols-2 lg:grid-cols-3 gap-6\">\n    <% @countries_with_states.each do |country| %>\n      <%= link_to country_states_path(alpha2: country.code), class: \"card bg-white border hover:shadow-md transition-shadow\" do %>\n        <div class=\"card-body flex-row items-center gap-4\">\n          <span class=\"fi fi-<%= country.code %> text-4xl rounded\"></span>\n          <div>\n            <h2 class=\"card-title text-lg\"><%= country.name %></h2>\n            <p class=\"text-sm text-gray-500\"><%= country.states.count %> states/territories</p>\n          </div>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/states/map/index.html.erb",
    "content": "<%= render \"shared/location_map\",\n      location: @state,\n      layers: @layers || [],\n      time_layers: @time_layers || [],\n      geo_layers: @geo_layers || [],\n      online_events: @online_events || [] %>\n"
  },
  {
    "path": "app/views/states/meetups/index.html.erb",
    "content": "<%= render \"shared/location_meetups\", location: @location, meetups: @meetups %>\n"
  },
  {
    "path": "app/views/states/past/index.html.erb",
    "content": "<%= render \"shared/location_past\",\n      location: @state,\n      events: @events,\n      users: @users,\n      event_map_markers: @event_map_markers,\n      geo_layers: @geo_layers || [],\n      cities: @cities || [] %>\n"
  },
  {
    "path": "app/views/states/show.html.erb",
    "content": "<%= render \"shared/location_show\",\n      location: @state,\n      events: @events,\n      users: @users,\n      stamps: @stamps,\n      event_map_markers: @event_map_markers,\n      geo_layers: @geo_layers || [],\n      cities: @cities || [],\n      country: @country,\n      country_events: @country_events,\n      continent: @continent,\n      continent_events: @continent_events %>\n"
  },
  {
    "path": "app/views/states/stamps/index.html.erb",
    "content": "<%= render \"shared/location_stamps\",\n      location: @state,\n      stamps: @stamps %>\n"
  },
  {
    "path": "app/views/states/users/index.html.erb",
    "content": "<%= render \"shared/location_users\",\n      location: @state,\n      users: @users %>\n"
  },
  {
    "path": "app/views/talks/_card.html.erb",
    "content": "<%# locals: (talk:, user_favorite_talks_ids: [], favoritable: false, back_to: nil, back_to_title: nil, user_watched_talks: [], watched_talks: [], show_remove_from_watched: false) %>\n\n<% language = Language.by_code(talk.language) %>\n<% watched_talk = watched_talks.find { |wt| wt.talk_id == talk.id } || user_watched_talks.find { |wt| wt.talk_id == talk.id } %>\n\n<div\n  class=\"relative w-full bg-white border card card-compact <%= \"talk-all talk-kind-all talk-kind-#{talk.kind} talk-language-all talk-language-#{talk.language}\" %>\"\n  id=\"<%= dom_id talk %>\"\n  data-watched=\"<%= watched_talk&.watched? ? \"true\" : \"false\" %>\">\n  <% if talk.child_talks.size.positive? %>\n    <div\n      class=\"\n        absolute w-[calc(100%-20px)] ml-[10px] bg-gray-300 rounded-xl -mt-4\n      \">&nbsp;</div>\n    <div class=\"absolute w-[calc(100%-10px)] ml-[5px] bg-gray-500 rounded-xl -mt-2\">&nbsp;</div>\n  <% end %>\n\n  <%= link_to talk_path(talk, back_to: back_to, back_to_title: back_to_title), class: \"flex aspect-video overflow-hidden relative group\", data: {action: \"mouseover->preserve-scroll#updateLinkBackToWithScrollPosition\", turbo_frame: \"_top\"} do %>\n    <% if language && language != \"English\" %>\n      <div\n        class=\"\n          absolute top-0 left-0 z-20 flex p-1 px-2 m-3 rounded-full bg-black/15\n          backdrop-blur-md\n        \">\n        <span><%= language_to_emoji(language) %></span>\n        <span class=\"items-center hidden ml-1 text-sm text-white lg:group-hover:flex\"><%= language %></span>\n      </div>\n    <% end %>\n\n    <% if talk.scheduled? || talk.parent_talk&.scheduled? %>\n      <div\n        class=\"\n          absolute top-0 right-0 z-20 flex gap-2 p-2 m-3 rounded-full bg-black/15\n          backdrop-blur-md\n        \">\n        <span class=\"items-center hidden ml-1 text-sm text-white lg:group-hover:flex\">Scheduled</span>\n        <span><%= fa(\"clock\", size: :sm, class: \"fill-white\") %></span>\n      </div>\n    <% end %>\n\n    <% if talk.not_published? || talk.parent_talk&.not_published? %>\n      <div\n        class=\"\n          absolute top-0 right-0 z-20 flex gap-2 p-2 m-3 rounded-full bg-black/15\n          backdrop-blur-md\n        \">\n        <span class=\"items-center hidden ml-1 text-sm text-white lg:group-hover:flex\">Not published</span>\n        <span><%= fa(\"upload\", size: :sm, class: \"fill-white\") %></span>\n      </div>\n    <% end %>\n\n    <% if talk.not_recorded? || talk.parent_talk&.not_recorded? %>\n      <div\n        class=\"\n          absolute top-0 right-0 z-20 flex gap-2 p-2 m-3 rounded-full bg-black/15\n          backdrop-blur-md\n        \">\n        <span class=\"items-center hidden ml-1 text-sm text-white lg:group-hover:flex\">Not recorded</span>\n        <span><%= fa(\"video-slash\", size: :sm, class: \"fill-white\") %></span>\n      </div>\n    <% end %>\n\n    <% if talk.video_unavailable? %>\n      <div\n        class=\"\n          absolute top-0 right-0 z-20 flex gap-2 p-2 m-3 rounded-full bg-black/15\n          backdrop-blur-md\n        \">\n        <span class=\"items-center hidden ml-1 text-sm text-white lg:group-hover:flex\">Unavailable</span>\n        <span><%= fa(\"video-slash\", size: :sm, class: \"fill-white\") %></span>\n      </div>\n    <% end %>\n\n    <% if talk.duration_in_seconds.present? || watched_talk&.watched? %>\n      <div\n        class=\"\n          flex gap-1.5 items-center absolute bottom-0 right-0 z-20 m-3 px-1.5 py-1 bg-black\n          backdrop-blur-md rounded-md text-white text-xs font-normal\n        \">\n        <% if watched_talk&.watched? %>\n          <%= fa(\"circle-check\", size: :xs, style: :solid, class: \"fill-green-400\") %>\n        <% end %>\n        <% if talk.duration_in_seconds.present? %>\n          <%= seconds_to_formatted_duration(talk.duration_in_seconds) %>\n        <% end %>\n      </div>\n    <% end %>\n\n    <% if talk.parent_talk %>\n      <div\n        class=\"\n          absolute bottom-0 left-0 z-20 flex content-center gap-2 p-2 m-3 rounded-full\n          bg-black/15 backdrop-blur-md\n        \">\n        <span><%= fa(\"rectangle-history\", size: :sm, class: \"fill-white\") %></span>\n        <span\n          class=\"\n            items-center hidden gap-1 ml-1 text-xs font-normal text-white\n            lg:group-hover:inline-flex line-clamp-1\n          \">\n          <span class=\"text-nowrap\">Part of</span>\n          <span class=\"text-gray-300 line-clamp-1\"><%= talk.parent_talk.title %></span>\n        </span>\n      </div>\n\n      <% if talk.duration && talk.formatted_duration != \"00:00\" %>\n        <div\n          class=\"\n            flex gap-2 absolute bottom-0 right-0 z-20 m-3 px-1.5 py-1 bg-black\n            backdrop-blur-md rounded-md text-white text-xs font-normal\n          \">\n          <span><%= talk.formatted_duration %></span>\n        </div>\n      <% end %>\n    <% end %>\n\n    <% if talk.child_talks.size.positive? %>\n      <div\n        class=\"\n          flex gap-2 absolute bottom-0 right-0 z-20 m-3 px-1.5 py-1 bg-black\n          backdrop-blur-md rounded-md text-white text-xs font-normal\n        \">\n        <span>contains\n          <%= pluralize(talk.child_talks.size, \"talk\") %></span>\n      </div>\n    <% end %>\n\n    <% if watched_talk&.in_progress? %>\n      <div class=\"absolute bottom-0 left-0 right-0 z-10\">\n        <div class=\"w-full h-1 bg-white/40\">\n          <div class=\"h-1 bg-primary\" style=\"width: <%= watched_talk.progress_percentage.to_s %>%\"></div>\n        </div>\n      </div>\n    <% end %>\n\n    <% if talk.published? && !watched_talk&.watched? && talk.video_available? %>\n      <div\n        class=\"\n          absolute inset-0 z-10 items-center justify-center hidden lg:group-hover:flex\n          bg-black/30 rounded-t-xl\n        \">\n        <div class=\"p-3 bg-gray-500 rounded-full hover:bg-primary\">\n          <%= fa(\"play\", size: :md, class: \"fill-white\") %>\n        </div>\n      </div>\n    <% end %>\n\n    <%= image_tag(\n          talk.thumbnail_lg,\n          srcset: [\"#{talk.thumbnail_lg} 2x\"],\n          id: dom_id(talk),\n          height: 174,\n          width: 310,\n          loading: \"lazy\",\n          alt: \"talk by #{talk.speakers.map(&:name).join(\", \")}: #{talk.title}\",\n          style: \"view-transition-name: #{dom_id(talk, :image)}\",\n          class: class_names(\n            \"w-full object-cover skeleton rounded-t-xl border-b\",\n            talk.thumbnail_classes,\n            \"opacity-50 group-hover:opacity-75 transition-opacity\": watched_talk&.watched?\n          )\n        ) %>\n  <% end %>\n  <div class=\"flex flex-row items-start justify-between gap-2 card-body\">\n    <div class=\"flex flex-col items-start justify-between w-full h-full gap-2\">\n      <div class=\"flex items-start justify-between w-full gap-2\">\n        <%= link_to talk_path(talk, back_to: back_to, back_to_title: back_to_title), data: {action: \"mouseover->preserve-scroll#updateLinkBackToWithScrollPosition\", turbo_frame: \"_top\"} do %>\n          <%= content_tag :h2, class: \"text-sm font-sans font-medium\" do %>\n            <%= sanitize(talk.title_with_snippet, tags: [\"mark\"]) %>\n          <% end %>\n        <% end %>\n      </div>\n      <div class=\"flex items-end justify-between w-full gap-2\">\n        <div class=\"flex flex-col flex-grow w-full text-sm\">\n          <div class=\"flex items-center gap-2 font-light\">\n            <% speakers_count = talk.speakers.size %>\n            <% if speakers_count > 1 %>\n              <%= fa(\"users\", size: :sm, style: :light, class: \"shrink-0 grow-0 my-1\") %>\n            <% elsif speakers_count == 1 %>\n              <%= fa(\"user\", size: :sm, style: :regular, class: \"shrink-0 grow-0 my-1\") %>\n            <% end %>\n\n            <div class=\"line-clamp-1\">\n              <% talk.speakers.each do |speaker| %>\n                <%= link_to speaker.name,\n                      profile_path(speaker),\n                      class: \"link link-ghost\",\n                      data: {\n                        turbo_frame: \"_top\"\n                      } %><% if talk.speakers.last != speaker %>,\n                <% end %>\n              <% end %>\n            </div>\n          </div>\n          <% if talk.event %>\n            <div class=\"flex items-center gap-2 font-light\">\n              <%= fa(\"location-dot\", size: :sm, style: :light, class: \"shrink-0 grow-0\") %>\n              <%= link_to talk.event_name,\n                    talk.event,\n                    class: \"link link-ghost line-clamp-1\",\n                    data: {\n                      turbo_frame: \"_top\"\n                    } %>\n            </div>\n          <% end %>\n        </div>\n\n        <% if talk.slides_url.present? %>\n          <%= ui_tooltip \"Slides available\" do %>\n            <%= fa(\n                  \"presentation-screen\",\n                  style: :regular,\n                  size: :sm,\n                  class: \"shrink-0 grow-0 text-black\"\n                ) %>\n          <% end %>\n        <% end %>\n        <% if favoritable %>\n          <div class=\"self-end hotwire-native:hidden\">\n            <% if default_watch_list %>\n              <% if user_favorite_talks_ids.include?(talk.id) %>\n                <%= button_to watch_list_talk_path(default_watch_list, talk.id), method: :delete, form: {class: \"h-5\"} do %>\n                  <%= fa(\n                        \"bookmark\",\n                        style: :solid,\n                        class: \"text-primary shrink-0 cursor-pointer\",\n                        size: :sm\n                      ) %>\n                <% end %>\n              <% else %>\n                <%= button_to watch_list_talks_path(default_watch_list, talk_id: talk.id), method: :post, form: {class: \"h-5\"} do %>\n                  <%= fa(\n                        \"bookmark\",\n                        class: \"shrink-0 cursor-pointer\",\n                        style: :regular,\n                        size: :sm\n                      ) %>\n                <% end %>\n              <% end %>\n            <% else %>\n              <%= link_to new_session_path(redirect_to: request.fullpath), data: {turbo_frame: \"modal\"} do %>\n                <%= fa(\n                      \"bookmark\",\n                      class: \"shrink-0 cursor-pointer\",\n                      style: :regular,\n                      size: :sm\n                    ) %>\n              <% end %>\n            <% end %>\n          </div>\n        <% end %>\n\n        <% if show_remove_from_watched && watched_talk&.watched? %>\n          <div class=\"self-end\">\n            <%= button_to watched_talk_path(watched_talk), method: :delete,\n                  class: \"btn btn-ghost btn-sm p-1\",\n                  data: {turbo_confirm: \"Mark this talk as unwatched? Your feedback will be deleted.\"} do %>\n              <%= fa(\"xmark\", size: :sm, class: \"text-gray-600 shrink-0\") %>\n            <% end %>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/_card_horizontal.html.erb",
    "content": "<%# locals: (talk:, current_talk: nil, compact: false, turbo_frame: nil, user_watched_talks:, watched_talk: nil, tag: :a, tooltip: true, show_remove_from_watched: false, show_event_name: false) %>\n\n<% active = talk == current_talk %>\n<% watched_talk ||= user_watched_talks.find { |wt| wt.talk_id == talk.id } %>\n\n<% not_recorded = talk.not_recorded? || talk.parent_talk&.not_recorded? %>\n<% not_published = talk.not_published? || talk.parent_talk&.not_published? %>\n<% scheduled = talk.scheduled? || talk.parent_talk&.scheduled? %>\n\n<%= content_tag(\n      tag,\n      href: talk_path(talk),\n      class: class_names(\"w-full flex items-center gap-4 p-2 rounded-lg hover:bg-gray-200 group\", active: active, watched: watched_talk&.watched?, not_recorded: not_recorded, scheduled: scheduled, not_published: not_published),\n      id: dom_id(talk, :card_horizontal),\n      data: {\n        talk_horizontal_card: true,\n        scroll_into_view_target: (active ? \"active\" : nil),\n        talks_navigation_target: \"card\",\n        action: \"talks-navigation#setActive\",\n        turbo_frame: turbo_frame,\n        controller: tooltip ? \"tooltip\" : nil,\n        tooltip_content_value: talk.title\n      }\n    ) do %>\n\n  <div class=\"flex aspect-video shrink-0 relative w-20\">\n    <%= image_tag talk.thumbnail_sm, srcset: [\"#{talk.thumbnail_sm} 2x\"], id: dom_id(talk), class: \"w-full h-auto aspect-video object-cover border rounded #{talk.thumbnail_classes}\", loading: :lazy %>\n\n    <div class=\"absolute inset-0 bg-black/50 justify-center items-center rounded hidden group-[.active]:flex\">\n      <%= fa(\"play\", size: :sm, class: \"fill-white\") %>\n    </div>\n\n    <div class=\"absolute inset-0 bg-black/50 justify-center items-center rounded hidden group-[.watched]:flex group-[.active]:hidden\">\n      <%= fa(\"circle-check\", size: :sm, class: \"fill-white\") %>\n    </div>\n\n    <div class=\"absolute inset-0 bg-black/50 justify-center items-center rounded hidden group-[.not\\_recorded]:flex group-[.watched]:hidden group-[.active]:hidden\">\n      <%= fa(\"video-slash\", size: :sm, class: \"fill-white\") %>\n    </div>\n\n    <div class=\"absolute inset-0 bg-black/50 justify-center items-center rounded hidden group-[.not\\_published]:flex group-[.watched]:hidden group-[.active]:hidden\">\n      <%= fa(\"upload\", size: :sm, class: \"fill-white\") %>\n    </div>\n\n    <div class=\"absolute inset-0 bg-black/50 justify-center items-center rounded hidden group-[.scheduled]:flex group-[.active]:hidden\">\n      <%= fa(\"clock\", size: :sm, class: \"fill-white\") %>\n    </div>\n\n    <% if watched_talk&.in_progress? %>\n      <div class=\"absolute bottom-0 left-0 right-0 z-10\">\n        <div class=\"w-full h-1 bg-white/40\">\n          <div class=\"h-1 bg-primary\" style=\"width: <%= watched_talk.progress_percentage.to_s %>%\"></div>\n        </div>\n      </div>\n    <% end %>\n  </div>\n\n  <div class=\"flex flex-col gap-1 text-sm flex-grow\">\n    <%= content_tag :div do %>\n      <%= content_tag :div, talk.title, class: \"font-regular line-clamp-1\" %>\n    <% end %>\n\n    <div class=\"flex items-start gap-2 font-light\">\n      <div class=\"line-clamp-1 text-gray-500\">\n        <%= talk.speakers.map(&:name).to_sentence %><% if show_event_name && talk.event %> • <%= talk.event.name %><% end %>\n      </div>\n    </div>\n  </div>\n\n  <% if show_remove_from_watched && watched_talk&.watched? %>\n    <div class=\"flex items-center gap-1 shrink-0\">\n      <%= button_to new_talk_watched_talk_path(talk),\n            method: :get,\n            form: {data: {turbo_frame: \"modal\"}},\n            form_class: \"contents\",\n            class: \"btn btn-ghost btn-sm p-1\" do %>\n        <%= fa(\"star\", size: :sm, class: \"text-gray-600 shrink-0\") %>\n      <% end %>\n      <%= button_to watched_talk_path(watched_talk),\n            method: :delete,\n            form_class: \"contents\",\n            class: \"btn btn-ghost btn-sm p-1\",\n            data: {turbo_confirm: \"Mark this talk as unwatched? Your feedback will be deleted.\"} do %>\n        <%= fa(\"xmark\", size: :sm, class: \"text-gray-600 shrink-0\") %>\n      <% end %>\n    </div>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/_card_thumbnail.html.erb",
    "content": "<%# locals: (talk:, watched_talk: nil, back_to: nil, back_to_title: nil, exclude_speaker: nil) %>\n\n<% other_speakers = exclude_speaker ? talk.speakers.reject { |s| s.id == exclude_speaker.id } : [] %>\n<% speaker_text = if exclude_speaker && other_speakers.any?\n     \"with #{other_speakers.map(&:name).to_sentence}\"\n   elsif exclude_speaker\n     nil\n   else\n     talk.speakers.map(&:name).to_sentence.presence\n   end %>\n\n<%= link_to talk_path(talk, back_to: back_to, back_to_title: back_to_title), class: \"block group\", data: {turbo_frame: \"_top\"} do %>\n  <div class=\"aspect-video overflow-hidden relative rounded-xl sm:shadow-md transition-shadow\">\n    <%= image_tag(\n          talk.thumbnail_lg,\n          srcset: [\"#{talk.thumbnail_lg} 2x\"],\n          loading: \"lazy\",\n          alt: talk.title,\n          class: class_names(\"w-full h-full object-cover rounded-xl sm:group-hover:scale-105 transition-transform duration-300\", talk.thumbnail_classes)\n        ) %>\n\n    <div class=\"absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent rounded-xl hidden sm:block\"></div>\n\n    <% if talk.duration_in_seconds.present? %>\n      <div class=\"absolute top-2 right-2 z-20 px-1.5 py-0.5 bg-black/70 backdrop-blur-sm rounded text-white text-xs font-medium\">\n        <% if watched_talk&.in_progress? && watched_talk.progress_seconds.present? %>\n          <% remaining_seconds = talk.duration_in_seconds - watched_talk.progress_seconds %>\n          <% remaining_minutes = (remaining_seconds / 60.0).ceil %>\n          <%= remaining_minutes %> min left\n        <% else %>\n          <%= seconds_to_formatted_duration(talk.duration_in_seconds) %>\n        <% end %>\n      </div>\n    <% end %>\n\n    <div class=\"absolute inset-0 bottom-6 z-10 hidden sm:flex items-center justify-center opacity-0 sm:group-hover:opacity-100 transition-opacity duration-200\">\n      <div class=\"p-2 bg-white/20 backdrop-blur-sm rounded-full sm:group-hover:bg-white/30 sm:group-hover:scale-110 transition-all duration-200\">\n        <%= fa(\"play\", size: :sm, class: \"fill-white\") %>\n      </div>\n    </div>\n\n    <div class=\"absolute bottom-0 left-0 right-0 z-20 p-3 text-white hidden sm:block\">\n      <div class=\"text-sm font-semibold line-clamp-1 leading-tight mb-1\">\n        <%= talk.title %>\n      </div>\n\n      <div class=\"text-xs text-white/80 line-clamp-1\">\n        <% if speaker_text %><%= speaker_text %> • <% end %><%= talk.event&.name %>\n      </div>\n    </div>\n\n    <% if watched_talk&.in_progress? %>\n      <div class=\"absolute bottom-0 left-0 right-0 z-30\">\n        <div class=\"w-full h-1 bg-white/30\">\n          <div class=\"h-1 bg-primary\" style=\"width: <%= watched_talk.progress_percentage.to_s %>%\"></div>\n        </div>\n      </div>\n    <% end %>\n  </div>\n\n  <div class=\"mt-2 sm:hidden\">\n    <div class=\"text-sm font-semibold line-clamp-2 leading-tight\">\n      <%= talk.title %>\n    </div>\n\n    <div class=\"text-xs text-base-content/70 line-clamp-1 mt-0.5\">\n      <% if speaker_text %><%= speaker_text %> • <% end %><%= talk.event&.name %>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/_event.html.erb",
    "content": "<% video_provider ||= nil %>\n\n<%= link_to event, class: \"flex flex-col gap-4 hover:bg-gray-200 transition-bg duration-300 ease-in-out p-2 px-4 rounded-lg items-center\" do %>\n  <div class=\"flex items-center gap-4\">\n    <div class=\"avatar placeholder\">\n      <div class=\"w-12 rounded-full bg-primary text-neutral-content\">\n        <% if event.avatar_image_path.present? %>\n          <%= image_tag image_path(event.avatar_image_path) %>\n        <% else %>\n          <span class=\"text-lg\"><%= event.name.split(\" \").map(&:first).join %></span>\n        <% end %>\n      </div>\n    </div>\n\n    <div>\n      <div class=\"text-xs text-gray-500 line-clamp-1\">\n        <% if video_provider == \"scheduled\" && event.date&.future? %>\n          Scheduled for\n        <% elsif video_provider == \"not_recorded\" || (video_provider == \"scheduled\" && event.date&.past?) %>\n          Held at\n        <% else %>\n          Recorded at\n        <% end %>\n      </div>\n\n      <div class=\"font-semibold text-base line-clamp-1 flex items-center gap-1\">\n        <span><%= event.name %></span>\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/_event_tab.html.erb",
    "content": "<%# locals: (event:) %>\n\n<div class=\"flex flex-col gap-6\">\n  <div class=\"flex items-start gap-4\">\n    <%= image_tag image_path(event.avatar_image_path), class: \"rounded-full border border-gray-200 size-16 flex-shrink-0\", alt: event.name.to_s, loading: :lazy %>\n\n    <div class=\"flex-grow\">\n      <%= link_to event_path(event), class: \"text-xl font-bold hover:underline\" do %>\n        <%= event.name %>\n      <% end %>\n\n      <div class=\"text-sm text-gray-500 mt-1\">\n        <%= event.to_location.to_html %> · <%= event.formatted_dates %>\n      </div>\n\n      <% if event.website.present? %>\n        <div class=\"mt-2\">\n          <%= external_link_to event.website.gsub(%r{^https?://}, \"\").gsub(%r{/$}, \"\"), event.website, class: \"text-sm\" %>\n        </div>\n      <% end %>\n    </div>\n  </div>\n\n  <% if event.description.present? %>\n    <div class=\"prose prose-sm max-w-none\">\n      <%= simple_format event.description %>\n    </div>\n  <% end %>\n\n  <div class=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n    <% talks_count = event.talks.count %>\n    <% speakers_count = event.speakers.count %>\n\n    <div class=\"bg-white border rounded-lg p-4 text-center\">\n      <div class=\"text-2xl font-bold text-primary\"><%= talks_count %></div>\n      <div class=\"text-sm text-gray-500\"><%= \"Talk\".pluralize(talks_count) %></div>\n    </div>\n\n    <div class=\"bg-white border rounded-lg p-4 text-center\">\n      <div class=\"text-2xl font-bold text-primary\"><%= speakers_count %></div>\n      <div class=\"text-sm text-gray-500\"><%= \"Speaker\".pluralize(speakers_count) %></div>\n    </div>\n\n    <% if event.start_date && event.end_date %>\n      <% days_count = (event.end_date - event.start_date).to_i + 1 %>\n\n      <div class=\"bg-white border rounded-lg p-4 text-center\">\n        <div class=\"text-2xl font-bold text-primary\"><%= days_count %></div>\n        <div class=\"text-sm text-gray-500\"><%= \"Day\".pluralize(days_count) %></div>\n      </div>\n    <% end %>\n\n    <% if event.series %>\n      <% editions_count = event.series.events.count %>\n\n      <div class=\"bg-white border rounded-lg p-4 text-center\">\n        <div class=\"text-2xl font-bold text-primary\"><%= editions_count %></div>\n        <div class=\"text-sm text-gray-500\"><%= \"Edition\".pluralize(editions_count) %></div>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/_explore_event.html.erb",
    "content": "<%= link_to event_path(event), id: \"explore-event\", class: \"rounded-xl group bg-gray-100 border hover:bg-gray-200/50 transition-bg duration-300 ease-in-out w-full flex flex-row px-6 py-6 gap-8 mt-4 overflow-hidden\", style: \"background: #{event.static_metadata.featured_background}; color: #{event.static_metadata.featured_color}\", data: {turbo: {permanent: true}} do %>\n  <div class=\"aspect-video hidden md:block\">\n    <%= image_tag image_path(event.featured_image_path), id: dom_id(event, \"explore-card-image\"), alt: \"explore all talks recorded at #{event.name}\", class: \"h-24 aspect-video rounded-xl group-hover:scale-105 transition ease-in-out duration-300\" %>\n  </div>\n\n  <div class=\"flex flex-col w-full flex-1 self-start\">\n    <span class=\"text-lg font-semibold sm:text-md\">\n      Explore all talks\n\n      <% if event.start_date && event.start_date.future? %>\n         scheduled for\n      <% else %>\n        recorded at\n      <% end %>\n\n      <%= event.name %>\n    </span>\n\n    <div class=\"mt-4\">\n      <%= render Ui::AvatarGroupComponent.new(event.speakers.with_github.sample(8), max: 8, size: :md) %>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/_form.html.erb",
    "content": "<%= form_with(model: talk, class: \"contents\") do |form| %>\n  <% if talk.errors.any? %>\n    <div id=\"error_explanation\" class=\"bg-red-50 text-red-500 px-3 py-2 font-medium rounded-lg mt-3\">\n      <h2><%= pluralize(talk.errors.count, \"error\") %> prohibited this talk from being saved:</h2>\n\n      <ul>\n        <% talk.errors.each do |error| %>\n          <li><%= error.full_message %></li>\n        <% end %>\n      </ul>\n    </div>\n  <% end %>\n\n  <div class=\"my-5\">\n    <%= form.label :title %>\n    <%= form.text_field :title, class: \"input input-bordered w-full\" %>\n  </div>\n\n  <div class=\"my-5\">\n    <%= form.label :description %>\n    <%= form.text_area :description, rows: 4, class: \"textarea textarea-bordered w-full\" %>\n  </div>\n\n  <div class=\"my-5\">\n    <%= form.label :date %>\n    <%= form.text_field :date, class: \"input input-bordered w-full\" %>\n  </div>\n\n  <div class=\"my-5\">\n    <%= form.label :slides_url, \"Slides URL\" %>\n    <div class=\"text-sm font-light mb-2\">\n      For optimal experience, please provide the URL of the slides. Speakerdeck.com is recommended as it allows us to embed the slides with a player on the site.\n    </div>\n\n    <%= form.text_field :slides_url, class: \"input input-bordered w-full\" %>\n  </div>\n\n  <div class=\"my-5\">\n    <%= form.label :summarized_using_ai, \"Summarized using AI?\" %>\n    <div class=\"text-sm font-light mb-2\">\n      If this talk's summary was generated by AI, please check this box. A \"Summarized using AI\" badge will be displayed in the summary tab to indicate that the summary was generated using AI.\n    </div>\n\n    <div class=\"flex my-5 gap-2 align-center content-center items-center\">\n      <%= form.check_box :summarized_using_ai, class: \"block h-5 w-5\" %>\n      <%= form.label :summarized_using_ai, %(Show \"Summarized using AI\" badge on summary page), class: \"font-normal\" %>\n    </div>\n  </div>\n\n  <div class=\"my-5\">\n    <%= form.label :summary %>\n    <div class=\"text-sm font-light mb-2\">Markdown supported</div>\n    <%= form.text_area :summary, rows: 10, class: \"textarea textarea-bordered w-full\" %>\n  </div>\n\n  <div class=\"inline\">\n    <%= ui_button \"Suggest modifications\", type: :submit %>\n    <%= ui_button \"Cancel\", url: talk_path(talk), outline: true, role: :button %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/_schedule_tab.html.erb",
    "content": "<%# locals: (talk:, event:) %>\n\n<% schedule = event.schedule %>\n<% days = schedule.days %>\n<% tracks = schedule.tracks %>\n<% all_talks = event.talks_in_running_order(child_talks: false).includes(:speakers).to_a %>\n<% current_track = talk.static_metadata&.track %>\n\n<% current_index = all_talks.index { |t| t.id == talk.id } %>\n\n<% if current_track.present? %>\n  <% same_track_talks = all_talks.select { |t| t.static_metadata&.track == current_track } %>\n  <% track_index = same_track_talks.index { |t| t.id == talk.id } %>\n  <% prev_talk = (track_index && track_index > 0) ? same_track_talks[track_index - 1] : nil %>\n  <% next_talk = track_index ? same_track_talks[track_index + 1] : nil %>\n<% else %>\n  <% prev_talk = (current_index && current_index > 0) ? all_talks[current_index - 1] : nil %>\n  <% next_talk = current_index ? all_talks[current_index + 1] : nil %>\n<% end %>\n\n<% track_info = current_track.present? ? tracks.find { |t| t[\"name\"] == current_track } : nil %>\n<% prev_label = current_track.present? ? \"Previous in #{current_track}\" : \"Previous\" %>\n<% next_label = current_track.present? ? \"Next in #{current_track}\" : \"Next\" %>\n\n<% time_slot_talks = {} %>\n<% slot_talk_index = 0 %>\n\n<% days.each do |day| %>\n  <% day.dig(\"grid\").each do |grid| %>\n    <% next if grid.fetch(\"items\", []).any? %>\n\n    <% time_key = \"#{day.dig(\"date\")}-#{grid[\"start_time\"]}\" %>\n    <% time_slot_talks[time_key] ||= {start_time: grid[\"start_time\"], end_time: grid[\"end_time\"], talks: []} %>\n\n    <% grid[\"slots\"].times do %>\n      <% time_slot_talks[time_key][:talks] << all_talks[slot_talk_index] if all_talks[slot_talk_index] %>\n      <% slot_talk_index += 1 %>\n    <% end %>\n  <% end %>\n<% end %>\n\n<% find_time_for_talk = ->(t) {\n     return nil unless t\n     slot = time_slot_talks.find { |_, s| s[:talks].any? { |st| st&.id == t.id } }\n     slot ? [slot[1][:start_time], slot[1][:end_time]].uniq.join(\" - \") : nil\n   } %>\n\n<% prev_time = find_time_for_talk.call(prev_talk) %>\n<% current_time = find_time_for_talk.call(talk) %>\n<% next_time = find_time_for_talk.call(next_talk) %>\n\n<% parallel_talks = [] %>\n<% current_slot_time = nil %>\n\n<% if current_track.present? %>\n  <% current_time_slot = time_slot_talks.find { |_, slot| slot[:talks].any? { |t| t&.id == talk.id } } %>\n\n  <% if current_time_slot %>\n    <% parallel_talks = current_time_slot[1][:talks].reject { |t| t.nil? || t.id == talk.id } %>\n    <% current_slot_time = [current_time_slot[1][:start_time], current_time_slot[1][:end_time]].uniq.join(\" - \") %>\n  <% end %>\n<% end %>\n\n<% if track_info %>\n  <div class=\"mb-4\">\n    <span class=\"px-3 py-1 rounded text-sm font-medium\" style=\"background: <%= track_info[\"color\"] %>; color: <%= track_info[\"text_color\"] %>\">\n      <%= current_track %>\n    </span>\n  </div>\n<% end %>\n\n<div class=\"flex flex-col sm:flex-row items-stretch gap-2 mb-6 min-w-0\">\n  <div class=\"flex-1 min-w-0\">\n    <% if prev_talk %>\n      <%= link_to talk_path(prev_talk), class: \"flex flex-col h-full p-3 rounded border bg-white hover:bg-gray-50 transition-colors overflow-hidden\" do %>\n        <span class=\"text-xs text-gray-400 mb-1 truncate\"><%= fa(\"arrow-left\", size: :xs, class: \"fill-gray-400 inline mr-1\") %> <%= prev_label %></span>\n        <span class=\"font-medium text-sm line-clamp-2\"><%= prev_talk.title %></span>\n        <span class=\"text-xs text-gray-500 mt-1 truncate block w-full\"><%= prev_talk.speakers.map(&:name).join(\", \") %></span>\n\n        <% if prev_time %>\n          <span class=\"text-xs text-gray-400 mt-1\"><%= prev_time %></span>\n        <% end %>\n      <% end %>\n    <% else %>\n      <div class=\"flex flex-col h-full p-3 rounded border border-dashed bg-white text-gray-400\">\n        <span class=\"text-xs mb-1 truncate\"><%= prev_label %></span>\n        <span class=\"text-sm\">No previous session</span>\n      </div>\n    <% end %>\n  </div>\n\n  <div class=\"flex-1 min-w-0\">\n    <div class=\"flex flex-col h-full p-3 rounded bg-primary text-white overflow-hidden\">\n      <span class=\"text-xs text-white/70 mb-1\">Now Playing</span>\n      <span class=\"font-medium text-sm line-clamp-2\"><%= talk.title %></span>\n      <span class=\"text-xs text-white/70 mt-1 truncate block w-full\"><%= talk.speakers.map(&:name).join(\", \") %></span>\n\n      <% if current_time %>\n        <span class=\"text-xs text-white/70 mt-1\"><%= current_time %></span>\n      <% end %>\n    </div>\n  </div>\n\n  <div class=\"flex-1 min-w-0\">\n    <% if next_talk %>\n      <%= link_to talk_path(next_talk), class: \"flex flex-col h-full p-3 rounded border bg-white hover:bg-gray-50 transition-colors overflow-hidden\" do %>\n        <span class=\"text-xs text-gray-400 mb-1 truncate\"><%= next_label %> <%= fa(\"arrow-right\", size: :xs, class: \"fill-gray-400 inline ml-1\") %></span>\n        <span class=\"font-medium text-sm line-clamp-2\"><%= next_talk.title %></span>\n        <span class=\"text-xs text-gray-500 mt-1 truncate block w-full\"><%= next_talk.speakers.map(&:name).join(\", \") %></span>\n\n        <% if next_time %>\n          <span class=\"text-xs text-gray-400 mt-1\"><%= next_time %></span>\n        <% end %>\n      <% end %>\n    <% else %>\n      <div class=\"flex flex-col h-full p-3 rounded border border-dashed bg-white text-gray-400\">\n        <span class=\"text-xs mb-1 truncate\"><%= next_label %></span>\n        <span class=\"text-sm\">No next session</span>\n      </div>\n    <% end %>\n  </div>\n</div>\n\n<% if parallel_talks.any? %>\n  <div class=\"mb-6\">\n    <h4 class=\"text-sm font-medium text-gray-600 mb-3\">Other parallel sessions at <%= current_slot_time %></h4>\n\n    <div class=\"flex flex-col sm:flex-row gap-2\">\n      <% parallel_talks.each do |parallel_talk| %>\n        <% parallel_track = parallel_talk.static_metadata&.track %>\n        <% parallel_track_info = parallel_track && tracks.find { |t| t[\"name\"] == parallel_track } %>\n\n        <%= link_to talk_path(parallel_talk), class: \"flex-1 flex flex-col p-3 rounded border bg-white hover:bg-gray-50 transition-colors min-w-0 overflow-hidden\" do %>\n          <% if parallel_track_info %>\n            <span class=\"text-xs px-2 py-0.5 rounded self-start mb-2\" style=\"background: <%= parallel_track_info[\"color\"] %>; color: <%= parallel_track_info[\"text_color\"] %>\">\n              <%= parallel_track %>\n            </span>\n          <% end %>\n\n          <span class=\"font-medium text-sm line-clamp-2\"><%= parallel_talk.title %></span>\n          <span class=\"text-xs text-gray-500 mt-1 truncate block w-full\"><%= parallel_talk.speakers.map(&:name).join(\", \") %></span>\n        <% end %>\n      <% end %>\n    </div>\n  </div>\n<% end %>\n\n<hr class=\"mb-6\">\n\n<h3 class=\"font-bold text-lg mb-4\">Full Schedule</h3>\n\n<div class=\"flex flex-col gap-6\">\n  <% talk_index = 0 %>\n\n  <% days.each_with_index do |day, day_index| %>\n    <% date = Date.parse(day.dig(\"date\")) %>\n    <% date_string = date.strftime(\"%A, %b %d\") %>\n\n    <div>\n      <h4 class=\"font-semibold mb-3\"><%= day.dig(\"name\") %> - <%= date_string %></h4>\n\n      <div class=\"flex flex-col gap-2\">\n        <% day.dig(\"grid\").each do |grid| %>\n          <% start_time = grid[\"start_time\"] %>\n          <% end_time = grid[\"end_time\"] %>\n          <% slots = grid[\"slots\"] %>\n          <% items = grid.fetch(\"items\", []) %>\n\n          <% if items.any? %>\n            <div class=\"flex items-center gap-3 py-2 px-3 bg-gray-100 rounded text-sm text-gray-600\">\n              <span class=\"text-xs text-gray-400 w-24 flex-shrink-0\"><%= [start_time, end_time].uniq.join(\" - \") %></span>\n              <span><%= items.first.is_a?(String) ? items.first : items.first&.fetch(\"title\", \"\") %></span>\n            </div>\n          <% else %>\n            <% slots.times do |slot_index| %>\n              <% schedule_talk = all_talks[talk_index] %>\n              <% is_current = schedule_talk&.id == talk.id %>\n              <% talk_track = schedule_talk&.static_metadata&.track %>\n              <% track = talk_track && tracks.find { |t| t[\"name\"] == talk_track } %>\n\n              <% if schedule_talk %>\n                <% link_classes = class_names(\"flex items-center gap-3 py-2 px-3 rounded text-sm transition-colors\", \"bg-primary text-white\" => is_current, \"bg-white border hover:bg-gray-50\" => !is_current) %>\n                <% time_classes = is_current ? \"text-white/70\" : \"text-gray-400\" %>\n                <% speaker_classes = is_current ? \"text-white/70\" : \"text-gray-500\" %>\n\n                <%= link_to talk_path(schedule_talk), class: link_classes do %>\n                  <span class=\"text-xs w-20 flex-shrink-0 hidden sm:inline <%= time_classes %>\">\n                    <%= [start_time, end_time].uniq.join(\" - \") %>\n                  </span>\n\n                  <div class=\"w-16 h-9 flex-shrink-0 rounded overflow-hidden\">\n                    <%= image_tag schedule_talk.thumbnail_sm, class: \"w-full h-full object-cover #{schedule_talk.thumbnail_classes}\", loading: :lazy, alt: \"\" %>\n                  </div>\n\n                  <div class=\"flex-grow min-w-0\">\n                    <div class=\"font-medium truncate\"><%= schedule_talk.title.truncate(100) %></div>\n\n                    <div class=\"text-xs <%= speaker_classes %> truncate overflow-hidden flex max-w-full\">\n                      <%= schedule_talk.speakers.map(&:name).join(\", \").truncate(120) %>\n                    </div>\n                  </div>\n\n                  <% if track && talk_track %>\n                    <span class=\"text-xs px-2 py-0.5 rounded flex-shrink-0 min-w-[100px] text-center\" style=\"background: <%= track[\"color\"] %>; color: <%= track[\"text_color\"] %>\">\n                      <%= talk_track %>\n                    </span>\n                  <% end %>\n\n                <% end %>\n\n                <% talk_index += 1 %>\n              <% end %>\n            <% end %>\n          <% end %>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/talks/_sections.html.erb",
    "content": "<div class=\"relative group border border-transparent\" id=\"talkToggle\">\n  <div class=\"max-h-[220px] group-data-[expanded]:max-h-none overflow-y-hidden transition transition-all\">\n    <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-2 md:gap-4 mb-3\">\n      <% talk.child_talks.order(:start_seconds).each_with_index do |child_talk, index| %>\n        <%= link_to child_talk, data: {turbo_frame: \"talk\"}, class: \"p-2 border rounded group bg-white hover:bg-gray-100 data-[active]:border-blue-700/30 data-[active]:bg-blue-50 hover:data-[active]:bg-blue-100 data-[active]:text-blue-700\", **{\"data-active\" => child_talk == talk}.select { |_, v| v } do %>\n          <div class=\"flex justify-between\">\n            <div <% if child_talk == talk %> data-active <% end %> class=\"flex gap-3 text-gray-700 data-[active]:font-bold text-sm\">\n              <div class=\"flex aspect-video shrink-0 relative w-16 lg:w-24 xl:w-36\">\n                <%= image_tag child_talk.thumbnail_sm, srcset: [\"#{child_talk.thumbnail_sm} 2x\"], id: dom_id(child_talk), class: \"w-full h-auto aspect-video object-cover rounded #{child_talk.thumbnail_classes}\", loading: :lazy %>\n              </div>\n\n              <div class=\"flex flex-col gap-0.5 justify-center\">\n                <div class=\"text-xs text-gray-500 mb-1 hidden xl:block\">\n                  Section <%= index + 1 %>\n                </div>\n                <div class=\"text-sm font-bold\">\n                  <%= child_talk.speakers.map(&:name).to_sentence %>\n                </div>\n                <div class=\"text-sm text-gray-500 line-clamp-2 data-[active]:text-blue-700\" <% if child_talk == talk %> data-active <% end %>>\n                  <%= child_talk.title %>\n\n                  <% if child_talk.language_name != \"English\" %>\n                    <span data-controller=\"tooltip\" data-tooltip-content-value=\"<%= child_talk.language_name %>\">\n                      - <%= language_to_emoji(child_talk.language_name) %>\n                    </span>\n                  <% end %>\n                </div>\n              </div>\n            </div>\n\n            <div class=\"flex flex-col gap-2 justify-right\">\n              <% if child_talk.start_seconds %>\n                <div class=\"badge\">\n                  <%= seconds_to_formatted_duration(child_talk.start_seconds) %>\n                </div>\n              <% end %>\n            </div>\n          </div>\n        <% end %>\n      <% end %>\n    </div>\n  </div>\n\n  <% if talk.child_talks.size > 4 %>\n    <div class=\"absolute bottom-0 left-0 w-full h-36 bg-gradient-to-t from-base-100 to-transparent group-data-[expanded]:hidden flex justify-center items-end\">\n      <button class=\"btn btn-sm btn-white shadow\" onclick=\"talkToggle.toggleAttribute('data-expanded')\">Show all <%= pluralize(talk.child_talks.size, \"section\") %></button>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/talks/_similar_talks_tab.html.erb",
    "content": "<%# locals: (talk:, similar_talks:) %>\n\n<div class=\"flex flex-col gap-4 min-w-0 w-full max-w-full\">\n  <p class=\"text-sm text-gray-600\">\n    Similar Talks that share the same topics:\n  </p>\n\n  <div class=\"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4 w-full max-w-full\">\n    <% similar_talks.each do |similar_talk| %>\n      <div class=\"min-w-0\">\n        <%= render \"talks/card_thumbnail\", talk: similar_talk %>\n      </div>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/_speaker_tab.html.erb",
    "content": "<%# locals: (talk:, favorite_users:) %>\n\n<div class=\"flex flex-col gap-6 overflow-hidden min-w-0\">\n  <% talk.speakers.each do |speaker| %>\n    <div class=\"rounded-lg overflow-hidden min-w-0\">\n      <div class=\"flex items-start gap-4\">\n        <%= link_to profile_path(speaker), class: \"flex-shrink-0\" do %>\n          <%= ui_avatar speaker, size: :md, size_class: \"w-16\" %>\n        <% end %>\n\n        <div class=\"flex-grow min-w-0\">\n          <div class=\"flex items-center gap-2 flex-wrap\">\n            <%= link_to profile_path(speaker), class: \"text-xl font-bold hover:underline\" do %>\n              <%= speaker.name %>\n            <% end %>\n\n            <% if speaker.pronouns.present? %>\n              <span class=\"text-sm text-gray-500\">(<%= speaker.pronouns %>)</span>\n            <% end %>\n\n            <% if favorite_users[speaker.id] %>\n              <%= render partial: \"favorite_users/favorite_user\", locals: {favorite_user: favorite_users[speaker.id]} %>\n            <% end %>\n          </div>\n\n          <div class=\"flex items-center gap-3 text-sm text-gray-500 mt-1\">\n            <% if speaker.location.present? %>\n              <span><%= speaker.location %></span>\n            <% end %>\n\n            <div class=\"flex gap-2\">\n              <% if speaker.github_handle.present? %>\n                <%= link_to \"https://github.com/#{speaker.github_handle}\", target: \"_blank\", class: \"text-gray-400 hover:text-gray-600\" do %>\n                  <%= fa(\"github-brands\", size: :sm, class: \"fill-current\") %>\n                <% end %>\n              <% end %>\n\n              <% if speaker.twitter.present? %>\n                <%= link_to \"https://twitter.com/#{speaker.twitter}\", target: \"_blank\", class: \"text-gray-400 hover:text-gray-600\" do %>\n                  <%= fa(\"x-twitter-brands\", size: :sm, class: \"fill-current\") %>\n                <% end %>\n              <% end %>\n\n              <% if speaker.bsky.present? %>\n                <%= link_to \"https://bsky.app/profile/#{speaker.bsky}\", target: \"_blank\", class: \"text-gray-400 hover:text-gray-600\" do %>\n                  <%= fa(\"bluesky-brands\", size: :sm, class: \"fill-current\") %>\n                <% end %>\n              <% end %>\n\n              <% if speaker.website.present? %>\n                <%= link_to speaker.website, target: \"_blank\", class: \"text-gray-400 hover:text-gray-600\" do %>\n                  <%= fa(\"globe\", size: :sm, class: \"fill-current\") %>\n                <% end %>\n              <% end %>\n            </div>\n          </div>\n        </div>\n\n        <%= link_to profile_path(speaker), class: \"text-sm text-primary hover:underline flex-shrink-0\" do %>\n          View Profile\n        <% end %>\n      </div>\n\n      <% if speaker.bio.present? %>\n        <p class=\"text-sm text-gray-600 mt-4 mb-3 line-clamp-2\"><%= speaker.bio %></p>\n      <% end %>\n\n      <% other_talks = speaker.kept_talks.watchable.where.not(id: talk.id).includes(:event, :speakers).order(date: :desc).limit(8) %>\n      <% total_other_talks = speaker.kept_talks.watchable.where.not(id: talk.id).count %>\n\n      <% if other_talks.any? %>\n        <div class=\"pt-3 border-t overflow-hidden min-w-0\">\n          <div class=\"flex items-center justify-between mb-2\">\n            <span class=\"text-sm font-medium text-gray-600 mb-3\">\n              More from <%= speaker.name %> (<%= total_other_talks %>)\n            </span>\n\n            <% if total_other_talks > 8 %>\n              <%= link_to \"View all\", profile_talks_path(speaker), class: \"text-sm text-primary hover:underline\" %>\n            <% end %>\n          </div>\n\n          <div class=\"flex gap-3 overflow-x-auto scroll-smooth snap-x snap-mandatory pb-2\" style=\"contain: inline-size;\">\n            <% other_talks.each do |other_talk| %>\n              <div class=\"snap-start flex-none w-[180px] sm:w-[220px]\">\n                <%= render \"talks/card_thumbnail\", talk: other_talk, exclude_speaker: speaker %>\n              </div>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/talks/_talk.html.erb",
    "content": "<%# locals: (talk:, speakers:, user_favorite_talks_ids:, favorite_users:) %>\n\n<% current_user_watched_talk = talk.watched_talks.find { |wt| wt.user_id == Current.user&.id } %>\n<% is_watched = signed_in? && current_user_watched_talk&.watched? %>\n\n<% video_provider = case talk.video_provider\n   when \"mp4\" then \"mp4\"\n   when \"parent\" then talk.parent_talk.video_provider\n   else talk.video_provider\n   end %>\n\n<% if talk.parent_talk&.video_provider == \"children\" %>\n  <% video_provider = talk.video_provider %>\n<% end %>\n\n<% video_id = (talk.video_provider == \"parent\") ? talk.parent_talk.video_id : talk.video_id %>\n\n<% language = Language.by_code(talk.language) %>\n<%= content_tag :div, id: dom_id(talk) do %>\n\n  <%= turbo_frame_tag dom_id(talk, :video_player) do %>\n    <%= render partial: \"talks/video_player\", locals: {talk: talk, current_user_watched_talk: current_user_watched_talk, is_watched: is_watched, video_provider: video_provider, video_id: video_id} %>\n  <% end %>\n\n  <div id=\"<%= dom_id(talk, :feedback_banner) %>\">\n    <% if is_watched %>\n      <%= render partial: \"talks/watched_talks/feedback_banner\", locals: {talk: talk, watched_talk: current_user_watched_talk} %>\n    <% end %>\n  </div>\n\n  <div class=\"flex flex-col\">\n    <% if talk.meta_talk? %>\n      <div class=\"flex gap-1 px-3 py-3 my-3 badge badge-ghost hover:bg-gray-300\">\n        <%= fa(\"rectangle-history\", size: :xs, class: \"fill-gray-700 mr-2\") %>\n        <span class=\"text-gray-700\">This video contains <%= pluralize(talk.child_talks.size, \"individual talk\") %></span>\n      </div>\n      <hr>\n    <% end %>\n\n    <% if talk.parent_talk.present? %>\n      <div class=\"py-3\">\n        <div class=\"mb-2 text-xs text-gray-500 text-nowrap\">Part of recording</div>\n        <%= link_to talk.parent_talk, class: \"badge badge-ghost hover:bg-gray-300 px-4 py-4 text-sm\" do %>\n          <%= fa(\"rectangle-history\", size: :xs, class: \"fill-black mr-2\") %>\n          <%= talk.parent_talk.title %>\n        <% end %>\n      </div>\n      <hr>\n    <% end %>\n\n    <div class=\"flex flex-col w-full divide-y md:gap-1\">\n      <div class=\"flex flex-wrap justify-between w-full divide-y\">\n        <div class=\"py-4 text-xl font-bold\">\n          <span><%= talk.title %></span>\n          <% if talk.original_title.present? %>\n            <div class=\"mb-2 text-xs text-gray-500\">Original title (<%= talk.language %>): <%= talk.original_title %></div>\n          <% end %>\n\n        </div>\n\n        <div class=\"flex order-last gap-1 py-3 overflow-x-scroll overflow-y-visible text-xs grow lg:divide-y-0 xl:justify-end lg:overflow-x-hidden xl:order-none\">\n          <% if Current.user&.admin? %>\n            <%= ui_button url: avo.resources_talk_path(talk), kind: :pill, target: \"_blank\" do %>\n              <%= fa :avocado, size: :xs, style: :solid %>\n\n              <span class=\"text-xs\">Open in Avo</span>\n            <% end %>\n          <% end %>\n\n          <% if default_watch_list %>\n            <% if user_favorite_talks_ids.include?(talk.id) %>\n              <%= ui_tooltip \"Add talk to your watch list\" do %>\n                <%= ui_button url: watch_list_talk_path(default_watch_list, talk.id), method: :delete, kind: :pill do %>\n                  <%= fa(\"bookmark\", size: :xs, style: :solid, class: \"text-primary\") %>\n                  <span class=\"text-xs\">Bookmark</span>\n                <% end %>\n              <% end %>\n            <% else %>\n              <%= ui_tooltip \"Add talk to your watch list\" do %>\n                <%= ui_button url: watch_list_talks_path(default_watch_list, talk_id: talk.id), method: :post, kind: :pill do %>\n                  <%= fa(\"bookmark\", size: :xs, style: :regular) %>\n                  <span class=\"text-xs\">Bookmark</span>\n                <% end %>\n              <% end %>\n            <% end %>\n          <% else %>\n            <%= ui_tooltip \"Add talk to your watch list\" do %>\n              <%= ui_button url: new_session_path(redirect_to: request.fullpath), data: {turbo_frame: \"modal\"}, kind: :pill do %>\n                <%= fa(\"bookmark\", size: :xs, style: :regular) %>\n                <span class=\"text-xs\">Bookmark</span>\n              <% end %>\n            <% end %>\n          <% end %>\n\n          <% if talk.youtube? || talk.parent_talk&.youtube? %>\n            <%= ui_tooltip \"Watch on YouTube\" do %>\n              <%= ui_button url: talk.external_player_url, kind: :pill, target: \"_blank\", data: {action: \"click->video-player#pause\"} do %>\n                <%= fa(\"youtube-brands\", size: :xs, style: :solid) %>\n                <span class=\"text-xs\">Play on YouTube</span>\n              <% end %>\n            <% end %>\n          <% end %>\n\n          <% if talk.vimeo? || talk.parent_talk&.vimeo? %>\n            <%= ui_tooltip \"Watch on Vimeo\" do %>\n              <%= ui_button url: talk.external_player_url, kind: :pill, target: \"_blank\" do %>\n                <%= fa(\"vimeo-v-brands\", size: :xs, style: :solid) %>\n                <span class=\"text-xs\">Play on Vimeo</span>\n              <% end %>\n            <% end %>\n          <% end %>\n\n          <% if talk.static_metadata&.external_player_url.present? || talk.parent_talk&.static_metadata&.external_player_url.present? %>\n            <% player_url = talk.parent_talk&.static_metadata&.external_player_url || talk.static_metadata.external_player_url %>\n\n            <%= ui_tooltip \"Watch on Website\" do %>\n              <%= ui_button url: player_url, kind: :pill, target: \"_blank\", data: {action: \"click->video-player#pause\"} do %>\n                <%= fa(\"website-brands\", size: :xs, style: :solid) %>\n                <span class=\"text-xs\">Play on Website</span>\n              <% end %>\n            <% end %>\n          <% end %>\n\n          <%= turbo_frame_tag dom_id(talk, :watched_button) do %>\n            <% if signed_in? %>\n              <%= render partial: \"talks/watched_talks/button\", locals: {talk: talk, is_watched: is_watched} %>\n            <% end %>\n          <% end %>\n\n          <%= ui_tooltip \"You can suggest some modifications to this talk\", class: \"hotwire-native:hidden\" do %>\n            <%= ui_button url: edit_talk_path(talk), kind: :pill, data: {turbo_frame: \"modal\"} do %>\n              <%= fa(\"pen\", size: :xs, style: :solid) %>\n              <span class=\"text-xs\">Edit</span>\n            <% end %>\n          <% end %>\n        </div>\n\n        <div class=\"flex justify-between w-full py-2\">\n          <div class=\"flex flex-wrap\">\n            <% speaker_size = 2 %>\n            <% more_speakers = speakers.size > speaker_size %>\n            <% speaker_preview_count = more_speakers ? 1 : 2 %>\n\n            <% speakers.take(speaker_preview_count).each do |speaker| %>\n              <%= content_tag :div, class: class_names(\"hidden xl:block\" => more_speakers) do %>\n                <%= render partial: \"users/card\", locals: {user: speaker, favorite_user: favorite_users[speaker.id]} %>\n              <% end %>\n            <% end %>\n\n            <% if more_speakers %>\n              <div class=\"flex flex-col gap-4 px-4 duration-300 ease-in-out rounded-lg cursor-pointer hover:bg-gray-200 transition-bg md:p-2\" onclick=\"document.querySelector('[name=talk_tabs][aria-label=Speakers]').checked = true\" data-tip=\"<%= speakers.to_a.from(2).map(&:name).to_sentence %>\">\n                <div class=\"flex items-center <% if !talk.meta_talk? %> gap-x-4 <% end %>\">\n                  <div class=\"-space-x-6 avatar-group rtl:space-x-reverse\">\n                    <% speakers.to_a.from(speaker_preview_count).each do |speaker| %>\n                      <div class=\"avatar placeholder border-none <% if talk.meta_talk? %>hidden <% end %>\">\n                        <%= ui_avatar speaker %>\n                      </div>\n                    <% end %>\n                  </div>\n\n                  <div class=\"flex gap-4\">\n                    <% if talk.meta_talk? %>\n                      <div class=\"border-none avatar placeholder\">\n                        <%= content_tag :div, class: \"w-12 rounded-full bg-primary text-neutral-content\" do %>\n                          <span class=\"hidden text-lg xl:block\">\n                            +<%= speakers.size - 1 %>\n                          </span>\n\n                          <span class=\"block text-lg xl:hidden\">\n                            +<%= speakers.size %>\n                          </span>\n                        <% end %>\n                      </div>\n                    <% end %>\n\n                    <div class=\"flex flex-col justify-center\">\n                      <div class=\"text-xs text-gray-500 line-clamp-1\">\n                        See all speakers\n                      </div>\n\n                      <div class=\"hidden text-base font-bold xl:block line-clamp-1\">\n                        <%= pluralize(speakers.size - 1, \"more speaker\") %>\n                      </div>\n\n                      <div class=\"block text-base font-bold xl:hidden line-clamp-1\">\n                        See all <%= pluralize(speakers.size, \"speaker\") %>\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            <% end %>\n          </div>\n\n          <div class=\"hidden 2xl:block\">\n            <%= render partial: \"talks/event\", locals: {event: talk.event, talk: talk, video_provider: talk.video_provider} %>\n          </div>\n        </div>\n      </div>\n    </div>\n\n    <hr>\n\n    <% if (talk.parent_talk.present? || talk.meta_talk?) && talk.video_provider != \"children\" %>\n      <% parent_talk = talk.parent_talk || talk %>\n\n      <h3 class=\"my-3 font-bold text-md\">Sections in this recording</h3>\n\n      <%= render partial: \"talks/sections\", locals: {talk: parent_talk} %>\n\n      <br><hr>\n    <% end %>\n\n    <% if talk.approved_topics.any? %>\n      <div class=\"py-4\">\n        <%= render partial: \"topics/badge_list\", locals: {topics: talk.approved_topics, back_to_url: back_to_from_request, back_to_title: talk.title} %>\n      </div>\n      <hr>\n    <% end %>\n\n    <%= render Events::UpcomingEventBannerComponent.new(event: talk.event) %>\n\n    <div role=\"tablist\" class=\"mt-6 tabs tabs-bordered [&>.tab]:flex-shrink-0\">\n      <% if talk.summary.present? %>\n        <input type=\"radio\" name=\"talk_tabs\" role=\"tab\" class=\"tab\" aria-label=\"Summary\" checked>\n        <div role=\"tabpanel\" class=\"tab-content !rounded-s-xl rounded-xl bg-base-200/50 p-6 mt-6 overflow-x-auto max-w-full\">\n          <% if talk.summarized_using_ai? %>\n            <div class=\"badge text-white bg-[linear-gradient(to_right,rgb(132,71,198),rgb(171,93,139))] px-3 py-3 mb-4\">\n              <span class=\"flex tooltip tooltip-right\" data-tip=\"This summary is auto-generated by an AI based on the transcript of the talk.\">\n                <%= fa :sparkles, size: :xs, class: \"mr-2 fill-white\" %> Summarized using AI\n              </span>\n            </div>\n          <% end %>\n\n          <h2><%= talk.title %></h2>\n          <%= speakers.map(&:name).to_sentence %> • <%= talk.formatted_date %> • <%= talk.to_location.to_html(show_links: false) %> <% if language && language != \"English\" %> • <%= language %> <% end %> • <%= talk.formatted_kind %>\n\n          <article class=\"mt-4 prose markdown\"><%= markdown_to_html(talk.summary) %></article>\n        </div>\n      <% end %>\n\n      <input type=\"radio\" name=\"talk_tabs\" role=\"tab\" class=\"tab\" aria-label=\"Description\" <% if talk.summary.blank? %> checked <% end %>>\n      <div role=\"tabpanel\" class=\"tab-content !rounded-s-xl rounded-xl bg-base-200/50 p-6 mt-6 overflow-x-auto max-w-full\">\n        <article class=\"prose\">\n          <p>\n            <b><%= talk.title %></b><br>\n            <%= speakers.map(&:name).to_sentence %>\n            • <%= talk.to_location.to_html(show_links: false) %>\n            <% if language && language != \"English\" %> • <%= language %> <% end %> •\n            <%= talk.formatted_kind %>\n          </p>\n\n          <p>\n            Held on: <%= talk.formatted_date %><br>\n\n            <span class=\"text-gray-400\">\n              Published: <% if talk.published_at %><%= l(talk.published_at&.to_date, default: \"unknown\") %><% elsif talk.published? %> unknown <% else %> not published <% end %><br>\n\n              <% if talk.video_unavailable? %>\n                Unavailable: <%= l(talk.video_unavailable_at.to_date) %><br>\n              <% end %>\n\n              <% if talk.announced_at.present? %>\n                Announced: <%= l(talk.announced_at&.to_date, default: \"unknown\") %><br>\n              <% end %>\n            </span>\n          </p>\n\n          <%= simple_format auto_link(talk.description, html: {target: \"_blank\", class: \"link\"}) %>\n\n          <p class=\"flex\">\n            <span><%= talk.event_name %></span>\n          </p>\n        </article>\n      </div>\n\n      <% if talk.transcript.present? %>\n        <input type=\"radio\" name=\"talk_tabs\" role=\"tab\" class=\"tab\" aria-label=\"Transcript\">\n        <div role=\"tabpanel\" class=\"tab-content !rounded-s-xl rounded-xl bg-base-200/50 p-6 mt-6 overflow-x-auto max-w-full\">\n          <%= render partial: \"talks/transcript\", locals: {talk: talk} %>\n        </div>\n      <% end %>\n\n      <% if talk.slides_url.present? %>\n        <input type=\"radio\" name=\"talk_tabs\" role=\"tab\" class=\"tab\" aria-label=\"Slides\">\n        <div role=\"tabpanel\" class=\"tab-content !rounded-s-xl rounded-xl bg-base-200/50 p-6 mt-6 overflow-x-auto max-w-full\">\n          <%= turbo_frame_tag dom_id(talk, :slides), src: talk_slides_path(talk), loading: :lazy do %>\n            <div class=\"w-full h-32 rounded skeleton\"></div>\n          <% end %>\n        </div>\n      <% end %>\n\n      <% if talk.additional_resources.present? %>\n        <input type=\"radio\" name=\"talk_tabs\" role=\"tab\" class=\"tab\" aria-label=\"Resources\">\n        <div role=\"tabpanel\" class=\"tab-content !rounded-s-xl rounded-xl bg-base-200/50 p-6 mt-6 overflow-x-auto max-w-full\">\n          <ul class=\"space-y-4\">\n            <% talk.additional_resources.each do |resource| %>\n              <li class=\"flex items-start gap-3\">\n                <%= fa(resource_icon(resource), size: :sm, class: \"fill-gray-500 mt-1 flex-shrink-0\") %>\n\n                <div class=\"flex flex-col\">\n                  <%= link_to resource[\"url\"], target: \"_blank\", rel: \"noopener noreferrer\", class: \"link link-primary\" do %>\n                    <%= resource_display_title(resource) %>\n                  <% end %>\n\n                  <span class=\"text-xs text-gray-500\">\n                    <%= resource[\"name\"] %> · <%= resource_domain(resource) %>\n                  </span>\n                </div>\n              </li>\n            <% end %>\n          </ul>\n        </div>\n      <% end %>\n\n      <% if speakers.length.positive? %>\n        <input type=\"radio\" name=\"talk_tabs\" role=\"tab\" class=\"tab\" aria-label=\"<%= \"Speaker\".pluralize(speakers.size) %>\">\n        <div role=\"tabpanel\" class=\"tab-content !rounded-s-xl rounded-xl bg-base-200/50 p-6 mt-6 overflow-x-auto max-w-full min-w-0\">\n          <%= render partial: \"talks/speaker_tab\", locals: {talk: talk, favorite_users: favorite_users} %>\n        </div>\n      <% end %>\n\n      <input type=\"radio\" name=\"talk_tabs\" role=\"tab\" class=\"tab\" aria-label=\"Event\">\n      <div role=\"tabpanel\" class=\"tab-content !rounded-s-xl rounded-xl bg-base-200/50 p-6 mt-6 overflow-x-auto max-w-full\">\n        <%= render partial: \"talks/event_tab\", locals: {event: talk.event} %>\n      </div>\n\n      <% if talk.event.schedule.exist? %>\n        <input type=\"radio\" name=\"talk_tabs\" role=\"tab\" class=\"tab\" aria-label=\"Schedule\">\n        <div role=\"tabpanel\" class=\"tab-content !rounded-s-xl rounded-xl bg-base-200/50 p-6 mt-6 overflow-x-auto max-w-full\">\n          <%= render partial: \"talks/schedule_tab\", locals: {talk: talk, event: talk.event} %>\n        </div>\n      <% end %>\n\n      <% similar_talks = talk.similar_recommender.talks %>\n\n      <% if similar_talks.any? %>\n        <input type=\"radio\" name=\"talk_tabs\" role=\"tab\" class=\"tab\" aria-label=\"Similar Talks\">\n\n        <div role=\"tabpanel\" class=\"tab-content !rounded-s-xl rounded-xl bg-base-200/50 p-6 mt-6 overflow-x-auto max-w-full min-w-0\">\n          <%= render partial: \"talks/similar_talks_tab\", locals: {talk: talk, similar_talks: similar_talks} %>\n        </div>\n      <% end %>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/_talk_filter.html.erb",
    "content": "<% classes = \"bg-white hover:bg-gray-100 cursor-pointer px-4 py-2 text-sm text-gray-500 rounded-full border font-bold select-none\" %>\n<% active_classes = \"!bg-red-500 hover:!bg-red-600 !text-white !border-red-500\" %>\n\n<% talks_by_language = talks.group_by(&:language) %>\n<% talks_by_kind = talks.group_by(&:kind) %>\n\n<% if talks_by_language.length >= 2 || talks_by_kind.length >= 2 %>\n  <div class=\"mb-6\" data-controller=\"talks-filter-pill\" data-talks-filter-pill-active-class=\"<%= active_classes %>\">\n    <div class=\"flex flex-wrap sm:divide-y divide-x\">\n      <% if talks_by_kind.length >= 2 %>\n        <div class=\"flex gap-2 mb-3 pr-6 justify-center\">\n          <% talks_by_kind.each do |kind, talks| %>\n            <div data-action=\"click->talks-filter-pill#selectKind\" data-talks-filter-pill-target=\"button\" class=\"<%= classes %>\" data-kind-value=\"<%= kind %>\">\n              <%= Talk::KIND_LABELS[kind] %>\n              <span class=\"count count-kind count-language-all\">(<%= talks.length %>)</span>\n\n              <% talks_by_language.each do |language, talks| %>\n                <span class=\"hidden count count-kind count-language-<%= language %>\">(<%= talks.select { |talk| talk.kind == kind }.count %>)</span>\n              <% end %>\n            </div>\n          <% end %>\n        </div>\n      <% end %>\n\n      <% if talks_by_language.length >= 2 %>\n        <div class=\"flex gap-2 mb-3 px-6 justiy-center\">\n          <% talks_by_language.each do |language, talks| %>\n            <div data-action=\"click->talks-filter-pill#selectLanguage\" data-talks-filter-pill-target=\"button\" class=\"<%= classes %>\" data-language-value=\"<%= language %>\">\n              <%= Language.by_code(language) %>\n              <span class=\"count count-language count-kind-all\">(<%= talks.length %>)</span>\n\n              <% talks_by_kind.each do |kind, talks| %>\n                <span class=\"hidden count count-language count-kind-<%= kind %>\">(<%= talks.select { |talk| talk.language == language }.count %>)</span>\n              <% end %>\n            </div>\n          <% end %>\n        </div>\n      <% end %>\n    </div>\n\n    <div class=\"hidden\" data-talks-filter-pill-target=\"none\">\n      <div class=\"w-full border bg-white text-gray-500 flex justify-center content-center font-medium text-lg rounded-lg py-10 mt-6\">\n        No videos matched your filters.\n      </div>\n    </div>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/_transcript.html.erb",
    "content": "<%# locals: (talk:) %>\n\n<div class=\"flex flex-col gap-2\">\n  <% talk.transcript.cues.each do |cue| %>\n    <% next if cue.nil? || cue.text.blank? || cue.sound_descriptor? %>\n    <div class=\"flex gap-4\">\n      <span class=\"link\" data-action=\"click->video-player#seekTo\" data-video-player-time-param=\"<%= cue.start_time_in_seconds %>\">\n        <%= cue.start_time %>\n      </span>\n      <span><%= cue.text %></span>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/talks/_video_player.html.erb",
    "content": "<%# locals: (talk:, current_user_watched_talk:, is_watched:, video_provider:, video_id:) %>\n\n<% video_player_controller = talk.external_player ? nil : \"video-player\" %>\n\n<%= content_tag :div, id: dom_id(talk, :player_container),\n      class: \"w-full max-w-full\",\n      data: {\n        controller: video_player_controller,\n        video_player_poster_value: talk.thumbnail_xl,\n        video_player_provider_value: video_provider,\n        video_player_src_value: video_id,\n        video_player_start_seconds_value: (is_watched ? nil : talk.start_seconds),\n        video_player_end_seconds_value: talk.end_seconds,\n        video_player_duration_seconds_value: talk.duration_in_seconds,\n        video_player_watched_talk_path_value: talk_watched_talk_path(talk),\n        video_player_current_user_present_value: signed_in?,\n        video_player_progress_seconds_value: current_user_watched_talk&.progress_seconds || 0,\n        video_player_watched_value: is_watched\n      } do %>\n\n  <div class=\"relative overflow-hidden bg-gray-300 aspect-video banner-img card-horizontal-img rounded-xl outline outline-1 outline-gray-300 w-full max-w-full\">\n    <% if talk.external_player %>\n      <%= link_to talk.external_player_url, target: \"_blank\", class: \"relative w-full h-full block\" do %>\n        <%= image_tag talk.thumbnail_xl, class: \"w-full h-full object-cover rounded-xl\", style: \"view-transition-name: #{dom_id(talk, :image)}\" %>\n\n        <div class=\"absolute inset-0 flex flex-col items-center justify-center gap-6 p-6 text-xl font-bold text-center text-white bg-black/80 rounded-xl\">\n          This talk is available to watch on <%= URI.parse(talk.external_player_url).host %>\n\n          <%= ui_button do %>\n            <%= fa(\"play\", size: :xs, class: \"fill-white\") %> <span>Watch <span class=\"hidden sm:inline-block\"> on <%= URI.parse(talk.external_player_url).host %></span></span>\n          <% end %>\n        </div>\n      <% end %>\n\n    <% else %>\n      <% if talk.video_unavailable? %>\n        <%= render partial: \"talks/video_providers/video_unavailable\", locals: {talk: talk, video_provider: video_provider, video_id: video_id, is_watched: is_watched} %>\n      <% elsif video_provider.in?([\"mp4\", \"youtube\", \"vimeo\", \"scheduled\", \"not_published\", \"not_recorded\", \"children\"]) %>\n        <%= render partial: \"talks/video_providers/#{video_provider}\", locals: {talk: talk, video_provider: video_provider, video_id: video_id, is_watched: is_watched} %>\n      <% else %>\n        Provider <%= video_provider.inspect %> is not configured.\n      <% end %>\n\n      <div id=\"<%= dom_id(talk, :watched_overlay) %>\">\n        <% if is_watched %>\n          <%= render partial: \"talks/watched_talks/watched_overlay\", locals: {talk: talk} %>\n        <% end %>\n      </div>\n\n      <% if current_user_watched_talk&.in_progress? && !is_watched && talk.video_available? %>\n        <div class=\"absolute inset-0 cursor-pointer group/resume\" data-video-player-target=\"resumeOverlay\" data-action=\"click->video-player#resumePlayback\">\n          <%= image_tag talk.thumbnail_xl, class: \"absolute inset-0 w-full h-full object-cover rounded-xl\", style: \"view-transition-name: #{dom_id(talk, :image)}\" %>\n          <div class=\"absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-black/20 rounded-xl\"></div>\n          <div class=\"absolute inset-0 bg-gradient-to-t from-black/60 via-black/20 to-transparent rounded-xl opacity-0 group-hover/resume:opacity-100 transition-opacity duration-300\"></div>\n          <div class=\"absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 text-center text-white\">\n            <div class=\"p-4 bg-white/20 backdrop-blur-sm rounded-full group-hover/resume:bg-white/30 group-hover/resume:scale-105 transition-all duration-300\">\n              <%= fa(\"play\", size: :xl, class: \"fill-white ml-1\") %>\n            </div>\n\n            <div class=\"flex flex-col gap-1\">\n              <div class=\"text-lg font-semibold\">Continue Watching</div>\n              <div class=\"text-sm text-white/80\"><%= seconds_to_formatted_duration(current_user_watched_talk.progress_seconds) %> / <%= seconds_to_formatted_duration(talk.duration_in_seconds) %></div>\n            </div>\n          </div>\n        </div>\n      <% elsif video_provider.in?([\"mp4\", \"youtube\", \"vimeo\"]) && !is_watched && talk.video_available? %>\n        <div class=\"absolute inset-0 cursor-pointer group/play\" data-video-player-target=\"playOverlay\" data-action=\"click->video-player#startPlayback\">\n          <%= image_tag talk.thumbnail_xl, class: \"absolute inset-0 w-full h-full object-cover rounded-xl\", style: \"view-transition-name: #{dom_id(talk, :image)}\" %>\n          <div class=\"absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-black/20 rounded-xl\"></div>\n          <div class=\"absolute inset-0 bg-gradient-to-t from-black/60 via-black/20 to-transparent rounded-xl opacity-0 group-hover/play:opacity-100 transition-opacity duration-300\"></div>\n          <div class=\"absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 text-center text-white\">\n            <div class=\"p-4 bg-white/20 backdrop-blur-sm rounded-full group-hover/play:bg-white/30 group-hover/play:scale-105 transition-all duration-300\">\n              <%= fa(\"play\", size: :xl, class: \"fill-white ml-1\") %>\n            </div>\n\n            <div class=\"flex flex-col gap-1\">\n              <div class=\"text-lg font-semibold\">Play</div>\n              <% if talk.duration_in_seconds.present? %>\n                <div class=\"text-sm text-white/80\"><%= seconds_to_formatted_duration(talk.duration_in_seconds) %></div>\n              <% end %>\n            </div>\n          </div>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/edit.html.erb",
    "content": "<% content_for :canonical_url, talk_url(@talk) %>\n\n<div class=\"w-full py-8 px-4\">\n  <h1 class=\"text-4xl font-bold\">Suggest modification to this talk</h1>\n\n  <%= render \"form\", talk: @talk %>\n</div>\n"
  },
  {
    "path": "app/views/talks/index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<div class=\"container flex flex-col w-full gap-4 my-8 hotwire-native:my-0 hotwire-native:mb-8\">\n  <div class=\"flex items-end gap-2 title text-primary hotwire-native:mb-3\">\n    <h1 class=\"title hotwire-native:hidden\">\n\n      <% if params[:status] == \"scheduled\" %>\n        <%= title \"Scheduled Talks\" %>\n      <% else %>\n        <%= title \"Video Recordings of Talks\" %>\n      <% end %>\n\n      <% if params[:s].present? %>\n        : search results for \"<%= params[:s] %>\"\n      <% end %>\n    </h1>\n  </div>\n\n  <div class=\"flex flex-col items-end justify-end gap-2 sm:items-center sm:flex-row hotwire-native:hidden\">\n    <% if filtered_search? %>\n      <div class=\"text-sm\">Results: <%= @pagy.count %></div>\n    <% end %>\n\n    <div class=\"tabs tabs-boxed\">\n      <%= link_to \"All\", talks_path(search_params.except(:status).merge(status: \"all\")),\n            class: \"tab #{\"tab-active\" if params[:status] == \"all\"}\" %>\n      <%= link_to \"Published\", talks_path(search_params.except(:status)),\n            class: \"tab #{\"tab-active\" if params[:status].blank?}\" %>\n      <%= link_to \"Scheduled\", talks_path(search_params.except(:status).merge(status: \"scheduled\")),\n            class: \"tab #{\"tab-active\" if params[:status] == \"scheduled\"}\" %>\n    </div>\n\n    <div class=\"flex items-center gap-2\">\n      <div class=\"text-sm text-gray-500\">Sort by:</div>\n      <div class=\"flex items-center gap-2\">\n        <details class=\"dropdown dropdown-end\">\n          <summary class=\"pl-0 m-1 font-normal bg-transparent border-none shadow-none btn hover:bg-transparent\"><%= ordering_title %></summary>\n          <ul class=\"z-30 p-2 shadow menu dropdown-content bg-base-100 rounded-box w-52\">\n            <% if params[:s].present? %>\n              <li>\n                <%= link_to \"Relevance\", {**search_params, order_by: \"ranked\"} %>\n              </li>\n            <% end %>\n            <li>\n              <%= link_to \"Newest first\", {**search_params, order_by: \"date_desc\"} %>\n            </li>\n            <li>\n              <%= link_to \"Oldest first\", {**search_params, order_by: \"date_asc\"} %>\n            </li>\n          </ul>\n        </details>\n      </div>\n    </div>\n  </div>\n  <%= turbo_frame_tag \"talks\", target: \"_top\" do %>\n    <div id=\"talks\" class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gallery\">\n      <%= render partial: \"talks/card\",\n            collection: @talks,\n            as: :talk,\n            locals: {\n              favoritable: true,\n              user_favorite_talks_ids: @user_favorite_talks_ids,\n              user_watched_talks: user_watched_talks,\n              back_to: back_to_from_request\n            } %>\n    </div>\n    <div class=\"flex w-full mt-4\">\n      <%== pagy_nav(@pagy) if @pagy.pages > 1 %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/talks/index.json.jbuilder",
    "content": "json.talks @talks do |talk|\n  json.title talk.title\n  json.video_id talk.video_id\n  json.video_provider talk.video_provider\n  json.date talk.date\n  json.parent_talk_slug talk.parent_talk&.slug\n  json.child_talks_slugs talk.child_talks.pluck(:slug)\n  json.language talk.language\n  json.url talk_url(talk)\n  json.video_id talk.video_id\n  json.video_provider talk.video_provider\n  json.slug talk.slug\n  json.static_id talk.static_id\n\n  json.event do\n    json.slug talk.event&.slug\n    json.name talk.event&.name\n    json.url talk.event ? event_url(talk.event) : nil\n  end\n\n  json.speakers talk.speakers do |speaker|\n    json.slug speaker.slug\n    json.name speaker.name\n    json.url profile_url(speaker)\n  end\nend\n\njson.pagination do\n  json.current_page @pagy.page\n  json.total_pages @pagy.pages\n  json.total_count @pagy.count\n  json.next_page @pagy.next\n  json.prev_page @pagy.prev\nend\n"
  },
  {
    "path": "app/views/talks/new.html.erb",
    "content": "<div class=\"mx-auto md:w-2/3 w-full\">\n  <h1 class=\"font-bold text-4xl\">New talk</h1>\n\n  <%= render \"form\", talk: @talk %>\n\n  <%= link_to \"Back to talks\", talks_path, class: \"ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium\" %>\n</div>\n"
  },
  {
    "path": "app/views/talks/recommendations/index.html.erb",
    "content": "<%= turbo_frame_tag \"recommended_talks\" do %>\n  <div data-turbo-temporary data-controller=\"transition\" class=\"hidden\" data-transition-enter-after-value=\"0\">\n    <%= render partial: \"talks/card_horizontal\",\n          collection: @talks,\n          as: :talk,\n          locals: {compact: true,\n                   user_watched_talks: user_watched_talks} %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/show.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<div class=\"container my-8 w-full flex flex-col gap-4\">\n  <% back_path = params[:back_to].presence || talks_path %>\n  <% back_to_title = params[:back_to_title].presence || \"Talks\" %>\n\n  <div class=\"w-full flex\">\n    <div class=\"flex-grow min-w-0 overflow-hidden\">\n      <div class=\"flex items-center justify-between w-full hotwire-native:hidden\">\n        <%= link_to sanitize_url(back_path, fallback: talks_path) do %>\n          <div class=\"flex items-center gap-2 title text-base text-primary mb-4\">\n            <%= fa(\"arrow-left-long\", class: \"transition-arrow fill-primary\", size: :xs) %>\n            <div><%= back_to_title %></div>\n          </div>\n        <% end %>\n      </div>\n\n      <%= turbo_frame_tag \"talk\", target: \"_top\", data: {turbo_action: \"advance\"} do %>\n        <% cache [@talk, Current.user].compact do %>\n          <%= render partial: \"talks/talk\", locals: {talk: @talk, speakers: @speakers, user_favorite_talks_ids: @user_favorite_talks_ids, favorite_users: @favorite_users} %>\n        <% end %>\n      <% end %>\n\n      <% cache @talk.event do %>\n        <%= render partial: \"talks/explore_event\", locals: {event: @talk.event} %>\n      <% end %>\n    </div>\n\n    <%= turbo_stream_from [@talk.event, :talks] %>\n\n    <div class=\"gap-4 w-96 flex-shrink-0 hidden lg:flex lg:flex-col px-4\" data-turbo-permanent=\"true\" id=\"<%= dom_id(@talk.event, :talks_wrapper) %>\">\n      <%= link_to @talk.event.name, event_path(@talk.event), class: \"pl-2 mt-8 text-neutral text-base text-lg font-bold hover:underline\" %>\n      <%= turbo_frame_tag dom_id(@talk.event, :talks), src: event_related_talks_path(@talk.event, active_talk: @talk), loading: \"lazy\" %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/show.json.jbuilder",
    "content": "json.talk do\n  json.slug @talk.slug\n  json.title @talk.title\n  json.original_title @talk.original_title\n  json.description @talk.description\n  json.summary @talk.summary\n  json.date @talk.date\n  json.kind @talk.kind\n  json.video_provider @talk.video_provider\n  json.video_id @talk.video_id\n  json.slides_url @talk.slides_url\n\n  if @talk.event.present?\n    json.event do\n      json.slug @talk.event.slug\n      json.name @talk.event.name\n      json.start_date @talk.event.start_date\n      json.end_date @talk.event.end_date\n\n      if @talk.event.series.present?\n        json.series do\n          json.id @talk.event.series.id\n          json.name @talk.event.series.name\n          json.slug @talk.event.series.slug\n        end\n      end\n    end\n  end\n\n  json.speakers @talk.speakers do |user|\n    json.id user.id\n    json.name user.name\n    json.slug user.slug\n    json.bio user.bio\n    json.avatar_url user.avatar_url\n  end\n\n  json.topics @talk.approved_topics do |topic|\n    json.id topic.id\n    json.name topic.name\n    json.slug topic.slug\n  end\n\n  json.transcript do\n    json.raw @talk.raw_transcript\n    json.enhanced @talk.enhanced_transcript\n  end\n\n  json.created_at @talk.created_at\n  json.updated_at @talk.updated_at\nend\n"
  },
  {
    "path": "app/views/talks/slides/show.html.erb",
    "content": "<%= turbo_frame_tag dom_id(@talk, :slides) do %>\n  <% if @talk.slides_url.present? %>\n    <% uri = URI(@talk.slides_url) %>\n    <% cache [@talk.slides_url] do %>\n      <% if [\"speakerdeck.com\", \"www.speakerdeck.com\"].include?(uri.host) %>\n        <% oembed_url = URI(\"https://speakerdeck.com/oembed.json?url=#{@talk.slides_url}\") %>\n        <% oembed_json = begin\n             JSON.parse(Net::HTTP.get(oembed_url))\n           rescue\n             {}\n           end %>\n\n        <div class=\"responsive-iframe-container\">\n          <%= sanitize oembed_json.dig(\"html\"), tags: [\"iframe\"], attributes: [\"id\", \"class\", \"src\", \"width\", \"height\", \"style\", \"frameborder\", \"allowtransparency\", \"allowfullscreen\"] %>\n        </div>\n      <% end %>\n    <% end %>\n\n    <a class=\"btn btn-primary mt-6\" href=\"<%= sanitize(@talk.slides_url) %>\" target=\"_blank\">See Slides on <%= uri.host %></a>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/video_providers/_children.html.erb",
    "content": "<%# locals: (talk:, video_provider:, video_id:, is_watched: false) %>\n\n<div class=\"relative w-full h-full block max-w-full\">\n  <%= image_tag talk.thumbnail_xl, class: \"w-full h-full object-cover rounded-xl #{talk.thumbnail_classes}\" %>\n\n  <div class=\"absolute inset-0 text-white bg-black/70 flex flex-col gap-3 justify-center items-center text-xl rounded-xl p-6 overflow-y-scroll\">\n    <span class=\"text-center text-2xl p-4 rounded-full mb-2 font-bold\">\n      <%= talk.title %>\n    </span>\n\n    <%= render partial: \"talks/sections\", locals: {talk: talk} %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/video_providers/_mp4.html.erb",
    "content": "<%# locals: (talk:, video_provider:, video_id:, is_watched: false) %>\n\n<div data-video-player-target=\"playerWrapper\" class=\"w-full max-w-full\">\n  <div class=\"picture-in-picture-container w-full max-w-full\" style=\"view-transition-name: <%= dom_id(talk, :image) %>\">\n    <video id=\"player\" class=\"rounded-xl w-full\" data-video-player-target=\"player\" src=\"<%= talk.provider_url %>\"></video>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/video_providers/_not_published.html.erb",
    "content": "<%# locals: (talk:, video_provider:, video_id:, is_watched: false) %>\n\n<div class=\"relative w-full h-full block max-w-full\">\n  <%= image_tag talk.thumbnail_xl, class: \"w-full h-full object-cover rounded-xl #{talk.thumbnail_classes}\" %>\n\n  <div class=\"absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 text-center text-white bg-gradient-to-t from-black/80 via-black/50 to-black/30 rounded-xl\">\n    <div class=\"p-4 bg-white/20 backdrop-blur-sm rounded-full\">\n      <%= fa(\"upload\", size: :xl, class: \"fill-white\") %>\n    </div>\n\n    <div class=\"flex flex-col gap-1\">\n      <div class=\"text-lg font-semibold\">Not Published Yet</div>\n      <div class=\"text-sm text-white/80\">This <%= talk.kind.humanize.downcase %> was recorded but hasn't been released</div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/video_providers/_not_recorded.html.erb",
    "content": "<%# locals: (talk:, video_provider:, video_id:, is_watched: false) %>\n\n<div class=\"relative w-full h-full block max-w-full\">\n  <%= image_tag talk.thumbnail_xl, class: \"w-full h-full object-cover rounded-xl #{talk.thumbnail_classes}\" %>\n\n  <div class=\"absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 text-center text-white bg-gradient-to-t from-black/80 via-black/50 to-black/30 rounded-xl\">\n    <div class=\"p-4 bg-white/20 backdrop-blur-sm rounded-full\">\n      <%= fa(\"video-slash\", size: :xl, class: \"fill-white\") %>\n    </div>\n\n    <div class=\"flex flex-col gap-1\">\n      <div class=\"text-lg font-semibold\">Not Recorded</div>\n      <div class=\"text-sm text-white/80\">Unfortunately, this <%= talk.kind.humanize.downcase %> wasn't recorded</div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/video_providers/_scheduled.html.erb",
    "content": "<%# locals: (talk:, video_provider:, video_id:, is_watched: false) %>\n\n<div class=\"relative w-full h-full block max-w-full\">\n  <%= image_tag talk.thumbnail_xl, class: \"w-full h-full object-cover rounded-xl #{talk.thumbnail_classes}\" %>\n\n  <div class=\"absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 text-center text-white bg-gradient-to-t from-black/80 via-black/50 to-black/30 rounded-xl\">\n    <div class=\"p-4 bg-white/20 backdrop-blur-sm rounded-full\">\n      <%= fa(\"clock\", size: :xl, class: \"fill-white\") %>\n    </div>\n\n    <div class=\"flex flex-col gap-1\">\n      <div class=\"text-lg font-semibold\">\n        <% if talk.date.past? %>\n          <%= talk.formatted_kind.capitalize %> was held\n        <% else %>\n          Scheduled\n        <% end %>\n      </div>\n      <div class=\"text-sm text-white/80\">\n        <%= talk.event.name %>\n        <% if talk.to_location.present? && !talk.location.in?([\"Earth\", \"online\", \"Online\"]) %>\n          · <%= talk.to_location.to_html(show_links: false) %>\n        <% end %>\n        · <%= talk.formatted_date %>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/video_providers/_video_unavailable.html.erb",
    "content": "<%# locals: (talk:, video_provider:, video_id:, is_watched: false) %>\n\n<div class=\"relative w-full h-full block max-w-full\">\n  <%= image_tag talk.thumbnail_xl, class: \"w-full h-full object-cover rounded-xl\" %>\n\n  <div class=\"absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 text-center text-white bg-gradient-to-t from-black/80 via-black/50 to-black/30 rounded-xl\">\n    <div class=\"p-4 bg-white/20 backdrop-blur-sm rounded-full\">\n      <%= fa(\"video-slash\", size: :xl, class: \"fill-white\") %>\n    </div>\n\n    <div class=\"flex flex-col gap-1\">\n      <div class=\"text-lg font-semibold\">Video Unavailable</div>\n      <div class=\"text-sm text-white/80\">\n        This video is no longer available on <%= video_provider.humanize %>\n\n        <% if talk.video_unavailable_at.present? %>\n          as of <%= talk.video_unavailable_at.to_date.to_fs(:long) %>\n        <% end %>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/video_providers/_vimeo.html.erb",
    "content": "<%# locals: (talk:, video_provider:, video_id:, is_watched: false) %>\n\n<div data-video-player-target=\"playerWrapper\" class=\"w-full max-w-full\">\n  <div class=\"picture-in-picture-container w-full max-w-full\" style=\"view-transition-name: <%= dom_id(talk, :image) %>\">\n    <div\n      class=\"image rounded-xl w-full\"\n      id=\"<%= dom_id(talk, :vimeo) %>\"\n      data-video-player-target=\"player\"\n      data-vimeo-id=\"<%= video_id %>\"\n      data-vimeo-start-time=\"<%= is_watched ? nil : talk.start_seconds %>\"\n      data-vimeo-end-time=\"<%= talk.end_seconds %>\">\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/video_providers/_youtube.html.erb",
    "content": "<%# locals: (talk:, video_provider:, video_id:, is_watched: false) %>\n\n<div data-video-player-target=\"playerWrapper\" class=\"w-full max-w-full\">\n  <div class=\"picture-in-picture-container w-full max-w-full\" style=\"view-transition-name: <%= dom_id(talk, :image) %>\">\n    <div\n      class=\"image rounded-xl w-full\"\n      id=\"<%= dom_id(talk, :youtube) %>\"\n      data-video-player-target=\"player\"\n      data-youtube-id=\"<%= video_id %>\">\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/watched_talks/_button.html.erb",
    "content": "<%# locals: (talk:, is_watched:) %>\n\n<% if is_watched %>\n  <%= ui_tooltip \"Mark talk as unwatched\" do %>\n    <%= ui_button url: talk_watched_talk_path(talk), method: :delete, kind: :pill, data: {turbo_confirm: \"Mark this talk as unwatched? Your feedback will be deleted.\"} do %>\n      <%= fa(\"circle-check\", size: :xs, style: :solid, class: \"fill-green-700\") %>\n      <span class=\"text-xs text-nowrap\">Watched</span>\n    <% end %>\n  <% end %>\n<% elsif talk.date.blank? || talk.date <= Date.current %>\n  <%= ui_tooltip \"Mark talk as watched\" do %>\n    <%= ui_button url: new_talk_watched_talk_path(talk), kind: :pill, data: {turbo_frame: \"modal\"} do %>\n      <%= fa(\"circle\", size: :xs, style: :regular) %>\n      <span class=\"text-xs text-nowrap\">Watched</span>\n    <% end %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/watched_talks/_feedback_banner.html.erb",
    "content": "<%# locals: (talk:, watched_talk:, form_open: false) %>\n\n<% has_rating_feedback = watched_talk&.has_rating_feedback? %>\n<% feedback_allowed = talk.feedback_allowed_for?(Current.user) %>\n<% has_watched_on = watched_talk&.watched_on.present? %>\n\n<div class=\"mt-4 p-4 bg-base-200/50 rounded-xl\" data-controller=\"collapsible collapsible-feedback\" data-collapsible-open-value=\"<%= !has_watched_on %>\" data-collapsible-feedback-open-value=\"<%= form_open %>\">\n  <div class=\"flex items-center justify-between flex-wrap gap-2\">\n    <div class=\"flex items-center gap-2\">\n      <%= fa(\"circle-check\", size: :sm, style: :solid, class: \"text-green-600\") %>\n      <span class=\"font-medium\"><% if watched_talk&.watched_on == \"another_version\" %>You watched another version of this talk!<% elsif watched_talk&.watched_on == \"in_person\" %>You watched this talk in-person<% if watched_talk&.watched_at %> on <%= watched_talk.watched_at.strftime(\"%B %-d, %Y\") %><% end %>!<% else %>You watched this talk<% if watched_talk&.watched_on.present? && watched_talk.watched_on != \"other\" %> on <%= WatchedTalk::WATCHED_ON_OPTIONS.dig(watched_talk.watched_on, :label) || watched_talk.watched_on.titleize %><% end %><% if watched_talk&.watched_at %> on <%= watched_talk.watched_at.strftime(\"%B %-d, %Y\") %><% end %>!<% end %></span>\n    </div>\n\n    <div class=\"flex items-center gap-2\">\n      <% if has_watched_on %>\n        <button type=\"button\" class=\"btn btn-sm bg-white border border-gray-300 hover:bg-gray-100\" data-action=\"click->collapsible#toggle click->collapsible-feedback#close\" data-collapsible-target=\"trigger\">\n          <%= fa(\"pen-to-square\", size: :xs, class: \"mr-1\") %>\n          Change\n        </button>\n      <% end %>\n\n      <% if feedback_allowed %>\n        <button type=\"button\" class=\"btn btn-sm btn-primary\" data-action=\"click->collapsible#close click->collapsible-feedback#toggle\" data-collapsible-feedback-target=\"trigger\">\n          <%= fa(\"star\", size: :xs, class: \"mr-1\") %>\n          <%= has_rating_feedback ? \"Update Feedback\" : \"Share Feedback\" %>\n        </button>\n      <% end %>\n    </div>\n  </div>\n\n  <div class=\"mt-4 <%= has_watched_on ? \"hidden\" : \"\" %>\" data-collapsible-target=\"content\">\n    <%= turbo_frame_tag dom_id(talk, :where_watched) do %>\n      <%= render partial: \"talks/watched_talks/where_watched\", locals: {talk: talk, watched_talk: watched_talk} %>\n    <% end %>\n  </div>\n\n  <% if feedback_allowed %>\n    <div class=\"mt-4 <%= form_open ? \"\" : \"hidden\" %>\" data-collapsible-feedback-target=\"content\">\n      <%= turbo_frame_tag dom_id(talk, :feedback_form) do %>\n        <%= render partial: \"talks/watched_talks/feedback_questions\", locals: {talk: talk, watched_talk: watched_talk} %>\n      <% end %>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/talks/watched_talks/_feedback_questions.html.erb",
    "content": "<%# locals: (talk:, watched_talk:) %>\n\n<% update_path = talk_watched_talk_path(talk) %>\n<% is_selected = ->(field, value) { watched_talk.send(field).to_s == value.to_s } %>\n\n<div class=\"space-y-6\">\n  <div>\n    <label class=\"text-sm font-medium text-gray-700 mb-3 block\">How did it make you feel?</label>\n\n    <div class=\"grid grid-cols-4 sm:grid-cols-8 gap-2\">\n      <% WatchedTalk::FEELING_OPTIONS.each do |key, option| %>\n        <% selected = watched_talk.feeling == key %>\n\n        <%= button_to update_path, method: :patch, class: \"contents\", params: {watched_talk: {feeling: selected ? nil : key}} do %>\n          <div class=\"flex flex-col items-center justify-center p-2 border-2 rounded-lg cursor-pointer transition-colors <%= selected ? option[:selected_class] : \"bg-white hover:bg-gray-50\" %>\">\n            <%= fa(option[:emoji], size: :lg, class: \"mb-1 #{\"fill-white\" if selected}\") %>\n            <span class=\"text-xs text-center\"><%= option[:label] %></span>\n          </div>\n        <% end %>\n      <% end %>\n    </div>\n  </div>\n\n  <hr class=\"my-4\">\n\n  <div>\n    <label class=\"text-sm font-medium text-gray-700 mb-3 block\">What level of experience do you think is needed?</label>\n\n    <div class=\"grid grid-cols-3 gap-2\">\n      <% WatchedTalk::EXPERIENCE_LEVELS.each do |key, level| %>\n        <% selected = watched_talk.experience_level == key %>\n\n        <%= button_to update_path, method: :patch, class: \"contents\", params: {watched_talk: {experience_level: selected ? nil : key}} do %>\n          <div class=\"flex flex-col items-center justify-center p-3 border-2 rounded-lg cursor-pointer transition-colors <%= selected ? \"border-blue-500 bg-blue-500 text-white hover:bg-blue-600\" : \"bg-white hover:bg-gray-50\" %>\">\n            <%= fa(level[:icon], size: :lg, class: \"mb-1 #{\"fill-white\" if selected}\") %>\n            <span class=\"text-sm font-medium\"><%= level[:label] %></span>\n            <span class=\"text-xs <%= selected ? \"text-blue-100\" : \"text-gray-500\" %>\"><%= level[:description] %></span>\n          </div>\n        <% end %>\n      <% end %>\n    </div>\n  </div>\n\n  <hr class=\"my-4\">\n\n  <div>\n    <label class=\"text-sm font-medium text-gray-700 mb-3 block\">How would you describe the content?</label>\n\n    <div class=\"grid grid-cols-3 gap-2\">\n      <% WatchedTalk::CONTENT_FRESHNESS.each do |key, level| %>\n        <% selected = watched_talk.content_freshness == key %>\n\n        <%= button_to update_path, method: :patch, class: \"contents\", params: {watched_talk: {content_freshness: selected ? nil : key}} do %>\n          <div class=\"flex flex-col items-center justify-center p-3 border-2 rounded-lg cursor-pointer transition-colors <%= selected ? \"border-green-500 bg-green-500 text-white hover:bg-green-600\" : \"bg-white hover:bg-gray-50\" %>\">\n            <%= fa(level[:icon], size: :lg, class: \"mb-1 #{\"fill-white\" if selected}\") %>\n            <span class=\"text-sm font-medium\"><%= level[:label] %></span>\n            <span class=\"text-xs <%= selected ? \"text-green-100\" : \"text-gray-500\" %>\"><%= level[:description] %></span>\n          </div>\n        <% end %>\n      <% end %>\n    </div>\n  </div>\n\n  <hr class=\"my-4\">\n\n  <div>\n    <label class=\"text-sm font-medium text-gray-700 mb-3 block\">Feedback</label>\n\n    <div class=\"space-y-3\">\n      <% WatchedTalk::FEEDBACK_QUESTIONS.each do |key, question| %>\n        <div class=\"flex items-center justify-between p-2 -mx-2 rounded-lg hover:bg-base-200 transition-colors\">\n          <span class=\"text-sm flex items-center gap-2\">\n            <%= fa(question[:icon], size: :sm, class: \"text-gray-400\") %>\n            <%= question[:label] %>\n          </span>\n\n          <div class=\"flex\">\n            <% yes_selected = is_selected.call(key, true) %>\n            <% no_selected = is_selected.call(key, false) %>\n\n            <%= button_to update_path, method: :patch, class: \"contents\", params: {watched_talk: {key => yes_selected ? nil : true}} do %>\n              <div class=\"px-3 py-1 text-sm border rounded-l-lg cursor-pointer <%= yes_selected ? \"bg-green-500 text-white border-green-500 hover:bg-green-600\" : \"bg-white hover:bg-green-100\" %>\">\n                Yes\n              </div>\n            <% end %>\n\n            <%= button_to update_path, method: :patch, class: \"contents\", params: {watched_talk: {key => no_selected ? nil : false}} do %>\n              <div class=\"px-3 py-1 text-sm border rounded-r-lg cursor-pointer <%= no_selected ? \"bg-red-500 text-white border-red-500 hover:bg-red-600\" : \"bg-white hover:bg-red-100\" %>\">\n                No\n              </div>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/watched_talks/_form.html.erb",
    "content": "<%# locals: (talk:, watched_talk:, inline: false) %>\n\n<div class=\"space-y-6\">\n  <%= render partial: \"talks/watched_talks/where_watched\", locals: {talk: talk, watched_talk: watched_talk} %>\n\n  <% if talk.feedback_allowed_for?(Current.user) %>\n    <hr class=\"my-4\">\n    <%= render partial: \"talks/watched_talks/feedback_questions\", locals: {talk: talk, watched_talk: watched_talk} %>\n  <% end %>\n</div>\n\n<% unless inline %>\n  <% form_options = {model: watched_talk, url: talk_watched_talk_path(talk), method: :patch} %>\n\n  <%= form_with(**form_options) do |form| %>\n    <div class=\"flex items-center gap-4 justify-end mt-6\">\n      <%= ui_button \"Cancel\", data: {action: \"click->modal#close\"}, role: :button, kind: :ghost %>\n      <%= ui_button watched_talk.persisted? ? \"Update\" : \"Mark as Watched\", type: :submit %>\n    </div>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/watched_talks/_watched_overlay.html.erb",
    "content": "<%# locals: (talk:) %>\n\n<div class=\"absolute inset-0 cursor-pointer group/watched\" data-video-player-target=\"watchedOverlay\" data-action=\"click->video-player#dismissWatchedOverlay\">\n  <%= image_tag talk.thumbnail_xl, class: \"absolute inset-0 w-full h-full object-cover rounded-xl opacity-60\", style: \"view-transition-name: #{dom_id(talk, :image)}\" %>\n  <div class=\"absolute inset-0 bg-gradient-to-t from-black/80 via-black/40 to-black/20 rounded-xl\"></div>\n  <div class=\"absolute inset-0 bg-gradient-to-t from-black/60 via-black/20 to-transparent rounded-xl opacity-0 group-hover/watched:opacity-100 transition-opacity duration-300\"></div>\n  <div class=\"absolute inset-0 flex flex-col items-center justify-center gap-3 p-6 text-center text-white\">\n    <div class=\"p-4 bg-white/20 backdrop-blur-sm rounded-full group-hover/watched:bg-white/30 group-hover/watched:scale-105 transition-all duration-300\">\n      <%= fa(\"rotate-right\", size: :xl, class: \"fill-white\") %>\n    </div>\n\n    <div class=\"flex flex-col gap-1\">\n      <div class=\"text-lg font-semibold\">Watch Again</div>\n      <div class=\"text-sm text-white/80 flex items-center justify-center gap-1\">\n        <%= fa(\"circle-check\", size: :xs, style: :solid, class: \"fill-green-400\") %>\n        Watched\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/watched_talks/_where_watched.html.erb",
    "content": "<%# locals: (talk:, watched_talk:) %>\n\n<% update_path = talk_watched_talk_path(talk) %>\n\n<div>\n  <label class=\"text-sm font-medium text-gray-700 mb-3 block\">Where did you watch?</label>\n\n  <div class=\"grid grid-cols-2 sm:grid-cols-5 gap-2 auto-rows-fr\">\n    <% WatchedTalk.watched_on_options_for(talk).each do |key, option| %>\n      <% selected = watched_talk&.watched_on == key %>\n      <% watched_at = (key == \"in_person\" && talk.date) ? talk.date.to_date : nil %>\n\n      <%= button_to update_path, method: :patch, class: \"contents\", data: {turbo_stream: true}, params: {watched_talk: {watched_on: selected ? nil : key, watched_at: watched_at}.compact} do %>\n        <div class=\"flex flex-col items-center justify-center p-3 border-2 rounded-lg cursor-pointer transition-colors h-full <%= selected ? \"border-red-500 bg-red-500 text-white hover:bg-red-600\" : \"bg-white hover:bg-gray-50\" %>\">\n          <%= fa(option[:icon], size: :lg, class: class_names(\"mb-1\", \"fill-white\": selected)) %>\n          <span class=\"text-xs text-center leading-tight\"><%= option[:label] %></span>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/watched_talks/create.turbo_stream.erb",
    "content": "<%\n  video_provider = case @talk.video_provider\n  when \"mp4\" then \"mp4\"\n  when \"parent\" then @talk.parent_talk.video_provider\n  else @talk.video_provider\n  end\n\n  video_provider = @talk.video_provider if @talk.parent_talk&.video_provider == \"children\"\n  video_id = (@talk.video_provider == \"parent\") ? @talk.parent_talk.video_id : @talk.video_id\n%>\n\n<%= turbo_stream.update \"modal\" do %>\n<% end %>\n\n<%= turbo_stream.update dom_id(@talk, :video_player) do %>\n  <%= render partial: \"talks/video_player\", locals: {talk: @talk, current_user_watched_talk: @watched_talk, is_watched: true, video_provider: video_provider, video_id: video_id} %>\n<% end %>\n\n<%= turbo_stream.update dom_id(@talk, :feedback_banner) do %>\n  <%= render partial: \"talks/watched_talks/feedback_banner\", locals: {talk: @talk, watched_talk: @watched_talk} %>\n<% end %>\n\n<%= turbo_stream.update dom_id(@talk, :watched_button) do %>\n  <%= render partial: \"talks/watched_talks/button\", locals: {talk: @talk, is_watched: true} %>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/watched_talks/destroy.turbo_stream.erb",
    "content": "<%\n  video_provider = case @talk.video_provider\n  when \"mp4\" then \"mp4\"\n  when \"parent\" then @talk.parent_talk.video_provider\n  else @talk.video_provider\n  end\n\n  video_provider = @talk.video_provider if @talk.parent_talk&.video_provider == \"children\"\n  video_id = (@talk.video_provider == \"parent\") ? @talk.parent_talk.video_id : @talk.video_id\n%>\n\n<%= turbo_stream.update dom_id(@talk, :video_player) do %>\n  <%= render partial: \"talks/video_player\", locals: {talk: @talk, current_user_watched_talk: nil, is_watched: false, video_provider: video_provider, video_id: video_id} %>\n<% end %>\n\n<%= turbo_stream.update dom_id(@talk, :feedback_banner) do %>\n<% end %>\n\n<%= turbo_stream.update dom_id(@talk, :watched_button) do %>\n  <%= render partial: \"talks/watched_talks/button\", locals: {talk: @talk, is_watched: false} %>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/watched_talks/new.html.erb",
    "content": "<div class=\"space-y-4\">\n  <h3 class=\"text-lg font-semibold\">Mark as Watched</h3>\n  <p class=\"text-sm text-gray-600\">Where did you watch this talk?</p>\n\n  <div class=\"grid grid-cols-2 sm:grid-cols-5 gap-2 auto-rows-fr\">\n    <% WatchedTalk.watched_on_options_for(@talk).each do |key, option| %>\n      <% watched_at = (key == \"in_person\" && @talk.date) ? @talk.date.to_date : nil %>\n\n      <%= button_to talk_watched_talk_path(@talk), method: :post, class: \"contents\", params: {watched_talk: {watched_on: key, watched_at: watched_at}.compact} do %>\n        <div class=\"flex flex-col items-center justify-center p-3 border-2 rounded-lg cursor-pointer transition-colors h-full hover:bg-gray-50 hover:border-gray-300\">\n          <%= fa(option[:icon], size: :lg, class: \"mb-1\") %>\n          <span class=\"text-xs text-center leading-tight\"><%= option[:label] %></span>\n        </div>\n      <% end %>\n    <% end %>\n  </div>\n\n  <div class=\"flex justify-end pt-2\">\n    <%= button_to talk_watched_talk_path(@talk), method: :post, class: \"btn btn-sm btn-ghost\" do %>\n      Skip\n    <% end %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/talks/watched_talks/toggle_attendance.turbo_stream.erb",
    "content": "<%= turbo_stream.replace dom_id(@talk, :attendance) do %>\n  <% track_name = @talk.static_metadata&.track %>\n  <% tracks = @talk.event.schedule.exist? ? @talk.event.schedule.tracks : [] %>\n  <% track = track_name && tracks.find { |t| t[\"name\"] == track_name } %>\n  <% watched_talk = @talk.watched_talks.find_by(user: Current.user) %>\n\n  <%= render \"events/my_attendance_talk\",\n        talk: @talk,\n        track: track,\n        attended_in_person: @attended,\n        watched_online: @watched_online,\n        has_feedback: watched_talk&.has_rating_feedback? || false %>\n<% end %>\n"
  },
  {
    "path": "app/views/talks/watched_talks/update.turbo_stream.erb",
    "content": "<%= turbo_stream.update dom_id(@talk, :feedback_banner) do %>\n  <%= render partial: \"talks/watched_talks/feedback_banner\", locals: {talk: @talk, watched_talk: @watched_talk, form_open: @form_open} %>\n<% end %>\n\n<%= turbo_stream.update dom_id(@talk, :where_watched) do %>\n  <%= render partial: \"talks/watched_talks/where_watched\", locals: {talk: @talk, watched_talk: @watched_talk} %>\n<% end %>\n"
  },
  {
    "path": "app/views/templates/_talk_fields.html.erb",
    "content": "<div\n  id=\"child_<%= index %>\"\n  class=\"card bg-base-100 border border-gray-200 mb-4\">\n  <div class=\"card-body p-4\">\n    <div class=\"flex justify-between items-center mb-4\">\n      <h4 class=\"font-semibold\">Talk</h4>\n      <%= link_to \"Remove\",\n            delete_child_templates_path(index: index),\n            data: {\n              turbo_method: :delete\n            },\n            class: \"btn btn-outline btn-error btn-xs\" %>\n    </div>\n\n    <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n      <div class=\"form-control\">\n        <%= form.label :title, \"Title *\", class: \"label\" %>\n        <%= form.text_field :title,\n              class:\n                class_names(\n                  \"input input-bordered w-full\",\n                  \"input-error\": form.object.errors[:title].any?\n                ),\n              placeholder: \"e.g., Introducing Type Guard to Steep\" %>\n        <% if form.object.errors[:title].any? %>\n          <div class=\"label\">\n            <span class=\"label-text-alt text-error\"><%= form.object.errors[:title].join(\", \") %></span>\n          </div>\n        <% end %>\n      </div>\n\n      <div class=\"form-control\">\n        <%= form.label :event_name, \"Event Name *\", class: \"label\" %>\n        <%= form.text_field :event_name,\n              class:\n                class_names(\n                  \"input input-bordered w-full\",\n                  \"input-error\": form.object.errors[:event_name].any?\n                ),\n              placeholder: \"e.g., RubyKaigi 2025\" %>\n        <% if form.object.errors[:event_name].any? %>\n          <div class=\"label\">\n            <span class=\"label-text-alt text-error\"><%= form.object.errors[:event_name].join(\", \") %></span>\n          </div>\n        <% end %>\n      </div>\n\n      <div class=\"form-control\">\n        <%= form.label :speakers, \"Speakers\", class: \"label\" %>\n        <!-- Using combobox tag here because form.combobox doesn't generate the right ID for some reason -->\n        <%= combobox_tag \"template[children_attributes][#{index}][speakers]\",\n              async_src: speakers_search_templates_path,\n              multiselect_chip_src: speakers_search_chips_templates_path,\n              name_when_new: \"template[children_attributes][#{index}][speakers]\",\n              free_text: true,\n              placeholder: \"Search or add speakers...\" %>\n      </div>\n\n      <div class=\"form-control\">\n        <%= form.label :date, \"Date\", class: \"label\" %>\n        <%= form.date_field :date,\n              class:\n                class_names(\n                  \"input input-bordered w-full\",\n                  \"input-error\": form.object.errors[:date].any?\n                ) %>\n        <% if form.object.errors[:date].any? %>\n          <div class=\"label\">\n            <span class=\"label-text-alt text-error\"><%= form.object.errors[:date].join(\", \") %></span>\n          </div>\n        <% end %>\n      </div>\n\n      <div class=\"form-control\">\n        <%= form.label :published_at, \"Published At\", class: \"label\" %>\n        <%= form.date_field :published_at,\n              class:\n                class_names(\n                  \"input input-bordered w-full\",\n                  \"input-error\": form.object.errors[:published_at].any?\n                ) %>\n        <% if form.object.errors[:published_at].any? %>\n          <div class=\"label\">\n            <span class=\"label-text-alt text-error\"><%= form.object.errors[:published_at].join(\", \") %></span>\n          </div>\n        <% end %>\n      </div>\n\n      <div class=\"form-control mt-4\">\n        <%= form.label :slides_url, \"Slides URL\", class: \"label\" %>\n        <%= form.url_field :slides_url,\n              class: \"input input-bordered w-full\",\n              placeholder: \"https://...\" %>\n      </div>\n\n      <div class=\"form-control\">\n        <%= form.label :video_provider, \"Video Provider\", class: \"label\" %>\n        <%= form.select :video_provider,\n              ::Template::VIDEO_PROVIDERS.map { [it, it.squish.underscore] },\n              {prompt: \"Select provider...\"},\n              {class: \"select select-bordered w-full\"} %>\n      </div>\n\n      <div class=\"form-control\">\n        <%= form.label :video_id, \"Video ID\", class: \"label\" %>\n        <%= form.text_field :video_id,\n              class: \"input input-bordered w-full\",\n              placeholder: \"e.g., kp_jeGkUmhY\" %>\n      </div>\n\n      <div class=\"form-control\">\n        <%= form.label :start_cue, \"Start Time\", class: \"label\" %>\n        <%= form.time_field :start_cue,\n              class: \"input input-bordered w-full\",\n              placeholder: \"e.g., 02:00\" %>\n      </div>\n\n      <div class=\"form-control\">\n        <%= form.label :end_cue, \"End Time\", class: \"label\" %>\n        <%= form.time_field :end_cue,\n              class: \"input input-bordered w-full\",\n              placeholder: \"e.g., 30:00\" %>\n      </div>\n    </div>\n\n    <div class=\"form-control mt-4\">\n      <%= form.label :description, \"Description\", class: \"label\" %>\n      <%= form.text_area :description,\n            class: \"textarea textarea-bordered w-full\",\n            rows: 3,\n            placeholder: \"Talk or event description...\" %>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/templates/create.turbo_stream.erb",
    "content": "<%= turbo_stream.replace @talk do %>\n  <%= render \"new\", talk: @talk %>\n<% end %>\n"
  },
  {
    "path": "app/views/templates/delete_child.turbo_stream.erb",
    "content": "<%= turbo_stream.remove \"child_#{params[:index]}\" %>\n"
  },
  {
    "path": "app/views/templates/new.html.erb",
    "content": "<div class=\"container py-8\">\n  <h1 class=\"text-3xl font-bold mb-6\">YAML Template Generator</h1>\n  <p class=\"text-gray-600 mb-8\">Generate YAML templates for adding new talks and events to the Ruby Events\n    database.</p>\n\n  <%= turbo_frame_tag @talk do %>\n    <%= form_with model: @talk do |form| %>\n\n      <div class=\"space-y-6\">\n        <div class=\"card bg-base-100 shadow-sm\">\n          <div class=\"card-body\">\n            <h2 class=\"card-title text-lg mb-4\">Required</h2>\n\n            <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n              <div class=\"form-control\">\n                <%= form.label :title, \"Title *\", class: \"label\" %>\n                <%= form.text_field :title,\n                      class:\n                        class_names(\n                          \"input input-bordered w-full\",\n                          \"input-error\": @talk.errors[:title].any?\n                        ),\n                      placeholder: \"e.g., Introducing Type Guard to Steep\" %>\n                <% if @talk.errors[:title].any? %>\n                  <div class=\"label\">\n                    <span class=\"label-text-alt text-error\"><%= @talk.errors[:title].join(\", \") %></span>\n                  </div>\n                <% end %>\n              </div>\n\n              <div class=\"form-control\">\n                <%= form.label :event_name, \"Event Name *\", class: \"label\" %>\n                <%= form.text_field :event_name,\n                      class:\n                        class_names(\n                          \"input input-bordered w-full\",\n                          \"input-error\": @talk.errors[:event_name].any?\n                        ),\n                      placeholder: \"e.g., RubyKaigi 2025\" %>\n                <% if @talk.errors[:event_name].any? %>\n                  <div class=\"label\">\n                    <span class=\"label-text-alt text-error\"><%= @talk.errors[:event_name].join(\", \") %></span>\n                  </div>\n                <% end %>\n              </div>\n\n              <div class=\"form-control\">\n                <%= form.label :date, \"Date *\", class: \"label\" %>\n                <%= form.date_field :date,\n                      class:\n                        class_names(\n                          \"input input-bordered w-full\",\n                          \"input-error\": @talk.errors[:date].any?\n                        ) %>\n                <% if @talk.errors[:date].any? %>\n                  <div class=\"label\">\n                    <span class=\"label-text-alt text-error\"><%= @talk.errors[:date].join(\", \") %></span>\n                  </div>\n                <% end %>\n              </div>\n\n              <div class=\"form-control\">\n                <%= form.label :speakers, \"Speakers\", class: \"label\" %>\n                <%= form.combobox :speakers,\n                      speakers_search_templates_path,\n                      multiselect_chip_src: speakers_search_chips_templates_path,\n                      name_when_new: \"template[speakers]\",\n                      free_text: true,\n                      class: \"w-full\" %>\n              </div>\n            </div>\n\n            <div class=\"form-control\">\n              <%= form.label :description, \"Description\", class: \"label\" %>\n              <%= form.text_area :description,\n                    class: \"textarea textarea-bordered w-full\",\n                    rows: 3,\n                    placeholder: \"Talk or event description...\" %>\n            </div>\n          </div>\n        </div>\n        <!-- Optional Fields - Collapsible -->\n        <div class=\"collapse collapse-arrow bg-base-100 shadow-sm\">\n          <input type=\"checkbox\" class=\"peer\">\n          <div class=\"collapse-title text-lg font-medium\">\n            Optional Fields\n          </div>\n          <div class=\"collapse-content\">\n            <div class=\"space-y-4\">\n              <div class=\"form-control\">\n                <%= form.label :raw_title, \"Raw Title\", class: \"label\" %>\n                <%= form.text_field :raw_title,\n                      class: \"input input-bordered w-full\",\n                      placeholder:\n                        \"e.g., [JA] Introducing Type Guard to Steep / Takeshi KOMIYA @tk0miya\" %>\n              </div>\n\n              <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n                <div class=\"form-control\">\n                  <%= form.label :published_at, \"Published At\", class: \"label\" %>\n                  <%= form.date_field :published_at, class: \"input input-bordered w-full\" %>\n                </div>\n\n                <div class=\"form-control\">\n                  <%= form.label :announced_at, \"Announced At\", class: \"label\" %>\n                  <%= form.date_field :announced_at, class: \"input input-bordered w-full\" %>\n                </div>\n              </div>\n\n              <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n                <div class=\"form-control\">\n                  <%= form.label :language, \"Language\", class: \"label\" %>\n                  <%= form.select :language,\n                        [\n                          %w[English english],\n                          %w[Japanese japanese],\n                          %w[Spanish spanish],\n                          %w[French french],\n                          %w[German german]\n                        ],\n                        {prompt: \"Select language...\"},\n                        {class: \"select select-bordered w-full\"} %>\n                </div>\n\n                <div class=\"form-control\">\n                  <%= form.label :track, \"Track/Room\", class: \"label\" %>\n                  <%= form.text_field :track,\n                        class: \"input input-bordered w-full\",\n                        placeholder: \"e.g., Main Stage, Room A\" %>\n                </div>\n              </div>\n\n              <div class=\"form-control\">\n                <%= form.label :slides_url, \"Slides URL\", class: \"label\" %>\n                <%= form.url_field :slides_url,\n                      class: \"input input-bordered w-full\",\n                      placeholder: \"https://...\" %>\n              </div>\n\n              <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n                <div class=\"form-control\">\n                  <%= form.label :thumbnail_xs, \"Thumbnail XS\", class: \"label\" %>\n                  <%= form.url_field :thumbnail_xs,\n                        class: \"input input-bordered w-full\",\n                        placeholder: \"https://...\" %>\n                </div>\n\n                <div class=\"form-control\">\n                  <%= form.label :thumbnail_sm, \"Thumbnail SM\", class: \"label\" %>\n                  <%= form.url_field :thumbnail_sm,\n                        class: \"input input-bordered w-full\",\n                        placeholder: \"https://...\" %>\n                </div>\n\n                <div class=\"form-control\">\n                  <%= form.label :thumbnail_md, \"Thumbnail MD\", class: \"label\" %>\n                  <%= form.url_field :thumbnail_md,\n                        class: \"input input-bordered w-full\",\n                        placeholder: \"https://...\" %>\n                </div>\n\n                <div class=\"form-control\">\n                  <%= form.label :thumbnail_lg, \"Thumbnail LG\", class: \"label\" %>\n                  <%= form.url_field :thumbnail_lg,\n                        class: \"input input-bordered w-full\",\n                        placeholder: \"https://...\" %>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n        <!-- Video Information - Collapsible -->\n        <div class=\"collapse collapse-arrow bg-base-100 shadow-sm\">\n          <input type=\"checkbox\" class=\"peer\">\n          <div class=\"collapse-title text-lg font-medium\">\n            Video Information\n          </div>\n          <div class=\"collapse-content\">\n            <div class=\"space-y-4\">\n              <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n                <div class=\"form-control\">\n                  <%= form.label :video_provider, \"Video Provider\", class: \"label\" %>\n                  <%= form.select :video_provider,\n                        ::Template::VIDEO_PROVIDERS.map { [it, it.squish.underscore] },\n                        {prompt: \"Select provider...\"},\n                        {class: \"select select-bordered w-full\"} %>\n                </div>\n\n                <div class=\"form-control\">\n                  <%= form.label :video_id, \"Video ID\", class: \"label\" %>\n                  <%= form.text_field :video_id,\n                        class: \"input input-bordered w-full\",\n                        placeholder: \"e.g., kp_jeGkUmhY\" %>\n                </div>\n              </div>\n\n              <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n                <div class=\"form-control\">\n                  <%= form.label :start_cue, \"Start Time\", class: \"label\" %>\n                  <%= form.time_field :start_cue,\n                        class: \"input input-bordered w-full\",\n                        placeholder: \"e.g., 02:00\" %>\n                </div>\n\n                <div class=\"form-control\">\n                  <%= form.label :end_cue, \"End Time\", class: \"label\" %>\n                  <%= form.time_field :end_cue,\n                        class: \"input input-bordered w-full\",\n                        placeholder: \"e.g., 30:00\" %>\n                </div>\n              </div>\n\n              <div class=\"form-control\">\n                <label class=\"label cursor-pointer justify-start\">\n                  <%= form.check_box :external_player, class: \"checkbox mr-3\" %>\n                  <span class=\"label-text\">External Player</span>\n                </label>\n              </div>\n\n              <div class=\"form-control\">\n                <%= form.label :external_player_url, \"External Player URL\", class: \"label\" %>\n                <%= form.url_field :external_player_url,\n                      class: \"input input-bordered w-full\",\n                      placeholder: \"https://...\" %>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <div class=\"card bg-base-100 shadow-sm\">\n          <div class=\"card-body\">\n            <h2 class=\"card-title text-lg mb-4\">Child Talks</h2>\n            <p class=\"text-sm text-gray-600 mb-4\">Add individual talks if this is a meetup or multi-talk event.</p>\n\n            <div id=\"children\" class=\"space-y-4 mb-4\">\n              <% @talk.children.each do |child| %>\n                <% index = Time.current.to_i %>\n                <%= fields_for \"template[children_attributes][]\", child, index: index do |form| %>\n                  <%= render \"talk_fields\", form: form, index: index %>\n                <% end %>\n              <% end %>\n            </div>\n\n            <%= link_to \"Add Talk\",\n                  new_child_templates_path,\n                  data: {\n                    turbo_method: :get,\n                    turbo_stream: true\n                  },\n                  class: \"btn btn-outline btn-lg w-full\" %>\n          </div>\n        </div>\n\n        <div class=\"card bg-base-100 shadow-sm\">\n          <div class=\"card-body\">\n            <%= form.submit \"Generate YAML\", class: \"btn btn-primary btn-lg w-full\" %>\n          </div>\n        </div>\n      </div>\n\n      <div class=\"mt-8\">\n        <div class=\"card bg-base-100 shadow-sm\">\n          <div class=\"card-body\">\n            <h2 class=\"card-title text-xl mb-4\">Generated YAML</h2>\n            <div class=\"bg-white rounded border p-4 min-h-[200px]\">\n              <% if @yaml.present? %>\n                <div\n                  class=\"relative\"\n                  data-controller=\"copy-to-clipboard\"\n                  data-copy-to-clipboard-success-class=\"scale-95\">\n                  <button\n                    class=\"\n                      btn btn-sm btn-outline absolute top-1 right-1 transition-transform duration-150\n                      ease-in-out\n                    \"\n                    data-action=\"click->copy-to-clipboard#copy\"\n                    data-copy-to-clipboard-target=\"button\">\n                    Copy\n                  </button>\n                  <pre\n                    class=\"\n                      text-sm font-mono text-gray-800 whitespace-pre-wrap break-words\n                    \"\n                    data-copy-to-clipboard-target=\"source\"><%= @yaml %></pre>\n                </div>\n              <% else %>\n                <div class=\"text-sm font-mono text-gray-500\">\n                  Fill out the form and click \"Generate YAML\" to see the output\n                  here.\n                </div>\n              <% end %>\n            </div>\n          </div>\n        </div>\n      </div>\n    <% end %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/templates/new_child.turbo_stream.erb",
    "content": "<%= turbo_stream.append \"children\" do %>\n  <% index = Time.current.to_i %>\n  <%= fields_for 'template[children_attributes][]', ::Template.new, index: index do |form| %>\n    <%= render \"talk_fields\", form: form, index: index %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/templates/speakers_search.turbo_stream.erb",
    "content": "<%= async_combobox_options @speakers, value: proc { |element| element.name } %>\n"
  },
  {
    "path": "app/views/todos/_by_event.html.erb",
    "content": "<div class=\"flex flex-col gap-4\">\n  <% series_with_todos.each do |series_data| %>\n    <div class=\"card bg-base-200\">\n      <div class=\"card-body p-4\">\n        <div class=\"flex items-center gap-2 mb-3\">\n          <span class=\"badge badge-primary\"><%= series_data[:total_count] %></span>\n\n          <% if series_data[:series] %>\n            <%= link_to series_path(series_data[:series].slug), class: \"font-bold text-lg hover:underline\" do %>\n              <%= series_data[:series].name %>\n            <% end %>\n          <% else %>\n            <span class=\"font-bold text-lg\"><%= series_data[:series_slug] %></span>\n          <% end %>\n        </div>\n\n        <% series_data[:events].each do |event_data| %>\n          <div class=\"collapse collapse-arrow bg-base-300 mb-1\">\n            <input type=\"checkbox\">\n            <div class=\"collapse-title py-2 min-h-0 font-medium flex items-center gap-2\">\n              <span class=\"badge badge-sm badge-secondary\"><%= event_data[:total_count] %></span>\n\n              <% if event_data[:event] %>\n                <%= link_to event_path(event_data[:event].slug), class: \"hover:underline\" do %>\n                  <%= event_data[:event].title %>\n                <% end %>\n                <% if event_data[:event].end_date %>\n                  <span class=\"text-base-content/50 text-sm\">(<%= event_data[:event].end_date.strftime(\"%b %Y\") %>)</span>\n                <% end %>\n              <% else %>\n                <span><%= event_data[:event_slug] %></span>\n              <% end %>\n            </div>\n            <div class=\"collapse-content\">\n              <table class=\"table table-xs\">\n                <thead>\n                  <tr>\n                    <th>Location</th>\n                    <th>Content</th>\n                  </tr>\n                </thead>\n                <tbody>\n                  <% event_data[:files].each do |file, todos| %>\n                    <% todos.each do |todo| %>\n                      <tr>\n                        <td class=\"font-mono text-xs\">\n                          <%= link_to todo.url, target: \"_blank\", class: \"link link-primary\" do %>\n                            <%= File.basename(todo.file) %>:<%= todo.line %>\n                          <% end %>\n                        </td>\n                        <td><code class=\"text-xs break-all\"><%= todo.content %></code></td>\n                      </tr>\n                    <% end %>\n                  <% end %>\n                </tbody>\n              </table>\n            </div>\n          </div>\n        <% end %>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/todos/_by_type.html.erb",
    "content": "<div class=\"flex flex-col gap-4\">\n  <% todos_by_type.each do |todo_type| %>\n    <div class=\"card bg-base-200\">\n      <div class=\"card-body p-4\">\n        <div class=\"flex items-center gap-2 mb-2\">\n          <span class=\"badge badge-primary\"><%= todo_type[:count] %></span>\n          <span class=\"font-medium\">TODO:</span>\n          <code class=\"bg-base-300 px-2 py-1 rounded text-sm\"><%= todo_type[:normalized_content] %></code>\n        </div>\n\n        <div class=\"collapse collapse-arrow bg-base-300\">\n          <input type=\"checkbox\">\n          <div class=\"collapse-title py-2 min-h-0 font-medium\">\n            Show <%= todo_type[:count] %> <%= \"occurrence\".pluralize(todo_type[:count]) %>\n          </div>\n          <div class=\"collapse-content\">\n            <table class=\"table table-xs\">\n              <thead>\n                <tr>\n                  <th>File</th>\n                  <th>Content</th>\n                </tr>\n              </thead>\n              <tbody>\n                <% todo_type[:matches].each do |todo| %>\n                  <tr>\n                    <td>\n                      <%= link_to todo.url, target: \"_blank\", class: \"link link-hover text-xs\" do %>\n                        <code><%= todo.file %>:<%= todo.line %></code>\n                      <% end %>\n                    </td>\n                    <td><code class=\"text-xs break-all\"><%= todo.content %></code></td>\n                  </tr>\n                <% end %>\n              </tbody>\n            </table>\n          </div>\n        </div>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/todos/index.html.erb",
    "content": "<div class=\"container py-8\">\n  <h1 class=\"text-2xl font-bold mb-2\">Data TODOs</h1>\n  <p class=\"text-base-content/70 mb-4\">\n    These are items in our data files that need attention. Want to help? Check out our\n    <%= link_to \"contribution guide\", contributions_path, class: \"link link-primary\" %>.\n  </p>\n\n  <div class=\"flex flex-wrap items-center gap-4 mb-6\">\n    <div class=\"stats shadow\">\n      <div class=\"stat py-2 px-4\">\n        <div class=\"stat-title text-xs\">Total TODOs</div>\n        <div class=\"stat-value text-lg text-primary\"><%= number_with_delimiter(@todos.size) %></div>\n      </div>\n\n      <div class=\"stat py-2 px-4\">\n        <div class=\"stat-title text-xs\">Files with TODOs</div>\n        <div class=\"stat-value text-lg text-secondary\"><%= number_with_delimiter(@todos.map(&:file).uniq.size) %></div>\n      </div>\n    </div>\n\n    <div class=\"join\">\n      <%= link_to todos_path(view: \"by_type\"), class: \"join-item btn btn-sm #{\"btn-active\" if @view == \"by_type\"}\" do %>\n        By Type\n      <% end %>\n      <%= link_to todos_path(view: \"by_event\"), class: \"join-item btn btn-sm #{\"btn-active\" if @view == \"by_event\"}\" do %>\n        By Series\n      <% end %>\n    </div>\n  </div>\n\n  <% if @view == \"by_type\" %>\n    <%= render partial: \"by_type\", locals: {todos_by_type: @todos_by_type} %>\n  <% else %>\n    <%= render partial: \"by_event\", locals: {series_with_todos: @series_with_todos} %>\n  <% end %>\n\n  <div class=\"mt-6\">\n    <%== pagy_nav(@pagy) %>\n  </div>\n</div>\n"
  },
  {
    "path": "app/views/topics/_badge.html.erb",
    "content": "<%= link_to topic_path(topic, back_to: back_to_url, back_to_title: back_to_title), data: {turbo_frame: \"_top\"} do %>\n  <div class=\"badge badge-ghost hover:bg-gray-300 px-2 py-3 text-xs\">#<%= topic.name.parameterize %></div>\n<% end %>\n"
  },
  {
    "path": "app/views/topics/_badge_list.html.erb",
    "content": "<% limit ||= 8 %>\n<% more_topics = topics.to_a.from(limit) %>\n\n<div class=\"flex flex-wrap gap-2\" data-controller=\"toggable\" data-toggable-hide-text-value=\"show less topics\">\n  <%= render partial: \"topics/badge\", collection: topics.first(limit), as: :topic, locals: {back_to_url: back_to_url, back_to_title: back_to_title} %>\n\n  <% more_topics.each do |topic| %>\n    <span class=\"hidden\" data-toggable-target=\"toggable\">\n      <%= render partial: \"topics/badge\", locals: {topic: topic, back_to_url: back_to_url, back_to_title: back_to_title} %>\n    </span>\n  <% end %>\n\n  <% if more_topics.any? %>\n    <button type=\"button\" data-action=\"click->toggable#toggle\">\n      <div class=\"badge badge-ghost hover:bg-gray-300 px-2 py-3 text-xs\" data-toggable-target=\"toggle\"><%= more_topics.count %> more</div>\n    </button>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/topics/_gem_info.html.erb",
    "content": "<% topic.topic_gems.each do |topic_gem| %>\n  <div class=\"flex flex-col gap-4 p-5 bg-base-200 rounded-lg max-w-3xl\">\n    <div class=\"flex flex-wrap items-center justify-between gap-2\">\n      <%= link_to gem_path(gem_name: topic_gem.gem_name), class: \"flex items-center gap-2 hover:opacity-80\" do %>\n        <%= fa(\"gem\", size: :md, class: \"fill-primary\") %>\n        <code class=\"font-bold text-lg font-mono\"><%= topic_gem.gem_name %></code>\n\n        <% if topic_gem.version.present? %>\n          <span class=\"badge badge-primary badge-outline\">v<%= topic_gem.version %></span>\n        <% end %>\n      <% end %>\n    </div>\n\n    <% if topic_gem.summary.present? %>\n      <p class=\"text-gray-700\"><%= topic_gem.summary %></p>\n    <% end %>\n\n    <div class=\"flex flex-wrap items-center gap-4 text-sm text-gray-600\">\n      <% if topic_gem.downloads.present? %>\n        <div class=\"flex items-center gap-1.5\" title=\"Total downloads\">\n          <%= fa(\"download\", size: :xs) %>\n          <span><%= number_to_human(topic_gem.downloads) %> downloads</span>\n        </div>\n      <% end %>\n\n      <% if topic_gem.version_created_at.present? %>\n        <div class=\"flex items-center gap-1.5\" title=\"Latest release\">\n          <%= fa(\"calendar\", size: :xs) %>\n          <span>Released <%= time_ago_in_words(topic_gem.version_created_at) %> ago</span>\n        </div>\n      <% end %>\n\n      <% if topic_gem.license.present? %>\n        <div class=\"flex items-center gap-1.5\" title=\"License\">\n          <%= fa(\"scale-balanced\", size: :xs) %>\n          <span><%= topic_gem.license %></span>\n        </div>\n      <% end %>\n    </div>\n\n    <% maintainers = topic_gem.maintainers %>\n\n    <% if maintainers.any? %>\n      <div class=\"flex flex-col gap-2\">\n        <span class=\"text-sm text-gray-500\">Authors on RubyEvents.org</span>\n        <div class=\"flex flex-wrap gap-3\">\n          <% maintainers.each do |user| %>\n            <%= link_to profile_path(user), class: \"flex items-center gap-2 hover:opacity-80\", data: {turbo_frame: \"_top\"} do %>\n              <%= ui_avatar(user, size: :sm) %>\n              <span class=\"text-sm font-medium\"><%= user.name %></span>\n            <% end %>\n          <% end %>\n        </div>\n      </div>\n    <% end %>\n\n    <% if topic_gem.github_repo.present? %>\n      <div class=\"flex items-center gap-2 text-sm\">\n        <%= fab(\"github\", size: :sm) %>\n        <%= external_link_to topic_gem.github_repo, topic_gem.github_url, class: \"link\" %>\n      </div>\n    <% end %>\n\n    <div class=\"flex flex-wrap gap-2\">\n      <%= external_link_to \"RubyGems\", topic_gem.rubygems_url, class: \"btn btn-sm btn-outline\" %>\n\n      <% if topic_gem.github_url.present? %>\n        <%= external_link_to \"GitHub\", topic_gem.github_url, class: \"btn btn-sm btn-outline\" %>\n      <% end %>\n\n      <% if topic_gem.documentation_url.present? %>\n        <%= external_link_to \"Documentation\", topic_gem.documentation_url, class: \"btn btn-sm btn-outline\" %>\n      <% end %>\n\n      <% if topic_gem.changelog_url.present? %>\n        <%= external_link_to \"Changelog\", topic_gem.changelog_url, class: \"btn btn-sm btn-outline\" %>\n      <% end %>\n\n      <% if topic_gem.bug_tracker_url.present? %>\n        <%= external_link_to \"Issues\", topic_gem.bug_tracker_url, class: \"btn btn-sm btn-outline\" %>\n      <% end %>\n\n      <% if topic_gem.homepage_url.present? && topic_gem.homepage_url != topic_gem.source_code_url && topic_gem.homepage_url != topic_gem.github_url %>\n        <%= external_link_to \"Homepage\", topic_gem.homepage_url, class: \"btn btn-sm btn-outline\" %>\n      <% end %>\n\n      <% if topic_gem.funding_url.present? %>\n        <%= external_link_to \"Sponsor\", topic_gem.funding_url, class: \"btn btn-sm btn-outline\" %>\n      <% end %>\n    </div>\n\n    <% if topic_gem.runtime_dependencies.any? %>\n      <details class=\"text-sm\">\n        <summary class=\"cursor-pointer text-gray-600 hover:text-gray-800\">\n          <%= pluralize(topic_gem.runtime_dependencies.size, \"runtime dependency\") %>\n        </summary>\n\n        <div class=\"mt-2 flex flex-wrap gap-1\">\n          <% topic_gem.runtime_dependencies.each do |dep| %>\n            <span class=\"badge badge-ghost badge-sm\"><%= dep[\"name\"] %></span>\n          <% end %>\n        </div>\n      </details>\n    <% end %>\n  </div>\n<% end %>\n"
  },
  {
    "path": "app/views/topics/_talks_cursor.html.erb",
    "content": "<% manual = (pagy.page % 3 == 0) %>\n<% controller = manual ? \"\" : \"auto-click\" %>\n\n<div class=\"<%= class_names(\"flex justify-center\", invisible: !manual) %>\" id=\"talks-cursor\">\n  <% if pagy.next %>\n    <%= link_to \"Load more\", topic_path(topic, page: pagy.next),\n          class: \"btn btn-primary\",\n          data: {turbo_stream: true, controller: controller} %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/topics/_topic.html.erb",
    "content": "<%= link_to topic_path(topic), id: dom_id(topic), class: \"flex justify-between\" do %>\n  <div class=\"flex items-center gap-2\">\n    <span><%= topic.name %></span>\n    <% if topic.topic_gems.any? %>\n      <%= fa(\"gem\", size: :xs, class: \"fill-primary\") %>\n    <% end %>\n  </div>\n  <%= ui_badge(topic.talks_count, kind: :secondary, outline: true, size: :lg, class: \"min-w-10\") %>\n<% end %>\n"
  },
  {
    "path": "app/views/topics/index.html.erb",
    "content": "<div class=\"container py-8\">\n  <div class=\"flex items-center justify-between\">\n    <div class=\"flex items-center gap-2 title text-primary\">\n      <h1>Topics</h1>\n    </div>\n\n    <%= link_to gems_path, class: \"btn btn-sm btn-outline btn-primary\" do %>\n      <%= inline_svg_tag \"icons/fontawesome/gem-solid.svg\", class: \"size-4\" %>\n      View Gems\n    <% end %>\n  </div>\n\n  <div class=\"flex flex-wrap w-full justify-between hotwire-native:hidden py-8 gap-1\">\n    <% (\"a\"..\"z\").each do |letter| %>\n      <%= link_to topics_path(letter: letter), class: class_names(\"flex items-center justify-center w-10 text-gray-500 rounded hover:bg-brand-lighter border\", \"bg-brand-lighter\": letter == params[:letter]) do %>\n        <%= letter.upcase %>\n      <% end %>\n    <% end %>\n    <%= link_to topics_path, class: class_names(\"flex items-center justify-center w-10 text-gray-500 rounded hover:bg-brand-lighter border\", \"bg-brand-lighter\": params[:letter].blank?) do %>\n        all\n      <% end %>\n  </div>\n\n  <div id=\"topics\" class=\"grid sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-8 lg:gap-x-12 gap-y-2 min-w-full\">\n    <%= render partial: \"topic\", collection: @topics, as: :topic %>\n  </div>\n\n  <% if @pagy.next.present? %>\n    <%= turbo_frame_tag :pagination,\n          data: {\n            controller: \"lazy-loading\",\n            lazy_loading_src_value: topics_path(letter: params[:letter], s: params[:s], page: @pagy.next, format: :turbo_stream)\n          } %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/topics/index.turbo_stream.erb",
    "content": "<%= turbo_stream.append \"topics\" do %>\n  <% cache @topics do %>\n    <%= render partial: \"topic\", collection: @topics, as: :topic %>\n  <% end %>\n<% end %>\n\n<% if @pagy.next.present? %>\n  <%= turbo_stream.replace \"pagination\" do %>\n    <%= turbo_frame_tag :pagination,\n                        data: {\n                          controller: \"lazy-loading\",\n                          lazy_loading_src_value: topics_path(letter: params[:letter], s: params[:s], page: @pagy.next, format: :turbo_stream)\n                        } %>\n  <% end %>\n<% end %>\n"
  },
  {
    "path": "app/views/topics/show.html.erb",
    "content": "<div class=\"container flex flex-col w-full gap-4 my-8\">\n  <% back_path = params[:back_to].presence || topics_path %>\n  <% back_to_title = params[:back_to_title].presence || \"Topics\" %>\n  <%= link_to sanitize_url(back_path, fallback: topics_path), class: \"hotwire-native:hidden\" do %>\n    <div class=\"flex items-center gap-2 title text-primary\">\n      <%= fa(\"arrow-left-long\", class: \"transition-arrow fill-primary\", size: :xs) %>\n      <div><%= back_to_title %></div>\n    </div>\n  <% end %>\n  <div class=\"flex flex-col gap-4 hotwire-native:hidden\">\n    <div class=\"flex items-center gap-3 title text-primary\">\n      <h1><%= @topic.name %></h1>\n      <% if @topic.gem_info.gem? %>\n        <span class=\"badge badge-primary badge-outline gap-1\">\n          <%= fa(\"gem\", size: :xs) %>\n          Ruby Gem\n        </span>\n      <% end %>\n    </div>\n\n    <% if @topic.gem_info.gem? %>\n      <%= render \"topics/gem_info\", topic: @topic %>\n    <% end %>\n  </div>\n  <div\n    id=\"topic-talks\"\n    class=\"\n      grid min-w-full grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4 gallery\n    \">\n    <%= render partial: \"talks/card\",\n          collection: @talks,\n          as: :talk,\n          locals: {\n            favoritable: true,\n            user_favorite_talks_ids: @user_favorite_talks_ids,\n            user_watched_talks: user_watched_talks,\n            back_to: back_to_from_request,\n            back_to_title: @topic.name\n          } %>\n  </div>\n  <%= render \"topics/talks_cursor\", pagy: @pagy, topic: @topic %>\n</div>\n"
  },
  {
    "path": "app/views/topics/show.turbo_stream.erb",
    "content": "<%= turbo_stream.append \"topic-talks\" do %>\n  <%= render partial: \"talks/card\",\n        collection: @talks,\n        as: :talk,\n        locals: {\n          favoritable: true,\n          user_favorite_talks_ids: @user_favorite_talks_ids,\n          user_watched_talks: user_watched_talks,\n          back_to: back_to_from_request,\n          back_to_title: @topic.name\n        } %>\n<% end %>\n\n<%= turbo_stream.replace \"talks-cursor\" do %>\n  <%= render \"topics/talks_cursor\", pagy: @pagy, topic: @topic %>\n<% end %>\n"
  },
  {
    "path": "app/views/users/_card.html.erb",
    "content": "<%# locals: (user:, content: \"\", favorite_user: nil) %>\n\n<div class=\"flex items-center px-2\">\n  <% if favorite_user.present? %>\n    <%= render partial: \"favorite_users/favorite_user\", locals: {favorite_user: favorite_user} %>\n  <% end %>\n  <%= link_to profile_path(user), class: \"flex flex-col gap-4 hover:bg-gray-200 transition-bg duration-300 ease-in-out p-2 px-4 rounded-lg\", data: {turbo_frame: \"_top\"} do %>\n    <div class=\"flex items-center gap-4\">\n      <%= ui_avatar(user) %>\n      <div>\n        <div class=\"font-bold text-base line-clamp-1 flex items-center gap-1.5\">\n          <span class=\"line-clamp-1\"><%= user.name %></span>\n\n          <% if user.verified? %>\n            <%= fa(\"badge-check\", class: \"fill-blue-500\", size: :xs) %>\n          <% end %>\n\n          <% if user.ruby_passport_claimed? %>\n            <%= fa(\"passport\", class: \"fill-orange-800\", size: :xs) %>\n          <% end %>\n        </div>\n\n        <div class=\"text-xs text-gray-500 line-clamp-1\">\n          <% if defined?(content) %>\n            <%= content %>\n          <% elsif user.github_handle.present? %>\n            <%= \"@#{user.github_handle}\" %>\n          <% elsif user.bsky.present? %>\n            <%= \"@#{user.bsky}\" %>\n          <% else %>\n            <%= \"@#{user.slug}\" %>\n          <% end %>\n        </div>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/watch_lists/_watch_list.html.erb",
    "content": "<div class=\"flex flex-col gap-4\">\n  <% if watch_list.talks.present? %>\n    <div id=\"talks\" class=\"grid min-w-full grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gallery\">\n      <%= render partial: \"talks/card\",\n            collection: watch_list.talks,\n            as: :talk,\n            locals: {\n              favoritable: true,\n              user_favorite_talks_ids: watch_list.talks.ids,\n              user_watched_talks: user_watched_talks,\n              back_to: watch_lists_path,\n              back_to_title: watch_list.name\n            } %>\n    </div>\n  <% else %>\n    <div class=\"text-center py-12\">\n      <div class=\"max-w-md mx-auto\">\n        <div class=\"text-6xl mb-4\">🔖</div>\n        <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No bookmarks yet</h2>\n        <p class=\"text-gray-600 mb-6\">\n          Start bookmarking talks and easily find them later.\n        </p>\n        <div class=\"bg-purple-50 border border-purple-200 rounded-lg p-4 text-left\">\n          <h3 class=\"font-semibold text-purple-800 mb-2\">How to bookmark talks:</h3>\n          <ul class=\"text-sm text-purple-700 space-y-1\">\n            <li>• Browse talks and click the bookmark icon</li>\n            <li>• Access your bookmarks anytime</li>\n          </ul>\n        </div>\n        <div class=\"mt-6\">\n          <%= link_to talks_path, class: \"btn btn-primary\" do %>\n            <%= fa \"video\", variant: :solid, class: \"w-5 h-5 mr-2\" %>\n            Browse Talks\n          <% end %>\n        </div>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/watch_lists/edit.html.erb",
    "content": ""
  },
  {
    "path": "app/views/watch_lists/index.html.erb",
    "content": "<%= turbo_refreshes_with method: :morph, scroll: :preserve %>\n\n<div class=\"container flex flex-col w-full gap-4 my-8\">\n  <div class=\"flex justify-between items-center mb-6\">\n    <h1><%= title @watch_list.name %></h1>\n  </div>\n\n  <%= turbo_frame_tag \"watch_list_talks\", target: \"_top\", src: watch_list_path(@watch_list) do %>\n    <%= render partial: \"watch_lists/watch_list\",\n          locals: {watch_list: @watch_list,\n                   user_watched_talks: user_watched_talks} %>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/watch_lists/new.html.erb",
    "content": ""
  },
  {
    "path": "app/views/watch_lists/show.html.erb",
    "content": "<%= turbo_frame_tag \"watch_list_talks\", target: \"\" do %>\n  <%= render partial: \"watch_lists/watch_list\",\n        locals: {watch_list: @watch_list,\n                 user_watched_talks: user_watched_talks} %>\n<% end %>\n"
  },
  {
    "path": "app/views/watched_talks/index.html.erb",
    "content": "<div class=\"container container-sm flex flex-col w-full gap-4 my-8 hotwire-native:my-0 hotwire-native:mb-8\">\n  <div class=\"flex items-end gap-2 title text-primary hotwire-native:mb-3\">\n    <h1 class=\"title hotwire-native:hidden\">\n      <%= title \"Recently Watched Videos\" %>\n    </h1>\n  </div>\n\n  <% if @in_progress_talks.any? %>\n    <div class=\"flex flex-col gap-3 mb-6\">\n      <h2 class=\"text-lg font-bold text-gray-900 flex items-center gap-2\">\n        <%= fa(\"play\", size: :sm) %>\n        Continue Watching\n      </h2>\n\n      <div class=\"relative\" data-controller=\"scroll\">\n        <div class=\"overflow-x-auto scroll-smooth snap-x snap-mandatory [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]\"\n             data-scroll-target=\"container\"\n             data-action=\"scroll->scroll#checkScroll\">\n          <div class=\"flex pb-4 gap-4\">\n            <% @in_progress_talks.each do |watched_talk| %>\n              <div class=\"flex-none w-64 snap-start\" data-scroll-target=\"card\">\n                <%= render partial: \"talks/card_thumbnail\",\n                      locals: {\n                        talk: watched_talk.talk,\n                        watched_talk: watched_talk,\n                        back_to: watched_talks_path,\n                        back_to_title: \"Continue Watching\"\n                      } %>\n              </div>\n            <% end %>\n          </div>\n        </div>\n        <div class=\"absolute right-0 top-0 h-full w-24 bg-gradient-to-l from-white to-transparent pointer-events-none\"\n             data-scroll-target=\"gradient\"></div>\n      </div>\n    </div>\n  <% end %>\n\n  <% if @watched_talks_by_date.present? %>\n    <div id=\"talks\" class=\"flex flex-col gap-8\">\n      <% @watched_talks_by_date.each do |date, watched_talks| %>\n        <div class=\"flex flex-col gap-3\">\n          <h2 class=\"text-lg font-bold text-gray-900\">\n            <% if date == Date.current %>\n              Today\n            <% elsif date == Date.current - 1 %>\n              Yesterday\n            <% else %>\n              <%= date.strftime(\"%B %-d, %Y\") %>\n            <% end %>\n          </h2>\n\n          <div class=\"flex flex-col gap-2\">\n            <% watched_talks.each do |watched_talk| %>\n              <%= render partial: \"talks/card_horizontal\",\n                    locals: {\n                      talk: watched_talk.talk,\n                      watched_talk: watched_talk,\n                      user_watched_talks: user_watched_talks,\n                      show_remove_from_watched: true,\n                      show_event_name: true,\n                      tooltip: false\n                    } %>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n    </div>\n  <% end %>\n\n  <% if @in_progress_talks.empty? && @watched_talks_by_date.blank? %>\n    <div class=\"text-center py-12\">\n      <div class=\"max-w-md mx-auto\">\n        <div class=\"text-6xl mb-4\">📺</div>\n        <h2 class=\"text-2xl font-bold text-gray-900 mb-4\">No watched videos yet</h2>\n        <p class=\"text-gray-600 mb-6\">\n          Start watching talks to track your viewing history and pick up where you left off.\n        </p>\n        <div class=\"bg-purple-50 border border-purple-200 rounded-lg p-4 text-left\">\n          <h3 class=\"font-semibold text-purple-800 mb-2\">How it works:</h3>\n          <ul class=\"text-sm text-purple-700 space-y-1\">\n            <li>• Watch talks to automatically track your progress</li>\n            <li>• See your recently watched videos here</li>\n            <li>• Resume watching where you left off</li>\n          </ul>\n        </div>\n        <div class=\"mt-6\">\n          <%= link_to talks_path, class: \"btn btn-primary\" do %>\n            <%= fa \"video\", variant: :solid, class: \"w-5 h-5 mr-2\" %>\n            Browse Talks\n          <% end %>\n        </div>\n      </div>\n    </div>\n  <% end %>\n</div>\n"
  },
  {
    "path": "app/views/wrapped/_card.html.erb",
    "content": "<section class=\"w-full\">\n  <%= link_to wrapped_path, class: \"block w-full p-6 lg:p-10 rounded-[10px] lg:rounded-[25px] bg-gradient-to-br from-red-600 to-red-800 text-white hover:from-red-700 hover:to-red-900 transition-all shadow-lg hover:shadow-xl\" do %>\n    <div class=\"flex flex-col lg:flex-row items-center gap-6 lg:gap-10\">\n      <div class=\"flex-shrink-0\">\n        <div class=\"w-24 h-24 lg:w-32 lg:h-32 bg-white/10 rounded-2xl flex items-center justify-center\">\n          <svg class=\"w-16 h-16 lg:w-20 lg:h-20 text-white\" viewBox=\"0 0 80 80\" fill=\"currentColor\">\n            <path d=\"M2 25 L16 10 L64 10 L78 25 L40 70 Z\" />\n          </svg>\n        </div>\n      </div>\n      <div class=\"flex-1 text-center lg:text-left\">\n        <p class=\"text-red-200 text-sm font-medium mb-1\">RubyEvents.org</p>\n        <h2 class=\"text-3xl lg:text-4xl font-black mb-2\">2025 Wrapped</h2>\n        <p class=\"text-red-100 text-base lg:text-lg max-w-xl\">\n          Discover your year in Ruby events. See your watching stats, top speakers, events attended, and more!\n        </p>\n      </div>\n      <div class=\"flex-shrink-0\">\n        <span class=\"inline-flex items-center gap-2 px-6 py-3 bg-white text-red-700 font-semibold rounded-full hover:bg-red-50 transition\">\n          View Your 2025 Wrapped\n          <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n            <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\" />\n          </svg>\n        </span>\n      </div>\n    </div>\n  <% end %>\n</section>\n"
  },
  {
    "path": "app/views/wrapped/_featured.html.erb",
    "content": "<div\n  class=\"w-full pt-4 lg:pt-6 pb-4 lg:pb-12 lg:min-h-[600px]\"\n  style=\"\n    color: white;\n    background: #991b1b;\n  \">\n  <a href=\"<%= wrapped_path %>\" class=\"block h-full\">\n    <div class=\"container h-full\">\n      <div class=\"grid grid-cols-1 lg:grid-cols-[1fr_2fr] gap-6 lg:gap-12 items-center h-full\">\n        <div class=\"flex flex-col gap-4\">\n          <div class=\"flex justify-center mb-4\">\n            <svg class=\"w-1/2 text-white center bg-white/10 rounded-2xl p-12\" viewBox=\"0 0 80 80\" fill=\"currentColor\">\n              <path d=\"M2 25 L16 10 L64 10 L78 25 L40 70 Z\" />\n            </svg>\n          </div>\n\n          <div class=\"flex flex-col gap-3 text-center lg:text-left\">\n            <h1 class=\"text-inherit font-bold text-xl line-clamp-1 lg:line-clamp-2\">RubyEvents.org 2025 Wrapped</h1>\n            <h2 class=\"text-inherit opacity-60 text-sm line-clamp-1\">2025 Wrapped</h2>\n            <h2 class=\"text-inherit font-medium text-sm line-clamp-3 hidden lg:block\">\n              Discover your watching stats, top users, events attended, and more. See how the Ruby community spent their year!<br><br>\n            </h2>\n          </div>\n\n          <%= ui_button kind: :rounded, class: \"btn-sm lg:btn-md mx-auto lg:mx-0 mt-4\" do %>\n            <span>View Your 2025 Wrapped</span>\n          <% end %>\n        </div>\n\n        <div class=\"hidden lg:flex flex-col justify-end items-end gap-6\">\n          <div class=\"flex flex-col gap-6 items-center px-12\">\n            <div class=\"avatar-group -space-x-6 rtl:space-x-reverse\">\n              <% shown_users = [] %>\n              <% all_users = users.shuffle %>\n              <% users_with_avatars = all_users.select { |user| user.avatar_url.present? } %>\n\n              <% users_with_avatars.first(4).each do |user| %>\n                <% shown_users << user %>\n                <%= ui_avatar(user, size: :lg, size_class: \"w-12 lg:w-28 xl:w-40\") %>\n              <% end %>\n            </div>\n\n            <div class=\"avatar-group -space-x-6 lg:-space-x-3 rtl:space-x-reverse\">\n              <% remaining_users = users_with_avatars - shown_users %>\n\n              <% if remaining_users.any? %>\n                <% remaining_users.first(10).each do |user| %>\n                  <% shown_users << user %>\n                  <%= ui_avatar(user) %>\n                <% end %>\n              <% end %>\n\n              <% more_users_count = all_users.count - shown_users.count %>\n\n              <% if more_users_count.positive? %>\n                <%= ui_avatar(nil, kind: :neutral) do %>\n                  <span>+<%= more_users_count %></span>\n                <% end %>\n              <% end %>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </a>\n</div>\n"
  },
  {
    "path": "app/views/wrapped/index.html.erb",
    "content": "<div class=\"min-h-screen bg-[linear-gradient(to_bottom,#991b1b_0%,#450a0a_20%,#081625_60%,#081625_100%)]\">\n  <div class=\"max-w-4xl mx-auto px-4 py-12\">\n    <div class=\"text-center text-white mb-16\">\n      <p class=\"text-red-300 text-lg\" style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">RubyEvents.org</p>\n      <h1 class=\"text-6xl font-black text-white mt-2\" style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\"><%= @year %></h1>\n      <p class=\"text-3xl font-bold text-red-200 mt-1\" style=\"font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\">Wrapped</p>\n\n      <p class=\"text-xl text-red-100 mt-8 mb-8 max-w-lg mx-auto\">\n        Your year in Ruby events, talks watched, and community connections.\n      </p>\n\n      <% if Current.user %>\n        <%= link_to profile_wrapped_index_path(profile_slug: Current.user.to_param), class: \"inline-flex items-center gap-2 px-8 py-4 bg-white text-red-700 font-bold rounded-full hover:bg-red-100 transition-colors text-lg shadow-lg\" do %>\n          <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"w-6 h-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\">\n            <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z\" />\n            <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n          </svg>\n          View Your <%= @year %> Wrapped\n        <% end %>\n      <% else %>\n        <%= link_to new_session_path(redirect_to: request.fullpath), data: {turbo_frame: \"modal\"}, class: \"inline-flex items-center gap-2 px-8 py-4 bg-white text-red-700 font-bold rounded-full hover:bg-red-100 transition-colors text-lg shadow-lg\" do %>\n          Sign in to see your Wrapped\n        <% end %>\n      <% end %>\n    </div>\n\n    <div class=\"mb-16\">\n      <div class=\"text-center mb-8\">\n        <h2 class=\"text-2xl font-bold text-white mb-2\">Platform Stats</h2>\n        <p class=\"text-red-200\">The Ruby community in <%= @year %></p>\n      </div>\n\n      <div class=\"grid grid-cols-2 md:grid-cols-4 gap-4 mb-8\">\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Talks that took place at Ruby conferences and meetups in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@talks_held) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Talks Held</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Talk recordings published in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@talks_published) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Talks Published</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Ruby conferences that took place in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@total_conferences) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Conferences</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Unique speakers who gave talks at Ruby events in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@total_speakers) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Speakers</p>\n        </div>\n      </div>\n\n      <div class=\"grid grid-cols-2 md:grid-cols-4 gap-4 mb-8\">\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Talks from <%= @year %> that have slide decks linked on RubyEvents.org\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@talks_with_slides) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Slide Decks</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Total hours of talk recordings published in <%= @year %> available to watch on RubyEvents.org\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@total_hours) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Hours to Watch</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Countries that hosted Ruby conferences or meetups in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@countries_with_events.count) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Event Countries</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Organizers, MCs, volunteers, and other people who helped run Ruby events in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@people_involved) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">People Involved</p>\n        </div>\n      </div>\n\n      <div class=\"grid grid-cols-2 md:grid-cols-4 gap-4 mb-8\">\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Organizations that sponsored Ruby conferences in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@unique_sponsors) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Unique Sponsors</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Ruby Passports connected to RubyEvents.org accounts in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@passports_issued) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Ruby Passports Linked</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Users who marked their attendance at events on RubyEvents.org in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@event_participations) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Event Check-ins</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Total number of talks watched by users on RubyEvents.org in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@total_talks_watched) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Talks Watched</p>\n        </div>\n      </div>\n\n      <div class=\"grid grid-cols-2 md:grid-cols-3 gap-4 mb-8\">\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Total registered Rubyists on RubyEvents.org\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@total_rubyists) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Rubyists</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Countries where Rubyists are from\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@rubyist_countries) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Rubyist Countries</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"New users who signed up to RubyEvents.org in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@new_users) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">New Users</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Contributors to the RubyEvents.org codebase on GitHub\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@github_contributors) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">GitHub Contributors</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Unique visitor sessions to RubyEvents.org in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@total_visits) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Visits</p>\n        </div>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 text-center cursor-help\" data-controller=\"tooltip\" data-tooltip-content-value=\"Total page views across all pages on RubyEvents.org in <%= @year %>\">\n          <p class=\"text-4xl font-black text-white\"><%= number_with_delimiter(@total_page_views) %></p>\n          <p class=\"text-red-200 text-sm mt-1\">Page Views</p>\n        </div>\n      </div>\n\n      <div class=\"grid md:grid-cols-2 gap-6\">\n        <% if @top_topics.any? %>\n          <div class=\"bg-white/10 backdrop-blur rounded-xl p-6\">\n            <h3 class=\"text-lg font-bold text-white mb-4\">🔥 Most Popular Topics</h3>\n            <div class=\"space-y-3\">\n              <% @top_topics.each_with_index do |topic, index| %>\n                <%= link_to topic_path(topic), class: \"flex items-center gap-3 text-white hover:text-red-200 transition\" do %>\n                  <span class=\"text-2xl font-bold text-red-400\"><%= index + 1 %></span>\n                  <span class=\"font-medium\"><%= topic.name %></span>\n                <% end %>\n              <% end %>\n            </div>\n          </div>\n        <% end %>\n\n        <% if @most_watched_events.any? %>\n          <div class=\"bg-white/10 backdrop-blur rounded-xl p-6\">\n            <h3 class=\"text-lg font-bold text-white mb-4\">👀 Most Watched Events</h3>\n            <div class=\"space-y-3\">\n              <% @most_watched_events.each_with_index do |event, index| %>\n                <%= link_to event_path(event), class: \"flex items-center gap-3 text-white hover:text-red-200 transition\" do %>\n                  <span class=\"text-2xl font-bold text-red-400\"><%= index + 1 %></span>\n                  <span class=\"font-medium truncate\"><%= event.name %></span>\n                <% end %>\n              <% end %>\n            </div>\n          </div>\n        <% end %>\n\n        <% if @events_by_sessions.any? %>\n          <div class=\"bg-white/10 backdrop-blur rounded-xl p-6\">\n            <h3 class=\"text-lg font-bold text-white mb-4\">🎪 Most Sessions</h3>\n            <div class=\"space-y-3\">\n              <% @events_by_sessions.each_with_index do |event, index| %>\n                <%= link_to event_path(event), class: \"flex items-center gap-3 text-white hover:text-red-200 transition\" do %>\n                  <span class=\"text-2xl font-bold text-red-400\"><%= index + 1 %></span>\n                  <span class=\"font-medium truncate\"><%= event.name %></span>\n                  <span class=\"text-red-300 text-sm\"><%= event.talks_count %></span>\n                <% end %>\n              <% end %>\n            </div>\n          </div>\n        <% end %>\n\n        <% if @events_by_attendees.any? %>\n          <div class=\"bg-white/10 backdrop-blur rounded-xl p-6\">\n            <h3 class=\"text-lg font-bold text-white mb-4\">🙋 Most Registered Attendees</h3>\n            <div class=\"space-y-3\">\n              <% @events_by_attendees.each_with_index do |event, index| %>\n                <%= link_to event_path(event), class: \"flex items-center gap-3 text-white hover:text-red-200 transition\" do %>\n                  <span class=\"text-2xl font-bold text-red-400\"><%= index + 1 %></span>\n                  <span class=\"font-medium truncate\"><%= event.name %></span>\n                  <span class=\"text-red-300 text-sm\"><%= event.attendees_count %></span>\n                <% end %>\n              <% end %>\n            </div>\n          </div>\n        <% end %>\n      </div>\n\n      <% if @most_watched_talks.any? %>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 mt-6\">\n          <h3 class=\"text-lg font-bold text-white mb-4\">👀 Most Watched Talks on RubyEvents.org</h3>\n          <div class=\"space-y-4\">\n            <% @most_watched_talks.each_with_index do |talk, index| %>\n              <%= link_to talk_path(talk), class: \"flex items-start gap-4 text-white hover:text-red-200 transition group\" do %>\n                <span class=\"text-2xl font-bold text-red-400 shrink-0\"><%= index + 1 %></span>\n                <div class=\"min-w-0\">\n                  <p class=\"font-medium group-hover:underline truncate\"><%= talk.title %></p>\n                  <p class=\"text-sm text-red-300 truncate\">\n                    <%= talk.speakers.map(&:name).join(\", \") %>\n                    <% if talk.event.present? %>\n                      <span class=\"text-red-400\">•</span>\n                      <%= talk.event.name %>\n                    <% end %>\n                  </p>\n                </div>\n              <% end %>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n\n      <% if @countries_with_events.any? %>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 mt-6\">\n          <h3 class=\"text-lg font-bold text-white mb-4\">🌍 Events Across the Globe</h3>\n          <p class=\"text-red-200 mb-4\"><%= @countries_with_events.count %> countries hosted Ruby events</p>\n          <div class=\"flex flex-wrap gap-2\">\n            <% @countries_with_events.sort_by(&:name).each do |country| %>\n              <%= link_to country.path, class: \"inline-flex items-center gap-1 px-3 py-1 bg-white/10 rounded-full text-sm text-white hover:bg-white/20 transition\" do %>\n                <%= country.emoji_flag %> <%= country.name %>\n              <% end %>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n\n      <% if @languages.any? %>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-6 mt-6\">\n          <h3 class=\"text-lg font-bold text-white mb-4\">🗣️ Talk Languages</h3>\n          <p class=\"text-red-200 mb-4\">Languages spoken at Ruby conferences this year</p>\n          <div class=\"flex flex-wrap gap-3\">\n            <% @languages.each do |language, count| %>\n              <span class=\"inline-flex items-center gap-2 px-3 py-1 bg-white/10 rounded-full text-sm text-white\">\n                <%= language.respond_to?(:name) ? language.name : language %>\n                <span class=\"text-red-300\"><%= count %></span>\n              </span>\n            <% end %>\n          </div>\n        </div>\n      <% end %>\n\n      <% if @new_speakers.positive? %>\n        <div class=\"text-center mt-8\">\n          <p class=\"text-red-200\">\n            🎤 <span class=\"text-white font-bold\"><%= number_with_delimiter(@new_speakers) %></span> speakers gave their first conference talk\n          </p>\n        </div>\n      <% end %>\n\n      <% if @next_year_conferences.positive? || @next_year_talks.positive? || @open_cfps.positive? %>\n        <div class=\"bg-white/10 backdrop-blur rounded-xl p-8 mt-8 text-center\">\n          <p class=\"text-red-300 text-sm mb-2\">Sneak Peek</p>\n          <h3 class=\"text-3xl font-black text-white mb-4\"><%= @next_year %></h3>\n          <div class=\"flex justify-center gap-8\">\n            <% if @next_year_conferences.positive? %>\n              <div>\n                <p class=\"text-3xl font-bold text-white\"><%= @next_year_conferences %></p>\n                <p class=\"text-red-200 text-sm\">Conferences</p>\n              </div>\n            <% end %>\n            <% if @next_year_talks.positive? %>\n              <div>\n                <p class=\"text-3xl font-bold text-white\"><%= @next_year_talks %></p>\n                <p class=\"text-red-200 text-sm\">Talks Scheduled</p>\n              </div>\n            <% end %>\n            <% if @open_cfps.positive? %>\n              <div>\n                <p class=\"text-3xl font-bold text-white\"><%= @open_cfps %></p>\n                <p class=\"text-red-200 text-sm\">Open CFPs</p>\n              </div>\n            <% end %>\n          </div>\n          <%= link_to events_path(year: @next_year), class: \"inline-block mt-6 px-6 py-2 bg-white/20 text-white rounded-full hover:bg-white/30 transition text-sm\" do %>\n            View <%= @next_year %> Events →\n          <% end %>\n        </div>\n      <% end %>\n    </div>\n\n    <% if @public_users.any? %>\n      <div class=\"text-center mb-8\">\n        <h2 class=\"text-2xl font-bold text-white mb-2\">Community Wrappeds</h2>\n        <p class=\"text-red-200\">See what others experienced this year</p>\n      </div>\n\n      <div class=\"flex flex-wrap justify-center gap-4\">\n        <% @public_users.each do |user| %>\n          <%= link_to profile_wrapped_index_path(profile_slug: user.to_param), class: \"group\" do %>\n            <div class=\"relative\">\n              <div class=\"w-20 h-20 md:w-24 md:h-24 rounded-full p-[3px] bg-gradient-to-tr from-red-400 via-red-500 to-[#081625] group-hover:scale-105 transition-transform\">\n                <div class=\"w-full h-full rounded-full p-[2px] bg-[#081625]\">\n                  <div class=\"w-full h-full rounded-full overflow-hidden bg-gray-100\">\n                    <% if user.custom_avatar? %>\n                      <%= image_tag user.avatar_url(size: 96), class: \"w-full h-full object-cover\", alt: user.name %>\n                    <% else %>\n                      <div class=\"w-full h-full flex items-center justify-center text-2xl font-bold text-gray-600 bg-gray-200\">\n                        <%= user.name.first.upcase %>\n                      </div>\n                    <% end %>\n                  </div>\n                </div>\n              </div>\n            </div>\n            <p class=\"text-center text-white text-sm mt-2 max-w-[80px] md:max-w-[96px] truncate mx-auto\">\n              <%= user.name.split.first %>\n            </p>\n          <% end %>\n        <% end %>\n      </div>\n    <% end %>\n\n    <% if @top_organizations.any? %>\n      <div class=\"text-center mb-8 mt-16\">\n        <h2 class=\"text-2xl font-bold text-white mb-2\">Top Supporters</h2>\n        <p class=\"text-red-200\">Organizations supporting the Ruby community — check out their Wrapped!</p>\n      </div>\n\n      <div class=\"flex flex-wrap justify-center gap-4\">\n        <% @top_organizations.each do |organization| %>\n          <%= link_to organization_wrapped_index_path(organization_slug: organization.slug), class: \"group\" do %>\n            <div class=\"relative\">\n              <div class=\"w-20 h-20 md:w-24 md:h-24 rounded-xl p-[3px] bg-gradient-to-tr from-red-400 via-red-500 to-[#081625] group-hover:scale-105 transition-transform\">\n                <div class=\"w-full h-full rounded-xl p-[2px] bg-[#081625]\">\n                  <div class=\"w-full h-full rounded-lg overflow-hidden bg-white flex items-center justify-center p-2\">\n                    <% if organization.logo_url.present? %>\n                      <%= image_tag organization.logo_url, class: \"w-full h-full object-contain\", alt: organization.name %>\n                    <% else %>\n                      <span class=\"text-2xl font-bold text-gray-600\"><%= organization.name.first.upcase %></span>\n                    <% end %>\n                  </div>\n                </div>\n              </div>\n            </div>\n            <p class=\"text-center text-white text-sm mt-2 max-w-[80px] md:max-w-[96px] truncate mx-auto\">\n              <%= organization.name %>\n            </p>\n          <% end %>\n        <% end %>\n      </div>\n    <% end %>\n\n    <div class=\"text-center mt-16 text-red-200 text-sm\">\n      <p>Share your year with the Ruby community</p>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "bin/brakeman",
    "content": "#!/usr/bin/env ruby\nrequire \"rubygems\"\nrequire \"bundler/setup\"\n\nARGV.unshift(\"--ensure-latest\")\n\nload Gem.bin_path(\"brakeman\", \"brakeman\")\n"
  },
  {
    "path": "bin/bundle",
    "content": "#!/usr/bin/env ruby\n# frozen_string_literal: true\n\n#\n# This file was generated by Bundler.\n#\n# The application 'bundle' is installed as part of a gem, and\n# this file is here to facilitate running it.\n#\n\nrequire \"rubygems\"\n\nm = Module.new do\n  module_function\n\n  def invoked_as_script?\n    File.expand_path($0) == File.expand_path(__FILE__)\n  end\n\n  def env_var_version\n    ENV[\"BUNDLER_VERSION\"]\n  end\n\n  def cli_arg_version\n    return unless invoked_as_script? # don't want to hijack other binstubs\n    return unless \"update\".start_with?(ARGV.first || \" \") # must be running `bundle update`\n    bundler_version = nil\n    update_index = nil\n    ARGV.each_with_index do |a, i|\n      if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN\n        bundler_version = a\n      end\n      next unless a =~ /\\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\\z/\n      bundler_version = $1\n      update_index = i\n    end\n    bundler_version\n  end\n\n  def gemfile\n    gemfile = ENV[\"BUNDLE_GEMFILE\"]\n    return gemfile if gemfile && !gemfile.empty?\n\n    File.expand_path(\"../Gemfile\", __dir__)\n  end\n\n  def lockfile\n    lockfile =\n      case File.basename(gemfile)\n      when \"gems.rb\" then gemfile.sub(/\\.rb$/, \".locked\")\n      else \"#{gemfile}.lock\"\n      end\n    File.expand_path(lockfile)\n  end\n\n  def lockfile_version\n    return unless File.file?(lockfile)\n    lockfile_contents = File.read(lockfile)\n    return unless lockfile_contents =~ /\\n\\nBUNDLED WITH\\n\\s{2,}(#{Gem::Version::VERSION_PATTERN})\\n/\n    Regexp.last_match(1)\n  end\n\n  def bundler_requirement\n    @bundler_requirement ||=\n      env_var_version ||\n      cli_arg_version ||\n      bundler_requirement_for(lockfile_version)\n  end\n\n  def bundler_requirement_for(version)\n    return \"#{Gem::Requirement.default}.a\" unless version\n\n    bundler_gem_version = Gem::Version.new(version)\n\n    bundler_gem_version.approximate_recommendation\n  end\n\n  def load_bundler!\n    ENV[\"BUNDLE_GEMFILE\"] ||= gemfile\n\n    activate_bundler\n  end\n\n  def activate_bundler\n    gem_error = activation_error_handling do\n      gem \"bundler\", bundler_requirement\n    end\n    return if gem_error.nil?\n    require_error = activation_error_handling do\n      require \"bundler/version\"\n    end\n    return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))\n    warn \"Activating bundler (#{bundler_requirement}) failed:\\n#{gem_error.message}\\n\\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`\"\n    exit 42\n  end\n\n  def activation_error_handling\n    yield\n    nil\n  rescue StandardError, LoadError => e\n    e\n  end\nend\n\nm.load_bundler!\n\nif m.invoked_as_script?\n  load Gem.bin_path(\"bundler\", \"bundle\")\nend\n"
  },
  {
    "path": "bin/bundler-audit",
    "content": "#!/usr/bin/env ruby\nrequire_relative \"../config/boot\"\nrequire \"bundler/audit/cli\"\n\nARGV.concat %w[ --config config/bundler-audit.yml ] if ARGV.empty? || ARGV.include?(\"check\")\nBundler::Audit::CLI.start\n"
  },
  {
    "path": "bin/ci",
    "content": "#!/usr/bin/env ruby\nrequire_relative \"../config/boot\"\nrequire \"active_support/continuous_integration\"\n\nCI = ActiveSupport::ContinuousIntegration\nrequire_relative \"../config/ci.rb\"\n"
  },
  {
    "path": "bin/dev",
    "content": "#!/usr/bin/env sh\n\n# Default to port 3000 if not specified\nexport PORT=\"${PORT:-3000}\"\n\nif command -v overmind > /dev/null 2>&1; then\n  exec overmind start -f Procfile.dev \"$@\"\nelse\n  if ! gem list foreman -i --silent; then\n    echo \"Installing foreman...\"\n    gem install foreman\n  fi\n\n  exec foreman start -f Procfile.dev \"$@\"\nfi\n"
  },
  {
    "path": "bin/docker-entrypoint",
    "content": "#!/bin/bash -e\n\n# Enable jemalloc for reduced memory usage and latency.\nif [ -z \"${LD_PRELOAD+x}\" ]; then\n    LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit)\n    export LD_PRELOAD\nfi\n\n# If running the rails server then create or migrate existing database\nif [ \"${@: -2:1}\" == \"./bin/rails\" ] && [ \"${@: -1:1}\" == \"server\" ]; then\n  ./bin/rails db:prepare\nfi\n\nexec \"${@}\"\n"
  },
  {
    "path": "bin/dump_prod.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\n# === Config ===\nREMOTE_USER=\"root\"\nREMOTE_HOST=\"91.107.208.207\"\n\n# Inside the container (mounted volume)\nCONTAINER_DB_PATH=\"/rails/storage/production_rubyvideo.sqlite3\"\nCONTAINER_TMP_DIR=\"/rails/storage\"\nCONTAINER_TMP_BACKUP=\"/rails/storage/production_rubyvideo-backup.sqlite3\"\n# CONTAINER_TMP_BACKUP=\"${CONTAINER_TMP_DIR}/production_rubyvideo-backup.sqlite3\"\n\n# Host path for the same Docker volume (what scp will read)\nHOST_VOLUME_DIR=\"/var/lib/docker/volumes/storage/_data\"\nHOST_TMP_BACKUP=\"${HOST_VOLUME_DIR}/production_rubyvideo-backup.sqlite3\"\n\n# Local target + local safety backup dir\nLOCAL_DEST=\"storage/development_rubyvideo.sqlite3\"\nLOCAL_BACKUP_DIR=\"storage/backups\"\n\n# === Step 0: Local safety copy (timestamped) ===\nif [ -f \"${LOCAL_DEST}\" ]; then\n  mkdir -p \"${LOCAL_BACKUP_DIR}\"\n  TS=$(date +\"%Y%m%d-%H%M%S\")\n  LOCAL_SNAPSHOT=\"${LOCAL_BACKUP_DIR}/development_rubyvideo-${TS}.sqlite3\"\n  echo \"→ Creating local pre-download snapshot: ${LOCAL_SNAPSHOT}\"\n  cp \"${LOCAL_DEST}\" \"${LOCAL_SNAPSHOT}\"\nfi\n\n# === Step 1: Create backup inside container via Kamal ===\necho \"→ Creating SQLite backup in container (via Kamal)...\"\ndotenv kamal app exec \"sqlite3 '${CONTAINER_DB_PATH}' \\\".backup '${CONTAINER_TMP_BACKUP}'\\\"\"\ndotenv kamal app exec \"ls -la '${CONTAINER_TMP_DIR}'\"\n\n# === Step 2: Download the backup from the host volume ===\necho \"→ Downloading backup from host to local: ${LOCAL_DEST}\"\nscp \"${REMOTE_USER}@${REMOTE_HOST}:${HOST_TMP_BACKUP}\" \"${LOCAL_DEST}\"\n\n# Optional: verify integrity locally (uncomment to enforce)\necho '→ Running local PRAGMA integrity_check...'\nsqlite3 \"${LOCAL_DEST}\" \"PRAGMA integrity_check;\" | grep -q '^ok$' || {\n  echo \"Integrity check failed!\" >&2\n  exit 1\n}\n\n# === Step 3: Clean up the temp backup inside container ===\necho \"→ Cleaning up temp backup in container...\"\ndotenv kamal app exec \"rm -f '${CONTAINER_TMP_BACKUP}'\"\n\necho \"✅ Done. Local DB refreshed at: ${LOCAL_DEST}\"\n"
  },
  {
    "path": "bin/jobs",
    "content": "#!/usr/bin/env ruby\n\nrequire_relative \"../config/environment\"\nrequire \"solid_queue/cli\"\n\nSolidQueue::Cli.start(ARGV)\n"
  },
  {
    "path": "bin/lint",
    "content": "#!/usr/bin/env bash\n\n# Exit when any command fails\nset -e\n\n# Check Ruby code formatting\necho \"Checking Ruby code formatting...\"\nbundle exec standardrb --fix\n\n# Check Ruby code formatting\necho \"Checking JS code formatting...\"\nyarn format\n\n# Check erb file formatting\necho \"Checking erb file formatting...\"\nbundle exec erb_lint --lint-all --autocorrect\n\n# Check YAML file formatting\necho \"Checking YAML file formatting in data/ ...\"\nyarn format:yml\n\necho \"Validating Schema of files in data/ ...\"\nbin/rails validate:all\n"
  },
  {
    "path": "bin/mcp_server",
    "content": "#!/usr/bin/env ruby\n# frozen_string_literal: true\n\n# MCP Server for Claude Code\n# Run with: bin/mcp_server\n\nrequire_relative \"../config/environment\"\nrequire \"json\"\n\nclass MCPServer\n  PROTOCOL_VERSION = \"2024-11-05\"\n\n  def initialize\n    @tools = discover_tools\n  end\n\n  def run\n    $stderr.puts \"MCP Server started with #{@tools.size} tools\"\n\n    loop do\n      line = $stdin.gets\n      break if line.nil?\n\n      begin\n        request = JSON.parse(line)\n        response = handle_request(request)\n        send_response(response) if response\n      rescue JSON::ParserError => e\n        send_error(nil, -32700, \"Parse error: #{e.message}\")\n      rescue => e\n        send_error(request&.dig(\"id\"), -32603, \"Internal error: #{e.message}\")\n      end\n    end\n  end\n\n  private\n\n  def discover_tools\n    Dir[Rails.root.join(\"app/tools/**/*_tool.rb\")].each_with_object({}) do |file, tools|\n      require file\n      class_name = File.basename(file, \".rb\").camelize\n      tool_class = class_name.constantize\n      tools[tool_name(class_name)] = tool_class\n    end\n  end\n\n  def tool_name(class_name)\n    class_name.underscore.sub(/_tool$/, \"\")\n  end\n\n  def handle_request(request)\n    method = request[\"method\"]\n    id = request[\"id\"]\n    params = request[\"params\"] || {}\n\n    case method\n    when \"initialize\"\n      handle_initialize(id, params)\n    when \"notifications/initialized\"\n      nil\n    when \"tools/list\"\n      handle_tools_list(id)\n    when \"tools/call\"\n      handle_tools_call(id, params)\n    when \"ping\"\n      handle_ping(id)\n    else\n      error_response(id, -32601, \"Method not found: #{method}\")\n    end\n  end\n\n  def handle_initialize(id, params)\n    {\n      jsonrpc: \"2.0\",\n      id: id,\n      result: {\n        protocolVersion: PROTOCOL_VERSION,\n        capabilities: {tools: {}},\n        serverInfo: {name: \"rubyevents-mcp\", version: \"1.0.0\"}\n      }\n    }\n  end\n\n  def handle_ping(id)\n    {jsonrpc: \"2.0\", id: id, result: {}}\n  end\n\n  def handle_tools_list(id)\n    tools_list = @tools.map do |name, tool_class|\n      {\n        name: name,\n        description: tool_class.description,\n        inputSchema: build_input_schema(tool_class)\n      }\n    end\n\n    {jsonrpc: \"2.0\", id: id, result: {tools: tools_list}}\n  end\n\n  def handle_tools_call(id, params)\n    tool_name = params[\"name\"]\n    arguments = params[\"arguments\"] || {}\n\n    tool_class = @tools[tool_name]\n    return error_response(id, -32602, \"Unknown tool: #{tool_name}\") unless tool_class\n\n    tool = tool_class.new\n    result = tool.execute(**arguments.symbolize_keys)\n\n    {\n      jsonrpc: \"2.0\",\n      id: id,\n      result: {\n        content: [{type: \"text\", text: result.is_a?(String) ? result : JSON.pretty_generate(result)}]\n      }\n    }\n  rescue => e\n    {\n      jsonrpc: \"2.0\",\n      id: id,\n      result: {\n        content: [{type: \"text\", text: JSON.pretty_generate({error: e.message})}],\n        isError: true\n      }\n    }\n  end\n\n  def build_input_schema(tool_class)\n    schema = {type: \"object\", properties: {}, required: []}\n\n    if tool_class.respond_to?(:parameters)\n      tool_class.parameters.each do |name, param|\n        schema[:properties][name.to_s] = {\n          type: param.type || \"string\",\n          description: param.description\n        }\n        schema[:required] << name.to_s if param.required\n      end\n    end\n\n    schema\n  end\n\n  def send_response(response)\n    $stdout.puts JSON.generate(response)\n    $stdout.flush\n  end\n\n  def error_response(id, code, message)\n    {jsonrpc: \"2.0\", id: id, error: {code: code, message: message}}\n  end\n\n  def send_error(id, code, message)\n    send_response(error_response(id, code, message))\n  end\nend\n\nMCPServer.new.run\n"
  },
  {
    "path": "bin/rails",
    "content": "#!/usr/bin/env ruby\nAPP_PATH = File.expand_path(\"../config/application\", __dir__)\nrequire_relative \"../config/boot\"\nrequire \"rails/commands\"\n"
  },
  {
    "path": "bin/rake",
    "content": "#!/usr/bin/env ruby\nrequire_relative \"../config/boot\"\nrequire \"rake\"\nRake.application.run\n"
  },
  {
    "path": "bin/rubocop",
    "content": "#!/usr/bin/env ruby\nrequire \"rubygems\"\nrequire \"bundler/setup\"\n\n# Explicit RuboCop config increases performance slightly while avoiding config confusion.\nARGV.unshift(\"--config\", File.expand_path(\"../.rubocop.yml\", __dir__))\n\nload Gem.bin_path(\"rubocop\", \"rubocop\")\n"
  },
  {
    "path": "bin/setup",
    "content": "#!/usr/bin/env ruby\nrequire \"fileutils\"\n\nAPP_ROOT = File.expand_path(\"..\", __dir__)\nAPP_NAME = \"rubyevents\"\n\ndef system!(cmd)\n  system(cmd, exception: true)\nrescue StandardError => e\n  STDOUT.puts\n  STDOUT.puts \"Failed to run #{cmd}: #{e.message}\"\n  STDOUT.puts\n\n  raise\nend\n\nFileUtils.chdir APP_ROOT do\n  # This script is a way to set up or update your development environment automatically.\n  # This script is idempotent, so that you can run it at any time and get an expectable outcome.\n  # Add necessary setup steps to this file.\n\n  puts \"== Installing dependencies ==\"\n  system! \"gem install bundler --conservative\"\n  system(\"bundle check\") || system!(\"bundle install\")\n\n  # puts \"\\n== Copying sample files ==\"\n  # unless File.exist?(\"config/database.yml\")\n  #   FileUtils.cp \"config/database.yml.sample\", \"config/database.yml\"\n  # end\n\n  # puts \"\\n== Configuring puma-dev ==\"\n  # system \"ln -nfs #{APP_ROOT} ~/.puma-dev/#{APP_NAME}\"\n  # system \"curl -Is https://#{APP_NAME}.test/up | head -n 1\"\n  unless File.exist?(\".env\") || !File.exist?(\".env.sample\") # env.sample is not found in Docker\n    puts \"\\n== Copying .env.sample to .env ==\"\n    FileUtils.cp \".env.sample\", \".env\"\n  end\n\n  puts \"\\n== Installing node dependencies ==\"\n  system! \"yarn install\"\n\n  puts \"\\n== Preparing database ==\"\n  system! \"bin/rails db:prepare\"\n\n  puts \"\\n== Removing old logs and tempfiles ==\"\n  system! \"bin/rails log:clear tmp:clear\"\n\n  puts \"\\n== How to start the application ==\"\n  puts \"\\n use 'bin/dev' to start the Rails server, solid_queue and Vite\"\n\n  puts \"\\n== How to set up initial data ==\"\n  puts \"\\n use 'bin/rails db:seed:all' to set up initial data\"\n\n  unless ARGV.include?(\"--skip-server\")\n    puts \"\\n== Starting development server ==\"\n    STDOUT.flush # flush the output before exec(2) so that it displays\n    exec \"bin/dev\"\n  end\nend\n"
  },
  {
    "path": "bin/thrust",
    "content": "#!/usr/bin/env ruby\nrequire \"rubygems\"\nrequire \"bundler/setup\"\n\nload Gem.bin_path(\"thruster\", \"thrust\")\n"
  },
  {
    "path": "bin/update_lrug_meetups",
    "content": "#!/usr/bin/env bash\n\nset -e  # Exit on error\n\nif command -v mise &> /dev/null; then\n  eval \"$(mise activate bash)\"\nfi\n\ncurl https://lrug.org/rubyevents-video-playlist.yml > data/lrug/lrug-meetup/videos.yml\nnode yaml/enforce_strings.mjs data/lrug/lrug-meetup/videos.yml\nprettier -c data/lrug/lrug-meetup/videos.yml -w\ngit add data/lrug/lrug-meetup/videos.yml\ngit commit -m \"Update LRUG Meetups\"\n"
  },
  {
    "path": "bin/vite",
    "content": "#!/usr/bin/env ruby\n# frozen_string_literal: true\n\n#\n# This file was generated by Bundler.\n#\n# The application 'vite' is installed as part of a gem, and\n# this file is here to facilitate running it.\n#\n\nENV[\"BUNDLE_GEMFILE\"] ||= File.expand_path(\"../Gemfile\", __dir__)\n\nbundle_binstub = File.expand_path(\"bundle\", __dir__)\n\nif File.file?(bundle_binstub)\n  if File.read(bundle_binstub, 300).include?(\"This file was generated by Bundler\")\n    load(bundle_binstub)\n  else\n    abort(\"Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.\nReplace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.\")\n  end\nend\n\nrequire \"rubygems\"\nrequire \"bundler/setup\"\n\nload Gem.bin_path(\"vite_ruby\", \"vite\")\n"
  },
  {
    "path": "config/application.rb",
    "content": "require_relative \"boot\"\n\nrequire \"rails\"\n# Pick the frameworks you want:\nrequire \"active_model/railtie\"\nrequire \"active_job/railtie\"\nrequire \"active_record/railtie\"\nrequire \"active_storage/engine\"\nrequire \"action_controller/railtie\"\nrequire \"action_mailer/railtie\"\n# require \"action_mailbox/engine\"\nrequire \"action_text/engine\"\nrequire \"action_view/railtie\"\nrequire \"action_cable/engine\"\nrequire \"rails/test_unit/railtie\"\n\n# Require the gems listed in Gemfile, including any gems\n# you've limited to :test, :development, or :production.\nBundler.require(*Rails.groups)\n\nmodule RubyEvents\n  class Application < Rails::Application\n    # Initialize configuration defaults for originally generated Rails version.\n    config.load_defaults 8.1\n\n    # Please, add to the `ignore` list any other `lib` subdirectories that do\n    # not contain `.rb` files, or that should not be reloaded or eager loaded.\n    # Common ones are `templates`, `generators`, or `middleware`, for example.\n    config.autoload_lib(ignore: %w[assets tasks])\n\n    # Configuration for the application, engines, and railties goes here.\n    #\n    # These settings can be overridden in specific environments using the files\n    # in config/environments, which are processed later.\n    #\n    # config.time_zone = \"Central Time (US & Canada)\"\n    # config.eager_load_paths << Rails.root.join(\"extras\")\n    #\n    config.autoload_lib(ignore: %w[assets tasks protobuf guard generators])\n\n    config.active_job.queue_adapter = :solid_queue\n    config.solid_queue.connects_to = {database: {writing: :queue}}\n\n    # to remove once encrytion completed\n    config.active_record.encryption.support_unencrypted_data = true\n\n    # disable Mission Control auth as we use the route Authenticator\n    config.mission_control.jobs.http_basic_auth_enabled = false\n  end\nend\n"
  },
  {
    "path": "config/appsignal.yml",
    "content": "default:\n  &defaults # Your push api key, it is possible to set this dynamically using ERB:\n  push_api_key: \"<%= Rails.application.credentials.appsignal&.dig(:push_api_key) || ENV['APPSIGNAL_PUSH_API_KEY'] %>\"\n\n  # Your app's name\n  name: \"RubyVideo\"\n\n  # Enable host metrics for container monitoring\n  enable_host_metrics: true\n\n  # Set a static hostname to aggregate host metrics across deploys\n  # Without this, each container gets a unique hostname with the container ID\n  # Use APPSIGNAL_HOSTNAME env var to differentiate web vs job containers\n  hostname: \"<%= ENV.fetch('APPSIGNAL_HOSTNAME', 'rubyevents-vps') %>\"\n\n  # Actions that should not be monitored by AppSignal\n  ignore_actions:\n    - Rails::HealthController#show\n\n  # Errors that should not be recorded by AppSignal\n  # For more information see our docs:\n  # https://docs.appsignal.com/ruby/configuration/ignore-errors.html\n  # ignore_errors:\n  #   - Exception\n  #   - NoMemoryError\n  #   - ScriptError\n  #   - LoadError\n  #   - NotImplementedError\n  #   - SyntaxError\n  #   - SecurityError\n  #   - SignalException\n  #   - Interrupt\n  #   - SystemExit\n  #   - SystemStackError\n\n  # See https://docs.appsignal.com/ruby/configuration/options.html for\n  # all configuration options.\n\n# Configuration per environment, leave out an environment or set active\n# to false to not push metrics for that environment.\ndevelopment:\n  <<: *defaults\n  active: false\n\nproduction:\n  <<: *defaults\n  active: true\n\nstaging:\n  <<: *defaults\n  active: true\n"
  },
  {
    "path": "config/boot.rb",
    "content": "ENV[\"BUNDLE_GEMFILE\"] ||= File.expand_path(\"../Gemfile\", __dir__)\n\nrequire \"bundler/setup\" # Set up gems listed in the Gemfile.\nrequire \"bootsnap/setup\" # Speed up boot time by caching expensive operations.\n"
  },
  {
    "path": "config/bundler-audit.yml",
    "content": "# Audit all gems listed in the Gemfile for known security problems by running bin/bundler-audit.\n# CVEs that are not relevant to the application can be enumerated on the ignore list below.\n\nignore:\n  - CVE-THAT-DOES-NOT-APPLY\n"
  },
  {
    "path": "config/cable.yml",
    "content": "development:\n  adapter: async\n\ntest:\n  adapter: async\n\nproduction:\n  adapter: async\n"
  },
  {
    "path": "config/cache.yml",
    "content": "default: &default\n  database: cache\n  size_estimate_samples: 100\n  store_options:\n    max_age: <%= 60.days.to_i %>\n    max_size: <%= 1.gigabytes %>\n    namespace: <%= Rails.env %>\n    expiry_method: :job\n    expiry_queue: :low\n\ndevelopment:\n  <<: *default\n\ntest:\n  <<: *default\n\nstaging:\n  <<: *default\n\nproduction:\n  <<: *default\n"
  },
  {
    "path": "config/ci.rb",
    "content": "# Run using bin/ci\n\nCI.run do\n  step \"Style: Ruby\", \"bundle exec standardrb --fix\"\n  step \"Style: JS\", \"yarn format\"\n  step \"Style: ERB\", \"bundle exec erb_lint --lint-all --autocorrect\"\n  step \"Style: YAML\", \"yarn format:yml\"\n\n  step \"Security: Gem audit\", \"bin/bundler-audit\"\n  # step \"Security: Importmap vulnerability audit\", \"bin/importmap audit\"\n\n  step \"Tests: Rails\", \"bin/rails test\"\n  step \"Tests: System\", \"bin/rails test:system\"\n  # step \"Tests: Seeds\", \"env RAILS_ENV=test bin/rails db:seed:replant\"\n\n  # Optional: set a green GitHub commit status to unblock PR merge.\n  # Requires the `gh` CLI and `gh extension install basecamp/gh-signoff`.\n  # if success?\n  #   step \"Signoff: All systems go. Ready for merge and deploy.\", \"gh signoff\"\n  # else\n  #   failure \"Signoff: CI failed. Do not merge or deploy.\", \"Fix the issues and try again.\"\n  # end\nend\n"
  },
  {
    "path": "config/credentials/development.key",
    "content": "72f8f5453ad7bc95d52e0210095a943d"
  },
  {
    "path": "config/credentials/development.yml.enc",
    "content": "0IEwrEW40oNn/MYRx0ePkPgpvrg+0Kidnh01ZteKFXLckIjQCShmdUXeYe7Mky5RBhDXwMj/01vw6gLQjLuQoW+5yUUxbBwnd9bx9cNtR/dE9kJ4Wz9W7wKnvw4/t28COf7jOoyS97ibcP+rk/FKx0KHM1DLMO2ZK8ypxElJ+3ZjKulEjAfdgutGGLcXi8gQkbj06brDJdUJkHxBy0g006Xh3U6a6bvzabLzTFGeyyn7pJEOLo3FIOtgkCqaNslLbK+5a4OA3hiF5dRmNeJoe8z7EusU1Nr3hnKIrFHLKbGjspzGIby4hEEEcrSiR3CDDrT51Sqanw/jaOyAgSp6lJBrui4zAU9aNFwWb6wInxoh+Y2qOWDo1KF7Nc65WeM6dn/ojsWLZ8p3lwDsQWROf5a81Q8Gw9I4deZYh7nxIPiTHytMy+sF9TG4MNxsU1tQNFpLKcLGDusIAvBip5zaEWCMcmoUzNnRWsFqealfLVDtOKHu7/h8bMD6Am/GgnX1vdwqsHUgjtc0fw==--n33h9L0ZA83CjkxK--xoKDkI9CocR60YXb2G+jjQ=="
  },
  {
    "path": "config/credentials/production.yml.enc",
    "content": "BGeaAaR/RMWA44Rov4szQW9BpzUEi1D0P7eFF3YHyirpdcndjVlzdwwE+tXc2dk+ZEoWP9oBvPQVC3QjJG0mOF11AkACy5i/SlMI5fwt8b/zLA6wCAuLoTI2pP+zhJdT2aD4+q/Aqg1k1SJeKoBC8R6DmhQOMMC+ONruvhuHIxWDoPUGhO1+jdQf/g+nEyJqR1yH20KHIS1KRgNr9VIt5FTO9mzR+/qh/mAxJ0S2Pg9A7JfGjp/qr5oxXn8aOccNfOf0Zt9bz9OtT/OQqLsBK3HWyYP7uPgQKCUKe+lkEZDjKiLwbj/1M0sEx2mAfAls2AXzFljufwPB98Y5FeaeVGUJLlSCvDvE9Q2jas0rYgifZ9Ane0ETVF5hID70nCtSMu3u9+E1n0TvRtladdHg1CTZPuNRF/Yf5v6eFBN268qBh57Z3uNgx2474o8a8mDr2e60HQKFi6nvwCcfS3Sv42YDWEkcZMMFCq1PZhCwn7ThYuewkTQJkyCaTcw42jd5PpCJ6z7QeMMx/scyf1wVqVZVsOpLz33y/Y9Ir+xmL3TnjsXIuFzJdMk5xL3+UQ09A3bPX8n7ma8VFBaGhpQF/9TkV/FLdm79O9xBDh6asrOOBV4y6s+HIRCCoXBR8cHlw/ucjvpnhyRAmT4UOLee5IONpSajfnYuSf2ospiOAA1uFjwuXE8FoVn7YQBsG+/M057c/uTF3fpUJrqgODT02TwlTS7YcDfQMjM9mi+sXYBN/BENV5zXp/Mhwdo5izZlYmh+KatyiMDmqEK4Yp9QjgoBz/Wj7QsYTkcCJDXaPT8KUwOQMB71axbcqBUmOeWHgWPEywyovhmHVaztdb1EfcEVtkKQofWqQfvERTWCNQDNd1vOb8u5/PjeVPzydDIw/0U1r2UXzt+b6+JX3xHQrJueplkoJ/tsQCPyxj9ljoc4C2/qx6+Z4sWru+vMxN1rakkb6X9VTkPFaqB2H5NdRtYoww6whezGUb0YpnuSKCiw2DaWc/fQFqULFs520yEOmBCxFoM3AOZtpEhURpVU2SOn+c2NfZjtYYL2eByBjyvmovoPyVu9xhic3ON7TMNnTJF8/Zw8O+1h2kUJRO4K02pG6NIbY+ArtKgyNa9CRtDK+6i5z2cbDT5BYllDDHzOAIuyZlLT6zbW3Pd5ADu9UCQSkNW/7LBM6Ds8AvKnjsIpWFxfq71D5ja1YSQZgm4iputOS3dWqgvQZiZSZM8eyJPw7Hm7fRw1vkIZMdxLzt+L7joPQJMsAvV5C8dnN4I4xJ4KgInqyLDo6foAhVQXOziy/ZFD6zRLXwQzBJxLVuRS3b6N4O1ohK2ScOE3nwe/NGI=--xuVBbZ9kAoYzrTCb--jOSwSSI07tN5jlPLYiY/GQ=="
  },
  {
    "path": "config/credentials/staging.yml.enc",
    "content": "s7PNBdaT0cavaFVQ3QuZBeVdnR5REXt056UJpAm40gRYCPMoSNWQsauveG36PJrNTn4h09d0NPTec9m19xi2Fiho8I2eIskjGIfSHiqpm/2yx96JjJ51Bmkt7d/RtCeIxEWltZVke+aCLU4Pw/11P/aPVShO9xeizytXsZoTXyIwdP6XBoGcIwnc9RR3a+ZVZDSH+VEFVphTw2UWg0lYdLQM0n3t7km4DDlBZ9I8o48swecDexOLuAYDo2wWhFvgZXBXesu1XgP1iuXNejJdrg42xhcGuQVJnThaOYJgfq1qz7/4IuxFymjlqLIg5DKIav1cyEecGmYSDwmw+7yAm8vwWCADA9pZhp071oHWQR5Zq+MgVhpVgvOkSzXlR963ap/cNuwm+IDaKfsZP0qW9m6rlrlDr4tDgnkm0ymPJJrB0Pzwj/+/tcmg6cJKEjNj2bSZYu30KdJuyha+aFW8XXbFKtl+9x0ZogAoq8irTatNYcKzesJbyULq2yxuMM28MKrNF6+oSB2UtQh5Pr9lt97b+o9ijJlyJa8Z1hDKAEaWBHa85+iit3eqF7HdRoG1fIrPsSgAuozMwvIN4gPB6ice7RdrLO+oNN5zs4g7splqjjxsR21pzJM5onh7wDZjNHrMSGRNpBQEzMnw02npy8e/yhBBb4JmqiN4R1aavYK3A/VhnaunbllGzBHILZeI8LeNS2kQGnmLt2a8b+IL9lGtd2ERa+mgPVaPJpgtmEM7OcojJO8rtH1x6EFhlzEHY43vL3DaopiXOLa/jdYsfEKn6+Aaz3GhlzgrspdGrbVqktPuCFsxa9mUe9Cc76+zA3aTcE9nHj5RD3soQbKS6dbdbxHKN4TNZvfqVGPpDDikXZIdm74PHOtdjb6SDpayfolON7LbykypUiyjzT+t+gaYu+HfHoOHW5Nt3nrU8Xx+Sm3wUcxjjuay6c1vakAbyM06BsxW7cYMKJDJP7iQbOvmO966rhgXW/H37ZeRLLMOs7lD+zVHVFg2KewY/vItrGP3tqVoksZmkieqMpDsYhTLtUENyKrFc7nUg0wlTRn/N9r9X9ig5fW570+Afy4exEPmnrhX6nDKLJbUDeSWukqdUbbUZVz9DvXRhEKRrAmkiOIFyXxUfRYpxgGwz5SCkTUQtPBgiKdhZycY04oyxbmtVsOukisVEiReCgzGQYP/7gxqhiB4aFEzg2C+ru0XzMNY4rWtLQ5/l8erb1r06WuL0AX5R+8Rgs/2Hn+6tis7nH5SSEGrTKqsu1II--id4fEGNTG+eWltzT--IBw5NqAtqTGKAYuF57zc9w=="
  },
  {
    "path": "config/credentials/test.key",
    "content": "5fab4be5ef069dd2127b084bb86c4c70"
  },
  {
    "path": "config/credentials/test.yml.enc",
    "content": "1p8Eh6KdkpRPCf1hKjd2tkgZcqhVBKobvqZrmuzJvFjFP50aTzjpz0CgWDQ7JexX3Bk8EC5G3Hl4Gwgr3PUOXQtDGt+aEjTFA804UZOmP7N3A8Ub6SIy2pvpY0cuV2y5ln5FL/0wz/eDZd+qU1Fex1N/dk4fIIXQRNksBHbdlm5P1yGmioqPlrSC2HN+YAukX7zo463B1DFH9Yj+PNZPD2uiwYx4CZUPrHfvM8uGHdoRVg2MdIolLJ3HNLOtASBJ5neVLGheLKHdEJEND6QEPSZWb7XCkuV8obFE+yAWldChVvHKpNg4KUeU9R/wue+vL00Eklx6Pu8NezQaSFAIGxycP5fwdmpjhpqLe0b4LXzPST9KBJIyK885FW8Y22Q/RtNiKt+xzuWdcW7opnkJrkK/XWW0WxqNrWSsWjE392nqEoY2oU974TRWNuj8+HP9Lw==--BwXZhJwNKzNmfCWc--CWN1LSxp+nX4qAQCiuDYig=="
  },
  {
    "path": "config/database.yml",
    "content": "# SQLite. Versions 3.8.0 and up are supported.\n#   gem install sqlite3\n#\n#   Ensure the SQLite 3 gem is defined in your Gemfile\n#   gem \"sqlite3\"\n#\ndefault: &default\n  adapter: sqlite3\n  min_connections: 20\n  timeout: 5000\n\n# DATABASE CONFIGURATIONS\nprimary: &primary\n  <<: *default\n  database: storage/<%= Rails.env %>_rubyvideo.sqlite3\n\ncache: &cache\n  <<: *default\n  migrations_paths: db/cache_migrate\n  database: storage/<%= Rails.env %>_rubyvideo-cache.sqlite3\n\nqueue: &queue\n  <<: *default\n  migrations_paths: db/queue_migrate\n  database: storage/<%= Rails.env %>_rubyvideo-queue.sqlite3\n\ndevelopment:\n  primary: *primary\n  cache: *cache\n  queue: *queue\n\ntest:\n  primary: *primary\n  cache: *cache\n  queue: *queue\n\nstaging:\n  primary: *primary\n  cache: *cache\n  queue: *queue\n\nproduction:\n  primary: *primary\n  cache: *cache\n  queue: *queue\n"
  },
  {
    "path": "config/deploy.staging.yml",
    "content": "<% require \"dotenv\"; Dotenv.load(\".env\") %>\n# Name of your application. Used to uniquely configure containers.\nservice: rubyvideo_staging\n\n# Name of the container image.\nimage: ghcr.io/rubyevents/rubyevents_staging\n\n# Deploy to these servers.\nservers:\n  web:\n    hosts:\n      - 138.199.198.123\n    options:\n      memory: 1GB\n      cpus: 1\n\n  job:\n    hosts:\n      - 138.199.198.123\n    cmd: bin/jobs\n    options:\n      memory: 1GB\n      cpus: 0.5\n\n# Enable SSL auto certification via Let's Encrypt and allow for multiple apps on a single web server.\n# Remove this section when using multiple web servers and ensure you terminate SSL at your load balancer.\n#\n# Note: If using Cloudflare, set encryption mode in SSL/TLS setting to \"Full\" to enable CF-to-app encryption.\nproxy:\n  ssl: true\n  hosts:\n    - staging.rubyevents.org\n  # kamal-proxy connects to your container over port 80, use `app_port` to specify a different port.\n  app_port: 80\n\n# Credentials for your image host.\nregistry:\n  server: ghcr.io\n  username: rubyevents\n  password:\n    - KAMAL_REGISTRY_PASSWORD\n\nenv:\n  clear:\n    WEB_CONCURRENCY: 1\n    RAILS_MAX_THREADS: 3\n    RAILS_ENV: staging\n    TYPESENSE_HOST: rubyvideo_staging-typesense\n    TYPESENSE_PORT: 8108\n    TYPESENSE_PROTOCOL: http\n  secret:\n    - RAILS_MASTER_KEY\n    - MAPBOX_ACCESS_TOKEN\n    - TYPESENSE_API_KEY\n\n# Aliases are triggered with \"bin/kamal <alias>\". You can overwrite arguments on invocation:\n# \"bin/kamal logs -r job\" will tail logs from the first server in the job section.\naliases:\n  console: app exec --interactive --reuse \"bin/rails console\"\n  shell: app exec --interactive --reuse \"bash\"\n  logs: app logs -f\n  dbc: app exec --interactive --reuse \"bin/rails dbconsole\"\n\n# Use a persistent storage volume for sqlite database files and local Active Storage files.\n# Recommended to change this to a mounted volume path that is backed up off server.\nvolumes:\n  - \"storage:/rails/storage\"\n\n# Bridge fingerprinted assets, like JS and CSS, between versions to avoid\n# hitting 404 on in-flight requests. Combines all files from new and old\n# version inside the asset_path.\nasset_path: /rails/public/assets\n\n# Configure the image builder.\nbuilder:\n  arch:\n    - amd64\n  cache:\n    type: gha\n    options: mode=max\n    image: rubyvideo-staging-build-cache\n  secrets:\n    - RAILS_MASTER_KEY\n  remote: false\n  local: true\n\n  # # Build image via remote server (useful for faster amd64 builds on arm64 computers)\n  # remote: ssh://docker@docker-builder-server\n  #\n  # # Pass arguments and secrets to the Docker build process\n  # args:\n  #   RUBY_VERSION: ruby-3.3.4\n  # secrets:\n  #   - GITHUB_TOKEN\n  #   - RAILS_MASTER_KEY\n# Use a different ssh user than root\n# ssh:\n#   user: app\n\n# Use accessory services (secrets come from .kamal/secrets).\n# accessories:\naccessories:\n  litestream:\n    roles: [\"web\"]\n    image: litestream/litestream\n    files: [\"config/litestream.staging.yml:/etc/litestream.yml\"]\n    volumes: [\"storage:/rails/storage\"]\n    cmd: replicate\n    env:\n      secret:\n        - LITESTREAM_ENDPOINT\n        - LITESTREAM_ACCESS_KEY_ID\n        - LITESTREAM_SECRET_ACCESS_KEY\n\n  chrome:\n    roles: [\"web\", \"job\"]\n    image: browserless/chrome:latest\n    port: 3000\n    env:\n      clear:\n        CONNECTION_TIMEOUT: \"60000\"\n        MAX_CONCURRENT_SESSIONS: \"5\"\n    options:\n      memory: 1GB\n      cpus: 0.5\n\n  typesense:\n    roles: [\"web\"]\n    image: typesense/typesense:27.1\n    port: \"8108:8108\"\n    volumes:\n      - \"typesense-data:/data\"\n    env:\n      clear:\n        TYPESENSE_DATA_DIR: /data\n        TYPESENSE_ENABLE_CORS: \"true\"\n      secret:\n        - TYPESENSE_API_KEY\n"
  },
  {
    "path": "config/deploy.yml",
    "content": "<% require \"dotenv\"; Dotenv.load(\".env\") %>\n# Name of your application. Used to uniquely configure containers.\nservice: rubyvideo\n\n# Name of the container image.\nimage: ghcr.io/rubyevents/rubyevents\n\n# Deploy to these servers.\nservers:\n  web:\n    hosts:\n      - 91.107.208.207\n    options:\n      memory: 4GB\n      cpus: 3\n    env:\n      clear:\n        APPSIGNAL_HOSTNAME: rubyevents-web\n\n  job:\n    hosts:\n      - 91.107.208.207\n    cmd: bin/jobs --mode=async\n    options:\n      memory: 1GB\n      cpus: 1\n    env:\n      clear:\n        APPSIGNAL_HOSTNAME: rubyevents-job\n\n# Enable SSL auto certification via Let's Encrypt (and allow for multiple apps on one server).\n# If using something like Cloudflare, it is recommended to set encryption mode\n# in Cloudflare's SSL/TLS setting to \"Full\" to enable end-to-end encryption.\nproxy:\n  ssl: true\n  hosts:\n    - rubyvideo.dev\n    - www.rubyvideo.dev\n    - rubyevents.org\n    - www.rubyevents.org\n  # kamal-proxy connects to your container over port 80, use `app_port` to specify a different port.\n  app_port: 80\n\n# Credentials for your image host.\nregistry:\n  server: ghcr.io\n  username: rubyevents\n  password:\n    - KAMAL_REGISTRY_PASSWORD\n\n# Configure builder setup.\nbuilder:\n  arch:\n    - arm64\n  cache:\n    type: gha\n    options: mode=max\n    image: rubyvideo-build-cache\n  secrets:\n    - RAILS_MASTER_KEY\n  local: true\n\nenv:\n  clear:\n    WEB_CONCURRENCY: 3\n    RAILS_MAX_THREADS: 3\n    RAILS_ENV: production\n    TYPESENSE_PORT: 443\n    TYPESENSE_PROTOCOL: https\n  secret:\n    - RAILS_MASTER_KEY\n    - GEOLOCATE_API_KEY\n    - MAPBOX_ACCESS_TOKEN\n    - TYPESENSE_API_KEY\n    - TYPESENSE_NODES\n    - TYPESENSE_NEAREST_NODE\n\n# Aliases are triggered with \"bin/kamal <alias>\". You can overwrite arguments on invocation:\n# \"bin/kamal logs -r job\" will tail logs from the first server in the job section.\n#\naliases:\n  shell: app exec --interactive --reuse \"bash\"\n  console: app exec --reuse -i \"bin/rails console\"\n  stats: server exec \"docker stats --no-stream\"\n  seed_all: app exec \"rake db:seed:all\"\n\n# Use a persistent storage volume.\n#\nvolumes:\n  - \"storage:/rails/storage\"\n\naccessories:\n  litestream:\n    roles: [\"web\"]\n    image: litestream/litestream\n    files: [\"config/litestream.yml:/etc/litestream.yml\"]\n    volumes: [\"storage:/rails/storage\"]\n    cmd: replicate\n    env:\n      secret:\n        - LITESTREAM_ENDPOINT\n        - LITESTREAM_ACCESS_KEY_ID\n        - LITESTREAM_SECRET_ACCESS_KEY\n\n  chrome:\n    roles: [\"web\", \"job\"]\n    image: browserless/chrome:latest\n    port: 3000\n    env:\n      clear:\n        CONNECTION_TIMEOUT: \"60000\"\n        MAX_CONCURRENT_SESSIONS: \"5\"\n    options:\n      memory: 1GB\n      cpus: 0.5\n\n  typesense:\n    roles: [\"web\"]\n    image: typesense/typesense:27.1\n    port: \"8108:8108\"\n    volumes:\n      - \"typesense-data:/data\"\n    env:\n      clear:\n        TYPESENSE_DATA_DIR: /data\n        TYPESENSE_ENABLE_CORS: \"true\"\n      secret:\n        - TYPESENSE_API_KEY\n"
  },
  {
    "path": "config/environment.rb",
    "content": "# Load the Rails application.\nrequire_relative \"application\"\n\n# Initialize the Rails application.\nRails.application.initialize!\n"
  },
  {
    "path": "config/environments/development.rb",
    "content": "require \"active_support/core_ext/integer/time\"\n\nRails.application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  # Make code changes take effect immediately without server restart.\n  config.enable_reloading = true\n\n  # Do not eager load code on boot.\n  config.eager_load = false\n\n  # Show full error reports.\n  config.consider_all_requests_local = true\n\n  # Enable server timing.\n  config.server_timing = true\n\n  # Enable/disable Action Controller caching. By default Action Controller caching is disabled.\n  # Run rails dev:cache to toggle Action Controller caching.\n  if Rails.root.join(\"tmp/caching-dev.txt\").exist?\n    config.action_controller.perform_caching = true\n    config.action_controller.enable_fragment_cache_logging = true\n\n    config.cache_store = :solid_cache_store\n    config.public_file_server.headers = {\"cache-control\" => \"public, max-age=#{2.days.to_i}\"}\n  else\n    config.action_controller.perform_caching = false\n\n    config.cache_store = :null_store\n  end\n\n  # Change to :null_store to avoid any caching.\n  # config.cache_store = :memory_store\n\n  # Store uploaded files on the local file system (see config/storage.yml for options).\n  config.active_storage.service = :local\n\n  # Enable serving of images with full URLs\n  config.asset_host = \"http://localhost:3000\"\n  # Enable serving of images, stylesheets, and JavaScripts from an asset server.\n  config.asset_host = lambda { |source, request = nil|\n    request&.host&.include?(\"localhost\") ? \"http://localhost:3000\" : \"#{request&.protocol}#{request&.host_with_port}\"\n  }\n\n  # Don't care if the mailer can't send.\n  config.action_mailer.raise_delivery_errors = false\n\n  # Make template changes take effect immediately.\n  config.action_mailer.perform_caching = false\n\n  # Set localhost to be used by links generated in mailer templates.\n  config.action_mailer.default_url_options = {host: \"localhost\", port: 3000}\n\n  # Print deprecation notices to the Rails logger.\n  config.active_support.deprecation = :log\n\n  # Raise an error on page load if there are pending migrations.\n  config.active_record.migration_error = :page_load\n\n  # Highlight code that triggered database queries in logs.\n  config.active_record.verbose_query_logs = true\n\n  # Append comments with runtime information tags to SQL queries in logs.\n  config.active_record.query_log_tags_enabled = true\n\n  # Highlight code that enqueued background job in logs.\n  config.active_job.verbose_enqueue_logs = true\n\n  # Suppress logger output for asset requests.\n  config.assets.quiet = true\n\n  # Raises error for missing translations.\n  # config.i18n.raise_on_missing_translations = true\n\n  # Annotate rendered view with file names.\n  config.action_view.annotate_rendered_view_with_filenames = true\n\n  # Uncomment if you wish to allow Action Cable access from any origin.\n  # config.action_cable.disable_request_forgery_protection = true\n\n  # Raise error when a before_action's only/except options reference missing actions.\n  config.action_controller.raise_on_missing_callback_actions = true\n\n  # Apply autocorrection by RuboCop to files generated by `bin/rails generate`.\n  # config.generators.apply_rubocop_autocorrect_after_generate!\n\n  config.file_watcher = ActiveSupport::EventedFileUpdateChecker\n\n  # View local server when hosted by GitHub Codespaces.\n  config.hosts << /^[a-zA-Z0-9-]+-\\d{4}\\.app\\.github\\.dev$/\n\n  # https://vite-ruby.netlify.app/guide/troubleshooting.html#safari-does-not-reflect-css-and-js-changes-in-development\n  # https://bugs.webkit.org/show_bug.cgi?id=193533\n  config.action_view.preload_links_header = false\n\n  config.solid_queue.logger = ActiveSupport::Logger.new($stdout)\n\n  if ENV[\"PROFILE\"]\n    config.cache_classes = true\n    config.eager_load = true\n\n    config.logger = ActiveSupport::Logger.new($stdout)\n    config.log_level = :info\n\n    config.public_file_server.headers = {\n      \"Cache-Control\" => \"max-age=315360000, public\",\n      \"Expires\" => \"Thu, 31 Dec 2037 23:55:55 GMT\"\n    }\n    config.assets.compile = false\n    config.assets.digest = true\n    config.assets.debug = false\n\n    config.active_record.migration_error = false\n    config.active_record.verbose_query_logs = false\n    config.action_view.cache_template_loading = true\n  end\nend\n"
  },
  {
    "path": "config/environments/production.rb",
    "content": "require \"active_support/core_ext/integer/time\"\n\nRails.application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  # Code is not reloaded between requests.\n  config.enable_reloading = false\n\n  # Eager load code on boot for better performance and memory savings (ignored by Rake tasks).\n  config.eager_load = true\n\n  # Full error reports are disabled.\n  config.consider_all_requests_local = false\n\n  # Turn on fragment caching in view templates.\n  config.action_controller.perform_caching = true\n\n  # Cache digest stamped assets for far-future expiry.\n  config.public_file_server.headers = {\"cache-control\" => \"public, max-age=#{1.year.to_i}\"}\n\n  # Enable serving of images, stylesheets, and JavaScripts from an asset server.\n  config.asset_host = lambda { |source, request = nil|\n    request&.host&.include?(\"rubyevents.org\") ? \"https://www.rubyevents.org\" : \"https://www.rubyvideo.dev\"\n  }\n\n  # Store uploaded files on the local file system (see config/storage.yml for options).\n  config.active_storage.service = :local\n\n  # Assume all access to the app is happening through a SSL-terminating reverse proxy.\n  config.assume_ssl = true\n\n  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.\n  # config.force_ssl = true\n\n  # Skip http-to-https redirect for the default health check endpoint.\n  # config.ssl_options = { redirect: { exclude: ->(request) { request.path == \"/up\" } } }\n\n  # Log to STDOUT with the current request id as a default log tag.\n  config.log_tags = [:request_id]\n  config.logger = ActiveSupport::TaggedLogging.logger($stdout)\n\n  # Change to \"debug\" to log everything (including potentially personally-identifiable information!).\n  config.log_level = ENV.fetch(\"RAILS_LOG_LEVEL\", \"info\")\n\n  # Prevent health checks from clogging up the logs.\n  config.silence_healthcheck_path = \"/up\"\n\n  # Don't log any deprecations.\n  config.active_support.report_deprecations = false\n\n  # Replace the default in-process memory cache store with a durable alternative.\n  config.cache_store = :solid_cache_store\n\n  # Replace the default in-process and non-durable queuing backend for Active Job.\n  config.active_job.queue_adapter = :solid_queue\n  config.solid_queue.connects_to = {database: {writing: :queue, reading: :queue}}\n\n  config.action_mailer.perform_caching = false\n\n  # Ignore bad email addresses and do not raise email delivery errors.\n  # Set this to true and configure the email server for immediate delivery to raise delivery errors.\n  # config.action_mailer.raise_delivery_errors = false\n\n  # Set host to be used by links generated in mailer templates.\n  config.action_mailer.default_url_options = {host: \"rubyvideo.dev\"}\n\n  # Specify outgoing SMTP server. Remember to add smtp/* credentials via bin/rails credentials:edit.\n  # config.action_mailer.smtp_settings = {\n  #   user_name: Rails.application.credentials.dig(:smtp, :user_name),\n  #   password: Rails.application.credentials.dig(:smtp, :password),\n  #   address: \"smtp.example.com\",\n  #   port: 587,\n  #   authentication: :plain\n  # }\n\n  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to\n  # the I18n.default_locale when a translation cannot be found).\n  config.i18n.fallbacks = true\n\n  # Do not dump schema after migrations.\n  config.active_record.dump_schema_after_migration = false\n\n  # Only use :id for inspections in production.\n  config.active_record.attributes_for_inspect = [:id]\n\n  # Enable DNS rebinding protection and other `Host` header attacks.\n  config.hosts = [\n    \"rubyvideo.dev\", # Allow requests to the server itself\n    /.*\\.rubyvideo\\.dev/, # Allow requests from subdomains like `www.example.com`\n    /^(.*\\.)?rubyevents\\.org/\n  ]\n  # Skip DNS rebinding protection for the default health check endpoint.\n  config.host_authorization = {exclude: ->(request) { request.path == \"/up\" }}\n\n  config.active_record.action_on_strict_loading_violation = :log\n\n  # Configure CORS to allow requests from the new domain\n  # config.middleware.insert_before 0, Rack::Cors do\n  #   allow do\n  #     origins \"rubyevents.org\", \"www.rubyevents.org\"\n  #     resource \"*\",\n  #       headers: :any,\n  #       methods: [:get, :options]\n  #   end\n  # end\nend\n"
  },
  {
    "path": "config/environments/staging.rb",
    "content": "require \"active_support/core_ext/integer/time\"\n\nRails.application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  # Code is not reloaded between requests.\n  config.enable_reloading = false\n\n  # Eager load code on boot for better performance and memory savings (ignored by Rake tasks).\n  config.eager_load = true\n\n  # Full error reports are disabled.\n  config.consider_all_requests_local = false\n\n  # Turn on fragment caching in view templates.\n  config.action_controller.perform_caching = true\n\n  # Cache digest stamped assets for far-future expiry.\n  config.public_file_server.headers = {\"cache-control\" => \"public, max-age=#{1.year.to_i}\"}\n\n  # Enable serving of images, stylesheets, and JavaScripts from an asset server.\n  config.asset_host = lambda { |source, request = nil|\n    request&.host&.include?(\"rubyevents.org\") ? \"https://staging.rubyevents.org\" : \"https://staging.rubyvideo.dev\"\n  }\n\n  # Store uploaded files on the local file system (see config/storage.yml for options).\n  config.active_storage.service = :local\n\n  # Assume all access to the app is happening through a SSL-terminating reverse proxy.\n  config.assume_ssl = true\n\n  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.\n  # config.force_ssl = true\n\n  # Skip http-to-https redirect for the default health check endpoint.\n  # config.ssl_options = { redirect: { exclude: ->(request) { request.path == \"/up\" } } }\n\n  # Log to STDOUT with the current request id as a default log tag.\n  config.log_tags = [:request_id]\n  config.logger = ActiveSupport::TaggedLogging.logger($stdout)\n\n  # Change to \"debug\" to log everything (including potentially personally-identifiable information!).\n  config.log_level = ENV.fetch(\"RAILS_LOG_LEVEL\", \"info\")\n\n  # Prevent health checks from clogging up the logs.\n  config.silence_healthcheck_path = \"/up\"\n\n  # Don't log any deprecations.\n  config.active_support.report_deprecations = false\n\n  # Replace the default in-process memory cache store with a durable alternative.\n  config.cache_store = :solid_cache_store\n\n  # Replace the default in-process and non-durable queuing backend for Active Job.\n  config.active_job.queue_adapter = :solid_queue\n  config.solid_queue.connects_to = {database: {writing: :queue, reading: :queue}}\n\n  config.action_mailer.perform_caching = false\n\n  # Ignore bad email addresses and do not raise email delivery errors.\n  # Set this to true and configure the email server for immediate delivery to raise delivery errors.\n  # config.action_mailer.raise_delivery_errors = false\n\n  # Set host to be used by links generated in mailer templates.\n  config.action_mailer.default_url_options = {host: \"staging.rubyvideo.dev\"}\n\n  # Specify outgoing SMTP server. Remember to add smtp/* credentials via bin/rails credentials:edit.\n  # config.action_mailer.smtp_settings = {\n  #   user_name: Rails.application.credentials.dig(:smtp, :user_name),\n  #   password: Rails.application.credentials.dig(:smtp, :password),\n  #   address: \"smtp.example.com\",\n  #   port: 587,\n  #   authentication: :plain\n  # }\n\n  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to\n  # the I18n.default_locale when a translation cannot be found).\n  config.i18n.fallbacks = true\n\n  # Do not dump schema after migrations.\n  config.active_record.dump_schema_after_migration = false\n\n  # Only use :id for inspections in production.\n  config.active_record.attributes_for_inspect = [:id]\n\n  # Enable DNS rebinding protection and other `Host` header attacks.\n  config.hosts = [\n    \"rubyvideo.dev\", # Allow requests to the server itself\n    /.*\\.rubyvideo\\.dev/, # Allow requests from subdomains like `www.example.com`\n    /.*\\.adrienpoly\\.com/, # Allow requests from subdomains like `www.example.com`\n    /.*\\.rubyevents\\.org/\n  ]\n  # Skip DNS rebinding protection for the default health check endpoint.\n  config.host_authorization = {exclude: ->(request) { request.path == \"/up\" }}\n\n  config.active_record.action_on_strict_loading_violation = :log\n\n  # Configure CORS to allow requests from the new domain\n  # config.middleware.insert_before 0, Rack::Cors do\n  #   allow do\n  #     origins \"rubyevents.org\", \"www.rubyevents.org\"\n  #     resource \"*\",\n  #       headers: :any,\n  #       methods: [:get, :options]\n  #   end\n  # end\nend\n"
  },
  {
    "path": "config/environments/test.rb",
    "content": "# The test environment is used exclusively to run your application's\n# test suite. You never need to work with it otherwise. Remember that\n# your test database is \"scratch space\" for the test suite and is wiped\n# and recreated between test runs. Don't rely on the data there!\n\nRails.application.configure do\n  # Settings specified here will take precedence over those in config/application.rb.\n\n  # While tests run files are not watched, reloading is not necessary.\n  config.enable_reloading = false\n\n  # Eager loading loads your entire application. When running a single test locally,\n  # this is usually not necessary, and can slow down your test suite. However, it's\n  # recommended that you enable it in continuous integration systems to ensure eager\n  # loading is working properly before deploying your code.\n  config.eager_load = ENV[\"CI\"].present?\n\n  # Configure public file server for tests with cache-control for performance.\n  config.public_file_server.headers = {\"cache-control\" => \"public, max-age=3600\"}\n\n  # Show full error reports.\n  config.consider_all_requests_local = true\n\n  config.cache_store = :solid_cache_store\n\n  # Render exception templates for rescuable exceptions and raise for other exceptions.\n  config.action_dispatch.show_exceptions = :rescuable\n\n  # Disable request forgery protection in test environment.\n  config.action_controller.allow_forgery_protection = false\n\n  # Store uploaded files on the local file system in a temporary directory.\n  config.active_storage.service = :test\n\n  # Tell Action Mailer not to deliver emails to the real world.\n  # The :test delivery method accumulates sent emails in the\n  # ActionMailer::Base.deliveries array.\n  config.action_mailer.delivery_method = :test\n\n  # Set host to be used by links generated in mailer templates.\n  config.action_mailer.default_url_options = {host: \"example.com\"}\n\n  # Print deprecation notices to the stderr.\n  config.active_support.deprecation = :stderr\n\n  # Raises error for missing translations.\n  # config.i18n.raise_on_missing_translations = true\n\n  # Annotate rendered view with file names.\n  # config.action_view.annotate_rendered_view_with_filenames = true\n\n  # Raise error when a before_action's only/except options reference missing actions.\n  config.action_controller.raise_on_missing_callback_actions = true\n\n  config.active_job.queue_adapter = :test\n\n  # encryption\n  config.active_record.encryption.encrypt_fixtures = true\nend\n"
  },
  {
    "path": "config/initializers/active_genie.rb",
    "content": "ActiveGenie.configure do |config|\n  config.providers.openai.api_key = Rails.application.credentials.open_ai&.dig(:access_token) || ENV[\"OPENAI_ACCESS_TOKEN\"]\nend\n"
  },
  {
    "path": "config/initializers/ahoy.rb",
    "content": "class Ahoy::Store < Ahoy::DatabaseStore\nend\n\n# set to true for JavaScript tracking\nAhoy.api = false\n\n# set to true for geocoding (and add the geocoder gem to your Gemfile)\n# we recommend configuring local geocoding as well\n# see https://github.com/ankane/ahoy#geocoding\nAhoy.geocode = false\n"
  },
  {
    "path": "config/initializers/assets.rb",
    "content": "# Be sure to restart your server when you modify this file.\n\n# Version of your assets, change this if you want to expire all your assets.\nRails.application.config.assets.version = \"1.0\"\n\n# Add additional assets to the asset load path.\n# Rails.application.config.assets.paths << Emoji.images_path\n"
  },
  {
    "path": "config/initializers/avo.rb",
    "content": "# Ignore avo-pro directories when the gem isn't loaded\n# https://docs.avohq.io/3.0/gem-server-authentication.html#bundle-without-paid-gems\nunless defined?(Avo::Cards::BaseCard)\n  Rails.autoloaders.main.ignore(Rails.root.join(\"app/avo/cards\"))\nend\n\nunless defined?(Avo::Dashboards::BaseDashboard)\n  Rails.autoloaders.main.ignore(Rails.root.join(\"app/avo/dashboards\"))\nend\n\n# For more information regarding these settings check out our docs https://docs.avohq.io\n# The values disaplayed here are the default ones. Uncomment and change them to fit your needs.\nAvo.configure do |config|\n  ## == Routing ==\n  config.root_path = \"/admin\"\n  # used only when you have custom `map` configuration in your config.ru\n  # config.prefix_path = \"/internal\"\n\n  # Sometimes you might want to mount Avo's engines yourself.\n  # https://docs.avohq.io/3.0/routing.html\n  # config.mount_avo_engines = true\n\n  # Where should the user be redirected when visiting the `/avo` url\n  # config.home_path = nil\n\n  ## == Licensing ==\n  # config.license_key = ENV['AVO_LICENSE_KEY']\n\n  ## == Set the context ==\n  config.set_context do\n    # Return a context object that gets evaluated in Avo::ApplicationController\n  end\n\n  ## == Authentication ==\n  # config.current_user_method = {}\n  # config.authenticate_with do\n  # end\n\n  ## == Authorization ==\n  # config.authorization_methods = {\n  #   index: 'index?',\n  #   show: 'show?',\n  #   edit: 'edit?',\n  #   new: 'new?',\n  #   update: 'update?',\n  #   create: 'create?',\n  #   destroy: 'destroy?',\n  #   search: 'search?',\n  # }\n  # config.raise_error_on_missing_policy = false\n  config.authorization_client = nil\n\n  ## == Localization ==\n  # config.locale = 'en-US'\n\n  ## == Resource options ==\n  # config.resource_controls_placement = :right\n  # config.model_resource_mapping = {}\n  # config.default_view_type = :table\n  # config.per_page = 24\n  # config.per_page_steps = [12, 24, 48, 72]\n  # config.via_per_page = 8\n  # config.id_links_to_resource = false\n\n  ## == Cache options ==\n  ## Provide a lambda to customize the cache store used by Avo.\n  ## We compute the cache store by default, this is NOT the default, just an example.\n  config.cache_store = -> {\n    ActiveSupport::Cache.lookup_store(:solid_cache_store)\n  }\n  # config.cache_resources_on_index_view = true\n  ## permanent enable or disable cache_resource_filters, default value is false\n  # config.cache_resource_filters = false\n  ## provide a lambda to enable or disable cache_resource_filters per user/resource.\n  # config.cache_resource_filters = -> { current_user.cache_resource_filters? }\n\n  ## == Logger ==\n  # config.logger = -> {\n  #   file_logger = ActiveSupport::Logger.new(Rails.root.join(\"log\", \"avo.log\"))\n  #\n  #   file_logger.datetime_format = \"%Y-%m-%d %H:%M:%S\"\n  #   file_logger.formatter = proc do |severity, time, progname, msg|\n  #     \"[Avo] #{time}: #{msg}\\n\".tap do |i|\n  #       puts i\n  #     end\n  #   end\n  #\n  #   file_logger\n  # }\n  #\n  config.associations_lookup_list_limit = 10000\n\n  ## == Customization ==\n  config.app_name = \"RubyEvents\"\n  # config.timezone = 'UTC'\n  # config.currency = 'USD'\n  # config.hide_layout_when_printing = false\n  # config.full_width_container = false\n  # config.full_width_index_view = false\n  # config.search_debounce = 300\n  # config.view_component_path = \"app/components\"\n  # config.display_license_request_timeout_error = true\n  # config.disabled_features = []\n  # config.buttons_on_form_footers = true\n  # config.field_wrapper_layout = true\n  # config.resource_parent_controller = \"Avo::ResourcesController\"\n\n  ## == Branding ==\n  # config.branding = {\n  #   colors: {\n  #     background: \"248 246 242\",\n  #     100 => \"#CEE7F8\",\n  #     400 => \"#399EE5\",\n  #     500 => \"#0886DE\",\n  #     600 => \"#066BB2\",\n  #   },\n  #   chart_colors: [\"#0B8AE2\", \"#34C683\", \"#2AB1EE\", \"#34C6A8\"],\n  #   logo: \"/avo-assets/logo.png\",\n  #   logomark: \"/avo-assets/logomark.png\",\n  #   placeholder: \"/avo-assets/placeholder.svg\",\n  #   favicon: \"/avo-assets/favicon.ico\"\n  # }\n\n  ## == Breadcrumbs ==\n  # config.display_breadcrumbs = true\n  # config.set_initial_breadcrumbs do\n  #   add_breadcrumb \"Home\", '/avo'\n  # end\n\n  ## == Menus ==\n  # config.main_menu = -> {\n  #   section \"Dashboards\", icon: \"dashboards\" do\n  #     all_dashboards\n  #   end\n\n  #   section \"Resources\", icon: \"resources\" do\n  #     all_resources\n  #   end\n\n  #   section \"Tools\", icon: \"tools\" do\n  #     all_tools\n  #   end\n  # }\n  # config.profile_menu = -> {\n  #   link \"Profile\", path: \"/avo/profile\", icon: \"user-circle\"\n  # }\nend\n\nRails.configuration.to_prepare do\n  Avo::ApplicationController.include Appsignal::AdminNamespace\nend\n"
  },
  {
    "path": "config/initializers/content_security_policy.rb",
    "content": "# Be sure to restart your server when you modify this file.\n\n# Define an application-wide content security policy.\n# See the Securing Rails Applications Guide for more information:\n# https://guides.rubyonrails.org/security.html#content-security-policy-header\n\n# Rails.application.configure do\n#   config.content_security_policy do |policy|\n#     policy.default_src :self, :https\n#     policy.font_src    :self, :https, :data\n#     policy.img_src     :self, :https, :data\n#     policy.object_src  :none\n#     policy.script_src  :self, :https\n#     policy.style_src   :self, :https\n#     # Specify URI for violation reports\n#     # policy.report_uri \"/csp-violation-report-endpoint\"\n#   end\n#\n#   # Generate session nonces for permitted importmap, inline scripts, and inline styles.\n#   config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }\n#   config.content_security_policy_nonce_directives = %w(script-src style-src)\n#\n#   # Automatically add `nonce` to `javascript_tag`, `javascript_include_tag`, and `stylesheet_link_tag`\n#   # if the corresponding directives are specified in `content_security_policy_nonce_directives`.\n#   # config.content_security_policy_nonce_auto = true\n#\n#   # Report violations without enforcing the policy.\n#   # config.content_security_policy_report_only = true\n# end\n"
  },
  {
    "path": "config/initializers/filter_parameter_logging.rb",
    "content": "# Be sure to restart your server when you modify this file.\n\n# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.\n# Use this to limit dissemination of sensitive information.\n# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.\nRails.application.config.filter_parameters += [\n  :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc\n]\n"
  },
  {
    "path": "config/initializers/geocoder.rb",
    "content": "# frozen_string_literal: true\n\nclass GeocoderCacheStore\n  def [](key)\n    GeocodeResult.find_by(query: normalize_key(key))&.response_body\n  end\n\n  def []=(key, value)\n    normalized_key = normalize_key(key)\n    return if normalized_key.blank? || value.blank?\n\n    GeocodeResult.find_or_initialize_by(query: normalized_key).update!(\n      response_body: value.to_s\n    )\n  rescue ActiveRecord::RecordInvalid => e\n    Rails.logger.warn \"GeocodeResult::CacheStore failed to cache: #{e.message}\"\n\n    nil\n  end\n\n  def del(key)\n    GeocodeResult.where(query: normalize_key(key)).destroy_all\n  end\n\n  def keys\n    GeocodeResult.pluck(:query)\n  end\n\n  alias_method :read, :[]\n  alias_method :get, :[]\n  alias_method :write, :[]=\n  alias_method :set, :[]=\n  alias_method :delete, :del\n\n  private\n\n  def normalize_key(key)\n    key.to_s.strip.downcase.gsub(/\\s+/, \" \")\n  end\nend\n\ngoogle_api_key = ENV[\"GEOLOCATE_API_KEY\"]\n\nif google_api_key.present? && google_api_key != \"YOUR_GEOLOCATE_API\"\n  Geocoder.configure(\n    lookup: :google,\n    api_key: google_api_key,\n    timeout: 5,\n    use_https: true,\n    cache: GeocoderCacheStore.new\n  )\nelsif Rails.env.development?\n  git_name = `git config user.name 2>/dev/null`.strip.presence\n\n  # Fallback to a generic name if git user.name is not set\n  # which is common when first building a devcontainer\n  anonymous_user = \"RubyEvents DevWithNoGitNameConfigured\" if git_name.blank?\n\n  # Nominatim usage policy requires a valid User-Agent identifying the application\n  # and a way to contact the application maintainer\n  # https://operations.osmfoundation.org/policies/nominatim/\n\n  # Please set your git user.name or modify the anonymous_user string above\n  Rails.logger.error \"Nominatim requires contact info. Please set your git user.name.\"\n\n  Geocoder.configure(\n    lookup: :nominatim,\n    timeout: 5,\n    use_https: true,\n    cache: GeocoderCacheStore.new,\n    http_headers: {\"User-Agent\" => git_name || anonymous_user}\n  )\nend\n"
  },
  {
    "path": "config/initializers/groupe_date.rb",
    "content": "# https://github.com/ankane/groupdate/pull/277\n\nGroupdate.register_adapter \"litedb\", Groupdate::Adapters::SQLiteAdapter\n"
  },
  {
    "path": "config/initializers/inflections.rb",
    "content": "# Be sure to restart your server when you modify this file.\n\n# Add new inflection rules using the following format. Inflections\n# are locale specific, and you may define rules for as many different\n# locales as you wish. All of these examples are active by default:\n# ActiveSupport::Inflector.inflections(:en) do |inflect|\n#   inflect.plural /^(ox)$/i, \"\\\\1en\"\n#   inflect.singular /^(ox)en/i, \"\\\\1\"\n#   inflect.irregular \"person\", \"people\"\n#   inflect.uncountable %w( fish sheep )\n# end\n\n# These inflection rules are supported but not enabled by default:\nActiveSupport::Inflector.inflections(:en) do |inflect|\n  inflect.acronym \"CFP\"\n  inflect.acronym \"FTS\"\n  inflect.acronym \"GitHub\"\n  inflect.acronym \"IOS\"\n  inflect.acronym \"LLM\"\n  inflect.acronym \"RubyEvents\"\n  inflect.acronym \"SQL\"\n  inflect.acronym \"SQLite\"\n  inflect.acronym \"SQLiteFTS\"\n  inflect.acronym \"UK\"\n  inflect.acronym \"YAML\"\n  inflect.acronym \"YouTube\"\nend\n"
  },
  {
    "path": "config/initializers/locale.rb",
    "content": "I18n.load_path += Dir[Rails.root.join(\"config\", \"locales\", \"**\", \"*.{rb,yml}\")]\n\nI18n.available_locales = [:en]\n\nI18n.default_locale = :en\n"
  },
  {
    "path": "config/initializers/markdown.rb",
    "content": "module Handlers\n  class CustomRenderer < Redcarpet::Render::HTML\n    # Override the link method to add target=\"_blank\" and rel=\"noopener noreferrer\"\n    def link(link, title, content)\n      %(<a href=\"#{link}\" target=\"_blank\" rel=\"noopener noreferrer\" #{\"title=\\\"#{title}\\\"\" if title}>#{content}</a>)\n    end\n  end\n\n  class MarkdownHandler\n    def call(template, source)\n      # Use the custom renderer instead of the default one\n      renderer = CustomRenderer.new\n      markdown = Redcarpet::Markdown.new(renderer, autolink: true, tables: true)\n      rendered_content = markdown.render(source)\n\n      # Escape the rendered content to prevent string interpolation issues\n      escaped_content = rendered_content.gsub('\"', '\\\"').gsub(\"\\n\", \"\\\\n\")\n\n      %(\n        \"<div class='container my-8 markdown max-w-3xl'>#{escaped_content}</div>\".html_safe\n      )\n    end\n  end\nend\n\nActionView::Template.register_template_handler :md, Handlers::MarkdownHandler.new\n"
  },
  {
    "path": "config/initializers/meta_tags.rb",
    "content": "# frozen_string_literal: true\n\n# Use this setup block to configure all options available in MetaTags.\nMetaTags.configure do |config|\n  # How many characters should the title meta tag have at most. Default is 70.\n  # Set to nil or 0 to remove limits.\n  # config.title_limit = 70\n\n  # When true, site title will be truncated instead of title. Default is false.\n  # config.truncate_site_title_first = false\n\n  # Maximum length of the page description. Default is 300.\n  # Set to nil or 0 to remove limits.\n  # config.description_limit = 300\n\n  # Maximum length of the keywords meta tag. Default is 255.\n  # config.keywords_limit = 255\n\n  # Default separator for keywords meta tag (used when an Array passed with\n  # the list of keywords). Default is \", \".\n  # config.keywords_separator = ', '\n\n  # When true, keywords will be converted to lowercase, otherwise they will\n  # appear on the page as is. Default is true.\n  # config.keywords_lowercase = true\n\n  # When true, the output will not include new line characters between meta tags.\n  # Default is false.\n  # config.minify_output = false\n\n  # When false, generated meta tags will be self-closing (<meta ... />) instead\n  # of open (`<meta ...>`). Default is true.\n  # config.open_meta_tags = true\n\n  # List of additional meta tags that should use \"property\" attribute instead\n  # of \"name\" attribute in <meta> tags.\n  # config.property_tags.push(\n  #   'x-hearthstone:deck',\n  # )\nend\n"
  },
  {
    "path": "config/initializers/omniauth.rb",
    "content": "Rails.application.config.middleware.use OmniAuth::Builder do\n  provider :developer, fields: [:name, :github_handle] unless Rails.env.production? # You should replace it with your provider\n\n  github_client_id = Rails.application.credentials.dig(:github, :client_id) || ENV[\"GITHUB_CLIENT_ID\"]\n  github_client_secret = Rails.application.credentials.dig(:github, :client_secret) || ENV[\"GITHUB_CLIENT_SECRET\"]\n  provider :github, github_client_id, github_client_secret, scope: \"read:user,user:email\"\nend\n"
  },
  {
    "path": "config/initializers/openai.rb",
    "content": "OpenAI.configure do |config|\n  config.access_token = Rails.application.credentials.open_ai&.dig(:access_token) || ENV[\"OPENAI_ACCESS_TOKEN\"]\n  config.organization_id = Rails.application.credentials.open_ai&.dig(:organization_id) || ENV[\"OPENAI_ORGANIZATION_ID\"]\n  config.log_errors = Rails.env.development?\n  config.request_timeout = 1800 # with flex tier we can have very long requests\nend\n"
  },
  {
    "path": "config/initializers/pagy.rb",
    "content": "require \"pagy/extras/overflow\"\nrequire \"pagy/extras/gearbox\"\nrequire \"pagy/extras/countless\"\nrequire \"pagy/extras/array\"\n\nPagy::DEFAULT[:overflow] = :last_page\nPagy::DEFAULT[:gearbox_extra] = false\n"
  },
  {
    "path": "config/initializers/permissions_policy.rb",
    "content": "# Be sure to restart your server when you modify this file.\n\n# Define an application-wide HTTP permissions policy. For further\n# information see: https://developers.google.com/web/updates/2018/06/feature-policy\n\n# Rails.application.config.permissions_policy do |policy|\n#   policy.camera      :none\n#   policy.gyroscope   :none\n#   policy.microphone  :none\n#   policy.usb         :none\n#   policy.fullscreen  :self\n#   policy.payment     :self, \"https://secure.example.com\"\n# end\n"
  },
  {
    "path": "config/initializers/reactionview.rb",
    "content": "# frozen_string_literal: true\n\nReActionView.configure do |config|\n  # Intercept .html.erb templates and process them with `Herb::Engine` for enhanced features\n  config.intercept_erb = true\n\n  # Enable debug mode in development (adds debug attributes to HTML)\n  config.debug_mode = Rails.env.development?\n\n  # Add custom transform visitors to process templates before compilation\n  # config.transform_visitors = [\n  #   Herb::Visitor::new\n  # ]\nend\n"
  },
  {
    "path": "config/initializers/ruby_llm.rb",
    "content": "require \"ruby_llm\"\n\nRubyLLM.configure do |config|\n  config.openai_api_key = ENV[\"OPENAI_API_KEY\"]\n  # config.default_model = \"gpt-4.1-nano\"\n\n  # Enable the new Rails-like API\n  config.use_new_acts_as = true\nend\n"
  },
  {
    "path": "config/initializers/typesense.rb",
    "content": "# frozen_string_literal: true\n\n# Typesense Cloud configuration with Search Delivery Network (SDN) support\n#\n# For local development (single node):\n#   TYPESENSE_HOST=localhost\n#   TYPESENSE_PORT=8108\n#   TYPESENSE_PROTOCOL=http\n#   TYPESENSE_API_KEY=xyz\n#\n# For Typesense Cloud with SDN (multiple nodes):\n#   TYPESENSE_NEAREST_NODE=xxx.a1.typesense.net\n#   TYPESENSE_NODES=xxx-1.a1.typesense.net,xxx-2.a1.typesense.net,xxx-3.a1.typesense.net\n#   TYPESENSE_PORT=443\n#   TYPESENSE_PROTOCOL=https\n#   TYPESENSE_API_KEY=your-api-key\n\ntypesense_config = {\n  api_key: ENV.fetch(\"TYPESENSE_API_KEY\", \"xyz\"),\n  connection_timeout_seconds: 2,\n  log_level: Rails.env.development? ? :debug : :info,\n  pagination_backend: :pagy\n}\n\nif ENV[\"TYPESENSE_NODES\"].present?\n  port = ENV.fetch(\"TYPESENSE_PORT\", \"443\").to_i\n  protocol = ENV.fetch(\"TYPESENSE_PROTOCOL\", \"https\")\n\n  typesense_config[:nodes] = ENV[\"TYPESENSE_NODES\"].split(\",\").map do |host|\n    {host: host.strip, port: port, protocol: protocol}\n  end\n\n  if ENV[\"TYPESENSE_NEAREST_NODE\"].present?\n    typesense_config[:nearest_node] = {\n      host: ENV[\"TYPESENSE_NEAREST_NODE\"],\n      port: port,\n      protocol: protocol\n    }\n  end\nelse\n  typesense_config[:nodes] = [{\n    host: ENV.fetch(\"TYPESENSE_HOST\", \"localhost\"),\n    port: ENV.fetch(\"TYPESENSE_PORT\", \"8108\").to_i,\n    protocol: ENV.fetch(\"TYPESENSE_PROTOCOL\", \"http\")\n  }]\nend\n\nTypesense.configuration = typesense_config\n"
  },
  {
    "path": "config/initializers/yjit.rb",
    "content": "Rails.application.configure do\n  # YJIT slows down the test suite and doesn't really help in development\n  # It will be disabled by default in Rails 8.1\n  # https://github.com/rails/rails/pull/53746\n\n  config.yjit = !Rails.env.local?\nend\n"
  },
  {
    "path": "config/initializers/yt.rb",
    "content": "require \"yt\"\n\napi_key = Rails.application.credentials.youtube&.dig(:api_key) || ENV[\"YOUTUBE_API_KEY\"]\n\nYt.configure do |config|\n  config.api_key = api_key\nend\n"
  },
  {
    "path": "config/litestream.staging.yml",
    "content": "# This is the actual configuration file for litestream.\n#\n# You can either use the generated `config/initializers/litestream.rb`\n# file to configure the litestream-ruby gem, which will populate these\n# ENV variables when using the `rails litestream:replicate` command.\n#\n# Or, if you prefer, manually manage ENV variables and this configuration file.\n# In that case, simply ensure that the ENV variables are set before running the\n# `replicate` command.\n#\n# For more details, see: https://litestream.io/reference/config/\n\n# global settings\nsync-interval: 60m\n\nsnapshot:\n  interval: 24h\n  retention: 24h # 1 day\n\ndbs:\n  - path: /rails/storage/staging_rubyvideo.sqlite3\n    replicas:\n      - type: s3\n        endpoint: $LITESTREAM_ENDPOINT\n        bucket: rubyevents-staging\n        path: storage/staging_rubyvideo.sqlite3\n        access-key-id: $LITESTREAM_ACCESS_KEY_ID\n        secret-access-key: $LITESTREAM_SECRET_ACCESS_KEY\n        retention: 24h # How long to keep WAL files on replica\n        retention-check-interval: 1h\n"
  },
  {
    "path": "config/litestream.yml",
    "content": "# This is the actual configuration file for litestream.\n#\n# You can either use the generated `config/initializers/litestream.rb`\n# file to configure the litestream-ruby gem, which will populate these\n# ENV variables when using the `rails litestream:replicate` command.\n#\n# Or, if you prefer, manually manage ENV variables and this configuration file.\n# In that case, simply ensure that the ENV variables are set before running the\n# `replicate` command.\n#\n# For more details, see: https://litestream.io/reference/config/\n\n# global settings\nsync-interval: 10m\n\nsnapshot:\n  interval: 24h\n  retention: 72h # 3 days\n\ndbs:\n  # production\n  - path: /rails/storage/production_rubyvideo.sqlite3\n    replicas:\n      - type: s3\n        endpoint: $LITESTREAM_ENDPOINT\n        bucket: rubyevents-production\n        path: storage/production_rubyvideo.sqlite3\n        access-key-id: $LITESTREAM_ACCESS_KEY_ID\n        secret-access-key: $LITESTREAM_SECRET_ACCESS_KEY\n        retention: 24h # How long to keep WAL files on replica\n        retention-check-interval: 1h\n"
  },
  {
    "path": "config/locales/en.yml",
    "content": "# Files in the config/locales directory are used for internationalization\n# and are automatically loaded by Rails. If you want to use locales other\n# than English, add the necessary files in this directory.\n#\n# To use the locales, use `I18n.t`:\n#\n#     I18n.t \"hello\"\n#\n# In views, this is aliased to just `t`:\n#\n#     <%= t(\"hello\") %>\n#\n# To use a different locale, set it with `I18n.locale`:\n#\n#     I18n.locale = :es\n#\n# This would use the information in config/locales/es.yml.\n#\n# The following keys must be escaped otherwise they will not be retrieved by\n# the default I18n backend:\n#\n# true, false, on, off, yes, no\n#\n# Instead, surround them with single quotes.\n#\n# en:\n#   'true': 'foo'\n#\n# To learn more, please read the Rails Internationalization guide\n# available at https://guides.rubyonrails.org/i18n.html.\n\nen:\n  date:\n    formats:\n      default: \"%B %d, %Y\"\n      medium: \"%b %d, %Y\"\n      month_day: \"%B %d\"\n"
  },
  {
    "path": "config/locales/models/event_participation.en.yml",
    "content": "en:\n  event_participation:\n    past:\n      attended_as:\n        keynote_speaker: Attended as Keynote Speaker\n        speaker: Attended as Speaker\n        visitor: Attended as Visitor\n    upcoming:\n      attended_as:\n        keynote_speaker: Will Attend as Keynote Speaker\n        speaker: Will Attend as Speaker\n        visitor: Will Attend as Visitor\n"
  },
  {
    "path": "config/locales/transliterate.en.yml",
    "content": "en:\n  i18n:\n    transliterate:\n      rule:\n        # German umlauts\n        ü: \"ue\"\n        ö: \"oe\"\n        ä: \"ae\"\n        ß: \"ss\"\n        ÿ: \"y\"\n\n        # Cyrillic characters (lowercase)\n        а: \"a\"\n        б: \"b\"\n        в: \"v\"\n        г: \"g\"\n        д: \"d\"\n        е: \"e\"\n        ё: \"yo\"\n        ж: \"zh\"\n        з: \"z\"\n        и: \"i\"\n        й: \"y\"\n        к: \"k\"\n        л: \"l\"\n        м: \"m\"\n        н: \"n\"\n        о: \"o\"\n        п: \"p\"\n        р: \"r\"\n        с: \"s\"\n        т: \"t\"\n        у: \"u\"\n        ф: \"f\"\n        х: \"h\"\n        ц: \"ts\"\n        ч: \"ch\"\n        ш: \"sh\"\n        щ: \"sch\"\n        ъ: \"\"\n        ы: \"y\"\n        ь: \"\"\n        э: \"e\"\n        ю: \"yu\"\n        я: \"ya\"\n\n        # Cyrillic characters (uppercase)\n        А: \"A\"\n        Б: \"B\"\n        В: \"V\"\n        Г: \"G\"\n        Д: \"D\"\n        Е: \"E\"\n        Ё: \"Yo\"\n        Ж: \"Zh\"\n        З: \"Z\"\n        И: \"I\"\n        Й: \"Y\"\n        К: \"K\"\n        Л: \"L\"\n        М: \"M\"\n        Н: \"N\"\n        О: \"O\"\n        П: \"P\"\n        Р: \"R\"\n        С: \"S\"\n        Т: \"T\"\n        У: \"U\"\n        Ф: \"F\"\n        Х: \"H\"\n        Ц: \"Ts\"\n        Ч: \"Ch\"\n        Ш: \"Sh\"\n        Щ: \"Sch\"\n        Ъ: \"\"\n        Ы: \"Y\"\n        Ь: \"\"\n        Э: \"E\"\n        Ю: \"Yu\"\n        Я: \"Ya\"\n"
  },
  {
    "path": "config/puma.rb",
    "content": "# This configuration file will be evaluated by Puma. The top-level methods that\n# are invoked here are part of Puma's configuration DSL. For more information\n# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.\n#\n# Puma starts a configurable number of processes (workers) and each process\n# serves each request in a thread from an internal thread pool.\n#\n# You can control the number of workers using ENV[\"WEB_CONCURRENCY\"]. You\n# should only set this value when you want to run 2 or more workers. The\n# default is already 1. You can set it to `auto` to automatically start a worker\n# for each available processor.\n#\n# The ideal number of threads per worker depends both on how much time the\n# application spends waiting for IO operations and on how much you wish to\n# prioritize throughput over latency.\n#\n# As a rule of thumb, increasing the number of threads will increase how much\n# traffic a given process can handle (throughput), but due to CRuby's\n# Global VM Lock (GVL) it has diminishing returns and will degrade the\n# response time (latency) of the application.\n#\n# The default is set to 3 threads as it's deemed a decent compromise between\n# throughput and latency for the average Rails application.\n#\n# Any libraries that use a connection pool or another resource pool should\n# be configured to provide at least as many connections as the number of\n# threads. This includes Active Record's `pool` parameter in `database.yml`.\nthreads_count = ENV.fetch(\"RAILS_MAX_THREADS\", 3)\nthreads threads_count, threads_count\n\n# Specifies the `port` that Puma will listen on to receive requests; default is 3000.\nport ENV.fetch(\"PORT\", 3000)\n\n# Allow puma to be restarted by `bin/rails restart` command.\nplugin :tmp_restart\n\n# Run the Solid Queue supervisor inside of Puma for single-server deployments.\nplugin :solid_queue if ENV[\"SOLID_QUEUE_IN_PUMA\"]\n\n# Specify the PID file. Defaults to tmp/pids/server.pid in development.\n# In other environments, only set the PID file if requested.\npidfile ENV[\"PIDFILE\"] if ENV[\"PIDFILE\"]\n"
  },
  {
    "path": "config/queue.yml",
    "content": "default: &default\n  dispatchers:\n    - polling_interval: 1\n      batch_size: 500\n  workers:\n    - queues: \"*\"\n      threads: 3\n      processes: <%= ENV.fetch(\"JOB_CONCURRENCY\", 1) %>\n      polling_interval: 0.1\n\ndevelopment:\n  <<: *default\n\ntest:\n  <<: *default\n\nstaging:\n  <<: *default\n\nproduction:\n  <<: *default\n"
  },
  {
    "path": "config/recurring.yml",
    "content": "youtube_video_statistics_job:\n  class: Recurring::YouTubeVideoStatisticsJob\n  schedule: every day at 1am\nyoutube_video_duration_job:\n  class: Recurring::YouTubeVideoDurationJob\n  schedule: every day at 3am\nyoutube_thumbnail_validation_job:\n  class: Recurring::YouTubeThumbnailValidationJob\n  schedule: every week on sunday at 4am\nyoutube_video_availability_job:\n  class: Recurring::YouTubeVideoAvailabilityJob\n  schedule: every week on sunday at 5am\nrollup_aggregate_analytics:\n  class: Recurring::RollupJob\n  schedule: every hour\nfetch_contributors:\n  class: Recurring::FetchContributorsJob\n  schedule: every day at 2am\nclear_solid_queue_finished_jobs:\n  command: \"SolidQueue::Job.clear_finished_in_batches(sleep_between_batches: 0.3)\"\n  schedule: every hour at minute 12\nmark_suspicious_users:\n  class: Recurring::MarkSuspiciousUsersJob\n  schedule: every 6 hours\n"
  },
  {
    "path": "config/routes.rb",
    "content": "# == Route Map\n#\n\nRails.application.routes.draw do\n  extend Authenticator\n\n  # static pages\n  get \"/uses\", to: \"page#uses\"\n  get \"/privacy\", to: \"page#privacy\"\n  get \"/components\", to: \"page#components\"\n  get \"/about\", to: \"page#about\"\n  get \"/stickers\", to: \"page#stickers\"\n  get \"/contributors\", to: \"page#contributors\"\n  get \"/stamps\", to: \"stamps#index\"\n  get \"/wrapped\", to: \"wrapped#index\"\n  get \"/pages/assets\", to: \"page#assets\"\n  get \"/featured\" => \"page#featured\"\n\n  # announcements/blog\n  resources :announcements, only: [:index, :show], param: :slug do\n    collection do\n      get :feed, defaults: {format: :rss}\n    end\n  end\n\n  resources :browse, only: [:index, :show]\n\n  # authentication\n  get \"/auth/failure\", to: \"sessions/omniauth#failure\"\n  get \"/auth/:provider/callback\", to: \"sessions/omniauth#create\"\n  post \"/auth/:provider/callback\", to: \"sessions/omniauth#create\"\n  resources :sessions, only: [:new, :create, :destroy]\n\n  resource :password, only: [:edit, :update]\n  resource :settings, only: [:show, :update]\n  namespace :identity do\n    resource :email, only: [:edit, :update]\n    resource :email_verification, only: [:show, :create]\n    resource :password_reset, only: [:new, :edit, :create, :update]\n  end\n\n  if Rails.env.development?\n    mount MissionControl::Jobs::Engine, at: \"/jobs\"\n    mount Avo::Engine, at: Avo.configuration.root_path\n    mount Avo::Dashboards::Engine, at: \"#{Avo.configuration.root_path}/dashboards\" if defined?(Avo::Dashboards::Engine)\n  else\n    authenticate :admin do\n      mount MissionControl::Jobs::Engine, at: \"/jobs\"\n      mount Avo::Engine, at: Avo.configuration.root_path\n      mount Avo::Dashboards::Engine, at: \"#{Avo.configuration.root_path}/dashboards\" if defined?(Avo::Dashboards::Engine)\n    end\n  end\n\n  resources :topics, param: :slug, only: [:index, :show]\n  resources :cfp, only: :index\n\n  resources :continents, param: :continent, only: [:index, :show] do\n    scope module: :locations do\n      resources :past, only: [:index]\n      resources :users, only: [:index]\n      resources :stamps, only: [:index]\n      resources :map, only: [:index]\n    end\n    resources :countries, only: [:index], module: :continents\n  end\n\n  resources :countries, param: :country, only: [:index, :show] do\n    scope module: :locations do\n      resources :past, only: [:index]\n      resources :users, only: [:index]\n      resources :meetups, only: [:index]\n      resources :stamps, only: [:index]\n      resources :map, only: [:index]\n    end\n    resources :cities, only: [:index], module: :countries\n  end\n\n  get \"/states\", to: \"states#index\", as: :states\n  get \"/states/:alpha2\", to: \"states#country_index\", as: :country_states\n  get \"/states/:state_alpha2/:state_slug\", to: \"states#show\", as: :state\n  scope \"/states/:state_alpha2/:state_slug\", as: :state do\n    scope module: :locations do\n      resources :past, only: [:index]\n      resources :users, only: [:index]\n      resources :meetups, only: [:index]\n      resources :stamps, only: [:index]\n      resources :map, only: [:index]\n    end\n    resources :cities, only: [:index], module: :states\n  end\n\n  get \"/cities\", to: \"cities#index\", as: :cities\n  get \"/cities/tokyo\", to: redirect(\"/states/jp/tokyo\", status: 301)\n\n  get \"/cities/:alpha2/:city\", to: \"cities#show_by_country\", as: :city_by_country, constraints: {alpha2: /[a-z]{2}/i}\n  scope \"/cities/:alpha2/:city\", as: :city_by_country, constraints: {alpha2: /[a-z]{2}/i} do\n    scope module: :locations do\n      resources :past, only: [:index]\n      resources :users, only: [:index]\n      resources :meetups, only: [:index]\n      resources :stamps, only: [:index]\n      resources :map, only: [:index]\n    end\n  end\n\n  get \"/cities/:alpha2/:state/:city\", to: \"cities#show_with_state\", as: :city_with_state, constraints: {alpha2: /[a-z]{2}/i}\n  scope \"/cities/:alpha2/:state/:city\", as: :city_with_state, constraints: {alpha2: /[a-z]{2}/i} do\n    scope module: :locations do\n      resources :past, only: [:index]\n      resources :users, only: [:index]\n      resources :meetups, only: [:index]\n      resources :stamps, only: [:index]\n      resources :map, only: [:index]\n    end\n  end\n\n  get \"/cities/:slug\", to: \"cities#show\", as: :city\n  scope \"/cities/:slug\", as: :city do\n    scope module: :locations do\n      resources :past, only: [:index]\n      resources :users, only: [:index]\n      resources :meetups, only: [:index]\n      resources :stamps, only: [:index]\n      resources :map, only: [:index]\n    end\n  end\n\n  resources :featured_cities, only: [:create, :destroy], param: :slug\n\n  get \"/locations/online\", to: \"online#show\", as: :online\n  scope \"/locations/online\", as: :online, online: true do\n    scope module: :locations do\n      resources :past, only: [:index]\n    end\n  end\n\n  get \"/locations/search\", to: \"coordinates#index\", as: :locations_search\n\n  get \"/locations/@:coordinates\", to: \"coordinates#show\", as: :coordinates,\n    constraints: {coordinates: /[-\\d.]+,[-\\d.]+/}\n  scope \"/locations/@:coordinates\", as: :coordinates, constraints: {coordinates: /[-\\d.]+,[-\\d.]+/} do\n    scope module: :locations do\n      resources :past, only: [:index]\n      resources :users, only: [:index]\n      resources :map, only: [:index]\n    end\n  end\n\n  resources :gems, param: :gem_name, only: [:index, :show] do\n    member do\n      get :talks\n    end\n  end\n\n  namespace :profiles do\n    resources :connect, only: [:index, :show]\n    resources :claims, only: [:create]\n    resources :enhance, only: [:update], param: :slug\n  end\n\n  resources :contributions, only: [:index, :show], param: :step\n  resources :todos, only: [:index], path: \"data/todos\"\n\n  resources :templates, only: [:new, :create] do\n    collection do\n      get :new_child\n      delete :delete_child\n      get :speakers_search\n      post :speakers_search_chips\n    end\n  end\n\n  # resources\n  namespace :analytics do\n    resource :dashboards, only: [:show] do\n      get :daily_page_views\n      get :daily_visits\n      get :monthly_page_views\n      get :monthly_visits\n      get :top_referrers\n      get :top_landing_pages\n      get :yearly_conferences\n      get :yearly_talks\n      get :top_searches\n    end\n  end\n\n  resources :talks, param: :slug, only: [:index, :show, :update, :edit] do\n    scope module: :talks do\n      resources :recommendations, only: [:index]\n      resource :watched_talk, only: [:new, :create, :destroy, :update] do\n        post :toggle_attendance, on: :collection\n        post :toggle_online, on: :collection\n      end\n      resource :slides, only: :show\n    end\n  end\n\n  resources :watched_talks, only: [:index, :destroy]\n\n  resources :speakers, param: :slug, only: [:index]\n  get \"/speakers/:slug\", to: redirect(\"/profiles/%{slug}\", status: 301), as: :speaker\n\n  namespace :hover_cards do\n    resources :users, only: [:show], param: :slug\n    resources :events, only: [:show], param: :slug\n  end\n\n  resources :profiles, param: :slug, only: [:show, :update, :edit] do\n    post :reindex, on: :member\n\n    scope module: :profiles do\n      resources :talks, only: [:index]\n      resources :events, only: [:index]\n      resources :mutual_events, only: [:index]\n      resource :notes, only: [:show, :edit]\n      resources :stamps, only: [:index]\n      resources :stickers, only: [:index]\n      resources :involvements, only: [:index]\n      resources :map, only: [:index]\n      resources :aliases, only: [:index]\n      resources :wrapped, only: [:index] do\n        collection do\n          get :card\n          get :og_image\n          post :toggle_visibility\n          post :generate_card\n        end\n      end\n    end\n  end\n\n  resources :favorite_users, only: [:index, :create, :destroy, :update]\n\n  resources :events, param: :slug, only: [:index, :show, :update, :edit] do\n    resources :event_participations, only: [:create, :destroy]\n\n    post :reimport, on: :member\n    post :reindex, on: :member\n\n    scope module: :events do\n      collection do\n        get \"/:year\" => \"years#index\", :as => :year, :constraints => {year: /\\d{4}/}\n        get \"/past\" => \"past#index\", :as => :past\n        get \"/archive\" => \"archive#index\", :as => :archive\n        get \"/meetups\" => \"meetups#index\", :as => :meetups\n        get \"/countries\" => redirect(\"/countries\")\n        get \"/countries/:country\" => redirect { |params, _| \"/countries/#{params[:country]}\" }\n        get \"/cities\", to: redirect(\"/cities\", status: 301)\n        get \"/cities/:city\", to: redirect(\"/cities\", status: 301)\n        resources :series, param: :slug, only: [:index, :show] do\n          post :reimport, on: :member\n          post :reindex, on: :member\n        end\n        resources :attendances, only: [:index, :show], param: :event_slug\n      end\n\n      resources :schedules, only: [:index], path: \"/schedule\" do\n        get \"/day/:date\", action: :show, on: :collection, as: :day\n      end\n      resource :venue, only: [:show]\n      resources :speakers, only: [:index]\n      resources :participants, only: [:index]\n      resources :involvements, only: [:index]\n      resources :talks, only: [:index]\n      resources :related_talks, only: [:index]\n      resources :events, only: [:index, :show]\n      resources :videos, only: [:index]\n      resources :sponsors, only: [:index]\n      resources :cfp, only: [:index]\n      resources :collectibles, only: [:index]\n      resource :tickets, only: [:show]\n      resources :todos, only: [:index]\n    end\n  end\n\n  resources :organizations, param: :slug, only: [:index, :show] do\n    resource :logos, only: [:show, :update], controller: \"organizations/logos\"\n    resources :wrapped, only: [:index], controller: \"organizations/wrapped\" do\n      collection do\n        get :og_image\n      end\n    end\n  end\n\n  namespace :sponsors do\n    resources :missing, only: [:index]\n  end\n\n  get \"/sponsors\", to: redirect(\"/organizations\", status: 301)\n  get \"/sponsors/:slug\", to: redirect(\"/organizations/%{slug}\", status: 301)\n  get \"/sponsors/:slug/logos\", to: redirect(\"/organizations/%{slug}/logos\", status: 301)\n\n  get \"/organisations\", to: redirect(\"/events/series\")\n  get \"/organisations/:slug\", to: redirect(\"/events/series/%{slug}\")\n\n  namespace \"spotlight\" do\n    resources :talks, only: [:index]\n    resources :speakers, only: [:index]\n    resources :events, only: [:index]\n    resources :topics, only: [:index]\n    resources :series, only: [:index]\n    resources :organizations, only: [:index]\n    resources :locations, only: [:index]\n    resources :languages, only: [:index]\n    resources :kinds, only: [:index]\n  end\n\n  resources :recommendations, only: [:index]\n\n  get \"leaderboard\", to: \"leaderboard#index\"\n\n  # admin\n  namespace :admin, if: -> { Current.user & admin? } do\n    resources :suggestions, only: %i[index update destroy]\n  end\n\n  get \"/sitemap.xml\", to: \"sitemaps#show\", defaults: {format: \"xml\"}\n\n  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html\n\n  # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.\n  # Can be used by load balancers and uptime monitors to verify that the app is live.\n  get \"up\" => \"rails/health#show\", :as => :rails_health_check\n\n  # Defines the root path route (\"/\")\n  root \"page#home\"\n\n  resources :watch_lists, only: [:index, :new, :create, :show, :edit, :update, :destroy], path: \"bookmarks\" do\n    resources :talks, only: [:create, :destroy], controller: \"watch_list_talks\"\n  end\n\n  namespace :hotwire do\n    namespace :native do\n      namespace :v1 do\n        get \"home\", to: \"/page#home\", defaults: {format: \"json\"}\n        namespace :android do\n          resource :path_configuration, only: :show\n        end\n        namespace :ios do\n          resource :path_configuration, only: :show\n        end\n      end\n    end\n  end\n\n  namespace :api, defaults: {format: \"json\"} do\n    namespace :v1 do\n      namespace :embed do\n        match \"*path\", to: \"base#preflight\", via: :options\n\n        resources :talks, only: [:index, :show], param: :slug\n        resources :speakers, only: [:index, :show], param: :slug\n        resources :profiles, only: [:index, :show], param: :slug\n        resources :topics, only: [:show], param: :slug\n        resources :stickers, only: [:show], param: :slug\n        resources :stamps, only: [:show], param: :slug\n        resources :events, only: [:index, :show], param: :slug do\n          get :participants, on: :member\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "config/storage.yml",
    "content": "test:\n  service: Disk\n  root: <%= Rails.root.join(\"tmp/storage\") %>\n\nlocal:\n  service: Disk\n  root: <%= Rails.root.join(\"storage\") %>\n\n# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)\n# amazon:\n#   service: S3\n#   access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>\n#   secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>\n#   region: us-east-1\n#   bucket: your_own_bucket-<%= Rails.env %>\n\n# Remember not to checkin your GCS keyfile to a repository\n# google:\n#   service: GCS\n#   project: your_project\n#   credentials: <%= Rails.root.join(\"path/to/gcs.keyfile\") %>\n#   bucket: your_own_bucket-<%= Rails.env %>\n\n# Use bin/rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)\n# microsoft:\n#   service: AzureStorage\n#   storage_account_name: your_account_name\n#   storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>\n#   container: your_container_name-<%= Rails.env %>\n\n# mirror:\n#   service: Mirror\n#   primary: local\n#   mirrors: [ amazon, google, microsoft ]\n"
  },
  {
    "path": "config/vite.json",
    "content": "{\n  \"all\": {\n    \"sourceCodeDir\": \"app/javascript\",\n    \"watchAdditionalPaths\": [\"app/assets/stylesheets\"]\n  },\n  \"development\": {\n    \"autoBuild\": true,\n    \"publicOutputDir\": \"vite-dev\",\n    \"host\": \"0.0.0.0\",\n    \"port\": 3036\n  },\n  \"test\": {\n    \"autoBuild\": true,\n    \"publicOutputDir\": \"vite-test\",\n    \"port\": 3037\n  }\n}\n"
  },
  {
    "path": "config.ru",
    "content": "# This file is used by Rack-based servers to start the application.\n\nrequire_relative \"config/environment\"\n\nrun Rails.application\nRails.application.load_server\n"
  },
  {
    "path": "content/announcements/2026-01-01-happy-new-year-2026.md",
    "content": "---\ntitle: \"Happy New Year 2026!\"\nslug: happy-new-year-2026\ndate: 2026-01-01\nauthor: marcoroth\npublished: true\nexcerpt: \"2025 was an incredible year for Ruby Events around the world and also for the RubyEvents.org platform! A look back at talks, events, speakers, sponsors, and the Ruby community's year!\"\ntags:\n  - community\n  - wrapped\n  - year-in-review\nfeatured_image: /images/announcements/rubyevents-2025-wrapped.jpg\n---\n\nHappy New Year! 🎉\n\n2025 was an incredible year for Ruby Events around the world and also for the [RubyEvents.org](https://rubyevents.org) platform!\n\nTo celebrate, we're releasing **RubyEvents Wrapped**!\n\nA look back at talks, events, speakers, sponsors, and the Ruby community's year!\n\n## 2025 in Numbers\n\nIn 2025, we added and backfilled over **450 events** and indexed over **2,500 new talks**!\n\nThe Ruby community delivered **1,043 talks** from **670 speakers** at **33 conferences** across **18 countries**!\n\nYou can find them all on [rubyevents.org](https://rubyevents.org)!\n\n## Community Contributions\n\nWe also received incredible contributions from the community this year!\n\n**478 pull requests** merged from **83 contributors** 🙌\n\nThank you to everyone who contributed code, reported bugs, added events, or helped improve RubyEvents.org!\n\n## Welcome to the Team!\n\nWelcome @chaelcodes to the RubyEvents.org team! 🎉\n\nRachael has been building new features, improving docs, smoothing onboarding, and spreading the word at events.\n\nShe is all-in and also built [MeetAnother.day](https://meetanother.day), which shares our mission of connecting Rubyists.\n\nWe can't wait to build together!\n\n## Check Your Wrapped!\n\nHave you checked your RubyEvents Wrapped yet?\n\nSee your 2025 in review and share it with the Ruby community!\n\n👉 [rubyevents.org/wrapped](https://rubyevents.org/wrapped)\n\nHappy 2026, we hope to see you at a Ruby event soon! ❤️\n"
  },
  {
    "path": "content/announcements/2026-01-21-introducing-web-components.md",
    "content": "---\ntitle: \"Introducing Web Components for RubyEvents.org\"\nslug: introducing-web-components\ndate: 2026-01-21\nauthor: marcoroth\npublished: false\nexcerpt: \"Speakers and organizers can now embed parts of RubyEvents.org on their own websites using simple web components. Display talks, speakers, events, and more with just a single HTML tag!\"\ntags:\n  - feature\n  - web-components\n  - embed\nfeatured_image:\n---\n\nWe're excited to announce a new way to share Ruby community content: **Web Components for RubyEvents.org**!\n\nSpeakers, organizers, and community members can now embed parts of RubyEvents.org directly into their own websites, blogs, or documentation using simple HTML tags. No JavaScript configuration required – just drop in a tag and you're done!\n\n## Getting Started\n\nAdd the RubyEvents.org script to your page:\n\n```html\n<script type=\"module\" src=\"https://www.rubyevents.org/embed.js\"></script>\n```\n\nThen use any of the components below!\n\n---\n\n## Talk Component\n\nDisplay a single talk with video thumbnail, speakers, and event info.\n\n```html\n<rubyevents-talk slug=\"keynote-rubyllm\" show-footer></rubyevents-talk>\n```\n\n<div class=\"my-6 p-4 bg-base-200 rounded-lg\">\n<rubyevents-talk slug=\"keynote-rubyllm\" show-footer></rubyevents-talk>\n</div>\n\n---\n\n## Speaker Component\n\nDisplay a speaker profile with their talks and events.\n\n```html\n<rubyevents-speaker slug=\"tenderlove\" tab=\"talks\"></rubyevents-speaker>\n```\n\n<div class=\"my-6 p-4 bg-base-200 rounded-lg\">\n<rubyevents-speaker slug=\"tenderlove\" tab=\"talks\"></rubyevents-speaker>\n</div>\n\n---\n\n## Topic Component\n\nDisplay talks for a specific topic.\n\n```html\n<rubyevents-topic slug=\"truffleruby\" limit=\"10\"></rubyevents-topic>\n```\n\n<div class=\"my-6 p-4 bg-base-200 rounded-lg\">\n<rubyevents-topic slug=\"truffleruby\" limit=\"10\"></rubyevents-topic>\n</div>\n\n---\n\n## Events Component\n\nDisplay a list of upcoming or past events.\n\n```html\n<rubyevents-events filter=\"upcoming\" show-filter></rubyevents-events>\n```\n\n<div class=\"my-6 p-4 bg-base-200 rounded-lg\">\n<rubyevents-events filter=\"upcoming\" show-filter></rubyevents-events>\n</div>\n\n---\n\n## Event Component\n\nDisplay a single event with details, stats, and participant avatars.\n\n```html\n<rubyevents-event slug=\"rubyconf-2024\" show-participants></rubyevents-event>\n```\n\n<div class=\"my-6 p-4 bg-base-200 rounded-lg\">\n<rubyevents-event slug=\"rubyconf-2024\" show-participants></rubyevents-event>\n</div>\n\n---\n\n## Profile Component\n\nDisplay a user profile with attending events and watch lists.\n\n```html\n<rubyevents-profile slug=\"chaelcodes\"></rubyevents-profile>\n```\n\n<div class=\"my-6 p-4 bg-base-200 rounded-lg\">\n<rubyevents-profile slug=\"chaelcodes\"></rubyevents-profile>\n</div>\n\n---\n\n## Passport Component\n\nDisplay a user's stamps in a passport/stamp book style layout.\n\n```html\n<rubyevents-passport slug=\"chaelcodes\"></rubyevents-passport>\n```\n\n<div class=\"my-6 p-4 bg-base-200 rounded-lg\">\n<rubyevents-passport slug=\"chaelcodes\"></rubyevents-passport>\n</div>\n\n---\n\n## Stickers Component\n\nDisplay a user's stickers on a MacBook-style laptop lid.\n\n```html\n<rubyevents-stickers slug=\"chaelcodes\"></rubyevents-stickers>\n```\n\n<div class=\"my-6 p-4 bg-base-200 rounded-lg\">\n<rubyevents-stickers slug=\"chaelcodes\"></rubyevents-stickers>\n</div>\n\n---\n\n## Use Cases\n\n- **Speakers**: Embed your talk history on your personal website or portfolio\n- **Event Organizers**: Showcase upcoming events and past recordings on your conference site\n- **Community Blogs**: Feature talks on specific topics in your blog posts\n- **Company Pages**: Highlight your team's conference participation\n\n## What's Next?\n\nWe're just getting started! We'd love to hear your feedback and ideas for new components or features. Feel free to open an issue on [GitHub](https://github.com/rubyevents/rubyevents) or reach out to us on social media.\n\nHappy embedding! 🎉\n"
  },
  {
    "path": "content/announcements/2026-01-22-announcements-and-news.md",
    "content": "---\ntitle: \"RubyEvents.org announcements & news\"\nslug: announcements-and-news\ndate: 2026-01-22\nauthor: adrienpoly\npublished: true\nexcerpt: \"RubyEvents.org now has an announcement system to share news and updates with the Ruby community.\"\ntags:\n  - documentation\nfeatured_image:\n---\n\nRubyEvents.org now includes an announcement system to share platform updates and curated community news. You'll see updates about new features and content additions, alongside monthly round-ups of upcoming CFPs and conference announcements.\n\n## Documentation\n\n### Mentions\n\nYou can mention users with the `@username` syntax. When the username matches a registered user, it will automatically be converted to a link to their profile.\n\n**Syntax:**\n\n```markdown\n@username\n```\n\n**Results:**\n\nCheck out @adrienpoly's profile.\n\n### Topics\n\nYou can link to topics using the wiki-link syntax `[[topic-slug]]`. When the topic exists, it will be converted to a link to that topic's page.\n\n**Syntax:**\n\n```markdown\n[[topic-slug]]\n```\n\n**Examples:**\n\n- [[hotwire]]\n- [[web-components]]\n- [[rails]]\n\nThis is great for connecting announcements to relevant topic pages, helping readers discover more content.\n\n## Writing Announcements\n\nAnnouncements support full Markdown syntax including:\n\n### Styling text\n\n| Style                  | Syntax             | Example                                    | Output                                   |\n| ---------------------- | ------------------ | ------------------------------------------ | ---------------------------------------- |\n| Bold                   | `** **` or `__ __` | `**This is bold text**`                    | **This is bold text**                    |\n| Italic                 | `* *` or `_ _`     | `_This text is italicized_`                | _This text is italicized_                |\n| Strikethrough          | `~~ ~~` or `~ ~`   | `~~This was mistaken text~~`               | ~~This was mistaken text~~               |\n| Bold and nested italic | `** **` and `_ _`  | `**This text is _extremely_ important**`   | **This text is _extremely_ important**   |\n| All bold and italic    | `*** ***`          | `***All this text is important***`         | **_All this text is important_**         |\n| Subscript              | `<sub> </sub>`     | `This is a <sub>subscript</sub> text`      | This is a <sub>subscript</sub> text      |\n| Superscript            | `<sup> </sup>`     | `This is a <sup>superscript</sup> text`    | This is a <sup>superscript</sup> text    |\n| Underline              | `<ins> </ins>`     | `This is an <ins>underlined</ins> text`    | This is an <ins>underlined</ins> text    |\n| Links                  | `[Text](URL)`      | `[RubyEvents](https://www.rubyevents.org)` | [RubyEvents](https://www.rubyevents.org) |\n\n### Code blocks with syntax highlighting\n\n<pre class=\"highlight\"><code class=\"language-ruby\">&#96;&#96;&#96;ruby\ndef hello_world\n&#160;&#160;puts \"Hello, world!\"\nend\n&#96;&#96;&#96;</code></pre>\n\n**Results:**\n\n```ruby\ndef hello_world\n  puts \"Hello, world!\"\nend\n```\n\n### Tables\n\n```markdown\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Row 1    | Row 1    | Row 1    |\n| Row 2    | Row 2    | Row 2    |\n| Row 3    | Row 3    | Row 3    |\n```\n\n**Results:**\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Row 1    | Row 1    | Row 1    |\n| Row 2    | Row 2    | Row 2    |\n| Row 3    | Row 3    | Row 3    |\n\n### Lists\n\n```markdown\n- Item 1\n- Item 2\n- Item 3\n```\n\n**Results:**\n\n- Item 1\n- Item 2\n- Item 3\n\n### Frontmatter Options\n\nEach announcement requires a YAML frontmatter with the following fields:\n\n| Field            | Required | Description                     |\n| ---------------- | -------- | ------------------------------- |\n| `title`          | Yes      | The announcement title          |\n| `slug`           | Yes      | URL-friendly identifier         |\n| `date`           | Yes      | Publication date (YYYY-MM-DD)   |\n| `author`         | Yes      | GitHub username of the author   |\n| `published`      | Yes      | Set to `true` to publish        |\n| `excerpt`        | No       | Short description for previews  |\n| `tags`           | No       | List of tags for categorization |\n| `featured_image` | No       | URL or path to a featured image |\n\n## Tips\n\n1. **Check usernames exist** - Mentions only link if the user is registered on RubyEvents.org\n2. **Use topic slugs** - Topics are matched by slug or name, but slugs are more reliable\n3. **Preview before publishing** - Set `published: false` to preview your announcement locally before going live\n"
  },
  {
    "path": "content/announcements/2026-03-01-february-newsletter.md",
    "content": "---\ntitle: \"RubyEvents.org February 2026 Newsletter\"\nslug: february-2026-newsletter\ndate: 2026-03-01\nauthor: chaelcodes\npublished: true\nexcerpt: |-\n  In February, RubyEvents had 12 contributors and 55 PRs merged! This month, we had RubyForGood - Belgium, Belfast RubyFest, and Fukuoka RubyistKaigi 05. We're looking forward to Ruby Community Conference Winter Edition and RBQConf next month!\ntags:\n  - newsletter\n  - february\n  - 2026\nfeatured_image:\n---\nIn February, RubyEvents had 12 contributors and 55 PRs merged! This month, we had RubyForGood - Belgium, Belfast RubyFest, and Fukuoka RubyistKaigi 05. We're looking forward to Ruby Community Conference Winter Edition and RBQConf next month!\n\n## This month's events \n\n- [Ruby for Good Belgium](https://www.rubyevents.org/events/ruby-for-good-belgium-2026) was in Ghent, Belgium from February 2-4.\n- [Belfast RubyFest](https://www.rubyevents.org/events/belfast-rubyfest-2026) was in Belfast, Ireland on February 11.\n- [Fukuoka RubyistKaigi 05](https://www.rubyevents.org/events/fukuoka-rubyistkaigi-05) was in Fukuoka, Japan on February 28.\n\n> Did you attend a Ruby event this month that isn't on the list? Let us know with an issue or PR!\n\n## Next month's events\n\n- [Ruby Community Conference Winter Edition](https://www.rubyevents.org/events/ruby-community-conference-winter-edition-2026) will be in Kraków, Poland on March 13th. [Tickets](https://luma.com/RubyCommunityConference2026) are PLN 450. _Meet RubyEvents team member, Marco Roth, who'll be speaking about Herb and ReActionView!_\n- [RBQConf](https://www.rubyevents.org/events/rbqconf-2026) will be in Austin, TX on March 26-27. [Tickets](https://www.rubyevents.org/events/rbqconf-2026/tickets) are USD $399. Price increases to $499 on March 4th.\n\n## Open CFPs\n\n- [RubyConf Africa](https://www.rubyevents.org/events/rubyconf-africa-2026/cfp) will be in Nairobi, Kenya from August 21-22. The [CFP](https://www.papercall.io/ruby-conf-africa-2026) closes March 11.\n- [RubyConf](https://www.rubyevents.org/events/rubyconf-2026/cfp) will be in Las Vegas from July 14-16. The [CFP](https://sessionize.com/rubyconf-2026/) closes March 15.\n- [Matsue RubyKaigi 12](https://www.rubyevents.org/events/matsue-rubykaigi-12/cfp) will be in Matsue, Japan on June 6. The [CFP](https://docs.google.com/forms/d/e/1FAIpQLSdINI42_XRbNUpfQfz7y5YVrYi2cFarvzfo3o5QVOkSFfsSsg/viewform) closes March 13.\n- [RBQConf](http://localhost:3000/events/rbqconf-2026/cfp) is looking for lightning talks! The [lightning talk CFP](https://docs.google.com/forms/d/e/1FAIpQLSdVIotL2KY-ZLSCAa6tZfsYZGctnWBKwEfuAtrL4JDqmq6xOg/viewform) closes soon!\n- [tiny ruby #{conf}](https://www.rubyevents.org/events/tiny-ruby-conf-2026/cfp) will be in Helsinki, Finland on October 1. The [CFP](https://cfp.helsinkiruby.fi/) closes June 14.\n\n## Uploaded videos\n\n- [RubyConf TH 2026](https://www.rubyevents.org/events/rubyconfth-2026/talks) added 18 talks!\n- [RubyConf Kenya 2017](https://www.rubyevents.org/events/rubyconf-kenya-2017/talks) added 10 talks!\n- [SF Ruby December Meetup](https://www.rubyevents.org/talks/sf-bay-area-ruby-meetup-december-2025) added 5 talks!\n- [SF Ruby January Meetup](https://www.rubyevents.org/talks/sf-bay-area-ruby-meetup-january-2026) added 5 talks!\n- [RubyConf India 2019](https://www.rubyevents.org/events/rubyconf-india-2019/talks) added 12 talks!\n\n## Contributions\n\nWe had 12 contributors this month and 55 merged PRs!\n\n- Rachael Wright-Munn (@ChaelCodes)\n  - [Ruby Community Conference Winter Edition 2026 Updates (#1457)](https://github.com/rubyevents/rubyevents/pull/1457)\n  - [Add pull request template to standardize contributions. (#1455)](https://github.com/rubyevents/rubyevents/pull/1455)\n  - [Favorite User Bug + Favorite Users on Participants (#1446)](https://github.com/rubyevents/rubyevents/pull/1446)\n  - [RBQConf Schedule (#1429)](https://github.com/rubyevents/rubyevents/pull/1429)\n  - [Update Blue Ridge Ruby talk ids and Talks Generator (#1427)](https://github.com/rubyevents/rubyevents/pull/1427)\n  - [Blue Ridge Ruby talks and TalkGenerator (#1425)](https://github.com/rubyevents/rubyevents/pull/1425)\n  - [RubyConf 2026 updates & Sponsor/CFP Generator updates (#1423)](https://github.com/rubyevents/rubyevents/pull/1423)\n  - [Create EventGenerator (#1417)](https://github.com/rubyevents/rubyevents/pull/1417)\n  - [Organization improvements (#1406)](https://github.com/rubyevents/rubyevents/pull/1406)\n  - [Fix locations/:location/users (#1392)](https://github.com/rubyevents/rubyevents/pull/1392)\n  - [Add Favorite to talk page (#1391)](https://github.com/rubyevents/rubyevents/pull/1391)\n  - [Move Fukuoka Assets to new event-series slug (#1390)](https://github.com/rubyevents/rubyevents/pull/1390)\n  - [Tropical on rails 2026 speakers (#1385)](https://github.com/rubyevents/rubyevents/pull/1385)\n  - [Add Favorite Rubyists (#1381)](https://github.com/rubyevents/rubyevents/pull/1381)\n- Adrien Poly (@adrienpoly)\n  - [add file based news/announcements articles (#1362)](https://github.com/rubyevents/rubyevents/pull/1362)\n- 🤖 (@app/copilot-swe-agent)\n  - [Fix CFP link in mobile nav pointing to /events instead of /cfp (#1430)](https://github.com/rubyevents/rubyevents/pull/1430)\n  - [Update tickets_url for Wroclove.rb 2026 (#1394)](https://github.com/rubyevents/rubyevents/pull/1394)\n- Ender Ahmet Yurt (@enderahmetyurt)\n  - [Strip diacritics in Country slug instead of transliterating (#1411)](https://github.com/rubyevents/rubyevents/pull/1411)\n- Hans Schnedlitz (@hschne)\n  - [Fix continent list  (#1428)](https://github.com/rubyevents/rubyevents/pull/1428)\n  - [Add Vienna.rb March 2026 (#1409)](https://github.com/rubyevents/rubyevents/pull/1409)\n- Irina Nazarova (@irinanazarova)\n  - [Add YouTube recordings for SF Ruby Meetup Dec 2025 & Jan 2026 (#1461)](https://github.com/rubyevents/rubyevents/pull/1461)\n- Marco Roth (@marcoroth)\n  - [EuRuKo 2026 dates and venue (#1459)](https://github.com/rubyevents/rubyevents/pull/1459)\n  - [Upgrade Herb to `v0.8.10` and ReActionView to `v0.2.1` (#1414)](https://github.com/rubyevents/rubyevents/pull/1414)\n  - [Add Ruby Hoedown 2007 (#1368)](https://github.com/rubyevents/rubyevents/pull/1368)\n  - [Add Avo Dashboards for Unavailable Videos, Suspicious/Duplicate Users (#1302)](https://github.com/rubyevents/rubyevents/pull/1302)\n  - [Add Ruby Australia Meetups and artwork (#605)](https://github.com/rubyevents/rubyevents/pull/605)\n  - [Implement basic talks filter based on language and kind (#384)](https://github.com/rubyevents/rubyevents/pull/384)\n- Matias Korhonen (@matiaskorhonen)\n  - [Add tiny ruby #{conf} CFP (#1405)](https://github.com/rubyevents/rubyevents/pull/1405)\n- Matt Mayer (@matthewmayer)\n  - [More helpful keynote names for RubyConf India 2019 (#1464)](https://github.com/rubyevents/rubyevents/pull/1464)\n  - [Rubyconf India and DeccanRubyConf assets (#1452)](https://github.com/rubyevents/rubyevents/pull/1452)\n  - [RubyConf India 2019 videos (#1444)](https://github.com/rubyevents/rubyevents/pull/1444)\n  - [Add videos and aliases for RubyConf Kenya 2017 (#1443)](https://github.com/rubyevents/rubyevents/pull/1443)\n  - [fix typo Afria -> Africa (#1442)](https://github.com/rubyevents/rubyevents/pull/1442)\n  - [include aliases when ignoring old events from rubyconferences.org (#1439)](https://github.com/rubyevents/rubyevents/pull/1439)\n  - [Fix awkward line breaking on mobile event metadata (#1435)](https://github.com/rubyevents/rubyevents/pull/1435)\n  - [add 2026 RubyConf TH videos (#1432)](https://github.com/rubyevents/rubyevents/pull/1432)\n  - [Add additional Haggis Ruby info for 2026 (#1422)](https://github.com/rubyevents/rubyevents/pull/1422)\n  - [Case insensitive speaker sort (#1421)](https://github.com/rubyevents/rubyevents/pull/1421)\n  - [Merge some sponsors (#1420)](https://github.com/rubyevents/rubyevents/pull/1420)\n  - [Add RubyConfIndia 2010-2013 events and update website links (#1418)](https://github.com/rubyevents/rubyevents/pull/1418)\n  - [updated assets for RubyConfTH (#1416)](https://github.com/rubyevents/rubyevents/pull/1416)\n  - [Better handling of cancelled events and events with no year in YAML (#1415)](https://github.com/rubyevents/rubyevents/pull/1415)\n  - [RubyConfTH 2019 extra talks (#1413)](https://github.com/rubyevents/rubyevents/pull/1413)\n  - [RubyConfTH: add full schedules for 2019, 2022, 2023; remove 2020 (#1401)](https://github.com/rubyevents/rubyevents/pull/1401)\n  - [fix slug for fastruby (#1400)](https://github.com/rubyevents/rubyevents/pull/1400)\n  - [Case insensitive organizations for sorting (#1396)](https://github.com/rubyevents/rubyevents/pull/1396)\n  - [more detail for rubyconfth: keynote titles, schedule, sponsors, involvements (#1395)](https://github.com/rubyevents/rubyevents/pull/1395)\n  - [Fix website and add Bangkok.rb as organizer for all past rubyconfth events (#1387)](https://github.com/rubyevents/rubyevents/pull/1387)\n- Sudeep Tarlekar (@sudeeptarlekar)\n  - [Count event involvements for organizations (#1449)](https://github.com/rubyevents/rubyevents/pull/1449)\n  - [Order event involvements for organization by date (#1445)](https://github.com/rubyevents/rubyevents/pull/1445)\n- Tom Stuart (@tomstuart)\n  - [Move incorrectly-attributed @tomstuart talks to @rentalcustard (#1440)](https://github.com/rubyevents/rubyevents/pull/1440)\n- Vinícius Alonso (@viniciusalonso)\n  - [Add og informations for missing places in events area (#1448)](https://github.com/rubyevents/rubyevents/pull/1448)\n  - [Order events archive by name and start date (#1447)](https://github.com/rubyevents/rubyevents/pull/1447)\n- Julia López (@yukideluxe)\n  - [Baruco conferences assets (#1412)](https://github.com/rubyevents/rubyevents/pull/1412)\n  - [Fix hidden grid items on tablet viewports (#1410)](https://github.com/rubyevents/rubyevents/pull/1410)\n\nThank you to everyone for your contributions! ❤️ \n\n> Looking to join this list in March? Check out our [contributions page](https://www.rubyevents.org/contributions) or the [CONTRIBUTING.md](https://github.com/rubyevents/rubyevents/blob/main/CONTRIBUTING.md) in GitHub."
  },
  {
    "path": "content/announcements/2026-04-01-march-newsletter.md",
    "content": "---\ntitle: \"RubyEvents.org March 2026 Newsletter\"\nslug: march-2026-newsletter\ndate: 2026-04-01\nauthor: chaelcodes\npublished: true\nexcerpt: |-\n  In March, RubyEvents had a shocking 89 PRs from 20 contributors merged! This month, we had Ruby Community Conference Winter Edition and RBQConf. April will be busy with 5 different events - Tropical on Rails, wroclove.rb, RubyKaigi, Haggis Ruby, and Blue Ridge Ruby!\ntags:\n  - newsletter\n  - march\n  - 2026\nfeatured_image:\n---\n\nIn March, RubyEvents had a shocking 89 PRs from 20 contributors merged! This month, we had Ruby Community Conference Winter Edition and RBQConf. April will be busy with 5 different events - Tropical on Rails, wroclove.rb, RubyKaigi, Haggis Ruby, and Blue Ridge Ruby!\n\n## Open CFPs\n\n- You'll need to be lightning quick to make it into [RubyKaigi](https://www.rubyevents.org/events/rubykaigi-2026/cfp)'s lightning talk [CFP](https://cfp.rubykaigi.org/events/2026LT). It's closing April 5. The conference will be in Hakodate, Hokkaido, Japan from April 22-24.\n- [RubyConf](https://www.rubyevents.org/events/rubyconf-2026/cfp) is looking for open-source projects to feature in the Hack Spaces! This year there's a [CFP](https://docs.google.com/forms/d/e/1FAIpQLSeFyvgo05RYHsI-UPylYYq3KTgfgPPAE1pVZKhbVGXZKrIKFw/viewform) - which closes May 1. The conference will be in Las Vegas, NV from July 14-16.\n- [Kansai RubyKaigi](https://www.rubyevents.org/events/kansai-rubykaigi-09/cfp) will be Otsu, Shiga, Japan on July 18. The [CFP](https://docs.google.com/forms/d/e/1FAIpQLSeiwW2bwsl5FkKUDcvjvr3jlppRIRFbmfWsxWbgKs8WJuszUg/viewform) closes May 10.\n- [Deccan Queen on Rails](https://www.rubyevents.org/events/deccan-queen-on-rails-2026/cfp) will be in Pune, Maharashtra, India from October 8-9. The [CFP](https://cfp.deccanqueenonrails.com/) closes May 31.\n- [tiny ruby #{conf}](https://www.rubyevents.org/events/tiny-ruby-conf-2026/cfp) will be in Helsinki, Finland on October 1. The [CFP](https://cfp.helsinkiruby.fi) closes June 14.\n\n> None of these feel quite right? Check out our list of [meetup cfps](https://www.rubyevents.org/cfp?kind=meetup)! Many are open year round and always looking for new talks.\n\n## This month's events\n\n- [Ruby Community Conference Winter Edition](https://www.rubyevents.org/events/ruby-community-conference-winter-edition-2026) was in Kraków, Poland on March 13th.\n- [RBQConf](https://www.rubyevents.org/events/rbqconf-2026) was in Austin, TX from March 26-27.\n\n> Did you attend a Ruby event this month that isn't on the list? Let us know with an [issue](https://github.com/rubyevents/rubyevents/issues/new) or [PR](https://github.com/rubyevents/rubyevents/blob/main/CONTRIBUTING.md)!\n\n## Next month's events\n\n- [Tropical on Rails](https://rubyevents.org/events/tropical-on-rails-2026) will be in São Paulo, Brazil on April 9-10. [Ticket](https://www.sympla.com.br/evento/tropical-on-rails-2026-the-brazilian-rails-conference/3181423) sales end TODAY! You can buy workshop tickets until April 4. Tickets are between R$ 649-1.048. _Meet RubyEvents Team Members - Marco Roth and Rachael Wright-Munn!_\n- [wroclove.rb](https://rubyevents.org/events/wroclove-rb-2026) will be in Wrocław, Poland from April 17-19. [Tickets](https://wrocloverb2026.konfeo.com/en/groups) are 123.00 EUR and there are very few left!\n- [RubyKaigi](https://rubyevents.org/events/rubykaigi-2026) will be in Hakodate, Hokkaido, Japan from April 22-24. [Tickets](https://ti.to/rubykaigi/2026) are ¥30,000-¥40,000 (¥5,000 for students).\n- [Haggis Ruby](https://rubyevents.org/events/haggis-ruby-2026) will be in Glasgow, Scotland from April 23-24.[Tickets](https://ti.to/haggis-ruby/haggis-ruby-2026) are £230!\n- [Blue Ridge Ruby](https://rubyevents.org/events/blue-ridge-ruby-2026) will be in Asheville, NC from April 30-May 1. [Tickets](https://ti.to/blue-ridge-ruby/blue-ridge-ruby-2026) are $249 for individual and $499 for corporate. There will be optional events the Saturday after the conference including river tubing and a Hack Day. _Meet RubyEvents team member, Rachael Wright-Munn, who'll be talking about open-source contributing, and join her on Hack Day to work on RubyEvents!_\n\n> Prepare more than a month ahead by checking out our [calendar](https://www.rubyevents.org/events/2026) or the full [list of events](https://www.rubyevents.org/events).\n\n## Uploaded videos\n\n- [RubyConf India 2017](https://www.rubyevents.org/events/rubyconf-india-2017/talks) added 14 talks!\n- [RubyConf India 2018](https://www.rubyevents.org/events/rubyconf-india-2018/talks) added 15 talks!\n- [RubyConf India 2022](https://www.rubyevents.org/events/rubyconf-india-2022/talks) added 10 talks!\n- [Vienna.rb Meetup](https://www.rubyevents.org/talks/vienna-rb-march-2026) added the March meetup with 3 talks!\n- [Chicago Ruby Meetup](https://www.rubyevents.org/events/chicagoruby) added videos across April 2025-March 2026 and 2008-2016!\n- [Haggis Ruby 2024](https://www.rubyevents.org/events/haggis-ruby-2024/talks) added 5 new talks and 2 lightning talks!\n- [GORUCO 2008](https://www.rubyevents.org/events/goruco-2008/talks) got timestamp metadata for 13 lightning talks!\n- [GORUCO 2009](https://www.rubyevents.org/events/goruco-2009/talks) got timestamp metadata for 11 lightning talks!\n- [GORUCO 2010](https://www.rubyevents.org/events/goruco-2010/talks) added 7 new talks and 12 RejectConf lightning talks!\n- [GORUCO 2011](https://www.rubyevents.org/events/goruco-2011/talks) added 8 new talks and 16 RecejtConf lightning talks!\n- [BridgetownConf 2022](https://www.rubyevents.org/events/bridgetownconf-2022/talks) added 6 new talks, including a Q&A with the Bridgetown Core team!\n\n## Contributions\n\nThis month, we had an unbelievable number of contributions! We saw 89 merged PRs from 20 contributors!\n\n### Big Updates\n\nMeetups have seen some major improvements this month thanks to @matthewmayer and @viniciusalonso! Meetups are now listed on the events page under a [Meetups](https://www.rubyevents.org/events/meetups) link. When viewing a location (city/region/country), you can now see a meetups tab that lists all meetups for that location.\n\nWhen editing yaml files in VS Code, you may have noticed [in-editor schema validation](https://github.com/rubyevents/rubyevents/pull/1564). If you haven't, install the [vs code extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml), and give it a try! This relies on the yaml-language-server which supports [multiple editors](https://github.com/redhat-developer/yaml-language-server?tab=readme-ov-file#clients). We only have VS Code configured so far, but are definitely open to contributions for other editors!\n\n### Rachael Wright-Munn (@ChaelCodes)\n- Meetups without talks/videos are displayed [(#1590)](https://github.com/rubyevents/rubyevents/pull/1590)\n- Improve generator template [(#1583)](https://github.com/rubyevents/rubyevents/pull/1583)\n- Event data skill [(#1582)](https://github.com/rubyevents/rubyevents/pull/1582)\n- JSON Schema Validation in VS Code [(#1564)](https://github.com/rubyevents/rubyevents/pull/1564)\n- Add Assets to Tropical 2015 [(#1544)](https://github.com/rubyevents/rubyevents/pull/1544)\n- Generator updates [(#1542)](https://github.com/rubyevents/rubyevents/pull/1542)\n- Wroclove rb updates [(#1541)](https://github.com/rubyevents/rubyevents/pull/1541)\n- Better TODO Title in TalkGenerator [(#1535)](https://github.com/rubyevents/rubyevents/pull/1535)\n- Haggis ruby [(#1533)](https://github.com/rubyevents/rubyevents/pull/1533)\n- Tropical on Rails updates [(#1524)](https://github.com/rubyevents/rubyevents/pull/1524)\n- RBQConf 2026 Updates [(#1521)](https://github.com/rubyevents/rubyevents/pull/1521)\n- Update to Schedule and Talks for RuCoCo 2026 [(#1520)](https://github.com/rubyevents/rubyevents/pull/1520)\n- Isolate Generator specs [(#1497)](https://github.com/rubyevents/rubyevents/pull/1497)\n- Add RubyKaigi 2026 Speakers [(#1496)](https://github.com/rubyevents/rubyevents/pull/1496)\n- Fix Event Attendance Button [(#1485)](https://github.com/rubyevents/rubyevents/pull/1485)\n- Tropical on Rails Workshops and Talk Generator Improvements [(#1481)](https://github.com/rubyevents/rubyevents/pull/1481)\n- February 2026 Newsletter! [(#1471)](https://github.com/rubyevents/rubyevents/pull/1471)\n- Favorite User Notes [(#1469)](https://github.com/rubyevents/rubyevents/pull/1469)\n- ScheduleGenerator [(#1458)](https://github.com/rubyevents/rubyevents/pull/1458)\n- Updates to Docker and Devcontainers [(#1456)](https://github.com/rubyevents/rubyevents/pull/1456)\n\n### Zakir Jiwani (@JiwaniZakir)\n- fix: Leave # in Generate Assets rake task [(#1543)](https://github.com/rubyevents/rubyevents/pull/1543)\n\n### Vishwajeetsingh Desurkar  (@Selectus2)\n- Add deccan queen on rails details for 2026 edition [(#1486)](https://github.com/rubyevents/rubyevents/pull/1486)\n\n### DavidMei (@XiaoPengMei)\n- fix: keep selected talk labels active after hover [(#1578)](https://github.com/rubyevents/rubyevents/pull/1578)\n\n### 🤖 (@app/copilot-swe-agent)\n- Add Community Day Application CFP to RubyConf 2026 [(#1585)](https://github.com/rubyevents/rubyevents/pull/1585)\n- Add Balkan Ruby 2026 Talks [(#1572)](https://github.com/rubyevents/rubyevents/pull/1572)\n- Add talks for RubyCon 2026 [(#1563)](https://github.com/rubyevents/rubyevents/pull/1563)\n- Add Typesense as Gold sponsor for Haggis Ruby 2026 [(#1552)](https://github.com/rubyevents/rubyevents/pull/1552)\n- Add Tropical on Rails 2026 talk titles and language tags [(#1550)](https://github.com/rubyevents/rubyevents/pull/1550)\n- Change February 2026 Newsletter published date to March 1, 2026 [(#1477)](https://github.com/rubyevents/rubyevents/pull/1477)\n- Add Typesense and FastRuby.io sponsors to Blue Ridge Ruby 2026 [(#1475)](https://github.com/rubyevents/rubyevents/pull/1475)\n- New Talks for Blastoff Rails 2026 [(#1473)](https://github.com/rubyevents/rubyevents/pull/1473)\n\n### Ender Ahmet Yurt (@enderahmetyurt)\n- Revert showing up all button [(#1514)](https://github.com/rubyevents/rubyevents/pull/1514)\n- Fix past scope to include events with missing dates [(#1479)](https://github.com/rubyevents/rubyevents/pull/1479)\n\n### Mike Dalessio (@flavorjones)\n- Add GORUCO 2010/2011 RejectConf lightning talk details [(#1562)](https://github.com/rubyevents/rubyevents/pull/1562)\n- Improve GORUCO 2007-2009 lightning talk metadata and thumbnails [(#1561)](https://github.com/rubyevents/rubyevents/pull/1561)\n- Add GORUCO 2010 and 2011 talks, schedules, venues, and sponsors [(#1560)](https://github.com/rubyevents/rubyevents/pull/1560)\n\n### Francois DUMAS LATTAQUE (@francoisedumas)\n- Nantes RB update [(#1527)](https://github.com/rubyevents/rubyevents/pull/1527)\n- Add Nantes Rb meetup [(#1483)](https://github.com/rubyevents/rubyevents/pull/1483)\n\n### Hiroshi SHIBATA (@hsbt)\n- Add Ruby 30th Anniversary stamp image [(#1565)](https://github.com/rubyevents/rubyevents/pull/1565)\n\n### Hans Schnedlitz (@hschne)\n- Videos for  Vienna.rb March 2026  [(#1517)](https://github.com/rubyevents/rubyevents/pull/1517)\n- Change name for Eileen Alayce [(#1508)](https://github.com/rubyevents/rubyevents/pull/1508)\n\n### Mike Dalton (@kcdragon)\n- Add Philly.rb [(#1581)](https://github.com/rubyevents/rubyevents/pull/1581)\n\n### Marco Roth (@marcoroth)\n- Add missing schemas for YAML files [(#1580)](https://github.com/rubyevents/rubyevents/pull/1580)\n- Speakers.yml validations and updates [(#1579)](https://github.com/rubyevents/rubyevents/pull/1579)\n- Add BridgetownConf 2022 talks and assets [(#1576)](https://github.com/rubyevents/rubyevents/pull/1576)\n- Add Haggis Ruby 2024 recordings [(#1567)](https://github.com/rubyevents/rubyevents/pull/1567)\n- Add RubyKaigi 2026 talk details, schedule, sponsors and new branding [(#1559)](https://github.com/rubyevents/rubyevents/pull/1559)\n- Upgrade to Herb v0.9 and ReActionView 0.3 [(#1548)](https://github.com/rubyevents/rubyevents/pull/1548)\n- Add EuRuKo 2026 assets [(#1482)](https://github.com/rubyevents/rubyevents/pull/1482)\n\n### Matt Mayer (@matthewmayer)\n- Add missing meetup URLs to some meetup series [(#1566)](https://github.com/rubyevents/rubyevents/pull/1566)\n- Add upcoming meetup editions [(#1557)](https://github.com/rubyevents/rubyevents/pull/1557)\n- fix redirect for city meetups tab [(#1546)](https://github.com/rubyevents/rubyevents/pull/1546)\n- Add banner requesting contributions for meetups [(#1545)](https://github.com/rubyevents/rubyevents/pull/1545)\n- hex colors must include # [(#1538)](https://github.com/rubyevents/rubyevents/pull/1538)\n- Date fixes for Thailand data [(#1522)](https://github.com/rubyevents/rubyevents/pull/1522)\n- Add videos for RubyConf India 2017 [(#1515)](https://github.com/rubyevents/rubyevents/pull/1515)\n- Bugfixes for contributions page [(#1513)](https://github.com/rubyevents/rubyevents/pull/1513)\n- remove bios from speakers.yml where github is available [(#1512)](https://github.com/rubyevents/rubyevents/pull/1512)\n- fix typo in attended one conference badge [(#1506)](https://github.com/rubyevents/rubyevents/pull/1506)\n- add RubyAndRails 2010 (former RubyEnRails) [(#1505)](https://github.com/rubyevents/rubyevents/pull/1505)\n- fix typo of 'calendar' [(#1504)](https://github.com/rubyevents/rubyevents/pull/1504)\n- Add videos for RubyConf India 2018 and 2022 [(#1500)](https://github.com/rubyevents/rubyevents/pull/1500)\n- Add docs for adding meetups [(#1495)](https://github.com/rubyevents/rubyevents/pull/1495)\n- Sort by series name case insensitive on /events/archive [(#1494)](https://github.com/rubyevents/rubyevents/pull/1494)\n- Add Meetups tab to countries, states and cities [(#1492)](https://github.com/rubyevents/rubyevents/pull/1492)\n- Add bangkok.rb's Ruby Tuesday meetup with historical data [(#1487)](https://github.com/rubyevents/rubyevents/pull/1487)\n- Add a scripts/sort_speakers.rb to sort speakers.yml alphabetically [(#1484)](https://github.com/rubyevents/rubyevents/pull/1484)\n- combine windy city rails series [(#1463)](https://github.com/rubyevents/rubyevents/pull/1463)\n- sort speakers.yml [(#1462)](https://github.com/rubyevents/rubyevents/pull/1462)\n- Show playlists for events with no videos page [(#1451)](https://github.com/rubyevents/rubyevents/pull/1451)\n\n### Matt Van Horn (@mvanhorn)\n- fix: correct talk dates for RubyConf 2022 Mini [(#1574)](https://github.com/rubyevents/rubyevents/pull/1574)\n\n### Panacotar (@panacotar)\n- Add sanitize_url helper to properly fix xss in back_path [(#1558)](https://github.com/rubyevents/rubyevents/pull/1558)\n\n### Spike Ilacqua (@spikex)\n- Add Rocky Mountain Ruby 2026 [(#1556)](https://github.com/rubyevents/rubyevents/pull/1556)\n\n### Steven T Ancheta (@stancheta)\n- Adding ChicagoRuby meetup videos from YouTube and Vimeo [(#1536)](https://github.com/rubyevents/rubyevents/pull/1536)\n\n### Sudeep Tarlekar (@sudeeptarlekar)\n- Sort conferences on CFPs at the top [(#1525)](https://github.com/rubyevents/rubyevents/pull/1525)\n- Fix polymorphic path in maps controller [(#1509)](https://github.com/rubyevents/rubyevents/pull/1509)\n\n### Vinícius Alonso (@viniciusalonso)\n- Sort past events in profiles by most recent [(#1592)](https://github.com/rubyevents/rubyevents/pull/1592)\n- Hide empty participant group [(#1575)](https://github.com/rubyevents/rubyevents/pull/1575)\n- Fix bug in meetups date today method [(#1547)](https://github.com/rubyevents/rubyevents/pull/1547)\n- Add informations about upcoming and past meetups [(#1526)](https://github.com/rubyevents/rubyevents/pull/1526)\n- Add upcoming events link in meetups page [(#1519)](https://github.com/rubyevents/rubyevents/pull/1519)\n- Create an initial version of meetups page [(#1511)](https://github.com/rubyevents/rubyevents/pull/1511)\n- Remove stamp code [(#1510)](https://github.com/rubyevents/rubyevents/pull/1510)\n- Order sponsors by tier level [(#1499)](https://github.com/rubyevents/rubyevents/pull/1499)\n- Add filter kind in events archived [(#1478)](https://github.com/rubyevents/rubyevents/pull/1478)\n\n### Yudai Takada (@ydah)\n- Correct the official names of Fukuoka RubyKaigi 01 and 02 [(#1593)](https://github.com/rubyevents/rubyevents/pull/1593)\n- Add Kansai RubyKaigi 09 event and assets [(#1588)](https://github.com/rubyevents/rubyevents/pull/1588)\n- Update metadata for regional RubyKaigi series [(#1587)](https://github.com/rubyevents/rubyevents/pull/1587)\n- Add Kansai Ruby community meetups and assets [(#1586)](https://github.com/rubyevents/rubyevents/pull/1586)\n\nThank you to everyone for your contributions! ❤️\n\n> Looking to join this list in April? Check out our [contributions page](https://www.rubyevents.org/contributions) or the [CONTRIBUTING.md](https://github.com/rubyevents/rubyevents/blob/main/CONTRIBUTING.md) in GitHub.\n"
  },
  {
    "path": "data/acts-as-conference/acts-as-conference-2008/event.yml",
    "content": "---\nid: \"acts-as-conference-2008\"\ntitle: \"acts_as_conference 2008\"\nkind: \"conference\"\nlocation: \"Orlando, FL, United States\"\ndescription: |-\n  Acts As Conference 2008\nstart_date: \"2008-02-08\"\nend_date: \"2008-02-09\"\nyear: 2008\nwebsite: \"https://web.archive.org/web/20080518013910/http://www.actsasconference.com/\"\noriginal_website: \"https://actsasconference.com\"\ncoordinates:\n  latitude: 28.5383832\n  longitude: -81.3789269\n"
  },
  {
    "path": "data/acts-as-conference/acts-as-conference-2008/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/acts-as-conference/acts-as-conference-2009/event.yml",
    "content": "---\nid: \"acts-as-conference-2009\"\ntitle: \"acts_as_conference 2009\"\nkind: \"conference\"\nlocation: \"Orlando, FL, United States\"\ndescription: |-\n  Acts As Conference 2009\nstart_date: \"2009-02-06\"\nend_date: \"2009-02-07\"\nyear: 2009\nwebsite: \"https://web.archive.org/web/20090803033010/http://www.actsasconference.com/\"\noriginal_website: \"https://actsasconference.com\"\ncoordinates:\n  latitude: 28.5383832\n  longitude: -81.3789269\n"
  },
  {
    "path": "data/acts-as-conference/acts-as-conference-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/acts-as-conference/series.yml",
    "content": "---\nname: \"acts_as_conference\"\nwebsite: \"https://web.archive.org/web/20100218135712/http://www.actsasconference.com/\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\naliases:\n  - Acts As Conference\n  - actsasconference\n  - acts-as-conference\n"
  },
  {
    "path": "data/african-ruby-community/african-ruby-mini-conference-2021/event.yml",
    "content": "---\nid: \"PLb6Zr8jHuhjz_v8223h1fWpCJjzy87iRZ\"\ntitle: \"African Ruby Mini-Conference 2021\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2021-08-12\"\nend_date: \"2021-08-12\"\nwebsite: \"https://web.archive.org/web/20210924131342/http://conference.nairuby.org/\"\noriginal_website: \"http://conference.nairuby.org/\"\ntwitter: \"NairubyKE\"\nplaylist: \"https://www.youtube.com/playlist?list=PLb6Zr8jHuhjz_v8223h1fWpCJjzy87iRZ\"\ncoordinates: false\n"
  },
  {
    "path": "data/african-ruby-community/african-ruby-mini-conference-2021/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://conference.nairuby.org/\n# Videos: https://www.youtube.com/playlist?list=PLb6Zr8jHuhjz_v8223h1fWpCJjzy87iRZ\n---\n[]\n"
  },
  {
    "path": "data/african-ruby-community/series.yml",
    "content": "---\nname: \"African Ruby Community\"\nwebsite: \"http://conference.nairuby.org/\"\ntwitter: \"ruby_african\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/akashi-rb/akashi-rb-meetup/event.yml",
    "content": "---\nid: \"akashi-rb-meetup\"\ntitle: \"AKASHI.rb Meetup\"\nlocation: \"Akashi, Japan\"\ndescription: |-\n  A Ruby-focused engineering community for people in and around Akashi. It welcomes beginners and experienced developers alike and aims to provide a relaxed place to learn together through study sessions and events.\nwebsite: \"https://akashi-rb.connpass.com\"\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 34.6482884\n  longitude: 134.993215\n"
  },
  {
    "path": "data/akashi-rb/akashi-rb-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/akashi-rb/series.yml",
    "content": "---\nname: \"AKASHI.rb\"\nwebsite: \"https://akashi-rb.connpass.com\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/aloha-on-rails/aloha-on-rails-2009/event.yml",
    "content": "---\nid: \"aloha-on-rails-2009\"\ntitle: \"Aloha on Rails 2009\"\ndescription: \"\"\nlocation: \"Waikiki, HI, United States\"\nkind: \"conference\"\nstart_date: \"2009-10-05\"\nend_date: \"2009-10-06\"\nwebsite: \"http://alohaonrails.com/\"\ncoordinates:\n  latitude: 21.2793462\n  longitude: -157.8291847\n"
  },
  {
    "path": "data/aloha-on-rails/aloha-on-rails-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/aloha-on-rails/series.yml",
    "content": "---\nname: \"Aloha on Rails\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"US\"\nwebsite: \"http://alohaonrails.com/\"\n"
  },
  {
    "path": "data/aloha-rubyconf/aloha-rubyconf-2012/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZEtH07rRfwY2IaA_J5b-Eq\"\ntitle: \"Aloha RubyConf 2012\"\nkind: \"conference\"\nlocation: \"Honolulu, HI, United States\"\ndescription: |-\n  Join us for this 2 day event which brings the Ruby and Rails community’s top speakers and talent together with excited attendees for an unforgettable experience in beautiful Hawaii.\npublished_at: \"2012-10-08\"\nstart_date: \"2012-10-08\"\nend_date: \"2012-10-09\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2012\nbanner_background: \"#EEE8DA\"\nfeatured_background: \"#EEE8DA\"\nfeatured_color: \"#B12731\"\ncoordinates:\n  latitude: 21.3098845\n  longitude: -157.8581401\n"
  },
  {
    "path": "data/aloha-rubyconf/aloha-rubyconf-2012/videos.yml",
    "content": "---\n# https://web.archive.org/web/20121015172556/http://aloharubyconf.com/schedule\n\n## Day 1 - 2012-10-08\n\n# Registration & Breakfast\n\n# Welcome & Introduction\n\n- id: \"aaron-patterson-aloha-rubyconf-2012\"\n  title: \"Keynote: Rails 4 and the Future of Web\"\n  raw_title: \"Aloha Ruby Conf 2012 - Keynote - Rails 4 and the Future of Web by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  slides_url: \"https://speakerdeck.com/tenderlove/aloha-ruby-conference-2012\"\n  description: |-\n    What's new in Rails 4? How does Rails 4 fit in to the future of web development? Why are cats so important to the development of Ruby and Rails? All these questions and more will be answered if you attend this talk. Seats are limited, so act now!\n\n  video_provider: \"youtube\"\n  video_id: \"kufXhNkm5WU\"\n  published_at: \"2012-10-24\"\n\n# ---\n\n- id: \"zach-holman-aloha-rubyconf-2012\"\n  title: \"Git and GitHub Secrets\"\n  raw_title: \"Aloha Ruby Conference 2012 Git and GitHub Secrets by Zach Holman\"\n  speakers:\n    - Zach Holman\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  track: \"Track 1\"\n  description: |-\n    We tuck a lot of features away on github.com.\n\n    Sometimes the UI just hasn't been fleshed out. Or we have bigger plans in mind for the feature in the future. Or it just hasn't been finished yet. But we still want to give you the flexibility of using that feature today.\n\n    The same can be said about Git. If you've ever looked at the manpages, there's feature after feature and option after option in its binaries. Part of the strength of Git and GitHub is having access to those features when you need them, and getting them out of your way when you don't.\n\n    This talk covers both Git and GitHub: different tricks I've picked up after two years at GitHub, helpful advice on common gripes I've seen in support tickets and tweets, and just general nifty things that make you a faster, more capable technologist.\n  video_provider: \"youtube\"\n  video_id: \"Foz9yvMkvlA\"\n  published_at: \"2012-10-26\"\n\n- id: \"richard-schneeman-aloha-rubyconf-2012\"\n  title: \"My Server for Aiur: How Starcraft Taught Me To Scale\"\n  raw_title: \"My Server for Aiur: How Starcraft Taught Me To Scale by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  track: \"Track 2\"\n  description: |-\n    All the Starcraft n00bs know exactly how to win. They take all the resources they can, and upgrade all the expensive tech and think to themselves, \"soon i'll be unstoppable\". Unfortunately \"eventually unstoppable\" is the same as dead right now. This type of premature optimization and abstraction can kill a business faster than not being able to scale. In this talk we'll take a look at how to pick the right unit composition (databases vs. NoSQL), balance your macro and micro (scale out vs. up), and choose the right race (programing language). If you've never played Starcraft, and can't tell a ultralisk from a firebat, don't worry there's still a room for you. Sorry, no Zerg allowed.\n  video_provider: \"youtube\"\n  video_id: \"4wvtvc0C2SY\"\n  published_at: \"2012-10-26\"\n\n# ---\n\n- id: \"jerry-cheung-aloha-rubyconf-2012\"\n  title: \"Evented Ruby vs Node.js\"\n  raw_title: \"Evented Ruby vs Node.js by Jerry Cheung\"\n  speakers:\n    - Jerry Cheung\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  track: \"Track 1\"\n  description: |-\n    While Node.js is the hot new kid on the block, evented libraries like EventMachine for Ruby and Twisted for Python have existed for a long time. When does it make sense to use one over the other? What are the advantages and disadvantages to using node over ruby? In this talk, you will learn how to get the same power of concurrency enjoyed by Node.js while continuing to write in the language you know and love. Topics covered will include pubsub with redis or faye, building evented rack applications, and running evented applications alongside existing Rails apps.\n\n  video_provider: \"youtube\"\n  video_id: \"hNfURUailz0\"\n  published_at: \"2012-10-26\"\n\n- id: \"evan-machnic-aloha-rubyconf-2012\"\n  title: \"Rails Development on Windows. Seriously.\"\n  raw_title: \"Rails Development on Windows - Seriously by Evan Machnic\"\n  speakers:\n    - Evan Machnic\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  track: \"Track 2\"\n  description: |-\n    I started programming Rails on Windows in 2008. The experience was not the best but I still made the best of it. Fast-forward to 2012 and because of tools like RailsInstaller, Windows users have things almost easier than Mac/Linux. This talk will focus on some of the best-practices that I've found when using Windows for Ruby on Rails development and is really geared toward helping people get started programming Rails in a Windows environment. The talk is sexy and it knows it so be prepared to laugh and have fun.\n\n  video_provider: \"youtube\"\n  video_id: \"QASKzyJdcTY\"\n  published_at: \"2012-10-28\"\n\n# Lunch\n\n- id: \"ben-orenstein-aloha-rubyconf-2012\"\n  title: \"Refactoring from Good to Great\"\n  raw_title: \"Aloha Ruby Conf 2012 Refactoring from Good to Great by Ben Orenstein\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  track: \"Track 1\"\n  description: |-\n    Most developers know enough about refactoring to write code that's pretty good. They create short methods, and classes with one responsibility. They're also familiar with a good handful of refactorings, and the code smells that motivate them.\n\n    This talk is about the next level of knowledge: the things advanced developers know that let them turn good code into great. Code that's easy to read and a breeze to change.\n\n    These topics will be covered solely by LIVE CODING; no slides. We'll boldly refactor right on stage, and pray the tests stay green. You might even learn some vim tricks as well as an expert user shows you his workflow.\n\n    Topics include:\n\n    The Open-Closed Principle The types of coupling, and their dangers Why composition is so damn great A powerful refactoring that Kent Beck refers to as \"deep deep magic\" How to destroy conditionals with a NullObject The beauty of the Decorator pattern Testing smells, including Mystery Guest and stubbing the system under test The stuff from the last halves of Refactoring and Clean Code that you never quite got to.\n\n  video_provider: \"youtube\"\n  video_id: \"DC-pQPq0acs\"\n  published_at: \"2012-10-26\"\n\n- id: \"james-rosen-aloha-rubyconf-2012\"\n  title: \"Carson: On the Path from Big-Ball-of-Mud to SOA\"\n  raw_title: \"Carson: On the Path from Big-Ball-of-Mud to SOA by James Rosen\"\n  speakers:\n    - James Rosen\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  track: \"Track 2\"\n  description: |-\n    As applications grow, dependency management becomes painful, tests get slower, and development becomes less joyful. Breaking up the application into services can be a great solution to these problems, but not every team is ready to leap fully into a SOA. Carson is Zendesk's compromise to this problem. It's a Rails 3 engine host: an application that contains only a Gemfile full of engines and some configuration. In this talk we'll explore the benefits and drawbacks of delivering features as engines and how this approach can act as a stepping stone from big-ball-of-mud architectures to service-oriented ones.\n\n  video_provider: \"youtube\"\n  video_id: \"q0DmmLDJ-vQ\"\n  published_at: \"2012-10-28\"\n\n# ---\n\n- id: \"charles-nutter-aloha-rubyconf-2012\"\n  title: \"Why JRuby?\"\n  raw_title: \"Why JRuby? by Charles Nutter\"\n  speakers:\n    - Charles Nutter\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  slides_url: \"https://speakerdeck.com/headius/aloha-rubyconf-2012-jruby\"\n  track: \"Track 1\"\n  description: |-\n    You've probably heard of JRuby. Maybe you've even tried it. But why is JRuby a good idea? How can it help you build better applications? In this talk, we'll cover everything that makes JRuby awesome, from the JVM with its top-notch memory management, solid multithreading, and lightning-fast optimizing compiler, to JRuby itself, giving you easy access to Java libraries, robust Ruby compatibility, and trivial app deployment and distribution options. JRuby is an amazing tool for any Rubyist...come find out why.\n\n  video_provider: \"youtube\"\n  video_id: \"etCJKDCbCj4\"\n  published_at: \"2012-10-26\"\n\n- id: \"konstantin-haase-aloha-rubyconf-2012\"\n  title: \"Message in a Bottle\"\n  raw_title: \"Message in a Bottle by Konstantin Haase\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  slides_url: \"https://speakerdeck.com/rkh/aloha-ruby-conf-2012-message-in-a-bottle\"\n  track: \"Track 2\"\n  description: |-\n    What does really happen when we call a method? How do the different Ruby implementations actually figure out what code to execute? What plumbing is going on under the hood to get a speedy dispatch? In this talk we will have a look at the internals of the the major Ruby implementations, focusing on their dispatch. From look-up tables and call site caches, to inlining and what on earth is invokedynamic? Fear not, all will be explained!\n\n  video_provider: \"youtube\"\n  video_id: \"1MKsTx_pBKw\"\n  published_at: \"2012-10-28\"\n\n# ---\n\n- id: \"corey-haines-aloha-rubyconf-2012\"\n  title: \"Yay! Mocks!\"\n  raw_title: \"Yay! Mocks! by Corey Haines\"\n  speakers:\n    - Corey Haines\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  track: \"Track 1\"\n  description: |-\n    Mocks, Stubs and other test doubles are a common and convenient scapegoat when talking about fragile test suites. But test doubles can be useful guides, highlighting design issues and in our application. By treating them as companions, we can find our way to long-term maintainable designs and effective test suites.\n\n    We'll look at specific, common complaints about test doubles and show how these are indications of design issues. Listening to these pains in our tests can be a great way to move from using our tests as verification to seeing our test suite as a design tool.\n\n    Coming out of this talk, you'll have a better appreciation for the techniques of isolation testing in effective test-driven design.\n\n  video_provider: \"youtube\"\n  video_id: \"t430e6M5YAo\"\n  published_at: \"2012-10-27\"\n\n- id: \"kowsik-guruswamy-aloha-rubyconf-2012\"\n  title: \"Ensuring High Performance for Your Ruby App\"\n  raw_title: \"Ensuring High Performance for Your Ruby App by Kowsik Guruswamy\"\n  speakers:\n    - Kowsik Guruswamy\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  track: \"Track 2\"\n  description: |-\n    There’s nothing more frustrating for a developer than spending months creating an application and then having it fail because of performance issues. That’s why integrating application performance management into each step of the development lifecycle is critical to your application’s success. Of course, easy-to-use tools for performance management are rare, and often prohibitively expensive. Not to mention that they don’t reflect actual user behavior. In order for APM solutions to succeed in the Ruby community, they must be affordable, easy to use, require no scripting; and easily integrate into the development process – be it a PaaS system such as Heroku or some other delivery system. From idea formation to final delivery, Rubyists must know their product is working every step of the way.\n\n  video_provider: \"youtube\"\n  video_id: \"MBUUmTK3YDc\"\n  published_at: \"2012-10-28\"\n\n# ---\n\n- id: \"wesley-beary-aloha-rubyconf-2012\"\n  title: \"Maintain Less, Mentor More: Community Building Techniques from Open Source\"\n  raw_title: \"Maintain Less, Mentor More: Community Building Techniques from Open Source by Wesley Beary\"\n  speakers:\n    - Wesley Beary\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-08\"\n  description: |-\n    Open source is hard but it gets much easier with a community backing you. I tried many approaches while developing fog, and thankfully, the resulting community is amazing. Now I'm doing my best to apply the same principles to the Heroku CLI and other open source projects. I make mistakes and often get lucky, but I have learned a lot about fostering community in the process. This session distills some of my techniques and explains how you can help build community around your favorite projects.\n\n  video_provider: \"youtube\"\n  video_id: \"2hrnZZDV9Ow\"\n  published_at: \"2012-10-27\"\n\n# Thank you and Information\n\n# GitHub Drink-Up\n\n## Day 2 - 2012-10-09\n\n# Registration & Breakfast\n\n# Welcome & Introduction\n\n- id: \"chad-fowler-aloha-rubyconf-2012\"\n  title: \"This is Not a Rails Shop\"\n  raw_title: \"This is Not a Rails Shop by Chad Fowler\"\n  speakers:\n    - Chad Fowler\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 1\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"P4xSmYr7PEg\"\n  published_at: \"2012-10-28\"\n\n- id: \"patrick-huesler-aloha-rubyconf-2012\"\n  title: \"Web API's with ERLANG a Ruby Dev's POV\"\n  raw_title: \"Web API's with ERLANG a Ruby Dev's POV by Patrick Huesler\"\n  speakers:\n    - Patrick Huesler\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 2\"\n  description: |-\n    A story of a Ruby programmer having to understand that learning Erlang is more than just syntax. Learn differences in paradigms, pitfalls and applied use cases for this incredibly powerful language.\n\n    * Concurrency (Threading, Reactor pattern vs Erlang processes)\n    * Stateful services\n    * Non-blocking calls (e.g to an http service)\n    * Inter-process communication\n    * Inter-service communication\n    * Event handling (e.g Active Support Notifications vs. gen_event)\n    * Instrumentation and Reporting\n\n  video_provider: \"youtube\"\n  video_id: \"DlgFpDWj_eE\"\n  published_at: \"2012-10-28\"\n\n# ---\n\n- id: \"mark-bates-aloha-rubyconf-2012\"\n  title: \"CoffeeScript for the Rubyist\"\n  raw_title: \"CoffeeScript for the Rubyist by Mark Bates\"\n  speakers:\n    - Mark Bates\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 1\"\n  description: |-\n    CoffeeScript is taking the world, and particularly the Rails eco system, by storm. This little language has provided an almost Ruby like abstraction onto of JavaScript. CoffeeScript is trying to make writing front end code as much fun as Ruby makes writing backend code.\n\n    In this talk we start with the basic concepts of CoffeeScript and move on to the more powerful and fun features of the language. While we're looking at CoffeeScript we'll see how it relates to the Ruby code we write everyday. What do Ruby 1.9 lambdas and CoffeeScript functions have in common? Which of the two languages supports splats, default arguments, and ranges? The answers may surprise you.\n\n  video_provider: \"youtube\"\n  video_id: \"T1VE4soWzgw\"\n  published_at: \"2012-10-28\"\n\n- id: \"ben-smith-aloha-rubyconf-2012\"\n  title: \"Hacking with Gems\"\n  raw_title: \"Hacking with Gems by Ben Smith\"\n  speakers:\n    - Ben Smith\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 2\"\n  description: |-\n    Do you ever use \"gem install\"? What about bundle?\n\n    What's the worst that could happen if your app has a dependency on a malicious gem? How easy would it be to write a gem that could compromise a box?\n\n    Much of the Ruby community blindly trusts our gems. This talk will make you second guess that trust. It will also show you how to vet gems that you do choose to use.\n\n  video_provider: \"youtube\"\n  video_id: \"z-5bO0Q1J9s\"\n  published_at: \"2012-10-28\"\n\n# ---\n\n- id: \"james-edward-gray-ii-aloha-rubyconf-2012\"\n  title: \"Ten Things You Didn't Know You Could Do\"\n  raw_title: \"Aloha Ruby Conf 2012 Ten Things You Didn't Know You Could Do by James Edward Gray II\"\n  speakers:\n    - James Edward Gray II\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  slides_url: \"https://speakerdeck.com/jeg2/10-things-you-didnt-know-ruby-could-do\"\n  track: \"Track 1\"\n  description: |-\n    There's a lot to Ruby and even experienced Rubyists are sometimes surprised to learn about parts of the language they haven't encountered before.\n\n    Do you really know all of the syntax Ruby can read? Are you familiar with all of the methods provided in Ruby's core? Have you used all of the roughly 100 standard libraries?\n\n    In this talk, I'll dig into the extras of Ruby and see if I can't turn up some features that you don't see all of the time, but that might just be handy to know about anyway. I'll make sure you come out of this able to impress your friends at the hackfest.\n\n  video_provider: \"youtube\"\n  video_id: \"aBgnlBoIkVM\"\n  published_at: \"2012-10-28\"\n\n- id: \"ray-hightower-aloha-rubyconf-2012\"\n  title: \"Building iOS Apps with RubyMotion\"\n  raw_title: \"Building iOS Apps with RubyMotion by Ray Hightower\"\n  speakers:\n    - Ray Hightower\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 2\"\n  description: |-\n    RubyMotion is a tool that lets Ruby developers write native iOS apps using the Ruby language. It's based on MacRuby which is an implementation of the Ruby language for Mac OS X. This talk will introduce RubyMotion with some simple live code demos and a twist of TDD. The level is introductory; you don't need to know Ruby or iOS to attend.\n\n  video_provider: \"youtube\"\n  video_id: \"3gCsen5Zs4s\"\n  published_at: \"2012-10-28\"\n\n# Lunch\n\n- id: \"mitchell-hashimoto-aloha-rubyconf-2012\"\n  title: \"Building a Ruby Library, the Parts No One Talks About\"\n  raw_title: \"Building a Ruby Library the Parts No One Talks About by Mitchell Hashimoto\"\n  speakers:\n    - Mitchell Hashimoto\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 1\"\n  description: |-\n    We all interface with Ruby libraries every day, so we all know what makes up a \"good\" Ruby API. But there is a lot more to a \"good\" library than just the API: proper logging, flexible configuration, a sane exception hierarchy, and useful documentation, just to name a few. How do we do these things properly? What pros/cons are there to different approaches? Unfortunately, no one really talks about these things, despite being very important to the overall feel of a library.\n\n    In this talk I'll share my knowledge of these things from being the maintainer of popular Ruby applications and libraries. I'll show you the idiomatic Ruby way to do logging, configuration, exception handling, and much much more. But don't worry, I won't just be preaching, I'll show you the reasons why these methods have become the community approved way of doing things.\n\n  video_provider: \"youtube\"\n  video_id: \"rUuee8E5Yk4\"\n  published_at: \"2012-10-28\"\n\n- id: \"brandon-keepers-aloha-rubyconf-2012\"\n  title: \"Git: The NoSQL Database\"\n  raw_title: \"Git the NoSQL Database by Brandon Keepers\"\n  speakers:\n    - Brandon Keepers\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 2\"\n  description: |-\n    We all know that Git is amazing for storing code. It is fast, reliable, flexible, and it keeps our project history nuzzled safely in its object database while we sleep soundly at night.\n\n    But what about storing more than code? Why not data? Much flexibility is gained by ditching traditional databases, but at what cost?\n\n    In this talk, I will explore the idea of using Git as a data store. I will look at the benefits of using a schema-less data store, the incredible opportunity opened up by having every change to every model versioned, and the crazy things that could be done with branching and merging changes to data.\n\n    I will also explore the challenges posed by using and scaling Git as a data store, including concurrent access and distributing load.\n\n  video_provider: \"youtube\"\n  video_id: \"fjN4c4RWiV0\"\n  published_at: \"2012-10-28\"\n\n# ---\n\n- id: \"glenn-gillen-aloha-rubyconf-2012\"\n  title: \"The Designers Are Coming!\"\n  raw_title: \"The Designers Are Coming by Glenn Gillen\"\n  speakers:\n    - Glenn Gillen\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 1\"\n  description: |-\n    As developers and engineers we've spent a lot of time improving our tools to make our lives easier. Somewhere along the way, those improvements have introduced a new threat to our livelihood... Designers! Learn about how we've got ourselves into this place, why we have to lift our game, and why that can only be a good thing for everyone.\n\n  video_provider: \"youtube\"\n  video_id: \"2O5cP0cVhX0\"\n  published_at: \"2012-10-28\"\n\n- id: \"charles-max-wood-aloha-rubyconf-2012\"\n  title: \"Facing the Monolith Overcoming Monolithic Applications with SOA\"\n  raw_title: \"Facing the Monolith Overcoming Monolithic Applications with SOA by Charles Max Wood\"\n  speakers:\n    - Charles Max Wood\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 2\"\n  description: |-\n    For many small sites with a minimal amount of complexity, a single rails application works fine. The problem is that as the application's complexity and scope grow, several problems arise. These include: heavy coupling, increased load and response times, and test complexity. All of these cause your feature development to slow considerably.\n\n    The concepts to solving these problems is relatively simple. The primary approach is extracting each concern in your application into its own service. The trick is extricating the data and classes when they are interdepend on the other aspects of the application.\n\n    We'll go over how this is done and what it meant when we had successfully teased the application apart. This approach was used on an application that collected, stored and managed millions of leads each month.\n\n  video_provider: \"youtube\"\n  video_id: \"sxvBK3QpP-c\"\n  published_at: \"2012-10-28\"\n\n# ---\n\n- id: \"noah-zoschke-aloha-rubyconf-2012\"\n  title: \"Running Heroku on Heroku\"\n  raw_title: \"Running Heroku on Heroku by Noah Zoschke\"\n  speakers:\n    - Noah Zoschke\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 1\"\n  description: |-\n    The Heroku application platform makes deploying, running and scaling applications incredibly easy.\n\n    Traditionally these apps have been Ruby web applications. But as both the platform and its users mature, we are seeing the complexity of hosted apps increase, with more complex infrastructure systems running on Heroku.\n\n    Today, nobody is more interested in running infrastructure on Heroku than Heroku itself, as self-hosting offers massive benefits and is a fascinating engineering puzzle to boot.\n\n    We will first discuss the concept of self-hosting and why it such an interesting computer science problem, and a vital property of many systems. Compilers, revision control systems and application platforms all exhibit similar properties of bootstrapping, cross-compiling, and avoiding circular dependencies.\n\n    Then we will take a look at the more interesting self-hosted components of Heroku such as the the distributed application compiler that used to be a server farm but now is little more than a Heroku app that can even compile itself for releasing new versions.\n\n    All of this will show how working towards a self-hosted platform results in comprehensive consistency assurance and gains in efficiency, noble goals for such a complex software system.\n\n  video_provider: \"youtube\"\n  video_id: \"3JrJUB-JAww\"\n  published_at: \"2012-10-28\"\n\n- id: \"lori-olson-aloha-rubyconf-2012\"\n  title: \"Rockstars & Consultants, Who needs 'em?\"\n  raw_title: \"Rockstars & Consultants, Who needs 'em? by Lori Olson\"\n  speakers:\n    - Lori M Olson\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  track: \"Track 2\"\n  description: |-\n    Sound familiar? The Rails ecosystem has grown in leaps and bounds, like the Java ecosystem did in its’ early days. So many languages, frameworks, plugins, engines, libraries and tools. So little time to deliver your new project.\n\n    It’s tempting to hire a rock star who knows absolutely everything to get your new project off the ground. You can also hire \"consultants\" to help fill in the holes in your team when taking your existing product to the next level. Or maybe just hire a whole bunch of people for cheap, and they’ll get the job done... But did you ever consider the untapped wealth of the team you already have?\n\n    In this session we’ll explore ways in which the average development team can explore, learn, teach, and grow, until the sum of members of the team is as great as any Consultant or Rockstar.\n\n  video_provider: \"youtube\"\n  video_id: \"5WettBcU_OE\"\n  slides_url: \"https://speakerdeck.com/wndxlori/rockstars-and-consultants-who-needs-em-aloha-ruby-conf\"\n  published_at: \"2012-10-29\"\n\n# ---\n\n- id: \"matt-aimonetti-aloha-rubyconf-2012\"\n  title: \"mmm..mruby, or why yet another Ruby implementation.\"\n  raw_title: \"mmm..mruby, or why yet another Ruby implementation by Matt Aimonetti\"\n  speakers:\n    - Matt Aimonetti\n  event_name: \"Aloha RubyConf 2012\"\n  date: \"2012-10-09\"\n  slides_url: \"https://speakerdeck.com/matt_aimonetti/mmmm-dot-mruby-everywhere-and-revisiting-ruby\"\n  description: |-\n    mruby is Matz’ new Ruby implementation, it’s not cooler than node.js, it doesn’t natively support Hypstermedia, it looks just like the good old Ruby. So why should we, as a community care?\n\n  video_provider: \"youtube\"\n  video_id: \"eZYRd86OTbk\"\n  published_at: \"2012-10-28\"\n#\n# Mahalo\n"
  },
  {
    "path": "data/aloha-rubyconf/series.yml",
    "content": "---\nname: \"Aloha RubyConf\"\nwebsite: \"https://web.archive.org/web/20121104054253/http://aloharubyconf.com/\"\ntwitter: \"AlohaRubyConf\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Aloha RubyConf\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/amsterdam-rb/amsterdam-rb-meetup/event.yml",
    "content": "---\nid: \"PL9_A7olkztLlSKHyauWf09QxgaAqkC53n\"\ntitle: \"Amsterdam.rb Meetup\"\nlocation: \"Amsterdam, Netherlands\"\ndescription: |-\n  Catch up with Amsterdam.rb meetup livestreams. For more information visit amsrb.org!\nwebsite: \"https://www.amsrb.org\"\nkind: \"meetup\"\npublished_at: \"2024-04-25\"\nchannel_id: \"UCyExf-593j4hjN_cFCSnr2w\"\nyear: 2024\nbanner_background: \"#2D132C\"\nfeatured_background: \"#EC464B\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 52.3675734\n  longitude: 4.9041389\n"
  },
  {
    "path": "data/amsterdam-rb/amsterdam-rb-meetup/videos.yml",
    "content": "---\n- id: \"amsterdamrb-meetup-november-2019\"\n  title: \"Amsterdam.rb Meetup November 2019\"\n  raw_title: \"Amsterdam.rb Meetup November 2019\"\n  date: \"2019-11-19\"\n  event_name: \"Amsterdam.rb Meetup November 2019\"\n  published_at: \"2019-11-19\"\n  video_provider: \"youtube\"\n  video_id: \"VNB4hEicKxA\"\n  description: |-\n    Live stream of the Amsterdam.rb Meetup of the 19th of November.\n\n    Video program:\n\n    00:00 - Welcome, Code of Conduct and sponsor talk\n    04:30 - Tinco Andringa about DDD (Domain Driven Design)\n    47:27 - Break\n    48:14 - After break intro\n    48:49 - Alejandro Cadavid (@acadavid) on Logbook: An experiment on event streaming with Kafka\n\n    Event page: https://www.meetup.com/Amsterdam-rb/events/266071858/\n    Website: https://amsrb.org/\n    Twitter: https://twitter.com/amsrb\n  talks:\n    - title: \"Ruby vs. DDD (Domain Driven Design)\"\n      start_cue: \"04:30\"\n      end_cue: \"47:27\"\n      video_provider: \"parent\"\n      id: \"tinco-adringa-amsterdam-rb-2019-11\"\n      video_id: \"tinco-adringa-amsterdam-rb-2019-11\"\n      speakers:\n        - Tinco Andringa\n\n    - title: \"Logbook: An experiment on event streaming with Kafka\"\n      start_cue: \"48:49\"\n      end_cue: \"1:15:45\"\n      video_provider: \"parent\"\n      id: \"alejandro-cadavid-talk-amsterdam-rb-2019-11\"\n      video_id: \"alejandro-cadavid-talk-amsterdam-rb-2019-11\"\n      speakers:\n        - Alejandro Cadavid\n\n- id: \"amsterdam-rb-2019-12\"\n  title: \"Amsterdam.rb Meetup December 2019\"\n  raw_title: \"Amsterdam.rb Meetup December 2019 - OPSDEV - Pieter Lange\"\n  date: \"2019-12-17\"\n  event_name: \"Amsterdam.rb Meetup December 2019\"\n  published_at: \"2019-12-17\"\n  video_provider: \"children\"\n  video_id: \"amsterdam-rb-2019-12\"\n  description: \"\"\n  talks:\n    - title: \"How Ruby devs can make the lives of their ops people easier / better / more enjoyable\"\n      raw_title: \"Amsterdam.rb Meetup December 2019 - OPSDEV - Pieter Lange\"\n      date: \"2019-12-17\"\n      event_name: \"Amsterdam.rb Meetup December 2019\"\n      published_at: \"2019-12-17\"\n      video_provider: \"youtube\"\n      id: \"pieter-lange-amsterdamrb-meetup-december-2019\"\n      video_id: \"NgSFh_hGQVk\"\n      speakers:\n        - Pieter Lange\n      description: |-\n        Live stream of the Amsterdam.rb Meetup of the 17th of December.\n\n        Meetup description:\n        Talk 1: Pieter Lange (@kuberpieters), OSS Cloud Native Engineer / Kubernetes at Fullstaq, ex Nerdalize, ex Snow, Cloud Native Amsterdam, and Kubernetes Addicts organizer, on how Ruby devs can make the lives of their ops people easier / better / more enjoyable.\n\n        0:00 Welcome, Code of Conduct and sponsor talk\n        2:45 Start of talk\n        8:50 Why OPSDEV\n        12:00 Stereotypes\n        21:10 How did we end up here\n        22:40 Continuous Integration Continuous Delivery\n        28:20 Learning curve\n        36:05 Production logs\n        39:41 Autoscaling\n        42:01 Software Delivery Lifecycle\n        42:50 Asset management\n        43:21 Ruby Gems\n        44:02 Software management\n        47:17 Observability\n\n        Find this talk in part 1 of the livestream: https://www.youtube.com/watch?v=NgSFh_hGQVk\n\n        Break\n\n        Talk 2: Noah Berman (@additionaltext), Security Engineer and a familiar face at the meetup, will come speak about the Hippocratic license, how it came about, what it means, what one should consider, ALL THE THINGS\n\n        Find this talk in part 2 of the livestream: https://www.youtube.com/watch?v=Yg9LapGCP4I\n\n        ---\n\n        Event page: https://www.meetup.com/Amsterdam-rb/events/266702466/\n        Website: https://amsrb.org/\n        Twitter: https://twitter.com/amsrb\n\n    - title: \"The Hippocratic license\"\n      raw_title: \"Amsterdam.rb Meetup December 2019 - Hippocratic license - Noah Berman\"\n      date: \"2019-12-17\"\n      event_name: \"Amsterdam.rb Meetup December 2019\"\n      published_at: \"2019-12-17\"\n      video_provider: \"youtube\"\n      id: \"noah-berman-amsterdamrb-meetup-december-2019\"\n      video_id: \"Yg9LapGCP4I\"\n      speakers:\n        - Noah Berman\n      description: |-\n        Live stream of the Amsterdam.rb Meetup of the 17th of December.\n\n        Video program:\n        00:00 - Welcome, Code of Conduct and sponsor talk\n        00:50 - Noah Berman (@additionaltext), Security Engineer and a familiar face at the meetup, will come speak about the Hippocratic license, how it came about, what it means, what one should consider, ALL THE THINGS\n\n        ---\n\n        Meetup description:\n        Talk 1: Pieter Lange (@kuberpieters), OSS Cloud Native Engineer / Kubernetes at Fullstaq, ex Nerdalize, ex Snow, Cloud Native Amsterdam, and Kubernetes Addicts organizer, on how Ruby devs can make the lives of their ops people easier / better / more enjoyable.\n\n        Find this talk in part 1 of the livestream: https://www.youtube.com/watch?v=NgSFh_hGQVk\n\n        Break\n\n        Talk 2: Noah Berman (@additionaltext), Security Engineer and a familiar face at the meetup, will come speak about the Hippocratic license, how it came about, what it means, what one should consider, ALL THE THINGS\n\n        Find this talk in part 2 of the livestream: https://www.youtube.com/watch?v=Yg9LapGCP4I\n\n        ---\n\n        Event page: https://www.meetup.com/Amsterdam-rb/events/266702466/\n        Website: https://amsrb.org/\n        Twitter: https://twitter.com/amsrb\n\n- id: \"amsterdamrb-meetup-january-2020\"\n  title: \"Amsterdam.rb Meetup January 2020\"\n  raw_title: \"Amsterdam.rb Meetup January 2020\"\n  date: \"2020-01-14\"\n  event_name: \"Amsterdam.rb Meetup January 2020\"\n  published_at: \"2020-01-14\"\n  video_provider: \"youtube\"\n  video_id: \"bfM1gq9YPLs\"\n  description: |-\n    Live stream of the Amsterdam.rb Meetup of the 14th of January 2020.\n\n    Video program:\n\n    00:00 - Welcome, Code of Conduct and sponsor talk\n    07:40 - Arno Fleming, Backend engineer at WeTransfer - Rails and MySQL migrations; a bumpy ride but eventually a love story. Slides: https://pasteapp.com/p/pScI2NLtWVX?view=AUZhlLv65Nu\n\n    Break\n\n    45:44 - Welcome after break\n    48:38 - Gabriel Mazetto, Backend engineer at GitLab - Ruby 2.7: Let's go beyond the CHANGELOG and answer the important questions. Slides: https://speakerdeck.com/brodock/ruby-2-dot-7-beyond-the-changelog\n\n    Event page: https://www.meetup.com/Amsterdam-rb/events/267379972/\n    Website: https://amsrb.org/\n    Twitter: https://twitter.com/amsrb\n  talks:\n    - title: \"Rails and MySQL migrations\"\n      start_cue: \"07:40\"\n      end_cue: \"45:44\"\n      thumbnail_cue: \"7:59\"\n      video_provider: \"parent\"\n      id: \"arno-fleming-amsterdam-rb-2020-01\"\n      video_id: \"arno-fleming-amsterdam-rb-2020-01\"\n      speakers:\n        - Arno Fleming\n\n    - title: \"Ruby 2.7: Let's go beyond the CHANGELOG and answer the important questions\"\n      start_cue: \"48:38\"\n      end_cue: \"1:21:38\"\n      thumbnail_cue: \"49:13\"\n      video_provider: \"parent\"\n      id: \"gabriel-mazetto-amsterdam-rb-2020-01\"\n      video_id: \"gabriel-mazetto-amsterdam-rb-2020-01\"\n      slides_url: \"https://speakerdeck.com/brodock/ruby-2-dot-7-beyond-the-changelog\"\n      speakers:\n        - Gabriel Mazetto\n\n- id: \"amsterdamrb-meetup-february-2020\"\n  title: \"Amsterdam.rb Meetup February 2020\"\n  raw_title: \"Amsterdam.rb Meetup February 2020 with Wander and Melanie\"\n  date: \"2020-02-18\"\n  event_name: \"Amsterdam.rb Meetup February 2020\"\n  published_at: \"2020-02-18\"\n  video_provider: \"youtube\"\n  video_id: \"btsW-xHHpjg\"\n  thumbnail_xs: \"https://i3.ytimg.com/vi/btsW-xHHpjg/default.jpg\"\n  thumbnail_sm: \"https://i3.ytimg.com/vi/btsW-xHHpjg/default.jpg\"\n  thumbnail_md: \"https://i3.ytimg.com/vi/btsW-xHHpjg/mqdefault.jpg\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/btsW-xHHpjg/hqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/btsW-xHHpjg/hqdefault.jpg\"\n  description: |-\n    Live stream of the Amsterdam.rb Meetup of the 18th of February 2020.\n\n    The friendly folks at Catawiki were happy to host and feed us ❤️\n\n    Video program:\n\n    00:00 - Welcome and sponsor talk\n    06:05 - Wander Hillen (see blog: https://www.wjwh.eu/) - Crystal. Do you need it?\n    Unfortunately the audio cuts out at 21:40 because of battery issues.\n\n    Break\n\n    34:25 - Melanie Keatley (https://www.twitter.com/Keatley) - Code smells - the sequel\n\n    ---\n\n    Event page: https://www.meetup.com/Amsterdam-rb/events/267720193/\n    Website: https://amsrb.org/\n    Twitter: https://twitter.com/amsrb\n  talks:\n    - title: \"Crystal. Do you need it?\"\n      event_name: \"Amsterdam.rb Meetup February 2020\"\n      start_cue: \"06:05\"\n      end_cue: \"34:25\"\n      thumbnail_cue: \"6:43\"\n      video_provider: \"parent\"\n      id: \"wander-hillen-amsterdam-rb-2020-02\"\n      video_id: \"wander-hillen-amsterdam-rb-2020-02\"\n      speakers:\n        - Wander Hillen\n\n    - title: \"Code smells - the sequel\"\n      event_name: \"Amsterdam.rb Meetup February 2020\"\n      start_cue: \"34:30\"\n      end_cue: \"1:02:44\"\n      thumbnail_cue: \"34:50\"\n      video_provider: \"parent\"\n      id: \"melanie-keatley-amsterdam-rb-2020-02\"\n      video_id: \"melanie-keatley-amsterdam-rb-2020-02\"\n      speakers:\n        - Melanie Keatley\n\n- id: \"amsterdamrb-meetup-june-2020\"\n  title: \"Amsterdam.rb Meetup June 2020\"\n  raw_title: \"Amsterdam.rb June 2020 -  With Coraline and Anton\"\n  date: \"2020-06-16\"\n  event_name: \"Amsterdam.rb Meetup June 2020\"\n  published_at: \"2020-06-17\"\n  video_provider: \"youtube\"\n  video_id: \"JS-1K5qW7fo\"\n  description: |-\n    Dear Ruby friends 🦊🐙🐹🐟,\n\n    It's been a while since the last Amsterdam.rb event 👋\n\n    All attendees can talk and ask questions with the community and speakers on the Ruby Netherlands Slack. Join our Slack today at: https://slack.amsrb.org\n\n    With this being a virtual meetup, food and beverages will be of the \"bring your own\" kind. Grab a comfy chair and your favorite snacks and join us online!\n\n    Program\n\n    0:00 - Welcome\n    4:31 - Coraline Ada Ehmke - on #ethicalsource\n    40:40 - Anton Volkov - Event Processing with Redis Streams\n\n    See you on the interwebs!\n\n    Arno, Floor, Tom & Rayta\n  talks:\n    - title: \"On #ethicalsource\"\n      event_name: \"Amsterdam.rb Meetup June 2020\"\n      start_cue: \"04:31\"\n      end_cue: \"38:20\"\n      thumbnail_cue: \"5:20\"\n      video_provider: \"parent\"\n      id: \"coraline-ada-ehmke-talk-amsterdam-rb-2020-06\"\n      video_id: \"coraline-ada-ehmke-talk-amsterdam-rb-2020-06\"\n      speakers:\n        - Coraline Ada Ehmke\n\n    - title: \"Event Processing with Redis Streams\"\n      event_name: \"Amsterdam.rb Meetup June 2020\"\n      start_cue: \"40:40\"\n      end_cue: \"1:15:45\"\n      thumbnail_cue: \"41:00\"\n      video_provider: \"parent\"\n      id: \"anton-volkov-talk-amsterdam-rb-2020-06\"\n      video_id: \"anton-volkov-talk-amsterdam-rb-2020-06\"\n      speakers:\n        - Anton Volkov\n\n- id: \"amsterdamrb-meetup-april-2021\"\n  title: \"Amsterdam.rb Meetup April 2021\"\n  raw_title: \"Amsterdam.rb Meetup April 2021\"\n  date: \"2021-04-20\"\n  event_name: \"Amsterdam.rb Meetup April 2021\"\n  published_at: \"2021-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"nk24WMICx4k\"\n  description: |-\n    Live stream of the Amsterdam.rb Meetup of the 20th of April 2021.\n\n    Program of the video:\n    0:00 Introduction\n    3:33 Arno Fleming - Stepping up your game\n    26:35 Q&A with Arno Fleming\n    44:46 Julik Tarkhanov - Concurrency, Fibers and you\n    1:23:20 Q&A with Julik Tarkhanov\n    1:30:40 Closing notes and next meetup\n    1:33:00 Awkward waving\n\n    ---\n\n    It's been a while since the last Amsterdam.rb event 👋 We hope everyone is still doing well during this time.\n\n    All attendees can talk and ask questions with the community and speakers on the Ruby Netherlands Slack. Join our Slack today by following this link: https://slack.amsrb.org.\n    We will be chatting in the #amsterdam channel during this event, so don't forget to join the #amsterdam channel.\n\n    With this being a virtual meetup, food and beverages will be of the \"bring your own\" kind. Grab your most comfy chair and your favorite snacks and join us online!\n\n    See you on the interwebs!\n\n    Arno, Floor, Tom & Rayta\n\n    Event page: https://www.meetup.com/Amsterdam-rb/events/277117196/\n    Website: https://amsrb.org/\n    Twitter: https://twitter.com/amsrb\n\n    #Amsterdamrb #Ruby #Meetup #Amsterdam\n  talks:\n    - title: \"Stepping up your game\"\n      event_name: \"Amsterdam.rb Meetup April 2021\"\n      start_cue: \"03:33\"\n      end_cue: \"44:46\"\n      thumbnail_cue: \"4:16\"\n      video_provider: \"parent\"\n      id: \"arno-fleming-talk-amsterdam-rb-2021-04\"\n      video_id: \"arno-fleming-talk-amsterdam-rb-2021-04\"\n      speakers:\n        - Arno Fleming\n\n    - title: \"Concurrency, Fibers and you\"\n      event_name: \"Amsterdam.rb Meetup April 2021\"\n      start_cue: \"44:46\"\n      end_cue: \"1:23:20\"\n      thumbnail_cue: \"46:30\"\n      video_provider: \"parent\"\n      id: \"julik-tarkhanov-talk-amsterdam-rb-2021-04\"\n      video_id: \"julik-tarkhanov-talk-amsterdam-rb-2021-04\"\n      speakers:\n        - Julik Tarkhanov\n\n- id: \"amsterdamrb-meetup-may-2021\"\n  title: \"Amsterdam.rb Meetup May 2021\"\n  raw_title: \"Amsterdam.rb Meetup May 2021\"\n  date: \"2021-05-18\"\n  event_name: \"Amsterdam.rb Meetup May 2021\"\n  published_at: \"2021-05-18\"\n  video_provider: \"youtube\"\n  video_id: \"F2mp3DOHwq8\"\n  description: |-\n    Live stream of the Amsterdam.rb Meetup of the 18th of May 2021.\n\n    All attendees can talk and ask questions with the community and speakers on the Ruby Netherlands Slack. Join our Slack today by following this link: https://amsrbslack.herokuapp.com and navigate to the #amsterdam channel.\n\n    With this being a virtual meetup, food and beverages will be of the \"bring your own\" kind. Grab your most comfy chair and your favorite snacks and join us online!\n\n    Program of the event:\n    00:00 - Welcome and program\n    06:18 - Wander Hillen on \"Fibers from the inside\"*\n    34:54 - Q&A with Wander Hillen\n    45:10 - Call for speakers\n    46:01 - Sophia Castellarin on \"Building Vagrant (with Vagrant)\"\n    57:33 - Q&A with Sophia Castellarin\n    1:00:52 - Next meetup announcement\n\n    See you on the interwebs!\n\n    Arno, Floor, Tom & Rayta\n\n    *A continuation of Julik's talk at the last meetup (https://www.youtube.com/watch?v=nk24WMICx4k), and the talk-version of his blog on the subject: https://wjwh.eu/posts/2021-02-07-ruby-preemptive-fiber.html\n\n    PS. Are you interested in giving a talk at a future meetup? Contact us on Twitter (https://twitter.com/amsrb), Email (amsrborgs@rubynl.org), or on Slack (@Arno - he/him, @FloorD, @tombruijn or @rayta).\n\n    Event page: https://www.meetup.com/Amsterdam-rb/events/278021912/\n    Website: https://amsrb.org/\n    Twitter: https://twitter.com/amsrb\n\n    #Amsterdamrb #Ruby #Meetup #Amsterdam\n  talks:\n    - title: \"Fibers from the inside\"\n      event_name: \"Amsterdam.rb Meetup May 2021\"\n      start_cue: \"06:18\"\n      end_cue: \"45:10\"\n      thumbnail_cue: \"6:53\"\n      video_provider: \"parent\"\n      id: \"wander-hillen-talk-amsterdam-rb-2021-05\"\n      video_id: \"wander-hillen-talk-amsterdam-rb-2021-05\"\n      speakers:\n        - Wander Hillen\n\n    - title: \"Building Vagrant (with Vagrant)\"\n      event_name: \"Amsterdam.rb Meetup May 2021\"\n      start_cue: \"46:01\"\n      end_cue: \"1:00:52\"\n      thumbnail_cue: \"46:46\"\n      video_provider: \"parent\"\n      id: \"sophia-castellarin-talk-amsterdam-rb-2021-05\"\n      video_id: \"sophia-castellarin-talk-amsterdam-rb-2021-05\"\n      speakers:\n        - Sophia Castellarin\n\n- id: \"amsterdamrb-meetup-february-2022\"\n  title: \"Amsterdam.rb Meetup February 2022\"\n  raw_title: \"Amsterdam.rb Meetup February 2022\"\n  date: \"2022-02-22\"\n  event_name: \"Amsterdam.rb Meetup February 2022\"\n  published_at: \"2022-02-22\"\n  video_provider: \"youtube\"\n  video_id: \"jwhh_C80dBA\"\n  description: |-\n    Dear Ruby friends 🦊🐙🐹🐟,\n\n    It's been a while since the last Amsterdam.rb event 👋\n\n    The talks will be live streamed through YouTube (i.e you're at the right place). No proprietary software is needed and no need to join.\n\n    All attendees can talk and ask questions with the community and speakers on the Ruby Netherlands Slack. Join our Slack today: https://slack.amsrb.org\n\n    With this being a virtual meetup, food and beverages will be of the \"bring your own\" kind. Grab a comfy chair and your favorite snacks and join us online!\n\n    Program\n\n    - Benjamin Udink ten Cate on talking about technical debt\n    - Benoit Tigeot on fixing a gnarly issue in RSpec\n\n    Program:\n\n    - 00:00 - Introduction\n    - 03:40 - Benjamin Udink ten Cate on talking about technical debt\n    - 26:40 - Q&A\n    - 39:50 - Introduction after the break\n    - 41:33 - Benoit Tigeot on fixing a gnarly issue in RSpec\n    - 1:08:45 - Q&A\n    - 1:21:15 - Closing statements\n\n    Arno, Floor, Tom & Rayta\n  talks:\n    - title: \"Let's talk about technical debt\"\n      event_name: \"Amsterdam.rb Meetup February 2022\"\n      start_cue: \"03:40\"\n      end_cue: \"39:50\"\n      thumbnail_cue: \"4:43\"\n      video_provider: \"parent\"\n      id: \"benjamin-udink-ten-cate-talk-amsterdam-rb-2022-02\"\n      video_id: \"benjamin-udink-ten-cate-talk-amsterdam-rb-2022-02\"\n      speakers:\n        - Benjamin Udink ten Cate\n\n    - title: \"Fixing a gnarly issue in RSpec\"\n      event_name: \"Amsterdam.rb Meetup February 2022\"\n      start_cue: \"41:33\"\n      end_cue: \"1:21:15\"\n      video_provider: \"parent\"\n      id: \"benoit-tigiot-talk-amsterdam-rb-2022-02\"\n      video_id: \"benoit-tigiot-talk-amsterdam-rb-2022-02\"\n      speakers:\n        - Benoit Tigeot\n\n- id: \"amsterdamrb-meetup-may-2022\"\n  title: \"Amsterdam.rb Meetup May 2022\"\n  raw_title: \"Amsterdam.rb Meetup May 2022\"\n  date: \"2022-05-18\"\n  event_name: \"Amsterdam.rb Meetup May 2022\"\n  published_at: \"2022-05-17\"\n  video_provider: \"youtube\"\n  video_id: \"VU2eEnwWrhc\"\n  description: |-\n    Howdy folks! 🤠\n\n    We are back with a \"real life\" event!  Since this will be our first in-person event this year, we picked a venue with a view 🌅.\n\n    Zilverline will not just host our event, they will also provide us with food and drinks.\n\n    It goes without saying that we have a great set of speakers again.\n\n    In \"Introduction to Ruby Fibers and the SchedulerInterface\", Lars Vonk from Zilverline will kick off with his learnings on Ruby Fibers. Target audience: Junior - Senior level\n\n    Our second speaker is Jonathan Boccara from Doctolib and will talk about testing principles. Spoiler: it's not about the testing pyramid nor measuring code coverage....\n\n    Program:\n\n    00:00 Start\n    03:33 Opening, with Arno Fleming\n    08:08 Lars Vonk - Introduction to Ruby Fibers and the SchedulerInterface\n    41:28 Q&A with Lars\n    50:18 Break time\n    1:01:55 Jonathan Boccara - Thinking outside the (testing) pyramid\n    1:42:12 Q&A with Jonathan\n\n    The Amsterdam Ruby meetup: https://www.meetup.com/Amsterdam-rb/\n    Lars on LinkedIn: https://www.linkedin.com/in/larsvonk/\n    Jonathan on LinkedIn: https://www.linkedin.com/in/jonathan-boccara-23826921/\n\n    Arno, Floor, Tom & Rayta\n  talks:\n    - title: \"Introduction to Ruby Fibers and the SchedulerInterface\"\n      event_name: \"Amsterdam.rb Meetup May 2022\"\n      start_cue: \"08:08\"\n      end_cue: \"50:18\"\n      video_provider: \"parent\"\n      id: \"lars-vonk-talk-amsterdam-rb-2022-05\"\n      video_id: \"lars-vonk-talk-amsterdam-rb-2022-05\"\n      speakers:\n        - Lars Vonk\n\n    - title: \"Thinking outside the (testing) pyramid\"\n      event_name: \"Amsterdam.rb Meetup May 2022\"\n      start_cue: \"1:01:55\"\n      end_cue: \"2:04:23\"\n      thumbnail_cue: \"1:03:28\"\n      video_provider: \"parent\"\n      id: \"jonathan-boccara-talk-amsterdam-rb-2022-05\"\n      video_id: \"jonathan-boccara-talk-amsterdam-rb-2022-05\"\n      speakers:\n        - Jonathan Boccara\n\n- id: \"amsterdamrb-meetup-june-2022\"\n  title: \"Amsterdam.rb Meetup June 2022\"\n  raw_title: \"Amsterdam.rb Meetup June 2022\"\n  date: \"2022-06-22\"\n  event_name: \"Amsterdam.rb Meetup June 2022\"\n  published_at: \"2022-06-21\"\n  video_provider: \"youtube\"\n  video_id: \"kDh7DyWH5dM\"\n  thumbnail_xs: \"https://i3.ytimg.com/vi/kDh7DyWH5dM/default.jpg\"\n  thumbnail_sm: \"https://i3.ytimg.com/vi/kDh7DyWH5dM/default.jpg\"\n  thumbnail_md: \"https://i3.ytimg.com/vi/kDh7DyWH5dM/mqdefault.jpg\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/kDh7DyWH5dM/hqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/kDh7DyWH5dM/hqdefault.jpg\"\n  description: |-\n    HElLo RuBy-explorers 👩🏾‍🚀🚀,\n\n    This edition we will explore the world beyond Ruby!\n    Let's talk about Resilience and Accessibility...\n\n    We are doing this live at Codaisseur, in Amsterdam. Codaisseur will not just host our event, they will also provide us with food 🥦 and drinks 🧃.\n\n    It goes without saying that we have a great set of speakers again.\n    Our first guest is the marvelous, Bart de Water on how to build resilient systems.\n    Our second guest is the astonishing Derk-Jan Karrenbeld, CTO at NoticeSound, Co-Founder at Delft Solutions, with a talk on accessibility.\n\n    ---\n\n    Program:\n\n    - 00:00 - Opening and announcements\n    - 07:50 - Bart de Water: how to build resilient systems\n    - 39:15 - Q&A with Bart de Water\n    - 53:05 - Welcome after the break\n    - 53:55 - Derk-Jan Karrenbeld - Practically accessibility\n    - 1:46:00 - Q&A with Derk-Jan Karrenbeld\n\n    ---\n\n    This location is completely (wheelchair) accessible. Don't feel like joining in person? The live stream is on youtube, and it will stay up after the event. https://www.youtube.com/watch?v=kDh7DyWH5dM\n\n    See you there! Can't wait ✨ 🌈\n\n    Floor, Arno, Tom, Rayta\n  talks:\n    - title: \"How to build resilient systems\"\n      event_name: \"Amsterdam.rb Meetup June 2022\"\n      start_cue: \"07:50\"\n      end_cue: \"53:05\"\n      video_provider: \"parent\"\n      id: \"bart-de-water-talk-amsterdam-rb-2022-06\"\n      video_id: \"bart-de-water-talk-amsterdam-rb-2022-06\"\n      speakers:\n        - Bart de Water\n\n    - title: \"Practically accessibility\"\n      event_name: \"Amsterdam.rb Meetup June 2022\"\n      start_cue: \"53:55\"\n      end_cue: \"1:50:32\"\n      thumbnail_cue: \"54:14\"\n      video_provider: \"parent\"\n      id: \"derk-jan-karrenbeld-talk-amsterdam-rb-2022-06\"\n      video_id: \"derk-jan-karrenbeld-talk-amsterdam-rb-2022-06\"\n      speakers:\n        - Derk-Jan Karrenbeld\n\n- id: \"amsterdamrb-meetup-august-2022\"\n  title: \"Amsterdam.rb Meetup August 2022\"\n  raw_title: \"Amsterdam.rb Meetup August 2022\"\n  date: \"2022-08-18\"\n  event_name: \"Amsterdam.rb Meetup August 2022\"\n  published_at: \"2022-08-16\"\n  video_provider: \"youtube\"\n  video_id: \"Sqqb2fG74Rw\"\n  description: |-\n    Hello Rubyists 👋🧑‍🎨,\n\n    Welcome to the summer edition of the Amsterdam Ruby meetup! Let's talk about hosting and how our hobby projects are going.\n\n    We are doing this live at WeTravel in Amsterdam. WeTravel will not just host our event, they will also provide us with food 🥦 and drinks 🧃.\n\n    It goes without saying that we have a great set of speakers again.\n\n    Our first guest is the marvelous, Esther Barthel who will talk to us about using your dev skils to transition Ops to the Cloud.\n\n    Our second guest is the astonishing Aidan Rudkovskyi who will talk about his NotForSale project.\n\n    ---\n\n    Program:\n\n    00:00 Opening\n    05:50 Esther Barthel: Transitioning Ops to the Cloud, adding Dev skills to the mix\n    36:42 Q&A with Esther Barthel\n    46:00 End of break\n    47:15 Aidan Rudkovskyi: The NotForSale project\n    1:09:50 Q&A with Aidan Rudkovskyi\n\n    ---\n\n    This location is completely (wheelchair) accessible. Don't feel like joining in person? The live stream is on YouTube, and it will stay up after the event.\n\n    See you there! Can't wait ✨ 🌈\n\n    Floor, Arno, Tom, Rayta\n  talks:\n    - title: \"Transitioning Ops to the Cloud, adding Dev skills to the mix\"\n      event_name: \"Amsterdam.rb Meetup August 2022\"\n      start_cue: \"05:50\"\n      end_cue: \"46:00\"\n      thumbnail_cue: \"6:05\"\n      video_provider: \"parent\"\n      id: \"esther-barthel-talk-amsterdam-rb-2022-08\"\n      video_id: \"esther-barthel-talk-amsterdam-rb-2022-08\"\n      speakers:\n        - Esther Barthel\n\n    - title: \"The NotForSale project\"\n      event_name: \"Amsterdam.rb Meetup August 2022\"\n      start_cue: \"47:15\"\n      end_cue: \"1:18:28\"\n      thumbnail_cue: \"56:55\"\n      video_provider: \"parent\"\n      id: \"aidan-rudkovskyi-talk-amsterdam-rb-2022-08\"\n      video_id: \"aidan-rudkovskyi-talk-amsterdam-rb-2022-08\"\n      speakers:\n        - Aidan Rudkovskyi\n\n- id: \"amsterdamrb-meetup-september-2022\"\n  title: \"Amsterdam.rb Meetup September 2022\"\n  raw_title: \"Amsterdam.rb Meetup September 2022\"\n  date: \"2022-09-08\"\n  event_name: \"Amsterdam.rb Meetup September 2022\"\n  published_at: \"2022-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"kTI9E6pOHpM\"\n  description: |-\n    Hello Rubyists 🤖👶,\n\n    We're back in September with two great talks! Learn about the new static and dynamic website generator in town: Bridgetown. Learn how BetterUp managed data sovereignty across two continents without ruining people's experiences.\n\n    Program\n\n    00:00 Start\n    00:35 BetterUp introduction\n    04:50 Technical difficulties!\n    06:45 Opening statements\n    10:55 Jared White: Bridgetown: Server-Side Rendering in a Static Site Generator\n    43:20 Q&A with Jared White\n    54:55 Break\n    55:35 Welcome after the break\n    56:50 Ahmad Elassuty: learnings on BetterUp's European expansion\n    1:19:30 Q&A with Ahmad Elassuty\n\n    This month's meetup will take place at the BetterUp offices. They will not just host the event, but also provide delicious food and drinks to power you through the evening.\n\n    This location is completely (wheelchair) accessible. Sign up on meetup: https://www.meetup.com/amsterdam-rb/events/288348816/\n    Don't feel like joining in person? Join the live stream here. It will stay up after the event. Join us in the chat!\n\n    See you there! We can't wait 👋💚\n\n    Floor, Arno, Tom and Rayta\n  talks:\n    - title: \"Bridgetown: Server-Side Rendering in a Static Site Generator\"\n      event_name: \"Amsterdam.rb Meetup September 2022\"\n      start_cue: \"10:55\"\n      end_cue: \"54:55\"\n      video_provider: \"parent\"\n      id: \"jared-white-talk-amsterdam-rb-2022-09\"\n      video_id: \"jared-white-talk-amsterdam-rb-2022-09\"\n      speakers:\n        - Jared White\n\n    - title: \"Learnings on BetterUp's European expansion\"\n      event_name: \"Amsterdam.rb Meetup September 2022\"\n      start_cue: \"56:50\"\n      end_cue: \"1:33:32\"\n      video_provider: \"parent\"\n      id: \"ahmad-elassuty-talk-amsterdam-rb-2022-09\"\n      video_id: \"ahmad-elassuty-talk-amsterdam-rb-2022-09\"\n      speakers:\n        - Ahmad Elassuty\n\n- id: \"amsterdamrb-meetup-november-2022\"\n  title: \"Amsterdam.rb Meetup November 2022\"\n  raw_title: \"Amsterdam.rb Meetup November 2022\"\n  date: \"2022-11-15\"\n  event_name: \"Amsterdam.rb Meetup November 2022\"\n  published_at: \"2022-11-16\"\n  video_provider: \"youtube\"\n  video_id: \"W5kaiwm5mZE\"\n  description: |-\n    Hello Rubyists 🚢 🦆,\n\n    Thank you for joining us for the last meetup of the year! The second talk of the evening of the 15th of November 2022 meetup was recorded on location.\n\n    This talk is by Tom de Bruijn about Writing your own Domain Specific Language in Ruby.\n\n    - Module builder pattern: https://dejimata.com/2017/5/20/the-ruby-module-builder-pattern\n    - Slides: https://speakerdeck.com/tombruijn/write-your-own-domain-specific-language-in-ruby-lets-do-some-metaprogramming\n\n    This month's meetup will took place at the Flexport offices. They did not just host the event, but also provided delicious food and drinks to power us through the evening.\n\n    Thank you for joining us! 👋💚\n\n    Floor, Arno, Tom and Rayta\n\n    00:00 Introduction\n    00:37 Start of talk\n    22:25 Questions & Answers\n  talks:\n    - title: \"Write your own DSL in Ruby\"\n      event_name: \"Amsterdam.rb Meetup November 2022\"\n      start_cue: \"00:37\"\n      end_cue: \"31:33\"\n      video_provider: \"parent\"\n      id: \"tom-de-bruijn-talk-amsterdam-rb-2022-11\"\n      video_id: \"tom-de-bruijn-talk-amsterdam-rb-2022-11\"\n      slides_url: \"https://speakerdeck.com/tombruijn/write-your-own-domain-specific-language-in-ruby-lets-do-some-metaprogramming\"\n      speakers:\n        - Tom de Bruijn\n\n- id: \"amsterdamrb-meetup-february-2023\"\n  title: \"Amsterdam.rb Meetup February 2023\"\n  raw_title: \"Amsterdam.rb Meetup February 2023\"\n  date: \"2023-02-21\"\n  event_name: \"Amsterdam.rb Meetup February 2023\"\n  published_at: \"2023-02-21\"\n  video_provider: \"youtube\"\n  video_id: \"7azEFrQcVNE\"\n  description: |-\n    Hello Rubyists ❄️ ⛄️,\n\n    Join us for the first meetup of 2023! The February meetup will start with two new talks! Join us to learn new things and chat people from the community. Check out the event program.\n\n    This month's meetup will take place at the Reaktor's office! 🏢 OfferZen will provide the delicious food and drinks to power you through the evening! 😋\n\n    This location is completely (wheelchair) accessible. We will most likely livestream this event.\n\n    See you there! We can't wait 👋💚\n\n    Floor, Arno, Tom and Rayta\n\n    Program:\n    00:00 - Opening statements\n    10:20 - Aleks Yanchuk: Why would I need Cucumber if I'm already using RSpec?\n    39:03 - Aleks Yanchuk: Q&A\n    48:45 - Statements after the break (sorry for the racing noises)\n    51:43 - Gys Muller: Techniques for Terrible Technical Leadership\n    1:25:00 - Gys Muller: Q&A\n  talks:\n    - title: \"Why would I need Cucumber if I'm already using RSpec?\"\n      event_name: \"Amsterdam.rb Meetup February 2023\"\n      start_cue: \"10:20\"\n      end_cue: \"48:45\"\n      video_provider: \"parent\"\n      id: \"aleks-yanchuk-talk-amsterdam-rb-2023-02\"\n      video_id: \"aleks-yanchuk-talk-amsterdam-rb-2023-02\"\n      speakers:\n        - Aleks Yanchuk\n\n    - title: \"Techniques for Terrible Technical Leadership\"\n      event_name: \"Amsterdam.rb Meetup February 2023\"\n      start_cue: \"51:43\"\n      end_cue: \"1:32:57\"\n      video_provider: \"parent\"\n      id: \"gys-muller-talk-amsterdam-rb-2023-02\"\n      video_id: \"gys-muller-talk-amsterdam-rb-2023-02\"\n      speakers:\n        - Gys Muller\n\n- id: \"amsterdamrb-meetup-march-2023\"\n  title: \"Amsterdam.rb Meetup March 2023\"\n  raw_title: \"Amsterdam.rb Meetup March 2023\"\n  date: \"2023-03-22\"\n  event_name: \"Amsterdam.rb Meetup March 2023\"\n  published_at: \"2023-03-21\"\n  video_provider: \"youtube\"\n  video_id: \"hgdp3qDXW4w\"\n  description: |-\n    Hello Rubyists 🌦️🍀,\n\n    Join us for lightning talks in our second meetup of the year! The March meetup will start with 4 fresh talks, followed by another 4 talks. Join us to see what the community is thinking, building, and procrastinating on. There is plenty of time to talk shop with other Ruby professionals, or have a casual chat with people from the community. Check out the event program.\n\n    This month's meetup will take place at the office of recharge.com! OfferZen will provide the delicious food and drinks to power you through the evening! 😋\n\n    00:00 Start - without audio\n    00:16 Introduction\n    08:08 Wander Hillen - Multiplying fishes as fast as possible (for Santa!)\n    19:44 Brett Beutell - Metaprogramming our merry ways to metrics for Ruby methods\n    31:36 Derk-Jan Karrenbeld - Exercis[em] is excellent\n    43:35 Amanda Perino - The Rails Foundation - what you can expect\n    49:10 Break\n    49:30 Introduction after the break\n    50:53 David Kelly - Looking forward instead of looking back - how we built a better circuit breaker\n    1:02:43 Daniel Paulus - Power naps, self care and mental health\n    1:12:52 Arno Fleming - More power in energy constrained times\n    1:24:34 Floor Drees - What Rubyists need to know to start securing their open source software supply chains\n    1:37:00 Closing notes\n\n    See you there! We can't wait 👋💚\n\n    Floor, Arno, Tom and Rayta\n\n    https://www.amsrb.org/\n    https://www.meetup.com/Amsterdam-rb/\n    #Ruby #Amsterdam #amsrb\n  talks:\n    - title: \"Multiplying fishes as fast as possible (for Santa!)\"\n      event_name: \"Amsterdam.rb Meetup March 2023\"\n      start_cue: \"08:08\"\n      end_cue: \"19:44\"\n      video_provider: \"parent\"\n      id: \"wander-hillen-talk-amsterdam-rb-2023-03\"\n      video_id: \"wander-hillen-talk-amsterdam-rb-2023-03\"\n      speakers:\n        - Wander Hillen\n\n    - title: \"Metaprogramming our merry ways to metrics for Ruby methods\"\n      event_name: \"Amsterdam.rb Meetup March 2023\"\n      start_cue: \"19:44\"\n      end_cue: \"31:36\"\n      video_provider: \"parent\"\n      id: \"brett-beutell-talk-amsterdam-rb-2023-03\"\n      video_id: \"brett-beutell-talk-amsterdam-rb-2023-03\"\n      speakers:\n        - Brett Beutell\n\n    - title: \"Exercis[em] is excellent\"\n      event_name: \"Amsterdam.rb Meetup March 2023\"\n      start_cue: \"31:36\"\n      end_cue: \"43:35\"\n      video_provider: \"parent\"\n      id: \"derk-jan-karrenbeld-talk-amsterdam-rb-2023-03\"\n      video_id: \"derk-jan-karrenbeld-talk-amsterdam-rb-2023-03\"\n      speakers:\n        - Derk-Jan Karrenbeld\n\n    - title: \"The Rails Foundation - what you can expect\"\n      event_name: \"Amsterdam.rb Meetup March 2023\"\n      start_cue: \"43:35\"\n      end_cue: \"49:10\"\n      thumbnail_cue: \"43:57\"\n      video_provider: \"parent\"\n      id: \"amanda-perino-talk-amsterdam-rb-2023-03\"\n      video_id: \"amanda-perino-talk-amsterdam-rb-2023-03\"\n      speakers:\n        - Amanda Perino\n\n    - title: \"Looking forward instead of looking back - how we built a better circuit breaker\"\n      event_name: \"Amsterdam.rb Meetup March 2023\"\n      start_cue: \"50:53\"\n      end_cue: \"1:02:43\"\n      thumbnail_cue: \"51:15\"\n      video_provider: \"parent\"\n      id: \"david-kelly-talk-amsterdam-rb-2023-03\"\n      video_id: \"david-kelly-talk-amsterdam-rb-2023-03\"\n      speakers:\n        - David Kelly\n\n    - title: \"Power naps, self care and mental health\"\n      event_name: \"Amsterdam.rb Meetup March 2023\"\n      start_cue: \"1:02:43\"\n      end_cue: \"1:12:52\"\n      video_provider: \"parent\"\n      id: \"daniel-paulus-talk-amsterdam-rb-2023-03\"\n      video_id: \"daniel-paulus-talk-amsterdam-rb-2023-03\"\n      speakers:\n        - Daniel Paulus\n\n    - title: \"More power in energy constrained times\"\n      event_name: \"Amsterdam.rb Meetup March 2023\"\n      start_cue: \"1:12:52\"\n      end_cue: \"1:24:34\"\n      thumbnail_cue: \"1:13:09\"\n      video_provider: \"parent\"\n      id: \"arno-fleming-talk-amsterdam-rb-2023-03\"\n      video_id: \"arno-fleming-talk-amsterdam-rb-2023-03\"\n      speakers:\n        - Arno Fleming\n\n    - title: \"What Rubyists need to know to start securing their open source software supply chains\"\n      event_name: \"Amsterdam.rb Meetup March 2023\"\n      start_cue: \"1:24:34\"\n      end_cue: \"1:37:00\"\n      video_provider: \"parent\"\n      id: \"floor-drees-talk-amsterdam-rb-2023-03\"\n      video_id: \"floor-drees-talk-amsterdam-rb-2023-03\"\n      speakers:\n        - Floor Drees\n\n- id: \"amsterdamrb-meetup-november-2023\"\n  title: \"Amsterdam.rb Meetup November 2023\"\n  raw_title: \"Amsterdam.rb Meetup November 2023\"\n  date: \"2023-11-21\"\n  event_name: \"Amsterdam.rb Meetup November 2023\"\n  published_at: \"2023-11-22\"\n  video_provider: \"youtube\"\n  video_id: \"gQyIsEq4hrg\"\n  description: |-\n    Hello Rubyists! 🧣🧤\n\n    Are you ready for winter?  Join us for the last meetup of 2023! The November meetup will end with two talks!  Join us to learn new things and chat with people from the community. Anyone interested in learning more about Ruby and the local tech community is welcome to join!\n\n    This month's meetup will take place at the Catawiki office! They will also provide the delicious food and drinks to power us through the evening 😋\n\n    We had some technical difficulties with this meetup's stream, so some parts were removed in the livestream or have low audio volume.\n\n    00:00 Meetup start\n    00:40 Catawiki sponsorship\n    02:43 Meetup welcome\n    05:58 Community questionnaire discussion\n    17:52 Kirill Kaiumov - Detecting N+1 query problem effectively\n\n    Cheers,\n\n    Tom, Arno and Aidan\n\n    https://www.amsrb.org/\n    https://www.meetup.com/Amsterdam-rb/\n    #Ruby #Amsterdam #amsrb\n  talks:\n    - title: \"Detecting N+1 query problem effectively\"\n      event_name: \"Amsterdam.rb Meetup November 2023\"\n      start_cue: \"17:52\"\n      end_cue: \"47:09\"\n      thumbnail_cue: \"18:58\"\n      video_provider: \"parent\"\n      id: \"kirill-kaiumov-talk-amsterdam-rb-2023-11\"\n      video_id: \"kirill-kaiumov-talk-amsterdam-rb-2023-11\"\n      speakers:\n        - Kirill Kaiumov\n\n- id: \"amsterdamrb-meetup-april-2024\"\n  title: \"Amsterdam.rb Meetup April 2024\"\n  raw_title: \"Amsterdam.rb Meetup April 2024\"\n  date: \"2024-04-25\"\n  event_name: \"Amsterdam.rb Meetup April 2024\"\n  published_at: \"2024-04-19\"\n  video_provider: \"youtube\"\n  video_id: \"CWBD3vUTzTg\"\n  description: |-\n    Hello Rubyists!\n\n    Join us for this April for another wonderful meetup! We will have two talks, to be announced later. Join us to learn new things and chat with people from the community. Anyone interested in learning more about Ruby and the local tech community is welcome to join!\n\n    Program\n    00:00 Opening statements\n    6:56 Krzysztof Hasiński - 'Fantastic Databases And Where to Find Them'\n    44:22 Sebastian van Hesteren - 'Locking with PostgreSQL at Cheddar'\n    1:10:52 Closing statements\n\n    This month's meetup will take place at the Catawiki Amsterdam office! They will also provide the delicious food and drinks to power us through the evening 😋\n\n    Cheers,\n    Tom, Arno and Aidan\n\n    PS 1. This month the meetup will take place on a Thursday, not a Tuesday.\n    PS 2. If you are interested in giving a talk, let us know. Learn more about giving a talk at Amsterdam.rb.\n  talks:\n    - title: \"Fantastic Databases And Where to Find Them\"\n      event_name: \"Amsterdam.rb Meetup April 2024\"\n      start_cue: \"6:56\"\n      end_cue: \"44:22\"\n      video_provider: \"parent\"\n      id: \"krzysztof-hasinski-talk-amsterdam-rb-2024-04\"\n      video_id: \"krzysztof-hasinski-talk-amsterdam-rb-2024-04\"\n      speakers:\n        - Krzysztof Hasiński\n\n    - title: \"Locking with PostgreSQL at Cheddar\"\n      event_name: \"Amsterdam.rb Meetup April 2024\"\n      start_cue: \"44:22\"\n      end_cue: \"1:10:52\"\n      video_provider: \"parent\"\n      id: \"sebastian-van-hesteren-talk-amsterdam-rb-2024-04\"\n      video_id: \"sebastian-van-hesteren-talk-amsterdam-rb-2024-04\"\n      speakers:\n        - Sebastian van Hesteren\n"
  },
  {
    "path": "data/amsterdam-rb/series.yml",
    "content": "---\nname: \"Amsterdam.rb\"\nwebsite: \"https://www.amsrb.org\"\nmeetup: \"https://www.meetup.com/amsterdam-rb/\"\ngithub: \"https://github.com/amsrb\"\ntwitter: \"amsrb\"\nmastodon: \"https://ruby.social/@amsrb\"\nyoutube_channel_name: \"rubynl\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"NL\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCyExf-593j4hjN_cFCSnr2w\"\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2013/event.yml",
    "content": "---\nid: \"PLrjohaqTgNJMPfLcEek4_3OkoG9wXwFlG\"\nlocation: \"St. Augustine, FL, United States\"\ntitle: \"Ancient City Ruby 2013\"\nkind: \"conference\"\ndescription: |-\n  Presentation videos from Ancient City Ruby 2013\nstart_date: \"2013-04-04\"\nend_date: \"2013-04-05\"\npublished_at: \"2013-06-24\"\nchannel_id: \"UCk7lIUwfv3OAWCfk3rreAAg\"\nyear: 2013\nwebsite: \"https://web.archive.org/web/20130305234849/http://www.ancientcityruby.com/\"\nbanner_background: |-\n  linear-gradient(to bottom, #B8DBDF 67%, #0C7F8B 67%) left top / 50% 100% no-repeat, /* Left side */\n  linear-gradient(to bottom, #B8DBDF 67%, #0C7F8B 67%) right top / 50% 100% no-repeat /* Right side */\nfeatured_background: \"#B8DBDF\"\nfeatured_color: \"#0C7F8B\"\ncoordinates:\n  latitude: 29.8921835\n  longitude: -81.3139313\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2013/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: schedule website\n\n# Website: https://web.archive.org/web/20130305234849/http://www.ancientcityruby.com/\n\n- id: \"nell-shamrell-ancient-city-ruby-2013\"\n  title: \"Test Driven Development: A Love Story\"\n  raw_title: \"Nell Shamrell - Test Driven Development: A Love Story - Ancient City Ruby 2013\"\n  speakers:\n    - Nell Shamrell\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-06-24\"\n  description: |-\n    Practicing Test Driven Development (TDD) is like falling in love. It may first seem like all your development problems will disappear. However, it's not all unicorns and rainbows. You have to work at it, and keep working at it, for the rest of your development life. It is hard, and it's natural to question whether the value is worth the effort.\n\n    So why do it? Why would you bother going through all that trouble, dramatically changing the way you code, learn new domain specific languages, and initially slow down the rate at which you produce code when you have no time to lose?\n\n    This talk will answer the \"why\" by sharing my experience of passing through the five stages of grief (denial, anger, bargaining, depression, and acceptance) as I learned TDD, and how acceptance grew to love.\n\n    You will walk away from the talk with techniques for maintaining and strengthening your relationship with TDD. Test frameworks and languages may come and go, but the fundamentals and value of TDD remain.\n  video_provider: \"youtube\"\n  video_id: \"nBtO1UOK9Hs\"\n\n- id: \"russ-olsen-ancient-city-ruby-2013\"\n  title: \"Insight, Intuition and Programming\"\n  raw_title: \"Russ Olsen - Insight, Intuition and Programming - Ancient City Ruby 2013\"\n  speakers:\n    - Russ Olsen\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-06-24\"\n  description: |-\n    We programmers tend to think of ourselves as concrete, logical thinkers. We work from step 1 to step 2 through to step N. So we say. But real life is not like that: One minute you have no idea how the new design will come together and the next, well, there it is. One minute you haven't a clue as to why the program is doing that and the next it is all just obvious. And we have all seen code that is wonderful or horrible in some indescribable way.\n  video_provider: \"youtube\"\n  video_id: \"rQp1CFJxgs0\"\n\n- id: \"chris-hunt-ancient-city-ruby-2013\"\n  title: \"Impressive Ruby Productivity with Vim and Tmux\"\n  raw_title: \"Chris Hunt - Impressive Ruby Productivity with Vim and Tmux - Ancient City Ruby 2013\"\n  speakers:\n    - Chris Hunt\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-06-25\"\n  description: |-\n    Impress your friends, scare your enemies, and boost your productivity by 800% with this live demonstration of Vim and Tmux. You will learn how to build custom IDEs for each of your projects, navigate quickly between files, write and run tests, view and compare git history, create pull requests, publish gists, format and refactor your code with macros, remote pair program, and more, all without leaving the terminal. Come prepared to learn and ask questions; this is serious business.\n  video_provider: \"youtube\"\n  video_id: \"9jzWDr24UHQ\"\n\n- id: \"eric-redmond-ancient-city-ruby-2013\"\n  title: \"Distributed Patterns in Ruby\"\n  raw_title: \"Eric Redmond - Distributed Patterns in Ruby - Ancient City Ruby 2013\"\n  speakers:\n    - Eric Redmond\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-06-25\"\n  description: |-\n    Scalability today is no longer a question of which programming language you use, or (largely) which web architecture you choose. Instead, scalability is a matter of how you handle two things: data distribution and message passing. This talk is over a few ways of solving both: distributed data structures and messaging patterns.\n  video_provider: \"youtube\"\n  video_id: \"Adu_dbcnUHA\"\n\n- id: \"jacob-burkhart-ancient-city-ruby-2013\"\n  title: \"How to Fail at Background Jobs\"\n  raw_title: \"Jacob Burkhart - How to Fail at Background Jobs - Ancient City Ruby 2013\"\n  speakers:\n    - Jacob Burkhart\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-06-26\"\n  description: |-\n    From DRB, XMPP, and AMQP to Resque and Rails 4. Running a background worker process is a tool I've reached for often, and while the underlying tools may change, the same problems seem to crop up in every one. A failed request serves your fancy custom 500 error page, but what about a failed job? Is there such a thing as a \"reliable\" queuing system that will never lose OR double process any jobs? Are we talking about \"simple\" asynchronous method calls on models or should we build \"pure\" workers with only the knowledge of a single task? What does \"idempotent\" mean again? Please allow me to enliven the debates.\n  video_provider: \"youtube\"\n  video_id: \"dkFwNEFr9cg\"\n\n- id: \"andy-lindeman-ancient-city-ruby-2013\"\n  title: \"Building a mocking library\"\n  raw_title: \"Andy Lindeman - Building a mocking library - Ancient City Ruby 2013\"\n  speakers:\n    - Andy Lindeman\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-06-27\"\n  description: |-\n    This talk is not about testing, nor is it really about mocking. However, analyzing a mock object library is a great way to showcase advanced Ruby topics. Have you ever wondered exactly how a mock object library does what it does? You can understand it!\n\n    This talk uses a simplified mock object library as the basis for delving into topics such as metaprogramming and the Ruby object model. The goal is to increase the knowledge of these topics in the Ruby community. With this know--how, you will be better suited to build from and contribute to common Ruby tools that use them.\n  video_provider: \"youtube\"\n  video_id: \"2aYdtS7FZJA\"\n\n- id: \"paolo-nusco-perrotta-ancient-city-ruby-2013\"\n  title: \"This is Your Brain on Software\"\n  raw_title: \"Paolo Perrotta - This is Your Brain on Software - Ancient City Ruby 2013\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-06-27\"\n  description: |-\n    Developers are rational thinkers who take objective decisions. Yeah, sure. If that is the case, how can we disagree on so many things?\n\n    Examples are all around. Why do Rubyists and Java developers despise each others' designs? Why do people try hard to fit static typing and distributed environments? Why do Windows programmers loathe the command line? Let me try answering these questions, with a few hints from cognitive psychology.\n  video_provider: \"youtube\"\n  video_id: \"v9Gkq9-dnlU\"\n\n- id: \"ben-orenstein-ancient-city-ruby-2013\"\n  title: \"Live Coding with Ben\"\n  raw_title: \"Ben Orenstein - Live Coding with Ben - Ancient City Ruby 2013\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-07-01\"\n  description: |-\n    Ben believes that the best way for programmers to learn is to watch each other work. We'll leave slides behind and focus instead on the greater information density achieved through live coding. We'll discuss the strengths and weaknesses of real code, and refactor it right onstage. As we do so, we'll bump into lots of meaty topics:\n    -  Potential downfalls of the 'extract module' refactoring (aka ActiveSupport::Concern).\n    -  The pros and cons of Dependency Injection.\n    -  How two good OO design ideas (like SRP and Tell Don't Ask) can contradict each other, and what to do about it.\n    -  How well--placed functional programming can improve a codebase.\n    -  Whether the Law of Demeter should be followed religiously, and what it means if that's hard to do.\n    -  Why fast tests are usually good tests, and vice versa.\n    -  Audience participation is strongly encouraged, as is stealing the speaker's Vim tricks for your own use.\n  video_provider: \"youtube\"\n  video_id: \"C0H-LyZy9Ko\"\n\n- id: \"sandi-metz-ancient-city-ruby-2013\"\n  title: \"The Magic Tricks of Testing\"\n  raw_title: \"Sandi Metz - Magic Tricks of Testing - Ancient City Ruby 2013\"\n  speakers:\n    - Sandi Metz\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-07-02\"\n  slides_url: \"https://speakerdeck.com/skmetz/magic-tricks-of-testing-ancientcityruby\"\n  description: |-\n    Tests are supposed to save us money. How is it, then, that many times they become millstones around our necks, gradually morphing into fragile, breakable things that raise the cost of change?\n\n    We write too many tests and we test the wrong kinds of things. This talk strips away the veil and offers simple, practical guidelines for choosing what to test and how to test it. Finding the right testing balance isn't magic, it's a magic trick; come and learn the secret of writing stable tests that protect your application at the lowest possible cost.\n  video_provider: \"youtube\"\n  video_id: \"qPfQM4w4I04\"\n\n- id: \"avdi-grimm-ancient-city-ruby-2013\"\n  title: \"Pairing is Caring\"\n  raw_title: \"Avdi Grimm - Pairing is Caring - Ancient City Ruby 2013\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-07-08\"\n  description: |-\n    In the second half of 2012 I \"quit my job\" as a traditional Ruby/Rails consultant in order to become a consulting pair programmer. After spending hundreds of hours pairing with dozens of developers from around the world, I'd like to share some of my observations. We'll talk about the mechanics of ad-hoc remote pair-programming, but more importantly about why I think widespread pairing is important to maintaining the health of the Ruby community. Whether you work solo or you pair regularly, you should leave this talk empowered and excited to broaden your pair-programming horizons.\n  video_provider: \"youtube\"\n  video_id: \"zCzc5W7vHQg\"\n\n- id: \"ben-smith-ancient-city-ruby-2013\"\n  title: \"Hacking with Gems\"\n  raw_title: \"Ben Smith - Hacking with Gems - Ancient City Ruby 2013\"\n  speakers:\n    - Ben Smith\n  event_name: \"Ancient City Ruby 2013\"\n  date: \"2013-04-04\"\n  published_at: \"2013-07-03\"\n  description: |-\n    What's the worst that could happen if your app has a dependency on a malicious gem? How easy would it be to write a gem that could compromise a box?\n\n    Much of the Ruby community blindly trusts our gems. This talk will make you second--guess that trust, and show you how to vet gems that you do choose to use.\n  video_provider: \"youtube\"\n  video_id: \"UksbZx4ph8E\"\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2014/event.yml",
    "content": "---\nid: \"PLrjohaqTgNJMDh6Jg0vPftT2S34zPEPhJ\"\ntitle: \"Ancient City Ruby 2014\"\nkind: \"conference\"\nlocation: \"St. Augustine, FL, United States\"\ndescription: \"\"\nstart_date: \"2014-04-03\"\nend_date: \"2014-04-04\"\npublished_at: \"2014-04-24\"\nchannel_id: \"UCk7lIUwfv3OAWCfk3rreAAg\"\nyear: 2014\nwebsite: \"https://web.archive.org/web/20140627164046/http://www.ancientcityruby.com/\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#171717\"\ncoordinates:\n  latitude: 29.8921835\n  longitude: -81.3139313\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2014/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20140627164046/http://www.ancientcityruby.com/\n# Schedule: https://web.archive.org/web/20140627164046/http://www.ancientcityruby.com/\n\n# April 3 & 4, 2024 - St. Augustine, FL\n\n## Day 1 - 2014-04-03\n\n# Breakfast & Registration\n\n- id: \"leon-gersing-ancient-city-ruby-2014\"\n  title: \"Leon's Allegory of the Cave\"\n  raw_title: \"Leon Gersing - Leon's Allegory of the Cave - Ancient City Ruby 2014\"\n  speakers:\n    - Leon Gersing\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-03\"\n  published_at: \"2014-05-08\"\n  description: |-\n    What is the role of the software developer in the modern world? We are more educated now than during any time in recorded human history. We have more access to tools and the ability to craft our own in order to better communicate with one another; to see the world in all of its various forms, beautiful and strange. All of this information, all of this knowledge and yet the quest for truth, understanding and wisdom has become increasingly strained. We adopt the ideologies and rituals of archetypes instead of masters and therein feel the hollowness of the modern human condition. In this session, I will present to you the teachings of my masters as I have come to understand them and the wisdom I've gained over the years in my relentless pursuit for truth in the modern world. Our collective existential ennui is distorting the very fabric of reality. Seeing the world as it truly is can free our minds to the infinite possibilities that lie before us. Can we be more than the context we are born into? Can we rise above the confining binds of hierarchy, class, status and the distortions of those we choose to associate ourselves? Let's take some time to remember who we are, where we are going and discover, perhaps, why we are here.\n  video_provider: \"youtube\"\n  video_id: \"_oTEnczCS0s\"\n\n# Sponsor Lightning Talks\n\n- id: \"justin-searls-ancient-city-ruby-2014\"\n  title: \"Breaking Up (With) Your Test Suite\"\n  raw_title: \"Justin Searls - Breaking Up (With) Your Test Suite - Ancient City Ruby 2014\"\n  speakers:\n    - Justin Searls\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-03\"\n  published_at: \"2014-05-09\"\n  description: |-\n    It's about time for the Ruby community to adopt a more mature and nuanced approach to testing.\n\n    Gone are the days when \"is it tested?\" was a boolean question. It no longer makes sense for a single test suite to accomplish numerous objectives, because the design of our tests are so influenced by the benefit we hope to realize from them. What's less clear to most developers is the best approach to breaking a test suite up.\n\n    This talk will introduce a testing architecture that's appropriate for the post-monolithic age of Ruby application development. We'll discuss why each test suite can provide at most one type of confidence and one type of feedback. I'll introduce a set of five narrow, focused types of test suites and explore how each of their roles can combine to provide all of the value that test automation can hope to offer. Together, we'll gain the ability to discuss the value of each test with much greater precision and subtlety.\n  video_provider: \"youtube\"\n  video_id: \"vkAfGHd7sZY\"\n\n# Sponsor Lightning Talks\n\n# Break\n\n# TODO: missing talk: David Copeland - Let's Write Some Weird Ruby\n\n# Lunch\n\n- id: \"katrina-owen-ancient-city-ruby-2014\"\n  title: \"Overkill\"\n  raw_title: \"Katrina Owen - Overkill - Ancient City Ruby 2014\"\n  speakers:\n    - Katrina Owen\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-03\"\n  published_at: \"2014-05-09\"\n  description: |-\n    When is it okay to build an orbital laser to destroy an ant-hill?\n\n    Many cry \"overkill\" when design principles are applied to trivial problems. And for good reason: in the context of work, excessive embellishment gets us into trouble. Complexity costs us time and money.\n\n    This talk explores how stepping outside of the realm of work and applying outrageous engineering practices to toy problems can deepen our understanding of the trade-offs that we make. Comically simple problems provide the perfect ground for developing actionable heuristics which can be applied to those monstrous complexities that we face in the real world.\n  video_provider: \"youtube\"\n  video_id: \"GTpZ0ffQrIE\"\n\n# Sponsor Lightning Talks\n\n- id: \"richard-schneeman-ancient-city-ruby-2014\"\n  title: \"Testing the Untestable\"\n  raw_title: \"Richard Schneeman - Testing the Untestable - Ancient City Ruby 2014\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-03\"\n  published_at: \"2014-05-09\"\n  description: |-\n    Good tests are isolated, they're repeatable, they're deterministic. Good tests don't touch the network and are flexible when it comes to change. Bad tests are all of the above and more. Bad tests are no tests at all: which is where I found myself with a 5 year legacy codebase running in production and touching millions of customers with minimal use-case documentation. We'll cover this experience and several like it while digging into how to go from zero to total test coverage as painlessly as possible. You will learn how to stay sane in the face of insane testing conditions, and how to use these tests to deconstruct a monolith app. When life gives you a big ball of mud, write a big ball of tests.\n  video_provider: \"youtube\"\n  video_id: \"MdtfcLJwOf0\"\n\n# Sponsor Lightning Talks\n\n# Break\n\n- id: \"ben-lovell-ancient-city-ruby-2014\"\n  title: \"Fast, Testable and SANE APIs\"\n  raw_title: \"Ben Lovell - Fast, Testable and SANE APIs\"\n  speakers:\n    - Ben Lovell\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-03\"\n  published_at: \"2014-05-09\"\n  description: |-\n    By now, we've all written JSON APIs in Rails. But how do you write fast, testable and sane APIs? I'll guide you through the trials of designing and building awesome, scalable APIs. We'll cover rails-api, activemodelserializers, and all the associated goodness that our ecosystem has to offer.\n\n    I'll speak on the approaches to authentication, how to ensure we remain good REST/HTTP citizens and maybe if I have time I'll share some of my top secret beard grooming tips!\n  video_provider: \"youtube\"\n  video_id: \"dUPp4DhFLnY\"\n\n## Day 2 - 2014-04-04\n\n# Breakfast\n\n- id: \"terence-lee-ancient-city-ruby-2014\"\n  title: \"Ruby & You\"\n  raw_title: \"Terence Lee - Ruby & You - Ancient City Ruby 2014\"\n  speakers:\n    - Terence Lee\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-04\"\n  published_at: \"2015-02-12\"\n  description: |-\n    On November 22, 2013, a devastating security exploit was publicized to the Ruby community: Heap Overflow in Floating Point Parsing (CVE-2013-4164). There was no fixes provided for Ruby 1.9.2. In fact, Ruby 1.9.2 has never had a formal end of life announcement and at Heroku we realized this impacted our ability to provide reliable runtime support. Not wanting to leave our customers high and dry, Heroku released Ruby 1.8.7 and 1.9.2 security patches on our runtimes and pushed to get them upstream. This process lead me to receive commit bit to help maintain security fixes for 1.8.7 and 1.9.2. Over the last few months with help from zzak, I've been figuring out how to work with ruby core as well as proposing policy changes for more transparency. This talk, goes through the steps and mistakes that I learned on how to interact with members of ruby core. We'll remove the opacity around getting contributions upstreamed and how you can have meaningful discussions with the implementers about the language we all know and love. Help us make Ruby better.\n  video_provider: \"youtube\"\n  video_id: \"Vl5ASs3FtRw\"\n\n# Lightning Talks\n\n- id: \"craig-kerstiens-ancient-city-ruby-2014\"\n  title: \"Postgres Performance for Humans\"\n  raw_title: \"Craig Kerstiens - Postgres Performance for Humans - Ancient City Ruby 2014\"\n  speakers:\n    - Craig Kerstiens\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-04\"\n  published_at: \"2015-02-02\"\n  description: |-\n    To many developers the database is a black box. You expect to be able to put data into your database, have it to stay there, and get it out when you query it... hopefully in a performant manner. When its not performant enough the two options are usually add some indexes or throw some hardware at it. We'll walk through a bit of a clearer guide of how you can understand how database is doing from a 30,000 foot perspective as well as analyze specific problematic queries and how to tune them. In particular we'll cover:\n\n    * Postgres Caching\n    * Postgres Indexing\n    * Explain Plans\n    * Extensions\n    * More\n  video_provider: \"youtube\"\n  video_id: \"occqUdd7t4E\"\n\n# Lightning Talks\n\n# Break\n\n- id: \"josh-adams-ancient-city-ruby-2014\"\n  title: \"Introduction to Elixir for Rubyists\"\n  raw_title: \"Josh Adams - Introduction to Elixir for Rubyists - Ancient City Ruby 2014\"\n  speakers:\n    - Josh Adams\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-04\"\n  published_at: \"2015-02-02\"\n  description: |-\n    Elixir is a concurrency-oriented programming language built atop the Erlang VM. Its syntax is very Ruby-influenced, and it takes some great features from the Python world as well. In this talk, I'll provide a quick introduction to the language. I'll provide just a quick overview of the language syntactically, as well as cover some areas where it differs wildly from Ruby.\n  video_provider: \"youtube\"\n  video_id: \"rS5aeUi1sZs\"\n\n# Lunch\n\n- id: \"aaron-patterson-ancient-city-ruby-2014\"\n  title: \"Oh, Oh, Oh, It's Magic!\"\n  raw_title: \"Aaron Patterson - Oh, Oh, Oh, It's Magic! - Ancient City Ruby 2014\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-04\"\n  published_at: \"2015-02-02\"\n  description: |-\n    You know? Let's explore computer vision using Ruby and OpenCV! In this talk, we will learn techniques for speeding up our code, fetching data from the network, and doing image recognition, all in Ruby. Let's harness the power of Sauron's Eye (my webcam) together!\n  video_provider: \"youtube\"\n  video_id: \"csN-NYFba0U\"\n\n# Lightning Talks\n\n- id: \"konstantin-haase-ancient-city-ruby-2014\"\n  title: \"Hack Me If You Can\"\n  raw_title: \"Konstantin Haase - Hack Me If You Can - Ancient City Ruby 2014\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-04\"\n  published_at: \"2015-02-02\"\n  description: |-\n    Security is important. Yet, it's where a lot of web developers have little to no experience. We'll look at a whole range of opportunistic attack vectors that can be used against web applications, and how we can protect us against them.\n\n    This talk will include one currently undisclosed attack (at the time of writing).\n  video_provider: \"youtube\"\n  video_id: \"u_Le8-WsSs8\"\n\n# Sponsor Lightning Talks\n\n# Break\n\n- id: \"evan-machnic-ancient-city-ruby-2014\"\n  title: \"Juggling Children... and Rubies\"\n  raw_title: \"Evan Machnic - Juggling Children... and Rubies - Ancient City Ruby 2014\"\n  speakers:\n    - Evan Machnic\n  event_name: \"Ancient City Ruby 2014\"\n  date: \"2014-04-04\"\n  published_at: \"2015-02-03\"\n  description: |-\n    \"DAD! I'm hungry.\"\n    \"DAD! Can you tie my shoes?\"\n    \"HONEY! The baby needs a diaper change.\"\n\n    How do you balance all the distractions with raising children and still be able to deliver at your job? As Ruby developers, it's something that many of us can relate to but few really talk openly about. I work full-time at Engine Yard, create videos for Code TV, and also maintain RailsInstaller. All of that needs to balance nicely with my family and this talk will explore some of the problems I've faced and how I address them.\n  video_provider: \"youtube\"\n  video_id: \"F62cJHu53xc\"\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2015/event.yml",
    "content": "---\nid: \"PLrjohaqTgNJOWPOGH3R3ww7AulwmOadr2\"\nlocation: \"St. Augustine, FL, United States\"\ntitle: \"Ancient City Ruby 2015\"\nkind: \"conference\"\ndescription: |-\n  Casa Monica Hotel, St. Augustine, Fla.\npublished_at: \"2015-05-01\"\nstart_date: \"2015-03-25\"\nend_date: \"2015-03-27\"\nchannel_id: \"UCk7lIUwfv3OAWCfk3rreAAg\"\nyear: 2015\nwebsite: \"https://web.archive.org/web/20141218235253/http://www.ancientcityruby.com/\"\nbanner_background: \"#F6F6F6\"\nfeatured_background: \"#F6F6F6\"\nfeatured_color: \"#323232\"\ncoordinates:\n  latitude: 29.8921835\n  longitude: -81.3139313\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2015/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"hampton-catlin-ancient-city-ruby-2015\"\n  title: \"Ruby Survey: 6 Years of Data Revealed\"\n  raw_title: \"Hampton Catlin - Ruby Survey: 6 Years of Data Revealed - Ancient City Ruby 2015\"\n  speakers:\n    - Hampton Catlin\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    For the past 6 years, I’ve run the Ruby Survey (almost) every year. It asks the same questions every year, plus some new ones. It’s goal is to track changes in technology, community, fashions, attitudes, and tooling. This is the first time I’ll ever be fully sharing the data and it should make for an interesting exploration of the past, present, and maybe future of the Ruby ecosystem. Oh, and I’ll probably cuss a lot too.\n  video_provider: \"youtube\"\n  video_id: \"C7nRq25ZJls\"\n\n- id: \"jay-hayes-ancient-city-ruby-2015\"\n  title: \"Rubyist meets Swift\"\n  raw_title: \"Jay Hayes - Rubyist meets Swift - Ancient City Ruby 2015\"\n  speakers:\n    - Jay Hayes\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    There are a lot of reasons I love Ruby. It makes me a happy programmer. Apple recently released its latest programming language into the wild, Swift. Swift is an object oriented-programming language with a functional personality.\n\n    I will give you the whirlwind tour of what I have learned in my dabbling with the language. We will compare constructs in Swift to similar implementations in Ruby and contrast the differences. We’re talking language and syntax here, the good stuff. No need to bring your iOS or Cocoa chops :wink:. Perhaps we have established a trajectory to find happiness developing native applications as well?\n  video_provider: \"youtube\"\n  video_id: \"9oYBf9w40gI\"\n\n- id: \"pamela-vickers-ancient-city-ruby-2015\"\n  title: 'Your Company Culture is \"Awesome\"'\n  raw_title: 'Pamela Vickers - Your Company Culture is \"Awesome\" - Ancient City Ruby 2015'\n  speakers:\n    - Pamela Vickers\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    We all want to work for a company that cares about and promotes a balanced, fun, and, in a word, \"awesome\" culture, but unless a company has safeguards in place against bad clients, bad projects, and bad apples, this great company culture only exists on paper.\n\n        What can we do as developers, team leaders, or mentors to protect ourselves and others from cultural failure? What are successful companies doing to maintain their workers' happiness?\n\n        By examining what a developer needs for professional happiness, this talk will propose a functional, actionable company culture model while exploring the sometimes difficult task of owning your company culture and protecting it when things go wrong.\n  video_provider: \"youtube\"\n  video_id: \"W-gzcfFIv9o\"\n\n- id: \"ben-lovell-ancient-city-ruby-2015\"\n  title: \"RESCUE SQUAD: Rails Edition!\"\n  raw_title: \"Ben Lovell - RESCUE SQUAD: Rails Edition! - Ancient City Ruby 2015\"\n  speakers:\n    - Ben Lovell\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    Have you ever worked on a soul-destroying Rails application? I have! Inconsistent and non-idiomatic code, spaghetti concerns, and terrible, excruciatingly slow tests are just a few of the symptoms you might encounter – with complete developer indifference being the sad consequence.\n\n    As a traveling consultant and software journeyman, I’ve picked up a bunch of hacks along the way to help make the unbearable bearable. Don’t give up hope – this is a job for the rescue squad: RAILS EDITION!\n  video_provider: \"youtube\"\n  video_id: \"SQFIx1K4vyc\"\n\n- id: \"rebecca-poulson-ancient-city-ruby-2015\"\n  title: \"The Junior Jump: from Student to Team Member\"\n  raw_title: \"Rebecca Poulson - The Junior Jump: from Student to Team Member - Ancient City Ruby 2015\"\n  speakers:\n    - Rebecca Poulson\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    Whether you're a student or a CTO, it's worth taking a moment to consider the transition from student to professional. The Junior Jump will explore strategies that will help you become or mentor a confident junior developer. We'll discuss how candidates and employers can use the interview stage to set a foundation for a productive transition, how to figure out what kind of mentorship/pairing model will work best with the resources available at your company and examples of projects that are challenging and appropriate for developers transitioning into their first jobs.\n\n    I'll draw on my own experience working on the DMCA claim system at Kickstarter, as well as interviews with experienced software leads and developers currently in their first jobs. We will hear anecdotes from developers from university, bootcamp and self-taught backgrounds and as well as engineers experienced in mentoring junior devs at very diverse companies.\n  video_provider: \"youtube\"\n  video_id: \"3Qc6x8DMe74\"\n\n- id: \"laura-frank-ancient-city-ruby-2015\"\n  title: \"Containerized Ruby Applications with Docker\"\n  raw_title: \"Laura Frank - Containerized Ruby Applications with Docker - Ancient City Ruby 2015\"\n  speakers:\n    - Laura Frank\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    Docker’s lightweight virtualization may supplant our hypervisor-backed VMs at some point in the future, and change the way that tomorrow's Ruby applications are architected, packaged and deployed. Using Docker, your Ruby applications will sit atop an excellent platform for packing, shipping and running low-overhead, isolated execution environments. You will get a brief intro to the Docker ecosystem, get to know the tools and processes needed to create containerized Ruby applications, and learn best practices for interacting with the Docker API from Ruby.\n  video_provider: \"youtube\"\n  video_id: \"CIn7U8dayFE\"\n\n- id: \"ernie-miller-ancient-city-ruby-2015\"\n  title: \"Ruby after Rails\"\n  raw_title: \"Ernie Miller - Ruby after Rails - Ancient City Ruby 2015\"\n  speakers:\n    - Ernie Miller\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    What happens to Ruby when Rails dies?\n\n    Ruby rode the Rails rocketship to worldwide renown. While a handful of developers were writing Ruby code before Rails came along, many (if not most) of us owe Rails a debt of gratitude for taking Ruby mainstream, thus allowing us to make a living writing code in a language we love.\n\n    However, the application design preferences expressed by Rails are falling out of favor. Our apps have more complex domain logic that becomes burdensome to manage by following \"The Rails Way.\"\n\n    Is that it, then? Does transitioning from Rails mean leaving Ruby behind?\n\n    WHY?\n\n    If we're being honest, I think it's fair to say that all of us have thought about this at one point in the past year or two, or maybe before. Whether while we're cursing the mess we got ourselves into with ActiveRecord callback spaghetti or complicated modeling brought on by the predisposition to make everything in app/models a subclass of ActveRecord::Base, we think \"this just isn't fun anymore. What happened to the programmer happiness I felt when things were simpler?\"\n\n    But I strongly believe that even in a world where it's said that every programming language needs a \"concurrency story\" and functional programming is on the rise, there's room for Ruby. It's certainly not a language I want to stop writing any time soon, even if only as part of a larger whole.\n\n    There's no easy answer to the question posed at the start of the talk description, so don't watch this talk expecting to hear one. Instead, expect to be prompted to think critically about the way you view yourself as a programmer, and what that means for your life and career.\n  video_provider: \"youtube\"\n  video_id: \"IY6gx6wHdSY\"\n\n- id: \"romeeka-gayhart-ancient-city-ruby-2015\"\n  title: \"3D Printing, Ruby and Solar Panels\"\n  raw_title: \"Romeeka Gayhart - 3D Printing, Ruby and Solar Panels - Ancient City Ruby 2015\"\n  speakers:\n    - Romeeka Gayhart\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    Did you know that SketchUp has a Ruby API? Did you know that you can use SketchUp to do all kinds of things, including designing 3D printing templates? In her past career in the solar energy field, Meeka Gayhart used SketchUp for doing renderings and shading calculations for solar arrays. Come learn about how easy SketchUp is to use, and how to create your own drawing and design tools.\n  video_provider: \"youtube\"\n  video_id: \"lSIR_ESh2Y8\"\n\n- id: \"noel-rappin-ancient-city-ruby-2015\"\n  title: \"Estimation and Trust-Driven Development\"\n  raw_title: \"Noel Rappin - Estimation and Trust-Driven Development - Ancient City Ruby 2015\"\n  speakers:\n    - Noel Rappin\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    ** We apologize for technical difficulties - This video starts a bit into Noel's talk. ** \n\n    What makes some projects succeed and others fail? Often the problem is that the stakeholders in your project have stopped trusting one another. The root of this problem is not always technical, but can be that your team has structured its workflow in a way that is making your life more difficult and making it hard for stakeholders to understand and accept your progress.\n\n    As developers, we tend to dismiss project process as a \"soft skill\", right up until the moment you hit a deadline and realize you needed a better structure in place six weeks ago. Estimation is a particularly fraught process, and tension between developers and stakeholders will often manifest there first.\n\n    You may think that ugly project management is a fact of life and there's nothing you can do about it, but that's just not true. Agile processes are filled with small ways you can increase trust and improve the way your team works.\n  video_provider: \"youtube\"\n  video_id: \"6igUkv7vGZw\"\n\n- id: \"carlos-souza-ancient-city-ruby-2015\"\n  title: \"Building Better Web APIs with Rails\"\n  raw_title: \"Carlos Souza - Building Better Web APIs with Rails - Ancient City Ruby 2015\"\n  speakers:\n    - Carlos Souza\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    At some point every Rails developer needs to build an API, but what's the best way to do it and avoid the mess many run into when serving multiple client applications?\n\n    In this session, we'll go over how to use Rails to leverage the HTTP protocol and build rock-solid web APIs. This includes fine-tuning route endpoints, content negotiation, versioning and authentication. We will also review common practices for keeping your code organized, clean and testable.\n  video_provider: \"youtube\"\n  video_id: \"CDC7zA8a-mA\"\n\n- id: \"scott-parker-ancient-city-ruby-2015\"\n  title: \"Ancient Rails\"\n  raw_title: \"Scott Parker - Ancient Rails - Ancient City Ruby 2015\"\n  speakers:\n    - Scott Parker\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    As Rails enters its tweens, “legacy Rails” projects are increasingly common. Even if you haven’t dealt with such projects, every line of code we leave in production is destined to become legacy code.\n\n        As developers, our everyday decisions make it easier or harder to work in a codebase over time. I’ll share some of the decisions, both wise and unwise, that I’ve made or encountered in five years of working with aged Rails codebases. With just a bit of forethought, your Rails projects won’t be “aged” or “legacy” - they’ll be timeless.\n  video_provider: \"youtube\"\n  video_id: \"3TXcsRa8s_M\"\n\n- id: \"kerri-miller-ancient-city-ruby-2015\"\n  title: \"Beyond Good and ORMs\"\n  raw_title: \"Kerri Miller - Beyond Good and ORMs - Ancient City Ruby 2015\"\n  speakers:\n    - Kerri Miller\n  event_name: \"Ancient City Ruby 2015\"\n  date: \"2015-03-25\"\n  published_at: \"2015-06-08\"\n  description: |-\n    ORMs such as ActiveRecord or DataMapper are fabulous tools that have improved the speed at which we're able to develop working, shippable products. As DSLs for working with our persistence layers, they've proven their worth time and time again, but at the cost of stunting our collective knowledge about the built-in, powerful features that different databases have to offer. Let's take a look at some of those features, rediscover what we've left behind by accepting abstraction, and recover some tools that can help ensure the long-term health of our applications.\n  video_provider: \"youtube\"\n  video_id: \"0P859YkecpM\"\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2016/event.yml",
    "content": "---\nid: \"PLrjohaqTgNJPq3h7UGYbqNwrerEM05t_Q\"\nlocation: \"St. Augustine, FL, United States\"\ntitle: \"Ancient City Ruby 2016\"\nkind: \"conference\"\ndescription: |-\n  APRIL 6-8, 2016ST. AUGUSTINE, FL\nstart_date: \"2016-04-06\"\nend_date: \"2016-04-08\"\npublished_at: \"2016-04-14\"\nchannel_id: \"UCk7lIUwfv3OAWCfk3rreAAg\"\nyear: 2016\nwebsite: \"https://web.archive.org/web/20160324224513/http://www.ancientcityruby.com/\"\nbanner_background: |-\n  linear-gradient(to bottom, #BCFDF3 14%, #B7A632 14%, #B7A632 16%, #BCFDF3 16%, #BCFDF3 90%, #52F8D1 90%) left top / 50% 100% no-repeat, /* Left side */\n  linear-gradient(to bottom, #BCFDF3 14%, #B7A632 14%, #B7A632 16%, #BCFDF3 16%, #BCFDF3 90%, #52F8D1 90%) right top / 50% 100% no-repeat /* Right side */\nfeatured_background: \"#BCFDF3\"\nfeatured_color: \"#333333\"\ncoordinates:\n  latitude: 29.8921835\n  longitude: -81.3139313\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2016/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"sam-phippen-ancient-city-ruby-2016\"\n  title: \"What is Processor?\"\n  raw_title: \"Sam Phippen - What is Processor? - Ancient City Ruby 2016\"\n  speakers:\n    - Sam Phippen\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    Sometimes, writing Rails apps is awful. Do you know what's nearly always more awful? Handrolling assembly. Ruby lets us not think about how the processor works, but we're programmers. We're uniquely positioned to intellectually appreciate the wonderful, complex, engineering that goes into a processor.\n\n    In this talk, you’ll learn a little more about what it means for Ruby to be an “interpreted” language, how a processor executes programs, and what magical tricks processor designers use to make our programs go faster with every generation. If you’ve ever written a Ruby program, and understand that a computer has a processor in it, this talk is probably for you.\n  video_provider: \"youtube\"\n  video_id: \"rYOOTksanoU\"\n\n- id: \"ross-kaffenberger-ancient-city-ruby-2016\"\n  title: \"Enumberable's Ugly Cousin\"\n  raw_title: \"Ross Kaffenberger - Enumberable's Ugly Cousin - Ancient City Ruby 2016\"\n  speakers:\n    - Ross Kaffenberger\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    Everyone loves Ruby's Enumerable module. What about Enumerator? Many of us don't what Enumerator is or why it's useful. It's time to change that. We'll (finally?) understand why Enumerator is important and unveil the \"magic\" of how it works. After learning how to get started with Enumerator, we'll build up to some diverse use cases, including web crawlers and recurring events. We'll jump from crazy ideas, like emulating lazy sequences more common in functional programming languages, to sane takeaways for more common problems.\n\n    Even if you've been programming Ruby for years, you may see something new or, at least, see a familiar problem with a fresh perspective. Every if you don't adopt Enumerator into your daily work, you'll come away with a deeper understanding of its advantages and how it complements its famous relative.\n  video_provider: \"youtube\"\n  video_id: \"xXdl0KAPk9U\"\n\n- id: \"lauren-scott-ancient-city-ruby-2016\"\n  title: \"Shall I Compare Thee to a Line of Code\"\n  raw_title: \"Lauren Scott - Shall I Compare Thee to a Line of Code - Ancient City Ruby 2016\"\n  speakers:\n    - Lauren Scott\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    Ever wish that your peers called your code a \"work of art\"? What is it that artful programmers know that makes their work transcend functionality and become something that has value in its essence? There's a lot that we can learn from the arts, particularly from those that share our linguistic building blocks. Because as all programmers and poets know, writing is easy—it’s writing the good stuff that’s hard.\n\n    So what can we take from the study of poetry that would illuminate our own paths as developers? In this talk, I’ll go through some poetic principles that clarify ideas about software development, both in the way we write our code and the way we grow as creators and teammates. We’ll explore the way poets learn to shape their craft and see what we can steal to help our code level up from functioning to poetic.\n  video_provider: \"youtube\"\n  video_id: \"RRRsV10XdO0\"\n\n- id: \"paolo-nusco-perrotta-ancient-city-ruby-2016\"\n  title: \"Unconventional Computing\"\n  raw_title: \"Paolo Perrotta - Unconventional Computing - Ancient City Ruby 2016\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    Our computers have taken us to a dead end. We can't make them faster than they are. It may be time to go back to the drawing board and challenge the notion of what a computer should be like. What about computers made of light, fluid, or living beings?\n\n    Believe it or not, people are actually trying all of those ideas - and more. Let's make a sightseeing tour through the most unexpected and crazy approaches to computing.\n  video_provider: \"youtube\"\n  video_id: \"dtycLHNpNMk\"\n\n- id: \"ben-lovell-ancient-city-ruby-2016\"\n  title: \"FOSS like a Boss!\"\n  raw_title: \"Ben Lovell - FOSS like a Boss! - Ancient City Ruby 2016\"\n  speakers:\n    - Ben Lovell\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    For some, open source software is a way of life. For others it's a dark and scary place -- full of fear, uncertainty and doubt. The hard reality is: nobody truly knows what they're doing and we're all just one teeny step from getting rumbled.\n\n    Let's explore what it takes to contribute to popular open source software and dispel the myths. By the end of the talk I guarantee you'll be throwing pull requests like a BOSS or your money back! (OK, maybe not that money part)\n  video_provider: \"youtube\"\n  video_id: \"KxrOK71wDPo\"\n\n- id: \"seth-vargo-ancient-city-ruby-2016\"\n  title: \"Easy Ruby Development and Deployment with Otto\"\n  raw_title: \"Seth Vargo - Easy Ruby Development and Deployment with Otto - Ancient City Ruby 2016\"\n  speakers:\n    - Seth Vargo\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    Ruby is amazing, but it isn't always the easiest tool to get set up for local development. Vagrant continues to be a great tool for automated and reproducible development environments, but it often falls short of real production scenarios. Otto, the successor to Vagrant, encompasses the entire workflow managing local development environments, infrastructure creation, and application deployment in just three easy commands. You can have the Heroku-like workflow while maintaining full control over the stack, without all the overhead. Come meet Otto!\n\n    More and more, organizations desire extended control over their full stack. From development to production, controlling the entire stack ensures parity, reduces bugs in production, and ultimately makes for happier developers :). With Otto, you can say goodbye to staging/qa/testing environments because any user can easily create all the required infrastructure in a single command. This saves on infrastructure costs, maintenance, and makes for an amazing disaster recovery story!\n\n    Following the story of a fictitious Ruby app, I will deploy their application to AWS in just a two commands in live-demo format. Otto has codified knowledge of today's best practices for deploying applications, so even with no operational experience, a developer can create and manage infrastructure using today's best practices. Otto brings the \"Heroku-like\" workflow to the command line, but you control the entire stack from top to bottom!\n\n    After each phase, we will \"uncover the magic\", digging into the commands Otto is running, the decisions Otto is making, and the various customizations that can be injected along the way.\n  video_provider: \"youtube\"\n  video_id: \"Ym3wn5LG824\"\n\n- id: \"steve-klabnik-ancient-city-ruby-2016\"\n  title: \"Using Rust with Ruby\"\n  raw_title: \"Steve Klabnik - Using Rust with Ruby - Ancient City Ruby 2016\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    Ruby is a wonderful language, but sometimes, you need a little extra oomph. While C extensions are a great way to improve performance-sensitive parts of your application, you can use other languages too. In this talk, Steve will show off the Rust programming language and how to integrate it with Ruby. Rust is a systems language focused on safety, speed, and concurrency, and compliments Ruby nicely.\n  video_provider: \"youtube\"\n  video_id: \"Ms3EifxZopg\"\n\n- id: \"robert-jackson-ancient-city-ruby-2016\"\n  title: \"A Rails Developers Intro to Ember\"\n  raw_title: \"Robert Jackson - A Rail's Developers Intro to Ember - Ancient City Ruby 2016\"\n  speakers:\n    - Robert Jackson\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    So you want to make a nice shiny Ember app as your Rails API's main frontend and are not sure where to start? Lets jump into building a new Ember app that utilizes an existing Rails API. We will review project structure, some basic Ember concepts, how you can test your Ember app both independently and against your API server, and more ...\n  video_provider: \"youtube\"\n  video_id: \"fjvNUG_0cjw\"\n\n- id: \"ray-hightower-ancient-city-ruby-2016\"\n  title: \"Get Ready for Parallel Programming, Featuring Parallela\"\n  raw_title: \"Ray Hightower - Get Ready for Parallel Programming, Featuring Parallela - Ancient City Ruby 2016\"\n  speakers:\n    - Ray Hightower\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    Parallella is a single-board computer roughly the size of a credit card or Raspberry Pi. Parallella runs Linux. It has 18 cores (2 ARM, 16 RISC) and you can buy it online for about $150. This talk will explore two questions: (1) How parallel execution differs from serial, and (2) Why we care about parallelism.\n\n    This talk is the sequel to Ray's Parallella talk from 2015. To get a head-start on the subject, check out Part One: http://rayhightower.com/blog/2015/08/22/madison-ruby-and-parallella/.\n  video_provider: \"youtube\"\n  video_id: \"WMo69DShvqk\"\n\n- id: \"cameron-daigle-ancient-city-ruby-2016\"\n  title: \"It's All Just a Game\"\n  raw_title: \"Cameron Daigle - It's All Just a Game - Ancient City Ruby 2016\"\n  speakers:\n    - Cameron Daigle\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    No matter what your day-to-day role, you're going to occasionally find yourself in a meeting: a place where a motley crew of individuals with various skills and alignments gather 'round a table and attempt to accomplish something. Join me as I show you how archetypes used in game theory can help you better understand and interpret the personalities & motivations of the people around that table – maybe that one person who's always starting arguments is just Chaotic Good, after all!\n  video_provider: \"youtube\"\n  video_id: \"IF0rLjwhI-o\"\n\n- id: \"kerri-miller-ancient-city-ruby-2016\"\n  title: \"SOLID 101: A Review for Rubyists\"\n  raw_title: \"Kerri Miller - SOLID 101: A Review for Rubyists - Ancient City Ruby 2016\"\n  speakers:\n    - Kerri Miller\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-04-22\"\n  description: |-\n    SOLID is an acronym that tries to capture the first 5 principles of object-oriented programming and design, as enumerated by Michael Feathers and Robert Martin. Most Rubyists are probably familiar with one or two, but do you know what the rest are? Let's review them, see them in action, and learn how they can help us create maintainable, extensible, and comprehensible software.\n  video_provider: \"youtube\"\n  video_id: \"7U3e1MB_CQg\"\n\n- id: \"sean-griffin-ancient-city-ruby-2016\"\n  title: \"Rails 5 Features You Haven't Heard About\"\n  raw_title: \"[REVISED] Sean Griffin - Rails 5 Features You Haven't Heard About - Ancient City Ruby 2016\"\n  speakers:\n    - Sean Griffin\n  event_name: \"Ancient City Ruby 2016\"\n  date: \"2016-04-06\"\n  published_at: \"2016-07-08\"\n  description: |-\n    We've all heard about Action Cable, Turbolinks 5, and Rails::API. But Rails 5 was almost a thousand commits! They included dozens of minor features, many of which will be huge quality of life improvements if you aren't using WebSockets or Turbolinks.\n\n    This will be a deep look at several of the \"minor\" features of Rails 5. You won't just learn about the features, but you'll learn about why they were added, the reasoning behind them, and the difficulties of adding them from someone directly involved in many of them.\n  video_provider: \"youtube\"\n  video_id: \"OnTzyhwzqtc\"\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2019/event.yml",
    "content": "---\nid: \"PLrjohaqTgNJODBm0-VFsXvUFx1oidLyKa\"\nlocation: \"Jacksonville Beach, FL, United States\"\ntitle: \"Ancient City Ruby 2019\"\nkind: \"conference\"\ndescription: \"\"\nstart_date: \"2019-10-03\"\nend_date: \"2019-10-04\"\npublished_at: \"2019-10-03\"\nchannel_id: \"UCk7lIUwfv3OAWCfk3rreAAg\"\nyear: 2019\nwebsite: \"https://acr.zohobackstage.com/ACR2019\"\nbanner_background: |-\n  linear-gradient(to bottom, #F2E0E0, #F2E0E0 50%, #E6D5D5 50%) left top / 50% 100% no-repeat, /* Left side */\n  linear-gradient(to bottom, #F2E0E0, #F2E0E0 50%, #E6D5D5 50%) right top / 50% 100% no-repeat /* Right side */\nfeatured_background: \"#F2E0E0\"\nfeatured_color: \"#333333\"\ncoordinates:\n  latitude: 30.2893574\n  longitude: -81.389168\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2019/venue.yml",
    "content": "# https://acr.zohobackstage.com/ACR2019#/venue\n---\nname: \"Four Points by Sheraton Jacksonville Beachfront\"\n\naddress:\n  street: \"1 Ocean Blvd\"\n  city: \"Jacksonville Beach\"\n  region: \"Florida\"\n  postal_code: \"32250\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"11 1st St N, Jacksonville Beach, FL 32250, USA\"\n\ncoordinates:\n  latitude: 30.2893574\n  longitude: -81.389168\n\nmaps:\n  google: \"https://maps.google.com/?q=Four+Points+by+Sheraton+Jacksonville+Beachfront,30.2893574,-81.389168\"\n  apple: \"https://maps.apple.com/?q=Four+Points+by+Sheraton+Jacksonville+Beachfront&ll=30.2893574,-81.389168\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=30.2893574&mlon=-81.389168\"\n"
  },
  {
    "path": "data/ancient-city-ruby/ancient-city-ruby-2019/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"robert-mosolgo-ancient-city-ruby-2019\"\n  title: \"Getting Down To Business with GraphQL\"\n  raw_title: \"Robert Mosolgo\"\n  speakers:\n    - Robert Mosolgo\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"69KRSd77Lgc\"\n\n- id: \"jack-christensen-ancient-city-ruby-2019\"\n  title: \"Why Is This So Hard?\"\n  raw_title: \"Jack Christensen\"\n  speakers:\n    - Jack Christensen\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"dxDHfTf2fWs\"\n\n- id: \"jackie-potts-ancient-city-ruby-2019\"\n  title: \"SW Engineering and Mental Health are Not Mutually Exclusive\"\n  raw_title: \"Jackie Potts\"\n  speakers:\n    - Jackie Potts\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"c4zrhsTs_ag\"\n\n- id: \"joe-leo-ancient-city-ruby-2019\"\n  title: \"The Functional Rubyist\"\n  raw_title: \"Joe Leo\"\n  speakers:\n    - Joe Leo\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"XSN67rxmeII\"\n\n- id: \"jamon-holmgren-ancient-city-ruby-2019\"\n  title: \"Seamless GraphQL in Rails and React Native\"\n  raw_title: \"Jamon & Morgan\"\n  speakers:\n    - Jamon Holmgren\n    - Morgan Laco\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"B3shPZFbUh0\"\n\n- id: \"randall-thomas-ancient-city-ruby-2019\"\n  title: \"(UN)Learning Elixir: A self-effacing guide to making fewer mistakes than I did when I started with Elixir\"\n  raw_title: \"Randall Thomas\"\n  speakers:\n    - Randall Thomas\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6IvKG6s30nM\"\n\n- id: \"jake-worth-ancient-city-ruby-2019\"\n  title: \"Functioning in React: A Deep-Dive into useState()\"\n  raw_title: \"Jake Worth\"\n  speakers:\n    - Jake Worth\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"pBxdZ27QMjo\"\n\n- id: \"saimon-sharif-ancient-city-ruby-2019\"\n  title: \"We'll do it live: Underhanded Debugging Tactics\"\n  raw_title: \"Saimon Sharif\"\n  speakers:\n    - Saimon Sharif\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"g8HIFjhakDw\"\n\n- id: \"louisa-barrett-ancient-city-ruby-2019\"\n  title: \"Accessible JavaScript: Keep Your Hands Off My DOM\"\n  raw_title: \"Louisa Barrett\"\n  speakers:\n    - Louisa Barrett\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"KTesxNsCPxw\"\n\n- id: \"damir-svrtan-ancient-city-ruby-2019\"\n  title: \"Surrounded by Microservices\"\n  raw_title: \"Damir Svrtan\"\n  speakers:\n    - Damir Svrtan\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"gApEmNDhxVI\"\n\n- id: \"richard-evans-ancient-city-ruby-2019\"\n  title: \"Developing in React Native with Reactotron\"\n  raw_title: \"Richard Evans\"\n  speakers:\n    - Richard Evans\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"eO6WS4jtbIQ\"\n\n- id: \"jessie-shternshus-ancient-city-ruby-2019\"\n  title: \"Unlearning: The Challenge of Change\"\n  raw_title: \"Jessie Shternshus\"\n  speakers:\n    - Jessie Shternshus\n  event_name: \"Ancient City Ruby 2019\"\n  date: \"2019-10-03\"\n  published_at: \"2020-11-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"wwyjmErnmNg\"\n"
  },
  {
    "path": "data/ancient-city-ruby/series.yml",
    "content": "---\nname: \"Ancient City Ruby\"\nwebsite: \"https://twitter.com/ancientcityruby\"\ntwitter: \"ancientcityruby\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Ancient City Ruby\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"hashrocket\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCk7lIUwfv3OAWCfk3rreAAg\"\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2009-may/event.yml",
    "content": "---\nid: \"arrrrcamp-2009-may\"\ntitle: \"ArrrrCamp 2009 (1st edition)\"\ndescription: \"\"\nlocation: \"Ghent, Belgium\"\nkind: \"conference\"\nstart_date: \"2009-05-08\"\nend_date: \"2009-05-08\"\nwebsite: \"https://web.archive.org/web/20100209045656/http://arrrrcamp.be/editions/1-may-8th-2009\"\nplaylist: \"https://www.arrrrcamp.be/videos\"\ncoordinates:\n  latitude: 51.0499922\n  longitude: 3.7303853\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2009-may/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://arrrrcamp.be/\n# Videos: https://www.arrrrcamp.be/videos/\n---\n[]\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2009-october/event.yml",
    "content": "---\nid: \"arrrrcamp-2009-october\"\ntitle: \"ArrrrCamp 2009 (2nd edition)\"\ndescription: \"\"\nlocation: \"Ghent, Belgium\"\nkind: \"conference\"\nstart_date: \"2009-10-16\"\nend_date: \"2009-10-16\"\nwebsite: \"https://web.archive.org/web/20100208205735/http://arrrrcamp.be/editions/2-october-16th-2009\"\nplaylist: \"https://www.arrrrcamp.be/videos\"\ncoordinates:\n  latitude: 51.0499922\n  longitude: 3.7303853\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2009-october/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://arrrrcamp.be/\n# Videos: https://www.arrrrcamp.be/videos/\n---\n[]\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2010/event.yml",
    "content": "---\nid: \"arrrrcamp-2010\"\ntitle: \"ArrrrCamp 2010\"\ndescription: \"\"\nlocation: \"Ghent, Belgium\"\nkind: \"conference\"\nstart_date: \"2010-04-30\"\nend_date: \"2010-04-30\"\nwebsite: \"https://web.archive.org/web/20100206131340/http://arrrrcamp.be/editions/3\"\nplaylist: \"https://www.arrrrcamp.be/videos\"\ncoordinates:\n  latitude: 51.0499922\n  longitude: 3.7303853\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://arrrrcamp.be/\n# Videos: https://www.arrrrcamp.be/videos/\n---\n[]\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2011/event.yml",
    "content": "---\nid: \"arrrrcamp-2011\"\ntitle: \"ArrrrCamp 2011\"\ndescription: |-\n  A 3-track 10-hour Ruby, Rails and Radiant conference with plenty of good speakers, loads of free rum and a free pirate twist. Ayeee!\nlocation: \"Ghent, Belgium\"\nkind: \"conference\"\nstart_date: \"2011-10-07\"\nend_date: \"2011-10-07\"\nwebsite: \"https://web.archive.org/web/20111116232943/http://arrrrcamp.be/\"\nplaylist: \"https://www.arrrrcamp.be/videos\"\ncoordinates:\n  latitude: 51.0499922\n  longitude: 3.7303853\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://arrrrcamp.be/\n# Videos: https://www.arrrrcamp.be/videos/\n---\n[]\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2012/event.yml",
    "content": "---\nid: \"arrrrcamp-2012\"\ntitle: \"ArrrrCamp 2012\"\ndescription: |-\n  A 2-day, dual track Ruby, Rails and web related conference with plenty of good speakers, loads of free rum and a free pirate twist. Ayeee!\nlocation: \"Ghent, Belgium\"\nkind: \"conference\"\nstart_date: \"2012-10-04\"\nend_date: \"2012-10-05\"\nwebsite: \"https://web.archive.org/web/20120804075845/http://arrrrcamp.be/\"\nplaylist: \"https://www.arrrrcamp.be/videos\"\ncoordinates:\n  latitude: 51.0499922\n  longitude: 3.7303853\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://arrrrcamp.be/\n# Videos: https://www.arrrrcamp.be/videos/\n---\n[]\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2013/event.yml",
    "content": "---\nid: \"arrrrcamp-2013\"\ntitle: \"ArrrrCamp 2013\"\ndescription: |-\n  A 2-day, dual track Ruby, Rails and web related conference with plenty of good speakers, loads of free rum and a free pirate twist. Ayeee!\nlocation: \"Ghent, Belgium\"\nkind: \"conference\"\nstart_date: \"2013-10-03\"\nend_date: \"2013-10-04\"\nwebsite: \"https://web.archive.org/web/20130806111423/http://arrrrcamp.be/\"\nplaylist: \"https://www.arrrrcamp.be/videos\"\ncoordinates:\n  latitude: 51.0499922\n  longitude: 3.7303853\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://arrrrcamp.be/\n# Videos: https://www.arrrrcamp.be/videos/\n---\n[]\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2014/event.yml",
    "content": "---\nid: \"arrrrcamp-2014\"\ntitle: \"ArrrrCamp 2014\"\ndescription: |-\n  ArrrrCamp is a conference for the modern developer interested in Ruby, Rails or the industry in general. Our event will inspire you, help you learn new things, meet new people and hang out with old friends.\nlocation: \"Ghent, Belgium\"\nkind: \"conference\"\nstart_date: \"2014-10-02\"\nend_date: \"2014-10-03\"\nwebsite: \"https://web.archive.org/web/20140805145641/http://2014.arrrrcamp.be/\"\noriginal_website: \"https://2014.arrrrcamp.be\"\nplaylist: \"https://www.arrrrcamp.be/videos\"\ncoordinates:\n  latitude: 51.0499922\n  longitude: 3.7303853\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://arrrrcamp.be/\n# Videos: https://www.arrrrcamp.be/videos/\n---\n[]\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcya1ZncJ8Ou7zI0xzggyBRtW\"\ntitle: \"ArrrrCamp 2015\"\nkind: \"conference\"\nlocation: \"Ghent, Belgium\"\ndescription: |-\n  ArrrrCamp is a conference with a pirate twist for the modern developer into Ruby, Rails or the industry in general. 2015 edition is on the 1st & 2nd of October.\npublished_at: \"2015-12-02\"\nstart_date: \"2015-10-01\"\nend_date: \"2015-10-02\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://web.archive.org/web/20150905172254/http://2015.arrrrcamp.be/\"\noriginal_website: \"https://2015.arrrrcamp.be\"\ncoordinates:\n  latitude: 51.0499922\n  longitude: 3.7303853\n"
  },
  {
    "path": "data/arrrrcamp/arrrrcamp-2015/videos.yml",
    "content": "---\n# Website: https://www.arrrrcamp.be\n# Schedule: https://www.arrrrcamp.be/schedule\n\n## Day 1 - Thursday\n\n# Dorrs & Registration\n\n- id: \"sam-phippen-arrrrcamp-2015\"\n  title: \"Extremely Defensive Coding\"\n  raw_title: \"ArrrrCamp 2015 - Extremely Defensive Coding by Sam Phippen\"\n  speakers:\n    - Sam Phippen\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-01\"\n  description: |-\n    Defensive programming is one of those abstract ideas that seems great. We all want to use these ideas to ensure the long-term maintainability of our codebases. It is, however, often unclear what we should be defending against and what form those defenses should take. We can find places where defensive patterns could be added by looking at the edge cases that occur in our system. Where it seems appropriate, we can then apply ideas and patterns from defensive programming. In this talk we'll look at some of the extremely defensive patterns that have been driven out in RSpec throughout the years. We'll look at building Ruby that works accross a wide range of interpreters and versions (including 1.8.7!). We'll investigate how you can write code that defends against objects that redefine methods like send, method and is_a?. We'll also see how the behaviour of prepend can occasionally confuse even the most mature source bases. You should come to this talk if you want to learn about inheritence and method resolution in Ruby, defensive programming techniques and cross interpreter Ruby patterns.\n\n  video_provider: \"youtube\"\n  video_id: \"gr45bkXv-JQ\"\n  published_at: \"2015-12-03\"\n\n- id: \"florian-weingarten-arrrrcamp-2015\"\n  title: \"How to stay alive even when others go down: Writing and testing resilient applications in Ruby\"\n  raw_title: \"ArrrrCamp 2015 - How to stay alive even when others go down:...\"\n  speakers:\n    - Florian Weingarten\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-01\"\n  description: |-\n    By Florian Weingarten \n    Your application probably communicates with other services, whether it's a database, a key/value store, or a third-party API: you are performing \"external calls\". But do you know how your application behaves when one of those external services is behaving unexpected, is unreachable, or sometimes even worse, experiences high latency? This is something that you want to find out during testing, not in production, since it can easily lead to a series of cascading failures that will seriously affect your capacity or can even take your application down. Shopify operates one of the largest Ruby on Rails deployments in the world. We serve about 300k requests per minute on a boring day, integrating with countless external services. Focussing on Resiliency has been one of the most impactful improvements that we made in terms of uptime in the last year. In this talk, I will share some lessons learnt and we will walk through a series of ideas and tools that can help you make your application more stable and more resilient to the failure of external services, an issue that is often neglected until it's too late. More importantly, we will talk about how you can write meaningful and realistic integration tests and set up \"chaos testing environments\" to gain confidence in your application's resiliency.\n  video_provider: \"youtube\"\n  video_id: \"mTIO9fj1UIc\"\n  published_at: \"2015-12-03\"\n\n- id: \"laura-frank-arrrrcamp-2015\"\n  title: \"Developing Ruby Applications with Docker\"\n  raw_title: \"ArrrrCamp 2015 - Developing Ruby Applications with Docker by  Laura Frank\"\n  speakers:\n    - Laura Frank\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-01\"\n  description: |-\n    Docker’s lightweight virtualization may supplant our hypervisor-backed VMs at some point in the future, and change the way that tomorrow's Ruby applications are architected, packaged and deployed. Using Docker, your applications will sit atop an excellent platform for packing, shipping and running low-overhead, isolated execution environments. You will get a brief intro to the Docker ecosystem, get to know the tools and processes needed to create containerized applications, and learn best practices for interacting with the Docker API and CLI.\n\n  video_provider: \"youtube\"\n  video_id: \"hiiPMgZbzcA\"\n  published_at: \"2015-12-03\"\n\n# Lunch\n\n- id: \"jason-clark-arrrrcamp-2015\"\n  title: \"Peeking into Ruby: Tracing Running Code\"\n  raw_title: \"ArrrrCamp 2015 - Peeking into Ruby: Tracing Running Code by Jason Clark\"\n  speakers:\n    - Jason Clark\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-01\"\n  description: |-\n    Your Ruby app is in production, but something isn't quite right. It worked locally, it passed CI... yet the running app is acting up. Sounds familiar? You're in luck! Multiple tools exist for grappling with a running Ruby app. This talk will introduce a variety of tools and techniques for peeking into what your Ruby app is doing.\n\n  video_provider: \"youtube\"\n  video_id: \"SBtJ7da_rA8\"\n  published_at: \"2015-12-03\"\n\n- id: \"tienne-barri-arrrrcamp-2015\"\n  title: \"Ruby keyword args and the options hash, from the parser to the virtual machine\"\n  raw_title: \"ArrrrCamp 2015 - Ruby keyword args and the options hash, from the parser to the virtual machine\"\n  speakers:\n    - Étienne Barrié\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-01\"\n  description: |-\n    By Étienne Barrié\n    Ruby has slowly but surely added support for keyword arguments. Starting from the implicit braces for a hash at the end of an argument list, it has grown up to required keyword arguments in 2.1. This talk will try to convince you that keyword arguments are a lie and don't even exist, and why you should use them anyway.\n\n  video_provider: \"youtube\"\n  video_id: \"e4t9dts_07g\"\n  published_at: \"2015-12-03\"\n\n- id: \"lightning-talks-day-1-arrrrcamp-2015\"\n  title: \"Lightning Talks (Day 1)\"\n  raw_title: \"ArrrrCamp 2015 - Day 1 LIGHTNING TALKS\"\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3r2bJ5OYQ1o\"\n  published_at: \"2015-12-04\"\n  talks:\n    - title: \"Lighting Talk: Walking\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-01\"\n      start_cue: \"00:20\"\n      end_cue: \"06:48\"\n      id: \"yves-hanoulle-walking-arrrrcamp-2015\"\n      video_id: \"yves-hanoulle-walking-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Yves Hanoulle\n\n    - title: \"Lighting Talk: Code Bashing in the Enterprise / How Teenagers Force Us To Have Technology That Scales\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-01\"\n      start_cue: \"06:48\"\n      end_cue: \"12:30\"\n      id: \"michel-grootjans-lightning-talk-arrrrcamp-2015\"\n      video_id: \"michel-grootjans-lightning-talk-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Michel Grootjans\n\n    - title: \"Lighting Talk: WebRTC with Twilio\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-01\"\n      start_cue: \"12:30\"\n      end_cue: \"18:24\"\n      id: \"phil-nash-webrtc-with-twilio-arrrrcamp-2015\"\n      video_id: \"phil-nash-webrtc-with-twilio-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Phil Nash\n\n    - title: \"Lighting Talk: Ruby Belgium\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-01\"\n      start_cue: \"18:24\"\n      end_cue: \"24:23\"\n      id: \"christophe-philemotte-ruby-belgium-arrrrcamp-2015\"\n      video_id: \"christophe-philemotte-ruby-belgium-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Christophe Philemotte\n\n- id: \"carina-c-zona-arrrrcamp-2015\"\n  title: \"Consequences of an Insightful Algorithm\"\n  raw_title: \"ArrrrCamp 2015 - Consequences of an Insightful Algorithm by Carina C. Zona\"\n  speakers:\n    - Carina C. Zona\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-01\"\n  description: |-\n    We have ethical responsibilities when coding. We're able to extract remarkably precise intuitions about an individual. But do we have a right to know what they didn't consent to share, even when they willingly shared the data that leads us there? A major retailer's data-driven marketing accidentially revealed to a teen's family that she was pregnant. Eek. What are our obligations to people who did not expect themselves to be so intimately known without sharing directly? How do we mitigate against unintended outcomes? For instance, a social network algorithm accidentally triggering painful memories for families grieving their child's death. We design software for humans. Balancing human needs and business specs can be tough. It's crucial that we learn how to build in systematic empathy. In this talk, we'll delve into specific examples of uncritical programming, and painful results from using insightful data in ways that were benignly intended. You'll learn ways we can integrate practices for examining how our code might harm individuals. We'll look at how to flip the paradigm, netting consequences that can be better for everyone.\n\n  video_provider: \"youtube\"\n  video_id: \"roSxrWNgwgc\"\n  published_at: \"2015-12-03\"\n\n## Day 2 - Friday\n\n# Doors & Registration\n\n- id: \"wesley-beary-arrrrcamp-2015\"\n  title: \"API by Design\"\n  raw_title: \"ArrrrCamp 2015 - API by Design by Wesley Beary\"\n  speakers:\n    - Wesley Beary\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-02\"\n  description: |-\n    In a world of pervasive connectivity, APIs are more important than ever before. We can learn much from the rich history of APIs, but even more promise lies ahead of us. Difficult hardly begins to describe API development, but drawing from other disciplines provides a clearer path to superior APIs. Building and evolving the Heroku APIs has been full of epic wins, tragic fails and ongoing struggles. Learn about our journey and join our community to discuss, document, and build tools to realize the promise of a brighter API future.\n  video_provider: \"youtube\"\n  video_id: \"xTYz7TDs5hA\"\n  published_at: \"2015-12-04\"\n\n- id: \"andy-pike-arrrrcamp-2015\"\n  title: \"Opening up to Change\"\n  raw_title: \"ArrrrCamp 2015 - Opening up to change by Andy Pike\"\n  speakers:\n    - Andy Pike\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-02\"\n  description: |-\n    The one constant in software is change. Your code will need to change and adapt over time. We should try to write code that is easy to change in the future. If possible, change without having to edit existing code. This talk is all about the O in SOLID: the Open-Closed principle. I'll explain what the Open-Closed principle is, why this is important and how to structure and refactor code to make it \"open for extension but closed for modification\". In this talk I'll show you, by example, how to make your code more changeable. In fact, so changeable that you will be able to extend what your program does and how it behaves without modifying a single line of existing code. Starting with a real world example that is painful to extend, I’ll refactor it over many iterations until it truly is Open-Closed. I'll show techniques, trade-offs and some gotchas from real world experience which will help you write more flexible programs in the future. If you’ve never heard of the Open-Closed principle or are unsure how to put it into practice then this talk is for you. I would love to help open the door of this technique and give you the ability to alter your system in a painless way by opening it up to change.\n\n  video_provider: \"youtube\"\n  video_id: \"ECCaFvFDfJQ\"\n  published_at: \"2015-12-04\"\n\n- id: \"alexandra-leisse-arrrrcamp-2015\"\n  title: \"Developers, Start Designing!\"\n  raw_title: \"ArrrrCamp 2015 - Developers, start designing! by Alexandra Leisse\"\n  speakers:\n    - Alexandra Leisse\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-02\"\n  description: |-\n    We designers have been told for ages to learn how to program because we needed to know the technology. On the other hand, very few developers bother doing the same with design. This usually leads to worse results than necessary, and robs us of the opportunity to play on the same team. This presentation is meant to contribute to the much needed discussion about how developers and designers can work together to achieve excellence without losing their minds. Attendees should leave the room afterwards with a certain insight in how ignorance hinders best outcomes and how they personally can improve the situation.\n\n  video_provider: \"youtube\"\n  video_id: \"7EWvYZpU4pM\"\n  published_at: \"2015-12-04\"\n\n# Lunch\n\n- id: \"jain-rishi-arrrrcamp-2015\"\n  title: \"Game Development - The Ruby Way\"\n  raw_title: \"ArrrrCamp 2015 - Game Development - The Ruby way by Jain Rishi\"\n  speakers:\n    - Jain Rishi\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-02\"\n  description: |-\n    Playing games is fun, but building one is even more fun! Add Ruby to the game development mix and it just cannot get more awesome. Gosu is the rock star library which is used for 2D game development. But you’ll need to know more than just your rubies to built a game. Rishi promises to show some cool examples built entirely using Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"BqXU2JwMGBE\"\n  published_at: \"2015-12-04\"\n\n- id: \"kerstin-puschke-arrrrcamp-2015\"\n  title: \"Decouple All The Things: Asynchronous Messaging Keeps It Simple\"\n  raw_title: \"ArrrrCamp 2015 - Decouple all the things: Asynchronous messaging keeps it simple by Kerstin Puschke\"\n  speakers:\n    - Kerstin Puschke\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-02\"\n  description: |-\n    If a customer changes their address, it's often not enough to update their master data record. E.g. the component processing customer orders might have to learn about the update in order to ship to the correct address. In a distributed architecture, you have to spread information about a master data update to several client apps. You can do this via REST, but if a client app is temporarily down or too busy to accept requests, it's going to miss the information. Adding a new client app requires changes to the master app. Asynchronous messaging helps to avoid such a tight coupling of components. And it offers much more than a simple action trigger: parallelizing computing-heavy tasks, load testing, or migrating existing components to new services are some of the possibilities explored in this talk. You're going to learn how to get started with asynchronous messaging from within Ruby, and how it helps you to keep your codebase clean and your overall system stable as well as maintainable.\n\n  video_provider: \"youtube\"\n  video_id: \"G4_AnaVsBh0\"\n  published_at: \"2015-12-04\"\n\n# Cocktail Break\n\n- id: \"lightning-talks-day-2-arrrrcamp-2015\"\n  title: \"Lightning Talks (Day 2)\"\n  raw_title: \"ArrrrCamp 2015 LIGHTNING TALKS Day2\"\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"WtoTlfJAIAc\"\n  published_at: \"2015-12-04\"\n  talks:\n    - title: \"Lightning Talk: Ruby Open Source Software - ROSSConf\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-02\"\n      start_cue: \"00:08\"\n      end_cue: \"05:04\"\n      id: \"sebastian-graessl-rossconf-arrrrcamp-2015\"\n      video_id: \"sebastian-graessl-rossconf-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Sebastian Gräßl\n\n    - title: \"Lightning Talk: KampAdmin.be - CoderDojo\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-02\"\n      start_cue: \"05:04\"\n      end_cue: \"10:04\"\n      id: \"pieterjan-muller-kampadmin-arrrrcamp-2015\"\n      video_id: \"pieterjan-muller-kampadmin-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Pieterjan Muller\n\n    - title: \"Lightning Talk: Ruby Issues Newsletter\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-02\"\n      start_cue: \"10:04\"\n      end_cue: \"14:22\"\n      id: \"sonja-heinen-ruby-issues-arrrrcamp-2015\"\n      video_id: \"sonja-heinen-ruby-issues-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Sonja Heinen\n\n    - title: \"Lightning Talk: How To Write Music in Ruby\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-02\"\n      start_cue: \"14:22\"\n      end_cue: \"20:33\"\n      id: \"anika-simir-music-ruby-arrrrcamp-2015\"\n      video_id: \"anika-simir-music-ruby-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Anika Simir\n\n    - title: \"Lightning Talk: Ruby TracePoint\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-02\"\n      start_cue: \"20:33\"\n      end_cue: \"24:13\"\n      id: \"christophe-philemotte-tracepoint-arrrrcamp-2015\"\n      video_id: \"christophe-philemotte-tracepoint-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Christophe Philemotte\n\n    - title: \"Lightning Talk: RubyCamp BE\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-02\"\n      start_cue: \"24:13\"\n      end_cue: \"28:45\"\n      id: \"joren-de-groof-rubycamp-arrrrcamp-2015\"\n      video_id: \"joren-de-groof-rubycamp-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Joren De Groof\n\n    - title: \"Lightning Talk: God, Toilets And Ruby\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-02\"\n      start_cue: \"28:45\"\n      end_cue: \"34:26\"\n      id: \"sebastian-eichner-god-toilets-ruby-arrrrcamp-2015\"\n      video_id: \"sebastian-eichner-god-toilets-ruby-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Sebastian Eichner\n\n    - title: \"Lightning Talk: Shoes 4\"\n      event_name: \"ArrrrCamp 2015\"\n      date: \"2015-10-02\"\n      start_cue: \"34:26\"\n      end_cue: \"39:50\"\n      id: \"jason-clark-shoes-4-arrrrcamp-2015\"\n      video_id: \"jason-clark-shoes-4-arrrrcamp-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Jason Clark\n\n- id: \"rachel-myers-arrrrcamp-2015\"\n  title: \"Stop Building Services, Episode 1: The Phantom Menace\"\n  raw_title: \"ArrrrCamp 2015 - Stop Building Services, Episode 1: The Phantom Menace by Rachel Myers\"\n  speakers:\n    - Rachel Myers\n  event_name: \"ArrrrCamp 2015\"\n  date: \"2015-10-02\"\n  description: |-\n    This talk runs through examples of services creating more brittle systems with worse failure cases. Building on those failure scenarios, I draw out guidelines for if, when, and how to consider Service Oriented Architecture. Software architecture is informed both by principles of software design and principles of operability; for lots of us, there are new skills to learn there. Also, set to music, this talk becomes a cool remake of StarWars, Episode 1.\n\n  video_provider: \"youtube\"\n  video_id: \"qiC9OAculcc\"\n  published_at: \"2015-12-04\"\n"
  },
  {
    "path": "data/arrrrcamp/series.yml",
    "content": "---\nname: \"ArrrrCamp\"\nwebsite: \"https://arrrrcamp.be\"\ntwitter: \"arrrrcamp\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"ArrrrCamp\"\ndefault_country_code: \"BE\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/artificialruby/artificialruby/event.yml",
    "content": "---\nid: \"artificialruby\"\ntitle: \"ArtificialRuby.ai Meetup\"\nkind: \"meetup\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  Artificial Ruby is a community of Rubyists who meet regularly in NYC to explore novel approaches to AI development using Ruby. Our mission is to ensure the Ruby mindset and approach to software development is represented in this new generation of AI applications, and provide a place for Rubyists to gather, share what they're building, and learn from each other.\n\n  Join our monthly meetups for workshops, talks, and hanging out with other Rubyists interested in defining our role in AI.\nbanner_background: \"#F9F1E6\"\nfeatured_background: \"#F9F1E6\"\nfeatured_color: \"#383F48\"\nwebsite: \"https://www.artificialruby.ai\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/artificialruby/artificialruby/videos.yml",
    "content": "---\n- id: \"artificial-ruby-meetup-april-2025\"\n  title: \"ArtificialRuby.ai Meetup April 2025\"\n  raw_title: \"ArtificialRuby.ai NYC Meetup\"\n  video_id: \"artificial-ruby-meetup-april-2025\"\n  video_provider: \"children\"\n  date: \"2025-04-09\"\n  published_at: \"2025-04-16\"\n  thumbnail_xs: \"https://www.artificialruby.ai/assets/images/events/april_9_2025/11-IMG_9773.jpg\"\n  thumbnail_sm: \"https://www.artificialruby.ai/assets/images/events/april_9_2025/11-IMG_9773.jpg\"\n  thumbnail_md: \"https://www.artificialruby.ai/assets/images/events/april_9_2025/11-IMG_9773.jpg\"\n  thumbnail_lg: \"https://www.artificialruby.ai/assets/images/events/april_9_2025/11-IMG_9773.jpg\"\n  thumbnail_xl: \"https://www.artificialruby.ai/assets/images/events/april_9_2025/11-IMG_9773.jpg\"\n  description: |-\n    Join us for an evening of Ruby x AI demos and drinks at Betaworks! This happy hour & demo night offers the perfect opportunity to connect with fellow enthusiasts while enjoying amazing views. Whether you're a seasoned Rubyist exploring AI possibilities or simply curious about the intersection of these technologies, you'll find something valuable here.\n\n    We look forward to seeing you there!\n\n    Important: Please bring a valid photo ID that matches your RSVP for admission.\n\n    Agenda:\n    6:00-6:45: Arrive, mingle, drinks and refreshments\n    6:45-7:00: Intros\n    7:00-8:00: Demos\n    8:00-9:00: Food, drinks and connections\n\n    Demos:\n\n    * Hao Wang: \"Anatomy of a Good (open) AI SDK\"\n    * Amanda Bizzinotto: \"Talk to Me: Building an AI-powered Slackbot\" - 'All your knowledge base are belong to us.' How to integrate all your knowledge bases into a bot that doesn't mind answering the same question over and over again.\n    * Scott Werner: \"We Were Voyagers. We Can Voyage Again!\" - Reigniting Ruby's creative spark with AI.\n\n    If you are interested in speaking at future events, please fill out the form below. The demos are usually about 10 minutes and feature a cool AI tool or feature built in Ruby/Rails.\n\n    https://forms.gle/k2NyKQJYiXCF5L2w6\n\n\n    Sponsors:\n\n    Def Method pours love into Ruby applications until the applications love you back. We are the authors of Phoenix, the AI-powered Rails testing system that helps you ship faster and with more confidence.\n\n    Niva is an AI-native platform making it effortless to trust businesses anywhere in the world.\n\n    Sublayer is building Augmentations.ai a platform for getting AI to take care of the parts of engineering you don't want to do.\n\n    OmbuLabs offers custom development of classic machine learning models and AI-powered systems. We are the friendly folks behind FastRuby.io and your favorite open source projects for remediating tech debt.\n\n    Whop: At Whop, our mission is to make everyone a lot of money. We’re building the most addicting mall on the internet; bridging the gap between connection, creation, and commerce. We firmly believe that money is freedom of time and we dream of a platform of one million millionaires. We are a team of entrepreneurs building for entrepreneurs. Our creators earn almost $1B / year with a team of about 70 people based in Brooklyn, NY.\n\n\n    Host:\n\n    Betaworks: Betaworks is a product-focused, seed-stage venture capital fund. We are thematic by design, we immerse ourselves in irruption-phase technologies and work with founders and our community to understand new user behavior.\n\n    https://www.artificialruby.ai/events/april-9-2025\n    https://lu.ma/51iv0zzl\n\n  talks:\n    - title: \"Anatomy of a Good (open) AI SDK\"\n      event_name: \"ArtificialRuby.ai Meetup April 2025\"\n      date: \"2025-04-09\"\n      published_at: \"2025-04-16\"\n      video_provider: \"youtube\"\n      id: \"hao-wang-artificialrubyai-meetup-april-2025\"\n      video_id: \"Z7MI6pX0eV0\"\n      description: |-\n        Hao Wang will talk about the anatomy of a good (open) AI SDK.\n      speakers:\n        - Hao Wang\n\n    - title: \"Talk to Me: Building an AI-powered Slackbot\"\n      event_name: \"ArtificialRuby.ai Meetup April 2025\"\n      date: \"2025-04-09\"\n      published_at: \"2025-04-16\"\n      video_provider: \"youtube\"\n      id: \"amanda-bizzinotto-artificialrubyai-meetup-april-2025\"\n      video_id: \"_NGmEEtcZ3I\"\n      description: |-\n        Amanda Bizzinotto will talk about building an AI-powered Slackbot.\n      speakers:\n        - Amanda Bizzinotto\n\n    - title: \"We Were Voyagers. We Can Voyage Again!\"\n      event_name: \"ArtificialRuby.ai Meetup April 2025\"\n      date: \"2025-04-09\"\n      published_at: \"2025-04-16\"\n      video_provider: \"youtube\"\n      id: \"scott-werner-artificialrubyai-meetup-april-2025\"\n      video_id: \"oE6qSVsjWL8\"\n      description: |-\n        Scott Werner will talk about reigniting Ruby's creative spark with AI.\n      speakers:\n        - Scott Werner\n\n- id: \"artificial-ruby-meetup-may-2025\"\n  title: \"ArtificialRuby.ai Meetup May 2025\"\n  raw_title: \"ArtificialRuby.ai NYC Meetup\"\n  video_id: \"artificial-ruby-meetup-may-2025\"\n  video_provider: \"children\"\n  date: \"2025-05-07\"\n  published_at: \"2025-05-13\"\n  thumbnail_xs: \"https://mcusercontent.com/d5e6863e7bc3fd8c3f1495e6d/images/35801130-af29-04b4-3c87-545d90de3be0.png\"\n  thumbnail_sm: \"https://mcusercontent.com/d5e6863e7bc3fd8c3f1495e6d/images/35801130-af29-04b4-3c87-545d90de3be0.png\"\n  thumbnail_md: \"https://mcusercontent.com/d5e6863e7bc3fd8c3f1495e6d/images/35801130-af29-04b4-3c87-545d90de3be0.png\"\n  thumbnail_lg: \"https://mcusercontent.com/d5e6863e7bc3fd8c3f1495e6d/images/35801130-af29-04b4-3c87-545d90de3be0.png\"\n  thumbnail_xl: \"https://mcusercontent.com/d5e6863e7bc3fd8c3f1495e6d/images/35801130-af29-04b4-3c87-545d90de3be0.png\"\n  description: |-\n    Join us for an evening of Ruby x AI demos and drinks at Betaworks! This happy hour & demo night offers the perfect opportunity to connect with the community while enjoying amazing views. Whether you're a seasoned Rubyist exploring AI possibilities or simply curious about the intersection of these technologies, you'll find something valuable here.\n\n    We look forward to seeing you there!\n\n    Important: Please bring a valid photo ID that matches your RSVP for admission.\n\n    Agenda:\n\n    6:00-6:45: Arrive, mingle, drinks and refreshments\n    6:45-7:00: Intros\n    7:00-8:00: Demos\n    8:00-9:00: Food, drinks and connections\n\n    Demos:\n\n    * Chris Power (aka: Typecraft): \"AI Critiques Your Vim-fu\" - What if AI could be more than an encyclopedia? At Typecraft, we merge bite-sized Vim challenges and deep-dive mini-courses to analyze every keystroke—evaluating your edits and coaching you on techniques you never knew (or have forgotten), making learning a true two-way street.\n    * Keith Harper: \"The future is here, and anyone can code it.\" - My experience as a designer working with AI to launch an MVP\n    * Brian Fountain: \"World Premier of 1000 Notes\" - At the last meetup Scott challenged the community to build and share weird ideas, and Brian Fountain answered that call. You won't want to miss it!\n\n    If you are interested in speaking at future events, please fill out the form below. The demos are usually about 10 minutes and feature a cool AI tool or feature built in Ruby/Rails.\n\n    https://forms.gle/k2NyKQJYiXCF5L2w6\n\n\n    Sponsors:\n\n    Def Method pours love into Ruby applications until the applications love you back. We are the authors of Phoenix, the AI-powered Rails testing system that helps you ship faster and with more confidence.\n\n    Niva is an AI-native platform making it effortless to trust businesses anywhere in the world.\n\n    Sublayer is building Augmentations.ai a platform for getting AI to take care of the parts of engineering you don't want to do.\n\n    OmbuLabs offers custom development of classic machine learning models and AI-powered systems. We are the friendly folks behind FastRuby.io and your favorite open source projects for remediating tech debt.\n\n    Whop: At Whop, our mission is to make everyone a lot of money. We’re building the most addicting mall on the internet; bridging the gap between connection, creation, and commerce. We firmly believe that money is freedom of time and we dream of a platform of one million millionaires. We are a team of entrepreneurs building for entrepreneurs. Our creators earn almost $1B / year with a team of about 70 people based in Brooklyn, NY.\n\n\n    Host:\n\n    Betaworks: Betaworks is a product-focused, seed-stage venture capital fund. We are thematic by design, we immerse ourselves in irruption-phase technologies and work with founders and our community to understand new user behavior.\n\n    By registering for this event, you agree to receive email communication from the Artificial Ruby team about future events and other community activities.\n\n    https://www.artificialruby.ai/events/may-7-2025\n    https://lu.ma/51iv0zzl\n\n  talks:\n    - title: \"AI Critiques Your Vim-fu\"\n      event_name: \"ArtificialRuby.ai Meetup May 2025\"\n      date: \"2025-05-07\"\n      published_at: \"2025-05-13\"\n      video_provider: \"youtube\"\n      id: \"chris-power-artificialrubyai-meetup-may-2025\"\n      video_id: \"QvLItsJjMfM\"\n      description: |-\n        What if AI could be more than an encyclopedia? At Typecraft, we merge bite-sized Vim challenges and deep-dive mini-courses to analyze every keystroke—evaluating your edits and coaching you on techniques you never knew (or have forgotten), making learning a true two-way street.\n      speakers:\n        - Chris Power\n\n    - title: \"The future is here, and anyone can code it.\"\n      event_name: \"ArtificialRuby.ai Meetup May 2025\"\n      date: \"2025-05-07\"\n      published_at: \"2025-05-13\"\n      video_provider: \"youtube\"\n      id: \"keith-harper-artificialrubyai-meetup-may-2025\"\n      video_id: \"ZlI_CQdOZ2g\"\n      description: |-\n        My experience as a designer working with AI to launch an MVP.\n      speakers:\n        - Keith Harper\n\n    - title: \"World Premier of 1000 Notes\"\n      event_name: \"ArtificialRuby.ai Meetup May 2025\"\n      date: \"2025-05-07\"\n      published_at: \"2025-05-13\"\n      video_provider: \"youtube\"\n      id: \"brian-fountain-artificialrubyai-meetup-may-2025\"\n      video_id: \"zzXLk-01Uyk\"\n      description: |-\n        At the last meetup Scott challenged the community to build and share weird ideas, and Brian Fountain answered that call. You won't want to miss it!\n      speakers:\n        - Brian Fountain\n\n# July 2025\n\n- id: \"artificial-ruby-meetup-july-2025\"\n  title: \"ArtificialRuby.ai Meetup July 2025\"\n  raw_title: \"ArtificialRuby.ai NYC Meetup\"\n  video_id: \"artificial-ruby-meetup-july-2025\"\n  video_provider: \"children\"\n  date: \"2025-07-16\"\n  thumbnail_xs: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=400,height=400/event-covers/f6/89634ba1-0ca2-46e6-b0a6-b2a7117a894b.png\"\n  thumbnail_sm: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=400,height=400/event-covers/f6/89634ba1-0ca2-46e6-b0a6-b2a7117a894b.png\"\n  thumbnail_md: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=400,height=400/event-covers/f6/89634ba1-0ca2-46e6-b0a6-b2a7117a894b.png\"\n  thumbnail_lg: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=400,height=400/event-covers/f6/89634ba1-0ca2-46e6-b0a6-b2a7117a894b.png\"\n  thumbnail_xl: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=400,height=400/event-covers/f6/89634ba1-0ca2-46e6-b0a6-b2a7117a894b.png\"\n  description: |-\n    Join us for an evening of Ruby x AI demos and drinks at Betaworks! This happy hour & demo night offers the perfect opportunity to connect with the community while enjoying amazing views. Whether you're a seasoned Rubyist exploring AI possibilities or simply curious about the intersection of these technologies, you'll find something valuable here.\n\n    We look forward to seeing you there!\n\n    Important: Please bring a valid photo ID that matches your RSVP for admission.\n\n    Agenda:\n\n    6:00-6:45: Arrive, mingle, drinks and refreshments\n    6:45-7:00: Intros\n    7:00-8:00: Demos\n    8:00-9:00: Food, drinks and connections\n\n    Demos:\n\n    [COMING SOON]\n\n    If you are interested in speaking at future events, please fill out the form below. The demos are usually about 10 minutes and feature a cool AI tool or feature built in Ruby/Rails.\n\n    https://forms.gle/k2NyKQJYiXCF5L2w6\n\n\n    Sponsors:\n\n    Def Method pours love into Ruby applications until the applications love you back. We are the authors of Phoenix, the AI-powered Rails testing system that helps you ship faster and with more confidence.\n\n    Niva is an AI-native platform making it effortless to trust businesses anywhere in the world.\n\n    Sublayer is building Augmentations.ai a platform for getting AI to take care of the parts of engineering you don't want to do.\n\n    OmbuLabs offers custom development of classic machine learning models and AI-powered systems. We are the friendly folks behind FastRuby.io and your favorite open source projects for remediating tech debt.\n\n    Whop: At Whop, our mission is to make everyone a lot of money. We’re building the most addicting mall on the internet; bridging the gap between connection, creation, and commerce. We firmly believe that money is freedom of time and we dream of a platform of one million millionaires. We are a team of entrepreneurs building for entrepreneurs. Our creators earn almost $1B / year with a team of about 70 people based in Brooklyn, NY.\n\n\n    Host:\n\n    Betaworks: Betaworks is a product-focused, seed-stage venture capital fund. We are thematic by design, we immerse ourselves in irruption-phase technologies and work with founders and our community to understand new user behavior.\n\n    By registering for this event, you agree to receive email communication from the Artificial Ruby team about future events and other community activities.\n\n    https://lu.ma/vbbdhwm1\n  speakers:\n    - TBD\n"
  },
  {
    "path": "data/artificialruby/series.yml",
    "content": "---\nname: \"Artificial Ruby\"\nwebsite: \"https://www.artificialruby.ai\"\ntwitter: \"artificialruby\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"Artificial Ruby\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"artificial_ruby\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCKeTdPW5f7IMMsKP25XwOgA\"\n"
  },
  {
    "path": "data/austinrb/austinrb/cfp.yml",
    "content": "---\n- link: \"https://austinrb.org/speakers.html\"\n"
  },
  {
    "path": "data/austinrb/austinrb/event.yml",
    "content": "---\nid: \"austinrb-meetup\"\ntitle: \"Austin.rb Meetup\"\nlocation: \"Austin, TX, United States\"\ndescription: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nmeetup: \"https://www.meetup.com/austinrb\"\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://austinrb.org/\"\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/austinrb/series.yml",
    "content": "---\nname: \"austin.rb\"\nwebsite: \"https://austinrb.org/\"\ntwitter: \"austinrb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2018/event.yml",
    "content": "---\nid: \"PLAkGYJoUfB0v4ssiPcL_OIM1-t_LssfAY\"\ntitle: \"Balkan Ruby 2018\"\nkind: \"conference\"\nlocation: \"Sofia, Bulgaria\"\ndescription: |-\n  https://2018.balkanruby.com\npublished_at: \"2018-10-07\"\nstart_date: \"2018-05-25\"\nend_date: \"2018-05-26\"\nchannel_id: \"UCR076_JBPtcQKfiwiVOB3Cg\"\nyear: 2018\nbanner_background: \"#EFEFEF\"\nfeatured_background: \"#EFEFEF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 42.6977082\n  longitude: 23.3218675\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2018/videos.yml",
    "content": "---\n# TODO: talk dates\n\n# Website: https://2018.balkanruby.com\n# Schedule: https://2018.balkanruby.com/schedule\n\n## Day 1 - Friday\n\n# Registration and morning coffee\n\n- id: \"zach-holman-balkan-ruby-2018\"\n  title: \"UTC is Enough for Everybody, Right?\"\n  raw_title: \"UTC is Enough for Everybody, Right? – Zach Holman – Balkan Ruby 2018\"\n  speakers:\n    - Zach Holman\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Zach Holman is a developer living in San Francisco. He joined GitHub in 2010 as one of their first engineering hires, and helped build and grow their product and culture over five years. Currently he’s the founder and CEO of During, a new calendar to help you during your day. He also advises startups, including GitLab and Dockbit.\n  video_provider: \"youtube\"\n  video_id: \"44i-H2bn6vM\"\n  published_at: \"2018-10-08\"\n\n- id: \"robert-mosolgo-balkan-ruby-2018\"\n  title: \"GraphQL\"\n  raw_title: \"GraphQL – Robert Mosolgo – Balkan Ruby 2018\"\n  speakers:\n    - Robert Mosolgo\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Robert is a Ruby developer at GitHub, focused on the GraphQL API. In his free time, he likes spending time with his family, reading about programming language design, and doing upholstery projects.\n  video_provider: \"youtube\"\n  video_id: \"gvwThoJ_In4\"\n  published_at: \"2018-10-08\"\n\n- id: \"gabriela-luhova-balkan-ruby-2018\"\n  title: \"JSON API in the Ruby World\"\n  raw_title: \"JSON API in the Ruby world – Gabriela Luhova – Balkan Ruby 2018\"\n  speakers:\n    - Gabriela Luhova\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Rails Girls mentor since 2015. Ruby on Rails developer at Tutuf. Faculty of Mathematics and Informatics at the Sofia University graduate. Took part in a lot of conferences as an assistant organizer, because being part of community is giving me motivation and inspiration.\n  video_provider: \"youtube\"\n  video_id: \"B6S0jdGhkl0\"\n  published_at: \"2018-10-08\"\n\n# Lunch\n\n- id: \"piotr-szotkowski-balkan-ruby-2018\"\n  title: \"The Modern Prometheus\"\n  raw_title: \"The Modern Prometheus – Piotr Szotkowski – Balkan Ruby 2018\"\n  speakers:\n    - Piotr Szotkowski\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Most non-scripting languages are faster than Ruby (Rust: tremendously so), but few (Crystal?) can match its optimisation for developer happiness and productivity. Let’s try to gauge Ruby’s chances when it comes to matching modern performance expectations: Are the changes in recent CRuby versions significant? Can JRuby bring enough JVM performance? And – to address the titular Frankenstein – how easily can we harness the power of Crystal, Rust, C or even assembly from within our Ruby applications?\n\n    Hacker scientist. Assistant professor at Warsaw University of Technology.\n  video_provider: \"youtube\"\n  video_id: \"MszdAuNTukk\"\n  published_at: \"2018-10-08\"\n  slides_url: \"https://talks.chastell.net/krug-2018-10\"\n\n- id: \"dinah-shi-balkan-ruby-2018\"\n  title: \"Eager Loading for ActiveRecord Performance\"\n  raw_title: \"Eager Loading for ActiveRecord Performance – Dinah Shi – Balkan Ruby 2018\"\n  speakers:\n    - Dinah Shi\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Dinah is wrapping up her engineering degree at the University of Waterloo. In 2017, she spent four months backpacking around Europe and China while looking for half-decent WIFI connections to power her open-source contributions. For the last few months, she has been building a public API to expose more preloading options in Ruby on Rails.\n  video_provider: \"youtube\"\n  video_id: \"BwNbnkUSzm8\"\n  published_at: \"2018-10-08\"\n\n# Coffee break\n\n- id: \"marko-bogdanovi-balkan-ruby-2018\"\n  title: \"Start your Open Source journey with Ruby Bench\"\n  raw_title: \"Start your Open Source journey with Ruby Bench – Marko Bogdanović – Balkan Ruby 2018\"\n  speakers:\n    - Marko Bogdanović\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Spent last summer crafting RubyBench as a participant of Google Summer of Code. Recently joined guys at the Semaphore CI as a full time Ruby newbie. Most of the non-work time spend on Fruska gora hiking, running or preferably mountain biking.\n  video_provider: \"youtube\"\n  video_id: \"tNxGoaKmc10\"\n  published_at: \"2018-10-08\"\n\n- id: \"bozhidar-batsov-balkan-ruby-2018\"\n  title: \"Panel: The Future of Ruby\"\n  raw_title: \"Panel discussions with Bozhidar Batsov – Balkan Ruby 2018\"\n  speakers:\n    - Bozhidar Batsov\n    - Vladimir Dementyev\n    - Serdar Doğruyol\n    - Nick Sutterer\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Bozhidar Batsov moderates a panel about the future of Ruby with Vladimir Dementyev, Serdar Doğruyol and Nick Sutterer.\n  video_provider: \"youtube\"\n  video_id: \"uT4Cth4iChU\"\n  published_at: \"2018-10-08\"\n\n- id: \"vladimir-dementyev-balkan-ruby-2018\"\n  title: \"Take your slow tests to the doctor\"\n  raw_title: \"Take your slow tests to the doctor – Vladimir Dementyev – Balkan Ruby 2018\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Vladimir is a mathematician who found his happiness in programming Ruby and Erlang, contributing to open source and being an Evil Martian. Author of AnyCable, TestProf and many yet unknown ukulele melodies.\n  video_provider: \"youtube\"\n  video_id: \"rOcrme82vC8\"\n  published_at: \"2018-10-08\"\n  slides_url: \"https://speakerdeck.com/palkan/balkanruby-2018-take-your-slow-tests-to-the-doctor\"\n\n## Day 2 - Saturday\n\n# Morning coffee\n\n- id: \"radoslav-stankov-balkan-ruby-2018\"\n  title: \"How to get to zero unhandled exceptions in production\"\n  raw_title: \"How to get to zero unhandled exceptions in production – Radoslav Stankov – Balkan Ruby 2018\"\n  speakers:\n    - Radoslav Stankov\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Radoslav is a web developer for more than a decade. He believes that frontend and backend are equally important. In the last several years he juggles between Ruby and JavaScript projects. Organizer of React.NotAConf. Currently works at Product Hunt.\n  video_provider: \"youtube\"\n  video_id: \"vGDL6xZ1L-I\"\n  published_at: \"2018-10-08\"\n\n- id: \"armin-paali-balkan-ruby-2018\"\n  title: \"Beyond the current state: Time travel as answer to hard questions\"\n  raw_title: \"Beyond the current state: Time travel as answer to hard questions – Armin Pašalić – Balkan Ruby 2018\"\n  speakers:\n    - Armin Pašalić\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Software builder, mostly Ruby and a bit of Go. Passionate about \"proper\" testing, clean architecture and DDD. Currently busy constructing a distributed software system with the best colleagues ever at solarisBank AG.\n  video_provider: \"youtube\"\n  video_id: \"6EX70LJvLbQ\"\n  published_at: \"2018-10-08\"\n\n# TODO: missing talk: Sameer Deshmukh - Ferrari Driven Development: superfast Ruby with Rubex\n\n# Lunch\n\n- id: \"jan-krutisch-balkan-ruby-2018\"\n  title: \"My Ruby is a Paintbrush. My Ruby is a Synth\"\n  raw_title: \"My Ruby is a Paintbrush. My Ruby is a Synth. – Jan Krutisch – Balkan Ruby 2018\"\n  speakers:\n    - Jan Krutisch\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Jan is a software developer, tech writer, speaker and multi purpose geek.\n  video_provider: \"youtube\"\n  video_id: \"O8Z8doHL4qE\"\n  published_at: \"2018-10-08\"\n\n- id: \"serdar-doruyol-balkan-ruby-2018\"\n  title: \"Crystal: A Language for Humans and Computers\"\n  raw_title: \"Crystal: A language for humans and computers – Serdar Doğruyol – Balkan Ruby 2018\"\n  speakers:\n    - Serdar Doğruyol\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Rubyist, Crystal Evangelist, Creator of Kemal – a lightning fast, super simple web framework written in Crystal.\n  video_provider: \"youtube\"\n  video_id: \"xmkEGKacKeU\"\n  published_at: \"2018-10-08\"\n\n# Coffee Break\n\n- id: \"nynne-just-christoffersen-balkan-ruby-2018\"\n  title: \"What I Learned From Building a Twitter Art Bot\"\n  raw_title: \"What I learned from building a twitter Art Bot – Nynne Just Christoffersen – Balkan Ruby 2018\"\n  speakers:\n    - Nynne Just Christoffersen\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Nynne Just Christoffersen is a Copenhagen-based developer with a background in Art and Design History. In her spare time she enjoys her unhealthy obsession with meetup.com. She's the organiser of Rails Girls Copenhagen and the Copenhagen tech book and film club, among many other things.\n  video_provider: \"youtube\"\n  video_id: \"u2MDw6RF--c\"\n  published_at: \"2018-10-08\"\n\n- id: \"lightning-talks-balkanruby-2018\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning talks – Balkan Ruby 2018\"\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"lpkePkbYeoI\"\n  published_at: \"2018-10-08\"\n  talks:\n    - title: \"Lightning Talk: How To Talk To Non-Technical People\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"martina-koleva-lighting-talk-balkan-ruby-2018\"\n      video_id: \"martina-koleva-lighting-talk-balkan-ruby-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Martina Koleva\n\n    - title: \"Lightning Talk: #rubythankful\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"vladimir-dementyev-lighting-talk-balkan-ruby-2018\"\n      video_id: \"vladimir-dementyev-lighting-talk-balkan-ruby-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Vladimir Dementyev\n\n    - title: \"Lightning Talk: Cyberneat\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"evgeni-kunev-lighting-talk-balkan-ruby-2018\"\n      video_id: \"evgeni-kunev-lighting-talk-balkan-ruby-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Evgeni Kunev\n\n    - title: \"Lightning Talk: Stop Using Alt And Shift When You Do Not Need It\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"dusan-orlovic-lighting-talk-balkan-ruby-2018\"\n      video_id: \"dusan-orlovic-lighting-talk-balkan-ruby-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Dusan Orlovic\n\n    - title: \"Lightning Talk: Programming Spreadsheets\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tomasz-stachewicz-lighting-talk-balkan-ruby-2018\"\n      video_id: \"tomasz-stachewicz-lighting-talk-balkan-ruby-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomasz Stachewicz\n\n    - title: \"Lightning Talk: Remote Work\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"archon-lighting-talk-balkan-ruby-2018-1\"\n      video_id: \"archon-lighting-talk-balkan-ruby-2018-1\"\n      video_provider: \"parent\"\n      speakers:\n        - Archon # TODO: lastname\n\n    - title: \"Lightning Talk: Gem Dependencies\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"andreas-finger-lighting-talk-balkan-ruby-2018\"\n      video_id: \"andreas-finger-lighting-talk-balkan-ruby-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Andreas Finger\n\n    - title: \"Lightning Talk: GraphQL - Is It Worth Using It?\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"robert-pawlas-lighting-talk-balkan-ruby-2018\"\n      video_id: \"robert-pawlas-lighting-talk-balkan-ruby-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Robert Pawlas\n\n- id: \"nick-sutterer-balkan-ruby-2018\"\n  title: \"Trailblazer\"\n  raw_title: \"Trailblazer – Nick Sutterer – Balkan Ruby 2018\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"Balkan Ruby 2018\"\n  date: \"2018-05-26\"\n  description: |-\n    Whenever Open-Source meets deep and profound debates about architecting software, and there's free beers involved, Nick Sutterer must be just around the corner. Say \"Hi!\" to him, he loves people.\n  video_provider: \"youtube\"\n  video_id: \"bhxD9n-UWQ0\"\n  published_at: \"2018-10-08\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2019/event.yml",
    "content": "---\nid: \"PLAkGYJoUfB0vutEvm7Z2dcrxbtAQfPUSp\"\ntitle: \"Balkan Ruby 2019\"\nkind: \"conference\"\nlocation: \"Sofia, Bulgaria\"\ndescription: |-\n  https://balkanruby.com\npublished_at: \"2019-08-05\"\nstart_date: \"2019-05-17\"\nend_date: \"2019-05-18\"\nchannel_id: \"UCR076_JBPtcQKfiwiVOB3Cg\"\nyear: 2019\nbanner_background: \"#101010\"\nfeatured_background: \"#101010\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 42.6977082\n  longitude: 23.3218675\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2019/videos.yml",
    "content": "---\n# TODO: talk dates\n\n# Website: https://web.archive.org/web/20190809132609/https://balkanruby.com/\n# Schedule: https://web.archive.org/web/20190609074501mp_/https://balkanruby.com/schedule\n\n## Day 1 - Friday\n\n# Registration and morning coffee\n\n- id: \"eileen-m-uchitelle-balkan-ruby-2019\"\n  title: \"Keynote: The Past, Present and Future of Rails at GitHub\"\n  raw_title: \"Balkan Ruby 2019 – Eileen Uchitelle – The Past, Present and Future of Rails at GitHub\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"Balkan Ruby 2019\"\n  slides_url: \"https://speakerdeck.com/eileencodes/railsconf-and-balkan-ruby-2019-the-past-present-and-future-of-rails-at-github\"\n  date: \"2019-05-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"eZOhUh6FzHU\"\n  published_at: \"2019-06-18\"\n\n- id: \"tung-nguyen-balkan-ruby-2019\"\n  title: \"Jets: The Ruby Serverless Framework\"\n  raw_title: \"Balkan Ruby 2019 – Tung Nguyen – Jets: The Ruby Serverless Framework\"\n  speakers:\n    - Tung Nguyen\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"i11jXvR5hPA\"\n  published_at: \"2019-06-18\"\n\n- id: \"kaja-santro-balkan-ruby-2019\"\n  title: \"Productive Unemployment\"\n  raw_title: \"Balkan Ruby 2019 – Kaja Santro – Productive Unemployment\"\n  speakers:\n    - Kaja Santro\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"iFbGkGq8wOQ\"\n  published_at: \"2019-06-18\"\n\n# Lunch\n\n- id: \"sergei-alekseenko-balkan-ruby-2019\"\n  title: \"Nginx + Mruby. Features and Use Cases\"\n  raw_title: \"Balkan Ruby 2019 – Sergei Alekseenko – Nginx + Mruby. Features and use cases\"\n  speakers:\n    - Sergei Alekseenko\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"QMhgm9ir8js\"\n  published_at: \"2019-08-04\"\n\n- id: \"alexandre-lairan-balkan-ruby-2019\"\n  title: \"How I Entered The Machine Learning World\"\n  raw_title: \"Balkan Ruby 2019 – Alexandre Lairan – How I entered the machine learning world\"\n  speakers:\n    - Alexandre Lairan\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"493EzEQFVFQ\"\n  published_at: \"2019-08-14\"\n\n# Coffee break\n\n# TODO: missing panel: Bozhidar Batsov, Emil Petkov, Radoslav Stankov - Panel: Running a Ruby business in Bulgaria\n\n- id: \"edouard-chin-balkan-ruby-2019\"\n  title: \"Getting Ready for I18n, Shopify's case study\"\n  raw_title: \"Balkan Ruby 2019 – Edouard Chin – Getting ready for I18n, Shopify's case study\"\n  speakers:\n    - Edouard Chin\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"2WnFh6Ps_cE\"\n  published_at: \"2019-08-04\"\n\n## Day 2 - Saturday\n\n# Morning coffee\n\n- id: \"fernando-mendes-balkan-ruby-2019\"\n  title: \"You. And The Morals of Technology\"\n  raw_title: \"Balkan Ruby 2019 – Fernando Mendes – You. And the morals of technology\"\n  speakers:\n    - Fernando Mendes\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"joZVgTY9kCU\"\n  published_at: \"2019-08-04\"\n\n- id: \"eli-kroumova-balkan-ruby-2019\"\n  title: \"Exploring Graphs with Ruby\"\n  raw_title: \"Balkan Ruby 2019 – Eli Kroumova – Exploring Graphs with Ruby\"\n  speakers:\n    - Eli Kroumova\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"7z1Aoc7W6Lk\"\n  published_at: \"2019-08-04\"\n\n- id: \"soutaro-matsumoto-balkan-ruby-2019\"\n  title: \"An Introduction to Typed Ruby Programming\"\n  raw_title: \"Balkan Ruby 2019 – Soutaro Matsumoto – An introduction to typed Ruby programming\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"GbTZibgIhVk\"\n  published_at: \"2019-08-04\"\n\n# Lunch\n\n- id: \"amr-abdelwahab-balkan-ruby-2019\"\n  title: \"Deconstructing a Hype: What People Think Is Wrong With Ruby?\"\n  raw_title: \"Balkan Ruby 2019 – Amr Abdelwahab – Deconstructing a hype: What people think is wrong with Ruby?\"\n  speakers:\n    - Amr Abdelwahab\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"BW5rv_uINLA\"\n  published_at: \"2019-08-04\"\n\n- id: \"yulia-oletskaya-balkan-ruby-2019\"\n  title: \"RPC Frameworks Overview\"\n  raw_title: \"Balkan Ruby 2019 – Yulia Oletskaya – RPC Frameworks Overview\"\n  speakers:\n    - Yulia Oletskaya\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zVJ8QA6TizE\"\n  published_at: \"2019-08-04\"\n\n# Coffee Break\n\n# Lightning Talks\n\n- id: \"aaron-patterson-balkan-ruby-2019\"\n  title: \"Keynote: Compacting GC for MRI\"\n  raw_title: \"Balkan Ruby 2019 – Aaron Patterson – Compacting GC for MRI\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Balkan Ruby 2019\"\n  date: \"2019-05-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"S8NcX7low2Q\"\n  published_at: \"2019-08-04\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2020/event.yml",
    "content": "---\nid: \"balkanruby-2020\"\ntitle: \"Balkan Ruby 2020 (Cancelled)\"\ndescription: \"\"\nlocation: \"Sofia, Bulgaria\"\nkind: \"conference\"\nstart_date: \"2020-05-15\"\nend_date: \"2020-05-16\"\nwebsite: \"https://balkanruby.com\"\nstatus: \"cancelled\"\ntwitter: \"balkanruby\"\ncoordinates:\n  latitude: 42.6977082\n  longitude: 23.3218675\naliases:\n  - Balkan Ruby 2020\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://balkanruby.com\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2024/cfp.yml",
    "content": "---\n- link: \"https://forms.gle/NJY9PJWpud39ZQAr8\"\n  open_date: \"2023-11-20\"\n  close_date: \"2024-02-02\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2024/event.yml",
    "content": "---\nid: \"PLAkGYJoUfB0s1x8AcxBlnpnKFOPblEkRa\"\ntitle: \"Balkan Ruby 2024\"\nkind: \"conference\"\nlocation: \"Sofia, Bulgaria\"\ndescription: |-\n  Balkan Ruby was back to business after a 5-year hiatus. To celebrate our return, we ran a business theme exploring how Ruby helps us start, build, and maintain small; big; side; open/closed and weird businesses!\npublished_at: \"2024-06-05\"\nstart_date: \"2024-04-26\"\nend_date: \"2024-04-27\"\nchannel_id: \"UCR076_JBPtcQKfiwiVOB3Cg\"\nyear: 2024\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2024.balkanruby.com\"\ncoordinates:\n  latitude: 42.6618769\n  longitude: 23.3179147\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2024/schedule.yml",
    "content": "# Schedule: https://web.archive.org/web/20240423072255/https://balkanruby.com/\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-04-26\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"10:00\"\n        end_time: \"10:10\"\n        slots: 1\n        items:\n          - Introduction\n\n      - start_time: \"10:10\"\n        end_time: \"10:40\"\n        slots: 1\n\n      - start_time: \"10:40\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch break\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:40\"\n        slots: 1\n        items:\n          - Coffee break\n\n      - start_time: \"16:40\"\n        end_time: \"17:10\"\n        slots: 1\n\n      - start_time: \"17:10\"\n        end_time: \"17:10\"\n        slots: 1\n        items:\n          - Closing\n\n  - name: \"Day 2\"\n    date: \"2024-04-27\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"10:00\"\n        end_time: \"10:10\"\n        slots: 1\n        items:\n          - Introduction\n\n      - start_time: \"10:10\"\n        end_time: \"10:40\"\n        slots: 1\n\n      - start_time: \"10:40\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch break\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:40\"\n        slots: 1\n        items:\n          - Coffee break\n\n      - start_time: \"16:40\"\n        end_time: \"17:10\"\n        slots: 1\n\n      - start_time: \"17:10\"\n        end_time: \"17:10\"\n        slots: 1\n        items:\n          - Closing\n\ntracks: []\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2024/venue.yml",
    "content": "---\nname: \"Puzl CowOrKing - Greenhouse Office Spaces, Siven Building\"\n\naddress:\n  street: 'Promishlena zona Hladilnika, Blvd. \"Cherni vrah\" 47'\n  city: \"Sofia\"\n  region: \"\"\n  postal_code: \"1407\"\n  country: \"Bulgaria\"\n  country_code: \"BG\"\n  display: 'Промишлена зона Хладилника, Blvd. \"Cherni vrah\" 47, 1407 Sofia, Bulgaria'\n\ncoordinates:\n  latitude: 42.6618769\n  longitude: 23.3179147\n\nmaps:\n  google: \"https://maps.google.com/?q=Puzl+CowOrKing+-+Greenhouse+Office+Spaces,+Siven+Building,+Sofia,+Bulgaria,42.6618769,23.3179147\"\n  apple: \"https://maps.apple.com/?q=Puzl+CowOrKing+-+Greenhouse+Office+Spaces,+Siven+Building,+Sofia,+Bulgaria&ll=42.6618769,23.3179147\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=42.6618769&mlon=23.3179147\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2024/videos.yml",
    "content": "---\n# Website: https://balkanruby.com/2024\n# Schedule: https://web.archive.org/web/20240423072255/https://balkanruby.com/\n\n## Day 1 - April 26, 2024\n\n- id: \"irina-nazarova-balkan-ruby-2024\"\n  title: \"How to do well in consulting\"\n  raw_title: \"Irina Nazarova – How to do well in consulting\"\n  speakers:\n    - Irina Nazarova\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-05\"\n  slides_url: \"https://speakerdeck.com/irinanazarova/how-to-do-well-in-consulting-balkan-ruby-2024\"\n  description: |-\n    Irina Nazarova is the CEO of Evil Martians. Evil Martians transform growth-stage startups into unicorns, build developer tools, and create open-source products.\n\n    Irina opened up Balkan Ruby 2024 which was all about running business with Ruby and running Ruby businesses.\n  video_provider: \"youtube\"\n  video_id: \"ZR-Mk4u3m7Q\"\n  published_at: \"2024-06-05\"\n\n- id: \"adrian-marin-balkan-ruby-2024\"\n  title: \"Build a business on Open Source and Ruby\"\n  raw_title: \"Adrian Marin – Build a business on Open Source and Ruby\"\n  speakers:\n    - Adrian Marin\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-05\"\n  description: |-\n    Adrian Marin is a self-thought engineer and entrepreneur running Avo. Avo started as a side project, and now is a lively project with about 150 paying customers, and more than 400 apps running it in production.\n\n    Building a business is not easy. Selling to developers is even harder. Adrian chose the difficult path to do both and he's been lucky enough to survive it.\n  video_provider: \"youtube\"\n  video_id: \"XuUg_cg1lew\"\n  published_at: \"2024-06-05\"\n\n- id: \"bozhidar-batsov-balkan-ruby-2024\"\n  title: \"Sustainable OSS Development\"\n  raw_title: \"Bozhidar Batsov – Sustainable OSS Development\"\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-06\"\n  description: |-\n    Bozhidar is the author of RuboCop, Cider, Prelude, Projectile, and many other popular open-source projects. He has been doing open-source development for more than a decade, sustainably. Not an easy task!\n\n    In this talk, Bozhidar walks us through what it is to maintain, and sustain, open-source projects for the long term.\n  video_provider: \"youtube\"\n  video_id: \"FUDxvFUtWH0\"\n  published_at: \"2024-06-06\"\n\n# Lunch\n\n- id: \"aitor-garcia-rey-balkan-ruby-2024\"\n  title: \"Running a Fintech with Ruby\"\n  raw_title: \"Aitor Garcia Rey – Running a Fintech with Ruby (Balkan Ruby 2024)\"\n  speakers:\n    - Aitor Garcia Rey\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-07\"\n  description: |-\n    Aitor García Rey is a founder, staff engineer, and fractional CTO. He has been shipping software used by small companies, VC-backed startups, and big publicly traded multinationals for over 20 years, leading and mentoring highly technical teams.\n  video_provider: \"youtube\"\n  video_id: \"t1vT3a5cQ8g\"\n  published_at: \"2024-06-07\"\n\n- id: \"cristian-planas-balkan-ruby-2024\"\n  title: \"2,000 Engineers, 2 Million Lines of Code: The History of a Rails Monolith\"\n  raw_title: \"Cristian Planas & Anatoly Mikhaylov – The history of a Rails monolith\"\n  speakers:\n    - Cristian Planas\n    - Anatoly Mikhaylov\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-07\"\n  description: |-\n    Cristian Planas is a software engineer working primarily with Rails since the release of Rails 3, more than 10 years ago.  Currently, a group tech lead and senior staff engineer at Zendesk.\n\n    Anatoly Mikhaylov is a Performance and Reliability engineer with over 15 years of experience. He's a part of the Capacity and Performance team at Zendesk.\n\n    They're delivering a story about a long-running Ruby monolith powering a successful business at scale.\n  video_provider: \"youtube\"\n  video_id: \"2mu1B75UHAE\"\n  published_at: \"2024-06-07\"\n\n- id: \"josef-strzibny-balkan-ruby-2024\"\n  title: 'Writing and marketing \"Deployment from Scratch\"'\n  raw_title: 'Josef Strzibny – Writing and marketing \"Deployment from Scratch\"'\n  speakers:\n    - Josef Strzibny\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-07\"\n  description: |-\n    Josef is a longtime Rails developer, freelancer, and author of Deployment from Scratch. Previously he was a small startup CTO, senior Rails engineer, and a Linux packager at Red Hat. He now spends most of his time building a Rails starter kit Business Class while regularly watching Gordon Ramsay cooking shows.\n\n    He quit his job and went to write a book for 6 months. 2.5 years later he realized his book was not finished and he hadn't made any sales. But in the end, he made a book that brings in sales every month. Here's a story of ideating, starting, writing, finishing, marketing, promoting, and selling his book to 1000 sales as an independent author without a publisher.\n  video_provider: \"youtube\"\n  video_id: \"11ihYaEhi1g\"\n  published_at: \"2024-06-07\"\n\n## Day 2 - April 27, 2024\n\n- id: \"xavier-noria-balkan-ruby-2024\"\n  title: \"A Dateless Mindset\"\n  raw_title: \"Xavier Noria – A Dateless Mindset\"\n  speakers:\n    - Xavier Noria\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-07\"\n  description: |-\n    Xavier Noria is an everlasting student, a Ruby on Rails Core team member, the creator of Zeitwerk, a freelancer, and a life lover. In this talk, Xavi is sharing his experience of working without dates as a freelancer for the last 14 years.\n  video_provider: \"youtube\"\n  video_id: \"cKxfaHfiZyc\"\n  published_at: \"2024-06-07\"\n\n- id: \"dimiter-petrov-balkan-ruby-2024\"\n  title: \"20 Years and Counting: Making it as a Consultancy\"\n  raw_title: \"Dimiter Petrov – 20 years and going: making it as a consultancy\"\n  speakers:\n    - Dimiter Petrov\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-07\"\n  description: |-\n    Dimiter is a development team lead at thoughtbot and the co-organizer of the Helvetic Ruby conference. He likes spending time away from the computer running and hiking.\n\n    thoughtbot gets leads thanks to its strong presence in the community: open source contributions, blog posts, podcasts, conference talks. This talk is about how they do it.\n  video_provider: \"youtube\"\n  video_id: \"2XsrA-dXDGw\"\n  published_at: \"2024-06-07\"\n\n- id: \"radoslav-stankov-balkan-ruby-2024\"\n  title: \"One Engineer Company with Ruby on Rails\"\n  raw_title: \"Radoslav Stankov – One engineer company with Ruby on Rails\"\n  speakers:\n    - Radoslav Stankov\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-07\"\n  description: |-\n    Radoslav was the CTO of Product Hunt. He recently built Angry Buildings as the single technical person on the team. This talks is about how he did it all by himself.\n  video_provider: \"youtube\"\n  video_id: \"lUM4KIrsaQo\"\n  published_at: \"2024-06-07\"\n\n# Lunch\n\n- id: \"stephen-margheim-balkan-ruby-2024\"\n  title: \"How (and why) to run SQLite in production\"\n  raw_title: \"Stephen Margheim – How (and why) to run SQLite in production\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-07\"\n  slides_url: \"https://speakerdeck.com/fractaledmind/wroclove-dot-rb-2024-how-and-why-to-run-sqlite-on-rails-in-production\"\n  description: |-\n    Stephen is an American expat living in Berlin with his wife and two dogs. He is a contributor to Ruby on Rails, sqlite3-ruby gem, and the maintainer of a handful of gems aimed at making Ruby and Rails the absolute best platforms in the world to run SQLite projects. For his day job, he is an engineering manager at Test IO.\n\n    Join him on a journey to explore the use-cases and benefits of running SQLite in a production environment.\n  video_provider: \"youtube\"\n  video_id: \"7QMYfpU6_-s\"\n  published_at: \"2024-06-07\"\n\n- id: \"monica-giambitto-balkan-ruby-2024\"\n  title: \"Тоо much of a Good Thing\"\n  raw_title: \"Monica Giambitto – Тоо much of a Good Thing\"\n  speakers:\n    - Monica Giambitto\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-07\"\n  description: |-\n    Monica is an Italian expat living in Munich, Germany. She is an engineering manager and in this talk, she guides us into a good thing for a business – lots of usage and incoming traffic, and the tricky things that come with it, like the actual handling of this incoming traffic.\n  video_provider: \"youtube\"\n  video_id: \"rcucUXnsE7s\"\n  published_at: \"2024-06-07\"\n\n- id: \"nick-sutterer-balkan-ruby-2024\"\n  title: \"Trailblazer, the almost sustainable underdog\"\n  raw_title: \"Nick Sutterer – Trailblazer, the almost sustainable underdog\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"Balkan Ruby 2024\"\n  date: \"2024-06-06\"\n  description: |-\n    Nick is a rock star who happens to be a rock-star Ruby developer too. He has been crafting approaches way before their time like cells. He is the creator of Trailblazer, a business-focused framework and a business by itself. In this deep-and-profound talk, Nick tells us how he runs Trailblazer, the business, and how it is ALMOST sustainable.\n  video_provider: \"youtube\"\n  video_id: \"hADHELW066k\"\n  published_at: \"2024-06-06\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2025/cfp.yml",
    "content": "---\n- link: \"https://forms.gle/Wzp4QvDzAiWVrB7d9\"\n  open_date: \"2024-11-19\"\n  close_date: \"2025-02-05\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2025/event.yml",
    "content": "---\nid: \"PLAkGYJoUfB0utM9M6WiZsCHhz2F1CgAic\"\ntitle: \"Balkan Ruby 2025\"\nkind: \"conference\"\nlocation: \"Sofia, Bulgaria\"\ndescription: |-\n  Let's talk about the long term – setting up a project, running one, designing you architecture, organizing your team, your career, or your mindset. It's all about the long term.\npublished_at: \"2025-05-05\"\nstart_date: \"2025-04-25\"\nend_date: \"2025-04-26\"\nchannel_id: \"UCR076_JBPtcQKfiwiVOB3Cg\"\nyear: 2025\nbanner_background: \"#FDF1F3\"\nfeatured_background: \"#FDF1F3\"\nfeatured_color: \"#000000\"\nwebsite: \"https://2025.balkanruby.com\"\ncoordinates:\n  latitude: 42.6701698\n  longitude: 23.3508864\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Exclusive\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Avo\"\n          badge: \"Party Sponsor\"\n          website: \"https://avohq.io\"\n          slug: \"avo\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6NDEsInB1ciI6ImJsb2JfaWQifX0=--cbce6aee6ac3d7174a63c79803abc5d83d624bce\\\n            /eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDAwLDEwMDBdfSwicHVyIjoidmFyaWF0aW9uIn19--90aa1f705a8641278e058d0a7e67d4761d73c997/avo.png\"\n\n        - name: \"Sidekiq\"\n          badge: \"\"\n          website: \"https://sidekiq.org/\"\n          slug: \"sidekiq\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MjI5LCJwdXIiOiJibG9iX2lkIn19--e4f2eec6b24538818904659f5fe40eb485c30f70/sidekiq-h\\\n            orizontal-logo.svg\"\n\n        - name: \"AppSignal\"\n          badge: \"\"\n          website: \"https://www.appsignal.com\"\n          slug: \"appsignal\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6NDAsInB1ciI6ImJsb2JfaWQifX0=--6594f09203f380442d3fc6da9f13987d6f559b84\\\n            /eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDAwLDEwMDBdfSwicHVyIjoidmFyaWF0aW9uIn19--90aa1f705a8641278e058d0a7e67d4761d73c997/appsignal.p\\\n            ng\"\n\n        - name: \"Studio Raketa\"\n          badge: \"\"\n          website: \"https://raketadesign.com/\"\n          slug: \"studio-raketa\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsiZGF0YSI6Mjc0LCJwdXIiOiJibG9iX2lkIn19--018415d5ff1ee67859e9f479475c90d607ded6cd/raketa-lo\\\n            go.svg\"\n\n    - name: \"Partner\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Evil Martians\"\n          badge: \"\"\n          website: \"https://evilmartians.com\"\n          slug: \"evil-martians\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MjQ1LCJwdXIiOiJibG9iX2lkIn19--8b68bdc6b32bd81b25f8ddfc3bc9c444cad3ef74/evil-mart\\\n            ians-logo.svg\"\n\n        - name: \"Harvest\"\n          badge: \"\"\n          website: \"https://www.getharvest.com/\"\n          slug: \"harvest\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6OTMsInB1ciI6ImJsb2JfaWQifX0=--8e82cd36e43af1c4af9944b0e16a419e54a9e8ba\\\n            /eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOls1MDAsNTAwXX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--1af0099157b76e9cbcc497a0d35cdb95437cfe52/Harvest%20L\\\n            ockup%20Orange.png\"\n\n        - name: \"Visuality\"\n          badge: \"\"\n          website: \"https://www.visuality.pl\"\n          slug: \"visuality\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MTYwLCJwdXIiOiJibG9iX2lkIn19--b1cda05b1446764199adf4d896d2097fed602254/visuality\\\n            -logo.svg\"\n\n        - name: \"Manas\"\n          badge: \"\"\n          website: \"https://manas.tech\"\n          slug: \"manas-tech\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MjQ0LCJwdXIiOiJibG9iX2lkIn19--216ad1458f0e457a31351694b20a2010c3eca610/manas-log\\\n            o.svg\"\n\n    - name: \"Community partners\"\n      description: |-\n        Community partners section showing various community organizations and companies supporting the event.\n      level: 3\n      sponsors:\n        - name: \"Ruby Community Conference\"\n          badge: \"\"\n          website: \"https://www.rubycommunityconference.com\"\n          slug: \"ruby-community-conference\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MzIsInB1ciI6ImJsb2JfaWQifX0=--aeaa51951de5ad099484406c7fd757b0caa9d3ee\\\n            /eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOls1MDAsNTAwXX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--1af0099157b76e9cbcc497a0d35cdb95437cfe52/rubycommuni\\\n            tyconference.png\"\n\n        - name: \"Friendly.rb\"\n          badge: \"\"\n          website: \"https://friendlyrb.com/\"\n          slug: \"friendlyrb\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MzQsInB1ciI6ImJsb2JfaWQifX0=--5329076cb56b04afde34393156a73c9a8ca34cc2\\\n            /eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOls1MDAsNTAwXX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--1af0099157b76e9cbcc497a0d35cdb95437cfe52/friendlyrb.\\\n            png\"\n\n        - name: \"Openfest\"\n          badge: \"\"\n          website: \"https://www.openfest.org\"\n          slug: \"openfest\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MzUsInB1ciI6ImJsb2JfaWQifX0=--63cf73086c2ff7092f47545e60f4403d7dcfac21\\\n            /eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOls1MDAsNTAwXX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--1af0099157b76e9cbcc497a0d35cdb95437cfe52/openfest.pn\\\n            g\"\n\n        - name: \"Puzl\"\n          badge: \"\"\n          website: \"https://puzl.com/\"\n          slug: \"puzl\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MzYsInB1ciI6ImJsb2JfaWQifX0=--6128ffd728c1bfec82983c3ca5ebd14e50d6ca6f\\\n            /eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOls1MDAsNTAwXX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--1af0099157b76e9cbcc497a0d35cdb95437cfe52/puzl.png\"\n\n        - name: \"Baltic Ruby\"\n          badge: \"\"\n          website: \"https://balticruby.org\"\n          slug: \"baltic-ruby\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MjMwLCJwdXIiOiJibG9iX2lkIn19--d27235c0c572d2dafd5ae8aa5b511f1f8f65ac4b\\\n            /eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOls1MDAsNTAwXX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--1af0099157b76e9cbcc497a0d35cdb95437cfe52/Baltic_Ruby\\\n            _logo_blue.png\"\n\n        - name: \"Digger Video\"\n          badge: \"\"\n          website: \"\"\n          slug: \"digger-video\"\n          logo_url:\n            \"https://2025.balkanruby.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6Mjc2LCJwdXIiOiJibG9iX2lkIn19--b05b01f34a32a3eadd482786b8b0f0f23d58b5c4\\\n            /eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOls1MDAsNTAwXX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--1af0099157b76e9cbcc497a0d35cdb95437cfe52/digger-vide\\\n            o.png\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2025/venue.yml",
    "content": "---\nname: \"World Trade Center (WTC) Interpred\"\n\naddress:\n  street: \"1040, ж.к. Изгрев, бул. „Драган Цанков“ 36, 1113 София\"\n  city: \"Sofia\"\n  region: \"Sofia City Province\"\n  postal_code: \"1113\"\n  country: \"Bulgaria\"\n  country_code: \"BG\"\n  display: 'g.k. Izgrev, bul. \"Dragan Tsankov\" 36, 1113 Sofia, Bulgaria'\n\ncoordinates:\n  latitude: 42.6701698\n  longitude: 23.3508864\n\nmaps:\n  google: \"https://maps.google.com/?q=World+Trade+Center+(WTC)+Interpred,+Sofia,42.6701698,23.3508864\"\n  apple: \"https://maps.apple.com/?q=World+Trade+Center+(WTC)+Interpred,+Sofia&ll=42.6701698,23.3508864\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=42.6701698&mlon=23.3508864\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2025/videos.yml",
    "content": "---\n# Website: https://balkanruby.com\n# Schedule: https://balkanruby.com\n\n## Day 1 - 2025-04-25\n\n# Registration\n\n# Introduction\n\n- id: \"andrey-sitnik-balkan-ruby-2025\"\n  title: \"Privacy-first architecture\"\n  raw_title: \"Andrey Sitnik - Privacy-first architecture\"\n  speakers:\n    - Andrey Sitnik\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-25\"\n  published_at: \"2025-05-01\"\n  description: |-\n    Why and how modern developers could increase the privacy of modern Web.\n\n    The popularity of clouds, the rise of huge monopolies across the internet, and the growth of shady data brokers recently have made the world a much more dangerous place for ordinary people—here is how we fix it.\n\n    In this talk, Andrey Sitnik, the creator of PostCSS and the privacy-first open-source RSS reader, will explain how we can stop this dangerous trend and make the web a private place again. — Beginners will find simple steps, which can be applied to any website — Advanced developers will get practical insights into new local-first architecture — Privacy experts could find useful unique privacy tricks from a global world perspective and beyond just U.S. privacy risks\n\n    https://evilmartians.com/events/privacy-first-architecture-balkanruby\n  video_provider: \"youtube\"\n  video_id: \"dPvX3u8BI2U\"\n\n# Break\n\n- id: \"jasveen-sandral-balkan-ruby-2025\"\n  title: \"The Long Game: Building for Forever in Ruby Core\"\n  raw_title: \"Jasveen Sandral - The Long Game: Building for Forever in Ruby Core\"\n  speakers:\n    - Jasveen Sandral\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-25\"\n  published_at: \"2025-05-02\"\n  description: |-\n    When you contribute to Ruby Core, you're not just writing code for today - you're crafting an API that could be used for decades. Through the journey of implementing CSV::TSV in Ruby's standard library, I'll share critical insights about long-term thinking in core development.\n\n    Key aspects we'll explore: - Why seemingly simple features (like TSV support) can take months to get right - How decisions made today impact thousands of developers for years to come - Real examples of API design choices that aged well (and some that didn't) - Balancing backward compatibility with modern expectations - Cross-cultural collaboration in long-term open-source maintenance\n\n    You'll learn: - Practical strategies for designing APIs that stand the test of time - How to make breaking changes without breaking the community's trust.\n  video_provider: \"youtube\"\n  video_id: \"4QCnyAYMKjE\"\n\n# Break\n\n- id: \"denitsa-belogusheva-balkan-ruby-2025\"\n  title: \"Adapting and Thriving: Insights from a 16-Year Project Journey\"\n  raw_title: \"Denitsa Belogusheva - Adapting and Thriving: Insights from a 16-Year Project Journey\"\n  speakers:\n    - Denitsa Belogusheva\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-25\"\n  published_at: \"2025-05-02\"\n  description: |-\n    In this talk, I’ll share insights from my 16-year journey with a long-term project and discuss sustained work's technical and personal challenges.\n\n    From evolving technologies and legacy code to managing team dynamics, burnout, and the shifting needs of stakeholders. We’ll dive into how long-term projects build resilience, creativity, and humility and how the project and its stakeholders evolve.\n  video_provider: \"youtube\"\n  video_id: \"efAb_r7DRQs\"\n\n# Lunch Break\n\n- id: \"micha-cicki-balkan-ruby-2025\"\n  title: \"Shit Happens: Handling Mistakes 101\"\n  raw_title: \"Michał Łęcicki - Shit Happens: Handling Mistakes 101\"\n  speakers:\n    - \"Michał Łęcicki\"\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-25\"\n  published_at: \"2025-05-02\"\n  description: |-\n    Let’s face it: programmers make mistakes. Some are minor, some are hilarious, and some can lead to disaster. But how we handle those mistakes can make all the difference - not just in the moment, but for the long-term success of our teams.\n  video_provider: \"youtube\"\n  video_id: \"0CuW5mvhZpY\"\n\n# Break\n\n- id: \"franz-fischbach-balkan-ruby-2025\"\n  title: \"CodeTracer, A new way to debug\"\n  raw_title: \"Franz Fischbach and Stanislav Vasilev - CodeTracer, A new way to debug Ruby\"\n  speakers:\n    - Franz Fischbach\n    - Stanislav Vasilev\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-25\"\n  published_at: \"2025-05-02\"\n  description: |-\n    CodeTracer is a powerful, open-source, time-traveling debugger designed to revolutionize debugging for Ruby and other programming languages. Unlike traditional debuggers, CodeTracer records the execution of a program into a self-contained trace file, allowing developers to replay, analyze, and debug issues effortlessly.\n\n    https://github.com/metacraft-labs/codetracer\n  video_provider: \"youtube\"\n  video_id: \"PkvZxHv9u3g\"\n  additional_resources:\n    - name: \"metacraft-labs/codetracer\"\n      type: \"repo\"\n      url: \"https://github.com/metacraft-labs/codetracer\"\n\n# Break\n\n- id: \"martin-verzilli-balkan-ruby-2025\"\n  title: \"Sometimes you need to change to stay the same\"\n  raw_title: \"Martin Verzilli - Sometimes you need to change to stay the same\"\n  speakers:\n    - Martin Verzilli\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-25\"\n  published_at: \"2025-05-02\"\n  description: |-\n    Next September, the Crystal programming language will turn 13 years old. I was there when it was born as a fun experiment, and I'm still there 13 years later, as it continues to develop into a proud descendant of our beloved Ruby. I'm going to share a handful of stories of key decisions we had to made along these years to guarantee its continued existence. I want us all to smile at the sweet irony that, often times, embracing change is our best chance at building somewhat permanent things in a fundamentally impermanent world.\n  video_provider: \"youtube\"\n  video_id: \"D4i-tsQ8E68\"\n\n## Day 2 - 2025-04-26\n\n# Breakfast\n\n# Introduction\n\n- id: \"yaroslav-shmarov-balkan-ruby-2025\"\n  title: \"Staying competitive\"\n  raw_title: \"Yaroslav Shmarov - Staying competitive\"\n  speakers:\n    - Yaroslav Shmarov\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-26\"\n  published_at: \"2025-05-05\"\n  description: |-\n    As a developer\n\n    Embrace AI coding tools. Buy a Cursor subscription. Your most productive peers use it. Business cares about delivering results, not your artisanship.\n\n    As a job applicant\n\n    Remote work = much more competition for a job. Last month I posted on Linkedin that I am looking for a Ruby dev. I had over 500 applications. How can I choose?! Stand out. Write a \"Today I learned\", \"notes to self\" blog. Create a few youtube videos. Hundreds of Ruby devs have created videos. Are you a Web developer? Do you have at least one web app running on your own? (Not client work?) You must have a portfolio. Visit conferences. Make connections. I found all my best jobs over the last 4 years via connections.\n\n    As a content creator\n\n    Most of my old videos can be answered by ChatGPT. But do you know what question you want to ask? Inform about the general concepts, and the learner can use AI to dive into details. Focus on value, not technical details. Before: \"How to use gem Friendly ID\"? After: \"Use friendly urls for better SEO\".\n\n    Cohorts have unique value over self-paced learning.\n\n    Create videos about multi-tool integrations, that require to click through multiple screens (example: apple oauth setup)\n  video_provider: \"youtube\"\n  video_id: \"VfrjNufF_Fg\"\n\n# Break\n\n- id: \"jeremy-smith-balkan-ruby-2025\"\n  title: \"In Limbo: Managing Transitional States\"\n  raw_title: \"Jeremy Smith - In Limbo: Managing Transitional States\"\n  speakers:\n    - \"Jeremy Smith\"\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-26\"\n  published_at: \"2025-05-05\"\n  description: |-\n    \"We're switching to a new CSS framework.\" \"Billing needs to be decoupled from the user model.\" \"The team has decided to change authorization libraries.\" \"We have to refactor that critical data process with low test coverage.\"\n\n    Over a web application's lifespan, many changes to code and data cannot (or should not) be made in one deployment. These complex, incremental transitions often need to be interleaved with feature development and other work.\n\n    How do developers manage these limbo states? How do teams ensure they arrive at their destination safely? In this talk, we'll investigate different transitions within Rails applications, including changes to dependencies, modeling/architecture, and data processing. We'll uncover some underlying principles and practices to help us succeed when managing transitions in our software systems.\n  video_provider: \"youtube\"\n  video_id: \"weIbPgDdlQo\"\n\n# Break\n\n- id: \"stefan-kanev-balkan-ruby-2025\"\n  title: \"The Joy and Agony of GraphQL\"\n  raw_title: \"Stefan Kanev - The Joy and Agony of GraphQL\"\n  speakers:\n    - Stefan Kanev\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-26\"\n  published_at: \"2025-05-05\"\n  description: |-\n    Stefan Kanev is a CTO at Dext and a host of https://tilde-slash.fm.\n  video_provider: \"youtube\"\n  video_id: \"tTCeLE2GpeQ\"\n\n# Lunch Break\n\n- id: \"julia-lpez-balkan-ruby-2025\"\n  title: \"Beyond the Hype: Practical lessons in Long-Term Rails\"\n  raw_title: \"Julia Lopez - Beyond the Hype: Practical lessons in Long-Term Rails maintenance\"\n  speakers:\n    - Julia López\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-26\"\n  published_at: \"2025-05-05\"\n  slides_url: \"https://speakerdeck.com/yukideluxe/beyond-the-hype-practical-lessons-in-long-term-rails-maintenance\"\n  description: |-\n    Beyond the Hype: Practical lessons in Long-Term Rails maintenance\n\n    New Rails features like Hotwire, Kamal, and Solid AllTheThings are super cool, but not everyone uses them daily. Many of us work on Rails apps that have grown large and complex. To keep these apps thriving, we need to stay up to date, deal with technical debt, and add new features that are important for our business needs while ensuring nothing breaks for our customers.\n\n    In this talk, I’ll give you a real-life look at how a small team of engineers keeps an almost 20-year-old monolithic Rails application at Harvest running strong and ready for the future. I’ll share how our workflows have changed (like how we write PR descriptions or how we advocate for refactoring through exploration), how we stay up to date with Rails updates (including why we chose to utilize new out-of-the-box technologies and why we decided to keep older libraries in other situations), and the practical lessons and strategies we use to keep things running smoothly, like observability, feature flags, and other utils and gems like scientist.\n  video_provider: \"youtube\"\n  video_id: \"uublj1pAkOg\"\n\n# Break\n\n- id: \"pawe-strzakowski-balkan-ruby-2025\"\n  title: \"Creativity: The only skill you need in the long\"\n  raw_title: \"Pavel Strzalkowski - Creativity: The only skill you need in the long term\"\n  speakers:\n    - Paweł Strzałkowski\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-26\"\n  published_at: \"2025-05-05\"\n  description: |-\n    How does a developer fit into IT after turning 40 or 50? Would they still have the stamina to learn and keep up? With over two decades of experience in web development, I can confidently say that one skill remains in constant demand: creativity. You may write in Ruby, JavaScript, Swift, or Python. An engineering mindset combined with creativity can solve any problem and position you as a leader in any field. This presentation addresses this topic and offers an entertaining, live demonstration of creative possibilities for the upcoming years—leveraging a combination of Ruby, Rails, and large language models (e.g., GPT-4). It shows that it is easy to implement features such as voice control and image recognition in Ruby. Showcases how the Ruby ecosystem gives a creative advantage in the long term.\n  video_provider: \"youtube\"\n  video_id: \"wSTopJCS3Iw\"\n\n# Break\n\n- id: \"bozhidar-batsov-balkan-ruby-2025\"\n  title: \"Ruby Got it Right: Lessons in Innovation for Everyone\"\n  raw_title: \"Bozhidar Batsov - Ruby Got it Right: Lessons in Innovation for Everyone\"\n  speakers:\n    - \"Bozhidar Batsov\"\n  event_name: \"Balkan Ruby 2025\"\n  date: \"2025-04-26\"\n  published_at: \"2025-05-05\"\n  description: |-\n    Bozhidar is the author of RuboCop and the editor of the community Ruby style guide. He's involved in a myriad of open-source projects, mostly related to Ruby, Clojure and Emacs. Many people would probably describe him as an Emacs zealot (and they would be right)\n  video_provider: \"youtube\"\n  video_id: \"riiGCpRmxH4\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2026/cfp.yml",
    "content": "---\n- link: \"https://forms.gle/Xe2KfxiSCzUb8nqE7\"\n  open_date: \"2025-11-13\"\n  close_date: \"2026-02-09\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2026/event.yml",
    "content": "---\nid: \"balkanruby-2026\"\ntitle: \"Balkan Ruby 2026\"\ndescription: \"\"\nlocation: \"Sofia, Bulgaria\"\nkind: \"conference\"\nstart_date: \"2026-05-15\"\nend_date: \"2026-05-16\"\nwebsite: \"https://balkanruby.com\"\ntickets_url: \"https://balkanruby.com/checkouts\"\ntwitter: \"balkanruby\"\nbanner_background: \"#FDF1F3\"\nfeatured_background: \"#FDF1F3\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 42.6799413\n  longitude: 23.3206872\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2026/venue.yml",
    "content": "---\nname: 'National Museum \"Earth and Man\"'\n\naddress:\n  street: \"4 Cherni Vrah Blvd\"\n  city: \"Sofia\"\n  region: \"\"\n  postal_code: \"\"\n  country: \"Bulgaria\"\n  country_code: \"BG\"\n  display: 'g.k. Lozenets, Blvd. \"Cherni vrah\" 4, 1421 Sofia, Bulgaria'\n\ncoordinates:\n  latitude: 42.6799413\n  longitude: 23.3206872\n\nmaps:\n  google: 'https://maps.google.com/?q=National+Museum+\"Earth+and+Man\"+in+Sofia,42.6799413,23.3206872'\n  apple: 'https://maps.apple.com/?q=National+Museum+\"Earth+and+Man\"+in+Sofia&ll=42.6799413,23.3206872'\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=42.6799413&mlon=23.3206872\"\n"
  },
  {
    "path": "data/balkanruby/balkanruby-2026/videos.yml",
    "content": "# TODO: Add talks and videos\n# TODO: Add videos - docs/ADDING_VIDEOS.md\n# TODO: Order when Schedule comes out\n#\n# Website: https://balkanruby.com\n# Videos: -\n---\n- id: \"onur-ozer-balkanruby-2026\"\n  title: \"Your tech stack doesn't matter\"\n  speakers:\n    - Onur Özer\n  date: \"2026-05-15\"\n  video_provider: \"scheduled\"\n  video_id: \"onur-ozer-balkanruby-2026\"\n  description: |-\n    If your goal is building an online business, your tech stack doesn't really matter. There are so many other things you need to get right first, such as finding the right market, positioning effectively, and providing a great user experience. And as tech gets further commoditized, even more so with AI, your tech stack is going to matter even less. And when it does matter, Rails is good enough.\n  additional_resources:\n    - name: \"Blog Post\"\n      title: \"Rails is Good Enough\"\n      type: \"article\"\n      url: \"https://onurozer.me/rails-is-good-enough/\"\n\n- id: \"vladimir-dementyev-balkanruby-2026\"\n  title: \"Drop your app/services!\"\n  description: |-\n    Remove your app/services folder! Let your models model.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Vladimir Dementyev\n  video_provider: \"scheduled\"\n  video_id: \"vladimir-dementyev-balkanruby-2026\"\n\n- id: \"jean-boussier-balkanruby-2026\"\n  title: \"Multiprocessing is the most efficient way to serve Rails apps\"\n  description: |-\n    You've been wondering how many threads Puma should be configured to use, or how much cool stuff you'll be able to build once you've migrated to use fibers and async?\n\n    I'll show you how to stop worrying about all that, and significantly improve performance and developer experience by embracing good old multi-processing.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Jean Boussier\n  video_provider: \"scheduled\"\n  video_id: \"jean-boussier-balkanruby-2026\"\n\n- id: \"stephen-margheim-balkanruby-2026\"\n  title: \"Plain and .css can be beautiful\"\n  description: |-\n    TODO: Plain and .css can be beautiful description\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Stephen Margheim\n  video_provider: \"scheduled\"\n  video_id: \"stephen-margheim-balkanruby-2026\"\n\n- id: \"hans-schnedlitz-balkanruby-2026\"\n  title: \"Gems Are Overrated: or How I Learned to Stop Worrying and Love Copy-Pasting\"\n  description: |-\n    When I started working with Ruby, I embraced its rich ecosystem. My Gemfile for any new project immediately grew longer than Gandalf's beard. Unfortunately, using Gems comes with downsides. On the practical side, pulling in third-party libraries exposes your app to supply-chain attacks that are increasingly common. However, what's even worse is that most Gems are pure bloatware. They add thousands of lines of code you'll never need, and churn constantly.\n\n    The alternative, obviously, is to build everything from scratch. In this talk, we'll look at some examples of how some well-known gems can be boiled down to a single file that you can copy-paste to any new project. We'll also look at the limits of this approach, and when you actually should reach for that Gem.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Hans Schnedlitz\n  video_provider: \"scheduled\"\n  video_id: \"hans-schnedlitz-balkanruby-2026\"\n\n- id: \"bernard-banta-balkanruby-2026\"\n  title: \"Sanarei: Offline Web Browsing with Ruby\"\n  description: |-\n    This talk introduces Sanarei, a Ruby middleware that leverages USSD to enable offline-friendly web experiences on basic mobile phones. Attendees will learn how to build web applications that function without internet access and how to extend digital services to billions of underserved users worldwide. Discover how Ruby can help drive meaningful financial and digital inclusion.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Bernard Banta\n  video_provider: \"scheduled\"\n  video_id: \"bernard-banta-balkanruby-2026\"\n\n- id: \"tsvetelina-borisova-balkanruby-2026\"\n  title: \"Why We Talk About Tools and Not About Humans in Tech\"\n  description: |-\n    The tech industry excels at talking about tools.\n\n    We analyze frameworks, architectures, performance, and scalability in great detail. But when it comes to the human side of our work — power, emotional responsibility, communication, and impact — the conversation often becomes vague or uncomfortable.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Tsvetelina Borisova\n  video_provider: \"scheduled\"\n  video_id: \"tsvetelina-borisova-balkanruby-2026\"\n\n- id: \"roman-samoilov-balkanruby-2026\"\n  title: \"Rage Under the Hood: Breaking Rack and Embracing Fibers\"\n  description: |-\n    \"Ruby is not dead\" has become the ecosystem's favourite reassurance. It's also the wrong conversation. Ruby is alive — but companies are still leaving, and the reasons are concrete: blocking I/O by default, framework overhead that's become Ruby's reputation, and generic abstractions that prioritise backend-swappability.\n\n    Rails.cache, Active Job, the Rack interface itself — these are designed to work with everything, which means they're optimised for nothing.\n\n    This talk introduces Rage, a framework that takes the opposite approach: every layer is purpose-built for a fiber-based, single-process runtime. No generic adapters but tailored solutions for a specific architecture. Rage challenges the status quo by coupling directly with the web server and leveraging the Fiber Scheduler to achieve asynchronous I/O that feels synchronous to write. In this talk, we'll open up the framework and look at the decisions inside:\n\n    The \"Synchronous Illusion\" — how Rage lets developers write linear Ruby that executes asynchronously, with no callbacks and no new syntax.\n    \"Promise.all\" style concurrency using Ruby Fibers — and the scheduler mechanics that make it possible.\n    What we learned by replacing ActiveRecord's connection pool — and how it unlocked a 2.6x throughput gain in CPU-bound workloads.\n    Real-world load tests comparing Rage against standard Rails setups under sustained heavy traffic.\n\n    This talk is for anyone who believes Ruby's best days aren't behind it — but only if we're willing to rethink the foundations.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Roman Samoilov\n  video_provider: \"scheduled\"\n  video_id: \"roman-samoilov-balkanruby-2026\"\n\n- id: \"galia-kraicheva-balkanruby-2026\"\n  title: \"Stop Tuning Hyperparameters. Start Looking at Your Data.\"\n  description: |-\n    Why do so many AI projects fail — even with fancy models and impressive metrics?\n\n    Because we obsess over algorithms and ignore the one thing that actually matters: the data.\n\n    In this talk, we'll challenge the \"model-first\" mindset that dominates modern data science. Instead of jumping straight to XGBoost, deep learning, or the latest AI trend, we'll step back and ask a simpler question: Have we actually looked at our data?\n\n    We'll talk about how skipping proper exploratory data analysis leads to false confidence, hidden leakage, biased predictions, and systems that work great in a notebook… and fall apart in production. Through practical examples and clear principles, I'll argue that understanding your data-generating process is more valuable than any hyperparameter search strategy.\n\n    Better models don't start with better tuning. They start with better questions.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Galia Kraicheva\n  video_provider: \"scheduled\"\n  video_id: \"galia-kraicheva-balkanruby-2026\"\n\n- id: \"giovanni-panasiti-balkanruby-2026\"\n  title: \"Rails Engines Are the Best-Kept Secret (And You're Using Them Wrong)\"\n  description: |-\n    Rails engines are the most powerful architectural tool Rails gives you. After 5+ years building engines in production (including the 440+ star Active Storage Dashboard), I've learned that engines aren't just \"gems with views.\" They're the missing piece between \"monolith that's getting painful\" and \"let's rewrite everything as microservices.\" In this talk, I want to share the patterns that work, the mistakes that will ruin your week, and my zero-dependency philosophy that keeps engines maintainable for years. I'll also introduce ActiveCanvas a new open-source Rails engine that is a CMS/builder where marketing views can be dynamically changed by the marketing team without requiring too much html knowledge and without redeploy every time. Hot take: You don't need microservices. You don't need a team of ten. You need engines.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Giovanni Panasiti\n  video_provider: \"scheduled\"\n  video_id: \"giovanni-panasiti-balkanruby-2026\"\n\n- id: \"fernando-martinez-balkanruby-2026\"\n  title: \"Ruby off Rails\"\n  description: |-\n    Rails was key in Ruby's rise to fame, but there's much more you can do with it, so much it does not fit in a talk, but let's see an example building a ruby cli utility with the tools we don't use every day.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Fernando Martínez\n  video_provider: \"scheduled\"\n  video_id: \"fernando-martinez-balkanruby-2026\"\n\n- id: \"wojtek-wrona-balkanruby-2026\"\n  title: \"From PostgreSQL to SQLite in Rails: Our Migration Journey, Challenges, and Lasting Trade-Offs\"\n  description: |-\n    SQLite's rise in production use - boosted by recent Rails improvements - has caught many developers' attention. But beyond the buzz, what does it take to migrate a Rails app from PostgreSQL, and what trade-offs come with it?\n\n    In this talk, I'll share our real-world migration story: the incremental process we followed, the challenges we faced, and the ongoing post-migration quirks you'll need to accept.\n\n    Whether you're drawn to the promise of a simpler, more cost-effective setup or are cautious about potential compromises, you'll leave with clear, practical insights.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-15\"\n  speakers:\n    - Wojtek Wrona\n  video_provider: \"scheduled\"\n  video_id: \"wojtek-wrona-balkanruby-2026\"\n"
  },
  {
    "path": "data/balkanruby/series.yml",
    "content": "---\nname: \"Balkan Ruby\"\nwebsite: \"https://balkanruby.com\"\ntwitter: \"balkanruby\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Balkan Ruby\"\ndefault_country_code: \"BG\"\nyoutube_channel_name: \"balkanruby6171\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCR076_JBPtcQKfiwiVOB3Cg\"\n"
  },
  {
    "path": "data/balticruby/balticruby-2024/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/balticruby\"\n  open_date: \"2024-02-26\"\n  close_date: \"2024-04-07\"\n"
  },
  {
    "path": "data/balticruby/balticruby-2024/event.yml",
    "content": "---\nid: \"PLJpWVOZvCYR71MeIykNJoBeIMhJ1G6OcT\"\ntitle: \"Baltic Ruby 2024\"\nkind: \"conference\"\nlocation: \"Malmö, Sweden\"\ndescription: |-\n  Baltic Ruby, Malmö, Sweden. June 13 — 15, 2024.\npublished_at: \"2024-07-25\"\nstart_date: \"2024-06-13\"\nend_date: \"2024-06-15\"\nchannel_id: \"UCyTip8pDXBqTxTR6fDZItDw\"\nyear: 2024\nbanner_background: \"#D9FB6E\"\nfeatured_background: \"#D9FB6E\"\nfeatured_color: \"#4738FF\"\nwebsite: \"https://balticruby.org/archive/2024\"\ncoordinates:\n  latitude: 55.5669988\n  longitude: 12.977422\n"
  },
  {
    "path": "data/balticruby/balticruby-2024/schedule.yml",
    "content": "# Schedule: https://balticruby.org/archive/2024/mainstage\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-06-13\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Door Opening\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening Notes\n\n      - start_time: \"10:00\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:45\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:45\"\n        slots: 1\n\n      - start_time: \"18:30\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Opening Party\n\n      - start_time: \"22:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Wrapping Up\n\n  - name: \"Day 2\"\n    date: \"2024-06-14\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Door Opening\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Org Notes\n\n      - start_time: \"10:00\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:45\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - title: \"OSS Expo & Campfire Sessions\"\n            description: |-\n              Join everyone at our OSS campfires to collaborate on various open-source projects like Hotwire, ActiveRecord, ViewComponent, Litestack, Kommandant, Pundit, LoggableActivity, and Oaken, and engage in discussions with their maintainers about the tools and the problems they solve.\n\n      - start_time: \"18:00\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - Wrapping Up\n\n  - name: \"Day 3\"\n    date: \"2024-06-15\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Door Opening\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Org Notes\n\n      - start_time: \"10:00\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:45\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Closing Notes\n\n      - start_time: \"17:30\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Wrapping Up\n\ntracks: []\n"
  },
  {
    "path": "data/balticruby/balticruby-2024/venue.yml",
    "content": "---\nname: \"MalmöMässan (Malmö Convention Center)\"\n\naddress:\n  street: \"Mässgatan 6\"\n  city: \"Malmö\"\n  region: \"\"\n  postal_code: \"21532\"\n  country: \"Sweden\"\n  country_code: \"SE\"\n  display: \"Mässgatan 6, 215 32 Malmö, Sweden\"\n\nhotels:\n  - name: \"Malmö Arena Hotel\"\n    address:\n      street: \"12 Hyllie Boulevard\"\n      city: \"Malmö\"\n      region: \"Skåne län\"\n      postal_code: \"215 32\"\n      country: \"Sweden\"\n      country_code: \"SE\"\n      display: \"Hyllie Boulevard 12, 215 32 Malmö, Sweden\"\n    distance: \"Near MalmöMässan\"\n    coordinates:\n      latitude: 55.5656778\n      longitude: 12.9760859\n    maps:\n      google: \"https://maps.google.com/?q=Malmö+Arena+Hotel,55.5656778,12.9760859\"\n      apple: \"https://maps.apple.com/?q=Malmö+Arena+Hotel&ll=55.5656778,12.9760859\"\n\ncoordinates:\n  latitude: 55.5669988\n  longitude: 12.977422\n\nmaps:\n  google: \"https://maps.google.com/?q=MalmöMässan+(Malmö+Convention+Center),55.5669988,12.977422\"\n  apple: \"https://maps.apple.com/?q=MalmöMässan+(Malmö+Convention+Center)&ll=55.5669988,12.977422\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=55.5669988&mlon=12.977422\"\n"
  },
  {
    "path": "data/balticruby/balticruby-2024/videos.yml",
    "content": "---\n# Website: https://balticruby.org/archive/2024\n# Schedule: https://balticruby.org/archive/2024/mainstage\n\n## Day 1 - 13.06\n\n# Door Opening\n\n# Opening Notes\n\n- id: \"yukihiro-matz-matsumoto-baltic-ruby-2024\"\n  title: \"Keynote: Second System Syndrome\"\n  raw_title: '\"Second system syndrome\"'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-13\"\n  description: |-\n    Keynote.\n  video_provider: \"youtube\"\n  video_id: \"B0kLnbXEO50\"\n  published_at: \"2024-07-25\"\n\n- id: \"cristian-planas-baltic-ruby-2024\"\n  title: \"2,000 Engineers, 2 Million Lines of Code: The History of a Rails Monolith\"\n  raw_title: '\"2000 engineers, 2 millions lines of code: the history of a Rails monolith\"'\n  speakers:\n    - Cristian Planas\n    - Anatoly Mikhaylov\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-13\"\n  description: |-\n    How to scale an application and a team to manage a global business? This presentation summarizes 10 years of experience in a company that has succeeded by keeping Rails in its core.\n  video_provider: \"youtube\"\n  video_id: \"LaoeB5nYOnI\"\n  published_at: \"2024-07-25\"\n\n- id: \"janis-baiza-baltic-ruby-2024\"\n  title: \"Easy threading with JRuby, is it?\"\n  raw_title: '\"Easy threading with JRuby, is it?\"'\n  speakers:\n    - Janis Baiza\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-13\"\n  description: |-\n    Threading is a known issue with MRI due to Global Interpreter Lock. As JRuby uses Java native threads, in theory, this should be easier and much more effective in JRuby. But is it really so?\n  video_provider: \"youtube\"\n  video_id: \"IjRmrwT9dWY\"\n  published_at: \"2024-07-25\"\n\n# Lunch\n\n- id: \"erica-weistrand-baltic-ruby-2024\"\n  title: \"Ruby off Rails\"\n  raw_title: '\"Ruby off Rails\"'\n  speakers:\n    - Erica Weistrand\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-13\"\n  description: |-\n    In this talk we'll delve into the web frameworks Rails, Hanami and Sinatra and we'll explain how we try to combine the best out of the frameworks to create web apps at 84codes.\n  video_provider: \"youtube\"\n  video_id: \"auRaa-iyrTM\"\n  published_at: \"2024-07-25\"\n\n- id: \"mateusz-woniczka-baltic-ruby-2024\"\n  title: \"Pokedex Chronicles: Part 1 - Database Normalisation, Part 2 - Indexes Strike Back\"\n  raw_title: '\"Pokedex Chronicles: part 1 - database normalisation,part 2 - indexes strike back\"'\n  speakers:\n    - Mateusz Woźniczka\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-13\"\n  description: |-\n    Step into the world of database mastery with our Pokedex adventure! Embark on a journey to unravel the secrets of normalization and indexing, enhancing data integrity, efficiency and performance along the way!\n  video_provider: \"youtube\"\n  video_id: \"xa9ixrLU7X4\"\n  published_at: \"2024-07-25\"\n\n- id: \"tomasz-jozwik-baltic-ruby-2024\"\n  title: \"Mathematical Programming in Ruby\"\n  raw_title: '\"Mathematical Programming in Ruby\"'\n  speakers:\n    - Tomasz Jóźwik\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-13\"\n  description: |-\n    When using math programming, we can achieve optimal solutions for complex problems by defining them with math equations. We'll try to use this approach in Ruby to solve a real-life problem.\n  video_provider: \"youtube\"\n  video_id: \"rKkvr0wQb2k\"\n  published_at: \"2024-07-25\"\n\n- id: \"stephen-margheim-baltic-ruby-2024\"\n  title: \"Solid SQLite Apps on Rails\"\n  raw_title: '\"Solid SQLite Apps on Rails\"'\n  speakers:\n    - Stephen Margheim\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-13\"\n  slides_url: \"https://speakerdeck.com/fractaledmind/solid-sqlite-apps-on-rails\"\n  description: |-\n    Join me to learn how to pair the enhancements to Rails’ SQLite adapter with the suite of Solid libraries to create resilient, high-performance production apps.\n  video_provider: \"youtube\"\n  video_id: \"_F02oXFSfX8\"\n  published_at: \"2024-07-25\"\n\n# Opening Party\n\n# Wrapping Up\n\n## DAY 2 - 14.06\n\n# DOOR OPENING\n\n# ORG NOTES\n\n- id: \"samuel-giddins-baltic-ruby-2024\"\n  title: \"Keynote: What it takes to keep Ruby gems a thing\"\n  raw_title: '\"What it takes to keep Ruby gems a thing\"'\n  speakers:\n    - Samuel Giddins\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-14\"\n  description: |-\n    Keynote.\n  video_provider: \"youtube\"\n  video_id: \"W21O4i1znLE\"\n  published_at: \"2024-07-25\"\n\n- id: \"jan-krutisch-baltic-ruby-2024\"\n  title: \"Going back to the BASICs\"\n  raw_title: '\"Going back to the BASICs\"'\n  speakers:\n    - Jan Krutisch\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-14\"\n  description: |-\n    BASIC was once the most important programming language on home computers. Let's re-implement it in Ruby, learn some history on how computers worked back then and a few tricks along the way.\n  video_provider: \"youtube\"\n  video_id: \"UEoE87WBLac\"\n  published_at: \"2024-07-25\"\n\n- id: \"guilherme-carreiro-baltic-ruby-2024\"\n  title: \"Building native Ruby extensions in Rust\"\n  raw_title: '\"Building native Ruby extensions in Rust\"'\n  speakers:\n    - Guilherme Carreiro\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-14\"\n  description: |-\n    When we occasionally reach the limits of Ruby and need the power of native extensions, we no longer have to default to C. It's easier than ever to build production-ready Rust native extensions, bringing the best of both ecosystems together!\n  video_provider: \"youtube\"\n  video_id: \"-tM3Npsb2wE\"\n  published_at: \"2024-07-25\"\n\n# LUNCH\n\n# OSS EXPO CAMPFIRE SESSIONS\n\n# WRAPPING UP\n\n## Day 3 - 15.06\n\n# DOOR OPENING\n\n# ORG NOTES\n\n- id: \"panel-baltic-region-communities-baltic-ruby-2024\"\n  title: 'Panel: Baltic Region Communities - \"Renaissance or Die\"'\n  raw_title: 'PANEL DISCUSSION OF BALTIC REGION COMMUNITIES \"Renaissance or Die\"'\n  speakers:\n    - James Bell\n    - Chris Mckenzie\n    - Aurora Nockert\n    - Mariusz Kozieł\n    - Janis Baiza\n    - Jan Krutisch\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-15\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"panel-baltic-region-communities-baltic-ruby-2024\"\n\n- id: \"radoslav-stankov-baltic-ruby-2024\"\n  title: \"How to get to zero unhandled exceptions in production\"\n  raw_title: '\"How to get to zero unhandled exceptions in production\"'\n  speakers:\n    - Radoslav Stankov\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-15\"\n  description: |-\n    Exceptions in production seem like something unavoidable. But does it have to be? I don't think so. If you have the right process and tooling, you can avoid them.\n  video_provider: \"youtube\"\n  video_id: \"4iQHtPrf8wI\"\n  published_at: \"2024-07-25\"\n\n- id: \"tim-kchele-baltic-ruby-2024\"\n  title: \"How to build an exchange\"\n  raw_title: '\"How to build an exchange\"'\n  speakers:\n    - Tim Kächele\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-15\"\n  description: |-\n    They say working in finance is boring, but is it really? Let's learn how to build an exchange system in Ruby and solve interesting computer science problems along the way.\n  video_provider: \"youtube\"\n  video_id: \"mZzIJ4QpQck\"\n  published_at: \"2024-07-25\"\n\n# Lunch\n\n- id: \"daniel-magliola-baltic-ruby-2024\"\n  title: \"What does high priority mean? The secret to happy queues\"\n  raw_title: '\"What does \"high priority\" mean? The secret to happy queues\"'\n  speakers:\n    - Daniel Magliola\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-15\"\n  description: |-\n    In this talk, I will present a latency-focused approach to managing your queues reliably, keeping your jobs flowing and your users happy.\n  video_provider: \"youtube\"\n  video_id: \"U80H3bagJDk\"\n  published_at: \"2024-07-25\"\n\n- id: \"jeremy-smith-baltic-ruby-2024\"\n  title: \"Refactoring Volatile Views into Cohesive Components\"\n  raw_title: '\"Refactoring Volatile Views into Cohesive Components\"'\n  speakers:\n    - Jeremy Smith\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-15\"\n  slides_url: \"https://speakerdeck.com/jeremysmithco/refactoring-volatile-views-into-cohesive-components\"\n  description: |-\n    It's easy for models to grow unwieldy, accumulating methods, attributes, and responsibilities. But views can be even worse. Let's refactor the mess into clean, cohesive components with ViewComponent.\n  video_provider: \"youtube\"\n  video_id: \"6tPz5_iXK38\"\n  published_at: \"2024-07-25\"\n\n- id: \"tobias-pfeiffer-baltic-ruby-2024\"\n  title: \"Stories in Open Source\"\n  raw_title: '\"Stories in Open Source\"'\n  speakers:\n    - Tobias Pfeiffer\n  event_name: \"Baltic Ruby 2024\"\n  date: \"2024-06-15\"\n  description: |-\n    Walk with me through some stories that I experienced in Open Source, the friends made and the lessons learned along the way. Let it help you make your own Open Source contributions!\n  video_provider: \"youtube\"\n  video_id: \"C5ZwxCV_-qk\"\n  published_at: \"2024-07-25\"\n\n# Closing Notes\n\n# Wrapping Up\n\n## Extras\n\n- id: \"yukihiro-matz-matsumoto-baltic-ruby-2024-interview-with-matz\"\n  title: \"Interview with Matz\"\n  raw_title: \"Interview with Yukihiro Matz Matsumoto at Baltic Ruby\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n    - Sergy Sergyenko\n  event_name: \"Baltic Ruby 2024\"\n  kind: \"interview\"\n  date: \"2024-06-15\"\n  published_at: \"2024-11-22\"\n  description: |-\n    An interview with Yukihiro Matsumoto about Ruby, the community, his profession, and personal life, which he gave at the Baltic Ruby conference in Malmö in 2024.\n  video_provider: \"youtube\"\n  video_id: \"iwDJ6zmuI_w\"\n"
  },
  {
    "path": "data/balticruby/balticruby-2025/cfp.yml",
    "content": "---\n- link: \"https://papercall.io/balticruby25\"\n  open_date: \"2024-11-25\"\n  close_date: \"2025-02-01\"\n"
  },
  {
    "path": "data/balticruby/balticruby-2025/event.yml",
    "content": "---\nid: \"balticruby-2025\"\ntitle: \"Baltic Ruby 2025\"\nkind: \"conference\"\nlocation: \"Riga, Latvia\"\ndescription: |-\n  Baltic Ruby, Riga, Latvia. Show The Diff. June 12 — 14, 2025.\nstart_date: \"2025-06-12\"\nend_date: \"2025-06-14\"\nchannel_id: \"UCyTip8pDXBqTxTR6fDZItDw\"\nyear: 2025\nbanner_background: \"#22175F\"\nfeatured_background: \"#22175F\"\nfeatured_color: \"#D9FB6E\"\nwebsite: \"https://balticruby.org\"\ncoordinates:\n  latitude: 56.9637421\n  longitude: 24.134052\n"
  },
  {
    "path": "data/balticruby/balticruby-2025/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 1\"\n    date: \"2025-06-12\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Doors Opening\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Opening Notes\n\n      - start_time: \"09:30\"\n        end_time: \"10:40\"\n        slots: 1\n\n      - start_time: \"10:40\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:20\"\n        slots: 1\n\n      - start_time: \"12:20\"\n        end_time: \"13:00\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:50\"\n        slots: 1\n\n      - start_time: \"14:50\"\n        end_time: \"15:35\"\n        slots: 1\n\n      - start_time: \"15:35\"\n        end_time: \"16:25\"\n        slots: 1\n\n      - start_time: \"16:25\"\n        end_time: \"17:15\"\n        slots: 1\n\n      # - start_time: \"17:15\"\n      #   end_time: \"18:00\"\n      #   slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - IELĪGOŠANA — The Summer Solstice Festival\n\n  - name: \"Day 2\"\n    date: \"2025-06-13\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Doors Opening\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Org Notes\n\n      - start_time: \"11:30\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Junior Bootcamp\n\n      - start_time: \"09:30\"\n        end_time: \"10:40\"\n        slots: 1\n\n      - start_time: \"10:40\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:20\"\n        slots: 1\n\n      - start_time: \"12:20\"\n        end_time: \"13:00\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - Open Source Expo and Workshops\n\n      - start_time: \"19:00\"\n        end_time: \"End\"\n        slots: 1\n        items:\n          - Silent Disco\n\n  - name: \"Day 3\"\n    date: \"2025-06-14\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Doors Opening\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Org Notes\n\n      - start_time: \"10:00\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Junior Bootcamp\n\n      - start_time: \"09:30\"\n        end_time: \"10:20\"\n        slots: 1\n\n      - start_time: \"10:20\"\n        end_time: \"11:10\"\n        slots: 1\n\n      - start_time: \"11:10\"\n        end_time: \"11:55\"\n        slots: 1\n\n      - start_time: \"11:55\"\n        end_time: \"12:35\"\n        slots: 1\n\n      - start_time: \"12:35\"\n        end_time: \"13:35\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:35\"\n        end_time: \"14:25\"\n        slots: 1\n\n      - start_time: \"14:25\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"16:05\"\n        slots: 1\n\n      - start_time: \"16:05\"\n        end_time: \"16:55\"\n        slots: 1\n\n      - start_time: \"16:55\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"End\"\n        slots: 1\n        items:\n          - Baltic Ruby Party\n"
  },
  {
    "path": "data/balticruby/balticruby-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Level Gold\"\n      description: |-\n        Gold level sponsors\n      level: 1\n      sponsors:\n        - name: \"LevelPath\"\n          website: \"https://www.levelpath.com/\"\n          slug: \"LevelPath\"\n          logo_url: \"https://static.tildacdn.net/tild6438-3866-4261-b265-373965333337/svgexport-1_1.svg\"\n\n        - name: \"GoCardless\"\n          website: \"https://gocardless.com/\"\n          slug: \"GoCardless\"\n          logo_url: \"https://thb.tildacdn.net/tild3861-6136-4134-b430-303839383636/-/resize/20x/GoCardless_Wordmark_.png\"\n\n    - name: \"Level Silver\"\n      description: |-\n        Silver level sponsors\n      level: 2\n      sponsors:\n        - name: \"Karnov Group\"\n          website: \"https://www.karnovgroup.com/en/\"\n          slug: \"KarnovGroup\"\n          logo_url: \"https://static.tildacdn.net/tild3331-6131-4535-a666-373164356165/Karnov_Group_logo_1.svg\"\n\n        - name: \"TypeSense\"\n          website: \"https://typesense.org/\"\n          slug: \"TypeSense\"\n          logo_url: \"https://static.tildacdn.net/tild6539-3830-4831-b332-303133646438/Typesense_logo.svg\"\n\n    - name: \"Level Bronze\"\n      description: |-\n        Bronze level sponsors\n      level: 3\n      sponsors:\n        - name: \"EazyBI\"\n          website: \"https://www.eazybi.com/\"\n          slug: \"EazyBI\"\n          logo_url: \"https://static.tildacdn.net/tild6566-3564-4335-b866-383266323163/svgexport-2_2.svg\"\n\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"AppSignal\"\n          logo_url: \"https://static.tildacdn.net/tild3165-3132-4530-b464-333030386163/svgexport-3_1.svg\"\n\n    - name: \"Travel\"\n      description: |-\n        Companies that supported their employees, making it possible for them to speak at Baltic Ruby.\n      level: 4\n      sponsors:\n        - name: \"Dexter\"\n          website: \"https://www.getdexter.co/\"\n          slug: \"Dexter\"\n          logo_url: \"https://static.tildacdn.net/tild6462-3361-4334-a238-383337396261/dexter.svg\"\n\n        - name: \"SkillerWhale\"\n          website: \"https://www.skillerwhale.com/\"\n          slug: \"SkillerWhale\"\n          logo_url: \"https://static.tildacdn.net/tild3334-3331-4033-b034-353266303533/Copy_of_SW_stacked_c.svg\"\n\n        - name: \"2N\"\n          website: \"https://www.2n.pl/\"\n          slug: \"2N\"\n          logo_url: \"https://static.tildacdn.net/tild3839-3363-4531-b338-353863363463/2N_logo___napis.svg\"\n\n        - name: \"Meistertask\"\n          website: \"https://www.meistertask.com/pages/about-us\"\n          slug: \"Meistertask\"\n          logo_url: \"https://static.tildacdn.net/tild3633-6332-4561-b935-616336346661/meister.svg\"\n\n        - name: \"EazyBI\"\n          website: \"https://www.eazybi.com/\"\n          slug: \"EazyBI\"\n          logo_url: \"https://static.tildacdn.net/tild6566-3564-4335-b866-383266323163/svgexport-2_2.svg\"\n\n        - name: \"Visuality\"\n          website: \"https://www.visuality.pl/\"\n          slug: \"Visuality\"\n          logo_url: \"https://static.tildacdn.net/tild3462-3866-4833-b465-363862623063/logo_black.svg\"\n\n        - name: \"Workato\"\n          website: \"https://www.workato.com/\"\n          slug: \"Workato\"\n          logo_url: \"https://static.tildacdn.net/tild6666-3239-4033-b366-373438343061/workato_logo_1.svg\"\n\n        - name: \"Lanes & Planes\"\n          website: \"https://www.lanes-planes.com/\"\n          slug: \"Lanes&Planes\"\n          logo_url: \"https://static.tildacdn.net/tild3935-3138-4134-b230-393535343336/Lanes-Planes_primary.png\"\n\n        - name: \"Scan.com\"\n          website: \"https://scan.com/\"\n          slug: \"Scan.com\"\n          logo_url: \"https://static.tildacdn.net/tild3637-6338-4739-b163-396439613032/scan_com.svg\"\n    # - name: Partners\n    #   description: Those who build the community with us, contributing their time, ideas, or network.\n    #   level: 5\n    #   sponsors:\n    #     - name: Ruby Central\n    #       website: https://rubycentral.org/\n    #       slug: RubyCentral\n    #       logo_url: https://static.tildacdn.net/tild3537-3337-4638-b337-653438373033/Ruby_central_no_padd.png\n    #\n    #     - name: Short Ruby Newsletter\n    #       website: https://newsletter.shortruby.com\n    #       slug: short-ruby-newsletter\n    #       logo_url: https://optim.tildacdn.net/tild3730-6165-4662-b035-306632313861/-/resize/160x/-/format/webp/image.png.webp\n\n    # - name: Friends\n    #   description: Those who do and believe in the same things we do. We love and appreciate you deeply.\n    #   level: 6\n    #   sponsors:\n    #     - name: Malmö.rb\n    #       website: https://malmoruby.se/\n    #       slug: MalmoRB\n    #       logo_url: https://static.tildacdn.net/tild3662-3930-4266-b966-363137393364/MalmoRB_logo.png\n    #\n    #     - name: Vilnius.rb\n    #       website: https://malmoruby.se/\n    #       slug: vilnius-rb\n    #       logo_url: \"\"\n    #\n    #     - name: WrocRB\n    #       website: https://wroclawruby.pl/\n    #       slug: WrocRB\n    #       logo_url: https://static.tildacdn.net/tild3730-6165-4662-b035-306632313861/image.png\n    #\n    #     - name: Ruby Latvia\n    #       website: https://rubylatvia.com/\n    #       slug: RubyLatvia\n    #       logo_url: https://static.tildacdn.net/tild3539-3361-4863-b437-613637373139/Ruby_Latvia.png\n    #\n    #     - name: Copenhagen\n    #       website: https://copenhagen.rb.org/\n    #       slug: Copenhagen\n    #       logo_url: https://static.tildacdn.net/tild3539-3161-4165-a538-616434646430/copenhagen.png\n    #\n    #     - name: KRug\n    #       website: https://k-rug.org/\n    #       slug: KRug\n    #       logo_url: https://static.tildacdn.net/tild3633-3632-4961-a562-613366356137/KRUG_logo_color_02.png\n    #\n    #     - name: Balkan Ruby\n    #       website: https://balkanruby.org/\n    #       slug: BalkanRuby\n    #       logo_url: https://static.tildacdn.net/tild6133-6163-4063-b837-373063643566/balkan_ruby.svg\n    #\n    #     - name: wnb-rb\n    #       website: https://www.wnb-rb.dev/\n    #       slug: wnb-rb\n    #       logo_url: https://static.tildacdn.net/tild3233-6434-4538-a131-623563656434/wnb-rb.svg\n    #\n    #     - name: Helvetic Ruby\n    #       website: https://helveticruby.ch/\n    #       slug: HelveticRuby\n    #       logo_url: https://static.tildacdn.net/tild3635-3238-4366-b437-393633313133/helvetic_ruby.png\n"
  },
  {
    "path": "data/balticruby/balticruby-2025/venue.yml",
    "content": "---\nname: \"Angārs\"\n\naddress:\n  street: \"10 Tallinas iela\"\n  city: \"Rīga\"\n  postal_code: \"1001\"\n  country: \"Latvia\"\n  country_code: \"LV\"\n  display: \"Tallinas iela 10-3, Centra rajons, Rīga, LV-1001, Latvia\"\n\ncoordinates:\n  latitude: 56.9637421\n  longitude: 24.134052\n\nmaps:\n  google: \"https://maps.google.com/?q=Angars,56.9637421,24.134052\"\n  apple: \"https://maps.apple.com/?q=Angars&ll=56.9637421,24.134052\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=56.9637421&mlon=24.134052\"\n"
  },
  {
    "path": "data/balticruby/balticruby-2025/videos.yml",
    "content": "---\n## Day 1 - 2025-06-12\n\n- title: \"Keynote: Programming Language for AI age\"\n  raw_title: \"Keynote by Matz\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    In this keynote, Yukihiro \"Matz\" Matsumoto, the creator of Ruby, explores the ideal programming language for the AI age.\n    Discover the characteristics that make a language fit for modern AI challenges and learn Matz's insights into Ruby's role in this evolving landscape.\n  date: \"2025-06-12\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"XVaRRryB_cQ\"\n  id: \"yukihiro-matz-matsumoto-baltic-ruby-2025\"\n\n- title: \"ActiveRecord Unveiled: Mastering Rails' ORM\"\n  raw_title: \"ACTIVERECORD UNVEILED: MASTERING RAILS' ORM\"\n  speakers:\n    - Jess Sullivan\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    ActiveRecord powers Rails' database magic — but what happens behind the scenes? This talk unpacks how Rails' ORM maps data, revealing the key mechanisms at work.\n  date: \"2025-06-12\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"KxKvUsyQ5Zw\"\n  id: \"jess-sullivan-baltic-ruby-2025\"\n\n- title: \"Failed to Build Gem Native Extension\"\n  raw_title: \"FAILED TO BUILD GEM NATIVE EXTENSION\"\n  speakers:\n    - Youssef Boulkaid\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    This talk demystifies concepts such as native extensions, C Makefiles and compiler flags so you can understand this dreaded error and how to solve it!\n  date: \"2025-06-12\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"E71_StMXI8A\"\n  id: \"youssef-boulkaid-baltic-ruby-2025\"\n\n- title: \"More Ruby, Less Rails: Rediscover the Beauty of Ruby\"\n  raw_title: \"MORE RUBY, LESS RAILS: REDISCOVER THE BEAUTY OF RUBY\"\n  speakers:\n    - Michał Łęcicki\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    I will cover the basic Ruby features and unfamiliar topics, such as Ruby refinements. Be prepared for some eye-opening insights from the Ruby documentation!\n  date: \"2025-06-12\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"mutIIM7Sy9c\"\n  id: \"michal-lecicki-baltic-ruby-2025\"\n\n- title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  speakers:\n    - TODO\n  event_name: \"Baltic Ruby 2025\"\n  description: \"\"\n  date: \"2025-06-12\"\n  video_provider: \"scheduled\"\n  video_id: \"lightning-talks-baltic-ruby-2025\"\n  id: \"lightning-talks-baltic-ruby-2025\"\n\n- title: \"What Software Engineers Can Learn from the Chernobyl Disaster\"\n  raw_title: \"WHAT SOFTWARE ENGINEERS CAN LEARN FROM THE CHERNOBYL DISASTER\"\n  speakers:\n    - Frederick Cheung\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    The Chernobyl disaster sounds remote, but the incredible events around it are full of insights about the everyday challenges we face as developers.\n  date: \"2025-06-12\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"xAP4ha3lpT8\"\n  id: \"frederick-cheung-baltic-ruby-2025\"\n\n- title: \"Event-Sourced Mental Models in Ruby\"\n  raw_title: \"EVENT-SOURCED MENTAL MODELS IN RUBY\"\n  speakers:\n    - Ismael Celis\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    I'll show how Event Sourcing and Ruby can provide a cohesive programming model where auditable data, durable workflows and reactive UIs are the default.\n  date: \"2025-06-12\"\n  published_at: \"2025-09-01\"\n  video_provider: \"youtube\"\n  video_id: \"KKgc5T-qe5w\"\n  id: \"ismael-celis-baltic-ruby-2025\"\n\n- title: \"Fresh Features, Julienne Cut\"\n  raw_title: \"FRESH FEATURES, JULIENNE CUT\"\n  speakers:\n    - Hans Schnedlitz\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    Cooking and software engineering have more in common than you think. For one, both involve cutting things to pieces! In cooking, we slice veggies. In software, we dice features. In this talk, we'll learn how to ship faster by breaking extensive features into manageable chunks.\n  date: \"2025-06-12\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"QMYqMvlrAOs\"\n  id: \"hans-schnedlitz-baltic-ruby-2025\"\n\n## Day 2 - 2025-06-13\n\n- title: \"Keynote: Sustained Open Source\"\n  raw_title: \"SUSTAINED OPEN SOURCE\"\n  speakers:\n    - Marty Haught\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    The power of open source is at the heart of the Ruby ecosystem. Ruby is over 30 years old and RubyGems is over 20 years. We have lasted this far. Are we poised for another 20 years? Marty will explore his views on open source through the lens of sustainability, security, and reliability.\n  date: \"2025-06-13\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"9S6l_RZwuxM\"\n  id: \"marty-haught-baltic-ruby-2025\"\n\n- title: \"Scaling RubyEvents.org: The mission to index all Ruby conferences\"\n  raw_title: \"SCALING RUBYEVENTS.ORG:THE MISSION TO INDEX ALL RUBY CONFERENCES\"\n  speakers:\n    - Marco Roth\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    RubyEvents.org (formerly RubyVideo.dev) is building a complete index of Ruby conference talks! Learn the technical, organizational, and community-driven strategies used to scale this project.\n  date: \"2025-06-13\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"Xk1NdZRN9lA\"\n  id: \"marco-roth-baltic-ruby-2025\"\n  slides_url: \"https://speakerdeck.com/marcoroth/scaling-rubyevents-dot-org-the-mission-to-index-all-ruby-conferences-at-baltic-ruby-2025-riga-latvia\"\n\n- title: \"JRuby Everywhere: Desktop, Server, and Mobile\"\n  raw_title: \"JRUBY EVERYWHERE: DESKTOP, SERVER, AND MOBILE\"\n  speakers:\n    - Charles Nutter\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    With JRuby, you can build cross-platform desktop apps, scalable server apps, and Android mobile apps. Charles Oliver Nutter will show you how to make it happen — and have fun along the way!\n  date: \"2025-06-13\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"JCCKD523Mos\"\n  id: \"charles-oliver-nutter-baltic-ruby-2025\"\n  slides_url: \"https://speakerdeck.com/headius/jruby-everywhere-desktop-server-and-mobile\"\n\n- title: \"Modernising Ruby Systems with Rage\"\n  raw_title: \"MODERNISING RUBY SYSTEMSWITH RAGE\"\n  speakers:\n    - Roman Samoilov\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    Discover the story behind the Rage framework: the challenges it solves for Ruby developers and its impact on real-world systems.\n  date: \"2025-06-13\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"p1pvLZIIReQ\"\n  id: \"roman-samoilov-baltic-ruby-2025\"\n\n# OPEN SOURCE EXPO AND WORKSHOPS\n\n## Day 3 - 2025-06-14\n\n- title: \"Exploring Expressiveness: Creating DSLs in Ruby\"\n  raw_title: \"EXPLORING EXPRESSIVENESS: CREATING DSLS IN RUBY\"\n  speakers:\n    - Steven Baker\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    Ruby's expressiveness, dynamic features, and even cultural norms make it especially well suited for crafting DSLs. We'll explore how\n  date: \"2025-06-14\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"6SYjZGkiwnQ\"\n  id: \"steven-r-baker-baltic-ruby-2025\"\n\n- title: \"Image Vector Search\"\n  raw_title: \"IMAGE VECTOR SEARCH\"\n  speakers:\n    - Chris Hasinski\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    An AI model in my app? No APIs, no Python and no arcane knowledge! A demo on how to build an ONNX-powered unlabeled image recognition with just Ruby.\n  date: \"2025-06-14\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"07LYL8gURx8\"\n  id: \"chris-hasinski-baltic-ruby-2025\"\n\n- title: \"Full Circle: How Modern Ruby Powers the Re-integration of High-Speed Microservices into Rails\"\n  raw_title: \"FULL CIRCLE: HOW MODERN RUBY POWERS THE RE-INTEGRATION OF HIGH-SPEED MICROSERVICES INTO RAILS\"\n  speakers:\n    - Cristian Planas\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    This talk shows how the modern Ruby ecosystems can reintroduce microservices into monoliths, reversing older splits spurred by C-Ruby's constraints.\n  date: \"2025-06-14\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"mRh4Njb20gg\"\n  id: \"cristian-planas-baltic-ruby-2025\"\n\n- title: \"The Boring Bits Bite Back\"\n  raw_title: \"THE BORING BITS BITE BACK\"\n  speakers:\n    - Katie Miller\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    Tech Debt is talked about a lot. Sometimes the debt that builds up comes from the most boring but most crucial areas. Knowing about the traps and keeping those boring parts truly boring can be hugely beneficial. Don't get sidelined from building features that differentiate.\n  date: \"2025-06-14\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"YU3xZFhmxQs\"\n  id: \"katie-miller-baltic-ruby-2025\"\n\n- title: \"Is the Monolith a Problem?\"\n  raw_title: \"IS THE MONOLITH A PROBLEM?\"\n  speakers:\n    - Chikahiro Tokoro\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    This talk shows how the modern Ruby ecosystems can reintroduce microservices into monoliths, reversing older splits spurred by C-Ruby's constraints.\n  date: \"2025-06-14\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"3ENa9Yn8-hk\"\n  id: \"chikahiro-tokoro-baltic-ruby-2025\"\n  slides_url: \"https://speakerdeck.com/kibitan/is-the-monolith-a-problem\"\n\n- title: \"Objects Talking to Objects\"\n  raw_title: \"OBJECTS TALKING TO OBJECTS\"\n  speakers:\n    - Gavin Morrice\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    An exploration of what it means to think in OOP, where process lives, and how to keep complex systems robust, scalable, and flexible.\n  date: \"2025-06-14\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"xow9xfa7qlE\"\n  id: \"gavin-morrice-baltic-ruby-2025\"\n\n- title: \"It Is Not So Bad, After All.\"\n  raw_title: \"IT IS NOT SO BAD, AFTER ALL.\"\n  speakers:\n    - Adam Piotrowski\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    It's easy to complain about your project and envy others for the technology they use or the clients they work with. But let's talk about the funny pathologies of the industry, the weird f*ckups — just so I can remind you that the grass is always greener in the neighbor's courtyard, and your project might not be so bad after all :)\n  date: \"2025-06-14\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"-UKInSuNMnw\"\n  id: \"adam-piotrowski-baltic-ruby-2025\"\n\n- title: \"A Framework for Tech. Debt\"\n  raw_title: \"A FRAMEWORK FOR TECH. DEBT\"\n  speakers:\n    - Christoph Lipautz\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    This talk reveals a framework to tackle technical debt, clear roadblocks, and boost innovation. Learn practical steps to conquer your Ruby legacy!\n  date: \"2025-06-14\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"sQJ0wyVgzYM\"\n  id: \"christoph-lipautz-baltic-ruby-2025\"\n\n- title: \"Keynote: What I Talk About When I Talk About Ruby\"\n  raw_title: \"WHAT I TALK ABOUT WHEN I TALK ABOUT RUBY\"\n  speakers:\n    - Tim Riley\n  event_name: \"Baltic Ruby 2025\"\n  description: |-\n    Our path to a more diverse Ruby, and the rewards from the journey.\n  date: \"2025-06-14\"\n  published_at: \"2025-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"6jUEmcezkBo\"\n  id: \"tim-riley-baltic-ruby-2025\"\n"
  },
  {
    "path": "data/balticruby/balticruby-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://www.papercall.io/balticruby2026\"\n  open_date: \"2025-09-04\"\n  close_date: \"2025-12-31\"\n\n- name: \"Call for Proposals Extension\"\n  link: \"https://www.papercall.io/balticruby2026\"\n  open_date: \"2026-01-05\"\n  close_date: \"2026-01-31\"\n"
  },
  {
    "path": "data/balticruby/balticruby-2026/event.yml",
    "content": "---\nid: \"balticruby-2026\"\ntitle: \"Baltic Ruby 2026\"\nlocation: \"Hamburg, Germany\"\nkind: \"conference\"\ndescription: |-\n  Baltic Ruby, Hamburg Germany. 2026.\nstart_date: \"2026-06-12\"\nend_date: \"2026-06-13\"\nchannel_id: \"UCyTip8pDXBqTxTR6fDZItDw\"\nyear: 2026\nbanner_background: \"#D9FB6E\"\nfeatured_background: \"#D9FB6E\"\nfeatured_color: \"#4738FF\"\nwebsite: \"https://balticruby.org\"\ntickets_url: \"https://pretix.eu/balticruby/hamburg/\"\ncoordinates:\n  latitude: 53.5488282\n  longitude: 9.987170299999999\n"
  },
  {
    "path": "data/balticruby/balticruby-2026/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Ali Krynitsky\n\n  organisations:\n    - Rubyness\n\n- name: \"Programm Comittee Member\"\n  users:\n    - Mina Slater\n    - Youssef Boulkaid\n    - Irina Lindt\n    - Jan Krutisch\n    - Ole Michaelis\n    - Olle Jonsson\n    - Judith Umbach\n    - Joschka Schulz\n"
  },
  {
    "path": "data/balticruby/balticruby-2026/videos.yml",
    "content": "---\n- title: \"Talk by Augustin Gottlieb\"\n  speakers:\n    - Augustin Gottlieb\n  description: \"\"\n  date: \"2026-06-12\"\n  event_name: \"Baltic Ruby 2026\"\n  video_provider: \"scheduled\"\n  video_id: \"agustin-gottlieb-baltic-ruby-2026\"\n  id: \"agustin-gottlieb-baltic-ruby-2026\"\n\n- title: \"Ruby should not be serious, let it be fun!\"\n  speakers:\n    - OKURA Masafumi\n  description: \"\"\n  date: \"2026-06-12\"\n  event_name: \"Baltic Ruby 2026\"\n  video_provider: \"scheduled\"\n  video_id: \"okura-masafumi-baltic-ruby-2026\"\n  id: \"okura-masafumi-baltic-ruby-2026\"\n\n- title: \"Talk by Łukasz Reszke\"\n  speakers:\n    - Łukasz Reszke\n  description: \"\"\n  date: \"2026-06-12\"\n  event_name: \"Baltic Ruby 2026\"\n  video_provider: \"scheduled\"\n  video_id: \"lukasz-reszke-baltic-ruby-2026\"\n  id: \"lukasz-reszke-baltic-ruby-2026\"\n\n- title: \"Talk by Nicolò Rebughini\"\n  speakers:\n    - Nicolò Rebughini\n  description: \"\"\n  date: \"2026-06-12\"\n  event_name: \"Baltic Ruby 2026\"\n  video_provider: \"scheduled\"\n  video_id: \"nicolo-rebughini-baltic-ruby-2026\"\n  id: \"nicolo-rebughini-baltic-ruby-2026\"\n\n- title: \"Talk by Udbhav Gambhir\"\n  speakers:\n    - Udbhav Gambhir\n  description: \"\"\n  date: \"2026-06-12\"\n  event_name: \"Baltic Ruby 2026\"\n  video_provider: \"scheduled\"\n  video_id: \"udbhav-gambhir-baltic-ruby-2026\"\n  id: \"udbhav-gambhir-baltic-ruby-2026\"\n\n- title: \"Keep Rails Boring, Build Your DX\"\n  speakers:\n    - François Pradel\n  description: \"\"\n  date: \"2026-06-12\"\n  event_name: \"Baltic Ruby 2026\"\n  video_provider: \"scheduled\"\n  video_id: \"francois-pradel-baltic-ruby-2026\"\n  id: \"francois-pradel-baltic-ruby-2026\"\n\n- title: \"Small Clouds & Boring Tech\"\n  speakers:\n    - Lucas Dohmen\n    - Dirk Breuer\n  description: \"\"\n  date: \"2026-06-12\"\n  event_name: \"Baltic Ruby 2026\"\n  video_provider: \"scheduled\"\n  video_id: \"lucas-dohmen-dirk-breuer-baltic-ruby-2026\"\n  id: \"lucas-dohmen-dirk-breuer-baltic-ruby-2026\"\n"
  },
  {
    "path": "data/balticruby/series.yml",
    "content": "---\nname: \"Baltic Ruby\"\nwebsite: \"https://balticruby.org\"\ntwitter: \"balticruby\"\nyoutube_channel_name: \"balticruby\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCyTip8pDXBqTxTR6fDZItDw\"\n"
  },
  {
    "path": "data/bangkok-rb/ruby-tuesday/event.yml",
    "content": "---\nid: \"ruby-tuesday\"\ntitle: \"Ruby Tuesday\"\nlocation: \"Bangkok, Thailand\"\ndescription: |-\n  Ruby Tuesday - Ruby meetup in Bangkok on the last Tuesday of every month.\nkind: \"meetup\"\npublished_at: \"2026-03-07\"\nyear: 2018\nwebsite: \"https://www.meetup.com/bangkok-rb/events/\"\nbanner_background: \"#FFFFFF\"\ncoordinates:\n  latitude: 13.738\n  longitude: 100.562\n"
  },
  {
    "path": "data/bangkok-rb/ruby-tuesday/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users: []\n  organisations:\n    - bangkok.rb\n"
  },
  {
    "path": "data/bangkok-rb/ruby-tuesday/videos.yml",
    "content": "---\n- id: \"bangkok-rb-ruby-tuesday-1\"\n  title: \"Ruby Tuesday #1\"\n  date: \"2018-02-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-1\"\n  video_provider: \"children\"\n  description: |-\n    The very first Ruby Tuesday!\n\n    https://www.meetup.com/bangkok-rb/events/246894729/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-2\"\n  title: \"Ruby Tuesday #2\"\n  date: \"2018-03-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-2\"\n  video_provider: \"children\"\n  description: |-\n    Second Ruby Tuesday is up! Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. The award winning digital agency, MAQE Bangkok Co. Ltd has kindly sponsored our meetup for Ruby Tuesday #2. There will be two short talks, with plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/248192057/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-3\"\n  title: \"Ruby Tuesday #3\"\n  date: \"2018-04-24\"\n  video_id: \"bangkok-rb-ruby-tuesday-3\"\n  video_provider: \"children\"\n  description: |-\n    This month, we decided to let you choose which topic you're most interested in. Pick your preferred topic through this link: https://www.meetup.com/ruby-tuesdays-bangkok/polls/1264845/\n\n    https://www.meetup.com/bangkok-rb/events/249697229/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-4\"\n  title: \"Ruby Wednesday #4\"\n  date: \"2018-05-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-4\"\n  video_provider: \"children\"\n  description: |-\n    We're having Ruby Tuesday on a Wednesday this month to work around the Visakha Bucha holiday!\n\n    https://www.meetup.com/bangkok-rb/events/250440423/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-5\"\n  title: \"Ruby Tuesday #5\"\n  date: \"2018-06-26\"\n  video_id: \"bangkok-rb-ruby-tuesday-5\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday #5, with Robin Clart (Omise)\n\n    https://www.meetup.com/bangkok-rb/events/251878139/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-6\"\n  title: \"Ruby Tuesday #6: Workshop Special!\"\n  date: \"2018-07-31\"\n  video_id: \"bangkok-rb-ruby-tuesday-6\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday #6: Workshop Special!\n\n    https://www.meetup.com/bangkok-rb/events/252967303/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-7\"\n  title: \"Ruby Tuesday #7\"\n  date: \"2018-08-28\"\n  video_id: \"bangkok-rb-ruby-tuesday-7\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday will be in Asoke area this month! International software development company Nimbl3 will be hosting our meetup again. Thank you Nimbl3 for your support once again!\n\n    https://www.meetup.com/bangkok-rb/events/253676324/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-8\"\n  title: \"Ruby Tuesday #8\"\n  date: \"2018-09-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-8\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday will again be at Nimbl3, in Asoke, this month! Nimbl3 will also be providing food and drinks. Thank you for all your support!\n\n    https://www.meetup.com/bangkok-rb/events/254547238/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-9\"\n  title: \"Ruby Tuesday #9\"\n  date: \"2018-10-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-9\"\n  video_provider: \"children\"\n  description: |-\n    We're back for a special spooky Ruby Tuesday the day before Halloween! We will again be at Nimbl3, in Asoke, on Tuesday 30 October! Food and drinks will be provided by Go-Jek Financial. Thank you Nimbl3 and Go-Jek for all your support!\n\n    https://www.meetup.com/bangkok-rb/events/255290146/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-10\"\n  title: \"Ruby Tuesday #10 - Real Time Rails App: ActionCable, AnyCable or Pusher?\"\n  date: \"2018-11-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-10\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday's group has been renamed Bangkok.rb as you have seen. But our regular monthly meetup will still stay stick to last Tuesday of the month except for December since last Tuesday is Christmas Day!\n\n    https://www.meetup.com/bangkok-rb/events/256399914/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-11\"\n  title: \"Ruby Tuesday #11 - First Meetup of 2019\"\n  date: \"2019-01-29\"\n  video_id: \"bangkok-rb-ruby-tuesday-11\"\n  video_provider: \"children\"\n  description: |-\n    Welcome back to our first Ruby Tuesday of 2019! We have a new host for this month at Monstar Hub. Food and drinks will be sponsored by Go Finance. Thank you Monstar Hub for hosting us in your wonderful co-working space and Go Finance for sponsoring the event!\n\n    https://www.meetup.com/bangkok-rb/events/257947540/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-12\"\n  title: \"Ruby Tuesday #12 - Crystal, Amber, and More\"\n  date: \"2019-02-26\"\n  video_id: \"bangkok-rb-ruby-tuesday-12\"\n  video_provider: \"children\"\n  description: |-\n    Welcome back to Ruby Tuesday! Once again we'll be meeting at Monstar Hub near Asoke. Thanks again to Monstar Hub for hosting us in your wonderful co-working space!\n\n    https://www.meetup.com/bangkok-rb/events/259031557/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-13\"\n  title: \"Ruby Tuesday #13 - March Meetup\"\n  date: \"2019-03-26\"\n  video_id: \"bangkok-rb-ruby-tuesday-13\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. As usual, there will be two short talks, with plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/259522861/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-14\"\n  title: \"Ruby Tuesday #14 - April Meetup\"\n  date: \"2019-04-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-14\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. As usual, there will be two short talks, with plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/259522869/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-15\"\n  title: \"Ruby Tuesday #15 - May Meetup\"\n  date: \"2019-05-28\"\n  video_id: \"bangkok-rb-ruby-tuesday-15\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. As usual, there will be two short talks, with plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/259522878/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-16\"\n  title: \"Ruby Tuesday #16 - June Meetup\"\n  date: \"2019-06-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-16\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. As usual, there will be two short talks, with plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/259522883/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-17\"\n  title: \"Ruby Tuesday #17 - July Meetup\"\n  date: \"2019-07-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-17\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. As usual, there will be two short talks, with plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/259522897/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-18\"\n  title: \"Ruby Tuesday #18 - August Meetup\"\n  date: \"2019-08-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-18\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be one short talk, a ruby clinic to discuss about some questions that you need help on while you code, a ruby quiz,and also plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/259522910/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-19\"\n  title: \"Ruby Tuesday #19 - September Meetup\"\n  date: \"2019-09-24\"\n  video_id: \"bangkok-rb-ruby-tuesday-19\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be one short talk, a ruby clinic to discuss about some questions that you need help on while you code, a ruby quiz,and also plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/264362708/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-20\"\n  title: \"Ruby Tuesday #20 - Hacktoberfest Meetup\"\n  date: \"2019-10-29\"\n  video_id: \"bangkok-rb-ruby-tuesday-20\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be two short talks, a Ruby quiz, and also plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/265464769/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-21\"\n  title: \"Ruby Tuesday #21\"\n  date: \"2019-11-26\"\n  video_id: \"bangkok-rb-ruby-tuesday-21\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be two short talks, a Ruby quiz, and also plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/266204185/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-22\"\n  title: \"Ruby Tuesday #22 Special - Bangkok Christmas Codewar 2019\"\n  date: \"2019-12-13\"\n  video_id: \"bangkok-rb-ruby-tuesday-22\"\n  video_provider: \"children\"\n  description: |-\n    Join in the final battle of the year before 2019 ends. Get into the codewar challenge!\n\n    https://www.meetup.com/bangkok-rb/events/266340438/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-23\"\n  title: \"Ruby Tuesday #23\"\n  date: \"2020-01-28\"\n  video_id: \"bangkok-rb-ruby-tuesday-23\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be two short talks, a Ruby quiz, and also plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/266576588/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-24\"\n  title: \"Ruby Tuesday #24\"\n  date: \"2020-02-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-24\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be two short talks, a Ruby quiz, and also plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/266576583/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-25\"\n  title: \"Ruby Tuesday #25\"\n  date: \"2020-08-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-25\"\n  video_provider: \"children\"\n  description: |-\n    After a long lockdown Ruby Tuesday is back!\n\n    https://www.meetup.com/bangkok-rb/events/271788447/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-26\"\n  title: \"Ruby Tuesday #26 - Microcontroller Code &amp; Solve Murder Case with Sequel!\"\n  date: \"2020-09-29\"\n  video_id: \"bangkok-rb-ruby-tuesday-26\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be two short talks, a Ruby quiz, and also plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/273431006/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-27\"\n  title: \"Enterprise on Rails + Ruby in Production - Ruby Tuesday #27\"\n  date: \"2020-10-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-27\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be two short talks, a Ruby quiz, and also plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/273431106/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-28\"\n  title: \"Ruby Tuesday #28 - Concept of Direct Upload + Fukuoka Ruby Award 2020\"\n  date: \"2020-11-24\"\n  video_id: \"bangkok-rb-ruby-tuesday-28\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be two short talks, a Ruby quiz, and also plenty of time to mingle and to meet other Ruby developers and friendly tech people.\n\n    https://www.meetup.com/bangkok-rb/events/274226780/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-29\"\n  title: \"Ruby Tuesday #29 - Scraping IG Followers + Learning Software Dev with Train Set\"\n  date: \"2021-03-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-29\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be two short talks, a Ruby quiz, and also plenty of time to mingle and to meet other Ruby developers and friendly tech people. We will be hosting our meetup at AIS Design this month.\n\n    https://www.meetup.com/bangkok-rb/events/276892143/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-30\"\n  title: \"Ruby Tuesday #30 - WE'RE BACK!\"\n  date: \"2021-11-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-30\"\n  video_provider: \"children\"\n  description: |-\n    We're excited to be able to restart in-person events from November!\n\n    https://www.meetup.com/bangkok-rb/events/281788120/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-31\"\n  title: \"Ruby Tuesday #31 - Our first event of 2022!\"\n  date: \"2022-03-29\"\n  video_id: \"bangkok-rb-ruby-tuesday-31\"\n  video_provider: \"children\"\n  description: |-\n    Welcome back for the first Ruby Tuesday of 2022!\n\n    https://www.meetup.com/bangkok-rb/events/284502041/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-32\"\n  title: \"Ruby Tuesday #32\"\n  date: \"2022-04-26\"\n  video_id: \"bangkok-rb-ruby-tuesday-32\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby. Whether you're an expert or a beginner, you're welcome to join. There will be two short talks, a Ruby quiz, and also plenty of time to mingle and to meet other Ruby developers and friendly tech people. We will be hosting our meetup at Nimble at Interchange 21 near Asoke this month.\n\n    https://www.meetup.com/bangkok-rb/events/284694341/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-33\"\n  title: \"Ruby Tuesday #33 - Ruby Quiz is back 💯\"\n  date: \"2022-05-31\"\n  video_id: \"bangkok-rb-ruby-tuesday-33\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/285794483/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-34\"\n  title: \"Ruby Tuesday #34\"\n  date: \"2022-06-28\"\n  video_id: \"bangkok-rb-ruby-tuesday-34\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/286414072/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-35\"\n  title: \"Ruby Tuesday #35\"\n  date: \"2022-07-26\"\n  video_id: \"bangkok-rb-ruby-tuesday-35\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/286865120/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-36\"\n  title: \"Ruby Tuesday #36 - Multi-tenancy with Rails &amp; Ruby on Rails + Vite + React\"\n  date: \"2022-08-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-36\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/287522722/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-37\"\n  title: \"Ruby Tuesday #37 - From Jekyll to Bridgetown + Web3 with Ruby\"\n  date: \"2022-09-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-37\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/288224040/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-38\"\n  title: \"Ruby Tuesday #38\"\n  date: \"2022-10-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-38\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/288791566/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-39\"\n  title: \"Ruby Tuesday #39\"\n  date: \"2022-11-29\"\n  video_id: \"bangkok-rb-ruby-tuesday-39\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/289349252/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-40\"\n  title: \"Ruby Tuesday #40\"\n  date: \"2023-01-31\"\n  video_id: \"bangkok-rb-ruby-tuesday-40\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/290051527/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-41\"\n  title: \"Ruby Tuesday #41\"\n  date: \"2023-02-28\"\n  video_id: \"bangkok-rb-ruby-tuesday-41\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/291286433/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-42\"\n  title: \"Ruby Tuesday #42\"\n  date: \"2023-03-28\"\n  video_id: \"bangkok-rb-ruby-tuesday-42\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/291286477/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-43\"\n  title: \"Ruby Tuesday #43\"\n  date: \"2023-04-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-43\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/291837757/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-44\"\n  title: \"Ruby Tuesday #44\"\n  date: \"2023-05-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-44\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/291837783/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-45\"\n  title: \"Ruby Tuesday #45\"\n  date: \"2023-06-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-45\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/291837794/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-46\"\n  title: \"Ruby Tuesday #46\"\n  date: \"2023-07-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-46\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/291837925/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-47\"\n  title: \"Ruby Tuesday #47\"\n  date: \"2023-08-29\"\n  video_id: \"bangkok-rb-ruby-tuesday-47\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/291838026/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-48\"\n  title: \"Ruby Tuesday #48\"\n  date: \"2023-09-26\"\n  video_id: \"bangkok-rb-ruby-tuesday-48\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/293929319/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-49\"\n  title: \"Ruby Tuesday #49\"\n  date: \"2023-11-28\"\n  video_id: \"bangkok-rb-ruby-tuesday-49\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/293929757/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-50\"\n  title: \"Ruby Tuesday #50\"\n  date: \"2024-01-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-50\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/293929814/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-51\"\n  title: \"Ruby Tuesday #51\"\n  date: \"2024-02-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-51\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/299229012/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-52\"\n  title: \"Ruby Tuesday #52\"\n  date: \"2024-03-26\"\n  video_id: \"bangkok-rb-ruby-tuesday-52\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/299808428/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-53\"\n  title: \"Ruby Tuesday #53\"\n  date: \"2024-04-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-53\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/300369463/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-54\"\n  title: \"Ruby Tuesday #54\"\n  date: \"2024-05-28\"\n  video_id: \"bangkok-rb-ruby-tuesday-54\"\n  video_provider: \"children\"\n  description: |-\n    Ruby Tuesday is an event to gather all who are interested in the programming language Ruby and its community 💎\n\n    https://www.meetup.com/bangkok-rb/events/300369465/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-55\"\n  title: \"Ruby Tuesday #55\"\n  date: \"2024-06-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-55\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/301754840/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-56\"\n  title: \"Ruby Tuesday #56\"\n  date: \"2024-08-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-56\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/302552577/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-57\"\n  title: \"Ruby Tuesday #57\"\n  date: \"2024-09-24\"\n  video_id: \"bangkok-rb-ruby-tuesday-57\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/303075559/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-58\"\n  title: \"Ruby Tuesday #58\"\n  date: \"2024-10-29\"\n  video_id: \"bangkok-rb-ruby-tuesday-58\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/304156776/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-59\"\n  title: \"Ruby Tuesday #59\"\n  date: \"2024-11-26\"\n  video_id: \"bangkok-rb-ruby-tuesday-59\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/304666405/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-60\"\n  title: \"Ruby Tuesday #60\"\n  date: \"2025-01-28\"\n  video_id: \"bangkok-rb-ruby-tuesday-60\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/305789259/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-61\"\n  title: \"Ruby Tuesday #61\"\n  date: \"2025-02-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-61\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/305915629/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-62\"\n  title: \"Ruby Tuesday #62\"\n  date: \"2025-03-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-62\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/306802526/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-63\"\n  title: \"Ruby Tuesday #63\"\n  date: \"2025-04-29\"\n  video_id: \"bangkok-rb-ruby-tuesday-63\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/307456423/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-64\"\n  title: \"Ruby Tuesday #64\"\n  date: \"2025-05-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-64\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/307801105/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-65\"\n  title: \"Ruby Tuesday #65\"\n  date: \"2025-06-24\"\n  video_id: \"bangkok-rb-ruby-tuesday-65\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/308225743/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-66\"\n  title: \"Ruby Tuesday #66\"\n  date: \"2025-08-26\"\n  video_id: \"bangkok-rb-ruby-tuesday-66\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/310246437/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-67\"\n  title: \"Ruby Tuesday #67\"\n  date: \"2025-09-30\"\n  video_id: \"bangkok-rb-ruby-tuesday-67\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/310967763/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-68\"\n  title: \"Ruby Tuesday #68\"\n  date: \"2025-10-28\"\n  video_id: \"bangkok-rb-ruby-tuesday-68\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/311318924/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-69\"\n  title: \"Ruby Tuesday #69\"\n  date: \"2025-11-25\"\n  video_id: \"bangkok-rb-ruby-tuesday-69\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/312146826/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-70\"\n  title: \"Ruby Tuesday #70 (Ruby Conference Edition)\"\n  date: \"2026-01-27\"\n  video_id: \"bangkok-rb-ruby-tuesday-70\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/312953282/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-71\"\n  title: \"Ruby Tuesday #71\"\n  date: \"2026-02-24\"\n  video_id: \"bangkok-rb-ruby-tuesday-71\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/313168390/\n  talks: []\n- id: \"bangkok-rb-ruby-tuesday-72\"\n  title: \"Ruby Tuesday #72\"\n  date: \"2026-03-31\"\n  video_id: \"bangkok-rb-ruby-tuesday-72\"\n  video_provider: \"children\"\n  description: |-\n    We will be hosting our meetup at Nimble at Interchange 21 near Asoke.\n\n    https://www.meetup.com/bangkok-rb/events/313644454/\n  talks: []\n"
  },
  {
    "path": "data/bangkok-rb/series.yml",
    "content": "---\nname: \"bangkok.rb\"\nwebsite: \"https://meetup.com/bangkok-rb/\"\ntwitter: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"TH\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/barcelona-rb/barcelona-rb-meetup/event.yml",
    "content": "---\nid: \"barcelona-rb-meetup\"\ntitle: \"Barcelona.rb Meetup\"\nlocation: \"Barcelona, Spain\"\ndescription: |-\n  Barcelona Ruby User Group\nkind: \"meetup\"\npublished_at: \"2024-11-26\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://www.meetup.com/barcelona-rb\"\ncoordinates:\n  latitude: 41.3874374\n  longitude: 2.1686496\n"
  },
  {
    "path": "data/barcelona-rb/barcelona-rb-meetup/videos.yml",
    "content": "---\n# 2024\n\n- id: \"barcelona-rb-meetup-november-2024\"\n  title: \"Barcelona.rb November 2024\"\n  event_name: \"Barcelona.rb November 2024\"\n  date: \"2024-11-05\"\n  published_at: \"2024-11-26\"\n  video_provider: \"children\"\n  video_id: \"barcelona-rb-meetup-november-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/3/f/9/5/event_524836277.webp?w=640\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/3/f/9/5/event_524836277.webp?w=1080\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/3/f/9/5/highres_524836277.webp\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/3/f/9/5/highres_524836277.webp\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/3/f/9/5/highres_524836277.webp\"\n  description: |-\n    Hi there, Fellow Ruby Engineers!\n    Join us for the #November Barcelona.rb meetup!\n    This meetup marks the beginning of an exciting journey across Spain, connecting Ruby enthusiasts in Barcelona, Valencia, and Madrid. Be part of this historic moment in the Spanish Ruby community!\n\n    📆 05.11.2024\n    ⏰ 18:00\n    📍 Loft de Gràcial, C. de Montmany, 30, Barcelona\n\n    Agenda\n\n    🎙️ Mariusz Kozieł - Beyond Meetups: Creating Ruby Ecosystem\n    🎙️ Roman Samoilov - Modernising Ruby Systems with Rage\n    🎙️ Genar Trias Ortiz - Life beyond MVC: scaling Rails monolith for hundreds of developers\n    🔥 Networking!\n\n    The Spain Triangle Project\n\n    This meetup is part of the larger Spain Triangle Project, an initiative by Ruby Europe to strengthen the Ruby community in Spain. Don't miss the other events:\n\n    Barcelona.rb on November 5th\n    Valencia.rb on November 6th: Valencia.rb (Postponed due to recent tragic events)\n    Madrid.rb on November 7th: Madrid.rb\n    🚂 Join the Ruby Train! We're inviting a group of enthusiasts to travel together to all three events. More Ruby, more networking, more fun! Train group: Google Form\n\n    About Ruby Europe\n\n    Ruby Europe is uniting Ruby enthusiasts across the continent to build a thriving community. Join us on Discord and visit rubyeurope.com to learn more!\n    Join us for an evening of learning, networking, and celebrating Ruby. Let's kickstart this Ruby revolution together!\n\n    https://www.meetup.com/barcelona-rb/events/304030335\n  talks:\n    - title: \"Beyond Meetups: Creating Ruby Ecosystem\"\n      event_name: \"Barcelona.rb November 2024\"\n      date: \"2024-11-05\"\n      published_at: \"2024-11-26\"\n      id: \"mariusz-koziel-barcelona-meetup-november-2024\"\n      video_provider: \"youtube\"\n      video_id: \"xsHQ-c3uPxQ\"\n      language: \"english\"\n      description: |-\n        Mariusz Kozieł presentation at the Barcelona.rb meetup, which took place on November 5th, 2024.\n\n        ► Find us here:\n\n        Linkedin: https://www.linkedin.com/company/ruby-europe/posts/?feedView=all\n        X: https://x.com/RubyEurope\n      speakers:\n        - Mariusz Kozieł\n\n    - title: \"Modernising Ruby Systems with Rage\"\n      event_name: \"Barcelona.rb November 2024\"\n      date: \"2024-11-05\"\n      published_at: \"2024-11-26\"\n      id: \"roman-samoilov-barcelona-meetup-november-2024\"\n      video_provider: \"youtube\"\n      video_id: \"C14_vqAjtMM\"\n      language: \"english\"\n      description: |-\n        Roman Samoilov presentation at the Barcelona.rb meetup, which took place on November 5th, 2024.\n\n        ► Find us here:\n\n        Linkedin: https://www.linkedin.com/company/ruby-europe/posts/?feedView=all\n        X: https://x.com/RubyEurope\n      speakers:\n        - Roman Samoilov\n\n    - title: \"Life Beyond MVC: Scaling Rails Monolith for Hundreds of Developers\"\n      event_name: \"Barcelona.rb November 2024\"\n      date: \"2024-11-05\"\n      published_at: \"2024-11-26\"\n      video_provider: \"youtube\"\n      id: \"genar-trias-ortis-barcelonarb-november-2024\"\n      video_id: \"Ur1vHMakuy8\"\n      language: \"english\"\n      description: |-\n        Genar Trias Ortis presentation at the Barcelona.rb meetup, which took place on November 5th, 2024.\n\n        ► Find us here:\n\n        Linkedin: https://www.linkedin.com/company/ruby-europe/posts/?feedView=all\n        X: https://x.com/RubyEurope\n      speakers:\n        - Genar Trias Ortis\n# 2025\n\n- id: \"barcelona-rb-meetup-february-2025\"\n  title: \"Barcelona.rb February 2025\"\n  event_name: \"Barcelona.rb February 2025\"\n  date: \"2025-02-11\"\n  announced_at: \"2025-01-29 14:51:00 UTC\"\n  video_provider: \"children\"\n  video_id: \"barcelona-rb-meetup-february-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/3/9/a/1/highres_525974753.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/3/9/a/1/highres_525974753.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/3/9/a/1/highres_525974753.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/3/9/a/1/highres_525974753.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/3/9/a/1/highres_525974753.webp?w=750\"\n  description: |-\n    Hi there, Fellow Ruby Engineers!\n\n    Barcelona.rb is coming back after the New Year break with two fantastic talks. First, Kirill Platonov will introduce us to the world of ViewComponents, then Gleb Glazov will share his favourite tips and tricks on how to boost your productivity.\n\n    📆 11.02.2024\n    ⏰ 18:00\n    📍 Loft de Gràcial, C. de Montmany, 30, Barcelona\n\n    Agenda\n\n    🎙️ 18:30. Kirill Platonov - Getting Started with ViewComponents.\n    🎙️ 19:30. Gleb Glazov - My workflow sucks, yours shouldn't a.k.a. how to use computer efficiently.\n    🔥 Networking!\n\n    After a substantial dose of knowledge, we invite you to engage in discussions during the informal part. Hope to see you there!\n\n    https://www.meetup.com/barcelona-rb/events/305879212\n  talks:\n    - title: \"Getting Started with ViewComponents\"\n      event_name: \"Barcelona.rb February 2025\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-02-04 20:57:00 UTC\"\n      id: \"kirill-platonov-barcelona-rb-meetup-february-2025\"\n      video_provider: \"scheduled\"\n      video_id: \"kirill-platonov-barcelona-rb-meetup-february-2025\"\n      language: \"english\"\n      description: |-\n        Kirill Platonov will introduce us to the world of ViewComponents.\n      speakers:\n        - Kirill Platonov\n\n    - title: \"My workflow sucks, yours shouldn't a.k.a. how to use computer efficiently\"\n      event_name: \"Barcelona.rb February 2025\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-01-29 14:51:00 UTC\"\n      id: \"gleb-glazov-barcelona-rb-meetup-february-2025\"\n      video_provider: \"scheduled\"\n      video_id: \"gleb-glazov-barcelona-rb-meetup-february-2025\"\n      language: \"english\"\n      description: |-\n        Gleb Glazov will share his favourite tips and tricks on how to boost your productivity.\n      speakers:\n        - Gleb Glazov\n\n- id: \"barcelona-rb-meetup-march-2025\"\n  title: \"Barcelona.rb March 2025\"\n  event_name: \"Barcelona.rb March 2025\"\n  date: \"2025-03-26\"\n  video_provider: \"children\"\n  video_id: \"barcelona-rb-meetup-march-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/3/5/3/b/highres_526873627.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/3/5/3/b/highres_526873627.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/3/5/3/b/highres_526873627.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/3/5/3/b/highres_526873627.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/3/5/3/b/highres_526873627.webp?w=750\"\n  description: |-\n    Hello there, Fellow Ruby Engineers!\n\n    In continuation of our tradition, we would like to invite you to our special edition of Barcelona.rb!\n    We will be gathering at the bar, having beers in an amazing company of fellow ruby engineers! There will be no official talks, no speakers, formal agenda and budget (meaning that everyone pays for their own beer 😅), just a company of friendly engineers, willing to chat, joke, laugh and discuss the latest news of the Ruby community!\n\n    📆 26.03.2025\n    ⏰ 18:30\n    📍 la textil collective / 303 audiophile bar, Carrer de Casp, 33B, Barcelona\n\n    Join us and let's spend some good time together!\n\n    https://www.meetup.com/barcelona-rb/events/306812440\n  talks: []\n\n- id: \"barcelona-rb-meetup-may-2025\"\n  title: \"Barcelona.rb May 2025\"\n  event_name: \"Barcelona.rb May 2025\"\n  date: \"2025-05-08\"\n  video_provider: \"children\"\n  video_id: \"barcelona-rb-meetup-may-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/8/3/a/f/highres_527613711.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/8/3/a/f/highres_527613711.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/8/3/a/f/highres_527613711.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/8/3/a/f/highres_527613711.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/8/3/a/f/highres_527613711.webp?w=750\"\n  description: |-\n    Hi there, Fellow Ruby Engineers!\n\n    **Barcelona.rb** is coming back this spring with the #May Meetup! This time, we will have Cristian Planas as our guest with a talk about Rails and microservices, as well as Rich Steinmetz, with whom we will discuss API Integrations.\n\n    📆 08.05.2025\n    ⏰ 18:00\n    📍 Loft de Gràcial, C. de Montmany, 30, Barcelona\n\n    Agenda\n\n    🎙️ 18:30. Cristian Planas - How Modern Ruby Powers High-Speed Microservices Reintegration in Rails.\n    🎙️ 19:30. Rich Steinmetz - Grow Your API Integration Suite While Keeping Your Devs Focused on the Product Core.\n    🔥 Networking!\n\n    After a substantial dose of knowledge, we invite you to engage in discussions during the informal part. Hope to see you there!\n\n    https://www.meetup.com/barcelona-rb/events/307510388\n  talks:\n    - title: \"How Modern Ruby Powers High-Speed Microservices Reintegration in Rails\"\n      event_name: \"Barcelona.rb May 2025\"\n      date: \"2025-05-08\"\n      id: \"cristian-planas-barcelona-meetup-may-2025\"\n      video_provider: \"scheduled\"\n      video_id: \"cristian-planas-barcelona-meetup-may-2025\"\n      language: \"english\"\n      description: |-\n        Cristian Planas discusses Rails and microservices at Barcelona.rb.\n      speakers:\n        - Cristian Planas\n\n    - title: \"Grow Your API Integration Suite While Keeping Your Devs Focused on the Product Core\"\n      event_name: \"Barcelona.rb May 2025\"\n      date: \"2025-05-08\"\n      id: \"rich-steinmetz-barcelona-meetup-may-2025\"\n      video_provider: \"scheduled\"\n      video_id: \"rich-steinmetz-barcelona-meetup-may-2025\"\n      language: \"english\"\n      description: |-\n        Rich Steinmetz leads a discussion on API design at Barcelona.rb.\n      speakers:\n        - Rich Steinmetz\n"
  },
  {
    "path": "data/barcelona-rb/series.yml",
    "content": "---\nname: \"Barcelona.rb\"\nwebsite: \"https://www.meetup.com/barcelona-rb\"\ntwitter: \"bcnrails\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"ES\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/baruco/barcelona-ruby-conf-2012/event.yml",
    "content": "---\nid: \"barcelona-ruby-conf-2012\"\ntitle: \"Barcelona Ruby Conf 2012\"\ndescription: \"\"\nlocation: \"Barcelona, Spain\"\nkind: \"conference\"\nstart_date: \"2012-09-08\"\nend_date: \"2012-09-09\"\nwebsite: \"https://web.archive.org/web/20120608025841/http://baruco.org/\"\ntwitter: \"baruco\"\nplaylist: \"https://web.archive.org/web/20220818125240/https://confreaks.tv/events/baruco2012\"\ncoordinates:\n  latitude: 41.3874374\n  longitude: 2.1686496\nbanner_background: \"#47a299\"\nfeatured_background: \"#47a299\"\nfeatured_color: \"#f3c83b\"\n"
  },
  {
    "path": "data/baruco/barcelona-ruby-conf-2012/videos.yml",
    "content": "# Website: https://web.archive.org/web/20120608025841/http://baruco.org/\n# Videos: https://www.youtube.com/watch?v=npOGOmkxuio&list=PLe9psSNJBf75GtwxHQzESHqSUgsS0Pv_N\n---\n- id: \"scott-chacon-baruco-2012\"\n  title: \"Back to First Principles\"\n  raw_title: \"Scott Chacon - Back to First Principles - BaRuCo 2012\"\n  speakers:\n    - Scott Chacon\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-08\"\n  published_at: \"2020-12-02\"\n  description: |-\n    Nearly everything in business is changing thanks to the new availability of high speed internet to nearly everyone on the planet. Everything you know about business is probably based on knowledge that is no longer applicable. People like you have made it possible to upend nearly every business lesson learned and ingrained over the past several hundred years. At this time, with these tools and this global network available to us, we have the power and opportunity to go back to first principles and re-imagine nearly everything - from product all the way to the workplace.\n  video_provider: \"youtube\"\n  video_id: \"zXWxc4NFu6E\"\n  kind: \"keynote\"\n\n- id: \"zed-a-shaw-baruco-2012\"\n  title: \"The Top 10 Ways to Scam the Modern American Programmer\"\n  raw_title: \"Zed A. Shaw - The Top 10 Ways to Scam the Modern American Programmer - BaRuCo 2012\"\n  speakers:\n    - Zed A. Shaw\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-08\"\n  published_at: \"2020-12-02\"\n  description: |-\n    Do you want to be successful in the world of startups and Information Technologies? Then come listen to Zed tell you the 10 best ways to scam, rip off, fool, and influence today's American programmer. While focusing on the American variety of coder, these tactics are sure to work on people from all over the world with only minor modifications.\n  video_provider: \"youtube\"\n  video_id: \"Q47FOiwXDh8\"\n  kind: \"keynote\"\n\n- id: \"paolo-perrotta-baruco-2012\"\n  title: \"A Short History of Software Engineering, and Other Ideas That Didn't Work\"\n  raw_title: \"Paolo Perrotta - A Short History of Software Engineering - BaRuCo 2012\"\n  speakers:\n    - Paolo Perrotta\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-08\"\n  published_at: \"2020-12-02\"\n  description: |-\n    Building software is a young discipline, but it already has a fascinating history. For a young rubyist, it's easy to forget where we all come from, and why we do software the way we do today. Let a slightly-less-young rubyist tell you the story of software engineering - a story of big problems, brilliant solutions and miserable failures.\n  video_provider: \"youtube\"\n  video_id: \"CnquVcxvAl0\"\n\n- id: \"xavier-noria-baruco-2012\"\n  title: \"Constant Autoloading in Ruby on Rails\"\n  raw_title: \"Xavier Noria - Constant Autoloading in Ruby on Rails - BaRuCo 2012\"\n  speakers:\n    - Xavier Noria\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-08\"\n  published_at: \"2020-12-02\"\n  description: |-\n    Ruby on Rails lets users largely forget about explicit requires. Active Support provides constant autoloading to Ruby on Rails applications, and leverages this feature to also offer automatic code reloading in development mode. In this talk we study how these nifty hacks work under the hood.\n  video_provider: \"youtube\"\n  video_id: \"sDCIUHKUbiM\"\n\n- id: \"gary-bernhardt-baruco-2012\"\n  title: \"Deconstructing the Framework\"\n  raw_title: \"Gary Bernhardt - Deconstructing the Framework - BaRuCo 2012\"\n  speakers:\n    - Gary Bernhardt\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-08\"\n  published_at: \"2020-12-03\"\n  description: |-\n    Rails gives us M, V, C, routes, and helpers. Some people add observers and concerns, among others. We've standardized on presenters. Service objects are gaining popularity. Uncle Bob wants you to add interactors, request models, response models, and entities. That's a lot of stuff! Let's step back: ideally, how do all of these things fit together? Does it make sense to have so many different components? How do different web frameworks project these onto actual components? Most importantly: how does this explain the tangled mess in Rails controllers and how we might fix it?\n  video_provider: \"youtube\"\n  video_id: \"57lwoBpfrgk\"\n\n- id: \"brian-ford-baruco-2012\"\n  title: \"Grand Unification Theory: Writing and Running Code\"\n  raw_title: \"Brian Ford - Grand Unification Theory: Writing and Running Code - BaRuCo 2012\"\n  speakers:\n    - Brian Ford\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-08\"\n  published_at: \"2020-12-03\"\n  description: |-\n    Whether you are using a statically typed or dynamically typed language, there is typically a rigid separation between writing code and running code. Smalltalk environments focused on running code where writing code was actually a function of the running program. However, this approach was usually implemented using a snapshot of a running process that makes sharing code and managing changes over time quite difficult. What if we could blur the separation between writing code and running code? This could empower us to use information about how our program is running in production while adding new features or maintaining existing code. What if we could combine data from test runs, a coworker's activities, and running production applications while writing code? Such a feature could enable powerful code analysis and auditing tools. This talk will take a tour of these possibilities on the Rubinius dynamic language environment.\n  video_provider: \"youtube\"\n  video_id: \"V5o-6bE5FM0\"\n\n- id: \"josh-kalderimis-baruco-2012\"\n  title: \"It's Not How Good Your App Is, It's How Good You Want It to Be\"\n  raw_title: \"Josh Kalderimis - It's Not How Good Your App Is, It's How Good You Want It to Be - BaRuCo 2012\"\n  speakers:\n    - Josh Kalderimis\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-08\"\n  published_at: \"2020-12-02\"\n  description: |-\n    This talk is part story, part code, and part mustache. Travis CI is a distributed continuous integration system running over 7,000 tests daily. For us to get a true insight into what is going on behind the scenes we have had to come a long way by integrating and building both tools and libraries so that Travis and its many parts are not just a black box of information. Reading logs and using NewRelic is not new, but far from enough, especially when it comes to apps which are composed of many smaller apps, like Travis. How do you track and visualize requests being processed by multiple services? How do you silence verbose logs while not losing the core of the message? And how do you aggregate, visualize and share metrics? A lot of how we track, manage, and visualize what is going on in Travis has been created as a set of internal tools and by using a range of awesome services, but core to a lot of this is ActiveSupport Notifications and Travis Instrumentation. This session will give insight to how Travis is composed and connected, as well as shedding light on how simple it can be to gain more visibility into even a complex, distributed system like Travis, as well as your applications too.\n  video_provider: \"youtube\"\n  video_id: \"_Wz5GlyxyFw\"\n\n- id: \"anthony-eden-baruco-2012\"\n  title: \"Life Beyond HTTP\"\n  raw_title: \"Anthony Eden - Life Beyond HTTP - BaRuCo 2012\"\n  speakers:\n    - Anthony Eden\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-08\"\n  published_at: \"2020-12-02\"\n  description: |-\n    Attention all rubyists, there is a world of protocols for you to experience beyond HTTP. In this talk I'll introduce you to some of them, including the one I'm most passionate about: DNS. I'll provide you with some examples of how to use existing libraries to talk various protocols using Ruby and maybe even get into some low-level bit slinging. We'll have a grand old time geeking out and in the end you might just find a protocol that you can fall in love with other than HTTP.\n  video_provider: \"youtube\"\n  video_id: \"8b0MyL3xunw\"\n\n- id: \"konstantin-haase-baruco-2012\"\n  title: \"Message in a Bottle\"\n  raw_title: \"Konstantin Haase - Message in a Bottle - BaRuCo 2012\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-09\"\n  published_at: \"2020-12-02\"\n  description: |-\n    What does really happen when we call a method? How do the different Ruby implementations actually figure out what code to execute? What plumbing is going on under the hood to get a speedy dispatch? In this talk we will have a look at the internals of the the major Ruby implementations, focusing on their dispatch. From look-up tables and call site caches, to inlining and what on earth is invokedynamic? Fear not, all will be explained!\n  video_provider: \"youtube\"\n  video_id: \"UDTYs195BHM\"\n\n- id: \"fred-george-baruco-2012\"\n  title: \"Micro-Service Architecture\"\n  raw_title: \"Fred George - Micro-Service Architecture - BaRuCo 2012\"\n  speakers:\n    - Fred George\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-09\"\n  published_at: \"2020-12-03\"\n  description: |-\n    SOA, service-oriented architectures, burst on the scene in the new millennium as the latest technology to support application growth. In concert with the Web, SOA ushered in new paradigms for structuring enterprise applications. At the Forward Internet Group in London, we are implementing SOA in unusual ways. Rather than a few, business-related services being implemented per the original vision, we have developed systems made of myriads of very small, usually short-lived services. In this workshop, we will start by exploring the evolution of SOA implementations by the speaker. In particular, lessons learned from each implementation will be discussed, and re-application of these lessons on the next implementation. Challenges (and even failures) will be explicitly identified. We will arrive at a model of the current systems: An environment of very small services that are loosely coupled into a complex system. We explore the demise of acceptance tests in this complex environment, and the clever replacement of business metrics in their stead. Finally, we will conclude with the surprising programmer development process impacts of this architecture. Indeed, bedrock principles of Agile have been rendered unnecessary, something that equally surprised us.\n  video_provider: \"youtube\"\n  video_id: \"mK2rqaEjVq4\"\n\n- id: \"michal-taszycki-baruco-2012\"\n  title: \"Programming Workout\"\n  raw_title: \"Michal Taszycki - Programming Workout - BaRuCo 2012\"\n  speakers:\n    - Michał Taszycki\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-09\"\n  published_at: \"2020-12-02\"\n  description: |-\n    Our tools are becoming ever more efficient... Command line tools are becoming obsolete... Programmers today don't need to touch-type... Using the mouse to copy and paste is perfectly fine... You can always look up those design patterns on the web... Your IDE can do many things for you, so why do you even need to think? Can you feel it? Can you feel that this is TRUE? Then stop being UNPROFESSIONAL and think again! In this talk, I'm going to convince you that learning seemingly obsolete skills can have huge impact on your productivity. I will show you how these skills and other seemingly unimportant factors can impact your career. I will help you find ways to improve these skills in order to become a better programmer. I will also show you tools that can facilitate this process. In other words, I will show you how programmers WORK OUT. You will either leave this talk with a strong resolution to level up, or curl up in your comfort zone with your lovely mouse and IDE.\n  video_provider: \"youtube\"\n  video_id: \"sqIz261GBw4\"\n\n- id: \"dirkjan-bussink-baruco-2012\"\n  title: \"Rubinius - Tales from the Trenches of Developing a Ruby Implementation\"\n  raw_title: \"Dirkjan Bussink - Rubinius: Tales from the Trenches - BaRuCo 2012\"\n  speakers:\n    - Dirkjan Bussink\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-09\"\n  published_at: \"2020-12-02\"\n  description: |-\n    Programming is hard, so writing a programming language is hard too. If you think that your users are good at finding and creating weird edge cases, just wait until programmers are using your code. I'll be discussing some of the dumbest, unexpected, trickiest and weirded cases that we've encountered when implementing Rubinius. No shaming people here, some of the most interesting ones were us (ok, me) being stupid.\n  video_provider: \"youtube\"\n  video_id: \"Qb2h04K0pgw\"\n\n- id: \"tammer-saleh-randall-thomas-baruco-2012\"\n  title: \"RubyMotion for Faster Client/Server Development\"\n  raw_title: \"Tammer Saleh & Randall Thomas - RubyMotion for Faster Client/Server Development - BaRuCo 2012\"\n  speakers:\n    - Tammer Saleh\n    - Randall Thomas\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-09\"\n  published_at: \"2020-12-02\"\n  description: |-\n    The founders of Thunderbolt Labs will take you through the process of writing a RubyMotion iOS application that interfaces seamlessly with a backend Rails API. They'll explore all of the modern iOS techniques through RubyMotion, while using Storyboards, Bundler, and pulling data from a JSON API. In the process, they'll discuss the merits and pitfalls of using RubyMotion, and when it is and isn't appropriate for your project.\n  video_provider: \"youtube\"\n  video_id: \"_anf8D8SFVY\"\n\n- id: \"elise-huard-baruco-2012\"\n  title: \"Tracing Your Way Through Ruby\"\n  raw_title: \"Elise Huard - Tracing Your Way Through Ruby - BaRuCo 2012\"\n  speakers:\n    - Elise Huard\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-09\"\n  published_at: \"2020-12-02\"\n  description: |-\n    When a ruby program gets awfully slow and you don't know why, or you have a segfault out of the blue, or your memory usage is strangely high, it's time to open other drawers of the toolbox. This talk presents an overview of the most interesting tools which allow us to have an insight in what's happening in ruby when we run a program. To name but a few: perftools.rb, dtrace, instruments, and debugging the ruby code itself. Standing on the shoulders of giant: it works.\n  video_provider: \"youtube\"\n  video_id: \"XPLRELNaPwM\"\n\n- id: \"alex-koppel-baruco-2012\"\n  title: \"Uniformity Ain't All Bad: Getting Consistent Behavior Across Your API\"\n  raw_title: \"Alex Koppel - Uniformity Ain't All Bad - BaRuCo 2012\"\n  speakers:\n    - Alex Koppel\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-09\"\n  published_at: \"2020-12-02\"\n  description: |-\n    We all love API-based applications. By letting the server focus on data handling and leaving presentation to the clients, you can create remarkably flexible applications across a variety of platforms. Best of all, you can even open your app to your fellow developers. The more clients you add, though, the more varied the requests and needs of your users become, and the more important -- and difficult -- it is to keep everything consistent. In this talk, I'll review approaches you can take to easily and maintainably standardize... * What data you fetch: letting clients manage limits, filters, sorting, etc. for all their queries -- very useful when different clients have different needs, for instance mobile v. desktop. * How you present that data: allowing control over the level of response detail and other options, as well as handling response formats, exceptions, etc. in a standard way. * How you secure your data: making sure that you don't accidentally send clients data they're not allowed to view -- an additional centralized layer on top of your other security. We'll review plenty of code samples, along with advantages and disadvantages of each approach.\n  video_provider: \"youtube\"\n  video_id: \"mBbtNhWCsNs\"\n\n- id: \"zach-holman-baruco-2012\"\n  title: \"Unsucking Your Team's Development Environment\"\n  raw_title: \"Zach Holman - Unsucking Your Team's Development Environment - BaRuCo 2012\"\n  speakers:\n    - Zach Holman\n  event_name: \"Barcelona Ruby Conf 2012\"\n  date: \"2012-09-09\"\n  published_at: \"2020-12-02\"\n  description: |-\n    Success can bring many glamorous changes to your company: hiring more employees, getting free coffee, and giving everyone a private jet filled with cash and endangered African predatory cats. Success can lead to less-glamorous problems, though. As you grow, your team's development environment becomes really important. How long does it take to clone, set up, and boot your apps? Can your employees still be productive on an aging codebase? How can you automate CI, hooks, and other setup for new projects? Is any of this fun anymore? GitHub ran into these problems as we expanded our team tremendously over the last two years. Let's look at some of the ways we've improved our employees' development environments.\n  video_provider: \"youtube\"\n  video_id: \"H3AdJWueSZM\"\n"
  },
  {
    "path": "data/baruco/barcelona-ruby-conf-2013/event.yml",
    "content": "---\nid: \"barcelona-ruby-conf-2013\"\ntitle: \"Barcelona Ruby Conf 2013\"\ndescription: \"\"\nlocation: \"Barcelona, Spain\"\nkind: \"conference\"\nstart_date: \"2013-09-14\"\nend_date: \"2013-09-15\"\nwebsite: \"https://web.archive.org/web/20130731100639/http://www.baruco.org/\"\ntwitter: \"baruco\"\nplaylist: \"https://www.youtube.com/@BarucoOrg\"\ncoordinates:\n  latitude: 41.3874374\n  longitude: 2.1686496\nbanner_background: \"#091C39\"\nfeatured_background: \"#091C39\"\nfeatured_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/baruco/barcelona-ruby-conf-2013/videos.yml",
    "content": "# Website: https://web.archive.org/web/20130731100639/http://www.baruco.org/\n# Videos: https://www.youtube.com/watch?v=npOGOmkxuio&list=PLe9psSNJBf75GtwxHQzESHqSUgsS0Pv_N\n---\n- id: \"yukihiro-matz-matsumoto-baruco-2013\"\n  title: \"Changing Your World\"\n  raw_title: \"Baruco 2013 Keynote: Changing Your World, by Yukihiro Matz\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-10-15\"\n  description: |-\n    Unlike past generations, we can reach out and change the world, due to the Internet and open source. But first of all, you can change your world, the small world inside of you. And that change will lead to the great success to change the whole world! I will explain what has happened in the history of the Ruby development, and what was crucial to its success.\n  video_provider: \"youtube\"\n  video_id: \"6vdum5aXew8\"\n  kind: \"keynote\"\n\n- id: \"vicent-marti-baruco-2013\"\n  title: \"Once Upon a Time, Ruby\"\n  raw_title: \"Baruco 2013: Once Upon a Time, Ruby, by Vicent Martí\"\n  speakers:\n    - Vicent Marti\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-10-16\"\n  description: |-\n    This is a scary story about scary Ruby internals -- told as a fairy tale, but with a rather gloomy ending. There's a lot going on under the hood in MRI, YARV and Rubinius. The C and C++ layer that interacts with the OS is a tangly mess full of tricky bugs and arcane issues; the kind of issues that don't raise exceptions, but kill whole processes and make them bleed rainbows. The kind of issues that only show up when you deploy massive Ruby systems at a large scale. This is a talk about how we discover, tackle and fix these fundamental flaws in the Ruby VM at GitHub, one of the largest Ruby deployments in the world. Ruby internals are hard. This fairy tale may not have a happy ending.\n  video_provider: \"youtube\"\n  video_id: \"_BZHOfWusW4\"\n\n- id: \"sandi-metz-baruco-2013\"\n  title: \"Rules\"\n  raw_title: \"Baruco 2013: Rules, by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-10-20\"\n  description: |-\n    We're iconoclasts who reject arbitrary constraints yet long for understandable, predictable, changeable applications. We want code that follows rules yet we refuse to let rules to get in our way. We're deeply attached to the little rules that help get things done (No trailing whitespace! Indent using two spaces!) and despise the big, complicated ones that impose one-size-fits-all straitjackets on otherwise sane programming problems. This talk proposes 5 'little' rules for writing object-oriented code. These rules are determinedly simple yet produce code that experts love and novices can be trusted to change; they fill the space between anarchy and order with practical, common sense. The rules guide without impeding, help without hindering and constrain without binding, and let you create applications that are easy to change and fun to work their whole life long.\n  video_provider: \"youtube\"\n  video_id: \"npOGOmkxuio\"\n\n- id: \"katrina-owen-baruco-2013\"\n  title: \"Here Be Dragons\"\n  raw_title: \"Baruco 2013: Here Be Dragons, by Katrina Owen\"\n  speakers:\n    - Katrina Owen\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-11-07\"\n  description: |-\n    It's not your fault. Code rots. We don't hold entropy against you, but we expect you to give a damn. This story is about code that brings new meaning to the word 'legacy'. The accidental discovery of this body of code provoked a moral crisis. I wanted to pretend I hadn't seen it, yet I couldn't justify tiptoeing quietly away. This talk examines the dilemmas we face when balancing our choices today with their cost tomorrow. It's not your fault. Even so, it is your responsibility.\n  video_provider: \"youtube\"\n  video_id: \"HsWLrSof-ns\"\n\n- id: \"aaron-patterson-baruco-2013\"\n  title: \"Yak Shaving is Best Shaving\"\n  raw_title: \"Baruco 2013: Yak Shaving is Best Shaving, by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-10-28\"\n  description: |-\n    Many developers try to avoid yak shaving. In this talk we will attempt to explore the joys of shaving a yak. We'll explore new features of Active Record, along with techniques for performance improvements. All which were realized through the journey of software development, rather than the goal. Yak shaving can get hairy, but with enough mousse, we can tame any mane.\n  video_provider: \"youtube\"\n  video_id: \"nY_Pl2x7Fgs\"\n\n- id: \"charles-nutter-baruco-2013\"\n  title: \"The Future of JRuby\"\n  raw_title: \"Baruco 2013: The Future of JRuby, by Charles Nutter\"\n  speakers:\n    - Charles Nutter\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-10-31\"\n  description: |-\n    Over the past six years, JRuby has gone from a wobbly 1.0 release to being the alternative implementation of choice for high performance, horizontal scaling, big data, and wide ranging deployment. We've steadily improved JRuby's runtime while catching up with MRI 1.9 and 2.0 features. Now we're looking toward the future with an upcoming rework of JRuby. What will it bring? How will we boost performance? What will we add to the Ruby platform to make concurrency commonplace and painless? This talk will summarize our plans for JRuby 9000 and open a dialog on what Ruby needs to survive long term.\n  video_provider: \"youtube\"\n  video_id: \"8ZEAwWLwmfQ\"\n\n- id: \"avdi-grimm-baruco-2013\"\n  title: \"You Gotta Try This\"\n  raw_title: \"Baruco 2013: You Gotta Try This, by Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-10-24\"\n  description: |-\n    A talk about metaprogramming, coding for fun, and the joy of sharing.\n  video_provider: \"youtube\"\n  video_id: \"ZhINjILA5yw\"\n\n- id: \"paolo-perrotta-baruco-2013\"\n  title: \"Hunters and Gatherers\"\n  raw_title: \"Baruco 2013: Hunters and Gatherers, by Paolo Perrotta\"\n  speakers:\n    - Paolo Perrotta\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-10-28\"\n  description: |-\n    Let's open the day talking about programming languages, the progress of science, and a few things that didn't go quite as planned in the last half-millennium - from the Problem of Longitude to the resurrection of LISP, passing by debuggers and type systems. At the end of it all, one question: are you a hunter or a gatherer?\n  video_provider: \"youtube\"\n  video_id: \"ahh-QkttjuM\"\n\n- id: \"corey-haines-baruco-2013\"\n  title: \"Design Patterns And The Proper Cultivation Thereof\"\n  raw_title: \"Baruco 2013: Design Patterns And The Proper Cultivation Thereof, by Corey Haines\"\n  speakers:\n    - Corey Haines\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-10-25\"\n  description: |-\n    Design Patterns often are discussed with a negative tone. We laugh at Java developers and their heavy classes with the patterns encoded in the name. After all, who wants to try to understand the AbstractBaseClassFactoryManager? But don't most Ruby developers spend their time in a framework that glorifies a select few patterns to the point where the idea of writing code outside these patterns is considered heretical? On the other hand, Evolutionary Design says we are supposed to let the design come out over time, listening to the feedback we get from the combination of tests and refactoring, planning as little ahead as possible. What's a developer to do? Ideally, Design Patterns are used as communication, not construction, as description, not prescription. In this talk, we'll discuss using patterns as a goal, as guides when iterating and evolving our system's design.\n  video_provider: \"youtube\"\n  video_id: \"vqN3TQgsXzI\"\n\n- id: \"richard-schneeman-baruco-2013\"\n  title: \"Millions of Apps: What we've Learned\"\n  raw_title: \"Baruco 2013: Millions of Apps: What we've Learned, by Richard Shneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-10-23\"\n  description: |-\n    It is all about the things that Heroku has seen people doing with their apps, the good, bad, and the ugly. I focus on ways you can make your app better: easier to maintain, more secure, and less painful to develop on.\n  video_provider: \"youtube\"\n  video_id: \"gIdB9Yw2gXc\"\n\n- id: \"bryan-helmkamp-baruco-2013\"\n  title: \"Building a Culture of Quality\"\n  raw_title: \"Baruco 2013: Building a Culture of Quality, by Bryan Helmkamp\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-10-31\"\n  description: |-\n    Time and time again, skilled developers with good intentions set out into the green field of their new Rails app. Alas, as days turn to weeks, weeks to months and months to years, they find themselves with an ever increasing maintenance burden. Adding new features in a well-designed way starts to feel like an exercise in futility, so they resort to liberal use of conditionals to avoid breaking existing code. This leads to more complexity, and on the cycle goes. It doesn't need to be like this. There's no silver bullet that will save your project from this fate, but by practicing a holistic approach to code quality you can stave off the maintenance monsters and keep your app's code feeling fresh and clean. This talk will look at low ceremony, common sense approaches to taking control of the quality of your codebase. You'll leave with an expanded toolbox of techniques to build a culture of quality within your organization.\n  video_provider: \"youtube\"\n  video_id: \"Jsi1YTkXwxA\"\n\n- id: \"brian-sam-bodden-baruco-2013\"\n  title: \"iOS Games with RubyMotion\"\n  raw_title: \"Baruco 2013: iOS Games with RubyMotion, by Brian Sam Bodden\"\n  speakers:\n    - Brian Sam-Bodden\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-14\"\n  published_at: \"2013-11-03\"\n  description: |-\n    As Ruby Developer I've had a pretty involved relationship with my Mac. I own iPads and iPhones since Apple started to make them. A few years back I told myself I was going to build apps for the Mac/iPhone/iPad but then reality sunk in when I started learning Objective-C and using it in XCode. The environment (and the language) felt like a trip back to 1995. If you are a Web developer used to working with dynamically-typed, lightweight languages, following agile practices like Test-Driven Development, and comfortable with a Unix Shell, then jumping into a development world with an ugly cousin of C++ and an IDE that looks like an F16 cockpit just doesn't seem appealing. Luckily for us there is an alternative in RubyMotion, a Ruby-based toolchain for iOS that brings a Ruby on Rails style of development to the world of iOS application development. In this talk I will quickly introduce you to RubyMotion and jump right in into the world of game development for iOS using your favorite language; Ruby!\n  video_provider: \"youtube\"\n  video_id: \"h6PfXWpANeI\"\n\n- id: \"matt-wynne-baruco-2013\"\n  title: \"Treating objects like people\"\n  raw_title: \"Baruco 2013: Treating objects like people, by Matt Wynne\"\n  speakers:\n    - Matt Wynne\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-15\"\n  published_at: \"2013-10-20\"\n  description: |-\n    We all know it's wrong to treat people like objects. Have you ever considered what happens when you design your objects to be treated the same way? In this talk Matt explores the intersection between psychology and OO design. You'll leave with some food for thought about how to model the interactions between your objects, as well as how to relate to the people around you.\n  video_provider: \"youtube\"\n  video_id: \"lMCsQ_Mg3tI\"\n\n- id: \"jeremy-walker-baruco-2013\"\n  title: \"Refactoring Your Productivity\"\n  raw_title: \"Baruco 2013: Refactoring Your Productivity, by Jeremy Walker\"\n  speakers:\n    - Jeremy Walker\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-15\"\n  published_at: \"2013-10-22\"\n  description: |-\n    This talk explores how to get the most out of the hours behind a keyboard. It looks at what motivates us, how to avoid distractions, be happy, and generally be more productive, specifically in the world of Ruby. It looks at how to refactor the most important system you'll ever use - yourself. It's a non-technical and laugh-out-loud type of talk, but it contains lots of valuable thought-provoking information and practical ideas to make you a better developer. It aims to leave you feeling motivated and better equipped to become excellent at what you do, and to enjoy doing so.\n  video_provider: \"youtube\"\n  video_id: \"utO5d56LA0s\"\n\n- id: \"david-chelimsky-baruco-2013\"\n  title: \"A Rubyist in Clojure-land\"\n  raw_title: \"Baruco 2013: A Rubyist in Clojure-land, by David Chelimsky\"\n  speakers:\n    - David Chelimsky\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-15\"\n  published_at: \"2013-11-05\"\n  description: |-\n    After working with Ruby for several years, I joined a project team focused on Clojure, which provided an opportunity to look at programming through a new lens. In this talk I'll share some of the challenges I faced, new lessons I learned, and old lessons that were reinforced.\n  video_provider: \"youtube\"\n  video_id: \"PbeCeM344z8\"\n\n- id: \"chris-kelly-baruco-2013\"\n  title: \"Rabbit Hole: Garbage Collection and Ruby's Future\"\n  raw_title: \"Baruco 2013: Rabbit Hole: Garbage Collection and Ruby's Future, by Chris Kelly\"\n  speakers:\n    - Chris Kelly\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-15\"\n  published_at: \"2013-10-17\"\n  description: |-\n    Despite its reputation for being slow, MRI is still the most widely installed implementation of Ruby. Do you know how MRI got that reputation? Do you know what goes into executing Ruby on MRI? And more importantly, should today's Ruby be saddled with that reputation still? We're going to take a walk through the C internals from Foo.new through garbage collection in Ruby's MRI. We'll examine the idioms and optimizations in the C source and leave you feeling comfortable to explore the code yourself. At the end of the rb_newobj() rabbit hole is a whole world of garbage collection. Major changes have been made in MRI's garbage collector from Ruby 1.8 through 2.0: changes intended to make Ruby more performant, changes intended to capitalize on MRI's roots in UNIX. From mark-and-sweep to copy-on-write and bitmap marking, we'll see what the future of Ruby performance might look like by peering through the window of the garbage collector.\n  video_provider: \"youtube\"\n  video_id: \"R8ifdjbFETo\"\n\n- id: \"reginald-braithwaite-baruco-2013\"\n  title: \"What Developing With Ruby Can Teach Us About Developing Ruby\"\n  raw_title: \"Baruco 2013: What Developing With Ruby Can Teach Us About Developing Ruby, by Reg Braithwaite\"\n  speakers:\n    - Reginald Braithwaite\n  event_name: \"Barcelona Ruby Conf 2013\"\n  date: \"2013-09-15\"\n  published_at: \"2013-11-06\"\n  description: |-\n    When visualizing the future of a programming language, we look to the features and paradigms from other programming languages. In this talk, I will look towards a much more important source of ideas for the future of Ruby: The tools and practices the Ruby community is already using to develop successful Ruby projects.\n  video_provider: \"youtube\"\n  video_id: \"WWKN-fjn4E4\"\n"
  },
  {
    "path": "data/baruco/barcelona-ruby-conf-2014/event.yml",
    "content": "---\nid: \"barcelona-ruby-conf-2014\"\ntitle: \"Barcelona Ruby Conf 2014\"\ndescription: \"\"\nlocation: \"Barcelona, Spain\"\nkind: \"conference\"\nstart_date: \"2014-09-11\"\nend_date: \"2014-09-13\"\nwebsite: \"https://web.archive.org/web/20141219035936/http://www.baruco.org/\"\ntwitter: \"baruco\"\nplaylist: \"https://web.archive.org/web/20221006144651/http://confreaks.tv/events/baruco2014\"\ncoordinates:\n  latitude: 41.3874374\n  longitude: 2.1686496\nbanner_background: \"#332f50\"\nfeatured_background: \"#332f50\"\nfeatured_color: \"#ea1651\"\n"
  },
  {
    "path": "data/baruco/barcelona-ruby-conf-2014/videos.yml",
    "content": "# Website: https://web.archive.org/web/20141219035936/http://www.baruco.org/\n# Videos: https://www.youtube.com/watch?v=Q47FOiwXDh8&list=PLe9psSNJBf75BNEHA41k8SkGsssIF6A97\n---\n- id: \"yukihiro-matz-matsumoto-baruco-2014\"\n  title: \"mRuby: AltRuby\"\n  raw_title: \"Yukihiro 'Matz' Matsumoto - mRuby: AltRuby - BaRuCo 2014\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-12\"\n  published_at: \"2014-09-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5FLrKg-b6o8\"\n  kind: \"keynote\"\n\n- id: \"tom-stuart-refactoring-ruby-with-monads-baruco-2014\"\n  title: \"Refactoring Ruby with Monads\"\n  raw_title: \"Tom Stuart - Refactoring Ruby with Monads - BaRuCo 2014\"\n  speakers:\n    - Tom Stuart\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-12\"\n  published_at: \"2014-10-01\"\n  description: |-\n    Monads are in danger of becoming a bit of a joke: for every person who raves about them, there's another person asking what in the world they are, and a third person writing a confusing tutorial about them. With their technical-sounding name and forbidding reputation, monads can seem like a complex, abstract idea that's only relevant to mathematicians and Haskell programmers. Forget all that! In this pragmatic talk we'll roll up our sleeves and get stuck into refactoring some awkward Ruby code, using the good parts of monads to tackle the problems we encounter along the way. We'll see how the straightforward design pattern underlying monads can help us to make our code simpler, clearer and more reusable by uncovering its hidden structure, and we'll all leave with a shared understanding of what monads actually are and why people won't shut up about them.\n  video_provider: \"youtube\"\n  video_id: \"J1jYlPtkrqQ\"\n\n- id: \"jeremy-walker-baruco-2014\"\n  title: \"The Monorail\"\n  raw_title: \"Jeremy Walker - The Monorail - BaRuCo 2014\"\n  speakers:\n    - Jeremy Walker\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-12\"\n  published_at: \"2014-10-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ZM3-Gl5DVgM\"\n\n- id: \"evan-phoenix-baruco-2014\"\n  title: \"Services, Services, Everywhere\"\n  raw_title: \"Evan Phoenix - Services, Services, Everywhere - BaRuCo 2014\"\n  speakers:\n    - Evan Phoenix\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-12\"\n  published_at: \"2014-10-02\"\n  description: |-\n    \"Wrote more services!\" they say. Agreeing with them is only the first step of a long journey. How should you write them? How should you deploy them? How should you monitor them? 30 minutes isn't enough solve all your problems, but we'll look at the big picture of how you can build a modern application as a set of services.\n  video_provider: \"youtube\"\n  video_id: \"msxQqvPFTXE\"\n\n- id: \"julian-cheal-baruco-2014\"\n  title: \"Dancing with Robots\"\n  raw_title: \"Julian Cheal - Dancing with Robots - BaRuCo 2014\"\n  speakers:\n    - Julian Cheal\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-12\"\n  published_at: \"2014-10-09\"\n  description: |-\n    Web apps are great and everything, but imagine using Ruby to fly drones and make them dance to the sounds of dubstep! Or to control disco lights and other robots! Sounds fun, right? In this talk, we will not only explore how we can write code to make this possible, but it will also be full of exciting, interactive (and possibly dangerous ;) ) demos!\n  video_provider: \"youtube\"\n  video_id: \"xt7l5bUWIA8\"\n\n- id: \"erik-michaels-ober-baruco-2014\"\n  title: \"Writing Fast Ruby\"\n  raw_title: \"Erik Michaels-Ober - Writing Fast Ruby - BaRuCo 2014\"\n  speakers:\n    - Erik Michaels-Ober\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-12\"\n  published_at: \"2014-10-14\"\n  description: |-\n    Performance is one of the most important features of any application. Research has shown that every 100 milliseconds decrease in speed can reduce sales by 1 percent. Ruby is not known as a fast language but there are things we can do to optimize the performance of our Ruby code. This talk will show how to properly benchmark your Ruby code and discuss various techniques for making code faster and more memory efficient.\n  video_provider: \"youtube\"\n  video_id: \"fGFM_UrSp70\"\n\n- id: \"jose-tomas-albornoz-baruco-2014\"\n  title: \"How I Built My Own Twitch-Plays-Pokémon\"\n  raw_title: \"José Tomás Albornoz - How I built my own Twitch-Plays-Pokémon - BaRuCo 2014\"\n  speakers:\n    - José Tomás Albornoz\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-12\"\n  published_at: \"2014-10-12\"\n  description: |-\n    February 14th, 2014. 10 pm CET.: While pretty much everyone with a partner is having some quality \"Valentine's Day\" time, a very interesting social experiment is growing: Twitch Plays Pokémon. A massive Pokémon gaming session where literally dozens of thousands of people play the same match of game at the same time is not something you see every day. The hacker lightbulb lit immediately: I need to make my own, and I need to do it with Ruby.\n  video_provider: \"youtube\"\n  video_id: \"wuvDeUHhzts\"\n\n- id: \"emily-stolfo-baruco-2014\"\n  title: \"Release Responsibly\"\n  raw_title: \"Emily Stolfo - Release Responsibly - BaRuCo 2014\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-12\"\n  published_at: \"2014-10-17\"\n  description: |-\n    The Ruby community is notorious for favoring innovation over stability. The reality is that software usually has other dependencies not able to keep up with our pace. So how can we keep our code backwards compatible? Releasing responsibly is critical, whether you maintain an open source library, your company's codebase, or a personal project. On the MongoDB driver team, we recognize that it's easier to upgrade a driver than to upgrade a database. Our code must therefore hide all the gory details of backwards compatibility and continue to expose the simplest possible API version-to-version. I'll talk about some best practices we follow to make sure our users never have unexpected API inconsistencies, regardless of the underlying database version.\n  video_provider: \"youtube\"\n  video_id: \"OUgqej5SC_M\"\n\n- id: \"ryan-levick-baruco-2014\"\n  title: \"A Dangerous Game: Safety in Ruby\"\n  raw_title: \"Ryan Levick - A Dangerous Game: Safety in Ruby - BaRuCo 2014\"\n  speakers:\n    - Ryan Levick\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-13\"\n  published_at: \"2014-10-13\"\n  description: |-\n    Ruby is an awesome language. It allows us to tell the computer what we want it to do in beautiful, poetic ways that other programming languages simply cannot. While programs in other languages like Java or C++ mostly read like microwave oven manuals, Ruby often leaps out of our text editors as if it were elegantly crafted prose. But Ruby isn't perfect. It has its bad parts. When it comes to, for example, concurrency or guaranteeing correctness, Ruby often times feels less than ideal. But who's doing it better? In this talk we'll explore some of Ruby's shortcomings by examining other languages that handle these problems extremely well. We'll then discuss how Ruby can benefit from an understanding of these shortcomings and the languages that do these things better.\n  video_provider: \"youtube\"\n  video_id: \"mDPJD_0_T_k\"\n\n- id: \"piotr-szotkowski-baruco-2014\"\n  title: \"Standard Library: Uncommon Uses\"\n  raw_title: \"Piotr Szotkowski - Standard Library: Uncommon Uses - BaRuCo 2014\"\n  speakers:\n    - Piotr Szotkowski\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-13\"\n  published_at: \"2014-10-15\"\n  description: |-\n    There are tonnes of little- or virtually unknown libraries in Ruby's stdlib, and they found their way there for a reason. Much like revisiting Enumerable's method list times and again makes you a better Ruby programmer, so does looking into its standard library – not only because there are things you didn't know existed, but also because the way they're implemented is often quite enlightening. This talk shows some of the useful, clever and tricky uses of Ruby's standard library – like PStore, GServer, Abbrev, DRb and IPAddr – that do not require the installation of any gems and can be used in any environment hosting a Ruby implementation. Did you ever want to write your own server, do some distributed computing, don't worry about persistence? It's all there; come and see for yourself!\n  video_provider: \"youtube\"\n  video_id: \"JjOCj-J5K9I\"\n\n- id: \"brian-shirai-baruco-2014\"\n  title: \"Types as Premature Optimization\"\n  raw_title: \"Brian Shirai - Types as Premature Optimization - BaRuCo 2014\"\n  speakers:\n    - Brian Shirai\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-13\"\n  published_at: \"2014-09-30\"\n  description: |-\n    As programmers, when are we designing the software and when are we building it? What is the separation between these activities? Does it matter? What if we used two different languages: one to experiment with the basic structure of the program and one to build the software that is deployed? Consider these questions in the context of other creative activities. No buildings are built with clay; they are built with materials like steel, bricks, concrete blocks, or concrete and rebar. These materials are rigid and largely inflexible, properties that make them difficult to work with but are essential for the integrity and safety of the buildings. On the other hand, clay is a preeminent modeling material. It holds its shape but is easily malleable when experimenting with structure and relationships. In Ruby, we often use IRB to experiment with code or explore an API. We experiment with relationships and structure in our code. We make the software do something and that helps us better understand what we're trying to do. We write tests and code and iterate. Ruby's malleability makes it a preeminent clay for experimenting and learning, for designing the software. But what about building the software? What provides the rigidity we need for integrity and safety? Can a single language be both our clay and our steel and concrete?\n  video_provider: \"youtube\"\n  video_id: \"bF9x6L_77FU\"\n\n- id: \"jason-clark-baruco-2014\"\n  title: \"Spelunking in Ruby\"\n  raw_title: \"Jason Clark - Spelunking in Ruby - BaRuCo 2014\"\n  speakers:\n    - Jason Clark\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-13\"\n  published_at: \"2014-10-08\"\n  description: |-\n    We've all heard, \"With good tests, you don't need a debugger.\" But faced with unfamiliar or poorly covered code, tests can fall short. Debugging tools are indispensable for taking that next step, and the Ruby ecosystem provides many options to help. This talk showcases a wide variety of techniques for digging into that daunting application or gem. Starting from the humble puts statement, we'll dive through the various platform-specific Ruby debuggers, eventually peeking into the murky depths of gdb and the Ruby VM itself. Jam packed with shortcuts, techniques, and gotchas, you'll be plumbing the depths of your code in no time.\n  video_provider: \"youtube\"\n  video_id: \"hYtUODuxy9c\"\n\n- id: \"pat-shaughnessy-baruco-2014\"\n  title: \"Twenty Thousand Leagues Under ActiveRecord\"\n  raw_title: \"Pat Shaughnessy - Twenty Thousand Leagues Under ActiveRecord - BaRuCo 2014\"\n  speakers:\n    - Pat Shaughnessy\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-13\"\n  published_at: \"2014-09-29\"\n  description: |-\n    We all know ActiveRecord allows you to perform complex SQL queries using simple, elegant Ruby code. It's like magic, a useful magic we all use everyday in our Rails apps. But how does it actually work? We'll find out by first exploring the shallow waters just under ActiveRecord: What is relational algebra? How does the Arel gem generate SQL strings from Ruby objects? Later, we'll dive into much deeper waters - all the way inside the PostgreSQL database! We'll discover what does Postgres does with our SQL strings, where our data is actually located, and how Postgres finds what we want. Join me and learn exactly how your Rails app gets the data it needs. Like the strange places and creatures Jules Verne described in his underwater adventure, we'll discover fascinating data structures and computer science algorithms you never knew you were using.\n  video_provider: \"youtube\"\n  video_id: \"rnLnRPZZ1Q4\"\n\n- id: \"leon-gersing-baruco-2014\"\n  title: \"Keep Software Weird\"\n  raw_title: \"Leon Gersing - Keep Software Weird - BaRuCo 2014\"\n  speakers:\n    - Leon Gersing\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-13\"\n  published_at: \"2014-10-05\"\n  description: |-\n    How much code coverage does it take it ship a minimal viable product? How many Scrum Certifications does it take to make your team agile? How many languages learned make a journeyman a master? In software, there is an expressed desire to be taken seriously as craftspeople. To this end, we've introduced process, metrics and quantifiable boundaries as goal posts to hold up to those who may not understand what is involved in shipping quality software. As this practice becomes normal, developers are faced with an ever-expanding landscape of techniques, practices and pressure from thought leaders to take extra course work or certifications to validate the assertion that you are, in fact, a software developer. While some may see this as a necessary evolution of our field, I see it as an albatross around the neck of the creative developer looking to explore the depths of what is possible. While the safety of a well worn path may provide solace to the uninitiated, I find dogmatic implementation oppressive and exclusionary to those interested in exploring alternative approaches to solving problems with technology. Join me in an exploration of what I believe makes us unique as a subculture in this business world; examples of how we came to be by challenging the established idioms of the past in order to move forward into something exciting and new. To be our best we must be willing to dive into the unknown, to loose the binds of convention and explore the vast expanse of the unfamiliar. We must dare to be wrong, to be new, to be foolish, to be amazing and keep software weird.\n  video_provider: \"youtube\"\n  video_id: \"5HRgfxDtaPI\"\n\n- id: \"matt-aimonetti-baruco-2014\"\n  title: \"Go Auth Urself\"\n  raw_title: \"Matt Aimonetti - Go Auth Urself - BaRuCo 2014\"\n  speakers:\n    - Matt Aimonetti\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-13\"\n  published_at: \"2014-10-07\"\n  description: |-\n    Extending your Rails app with some Go, Scala, Elixir or node.js sound interesting to you? The first challenge to get there is to safely share the session between your apps. Crypto is hard… but that won't prevent us from looking into how Rails sessions work and how to share them across programming languages.\n  video_provider: \"youtube\"\n  video_id: \"vC5xR5CgThM\"\n\n- id: \"tom-stuart-smalltalk-lisp-bash-baruco-2014\"\n  title: \"Smalltalk, Lisp, Bash: Three Interesting Languages\"\n  raw_title: \"Tom Stuart - Smalltalk, Lisp, Bash: Three Interesting Languages - BaRuCo 2014\"\n  speakers:\n    - Tom Stuart @mortice\n  event_name: \"Barcelona Ruby Conf 2014\"\n  date: \"2014-09-13\"\n  published_at: \"2014-10-07\"\n  description: |-\n    In this talk, we take a brief tour of three languages which influenced the design of Ruby. We'll see how each of them has an extremely minimal specification, requiring the programmer to grasp only one or two concepts to understand the whole language. We'll see how this same characteristic allows us to implement our own control flow structures, and perhaps explore how we might pull off the same tricks in Ruby, which incorporates the basic concepts of all three languages.\n  video_provider: \"youtube\"\n  video_id: \"Cix0SYZ7CMo\"\n"
  },
  {
    "path": "data/baruco/barcelona-ruby-conf-2015/event.yml",
    "content": "---\nid: \"barcelona-ruby-conf-2015\"\ntitle: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\ndescription: |-\n  Barcelona Ruby Conference and Barcelona Future JS join forces on a single-track, weeklong event\nlocation: \"Barcelona, Spain\"\nkind: \"conference\"\nstart_date: \"2015-09-01\"\nend_date: \"2015-09-02\"\nwebsite: \"https://web.archive.org/web/20150712013812/http://www.fullstackfest.com/?from_baruco\"\ntwitter: \"baruco\"\ncoordinates:\n  latitude: 41.3874374\n  longitude: 2.1686496\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\naliases:\n  - Barcelona Ruby Conf 2015\n  - Full Stack Fest 2015\n"
  },
  {
    "path": "data/baruco/barcelona-ruby-conf-2015/videos.yml",
    "content": "# Website: https://web.archive.org/web/20150712013812/http://www.fullstackfest.com/?from_baruco\n# Videos: https://www.youtube.com/playlist?list=PLe9psSNJBf77PgzYZ2yId2RfUkd9_lMMr\n---\n- id: \"yukihiro-matz-matsumoto-barcelona-ruby-conf-2015\"\n  title: \"Ruby 3.0\"\n  raw_title: \"Full Stack Fest 2015: Ruby 3.0, by Yukihiro Matsumoto\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-01\"\n  published_at: \"2015-09-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"48iKjUcENRE\"\n  kind: \"keynote\"\n\n- id: \"davy-stevenson-barcelona-ruby-conf-2015\"\n  title: \"Orders of Magnitude\"\n  raw_title: \"Full Stack Fest 2015: Orders of Magnitude, by Davy Stevenson\"\n  speakers:\n    - Davy Stevenson\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-01\"\n  published_at: \"2015-09-23\"\n  description: |-\n    Up until the 17th century, the world was mostly limited to what we could see with the naked eye. Our understanding of things much smaller and much larger than us was limited. In the past 400 years our worldview has increased enormously, which has led to the advent of technology, space exploration, computers and the internet. However, our brains are ill equipped to handle dealing with numbers at these scales, and attempt to trick us at every turn.\n\n    Software engineers deal with computers every day, and thus we are subject to both incredibly tiny and massively large numbers all the time. Learn about how your brain is fooling you when you are dealing with issues of latency, scalability, and algorithm optimization, so that you can become a better programmer.\n  video_provider: \"youtube\"\n  video_id: \"_YyzLKhjpiI\"\n\n- id: \"bryan-liles-barcelona-ruby-conf-2015\"\n  title: \"Running Ruby Apps\"\n  raw_title: \"Full Stack Fest 2015: Running Ruby Apps, by Bryan Liles\"\n  speakers:\n    - Bryan Liles\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-01\"\n  published_at: \"2015-09-24\"\n  description: |-\n    Let's have a discussion about running ruby apps. After you've written your app, how does it run in production. How do you know it is running properly? Are there other ways to run your apps? Getting your apps running and giving you meaningful metrics is just as important as writing them.\n  video_provider: \"youtube\"\n  video_id: \"xytTA4dKaP0\"\n\n- id: \"eileen-uchitelle-barcelona-ruby-conf-2015\"\n  title: \"How to Performance\"\n  raw_title: \"Full Stack Fest 2015: How to Performance, by Eileen Uchitelle\"\n  speakers:\n    - Eileen Uchitelle\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-01\"\n  published_at: \"2015-09-25\"\n  description: |-\n    Understanding performance output can feel like reading tea leaves. It makes sense to a few people, but many of us are left in the dark; overwhelmed and frustrated by the data. On top of that there are a ton of performance tools to choose from; StackProf, RubyProf, AllocationTracer. Where do you even start?\n\n    While working on speeding up integration tests in Rails source, I learned that the key to improving performance of Ruby code is having a baseline, not relying on one profiler and understanding the advantages and limitations of your tools. By utilizing these methods integration test are now 3 times faster than they were in Rails 4.2.0, with more improvements being made every day.\n\n    In this talk we will not only look at how to read performance output, but when and how to use the right profilers for the job. We'll discuss a variety of methods and techniques for benchmarking and profiling so you can get the most out of each performance tool.\n  video_provider: \"youtube\"\n  video_id: \"HbLPLdLvnVo\"\n\n- id: \"aaron-patterson-barcelona-ruby-conf-2015\"\n  title: \"Request and Response\"\n  raw_title: \"Full Stack Fest 2015: Request and Response, by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-09-28\"\n  description: |-\n    What goes in to a request and response in a Rails application? Where does the application get its data, and how does that data get to the client when you are done? In this talk we'll look at the request and response lifecycle in Rails. We'll start with how a request and response are serviced today, then move on to more exciting topics like adding HTTP2 support and what that means for developing Rails applications.\n  video_provider: \"youtube\"\n  video_id: \"1EeWXojdqvU\"\n\n- id: \"sandi-metz-barcelona-ruby-conf-2015\"\n  title: \"Nothing is Something\"\n  raw_title: \"Full Stack Fest 2015: Nothing is Something, by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-09-30\"\n  description: |-\n    Our code is full of hidden assumptions, things that seem like nothing, secrets that we did not name and thus cannot see. These secrets represent missing concepts and this talk shows you how to expose these concepts with code that is easy to understand, change and extend. Being explicit about ideas will make your code simpler, your apps clearer and your life better. Even very small ideas matter. Everything, even nothing, is something.\n  video_provider: \"youtube\"\n  video_id: \"9mLK_8hKii8\"\n\n- id: \"aaron-quint-barcelona-ruby-conf-2015\"\n  title: \"Beyond JSON: Improving inter-app communication\"\n  raw_title: \"Full Stack Fest 2015: Beyond JSON: Improving inter-app communication, by Aaron Quint\"\n  speakers:\n    - Aaron Quint\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-09-29\"\n  description: |-\n    Regardless of where you stand on the debate between monoliths and microservices, the fact is that its never really one or the other. As your applications grow they often need to start communicating with other applications and services. Because we're often building for the web, we usually think of web protocols first (HTTP/JSON) when designing communication, but this might not be the best option for high throughput, high availability services.\n\n    I'll walk through some of the large number of options we have here including Protocol Buffers, Custom TCP Framing, and HTTP/2 and outline some of the pros and cons of each. I'll also walk through how we used some of these newer tools to build a high performance communication layer that's being used in production systems for almost 2 years.\n\n    You might walk away still using JSON and HTTP , but I hope that you have a better understanding of the tradeoffs you're making.\n  video_provider: \"youtube\"\n  video_id: \"WnUccA7us4A\"\n\n- id: \"rin-raeuber-barcelona-ruby-conf-2015\"\n  title: \"Skynet for Beginners\"\n  raw_title: \"Full Stack Fest 2015:  Skynet for Beginners, by Rin Raeuber\"\n  speakers:\n    - Rin Raeuber\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-10-01\"\n  description: |-\n    According to common knowledge Skynet went online on August 4, 1997. Suprisingly, we haven't heard anything from it since. Maybe because it's still struggling with the color of that dress. Or maybe because it was written in Excel VBA.\n\n    Either way, how about we apply some of those fancy sounding artificial intelligence techniques to the game problem of writing a twitter bot?\n\n    This talk will introduce you to artificial neural networks in an accessible and fun way.\n\n    Disclaimer: Might contain traces of code. Self-Awareness not included.\n  video_provider: \"youtube\"\n  video_id: \"KlDMZyEwRzk\"\n\n- id: \"yehuda-katz-barcelona-ruby-conf-2015\"\n  title: \"Rewriting a Ruby C Extension in Rust\"\n  raw_title: \"Full Stack Fest 2015: Rewriting a Ruby C Extension in Rust, by Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-10-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"2BdJeSC4FFI\"\n\n- id: \"nell-shamrell-barcelona-ruby-conf-2015\"\n  title: \"First Do No Harm: Surgical Refactoring\"\n  raw_title: \"Full Stack Fest 2015: First Do No Harm: Surgical Refactoring, by Nell Shamrell\"\n  speakers:\n    - Nell Shamrell\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-10-05\"\n  description: |-\n    When a developer comes into an existing code base the urge to refactor can be overwhelming. However, legacy code bases - even those created and maintained with the best intentions - often resemble living organisms more than modular machines. Rather than simply taking out a module and replacing it with a better one, we have to surgically slice intricately connected sections of a code base apart and precisely tie each one off to prevent it from bleeding into another section. We also have to operate with the fear that a change in one part of a system may adversely affect other parts or even kill a critical piece of our application or infrastructure. This talk will teach you how to recognize the difference between necessary and cosmetic refactoring and how to assess and evaluate the risks of each. You will also walk away knowing how to develop safeguards and bypasses to minimize potential harm before, during, and after a refactor, as well as how to recognize the point of no return when rolling back a refactoring is riskier than keeping it in production. Maintaining a code base means you must constantly juggle the wish to improve it through refactoring and the potential side effects of changing a functional and often critical code base - you will walk away from this talk with clear techniques to help you find and maintain this balance.\n  video_provider: \"youtube\"\n  video_id: \"9ZY3t9BnMeQ\"\n\n- id: \"ernie-miller-barcelona-ruby-conf-2015\"\n  title: \"How to Build a Skyscraper\"\n  raw_title: \"Full Stack Fest 2015: How to Build a Skyscraper, by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-10-06\"\n  description: |-\n    Since 1884, humans have been building skyscrapers. This means that we had 6 decades of skyscraper-building experience before we started building software (depending on your definition of \"software\"). Maybe there are some lessons we can learn from past experience?\n\n    This talk won't make you an expert skyscraper-builder, but you might just come away with a different perspective on how you build software.\n  video_provider: \"youtube\"\n  video_id: \"7MeBuDLbF98\"\n\n- id: \"piotr-solnica-barcelona-ruby-conf-2015\"\n  title: \"Blending Functional and OO Programming in Ruby\"\n  raw_title: \"Full Stack Fest 2015: Blending Functional and OO Programming in Ruby, by Piotr Solnica\"\n  speakers:\n    - Piotr Solnica\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-10-07\"\n  description: |-\n    Functional programming is being revitalized thanks to languages like Clojure, Haskell and Elixir. Even though Ruby is an object-oriented language there are many beautiful concepts in functional programming that we can borrow and successfully apply in our Ruby code.\n\n    In this talk I'll show you how I mix FP with OO. I'll introduce you to functional objects, explain the beauty of Proc-like behavior, the power of call method and explain why immutability matters.\n  video_provider: \"youtube\"\n  video_id: \"rMxurF4oqsc\"\n\n- id: \"corey-haines-barcelona-ruby-conf-2015\"\n  title: \"Fun with Lambdas!\"\n  raw_title: \"Full Stack Fest 2015: Fun with Lambdas!, by Corey Haines\"\n  speakers:\n    - Corey Haines\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-10-08\"\n  description: |-\n    You've probably heard about the lambda calculus, building up our computing structures from just the treasured lambda. But how much have you played with it? In this talk, armed only with Vim and the CLI, we'll explore some interesting topics in building up our world with just the lambda and the thought process while doing it. While you probably don't want to program day-to-day at this level, it definitely can help with how you think about your regular programming. This talk consists almost entirely of live coding. FUN TIMES!\n  video_provider: \"youtube\"\n  video_id: \"gULkBpl3e7c\"\n\n- id: \"john-cinnamond-barcelona-ruby-conf-2015\"\n  title: \"Extreme Object-Oriented Ruby\"\n  raw_title: \"Full Stack Fest 2015: Extreme Object-Oriented Ruby, by John Cinnamond\"\n  speakers:\n    - John Cinnamond\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-10-13\"\n  description: |-\n    I recently saw the talk 'Nothing is Something' by Sandi Metz and something caught my eye - the idea that Ruby doesn't need the 'if' keyword. This got me thinking: what else could we remove from the language without making it less powerful? In this talk I take this idea and push it to breaking point. Along the way we'll learn a lot about expressiveness, the limits of computation, the nature of programming and why we shouldn't try to create pure OO languages.\n  video_provider: \"youtube\"\n  video_id: \"FDs-sSxo2iY\"\n\n- id: \"lauren-scott-barcelona-ruby-conf-2015\"\n  title: \"Shall I Compare Thee to a Line of Code?\"\n  raw_title: \"Full Stack Fest 2015: Shall I Compare Thee to a Line of Code?, by Lauren Scott\"\n  speakers:\n    - Lauren Scott\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-10-14\"\n  description: |-\n    Ever wish that your peers called your code a \"work of art\"? What is it that artful programmers know that makes their work transcend functionality and become something that has value in its essence? There's a lot that we can learn from the arts, particularly from art forms that share our linguistic building blocks. Because as all programmers and poets know, writing is easy—it's writing the good stuff that's hard.\n\n    So what can we take from the study of poetry that would illuminate our own paths as developers? In this talk, I'll go through some poetic principles that clarify ideas about software development, both in the way we write our code and the way we grow as creators and teammates. We'll explore the way poets learn to shape their craft and see what we can steal to help our code level up from functioning to poetic.\n  video_provider: \"youtube\"\n  video_id: \"KvFRf8aDrrU\"\n\n- id: \"liz-abinante-barcelona-ruby-conf-2015\"\n  title: \"Why I Ruby\"\n  raw_title: \"Full Stack Fest 2015: Why I Ruby, by Liz Abinante\"\n  speakers:\n    - Liz Abinante\n  event_name: \"Barcelona Ruby Conf 2015 (Full Stack Fest 2015)\"\n  date: \"2015-09-02\"\n  published_at: \"2015-10-15\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"l0YcugodNoE\"\n  slides_url: \"https://speakerdeck.com/feministy/why-i-ruby-or-my-first-program\"\n"
  },
  {
    "path": "data/baruco/series.yml",
    "content": "---\nname: \"Barcelona Ruby Conf\"\nwebsite: \"http://web.archive.org/web/20141219035936/http://www.baruco.org/\"\ntwitter: \"baruco\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - BaRuCo\n  - Barcelona Ruby Conference\n"
  },
  {
    "path": "data/bathruby/bathruby-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYo1VtPcjHhtPxQ0cTzq5Tn\"\ntitle: \"Bath Ruby 2015\"\nkind: \"conference\"\nlocation: \"Bath, UK\"\ndescription: |-\n  Bath Ruby is a one day, single track conference in the beautiful British city of Bath, organised by Simon Starr with help from Andrew Nesbitt and Jordan Elver.\npublished_at: \"2015-03-15\"\nstart_date: \"2015-03-15\"\nend_date: \"2015-03-15\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\nbanner_background: \"#D52630\"\nfeatured_background: \"#D52630\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2015.bathruby.co.uk/\"\ncoordinates:\n  latitude: 51.3781018\n  longitude: -2.3596827\n"
  },
  {
    "path": "data/bathruby/bathruby-2015/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20150318155917/2015.bathruby.org/\n# Schedule: https://web.archive.org/web/20150427052910/http://2015.bathruby.org/schedule.html\n# Repo: https://github.com/bathruby/bathruby-2015\n\n# Friday, 13th March 2015\n\n# Registration\n\n# Welcome\n\n- id: \"linda-liukas-bath-ruby-2015\"\n  title: \"Principles of Play\"\n  raw_title: \"BathRuby 2015 - Principles of Play\"\n  speakers:\n    - Linda Liukas\n  event_name: \"Bath Ruby 2015\"\n  date: \"2015-03-15\"\n  description: |-\n    By, Linda Liukas\n    If code is the colouring pens and lego blocks of our times - the tools of creation - how do we teach the curiosity, joy and wonder to our kids? I spent last summer looking at programming and play: how to create experiences that go deeper than just learning logic.\n    So, just like Alice, I swallowed the blue pill and fell down inside the machine.\n\n  video_provider: \"youtube\"\n  video_id: \"8tmOAx4MWuw\"\n  published_at: \"2015-04-08\"\n\n# Break\n\n- id: \"ben-orenstein-bath-ruby-2015\"\n  title: \"TBC\"\n  raw_title: \"BathRuby 2015 - TBC\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"Bath Ruby 2015\"\n  date: \"2015-03-15\"\n  description: |-\n    By, Ben Orenstein\n\n  video_provider: \"youtube\"\n  video_id: \"PU3qIVAO9aM\"\n  published_at: \"2015-04-08\"\n\n# Break\n\n- id: \"saron-yitbarek-bath-ruby-2015\"\n  title: \"Learning Code Good\"\n  raw_title: \"BathRuby 2015 - Learning Code Good\"\n  speakers:\n    - Saron Yitbarek\n  event_name: \"Bath Ruby 2015\"\n  date: \"2015-03-15\"\n  description: |-\n    By, Saron Yitbarek\n\n  video_provider: \"youtube\"\n  video_id: \"-nsnAYRqYLA\"\n  published_at: \"2015-04-10\"\n\n# Break\n\n- id: \"todo-bath-ruby-2015\"\n  title: \"Lightning Talks (Part 1)\"\n  raw_title: \"BathRuby 2015 - Lightning Talks Pt 1\"\n  speakers:\n    - TODO\n  event_name: \"Bath Ruby 2015\"\n  date: \"2015-03-15\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Jp0VKD_7pmw\"\n  published_at: \"2015-04-10\"\n\n# Lunch\n\n- id: \"katrina-owen-bath-ruby-2015\"\n  title: \"Here Be Dragons\"\n  raw_title: \"BathRuby 2015 - Here Be Dragons\"\n  speakers:\n    - Katrina Owen\n  event_name: \"Bath Ruby 2015\"\n  date: \"2015-03-15\"\n  description: |-\n    By, Katrina Owen\n    It's not your fault. Code rots. We don't hold entropy against you, but we expect you to give a damn.\n    This story is about code that brings new meaning to the word 'legacy'. The accidental discovery of this body of code provoked a moral crisis. I wanted to pretend I hadn't seen it, yet I couldn't justify tiptoeing quietly away.\n    This talk examines the dilemmas we face when balancing our choices today with their cost tomorrow.\n    It's not your fault. Even so, it is your responsibility.\n\n  video_provider: \"youtube\"\n  video_id: \"QAUHYzC9kFM\"\n  published_at: \"2015-04-10\"\n\n# Break\n\n- id: \"tom-stuart-bath-ruby-2015\"\n  title: \"A Lever for the Mind\"\n  raw_title: \"BathRuby 2015 - A Lever for the Mind\"\n  speakers:\n    - Tom Stuart\n  event_name: \"Bath Ruby 2015\"\n  date: \"2015-03-15\"\n  description: |-\n    By, Tom Stuart\n    Abstraction is a tool that magnifies the force of the human mind. The use of abstraction to make complex ideas manageable is fundamental to our work as programmers and to human culture as a whole. That's why mathematics — the study of abstraction — is so important and powerful.\n    This is a talk about abstraction: where it comes from, what it's for, and how we can use it to make our programs better.\n\n  video_provider: \"youtube\"\n  video_id: \"VLN10ymRiQQ\"\n  published_at: \"2015-04-08\"\n\n# Break\n\n- id: \"todo-bath-ruby-2015-lightning-talks-part-2\"\n  title: \"Lightning Talks (Part 2)\"\n  raw_title: \"BathRuby 2015 - Lightning Talks Pt 2\"\n  speakers:\n    - TODO\n  event_name: \"Bath Ruby 2015\"\n  date: \"2015-03-15\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3ifeFIiOacA\"\n  published_at: \"2015-04-10\"\n\n# Break\n\n- id: \"sandi-metz-bath-ruby-2015\"\n  title: \"Nothing is Something\"\n  raw_title: \"BathRuby 2015 - Nothing is Something\"\n  speakers:\n    - Sandi Metz\n  event_name: \"Bath Ruby 2015\"\n  date: \"2015-03-15\"\n  description: |-\n    By, Sandi Metz\n    Our code is full of hidden assumptions, things that seem like nothing, secrets that we did not name and thus cannot see.\n    These secrets represent missing concepts and this talk shows you how to expose these concepts with code that is easy to understand, change and extend.\n    Being explicit about ideas will make your code simpler, your apps clearer and your life better. Even very small ideas matter. Everything, even nothing, is something.\n\n  video_provider: \"youtube\"\n  video_id: \"9lv2lBq6x4A\"\n  published_at: \"2015-04-10\"\n# Wrap Up\n\n# After Party\n"
  },
  {
    "path": "data/bathruby/bathruby-2016/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcya7KMrkWwbRvGfTcI5bQJn0\"\ntitle: \"Bath Ruby 2016\"\nkind: \"conference\"\nlocation: \"Bath, UK\"\ndescription: |-\n  Situated in the beautiful British city of Bath, this is a conference for Rubyists of all skill levels.\npublished_at: \"2016-03-11\"\nstart_date: \"2016-03-11\"\nend_date: \"2016-03-11\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2016\nbanner_background: \"#EC1C24\"\nfeatured_background: \"#EC1C24\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2016.bathruby.co.uk/\"\ncoordinates:\n  latitude: 51.3781018\n  longitude: -2.3596827\n"
  },
  {
    "path": "data/bathruby/bathruby-2016/schedule.yml",
    "content": "# Schedule: https://2016.bathruby.co.uk/schedule/\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2016-03-11\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:30\"\n        end_time: \"09:40\"\n        slots: 1\n        items:\n          - Welcome\n\n      - start_time: \"09:40\"\n        end_time: \"10:10\"\n        slots: 1\n        # Rocking out in Ruby - a playful introduction to Sonic Pi - Xavier Riley\n\n      - start_time: \"10:10\"\n        end_time: \"10:25\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:25\"\n        end_time: \"10:55\"\n        slots: 1\n        # Lightning Talks (Part 1)\n\n      - start_time: \"10:55\"\n        end_time: \"11:10\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:10\"\n        end_time: \"11:35\"\n        slots: 1\n        # How Neo4j Saved My Relationship - Coraline Ada Ehmke\n\n      - start_time: \"11:35\"\n        end_time: \"11:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:50\"\n        end_time: \"12:15\"\n        slots: 1\n        # Open Source for Your Benefit - Courteney Ervin\n\n      - start_time: \"12:15\"\n        end_time: \"12:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"12:30\"\n        end_time: \"13:00\"\n        slots: 1\n        # Lightning Talks (Part 2)\n\n      - start_time: \"13:00\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:30\"\n        end_time: \"15:05\"\n        slots: 1\n        # The Surprising Neuroscience of Gender Inequality - Janet Crawford\n\n      - start_time: \"15:05\"\n        end_time: \"15:20\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:20\"\n        end_time: \"15:50\"\n        slots: 1\n        # Firing People - Zach Holman\n\n      - start_time: \"15:50\"\n        end_time: \"16:05\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:05\"\n        end_time: \"16:35\"\n        slots: 1\n        # Lightning Talks (Part 3)\n\n      - start_time: \"16:35\"\n        end_time: \"16:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:50\"\n        end_time: \"17:35\"\n        slots: 1\n        # How are method calls formed? - Aaron Patterson\n\n      - start_time: \"17:35\"\n        end_time: \"17:45\"\n        slots: 1\n        items:\n          - Wrap Up\n\n      - start_time: \"17:45\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - After Party\n\ntracks:\n  - name: \"Main Track\"\n    color: \"#CC0000\"\n    text_color: \"#ffffff\"\n"
  },
  {
    "path": "data/bathruby/bathruby-2016/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsor\"\n      description: |-\n        Ruby tier sponsor of Bath Ruby 2016\n      level: 1\n      sponsors:\n        - name: \"Sky\"\n          website: \"http://www.workforsky.com/find-job/technology-and-product-development/\"\n          slug: \"sky\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/sky-216915f9.jpg\"\n\n    - name: \"Venue Sponsor\"\n      description: |-\n        Venue sponsor of Bath Ruby 2016\n      level: 2\n      sponsors:\n        - name: \"Bath & North East Somerset Council\"\n          website: \"http://bathnes.gov.uk/\"\n          slug: \"bath-and-north-east-somerset-council\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/banes-58a9566f.png\"\n\n    - name: \"Gold Sponsors\"\n      description: |-\n        Gold tier sponsors of Bath Ruby 2016\n      level: 3\n      sponsors:\n        - name: \"Bytemark\"\n          website: \"https://www.bytemark.co.uk/\"\n          slug: \"bytemark\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/bytemark-ad16ccfa.png\"\n\n        - name: \"uSwitch\"\n          website: \"http://www.uswitch.com/vacancies/\"\n          slug: \"uswitch\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/uswitch-ef290edb.png\"\n\n    - name: \"After Party Sponsor\"\n      description: |-\n        After Party sponsor of Bath Ruby 2016\n      level: 4\n      sponsors:\n        - name: \"Mailjet\"\n          website: \"https://www.mailjet.com/\"\n          slug: \"mailjet\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/mailjet-30e90e68.png\"\n\n    - name: \"Silver Sponsors\"\n      description: |-\n        Silver tier sponsors of Bath Ruby 2016\n      level: 5\n      sponsors:\n        - name: \"Pusher\"\n          website: \"https://pusher.com/\"\n          slug: \"pusher\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/pusher-6d5bb3c1.png\"\n\n        - name: \"Alliants\"\n          website: \"http://www.alliants.com/\"\n          slug: \"alliants\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/alliants-0a5d94c3.png\"\n\n        - name: \"CookiesHQ\"\n          website: \"http://cookieshq.co.uk/\"\n          slug: \"cookieshq\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/cookieshq-6a6f0326.png\"\n\n        - name: \"Bugsnag\"\n          website: \"http://bugsnag.com/\"\n          slug: \"bugsnag\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/bugsnag-ecbff93e.png\"\n\n        - name: \"Bristol & Bath\"\n          website: \"https://www.bristolandbath.co.uk/\"\n          slug: \"bristol-and-bath\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/bristol-and-bath-96bcbfbe.png\"\n\n        - name: \"FreeAgent\"\n          website: \"http://www.freeagent.com/\"\n          slug: \"freeagent\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/freeagent-a6ebb57f.png\"\n\n    - name: \"Bronze Sponsors\"\n      description: |-\n        Bronze tier sponsors of Bath Ruby 2016\n      level: 6\n      sponsors:\n        - name: \"Rawnet\"\n          website: \"http://www.rawnet.com/\"\n          slug: \"rawnet\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/rawnet-2b0511b7.png\"\n\n        - name: \"Novate IT\"\n          website: \"http://www.novate-it.co.uk/\"\n          slug: \"novate-it\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/novate-24c73606.jpg\"\n\n        - name: \"Epimorphics\"\n          website: \"http://www.epimorphics.com/\"\n          slug: \"epimorphics\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/epimorphics-317dfbb4.png\"\n\n        - name: \"Heroku\"\n          website: \"https://www.heroku.com/\"\n          slug: \"heroku\"\n          logo_url: \"https://2016.bathruby.co.uk/images/supporters/heroku-d1cef5e5.png\"\n"
  },
  {
    "path": "data/bathruby/bathruby-2016/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20170627223359/http://2016.bathruby.co.uk\n# Schedule: https://web.archive.org/web/20170627223359/http://2016.bathruby.co.uk/schedule/index.html\n# Repo: https://github.com/bathruby/bathruby-2016\n\n## Friday, 11th March 2016\n\n# Registration\n\n# Welcome\n\n- id: \"xavier-riley-bath-ruby-2016\"\n  title: \"Rocking Out In Ruby - A Playful Introduction to Sonic Pi\"\n  raw_title: \"BathRuby 2016 - Rocking Out In Ruby - A Playful Introduction to Sonic PI by Xavier Riley\"\n  speakers:\n    - Xavier Riley\n  event_name: \"Bath Ruby 2016\"\n  date: \"2016-03-11\"\n  description: |-\n    Rocking Out In Ruby - A Playful Introduction to Sonic PI by Xavier Riley\n\n  video_provider: \"youtube\"\n  video_id: \"L06FlSoiBi4\"\n  published_at: \"2016-03-25\"\n\n# Break\n\n- id: \"lightning-talks-part-1-bathruby-2016\"\n  title: \"Lightning Talks (Part 1)\"\n  raw_title: \"BathRuby 2016 - Lightning Talks Part One\"\n  event_name: \"Bath Ruby 2016\"\n  date: \"2016-03-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"J8qqR_PPChQ\"\n  published_at: \"2016-03-25\"\n  talks:\n    - title: \"Lightning Talk: Complexity\"\n      start_cue: \"00:20\"\n      end_cue: \"05:00\"\n      id: \"john-cinnamond-lighting-talk-bathruby-2016\"\n      video_id: \"john-cinnamond-lighting-talk-bathruby-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - John Cinnamond\n\n    - title: \"Lightning Talk: Ruby Papers We Love\"\n      start_cue: \"04:59\"\n      end_cue: \"08:23\"\n      id: \"chris-seaton-lighting-talk-bathruby-2016\"\n      video_id: \"chris-seaton-lighting-talk-bathruby-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Seaton\n\n    - title: \"Lightning Talk: Accessible events\"\n      start_cue: \"08:23\"\n      end_cue: \"14:54\"\n      id: \"florian-gilcher-lighting-talk-bathruby-2016\"\n      video_id: \"florian-gilcher-lighting-talk-bathruby-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Florian Gilcher\n\n    - title: \"Lightning Talk: Mistakes I Made Chasing Startup Success\"\n      start_cue: \"14:54\"\n      end_cue: \"21:08\"\n      id: \"andy-croll-lighting-talk-bathruby-2016\"\n      video_id: \"andy-croll-lighting-talk-bathruby-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Andy Croll\n\n# Break\n\n- id: \"coraline-ada-ehmke-bath-ruby-2016\"\n  title: \"How NEO4J Saved my Relationship\"\n  raw_title: \"BathRuby 2016 - How NEO4J Saved my Relationship by Coraline Ada Ehmke\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"Bath Ruby 2016\"\n  date: \"2016-03-11\"\n  description: |-\n    How NEO4J Saved my Relationship by Coraline Ada Ehmke\n\n    Relational databases have come a long way in the past decade, but sometimes complex data models (a map of network infrastructure, or a quantum-entangled network of social relationships) call for a different approach. How can we address these sorts of modeling challenges? This talk will explore practical uses of Neo4J, a graph database designed to solve the problems of connections and relations that are too complex for traditional relational databases. We'll learn about managing and querying highly connected data and explore the power of graph databases in taming our complex data problems.\n\n  video_provider: \"youtube\"\n  video_id: \"NfyieD5det8\"\n  published_at: \"2016-03-25\"\n\n# Break\n\n- id: \"courteney-ervin-bath-ruby-2016\"\n  title: \"Open Source for your Benefit\"\n  raw_title: \"BathRuby 2016 - Open Source for your Benefit by Courteney Ervin\"\n  speakers:\n    - Courteney Ervin\n  event_name: \"Bath Ruby 2016\"\n  date: \"2016-03-11\"\n  description: |-\n    Open Source for your Benefit by Courteney Ervin\n\n    \"Open Source is good for you,\" they whisper to you while you drink your coffee. \"Just open source it,\" they say, hovering above your desk. \"FOSS & GTD,\" they scream, smiling broadly and leaning ever more intimately forward with so many, many teeth.\n\n    Yes, open source is an incredibly important element of the tech ecosystem, and it can be a valuable and meaningful part of your career as a software developer. However, it’s important to do open source with your own personal needs and goals in mind. In this interactive talk, we’ll explore a collaborative, take-charge approach to open source contributions that doesn’t sacrifice your individual flair.\n\n  video_provider: \"youtube\"\n  video_id: \"qhm7XhM2nZk\"\n  published_at: \"2016-03-25\"\n\n# Break\n\n- id: \"lightning-talks-part-2-bathruby-2016\"\n  title: \"Lightning Talks (Part 2)\"\n  raw_title: \"BathRuby 2016 - Lightning Talks Round Two\"\n  event_name: \"Bath Ruby 2016\"\n  date: \"2016-03-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"48atSJksRls\"\n  published_at: \"2016-03-26\"\n  talks:\n    - title: \"Lightning Talk: Descent from Antiquity\"\n      start_cue: \"00:20\"\n      end_cue: \"TODO\"\n      id: \"christopher-turtle-lighting-talk-bathruby-2016\"\n      video_id: \"christopher-turtle-lighting-talk-bathruby-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Christopher Turtle\n\n    - title: \"Lightning Talk: Programming and Paragliding - Hopping from Cloud to Cloud\"\n      start_cue: \"04:48\"\n      end_cue: \"TODO\"\n      id: \"philip-szalwinski-lighting-talk-bathruby-2016\"\n      video_id: \"philip-szalwinski-lighting-talk-bathruby-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Philip Szalwinski\n\n    - title: \"Lightning Talk: The Wonky Limerick\"\n      start_cue: \"09:22\"\n      end_cue: \"TODO\"\n      id: \"andrew-faraday-lighting-talk-bathruby-2016\"\n      video_id: \"andrew-faraday-lighting-talk-bathruby-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Faraday\n\n    - title: \"Lightning Talk: The 'Manifesto for Responsible Software Development'\"\n      start_cue: \"13:37\"\n      end_cue: \"TODO\"\n      id: \"nils-lowe-lighting-talk-bathruby-2016\"\n      video_id: \"nils-lowe-lighting-talk-bathruby-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Nils Löwe\n\n    - title: \"Lightning Talk: Our anonymous hiring process on Rails\"\n      start_cue: \"18:19\"\n      end_cue: \"23:43\"\n      id: \"matthew-bloch-lighting-talk-bathruby-2016\"\n      video_id: \"matthew-bloch-lighting-talk-bathruby-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Matthew Bloch\n\n# Lunch\n\n- id: \"janet-crawford-bath-ruby-2016\"\n  title: \"The Surprising Neuroscience of Gender Inequality\"\n  raw_title: \"BathRuby 2016 - The Surprising Neuroscience of Gender Inequality by Janet Crawford\"\n  speakers:\n    - Janet Crawford\n  event_name: \"Bath Ruby 2016\"\n  date: \"2016-03-11\"\n  description: |-\n    The Surprising Neuroscience of Gender Inequality by Janet Crawford\n\n    When it comes to the tech industry and gender, intolerance and under-representation are daily news items. Yet despite the glaring ugliness of scandals like Gamergate, the prime culprit in gender inequity is likely not overt sexism. Implicit bias, a normal byproduct of our neural design, leads well-intentioned men and women to reinforce the status quo, while constricting creativity and limiting strategic vision. This talk explores the biological basis of bias and the responsibility we all hold in changing the story.\n\n  video_provider: \"youtube\"\n  video_id: \"cn-L7zjIYfI\"\n  published_at: \"2016-03-25\"\n\n# Break\n\n- id: \"zach-holman-bath-ruby-2016\"\n  title: \"Firing People\"\n  raw_title: \"BathRuby 2016 - Firing People by Zach Holman\"\n  speakers:\n    - Zach Holman\n  event_name: \"Bath Ruby 2016\"\n  date: \"2016-03-11\"\n  description: |-\n    Firing People by Zach Holman\n\n    People don’t talk about getting fired. We come up with euphemisms: \"I’m funemployed!\", or \"I’m looking for my next journey!\" That’s strange, when you think about it, given that it’s a fairly normal event that happens from time to time. But mostly it’s tragic, because unless we start talking about firing and getting fired, we can’t begin to start improving this very real — and often very painful — process.\n\n  video_provider: \"youtube\"\n  video_id: \"dxGen7sPWTw\"\n  published_at: \"2016-03-25\"\n\n# Break\n\n- id: \"lightning-talks-part-3-bathruby-2016\"\n  title: \"Lightning Talks (Part 3)\"\n  raw_title: \"BathRuby 2016 - Lightning Talks Part Three\"\n  event_name: \"Bath Ruby 2016\"\n  date: \"2016-03-11\"\n  description: |-\n    1. Adam Butler - Life experiments\n    2. Ed Robinson - GRPC and Ruby\n    3. Cheryl Morgan - Introducing Trans*Code\n    4. Phil Nash - We need more gems\n    5. Peter Saxton\n\n  video_provider: \"youtube\"\n  video_id: \"UT0Rl_EJNN4\"\n  published_at: \"2016-03-25\"\n  talks:\n    - title: \"Life experiments\"\n      start_cue: \"00:20\"\n      end_cue: \"04:48\"\n      video_provider: \"parent\"\n      id: \"adam-butler-lighting-talk-bathruby-2016\"\n      video_id: \"adam-butler-lighting-talk-bathruby-2016\"\n      speakers:\n        - Adam Butler\n\n    - title: \"GRPC and Ruby\"\n      start_cue: \"04:48\"\n      end_cue: \"08:54\"\n      video_provider: \"parent\"\n      id: \"ed-robinson-lighting-talk-bathruby-2016\"\n      video_id: \"ed-robinson-lighting-talk-bathruby-2016\"\n      speakers:\n        - Ed Robinson\n\n    - title: \"Introducing Trans*Code\"\n      start_cue: \"08:54\"\n      end_cue: \"13:16\"\n      video_provider: \"parent\"\n      id: \"cheryl-morgan-lighting-talk-bathruby-2016\"\n      video_id: \"cheryl-morgan-lighting-talk-bathruby-2016\"\n      speakers:\n        - Cheryl Morgan\n\n    - title: \"We Need More Gems\"\n      start_cue: \"13:16\"\n      end_cue: \"18:47\"\n      video_provider: \"parent\"\n      id: \"phil-nash-lighting-talk-bathruby-2016\"\n      video_id: \"phil-nash-lighting-talk-bathruby-2016\"\n      speakers:\n        - Phil Nash\n\n    - title: \"Building on domain concepts\"\n      start_cue: \"18:47\"\n      video_provider: \"parent\"\n      id: \"peter-saxton-lighting-talk-bathruby-2016\"\n      video_id: \"peter-saxton-lighting-talk-bathruby-2016\"\n      speakers:\n        - Peter Saxton\n\n# Break\n\n- id: \"aaron-patterson-bath-ruby-2016\"\n  title: \"How are Method Calls Formed?\"\n  raw_title: \"BathRuby 2016 - How are Method Calls Formed? by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Bath Ruby 2016\"\n  date: \"2016-03-11\"\n  description: |-\n    How are Method Calls Formed? by Aaron Patterson\n\n    In this presentation we're going to study how method calls are executed. We'll go from bytecode created by Ruby's Virtual Machine down to the C code where the methods actually get executed.\n\n    After we've learned about how Ruby executes methods today, we'll dive in to optimizations we can make on method dispatch including various types of inline method caching. You should leave with a better understanding of Ruby's VM internals as well as ways to analyze and optimize your own code. Also the presentation will have really great transitions in Keynote.\n  video_provider: \"youtube\"\n  video_id: \"b77V0rkr5rk\"\n  published_at: \"2016-03-25\"\n# Wrap Up\n\n# After Party\n"
  },
  {
    "path": "data/bathruby/bathruby-2018/event.yml",
    "content": "---\nid: \"PLwdNEzbHNELWqMRxZzenE6Lgp16rPXu9A\"\ntitle: \"Bath Ruby 2018\"\ndescription: |-\n  Situated in the beautiful British city of Bath, this is a conference for Rubyists of all skill levels.\nlocation: \"Bath, UK\"\nkind: \"conference\"\nstart_date: \"2018-03-22\"\nend_date: \"2018-03-23\"\nwebsite: \"https://2018.bathruby.co.uk/\"\ntwitter: \"bathruby\"\nplaylist: \"https://www.youtube.com/playlist?list=PLwdNEzbHNELWqMRxZzenE6Lgp16rPXu9A\"\nbanner_background: \"#150D2D\"\nfeatured_background: \"#150D2D\"\nfeatured_color: \"#EC1C24\"\ncoordinates:\n  latitude: 51.3781018\n  longitude: -2.3596827\n"
  },
  {
    "path": "data/bathruby/bathruby-2018/schedule.yml",
    "content": "# Schedule: https://2018.bathruby.co.uk/schedule/\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2018-03-22\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:40\"\n        end_time: \"10:30\"\n        slots: 1\n        # Keynote: Ruby After 25 Years - Yukihiro \"Matz\" Matsumoto\n\n      - start_time: \"10:30\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:45\"\n        end_time: \"11:25\"\n        slots: 1\n        # The Impermanence of Software - Andy Croll\n\n      - start_time: \"11:25\"\n        end_time: \"11:40\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:40\"\n        end_time: \"12:10\"\n        slots: 1\n        # The Case of The Missing Method - Nadia Odunayo\n\n      - start_time: \"12:10\"\n        end_time: \"12:25\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"12:25\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"13:00\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n        # Code and Fear - Valerie Woolard\n\n      - start_time: \"15:00\"\n        end_time: \"15:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n        # Helix: Native Extensions for Everyone - Terence Lee\n\n      - start_time: \"15:45\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"16:30\"\n        end_time: \"16:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:45\"\n        end_time: \"17:25\"\n        slots: 1\n        # Around the Ruby Block - Eliza de Jager\n\n  - name: \"Day 2\"\n    date: \"2018-03-23\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"10:50\"\n        slots: 1\n        # Is Ruby Died? A history of the invasions of England - Kerri Miller\n\n      - start_time: \"10:50\"\n        end_time: \"11:05\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:05\"\n        end_time: \"11:25\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"11:25\"\n        end_time: \"11:40\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:40\"\n        end_time: \"12:20\"\n        slots: 1\n        # Esoteric, Obfuscated, Artistic Programming in Ruby - Yusuke Endoh\n\n      - start_time: \"12:20\"\n        end_time: \"12:35\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"12:35\"\n        end_time: \"13:05\"\n        slots: 1\n        # Ouch! That Code Hurts My Brain - Sihui Huang\n\n      - start_time: \"13:05\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n        # Feature Flags - Raven Covington\n\n      - start_time: \"15:00\"\n        end_time: \"15:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:15\"\n        end_time: \"15:35\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"15:35\"\n        end_time: \"15:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:50\"\n        end_time: \"16:20\"\n        slots: 1\n        # Mental Models for Better Code - Najaf Ali\n\n      - start_time: \"16:20\"\n        end_time: \"16:35\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:35\"\n        end_time: \"17:05\"\n        slots: 1\n        # With a Little Help from My Friends - Andrew Nesbitt\n\n      - start_time: \"17:15\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - title: \"After Party\"\n            description: |-\n              Join us for drinks and networking to close out the conference.\n\ntracks:\n  - name: \"Main Track\"\n    color: \"#CC0000\"\n    text_color: \"#ffffff\"\n"
  },
  {
    "path": "data/bathruby/bathruby-2018/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsor\"\n      description: |-\n        Ruby tier sponsor of Bath Ruby 2018\n      level: 1\n      sponsors:\n        - name: \"Cookpad\"\n          website: \"http://bit.ly/cookpad-jobs\"\n          slug: \"cookpad\"\n          logo_url: \"https://2018.bathruby.co.uk/assets/images/supporters/cookpad.png\"\n\n    - name: \"Gold Sponsors\"\n      description: |-\n        Gold tier sponsors of Bath Ruby 2018\n      level: 2\n      sponsors:\n        - name: \"FreeAgent\"\n          website: \"https://www.freeagent.com/company/careers/\"\n          slug: \"freeagent\"\n          logo_url: \"https://2018.bathruby.co.uk/assets/images/supporters/freeagent.png\"\n\n    - name: \"Venue Sponsor\"\n      description: |-\n        Venue sponsor of Bath Ruby 2018\n      level: 3\n      sponsors:\n        - name: \"Invest in Bath\"\n          website: \"https://www.investinbath.co.uk\"\n          slug: \"invest-in-bath\"\n          logo_url: \"https://2018.bathruby.co.uk/assets/images/supporters/invest-in-bath.png\"\n          badge: \"Venue Sponsor\"\n\n    - name: \"Silver Sponsors\"\n      description: |-\n        Silver tier sponsors of Bath Ruby 2018\n      level: 4\n      sponsors:\n        - name: \"Bytemark\"\n          website: \"https://www.bytemark.co.uk/\"\n          slug: \"bytemark\"\n          logo_url: \"https://2018.bathruby.co.uk/assets/images/supporters/bytemark.png\"\n\n        - name: \"Focus\"\n          website: \"http://thisisfocus.co.uk/\"\n          slug: \"focus\"\n          logo_url: \"https://2018.bathruby.co.uk/assets/images/supporters/focus.png\"\n\n        - name: \"carwow\"\n          website: \"https://www.carwow.co.uk/jobs\"\n          slug: \"carwow\"\n          logo_url: \"https://2018.bathruby.co.uk/assets/images/supporters/carwow.png\"\n\n        - name: \"Government Digital Service\"\n          website: \"https://gds.blog.gov.uk\"\n          slug: \"government-digital-service\"\n          logo_url: \"https://2018.bathruby.co.uk/assets/images/supporters/gds.png\"\n\n        - name: \"Bugsnag\"\n          website: \"https://www.bugsnag.com\"\n          slug: \"bugsnag\"\n          logo_url: \"https://2018.bathruby.co.uk/assets/images/supporters/bugsnag.png\"\n\n        - name: \"BookingBug\"\n          website: \"https://www.bookingbug.co.uk/careers\"\n          slug: \"bookingbug\"\n          logo_url: \"https://2018.bathruby.co.uk/assets/images/supporters/bookingbug.png\"\n"
  },
  {
    "path": "data/bathruby/bathruby-2018/videos.yml",
    "content": "# Website: http://2018.bathruby.co.uk\n# Videos: https://www.youtube.com/playlist?list=PLwdNEzbHNELWqMRxZzenE6Lgp16rPXu9A\n---\n## Thursday, 22nd March 2018\n\n# Registration\n\n# Welcome\n\n- id: \"yukihiro-matz-matsumoto-bath-ruby-2018\"\n  title: \"Keynote: Ruby After 25 Years\"\n  raw_title: \"Yukihiro Matsumoto - Keynote\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"XXxAvDRPzA4\"\n  published_at: \"2018-11-09\"\n\n# Break\n\n- id: \"the-impermanence-of-software-bathruby-2018\"\n  title: \"The Impermanence of Software\"\n  raw_title: \"The Impermanence of Software - Andy Croll\"\n  speakers:\n    - Andy Croll\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-22\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"the-impermanence-of-software-bathruby-2018\"\n\n# Break\n\n- id: \"nadia-odunayo-bath-ruby-2018\"\n  title: \"The Case of The Missing Method — A Ruby Mystery Story\"\n  raw_title: \"The case of the missing method — a Ruby mystery story - Nadia Odunayo\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"nbZk7KqGILU\"\n  published_at: \"2018-05-15\"\n\n# Break\n\n# Lunch\n\n- id: \"code-and-fear-bathruby-2018\"\n  title: \"Code and Fear\"\n  raw_title: \"Code and Fear - Valerie Woolard\"\n  speakers:\n    - Valerie Woolard\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-22\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"code-and-fear-bathruby-2018\"\n\n# Break\n\n- id: \"terence-lee-bath-ruby-2018\"\n  title: \"Helix: Native Extensions for Everyone\"\n  raw_title: \"Helix: Native Extensions for Everyone - Terence Lee\"\n  speakers:\n    - Terence Lee\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"rVui2ZGIjzs\"\n  published_at: \"2018-05-15\"\n\n# Break\n\n- id: \"around-the-ruby-block-bathruby-2018\"\n  title: \"Around the Ruby Block\"\n  raw_title: \"Around the Ruby Block - Eliza de Jager\"\n  speakers:\n    - Eliza de Jager\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-22\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"around-the-ruby-block-bathruby-2018\"\n\n# Wrap Up\n\n## Friday, 23nd March 2018\n\n# Welcome\n\n- id: \"kerri-miller-bath-ruby-2018\"\n  title: \"Is Ruby Died? A history of the invasions of England\"\n  raw_title: \"Is Ruby Died? A history of the invasions of England - Kerri Miller\"\n  speakers:\n    - Kerri Miller\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"v3RRuUy8E6U\"\n  published_at: \"2018-05-01\"\n\n# Break\n\n- id: \"yusuke-endoh-bath-ruby-2018\"\n  title: \"Esoteric, Obfuscated, Artistic Programming in Ruby\"\n  raw_title: \"Esoteric, Obfuscated, Artistic Programming in Ruby - Yusuke Endoh\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ky1GNpT1dEw\"\n  published_at: \"2018-11-09\"\n\n# Break\n\n- id: \"ouch-that-code-hurts-my-brain-bathruby-2018\"\n  title: \"Ouch! That Code Hurts My Brain\"\n  raw_title: \"Ouch! That Code Hurts My Brain - Sihui Huang\"\n  speakers:\n    - Sihui Huang\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-23\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"ouch-that-code-hurts-my-brain-bathruby-2018\"\n\n# Break\n\n# Lunch\n\n- id: \"raven-covington-bath-ruby-2018\"\n  title: \"Feature Flags\"\n  raw_title: \"Feature Flags - Raven Covington\"\n  speakers:\n    - Raven Covington\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DXuyKsf1k1Q\"\n  published_at: \"2018-05-15\"\n\n# Break\n\n- id: \"najaf-ali-bath-ruby-2018\"\n  title: \"Mental Models for Better Code\"\n  raw_title: \"Mental Models for Better Code - Najaf Ali\"\n  speakers:\n    - Najaf Ali\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"wZ4ONrAU8fE\"\n  published_at: \"2018-05-01\"\n\n# Break\n\n- id: \"andrew-nesbitt-bath-ruby-2018\"\n  title: \"With a Little Help from My Friends\"\n  raw_title: \"With a Little Help from My Friends - Andrew Nesbitt\"\n  speakers:\n    - Andrew Nesbitt\n  event_name: \"Bath Ruby 2018\"\n  date: \"2018-03-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"hW4wUpoBHr8\"\n  published_at: \"2018-05-01\"\n# Wrap Up\n\n# After Party\n"
  },
  {
    "path": "data/bathruby/series.yml",
    "content": "---\nname: \"BathRuby\"\nwebsite: \"https://github.com/bathruby\"\ntwitter: \"bathruby\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"BathRuby\"\ndefault_country_code: \"UK\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/belfastruby/belfast-rubyfest-2026/event.yml",
    "content": "---\nid: \"belfast-rubyfest-2026\"\ntitle: \"Belfast RubyFest 2026\"\nkind: \"event\"\nstart_date: \"2026-02-11\"\nend_date: \"2026-02-11\"\nfrequency: \"yearly\"\nlocation: \"Belfast, Northern Ireland, UK\"\ndescription: |-\n  A celebration of community, creativity, and all the wonderful things you can build with Ruby. This inaugural Ruby conference features interactive workshops, talks on game development and music composition using Ruby, live music and games created with Ruby, plus catered food and drinks.\nbanner_background: \"#050307\"\nfeatured_background: \"#5F0A05\"\nfeatured_color: \"#FBDE5F\"\nluma: \"https://lu.ma/yl6v0cy9\"\nwebsite: \"https://lu.ma/yl6v0cy9\"\ntickets_url: \"https://lu.ma/yl6v0cy9\"\ncoordinates:\n  latitude: 54.5930246\n  longitude: -5.9307359\n"
  },
  {
    "path": "data/belfastruby/belfast-rubyfest-2026/schedule.yml",
    "content": "# Schedule: Belfast RubyFest 2026\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2026-02-11\"\n    grid:\n      - start_time: \"17:00\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - title: \"Doors\"\n            description: |-\n              Bar onsite\n\n      - start_time: \"18:00\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - \"Light food and refreshments\"\n\n      - start_time: \"18:20\"\n        end_time: \"18:20\"\n        slots: 1\n        items:\n          - title: \"Welcome\"\n            description: |-\n              Nick Schwaderer\n\n      - start_time: \"18:30\"\n        end_time: \"18:30\"\n        slots: 1\n\n      - start_time: \"19:40\"\n        end_time: \"19:40\"\n        slots: 1\n\n      - start_time: \"20:20\"\n        end_time: \"20:20\"\n        slots: 1\n\n      - start_time: \"21:00\"\n        end_time: \"onwards\"\n        slots: 1\n        items:\n          - title: \"Post-event drinks\"\n            description: |-\n              Onsite and nearby\n\ntracks: []\n"
  },
  {
    "path": "data/belfastruby/belfast-rubyfest-2026/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      level: 1\n      sponsors:\n        - name: \"GitHub\"\n          website: \"https://github.com\"\n          slug: \"github\"\n          logo_url: \"https://images.lumacdn.com/cdn-cgi/image//editor-images/8v/01c81d53-72f6-4465-8b46-9a6d161dbb6c.png\"\n\n        - name: \"Ruby Central\"\n          website: \"https://rubycentral.org\"\n          slug: \"rubycentral\"\n          logo_url: \"https://images.lumacdn.com/cdn-cgi/image//editor-images/t6/46bcbc15-b87b-45e3-88dc-9d9673b53371.png\"\n\n        - name: \"Stora\"\n          website: \"https://stora.co\"\n          slug: \"stora\"\n          logo_url: \"https://images.lumacdn.com/cdn-cgi/image//editor-images/o1/1ce71b36-0c47-45f7-a68a-a7b44fce839b.png\"\n\n        - name: \"AppSignal\"\n          website: \"https://appsignal.com\"\n          slug: \"appsignal\"\n          logo_url: \"https://images.lumacdn.com/cdn-cgi/image//editor-images/gv/5fbab09e-d8be-4184-a5d3-725ae645a85d.png\"\n"
  },
  {
    "path": "data/belfastruby/belfast-rubyfest-2026/venue.yml",
    "content": "---\nname: \"Clayton Hotel Belfast\"\n\naddress:\n  street: \"22-26 Ormeau Avenue\"\n  city: \"Belfast\"\n  postal_code: \"BT2 8HS\"\n  country: \"United Kingdom\"\n  country_code: \"GB\"\n  display: \"22-26 Ormeau Ave, Belfast BT2 8HS, UK\"\n\ncoordinates:\n  latitude: 54.5930246\n  longitude: -5.9307359\n\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=54.5930246,-5.9307359\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=54.5930246&mlon=-5.9307359&zoom=17\"\n"
  },
  {
    "path": "data/belfastruby/belfast-rubyfest-2026/videos.yml",
    "content": "---\n- id: \"christian-bruckmayer-belfast-rubyfest-2026\"\n  title: \"Test Smarter, Not Harder - Crafting a Test Selection Framework from Scratch\"\n  raw_title: \"Test Smarter, Not Harder - Crafting a Test Selection Framework from Scratch\"\n  speakers:\n    - Christian Bruckmayer\n  event_name: \"Belfast RubyFest 2026\"\n  date: \"2026-02-11\"\n  description: \"\"\n  video_id: \"christian-bruckmayer-belfast-rubyfest-2026\"\n  video_provider: \"scheduled\"\n\n- id: \"julian-cheal-belfast-rubyfest-2026\"\n  title: \"Making Massively Multiplayer Games with DragonRuby\"\n  raw_title: \"Making Massively Multiplayer Games with DragonRuby\"\n  speakers:\n    - Julian Cheal\n  event_name: \"Belfast RubyFest 2026\"\n  date: \"2026-02-11\"\n  description: \"\"\n  video_id: \"julian-cheal-belfast-rubyfest-2026\"\n  video_provider: \"scheduled\"\n\n- id: \"thijs-cadier-belfast-rubyfest-2026\"\n  title: \"How music works, using Ruby\"\n  raw_title: \"How music works, using Ruby\"\n  speakers:\n    - Thijs Cadier\n  event_name: \"Belfast RubyFest 2026\"\n  date: \"2026-02-11\"\n  description: \"\"\n  video_id: \"thijs-cadier-belfast-rubyfest-2026\"\n  video_provider: \"scheduled\"\n"
  },
  {
    "path": "data/belfastruby/belfastruby-meetup/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://docs.google.com/forms/d/e/1FAIpQLSfCZ-BBgEPbPiz5yE4zrIiwtF5UlyVQSxo0zcAAvLg9pimHLw/viewform\"\n  open_date: \"2026-01-20\"\n"
  },
  {
    "path": "data/belfastruby/belfastruby-meetup/event.yml",
    "content": "---\nid: \"belfastruby\"\ntitle: \"Belfast Ruby Meetup\"\nkind: \"meetup\"\nlocation: \"Belfast, Northern Ireland, UK\"\ndescription: \"\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#F1D3D9\"\nfeatured_color: \"#A50000\"\nluma: \"https://lu.ma/BelfastRuby\"\nmeetup: \"https://www.meetup.com/belfastruby\"\nwebsite: \"https://lu.ma/BelfastRuby\"\ncoordinates:\n  latitude: 54.59728500000001\n  longitude: -5.93012\n"
  },
  {
    "path": "data/belfastruby/belfastruby-meetup/videos.yml",
    "content": "---\n- title: \"Belfast Ruby Meetup December 2015\"\n  raw_title: \"Belfast Ruby: December Meetup\"\n  event_name: \"Belfast Ruby Meetup December 2015\"\n  date: \"2015-12-01\"\n  video_provider: \"children\"\n  video_id: \"belfast-ruby-meetup-december-2015\"\n  id: \"belfast-ruby-meetup-december-2015\"\n  description: |-\n    Time to update your diaries, as the December 2015 BelfastRuby (http://belfastruby.com/) meetup has now been confirmed! We have three great talks lined up, suited to both the aspiring and experienced Rubyists among us.\n\n    Your unit tests may be working, but did you actually deliver that feature you promised? Let's take a step back, and test your web application as a whole - as the user would. Our first talk is presented by Alan Foster (http://www.alanfoster.me) who will discuss automated Capybara Feature Testing in Ruby.\n\n    Following Alan, Andrew Carr (https://twitter.com/ac2u) will be giving a talk on alternative rails architectures.\n\n    The third and final talk will be given by Lead ShopKeep (http://www.shopkeep.com/) Engineer Paul Guelpa. Paul will be specially visiting from the New York offices to impart his wisdom on how implementing ShopKeep's platform services in Go has taught him more about Ruby.\n\n    With the next meetup being so close to the festivity of Christmas, let's start the celebrations with mulled wine and food.\n\n    Be sure to watch this space for any updates!\n\n    https://www.meetup.com/belfastruby/events/226588609\n  talks:\n    []\n    # TODO: Add talks\n\n- title: \"Belfast Ruby Meetup March 2016\"\n  raw_title: \"Belfast Ruby: March Meetup\"\n  event_name: \"Belfast Ruby Meetup March 2016\"\n  date: \"2016-03-15\"\n  video_provider: \"children\"\n  video_id: \"belfast-ruby-meetup-march-2016\"\n  id: \"belfast-ruby-meetup-march-2016\"\n  description: |-\n    It's the new year, and BelfastRuby is back better than ever! The March 2016 meetup has two great beginner-friendly talks lined up. Be sure to not miss out!\n\n    James Burns will be delivering a talk on mobile testing with Ruby and Appium. Appium is an open source test automation framework for use with native, hybrid and mobile web apps. It drives iOS and Android apps using the WebDriver protocol.\n\n    Our second talker Heather McNamee, from GitLab (https://about.gitlab.com/) will be showing us how to effectively use Git Version Control Workflow within your projects. Specifically delving into how you can use GitLab to create branches, changes, and merge pull requests - and what is happening behind the scenes within Git to make this all happen.\n\n    Our final talker, David Kennedy of Shopkeep (http://www.shopkeep.com/) will present his beginner-friendly talk, \"Ruby makes me happy\". Where he will discuss the reasons why he loves Ruby, and what makes Ruby awesome!\n\n    As always, the next meetup will have Beer, Soft Drinks, and Pizza! Come meet us at the Hub within Queen's University Belfast Student Guidance Center, to the left of the Student's Union\n\n    Be sure to watch this space for any updates!\n\n    https://www.meetup.com/belfastruby/events/229455224\n  talks:\n    []\n    # TODO: Add talks\n\n- title: \"Belfast Ruby Meetup March 2017\"\n  raw_title: \"Belfast Ruby: Reboot & March Meetup\"\n  event_name: \"Belfast Ruby Meetup March 2017\"\n  date: \"2017-03-28\"\n  video_provider: \"children\"\n  video_id: \"belfast-ruby-meetup-march-2017\"\n  id: \"belfast-ruby-meetup-march-2017\"\n  description: |-\n    Hi,\n\n    In 2017 we want to reboot Belfast Ruby and have regular bi-monthly meetups again. This will take a group effort so please come along if you are interested.\n\n    We have lined up a meetup (venue to be decided) on Tuesday the 28th of March 2017. We have three great talks lined up.\n\n    Pete Hawkins\n\n    Pete (https://twitter.com/peteyhawkins) of Dawson & Andrews (https://dawsonandrews.com/) will give a talk on rails 5 + webpack and how to enrich your project with a suite of rich client side features.\n\n    David Schmitt\n\n    David (https://puppet.com/blog/author/david-schmitt) of Puppet Labs will give an introductory talk on RSpec the behaviour driven development framework.\n\n    Stephen McCullough\n\n    Stephen (http://twitter.com/swmcc) of ShopKeep (http://www.shopkeep.com) will build a bot for Slack. The time allotted is 30mins. The aim for this talk is:\n\n    • test driven\n\n    • have a bot talking in the belfastruby slack room\n\n    • pushed onto github so attendees can offer PRs in the form of bugfixes or enhancements later\n\n    Hope to see you there,\n\n    Stephen\n\n    https://www.meetup.com/belfastruby/events/238111264\n  talks:\n    []\n    # TODO: Add talks\n\n- title: \"Belfast Ruby Meetup November 2023\"\n  raw_title: \"Belfast Ruby: The Reboot Meetup\"\n  event_name: \"Belfast Ruby Meetup November 2023\"\n  date: \"2023-11-15\"\n  video_provider: \"children\"\n  video_id: \"belfast-ruby-meetup-november-2023\"\n  id: \"belfast-ruby-meetup-november-2023\"\n  description: |-\n    Belfast Ruby: The Reboot Meetup\n\n    Hello, Ruby enthusiasts of Belfast!\n\n    We're excited to invite you to a special kind of meetup, one without talks but plenty of conversation. We're calling it \"Reboot\", and the aim is simple: to have an open dialogue about what we want BelfastRuby to be, moving forward. We'd like to hear your thoughts, gauge interest in future talks, workshops, and events, and generally make plans to revive and rejuvenate our community.\n\n    There will be pizza!\n    Stora, a local Belfast-based startup, is generously sponsoring our next event! We're thrilled to announce that thanks to their support, we will not only have a great venue at FarsetLabs but also some delicious pizza to enjoy. Stora uses Ruby to drive their innovative business solutions, reflecting the spirit of our Belfast Ruby community. To learn more about them, check out their website at https://stora.co. A huge thank you to Stora for their help – their sponsorship is a perfect example of how local companies are playing a vital role in supporting and nurturing our community.\n\n    Let's Set the Agenda Together\n    If you have any ideas for the meetup or want to discuss potential topics, feel free to join the conversation on our Slack group, specifically the NI Tech #belfastruby channel.\n\n    We're really looking forward to seeing you there and reimagining what BelfastRuby can become with your input. Let's reboot and build something amazing together!\n\n    Best wishes,\n\n    The BelfastRuby Team\n\n    https://www.meetup.com/belfastruby/events/296946915\n  talks:\n    []\n    # TODO: Add talks\n\n- title: \"Belfast Ruby Meetup March 2024 (Cancelled)\"\n  raw_title: \"Belfast Ruby: The Campfire Code Review Meetup\"\n  event_name: \"Belfast Ruby Meetup March 2024\"\n  date: \"2024-03-06\"\n  status: \"cancelled\"\n  video_provider: \"children\"\n  video_id: \"belfast-ruby-meetup-march-2024\"\n  id: \"belfast-ruby-meetup-march-2024\"\n  description: |-\n    Belfast Ruby: The Campfire Code Review Meetup\n\n    Location: FarsetLabs - Weavers Court - Belfast - BT12 5GH\n\n    Sponsored by: SkillfulGorilla\n\n    Hello, Ruby enthusiasts of Belfast!\n\n    We're excited to invite you to a special kind of meetup, one without talks but plenty of conversation. It’s an attempt at a new kind of community led discussion around a piece of software. This time the special guest is 37signals \"Campfire\" (ONCE), and the aim is simple: to have an open dialogue about what the code base as we dive in together.\n\n    Join us on this first (of hopefully many) explorations of Ruby source code.\n\n    Suggestions welcone\n    The plan is to do a little preparation ahead of time to pull some stats and charts etc from analysis tools and try and pull together a visualisation of how the whole thing works as we review it together properly for the first time. No spoilers.\n\n    Let's Set the Agenda Together\n    If you have any ideas for the meetup for tools you would like to see run against the code, please message @davidjrice on Twitter(x)\n\n    We're really looking forward to seeing you there and prototyping a more collaborative style of event for BelfastRuby that could become something awesome with your input. Let's build something amazing together!\n\n    Pizza and soft drinks\n    Food will be provided by our sponsor - SkillfulGorilla - a local boutique software consultancy.\n\n    Best wishes,\n\n    The BelfastRuby Team\n  talks: []\n\n- title: \"Belfast Ruby Meetup September 2024\"\n  raw_title: \"Belfast Ruby: Rails\"\n  event_name: \"Belfast Ruby Meetup September 2024\"\n  date: \"2024-09-24\"\n  video_provider: \"children\"\n  video_id: \"belfast-ruby-meetup-september-2024\"\n  id: \"belfast-ruby-meetup-september-2024\"\n  description: |-\n    Join us for the next Belfast Ruby Meetup, where the agenda is up to you! Whether you want to hang out, share something interesting, or give a casual talk, your input will shape the event.\n\n    Cast your vote in the #belfastruby room on the Northern Ireland Tech Slack to help decide the lineup. Stay tuned for updates on the final plan. Hosted at Magnite and proudly sponsored by SkillfulGorilla. Don’t miss this chance to connect with the Ruby community in Belfast!\n\n    https://www.meetup.com/belfastruby/events/306590652\n  talks:\n    []\n    # TODO: Add talks\n\n- title: \"Belfast Ruby Meetup April 2025\"\n  raw_title: \"Belfast Ruby: James Stocks, Pablo Brasero, Matt Hutchinson, Nick Schwaderer\"\n  event_name: \"Belfast Ruby Meetup April 2025\"\n  date: \"2025-04-02\"\n  video_provider: \"children\"\n  video_id: \"belfast-ruby-meetup-april-2025\"\n  id: \"belfast-ruby-meetup-april-2025\"\n  description: |-\n    BelfastRuby's first Meetup of 2025 is here!\n\n    We hope you will join us for an evening of fun and talking about the language we love.\n\n    Where: Farset Labs\n\n    When: Wednesday, April 2nd, 6-9pm. Talks start at 7pm, feel free to filter in any time from 6-7.\n\n    What:\n\n    We have four lovely speakers doing lightning talks:\n    * James Stocks - DragonRuby (Write video games in Ruby!)\n    * Pablo Brasero - Adventures in Rails Performance\n    * Matt Hutchinson - Hey! Hot Hotwire Tips\n    * Nick Schwaderer - Building desktop applications in Ruby in 2025\n\n    Refreshments: Complementary beer, pizza and soft drinks will be provided by our sponsor\n\n    https://www.meetup.com/belfastruby/events/306590652\n  talks:\n    - title: \"DragonRuby (Write video games in Ruby!)\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Belfast Ruby Meetup April 2025\"\n      date: \"2025-04-02\"\n      speakers:\n        - James Stocks\n      id: \"james-stocks-belfast-ruby-meetup-april-2025\"\n      video_id: \"james-stocks-belfast-ruby-meetup-april-2025\"\n      video_provider: \"not_recorded\"\n\n    - title: \"Adventures in Rails Performance\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Belfast Ruby Meetup April 2025\"\n      date: \"2025-04-02\"\n      speakers:\n        - Pablo Brasero\n      id: \"pablo-brasero-belfast-ruby-meetup-april-2025\"\n      video_id: \"pablo-brasero-belfast-ruby-meetup-april-2025\"\n      video_provider: \"not_recorded\"\n\n    - title: \"Hey! Hot Hotwire Tips\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Belfast Ruby Meetup April 2025\"\n      date: \"2025-04-02\"\n      speakers:\n        - Matt Hutchinson\n      id: \"matt-hutchinson-belfast-ruby-meetup-april-2025\"\n      video_id: \"matt-hutchinson-belfast-ruby-meetup-april-2025\"\n      video_provider: \"not_recorded\"\n\n    - title: \"Building desktop applications in Ruby in 2025\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Belfast Ruby Meetup April 2025\"\n      date: \"2025-04-02\"\n      speakers:\n        - Nick Schwaderer\n      id: \"nick-schwaderer-belfast-ruby-meetup-april-2025\"\n      video_id: \"nick-schwaderer-belfast-ruby-meetup-april-2025\"\n      video_provider: \"not_recorded\"\n\n- title: \"Belfast Ruby Meetup June 2025\"\n  raw_title: \"Belfast Ruby: Marco Roth & John Gallagher\"\n  event_name: \"Belfast Ruby Meetup June 2025\"\n  date: \"2025-06-10\"\n  video_provider: \"children\"\n  video_id: \"belfast-ruby-meetup-june-2025\"\n  id: \"belfast-ruby-meetup-june-2025\"\n  description: |-\n    We hope you will join us for an evening of fun and talking about the language we love.\n\n    Speakers\n\n    Marco Roth: Scaling RubyEvents.org: The mission to index all Ruby conferences\n\n    Maintainer of rubyvideo.dev, gem.sh and RubyConferences.org\n    Core team StimulusReflex/CableReady\n    Hotwire Contributors Team\n    Maintainer of 14 popular Ruby projects\n    Given at least 17 conference talks\n\n    John Gallagher: Fix Bugs 20x Faster - The Power of Structured Logging in Rails\n\n    Joyful Programming Coach\n    Principal Engineer at Dynatrace\n    Author of Software Design Simplified\n    Sponsor: Sorcer\n\n    Sorcer are a specialist Ruby recruitment company who are trying to bring change to the industry by providing an honest and trustworthy service to their candidates and clients - 'recruitment with morals’. They cover the UK, US and Europe and also host a podcast; RubySorce and run a community for leaders in the Ruby space; The Rails Track\n\n    If you are looking for a new job, looking to hire Ruby people or just generally curious, you can reach out to them here: sawan@sorcer.io / www.sorcer.io\n\n    https://lu.ma/nfivv402\n    https://www.meetup.com/belfastruby/events/307911039\n  talks:\n    - title: \"Scaling RubyEvents.org: The mission to index all Ruby conferences\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Belfast Ruby Meetup June 2025\"\n      date: \"2025-06-10\"\n      speakers:\n        - Marco Roth\n      id: \"marco-roth-belfast-ruby-meetup-june-2025\"\n      video_id: \"marco-roth-belfast-ruby-meetup-june-2025\"\n      video_provider: \"not_recorded\"\n      slides_url: \"https://speakerdeck.com/marcoroth/scaling-rubyevents-dot-org-the-mission-to-index-all-ruby-conferences-at-belfastruby-meetup-june-2025\"\n\n    - title: \"Fix Bugs 20x Faster - The Power of Structured Logging in Rails\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Belfast Ruby Meetup June 2025\"\n      date: \"2025-06-10\"\n      speakers:\n        - John Gallagher\n      id: \"john-gallagher-belfast-ruby-meetup-june-2025\"\n      video_id: \"john-gallagher-belfast-ruby-meetup-june-2025\"\n      video_provider: \"not_recorded\"\n\n- title: \"Belfast Ruby Meetup September 2025\"\n  raw_title: \"BelfastRuby x PyBelfast at TeamFeePay\"\n  event_name: \"Belfast Ruby Meetup September 2025\"\n  date: \"2025-09-10\"\n  video_provider: \"children\"\n  video_id: \"belfast-ruby-meetup-september-2025\"\n  id: \"belfast-ruby-meetup-september-2025\"\n  description: |-\n    A joint meetup between BelfastRuby and PyBelfast, featuring speakers from Ruby and Python communities.\n\n    Where: TeamFeePay, Catalyst, The Innovation Center, Queens Rd, Belfast BT3 9DT, UK\n\n    When: Wednesday, September 10, 2025, 6:00 PM to 9:00 PM BST\n\n    What:\n    We have speakers from both Ruby and Python communities:\n    * Stephen Houston (CTO, TeamFeePay) - Ruby talk\n    * Nick Schwaderer - Ruby Lightning Talk\n    * Python speaker TBD\n\n    Refreshments will be provided.\n\n    https://lu.ma/ppyuhvwz\n    https://www.meetup.com/belfastruby/events/310407715\n  talks:\n    - title: \"Talk by Stephen Houston\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Belfast Ruby Meetup September 2025\"\n      date: \"2025-09-10\"\n      speakers:\n        - Stephen Houston\n      id: \"stephen-houston-belfast-ruby-meetup-september-2025\"\n      video_id: \"stephen-houston-belfast-ruby-meetup-september-2025\"\n      video_provider: \"scheduled\"\n\n    - title: \"Lightning Talk\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Belfast Ruby Meetup September 2025\"\n      date: \"2025-09-10\"\n      speakers:\n        - Nick Schwaderer\n      id: \"nick-schwaderer-belfast-ruby-meetup-september-2025-lightning\"\n      video_id: \"nick-schwaderer-belfast-ruby-meetup-september-2025-lightning\"\n      video_provider: \"scheduled\"\n\n    - title: \"Python Talk\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Belfast Ruby Meetup September 2025\"\n      date: \"2025-09-10\"\n      speakers:\n        - TODO\n      id: \"python-speaker-belfast-ruby-meetup-september-2025\"\n      video_id: \"python-speaker-belfast-ruby-meetup-september-2025\"\n      video_provider: \"scheduled\"\n"
  },
  {
    "path": "data/belfastruby/series.yml",
    "content": "---\nname: \"Belfast Ruby\"\nwebsite: \"https://lu.ma/BelfastRuby\"\ntwitter: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"GB\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/big-ruby/big-ruby-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaHEdrGvr475Vwc2YCDHir8\"\ntitle: \"Big Ruby 2013\"\nkind: \"conference\"\ndescription: |-\n  February 28th and March 1st, 2013\npublished_at: \"2013-02-28\"\nstart_date: \"2013-02-28\"\nend_date: \"2013-03-01\"\nlocation: \"Dallas, TX, United States\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2013\nwebsite: \"https://web.archive.org/web/20130310025302/http://www.bigrubyconf.com/\"\nbanner_background: \"#FFF6EC\"\nfeatured_background: \"#FFF6EC\"\nfeatured_color: \"#913F3E\"\ncoordinates:\n  latitude: 32.7766642\n  longitude: -96.79698789999999\n"
  },
  {
    "path": "data/big-ruby/big-ruby-2013/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n\n# Website: https://web.archive.org/web/20130310025302/http://www.bigrubyconf.com\n# Schedule: https://web.archive.org/web/20130310025302/http://www.bigrubyconf.com/#schedule\n\n- id: \"ernie-miller-big-ruby-2013\"\n  title: \"The Most Important Optimization: Happiness\"\n  raw_title: \"Big Ruby 2013 The Most Important Optimization: Happiness\"\n  speakers:\n    - Ernie Miller\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    Metaprogramming. It's awesome, right? Powerful? Maybe a little scary?\n\n    Let's kick things up a notch. If writing code that writes code is powerful, what's hacking the life of the programmer writing the code? That's got to be an 11 on the meta-meter. At least. We'll talk about some of the bad assumptions we've made, lies we've bought into, and why we have the most awesome job ever.\n\n  video_provider: \"youtube\"\n  video_id: \"Cq_RkrthKZo\"\n  published_at: \"2013-04-23\"\n\n- id: \"john-downey-big-ruby-2013\"\n  title: \"DevOps for the Rubyist Soul\"\n  raw_title: \"Big Ruby 2013 DevOps for the Rubyist Soul  by John Downey\"\n  speakers:\n    - John Downey\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    Ruby developers have many great options for simply hosting their web applications. But what happens when your product outgrows Heroku? Managing your own servers can be an intimidating task for the average developer. This session will cover the lessons we've learned at Braintree from building and maintaining our infrastructure. It will cover how we leverage Ruby to automate and control all of our environments. Some specific topics we'll cover:\n\n    Orchestrating servers with capistrano\n    Using puppet for configuration management\n    Our cap and puppet workflow using git\n    How vagrant can provide a sane test environment\n    Some pitfalls you should avoid\n\n  video_provider: \"youtube\"\n  video_id: \"e4lfvNQYIW4\"\n  published_at: \"2013-04-19\"\n\n- id: \"matt-kirk-big-ruby-2013\"\n  title: \"How to Overcome the Apathy of Big Data\"\n  raw_title: \"Big Ruby 2013 How to Overcome the Apathy of Big Data by Matt Kirk\"\n  speakers:\n    - Matt Kirk\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    We all know data is growing at a rapid pace and our ability to store it has become cheap. But what do we do with all this data? Do you feel overwhelmed with the infinite amounts of decisions you could make?\n\n    Big data was supposed to improve how businesses run, though in most cases it has complicated process. We have become apathetic to the amounts of data that are bombarding us.\n\n    This talk aims to help overcome this apathy towards the sheer amount of information out there. It will teach you how to come up with methods to finding metrics, and new dashboards specifically for your business.\n\n    We will talk about:\n\n       Backward induction, or goal based metrics.\n       Classification algorithms for making sense of data.\n       Graphing in higher dimensions.\n\n    By the end of this session, you will know how to be effective with data. You will understand how to find what you are looking for, how to classify it, and how to visually make sense of it all.\n\n  video_provider: \"youtube\"\n  video_id: \"8qhtngnhD70\"\n  published_at: \"2013-04-11\"\n\n- id: \"brian-morton-big-ruby-2013\"\n  title: \"Services and Rails: The Shit They Don't Tell You\"\n  raw_title: \"Big Ruby 2013 Services and Rails: The Shit They Don't Tell You by Brian Morton\"\n  speakers:\n    - Brian Morton\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    Building services and integrating them into Rails is hard. We want smaller Rails apps and nicely encapsulated services, but services introduce complexity. If you go overboard in the beginning, you're doing extra work and getting some of it wrong. If you wait too long, you've got a mess.\n\n    At Yammer, we constantly clean up the mess that worked well in the early days, but has become troublesome to maintain and scale. We pull things out of the core Rails app, stand them up on their own, and make sure they work well and are fast. With 20+ services, we've learned some lessons along the way. Services that seem clean in the beginning can turn into development environment nightmares. Temporary double-dispatching solutions turn into developer confusion. Monitoring one app turns into monitoring a suite of apps and handling failure between them.\n\n    This talk looks at our mistakes and solutions, the tradeoffs, and how we're able to keep moving quickly. Having services and a smaller Rails codebase makes for scalable development teams, happier engineers, and predictable production environments. Getting there is full of hard decisions -- sometimes we're right, sometimes we fuck it up, but we usually have a story to tell.\n\n  video_provider: \"youtube\"\n  video_id: \"GuJ49PNBsn8\"\n  published_at: \"2013-04-11\"\n\n- id: \"adam-keys-big-ruby-2013\"\n  title: \"Move Fast and Make Things\"\n  raw_title: \"Big Ruby 2013 Move fast and make things by Adam Keys\"\n  speakers:\n    - Adam Keys\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    Big team, small team. Huge company, tiny side business. No matter which, time is what you're short on. You're already using tools like Ruby and Rails to make more with the time you have. But what about non-web apps? What databases, development tools, and other libraries let you do more or do bigger things in'less time?\n\n    Finding high-leverage tools is a handy skill. Once you've found a tool that is simple to use, performant, and reliable, you can use it all over the place. We'll look at four tools: Faraday, Celluloid, Metriks, and Pow. These will help us talk HTTP, write concurrent programs, instrument our apps, and set up apps quickly. We'll see how to use them for multiple applications, play to their strengths, and work around their weaknesses.\n\n  video_provider: \"youtube\"\n  video_id: \"iXJXne0BzN4\"\n  published_at: \"2013-04-11\"\n\n- id: \"joshua-timberman-big-ruby-2013\"\n  title: \"5 Things You Didn't Know About Chef\"\n  raw_title: \"Big Ruby 2013 5 Things You Didn't Know About Chef by Joshua Timberman\"\n  speakers:\n    - Joshua Timberman\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    This talk is an exploration into five lesser-known things that Chef can be used for, or is capable of doing. Some of these features and capabilities are unknown by all but the most experienced Chef users. Some of them are anti-patterns but still really useful. And others give you additional flexibility for using Chef in your environment.\n\n    In-place File Editing for Greater Good Use Chef's Built-in Version Matching REPLs are fun, so Chef has one! Take the Resource Collection for a Stroll The Anatomy of Loading and Executing a Single Recipe\n\n  video_provider: \"youtube\"\n  video_id: \"FqHucWd634c\"\n  published_at: \"2013-04-11\"\n\n- id: \"john-duff-big-ruby-2013\"\n  title: \"How Shopify Scales Rails\"\n  raw_title: \"Big Ruby 2013 How Shopify Scales Rails by John Duff\"\n  speakers:\n    - John Duff\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    Tobi Lutke wrote the first line of code for Shopify nearly 10 years ago to power his own Snowboard shop. Two years later Shopify launched to the public on a single webserver using Rails 0.13.1. Today Shopify powers over 40k online stores and processes up to half a million product sales per day across the platform. Over 30 people actively work on Shopify which makes it the longest developed and likely largest Rails code base out there.\n\n    This is the story of how Shopify has evolved to handle its immense growth over the years. This is what getting big is all about: evolving to meet the needs of your customers. You don't start out with a system and infrastructure that can handle a billion dollar in GMV. You evolve to it. You evolve by adding caching layers, hardware, queuing systems and splitting your application to services.\n\n    This is the story of how we have tackled the various scaling pain points that Shopify has hit and what we have done to surpass them, what we are doing to go even further.\n\n  video_provider: \"youtube\"\n  video_id: \"j347oSSuNHA\"\n  published_at: \"2013-04-11\"\n\n- id: \"joe-kutner-big-ruby-2013\"\n  title: \"Build a Bigger Brain: How Healthy Living Makes You Smarter\"\n  raw_title: \"Big Ruby 2013 Build a Bigger Brain: How Healthy Living Makes You Smarter by Joe Kutner\"\n  speakers:\n    - Joe Kutner\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    To keep doing what you love, you need to maintain your own systems, not just the ones you write code for. Regular exercise and proper nutrition help you learn, remember, concentrate, and be creative—skills critical to doing your job well. Learn how to change your work habits, master exercises that make working at a computer more comfortable, and develop a plan to keep fit, healthy, and sharp for years to come.\n\n  video_provider: \"youtube\"\n  video_id: \"Z0WcQ749OIM\"\n  published_at: \"2013-04-12\"\n\n- id: \"jeremy-hinegardner-big-ruby-2013\"\n  title: \"Treading Water in a Stream of Data\"\n  raw_title: \"Big Ruby 2013 Treading Water in a Stream of Data by Jeremy Hinegardner\"\n  speakers:\n    - Jeremy Hinegardner\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    Data arrives in all sorts of forms, more and more today we are seeing data arrive in event-like systems: server logs, twitter, superfeedr notifications, github events, rubygems web hooks, couchdb change notifications, etc. We want to analyze streams of data, and find useful pieces of information in them.\n\n    In this talk, using an existing dataset, we will go through the process of obtaining, manipulating, processing, analyzing and storing a stream of data. We will attempt to touch upon a variety of possible topics including: differences between processing static datasets and stream datasets, pitfalls of stream processing, analyzing data in real time and using the datastream itself as data source.\n\n  video_provider: \"youtube\"\n  video_id: \"As1bB-vbD0s\"\n  published_at: \"2013-04-13\"\n\n- id: \"josh-schairbaum-big-ruby-2013\"\n  title: \"Fire It Up: How Empowered People Automated Provisioning In 6 Datacenters Across 4 Continents\"\n  raw_title: \"Big Ruby 2013 Fire It Up: How Empowered People Automated Provisioning In 6 Datacenters Across 4...\"\n  speakers:\n    - Josh Schairbaum\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"GbVaepN5F5w\"\n  published_at: \"2013-04-12\"\n\n- id: \"geoffrey-dagley-big-ruby-2013\"\n  title: \"Scaling with Friends\"\n  raw_title: \"Big Ruby 2013 SCALING WITH FRIENDS by Geoffrey Dagley\"\n  speakers:\n    - Geoffrey Dagley\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    What started with two brothers in the McKinney Public Library is now a world wide word phenomenon on multiple mobile platforms. We'll look at how we have grown, the mistakes we made, and the changes we have made along the way:\n\n    Serving millions of players a day: Stats, stats, stats!\n    Working with constraints: * 1 service, 6 games (and counting) * Native clients means backward compatibility, ftw!\n    How do I know what to fix? Instrumenting and reporting on everything\n    Where is the data? Using the database, memcache, Redis to the fullest\n    What we did wrong? What we did right? What would we do differently?\n\n  video_provider: \"youtube\"\n  video_id: \"DQQmhqZgXDk\"\n  published_at: \"2013-04-13\"\n\n- id: \"lightning-talks-big-ruby-2013\"\n  title: \"Lightning Talks\"\n  raw_title: \"Big Ruby 2013 Lightning Talks\"\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6T3Oa_5mO-g\"\n  published_at: \"2013-04-13\"\n  talks:\n    - title: \"Lightning Talk: Living Social\"\n      start_cue: \"00:00\"\n      end_cue: \"05:10\"\n      video_provider: \"parent\"\n      id: \"chris-morris-lighting-talk-big-ruby-2013\"\n      video_id: \"chris-morris-lighting-talk-big-ruby-2013\"\n      speakers:\n        - Chris Morris\n\n    - title: \"Lightning Talk: rock-oauth2\"\n      start_cue: \"05:10\"\n      end_cue: \"10:47\"\n      video_provider: \"parent\"\n      id: \"tom-brown-lighting-talk-big-ruby-2013\"\n      video_id: \"tom-brown-lighting-talk-big-ruby-2013\"\n      speakers:\n        - Tom Brown\n\n    - title: \"Lightning Talk: Jack - A New Programming Language\"\n      start_cue: \"10:47\"\n      end_cue: \"16:30\"\n      video_provider: \"parent\"\n      id: \"tim-caswell-lighting-talk-big-ruby-2013\"\n      video_id: \"tim-caswell-lighting-talk-big-ruby-2013\"\n      speakers:\n        - Tim Caswell\n\n    - title: \"Lightning Talk: JRuby\"\n      start_cue: \"16:30\"\n      end_cue: \"22:25\"\n      video_provider: \"parent\"\n      id: \"keith-bennett-lighting-talk-big-ruby-2013\"\n      video_id: \"keith-bennett-lighting-talk-big-ruby-2013\"\n      speakers:\n        - Keith Bennett\n\n    - title: \"Lightning Talk: kinectable_pipe\"\n      start_cue: \"22:25\"\n      end_cue: \"28:50\"\n      video_provider: \"parent\"\n      id: \"marshall-yount-lighting-talk-big-ruby-2013\"\n      video_id: \"marshall-yount-lighting-talk-big-ruby-2013\"\n      speakers:\n        - Marshall Yount\n\n    - title: \"Lightning Talk: Technical INTIMIDATION\"\n      start_cue: \"28:50\"\n      end_cue: \"34:29\"\n      video_provider: \"parent\"\n      id: \"chris-morris-lighting-talk-big-ruby-2013-lightning-talk-technical-intim\"\n      video_id: \"chris-morris-lighting-talk-big-ruby-2013\"\n      speakers:\n        - Chris Morris\n\n- id: \"wynn-netherland-big-ruby-2013\"\n  title: \"Hypermedia - Less Hype, More Media Please\"\n  raw_title: \"Big Ruby 2013 Hypermedia - less hype, more media please by Wynn Netherland\"\n  speakers:\n    - Wynn Netherland\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: |-\n    Like REST itself, Hypermedia is one of those topics everyone is talking about but few understand. Many discussions on the topic devolve into chaos until someone screams out \"Fielding, dang it!\" in exasperation. Even more civilized debates have a healthy dose of \"READ THE F-ING SPEC!\"\n\n    API consumers don't care about your API, your architecture, or your specs. They just want your data. This talk aims to provide a real world perspective of Hypermedia and show why it matters as we walk through the evolution of the GitHub API and the design decisions behind those changes. We'll dive into HATEOAS, media types, HAL, Collection+JSON, link templates, and the growing landscape of Ruby libraries for making all that easier to implement.\n\n    We'll also look at the impact of Hypermedia on API clients and when it might not be the best design pattern.\n\n  video_provider: \"youtube\"\n  video_id: \"yVuMqV_Ul5s\"\n  published_at: \"2013-04-13\"\n\n- id: \"jim-weirich-big-ruby-2013\"\n  title: \"Keynote: Ruby, Codes, Threads, Events... and???\"\n  raw_title: \"Big Ruby Conf 2013 Keynote by Jim Weirich\"\n  speakers:\n    - Jim Weirich\n  event_name: \"Big Ruby 2013\"\n  date: \"2013-02-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"vIHdhaF2R2w\"\n  published_at: \"2013-04-04\"\n"
  },
  {
    "path": "data/big-ruby/big-ruby-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybDQsdHP1e7msGEalUPaV06\"\ntitle: \"Big Ruby 2014\"\nkind: \"conference\"\ndescription: |-\n  February 20th and 21st, 2014\npublished_at: \"2014-02-20\"\nstart_date: \"2014-02-20\"\nend_date: \"2014-02-21\"\nlocation: \"Dallas, TX, United States\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2014\nwebsite: \"https://web.archive.org/web/20140422001806/http://www.bigrubyconf.com/\"\nbanner_background: \"#FFF6EC\"\nfeatured_background: \"#FFF6EC\"\nfeatured_color: \"#913F3E\"\ncoordinates:\n  latitude: 32.7766642\n  longitude: -96.79698789999999\n"
  },
  {
    "path": "data/big-ruby/big-ruby-2014/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n\n# Website: https://web.archive.org/web/20140422001806/http://www.bigrubyconf.com\n# Schedule: https://web.archive.org/web/20140422001806/http://www.bigrubyconf.com/#schedule\n\n- id: \"keavy-mcminn-big-ruby-2014\"\n  title: \"Keynote\"\n  raw_title: \"Big Ruby 2014 - Keynote by Keavy McMinn\"\n  speakers:\n    - Keavy McMinn\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"9PLY4TWo7f0\"\n  published_at: \"2014-03-15\"\n\n- id: \"richard-schneeman-big-ruby-2014\"\n  title: \"Testing The Untestable\"\n  raw_title: \"Big Ruby 2014 - TESTING THE UNTESTABLE by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    Good tests are isolatable, repeatable and deterministic. Good tests don't touch the network and are flexible when it comes to change. Bad tests are all of the above. Bad tests are no tests at all - which is where I found myself with a 5 year legacy codebase running in production and touching millions of customers with minimal use-case documentation. We'll cover this experience and several like it while digging into how to go from zero to total test coverage as painlessly as possible. You will learn how to stay sane in the face of insane testing conditions and how to use these tests to deconstruct a monolith app. When life gives you a big ball of mud, write a big ball of tests.\n\n  video_provider: \"youtube\"\n  video_id: \"QHMKIHkY1nM\"\n  published_at: \"2014-03-13\"\n\n- id: \"coraline-ada-ehmke-big-ruby-2014\"\n  title: \"Lightweight Business Intelligence with Ruby, Rails, and MongoDB\"\n  raw_title: \"Big Ruby 2014 - Lightweight Business Intelligence with Ruby, Rails, and MongoDB\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    By Coraline Ada Ehmke\n\n    Agile companies need timely and reliable access to data to make critical business decisions. In the enterprise world, this is accomplished with expensive and esoteric data warehousing solutions, while younger organizations make do with generic analytics platforms. In this talk I will introduce an agile approach to business intelligence that drives decision support, feeds data analysis, and delivers flexible reporting capabilities.\n\n    We will explore the complete architecture of a lightweight BI system that is used in the real world to capture and analyze customer information, monitor user behaviour, feed machine-learning algorithms for decision support, and deliver real knowledge and value to business stakeholders.\n\n  video_provider: \"youtube\"\n  video_id: \"Pf_nXuHhods\"\n  published_at: \"2014-03-16\"\n\n- id: \"tanner-burson-big-ruby-2014\"\n  title: \"Mo' Jobs Mo' Problems - Lessons Learned Scaling To Millions of Jobs an Hour\"\n  raw_title: \"Big Ruby 2014 - MO' JOBS MO' PROBLEMS - LESSONS LEARNED SCALING TO MILLIONS OF JOBS AN HOUR\"\n  speakers:\n    - Tanner Burson\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  slides_url: \"https://speakerdeck.com/tannerburson/mo-jobs-mo-problems-at-big-ruby-conf-2014\"\n  description: |-\n    By Tanner Burson\n\n    At Tapjoy we process over a million jobs an hour with Ruby. This talk is a discussion of tools, techniques, and interesting problems from the trenches of scaling up over the last two years. Expect to learn a lot about Ruby job queues (beyond Resque/Sidekiq), performance, concurrency and more.\n\n  video_provider: \"youtube\"\n  video_id: \"fXyDTkDtQfs\"\n  published_at: \"2014-03-13\"\n\n- id: \"vito-genovese-big-ruby-2014\"\n  title: \"Building DEF CON CTF with Ruby\"\n  raw_title: \"Big Ruby 2014 - BUILDING DEF CON CTF WITH RUBY by Vito Genovese\"\n  speakers:\n    - Vito Genovese\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  slides_url: \"https://speakerdeck.com/vito/building-def-con-ctf-with-ruby\"\n  description: |-\n    DEF CON Capture the Flag is the world series of computer hacking, with hundreds of teams from all over the world trying to qualify, and a select few competing on site in Las Vegas. For our first time hosting this event, we picked a Ruby-based stack running the game, which has teams attempting to defend their network services while hacking opponents' and stealing secrets.\n\n  video_provider: \"youtube\"\n  video_id: \"C0pZLgI5ReQ\"\n  published_at: \"2014-03-13\"\n\n- id: \"camilo-lopez-big-ruby-2014\"\n  title: \"How Shopify Sharded Rails\"\n  raw_title: \"Big Ruby 2014 - HOW SHOPIFY SHARDED RAILS by Camilo Lopez\"\n  speakers:\n    - Camilo Lopez\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    Last year at this very conference John Duff spoke about how Shopify\n    scales while maintaing one of the longest lived and largest Rails deployments,\n    and how we affront the challenges that come with growth. Shopify in 2013 became\n    more than twice the size in every single aspect; requests per minute, GMV, merchants,\n    number of developers, etc. \\n\\nAfter CyberMonday 2012 it became clear that if\n    we wanted to survive CyberMonday 2013 we needed to spread the load across more\n    than a single huge database, and move to a model of smaller databases to enable\n    horizontal scalability. This is the story of how, in 2013, we more than doubled\n    the number number of databases that power Shopify, and all the challenges that\n    come along when sharding a living, breathing and money producing Ruby application.\n  video_provider: \"youtube\"\n  video_id: \"6njTQdFLz6I\"\n  published_at: \"2014-03-13\"\n\n- id: \"chris-morris-big-ruby-2014\"\n  title: \"A 4-pack of Big Lightning Talks\"\n  raw_title: \"Big Ruby 2014 - A 4-PACK OF BIG LIGHTNING TALKS by Chris Morris\"\n  speakers:\n    - Chris Morris\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  slides_url: \"https://www.slideshare.net/slideshow/big-ruby-2014-a-4-pack-of-lightning-talks\"\n  description: |-\n    If you get 10 minutes into this talk and decide you don't really like the topic, the topic will change! If you don't like the speaker, well ... there's no accounting for taste.\n\n    The Cobbler's Production Console Has No Shoes. Don't give all your great stuff to your end-users, build something nice for yourself as well. We'll look at a few of the things I've built for myself at LivingSocial\n    and hopefully will inspire you to do the same. \\n\\nDo-It-Yourself Mocks and Fixtures.\n    Big projects need some custom love. factory_girl, ActiveRecord fixtures and mocha\n    demo nice, but sometimes they wear out their welcome in a big code base. How hard\n    could it be to do yourself? Let's find out! It might be easier than you think.\n    \\n\\nTrack yer Big Stuff without screwing up production with Humperdink. With over\n    2500 translation keys in one app, we decided to build out some tooling to track\n    at runtime what was and wasn't being used so we could prune out the dead stuff.\n    \\n\\nALL THE ANALOGIES We've all tried to wield the construction analogy to help\n    figure out what the heck it is we do. Let's get creative and think of 10 other\n    ways that don't quite capture it either.\\n\\n\\n\\n\n  video_provider: \"youtube\"\n  video_id: \"A1kjyQnQhUI\"\n  published_at: \"2014-03-13\"\n\n- id: \"ashe-dryden-big-ruby-2014\"\n  title: \"Open Source Isn't For Everyone, But It Could Be\"\n  raw_title: \"Big Ruby 2014 - OPEN SOURCE ISN'T FOR EVERYONE, BUT IT COULD BE\"\n  speakers:\n    - Ashe Dryden\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    By Ashe Dryden\n\n    The state of diversity in open source contributions is abysmal. With the number of female OSS contributors at a shockingly low 1.5% and other groups not even documented, we need to ask what we can be doing better as a community. We'll discuss the barriers that people face contributing to our open source projects and what we can do to increase participation.\n\n  video_provider: \"youtube\"\n  video_id: \"KiFTzsOdmcg\"\n  published_at: \"2014-03-13\"\n\n- id: \"ben-bleything-big-ruby-2014\"\n  title: \"Castle On a Cloud: The GitHub Story\"\n  raw_title: \"Big Ruby 2014 - CASTLE ON A CLOUD: THE GITHUB STORY by Ben Bleything\"\n  speakers:\n    - Ben Bleything\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    When you think \"GitHub\", you're probably thinking of what we lovingly refer to as GitHub Dot Com: The Web Site. GitHub Dot Com: The Web Site runs on an incredibly interesting infrastructure composed of very powerful, cleverly configured, and deeply handsome servers. This is not their story.\n\n    This is the story of the other 90% of our infrastructure. This is the story of the 350 AWS instances, 250 Heroku dynos, and dozens of Rackspace Cloud, Softlayer, and ESX VMs we run. This is a story of tooling and monitoring, of happiness and heartbreak, and, ultimately, of The Cloud.\n\n  video_provider: \"youtube\"\n  video_id: \"8TYfPhFSZFs\"\n  published_at: \"2014-03-13\"\n\n- id: \"glenn-vanderburg-big-ruby-2014\"\n  title: \"Keynote: Working Effectively on a Distrubuted Team\"\n  raw_title: \"Big Ruby 2014 - Keynote by Glenn Vanderburg\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"k448wiiBf80\"\n  published_at: \"2014-03-14\"\n\n- id: \"wynn-netherland-big-ruby-2014\"\n  title: \"Refactoring With Science\"\n  raw_title: \"Big Ruby 2014 - REFACTORING WITH SCIENCE by Wynn Netherland\"\n  speakers:\n    - Wynn Netherland\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    Changing code is easy. Changing code with confidence isn't. Even the most robust, mature test suites have blind spots that make large scale changes difficult. At GitHub we use Science to instrument, compare results, and measure performance of parallel code path experiments to see how new code runs against a current production baseline. This talk will show you how to Science, too.\n\n  video_provider: \"youtube\"\n  video_id: \"eMKG4puLfmM\"\n  published_at: \"2014-03-13\"\n\n- id: \"mando-escamilla-big-ruby-2014\"\n  title: \"It Looks Like You're Writing a Service: Would You Like\"\n  raw_title: \"Big Ruby 2014 - IT LOOKS LIKE YOU'RE WRITING A SERVICE: WOULD YOU LIKE HELP?\"\n  speakers:\n    - Mando Escamilla\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    By Mando Escamilla\n\n    Once you've properly structured your Rails app, you'll begin to find logical seams in your domain logic. These seams can be the perfect opportunity to extract a software component into a stand-alone service.\n\n    Using a live-in-production example, we'll walk through how we build and integrate services at Union Metrics. We'll go over some tips and patterns we've discovered as well as about some of the pitfalls and things to avoid when building and deploying stand-alone services.\n\n  video_provider: \"youtube\"\n  video_id: \"MUl4loZC58Y\"\n  published_at: \"2014-03-13\"\n\n- id: \"bj-allen-big-ruby-2014\"\n  title: \"In Praise of Smallness\"\n  raw_title: \"Big Ruby 2014 - In Praise of Smallness by B.J. Allen\"\n  speakers:\n    - B.J. Allen\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  slides_url: \"https://speakerdeck.com/bjallen/in-praise-of-smallness\"\n  description: |-\n    Getting big things done is important. We praise big accomplishments, but those involved can usually point to the small decisions and actions along the way that made it all possible. Structuring teams, projects, systems, and processes to embrace smallness enables the big things to evolve and succeed. This talk will cover ways in which the teams behind TripCase have succeeded and failed while making big things happen one small step at a time.\n\n  video_provider: \"youtube\"\n  video_id: \"Y2EWl2R9c0o\"\n  published_at: \"2014-03-14\"\n\n- id: \"kerri-miller-big-ruby-2014\"\n  title: \"Harry Potter and the Legacy Codebase\"\n  raw_title: \"Big Ruby 2014 - Harry Potter and the Legacy Codebase\"\n  speakers:\n    - Kerri Miller\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    It's your first day at Hogwarts.com, and everything is wonderful and\n    thrilling. You dig in to classes, and soon find a dusty book with a cryptic warning:\n\n    \"Do NOT on any circumstances make ANY change to this magic incantation without\n    talking to Doug first!!!\"\n\n    Sound familiar? Approaching a legacy code base\n    can feel like unraveling a mystery, not just about the code, but about the personalities\n    who wrote it. What tools and techniques can help you solve the maze of twisty\n    code? Let's explore how to get a handle on legacy code, how to negotiate joining\n    an existing team of developers, and how we can get a summa cum laude at graduation.\n  video_provider: \"youtube\"\n  video_id: \"QJhQ6oGHwS0\"\n  published_at: \"2014-03-14\"\n\n- id: \"lightning-talks-big-ruby-2014\"\n  title: \"Lightning Talks\"\n  raw_title: \"Big Ruby 2014 - Lightning Talks\"\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Gn75H9D3nOg\"\n  published_at: \"2014-03-14\"\n  talks:\n    - title: \"Lightning Talk: User Groups are Awesome\"\n      start_cue: \"00:00\"\n      end_cue: \"03:22\"\n      id: \"christopher-krailo-lighting-talk-big-ruby-2014\"\n      video_id: \"christopher-krailo-lighting-talk-big-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Christopher Krailo\n\n    - title: \"Lightning Talk: Interactions\"\n      start_cue: \"03:22\"\n      end_cue: \"08:58\"\n      id: \"aaron-lasseigne-lighting-talk-big-ruby-2014\"\n      video_id: \"aaron-lasseigne-lighting-talk-big-ruby-2014\"\n      video_provider: \"parent\"\n      slides_url: \"https://speakerdeck.com/aaronlasseigne/interactions\"\n      speakers:\n        - Aaron Lasseigne\n\n    - title: \"Lightning Talk: Lone Star Ruby Foundation\"\n      start_cue: \"08:58\"\n      end_cue: \"12:59\"\n      id: \"mando-escamila-lighting-talk-big-ruby-2014\"\n      video_id: \"mando-escamila-lighting-talk-big-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Mando Escamila\n\n    - title: \"Lightning Talk: From Intern to FTE\"\n      start_cue: \"12:59\"\n      end_cue: \"21:13\"\n      id: \"jeremy-perez-lighting-talk-big-ruby-2014\"\n      video_id: \"jeremy-perez-lighting-talk-big-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeremy Perez\n\n    - title: \"Lightning Talk: 3 Functional Programming 'words' that exist in Ruby\"\n      start_cue: \"21:13\"\n      end_cue: \"27:58\"\n      id: \"jeffery-davis-lighting-talk-big-ruby-2014\"\n      video_id: \"jeffery-davis-lighting-talk-big-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeffery Davis\n\n- id: \"hector-castro-big-ruby-2014\"\n  title: \"Throw Some Keys on it: Data Modeling For Key/Value Data Stores by Example\"\n  raw_title: \"Big Ruby 2014 - Throw Some Keys on it: Data Modeling For Key/Value Data Stores by Example\"\n  speakers:\n    - Hector Castro\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    By Hector Castro\n\n    Most Computer Science curriculums offer at least one course that focuses on databases. Most of the time, these courses promote relational database management systems (RDBMS) by emphasizing the relational model, relational algebra, data normalization, and Structured Query Language (SQL).\n\n    Key/value data stores are increasing in popularity but our mental model for storing data is still primarily relational.\n\n    In this talk, we'll explore data modeling for key/value stores using the Uber mobile application as an example.\n\n  video_provider: \"youtube\"\n  video_id: \"-_3Us7Ystyg\"\n  published_at: \"2014-03-14\"\n\n- id: \"clint-shryock-big-ruby-2014\"\n  title: \"Herding Elephants\"\n  raw_title: \"Big Ruby 2014 - Herding Elephants:  by Clint Shryock\"\n  speakers:\n    - Clint Shryock\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    Herding Elephants: How Heroku Uses Ruby to Run the Largest Fleet of Postgres Databases in the World\n\n    Heroku operates the largest fleet of Postgres databases in the world. Service oriented architecture, infrastructure as code, and fault tolerance make it possible. Come hear how the Heroku Postgres team uses a handful of Ruby applications to operate and scale the largest herd of your favorite elephant themed RDBMS.\n\n  video_provider: \"youtube\"\n  video_id: \"GGyT6Cxpb6U\"\n  published_at: \"2014-03-14\"\n\n- id: \"adam-keys-big-ruby-2014\"\n  title: \"Developers are From Mars, Developers are From Venus\"\n  raw_title: \"Big Ruby 2014 - Developers are From Mars, Developers are From Venus\"\n  speakers:\n    - Adam Keys\n  event_name: \"Big Ruby 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    By Adam Keys\n\n    Working well with other developers: it's difficult and it's crucial. Many projects that fail do so due to social problems, not technical problems. The ability to communicate and work with lots of different kinds of developers and stakeholders can be a superpower almost as awesome as writing software.\n\n    Sadly, there's no manual for developers to read about effective collaboration. But we can still try to better understand different kinds of developers and how to work with them. We can pick up some ideas for how to survive working in a team, or how to lead a team. We can learn how to get from our imperfect teams now to a better team in the future.\n\n    Collaboration is hard, but we can learn it and make it our superhero power.\n\n  video_provider: \"youtube\"\n  video_id: \"V5mPordkbD8\"\n  published_at: \"2014-03-14\"\n"
  },
  {
    "path": "data/big-ruby/series.yml",
    "content": "---\nname: \"Big Ruby Conf\"\nwebsite: \"http://web.archive.org/web/20140228185424/http://www.bigrubyconf.com:80/\"\noriginal_website: \"http://bigrubyconf.com\"\ntwitter: \"BigRubyConf\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Big Ruby\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/birmingham-on-rails/birmingham-on-rails-2020/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYC2lZzwTvEeJXghm4Ym4ZX\"\ntitle: \"Birmingham on Rails 2020\"\nkind: \"conference\"\nlocation: \"Birmingham, AL, United States\"\ndescription: |-\n  Birmingham on Rails 2020!\npublished_at: \"2020-02-19\"\nstart_date: \"2020-01-31\"\nend_date: \"2020-01-31\"\nyear: 2020\nbanner_background: \"#F7FAFC\"\nfeatured_background: \"#F7FAFC\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 33.5149464\n  longitude: -86.80827010000002\n"
  },
  {
    "path": "data/birmingham-on-rails/birmingham-on-rails-2020/venue.yml",
    "content": "# https://www.birminghamonrails.com/#location\n---\nname: \"McWane Science Center\"\n\naddress:\n  street: \"200 19th Street North\"\n  city: \"Birmingham\"\n  region: \"Alabama\"\n  postal_code: \"35203\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"200 19th St N, Birmingham, AL 35203, USA\"\n\ncoordinates:\n  latitude: 33.5149464\n  longitude: -86.80827010000002\n\nmaps:\n  google: \"https://maps.google.com/?q=McWane+Science+Center,33.5149464,-86.80827010000002\"\n  apple: \"https://maps.apple.com/?q=McWane+Science+Center&ll=33.5149464,-86.80827010000002\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=33.5149464&mlon=-86.80827010000002\"\n"
  },
  {
    "path": "data/birmingham-on-rails/birmingham-on-rails-2020/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"stephan-hagemann-birmingham-on-rails-2020\"\n  title: \"Opening Keynote: Structural Engineering in Ruby\"\n  raw_title: \"Birmingham on Rails 2020 - Morning Keynote by Stephan Hagemann\"\n  speakers:\n    - Stephan Hagemann\n  event_name: \"Birmingham on Rails 2020\"\n  date: \"2020-01-31\"\n  published_at: \"2020-02-19\"\n  description: |-\n    Birmingham on Rails 2020 - Morning Keynote by Stephan Hagemann\n  video_provider: \"youtube\"\n  video_id: \"EypRSLfKvak\"\n\n- id: \"ratnadeep-deshmane-birmingham-on-rails-2020\"\n  title: \"The Story of Rails!\"\n  raw_title: \"Birmingham on Rails 2020 -  The Story of Rails! by Ratnadeep Deshmane\"\n  speakers:\n    - Ratnadeep Deshmane\n  event_name: \"Birmingham on Rails 2020\"\n  date: \"2020-01-31\"\n  published_at: \"2020-02-19\"\n  description: |-\n    Birmingham on Rails 2020 -  The Story of Rails! by Ratnadeep Deshmane\n  video_provider: \"youtube\"\n  video_id: \"junKFYegzp4\"\n\n- id: \"yulia-oletskaya-birmingham-on-rails-2020\"\n  title: \"A Quick Guide to RPC Frameworks\"\n  raw_title: \"Birmingham on Rails 2020 - A Quick Guide to RPC Frameworks by Yulia Oletskaya\"\n  speakers:\n    - Yulia Oletskaya\n  event_name: \"Birmingham on Rails 2020\"\n  date: \"2020-01-31\"\n  published_at: \"2020-02-19\"\n  description: |-\n    Birmingham on Rails 2020 - A Quick Guide to RPC Frameworks by Yulia Oletskaya\n  video_provider: \"youtube\"\n  video_id: \"F8yHgTGayrw\"\n\n- id: \"claudio-baccigalupo-birmingham-on-rails-2020\"\n  title: \"Validating and Processing the Content of a File with Active Storage\"\n  raw_title: \"Birmingham on Rails 2020 - Validating and Processing the Content of... by Claudio B.\"\n  speakers:\n    - Claudio Baccigalupo\n  event_name: \"Birmingham on Rails 2020\"\n  date: \"2020-01-31\"\n  published_at: \"2020-02-19\"\n  description: |-\n    Birmingham on Rails 2020 - Validating and Processing the Content of a File with Active Storage by Claudio B.\n  video_provider: \"youtube\"\n  video_id: \"e-KcnR4PnT0\"\n\n- id: \"craig-kerstiens-birmingham-on-rails-2020\"\n  title: \"Postgres at any Scale\"\n  raw_title: \"Birmingham on Rails 2020 - Postgres at any Scale by Craig Kerstiens\"\n  speakers:\n    - Craig Kerstiens\n  event_name: \"Birmingham on Rails 2020\"\n  date: \"2020-01-31\"\n  published_at: \"2020-02-19\"\n  description: |-\n    Birmingham on Rails 2020 - Postgres at any Scale by Craig Kerstiens\n  video_provider: \"youtube\"\n  video_id: \"rXPtXkYU134\"\n\n- id: \"ben-greenberg-birmingham-on-rails-2020\"\n  title: \"What's Love Got To Do With It? Ruby and Sentiment Analysis\"\n  raw_title: \"Birmingham on Rails 2020 - What's Love Got To Do With It?... by Ben Greenberg\"\n  speakers:\n    - Ben Greenberg\n  event_name: \"Birmingham on Rails 2020\"\n  date: \"2020-01-31\"\n  published_at: \"2020-02-19\"\n  description: |-\n    Birmingham on Rails 2020 - What's Love Got To Do With It? Ruby and Sentiment Analysis by Ben Greenberg\n  video_provider: \"youtube\"\n  video_id: \"Xrr7Q-0HdtY\"\n\n- id: \"anthony-crumley-birmingham-on-rails-2020\"\n  title: \"Site Reliability on Rails\"\n  raw_title: \"Birmingham on Rails 2020 - Site Reliability on Rails by Anthony Crumley\"\n  speakers:\n    - Anthony Crumley\n  event_name: \"Birmingham on Rails 2020\"\n  date: \"2020-01-31\"\n  published_at: \"2020-02-19\"\n  description: |-\n    Birmingham on Rails 2020 - Site Reliability on Rails by Anthony Crumley\n  video_provider: \"youtube\"\n  video_id: \"BHLS2pmBrIk\"\n\n- id: \"sandi-metz-birmingham-on-rails-2020\"\n  title: \"Closing Keynote: Lucky You\"\n  raw_title: \"Birmingham on Rails 2020 - Closing Keynote: Lucky You by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"Birmingham on Rails 2020\"\n  date: \"2020-01-31\"\n  published_at: \"2020-02-19\"\n  description: |-\n    Birmingham on Rails 2020 - Closing Keynote: Lucky You by Sandi Metz\n  video_provider: \"youtube\"\n  video_id: \"3EUnauHNikw\"\n"
  },
  {
    "path": "data/birmingham-on-rails/series.yml",
    "content": "---\nname: \"Birmingham on Rails\"\nwebsite: \"https://www.birminghamonrails.com\"\ntwitter: \"bhmonrails\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Birmingham on Rails\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/blastoffrails/blastoffrails-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://www.papercall.io/blastoff\"\n  open_date: \"2025-09-15\"\n  close_date: \"2026-01-11\"\n"
  },
  {
    "path": "data/blastoffrails/blastoffrails-2026/event.yml",
    "content": "---\nid: \"blastoffrails-2026\"\ntitle: \"Blastoff Rails 2026\"\nlocation: \"Albuquerque, NM, United States\"\nkind: \"conference\"\ndescription: |-\n  Blastoff Rails Albuquerque 2026\nstart_date: \"2026-06-11\"\nend_date: \"2026-06-12\"\ndate_precision: \"day\"\nyear: 2026\nbanner_background: \"#fef0d4\"\nfeatured_background: \"#fef0d4\"\nfeatured_color: \"#b64023\"\nwebsite: \"https://blastoffrails.com\"\ntickets_url: \"https://ti.to/blastoff-rails/2025\"\ncoordinates:\n  latitude: 35.097735421515075\n  longitude: -106.6682148179672\n"
  },
  {
    "path": "data/blastoffrails/blastoffrails-2026/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - \"Travis Dockter\"\n"
  },
  {
    "path": "data/blastoffrails/blastoffrails-2026/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"typesense\"\n        - name: \"Avo\"\n          website: \"https://avohq.io/\"\n          slug: \"avo\"\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n"
  },
  {
    "path": "data/blastoffrails/blastoffrails-2026/venue.yml",
    "content": "---\nname: \"Albuquerque Museum\"\naddress:\n  street: \"2000 Mountain Rd NW\"\n  city: \"Albuquerque\"\n  region: \"NM\"\n  postal_code: \"87104\"\n  country: \"USA\"\n  country_code: \"US\"\n  display: \"2000 Mountain Rd NW, Albuquerque, NM 87104\"\ncoordinates:\n  latitude: 35.097735421515075\n  longitude: -106.6682148179672\nmaps:\n  google: \"https://maps.app.goo.gl/Cems3eEchX6VMPf4A\"\n\nhotels:\n  - name: \"Hotel Albuquerque\"\n    address:\n      street: \"800 Rio Grande Boulevard Northwest\"\n      city: \"Albuquerque\"\n      region: \"New Mexico\"\n      postal_code: \"87104\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"800 Rio Grande Blvd NW, Albuquerque, NM 87104\"\n    distance: \"6 minute walk from venue\"\n    coordinates:\n      latitude: 35.1003955\n      longitude: -106.6696236\n    maps:\n      google: \"https://maps.app.goo.gl/pm6oJCBdZMnAeuBT8\"\n  - name: \"Best Western Rio Grande Inn\"\n    address:\n      street: \"1015 Rio Grande Boulevard Northwest\"\n      city: \"Albuquerque\"\n      region: \"New Mexico\"\n      postal_code: \"87104\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"1015 Rio Grande Blvd NW, Albuquerque, NM 87104\"\n    distance: \"12 minute walk from venue\"\n    coordinates:\n      latitude: 35.104207\n      longitude: -106.6712297\n    maps:\n      google: \"https://maps.app.goo.gl/bYT46SnkoWouAhuy7\"\n"
  },
  {
    "path": "data/blastoffrails/blastoffrails-2026/videos.yml",
    "content": "---\n- id: \"irina-nazarova-blastoffrails-2026\"\n  title: \"Keynote: Irina Nazarova\"\n  video_provider: \"scheduled\"\n  video_id: \"blastoffrails-2026-irina-nazarova-keynote\"\n  date: \"2026-06-11\"\n  description: |-\n    CEO of Evil Martians, Irina Nazarova is deep in the world of startups and Ruby on Rails.\n  speakers:\n    - \"Irina Nazarova\"\n\n- id: \"kieran-klaassen-blastoffrails-2026\"\n  title: \"Keynote: Kieran Klaassen\"\n  date: \"2026-06-11\"\n  video_provider: \"scheduled\"\n  video_id: \"blastoffrails-2026-kieran-klaassen-keynote\"\n  description: |-\n    General Manager of Cora, Kieran Klaassen is a serial entrepreneur and a proponent of agentic coding and compounding engineering.\n  speakers:\n    - \"Kieran Klaassen\"\n\n- id: \"avi-flombaum-blastoffrails-2026\"\n  title: \"How to become a famous Ruby, Rails, Agentic Developer\"\n  description: |-\n    The next generation of great developers will not just write code. They will design workflows. They will build tools. They will publish their thinking. In this talk, Avi will show you how to understand and design your own development workflow, build your own tools while intelligently leveraging the ecosystem, create an Agentic Workbench tailored to how you think and ship, and write and publish in a way that compounds your reputation. Fame is not luck. It is output plus distribution. Let's build both.\n  date: \"2026-06-11\"\n  speakers:\n    - Avi Flombaum\n  video_provider: \"scheduled\"\n  video_id: \"avi-flombaum-blastoffrails-2026\"\n\n- id: \"neha-abraham-blastoffrails-2026\"\n  title: \"Powerful Data: Making Rails Apps Faster with Aggregation\"\n  description: |-\n    Slow dashboards are a classic Rails problem. This talk shows how powerful data aggregation can make Rails dashboards fast, predictable, and calm again by letting the database do the work and keeping Ruby out of performance-critical math.\n  date: \"2026-06-11\"\n  speakers:\n    - Neha Abraham\n  video_provider: \"scheduled\"\n  video_id: \"neha-abraham-blastoffrails-2026\"\n\n- id: \"nikky-southerland-blastoffrails-2026\"\n  title: \"Spaceships, Radiation Therapy, and Power Users\"\n  description: |-\n    We build software that our users interact with daily, and it's only natural that over time they become really, really good at navigating the interfaces we've designed. This is great! Except their skill makes them more prone to introducing unintended behavior to the system. We'll zoom in on a couple of notable interface designs from history: Apollo's guidance computer and the Therac-25 radiation therapy machine. We'll explore how to proactively keep power users in mind to increase efficiency and reduce frustration.\n  date: \"2026-06-11\"\n  speakers:\n    - Nikky Southerland\n  video_provider: \"scheduled\"\n  video_id: \"nikky-southerland-blastoffrails-2026\"\n\n- id: \"andrew-mason-blastoffrails-2026\"\n  title: \"We Are the Ruby Community\"\n  description: |-\n    Many developers feel like observers of the Ruby community rather than participants in it. This talk reframes what community actually means, breaks down the invisible barriers that make people feel like they don't belong, and shows practical ways anyone can participate right away. The goal is to show that the Ruby community isn't something you join, it's something you help create.\n  date: \"2026-06-11\"\n  speakers:\n    - Andrew Mason\n  video_provider: \"scheduled\"\n  video_id: \"andrew-mason-blastoffrails-2026\"\n\n- id: \"ifat-ribon-blastoffrails-2026\"\n  title: \"Fewer Tests, More Confidence\"\n  description: |-\n    AI can write tests in seconds, but it can't tell you which ones matter (yet). This talk shows how Rails teams can build high-confidence test suites when AI generates most specs, using clear testing principles and practical guidelines to write fewer, better, and more maintainable tests.\n  date: \"2026-06-11\"\n  speakers:\n    - Ifat Ribon\n  video_provider: \"scheduled\"\n  video_id: \"ifat-ribon-blastoffrails-2026\"\n\n- id: \"stephen-mckeon-blastoffrails-2026\"\n  title: \"Why We're Still Training Rails Developers in an Age of AI\"\n  description: |-\n    With the rapid rise of AI-assisted development tools, there's growing uncertainty about the future of junior developers—particularly those learning frameworks like Rails. Stephen shares lessons from teaching the Power Code Academy, an internal program at Power Home Remodeling that trains employees with little to no technical background into full-stack Rails developers. Rather than focusing on AI as a solution, this talk examines why sustained investment in human growth still matters—for businesses building Rails applications, for developers learning the framework, and for the long-term health of the Rails community.\n  date: \"2026-06-11\"\n  speakers:\n    - Stephen McKeon\n  video_provider: \"scheduled\"\n  video_id: \"stephen-mckeon-blastoffrails-2026\"\n\n- id: \"matheus-richard-blastoffrails-2026\"\n  title: \"Rubyists can make games too!\"\n  description: |-\n    Every developer dreams of making a game but eventually gets swallowed by the corporate job world. Dream no more. You don't need engines or new languages. You already have everything you need: Ruby. Let's build a real game together and scratch that gamedev itch you never outgrew.\n  date: \"2026-06-11\"\n  speakers:\n    - Matheus Richard\n  video_provider: \"scheduled\"\n  video_id: \"matheus-richard-blastoffrails-2026\"\n"
  },
  {
    "path": "data/blastoffrails/series.yml",
    "content": "---\nname: \"Blastoff Rails\"\nwebsite: \"https://blastoffrails.com\"\ngithub: \"\"\ntwitter: \"blastoffrails\"\nmastodon: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"USA\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2023/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKXxB73KZaZt1sNHqnSPdTp9\"\ntitle: \"Blue Ridge Ruby 2023\"\nkind: \"conference\"\nlocation: \"Asheville, NC, United States\"\ndescription: |-\n  A friendly, regional Ruby conference in the mountains of western North Carolina. We spend most of the year heads-down in our own projects and codebases. Once in a while, it’s good to step back and survey the horizon, alongside a few companions. “Take a break from the gem mine, and get up to the ridge line.”\npublished_at: \"2024-01-01\"\nstart_date: \"2023-06-08\"\nend_date: \"2023-06-09\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2023\nbanner_background: \"#fff\"\nfeatured_background: \"#E1EFFA\"\nfeatured_color: \"#0C2866\"\nwebsite: \"https://blueridgeruby.com/2023\"\ncoordinates:\n  latitude: 35.59816209289096\n  longitude: -82.55246525892764\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2023/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jeremy Smith\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2023/schedule.yml",
    "content": "# Schedule: https://web.archive.org/web/20230509154638/https://blueridgeruby.com/schedule/\n---\ndays:\n  - name: \"Wednesday, June 7th\"\n    date: \"2023-06-07\"\n    grid:\n      - start_time: \"19:00\"\n        end_time: \"21:00\"\n        slots: 1\n        items:\n          - Pre-Conference Meetup\n\n  - name: \"Thursday, June 8th\"\n    date: \"2023-06-08\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration, Coffee, Light Breakfast\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Welcome, Day 1\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Open Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Closing, Day 1\n\n      - start_time: \"17:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - Happy Hour\n\n  - name: \"Friday, June 9th\"\n    date: \"2023-06-09\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Coffee, Light Breakfast\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Welcome, Day 2\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Open Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Closing, Day 2\n\n      - start_time: \"20:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Afterparty\n\n  - name: \"Saturday, June 10th\"\n    date: \"2023-06-10\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Saturday Activities\n\ntracks: []\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2023/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby\"\n      level: 1\n      sponsors: []\n\n    - name: \"Sapphire\"\n      level: 2\n      sponsors:\n        - name: \"SOFware\"\n          website: \"https://sofwarellc.com/\"\n          slug: \"sofware\"\n          logo_url: \"https://blueridgeruby.com/images/sponsors/sofware.svg\"\n\n    - name: \"Emerald\"\n      level: 3\n      sponsors:\n        - name: \"Evil Martians\"\n          website: \"https://evilmartians.com/\"\n          slug: \"evil-martians\"\n          logo_url: \"https://blueridgeruby.com/images/sponsors/evil_martians.svg\"\n\n        - name: \"Spreedly\"\n          website: \"https://www.spreedly.com/\"\n          slug: \"spreedly\"\n          logo_url: \"https://blueridgeruby.com/images/sponsors/spreedly.svg\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2023/venue.yml",
    "content": "---\nname: \"Asheville Masonic Temple\"\naddress:\n  street: \"80 Broadway St\"\n  city: \"Asheville\"\n  region: \"NC\"\n  postal_code: \"28801\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"80 Broadway St, Asheville, NC 28801\"\ncoordinates:\n  latitude: 35.59816209289096\n  longitude: -82.55246525892764\nmaps:\n  google: \"https://maps.app.goo.gl/sbCxrvXLZNdeKg9RA\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: schedule website\n\n# Website: https://blueridgeruby.com/2023\n\n- id: \"kevin-murphy-blue-ridge-ruby-2023\"\n  title: \"Enough Coverage To Beat The Band\"\n  raw_title: \"BlueRidgeRuby 2023: Enough Coverage To Beat The Band. Meet Ruby's Coverage Module - Kevin Murphy\"\n  speakers:\n    - Kevin Murphy\n  event_name: \"Blue Ridge Ruby 2023\"\n  date: \"2023-06-08\"\n  slides_url: \"https://speakerdeck.com/kevinmurphy/enough-coverage-to-beat-the-band\"\n  description: |-\n    The lights cut out. The crowd roars. It’s time. The band takes the stage. They’ve practiced the songs, particularly the covers. They’ve sound checked the coverage of the speakers. They know the lighting rig has the proper colored gels covering the lamps. They’re nervous, but they’ve got it all covered.\n\n    Similarly, code coverage can give you confidence before your app performs on production and also tell you how live code is used (or not used). We’ll cover how to leverage ruby’s different coverage measurement techniques in concert to assist your crew and delight your audience.\n  video_provider: \"youtube\"\n  video_id: \"H4pBjWOMr_Y\"\n  published_at: \"2023-12-27\"\n\n- id: \"stephanie-minn-blue-ridge-ruby-2023\"\n  title: \"Empathetic Pair Programming with Nonviolent Communication\"\n  raw_title: \"BlueRidgeRuby 2023: Empathetic Pair Programming with Nonviolent Communication - Stephanie Minn\"\n  speakers:\n    - Stephanie Minn\n  event_name: \"Blue Ridge Ruby 2023\"\n  date: \"2023-06-08\"\n  description: |-\n    Pair programming is intimate. It’s the closest collaboration we do as software developers. When it goes well, it feels great! But when it doesn’t, you might be left feeling frustrated, discouraged, or withdrawn.\n\n    To navigate the vulnerability of sharing our keyboard and code, let’s learn about nonviolent communication (NVC), an established practice of deep listening to ourselves and others. We’ll cover real-life examples and how to apply the four tenets of NVC — observations, feelings, needs, and requests — to bring more joy and fulfillment the next time you pair.\n  video_provider: \"youtube\"\n  video_id: \"sVeKT36coAQ\"\n  published_at: \"2023-12-30\"\n\n- id: \"landon-gray-blue-ridge-ruby-2023\"\n  title: \"Forecasting the Future: An Introduction to Machine Learning for Weather Prediction in Native Ruby\"\n  raw_title: \"BlueRidgeRuby 2023: Forecasting the Future: An Intro to Machine Learning with Ruby - Landon Gray\"\n  speakers:\n    - Landon Gray\n  event_name: \"Blue Ridge Ruby 2023\"\n  date: \"2023-06-08\"\n  description: |-\n    Have you ever considered building a machine learning model in Ruby? It may surprise you to learn that you can train, build, and deploy ML models in Ruby. But what are the benefits of using Ruby over other languages?\n\n    One of the biggest advantages of using Ruby for machine learning is accessibility. You’re no longer limited to specific languages or tools when exploring AI and ML concepts. It’s time for Rubyists to dive into the world of machine learning!\n\n    In this talk, we’ll build a model that predicts the weather and explore the tools and libraries available for your own native Ruby Machine Learning projects.\n\n    Whether you’re a seasoned Rubyist or just starting out, don’t miss this opportunity to discover the possibilities of machine learning in Ruby.\n  video_provider: \"youtube\"\n  video_id: \"11yubbTx8Ow\"\n  published_at: \"2023-12-27\"\n\n- id: \"caleb-hearth-blue-ridge-ruby-2023\"\n  title: \"RSpec: The Bad Parts\"\n  raw_title: \"BlueRidgeRuby 2023: RSpec: The Bad Parts - Caleb Hearth\"\n  speakers:\n    - Caleb Hearth\n  event_name: \"Blue Ridge Ruby 2023\"\n  date: \"2023-06-08\"\n  description: |-\n    RSpec is good, but it’s even better with less of it. We’ll first look through a heavily obfuscated real-world example, learning why parts of RSpec like let, subject, before, shared_examples, and behaves like can make your tests hard to read, difficult to navigate, and more complex. We’ll discuss when DRY is not worth the price. Then we’ll refactor some real open source RSpec code from Mastodon. In the end, we’ll look at what’s left. RSpec: The Good Parts.\n  video_provider: \"youtube\"\n  video_id: \"5lNwSpgMwH0\"\n  published_at: \"2024-01-01\"\n\n- id: \"annie-kiley-blue-ridge-ruby-2023\"\n  title: \"Maintenance Matters: Maintaining Your Rails App and Your Sanity\"\n  raw_title: \"BlueRidgeRuby2023: Maintenance Matters: Maintaining Your Rails App and Your Sanity - Annie Kiley\"\n  speakers:\n    - Annie Kiley\n  event_name: \"Blue Ridge Ruby 2023\"\n  date: \"2023-06-08\"\n  description: |-\n    We all love shiny new tech and greenfield projects, but as software developers, we spend a lot of our time working with existing code. So let’s spend a few minutes talking about ways to improve the day-to-day developer experience of maintaining a Rails app. The examples and tools in this talk are specific to Ruby on Rails, but the ideas can apply to any stack. I will try to leave you with ten things that you can do tomorrow to make maintaining your application just a little easier.\n  video_provider: \"youtube\"\n  video_id: \"hIV7RDpvTzQ\"\n  published_at: \"2024-01-01\"\n\n- id: \"kevin-menard-blue-ridge-ruby-2023\"\n  title: \"Making Ruby Fast(er)\"\n  raw_title: \"BlueRidgeRuby2023: Making Ruby Fast(er) - Kevin Menard\"\n  speakers:\n    - Kevin Menard\n  event_name: \"Blue Ridge Ruby 2023\"\n  date: \"2023-06-08\"\n  description: |-\n    Ruby has always been a developer-friendly language, but that has often come at the expense of performance. The past several years have seen massive performance gains CRuby, JRuby, and TruffleRuby. Long-held assumptions about Ruby’s performance ceiling have been challenged and up-ended. In this talk, we’ll look at improvements in the virtual machine and the introduction of JIT compilers to better understand what’s making your Ruby code run fast(er).\n  video_provider: \"youtube\"\n  video_id: \"s0NMy_PBxkk\"\n  published_at: \"2024-01-01\"\n\n- id: \"emily-samp-blue-ridge-ruby-2023\"\n  title: \"What’s your type? Generating type signatures with Sorbet and Tapioca\"\n  raw_title: \"BlueRidgeRuby2023: What's you type? Generating type signatures with Sorbet and Tapioca - Emily Samp\"\n  speakers:\n    - Emily Samp\n  event_name: \"Blue Ridge Ruby 2023\"\n  date: \"2023-06-09\"\n  slides_url: \"https://drive.google.com/drive/folders/1Wv0i-WNrMaeInQma1H28i4pwHlb_lMHp?usp=sharing\"\n  description: |-\n    You’ve likely heard of Sorbet, a gradual type checker for Ruby. Using Sorbet, developers can harness the flexibility and creativity of a dynamic language like Ruby, while also benefitting from the safety of typing.\n\n    However, in most apps, Sorbet will need some help type checking gem dependencies. This is the purpose of Tapioca, a gem that generates type signatures for other gems so they can be type checked by Sorbet.\n\n    But how does Tapioca accomplish this? In this talk, we’ll dive into the tools and techniques used by Tapioca to reflect on Ruby code, and even walk through the process of building a new feature in the Tapioca codebase!\n  video_provider: \"youtube\"\n  video_id: \"TeMqO3lzfMI\"\n  published_at: \"2024-01-01\"\n\n- id: \"thomas-carr-blue-ridge-ruby-2023\"\n  title: \"Digital Identity or: How I Learned to Stop Worrying and Love Web3\"\n  raw_title: \"BlueRidgeRuby 2023: Digital Identity or:How I Learned to Stop Worrying and Love Web3 - Thomas Mann\"\n  speakers:\n    - Thomas Carr\n  event_name: \"Blue Ridge Ruby 2023\"\n  date: \"2023-06-09\"\n  description: |-\n    Rubyists love the web, and it’s usually the primary platform for our applications. We tend to be highly pragmatic developers, choosing boring, well-tested technologies over what’s new and hot on Hacker News. Nowhere is this more evident than web3. Tasked with finding real use-cases for the federal government using these “decentralized” protocols and technologies, I’m here to tell you that in our — mostly justified — dismissal of web3, we are missing out on a pivotal innovation for user experience across the web: portable, verifiable, & interoperable digital identity.\n  video_provider: \"youtube\"\n  video_id: \"YRmwQNmLbLQ\"\n  published_at: \"2023-12-30\"\n\n- id: \"ifat-ribon-blue-ridge-ruby-2023\"\n  title: \"Go Pro with POROs\"\n  raw_title: \"BlueRidgeRuby2023: Go Pro with POROs - Ifat Ribon\"\n  speakers:\n    - Ifat Ribon\n  event_name: \"Blue Ridge Ruby 2023\"\n  date: \"2023-06-09\"\n  description: |-\n    Plain Old Ruby Objects (POROs) are having a moment. Maybe you’ve heard a whisper in the corner about the jack-of-all trades Service Object, or a glimmering echo of advocacy for non-database-backed domain models? Think you’re using them right? Afraid you’re using them wrong? Then this is the talk for you! We’re going to explore the wonderful world of “convention plus choose-your-own configuration” of Rails codebases and the shining role of POROs (with their ride or dies, the Module). Come hear about the diversity of design patterns out in the wild so you too can confidently tell your coworkers “let’s just use a PORO for that”.\n  video_provider: \"youtube\"\n  video_id: \"rvTOWaWwIkQ\"\n  published_at: \"2024-01-01\"\n\n- id: \"mo-oconnor-blue-ridge-ruby-2023\"\n  title: \"How can I move forward when I don’t know where I want to go?\"\n  raw_title: \"BlueRidgeRuby2023: How Can I Move Forward When I Don't Know Where I Want To Go? - Mo O'Connor\"\n  speakers:\n    - Mo O'Connor\n  event_name: \"Blue Ridge Ruby 2023\"\n  date: \"2023-06-09\"\n  description: |-\n    Many of us are driven towards professional development and the next level, but what happens when the next level could be more than one thing? It could mean a promotion from mid-level to senior-level, taking on leadership responsibilities, or moving to a people-management role. What if we’re not sure which direction we want to go? In this talk, I’ll discuss ways you can move forward even when you haven’t decided on the trajectory yet. You'll walk away with tools and tactics you can utilize to pave and navigate your own path forward.\n  video_provider: \"youtube\"\n  video_id: \"7naaDdkcNt0\"\n  published_at: \"2023-12-30\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2024/cfp.yml",
    "content": "---\n- link: \"https://blueridgeruby.com/cfp\"\n  open_date: \"2024-01-18\"\n  close_date: \"2024-03-01\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2024/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaS0wvlCfYjl4fh9ALTxSg1\"\ntitle: \"Blue Ridge Ruby 2024\"\nkind: \"conference\"\nlocation: \"Asheville, NC, United States\"\ndescription: |-\n  A friendly, regional Ruby conference in the mountains of western North Carolina. We spend most of the year heads-down in our own projects and codebases. Once in a while, it’s good to step back and survey the horizon, alongside a few companions. “Take a break from the gem mine, and get up to the ridge line.”\npublished_at: \"2024-06-24\"\nstart_date: \"2024-05-30\"\nend_date: \"2024-05-31\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2024\nbanner_background: \"#fff\"\nfeatured_background: \"#E1EFFA\"\nfeatured_color: \"#0C2866\"\nwebsite: \"https://blueridgeruby.com/2024\"\ncoordinates:\n  latitude: 35.59491\n  longitude: -82.553696\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2024/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Mark Locklear\n    - Joe Peck\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2024/venue.yml",
    "content": "---\nname: \"The Collider\"\naddress:\n  street: \"1 Haywood St 4th floor\"\n  city: \"Asheville\"\n  region: \"NC\"\n  postal_code: \"28801\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"1 Haywood St 4th floor, Asheville, NC 28801\"\ncoordinates:\n  latitude: 35.594910\n  longitude: -82.553696\nmaps:\n  google: \"https://maps.app.goo.gl/LwAxp3gpRB3sqzJ56\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2024/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: schedule website\n\n# Website: https://blueridgeruby.com/2024/\n\n- id: \"daniel-colson-blue-ridge-ruby-2024\"\n  title: \"The Very Hungry Transaction\"\n  raw_title: \"Blue Ridge Ruby 2024 | The Very Hungry Transaction by Daniel Colson\"\n  speakers:\n    - Daniel Colson\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Have your database transactions become a liability? Transactions are an essential tool, and frameworks like Rails make them easy to write. But it's also easy to fall into some dangerous patterns that can threaten your data integrity and application availability. Find out more before it's too late!\n    ___________________________________________________________________________________________________\n    Daniel is a Senior Software Engineer on the Ruby Architecture team at GitHub. He's worked on Rails applications of all sizes, and contributed to numerous open source projects. Daniel was formerly a composer, violist da gamba, and professor of music.\n  video_provider: \"youtube\"\n  video_id: \"78HzHhMnhHY\"\n  published_at: \"2024-06-25\"\n\n- id: \"brian-childress-blue-ridge-ruby-2024\"\n  title: \"Simplicity: The Key to Software Success\"\n  raw_title: \"Blue Ridge Ruby 2024 | Simplicity: The Key to Software Success by Brian Childress\"\n  speakers:\n    - Brian Childress\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    In a world dominated by cutting-edge technologies and complex systems, it is easy to overlook the power of simplicity in software. Let's explore the benefits of simple software with real-world examples to uncover how simplicity can be a game-changer for developers, businesses, and end-users alike.\n    ___________________________________________________________________________\n    Brian is an accomplished technologist, having spent time building and scaling software in many highly-regulated environments. He holds multiple patents for software design, speaks internationally, and is a sought after thought leader.\n\n    Brian resides in Virginia and loves to travel and explore, often bringing his family along for the adventure.\n  video_provider: \"youtube\"\n  video_id: \"2Z2s4mRxT0A\"\n  published_at: \"2024-07-30\"\n\n- id: \"craig-buchek-blue-ridge-ruby-2024\"\n  title: \"Nil - Nothing is Easy, Is It?\"\n  raw_title: \"Blue Ridge Ruby 2024 | Nil - Nothing is Easy, Is It? by Craig Buchek\"\n  speakers:\n    - Craig Buchek\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Nil is pretty simple — it represents nothing. But that doesn't mean that it's always easy to use, or that it's always the right choice when it appears to be the obvious choice.\n\n    We'll cover several anti-patterns in the use of nil. We'll discuss *why* they're problematic, and explore some better alternatives. The refactorings that we'll look at will help to reduce errors and optimize for understanding. Writing good code might take a little longer in the short run, but it pays off in the long run.\n    ___________________________________________________________________________________________________\n    Craig has been using Ruby and Rails since 2005. He enjoys writing concise readable code, especially in Ruby. He enjoys a player-coach role, helping teams improve their processes, technical practices, and automation. (He's likely looking for work.)\n\n    Giving a conference talk is Craig's way to strike up some conversations. So feel free to go up to him and “talk shop”. If you want to make small talk, ask Craig about traveling, attending concerts, beekeeping, or where he was when the pandemic hit.\n  video_provider: \"youtube\"\n  video_id: \"UiHFBpXa0vE\"\n  published_at: \"2024-06-25\"\n\n- id: \"john-paul-ashenfelter-blue-ridge-ruby-2024\"\n  title: \"My Rails App is Old Enough to Drink: Over Two Decades with One App\"\n  raw_title: \"Blue Ridge Ruby 2024 | My Rails App is Old Enough to Drink: Over Two... by John Paul Ashenfelter\"\n  speakers:\n    - John Paul Ashenfelter\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    My Rails App is Old Enough to Drink: Over Two Decades with One App by John Paul Ashenfelter\n\n    I've been running the same Rails app for two decades. I want to share some history about why Rails was a good choice then (and now!), cover what has changed and what's remained the same over the years, and look ahead to what's in store as one developer and one app start our third decade together.\n  video_provider: \"youtube\"\n  video_id: \"AeZ-mDP7hwo\"\n  published_at: \"2024-06-25\"\n\n- id: \"lauren-auchter-blue-ridge-ruby-2024\"\n  title: \"Navigating Career Transitions - Stop Second Guessing and Let Go of Guilt\"\n  raw_title: \"Blue Ridge Ruby 2024 | Navigating Career Transitions - Stop Second Guessing... by Lauren Auchter\"\n  speakers:\n    - Lauren Auchter\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Navigating Career Transitions - Stop Second Guessing and Let Go of Guilt by Lauren Auchter\n\n    When navigating your career it's vital to evaluate whether it's time to take a new step and all to common to feel guilty about an impending change. Learn ways to refocus from guilt to appreciation as we walk through my winding career path and how I identified the right moments to make a change.\n    ___________________________________________________________________________________________________\n    Lauren started her career in edtech as an educator at science museums and transitioned to the engineering side with the help of Thinkful's Engineering Flex program. She continues having a positive impact on education as a Senior Engineer and technical lead at Instructure creating accessible applications. When she's not coding you can find Lauren chasing her toddler or surrounded by her latest crafting endeavor.\n  video_provider: \"youtube\"\n  video_id: \"O-d57To1ym4\"\n  published_at: \"2024-06-25\"\n\n- id: \"max-veldink-blue-ridge-ruby-2024\"\n  title: \"Refactoring: The ASMR of Programming Talks\"\n  raw_title: \"Blue Ridge Ruby 2024 | Refactoring: The ASMR of Programming Talks by Max VelDink\"\n  speakers:\n    - Max VelDink\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Ruby has a long history of incredible refactoring talks (shout out to Sandi Metz and Katrina Owen!), providing \"aha\" moments for developers and being oh-so-satisfying at the same time. In that vein, let's take an opportunity to refactor some code and release some serotonin.\n    ___________________________________________________________________________\n    I'm a staff software engineer who has created full-stack web applications for more than a decade. My focus is on combining the best of object-oriented and functional philosophies while meditating on novel architecture approaches, especially for Ruby applications.\n\n    Teaching the next generation of Rubyists is incredibly important to me, and I'm currently thinking through modern Ruby courses to replace the Ruby boot camps that have gone out of favor.\n  video_provider: \"youtube\"\n  video_id: \"5GnWGpUJ_2Q\"\n  published_at: \"2024-06-25\"\n\n- id: \"travis-turner-blue-ridge-ruby-2024\"\n  title: \"Narrative Reflections: Transmuting Ruby Code into Storytelling Gold\"\n  raw_title: \"Blue Ridge Ruby 2024 | Narrative Reflections: Transmuting Ruby Code into... by Travis Turner\"\n  speakers:\n    - Travis Turner\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Narrative Reflections: Transmuting Ruby Code into Storytelling Gold by Travis Turner\n\n    Uncover the secrets behind crafting compelling content, overcoming writer's block(s), best practices, and sharing your Ruby journey. This talk, from a seasoned writer and editor, is filled with lessons and tips from the pros and offers practical writing steps for every Rubyist.\n\n    ___________________________________________________________________________\n    Travis Turner is the editor-in-chief at Evil Martians. He helps write, edit, and shape content on a number of cool topics — including Ruby! With a background ranging from journalism, EdTech, to his own time as an IT consultant, he brings a wide-ranging perspective to his work, placing an emphasis on reader experience, helping developers find their voice, share knowledge, and illuminate interesting stories.\n  video_provider: \"youtube\"\n  video_id: \"YyBTAdpOCIY\"\n  published_at: \"2024-06-25\"\n\n- id: \"louis-antonopoulos-blue-ridge-ruby-2024\"\n  title: \"Glimpses of Humanity: My Game-Building AI Pair\"\n  raw_title: \"Blue Ridge Ruby 2024 | Glimpses of Humanity: My Game-Building AI Pair by Louis Antonopoulos\"\n  speakers:\n    - Louis Antonopoulos\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    I built a game in Rails with an AI partner: my associate, Atheniel-née-ChatGPT!\n\n    Improve how you talk with that special machine in your life ❤️❤️❤️ and learn how magical a machine-human conversation can be.\n\n    Live through our shared experience: from goals to a project plan to a working game.\n\n    ___________________________________________________________________________\n    Louis is a Rails developer, song-parody writer, and committed punster. He never once skied in the Olympics. Louis started as an iOS developer but couldn't help falling in love with Rails, TDD, and the joy of not having to wait for app store approval.\n  video_provider: \"youtube\"\n  video_id: \"SUPfww8gjUs\"\n  published_at: \"2024-06-25\"\n\n- id: \"rachael-wright-munn-blue-ridge-ruby-2024\"\n  title: \"Validate Me! - Demystifying Rails Validators\"\n  raw_title: \"Blue Ridge Ruby 2024 | Validate Me! - Demystifying Rails Validators by Rachael Wright-Munn\"\n  speakers:\n    - Rachael Wright-Munn\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Unlock the secrets of Rails validators in this enlightening session. Ever wondered what's really happening behind the scenes? Join us as we delve deep into the inner workings of Rails validators, unravel their hidden complexities, and empower you to craft your own custom validators with confidence!\n\n    ___________________________________________________________________________\n    Rachael has been a software engineer since 2012, 3x team lead, and enjoys livestreaming her open-source contributions on Twitch. She added the ComparisonValidator to Rails, built the Jekyll-Twitch gem, and is working on an app for making friends at conferences.\n  video_provider: \"youtube\"\n  video_id: \"evSgpTOYW-I\"\n  published_at: \"2024-06-25\"\n\n- id: \"cindy-backman-blue-ridge-ruby-2024\"\n  title: \"Lightning Talk: Confreaks\"\n  raw_title: \"Blue Ridge Ruby 2024 | Lightning Talk by Cindy Backman\"\n  speakers:\n    - Cindy Backman\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Lightning Talk by Cindy Backman\n  video_provider: \"youtube\"\n  video_id: \"5UNaP0gFENg\"\n  published_at: \"2024-06-25\"\n\n- id: \"daniel-nolan-blue-ridge-ruby-2024\"\n  title: \"Lightning Talk: ChatGPT Landscape Assistant\"\n  raw_title: \"Blue Ridge Ruby 2024 | Lightning Talk by Daniel Nolan\"\n  speakers:\n    - Daniel Nolan\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Lightning Talk by Daniel Nolan\n  video_provider: \"youtube\"\n  video_id: \"wYgojhbyHpE\"\n  published_at: \"2024-06-25\"\n\n- id: \"john-epperson-blue-ridge-ruby-2024\"\n  title: \"Lightning Talk: Shower Thoughts - Being Overwhelmed\"\n  raw_title: \"Blue Ridge Ruby 2024 | Lightning Talk by John Epperson\"\n  speakers:\n    - John Epperson\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Lightning Talk by John Epperson\n  video_provider: \"youtube\"\n  video_id: \"zQsvI2x04Xc\"\n  published_at: \"2024-06-25\"\n\n- id: \"eric-tillberg-blue-ridge-ruby-2024\"\n  title: \"Lightning Talk: History - Technology's Ultimate Disruption\"\n  raw_title: \"Blue Ridge Ruby 2024 | Lightning Talk by Eric Tillberg\"\n  speakers:\n    - Eric Tillberg\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Lightning Talk by Eric Tillberg\n  video_provider: \"youtube\"\n  video_id: \"ktcYpd2VMa8\"\n  published_at: \"2024-06-25\"\n\n- id: \"alli-zadrozny-blue-ridge-ruby-2024\"\n  title: \"Lightning Talk: Zettelkasten - A way to create a second brain & publish content you are passionate about\"\n  raw_title: \"Blue Ridge Ruby 2024 | Lightning Talk by Alli Zadrozny\"\n  speakers:\n    - Alli Zadrozny\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Lightning Talk by Alli Zadrozny\n  video_provider: \"youtube\"\n  video_id: \"_p2DM3dS1Jc\"\n  published_at: \"2024-06-25\"\n\n- id: \"giovann-filippi-blue-ridge-ruby-2024\"\n  title: \"Lightning Talk: Shape Up\"\n  raw_title: \"Blue Ridge Ruby 2024 | Lightning Talk by Giovann Filippi\"\n  speakers:\n    - Giovann Filippi\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Lightning Talk by Giovann Filippi\n  video_provider: \"youtube\"\n  video_id: \"ZOcFnlJvKzM\"\n  published_at: \"2024-06-25\"\n\n- id: \"lee-mcalilly-blue-ridge-ruby-2024\"\n  title: \"Lightning Talk: Synthetic Focus Groups - Predicting Human Behavior\"\n  raw_title: \"Blue Ridge Ruby 2024 | Lightning Talk by Lee McAlilly\"\n  speakers:\n    - Lee McAlilly\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Lightning Talk by Lee McAlilly\n  video_provider: \"youtube\"\n  video_id: \"MfrYKLv-1Ko\"\n  published_at: \"2024-06-25\"\n\n- id: \"michael-king-blue-ridge-ruby-2024\"\n  title: \"Lightning Talk: Things that you can (but not necessarily should) do with threads in Ruby/Rails\"\n  raw_title: \"Blue Ridge Ruby 2024 | Lightning Talk by Michael King\"\n  speakers:\n    - Michael King\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Lightning Talk by Michael King\n  video_provider: \"youtube\"\n  video_id: \"E6-A7DHz-8k\"\n  published_at: \"2024-06-25\"\n\n- id: \"chris-hagmann-blue-ridge-ruby-2024\"\n  title: \"Lightning Talk: Coding for the Future - A perspective\"\n  raw_title: \"Blue Ridge Ruby 2024 | Lightning Talk by Chris Hagmann\"\n  speakers:\n    - Chris Hagmann\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Lightning Talk by Chris Hagmann\n  video_provider: \"youtube\"\n  video_id: \"5EBsQ5Oyy_k\"\n  published_at: \"2024-06-25\"\n\n- id: \"dustin-haefele-tschan-blue-ridge-ruby-2024\"\n  title: \"The Pursuit of Happiness\"\n  raw_title: \"Blue Ridge Ruby 2024 | The Pursuit of Happiness by Dustin Haefele Tschan\"\n  speakers:\n    - Dustin Haefele Tschan\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  description: |-\n    Who in this world would say \"no\" to being a little happier? Luckily for us there has been a lot of wonderful scientific studies done on human happiness. This talk will cover a number of my favorite studies in this field, and how they can be applied to life and careers in tech.\n\n    ___________________________________________________________________________\n    Dustin is a Software Engineer at Spreedly who loves a good pun and riding his bike over bridges because the unabridged version is too long. In a previous life he was a Chemical engineer, but over the years he grew unhappy with factory work.\n\n    His passion for researching everything he could find about human happiness led him to quit his job, join a bootcamp, spend a few months exploring South America, and finally jump into Software Engineering full time. Dustin calls Athens, GA home, but loves to travel whenever he can.\n  video_provider: \"youtube\"\n  video_id: \"lBvo1walrKU\"\n  published_at: \"2024-06-25\"\n\n- id: \"jeremy-smith-blue-ridge-ruby-2024\"\n  title: \"A Rubyist's Guide to Existential Dread\"\n  raw_title: \"Blue Ridge Ruby 2024 | A Rubyist's Guide to Existential Dread by Jeremy Smith\"\n  speakers:\n    - Jeremy Smith\n  event_name: \"Blue Ridge Ruby 2024\"\n  date: \"2024-06-24\"\n  slides_url: \"https://speakerdeck.com/jeremysmithco/a-rubyists-guide-to-existential-dread\"\n  description: |-\n    The rumored rise of AI. A stagnant hiring market. The long shadow of industry layoffs. It seems like there's always a threat (or three) on the horizon, and even the bravest of us would be forgiven for feeling some apprehension about the future. So, what's a Rubyist to think? What's a Rubyist to do? While I don't have any guarantees, I do have a couple ideas.\n\n    ___________________________________________________________________________\n    Jeremy is a product-focused Rails developer running HYBRD, a one-person web studio. He has been working in Ruby for the past 15 years. He co-hosts the IndieRails podcast and is the founder and previous organizer for Blue Ridge Ruby.\n  video_provider: \"youtube\"\n  video_id: \"wAmq-7J9eHc\"\n  published_at: \"2024-06-25\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://blueridgeruby.com/cfp\"\n  open_date: \"2025-12-15\"\n  close_date: \"2026-02-03\"\n- name: \"Hack Day CFP\"\n  link: \"https://docs.google.com/forms/d/e/1FAIpQLSffmFRZ0M9SoxEEjLBwnKjLy_jvA8zg5JenYZ1SeOGNPglF3w/viewform\"\n  close_date: \"2026-05-02\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2026/event.yml",
    "content": "---\nid: \"blue-ridge-ruby-2026\"\ntitle: \"Blue Ridge Ruby 2026\"\nkind: \"conference\"\nlocation: \"Asheville, NC, United States\"\ndescription: |-\n  A friendly, regional Ruby conference in the mountains of western North Carolina. We spend most of the year heads-down in our own projects and codebases. Once in a while, it’s good to step back and survey the horizon, alongside a few companions. “Take a break from the gem mine, and get up to the ridge line.”\nstart_date: \"2026-04-30\"\nend_date: \"2026-05-01\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2026\nbanner_background: \"#fff\"\nfeatured_background: \"#E1EFFA\"\nfeatured_color: \"#0C2866\"\nwebsite: \"https://blueridgeruby.com/\"\ntickets_url: \"https://ti.to/blue-ridge-ruby/blue-ridge-ruby-2026\"\ncoordinates:\n  latitude: 35.593957\n  longitude: -82.550029\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2026/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jeremy Smith\n    - Mark Locklear\n    - Joe Peck\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2026/schedule.yml",
    "content": "# Schedule: https://blueridgeruby.com/schedule/\n---\ndays:\n  - name: \"Wednesday, April 29th\"\n    date: \"2026-04-29\"\n    grid:\n      - start_time: \"19:00\"\n        end_time: \"21:00\"\n        slots: 1\n        items:\n          - title: \"Pre-Conference Meetup\"\n            description: |-\n              Most likely somewhere on South Slope\n\n  - name: \"Thursday, April 30th\"\n    date: \"2026-04-30\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - title: \"Registration, Coffee, Light Snacks\"\n            description: |-\n              YMI Cultural Center - 39 S Market St, Asheville, NC 28801\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Welcome, Day 1\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Open Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Mystery Activity\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Closing, Day 1\n\n      - start_time: \"17:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - Open Dinner\n\n      - start_time: \"19:00\"\n        end_time: \"21:00\"\n        slots: 1\n        items:\n          - title: \"Roundtable Discussion\"\n            description: |-\n              YMI Cultural Center - 39 S Market St, Asheville, NC 28801\n\n  - name: \"Friday, May 1st\"\n    date: \"2026-05-01\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - title: \"Coffee, Light Snacks\"\n            description: |-\n              YMI Cultural Center - 39 S Market St, Asheville, NC 28801\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Welcome, Day 2\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Open Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Closing, Day 2\n\n      - start_time: \"17:30\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - Open Dinner\n\n      - start_time: \"20:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - title: \"Afterparty\"\n            description: |-\n              Burial - South Slope - 40 Collier Ave, Asheville, NC 28801\n\n  - name: \"Saturday, May 2nd\"\n    date: \"2026-05-02\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - title: \"Hack Day\"\n            description: |-\n              Hack on projects, or just come and hang out! YMI Cultural Center - 39 S Market St, Asheville, NC 28801\n\n      - start_time: \"17:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - title: \"Informal Dinner\"\n            description: |-\n              Asheville Pizza - South Slope - 77 Coxe Ave, Asheville, NC 28801\n\ntracks: []\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2026/sponsors.yml",
    "content": "# docs/ADDING_SPONSORS.md\n# Do not remove todo until event is over and all sponsors are added.\n# TODO: Add missing sponsors.\n---\n- tiers:\n    - name: \"Ruby\"\n      level: 1\n      sponsors:\n        - name: \"Typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"typesense\"\n\n    - name: \"Sapphire\"\n      level: 2\n      sponsors:\n        - name: \"Anonymous\"\n          website: \"https://blueridgeruby.com/#sponsors\"\n          slug: \"anonymous\"\n          logo_url: \"https://blueridgeruby.com/images/sponsors/anonymous.svg\"\n\n    - name: \"Emerald\"\n      level: 3\n      sponsors:\n        - name: \"FastRuby.io\"\n          website: \"https://www.fastruby.io/\"\n          slug: \"fastruby-io\"\n\n        - name: \"Judoscale\"\n          website: \"https://judoscale.com/\"\n          slug: \"judoscale\"\n          logo_url: \"https://blueridgeruby.com/images/sponsors/judoscale.svg\"\n\n        - name: \"Scout Monitoring\"\n          website: \"https://www.scoutapm.com\"\n          slug: \"scout-monitoring\"\n          logo_url: \"https://blueridgeruby.com/images/sponsors/scout_monitoring.svg\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2026/venue.yml",
    "content": "---\nname: \"YMI Cultural Center\"\ndescription: |-\n  The historic YMI Cultural Center is located in downtown Asheville, within a block or two of many nearby restaurants, hotels, cafes, and more!\naddress:\n  street: \"39 S Market St\"\n  city: \"Asheville\"\n  region: \"NC\"\n  postal_code: \"28801\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"39 S Market St, Asheville, NC 28801\"\ncoordinates:\n  latitude: 35.593957\n  longitude: -82.550029\nmaps:\n  google: \"https://maps.app.goo.gl/9eQvbRbA4XFXKa3r9\"\nhotels:\n  - name: \"Aloft Asheville Downtown\"\n    description: |-\n      3-minute walk from venue, nice and close, on-site parking for $17/day\n    address:\n      street: \"51 Biltmore Avenue\"\n      city: \"Asheville\"\n      region: \"North Carolina\"\n      postal_code: \"28801\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"51 Biltmore Ave, Asheville, NC 28801\"\n    distance: \"3 minute walk\"\n    url: \"https://www.marriott.com/en-us/hotels/avlal-aloft-asheville-downtown/overview/\"\n    coordinates:\n      latitude: 35.593074636003905\n      longitude: -82.55137981979105\n    maps:\n      google: \"https://maps.app.goo.gl/5NPCM1mpnQXgdyee9\"\n  - name: \"Renaissance Asheville Downtown\"\n    description: |-\n      7-minute walk from venue, higher capacity, on-site parking for $25/day\n    address:\n      street: \"31 Woodfin Street\"\n      city: \"Asheville\"\n      region: \"North Carolina\"\n      postal_code: \"28801\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"31 Woodfin St, Asheville, NC 28801\"\n    distance: \"7 minute walk\"\n    url: \"https://www.marriott.com/en-us/hotels/avlbr-renaissance-asheville-downtown-hotel/overview/\"\n    coordinates:\n      latitude: 35.59768665477134\n      longitude: -82.55003306212012\n    maps:\n      google: \"https://maps.app.goo.gl/RHVYhZeUqRa3EWbWA\"\n  - name: \"Downtown Inn and Suites\"\n    description: |-\n      11-minute walk from venue, closest tight-budget option. Note: They have a no-locals, no-extended stay policy and may contact you for verification. Just tell them you are attending the Blue Ridge Ruby conference.\n    address:\n      street: \"120 Patton Avenue\"\n      city: \"Asheville\"\n      region: \"North Carolina\"\n      postal_code: \"28801\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"120 Patton Ave, Asheville, NC 28801\"\n    distance: \"11 minute walk\"\n    url: \"https://downtowninnandsuites.com/\"\n    coordinates:\n      latitude: 35.59404110688292\n      longitude: -82.5566723026017\n    maps:\n      google: \"https://maps.app.goo.gl/qKBkhaGAUV2kHSB66\"\n  - name: \"Lazy Tiger Hostel\"\n    description: |-\n      10-minute drive from venue, unique hostel experience, good if traveling by car. Note: They are offering a 10% discount with coupon code BLUERIDGERUBY.\n    address:\n      street: \"104 Weaverville Road\"\n      city: \"Asheville\"\n      region: \"North Carolina\"\n      postal_code: \"28804\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"104 Weaverville Rd, Asheville, NC 28804\"\n    distance: \"10 minute drive\"\n    url: \"https://lazytigerhostel.com/\"\n    coordinates:\n      latitude: 35.64318018651534\n      longitude: -82.57987264417696\n    maps:\n      google: \"https://maps.app.goo.gl/qKQxQ6TBNs3wqTD48\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/blue-ridge-ruby-2026/videos.yml",
    "content": "# docs/ADDING_UNPUBLISHED_TALKS.md\n# docs/ADDING_VIDEOS.md\n---\n# Day 1 - Thursday, April 30th\n- id: \"john-athayde-blue-ridge-ruby-2026\"\n  title: \"Learning from Permaculture: Sustainable Software Development\"\n  description: |-\n    I've farmed with permaculture since 2013 and designed & built software for 20+ years. Turns out the same principles apply: observe before acting, produce no waste, value the margins. Let's explore what the garden can teach us about building software that lasts.\n  date: \"2026-04-30\"\n  speakers:\n    - John Athayde\n  video_provider: \"scheduled\"\n  video_id: \"john-athayde-blue-ridge-ruby-2026\"\n\n- id: \"joel-quenneville-blue-ridge-ruby-2026\"\n  title: \"State is the First Decision You Never Made\"\n  description: |-\n    Web apps are built on a paradox: stateful experiences over a stateless web. State decisions permeate the stack, yet are often made implicitly while teams debate frameworks, APIs, or architecture. This talk shows how those decisions shape real features and how to build *with* the web platform instead of fighting it.\n  date: \"2026-04-30\"\n  speakers:\n    - Joël Quenneville\n  video_provider: \"scheduled\"\n  video_id: \"joel-quenneville-blue-ridge-ruby-2026\"\n\n- id: \"ifat-ribon-blue-ridge-ruby-2026\"\n  title: \"Yes, &…: Ruby's Secret Talent for Improvisation\"\n  description: |-\n    Did you know Ruby is an improviser? With its ability to take blocks at will, Ruby lets methods pass the conversation to blocks that happily accept what's given and add to it. This talk explores blocks, procs, and lambdas as Ruby's way of saying \"Yes, and…\", with playful examples, surprising behavior, and joyful chaos along the way.\n  date: \"2026-04-30\"\n  speakers:\n    - Ifat Ribon\n  video_provider: \"scheduled\"\n  video_id: \"ifat-ribon-blue-ridge-ruby-2026\"\n\n- id: \"annie-kiley-blue-ridge-ruby-2026\"\n  title: \"How To Finish What You Start: Lessons From Actually Shipping a Big Refactor\"\n  description: |-\n    Every developer has at least one major refactor they would love to make happen. Somehow, these projects are tough to start and even tougher to finish. My team recently completed a major overhaul of our permissions and access system, and it felt great to actually get one of these big refactors done. In this talk, I'll share the practical lessons that helped us ship it without breaking things or losing momentum, so you can finish your next big change too.\n  date: \"2026-04-30\"\n  speakers:\n    - Annie Kiley\n  video_provider: \"scheduled\"\n  video_id: \"annie-kiley-blue-ridge-ruby-2026\"\n\n- id: \"kevin-murphy-blue-ridge-ruby-2026\"\n  title: \"InstiLLMent of Successful Practices in an Agentic World\"\n  description: |-\n    Congrats on joining Hours Unlimited. The Math and Numbers team is excited to have you join us on our journey to redefine the importance of numerals. This introductory session will provide tips and tricks for best interacting with powerfuLLMachine, the next-level platform we use to unlock productivity and effectiveness.\n  date: \"2026-04-30\"\n  speakers:\n    - Kevin Murphy\n  video_provider: \"scheduled\"\n  video_id: \"kevin-murphy-blue-ridge-ruby-2026\"\n\n# Day 2 - Friday, May 1st\n- id: \"brooke-kuhlmann-blue-ridge-ruby-2026\"\n  title: \"Terminus: A Hanami + htmx web application for e-ink devices\"\n  description: |-\n    Terminus is an open source web app built on Ruby, Hanami and htmx for displaying screens on e-ink devices. You'll learn about the design, architecture, and patterns used. Even better, the entire presentation is for e-ink displays (passed to the audience) so you can experience this in real-time!\n  date: \"2026-05-01\"\n  speakers:\n    - Brooke Kuhlmann\n  video_provider: \"scheduled\"\n  video_id: \"brooke-kuhlmann-blue-ridge-ruby-2026\"\n\n- id: \"rachael-wright-munn-blue-ridge-ruby-2026\"\n  title: \"Your First Open-Source Contribution\"\n  description: |-\n    Is open-source intimidating? Are you nervous about your code being rejected by the maintainers? Or maybe you just don't know where to start. Let's talk about it. Let's talk about the feelings. Let's talk about the practices. Let's get you that first open-source PR.\n  date: \"2026-05-01\"\n  speakers:\n    - Rachael Wright-Munn\n  video_provider: \"scheduled\"\n  video_id: \"rachael-wright-munn-blue-ridge-ruby-2026\"\n\n- id: \"david-paluy-blue-ridge-ruby-2026\"\n  title: \"LLM Telemetry as a First-Class Rails Concern\"\n  description: |-\n    Your LLM calls deserve the same observability as your database queries. This talk shows how to architect telemetry as a domain concern—not scattered logger calls—so you can review prompts, track costs, and debug production AI features like a proper Rails developer.\n  date: \"2026-05-01\"\n  speakers:\n    - David Paluy\n  video_provider: \"scheduled\"\n  video_id: \"david-paluy-blue-ridge-ruby-2026\"\n\n- id: \"christine-seeman-blue-ridge-ruby-2026\"\n  title: \"Optimize Your Mindset (Without Overclocking)\"\n  description: |-\n    A playful, research-backed guide to better focus, less stress, and habits that stick. Learn four practical techniques you can use immediately to improve your workday and your life. No woo, just tools that help busy developers thrive.\n  date: \"2026-05-01\"\n  speakers:\n    - Christine Seeman\n  video_provider: \"scheduled\"\n  video_id: \"christine-seeman-blue-ridge-ruby-2026\"\n\n- id: \"thomas-cannon-blue-ridge-ruby-2026\"\n  title: \"5 ways to invest in yourself for the long haul\"\n  description: |-\n    Now, more than ever, it's crucial to keep honing your craft. Rather than Herculean efforts every time you need to level up, change jobs, or share your work; let's build a breadcrumb trail! I'll talk about 5 tiny, everyday things that will reap immediate benefits and compound your self-investment.\n  date: \"2026-05-01\"\n  speakers:\n    - Thomas Cannon\n  video_provider: \"scheduled\"\n  video_id: \"thomas-cannon-blue-ridge-ruby-2026\"\n"
  },
  {
    "path": "data/blue-ridge-ruby/series.yml",
    "content": "---\nname: \"Blue Ridge Ruby\"\nwebsite: \"https://blueridgeruby.com\"\ntwitter: \"blueridgeruby\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Blue Ridge Ruby\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/bluegrass-ruby/bluegrass-ruby/event.yml",
    "content": "---\nid: \"bluegrass-ruby-meetup\"\ntitle: \"Bluegrass Ruby Meetup\"\nkind: \"meetup\"\nlocation: \"Lexington, KY, United States\"\ndescription: \"\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#CF2233\"\ncoordinates:\n  latitude: 38.0389091\n  longitude: -84.5152662\n"
  },
  {
    "path": "data/bluegrass-ruby/bluegrass-ruby/videos.yml",
    "content": "---\n- id: \"bluegrass-ruby-meetup-june-2025\"\n  title: \"Bluegrass Ruby Meetup June 2025\"\n  raw_title: \"Bluegrass Ruby Meetup June 2025\"\n  event_name: \"Bluegrass Ruby Meetup June 2025\"\n  date: \"2025-06-03\"\n  announced_at: \"2025-05-24 18:53:00 UTC\"\n  description: |-\n    Marli Baumann will provide a glimpse into the Rails and Phoenix apps at Baumann Paper Company.\n\n    https://www.meetup.com/the-bluegrass-developers-guild/events/308026901\n    https://guild.host/events/bluegrass-ruby-june-afzdf5\n  video_provider: \"children\"\n  video_id: \"bluegrass-ruby-meetup-june-2025\"\n  talks:\n    - title: \"Travel back in time to Rails 2.3.8, mixed with Phoenix LiveView.\"\n      date: \"2025-06-03\"\n      announced_at: \"2025-05-24 18:53:00 UTC\"\n      video_provider: \"scheduled\"\n      id: \"marli-baumann-bluegrass-ruby-meetup-june-2025\"\n      video_id: \"marli-baumann-bluegrass-ruby-meetup-june-2025\"\n      description: |-\n        Marli Baumann will provide a glimpse into the Rails and Phoenix apps at Baumann Paper Company.\n      speakers:\n        - Marli Baumann\n"
  },
  {
    "path": "data/bluegrass-ruby/series.yml",
    "content": "---\nname: \"Bluegrass Ruby Users Group\"\nwebsite: \"https://bluegrassruby.club\"\nmeetup: \"https://www.meetup.com/the-bluegrass-developers-guild/\"\nguild: \"https://guild.host/bluegrass-ruby\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"US\"\nlanguage: \"english\"\n"
  },
  {
    "path": "data/bridgetownconf/bridgetownconf-2022/event.yml",
    "content": "---\nid: \"bridgetownconf-2022\"\ntitle: \"BridgetownConf 2022\"\ndescription: |-\n  BridgetownConf 2022 is a free online conference for Ruby & Web developers using the Bridgetown framework to build modern, fast, ergonomic production deployments.\nkind: \"conference\"\nlocation: \"online\"\nstart_date: \"2022-11-07\"\nend_date: \"2022-11-07\"\nwebsite: \"https://www.bridgetownconf.rocks\"\ncoordinates: false\nbanner_background: \"#5B21B6\"\nfeatured_background: \"#5B21B6\"\nfeatured_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/bridgetownconf/bridgetownconf-2022/videos.yml",
    "content": "---\n# Website: https://www.bridgetownconf.rocks\n# Schedule: https://www.bridgetownconf.rocks\n\n- id: \"jared-white-bridgetownconf-2022-keynote\"\n  title: \"Keynote: What's New in Bridgetown 1.2, the Plugin Ecosystem, and Content Publishing\"\n  raw_title: \"Keynote: What's New in Bridgetown 1.2, the Plugin Ecosystem, and Content Publishing\"\n  kind: \"keynote\"\n  speakers:\n    - Jared White\n  event_name: \"BridgetownConf 2022\"\n  date: \"2022-11-07\"\n  video_provider: \"mp4\"\n  video_id: \"https://vz-33332009-cdc.b-cdn.net/48c73987-2a70-4374-828e-19803bffaa3c/play_720p.mp4\"\n  description: |-\n    With three major releases of Bridgetown rounding out 2022, it's been a busy year! In the opening keynote of BridgetownConf, you'll learn what's new in the latest version of Bridgetown, including the all-new initialization and configuration system which will enable a new class of plugin. You'll also learn about upcoming milestones in the plugin ecosystem and how Bridgetown can power your online publishing hub.\n  slides_url: \"https://btconf2022-keynote.onrender.com\"\n\n- id: \"andrew-mason-bridgetownconf-2022\"\n  title: \"Learn Enough Bridgetown to be Dangerous\"\n  raw_title: \"Learn Enough Bridgetown to be Dangerous\"\n  speakers:\n    - Andrew Mason\n  event_name: \"BridgetownConf 2022\"\n  date: \"2022-11-07\"\n  video_provider: \"mp4\"\n  video_id: \"https://vz-33332009-cdc.b-cdn.net/ffc16707-5e4d-4e47-917a-20860b3ca7b8/play_720p.mp4\"\n  description: |-\n    Bridgetown is the future of building static and progressive websites with Ruby, and the future is now! We will look at the current landscape of static site generators and how the industry is evolving as Server Side Rendering and Dynamic Rendering become more popular. We will also look at other Ruby based static site generators to see what the other options are and why you should choose Bridgetown.\n\n- id: \"ayush-newatia-bridgetownconf-2022\"\n  title: \"Content Modeling & API Integrations for the Win\"\n  raw_title: \"Content Modeling & API Integrations for the Win\"\n  speakers:\n    - Ayush Newatia\n  event_name: \"BridgetownConf 2022\"\n  date: \"2022-11-07\"\n  video_provider: \"mp4\"\n  video_id: \"https://vz-33332009-cdc.b-cdn.net/3afa6b90-288f-47c4-ad1e-b5a1a4aee363/play_720p.mp4\"\n  description: |-\n    Bridgetown shines as a static site generator, but it's so much more than that. In this talk we'll discuss the content engine which underpins Bridgetown, how to customise it, and add a sprinkle of dynamic interaction.\n  additional_resources:\n    - name: \"Demo Repo\"\n      url: \"https://github.com/ayushn21/bridgetownconf-2022-demo\"\n      type: \"repo\"\n\n- id: \"core-team-qa-bridgetownconf-2022\"\n  title: \"Core Team Q & A on Open Source\"\n  raw_title: \"Core Team Q & A on Open Source\"\n  speakers:\n    - Jared White\n    - Ayush Newatia\n    - Adrian Valenzuela\n  event_name: \"BridgetownConf 2022\"\n  date: \"2022-11-07\"\n  video_provider: \"mp4\"\n  video_id: \"https://vz-33332009-cdc.b-cdn.net/fbe14e93-48e7-4c88-a92c-ffad40813edc/play_720p.mp4\"\n  description: |-\n    How does an open source project begin? How do you contribute to an open source project? How do you overcome imposter syndrome? What does it mean to be part of Bridgetown's \"core team\"? These questions and more will be answered in this panel.\n\n- id: \"adrian-valenzuela-bridgetownconf-2022\"\n  title: \"Setting Up a Bridgetown Blog with Prismic Headless CMS\"\n  raw_title: \"Setting Up a Bridgetown Blog with Prismic Headless CMS\"\n  speakers:\n    - Adrian Valenzuela\n  event_name: \"BridgetownConf 2022\"\n  date: \"2022-11-07\"\n  video_provider: \"mp4\"\n  video_id: \"https://vz-33332009-cdc.b-cdn.net/433cf16b-5145-4317-8108-d7975dc60611/play_720p.mp4\"\n  description: |-\n    In this talk we will go over how Bridgetown can be a great solution to offer your clients for their company websites and how it can be expanded to a blog using Prismic CMS using the official Bridgetown-Prismic plugin.\n  additional_resources:\n    - name: \"Blog Post\"\n      url: \"https://www.adrianvalenz.com/code/setting-up-a-bridgetown-blog-with-prismics-headless-cms/\"\n      type: \"blog\"\n    - name: \"Demo Site Using Prismic\"\n      url: \"https://italianbistro.onrender.com/\"\n      type: \"link\"\n    - name: \"Source Code\"\n      url: \"https://github.com/adrianvalenz/italianbistro/\"\n      type: \"repo\"\n\n- id: \"jared-white-bridgetownconf-2022-database\"\n  title: \"Database-Driven Apps with Bridgetown, Roda, Hotwire Turbo, and Lifeform\"\n  raw_title: \"Database-Driven Apps with Bridgetown, Roda, Hotwire Turbo, and Lifeform\"\n  speakers:\n    - Jared White\n  event_name: \"BridgetownConf 2022\"\n  date: \"2022-11-07\"\n  video_provider: \"mp4\"\n  video_id: \"https://vz-33332009-cdc.b-cdn.net/0ecf3086-f24f-40c7-967e-62be6b8c6b9d/play_720p.mp4\"\n  description: |-\n    In this talk, you'll see a demonstration of how to pull Active Record into a Bridgetown site to handle database access through domain models, how to write dynamic endpoints using Roda, how to provide advanced user interactivity using Turbo, and how to render forms declaratively using objects powered by the new gem Lifeform.\n  slides_url: \"https://btconf2022-crud.onrender.com\"\n  additional_resources:\n    - name: \"Demo Repo\"\n      url: \"https://github.com/jaredcwhite/bt_crud_movies_demo\"\n      type: \"repo\"\n"
  },
  {
    "path": "data/bridgetownconf/series.yml",
    "content": "---\nname: \"BridgetownConf\"\nwebsite: \"https://www.bridgetownconf.rocks\"\nkind: \"conference\"\nfrequency: \"irregular\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_name: \"\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2014/event.yml",
    "content": "---\nid: \"brightonruby-2014\"\ntitle: \"Brighton Ruby 2014\"\nlocation: \"Brighton, UK\"\ndescription: \"\"\npublished_at: \"2014-07-21\"\nstart_date: \"2014-07-21\"\nend_date: \"2014-07-21\"\nkind: \"conference\"\nyear: 2014\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 50.8229402\n  longitude: -0.1362672\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2014/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n# Website: https://brightonruby.com/2014/\n\n[]\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2015/event.yml",
    "content": "---\nid: \"brightonruby-2015\"\ntitle: \"Brighton Ruby 2015\"\nlocation: \"Brighton, UK\"\ndescription: \"\"\npublished_at: \"2015-07-20\"\nstart_date: \"2015-07-20\"\nend_date: \"2015-07-20\"\nkind: \"conference\"\nyear: 2015\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 50.8229402\n  longitude: -0.1362672\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2015/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2015/videos.yml",
    "content": "---\n# Website: https://brightonruby.com/2015/\n# Schedule: https://brightonruby.com/2015/\n\n- id: \"sarah-making-software-fun\"\n  title: \"Making Software Fun\"\n  raw_title: \"Making Software Fun\"\n  speakers:\n    - Sarah Allen\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/making-software-fun-sarah-allen\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/sarah-making-software-fun.mp4\"\n  description: |-\n    Sarah walks us through the use of joy when we build the things we build.\n\n\n          Write code, connect pixels and speaks truth to make change. Founder of Bridge Foundry, Mightyverse. Works on the Firebase team at Google.\n\n- id: \"luca-lotus-rb-hanami-and-the-future-of-ruby\"\n  title: \"Lotus.rb (Hanami) and the Future of Ruby\"\n  raw_title: \"Lotus.rb (Hanami) and the Future of Ruby\"\n  speakers:\n    - Luca Guidi\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/lotus-hanami-and-the-future-of-ruby-luca-guidi\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/luca-lotus-rb-hanami-and-the-future-of-ruby.mp4\"\n  description: |-\n    The creator of Hanami (formally Lotus.rb) talks through his thoughts on the Ruby ecosystem.\n\n- id: \"elle-just-in-time\"\n  title: \"Just in Time\"\n  raw_title: \"Just in Time\"\n  speakers:\n    - Elle Meredith\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/just-in-time-elle-meredith\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/elle-just-in-time.mp4\"\n  description: |-\n    A terrific talk on time & zones in Ruby from one of the organisers of [Railscamp US](https://east.railscamp.us).\n\n- id: \"sam-do-you-need-that-gem\"\n  title: \"Do You Need That Gem?\"\n  raw_title: \"Do You Need That Gem?\"\n  speakers:\n    - Sam Phippen\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/do-you-need-that-gem-sam-phippen\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/sam-do-you-need-that-gem.mp4\"\n  description: |-\n    Sam discusses the problems and advantages of managing dependancies in Ruby.\n\n- id: \"lightning-talks-brighton-ruby-2016\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/lightning-talks\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/lightning-talks-brighton-ruby-2016.mp4\"\n  description: |-\n    A wonderful selection of five minute nuggets from the Brighton Ruby call for proposals. Some experienced. Some first timers. All great.\n  talks:\n    - title: \"Lightning Talk: Ruby Issues Newsletter\"\n      start_cue: \"00:05\"\n      end_cue: \"03:55\"\n      id: \"sonja-heinen-lighting-talk-brighton-ruby-2015\"\n      video_id: \"sonja-heinen-lighting-talk-brighton-ruby-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Sonja Heinen # https://twitter.com/sonjaheinen\n\n    - title: \"Lightning Talk: Sorting, moving, sharing and caching in complex tree structure\"\n      start_cue: \"04:10\"\n      end_cue: \"09:53\"\n      id: \"olga-scott-lighting-talk-brighton-ruby-2015\"\n      video_id: \"olga-scott-lighting-talk-brighton-ruby-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Olga Scott # https://twitter.com/olga_scott\n\n    - title: \"Lightning Talk: How to onboard Junior Developers well\"\n      start_cue: \"10:06\"\n      end_cue: \"15:27\"\n      id: \"tatiana-soukiassian-lighting-talk-brighton-ruby-2015\"\n      video_id: \"tatiana-soukiassian-lighting-talk-brighton-ruby-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Tatiana Soukiassian # https://twitter.com/binaryberry\n\n    - title: \"Lightning Talk: Continuous Delivery\"\n      start_cue: \"15:42\"\n      end_cue: \"20:18\"\n      id: \"robbie-clutton-lighting-talk-brighton-ruby-2015\"\n      video_id: \"robbie-clutton-lighting-talk-brighton-ruby-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Robbie Clutton # https://twitter.com/robb1e\n\n    - title: \"Lightning Talk: Ruby - The Weird Bits\"\n      start_cue: \"20:34\"\n      end_cue: \"26:42\"\n      id: \"alex-sunderland-lighting-talk-brighton-ruby-2015\"\n      video_id: \"alex-sunderland-lighting-talk-brighton-ruby-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Alex Sunderland # https://twitter.com/felltir\n\n- id: \"rob-mini-munging-the-joy-of-small-data\"\n  title: \"Mini-munging: The Joy of Small Data\"\n  raw_title: \"Mini-munging: The Joy of Small Data\"\n  speakers:\n    - Rob Miller\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/mini-munging-the-joy-of-small-data-rob-miller\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/rob-mini-munging-the-joy-of-small-data.mp4\"\n  description: |-\n    Why use R or Hadoop when it turns out you can use the marvels of the UNIX command line?\n\n- id: \"nadia-games-in-the-clouds\"\n  title: \"Playing Games in the Clouds\"\n  raw_title: \"Playing Games in the Clouds\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/playing-games-in-the-clouds-nadia-odunayo\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/nadia-games-in-the-clouds.mp4\"\n  description: |-\n    How can game theory help us solve practical cloud computing problems?\n\n\n          Nadia co-founded Ignition Works in order to find fun and sustainable ways to build worthwhile software products. She has taught good engineering practices through pair programming at Pivotal Labs and Pivotal Cloud Foundry. She originally learnt to code at Makers Academy and she runs the Ruby Book Club podcast in her spare time.\n\n- id: \"tadej-command-and-conquer-red-alert\"\n  title: \"Command & Conquer: Red Alert\"\n  raw_title: \"Command & Conquer: Red Alert\"\n  speakers:\n    - Tadej Murovec\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/command-and-conquer-red-alert-tadej-murovec\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/tadej-command-and-conquer-red-alert.mp4\"\n  description: |-\n    Constant error messages? Paged at 2AM for non-essential problems? Let Tadej explain a path to sanity and prioritising _real_ problems over false alarms.\n\n\n          Passionate Ruby developer, a g33k, indie music lover, petrol–head.\n\n- id: \"kinsey-the-struggle-to-stay-technical\"\n  title: \"The Struggle to Stay Technical\"\n  raw_title: \"The Struggle to Stay Technical\"\n  speakers:\n    - Kinsey Ann Durham\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/the-struggle-to-stay-technical-kinsey-ann-durham\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/kinsey-the-struggle-to-stay-technical.mp4\"\n  description: |-\n    What is tech's gender problem? Why do women seem to 'fall out' of our profession? A thought provoking talk.\n\n\n          Software Engineer at GoSpotCheck, co-founder [Kubmo](http://kubmo.org), Chair of Bridge Foundry board, mentor @trybloc. Addicted to fly fishing and her dog.\n\n- id: \"just-a-ruby-minute-2015\"\n  title: \"Gameshow: Just a Ruby Minute\"\n  raw_title: \"Just a Ruby Minute\"\n  speakers:\n    - Andrew Faraday\n    - Phil Nash\n    - Rob Miller\n    - Kinsey Ann Durham\n    - Sam Phippen\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/just-a-ruby-minute-andrew-faraday\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/just-a-ruby-minute-2015.mp4\"\n  description: |-\n    The premiere of the Brighton Ruby gameshow. Hosted by Andrew Faraday.\n\n\n          A tribute to the Radio 4 original, created with Playstation controllers and noises from the radio.\n\n- id: \"avdi-the-soul-of-software\"\n  title: \"The Soul of Software\"\n  raw_title: \"The Soul of Software\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"Brighton Ruby 2015\"\n  date: \"2015-07-20\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2015/the-soul-of-software-avdi-grimm\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2015/avdi-the-soul-of-software.mp4\"\n  description: |-\n    The conference was rounded off by a thoughtful treatise on where the Ruby community is and how we're building software.\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2016/event.yml",
    "content": "---\nid: \"brightonruby-2016\"\ntitle: \"Brighton Ruby 2016\"\nlocation: \"Brighton, UK\"\ndescription: \"\"\npublished_at: \"2016-07-08\"\nstart_date: \"2016-07-08\"\nend_date: \"2016-07-08\"\nkind: \"conference\"\nyear: 2016\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 50.8229402\n  longitude: -0.1362672\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2016/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2016/videos.yml",
    "content": "---\n# Website: https://brightonruby.com/2016/\n# Schedule: https://brightonruby.com/2016/\n\n- id: \"eileen-security-is-broken-understanding-common-vulnerabilities\"\n  title: \"Security is Broken\"\n  raw_title: \"Security is Broken\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/security-is-broken-eileen-uchitelle\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/eileen-security-is-broken-understanding-common-vulnerabilities.mp4\"\n  description: |-\n    The Internet is built on technology that was never meant to work together. Basic features in seemingly simple and innocuous technologies, such as XML, resulted in these technologies being insecure.\n\n    In this session we’ll talk about how attackers exploit well known vulnerabilities like XSS, XXE, and CSRF and how to make more secure software by avoiding similar decisions that resulted in these exploits.\n\n\n          Staff Engineer on the Ruby Architecture Team at GitHub and a member of the Rails Core team. She’s an avid contributor to open source focusing on the Ruby on Rails framework and its dependencies. Eileen is passionate about scalability, performance, and making open source communities more sustainable and welcoming.\n\n- id: \"john-the-point-of-objects\"\n  title: \"The Point of Objects\"\n  raw_title: \"The Point of Objects\"\n  speakers:\n    - John Cinnamond\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/the-point-of-objects-john-cinnamond\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/john-the-point-of-objects.mp4\"\n  description: |-\n    Objects are abstractions and we should be suspicious of them. Not only are abstractions hard, but bad abstractions are harmful to programming. So why use objects? Why not just stick to the simpler and more natural world of procedural programming?\n\n    In this talk we take some real world ruby code written in a procedural style and refactor it to an Object Oriented style. Along the way we’ll see how this changes the we think about programming, and how this gives us better tools for tackling the inevitable complexity that will creep into your project.\n\n- id: \"sam-what-is-processor\"\n  title: \"What is Processor?\"\n  raw_title: \"What is Processor?\"\n  speakers:\n    - Sam Phippen\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/what-is-processor-sam-phippen\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/sam-what-is-processor.mp4\"\n  description: |-\n    Sometimes, writing Rails apps is awful. Do you know what’s nearly always more awful? Hand-rolling assembly. Ruby lets us not think about how the processor works, but we’re programmers. We’re uniquely positioned to intellectually appreciate the wonderful, complex, engineering that goes into a processor.\n\n    In this talk, you’ll learn a little more about what it means for Ruby to be an “interpreted” language, how a processor executes programs, and what magical tricks processor designers use to make our programs go faster with every generation. If you’ve ever written a Ruby program, and understand that a computer has a processor in it, this talk is probably for you.\n\n- id: \"sara-the-function-of-bias\"\n  title: \"The Function of Bias\"\n  raw_title: \"The Function of Bias\"\n  speakers:\n    - Sara Simon\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/the-function-of-bias-sara-simon\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/sara-the-function-of-bias.mp4\"\n  description: |-\n    This is a talk about the process and product of code. It’s a talk about the open source community, about maintenance and tests. About starting projects from existing repositories, using existing APIs, and copy/pasting existing lines of code as that big, scary word we call plagiarism looms over a 21st century newsroom.\n\n    It’s a talk about building something the right way under deadline. About humans who write algorithms that determine the news. It’s about bias and about the function it serves. About the privileges and perspectives that programmers bring to their code and about the privileges and perspectives that journalists bring to their stories.\n\n    Prefer to read, rather than watch? [The Function of Bias](https://medium.com/@sarambsimon/the-function-of-bias-b92fc968fac1#.c5ch46ws3)\n  additional_resources:\n    - name: \"Blog Post\"\n      type: \"blog\"\n      url: \"https://medium.com/@sarambsimon/the-function-of-bias-b92fc968fac1#.c5ch46ws3\"\n\n- id: \"emily-do-it-yourself-testing\"\n  title: \"Do-it-Yourself Testing\"\n  raw_title: \"Do-it-Yourself Testing\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/do-it-yourself-testing-emily-stolfo\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/emily-do-it-yourself-testing.mp4\"\n  description: |-\n    The drivers team at MongoDB focused over the last year on conforming to common APIs and algorithms but we needed a shared way to test our 9 drivers. We therefore ended up building our own testing DSL, REST service, and individual test frameworks to validate our consistency.\n\n    Using these common tests and the Ruby driver’s test suite as examples, this talk shows you how they designed and built a custom testing framework and perhaps tempt you to do the same.\n\n- id: \"just-a-ruby-minute-2016\"\n  title: \"Gameshow: Just a Ruby Minute\"\n  raw_title: \"Just a Ruby Minute\"\n  speakers:\n    - Andrew Faraday\n    - Eileen M. Uchitelle\n    - Sam Phippen\n    - Britni Alexander\n    - Andy Croll\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/just-a-ruby-minute-andrew-faraday\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/just-a-ruby-minute-2016.mp4\"\n  description:\n    \"Just a Minute, the venerable BBC Radio 4 panel game institution, is given another Brighton Ruby run out with your host Andrew Faraday.\n\n\n    With panelists [@eileencodes](https://twitter.com/eileencodes), [@samphippen](https://twitter.com/samphippen), [@TwitniTheGirl](https://twitter.com/TwitniTheGirl) &\n    [@andycroll](https://twitter.com/andycroll).\n\n\n\n    \\      A tribute to the Radio 4 original, created with Playstation controllers and noises from the radio.\n\n    \\    \"\n\n- id: \"andy-five-minutes-with-elixir\"\n  title: \"Lightning Talk: Five Minutes with Elixir\"\n  raw_title: \"Five Minutes with Elixir\"\n  speakers:\n    - Andy Pike\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/five-minutes-with-elixir-andy-pike\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/andy-five-minutes-with-elixir.mp4\"\n  description: |-\n    We love Ruby but it has it’s problems. Concurrency, performance, fault tolerant being some of them. Elixir is a functional language built on the Erlang VM which is now around 30 years old. It was built to solve these problems for telephone networks.\n\n    When was the last time your phone network went down for “Scheduled Maintenance” or went down due to issues? I certainly can’t remember a single occasion. With Elixir we now have an expressive language like we have with Ruby but now with the power of the Erlang VM. This talk will show you a super brief look at Elixir with the hope that you might give it a try.\n\n    Contains mad rhymes.\n\n- id: \"jay-craft-and-cathedrals\"\n  title: \"Lightning Talk: Craft & Cathedrals\"\n  raw_title: \"Craft & Cathedrals\"\n  speakers:\n    - Jay Caines-Gooby\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/craft-and-cathedrals-jay-caines-gooby\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/jay-craft-and-cathedrals.mp4\"\n  description: |-\n    Historical craftsman's education, skills, processes and products, can inform our processes and outcomes as modern-day software developers.\n\n    Actually cathedrals are really big-balls of mud and that’s totally OK\n\n    Prefer to read, rather than watch? [Craft & Cathedrals](https://medium.com/@jaygooby/craft-and-cathedrals-e97460216e29#.t178yk48m)\n  additional_resources:\n    - name: \"Blog Post\"\n      type: \"blog\"\n      url: \"https://medium.com/@jaygooby/craft-and-cathedrals-e97460216e29#.t178yk48m\"\n\n- id: \"dot-5-wtfs-in-6-locs\"\n  title: \"Lightning Talk: Five WTFs in Six LOCs\"\n  raw_title: \"Five WTFs in Six LOCs\"\n  speakers:\n    - Dot Wingrove\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/five-wtfs-in-six-lines-of-code-dot-wingrove\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/dot-5-wtfs-in-6-locs.mp4\"\n  description: |-\n    I'd love to tell you about the Ruby in this talk, but I still don’t understand it.\n\n    One of my personal highlights of the day.\n\n\n          Co-organiser of @CodebarBrighton, studying maths with @OpenUniversity, humum to @morty_macgrove\n\n- id: \"phil-puppies-and-two-factor-auth\"\n  title: \"Lightning Talk: Puppies & Two Factor Authentication\"\n  raw_title: \"Puppies & Two Factor Authentication\"\n  speakers:\n    - Phil Nash\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/puppies-and-two-factor-authentication-phil-nash\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/phil-puppies-and-two-factor-auth.mp4\"\n  description: |-\n    Puppies need to be secure and safe, Phil shows you how you can get 2-factor authentication done in two minutes.\n\n- id: \"neil-the-heroku-flow\"\n  title: \"Lightning Talk: The Heroku Flow\"\n  raw_title: \"The Heroku Flow\"\n  speakers:\n    - Neil Middleton\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/the-heroku-flow-neil-middleton\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/neil-the-heroku-flow.mp4\"\n  description: |-\n    Over the last few years Heroku has developed and refined a process and set of tools called the ‘Heroku Flow’. This process aims to streamlined code development/deploy and review down to the very basics, opening up more time for you to worry about your code.\n\n- id: \"sean-rails-5-features-you-haven’t-heard-about\"\n  title: \"Rails 5 Features You Haven’t Heard About\"\n  raw_title: \"Rails 5 Features You Haven’t Heard About\"\n  speakers:\n    - Sean Griffin\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/rails-5-features-you-havent-heard-about-sean-griffin\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/sean-rails-5-features-you-haven’t-heard-about.mp4\"\n  description: |-\n    We’ve all heard about ActionCable, Turbolinks 5 & Rails::API. But Rails 5 was almost a thousand commits! They included dozens of minor features, many of which will be huge quality of life improvements even if you aren’t using WebSockets or Turbolinks.\n\n    A deep look at several of the “minor” features of Rails 5. You won’t just learn about the features, but you’ll learn about why they were added, the reasoning behind them, and the difficulties of adding them from someone directly involved in many of them.\n\n- id: \"patrick-hubs-and-spokes-on-rails\"\n  title: \"Hubs & Spokes on Rails\"\n  raw_title: \"Hubs & Spokes on Rails\"\n  speakers:\n    - Patrick McKenzie\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/hubs-and-spokes-on-rails-patrick-mckenzie\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/patrick-hubs-and-spokes-on-rails.mp4\"\n  description: |-\n    How do you move on from Monoliths? How can you run a stock exchange for fun? Are Enterprise Message Buses as scary as they sound?\n\n\n          A recovering Japanese salaryman who ran a succession of small software companies. Currently working at Stripe, on Atlas to make it easier to start and scale companies worldwide.\n\n- id: \"britni-mary-richards-and-the-delicate-art-of-yolo\"\n  title: \"Mary Richards and the Delicate Art of YOLO\"\n  raw_title: \"Mary Richards and the Delicate Art of YOLO\"\n  speakers:\n    - Britni Alexander\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/mary-richards-and-the-delicate-art-of-yolo-britni-alexander\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/britni-mary-richards-and-the-delicate-art-of-yolo.mp4\"\n  description: |-\n    In the wild world of pre-junior developers nothing seems more majestic and out of reach than that first paying developer role.\n\n    In this talk we will discover some of the key attitudes learned from CAN DO attitude of The Mary Tyler Moore Show and practices which are instrumental in _any_ job search at _any_ stage.\n\n- id: \"sarah-how-we-make-software_-a-new-theory-of-teams\"\n  title: \"How We Make Software: A New Theory of Teams\"\n  raw_title: \"How We Make Software: A New Theory of Teams\"\n  speakers:\n    - Sarah Mei\n  event_name: \"Brighton Ruby 2016\"\n  date: \"2016-07-08\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2016/how-we-make-software-a-new-theory-of-teams-sarah-mei\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2016/sarah-how-we-make-software_-a-new-theory-of-teams.mp4\"\n  description: |-\n    How do we talk about the teams and organisations that build software?\n\n    If the \"Henry Ford\" factory model is incorrect (and it is) how can we think and talk about our organisations to make better places to build software?\n\n    An _amazing_ keynote to finish 2016's edition of Brighton Ruby.\n\n\n          Architect at Salesforce UX, out of San Franciso. Director at Ruby Central (organisers of RailsConf & RubyConf). Founder of Bridge Foundry (Rails Bridge).\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2017/event.yml",
    "content": "---\nid: \"brightonruby-2017\"\ntitle: \"Brighton Ruby 2017\"\nlocation: \"Brighton, UK\"\ndescription: \"\"\npublished_at: \"2017-07-07\"\nstart_date: \"2017-07-07\"\nend_date: \"2017-07-07\"\nkind: \"conference\"\nyear: 2017\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 50.8229402\n  longitude: -0.1362672\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2017/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2017/videos.yml",
    "content": "---\n# Website: https://brightonruby.com/2017/\n# Schedule: https://brightonruby.com/2017/\n\n- id: \"saron-lucky\"\n  title: \"Lucky\"\n  raw_title: \"Lucky\"\n  speakers:\n    - Saron Yitbarek\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/lucky-saron-yitbarek\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/saron-lucky.mp4\"\n  description: |-\n    Being an open source contributor requires many resources we often take for granted: technical knowledge, confidence in that knowledge, access to technical tools, and a socioeconomic status that allows us to code without financial compensation. These resources are inaccessible to many, if not most.\n\n    Shifting the face of our community to better represent our increasingly global user base requires us to examine what groups are least likely to have access to these resources and how different organizations and initiatives are working to remove these barriers and create entry points for groups of people who face the biggest obstacles in their journey to becoming creators in our community.\n\n\n          Formerly an apprentice herself, she started the CodeNewbie movement: the most supportive community of programmers and people learning to code. Saron will bring her perspective to share ideas for learners and coaches.\n\n- id: \"alex-ruby-how-a-language-reflects-its-people\"\n  title: \"Ruby: How a Language Reflects its People\"\n  raw_title: \"Ruby: How a Language Reflects its People\"\n  speakers:\n    - Alex Coles\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/ruby-how-a-language-reflects-its-people-alex-coles\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/alex-ruby-how-a-language-reflects-its-people.mp4\"\n  description: |-\n    “The limits of my language mean the limits of my world”, said Wittgenstein.\n\n    In human-to-human languages the same core ideas get shaped differently depending on the language in which they are spoken. What if every computational language engenders a set (or a subset) of culture and values, and as a consequence attracts and shapes a corresponding community?\n\n    What are the values that entered into the language by way of its core committers and what are the values we identify with as a community. How can making these values explicit help us foster a better community?\n\n\n          CTO of education startup Skive and very active in the Ruby community, having founded the annual eurucamp camp/conference and JRubyConf EU.\\n\\nHe has also contributed extensively to many open-source projects including OpenProject, RefineryCMS and DataMapper.\n\n- id: \"dot-ruby-paper-scissors\"\n  title: \"Ruby Paper Scissors\"\n  raw_title: \"Ruby Paper Scissors\"\n  speakers:\n    - Dot Wingrove\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/ruby-paper-scissors-dot-wingrove\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/dot-ruby-paper-scissors.mp4\"\n  description: |-\n    In 1999 (and again in 2001) there was a competition for people to create bots to play RoShamBo, otherwise know as [Rock-paper-scissors](https://en.wikipedia.org/wiki/Rock–paper–scissors). The bot that won this competition, beating all the other entries including the competition-provided dummy bots, was called Iocaine Powder.\n\n    Let's explore approaches and techniques used to build a successful RoShamBo bot.\n\n\n          Co-organiser of @CodebarBrighton, studying maths with @OpenUniversity, humum to @morty_macgrove\n\n- id: \"piotr-rom.rb-4-is-coming\"\n  title: \"rom-rb 4.0 is Coming: Let Me Explain What It Means\"\n  raw_title: \"rom-rb 4.0 is Coming: Let Me Explain What It Means\"\n  speakers:\n    - Piotr Solnica\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/rom-rb-4-piotr-solnica\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/piotr-rom.rb-4-is-coming.mp4\"\n  description: |-\n    Ruby Object Mapper is an open-source persistence and mapping toolkit for Ruby built for speed and simplicity.\n\n    And its upcoming version is 4.0.\n\n    And Piotr knows about it.\n\n    And wants to tell you.\n\n\n          Piotr is a Technical Lead @icelab. Author and core team member @rom_rb and a co-founder and core team member @dry_rb.\n\n- id: \"najaf-debugging-a-short-guide-for-new-developers\"\n  title: \"Debugging For New Developers\"\n  raw_title: \"Debugging For New Developers\"\n  speakers:\n    - Najaf Ali\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/debugging-for-new-developers-ali-najaf\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/najaf-debugging-a-short-guide-for-new-developers.mp4\"\n  description: |-\n    Diagnosing and fixing bugs is one of the hardest things that all developers have to do. It's especially difficult for new developers that don’t have as much confidence in their abilities.\n\n    Learn about tactics and techniques for diagnosing bugs, reproducing them, researching around the problem, asking for help and implementing a fix.\n\n\n          Ali runs a Ruby on Rails consultancy called Happy Bear Software. He has fixed a lot of bugs and trained a lot of junior developers, who also have fixed a lot of bugs.\n\n- id: \"elliott-what-we-did-at-railscamp\"\n  title: \"Lightning Talk: What we did at Rails Camp\"\n  raw_title: \"What we did at Rails Camp\"\n  speakers:\n    - Elliott Hilaire\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/what-we-did-at-rails-camp-elliot-hilaire\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/elliott-what-we-did-at-railscamp.mp4\"\n  description: |-\n    Two of the best things to come from Australia are Vegemite and Rails Camp.\n\n    Find out what a bunch of Ruby developers got up to when they spent 4 days at a farmhouse in Scotland.\n\n\n          Elliott writes Ruby at Square Enix and likes to photograph small bitey things. He moved from Australia to London, where there is a shortage of small bitey things.\n\n- id: \"xavier-dont-drop-the-bass\"\n  title: \"Lightning Talk: Don’t Drop The Bass\"\n  raw_title: \"Don’t Drop The Bass\"\n  speakers:\n    - Xavier Riley\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/dont-drop-the-bass-xavier-riley\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/xavier-dont-drop-the-bass.mp4\"\n  description: |-\n    Ever wondered whether you can program a bass guitar with Ruby? Sonic Pi, everyone's favourite Ruby based live coding tool, has learnt some new tricks - it knows about live instruments and MIDI now. Let's see how it sounds when you combine them all!\n\n\n          Xavier likes music and Ruby, and where possible likes to combine the two. When he’s not procrastinating on side projects he works for Heroku in their support team.\n\n- id: \"ryan-doing-silly-stuff-with-postgres-for-fun-and-profit\"\n  title: \"Lightning Talk: Doing Silly Stuff with Postgres For Fun & Profit\"\n  raw_title: \"Doing Silly Stuff with Postgres For Fun & Profit\"\n  speakers:\n    - Ryan McGillivray\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/doing-silly-things-with-postgres-for-fun-and-profit-ryan-macgillivray\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/ryan-doing-silly-stuff-with-postgres-for-fun-and-profit.mp4\"\n  description: |-\n    A quick jump into the Postgres array datatype, the things you can use it for and why it's dangerous to do some of them in code that can make it to production.\n\n\n          Ruby guy living in London.\n\n- id: \"emma-developing-junior-developers\"\n  title: \"Lightning Talk: Developing Junior Developers\"\n  raw_title: \"Developing Junior Developers\"\n  speakers:\n    - Emma Beynon\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/developing-junior-developers-emma-beynon\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/emma-developing-junior-developers.mp4\"\n  description: |-\n    Starting out as junior developer can be an overwhelming experience, and sometimes teams don’t have the right tools to support their personal growth.\n\n    In this talk, I will cover the main obstacles that junior developers face at the beginning of their careers, and offer some practical tips so that you can help juniors in your team become the best developers they can be.\n\n\n          Emma is a junior developer at the Government Digital Service in London, helping make government better for users. A former marketer, she quit her job in late 2015 to undertake a 4-month intensive coding bootcamp. Having successfully landed her first junior position at GDS in early 2016, she has been trying to navigate the developer career path ever since.\n    When she’s not learning how to become a better developer, she enjoys going to gigs, eating burritos and travelling.\n\n- id: \"just-a-ruby-minute-2017\"\n  title: \"Gameshow: Just a Ruby Minute\"\n  raw_title: \"Just a Ruby Minute\"\n  speakers:\n    - Andrew Faraday\n    - Nadia Odunayo\n    - Najaf Ali\n    - Sarah Mei\n    - Adam Cuppy\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/just-a-ruby-minute-andrew-faraday\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/just-a-ruby-minute-2017.mp4\"\n  description: |-\n    Just a Minute, the venerable BBC Radio 4 panel game institution, is given a lunchtime run out with your host Andrew Faraday.\n\n\n          A tribute to the Radio 4 original, created with Playstation controllers and noises from the radio.\n\n- id: \"adam-difficult-conversations\"\n  title: \"Difficult Conversations\"\n  raw_title: \"Difficult Conversations\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/difficult-conversations-adam-cuppy\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/adam-difficult-conversations.mp4\"\n  description: |-\n    It’s never easy to have a tough conversations, and they never go away. Therefore, I see a better way to live with them, and I want everyone to hear it: empower yourself to understand why we do what we do so you can effect change.\n\n    Understanding creates empathy. Empathy reduces (not eliminates) conflict.\n\n    This talk is a practical course on the triad of human psychology: language, physiology and focus. I’ll walk through simple strategies that lower stress, create empathy and manage emotions.\n\n\n          Master of Smile Generation. Ambassador of Company Culture. Tech Entreprenur. Speaker/Educator. One-time Professional Actor @osfashland. Husband. Chief Zealous Officer @CodingZeal\n\n- id: \"nadia-this-code-sucks-a-story-about-non-violent-communication\"\n  title: \"This Code Sucks: A Story About Non-violent Communication\"\n  raw_title: \"This Code Sucks: A Story About Non-violent Communication\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/this-code-sucks-a-story-about-non-violent-communication-nadia-odunayo\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/nadia-this-code-sucks-a-story-about-non-violent-communication.mp4\"\n  description: |-\n    Think about something that happened at work recently. How did it make you feel? Why did it make you feel that way?\n\n    Chances are you answered those two questions poorly. Our inability to answer such questions effectively leads us to communicate in ways that are negative and unhelpful.\n\n    Let’s explore a day in the life of a fictional programmer who, just like us, means well and wants to do a great job. We’ll use our protagonist’s story to learn about how to honestly express our needs and effectively collaborate in disagreement.\n\n- id: \"andrew-can-my-friends-come-too\"\n  title: \"Can My Friends Come Too?\"\n  raw_title: \"Can My Friends Come Too?\"\n  speakers:\n    - Andrew Nesbitt\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/can-my-friends-come-too-andrew-nesbitt\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/andrew-can-my-friends-come-too.mp4\"\n  description: |-\n    The default app generated by create-react-app installs 768 transitive dependencies: am I the only one who thinks this is ridiculous?\n\n    What does an increasingly granular, sprawling tree of dependencies mean for your project? Is it a problem we all share? What should we be aware of when selecting software to use? Should we do things differently?\n\n\n          Andrew is a freelance software developer, based in Somerset, UK. He spends most of his days programming in Ruby, contributing to open source projects and organising local developer user groups.\n\n- id: \"eliza-eigen-what-now\"\n  title: \"Eigen What Now?\"\n  raw_title: \"Eigen What Now?\"\n  speakers:\n    - Eliza de Jager\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/eigen-what-now-eliza-de-jager\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/eliza-eigen-what-now.mp4\"\n  description: |-\n    Eigenclasses are an important construct in Ruby and, although obscured from the everyday developer, are core to many meta-programming principles and techniques.\n\n    We delve into what an eigenclass is, how to access it, and how to make use of this knowledge in order to improve our meta-programming techniques. Method lookup, singleton methods, `class_eval` and `instance_eval`, and `include` and `extend` will all be explained in the context of eigenclasses.\n\n\n          Developer at Zappi Store.\n\n- id: \"adam-boring-ruby-code\"\n  title: \"Boring Ruby Code\"\n  raw_title: \"Boring Ruby Code\"\n  speakers:\n    - Adam Niedzielski\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/boring-ruby-code-adam-niedzielski\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/adam-boring-ruby-code.mp4\"\n  description: |-\n    Ruby is a powerful language and this means that Ruby gives you a good chance to shoot yourself in a foot. “With great power comes great responsibility” and we all love to abuse our powers.\n\n    We will explore examples of “smart” Ruby code and see why they are confusing to junior programmers, your colleagues and even you revisiting the codebase after 6 months. Come to this talk if you want to learn why “boring” is better than “smart”.\n\n\n          Adam is a programmer that loves teaching people how to write code and sharing his knowledge. He enjoys conferences and local programming meetups as an attendee, speaker and organizer. Adam is obsessed with clean code, but he never forgets that the technology exists to serve its users. He is really proud of his blog.\\n\\nIn his free time Adam plays board games, drinks craft beer or explores new cities without checking a map.\n\n- id: \"sarah-livable-code\"\n  title: \"Livable Code\"\n  raw_title: \"Livable Code\"\n  speakers:\n    - Sarah Mei\n  event_name: \"Brighton Ruby 2017\"\n  date: \"2017-07-07\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2017/livable-code-sarah-mei\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2017/sarah-livable-code.mp4\"\n  description: |-\n    The modern practice of software isn’t much like architecture or construction. The buildings are largely built. These days, we make a pre-built space work for whoever lives there.\n\n    Ever been to a staged house? They hire interior designers to put furniture, rugs, etc. into the space, so people can imagine themselves there, and it's not just empty.\n\n    Staged houses are beautiful. They're designed to make you go \"WOW\" when you walk in, and think, \"I could live like this.\"\n\n    But you can’t actually live in a staged house. They leave out lots of things that make a space more cluttered, but also make it work.\n\n\n          Architect at Salesforce UX, out of San Franciso. Director at Ruby Central (organisers of RailsConf & RubyConf). Founder of Bridge Foundry (Rails Bridge).\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2018/event.yml",
    "content": "---\nid: \"brightonruby-2018\"\ntitle: \"Brighton Ruby 2018\"\nlocation: \"Brighton, UK\"\ndescription: \"\"\npublished_at: \"2018-07-06\"\nstart_date: \"2018-07-06\"\nend_date: \"2018-07-06\"\nkind: \"conference\"\nyear: 2018\nbanner_background: \"#292B2C\"\nfeatured_background: \"#292B2C\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 50.8229402\n  longitude: -0.1362672\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2018/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2018/videos.yml",
    "content": "---\n# Website: https://brightonruby.com/2018/\n# Schedule: https://brightonruby.com/2018/\n\n- id: \"andy-brighton-ruby-code-of-conduct\"\n  title: \"Welcome & Code of Conduct\"\n  raw_title: \"Welcome & Code of Conduct\"\n  speakers:\n    - Andy Croll\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/welcome-code-of-conduct-andy-croll\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/andy-brighton-ruby-code-of-conduct.mp4\"\n  description: |-\n    At the beginning of 2018's Brighton Ruby, during the introduction, I wanted to 'get into' what having a Code of Conduct means. I hadn't seen anyone do this, and it's a topic I'd been thinking about a lot this year.\n\n    It's important to be introspective, as an organiser, about the impact of your event and your own responsibility to include people into our communities. We all have responsibilities and expectations about our behaviour toward each other, this is my take on what it means, for Brighton Ruby at least.\n\n    I don't think I did a brilliant job, it's difficult to be clear, and I still have my blind spots.\n\n    However, the amount of positive feedback I've had about this 'impromptu lightning talk' indicated that I should share this and encourage other organisers to think about what they are doing to make sure that they are making the Code of Conduct a living thing and to ensure they are hearing about the stuff that people might otherwise ignore.\n\n- id: \"sarah-a-brief-history-of-types\"\n  title: \"A Brief History of Types\"\n  raw_title: \"A Brief History of Types\"\n  speakers:\n    - Sarah Mei\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/a-brief-history-of-types-sarah-mei\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/sarah-a-brief-history-of-types.mp4\"\n  description: |-\n    What they are, what they're good for, how they're traditionally specified & enforced, and how the whole concept is evolving.\n\n\n          Architect at Salesforce UX, out of San Franciso. Director at Ruby Central (organisers of RailsConf & RubyConf). Founder of Bridge Foundry (Rails Bridge).\n\n- id: \"katrina-cultivating-instinct\"\n  title: \"Cultivating Instinct\"\n  raw_title: \"Cultivating Instinct\"\n  speakers:\n    - Katrina Owen\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/cultivating-instinct-katrina-owen\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/katrina-cultivating-instinct.mp4\"\n  description: |-\n    As novices we slowly and laboriously sift through a chaotic flood of\n    minutia. To experts the significant details are obvious. Irrelevant\n    details fade to the background. The novice receives a jumble of\n    meaningless impressions; the expert sees patterns and meaning.\n\n    Somehow experts have made the trek from \"How could you possibly tell?\"\n    to \"How could you not?\". And they probably can't tell you how they got\n    there.\n\n    This talk examines the topic of perceptual learning through the lens\n    of theory and practice—research and anecdotes—and speculates how it\n    can be deployed strategically to train new experts.\n\n\n          An ecosystem engineer at GitHub and author. She accidentally became a developer while pursuing a degree in molecular author_biologymarkdown. When programming, her focus is on automation, workflow optimization, and refactoring.\n\n- id: \"ashley-git-driven-refactoring\"\n  title: \"Git-driven Refactoring\"\n  raw_title: \"Git-driven Refactoring\"\n  speakers:\n    - Ashley Ellis Pierce\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/git-driven-refactoring-ashley-ellis-pierce\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/ashley-git-driven-refactoring.mp4\"\n  description: |-\n    Often we know that our code needs refactoring, but we have no idea where to start. Maybe we studied some common code smells and learned about the things that we should be avoiding, but memorizing the rules doesn’t automatically lead to fixing all problems.\n\n    In this talk, we explore how you can use Git to recognize and address violations to each of the SOLID principles. Using diffs, commit history and pull requests you can learn to recognize patterns in code that point to problems. These same tools can help you correct those issues and write more maintainable code.\n\n\n          Ashley lives in Durham, NC and is an Application Engineer at GitHub. She enjoys helping others learn to code and is the lead organizer for RailsBridge Triangle and a mentor for Code the Dream\n\n- id: \"ana-lets-refactor-some-ruby-code\"\n  title: \"Let’s Refactor Some Ruby Code\"\n  raw_title: \"Let’s Refactor Some Ruby Code\"\n  speakers:\n    - Ana Martínez\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/lets-refactor-some-ruby-code-ana-martinez\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/ana-lets-refactor-some-ruby-code.mp4\"\n  description: |-\n    This year both Ruby and I are turning 25 years old. We all also have to admit that at some point we have found, or written, Ruby code that was not that great. Even the code that was pretty good at one point, could now be improved, due to the evolution of Ruby.\n\n    Let us refactor some code in long-lived Ruby and Rails open source projects and what can we learn while doing it.\n\n\n          Ana is in love the open source development. She is currently working at SUSE on the Open Build Service frontend, one of the oldest Rails projects that is still in use.\n\n- id: \"tekin-a-branch-in-time\"\n  title: \"A Branch in Time\"\n  raw_title: \"A Branch in Time\"\n  speakers:\n    - Tekin Süleyman\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/a-branch-in-time-tekin-suleyman\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/tekin-a-branch-in-time.mp4\"\n  description: |-\n    In one timeline a quick path to clarity. In the other a long and painful journey trying to understand the obscure intent of a line of code. The only difference between these two realities? The revision history.\n\n    This is a talk about writing maintainable code. But rather than the code itself, we'll see the impact a codebase's history can have on its maintainability. We'll explore the differences between a useful history and an unhelpful one, and you'll learn about the practices, tools and techniques that can make the difference.\n\n\n          Tekin Süleyman is a freelance consultant who's been shipping Ruby code for over a decade. He's worked with teams, large and small. He also runs the North West Ruby User Group in Manchester.\n\n- id: \"nick-cockcrofts-folly\"\n  title: \"Cockcroft’s Folly\"\n  raw_title: \"Cockcroft’s Folly\"\n  speakers:\n    - Nick Means\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/cockcrofts-folly-nick-means\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/nick-cockcrofts-folly.mp4\"\n  description: |-\n    Storyteller, empathetic leader, student of disasters, builder of distributed teams. Unabashed AV geek. VP of Engineering at Muve Health.\n\n- id: \"maria-a-clear-eyed-look-at-distributed-teams\"\n  title: \"A Clear-eyed Look at Distributed Teams\"\n  raw_title: \"A Clear-eyed Look at Distributed Teams\"\n  speakers:\n    - Maria Gutierrez\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/a-clear-eyed-look-at-distributed-teams-maria-gutierrez\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/maria-a-clear-eyed-look-at-distributed-teams.mp4\"\n  description: |-\n    Distributed teams can have big benefits for both employers and employees. But there are many challenges. Being successful requires changes to work practices, communication, and style — and not just from the remote people. Everyone will experience changes. It helps to be prepared … and most of what we see being written and discussed is focused on remote workers, not the organization that supports them.\n\n\n          VP of Engineering at Edinburgh-based FreeAgent. Previously worked at LivingSocial leading globally distributed teams, and at Adobe where she worked in the developer technologies group. Also a Director of the WomenWhoCode Edinburgh network.\n\n- id: \"alex-configuration-first-open-source\"\n  title: \"Lightning Talk: Configuration-first Open Source\"\n  raw_title: \"Configuration-first Open Source\"\n  speakers:\n    - Alex Balhatchet\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/configuration-first-open-source-alex-balhatchet\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/alex-configuration-first-open-source.mp4\"\n  description: |-\n    You might not realise it, but your Ruby project probably relies on a popular configuration-first OSS project. The `tzdata` library is updated regularly as time zones and daylight savings rules change more often than you might think!\n\n    By building a project configuration first, rather than focussing on one programming language, you can get a much wider range of people contributing to your open source package. We built a Ruby gem for public holidays that covered 71 countries. By converting it to a configuration first project we were able to release packages for Ruby, Node.js and Perl so that more people could use the data and we’d be more likely to get patches and bug fixes.\n\n\n          Senior software engineer at CharlieHR, building the HR software for teams with big ideas. Previously CTO at Nestoria so ask me about writing Perl for a decade before switching to Ruby :-)\n\n- id: \"alfredo-introduction-to-event-sourcing-for-rubyists\"\n  title: \"Lightning Talk: Introduction to Event Sourcing for Rubyists\"\n  raw_title: \"Introduction to Event Sourcing for Rubyists\"\n  speakers:\n    - Alfredo Motta\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/introduction-to-event-sourcing-for-rubyists-alfredo-motta\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/alfredo-introduction-to-event-sourcing-for-rubyists.mp4\"\n  description: |-\n    [Event sourcing](https://martinfowler.com/eaaDev/EventSourcing.html) is a design pattern to help build applications that are focused on the domain and easy to extend.\n\n    The key idea is to use a persistent event log to store every change to your data as an alternative the more classical relational database model for Rails applications. In one sentence, it is a git-like approach to manage your data.\n\n    Once you accept the premise of having an event log you can use it to extend your application in all sort of creative ways. You can use it to synchronize the data between your microservices, or you can trigger side effects without cluttering your controllers, or you can build data views optimized for your query needs.\n\n\n          CTO at CreditSpring, protecting people from unexpected financial emergencies. Loves data and scientific experimentation over intuition and learning over being too serious.\n\n- id: \"danny-random-thoughts\"\n  title: \"Lightning Talk: Random Thoughts\"\n  raw_title: \"Random Thoughts\"\n  speakers:\n    - Danny Berzon\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/random-thoughts-daniel-berzon\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/danny-random-thoughts.mp4\"\n  description: |-\n    How a single line of ruby code, the flip of a coin and some bad luck lead to an understanding of how random numbers really work, and why fairness isn’t always the best policy.\n\n\n          Danny has worked in Web Development since late last century, Java and Servlets then Ruby on Rails. Currently in a permanent position at Ocasta Studios.\n\n- id: \"andrew-the-best-worst-software-i’ve-ever-written\"\n  title: \"Lightning Talk: The Best Worst Software I’ve Ever Written\"\n  raw_title: \"The Best Worst Software I’ve Ever Written\"\n  speakers:\n    - Andrew Faraday\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/the-best-worst-software-ive-ever-written-andrew-faraday\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/andrew-the-best-worst-software-i’ve-ever-written.mp4\"\n  description: |-\n    You may remember Andrew from previous Brighton Ruby conferences (as well as those in London, Scotland, and the USA) where he's been providing light relief in the form of the panel game Just A Minute.\n\n    This year, instead, he’ll be revealing the technology behind the show, and sharing what he’s learned from the project.\n\n\n          Rubyist, music graduate, autistic, international panel game host, kidney donor, follower of Christ. Mostly tweets about politics and software. Host of Just a (Ruby) Minute.\n\n- id: \"paula-the-ballad-of-rspec\"\n  title: \"Lightning Talk: The Ballad of RSpec\"\n  raw_title: \"The Ballad of RSpec\"\n  speakers:\n    - Paula Muldoon\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/the-ballad-of-rspec-paula-muldoon\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/paula-the-ballad-of-rspec.mp4\"\n  description: |-\n    A violin and a testing framework.\n\n\n          Engineer at Kurt Geiger, graduated from Makers Academy and University of Michigan. Code by day, music by night.\n\n- id: \"hannah-cryptography-lessons\"\n  title: \"Cryptography Lessons\"\n  raw_title: \"Cryptography Lessons\"\n  speakers:\n    - Hannah Dwan\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/cryptography-lessons-hannah-dwan\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/hannah-cryptography-lessons.mp4\"\n  description: |-\n    The Matasano Crypto Challenges - or Cryptopals, to give them their much kinder, Saturday morning cartoon name - are a series of coding challenges, made by Matasano Security (now a part of NCC group). They challenge you to think about cryptography, security, and teach you the motions of how to encrypt, decrypt, and attack.\n\n    It’s not wildly complex, it’s not a set of logic systems above everything you already know if you can put together FizzBuzz. As an apprentice, a key part of my job is to learn - Cryptopals, regardless of your own expertise, is one of the most rewarding ways to learn Ruby, to learn logic, and to learn how all the encryption you rely on works.\n\n\n          Hannah Dwan is a developer at Happy Bear Software! She used to be a games journalist, but abandoned the glitz and glamour of esports in favour of pull requests and documentation.\n\n- id: \"piotr-the-ruby-alchemists-secret-potion\"\n  title: \"The Ruby Alchemist’s Secret Potion\"\n  raw_title: \"The Ruby Alchemist’s Secret Potion\"\n  speakers:\n    - Piotr Murach\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/the-ruby-alchemists-secret-potion-piotr-murach\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/piotr-the-ruby-alchemists-secret-potion.mp4\"\n  description: |-\n    What if there was a set of simple and potent gems that could exponentially increase productivity when building modern terminal applications such as Bundler, in next to no time?\n\n    If you’re curious about creating your own tools and games in the terminal, I can show you how to harness this power and become a command line applications alchemist. Learn how to mix and match various TTY potions to come up with a secret mixture for analysing cryptocurrency gold or breathing life into the ASCII characters.\n\n\n          Software engineer by day, open sourcer by night, mathematician by design and human languages enthusiast life, Piotr has released many open source projects such as tty, finite_machine, github_api. In recent years, Piotr has been obsessively thinking about optimising Ruby terminal applications development.\n\n- id: \"alex-ruby-us-hagrid_-writing-harry-potter-with-ruby\"\n  title: \"Ruby-us Hagrid: Writing Harry Potter with Ruby\"\n  raw_title: \"Ruby-us Hagrid: Writing Harry Potter with Ruby\"\n  speakers:\n    - Alex Peattie\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/writing-harry-potter-with-ruby-alex-peattie\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/alex-ruby-us-hagrid_-writing-harry-potter-with-ruby.mp4\"\n  description: |-\n    The average salary for a Ruby programmer (according to Techworld) is £52k, but the average net worth of a “J. K. Rowling” is more than $1bn! Clearly we’re in the wrong business; we shouldn’t be writing Ruby code, we should be writing Harry Potter books.\n\n    The bad news is that writing novels beloved by children across the world is hard. The good news is we can get Ruby to do it for us! It turns out that Ruby and the dark arts of NLP (Natural Language Programming) are a match made in heaven.\n\n    Using some basic language modeling techniques, a dash of probability, and a few lines of easy-to-follow Ruby code, we can create a virtual author capable of generating a very convincing Potter pastiche. And if the life of an author’s not for you, don’t worry. The techniques we’ll explore are applicable to a host of other problems, from machine translation to spam detection.\n\n\n          Alex is the co-founder and CTO of Peg, a technology platform helping multinational brands and agencies to find and work with top YouTubers.\n\n- id: \"joe-alpha-beta-gamer\"\n  title: \"Alpha. Beta. Gamer.\"\n  raw_title: \"Alpha. Beta. Gamer.\"\n  speakers:\n    - Joe Hart\n  event_name: \"Brighton Ruby 2018\"\n  date: \"2018-07-06\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2018/alpha-beta-gamer-joe-hart\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2018/joe-alpha-beta-gamer.mp4\"\n  description: |-\n    A live performance of video games and stand up comedy from comedian and coder, including pre prepared web games to play and even creating a video game with the audience on stage in only 10 minutes.\n\n\n          Joe Hart is a comedian who codes, or a software engineer who tells jokes depending on which time of the day he’s asked. He’s built software for the BBC, non profits and is currently making WebVR things for Blend Media.\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2019/event.yml",
    "content": "---\nid: \"brightonruby-2019\"\ntitle: \"Brighton Ruby 2019\"\nlocation: \"Brighton, UK\"\ndescription: \"\"\npublished_at: \"2019-07-05\"\nstart_date: \"2019-07-05\"\nend_date: \"2019-07-05\"\nkind: \"conference\"\nyear: 2019\nbanner_background: \"#292B2C\"\nfeatured_background: \"#292B2C\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 50.8229402\n  longitude: -0.1362672\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2019/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2019/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"FreeAgent\"\n          badge: \"\"\n          website: \"https://bit.ly/38L8H9i\"\n          slug: \"freeagent\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/freeagent.svg\"\n\n        - name: \"Cookpad\"\n          badge: \"\"\n          website: \"https://careers.cookpad.com\"\n          slug: \"cookpad\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/cookpad.svg\"\n\n        - name: \"TRX\"\n          badge: \"\"\n          website: \"https://trx.tv/careers/\"\n          slug: \"trx\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/trx.svg\"\n\n        - name: \"Simply Business\"\n          badge: \"\"\n          website: \"https://www.simplybusiness.co.uk/about-us/careers/tech/\"\n          slug: \"simply-business\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/simply_business.svg\"\n\n    - name: \"Silver\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Loco2\"\n          badge: \"\"\n          website: \"https://loco2.com\"\n          slug: \"loco2\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/loco2.svg\"\n\n        - name: \"Cleo\"\n          badge: \"\"\n          website: \"https://web.meetcleo.com/careers\"\n          slug: \"cleo\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/cleo.svg\"\n\n        - name: \"Immersive Labs\"\n          badge: \"\"\n          website: \"https://immersivelabs.com/careers/\"\n          slug: \"immersive-labs\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/immersive_labs.svg\"\n\n        - name: \"Nexmo\"\n          badge: \"\"\n          website: \"http://nexmo.dev/newgem\"\n          slug: \"nexmo\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/nexmo.svg\"\n\n    - name: \"Supported by\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"Bloom & Wild\"\n          badge: \"\"\n          website: \"https://www.bloomandwild.com/careers\"\n          slug: \"bloom-wild\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/bloom_&_wild.svg\"\n\n        - name: \"Dressipi\"\n          badge: \"\"\n          website: \"https://dressipi.com\"\n          slug: \"dressipi\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/dressipi.svg\"\n\n        - name: \"AppFolio\"\n          badge: \"\"\n          website: \"https://www.appfolio.com\"\n          slug: \"appfolio\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/appfolio.svg\"\n\n        - name: \"Error\"\n          badge: \"\"\n          website: \"\"\n          slug: \"error\"\n          logo_url: \"https://brightonruby.com/images/2019/sponsors/error.svg\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2019/videos.yml",
    "content": "---\n# Website: https://brightonruby.com/2019/\n# Schedule: https://brightonruby.com/2019/\n\n- id: \"vaidehi-setting-up-to-fail\"\n  title: \"Setting Up To Fail\"\n  raw_title: \"Setting Up To Fail\"\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/setting-up-to-fail-vaidehi-joshi\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/vaidehi-setting-up-to-fail.mp4\"\n  description: |-\n    What are the semantics of failure in distributed systems (how we identify failures and faults) and how to think about what we really mean when we design towards fault-tolerant systems.\n\n\n          Creator of Base CS\n\n- id: \"gareth-why-should-you-care-about-cultivating-trust\"\n  title: \"Why Should You Care About Cultivating Trust?\"\n  raw_title: \"Why Should You Care About Cultivating Trust?\"\n  speakers:\n    - Gareth Marlow\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/why-should-you-care-about-cultivating-trust-gareth-marlow\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/gareth-why-should-you-care-about-cultivating-trust.mp4\"\n  description: |-\n    Practical tips for building a culture of trust across your team, peers, investors, and company.\n\n\n          Executive coach at eqsystems.io; formerly COO at Redgate Software; Father of four; renaissance man.\n\n- id: \"matthew-from-developer-to-architect-and-back-again\"\n  title: \"Lightning Talk: From Developer to Architect (and back again)\"\n  raw_title: \"From Developer to Architect (and back again)\"\n  speakers:\n    - Matthew Rudy Jacobs\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/from-developer-to-architect-and-back-again-matthew-rudy-jacobs\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/matthew-from-developer-to-architect-and-back-again.mp4\"\n  description: |-\n    A year ago I was looking for a job, and ended up taking a job as a “Technical Architect”.\n\n    But what exactly is a Technical Architect?\n\n    Weren’t Software Architects a thing in the 90s, cast away when we learnt about Agile?\n\n    In this talk I’m going to tell the story of my year in government as a Technical Architect, and hopefully convince you that there is a place for just enough architecture in modern software development.\n\n    And maybe it’s a role you’d be interested in\n\n\n          Engineer at Babylon Health, and Organiser of Hong Kong Code Conf.\n\n- id: \"amina-embracing-openness-in-open-source\"\n  title: \"Lightning Talk: Embracing Openness in Open Source\"\n  raw_title: \"Embracing Openness in Open Source\"\n  speakers:\n    - Amina Adewusi\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/embracing-openness-in-open-source-amina-adewusi\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/amina-embracing-openness-in-open-source.mp4\"\n  description: |-\n    This is the story of how I struggled to get my first Junior Developer role and turned to Open Source projects looking for help. We’ll learn how the best GitHub repos are attracting new contributors, why developers early in their coding journey can struggle to get to grips with a new repo and how you avoid these stumbling blocks to create a vibrant open source project.\n\n\n          Amina is an Associate Software Engineer at the Guardian in London. She seeks to represent the voice of new developers in the software engineering industry and is passionate about encouraging under-represented groups into tech.\n\n- id: \"frederick-fixing-performance-problems-with-ruby-prof\"\n  title: \"Lightning Talk: Fixing Performance Problems with ruby-prof\"\n  raw_title: \"Fixing Performance Problems with ruby-prof\"\n  speakers:\n    - Frederick Cheung\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/fixing-performance-problems-with-ruby-prof-frederick-cheung\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/frederick-fixing-performance-problems-with-ruby-prof.mp4\"\n  description: |-\n    How do you find out why your code is slow? Profiling tools such as `ruby-prof` can help you understand your code and get to the root of performance problems. Learn how use ruby-prof and make sense of its output.\n\n\n          Ruby Hero, runner, cat servant & CTO at Dressipi\n\n- id: \"nadia-chats-with-sarah-mei\"\n  title: \"Nadia chats with... Sarah Mei\"\n  raw_title: \"Nadia chats with... Sarah Mei\"\n  speakers:\n    - Sarah Mei\n    - Nadia Odunayo\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/nadia-chats-with-sarah-mei\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/nadia-chats-with-sarah-mei.mp4\"\n  description: |-\n    Nadia sits down for a chat with Sarah Mei.\n\n\n          Architect at Salesforce UX, out of San Franciso. Director at Ruby Central (organisers of RailsConf & RubyConf). Founder of Bridge Foundry (Rails Bridge).\n\n- id: \"valerie-better-coding-through-unit-tests\"\n  title: \"Better Coding Through Unit Tests\"\n  raw_title: \"Better Coding Through Unit Tests\"\n  speakers:\n    - Valerie Woolard\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/better-coding-through-unit-tests-valerie-woolard-srinivasan\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/valerie-better-coding-through-unit-tests.mp4\"\n  description: |-\n    We all know that testing is important. But it’s also hard to get right. We’ll talk about how to write effective tests that not only protect against defects in our code, but encourage us to write better quality code to begin with.\n\n    You’ll leave this talk with ideas on the philosophies that should inform your tests, and a good idea of what makes a good test suite.\n\n\n          Valerie loves writing software, running marathons, and baking desserts.\n\n- id: \"sroop-the-life-changing-magic-of-tidying-technical-debt\"\n  title: \"The Life Changing Magic of Tidying Technical Debt\"\n  raw_title: \"The Life Changing Magic of Tidying Technical Debt\"\n  speakers:\n    - Sroop Sunar\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/life-changing-magic-of-tidying-technical-debt-sroop-sunar\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/sroop-the-life-changing-magic-of-tidying-technical-debt.mp4\"\n  description: |-\n    As developers, we talk a lot about the topic of clean code. We aspire for 100% test coverage, short reusable methods, we optimise for readability and beauty - but does any of that actually matter if your codebase is drowning in technical debt?\n\n    Should we be aiming for clean code, or tidy code? In this talk, you may discover that you are in fact a closet code slob, contributing to the clutter of your codebase every single day.\n\n    But fear not, because tidying a codebase is as simple as decluttering your home. Drawing on lots of practical examples, this talk will arm you with some simple techniques to permanently purge technical debt and be free from code-clutter forever.\n\n\n          Sroop Sunar is a Software Developer (and employee #1) at Peg. Before that, she worked at Thoughtbot, and in a previous life was an illustrator and graphic designer.\n\n- id: \"noah-six-years-of-ruby-performance-a-history\"\n  title: \"Six Years of Ruby Performance: A History\"\n  raw_title: \"Six Years of Ruby Performance: A History\"\n  speakers:\n    - Noah Gibbs\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/six-years-of-ruby-performance-noah-gibbs\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/noah-six-years-of-ruby-performance-a-history.mp4\"\n  description: |-\n    Ruby keeps getting faster. And people keep asking, “but how fast is it for Rails?” Rails makes a great way to measure Ruby’s speed, and how Ruby has changed version-by-version. Let’s look at six years of performance for apps big and small.\n\n    How fast is 2.6.0? With JIT or not? How do I measure? How close is Ruby 3x3? Should I upgrade?\n\n\n          Noah is a Ruby Fellow for AppFolio, working on the core Ruby language and related tooling. After over 30 years of communicating with computers, Noah now believes that communicating with humans may not be a passing fad, and he’s trying it out.\n\n- id: \"alyssa-you-may-have-encountered-a-bug-in-the-ruby-interpreter\"\n  title: \"You may have encountered a bug in the Ruby interpreter\"\n  raw_title: \"You may have encountered a bug in the Ruby interpreter\"\n  speakers:\n    - Alyssa Ross\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/you-may-have-encountered-a-bug-in-the-ruby-interpreter-alyssa-ross\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/alyssa-you-may-have-encountered-a-bug-in-the-ruby-interpreter.mp4\"\n  description: |-\n    People sometimes say “it’s never a compiler error”. They don’t mean it literally — what they mean is that it’s very tempting to blame the compiler or interpreter for a bug that is actually in our own code. But sometimes, when the stars align, there it is. The mythical interpreter bug.\n\n    I’m going to show you how I narrowed down from “the website is crashing on my computer” to a real, live bug in the Ruby interpreter. We’ll look at how we can use techniques we already know, like unit testing and git, in the unfamiliar context of Ruby’s C internals. And, when we’ve finally figured out what’s causing our bug, we’ll go through the bug reporting process and learn how to share our findings and help make Ruby better for everyone.\n\n\n          A free software developer on the Developer Platform team at FreeAgent, where she has worked on Ruby’s standard libraries and other key components of the Ruby ecosystem.\n\n- id: \"matias-ruby-like-its-1995\"\n  title: \"Ruby like it's 1995\"\n  raw_title: \"Ruby like it’s 1995\"\n  speakers:\n    - Matias Korhonen\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/ruby-like-its-1995-matias-korhonen\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/matias-ruby-like-its-1995.mp4\"\n  description: |-\n    Cast your mind back to the year 1995. Gansta’s Paradise is the top hit of the year. Friends is the hottest show on TV.\n\n    And just days after I turn nine, Matz releases Ruby publicly for the first time.\n\n    In this talk I go back to Ruby 0.95 and see what it takes to get it running on modern hardware.\n\n\n          Matias has been writing Ruby for almost a decade and in his spare time he's a beer enthusiast and general internet astronaut.\n\n- id: \"aaron-defragging-ruby\"\n  title: \"Defragging Ruby\"\n  raw_title: \"Defragging Ruby\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Brighton Ruby 2019\"\n  date: \"2019-07-05\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2019/defragging-ruby-aaron-patterson\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2019/aaron-defragging-ruby.mp4\"\n  description: |-\n    It’s been said that programmers like garbage collectors, so let’s take a look at Ruby’s GC! In this talk we'll walk through how Ruby allocates objects, then talk about how we can optimize object layout and memory usage via compaction. Finally we’ll take a look at how to actually build a compacting GC for Ruby as well as the interesting challenges that can be found within.\n\n\n          Aaron is on the Ruby core team, the Rails core team, and the team that takes care of his cat, Gorby puff.  During the day he works for a small technology company called GitHub.  Someday he will find the perfect safety gear to wear while extreme programming.\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2020/event.yml",
    "content": "---\nid: \"brightonruby-2020\"\ntitle: \"Brighton Ruby 2020\"\nlocation: \"online\"\ndescription: |-\n  A slightly odd, quasi-conference for strange times by Andy Croll. It’s recorded talks, it’s a physical book, it’s a podcast. Delivered throughout June/July 2020.\npublished_at: \"2020-06-01\"\nstart_date: \"2020-06-01\"\nend_date: \"2020-06-01\"\nkind: \"conference\"\nyear: 2020\nbanner_background: \"#343A40\"\nfeatured_background: \"#343A40\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://brightonruby.com/2020\"\naliases:\n  - Alt::BrightonRuby\n  - Brighton Ruby 2020 (Alt::BrightonRuby)\ncoordinates: false\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2020/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2020/videos.yml",
    "content": "---\n# TODO: schedule\n\n# Website: https://brightonruby.com/2020/\n# Website: https://web.archive.org/web/20200430194859/https://alt.brightonruby.com/\n\n- id: \"andy-the-games-developers-play\"\n  title: \"The Games Developers Play\"\n  raw_title: \"The Games Developers Play\"\n  speakers:\n    - Andy Croll\n  event_name: \"Brighton Ruby 2020\"\n  date: \"2020-06-01\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2020/the-games-developers-play-andy-croll/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2020/andy-the-games-developers-play.mp4\"\n  description: |-\n    “We protect our little fictions, like it’s all we are.” Elbow\n\n    Every human can get trapped in cycles of bad communication, that’s very true of developers. Join me for appalling Yorkshire accents, drama triangles and wittily-named psychological theories.\n\n- id: \"mary-you-dont-need-a-queuing-service\"\n  title: \"You Don’t Need A Queuing Service, You Have Postgres\"\n  raw_title: \"You Don’t Need A Queuing Service, You Have Postgres\"\n  speakers:\n    - Mary Lee\n  event_name: \"Brighton Ruby 2020\"\n  date: \"2020-06-01\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2020/you-dont-need-a-queuing-service-mary-beth-lee/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2020/mary-you-dont-need-a-queuing-service.mp4\"\n  description: |-\n    You can sign up for SQS or use Sidekiq or Delayed Job. But what about the database you already have?\n\n    Senior developer at Hashrocket, host of pgcasts\n\n- id: \"eileen-technically-a-talk\"\n  title: \"Technically a Talk\"\n  raw_title: \"Technically a Talk\"\n  speakers:\n    - Eileen Uchitelle\n  event_name: \"Brighton Ruby 2020\"\n  date: \"2020-06-01\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2020/technically-a-talk-eileen-uchitelle/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2020/eileen-technically-a-talk.mp4\"\n  description: |-\n    Eileen talks through her experiences building a major feature—multiple database support—in Rails 6 and why she does the (good!) work she does for the Rails community.\n\n    Staff Engineer on the Ruby Architecture Team at GitHub and a member of the Rails Core team. She’s an avid contributor to open source focusing on the Ruby on Rails framework and its dependencies. Eileen is passionate about scalability, performance, and making open source communities more sustainable and welcoming.\n\n- id: \"penelope-building-rubyfmt\"\n  title: \"Building Rubyfmt\"\n  raw_title: \"Building Rubyfmt\"\n  speakers:\n    - Penelope Phippen\n  event_name: \"Brighton Ruby 2020\"\n  date: \"2020-06-01\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2020/building-rubyfmt-penelope-phippen/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2020/penelope-building-rubyfmt.mp4\"\n  description: |-\n    Why build a super-fast code-formatter for Ruby given there is no written standard for how Ruby is supposed to work?\n\n    To develop a superpower: an extremely cursed knowledge of the Ruby programming language’s grammar.\n\n    Cursedly obsessed with the Ruby parser and maintained RSpec for a number of years. Currently works at Google as a Developer Advocate. She is a trans woman, originally hailing from the Romsey, Hampshire, but currently lives in New York. She loves all things Ruby, and is super excited to meet you at Brighton Ruby!\n\n- id: \"josh-the-14-day-no-laptop-challenge\"\n  title: \"The 14-day No Laptop Challenge\"\n  raw_title: \"The 14-day No Laptop Challenge\"\n  speakers:\n    - Josh Puetz\n  event_name: \"Brighton Ruby 2020\"\n  date: \"2020-06-01\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2020/the-14-day-no-laptop-challenge-josh-puetz/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2020/josh-the-14-day-no-laptop-challenge.mp4\"\n  description: |-\n    Find out how to do Real Work (TM) on an iPad from a fella who does real Rails coding on their tablet.\n\n- id: \"emma-just-simply\"\n  title: \"Just Simply\"\n  raw_title: \"Just Simply\"\n  speakers:\n    - Emma Barnes\n  event_name: \"Brighton Ruby 2020\"\n  date: \"2020-06-01\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2020/just-simply-emma-barnes/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2020/emma-just-simply.mp4\"\n  description: |-\n    Emma wants to explain how trivial your work is, nowadays. After all, there are so many gems, libraries and frameworks that make your work as developers painfully simple, really obvious and frighteningly easy. All you have to do is just use them: they make programming painless!\n\n    Except she won’t. Expanding on her justsimply.dev manifesto, Emma will share some of the most egregious examples of technical documentation that infuriate rather than help. And she’ll provide useful advice to keep your technical writing friendly, supportive and impactful.\n\n    And yes. All the phrases in the first paragraph are from real world documentation. By the end of this talk you’ll have resolved not to put people off using the code you’ve worked so hard to create. Because if someone’s having to read your docs, it’s not “simple”.\n\n    Book publisher turned programmer. She runs generalproducts.co, makers of Consonance, as well as indie publisher Snowbooks, and she maintains schools publishing app Make Our Book on Side Project Fridays. She works in a first floor office in a market town in the Oxfordshire countryside, which attracts a local cat that visits through the window.\n\n- id: \"amina-how-to-become-a-developer-with-no-time-and-no-money\"\n  title: \"How to Become a Developer with No Time and No Money\"\n  raw_title: \"How to Become a Developer with No Time and No Money\"\n  speakers:\n    - Amina Adewusi\n  event_name: \"Brighton Ruby 2020\"\n  date: \"2020-06-01\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2020/how-to-become-a-developer-with-no-time-and-no-money-amina-adewusi/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2020/amina-how-to-become-a-developer-with-no-time-and-no-money.mp4\"\n  description: |-\n    Amina will share her story about what it takes to become a developer after teaching herself how to code, juggling a full-time job and baby. She will offer advice on how developers and managers can shape our engineering community by supporting new developers.\n\n    Amina is an Associate Software Engineer at the Guardian in London. She seeks to represent the voice of new developers in the software engineering industry and is passionate about encouraging under-represented groups into tech.\n\n- id: \"allison-personal-sparkles\"\n  title: \"Planning for Personal Sparkles\"\n  raw_title: \"Planning for Personal Sparkles\"\n  speakers:\n    - Allison McMillan\n  event_name: \"Brighton Ruby 2020\"\n  date: \"2020-06-01\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2020/personal-sparkles-allison-mcmillan/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2020/allison-personal-sparkles.mp4\"\n  description: |-\n    A new talk, based on an old one - planning for personal sparkles: A COVID-19 plan.\n\n    Before we talked about maximizing your work day but in today’s world, Allison has re-done the talk to focus on how to take advantage of the bits and bursts of focus you may get in a day.\n\n    There’s a lot going on in the world and hopefully this talk helps.\n\n    Allison McMillan is a Senior Engineering Manager at GitHub and the creator of the Parent Driven Development podcast.\n\n- id: \"nate-principles-of-web-app-performance\"\n  title: \"Principles of Web App Performance\"\n  raw_title: \"Principles of Web App Performance\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"Brighton Ruby 2020\"\n  date: \"2020-06-01\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2020/principles-of-web-app-performance-nate-berkopec/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2020/nate-principles-of-web-app-performance.mp4\"\n  description: |-\n    As one of (the?) best known folks working on Rails performance at speedshop.co Nate has some performance priorities he’d like to talk to you about.\n\n    Rails performance consultant at Speedshop\n\n- id: \"anjuan-aneika-managing-the-burnout-burndown\"\n  title: \"Managing the Burnout Burndown\"\n  raw_title: \"Managing the Burnout Burndown\"\n  speakers:\n    - Anjuan Simmons\n    - Aneika Simmons\n  event_name: \"Brighton Ruby 2020\"\n  date: \"2020-06-01\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2020/the-burnout-burndown-anjuan-aneika-simmons/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2020/anjuan-aneika-managing-the-burnout-burndown.mp4\"\n  description: |-\n    Engineering managers are, almost by definition, highly capable and strongly driven individuals. These traits are indispensable to success in leading software engineering teams, but they are also the very traits that make engineering managers susceptible to burn out. People who can get things done often find themselves overwhelmed by their to-do lists.\n\n    This talk will combine the understanding from the trenches of Anjuan Simmons (who has been an engineering manager for more than 20 years) with the academic understanding of his wife, Dr. Aneika Simmons. Together, they will provide a framework for reducing burnout and consistently keeping stress levels in a managed state.\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2022/event.yml",
    "content": "---\nid: \"brightonruby-2022\"\ntitle: \"Brighton Ruby 2022\"\nlocation: \"Brighton, UK\"\ndescription: |-\n  Thursday, 30th June, 2022, Brighton Dome\npublished_at: \"2022-06-30\"\nstart_date: \"2022-06-30\"\nend_date: \"2022-06-30\"\nkind: \"conference\"\nyear: 2022\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFBEB\"\nwebsite: \"https://brightonruby.com/2022\"\ncoordinates:\n  latitude: 50.8229402\n  longitude: -0.1362672\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2022/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2022/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"cookpad\"\n          website: \"https://careers.cookpad.com\"\n          slug: \"cookpad\"\n          logo_url: \"https://brightonruby.com/images/2022/sponsors/cookpad.svg\"\n\n        - name: \"FreeAgent\"\n          website: \"https://careers.freeagent.com\"\n          slug: \"FreeAgent\"\n          logo_url: \"https://brightonruby.com/images/2022/sponsors/freeagent.svg\"\n\n        - name: \"Bloom & Wild\"\n          website: \"https://www.bloomandwild.com/careers\"\n          slug: \"Bloom&Wild\"\n          logo_url: \"https://brightonruby.com/images/2022/sponsors/bloom_&_wild.svg\"\n\n        - name: \"Cleo\"\n          website: \"https://web.meetcleo.com/careers\"\n          slug: \"Cleo\"\n          logo_url: \"https://brightonruby.com/images/2022/sponsors/cleo.svg\"\n\n    - name: \"Supported by\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://shopify.com\"\n          slug: \"shopify\"\n          logo_url: \"https://brightonruby.com/images/2022/sponsors/shopify.svg\"\n\n        - name: \"Consonance\"\n          website: \"https://consonance.app/\"\n          slug: \"consonance\"\n          logo_url: \"https://brightonruby.com/images/2022/sponsors/consonance.svg\"\n\n        - name: \"GitHub\"\n          website: \"https://github.com/\"\n          slug: \"github\"\n          logo_url: \"https://brightonruby.com/images/2022/sponsors/github.svg\"\n\n        - name: \"Form3\"\n          website: \"https://form3.tech/\"\n          slug: \"form3\"\n          logo_url: \"https://brightonruby.com/images/2022/sponsors/form3.svg\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2022/videos.yml",
    "content": "---\n# Website: https://brightonruby.com/2022/\n# Website: https://web.archive.org/web/20220701042721/https://brightonruby.com/\n# Schedule: https://web.archive.org/web/20220701042721/https://brightonruby.com/\n\n- id: \"joel-hawksley-breaking-up-with-the-bundle\"\n  title: \"Breaking Up With The Bundle\"\n  raw_title: \"Breaking Up With The Bundle\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"Brighton Ruby 2022\"\n  date: \"2022-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2022/breaking-up-with-the-bundle-joel-hawksley/\"\n  video_id: \"https://videos.brightonruby.com/videos/2022/joel-hawksley-breaking-up-with-the-bundle.mp4\"\n  description: |-\n    Over the course of 14 years, the GitHub.com CSS bundle grew to over 40,000 lines of custom CSS. It became almost impossible to refactor. Visual regressions were common. In this talk, we’ll share an honest picture of our successes and failures as we’ve worked to break up with our CSS bundle by moving towards a component-driven UI architecture.\n\n    Joel’s a staff software engineer at GitHub, working on user interface architecture and strategy. He leads development of the ViewComponent framework.\n\n- id: \"kelly-sutton-you-had-me-at-lpush\"\n  title: \"You had me at LPUSH, a Sidekiq Love Story\"\n  raw_title: \"You had me at LPUSH, a Sidekiq love story\"\n  speakers:\n    - Kelly Sutton\n  event_name: \"Brighton Ruby 2022\"\n  date: \"2022-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2022/a-sidekiq-love-story-kelly-sutton/\"\n  video_id: \"https://videos.brightonruby.com/videos/2022/kelly-sutton-you-had-me-at-lpush.mp4\"\n  description: |-\n    Sidekiq, the popular Ruby job framework, moves billions of USD per year on behalf of 200,000 small businesses at Gusto, an American FinTech company. But every relationship is not without its trials. How did this library go from down on its luck to “bae” within one company?\n\n    In this talk, learn how to level-up your own usage of Sidekiq, avoid some of its pitfalls, set your databases on fire, teach your teammates Sidekiq’s best practices, and how to scale Sidekiq, whether you’re moving a few bucks or a few billion.\n\n    Kelly Sutton is a software engineer based in Seattle, WA, and works for Gusto.\n\n- id: \"tom-stuart-stop-ignoring-pattern-matching\"\n  title: \"Stop Ignoring Pattern Matching! It’s Really Good!\"\n  raw_title: \"Stop ignoring pattern matching! It’s really good!\"\n  speakers:\n    - Tom Stuart\n  event_name: \"Brighton Ruby 2022\"\n  date: \"2022-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2022/stop-ignoring-pattern-matching-tom-stuart/\"\n  video_id: \"https://videos.brightonruby.com/videos/2022/tom-stuart-stop-ignoring-pattern-matching.mp4\"\n  description: |-\n    Pattern matching was introduced as a major language feature in Ruby 2.7 and has been improved in subsequent releases, but not many people are using it yet.\n\n    It’s really helpful and can make your programs clearer, simpler, safer, or all three. So why aren’t you using it? You should totally use it! I’ll show you how.\n\n    Tom is a computer scientist, longtime Rubyist and Senior Staff Engineer at Shopify. He has taught optimising compilers at the University of Cambridge and written about technology for the Guardian. His book about computation theory in Ruby, “Understanding Computation”, is published by O’Reilly.\n\n- id: \"jemma-issroff-setting-and-getting-instance-variables\"\n  title: \"Cache me if you can: How instance variables work in CRuby\"\n  raw_title: \"Cache me if you can: How instance variables work in CRuby\"\n  speakers:\n    - Jemma Issroff\n  event_name: \"Brighton Ruby 2022\"\n  date: \"2022-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2022/how-instance-variables-work-in-cruby-jemma-issroff/\"\n  video_id: \"https://videos.brightonruby.com/videos/2022/jemma-issroff-setting-and-getting-instance-variables.mp4\"\n  description: |-\n    We all use instance variables practically every time we write Ruby code. Most of us do this without a second thought for how performant instance variables accesses are or what Ruby is doing behind the scenes.\n\n    In this talk, we’ll learn what actually happens each time we access an instance variable. We’ll start with the most naive possible implementation of instance variables, iterate on it until we learn what CRuby is doing today, including how instance variable caching works, and ultimately discuss a new idea for instance variable caching that CRuby could adopt: object shapes.\n\n    Jemma Issroff works on Shopify’s Ruby Infrastructure team. She is also a co-founder of WNB.rb, a women / non-binary Ruby community, a co-host on The Ruby on Rails Podcast, the author of both Ruby Weekly’s Tip of the Week, and an ebook about Ruby garbage collection.\n\n# Lunch\n\n- id: \"roberta-mataityte-a-framework-for-more-productive-debugging\"\n  title: \"A Framework For More Productive Debugging\"\n  raw_title: \"A framework for more productive debugging\"\n  speakers:\n    - Roberta Mataityte\n  event_name: \"Brighton Ruby 2022\"\n  date: \"2022-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2022/more-productive-debugging-roberta-mataityte/\"\n  video_id: \"https://videos.brightonruby.com/videos/2022/roberta-mataityte-a-framework-for-more-productive-debugging.mp4\"\n  description: |-\n    You can either try to guess your way out of a bug and potentially end up spending a large amount of time getting carried away and going off in unproductive directions.\n\n    Or you can make use of the 9 golden rules of debugging to track down pesky bugs systematically, in no time at all.\n\n    This is a talk inspired by a book by David J. Agans book, a forgotten classic, “Debugging: the 9 indispensable rules for finding even the most elusive software and hardware problems”.\n\n    Roberta is a Software Engineer at FutureLearn, a leading online education platform. Prior to working in technology she worked for the arts and film sector and has a keen interest in the cross section of art, culture and technology. These days when not learning, coding or debugging, she is probably trying to grow the perfect balcony tomatoes.\n\n- id: \"https://brightonruby.com/2022/an-archaeological-excavation-ten-year-old-rails-monolith-emma-barnes/\"\n  title: \"@consonance.dig(:past, :history) => An Archaeological Excavation of a ten-year-old Rails Monolith\"\n  raw_title: \"@consonance.dig(:past, :history) => An archaeological excavation of a ten-year-old Rails monolith\"\n  speakers:\n    - Emma Barnes\n  event_name: \"Brighton Ruby 2022\"\n  date: \"2022-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2022/an-archaeological-excavation-ten-year-old-rails-monolith-emma-barnes/\"\n  video_id: \"https://brightonruby.com/2022/an-archaeological-excavation-ten-year-old-rails-monolith-emma-barnes/\"\n  description: |-\n    You really had to be there. We didn’t record this, because it had “not for the Internet” stuff in it.\n\n    Consonance is a 10+ year old Rails monolith. Its CEO, Emma Barnes, finally gets some use out of her archaeology degree and digs into the code to see what artefacts lie within, and what we can learn from them.\n\n    Book publisher turned programmer. She runs generalproducts.co, makers of Consonance, as well as indie publisher Snowbooks, and she maintains schools publishing app Make Our Book on Side Project Fridays. She works in a first floor office in a market town in the Oxfordshire countryside, which attracts a local cat that visits through the window.\n\n- id: \"john-cinnamond-maybe-youre-not-my-type\"\n  title: \"Maybe You Aren’t My Type?\"\n  raw_title: \"Maybe You Aren’t My Type?\"\n  speakers:\n    - John Cinnamond\n  event_name: \"Brighton Ruby 2022\"\n  date: \"2022-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2022/maybe-you-arent-my-type-john-cinnamond/\"\n  video_id: \"https://videos.brightonruby.com/videos/2022/john-cinnamond-maybe-youre-not-my-type.mp4\"\n  description: |-\n    `nil`\n\n    Well that’s awkward. What do we do now? We can’t just carry on and pretend we have a value – that never ends well. Do we swap it out for a default value? Do we write a special program just for handling nil? Do we crash? Or do we rewrite everything from scratch in Haskell?\n\n    What can we learn about Ruby by thinking about a world where nil can never exist? And what can we learn about Haskell by thinking about a world where it can? And what can we learn about ourselves by recognising that both of these worlds are the world we live in.\n\n    John is a Lead Engineer at Form3, a payment technology company. When not coding in Go for a living John can probably be found learning Haskell, reading about mathematics, or having a nice sit down and thinking about what kind of thing programming is.\n\n- id: \"naomi-freeman-resilience\"\n  title: \"Resilience\"\n  raw_title: \"Resilience\"\n  speakers:\n    - Naomi Freeman\n  event_name: \"Brighton Ruby 2022\"\n  date: \"2022-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2022/resilience-naomi-freeman/\"\n  video_id: \"https://videos.brightonruby.com/videos/2022/naomi-freeman-resilience.mp4\"\n  description: |-\n    Once upon a time there was a pandemic, and Zoom parties and COVID leave. Now your team has been told to come back to work - as if these past two years were not work. How can we build resilience in our teams to help them through this transition?\n\n    Previously: Ruby dev (payments and infra). Women Who Code Data Science & Blockchain Fellow. CTO. Founder. etc. Currently: bridging business and tech as a Subject Matter Expert: Technical Management at Noroff University - Accelerate (Norway). Canadian living in Norway. I like cats.\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2023/event.yml",
    "content": "---\nid: \"brightonruby-2023\"\ntitle: \"Brighton Ruby 2023\"\nlocation: \"Brighton, UK\"\ndescription: |-\n  Friday 30th June, 2023, Brighton Dome\npublished_at: \"2023-06-30\"\nstart_date: \"2023-06-30\"\nend_date: \"2023-06-30\"\nkind: \"conference\"\nyear: 2023\nfeatured_background: \"#7F1D1D\"\nfeatured_color: \"#FFFBEB\"\nbanner_background: |-\n  linear-gradient(\n    to bottom,\n    #7F1D1D 70%,\n    #B91C1C 70%, #B91C1C 90%,\n    #0F172A 90%\n  )\nwebsite: \"https://brightonruby.com/2023\"\ncoordinates:\n  latitude: 50.8229402\n  longitude: -0.1362672\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2023/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2023/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"cookpad\"\n          website: \"https://careers.cookpad.com\"\n          slug: \"cookpad\"\n          logo_url: \"https://brightonruby.com/images/2023/sponsors/cookpad.svg\"\n\n        - name: \"Bloom & Wild\"\n          website: \"https://www.bloomandwild.com/careers\"\n          slug: \"bloomandwild\"\n          logo_url: \"https://brightonruby.com/images/2023/sponsors/bloom_&_wild.svg\"\n\n        - name: \"Simply Business\"\n          website: \"https://www.tech.sb/\"\n          slug: \"simplybusiness\"\n          logo_url: \"https://brightonruby.com/images/2023/sponsors/simply_business.svg\"\n\n        - name: \"Sorcer\"\n          website: \"https://sorcer.io\"\n          slug: \"sorcer\"\n          logo_url: \"https://brightonruby.com/images/2023/sponsors/sorcer.svg\"\n\n    - name: \"Silver\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Vonage\"\n          website: \"https://developer.vonage.com\"\n          slug: \"vonage\"\n          logo_url: \"https://brightonruby.com/images/2023/sponsors/vonage.svg\"\n\n    - name: \"Supported by\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://shopify.com\"\n          slug: \"shopify\"\n          logo_url: \"https://brightonruby.com/images/2023/sponsors/shopify.svg\"\n\n        - name: \"Consonance\"\n          website: \"https://consonance.app/\"\n          slug: \"consonance\"\n          logo_url: \"https://brightonruby.com/images/2023/sponsors/consonance.svg\"\n\n        - name: \"Theta Lake, Inc.\"\n          website: \"https://thetalake.com/\"\n          slug: \"theta_lake\"\n          logo_url: \"https://brightonruby.com/images/2023/sponsors/theta_lake.svg\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2023/videos.yml",
    "content": "---\n- id: \"eileen-uchitelle-the-magic-of-rails\"\n  title: \"The Magic of Rails\"\n  raw_title: \"The Magic of Rails\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  # thumbnail_xs: https://brightonruby.com/images/2023/photos/Eileen3_IMG1335.jpg\n  # thumbnail_sm: https://brightonruby.com/images/2023/photos/Eileen3_IMG1335.jpg\n  # thumbnail_md: https://brightonruby.com/images/2023/photos/Eileen3_IMG1335.jpg\n  # thumbnail_lg: https://brightonruby.com/images/2023/photos/Eileen3_IMG1335.jpg\n  # thumbnail_xl: https://brightonruby.com/images/2023/photos/Eileen3_IMG1335.jpg\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/the-magic-of-rails-eileen-uchitelle\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/eileen-uchitelle-the-magic-of-rails.mp4\"\n  slides_url: \"https://speakerdeck.com/eileencodes/brighton-ruby-2023-the-magic-of-rails\"\n  description: |-\n    We’ll look at the philosophy behind the framework as well as the overall structure of the components and explore some of the common patterns that Rails uses to build agnostic and beautiful interfaces, and the techniques it implements to hide complexity so you can focus on building your application.\n\n    By the end of this talk you’ll be more confident navigating the Rails codebase and better understand the patterns it uses to create the framework we all know and love. But Rails is so much more than its design and architecture. We’ll dive into my motivations for working on the framework and why the community is so important to the long term success of Rails.\n\n- id: \"nick-schwaderer-scarpe-diem\"\n  title: \"Scarpe Diem\"\n  raw_title: \"Scarpe Diem\"\n  speakers:\n    - Nick Schwaderer\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  # thumbnail_xs: https://brightonruby.com/images/2023/photos/Schwad5_IMG1394.jpg\n  # thumbnail_sm: https://brightonruby.com/images/2023/photos/Schwad5_IMG1394.jpg\n  # thumbnail_md: https://brightonruby.com/images/2023/photos/Schwad5_IMG1394.jpg\n  # thumbnail_lg: https://brightonruby.com/images/2023/photos/Schwad5_IMG1394.jpg\n  # thumbnail_xl: https://brightonruby.com/images/2023/photos/Schwad5_IMG1394.jpg\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/scarpe-diem-nick-schwaderer\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/nick-schwaderer-scarpe-diem.mp4\"\n  description: |-\n    Why the Lucky Stiff, one of the most beloved members of the historical Ruby community, is widely known for his seminal Poignant Guide to Ruby. His second-most ambitious writing, NOBODY KNOWS SHOES, is lesser-known. This text was the manual for an amazing set of tools _why developed in 2007 called Shoes.rb.\n\n    With pure Ruby, married with _why’s supreme taste in APIs, one could easily write desktop applications and package them for Mac, Windows or Linux. In 2007! Imagine writing useful native applications and sharing them with your friend who didn’t have Ruby on their machine nor any technical knowledge. Dear reader, your speaker in fact used Shoes.rb to build Desktop apps before using Rails to write Webapps.\n\n    Over the years, Shoes has fought off the endless wave of bitrot. An effort to rewrite Shoes in JRuby stalled in 2017. Existing Shoes is difficult, likely impossible, to run.\n\n    Nick will walk you through Shoes history; and cover his work on a new Shoes.rb implementation to bring Shoes back to life on modern tooling with Scarpe. (Italian for “Shoes”)\n\n- id: \"kaitlyn-tierney-librarians-guide-to-documentation\"\n  title: \"Librarian's Guide to Documentation\"\n  raw_title: \"Librarian's Guide to Documentation\"\n  speakers:\n    - Kaitlyn Tierney\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/librarians-guide-to-documentation-kaitlyn-tierney\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/kaitlyn-tierney-librarians-guide-to-documentation.mp4\"\n  description: |-\n    Learn how to leverage librarian skills to create and maintain internal documentation that works for you.\n\n    Improve technical decision making by fostering a culture of documentation excellence and inspiring clear, effective written communication with a few simple practices.\n\n- id: \"noah-gibbs-when-should-you-not-use-rails\"\n  title: \"When Should You Not Use Rails\"\n  raw_title: \"When Should You Not Use Rails\"\n  speakers:\n    - Noah Gibbs\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/when-should-you-not-use-rails-noah-gibbs\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/noah-gibbs-when-should-you-not-use-rails.mp4\"\n  description: |-\n    Rails is a great tool for a lot of projects, but not every project.\n\n    Be the senior engineer you dream of, and learn the long answer to “should we use Rails?” You can say “it depends” with the greatest of authority!\n\n- id: \"paul-battley-twenty-years-of-ruby-in-five-minutes\"\n  title: \"Lightning Talk: Twenty Years of Ruby in Five Minutes\"\n  raw_title: \"Lightning Talk: Twenty Years of Ruby in Five Minutes\"\n  speakers:\n    - Paul Battley\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/twenty-years-of-ruby-in-five-minutes-paul-battley\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/paul-battley-twenty-years-of-ruby-in-five-minutes.mp4\"\n  description: |-\n    I’ve been working with Ruby since the early 2000s. Ruby has changed a lot in that time, but we don’t always remember how much. Let’s rewrite a short program so that it runs in a twenty-year-old version of Ruby and see how much syntax and performance has changed for the better in twenty years.\n\n    Ruby is being actively developed, and getting better over time, but even when it was more limited and slower it was still a viable language for development.\n\n    There is always room for improvement. Let this talk illuminate newer programmers and remind grizzled veterans. Be grateful for those who have got us here and optimistic about using Ruby in the future.\n\n- id: \"hana-harencarova-five-things-i-love-about-ruby\"\n  title: \"Lightning Talk: Five Things I Love About Ruby\"\n  raw_title: \"Lightning Talk: Five Things I Love About Ruby\"\n  speakers:\n    - Hana Harencarova\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/five-things-i-love-about-ruby-hana-harencarova\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/hana-harencarova-five-things-i-love-about-ruby.mp4\"\n  description: |-\n    The talk caters to both newcomers and veterans of the Ruby world and offers a humorous yet informative perspective on the language and its community. It will cover various Ruby events and initiatives, diversity of the Ruby community, and more. Let’s appreciate our Ruby world together.\n\n- id: \"lizz-jennings-ux-doesnt-equal-front-end\"\n  title: \"Lightning Talk: UX Doesn't Equal Front-End\"\n  raw_title: \"Lightning Talk: UX Doesn't Equal Front-End\"\n  speakers:\n    - Lizz Jennings\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/ux-doesnt-equal-front-end-lizz-jennings\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/lizz-jennings-ux-doesnt-equal-front-end.mp4\"\n  description: |-\n    When people think of usability improvements, they often think of the front end. But when you really understand your domain, using the power of the back end can be the best way to save your users’ time.\n\n    A book app is often a starter example for learning to code. Using an example audiobook, I show how quickly a basic book record becomes complex.\n\n    A side quest to explain Ranganathan’s five laws of library science and how well they translate to building web apps (particularly law 4 - “Save the time of the ~~reader~~ user”).\n\n- id: \"jade-dickinson-how-to-write-a-custom-rubocop-rule\"\n  title: \"Lightning Talk: How to Write a Custom Rubocop Rule\"\n  raw_title: \"Lightning Talk: How to Write a Custom Rubocop Rule\"\n  speakers:\n    - Jade Dickinson\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/how-to-write-a-custom-rubocop-rule-jade-dickinson\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/jade-dickinson-how-to-write-a-custom-rubocop-rule.mp4\"\n  description: |-\n    You want to enforce a standard in your codebase, like making sure a company name is in title case. So you add “always check for correct capitalisation” to your pull request guidelines. Over time, people forget to check and mistakes sneak in.\n\n    But wait - there’s an easier way! I’ll show you how you can write a custom Rubocop rule to check for you. So if someone breaks the rule, your CI tooling will flag it up so they can fix it, freeing you up to focus on more important things.\n\n- id: \"maple-ong-beware-job-smearing\"\n  title: \"Lightning Talk: Beware Job Smearing\"\n  raw_title: \"Lightning Talk: Beware Job Smearing\"\n  speakers:\n    - Maple Ong\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/beware-job-smearing-maple-ong\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/maple-ong-beware-job-smearing.mp4\"\n  description: |-\n    What does Matthew McConaughey have in common with an uncomfortable sounding procedure and job frameworks?\n\n    Join for a “no slides”, five minute, investigation into what not to do with Sidekiq.\n\n- id: \"tim-riley-livin-la-vida-hanami\"\n  title: \"Livin' la Vida Hanami\"\n  raw_title: \"Livin' la Vida Hanami\"\n  speakers:\n    - Tim Riley\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/livin-la-vida-hanami-tim-riley\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/tim-riley-livin-la-vida-hanami.mp4\"\n  description: |-\n    You’re into applications Fast tests and method calls I feel a premonition This gem’s gonna stun you all\n\n    Upside, inside out, Hanami 2.0 is out!\n\n    This release brings new levels of polish and power to a framework that you can use for Ruby apps of all shapes and sizes.\n\n    Together we’ll discover what goes into living the life of real production Hanami app, and how Hanami apps can remain a joy to develop even as they grow.\n\n    Once you’ve had a taste of it you’ll never be the same! Come on!\n\n- id: \"nadia-odunayo-the-case-of-the-vanished-variable\"\n  title: \"The Case Of The Vanished Variable\"\n  raw_title: \"The Case Of The Vanished Variable\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/the-case-of-the-vanished-variable-nadia-odunayo\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/nadia-odunayo-the-case-of-the-vanished-variable.mp4\"\n  description: |-\n    After a stressful couple of days at work, Deirdre Bug is looking forward to a quiet evening in. But her plans are thwarted when the phone rings. “I know I’m the last person you want to hear from…but…I need your help!”\n\n    Follow Deirdre as she embarks on an adventure that features a looming Demo Day with serious prize money, a trip inside the walls of one of the Ruby community’s most revered institutions, and some broken code that appears to be much more simple than meets the eye.\n\n- id: \"joe-hart-new-game\"\n  title: \"New Game\"\n  raw_title: \"New Game\"\n  speakers:\n    - Joe Hart\n  event_name: \"Brighton Ruby 2023\"\n  date: \"2023-06-30\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2023/new-game-joe-hart\"\n  video_id: \"https://videos.brightonruby.com/videos/2023/joe-hart-new-game.mp4\"\n  description: |-\n    Fun and interactive games abound in this talk come work in progress interactive entertainment show. You’ll need yourself, a phone and good vibes.\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2024/cfp.yml",
    "content": "---\n- link: \"https://forms.reform.app/goodscary/brighton-ruby-2024-cfp/gci0d6\"\n  open_date: \"2024-01-21\"\n  close_date: \"2024-02-29\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2024/event.yml",
    "content": "---\nid: \"brightonruby-2024\"\ntitle: \"Brighton Ruby 2024\"\nlocation: \"Brighton, UK\"\ndescription: |-\n  Friday, 28th June, 2024, Brighton Dome\npublished_at: \"2024-11-03\"\nstart_date: \"2024-06-30\"\nend_date: \"2024-06-30\"\nkind: \"conference\"\nyear: 2024\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFBEB\"\nfeatured_color: \"#0F1729\"\nwebsite: \"https://brightonruby.com/2024\"\ncoordinates:\n  latitude: 50.823661\n  longitude: -0.138391\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2024/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2024/schedule.yml",
    "content": "# Schedule: Brighton Ruby\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-06-28\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Welcome\n\n      - start_time: \"09:45\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Coffee\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Ice Cream\n\n      - start_time: \"15:30\"\n        end_time: \"15:36\"\n        slots: 1\n\n      - start_time: \"15:36\"\n        end_time: \"15:42\"\n        slots: 1\n\n      - start_time: \"15:42\"\n        end_time: \"15:48\"\n        slots: 1\n\n      - start_time: \"15:48\"\n        end_time: \"15:54\"\n        slots: 1\n\n      - start_time: \"15:54\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - title: \"Drinks\"\n            description: |-\n              Medium & Soft ones, in the Bar\n\ntracks: []\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold\"\n      description: |-\n        Gold level sponsors of the 2024 Brighton Ruby Conference\n      level: 1\n      sponsors:\n        - name: \"Simply Business\"\n          website: \"https://www.tech.sb/\"\n          slug: \"SimplyBusiness\"\n          logo_url: \"https://brightonruby.com/images/2024/sponsors/simply_business.svg\"\n\n        - name: \"Sorcer\"\n          website: \"https://sorcer.io\"\n          slug: \"Sorcer\"\n          logo_url: \"https://brightonruby.com/images/2024/sponsors/sorcer.svg\"\n\n        - name: \"Mindful Chef\"\n          website: \"https://www.mindfulchef.com/\"\n          slug: \"MindfulChef\"\n          logo_url: \"https://brightonruby.com/images/2024/sponsors/mindful_chef.svg\"\n\n        - name: \"Bloom & Wild\"\n          website: \"https://www.bloomandwild.com/careers\"\n          slug: \"Bloom&Wild\"\n          logo_url: \"https://brightonruby.com/images/2024/sponsors/bloom_&_wild.svg\"\n\n        - name: \"Cleo\"\n          website: \"https://web.meetcleo.com/careers\"\n          slug: \"Cleo\"\n          logo_url: \"https://brightonruby.com/images/2024/sponsors/cleo.svg\"\n\n    - name: \"Silver\"\n      description: |-\n        Silver level sponsors of the 2024 Brighton Ruby Conference\n      level: 2\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://appsignal.com\"\n          slug: \"AppSignal\"\n          logo_url: \"https://brightonruby.com/images/2024/sponsors/appsignal.svg\"\n\n        - name: \"20i\"\n          website: \"https://www.20i.com/managed-hosting\"\n          slug: \"20i\"\n          logo_url: \"https://brightonruby.com/images/2024/sponsors/20i.svg\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2024/venue.yml",
    "content": "---\nname: \"Brighton Dome\"\n\naddress:\n  street: \"Church St\"\n  city: \"Brighton and Hove, Brighton\"\n  postal_code: \"BN1 1UE\"\n  country: \"United Kingdom\"\n  country_code: \"GB\"\n  display: \"Church St, Brighton and Hove, Brighton BN1 1UE, United Kingdom\"\n\ncoordinates:\n  latitude: 50.823661\n  longitude: -0.138391\n\nmaps:\n  google: \"https://goo.gl/maps/o5YdP27AZ8jNWdGT7\"\n  apple: \"https://maps.apple.com/?address=Brighton,%20BN1%201UE,%20England&auid=15913380656425988054&ll=50.823661,-0.138391&lsp=9902&q=Brighton%20Dome\"\n\nhotels:\n  - name: \"My Brighton\"\n    kind: \"Speaker Hotel\"\n    address:\n      street: \"17 Jubilee Street\"\n      city: \"Brighton and Hove\"\n      region: \"England\"\n      postal_code: \"BN1 1GE\"\n      country: \"United Kingdom\"\n      country_code: \"GB\"\n      display: \"17 Jubilee St, Brighton, BN1 1GE, England\"\n    coordinates:\n      latitude: 50.824485\n      longitude: -0.13862\n    maps:\n      google: \"https://maps.app.goo.gl/BkW4eSnUjqwk8tV8A\"\n      apple:\n        \"https://maps.apple.com/place?address=17%20Jubilee%20St,%20Brighton,%20BN1%201GE,%20England&coordinate=50.824485,-0.138620&name=My%20Brighton&place-id=IE506A59AE9FD07F&map=\\\n        transit\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2024/videos.yml",
    "content": "---\n- id: \"nadia-odunayo-getting-to-two-million-users-as-a-one-woman-dev-team\"\n  title: \"Getting to Two Million Users as a One Woman Dev Team\"\n  raw_title: \"Getting to Two Million Users as a One Woman Dev Team\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/getting-to-2-million-users-as-a-one-woman-dev-team/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/nadia-odunayo-getting-to-two-million-users-as-a-one-woman-dev-team.mp4\"\n  description: |-\n    Nadia Odunayo has been so often the smiling face on the door of this event, but did you know she’s the founder and (more impressively!) one woman development team behind The StoryGraph, a reading community of over a million book lovers. Her story is one of grit, insight and technical insights into what it takes to execute on the “one person framework”.\n\n    Nadia Odunayo is the founder and CEO of The StoryGraph, the app that helps you to track your reading and choose which book to read next based on your mood and favorite topics and themes. She previously worked at Pivotal Labs as a software engineer and originally learnt to code at Makers Academy in London. In her spare time she loves to take dance class and, naturally, read!\n\n- id: \"nicky-thompson-making-work-life-less-stressful-by-making-better-decisions\"\n  title: \"Making Work (& Life) Less Stressful by Making Better Decisions\"\n  raw_title: \"Making Work (& Life) Less Stressful by Making Better Decisions\"\n  speakers:\n    - Nicky Thompson\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/making-work-and-life-less-stressful-by-making-better-decisions-nicky-thomson/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/nicky-thompson-making-work-life-less-stressful-by-making-better-decisions.mp4\"\n  description: |-\n    Making mistakes is one way to learn. But no matter how many times someone says that to me, it still feels bad when it happens. This talk shares some ways to help you make fewer mistakes by making better decisions.\n\n    But there are tools and frameworks that you can use to sense-check when you’re about to make a difficult choice, to help you have the best possible outcome (or to learn better from a choice that in hindsight you think was wrong).\n\n    This talk is aimed at engineers, tech leads, managers, humans - anyone who makes decisions. Making better decisions is a skill that you can improve on, and this talk will introduce some ways to do that.\n\n    Nicky is a Principal Technologist at dxw, providing technical leadership and support to the Technology Team and dxw’s clients. She has spent more than two decades as a freelance and in-house developer, delivering successful projects for clients ranging from global banks and major publishing houses to indie storytelling agencies. She’s worked with designers all over the world, making beautiful websites that work for everyone. Offline, Nicky enjoys watching bad TV and learning new stuff: this year it’s a serious sewing/dressmaking habit.\n\n- id: \"daniel-vartanov-ractors-are-rubys-goroutines\"\n  title: \"Ractors are Ruby’s Goroutines\"\n  raw_title: \"Ractors are Ruby’s Goroutines\"\n  speakers:\n    - Daniel Vartanov\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/ractors-are-rubys-goroutines/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/daniel-vartanov-ractors-are-rubys-goroutines.mp4\"\n  description: |-\n    Many of us know that “ruby is slow” or that it doesn’t have a good concurrency story. Or does it?\n\n    ex-Deliveroo, Founding Engineer @ Veeqo (acquired by Amazon). CTO, Technical co-founder, Software Architect, Staff Engineer, Tech Lead. Distributed consensus geek. Love being a contractor occasionally.\n\n- id: \"mohamed-hassan-litestack-unleashing-the-power-of-sqlite-for-ruby-applications\"\n  title: \"Litestack: Unleashing the Power of SQLite for Ruby Applications\"\n  raw_title: \"Litestack: Unleashing the Power of SQLite for Ruby Applications\"\n  speakers:\n    - Mohamed Hassan\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/litestack-unleashing-the-power-of-sqlite-for-ruby-applications/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/mohamed-hassan-litestack-unleashing-the-power-of-sqlite-for-ruby-applications.mp4\"\n  description: |-\n    SQLite is having a moment in the Rails community so I thought, who better to cover its myriad production uses than the primary author of the LiteStack series of gems, Mohamed Hassan.\n\n    Passionate software developer who is interested in solving hard problems and producing robust software.\n\n- id: \"karen-jex-database-troubleshooting-for-developers\"\n  title: \"Database Troubleshooting for Developers\"\n  raw_title: \"Database Troubleshooting for Developers\"\n  speakers:\n    - Karen Jex\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/database-troubleshooting-for-developers/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/karen-jex-database-troubleshooting-for-developers.mp4\"\n  description: |-\n    What do you do if something goes wrong with your database? Maybe your queries are running slowly, you’re getting a weird error, or an important table seems to have disappeared. If you don’t have the luxury of a dedicated DBA, you’ll probably need to figure out what’s going wrong and fix it yourself. Let’s look at some common database issues and give you the tools you need to investigate and fix them.\n\n    Playing with (PostgreSQL) databases, keen cyclist, Mum to two amazing humans\n\n- id: \"chris-oliver-mapping-concepts-into-code\"\n  title: \"Mapping Concepts into Code\"\n  raw_title: \"Mapping Concepts into Code\"\n  speakers:\n    - Chris Oliver\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/mapping-concepts-into-code/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/chris-oliver-mapping-concepts-into-code.mp4\"\n  description: |-\n    Implementing a feature like “notifications” in an app sounds simple, right? As you dig in to problems like this, you’ll realize the complexity that lies below the surface.\n\n    In this talk, we’ll walk through designing a feature like Notifications and how naming, DSLs, metaprogramming, and a bunch of other small decisions can make code feel delightful to use. Plus, we’ll take a look at some of the decisions along the way that didn’t turn out so well, analyze why they didn’t work, and how we can improve them.\n\n    A software developer based in St. Louis, Missouri. I’m the founder of GoRails, a company focused on helping Ruby on Rails developers learn, build, and deploy their ideas.\n\n- id: \"murad-iusufov-why-i-dont-miss-rspec\"\n  title: \"Lightning Talk: Why I Don’t Miss RSpec\"\n  raw_title: \"⚡️ Why I Don’t Miss RSpec\"\n  speakers:\n    - Murad Iusufov\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/why-i-dont-miss-rspec/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/murad-iusufov-why-i-dont-miss-rspec.mp4\"\n  description: |-\n    Lots of people in Ruby community choose RSpec as the default without really considering its drawbacks. I feel like not much is being done to popularise other test frameworks. Cleo is a fairly successful project that has used Minitest since its inception in 2016, and I would love to share this success story from a perspective of someone who hadn’t professionally worked with Minitest before joining Cleo.\n\n    Using tech to make life better for folks who really need it. Over 10 years of experience in software engineering (not all of them were paid).\n\n- id: \"matt-rayner-resuscitating-an-abandoned-rails-application\"\n  title: \"Lightning Talk: Resuscitating an Abandoned Rails Application\"\n  raw_title: \"⚡️ Resuscitating an Abandoned Rails Application\"\n  speakers:\n    - Matt Rayner\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/resuscitating-an-abandoned-rails-application/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/matt-rayner-resuscitating-an-abandoned-rails-application.mp4\"\n  description: |-\n    So, you’ve joined a new company to ‘support’ and ‘upgrade’ a legacy application. One that’s not been updated until 2018, and began life in 2014. Ruby 2 and Rails 5, up to Ruby 3.3 and Rails 7. How hard can it be?\n\n    I’m Matt Rayner, a talented and dedicated full stack, polyglot engineer. I’m looking for a challenging environment to test and improve my skills. I love learning new things and am an early adopter of bleeding edge technologies. Outside of work I’m involved in volunteering and a number of side projects. Everything from training students in multimedia and design skills, through to Give Cat - a bookmarklet that replaces all the images on a website with pictures of cats (what more could you want, right?).\n\n- id: \"richard-brooke-java-is-for-platonists-ruby-is-for-aristotelians\"\n  title: \"Lightning Talk: Java is for Platonists, Ruby is for Aristotelians\"\n  raw_title: \"⚡️ Java is for Platonists, Ruby is for Aristotelians\"\n  speakers:\n    - Richard Brooke\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/java-is-for-platonists-ruby-is-for-aristotelians/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/richard-brooke-java-is-for-platonists-ruby-is-for-aristotelians.mp4\"\n  description: |-\n    A different philosophy lies behind Ruby compared with Java when it comes to conceptualising the world. Which one works for you?\n\n    Ruby Developer / Software Engineer / Troubleshooter / 🐞 Debugger / 🛤️ Ruby on Rails developer / 🏢 Software Architect / 🗣 Event speaker - helped over 30 businesses use IT successfully over 30 years\n\n- id: \"frederic-wong-the-f-word\"\n  title: \"Lightning Talk: The F Word\"\n  raw_title: \"⚡️ The F Word\"\n  speakers:\n    - Frederic Wong\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/the-f-word/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/frederic-wong-the-f-word.mp4\"\n  description: |-\n    Using his own experience, we’ll debunk the myth that failure is the end of the world for engineers. By going through one of his own failures, we’ll look at his reaction to it and how learning from it can lead to innovation and growth, benefiting everyone from managers to junior engineers.\n\n    Let’s embrace failure together.\n\n    Currently working as a software engineer at Simply Business. I am deeply passionate about passing on knowledge to the team, as well as creating simple solutions that our customers love and trust.\n\n- id: \"chris-howlett-pursuing-pointlessness\"\n  title: \"Lightning Talk: Pursuing Pointlessness\"\n  raw_title: \"⚡️ Pursuing Pointlessness\"\n  speakers:\n    - Chris Howlett\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/pursuing-pointlessness/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/chris-howlett-pursuing-pointlessness.mp4\"\n  description: |-\n    We spend our days coding for work. Why would we spend our spare time doing it too?\n\n    Extolling the virtues of (seemingly-pointless) side projects. Encouraging engineers especially, but anyone who might want to pick up programming, to try unfamiliar languages and write… anything that sounds fun! It’s a great way of learning things, including picking up tips from other languages’ paradigms.\n\n    Rubyist, actor, gamer, DM, mathematician, archer, serial procrastinator. Getting rapidly lefter with age. Was on #OnlyConnect once\n\n- id: \"marco-roth-revisiting-the-hotwire-landscape-after-turbo-8\"\n  title: \"Revisiting the Hotwire Landscape after Turbo 8\"\n  raw_title: \"Revisiting the Hotwire Landscape after Turbo 8\"\n  speakers:\n    - Marco Roth\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/revisiting-the-hotwire-landscape-after-turbo-8/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/marco-roth-revisiting-the-hotwire-landscape-after-turbo-8.mp4\"\n  slides_url: \"https://speakerdeck.com/marcoroth/the-hotwire-landscape-after-turbo-8-at-brighton-ruby-2024\"\n  description: |-\n    Hotwire has significantly altered the landscape of building interactive web applications with Ruby on Rails, marking a pivotal evolution toward seamless Full-Stack development.\n\n    With the release of Turbo 8, the ecosystem has gained new momentum, influencing how developers approach application design and interaction.\n\n    Rubyist, Full-Stack Devloper and Open Source Contributor\n\n- id: \"drew-bragg-who-wants-to-be-a-ruby-engineer\"\n  title: \"Who Wants to be a Ruby Engineer?\"\n  raw_title: \"Who Wants to be a Ruby Engineer?\"\n  speakers:\n    - Drew Bragg\n  kind: \"gameshow\"\n  event_name: \"Brighton Ruby 2024\"\n  date: \"2024-06-28\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2024/who-wants-to-be-a-ruby-engineer/\"\n  video_provider: \"mp4\"\n  video_id: \"https://videos.brightonruby.com/videos/2024/drew-bragg-who-wants-to-be-a-ruby-engineer.mp4\"\n  description: |-\n    The Ruby community’s gameshow! The video is just the intro, try and catch this live if you can.\n\n    Drew is a Senior Product Developer at Podia. He is the host of the monthly podcast Code and the Coding Coders who Code it, and a co-organizer of Philly.rb, the Philadelphia Rubyist meetup. When he isn’t hunting for weird Ruby syntax, he enjoys playing Ice Hockey, playing board games with his wife and daughter, and trail running with his dog, named Matz of course.\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2025/cfp.yml",
    "content": "---\n- link: \"https://forms.reform.app/goodscary/lightning-talks-at-brighton-ruby-2025-cfp/gci0d6\"\n  open_date: \"2025-03-10\"\n  close_date: \"2025-03-31\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2025/event.yml",
    "content": "---\nid: \"brightonruby-2025\"\ntitle: \"Brighton Ruby 2025\"\nlocation: \"Brighton, UK\"\ndescription: |-\n  Thursday 19th June, 2025, Brighton Dome\npublished_at: \"2025-11-20\"\nstart_date: \"2025-06-19\"\nend_date: \"2025-06-19\"\nkind: \"conference\"\nyear: 2025\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFBEB\"\nfeatured_color: \"#0F1729\"\nwebsite: \"https://brightonruby.com/2025/\"\ncoordinates:\n  latitude: 50.823661\n  longitude: -0.138391\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2025/schedule.yml",
    "content": "---\ndays:\n  - name: \"Brighton Ruby 2025\"\n    date: \"2025-06-19\"\n    grid:\n      - start_time: \"08:15\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Registration & Breakfast\n\n      - start_time: \"09:15\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Coffee\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:45\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:45\"\n        end_time: \"13:50\"\n        slots: 1\n\n      - start_time: \"13:50\"\n        end_time: \"14:05\"\n        slots: 1\n\n      - start_time: \"14:05\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:15\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Ice Cream\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:30\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"18:30\"\n        slots: 1\n        items:\n          - Drinks\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsored by\"\n      description: |-\n        Main sponsors for Brighton Ruby Conference 2025\n      level: 1\n      sponsors:\n        - name: \"Simply Business\"\n          website: \"https://www.simplybusiness.co.uk/about-us/careers/tech/\"\n          slug: \"SimplyBusiness\"\n          logo_url: \"https://brightonruby.com/images/2025/sponsors/simply_business.svg\"\n\n        - name: \"Bloom & Wild\"\n          website: \"https://www.bloomandwild.com/careers\"\n          slug: \"BloomAndWild\"\n          logo_url: \"https://brightonruby.com/images/2025/sponsors/bloom_&_wild.svg\"\n\n        - name: \"Henry Schein One\"\n          website: \"https://careers.henryscheinone.co.uk\"\n          slug: \"HenryScheinOne\"\n          logo_url: \"https://brightonruby.com/images/2025/sponsors/henry_schein_one.svg\"\n\n    - name: \"Also helped by\"\n      description: |-\n        Additional sponsors for Brighton Ruby Conference 2025\n      level: 2\n      sponsors:\n        - name: \"Sorcer\"\n          website: \"https://sorcer.io/\"\n          slug: \"Sorcer\"\n          logo_url: \"https://brightonruby.com/images/2025/sponsors/sorcer.svg\"\n\n        - name: \"Harvest\"\n          website: \"https://getharvest.com\"\n          slug: \"Harvest\"\n          logo_url: \"https://brightonruby.com/images/2025/sponsors/harvest.svg\"\n\n        - name: \"Heroku\"\n          website: \"https://heroku.com\"\n          slug: \"Heroku\"\n          logo_url: \"https://brightonruby.com/images/2025/sponsors/heroku.svg\"\n\n        - name: \"37signals\"\n          website: \"https://37signals.com\"\n          slug: \"37signals\"\n          logo_url: \"https://brightonruby.com/images/2025/sponsors/37signals.svg\"\n\n        - name: \"FreeAgent\"\n          website: \"https://freeagent.com\"\n          slug: \"FreeAgent\"\n          logo_url: \"https://brightonruby.com/images/2025/sponsors/freeagent.svg\"\n\n        - name: \"Scan\"\n          website: \"https://scan.com\"\n          slug: \"Scan\"\n          logo_url: \"https://brightonruby.com/images/2025/sponsors/scan.svg\"\n\n        - name: \"AppSignal\"\n          website: \"https://appsignal.com\"\n          slug: \"AppSignal\"\n          logo_url: \"https://brightonruby.com/images/2025/sponsors/appsignal.svg\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2025/venue.yml",
    "content": "---\nname: \"Brighton Dome\"\n\naddress:\n  street: \"Church St\"\n  city: \"Brighton and Hove, Brighton\"\n  postal_code: \"BN1 1UE\"\n  country: \"United Kingdom\"\n  country_code: \"GB\"\n  display: \"Church St, Brighton and Hove, Brighton BN1 1UE, United Kingdom\"\n\ncoordinates:\n  latitude: 50.823661\n  longitude: -0.138391\n\nmaps:\n  google: \"https://goo.gl/maps/o5YdP27AZ8jNWdGT7\"\n  apple: \"https://maps.apple.com/?address=Brighton,%20BN1%201UE,%20England&auid=15913380656425988054&ll=50.823661,-0.138391&lsp=9902&q=Brighton%20Dome\"\n\nhotels:\n  - name: \"My Brighton\"\n    kind: \"Speaker Hotel\"\n    address:\n      street: \"17 Jubilee Street\"\n      city: \"Brighton and Hove\"\n      region: \"England\"\n      postal_code: \"BN1 1GE\"\n      country: \"United Kingdom\"\n      country_code: \"GB\"\n      display: \"17 Jubilee St, Brighton, BN1 1GE, England\"\n    coordinates:\n      latitude: 50.824485\n      longitude: -0.13862\n    maps:\n      google: \"https://maps.app.goo.gl/BkW4eSnUjqwk8tV8A\"\n      apple:\n        \"https://maps.apple.com/place?address=17%20Jubilee%20St,%20Brighton,%20BN1%201GE,%20England&coordinate=50.824485,-0.138620&name=My%20Brighton&place-id=IE506A59AE9FD07F&map=\\\n        transit\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2025/videos.yml",
    "content": "---\n- title: \"Welcome\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Andy Croll\n  id: \"andy-croll-brighton-ruby-2025\"\n  video_id: \"andy-croll-brighton-ruby-2025\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibkuxdbfacbfshds7ypnztpvjnpie6pljcgc2h3xebhetpkdeqzpi@jpeg\"\n  thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibkuxdbfacbfshds7ypnztpvjnpie6pljcgc2h3xebhetpkdeqzpi@jpeg\"\n  thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibkuxdbfacbfshds7ypnztpvjnpie6pljcgc2h3xebhetpkdeqzpi@jpeg\"\n  thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibkuxdbfacbfshds7ypnztpvjnpie6pljcgc2h3xebhetpkdeqzpi@jpeg\"\n  thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibkuxdbfacbfshds7ypnztpvjnpie6pljcgc2h3xebhetpkdeqzpi@jpeg\"\n  description: |-\n    Andy opens Brighton Ruby 2025 with a welcome address.\n\n- title: \"Machines That Talk About Themselves\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Rosa Gutiérrez\n  id: \"rosa-gutierrez-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/rosa-gutierrez-machines-that-talk-about-themselves.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/machines-that-talk-about-themselves-rosa-gutierrez/\"\n  thumbnail_xs: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/709/145/158/247/791/small/eec438e4850f6bb8.jpg\"\n  thumbnail_sm: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/709/145/158/247/791/small/eec438e4850f6bb8.jpg\"\n  thumbnail_md: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/709/145/158/247/791/small/eec438e4850f6bb8.jpg\"\n  thumbnail_lg: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/709/145/158/247/791/original/eec438e4850f6bb8.jpg\"\n  thumbnail_xl: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/709/145/158/247/791/original/eec438e4850f6bb8.jpg\"\n  description: |-\n    Rosa loves learning languages, both for computers and humans, mathematics and theoretical Computer Science. She is based in Madrid, Spain, and has worked as a principal programmer at 37signals since 2017 where she recently was the primary creator of Solid Queue.\n\n- title: \"Beyond Type Checking\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Emily Samp\n  id: \"emily-samp-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/emily-samp-beyond-type-checking.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/beyond-type-checking-emily-samp/\"\n  thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreiho322olr5fvaubfohlhtfcr2ywk2cyzaed54ajqasmm5oan3o65u@jpeg\"\n  thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreiho322olr5fvaubfohlhtfcr2ywk2cyzaed54ajqasmm5oan3o65u@jpeg\"\n  thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreiho322olr5fvaubfohlhtfcr2ywk2cyzaed54ajqasmm5oan3o65u@jpeg\"\n  thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreiho322olr5fvaubfohlhtfcr2ywk2cyzaed54ajqasmm5oan3o65u@jpeg\"\n  thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreiho322olr5fvaubfohlhtfcr2ywk2cyzaed54ajqasmm5oan3o65u@jpeg\"\n  description: |-\n    Many Ruby developers have remained skeptical of type checking, viewing it as unnecessary complexity in a language celebrated for its simplicity and flexibility. Behind the scenes, however, type checking advancements are driving dramatic improvements to Ruby developer tools.\n\n    In this talk, we’ll explore how static analysis has the potential to enable Ruby developer tooling that is as intelligent, accurate, and responsive as state-of-the-art tooling for other languages. We’ll learn how these improvements will eventually benefit all Ruby developers — typing enthusiasts or not — and discover why the entire community should be excited about the era of Ruby developer tooling that’s now on the horizon.\n\n- title: \"Defending Your Rails App\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Julia López\n  id: \"julia-lopez-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/julia-lopez-defending-your-rails-app.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/defending-your-rails-app-julia-lopez/\"\n  thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreifmpgvsuapiqfuwxz5ee3kfcexqh5dfkkas4yulimmxtgvhbzdm3i@jpeg\"\n  thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreifmpgvsuapiqfuwxz5ee3kfcexqh5dfkkas4yulimmxtgvhbzdm3i@jpeg\"\n  thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreifmpgvsuapiqfuwxz5ee3kfcexqh5dfkkas4yulimmxtgvhbzdm3i@jpeg\"\n  thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreifmpgvsuapiqfuwxz5ee3kfcexqh5dfkkas4yulimmxtgvhbzdm3i@jpeg\"\n  thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreifmpgvsuapiqfuwxz5ee3kfcexqh5dfkkas4yulimmxtgvhbzdm3i@jpeg\"\n  slides_url: \"https://speakerdeck.com/yukideluxe/defending-your-rails-app\"\n  description: |-\n    This talk goes beyond classic security topics like XSS and CSRF, and focuses on how to defend Rails applications from real-world abuse and how Harvest leverages on the rack-attack gem to achive so.\n\n- title: \"Fake Minds Think Alike\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Valerie Woolard\n  id: \"valerie-woolard-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/valerie-woolard-fake-minds-think-alike.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/fake-minds-think-alike-valerie-woolard/\"\n  thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreif7ygql6cr4x2pxxh7l6hrien4dddjmyiivc342ueyabcwnyarpwq@jpeg\"\n  thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreif7ygql6cr4x2pxxh7l6hrien4dddjmyiivc342ueyabcwnyarpwq@jpeg\"\n  thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreif7ygql6cr4x2pxxh7l6hrien4dddjmyiivc342ueyabcwnyarpwq@jpeg\"\n  thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreif7ygql6cr4x2pxxh7l6hrien4dddjmyiivc342ueyabcwnyarpwq@jpeg\"\n  thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreif7ygql6cr4x2pxxh7l6hrien4dddjmyiivc342ueyabcwnyarpwq@jpeg\"\n  description: |-\n    A primer on vector data types and how they are used in large language models and AI. We’ll talk about how models can fall short and walk through a practical example of how to build a similarity search with Ruby.\n\n- title: \"Lighting Talk: Laravel & Rails: Framework Cousins\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Maria Yudina\n  id: \"maria-yudina-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/maria-yudina-laravel-rails-framework-cousins.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/laravel-rails-framework-cousins-maria-yudina/\"\n  thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreif43uvdavjfsfl3hizzvu3lwqeabe6n2kqsrlxf52kb3qmbxawnpe@jpeg\"\n  thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreif43uvdavjfsfl3hizzvu3lwqeabe6n2kqsrlxf52kb3qmbxawnpe@jpeg\"\n  thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreif43uvdavjfsfl3hizzvu3lwqeabe6n2kqsrlxf52kb3qmbxawnpe@jpeg\"\n  thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreif43uvdavjfsfl3hizzvu3lwqeabe6n2kqsrlxf52kb3qmbxawnpe@jpeg\"\n  thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreif43uvdavjfsfl3hizzvu3lwqeabe6n2kqsrlxf52kb3qmbxawnpe@jpeg\"\n  description: |-\n    Laravel was born from Rails’ philosophy but over time, it’s grown into a rich ecosystem with its own identity. In this lightning talk, I’ll share insights from working with both frameworks, explore how Laravel has borrowed from Rails, and highlight what Rails might borrow back in return.\n\n- title: \"Lighting Talk: Covers To Conversations\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Jess Sullivan\n  id: \"jess-sullivan-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/jess-sullivan-covers-to-conversations.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/covers-to-conversations-jess-sullivan/\"\n  thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreihcbujdrv63b6rsk4z3e3zzhxfzuqr33nccr6mlahuwz7wzdiu7km@jpeg\"\n  thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreihcbujdrv63b6rsk4z3e3zzhxfzuqr33nccr6mlahuwz7wzdiu7km@jpeg\"\n  thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreihcbujdrv63b6rsk4z3e3zzhxfzuqr33nccr6mlahuwz7wzdiu7km@jpeg\"\n  thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreihcbujdrv63b6rsk4z3e3zzhxfzuqr33nccr6mlahuwz7wzdiu7km@jpeg\"\n  thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreihcbujdrv63b6rsk4z3e3zzhxfzuqr33nccr6mlahuwz7wzdiu7km@jpeg\"\n  description: |-\n    Have you ever wanted to start a tech book club but felt unsure where to begin? In this lightning talk, I’ll demystify the process and share practical tips from my own experience leading a technical book club. Whether you’re a first-time host or a seasoned participant, you’ll walk away with actionable strategies to create a fun, engaging, and educational book club experience.\n\n- title: \"Lighting Talk: Accessibility Boost!\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Carme Mias\n  id: \"carme-mias-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/carme-mias-accessibility-boost.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/accessibility-boost-carme-mias/\"\n  thumbnail_xs: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/212/827/143/258/small/2d593a8353b2c6b4.jpg\"\n  thumbnail_sm: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/212/827/143/258/small/2d593a8353b2c6b4.jpg\"\n  thumbnail_md: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/212/827/143/258/small/2d593a8353b2c6b4.jpg\"\n  thumbnail_lg: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/212/827/143/258/original/2d593a8353b2c6b4.jpg\"\n  thumbnail_xl: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/212/827/143/258/original/2d593a8353b2c6b4.jpg\"\n  description: |-\n    Sometimes, the best way to help solve a complex problem is by completely ignoring its causes. This is a tale about how we boosted the accessibility of our work by starting a grassroots champions network, how we went about it, and what we learned along the way.\n\n- title: \"Fireside Chat: Rails Foundation\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Amanda Perino\n    - Rosa Gutiérrez\n    - Andy Croll\n  id: \"amanda-perino-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/amanda-perino-rails-foundation-fireside-chat.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/rails-foundation-fireside-chat-amanda-perino-rosa/\"\n  thumbnail_xs: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/254/239/242/941/small/3903152f1a512726.jpg\"\n  thumbnail_sm: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/254/239/242/941/small/3903152f1a512726.jpg\"\n  thumbnail_md: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/254/239/242/941/small/3903152f1a512726.jpg\"\n  thumbnail_lg: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/254/239/242/941/original/3903152f1a512726.jpg\"\n  thumbnail_xl: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/254/239/242/941/original/3903152f1a512726.jpg\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    A fireside chat covering the last couple of years of the Rails Foundation’s work and plans for the future, with Amanda Perino in conversation with Andy Croll, supported by Rosa Gutierrez.\n\n- title: \"Systems of Harm\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Amy Hupe\n  id: \"amy-hupe-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/amy-hupe-systems-of-harm.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/systems-of-harm-amy-hupe/\"\n  thumbnail_xs: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/530/688/537/052/small/2947a34318c6003f.jpg\"\n  thumbnail_sm: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/530/688/537/052/small/2947a34318c6003f.jpg\"\n  thumbnail_md: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/530/688/537/052/small/2947a34318c6003f.jpg\"\n  thumbnail_lg: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/530/688/537/052/original/2947a34318c6003f.jpg\"\n  thumbnail_xl: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/530/688/537/052/original/2947a34318c6003f.jpg\"\n  description: |-\n    Design systems are scaling machines that can either reproduce harm or create more inclusive experiences. This talk explores how design systems can unintentionally perpetuate discrimination and exclusion, and presents three key principles for creating socially responsible design systems: starting with diverse teams, centering stress cases over edge cases, and embracing complexity rather than oversimplified patterns.\n\n- title: \"Spinning Multiple Plates: Concurrency in Rails\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Harriet Oughton\n  id: \"harriet-oughton-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/harriet-oughton-spinning-multiple-plates-concurrency-in-rails.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/spinning-multiple-plates-concurrency-in-rails-harriet-oughton/\"\n  thumbnail_xs: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/683/192/068/649/small/581b1fee7a4de1f1.jpg\"\n  thumbnail_sm: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/683/192/068/649/small/581b1fee7a4de1f1.jpg\"\n  thumbnail_md: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/683/192/068/649/small/581b1fee7a4de1f1.jpg\"\n  thumbnail_lg: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/683/192/068/649/original/581b1fee7a4de1f1.jpg\"\n  thumbnail_xl: \"https://cdn.masto.host/rubysocial/media_attachments/files/114/710/683/192/068/649/original/581b1fee7a4de1f1.jpg\"\n  description: |-\n    An exploration of the concurrency built into Rails, drawing from work on the Rails Guides and featuring a fun, chaotic physical demonstration of the difficulties of multi-threaded workloads.\n\n- title: \"Case of the Peculiar Pattern\"\n  event_name: \"Brighton Ruby 2025\"\n  date: \"2025-06-19\"\n  published_at: \"2025-11-20T07:28:17Z\"\n  announced_at: \"2025-03-22T19:01:00Z\"\n  speakers:\n    - Nadia Odunayo\n  id: \"nadia-odunayo-brighton-ruby-2025\"\n  video_id: \"https://videos.brightonruby.com/videos/2025/nadia-odunayo-case-of-the-peculiar-pattern.mp4\"\n  video_provider: \"mp4\"\n  external_player: true\n  external_player_url: \"https://brightonruby.com/2025/case-of-the-peculiar-pattern-nadia-odunayo/\"\n  thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreib3byuchhugvbecettude7sv2e7opiyf4uawqdxwrmonfevjocz4u@jpeg\"\n  thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreib3byuchhugvbecettude7sv2e7opiyf4uawqdxwrmonfevjocz4u@jpeg\"\n  thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreib3byuchhugvbecettude7sv2e7opiyf4uawqdxwrmonfevjocz4u@jpeg\"\n  thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreib3byuchhugvbecettude7sv2e7opiyf4uawqdxwrmonfevjocz4u@jpeg\"\n  thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:wcqxrf2bmclnqk37zskkmw7p/bafkreib3byuchhugvbecettude7sv2e7opiyf4uawqdxwrmonfevjocz4u@jpeg\"\n  description: |-\n    When a mysterious pattern matching bug crashes during a major product launch, Ruby Private Investigator Deirdre Bug is forced to seek help from an unexpected source. What begins as urgent debugging evolves into something much more, causing her to question everything.\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://forms.reform.app/goodscary/brighton-ruby-2026-cfp/gci0d6\"\n  open_date: \"2026-01-11\"\n  close_date: \"2026-02-28\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2026/event.yml",
    "content": "---\nid: \"brightonruby-2026\"\ntitle: \"Brighton Ruby 2026\"\nlocation: \"Brighton, UK\"\ndescription: |-\n  Thursday 25th June, 2026, Brighton Dome\nstart_date: \"2026-06-25\"\nend_date: \"2026-06-25\"\nkind: \"conference\"\nyear: 2026\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFBEB\"\nfeatured_color: \"#0F1729\"\nwebsite: \"https://brightonruby.com\"\ntickets_url: \"https://ti.to/goodscary/brightonruby-2026\"\ncoordinates:\n  latitude: 50.8236999\n  longitude: -0.1380842\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2026/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Andy Croll\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2026/schedule.yml",
    "content": "---\ndays:\n  - name: \"Brighton Ruby 2026\"\n    date: \"2026-06-25\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Coffee\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"12:15\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"14:15\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:15\"\n        end_time: \"14:25\"\n        slots: 1\n\n      - start_time: \"14:25\"\n        end_time: \"14:35\"\n        slots: 1\n\n      - start_time: \"14:35\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Ice Cream\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - Drinks\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2026/sponsors.yml",
    "content": "# TODO: remove when event is over and all sponsors are confirmed\n---\n- tiers:\n    - name: \"Sponsored by\"\n      description: |-\n        Main sponsors for Brighton Ruby Conference 2026\n      level: 1\n      sponsors:\n        - name: \"Cleo\"\n          website: \"https://web.meetcleo.com\"\n          slug: \"Cleo\"\n          logo_url: \"https://brightonruby.com/images/2026/sponsors/cleo.svg\"\n\n    - name: \"Supporters\"\n      description: |-\n        Supporters for Brighton Ruby Conference 2026\n      level: 2\n      sponsors:\n        - name: \"Sorcer\"\n          website: \"https://sorcer.io/\"\n          slug: \"Sorcer\"\n          logo_url: \"https://brightonruby.com/images/2026/sponsors/sorcer.svg\"\n\n        - name: \"MMTM\"\n          website: \"https://mmtm.io\"\n          slug: \"MMTM\"\n          logo_url: \"https://brightonruby.com/images/2026/sponsors/mmtm.svg\"\n\n        - name: \"Bookwhen\"\n          website: \"https://bookwhen.com\"\n          slug: \"Bookwhen\"\n          logo_url: \"https://brightonruby.com/images/2026/sponsors/bookwhen.svg\"\n\n        - name: \"Jelly\"\n          website: \"https://app.letsjelly.com\"\n          slug: \"Jelly\"\n          logo_url: \"https://brightonruby.com/images/2026/sponsors/jelly.svg\"\n\n        - name: \"Intercom\"\n          website: \"https://www.intercom.com\"\n          slug: \"Intercom\"\n          logo_url: \"https://brightonruby.com/images/2026/sponsors/intercom.svg\"\n\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com\"\n          slug: \"Shopify\"\n          logo_url: \"https://brightonruby.com/images/2026/sponsors/shopify.svg\"\n\n        - name: \"CaptionHub\"\n          website: \"https://captionhub.com\"\n          slug: \"CaptionHub\"\n          logo_url: \"https://brightonruby.com/images/2026/sponsors/captionhub.svg\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2026/venue.yml",
    "content": "---\nname: \"Brighton Dome\"\n\naddress:\n  street: \"Church Street\"\n  city: \"Brighton and Hove\"\n  region: \"England\"\n  postal_code: \"BN1 1UE\"\n  country: \"United Kingdom\"\n  country_code: \"GB\"\n  display: \"Church St, Brighton and Hove, Brighton BN1 1UE, UK\"\n\ncoordinates:\n  latitude: 50.8236999\n  longitude: -0.1380842\n\nmaps:\n  google: \"https://maps.google.com/?q=Brighton+Dome,50.8236999,-0.1380842\"\n  apple: \"https://maps.apple.com/place?address=Church%20Street%0ABrighton%0ABN1%201UE%0AEngland&coordinate=50.823676,-0.138472&name=Brighton%20Dome&place-id=IDCD7AF64F1D7EFD6&map=h\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=50.8236999&mlon=-0.1380842\"\n\nhotels:\n  - name: \"Numa Brighton Pavilion\"\n    kind: \"Recommended Hotel\"\n    description: |-\n      Super close to the venue (formerly MyBrighton)\n\n    address:\n      street: \"17 Jubilee Street\"\n      city: \"Brighton and Hove\"\n      region: \"England\"\n      postal_code: \"BN1 1GE\"\n      country: \"United Kingdom\"\n      country_code: \"GB\"\n      display: \"17 Jubilee St, Brighton, BN1 1GE, England\"\n\n    coordinates:\n      latitude: 50.8245242\n      longitude: -0.1385486\n\n    maps:\n      google: \"https://maps.app.goo.gl/XozrWsD4MWYeihcz7\"\n      apple:\n        \"https://maps.apple.com/place?address=17%20Jubilee%20Street,%20Brighton,%20BN1%201GE,%20England&coordinate=50.824485,-0.138620&name=Numa%20Brighton%20Pavilion&place-id=I657\\\n        99A274691ABD5&map=h\"\n"
  },
  {
    "path": "data/brightonruby/brightonruby-2026/videos.yml",
    "content": "# Website: https://brightonruby.com\n# Videos: -\n---\n- id: \"andy-croll-brightonruby-2026\"\n  title: \"Welcome\"\n  description: |-\n    Welcome to Brighton Ruby 2026.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - Andy Croll\n  video_provider: \"scheduled\"\n  video_id: \"andy-croll-brightonruby-2026\"\n\n- id: \"brian-casel-brightonruby-2026\"\n  title: \"Your experience is your (AI) advantage\"\n  description: |-\n    Everyone's seen AI spin up a fresh app from scratch. But what about your well-established codebase, with years of decisions, conventions, and real users? Brian Casel argues that experienced developers have the biggest advantage in the AI era, and shows why the best teams are blurring the lines between developer, designer, and product manager—and what that means for us as builders.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - Brian Casel\n  video_provider: \"scheduled\"\n  video_id: \"brian-casel-brightonruby-2026\"\n\n- id: \"elena-tanasoiu-emma-gabriel-brightonruby-2026\"\n  title: \"Performance Engineering for Everyone\"\n  description: |-\n    Your app has a slow endpoint. You've added a database index, turned on caching, reached for larger instances — and you're still guessing. This talk teaches you how to read flamegraphs: the visualization that shows exactly where your code spends time, no guesswork required. We'll demonstrate the technique through a real production story from GitHub, where profiling a single page cut CPU consumption by 13% and rebuilt developer trust in the merge button on the Pull Request page.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - \"Elena Tănăsoiu\"\n    - Emma Gabriel\n  video_provider: \"scheduled\"\n  video_id: \"elena-tanasoiu-emma-gabriel-brightonruby-2026\"\n\n- id: \"craig-norford-brightonruby-2026\"\n  title: \"Scaling Sidekiq: Managing Multi Tenancy\"\n  description: |-\n    Different strategies for managing multi tenancy in Sidekiq and different strategies based on your business needs. Especially looking at balancing cost and compute with shuffle sharding.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - Craig Norford\n  video_provider: \"scheduled\"\n  video_id: \"craig-norford-brightonruby-2026\"\n\n- id: \"remy-hannequin-brightonruby-2026\"\n  title: \"Time is a Lie (and How to Deal With It in Ruby)\"\n  description: |-\n    Time seems simple until a background job vanishes during the DST switch or an API silently shifts dates because it assumed UTC. We'll look at why time is genuinely weird, and then work through practical patterns for handling it safely in Ruby and Rails.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - \"Rémy Hannequin\"\n  video_provider: \"scheduled\"\n  video_id: \"remy-hannequin-brightonruby-2026\"\n\n- id: \"tekin-suleyman-brightonruby-2026\"\n  title: \"Lightning Talk: 10 Cool Things You Probably Didn't Know About Internationalisation\"\n  description: |-\n    10 cool things you probably didn't know about internationalisation.\n  kind: \"lightning_talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - \"Tekin Süleyman\"\n  video_provider: \"scheduled\"\n  video_id: \"tekin-suleyman-brightonruby-2026\"\n\n- id: \"tijmen-brommet-brightonruby-2026\"\n  title: \"Lightning Talk: Woodworking for Rubyists\"\n  description: |-\n    What woodworking can teach us about software development. From jigs to joints, the parallels between crafting with wood and crafting with code.\n  kind: \"lightning_talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - Tijmen Brommet\n  video_provider: \"scheduled\"\n  video_id: \"tijmen-brommet-brightonruby-2026\"\n\n- id: \"jennie-evans-brightonruby-2026\"\n  title: \"Lightning Talk: Kindness is a Superpower\"\n  description: |-\n    How kindness shows up in development teams and why it matters. A look at the small acts that make teams stronger.\n  kind: \"lightning_talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - Jennie Evans\n  video_provider: \"scheduled\"\n  video_id: \"jennie-evans-brightonruby-2026\"\n\n- id: \"maria-yudina-brightonruby-2026\"\n  title: \"Code, Prompts, and Stories\"\n  description: |-\n    What screenwriting can teach us about writing code and prompts. The same craft principles that make stories work — clarity, structure, naming — apply across code, prompts, and communication.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - Maria Yudina\n  video_provider: \"scheduled\"\n  video_id: \"maria-yudina-brightonruby-2026\"\n\n- id: \"iliana-hadzhiatanasova-brightonruby-2026\"\n  title: \"From Rails 3.0 to Rails Edge: 15 years of upgrades in a 3 million line monolith\"\n  description: |-\n    Intercom has been running on Rails since 2011. Starting from Rails 3.0, today our 3 million line monolith is running on the main branch of Rails. This talk covers our Rails upgrade journey over the last 15 years - the things that broke, the monkey patches keeping it all together, and what it takes to get 300 engineers comfortable shipping on unreleased Rails versions.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - Iliana Hadzhiatanasova\n  video_provider: \"scheduled\"\n  video_id: \"iliana-hadzhiatanasova-brightonruby-2026\"\n\n- id: \"alex-watt-brightonruby-2026\"\n  title: \"Ethiopia on Rails\"\n  description: |-\n    Improving healthcare in Addis Ababa, Ethiopia, with a Rails app for mobile medical clinics.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-06-25\"\n  speakers:\n    - Alex Watt\n  video_provider: \"scheduled\"\n  video_id: \"alex-watt-brightonruby-2026\"\n"
  },
  {
    "path": "data/brightonruby/series.yml",
    "content": "---\nname: \"Brighton Ruby\"\nwebsite: \"https://brightonruby.com\"\ntwitter: \"BrightonRuby\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"UK\"\nyoutube_channel_name: \"BrightonRubyUK\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCTj2HxTYg7Q4fi1cLccSoQA\"\n"
  },
  {
    "path": "data/burlington-ruby-conference/burlington-ruby-conference-2012/event.yml",
    "content": "---\nid: \"burlington-ruby-conference-2012\"\ntitle: \"Burlington Ruby Conference 2012\"\ndescription: |-\n  Main Street Landing Performing Arts Center\nlocation: \"Burlington, VT, United States\"\nkind: \"conference\"\nstart_date: \"2012-07-28\"\nend_date: \"2012-07-29\"\nwebsite: \"https://burlingtonruby.github.io/buruco2012\"\ncoordinates:\n  latitude: 44.4758825\n  longitude: -73.21207199999999\n"
  },
  {
    "path": "data/burlington-ruby-conference/burlington-ruby-conference-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://burlingtonruby.github.io/buruco2012/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/burlington-ruby-conference/burlington-ruby-conference-2013/event.yml",
    "content": "---\nid: \"burlington-ruby-conference-2013\"\ntitle: \"Burlington Ruby Conference 2013\"\ndescription: |-\n  Burlington Ruby Conference is the event of the summer for Ruby enthusiasts to network, learn and relax in the beautiful state of Vermont.\nlocation: \"Burlington, VT, United States\"\nkind: \"conference\"\nstart_date: \"2013-08-03\"\nend_date: \"2013-08-04\"\nwebsite: \"https://burlingtonruby.github.io/buruco2013\"\ncoordinates:\n  latitude: 44.4758825\n  longitude: -73.21207199999999\n"
  },
  {
    "path": "data/burlington-ruby-conference/burlington-ruby-conference-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://burlingtonruby.github.io/buruco2013/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/burlington-ruby-conference/burlington-ruby-conference-2014/event.yml",
    "content": "---\nid: \"burlington-ruby-conference-2014\"\ntitle: \"Burlington Ruby Conference 2014\"\ndescription: |-\n  Held on the picturesque Lake Champlain waterfront, Burlington Ruby Conference is the event of the summer for Ruby enthusiasts to network, learn and relax in the beautiful state of Vermont.\nlocation: \"Burlington, VT, United States\"\nkind: \"conference\"\nstart_date: \"2014-08-01\"\nend_date: \"2014-08-03\"\nwebsite: \"https://burlingtonruby.github.io/burlingtonrubyconference2014\"\nplaylist: \"https://vimeo.com/showcase/2996485\"\ncoordinates:\n  latitude: 44.4758825\n  longitude: -73.21207199999999\n"
  },
  {
    "path": "data/burlington-ruby-conference/burlington-ruby-conference-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://burlingtonruby.github.io/burlingtonrubyconference2014/\n# Videos: https://vimeo.com/showcase/2996485\n---\n[]\n"
  },
  {
    "path": "data/burlington-ruby-conference/burlington-ruby-conference-2015/event.yml",
    "content": "---\nid: \"burlington-ruby-conference-2015\"\ntitle: \"Burlington Ruby Conference 2015\"\ndescription: |-\n  The fourth annual gathering of Ruby friends in Burlington, Vermont, USA.\nlocation: \"Burlington, VT, United States\"\nkind: \"conference\"\nstart_date: \"2015-07-31\"\nend_date: \"2015-08-02\"\nwebsite: \"https://burlingtonruby.github.io/burlingtonrubyconference2015\"\ncoordinates:\n  latitude: 44.4758825\n  longitude: -73.21207199999999\n"
  },
  {
    "path": "data/burlington-ruby-conference/burlington-ruby-conference-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://burlingtonruby.github.io/burlingtonrubyconference2015\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/burlington-ruby-conference/series.yml",
    "content": "---\nname: \"Burlington Ruby Conference\"\nwebsite: \"http://burlingtonruby.github.io/burlingtonrubyconference2014/\"\ntwitter: \"btvrubyconf\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/cascadia-ruby/cascadia-ruby-2011/event.yml",
    "content": "---\nid: \"cascadia-ruby-2011\"\ntitle: \"Cascadia Ruby 2011\"\ndescription: \"\"\nlocation: \"Seattle, WA, United States\"\nkind: \"conference\"\nstart_date: \"2011-07-29\"\nend_date: \"2011-07-30\"\nwebsite: \"https://web.archive.org/web/20120701203713/http://2011.cascadiaruby.com/\"\noriginal_website: \"http://2011.cascadiaruby.com/\"\ntwitter: \"cascadiaruby\"\ncoordinates:\n  latitude: 47.6061389\n  longitude: -122.3328481\n"
  },
  {
    "path": "data/cascadia-ruby/cascadia-ruby-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2011.cascadiaruby.com/\n# Videos: -\n# https://www.flickr.com/photos/jremsikjr/albums/72157627210248089\n---\n[]\n"
  },
  {
    "path": "data/cascadia-ruby/cascadia-ruby-2012/event.yml",
    "content": "---\nid: \"cascadia-ruby-2012\"\ntitle: \"Cascadia Ruby 2012\"\ndescription: \"\"\nlocation: \"Seattle, WA, United States\"\nkind: \"conference\"\nstart_date: \"2012-08-03\"\nend_date: \"2012-08-04\"\nwebsite: \"https://web.archive.org/web/20120805055736/http://cascadiaruby.com/\"\noriginal_website: \"http://cascadiaruby.com/\"\ntwitter: \"cascadiaruby\"\ncoordinates:\n  latitude: 47.6061389\n  longitude: -122.3328481\n"
  },
  {
    "path": "data/cascadia-ruby/cascadia-ruby-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://cascadiaruby.com/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/cascadia-ruby/cascadia-ruby-2014/event.yml",
    "content": "---\nid: \"cascadia-ruby-2014\"\ntitle: \"Cascadia Ruby 2014\"\ndescription: \"\"\nlocation: \"Portland, OR, United States\"\nkind: \"conference\"\nstart_date: \"2014-08-11\"\nend_date: \"2014-08-12\"\nwebsite: \"https://web.archive.org/web/20140921082634/http://cascadiaruby.com/\"\noriginal_website: \"http://cascadiaruby.com/\"\ntwitter: \"cascadiaruby\"\nplaylist: \"http://confreaks.com/events/cascadiaruby2014\"\ncoordinates:\n  latitude: 45.515232\n  longitude: -122.6783853\n"
  },
  {
    "path": "data/cascadia-ruby/cascadia-ruby-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://cascadiaruby.com/\n# Videos: http://confreaks.com/events/cascadiaruby2014\n---\n[]\n"
  },
  {
    "path": "data/cascadia-ruby/series.yml",
    "content": "---\nname: \"Cascadia Ruby\"\nwebsite: \"http://cascadiaruby.com/\"\ntwitter: \"cascadiaruby\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ceru-camp/ceru-camp-2009/event.yml",
    "content": "---\nid: \"ceru-camp-2009\"\ntitle: \"CERU Camp 2009\"\ndescription: |-\n  Central eUropean RUby camp\nlocation: \"Vienna, Austria\"\nkind: \"retreat\"\nstart_date: \"2009-09-26\"\nend_date: \"2009-09-27\"\noriginal_website: \"http://curucamp.org/\"\ncoordinates:\n  latitude: 48.20806959999999\n  longitude: 16.3713095\n"
  },
  {
    "path": "data/ceru-camp/ceru-camp-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/ceru-camp/series.yml",
    "content": "---\nname: \"CERU Camp\"\nkind: \"retreat\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"AT\"\naliases:\n  - Central eUropean RUby camp\n  - CERU\n"
  },
  {
    "path": "data/chicagoruby/chicagoruby/event.yml",
    "content": "---\nid: \"chicagoruby-meetup\"\ntitle: \"ChicagoRuby Meetup\"\nkind: \"meetup\"\nlocation: \"Chicago, IL, United States\"\ndescription: |-\n  ChicagoRuby is a group of developers & designers who use Ruby, Rails, and related tech.\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D0232B\"\nwebsite: \"https://chicagoruby.org\"\ncoordinates:\n  latitude: 41.88325\n  longitude: -87.6323879\n"
  },
  {
    "path": "data/chicagoruby/chicagoruby/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Supporter\"\n      level: 1\n      sponsors:\n        - name: \"Gotoinc\"\n          website: \"https://gotoinc.co/\"\n          slug: \"gotoinc\"\n          logo_url: \"https://ithub.ua/sites/default/files/gotoinc.jpg\"\n"
  },
  {
    "path": "data/chicagoruby/chicagoruby/videos.yml",
    "content": "---\n- title: \"ChicagoRuby Meetup - February 2008\"\n  raw_title: \"Metromix on Rails\"\n  event_name: \"ChicagoRuby Meetup - February 2008\"\n  date: \"2008-02-24\"\n  description: |-\n    Evan Petrie presents on moving Metromix from J2EE to Ruby on Rails.\n  video_provider: \"children\"\n  video_id: \"chicagoruby-meetup-february-2008\"\n  id: \"chicagoruby-meetup-february-2008\"\n  talks:\n    - title: \"Metromix on Rails\"\n      date: \"2008-02-24\"\n      id: \"evan-petrie-chicagoruby-meetup-february-2008\"\n      video_id: \"26081191\"\n      video_provider: \"vimeo\"\n      event_name: \"ChicagoRuby Meetup - February 2008\"\n      speakers:\n        - Evan Petrie\n\n    - title: \"Metromix on Rails - Bonus Q&A\"\n      date: \"2008-02-24\"\n      id: \"evan-petrie-qa-chicagoruby-meetup-february-2008\"\n      video_id: \"724086\"\n      video_provider: \"vimeo\"\n      event_name: \"ChicagoRuby Meetup - February 2008\"\n      speakers:\n        - Evan Petrie\n\n- title: \"ChicagoRuby Meetup - May 2008\"\n  raw_title: \"Mobtropolis\"\n  event_name: \"ChicagoRuby Meetup - May 2008\"\n  date: \"2008-05-06\"\n  description: |-\n    Wil Chung presents Mobtropolis, a Ruby on Rails powered social experiment.\n  video_provider: \"children\"\n  video_id: \"chicagoruby-meetup-may-2008\"\n  id: \"chicagoruby-meetup-may-2008\"\n  talks:\n    - title: \"Mobtropolis\"\n      date: \"2008-05-06\"\n      id: \"wil-chung-chicagoruby-meetup-may-2008\"\n      video_id: \"981374\"\n      video_provider: \"vimeo\"\n      event_name: \"ChicagoRuby Meetup - May 2008\"\n      speakers:\n        - Wil Chung\n\n- title: \"ChicagoRuby Meetup - March 2009\"\n  raw_title: \"Converting a Legacy App Into Rails\"\n  event_name: \"ChicagoRuby Meetup - March 2009\"\n  date: \"2009-03-23\"\n  description: |-\n    Jeremy Peterson presents on the process of taking data from a legacy database and converting it into a Rails application.\n  video_provider: \"children\"\n  video_id: \"chicagoruby-meetup-march-2009\"\n  id: \"chicagoruby-meetup-march-2009\"\n  talks:\n    - title: \"Converting a Legacy App Into Rails\"\n      date: \"2009-03-23\"\n      id: \"jeremy-peterson-chicagoruby-meetup-march-2009\"\n      video_id: \"3823039\"\n      video_provider: \"vimeo\"\n      event_name: \"ChicagoRuby Meetup - March 2009\"\n      speakers:\n        - Jeremy Peterson\n\n- title: \"ChicagoRuby Meetup - April 2009\"\n  raw_title: \"Coding Dojo\"\n  event_name: \"ChicagoRuby Meetup - April 2009\"\n  date: \"2009-04-29\"\n  description: |-\n    Dave Giunta leads a Coding Dojo session at the ITA in Chicago for ChicagoRuby.\n  video_provider: \"children\"\n  video_id: \"chicagoruby-meetup-april-2009\"\n  id: \"chicagoruby-meetup-april-2009\"\n  talks:\n    - title: \"Coding Dojo\"\n      date: \"2009-04-29\"\n      id: \"dave-giunta-chicagoruby-meetup-april-2009\"\n      video_id: \"4386730\"\n      video_provider: \"vimeo\"\n      event_name: \"ChicagoRuby Meetup - April 2009\"\n      speakers:\n        - Dave Giunta\n\n- title: \"ChicagoRuby Meetup - August 2013\"\n  raw_title: \"Data Visualization\"\n  event_name: \"ChicagoRuby Meetup - August 2013\"\n  date: \"2013-08-06\"\n  description: |-\n    Vanessa Shen presents on Data Visualization - detecting patterns and relationships in data using goals, examples, resources, and tools.\n  video_provider: \"children\"\n  video_id: \"chicagoruby-meetup-august-2013\"\n  id: \"chicagoruby-meetup-august-2013\"\n  talks:\n    - title: \"Data Visualization\"\n      date: \"2013-08-06\"\n      id: \"vanessa-shen-chicagoruby-meetup-august-2013\"\n      video_id: \"71927518\"\n      video_provider: \"vimeo\"\n      event_name: \"ChicagoRuby Meetup - August 2013\"\n      speakers:\n        - Vanessa Shen\n\n- title: \"ChicagoRuby Meetup - September 2013\"\n  raw_title: \"Smash the Monolith: Refactoring Rails Applications\"\n  event_name: \"ChicagoRuby Meetup - September 2013\"\n  date: \"2013-09-03\"\n  description: |-\n    Corey Ehmke presents on refactoring Rails applications - breaking apart monolithic apps that have grown to unmanageable sizes.\n  video_provider: \"children\"\n  video_id: \"chicagoruby-meetup-september-2013\"\n  id: \"chicagoruby-meetup-september-2013\"\n  talks:\n    - title: \"Smash the Monolith: Refactoring Rails Applications\"\n      date: \"2013-09-03\"\n      id: \"corey-ehmke-chicagoruby-meetup-september-2013\"\n      video_id: \"73747370\"\n      video_provider: \"vimeo\"\n      event_name: \"ChicagoRuby Meetup - September 2013\"\n      speakers:\n        - Corey Ehmke\n\n- title: \"ChicagoRuby Meetup - October 2016\"\n  raw_title: \"ETLS - Not Just for Enterprise\"\n  event_name: \"ChicagoRuby Meetup - October 2016\"\n  date: \"2016-10-04\"\n  description: |-\n    Mark Yoon presents on ETLs (Extract, Transform, Load) and how they are not just for enterprise applications.\n  video_provider: \"children\"\n  video_id: \"chicagoruby-meetup-october-2016\"\n  id: \"chicagoruby-meetup-october-2016\"\n  talks:\n    - title: \"ETLS - Not Just for Enterprise\"\n      date: \"2016-10-04\"\n      id: \"mark-yoon-chicagoruby-meetup-october-2016\"\n      video_id: \"185588160\"\n      video_provider: \"vimeo\"\n      event_name: \"ChicagoRuby Meetup - October 2016\"\n      speakers:\n        - Mark Yoon\n\n- title: \"ChicagoRuby Meetup - November 2016\"\n  raw_title: \"Crystal - The Programming Language\"\n  event_name: \"ChicagoRuby Meetup - November 2016\"\n  date: \"2016-11-01\"\n  description: |-\n    Justin McNally presents on Crystal, a programming language that compiles to a native binary but is almost exactly the same as Ruby syntactically.\n  video_provider: \"children\"\n  video_id: \"chicagoruby-meetup-november-2016\"\n  id: \"chicagoruby-meetup-november-2016\"\n  talks:\n    - title: \"Crystal - The Programming Language\"\n      date: \"2016-11-01\"\n      id: \"justin-mcnally-chicagoruby-meetup-november-2016\"\n      video_id: \"189886418\"\n      video_provider: \"vimeo\"\n      event_name: \"ChicagoRuby Meetup - November 2016\"\n      speakers:\n        - Justin McNally\n\n- id: \"chicagoruby-new-year-january-2025\"\n  title: \"ChicagoRuby Meetup - January 2025\"\n  raw_title: \"New Year. New Ruby. New Rails. Welcome Ruby 3.4 + Rails 8!\"\n  event_name: \"ChicagoRuby Meetup - January 2025\"\n  date: \"2025-01-08\"\n  description: |-\n    New Year. New Ruby. New Rails. Welcome Ruby 3.4 + Rails 8!\n\n    Rails 8 was recently released, and Ruby 3.4 is coming this Christmas Day! Let's get together to explore all the exciting new features.\n\n    Speakers:\n    * Daniel Schadd - \"Solid Queue\"\n    * Brian Lesperance - \"Dev Containers\"\n    * Tony Yunker - \"Kamal\"\n\n    Potential additional topics:\n    * Propshaft\n    * Solid Cable\n    * Solid Cache\n    * Other Ruby and Rails tips and tricks\n\n    Location: Pumping Station: One, 3519 N. Elston Ave., Chicago, IL\n\n    https://www.meetup.com/chicagoruby/events/304769227\n  video_provider: \"children\"\n  video_id: \"chicagoruby-new-year-january-2025\"\n  talks:\n    - title: \"Solid Queue\"\n      date: \"2025-01-08\"\n      id: \"daniel-schadd-chicagoruby-new-year-january-2025\"\n      video_id: \"daniel-schadd-chicagoruby-new-year-january-2025\"\n      video_provider: \"scheduled\"\n      event_name: \"ChicagoRuby Meetup - January 2025\"\n      speakers:\n        - Daniel Schadd\n\n    - title: \"Dev Containers\"\n      date: \"2025-01-08\"\n      id: \"brian-lesperance-chicagoruby-new-year-january-2025\"\n      video_id: \"brian-lesperance-chicagoruby-new-year-january-2025\"\n      video_provider: \"scheduled\"\n      event_name: \"ChicagoRuby Meetup - January 2025\"\n      speakers:\n        - Brian Lesperance\n\n    - title: \"Kamal\"\n      date: \"2025-01-08\"\n      id: \"tony-yunker-chicagoruby-new-year-january-2025\"\n      video_id: \"tony-yunker-chicagoruby-new-year-january-2025\"\n      video_provider: \"scheduled\"\n      event_name: \"ChicagoRuby Meetup - January 2025\"\n      speakers:\n        - Tony Yunker\n\n- id: \"chicagoruby-meetup-march-2025-chicagoruby\"\n  title: \"ChicagoRuby Meetup - March 2025\"\n  raw_title: \"ChicagoRuby Meetup at Adler Planetarium (March, 2025)\"\n  event_name: \"ChicagoRuby Meetup - March 2025\"\n  date: \"2025-03-05\"\n  published_at: \"2025-05-22\"\n  description: |-\n    Save the date! On March 5th we'll have the Ruby meetup at Adler Planetarium.\n\n    Please RSVP on meetup so we know how many to expect. We plan to close registration for the event March 2nd or when our RSVP count has hit room capacity. You DO NOT need to be an Illinois Resident for this particular event.\n    Due to building safety regulations, we can only allow max 60 attendees to the planetarium's Education Hub.\n    Reach out to Michelle or other organizers with any questions/issues.\n\n    While the ticket to the planetarium is free, tickets for the sky shows are not included but available for purchase at the desk by the Accessible Entrance. Follow this link for a list of the available sky shows.\n\n    Speaker: Ifat Ribon\n    Speaker: Noel Rappin - “Does Ruby Love Me Back? What Developer Happiness Means in Ruby”\n\n    Looking for people to give a demo, a talk, or a workshop on something Ruby on Rails related. Please reach out if interested. [or send ideas!]\n\n    EVENT AND LOCATION DETAILS:\n    Unfortunately, there will not be food served at this event. There is a cafe at the Adler that has food and drinks available for purchase. Menu can be viewed here.\n\n    This event will be happening during Adler's hours of operation. We will be at Education Hub A.\n\n    Please enter through the Accessible Entrance and head straight to the desk at the Accessible Entrance. Adler employees at the desk should be aware of the event and will be around to point you to the Education Hub A area. Staff at the desk will hand you a wristband that will give you standard museum access (i.e. shows not included, but available for purchase). Your display name on the Attendees list of this Meetup event will be what we use for our event names list. (If you go by a different name than your meetup display name, please message Michelle at michelle@zooniverse.org and she will make sure that your preferred name is on the event list.)\n\n    The Education Hub should be straight ahead once you have entered the Accessible Entrance, near the vending machines and right across from the restrooms. Follow this link for an onsite map. Note that the Accessible Entrance and the Education Hub is in the Mid-level section of the planetarium.\n\n    Can't join in person? No problem!\n    This event will be recorded and live streamed via Zoom. Zoom link can be found here:\n    https://us02web.zoom.us/j/85067995016?pwd=3I8bmOdgeaiNNiBGPtYiFZVAcabZGn.1\n\n    https://www.meetup.com/chicagoruby/events/305503069\n  video_provider: \"youtube\"\n  video_id: \"tA8Omrq0Px4\"\n  talks:\n    - title: \"Intro\"\n      date: \"2025-03-05\"\n      start_cue: \"00:00\"\n      end_cue: \"11:40\"\n      id: \"michelle-yuen-chicagoruby-meetup-march-2025\"\n      video_id: \"michelle-yuen-chicagoruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - March 2025\"\n      speakers:\n        - Michelle Yuen\n\n    - title: \"Build or Buy?\"\n      date: \"2025-03-05\"\n      start_cue: \"11:40\"\n      end_cue: \"41:30\"\n      id: \"ifat-ribon-chicagoruby-meetup-march-2025\"\n      video_id: \"ifat-ribon-chicagoruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - March 2025\"\n      description: |-\n        A practical talk that tackles the classic developer question:\n\n        Should you build it yourself, use a gem, or go with an existing SaaS solution?\n\n        Ifat shares a 5-factor framework to help make smarter architectural decisions, with a live demo comparing:\n        * Pure Ruby\n        * ActionMailer\n        * MailJet API\n      speakers:\n        - Ifat Ribon\n\n    - title: \"Does Ruby Love Me Back?\"\n      date: \"2025-03-05\"\n      start_cue: \"48:37\"\n      end_cue: \"1:23:00\"\n      thumbnail_cue: \"50:01\"\n      id: \"noel-rappin-chicagoruby-meetup-march-2025\"\n      video_id: \"noel-rappin-chicagoruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - March 2025\"\n      description: |-\n        A nostalgic and insightful journey into what makes Ruby uniquely expressive and joyful.\n      speakers:\n        - Noel Rappin\n\n- id: \"chicagoruby-tegus-april-2025\"\n  title: \"ChicagoRuby Meetup - April 2025\"\n  raw_title: \"Ruby @ Tegus by AlphaSense\"\n  event_name: \"ChicagoRuby Meetup - April 2025\"\n  date: \"2025-04-02\"\n  published_at: \"2025-06-06\"\n  description: |-\n    Ruby @ Tegus by AlphaSense\n\n    Join us for a Ruby meetup at Tegus HQ!\n\n    Speaker:\n    * Lionel Barrow (from Tegus) - \"Reflecting on the modular monolith: lessons learned from building a large Rails application\"\n\n    Location: Tegus, 200 N. LaSalle Street. Suite 1100, Chicago, IL\n\n    Hosted by Tegus by AlphaSense\n    RSVP requested by April 1st, 2025\n    Remote attendance option via Zoom\n    Building security check-in required\n\n    https://www.meetup.com/chicagoruby/events/305899516\n  video_provider: \"youtube\"\n  video_id: \"Pm2qC7__MZQ\"\n  thumbnail_lg: \"https://img.youtube.com/vi/Pm2qC7__MZQ/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/Pm2qC7__MZQ/hqdefault.jpg\"\n  talks:\n    - title: \"Reflecting on the modular monolith: lessons learned from building a large Rails application\"\n      date: \"2025-04-02\"\n      published_at: \"2025-06-06\"\n      start_cue: \"05:47\"\n      end_cue: \"1:08:23\"\n      id: \"lionel-barrow-chicagoruby-tegus-april-2025\"\n      video_id: \"lionel-barrow-chicagoruby-tegus-april-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - April 2025\"\n      speakers:\n        - Lionel Barrow\n\n- id: \"chicagoruby-avant-may-2025\"\n  title: \"ChicagoRuby Meetup - May 2025\"\n  raw_title: \"Chicago Ruby @ Avant\"\n  event_name: \"ChicagoRuby Meetup - May 2025\"\n  date: \"2025-05-07\"\n  published_at: \"2025-06-18\"\n  description: |-\n    Chicago Ruby @ Avant\n\n    Join us for an evening of Ruby talks at Avant!\n\n    Speakers:\n    * Chelsea Troy (Mozilla) - \"How does Generative AI affect Developer Productivity?\"\n    * Joel Hawksley (Github) - \"Lessons from 5 years of UI architecture at Github\"\n\n    Location: 222 W Merchandise Mart Plaza, Chicago, IL 60654\n\n    Hosted by Avant\n    Registration was required (no walk-ins)\n    Remote attendance available via Zoom\n\n    https://www.meetup.com/chicagoruby/events/306598554\n  video_provider: \"youtube\"\n  video_id: \"SQXIrKHpv8A\"\n  thumbnail_lg: \"https://img.youtube.com/vi/SQXIrKHpv8A/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/SQXIrKHpv8A/hqdefault.jpg\"\n  talks:\n    - title: \"Lessons from 5 years of UI architecture at Github\"\n      date: \"2025-05-07\"\n      published_at: \"2025-06-18\"\n      start_cue: \"05:12\"\n      end_cue: \"52:17\"\n      id: \"joel-hawksley-chicagoruby-avant-may-2025\"\n      video_id: \"joel-hawksley-chicagoruby-avant-may-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - May 2025\"\n      speakers:\n        - Joel Hawksley\n\n    - title: \"How does Generative AI affect Developer Productivity?\"\n      date: \"2025-05-07\"\n      published_at: \"2025-06-18\"\n      start_cue: \"52:17\"\n      end_cue: \"1:44:34\"\n      id: \"chelsea-troy-chicagoruby-avant-may-2025\"\n      video_id: \"chelsea-troy-chicagoruby-avant-may-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - May 2025\"\n      speakers:\n        - Chelsea Troy\n\n- id: \"chicagoruby-chime-june-2025\"\n  title: \"ChicagoRuby Meetup - June 2025\"\n  raw_title: \"Chicago Ruby @ Chime\"\n  event_name: \"ChicagoRuby Meetup - June 2025\"\n  date: \"2025-06-04\"\n  published_at: \"2025-07-03\"\n  description: |-\n    Chicago Ruby @ Chime\n\n    Join us for an evening of Ruby talks at Chime!\n\n    Speakers:\n    * Andrzej Krzywda - \"15 years of Rails with Domain Driven Design - lessons learnt\"\n    * Alan Ridlehoover & Fito von Zastrow - \"Derailing Our Application: How And Why We Are Decoupling Our Code From Rails\"\n\n    Location: 333 North Green Street, Chicago, IL\n\n    Chime is hosting the Chicago Ruby meetup\n    Remote attendance via Zoom available\n    Allows walk-ins, requires ID and waiver signing at check-in\n\n    https://www.meetup.com/chicagoruby/events/307067943\n  video_provider: \"youtube\"\n  video_id: \"t9tXHMcvIk4\"\n  thumbnail_lg: \"https://img.youtube.com/vi/t9tXHMcvIk4/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/t9tXHMcvIk4/hqdefault.jpg\"\n  talks:\n    - title: \"15 years of Rails with Domain Driven Design - lessons learnt\"\n      date: \"2025-06-04\"\n      published_at: \"2025-07-03\"\n      start_cue: \"06:27\"\n      end_cue: \"1:15:03\"\n      id: \"andrzej-krzywda-chicagoruby-chime-june-2025\"\n      video_id: \"andrzej-krzywda-chicagoruby-chime-june-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - June 2025\"\n      speakers:\n        - Andrzej Krzywda\n\n    - title: \"Derailing Our Application: How And Why We Are Decoupling Our Code From Rails\"\n      date: \"2025-06-04\"\n      published_at: \"2025-07-03\"\n      start_cue: \"1:15:03\"\n      end_cue: \"2:02:09\"\n      id: \"alan-ridlehoover-fito-von-zastrow-chicagoruby-chime-june-2025\"\n      video_id: \"alan-ridlehoover-fito-von-zastrow-chicagoruby-chime-june-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - June 2025\"\n      speakers:\n        - Alan Ridlehoover\n        - Fito von Zastrow\n\n- id: \"ruby-drinkup-july-2025\"\n  title: \"ChicagoRuby Meetup - July 2025\"\n  raw_title: \"Ruby Drinkup July 2nd @ Chicago Brewhouse Riverwalk\"\n  event_name: \"ChicagoRuby Meetup - July 2025\"\n  date: \"2025-07-02\"\n  description: |-\n    Ruby Drinkup July 2nd @ Chicago Brewhouse Riverwalk\n\n    A casual hang after RailsConf for meeting and networking with fellow Ruby enthusiasts and developers.\n\n    Location: Chicago Brewhouse, 31 E. Riverwalk, Chicago, IL\n\n    Hosted by Sara G., Michelle Yuen, and Anton Tkachov\n\n    https://www.meetup.com/chicagoruby/events/308006843\n  video_provider: \"not_recorded\"\n  video_id: \"ruby-drinkup-july-2025\"\n  talks: []\n\n- id: \"chicagoruby-workforce-august-2025\"\n  title: \"ChicagoRuby Meetup - August 2025\"\n  raw_title: \"ChicagoRuby @ Workforce.com\"\n  event_name: \"ChicagoRuby Meetup - August 2025\"\n  date: \"2025-08-06\"\n  published_at: \"2025-08-07\"\n  description: |-\n    ChicagoRuby @ Workforce.com\n\n    Join us for a hybrid evening of Ruby talks at Workforce.com!\n\n    Speakers:\n    * Miles Georgi (in-person) - \"Wrangle domain complexity with Foobara\"\n    * Stephen Margheim (remote from Berlin) - \"Testing Jobs for Resilience\"\n\n    Location: Workforce.com, 150 N Michigan Ave, Chicago, IL 60601\n\n    Limited to 35 attendees\n    Requires ID for check-in\n    Light snacks and drinks provided\n    Zoom URL available for remote attendance\n\n    https://www.meetup.com/chicagoruby/events/308610556\n  video_provider: \"youtube\"\n  video_id: \"xu09IkchT_I\"\n  thumbnail_lg: \"https://img.youtube.com/vi/xu09IkchT_I/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/xu09IkchT_I/hqdefault.jpg\"\n  talks:\n    - title: \"Testing Jobs for Resilience\"\n      date: \"2025-08-06\"\n      published_at: \"2025-08-07\"\n      start_cue: \"06:47\"\n      end_cue: \"1:00:02\"\n      id: \"stephen-margheim-chicagoruby-workforce-august-2025\"\n      video_id: \"stephen-margheim-chicagoruby-workforce-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - August 2025\"\n      speakers:\n        - Stephen Margheim\n\n    - title: \"Wrangle domain complexity with Foobara\"\n      date: \"2025-08-06\"\n      published_at: \"2025-08-07\"\n      start_cue: \"1:00:02\"\n      end_cue: \"2:06:02\"\n      id: \"miles-georgi-chicagoruby-workforce-august-2025\"\n      video_id: \"miles-georgi-chicagoruby-workforce-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - August 2025\"\n      speakers:\n        - Miles Georgi\n\n- id: \"chicagoruby-beyond-finance-september-2025\"\n  title: \"ChicagoRuby Meetup - September 2025\"\n  raw_title: \"ChicagoRuby @ Beyond Finance\"\n  event_name: \"ChicagoRuby Meetup - September 2025\"\n  date: \"2025-09-10\"\n  published_at: \"2025-09-22\"\n  description: |-\n    ChicagoRuby @ Beyond Finance\n\n    Join us for an evening of Ruby talks at Beyond Finance!\n\n    Speakers:\n    * Aji Slater (in-person) - \"Zen and the Art of Incremental Automation\"\n    * Prathana Shiva (remote) - \"From Schema-based Multi-tenancy to Single Schema with UUIDs\"\n\n    Location: Beyond Finance, 15th Floor, 222 N LaSalle St #1500, Chicago, IL 60601\n\n    Dinner will be provided (Pizza + Drinks)\n    Photo ID required for check-in\n    Building security at LaSalle entrance\n\n    https://www.meetup.com/chicagoruby/events/310313555\n  video_provider: \"youtube\"\n  video_id: \"_RsW2DYGWB8\"\n  thumbnail_lg: \"https://img.youtube.com/vi/_RsW2DYGWB8/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/_RsW2DYGWB8/hqdefault.jpg\"\n  talks:\n    - title: \"Zen and the Art of Incremental Automation\"\n      date: \"2025-09-10\"\n      published_at: \"2025-09-22\"\n      start_cue: \"09:22\"\n      end_cue: \"55:32\"\n      id: \"aji-slater-chicagoruby-beyond-finance-september-2025\"\n      video_id: \"aji-slater-chicagoruby-beyond-finance-september-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - September 2025\"\n      speakers:\n        - Christopher \"Aji\" Slater\n\n    - title: \"What If We Did Less?\"\n      date: \"2025-09-10\"\n      published_at: \"2025-09-22\"\n      start_cue: \"55:32\"\n      end_cue: \"1:27:47\"\n      id: \"jim-remsik-chicagoruby-beyond-finance-september-2025\"\n      video_id: \"jim-remsik-chicagoruby-beyond-finance-september-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - September 2025\"\n      speakers:\n        - Jim Remsik\n\n- title: \"ChicagoRuby Meetup - October 2025\"\n  raw_title: \"ChicagoRuby @ Prism Spaces\"\n  event_name: \"ChicagoRuby Meetup - October 2025\"\n  date: \"2025-10-01\"\n  published_at: \"2025-10-28\"\n  description: |-\n    ChicagoRuby @ Prism Spaces\n\n    Join us for an evening of Ruby talks at Prism Spaces!\n\n    Speakers:\n    * Peter Bhat Harkins (in-person) – \"Perfect is Too Expensive\"\n    * Prathana Shiva (remote) - “From Schema-Based Multi-Tenancy to Single Schema with UUIDs”\n\n    Location: Prism Spaces, 1212 N Ashland Ave #202, Chicago, IL 60622\n\n    Remote attendance option via Zoom\n\n    Hosted by Dan H., Michelle Yuen, and Anton Tkachov\n\n    https://www.meetup.com/chicagoruby/events/310937426\n  video_provider: \"youtube\"\n  video_id: \"I0UOJYxOcBA\"\n  id: \"chicagoruby-meetup-october-2025\"\n  thumbnail_lg: \"https://img.youtube.com/vi/I0UOJYxOcBA/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/I0UOJYxOcBA/hqdefault.jpg\"\n  talks:\n    - title: \"Intro\"\n      date: \"2025-10-01\"\n      published_at: \"2025-10-28\"\n      start_cue: \"00:00\"\n      end_cue: \"07:40\"\n      thumbnail_cue: \"01:45\"\n      id: \"intro-chicagoruby-meetup-october-2025\"\n      video_id: \"intro-chicagoruby-meetup-october-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - October 2025\"\n      description: \"\"\n      speakers:\n        - Dan Heintzelman\n        - Ben Sanders\n\n    - title: \"Perfect is Too Expensive\"\n      date: \"2025-10-01\"\n      published_at: \"2025-10-28\"\n      start_cue: \"08:20\"\n      end_cue: \"43:22\"\n      thumbnail_cue: \"08:22\"\n      id: \"peter-bhat-harkins-chicagoruby-meetup-october-2025\"\n      video_id: \"peter-bhat-harkins-chicagoruby-meetup-october-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - October 2025\"\n      slides_url: \"https://push.cx/talks\"\n      description: |-\n        Every nontrivial database has invalid data in it. Records that can't pass theirvalidations, NULLs where background jobs silently failed, records that combineto impossible states, and even errors introduced when fixing other bugs. There's a missing tool from our toolboxes. (No, it's not SQL constraints). Come learn how to catch these bugs before your users do.\n      speakers:\n        - Peter Bhat Harkins\n\n    - title: \"From Schema-Based Multi-Tenancy to Single Schema with UUIDs\"\n      date: \"2025-10-01\"\n      published_at: \"2025-10-28\"\n      start_cue: \"01:08:27\"\n      end_cue: \"01:33:40\"\n      thumbnail_cue: \"57:33\"\n      location: \"Remote\"\n      id: \"prathana-shiva-chicagoruby-meetup-october-2025\"\n      video_id: \"prathana-shiva-chicagoruby-meetup-october-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - October 2025\"\n      speakers:\n        - Prathana Shiva\n\n- title: \"ChicagoRuby Meetup - November 2025\"\n  raw_title: \"ChicagoRuby @ Cisco Systems\"\n  event_name: \"ChicagoRuby Meetup - November 2025\"\n  date: \"2025-11-05\"\n  published_at: \"2025-12-02\"\n  description: |-\n    ChicagoRuby @ Cisco Systems\n\n    Join us for an evening of Ruby talks at Cisco Systems!\n\n    Speakers:\n    * Andy Andrea (in-person, joining us from North Carolina) - \"Reusable JSON Schemas\"\n    * Patrick McSweeny (in-person, joining us from Michigan) - \"Hotwire Your UX\"\n\n    Location: Cisco Systems, 433 W Van Buren St, 7th Floor, Chicago, IL 60607\n\n    Location details:\n    * ID required upon check-in; registration name must match your ID\n    * No walk-ins allowed (every attendee must be registered)\n    * Please arrive before 6pm; Cisco will only have wayfinders until around 6:00–6:15pm\n    * Parking: closest garage is 326 S Wells St, Chicago, IL 60606 (paid covered parking)\n    * Dinner from Noodles & Company (vegetarian options available; no gluten-free options)\n\n    Remote attendance option via Webex\n\n    Hosted by Dan H., Michelle Yuen, and Anton Tkachov\n\n    https://www.meetup.com/chicagoruby/events/311241901\n  video_provider: \"youtube\"\n  video_id: \"aeLcOW4Cfe4\"\n  id: \"chicagoruby-meetup-november-2025\"\n  thumbnail_lg: \"https://img.youtube.com/vi/aeLcOW4Cfe4/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/aeLcOW4Cfe4/hqdefault.jpg\"\n  talks:\n    - title: \"Intro\"\n      date: \"2025-11-05\"\n      published_at: \"2025-12-02\"\n      start_cue: \"00:30\"\n      end_cue: \"07:30\"\n      thumbnail_cue: \"00:34\"\n      id: \"intro-chicagoruby-meetup-november-2025\"\n      video_id: \"intro-chicagoruby-meetup-november-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - November 2025\"\n      speakers:\n        - Michelle Yuen\n        - Kevin Hurley\n\n    - title: \"The little schema that could\"\n      date: \"2025-11-05\"\n      published_at: \"2025-12-02\"\n      start_cue: \"07:45\"\n      end_cue: \"36:00\"\n      thumbnail_cue: \"07:39\"\n      id: \"andy-andrea-chicagoruby-meetup-november-2025\"\n      video_id: \"andy-andrea-chicagoruby-meetup-november-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - November 2025\"\n      speakers:\n        - Andy Andrea\n\n    - title: \"Hotwire Your UX\"\n      date: \"2025-11-05\"\n      published_at: \"2025-12-02\"\n      start_cue: \"57:10\"\n      end_cue: \"01:19:05\"\n      thumbnail_cue: \"57:15\"\n      id: \"patrick-mcsweeny-chicagoruby-meetup-november-2025\"\n      video_id: \"patrick-mcsweeny-chicagoruby-meetup-november-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - November 2025\"\n      speakers:\n        - Patrick McSweeny\n\n- title: \"ChicagoRuby Meetup - December 2025\"\n  raw_title: \"Year-in-Poem & Hack Night: ChicagoRuby December 2025 Intro\"\n  event_name: \"ChicagoRuby Meetup - December 2025\"\n  date: \"2025-12-03\"\n  published_at: \"2025-12-18\"\n  description: |-\n    ChicagoRuby December 2025 Hack Night\n\n    A casual hack night to close out the year, featuring community announcements,\n    2026 meetup plans, and Michelle's \"Hack Night Before Christmas\" poem.\n  video_provider: \"youtube\"\n  video_id: \"VW_5v0mFdIQ\"\n  id: \"chicagoruby-meetup-december-2025\"\n  thumbnail_lg: \"https://img.youtube.com/vi/VW_5v0mFdIQ/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/VW_5v0mFdIQ/hqdefault.jpg\"\n  talks:\n    - title: \"Year-in-Poem & Hack Night Intro\"\n      date: \"2025-12-03\"\n      published_at: \"2025-12-18\"\n      start_cue: \"00:00\"\n      end_cue: \"19:46\"\n      id: \"intro-chicagoruby-meetup-december-2025\"\n      video_id: \"intro-chicagoruby-meetup-december-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - December 2025\"\n      speakers:\n        - Michelle Yuen\n        - Anton Tkachov\n\n- title: \"ChicagoRuby Meetup - February 2026\"\n  raw_title: \"Chicago Ruby Meetup - February 2026: Continuous Learning Meets Release Automation\"\n  event_name: \"ChicagoRuby Meetup - February 2026\"\n  date: \"2026-02-04\"\n  published_at: \"2026-02-06\"\n  description: |-\n    Chicago Ruby Meetup - February 2026: Continuous Learning Meets Release Automation\n\n    Speakers:\n    * Jeffrey Cohen - \"A Framework for Learning: Finding Contentment and Growth in Your Career\"\n    * Brooke Kuhlmann - \"Milestones, Semantic Versioning & Automated Release Notes\"\n  video_provider: \"youtube\"\n  video_id: \"jG9YtRx0Ye4\"\n  id: \"chicagoruby-meetup-february-2026\"\n  thumbnail_lg: \"https://img.youtube.com/vi/jG9YtRx0Ye4/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/jG9YtRx0Ye4/hqdefault.jpg\"\n  talks:\n    - title: \"A Framework for Learning\"\n      date: \"2026-02-04\"\n      published_at: \"2026-02-06\"\n      start_cue: \"19:12\"\n      end_cue: \"1:19:04\"\n      id: \"jeffrey-cohen-chicagoruby-meetup-february-2026\"\n      video_id: \"jeffrey-cohen-chicagoruby-meetup-february-2026\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - February 2026\"\n      description: |-\n        A non-technical talk on learning frameworks - spiral staircase learning, big-rocks-first approach, and finding contentment and growth in your career as a developer.\n      speakers:\n        - Jeffrey Cohen\n\n    - title: \"Milestones, Semantic Versioning & Automated Release Notes\"\n      date: \"2026-02-04\"\n      published_at: \"2026-02-06\"\n      start_cue: \"1:19:04\"\n      end_cue: \"2:05:12\"\n      id: \"brooke-kuhlmann-chicagoruby-meetup-february-2026\"\n      video_id: \"brooke-kuhlmann-chicagoruby-meetup-february-2026\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - February 2026\"\n      description: |-\n        Semantic versioning, Git tag trailers, and the Milestoner gem for automating release notes.\n      speakers:\n        - Brooke Kuhlmann\n\n- title: \"ChicagoRuby Meetup - March 2026\"\n  raw_title: \"Building Mobile Apps with Hotwire Native & Creating a Custom CI Platform -- ChicagoRuby Meetup\"\n  event_name: \"ChicagoRuby Meetup - March 2026\"\n  date: \"2026-03-04\"\n  published_at: \"2026-03-10\"\n  description: |-\n    Building Mobile Apps with Hotwire Native & Creating a Custom CI Platform\n\n    Speakers:\n    * Mike Dalton - \"Building iOS & Android Apps with Hotwire Native\"\n    * Jason Swett - \"How I Built My Own Continuous Integration Platform on Rails\"\n  video_provider: \"youtube\"\n  video_id: \"6VfjG9PxD-0\"\n  id: \"chicagoruby-meetup-march-2026\"\n  thumbnail_lg: \"https://img.youtube.com/vi/6VfjG9PxD-0/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/6VfjG9PxD-0/hqdefault.jpg\"\n  talks:\n    - title: \"Building iOS & Android Apps with Hotwire Native\"\n      date: \"2026-03-04\"\n      published_at: \"2026-03-10\"\n      start_cue: \"24:08\"\n      end_cue: \"1:26:47\"\n      id: \"mike-dalton-chicagoruby-meetup-march-2026\"\n      video_id: \"mike-dalton-chicagoruby-meetup-march-2026\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - March 2026\"\n      description: |-\n        Rails app inside native mobile containers using Hotwire Native, bridge components, Turbo Frames and Streams for building iOS and Android apps.\n      speakers:\n        - Mike Dalton\n\n    - title: \"How I Built My Own Continuous Integration Platform on Rails\"\n      date: \"2026-03-04\"\n      published_at: \"2026-03-10\"\n      start_cue: \"1:26:47\"\n      end_cue: \"2:03:27\"\n      id: \"jason-swett-chicagoruby-meetup-march-2026\"\n      video_id: \"jason-swett-chicagoruby-meetup-march-2026\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - March 2026\"\n      description: |-\n        Building Saturn CI, a custom continuous integration platform with Rails, Docker, and shell scripts.\n      speakers:\n        - Jason Swett\n- id: \"chicagoruby-meetup-april-2026\"\n  title: \"ChicagoRuby Meetup - April 2026\"\n  date: \"2026-04-01\"\n  video_id: \"chicagoruby-chicagoruby-paypal-braintree\"\n  video_provider: \"scheduled\"\n  description: |-\n    Our Host: Paypal/Braintree - For over 25 years, PayPal has revolutionized global commerce with innovative experiences that make shopping, selling, and sending money simple, personalized, and secure. We empower consumers and businesses in nearly 200 markets to thrive in the global economy. **Speakers:** ⁭ **Joel Hawksley (remote) -** Beyond Senior: Consider the staff path! You’re at senior, but you’re hungry for more. What’s next? In this talk, we’ll attempt to define the staff role and help you decide if it’s a good fit for your career. **About Joel:** _Joel is a staff software engineer at GitHub, working on the health of the GitHub.com Rails monolith._ ⁭ **Tyler Ewing (in person) -** Your Business Workflows Are Invisible But They Shouldn't Be Every Rails app has critical business processes hiding in plain sight: scattered across background jobs, boolean columns, and callback chains that no one can fully trace. In this talk, we will live-refactor a realistic onboarding workflow from tangled, implicit logic into an explicit, readable pipeline, showing how treating workflows as first-class objects transforms your ability to debug, observe, and reason about what your app is actually doing. **About Tyler:** With over a decade of experience in Ruby, Tyler Ewing runs his own shop that created and maintains Ductwork: a Ruby workflow framework. He lives on the north side of Chicago.\n\n    https://www.meetup.com/chicagoruby/events/313433468/\n  talks: []\n"
  },
  {
    "path": "data/chicagoruby/series.yml",
    "content": "---\nname: \"ChicagoRuby\"\nwebsite: \"https://chicagoruby.org\"\nmeetup: \"https://www.meetup.com/ChicagoRuby\"\nvimeo: \"https://vimeo.com/chicagoruby\"\ntwitter: \"chicagoruby\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"ChicagoRubyMeetups\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCjlqhpqtKHGmM7O12QB_N9A\"\n"
  },
  {
    "path": "data/conferencia-rails/conferencia-rails-2009/event.yml",
    "content": "# https://github.com/fguillen/ConfRoR2009\n# https://discuss.rubyonrails.org/t/call-for-papers-for-the-spanish-rails-conference-2009/46313\n---\nid: \"conferencia-rails-2009\"\ntitle: \"Conferencia Rails 2009\"\ndescription: \"\"\nlocation: \"Madrid, Spain\"\nkind: \"conference\"\nstart_date: \"2009-11-13\"\nend_date: \"2009-11-14\"\nwebsite: \"http://www.conferenciarails.org\"\ntwitter: \"conferenciaror\"\ncoordinates:\n  latitude: 40.41672790000001\n  longitude: -3.7032905\n"
  },
  {
    "path": "data/conferencia-rails/conferencia-rails-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://conferenciaror.es/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/conferencia-rails/conferencia-rails-2010/event.yml",
    "content": "# https://discuss.rubyonrails.org/t/call-for-papers-for-conferencia-rails-2010-in-madrid/54328\n# https://drodriguez.github.io/schedule5/\n---\nid: \"conferencia-rails-2010\"\ntitle: \"Conferencia Rails 2010\"\ndescription: \"\"\nlocation: \"Madrid, Spain\"\nkind: \"conference\"\nstart_date: \"2010-11-04\"\nend_date: \"2010-11-05\"\nwebsite: \"http://conferenciaror.es/\"\ntwitter: \"conferenciaror\"\ncoordinates:\n  latitude: 40.41672790000001\n  longitude: -3.7032905\n"
  },
  {
    "path": "data/conferencia-rails/conferencia-rails-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://conferenciaror.es/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/conferencia-rails/conferencia-rails-2016/event.yml",
    "content": "---\nid: \"conferencia-rails-2016\"\ntitle: \"Conferencia Rails 2016\"\ndescription: \"\"\nlocation: \"Madrid, Spain\"\nkind: \"conference\"\nstart_date: \"2016-10-13\"\nend_date: \"2016-10-15\"\nwebsite: \"http://conferenciaror.es/\"\ntwitter: \"conferenciaror\"\ncoordinates:\n  latitude: 40.41672790000001\n  longitude: -3.7032905\n"
  },
  {
    "path": "data/conferencia-rails/conferencia-rails-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://conferenciaror.es/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/conferencia-rails/series.yml",
    "content": "---\nname: \"Conferencia Rails\"\nwebsite: \"http://conferenciaror.es/\"\ntwitter: \"conferenciaror\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/deccan-queen-on-rails/deccan-queen-on-rails-2026/cfp.yml",
    "content": "---\n- link: \"https://cfp.deccanqueenonrails.com/\"\n  name: \"Call for Proposals\"\n  open_date: \"2026-03-05\"\n  close_date: \"2026-05-31\"\n"
  },
  {
    "path": "data/deccan-queen-on-rails/deccan-queen-on-rails-2026/event.yml",
    "content": "---\nid: \"deccan-queen-on-rails-2026\"\ntitle: \"Deccan Queen on Rails 2026\"\nkind: \"conference\"\nyear: 2026\nstart_date: \"2026-10-08\"\nend_date: \"2026-10-09\"\nlocation: \"Pune, Maharashtra, India\"\nwebsite: \"https://deccanqueenonrails.com/\"\ntwitter: \"hideccanqueen\"\nstatus: \"scheduled\"\nbanner_background: \"#F7E3D4\"\nfeatured_background: \"#F7E3D4\"\nfeatured_color: \"#981B34\"\ncoordinates:\n  latitude: 18.5204\n  longitude: 73.8567\n"
  },
  {
    "path": "data/deccan-queen-on-rails/deccan-queen-on-rails-2026/videos.yml",
    "content": "---\n"
  },
  {
    "path": "data/deccan-queen-on-rails/series.yml",
    "content": "---\nname: \"Deccan Queen on Rails\"\nwebsite: \"https://deccanqueenonrails.com/\"\ntwitter: \"hideccanqueen\"\nlinkedin: \"https://www.linkedin.com/company/deccan-queen-on-rails\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"IN\"\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2014/event.yml",
    "content": "---\nid: \"deccanrubyconf-2014\"\ntitle: \"DeccanRubyConf 2014\"\ndescription: \"\"\nlocation: \"Pune, India\"\nkind: \"conference\"\nstart_date: \"2014-07-19\"\nend_date: \"2014-07-19\"\nwebsite: \"https://web.archive.org/web/20140525045009/http://www.deccanrubyconf.org/\"\noriginal_website: \"https://www.deccanrubyconf.org\"\ncoordinates:\n  latitude: 18.5246091\n  longitude: 73.8786239\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2015/event.yml",
    "content": "---\nid: \"deccanrubyconf-2015\"\ntitle: \"DeccanRubyConf 2015\"\ndescription: \"\"\nlocation: \"Pune, India\"\nkind: \"conference\"\nstart_date: \"2015-08-08\"\nend_date: \"2015-08-08\"\nwebsite: \"https://web.archive.org/web/20150910064029/http://www.deccanrubyconf.org/\"\noriginal_website: \"https://www.deccanrubyconf.org\"\ncoordinates:\n  latitude: 18.5246091\n  longitude: 73.8786239\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2016/event.yml",
    "content": "---\nid: \"deccanrubyconf-2016\"\ntitle: \"DeccanRubyConf 2016\"\ndescription: |-\n  6th Aug. 2016 Conference at Hyatt Regency Pune. 7th Aug. 2016 Workshops\nlocation: \"Pune, India\"\nkind: \"conference\"\nstart_date: \"2016-08-06\"\nend_date: \"2016-08-06\"\nwebsite: \"https://web.archive.org/web/20160729201845/http://www.deccanrubyconf.org/\"\noriginal_website: \"https://www.deccanrubyconf.org\"\nplaylist: \"https://www.youtube.com/playlist?list=PLo3sQWbYZbskTlzH7Ert-FucR7QmIuwE5\"\ncoordinates:\n  latitude: 18.5246091\n  longitude: 73.8786239\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2016/schedule.yml",
    "content": "---\ndays:\n  - name: \"Conference Talks\"\n    date: \"2016-08-06\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:15\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Kickoff\n\n      - start_time: \"09:30\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Tea Break\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"12:15\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"12:45\"\n        slots: 1\n        items:\n          - Cancelled speaker\n\n      - start_time: \"12:45\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Tea Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Lightening Talks\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - Open Hours\n\n      - start_time: \"18:30\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Party!\n\n  - name: \"Workshops\"\n    date: \"2016-08-07\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"16:00\"\n        slots: 2\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2016/videos.yml",
    "content": "---\n- id: \"ernie-miller-deccanrubyconf-2016\"\n  title: \"Opening Keynote\"\n  raw_title: \"Opening Keynote by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  date: \"2016-08-06\"\n  event_name: \"DeccanRubyConf 2016\"\n  published_at: \"2016-09-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"9kh3-_JOkmA\"\n\n- id: \"aditya-godbole-deccanrubyconf-2016\"\n  title: \"Programming in the large - designing with Interfaces\"\n  raw_title: \"Programming in the large - designing with Interfaces by Aditya Godbole\"\n  speakers:\n    - Aditya Godbole\n  date: \"2016-08-06\"\n  event_name: \"DeccanRubyConf 2016\"\n  published_at: \"2016-09-01\"\n  description: |-\n    Software design is about people. As the development team size grows, the strengths of Ruby start becoming its weaknesses. In this talk, we will see how we can deal with this problem.\n  video_provider: \"youtube\"\n  video_id: \"Tc6izy_oeus\"\n\n- id: \"mike-north-deccanrubyconf-2016\"\n  title: \"Phoenix for Rubyists\"\n  raw_title: \"Phoenix for Rubyists by Mike North\"\n  speakers:\n    - Mike North\n  date: \"2016-08-06\"\n  event_name: \"DeccanRubyConf 2016\"\n  published_at: \"2016-09-01\"\n  description: |-\n    Because Elixir and Phoenix borrow so many good ideas from the Rails ecosystem, it’s astoundingly easy for Ruby developers to become proficient in this powerful new set of tools. First, I’ll introduce Phoenix from a Rails POV, and then show two ways it can be used in conjunction with Rails.\n  video_provider: \"youtube\"\n  video_id: \"UFpV3BMyTiA\"\n\n- id: \"pramod-shinde-deccanrubyconf-2016\"\n  title: \"Lost while developing API's in Rails?\"\n  raw_title: \"Lost while developing API's in Rails? by Pramod Shinde\"\n  speakers:\n    - Pramod Shinde\n  date: \"2016-08-06\"\n  event_name: \"DeccanRubyConf 2016\"\n  published_at: \"2016-09-01\"\n  description: |-\n    As web development is leaning towards single page application’s with JS framework’s, scalable API’s are now critical. I will be talking about the WHAT, WHY and HOW of RoR JSON API’s. You will also see how to build generic API’s to serve web and mobile platforms.\n  video_provider: \"youtube\"\n  video_id: \"QRz3TjH-xCg\"\n\n- id: \"pat-allan-deccanrubyconf-2016\"\n  title: \"Open Source: Power and the Passion\"\n  raw_title: \"Open Source: Power and the Passion by Pat Allan\"\n  speakers:\n    - Pat Allan\n  date: \"2016-08-06\"\n  event_name: \"DeccanRubyConf 2016\"\n  published_at: \"2016-09-01\"\n  description: |-\n    You likely use open source software every day: in your code, tools, and servers. But is it the stable foundation we expected? Let’s look at the strengths & weaknesses of open source and trade in our assumptions for a greater awareness. Together let’s shape a more sustainable open source ecosystem!\n  video_provider: \"youtube\"\n  video_id: \"jhefKyHlrrU\"\n\n- id: \"arthur-neves-deccanrubyconf-2016\"\n  title: \"Using multiple connections in ActiveRecord\"\n  raw_title: \"Using multiple connections in ActiveRecord by Arthur Neves\"\n  speakers:\n    - Arthur Neves\n  date: \"2016-08-06\"\n  event_name: \"DeccanRubyConf 2016\"\n  published_at: \"2016-09-01\"\n  description: |-\n    Historically to handle multiple connections in Rails, you had to either patch active record or use a gem. Now, with some new apis on Rails 5.0, we can connect to multiple databases without needing any extra dependencies, and with just a few line of codes. And that will be even easier on Rails 5.1.\n  video_provider: \"youtube\"\n  video_id: \"-41V0qETxmE\"\n\n- id: \"santosh-wadghule-deccanrubyconf-2016\"\n  title: \"Aila! Caching in Rails\"\n  raw_title: \"Aila! Caching in Rails by Santosh Wadghule\"\n  speakers:\n    - Santosh Wadghule\n  date: \"2016-08-06\"\n  event_name: \"DeccanRubyConf 2016\"\n  published_at: \"2016-09-01\"\n  description: |-\n    I will be speaking on why caching is important and how we can scale up the Rails app using different caching strategies like page, action & fragment. I will also speak on how we can improve the performance in the simplest way by using instance variable caching for expensive command’s result.\n  video_provider: \"youtube\"\n  video_id: \"bQ9XGMXQMcw\"\n\n- id: \"jim-remsik-deccanrubyconf-2016\"\n  title: \"How (Not) To Build & Scale Teams\"\n  raw_title: \"How (Not) To Build & Scale Teams by Jim Remsik\"\n  speakers:\n    - Jim Remsik\n  date: \"2016-08-06\"\n  event_name: \"DeccanRubyConf 2016\"\n  published_at: \"2016-09-01\"\n  description: |-\n    Organizations time & again recognize desired results and attempt to achieve more success by doing more of the same. Two decades of experience and stories will show you what to look for and what to avoid in your next team whether your building it or being courted.\n  video_provider: \"youtube\"\n  video_id: \"wOovLjurfkw\"\n\n- id: \"nick-sutterer-deccanrubyconf-2016\"\n  title: \"Architecture Matters! A Trailblazer workshop\"\n  raw_title: \"Architecture Matters! A Trailblazer workshop by Nick Sutterer\"\n  speakers:\n    - Nick Sutterer\n  date: \"2016-08-07\"\n  event_name: \"DeccanRubyConf 2016\"\n  published_at: \"N/A\"\n  description: |-\n    Trailblazer adds new abstraction layers to Rails. It introduces operations, form objects, policies and, of course, more. Why this is a good thing, and how additional abstractions help to master complex web applications you will learn in this full-day workshop.\n  video_provider: \"not_recorded\"\n  video_id: \"nick-sutterer-deccanrubyconf-2016\"\n\n- id: \"mohit-thatte-sahil-muthoo-deccanrubyconf-2016\"\n  title: \"Automate your Infrastructure with Chef\"\n  raw_title: \"Automate your Infrastructure with Chef by Mohit Thatte, Sahil Muthoo\"\n  speakers:\n    - Mohit Thatte\n    - Sahil Muthoo\n  date: \"2016-08-07\"\n  event_name: \"DeccanRubyConf 2016\"\n  published_at: \"N/A\"\n  description: |-\n    This workshop will be a gentle introduction to the concepts of infrastructure automation with Chef. We will work on writing as much code as we can, so that attendees can get comfortable with the practical aspects of using Chef. The goal at the end of the workshop would be to be able to deploy a Rails app to AWS using your own Chef recipes and community cookbooks.\n  video_provider: \"not_recorded\"\n  video_id: \"mohit-thatte-sahil-muthoo-deccanrubyconf-2016\"\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2017/event.yml",
    "content": "---\nid: \"deccanrubyconf-2017\"\ntitle: \"DeccanRubyConf 2017\"\ndescription: |-\n  12th Aug. 2017 Conference at Sheraton Grand Pune\nlocation: \"Pune, India\"\nkind: \"conference\"\nstart_date: \"2017-08-12\"\nend_date: \"2017-08-12\"\nwebsite: \"https://web.archive.org/web/20170803192159/http://www.deccanrubyconf.org/\"\noriginal_website: \"https://www.deccanrubyconf.org\"\nplaylist: \"https://www.youtube.com/channel/UCaFWc_6VQ7lk11sU-AYUKtg\"\ncoordinates:\n  latitude: 18.5246091\n  longitude: 73.8786239\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: https://www.youtube.com/channel/UCaFWc_6VQ7lk11sU-AYUKtg\n---\n[]\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2018/event.yml",
    "content": "---\nid: \"deccanrubyconf-2018\"\ntitle: \"DeccanRubyConf 2018\"\ndescription: |-\n  4th Aug. 2018 Conference at Sheraton Grand Pune\nlocation: \"Pune, India\"\nkind: \"conference\"\nstart_date: \"2018-08-04\"\nend_date: \"2018-08-04\"\nwebsite: \"https://web.archive.org/web/20180831233454/https://www.deccanrubyconf.org/\"\noriginal_website: \"https://www.deccanrubyconf.org\"\nplaylist: \"https://www.youtube.com/playlist?list=PLo3sQWbYZbsm02wEkMvD9QB1qNeARuAJa\"\ncoordinates:\n  latitude: 18.5246091\n  longitude: 73.8786239\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.deccanrubyconf.org/\n# Videos: https://www.youtube.com/playlist?list=PLo3sQWbYZbsm02wEkMvD9QB1qNeARuAJa\n---\n[]\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2019/event.yml",
    "content": "---\nid: \"deccanrubyconf-2019\"\ntitle: \"DeccanRubyConf 2019\"\ndescription: \"\"\nlocation: \"Pune, India\"\nkind: \"conference\"\nstart_date: \"2019-08-10\"\nend_date: \"2019-08-10\"\nwebsite: \"https://web.archive.org/web/20190916105601/http://www.deccanrubyconf.org/\"\noriginal_website: \"https://www.deccanrubyconf.org\"\ncoordinates:\n  latitude: 18.5246091\n  longitude: 73.8786239\n"
  },
  {
    "path": "data/deccanrubyconf/deccanrubyconf-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://www.deccanrubyconf.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/deccanrubyconf/series.yml",
    "content": "---\nname: \"DeccanRubyConf\"\nwebsite: \"https://www.deccanrubyconf.org\"\ntwitter: \"deccanrubyconf\"\nmastodon: \"https://github.com/deccanrubyconf/deccanrubyconf.github.io\"\ngithub: \"https://github.com/deccanrubyconf\"\nyoutube_channel_name: \"DeccanRubyConf\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCaFWc_6VQ7lk11sU-AYUKtg\"\n"
  },
  {
    "path": "data/dotrb/dotrb-2013/event.yml",
    "content": "---\nid: \"PLMW8Xq7bXrG6ZItH9Oq2tceeTS0fjXyii\"\ntitle: \"dotRB 2013\"\ndescription: |-\n  https://www.dotconferences.com\nlocation: \"Paris, France\"\nkind: \"conference\"\nstart_date: \"2013-10-28\"\nend_date: \"2013-10-28\"\nwebsite: \"https://web.archive.org/web/20130517120138/http://www.dotrb.eu/\"\noriginal_website: \"http://www.dotrb.eu\"\ncoordinates:\n  latitude: 48.8575475\n  longitude: 2.3513765\n"
  },
  {
    "path": "data/dotrb/dotrb-2013/videos.yml",
    "content": "---\n- id: \"emily-stolfo-dotrb-2013\"\n  title: \"Thread Safety First!\"\n  raw_title: \"dotRB 2013 - Emily Stolfo - Thread Safety First!\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-06\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"d7UeQ8XoYeo\"\n\n- id: \"aaron-patterson-dotrb-2013\"\n  title: \"Panel: Ruby Implementors\"\n  raw_title: \"dotRB 2013 - The Ruby Implementors panel\"\n  speakers:\n    - Aaron Patterson\n    - Charles Nutter\n    - Brian Shirai\n    - Laurent Sansonetti\n    - Evan Phoenix\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-13\"\n  description: |-\n    The Ruby Implementors panel:\n\n    - Aaron Patterson (Committer to Ruby MRI and Ruby on Rails)\n    - Charles Nutter (Lead developer of JRuby)\n    - Brian Shirai (Creator of RubySpec, maintainer of Rubinius)\n    - Laurent Sansonetti (Creator of RubyMotion)\n    - Evan Phoenix (Creator of Rubinius)\n  video_provider: \"youtube\"\n  video_id: \"3hpRbIaMy20\"\n\n- id: \"konstantin-haase-dotrb-2013\"\n  title: \"Death to Cookies\"\n  raw_title: \"dotRB 2013 - Konstantin Haase - Death to Cookies\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"exwxOwT07pk\"\n\n- id: \"erik-michaels-ober-dotrb-2013\"\n  title: \"A Brief History of Technology Booms\"\n  raw_title: \"dotRB 2013 - Erik Michaels-Ober - A Brief History of Technology Booms\"\n  speakers:\n    - Erik Michaels-Ober\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-19\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"iXkPty3y7gA\"\n\n- id: \"bryan-helmkamp-dotrb-2013\"\n  title: \"Building a Culture of Code Quality\"\n  raw_title: \"dotRB 2013 - Bryan Helmkamp - Building a Culture of Code Quality\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-02-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"IadcIkBeBuI\"\n\n- id: \"ori-pekelman-dotrb-2013\"\n  title: \"Adoption Agency for Abandoned Repos (AAAR)\"\n  raw_title: \"dotRB 2013 - Ori Pekelman - Adoption Agency for Abandoned Repos (AAAR)\"\n  speakers:\n    - Ori Pekelman\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-03\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"NCufi3K6bcA\"\n\n- id: \"juris-galang-dotrb-2013\"\n  title: \"How we move code at ZenDesk\"\n  raw_title: \"dotRB 2013 - Juris Galang - How we move code at ZenDesk\"\n  speakers:\n    - Juris Galang\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zSP8w0vFvG4\"\n\n- id: \"wiktoria-dalach-dotrb-2013\"\n  title: \"Rails Girls Summer of Code\"\n  raw_title: \"dotRB 2013 - Wiktoria Dalach - Rails Girls Summer of Code\"\n  speakers:\n    - Wiktoria Dalach\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-06\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"O6nqLpsinok\"\n\n- id: \"gleb-mazovetskiy-dotrb-2013\"\n  title: \"Visual Version History\"\n  raw_title: \"dotRB 2013 - Gleb Mazovetskiy - Visual Version History\"\n  speakers:\n    - Gleb Mazovetskiy\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"VMhdKZDxFjg\"\n\n- id: \"agathe-begault-dotrb-2013\"\n  title: \"ACLs in REST APIs\"\n  raw_title: \"dotRB 2013 - Agathe Begault - ACLs in REST APIs\"\n  speakers:\n    - Agathe Begault\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-06\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"uUrDZLyYJLM\"\n\n- id: \"steve-klabnik-dotrb-2013\"\n  title: \"Web Browsers: Om nom nom\"\n  raw_title: \"dotRB 2013 - Steve Klabnik - Web Browsers: Om nom nom\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"hb19PzOswFk\"\n\n- id: \"kinsey-ann-durham-dotrb-2013\"\n  title: \"Becoming a Software Engineer\"\n  raw_title: \"dotRB 2013 - Kinsey Ann Durham - Becoming a Software Engineer\"\n  speakers:\n    - Kinsey Ann Durham\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Nf2B_8wy28w\"\n\n- id: \"george-brocklehurst-dotrb-2013\"\n  title: \"It's a UNIX system, I know this!\"\n  raw_title: \"dotRB 2013 - George Brocklehurst - It's a UNIX system, I know this!\"\n  speakers:\n    - George Brocklehurst\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-02-27\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Qucn0QuXFhc\"\n\n- id: \"terence-lee-dotrb-2013\"\n  title: \"A History of Fetching Specs\"\n  raw_title: \"dotRB 2013 - Terence Lee - A History of Fetching Specs\"\n  speakers:\n    - Terence Lee\n  event_name: \"dotRB 2013\"\n  date: \"2013-10-18\"\n  published_at: \"2014-03-12\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"WHdAmuiIpmE\"\n"
  },
  {
    "path": "data/dotrb/series.yml",
    "content": "---\nname: \"dotRB\"\nwebsite: \"https://web.archive.org/web/20130517120138/http://www.dotrb.eu/\"\nmastodon: \"\"\nyoutube_channel_name: \"dotconferences\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"dotRB\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/dresden-rb/dresden-rb-meetup/event.yml",
    "content": "---\nid: \"dresden-rb-meetup\"\ntitle: \"Dresden.rb Meetup\"\nlocation: \"Dresden, Germany\"\nkind: \"meetup\"\nwebsite: \"https://dresdenrb.onruby.de\"\nbanner_background: \"#FFF\"\nfeatured_background: \"#FFF\"\nfeatured_color: \"#393939\"\ncoordinates:\n  latitude: 51.0504088\n  longitude: 13.7372621\n"
  },
  {
    "path": "data/dresden-rb/dresden-rb-meetup/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors in 2025\"\n      description: |-\n        All sponsors supporting our user group in 2025!\n      level: -2025\n      sponsors:\n        - name: \"RubyCentral\"\n          website: \"https://rubycentral.org/\"\n          slug: \"rubycentral\"\n        - name: \"Fastly\"\n          website: \"https://www.fastly.com/\"\n          slug: \"fastly\"\n        - name: \"GitHub\"\n          website: \"https://github.com/\"\n          slug: \"github\"\n    - name: \"Hosting sponsors\"\n      description: |-\n        All companies hosting our user group!\n      level: 1\n      sponsors:\n        - name: \"webit!\"\n          slug: \"webit\"\n          website: \"https://www.webit.de/\"\n        - name: \"aifinyo\"\n          slug: \"aifinyo\"\n          website: \"https://www.aifinyo.de\"\n          logo_url: \"https://www.aifinyo.de/wp-content/uploads/2025/10/aifinyo-222.svg\"\n"
  },
  {
    "path": "data/dresden-rb/dresden-rb-meetup/videos.yml",
    "content": "---\n# Website: https://dresdenrb.onruby.de\n\n# 2024\n\n- id: \"dresden-rb-meetup-november-2024\"\n  title: \"Dresden.rb meetup November 2024\"\n  event_name: \"Dresden.rb meetup November 2024\"\n  date: \"2024-11-28\"\n  video_provider: \"children\"\n  video_id: \"dresden-rb-meetup-november-2024\"\n  description: |-\n    Die neue Ruby User Group in Dresden richtet sich an alle Interessierten, die sich für die Programmiersprache Ruby und deren vielfältige Anwendungen begeistern. Am 28.11.2024 um 19:00 findet das erste Meetup statt.\n\n    Ziel ist der Austausch von Wissen, Erfahrungen und Ideen durch regelmäßige Treffen, Vorträge und evtl. kleinere Workshops. Mitglieder können voneinander lernen, kreative Projekte vorstellen und die neuesten Trends der Community diskutieren. Ein paar Snacks und Getränke gibt es auch, und jeder ist herzlich willkommen!\n\n    The new Ruby User Group in Dresden is aimed at anyone interested in the Ruby programming language. The first meetup will take place on 28.11.2024 at 19:00. We want to exchange knowledge, experiences and ideas through regular meetings, lectures and possibly smaller workshops. Members can learn from each other, present creative projects and discuss the latest trends in the community. There are also a few snacks and drinks, and everyone is welcome!\n\n    https://dresdenrb.onruby.de/events/dresden-rb-meetup-november-2024-980\n  talks:\n    - title: \"Solid Queue in practice\"\n      event_name: \"Dresden.rb meetup November 2024\"\n      date: \"2024-11-28\"\n      video_provider: \"not_recorded\"\n      id: \"dresden-rb-meetup-november-2024-solid-queue-in-practice\"\n      video_id: \"dresden-rb-meetup-november-2024-solid-queue-in-practice\"\n      description: |-\n        An introduction to Solid Queue in Rails 8.\n      speakers:\n        - Johannes Balk\n\n    - title: \"Docker Swarm - What is it? How to set it up and use it?\"\n      event_name: \"Dresden.rb meetup November 2024\"\n      date: \"2024-11-28\"\n      video_provider: \"not_recorded\"\n      id: \"dresden-rb-meetup-november-2024-docker-swarm\"\n      video_id: \"dresden-rb-meetup-november-2024-docker-swarm\"\n      description: |-\n        I'll tell you all a little story about swarm.\n      speakers:\n        - Ben Rexin\n\n# 2025\n\n- id: \"dresden-rb-meetup-march-2025\"\n  title: \"Dresden.rb meetup March 2025\"\n  event_name: \"Dresden.rb meetup March 2025\"\n  date: \"2025-03-06\"\n  video_provider: \"children\"\n  video_id: \"dresden-rb-meetup-march-2025\"\n  description: |-\n    The new Ruby User Group in Dresden welcomes everyone with an interest in the Ruby programming language. Our second meetup will take place on March 6, 2025, at 19:00.\n\n    We aim to foster knowledge exchange, share experiences, and spark new ideas through regular meetups, talks, and occasional hands-on workshops. Members can learn from one another, showcase creative projects, and discuss the latest trends in the Ruby community. Plus, there will be pizza and drinks—everyone is welcome!\n\n    https://dresdenrb.onruby.de/events/dresden-rb-meetup-march-2025-1079\n  talks:\n    - title: \"Tackling increasing complexity in growing Ruby on Rails projects\"\n      event_name: \"Dresden.rb meetup March 2025\"\n      date: \"2025-03-06\"\n      video_provider: \"not_recorded\"\n      id: \"dresden-rb-meetup-march-2025-tackling-complexity-in-rails\"\n      video_id: \"dresden-rb-meetup-march-2025-tackling-complexity-in-rails\"\n      description: |-\n        Ruby on Rails is a framework designed for straightforward web development with MVC architecture. This talk is about problems with increasing complexity in growing projects and different approaches in software architecture to tackle these problems.\n      speakers:\n        - Steve Reinke\n\n- id: \"dresden-rb-meetup-may-2025\"\n  title: \"Dresden.rb meetup May 2025\"\n  event_name: \"Dresden.rb meetup May 2025\"\n  date: \"2025-05-22\"\n  video_provider: \"children\"\n  video_id: \"dresden-rb-meetup-may-2025\"\n  description: |-\n    The new Ruby User Group in Dresden welcomes everyone with an interest in the Ruby programming language. Our third meetup will take place on May 22 2025, at 19:00.\n\n    We aim to foster knowledge exchange, share experiences, and spark new ideas through regular meetups, talks, and occasional hands-on workshops. Members can learn from one another, showcase creative projects, and discuss the latest trends in the Ruby community.\n\n    https://dresdenrb.onruby.de/events/dresden-rb-meetup-may-2025-1475\n  talks:\n    - title: \"Kamal - Deploy web apps anywhere\"\n      event_name: \"Dresden.rb meetup May 2025\"\n      date: \"2025-05-21\"\n      video_provider: \"not_recorded\"\n      id: \"dresden-rb-meetup-may-2025-kamal\"\n      video_id: \"dresden-rb-meetup-may-2025-kamal\"\n      description: |-\n        Short intro to kamal including a live demo.\n\n        What will be covered:\n\n        * What is kamal\n        * Kamals concept\n        * What features are there\n        * Demo of build and deploy\n      speakers:\n        - Benjamin Deutscher\n    - title: \"Jarbler: Pack a Ruby application into an executable jar file.\"\n      event_name: \"Dresden.rb meetup May 2025\"\n      date: \"2025-05-21\"\n      video_provider: \"not_recorded\"\n      id: \"dresden-rb-meetup-may-2025-jarbler\"\n      video_id: \"dresden-rb-meetup-may-2025-jarbler\"\n      slides_url: \"https://speakerdeck.com/rammpeter/jarbler-run-a-ruby-application-as-java-jar-file\"\n      description: |-\n        Jarbler is a solution that packages Ruby applications in a jar file so that they can be executed on the target environment without a Ruby runtime environment under Java.\n\n        https://github.com/rammpeter/jarbler\n\n        The main motivation for the function in principle is to be able to run Ruby applications without Ruby being installed on the target system. This is particularly important for frequently used apps where the various runtime environments in Linux, Windows or Mac OS are not known beforehand. Java is a lower hurdle than Ruby. The driver for Development of this tool was that the actual standard tool “Warbler” was only poorly maintained in the JRuby cosmos and was no longer usable with the current JRuby versions.\n\n        Jarbler can be used as a standalone gem, may one day migrate to JRuby as a standard tool.\n      speakers:\n        - Peter Ramm\n      additional_resources:\n        - name: \"rammpeter/jarbler\"\n          type: \"repo\"\n          url: \"https://github.com/rammpeter/jarbler\"\n\n- id: \"dresden-rb-meetup-august-2025\"\n  title: \"Dresden.rb meetup August 2025\"\n  event_name: \"Dresden.rb meetup August 2025\"\n  date: \"2025-08-21\"\n  video_provider: \"children\"\n  video_id: \"dresden-rb-meetup-august-2025\"\n  description: |-\n    The new Ruby User Group in Dresden welcomes everyone with an interest in the Ruby programming language. Our fourth meetup will take place on August 21, 2025, at 19:00.\n\n    We aim to foster knowledge exchange, share experiences, and spark new ideas through regular meetups, talks, and occasional hands-on workshops. Members can learn from one another, showcase creative projects, and discuss the latest trends in the Ruby community. Plus, there will be pizza and drinks—everyone is welcome!\n\n    https://dresdenrb.onruby.de/events/dresden-rb-meetup-august-2025-1772\n  talks:\n    - title: \"Automatische Generierung von Ruby-Quellcodedokumentation mit lokal laufenden LLMs (German)\"\n      event_name: \"Dresden.rb meetup August 2025\"\n      date: \"2025-08-21\"\n      language: \"german\"\n      video_provider: \"not_recorded\"\n      id: \"dresden-rb-meetup-august-2025-llm-generated-documentation\"\n      video_id: \"dresden-rb-meetup-august-2025-llm-generated-documentation\"\n      description: |-\n        Automatische Generierung von Ruby-Quellcodedokumentation mit lokal laufenden LLMs (via Ollama), inklusive Qualitätsbewertung. (German)\n      speakers:\n        - Hadi Al Qawas\n    - title: \"No Browser Required: Dynamic OpenGraph Images with Rails and Rust\"\n      event_name: \"Dresden.rb meetup August 2025\"\n      date: \"2025-08-21\"\n      video_provider: \"not_recorded\"\n      id: \"dresden-rb-meetup-august-2025-himg\"\n      video_id: \"dresden-rb-meetup-august-2025-himg\"\n      description: |-\n        How would you convert a <div> to a PNG? A technical deep dive into how Himg generates images from HTML without using a browser.\n\n        We'll cover a mix of technical detail like parsing and rendering, practical code like calling Rust from Ruby, and business tricks like using OpenGraph images to make your links less boring to help you go viral 🦋\n      speakers:\n        - Jamed EdJo\n\n- id: \"dresden-rb-meetup-november-2025\"\n  title: \"Dresden.rb meetup November 2025\"\n  event_name: \"Dresden.rb meetup November 2025\"\n  date: \"2025-11-06\"\n  video_provider: \"children\"\n  video_id: \"dresden-rb-meetup-november-2025\"\n  description: |-\n    The new Ruby User Group in Dresden welcomes everyone with an interest in the Ruby programming language. Our fifth meetup will take place on November 06, 2025, at 19:00.\n\n    We aim to foster knowledge exchange, share experiences, and spark new ideas through regular meetups, talks, and occasional hands-on workshops. Members can learn from one another, showcase creative projects, and discuss the latest trends in the Ruby community. Plus, there will be snacks and drinks—everyone is welcome!\n\n    https://dresdenrb.onruby.de/events/dresden-rb-meetup-november-2025-1970\n  talks:\n    - title: \"Give me a BEAM long enough and I will move the world - An introduction to the Elixir programming language\"\n      event_name: \"Dresden.rb meetup November 2025\"\n      date: \"2025-11-06\"\n      video_provider: \"not_recorded\"\n      id: \"dresden-rb-meetup-november-2025-elixir\"\n      video_id: \"dresden-rb-meetup-november-2025-elixir\"\n      description: |-\n        An introduction to the Elixir programming language, its advantages, and when to use it, with particular reference to concurrency and parallelism.\n      speakers:\n        - Felix Stüber\n"
  },
  {
    "path": "data/dresden-rb/series.yml",
    "content": "---\nname: \"Dresden.rb\"\nwebsite: \"https://dresdenrb.onruby.de/\"\nyoutube_channel_name: \"\"\nkind: \"meetup\"\nfrequency: \"quarterly\"\nlanguage: \"english\"\ndefault_country_code: \"DE\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/emea-on-rails/emea-on-rails-2021/event.yml",
    "content": "---\nid: \"PL-pWnolRukJX1d7-cxY2jruggH47EplAe\"\ntitle: \"EMEA on Rails 2021\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  The conference experience, minus the jetlag! There are so many Rubyists in Europe, the Middle East, and Africa, but we haven\"t managed to gather much in the past year, and we could definitely learn a lot from each other. Let\"s get together (virtually for now) and experience some of the excitement of an international conference (remember those?), without jetlag or timezone challenges! Our first event will be a meetup-of-meetups featuring EMEA speakers from this past RailsConf and recent EMEA conferences.\npublished_at: \"2021-09-30\"\nstart_date: \"2021-06-09\"\nend_date: \"2021-06-09\"\nchannel_id: \"UCpFp-lBTusrapElhe4hYhxA\"\nyear: 2021\nbanner_background: \"#000000\"\nfeatured_background: \"#F6F7FC\"\nfeatured_color: \"#AD3E3E\"\ncoordinates: false\n"
  },
  {
    "path": "data/emea-on-rails/emea-on-rails-2021/videos.yml",
    "content": "---\n# TODO: running order of talks\n# TODO: tracks\n# TODO: schedule\n\n# Website: https://emeaonrails.com\n# Schedule: https://emeaonrails.com\n\n- id: \"hongli-lai-emea-on-rails-2021\"\n  title: \"Democratizing the Fight Against Ruby Memory Bloat\"\n  raw_title: \"Democratizing the Fight Against Ruby Memory Bloat - Hongli Lai\"\n  speakers:\n    - Hongli Lai\n  event_name: \"EMEA on Rails 2021\"\n  date: \"2021-06-09\"\n  description: |-\n    Ruby apps can use a lot of memory, but not for the reasons you think. I've discovered that as much as 70% of the memory usage is not caused by Ruby, but by the system's memory allocator! The good news is that there are technically simple solutions. So why isn't everybody using them? That's the bad news: they're cumbersome to deploy. We can say that the solutions are not \"democratized\".\n\n    I'm on a mission to allow everyone to easily get rid of Ruby memory bloat. In this talk I'll explain where Ruby memory bloat comes from, what the solutions are, and how I'm working on democratizing the solutions in the form of Fullstaq Ruby. I will also talk about my efforts to make Fullstaq Ruby a sustainable open source project.\n\n    This talk was delivered at EMEA on Rails, a virtual mega-meetup which took place on June 9, 2021.\n  video_provider: \"youtube\"\n  video_id: \"-zlfQm6rEh0\"\n  published_at: \"2021-12-09\"\n\n- id: \"vladimir-dementyev-emea-on-rails-2021\"\n  title: \"Frontendless Rails Frontend\"\n  raw_title: \"Frontendless Rails Frontend - Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"EMEA on Rails 2021\"\n  date: \"2021-06-09\"\n  description: |-\n    Everything is cyclical, and web development is not an exception: ten years ago, we enjoyed developing Rails apps using HTML forms, a bit of AJAX, and jQuery—our productivity had no end! As interfaces gradually became more sophisticated, the \"classic\" approach began to give way to frontend frameworks, pushing Ruby into an API provider's role.\n\n    The situation started to change; the \"new wave\" is coming, and ViewComponent, StimulusReflex, and Hotwire are riding the crest.\n\n    In this talk, I'd like to demonstrate how we can develop modern \"frontend\" applications in the New Rails Way.\n\n    This talk was delivered at EMEA on Rails, a virtual mega-meetup which took place on June 9, 2021\n  video_provider: \"youtube\"\n  video_id: \"5fDPPUinTq4\"\n  published_at: \"2021-12-09\"\n\n- id: \"michael-kimathi-emea-on-rails-2021\"\n  title: \"A History of Nairuby and Tech Development in Africa: Impacting through Solutions\"\n  raw_title: \"A History of Nairuby and Tech Development in Africa: Impacting through Solutions - Michael Kimathi\"\n  speakers:\n    - Michael Kimathi\n  event_name: \"EMEA on Rails 2021\"\n  date: \"2021-06-09\"\n  description: |-\n    What is a tech community? Why should you join a tech community? How can you add value to a community you are a member of? Nairuby has come a long way and so has the tech ecosystem. Reminiscing about the community journey will guide us for the next few decades.\n\n    This talk was delivered at EMEA on Rails, a virtual mega-meetup which took place on June 9, 2021.\n  video_provider: \"youtube\"\n  video_id: \"TUV6WKrFiTo\"\n  published_at: \"2021-12-09\"\n\n- id: \"jonas-jabari-emea-on-rails-2021\"\n  title: 'Beautiful reactive web UIs, Ruby and you: The RailsConf \"Live Demo\" Addon'\n  raw_title: 'Beautiful reactive web UIs, Ruby and you: The RailsConf \"Live Demo\" Addon - Jonas Jabari'\n  speakers:\n    - Jonas Jabari\n  event_name: \"EMEA on Rails 2021\"\n  date: \"2021-06-09\"\n  description: |-\n    A lot of life changing things have happened in 2020. And I'm obviously speaking about Stimulus Reflex and Hotwire and how we as Rails devs are finally enabled to skip a lot of JS while implementing reactive web UIs. But what if I told you, there's room for even more developer happiness? Imagine crafting beautiful UIs in pure Ruby, utilizing a library reaching from simple UI components representing basic HTML tags over styled UI concepts based on Bootstrap to something like a collection, rendering reactive data sets. Beautiful, reactive web UIs implemented in pure Ruby are waiting for you!\n\n    This talk was delivered at EMEA on Rails, a virtual mega-meetup which took place on June 9, 2021.\n  video_provider: \"youtube\"\n  video_id: \"2P8NRoqUgCE\"\n  published_at: \"2021-12-09\"\n\n- id: \"tanaka-mutakwa-emea-on-rails-2021\"\n  title: \"Making the Leap into Teach Leadership\"\n  raw_title: \"Making the Leap into Teach Leadership - Tanaka Mutakwa\"\n  speakers:\n    - Tanaka Mutakwa\n  event_name: \"EMEA on Rails 2021\"\n  date: \"2021-06-09\"\n  description: |-\n    Taking on a technology leadership role is a tough transition for any developer, because only part of the skills and experience you had as a developer prepares you for the expectations of a new role. In this talk I will share common challenges new tech leaders face and how to tackle them.\n\n    This talk was delivered at EMEA on Rails, a virtual mega-meetup which took place on June 9, 2021.\n  video_provider: \"youtube\"\n  video_id: \"MkMLNNfa3RU\"\n  published_at: \"2021-12-09\"\n\n- id: \"ramon-huidobro-emea-on-rails-2021\"\n  title: \"New dev, old codebase: A series of mentorship stories\"\n  raw_title: \"New dev, old codebase: A series of mentorship stories - Ramón Huidobro\"\n  speakers:\n    - Ramón Huidobro\n  event_name: \"EMEA on Rails 2021\"\n  date: \"2021-06-09\"\n  description: |-\n    Mentorship in software development carries a lot of responsibility, but plays an integral part in making tech communities as well as individuals thrive.\n\n    In this talk, we'll go over some of my mentorship experiences, adopting techniques and learning to teach, so we can teach to learn. Anyone can be a great mentor!\n\n    This talk was delivered at EMEA on Rails, a virtual mega-meetup which took place on June 9, 2021.\n  video_provider: \"youtube\"\n  video_id: \"5uYCpBdtLmk\"\n  published_at: \"2021-12-09\"\n\n- id: \"maciek-rzasa-emea-on-rails-2021\"\n  title: \"API Optimization Tale: Monitor, Fix and Deploy on Friday\"\n  raw_title: \"API Optimization Tale: Monitor, Fix and Deploy on Friday - Maciek Rząsa\"\n  speakers:\n    - Maciek Rząsa\n  event_name: \"EMEA on Rails 2021\"\n  date: \"2021-10-21\"\n  description: |-\n    I saw a green build on a Friday afternoon. I knew I need to push it to production before the weekend. My gut told me it was a trap. I had already stayed late to revert a broken deploy. I knew the risk.\n\n    In the middle of a service extraction project, we decided to migrate from REST to GraphQL and optimize API usage. My deploy was a part of this radical change.\n\n    Why was I deploying so late? How did we measure the migration effects? And why was I testing on production? I'll tell you a tale of small steps, monitoring, and old tricks in a new setting. Hope, despair, and broken production included.\n\n    This talk was delivered at EMEA on Rails, a virtual mega-meetup which took place on June 9, 2021.\n  video_provider: \"youtube\"\n  video_id: \"-UgDdlG0tIc\"\n  published_at: \"2021-12-09\"\n\n- id: \"miriam-tocino-emea-on-rails-2021\"\n  title: \"Zerus & Ona: A warm welcome to the world of technology\"\n  raw_title: \"Zerus & Ona: A warm welcome to the world of technology - Miriam Tocino\"\n  speakers:\n    - Miriam Tocino\n  event_name: \"EMEA on Rails 2021\"\n  date: \"2021-10-21\"\n  description: |-\n    Young children are growing up highly surrounded by technology without knowing what's behind it. How do we spark their curiosity and introduce them to the world of technology to not only use it as consumers but to start seeing themselves as creators?\n\n    In this workshop, you'll get to know Zerus and Ona, a 0 and a 1, living inside your computer and sharing their adventures in The Binary World. Along with Miriam, you'll create a new story from scratch that will inspire every child to learn more about technology and start gaining superpowers.\n\n    This talk was delivered at EMEA on Rails, a virtual mega-meetup which took place on June 9, 2021.\n  video_provider: \"youtube\"\n  video_id: \"AGMofrIsTlM\"\n  published_at: \"2021-12-09\"\n\n- id: \"ben-greenberg-emea-on-rails-2021\"\n  title: \"Self-Care on Rails\"\n  raw_title: \"Self-Care on Rails - Ben Greenberg\"\n  speakers:\n    - Ben Greenberg\n  event_name: \"EMEA on Rails 2021\"\n  date: \"2021-10-21\"\n  description: |-\n    This past year has been one of the most challenging years in recent memory. The pandemic has taken a toll, including on children.\n\n    Adults used their professional skills to help make the year a little better for the kids in our lives: Therapists counseled, entertainers delighted, teachers educated... and Rails developers developed!\n\n    In this talk, I'll share the apps I built on Rails that helped my kids and me cope, celebrate and persevere through the year.\n\n    In 2020, tech was pivotal in keeping us going, and for my kids, Rails made the year a little more manageable.\n\n    This talk was delivered at EMEA on Rails, a virtual mega-meetup which took place on June 9, 2021.\n  video_provider: \"youtube\"\n  video_id: \"HuhzXPB1wQg\"\n  published_at: \"2021-12-09\"\n# TODO: missing talk: Ufuk Kayserilioglu - The Curious Case of the Bad Clone\n# TODO: missing workshop: Avital Tzubeli - Storytelling for Tech People\n# TODO: missing workshop: Miriam Tocino - Zerus & Ona: A warm welcome to the world of technology\n"
  },
  {
    "path": "data/emea-on-rails/series.yml",
    "content": "---\nname: \"EMEA on Rails\"\nwebsite: \"https://emeaonrails.com\"\ntwitter: \"emeaonrails\"\nkind: \"meetup\"\nfrequency: \"yearly\"\nplaylist_matcher: \"EMEA on Rails\"\ndefault_country_code: \"IL\"\nyoutube_channel_name: \"emeaonrails9306\"\nlanguage: \"english\"\nyoutube_channel_id: \"PL-pWnolRukJX1d7-cxY2jruggH47EplAe\"\n"
  },
  {
    "path": "data/erubycon/erubycon-2009/event.yml",
    "content": "---\nid: \"erubycon-2009\"\ntitle: \"eRubyCon 2009\"\ndescription: \"\"\nlocation: \"Columbus, OH, United States\"\nkind: \"conference\"\nstart_date: \"2009-08-07\"\nend_date: \"2009-08-09\"\noriginal_website: \"http://erubycon.com/\"\ncoordinates:\n  latitude: 39.9625112\n  longitude: -83.0032218\n"
  },
  {
    "path": "data/erubycon/erubycon-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/erubycon/series.yml",
    "content": "---\nname: \"eRubyCon\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"US\"\n"
  },
  {
    "path": "data/eurucamp/eurucamp-2014/event.yml",
    "content": "---\nid: \"eurucamp-2014\"\ntitle: \"eurucamp 2014\"\ndescription: |-\n  where Ruby conference meets camp\nlocation: \"Potsdam, Germany\"\nkind: \"conference\"\nstart_date: \"2014-08-01\"\nend_date: \"2014-08-03\"\nwebsite: \"http://2014.eurucamp.org\"\ntwitter: \"eurucamp\"\nplaylist: \"http://media.eurucamp.org/\"\ncoordinates:\n  latitude: 52.3905689\n  longitude: 13.0644729\n"
  },
  {
    "path": "data/eurucamp/eurucamp-2014/videos.yml",
    "content": "---\n- title: \"RubyMotion and Accessibility\"\n  raw_title: \"eurucamp 2014 - RubyMotion and Accessibility by Austin Seraphin\"\n  speakers:\n    - Austin Seraphin\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_austin-seraphin_rubymotion-and-accessibility.webm\"\n  id: \"austin-seraphin-rubymotion-and-accessibility-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Not being an asshole is not enough\"\n  raw_title: \"eurucamp 2014 - Not being an asshole is not enough by Ellen Koenig\"\n  speakers:\n    - Ellen Koenig\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014-ellen-koenig_not-being-an-asshole-is-not-enough.webm\"\n  id: \"ellen-koenig-not-being-an-asshole-is-not-enough-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Let's build a game with Ruby\"\n  raw_title: \"eurucamp 2014 - Let's build a game with Ruby by Rin Raeuber\"\n  speakers:\n    - Rin Raeuber\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_rin-raeuber_lets-build-a-game-with-ruby.webm\"\n  id: \"rin-raeuber-lets-build-a-game-with-ruby-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Refactoring Ruby with Monads(or, Monads: The Good Parts)\"\n  raw_title: \"eurucamp 2014 - Refactoring Ruby with Monads(or, Monads: The Good Parts) by Tom Stuart\"\n  speakers:\n    - Tom Stuart\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_tom-stuart_refactoring-ruby-with-monads.webm\"\n  id: \"tom-stuart-refactoring-ruby-with-monadsor-monads-the-good-parts-eurucamp-2014\"\n  description: \"\"\n\n- title: \"The Scientific Method of Troubleshooting\"\n  raw_title: \"eurucamp 2014 - The Scientific Method of Troubleshooting by Blithe Rocher\"\n  speakers:\n    - Blithe Rocher\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_blithe-rocher_the-scientific-method-of-troubleshooting.webm\"\n  id: \"blithe-rocher-the-scientific-method-of-troubleshooting-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Internet of Dusty Things\"\n  raw_title: \"eurucamp 2014 - Internet of Dusty Things by Daniel Bovensiepen\"\n  speakers:\n    - Daniel Bovensiepen\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_daniel-bovensiepen_the-internet-of-dusty-things.webm\"\n  id: \"daniel-bovensiepen-internet-of-dusty-things-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Utils is a Junk Drawer!\"\n  raw_title: \"eurucamp 2014 - Utils is a Junk Drawer! by Frank Webber\"\n  speakers:\n    - Frank Webber\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_franklin-webber_utils-is-a-junk-drawer.webm\"\n  id: \"frank-webber-utils-is-a-junk-drawer-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Culture Eats Products For Breakfast\"\n  raw_title: \"eurucamp 2014 - Culture Eats Products For Breakfast by Laura Eck\"\n  speakers:\n    - Laura Eck\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_laura-eck_culture-eats-product-for-breakfast.webm\"\n  id: \"laura-eck-culture-eats-products-for-breakfast-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Decentralise ALL THE THINGS!\"\n  raw_title: \"eurucamp 2014 - Decentralise ALL THE THINGS! by Jan Krutisch\"\n  speakers:\n    - Jan Krutisch\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_jan_krutisch_-_decentralise_all_the_things.webm\"\n  id: \"jan-krutisch-decentralise-all-the-things-eurucamp-2014\"\n  description: \"\"\n\n- title: \"It Takes a Village to Make a Programmer\"\n  raw_title: \"eurucamp 2014 - It Takes a Village to Make a Programmer by Michelle Guido\"\n  speakers:\n    - Michelle Guido\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_michele-guido_it-takes-a-village-to-make-a-programmer.webm\"\n  id: \"michelle-guido-it-takes-a-village-to-make-a-programmer-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Hello, SOA World!\"\n  raw_title: \"eurucamp 2014 - Hello, SOA World! by Grayson Wright\"\n  speakers:\n    - Grayson Wright\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_grayson-wright_hello-soa-world.webm\"\n  id: \"grayson-wright-hello-soa-world-eurucamp-2014\"\n  description: \"\"\n\n- title: \"How Ruby helps get more Women on stage\"\n  raw_title: \"eurucamp 2014 - How Ruby helps get more Women on stage by Maren Heltsche & Anja R.\"\n  speakers:\n    - Maren Heltsche\n    - Anja R.\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_maren-heltsche-and-anja-r_how-ruby-helps-get-more-women-on-stage.webm\"\n  id: \"maren-heltsche-anja-r-how-ruby-helps-get-more-women-on-stage-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Web Controlled Automation\"\n  raw_title: \"eurucamp 2014 - Web Controlled Automation by Tworit Kumar Dash\"\n  speakers:\n    - Tworit Kumar Dash\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_tworit_kumar_dash_-_web_controlled_automation.webm\"\n  id: \"tworit-kumar-dash-web-controlled-automation-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Code, Complexity and Frogs\"\n  raw_title: \"eurucamp 2014 - Code, Complexity and Frogs by Paolo 'Nusco' Perrotta\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_paolo-perrotta_keynote.webm\"\n  id: \"paolo-nusco-perrotta-code-complexity-and-frogs-eurucamp-2014\"\n  description: \"\"\n\n- title: \"How I tried to self medicate my depression by doing sports\"\n  raw_title: \"eurucamp 2014 - How I tried to self medicate my depression by doing sports by Andre Cedik\"\n  speakers:\n    - André Cedik\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_andre-cedik_how-i-tried-to-self-medicate-my-depression.webm\"\n  id: \"andre-cedik-how-i-tried-to-self-medicate-my-depression-by-doing-sports-eurucamp-2014\"\n  description: \"\"\n\n- title: \"Far-East Ruby\"\n  raw_title: \"eurucamp 2014 - Far-East Ruby by Sebastian Korfmann\"\n  speakers:\n    - Sebastian Korfmann\n  date: \"2014-08-01\"\n  event_name: \"Eurucamp 2014\"\n  published_at: \"2015-05-28\"\n  video_provider: \"mp4\"\n  video_id: \"https://s3.eu-central-1.amazonaws.com/eurucamp-2014-encoded/eurucamp_2014_sebastian_korfmann_-_far-east_ruby.webm\"\n  id: \"sebastian-korfmann-far-east-ruby-eurucamp-2014\"\n  description: \"\"\n"
  },
  {
    "path": "data/eurucamp/eurucamp-2015/event.yml",
    "content": "---\nid: \"eurucamp-2015\"\ntitle: \"eurucamp 2015\"\ndescription: |-\n  where Ruby conference meets camp\nlocation: \"Potsdam, Germany\"\nkind: \"conference\"\nstart_date: \"2015-07-31\"\nend_date: \"2015-08-02\"\nwebsite: \"http://2015.eurucamp.org\"\ntwitter: \"eurucamp\"\nplaylist: \"http://media.eurucamp.org/\"\ncoordinates:\n  latitude: 52.3905689\n  longitude: 13.0644729\n"
  },
  {
    "path": "data/eurucamp/eurucamp-2015/videos.yml",
    "content": "---\n- id: \"joanne-cheng-eurucamp-2015\"\n  title: \"Keynote: Awe\"\n  raw_title: \"eurucamp 2015 - Keynote by Joanne Cheng\"\n  speakers:\n    - Joanne Cheng\n  date: \"2015-07-31\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"RfF6wFK_eFY\"\n\n- id: \"ivan-zarea-eurucamp-2015\"\n  title: \"Passing Down the Pain: Difficulties in Teaching Software Development\"\n  raw_title: \"eurucamp 2015 - Passing Down the Pain: Difficulties in Teaching Software Development by Ivan Zarea\"\n  speakers:\n    - Ivan Zarea\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    How do you teach proper software engineering? How do you design a teaching program that highlights the pain of maintaining software to students who have never actually had to maintain software? And, while doing that, how do you keep your students engaged?\n\n    Teaching at an experimental group at the Technical University of Moldova, I’m able to employ new techniques including testing, live coding and software maintenance into a regular university curriculum.\n\n    Some of the techniques work well to convey the difficulties of writing software, others were failed experiments involving chinchillas and drug dealers. It’s a different age for teaching. The students have already had experience with hackathons, code camps, fancy javascript frameworks and it’s our mission as educators to stay relevant and provide engaging material. I believe that we can leverage the new tools and drastically improve the way we teach software development.\n  video_provider: \"youtube\"\n  video_id: \"KhTvqCqln5M\"\n\n- id: \"luis-ferreira-eurucamp-2015\"\n  title: \"Crystal: The Programming Language\"\n  raw_title: \"eurucamp 2015 - Crystal: The Programming Language by Luis Ferreira\"\n  speakers:\n    - Luis Ferreira\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Crystal is a typed, LLVM compiled language that reads (mostly) as Ruby.\n\n    If you’ve ever faced a problem in which you would like to use Ruby (because it is awesome), but it is just not performant enough, maybe Crystal is the solution you’ve been looking for.\n\n    Crystal’s standard lib comes bundled with support for WebSockets, OAuth, MySQL, and other nice utilities. It has a very simple testing framework, dependency management system, and even the beginnings of a web framework.\n\n    This is a very exciting time to come aboard the Crystal train, especially coming from a Ruby background.\n  video_provider: \"youtube\"\n  video_id: \"aEDnRjor21Y\"\n\n- id: \"christophe-philemotte-eurucamp-2015\"\n  title: \"Deep Diving: How to Explore a New Code Base\"\n  raw_title: \"eurucamp 2015 - Deep Diving: How to Explore a New Code Base by Christophe Philemotte\"\n  speakers:\n    - Christophe Philemotte\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    As a developer, diving in a new code base is not uncommon: you’ve just been hired, you change of project, you want to help an open source project, the open source library your project depends on is buggy, etc. It’s like entering in a underwater cave, you don’t know the treasures or the monsters you’ll find there, neither if the path is treacherous or if it’s a true labyrinth where you’ll get lost. You can prepare yourself, you can plan your visit, you can equip yourself, you can survive and find the gem you’re looking for…\n  video_provider: \"youtube\"\n  video_id: \"s47uru_-inc\"\n\n- id: \"davy-stevenson-eurucamp-2015\"\n  title: \"Orders of Magnitude\"\n  raw_title: \"eurucamp 2015 - Orders of Magnitude by Davy Stevenson\"\n  speakers:\n    - Davy Stevenson\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Up until the 17th century, the world was mostly limited to what we could see with the naked eye. Our understanding of things much smaller and much larger than us was limited. In the past 400 years our worldview has increased enormously, which has led to the advent of technology, space exploration, computers and the internet. However, our brains are ill equipped to handle dealing with numbers at these scales, and attempt to trick us at every turn. Software engineers deal with computers every day, and thus we are subject to both incredibly tiny and massively large numbers all the time. Learn about how your brain is fooling you when you are dealing with issues of latency, scalability, and algorithm optimization, so that you can become a better programmer.\n  video_provider: \"youtube\"\n  video_id: \"iWwvcwlS3KI\"\n\n- id: \"marta-paciorkowska-eurucamp-2015\"\n  title: \"A Case Against Showmanship\"\n  raw_title: \"eurucamp 2015 - A Case Against Showmanship by Marta Paciorkowska\"\n  speakers:\n    - Marta Paciorkowska\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Every other company is looking for ninjas, cowboys or superheroes. Every other conference talk is full of jokes, puns, comedy skits and personality. Nowadays, conferences breathe showmanship, but in our need to be the best of the best, the funniest of the funniest, we are excluding others. When less than exceptional becomes not good enough, the barrier of entry goes up and it is the underrepresented groups that suffer. When did we start mistaking programming conferences for stand up comedy shows? Our drive to be edgy, exceptional, memorable or controversial too often ends up with distressed audiences and badly handled PR scandals. This talk’s aim is to reflect on how this is a problem, how we’re all losing and how the cult of the stage hero needs to stop.\n  video_provider: \"youtube\"\n  video_id: \"oAkmQWpGZwY\"\n\n- id: \"terence-lee-eurucamp-2015\"\n  title: \"mruby: a Packaging Story Filled with Freedom\"\n  raw_title: \"eurucamp 2015 - mruby: a Packaging Story Filled with Freedom by Terence Lee\"\n  speakers:\n    - Terence Lee\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Ruby is a great language for building CLIs. There’s an amazing selection of existing libraries like Thor, GLI, or even OptionParser. You probably use a number of Ruby tools everyday like chef, the heroku toolbelt, , and of course the rails command line tool.\n    Though it’s easy to build a Ruby CLI, distributing it to end users is much more complicated because it requires a Ruby runtime. One option is to rely on Ruby being already installed on the end user’s computer. The other is to bundle ruby as part of the distribution package. Both of these are problematic so much that Vagrant, CloudFoundry and hub (Github command-line tool) have all switched over to Go.\n    But there’s still hope! In 2012, Matz started working on a lightweight embeddable ruby called mruby. Since mruby is designed for being embedded in other compiled languages, it also solves the distribution problem. In this talk we’ll look how we can write CLI tools using mruby to produce a self-contained binary that can be shipped to end users.\n  video_provider: \"youtube\"\n  video_id: \"OvuZ8R4Y9xA\"\n\n- id: \"rebecca-poulson-eurucamp-2015\"\n  title: \"The Junior Jump\"\n  raw_title: \"eurucamp 2015 - The Junior Jump by Rebecca Poulson\"\n  speakers:\n    - Rebecca Poulson\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    The Junior Jump deals with a topic that is increasingly important to the Ruby community--onboarding new engineers into their first jobs. We’ll discuss how the interview stage can be used to design a roadmap for a new engineer’s early days, how to select meaningful and appropriate projects and how to come up with a mentorship model that works given the resources at your organization. We will here anecdotes from junior developers from diverse backgrounds (bootcamp and university grads as well as self taught programmers) and more senior developers with experience onboarding new engineers.\n  video_provider: \"youtube\"\n  video_id: \"RK6l_l7TdB8\"\n\n- id: \"daniel-schweighfer-eurucamp-2015\"\n  title: \"Programming Parents\"\n  raw_title: \"eurucamp 2015 - Programming Parents by Daniel Schweighöfer\"\n  speakers:\n    - Daniel Schweighöfer\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Working as a developer while raising a child isn’t as difficult as you may think. A big share of adults are parents, and many can still become one some day. Becoming a parent changes a lot of things in your life. What it doesn’t change is your ability to work. It surely changes your priorities, and you don’t get much sleep during the first years, but this doesn’t have to prevent anybody from doing awesome work. If we have this in mind, it’s strange to observe what an exotic status parents and children have in our industry. The share of family-friendly employees and workspaces is tremendously low. Also, work organised in a way that doesn’t require everybody to work 40 hours a week is particularly rare, as my current difficulties finding a new job with less hours have shown. Parents in our industry have just become visible in recent years. Therefore, parents are often disregarded when a startup is founded. Creating a family-friendly workspace isn’t difficult, it’s just uncommon. This talk will introduce what it means to be a parent working as a developer and how work can be organised in a family-friendly way. It will show which benefits there are for everybody working in a family-friendly workspace, leaving you with a practical list of ideas how you could improve your work-live.\n  video_provider: \"youtube\"\n  video_id: \"mIaK98BZh_8\"\n\n- id: \"meike-wiemann-eurucamp-2015\"\n  title: \"Moving the Web into the Physical World with Beacons\"\n  raw_title: \"eurucamp 2015 - Moving the Web into the Physical World with Beacons by Meike Wiemann\"\n  speakers:\n    - Meike Wiemann\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Have you ever wondered what those beacons are? Beacons come in a lot of forms. I lately got my hands on some of the so-called physical web beacons. Physical web beacons are little devices that broadcast a URL via Bluetooth within a certain radius. You might wonder, so what? Well, the power of these beacons is that people, places and objects can become part of the Web and we can start designing for context-sensitive experiences. To give you an idea about the range of possibilities that become available I want to show some of my very simple prototypes that I built with Ruby, Rails and JavaScript. However, just being able to build cool stuff does not necessarily mean that it will be useful for someone. So, I evaluated how users experience this technology and I want to present the results to you as well.\n  video_provider: \"youtube\"\n  video_id: \"WZJBSmFZ-LY\"\n\n- id: \"leslie-hawthorn-eurucamp-2015\"\n  title: \"Will the Real Technical People Please Stand Up?\"\n  raw_title: \"eurucamp 2015 - Will the Real Technical People Please Stand Up? by Leslie Hawthorn\"\n  speakers:\n    - Leslie Hawthorn\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-13\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    How often have you heard – or said – the phrase “$PERSON just isn’t technical”?\n    If you’re our speaker, you’ve heard it plenty of times over the past 15 years, and frequently applied to yourself and other colleagues who didn’t quite fit into well understood “technologist” categories.\n    But what does technical actually mean? What makes someone technical? What makes them not technical?\n    In this talk, the speaker will explore how “not technical” is dangerous phrase we use to ensure that we need never question our hidden biases about others and their aptitudes. She will demonstrate how this phrase not only encourages a lack of collaboration, but leads to stagnation in the growth of your orgnization by actively discouraging your peers from learning new skills.\n    She will conclude with concrete steps attendees can take to better understand the capabilities of everyone on their team – coders or not – so their projects, company or teams can be most successful.\n  video_provider: \"youtube\"\n  video_id: \"QZxcg1NiN2A\"\n\n- id: \"joseph-wilk-eurucamp-2015\"\n  title: \"Programming as a Performance\"\n  raw_title: \"eurucamp 2015 - Programming as a Performance by Joseph Wilk\"\n  speakers:\n    - Joseph Wilk\n  date: \"2015-08-01\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Since the inception of the programmable computer we have grappled with the challenge of validating the outcome of a conversation in code between a human and a machine. Programming as a performance embraces this challenge, putting it at the centre of a performance. Focusing on the liveliness and complexity of dancing with a machine in realtime. In a performance a human edits and writes algorithms, expressing their thoughts and composition in front of an audience. Binding to their fingertips control of light, sound and poetry. Sharing their screens and code and its effects on the world.\n    This talk will dive into the world of the live programmer and how you can turn your Ruby coding skills into a live performance. Discover what performance and expression has to teach us about programming.\n  video_provider: \"youtube\"\n  video_id: \"pJ5oVqZ9BgY\"\n\n- id: \"bozhidar-batsov-eurucamp-2015\"\n  title: \"Opal: The Journey From JavaScript to Ruby\"\n  raw_title: \"eurucamp 2015 - Opal: The Journey From JavaScript to Ruby by Bozhidar Batsov\"\n  speakers:\n    - Bozhidar Batsov\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Don't like JavaScript? Don't like CoffeeScript? Want to use Ruby on the backend and on front-end? Then this talk is for you!\n\n    Opal is a Ruby to JavaScript source-to-source compiler, which also has an implementation of the Ruby corelib. In this talk we'll examine how Opal works, where it delivers and where it falls short. And above all - we'll have fun!\n  video_provider: \"youtube\"\n  video_id: \"6Co0qmCvgq0\"\n\n- id: \"katherine-wu-eurucamp-2015\"\n  title: \"Ask vs. Guess Culture Communication\"\n  raw_title: \"eurucamp 2015 - Ask vs. Guess Culture Communication by Katherine Wu\"\n  speakers:\n    - Katherine Wu\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Have you ever been told you’re “too direct,” or feel like you don’t understand what others want? Or on the other side, do you think others are often too confrontational? These are Ask vs Guess Culture differences. Ask folks believe it’s ok to ask anything, because it’s ok to say no, while Guess folks prioritize not imposing on others. It’s a culture clash that isn’t often recognized, yet causes quite a bit of tension and frustration. This talk will cover the nuances of these different communication styles, as well as strategies for bridging the gap. Gaining an understanding of these differences and learning specific tactics for a professional context will make you a drastically more effective communicator.\n  video_provider: \"youtube\"\n  video_id: \"fp4ZD3GkAx8\"\n\n- id: \"kinsey-ann-durham-eurucamp-2015\"\n  title: \"The Struggle to Stay Technical\"\n  raw_title: \"eurucamp 2015 - The Struggle to Stay Technical by Kinsey Ann Durham\"\n  speakers:\n    - Kinsey Ann Durham\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Life is good. More and more people who never thought they could code, people of diverse backgrounds are learning to write Ruby and become full time developers. Outreach programs are doing an amazing job of getting these people into the community, but now we are facing an even bigger problem. Getting them to stay there. 57% of women alone leave the tech industry once they are there. At every turn, we are told we can’t do it, offered different untechnical positions, or bullied out by toxic cultures. This talk will explore the barriers people of different backgrounds face to stay in technical positions, even once they have overcome the barriers to get there. It will present different perspectives and bring light to things we can do as an individual, an employer, a co-worker and as a community to solve this large problem that we face.\n  video_provider: \"youtube\"\n  video_id: \"D5svAP1aPCk\"\n\n- id: \"josep-m-tsux-bach-eurucamp-2015\"\n  title: \"The Power Of Small Abstractions\"\n  raw_title: 'eurucamp 2015 - The Power Of Small Abstractions by Josep M. \"Tsux\" Bach'\n  speakers:\n    - Josep M. \"Tsux\" Bach\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Every time we solve an everyday programming problem we learn from its solution. When we come across a similar problem later on, we think “aha! I’ve seen this before! I know how to solve it!”. Many of us are also familiar with design patterns, which are abstractions that solve entire classes of problems. There also exists, however, a different kind of pattern. But, as opposed to help you structure a whole compiler or business application, these patterns love hiding in small things like methods or functions, or even binary operations. They whisper to you when you concatenate two strings. They leave a trail of breadcrumbs every time you map over a list. These abstractions have superpowers, too. They can separate the what from the when, or even from the how. They can add together things other than numbers. They can control time, or take over the control flow of your program entirely. In this talk you will discover the amazing power of small abstractions. After that you’ll start hearing their whispers and seeing their breadcrumb trails. And only then you will be ready to let them unfold their full potential in your programs.\n  video_provider: \"youtube\"\n  video_id: \"U_yIxD_U-IY\"\n\n- id: \"lightning-talks-eurucamp-2015\"\n  title: \"Lightning Talks\"\n  raw_title: \"eurucamp 2015 - Lightning Talks\"\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"mJcxAY172y8\"\n  talks:\n    - title: \"Lightning Talk: Protocol buffer on JRuby\"\n      date: \"2015-08-02\"\n      start_cue: \"00:06:52\"\n      end_cue: \"00:11:00\"\n      video_provider: \"parent\"\n      id: \"isaiah-peng-lightning-talk-polar-buffers-eurucamp-2015\"\n      video_id: \"isaiah-peng-lightning-talk-polar-buffers-eurucamp-2015\"\n      speakers:\n        - Isaiah Peng\n\n    - title: \"Lightning Talk: Study Groups\"\n      date: \"2015-08-02\"\n      start_cue: \"00:11:10\"\n      end_cue: \"00:15:34\"\n      video_provider: \"parent\"\n      id: \"ruby-corns-study-group-lightning-talk-study-groups-eurucamp-2015\"\n      video_id: \"ruby-corns-study-group-lightning-talk-study-groups-eurucamp-2015\"\n      speakers:\n        - the rubycorns\n\n    - title: \"Lightning Talk: Ruby\"\n      date: \"2015-08-02\"\n      start_cue: \"00:15:34\"\n      end_cue: \"00:21:56\"\n      video_provider: \"parent\"\n      id: \"piotr-szotkowski-lightning-talk-ruby-eurucamp-2015\"\n      video_id: \"piotr-szotkowski-lightning-talk-ruby-eurucamp-2015\"\n      speakers:\n        - Piotr Szotkowski\n\n    - title: \"Lightning Talk: Ruby Issues\"\n      date: \"2015-08-02\"\n      start_cue: \"00:21:56\"\n      end_cue: \"00:25:18\"\n      video_provider: \"parent\"\n      id: \"robin-boening-lightning-talk-ruby-issues-eurucamp-2015\"\n      video_id: \"robin-boening-lightning-talk-ruby-issues-eurucamp-2015\"\n      speakers:\n        - Robin Boening\n\n    - title: \"Lightning Talk: Make Games!\"\n      date: \"2015-08-02\"\n      start_cue: \"00:25:35\"\n      end_cue: \"00:30:04\"\n      video_provider: \"parent\"\n      id: \"jan-krutisch-lightning-talk-ruby-issues-eurucamp-2015\"\n      video_id: \"jan-krutisch-lightning-talk-ruby-issues-eurucamp-2015\"\n      speakers:\n        - Jan Krutisch\n\n    - title: \"Lightning Talk: Get Your Shoes (Back) On\"\n      date: \"2015-08-02\"\n      start_cue: \"00:30:04\"\n      end_cue: \"00:47:02\"\n      video_provider: \"parent\"\n      id: \"jason-r-clark-lightning-talk-shoes-eurucamp-2015\"\n      video_id: \"jason-r-clark-lightning-talk-shoes-eurucamp-2015\"\n      speakers:\n        - Jason R. Clark\n\n- id: \"kylie-stradley-eurucamp-2015\"\n  title: \"Amelia Bedelia Learns to Code\"\n  raw_title: \"eurucamp 2015 - Amelia Bedelia Learns to Code by Kylie Stradley\"\n  speakers:\n    - Kylie Stradley\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    \"Did you really think you could make changes to the database by editing the schema file? Who are you, Amelia Bedelia?\"\n\n    The silly mistakes we all made when first learning Rails may be funny to us now, but we should remember how we felt at the time. New developers don't always realize senior developers were once beginners too and may assume they are the first and last developer to mix up when to use the rails and rake commands.\n\n    This talk, presented in a storybook style, will be a lighthearted examination of some of the common mistakes (and causes of those mistakes) made by beginner Rails developers.\n  video_provider: \"youtube\"\n  video_id: \"83bpBy7Gesw\"\n\n- id: \"elise-huard-eurucamp-2015\"\n  title: \"Game Programming in Haskell\"\n  raw_title: \"eurucamp 2015 - Game Programming in Haskell by Elise Huard\"\n  speakers:\n    - Elise Huard\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Game programming in Haskell: it is possible. I'll talk about the pros and cons of using Haskell for a game, and how to build a game from scratch.\n\n    The talk will cover the basics of functional reactive programming, a technique to handle reacting to user inputs in a UI. I'll also touch on Game design, which is actually the hard part.\n  video_provider: \"youtube\"\n  video_id: \"bHPze9H-Ces\"\n  additional_resources:\n    - name: \"Ebook\"\n      title: \"Game Programming in Haskell\"\n      type: \"book\"\n      url: \"https://leanpub.com/gameinhaskell\"\n\n    - name: \"Code\"\n      title: \"elisehuard/game-in-haskell\"\n      type: \"repo\"\n      url: \"https://github.com/elisehuard/game-in-haskell\"\n\n- id: \"ramn-huidobro-eurucamp-2015\"\n  title: \"How Teaching Kids to Code Made Me a Better Developer\"\n  raw_title: \"eurucamp 2015 - How Teaching Kids to Code Made Me a Better Developer by Ramón Huidobro\"\n  speakers:\n    - \"Ramón Huidobro\"\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Kids have this magical ability to take something you think you understand well and turn it upside down within an instant. They challenge norms and ask questions that you never thought existed or could be asked.\n\n    In this talk, I’ll go over some of the challenges I faced introducing kids to the world of programming, and how their inquisitiveness changed the way I look at software development, how I learn to get better at it and finally, how it boosted my confidence in my code. Teaching anyone is a rewarding, learning experience, and it motivated me to become active in the community.\n  video_provider: \"youtube\"\n  video_id: \"yQye2BCPHpw\"\n\n- id: \"hanneli-tavante-eurucamp-2015\"\n  title: \"Humanising Math and Physics on Computer Science\"\n  raw_title: \"eurucamp 2015 - Humanising Math and Physics on Computer Science by Hanneli Tavante\"\n  speakers:\n    - Hanneli Tavante\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    There are some myths around Science – it’s boring, useless, difficult. Many of them are heard while we are young, and many people tend to take then for the entire life. Science is very important, specially on Computer Science and Engineering, for building the basis of our logical thinking.\n  video_provider: \"youtube\"\n  video_id: \"qMfAZpmWux4\"\n\n- id: \"boris-bgling-eurucamp-2015\"\n  title: \"Calling Native Code From Ruby\"\n  raw_title: \"eurucamp 2015 - Calling Native Code From Ruby by Boris Bügling\"\n  speakers:\n    - Boris Bügling\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    This talk gives a quick introduction into the not so well known Fiddle, which is a part of MRI since 1.9. It allows directly interacting with C code via a Foreign Function Interface, which allows wrapping native code without compiling C extensions, making the live of users of your projects much easier.\n  video_provider: \"youtube\"\n  video_id: \"7Kplh69juPA\"\n\n- id: \"dajana-eurucamp-2015\"\n  title: \"Cultivating Empathy\"\n  raw_title: \"eurucamp 2015 - Cultivating Empathy by Dajana and Leslie Hawthorn\"\n  speakers:\n    - Dajana Günther\n    - Leslie Hawthorn\n  date: \"2015-08-02\"\n  event_name: \"eurucamp 2015\"\n  published_at: \"2015-08-14\"\n  announced_at: \"2014-11-17\"\n  description: |-\n    Cultivating Empathy by Dajana and Leslie Hawthorn. Dajana will be joined by Leslie Hawthorn to give this talk! When considering how to design products, teams or even common every day household objects, empathy doesn't end up on the required features list. Yet, without empathy, teams with enormous technical skills can fail in their quest to deliver quality products to their users. Incredible projects fail to create communities because they don't exercise it. Fail at empathy and your chances of failing at everything skyrocket.Contrary to what you may have heard, empathy is not something you're innately born with - it's a skill that can be learned, cultivated, refined and taught to others. In this presentation, your lovely co-speakers will discuss the value of empathy, how you can cultivate in yourself and your organizational culture, and conclude with concrete steps for leveling up in your interactions with your fellow human beings.\n  video_provider: \"youtube\"\n  video_id: \"q17GKDnSAec\"\n"
  },
  {
    "path": "data/eurucamp/series.yml",
    "content": "---\nname: \"eurucamp\"\nwebsite: \"http://2014.eurucamp.org\"\ntwitter: \"eurucamp\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/euruko/euruko-2003/event.yml",
    "content": "---\nid: \"euruko-2003\"\ntitle: \"EuRuKo 2003\"\nkind: \"conference\"\nlocation: \"Karlsruhe, Germany\"\ndescription: \"\"\nstart_date: \"2003-06-21\"\nend_date: \"2003-06-22\"\nyear: 2003\nwebsite: \"https://web.archive.org/web/20030401130152/http://www.approximity.com/cgi-bin/europeRuby/tiki.cgi?c=v&p=EuropeanRubyConference\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 49.0068901\n  longitude: 8.4036527\n"
  },
  {
    "path": "data/euruko/euruko-2003/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2004/event.yml",
    "content": "---\nid: \"euruko-2004\"\ntitle: \"EuRuKo 2004\"\nkind: \"conference\"\nlocation: \"Munich, Germany\"\ndescription: \"\"\nstart_date: \"2004-10-09\"\nend_date: \"2004-10-10\"\nyear: 2004\nwebsite: \"https://web.archive.org/web/20041010230509/http://www.ntecs.de/wiki/euruko2004/show/HomePage\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 48.1351253\n  longitude: 11.5819806\n"
  },
  {
    "path": "data/euruko/euruko-2004/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2005/event.yml",
    "content": "---\nid: \"euruko-2005\"\ntitle: \"EuRuKo 2005\"\nkind: \"conference\"\nlocation: \"Berlin, Germany\"\ndescription: \"\"\nstart_date: \"2005-10-15\"\nend_date: \"2005-10-16\"\nyear: 2005\nwebsite: \"https://web.archive.org/web/20051122173527/http://www.approximity.com/cgi-bin/europeRuby/tiki.cgi?c=v&p=Euruko05\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/euruko/euruko-2005/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2006/event.yml",
    "content": "---\nid: \"euruko-2006\"\ntitle: \"EuRuKo 2006\"\nkind: \"conference\"\nlocation: \"Munich, Germany\"\ndescription: \"\"\nstart_date: \"2006-11-04\"\nend_date: \"2006-11-05\"\nyear: 2006\nwebsite: \"https://web.archive.org/web/20070220004959/http://www.approximity.com/cgi-bin/europeRuby/tiki.cgi?c=v&p=Euruko06\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 48.1351253\n  longitude: 11.5819806\n"
  },
  {
    "path": "data/euruko/euruko-2006/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2007/event.yml",
    "content": "---\nid: \"euruko-2007\"\ntitle: \"EuRuKo 2007\"\nkind: \"conference\"\nlocation: \"Vienna, Austria\"\ndescription: \"\"\nstart_date: \"2007-11-10\"\nend_date: \"2007-11-11\"\nyear: 2007\nwebsite: \"https://web.archive.org/web/20080125150440/http://www.approximity.com/cgi-bin/europeRuby/tiki.cgi?c=v&p=Euruko07\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 48.20806959999999\n  longitude: 16.3713095\n"
  },
  {
    "path": "data/euruko/euruko-2007/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2008/event.yml",
    "content": "---\nid: \"euruko-2008\"\ntitle: \"EuRuKo 2008\"\nkind: \"conference\"\nlocation: \"Prague, Czech Republic\"\ndescription: \"\"\nstart_date: \"2008-03-29\"\nend_date: \"2008-03-30\"\nyear: 2008\nwebsite: \"https://2008.euruko.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 50.0755381\n  longitude: 14.4378005\n"
  },
  {
    "path": "data/euruko/euruko-2008/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2009/event.yml",
    "content": "---\nid: \"euruko-2009\"\ntitle: \"EuRuKo 2009\"\nkind: \"conference\"\nlocation: \"Barcelona, Spain\"\ndescription: \"\"\nstart_date: \"2009-05-09\"\nend_date: \"2009-05-10\"\nyear: 2009\nwebsite: \"https://2009.euruko.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 41.3874374\n  longitude: 2.1686496\n"
  },
  {
    "path": "data/euruko/euruko-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2010/event.yml",
    "content": "---\nid: \"euruko-2010\"\ntitle: \"EuRuKo 2010\"\nkind: \"conference\"\nlocation: \"Kraków, Poland\"\ndescription: \"\"\nstart_date: \"2010-05-29\"\nend_date: \"2010-05-30\"\nyear: 2010\nwebsite: \"https://2010.euruko.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 50.06465009999999\n  longitude: 19.9449799\n"
  },
  {
    "path": "data/euruko/euruko-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2011/event.yml",
    "content": "---\nid: \"euruko-2011\"\ntitle: \"EuRuKo 2011\"\nkind: \"conference\"\nlocation: \"Berlin, Germany\"\ndescription: \"\"\nstart_date: \"2011-05-28\"\nend_date: \"2011-05-29\"\nyear: 2011\nwebsite: \"https://2011.euruko.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/euruko/euruko-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2012/event.yml",
    "content": "---\nid: \"euruko-2012\"\ntitle: \"EuRuKo 2012\"\nkind: \"conference\"\nlocation: \"Amsterdam, Netherlands\"\ndescription: \"\"\nstart_date: \"2012-06-01\"\nend_date: \"2012-06-02\"\nyear: 2012\nwebsite: \"https://2012.euruko.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 52.3675734\n  longitude: 4.9041389\n"
  },
  {
    "path": "data/euruko/euruko-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2013/event.yml",
    "content": "---\nid: \"euruko-2013\"\ntitle: \"EuRuKo 2013\"\nkind: \"conference\"\nlocation: \"Athens, Greece\"\ndescription: \"\"\nstart_date: \"2013-06-28\"\nend_date: \"2013-06-29\"\nyear: 2013\nwebsite: \"https://2013.euruko.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 37.9838096\n  longitude: 23.7275388\n"
  },
  {
    "path": "data/euruko/euruko-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2014/event.yml",
    "content": "---\nid: \"euruko-2014\"\ntitle: \"EuRuKo 2014 (Cancelled)\"\nkind: \"conference\"\nstatus: \"cancelled\"\nlocation: \"Kyiv, Ukraine\"\ndescription: \"\"\nstart_date: \"2014-06-20\"\nend_date: \"2014-06-21\"\nyear: 2014\nwebsite: \"https://2014.euruko.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 50.4503596\n  longitude: 30.5245025\n"
  },
  {
    "path": "data/euruko/euruko-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2015/event.yml",
    "content": "---\nid: \"euruko-2015\"\ntitle: \"EuRuKo 2015\"\nkind: \"conference\"\nlocation: \"Salzburg, Austria\"\ndescription: \"\"\nstart_date: \"2015-10-17\"\nend_date: \"2015-10-18\"\nyear: 2015\nwebsite: \"https://2015.euruko.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D55751\"\ncoordinates:\n  latitude: 47.8014154\n  longitude: 13.0448441\n"
  },
  {
    "path": "data/euruko/euruko-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/euruko/euruko-2016/event.yml",
    "content": "---\nid: \"PLiiwaDvnsMkHvqFifIqcQWFfHNdp9gaKs\"\ntitle: \"EuRuKo 2016\"\nkind: \"conference\"\nlocation: \"Sofia, Bulgaria\"\ndescription: \"\"\npublished_at: \"2016-09-23\"\nstart_date: \"2016-09-23\"\nend_date: \"2016-09-24\"\nchannel_id: \"UChGs1td4ViQFqT0jlvkyUJg\"\nyear: 2016\nbanner_background: \"#2B343E\"\nfeatured_background: \"#2B343E\"\nfeatured_color: \"#C15A5B\"\nwebsite: \"https://2016.euruko.org\"\ncoordinates:\n  latitude: 42.6977082\n  longitude: 23.3218675\n"
  },
  {
    "path": "data/euruko/euruko-2016/videos.yml",
    "content": "---\n# https://2016.euruko.org/schedule\n\n## Day 1\n\n- id: \"yukihiro-matz-matsumoto-euruko-2016\"\n  title: \"Opening Keynote: Ruby 3 Today\"\n  raw_title: 'EuRuKo 2016 - Day 1 Keynote by Yukihiro \"Matz\" Matsumoto'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8aHmArEq4y0\"\n  published_at: \"2016-10-19\"\n\n- id: \"xavier-noria-euruko-2016\"\n  title: \"Little Snippets\"\n  raw_title: \"EuRuKo 2016 - Little Snippets by Xavier Noria\"\n  speakers:\n    - Xavier Noria\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"mC9TyVeER_8\"\n  published_at: \"2016-10-19\"\n\n- id: \"andrew-radev-euruko-2016\"\n  title: \"Rules, Laws, and Gentle Guidelines\"\n  raw_title: \"EuRuKo 2016 - Rules, Laws, and Gentle Guidelines by Andrew Radev\"\n  speakers:\n    - Andrew Radev\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"BDXQ4pcbEBA\"\n  published_at: \"2016-10-19\"\n\n# Lunch\n\n- id: \"terence-lee-euruko-2016\"\n  title: \"Simplifying Logs, Events and Streams: Kafka + Rails\"\n  raw_title: \"EuRuKo 2016 - Simplifying Logs, Events and Streams: Kafka + Rails by Terence Lee\"\n  speakers:\n    - Terence Lee\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"yl3JmF3n2bQ\"\n  published_at: \"2016-10-11\"\n\n- id: \"marc-andr-giroux-euruko-2016\"\n  title: \"GraphQL on Rails\"\n  raw_title: \"EuRuKo 2016 - GraphQL on Rails by Marc-André Giroux\"\n  speakers:\n    - Marc-André Giroux\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"_V96jduEvjY\"\n  published_at: \"2016-10-19\"\n\n- id: \"grace-chang-euruko-2016\"\n  title: \"Herding Cats to a Firefight\"\n  raw_title: \"EuRuKo 2016 - Herding Cats to a Firefight by Grace Chang\"\n  speakers:\n    - Grace Chang\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"u_7wrPXaSto\"\n  published_at: \"2016-10-19\"\n\n# Coffee Break\n\n- id: \"rafael-mendona-frana-euruko-2016\"\n  title: \"How Sprockets Works\"\n  raw_title: \"EuRuKo 2016 - How Sprockets Works by Rafael França\"\n  speakers:\n    - Rafael Mendonça França\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"rbM_1wRVfeI\"\n  published_at: \"2016-10-19\"\n\n- id: \"lightning-talks-day-1-euruko-2016\"\n  title: \"Lightning Talks: Day 1\"\n  raw_title: \"EuRuKo 2016 - Day 1 Lightning Talks\"\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-23\"\n  description: |-\n    Lightning talks from Day 1 of EuRuKo\n\n    * \"Making a Multiplayer Memory Game with Elixir and Elm\" by Max Gorin (0:29)\n    * \"Team Joda 2016 (Rails Girls Summer of Code 2016)\" by Johanna Lang & Dayana Mick (6:20)\n    * \"We Are Rubycats! (Rails Girls Summer of Code 2016)\" by Kinga Kalinowska & Izabela Komorek (12:11)\n    * \"Magic Solution to the Tech Gender Gap\" by Melanie Keatley & Stephanie Nemeth (18:22)\n    * \"Validations\" by Krzysztof (Christopher) Wawer (23:39)\n    * \"The Importance of Teaching and Metoring\" by Demir Zekić (28:53)\n    * \"Whirly - The Friendly Terminal Spinner\" by Jan Lelis (35:25)\n\n  video_provider: \"youtube\"\n  video_id: \"UehkClMTJDw\"\n  published_at: \"2016-10-20\"\n  talks:\n    - title: \"Making a Multiplayer Memory Game with Elixir and Elm\"\n      start_cue: \"0:29\"\n      end_cue: \"6:20\"\n      video_provider: \"parent\"\n      id: \"max-gorin-lighting-talk-euruko-2016\"\n      video_id: \"max-gorin-lighting-talk-euruko-2016\"\n      speakers:\n        - Max Gorin\n\n    - title: \"Team Joda 2016 (Rails Girls Summer of Code 2016)\"\n      start_cue: \"6:20\"\n      end_cue: \"12:11\"\n      video_provider: \"parent\"\n      id: \"johanna-lang-lighting-talk-euruko-2016\"\n      video_id: \"johanna-lang-lighting-talk-euruko-2016\"\n      speakers:\n        - Johanna Lang\n        - Dayana Mick\n\n    - title: \"We Are Rubycats! (Rails Girls Summer of Code 2016)\"\n      start_cue: \"12:11\"\n      end_cue: \"18:22\"\n      video_provider: \"parent\"\n      id: \"kinga-kalinowska-lighting-talk-euruko-2016\"\n      video_id: \"kinga-kalinowska-lighting-talk-euruko-2016\"\n      speakers:\n        - Kinga Kalinowska\n        - Izabela Komorek\n\n    - title: \"Magic Solution to the Tech Gender Gap\"\n      start_cue: \"18:22\"\n      end_cue: \"23:39\"\n      video_provider: \"parent\"\n      id: \"melanie-keatley-lighting-talk-euruko-2016\"\n      video_id: \"melanie-keatley-lighting-talk-euruko-2016\"\n      speakers:\n        - Melanie Keatley\n        - Stephanie Nemeth\n\n    - title: \"Validations\"\n      start_cue: \"23:39\"\n      end_cue: \"28:53\"\n      video_provider: \"parent\"\n      id: \"krzysztof-wawer-lighting-talk-euruko-2016\"\n      video_id: \"krzysztof-wawer-lighting-talk-euruko-2016\"\n      speakers:\n        - Krzysztof (Christopher) Wawer\n\n    - title: \"The Importance of Teaching and Metoring\"\n      start_cue: \"28:53\"\n      end_cue: \"35:25\"\n      video_provider: \"parent\"\n      id: \"demir-zekic-lighting-talk-euruko-2016\"\n      video_id: \"demir-zekic-lighting-talk-euruko-2016\"\n      speakers:\n        - Demir Zekić\n\n    - title: \"Whirly - The Friendly Terminal Spinner\"\n      start_cue: \"35:25\"\n      video_provider: \"parent\"\n      id: \"jan-lelis-lighting-talk-euruko-2016\"\n      video_id: \"jan-lelis-lighting-talk-euruko-2016\"\n      speakers:\n        - Jan Lelis\n\n## Day 2\n\n- id: \"jos-valim-euruko-2016\"\n  title: \"Idioms for Building Distributed Fault–Tolerant Applications with Elixir\"\n  raw_title: \"EuRuKo 2016 - Idioms for Building Distributed Fault–Tolerant Applications with Elixir by José Valim\"\n  speakers:\n    - José Valim\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"xhwnHovnq_0\"\n  published_at: \"2016-10-19\"\n\n- id: \"hiroshi-shibata-euruko-2016\"\n  title: \"How to Begin to Develop Ruby Core\"\n  raw_title: \"EuRuKo 2016 - How to Begin to Develop Ruby Core by Hiroshi Shibata\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"IRfsakcZJKw\"\n  published_at: \"2016-10-19\"\n\n- id: \"carina-c-zona-euruko-2016\"\n  title: \"Consequences of an Insightful Algorithm\"\n  raw_title: \"EuRuKo 2016 - Consequences of an Insightful Algorithm by Carina C. Zona\"\n  speakers:\n    - Carina C. Zona\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"bp4yFKw_1QM\"\n  published_at: \"2016-10-19\"\n\n# Lunch\n\n- id: \"anton-davydov-euruko-2016\"\n  title: \"Viewing Ruby Blossom\"\n  raw_title: \"EuRuKo 2016 - Viewing Ruby Blossom by Anton Davydov\"\n  speakers:\n    - Anton Davydov\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3L6I4UoK8xM\"\n  published_at: \"2016-10-19\"\n\n- id: \"ivan-nemytchenko-euruko-2016\"\n  title: \"What I Have Learned From Organizing Remote Internship\"\n  raw_title: \"EuRuKo 2016 - What I Have Learned From Organizing Remote Internship by Ivan Nemytchenko\"\n  speakers:\n    - Ivan Nemytchenko\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"H-K0ZKOclBU\"\n  published_at: \"2016-10-19\"\n\n- id: \"andr-arko-euruko-2016\"\n  title: \"A Year of Ruby, Together\"\n  raw_title: \"EuRuKo 2016 - A Year of Ruby, Together by André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"SJddsEfvcW8\"\n  published_at: \"2016-10-19\"\n\n# Coffee Break\n\n- id: \"lightning-talks-day-2-euruko-2016\"\n  title: \"Lightning Talks: Day 2\"\n  raw_title: \"EuRuKo 2016 - Day 2 Lightning Talks\"\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-24\"\n  description: |-\n    Lightning talks from Day 2 of EuRuKo\n  video_provider: \"youtube\"\n  video_id: \"WnlgKWCt8wQ\"\n  published_at: \"2016-10-19\"\n  talks:\n    - title: \"The HTT(Pancake) Request - Keeping Your Clients Happy, Not Hangry\"\n      start_cue: \"00:57\"\n      end_cue: \"07:50\"\n      video_provider: \"parent\"\n      id: \"kriselda-rabino-lighting-talk-euruko-2016\"\n      video_id: \"kriselda-rabino-lighting-talk-euruko-2016\"\n      speakers:\n        - Kriselda Rabino\n\n    - title: \"How to decode ADSK data (Commodore 64 Edition)\"\n      start_cue: \"07:50\"\n      end_cue: \"13:47\"\n      video_provider: \"parent\"\n      id: \"stefan-daschek-lighting-talk-euruko-2016\"\n      video_id: \"stefan-daschek-lighting-talk-euruko-2016\"\n      speakers:\n        - Stefan Daschek\n\n    - title: \"Working with PDFs in Ruby\"\n      start_cue: \"13:47\"\n      end_cue: \"22:55\"\n      video_provider: \"parent\"\n      id: \"thomas-leitner-lighting-talk-euruko-2016\"\n      video_id: \"thomas-leitner-lighting-talk-euruko-2016\"\n      speakers:\n        - Thomas Leitner\n\n    - title: \"Ruby for Science and Open Data\"\n      start_cue: \"22:55\"\n      end_cue: \"29:37\"\n      video_provider: \"parent\"\n      id: \"victor-shepelev-lighting-talk-euruko-2016\"\n      video_id: \"victor-shepelev-lighting-talk-euruko-2016\"\n      speakers:\n        - Victor Shepelev\n\n    - title: \"CodeMarathon & HiredInTech - Using Rails to scale teaching CS online\"\n      start_cue: \"29:37\"\n      end_cue: \"34:16\"\n      video_provider: \"parent\"\n      id: \"anton-dimitrov-lighting-talk-euruko-2016\"\n      video_id: \"anton-dimitrov-lighting-talk-euruko-2016\"\n      speakers:\n        - Anton Dimitrov\n\n    - title: \"Opening a calculator with Rails\"\n      start_cue: \"34:16\"\n      end_cue: \"40:35\"\n      video_provider: \"parent\"\n      id: \"igor-omokov-lighting-talk-euruko-2016\"\n      video_id: \"igor-omokov-lighting-talk-euruko-2016\"\n      speakers:\n        - Igor Omokov\n\n    - title: \"Feel Worse, Do Better\"\n      start_cue: \"40:35\"\n      end_cue: \"48:09\"\n      video_provider: \"parent\"\n      id: \"alex-jahraus-lighting-talk-euruko-2016\"\n      video_id: \"alex-jahraus-lighting-talk-euruko-2016\"\n      speakers:\n        - Alex Jahraus\n\n- id: \"nick-sutterer-euruko-2016\"\n  title: \"The Illusion of Stable APIs\"\n  raw_title: \"EuRuKo 2016 - The Illusion of Stable APIs by Nick Sutterer\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"EuRuKo 2016\"\n  date: \"2016-09-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"mvHwTtsIH8g\"\n  published_at: \"2016-10-19\"\n"
  },
  {
    "path": "data/euruko/euruko-2017/event.yml",
    "content": "---\nid: \"PLZW-kXE0oRykQpf54Jhf1geLAeq5sM7Kt\"\ntitle: \"EuRuKo 2017\"\nkind: \"conference\"\nlocation: \"Budapest, Hungary\"\ndescription: \"\"\npublished_at: \"2021-06-01\"\nstart_date: \"2017-09-29\"\nend_date: \"2017-09-30\"\nchannel_id: \"UCgXsZr2e0AgUJMZm5t03WVw\"\nyear: 2017\nbanner_background: \"#FAFAFA\"\nfeatured_background: \"#FAFAFA\"\nfeatured_color: \"black\"\nwebsite: \"https://2017.euruko.org\"\ncoordinates:\n  latitude: 47.497912\n  longitude: 19.040235\n"
  },
  {
    "path": "data/euruko/euruko-2017/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n# Website: https://2017.euruko.org\n# Schedule: https://2017.euruko.org/schedule/\n\n## Day 1 - 9/29 FRIDAY\n\n- id: \"yukihiro-matz-matsumoto-euruko-2017\"\n  title: \"Keynote: MJIT, what, how and why\"\n  raw_title: \"Yukihiro Matsumoto Keynote @EuRuKo2017\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-29\"\n  published_at: \"2017-12-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"nlMsi8S3kZg\"\n\n- id: \"sasha-romijn-euruko-2017\"\n  title: \"Helping communities & products thrive\"\n  raw_title: \"Sasha Romijn- Helping communities & products thrive by fostering empathy @EuRuKo2017\"\n  speakers:\n    - Sasha Romijn\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-29\"\n  published_at: \"2017-12-20\"\n  slides_url: \"https://github.com/mxsasha/empathy-talk/blob/e181c1a273a22f01d9ff54cb278496d285ebfffd/deckset.pdf\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"biwApccM1Sg\"\n\n- id: \"sai-warang-euruko-2017\"\n  title: \"Data-driven production apps\"\n  raw_title: \"Sai Warang- Data-driven production apps @EuRuKo2017\"\n  speakers:\n    - Sai Warang\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-29\"\n  published_at: \"2017-12-20\"\n  slides_url: \"https://speakerdeck.com/cyprusad/euruko-2017-data-driven-production-apps\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"u4Z2M5HSGJs\"\n\n# Lunch\n\n- id: \"judit-rdg-andrsi-euruko-2017\"\n  title: \"The Real Black Friday aka How To Scale an Unscalable Service\"\n  raw_title: \"Judit Ördög-Andrási- The Real Black Friday aka How To Scale an Unscalable Service @EuRuKo2017\"\n  speakers:\n    - Judit Ördög-Andrási\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-29\"\n  published_at: \"2017-12-20\"\n  slides_url: \"https://euruko2017.org/downloads/slides/the_real_black_friday.pdf\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ZeGIw8jkRmA\"\n\n- id: \"arafat-khan-euruko-2017\"\n  title: \"Introducing Tensorflow Ruby API\"\n  raw_title: \"Arafat Khan- Introducing Tensorflow Ruby API @EuRuKo2017\"\n  speakers:\n    - Arafat Khan\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-29\"\n  published_at: \"2017-12-20\"\n  slides_url: \"https://docs.google.com/presentation/d/1FSfVfwFrWQ5AXgedVoqk_-50vT5q2vyQD0uA3_CewTU/edit?usp=sharing\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Bb8izrSSt3M\"\n\n- id: \"anthony-zacharakis-euruko-2017\"\n  title: \"Distributed Systems: Your Only Guarantee Is Inconsistency\"\n  raw_title: \"Anthony Zacharakis- Distributed Systems: Your Only Guarantee Is Inconsistency @EuRuKo2017\"\n  speakers:\n    - Anthony Zacharakis\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-29\"\n  published_at: \"2017-12-20\"\n  slides_url: \"https://speakerdeck.com/azach/distributed-systems-your-only-guarantee-is-inconsistency\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"JvBq27cbv_0\"\n\n- id: \"katarzyna-turbiasz-bugaa-euruko-2017\"\n  title: \"Things I Learned the Hard Way Building a Search Engine\"\n  raw_title: \"Katarzyna Turbiasz-Bugała- Things I Learned the Hard Way Building a Search Engine @EuRuKo2017\"\n  speakers:\n    - Katarzyna Turbiasz-Bugała\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-29\"\n  published_at: \"2017-12-20\"\n  slides_url: \"https://euruko2017.org/downloads/slides/search_engine.pdf\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"4zanERox264\"\n\n- id: \"lightning-talks-day-1-euruko-2017\"\n  title: \"Lightning Talks (Day 1)\"\n  raw_title: \"Lightning talks day1@EuRuKo2017\"\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-29\"\n  published_at: \"2018-01-05\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"NEnZViT581o\"\n  talks:\n    - title: \"Lightning Talk: Health Checks Are Great\"\n      start_cue: \"00:09\"\n      end_cue: \"05:17\"\n      thumbnail_cue: \"00:15\"\n      id: \"manuel-morales-lightning-talk-euruko-2017\"\n      video_id: \"manuel-morales-lightning-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Manuel Morales\n\n    - title: \"Lightning Talk: Warm Blanket - Good Crappy After-Boot Performance\"\n      start_cue: \"05:40\"\n      end_cue: \"08:40\"\n      thumbnail_cue: \"05:41\"\n      id: \"ivo-anjo-lightning-talk-euruko-2017\"\n      video_id: \"ivo-anjo-lightning-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Ivo Anjo\n\n    - title: \"Lightning Talk: Ruby Standard Gems\"\n      start_cue: \"08:55\"\n      end_cue: \"13:53\"\n      id: \"jan-lelis-lightning-talk-euruko-2017\"\n      video_id: \"jan-lelis-lightning-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jan Lelis\n\n    - title: \"Lightning Talk: Reality (now the right way)\"\n      start_cue: \"14:28\"\n      end_cue: \"17:36\"\n      id: \"victor-shepelev-lightning-talk-euruko-2017\"\n      video_id: \"victor-shepelev-lightning-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Victor Shepelev\n\n    - title: \"Lightning Talk: Good names are half the battle\"\n      start_cue: \"17:48\"\n      end_cue: \"22:44\"\n      id: \"good-names-are-half-the-battle-lightning-talk-euruko-2017\"\n      video_id: \"good-names-are-half-the-battle-lightning-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO\n\n    - title: \"Lightning Talk: TTY - Terminal Apps Toolkit\"\n      start_cue: \"23:37\"\n      end_cue: \"27:15\"\n      id: \"piotr-murach-lightning-talk-euruko-2017\"\n      video_id: \"piotr-murach-lightning-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Piotr Murach\n\n    - title: \"Lightning Talk: Gemfile's new clothes\"\n      start_cue: \"27:34\"\n      end_cue: \"33:13\"\n      thumbnail_cue: \"27:33\"\n      id: \"jan-krutisch-lightning-talk-euruko-2017\"\n      video_id: \"jan-krutisch-lightning-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jan Krutisch\n\n## Day 2 - 9/30 SATURDAY (UPDATED)\n\n- id: \"charles-nutter-euruko-2017\"\n  title: \"Keynote: The Story of JRuby\"\n  raw_title: \"Charles Nutter- Keynote @ EuRuKo2017\"\n  speakers:\n    - Charles Nutter\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-30\"\n  published_at: \"2017-12-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"sPS7F-ITqK4\"\n\n- id: \"katelyn-hertel-euruko-2017\"\n  title: \"How to Make It As A Junior Dev and Stay Sane\"\n  raw_title: \"Katelyn Hertel- How to Make It As A Junior Dev and Stay Sane @ EuRuKo2017\"\n  speakers:\n    - Katelyn Hertel\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-30\"\n  published_at: \"2017-12-22\"\n  description: \"\"\n  slides_url: \"https://www.slideshare.net/KatelynKatieHertel/how-to-make-it-as-a-junior-dev/1\"\n  video_provider: \"youtube\"\n  video_id: \"1Ai5GsL6tP4\"\n\n- id: \"anna-shcherbinina-euruko-2017\"\n  title: \"Issues with asynchronous interaction\"\n  raw_title: \"Anna Shcherbinina- Issues with asynchronous interaction @ EuRuKo2017\"\n  speakers:\n    - Anna Shcherbinina\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-30\"\n  published_at: \"2017-12-22\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/gaar4ica/issues-with-asynchronous-interaction\"\n  video_provider: \"youtube\"\n  video_id: \"m3QwxkfhhYg\"\n\n# Lunch\n\n- id: \"sebastian-sogamoso-euruko-2017\"\n  title: \"The overnight failure\"\n  raw_title: \"Sebastian Sogamoso- The overnight failure @ EuRuKo2017\"\n  speakers:\n    - Sebastian Sogamoso\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-30\"\n  published_at: \"2017-12-22\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/sebasoga/the-overnight-failure-2\"\n  video_provider: \"youtube\"\n  video_id: \"Q_rqdNVElSg\"\n\n- id: \"netto-farah-euruko-2017\"\n  title: \"Rescuing legacy codebases with GraphQL and Rails\"\n  raw_title: \"Netto Farah- Rescuing legacy codebases with GraphQL and Rails @ EuRuKo2017\"\n  speakers:\n    - Netto Farah\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-30\"\n  published_at: \"2017-12-22\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/nettofarah/rescuing-legacy-codebases-with-graphql-1\"\n  video_provider: \"youtube\"\n  video_id: \"Lk3Xx7k1aOk\"\n\n- id: \"todo-euruko-2017\"\n  title: \"City Pitches (Take EuRuKo Home pitches)\"\n  raw_title: \"Hosting City Pitches @EuRuKo2017\"\n  speakers:\n    - TODO\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-30\"\n  published_at: \"2017-12-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"-z9s743MUiw\"\n\n- id: \"wojtek-rzsa-euruko-2017\"\n  title: \"Predicting Performance Changes of Distributed Applications\"\n  raw_title: \"Wojtek Rząsa- Predicting Performance Changes of Distributed Applications @ EuRuKo2017\"\n  speakers:\n    - Wojtek Rząsa\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-30\"\n  published_at: \"2017-12-22\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/wrzasa/predicting-performance-changes-of-distributed-applications\"\n  video_provider: \"youtube\"\n  video_id: \"9yJcTsMFVjc\"\n\n# Coffee Break\n\n- id: \"lightning-talks-day-2-euruko-2017\"\n  title: \"Lightning Talks (Day 2)\"\n  raw_title: \"Lightning Talks Day2 @ EuRuKo2017\"\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-30\"\n  published_at: \"2017-12-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"0bDRKUqIu24\"\n  talks:\n    - title: \"Lightning Talk: Pilar Andrea Huidobro Peltier\"\n      event_name: \"EuRuKo 2017\"\n      date: \"2017-09-30\"\n      published_at: \"2017-12-22\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pilar-andrea-huidobro-peltier-lighting-talk-euruko-2017\"\n      video_id: \"pilar-andrea-huidobro-peltier-lighting-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Pilar Andrea Huidobro Peltier\n\n    - title: \"Lightning Talk: Jake\"\n      event_name: \"EuRuKo 2017\"\n      date: \"2017-09-30\"\n      published_at: \"2017-12-22\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jake-lighting-talk-euruko-2017\"\n      video_id: \"jake-lighting-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jake\n\n    - title: \"Lightning Talk: Quentin Godfroy\"\n      event_name: \"EuRuKo 2017\"\n      date: \"2017-09-30\"\n      published_at: \"2017-12-22\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"quentin-godfroy-lighting-talk-euruko-2017\"\n      video_id: \"quentin-godfroy-lighting-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Quentin Godfroy\n\n    - title: \"Lightning Talk: Mehdi Lahmam B.\"\n      event_name: \"EuRuKo 2017\"\n      date: \"2017-09-30\"\n      published_at: \"2017-12-22\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"mehdi-lahmam-b-lighting-talk-euruko-2017\"\n      video_id: \"mehdi-lahmam-b-lighting-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Mehdi Lahmam B.\n\n    - title: \"Lightning Talk: Ana María Martínez Gómez\"\n      event_name: \"EuRuKo 2017\"\n      date: \"2017-09-30\"\n      published_at: \"2017-12-22\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"ana-maria-martinez-gomez-lighting-talk-euruko-2017\"\n      video_id: \"ana-maria-martinez-gomez-lighting-talk-euruko-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Ana María Martínez Gómez\n\n- id: \"bozhidar-batsov-euruko-2017\"\n  title: \"Ruby 4.0: To Infinity and Beyond\"\n  raw_title: \"Bozhidar Batsov- Ruby 4.0: To Infinity and Beyond @ EuRuKo2017\"\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"EuRuKo 2017\"\n  date: \"2017-09-30\"\n  published_at: \"2017-12-22\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/bbatsov/ruby-4-to-infinity-and-beyond\"\n  video_provider: \"youtube\"\n  video_id: \"aFSuXUXRySc\"\n# Closing Ceremony\n"
  },
  {
    "path": "data/euruko/euruko-2018/event.yml",
    "content": "---\nid: \"PLZW-kXE0oRyn-mwcNhytWaCIAQJXJGMxo\"\ntitle: \"EuRuKo 2018\"\nkind: \"conference\"\nlocation: \"Vienna, Austria\"\ndescription: \"\"\npublished_at: \"2021-06-01\"\nstart_date: \"2018-08-24\"\nend_date: \"2018-08-25\"\nchannel_id: \"UCgXsZr2e0AgUJMZm5t03WVw\"\nyear: 2018\nbanner_background: \"linear-gradient(to top, #86E4FF, #FFFFFF)\"\nfeatured_background: \"linear-gradient(to top, #86E4FF, #FFFFFF)\"\nfeatured_color: \"#595959\"\nwebsite: \"https://2018.euruko.org\"\ncoordinates:\n  latitude: 48.20806959999999\n  longitude: 16.3713095\n"
  },
  {
    "path": "data/euruko/euruko-2018/videos.yml",
    "content": "---\n# Website: https://2018.euruko.org\n# Schedule: https://2018.euruko.org/schedule/\n\n## Day 0 - 2018-08-23\n\n# Pre-registration @ Vienna.rb\n\n## Day 1 - 2018-08-24\n\n# Registration\n\n- id: \"pilar-andrea-huidobro-peltier-euruko-2018\"\n  title: \"Introduction\"\n  raw_title: \"EuRuKo 2018 Introduction\"\n  speakers:\n    - Pilar Andrea Huidobro Peltier\n    - Carmen Huidobro\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"YhPP_Knq0qM\"\n  published_at: \"2018-08-24\"\n\n- id: \"yukihiro-matz-matsumoto-euruko-2018\"\n  title: \"Keynote: Ruby After 25 Years\"\n  raw_title: \"Yukihiro Matsumoto - Keynote\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"cs0s5lZAUwc\"\n  published_at: \"2018-08-24\"\n\n# Break\n\n- id: \"chris-salzberg-euruko-2018\"\n  title: \"Metaprogramming For Generalists\"\n  raw_title: \"Chris Salzberg - Metaprogramming for generalists\"\n  speakers:\n    - Chris Salzberg\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"1fIlcnrJHxs\"\n  published_at: \"2018-08-24\"\n\n- id: \"joannah-nanjekye-euruko-2018\"\n  title: \"Ruby in Containers\"\n  raw_title: \"Joannah Nanjekye - Ruby in containers\"\n  speakers:\n    - Joannah Nanjekye\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"qPNkOPvjecs\"\n  published_at: \"2018-08-24\"\n\n# Lunch\n\n- id: \"damir-zeki-euruko-2018\"\n  title: \"Tool Belt of a Seasoned Bug Hunter\"\n  raw_title: \"Damir Zekić - Tool belt of a seasoned bug hunter\"\n  speakers:\n    - Damir Zekić\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ObB0dzX_rBs\"\n  published_at: \"2018-08-24\"\n\n- id: \"igor-morozov-euruko-2018\"\n  title: \"Ducks and Monads: Wonders of Ruby Types\"\n  raw_title: \"Igor Morozov - Ducks and monads: wonders of Ruby types\"\n  speakers:\n    - Igor Morozov\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"v-H9nK8hqfE\"\n  published_at: \"2018-08-24\"\n\n# Break\n\n- id: \"brad-urani-euruko-2018\"\n  title: \"Rails Anti-Patterns: How Not To Design Your Database\"\n  raw_title: \"Brad Urani - Rails anti-patterns: how not to design your database\"\n  speakers:\n    - Brad Urani\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zo3iRBPzscU\"\n  published_at: \"2018-08-24\"\n\n- id: \"coraline-ada-ehmke-euruko-2018\"\n  title: \"The Broken Promise of Open Source\"\n  raw_title: \"Coraline Ada Ehmke - The broken promise of Open Source\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5ByUPh_uPqQ\"\n  published_at: \"2018-08-24\"\n\n# Break\n\n- id: \"louisa-barrett-euruko-2018\"\n  title: \"Ruby Not Red: Color Theory For The Rest Of Us\"\n  raw_title: \"Louisa Barrett - Ruby not red: color theory for the rest of us\"\n  speakers:\n    - Louisa Barrett\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"OgO1EIFDgPU\"\n  published_at: \"2018-08-24\"\n\n# Wrap up\n\n# Party\n\n## Day 2 - 2018-08-25\n\n# Welcome\n\n- id: \"nadia-odunayo-euruko-2018\"\n  title: \"The Case of The Missing Method — A Ruby Mystery Story\"\n  raw_title: \"Nadia Odunayo - The case of the missing method — a Ruby mystery story\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-25\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"wkz-B1w2GVM\"\n  published_at: \"2018-08-25\"\n\n- id: \"city-pitches-euruko-2018\"\n  title: \"City Pitches\"\n  raw_title: \"Pitch the next EuRuKo's location\"\n  event_name: \"Euruko 2018\"\n  date: \"2021-06-01\"\n  description: |-\n    Pitch the next EuRuKo's location\n  video_provider: \"youtube\"\n  video_id: \"YXe9OoQW8lc\"\n  published_at: \"2018-08-25\"\n  talks:\n    - title: \"City Pitch: Bristol\"\n      start_cue: \"00:35\"\n      end_cue: \"04:35\"\n      id: \"miles-woodroffe-city-pitch-euruko-2018\"\n      video_id: \"miles-woodroffe-city-pitch-euruko-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Miles Woodroffe\n\n    - title: \"City Pitch: Rotterdam\"\n      start_cue: \"04:35\"\n      end_cue: \"07:40\"\n      id: \"floor-drees-rayta-van-rijswijk-city-pitch-euruko-2018\"\n      video_id: \"floor-drees-rayta-van-rijswijk-city-pitch-euruko-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Floor Drees\n        - Rayta van Rijswijk\n\n    - title: \"City Pitch: Plovediv\"\n      start_cue: \"07:40\"\n      end_cue: \"11:35\"\n      id: \"gabriela-luhova-city-pitch-euruko-2018\"\n      video_id: \"gabriela-luhova-city-pitch-euruko-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Gabriela Luhova\n\n# Lunch & voting on the next EuRuKo's location\n\n- id: \"ana-mara-martnez-gmez-euruko-2018\"\n  title: \"Let's Refactor Some Ruby Code\"\n  raw_title: \"Ana María Martínez Gómez - Let's refactor some Ruby code\"\n  speakers:\n    - Ana María Martínez Gómez\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-25\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jUc8InwoA-E\"\n  published_at: \"2018-08-25\"\n\n- id: \"pan-thomakos-euruko-2018\"\n  title: \"Debugging Adventures in Rack-land\"\n  raw_title: \"Pan Thomakos - Debugging adventures in Rack-land\"\n  speakers:\n    - Pan Thomakos\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-25\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5o4krwjJbOI\"\n  published_at: \"2018-08-25\"\n\n# Break\n\n- id: \"lightning-talks-euruko-2018\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning talks\"\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-25\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zSeaNPjwnnA\"\n  published_at: \"2018-08-25\"\n  talks:\n    - title: \"Lightning Talk: Fun With Programming Spreadsheets\"\n      event_name: \"EuRuKo 2018\"\n      date: \"2018-08-25\"\n      start_cue: \"03:38\"\n      end_cue: \"08:40\"\n      id: \"tomasz-stachewicz-lighting-talk-euruko-2018\"\n      video_id: \"tomasz-stachewicz-lighting-talk-euruko-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomasz Stachewicz\n\n    - title: \"Lightning Talk: The information flow: +1 way to be up-to-date\"\n      event_name: \"EuRuKo 2018\"\n      date: \"2018-08-25\"\n      start_cue: \"08:55\"\n      end_cue: \"12:32\"\n      id: \"anna-shcherbinina-lighting-talk-euruko-2018\"\n      video_id: \"anna-shcherbinina-lighting-talk-euruko-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Anna Shcherbinina\n\n    - title: \"Lightning Talk: CP-8: GitHub Automation with CP-8 Bot\"\n      event_name: \"EuRuKo 2018\"\n      date: \"2018-08-25\"\n      start_cue: \"12:52\"\n      end_cue: \"17:02\"\n      id: \"miles-woodroffe-lighting-talk-euruko-2018\"\n      video_id: \"miles-woodroffe-lighting-talk-euruko-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Miles Woodroffe\n\n    - title: \"Lightning Talk: How to do microservices...... badly\"\n      event_name: \"EuRuKo 2018\"\n      date: \"2018-08-25\"\n      start_cue: \"17:22\"\n      end_cue: \"21:40\"\n      id: \"mazin-power-lighting-talk-euruko-2018\"\n      video_id: \"mazin-power-lighting-talk-euruko-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Mazin Power\n\n    - title: \"Lightning Talk: The Power of Community\"\n      event_name: \"EuRuKo 2018\"\n      date: \"2018-08-25\"\n      start_cue: \"22:10\"\n      end_cue: \"25:50\"\n      id: \"gabriela-luhova-lighting-talk-euruko-2018\"\n      video_id: \"gabriela-luhova-lighting-talk-euruko-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Gabriela Luhova\n\n- id: \"kerstin-puschke-euruko-2018\"\n  title: \"Scaling a Monolith isn't Scaling Microservices\"\n  raw_title: \"Kerstin Puschke - Scaling a monolith isn't scaling microservices\"\n  speakers:\n    - Kerstin Puschke\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-25\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"tA8gGd_Rl7E\"\n  published_at: \"2018-08-25\"\n\n# Break\n\n- id: \"amr-abdelwahab-euruko-2018\"\n  title: \"An Empathy Exercise: Contextualising The Question of Privilege\"\n  raw_title: \"Amr Abdelwahab - An empathy exercise: contextualising the question of privilege\"\n  speakers:\n    - Amr Abdelwahab\n  event_name: \"EuRuKo 2018\"\n  date: \"2018-08-25\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6CqmGYvFwAQ\"\n  published_at: \"2018-08-25\"\n# Wrap up & announcing the next EuRuKo's location - https://www.youtube.com/watch?v=wMggsShGTzk\n"
  },
  {
    "path": "data/euruko/euruko-2019/event.yml",
    "content": "---\nid: \"PLZW-kXE0oRykFFY4CTzKBqXC_RDNL_TD6\"\ntitle: \"EuRuKo 2019\"\nkind: \"conference\"\nlocation: \"Rotterdam, Netherlands\"\ndescription: \"\"\npublished_at: \"2021-06-01\"\nstart_date: \"2019-06-21\"\nend_date: \"2019-06-22\"\nchannel_id: \"UCgXsZr2e0AgUJMZm5t03WVw\"\nyear: 2019\nbanner_background: \"linear-gradient(#FEEBD1, #FDD7A2)\"\nfeatured_background: \"linear-gradient(#FEEBD1, #FDD7A2)\"\nfeatured_color: \"#633152\"\nwebsite: \"https://2019.euruko.org\"\ncoordinates:\n  latitude: 51.89769099999999\n  longitude: 4.4733852\n"
  },
  {
    "path": "data/euruko/euruko-2019/venue.yml",
    "content": "---\nname: \"ss Rotterdam\"\ndescription: |-\n  A ship with a rich history now permanently docked in Rotterdam, serving as the event venue.\n\naddress:\n  street: \"3e Katendrechtsehoofd 25\"\n  city: \"Rotterdam\"\n  region: \"Zuid-Holland\"\n  postal_code: \"3072AM\"\n  country: \"Netherlands\"\n  country_code: \"NL\"\n  display: \"3e Katendrechtse Hoofd 25, 3072 AM Rotterdam, Netherlands\"\n\naccessibility:\n  wheelchair: true\n  notes: \"The event space is wheelchair accessible.\"\n\ncoordinates:\n  latitude: 51.89769099999999\n  longitude: 4.4733852\n\nmaps:\n  google: \"https://maps.google.com/?q=ss+Rotterdam,51.89769099999999,4.4733852\"\n  apple: \"https://maps.apple.com/?q=ss+Rotterdam&ll=51.89769099999999,4.4733852\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=51.89769099999999&mlon=4.4733852\"\n"
  },
  {
    "path": "data/euruko/euruko-2019/videos.yml",
    "content": "---\n# Website: https://2019.euruko.org\n# Schedule: https://2019.euruko.org/#schedule\n\n## Day 1 - Friday, June 21\n\n- id: \"yukihiro-matz-matsumoto-euruko-2019\"\n  title: \"Keynote: Functional Future Ruby by Yukihiro Matsumoto\"\n  raw_title: \"EuRuKo 2019 Keynote: Functional Future Ruby by Yukihiro Matsumoto\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-21\"\n  published_at: \"2021-01-11\"\n  description: |-\n    Keynote: Functional (Future) Ruby\n\n    Yukihiro Matsumoto - https://twitter.com/yukihiro_matz\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"DC05C-UT3QQ\"\n\n- id: \"kaja-santro-euruko-2019\"\n  title: \"From multiple apps to Monolith\"\n  raw_title: \"From multiple apps to Monolith by Kaja Santro\"\n  speakers:\n    - Kaja Santro\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-21\"\n  published_at: \"2021-01-11\"\n  description: |-\n    From multiple apps to Monolith - #BuildingMonsterservices\n\n    We are currently transferring our 5 public Rails apps to 1 big monolith. All five of them are job boards with seemingly similar logic but historically grown exceptions and weird peculiarities. The perspective to have multiple data bases managed in 1 app in Rails 6 sparked our idea. The whole story!\n\n    Kaja Santro - https://twitter.com/AlizeNero\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"V6oBzmVAhl0\"\n\n- id: \"damir-svrtan-euruko-2019\"\n  title: \"Surrounded by Microservices\"\n  raw_title: \"Surrounded by Microservices by Damir Svrtan\"\n  speakers:\n    - Damir Svrtan\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-21\"\n  published_at: \"2021-01-11\"\n  description: |-\n    Surrounded by Microservices\n\n    How to architect an app that consumes endless data sources via various different protocols? How to support easy swapping of those data sources and how to test it with confidence? Let's checkout how these and many other requirements are fulfilled within the Netflix Studio space.\n\n    Damir Svrtan - https://twitter.com/DamirSvrtan\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"L7Q2e0i2osc\"\n\n- id: \"hongli-lai-euruko-2019\"\n  title: \"What causes Ruby memory bloat?\"\n  raw_title: \"What causes Ruby memory bloat? by Hongli Lai\"\n  speakers:\n    - Hongli Lai\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-21\"\n  published_at: \"2021-01-11\"\n  description: |-\n    What causes Ruby memory bloat?\n\n    Ruby apps can use a lot of memory. But why? I set out on a journey of discovery, and not only found evidence that defies common wisdom, but also a simple way to reduce memory usage by 70%.\n\n    Hongli Lai - https://twitter.com/honglilai\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"JBIN-Hh8wTA\"\n\n- id: \"melanie-keatley-euruko-2019\"\n  title: \"Using Pokemon To Catch All Code Smells\"\n  raw_title: \"using Pokemon to catch all code smells by Melanie Keatley\"\n  speakers:\n    - Melanie Keatley\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-21\"\n  published_at: \"2021-01-11\"\n  description: |-\n    It's very effective; using Pokemon to catch all code smells\n\n    When learning new skills, connecting what you already know is key. Studying the most common code smells in Ruby and their fixes, exposes a pattern that is similar to how the game mechanic in the popular video game Pokemon works. Grouping certain types and finding the way to beat them.\n\n    Melanie Keatley - https://twitter.com/Keatley\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"BeATptdwNSw\"\n\n- id: \"torsten-schnebaum-euruko-2019\"\n  title: \"A journey to MRuby on LEGO robots\"\n  raw_title: \"A journey to MRuby on LEGO robots by Torsten Schönebaum\"\n  speakers:\n    - Torsten Schönebaum\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-21\"\n  published_at: \"2021-01-11\"\n  description: |-\n    Building bricks with MRuby: A journey to MRuby on LEGO robots\n\n    Constructing robots with LEGO is fun, programming them using Ruby even more. If you ever wanted to know how to start with MRuby on a device that can be changed into anything you can build with LEGO — this talk is for you.\n\n    Torsten Schönebaum - https://twitter.com/radlepunktde\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"54v7kMzVAW8\"\n\n- id: \"ashley-jean-euruko-2019\"\n  title: \"A gentle introduction to Data Structure Trees\"\n  raw_title: \"A gentle introduction to Data Structure Trees by Ashley Jean\"\n  speakers:\n    - Ashley Jean\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-21\"\n  published_at: \"2021-01-11\"\n  description: |-\n    A gentle introduction to Data Structure Trees\n\n    In this talk, we’ll dive into Data Structure Trees. We’ll talk about how to work with them and why they’re useful. Also, we’ll discuss how they’re visible in our codebase and look at some modern examples using applications and systems.\n\n    Ashley Jean - https://twitter.com/AshhJean\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"BfZHmzMnPmM\"\n\n- id: \"laura-linda-laugwitz-euruko-2019\"\n  title: \"Keynote: The Miseducation of This Machine by Laura Linda Laugwitz\"\n  raw_title: \"EuRuKo 2019 Keynote: The Miseducation of This Machine by Laura Linda Laugwitz\"\n  speakers:\n    - Laura Linda Laugwitz\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-21\"\n  published_at: \"2021-01-11\"\n  description: |-\n    Closing keynote: The Miseducation of This Machine \n\n    While machines continue to learn with more sophisticated algorithms and larger amounts of data, humans need to understand how such learning works in order to take its results with the proper grain of salt. Let's make ML tangible and thus help you become a better machine teacher!\n\n    Laura Linda Laugwitz - https://twitter.com/lauralindal\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"1-8J0wfvhrU\"\n\n## Day 2 - Saturday, June 22\n\n- id: \"charity-majors-euruko-2019\"\n  title: \"Keynote: I Test In Production by Charity Majors\"\n  raw_title: \"EuRuKo 2019 Keynote: I Test In Production by Charity Majors\"\n  speakers:\n    - Charity Majors\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-22\"\n  published_at: \"2021-01-19\"\n  description: |-\n    Keynote: Yes, I Test In Production... And So Should You \n\n    Testing in prod has gotten a bad rap. It's both inevitable - you can't know everything before you ship - and desirable. In modern complex systems, failure is a constant and the only guiding principle is that \"users should never notice\". So how do you test safely in prod, and how should you allocate your scarce engineering cycles between prod and staging?\n\n    Charity Majors - https://twitter.com/mipsytipsy\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"b2oota_FhGY\"\n\n- id: \"bilawal-maheed-euruko-2019\"\n  title: \"Making Tech Documentation Better, Easier, And Less Boring\"\n  raw_title: \"Making Tech Documentation Better, Easier, And Less Boring by Bilawal Maheed\"\n  speakers:\n    - Bilawal Maheed\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-22\"\n  published_at: \"2021-01-19\"\n  description: |-\n    How We’re Making Tech Documentation Better, Easier, And Less Boring\n\n    Engineers optimize for scale. We think about writing the “best” code, designing non-flaky tests to give us confidence, and adopting the latest and greatest - but why do we still fail to write, maintain, and improve our docs? Given we all rely on docs, what went wrong?\n\n    Bilawal Maheed - https://twitter.com/bilawalhameed\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"jjVeRxQKTYU\"\n\n- id: \"yusuke-endoh-euruko-2019\"\n  title: \"A Plan towards Ruby 3 Types\"\n  raw_title: \"A Plan towards Ruby 3 Types by Yusuke Endoh\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-22\"\n  published_at: \"2021-01-19\"\n  description: |-\n    Plan towards Ruby 3 Types\n\n    We introduce Ruby Type Profiler which is one of the proposals for Ruby 3’s static analysis. As far as we know, it is only one approach to statically analyze a non-type-annotated program for MRI. We aim to realize a static analysis tool that imposes no change of the great Ruby programming experience.\n\n    Yusuke Endoh - https://twitter.com/mametter\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"3HB3WGn2LAQ\"\n\n- id: \"lightning-talks-euruko-2019\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-22\"\n  published_at: \"2021-01-19\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"2-1wlXkLt-I\"\n  talks:\n    - title: \"Lightning Talk: Super-powering your editor with Sorbet Typer\"\n      event_name: \"EuRuKo 2019\"\n      date: \"2019-06-22\"\n      published_at: \"2021-01-19\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"madison-white-lighting-talk-euruko-2019\"\n      video_id: \"madison-white-lighting-talk-euruko-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Madison White\n\n    - title: \"Lightning Talk: Zerus & Ona\"\n      event_name: \"EuRuKo 2019\"\n      date: \"2019-06-22\"\n      published_at: \"2021-01-19\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"miriam-tocino-lighting-talk-euruko-2019\"\n      video_id: \"miriam-tocino-lighting-talk-euruko-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Miriam Tocino\n\n    - title: \"Lightning Talk: NoSuchBucket\"\n      event_name: \"EuRuKo 2019\"\n      date: \"2019-06-22\"\n      published_at: \"2021-01-19\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"julik-tarkhanov-lighting-talk-euruko-2019\"\n      video_id: \"julik-tarkhanov-lighting-talk-euruko-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Julik Tarkhanov\n\n    - title: \"Lightning Talk: search_flip\"\n      event_name: \"EuRuKo 2019\"\n      date: \"2019-06-22\"\n      published_at: \"2021-01-19\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"benjamin-vetter-lighting-talk-euruko-2019\"\n      video_id: \"benjamin-vetter-lighting-talk-euruko-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Benjamin Vetter\n\n    - title: 'Lightning Talk: A \"Splash\" Course on Live Captioning'\n      event_name: \"EuRuKo 2019\"\n      date: \"2019-06-22\"\n      published_at: \"2021-01-19\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"norma-miller-lighting-talk-euruko-2019\"\n      video_id: \"norma-miller-lighting-talk-euruko-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Norma Miller\n\n- id: \"jan-krutisch-euruko-2019\"\n  title: \"The Musical Ruby\"\n  raw_title: \"The musical Ruby by Jan Krutisch\"\n  speakers:\n    - Jan Krutisch\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-22\"\n  published_at: \"2021-01-19\"\n  description: |-\n    The musical Ruby\n\n    Let’s make some music with Ruby. After cheating a bit with the amazing SonicPi, we’ll drop down to the foundations - While explaining the basics of digital sound synthesis and a tiny bit of music theory, we’ll create a tune to dance to using nothing but pure Ruby.\n\n    Jan Krutisch - https://twitter.com/halfbyte\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"D6EIHoSkPYQ\"\n\n- id: \"aaron-cruz-euruko-2019\"\n  title: \"Steal this talk\"\n  raw_title: \"Steal this talk by Aaron Cruz\"\n  speakers:\n    - Aaron Cruz\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-22\"\n  published_at: \"2021-01-19\"\n  description: |-\n    Steal this talk\n\n    It’s been a long journey building “Talkie”, but in the process I’ve consumed 100’s of Ruby talks from over the last years and I want to boil them down to the best things I can fit into this time slot. This talk is like a listicle of listicles, a best of Ruby talks. Like if you soaked up all the Ruby talks, cooked them down into a thick paste and then smeared it all over the EuRuKo stage.\n\n    Aaron Cruz - https://twitter.com/mraaroncruz\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"yiFYRArX6Bo\"\n\n- id: \"richard-schneeman-euruko-2019\"\n  title: \"Tidying Active Record Allocations\"\n  raw_title: \"Tidying Active Record Allocations by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-22\"\n  published_at: \"2021-01-19\"\n  description: |-\n    The Life-Changing Magic of Tidying Active Record Allocations\n    Your app is slow. It does not spark joy. In this talk, we will use memory profiling tools to discover performance hotspots. We will use this technique with a real-world application to identify a piece of optimizable code in Active Record that leads to a patch with substantial page speed impact.\n\n    Richard Schneeman - https://twitter.com/schneems\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"Aczy01drwkg\"\n\n- id: \"eileen-m-uchitelle-euruko-2019\"\n  title: \"Keynote: The Past, Present, and Future of Rails at GitHub\"\n  raw_title: \"EuRuKo 2019 Keynote: The Past, Present, and Future of Rails at GitHub by Eileen M. Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"EuRuKo 2019\"\n  date: \"2019-06-22\"\n  published_at: \"2021-01-19\"\n  description: |-\n    Closing keynote: The Past, Present, and Future of Rails at GitHub\n\n\n    We'll look at GitHub's story, our Rails upgrade, and how cumulative technical debt can stifle development. At the end we'll explore how we're staying up to date with Rails and our investment in the future of Rails.\n\n    Eileen M. Uchitelle - https://twitter.com/eileencodes\n    EuRuKo 2019\n  video_provider: \"youtube\"\n  video_id: \"ZrcPoRx_kQE\"\n"
  },
  {
    "path": "data/euruko/euruko-2021/event.yml",
    "content": "---\nid: \"PLZW-kXE0oRyknRwEUrg5o491KomjkNU16\"\ntitle: \"EuRuKo 2021\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  EuRuKo 2021, Helsinki, Finland\npublished_at: \"2021-06-01\"\nstart_date: \"2021-05-28\"\nend_date: \"2021-05-29\"\nchannel_id: \"UCgXsZr2e0AgUJMZm5t03WVw\"\nyear: 2021\nbanner_background: \"#503469\"\nfeatured_background: \"#503469\"\nfeatured_color: \"#FF9A1B\"\nwebsite: \"https://2021.euruko.org\"\ncoordinates: false\n"
  },
  {
    "path": "data/euruko/euruko-2021/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"peter-zhu-euruko-2021\"\n  title: \"Optimizing Ruby's memory layout\"\n  raw_title: \"Optimizing Ruby's memory layout (Peter Zhu & Matthew Valentine-House)\"\n  speakers:\n    - Peter Zhu\n    - Matthew Valentine-House\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Ruby’s current memory layout does not optimize for cache performance, and this has implications: object data like string and array contents are often not stored close to the objects that use them, causing poor data locality, reducing the efficiency of CPU caches, and making it more complex for the garbage collector to manage these objects. Additionally, objects can also contain pointers to data that then point back into the Ruby heap, slowing down object access due to pointer indirection.\n\n    Join us as we explore how the variable width allocation project will change the garbage collector heap to replace the system’s malloc heap, giving us finer control of the memory layout to optimize for performance.\n  video_provider: \"youtube\"\n  video_id: \"x_YhDCNeFQ8\"\n\n- id: \"eeva-jonna-panula-euruko-2021\"\n  title: \"Don't Develop Just for Yourself - A Developer's Checklist to Accessibility\"\n  raw_title: \"Don't Develop Just for Yourself - A Developer's Checklist to Accessibility (Eeva-Jonna Panula)\"\n  speakers:\n    - Eeva-Jonna Panula\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Developer, are you (unconsciously) developing sites for users just like yourself? It often means a sighted mouse user with good fine motor skills and who is proficient with computers. But not every user is like that.\n\n    Many projects have automated accessibility checkers, and that is a good start. However, they don’t catch most of the failures on accessibility. There are some fairly simple checks to ensure a better experience for your users, and from this talk, you’ll learn how to do them and, most importantly, why they are essential to do.\n  video_provider: \"youtube\"\n  video_id: \"s8F1Qar4SkA\"\n\n- id: \"thomas-leitner-euruko-2021\"\n  title: \"Lightning Talk: State of the PDF\"\n  raw_title: \"Lightning talk: State of the PDF (Thomas Leitner)\"\n  speakers:\n    - Thomas Leitner\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    What are your options when dealing with PDFs in Ruby? Are you creating PDFs? Then you are likely using wkhtmltopdf or Prawn.\n\n    What if you need to manipulate PDF files? Are you resorting to calling command line tools like pdftk? Or chaining multiple libraries/CLI tools together?\n\n    Have you tried HexaPDF? It is a relatively new PDF library for Ruby which unites all PDF manipulation and creation facilities under one pure-Ruby roof. It is fast with low memory usage and a very Ruby-esque API interface.\n\n    The lightning talk will give a short introduction into the available libraries and then focus on the current state of HexaPDF and what it brings to the table.\n  video_provider: \"youtube\"\n  video_id: \"UpwSpQAm-Rc\"\n\n- id: \"lisa-karlin-curtis-euruko-2021\"\n  title: \"How to stop breaking other people's things\"\n  raw_title: \"How to stop breaking other people's things (Lisa Karlin Curtis)\"\n  speakers:\n    - Lisa Karlin Curtis\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Breaking changes are sad. We’ve all been there; someone else changes their API in a way you weren’t expecting, and now you have a live-ops incident you need to fix urgently to get your software working again. Of course, many of us are on the other side too: we build APIs that other people’s software relies on.\n  video_provider: \"youtube\"\n  video_id: \"eEFcS_cmusQ\"\n\n- id: \"alan-wu-euruko-2021\"\n  title: \"Lightning Talk: Fun Passing Blocks Around\"\n  raw_title: \"Fun Passing Blocks Around (sponsored) (Alan Wu, Shopify)\"\n  speakers:\n    - Alan Wu\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    A sponsored lightning talk from Shopify\n  video_provider: \"youtube\"\n  video_id: \"MOfqH8euU58\"\n\n- id: \"dmitry-tsepelev-euruko-2021\"\n  title: \"Building high–performance GraphQL APIs\"\n  raw_title: \"Building high–performance GraphQL APIs (Dmitry Tsepelev)\"\n  speakers:\n    - Dmitry Tsepelev\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    One day you decided to give GraphQL a try and implement an API of your new application using GraphQL. You deployed the app to production, but after a while, you realized, that responses are not super fast. How to find out what makes your GraphQL endpoint slow?\n\n    We’ll discuss how queries are executed and what makes processing slower. After that, we’ll learn how to measure performance in the GraphQL era and determine the part we should improve. Finally, we’ll discuss possible solutions and some advanced technics to keep your GraphQL app fast!\n  video_provider: \"youtube\"\n  video_id: \"kIJdauCgBC8\"\n\n- id: \"zhi-ren-guoy-euruko-2021\"\n  title: \"Lightning Talk: Adding byebug to the Professional Puts Debugger Tool Set\"\n  raw_title: \"Lightning talk: Adding byebug to the Professional Puts Debugger Tool Set (Zhi Ren Guoy)\"\n  speakers:\n    - Zhi Ren Guoy\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    A crash course on getting started with the ‘byebug’ debugger.\n  video_provider: \"youtube\"\n  video_id: \"YibyXazjnII\"\n\n- id: \"juan-carlos-ruiz-euruko-2021\"\n  title: \"Going native with FFI\"\n  raw_title: \"Going native with FFI (Juan Carlos Ruiz)\"\n  speakers:\n    - Juan Carlos Ruiz\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Ruby is a flexible language that allows us to write expressive and maintainable code. However, sometimes it could be necessary to work with a low-level language, looking for better performance. In this talk, I’m going to show you how to use Ruby to create an interface for compiled languages like C.\n  video_provider: \"youtube\"\n  video_id: \"75bAbaUu5jI\"\n\n- id: \"yukihiro-matz-matsumoto-euruko-2021\"\n  title: \"Keynote: Beyond Ruby 3.0\"\n  raw_title: \"Keynote: Beyond Ruby 3.0 (Yukihiro Matsumoto)\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Matz's keynote from EuRuKo 2021\n  video_provider: \"youtube\"\n  video_id: \"Dp12a3KGNFw\"\n\n- id: \"linda-liukas-euruko-2021\"\n  title: \"Keynote: Q&A (Food for thought: home-cooked software)\"\n  raw_title: \"Q&A with Linda Liukas\"\n  speakers:\n    - Linda Liukas\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Unfortunately we cannot provide the recording of the closing keynote by Linda Liukas. We are only able to publish the Q&A section of the talk.\n  video_provider: \"youtube\"\n  video_id: \"ICu0mVWU7Y8\"\n\n- id: \"moncef-belyamani-euruko-2021\"\n  title: \"Lightning Talk: The 6 Characters That Could Bring Down Your App\"\n  raw_title: \"Lightning talk: The 6 Characters That Could Bring Down Your App (Moncef Belyamani)\"\n  speakers:\n    - Moncef Belyamani\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    This is a true story about how using the wrong method caused the app to hang for our users, and how it increased our database CPU usage by up to 10 times!\n\n    You probably are using this same method in your app right now. Find out what you should use instead.\n  video_provider: \"youtube\"\n  video_id: \"XgA_2pJtJEM\"\n\n- id: \"soutaro-matsumoto-euruko-2021\"\n  title: \"IDE development with Ruby\"\n  raw_title: \"IDE development with Ruby (Soutaro Matsumoto)\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Integrated development environment (IDE) is one of the most frequently used tools for programming. It’s a kind of text editor where you type and read the code, but it does more for you. On-the-fly error reporting, completion, go-to-definition, and more. These features help you writing and reading the code and make the tools more valuable than simple text editors.\n\n    I have been working for IDE development to support Ruby programming with a static type checker. It is based on the Language Server Protocol (LSP) and implemented in Ruby.\n\n    I want to share my experience. What is the protocol? How can the LSP features be implemented? You will get to know the under-the-hood of IDEs, and the tools will become more familiar to you.\n  video_provider: \"youtube\"\n  video_id: \"l_G4_qTqrGQ\"\n\n- id: \"ville-lautanala-euruko-2021\"\n  title: \"Streaming data transformations with Ruby\"\n  raw_title: \"Streaming data transformations with Ruby (sponsored) (Ville Lautanala, Smartly)\"\n  speakers:\n    - Ville Lautanala\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Sponsored lightning talk from Smartly\n  video_provider: \"youtube\"\n  video_id: \"lEedrF7ZNZU\"\n\n- id: \"lena-wiberg-euruko-2021\"\n  title: \"Delivering fast and slow - Ethics of quality\"\n  raw_title: \"Delivering fast and slow - Ethics of quality (Lena Wiberg)\"\n  speakers:\n    - Lena Wiberg\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Daily, we are pushing the boundaries of how fast we can deliver software. Constantly running on a knife’s edge between great success and horrible failure.\n\n    Delivering something new, better, faster than our competition can mean incredible payoff and we are constantly being asked to cut costs and deliver more, faster, cheaper. But then suddenly, you fall off the other side of the edge and wake up to 189 dead in a plane crash or having to take down and redesign your entire banking service because the architecture didn’t hold up to the load. It probably wasn’t your decision to push that to production but one can imagine that a long chain of people have to have made a number of small (or huge) decisions that led up to that result.\n  video_provider: \"youtube\"\n  video_id: \"Yj4oSyRVz9A\"\n\n- id: \"cyril-rohr-euruko-2021\"\n  title: \"Lightning Talk: Shipping Ruby and Rails apps as native Linux packages\"\n  raw_title: \"Lightning talk: Shipping Ruby and Rails apps as native Linux packages (Cyril Rohr)\"\n  speakers:\n    - Cyril Rohr\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Ruby and Rails applications are notoriously difficult to package in the native formats (.deb, .rpm) used by the main Linux distributions.\n\n    Although Docker has allowed to ship applications almost anywhere, native packages remain relevant in constrained environments (banks, etc.), or when distributing an app or CLI to end users that may not have or want to use Docker.\n\n    In this presentation you’ll learn how to package a Rails application for the main Linux distributions available. You’ll also learn how to host the resulting packages, and apply the same recipe to package a Ruby CLI that can be shipped to users.\n  video_provider: \"youtube\"\n  video_id: \"VK65X8fyqVM\"\n\n- id: \"maple-ong-euruko-2021\"\n  title: \"Building a Ruby web app using the Ruby Standard Library\"\n  raw_title: \"Building a Ruby web app using the Ruby Standard Library (Maple Ong)\"\n  speakers:\n    - Maple Ong\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Do you want to understand how a web application works without Rails magic? Let’s go back to the basics of a web application and build one from the ground up using Ruby Standard Library. After this session, you’ll appreciate Rails that much more.\n  video_provider: \"youtube\"\n  video_id: \"lxczDssLYKA\"\n\n- id: \"melissa-jurkoic-euruko-2021\"\n  title: \"Why a Diverse Team is Crucial to Startup Success\"\n  raw_title: \"Why a Diverse Team is Crucial to Startup Success (Melissa Jurkoic)\"\n  speakers:\n    - Melissa Jurkoic\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    Team diversity refers to differences between members of startup team. Those differences can include demographic differences (like age, race, sex, ethnicity), personality (extrovert, introvert, and differing Myers-Briggs types) and functional (as in skill sets, like engineering, design, copywriting, and marketing).\n\n    How does team diversity impact your customers’ experience from the moment they learn about you through their journey with you? You will attract and relate to customers how look like you. They will understand your messaging and you will understand their needs. If you don’t represent the right dimensions of diversity, you are leaving an amazing experience behind.\n  video_provider: \"youtube\"\n  video_id: \"08wUjbh4RoQ\"\n\n- id: \"amy-wall-euruko-2021\"\n  title: \"Lockdown: The Mother of Invention\"\n  raw_title: \"Lockdown: The Mother of Invention (Amy Wall)\"\n  speakers:\n    - Amy Wall\n  event_name: \"EuRuKo 2021\"\n  date: \"2021-05-28\"\n  published_at: \"2021-06-03\"\n  description: |-\n    The last year has been hard on all of us. Cutting through the bad news and the mundanity has required resilience, creativity, and determination. Thankfully, we have had a secret weapon on our side to keep us occupied: Ruby.\n\n    Join me as I explore some of the good, the bad, and the just plain hilarious ideas Rubyists have been working on during lockdown. I will survey Ruby lovers of all levels to see what has been holding their attention during this difficult year.\n\n    I will also share my own experience with staying busy, including my adventure building an “On Air” alert system for Zoom in my home office space using Ruby.\n  video_provider: \"youtube\"\n  video_id: \"9zEkCM2MElY\"\n"
  },
  {
    "path": "data/euruko/euruko-2022/event.yml",
    "content": "---\nid: \"PLZW-kXE0oRykcraQ1b6tT5ozKPeK-Jttq\"\ntitle: \"EuRuKo 2022\"\nkind: \"conference\"\nlocation: \"Helsinki, Finland\"\ndescription: |-\n  Talks from EuRuKo 2022\npublished_at: \"2022-10-20\"\nstart_date: \"2022-10-13\"\nend_date: \"2022-10-14\"\nchannel_id: \"UCgXsZr2e0AgUJMZm5t03WVw\"\nyear: 2022\nbanner_background: \"#010024\"\nfeatured_background: \"#010024\"\nfeatured_color: \"#FF9001\"\nwebsite: \"https://2022.euruko.org\"\ncoordinates:\n  latitude: 60.17853719999999\n  longitude: 24.9473058\n"
  },
  {
    "path": "data/euruko/euruko-2022/venue.yml",
    "content": "---\nname: \"Helsinki Congress Paasitorni\"\ndescription: |-\n  A historic conference and event venue located in Helsinki, Finland.\n\naddress:\n  street: \"Paasivuorenkatu 5 A, FIN-00530 Helsinki\"\n  city: \"Helsinki\"\n  region: \"Uusimaa\"\n  postal_code: \"00530\"\n  country: \"Finland\"\n  country_code: \"FI\"\n  display: \"Paasivuorenkatu 5 A, 00530 Helsinki, Finland\"\n\nhotels:\n  - name: \"Scandic Paasi\"\n    address:\n      street: \"5b Paasivuorenkatu\"\n      city: \"Helsinki\"\n      region: \"Uusimaa\"\n      postal_code: \"00530\"\n      country: \"Finland\"\n      country_code: \"FI\"\n      display: \"Paasivuorenkatu 5 B, 00530 Helsinki, Finland\"\n    distance: \"Next to the venue, in the same building\"\n    coordinates:\n      latitude: 60.1786207\n      longitude: 24.9479391\n    maps:\n      google: \"https://maps.google.com/?q=Scandic+Paasi,60.1786207,24.9479391\"\n      apple: \"https://maps.apple.com/?q=Scandic+Paasi&ll=60.1786207,24.9479391\"\n\ncoordinates:\n  latitude: 60.17853719999999\n  longitude: 24.9473058\n\nmaps:\n  google: \"https://maps.google.com/?q=Helsinki+Congress+Paasitorni,60.17853719999999,24.9473058\"\n  apple: \"https://maps.apple.com/?q=Helsinki+Congress+Paasitorni&ll=60.17853719999999,24.9473058\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=60.17853719999999&mlon=24.9473058\"\n"
  },
  {
    "path": "data/euruko/euruko-2022/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n# Website: https://2022.euruko.org\n# Repo: https://github.com/euruko/2022.euruko.org/tree/main/src/_data\n\n- id: \"yukihiro-matz-matsumoto-euruko-2022\"\n  title: \"Opening Keynote: MythBuster\"\n  raw_title: \"Opening keynote by Matz: MythBuster\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    The opening keynote by Yukihiro Matsumoto from EuRuKo 2022.\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=reVGR35H264&t=2010s\n  video_provider: \"youtube\"\n  video_id: \"r78H-QBkxyk\"\n\n- id: \"thijs-cadier-euruko-2022\"\n  title: \"How music works, using Ruby\"\n  raw_title: \"How music works, using Ruby by Thijs Cadier\"\n  speakers:\n    - Thijs Cadier\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    Musicians and sound engineers have found many ways of creating music, and making music sound good when played from a record. Some of their methods have become industry staples used on every recording released today. Let's look at what they do and reproduce some of their methods in Ruby!\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=reVGR35H264&t=6070s\n  video_provider: \"youtube\"\n  video_id: \"MtweO89OsUM\"\n\n- id: \"mel-kaulfuss-euruko-2022\"\n  title: \"Applying SRE Principles to CI/CD\"\n  raw_title: \"Applying SRE Principles to CI/CD by Mel Kaulfuss\"\n  speakers:\n    - Mel Kaulfuss\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    Discover how to approach CI/CD with an SRE mindset. Learn what SLOs, SLIs & error budgets are, and how to define them for your own build & deploy processes. Rebuild trust with your system’s stakeholders, and reclaim control over slow & unreliable build and deploy processes.\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=reVGR35H264&t=11910s\n  video_provider: \"youtube\"\n  video_id: \"dvTvq2sduV4\"\n\n- id: \"jemma-issroff-euruko-2022\"\n  title: \"Implementing Object Shapes in CRuby\"\n  raw_title: \"Implementing Object Shapes in CRuby by Jemma Issroff\"\n  speakers:\n    - Jemma Issroff\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    Object Shapes are a technique for representing objects' properties that can increase cache hits in instance variable lookups, decrease runtime checks, and improve JIT performance. In this talk, we'll learn how they work, why implement them, and interesting implementation details.\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=reVGR35H264&t=14985s\n  video_provider: \"youtube\"\n  video_id: \"2aVyTtxs0GU\"\n\n- id: \"wiktoria-dalach-euruko-2022\"\n  title: \"Security Doesn’t Have To Be a Nightmare\"\n  raw_title: \"Security Doesn’t Have To Be a Nightmare by Wiktoria Dalach\"\n  speakers:\n    - Wiktoria Dalach\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    Security doesn’t have to be scary. From this talk, you will learn 5 tips that can almost immediately make your code base more secure.\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=reVGR35H264&t=19095s\n  video_provider: \"youtube\"\n  video_id: \"l4uyAQZBwyY\"\n\n- id: \"maple-ong-euruko-2022\"\n  title: \"Looking Into Peephole Optimizations\"\n  raw_title: \"Looking Into Peephole Optimizations by Maple Ong\"\n  speakers:\n    - Maple Ong\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    Let's learn about various peephole optimizations used to make bytecode generated by the Ruby compiler more performant. Do these small changes make any impact on the final runtime? Let's find out - experience reading bytecode is not needed!\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=reVGR35H264&t=22110s\n  video_provider: \"youtube\"\n  video_id: \"gnX1o8GBed0\"\n\n- id: \"adarsh-pandit-euruko-2022\"\n  title: \"The Technical and Organizational Infrastructure of the Ruby Community\"\n  raw_title: \"The Technical and Organizational Infrastructure of the Ruby Community by Adarsh Pandit\"\n  speakers:\n    - Adarsh Pandit\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    This is a talk which reviews all of the things which enable Ruby developers to use a secure programming language with easy package management in a supportive community. Specifically we will be tracking money spent and code shipped.\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=m2qelRkp1CY&t=1650s\n  video_provider: \"youtube\"\n  video_id: \"cNLscH0sGz4\"\n\n- id: \"vesa-vnsk-euruko-2022\"\n  title: \"From massive pull requests to trunk-based development with Ruby\"\n  raw_title: \"From massive pull requests to trunk-based development with Ruby by Vesa Vänskä\"\n  speakers:\n    - Vesa Vänskä\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    Talk about how to go from massive pull requests to trunk-based development with Ruby. Includes concrete examples of code, architecture, and workflows to implement smooth trunk-based development workflow.\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=m2qelRkp1CY&t=4980s\n  video_provider: \"youtube\"\n  video_id: \"M76dNDySrNc\"\n\n- id: \"lightning-talks-city-pitches-euruko-2022\"\n  title: \"Lightning Talks & City Pitches\"\n  raw_title: \"Lightning talks & city pitches\"\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    EuRuKo 2022 lightning talks:\n\n    - From Sinatra to Grape (How we're migrating from Sinatra to Grape and why) by Renato dos Santos Cerqueira\n    - Why bother about 'Questions?' by Mohnish Jadwani\n    - Building Delightful Command-Line Apps in Ruby by Hans Schnedlitz\n    - Welcome Ruby juniors by Hana Harencarova\n\n    Followed by EuRuKo 2023 host city pitches from Gdansk, Granada, Istanbul, Lviv, Vilnius, and Brighton.\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=m2qelRkp1CY&t=10965s\n  video_provider: \"youtube\"\n  video_id: \"JvVAtssjOu0\"\n  talks:\n    - title: \"Lightning Talks Intro\"\n      date: \"2022-10-13\"\n      start_cue: \"00:05\"\n      end_cue: \"02:13\"\n      thumbnail_cue: \"00:24\"\n      id: \"lighting-talks-intro-euruko-2022\"\n      video_id: \"lighting-talks-intro-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Antti Merilehto # Host/MC\n\n    - title: \"Lightning Talk: From Sinatra to Grape\"\n      date: \"2022-10-13\"\n      start_cue: \"02:13\"\n      end_cue: \"06:00\"\n      thumbnail_cue: \"02:24\"\n      id: \"renato-dos-santos-cerqueira-lighting-talk-euruko-2022\"\n      video_id: \"renato-dos-santos-cerqueira-lighting-talk-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Renato dos Santos Cerqueira\n\n    - title: \"Lightning Talk: Why bother about 'Questions?'\"\n      date: \"2022-10-13\"\n      start_cue: \"07:05\"\n      end_cue: \"12:24\"\n      thumbnail_cue: \"07:09\"\n      id: \"mohnish-jadwani-lighting-talk-euruko-2022\"\n      video_id: \"mohnish-jadwani-lighting-talk-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Mohnish Jadwani\n\n    - title: \"Lightning Talk: Building Delightful Command-Line Apps in Ruby\"\n      date: \"2022-10-13\"\n      start_cue: \"14:14\"\n      end_cue: \"19:00\"\n      id: \"hans-schnedlitz-lighting-talk-euruko-2022\"\n      video_id: \"hans-schnedlitz-lighting-talk-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Hans Schnedlitz\n\n    - title: \"Lightning Talk: Welcome Ruby Juniors\"\n      date: \"2022-10-13\"\n      start_cue: \"20:38\"\n      end_cue: \"25:50\"\n      id: \"hana-harencarova-lighting-talk-euruko-2022\"\n      video_id: \"hana-harencarova-lighting-talk-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Hana Harencarova\n\n    - title: \"City Pitch: Granada\"\n      date: \"2022-10-13\"\n      start_cue: \"27:32\"\n      end_cue: \"28:32\"\n      id: \"city-pitch-granada-lighting-talk-euruko-2022\"\n      video_id: \"city-pitch-granada-lighting-talk-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name\n\n    - title: \"City Pitch: Gdańsk\"\n      date: \"2022-10-13\"\n      start_cue: \"29:48\"\n      end_cue: \"31:38\"\n      id: \"city-pitch-gdansk-lighting-talk-euruko-2022\"\n      video_id: \"city-pitch-gdansk-lighting-talk-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomasz Stachewicz\n\n    - title: \"City Pitch: Istanbul\"\n      date: \"2022-10-13\"\n      start_cue: \"32:14\"\n      end_cue: \"34:53\"\n      thumbnail_cue: \"34:49\"\n      id: \"city-pitch-istanbul-lighting-talk-euruko-2022\"\n      video_id: \"city-pitch-istanbul-lighting-talk-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Ufuk Kayserilioglu\n\n    - title: \"City Pitch: Lviv\"\n      date: \"2022-10-13\"\n      start_cue: \"35:39\"\n      end_cue: \"37:02\"\n      thumbnail_cue: \"36:02\"\n      id: \"city-pitch-lviv-lighting-talk-euruko-2022\"\n      video_id: \"city-pitch-lviv-lighting-talk-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing speaker name 1\n        # - TODO # TODO: missing speaker name 2\n\n    - title: \"City Pitch: Vilnius\"\n      date: \"2022-10-13\"\n      start_cue: \"37:37\"\n      end_cue: \"41:30\"\n      id: \"city-pitch-vilnius-lighting-talk-euruko-2022\"\n      video_id: \"city-pitch-vilnius-lighting-talk-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Sergy Sergyenko\n\n    - title: \"City Pitch: Brighton\"\n      date: \"2022-10-13\"\n      start_cue: \"41:56\"\n      end_cue: \"44:44\"\n      thumbnail_cue: \"44:37\"\n      id: \"city-pitch-brighton-lighting-talk-euruko-2022\"\n      video_id: \"city-pitch-brighton-lighting-talk-euruko-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Andy Croll\n\n    - title: \"Special Announcement & Prize for Matias Korhonen\"\n      date: \"2022-10-13\"\n      start_cue: \"45:02\"\n      end_cue: \"48:49\"\n      id: \"special-announcement-euruko-2022\"\n      video_id: \"special-announcement-euruko-2022\"\n      video_provider: \"parent\"\n      description: |-\n        Lifetime Award for Ruby Community Excellence\n      speakers:\n        - Antti Merilehto # Host/MC\n        - Vesa Vänskä\n        - Matias Korhonen\n\n- id: \"yarden-laifenfeld-euruko-2022\"\n  title: \"Ruby & JVM: A (JRuby) Love Story\"\n  raw_title: \"Ruby & JVM: A (JRuby) Love Story by Yarden Laifenfeld\"\n  speakers:\n    - Yarden Laifenfeld\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    In this talk I will dive into why you should - or shouldn’t - use JRuby in your upcoming projects. We’ll compare the language to Ruby and other JVM languages, discuss its limitations and restrictions, and even dive into how such a strange concoction of languages came to be.\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=m2qelRkp1CY&t=16350s\n  video_provider: \"youtube\"\n  video_id: \"FN0gfZJazM8\"\n\n- id: \"andy-croll-euruko-2022\"\n  title: \"Closing Keynote: The Mrs Triggs Problem\"\n  raw_title: \"Closing keynote by Andy Croll\"\n  speakers:\n    - Andy Croll\n  event_name: \"EuRuKo 2022\"\n  date: \"2022-10-13\"\n  published_at: \"2022-10-20\"\n  description: |-\n    As a society we have an attribution problem. People who look like me get it easy. Join me to explore how we can push back on the default stories & myths of who is providing value in our community.\n\n    To watch with closed captions, view the livestream recording: https://www.youtube.com/watch?v=m2qelRkp1CY&t=19250s\n  video_provider: \"youtube\"\n  video_id: \"0UcTD49KugA\"\n"
  },
  {
    "path": "data/euruko/euruko-2023/event.yml",
    "content": "---\nid: \"PLZW-kXE0oRyljniGHqYqtQVIXoI4M97ck\"\ntitle: \"EuRuKo 2023\"\nkind: \"conference\"\nlocation: \"Vilnius, Lithuania\"\ndescription: \"\"\npublished_at: \"2023-10-04\"\nstart_date: \"2023-09-21\"\nend_date: \"2023-09-23\"\nchannel_id: \"UCgXsZr2e0AgUJMZm5t03WVw\"\nyear: 2023\nbanner_background: \"#2ABA7D\"\nfeatured_background: \"black\"\nfeatured_color: \"white\"\nwebsite: \"https://2023.euruko.org\"\ncoordinates:\n  latitude: 54.7226447\n  longitude: 25.3378447\n"
  },
  {
    "path": "data/euruko/euruko-2023/involvements.yml",
    "content": "---\n- name: \"Review Committee Member\"\n  users:\n    - Adrian Marin\n    # TODO: add all Review Committee Members\n"
  },
  {
    "path": "data/euruko/euruko-2023/venue.yml",
    "content": "---\nname: \"Vilnius Gediminas Technical University\"\naddress:\n  street: \"11 Saulėtekio alėja\"\n  city: \"Vilnius\"\n  region: \"Vilniaus apskritis\"\n  postal_code: \"10223\"\n  country: \"Lithuania\"\n  country_code: \"LT\"\n  display: \"Saulėtekio al. 11, 10223 Vilnius, Lithuania\"\n\ncoordinates:\n  latitude: 54.7226447\n  longitude: 25.3378447\n\nmaps:\n  google: \"https://maps.google.com/?q=Vilnius+Gediminas+Technical+University+(VILNIUS+TECH),54.7226447,25.3378447\"\n  apple: \"https://maps.apple.com/?q=Vilnius+Gediminas+Technical+University+(VILNIUS+TECH)&ll=54.7226447,25.3378447\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=54.7226447&mlon=25.3378447\"\n\nlocations:\n  - name: \"Dūmų fabrikas\"\n    kind: \"After Party\"\n    address:\n      street: \"5 Dūmų gatvė\"\n      city: \"Vilnius\"\n      region: \"Vilniaus apskritis\"\n      postal_code: \"11119\"\n      country: \"Lithuania\"\n      country_code: \"LT\"\n      display: \"Dūmų gatvė 5, 11119 Vilnius, Lithuania\"\n    coordinates:\n      latitude: 54.6928956\n      longitude: 25.3988573\n    maps:\n      google: \"https://maps.google.com/?q=Dūmų+fabrikas,54.6928956,25.3988573\"\n      apple: \"https://maps.apple.com/?q=Dūmų+fabrikas&ll=54.6928956,25.3988573\"\n\n  - name: \"rePUBlic No.4\"\n    kind: \"GitButler Party\"\n    address:\n      street: \"27 Vilniaus gatvė\"\n      city: \"Vilnius\"\n      region: \"Vilniaus apskritis\"\n      postal_code: \"01402\"\n      country: \"Lithuania\"\n      country_code: \"LT\"\n      display: \"Vilniaus g. 27, 01402 Vilnius, Lithuania\"\n    coordinates:\n      latitude: 54.6847266\n      longitude: 25.2793018\n    maps:\n      google: \"https://maps.google.com/?q=rePUBlic+No.4,54.6847266,25.2793018\"\n      apple: \"https://maps.apple.com/?q=rePUBlic+No.4&ll=54.6847266,25.2793018\"\n"
  },
  {
    "path": "data/euruko/euruko-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"steven-baker-euruko-2023\"\n  title: \"Keynote: Reflections on a Reluctant Revolution\"\n  raw_title: \"STEVEN R. BAKER, KEYNOTE, “Reflections on a Reluctant Revolution”\"\n  speakers:\n    - Steven Baker\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Olc0qbSyJQw\"\n\n- id: \"carla-urrea-stabile-euruko-2023\"\n  title: \"No Passwords, No Problems: Move Beyond Passwords With Web Authn And Passkeys\"\n  raw_title: \"CARLA URREA STABILE, “No passwords, no problems: Move beyond passwords with WebAuthn and passkeys”\"\n  speakers:\n    - Carla Urrea Stabile\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Dxmc2maYsA4\"\n\n- id: \"hiroshi-shibata-euruko-2023\"\n  title: \"How resolve Gem dependencies in your code?\"\n  raw_title: \"HIROSHI SHIBATA, “How resolve Gem dependencies in your code?”\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"LbDn5PKLkgc\"\n\n- id: \"hitoshi-hasumi-euruko-2023\"\n  title: \"A Beginner's Complete Guide to Microcontroller Programming\"\n  raw_title: \"HITOSHI HASUMI, “A Beginner's Complete Guide to Microcontroller Programming with Ruby”\"\n  speakers:\n    - Hitoshi Hasumi\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"WiJC_v5Lus8\"\n\n- id: \"adrian-marin-euruko-2023\"\n  title: \"Build Rails Apps 10x Faster\"\n  raw_title: 'Adrian Marin, \"BUILD RAILS APPS 10X FASTER\"'\n  speakers:\n    - Adrian Marin\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"28BcGUvyzQQ\"\n\n- id: \"alexander-nicholson-euruko-2023\"\n  title: \"Sinatra Is All You Need!\"\n  raw_title: 'Alexander Nicholson, \"SINATRA IS ALL YOU NEED!\"'\n  speakers:\n    - Alexander Nicholson\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"f3IL6C214TA\"\n\n- id: \"chikahiro-tokoro-euruko-2023\"\n  title: \"Generate Anonymised Databases with MasKING\"\n  raw_title: 'Chikahiro Tokoro, \"GENERATE ANONYMISED DATABASE WITH MASKING\"'\n  speakers:\n    - Chikahiro Tokoro\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"oml7dcDo_jo\"\n\n- id: \"johnny-shields-euruko-2023\"\n  title: \"Ruby Threads (And So Can You!)\"\n  raw_title: 'Johnny Shields, \"RUBY THREADS (AND SO CAN YOU!)\"'\n  speakers:\n    - Johnny Shields\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"HLTJJh8EHdU\"\n\n- id: \"yukihiro-matz-matsumoto-euruko-2023\"\n  title: \"Keynote: In defence of GVL\"\n  raw_title: 'YUKIHIRO \"MATZ\" MATSUMOTO, KEYNOTE, \"In defence of GVL\"'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"On4YAsghWM0\"\n\n- id: \"scott-chacon-euruko-2023\"\n  title: \"Ask Your Code\"\n  raw_title: \"SCOTT CHACON, “Ask Your Code”\"\n  speakers:\n    - Scott Chacon\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"OOYdS4Nw3Ek\"\n\n- id: \"ivo-anjo-euruko-2023\"\n  title: \"Look out! Gotchas of Using Threads in Ruby\"\n  raw_title: \"IVO ANJO, “Look out! Gotchas of Using Threads in Ruby”\"\n  speakers:\n    - Ivo Anjo\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"B8f8-UhgQkQ\"\n\n- id: \"okura-masafumi-euruko-2023\"\n  title: \"Reading RSpec — a journey of meta programming\"\n  raw_title: \"MASAFUMI OKURA, “Reading RSpec — a journey of meta programming”\"\n  speakers:\n    - OKURA Masafumi\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Gk5n9lQGFG8\"\n\n- id: \"daniel-susveila-euruko-2023\"\n  title: \"Steven, Just let_it_be. A Guide To Improve Your RSpec Performance\"\n  raw_title: 'Daniel Susveila. \"STEVEN, JUST LET_IT_BE. A GUIDE TO IMPROVE YOUR RSPEC PERFORMANCE\"'\n  speakers:\n    - Daniel Susveila\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"AIh0fbA28GI\"\n\n- id: \"cristian-planas-euruko-2023\"\n  title: \"A Rails Performance Guidebook: from 0 to 1B requests/day\"\n  raw_title: 'Cristian Planas, \"A RAILS PERFORMANCE GUIDEBOOK\"'\n  speakers:\n    - Cristian Planas\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"fP96dmzoPT4\"\n\n- id: \"chris-hasinski-euruko-2023\"\n  title: \"Fantastic Databases And Where To Find Them\"\n  raw_title: 'Chris Hasinski, \"FANTASTIC DATABASES AND WHERE TO FIND THEM\"'\n  speakers:\n    - Chris Hasinski\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"-Lwaaj5Zimk\"\n\n- id: \"miron-marczuk-euruko-2023\"\n  title: \"How To Safely Split Your Multi Tenant Application\"\n  raw_title: 'Miron Marczuk, \"HOW TO SAFELY SPLIT YOUR MULTI-TENANT APPLICATION (BASED ON REAL EXAMPLES!)\"'\n  speakers:\n    - Miron Marczuk\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5BRtOBUeObM\"\n\n- id: \"hana-harencarova-euruko-2023\"\n  title: \"Keynote: Seamless Releases with Feature Flags: Insights from GitHub's Experience\"\n  raw_title: \"HANA HARENCAROVA, KEYNOTE, “Seamless Releases with Feature Flags: Insights from GitHub's Experience”\"\n  speakers:\n    - Hana Harencarova\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"79LN5Sn4Nac\"\n\n- id: \"james-bell-euruko-2023\"\n  title: \"Panel: 30 years of Ruby\"\n  raw_title: 'Panel discussion \"30 years of Ruby\"'\n  speakers:\n    - James Bell\n    - Yukihiro \"Matz\" Matsumoto\n    - Steven Baker\n    - Carla Urrea Stabile\n    - Hana Harencarova\n    - Hiroshi Shibata\n\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"lK9vzms1ENI\"\n\n- id: \"matias-korhonen-euruko-2023\"\n  title: \"Doing terrible things with ruby.wasm\"\n  raw_title: \"MATIAS KORHONEN, “Doing terrible things with ruby.wasm”\"\n  speakers:\n    - Matias Korhonen\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Z_zcTt8q5PQ\"\n\n- id: \"tom-de-bruijn-euruko-2023\"\n  title: \"Crafting elegant code with Ruby DSLs\"\n  raw_title: \"TOM DE BRUIJN, “Crafting elegant code with Ruby DSLs”\"\n  speakers:\n    - Tom de Bruijn\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"9fzMs_CEzrA\"\n\n- id: \"unconference-pitches-day-1-euruko-2023\"\n  title: \"Unconference Pitches (Day 1)\"\n  raw_title: \"Unconference pitches\"\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"J7oargktOEw\"\n  talks:\n    - title: \"Unconference Pitch: Josua Schmid\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"josua-schmid-unconference-pitch-euruko-2023\"\n      video_id: \"josua-schmid-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Josua Schmid\n\n    - title: \"Unconference Pitch: Frederick Cheung\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"frederick-cheung-unconference-pitch-euruko-2023\"\n      video_id: \"frederick-cheung-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Frederick Cheung\n\n    - title: \"Unconference Pitch: Andy\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"andy-unconference-pitch-euruko-2023\"\n      video_id: \"andy-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Andy # TODO: missing last name\n\n    - title: \"Unconference Pitch: Andres\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"andres-unconference-pitch-euruko-2023\"\n      video_id: \"andres-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Andres # TODO: missing last name\n\n    - title: \"Unconference Pitch: Michał Łęcicki\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-lecicki-unconference-pitch-euruko-2023\"\n      video_id: \"michal-lecicki-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Łęcicki\n\n    - title: \"Unconference Pitch: Giorgio Fochesato\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"giorgio-fochesato-unconference-pitch-euruko-2023\"\n      video_id: \"giorgio-fochesato-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Giorgio Fochesato\n\n    - title: \"Unconference Pitch: Chikahiro Tokoro\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"chikahiro-tokoro-unconference-pitch-euruko-2023\"\n      video_id: \"chikahiro-tokoro-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Chikahiro Tokoro\n\n    - title: \"Unconference Pitch: Alexander Nicholson\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"alexander-nicholson-unconference-pitch-euruko-2023\"\n      video_id: \"alexander-nicholson-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Alexander Nicholson\n\n    - title: \"Unconference Pitch: Paweł Strzałkowski\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pawel-strzalkowski-unconference-pitch-euruko-2023\"\n      video_id: \"pawel-strzalkowski-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Paweł Strzałkowski\n\n    - title: \"Unconference Pitch: Johnny Shields\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"johnny-shields-unconference-pitch-euruko-2023\"\n      video_id: \"johnny-shields-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Johnny Shields\n\n    - title: \"Unconference Pitch: Alekander\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"alekander-unconference-pitch-euruko-2023\"\n      video_id: \"alekander-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Alekander # TODO: missing last name\n\n    - title: \"Unconference Pitch: Mariusz Kozieł\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"mariusz-koziel-unconference-pitch-euruko-2023\"\n      video_id: \"mariusz-koziel-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Mariusz Kozieł\n\n    - title: \"Unconference Pitch: Adrian Marin\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"adrian-marin-unconference-pitch-euruko-2023\"\n      video_id: \"adrian-marin-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Adrian Marin\n\n    - title: \"Unconference Pitch: Yaroslav Shmarov\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"yaroslav-shmarov-unconference-pitch-euruko-2023\"\n      video_id: \"yaroslav-shmarov-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Yaroslav Shmarov\n\n- id: \"unconference-pitches-day-2-euruko-2023\"\n  title: \"Unconference Pitches (Day 2)\"\n  raw_title: \"Unconference pitches\"\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"t6_uvjX25Jk\"\n  talks:\n    - title: \"Unconference Pitch: Daniel\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"daniel-unconference-pitch-euruko-2023\"\n      video_id: \"daniel-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Daniel # TODO: missing last name\n\n    - title: \"Unconference Pitch: Daniel Susveila\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"daniel-susveila-unconference-pitch-euruko-2023\"\n      video_id: \"daniel-susveila-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Daniel Susveila\n\n    - title: \"Unconference Pitch: Cristian Planas\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"cristian-planas-unconference-pitch-euruko-2023\"\n      video_id: \"cristian-planas-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Cristian Planas\n\n    - title: \"Unconference Pitch: Andres\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"andres-unconference-pitch-euruko-2023-unconference-pitch-andres\"\n      video_id: \"andres-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Andres # TODO: missing last name\n\n    - title: \"Unconference Pitch: Youssef Boulkaid\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"youssef-boulkaid-unconference-pitch-euruko-2023\"\n      video_id: \"youssef-boulkaid-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Youssef Boulkaid\n\n    - title: \"Unconference Pitch: Josua Schmid\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"josua-schmid-unconference-pitch-euruko-2023-unconference-pitch-josua-schmi\"\n      video_id: \"josua-schmid-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Josua Schmid\n\n    - title: \"Unconference Pitch: OKURA Masafumi\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"masafumi-okura-unconference-pitch-euruko-2023\"\n      video_id: \"masafumi-okura-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - OKURA Masafumi\n\n    - title: \"Unconference Pitch: Miron Marczuk\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"miron-marczuk-unconference-pitch-euruko-2023\"\n      video_id: \"miron-marczuk-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Miron Marczuk\n\n    - title: \"Unconference Pitch: Chris Hasiński\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"chris-hasinski-unconference-pitch-euruko-2023\"\n      video_id: \"chris-hasinski-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Hasiński\n\n    - title: \"Unconference Pitch: Yakau\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"yakau-unconference-pitch-euruko-2023\"\n      video_id: \"yakau-unconference-pitch-euruko-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Yakau # TODO: missing last name\n\n- id: \"mariusz-kozie-euruko-2023\"\n  title: \"City Pitch: Warsaw\"\n  raw_title: \"City Pitching. Warsaw\"\n  speakers:\n    - Mariusz Kozieł\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zmRS3Q-t4pc\"\n\n- id: \"muhamed-isabegovi-euruko-2023\"\n  title: \"City Pitch: Tuzla\"\n  raw_title: \"City pitching. Bosnia\"\n  speakers:\n    - Muhamed Isabegović\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DJWyvVnvyRw\"\n\n- id: \"todo-euruko-2023\"\n  title: \"City Pitch: Kyiv\"\n  raw_title: \"City pitch. Kyiv\"\n  speakers:\n    - TODO\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"PcRbFElb18c\"\n\n- id: \"todo-euruko-2023-city-pitch-copenhagen\"\n  title: \"City Pitch: Copenhagen\"\n  raw_title: \"City pitching. Copenhagen\"\n  speakers:\n    - TODO\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"j2zOBQkY4XM\"\n\n- id: \"frederick-cheung-euruko-2023\"\n  title: \"City Pitch: Manchester\"\n  raw_title: \"City pitching. Manchester\"\n  speakers:\n    - Frederick Cheung\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"re1N1ZQ5CSQ\"\n\n- id: \"matias-korhonen-euruko-2023-city-pitch-helsinki\"\n  title: \"City Pitch: Helsinki\"\n  raw_title: \"City pitching. Helsinki\"\n  speakers:\n    - Matias Korhonen\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"syRtJsFdTvI\"\n\n- id: \"giorgio-fochesato-euruko-2023\"\n  title: \"City Pitch: Verona\"\n  raw_title: \"City Pitching. Verona\"\n  speakers:\n    - Giorgio Fochesato\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"usrc27rytMk\"\n\n- id: \"sergy-sergyenko-euruko-2023\"\n  title: \"Winner Ceremony\"\n  raw_title: \"Euruko 2023. Winner Ceremony\"\n  speakers:\n    - Sergy Sergyenko\n    - Muhamed Isabegović\n  event_name: \"EuRuKo 2023\"\n  date: \"2023-09-21\"\n  published_at: \"2023-10-04\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"IlaLqll1rZA\"\n"
  },
  {
    "path": "data/euruko/euruko-2024/event.yml",
    "content": "---\nid: \"euruko-2024\"\ntitle: \"EuRuKo 2024\"\nkind: \"conference\"\nlocation: \"Sarajevo, Bosnia and Herzegovina\"\ndescription: \"\"\npublished_at: \"2025-01-13\"\nstart_date: \"2024-09-11\"\nend_date: \"2024-09-13\"\nchannel_id: \"UCgXsZr2e0AgUJMZm5t03WVw\"\nyear: 2024\nbanner_background: \"linear-gradient(to top, #E61F1F 4%, #031B23 4%)\"\nfeatured_background: \"#031B23\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2024.euruko.org\"\ncoordinates:\n  latitude: 43.826422\n  longitude: 18.31242\n"
  },
  {
    "path": "data/euruko/euruko-2024/involvements.yml",
    "content": "---\n- name: \"Chief Organizer\"\n  users:\n    - Muhamed Isabegović\n\n- name: \"Organizer\"\n  users:\n    - René Schade\n\n- name: \"Organization & Venue Coordinator\"\n  users:\n    - Emir Vatrić\n    - Damir Zekić\n\n- name: \"Organization & Sponsor Manager\"\n  users:\n    - Zlatko Alomerović\n    - Mustafa Duranović\n    - Ena Dzemila\n    - Alessandro Brückheimer\n\n- name: \"Speakers & Program Coordinator\"\n  users:\n    - Christoph Lipautz\n    - Damir Zekić\n\n- name: \"Designer\"\n  users:\n    - Denis Stankić\n    - Zehra Bučo\n    - Midhet Mujkanović\n    - Emina Škaljić\n    - Amila Mašović\n\n- name: \"Website Developer\"\n  users:\n    - Enes Smajić\n\n- name: \"Review Committee Member\"\n  users:\n    - Adrian Marin\n    # TODO: add all Review Committee Members\n"
  },
  {
    "path": "data/euruko/euruko-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Meister\"\n          website: \"https://www.meisterlabs.com/\"\n          slug: \"Meister\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/meister_light.png\"\n\n    - name: \"Gold\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"CloudAMQP\"\n          website: \"https://www.cloudamqp.com/\"\n          slug: \"CloudAMQP\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/cloudamqp-light.svg\"\n\n    - name: \"Silver\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"AppSignal\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/appsignal.png\"\n\n        - name: \"ViaEurope\"\n          website: \"https://www.viaeurope.com/\"\n          slug: \"ViaEurope\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/viaeurope-logo.png\"\n\n        - name: \"seQura\"\n          website: \"https://www.sequra.com/en\"\n          slug: \"seQura\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/sequra-logo.png\"\n\n    - name: \"Bronze Online\"\n      description: \"\"\n      level: 4\n      sponsors:\n        - name: \"WizardHealth\"\n          website: \"https://www.wizardhealth.co/?lang=en\"\n          slug: \"WizardHealth\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/wizardhealth.png\"\n\n        - name: \"Welaika\"\n          website: \"https://welaika.com/\"\n          slug: \"Welaika\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/logoWelaika.png\"\n\n        - name: \"Happy Scribe\"\n          website: \"https://www.happyscribe.com/\"\n          slug: \"HappyScribe\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/happyscribe.png\"\n\n        - name: \"Ministry of Programming\"\n          website: \"https://www.ministryofprogramming.com/\"\n          slug: \"MinistryofProgramming\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/ministryofprogramming-white.png\"\n\n    - name: \"Travel\"\n      description: \"\"\n      level: 5\n      sponsors:\n        - name: \"Evil Martians\"\n          website: \"https://evilmartians.com/\"\n          slug: \"EvilMartians\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/evilmartians.png\"\n\n        - name: \"Avo\"\n          website: \"https://avohq.io/rails-admin\"\n          slug: \"Avo\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/avo-logo.png\"\n\n        - name: \"Zendesk\"\n          website: \"https://www.zendesk.com/\"\n          slug: \"zendesk\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/zendesk.png\"\n\n        - name: \"prevail\"\n          website: \"https://prevail.ai/\"\n          slug: \"prevail\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/prevail-logo-white.png\"\n\n        - name: \"Culture Amp\"\n          website: \"https://www.cultureamp.com/\"\n          slug: \"cultureamp\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/cultureamp.png\"\n\n        - name: \"Olympia\"\n          website: \"https://olympia.chat/\"\n          slug: \"olympia\"\n          logo_url: \"https://2024.euruko.org/assets/images/sponsors/olympia-chat.png\"\n"
  },
  {
    "path": "data/euruko/euruko-2024/venue.yml",
    "content": "---\nname: \"Hotel Hills Sarajevo Congress & Termal Spa Resort\"\n\naddress:\n  street: \"Butmirska cesta 18\"\n  city: \"Ilidža, Sarajevo\"\n  postal_code: \"71000\"\n  country: \"Bosnia & Herzegovina\"\n  country_code: \"BA\"\n  display: \"Butmirska cesta 18, Ilidža, Sarajevo 71000, Bosnia & Herzegovina\"\n\ncoordinates:\n  latitude: 43.826422\n  longitude: 18.312420\n\nmaps:\n  google: \"https://maps.app.goo.gl/KUQttP8uMVG31kep9\"\n  apple:\n    \"https://maps.apple.com/place?address=Butmirska%20cesta%2018,%2071210%20Ilid%C5%BEa,%20Bosnia%20and%20Herzegovina&coordinate=43.827090,18.312193&name=Congress%20Center%20Ho\\\n    tel%20Hills&place-id=IDB60857BE737A8B7&map=transit\"\n  openstreetmap: \"https://www.openstreetmap.org/?#map=19/43.826422/18.312420\"\n\nhotels:\n  - name: \"Hotel Hills Sarajevo Congress & Termal Spa Resort\"\n    kind: \"Speaker Hotel\"\n    address:\n      street: \"18 Butmirska cesta\"\n      city: \"Ilidža\"\n      region: \"Federacija Bosne i Hercegovine\"\n      country: \"Bosnia and Herzegovina\"\n      country_code: \"BA\"\n      display: \"Butmirska cesta 18, Ilidža, Sarajevo 71000, Bosnia & Herzegovina\"\n    description: |-\n      Conference venue hotel\n    coordinates:\n      latitude: 43.8269694\n      longitude: 18.3135424\n    maps:\n      google: \"https://maps.app.goo.gl/QmPDxD8Yq27oLVUDA\"\n\n  - name: \"Hollywood Hotel\"\n    kind: \"Speaker Hotel\"\n    address:\n      street: \"23 Dr. Mustafe Pintola\"\n      city: \"Ilidža\"\n      region: \"Federacija Bosne i Hercegovine\"\n      country: \"Bosnia and Herzegovina\"\n      country_code: \"BA\"\n      display: \"Dr. Mustafe Pintola 23, Ilidža 71210, Bosnia & Herzegovina\"\n    coordinates:\n      latitude: 43.8291098\n      longitude: 18.3092244\n    maps:\n      google: \"https://maps.app.goo.gl/dicCnuaRvhn1y6z17\"\n"
  },
  {
    "path": "data/euruko/euruko-2024/videos.yml",
    "content": "---\n# Website: https://2024.euruko.org\n# Schedule: https://2024.euruko.org/#agenda\n# Repo: https://github.com/euruko/2024.euruko.org\n\n# REGISTRATION\n\n# - title: MC welcomes the audience\n#   raw_title: MC welcomes the audience\n#   event_name: EuRuKo 2024\n#   date: '2024-09-11'\n#   time: '09:40 - 10:00'\n#   track: Main Track\n#   speakers:\n#     - Carmen Huidobro\n#   description: Carmen will take on the role of our MC for the event.\n\n- id: \"xavier-noria-euruko-2024\"\n  title: \"Opening Keynote: Zeitwerk: A Retrospective\"\n  raw_title: \"Opening Keynote: Zeitwerk: A Retrospective\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"10:00 - 10:50\"\n  track: \"Main Track\"\n  speakers:\n    - Xavier Noria\n  description: |-\n    Last month marked the 5th anniversary of Rails 6, the first Rails version to ship with Zeitwerk. In this talk, we'll do a retrospective about the Zeitwerk project. We are going to understand its motivations, technical details, milestones, API design, and other topics.\n  video_id: \"sUhElM03QB4\"\n  video_provider: \"youtube\"\n\n- id: \"jean-boussier-euruko-2024\"\n  title: \"A Decade of Rails Bug Fixes\"\n  raw_title: \"A Decade of Rails Bug Fixes\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"11:00 - 11:30\"\n  track: \"Main Track\"\n  speakers:\n    - Jean Boussier\n  description: \"\"\n  video_id: \"VbIu0U9StGU\"\n  video_provider: \"youtube\"\n\n- id: \"ivan-nemytchenko-euruko-2024\"\n  title: \"The Curse of Service Objects\"\n  raw_title: \"The Curse of Service Objects\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"11:00 - 11:30\"\n  track: \"Second Track\"\n  speakers:\n    - Ivan Nemytchenko\n  description: |-\n    Service Objects were a mistake. It has nothing to do with OOP. It has little to do with ideas of Fowler, Evans and Martin. I analyzed a plenty of open repositories, videos and articles, and in this talk I will show all the flaws of this “pattern”, and how it contributes to complexity management.\n\n    Service Objects is most widely accepted practice in the Ruby community. Yet, I insist, it is very controversial “pattern”, and in some cases hurtful. In most cases it opposes the idea of Single Responsibility Proinciple, kills the idea of Layered Architecture and makes our code non-modular.\n\n    In my talk I will analyze the idea of Service Objects from four different perspec- tives: 1. Idea of OOP 2. Practice (analysis of articles videos about Service Objects) 3. Philosophy (how it matches the ideas of Evans, Fowler and Martin) 4. Its effect on complexity distribution in dynamics (based on code of GitLab and Discourse)\n\n    My goal is to shake your beliefs by exposing issues of the “pattern”, show where we took a wrong turn, and show how ideas of Service Layer (Fowler) and Domain Services (Evans) can be implemented in Rails without all the problems of commonly used pattern.\n  video_id: \"CPpcB_GPH2E\"\n  video_provider: \"youtube\"\n\n- id: \"igor-morozov-euruko-2024\"\n  title: \"Benefits and challenges of introducing a strict Content Security Policy\"\n  raw_title: \"Benefits and challenges of introducing a strict Content Security Policy\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"11:00 - 11:30\"\n  track: \"Third Track\"\n  speakers:\n    - Igor Morozov\n  description: |-\n    Content Security Policy is kind of getting hot right now. I myself felt like it was a niche technology, just an extra layer of security against XSS. Security experts think otherwise, and they're now asking for CSP during audits. So, let's take a look at that from the developer's standpoint\n\n    Content Security Policy is a web standard and browser mechanism that improves our security against multiple attacks, specifically XSS and data injection. It's pretty widespread: it has made its way into Ruby's major tools such as Rails, Hanami, Roda, and Bullet. Basically, if a gem adds script tags to the page – it'll probably have to deal with CSP one way or another.\n\n    However, introducing an extra level of security brings its own challenges and limitations. How do we decide on the level of security we want? How do we limit the impact on developers? How do we safely roll out the changes? HOW do we work with static pages? Lots of general questions and a lot of more specific ones.\n\n    We'll talk about the principles and specifics of introducing CSP into existing systems. We'll tap into community wisdom and share ways to overcome technical challenges that people had to grind through, making our own experience as pain-free as possible.\n\n    GitHub Repo: https://github.com/Morozzzko/EuRuKo-CSP-Demo\n  video_id: \"fA76Pny03u4\"\n  video_provider: \"youtube\"\n  additional_resources:\n    - name: \"Morozzzko/EuRuKo-CSP-Demo\"\n      type: \"repo\"\n      url: \"https://github.com/Morozzzko/EuRuKo-CSP-Demo\"\n\n- id: \"piotr-szotkowski-euruko-2024\"\n  title: \"Simplify, Then Add Lightness\"\n  raw_title: \"Simplify, Then Add Lightness\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"11:40 - 12:10\"\n  track: \"Main Track\"\n  speakers:\n    - Piotr Szotkowski\n  description: |-\n    With ZIRP behind us smaller teams often need to deliver leaner solutions – and projects like LiteStack are there to help. Meanwhile even the smallest dependencies keep getting new features (and Ruby keeps getting significantly more performant) – so let's see how to keep the stack simple and cutting-edge.\n\n    Let's take a look at how simple modern stacks can be – from sending HTML snippets over WebSocket to operating job queues in SQLite. Full-stack development in Ruby means quicker turn-around and simpler deploys – and paired with a well-thought-out approach to keeping all the dependencies fresh, the maintenance part of our life can be both much easier and actually enjoyable.\n\n    This talk covers the current shift in web development reality and the trend towards a (most welcome) simplification of the tools we work with. The experience with running multiple codebases (including the biggest Ruby monolith) on the most recent version of Ruby and Rails' main branch shows this, too, is actually doable.\n  video_id: \"cfdxpPQ7KDE\"\n  video_provider: \"youtube\"\n  slides_url: \"https://talks.chastell.net/euruko-2024\"\n\n- id: \"guilherme-carreiro-euruko-2024\"\n  title: \"Building native Ruby extensions in Rust\"\n  raw_title: \"Building native Ruby extensions in Rust\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"11:40 - 12:10\"\n  track: \"Second Track\"\n  speakers:\n    - Guilherme Carreiro\n  description: |-\n    2024 is such a great time to be a Ruby developer! The language is improving with initiatives like YJIT, enhanced GC, and Prism.\n\n    Even when we face language boundaries, we no longer need to default to C. Extending our gems using the modern and fast tooling provided by the Rust ecosystem is easier than ever.\n\n    In this talk, I will share my journey at Shopify in creating a Ruby gem with a Rust native extension, discuss the advantages, challenges, good practices, and how to avoid common pitfalls.\n  video_id: \"2kM4me8QNHc\"\n  video_provider: \"youtube\"\n\n- id: \"erica-weistrand-euruko-2024\"\n  title: \"Ruby off Rails\"\n  raw_title: \"Ruby off Rails\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"11:40 - 12:10\"\n  track: \"Third Track\"\n  speakers:\n    - Erica Weistrand\n  description: |-\n    In the Ruby landscape, Rails has become the primary approach for web development and you get a lot of configuration and features for free when using Rails. In this talk, we'll delve into the world of Rails, have a quick look at Hanami and then discuss how we navigate the challenges of building web apps with Sinatra at 84codes. We'll also share what we learned from Rails and Hanami and how we tried to get the best out of all worlds by implementing some of those learnings in our own web apps.\n  video_id: \"TnqFTNcIZrs\"\n  video_provider: \"youtube\"\n\n- id: \"victor-shepelev-euruko-2024\"\n  title: \"Seven things I know after 25 years of development\"\n  raw_title: \"Seven things I know after 25 years of development\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"12:20 - 13:00\"\n  track: \"Main Track\"\n  speakers:\n    - Victor Shepelev\n  description: |\n    Through years of career, every developer dedicated to their craft gathers their own set of beliefs, opinions, and habits. Some of them are just reinforcing the common wisdom, some might be quite peculiar; some become irrelevant with time, some only grow stronger; some are about big and important things, and some might be considered nitpicks.\n\n    Let me share some of mine—without promising them to be universal or even extremely useful, but with a promise of interesting stories and choices behind them.\n  video_id: \"r9EQjBPU474\"\n  video_provider: \"youtube\"\n\n# LUNCH BREAK\n\n- id: \"julik-tarkhanov-euruko-2024\"\n  title: \"On the benefits of slot scheduling\"\n  raw_title: \"On the benefits of slot scheduling\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"14:00 - 14:30\"\n  track: \"Main Track\"\n  speakers:\n    - Julik Tarkhanov\n  description: |-\n    Ensuring smooth operation for thousands of users with regular workloads is hard. Using slot scheduling can help you make your workload and throughput more predictable and your users happy. Slot scheduling is a great medicine to alleviate load spikes on your background jobs cluster.\n\n    The traditional way of performing tasks for multiple users in the system is to schedule them using cron or similar. The issue however, is that scheduling “all the work for all the users” into one time slot will create a large load spike. This is bad for your shared services - the DB, Redis, APIs you call into - but also bad for your wallet, as you will need to suddenly scale your system by a factor when the time comes to run those jobs. In our company we need to run sync jobs to external APIs for every user - tens of thousands of users, and we want those jobs to run with predictable frequency. While we previously selected “least-recently-synced” workloads first, this came with the load spikes and all the accompanying issues.\n\n    Slot scheduling tackles the problem differently. It computes a modulo over the workload owner ID (like the user ID) and then buckets the user into one of a fixed number of slots. This allows us to run an approximately even number of tasks at any given point in time, providing for a near-flat throughput. It is better for the shared services, better for the queue - as jobs get portioned into the job queue in smaller batches, and do not stick around for long - and better for autoscaling, as there is much less of it needed.\n\n    We are also going to discuss a very viable strategy for designing systems like this - discrete simulations, which - when applied properly - can save hours of testing.\n  video_id: \"q_EbeIaH0xw\"\n  video_provider: \"youtube\"\n\n- id: \"dmitry-pogrebnoy-euruko-2024\"\n  title: \"Demystifying Debugger\"\n  raw_title: \"Demystifying Debugger\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"14:00 - 14:30\"\n  track: \"Second Track\"\n  speakers:\n    - Dmitry Pogrebnoy\n  description: |-\n    Know the tool you are using! Maximize your debugger knowledge with our in-depth talk! Gain vital insights of Byebug, debug gem and RubyMine Debugger. Uncover the secrets of Ruby debugger internals. This talk will equip you with advanced understanding of how ruby debuggers work and provide you useful insights of how RubyMine Debugger can accelerate your debugging process.\n\n    Expert-led talk, “Demystifying Debugger”, offers a sophisticated exploration into the labyrinths of advanced debugging tools at the disposal of Ruby developers. Elevate your debugging from a routine task to an expert skill.\n  video_id: \"9jjQIrunl00\"\n  video_provider: \"youtube\"\n\n- id: \"riccardo-carlesso-andrei-bondarev-euruko-2024\"\n  title: \"Workshop: Bring your Ruby app in the Cloud\"\n  raw_title: \"Workshop: Bring your Ruby app in the Cloud\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  time: \"14:00 - 15:50\"\n  track: \"Third Track\"\n  speakers:\n    - Riccardo Carlesso\n    - Andrei Bondarev\n  description: |-\n    In this ~2 hours workshop, Riccardo and Andrei (Langchain.rb creator) will give you the resources to run three different labs according to your tastes and assist you whenever you're blocked. The idea is to build something simple and fast so you can go home and tweak it to make your next startup.\n\n    [30m] Codelab:Gemini to accelerate test driven development. In this codelab, you'll learn how to use AI to help you create a small Calculator application starting from tests (Test-driven development), and then push it's functionality to the Cloud.\n\n    [60m] [Codelab] Using Ruby on Rails + PostgreSQL on Cloud Run. In this Lab, you will learn to take an existing Ruby on Rails application and deploy it to Google Cloud, instantiating a Database, dockerizing the app and running the dockerized app on Cloud run, and managing Secrets like a pro.\n\n    [15m] Build an AI agent in 15 min Langchain.rb. In this Lab, you will learn how to build an AI agent utilizing the latest Function Calling functionality. You'll build your own functions/tools and program an assistant to interact with final user in an engaging conversation which calls smart functions under the hood (weather, news, stocks, DB, ..).\n  video_id: \"riccardo-carlesso-andrei-bondarev-euruko-2024\"\n  video_provider: \"not_recorded\"\n\n- id: \"karen-jex-euruko-2024\"\n  title: \"Optimising your database for analytics\"\n  raw_title: \"Optimising your database for analytics\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"14:40 - 15:10\"\n  track: \"Main Track\"\n  speakers:\n    - Karen Jex\n  description: |-\n    Your database is configured for the needs of your day-to-day application activity, but what if you need to run complex analytics queries against your application data? Let's look at how you can optimise your database for an analytics workload without compromising the performance of your application.\n\n    Data analytics still isn't always done in a dedicated analytics database. The business wants to glean insights and value from the data that's generated over time by your OLTP applications, and the simplest way to do that is often just to run analytics queries directly on your application database.\n\n    Of course, this almost certainly involves running complex queries, joining data from multiple tables, and working on large data sets. If your database and code are optimised for performance of your day-to-day application activity, you're likely to slow down your application and find yourself with analytics queries that take far too long to run.\n\n    In this talk, we'll discuss the challenges associated with running data analytics on an existing application database. We'll look at some of the impacts this type of workload could have on the application, and why it could cause the analytics queries themselves to perform poorly.\n\n    We'll then look at a number of different strategies, tools and techniques that can prevent the two workloads from impacting each other. We will look at things such as architecture choices, configuration parameters, materialized views and external tools.\n\n    The focus will be on PostgreSQL, but most of the concepts are relevant to other database systems.\n  video_id: \"Vrf1emGGKVQ\"\n  video_provider: \"youtube\"\n\n- id: \"tim-kchele-euruko-2024\"\n  title: \"Mechanical sympathy, or: writing fast ruby programs\"\n  raw_title: \"Mechanical sympathy, or: writing fast ruby programs\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"14:40 - 15:10\"\n  track: \"Second Track\"\n  speakers:\n    - Tim Kächele\n  description: |-\n    Premature optimization is the root of all evil, that's what you hear whenever someone wants to optimize something, let's break with conventions. Let's learn about the limits of modern computers, how they apply to ruby and how we can use our knowledge to write faster ruby programs.\n\n    Ruby is a magical language and it's easy to forget that at the end of the day an actual CPU is running your program, but knowing a bit about CPUs and how they work can help you speed up your programs tremendously.\n\n    In this talk we are going to look at the physical limits of modern computing and how we can apply this knowledge to write fast ruby programs.\n  video_id: \"wCOuJB6MEQo\"\n  video_provider: \"youtube\"\n\n- id: \"igor-jancev-euruko-2024\"\n  title: \"Patterns and solutions distilled from 10 years development and maintenance of a big campus software ruby on rails application\"\n  raw_title: \"Patterns and solutions distilled from 10 years development and maintenance of a big campus software ruby on rails application\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"15:20 - 15:50\"\n  track: \"Main Track\"\n  speakers:\n    - Igor Jancev\n  description: |-\n    Did you know that the campus software of the Technical University in Vienna is powered by a >380.000 LOC Ruby on Rails application that was started in 2011?A senior Ruby developer from the team shares patterns and solutions distilled from 10 years of development, maintenance and upgrades.\n\n    We all know Ruby and Rails are great tools for startups and fast development of new applications. But did you know that the campus software of the Technical University in Vienna is powered by a >380.000 LOC Ruby on Rails application that was started in 2011 and is actively developed and maintained by a small, dedicated team of Ruby developers ever since?\n\n    A senior Ruby developer from this team shares patterns and solutions distilled from more than 10 years of his work on this project, for example how the team gradually migrated the Rails application from Rails 2.3 to Rails 6.1 and Hotwire Turbo, how a big amount of data is kept in sync between the rails applications and many other applications at the university, how to make big changes to the code base without upsetting all users, and much more.\n  video_id: \"XrsmP6FmDo0\"\n  video_provider: \"youtube\"\n\n- id: \"marko-ilimkovi-euruko-2024\"\n  title: \"Lessons From Escaping the Dependency Upgrade Maze\"\n  raw_title: \"Lessons From Escaping the Dependency Upgrade Maze\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"15:20 - 15:50\"\n  track: \"Second Track\"\n  speakers:\n    - Marko Ćilimković\n  description: |-\n    Open-source dependencies are double-edged swords: convenient when applying, but dangerous if left unattended.\n\n    In the last couple of years, we've performed maintenance of 20+ apps with severely outdated dependencies, and it's safe to say we've learnt a few lessons along the 500 hours we put into it.\n\n    Join the talk to learn:\n\n      * the fresh approach to updating dependencies that will help you stay ahead of the curve\n      * what does one team have to do in order to keep a healthy app ecosystem\n      * and how to pitch this investment to the clients.\n  video_id: \"fxAcn6bnmT0\"\n  video_provider: \"youtube\"\n\n# COFFEE BREAK\n\n- id: \"irina-nazarova-euruko-2024\"\n  title: \"Keynote: Evolution of real-time, AnyCable Pro and... me\"\n  raw_title: \"Keynote: Evolution of real-time and AnyCable Pro\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"16:30 - 17:20\"\n  track: \"Main Track\"\n  speakers:\n    - Irina Nazarova\n  description: |-\n    We started AnyCable Pro with a few Pro features on top of AnyCable, which was built as a performant replacement for Action Cable for Rails developers, and we needed to make it commercially successful for Evil Martians. So we focused on building what people wanted and saw their priorities shift from GraphQL to Hotwire, from chats to collaboration, and to AI-powered voice apps. With the initial value proposition in performance, we switched to solving data reliability in WebSockets, building session and data recovery, fallbacks and much more, to allow engineers to focus on their business logic, not the specific realtime issues. AnyCable became language and framework agnostic, with a much more simple initial setup and deploy. Finally we launched Managed AnyCable earlier this year. Let's reflect on our story three years in: what worked, what didn't, and our most precious learnings. And what does the future look like for AnyCable and realtime?\n\n    The talk will weave together two narratives: our experience building and growing AnyCable Pro, and the evolution of real-time applications as we've observed.\n\n    Part 1: AnyCable Pro Journey\n\n    Launching a Commercial Version: Strategies for introducing a commercial version of an open-source product while keeping it low-code, simple, and cost-effective. Telemetry and Insights: Setting up telemetry and using it to make informed decisions. Marketing Tactics: Using blog posts, case studies, newsletters, social media, and conference talks to promote the product. On-Premise Considerations: Key factors in making on-premise products user-friendly. Managed Service Launch: How to build an MVP of a managed service.\n\n    Part 2: Evolution of Real-Time Applications\n\n    Observing the shift from GraphQL to Hotwire, from chat apps to collaborative tools, and to AI-powered voice applications.\n\n    The talk will conclude with thoughts on the future of real-time applications and AnyCable.\n  slides_url: \"https://speakerdeck.com/irinanazarova/evolution-of-real-time-irina-nazarova-euruko-2024\"\n  video_id: \"JLirKGbwTVw\"\n  video_provider: \"youtube\"\n\n- id: \"irina-nazarova-euruko-2024-fireside-chat-open-source-busi\"\n  title: \"Fireside Chat: Open Source & Business\"\n  raw_title: \"Irina's fireside chat with Bartosz Blimke, Adrian Marin José Valim\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-11\"\n  published_at: \"2025-01-12\"\n  time: \"17:30 - 18:30\"\n  track: \"Main Track\"\n  speakers:\n    - Irina Nazarova\n    - Bartosz Blimke\n    - Adrian Marin\n    - José Valim\n  description: |-\n    Irina will host a panel discussion on the topic of Open Source & Business.\n\n    This session will close the second day of the conference.\n  video_id: \"Wi8qbd80-qg\"\n  video_provider: \"youtube\"\n\n# NETWORKING & SPA / PUB CRAWLING\n\n# - title: Good Morning and Agenda\n#   raw_title: Good Morning and Agenda\n#   event_name: EuRuKo 2024\n#   date: '2024-09-12'\n#   time: '09:40 - 10:00'\n#   track: Main Track\n#   speakers:\n#     - Carmen Huidobro\n#   description: ''\n\n- id: \"koichi-sasada-euruko-2024\"\n  title: \"Keynote: 20th years of YARV\"\n  raw_title: \"Keynote: 20th years of YARV\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-01-12\"\n  time: \"10:00 - 10:50\"\n  track: \"Main Track\"\n  speakers:\n    - Koichi Sasada\n  description: |-\n    YARV: Yet Another RubyVM was started in January 2004 to speed up the execution of Ruby, and YARV is still running in your Ruby today as the core of Ruby.\n\n    In this presentation, I will look back on 20 years of YARV and describe the good and bad points of YARV.\n  video_id: \"Z90ObH9zJCE\"\n  video_provider: \"youtube\"\n\n- id: \"yuta-saito-euruko-2024\"\n  title: \"What you can do with Ruby on WebAssembly\"\n  raw_title: \"What you can do with Ruby on WebAssembly\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-01-12\"\n  time: \"11:00 - 11:30\"\n  track: \"Main Track\"\n  speakers:\n    - Yuta Saito\n  description: \"\"\n  video_id: \"6i-7WRMEDi4\"\n  video_provider: \"youtube\"\n\n- id: \"marco-roth-euruko-2024\"\n  title: \"Leveling Up Developer Tooling For The Modern Rails & Hotwire Era\"\n  raw_title: \"Leveling Up Developer Tooling For The Modern Rails & Hotwire Era\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-01-12\"\n  time: \"11:00 - 11:30\"\n  track: \"Second Track\"\n  speakers:\n    - Marco Roth\n  description: |-\n    The evolution of developer experience (DX) tooling has been a game-changer in how we build, debug, and enhance web applications.\n\n    This talk aims to illuminate the path toward enriching the Ruby on Rails ecosystem with advanced DX tools, focusing on the implementation of Language Server Protocols (LSP) for Stimulus and Turbo.\n\n    Drawing inspiration from the rapid advancements in JavaScript tooling, we explore the horizon of possibilities for Rails developers, including how advanced browser extensions and tools specifically designed for the Hotwire ecosystem can level up your developer experience.\n  slides_url: \"https://speakerdeck.com/marcoroth/developer-tooling-for-the-modern-rails-and-hotwire-era-at-euruko-2024-sarajevo-bih\"\n  video_id: \"xdS0FkDGF48\"\n  video_provider: \"youtube\"\n\n- title: \"Workshop: Embedded Ruby Revolution: A Hands-On Workshop with PicoRuby\"\n  raw_title: \"Workshop: Embedded Ruby Revolution: A Hands-On Workshop with PicoRuby\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  time: \"11:00 - 13:00\"\n  track: \"Third Track\"\n  speakers:\n    - Hitoshi Hasumi\n  description: |-\n    As you might witness at EuRuKo 2023, PicoRuby is kind of a language-wide revolution, bridging the gap between the elegant Ruby language and the thrilling world of embedded systems programming. This workshop is designed specifically for Ruby beginners who have grasped the basics of the language and are eager to apply their knowledge in new, innovative ways.\n\n    The workshop will cover essential topics such as setting up your development environment, writing your first PicoRuby script, and interacting with hardware components like LEDs, sensors, and small displays. We aim to demystify the process of embedded programming and show how Ruby's syntax and libraries can be extended to physical computing.\n\n    This workshop is more than just learning; it's about joining a community of Ruby enthusiasts who are expanding the language's boundaries. Whether you aim to build smart home devices, or custom gadgets, or just gain a deeper understanding of how software can interact with hardware, this workshop will provide the knowledge, tools, and inspiration you need to start on that journey.\n  id: \"hitoshi-hasumi-euruko-2024\"\n  video_id: \"cFK_2FW7wRg\"\n  published_at: \"2025-06-02\"\n  video_provider: \"youtube\"\n\n- title: \"Concurrency in Ruby: Threads, Fibers, and Ractors Demistified\"\n  raw_title: \"Concurrency in Ruby: Threads, Fibers, and Ractors Demistified\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-02-23\"\n  time: \"11:40 - 12:10\"\n  track: \"Main Track\"\n  speakers:\n    - Magesh S\n  description: |-\n    Speed up your Ruby applications with the power of concurrency! Join us as we demystify threads, fibers, and Ractors, understanding their unique strengths, use cases, and impact on Ruby performance. Learn to tackle I/O bottlenecks and enable parallel execution, boosting your code’s speed.\n\n    For a very long time, Ruby had limited options for concurrency, mainly relying on threads, which developers often dreaded. However, with the exciting updates introduced in Ruby 3.0, the fiber scheduler and Ractors provided a remarkable 3x performance boost. Despite these advancements, few have used these features in production. But now, we can confidently say that they are ready for use.\n  id: \"magesh-s-euruko-2024\"\n  video_id: \"LVHiq_SbQOE\"\n  video_provider: \"youtube\"\n\n- id: \"yaroslav-shmarov-euruko-2024\"\n  title: \"Rails 8 Frontend: 10 commandments and 7 deadly sins in 2025\"\n  raw_title: \"Rails 8 Frontend: 10 commandments and 7 deadly sins in 2025\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-01-12\"\n  time: \"11:40 - 12:10\"\n  track: \"Second Track\"\n  speakers:\n    - Yaroslav Shmarov\n  description: |-\n    Rewire your React/Rails API brain and learn to build a maintainable Rails Frontend!We will analyse some design patterns (10 commandments) and antipatterns (7 deadly sins).You will discover practical solutions to classic frontend problems (modals, sliders, multistep forms, dynamic elements).\n\n    Learn how to balance between components, decorators, helpers and partials and other frontend patterns.\n\n    Discover the ecosystem of Rails Frontend tools, like component and UI libraries (stimulus-component, stimulus-use, RailsUI, ZestUI, RapidRailsUI, PhlexUI), encapsulation frameworks (phlex, view components), frontend focused gems (Hotwire combobox, cocoon, lookbook)\n\n    Discover some practical solutions to classic problems like multistep forms, styled select dropdowns, dynamic forms, responsive tables, nested forms, modals, sliders.\n  video_id: \"szcMRq8HCuo\"\n  video_provider: \"youtube\"\n\n- id: \"lightning-talks-euruko-2024\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  time: \"12:20 - 13:00\"\n  track: \"Main Track\"\n  speakers:\n    - TODO\n  description: \"\"\n  video_id: \"lightning-talks-euruko-2024\"\n  video_provider: \"not_recorded\"\n\n- id: \"yaroslav-shmarov-workshop-euruko-2024\"\n  title: \"Workshop: Introduction to Ruby on Rails\"\n  raw_title: \"Workshop: Introduction to Ruby on Rails\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  time: \"12:20 - 13:00\"\n  track: \"Second Track\"\n  speakers:\n    - Yaroslav Shmarov\n  description: \"\"\n  video_id: \"yaroslav-shmarov-workshop-euruko-2024\"\n  video_provider: \"not_recorded\"\n\n# LUNCH BREAK\n\n- id: \"maple-ong-euruko-2024\"\n  title: \"Lessons from a Rails Infrastructure Team\"\n  raw_title: \"Lessons from a Rails Infrastructure Team\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-01-12\"\n  time: \"14:00 - 14:30\"\n  track: \"Main Track\"\n  speakers:\n    - Maple Ong\n  description: \"\"\n  video_id: \"wi3U-e1VTl4\"\n  video_provider: \"youtube\"\n\n- id: \"fernando-perales-euruko-2024\"\n  title: \"Let's give REST a rest: exploring the state of gRPC in Ruby\"\n  raw_title: \"Let's give REST a rest: exploring the state of gRPC in Ruby\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-01-12\"\n  time: \"14:00 - 14:30\"\n  track: \"Second Track\"\n  speakers:\n    - Fernando Perales\n  description: |-\n    I'll present some of the advantages of gRPC such as duplex streaming, auto generated client code, connection pool and first class load balancing, and how it can be applied. I'll also talk about the main disadvantages of implementing gRPC in an existing codebase.\n\n    gRPC has been around for a while and, even though it's neither a replacement of REST nor a better option for building APIs, it is an alternative that can be useful in certain cases where we can benefit from lightweight messages, built-in code generation and high performance. In this talk I'll share the concepts, pros and cons, and use cases of gRPC with examples in Ruby.\n\n    We'll start with a quick refresher on HTTP and REST. We'll move along with an introduction to gRPC/protobuf architecture and we will go through a demo on how to integrate gRPC in our Ruby applications and how to make it communicate with a Go service and we'll wrap up our session with some use cases where you may consider using gRPC instead of a REST API\n  video_id: \"CJTVey45isw\"\n  video_provider: \"youtube\"\n\n- title: \"Workshop: Testing: How to write fewer tests and cover more cases\"\n  raw_title: \"Workshop: Testing: How to write fewer tests and cover more cases\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  time: \"14:00 - 15:50\"\n  track: \"Third Track\"\n  speakers:\n    - Lucian Ghinda\n  description: |-\n    When learning Ruby or Ruby on Rails, you learn about RSpec or Minitest and how to use the library to write model, controller, or integration tests.\n    Yet you don’t learn much about testing: What is testing and how do you know that the tests you wrote will catch bugs?\n    How do you pick what to test?\n\n    There are a lot of resources out there about how to write RSpec or Minitest and about speeding up test case execution, but there is little knowledge shared online about how to decide what to test and how to write a good test case in Ruby.\n    This workshop plans to close this knowledge gap by showing easy-to-use and practical test design techniques, all applied in Ruby and Ruby on Rails.\n\n    I will cover test design techniques that help you write the minimum number of tests that would cover the widest surface of your app.\n    You will learn about Decision Tables, Boundary Value Analysis, Equivalence Partitioning and more, all with Ruby code examples.\n    You will lean how to write the minimum amount of tests while trying to cover as much as possible the part that you are testing.\n    All are based on mathematically proven techniques.\n  id: \"lucian-ghinda-workshop-euruko-2024\"\n  video_id: \"zqaj9eyUTb4\"\n  published_at: \"2025-06-01\"\n  video_provider: \"youtube\"\n\n- id: \"joel-drapper-euruko-2024\"\n  title: \"Building Beautiful Views in Ruby with Phlex\"\n  raw_title: \"Building Beautiful Views in Ruby with Phlex\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-01-12\"\n  time: \"14:40 - 15:10\"\n  track: \"Main Track\"\n  speakers:\n    - Joel Drapper\n  description: |-\n    In this practical talk, you'll learn how to use object-oriented programming to create fast, maintainable UI components in pure Ruby with Phlex.\n\n    Ruby applications tend to end up with a spaghetti soup of HTML, ERB, Ruby and Tailwind directives all muddled up and entangled in huge template files that become increasingly difficult to test, debug and maintain over time.\n\n    ViewComponent can help to unravel some of that, but it only goes so far. Now, many teams — including GitHub (behind ViewComponent) — are turning the view layer over to frontend JavaScript frameworks such as React.\n\n    Despite this, I still believe that returning simple HTML documents from a simple backend is the best way to build most web applications today — whether you're optimising for performance, developer productivity or long-term maintainability.\n\n    This talk introduces Phlex, a new Ruby gem that brings component-based architecture to the backend, enabling developers to create views that are fast, maintainable and really fun to work with in pure Ruby.\n\n    We'll start by identifying common pain points in traditional approaches, such as lack of encapsulation, difficult testing and poor performance.\n\n    We'll explore how Phlex addresses these issues by leveraging object-oriented programming to create reusable, composable UI components.\n\n    Through a series of real-world examples, you'll learn how to:\n\n    * Agradually refactor an existing Rails application;\n    * apply OOP patterns like inheritance and composition to your views;\n    * extract methods and objects, applying your existing Ruby refactoring skills to a new domain;\n    * encapsulate view logic and helpers within components;\n    * yield interfaces to enable composition;\n    * test your components in isolation; and\n    * package components into reusable UI kit gems.\n\n    We'll also cover the trade-offs and challenges of caching the view layer, the difference between views, layouts and components, and why you might want to reconsider the lost art of streaming HTML.\n\n    Finally, we'll learn about the emergent capabilities of a view layer that understands the structure of HTML documents, and how Phlex can help you write safer, more accessible HTML.\n\n    We'll also learn about Selective Rendering and the kinds of things that become possible when the frontend can ask the backend to render specific elements.\n\n    By the end of the talk, you'll be equipped with a set of patterns and best practices for building and maintaining component-based architectures in Ruby applications, and you'll have a solid foundation for using Phlex in your own projects, as well as a new perspective on what's possible with Ruby.\n  video_id: \"vlThDr3JJYw\"\n  video_provider: \"youtube\"\n\n- id: \"bruno-sutic-euruko-2024\"\n  title: \"Async Ruby\"\n  raw_title: \"Async Ruby\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-01-12\"\n  time: \"14:40 - 15:10\"\n  track: \"Second Track\"\n  speakers:\n    - Bruno Sutic\n  description: |-\n    Async Ruby is an exciting and innovating part of Ruby. It's a new approach to concurrency best described as “threads with NONE of the downsides”. Async Ruby has mind-blowing capabilities, and is so good Matz invited the gem to the standard library.\n\n    This talk is suitable for both beginners and experts, and is relevant for you if you're making web requests in Ruby. It will introduce you to some the most impressive Async features and explain its core concepts.\n  video_id: \"QLy6w5Rgm8s\"\n  video_provider: \"youtube\"\n\n- title: \"One does not simply... rebuild a product\"\n  raw_title: \"One does not simply... rebuild a product\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-02-23\"\n  time: \"15:20 - 15:50\"\n  track: \"Main Track\"\n  speakers:\n    - Prakriti Mateti\n  description: |-\n    \"A rebuild is never finished, only started\"\n\n    \"Technical rebuilds are doomed to fail\"\n\n    “It takes 3 times as long as you expect to rewrite a system”\n\n    We're rebuilding Culture Amp's second largest product - Performance. It came in as a Series A acquisition 5 years ago and has thousands of customers today with the largest one at 77k users. Against conventional wisdom, we're rebuilding it from the ground up with an aggressive timeline. The underlying model is outdated, slow to iterate on, and not extensible. The monoliths are riddled with tech debt, tightly coupled, patched and band-aided over many times, and won't take us towards the $3b global Performance market we're targeting.\n\n    That wasn't challenging enough already so I'm also using this opportunity to rebuild our engineering culture. Setting a high bar for engineering standards, ways of working, and hoping to improve engagement as we go.\n\n    In this talk, I'll share:\n\n    * How I came to this decision\n    * How we got buy in from Exec and the Board for a technical rebuild\n    * How we tried to set up for success, our principles and standards\n    * Where we failed\n    * Where we succeeded\n    * Lessons that could be useful for anyone thinking about rebuilding a product that's hampering speed and hindering your ability to innovate or deliver value to your customers.\n\n    The rebuild is still in progress. I don't have all the answers (or any!). But we've already learned much - what to do, what not to do, and where the spiders are hiding.\n  id: \"prakriti-mateti-euruko-2024\"\n  video_id: \"cyLNRYJ7SGY\"\n  video_provider: \"youtube\"\n\n- id: \"svyatoslav-kryukov-euruko-2024\"\n  title: \"Assembling the Future: crafting the missing pieces of the Ruby on Wasm puzzle\"\n  raw_title: \"Assembling the Future: crafting the missing pieces of the Ruby on Wasm puzzle\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-01-12\"\n  time: \"15:20 - 15:50\"\n  track: \"Second Track\"\n  speakers:\n    - Svyatoslav Kryukov\n  description: |-\n    Buckle up for a journey beyond ruby.wasm limits—making the entire Ruby ecosystem run in-browser a reality! No threads, networking, or beloved nokogiri? We tackle it all—from Kernel patches to CORS, crafting WASI functions, and Wasm within Wasm—we're bending reality to shape the web's next frontier!\n\n    Dive into the frontier of web innovation with a mission to bring Bundler, Rack, Rake, and more Ruby ecosystem tools into the browser! This session unveils the potential of Ruby.wasm, pushing past the limits of WASI to reshape how we think about web development. Explore the possibilities of running essential Ruby development tools directly in your browser, turning the dream of a fully interactive Ruby development environment on the web into reality.\n\n    Discover strategies for integrating Bundler for gem management, enabling Rack for web server interfacing, and leveraging Rake for automated tasks—all within the browser. We'll navigate the challenges of virtual file systems, dynamic gem loading, and network interactions through Ruby.wasm, offering insights into overcoming these hurdles.\n\n    We'll shine a light on the critical gaps in the ecosystem and the essential components still needed to make running comprehensive Ruby tools in the browser—from a theoretical dream to a practical, everyday reality. Get ready for a journey that promises to expand your understanding of what's possible with Ruby.wasm, setting the stage for a future where the web is powered by Ruby's elegance and versatility. Buckle up!\n  slides_url: \"https://speakerdeck.com/skryukov/assembling-the-future-crafting-the-missing-pieces-of-the-ruby-on-wasm-puzzle\"\n  video_id: \"T_ci4BHBqF0\"\n  video_provider: \"youtube\"\n\n# COFFEE BREAK\n\n- id: \"yukihiro-matz-matsumoto-euruko-2024\"\n  title: \"Podcast: Adrian & Yaro's Friendly Show with Yukihiro Matsumoto\"\n  raw_title: \"Adrian & Yaro's Friendly Show with Yukihiro Matsumoto\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  published_at: \"2025-01-12\"\n  track: \"Main Track\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n    - Yaroslav Shmarov\n    - Adrian Marin\n  description: |-\n    https://www.friendly.show/2278525\n  video_id: \"mbtXNkXtung\"\n  video_provider: \"youtube\"\n\n- id: \"jose-valim-euruko-2024\"\n  title: \"Keynote: Livebook: where Web, AI, and Concurrency meet\"\n  raw_title: \"Keynote: Livebook: where Web, AI, and Concurrency meet\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-12\"\n  time: \"16:30 - 17:20\"\n  track: \"Main Track\"\n  speakers:\n    - José Valim\n  description: |-\n    While it has been more than a decade since I wrote my last line of Ruby code, there are lessons the Ruby community taught me that I have never forgotten. And the biggest of them is to always be open to new ideas. In this talk, I will present Livebook, which borrows from Python, Erlang, JavaScript, and more, and enables us to introspect systems at scale, build machine learning applications, and run web applications, and much more within minutes. I hope I will inspire the audience to explore new ideas within their daily tools.\n  video_id: \"jose-valim-euruko-2024\"\n  video_provider: \"not_recorded\"\n  alternative_recordings:\n    - title: \"Livebook & Elixir: Where AI, Web & Concurrency Meet\"\n      event_name: \"YOW. 2023\"\n      date: \"2023-12-08\"\n      video_provider: \"youtube\"\n      video_id: \"pas9WdWIBHs\"\n      external_url: \"https://yowcon.com/sydney-2023/sessions/2758/livebook-and-elixir-where-ai-web-and-concurrency-meet\"\n\n# EURUKO PARTY & NETWORKING CHECK-IN\n\n# ORGANIZING PARTNER'S OPENING SPEECH\n\n# - title: Party\n#   raw_title: Party\n#   event_name: EuRuKo 2024\n#   date: '2024-09-12'\n#   time: 20:45 - 00:00\n#   track: Main Track\n#   speakers:\n#     - 'DJ: Obie Fernandez'\n#   description: ''\n\n# - title: Karaoke\n#   raw_title: Karaoke\n#   event_name: EuRuKo 2024\n#   date: '2024-09-12'\n#   time: 20:45 - 00:00\n#   track: Second Track\n#   speakers:\n#     - Open Stage\n#   description: ''\n\n# - title: 'Why''s poignant guide to Ruby: Documentary viewing book giveaway. Hacking\n#     and impromptu workshops / lightning talks afterwards.'\n#   raw_title: 'Why''s poignant guide to Ruby: Documentary viewing book giveaway. Hacking\n#     and impromptu workshops / lightning talks afterwards.'\n#   event_name: EuRuKo 2024\n#   date: '2024-09-12'\n#   time: 20:45 - 00:00\n#   track: Third Track\n#   speakers:\n#     - Org Team\n#   description: ''\n\n# - title: Good Morning and Agenda\n#   raw_title: Good Morning and Agenda\n#   event_name: EuRuKo 2024\n#   date: '2024-09-13'\n#   time: '09:40 - 10:00'\n#   track: Main Track\n#   speakers:\n#     - Carmen Huidobro\n#   description: ''\n\n- id: \"dave-thomas-euruko-2024\"\n  title: \"Keynote: Love, Limerence, and Programming Languages\"\n  raw_title: \"Keynote: Love, Limerence, and Programming Languages\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"10:00 - 10:50\"\n  track: \"Main Track\"\n  speakers:\n    - Dave Thomas\n  description: |-\n    They say that a well-used tool takes on the shape of the hand that uses it. But the opposite also holds: the tools we use shape the way we think about and execute things. Often, we aren't even aware how much influence the tool has on us.\n\n    This is a personal talk: I want to look back at the languages that changed me as a developer. Why was I attracted to them, why did I use them, and how did I benefit as a result. I also want to look forward, and offer some suggestions: things you might look for in a future coding partner. I even have some suggestions. Whether you swipe right is your choice.\n  video_id: \"imTop4ha1R4\"\n  video_provider: \"youtube\"\n\n- id: \"yudai-takada-euruko-2024\"\n  title: \"How does Lrama make the Ruby parser grammar G.O.A.T.?\"\n  raw_title: \"How does Lrama make the Ruby parser grammar G.O.A.T.?\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"11:00 - 11:30\"\n  track: \"Main Track\"\n  speakers:\n    - Yudai Takada\n  description: |-\n    The Ruby parser has historically been hacked in many complex ways. As a result, the files that define Ruby syntax and its capabilities are complex enough to be called the Demon Castle.\n\n    In Ruby 3.3, Lrama now generates Ruby parsers instead of GNU Bison, which generated the Ruby parser. In this talk, I'll show you why we are developing Lrama and how it improves the complex syntax definitions of Ruby.\n\n    In particular, this talk will show you how the syntax definition file syntax in Ruby has been improved to be G.O.A.T. This talk also covers the basics of parsers and parser generators, as well as the current state of the Ruby parser. Therefore, I plan to make the talk easier to understand for an audience that doesn't know much about Ruby parsers.\n  slides_url: \"https://speakerdeck.com/ydah/how-does-lrama-make-the-ruby-parser-grammar-g-dot-o-a-dot-t\"\n  video_id: \"7gGrNiufv54\"\n  video_provider: \"youtube\"\n\n- id: \"obie-fernandez-euruko-2024\"\n  title: \"Patterns of Application Development Using AI\"\n  raw_title: \"Patterns of Application Development Using AI\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"11:00 - 11:30\"\n  track: \"Second Track\"\n  speakers:\n    - Obie Fernandez\n  description: |-\n    This presentation draws on over a year of practical real-world experience and explores patterns ranging from code generation to real-time data analysis and automated customer support. Attendees will learn how to integrate AI tools and techniques: both potential pitfalls and emerging best practices.\n\n    Taking advantage of AI components can transform an application developer's workflow into an incredibly potent force, capable of competing at an unprecedented scale. This presentation draws on practical real-world experience gained by the presenter over the last 12 months of developing Olympia.chat. We will explore practical approaches ranging from code generation to real-time data analysis and automated customer support. The emphasis is on new tools that let application developers focus more than ever on innovation and creativity.\n\n    Attendees will leave with a roadmap for integrating AI tools and techniques into their projects, insights into the potential pitfalls and best practices, and inspiration to explore the boundaries of what a single developer or a small team can achieve with the right tools. The presenter is a well-known Ruby on Rails expert and his latest book, “Patterns of Application Development Using AI” is the definitive tome on the subject.\n  video_id: \"2CpHmDbmqCI\"\n  video_provider: \"youtube\"\n\n- id: \"rafael-pea-azar-euruko-2024\"\n  title: \"How Ruby forged Crystal\"\n  raw_title: \"How Ruby forged Crystal\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"11:00 - 11:30\"\n  track: \"Third Track\"\n  speakers:\n    - Rafael Peña-Azar\n  description: |-\n    Explore how Ruby's DNA shaped Crystal into a powerhouse language. From syntax to philosophy, discover the journey of inspiration and innovation behind Crystal's evolution. Join me as we uncover the dynamic interplay between two iconic languages at EuRuKo!!!\n\n    In this talk, we will explore the fascinating journey from the conception of Crystal to its current state as an elegant and efficient programming language. Through concrete examples and detailed analysis, we will see how Ruby has influenced the creation and evolution of Crystal, from syntax to fundamental concepts.\n\n    Things that will bring to the talk. + Brief overview of Crystal and its place in the programming language landscape. + Exploration of how key principles and features of Ruby have influenced the design of Crystal. + Comparison of the similarities and differences in syntax and semantics between Ruby and Crystal. + Analysis of how Ruby's design principles, such as readability and expres- siveness, have been integrated into Crystal. + Discussion on how Crystal has evolved and diverged from Ruby to meet its own needs and goals. + Practical examples of how Ruby has influenced problem-solving and feature implementation in Crystal. + Reflection on the future of Crystal and how Ruby's influence will continue to shape its development.\n  video_id: \"f7_qc7CWKV8\"\n  video_provider: \"youtube\"\n\n- id: \"cristian-planas-euruko-2024\"\n  title: \"2,000 Engineers, 2 Million Lines of Code: The History of a Rails Monolith\"\n  raw_title: \"2000 engineers, 2 millions lines of code: the history of a Rails monolith\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"11:40 - 12:10\"\n  track: \"Main Track\"\n  speakers:\n    - Cristian Planas\n    - Anatoly Mikhaylov\n  description: |-\n    Rails is the best framework for building your startup. But what happens when the startup becomes a leading business? How do you grow and maintain a Rails application for 15 years? In this talk, we will through the life of a Rails-centered org, from 0 to planetary scale.\n\n    How do companies grow while keeping Rails at the heart of its stack? How do you maintain a growing application for 15 years in a constantly changing environment?\n\n    In this talk, Anatoly Mikhaylov and Cristian Planas, Senior Staff Engineers at Zendesk, will share with you their 10 years of experience in a company that has succeeded with Rails in its core. They will guide you through the life of a Rails-centered organization, that scaled from zero to hundreds of millions of users.\n\n    The talk will deal with:\n\n    * From the distributed monolith to microservices “lite”: 15 years of an evolving architecture\n    * Upgrading a Rails application: from 1.0 to 7.0\n    * Infrastructure: Self-hosted vs Cloud\n    * Managing growing costs: from product design to resource optimization\n    * Choosing the right storage for the task: database-driven development\n    * Collaborating with thousands of engineers around the world: creating a resilient development environment and release pipelines.\n    * Keeping the lights on: our take on reliability and monitoring\n  video_id: \"2nmgfVqhfiw\"\n  video_provider: \"youtube\"\n\n- id: \"andrei-bondarev-euruko-2024\"\n  title: \"Intro to AI Agents\"\n  raw_title: \"Build an AI agent in 15 min\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"11:40 - 12:10\"\n  track: \"Second Track\"\n  speakers:\n    - Andrei Bondarev\n  description: |-\n    The author of Langchain.rb will walk you through current capabilities of LLMs and what can be built today. We will build a business process automation AI agent in Ruby and discuss the common pitfalls and misconceptions. We'll discuss what might be emerging as a new LLM-powered software stack.\n\n    Generative AI has been taking the world by storm. The Coatue AI (Nov 2023) report is putting AI models at the centerpiece of all modern tech stacks going forward that Application Developers will be using to build on top of. It would not be controversial to say that the Ruby ecosystem lacks in its support and understanding of the AI, ML and DS landscape. If we'd like to stay relevant in the future, we need to start building the foundations now. We'll look at what Generative AI is, what kind of applications developers in other communities are building and how Ruby can be used to build similar applications today. We'll cover Retrieval Augmented Generation (RAG), vector embeddings and semantic search, prompt engineering, and what the state of art (SOTA) in evaluating LLM output looks like today. We will also cover AI Agents, semi-autonomous general purpose LLM-backed applications, and what they're capable of today. We'll make a case why Ruby is a great language to build these applications because on its strengths and its incredible ecosystem. After the slides, I'll walk the attendees through building an AI Agent in 15 min with Langchain.rb.\n  slides_url: \"https://speakerdeck.com/andreibondarev/euruko-2024-intro-to-ai-agents\"\n  video_id: \"J6xgDUhAHTo\"\n  video_provider: \"youtube\"\n\n- id: \"bartosz-blimke-euruko-2024\"\n  title: \"WebMock Unmocked\"\n  raw_title: \"WebMock Unmocked\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"11:40 - 12:10\"\n  track: \"Third Track\"\n  speakers:\n    - Bartosz Blimke\n  description: |-\n    Join Bartosz Blimke, the creator of WebMock, as he takes you on a journey through the internals of this indispensable Ruby library. Discover how WebMock has been simplifying the process of testing code that interacts with external APIs for the past 15 years.\n\n    In this talk, you'll learn:\n\n    * How WebMock makes tests faster, more reliable, and independent of network connection\n    * The different features WebMock offers, from stubbing requests to verifying specific requests\n    * The story behind WebMock's creation during a hackathon in 2009\n    * How WebMock has become a cornerstone of the Ruby testing ecosystem and influenced other programming languages\n    * A deep dive into the internals of WebMock, revealing how it works under the hood\n\n    Whether you're a seasoned Ruby developer or just starting out, this talk will give you a deeper appreciation for the tools you use daily. Celebrate WebMock's 15th anniversary and gain insights from the maintainer's perspective.\n\n    Get ready to unmock the magic of WebMock and discover how it has been helping developers write better tests for the past 15 years!\n  video_id: \"CCbZOYKz5CE\"\n  video_provider: \"youtube\"\n\n# CITY PITCHING\n\n# LUNCH BREAK\n\n- id: \"seong-heon-jung-euruko-2024\"\n  title: \"Using Ractors and Making Ractors Usable\"\n  raw_title: \"Using Ractors and Making Ractors Usable\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"14:00 - 14:30\"\n  track: \"Main Track\"\n  speakers:\n    - Seong-Heon Jung\n  description: |-\n    Enough Fibonacci functions! It's time for Ractors to work a real job. Join me in building a Rack server with Ractors. We'll solve real-world problems like worker pooling, async programming, and sharing global objects across Ractors (gasp). In the process, we'll discuss where Ractors need to go next.\n\n    Ractor is an ambitious feature introduced with Ruby 3.0 enabling truly parallel execution on CRuby. Adoption of Ractors has been somewhat slow, however, because Ractors are not a drop-in replacement for previous concurrency abstractions. In fact, they require a different architecture altogether. In this talk, we'll walk through the process of building a project using Ractors through the example of a Ractor-based Rack-compatible web server. We'll look at using Ractors with - existing design patterns - novel design patterns - Ractor-unfriendly patterns. Simultaneously, we'll evaluate Ractors as a language feature; that is, examine its stability, reliability, and coherence with other concurrency abstractions like Fibers and Threads. The talk aims to lend insight into how you can use Ractors in your own, non-trivial project and leave with ideas on how you can contribute to the improvement of Ractors as a language feature.\n  video_id: \"PnaQay6aRDE\"\n  video_provider: \"youtube\"\n\n- id: \"kasper-timm-hansen-euruko-2024\"\n  title: \"How to Break into Reading Open Source\"\n  raw_title: \"How to Break into Reading Open Source\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"14:00 - 14:30\"\n  track: \"Second Track\"\n  speakers:\n    - Kasper Timm Hansen\n  description: |-\n    There's a treasure trove of code that you could learn from hiding in plain sight: Open Source.\n\n    By reading other people's code you can pick up new tricks, names, and concepts — and apply them to your code. You can even be exposed to things you'd never think of.\n\n    My journey reading Open Source for the hell of it started back in 2013, when I set out to read all of Rails as a Google Summer of Code student.\n\n    Join this session to see how I've grown my skills through reading and have the process demystified so you can too. You'll walk away knowing how to start breaking into even the gnarliest codebases.\n  video_id: \"5SISrSgaRCY\"\n  video_provider: \"youtube\"\n  slides_url: \"https://speakerdeck.com/kaspth/how-to-break-into-reading-open-source\"\n\n- title: \"Workshop: SQLite on Rails: From rails new to 50k concurrent users and everything in between\"\n  raw_title: \"Workshop: SQLite on Rails: From rails new to 50k concurrent users and everything in between\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  time: \"14:00 - 15:50\"\n  track: \"Third Track\"\n  speakers:\n    - Stephen Margheim\n  description: |-\n    Hands-on building Rails applications using SQLite! This workshop offers a mix of the basics (rails new with SQLite and Solid gems, getting backups setup, core deployment considerations, etc.) and more advanced use-cases, like installing extensions, running multiple databases, full-text search, etc.\n\n    Learn how to build and deploy a Rails application using SQLite with hands-on exercises! Together we will take a brand new Rails application and walk through various features and enhancements to make a production-ready, full-featured application using only SQLite. We will take advantage of SQLite's lightweight database files to create separate databases for our data, job queue, cache, error monitoring, etc. We will install and use a SQLite extension to build vector similarity search. We will setup point-in-time backups with Litestream. We will also explore how to deploy your application. By the end of this workshop, you will understand what kinds of applications are a good fit for SQLite, how to build a resilient SQLite on Rails application, and how to scale to 50k+ concurrent users.\n\n    This workshop is intended for Rails developers of all levels, though it will likely be most valuable to developers who have pre-existing experience with building and deploying a Rails application.\n\n    The primary desired outcome is the developers feeling knowledgable and comfortable with the differences and details of running a SQLite on Rails application. Secondarily and relatedly, this workshop will provide a hands-on introduction to the emerging SQLite+Ruby/Rails ecosystem of tools.\n  id: \"stephen-margheim-euruko-2024\"\n  video_id: \"BVOszNjCPOs\"\n  published_at: \"2025-02-23\"\n  video_provider: \"youtube\"\n\n- id: \"samuel-giddins-euruko-2024\"\n  title: \"A survey of recent RubyGems CVEs\"\n  raw_title: \"A survey of recent RubyGems CVEs\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"14:40 - 15:10\"\n  track: \"Main Track\"\n  speakers:\n    - Samuel Giddins\n  description: |-\n    RubyGems, like any sufficiently-used piece of software, has its fair share of bugs. Being a package manager (and gem host), many of those bugs turn out to have security implications. Let's take a tour of recent RubyGems RubyGems.org vulnerabilities, and learn how we're keeping the ecosystem safe.\n\n    Marshal, insufficient input validation, symlink traversal, oh my! Over the past couple of years, there's been a slow trickle of CVEs announced, covering both RubyGems RubyGems.org. Let's go on a quick tour of those vulnerabilities, covering their lifecycle from discovery to mitigation to announcement. We'll dive into some patterns that have started to emerge, and discuss the steps the RubyGems team is taking to keep the Ruby ecosystem secure in an increasingly adversarial world.\n  video_id: \"T9VDTcrRi_M\"\n  video_provider: \"youtube\"\n\n- id: \"jakub-godawa-euruko-2024\"\n  title: \"Visualized multi-threaded simulators in Ruby\"\n  raw_title: \"Visualized multi-threaded simulators in Ruby\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-02-23\"\n  time: \"14:40 - 15:10\"\n  track: \"Second Track\"\n  speakers:\n    - Jakub Godawa\n  description: |-\n    We all do simulations in our heads, so why not make one in Ruby? Something that we can observe, fast forward, or let it linger. Let's see how custom shared timers, threads, queues, and mutexes work together, and how they can form a petrol station with optimal cost and throughput.\n\n    The cars are coming to a station. They want to get some fuel. They come at different times and they need to be served. Just like web requests but this time we'll not do web development. This we do at work. So for fun we want to build something that feels more alive. A small closed system that we could fully control and derive further ideas from. This is how we start thinking about simulators.\n\n    The main idea of a simulation is that it happens in some programmable environment. First, we need to think about how to control time. If every piece of the simulation, like a car or a station, runs in its own thread, then how do we synchronize them? How to handle access into shared resources? What data structures should we use?\n\n    Also, how do we create a protocol for gathering results to help us make decisions? How do we write a config file for a simulator engine that can spawn multiple scenarios in parallel? And last but not least, how do we visualize a simulation?\n\n    This presentation is a pure Ruby feast. We will operate on MRI and visualize the simulation in two ways: with d3.js, and through ASCII art. See you there! 🚕\n  video_id: \"Qu_Wqe6wkLY\"\n  video_provider: \"youtube\"\n\n- id: \"lucian-ghinda-euruko-2024\"\n  title: \"The Modern Rubyist: When and How to Use the Latest Features\"\n  raw_title: \"The Modern Rubyist: When and How to Use the Latest Features\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"15:20 - 15:50\"\n  track: \"Main Track\"\n  speakers:\n    - Lucian Ghinda\n  description: |-\n    Explore how Ruby has evolved with features like numbered params, endless methods, and pattern matching. Let’s embrace these changes to future-proof our code rather than sticking to old habits. You will learn how to use the new features, when to apply them, and when to avoid them.\n\n    There are almost 5 years since we started seeing many new features and syntax being added to Ruby, and still, a huge part of the developers are not using it. We have become conservative and thus this is a protecting position and when we focus on protecting what we have, we close in and are not focused on evolving and the future. As Matz says in a talk, we need to push forward and adopt new features if we want to avoid the Boredom Trap, where existing developers are getting bored and moving out while new people are not coming in as the language does not evolve to offer new solutions to new problems.\n\n    Ruby has evolved a lot since Ruby 2.7 and has added a wide range of new features that can transform both how we think about and write code.\n\n    You may have heard about some of them: numbered block params, endless method definition, hash literal value omission, pattern matching, object shapes, or new stdlib/core methods and classes. These features hold immense potential, yet most codebases do not take full advantage of them.\n\n    The primary outcome of this talk is to show developers practical knowledge about the new features. They will not only understand what these features do but also when it is a good idea and a bad idea to apply them. It might be that everybody knows about these new features, but adopting them takes work to convince colleagues about the benefits and use cases where new features fit.\n\n    In this talk, I will review a series of code snippets taken straight from production and see how they can be improved using the new Ruby features while extracting rules or guides about how and when to apply them.\n  video_id: \"8NFeASvuhiI\"\n  video_provider: \"youtube\"\n\n- id: \"john-gallagher-euruko-2024\"\n  title: \"Squash Production Defects Quickly - The Power of Structured Logging in Rails\"\n  raw_title: \"Squash Production Defects Quickly - The Power of Structured Logging in Rails\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"15:20 - 15:50\"\n  track: \"Second Track\"\n  speakers:\n    - John Gallagher\n  description: |-\n    Rails apps can be a black box. Ever seen a defect where you just can't figure out what's going on?This talk will give you practical steps to improve the observability of your Rails app, taking the time to understand and fix defects from hours or days to minutes.\n\n    Rails 8 brings an exciting new feature: built-in structured logging. This talk will delve into the transformative impact of structured logging on application observability and fixing defects.\n\n    Structured logging, as a cornerstone of observability, offers a more organized and query-able way to handle logs compared to traditional text-based logs. This session will guide you through the nuances of structured logging in Rails, demonstrating how it can be leveraged to gain better insights into your application's behavior.\n\n    This talk will be a deep technical dive into how to make structured logging work with an existing Rails app.\n  video_id: \"b2LrEFVqLG4\"\n  video_provider: \"youtube\"\n\n# CITY VOTING RESULTS & COFFEE\n\n- id: \"yukihiro-matz-matsumoto-euruko-2024-closing-keynote-better-ruby\"\n  title: \"Closing Keynote: Better Ruby\"\n  raw_title: \"Closing Keynote\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"16:30 - 17:20\"\n  track: \"Main Track\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  description: \"\"\n  video_id: \"JYBGXSEijTg\"\n  video_provider: \"youtube\"\n\n- id: \"dave-thomas-euruko-2024-panel-daves-uninterrupted-conv\"\n  title: \"Panel: Dave's uninterrupted conversation with Matz & José Valim\"\n  raw_title: \"Dave's uninterrupted conversation with Matz José Valim\"\n  event_name: \"EuRuKo 2024\"\n  date: \"2024-09-13\"\n  published_at: \"2025-01-12\"\n  time: \"17:30 - ?\"\n  track: \"Main Track\"\n  speakers:\n    - Dave Thomas\n    - Yukihiro \"Matz\" Matsumoto\n    - José Valim\n  description: \"\"\n  video_id: \"nl1tYQjdYwY\"\n  video_provider: \"youtube\"\n# EVENT CLOSING\n"
  },
  {
    "path": "data/euruko/euruko-2025/cfp.yml",
    "content": "---\n- link: \"https://papercall.io/euruko-2025\"\n  open_date: \"2025-03-14\"\n  close_date: \"2025-04-10\"\n"
  },
  {
    "path": "data/euruko/euruko-2025/event.yml",
    "content": "---\nid: \"euruko-2025\"\ntitle: \"EuRuKo 2025\"\nkind: \"conference\"\nlocation: \"Viana do Castelo, Portugal\"\ndescription: |-\n  Join us in Viana do Castelo, a charming coastal city where history meets modernity. Experience a city rich in culture and architectural heritage, and conveniently located only 40 minutes from Porto Airport.\npublished_at: \"2025-11-10\"\nstart_date: \"2025-09-18\"\nend_date: \"2025-09-19\"\nchannel_id: \"UCgXsZr2e0AgUJMZm5t03WVw\"\nyear: 2025\nbanner_background: \"linear-gradient(to bottom, #d1424d 0%, #c82f3d 30%, #a81420 100%)\"\nfeatured_background: \"#CC1525\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2025.euruko.org\"\ncoordinates:\n  latitude: 41.6902296\n  longitude: -8.8288455\n"
  },
  {
    "path": "data/euruko/euruko-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Henrique Cardoso de Faria\n  organisations: []\n\n- name: \"Conference MC\"\n  users:\n    - Zuzanna Kusznir\n    - Andrzej Krzywda\n\n- name: \"Review Committee Member\"\n  users:\n    - Adrian Marin\n    - Alessandro Brückheimer\n    - Ali Krynitsky\n    - Bruno Gerotto\n    - Marcelo Menezes\n    - Mariusz Kozieł\n    - Mike Hickman\n    - Muhamed Isabegović\n    - Pedro Carmona\n    - Pedro Torres\n    - Rosa Gutiérrez\n    - Sarah Eggleston\n    - Sergy Sergyenko\n    - Vladimir Dementyev\n    - Zuzanna Kusznir\n"
  },
  {
    "path": "data/euruko/euruko-2025/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 0\"\n    date: \"2025-09-17\"\n    grid:\n      - start_time: \"14:00\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - title: \"Pre-Registration\"\n            description: |-\n              Early registration at Link Cowork & Business\n\n  - name: \"Day 1\"\n    date: \"2025-09-18\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Registration / Welcome Coffee\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:50\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 1\n\n      - start_time: \"14:05\"\n        end_time: \"14:35\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:20\"\n        end_time: \"15:50\"\n        slots: 1\n\n      - start_time: \"15:50\"\n        end_time: \"16:40\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"16:40\"\n        end_time: \"17:10\"\n        slots: 1\n\n      - start_time: \"17:15\"\n        end_time: \"17:45\"\n        slots: 1\n\n      - start_time: \"17:45\"\n        end_time: \"18:30\"\n        slots: 1\n        items:\n          - title: \"Verde de Honra\"\n            description: |-\n              Party Kickoff\n\n      - start_time: \"18:30\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - title: \"DJ Sunset Party\"\n            description: |-\n              Party by the river\n\n      - start_time: \"19:30\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - title: \"Karaoke\"\n            description: |-\n              Main stage\n\n  - name: \"Day 2\"\n    date: \"2025-09-19\"\n    grid:\n      - start_time: \"08:50\"\n        end_time: \"09:25\"\n        slots: 1\n        items:\n          - Doors Open / Welcome Coffee\n\n      - start_time: \"09:25\"\n        end_time: \"09:55\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"10:55\"\n        slots: 1\n        items:\n          - \"Pitch: Next Year's Host\"\n\n      - start_time: \"10:55\"\n        end_time: \"11:25\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Meetup for Ruby Community and Conference Organizers\n\n      - start_time: \"13:30\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"13:30\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"13:30\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"13:30\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"13:30\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"13:30\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"13:30\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"16:15\"\n        end_time: \"16:45\"\n        slots: 1\n\n      - start_time: \"16:50\"\n        end_time: \"17:20\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"18:15\"\n        slots: 1\n\n      - start_time: \"18:15\"\n        end_time: \"18:30\"\n        slots: 1\n        items:\n          - Closing Notes and Host Results\n\n      - start_time: \"18:30\"\n        end_time: \"19:30\"\n        slots: 1\n        items:\n          - Social & Cultural Event\n\n  - name: \"Day 3\"\n    date: \"2025-09-20\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - title: \"Ruby Safari\"\n            description: |-\n              Viana do Castelo City\n"
  },
  {
    "path": "data/euruko/euruko-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Silver Sponsors\"\n      description: |-\n        Silver Sponsors\n      level: 1\n      sponsors:\n        - name: \"CloudAMQP by 84codes\"\n          website: \"https://84codes.com\"\n          slug: \"cloudamqp-by-84codes\"\n          logo_url: \"https://2025.euruko.org/images/sponsors/cloudamqp-by-84codes.svg\"\n\n        - name: \"Salsify\"\n          website: \"https://www.salsify.com\"\n          slug: \"salsify\"\n          logo_url: \"https://2025.euruko.org/images/sponsors/salsify.png\"\n\n        - name: \"GoCardless\"\n          website: \"https://gocardless.com\"\n          slug: \"gocardless\"\n          logo_url: \"https://2025.euruko.org/images/sponsors/gocardless.svg\"\n\n    - name: \"Bronze Sponsors\"\n      description: |-\n        Bronze Sponsors\n      level: 2\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com\"\n          slug: \"appsignal\"\n          logo_url: \"https://2025.euruko.org/images/sponsors/appsignal.png\"\n\n        - name: \"Evil Martians\"\n          website: \"https://evilmartians.com\"\n          slug: \"evilmartians\"\n          logo_url: \"https://2025.euruko.org/images/sponsors/evil_martians.jpeg\"\n\n        - name: \"RoRvsWild\"\n          website: \"https://www.rorvswild.com\"\n          slug: \"rorvswild\"\n          logo_url: \"https://2025.euruko.org/images/sponsors/rorvswild.svg\"\n\n        - name: \"Typesense\"\n          website: \"https://typesense.org\"\n          slug: \"typesense\"\n          logo_url: \"https://2025.euruko.org/images/sponsors/typesense.svg\"\n\n        - name: \"ventrata\"\n          website: \"https://ventrata.com\"\n          slug: \"ventrata\"\n          logo_url: \"https://2025.euruko.org/images/sponsors/ventrata.svg\"\n\n    - name: \"Online Sponsors\"\n      description: |-\n        Online Sponsors\n      level: 3\n      sponsors:\n        - name: \"WeLaika\"\n          website: \"https://welaika.com\"\n          slug: \"WeLaika\"\n          logo_url: \"https://2025.euruko.org/images/sponsors/welaika.png\"\n\n    - name: \"Travel Sponsors\"\n      description: |-\n        Travel Sponsors\n      level: 4\n      sponsors:\n        - name: \"Arkency\"\n          website: \"https://arkency.com\"\n          slug: \"arkency\"\n          logo_url: \"https://2025.euruko.org/images/sponsors/arkency.svg\"\n# Our Amazing Partners\n\n# Community Partners\n"
  },
  {
    "path": "data/euruko/euruko-2025/venue.yml",
    "content": "---\nname: \"Cultural Center of Viana do Castelo\"\naddress:\n  street: \"269 Rua Manuel Espregueira\"\n  city: \"Viana do Castelo\"\n  region: \"Viana do Castelo\"\n  postal_code: \"4900-344\"\n  country: \"Portugal\"\n  country_code: \"PT\"\n  display: \"Praça Marques Júnior, R. Manuel Espregueira 269, 4900-344 Viana do Castelo, Portugal\"\n\ncoordinates:\n  latitude: 41.6902296\n  longitude: -8.8288455\n\nmaps:\n  google: \"https://maps.google.com/?q=Cultural+Center+of+Viana+do+Castelo,41.6902296,-8.8288455\"\n  apple: \"https://maps.apple.com/?q=Cultural+Center+of+Viana+do+Castelo&ll=41.6902296,-8.8288455\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=41.6902296&mlon=-8.8288455\"\n\naccessibility:\n  wheelchair: true\n  elevators: true\n  accessible_restrooms: true\n  notes: \"The venue is 100% wheelchair accessible. The entire conference area is on a flat level.\"\n\nlocations:\n  - name: \"Ruby Safari Meeting Point\"\n    kind: \"Meeting Point\"\n    address:\n      street: \"Praça da República\"\n      city: \"Viana do Castelo\"\n      region: \"Viana do Castelo\"\n      postal_code: \"4900-520\"\n      country: \"Portugal\"\n      country_code: \"PT\"\n      display: \"Praça da República, 4900-520 Viana do Castelo, Portugal\"\n    coordinates:\n      latitude: 41.6936323\n      longitude: -8.8282325\n    maps:\n      google: \"https://maps.google.com/?q=Chafariz+da+Praça+da+República,41.6936323,-8.8282325\"\n      apple: \"https://maps.apple.com/?q=Chafariz+da+Praça+da+República&ll=41.6936323,-8.8282325\"\n\nhotels:\n  - name: \"AP Dona Aninhas\"\n    kind: \"Speaker Hotel\"\n    address:\n      street: \"38 Largo Vasco da Gama\"\n      city: \"Viana do Castelo\"\n      region: \"Viana do Castelo\"\n      postal_code: \"4900-322\"\n      country: \"Portugal\"\n      country_code: \"PT\"\n      display: \"Largo Vasco da Gama 38, 4900-322 Viana do Castelo, Portugal\"\n    coordinates:\n      latitude: 41.6911865\n      longitude: -8.8303231\n    maps:\n      google: \"https://maps.google.com/?q=AP+Dona+Aninhas,41.6911865,-8.8303231\"\n      apple: \"https://maps.apple.com/?q=AP+Dona+Aninhas&ll=41.6911865,-8.8303231\"\n"
  },
  {
    "path": "data/euruko/euruko-2025/videos.yml",
    "content": "# Website: https://2025.euruko.org/\n---\n- title: \"Opening Ceremony\"\n  raw_title: \"Opening Ceremony with Zuzanna Kusznir, Andrzej Krzywda Henrique Cardoso de Faria\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-18\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Zuzanna Kusznir\n    - Andrzej Krzywda\n    - Henrique Cardoso de Faria\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"opening-ceremony-euruko-2025\"\n  id: \"opening-ceremony-euruko-2025\"\n\n- title: \"Opening Keynote: My Favorite Things\"\n  raw_title: 'Opening Keynote by Yukihiro \"Matz\" Matsumoto'\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-18\"\n  published_at: \"2025-10-12\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"gYI4YzSCLRo\"\n  id: \"yukihiro-matz-matsumoto-euruko-2025\"\n\n- title: \"Introducing ReActionView: A new ActionView-Compatible ERB Engine\"\n  raw_title: \"Introducing ReActionView: A new ActionView-Compatible ERB Engine by Marco Roth\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-18\"\n  published_at: \"2025-10-13\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Marco Roth\n  description: |-\n    This talk is the conclusion of a journey I've been sharing throughout 2025. At RubyKaigi, I introduced Herb: a new HTML-aware ERB parser and tooling ecosystem. At RailsConf, I released developer tools built on Herb, including a formatter, linter, and language server, alongside a vision for modernizing and improving the Rails view layer.\n\n    Now, I'll continue with ReActionView: a new ERB engine built on Herb, fully compatible with .html.erb but with HTML validation, better error feedback, reactive updates, and built-in tooling.\n  video_provider: \"youtube\"\n  video_id: \"H0d3jmK8D44\"\n  id: \"marco-roth-euruko-2025\"\n  slides_url: \"https://speakerdeck.com/marcoroth/introducing-reactionview-a-new-actionview-compatible-erb-engine-at-euruko-2025-viana-do-castelo-portugal\"\n\n- title: \"Postgres Partitioning Best Practices\"\n  raw_title: \"Postgres Partitioning Best Practices by Karen Jex\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-18\"\n  published_at: \"2025-10-13\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Karen Jex\n  description: |-\n    As the databases behind your apps grow, you need strategies to help manage large tables. Partitioning your Postgres tables might be the approach you need. This talk will give you an understanding of whether partitioning is right for you and, if so, how you need to go about putting it in place.\n  video_provider: \"youtube\"\n  video_id: \"GBK9wcEcmiI\"\n  id: \"karen-jex-euruko-2025\"\n\n- title: \"Rewrite with confidence: validating business rules through isolated testing\"\n  raw_title: \"Rewrite with confidence: validating business rules through isolated testing by Szymon Fiedler\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-18\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Szymon Fiedler\n  description: |-\n    Learn how we used Rubys metaprogramming at Lemonade Inc. to rewrite critical business logic by building a snapshot-based verification system. See how recording HTTP interactions and raw database state enabled equivalence verification when documentation was sparse and business rules were scattered.\n  video_provider: \"scheduled\"\n  video_id: \"szymon-fiedler-euruko-2025\"\n  id: \"szymon-fiedler-euruko-2025\"\n\n- title: \"The hidden value of niche open-source projects\"\n  raw_title: \"The hidden value of niche open-source projects by Rémy Hannequin\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-18\"\n  published_at: \"2025-10-14\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Rémy Hannequin\n  description: |-\n    Imagine your quirky side project sparking professional breakthroughs. Discover how a niche Ruby gem turned passion into progress and learn why your wild idea might be the one that changes everything.\n  video_provider: \"youtube\"\n  video_id: \"oE9EQ-IHYyg\"\n  id: \"remy-hannequin-euruko-2025\"\n\n- title: \"How a Ruby profiler works: Stackprof under a microscope\"\n  raw_title: \"How a Ruby profiler works: Stackprof under a microscope by Ivo Anjo\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-18\"\n  published_at: \"2025-11-10\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Ivo Anjo\n  description: |-\n    Stackprof is a powerful, low-overhead Ruby profiler. Did you know its built with only 2k lines of C + Ruby? In this talk well learn how to use a profiler by examining how one works, end-to-end: from different triggers, to sampling data to reduce overhead to producing pretty flamegraphs.\n  video_provider: \"youtube\"\n  video_id: \"mq9P-afMMus\"\n  id: \"ivo-anjo-euruko-2025\"\n\n- title: \"Conquering Massive Traffic Spikes in Ruby Applications with Pitchfork\"\n  raw_title: 'Conquering Massive Traffic Spikes in Ruby Applications with Pitchfork by Sangyong \"Shia\" Sim'\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-18\"\n  published_at: \"2025-11-10\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Sangyong \"Shia\" Sim\n  description: |-\n    Discover how we tackled extreme traffic spikes on our Rails platform using Pitchfork. Learn to efficiently warm up Rails applications and significantly improve latency during massive sales events.\n  video_provider: \"youtube\"\n  video_id: \"vOH0RuvQrQA\"\n  id: \"sangyong-shia-sim-euruko-2025\"\n\n- title: \"Building interactive Ruby gem tutorials with Wasm - yes, right in the browser!\"\n  raw_title: \"Building interactive Ruby gem tutorials with Wasm - yes, right in the browser! by Albert Pazderin\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-18\"\n  published_at: \"2025-11-10\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Albert Pazderin\n  description: |-\n    What if you could experiment with a gem instantly? No environment setup, no need to install a library, clone a repo, or read tons of docs. That could accelerate adoption--especially for new gems finding an audience. Well, its possible! My talk is on bringing Ruby gems into browsers via WebAssembly!\n  video_provider: \"youtube\"\n  video_id: \"RUbAaEluDVA\"\n  id: \"albert-pazderin-euruko-2025\"\n\n- title: \"Roasting Code for Fun & Profit with Structured AI Workflows\"\n  raw_title: \"Roasting Code for Fun & Profit with Structured AI Workflows by Obie Fernandez\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-18\"\n  published_at: \"2025-11-10\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Obie Fernandez\n  description: |-\n    Roast is Shopify's innovative Ruby-based tool leveraging structured AI workflows and state machines to analyze, grade, and generate deterministic, high-quality code across many languages, not just Ruby. Its modular prompt architecture enables easy customization and enables developer collaboration.\n  video_provider: \"youtube\"\n  video_id: \"EjqfFTbayBE\"\n  id: \"obie-fernandez-euruko-2025\"\n\n- title: \"RubyLLM: Making AI Development Beautiful Again\"\n  raw_title: \"RubyLLM: Making AI Development Beautiful Again by Carmine Paolino\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  published_at: \"2025-11-10\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Carmine Paolino\n  description: |-\n    While others drown in Python-like frameworks and provider-specific abstractions, were proving AI development can be as elegant as Rails itself. 1700+ GitHub stars in its first week shows the Ruby community is ready for AI development thats beautiful AND async-fast.\n  video_provider: \"youtube\"\n  video_id: \"LuNAzhTqnhg\"\n  id: \"carmine-paolino-euruko-2025\"\n\n- title: 'Don''t Be \"Thread\"-ened: Testing Multithreaded Code with Confidence'\n  raw_title: 'Don''t Be \"Thread\"-ened: Testing Multithreaded Code with Confidence by Julia Egorova'\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  published_at: \"2025-11-10\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Julia Egorova\n  description: |-\n    All code deserves testing--but especially multithreaded code. Yet, threads really love to do their own thing--running in random orders, messing with timing, fighting over shared resources. So, my talk will dig into the world of multithreaded testing and check out tools and tips for taming the chaos!\n  video_provider: \"youtube\"\n  video_id: \"SCMYlsOEE2Y\"\n  id: \"julia-egorova-euruko-2025\"\n\n- title: \"City Pitches\"\n  raw_title: \"City Pitches\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  video_provider: \"children\"\n  video_id: \"city-pitches-euruko-2025\"\n  id: \"city-pitches-euruko-2025\"\n  description: |-\n    Every year, Euruko takes place in a different European city — chosen by the community.\n\n    If you want to bring Euruko to your city in 2026, submit your pitch below!\n\n    Selected proposals will have a dedicated moment during Euruko 2025 to present their city live on stage.\n  talks:\n    - title: \"City Pitch: Paris\"\n      raw_title: \"City Pitch: Paris\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      speakers:\n        - Rémy Hannequin\n      description: \"\"\n      video_provider: \"scheduled\"\n      video_id: \"city-pitch-paris-euruko-2025\"\n      id: \"city-pitch-paris-euruko-2025\"\n\n    - title: \"City Pitch: Poznań\"\n      raw_title: \"City Pitch: Poznań\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      speakers:\n        - Chris Hasinski\n      description: \"\"\n      video_provider: \"scheduled\"\n      video_id: \"city-pitch-poznan-euruko-2025\"\n      id: \"city-pitch-poznan-euruko-2025\"\n\n    - title: \"City Pitch: Brno\"\n      raw_title: \"City Pitch: Brno\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      speakers:\n        - Oliver Morgan\n      description: \"\"\n      video_provider: \"scheduled\"\n      video_id: \"city-pitch-brno-euruko-2025\"\n      id: \"city-pitch-brno-euruko-2025\"\n\n    - title: \"City Pitch: Coimbra\"\n      raw_title: \"City Pitch: Coimbra\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      speakers:\n        - TODO\n      description: \"\"\n      video_provider: \"scheduled\"\n      video_id: \"city-pitch-coimbra-euruko-2025\"\n      id: \"city-pitch-coimbra-euruko-2025\"\n\n- title: \"gRPC on Ruby On Rails - a perfect match!\"\n  raw_title: \"gRPC on Ruby On Rails - a perfect match! by Emiliano Della Casa\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  published_at: \"2025-11-10\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Emiliano Della Casa\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"KS-Er7VentM\"\n  id: \"emiliano-della-casa-euruko-2025\"\n\n- title: \"Prioritization justice: lessons from making background jobs fair at scale\"\n  raw_title: \"Prioritization justice: lessons from making background jobs fair at scale by Alexander Baygeldin\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  published_at: \"2025-11-10\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Alexander Baygeldin\n  description: |-\n    Are you treating your users fairly? They could be stuck in the queue while a greedy user monopolizes resources. And you might not even know it! In this talk, you'll see if its time for you to take background job prioritization seriously--and how to make it fair for all users.\n  video_provider: \"youtube\"\n  video_id: \"Gzdl5hscPqE\"\n  id: \"alexander-baygeldin-euruko-2025\"\n\n- title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks – Community Voices & Ruby Sparks\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  time: \"13:30 - 15:45\"\n  published_at: \"2025-11-10\"\n  description: |-\n    A mix of scheduled brilliance and spontaneous inspiration, this lightning talk session brought together voices from across the Ruby community. Some speakers signed up in advance — others stepped up on the spot. The result? Fast-paced, passionate talks straight from the heart of Ruby.\n  video_provider: \"youtube\"\n  video_id: \"sgAysDO3mwU\"\n  id: \"lightning-talks-euruko-2025\"\n  talks:\n    - title: \"Lightning Talk: Mind your business – configure your app with Fino\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"00:10\"\n      end_cue: \"03:44\"\n      thumbnail_cue: \"00:12\"\n      id: \"egor-iskrenkov-lightning-talk-euruko-2025\"\n      video_id: \"egor-iskrenkov-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Egor Iskrenkov\n\n    - title: \"Lightning Talk: Baltic Ruby x Ruby Unconf — double everything at your community event\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"03:49\"\n      end_cue: \"09:43\"\n      thumbnail_cue: \"03:49\"\n      id: \"ali-krynitsky-lightning-talk-euruko-2025\"\n      video_id: \"ali-krynitsky-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Ali Krynitsky\n\n    - title: \"Lightning Talk: You should also make a game with Ruby\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"09:49\"\n      end_cue: \"14:32\"\n      thumbnail_cue: \"09:54\"\n      id: \"kim-burgestrand-lightning-talk-euruko-2025\"\n      video_id: \"kim-burgestrand-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Kim Burgestrand\n\n    - title: \"Lightning Talk: Ruby Europe\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"14:37\"\n      end_cue: \"20:56\"\n      thumbnail_cue: \"14:39\"\n      id: \"mariusz-koziel-lightning-talk-euruko-2025\"\n      video_id: \"mariusz-koziel-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Mariusz Kozieł\n\n    - title: \"Lightning Talk: Conditional Organizer\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"21:00\"\n      end_cue: \"24:43\"\n      thumbnail_cue: \"21:05\"\n      id: \"gamberi-elia-lightning-talk-euruko-2025\"\n      video_id: \"gamberi-elia-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Elia Gamberi\n\n    - title: \"Lightning Talk: Let's fine-tune a model!\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"24:48\"\n      end_cue: \"29:59\"\n      thumbnail_cue: \"24:53\"\n      id: \"chris-hasinski-lightning-talk-euruko-2025\"\n      video_id: \"chris-hasinski-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Hasiński\n\n    - title: \"Lightning Talk: Papercraft – functional HTML templating for Ruby\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"30:03\"\n      end_cue: \"34:57\"\n      thumbnail_cue: \"30:08\"\n      id: \"sharon-rosner-lightning-talk-euruko-2025\"\n      video_id: \"sharon-rosner-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Sharon Rosner\n\n    - title: \"Lightning Talk: Why Ruby?\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"35:01\"\n      end_cue: \"36:46\"\n      thumbnail_cue: \"35:03\"\n      id: \"yuri-sidorov-lightning-talk-euruko-2025\"\n      video_id: \"yuri-sidorov-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Yuri Sidorov\n\n    - title: \"Lightning Talk: Save hours each week developing Rails apps\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"36:51\"\n      end_cue: \"42:17\"\n      thumbnail_cue: \"41:11\"\n      id: \"andrei-kaleshka-lightning-talk-euruko-2025\"\n      video_id: \"andrei-kaleshka-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrei Kaleshka\n\n    - title: \"Lightning Talk: Are you a team member?\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"42:20\"\n      end_cue: \"47:21\"\n      thumbnail_cue: \"42:25\"\n      id: \"alina-leskova-lightning-talk-euruko-2025\"\n      video_id: \"alina-leskova-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Alina Leskova\n\n    - title: \"Lightning Talk: Do you want to run Ruby on Azure Functions?\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"47:26\"\n      end_cue: \"50:30\"\n      thumbnail_cue: \"47:31\"\n      id: \"david-halasz-lightning-talk-euruko-2025\"\n      video_id: \"david-halasz-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Dávid Halász\n\n    - title: \"Lightning Talk: Hands Free Development\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"50:35\"\n      end_cue: \"55:57\"\n      thumbnail_cue: \"51:31\"\n      id: \"valiantsin-zavadski-lightning-talk-euruko-2025\"\n      video_id: \"valiantsin-zavadski-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Valiantsin Zavadski\n\n    - title: \"Lightning Talk: active_module: Modules and Classes as first-class active record values!\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"56:04\"\n      end_cue: \"01:01:21\"\n      thumbnail_cue: \"56:09\"\n      id: \"pedro-morte-rolo-lightning-talk-euruko-2025\"\n      video_id: \"pedro-morte-rolo-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Pedro Morte Rolo\n\n    - title: \"Lightning Talk: Arch\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"01:01:24\"\n      end_cue: \"01:07:12\"\n      thumbnail_cue: \"01:01:26\"\n      id: \"nicolas-erlichman-lightning-talk-euruko-2025\"\n      video_id: \"nicolas-erlichman-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Nicolas Erlichman\n\n    - title: \"Lightning Talk: Rubycon Italy\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"01:07:15\"\n      end_cue: \"01:13:47\"\n      thumbnail_cue: \"01:07:20\"\n      id: \"riccardo-carlesso-lightning-talk-euruko-2025\"\n      video_id: \"riccardo-carlesso-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Riccardo Carlesso\n\n    - title: \"Lightning Talk: wroclove.rb\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"01:13:52\"\n      end_cue: \"01:17:14\"\n      thumbnail_cue: \"01:14:41\"\n      id: \"zuzanna-kusznir-andrzej-krzywda-lightning-talk-euruko-2025\"\n      video_id: \"zuzanna-kusznir-andrzej-krzywda-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Zuzanna Kusznir\n        - Andrzej Krzywda\n\n    - title: \"Lightning Talk: Thank You, from GoCardless\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"01:17:19\"\n      end_cue: \"01:20:14\"\n      thumbnail_cue: \"01:17:24\"\n      id: \"michael-wawra-lightning-talk-euruko-2025\"\n      video_id: \"michael-wawra-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Wawra\n\n    - title: \"Lightning Talk: SupeRails\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"01:20:18\"\n      end_cue: \"01:22:07\"\n      thumbnail_cue: \"01:20:23\"\n      id: \"yaroslav-shmarov-lightning-talk-euruko-2025\"\n      video_id: \"yaroslav-shmarov-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Yaroslav Shmarov\n\n    - title: \"Lightning Talk: RubyConf Austria\"\n      event_name: \"EuRuKo 2025\"\n      date: \"2025-09-19\"\n      published_at: \"2025-11-10\"\n      start_cue: \"01:22:10\"\n      end_cue: \"01:23:33\"\n      thumbnail_cue: \"01:22:31\"\n      id: \"muhamed-isabegovic-lightning-talk-euruko-2025\"\n      video_id: \"muhamed-isabegovic-lightning-talk-euruko-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Muhamed Isabegović\n\n- title: \"Workshop: PicoRuby Hands-on: Internet of Things Edition\"\n  raw_title: \"Workshop: PicoRuby Hands-on: Internet of Things Edition by Hitoshi Hasumi\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  time: \"13:30 - 15:45\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Hitoshi Hasumi\n  description: |-\n    The hugely popular PicoRuby workshop from EuRuKo 2024 is back again this year!\n\n    No prior experience with microcontrollers? No problem!\n\n    This talk starts from the basics and introduces you to practical applications.\n\n    The 2025 edition includes exciting new content, such as WiFi networking and BLE, providing insights into transforming your Ruby code into a true IoT solution.\n  video_provider: \"not_recorded\"\n  video_id: \"hitoshi-hasumi-euruko-2025\"\n  id: \"hitoshi-hasumi-euruko-2025\"\n\n- title: \"Workshop: Smoke and Mirrors: the Tricks Behind Magical Ruby Interfaces\"\n  raw_title: \"Workshop: Smoke and Mirrors: the Tricks Behind Magical Ruby Interfaces by Joel Drapper\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  time: \"13:30 - 15:45\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Joel Drapper\n  description: |-\n    Ruby feels like magic, but every magic trick can be learned.  Bridging programming and meta-programming, this is a practical technical talk/workshop about the patterns and interfaces you can implement to make your own magical APIs in Ruby.\n  video_provider: \"not_recorded\"\n  video_id: \"joel-drapper-euruko-2025\"\n  id: \"joel-drapper-euruko-2025\"\n\n- title: \"Workshop: How to improve your own and others code\"\n  raw_title: \"Workshop: How to improve your own and others code by Fritz Meissner\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  time: \"13:30 - 15:45\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Fritz Meissner\n  description: |-\n    Wish you worked with understandable and easily changeable code? Practice fixing the incomprehensible in an interactive, zero-background-required exercise on the career-changing topic of refactoring. Bonus: take it home! Learn how to run your own coding exercise to spread the knowledge even further.\n  video_provider: \"not_recorded\"\n  video_id: \"fritz-meissner-euruko-2025\"\n  id: \"fritz-meissner-euruko-2025\"\n\n- title: \"Workshop: Dont Let Your AI Guess: Teach It to Test!\"\n  raw_title: \"Workshop: Dont Let Your AI Guess: Teach It to Test! by Lucian Ghinda\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  time: \"13:30 - 15:45\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Lucian Ghinda\n  description: |-\n    Stop letting AI guess your tests! Learn how to guide LLMs like ChatGPT to write smarter, bug-catching tests using proven test design techniques--built for the way Ruby devs think, test, and ship fast.\n  video_provider: \"not_recorded\"\n  video_id: \"lucian-ghinda-euruko-2025\"\n  id: \"lucian-ghinda-euruko-2025\"\n\n- title: \"Workshop: What Really Happens When You `Thread.new`\"\n  raw_title: \"Workshop: What Really Happens When You `Thread.new` by Dmitrijs Zubriks\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  time: \"13:30 - 15:45\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Dmitrijs Zubriks\n  description: |-\n    This workshop peels back the layers of Ruby MRI to reveal what is really happening beneath the language's abstractions. Using Thread.new call as a starting point, the session dives deep into CRuby's internals - not with a high-level overview of concurrency models, but with a practical look at the underlying machinery in action.\n\n    The entire execution path will be traced, beginning with a single line of Ruby code. The process will be followed as it's transformed into YARV bytecode, creates a native OS thread, and interacts with the VM's core scheduling components.\n\n    Along the way, participants will gain an understanding of the functions that manage a thread's lifecycle and how Ruby interacts with the operating system behind the scenes. Modern observability tools will be used to make these internal processes visible. By the end of the workshop, attendees will have an intuitive mental model of how CRuby works.\n  video_provider: \"not_recorded\"\n  video_id: \"dmitrijs-zubriks-euruko-2025\"\n  id: \"dmitrijs-zubriks-euruko-2025\"\n\n- title: \"Workshop: Hands-on with Message Queues: Build and Connect Microservices with AMQP\"\n  raw_title: \"Workshop: Hands-on with Message Queues: Build and Connect Microservices with AMQP by Anders Bälter and Patrik Ragnarsson\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  time: \"13:30 - 15:45\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Anders Bälter\n    - Patrik Ragnarsson\n  description: |-\n    This workshop covers the basics of building applications with a microservice architecture. Youll learn how services communicate using message brokers and how to implement this with LavinMQ and AMQP. Through hands-on exercises, youll gain practical experience in designing scalable, decoupled systems that handle real-world messaging patterns. Perfect for anyone looking to get started or refine their approach to microservices.\n  video_provider: \"not_recorded\"\n  video_id: \"anders-balter-patrik-ragnarsson-euruko-2025\"\n  id: \"anders-balter-patrik-ragnarsson-euruko-2025\"\n\n- title: \"Navigating Uncharted Waters: Coding Agents and Tooling Evolution\"\n  raw_title: '[Euruko 2025] \"Navigating Uncharted Waters: Coding Agents and Tooling Evolution\" – José Valim'\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  published_at: \"2025-11-23\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - José Valim\n  description: |-\n    As AI becomes increasingly integrated into software development, we find ourselves facing questions about how our programming languages and tools should evolve - questions that dont yet have clear answers. Rather than prescribing solutions, this talk explores possible directions that developers and tooling authors should be grappling with.\n  video_provider: \"youtube\"\n  video_id: \"GDzaWiFF8Qk\"\n  id: \"jose-valim-euruko-2025\"\n\n- title: \"Making Rails AI-Native with the Model Context Protocol\"\n  raw_title: \"Making Rails AI-Native with the Model Context Protocol by Paweł Strzałkowski\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  published_at: \"2025-11-10\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Paweł Strzałkowski\n  description: |-\n    Remember Rails scaffold magic? Now, scaffold AI interactions! See how Rails + the Model Context Protocol standard unlock your apps core features for AI agents. This is the Ruby competitive advantage for the AI era: make your app AI-native effortlessly!\n  video_provider: \"youtube\"\n  video_id: \"1gYGfiUBsEY\"\n  id: \"pawel-strzalkowski-euruko-2025\"\n\n- title: \"Closing Keynote: The Myth of the Modular Monolith\"\n  raw_title: \"Closing Keynote by Eileen M. Uchitelle\"\n  event_name: \"EuRuKo 2025\"\n  date: \"2025-09-19\"\n  published_at: \"2025-11-10\"\n  announced_at: \"2025-05-24\"\n  speakers:\n    - Eileen M. Uchitelle\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"F5BkAaM1t_Q\"\n  id: \"eileen-m-uchitelle-euruko-2025\"\n"
  },
  {
    "path": "data/euruko/euruko-2026/event.yml",
    "content": "---\nid: \"euruko-2026\"\ntitle: \"EuRuKo 2026\"\nkind: \"conference\"\nlocation: \"Brno, Czechia\"\ndescription: \"\"\npublished_at: \"\"\nstart_date: \"2026-09-16\"\nend_date: \"2026-09-18\"\nchannel_id: \"UCgXsZr2e0AgUJMZm5t03WVw\"\nyear: 2026\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#EE0024\"\nwebsite: \"https://2026.euruko.org\"\nvenue: \"Hotel Passage\"\ncoordinates:\n  latitude: 49.202154\n  longitude: 16.6070931\n"
  },
  {
    "path": "data/euruko/euruko-2026/venue.yml",
    "content": "# https://www.hotelpassage.eu/en/\n---\nname: \"Hotel Passage\"\naddress:\n  street: \"23 Lidická\"\n  city: \"Brno\"\n  region: \"Jihomoravský kraj\"\n  postal_code: \"602 00\"\n  country: \"Czechia\"\n  country_code: \"CZ\"\n  display: \"Lidická 23, 602 00 Brno, Czechia\"\ncoordinates:\n  latitude: 49.202154\n  longitude: 16.6070931\nmaps:\n  google: \"https://maps.google.com/?q=Hotel+Passage,49.202154,16.6070931\"\n  apple: \"https://maps.apple.com/?q=Hotel+Passage&ll=49.202154,16.6070931\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=49.202154&mlon=16.6070931\"\n"
  },
  {
    "path": "data/euruko/euruko-2026/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/euruko/noruko-2020/event.yml",
    "content": "---\nid: \"PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\"\ntitle: \"NoRuKo 2020\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  NoRuKo 2020 is a virtual mini-conference filling a bit of the void all the cancelled and postponed events created. The name is a play on the biggest European Ruby Conference, \"EuRuKo\"\npublished_at: \"2020-08-24\"\nstart_date: \"2020-08-21\"\nend_date: \"2020-08-21\"\nchannel_id: \"UCyExf-593j4hjN_cFCSnr2w\"\nyear: 2020\nbanner_background: \"linear-gradient(170deg, #ffddfb 40%, #ffb3a1)\"\nfeatured_background: \"linear-gradient(170deg, #ffddfb 40%, #ffb3a1)\"\nfeatured_color: \"#000000\"\nwebsite: \"https://noruko.rubynl.org\"\ncoordinates: false\n"
  },
  {
    "path": "data/euruko/noruko-2020/videos.yml",
    "content": "---\n# Website:  https://noruko.rubynl.org\n# Schedule: https://noruko.rubynl.org/#schedule\n\n- id: \"rayta-van-rijswijk-noruko-2020\"\n  title: \"Welcome and Introduction\"\n  raw_title: \"#NoRuKo welcome and introduction\"\n  speakers:\n    - Rayta van Rijswijk\n    - Ramón Huidobro\n    - Arno Fleming\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    In this video, an introduction to #NoRuKo, explanation of the schedule and tracks.\n\n    A thank you to our #NoRuKo sponsors:\n\n    - Fullstaq - https://fullstaq.com - Hosting sponsor\n    - AppSignal - https://appsignal.com - Accessibility sponsor\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"\"\n  video_provider: \"youtube\"\n  video_id: \"kadEbkLLLAQ\"\n\n- id: \"yukihiro-matz-matsumoto-noruko-2020\"\n  title: \"Ruby 3 and beyond\"\n  raw_title: \"Ruby3 and beyond by Yukihiro Matsumoto | #NoRuKo 2020\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    Ruby3 is coming! The creator of the language himself explains what is coming with Ruby3. In addition, what will happen after Ruby3.0! \n\n    Yukihiro Matsumoto is the creator of Ruby. What can we really say to introduce Matz better than previous line?\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"\"\n  video_provider: \"youtube\"\n  video_id: \"-MohBT-xwbg\"\n\n- id: \"penelope-phippen-noruko-2020\"\n  title: \"Building Rubyfmt\"\n  raw_title: \"Building Rubyfmt by Penelope Phippen | #NoRuKo 2020\"\n  speakers:\n    - Penelope Phippen\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    In this talk I'll discuss Rubyfmt, a work in progress Ruby autoformatter. Why I'm building it, and how it differs from Rubocop, the closest similar tool that you might be familiar with. I'll get deep in to the weeds on some of the technical challenges of building a system like this, and what the overall goals for the project are.\n\n    Penelope Phippen makes Rubyfmt, and was previously a lead maintainer of the Rspec testing framework. She's been writing Ruby for just about a decade, and still remembers writing Ruby for 1.8.6.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Main\"\n  video_provider: \"youtube\"\n  video_id: \"0R3FO666Jzk\"\n\n- id: \"phil-nash-noruko-2020\"\n  title: \"Fantastic Passwords and Where to Find Them\"\n  raw_title: \"Fantastic Passwords and Where to Find Them by Phil Nash | #NoRuKo 2020\"\n  speakers:\n    - Phil Nash\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    The humble password is broken. The internet is littered with poor security practices and password breaches, but the world is not ready to go password free yet. So what can we do to protect our users? Let's take a look at how we currently protect passwords, at what we can throw away from those processes and what we can bring in to help strengthen our users' passwords. We'll investigate the tools, practices and APIs that can help us in this endeavour. Together we can move the world from *password1* to *correct horse battery staple* and beyond! \n\n    Phil is a developer evangelist for Twilio and a Google Developer Expert. He's been in the web industry for 10 years building with JavaScript and Ruby. He can be found hanging out at meetups and conferences, playing with new technologies and APIs or writing open source code online. Sometimes he makes his own beer, but he's more likely to be found discovering new ones around the world.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Community Track\"\n  video_provider: \"youtube\"\n  video_id: \"SbmSlUcAezc\"\n\n- id: \"tetiana-chupryna-noruko-2020\"\n  title: \"Ruby + OpenGL = infinite abilities\"\n  raw_title: \"Ruby + OpenGL = infinite abilities by Tetiana Chupryna | #NoRuKo 2020\"\n  speakers:\n    - Tetiana Chupryna\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    In this talk we’ll explore what can we create using Ruby and OpenGL. We’ll talk about drawing pictures, designing animations and building interfaces. You’ll learn about the basics of OpenGL and eventually, how you can build your own game engine.\n\n    Tetiana Chupryna is a Backend Engineer at GitLab where she is working on security analysis. At my spare time, she likes drawing or painting with any materials available.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Main\"\n  video_provider: \"youtube\"\n  video_id: \"DIShTUHEpxs\"\n\n- id: \"ali-ilman-noruko-2020\"\n  title: \"Type Checking with Sorbet\"\n  raw_title: \"Type Checking with Sorbet by Ali Ilman | #NoRuKo 2020\"\n  speakers:\n    - Ali Ilman\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    If you enjoy building projects using TypeScript, you probably wish you could build Ruby projects with a type checker. I've been in that boat! Recently, I stumbled upon Sorbet, a well-maintained type checker for Ruby. In this talk, we'll take a look at how we can use Sorbet. \n\n    Ali Ilman is a software engineer from Malaysia. He works for Suria Labs as a full-stack developer. He writes Ruby and JavaScript and other than these technologies, he's getting his hands dirty with Docker and Kubernetes. He loves TDD and service objects. In his free time, he tends to have his head buried in a book.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Community Track\"\n  video_provider: \"youtube\"\n  video_id: \"tsxip-zexJY\"\n\n- id: \"penelope-phippen-noruko-2020-speaker-panel-main-track\"\n  title: \"Speaker Panel: Main Track\"\n  raw_title: \"Speaker panel 1 - Main track | #NoRuKo 2020\"\n  speakers:\n    - Penelope Phippen\n    - Tetiana Chupryna\n    - Ramón Huidobro\n    - Rayta van Rijswijk\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    Penelope and Tetiana talk through the first part of the day, with the NoRuKo hosts. \n\n    Penelope Phippen makes Rubyfmt, and was previously a lead maintainer of the Rspec testing framework. She's been writing Ruby for just about a decade, and still remembers writing Ruby for 1.8.6.\n    Tetiana Chupryna is a Backend Engineer at GitLab where she is working on security analysis. At my spare time, she likes drawing or painting with any materials available.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Main\"\n  video_provider: \"youtube\"\n  video_id: \"mcZUFNCXxUk\"\n\n- id: \"victor-shepelev-noruko-2020\"\n  title: \"The struggle for better documentation for Ruby itselfby\"\n  raw_title: \"The struggle for better documentation for Ruby itselfby Victor Shepelev | #NoRuKo 2020\"\n  speakers:\n    - Victor Shepelev\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    Ruby is known to be \"complex language for writing simple code\" and \"designed to make programmers happy\". Yet while those principles are fully embodied in the language spirit and logic, the documentation is traditionally more problematic, especially for newcomers who are already programming-literate and expect a quick and deep dive. Let's talk about several aspects of language and standard library documentation, its history, current state, and the future, expectations it should ideally meet and some unfortunate road bumps. \n\n    Victor Shepelev is an Ukrainian programmer and poet with twelve years of programming experience and fifteen years of Ruby programming. Working at Verbit.ai, mentoring students (including Google Summer of Code-2016-2018, as a mentor for SciRuby organization), developing open source (Ruby Association Grant 2015).\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Community Track\"\n  video_provider: \"youtube\"\n  video_id: \"2VVEcOyeYLA\"\n\n- id: \"jan-krutisch-noruko-2020\"\n  title: \"Musical Intermezzo: half/byte & NERDDISCO\"\n  raw_title: \"half/byte & NERDDISCO @ NoRuKo 2020\"\n  speakers:\n    - Jan Krutisch\n    - Tim Pietrusky\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-08-23\"\n  description: |-\n    We had the honor to perform at NoRuKo 2020 in the 18:00 break and it was very cool. half/byte created most of his sound with Ruby and combined this with some custom audio samples. NERDDISCO had a ruby shader (aka diamond) in combination with a rainbow nebula as the main visual element.\n\n    ### Event\n\n    NoRuKo 2020, https://noruko.rubynl.org/\n\n    ###  Artists\n    \\\n    Music: half/byte, https://halfbyte.org\n    Visuals: NERDDISCO, https://nerddis.co \n\n    ### Credits\n\n    - \"A lonely Diamond...\" by Nrx, https://www.shadertoy.com/view/ltfXDM\n    - \"Perlin noise Nebula\" by Lea Rosema, https://codepen.io/terabaud/pen/mdPVewg\n  track: \"\"\n  video_provider: \"youtube\"\n  video_id: \"XntC412ETgM\"\n\n- id: \"tom-de-bruijn-noruko-2020\"\n  title: \"Git is about communication\"\n  raw_title: \"Git is about communication by Tom de Bruijn | #NoRuKo 2020\"\n  speakers:\n    - Tom de Bruijn\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    Git is about talking to your team. It’s about talking to yourself, from the future. What about that colleague who hasn’t even joined the team yet? Yes, them too. But how to be \"good at Git\"?\n\n    Tom de Bruijn is a developer at AppSignal, writing in Ruby, Rust, Elixir and JavaScript. Tom writes novels in his free time, which he'll probably publish... one day. Tom helps organize the monthly Amsterdam Ruby meetup, Rails Girls Netherlands events, and previously the EuRuKo 2019 Rotterdam conference.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Main\"\n  video_provider: \"youtube\"\n  video_id: \"yp9ddMU2Q3Q\"\n\n- id: \"sian-griffin-noruko-2020\"\n  title: \"Learning Empathy From Pokemon Blue\"\n  raw_title: \"Learning Empathy From Pokemon Blue by Siân Griffin | #NoRuKo 2020\"\n  speakers:\n    - Siân Griffin\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    Have you ever looked at a bug and wondered why it actually happens? It's easy to chalk it up to sloppy coding but that's almost never the case. In this talk we'll be dissecting a exploit from Pokemon Blue known as the \"Missingno\" glitch. We'll look at the details of each of the seemingly random bugs behind this exploit. We'll look at why these bugs happened, and the lessons we can apply to our Ruby code more than 20 years later.\n\n    Siân Griffin is a former Rails committer, and co-leads the team responsible for crates.io, the package repository for Rust.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Community Track\"\n  video_provider: \"youtube\"\n  video_id: \"Otky83cVLUw\"\n\n- id: \"allison-mcmillan-noruko-2020\"\n  title: \"Everything is 🔥fine🔥\"\n  raw_title: \"Everything is 🔥fine🔥 by Allison McMillan | #NoRuKo 2020\"\n  speakers:\n    - Allison McMillan\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    Working during a global pandemic offers unique challenges. Parents, in particular, are facing a world of new responsibilities resulting in burn out, information overload, and other COVID side effects. The only question is what will break first… parents or the way we work?\n\n    Allison McMillan is director of Engineering at GitHub. Developer. Mom. Speaker. Former Rails Girls Washington org. @parentdrivendev podcast creator.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Main\"\n  video_provider: \"youtube\"\n  video_id: \"7FLu78t5-sM\"\n\n- id: \"miriam-tocino-noruko-2020\"\n  title: \"Zerus & Ona A warm welcome to the world of computers\"\n  raw_title: \"Zerus & Ona A warm welcome to the world of computers by Miriam Tocino | #NoRuKo 2020\"\n  speakers:\n    - Miriam Tocino\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    Miriam Tocino shares the idea behind Zerus & Ona — her unique book series designed to get young children excited about technology through the power of books. \n\n    Miriam is a coding teacher, programmer, and mom dedicated to making computers more approachable, friendly, and easy to understand. She is the author of Zerus & Ona, a book series that teaches young children about the digital world without the need for a screen.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Community Track\"\n  video_provider: \"youtube\"\n  video_id: \"IIvs63L8IiY\"\n\n- id: \"julik-tarkhanov-noruko-2020\"\n  title: \"Sleeping on the job\"\n  raw_title: \"Sleeping on the job by Julik Tarkhanov & Kir Shatrov | #NoRuKo 2020\"\n  speakers:\n    - Julik Tarkhanov\n    - Kir Shatrov\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    We all love our Sidekiq’s and our Resque’s. But they do let us down sometimes. Not because they are bad, but because the queueing theory is limiting us. There is a way to break out of the madness though - let’s explore how to get our job queues under control. \n\n    Kir Shatrov is a platform engineer at Shopify where he works on scalability and reliability of one of the world’s largest ecommerce platforms. When not into working, Kir enjoys cooking, gastronomic tourism (he even has a GitHub repo with his favourite spots!) and exploring London on the bike.\n    Julik Tarkhanov is a software developer at WeTransfer where he is responsible for the backend components of the Transfer product, enabling effortless transfer of creative ideas. Prior to WeTransfer he worked in the visual effects industry creating images that inspire and befuddle. On his free time he explores weird user interfaces and plays trumpet.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Main\"\n  video_provider: \"youtube\"\n  video_id: \"aEVVbFn0_A4\"\n\n- id: \"amr-abdelwahab-noruko-2020\"\n  title: \"Dockerization in the land of Ruby\"\n  raw_title: \"Dockerization in the land of Ruby by Amr Abdelwahab | #NoRuKo 2020\"\n  speakers:\n    - Amr Abdelwahab\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    Whether you have never seen a dockerfile in your life or you have been working on a daily basis with docker in different environments, join this talk to learn some tips and tricks on improving your docker setup all the way from development to live environments passing through continuous integration. \n\n    Amr's is an African Egyptian native who crossed continents to work with his passion in digital environments.  His interests span technology, tech-communities, politics and politics in tech, all enriched through various software engineering roles in Egypt, Hungary and Germany. In Berlin he's a co-organiser of RUG::B and code curious (Formerly known as Rails Girls Berlin)\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"Community Track\"\n  video_provider: \"youtube\"\n  video_id: \"ua6tJ9d8pE8\"\n\n- id: \"tom-de-bruijn-noruko-2020-speaker-panel-main-track\"\n  title: \"Speaker Panel: Main Track\"\n  raw_title: \"Speaker panel 2 - Main track | #NoRuKo 2020\"\n  speakers:\n    - Tom de Bruijn\n    - Julik Tarkhanov\n    - Kir Shatrov\n    - Ramón Huidobro\n    - Rayta van Rijswijk\n  event_name: \"NoRuKo 2020\"\n  date: \"2020-08-21\"\n  published_at: \"2020-09-11\"\n  description: |-\n    Tom, Julik and Kir talk through the second part of the day, with the NoRuKo hosts.\n\n    - Tom de Bruijn is a developer at AppSignal, writing in Ruby, Rust, Elixir and JavaScript. Tom writes novels in his free time, which he'll probably publish... one day. Tom helps organize the monthly Amsterdam Ruby meetup, Rails Girls Netherlands events, and previously the EuRuKo 2019 Rotterdam conference.\n    - Kir Shatrov is a platform engineer at Shopify where he works on scalability and reliability of one of the world’s largest ecommerce platforms. When not into working, Kir enjoys cooking, gastronomic tourism (he even has a GitHub repo with his favourite spots!) and exploring London on the bike.\n    - Julik Tarkhanov is a software developer at WeTransfer where he is responsible for the backend components of the Transfer product, enabling effortless transfer of creative ideas. Prior to WeTransfer he worked in the visual effects industry creating images that inspire and befuddle. On his free time he explores weird user interfaces and plays trumpet.\n\n    Welcome to the #NoRuKo conference. A virtual unconference organized by Stichting Ruby NL.\n\n    #NoRuKo playlist with all talks and panels: https://www.youtube.com/playlist?list=PL9_A7olkztLlmJIAc567KQgKcMi7-qnjg\n\n    Recorded 21th of August, 2020.\n    NoRuKo website: https://noruko.rubynl.org/\n    Stichting Ruby NL website: https://rubynl.org/\n  track: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ngL-WJTJyEs\"\n# Afterparty / #Quaraoke (virtual karaoke)\n"
  },
  {
    "path": "data/euruko/series.yml",
    "content": "---\nname: \"EuRuKo\"\nwebsite: \"https://euruko.org\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"DE\"\nyoutube_channel_name: \"EuRuKo\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCgXsZr2e0AgUJMZm5t03WVw\"\naliases:\n  - Europäische Ruby Konferenz\n  - European Ruby Konferenz\n  - European Ruby Conference\n  - European Ruby Conf\n  - EURUKO\n"
  },
  {
    "path": "data/featured_cities.yml",
    "content": "---\n- name: \"Amsterdam\"\n  slug: \"amsterdam\"\n  state_code: \"NH\"\n  country_code: \"NL\"\n  latitude: 52.3676\n  longitude: 4.9041\n  aliases:\n    - ams\n    - adam\n\n- name: \"Atlanta\"\n  slug: \"atlanta\"\n  state_code: \"GA\"\n  country_code: \"US\"\n  latitude: 33.7501\n  longitude: -84.3885\n  aliases:\n    - atl\n\n- name: \"Auckland\"\n  slug: \"auckland\"\n  state_code: \"Auckland\"\n  country_code: \"NZ\"\n  latitude: -36.8509\n  longitude: 174.7645\n  aliases:\n    - akl\n\n- name: \"Austin\"\n  slug: \"austin\"\n  state_code: \"TX\"\n  country_code: \"US\"\n  latitude: 30.2672\n  longitude: -97.7431\n  aliases:\n    - aus\n    - atx\n\n- name: \"Bangkok\"\n  slug: \"bangkok\"\n  state_code: \"Bangkok\"\n  country_code: \"TH\"\n  latitude: 13.7563\n  longitude: 100.5018\n  aliases:\n    - bkk\n\n- name: \"Basel\"\n  slug: \"basel\"\n  state_code: \"BS\"\n  country_code: \"CH\"\n  latitude: 47.5596\n  longitude: 7.5886\n  aliases:\n    - bsl\n    - Bâle\n    - Bale\n\n- name: \"Barcelona\"\n  slug: \"barcelona\"\n  state_code: \"CT\"\n  country_code: \"ES\"\n  latitude: 41.3874\n  longitude: 2.1686\n  aliases:\n    - bcn\n    - barna\n\n- name: \"Berlin\"\n  slug: \"berlin\"\n  state_code: \"BE\"\n  country_code: \"DE\"\n  latitude: 52.52\n  longitude: 13.405\n  aliases:\n    - ber\n\n- name: \"Birmingham\"\n  slug: \"birmingham\"\n  state_code: \"ENG\"\n  country_code: \"GB\"\n  latitude: 52.4823\n  longitude: -1.89\n  aliases:\n    - brum\n\n- name: \"Boston\"\n  slug: \"boston\"\n  state_code: \"MA\"\n  country_code: \"US\"\n  latitude: 42.3555\n  longitude: -71.0565\n  aliases:\n    - bos\n\n- name: \"Brighton\"\n  slug: \"brighton\"\n  state_code: \"ENG\"\n  country_code: \"GB\"\n  latitude: 50.8225\n  longitude: -0.1372\n\n- name: \"Brussels\"\n  slug: \"brussels\"\n  state_code: \"BRU\"\n  country_code: \"BE\"\n  latitude: 50.8260\n  longitude: 4.3802\n  aliases:\n    - bru\n    - Bruxelles\n    - Brussel\n\n- name: \"Budapest\"\n  slug: \"budapest\"\n  state_code:\n  country_code: \"HU\"\n  latitude: 47.4979\n  longitude: 19.0402\n  aliases:\n    - bud\n\n- name: \"Buenos Aires\"\n  slug: \"buenos-aires\"\n  state_code: \"Buenos Aires\"\n  country_code: \"AR\"\n  latitude: -34.6037\n  longitude: -58.3821\n  aliases:\n    - ba\n    - bsas\n\n- name: \"Chicago\"\n  slug: \"chicago\"\n  state_code: \"IL\"\n  country_code: \"US\"\n  latitude: 41.8781\n  longitude: -87.6298\n  aliases:\n    - chi\n    - chi-town\n    - chitown\n\n- name: \"Copenhagen\"\n  slug: \"copenhagen\"\n  state_code:\n  country_code: \"DK\"\n  latitude: 55.6761\n  longitude: 12.5683\n  aliases:\n    - cph\n    - Kobenhavn\n    - København\n\n- name: \"Dallas\"\n  slug: \"dallas\"\n  state_code: \"TX\"\n  country_code: \"US\"\n  latitude: 32.7767\n  longitude: -96.797\n  aliases:\n    - dfw\n    - Dallas-Fort Worth\n    - Fort Worth\n\n- name: \"Denver\"\n  slug: \"denver\"\n  state_code: \"CO\"\n  country_code: \"US\"\n  latitude: 39.7392\n  longitude: -104.9903\n  aliases:\n    - den\n\n- name: \"Detroit\"\n  slug: \"detroit\"\n  state_code: \"MI\"\n  country_code: \"US\"\n  latitude: 42.3297\n  longitude: -83.0425\n  aliases:\n    - det\n\n- name: \"Edinburgh\"\n  slug: \"edinburgh\"\n  state_code: \"SCT\"\n  country_code: \"GB\"\n  latitude: 55.9533\n  longitude: -3.1883\n  aliases:\n    - edin\n\n- name: \"Geneva\"\n  slug: \"geneva\"\n  state_code: \"GE\"\n  country_code: \"CH\"\n  latitude: 46.2044\n  longitude: 6.1432\n  aliases:\n    - gva\n    - Geneve\n    - Genève\n\n- name: \"Helsinki\"\n  slug: \"helsinki\"\n  state_code: \"Uusimaa\"\n  country_code: \"FI\"\n  latitude: 60.1699\n  longitude: 24.9384\n  aliases:\n    - hel\n\n- name: \"Hong Kong\"\n  slug: \"hong-kong\"\n  state_code:\n  country_code: \"HK\"\n  latitude: 22.3193\n  longitude: 114.1694\n  aliases:\n    - hk\n    - hongkong\n\n- name: \"Houston\"\n  slug: \"houston\"\n  state_code: \"TX\"\n  country_code: \"US\"\n  latitude: 29.7601\n  longitude: -95.3701\n  aliases:\n    - hou\n\n- name: \"Kraków\"\n  slug: \"krakow\"\n  state_code: \"Lesser Poland Voivodeship\"\n  country_code: \"PL\"\n  latitude: 50.0647\n  longitude: 19.9450\n  aliases:\n    - krk\n    - Krakow\n    - Cracow\n\n- name: \"Kuala Lumpur\"\n  slug: \"kuala-lumpur\"\n  state_code: \"Federal Territory of Kuala Lumpur\"\n  country_code: \"MY\"\n  latitude: 3.1319\n  longitude: 101.6841\n  aliases:\n    - kl\n\n- name: \"Las Vegas\"\n  slug: \"las-vegas\"\n  state_code: \"NV\"\n  country_code: \"US\"\n  latitude: 36.1716\n  longitude: -115.1391\n  aliases:\n    - vegas\n    - lv\n\n- name: \"Lisbon\"\n  slug: \"lisbon\"\n  state_code: \"Lisbon\"\n  country_code: \"PT\"\n  latitude: 38.7223\n  longitude: -9.1393\n  aliases:\n    - lis\n    - Lisboa\n\n- name: \"London\"\n  slug: \"london\"\n  state_code: \"ENG\"\n  country_code: \"GB\"\n  latitude: 51.5074\n  longitude: -0.1278\n  aliases:\n    - ldn\n    - lon\n\n- name: \"Los Angeles\"\n  slug: \"los-angeles\"\n  state_code: \"CA\"\n  country_code: \"US\"\n  latitude: 34.0549\n  longitude: -118.2426\n  aliases:\n    - la\n\n- name: \"Madrid\"\n  slug: \"madrid\"\n  state_code: \"MD\"\n  country_code: \"ES\"\n  latitude: 40.4167\n  longitude: -3.7033\n  aliases:\n    - mad\n\n- name: \"Manchester\"\n  slug: \"manchester\"\n  state_code: \"ENG\"\n  country_code: \"GB\"\n  latitude: 53.4808\n  longitude: -2.2426\n  aliases:\n    - manc\n\n- name: \"Melbourne\"\n  slug: \"melbourne\"\n  state_code: \"VIC\"\n  country_code: \"AU\"\n  latitude: -37.8136\n  longitude: 144.9631\n  aliases:\n    - mel\n    - melb\n\n- name: \"Mexico City\"\n  slug: \"mexico-city\"\n  state_code: \"CDMX\"\n  country_code: \"MX\"\n  latitude: 19.4326\n  longitude: -99.1332\n  aliases:\n    - cdmx\n    - df\n    - Ciudad de Mexico\n    - Ciudad de México\n\n- name: \"Miami\"\n  slug: \"miami\"\n  state_code: \"FL\"\n  country_code: \"US\"\n  latitude: 25.7617\n  longitude: -80.1918\n  aliases:\n    - MIA\n\n- name: \"Minneapolis\"\n  slug: \"minneapolis\"\n  state_code: \"MN\"\n  country_code: \"US\"\n  latitude: 44.9778\n  longitude: -93.265\n  aliases:\n    - MSP\n    - Twin cities\n    - St Paul\n    - Saint Paul\n    - Minneapolis-Saint Paul\n\n- name: \"Montréal\"\n  slug: \"montreal\"\n  state_code: \"QC\"\n  country_code: \"CA\"\n  latitude: 45.5019\n  longitude: -73.5674\n  aliases:\n    - MTL\n    - YUL\n    - Montreal\n\n- name: \"Munich\"\n  slug: \"munich\"\n  state_code: \"BY\"\n  country_code: \"DE\"\n  latitude: 48.1351\n  longitude: 11.5820\n  aliases:\n    - MUC\n    - Munchen\n    - München\n\n- name: \"New Orleans\"\n  slug: \"new-orleans\"\n  state_code: \"LA\"\n  country_code: \"US\"\n  latitude: 29.9509\n  longitude: -90.0758\n  aliases:\n    - NOLA\n\n- name: \"New York\"\n  slug: \"new-york\"\n  state_code: \"NY\"\n  country_code: \"US\"\n  latitude: 40.7128\n  longitude: -74.006\n  aliases:\n    - NYC\n    - NY\n    - New York City\n    - Manhattan\n\n- name: \"Osaka\"\n  slug: \"osaka\"\n  state_code: \"Osaka\"\n  country_code: \"JP\"\n  latitude: 34.6937\n  longitude: 135.5023\n  aliases:\n    - OSA\n\n- name: \"Paris\"\n  slug: \"paris\"\n  state_code: \"IDF\"\n  country_code: \"FR\"\n  latitude: 48.8566\n  longitude: 2.3522\n  aliases:\n    - PAR\n\n- name: \"Philadelphia\"\n  slug: \"philadelphia\"\n  state_code: \"PA\"\n  country_code: \"US\"\n  latitude: 39.9526\n  longitude: -75.1652\n  aliases:\n    - Philly\n    - PHL\n\n- name: \"Portland\"\n  slug: \"portland\"\n  state_code: \"OR\"\n  country_code: \"US\"\n  latitude: 45.5152\n  longitude: -122.6784\n  aliases:\n    - PDX\n\n- name: \"Prague\"\n  slug: \"prague\"\n  state_code: \"Prague\"\n  country_code: \"CZ\"\n  latitude: 50.0755\n  longitude: 14.4378\n  aliases:\n    - PRG\n    - Praha\n\n- name: \"Rio de Janeiro\"\n  slug: \"rio-de-janeiro\"\n  state_code: \"RJ\"\n  country_code: \"BR\"\n  latitude: -22.9068\n  longitude: -43.1729\n  aliases:\n    - RIO\n\n- name: \"Salt Lake City\"\n  slug: \"salt-lake-city\"\n  state_code: \"UT\"\n  country_code: \"US\"\n  latitude: 40.7608\n  longitude: -111.891\n  aliases:\n    - SLC\n    - Salt Lake\n\n- name: \"San Francisco\"\n  slug: \"san-francisco\"\n  state_code: \"CA\"\n  country_code: \"US\"\n  latitude: 37.7749\n  longitude: -122.4194\n  aliases:\n    - SF\n    - Bay Area\n    - San Francisco Bay Area\n    - SF Bay Area\n\n- name: \"São Paulo\"\n  slug: \"sao-paulo\"\n  state_code: \"SP\"\n  country_code: \"BR\"\n  latitude: -23.5558\n  longitude: -46.6396\n  aliases:\n    - SP\n    - Sampa\n    - Sao Paulo\n\n- name: \"Seattle\"\n  slug: \"seattle\"\n  state_code: \"WA\"\n  country_code: \"US\"\n  latitude: 47.6062\n  longitude: -122.3321\n  aliases:\n    - SEA\n\n- name: \"Singapore\"\n  slug: \"singapore\"\n  state_code:\n  country_code: \"SG\"\n  latitude: 1.3521\n  longitude: 103.8198\n  aliases:\n    - SG\n    - SGP\n\n- name: \"Stockholm\"\n  slug: \"stockholm\"\n  state_code: \"Stockholm County\"\n  country_code: \"SE\"\n  latitude: 59.3327\n  longitude: 18.0656\n  aliases:\n    - STO\n    - sthlm\n\n- name: \"Sydney\"\n  slug: \"sydney\"\n  state_code: \"NSW\"\n  country_code: \"AU\"\n  latitude: -33.8688\n  longitude: 151.2093\n  aliases:\n    - SYD\n\n- name: \"Taipei\"\n  slug: \"taipei\"\n  state_code: \"TPE\"\n  country_code: \"TW\"\n  latitude: 25.0330\n  longitude: 121.5654\n  aliases:\n    - TPE\n\n- name: \"Tokyo\"\n  slug: \"tokyo\"\n  state_code: \"Tokyo\"\n  country_code: \"JP\"\n  latitude: 35.6762\n  longitude: 139.6503\n  aliases:\n    - TYO\n\n- name: \"Shibuya\"\n  slug: \"shibuya\"\n  state_code: \"Tokyo\"\n  country_code: \"JP\"\n  latitude: 35.6619707\n  longitude: 139.703795\n\n- name: \"Toronto\"\n  slug: \"toronto\"\n  state_code: \"ON\"\n  country_code: \"CA\"\n  latitude: 43.6548\n  longitude: -79.3884\n  aliases:\n    - YYZ\n\n- name: \"Vancouver\"\n  slug: \"vancouver\"\n  state_code: \"BC\"\n  country_code: \"CA\"\n  latitude: 49.2827\n  longitude: -123.1207\n  aliases:\n    - YVR\n    - Van\n\n- name: \"Vienna\"\n  slug: \"vienna\"\n  state_code:\n  country_code: \"AT\"\n  latitude: 48.2081\n  longitude: 16.3713\n  aliases:\n    - VIE\n    - Wien\n\n- name: \"Warsaw\"\n  slug: \"warsaw\"\n  state_code:\n  country_code: \"PL\"\n  latitude: 52.2297\n  longitude: 21.0122\n  aliases:\n    - WAW\n    - Warszawa\n\n- name: \"Washington\"\n  slug: \"washington\"\n  state_code: \"DC\"\n  country_code: \"US\"\n  latitude: 38.9073\n  longitude: -77.0369\n  aliases:\n    - DC\n    - DMV\n    - Washington DC\n    - Washington D.C\n    - Washington, DC\n    - Washington, D.C\n\n- name: \"Zurich\"\n  slug: \"zurich\"\n  state_code: \"ZH\"\n  country_code: \"CH\"\n  latitude: 47.3769\n  longitude: 8.5417\n  aliases:\n    - ZRH\n    - Zürich\n"
  },
  {
    "path": "data/fosdem/ruby-devroom-at-fosdem-2015/event.yml",
    "content": "---\nid: \"ruby-devroom-at-fosdem-2015\"\ntitle: \"Ruby devroom at FOSDEM 2015\"\ndescription: \"\"\nlocation: \"Brussels, Belgium\"\nkind: \"conference\"\nstart_date: \"2015-01-31\"\nend_date: \"2015-02-01\"\nwebsite: \"http://fosdem-ruby.github.io/\"\ntwitter: \"ruby_fosdem\"\ncoordinates:\n  latitude: 50.8260453\n  longitude: 4.3802052\n"
  },
  {
    "path": "data/fosdem/ruby-devroom-at-fosdem-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://fosdem-ruby.github.io/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/fosdem/ruby-devroom-at-fosdem-2016/event.yml",
    "content": "---\nid: \"ruby-devroom-at-fosdem-2016\"\ntitle: \"Ruby devroom at FOSDEM 2016\"\ndescription: \"\"\nlocation: \"Brussels, Belgium\"\nkind: \"conference\"\nstart_date: \"2016-01-31\"\nend_date: \"2016-01-31\"\nwebsite: \"http://fosdem.rubybelgium.be/\"\ntwitter: \"ruby_fosdem\"\ncoordinates:\n  latitude: 50.8260453\n  longitude: 4.3802052\n"
  },
  {
    "path": "data/fosdem/ruby-devroom-at-fosdem-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://fosdem.rubybelgium.be/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/fosdem/ruby-devroom-at-fosdem-2017/event.yml",
    "content": "---\nid: \"ruby-devroom-at-fosdem-2017\"\ntitle: \"Ruby devroom at FOSDEM 2017\"\ndescription: \"\"\nlocation: \"Brussels, Belgium\"\nkind: \"conference\"\nstart_date: \"2017-02-03\"\nend_date: \"2017-02-04\"\nwebsite: \"http://fosdem.rubybelgium.be/\"\ntwitter: \"ruby_fosdem\"\ncoordinates:\n  latitude: 50.8260453\n  longitude: 4.3802052\n"
  },
  {
    "path": "data/fosdem/ruby-devroom-at-fosdem-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://fosdem.rubybelgium.be/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/fosdem/ruby-devroom-at-fosdem-2024/cfp.yml",
    "content": "---\n- link: \"https://pretalx.fosdem.org/fosdem-2024/cfp\"\n  close_date: \"2023-12-01\"\n"
  },
  {
    "path": "data/fosdem/ruby-devroom-at-fosdem-2024/event.yml",
    "content": "---\nid: \"ruby-devroom-at-fosdem-2024\"\ntitle: \"Ruby devroom at FOSDEM 2024\"\ndescription: \"\"\nlocation: \"Brussels, Belgium\"\nkind: \"conference\"\nstart_date: \"2024-02-03\"\nend_date: \"2024-02-04\"\nwebsite: \"https://fosdem.rubybelgium.be\"\ntwitter: \"rubybelgium\"\ncoordinates:\n  latitude: 50.8260453\n  longitude: 4.3802052\n"
  },
  {
    "path": "data/fosdem/ruby-devroom-at-fosdem-2024/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://fosdem.rubybelgium.be\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/fosdem/series.yml",
    "content": "---\nname: \"Ruby devroom at FOSDEM\"\nwebsite: \"http://fosdem-ruby.github.io/\"\ntwitter: \"ruby_fosdem\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2023/event.yml",
    "content": "---\nid: \"PLjHS2aIdExPdwbsmv2-e3DFN677fyFme7\"\ntitle: \"Friendly.rb 2023\"\nkind: \"conference\"\nlocation: \"Bucharest, Romania\"\ndescription: |-\n  Your friendly european Ruby conference in Bucharest, Romania\npublished_at: \"2023-10-30\"\nstart_date: \"2023-09-27\"\nend_date: \"2023-09-28\"\nchannel_id: \"UC-PJCpt-6EgR4Ks6e0RSs1g\"\nyear: 2023\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FEFBF0\"\nfeatured_color: \"#0C2866\"\nwebsite: \"https://2023.friendlyrb.com\"\ncoordinates:\n  latitude: 44.4356575\n  longitude: 26.094038\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2023/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Adrian Marin\n    - Lucian Ghindă\n    - Jakob Cosoroabă\n    - Alex Marinescu\n    - Stefan Cosma\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2023/venue.yml",
    "content": "---\nname: \"Apollo 111\"\n\naddress:\n  street: \"Strada Ion Brezoianu 23-25\"\n  city: \"București\"\n  postal_code: \"030167\"\n  country: \"Romania\"\n  country_code: \"RO\"\n  display: \"Palatul Universul, Corp B, subsol, Strada Ion Brezoianu 23-25, București 030167, Romania\"\n\ndescription: |\n  Right in the heart of the city with the most comfortable seats you've ever seen at a conference.\n\ncoordinates:\n  latitude: 44.4356575\n  longitude: 26.094038\n\nmaps:\n  google: \"https://www.google.com/maps/place/Apollo111/@44.4357348,26.0945119,18.55z\"\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"xavier-noria-friendlyrb-2023\"\n  title: \"Zeitwerk Internals\"\n  raw_title: \"Xavier Noria - Zeitwerk Internals\"\n  speakers:\n    - Xavier Noria\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-05\"\n  description: |-\n    Xavier Noria is a Rails core member & author of the Zeitwerk gem. He's speaking at Friendly.rb about How Zeitwerk works internally.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"4n2Nhw3vzIM\"\n\n- id: \"marian-posceanu-friendlyrb-2023\"\n  title: \"Lightning Talk: Ruby and the Lisp\"\n  raw_title: \"Marian Posăceanu - Ruby and the Lisp - Lightning Talk\"\n  speakers:\n    - Marian Posăceanu\n\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-07\"\n  description: |-\n    Marian is a talented Ruby developer from the seaside of Romania, where he's making the World Economic Forum stay on track while exploring his passions. He shared his passion for lisp at Friendly.rb.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"eOmF9SnIG5A\"\n\n- id: \"julian-cheal-friendlyrb-2023\"\n  title: \"Lightning Talk: Making music with Ruby and Sonic Pi\"\n  raw_title: \"Julian Cheal - Making music with Ruby and Sonic Pi - Lightning Talk\"\n  speakers:\n    - Julian Cheal\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-06\"\n  description: |-\n    Julian Cheal is a British Ruby/Rails developer with a pen­chant for tweed, fine coffee, and homebrewing. At Friendly.rb he gave a cool demo on how one can create music using Sonic Pi and Ruby.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"-oZVEAtdXDM\"\n\n- id: \"ayush-newatia-friendlyrb-2023\"\n  title: \"Use Turbo Native to make hybrid apps that don't suck\"\n  raw_title: \"Ayush Newatia - Use Turbo Native to make hybrid apps that don't suck\"\n  speakers:\n    - Ayush Newatia\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-15\"\n  description: |-\n    Ayush is the author of The Rails and Hotwire codex, Bridgetown core member, and Just a spec podcast host.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"N4g_raRF-cE\"\n\n- id: \"jason-swett-friendlyrb-2023\"\n  title: \"Getting the most out of Chat GPT\"\n  raw_title: \"Jason Swett - Getting the most out of Chat GPT\"\n  speakers:\n    - Jason Swett\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Jason Swett is the host of the Code with Jason podcast, Code with Jason Meetup, and author of his snail mail Nonsense Monthly and The Complete Guide to Rails Testing book.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"ga0h17TUuX0\"\n\n- id: \"marian-dumitru-friendlyrb-2023\"\n  title: \"Lightning Talk: Become a Roma connoisseur in less than 5 minutes\"\n  raw_title: \"Marian Dumitru - Become a Roma connoisseur in less than 5 minutes - Lightning Talk\"\n  speakers:\n    - Marian Dumitru\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-14\"\n  description: |-\n    Marian Dumitru is a funny self-taught developer that shared with us the history of the Roma people.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"nN7MtpSNyhI\"\n\n- id: \"irina-paraschiv-friendlyrb-2023\"\n  title: \"Mental Health for Developers\"\n  raw_title: \"Irina Paraschiv - Mental Health for Developers\"\n  speakers:\n    - Irina Paraschiv\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Irina is a licensed Psychotherapist, Emotional Educator, and the Co-founder of Acertivo, the Mental Health platform, designed for agile teams\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"bnKjnxUL1MI\"\n\n- id: \"elena-tnsoiu-friendlyrb-2023\"\n  title: \"Service modeling at GitHub\"\n  raw_title: \"Elena Tănăsoiu - Service modeling at GitHub\"\n  speakers:\n    - Elena Tănăsoiu\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Elena Tănăsoiu is a Senior Engineer at GitHub. She spoke about how they do service modeling and other things at GitHub.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"2G35mRB0WFk\"\n\n- id: \"lorin-thwaits-friendlyrb-2023\"\n  title: \"Lightning Talk: From a spreadsheet to a Rails app in 5 minutes\"\n  raw_title: \"Lorin Thwaits - From a spreadsheet to a Rails app in 5 minutes - Lightning Talk\"\n  speakers:\n    - Lorin Thwaits\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Lorin has been involved with data for three decades and somehow never gets tired of it! He's on a mission to make life easier for developers and product people around the world.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"kTeOovIoSQg\"\n\n- id: \"naijeria-toweett-friendlyrb-2023\"\n  title: \"React-ing to Rails: Why Ruby on Rails is the best Stop for Web Developer\"\n  raw_title: \"Naijeria Toweett - React-ing to Rails: Why Ruby on Rails is the best Stop for Web Developer\"\n  speakers:\n    - Naijeria Toweett\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Naijeria is a product manager turned Rails developer, and she talks about her experience from not being in tech, to learning React and then switching to Rails.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"SasYDQwtdr0\"\n\n- id: \"lucian-ghind-friendlyrb-2023\"\n  title: \"The state of the Rubyverse\"\n  raw_title: \"Lucian Ghindă - The state of the Rubyverse\"\n  speakers:\n    - Lucian Ghindă\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-08\"\n  description: |-\n    Lucian Ghindă is a passionate Ruby developer and the author of the Short Ruby Newsletter.\n    He was the best person to deliver the State of the Rubyverse with us as he watches everything that happens online with our beloved programming language.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"QrH2A70JlsM\"\n\n- id: \"gabriela-luhova-friendlyrb-2023\"\n  title: \"The Power of We: Unleashing the Collective Strength of Your Team\"\n  raw_title: \"Gabriela Luhova - The Power of We: Unleashing the Collective Strength of Your Team\"\n  speakers:\n    - Gabriela Luhova\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Gabriela Luhova is a prominent Ruby community member from Bulgaria, Rails Girls, and Balkan Ruby co-organizer.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"SLqb5x-Mu7w\"\n\n- id: \"jeremy-smith-friendlyrb-2023\"\n  title: \"Making it as an Indie Developer\"\n  raw_title: \"Jeremy Smith - Making it as an Indie Developer\"\n  speakers:\n    - Jeremy Smith\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  slides_url: \"https://speakerdeck.com/jeremysmithco/making-it-as-an-indie-developer\"\n  description: |-\n    Jeremy Smith is the co-host of the IndieRails podcast and Blue Ridge Ruby organizer.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"HC2T5ekVXPg\"\n\n- id: \"svyatoslav-kryukov-friendlyrb-2023\"\n  title: \"Let there be docs!\"\n  raw_title: \"Svyatoslav Kryukov - Let there be docs!\"\n  speakers:\n    - Svyatoslav Kryukov\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Svyat is the funny one from Evil Martians.\n\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"P86lC2EskaY\"\n\n- id: \"tom-de-bruijn-friendlyrb-2023\"\n  title: \"Crafting elegant code with ruby DSLs\"\n  raw_title: \"Tom de Bruijn - Crafting elegant code with ruby DSLs\"\n  speakers:\n    - Tom de Bruijn\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Tom is a software developer at AppSignal based in Amsterdam. He is one of the organizers of the Amsterdam Ruby meetup and Rails Girls workshops.\n    He gave a great talk at Friendly about how they design elegant code with Ruby DSLs.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"QrweucKRsmM\"\n\n- id: \"nick-sutterer-friendlyrb-2023\"\n  title: \"Beyond the service object\"\n  raw_title: \"Nick Sutterer - Beyond the service object\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Nick is an Open-Source developer at Trailblazer GmbH, pushing the limits of Ruby with his alternative frameworks.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"Eh2wATXq0_8\"\n\n- id: \"yaroslav-shmarov-friendlyrb-2023\"\n  title: \"Lightning Talk: Hotwire Cookbook and common use cases\"\n  raw_title: \"Yaroslav Shmarov - Hotwire Cookbook and common use cases - Lightning Talk\"\n  speakers:\n    - Yaroslav Shmarov\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Yaroslav Shmarov is the co-host of the Friendly Show podcast, a content creator on SupeRails.com, and a prominent Ruby community member who focuses on education.\n    He gave a surprise (even from him) talk, encouraging us to try Hotwire.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"fdMGUV_E4yU\"\n\n- id: \"victor-motogna-friendlyrb-2023\"\n  title: \"Lightning Talk: Ruby, the hidden programming teacher\"\n  raw_title: \"Victor Motogna - Ruby, the hidden programming teacher - Lightning Talk\"\n  speakers:\n    - Victor Motogna\n  event_name: \"Friendly.rb 2023\"\n  date: \"2023-09-27\"\n  published_at: \"2023-12-28\"\n  description: |-\n    Victor Motogna is the Head of Web Development at Wolfpack Digital a well-known development agency from Cluj.\n\n    Friendly.rb is an International Ruby Conference hosted in Bucharest at the end of September and focuses on community and creating connections.\n\n    https://friendlyrb.com\n    https://twitter.com/friendlyrb\n  video_provider: \"youtube\"\n  video_id: \"FIcZkeaP560\"\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2024/cfp.yml",
    "content": "---\n- link: \"https://friendlyrb.com/cfp\"\n  open_date: \"2024-03-29\"\n  close_date: \"2024-07-01\"\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2024/event.yml",
    "content": "---\nid: \"friendly-rb-2024\"\ntitle: \"Friendly.rb 2024\"\nkind: \"conference\"\nlocation: \"Bucharest, Romania\"\ndescription: |-\n  Your friendly european Ruby conference in Bucharest, Romania\npublished_at: \"2024-09-19\"\nstart_date: \"2024-09-18\"\nend_date: \"2024-09-19\"\nchannel_id: \"UC-PJCpt-6EgR4Ks6e0RSs1g\"\nyear: 2024\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FEFBF0\"\nfeatured_color: \"#0C2866\"\nwebsite: \"https://friendlyrb.com\"\ncoordinates:\n  latitude: 44.4356575\n  longitude: 26.094038\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2024/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Adrian Marin\n    - Lucian Ghindă\n    - Jakob Cosoroabă\n    - Alex Marinescu\n    - Stefan Cosma\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2024/schedule.yml",
    "content": "# Schedule: https://friendlyrb.com\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-09-18\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"10:00\"\n        end_time: \"10:15\"\n        slots: 1\n        items:\n          - Opening\n\n      - start_time: \"10:15\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:00\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"15:45\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:30\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - Guided Bucharest Walking Tour\n\n      - start_time: \"20:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Afterparty at Cross Fire\n\n  - name: \"Day 2\"\n    date: \"2024-09-19\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"10:45\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:15\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"13:00\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Surprise 💃\n\n      - start_time: \"15:45\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:15\"\n        slots: 1\n\n      - start_time: \"17:15\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"18:30\"\n        slots: 1\n        items:\n          - Closing\n\n      - start_time: \"18:30\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - Drinks at Ironic Taproom\n\n  - name: \"Day 3\"\n    date: \"2024-09-20\"\n    grid:\n      - start_time: \"09:20\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Day Trip to Buşteni\n\ntracks: []\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2024/venue.yml",
    "content": "---\nname: \"Apollo 111\"\n\naddress:\n  street: \"Strada Ion Brezoianu 23-25\"\n  city: \"București\"\n  postal_code: \"030167\"\n  country: \"Romania\"\n  country_code: \"RO\"\n  display: \"Palatul Universul, Corp B, subsol, Strada Ion Brezoianu 23-25, București 030167, Romania\"\n\ndescription: |\n  Right in the heart of the city with the most comfortable seats you've ever seen at a conference.\n\ncoordinates:\n  latitude: 44.4356575\n  longitude: 26.094038\n\nmaps:\n  google: \"https://www.google.com/maps/place/Apollo111/@44.4357348,26.0945119,18.55z\"\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2024/videos.yml",
    "content": "## Day 1, Wednesday, September 18\n\n# Registration\n\n# Opening\n---\n- title: \"Invalid byte sequence in UTF-8\"\n  raw_title: \"Invalid byte sequence in UTF-8\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Rosa Gutierrez\n  video_provider: \"youtube\"\n  video_id: \"dFw9W6Hm9T8\"\n  id: \"rosa-gutierrez-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-18\"\n  published_at: \"2025-07-01\"\n\n- title: \"OWASP Top 10 for Rails developers\"\n  raw_title: \"OWASP Top 10 for Rails developers\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Greg Molnar\n  video_id: \"1tr3D536Jjs\"\n  video_provider: \"youtube\"\n  id: \"greg-molnar-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-18\"\n  published_at: \"2025-07-01\"\n\n- title: \"The 8-Second Nightmare: How One Change Reduced Latency by 99.9%\"\n  raw_title: \"The 8-Second Nightmare: How One Change Reduced Latency by 99.9%\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Nabeelah Yousuph\n  video_id: \"S55_YzxtXGs\"\n  video_provider: \"youtube\"\n  id: \"nabeelah-yousuph-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-18\"\n  published_at: \"2025-07-01\"\n\n- title: \"SaaS Lessons Learned\"\n  raw_title: \"SaaS Lessons Learned\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Tom Rossi\n  video_id: \"QaZ-5Zpzb5k\"\n  video_provider: \"youtube\"\n  id: \"tom-rossi-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-18\"\n  published_at: \"2025-07-01\"\n\n# Lunch break\n\n- title: \"Make a Massively Multiplayer Ruby Game with Dragon Ruby\"\n  raw_title: \"Make a Massively Multiplayer Ruby Game with Dragon Ruby\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Julian Cheal\n  video_id: \"pTR5BPRMAcs\"\n  video_provider: \"youtube\"\n  id: \"julian-cheal-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-18\"\n  published_at: \"2025-07-01\"\n\n- title: \"Ruby in the Billions\"\n  raw_title: \"Ruby in the Billions\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Celso Fernandes\n  video_id: \"1ygEiLRAxus\"\n  video_provider: \"youtube\"\n  id: \"celso-fernandes-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-18\"\n  published_at: \"2025-07-01\"\n\n- title: \"Panel: Ruby at Scale\"\n  raw_title: \"Discussion Panel - Ruby at scale\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Celso Fernandes\n    - Hana Harencarova\n    - Alexandru Călinoiu\n    - Cristian Planas\n  video_id: \"UZF3X_Bj9Ao\"\n  video_provider: \"youtube\"\n  id: \"discussion-panel-ruby-at-scale-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-18\"\n  published_at: \"2025-07-01\"\n\n# Guided Bucharest Walking Tour\n\n# Afterparty at Cross Fire\n\n## Day 2, Thursday, September 19\n\n- title: \"SQLite on Rails: Everything you need to know\"\n  raw_title: \"SQLite on Rails: Everything you need to know\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Stephen Margheim\n  video_id: \"bNapLzKePbg\"\n  video_provider: \"youtube\"\n  id: \"stephen-margheim-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-19\"\n  published_at: \"2025-07-01\"\n\n- title: \"Building for web and mobile in 2024: Production story and brighter future with Rails 8\"\n  raw_title: \"Building for web and mobile in 2024: Production story and brighter future with Rails 8\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Hana Harenčárová\n  video_id: \"sbB0d7j3AO4\"\n  video_provider: \"youtube\"\n  id: \"hana-harencarova-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-19\"\n  published_at: \"2025-07-01\"\n\n- title: \"Fibonacci Funhouse\"\n  raw_title: \"Fibonacci Funhouse\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Kyle d'Oliveira\n  video_id: \"L9lM2iH7oEc\"\n  video_provider: \"youtube\"\n  id: \"kyle-d-oliveira-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-19\"\n  published_at: \"2025-07-01\"\n\n- title: \"Rails frontend: 10 commandments and 7 deadly sins in 2025\"\n  raw_title: \"Rails frontend: 10 commandments and 7 deadly sins in 2025\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Yaroslav Shmarov\n  video_id: \"W39MvChAWWI\"\n  video_provider: \"youtube\"\n  id: \"yaroslav-shmarov-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-19\"\n  published_at: \"2025-07-01\"\n\n# Lunch break\n\n# Surprise\n\n- title: \"A day in the life of 2,000 developers\"\n  raw_title: \"A day in the life of 2,000 developers\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - James Carr\n  video_id: \"mImdzQGKoPo\"\n  video_provider: \"youtube\"\n  id: \"james-carr-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-19\"\n  published_at: \"2025-07-01\"\n\n- title: \"Web Accessibility by 2025\"\n  raw_title: \"Web Accessibility by 2025\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Victor Motogna\n  video_id: \"qwFpx_NkJX8\"\n  video_provider: \"youtube\"\n  id: \"victor-motogna-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-19\"\n  published_at: \"2025-07-01\"\n\n- title: \"Embracing Uncertainty: Thriving in Complexity and Legacy Code\"\n  raw_title: \"Embracing Uncertainty: Thriving in Complexity and Legacy Code\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Benjamin Wood\n  video_id: \"CHpk-pJ-5N8\"\n  video_provider: \"youtube\"\n  id: \"benjamin-wood-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-19\"\n  published_at: \"2025-07-01\"\n\n- title: \"Stop overthinking and go create things\"\n  raw_title: \"Stop overthinking and go create things\"\n  event_name: \"Friendly.rb 2024\"\n  speakers:\n    - Olly Headey\n  video_id: \"ZsvJKG3uzpU\"\n  video_provider: \"youtube\"\n  id: \"olly-headey-friendly-rb-2024\"\n  description: \"\"\n  date: \"2024-09-19\"\n  published_at: \"2025-07-01\"\n# Closing\n\n#  Drinks at Ironic Taproom\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2025/cfp.yml",
    "content": "---\n- link: \"https://friendlyrb.com/cfp\"\n  open_date: \"2025-03-05\"\n  close_date: \"2025-07-01\"\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2025/event.yml",
    "content": "---\nid: \"friendly-rb-2025\"\ntitle: \"Friendly.rb 2025\"\nkind: \"conference\"\nlocation: \"Bucharest, Romania\"\ndescription: |-\n  Your friendly european Ruby conference in Bucharest, Romania\npublished_at: \"2025-09-11\"\nstart_date: \"2025-09-10\"\nend_date: \"2025-09-11\"\nchannel_id: \"UC-PJCpt-6EgR4Ks6e0RSs1g\"\nyear: 2025\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FEFBF0\"\nfeatured_color: \"#0C2866\"\nwebsite: \"https://friendlyrb.com\"\ncoordinates:\n  latitude: 44.4356575\n  longitude: 26.094038\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Adrian Marin\n    - Lucian Ghindă\n    - Jakob Cosoroabă\n    - Alex Marinescu\n    - Stefan Cosma\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsors\"\n      description: |-\n        ( we ❤️ you )\n      level: 1\n      sponsors:\n        - name: \"Clickfunnels\"\n          badge: \"\"\n          website: \"https://clickfunnels.com\"\n          slug: \"clickfunnels\"\n          logo_url: \"https://framerusercontent.com/images/JDAwX1pedjeG0XoxmqCdQEa9aWI.svg?scale-down-to=512\"\n\n        - name: \"Typesense\"\n          badge: \"\"\n          website: \"https://typesense.org\"\n          slug: \"typesense\"\n          logo_url: \"https://framerusercontent.com/images/UY9RULWTl8BRU3J0d0L3g76APIQ.png?scale-down-to=512\"\n\n    - name: \"Gold Sponsors\"\n      description: |-\n        ( thank you, thank you, thank you! )\n      level: 2\n      sponsors:\n        - name: \"Buzzsprout\"\n          badge: \"\"\n          website: \"https://www.buzzsprout.com\"\n          slug: \"buzzsprout-logo\"\n          logo_url: \"https://framerusercontent.com/images/CHqHeP3jq4RJQ9wlDxwuyyBnZt8.png?scale-down-to=512\"\n\n        - name: \"Appsignal\"\n          badge: \"\"\n          website: \"https://appsignal.com\"\n          slug: \"appsignal\"\n          logo_url: \"https://framerusercontent.com/assets/1HqchpvEe1PG2DHsRgia6DIicH6P.svg\"\n\n    - name: \"Community Sponsor\"\n      description: |-\n        ( proudly helping the community )\n      level: 3\n      sponsors:\n        - name: \"Bitzesty\"\n          badge: \"\"\n          website: \"https://bitzesty.com\"\n          slug: \"bitzesty\"\n          logo_url: \"https://framerusercontent.com/images/0Y5Cwh48wvm5Jv1RI6kJAOlCmGo.svg\"\n\n        - name: \"TRMNL\"\n          badge: \"\"\n          website: \"https://usetrmnl.com\"\n          slug: \"usetrmnl\"\n          logo_url: \"https://framerusercontent.com/images/ErJtZBjDongc9P5DpL30IJUiz8.svg\"\n\n    - name: \"Organizers\"\n      description: \"\"\n      level: 4\n      sponsors:\n        - name: \"Avo\"\n          badge: \"\"\n          website: \"https://avohq.io/rails-admin\"\n          slug: \"avo\"\n          logo_url: \"https://framerusercontent.com/images/PWzKRQeDuM16uywSBENulWlLQ.png?scale-down-to=512\"\n\n        - name: \"Short Ruby\"\n          badge: \"\"\n          website: \"https://shortruby.com/\"\n          slug: \"short-ruby\"\n          logo_url: \"https://framerusercontent.com/images/i8tnHkmUhpeVpLh66cJmCSBrc.png\"\n\n        - name: \"Sibiu Web Meetup\"\n          badge: \"\"\n          website: \"https://sibiuwebmeetup.org\"\n          slug: \"sibiu-web-meetup\"\n          logo_url: \"https://framerusercontent.com/images/M2Za7pyCn0hMQOaoz2KYoHZdY8.png\"\n\n    - name: \"Community partners\"\n      description: \"\"\n      level: 5\n      sponsors:\n        - name: \"Helvetic Ruby\"\n          badge: \"\"\n          website: \"https://helvetic-ruby.ch\"\n          slug: \"helvetic-ruby\"\n          logo_url: \"https://framerusercontent.com/images/KYXWmDAXbU458AYUjcOm8SotNo.png\"\n\n        - name: \"WomenInTechCluj\"\n          badge: \"\"\n          website: \"https://www.womenintechcluj.com\"\n          slug: \"womenintechcluj\"\n          logo_url: \"https://framerusercontent.com/images/pn7af4fnrRcOw0fLGqmg0KYJIE.webp\"\n\n        - name: \"Ruby Community Conference\"\n          badge: \"\"\n          website: \"https://rubycommunityconference.com\"\n          slug: \"ruby-community-conference\"\n          logo_url: \"https://framerusercontent.com/images/4lKsip0JirNOilWAuQPEhAtXmg.svg\"\n\n        - name: \"Balkan Ruby\"\n          badge: \"\"\n          website: \"https://balkanruby.com\"\n          slug: \"balkan-ruby\"\n          logo_url: \"https://framerusercontent.com/images/WzEPFe3rJRIUg1G3Hr0Y074Qao.png\"\n\n        - name: \"Ruby Türkiye\"\n          badge: \"\"\n          website: \"https://rubyturkiye.org\"\n          slug: \"rubyturkiye\"\n          logo_url: \"https://framerusercontent.com/images/H5m1iIZ3uWOLaVcbZzeUfc6iQ.svg\"\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2025/venue.yml",
    "content": "---\nname: \"Apollo 111\"\n\naddress:\n  street: \"Strada Ion Brezoianu 23-25\"\n  city: \"București\"\n  postal_code: \"030167\"\n  country: \"Romania\"\n  country_code: \"RO\"\n  display: \"Palatul Universul, Corp B, subsol, Strada Ion Brezoianu 23-25, București 030167, Romania\"\n\ndescription: |\n  Right in the heart of the city with the most comfortable seats you've ever seen at a conference.\n\ncoordinates:\n  latitude: 44.4356575\n  longitude: 26.094038\n\nmaps:\n  google: \"https://www.google.com/maps/place/Apollo111/@44.4357348,26.0945119,18.55z\"\n\nlocations:\n  - name: \"Fire Club\"\n    kind: \"Afterparty Location\"\n    address:\n      street: \"4 Strada Zarafi\"\n      city: \"București\"\n      region: \"București\"\n      postal_code: \"030167\"\n      country: \"Romania\"\n      country_code: \"RO\"\n      display: \"Strada Zarafi 4, București 030091, Romania\"\n    description: |-\n      Official afterparty venue for Friendly.rb 2025\n    coordinates:\n      latitude: 44.4314355\n      longitude: 26.1023595\n    maps:\n      google: \"https://maps.app.goo.gl/Fygkv7kxrAYYj53Y7\"\n\n  - name: \"Ironic Taproom\"\n    kind: \"Afterparty Location\"\n    address:\n      street: \"4 Strada Domnița Anastasia\"\n      city: \"București\"\n      region: \"București\"\n      postal_code: \"010403\"\n      country: \"Romania\"\n      country_code: \"RO\"\n      display: \"Strada Domnița Anastasia 4, București 075100, Romania\"\n    description: |-\n      Popular spot where attendees hung out after the conference\n    coordinates:\n      latitude: 44.4339474\n      longitude: 26.0951042\n    maps:\n      google: \"https://www.google.com/maps/place/Ironic+taproom/@44.4339474,26.0951042,17z\"\n\nhotels:\n  - name: \"Moxy Bucharest Old Town\"\n    kind: \"Recommended\"\n    description: |-\n      Modern hotel in the Old Town, close to the venue\n    address:\n      street: \"Strada Doamnei\"\n      city: \"București\"\n      region: \"București\"\n      postal_code: \"030052\"\n      country: \"Romania\"\n      country_code: \"RO\"\n      display: \"Strada Doamnei, București 030052, Romania\"\n    coordinates:\n      latitude: 44.4332171\n      longitude: 26.1015606\n    maps:\n      google: \"https://www.google.com/maps/place/Moxy+Bucharest+Old+Town/@44.4332171,26.0989857,17z\"\n"
  },
  {
    "path": "data/friendly-rb/friendly-rb-2025/videos.yml",
    "content": "# Website: https://friendlyrb.com\n---\n- title: \"Great Developers Do Sales, Marketing and Support\"\n  raw_title: \"Friendly.rb 2025 - Talk by Jonathan Markwell\"\n  speakers:\n    - Jonathan Markwell\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-10\"\n  language: \"en\"\n  description: |-\n    Talk by Jonathan Markwell, Urlbox Chief Operations Officer and Co-Founder of The Skiff.\n  video_provider: \"not_published\"\n  video_id: \"jonathan-markwell-friendly-rb-2025\"\n  id: \"jonathan-markwell-friendly-rb-2025\"\n\n- title: \"Starting your own SaaS\"\n  raw_title: \"Friendly.rb 2025 - Starting your own SaaS by Michael Koper\"\n  speakers:\n    - Michael Koper\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-10\"\n  language: \"en\"\n  description: |-\n    A guide to launching your own SaaS business from Michael Koper, Founder of Nusii and Rails developer.\n  video_provider: \"not_published\"\n  video_id: \"michael-koper-friendly-rb-2025\"\n  id: \"michael-koper-friendly-rb-2025\"\n\n- title: \"Rails on SQLite: exciting new ways to cause outages\"\n  raw_title: \"Friendly.rb 2025 - Rails on SQLite: exciting new ways to cause outages by André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-10\"\n  language: \"en\"\n  description: |-\n    A humorous yet informative look at Rails and SQLite integration pitfalls from André Arko, Rubygems core team member.\n  video_provider: \"not_published\"\n  video_id: \"andre-arko-friendly-rb-2025\"\n  id: \"andre-arko-friendly-rb-2025\"\n  slides_url: \"https://speakerdeck.com/indirect/rails-on-sqlite-exciting-new-ways-to-cause-outages\"\n\n- title: \"From Imposter to Influencer: Building the Community I Craved\"\n  raw_title: \"Friendly.rb 2025 - From Imposter to Influencer: Building the Community I Craved by Naijeria Toweett\"\n  speakers:\n    - Naijeria Toweett\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-10\"\n  language: \"en\"\n  description: |-\n    A personal journey of overcoming imposter syndrome and building tech communities from Naijeria Toweett, Founder & CEO at Mama Tech.\n  video_provider: \"not_published\"\n  video_id: \"naijeria-toweett-friendly-rb-2025\"\n  id: \"naijeria-toweett-friendly-rb-2025\"\n\n- title: \"Ruby+AI Tech Landscape 2025: A Survey\"\n  raw_title: \"Friendly.rb 2025 - Ruby+AI Tech Landscape 2025: A Survey by Obie Fernandez\"\n  speakers:\n    - Obie Fernandez\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-10\"\n  language: \"en\"\n  description: |-\n    A comprehensive survey of the Ruby and AI technology landscape in 2025 from Obie Fernandez, Chief Consultant at Magma Labs.\n  video_provider: \"not_published\"\n  video_id: \"obie-fernandez-friendly-rb-2025\"\n  id: \"obie-fernandez-friendly-rb-2025\"\n\n- title: \"Let's fine-tune a model!\"\n  raw_title: \"Friendly.rb 2025 - Let's fine-tune a model! by Chris Hasiński\"\n  speakers:\n    - Chris Hasiński\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-10\"\n  language: \"en\"\n  description: |-\n    A practical guide to fine-tuning machine learning models from Chris Hasiński, Independent Consultant.\n  video_provider: \"not_published\"\n  video_id: \"chris-hasinski-friendly-rb-2025\"\n  id: \"chris-hasinski-friendly-rb-2025\"\n\n- title: \"Security in the age of AI\"\n  raw_title: \"Friendly.rb 2025 - Security in the age of AI by Greg Molnar\"\n  speakers:\n    - Greg Molnar\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-10\"\n  language: \"en\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"greg-molnar-friendly-rb-2025\"\n  id: \"greg-molnar-friendly-rb-2025\"\n\n- title: \"Why doesn't Ruby have a Boolean class?\"\n  raw_title: \"Friendly.rb 2025 - Why doesn't Ruby have a Boolean class? by OKURA Masafumi\"\n  speakers:\n    - OKURA Masafumi\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-10\"\n  language: \"en\"\n  description: |-\n    Exploring Ruby's object-oriented design and the absence of a Boolean class. OKURA Masafumi is the chief organizer of Kaigi on Rails.\n  video_provider: \"not_published\"\n  video_id: \"okura-masafumi-friendly-rb-2025\"\n  id: \"okura-masafumi-friendly-rb-2025\"\n\n- title: \"Back to simplicity\"\n  raw_title: \"Friendly.rb 2025 - Back to simplicity by Jan Dudulski\"\n  speakers:\n    - Jan Dudulski\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-10\"\n  language: \"en\"\n  description: |-\n    Advocating for simplicity in software development from Jan Dudulski, Principal Software Engineer at Gainsight and Wroclove.rb co-organizer.\n  video_provider: \"not_published\"\n  video_id: \"jan-dudulski-friendly-rb-2025\"\n  id: \"jan-dudulski-friendly-rb-2025\"\n\n## Day 2\n\n- title: \"Versatility as a technologist\"\n  raw_title: \"Friendly.rb 2025 - Versatility as a technologist by Carmen Huidobro\"\n  speakers:\n    - Carmen Huidobro\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-11\"\n  language: \"en\"\n  description: |-\n    Exploring versatility in technology careers from Carmen Huidobro, Freelance Software Engineer.\n  video_provider: \"not_published\"\n  video_id: \"carmen-huidobro-friendly-rb-2025\"\n  id: \"carmen-huidobro-friendly-rb-2025\"\n\n- title: \"Counter-Strike, Rails, and Building Performant Software\"\n  raw_title: \"Friendly.rb 2025 - Counter-Strike, Rails, and Building Performant Software by Victor Motogna\"\n  speakers:\n    - Victor Motogna\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-11\"\n  language: \"en\"\n  description: |-\n    Lessons from gaming and software development on building high-performance applications. Victor Motogna is Head of Web Development at Wolfpack Digital.\n  video_provider: \"not_published\"\n  video_id: \"victor-motogna-friendly-rb-2025\"\n  id: \"victor-motogna-friendly-rb-2025\"\n\n# Share your Ruby passion project\n\n- title: \"Panel: Rails SaaS\"\n  raw_title: \"Friendly.rb 2025 - Rails SaaS panel\"\n  speakers:\n    - Lucian Ghindă\n    - Irina Nazarova\n    - Jonathan Markwell\n    - Onur Özer\n    - Julian Rubisch\n    - Michael Koper\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-11\"\n  language: \"en\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"rails-saas-panel-friendly-rb-2025\"\n  id: \"rails-saas-panel-friendly-rb-2025\"\n\n- title: \"Poly-table Inheritance\"\n  raw_title: \"Friendly.rb 2025 - Poly-table Inheritance by Nicolas Erlichman\"\n  speakers:\n    - Nicolas Erlichman\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-11\"\n  language: \"en\"\n  description: |-\n    Exploring advanced inheritance patterns in database design from Nicolas Erlichman, CTO at GoGrow.\n  video_provider: \"not_published\"\n  video_id: \"nicolas-erlichman-friendly-rb-2025\"\n  id: \"nicolas-erlichman-friendly-rb-2025\"\n\n- title: \"Game Show\"\n  raw_title: \"Friendly.rb 2025 - ✨Game show✨ by Jakob Cosoroabă\"\n  speakers:\n    - Jakob Cosoroabă\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-11\"\n  language: \"en\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"jakob-cosoroaba-friendly-rb-2025\"\n  id: \"jakob-cosoroaba-friendly-rb-2025\"\n\n- title: \"Abstractions: Friend, Foe, or Frenemy?\"\n  raw_title: \"Friendly.rb 2025 - Abstractions: Friend, Foe, or Frenemy? by Abiodun Olowode\"\n  speakers:\n    - Abiodun Olowode\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-11\"\n  language: \"en\"\n  description: |-\n    Examining the role of abstractions in software development from Abiodun Olowode, CTO of Metrifox.\n  video_provider: \"not_published\"\n  video_id: \"abiodun-olowode-friendly-rb-2025\"\n  id: \"abiodun-olowode-friendly-rb-2025\"\n\n- title: \"Learning to Consult, Learning to Live\"\n  raw_title: \"Friendly.rb 2025 - Learning to Consult, Learning to Live by Irina Nazarova\"\n  speakers:\n    - Irina Nazarova\n  event_name: \"Friendly.rb 2025\"\n  date: \"2025-09-11\"\n  language: \"en\"\n  description: |-\n    Insights into consulting and life lessons from Irina Nazarova, CEO of Evil Martians and SF Ruby Host.\n  video_provider: \"not_published\"\n  video_id: \"irina-nazarova-friendly-rb-2025\"\n  id: \"irina-nazarova-friendly-rb-2025\"\n"
  },
  {
    "path": "data/friendly-rb/series.yml",
    "content": "---\nname: \"Friendly.rb\"\nwebsite: \"https://friendlyrb.com/\"\ntwitter: \"friendlyrb\"\nyoutube_channel_name: \"friendlyrb\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"RO\"\nlanguage: \"english\"\nyoutube_channel_id: \"UC-PJCpt-6EgR4Ks6e0RSs1g\"\naliases:\n  - Friendly rb\n  - Friendlyrb\n  - Friendly Ruby\n  - Friendly\n"
  },
  {
    "path": "data/frozen-rails/frozen-rails-2010/event.yml",
    "content": "---\nid: \"frozen-rails-2010\"\ntitle: \"Frozen Rails 2010\"\ndescription: \"\"\nlocation: \"Helsinki, Finland\"\nkind: \"conference\"\nstart_date: \"2010-05-07\"\nend_date: \"2010-05-07\"\nwebsite: \"https://2010.frozenrails.eu\"\ntwitter: \"frozenrails\"\ncoordinates:\n  latitude: 60.16985569999999\n  longitude: 24.938379\n"
  },
  {
    "path": "data/frozen-rails/frozen-rails-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2010.frozenrails.eu\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/frozen-rails/frozen-rails-2011/event.yml",
    "content": "---\nid: \"frozen-rails-2011\"\ntitle: \"Frozen Rails 2011\"\ndescription: \"\"\nlocation: \"Helsinki, Finland\"\nkind: \"conference\"\nstart_date: \"2011-09-20\"\nend_date: \"2011-09-21\"\nwebsite: \"https://2011.frozenrails.eu\"\ntwitter: \"frozenrails\"\ncoordinates:\n  latitude: 60.16985569999999\n  longitude: 24.938379\n"
  },
  {
    "path": "data/frozen-rails/frozen-rails-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2011.frozenrails.eu\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/frozen-rails/frozen-rails-2012/event.yml",
    "content": "---\nid: \"frozen-rails-2012\"\ntitle: \"Frozen Rails 2012\"\ndescription: \"\"\nlocation: \"Helsinki, Finland\"\nkind: \"conference\"\nstart_date: \"2012-09-20\"\nend_date: \"2012-09-21\"\nwebsite: \"https://2012.frozenrails.eu\"\ntwitter: \"frozenrails\"\ncoordinates:\n  latitude: 60.16985569999999\n  longitude: 24.938379\n"
  },
  {
    "path": "data/frozen-rails/frozen-rails-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2012.frozenrails.eu\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/frozen-rails/frozen-rails-2014/event.yml",
    "content": "---\nid: \"frozen-rails-2014\"\ntitle: \"Frozen Rails 2014\"\ndescription: \"\"\nlocation: \"Helsinki, Finland\"\nkind: \"conference\"\nstart_date: \"2014-09-11\"\nend_date: \"2014-09-12\"\nwebsite: \"http://2014.frozenrails.eu/\"\ntwitter: \"frozenrails\"\ncoordinates:\n  latitude: 60.16985569999999\n  longitude: 24.938379\n"
  },
  {
    "path": "data/frozen-rails/frozen-rails-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2014.frozenrails.eu/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/frozen-rails/series.yml",
    "content": "---\nname: \"Frozen Rails\"\nwebsite: \"https://frozenrails.eu/\"\ntwitter: \"frozenrails\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-03/event.yml",
    "content": "---\nid: \"fukuoka-rubyistkaigi-03\"\ntitle: \"Fukuoka RubyistKaigi 03\"\ndescription: \"\"\nlocation: \"Fukuoka, Japan\"\nkind: \"conference\"\nstart_date: \"2023-02-18\"\nend_date: \"2023-02-18\"\nwebsite: \"https://regional.rubykaigi.org/fukuoka03/\"\nfeatured_background: \"#7C152B\"\nfeatured_color: \"#FFFFFF\"\nbanner_background: |-\n  linear-gradient(to bottom, #701227 67%, #701227 67%) left top / 50% 100% no-repeat, /* Left side */\n  linear-gradient(to bottom, #7C152B 67%, #7C152B 67%) right top / 50% 100% no-repeat /* Right side */\ncoordinates:\n  latitude: 33.5901838\n  longitude: 130.4016888\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-03/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: |-\n        福岡Rubyist会議03のスポンサー企業\n      level: 1\n      sponsors:\n        - name: \"FjordBootCamp\"\n          website: \"https://bootcamp.fjord.jp/\"\n          slug: \"FjordBootCamp\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka03/images/sponsor/fbc.jpg\"\n\n        - name: \"Yamap Co., Ltd\"\n          website: \"https://yamap.com/\"\n          slug: \"yamap\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka03/images/sponsor/yamap.jpg\"\n\n        - name: \"Money Forward, Inc.\"\n          website: \"https://corp.moneyforward.com/\"\n          slug: \"moneyforward\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka03/images/sponsor/moneyforward.jpg\"\n\n    - name: \"Support\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Nihon Ruby no Kai\"\n          website: \"https://ruby-no-kai.org\"\n          slug: \"japan-ruby-association\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka03/images/sponsor/nihon_ruby.jpg\"\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-03/videos.yml",
    "content": "# Website: https://regional.rubykaigi.org/fukuoka03/\n# Schedule: https://regional.rubykaigi.org/fukuoka03/timetable.html\n# Videos: -\n---\n- id: \"yasulab-fukuoka-rubyistkaigi-03\"\n  title: \"RubyistによるRubyistのためのカンタン動画制作\"\n  raw_title: \"RubyistによるRubyistのためのカンタン動画制作\"\n  speakers:\n    - Yohei Yasukawa\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"yasulab-fukuoka-rubyistkaigi-03\"\n  language: \"ja\"\n\n- id: \"hiroshi-shibata-fukuoka-rubyistkaigi-03\"\n  title: \"Ruby のリリースを爆速にするための方法\"\n  raw_title: \"Ruby のリリースを爆速にするための方法\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"hiroshi-shibata-fukuoka-rubyistkaigi-03\"\n  language: \"ja\"\n\n- id: \"sho-hashimoto-fukuoka-rubyistkaigi-03\"\n  title: \"Keynote: Coming soon\"\n  raw_title: \"Coming soon\"\n  speakers:\n    - Sho Hashimoto\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"sho-hashimoto-fukuoka-rubyistkaigi-03\"\n  language: \"ja\"\n\n- id: \"yuhei-okazaki-fukuoka-rubyistkaigi-03\"\n  title: \"mruby on IoT devices\"\n  raw_title: \"mruby on IoT devices\"\n  speakers:\n    - Yuhei Okazaki\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"yuhei-okazaki-fukuoka-rubyistkaigi-03\"\n  language: \"en\"\n\n- id: \"hachi-fukuoka-rubyistkaigi-03\"\n  title: \"Factorybot 改善ツール作成失敗と学び\"\n  raw_title: \"Factorybot 改善ツール作成失敗と学び\"\n  speakers:\n    - Hayao Kimura\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"hachi-fukuoka-rubyistkaigi-03\"\n  language: \"ja\"\n\n- id: \"pocke-fukuoka-rubyistkaigi-03\"\n  title: \"外部コマンド実行入門\"\n  raw_title: \"外部コマンド実行入門\"\n  speakers:\n    - Masataka Kuwabara\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"pocke-fukuoka-rubyistkaigi-03\"\n  language: \"ja\"\n\n- id: \"fjordbootcamp-fukuoka-rubyistkaigi-03\"\n  title: \"Sponsor Session: FjordBootCamp\"\n  raw_title: \"スポンサーセッション①: FjordBootCamp\"\n  speakers:\n    - FjordBootCamp\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"fjordbootcamp-fukuoka-rubyistkaigi-03\"\n  language: \"ja\"\n\n- id: \"yamap-fukuoka-rubyistkaigi-03\"\n  title: \"Sponsor Session: YAMAP\"\n  raw_title: \"スポンサーセッション②: 株式会社ヤマップ\"\n  speakers:\n    - YAMAP\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"yamap-fukuoka-rubyistkaigi-03\"\n  language: \"ja\"\n\n- id: \"money-forward-fukuoka-rubyistkaigi-03\"\n  title: \"Sponsor Session: Money Forward\"\n  raw_title: \"スポンサーセッション③: 株式会社マネーフォワード\"\n  speakers:\n    - Money Forward\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"money-forward-fukuoka-rubyistkaigi-03\"\n  language: \"ja\"\n\n- id: \"kazuhiro-nishiyama-fukuoka-rubyistkaigi-03\"\n  title: \"Rubyist Magazine Reboot\"\n  raw_title: \"Rubyist Magazine Reboot\"\n  speakers:\n    - Kazuhiro NISHIYAMA\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"kazuhiro-nishiyama-fukuoka-rubyistkaigi-03\"\n  language: \"ja\"\n\n- id: \"tompng-fukuoka-rubyistkaigi-03\"\n  title: \"Keynote: メンテできないコードをメンテする技術\"\n  raw_title: \"メンテできないコードをメンテする技術\"\n  speakers:\n    - Tomoya Ishida\n  event_name: \"Fukuoka RubyistKaigi 03\"\n  date: \"2023-01-13\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"tompng-fukuoka-rubyistkaigi-03\"\n  language: \"ja\"\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-04/event.yml",
    "content": "---\nid: \"fukuoka-rubyistkaigi-04\"\ntitle: \"Fukuoka RubyistKaigi 04\"\ndescription: \"\"\nlocation: \"Fukuoka, Japan\"\nkind: \"conference\"\nstart_date: \"2024-09-07\"\nend_date: \"2024-09-07\"\nwebsite: \"https://regional.rubykaigi.org/fukuoka04/\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#E86CA3\"\nbanner_background: \"#FFFFFF\"\ncoordinates:\n  latitude: 33.5901838\n  longitude: 130.4016888\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-04/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Support\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Japan Ruby Association\"\n          website: \"https://ruby-no-kai.org\"\n          slug: \"japan-ruby-association\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka04/astro/nihon_ruby.34dgfPk-_Z1j62v8.webp\"\n\n    - name: \"Special Thanks\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://bit.ly/shopifyatrubykaigi\"\n          slug: \"shopify\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka04/astro/shopify.fZTutJbg_1GVDQC.webp\"\n\n        - name: \"ESM, Inc.\"\n          website: \"https://agile.esm.co.jp/\"\n          slug: \"esm\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka04/astro/esm.bGJGoiU9_ZTg4kN.webp\"\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-04/videos.yml",
    "content": "# Website: https://regional.rubykaigi.org/fukuoka04/\n# Videos: -\n---\n- id: \"kevin-newton-fukuoka-rubyistkaigi-04\"\n  title: \"Keynote: Why Prism?\"\n  raw_title: \"Why Prism?\"\n  speakers:\n    - Kevin Newton\n  event_name: \"Fukuoka RubyistKaigi 04\"\n  date: \"2025-01-11\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"kevin-newton-fukuoka-rubyistkaigi-04\"\n\n- id: \"yukihiro-matsumoto-fukuoka-rubyistkaigi-04\"\n  title: \"Coming soon\"\n  raw_title: \"Coming soon\"\n  speakers:\n    - Yukihiro Matsumoto\n  event_name: \"Fukuoka RubyistKaigi 04\"\n  date: \"2025-01-11\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"yukihiro-matsumoto-fukuoka-rubyistkaigi-04\"\n\n- id: \"takashi-hatakeyama-fukuoka-rubyistkaigi-04\"\n  title: \"Building a Ruby-like Language Compiler with Ruby\"\n  raw_title: \"Building a Ruby-like Language Compiler with Ruby\"\n  speakers:\n    - Takashi Hatakeyama\n  event_name: \"Fukuoka RubyistKaigi 04\"\n  date: \"2025-01-11\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"takashi-hatakeyama-fukuoka-rubyistkaigi-04\"\n\n- id: \"shun-hiraoka-fukuoka-rubyistkaigi-04\"\n  title: \"Trying to Make Ruby's Parser Available as a Gem\"\n  raw_title: \"Trying to Make Ruby's Parser Available as a Gem\"\n  speakers:\n    - Shun Hiraoka\n  event_name: \"Fukuoka RubyistKaigi 04\"\n  date: \"2025-01-11\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"shun-hiraoka-fukuoka-rubyistkaigi-04\"\n\n- id: \"maimu-jarinko-fukuoka-rubyistkaigi-04\"\n  title: \"Rails Girls is My Gate to Join the Ruby Community / Rails Girls Fukuoka 3rd\"\n  raw_title: \"Rails Girls is My Gate to Join the Ruby Community / Rails Girls Fukuoka 3rd\"\n  speakers:\n    - maimu\n    - Jarinko\n  event_name: \"Fukuoka RubyistKaigi 04\"\n  date: \"2025-01-11\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"maimu-jarinko-fukuoka-rubyistkaigi-04\"\n\n- id: \"panel-discussion-fukuoka-rubyistkaigi-04\"\n  title: \"Panel Discussion\"\n  raw_title: \"Panel Discussion\"\n  speakers:\n    - Akira Matsuda\n    - Naoki Kishida\n    - Shintaro Kakutani\n  event_name: \"Fukuoka RubyistKaigi 04\"\n  date: \"2025-01-11\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"panel-discussion-fukuoka-rubyistkaigi-04\"\n\n- id: \"katsyoshi-fukuoka-rubyistkaigi-04\"\n  title: \"Ruby in Ruby: Building an AOT Compiler with Ruby\"\n  raw_title: \"Ruby in Ruby: Building an AOT Compiler with Ruby\"\n  speakers:\n    - katsyoshi\n  event_name: \"Fukuoka RubyistKaigi 04\"\n  date: \"2025-01-11\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"katsyoshi-fukuoka-rubyistkaigi-04\"\n\n- id: \"uchio-kondo-fukuoka-rubyistkaigi-04\"\n  title: \"Ruby is like a teenage angst to me\"\n  raw_title: \"Ruby is like a teenage angst to me\"\n  speakers:\n    - Kondo Uchio\n  event_name: \"Fukuoka RubyistKaigi 04\"\n  date: \"2025-01-11\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"uchio-kondo-fukuoka-rubyistkaigi-04\"\n\n- id: \"yuichiro-kaneko-fukuoka-rubyistkaigi-04\"\n  title: \"Keynote: Coming soon\"\n  raw_title: \"Coming soon\"\n  speakers:\n    - Yuichiro Kaneko\n  event_name: \"Fukuoka RubyistKaigi 04\"\n  date: \"2025-01-11\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"yuichiro-kaneko-fukuoka-rubyistkaigi-04\"\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-05/event.yml",
    "content": "---\ntitle: \"Fukuoka RubyistKaigi 05\"\nkind: \"conference\"\nid: \"fukuoka-rubyistkaigi-05\"\nstart_date: \"2026-02-28\"\nend_date: \"2026-02-28\"\nlocation: \"Fukuoka, Japan\"\nwebsite: \"https://regional.rubykaigi.org/fukuoka05/\"\ntickets_url: \"https://fukuokarb.connpass.com/event/379101/\"\nbanner_background: \"#8FC8CA\"\nfeatured_background: \"#8FC8CA\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 33.59105484945821\n  longitude: 130.42480689237757\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-05/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - ODA Hirohito\n    - Uchio KONDO\n    - Tomoyuki Chikanaga\n    - Takeru Ushio\n\n- name: \"Designer\"\n  users:\n    - moegi\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-05/schedule.yml",
    "content": "# Schedule: https://regional.rubykaigi.org/fukuoka05/timetable.html\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2026-02-28\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - \"開場\"\n\n      - start_time: \"10:00\"\n        end_time: \"10:10\"\n        slots: 1\n        items:\n          - Opening Talk\n\n      - start_time: \"10:10\"\n        end_time: \"10:15\"\n        slots: 1\n        items:\n          - \"日本Rubyの会からのお知らせ\"\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"10:50\"\n        end_time: \"11:05\"\n        slots: 1\n\n      - start_time: \"11:10\"\n        end_time: \"11:25\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch Time\n\n      - start_time: \"13:00\"\n        end_time: \"13:15\"\n        slots: 1\n\n      - start_time: \"13:20\"\n        end_time: \"13:35\"\n        slots: 1\n\n      - start_time: \"13:35\"\n        end_time: \"13:45\"\n        slots: 1\n        items:\n          - スポンサートーク①\n\n      - start_time: \"13:45\"\n        end_time: \"13:55\"\n        slots: 1\n        items:\n          - スポンサートーク②\n\n      - start_time: \"13:55\"\n        end_time: \"14:35\"\n        slots: 1\n        items:\n          - Tea Time\n\n      - start_time: \"14:35\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:15\"\n        slots: 1\n        items:\n          - スポンサートーク③\n\n      - start_time: \"15:15\"\n        end_time: \"15:25\"\n        slots: 1\n        items:\n          - スポンサートーク④\n\n      - start_time: \"15:25\"\n        end_time: \"16:05\"\n        slots: 1\n        items:\n          - Tea Time\n\n      - start_time: \"16:05\"\n        end_time: \"16:20\"\n        slots: 1\n\n      - start_time: \"16:25\"\n        end_time: \"16:40\"\n        slots: 1\n\n      - start_time: \"16:45\"\n        end_time: \"17:15\"\n        slots: 1\n\n      - start_time: \"17:15\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Closing Talk\n\n      - start_time: \"18:00\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - title: \"完全撤収\"\n            description: |-\n              ご理解ご協力のほど、よろしくお願いします。\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-05/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      level: 1\n      sponsors:\n        - name: \"ANDPAD Inc.\"\n          website: \"https://engineer.andpad.co.jp/\"\n          slug: \"andpad\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka05/images/sponsor/andpad.jpg\"\n\n        - name: \"STORES, Inc.\"\n          website: \"https://jobs.st.inc/\"\n          slug: \"stores\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka05/images/sponsor/stores.jpg\"\n\n        - name: \"SmartHR, Inc.\"\n          website: \"https://hello-world.smarthr.co.jp/\"\n          slug: \"smarthr\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka05/images/sponsor/smarthr.jpg\"\n\n        - name: \"Ruby Development Inc.\"\n          website: \"https://www.ruby-dev.jp/\"\n          slug: \"rubydevelopment\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka05/images/sponsor/rubydevelopment.jpg\"\n\n    - name: \"Support\"\n      level: 2\n      sponsors:\n        - name: \"Nihon Ruby no Kai\"\n          website: \"https://ruby-no-kai.org\"\n          slug: \"japan-ruby-association\"\n          logo_url: \"https://regional.rubykaigi.org/fukuoka05/images/sponsor/nihon_ruby.jpg\"\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-05/venue.yml",
    "content": "---\nname: \"3rd floor, Reference Station East Building Conference room H-2\"\ndescription: |-\n  〒812-0013 Fukuoka, Hakata Ward, Hakataekihigashi, 1-chōme−16−14 リファレンス駅東ビル\naddress:\n  street: \"1-chōme-16-14 Hakataekihigashi, Hakata Ward\"\n  city: \"Fukuoka\"\n  region: \"Fukuoka\"\n  postal_code: \"812-0013\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"会場: リファレンス駅東ビル３階 会議室H-2\"\ncoordinates:\n  latitude: 33.59105484945821\n  longitude: 130.42480689237757\nmaps:\n  google: \"https://maps.app.goo.gl/Djg7cWqXgu4usXCbA\"\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubyistkaigi-05/videos.yml",
    "content": "---\n- id: \"shinta-koyanagi-keynote-fukuoka-rubyistkaigi-05\"\n  title: \"Keynote: What was SQLQL\"\n  original_title: \"Keynote：SQLQL とは何だったのか\"\n  event_name: \"Fukuoka RubyistKaigi 05\"\n  description: |-\n    SQLQL というのは 2017 年頃に yancya が提唱し始めた API の仕様のコンセプトです。\n    SQLQL について軽くおさらいしつつ、現代的な実装例を示しつつ、SQLQL が yancya にとって何だったのかについて発表します。\n  language: \"ja\"\n  video_provider: \"scheduled\"\n  video_id: \"shinta-koyanagi-keynote-fukuoka-rubyistkaigi-05\"\n  speakers:\n    - Shinta Koyanagi\n  date: \"2026-02-28\"\n\n- id: \"toshiaki-koshiba-chobishiba-talk-fukuoka-rubyistkaigi-05\"\n  title: \"A normal Rubyist, a small device, a big year\"\n  original_title: \"ふつうの Rubyist、ちいさなデバイス、大きな一年\"\n  event_name: \"Fukuoka RubyistKaigi 05\"\n  description: |-\n    2025 年、爆発的ブームの PicoRuby。こしば家は総出で登壇・展示・mrbgem 開発などに飛び回っています。\n    きっかけ、モチベーション、協力分担といったご家庭コミュニティー活動の背景を紹介します。\n  language: \"ja\"\n  video_provider: \"scheduled\"\n  video_id: \"toshiaki-koshiba-chobishiba-talk-fukuoka-rubyistkaigi-05\"\n  speakers:\n    - Toshiaki \"bash\" KOSHIBA\n    - Miyuki Koshiba\n  date: \"2026-02-28\"\n\n- id: \"shia-talk-fukuoka-rubyistkaigi-05\"\n  title: \"The challenge of Ruby development without writing types\"\n  original_title: \"型を書かないRuby開発への挑戦\"\n  event_name: \"Fukuoka RubyistKaigi 05\"\n  description: |-\n    「型を書かなくても十分有用な型情報を得られる」を目標に開発中の LSP「type-guessr」について話します。\n    完全さを諦めることでいい感じの体験を目指します。\n  language: \"ja\"\n  video_provider: \"scheduled\"\n  video_id: \"shia-talk-fukuoka-rubyistkaigi-05\"\n  speakers:\n    - Shia\n  date: \"2026-02-28\"\n\n- id: \"jugyo-talk-fukuoka-rubyistkaigi-05\"\n  title: \"What happened after 10 years of fighting in America as a Rubyist\"\n  original_title: \"Rubyist としてアメリカで 10 年戦ったらどうなったか\"\n  event_name: \"Fukuoka RubyistKaigi 05\"\n  description: |-\n    なんの成果も！！得られませんでした！！ — 渡米した Rubyist の 10 年。\n    個で戦い、生き延びた末に見えた限界。そして帰国後、協働するチームのあり方を見つめ直している話。\n  language: \"ja\"\n  video_provider: \"scheduled\"\n  video_id: \"jugyo-talk-fukuoka-rubyistkaigi-05\"\n  speakers:\n    - Jugyo\n  date: \"2026-02-28\"\n\n- id: \"shugo-maeda-talk-fukuoka-rubyistkaigi-05\"\n  title: \"Making Textbringer User-Friendly\"\n  original_title: \"Making Textbringer User-Friendly\"\n  event_name: \"Fukuoka RubyistKaigi 05\"\n  description: |-\n    これまで Textbringer というテキストエディタを独りよがりに開発してきましたが、最近ちょっとだけ普通の人にも使いやすいように改めているというお話をします。\n  language: \"ja\"\n  video_provider: \"scheduled\"\n  video_id: \"shugo-maeda-talk-fukuoka-rubyistkaigi-05\"\n  speakers:\n    - Shugo Maeda\n  date: \"2026-02-28\"\n\n- id: \"panel-discussion-cross-the-boundaries-of-community-fukuoka-rubyistkaigi-05\"\n  title: 'Panel Discussion: \"Cross the boundaries of community\"'\n  original_title: \"Panel Discussion：「コミュニティの垣根を越えよう」\"\n  event_name: \"Fukuoka RubyistKaigi 05\"\n  description: |-\n    Panel Discussion：「コミュニティの垣根を越えよう」\n  language: \"ja\"\n  video_provider: \"scheduled\"\n  video_id: \"panel-discussion-cross-the-boundaries-of-community-fukuoka-rubyistkaigi-05\"\n  speakers:\n    - Asumikam\n    - Yuki Aki\n  date: \"2026-02-28\"\n\n- id: \"s-h-gamelinks-talk-fukuoka-rubyistkaigi-05\"\n  title: \"Ecosystem on parse.y\"\n  original_title: \"Ecosystem on parse.y\"\n  event_name: \"Fukuoka RubyistKaigi 05\"\n  description: |-\n    Ruby の parse.y で生成された AST を Ruby で扱う「Kanayago（金屋子）」と、それを用いたツール「Igata（鋳型）」から生まれつつある”parse.y をベースとしたエコシステム”について紹介します。\n  language: \"ja\"\n  video_provider: \"scheduled\"\n  video_id: \"s-h-gamelinks-talk-fukuoka-rubyistkaigi-05\"\n  speakers:\n    - S-H-GAMELINKS\n  date: \"2026-02-28\"\n\n- id: \"nikkie-talk-fukuoka-rubyistkaigi-05\"\n  title: \"Look into the deep research black box with OTel\"\n  original_title: \"deep research のブラックボックスを OTel で覗く\"\n  event_name: \"Fukuoka RubyistKaigi 05\"\n  description: |-\n    deep research の動作を OpenTelemetry で可視化しブラックボックスな LLM API への入力を覗く手法を、私に馴染み深い Python と皆さんに馴染み深い Ruby の実装例で紹介します。\n  language: \"ja\"\n  video_provider: \"scheduled\"\n  video_id: \"nikkie-talk-fukuoka-rubyistkaigi-05\"\n  speakers:\n    - Nikkie\n  date: \"2026-02-28\"\n\n- id: \"yuji-yokoo-keynote-fukuoka-rubyistkaigi-05\"\n  title: \"Keynote: mruby in the 8 bit world: mruby VM on Zilog Z80\"\n  original_title: \"Keynote：mruby in the 8 bit world: mruby VM on Zilog Z80\"\n  event_name: \"Fukuoka RubyistKaigi 05\"\n  description: |-\n    Zilog Z80 用の mruby VM を実装しています。Z80 は主に 80 年代に様々な環境で使用された CPU です。\n    8 ビットの制限の上に開発環境も限られていますが、実用に耐えうるような実装をしています。\n  language: \"ja\"\n  video_provider: \"scheduled\"\n  video_id: \"yuji-yokoo-keynote-fukuoka-rubyistkaigi-05\"\n  speakers:\n    - Yuji Yokoo\n  date: \"2026-02-28\"\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubykaigi-01/event.yml",
    "content": "---\nid: \"fukuoka-rubykaigi-01\"\ntitle: \"Fukuoka RubyKaigi 01\"\ndescription: \"\"\nlocation: \"Fukuoka, Japan\"\nkind: \"conference\"\nstart_date: \"2012-12-01\"\nend_date: \"2012-12-01\"\nwebsite: \"https://regional.rubykaigi.org/fukuoka01/\"\ncoordinates:\n  latitude: 33.5901838\n  longitude: 130.4016888\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubykaigi-01/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://regional.rubykaigi.org/fukuoka01/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubykaigi-02/event.yml",
    "content": "---\nid: \"fukuoka-rubykaigi-02\"\ntitle: \"Fukuoka RubyKaigi 02\"\ndescription: \"\"\nlocation: \"Fukuoka, Japan\"\nkind: \"conference\"\nstart_date: \"2017-11-25\"\nend_date: \"2017-11-25\"\nwebsite: \"https://regional.rubykaigi.org/fukuoka02/\"\ncoordinates:\n  latitude: 33.5901838\n  longitude: 130.4016888\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/fukuoka-rubykaigi-02/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://regional.rubykaigi.org/fukuoka02/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/fukuoka-rubyistkaigi/series.yml",
    "content": "---\nname: \"Fukuoka RubyistKaigi\"\nwebsite: \"https://x.com/Fukuoka_RK\"\ntwitter: \"Fukuoka_RK\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\nyoutube_channel_id: \"\"\naliases:\n  - \"福岡Rubyist会議\"\n  - \"福岡Ruby会議\"\n  - \"Fukuoka RubyKaigi\"\n"
  },
  {
    "path": "data/garden-city-ruby/garden-city-ruby-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyblPURtJo18HwEYDayBiJJ-\"\ntitle: \"Garden City Ruby 2014\"\nkind: \"conference\"\ndescription: |-\n  January 3rd & 4th, 2014 at Atria Hotel in Bangalore\npublished_at: \"2014-01-03\"\nstart_date: \"2014-01-03\"\nend_date: \"2014-01-04\"\nlocation: \"Bangalore, India\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2014\nwebsite: \"https://web.archive.org/web/20150210162607/http://2014.gardencityruby.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#A12C32\"\ncoordinates:\n  latitude: 12.9628669\n  longitude: 77.57750899999999\naliases:\n  - Garden City RubyConf 2014\n"
  },
  {
    "path": "data/garden-city-ruby/garden-city-ruby-2014/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20150210162607/http://2014.gardencityruby.org/\n\n# Photos Day 1: http://www.flickr.com/photos/prakblr/sets/72157639522648265/\n# Photos Day 2: http://www.flickr.com/photos/prakblr/sets/72157639557496894/\n\n# Schedule: https://web.archive.org/web/20161223180157/http://confreaks.tv/events/gardencityruby2014\n\n## Day 1 - 2014-01-03\n\n- id: \"chad-fowler-garden-city-ruby-2014\"\n  title: \"Keynote: Disposable Components\"\n  raw_title: \"Garden City Ruby 2014 - Keynote by Chad Fowler\"\n  speakers:\n    - Chad Fowler\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-03\"\n  published_at: \"2014-01-27\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"4LMWsFbj6js\"\n\n- id: \"yogi-kulkarni-garden-city-ruby-2014\"\n  title: \"Lessons Learnt Building India's E-Commerce Supply Chain in Ruby\"\n  raw_title: \"Garden City Ruby 2014 - Lessons Learnt Building India's E-Commerce Supply Chain in Ruby\"\n  speakers:\n    - Yogi Kulkarni\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-03\"\n  published_at: \"2014-01-27\"\n  description: |-\n    By Yogi Kulkarni\n\n    In 2012 Flipkart's supply chain system was re-built as a service oriented architecture with Ruby at its core.\n\n    This talk will cover our experiences designing, building and scaling a mission-critical Ruby-based system where data integrity and performance is vital.\n\n    Dealing with cross-service transaction integrity\n    JRuby - the good, bad & ugly\n    Coordinating gem upgrades across multiple services\n    Performance tuning to get predictable response times - taming queries, external calls, GC, locks\n    Monitoring & profiling production systems\n    Ruby app servers: Trinidad vs Passenger vs Unicorn\n    Challenges in ramping up teams on Ruby\n    etc\n  video_provider: \"youtube\"\n  video_id: \"FXg2n7Uf4DY\"\n\n- id: \"tejas-deinkar-garden-city-ruby-2014\"\n  title: \"Native Extensions Served 3 Ways\"\n  raw_title: \"Garden City Ruby 2014 - Native Extensions Served 3 Ways by Tejas Deinkar\"\n  speakers:\n    - Tejas Deinkar\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-03\"\n  published_at: \"2014-01-27\"\n  description: |-\n    New runtimes, technologies and languages keep popping up, and there is a need for libraries that work across language, and across runtimes.\n\n    This talk will contrast some of the ways to build a native (usually C/C++) extension, and integrate them with your application. We'll look at how to build a native extension, while staying within the paradigm of the language.\n\n    We will be covering (in some detail): * Native C extensions using MRI/Rbx APIs (and contrasting it with the python API possibly) * SWIG to automatically generate wrapper code * FFI to build libraries that work across multiple implementations of ruby\n\n  video_provider: \"youtube\"\n  video_id: \"bI5oJr4ueQc\"\n\n- id: \"coby-randquist-garden-city-ruby-2014\"\n  title: \"A Bit of History\"\n  raw_title: \"Garden City Ruby 2014 - A Bit of History by Coby Randquist\"\n  speakers:\n    - Coby Randquist\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-03\"\n  published_at: \"2014-01-27\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"UPRFRa4vdmk\"\n\n- id: \"sakshi-jain-garden-city-ruby-2014\"\n  title: \"The Rails Girls Summer of Code Journey\"\n  raw_title: \"Garden City Ruby 2014 - The Rails GIrls Summer of Code Journey\"\n  speakers:\n    - Sakshi Jain\n    - Pallavi Shastry\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-03\"\n  published_at: \"2014-01-28\"\n  description: |-\n    By Sakshi Jain and Pallavi Shastry\n\n    The Rails Girls Summer of Code found me as a Ruby enthusiast. A little syntactical knowledge of Ruby took me to the glamour of Rails Girls SoC. Me and my partner, Pallavi Shastry, from Bengaluru, chose to work for diaspora, a privacy-aware decentralized, social network. Before contributing to diaspora, we tried our hands at Rails Girls Rails App Generator. The generator adds comments targeted at Rails Girls students to migrations, routes, controllers, models and views. It omits more advanced things like the respond_to blocks and jason stuff in controllers etc. This project also includes a Jekyll-based website on Github Pages which explains things briefly and gives pointers to guides or other resources. After completing the Rails Girls App Generator project, we dived into diaspora* which did sound more like learning to swim in a big ocean instead of a pool! The diaspora* issues that were assigned to us by our mentor were: 1. Blocking people from the profile page 2. Adopt a pull request 3. Full content in email notification for public posts 4. No content in email notification for limited posts We got 2 pull requests merged into diaspora*. Learnt about the testing workflow, rails internationalization, ActionMailers and a lot more. The open source journey with Rails Girls Summer of Code helped me build my confidence and made me realize that I too have an amazing chance to change the world and make things better and happen! The talk will surely benefit the students who wish to apply for RGSOC next time. The attendees of the conference might get inspired to become coaches for the future Rails Girls. The attendees could also help girls to understand Ruby on Rails technology and help them contribute to open source. Hopefully, there will be more RGSOC participants from India, in future.\n\n  video_provider: \"youtube\"\n  video_id: \"26DzU6MPr4E\"\n\n- id: \"chad-fowler-garden-city-ruby-2014-panel-programming-languages-an\"\n  title: \"Panel: Programming Languages and The Evolution of Ruby\"\n  raw_title: \"Garden City Ruby 2014 - Panel\"\n  speakers:\n    - Chad Fowler\n    - Yogi Kulkarni\n    - Hemant Kumar\n    - Baishampayan Ghose\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-03\"\n  published_at: \"2014-01-30\"\n  description: |-\n    Panel Members: Chad Fowler, Yogi Kulkarni, Hemant Kumar, and Baishampayan Ghose\n\n    Discussion on Programming languages and evolution of Ruby. This will be a unique opportunity to learn how good programmers learn new programming languages and as a Rubyist what we should be doing next to improve ourselves.\n\n  video_provider: \"youtube\"\n  video_id: \"zmGEUorbkPc\"\n\n- id: \"aman-king-garden-city-ruby-2014\"\n  title: \"Simple Ruby DSL Techniques: Big Project Impact!\"\n  raw_title: \"Garden City Ruby 2014 - Simple Ruby DSL Techniques: Big Project Impact!\"\n  speakers:\n    - Aman King\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-03\"\n  published_at: \"2014-01-29\"\n  description: |-\n    By Aman King\n\n    Will showcase real-world project code, highlighting custom-written Ruby DSLs that contribute to project success by improving team productivity. Ranging from simple authentication rules to complex social networking capabilities, DSLs can help tackle cross-cutting requirements and domain-specific abstractions. Benefits include faster story development, easier bug fixes, and deeper technical exposure for team members. Will also talk about some gotchas.\n\n    Will explain multiple techniques for creating DSLs within a Ruby project, including simple OO code without any metaprogramming, to medium-complexity use of mixins, to advanced usage of metaprogramming.\n\n  video_provider: \"youtube\"\n  video_id: \"E1rH2bcWN5A\"\n\n- id: \"prateek-dayal-garden-city-ruby-2014\"\n  title: \"Closing Keynote: Coding_Your_Business()\"\n  raw_title: \"Garden City Ruby 2014 - Closing Keynote by Prateek Dayal\"\n  speakers:\n    - Prateek Dayal\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-03\"\n  published_at: \"2014-01-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DwcCwdyLkBI\"\n\n## Day 2 - 2014-01-04\n\n- id: \"ajey-gore-garden-city-ruby-2014\"\n  title: \"Lorum Ipsum\"\n  raw_title: \"Garden City Ruby 2014 - Lorum Ipsum by Ajey Gore\"\n  speakers:\n    - Ajey Gore\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-04\"\n  published_at: \"2014-01-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8CqAHH9jp6A\"\n\n- id: \"gautam-rege-garden-city-ruby-2014\"\n  title: \"The Dark Side of Ruby\"\n  raw_title: \"Garden City Ruby 2014 - The Dark Side of Ruby by Gautam Rege\"\n  speakers:\n    - Gautam Rege\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-04\"\n  published_at: \"2014-01-29\"\n  description: |-\n    I love Ruby! But as in any relationship, to love means that you have to accept the \"dark side\" too! Ruby is human and has a lot of gotchas, tricks, wierdness and sometimes scary features that I plan to highlight. This talk aims to provide the \"Ah-ha!\" moments when working in Ruby.\n\n    This talk is for beginners and experts alike - in fact, I tag slides to mark their level and beginners can choose to tune out of the heavy stuff! My talk shall cover the dark side of the following features of Ruby (in no particular order)\n\n    Base Conversions\n    Infinity\n    Keywords\n    method missing\n    Module inheritance (it exists!)\n    Curried Procs\n    Cherry picking module methods\n    Oniguruma games\n    procs, blocks and my friend stubby.\n    Object ids\n    ==, ===, eql? and equal?\n    and more...\n    As with most of my talks, humor play an important role and I shall aim to get everyone high on Ruby with a deep dive!\n\n  video_provider: \"youtube\"\n  video_id: \"-oorcRJ2Kfg\"\n\n- id: \"arnab-deka-garden-city-ruby-2014\"\n  title: \"I've Got Your Number: Machine Learning in Ruby\"\n  raw_title: \"Garden City Ruby 2014 - I've got your number: Machine Learning in Ruby\"\n  speakers:\n    - Arnab Deka\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-04\"\n  published_at: \"2014-01-29\"\n  description: |-\n    By Arnab Deka\n\n    Would you like to do some OCR using Ruby and learn some machine-learning along the way?\n\n    In this talk, first up, we'll have a quick demo where an attendee writes down a digit on a sticky note and a Ruby program tries to to recognize it. Then we'll pick it apart, covering:\n\n    the basics of machine-learning (and different applications)\n    brief look into the Math behind supervised learning (classification)\n    (mostly) hand-rolled code applying this Math\n    libraries/tools available to Rubyists (and choice of Ruby platforms) including weka, mahout, libsvm, and the Ruby Matrix class :)\n    ways to dive deeper into ML\n  video_provider: \"youtube\"\n  video_id: \"aCIoerxtQ3w\"\n\n- id: \"todo-garden-city-ruby-2014\"\n  title: \"Quiz\"\n  raw_title: \"Garden City Ruby 2014 - GCRC Quiz\"\n  speakers:\n    - TODO # TODO: MC: https://cln.sh/km1vns9r\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-04\"\n  published_at: \"2014-01-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"UuWpfkyKXhk\"\n\n- id: \"lightning-talks-garden-city-ruby-2014\"\n  title: \"Lightning Talks\"\n  raw_title: \"Garden City Ruby 2014 - Lightning Talks\"\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-04\"\n  published_at: \"2014-01-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"xjCjydbQpI4\"\n  talks:\n    - title: \"Lightning Talk: Smith\" # TODO: missing last name\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"smith-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"smith-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Smith # TODO: missing last name - https://cln.sh/19fCQ4lT\n\n    - title: \"Lightning Talk: Tri Hari\"\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tri-hari-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"tri-hari-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Tri Hari\n\n    - title: \"Lightning Talk: Kashyap\" # TODO: missing last name\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"kashyap-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"kashyap-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Kashyap # TODO: missing last name - https://cln.sh/LdbWWYJX\n\n    - title: \"Lightning Talk: Bilal Budhani\"\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"bilal-budhani-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"bilal-budhani-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Bilal Budhani\n\n    - title: \"Lightning Talk: Vinash\" # TODO: missing last name\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"vinash-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"vinash-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Vinash # TODO: missing last name - https://cln.sh/Lr1Dnzfy\n\n    - title: \"Lightning Talk: Satya Kalluri\"\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"satya-kalluri-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"satya-kalluri-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Satya Kalluri\n\n    - title: \"Lightning Talk: Sarish\" # TODO: missing last name\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"sarish-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"sarish-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Sarish # TODO: missing last name - https://cln.sh/WMy4qGFp\n\n    - title: \"Lightning Talk: Soru\" # TODO: missing last name\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"soru-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"soru-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Soru # TODO: missing last name - https://cln.sh/z97WYYpv\n\n    - title: \"Lightning Talk: TODO\" # TODO: missing talk title\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-1-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"todo-1-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name - https://cln.sh/YcPccQg6\n\n    - title: \"Lightning Talk: TODO\" # TODO: missing talk title\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-2-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"todo-2-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name - https://cln.sh/5NSHP2hf\n\n    - title: \"Lightning Talk: Niranjan Paranjape\"\n      event_name: \"Garden City Ruby 2014\"\n      date: \"2014-01-04\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"niranjan-paranjape-lighting-talk-garden-city-ruby-2014\"\n      video_id: \"niranjan-paranjape-lighting-talk-garden-city-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Niranjan Paranjape\n\n- id: \"vamsee-kanakala-garden-city-ruby-2014\"\n  title: \"Zero Downtime Deployments with Docker\"\n  raw_title: \"Garden City Ruby 2014 - Zero Downtime Deployments with Docker\"\n  speakers:\n    - Vamsee Kanakala\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-04\"\n  published_at: \"2014-01-30\"\n  description: |-\n    By Vamsee Kanakala\n\n    Increasingly developers are being pushed to understand the operations world of web application deployments as continuous delivery gains importance in the \"new normal\" world of agile developer workflows. Configuration management tools like Puppet and Chef are gaining popularity for precisely the same reason, as they allow developers to deal with \"infrastructure as code\". However, there is also a growing understanding that servers are better off being treated as immutable, to avoid the various complications that arise from constantly evolving/changing configurations. Docker is a tool that allows us to deploy various parts of a server into separate containers and let us save a container state so this can either be published or improved upon. This talk will allow us to understand all these concepts in order to achieve immutable servers and zero-downtime deployments.\n\n  video_provider: \"youtube\"\n  video_id: \"mQvIWIgQ1xg\"\n\n- id: \"pavan-sudarshan-garden-city-ruby-2014\"\n  title: \"Pharmacist or a Doctor - What Does Your Codebase Need?\"\n  raw_title: \"Garden City Ruby 2014 - Pharmacist or a Doctor - What does your codebase need?\"\n  speakers:\n    - Pavan Sudarshan\n    - Anandha Krishnan\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-04\"\n  published_at: \"2014-01-30\"\n  description: |-\n    By Pavan Sudarshan and Anandha Krishnan\n\n    You might know of every single code quality & metrics tool in the Ruby ecosystem and what they give you, but do you know:\n\n    Which metrics do you currently need?\n    Do you really need them?\n    How do you make your team members own them?\n    Wait, there was a metaphor in the title\n\n    While a pharmacist knows about pretty much every medicine out there and what it cures, its really a doctor who figures out what is required given the symptoms of a patient.\n\n    Just like the vitals recorded for healthy adults, infants, pregnant women or an accident patient in an ICU changes, your code base needs different metrics in different contexts to help you uncover problems.\n\n    Talk take aways\n\n    Through a lot of examples, the talk helps:\n\n    Identify the current state of your code base\n    Understand different metrics and what do they tell you about your code base\n    Drive your team towards continuously fixing problems uncovered by these metrics\n\n  video_provider: \"youtube\"\n  video_id: \"c-AuPryBSZs\"\n\n- id: \"hari-krishnan-garden-city-ruby-2014\"\n  title: \"Ruby Memory Model\"\n  raw_title: \"Garden City Ruby 2014 - Ruby memory Model by Hari Krishnan\"\n  speakers:\n    - Hari Krishnan\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-04\"\n  published_at: \"2014-01-30\"\n  description: |-\n    An intermediate level talk to understand the inner workings of Ruby Memory Model. Topics covered:\n\n    What is a Memory Model and why should I care\n    Evolution of Ruby Memory Model\n    What every developer should know about the memory management in Ruby\n    Design considerations\n    Having worked on several tech stacks (Java, CLR), where it is critical to understand the underlying Memory Model, I was curious to understand the details about Ruby Memory Management. I will be presenting my learning and experience about improving application performance and keeping a low memory footprint.\n\n  video_provider: \"youtube\"\n  video_id: \"d21z5Croq1I\"\n\n- id: \"prakash-murthy-garden-city-ruby-2014\"\n  title: \"How Garden City Ruby Came To Be\"\n  raw_title: \"Garden City Ruby 2014 - How Garden City Ruby came to be by Prakash Murthy\"\n  speakers:\n    - Prakash Murthy\n  event_name: \"Garden City Ruby 2014\"\n  date: \"2014-01-04\"\n  published_at: \"2014-01-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"RvlmVKf-NDs\"\n"
  },
  {
    "path": "data/garden-city-ruby/garden-city-ruby-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYw6pbw7bIsfxqJK6D2z-7G\"\ntitle: \"Garden City Ruby 2015\"\nkind: \"conference\"\ndescription: |-\n  January 10, 2015, Bangalore\nstart_date: \"2015-01-10\"\nend_date: \"2015-01-10\"\nlocation: \"Bangalore, India\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\nwebsite: \"https://web.archive.org/web/20161226185837/http://2015.gardencityruby.org\"\nbanner_background: \"#D94152\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D94152\"\ncoordinates:\n  latitude: 12.9628669\n  longitude: 77.57750899999999\naliases:\n  - Garden City RubyConf 2015\n"
  },
  {
    "path": "data/garden-city-ruby/garden-city-ruby-2015/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20161226185837/http://2015.gardencityruby.org\n# Photos: https://www.flickr.com/photos/131361710@N02/sets/72157650452569590\n# Schedule: http://gardencityruby.github.io/GCRC2015/program\n\n# Registration\n\n# Welcome Note\n\n- id: \"konstantin-haase-garden-city-ruby-2015\"\n  title: \"Opening Keynote: Abstract Thoughts on Abstract Things\"\n  raw_title: \"Garden City Ruby Conference - Opening Keynote\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"Garden City Ruby 2015\"\n  date: \"2015-01-10\"\n  published_at: \"2015-02-06\"\n  description: |-\n    By,  Konstantin Haase\n\n  video_provider: \"youtube\"\n  video_id: \"dHiE6egJPjY\"\n\n- id: \"vipul-a-m-garden-city-ruby-2015\"\n  title: \"Active Record Can't Do It? Arel can!\"\n  raw_title: \"Garden City Ruby Conference - ActiveRecord can't do it? Arel can!\"\n  speakers:\n    - Vipul A M\n    - Prathamesh Sonpatki\n  event_name: \"Garden City Ruby 2015\"\n  date: \"2015-01-10\"\n  published_at: \"2015-02-06\"\n  description: |-\n    By, Vipul A Prathamesh Sonpatki\n\n    ActiveRecord can't do it? Arel can! Active Record is awesome. But how does ActiveRecord handle generating complex SQL queries? Under the hood it's handled by Arel. Most of the time, Rails developers don't have to know about how Arel works. But sometimes Active Record can't satisfy our needs. Also Arel has many strengths not exposed through Active Record. Let's experiment with Arel directly and wield great SQL power in database agnostic way. Oh and did I mention, this is a fun talk, even for us, to “perform”.\n\n  video_provider: \"youtube\"\n  video_id: \"94ufKHERZ1k\"\n\n# Coffee break\n\n- id: \"ranjeet-singh-garden-city-ruby-2015\"\n  title: \"Immutability Matters\"\n  raw_title: \"Garden City Ruby Conference - Immutability Matters\"\n  speakers:\n    - Ranjeet Singh\n  event_name: \"Garden City Ruby 2015\"\n  date: \"2015-01-10\"\n  published_at: \"2015-02-06\"\n  description: |-\n    By, Ranjeet Singh\n\n    The Ruby codebase and standard libraries make heavy use of mutable objects, as does pretty much any mainstream language. Mutable objects are not thread-safe, comparatively harder to maintain and write tests for, and with the resulting tests being slow and brittle. Thus, it becomes very hard to understand applications and libraries written using mutable object states to pass values around and perform operation on those values. Immutability resolves a lot of concurrency issues (race conditions, dirty read/write etc.), and also simplifies the codebase and test cases.\n\n  video_provider: \"youtube\"\n  video_id: \"PSQ547GXUno\"\n\n- id: \"anmol-agarwal-garden-city-ruby-2015\"\n  title: \"Fun with Ruby and Arduino\"\n  raw_title: \"Garden City Ruby Conference - Fun with Ruby and Arduino\"\n  speakers:\n    - Anmol Agarwal\n  event_name: \"Garden City Ruby 2015\"\n  date: \"2015-01-10\"\n  published_at: \"2015-02-06\"\n  description: |-\n    By, Anmol Agarwal\n\n    “Internet of things” is the concept of basically connecting any device with an on and off switch to the Internet. IoT has been possible through devices like Arduino, Raspberry Pi and many more. Although most of the APIs to work with them are available in Ruby, I haven’t seen many projects programmed in Ruby, but C++, Python or JS. I would like to share my approach, resources etc I learned from and show things that are possible. I hope audience would learn new possibilities with Ruby and not have to spent time learning a new language to interact with hardware.\n\n  video_provider: \"youtube\"\n  video_id: \"t2jL0OrpILw\"\n\n# Break\n\n- id: \"monika-m-garden-city-ruby-2015\"\n  title: \"WAT!! ActiveRecord Callbacks\"\n  raw_title: \"Garden City Ruby Conference - WAT!! ActiveRecord Callbacks\"\n  speakers:\n    - Monika M\n  event_name: \"Garden City Ruby 2015\"\n  date: \"2015-01-10\"\n  published_at: \"2015-02-06\"\n  description: |-\n    By, Monika M\n\n    The talk is about the gotchas of ActiveRecord callbacks even in the most common usage patterns and touches upon some possible alternatives to avoid each of these pitfalls. As Rails developers most of us would have inevitably have run into callbacks. This is something easy to get started with but is even easier to lead you into unexpected behaviour in production. Also, due to their unobtrusive nature they can become forgotten landmines. Structured in the popular and fun “WAT” style, the focus is mostly on beginner to intermediate levels, others might find one or two anecdotes surprising.\n\n  video_provider: \"youtube\"\n  video_id: \"bQBC501kiRY\"\n\n# Lightning Talks\n\n# Lunch\n\n- id: \"paolo-nusco-perrotta-garden-city-ruby-2015\"\n  title: \"Keynote: Wrapping Your Head Around Git\"\n  raw_title: \"Garden City Ruby Conference - Keynote: Wrapping Your Head Around Git\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"Garden City Ruby 2015\"\n  date: \"2015-01-10\"\n  published_at: \"2015-02-06\"\n  description: |-\n    By, Paolo Perrotta\n\n    A confession: I used Git for months without really understanding what was going on. I knew all the basic commands, but I still got stranded when something went wrong. Why did my rebase fail? How did I manage to mess up the remote?\n\n    Then I found the key to Git: the unfamiliar .git directory. That was my lightbulb moment. Once I understood the underlying model, everything\n    about Git clicked into place. Things that used to be baffling and complicated\n    suddenly looked simple and elegant.\n\n    Let me share this lightbulb with you. It will take you less than an hour to wrap your head around Git.\n\n  video_provider: \"youtube\"\n  video_id: \"RwYbl_tpoVE\"\n\n- id: \"vijayanand-nandam-garden-city-ruby-2015\"\n  title: \"Capacity Planning with Capybara and RabbitMQ\"\n  raw_title: \"Garden City Ruby Conference - Capacity planning with Capybara and RabbitMQ\"\n  speakers:\n    - Vijayanand Nandam\n  event_name: \"Garden City Ruby 2015\"\n  date: \"2015-01-10\"\n  published_at: \"2015-02-06\"\n  description: |-\n    By, Vijayanand Nandam\n\n    The number of users a web app can handle simultaneously is tricky to determine. Often we go by intuition and choose a deployment architecture which is either insufficient or oversized. Most web bench marking tools, like apache bench, are designed to benchmark the web server, and end-up provide unreliable information as the test scenario is far off from real world usage. Capybara, the defacto acceptance testing framework in rails world, combined with rabbitmq, can help us in determining bottlenecks and choosing the right deployment architecture.\n\n  video_provider: \"youtube\"\n  video_id: \"BD4p1i54gWo\"\n\n# Coffee break\n\n- id: \"smit-shah-garden-city-ruby-2015\"\n  title: \"Resilient by Design\"\n  raw_title: \"Garden City Ruby Conference - Resilient by Design\"\n  speakers:\n    - Smit Shah\n  event_name: \"Garden City Ruby 2015\"\n  date: \"2015-01-10\"\n  published_at: \"2015-02-06\"\n  description: |-\n    By, Smit Shah\n\n    Modern distributed systems have aggressive requirements around uptime and performance, they need to face harsh realities such as sudden rush of visitors, network issues, tangled databases and other unforeseen bugs. With so many moving parts involved even in the simplest of services, it becomes mandatory to adopt defensive patterns which would guard against some of these problems and identify anti-patterns before they trigger cascading failures across systems. This talk is for all those developers who hate getting a oncall at 4 AM in the morning\n\n  video_provider: \"youtube\"\n  video_id: \"yTkaq26YgDU\"\n\n- id: \"akanksha-agarwal-garden-city-ruby-2015\"\n  title: \"Rubinius — Ruby Implemented with Ruby\"\n  raw_title: \"Garden City Ruby Conference - Rubinius — Ruby implemented with Ruby\"\n  speakers:\n    - Akanksha Agarwal\n    - Sana Khan\n  event_name: \"Garden City Ruby 2015\"\n  date: \"2015-01-10\"\n  published_at: \"2015-02-06\"\n  description: |-\n    By, Akanksha Agarwal & Sana Khan\n\n    Rubinius is an alternative Ruby language implementation. We would be giving a brief overview of Rubinius Internals and would be majorly talking about the Heap Dump interface that Rubinius provides for analysis of memory dumps.\n\n  video_provider: \"youtube\"\n  video_id: \"8t17itEbBbY\"\n\n# Coffee break\n\n- id: \"konstantin-haase-garden-city-ruby-2015-fishbowl-discussion\"\n  title: \"Fishbowl Discussion\"\n  raw_title: \"Garden City Ruby Conference - Panel Discussion\"\n  speakers:\n    # - TODO: MC1\n    # - TODO: MC2\n    - Konstantin Haase\n    - Monika M\n    # - TODO: Panelist 1\n    # - TODO: Panelist 2\n  event_name: \"Garden City Ruby 2015\"\n  date: \"2015-01-10\"\n  published_at: \"2015-02-06\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"_Jv7ftgQ3Bc\"\n# TODO: missing talk: Sidu Ponnappa & Niranjan Paranjape - Keynote\n\n# Closing Note\n"
  },
  {
    "path": "data/garden-city-ruby/series.yml",
    "content": "---\nname: \"Garden City Ruby\"\nwebsite: \"https://gardencityruby.org\"\ntwitter: \"gardencityrb\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Garden City Ruby\"\ndefault_country_code: \"IN\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/geneva-rb/geneva-rb-meetup/event.yml",
    "content": "---\nid: \"geneva-rb-meetup\"\ntitle: \"Geneva.rb Meetup\"\nlocation: \"Geneva, Switzerland\"\ndescription: |-\n  Welcome to the exciting world of Ruby and Ruby on Rails in Geneva!\nkind: \"meetup\"\npublished_at: \"2025-02-04\"\nyear: 2025\nbanner_background: |-\n  linear-gradient(to bottom, #9A2528, #9A2528 100%) left top / 50% 100% no-repeat, /* Left side */\n  linear-gradient(to bottom, #FFFFFF, #FFFFFF 100%) right top / 50% 100% no-repeat /* Right side */\nfeatured_background: \"#9A2528\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://www.meetup.com/geneva-rb\"\ncoordinates:\n  latitude: 46.2043907\n  longitude: 6.1431577\n"
  },
  {
    "path": "data/geneva-rb/geneva-rb-meetup/videos.yml",
    "content": "---\n- id: \"geneva-rb-october-2023\"\n  title: \"Geneva.rb October 2023\"\n  event_name: \"Geneva.rb October 2023\"\n  date: \"2023-10-30\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-october-2023\"\n  description: |-\n    This first meeting will be fairly informal. We'll do an initial round of introductions (please prepare a few words about yourself in french or english, 2-3 minutes per person). We'll then discuss the expectations we have for this group and the program for the next meeting on November 7.\n\n    Yannis will then give a short presentation of a new feature of Ruby 3.2: The Data class.\n\n    https://www.meetup.com/geneva-rb/events/295865704\n  talks:\n    - title: \"New Feature of Ruby 3.2: The Data class\"\n      event_name: \"Geneva.rb October 2023\"\n      date: \"2023-10-03\"\n      speakers:\n        - Yannis Jaquet\n      id: \"yannis-jaquet-geneva-rb-october-2023\"\n      video_id: \"yannis-jaquet-geneva-rb-october-2023\"\n      video_provider: \"not_recorded\"\n      description: |-\n        Yannis will then give a short presentation of a new feature of Ruby 3.2: The Data class.\n\n- id: \"geneva-rb-november-2023\"\n  title: \"Geneva.rb November 2023\"\n  event_name: \"Geneva.rb November 2023\"\n  date: \"2023-11-07\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-november-2023\"\n  description: |-\n    Sean Carroll, Engineering Manager at GitLab, will talk about the Ruby on Rails stack used by GitLab, and in particular the repository and commits views.\n\n    Drinks will be served after the presentation.\n\n    https://www.meetup.com/geneva-rb/events/296528746\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/4/3/8/600_516449752.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/4/3/8/600_516449752.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/4/3/8/600_516449752.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/4/3/8/600_516449752.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/4/3/8/600_516449752.webp?w=750\"\n  talks:\n    - title: \"git push: How GitLab manages git data\"\n      event_name: \"Geneva.rb November 2023\"\n      date: \"2023-11-07\"\n      speakers:\n        - Sean Carroll\n      id: \"sean-carroll-geneva-rb-november-2023\"\n      video_id: \"sean-carroll-geneva-rb-november-2023\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/4/3/8/600_516449752.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/4/3/8/600_516449752.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/4/3/8/600_516449752.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/4/3/8/600_516449752.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/4/3/8/600_516449752.webp?w=750\"\n      description: |-\n        Sean Carroll, Engineering Manager at GitLab, will talk about the Ruby on Rails stack used by GitLab, and in particular the repository and commits views.\n\n- id: \"geneva-rb-december-2023\"\n  title: \"Geneva.rb December 2023\"\n  event_name: \"Geneva.rb December 2023\"\n  date: \"2023-12-05\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-december-2023\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/2/a/8/600_517169352.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/2/a/8/600_517169352.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/2/a/8/600_517169352.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/2/a/8/600_517169352.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/2/a/8/600_517169352.webp?w=750\"\n  description: |-\n    Meetup proudly sponsored my mobilidée.\n    ---------------------------------\n    Join us for a dynamic meetup where Alexis Bernard from RoRvsWild will unleash the secrets to high-performance Ruby on Rails applications.\n\n    Drawing upon principles akin to Anthony Hobday's \"Visual design rules you can safely follow every time,\" Alexis will offer you a robust playbook for crafting responsive, efficient applications.\n\n    Delve into best practices for HTTP, Ruby on Rails, databases, and servers, and discover when to adhere to the rules or when breaking them could set your code apart.\n\n    Don't miss this opportunity to enhance your apps and your expertise under the guidance of a seasoned Ruby specialist.\n\n    Gear up for an enlightening evening – because when it comes to performance, good enough never is.\n\n    Drinks will be served after the presentation.\n\n    https://www.meetup.com/geneva-rb/events/297258824\n  talks:\n    - title: \"Everyday Performance Rules for Ruby on Rails Developers\"\n      event_name: \"Geneva.rb December 2023\"\n      date: \"2023-12-05\"\n      speakers:\n        - Alexis Bernard\n      id: \"alexis-bernard-geneva-rb-december-2023\"\n      video_id: \"alexis-bernard-geneva-rb-december-2023\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/2/a/8/600_517169352.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/2/a/8/600_517169352.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/2/a/8/600_517169352.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/2/a/8/600_517169352.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/2/a/8/600_517169352.webp?w=750\"\n      description: |-\n        Join us for a dynamic meetup where Alexis Bernard from RoRvsWild will unleash the secrets to high-performance Ruby on Rails applications.\n\n        Drawing upon principles akin to Anthony Hobday's \"Visual design rules you can safely follow every time,\" Alexis will offer you a robust playbook for crafting responsive, efficient applications.\n\n        Delve into best practices for HTTP, Ruby on Rails, databases, and servers, and discover when to adhere to the rules or when breaking them could set your code apart.\n\n- id: \"geneva-rb-january-2024\"\n  title: \"Geneva.rb January 2024\"\n  event_name: \"Geneva.rb January 2024\"\n  date: \"2024-01-10\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-january-2024\"\n  description: |-\n    🌟 Meetup kindly sponsored by mobilidée and GitLab\n\n    🚀 Sean Carroll (Gitlab) will be back to showcase the magic of integrating your Ruby on Rails web application into a sleek iOS app. He'll dive into the wonders of Hotwire/Strada, revealing how these powerful tools can transform your web app into a native iOS experience.\n\n    🍹 Drinks will be served after the presentation\n\n    https://www.meetup.com/geneva-rb/events/297635660\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/a/5/3/600_517891315.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/a/5/3/600_517891315.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/a/5/3/600_517891315.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/a/5/3/600_517891315.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/a/5/3/600_517891315.webp?w=750\"\n  talks:\n    - title: \"Turbo Native: iOS apps with Hotwire Rails\"\n      event_name: \"Geneva.rb January 2024\"\n      date: \"2024-01-10\"\n      speakers:\n        - Sean Carroll\n      id: \"sean-carroll-geneva-rb-january-2024\"\n      video_id: \"sean-carroll-geneva-rb-january-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/a/5/3/600_517891315.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/a/5/3/600_517891315.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/a/5/3/600_517891315.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/a/5/3/600_517891315.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/a/5/3/600_517891315.webp?w=750\"\n      description: |-\n        Sean Carroll (Gitlab) will be back to showcase the magic of integrating your Ruby on Rails web application into a sleek iOS app. He'll dive into the wonders of Hotwire/Strada, revealing how these powerful tools can transform your web app into a native iOS experience.\n\n- id: \"geneva-rb-february-2024\"\n  title: \"Geneva.rb February 2024\"\n  event_name: \"Geneva.rb February 2024\"\n  date: \"2024-02-07\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-february-2024\"\n  description: |-\n    🙏 Meetup kindly sponsored by mobilidée and RoRvsWild!\n\n    Get ready for an exciting Ruby/Rails meetup where YOUR insights take center stage!\n    We're inviting each one of you to share either your favorite Ruby gem 🔻 or a programming tip or trick 🪄 that's close to your heart.\n\n    This is a fantastic opportunity to showcase your favorite tools, discuss innovative techniques, and learn from the collective wisdom of our community.\n\n    What to Expect:\n\n    🎤 Roundtable Presentations: You'll have 5-10 minutes to present your chosen gem(s) or tip(s). While slides are not mandatory, if you choose to use them, please prepare with Google Slides. This will help us share your presentation smoothly with the team and ensure seamless transitions between speakers.\n\n    🍹 Networking with Drinks and Snacks: After the presentations, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby and Rails. A great chance to connect with fellow developers and forge lasting friendships.\n\n    🙌 Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey, we warmly welcome you to join and contribute. This meetup is about mutual learning and sharing, so don't hesitate to participate, no matter your level of expertise.\n\n    https://www.meetup.com/geneva-rb/events/297635673\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n  talks:\n    - title: \"Intro: Share Your Favorite Gem, Tip, or Trick!\"\n      event_name: \"Geneva.rb February 2024\"\n      date: \"2024-02-07\"\n      speakers:\n        - Yannis Jaquet\n      id: \"intro-geneva-rb-february-2024\"\n      video_id: \"intro-geneva-rb-february-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      description: |-\n        Get ready for an exciting Ruby/Rails meetup where YOUR insights take center stage!\n\n        We're inviting each one of you to share either your favorite Ruby gem 🔻 or a programming tip or trick 🪄 that's close to your heart.\n\n        This is a fantastic opportunity to showcase your favorite tools, discuss innovative techniques, and learn from the collective wisdom of our community.\n\n        https://ruby.social/@genevarb/111894836694599178\n\n    - title: \"i18n-tasks\"\n      event_name: \"Geneva.rb February 2024\"\n      date: \"2024-02-07\"\n      speakers:\n        - Yannis Jaquet\n      id: \"yannis-jaquet-geneva-rb-february-2024\"\n      video_id: \"yannis-jaquet-geneva-rb-february-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      description: |-\n        Yannis opened the session with an introduction to [i18n-tasks](https://github.com/glebm/i18n-tasks), a vital gem for Rails developers dealing with internationalization. This tool simplifies managing translations by identifying missing or unused keys and generating translation files directly from the source code, ensuring that your app speaks every user's language fluently.\n      additional_resources:\n        - name: \"glebm/i18n-tasks\"\n          type: \"repo\"\n          url: \"https://github.com/glebm/i18n-tasks\"\n\n    - title: \"standard & danger\"\n      event_name: \"Geneva.rb February 2024\"\n      date: \"2024-02-07\"\n      speakers:\n        - Olivier Robert\n      id: \"olivier-robert-geneva-rb-february-2024\"\n      video_id: \"olivier-robert-geneva-rb-february-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      description: |-\n        Olivier shared a Gemfile structuring tip for enhancing team collaboration. By dividing the Gemfile, teams can have a shared dependency list plus individual `Gemfile.local` for personal tools.\n\n        He spotlighted https://github.com/testdouble/standard, a RuboCop-based gem for consistent coding styles, and https://github.com/danger/danger, which automates code reviews by pre-screening pull requests. These gems streamline workflow and ensure code quality.\n      additional_resources:\n        - name: \"testdouble/standard\"\n          type: \"repo\"\n          url: \"https://github.com/testdouble/standard\"\n\n        - name: \"danger/danger\"\n          type: \"repo\"\n          url: \"https://github.com/danger/danger\"\n\n    - title: \"flipper & Stripe webhooks\"\n      event_name: \"Geneva.rb February 2024\"\n      date: \"2024-02-07\"\n      speakers:\n        - Ben Colon\n      id: \"ben-colon-geneva-rb-february-2024\"\n      video_id: \"ben-colon-geneva-rb-february-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      description: |-\n        Ben's contribution focused on the https://github.com/jnunemaker/flipper gem, particularly its ability to manage feature flags, enabling developers to toggle features on and off in production. This approach allows for safer testing and incremental feature releases.\n\n        He also shared insights into testing Stripe webhooks effectively within Rails apps, leveraging stripe test clocks (https://stripe.com/docs/billing/testing/test-clocks) for time manipulation during tests.\n      additional_resources:\n        - name: \"jnunemaker/flipper\"\n          type: \"repo\"\n          url: \"https://github.com/jnunemaker/flipper\"\n\n        - name: \"Stripe Test Clocks\"\n          type: \"documentation\"\n          url: \"https://stripe.com/docs/billing/testing/test-clocks\"\n\n    - title: \"strong_migrations, scenic & fx\"\n      event_name: \"Geneva.rb February 2024\"\n      date: \"2024-02-07\"\n      speakers:\n        - Jean-Charles Santi\n      id: \"jean-charles-santi-geneva-rb-february-2024\"\n      video_id: \"jean-charles-santi-geneva-rb-february-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      description: |-\n        Jean-Charles focused on database tools. https://github.com/ankane/strong_migrations guards against dangerous migrations by detecting and preventing them. https://github.com/scenic-views/scenic and https://github.com/teoljungberg/fx help manage database views and functions, ensuring that database schema changes are seamless and safe.\n\n        He also recommended the RailsConf talk \"rails db:migrate:even_safer\" (https://www.youtube.com/watch?v=uMcRCSiNzuc or https://www.rubyevents.org/talks/rails-db-migrate-even_safer) by Matt Duszynski for a dive into safe migration practices.\n      additional_resources:\n        - name: \"ankane/strong_migrations\"\n          type: \"repo\"\n          url: \"https://github.com/ankane/strong_migrations\"\n\n        - name: \"scenic-views/scenic\"\n          type: \"repo\"\n          url: \"https://github.com/scenic-views/scenic\"\n\n        - name: \"teoljungberg/fx\"\n          type: \"repo\"\n          url: \"https://github.com/teoljungberg/fx\"\n\n        - name: 'RailsConf talk \"rails db:migrate:even_safer\"'\n          type: \"link\"\n          url: \"https://www.rubyevents.org/talks/rails-db-migrate-even_safer\"\n\n    - title: \"pghero\"\n      event_name: \"Geneva.rb February 2024\"\n      date: \"2024-02-07\"\n      speakers:\n        - Alexis Bernard\n      id: \"alexis-bernard-geneva-rb-february-2024\"\n      video_id: \"alexis-bernard-geneva-rb-february-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/c/1/c/600_518599484.webp?w=750\"\n      description: |-\n        Alexis presented https://github.com/ankane/pghero, a comprehensive tool for PostgreSQL database monitoring. It shines a light on slow queries, suggests indexes, and provides a wealth of information on database performance, helping developers keep their databases efficient and responsive.\n      additional_resources:\n        - name: \"ankane/pghero\"\n          type: \"repo\"\n          url: \"https://github.com/ankane/pghero\"\n\n- id: \"geneva-rb-march-2024-1\"\n  title: \"Geneva.rb March 2024\"\n  event_name: \"Geneva.rb March 2024\"\n  date: \"2024-03-06\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-march-2024-1\"\n  description: |-\n    🙏 Meetup kindly sponsored by mobilidée and RoRvsWild!\n\n    In his latest blog post, Alexis Bernard (RoRvsWild) shared his insightful habits on running load tests, opening up a world of optimization for us. At our next meetup, Alexis will take this discussion from theory to practice with a live demonstration on a real production application!\n\n    Prepare to be captivated as Alexis expertly shows us how to initiate a load test using a variety of tools, and then, more importantly, how to decode the results. But that's not all—we'll dive deeper into the tech world by monitoring servers and profiling code, all in our quest to uncover those elusive bottlenecks.\n\n    Don't miss this opportunity to see load testing in action and to gain valuable knowledge that can transform your approach to application performance. Let's learn, engage, and optimize together!\n\n    What to Expect:\n    🎤 Presentation: A 30-45 minute presentation by Alexis Bernard\n\n    🍹 Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more. A great chance to connect with fellow developers and forge lasting friendships.\n\n    🙌 Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey, we warmly welcome you to join and contribute. This meetup is about mutual learning and sharing, so don't hesitate to participate, no matter your level of expertise.\n\n    https://www.meetup.com/geneva-rb/events/297635680\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/0/2/2/600_519208706.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/0/2/2/600_519208706.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/0/2/2/600_519208706.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/0/2/2/600_519208706.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/0/2/2/600_519208706.webp?w=750\"\n  talks:\n    - title: \"Live load testing on a real production app\"\n      event_name: \"Geneva.rb March 2024\"\n      date: \"2024-03-06\"\n      speakers:\n        - Alexis Bernard\n      id: \"alexis-bernard-geneva-rb-march-2024\"\n      video_id: \"alexis-bernard-geneva-rb-march-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/0/2/2/600_519208706.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/0/2/2/600_519208706.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/0/2/2/600_519208706.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/0/2/2/600_519208706.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/0/2/2/600_519208706.webp?w=750\"\n      description: |-\n        In his latest blog post, Alexis Bernard (RoRvsWild) shared his insightful habits on running load tests, opening up a world of optimization for us. At our next meetup, Alexis will take this discussion from theory to practice with a live demonstration on a real production application!\n\n        Prepare to be captivated as Alexis expertly shows us how to initiate a load test using a variety of tools, and then, more importantly, how to decode the results. But that's not all—we'll dive deeper into the tech world by monitoring servers and profiling code, all in our quest to uncover those elusive bottlenecks.\n\n        Don't miss this opportunity to see load testing in action and to gain valuable knowledge that can transform your approach to application performance. Let's learn, engage, and optimize together!\n\n        Blog Post: https://www.rorvswild.com/blog/2024/ruby-on-rails-load-testing-habits\n\n- id: \"geneva-rb-march-2024-2\"\n  title: \"Geneva.rb March 2024\"\n  event_name: \"Geneva.rb March 2024\"\n  date: \"2024-03-27\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-march-2024-2\"\n  description: |-\n    🙏 Meetup kindly sponsored by mobilidée and RoRvsWild!\n\n    Join us for an engaging session with Dimiter, who will explore the significant role of community contributions in enhancing consultancy success. Leveraging insights from thoughtbot's experiences, he'll share practical examples that highlight the benefits of being active in the community. Moreover, Dimiter will present a thoughtful argument on why product companies should consider giving back as well. This discussion promises to be insightful, offering valuable perspectives on fostering a culture of contribution. Don't miss out on this opportunity to gain new understandings and connect with like-minded professionals.\n\n    What to Expect:\n\n    🎤 Presentation: A 30-45 minute presentation\n    🍹 Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more. A great chance to connect with fellow developers and forge lasting friendships.\n    🙌 Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute. This meetup is about mutual learning and sharing, so don't hesitate to participate, no matter your level of expertise.\n\n    https://www.meetup.com/geneva-rb/events/299288500\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/5/7/1/1/600_519442289.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/5/7/1/1/600_519442289.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/5/7/1/1/600_519442289.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/5/7/1/1/600_519442289.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/5/7/1/1/600_519442289.webp?w=750\"\n  talks:\n    - title: \"Contribute!\"\n      event_name: \"Geneva.rb March 2024\"\n      date: \"2024-03-27\"\n      speakers:\n        - Dimiter Petrov\n      id: \"dimiter-petrov-geneva-rb-march-2024\"\n      video_id: \"dimiter-petrov-geneva-rb-march-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/5/7/1/1/600_519442289.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/5/7/1/1/600_519442289.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/5/7/1/1/600_519442289.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/5/7/1/1/600_519442289.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/5/7/1/1/600_519442289.webp?w=750\"\n      description: |-\n        Join us for an engaging session with Dimiter, who will explore the significant role of community contributions in enhancing consultancy success. Leveraging insights from thoughtbot's experiences, he'll share practical examples that highlight the benefits of being active in the community. Moreover, Dimiter will present a thoughtful argument on why product companies should consider giving back as well. This discussion promises to be insightful, offering valuable perspectives on fostering a culture of contribution. Don't miss out on this opportunity to gain new understandings and connect with like-minded professionals.\n\n- id: \"geneva-rb-april-2024\"\n  title: \"Geneva.rb April 2024\"\n  event_name: \"Geneva.rb April 2024\"\n  date: \"2024-04-16\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-april-2024\"\n  description: |-\n    🙏 Meetup kindly sponsored by mobilidée and RoRvsWild!\n\n    ✨ Hotwire has significantly altered the landscape of building interactive web applications with Ruby on Rails, marking a pivotal evolution toward seamless Full-Stack development.\n\n    With the release of Turbo 8, the ecosystem has gained new momentum, influencing how developers approach application design and interaction.\n\n    This session, led by Marco Roth, a core maintainer of Stimulus, StimulusReflex, and CableReady, dives into capabilities introduced with Turbo 8, reevaluating its impact on the whole Rails and Hotwire ecosystem.\n\n    What to Expect:\n    🎤 Presentation: A 30-45 minute presentation\n    🍹 Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more. A great chance to connect with fellow developers and forge lasting friendships.\n    🙌 Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute. This meetup is about mutual learning and sharing, so don't hesitate to participate, no matter your level of expertise.\n    📍 Exceptionally, this meetup will be held in a different room from the one we're used to. The room called \"Auditorium\" is located in the basement of the UOG, accessed via the main entrance, 3 place des Grottes.\n\n    https://www.meetup.com/geneva-rb/events/299288679\n  thumbnail_xs: \"https://files.speakerdeck.com/presentations/97f9ab3990084121bd0a65e2a3d33c49/slide_1.jpg?30137407\"\n  thumbnail_sm: \"https://files.speakerdeck.com/presentations/97f9ab3990084121bd0a65e2a3d33c49/slide_1.jpg?30137407\"\n  thumbnail_md: \"https://files.speakerdeck.com/presentations/97f9ab3990084121bd0a65e2a3d33c49/slide_1.jpg?30137407\"\n  thumbnail_lg: \"https://files.speakerdeck.com/presentations/97f9ab3990084121bd0a65e2a3d33c49/slide_1.jpg?30137407\"\n  thumbnail_xl: \"https://files.speakerdeck.com/presentations/97f9ab3990084121bd0a65e2a3d33c49/slide_1.jpg?30137407\"\n  talks:\n    - title: \"Revisiting the Hotwire Landscape after Turbo 8\"\n      event_name: \"Geneva.rb April 2024\"\n      date: \"2024-04-16\"\n      speakers:\n        - Marco Roth\n      id: \"marco-roth-geneva-rb-april-2024\"\n      video_id: \"marco-roth-geneva-rb-april-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://files.speakerdeck.com/presentations/97f9ab3990084121bd0a65e2a3d33c49/slide_1.jpg?30137407\"\n      thumbnail_sm: \"https://files.speakerdeck.com/presentations/97f9ab3990084121bd0a65e2a3d33c49/slide_1.jpg?30137407\"\n      thumbnail_md: \"https://files.speakerdeck.com/presentations/97f9ab3990084121bd0a65e2a3d33c49/slide_1.jpg?30137407\"\n      thumbnail_lg: \"https://files.speakerdeck.com/presentations/97f9ab3990084121bd0a65e2a3d33c49/slide_1.jpg?30137407\"\n      thumbnail_xl: \"https://files.speakerdeck.com/presentations/97f9ab3990084121bd0a65e2a3d33c49/slide_1.jpg?30137407\"\n      description: |-\n        Hotwire has significantly altered the landscape of building interactive web applications with Ruby on Rails, marking a pivotal evolution toward seamless Full-Stack development.\n\n        With the release of Turbo 8, the ecosystem has gained new momentum, influencing how developers approach application design and interaction.\n\n        This session, led by Marco Roth, a core maintainer of Stimulus, StimulusReflex, and CableReady, dives into capabilities introduced with Turbo 8, reevaluating its impact on the whole Rails and Hotwire ecosystem.\n\n- id: \"geneva-rb-may-2024\"\n  title: \"Geneva.rb May 2024\"\n  event_name: \"Geneva.rb May 2024\"\n  date: \"2024-05-14\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-may-2024\"\n  description: |-\n    🙏 Meetup kindly sponsored by mobilidée and RoRvsWild!\n\n    Vincent Pochet (Ruby42, Lago) will give an overview of timezone management in Ruby and in Rails application.\n\n    He will use Lago as an example to illustrate some real-life challenge and edge cases that developers can face when trying to deal with multi-timezone applications.\n\n    What to Expect:\n    🎤 Presentation: A 30-45 minute presentation\n    🍹 Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more. A great chance to connect with fellow developers and forge lasting friendships.\n    🙌 Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute. This meetup is about mutual learning and sharing, so don't hesitate to participate, no matter your level of expertise.\n\n    https://www.meetup.com/geneva-rb/events/299288843\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/0/5/7/600_520476951.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/0/5/7/600_520476951.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/0/5/7/600_520476951.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/0/5/7/600_520476951.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/0/5/7/600_520476951.webp?w=750\"\n  talks:\n    - title: \"Travel through Time (zones) with Ruby and Rails\"\n      event_name: \"Geneva.rb May 2024\"\n      date: \"2024-05-14\"\n      speakers:\n        - Vincent Pochet\n      id: \"vincent-pochet-geneva-rb-may-2024\"\n      video_id: \"vincent-pochet-geneva-rb-may-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/0/5/7/600_520476951.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/0/5/7/600_520476951.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/0/5/7/600_520476951.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/0/5/7/600_520476951.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/0/5/7/600_520476951.webp?w=750\"\n      description: |-\n        Vincent Pochet (Ruby42, Lago) will give an overview of timezone management in Ruby and in Rails application.\n\n        He will use Lago as an example to illustrate some real-life challenge and edge cases that developers can face when trying to deal with multi-timezone applications.\n\n- id: \"geneva-rb-june-2024\"\n  title: \"Geneva.rb June 2024\"\n  event_name: \"Geneva.rb June 2024\"\n  date: \"2024-06-05\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-june-2024\"\n  description: |-\n    🙏 Meetup kindly sponsored by mobilidée and RoRvsWild!\n\n    For this last meetup before the Summer break, Yannis (@yannis) will demonstrate how to use OpenAI's GPT-4 and Embedding APIs to implement a semantic search system in Ruby on Rails, using the pg_vector PostgreSQL extension and the neighbor gem. He will illustrate this with concrete examples from MyFoodRepo, the application he is currently working on.\n\n    What to Expect:\n    * A presentation of about 30-45 minutes\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    https://www.meetup.com/geneva-rb/events/299288852\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/8/6/2/f/600_521194351.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/8/6/2/f/600_521194351.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/8/6/2/f/600_521194351.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/8/6/2/f/600_521194351.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/8/6/2/f/600_521194351.webp?w=750\"\n  talks:\n    - title: \"Semantic search in RubyOnRails with GPT-4\"\n      event_name: \"Geneva.rb June 2024\"\n      date: \"2024-06-05\"\n      speakers:\n        - Yannis Jaquet\n      id: \"yannis-jaquet-geneva-rb-june-2024\"\n      video_id: \"yannis-jaquet-geneva-rb-june-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/8/6/2/f/600_521194351.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/8/6/2/f/600_521194351.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/8/6/2/f/600_521194351.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/8/6/2/f/600_521194351.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/8/6/2/f/600_521194351.webp?w=750\"\n      description: |-\n        For this last meetup before the Summer break, Yannis (@yannis) will demonstrate how to use OpenAI's GPT-4 and Embedding APIs to implement a semantic search system in Ruby on Rails, using the pg_vector PostgreSQL extension and the neighbor gem. He will illustrate this with concrete examples from MyFoodRepo, the application he is currently working on.\n\n- id: \"geneva-rb-september-2024\"\n  title: \"Geneva.rb September 2024\"\n  event_name: \"Geneva.rb September 2024\"\n  date: \"2024-09-18\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-september-2024\"\n  description: |-\n    Rafael Millán, a staff backend engineer at Inyova, a leading Swiss impact investing startup that uses Ruby on Rails heavily for their backend services, will share insights into how his team streamlined the ingestion of financial account data. He will discuss their approach to standardizing data from diverse sources, overcoming performance and reliability challenges, and ensuring seamless delivery to end users.\n\n    What to Expect:\n    * A presentation of about 30-45 minutes\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild!\n\n    https://www.meetup.com/geneva-rb/events/303018636\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/5/a/e/600_523178318.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/5/a/e/600_523178318.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/5/a/e/600_523178318.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/5/a/e/600_523178318.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/5/a/e/600_523178318.webp?w=750\"\n  talks:\n    - title: \"Optimizing Financial Data Ingestion at Inyova\"\n      event_name: \"Geneva.rb September 2024\"\n      date: \"2024-09-18\"\n      speakers:\n        - Rafael Millán\n      id: \"rafael-millan-geneva-rb-september-2024\"\n      video_id: \"rafael-millan-geneva-rb-september-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/5/a/e/600_523178318.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/5/a/e/600_523178318.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/5/a/e/600_523178318.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/5/a/e/600_523178318.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/5/a/e/600_523178318.webp?w=750\"\n      description: |-\n        Rafael Millán, a staff backend engineer at Inyova, a leading Swiss impact investing startup that uses Ruby on Rails heavily for their backend services, will share insights into how his team streamlined the ingestion of financial account data. He will discuss their approach to standardizing data from diverse sources, overcoming performance and reliability challenges, and ensuring seamless delivery to end users.\n\n- id: \"geneva-rb-october-2024\"\n  title: \"Geneva.rb October 2024\"\n  event_name: \"Geneva.rb October 2024\"\n  date: \"2024-10-16\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-october-2024\"\n  description: |-\n    Marco Roth (@marcoroth), core team member of StimulusReflex/CableReady and part of the Hotwire Contributors Team, will focus on the latest tools and best practices for Ruby on Rails and Hotwire developers.\n\n    He will explore how the new tools he has developed can streamline development, boost productivity, and enhance the overall developer experience within the Rails and Hotwire stack.\n\n    What to Expect:\n    * A presentation of about 30-45 minutes\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild!\n\n    https://www.meetup.com/geneva-rb/events/303018643\n  thumbnail_xs: \"https://files.speakerdeck.com/presentations/9ef1624742144bfaa9239e0e5d7fd2d3/preview_slide_0.jpg\"\n  thumbnail_sm: \"https://files.speakerdeck.com/presentations/9ef1624742144bfaa9239e0e5d7fd2d3/preview_slide_0.jpg\"\n  thumbnail_md: \"https://files.speakerdeck.com/presentations/9ef1624742144bfaa9239e0e5d7fd2d3/preview_slide_0.jpg\"\n  thumbnail_lg: \"https://files.speakerdeck.com/presentations/9ef1624742144bfaa9239e0e5d7fd2d3/preview_slide_0.jpg\"\n  thumbnail_xl: \"https://files.speakerdeck.com/presentations/9ef1624742144bfaa9239e0e5d7fd2d3/preview_slide_0.jpg\"\n  talks:\n    - title: \"Developer Tooling for the Modern Rails & Hotwire era\"\n      event_name: \"Geneva.rb October 2024\"\n      date: \"2024-10-16\"\n      speakers:\n        - Marco Roth\n      id: \"marco-roth-geneva-rb-october-2024\"\n      video_id: \"marco-roth-geneva-rb-october-2024\"\n      thumbnail_xs: \"https://files.speakerdeck.com/presentations/9ef1624742144bfaa9239e0e5d7fd2d3/preview_slide_0.jpg\"\n      thumbnail_sm: \"https://files.speakerdeck.com/presentations/9ef1624742144bfaa9239e0e5d7fd2d3/preview_slide_0.jpg\"\n      thumbnail_md: \"https://files.speakerdeck.com/presentations/9ef1624742144bfaa9239e0e5d7fd2d3/preview_slide_0.jpg\"\n      thumbnail_lg: \"https://files.speakerdeck.com/presentations/9ef1624742144bfaa9239e0e5d7fd2d3/preview_slide_0.jpg\"\n      thumbnail_xl: \"https://files.speakerdeck.com/presentations/9ef1624742144bfaa9239e0e5d7fd2d3/preview_slide_0.jpg\"\n      slides_url: \"https://speakerdeck.com/marcoroth/developer-tooling-for-the-modern-rails-and-hotwire-era-at-geneva-dot-rb-meetup-october-2024\"\n      video_provider: \"not_recorded\"\n      description: |-\n        Marco Roth (@marcoroth), core team member of StimulusReflex/CableReady and part of the Hotwire Contributors Team, will focus on the latest tools and best practices for Ruby on Rails and Hotwire developers.\n\n        He will explore how the new tools he has developed can streamline development, boost productivity, and enhance the overall developer experience within the Rails and Hotwire stack.\n\n- id: \"geneva-rb-november-2024\"\n  title: \"Geneva.rb November 2024\"\n  event_name: \"Geneva.rb November 2024\"\n  date: \"2024-11-13\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-november-2024\"\n  description: |-\n    Sean Carroll (GitLab) will present Kamal, a versatile deployment tool originally built for Ruby on Rails, now adaptable to any containerized web app. Kamal enables zero-downtime deploys, rolling restarts, remote builds, and accessory service management with Docker, making production deployments seamless. Unlike commercial platforms like Heroku, Fly.io, or hosted Kubernetes, Kamal focuses on portability and freedom—allowing users to deploy across various clouds or even their own hardware. It's designed to simplify deployment while avoiding vendor lock-in, providing a modern alternative to tools like Capistrano, Kubernetes, and Docker Swarm.\n\n    What to Expect:\n    * A presentation of about 30-45 minutes\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild!\n\n\n    https://www.meetup.com/geneva-rb/events/303018670\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/5/7/2/9/600_524122313.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/5/7/2/9/600_524122313.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/5/7/2/9/600_524122313.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/5/7/2/9/600_524122313.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/5/7/2/9/600_524122313.webp?w=750\"\n  talks:\n    - title: \"Rails Deployment with Kamal\"\n      event_name: \"Geneva.rb November 2024\"\n      date: \"2024-11-13\"\n      speakers:\n        - Sean Carroll\n      id: \"sean-carroll-geneva-rb-november-2024\"\n      video_id: \"sean-carroll-geneva-rb-november-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/5/7/2/9/600_524122313.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/5/7/2/9/600_524122313.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/5/7/2/9/600_524122313.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/5/7/2/9/600_524122313.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/5/7/2/9/600_524122313.webp?w=750\"\n      description: |-\n        Sean Carroll (GitLab) will present Kamal, a versatile deployment tool originally built for Ruby on Rails, now adaptable to any containerized web app. Kamal enables zero-downtime deploys, rolling restarts, remote builds, and accessory service management with Docker, making production deployments seamless. Unlike commercial platforms like Heroku, Fly.io, or hosted Kubernetes, Kamal focuses on portability and freedom—allowing users to deploy across various clouds or even their own hardware. It's designed to simplify deployment while avoiding vendor lock-in, providing a modern alternative to tools like Capistrano, Kubernetes, and Docker Swarm.\n\n- id: \"geneva-rb-december-2024\"\n  title: \"Geneva.rb December 2024\"\n  event_name: \"Geneva.rb December 2024\"\n  date: \"2024-12-11\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-december-2024\"\n  description: |-\n    After a successful first talk where Alexis Bernard from RoRvsWild explored the secrets to high-performance Ruby on Rails applications, he’s back for part two.\n\n    You'll also gain insight into new performance monitoring techniques and troubleshooting methods to ensure your application is always operating at peak speed.\n\n    What to Expect:\n    * A presentation of about 30-45 minutes\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild!\n\n    https://www.meetup.com/geneva-rb/events/303018673\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/a/f/7/5/600_524744917.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/a/f/7/5/600_524744917.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/a/f/7/5/600_524744917.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/a/f/7/5/600_524744917.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/a/f/7/5/600_524744917.webp?w=750\"\n  talks:\n    - title: \"More everyday performance rules for Ruby on Rails developers\"\n      event_name: \"Geneva.rb December 2024\"\n      date: \"2024-12-11\"\n      speakers:\n        - Alexis Bernard\n      id: \"alexis-bernard-geneva-rb-december-2024\"\n      video_id: \"alexis-bernard-geneva-rb-december-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/a/f/7/5/600_524744917.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/a/f/7/5/600_524744917.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/a/f/7/5/600_524744917.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/a/f/7/5/600_524744917.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/a/f/7/5/600_524744917.webp?w=750\"\n      description: |-\n        After a successful first talk where Alexis Bernard from RoRvsWild explored the secrets to high-performance Ruby on Rails applications, he’s back for part two.\n\n        You'll also gain insight into new performance monitoring techniques and troubleshooting methods to ensure your application is always operating at peak speed.\n\n- id: \"geneva-rb-january-2025\"\n  title: \"Geneva.rb January 2025\"\n  event_name: \"Geneva.rb January 2025\"\n  date: \"2025-01-15\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-january-2025\"\n  description: |-\n    Jean-Charles Santi (Gold Avenue) will explore strategies for identifying and resolving performance bottlenecks after addressing common issues like N+1 queries and analyzing flamegraphs. He’ll also dive into how the Scenic gem can be leveraged to optimize slow relationships and improve query efficiency. Perfect for developers looking to push beyond standard debugging approaches and refine their Rails applications.\n\n    What to Expect:\n    * A presentation of about 30-45 minutes\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild!\n\n    https://www.meetup.com/geneva-rb/events/304627310\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/6/3/4/d/600_524845421.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/6/3/4/d/600_524845421.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/6/3/4/d/600_524845421.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/6/3/4/d/600_524845421.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/6/3/4/d/600_524845421.webp?w=750\"\n  talks:\n    - title: \"Beyond the Basics: Tackling Edge Cases in Slow Ruby on Rails Code\"\n      event_name: \"Geneva.rb January 2025\"\n      date: \"2025-01-15\"\n      speakers:\n        - Jean-Charles Santi\n      id: \"jean-charles-santi-geneva-rb-january-2025\"\n      video_id: \"jean-charles-santi-geneva-rb-january-2025\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/6/3/4/d/600_524845421.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/6/3/4/d/600_524845421.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/6/3/4/d/600_524845421.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/6/3/4/d/600_524845421.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/6/3/4/d/600_524845421.webp?w=750\"\n      description: |-\n        Jean-Charles Santi (Gold Avenue) will explore strategies for identifying and resolving performance bottlenecks after addressing common issues like N+1 queries and analyzing flamegraphs. He’ll also dive into how the Scenic gem can be leveraged to optimize slow relationships and improve query efficiency. Perfect for developers looking to push beyond standard debugging approaches and refine their Rails applications.\n\n- id: \"geneva-rb-february-2025\"\n  title: \"Geneva.rb February 2025\"\n  event_name: \"Geneva.rb February 2025\"\n  date: \"2025-02-19\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-february-2025\"\n  description: |-\n    Remote presentation\n\n    Joel Hawksley is a staff software engineer at GitHub, based in Louisville, CO, USA. He's the creator of ViewComponent, a framework for building encapsulated, unit-testable view components in Ruby on Rails.\n\n    In his talk, Joel will share reflections from five years of UI architecture at GitHub, focusing on three key lessons: native is the new baseline, design systems are victims of their own success, and frontend costs 10x backend.\n\n    What to Expect:\n\n    * A remote presentation of about 30-45 minutes followed by a Q&A session,\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild!\n\n    https://www.meetup.com/geneva-rb/events/304627311\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/6/3/b/5/highres_525745525.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/6/3/b/5/highres_525745525.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/6/3/b/5/highres_525745525.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/6/3/b/5/highres_525745525.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/6/3/b/5/highres_525745525.webp?w=750\"\n  talks:\n    - title: \"The Past, Present and Future of UI at GitHub\"\n      event_name: \"Geneva.rb February 2025\"\n      date: \"2025-02-19\"\n      speakers:\n        - Joel Hawksley\n      id: \"joel-hawksley-geneva-rb-february-2025\"\n      video_id: \"joel-hawksley-geneva-rb-february-2025\"\n      video_provider: \"scheduled\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/6/3/b/5/600_525745525.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/6/3/b/5/600_525745525.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/6/3/b/5/600_525745525.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/6/3/b/5/600_525745525.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/6/3/b/5/600_525745525.webp?w=750\"\n      description: |-\n        Remote presentation\n\n        Joel Hawksley is a staff software engineer at GitHub, based in Louisville, CO, USA. He's the creator of ViewComponent, a framework for building encapsulated, unit-testable view components in Ruby on Rails.\n\n        In his talk, Joel will share reflections from five years of UI architecture at GitHub, focusing on three key lessons: native is the new baseline, design systems are victims of their own success, and frontend costs 10x backend.\n\n- id: \"geneva-rb-march-2025\"\n  title: \"Geneva.rb March 2025\"\n  event_name: \"Geneva.rb March 2025\"\n  date: \"2025-03-12\"\n  published_at: \"2025-03-16\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-march-2025\"\n  description: |-\n    Guillaume Briday (SpendHQ) will be diving into the \"why\" and \"how\" of migrating to a multi-database setup. Building on his previous talks and blog posts about Kamal and Rails, he'll also explore implementing Basecamp’s Solid Cache and Solid Queue, as well as deploying them seamlessly with Kamal.\n\n    What to Expect:\n    * A presentation of about 30-45 minutes\n    * Networking with a Cheese Fondue! 🧀✨ After the presentation, join us at the Buvette des Bains des Pâquis for a delicious cheese fondue! It's the perfect opportunity to mingle, network, and dive into discussions about Ruby, Rails, and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild and Ruby Central!\n\n    https://www.meetup.com/geneva-rb/events/304629277\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/d/c/3/b/highres_526616379.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/d/c/3/b/highres_526616379.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/d/c/3/b/highres_526616379.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/d/c/3/b/highres_526616379.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/d/c/3/b/highres_526616379.webp?w=750\"\n  talks:\n    - title: \"Rails 8: Multi-db with Solid Queue, Solid Cache and Kamal\"\n      event_name: \"Geneva.rb March 2025\"\n      date: \"2025-03-12\"\n      published_at: \"2025-03-16\"\n      speakers:\n        - Guillaume Briday\n      id: \"guillaume-briday-genevarb-march-2025\"\n      video_id: \"UfzbdfDg4JM\"\n      video_provider: \"youtube\"\n      thumbnail_xs: \"https://img.youtube.com/vi/UfzbdfDg4JM/default.jpg\"\n      thumbnail_sm: \"https://img.youtube.com/vi/UfzbdfDg4JM/mqdefault.jpg\"\n      thumbnail_md: \"https://img.youtube.com/vi/UfzbdfDg4JM/mqdefault.jpg\"\n      thumbnail_lg: \"https://img.youtube.com/vi/UfzbdfDg4JM/hqdefault.jpg\"\n      thumbnail_xl: \"https://img.youtube.com/vi/UfzbdfDg4JM/hqdefault.jpg\"\n      slides_url: \"https://rails-8-multi-db-solid-queue-cache.guillaumebriday.fr\"\n      language: \"french\"\n\n- id: \"geneva-rb-april-2025\"\n  title: \"Geneva.rb April 2025\"\n  event_name: \"Geneva.rb April 2025\"\n  date: \"2025-04-09\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-april-2025\"\n  description: |-\n    At QoQa, we deploy several times a day, and every backend developer can deploy to production.\n\n    We are also a bit lazy, so we try to optimize the process to be as simple as possible.\n\n    The result: the developer in charge of the releases only discusses with a bot to make all deployment and, all steps of the process are easily accessible through Slack to let everyone understand what happened and see what arrived in production.\n\n    Let's see together how it works.\n\n    PS: if you love trains, you will be pleased with this presentation.\n\n    What to Expect:\n    * A presentation of about 30-45 minutes\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Event supported by RoRvsWild and Ruby Central\n\n    https://www.meetup.com/geneva-rb/events/304629280\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/2/d/7/9/highres_526631641.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/2/d/7/9/highres_526631641.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/2/d/7/9/highres_526631641.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/2/d/7/9/highres_526631641.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/2/d/7/9/highres_526631641.webp?w=750\"\n  talks:\n    - title: \"How to release in production 5 times a day while enjoying the apero\"\n      event_name: \"Geneva.rb April 2025\"\n      date: \"2025-04-09\"\n      speakers:\n        - Diane Delallée\n      id: \"diane-delallee-geneva-rb-april-2025\"\n      video_id: \"diane-delallee-geneva-rb-april-2025\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/2/d/7/9/highres_526631641.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/2/d/7/9/highres_526631641.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/2/d/7/9/highres_526631641.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/2/d/7/9/highres_526631641.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/2/d/7/9/highres_526631641.webp?w=750\"\n      description: |-\n        At QoQa, we deploy several times a day, and every backend developer can deploy to production.\n\n        We are also a bit lazy, so we try to optimize the process to be as simple as possible.\n\n        The result: the developer in charge of the releases only discusses with a bot to make all deployment and, all steps of the process are easily accessible through Slack to let everyone understand what happened and see what arrived in production.\n\n        Let's see together how it works.\n\n        PS: if you love trains, you will be pleased with this presentation.\n\n- id: \"geneva-rb-may-2025\"\n  title: \"Geneva.rb May 2025\"\n  event_name: \"Geneva.rb May 2025\"\n  date: \"2025-05-14\"\n  video_provider: \"scheduled\"\n  video_id: \"geneva-rb-may-2025\"\n  description: |-\n    For this special edition of Geneva.rb, each participant will take turns presenting a tip or insight they care about, in a 5 to 10 minute slot. Whether it’s a library, a pattern, a best practice, or a useful resource, the goal is to share it with the group. You can present in either French or English, with or without slides. The atmosphere will be informal, so feel free to keep it casual!\n\n    What to Expect:\n    * 30-45 minutes of presentations\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild and Ruby Central!\n\n    https://www.meetup.com/geneva-rb/events/304629281\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/8/0/b/7/highres_527312951.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/8/0/b/7/highres_527312951.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/8/0/b/7/highres_527312951.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/8/0/b/7/highres_527312951.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/8/0/b/7/highres_527312951.webp?w=750\"\n  talks:\n    - title: \"Tips and Tricks\"\n      event_name: \"Geneva.rb May 2025\"\n      date: \"2025-05-14\"\n      speakers:\n        - TODO\n      id: \"geneva-rb-may-2025-tips-and-tricks\"\n      video_id: \"geneva-rb-may-2025-tips-and-tricks\"\n      video_provider: \"not_recorded\"\n      description: |-\n        For this special edition of Geneva.rb, each participant will take turns presenting a tip or insight they care about, in a 5 to 10 minute slot. Whether it’s a library, a pattern, a best practice, or a useful resource, the goal is to share it with the group. You can present in either French or English, with or without slides. The atmosphere will be informal, so feel free to keep it casual!\n\n- id: \"geneva-rb-june-2025\"\n  title: \"Geneva.rb June 2025\"\n  event_name: \"Geneva.rb June 2025\"\n  date: \"2025-06-11\"\n  video_provider: \"scheduled\"\n  video_id: \"geneva-rb-june-2025\"\n  description: |-\n    Ben Colon (mobilidée) will take you on a humorous journey through the chaos of race conditions in Ruby on Rails. When a well-meaning dad builds a Rails app to sell his kid's Pokémon cards, success comes fast—and so do race conditions. Follow his funny and chaotic path as he discovers the pitfalls of concurrency, and learns how to fix them using transactions, optimistic and pessimistic locks, and advisory locking before every rare card manages to sell out twice.\n\n    What to Expect:\n    * A presentation of about 30-45 minutes\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild and Ruby Central!\n\n    https://www.meetup.com/geneva-rb/events/304629286\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/2/b/7/2/highres_527891122.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/2/b/7/2/highres_527891122.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/2/b/7/2/highres_527891122.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/2/b/7/2/highres_527891122.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/2/b/7/2/highres_527891122.webp?w=750\"\n  talks:\n    - title: \"Race Conditions in Rails: Gotta Catch 'Em All (Before Your Buyers Do)\"\n      event_name: \"Geneva.rb June 2025\"\n      date: \"2025-06-11\"\n      speakers:\n        - Ben Colon\n      id: \"ben-colon-geneva-rb-june-2025\"\n      video_id: \"ben-colon-geneva-rb-june-2025\"\n      video_provider: \"not_recorded\"\n      description: |-\n        Ben Colon (mobilidée) will take you on a humorous journey through the chaos of race conditions in Ruby on Rails. When a well-meaning dad builds a Rails app to sell his kid's Pokémon cards, success comes fast—and so do race conditions. Follow his funny and chaotic path as he discovers the pitfalls of concurrency, and learns how to fix them using transactions, optimistic and pessimistic locks, and advisory locking before every rare card manages to sell out twice.\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/2/b/7/2/highres_527891122.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/2/b/7/2/highres_527891122.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/2/b/7/2/highres_527891122.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/2/b/7/2/highres_527891122.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/2/b/7/2/highres_527891122.webp?w=750\"\n\n- id: \"geneva-rb-october-2025\"\n  title: \"Geneva.rb October 2025\"\n  event_name: \"Geneva.rb October 2025\"\n  date: \"2025-10-15\"\n  video_provider: \"scheduled\"\n  video_id: \"geneva-rb-october-2025\"\n  location: \"Bussigny, Switzerland\"\n  description: |-\n    Foreword\n    For its 2025 kickoff, Genevarb is exceptionally relocating to Qoqa!\n\n    ––––\n\n    Over 2025, Marco explored a new direction for Rails views — starting with Herb (an HTML-aware ERB parser) and developer tools (formatter, linter, language server).\n\n    Echoing his recent talk at Rails World 2025, he’ll present ReActionView, an ERB engine built on Herb that stays compatible with html+erb while providing HTML validation, improved error messages, reactive updates, and built-in tooling.\n\n    ––––\n\n    What to Expect:\n\n    * A presentation of about 30-45 minutes\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild and Ruby Central!\n\n\n    https://www.meetup.com/geneva-rb/events/311083533\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/5/4/f/1/highres_530241745.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/5/4/f/1/highres_530241745.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/5/4/f/1/highres_530241745.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/5/4/f/1/highres_530241745.webp?w=1080\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/5/4/f/1/highres_530241745.webp?w=1080\"\n  talks:\n    - title: \"Introducing ReActionView: A new ActionView-Compatible ERB Engine\"\n      event_name: \"Geneva.rb October 2025\"\n      date: \"2025-10-15\"\n      speakers:\n        - Marco Roth\n      id: \"marco-roth-geneva-rb-october-2025\"\n      video_id: \"marco-roth-geneva-rb-october-2025\"\n      video_provider: \"not_recorded\"\n      description: |-\n        Over 2025, Marco explored a new direction for Rails views — starting with Herb (an HTML-aware ERB parser) and developer tools (formatter, linter, language server).\n\n        Echoing his recent talk at Rails World 2025, he’ll present ReActionView, an ERB engine built on Herb that stays compatible with html+erb while providing HTML validation, improved error messages, reactive updates, and built-in tooling.\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/5/4/f/1/highres_530241745.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/5/4/f/1/highres_530241745.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/5/4/f/1/highres_530241745.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/5/4/f/1/highres_530241745.webp?w=1080\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/5/4/f/1/highres_530241745.webp?w=1080\"\n      slides_url: \"https://speakerdeck.com/marcoroth/introducing-reactionview-a-new-actionview-compatible-erb-engine-at-geneva-dot-rb-meetup-october-2025\"\n\n- id: \"geneva-rb-january-2026\"\n  title: \"Geneva.rb January 2026\"\n  event_name: \"Geneva.rb January 2026\"\n  date: \"2026-01-21\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-january-2026\"\n  description: |-\n    👉 Notice to attendees\n\n    The event is still located at the Université Ouvrière de Genève but in a different room. 🗺️📌\n\n    See the \"Location\" section below for more details.\n\n    ----\n\n    Why wait for a third-party app when you can build exactly what you need with the Ruby tools you already master?\n\n    Paul Lahana will introduce us to xbar, a very accessible tool that lets you transform script outputs into macOS menu bar plugins. In this talk, he’ll show how he applied familiar MVC-style thinking to desktop automation.\n\n    ––––\n\n    What to Expect:\n\n    * A presentation of about 30-45 minutes\n    * Networking with Drinks and Snacks: After the presentation, join us for drinks and snacks. It's the perfect time to mingle, network, and dive deep into discussions about all things Ruby, Rails and more.\n    * Open to Everyone: Whether you're a seasoned Rubyist, a Rails enthusiast, or just beginning your journey as a developer, we warmly welcome you to join and contribute.\n\n    🙏 Meetup kindly sponsored by RoRvsWild!\n\n    https://www.meetup.com/geneva-rb/events/312854274\n  talks:\n    - title: \"Using xbar and Rails patterns to build macOS Add-ons\"\n      event_name: \"Geneva.rb January 2026\"\n      date: \"2026-01-21\"\n      speakers:\n        - Paul Lahana\n      id: \"paul-lahana-geneva-rb-january-2026\"\n      video_id: \"paul-lahana-geneva-rb-january-2026\"\n      video_provider: \"not_recorded\"\n      description: |-\n        Paul Lahana will introduce us to xbar, a very accessible tool that lets you transform script outputs into macOS menu bar plugins. In this talk, he’ll show how he applied familiar MVC-style thinking to desktop automation.\n"
  },
  {
    "path": "data/geneva-rb/series.yml",
    "content": "---\nname: \"Geneva.rb\"\nwebsite: \"https://www.meetup.com/geneva-rb\"\ntwitter: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"CH\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2009/event.yml",
    "content": "---\nid: \"gogaruco-2009\"\ntitle: \"GoGaRuCo 2009\"\nkind: \"conference\"\nlocation: \"San Francisco, CA, United States\"\ndescription: |-\n  https://web.archive.org/web/20140926004712/http://2009.gogaruco.com/\nstart_date: \"2009-04-17\"\nend_date: \"2009-04-18\"\npublished_at: \"2009-04-17\"\nyear: 2009\ncoordinates:\n  latitude: 37.7749295\n  longitude: -122.4194155\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2010/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybZLrVKlDUMgcMEchVqrpl5\"\ntitle: \"GoGaRuCo 2010\"\nkind: \"conference\"\nlocation: \"San Francisco, CA, United States\"\ndescription: |-\n  https://web.archive.org/web/20141117004015/http://2010.gogaruco.com/\nstart_date: \"2010-09-17\"\nend_date: \"2010-09-18\"\npublished_at: \"2010-09-17\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2010\ncoordinates:\n  latitude: 37.7749295\n  longitude: -122.4194155\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2010/videos.yml",
    "content": "---\n# https://web.archive.org/web/20150227160256/http://2010.gogaruco.com/schedule.html\n\n## Day 1\n\n- id: \"evan-phoenix-gogaruco-2010\"\n  title: \"Being Your Best Asset and Not Your Worst Enemy by\"\n  raw_title: \"GoGaRuCo 2010 - Being Your Best Asset and Not Your Worst Enemy by: Evan Phoenix\"\n  speakers:\n    - Evan Phoenix\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-17\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Ruby is almost synonymous with Open Source thanks to an amazing community. Managing a successful Open Source project requires maintaining a careful balance of pragmatism, exuberance, and patience.\n\n    As soon as you have your first contributor you have to begin to think about how to manage not just the code but also the people. There are no org charts or managers to lean on for assistance; you have to figure out how to keep your contributors happy and on the right path. The tone you set for your project early on will stick with it for a very long time, so it's important to be sure you're the one setting it rather than allowing it to happen outside your control.\n\n    Evan will discuss managing a project as well as how contributors can make life easier for fellow developers.\n\n  video_provider: \"youtube\"\n  video_id: \"wu3gmXWiihg\"\n\n- id: \"rein-henrichs-gogaruco-2010\"\n  title: \"Real World Ruby Testing\"\n  raw_title: \"GoGaRuCo 2010 - Real World Ruby Testing by: Rein Henrichs\"\n  speakers:\n    - Rein Henrichs\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-17\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Are you confident that your code works the way you expect? Is it easy to change? Do you get accurate feedback when you do change it? If the answer to any of these questions is no, the problem is not your code: it's your tests.\n\n    We'll look at the state-of-the-art Ruby testing libraries and frameworks to start you off with an effective testing toolset. In addition to the toolset, we'll also explore the testing mindset. Should I mock this or stub it? Should I write a unit test or an integration test? How do I write tests that allow me to refactor with confidence? If you've ever asked yourself questions like these, this session is for you.\n\n    Intended for new testers; those who \"just don't get this testing thing;\" people with brittle, unwieldy test suites they need to work into shape; and everyone in between.\n\n  video_provider: \"youtube\"\n  video_id: \"vULxZFB-S_w\"\n\n- id: \"sarah-mei-gogaruco-2010\"\n  title: \"Ruby APIs for NoSQL\"\n  raw_title: \"GoGaRuCo 2010 - Ruby APIs for NoSQL by: Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-17\"\n  published_at: \"2015-04-07\"\n  description: |-\n    I secretly think that NoSQL data stores are rabbits. They're breeding under the floorboards when we're asleep. How else do you explain a landscape that includes Redis, Riak, CouchDB, Tokyo Cabinet, Flock, MongoDB, and Cassandra, among many others? Mopsy and Cottontail can't be far behind.\n\n    Given this, picking the right rabâ€¦ er, data store for your project can be a challenge. There are lots of factors to consider, such as tail fluffiness, consistency guarantees, replication strategies, and ear length.\n\n    But the Ruby API for the data store is important too. That's what you'll be dealing with day in and day out once you make your choice. If you can't stand the interface, you'll get sick of cleaning the cage pretty quickly.\n\n    In this talk, I'll run you through the mechanics of accessing several NoSQL data stores with Ruby. I promise not to bring a rabbit to the conference, and I definitely won't bring two. The last thing we need is more.\n\n  video_provider: \"youtube\"\n  video_id: \"irKvd4DfAtU\"\n\n- id: \"eric-mill-gogaruco-2010\"\n  title: \"Data-Driven Government and the Ruby Developer\"\n  raw_title: \"GoGaRuCo 2010 -  Data-Driven Government and the Ruby Developer by Eric Mill\"\n  speakers:\n    - Eric Mill\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-17\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Data-Driven Government and the Ruby Developer by Eric Mill\n\n    A radically new relationship between developers and our government is taking shape. All levels of governmentâ€”federal agencies, states, and citiesâ€”have begun opening their vast troves of data to citizens, free of charge and license.\n\n    It started small, but as inspired citizens, including many Ruby developers, have taken government data and created awesome apps, more and more governments have taken the leap to give their data away. Some have even started collaborating with citizens and creating new government services that never existed before.\n\n    It's a historic and powerful opportunity for us as Ruby developers, and we need to take advantage of it. This talk is about why you should care, what your fellow developers have been doing so far, and what you might do yourself.\n\n  video_provider: \"youtube\"\n  video_id: \"E7T8NilHhyc\"\n\n# Lunch\n\n- id: \"yehuda-katz-gogaruco-2010\"\n  title: \"Extending Rails 3\"\n  raw_title: \"GoGaRuCo 2010 - Extending Rails 3 by: Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-17\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Rails 3 has added quite a number of new ways to extend the framework. These include swapping in a new ORM that still works cleanly with ActionPack, a brand new instrumentation system, and ways to build custom controllers, mixing and matching the pieces that you want. In this talk, Yehuda will give an overview of these new systems, and show some real-world examples of using them in plugins and in your application itself. He will also talk about how to think about using the new Rails architecture to streamline your stack for performance-critical parts of your app, without losing the integration you've come to expect or the features you absolutely need in those cases.\n\n  video_provider: \"youtube\"\n  video_id: \"n3112epmkkA\"\n\n- id: \"bryan-liles-gogaruco-2010\"\n  title: \"Bryan's ActieModel Extravaganza\"\n  raw_title: \"GoGaRuCo 2010 - Bryan's ActieModel Extravaganza by: Bryan Liles\"\n  speakers:\n    - Bryan Liles\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-17\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Imagine you are at a conference. Imagine while you are at the conference, there are 30-minute sessions of various Ruby related topics. Imagine Bryan Liles is at this same conference. Imagine Bryan Liles. Imagine ActiveModel. Imagine Bryan Liles talking about ActiveModel. Can you imagine anything better? Maybe vanilla ice cream on apple pie. As a close second place, Bryan will show you why you need to at least investigate ActiveModel for your current or next project. Of course there will be tests, code, and more tests at Bryan's ActiveModel Extravaganza.\n\n    In this session, I will discuss why ActiveModel could be a great interface to allow Rails to get access to your data on your own terms. I'll start from the beginning, and using TDD, I'll explore the interfaces Rails 3 exposes in their API. Next, I'll explore the components of ActiveModel. Finally, I'll show you how I'm using ActiveModel right now, and give you a real-world war report. I repeat: There will be code.\n\n  video_provider: \"youtube\"\n  video_id: \"1K0NSPmD8Go\"\n\n- id: \"jim-weirich-gogaruco-2010\"\n  title: \"Keynote: (Parenthetically Speaking)\"\n  raw_title: \"GoGaRuCo 2010 - Keynote: (Parenthetically Speaking) by: Jim Weirich\"\n  speakers:\n    - Jim Weirich\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-17\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"GT9b2G-fHo4\"\n\n- id: \"sarah-allen-gogaruco-2010\"\n  title: \"Test-First Teaching\"\n  raw_title: \"GoGaRuCo 2010 - Test-First Teaching by: Sarah Allen\"\n  speakers:\n    - Sarah Allen\n    - Alex Chaffee\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-17\"\n  published_at: \"2015-04-07\"\n  description: |-\n    We've all learned that writing tests before code is a great way to develop software. It turns out that it's also a great way to learn how to develop software in the first place! In this talk we discuss a number of projects that have used test-first approaches to teach Ruby, including Ruby Koans, RailsBridge Workshops, Wolfram Arnold's BFT (behavior-first teaching), Blazing Cloud JavaScript and Rails classes, plus our own open-source Learn Ruby TFT (test-first teaching) curriculum (at a href=\"http://testfirst.org\" target=\"_blank\"testfirst.org/a). Come hear about our experiences or share your own.\n\n  video_provider: \"youtube\"\n  video_id: \"1Y6IE5yqpSA\"\n\n- id: \"blake-mizerany-gogaruco-2010\"\n  title: \"Polyglot: When Ruby isn't enough or even sane\"\n  raw_title: \"GoGaRuCo 2010 - Polyglot: When Ruby isn't enough or even sane by: Blake Mizerany\"\n  speakers:\n    - Blake Mizerany\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-17\"\n  published_at: \"2015-04-07\"\n  description: |-\n    You're so polyglot and you don't even know it. You may be using Ruby for too much. It's not the holy grail. This talk will pull from my experience at Heroku where I use much more than Ruby everyday; and I'm not just talking JavaScript. Technologies are designed to take on problems of a specific nature. There are those that are great for systems work and those that are not. Some make generating reports a cinch. A few are remarkable at digging through data. Networking can be a nightmare in some. I'll start with a swift but gentle introduction to Ruby's good but not great suits and move us into what to replace them with.\n\n  video_provider: \"youtube\"\n  video_id: \"drmOYNo-gv0\"\n\n## Day 2\n\n- id: \"avi-bryant-gogaruco-2010\"\n  title: \"Rails is Obsolete (But So's Everything Else)\"\n  raw_title: \"GoGaRuCo 2010 - Rails is Obsolete (But So's Everything Else) by: Avi Bryant\"\n  speakers:\n    - Avi Bryant\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-18\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Back in the old days, you submitted a form to some URL and you got back some HTML. These days, you probably didn't hit submit, your URL probably didn't change, and what you got back was probably JSONâ€”but you never saw it because it came in asynchronously in the background. Best practices around web applications are changing fast, driven by new browser standards, sophisticated JavaScript libraries and super fast JavaScript implementations. Why would a web framework design from 2004 still be appropriate? What can we be doing to adapt, or reinvent, our approaches to building web apps?\n\n  video_provider: \"youtube\"\n  video_id: \"1iy2kqRwdZ4\"\n\n- id: \"elisabeth-hendrickson-gogaruco-2010\"\n  title: \"Eschew Obfuscation and Omit Needless Words: Writing Clear Acceptance Tests\"\n  raw_title: \"GoGaRuCo 2010 - Eschew Obfuscation and Omit Needless Words: Writing Clear Acceptance Tests\"\n  speakers:\n    - Elisabeth Hendrickson\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-18\"\n  published_at: \"2015-04-07\"\n  description: |-\n    by: Elisabeth Hendrickson\n\n    Modern acceptance testing frameworks like Cucumber express tests in natural language, enabling organizations to establish their own Domain Specific Languages (DSLs). This powerful capability is a huge boon for communication: technical team members and non-technical business stakeholders can use the same vocabulary in expressing both requirements and tests. However, just creating a DSL does not ensure we will write good, clear tests. Indeed, it is all too easy to create acceptance tests that contain so many extraneous details that the real intentions behind the tests are obfuscated. In this session, Elisabeth will demonstrate how to edit technically correct but verbose Cucumber tests to increase clarity, reduce extraneous distracting details, and improve maintainability. Along the way we'll see how paying attention to the advice in Elements of Style applies to writing better automated acceptance tests. Strunk and White would be proud.\n\n  video_provider: \"youtube\"\n  video_id: \"h4DG57zRGEo\"\n\n- id: \"ilya-grigorik-gogaruco-2010\"\n  title: \"Intelligent Ruby: Getting Started with Machine Learning\"\n  raw_title: \"GoGaRuCo 2010 - Intelligent Ruby: Getting Started with Machine Learning by: Ilya Grigorik\"\n  speakers:\n    - Ilya Grigorik\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-18\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Machine learning is a discipline that is concerned with the design and development of algorithms that allow computers to evolve behaviors based on empirical data â€” a fancy name for a simple concept. Behind all the buzzword algorithms such as Decision Trees, Singular Value Decomposition, Bayes and Support Vector Machines lie the simple observations and principles that make them tick. In this presentation, we will take a ground-up look at how they work (in practical terms), why they work, and how you can apply them in Ruby for fun and profit.\n\n    No prior knowledge required. We will take a quick look at the foundations (representing and modeling knowledge, compression, and inference), and build up to simple but powerful examples such as clustering, recommendations, and classification â€” all in 30 minutes or less, believe it or not.\n\n  video_provider: \"youtube\"\n  video_id: \"FAbwtyCj-sk\"\n\n- id: \"rich-kilmer-gogaruco-2010\"\n  title: \"The Revolution will not be Tweeted\"\n  raw_title: \"GoGaRuCo 2010 - The Revolution will not be Tweeted by: Rich Kilmer\"\n  speakers:\n    - Rich Kilmer\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-18\"\n  published_at: \"2015-04-07\"\n  description: |-\n    The Rails revolution, and Ruby along with it, began in the loud public echosphere of startup companies. The arrival of the Rails framework and the \"Web 2.0\" explosion created a very thunderous effect. Magazine after magazine reported on Rails. All the hip, funded and loud startups were using Rails to build their wares. It became a thing that VCs would assume you were using, and if not, why? The first RailsConf was 90% attended by startups. Rails was a revolution. Since then the loudness has waned. Is the revolution over? Is Rails done? Au contraire, the revolution has gone underground. It's penetrating places that Twitter does not hear. It's building things that are not reported. It's entered the enterprise. This talk will document the rise of Rails and glorious revolution which we barely see, but is happening every day.\n\n  video_provider: \"youtube\"\n  video_id: \"6UC36otvtzM\"\n\n# Lunch\n\n- id: \"ryan-tomayko-gogaruco-2010\"\n  title: \"The Shell Hater's Handbook\"\n  raw_title: \"GoGaRuCo 2010 - The Shell Hater's Handbook by: Ryan Tomayko\"\n  speakers:\n    - Ryan Tomayko\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-18\"\n  published_at: \"2015-04-07\"\n  description: |-\n    The Unix shell is widely despised as a modern programming language due to its arcane syntax, unpredictable control flow, and lack of support for fundamental constructs like: exception handling, objects, a module system, string functions, or even local variables! It's old. There are a billion implementations of the core language and userland utilities, each with subtle and incompatible differences. Documentation is too sparse or too dense or available only at your local library. It's a minefield.\n\n    But for all its perceived flaws, the Unix shell can be an amazingly productive environmentâ€”once you learn to hate it properly. It has super powers. Stuff you won't find in more general purpose languages. Learn to harness the shell's AWESOME POWER and you'll be able to quickly automate a wide range of tasks related to development workflow, source code editing, and systems administration/analysis.\n\n    In this talk, I want to show how to navigate the minefield, how to \"think in shell,\" demystify the strange grammar (yes, there's an actual grammar in there), and compare approaches to common problems in shell vs. Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"olH-9b3VJfs\"\n\n- id: \"ryan-davis-gogaruco-2010\"\n  title: \"Panel: Sharing our Workflows\"\n  raw_title: \"GoGaRuCo 2010 - Workflow by: Ryan Davis\"\n  speakers:\n    - Ryan Davis\n    - Jim Weirich\n    - Rein Hendrichs\n    - Evan Phoenix\n    - Dennis Collinson\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-18\"\n  published_at: \"2015-04-07\"\n  description: |-\n    How do you develop software? Is it effective? Could you do better? Where could you put the least amount of effort to improve the most? When do you do that? What would your teammates answer? What can you learn from them?\n\n    I shall give you my answers.  em You will give me yours /em .\n\n  video_provider: \"youtube\"\n  video_id: \"o9X4mkaPRKU\"\n\n- id: \"lightning-talks-gogaruco-2010\"\n  title: \"Lightning Talks\"\n  raw_title: \"GoGaRuCo 2010 - Lightning Talks by: Various Presenters\"\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-18\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Get electrified with a dozen five minute talks on various topics by your fellow conference attendees, or give a talk yourself!\n\n  video_provider: \"youtube\"\n  video_id: \"me-2gFihaHw\"\n  talks:\n    - title: \"Lightning Talk: Rubinius Concurrency Demo\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"evan-phoenix-lighting-talk-gogaruco-2010\"\n      video_id: \"evan-phoenix-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Evan Phoenix\n\n    - title: \"Lightning Talk: Ticketmast: Take Command of Your Ticketing System(s)\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"ron-evans-lighting-talk-gogaruco-2010\"\n      video_id: \"ron-evans-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Ron Evans\n\n    - title: \"Lightning Talk: Polaroid Cameras\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pete-forde-lighting-talk-gogaruco-2010\"\n      video_id: \"pete-forde-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Pete Forde\n\n    - title: \"Lightning Talk: Fixture Builder\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"david-stephenson-lighting-talk-gogaruco-2010\"\n      video_id: \"david-stephenson-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - David Stephenson\n\n    - title: \"Lightning Talk: Getting Rid Of Java\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"noah-gibbs-lighting-talk-gogaruco-2010\"\n      video_id: \"noah-gibbs-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Noah Gibbs\n\n    - title: \"Lightning Talk: Debugging Ruby - perftools.rb\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"aman-gupta-lighting-talk-gogaruco-2010\"\n      video_id: \"aman-gupta-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Aman Gupta\n\n    - title: \"Lightning Talk: Dubious\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"john-woodell-lighting-talk-gogaruco-2010\"\n      video_id: \"john-woodell-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - John Woodell\n\n    - title: \"Lightning Talk: Smart Browsers\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"seth-ladd-lighting-talk-gogaruco-2010\"\n      video_id: \"seth-ladd-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Seth Ladd\n\n    - title: \"Lightning Talk: Screw Cucumber\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pat-nakajima-lighting-talk-gogaruco-2010\"\n      video_id: \"pat-nakajima-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Pat Nakajima\n\n    - title: \"Lightning Talk: Terminator\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"thomas-shafer-lighting-talk-gogaruco-2010\"\n      video_id: \"thomas-shafer-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Thomas Shafer\n\n    - title: \"Lightning Talk: Terminator\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"nathan-esquenazi-lighting-talk-gogaruco-2010\"\n      video_id: \"nathan-esquenazi-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Nathan Esquenazi\n\n    - title: \"Lightning Talk: What is CoffeeScript\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jim-puls-lighting-talk-gogaruco-2010\"\n      video_id: \"jim-puls-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Jim Puls\n\n    - title: \"Lightning Talk: Doing Better Presentation Slides\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"shane-becker-lighting-talk-gogaruco-2010\"\n      video_id: \"shane-becker-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Shane Becker\n\n    - title: \"Lightning Talk: Ruby & Teaching Ruby\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"mislav-marohnic-lighting-talk-gogaruco-2010\"\n      video_id: \"mislav-marohnic-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Mislav Marohnić\n\n    - title: \"Lightning Talk: Revive assert\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"alex-chaffee-lighting-talk-gogaruco-2010\"\n      video_id: \"alex-chaffee-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Alex Chaffee\n\n    - title: \"Lightning Talk: Client-Side Caching\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"yehuda-katz-lighting-talk-gogaruco-2010\"\n      video_id: \"yehuda-katz-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Yehuda Katz\n\n    - title: \"Lightning Talk: Roundup\"\n      event_name: \"GoGaRuCo 2010\"\n      date: \"2010-09-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"blake-mizerany-lighting-talk-gogaruco-2010\"\n      video_id: \"blake-mizerany-lighting-talk-gogaruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Blake Mizerany\n\n- id: \"bryan-helmkamp-gogaruco-2010\"\n  title: \"Arel: The Ruby Relational Algebra\"\n  raw_title: \"GoGaRuCo 2010 - Arel: The Ruby Relational Algebra Library by: Bryan Helmkamp\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-18\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Arel (also known as ActiveRelation) is the Ruby relational algebra engine powering ActiveRecord in Rails 3. By replacing string concatenation with an object model to express SQL queries, Arel had a big immediate impact on the ActiveRecord codebase and opens the door for more powerful Object Relation Mapping (ORM) functionality in the future. This talk will introduce the concept of relational algebra, cover the past, present and future of Arel, and dive into how you can leverage it today either on its own, or in your Rails 3 applications\n\n  video_provider: \"youtube\"\n  video_id: \"zAqts0oFL_w\"\n\n- id: \"aaron-patterson-gogaruco-2010\"\n  title: \"Hidden Gems of Ruby 1.9\"\n  raw_title: \"GoGaRuCo 2010 - Hidden Gems of Ruby 1.9 by: Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"GoGaRuCo 2010\"\n  date: \"2010-09-18\"\n  published_at: \"2015-04-07\"\n  description: |-\n    When attempting to solve our latest 367 hidden gems of ruby 1 9programming conundrum, we typically reach for the latest Ruby Gem that solves the problem for us. Oftentimes in our search for a solution, we neglect to look through some of the great libraries that come shipped with Ruby. In this talk we'll explore some of the tools we can use that don't require a gem install. We'll especially focus on the new toys in Ruby's standard library that ship with Ruby 1.9, but also look at some of the toys that ship with Ruby Classicâ„¢. Be prepared to be amazed and entertained. But most of all, be prepared to go home with something useful!\n\n  video_provider: \"youtube\"\n  video_id: \"bPPGuecH1QM\"\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2011/event.yml",
    "content": "---\nid: \"gogaruco-2011\"\ntitle: \"GoGaRuCo 2011\"\nkind: \"conference\"\nlocation: \"San Francisco, CA, United States\"\ndescription: |-\n  https://web.archive.org/web/20141005044604/http://2011.gogaruco.com/\nstart_date: \"2011-09-16\"\nend_date: \"2011-09-17\"\npublished_at: \"2011-09-16\"\nyear: 2011\ncoordinates:\n  latitude: 37.7749295\n  longitude: -122.4194155\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2012/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyb1MTWZFk7C2AckCseCQMpB\"\ntitle: \"GoGaRuCo 2012\"\nkind: \"conference\"\nlocation: \"San Francisco, CA, United States\"\ndescription: |-\n  https://web.archive.org/web/20140924120247/http://2012.gogaruco.com/\nstart_date: \"2012-09-14\"\nend_date: \"2012-09-15\"\npublished_at: \"2012-09-14\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2012\ncoordinates:\n  latitude: 37.7749295\n  longitude: -122.4194155\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2012/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: schedule website\n\n# https://web.archive.org/web/20141116234933/http://2012.gogaruco.com/\n\n- id: \"ilya-grigorik-gogaruco-2012\"\n  title: \"Cargo Cult Web Performance Optimization\"\n  raw_title: \"GoGaRuCo 2012 - Cargo Cult Web Performance Optimization\"\n  speakers:\n    - Ilya Grigorik\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Cargo Cult Web Performance Optimization by: Ilya Grigorik\n\n    Put your CSS at the top, JavaScript at the bottom, domain shard all the things, and so on! But why? Do these rules even make sense?\n\n    The modern browser is not the black box it used to be. We can peek inside and see how it really works—we have the source code for WebKit, Chromium, and Firefox! In this talk we'll disassemble the basic architecture of WebKit / Chromium and see how it all comes together: from receiving the HTML bytes on the wire, to constructing the DOM, fetching the resources, performing the layout, and finally painting the pixels to the screen. Armed with this knowledge, we can then dismantle some of the web performance myths found in most every \"performance top 10\" list, and see how we can build better and faster web apps, regardless of the framework you're using.\n  video_provider: \"youtube\"\n  video_id: \"LrDtQLsKqxY\"\n\n- id: \"amit-kumar-gogaruco-2012\"\n  title: \"RubyMotion: Rubyizing iOS Development\"\n  raw_title: \"GoGaRuCo 2012 - RubyMotion: Rubyizing iOS development\"\n  speakers:\n    - Amit Kumar\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    RubyMotion: Rubyizing iOS development by: Amit Kumar\n\n    RubyMotion has revolutionized native app development for iOS devices. I would like to share some best practices/lessons learned building apps using RubyMotion. These include:\n\n    IDE Support\n    REPL\n    Using external Ruby libraries and gems\n    Using storyboard\n    DSL for views\n    ActiveRecord-like CoreData for iOS\n    Testing storyboard interface (Rspec and TestUnit)\n    CocoaPods\n    Outlets and Actions\n    XCode integration - is it possible?\n    Releasing to AppStore\n  video_provider: \"youtube\"\n  video_id: \"7v3LhtNZEcM\"\n\n- id: \"glenn-vanderburg-gogaruco-2012\"\n  title: \"Grasping Complexity with Both Hands\"\n  raw_title: \"GoGaRuCo 2012 - Grasping Complexity with Both Hands\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Grasping Complexity with Both Hands by:  Glenn Vanderburg\n  video_provider: \"youtube\"\n  video_id: \"QziXZM8tKAM\"\n\n- id: \"three-mini-talks-gogaruco-2012\"\n  title: \"Three Mini-talks\"\n  raw_title: \"GoGaRuCo 2012 - Three Mini-talks\"\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Three Mini-talks by: Sarah Mei, Tony Arcieri, and Chris Eppstein\n\n    One session, three talks.\n  video_provider: \"youtube\"\n  video_id: \"fK5llwBYBRg\"\n  talks:\n    - title: \"Three Mini-talks Intro\"\n      event_name: \"GoGaRuCo 2012\"\n      date: \"2012-09-14\"\n      published_at: \"2015-07-14\"\n      start_cue: \"00:00\"\n      end_cue: \"00:42\"\n      id: \"three-mini-talks-intro-gogaruco-2012\"\n      video_id: \"three-mini-talks-intro-gogaruco-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO\n\n    - title: \"Mini Talk: A Crash Course on Celluloid\"\n      event_name: \"GoGaRuCo 2012\"\n      date: \"2012-09-14\"\n      published_at: \"2015-07-14\"\n      start_cue: \"00:42\"\n      end_cue: \"09:40\"\n      id: \"tony-arcieri-lightning-talk-gogaruco-2012\"\n      video_id: \"tony-arcieri-lightning-talk-gogaruco-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Tony Arcieri\n      description: |-\n        This talk will provide a quick overview of how to use Celluloid, covering the basics of how to add Celluloid to your program and begin leveraging its concurrent features.\n\n    - title: \"Mini Talk: Naiveté\"\n      event_name: \"GoGaRuCo 2012\"\n      date: \"2012-09-14\"\n      published_at: \"2015-07-14\"\n      start_cue: \"09:40\"\n      end_cue: \"19:24\"\n      id: \"chris-eppstein-lightning-talk-gogaruco-2012\"\n      video_id: \"chris-eppstein-lightning-talk-gogaruco-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Eppstein\n      description: |-\n        Stepping outside your comfort zone.\n\n    - title: \"Mini Talk: MRI Internals\"\n      event_name: \"GoGaRuCo 2012\"\n      date: \"2012-09-14\"\n      published_at: \"2015-07-14\"\n      start_cue: \"19:24\"\n      end_cue: \"30:40\"\n      id: \"sarah-mei-lightning-talk-gogaruco-2012\"\n      video_id: \"sarah-mei-lightning-talk-gogaruco-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Sarah Mei\n      description: |-\n        How does a language become a language? We'll take a peek into the internals of the MRI, and explore how it came to be.\n\n- id: \"yehuda-katz-gogaruco-2012\"\n  title: \"Cruft and Technical Debt: A Long View\"\n  raw_title: \"GoGaRuCo 2012 - Cruft and Technical Debt: A Long View\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Cruft and Technical Debt: A Long View by: Yehuda Katz\n\n    Cruft is inevitable. Whether you're working around a bug in Internet Explorer, Heroku or Ruby 1.8, our libraries and applications quickly diverge from the platonic ideal of software. In the short-term, there's no point in fretting. Rather than an indication of a development process gone awry, the technical debt merely reflects the messy reality of the surrounding ecosystem that our code lives in.\n\n    For projects that last for years, though, this can lead to a resistance to re-evaluating the original assumptions that introduced the cruft to begin with. In this talk, I will give some examples of good and bad attempts to deal with this issue in the world of open source, and make some suggestions for how you can make your projects, both open-source and proprietary, more able to cope with the slow but steady long-term shifts that surround our projects.\n  video_provider: \"youtube\"\n  video_id: \"sojGI6hxU6U\"\n\n- id: \"carina-c-zona-gogaruco-2012\"\n  title: \"Schemas For The Real World\"\n  raw_title: \"GoGaRuco 2012 - Schemas for the Real World\"\n  speakers:\n    - Carina C. Zona\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Schemas for the Real World by: Carina C. Zona\n\n    App development, especially for social, challenges us to evaluate how to code for the complexity of modern life. Examples include the growing range of labels people ascribe to their important relationships, sexual orientation, and gender. Users are giving push-back to questions that carry ill-fitted assumptions or constrain their responses.\n\n    Facebook, Google+, and developers in many other industries are grappling with these issues. The most resilient approaches will arise from an app's own foundations. We'll look at schemas' influence on product scope, UX, and analytics. Then we'll check out a range of approaches for bringing modern realities into any app's schema, views, and logic.\n  video_provider: \"youtube\"\n  video_id: \"j0e8h5s248Y\"\n\n- id: \"david-copeland-gogaruco-2012\"\n  title: \"Services, Scale, Backgrounding and WTF is going on here?!??!\"\n  raw_title: \"GoGaRuCo 2012 - Services, Scale, Backgrounding and WTF is going on here?!??!\"\n  speakers:\n    - David Copeland\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Services, Scale, Backgrounding and WTF is going on here?!??! by: David Copeland\n\n    You want to improve the performance of your app, or you want to keep your system composed of small, easy to understand services. You start using background jobs, REST calls, and cron. And then weird things happen.\n\n    Designing services from the start can be tricky, but there is guidance out there. Extracting services can be even trickier, and whenever there's a message queue or job processing system, it becomes very difficult to truly understand the order in which things happen in your system. If you're lucky, you've got alerting when things go wrong, but even then, what do you do about it?\n\n    This talk will go through an increasingly frustrating set of circumstances that I've seen on a regular basis at LivingSocial as we extracted code from a monolithic app into a set of services. I'll then show the solutions to these issues that make our payment processing system more or less bullet-proof, and generalize these lessons into what you can do when extracting and designing services.\n  video_provider: \"youtube\"\n  video_id: \"swgub0239Y0\"\n\n- id: \"joe-kutner-gogaruco-2012\"\n  title: \"Deploy, Scale and Sleep at Night with JRuby\"\n  raw_title: \"GoGaRuCo 2012 - Deploy, Scale and Sleep at Night with JRuby\"\n  speakers:\n    - Joe Kutner\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Deploy, Scale and Sleep at Night with JRuby by: Joe Kutner\n  video_provider: \"youtube\"\n  video_id: \"P5mjivt2Zkw\"\n\n- id: \"avdi-grimm-gogaruco-2012\"\n  title: \"Code To Joy\"\n  raw_title: \"GoGaRuCo 2012 - Code to Joy\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Code to Joy by: Avdi Grimm\n\n    I got into Ruby because writing it made me happy, and after all these years it still finds ways to make me grin. Join me for a random walk through the Ruby language and standard library, stopping in to visit some of my favorite tools, hacks and implementation patterns. Some you may know. Others may be more obscure. My goal: to rekindle in you the joy of code, to inspire you to share that joy with your peers and with the next generation of developers, and most importantly, to bring a smile to your face!\n  video_provider: \"youtube\"\n  video_id: \"IS0H3jXb9iI\"\n\n- id: \"daniela-wellisz-gogaruco-2012\"\n  title: \"Why Is A Math Proof Like A Unit Test?\"\n  raw_title: \"GoGaRuCo 2012 - Why Is A Math Proof Like A Unit Test?\"\n  speakers:\n    - Daniela Wellisz\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Why Is A Math Proof Like A Unit Test? by: Daniela Wellisz\n  video_provider: \"youtube\"\n  video_id: \"RZUKxYfvtVo\"\n\n- id: \"sandi-metz-gogaruco-2012\"\n  title: \"Go Ahead, Make a Mess\"\n  raw_title: \"GoGaRuCo 2012 - Go Ahead, Make a Mess\"\n  speakers:\n    - Sandi Metz\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  slides_url: \"https://speakerdeck.com/skmetz/go-ahead-make-a-mess\"\n  description: |-\n    Go Ahead, Make a Mess by: Sandi Metz\n\n    Software is always a mess. You can't avoid this mess, and if hubris goads you into attempting to achieve perfection, you'll just make things worse. Perfection is a distant, dim land on the unreachable horizon. You'll not be going there today.\n\n    What you can do, however, is use the techniques of object-oriented design (OOD) to make your messes manageable. OOD is good at messes. It understands their origins, predicts their courses, and foresees their outcomes. It shines a light down the dusty nooks and crannies of your app, showing you what to do and what to avoid.\n\n    This talk shows you how to use OOD to create the best kinds of messes, those that let you get software out the door today without regretting your actions tomorrow.\n  video_provider: \"youtube\"\n  video_id: \"xi3DClfGuqQ\"\n\n- id: \"john-downey-gogaruco-2012\"\n  title: \"Modern Cryptography\"\n  raw_title: \"GoGaRuCo 2012 - Modern Cryptography\"\n  speakers:\n    - John Downey\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Modern Cryptography by: John Downey\n\n    Once the realm of shadowy government organizations, cryptography now permeates computing. Unfortunately, it is difficult to get correct and most developers know just enough to be harmful for their projects. Together, we’ll go through the basics of modern cryptography and where things can go horribly wrong.\n\n    Specific topics:\n\n    Cryptographic primitives\n    Secure password storage\n    Subtle flaws that can leave you insecure\n    Why you should use TLS/SSL and GPG instead\n  video_provider: \"youtube\"\n  video_id: \"W-0CIVd7mTI\"\n\n- id: \"charles-nutter-gogaruco-2012\"\n  title: \"High Performance Ruby\"\n  raw_title: \"GoGaRuCo 2012 - High Performance Ruby\"\n  speakers:\n    - Charles Nutter\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    High Performance Ruby by:  Charles Nutter\n  video_provider: \"youtube\"\n  video_id: \"3vzOSpcr4yk\"\n\n- id: \"jack-danger-canty-gogaruco-2012\"\n  title: \"Mega Rails\"\n  raw_title: \"GoGaRuCo 2012 - Mega Rails\"\n  speakers:\n    - Jack Danger Canty\n  event_name: \"GoGaRuCo 2012\"\n  date: \"2012-09-14\"\n  published_at: \"2015-07-14\"\n  description: |-\n    Mega Rails by: Jack Danger Canty\n\n    Square manages big data, high uptime, secure payment info and large teams in an agile Rails environment. It's hard. Our system has outgrown the patterns of a young Rails app and some of what used to help has started to hurt. It's painful to have your email templates in the same project as your API backend. It's agonizing to use your main datastore for analytics, and it hurts to throw code into ./lib or require unnecessary gems. This talk is about how we've turned individual Rails pieces into separate services and scaled our codebase, data, and integration testing practices to support multiple big teams efficiently.\n  video_provider: \"youtube\"\n  video_id: \"WDD_WoXAnQ4\"\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYAoKgLbr6Ug_OX1WfrtuPq\"\ntitle: \"GoGaRuCo 2013\"\nkind: \"conference\"\nlocation: \"San Francisco, CA, United States\"\ndescription: |-\n  https://web.archive.org/web/20140922034733/http://gogaruco.com/2013/\nstart_date: \"2013-09-20\"\nend_date: \"2013-09-21\"\npublished_at: \"2013-09-20\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2013\ncoordinates:\n  latitude: 37.7749295\n  longitude: -122.4194155\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2013/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"sam-saffron-gogaruco-2013\"\n  title: \"Measuring Ruby\"\n  raw_title: \"GoGaRuCo 2013 - Measuring Ruby by Sam Saffron and Jeff Atwood\"\n  speakers:\n    - Sam Saffron\n    - Jeff Atwood\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-09-27\"\n  description: |-\n    This talk will explore various techniques for measuring performance of Ruby apps. It will cover a wide set of tools: from Sam Saffron's own Flame Graphs and MiniProfiler, to rb-lineprof, and recent MRI commits that provide better information on object space allocation that will appear in Ruby 2.1. The talk will be highly technical.\n\n  video_provider: \"youtube\"\n  video_id: \"LWyEWUD-ztQ\"\n\n- id: \"steve-klabnik-gogaruco-2013\"\n  title: \"No Secrets Allowed\"\n  raw_title: \"GoGaRuCo 2013 - No Secrets Allowed by Steve Klabnik\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-10\"\n  description: |-\n    If there's anything that recent events have shown us, it's that what we thought was secret actually isn't. So what to do? Even if you're not a dissident, many of our applications need some form of private communications. And why aren't RubyGems signed, anyway? In this talk, Steve will discuss some of the basic tools, theory, and techniques that you can use to help keep secrets secret.\n\n  video_provider: \"youtube\"\n  video_id: \"LjZk8PP-u3c\"\n\n- id: \"jesse-toth-gogaruco-2013\"\n  title: \"Afternoon Storytime: Curiosity\"\n  raw_title: \"GoGaRuCo 2013 - Afternoon Storytime - Curiosity\"\n  speakers:\n    - Jesse Toth\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-10\"\n  description: |-\n    By Jesse Toth\n\n  video_provider: \"youtube\"\n  video_id: \"niC0Bsref5s\"\n\n- id: \"davy-stevenson-gogaruco-2013\"\n  title: \"Afternoon Storytime: Team Building\"\n  raw_title: \"GoGaRuCo 2013 - Afternoon Storytime - Team Building\"\n  speakers:\n    - Davy Stevenson\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-10\"\n  description: |-\n    By Davy Stevenson\n\n  video_provider: \"youtube\"\n  video_id: \"ZEqdyP-N-t8\"\n\n- id: \"davis-frank-gogaruco-2013\"\n  title: \"Afternoon Storytime: How I Test-Drove My Career\"\n  raw_title: \"GoGaRuCo 2013 - Afternoon Storytime - How I test-drove my Career\"\n  speakers:\n    - Davis Frank\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-10\"\n  description: |-\n    By Davis Frank\n\n  video_provider: \"youtube\"\n  video_id: \"ueeZKPGNk6I\"\n\n- id: \"tom-dale-gogaruco-2013\"\n  title: \"Stop Breaking The Web\"\n  raw_title: \"GoGaRuCo 2013 - Stop Breaking the Web by Tom Dale\"\n  speakers:\n    - Tom Dale\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-10\"\n  description: |-\n    You know that smartphone in your pocket? The one with gigahertz of processing power, a surprisingly good camera, and the ability to instantly access the whole of human knowledge? Despite all of that high technology, if I want to call you, I still have to punch in a phone number—a technological relic that remains integral to our telecommunication infrastructure.\n\n    URLs are the same thing. The web is URLs and URLs are the web. Unfortunately, for the past few years, many JavaScript developers have started treating the URL as an afterthought, or a nice-to-have. In this talk, I'll show why URL neglect happens at your own peril, and how making JavaScript apps that respect the URL can be, well, downright pleasant.\n\n  video_provider: \"youtube\"\n  video_id: \"r9oly00nYAE\"\n\n- id: \"emily-stolfo-gogaruco-2013\"\n  title: \"Thread Safety First\"\n  raw_title: \"GoGaRuCo 2013 - Thread Safety First by Emily Stolfo\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-10\"\n  description: |-\n    Concurrency in Ruby is hard and our thread-unsafe code often works by accident. We are not used to thinking about concurrency because of the GVL but there are different implementations of Ruby with their own semantics that can unearth concurrency bugs. We have to get more accustomed to writing threadsafe code and understanding concurrency, especially with the rise in popularity of JRuby.\n\n    I will discuss approaches to writing threadsafe code in this talk, with a specific focus on performance considerations. I'll start with explaining some basic concurrency concepts, describe methods for handling shared mutable data, and touch on the subtleties of concurrency primitives (Queue, ConditionVariable, Mutex). Historical, squashed, hair-raising bugs in the Ruby driver to MongoDB will be used throughout the presentation to illustrate particular concurrency issues and techniques for solving them.\n\n  video_provider: \"youtube\"\n  video_id: \"nzjIP6O4kEo\"\n\n- id: \"ron-evans-gogaruco-2013\"\n  title: \"Ruby On Robots Using Artoo\"\n  raw_title: \"GoGaRuCo 2013 - Ruby On Robots Using Artoo by Ron Evans\"\n  speakers:\n    - Ron Evans\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-09\"\n  description: |-\n    The robotics revolution has already begun. You can buy drones and robotic devices at local retail stores. Unfortunately, it's hard to develop code for robots, and nearly impossible to create solutions that integrate multiple different kind of devices. Introducing Artoo, a new robotics framework written in Ruby. Artoo can communicate with many different kinds of hardware devices, and integrate them together. With surprisingly few lines of code, you can write interesting applications that tie together Arduinos, ARDrones, Spheros, and more... even all at the same time! The time has come for Ruby-based robotics, and Artoo can help lead the way!\n\n  video_provider: \"youtube\"\n  video_id: \"b8_YyhUiVQ8\"\n\n- id: \"ryan-davis-gogaruco-2013\"\n  title: \"Scooping The Loop Snooper\"\n  raw_title: \"GoGaRuCo 2013 - Scooping The Loop Snooper by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"awjitzVU0Sk\"\n\n- id: \"tom-stuart-gogaruco-2013\"\n  title: \"Impossible Programs\"\n  raw_title: \"GoGaRuCo 2013 - Impossible Programs by Tom Stuart\"\n  speakers:\n    - Tom Stuart\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-09\"\n  description: |-\n    Every aspect of our lives has been transformed by the invention of general-purpose programmable computers. As a result, it's tempting to believe that computers can solve any logical or mathematical problem; that if we throw enough time, money and nerds at a question, we can produce a program which answers it.\n\n    Unfortunately the universe is never that convenient. There are hard theoretical limits on what programs are capable of doing, and there will always be straightforward problems which are impossible for any computer to solve.\n\n    This talk uses Ruby to tell a nail-biting, math-free story about the source of a computer's power, the inevitable drawbacks of that power, and the impossible programs which lie at the heart of uncomputability.\n\n  video_provider: \"youtube\"\n  video_id: \"xaH9YmNe8TM\"\n\n- id: \"nell-shamrell-gogaruco-2013\"\n  title: \"Beneath the Surface: Regular Expressions in Ruby\"\n  raw_title: \"GoGaRuCo 2013 - Beneath the Surface: Regular Expressions in Ruby\"\n  speakers:\n    - Nell Shamrell\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-09\"\n  description: |-\n    By Nell Shamrell\n\n    Many of us approach regular expressions with a certain fear and trepidation, using them only when absolutely necessary. We can get by when we need to use them, but we hesitate to dive any deeper into their cryptic world. Ruby has so much more to offer us. This talk showcases the incredible power of Ruby and the Oniguruma regex library Ruby runs on. It takes you on a journey beneath the surface, exploring the beauty, elegance, and power of regular expressions. You will discover the flexible, dynamic, and eloquent ways to harness this beauty and power in your own code.\n\n  video_provider: \"youtube\"\n  video_id: \"TMV3LrNG6-w\"\n\n- id: \"ben-orenstein-gogaruco-2013\"\n  title: \"Frequently Asked Questions\"\n  raw_title: \"GoGaRuCo 2013 - Frequently Asked Questions by Ben Orenstein\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-09\"\n  description: |-\n    This talk will explore various techniques for measuring performance of Ruby apps. It will cover a wide set of tools: from Sam Saffron's own Flame Graphs and MiniProfiler, to rb-lineprof, and recent MRI commits that provide better information on object space allocation that will appear in Ruby 2.1. The talk will be highly technical.\n\n  video_provider: \"youtube\"\n  video_id: \"8ZMOWypU34k\"\n\n- id: \"sarah-mei-gogaruco-2013\"\n  title: \"Why Hasn't Ruby Won?\"\n  raw_title: \"GoGaRuCo 2013 - Why hasn't Ruby won? by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-09\"\n  description: |-\n    For every enthusiastic attendee at a Ruby conference, there are a hundred people who have tried Ruby and walked away. There's also at least one person who's hit the top of Hacker News complaining about it. Are missing features or poor performance chasing people off? Is the community too international, or not responsive enough on GitHub? Maybe the problem is the ones who walk away — the inexperienced masses, poisoned by Flash, Visual Basic and PHP.\n\n    Languages and frameworks are interesting things. When you're choosing one, it's important to consider social information about your team — and the project you're evaluating — before making a decision. But while every README has bullet points listing the project's technical features, it's much more challenging to identify and extract the right social data to help that evaluation process.\n\n    Let's bring this missing information into the light and look at social data from real teams, real projects and real extracted code. We'll make better decisions. We'll understand why Hacker News exists. Everyone wins! And you still don't have to do Flash.\n\n  video_provider: \"youtube\"\n  video_id: \"dE4toi7y1MM\"\n\n- id: \"john-wilkinson-gogaruco-2013\"\n  title: \"SOA without the tears\"\n  raw_title: \"GoGaRuCo 2013 - SOA without the tears by John Wilkinson and Anthony Zacharakis\"\n  speakers:\n    - John Wilkinson\n    - Anthony Zacharakis\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-09\"\n  description: |-\n    Going full SOA has unarguable benefits, but the steep startup cost and need for excessive forward planning goes against the agile mentality of strictly necessary, small, incremental changes. At Lumosity, we've developed a set of best practices using engines to entirely divide behavior and responsibility by wrapping new services within well-defined, small Ruby APIs. This technique obviates the need for complex network (HTTP) APIs with their well-known problems of maintenance and testing. Get rid of spaghetti code without diving into the deep end of recorded responses and fake servers. Later, if the architecture demands a separate service, the engine will already have an API fully defined and ready to port over from Ruby to HTTP.\n\n  video_provider: \"youtube\"\n  video_id: \"JrS5pWp29OI\"\n\n- id: \"yehuda-katz-gogaruco-2013\"\n  title: \"A Tale of Two MVCs\"\n  raw_title: \"GoGaRuCo 2013 - A tale of two MVCs by Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"U9x-EaeJDuE\"\n\n- id: \"james-edward-gray-ii-gogaruco-2013\"\n  title: \"Built to Program\"\n  raw_title: \"GoGaRuCo 2013 - Built to Program by James Edward Gray II\"\n  speakers:\n    - James Edward Gray II\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-09\"\n  description: |-\n    James Edward Gray II has been programming long enough to learn a thing or two about how this computer stuff actually works. Nobody cares about that. Seriously, that's not the most common thing people ask him about. Instead, they often come with questions about why James tools around in an eletric wheelchair. Were legs just not hackable enough for his taste? Does he have a Charles Xavier complex? Does he not eat enough beta-carotene? James is ready to answer all of these questions. He believes the answers might even be just a little related to programming. Don't be surprised if you find yourself wishing for some neuromuscular disease of your very own. (Note: live genetic engineering is a violation of GoGaRuCo's insurance policy, but James can teach you how to fake a disability for the purposes of gaining deeper insight into code—allowable due to the Reprogrammed Humans for the Greater Good Act of 2442.)\n\n  video_provider: \"youtube\"\n  video_id: \"6cdbx1BmboQ\"\n\n- id: \"sarah-mei-gogaruco-2013-why-hasnt-ruby-won\"\n  title: \"Why Hasn't Ruby Won?\"\n  raw_title: \"GoGaRuCo 2013 - Why hasn't Ruby won? by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-09-28\"\n  description: |-\n    For every enthusiastic attendee at a Ruby conference, there are a hundred people who have tried Ruby and walked away. There's also at least one person who's hit the top of Hacker News complaining about it. Are missing features or poor performance chasing people off? Is the community too international, or not responsive enough on GitHub? Maybe the problem is the ones who walk away — the inexperienced masses, poisoned by Flash, Visual Basic and PHP.\n\n  video_provider: \"youtube\"\n  video_id: \"tlSFBGCaAwM\"\n\n- id: \"john-wilkinson-gogaruco-2013-soa-without-the-tears\"\n  title: \"SOA Without The Tears\"\n  raw_title: \"GoGaRuCo 2013 - SOA without the tears\"\n  speakers:\n    - John Wilkinson\n    - Anthony Zacharakis\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-09-28\"\n  description: |-\n    By John Wilkinson and Anthony Zacharakis\n\n    Going full SOA has unarguable benefits, but the steep startup cost and need for excessive forward planning goes against the agile mentality of strictly necessary, small, incremental changes. At Lumosity, we've developed a set of best practices using engines to entirely divide behavior and responsibility by wrapping new services within well-defined, small Ruby APIs. This technique obviates the need for complex network (HTTP) APIs with their well-known problems of maintenance and testing. Get rid of spaghetti code without diving into the deep end of recorded responses and fake servers. Later, if the architecture demands a separate service, the engine will already have an API fully defined and ready to port over from Ruby to HTTP.\n\n  video_provider: \"youtube\"\n  video_id: \"HV3BH2K5BQ8\"\n\n- id: \"yehuda-katz-gogaruco-2013-a-tale-of-wwo-mvcs\"\n  title: \"A Tale Of Wwo MVC's\"\n  raw_title: \"GoGaRuCo 2013 - A tale of two MVC's by Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-09-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"s1dhXamEAKQ\"\n\n- id: \"mike-dalessio-gogaruco-2013\"\n  title: \"Nokogiri: History, Present, and Future\"\n  raw_title: \"GoGaRuCo 2013 - Nokogiri: History, Present, and Future by Mike Dalessio\"\n  speakers:\n    - Mike Dalessio\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-09-25\"\n  description: |-\n    Over the past few years, Nokogiri has slowly eclipsed older XML parsing libraries to garner nearly 12 million downloads from rubygems.org. But why another XML parsing library? Isn't it boring? And what does \"nokogiri\" mean in Japanese, anyway?\n\n    These questions will be answered, and I'll do a brief dive into all the technologies that we use to make Nokogiri a fast, reliable and robust gem. Topics will include:\n\n    Origins of the project: motivation, problems and impact\n    Native C and Java extensions\n    FFI, and how to know if it's Right For You\n    Debugging tools (valgrind, perftools)\n    Packaging tools (mini_portile, rake-compiler)\n    Installation issues, and what we're doing to help\n\n  video_provider: \"youtube\"\n  video_id: \"BbG5slRsJ_0\"\n\n- id: \"aja-hammerly-gogaruco-2013\"\n  title: \"Seeing the Big Picture: Quick and Dirty Data Visualization with Ruby\"\n  raw_title: \"GoGaRuCo 2013 - Seeing the Big Picture: Quick and Dirty Data Visualization with Ruby\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-09-28\"\n  slides_url: \"https://thagomizer.com/files/dataviz_gogaruco_13.pdf\"\n  description: |-\n    By Aja Hammerly\n\n    Data is a hot buzz word in the industry. Every day there are more startups with \"Big Data\" somewhere in their elevator pitch. There are dozens of devices to record how we sleep, what we eat, how much we exercise, even how often we breathe. Every action we take online generates data that is stored and analyzed. Understanding all this data can be difficult. Humans aren't designed to see patterns in thousands of lines of json or XML. We are good at seeing patterns in pictures, graphs, diagrams, and spots in the underbrush. Often a simple visualization is what you need to understand a problem. In this talk, I'll demonstrate tools that you can use to quickly generate \"back-of-the-envelope\" visualizations from a variety of data sets.\n\n  video_provider: \"youtube\"\n  video_id: \"dWPRLCU39AU\"\n\n- id: \"chris-hunt-gogaruco-2013\"\n  title: \"Solving The Rubik's Cube in 20 Seconds\"\n  raw_title: \"GoGaRuCo 2013 - Solving the Rubik's Cube in 20 Seconds by Chris Hunt\"\n  speakers:\n    - Chris Hunt\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-09-27\"\n  description: |-\n    Come to San Francisco as a Rubyist, leave as a speedcuber. We are going to use Ruby, a video camera, and an insane amount of live demonstration to learn how to solve the Rubik's Cube in less than 20 seconds. You will leave this talk knowing which cube to buy, which of the five most popular solving methods you should be learning, how to practice for speed, where to ask questions, and how Ruby can help teach you to be the fastest speedcuber in town. People are solving the Rubik's Cube quicker today than any time in history and there's a reason why.\n\n  video_provider: \"youtube\"\n  video_id: \"PV9Tsu6ny-0\"\n\n- id: \"noah-gibbs-gogaruco-2013\"\n  title: \"The Littlest ORM\"\n  raw_title: \"GoGaRuCo 2013 - The Littlest ORM by Noah Gibbs\"\n  speakers:\n    - Noah Gibbs\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-09-27\"\n  description: |-\n    Ever wonder how Sequel, ActiveRecord or DataMapper work? Let's build a working mini-ORM, complete with an application and tests! Ruby makes it surprisingly easy. We'll go over all the code in 30 minutes. There will be a GitHub link so you don't have to type furiously.\n\n  video_provider: \"youtube\"\n  video_id: \"Uh5MYvNXt0A\"\n\n- id: \"ryan-davis-gogaruco-2013-lets-write-an-interpreter\"\n  title: \"Let's Write an Interpreter!\"\n  raw_title: \"GoGaRuCo 2013 - Let's Write an Interpreter! by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"GoGaRuCo 2013\"\n  date: \"2013-09-20\"\n  published_at: \"2013-10-10\"\n  description: |-\n    Let's dive into one of the the deep ends of CS and implement a turing-complete interpreter in just 30 minutes using ruby, ruby_parser, sexp_processor, and a minor amount of elbow grease.\n\n  video_provider: \"youtube\"\n  video_id: \"RPxvx9OkNic\"\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybfzulsRTEPaeN9_iTmeJPR\"\ntitle: \"GoGaRuCo 2014\"\nkind: \"conference\"\nlocation: \"San Francisco, CA, United States\"\ndescription: |-\n  https://web.archive.org/web/20141011232418/http://gogaruco.com/\nstart_date: \"2014-09-19\"\nend_date: \"2014-09-20\"\npublished_at: \"2014-09-19\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2014\ncoordinates:\n  latitude: 37.7749295\n  longitude: -122.4194155\naliases:\n  - Golden Gate Ruby Conference 2014\n"
  },
  {
    "path": "data/gogaruco/gogaruco-2014/videos.yml",
    "content": "---\n# https://web.archive.org/web/20141011232418/http://gogaruco.com/schedule/\n\n## Day 1\n\n- id: \"sarah-allen-gogaruco-2014\"\n  title: \"3 Reasons Not to Use Ruby\"\n  raw_title: \"GoGaRuCo 2014-  3 Reasons Not to Use Ruby\"\n  speakers:\n    - Sarah Allen\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-19\"\n  published_at: \"2014-10-02\"\n  description: |-\n    By, Sarah Allen\n    I love Ruby, but last year I found myself at the Smithsonian Institution coding in, of all things, PHP & Drupal. And I realized that despite my ambivalence towards those technologies, I had no compelling-enough reason to propose Ruby as an alternative. How did we get to this point? I’ll tell 3 reasons we didn't use Ruby, and reflect on whether these are things we want, or problems we should solve.\n  video_provider: \"youtube\"\n  video_id: \"ei_tanu3UyQ\"\n\n- id: \"tom-stuart-gogaruco-2014\"\n  title: \"Refactoring Ruby with Monads\"\n  raw_title: \"GoGaRuCo 2014- Refactoring Ruby with Monads\"\n  speakers:\n    - Tom Stuart\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-19\"\n  published_at: \"2014-10-02\"\n  description: |-\n    By, Tom Stuart\n    Monads are in danger of becoming a bit of a joke: for every person who raves about them, there's another person asking what in the world they are, and a third person writing a confusing tutorial about them. With their technical-sounding name and forbidding reputation, monads can seem like a complex, abstract idea that's only relevant to mathematicians and Haskell programmers.\n\n    Forget all that! In this pragmatic talk we'll roll up our sleeves and get stuck into refactoring some awkward Ruby code, using the good parts of monads to tackle the problems we encounter along the way. We'll see how the straightforward design pattern underlying monads can help us to make our code simpler, clearer and more reusable by uncovering its hidden structure, and we'll all leave with a shared understanding of what monads actually are and why people won't shut up about them.\n\n  video_provider: \"youtube\"\n  video_id: \"uTR__8RvgvM\"\n\n- id: \"starr-horne-gogaruco-2014\"\n  title: \"The Short and Happy Lives of TCP and HTTP Requests\"\n  raw_title: \"GoGaRuCo 2014- The Short and Happy Lives of TCP and HTTP Requests\"\n  speakers:\n    - Starr Horne\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-19\"\n  published_at: \"2014-10-02\"\n  description: |-\n    By, Starr Horne\n    As Rails developers we depend on the network. But if you're new to web development, it's probably a mystery. That's a problem. Knowing how the network works is critical for fixing certain types of bugs and for diagnosing performance issues.\n\n    In this talk, we'll follow the lives of a TCP and an HTTP request, marvel as they pass through your browse, OS, router, web server and app serve. Finally, we'll discuss how this knowledge is used to fix common bugs and increase app performance.\n\n  video_provider: \"youtube\"\n  video_id: \"4tBCDOgtWCg\"\n\n# Lunch\n\n- id: \"yonatan-bergman-gogaruco-2014\"\n  title: \"Building Board Games with Ruby\"\n  raw_title: \"GoGaRuCo 2014- Building Board Games with Ruby\"\n  speakers:\n    - Yonatan Bergman\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-19\"\n  published_at: \"2014-10-02\"\n  description: |-\n    By, Yonatan Bergman\n    Board games are seeing a huge resurgence right now, everywhere you look people are playing new games. The Internet and crowd funding has made it possible for almost anyone to design and develop a physical board game.\n\n    Join me while I share the story of how I used Ruby to design my first board game. How I honed the game mechanics and optimized all the different moving parts. You will leave this talk knowing the process of designing and developing a board game from scratch and how Ruby can help you iterate fast on new ideas using simple code, simulations and some statistics.\n\n  video_provider: \"youtube\"\n  video_id: \"EcnvbsXdbtI\"\n\n- id: \"aja-hammerly-gogaruco-2014\"\n  title: \"Giant Pile of Data\"\n  raw_title: \"GoGaRuCo 2014- Giant Pile of Data\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-19\"\n  published_at: \"2014-10-02\"\n  slides_url: \"https://thagomizer.com/files/GoGaRuCo2014.pdf\"\n  description: |-\n    By, Aja Hammerly\n    Storage gets cheaper every year and as a result many folks are turning into data hoaders. Maybe your current project has gigabytes or even terrabytes of data sitting in storage. Perhaps some has used the words \"big data\", \"data mining\", or \"personalized experience\" as an excuse to keep paying the storage bills.\n\n    Do you actually look at that data? How often do you use it? Is it really worth keeping it around? Do you know what questions it can answer?\n\n    In this talk I'll discuss how to use data to drive improvement and when to let it go. I'll focus not only on analysis tools, but also on interpretting data and how to decide if your data is valuable or clutter.\n\n  video_provider: \"youtube\"\n  video_id: \"aIMA_p2umQA\"\n\n- id: \"john-feminella-gogaruco-2014\"\n  title: \"Why We Can't Have Nice Things: FLoats, Dates, and Names\"\n  raw_title: \"GoGaRuCo 2014- Why We Can't Have Nice Things: FLoats, Dates, and Names\"\n  speakers:\n    - John Feminella\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-19\"\n  published_at: \"2014-10-03\"\n  description: |-\n    By, John Feminella\n    The real world is a messy place, and software reflects this to some extent. This messiness, however, doesn't mesh well with the general tendencies of software developers, who like to try to simplify the world with assumptions. When those assumptions later turn out to be wrong, bad things happen.\n\n    In this talk, we'll discuss three perennial sources of bad developer assumptions: floating point numbers, dates and times and the names of people, places, and things.\n\n    We'll illustrate why each of several commonly-made assumptions is incorrect, show how to use Ruby to arrive at the correct answer, and empower you to make better decisions about your code in the process.\n\n  video_provider: \"youtube\"\n  video_id: \"asttlUG2OuI\"\n\n# Snack Break\n\n- id: \"kate-heddleston-gogaruco-2014\"\n  title: \"Technical Onboarding, Training, and Mentoring\"\n  raw_title: \"GoGaRuCo 2014- Technical Onboarding, Training, and Mentoring\"\n  speakers:\n    - Kate Heddleston\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-19\"\n  published_at: \"2014-10-03\"\n  description: |-\n    By, Kate Heddleston\n    With the increase of code academies training new engineers there is an increase in junior engineers on the market. A lot of companies are hesitant to hire too many young engineers because they lack sufficient resources to train them. This is a talk about how to make junior engineers into independent and productive members of your engineering team faster and cheaper by outlining a plan for how to onboard engineers effectively based on data and anecdotes gathered from companies in San Francisco.\n\n  video_provider: \"youtube\"\n  video_id: \"3XfwanJe77s\"\n\n- id: \"daniel-doubrovkine-gogaruco-2014\"\n  title: \"Taking over Someone Else's Open-Source Projects\"\n  raw_title: \"GoGaRuCo 2014- Taking over Someone Else's Open-Source Projects\"\n  speakers:\n    - Daniel Doubrovkine\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-19\"\n  published_at: \"2014-10-03\"\n  description: |-\n    By, Daniel Doubrovkine\n    Over the past years I've created numerous open-source libraries, but my biggest and most popular open-source Ruby projects aren't my own. Three years ago I took over Grape and more recently Hashie Hashie. Both are very important to the community and used by thousands of projects.\n\n    Taking over someone else's project without just forking it away is both a commitment and a challenge. It's often ungrateful work, but it's really important. In this talk I'll give some history, motivations and practical tools of how to do it. What do to when maintainers go MIA, and more.\n\n  video_provider: \"youtube\"\n  video_id: \"8ijzefV-B7U\"\n\n- id: \"kiyoto-tamura-gogaruco-2014\"\n  title: \"How To Become a Data Scientist with Ruby and Fluentd\"\n  raw_title: \"GoGaRuCo 2014- How to become a data scientist with Ruby and Fluentd\"\n  speakers:\n    - Kiyoto Tamura\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-19\"\n  published_at: \"2014-10-03\"\n  description: |-\n    By, Kiyoto Tamura\n    As someone who once cut teeth in quantitative finance, I can tell you that a huge fraction of 'data science' is data collection. Yes, it's kind of unsexy, but it's hugely important. If you have bad data, you have no chance of drawing good conclusions from your data consistently. That was the thought behind the Fluentd project: we realized that the reality of data collection (especially for log data) is messy, and we wanted to clean it up.\n\n    In this talk, I plan to code live onstage to show how easy it is to get started with Fluentd by creating a useful data collection pipeline.\n\n  video_provider: \"youtube\"\n  video_id: \"jOaLG6IVhbs\"\n\n## Day 2\n\n- id: \"nathan-long-gogaruco-2014\"\n  title: \"Reimplementing Ruby's Hash\"\n  raw_title: \"GoGaRuCo 2014- Reimplementing Ruby's Hash\"\n  speakers:\n    - Nathan Long\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-20\"\n  published_at: \"2014-10-03\"\n  description: |-\n    By, Nathan Long\n    Hashes are very useful for labeling little bits of data. But do you know how cool they really are? For instance, whether a hash has 10 keys or 10 million doesn't change how long it takes to find the key you're looking for.\n\n    How does that work? I'll show you! We'll build our own hash class in Ruby. I'll also show you that \"Big O\" analysis isn't scary as we make our hash lean and mean.\n\n    Finally, we'll see what our hash can teach us about related topics, like programming languages and databases. Come ready to learn!\n\n  video_provider: \"youtube\"\n  video_id: \"rNXsqArbOx8\"\n\n- id: \"vipul-a-m-gogaruco-2014\"\n  title: \"Building an ORM with AReL: Walking up the (AS)Tree.\"\n  raw_title: \"GoGaRuCo 2014- Building an ORM with AReL: Walking up the (AS)Tree.\"\n  speakers:\n    - Vipul A M\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-20\"\n  published_at: \"2014-10-03\"\n  description: |-\n    By, Vipul Amler\n    We all love ActiveRecord. Its amazing. But how exactly does ActiveRecord handle generating complex SQL queries? How Joins, Associations and Table Relations are handled? Most of this raw power comes from ARel. ARel is packed up with many features for complex query generation.\n\n    Lets build our own ORM on top of ARel to see it in action. In the process we will also explore about how ActiveRecord hooks up with ARel.\n\n    This talk describes Relational Algebra, Object and Collection modelling of ARel using a tiny ORM at its base. At the end of talk you will be equipped with better understanding of ARel and AR as an ORM.\n\n  video_provider: \"youtube\"\n  video_id: \"pTmTh7LNVic\"\n\n- id: \"jessica-eldredge-gogaruco-2014\"\n  title: \"Sketchnoting: Creative Notes for Technical Content\"\n  raw_title: \"GoGaRuCo 2014- Sketchnoting: Creative Notes for Technical Content\"\n  speakers:\n    - Jessica Eldredge\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-20\"\n  published_at: \"2014-10-03\"\n  description: |-\n    By, Jessica Eldredge\n    As developers, most of our time is spent on computers and electronic devices; but sometimes good old-fashioned pen and paper is the best way to explore and develop our ideas. Sketchnoting combines hand-drawn elements and text to enhance focus, improve memory, and visualize important concepts. The practice of sketchnoting is not about the ability to draw—it's about the ability to listen.\n\n    This talk will cover tools and techniques to visually capture ideas, how to approach the mental multitasking required to sketch during technical talks and meetings, and why \"I can not draw\" is just a mental barrier to embracing creativity in your notes.\n\n  video_provider: \"youtube\"\n  video_id: \"dE2pqeI3LOI\"\n\n# Lunch\n\n- id: \"yehuda-katz-gogaruco-2014\"\n  title: \"Let's Talk About Rust\"\n  raw_title: \"GoGaRuCo 2014- Let’s Talk About Rust\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-20\"\n  published_at: \"2014-10-03\"\n  description: |-\n    By, Yehuda Katz\n\n  video_provider: \"youtube\"\n  video_id: \"ySW6Yk_DerY\"\n\n- id: \"blithe-rocher-gogaruco-2014\"\n  title: \"The Scientific Method of Troubleshooting\"\n  raw_title: \"GoGaRuCo 2014- The Scientific Method of Troubleshooting\"\n  speakers:\n    - Blithe Rocher\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-20\"\n  published_at: \"2014-10-07\"\n  description: |-\n    By, Blithe Rocher\n    For software engineers, troubleshooting is one of the toughest and most important skills to develop. When problems arise, a beginning developer's first instincts are to panic and head to StackOverflow. Rather than quick fixes, it's important to seek a deeper understanding of what went wrong.\n\n    Biologists, chemists, and physicists increase understanding about the world by applying the logical steps of the scientific method to discover solutions to complex problems. Like scientists, developers can learn troubleshooting skills by treating each problem like a mini \"science\" experiment.\n\n    In this talk we'll explore how using the scientific method can lead to greater understanding and more viable solutions to complex problems.\n\n  video_provider: \"youtube\"\n  video_id: \"h9YZXuUjyOs\"\n\n- id: \"ryan-davis-gogaruco-2014\"\n  title: \"Let's Build a Computer!\"\n  raw_title: \"GoGaRuCo 2014- Let's Build a Computer!\"\n  speakers:\n    - Ryan Davis\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-20\"\n  published_at: \"2014-10-07\"\n  description: |-\n    By, Ryan Davis\n    The increasing accessibility of computing and scripting languages means more and more of us don't have computer science fundamentals and hand-wave our laptops and servers as magic. But, it doesn't take much to learn that the wizard box you type on every day is just layers of simple logic wrapped and reused all the way up. Indeed, starting with a single nand gate you can build the entire realm of boolean logic, and from that, a computer.\n\n    Working through a curriculum called Nand to Tetrisand its associated text book The Elements of Computing Systems, the Seattle.rb Study Group did exactly that. In just 12 short weeks,we went from nothing to a whole stack computer starting from just a single nand gate. We built a (simulated) computer, an assembler for its machine code, a virtual machine, a high level language compiler, and an OS with games to run.\n\n    In this talk, I will start with the nand gate, and build up a working computer explaining each layer as I go. You may not be able to build along with me in just a half hour, but I hope to infect you with my love for this curriculum and hopefully have it spread to your ruby/study group.\n\n  video_provider: \"youtube\"\n  video_id: \"uZsiMG7N_B8\"\n\n# Snack Break\n\n- id: \"sarah-mei-gogaruco-2014\"\n  title: \"Lightning Talks\"\n  raw_title: \"GoGaRuCo 2014- Lightning Talks hosted by Sarah Mei\"\n  speakers:\n    - Sarah Mei # Host\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-20\"\n  published_at: \"2014-10-08\"\n  description: |-\n    Lightning talks are back! Share your Ruby-related talk of four minutes or less with 400 of your closest friends. We welcome the wacky, the serious, the ranty, and the technical.\n\n  video_provider: \"youtube\"\n  video_id: \"wQ9gHeT_Wx0\"\n  talks:\n    - title: \"Lightning Talk: Write Better Bug(report)s\"\n      event_name: \"GoGaRuCo 2014\"\n      date: \"2014-09-20\"\n      published_at: \"2014-10-08\"\n      start_cue: \"00:13\"\n      end_cue: \"04:05\"\n      id: \"marlena-compton-lighting-talk-gogaruco-2014\"\n      video_id: \"marlena-compton-lighting-talk-gogaruco-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Marlena Compton\n\n    - title: \"Lightning Talk: Huginn - Your Agents are standing by.\"\n      event_name: \"GoGaRuCo 2014\"\n      date: \"2014-09-20\"\n      published_at: \"2014-10-08\"\n      start_cue: \"04:05\"\n      end_cue: \"08:17\"\n      id: \"andrew-cantino-lighting-talk-gogaruco-2014\"\n      video_id: \"andrew-cantino-lighting-talk-gogaruco-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Cantino\n\n    - title: \"Lightning Talk: Code Reviews\"\n      event_name: \"GoGaRuCo 2014\"\n      date: \"2014-09-20\"\n      published_at: \"2014-10-08\"\n      start_cue: \"08:17\"\n      end_cue: \"11:10\"\n      id: \"enrique-morellon-lighting-talk-gogaruco-2014\"\n      video_id: \"enrique-morellon-lighting-talk-gogaruco-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Enrique Morellón\n\n    - title: \"Lightning Talk: WTF is ObjectSpace?!?\"\n      event_name: \"GoGaRuCo 2014\"\n      date: \"2014-09-20\"\n      published_at: \"2014-10-08\"\n      start_cue: \"11:10\"\n      end_cue: \"13:50\"\n      id: \"layne-mcnish-lighting-talk-gogaruco-2014\"\n      video_id: \"layne-mcnish-lighting-talk-gogaruco-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Layne McNish\n\n    - title: \"Lightning Talk: The Ruby Community\"\n      event_name: \"GoGaRuCo 2014\"\n      date: \"2014-09-20\"\n      published_at: \"2014-10-08\"\n      start_cue: \"13:50\"\n      end_cue: \"17:50\"\n      id: \"yehuda-katz-lighting-talk-gogaruco-2014\"\n      video_id: \"yehuda-katz-lighting-talk-gogaruco-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Yehuda Katz\n\n    - title: \"Lightning Talk: gem install console.log\"\n      event_name: \"GoGaRuCo 2014\"\n      date: \"2014-09-20\"\n      published_at: \"2014-10-08\"\n      start_cue: \"17:50\"\n      end_cue: \"20:17\"\n      id: \"conrad-irwin-lighting-talk-gogaruco-2014\"\n      video_id: \"conrad-irwin-lighting-talk-gogaruco-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Conrad Irwin\n\n    - title: \"Lightning Talk: Exercism\"\n      event_name: \"GoGaRuCo 2014\"\n      date: \"2014-09-20\"\n      published_at: \"2014-10-08\"\n      start_cue: \"20:17\"\n      end_cue: \"24:22\"\n      id: \"aarti-parikh-lighting-talk-gogaruco-2014\"\n      video_id: \"aarti-parikh-lighting-talk-gogaruco-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Aarti Parikh\n\n    - title: \"Lightning Talk: Geohashes are rad\"\n      event_name: \"GoGaRuCo 2014\"\n      date: \"2014-09-20\"\n      published_at: \"2014-10-08\"\n      start_cue: \"24:22\"\n      end_cue: \"28:40\"\n      id: \"brian-leonard-lighting-talk-gogaruco-2014\"\n      video_id: \"brian-leonard-lighting-talk-gogaruco-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Brian Leonard\n\n    - title: \"Lightning Talk: A GoGaRuCo Creation Myth\"\n      event_name: \"GoGaRuCo 2014\"\n      date: \"2014-09-20\"\n      published_at: \"2014-10-08\"\n      start_cue: \"28:40\"\n      end_cue: \"33:54\"\n      id: \"josh-susser-lighting-talk-gogaruco-2014\"\n      video_id: \"josh-susser-lighting-talk-gogaruco-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Josh Susser\n\n- id: \"randy-coulman-gogaruco-2014\"\n  title: \"Gilding the Rose: Refactoring Legacy Code\"\n  raw_title: \"GoGaRuCo 2014 Gilding the Rose: Refactoring Legacy Code\"\n  speakers:\n    - Randy Coulman\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-20\"\n  published_at: \"2014-10-07\"\n  description: |-\n    By, Randy Coulman\n    We all run into legacy code. Sometimes, we even write it ourselves. Working with legacy code can be a daunting challenge, but there are ways to tackle it. The Gilded Rose code kata is a coding exercise for practicing refactoring and testing skills in a legacy codebase.\n\n    In this presentation, I use the Gilded Rose kata to demonstrate techniques for safely working with a legacy codebase and using pure baby-step refactorings to improve the design.\n\n  video_provider: \"youtube\"\n  video_id: \"r3bi2xv5t20\"\n\n- id: \"pat-allan-gogaruco-2014\"\n  title: \"The Golden Age Of The Internet\"\n  raw_title: \"GoGaRuCo 2014- The Golden Age of the Internet\"\n  speakers:\n    - Pat Allan\n  event_name: \"GoGaRuCo 2014\"\n  date: \"2014-09-20\"\n  published_at: \"2014-10-08\"\n  description: |-\n    By, Pat Allan\n    Congratulations. The Internet is now the center of civilization as we know it, and we are the ones who shape the Internet. Our skills are in high demand, we are paid well, we find our work challenging, interesting, and even sometimes fulfilling. These are the glory days of our industry, and we should soak up every minute of it!\n\n    But with such great power comes a great deal of responsibility. Will we be looking back in the near future, wondering if we squandered our opportunities to shape the digital world accordingly?\n\n    There's no doubt that we value humanity, intelligence, and compassion. Let's take a look at the ways our industry can ensure these values are reflected not just in the people we are, but the way we work.\n\n  video_provider: \"youtube\"\n  video_id: \"Un4tH-dOjsM\"\n"
  },
  {
    "path": "data/gogaruco/series.yml",
    "content": "---\nname: \"Golden Gate Ruby Conference\"\nwebsite: \"https://gogaruco.com\"\ntwitter: \"gogaruco\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"GoGaRuCo\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\naliases:\n  - GoGaRuCo\n  - GOGARUCO\n  - Golden Gate Ruby Conf\n"
  },
  {
    "path": "data/goruco/goruco-2007/event.yml",
    "content": "---\nid: \"gorocu-2007\"\ntitle: \"GORUCO 2007\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  http://2007.goruco.com\npublished_at: \"2007-04-21\"\nstart_date: \"2007-04-21\"\nend_date: \"2007-04-21\"\nyear: 2007\nbanner_background: \"#101E27\"\nfeatured_background: \"#101E27\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2007.goruco.com\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2007/schedule.yml",
    "content": "# Schedule: https://2007.goruco.com/agenda/\n\n# 9:00 am – Registration and breakfast (provided by Google)\n# 10:00 am – Adhearsion — Jay Phillips\n# 11:05 am – JRuby: Ready for Prime Time — Nick Sieger\n# 12:10 pm – Going Camping — Jeremy McAnally\n# 1:00 pm – Lunch (provided by Google)\n# 2:30 pm – Lightning Talks\n# 3:35 pm – Categorizing Documents in Ruby — Paul Dix\n# 4:40 pm – Contexts, Mocks and Stubs. Oh My! — Trotter Cashion\n# 5:45 pm – Business Natural Language Ruby Systems — Jay Fields\n# 6:45 pm – Dinner (on your own)\n# 9:00 pm – 4:00 am – Afterparty\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2007-05-29\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Registration and breakfast (provided by Google)\n\n      - start_time: \"10:00\"\n        end_time: \"11:05\"\n        slots: 1\n\n      - start_time: \"11:05\"\n        end_time: \"12:10\"\n        slots: 1\n\n      - start_time: \"12:10\"\n        end_time: \"13:00\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch (provided by Google)\n\n      - start_time: \"14:30\"\n        end_time: \"15:35\"\n        slots: 1\n\n      - start_time: \"15:35\"\n        end_time: \"16:40\"\n        slots: 1\n\n      - start_time: \"16:40\"\n        end_time: \"17:45\"\n        slots: 1\n\n      - start_time: \"17:45\"\n        end_time: \"18:45\"\n        slots: 1\n\n      - start_time: \"18:45\"\n        end_time: \"21:00\"\n        slots: 1\n        items:\n          - Dinner (on your own)\n\n      - start_time: \"21:00\"\n        end_time: \"04:00\"\n        slots: 1\n        items:\n          - Afterparty\n"
  },
  {
    "path": "data/goruco/goruco-2007/venue.yml",
    "content": "---\nname: \"Pace University\"\naddress:\n  street: \"1 Pace Plaza\"\n  city: \"New York\"\n  region: \"NY\"\n  postal_code: \"10038\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"1 Pace Plaza, New York, NY 10038\"\ncoordinates:\n  latitude: 40.7112\n  longitude: -74.0042\nmaps:\n  google: \"https://maps.app.goo.gl/6vQWxbP5jFbTbmYr5\"\n"
  },
  {
    "path": "data/goruco/goruco-2007/videos.yml",
    "content": "---\n# http://2007.goruco.com/agenda/\n\n- id: \"adhearsion-GORUCO-2007\"\n  title: \"Adhearsion\"\n  raw_title: \"Adhearsion\"\n  speakers:\n    - Jay Phillips\n  event_name: \"GORUCO 2007\"\n  date: \"2007-04-21\"\n  description: |-\n    Adhearsion is a relatively new Ruby-based metaprogramming framework primarily for VoIP engineering with the popular, open-source PBX Asterisk. Adhearsion effectively takes over Asterisk’s internal instructions and replaces them with its own Ruby DSL which does the job orders of magnitude better. I’ll be speaking about how Adhearsion makes Ruby programmers overnight VoIP programming experts with the extreme ease and development efficiency it brings to the table. This presentation will focus on the Ruby aspects of Adhearsion and show how powerful Asterisk can become with Adhearsion calling its shots—specifically with VoIP integration into a Rails app, writing pure-Ruby dial plans, integrating your VoIP app with a database (something seldom done, believe it or not), how VoIP functionality can be exchanged (another thing seldom ever done), using Adhearsion’s internals over DRb, etc.\n\n    Jay Phillips is a passionate hacker and open source evangelist turned entrepreneur. Jay is the mind behind Adhearsion, a new open-source meta-programming framework bringing people, businesses, and technologies closer together than ever. With his company Codemecca LLC, Jay helps companies achieve newfound value in their VoIP deployments by tapping Adhearsion’s many strengths.\n  video_provider: \"not_published\"\n  video_id: \"adhearsion-GORUCO-2007\"\n\n- id: \"jruby-ready-for-prime-time-GORUCO-2007\"\n  title: \"JRuby: Ready for Prime Time\"\n  raw_title: \"JRuby: Ready for Prime Time\"\n  speakers:\n    - Nick Sieger\n  event_name: \"GORUCO 2007\"\n  date: \"2007-04-21\"\n  description: |-\n    JRuby development has been advancing at a blistering pace over the past year, closing in on its goal of being a mature, stable alternate implementation of the Ruby language. Performance gaps with C Ruby are narrowing each week; Rails runs with 90%+ of Rails core tests passing; Java versions of popular C-extension packages such as Mongrel and Hpricot have appeared, showing that JRuby is a viable platform for Ruby applications.\n\n    In this talk I'll present an up-to-date status on JRuby, discuss implementation pros and cons compared to C Ruby (e.g., native threading), and demonstrate an application or two that hit JRuby’s sweet spot, including deploying Rails to a Java application server.\n\n    Nick Sieger is a member of the JRuby core team since December 2006, and has been programming Ruby for two years and Java for too many. In addition to JRuby contributions, he has written some miscellaneous Ruby bits to for using RSpec with Autotest and generating XML reports of test/spec runs, among others. He maintains a blog on mostly-Ruby and JRuby-related topics at http://blog.nicksieger.com/.\n  video_provider: \"not_published\"\n  video_id: \"jruby-ready-for-prime-time-GORUCO-2007\"\n\n- id: \"going-camping-GORUCO-2007\"\n  title: \"Going Camping\"\n  raw_title: \"Going Camping\"\n  speakers:\n    - Jeremy McAnally\n  event_name: \"GORUCO 2007\"\n  date: \"2007-04-21\"\n  description: |-\n    This talk will go over the basics of using Camping, why the lucky stiff’s web development framework, when and why to use Camping as opposed to Rails or something else, and do its best to correlate all the knowledge that Rails developers have built up to its corollary in Camping.\n\n    Jeremy McAnally is a Ruby developer and author, living in Knoxville, TN. He wrote Mr. Neighborly’s Humble Little Ruby Book and is currently working on Ruby in Practice for Manning Publications. He is working on the official Rails documentation project and is the author of dcov, the Rdoc documentation coverage testing tool.\n  video_provider: \"not_published\"\n  video_id: \"going-camping-GORUCO-2007\"\n\n# Lunch\n\n- id: \"lightning-talks-GORUCO-2007\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  speakers:\n    - Various Speakers\n  event_name: \"GORUCO 2007\"\n  date: \"2007-04-21\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-GORUCO-2007\"\n\n- id: \"categorizing-documents-in-ruby-GORUCO-2007\"\n  title: \"Categorizing Documents in Ruby\"\n  raw_title: \"Categorizing Documents in Ruby\"\n  speakers:\n    - Paul Dix\n  event_name: \"GORUCO 2007\"\n  date: \"2007-04-21\"\n  description: |-\n    Text classification is the task of selecting a class or category for a document or block of text. The canonical example of this is the use of the Naive Bayes classifier for identifying spam vs. non-spam email. Classifiers can also be used for language identification, categorizing news articles or blog posts, detecting trackback spam, comment spam, wiki spam, and more. In my talk I will cover the basics of document classification while focusing on the various tools available in Ruby for each aspect of classification.\n\n    Paul Dix is a computer science student at Columbia University in New York City. Before going back to school in 2005, Paul worked at McAfee as a developer. He has been attending the nyc.rb meetings since October of 2005. Text classification is a subset of Paul’s interests in natural language processing, machine learning, and information retrieval. Last summer he worked as a consultant with EastMedia developing web applications in Ruby on Rails. Paul also attended RailsConf last June and codes in Ruby every chance he gets.\n  video_provider: \"not_published\"\n  video_id: \"categorizing-documents-in-ruby-GORUCO-2007\"\n\n- id: \"contexts-mocks-and-stubs-oh-my-GORUCO-2007\"\n  title: \"Contexts, Mocks and Stubs. Oh My!\"\n  raw_title: \"Contexts, Mocks and Stubs. Oh My!\"\n  speakers:\n    - Trotter Cashion\n  event_name: \"GORUCO 2007\"\n  date: \"2007-04-21\"\n  description: |-\n    My talk will cover the benefits of using contexts, mocks, and stubs in unit tests. These three concepts are in heavy use by RSpec users, but seem to have minimal adoption by the bulk of Ruby developers. In addition, many developers do not even realize that contexts are an option within TestUnit. This talk will serve to enlighten these developers by showing them how to make contexts, mocks, and stubs work for them. I will explain how contexts can be used to bring organization to large test classes by organizing tests into related groups of object state. In addition, I will explain how to use mocks and stubs to easily test hard to test components, while cautioning against the dangers of going overboard.\n\n    Trotter Cashion has been using Ruby for almost the past two years. At EastMedia, he worked on pip.verisignlabs.com, the first OpenID server in Rails. In addition, he worked on the cms for nyjets.com. He is now employed as an Application Developer at motionbox.com, a Rails based video sharing site. He is currently writing a Short Cut (e-book) for Addison Wesley about Refactoring and REST.\n  video_provider: \"not_published\"\n  video_id: \"contexts-mocks-and-stubs-oh-my-GORUCO-2007\"\n\n- id: \"business-natural-language-ruby-systems-GORUCO-2007\"\n  title: \"Business Natural Language Ruby Systems\"\n  raw_title: \"Business Natural Language Ruby Systems\"\n  speakers:\n    - Jay Fields\n  event_name: \"GORUCO 2007\"\n  date: \"2007-04-21\"\n  description: |-\n    A Business Natural Language is a Domain Specific Language where subject matter experts use natural language to represent business logic. For example, a marketing executive for an airline could specify point award descriptions as: “award 1 point for each mile flown where the total flight length is greater than 500 miles”\n\n    The above example reads as specification; however, the code is also executable. By providing a language that subject matter experts are comfortable working with several benefits are achieved, the two largest being:\n\n    * The business may change it's rules without intervention of a programmer\n    * Programmers no longer need to spend their time trying to represent the logic of a business in lower level languages and can focus on other more interesting tasks\n\n    Jay Fields is a software developer at ThoughtWorks. He is a early adopter who is consistantly looking for new exciting technologies. His most recent work has been in the Domain Specific Language space where he delivered applications that empowered subject matter experts to write the business rules of the applications.\n  video_provider: \"not_published\"\n  video_id: \"business-natural-language-ruby-systems-GORUCO-2007\"\n"
  },
  {
    "path": "data/goruco/goruco-2008/event.yml",
    "content": "---\nid: \"PL12686083008C28A5\"\ntitle: \"GORUCO 2008\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  http://2008.goruco.com\npublished_at: \"2008-04-26\"\nstart_date: \"2008-04-26\"\nend_date: \"2008-04-26\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2008\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#1D1D1D\"\nwebsite: \"https://2008.goruco.com\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2008/videos.yml",
    "content": "---\n# http://2008.goruco.com/agenda/\n\n- id: \"bryan-helmkamp-goruco-2008\"\n  title: \"Story Driven Development: The Next Generation of Rails Functional Testing\"\n  raw_title: \"Story Driven Development: The Next Generation of Rails Functional Testing by Bryan Helmkamp\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"GORUCO 2008\"\n  date: \"2008-04-26\"\n  published_at: \"2012-04-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ApD-F65Vv-Q\"\n\n- id: \"giles-bowkett-goruco-2008\"\n  title: \"Archaeopteryx: A Ruby MIDI Generator\"\n  raw_title: \"Archaeopteryx: A Ruby MIDI Generator by Giles Bowkett\"\n  speakers:\n    - Giles Bowkett\n  event_name: \"GORUCO 2008\"\n  date: \"2008-04-26\"\n  published_at: \"2012-04-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"0XDawYp9mKY\"\n\n- id: \"chris-wanstrath-goruco-2008\"\n  title: \"Forbidden Fruit: A Test of Ruby's Parse Tree\"\n  raw_title: \"Forbidden Fruit: A Test of Ruby's Parse Tree by Chris Wanstrath\"\n  speakers:\n    - Chris Wanstrath\n  event_name: \"GORUCO 2008\"\n  date: \"2008-04-26\"\n  published_at: \"2012-04-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DAoYufIKebU\"\n\n# Lunch\n\n- id: \"ryan-davis-goruco-2008\"\n  title: \"Hurting Code for Fun and Profit\"\n  raw_title: \"Hurting Code for Fun and Profit by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"GORUCO 2008\"\n  date: \"2008-04-26\"\n  published_at: \"2012-04-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"L_z5oqPrDWY\"\n\n- id: \"paul-dix-goruco-2008\"\n  title: \"Collective Intelligence\"\n  raw_title: \"Collective Intelligence by Paul Dix\"\n  speakers:\n    - Paul Dix\n  event_name: \"GORUCO 2008\"\n  date: \"2008-04-26\"\n  published_at: \"2012-04-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"dNzA5Yygm5U\"\n\n- id: \"ezra-zygmuntowicz-goruco-2008\"\n  title: \"Merb, All you need, nil you don't\"\n  raw_title: \"Goruco 2008 Merb, All you need, nil you don't by Ezra Zygmuntowicz\"\n  speakers:\n    - Ezra Zygmuntowicz\n  event_name: \"GORUCO 2008\"\n  date: \"2008-04-26\"\n  published_at: \"2012-04-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"BqjPOC_ckG4\"\n\n# Break\n\n- id: \"lightning-talks-rejectconf-goruco-2008\"\n  title: \"GORUCO 2008 RejectConf\"\n  raw_title: \"RejectConf / Lightning Talks by Various Presenters\"\n  event_name: \"GORUCO 2008\"\n  date: \"2008-04-26\"\n  published_at: \"2012-04-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"W7TGK7f_IDM\"\n  talks:\n    - title: \"Lightning Talk: Intro\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"00:08\"\n      end_cue: \"01:48\"\n      id: \"ryan-davis-lighting-talk-goruco-2008\"\n      video_id: \"ryan-davis-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Ryan Davis\n\n    - title: \"Lightning Talk: Johnson\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"01:48\"\n      end_cue: \"07:10\"\n      id: \"yehuda-katz-lighting-talk-goruco-2008\"\n      video_id: \"yehuda-katz-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Yehuda Katz\n\n    - title: \"Lightning Talk: Arepa\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"07:10\"\n      end_cue: \"12:35\"\n      id: \"sebastian-delmont-lighting-talk-goruco-2008\"\n      video_id: \"sebastian-delmont-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Sebastian Delmont\n\n    - title: \"Lightning Talk: Ruby Mendicant\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"12:35\"\n      end_cue: \"19:10\"\n      id: \"gregory-brown-lighting-talk-goruco-2008\"\n      video_id: \"gregory-brown-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Gregory Brown\n\n    - title: \"Lightning Talk: EEE PC\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"19:10\"\n      end_cue: \"22:59\"\n      id: \"dan-dimaggio-lighting-talk-goruco-2008\"\n      video_id: \"dan-dimaggio-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Dan DiMaggio\n\n    - title: \"Lightning Talk: Cinema Redux\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"22:59\"\n      end_cue: \"29:30\"\n      id: \"phil-matarese-lighting-talk-goruco-2008\"\n      video_id: \"phil-matarese-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Phil Matarese\n\n    - title: \"Lightning Talk: Rubot\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"29:30\"\n      end_cue: \"38:40\"\n      id: \"peter-jaros-lighting-talk-goruco-2008\"\n      video_id: \"peter-jaros-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Peter Jaros\n\n    - title: \"Lightning Talk: Mindstorms\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"38:40\"\n      end_cue: \"43:15\"\n      id: \"giles-bowkett-lighting-talk-goruco-2008\"\n      video_id: \"giles-bowkett-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Giles Bowkett\n\n    - title: \"Lightning Talk: Frameless RDoc\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"43:15\"\n      end_cue: \"44:30\"\n      id: \"eric-hodel-lighting-talk-goruco-2008\"\n      video_id: \"eric-hodel-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Eric Hodel\n\n    - title: \"Lightning Talk: Flog\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"44:30\"\n      end_cue: \"47:30\"\n      id: \"luke-melia-lighting-talk-goruco-2008\"\n      video_id: \"luke-melia-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Luke Melia\n\n    - title: \"Lightning Talk: Oil Lisp\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"47:49\"\n      end_cue: \"51:10\"\n      id: \"chris-wanstrath-lighting-talk-goruco-2008\"\n      video_id: \"chris-wanstrath-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Wanstrath\n\n    - title: \"Lightning Talk: Basset Bayesian Classifiers\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"51:10\"\n      end_cue: \"55:00\"\n      id: \"paul-dix-lighting-talk-goruco-2008\"\n      video_id: \"paul-dix-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Paul Dix\n\n    - title: \"Lightning Talk: Ruby Constants\"\n      event_name: \"GORUCO 2008\"\n      date: \"2008-04-26\"\n      published_at: \"2012-04-18\"\n      start_cue: \"55:00\"\n      id: \"wilson-bilkovich-lighting-talk-goruco-2008\"\n      video_id: \"wilson-bilkovich-lighting-talk-goruco-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Wilson Bilkovich\n"
  },
  {
    "path": "data/goruco/goruco-2009/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYk-_BMaCwBWgBzAuNcwMGZ\"\ntitle: \"GORUCO 2009\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  http://2009.goruco.com\nstart_date: \"2009-05-30\"\nend_date: \"2009-05-30\"\npublished_at: \"2009-05-30\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2009\nbanner_background: |-\n  linear-gradient(to bottom, #4D1B23, #4D1B23 100%) left top / 50% 100% no-repeat, /* Left side */\n  linear-gradient(to bottom, #080304, #080304 100%) right top / 50% 100% no-repeat /* Right side */\nfeatured_background: \"#2B2B2B\"\nfeatured_color: \"#080304\"\nwebsite: \"https://2009.goruco.com\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2009/videos.yml",
    "content": "---\n# http://2009.goruco.com\n\n- id: \"gregory-brown-goruco-2009\"\n  title: \"Where is Ruby Really Heading?\"\n  raw_title: \"GORUCO 2009 -Where is Ruby Really Heading? by Gregory Brown\"\n  speakers:\n    - Gregory Brown\n  event_name: \"GORUCO 2009\"\n  date: \"2009-05-30\"\n  published_at: \"2015-03-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"_I4hIdjO5vk\"\n\n- id: \"eleanor-mchugh-goruco-2009\"\n  title: \"The Ruby Guide to *nix Plumbing\"\n  raw_title: \"GORUCO 2009 - The Ruby Guide to *nix Plumbing by Eleanor McHugh\"\n  speakers:\n    - Eleanor McHugh\n  event_name: \"GORUCO 2009\"\n  date: \"2009-05-30\"\n  published_at: \"2015-03-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"d9mRPwLHMb8\"\n\n- id: \"dan-yoder-goruco-2009\"\n  title: \"Resource-Oriented Architecture With Waves\"\n  raw_title: \"GORUCO 2009 - Resource-Oriented Architecture With Waves by Dan Yoder\"\n  speakers:\n    - Dan Yoder\n  event_name: \"GORUCO 2009\"\n  date: \"2009-05-30\"\n  published_at: \"2015-03-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"q-BAtwhCcpE\"\n\n# Lunch\n\n- id: \"jake-howerton-goruco-2009\"\n  title: \"Into the Heart of Darkness: Rails Anti-Patterns\"\n  raw_title: \"GORUCO 2009 - Into the Heart of Darkness: Rails Anti-Patterns by Jake Howerton\"\n  speakers:\n    - Jake Howerton\n  event_name: \"GORUCO 2009\"\n  date: \"2009-05-30\"\n  published_at: \"2015-03-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"bnrNX9sASoE\"\n\n- id: \"sandi-metz-goruco-2009\"\n  title: \"SOLID Object-Oriented Design\"\n  raw_title: \"GORUCO 2009 - SOLID Object-Oriented Design by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"GORUCO 2009\"\n  date: \"2009-05-30\"\n  published_at: \"2015-03-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"v-2yFMzxqwU\"\n\n# Break\n\n- id: \"ben-stein-goruco-2009\"\n  title: \"Building Cross Platform Mobile Apps with Ruby and PhoneGap\"\n  raw_title: \"GORUCO 2009 - Building Cross Platform Mobile Apps with Ruby and PhoneGap by Ben Stein\"\n  speakers:\n    - Ben Stein\n  event_name: \"GORUCO 2009\"\n  date: \"2009-05-30\"\n  published_at: \"2015-03-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"VlcTf9kuk7U\"\n\n- id: \"yehuda-katz-goruco-2009\"\n  title: \"From Rails to Rack: Making Rails 3 a Better Ruby Citizen\"\n  raw_title: \"GORUCO 2009 - From Rails to Rack: Making Rails 3 a Better Ruby Citizen by Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"GORUCO 2009\"\n  date: \"2009-05-30\"\n  published_at: \"2015-03-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"m9eLeL9RdbA\"\n\n- id: \"lightning-talks-rejectconf-goruco-2009\"\n  title: \"GORUCO 2009 RejectConf\"\n  raw_title: \"GORUCO 2009 - RejectConf by Various Presenters\"\n  event_name: \"GORUCO 2009\"\n  date: \"2009-05-30\"\n  published_at: \"2015-03-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"_DY8P6Vkl0k\"\n  talks:\n    - title: \"Lightning Talk: Chef\"\n      start_cue: \"00:18\"\n      end_cue: \"02:20\"\n      id: \"josh-knowles-lighting-talk-goruco-2009\"\n      video_id: \"josh-knowles-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Josh Knowles\n\n    - title: \"Lightning Talk: Thunder\"\n      start_cue: \"02:20\"\n      end_cue: \"03:30\"\n      id: \"pat-nakajima-lighting-talk-goruco-2009\"\n      video_id: \"pat-nakajima-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Pat Nakajima\n\n    - title: \"Lightning Talk: Apps For America\"\n      start_cue: \"03:30\"\n      end_cue: \"06:30\"\n      id: \"eric-mill-lighting-talk-goruco-2009\"\n      video_id: \"eric-mill-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Eric Mill\n\n    - title: \"Lightning Talk: RailsBridge\"\n      start_cue: \"06:30\"\n      end_cue: \"08:35\"\n      id: \"aaron-quint-railsbridge-lighting-talk-goruco-2009\"\n      video_id: \"aaron-quint-railsbridge-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Aaron Quint\n\n    - title: \"Lightning Talk: Sammy.js\"\n      start_cue: \"08:35\"\n      end_cue: \"10:00\"\n      id: \"aaron-quint-sammy-lighting-talk-goruco-2009\"\n      video_id: \"aaron-quint-sammy-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Aaron Quint\n\n    - title: \"Lightning Talk: AHA - DOOP - not just for counting words\"\n      start_cue: \"10:00\"\n      end_cue: \"13:00\"\n      id: \"ben-woosley-lighting-talk-goruco-2009\"\n      video_id: \"ben-woosley-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Ben Woosley\n\n    - title: \"Lightning Talk: Abstraction and Freeze Ray\"\n      start_cue: \"13:00\"\n      end_cue: \"18:25\"\n      id: \"peter-jaros-lighting-talk-goruco-2009\"\n      video_id: \"peter-jaros-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Peter Jaros\n\n    - title: \"Lightning Talk: Fix Ruby Threads: 10x+ Perf Boost*\"\n      start_cue: \"18:25\"\n      end_cue: \"22:00\"\n      id: \"joe-damato-lighting-talk-goruco-2009\"\n      video_id: \"joe-damato-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Joe Damato\n\n    - title: \"Lightning Talk: Google Perf Tools\"\n      start_cue: \"22:00\"\n      end_cue: \"27:30\"\n      id: \"aman-gupta-lighting-talk-goruco-2009\"\n      video_id: \"aman-gupta-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Aman Gupta\n\n    - title: \"Lightning Talk: You're Doing it Wrong - Packaging Gems\"\n      start_cue: \"27:30\"\n      end_cue: \"30:38\"\n      id: \"eric-hodel-lighting-talk-goruco-2009\"\n      video_id: \"eric-hodel-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Eric Hodel\n\n    - title: \"Lightning Talk: Observable\"\n      start_cue: \"30:38\"\n      id: \"luke-melia-lighting-talk-goruco-2009\"\n      video_id: \"luke-melia-lighting-talk-goruco-2009\"\n      video_provider: \"parent\"\n      speakers:\n        - Luke Melia\n"
  },
  {
    "path": "data/goruco/goruco-2010/event.yml",
    "content": "---\nid: \"gorucuo-2010\"\ntitle: \"GORUCO 2010\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  http://2010.goruco.com\npublished_at: \"2010-05-22\"\nstart_date: \"2010-05-22\"\nend_date: \"2010-05-22\"\nyear: 2010\nbanner_background: \"#1D1D1D\"\nfeatured_background: \"#1D1D1D\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2010.goruco.com\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2010/schedule.yml",
    "content": "# Schedule: http://2010.goruco.com\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2010-05-22\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Registration and breakfast\n\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening Remarks\n\n      - start_time: \"10:00\"\n        end_time: \"10:55\"\n        slots: 1\n\n      - start_time: \"10:55\"\n        end_time: \"11:50\"\n        slots: 1\n\n      - start_time: \"11:50\"\n        end_time: \"12:35\"\n        slots: 1\n\n      - start_time: \"12:35\"\n        end_time: \"13:45\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:45\"\n        end_time: \"14:40\"\n        slots: 1\n\n      - start_time: \"14:40\"\n        end_time: \"15:25\"\n        slots: 1\n\n      - start_time: \"15:25\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:45\"\n        end_time: \"16:40\"\n        slots: 1\n\n      - start_time: \"16:40\"\n        end_time: \"17:35\"\n        slots: 1\n\n      - start_time: \"17:35\"\n        end_time: \"18:30\"\n        slots: 1\n"
  },
  {
    "path": "data/goruco/goruco-2010/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold Sponsors\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Pivotal Labs\"\n          website: \"http://pivotallabs.com\"\n          slug: \"pivotal-labs\"\n          logo_url: \"https://2010.goruco.com/images/sponsors/pivotal.png\"\n\n    - name: \"Silver Sponsors\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"Engine Yard\"\n          website: \"https://www.engineyard.com/\"\n          slug: \"engine-yard\"\n          logo_url: \"https://2010.goruco.com/images/sponsors/engineyard.png\"\n\n        - name: \"Medidata\"\n          website: \"http://www.mdsol.com/\"\n          slug: \"medidata\"\n          logo_url: \"https://2010.goruco.com/images/sponsors/medidata.png\"\n\n        - name: \"Cyrus Innovation\"\n          website: \"http://www.cyrusinnovation.com/\"\n          slug: \"cyrus-innovation\"\n          logo_url: \"https://2010.goruco.com/images/sponsors/cyrus.png\"\n\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 4\n      sponsors:\n        - name: \"New Relic\"\n          website: \"https://www.newrelic.com/\"\n          slug: \"new-relic\"\n          logo_url: \"\"\n"
  },
  {
    "path": "data/goruco/goruco-2010/venue.yml",
    "content": "---\nname: \"Pace University\"\naddress:\n  street: \"1 Pace Plaza\"\n  city: \"New York\"\n  region: \"NY\"\n  postal_code: \"10038\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"1 Pace Plaza, New York, NY 10038\"\ncoordinates:\n  latitude: 40.7112\n  longitude: -74.0042\nmaps:\n  google: \"https://maps.app.goo.gl/6vQWxbP5jFbTbmYr5\"\n"
  },
  {
    "path": "data/goruco/goruco-2010/videos.yml",
    "content": "---\n# Website: http://2010.goruco.com\n\n- id: \"nick-gauthier-goruco-2010\"\n  title: \"Grease Your Suite - Tips and Tricks for Faster Testing\"\n  raw_title: \"GORUCO 2010: Grease Your Suite - Tips and Tricks For Faster Testing (Nick Gauthier)\"\n  speakers:\n    - Nick Gauthier\n  event_name: \"GORUCO 2010\"\n  date: \"2010-05-22\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2010: Grease Your Suite - Tips and Tricks For Faster Testing (Nick Gauthier)\n  video_provider: \"youtube\"\n  video_id: \"3x1uXnvVwdY\"\n\n- id: \"aman-gupta-goruco-2010\"\n  title: \"memprof - The Ruby Level Memory Profiler\"\n  raw_title: \"GORUCO 2010: memprof - The Ruby Level Memory Profiler (Aman Gupta)\"\n  speakers:\n    - Aman Gupta\n  event_name: \"GORUCO 2010\"\n  date: \"2010-05-22\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2010: memprof - The Ruby Level Memory Profiler (Aman Gupta)\n  video_provider: \"youtube\"\n  video_id: \"djqDRbZfO8A\"\n\n- id: \"luke-melia-goruco-2010\"\n  title: \"Managing Ruby Teams\"\n  raw_title: \"GORUCO 2010: Managing Ruby Teams (Luke Melia)\"\n  speakers:\n    - Luke Melia\n  event_name: \"GORUCO 2010\"\n  date: \"2010-05-22\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2010: Managing Ruby Teams (Luke Melia)\n  video_provider: \"youtube\"\n  video_id: \"5IaCR5YmkLc\"\n\n- id: \"chris-williams-goruco-2010\"\n  title: \"Rails' Best Caching Method is JavaScript\"\n  raw_title: \"GORUCO 2010: Rails' Best Caching Method is JavaScript (Chris Williams)\"\n  speakers:\n    - Chris Williams\n  event_name: \"GORUCO 2010\"\n  date: \"2010-05-22\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2010: Rails' Best Caching Method is JavaScript (Chris Williams)\n  video_provider: \"youtube\"\n  video_id: \"zTN1bYRO5gg\"\n\n- id: \"alex-maccaw-goruco-2010\"\n  title: \"Bowline - Ruby Desktop Applications\"\n  raw_title: \"GORUCO 2010: Bowline - Ruby Desktop Applications (Alex Maccaw)\"\n  speakers:\n    - Alex MacCaw\n  event_name: \"GORUCO 2010\"\n  date: \"2010-05-22\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2010: Bowline - Ruby Desktop Applications (Alex Maccaw)\n  video_provider: \"youtube\"\n  video_id: \"29gPkhF74uI\"\n\n- id: \"paul-dix-goruco-2010\"\n  title: \"Building Web Service Clients with ActiveModel\"\n  raw_title: \"GORUCO 2010: Building Web Service Clients with ActiveModel (Paul Dix)\"\n  speakers:\n    - Paul Dix\n  event_name: \"GORUCO 2010\"\n  date: \"2010-05-22\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2010: Building Web Service Clients with ActiveModel (Paul Dix)\n  video_provider: \"youtube\"\n  video_id: \"AsAe4nIkDdg\"\n\n- id: \"james-golick-goruco-2010\"\n  title: \"Scaling to Hundreds of Millions of Requests\"\n  raw_title: \"GORUCO 2010: Scaling to Hundreds of Millions of Requests (James Golick)\"\n  speakers:\n    - James Golick\n  event_name: \"GORUCO 2010\"\n  date: \"2010-05-22\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2010: Scaling to Hundreds of Millions of Requests (James Golick)\n  video_provider: \"youtube\"\n  video_id: \"NSfXIGG7ue8\"\n\n- id: \"rejectconf-goruco-2010\"\n  title: \"GORUCO 2010 RejectConf\"\n  raw_title: \"GORUCO 2010: RejectConf\"\n  event_name: \"GORUCO 2010\"\n  date: \"2010-05-22\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2010: RejectConf\n  video_provider: \"youtube\"\n  video_id: \"1NB88zPQWOs\"\n  talks:\n    - title: \"Lightning Talk: Bookmarklets\"\n      start_cue: \"00:20\"\n      end_cue: \"02:25\"\n      id: \"pat-nakajima-lightning-talk-goruco-2010\"\n      video_id: \"pat-nakajima-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Pat Nakajima\n\n    - title: \"Lightning Talk: I Hate ORMs\"\n      start_cue: \"02:25\"\n      end_cue: \"06:00\"\n      id: \"mat-brown-lightning-talk-goruco-2010\"\n      video_id: \"mat-brown-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Mat Brown\n\n    - title: \"Lightning Talk: OHM Object Hash Mapper\"\n      start_cue: \"06:00\"\n      end_cue: \"09:40\"\n      id: \"michael-bernstein-lightning-talk-goruco-2010\"\n      video_id: \"michael-bernstein-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Bernstein\n\n    - title: \"Lightning Talk: Jim\"\n      start_cue: \"09:40\"\n      end_cue: \"14:25\"\n      id: \"aaron-quint-lightning-talk-goruco-2010\"\n      video_id: \"aaron-quint-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Aaron Quint\n\n    - title: \"Lightning Talk: New Rubyists SIG\"\n      start_cue: \"14:25\"\n      end_cue: \"15:35\"\n      id: \"malcom-arnold-lightning-talk-goruco-2010\"\n      video_id: \"malcom-arnold-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Malcom Arnold\n\n    - title: \"Lightning Talk: The Right Framework For You\"\n      start_cue: \"15:35\"\n      end_cue: \"19:20\"\n      id: \"tom-mornini-lightning-talk-goruco-2010\"\n      video_id: \"tom-mornini-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Tom Mornini\n\n    - title: \"Lightning Talk: RVM\"\n      start_cue: \"19:20\"\n      end_cue: \"22:15\"\n      id: \"michael-o-brien-lightning-talk-goruco-2010\"\n      video_id: \"michael-o-brien-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael O'Brien\n\n    - title: \"Lightning Talk: Disruption\"\n      start_cue: \"22:15\"\n      end_cue: \"25:55\"\n      id: \"ben-woosley-lightning-talk-goruco-2010\"\n      video_id: \"ben-woosley-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Ben Woosley\n\n    - title: \"Lightning Talk: Cloud Storage\"\n      start_cue: \"25:55\"\n      end_cue: \"31:20\"\n      id: \"james-macaulay-lightning-talk-goruco-2010\"\n      video_id: \"james-macaulay-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - James MacAulay\n\n    - title: \"Lightning Talk: Open Data\"\n      start_cue: \"31:20\"\n      end_cue: \"35:15\"\n      id: \"edward-ocampo-gooding-lightning-talk-goruco-2010\"\n      video_id: \"edward-ocampo-gooding-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Edward Ocampo-Gooding\n\n    - title: \"Lightning Talk: Integration Test Harnesses\"\n      start_cue: \"35:15\"\n      end_cue: \"38:10\"\n      id: \"dan-wellman-lightning-talk-goruco-2010\"\n      video_id: \"dan-wellman-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Dan Wellman\n\n    - title: \"Lightning Talk: I Got Trolled\"\n      start_cue: \"38:10\"\n      id: \"mark-menard-lightning-talk-goruco-2010\"\n      video_id: \"mark-menard-lightning-talk-goruco-2010\"\n      video_provider: \"parent\"\n      speakers:\n        - Mark Menard\n"
  },
  {
    "path": "data/goruco/goruco-2011/event.yml",
    "content": "---\nid: \"goruco-2011\"\ntitle: \"GORUCO 2011\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  The Premier New York City Ruby Conference.\npublished_at: \"2011-06-04\"\nstart_date: \"2011-06-04\"\nend_date: \"2011-06-04\"\nyear: 2011\nbanner_background: \"#F7F7F7\"\nfeatured_background: \"#F7F7F7\"\nfeatured_color: \"#242022\"\nwebsite: \"https://2011.goruco.com\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2011/schedule.yml",
    "content": "# Schedule: http://2011.goruco.com/schedule/\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2011-06-04\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Registration and breakfast\n\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening Remarks\n\n      - start_time: \"10:00\"\n        end_time: \"10:55\"\n        slots: 1\n\n      - start_time: \"10:55\"\n        end_time: \"11:50\"\n        slots: 1\n\n      - start_time: \"11:50\"\n        end_time: \"12:35\"\n        slots: 1\n\n      - start_time: \"12:35\"\n        end_time: \"13:45\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:45\"\n        end_time: \"14:40\"\n        slots: 1\n\n      - start_time: \"14:40\"\n        end_time: \"15:25\"\n        slots: 1\n\n      - start_time: \"15:25\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:45\"\n        end_time: \"16:40\"\n        slots: 1\n\n      - start_time: \"16:40\"\n        end_time: \"17:35\"\n        slots: 1\n\n      - start_time: \"17:35\"\n        end_time: \"18:30\"\n        slots: 1\n\n      - start_time: \"18:30\"\n        end_time: \"18:35\"\n        slots: 1\n        items:\n          - title: \"Recorded separately\"\n            description: |-\n              Jeff Casimir was unable to present at the conference but recorded the talk shortly afterwards.\n\n      # Jeff Casimir's talk, recorded shortly after the conference\n      - start_time: \"18:35\"\n        end_time: \"19:15\"\n        slots: 1\n"
  },
  {
    "path": "data/goruco/goruco-2011/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Engine Yard\"\n          website: \"https://www.engineyard.com/\"\n          slug: \"engine-yard\"\n          logo_url: \"https://2011.goruco.com/images/content/engine-yard.png\"\n\n    - name: \"Gold Sponsors\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Bluebox\"\n          website: \"http://bluebox.net\"\n          slug: \"bluebox\"\n          logo_url: \"https://2011.goruco.com/images/content/box.png\"\n\n    - name: \"Silver Sponsors\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"Efficiency 2.0\"\n          website: \"http://efficiency20.com\"\n          slug: \"efficiency-20\"\n          logo_url: \"https://2011.goruco.com/images/content/eff.png\"\n\n        - name: \"Pivotal Labs\"\n          website: \"http://pivotallabs.com\"\n          slug: \"pivotal-labs\"\n          logo_url: \"https://2011.goruco.com/images/content/pivotal.png\"\n\n        - name: \"Heroku\"\n          website: \"https://www.heroku.com/\"\n          slug: \"Heroku\"\n          logo_url: \"https://2011.goruco.com/images/content/heroku.png\"\n"
  },
  {
    "path": "data/goruco/goruco-2011/venue.yml",
    "content": "---\nname: \"Pace University\"\naddress:\n  street: \"1 Pace Plaza\"\n  city: \"New York\"\n  region: \"NY\"\n  postal_code: \"10038\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"1 Pace Plaza, New York, NY 10038\"\ncoordinates:\n  latitude: 40.7112\n  longitude: -74.0042\nmaps:\n  google: \"https://maps.app.goo.gl/6vQWxbP5jFbTbmYr5\"\n"
  },
  {
    "path": "data/goruco/goruco-2011/videos.yml",
    "content": "---\n# Website: http://2011.goruco.com/schedule/\n\n- id: \"ryan-smith-goruco-2011\"\n  title: \"Fewer Constraints More Concurrency\"\n  raw_title: \"GORUCO 2011: Fewer Constraints More Concurrency (Ryan Smith)\"\n  speakers:\n    - Ryan Smith\n  event_name: \"GORUCO 2011\"\n  date: \"2011-06-04\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2011: Fewer Constraints More Concurrency (Ryan Smith)\n  video_provider: \"youtube\"\n  video_id: \"Hgx0FxEr7EY\"\n\n- id: \"sandi-metz-goruco-2011\"\n  title: \"Less - The Path to Better Design\"\n  raw_title: \"GORUCO 2011: Less - The Path to Better Design (Sandi Metz)\"\n  speakers:\n    - Sandi Metz\n  event_name: \"GORUCO 2011\"\n  date: \"2011-06-04\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2011: Less - The Path to Better Design (Sandi Metz)\n  video_provider: \"youtube\"\n  video_id: \"X8ergNY2pgc\"\n\n- id: \"paul-dix-goruco-2011\"\n  title: \"Indexing Thousands of Writes Per Second With Redis\"\n  raw_title: \"GORUCO 2011: Indexing Thousands of Writes Per Second With Redis (Paul Dix)\"\n  speakers:\n    - Paul Dix\n  event_name: \"GORUCO 2011\"\n  date: \"2011-06-04\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2011: Indexing Thousands of Writes Per Second With Redis (Paul Dix)\n  video_provider: \"youtube\"\n  video_id: \"sZoBNH-EHoc\"\n\n- id: \"casey-rosenthal-goruco-2011\"\n  title: \"HysteriaEngine - Ruby Does Violence in the Name of Science\"\n  raw_title: \"GORUCO 2011: HysteriaEngine - Ruby Does Violence in the Name of Science (Casey Rosenthal)\"\n  speakers:\n    - Casey Rosenthal\n  event_name: \"GORUCO 2011\"\n  date: \"2011-06-04\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2011: HysteriaEngine - Ruby Does Violence in the Name of Science (Casey Rosenthal)\n  video_provider: \"youtube\"\n  video_id: \"e3MI_Ak85vM\"\n\n- id: \"jeremy-ashkenas-goruco-2011\"\n  title: \"CoffeeScript for the Well-Rounded Rubyist\"\n  raw_title: \"GORUCO 2011: Coffeescript For the Well Rounded Rubyist (Jeremy Ashkenas)\"\n  speakers:\n    - Jeremy Ashkenas\n  event_name: \"GORUCO 2011\"\n  date: \"2011-06-04\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2011: Coffeescript For the Well Rounded Rubyist (Jeremy Ashkenas)\n  video_provider: \"youtube\"\n  video_id: \"2P2tk1bEtFM\"\n\n- id: \"john-crepezzi-mat-brown-goruco-2011\"\n  title: \"Using Your Database\"\n  raw_title: \"GORUCO 2011: Using Your Database (John Crepezzi & Mat Brown)\"\n  speakers:\n    - John Crepezzi\n    - Mat Brown\n  event_name: \"GORUCO 2011\"\n  date: \"2011-06-04\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2011: Using Your Database (John Crepezzi & Mat Brown)\n  video_provider: \"youtube\"\n  video_id: \"eSJ1lvE1dfc\"\n\n- id: \"evan-phoenix-goruco-2011\"\n  title: \"Build It and They Will Come - Rubinius Edition\"\n  raw_title: \"GORUCO 2011: Build It and They Will Come: Rubinius Edition (Evan Phoenix)\"\n  speakers:\n    - Evan Phoenix\n  event_name: \"GORUCO 2011\"\n  date: \"2011-06-04\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2011: Build It and They Will Come: Rubinius Edition (Evan Phoenix)\n  video_provider: \"youtube\"\n  video_id: \"uJzD-rk_yeQ\"\n\n- id: \"rejectconf-goruco-2011\"\n  title: \"GORUCO 2011 RejectConf\"\n  raw_title: \"GORUCO 2011: RejectConf\"\n  event_name: \"GORUCO 2011\"\n  date: \"2011-06-04\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2011: RejectConf\n  video_provider: \"youtube\"\n  video_id: \"gM1KfHFocfI\"\n  talks:\n    - title: \"Lightning Talk: Backbone JS\"\n      start_cue: \"00:25\"\n      end_cue: \"00:50\"\n      id: \"jeremy-ashkenas-lightning-talk-goruco-2011\"\n      video_id: \"jeremy-ashkenas-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeremy Ashkenas\n\n    - title: \"Lightning Talk: Fog\"\n      start_cue: \"00:50\"\n      end_cue: \"01:40\"\n      id: \"fog-lightning-talk-goruco-2011\"\n      video_id: \"fog-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing speaker name\n\n    - title: \"Lightning Talk: Community Leadership\"\n      start_cue: \"01:40\"\n      end_cue: \"06:50\"\n      id: \"gregory-brown-lightning-talk-goruco-2011\"\n      video_id: \"gregory-brown-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Gregory Brown\n\n    - title: \"Lightning Talk: Memory Monitoring\"\n      start_cue: \"06:50\"\n      end_cue: \"09:40\"\n      id: \"michael-bernstein-lightning-talk-goruco-2011\"\n      video_id: \"michael-bernstein-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Bernstein\n\n    - title: \"Lightning Talk: Rethinking BDD\"\n      start_cue: \"09:40\"\n      end_cue: \"12:50\"\n      id: \"obie-fernandez-lightning-talk-goruco-2011\"\n      video_id: \"obie-fernandez-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Obie Fernandez\n\n    - title: \"Lightning Talk: SproutCore\"\n      start_cue: \"12:50\"\n      end_cue: \"15:00\"\n      id: \"luke-melia-lightning-talk-goruco-2011\"\n      video_id: \"luke-melia-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Luke Melia\n\n    - title: \"Lightning Talk: MailCatcher / Faye\"\n      start_cue: \"15:00\"\n      end_cue: \"17:00\"\n      id: \"haris-amin-lightning-talk-goruco-2011\"\n      video_id: \"haris-amin-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Haris Amin\n\n    - title: \"Lightning Talk: Monitoring AWS Resources\"\n      start_cue: \"17:00\"\n      end_cue: \"19:10\"\n      id: \"adam-fields-lightning-talk-goruco-2011\"\n      video_id: \"adam-fields-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Fields\n\n    - title: \"Lightning Talk: Weather Underground\"\n      start_cue: \"19:10\"\n      end_cue: \"19:55\"\n      id: \"sebastian-delmont-lightning-talk-goruco-2011\"\n      video_id: \"sebastian-delmont-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Sebastian Delmont\n\n    - title: \"Lightning Talk: Canvas Pong\"\n      start_cue: \"19:55\"\n      end_cue: \"20:03\"\n      id: \"john-crepezzi-lightning-talk-goruco-2011\"\n      video_id: \"john-crepezzi-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - John Crepezzi\n\n    - title: \"Lightning Talk: Rack After Reply\"\n      start_cue: \"20:03\"\n      end_cue: \"22:23\"\n      id: \"george-ogata-lightning-talk-goruco-2011\"\n      video_id: \"george-ogata-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - George Ogata\n\n    - title: \"Lightning Talk: Chloe for Realtime Data\"\n      start_cue: \"22:23\"\n      end_cue: \"26:23\"\n      id: \"trotter-cashion-lightning-talk-goruco-2011\"\n      video_id: \"trotter-cashion-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Trotter Cashion\n\n    - title: \"Lightning Talk: JS Prototypical Inheritance\"\n      start_cue: \"26:23\"\n      end_cue: \"30:15\"\n      id: \"js-prototypical-inheritance-lightning-talk-goruco-2011\"\n      video_id: \"js-prototypical-inheritance-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing speaker name (first name \"Dave\")\n\n    - title: \"Lightning Talk: Discovery on Github\"\n      start_cue: \"30:15\"\n      end_cue: \"31:49\"\n      id: \"discovery-on-github-lightning-talk-goruco-2011\"\n      video_id: \"discovery-on-github-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing speaker name\n\n    - title: \"Lightning Talk: Lua: The Little Language\"\n      start_cue: \"31:49\"\n      end_cue: \"35:25\"\n      id: \"joshua-ballanco-lightning-talk-goruco-2011\"\n      video_id: \"joshua-ballanco-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Joshua Ballanco\n\n    - title: \"Lightning Talk: Making Slides Less Horrible\"\n      start_cue: \"35:25\"\n      id: \"shane-becker-lightning-talk-goruco-2011\"\n      video_id: \"shane-becker-lightning-talk-goruco-2011\"\n      video_provider: \"parent\"\n      speakers:\n        - Shane Becker\n\n# Jeff Casimir was unable to present at the conference but recorded the talk shortly afterwards.\n- id: \"jeff-casimir-goruco-2011\"\n  title: \"Blow Up Your Views\"\n  raw_title: \"GORUCO 2011: Blow Up Your Views (Jeff Casimir)\"\n  speakers:\n    - Jeff Casimir\n  event_name: \"GORUCO 2011\"\n  date: \"2011-06-04\"\n  published_at: \"2025-10-25\"\n  description: |-\n    GORUCO 2011: Blow Up Your Views (Jeff Casimir)\n  video_provider: \"youtube\"\n  video_id: \"KtAGInFbjo4\"\n"
  },
  {
    "path": "data/goruco/goruco-2012/event.yml",
    "content": "---\nid: \"PLFE5C32B5513E0555\"\ntitle: \"GORUCO 2012\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: \"\"\npublished_at: \"2012-06-23\"\nstart_date: \"2012-06-23\"\nend_date: \"2012-06-23\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2012\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#242424\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2012/videos.yml",
    "content": "---\n# https://web.archive.org/web/20120616005211/http://goruco.com/schedule\n\n# TODO: Missing Talk: Dr. Nic Williams - Deployment - the difference between the 1st month and the next 59\n# https://github.com/goruco/videos/blob/master/_posts/2012-05-22-nic-williams-deployment-the-difference-between-the-1st-month-and-the-next-59.md\n# https://goruco.github.io/speakers/2012/williams-nic/\n\n# Break\n\n- id: \"david-chelimsky-goruco-2012\"\n  title: \"Maintaining Balance while Reducing Duplication: Part II\"\n  raw_title: \"Maintaining Balance while Reducing Duplication: Part II by David Chelimsky,\"\n  speakers:\n    - David Chelimsky\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-07-01\"\n  description: |-\n    This talk is a sequel to the talk David gave at RubyConf 2010, and will focus on refactorings that we rely on to reduce duplication, and their implications, both positive and negative.\n  video_provider: \"youtube\"\n  video_id: \"UvlyJv0eIf8\"\n\n# Break\n\n- id: \"francis-hwang-goruco-2012\"\n  title: \"The Front-End Future\"\n  raw_title: \"The Front-End Future by Francis Hwang\"\n  speakers:\n    - Francis Hwang\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-07-01\"\n  description: |-\n    With the rise of Javascript MVC frameworks like Ember and Backbone, web programmers find themselves at a fork in the road. If they keep doing server-side web programming, they'll benefit from tried-and-true tools and techniques. If they jump into Javascript MVC, they may be able to offer a more responsive web experience, but at significant added development cost. Which should they choose?\n\n    This talk will address the strategic costs and benefits of using Javascript MVC today. I will touch on subjects such as development speed, usability, conceptual similarities with desktop and mobile applications, the decoupling of rendering and routing from server logic, and the state of the emerging Javascript MVC community. I will also discuss the impact of this seismic change on Ruby, Rails, and your career as a software engineer.\n\n  video_provider: \"youtube\"\n  video_id: \"VdDDfVFQxJc\"\n\n# Lunch\n\n- id: \"luke-melia-goruco-2012\"\n  title: \"Micro Talk: Organizing and Packaging Rich Javascript Apps with Ruby\"\n  raw_title: \"Organizing and Packaging Rich Javascript Apps with Ruby by Luke Melia\"\n  speakers:\n    - Luke Melia\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-07-01\"\n  description: |-\n    More and more developers are facing the challenge of organizing and deploying complex client-side Javascript apps. It turns out there are some excellent solutions to this problem bubbling up in the Ruby ecosystem. I am responsible for two complex Javascript applications at Yapp, and in this micro-talk, I will share a solid solution to this problem using open source Ruby projects.\n  video_provider: \"youtube\"\n  video_id: \"swi_Pa5rQfk\"\n\n- id: \"haris-amin-goruco-2012\"\n  title: \"Micro Talk: Your Face in 10 minutes... with MacRuby!\"\n  raw_title: \"Your Face in 10 minutes... with Macruby! by Haris Amin,\"\n  speakers:\n    - Haris Amin\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-07-01\"\n  description: |-\n    In this talk we will build a face detection and recognition app all in Ruby with the power of MacRuby... in 10 minutes! The purpose of this talk is to demonstrate how one can take advantage of Apple API's and Ruby tools to quickly build powerful desktop applications.\n  video_provider: \"youtube\"\n  video_id: \"Ahwb_PU5WxY\"\n\n- id: \"matt-duncan-goruco-2012\"\n  title: \"Micro Talk: High Perfmance Caching with Rails\"\n  raw_title: \"High Perfmance Caching with Rails by Matt Duncan,\"\n  speakers:\n    - Matt Duncan\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-07-01\"\n  description: |-\n    In this talk, I'll dig into how this type of caching allows us to cache far less data than traditional methods, invalidate fewer records, improve our cache hit rates, and scale to hundreds of thousands of memcache of requests per second with a 98% cache hit rate - all while showing users data differently based on perspective.\n  video_provider: \"youtube\"\n  video_id: \"8A9t9nE4kkk\"\n\n- id: \"pat-shaughnessy-goruco-2012\"\n  title: \"Micro Talk: Why Hashes Will Be Faster in Ruby 2.0\"\n  raw_title: \"Why Hashes Will Be Faster in Ruby 2.0 by Pat Shaughnessy,\"\n  speakers:\n    - Pat Shaughnessy\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-07-01\"\n  description: |-\n    In this micro talk, I'll review the basic theory behind hash functions and hash tables, show you the new internal data structures that Ruby 2.0 uses to save keys and values, and present some performance data that proves this optimization exists and how much time it will actually save you.\n  video_provider: \"youtube\"\n  video_id: \"YHULcgaATh4\"\n\n# Break\n\n- id: \"justin-leitgeb-goruco-2012\"\n  title: \"Sensible Testing\"\n  raw_title: \"Goruco 2012 Sensible Testing by Justin Leitgeb,\"\n  speakers:\n    - Justin Leitgeb\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-10-03\"\n  description: |-\n    Most Ruby programmers spend significant time writing, maintaining and troubleshooting automated tests. While recent discussions in the Ruby community have focused on whether we're writing too few or too many tests, this talk looks at how we can write \"sensible\" tests that allow our applications to deliver the most possible value with the least amount of development time and effort.\n  video_provider: \"youtube\"\n  video_id: \"huH_hiK0U_Y\"\n\n# Break\n\n# Missing Talk: Matt Wynne - Hexagonal Rails\n# https://github.com/goruco/videos/blob/master/_posts/2012-05-22-matt-wynne-hexagonal-rails.md\n# https://goruco.github.io/speakers/2012/wynne-matt/\n\n# Break\n\n- id: \"jeff-casimir-goruco-2012\"\n  title: \"Micro Talk: Building Developers Lessons Learned from Hungry Academy\"\n  raw_title: \"GoRuCo 2012 Building Developers Lessons Learned from Hungry Academy by Jeff Casimir\"\n  speakers:\n    - Jeff Casimir\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-07-01\"\n  description: |-\n    Here's the quick story of what's worked, what hasn't, and the lessons learned as we try to solve the developer shortage.\n  video_provider: \"youtube\"\n  video_id: \"O4N9_3MVAcs\"\n\n- id: \"daniel-doubrovkine-goruco-2012\"\n  title: \"Micro Talk: From Zero to API Cache w Grape & MongoDB in 10 minutes\"\n  raw_title: \"GoRuCo 2012 From Zero to API Cache w Grape & MongoDB in 10 minutes by Daniel Doubrovkine\"\n  speakers:\n    - Daniel Doubrovkine\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-07-01\"\n  description: |-\n    We'll take a Grape API from zero to cache in 10-minutes. This cookbook includes support for ETags, handling relational data, 304s, etc., based on several months of incremental development at Art.sy.\n  video_provider: \"youtube\"\n  video_id: \"e9HLflRXMcA\"\n\n- id: \"sebastian-delmont-goruco-2012\"\n  title: \"Micro Talk: Maps want to be free!\"\n  raw_title: \"GoRuCo 2012 Maps want to be free! by Sebastian Delmont,\"\n  speakers:\n    - Sebastian Delmont\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-07-01\"\n  description: |-\n    How to build your own online maps and free yourself from Google Maps limitations and fees.\n  video_provider: \"youtube\"\n  video_id: \"XMH5zJpCqBE\"\n\n# Break\n\n- id: \"jim-weirich-goruco-2012\"\n  title: \"Power Rake\"\n  raw_title: \"Goruco 2012 Power Rake by Jim Weirich,\"\n  speakers:\n    - Jim Weirich\n  event_name: \"GORUCO 2012\"\n  date: \"2012-06-23\"\n  published_at: \"2012-07-01\"\n  description: |-\n    In this talk we will cover the \"hidden\" features of Rake that are not typically used by the casual Rake user. We will learn about the convenience of file lists, dynamic generation of tasks, rule based file generation and more.\n  video_provider: \"youtube\"\n  video_id: \"KaEqZtulOus\"\n"
  },
  {
    "path": "data/goruco/goruco-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZ4RsnTOCdqgWPXtm1h_Ale\"\ntitle: \"GORUCO 2013\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: \"\"\npublished_at: \"2013-06-08\"\nstart_date: \"2013-06-08\"\nend_date: \"2013-06-08\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2013\nbanner_background: \"#1F1B1D\"\nfeatured_background: \"#1F1B1D\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://web.archive.org/web/20130622030959/http://goruco.com/\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2013/videos.yml",
    "content": "---\n# Schedule: http://goruco.github.io/news/2013/agenda/\n\n- id: \"john-pignata-goruco-2013\"\n  title: \"Asynchronous Service Oriented Design\"\n  raw_title: \"GoRuCo 2013 - Asynchronous Service Oriented Design by John Pignata\"\n  speakers:\n    - John Pignata\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-02\"\n  description: |-\n    Your monolithic application is getting unwieldy. Concerns are entangled, response time is getting sluggish, and changing anything in production requires deploying your entire system. Teams facing this challenge often have an \"Introduce Services\" chore in their backlog that inevitably sinks to the bottom of the list. Despite the realization that your monolithic application will sink under its own weight, you fear the inherent operational complexities of a service oriented system.\n    The complexity of operating services results from the reality that your system will be only as strong as the weakest dependent service. Synchronous service requests require a round-trip request and response cycle in real-time. Your system's response time now might be only as fast as your slowest service and its uptime might be only as high as your weakest service. This potential brittleness is a high barrier to entry.\n    The boundaries of our potential services are defined by their communication patterns. One path forward toward service oriented design is to first target the components of your system that communicate asynchronously. These interactions do not require a roundtrip response in real-time and instead rely on incoming messages. First focusing on services that can be addressed through delayed messages will allow us to begin to carve up our application while ensuring the operational integrity of our system.\n    In this talk we'll look at using message passing patterns when designing our service oriented systems. We'll dig into an evolving feature from being some code sprinkled throughout the app folder in our Rails application to a standalone system that's independently scalable, testable, and deployable. We'll investigate the tactics we use to slice up our monolithic application, the operations and monitoring concerns it introduces, and look at several different messaging tools and protocols along the way.\n\n  video_provider: \"youtube\"\n  video_id: \"n8QUki5jhAM\"\n\n- id: \"mike-bernstein-goruco-2013\"\n  title: \"To Know A Garbage Collector\"\n  raw_title: \"GoRuCo 2013 - To Know A Garbage Collector by Mike Bernstein\"\n  speakers:\n    - Mike Bernstein\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-02\"\n  description: |-\n    It started as an obsession with making the web application used at my day job faster, and ended with trying to implement new Garbage Collection algorithms in a notoriously insane codebase. Garbage collection is an epic hack and a triumphant abstraction that supports various programming paradigms. As hardware and software changes, Garbage Collection's role also changes but remains equally important. I'll discuss my experiments with MRI Ruby, my investigations into other languages and the influence of their GC implementations, the history of the subject, and more.\n\n  video_provider: \"youtube\"\n  video_id: \"t8dj56h2gbg\"\n\n# Morning break\n\n- id: \"jd-harrington-goruco-2013\"\n  title: \"Microtalk: Take a picture, it'll last longer\"\n  raw_title: \"GoRuCo 2013 - Microtalk: Take a picture, it'll last longer by JD Harrington\"\n  speakers:\n    - JD Harrington\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-02\"\n  description: |-\n    Cheap code branches permeate our daily workflow, but the code we write is only half the story. Introducing data model changes into production can challenge developers and ops people alike, but how do we deal with these issues in our experimental phase?\n    In this talk, we'll discuss using features provided by modern filesystems like ZFS & Btrfs to branch databases along with code, letting developers experiment and ops people model complex environments, all from the comfort of our laptops.\n\n  video_provider: \"youtube\"\n  video_id: \"K66r3yZd2_I\"\n\n- id: \"matthew-salerno-goruco-2013\"\n  title: \"Microtalk: Motion in the Middle - RubyMotion as a Gateway to iOS Development\"\n  raw_title: \"GoRuCo 2013 - Microtalk: Motion in the Middle - RubyMotion as a Gateway to iOS development\"\n  speakers:\n    - Matthew Salerno\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    By Matt Salerno\n\n    In the past year or so, RubyMotion (RM) has gained its share of both adherents and skeptics. Some criticize RM for being too far removed from the underlying Cocoa frameworks, while others claim the toolchain isn't \"Ruby\" enough. While there is certainly merit to these conflicting objections, it is because of these supposed flaws, and not in spite of them, that RubyMotion is an excellent tool for producing iOS apps. By leveraging both the power of the Objective-C frameworks and the speed and expressiveness of Ruby (not to mention opening up the iOS ecosystem to the historically prolific open source Ruby community), RM has the potential to greatly expand the iOS developer base and change the mobile landscape for the better. In his talk, \"Motion in the Middle,\" Matthew will discuss the ways in which RubyMotion enables elegant, Ruby-esque design while exposing enough of the iOS/Cocoa frameworks to allow for wide-ranging and highly extendable applications.\n\n  video_provider: \"youtube\"\n  video_id: \"MliQDCrTsNU\"\n\n- id: \"emily-stolfo-goruco-2013\"\n  title: \"Microtalk: Hacking the Academic Experience\"\n  raw_title: \"GoRuCo 2013 - Microtalk: Hacking the Academic Experience by Emily Stolfo\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    When I was asked to teach Ruby on Rails at Columbia University I observed that a significant number of the skills required to become a successful professional in the industry are acquired on the job and aren't being taught in school. Many of us professionals thrive on open source software and on sharing code, but academia is not always teaching this type of resourcefulness to students.\n    This presentation will cover lessons learned from the experience teaching in my alma mater's CS program, how I developed a hacker-centric curriculum, and how we as hackers can fix this.\n\n  video_provider: \"youtube\"\n  video_id: \"wFlOhIWflRo\"\n\n- id: \"aaron-quint-goruco-2013\"\n  title: \"Microtalk: Working with Rubyists\"\n  raw_title: \"GoRuCo 2013 Microtalk: Working with Rubyists by Aaron Quint\"\n  speakers:\n    - Aaron Quint\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    Welcome to the trials and tribulations of managing a Ruby team. Let me introduce you to the characters, the challenges, the high stakes rat race. I'll share as fast as possible, what I've learned and what I failed at and why management shouldnt be an evil word.\n\n  video_provider: \"youtube\"\n  video_id: \"GPGm5PNzNIA\"\n\n# Lunch\n\n- id: \"lauren-voswinkel-goruco-2013\"\n  title: \"Putting off Persistence\"\n  raw_title: \"GoRuCo 2013 - Putting off Persistence by Lauren Voswinkel\"\n  speakers:\n    - Lauren Voswinkel\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    In Rails, we have a beautiful framework that can take us from a blank slate to a fully-functional app in little time. However, doing things \"The Rails Way\" has a lot of implicit dependencies, including persistence. Are you really equipped to make one of the largest decisions about your app before any of your code has even been written?\n    By putting this decision off you can get a feel for your domain before ever committing anything to a db schema. This means fewer migrations and fewer db-related hacks. Also, these practices encourage encapsulation and interchangeability, which means you get the ability to choose which datastore is best for you. Not just on an application level, but on a per model level as well!\n    During the talk we'll be walking through simple examples at different points in application lifecycle. These snapshots will address the biggest pain points of a persistence free process and leave you in a position to put off persistence in your own app development!\n\n  video_provider: \"youtube\"\n  video_id: \"Bjh_p-fBb9A\"\n\n- id: \"martin-bosslet-goruco-2013\"\n  title: \"Krypt. Semper Pi.\"\n  raw_title: \"GoRuCo 2013 - Krypt. Semper Pi. by Martin Bosslet\"\n  speakers:\n    - Martin Bosslet\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    Many people don't like Cryptography. Whenever he falls out of a bar, he carries this strong odor of ivory-towering, bikeshedding and plain, outright arrogance. He seems to be a loner and a smartass, rude, and it's hard to follow his boring, lengthy explanations. But once you get to know him better, it actually turns out that he's really a nice guy. Sure, a little bit paranoid, but his intentions are pure and just. He'll probably never be your buddy on Facebook ('cause he likely won't set up an account in the first place), but over time you will realize that it can be quite pleasant having him around.\n    Krypt is the tool that tames him, and krypt is the tool that translates his sentences into plain, understandable Ruby. Gone are the times when you just couldn't figure out what parameters to use in order to please him, gone are the times when he would take your passwords and not stow them away safely because yet again he didn't fully understand what you were asking him to do. OK, this metaphor thing is getting a little old now. krypt makes using crypto fun and easy, and it works on all Rubies on all platforms (yep, Windows, too) - out of the box, no restrictions. It is about diversity - it allows you to choose from different providers that are best-suited for the particular task at hand.\n    You'll get a whirlwind tour of how krypt is different than other crypto libraries and why. You'll find out about the finer pieces of its inner workings and you might take home a few tricks that evolved while developing the native extensions that sit at the very heart of krypt. With its recent integration into JRuby, you might already be using krypt with JRuby right now without even knowing. Learn about the details and how krypt is used to simulate OpenSSL features that were not available in JRuby before. Find out more about how it can help making Ruby a safer place. krypt tries to ultimately replace the OpenSSL extension in the Ruby standard library, and with our combined effort we could actually steer the story of Ruby cryptography towards a happy ending.\n    Find out how!\n\n  video_provider: \"youtube\"\n  video_id: \"p7ap-GvnXYs\"\n\n# Afternoon break\n\n- id: \"andre-arko-goruco-2013\"\n  title: \"Deathmatch Bundler vs Rubygems.org\"\n  raw_title: \"GoRuCo 2013 - Deathmatch Bundler vs Rubygems.org by Andre Arko\"\n  speakers:\n    - Andre Arko\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    The story of the quest to make bundle install faster; in which Rubyists around the world inadvertently DDoS rubygems.org, witness its ignominious death, and vow to rebuild it from the ashes stronger than it was before. Then, a tour of the changes; why is Redis so much slower than Postgres? Marvel at the gorgeous metrics and graphs used to measure and optimize; gasp in delight as we track, live, exactly how many Heroku dynos are needed. Finally, a happy ending: today, the server responds to requests TWO ORDERS OF MAGNITUDE faster than it did before.\n\n  video_provider: \"youtube\"\n  video_id: \"4_TqAMWbzfw\"\n\n- id: \"kevin-sherus-goruco-2013\"\n  title: \"Microtalk: Building a Theme Engine w/ Ruby Mustache\"\n  raw_title: \"GoRuCo 2013 - Microtalk: Building a Theme Engine w/ Ruby Mustache\"\n  speakers:\n    - Kevin Sherus\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    By Kevin Sherus\n\n    This talk will explore the design and architecture of the VHX theme engine, which allows our filmmakers to easily create highly-customizable websites to promote and sell their movies. We'll walk through the technical and UX decisions that were made to optimize for maintainability, flexibility and future-proofing.\n    VHX themes are a blend of HTML, CSS, JavaScript and Mustache templates that are parsed by both Ruby and JavaScript. On the Ruby side, our theme engine can take advantage of server-side rendering, caching, and testability; with the JavaScript implementation we can add client-side rendering, live previewing, and enable an offline development environment for theme designers.\n    We'll show off the code involved in VHX's theme engine, advanced code editor (with live previewing through the HTML5 postMessage API), a master/child inheritance system that allows themes to be forked, and piecing it all together in a beautiful, easy-to-use interface.\n\n  video_provider: \"youtube\"\n  video_id: \"Sh3hrETMPj8\"\n\n- id: \"julie-gill-goruco-2013\"\n  title: \"Microtalk: A House of Cards - The Perils of Maintaining a 7-Year-Old Codebase\"\n  raw_title: \"GoRuCo 2013 - Microtalk:A House of Cards - The Perils of Maintaining a 7-Year-Old Codebase\"\n  speakers:\n    - Julie Gill\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    By Julie Gill\n\n    With RoR, often the focus is on how easy it is to build an application from the ground up. But, there is a whole different set of\n    challenges when working on a mature application. This talk will discuss the issues\n    discovered when peeling back the layers of a 7-year-old pile of code. In the beginning,\n    the question isn't \"How do I build this,\" but more like \"Where does this go\"\n    or \"Where is this bug coming from.\" I will discuss the sometimes-unintended\n    consequences of introducing new features, tracking down and fixing ancient bugs,\n    estimating the time a new feature will take to build given the many other peculiar\n    surprises you will uncover, and finally how not to worry about the inevitable\n    day when you will break everything. The audience will hear from a developer who\n    works with old code every day and get tips to make their future selves and successors\n    less confused, more productive, and less unintentionally destructive.\n  video_provider: \"youtube\"\n  video_id: \"A56vxCYLpk4\"\n\n- id: \"mike-dalessio-goruco-2013\"\n  title: \"Microtalk: Nokogiri - History and Future\"\n  raw_title: \"GoRuCo 2013 - Microtalk: Nokogiri - History and Future by Mike Dalessio\"\n  speakers:\n    - Mike Dalessio\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    Over the past few years, Nokogiri has slowly eclipsed older XML parsing libraries to garner nearly 10 million downloads from rubygems.org.\n    But why another XML parsing library? Isn't it boring? And what does \"nokogiri\" mean in Japanese, anyway?\n    These questions will be answered, and I'll do a brief dive into all the technologies that we use to make Nokogiri a fast, reliable and robust gem. Topics will include:\n    Origins of the project: motivation, problems and impact\n    Native C and Java extensions\n    FFI, and how to know if it's Right For You\n    Debugging tools (valgrind, perftools)\n    Packaging tools (mini_portile, rake-compiler)\n    Installation issues, and what we're doing to help\n    Feature roadmap\n\n  video_provider: \"youtube\"\n  video_id: \"qkvEjZ-mGQA\"\n\n- id: \"steve-berry-goruco-2013\"\n  title: \"Microtalk: Usability Primer in 10 Minutes Flat\"\n  raw_title: \"GoRuCo 2013 - Microtalk: Usability Primer in 10 Minutes Flat by Steve Berry\"\n  speakers:\n    - Steve Berry\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    In this talk we will go over usability heuristics for building better web experiences.\n\n  video_provider: \"youtube\"\n  video_id: \"7ml8t6uw8ho\"\n\n- id: \"pat-shaughnessy-goruco-2013\"\n  title: \"Functional Programming and Ruby\"\n  raw_title: \"GoRuCo 2013 - Functional Programming and Ruby by Pat Shaughnessy\"\n  speakers:\n    - Pat Shaughnessy\n  event_name: \"GORUCO 2013\"\n  date: \"2013-06-08\"\n  published_at: \"2013-07-03\"\n  description: |-\n    While Ruby is object oriented and imperative, it does have some features that allow for functional programming. In this talk we'll compare Haskell, a functional programming language, with Ruby while exploring these common functional patterns: higher order functions, lazy evaluation, and memoization.\n    Along the way we'll explore how Ruby works internally, find out whether it's a true functional language, and zoom in to take a close look at Ruby 2.0's implementation of the new \"Enumerator::Lazy\" feature.\n\n  video_provider: \"youtube\"\n  video_id: \"5ZjwEPupybw\"\n"
  },
  {
    "path": "data/goruco/goruco-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZj4qdxsQKW4-8KnlpoGfgf\"\ntitle: \"GORUCO 2014\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  https://web.archive.org/web/20141008055937/http://goruco.com/\npublished_at: \"2014-06-21\"\nstart_date: \"2014-06-21\"\nend_date: \"2014-06-21\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2014\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#1F1B1D\"\nwebsite: \"https://web.archive.org/web/20141008055937/http://goruco.com/\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2014/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20141008055937/http://goruco.com/\n\n- id: \"aaron-quint-goruco-2014\"\n  title: \"The Future of Ruby Performance Tooling\"\n  raw_title: \"GoRuCo 2014 - The Future of Ruby Performance Tooling by Aaron Quint\"\n  speakers:\n    - Aaron Quint\n  event_name: \"GORUCO 2014\"\n  date: \"2014-07-16\"\n  published_at: \"2014-07-16\"\n  description: |-\n    It's just a fact that as a baseline, Ruby is not the fastest language or platform out there. We've always been comfortable with the trade of raw speed for the thrill and happiness of development.\n\n    We can however, be completely left in the dark when an application is in production and needs to grow to meet the requests of a very demanding audience. Ruby 2.1 has begun to provide hope for the future of Ruby, especially large production Ruby applications, by exposing new features and hooks for debugging performance problems. Though Ruby hasn't become as fast as other dynamic languages (yet) at least now we can build and use some of these new tools to make our applications as fast as possible.\n\n    I'd like to share an overview of these new features as well as some tooling and problems we've faced at Paperless Post as we've scaled, and how we've tried to use Ruby to solve them.\n\n    I'm extremely excited about the potential of Ruby 2.1, not just the tools it exposes, but what it means for the future of Ruby performance tooling. Now that there are a number of people working on Ruby who are concerned about its speed and performance visibility, these tools are only going to get better. I'd like to introduce the new Ruby features, then walk through some custom performance tooling we've been working on through real world examples.\n\n    (Some) of the topics I'd like to cover:\n\n        Brief overview of new Generational GC\n        Object Space dumps\n        Analyzing Object Space dumps\n        Using the object allocation maps\n        Rblineprof and ppprofiler\n        StackProf\n        rbtrace and attaching to a Unicorn\n\n    I'll also give a sneak preview of some tools we've been working on that are not Open Source (yet) which I'd like to share.\n\n  video_provider: \"youtube\"\n  video_id: \"cOaVIeX6qGg\"\n\n# Micro Break\n\n- id: \"lisa-larson-kelley-goruco-2014\"\n  title: \"Real-time Communication for Everyone with WebRTC\"\n  raw_title: \"GoRuCo 2014 - Real-Time Communication for Everyone by Lisa Larson-Kelley\"\n  speakers:\n    - Lisa Larson-Kelley\n  event_name: \"GORUCO 2014\"\n  date: \"2014-06-21\"\n  description: |-\n    WebRTC is a powerful open-source project that seamlessly enables real-time communication (RTC)-- baked right into modern web browsers. This means web developers can now incorporate video, voice and data sharing using peer-to-peer connectivity via simple JavaScript APIs, with no plugins or additional installs required.\n\n    In this session, Lisa Larson-Kelley introduces the fundamentals of WebRTC, explaining its elements and capabilities in easy-to-understand terms, and walks through a simple 'hello world' application using the WebRTC API and open source libraries. With over 10 years of experience with real-time communication apps, Lisa shares her perspective and enthusiasm for RTC -- you'll leave wanting to create your own innovative apps with this rapidly evolving technology that is poised revolutionize how we communicate on the web.\n\n  video_provider: \"youtube\"\n  video_id: \"ALmKhif7yo0\"\n  published_at: \"2014-07-15\"\n\n# Morning Break\n\n- id: \"michael-bernstein-goruco-2014\"\n  title: \"Know Your Types - Bringing Static Types to Dynamic Languages\"\n  raw_title: \"GoRuCo 2014 - Know Your Types - Bringing Static Types to Dynamic Languages by Michael Bernstein\"\n  speakers:\n    - Michael Bernstein\n  event_name: \"GORUCO 2014\"\n  date: \"2014-06-21\"\n  description: |-\n    After several years of being a professional programmer, I realized that I didn't really know what I was doing, and decided to teach myself Computer Science. After spending a year learning Computer Science from the ground up, I thought I was starting to understand things. Then I came across Haskell.\n\n    It fascinated and frustrated me, and I wanted to understand how types worked. I also began wondering - why doesn't Ruby have a modern type system? Do we need one? Do we want one? How would it work?\n\n    I ended up coming across three amazing pieces of writing that helped illuminate things for me:\n\n        \"Types and Programming Languages\" by Benjamin C. Pierce\n        \"Propositions as Types\" by Philip Wadler\n        \"A Practical Optional Type System for Clojure\" - Ambrose Bonnaire-Sergeant\n\n    After studying these works, I still can't write Haskell, but I do understand a lot more about what types are. In the course of my research, I also came across two fascinating projects - a static type checker for Ruby, and a type inferencer for Ruby, both experimental projects from the University of Maryland's Programming Languages lab (PLUM). These provocative projects helped me understand how static types could be integrated into dynamically typed languages. While they aren't practical implementations, they made me think. Which is what I'd like to make you do during this talk - think about types, how they could help us, and what we sacrifice by not having an expressive type system in Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"_HM8Vczybj4\"\n  published_at: \"2014-07-15\"\n\n# Micro Break\n\n- id: \"andrew-turley-goruco-2014\"\n  title: \"What We Can Learn From COBOL\"\n  raw_title: \"GoRuCo 2014 - What We Can Learn From COBOL by Andrew Turley\"\n  speakers:\n    - Andrew Turley\n  event_name: \"GORUCO 2014\"\n  date: \"2014-06-21\"\n  description: |-\n    COBOL was originally conceived as a programming language for building business applications. At the time this primarily meant processing large amounts of data and transforming it into useful information (commonly known at ETL). Interest in this kind of programming waned as the personal computing revolution swept through the industry, but it is waxing with the new focus on data science and \"big data\".\n\n  video_provider: \"youtube\"\n  video_id: \"sB9_hVO9Cik\"\n  published_at: \"2014-07-15\"\n\n- id: \"audrey-troutt-goruco-2014\"\n  title: \"Teaching Kids to Code on Raspberry Pi\"\n  raw_title: \"GoRuCo 2014 - Teaching Kids to Code on Raspberry Pi by Audrey Troutt\"\n  speakers:\n    - Audrey Troutt\n  event_name: \"GORUCO 2014\"\n  date: \"2014-06-21\"\n  description: |-\n    Back in September 2013 I taught a class of 12 middle-school aged girls to write code in Scratch on the Raspberry Pi and program simple electronic circuits. This was a workshop for the Philadelphia non-profit TechGirlz.\n\n    I created 5 structured activities using Scratch and simple electronics that covered both good programming principles and the basics of electronic circuits. https://github.com/atroutt/scratch-pi\n\n    I will be sharing these structured projects as a template for other beginner workshops, and talk about what I learned by building and teaching this workshop.\n    I'll cover\n\n        What can be effectively covered in a day?\n        How can you setup a workshop up to maximize fun and learning on the day\n        Demos of some of the best projects!\n\n  video_provider: \"youtube\"\n  video_id: \"E8xCgOjnZZY\"\n  published_at: \"2014-07-15\"\n  additional_resources:\n    - name: \"atroutt/scratch-pi\"\n      type: \"repo\"\n      url: \"https://github.com/atroutt/scratch-pi\"\n\n- id: \"solomon-kahn-goruco-2014\"\n  title: \"BI Tooling with Rails\"\n  raw_title: \"GoRuCo 2014 - BI Tooling with Rails by Kahn Solomon\"\n  speakers:\n    - Solomon Kahn\n  event_name: \"GORUCO 2014\"\n  date: \"2014-07-16\"\n  published_at: \"2014-07-16\"\n  description: |-\n    Non-technical people in companies need data, but don't have the programming skills to get it themselves. So, it becomes your part-time job to get them data. As your company grows, this problem only gets worse.\n\n    We built a (soon to be released as open source) Ruby on Rails app that has completely transformed the way non-technical people at Paperless Post access data. With this 'simple' rails app, we are able to offer sophisticated, on demand, realtime reporting, that takes almost no developer time.\n\n    The intended audience is anyone who works at a company with ten or more people, where it starts to becomes very painful that non-technical people don't have access to data.\n\n    I'll go over why the current solutions (often getting a developer to run a database query / lots of cronjobs) don't solve this problem well, and how their shortcomings become incredibly painful as an organization grows.\n\n    Then, I'll show the tool we built at Paperless Post, which does a really great job solving this problem. It uses some not-commonly-used features of ActiveRecord and erb to take this complicated problem and solve it elegantly.\n\n    To say this app has made life better at Paperless Post would be an understatement. At the end of the talk, I hope attendees can go back to their companies, implement our tool, and bring more joy and happiness into their lives.\n\n    Here's a step by step outline of the talk:\n\n        The Problem\n        How Most Companies Try To Solve It\n        How Activerecord & erb Create a Better Solution\n        Going Through The Code\n        Dashboards, Visualizations and Complex Reports\n        Deploying The Application\n        The Social & Political Benefits Within Your Company\n\n  video_provider: \"youtube\"\n  video_id: \"Xbn6SZ6TJpE\"\n\n# Lunch\n\n- id: \"chris-hunt-goruco-2014\"\n  title: \"Secrets of a World Memory Champion\"\n  raw_title: \"GoRuCo 2014 - Secrets of a World Memory Champion by Chris Hunt\"\n  speakers:\n    - Chris Hunt\n  event_name: \"GORUCO 2014\"\n  date: \"2014-06-21\"\n  description: |-\n    You don't have a bad memory, you were just never taught how to use it. We are going to practice several powerful memory techniques that have been perfected by memory contest champions over the last hundred years.\n\n    By the end of this talk, you will know how to quickly memorize a foreign language, driving directions, phone conversations, the entire Chuck Norris filmography, your friend's credit card number, a shuffled deck of playing cards, and the name of every person you meet at GORUCO.\n\n  video_provider: \"youtube\"\n  video_id: \"k44oJ961eFM\"\n  published_at: \"2014-07-15\"\n\n# Micro Break\n\n- id: \"luke-melia-goruco-2014\"\n  title: \"Growing a Tech Community\"\n  raw_title: \"GoRuCo 2014 - Growing a Tech Community by Luke Melia\"\n  speakers:\n    - Luke Melia\n  event_name: \"GORUCO 2014\"\n  date: \"2014-07-16\"\n  published_at: \"2014-07-16\"\n  description: |-\n    For the last two years, I've been growing the Ember.js community in NYC from nearly nothing to a vibrant group. Most of what works well for me are things that I learned from getting my sea legs in the Ruby community, so what better place to share than GORUCO?\n\n    In this talk, we'll cover the keys to fostering a strong local community, and why it's worth doing. From simple hacks to simple human truths, this talk aims to be pragmatic for tech community organizers and inspire everyone to get involved.\n\n  video_provider: \"youtube\"\n  video_id: \"23MsBL3kEHk\"\n\n- id: \"nathan-artz-goruco-2014\"\n  title: \"An Approach to Developing and Testing Third Party JavaScript Widgets\"\n  raw_title: \"GoRuCo 2014 - An Approach to Developing and Testing Third Party JavaScript Widgets by Nathan Artz\"\n  speakers:\n    - Nathan Artz\n  event_name: \"GORUCO 2014\"\n  date: \"2014-06-21\"\n  description: |-\n    Google Analytics, Like Buttons, Twitter Widgets, Olark chat boxes; all examples of third party JavaScript elements that are embedded by users in their websites.\n\n    Testing third party code once embedded in a page, is often difficult and cumbersome. Verifying those elements are working properly (or even more basically, are not breaking the page) is difficult to get right. Clients will often not give you access to their page, or allow you to debug 'live', leaving scope for bugs to creep in.\n\n    Complicating matters further, other JavaScripts are often competing to execute on the page (sometimes erroring out), and then you have to make this all work cross-browser!\n    So what is the right approach to take?\n\n    I will show you how using a Ruby script to generate and minify my JavaScript, and a Node.js proxy server to intercept responses, I am able to safely inject my JavaScript into the page.\n\n    In addition to this, I will show you ways to use Rspec/Capybara to come run regression tests that utilize the proxy, and test my JavaScript while it is live embedded on client pages.\n\n  video_provider: \"youtube\"\n  video_id: \"QmesIibMULY\"\n  published_at: \"2014-07-15\"\n\n- id: \"samantha-john-goruco-2014\"\n  title: \"Designing a Better Programmer Community\"\n  raw_title: \"GoRuCo 2014 - Designing a Better Programmer Community by Samantha John & Jason Brennan\"\n  speakers:\n    - Samantha John\n    - Jason Brennan\n  event_name: \"GORUCO 2014\"\n  date: \"2014-06-21\"\n  description: |-\n    We will show how new approaches to language design create a better programming community.\n\n    Traditionally, programming communities have been dominated by a certain type. Programmers tend to be analytical thinkers who don't mind banging their heads against errors all day long. New, more inclusive languages make programming attractive to a wider audience who wouldn't normally have considered it (and don't particularly enjoy error messages).\n\n    In this talk we will share our learnings from designing a programming language for kids. We'll talk about the tradeoffs between simplicity and power and how we found the optimal balance for our audience. We hope others can learn from our design principles to create more languages and platforms to bring the joy of programming to everybody.\n\n  video_provider: \"youtube\"\n  video_id: \"mtdaNlYyRCs\"\n  published_at: \"2014-07-15\"\n\n# Afternoon break\n\n- id: \"michael-may-goruco-2014\"\n  title: \"Edge Caching Dynamic Rails Apps\"\n  raw_title: \"GoRuCo 2014 - Edge Caching Dynamic Rails Apps by Michael May\"\n  speakers:\n    - Michael May\n  event_name: \"GORUCO 2014\"\n  date: \"2014-06-21\"\n  description: |-\n    Your rails app is slow. Even after memory caching, optimizing queries, and adding servers the problem persists, killing your user experience. You've heard of services called \"Content Delivery Networks\" (CDNs), that could help, but they only seem to work with static content. Worry not, for there is a solution: dynamic content caching at the edge. In this talk, we explain how CDNs can be used to accelerate dynamic rails applications.\n    We will cover:\n\n        What is Caching?\n        What are CDNs?\n        What is Dynamic Caching?\n        Instant Purging\n        Surrogate-Control headers\n        Key Based Purging\n        A Rails Plugin for dynamic caching integration\n\n    You'll leave with:\n\n    A deep understanding of how caching and content delivery networks actually work. Understand recent innovations in CDN technology; things that enable edge caching dynamic content. Understand how rails plugins can be used to easily add dynamic edge caching functionality to your app. Gain insight into how to hook things into rails with plugins.\n\n  video_provider: \"youtube\"\n  video_id: \"60rjetFNA_Q\"\n  published_at: \"2014-07-15\"\n\n# Break\n\n- id: \"james-golick-goruco-2014\"\n  title: \"How to Debug Anything\"\n  raw_title: \"GoRuCo 2014 - How to Debug Anything by James Golick\"\n  speakers:\n    - James Golick\n  event_name: \"GORUCO 2014\"\n  date: \"2014-07-16\"\n  published_at: \"2014-07-16\"\n  description: |-\n    Does your code work? Probably not. The libraries you're using probably don't work either. If you're lucky, the OS does, but even then you'll probably find something wrong if you look hard enough.\n\n    Debugging is the reason that the last 20% of shipping a product usually accounts for 80% of the time. And yet, there are a million blog posts and talks about writing code, but very few about figuring out why it doesn't work right once you have.\n\n    So, how do you find bugs? In this talk I'll explore a set of tools and techniques that have helped me diagnose defects in everything from php code to malloc implementations.\n\n    One time I even used this strategy to diagnose an outage in a codebase I'd never seen that was written in a language I barely knew and a framework I'd never heard of - in less than 5 minutes. You'll walk away with this talk with everything you need to learn how to debug anything.\n\n  video_provider: \"youtube\"\n  video_id: \"VV7b7fs4VI8\"\n"
  },
  {
    "path": "data/goruco/goruco-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyb6MU6H8PratMhV4bWUL8bv\"\ntitle: \"GORUCO 2015\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  http://2015.goruco.com\npublished_at: \"2015-06-20\"\nstart_date: \"2015-06-20\"\nend_date: \"2015-06-20\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\nbanner_background: \"#4C1B22\"\nfeatured_background: \"#4C1B22\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2015.goruco.com\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2015/videos.yml",
    "content": "---\n# http://2015.goruco.com/#schedule\n\n- id: \"nadia-odunayo-goruco-2015\"\n  title: \"Keynote: Playing Games in the Clouds\"\n  raw_title: \"GORUCO 2015: Nadia Odunayo: Keynote Playing games in the clouds\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @nodunayo\n\n    What does haggling at a garage sale have to do with load balancing in distributed systems? How does bidding in an art auction relate to cloud service orchestration? Familiarity with the ideas and technologies involved in cloud computing is becoming ever more important for developers. This talk will demonstrate how you can use game theory - the study of strategic decision making - to design more efficient, and innovative, distributed systems.\n     \"Talk given at GORUCO 2015: http://goruco.com\"\n  video_provider: \"youtube\"\n  video_id: \"aHJEzIzhbf8\"\n\n# Micro Break\n\n- id: \"eileen-m-uchitelle-goruco-2015\"\n  title: \"How to Performance\"\n  raw_title: \"GORUCO 2015: Eileen Uchitelle: How to Performance\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @eileencodes\n\n    Understanding performance output can feel like reading tea leaves. It makes sense to a few people, but many of us are left in the dark; overwhelmed and frustrated by the data. On top of that there are a ton of performance tools to choose from; StackProf, RubyProf, AllocationTracer. Where do you even start? While working on speeding up integration tests in Rails source, I learned that the key to improving the performance of Ruby code is having a baseline, not relying on one profiler and understanding the advantages and limitations of your tools. By utilizing these methods, integration tests are now 3 times faster than they were in Rails 4.2.0, with more improvements being made every day. In this talk we will not only look at how to read performance output, but when and how to use the right profilers for the job. We'll discuss a variety of methods and techniques for benchmarking and profiling so you can get the most out of any performance tool.\n\n     Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"oT74HLvDo_A\"\n\n# Morning Tea\n\n- id: \"zachary-feldman-goruco-2015\"\n  title: \"Home Automation with the Amazon Echo and Ruby\"\n  raw_title: \"GORUCO 2015: Zachary Feldman: Home Automation with the Amazon Echo and Ruby\"\n  speakers:\n    - Zachary Feldman\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @zachfeldman\n    The Amazon Echo recently debuted and made a big splash with its incredibly accurate voice recognition, capable of hearing and transliterating commands from 20-30 feet away. Home automation enthusiasts and hackers alike wondered if it would be possible to intercept commands from the device and trigger custom actions. While device traffic is encrypted, the device pushes commands to a history page in a web application. Using Watir WebDriver, which normally is used for feature testing, we've created a proxy that can be run on a Raspberry Pi as well as a modular Ruby framework based on Sinatra to run custom commands, allowing us to control the Hue wireless lighting system, Nest, and even request an Uber!\n    \\\n    Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"u1guHGWD1TU\"\n\n# Micro Break\n\n- id: \"lisa-van-gelder-goruco-2015\"\n  title: \"Great Caching Disasters!\"\n  raw_title: \"GORUCO 2015: Lisa van Gelder: Great Caching Disasters!\"\n  speakers:\n    - Lisa van Gelder\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @techbint\n    Whenever something has gone seriously wrong for me in production caching has been at the root of it. Live Q&A with Julian Assange almost brought the site down? Caching fail. Servers can't cope with traffic about a new woolly rat? Caching fail. Half the site is showing sorry pages? Caching fail. This talk will use these disasters to explain why the simplest caching is always the best.\n\n     Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"tLS2z8ndDak\"\n\n- id: \"amy-wibowo-goruco-2015\"\n  title: \"Sweaters as a service\"\n  raw_title: \"GORUCO 2015: Amy Wibowo: Sweaters as a service\"\n  speakers:\n    - Amy Wibowo\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @sailorhg\n    In the 1980's, Nintendo had plans for making a knitting add-on to the NES, with an interface that resembled Mariopaint, but with patterned mittens, sweaters, and scarves as output. Sadly, this product never saw the light of day. Devastated upon hearing this and dreaming about what could have been, a group of engineers (who knew nothing about machine knitting) set out to hack a knitting machine from the 1980's to be computer-controlled, using a tutorial from adafruit as a starting point. Hear about our struggles and triumphs, which ranged from learning to replace knitting machine needles and conduct basic repairs, to emulating a floppy drive and hacking together a custom cable cable to send our own patterns to the machine, to writing our own yarn printer API in ruby/sinatra and printing our first doge meme in yarn. And watch us (LIVE!) as we send images and knit requests to our yarn server, and behold as it knits ugly sweaters from those images!\n\n     Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"Z16dVnewZVs\"\n\n- id: \"nate-berkopec-goruco-2015\"\n  title: \"Rails 5, Turbolinks 3, and the future of View-Over-the-Wire\"\n  raw_title: \"GORUCO 2015: Nate Berkopec: Rails 5, Turbolinks 3, and the future of View-Over-the-Wire\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @nateberkopec\n    With Rails 5, Turbolinks is getting a nice upgrade, with new features like partial replacement and a progress bar with a public API. This talk will demonstrate how Rails 5 Turbolinks can achieve sub-100ms UI response times, and demonstrate some tools to help you get there.\n\n     Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"eBccDerJPJE\"\n\n# Lunch\n\n- id: \"godfrey-chan-goruco-2015\"\n  title: \"Dropping down to The Metal™\"\n  raw_title: \"GORUCO 2015: Godfrey Chan: Dropping down to The Metal™\"\n  speakers:\n    - Godfrey Chan\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @chancancode\n    As much as we love Ruby, when you need to be really close to the metal, you have no choice but to use JavaScript. This is why I developed the javascript gem to help you harness the raw power of your machines. In this talk, we will examine the Ruby tricks and black magic hidden behind this ludicrous invention. Along the way, we will learn about how Ruby internally deal with variable lookups, method calls, scoping and bindings. Together, we will push the limits of the Ruby language, taking it to places Matz never ever envisioned!\n\n     Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"90OytTY-xMo\"\n\n# Micro break\n\n- id: \"bryan-reinero-goruco-2015\"\n  title: \"Event Sourcing\"\n  raw_title: \"GORUCO 2015: Bryan Reinero: Event sourcing\"\n  speakers:\n    - Bryan Reinero\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @blimpyacht\n    Event Sourcing is powerful way to think about domain objects and transaction processing. Rather than persisting an object in it's current state, event sourcing instead writes an immutable log of deltas (domain events) to the database. from this set of events, an object's state is derived, at any point in the past, simply by replaying the event history sequentially. Event sourcing is a deceptively radical idea which challenges our contemporary notions about transaction processing, while also being a mature pattern with a long history. This talk will take a look at how event processing is used across a spectrum of use cases, including database engines and financial systems, to Google Docs hacks.\n\n     Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"dOlTRl8gJIs\"\n\n- id: \"melinda-seckington-goruco-2015\"\n  title: \"Un-Artificial Intelligence\"\n  raw_title: \"GORUCO 2015: Melinda Seckington: Un-Artificial Intelligence\"\n  speakers:\n    - Melinda Seckington\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-02\"\n  description: |-\n    @mseckington\n\n    HAL, Skynet, KITT… we've always been intrigued by artificial intelligence, but have you ever stopped to considered the un-artificial? Most developers are familiar with the basics of AI: how do you make a computer, an algorithm, a system learn something? How do you model real world problems in such a way that an artificial mind can process them? What most don't realize though is that the same principles can be applied to people. This talk looks at some of the theories behind how machines learn versus how people learn, and maps it to real life examples of how specifically our users learn their way around interfaces and how designers and developers apply learning methodologies in their day-to-day actions.\n\n    Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"7Y1Bv2BJDLs\"\n\n- id: \"rachel-warbelow-goruco-2015\"\n  title: \"Common Pitfalls of Junior Developers\"\n  raw_title: \"GORUCO 2015: Rachel Warbelow: Common pitfalls of junior developers\"\n  speakers:\n    - Rachel Warbelow\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @rwarbelow\n    The learning curve to becoming a great developer is incredibly steep, especially when starting with no background knowledge. And it's not a smooth ride, either - trying to learn tools, concepts, syntax, and best practices simultaneously will inevitably result in hiccups along the way. As a DevBootcamp alumnus, Rachel knows what it's like to go from zero to developer in a very short time frame and the challenges that journey can present. Now as an instructor at the Turing School of Software and Design, she draws on her years of experience in the classroom to employ strategies that allow her students just the right balance between hand-holding and struggling. In this talk, Rachel will share tips to help people who are just getting started with programming overcome common struggles while also sharing proven teaching techniques that will help more experienced developers become effective mentors.\n\n     Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"tYOx8mA5p2c\"\n\n# Afternoon Tea\n\n- id: \"simon-eskildsen-goruco-2015\"\n  title: \"Building and Testing Resilient Applications\"\n  raw_title: \"GORUCO 2015: Simon Eskildsen: Building and testing resilient applications\"\n  speakers:\n    - Simon Eskildsen\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @Sirupsen\n    Drives fail, databases crash, fibers get cut and unindexed queries hit production. Do you know how your application reacts to those events? Are they covered by tests? What about the failures you haven't even thought of? To avoid cascading failures applications must adopt general patterns to defend against misbehaving dependencies, including themselves. This talk covers the resiliency techniques Shopify has successfully put into production at scale, and how we write tests to ensure we don't reintroduce single points of failure. You'll walk away from this talk equipped with the tools to make your applications resilient and to better sleep at night.\n\n     Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"ev0KpoACieo\"\n\n# Break\n\n- id: \"aaron-patterson-goruco-2015\"\n  title: \"Closing Keynote: Code Required\"\n  raw_title: \"GORUCO 2015: Aaron Patterson: Closing Keynote\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @tenderlove\n\n     Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"kwkbrOwLsZY\"\n\n## Not on the schedule\n\n- id: \"kara-bernert-goruco-2015\"\n  title: \"Of Mice and Metrics\"\n  raw_title: \"GORUCO 2015: Kara Bernert: Of Mice and Metrics\"\n  speakers:\n    - Kara Bernert\n  event_name: \"GORUCO 2015\"\n  date: \"2015-06-20\"\n  published_at: \"2015-07-03\"\n  description: |-\n    @_beavz\n\n     Talk given at GORUCO 2015: http://goruco.com\n  video_provider: \"youtube\"\n  video_id: \"j5ePxpIyLa0\"\n"
  },
  {
    "path": "data/goruco/goruco-2016/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybaE0Xm_yOK8-a-WAcltv1q\"\ntitle: \"GORUCO 2016\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  https://web.archive.org/web/20160715194849/http://goruco.com/\npublished_at: \"2016-06-25\"\nstart_date: \"2016-06-25\"\nend_date: \"2016-06-25\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2016\nbanner_background: \"#CC2B43\"\nfeatured_background: \"#CC2B43\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://web.archive.org/web/20160715194849/http://goruco.com/\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2016/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20160715194849/http://goruco.com/\n\n- id: \"bryan-helmkamp-goruco-2016\"\n  title: \"Keynote: Code Quality Lessons Learned\"\n  raw_title: \"GORUCO 2016 - Keynote: Code Quality Lessons Learned Bryan Helmkamp\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    Keynote: Code Quality Lessons Learned Bryan Helmkamp\n\n    We started Code Climate with a simple hypothesis: static analysis can help developers ship better code, faster. Five years later, we analyze over 70,000 repositories each day spanning a wide variety of programming languages, and along the way we've learned a lot about code quality itself: what it means, why you want it, how you get it,and more. This talk will cover some of the more surprising insights, including what makes a code metric valuable, when unmaintainable code may be preferable, and the number one thing that prevents most developers from maintaining quality code over time.\n\n  video_provider: \"youtube\"\n  video_id: \"vcH0RBe4Eew\"\n\n- id: \"nadia-odunayo-goruco-2016\"\n  title: \"The Guest: A Guide To Code Hospitality\"\n  raw_title: \"GORUCO 2016 - The Guest: A Guide To Code Hospitality by Nadia Odunayo\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    The Guest: A Guide To Code Hospitality by Nadia Odunayo\n\n    You were living alone in the town of Ruby-on-Rails until you decided to open up your spare room to guests. Now your first visitor has booked in. Her arrival is imminent. How do you prepare? How can you make sure she has a great visit? Let’s explore the art of code hospitality — working on codebases in a way that respects your teammates and provides for their needs. By working hospitably, we can facilitate team productivity and help new members quickly feel at home.\n\n  video_provider: \"youtube\"\n  video_id: \"GUuAp6c1ylM\"\n\n- id: \"aditya-mukerjee-goruco-2016\"\n  title: \"Symmetric API Testing\"\n  raw_title: \"GORUCO 2016 - Symmetric API Testing by Aditya Mukerjee\"\n  speakers:\n    - Aditya Mukerjee\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    Symmetric API Testing by Aditya Mukerjee\n\n    When implementing REST API servers and clients, testing is critical. Symmetric API testing is a design pattern that ensures compatibility between client and server with transparent tests. Testing APIs symmetrically reduces build times and code complexity, while simultaneously improving API stability.\n\n  video_provider: \"youtube\"\n  video_id: \"6BdUV1pAWa8\"\n\n- id: \"fabio-akita-goruco-2016\"\n  title: \"Micro Talk: Pipe Operator for Ruby\"\n  raw_title: \"GORUCO 2016 - Pipe Operator for Ruby by Fabio Akita\"\n  speakers:\n    - Fabio Akita\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    Pipe Operator for Ruby by Fabio Akita\n\n    Elixir is one modern language that is introducing many Rubyists to the world of highly scalable, highly distributed, functional programming-based programming. In a more narrow scope, one language feature that many people liked is the now famous Pipe Operator . There is nothing like this in Ruby. But could there be such an operator? And if it could be done, would it be useful? I started a pet project called Chainable Methods to address just that.\n\n  video_provider: \"youtube\"\n  video_id: \"ThB2cpPsb1o\"\n\n- id: \"will-leinweber-goruco-2016\"\n  title: \"Micro Talk: Introducing the Crystal Programming Language\"\n  raw_title: \"GORUCO 2016 - Introducing the Crystal Programming Language by Will Leinweber\"\n  speakers:\n    - Will Leinweber\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    Introducing the Crystal Programming Language by Will Leinweber\n\n    Developer happiness is what brought me to Ruby in the first place. And of all the new compiled languages, Crystal is the only one that shares this value. The syntax and idioms are entirely Ruby inspired. Although Crystal looks very similar to Ruby, there are big differences between the two. Crystal is statically typed and dispatched. While there are no runtime dynamic features, the compile-time macros solve many of the same problems. In this session, we’ll take a close look at these differences as well as the similarities, and what Ruby developers can learn from this exciting language.\n\n  video_provider: \"youtube\"\n  video_id: \"oC9IknG40po\"\n\n- id: \"danielle-adams-goruco-2016\"\n  title: \"Micro Talk: Ruby Racing - Challenging Ruby Methods\"\n  raw_title: \"GORUCO 2016 - Ruby Racing: Challenging Ruby Methods Danielle Adams\"\n  speakers:\n    - Danielle Adams\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    Ruby Racing: Challenging Ruby Methods Danielle Adams\n\n    Ruby is widely-used and prides itself on \"simplicity and productivity\". But what is happening under the hood of our favorite programming language? Are there better, faster, or stronger ways to implement these methods? I'm going to take a deep, yet brief, dive into testing and optimizing some of Ruby's most popularly convenient methods.\n\n  video_provider: \"youtube\"\n  video_id: \"oKZgnntMTBM\"\n\n# Lunch\n\n- id: \"andrew-faraday-goruco-2016\"\n  title: \"Gameshow: Just A Ruby Minute\"\n  raw_title: \"GORUCO 2016 - Just A Ruby Minute by Andrew Faraday\"\n  speakers:\n    - Andrew Faraday\n    - Adam Cuppy\n    - Kinsey Ann Durham\n    - Nadia Odunayo\n    - Stephen Schor\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    Just A Ruby Minute by Andrew Faraday\n\n    Just a Minute the popular classic British gameshow format with some real coding and technology topics. The rules of the game are simple, the results are hilarious, and who knows, you might even learn something new! Come join us to see some of your favorite speakers take the challenge to speak without hesitation, repetition or deviation for one minute.\n\n  video_provider: \"youtube\"\n  video_id: \"RhtITcsM2UE\"\n\n- id: \"kinsey-ann-durham-goruco-2016\"\n  title: \"Micro Talk: Impactful Refactors - Refactoring for Readability\"\n  raw_title: \"GORUCO 2016 - Impactful Refactors: Refactoring for Readability by Kinsey Ann Durham\"\n  speakers:\n    - Kinsey Ann Durham\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    Impactful Refactors: Refactoring for Readability by Kinsey Ann Durham\n\n    We have no problem justifying a refactoring effort when it improves performance or eliminates a code smell. What if I told you there's a way your refactoring could be even more impactful? One of the most costly and time-consuming things we do is on boarding. It takes an incredible amount of effort to bring a developer up to speed on a new codebase. In this talk, we’ll see three real-world readability refactors, discuss how you can apply these techniques for the benefit of your current (and future) team members, and how we can continue to program with empathy in mind.\n\n  video_provider: \"youtube\"\n  video_id: \"T4reLGtp4fA\"\n\n- id: \"rocio-delgado-goruco-2016\"\n  title: \"Micro Talk: Database Performance at Scale for RoR Applications\"\n  raw_title: \"GORUCO 2016 - Database Performance at Scale for RoR Applications by Rocio Delgado\"\n  speakers:\n    - Rocio Delgado\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    Database Performance at Scale for RoR Applications by Rocio Delgado\n\n    We love Ruby on Rails because we can get a working prototype up and running in a very short period of time. It follows coding conventions that make it simple to go from one developer to the next, however, when the application scales to a certain point, there are some performance penalties that come from the auto-magic of Active Record. I intend to show the common pitfalls for performance degradation, monitoring tools to help identify problems and common solutions including MySQL indexing optimization, all this based on my current experience with one of the biggest RoR apps working at GitHub.\n\n  video_provider: \"youtube\"\n  video_id: \"01SISs0ni1o\"\n\n- id: \"ross-kaffenberger-goruco-2016\"\n  title: \"Micro Talk: Enumerable's Ugly Cousin\"\n  raw_title: \"GORUCO 2016 -  Enumerable's Ugly Cousin by Ross Kaffenberger\"\n  speakers:\n    - Ross Kaffenberger\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    Enumerable's Ugly Cousin by Ross Kaffenberger\n\n    Everyone loves Ruby's Enumerable module. What about Enumerator? Many of us don't what Enumerator is or why it's useful. It's time to change that. We'll challenge conventions and (finally?) understand why Enumerator is important while unveiling the 'magic' of how it works.\n\n  video_provider: \"youtube\"\n  video_id: \"D2E7t19pG0E\"\n\n- id: \"aja-hammerly-goruco-2016\"\n  title: \"Exploring Big Data with rubygems.org Download Data\"\n  raw_title: \"GORUCO 2016 - Exploring Big Data with rubygems.org Download Data by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  slides_url: \"https://thagomizer.com/files/GoRuCo2016.pdf\"\n  description: |-\n    Exploring Big Data with rubygems.org Download Data by Aja Hammerly\n\n    Many people strive to be armchair data scientists. Google BigQuery provides an easy way for anyone with basic SQL knowledge to dig into large data sets and just explore. Using the rubygems.org download data we'll see how the Ruby and SQL you already know can help you parse, upload, and analyze multiple gigabytes of data quickly and easily without any previous Big Data experience.\n\n  video_provider: \"youtube\"\n  video_id: \"0mzNNg62_kM\"\n\n- id: \"adam-cuppy-goruco-2016\"\n  title: \"Keynote: Cult(ure) by Adam Cuppy\"\n  raw_title: \"GORUCO 2016 - Keynote: Cult(ure) by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"GORUCO 2016\"\n  date: \"2016-06-25\"\n  published_at: \"2016-07-08\"\n  description: |-\n    Keynote: Cult(ure) by Adam Cuppy\n\n    As a team leader, the line between company culture and a dogmatic cult is thin. Embracing individuality, yet finding alignment (as a collective) is tough. Understanding what defines one over another is critical so everyone can bring 100% of themselves to table. If you're a member of a team, leader of a team or building a team, you're going to know five key components to assess, support and foster a 'culture of diverse talent' and prevent a 'cult of conformity.'\n\n  video_provider: \"youtube\"\n  video_id: \"ChVSV9vCs4Y\"\n"
  },
  {
    "path": "data/goruco/goruco-2017/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybxOnh9S9Hk-RDRXZRkrWwR\"\ntitle: \"GORUCO 2017\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  http://2017.goruco.com\nstart_date: \"2017-06-24\"\nend_date: \"2017-06-24\"\npublished_at: \"2017-06-24\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2017\nbanner_background: \"#1F014A\"\nfeatured_background: \"linear-gradient(to top, #1F014A, #D5018F)\"\nfeatured_color: \"#F5AC9F\"\nwebsite: \"https://2017.goruco.com\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2017/videos.yml",
    "content": "---\n# Website: http://2017.goruco.com/#schedule\n\n- id: \"liz-baillie-goruco-2017\"\n  title: \"The Rubyist's Illustrated Rust Adventure Survival Guide\"\n  raw_title: \"GORUCO 2017: The Rubyist's Illustrated Rust Adventure Survival Guide by Liz Baillie\"\n  speakers:\n    - Liz Baillie\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    The Rubyist's Illustrated Rust Adventure Survival Guide by Liz Baillie\n\n    Programming is an adventure, often more harrowing than it has to be. If you're more used to higher-level languages like Ruby or JavaScript, learning a lower-level language like Rust can feel like an impossible journey that leaves you wishing for a well-written and heavily illustrated field guide. Good news! I have already gone down this road and am now prepared to share my adventure with you. Luckily, I was able to capture much of the flora and fauna of Rustlandia with my primitive pictorial devices (paper and pen).\n  video_provider: \"youtube\"\n  video_id: \"CrqsXO_4Za8\"\n\n- id: \"brooks-swinnerton-goruco-2017\"\n  title: \"Optimizing for API Consumers with GraphQL\"\n  raw_title: \"GORUCO 2017: Optimizing for API Consumers with GraphQL by Brooks Swinnerton\"\n  speakers:\n    - Brooks Swinnerton\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    Optimizing for API Consumers with GraphQL by Brooks Swinnerton\n\n    GraphQL is an exciting new query language that's transforming the way we think about APIs. Used in production by Facebook, GitHub, and Shopify, it challenges RESTful API design by empowering consumers to query for exactly the information they need. In this talk, I will give an introduction to the query language, how GitHub uses it internally with Ruby and Rails, and the lessons they learned launching their GraphQL API externally.\n  video_provider: \"youtube\"\n  video_id: \"psPnEUAL08w\"\n\n- id: \"rebecca-miller-webster-goruco-2017\"\n  title: \"Trust and Teams\"\n  raw_title: \"GORUCO 2017: Trust and Teams by Rebecca Miller-Webster\"\n  speakers:\n    - Rebecca Miller-Webster\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    Trust and Teams by Rebecca Miller-Webster\n\n    Trust is at the core of whether we are happy at work or not. Trust is at the core of whether we like who we work with. Trust is at the core of whether people perceive us to be good at our jobs. But what is trust? How do you know when it's missing? And how do you fix it when it's gone. Let's discuss the elements of trust and the patterns of behavior the make or break trust\n  video_provider: \"youtube\"\n  video_id: \"Y16EuIKYszs\"\n\n- id: \"ryan-findley-goruco-2017\"\n  title: \"Object Oriented Thinking with Elixir and OTP\"\n  raw_title: \"GORUCO 2017: Object Oriented Thinking with Elixir and OTP by Ryan Findley\"\n  speakers:\n    - Ryan Findley\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    Object Oriented Thinking with Elixir and OTP by Ryan Findley\n\n    Processes in Erlang / Elixir resemble objects in many ways. Some even argue that Erlang processes and the Actor Model are a purer form of object-orientation. The Elixir community has a large contingent of Rubyists that have extended many of the core values (and joys) of Ruby into the world of Elixir. This talk exposes some of the reasons why while providing a starting point for further learning\n  video_provider: \"youtube\"\n  video_id: \"2C_IUMYzM7A\"\n\n- id: \"pan-thomakos-goruco-2017\"\n  title: \"Developer Productivity Engineering\"\n  raw_title: \"GORUCO 2017: Developer Productivity Engineering by Pan Thomakos\"\n  speakers:\n    - Pan Thomakos\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    Developer Productivity Engineering by  Panayiotis Thomakos\n\n    Ruby is often praised for being a happy language. For highly motivated developers, a large part of happiness is tied to being productive. How can we extend the productivity gains we experience from writing Ruby to an entire engineering organization? At Strava we are experimenting with a framework we call Developer Productivity Engineering (DPE). DPE applies the principles of Site Reliability Engineering, developed by Google, to improving productivity through automation for both individual engineers and engineering organizations. This talk is a detailed view of the DPE framework and our experience with it so far.\n  video_provider: \"youtube\"\n  video_id: \"mL6kOPxuQTI\"\n\n- id: \"paul-dix-goruco-2017\"\n  title: \"SQL to NoSQL to NewSQL and the rise of polyglot persistence\"\n  raw_title: \"GORUCO 2017: SQL to NoSQL to NewSQL and the rise of polyglot persistence Paul Dix\"\n  speakers:\n    - Paul Dix\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    SQL to NoSQL to NewSQL and the rise of polyglot persistence Paul Dix\n\n    The last ten years have brought many new developments in databases. Previously developers had SQL as the dominant and nearly only paradigm for databases. Then in the mid-aughts the rise of NoSQL databases like MongoDB, Redis, Cassandra, HBase and others brought new paradigms and options to developers. Over the last few years there seems to have been a swing back to NewSQL or scalable databases that support the SQL standard. In this talk we'll look at some of the new database models like document, data structure, time series, and key/value. I'll look at use cases where these different models end up being a better fit for their problem domains than SQL, the previous one true language to rule them all.\n  video_provider: \"youtube\"\n  video_id: \"CmbbtpGW_YY\"\n\n# Lunch\n\n- id: \"adam-cuppy-goruco-2017\"\n  title: \"Difficult Conversations\"\n  raw_title: \"GORUCO 2017: Difficult Conversations by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    Difficult Conversations by Adam Cuppy\n\n    It’s never easy to have a tough conversations, and they never go away. Therefore, I see a better way to live with them, and I want everyone to hear it: empower yourself to understand why we do what we do so you can effect change. Understanding creates empathy. Empathy reduces (not eliminates) conflict. This talk is a practical course on the triad of human psychology: language, physiology and focus. I’ll walk through simple strategies that lower stress, create empathy and manage emotions.\n  video_provider: \"youtube\"\n  video_id: \"usLWMtJlBeo\"\n\n- id: \"lauren-ellsworth-goruco-2017\"\n  title: \"What I Learned to Love About Ruby When I Switched to Python\"\n  raw_title: \"GORUCO 2017: What I Learned to Love About Ruby When I Switched to Python by Lauren Ellsworth\"\n  speakers:\n    - Lauren Ellsworth\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    What I Learned to Love About Ruby When I Switched to Python by Lauren Ellsworth\n\n    When I switched from a Ruby based company to a Python based company, things I had taken for granted in my Ruby life were suddenly sorely missed, and the transition to a language with only one way to do the same thing created quite a few bumps in the road. This talks draws parallels between Ruby and Python, spotlighting which brought the most developer happiness, what I miss and love about Ruby, and what Ruby can learn from Python.\n  video_provider: \"youtube\"\n  video_id: \"GC-XIchAcqM\"\n\n- id: \"justin-gordon-goruco-2017\"\n  title: \"Front-End Sadness to Happiness: The React on Rails Story\"\n  raw_title: \"GORUCO 2017: Front-End Sadness to Happiness: The React on Rails Story by Justin Gordon\"\n  speakers:\n    - Justin Gordon\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    Front-End Sadness to Happiness: The React on Rails Story by Justin Gordon\n\n    Standard Rails development made me happy like no other programming paradigm in my career. Simple front-end development with standard Rails and a sprinkling of jQuery was 'OK' Then, in 2014, I had to build a front-end that dynamically updated like a desktop app. I knew there had to be something better, and I went down the rabbit hole of integrating React with Rails using Webpack. Come find out how my obsessive pursuit of “developer happiness” for the Rails front-end eventually drove me to start the React on Rails gem, the most popular integration of Rails with React using Webpack.\n  video_provider: \"youtube\"\n  video_id: \"SGkTvKRPYrk\"\n\n- id: \"alex-qin-goruco-2017\"\n  title: \"Shaving my head made me a better programmer\"\n  raw_title: \"GORUCO 2017: Shaving my head made me a better programmer by Alex Qin\"\n  speakers:\n    - Alex Qin\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    Shaving my head made me a better programmer by Alex Qin\n\n    How do perceptions and stereotypes affect those in software and on engineering teams? This talk tells the true story of how I hacked my appearance, by shaving my head, to change the way I was perceived as a programmer. This talk also serves as a primer on unconscious bias and stereotype threat, and their effects on individuals and teams. I will provide actionable advice on how to make engineering teams more inclusive, more diverse, and thusly more productive, successful, and attractive to potential hires.\n  video_provider: \"youtube\"\n  video_id: \"99C6CphdpTg\"\n\n- id: \"vernica-lpez-goruco-2017\"\n  title: \"Beyond OSS\"\n  raw_title: \"GORUCO 2017: Beyond OSS by Veronica Lopez\"\n  speakers:\n    - Verónica López\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    Beyond OSS by Veronica Lopez\n\n    As software engineers, we're constantly encouraged to contribute to Open Source as a means of learning and giving back to our communities. However, this vision can alienate newcomers from different backgrounds. To fight this back, in this talk I'll explain why this happens, and I will share different ideas that can lead us to foster real diversity in our communities and workplaces.\n  video_provider: \"youtube\"\n  video_id: \"NUaHcomZ8FA\"\n\n- id: \"ross-kaffenberger-goruco-2017\"\n  title: \"Scars: On Handling Adversity\"\n  raw_title: \"GORUCO 2017: Scars: On Handling Adversity by Ross Kaffenberger\"\n  speakers:\n    - Ross Kaffenberger\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    Scars: On Handling Adversity by Ross Kaffenberger\n\n    As much as we'd like our programming careers to be filled with great success, it's more than likely we'll encounter setbacks along the way. We may have to deal with impossible clients or projects, imposter syndrome, confusion, self-doubt, and maybe much worse. Perhaps there's a bright side to failure. Let's take a close look at our scars and examine how they can help make us stronger.\n  video_provider: \"youtube\"\n  video_id: \"KyylfG9lXjY\"\n\n- id: \"andrew-metcalf-goruco-2017\"\n  title: \"How to Load 1m Lines of Ruby in 5s\"\n  raw_title: \"GORUCO 2017: How to Load 1m Lines of Ruby in 5s by Andrew Metcalf\"\n  speakers:\n    - Andrew Metcalf\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    How to Load 1m Lines of Ruby in 5s by Andrew Metcalf\n\n    Applications written in Ruby, Python and several other popular dynamic languages become very slow to boot as they grow to millions of lines of code. Waiting to reload code in development becomes a major frustration and drain on productivity. This talk will discuss how we reduced the time to boot a service at Stripe from 35s to 5s by statically analyzing dependencies in our codebase to drive an autoloader.\n  video_provider: \"youtube\"\n  video_id: \"lKMOETQAdzs\"\n\n- id: \"sam-phippen-goruco-2017\"\n  title: \"Type. Context.\"\n  raw_title: \"GORUCO 2017: Type. Context. by Sam Phippen\"\n  speakers:\n    - Sam Phippen\n  event_name: \"GORUCO 2017\"\n  date: \"2017-06-24\"\n  published_at: \"2017-06-29\"\n  description: |-\n    Type. Context. by Sam Phippen\n\n    Every language has at least one big idea behind it. In Ruby we cherish the powers of abstraction in the language and the conventions of Rails. Experienced Ruby programmers lean on these ideas without a thought. Imagine my surprise when I changed jobs, stopped programming Ruby full time, and those ideas were nowhere around. This talk is the antidote to the 'x language is cool talk'; It's a talk where you'll learn about the ideas behind a couple of current hot languages. You'll learn how new languages change the way you program. We'll find some gaps in Ruby and bring some neat stuff back.\n  video_provider: \"youtube\"\n  video_id: \"qzTOnnDePtc\"\n"
  },
  {
    "path": "data/goruco/goruco-2018/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcya2z3Q5AiwNqjV968p2TvHu\"\ntitle: \"GORUCO 2018\"\nkind: \"conference\"\nlocation: \"New York, NY, United States\"\ndescription: |-\n  GORUCO is a single day, single track conference taking place on Saturday, June 16th 2018 in New York City.\nstart_date: \"2018-06-16\"\nend_date: \"2018-06-16\"\npublished_at: \"2018-06-18\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2018\nbanner_background: \"#474D58\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#474D58\"\nwebsite: \"https://goruco.com\"\ncoordinates:\n  latitude: 40.7127753\n  longitude: -74.0059728\n"
  },
  {
    "path": "data/goruco/goruco-2018/videos.yml",
    "content": "---\n# Website: http://goruco.com/#schedule\n\n- id: \"jessica-rudder-goruco-2018\"\n  title: \"Opening Keynote: The Good Bad Bug - Fail Your Way to Better Code by Jessica Rudder\"\n  raw_title: \"GORUCO 2018: Opening Keynote: The Good Bad Bug: Fail Your Way to Better Code by Jessica Rudder\"\n  speakers:\n    - Jessica Rudder\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: Opening Keynote: The Good Bad Bug: Fail Your Way to Better Code by Jessica Rudder\n  video_provider: \"youtube\"\n  video_id: \"m76jMaIxJEY\"\n\n- id: \"scott-bellware-goruco-2018\"\n  title: \"Evented Autonomous Services in Ruby\"\n  raw_title: \"GORUCO 2018: Evented Autonomous Services in Ruby by Scott Bellware\"\n  speakers:\n    - Scott Bellware\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: Evented Autonomous Services in Ruby by Scott Bellware\n  video_provider: \"youtube\"\n  video_id: \"qgKlu5gFsJM\"\n\n- id: \"danielle-adams-goruco-2018\"\n  title: \"Locking It Down with Ruby & Lockfiles\"\n  raw_title: \"GORUCO 2018: Locking It Down with Ruby & Lockfiles by Danielle Adams\"\n  speakers:\n    - Danielle Adams\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: Locking It Down with Ruby & Lockfiles by Danielle Adams\n  video_provider: \"youtube\"\n  video_id: \"C9oVODkO4W4\"\n\n- id: \"kir-shatrov-goruco-2018\"\n  title: \"Running Jobs at Scale\"\n  raw_title: \"GORUCO 2018: Running Jobs at Scale by Kir Shatrov\"\n  speakers:\n    - Kir Shatrov\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: Running Jobs at Scale by Kir Shatrov\n  video_provider: \"youtube\"\n  video_id: \"XvnWjsmAl60\"\n\n- id: \"melissa-wahnish-goruco-2018\"\n  title: \"Encryption Pitfalls and Workarounds\"\n  raw_title: \"GORUCO 2018: Encryption Pitfalls and Workarounds by Melissa Wahnish\"\n  speakers:\n    - Melissa Wahnish\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: Encryption Pitfalls and Workarounds by Melissa Wahnish\n  video_provider: \"youtube\"\n  video_id: \"fqPPeDvKY9Y\"\n\n- id: \"max-tiu-goruco-2018\"\n  title: \"The Practical Guide to Building an Apprenticeship\"\n  raw_title: \"GORUCO 2018: The Practical Guide to Building an Apprenticeship by Max Tiu\"\n  speakers:\n    - Max Tiu\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: The Practical Guide to Building an Apprenticeship by Max Tiu\n  video_provider: \"youtube\"\n  video_id: \"31-DPycAKyY\"\n\n- id: \"andy-croll-goruco-2018\"\n  title: \"The Impermanence of Software\"\n  raw_title: \"GORUCO 2018: The Impermanence of Software by Andy Croll\"\n  speakers:\n    - Andy Croll\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: The Impermanence of Software by Andy Croll\n  video_provider: \"youtube\"\n  video_id: \"YTQf2ZbUSb4\"\n\n- id: \"kelly-sutton-goruco-2018\"\n  title: \"I've Made a Huge Mistake: We Did Services All Wrong\"\n  raw_title: \"GORUCO 2018:  I've Made a Huge Mistake: We Did Services All Wrong by Kelly Sutton\"\n  speakers:\n    - Kelly Sutton\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: I've Made a Huge Mistake: We Did Services All Wrong by Kelly Sutton\n  video_provider: \"youtube\"\n  video_id: \"NqdjRw1Msz8\"\n\n- id: \"joe-leo-goruco-2018\"\n  title: \"Writing Ruby Like it's 2018\"\n  raw_title: \"GORUCO 2018: Writing Ruby Like it's 2018 by Joe Leo\"\n  speakers:\n    - Joe Leo\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: Writing Ruby Like it's 2018 by Joe Leo\n  video_provider: \"youtube\"\n  video_id: \"VjR3GU0-vpc\"\n\n- id: \"rushaine-mcbean-goruco-2018\"\n  title: \"Building Efficient APIs with JSON-API\"\n  raw_title: \"GORUCO 2018: Building Efficient APIs with JSON-API by Rushaine McBean\"\n  speakers:\n    - Rushaine McBean\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: Building Efficient APIs with JSON-API by Rushaine McBean\n  video_provider: \"youtube\"\n  video_id: \"-1mdsGQxYc4\"\n\n- id: \"desmond-rawls-goruco-2018\"\n  title: \"The Twelve-Factor Function\"\n  raw_title: \"GORUCO 2018:  The Twelve-Factor Function by Desmond Rawls\"\n  speakers:\n    - Desmond Rawls\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: The Twelve-Factor Function by Desmond Rawls\n  video_provider: \"youtube\"\n  video_id: \"U0K9G3Eig2w\"\n\n- id: \"sam-phippen-goruco-2018\"\n  title: \"After Death\"\n  raw_title: \"GORUCO 2018: After Death by Sam Phippen\"\n  speakers:\n    - Sam Phippen\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018:  After Death by Sam Phippen\n  video_provider: \"youtube\"\n  video_id: \"QrdcNIgPbpo\"\n\n- id: \"aaron-patterson-goruco-2018\"\n  title: \"Closing Keynote: Analyzing and Reducing Ruby Memory Usage\"\n  raw_title: \"GORUCO 2018: Closing Keynote: Analyzing and Reducing Ruby Memory Usage by  Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: Closing Keynote: Analyzing and Reducing Ruby Memory Usage by  Aaron Patterson\n  video_provider: \"youtube\"\n  video_id: \"mecapKBzIMw\"\n\n- id: \"francis-hwang-goruco-2018\"\n  title: \"GORUCO Memories\"\n  raw_title: \"GORUCO 2018: GORUCO Memories Francis Hwang\"\n  speakers:\n    - Francis Hwang\n  event_name: \"GORUCO 2018\"\n  date: \"2018-06-18\"\n  published_at: \"2018-06-29\"\n  description: |-\n    GORUCO 2018: GORUCO Memories Francis Hwang\n  video_provider: \"youtube\"\n  video_id: \"pWx8w3bgVJ0\"\n"
  },
  {
    "path": "data/goruco/series.yml",
    "content": "---\nname: \"Gotham Ruby Conference\"\nwebsite: \"http://goruco.com\"\ntwitter: \"goruco\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"GORUCO\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\naliases:\n  - GORUCO\n  - GoRuCo\n  - Gotham Ruby Conf\n  - Gotham Ruby\n  - GothamRubyConference\n"
  },
  {
    "path": "data/grill-rb/grill-rb-2016/event.yml",
    "content": "---\nid: \"grill-rb-2016\"\ntitle: \"Grill.rb 2016\"\ndescription: \"\"\nlocation: \"Wrocław, Poland\"\nkind: \"conference\"\nstart_date: \"2016-06-25\"\nend_date: \"2016-06-26\"\nwebsite: \"\"\ntwitter: \"grill_rb\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\naliases:\n  - GrillRB 2016\n"
  },
  {
    "path": "data/grill-rb/grill-rb-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/grill-rb/grill-rb-2017/event.yml",
    "content": "---\nid: \"PLDraF2Fjmu8VuZ8CohiG4EZuwHpUACUIN\"\ntitle: \"Grill.rb 2017\"\ndescription: \"\"\nlocation: \"Wrocław, Poland\"\nkind: \"conference\"\nstart_date: \"2017-07-01\"\nend_date: \"2017-07-02\"\nwebsite: \"\"\ntwitter: \"grill_rb\"\nplaylist: \"https://www.youtube.com/playlist?list=PLDraF2Fjmu8VuZ8CohiG4EZuwHpUACUIN\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\naliases:\n  - Grill.RB 2017\n"
  },
  {
    "path": "data/grill-rb/grill-rb-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: https://www.youtube.com/playlist?list=PLDraF2Fjmu8VuZ8CohiG4EZuwHpUACUIN\n---\n[]\n"
  },
  {
    "path": "data/grill-rb/grill-rb-2018/event.yml",
    "content": "---\nid: \"grill-rb-2018\"\ntitle: \"Grill.rb 2018\"\ndescription: \"\"\nlocation: \"Wrocław, Poland\"\nkind: \"conference\"\nstart_date: \"2018-08-11\"\nend_date: \"2018-08-12\"\nwebsite: \"http://grillrb.com\"\ntwitter: \"grill_rb\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\naliases:\n  - Grill.RB 2018\n"
  },
  {
    "path": "data/grill-rb/grill-rb-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://grillrb.com\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/grill-rb/grill-rb-2019/event.yml",
    "content": "---\nid: \"PLDraF2Fjmu8WDwr5nInlqNzeiBk9sIsCt\"\ntitle: \"Grill.rb 2019\"\ndescription: \"\"\nlocation: \"Wrocław, Poland\"\nkind: \"conference\"\nstart_date: \"2019-08-31\"\nend_date: \"2019-09-01\"\nwebsite: \"http://grillrb.com\"\ntwitter: \"grill_rb\"\nplaylist: \"https://www.youtube.com/playlist?list=PLDraF2Fjmu8WDwr5nInlqNzeiBk9sIsCt\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\naliases:\n  - Grill.RB 2019\n"
  },
  {
    "path": "data/grill-rb/grill-rb-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://grillrb.com\n# Videos: https://www.youtube.com/playlist?list=PLDraF2Fjmu8WDwr5nInlqNzeiBk9sIsCt\n---\n[]\n"
  },
  {
    "path": "data/grill-rb/series.yml",
    "content": "---\nname: \"Grill.rb\"\nwebsite: \"\"\ntwitter: \"grill_rb\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/guru-pr/series.yml",
    "content": "---\nname: \"GURU-PR\"\nwebsite: \"https://web.archive.org/web/20161022020003/http://www.gurupr.org/\"\ndescription: |-\n  Ruby User Group of Paraná\ntwitter: \"guru_pr\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - Ruby Paraná\n  - Ruby User Group Paraná\n  - Ruby User Group of Paraná\n"
  },
  {
    "path": "data/guru-pr/tech-day-by-guru-pr-2016/event.yml",
    "content": "---\nid: \"tech-day-by-guru-pr-2016\"\ntitle: \"Tech Day by GURU-PR 2016\"\ndescription: \"\"\nlocation: \"Curitiba, Brazil\"\nkind: \"conference\"\nstart_date: \"2016-08-20\"\nend_date: \"2016-08-20\"\nwebsite: \"http://www.gurupr.org/eventos/2-tech-day-do-guru-pr\"\ntwitter: \"guru_pr\"\ncoordinates:\n  latitude: -25.4268985\n  longitude: -49.2651984\n"
  },
  {
    "path": "data/guru-pr/tech-day-by-guru-pr-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.gurupr.org/eventos/2-tech-day-do-guru-pr\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/haggis-ruby/haggis-ruby-2024/event.yml",
    "content": "---\nid: \"haggis-ruby-2024\"\ntitle: \"Haggis Ruby 2024\"\ndescription: \"\"\nlocation: \"Edinburgh, Scotland, UK\"\nkind: \"conference\"\nstart_date: \"2024-10-24\"\nend_date: \"2024-10-24\"\npublished_at: \"2026-03-23\"\nwebsite: \"https://haggisruby.co.uk/2024.html\"\nmastodon: \"https://ruby.social/@haggisruby\"\nbanner_background: \"#401010\"\nfeatured_background: \"#F6EBEA\"\nfeatured_color: \"#401010\"\ncoordinates:\n  latitude: 55.9534896\n  longitude: -3.1965506\n"
  },
  {
    "path": "data/haggis-ruby/haggis-ruby-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold\"\n      description: |-\n        Gold sponsors\n      level: 1\n      sponsors:\n        - name: \"FreeAgent\"\n          website: \"https://freeagent.com\"\n          slug: \"FreeAgent\"\n          logo_url: \"https://haggisruby.co.uk/images/freeagent.svg\"\n\n    - name: \"Silver\"\n      description: |-\n        Silver sponsors\n      level: 2\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"AppSignal\"\n          logo_url: \"https://haggisruby.co.uk/images/appsignal.svg\"\n\n    - name: \"Bronze\"\n      description: |-\n        Bronze sponsors\n      level: 3\n      sponsors:\n        - name: \"Cybergizer\"\n          website: \"https://cybergizer.com/\"\n          slug: \"Cybergizer\"\n          logo_url: \"https://haggisruby.co.uk/images/cybergizer2.png\"\n\n        - name: \"Miles Woodroffe\"\n          website: \"https://mileswoodroffe.com/\"\n          slug: \"miles-woodroffe\"\n          logo_url: \"\"\n\n    - name: \"Other Sponsoring\"\n      description: |-\n        Other sponsoring like speakers' dinner\n      level: 4\n      sponsors:\n        - name: \"Workbrew\"\n          website: \"https://workbrew.com/\"\n          slug: \"Workbrew\"\n          logo_url: \"https://haggisruby.co.uk/images/workbrew.svg\"\n"
  },
  {
    "path": "data/haggis-ruby/haggis-ruby-2024/venue.yml",
    "content": "---\nname: \"The Royal Society of Edinburgh\"\n\naddress:\n  street: \"22-26 George Street\"\n  city: \"Edinburgh\"\n  region: \"Scotland\"\n  postal_code: \"EH2 2PQ\"\n  country: \"United Kingdom\"\n  country_code: \"GB\"\n  display: \"22-26 George St, Edinburgh EH2 2PQ, UK\"\n\ncoordinates:\n  latitude: 55.9534896\n  longitude: -3.1965506\n\nmaps:\n  google: \"https://maps.google.com/?q=The+Royal+Society+of+Edinburgh,55.9534896,-3.1965506\"\n  apple: \"https://maps.apple.com/?q=The+Royal+Society+of+Edinburgh&ll=55.9534896,-3.1965506\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=55.9534896&mlon=-3.1965506\"\n"
  },
  {
    "path": "data/haggis-ruby/haggis-ruby-2024/videos.yml",
    "content": "# Website: https://haggisruby.co.uk\n# Videos: https://www.youtube.com/playlist?list=PLIrvfu-0pIAGmPk8o6zQ2mD99kXSxrdxE\n---\n- title: \"Welcome\"\n  speakers:\n    - James Bell\n  event_name: \"Haggis Ruby 2024\"\n  description: \"\"\n  date: \"2024-10-24\"\n  video_id: \"welcome-haggis-ruby-2024\"\n  video_provider: \"not_recorded\"\n  slug: \"welcome-haggis-ruby-2024\"\n  id: \"welcome-haggis-ruby-2024\"\n\n- title: \"Stop overthinking and go create things\"\n  speakers:\n    - Olly Headey\n  event_name: \"Haggis Ruby 2024\"\n  description: |-\n    Co-founder of FreeAgent, 37signals alumni\n  date: \"2024-10-24\"\n  video_id: \"olly-headey-haggis-ruby-2024\"\n  video_provider: \"not_recorded\"\n  slug: \"stop-overthinking-and-go-create-things-haggis-ruby-2024\"\n  id: \"olly-headey-haggis-ruby-2024\"\n\n- title: \"Invalid byte sequence in UTF-8 😭\"\n  speakers:\n    - Rosa Gutierrez\n  event_name: \"Haggis Ruby 2024\"\n  description: |-\n    Rosa Gutierrez talks about the trials and tribulations of character encoding.\n  date: \"2024-10-24\"\n  video_id: \"e6JsXcxD3G4\"\n  video_provider: \"youtube\"\n  published_at: \"2026-03-23\"\n  slug: \"invalid-byte-sequence-in-utf-8-haggis-ruby-2024\"\n  id: \"rosa-gutierrez-haggis-ruby-2024\"\n\n- title: \"Turn Left for Bridgetown: An overview of a next-generation static(ish) site generator\"\n  speakers:\n    - Ayush Newatia\n  event_name: \"Haggis Ruby 2024\"\n  description: |-\n    Ayush talks about Bridgetown - the newest Ruby based static site builder on the block.\n  date: \"2024-10-24\"\n  video_id: \"Mwd4un3bu5Q\"\n  video_provider: \"youtube\"\n  published_at: \"2026-03-23\"\n  slug: \"turn-left-for-bridgetown-an-overview-of-a-next-generation-static-ish-site-generator\"\n  id: \"ayush-newatia-haggis-ruby-2024\"\n\n- title: \"Lightning Talk: Fractional CTO explained\"\n  speakers:\n    - Ceri Shaw\n  event_name: \"Haggis Ruby 2024\"\n  description: |-\n    Ceri's lightning talk on their journey to being a Fractional CTO, and what a Fractional CTO even is.\n  date: \"2024-10-24\"\n  video_id: \"uo3bQEoFVjs\"\n  video_provider: \"youtube\"\n  published_at: \"2026-03-23\"\n  slug: \"fractional-cto-explained\"\n  id: \"ceri-shaw-haggis-ruby-2024\"\n\n- title: \"Lightning Talk: Ruby is more than Rails - ruby_rpg\"\n  speakers:\n    - Max Hatfull\n  event_name: \"Haggis Ruby 2024\"\n  description: |-\n    Max shows off a Ruby library he's created to build games in Ruby - 3D, platformers and all sorts.\n  date: \"2024-10-24\"\n  video_id: \"Twynr1p3bck\"\n  video_provider: \"youtube\"\n  published_at: \"2026-03-23\"\n  slug: \"ruby-is-more-than-rails-ruby_rpg\"\n  id: \"max-hatfull-haggis-ruby-2024\"\n\n- title: \"Ruby + AI for building multi-agent architecture\"\n  speakers:\n    - Sergy Sergyenko\n  event_name: \"Haggis Ruby 2024\"\n  description: |-\n    It's 2024, and Sergy is talking about Ruby and LLMs in a multi-agent way. What could your structure look like, and what tools and libraries exist right now?\n  date: \"2024-10-24\"\n  video_id: \"n1plPk3cZsk\"\n  video_provider: \"youtube\"\n  published_at: \"2026-03-23\"\n  slug: \"ruby-ai-for-building-multi-agent-architecture\"\n  id: \"sergy-sergyenko-haggis-ruby-2024\"\n\n- title: \"Building Resilience\"\n  speakers:\n    - Melinda Seckington\n  event_name: \"Haggis Ruby 2024\"\n  description: |-\n    Melinda talks about what resilience is, especially in a professional context, and how you can build your way towards improving your own.\n  date: \"2024-10-24\"\n  video_id: \"ziEA7AcBRXA\"\n  video_provider: \"youtube\"\n  published_at: \"2026-03-23\"\n  slug: \"building-resilience\"\n  id: \"melinda-seckington-haggis-ruby-2024\"\n\n- title: \"Ruby on (Guard) Rails\"\n  speakers:\n    - Mike McQuaid\n  event_name: \"Haggis Ruby 2024\"\n  description: |-\n    Ruby is powerful, and you want to move fast. So having guardrails can be useful? Mike takes us on a tour of the tools they use at Workbrew to guide their development.\n  date: \"2024-10-24\"\n  video_id: \"KgjFrEtMadQ\"\n  video_provider: \"youtube\"\n  published_at: \"2026-03-12\"\n  slug: \"ruby-on-guard-rails\"\n  id: \"mike-mcquaid-haggis-ruby-2024\"\n\n- title: \"monolith.dig(:artefacts, :lessons) => An archaeological investigation of a large, ancient Rails app\"\n  speakers:\n    - Emma Barnes\n  event_name: \"Haggis Ruby 2024\"\n  description: |-\n    CEO of consonance.app, MD of snowbooks.com and makeourbook.com\n  date: \"2024-10-24\"\n  video_id: \"emma-barnes-haggis-ruby-2024\"\n  video_provider: \"not_recorded\"\n  slug: \"monolith-dig-artefacts-lessons-an-archaeological-investigation-of-a-large-ancient-rails-app\"\n  id: \"emma-barnes-haggis-ruby-2024\"\n"
  },
  {
    "path": "data/haggis-ruby/haggis-ruby-2026/event.yml",
    "content": "---\nid: \"haggis-ruby-2026\"\ntitle: \"Haggis Ruby 2026\"\ndescription: |-\n  A Ruby conference in sunny Scotland!\n\n  Bringing the Scottish, British and European Ruby scenes together in Scotland's biggest city.\n\n  Fair fa’ your honest, sonsie face\nlocation: \"Glasgow, Scotland, UK\"\nkind: \"conference\"\nstart_date: \"2026-04-23\"\nend_date: \"2026-04-24\"\nwebsite: \"https://haggisruby.co.uk\"\ntickets_url: \"https://ti.to/haggis-ruby/haggis-ruby-2026\"\nmastodon: \"https://ruby.social/@haggisruby\"\nbanner_background: \"#401010\"\nfeatured_background: \"#F6EBEA\"\nfeatured_color: \"#401010\"\ncoordinates:\n  latitude: 55.8597616\n  longitude: -4.2592386\n"
  },
  {
    "path": "data/haggis-ruby/haggis-ruby-2026/sponsors.yml",
    "content": "# docs/ADDING_SPONSORS.md\n---\n- tiers:\n    - name: \"Gold\"\n      level: 1\n      sponsors:\n        - name: \"FreeAgent\"\n          website: \"https://freeagent.com\"\n          slug: \"freeagent\"\n\n        - name: \"Typesense\"\n          website: \"https://typesense.org\"\n          slug: \"typesense\"\n          badge: \"Wifi\"\n\n    - name: \"Silver\"\n      level: 2\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n"
  },
  {
    "path": "data/haggis-ruby/haggis-ruby-2026/venue.yml",
    "content": "---\nname: \"thestudio... Glasgow\"\ndescription: |-\n  The Studio Glasgow is located right in the heart of the city, literally seconds away from Glasgow Central Station. It occupies the 8th and 9th floors of a distinctive glass-fronted building.\n\n  The space is bright, friendly, and modern and boasts impressive views of the rooftops and hills beyond.\naddress:\n  street: \"67 Hope Street\"\n  city: \"Glasgow City\"\n  region: \"Scotland\"\n  postal_code: \"G2 6AE\"\n  country: \"United Kingdom\"\n  country_code: \"GB\"\n  display: \"67 Hope St, Glasgow G2 6AE, UK\"\ncoordinates:\n  latitude: 55.8597616\n  longitude: -4.2592386\nmaps:\n  google: \"https://maps.google.com/?q=thestudio...+Glasgow,55.8597616,-4.2592386\"\n  apple: \"https://maps.apple.com/?q=thestudio...+Glasgow&ll=55.8597616,-4.2592386\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=55.8597616&mlon=-4.2592386\"\n\nhotels:\n  - name: \"voco Grand Central\"\n    description: |-\n      A stylish hotel in the heart of Glasgow, and just across the road from the conference venue, offering a luxurious stay with a contemporary design and modern amenities.\n    url: \"https://www.ihg.com/voco/hotels/gb/en/find-hotels/select-roomrate\"\n    address:\n      street: \"99 Gordon Street\"\n      city: \"Glasgow\"\n      region: \"Scotland\"\n      postal_code: \"G1 3SF\"\n      country: \"United Kingdom\"\n      country_code: \"gb\"\n      display: \"99 Gordon Street, Glasgow, GB\"\n\n    coordinates:\n      latitude: 55.859874\n      longitude: -4.2587001\n\n    maps:\n      google: \"https://maps.app.goo.gl/pY5n7rUTZWD7g1Fx6\"\n      apple: \"\"\n      openstreetmap: \"\"\n\n  - name: \"Radisson Blu Hotel Glasgow\"\n    description: |-\n      Another great option just a few minutes walk from the Studio, offering a comfortable stay with modern amenities.\n    url: \"https://www.radissonhotels.com/en-us/hotels/radisson-blu-glasgow\"\n    address:\n      street: \"301 Argyle Street\"\n      city: \"Glasgow\"\n      region: \"Scotland\"\n      postal_code: \"G2 8DP\"\n      country: \"United Kingdom\"\n      country_code: \"gb\"\n      display: \"301 Argyle Street, Glasgow, Scotland\"\n\n    coordinates:\n      latitude: 55.8585079\n      longitude: -4.2603739\n\n    maps:\n      google: \"https://maps.app.goo.gl/4S8JmSJh3c1VgQgV7\"\n      apple: \"\"\n      openstreetmap: \"\"\n\n  - name: \"YOTEL Glasgow\"\n    description: |-\n      If you are looking for a more budget-friendly option, this is a great choice. Still as close to the conference venue as possible.\n    url: \"https://www.yotel.com/en/hotels/yotel-glasgow\"\n    address:\n      street: \"260 Argyle Street\"\n      city: \"Glasgow\"\n      region: \"Scotland\"\n      postal_code: \"G2 8QW\"\n      country: \"United Kingdom\"\n      country_code: \"gb\"\n      display: \"260 Argyle Street, Glasgow, Scotland\"\n\n    coordinates:\n      latitude: 55.8587934\n      longitude: -4.2596983\n\n    maps:\n      google: \"https://maps.app.goo.gl/NEaJcMZ7MD2ArJXq9\"\n      apple: \"\"\n      openstreetmap: \"\"\n\n  - name: \"The Address Glasgow\"\n    description: |-\n      Another great option if you are looking for a more luxurious stay.\n\n      For discounted rates, please contact the hotel directly at reservations.glasgow@theaddresscollective.com and mention \"Haggis Ruby\".\n    url: \"http://www.theaddressglasgow.com/\"\n    address:\n      street: \"39-45 Renfield Street\"\n      city: \"Glasgow\"\n      region: \"Scotland\"\n      postal_code: \"G2 1JS\"\n      country: \"United Kingdom\"\n      country_code: \"gb\"\n      display: \"39-45 Renfield Street, Glasgow, Scotland\"\n\n    coordinates:\n      latitude: 55.8621897\n      longitude: -4.256597\n\n    maps:\n      google: \"https://maps.app.goo.gl/wWjBgXyrQHEkGZqW8\"\n      apple: \"\"\n      openstreetmap: \"\"\n"
  },
  {
    "path": "data/haggis-ruby/haggis-ruby-2026/videos.yml",
    "content": "---\n- id: \"sue-smith-haggis-ruby-2026\"\n  title: \"Talk by Sue Smith\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Sue Smith\n  video_provider: \"scheduled\"\n  video_id: \"sue-smith-haggis-ruby-2026\"\n\n- id: \"hana-harencarova-haggis-ruby-2026\"\n  title: \"Talk by Hana Harencarova\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Hana Harencarova\n  video_provider: \"scheduled\"\n  video_id: \"hana-harencarova-haggis-ruby-2026\"\n\n- id: \"mike-mcquaid-haggis-ruby-2026\"\n  title: \"Talk by Mike McQuaid\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Mike McQuaid\n  video_provider: \"scheduled\"\n  video_id: \"mike-mcquaid-haggis-ruby-2026\"\n\n- id: \"colin-gemmell-haggis-ruby-2026\"\n  title: \"Talk by Colin Gemmell\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Colin Gemmell\n  video_provider: \"scheduled\"\n  video_id: \"colin-gemmell-haggis-ruby-2026\"\n\n- id: \"jess-sullivan-haggis-ruby-2026\"\n  title: \"Talk by Jess Sullivan\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Jess Sullivan\n  video_provider: \"scheduled\"\n  video_id: \"jess-sullivan-haggis-ruby-2026\"\n\n- id: \"donal-mcbreen-haggis-ruby-2026\"\n  title: \"Talk by Donal McBreen\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Donal McBreen\n  video_provider: \"scheduled\"\n  video_id: \"donal-mcbreen-haggis-ruby-2026\"\n\n- id: \"aji-slater-haggis-ruby-2026\"\n  title: \"Talk by Aji Slater\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Aji Slater\n  video_provider: \"scheduled\"\n  video_id: \"aji-slater-haggis-ruby-2026\"\n\n- id: \"miranda-heath-haggis-ruby-2026\"\n  title: \"Talk by Miranda Heath\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Miranda Heath\n  video_provider: \"scheduled\"\n  video_id: \"miranda-heath-haggis-ruby-2026\"\n\n- id: \"ismael-celis-haggis-ruby-2026\"\n  title: \"Talk by Ismael Celis\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Ismael Celis\n  video_provider: \"scheduled\"\n  video_id: \"ismael-celis-haggis-ruby-2026\"\n\n- id: \"carme-mias-haggis-ruby-2026\"\n  title: \"Talk by Carme Mias\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Carme Mias\n  video_provider: \"scheduled\"\n  video_id: \"carme-mias-haggis-ruby-2026\"\n\n- id: \"murray-steele-haggis-ruby-2026\"\n  title: \"Talk by Murray Steele\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Murray Steele\n  video_provider: \"scheduled\"\n  video_id: \"murray-steele-haggis-ruby-2026\"\n\n- id: \"peter-aitken-haggis-ruby-2026\"\n  title: \"Talk by Peter Aitken\" # TODO\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Peter Aitken\n  video_provider: \"scheduled\"\n  video_id: \"peter-aitken-haggis-ruby-2026\"\n"
  },
  {
    "path": "data/haggis-ruby/series.yml",
    "content": "---\nname: \"Haggis Ruby\"\nwebsite: \"https://haggisruby.co.uk\"\nmastodon: \"https://ruby.social/@haggisruby\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/helsinki-ruby/helsinki-ruby-brigade/event.yml",
    "content": "---\nid: \"PLF1jkqcXA5ckRPFZdq572uRHD_wHG0jO9\"\ntitle: \"Helsinki Ruby Brigade\"\nkind: \"meetup\"\nfrequency: \"quarterly\"\nlocation: \"Helsinki, Finland\"\ndescription: |-\n  Recordings from Ruby Brigade 2023/2024 meet-ups\npublished_at: \"2023-06-20\"\nchannel_id: \"UCcoS038f4xA_Lz5AoD0ShzA\"\nyear: 2023\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubybrigade.fi\"\ncoordinates:\n  latitude: 60.16985569999999\n  longitude: 24.938379\n"
  },
  {
    "path": "data/helsinki-ruby/helsinki-ruby-brigade/videos.yml",
    "content": "---\n- id: \"helsinki-ruby-brigade-may-2023\"\n  title: \"Helsinki Ruby Brigade May 2023\"\n  raw_title: \"Helsinki Ruby Brigade May 2023\"\n  event_name: \"Helsinki Ruby Brigade May 2023\"\n  date: \"2023-05-10\"\n  video_provider: \"children\"\n  video_id: \"helsinki-ruby-brigade-may-2023\"\n  description: |-\n    https://rubybrigade.fi/event/2023/the-return/\n  talks:\n    - title: \"Oivan's journey with Ruby on Rails\"\n      raw_title: \"Oivan’s journey with Ruby on Rails\"\n      speakers:\n        - Aki Teliö\n      event_name: \"Helsinki Ruby Brigade May 2023\"\n      date: \"2023-05-10\"\n      published_at: \"2023-06-20\"\n      description: |-\n        Oivan has built and scaling one of the largest applications in the ME region. Among this journey, there have been several learnings including restructuring the team, cultural differences and working with microservices application. Now we are scaling up and building larger teams.\n\n        Aki Teliö at the Helsinki Ruby Brigade meet-up on 2023-05-10.\n\n        https://rubybrigade.fi/event/2023/the-return/\n      video_provider: \"youtube\"\n      id: \"aki-teli-helsinki-ruby-brigade-may-2023\"\n      video_id: \"8s-8E0NhM88\"\n\n    - title: \"Ruby ❤️ Rust\"\n      raw_title: \"Ruby ❤️ Rust\"\n      speakers:\n        - Matias Korhonen\n      event_name: \"Helsinki Ruby Brigade May 2023\"\n      date: \"2023-05-10\"\n      published_at: \"2023-06-20\"\n      description: |-\n        A very quick intro to Rust-based gem extensions and an even quicker introduction to Rust itself.\n\n        Matias Korhonen at the Helsinki Ruby Brigade meet-up on 2023-05-10.\n\n        https://rubybrigade.fi/event/2023/the-return/\n      video_provider: \"youtube\"\n      id: \"matias-korhonen-helsinki-ruby-brigade-may-2023\"\n      video_id: \"O5HCGJIcK68\"\n\n    - title: \"Interact with AI effortlessly\"\n      raw_title: \"Interact with AI effortlessly\"\n      speakers:\n        - Lauri Jutila\n      event_name: \"Helsinki Ruby Brigade May 2023\"\n      date: \"2023-05-10\"\n      published_at: \"2023-06-20\"\n      description: |-\n        AI, and especially LLMs, are all the rage right now. Lauri will show you how interacting with AI models can be easy and effortless.\n\n        Lauri Jutila at the Helsinki Ruby Brigade meet-up on 2023-05-10.\n\n        https://rubybrigade.fi/event/2023/the-return/\n      video_provider: \"youtube\"\n      id: \"lauri-jutila-helsinki-ruby-brigade-may-2023\"\n      video_id: \"oftEvWV0us0\"\n\n- id: \"helsinki-ruby-brigade-september-2023\"\n  title: \"Helsinki Ruby Brigade September 2023\"\n  raw_title: \"Helsinki Ruby Brigade September 2023\"\n  event_name: \"Helsinki Ruby Brigade September 2023\"\n  date: \"2023-09-06\"\n  video_provider: \"children\"\n  video_id: \"helsinki-ruby-brigade-september-2023\"\n  thumbnail_xs: \"https://img.youtube.com/vi/GUKSN6ePoj8/default.jpg\"\n  thumbnail_sm: \"https://img.youtube.com/vi/GUKSN6ePoj8/sddefault.jpg\"\n  thumbnail_md: \"https://img.youtube.com/vi/GUKSN6ePoj8/mqdefault.jpg\"\n  thumbnail_lg: \"https://img.youtube.com/vi/GUKSN6ePoj8/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/GUKSN6ePoj8/maxresdefault.jpg\"\n  description: |-\n    https://rubybrigade.fi/event/2023/september-meet-up/\n  talks:\n    - title: \"Developers' role in elevating the quality of design\"\n      raw_title: \"Developers’ role in elevating the quality of design\"\n      speakers:\n        - Simo Virtanen\n      event_name: \"Helsinki Ruby Brigade September 2023\"\n      date: \"2023-09-06\"\n      published_at: \"2023-09-09\"\n      description: |-\n        Does designing end when designs are handed over to developers? A talk about how developers can help designers be better.\n\n        Helsinki Ruby Brigade on 2023-09-06.\n\n        https://rubybrigade.fi/event/2023/september-meet-up/\n      video_provider: \"youtube\"\n      id: \"simo-virtanen-helsinki-ruby-brigade-september-2023\"\n      video_id: \"GUKSN6ePoj8\"\n\n- id: \"helsinki-ruby-brigade-february-2024\"\n  title: \"Helsinki Ruby Brigade February 2024\"\n  raw_title: \"Helsinki Ruby Brigade February 2024\"\n  event_name: \"Helsinki Ruby Brigade February 2024\"\n  date: \"2024-02-21\"\n  video_provider: \"children\"\n  video_id: \"helsinki-ruby-brigade-february-2024\"\n  description: |-\n    https://rubybrigade.fi/event/2024/february-meet-up-at-juova/\n  talks:\n    - title: \"Dependencies - An Asset and a Curse\"\n      raw_title: \"Dependencies – an asset and a curse (Joakim Antman)\"\n      speakers:\n        - Joakim Antman\n      event_name: \"Helsinki Ruby Brigade February 2024\"\n      date: \"2024-02-21\"\n      published_at: \"2024-02-26\"\n      description: |-\n        Helsinki Ruby Brigade, 2024-02-21.\n\n        https://rubybrigade.fi/event/2024/february-meet-up-at-juova/\n      video_provider: \"youtube\"\n      id: \"joakim-antman-helsinki-ruby-brigade-february-2024\"\n      video_id: \"gYYBhmSFiCE\"\n\n    - title: \"How I'm trying to fix localization, and what you can do to help\"\n      raw_title: \"How I'm trying to fix localization, and what you can do to help (Eemeli Aro)\"\n      speakers:\n        - Eemeli Aro\n      event_name: \"Helsinki Ruby Brigade February 2024\"\n      date: \"2024-02-21\"\n      published_at: \"2024-02-26\"\n      description: |-\n        Like many other problems in coding, localization (the art of making your stuff usable and nice to people from various countries and cultures) can seem really easy, until it’s not. Really simple solutions often get you most of the way to what you need, but then the final few complexities turn out to be Hard. I’ve spent a decade working on making localization easier; let me share with you a couple of the projects I’m currently engaged in, and how you can help make the world a little bit more international.\n\n        Helsinki Ruby Brigade on 2024-02-21.\n\n        https://rubybrigade.fi/event/2024/february-meet-up-at-juova/\n      video_provider: \"youtube\"\n      id: \"eemeli-aro-helsinki-ruby-brigade-february-2024\"\n      video_id: \"_nRgzlBSUs8\"\n\n- id: \"helsinki-ruby-brigade-may-2024\"\n  title: \"Helsinki Ruby Brigade May 2024\"\n  raw_title: \"Helsinki Ruby Brigade May 2024\"\n  event_name: \"Helsinki Ruby Brigade May 2024\"\n  date: \"2024-05-29\"\n  video_provider: \"children\"\n  video_id: \"helsinki-ruby-brigade-may-2024\"\n  description: |-\n    Welcome to the Helsinki Ruby Brigade summer kick-off and after work drinks!\n\n    This is going to be a very casual event for meeting other Ruby folks. No talks nor any other official programming. Just come along to have a chat about Ruby stuff!\n\n    The location for this event is the Rotterdam terrace in Kamppi. In addition to drinks, they should also have smash burgers available for purchase. Look for Rubies, the Ruby Brigade logo, and other telltale signs of software engineers.\n\n    This event doesn't have a sponsor.\n\n    ⚠️ Note: depending on the weather and availability, we may need to move the event indoors or to another nearby location. Keep an eye on this page to make sure you navigate to the right place.\n\n    https://rubybrigade.fi/event/2024/summer-kick-off/\n  talks: []\n\n- id: \"helsinki-ruby-brigade-march-2025\"\n  title: \"Helsinki Ruby Brigade March 2025\"\n  raw_title: \"Helsinki Ruby Brigade March 2025\"\n  event_name: \"Helsinki Ruby Brigade March 2025\"\n  date: \"2025-03-26\"\n  video_provider: \"children\"\n  video_id: \"helsinki-ruby-brigade-march-2025\"\n  thumbnail_xs: \"https://img.youtube.com/vi/F51MpQJ-zWU/default.jpg\"\n  thumbnail_sm: \"https://img.youtube.com/vi/F51MpQJ-zWU/sddefault.jpg\"\n  thumbnail_md: \"https://img.youtube.com/vi/F51MpQJ-zWU/mqdefault.jpg\"\n  thumbnail_lg: \"https://img.youtube.com/vi/F51MpQJ-zWU/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/F51MpQJ-zWU/maxresdefault.jpg\"\n  description: |-\n    Welcome to the first meet-up of 2025, this time generously hosted by Kisko Labs.\n\n    Programme:\n    * Drinks & snacks\n    * Ruby pub quiz\n    * The Ruby community in Finland, what are we even doing here? (talk/discussion)\n    * Talk\n    * Networking\n\n    Talk: TracePoint for fun and profit by Matti Paksula\n\n    Ruby's built-in TracePoint API lets us hook into program execution in powerful ways. In this session, we'll explore how to use it to create a sandboxed execution context—catching method calls, restricting access, and preventing unsafe operations. Expect practical examples, challenges, and a discussion on its limits. Whether you’re into security, debugging, or metaprogramming, this should be an interesting dive into Ruby internals.\n\n    https://rubybrigade.fi/event/2025/march-meet-up-at-kisko-labs/\n  talks:\n    - title: \"TracePoint for fun and profit\"\n      raw_title: \"TracePoint for fun and profit by Matti Paksula\"\n      speakers:\n        - Matti Paksula\n      event_name: \"Helsinki Ruby Brigade March 2025\"\n      date: \"2025-03-16\"\n      published_at: \"2025-03-22\"\n      video_provider: \"youtube\"\n      id: \"matti-paksula-helsinki-ruby-brigade-march-2025\"\n      video_id: \"F51MpQJ-zWU\"\n      description: |-\n        Ruby's built-in TracePoint API lets us hook into program execution in powerful ways. In this session, we’ll explore how to use it to create a sandboxed execution context—catching method calls, restricting access, and preventing unsafe operations. Expect practical examples, challenges, and a discussion on its limits. Whether you’re into security, debugging, or metaprogramming, this should be an interesting dive into Ruby internals.\n\n        Helsinki Ruby Brigade, 2025-03-19.\n\n        https://rubybrigade.fi/event/2025/march-meet-up-at-kisko-labs/\n"
  },
  {
    "path": "data/helsinki-ruby/series.yml",
    "content": "---\nname: \"Helsinki Ruby\"\nwebsite: \"https://helsinkiruby.fi\"\nkind: \"organisation\"\nfrequency: \"quarterly\"\ndefault_country_code: \"FI\"\nyoutube_channel_name: \"helsinkiruby\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCcoS038f4xA_Lz5AoD0ShzA\"\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2023/event.yml",
    "content": "---\nid: \"PL4jngagx9f7TIyNkSkS15oDrVPCa7LXsT\"\ntitle: \"Helvetic Ruby 2023\"\nkind: \"conference\"\nlocation: \"Bern, Switzerland\"\ndescription: |-\n  Talks from the 2023 edition of Helvetic Ruby, a local Ruby conference in Switzerland.\npublished_at: \"2023-11-24\"\nstart_date: \"2023-11-24\"\nend_date: \"2023-11-24\"\nchannel_id: \"UChetoakh7nU0EXrKN8QFUUA\"\nyear: 2023\nbanner_background: \"#F2EDE1\"\nfeatured_background: \"#F2EDE1\"\nfeatured_color: \"#810202\"\nwebsite: \"https://helvetic-ruby.ch/2023\"\ncoordinates:\n  latitude: 46.9505516\n  longitude: 7.4435491\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2023/schedule.yml",
    "content": "# Schedule: https://helvetic-ruby.ch/2023/schedule/\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2023-11-24\"\n    grid:\n      - start_time: \"08:45\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Arrival & Registration\n\n      - start_time: \"09:30\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Conference Start\n\n      - start_time: \"09:45\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:10\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:10\"\n        end_time: \"11:40\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:00\"\n        end_time: \"14:40\"\n        slots: 1\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"16:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:50\"\n        end_time: \"17:30\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"17:45\"\n        slots: 1\n        items:\n          - Final Words\n\n      - start_time: \"17:45\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - Socializing and Drinks\n\n      - start_time: \"19:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - title: \"Conference Hall Closes\"\n            description: |-\n              You are welcome to continue at the Turnhalle bar downstairs.\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2023/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold\"\n      description: |-\n        Gold level sponsors for Helvetic Ruby 2023 conference.\n      level: 1\n      sponsors:\n        - name: \"GARAIO REM\"\n          website: \"https://www.garaio-rem.ch/\"\n          slug: \"GARAIOREM\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/garaio-rem.svg\"\n\n        - name: \"Puzzle ITC\"\n          website: \"https://www.puzzle.ch/\"\n          slug: \"PuzzleITC\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/puzzle.svg\"\n\n        - name: \"Renuo\"\n          website: \"https://www.renuo.ch/\"\n          slug: \"Renuo\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/renuo.png\"\n\n    - name: \"Bronze\"\n      description: |-\n        Bronze level sponsors for Helvetic Ruby 2023 conference.\n      level: 2\n      sponsors:\n        - name: \"Pia Planer\"\n          website: \"https://pia-planer.ch/\"\n          slug: \"PiaPlaner\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/pia.png\"\n\n        - name: \"On\"\n          website: \"https://www.on-running.com/\"\n          slug: \"On\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/on.svg\"\n\n    - name: \"Travel Sponsors\"\n      description: |-\n        Sponsors supporting travel for Helvetic Ruby 2023 conference.\n      level: 3\n      sponsors:\n        - name: \"Evil Martians\"\n          website: \"https://evilmartians.com/\"\n          slug: \"EvilMartians\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/evil-martians.svg\"\n\n        - name: \"Crunchy Data\"\n          website: \"https://www.crunchydata.com/\"\n          slug: \"CrunchyData\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/crunchy-data.svg\"\n\n    # https://helvetic-ruby.ch/2023/#sponsors\n    - name: \"Partners\"\n      description: |-\n        Partners\n      level: 4\n      sponsors: []\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2023/venue.yml",
    "content": "---\nname: \"PROGR\"\n\naddress:\n  street: \"Waisenhausplatz 30\"\n  city: \"Bern\"\n  region: \"Bern\"\n  postal_code: \"3011\"\n  country: \"Switzerland\"\n  country_code: \"CH\"\n  display: \"Waisenhausplatz 30, 3011 Bern, Switzerland\"\n\ncoordinates:\n  latitude: 46.9505516\n  longitude: 7.4435491\n\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=46.9505516,7.4435491\"\n  apple: \"https://maps.apple.com/?q=PROGR,+Waisenhausplatz+30,+Bern\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=46.9505516&mlon=7.4435491&zoom=17\"\n\naccessibility:\n  wheelchair: true\n  elevators: true\n  notes: |-\n    The Auditorium can be accessed through the courtyard. On the east side of the courtyard (side Lehrerzimmer), a door signalled with PROGR OST leads to a wheelchair lift, which transports you to the mezzanine. To the right, past the main staircase, a lift brings you to the first floor. From there, the Auditorium to the left is reachable without thresholds.\n\nnearby:\n  public_transport: \"5-10 minutes walking distance from Bern train station\"\n\nhotels:\n  - name: \"ibis Styles Bern City\"\n    kind: \"Partner Hotel\"\n    address:\n      street: \"66 Zieglerstrasse\"\n      city: \"Bern\"\n      region: \"Bern\"\n      postal_code: \"3007\"\n      country: \"Switzerland\"\n      country_code: \"CH\"\n      display: \"Zieglerstrasse 66, 3007 Bern, Switzerland\"\n    description: |-\n      Conference partner hotel with exclusive rates\n    coordinates:\n      latitude: 46.9424095\n      longitude: 7.4302501\n    maps:\n      google: \"https://www.google.com/maps/search/?api=1&query=46.9424095,7.4302501\"\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n# Website: https://helvetic-ruby.ch/2023/\n# Schedule: https://helvetic-ruby.ch/2023/schedule/\n\n- id: \"vladimir-dementyev-helvetic-ruby-2023\"\n  title: \"Profiling Ruby tests with Swiss precision\"\n  raw_title: \"Profiling Ruby tests with Swiss precision by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    Tests occupy a significant amount of developers’ time. We write them, run locally, and wait for CI builds to complete—the latter can last from a cup of coffee to a good day nap. And unfortunately, such “naps” are pretty common in the Ruby and Rails world.\n\n    Luckily, the reasons for slow tests vary greatly between codebases: misconfigured environment, test-unfriendly dependencies, and, of course, factories and database interactions in general.\n\n    I like to demonstrate the tools and techniques to help you identify bottlenecks in test suites to help you stay awake.\n  video_provider: \"youtube\"\n  video_id: \"WNluKNQ1OFU\"\n  slides_url: \"https://speakerdeck.com/palkan/helvetic-ruby-2023-profiling-ruby-tests-with-swiss-precision\"\n\n- id: \"abiodun-olowode-helvetic-ruby-2023\"\n  title: \"A Sneak Peek into Ractors!\"\n  raw_title: \"A Sneak Peek into Ractors! by Abiodun Olowode\"\n  speakers:\n    - Abiodun Olowode\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    Are you tired of dealing with race conditions in your Ruby code? Introducing Ractors - an experimental feature designed for parallel execution without thread-safety concerns. But are they really as fast as threads? And are they worth the trouble? In this talk, we'll explore the ins and outs of Ractors, shedding light on how they work and helping you decide if they're right for your project\n  video_provider: \"youtube\"\n  video_id: \"GhPAMDdOnU0\"\n\n- id: \"karen-jex-helvetic-ruby-2023\"\n  title: \"How to Keep your Database Happy\"\n  raw_title: \"How to Keep your Database Happy by Karen Jex\"\n  speakers:\n    - Karen Jex\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    You don't want to spend too much time looking after your database; you've got better things to do with your time, but you do want your database to run smoothly and perform well. Fortunately, there are a few simple things that you can do to make sure your database ticks along nicely in the background.\n    I've put together my top 5 tips, based on things that have been useful to me as a DBA. The focus will be on Postgres, but most of the tips are also relevant to other databases. These are things you can put in place, without too much effort, to make sure your database works well.\n  video_provider: \"youtube\"\n  video_id: \"y13fs-q4WGo\"\n\n- id: \"harriet-oughton-helvetic-ruby-2023\"\n  title: \"Postcards From An Early-Career Developer's First Months\"\n  raw_title: \"Postcards From An Early-Career Developer's First Months by Harriet Oughton\"\n  speakers:\n    - Harriet Oughton\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    Postcards From An Early-Career Developer's First Months: Recognising the Struggles and the Joys.\n\n    In the fast-paced learning environment of software development, it can be hard for more established developers to remember the experience of someone finding their feet in their first software role. This talk aims to remind most of us of the common things that new developers learn, grapple with and celebrate in the first few months on the job, and for the juniors themselves, to expose how common these struggles are (and hopefully provide some pointers along the way!).\n  video_provider: \"youtube\"\n  video_id: \"jNY4CViM76U\"\n\n# Lunch\n\n- id: \"ju-liu-helvetic-ruby-2023\"\n  title: \"The Functional Alternative\"\n  raw_title: \"The Functional Alternative by Ju Liu\"\n  speakers:\n    - Ju Liu\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    We'll start with a simple Ruby Kata and solve it together, live, with imperative programming. We'll then fix the many, many, many things we got wrong. Then we'll solve the problem again using patterns from functional programming. You'll leave this talk with a clear and concrete example of why functional programming matters, why immutable code matters, and why it can help you writing bug-free code. The next time you find yourself writing imperative code, you'll think about... the functional alternative.\n  video_provider: \"youtube\"\n  video_id: \"Fm099cLXdV8\"\n\n- id: \"christina-serra-helvetic-ruby-2023\"\n  title: \"Lightning Talk: Five Minutes of a Random Stranger Talking About Creativity\"\n  raw_title: \"Five Minutes of a Random Stranger Talking About Creativity by Christina Serra\"\n  speakers:\n    - Christina Serra\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    Five Minutes of a Random Stranger Talking About Creativity (and why you should squeeze it into your life)\n\n    A lightning talk from the Helvetic Ruby 2023 conference.\n\n    \"Creative people are just born that way\", right? Contrary to this opinion, like so many other things humans do, this too is a learned behavior! Lucky for us, right? Kinda like how “Some people are just born to program”, right? It may be more a mix of early and continued cultivated exposure and time+interest than lucky genes. Cultivating our creative juices has its benefits! This is a short 5-minute reminder on the why and how you can be even more awesome and add creativity back into your life, to help improve mental health, capacity for problem solving and joy. Like exercise, but more fun.\n  video_provider: \"youtube\"\n  video_id: \"l1UG9lYDnNk\"\n\n- id: \"severin-rz-helvetic-ruby-2023\"\n  title: \"Lightning Talk: Sliced Ruby - Enforcing Module Boundaries with private_const and packwerk\"\n  raw_title: \"Sliced Ruby: Enforcing module boundaries with private_const and packwerk by Severin Ráz\"\n  speakers:\n    - Severin Ráz\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    A lightning talk from the Helvetic Ruby 2023 conference.\n\n    Ideas on how ruby can help you protect your architecture. I'll work through an example of tightly coupled classes where it's not apparent who calls who and who should be allowed to call who. This is refactored in a few steps towards a design where the ruby interpreter and the packwerk gem prevent certain errors alltogether.\n  video_provider: \"youtube\"\n  video_id: \"ZBoiu0yUrwI\"\n\n- id: \"josua-schmid-helvetic-ruby-2023\"\n  title: \"Lightning Talk: Conventionally-Typed Ruby\"\n  raw_title: \"Conventionally-typed Ruby by Josua Schmid\"\n  speakers:\n    - Josua Schmid\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    A lightning talk from Helvetic Ruby 2023.\n\n    Dynamically typed vs statically typed, come-on… Why can we not have the best of both worlds? I'd like to introduce the theoretical concept of a conventionally-typed Ruby.\n  video_provider: \"youtube\"\n  video_id: \"MIl1AFWoAXQ\"\n\n- id: \"lucian-ghinda-helvetic-ruby-2023\"\n  title: \"Lightning Talk: Ideas For Growing Our Ruby Community\"\n  raw_title: \"Ideas for growing our Ruby community by Lucian Ghinda\"\n  speakers:\n    - Lucian Ghinda\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    A lightning talk from the Helvetic Ruby 2023 conference.\n\n    I want to touch on some points about bringing more people into our Ruby community.\n\n    I will talk more about what we can share online that could reach someone interested in learning Ruby: type of articles, project ideas, developer experience, starting kits, and some other points.\n\n    The purpose of this talk is to start a conversation or to invite people to share more.\n  video_provider: \"youtube\"\n  video_id: \"qrXscRsObvo\"\n\n- id: \"isabel-steiner-helvetic-ruby-2023\"\n  title: \"How To Bootstrap Your Software Startup\"\n  raw_title: \"How to bootstrap your software startup by Isabel Steiner\"\n  speakers:\n    - Isabel Steiner\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    In 2022, a close friend and former co-worker and myself founded The Happy Lab GmbH and we only had one purpose for the company: A place where happy co-workers develop products to make users happy.\n\n    In 6 months we went from exploring the problem space to come up with the first hypotheses a to a platform with recurring revenue by following the principles of lean startup and applying all the techniques and methods we have learned in our 15+ years in product management, engineering and leadership positions. In my talk, I will walk the audience through our bootstrapping steps and learnings.\n  video_provider: \"youtube\"\n  video_id: \"20gPjHP5szQ\"\n\n- id: \"cristian-planas-helvetic-ruby-2023\"\n  title: \"A Rails Performance Guidebook: from 0 to 1B requests/day\"\n  raw_title: \"A Rails performance guidebook: from 0 to 1B requests/day by Cristian Planas and Anatoly Mikhaylov\"\n  speakers:\n    - Cristian Planas\n    - Anatoly Mikhaylov\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    Building a feature is not good enough anymore: all your work won't be of use if it's not performant enough. So how to improve performance? After all, performance is not an easy discipline to master: all slow applications are slow in their own way, meaning that there is no silver bullet for these kinds of problems.\n\n    In this presentation, we will guide you across patterns, strategies, and little tricks to improve performance. We will do that by sharing real stories of our daily experience facing and solving real performance issues in an application that daily serves billions of requests per day.\n  video_provider: \"youtube\"\n  video_id: \"uDb71s9MtVk\"\n\n- id: \"raia-helvetic-ruby-2023\"\n  title: \"Anatomy of a Sonic Pi Song\"\n  raw_title: \"Anatomy of a Sonic Pi Song by Raia\"\n  speakers:\n    - Rebecca Fernandes\n  event_name: \"Helvetic Ruby 2023\"\n  date: \"2023-11-24\"\n  published_at: \"2023-12-08\"\n  description: |-\n    Have you ever considered what makes a \"good\" song? Maybe it's a sweet melody, or the beat that keeps you pushing through to the end of a workout. Whatever the use case, Ruby-based Sonic Pi can synthesize it. Raia guides participants through coding a range of song components. Together, we'll build a band of live loops including: rhythm sections, melody, chord progressions and audio embellishments. We'll build a song that can be mixed and modified at will and in the process, learn some key elements of what makes Sonic Pi \"sing.”\n  video_provider: \"youtube\"\n  video_id: \"A7owAl1Q6PQ\"\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2024/cfp.yml",
    "content": "---\n- link: \"https://helvetic-ruby.ch/call-for-speakers\"\n  open_date: \"2024-01-19\"\n  close_date: \"2024-02-25\"\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2024/event.yml",
    "content": "---\nid: \"PL4jngagx9f7RGaAjXE0PR3z_jsA9cyCji\"\ntitle: \"Helvetic Ruby 2024\"\nkind: \"conference\"\nlocation: \"Zurich, Switzerland\"\ndescription: |-\n  Talks from the 2024 edition of Helvetic Ruby, a local Ruby conference in Switzerland.\npublished_at: \"2024-06-04\"\nstart_date: \"2024-05-17\"\nend_date: \"2024-05-17\"\nchannel_id: \"UChetoakh7nU0EXrKN8QFUUA\"\nyear: 2024\nbanner_background: \"#F2EDE1\"\nfeatured_background: \"#F2EDE1\"\nfeatured_color: \"#810202\"\nwebsite: \"https://helvetic-ruby.ch/2024\"\ncoordinates:\n  latitude: 47.3893338\n  longitude: 8.5157189\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2024/schedule.yml",
    "content": "# Schedule: https://helvetic-ruby.ch/2024/schedule/\n---\ndays:\n  - name: \"Day 0\"\n    date: \"2024-05-16\"\n    grid:\n      - start_time: \"14:30\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - title: \"Open Source Pairing and Office Hours\"\n            description: |\n              We've booked a room in the Colab co-working space for community members to gather and work together on open source. Some ideas:\n\n                * showcase a library you've been working on,\n                * talk about features you'd like to see in a library or framework,\n                * collaborate on a bug report,\n                * improve documentation,\n                * hang out with like-minded individuals even if you don't have an idea what to work on in advance.\n\n              The open source office hours are also an opportunity to meet maintainers from the Ruby ecosystem in person. Ask questions, discuss new ideas, fix bugs together.\n\n              Who will be there?\n\n              * Marco Roth, open source contributor currently focusing on the Hotwire ecosystem\n              * Sarah Lima and Dimiter Petrov from thoughtbot\n              * Yves Senn, Rails Core team Alumnus\n              * Pascal Simon from Puzzle, maintainers of Hitobito\n\n              You! Bring your ideas and questions.\n\n  - name: \"Day 1\"\n    date: \"2024-05-17\"\n    grid:\n      - start_time: \"08:45\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Arrival & Registration\n\n      - start_time: \"09:30\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Conference Start\n\n      - start_time: \"09:45\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:45\"\n        end_time: \"12:15\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"15:36\"\n        slots: 1\n\n      - start_time: \"15:36\"\n        end_time: \"15:42\"\n        slots: 1\n\n      - start_time: \"15:42\"\n        end_time: \"15:48\"\n        slots: 1\n\n      - start_time: \"15:48\"\n        end_time: \"15:54\"\n        slots: 1\n\n      - start_time: \"15:54\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"18:15\"\n        slots: 1\n        items:\n          - Final Words\n\n      - start_time: \"18:15\"\n        end_time: \"19:45\"\n        slots: 1\n        items:\n          - After Party at the Conference Venue\n\n      - start_time: \"19:45\"\n        end_time: \"21:00\"\n        slots: 1\n        items:\n          - After After Party at \"Frau Gerolds Garten\"\n\n  - name: \"Post Conference\"\n    date: \"2024-05-18\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Hike from Triemli to Uetliberg Peak\n\n      - start_time: \"11:00\"\n        end_time: \"12:00\"\n        slots: 1\n        items:\n          - Arrival at Uetliberg Peak\n\n      - start_time: \"12:00\"\n        end_time: \"12:00\"\n        slots: 1\n        items:\n          - Open End\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold Sponsors\"\n      description: |-\n        Highest tier sponsor\n      level: 1\n      sponsors:\n        - name: \"Better Stack\"\n          website: \"https://betterstack.com/\"\n          slug: \"betterstack\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/betterstack.svg\"\n\n    - name: \"Silver Sponsors\"\n      description: |-\n        Second tier sponsor\n      level: 2\n      sponsors:\n        - name: \"Endress+Hauser\"\n          website: \"https://www.endress.com\"\n          slug: \"endress-hauser\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/E+H.png\"\n\n        - name: \"RoRvsWild\"\n          website: \"https://www.rorvswild.com/\"\n          slug: \"rorvswild\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/rorvswild.svg\"\n\n        - name: \"QoQa\"\n          website: \"https://www.qoqa.ch/\"\n          slug: \"qoqa\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/qoqa.svg\"\n\n    - name: \"Bronze Sponsors\"\n      description: |-\n        Third tier sponsor\n      level: 3\n      sponsors:\n        - name: \"Renuo\"\n          website: \"https://www.renuo.ch/\"\n          slug: \"renuo\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/renuo.png\"\n\n        - name: \"Deplo.io\"\n          website: \"https://deplo.io/\"\n          slug: \"deplo-io\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/deploio.svg\"\n\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/appsignal.svg\"\n\n        - name: \"Puzzle ITC\"\n          website: \"https://www.puzzle.ch/\"\n          slug: \"puzzleitc\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/puzzle.svg\"\n\n        - name: \"Pia Planer\"\n          website: \"https://pia-planer.ch/\"\n          slug: \"piaplaner\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/pia.png\"\n\n        - name: \"atpoint\"\n          website: \"https://atpoint.ch/\"\n          slug: \"atpoint\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/atpoint.svg\"\n\n    - name: \"Travel Sponsors\"\n      description: |-\n        Sponsors for travel\n      level: 4\n      sponsors:\n        - name: \"Manas\"\n          website: \"https://manas.tech/\"\n          slug: \"manas\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/manas.svg\"\n\n        - name: \"Netlify\"\n          website: \"https://www.netlify.com/\"\n          slug: \"netlify\"\n          logo_url: \"https://helvetic-ruby.ch/2024/images/sponsors/netlify.svg\"\n\n    # https://helvetic-ruby.ch/2024/#sponsors\n    - name: \"Partners\"\n      description: |-\n        Partners\n      level: 5\n      sponsors: []\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2024/venue.yml",
    "content": "---\nname: \"Technopark Zürich\"\n\naddress:\n  street: \"Technoparkstrasse 1\"\n  city: \"Zurich\"\n  region: \"\"\n  postal_code: \"8005\"\n  country: \"Switzerland\"\n  country_code: \"CH\"\n  display: \"Technoparkstrasse 1, 8005 Zürich, Switzerland\"\n\ncoordinates:\n  latitude: 47.3893338\n  longitude: 8.5157189\n\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=47.3893338,8.5157189\"\n  apple: \"https://maps.apple.com/?q=Technopark,+Technoparkstrasse+1,+Zürich\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=47.3893338&mlon=8.5157189&zoom=17\"\n\nhotels:\n  - name: \"Novotel Zürich City-West\"\n    address:\n      street: \"13 Turbinenplatz\"\n      city: \"Zurich\"\n      region: \"\"\n      postal_code: \"8005\"\n      country: \"Switzerland\"\n      country_code: \"CH\"\n      display: \"Turbinenplatz 13, 8005 Zürich, Switzerland\"\n    description: |-\n      Adjacent to the conference venue\n    coordinates:\n      latitude: 47.3891116\n      longitude: 8.5168028\n    maps:\n      google: \"https://www.google.com/maps/search/?api=1&query=47.3891116,8.5168028\"\n\n  - name: \"Ibis Zürich City-West\"\n    address:\n      street: \"11 Schiffbaustrasse\"\n      city: \"Zurich\"\n      region: \"\"\n      postal_code: \"8005\"\n      country: \"Switzerland\"\n      country_code: \"CH\"\n      display: \"Schiffbaustrasse 11, 8005 Zürich, Switzerland\"\n    description: |-\n      Adjacent to the conference venue\n    coordinates:\n      latitude: 47.3889746\n      longitude: 8.5170924\n    maps:\n      google: \"https://www.google.com/maps/search/?api=1&query=47.3889746,8.5170924\"\n\n  - name: \"Ibis Budget Zürich City-West\"\n    address:\n      street: \"2 Technoparkstrasse\"\n      city: \"Zurich\"\n      region: \"\"\n      postal_code: \"8005\"\n      country: \"Switzerland\"\n      country_code: \"CH\"\n      display: \"Technoparkstrasse 2, 8005 Zürich, Switzerland\"\n    description: |-\n      Adjacent to the conference venue\n    coordinates:\n      latitude: 47.3889874\n      longitude: 8.5162188\n    maps:\n      google: \"https://www.google.com/maps/search/?api=1&query=47.3889874,8.5162188\"\n\n  - name: \"25hours Hotel Zürich West\"\n    address:\n      street: \"102 Pfingstweidstrasse\"\n      city: \"Zurich\"\n      region: \"\"\n      postal_code: \"8005\"\n      country: \"Switzerland\"\n      country_code: \"CH\"\n      display: \"Pfingstweidstrasse 102, 8005 Zürich, Switzerland\"\n    description: |-\n      Walking distance, conference ticket discount available\n    coordinates:\n      latitude: 47.3909662\n      longitude: 8.5095164\n    maps:\n      google: \"https://www.google.com/maps/search/?api=1&query=47.3909662,8.5095164\"\n\n  - name: \"Hotel Züri by Fassbind\"\n    address:\n      street: \"254 Heinrichstrasse\"\n      city: \"Zurich\"\n      region: \"\"\n      postal_code: \"8005\"\n      country: \"Switzerland\"\n      country_code: \"CH\"\n      display: \"Heinrichstrasse 254, 8005 Zürich, Switzerland\"\n    description: |-\n      Walking distance from the venue\n    coordinates:\n      latitude: 47.389367\n      longitude: 8.5220483\n    maps:\n      google: \"https://www.google.com/maps/search/?api=1&query=47.389367,8.5220483\"\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2024/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"marco-roth-helvetic-ruby-2024\"\n  title: \"Revisiting the Hotwire Landscape after Turbo 8\"\n  raw_title: \"Revisiting the Hotwire Landscape after Turbo 8 by Marco Roth\"\n  speakers:\n    - Marco Roth\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-07-01\"\n  slides_url: \"https://speakerdeck.com/marcoroth/the-hotwire-landscape-after-turbo-8-at-helvetic-ruby-2024-zurich\"\n  description: |-\n    Hotwire has significantly altered the landscape of building interactive web applications with Ruby on Rails, marking a pivotal evolution toward seamless Full-Stack development.\n\n    With the release of Turbo 8, the ecosystem has gained new momentum, influencing how developers approach application design and interaction.\n\n    This session, led by Marco, a core maintainer of Stimulus, StimulusReflex, and CableReady, delves into capabilities introduced with Turbo 8, reevaluating its impact on the whole Rails and Hotwire ecosystem.\n  video_provider: \"youtube\"\n  video_id: \"cBlHywmKId8\"\n\n- id: \"katie-miller-helvetic-ruby-2024\"\n  title: \"The Boring Bits Bite Back\"\n  raw_title: \"The Boring Bits Bite Back by Katie Miller\"\n  speakers:\n    - Katie Miller\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-07-01\"\n  slides_url: \"https://helvetic-ruby.ch/2024/presentations/main_talks/Katie_Miller_The_Boring_Bits_Bite_Back.pdf\"\n  description: |-\n    Big is better right? Big data, big features, big customers. With those big customers comes requests for big acronyms like SAML, SCIM and RBAC. Getting those implemented depends on a strong foundation. The boring bits that were glossed over when building the company. Users, Accounts, Authorization, Billing… We can prevent heartache, tech debt and stress by getting a handle on them early on. I’ll talk about how to think about these basics as you go without overthinking it so hopefully you spend less time re-building the basics and more time creating products that wow people.\n  video_provider: \"youtube\"\n  video_id: \"6g5phlssviM\"\n\n- id: \"andy-pfister-helvetic-ruby-2024\"\n  title: \"Lessons learned from running Rails apps on-premise\"\n  raw_title: \"Lessons learned from running Rails apps on-premise by  Andy Pfister\"\n  speakers:\n    - Andy Pfister\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-07-03\"\n  slides_url: \"https://helvetic-ruby.ch/2024/presentations/main_talks/Andy_Pfister_Lessons_Learned.pdf\"\n  description: |-\n    37signals recently published a new software called Campfire. The main catch of it is \"you only pay once and can host it yourself.\" For our customer, we have been shipping three Rails apps for years to their customer's on-premise environments. Since these environments tend to be very different from each other, the deployment process is optimized for Linux and Windows systems, PostgreSQL, and Microsoft SQL servers, as well as installation without any internet access. In this talk, I'd like to share how we approach this, lessons learned over the years, and how you might apply this to your apps.\n  video_provider: \"youtube\"\n  video_id: \"zh6jfFDHo8M\"\n\n- id: \"youssef-boulkaid-helvetic-ruby-2024\"\n  title: \"Ask your logs\"\n  raw_title: \"Ask your logs by Youssef Boulkaid\"\n  speakers:\n    - Youssef Boulkaid\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-06-29\"\n  slides_url: \"https://helvetic-ruby.ch/2024/presentations/main_talks/Youssef_Boulkaid_Ask_Your_Logs.pdf\"\n  description: |-\n    Logging is often an afterthought when we put our apps in production. It's there, it's configured by default and it's... good enough?\n\n    If you have ever tried to debug a production issue by digging in your application logs, you know that it is a challenge to find the information you need in the gigabyte-sized haystack that is the default rails log output.\n\n    In this talk, let's explore how we can use structured logging to turn our logs into data and use dedicated tools to ask — and answer — some non-obvious questions of our logs.\n  video_provider: \"youtube\"\n  video_id: \"_NcU_Dlq8R8\"\n\n- id: \"daniel-colson-helvetic-ruby-2024\"\n  title: \"The Very Hungry Transaction\"\n  raw_title: \"The Very Hungry Transaction by Daniel Colson\"\n  speakers:\n    - Daniel Colson\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-06-27\"\n  slides_url: \"https://helvetic-ruby.ch/2024/presentations/main_talks/Daniel_Colson_The_Very_Hungry_Transaction.pdf\"\n  description: |-\n    The story begins with a little database transaction. As the days go by, more and more business requirements cause the transaction to grow in size. We soon discover that it isn't a little transaction anymore, and it now poses a serious risk to our application and business. What went wrong, and how can we fix it?\n\n    In this talk, we'll witness a database transaction gradually grow into a liability. We'll uncover some common but problematic patterns that can put our data integrity and database health at risk, and then offer strategies for fixing and preventing these patterns.\n  video_provider: \"youtube\"\n  video_id: \"sGlpbp11SY4\"\n\n- id: \"dvid-halsz-helvetic-ruby-2024\"\n  title: \"Lightning Talk: How to use Arel? Wrong answers only!\"\n  raw_title: \"How to use Arel? Wrong answers only! by Dávid Halász\"\n  speakers:\n    - Dávid Halász\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-06-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"KJY1IPheVAk\"\n\n- id: \"sarah-lima-helvetic-ruby-2024\"\n  title: \"Lightning Talk: Avoiding Sneaky Testing Antipatterns\"\n  raw_title: \"Avoiding Sneaky Testing Antipatterns by Sarah Lima\"\n  speakers:\n    - Sarah Lima\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"m-cxOc5wgUU\"\n\n- id: \"roland-studer-helvetic-ruby-2024\"\n  title: \"Lightning Talk: Phantastic Phlex\"\n  raw_title: \"Phantastic Phlex by Roland Studer\"\n  speakers:\n    - Roland Studer\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"n0mDMlC4O80\"\n\n- id: \"jenda-tovarys-helvetic-ruby-2024\"\n  title: \"Lightning Talk: 200k users in 3 years: How to do developer marketing\"\n  raw_title: \"200k users in 3 years: How to do developer marketing by Jenda Tovarys\"\n  speakers:\n    - Jenda Tovarys\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-07-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"AxFBjiOZqO0\"\n\n- id: \"marion-schleifer-helvetic-ruby-2024\"\n  title: \"Lightning Talk: On a mission for equality and diversity in tech\"\n  raw_title: \"On a mission for equality and diversity in tech by Marion Schleifer\"\n  speakers:\n    - Marion Schleifer\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-06-25\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"2tY3aEtInls\"\n\n- id: \"hilary-stohs-krause-helvetic-ruby-2024\"\n  title: \"How to Accessibility if You’re Mostly Back-End\"\n  raw_title: \"How to Accessibility if You’re Mostly Back-End by Hilary Stohs-Krause\"\n  speakers:\n    - Hilary Stohs-Krause\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-07-15\"\n  slides_url: \"https://helvetic-ruby.ch/2024/presentations/main_talks/Hilary_Stohs_Krause_How_To_Accessibility_If_You_Are_Mostly_Back-End.pdf\"\n  description: |-\n    When we think about “accessibility”, most of us associate it with design, HTML, CSS - in other words, the front-end. If you work primarily on the back-end of the tech stack, it’s easy to assume that your role is disengaged from accessibility concerns.\n\n    In fact, there are multiple ways back-end devs can impact accessibility, both for external users and for colleagues.\n\n    In this talk, we’ll walk through everything from APIs to specs to Ruby code to documentation, using examples throughout, to demonstrate how even those of us who rarely touch HTML can positively impact accessibility for all.\n  video_provider: \"youtube\"\n  video_id: \"4TQzELedOGI\"\n\n- id: \"johannes-mller-helvetic-ruby-2024\"\n  title: \"The Power of Crystal: A language for humans and computers\"\n  raw_title: \"The Power of Crystal: A language for humans and computers by Johannes Müller\"\n  speakers:\n    - Johannes Müller\n  event_name: \"Helvetic Ruby 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-07-01\"\n  slides_url: \"https://helvetic-ruby.ch/2024/presentations/main_talks/Johannes_Muller_Power%20of%20Crystal_A_language_for%20humans_and_computers.pdf\"\n  description: |-\n    Crystal is a language with a focus on developer happiness, like Ruby. The syntax and OOP model resemble that and any Ruby developer feels right at home.\n\n    It's statically typed and compiles to native code, making it intrinsically type safe and blazingly fast. Built-in type inference makes most type annotations unnecessary, resulting in easy to read and clean code.\n\n    It can be a good asset for performance-critical applications and is very approachable for Rubyists\n\n    Crystal is a joy to work with and having it in your toolbox is an asset, even when writing Ruby code.\n  video_provider: \"youtube\"\n  video_id: \"XdOh82qLzZQ\"\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2025/cfp.yml",
    "content": "---\n- link: \"https://helvetic-ruby.ch/call-for-speakers\"\n  open_date: \"2024-12-09\"\n  close_date: \"2025-01-29\"\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2025/event.yml",
    "content": "---\nid: \"PL4jngagx9f7SFyP6YwC_NkOsHtmyj4FYh\"\ntitle: \"Helvetic Ruby 2025\"\nlocation: \"Geneva, Switzerland\"\nkind: \"conference\"\ndescription: |-\n  Helvetic Ruby 2025 is a single-track conference for Ruby programming language enthusiasts and professionals from Switzerland and abroad.\npublished_at: \"2025-06-26\"\nstart_date: \"2025-05-22\"\nend_date: \"2025-05-23\"\nchannel_id: \"UChetoakh7nU0EXrKN8QFUUA\"\nyear: 2025\nbanner_background: \"#F2EDE1\"\nfeatured_background: \"#F2EDE1\"\nfeatured_color: \"#810202\"\nwebsite: \"https://helvetic-ruby.ch\"\ncoordinates:\n  latitude: 46.2094841\n  longitude: 6.1393365\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2025/schedule.yml",
    "content": "# Schedule: https://helvetic-ruby.ch/schedule/\n---\ndays:\n  - name: \"Community Day\"\n    date: \"2025-05-22\"\n    grid:\n      - start_time: \"13:15\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - title: \"Community hangout\"\n            description: |-\n              We've reserved a little space besides the workshops to chat or work with other Ruby folks.\n\n      - start_time: \"13:30\"\n        end_time: \"16:00\"\n        slots: 2\n\n  - name: \"Conference Day\"\n    date: \"2025-05-23\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Arrival & Registration\n\n      - start_time: \"09:30\"\n        end_time: \"09:40\"\n        slots: 1\n        items:\n          - Opening words\n\n      - start_time: \"09:40\"\n        end_time: \"10:10\"\n        slots: 1\n\n      - start_time: \"10:10\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:30\"\n        end_time: \"\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"12:15\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"15:38\"\n        slots: 1\n\n      - start_time: \"15:38\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"15:45\"\n        end_time: \"15:52\"\n        slots: 1\n\n      - start_time: \"15:52\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"18:15\"\n        slots: 1\n        items:\n          - Final Words\n\n      - start_time: \"18:15\"\n        end_time: \"20:20\"\n        slots: 1\n        items:\n          - title: \"After Party\"\n            description: |-\n              at the Conference Venue\n\n      - start_time: \"20:20\"\n        end_time: \"Open\"\n        slots: 1\n        items:\n          - title: \"After after party\"\n            description: |-\n              We leave the venue and head to bars and restaurants\n\n  - name: \"Post-conference activities\"\n    date: \"2025-05-24\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"12:00\"\n        slots: 1\n        items:\n          - title: \"Guided tour of CERN\"\n            description: |-\n              Booked out BUT you can visit CERN for free, individually or in small groups anytime. Check on https://home.cern\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Silver\"\n      description: |-\n        Silver tier sponsors of Helvetic Ruby 2025\n      level: 1\n      sponsors:\n        - name: \"RoRvsWild\"\n          website: \"https://www.rorvswild.com/\"\n          slug: \"RoRvsWild\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/rorvswild.svg\"\n\n        - name: \"QoQa\"\n          website: \"https://www.qoqa.ch/\"\n          slug: \"QoQa\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/qoqa.svg\"\n\n        - name: \"Endress+Hauser\"\n          website: \"https://www.endress.com\"\n          slug: \"EndressHauser\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/E+H.png\"\n\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"AppSignal\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/appsignal.svg\"\n\n    - name: \"Bronze\"\n      description: |-\n        Bronze tier sponsors of Helvetic Ruby 2025\n      level: 2\n      sponsors:\n        - name: \"Puzzle ITC\"\n          website: \"https://www.puzzle.ch/\"\n          slug: \"PuzzleITC\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/puzzle.svg\"\n\n        - name: \"Renuo\"\n          website: \"https://www.renuo.ch/\"\n          slug: \"Renuo\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/renuo.png\"\n\n        - name: \"Pia Planer\"\n          website: \"https://pia-planer.ch/\"\n          slug: \"PiaPlaner\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/pia.png\"\n\n        - name: \"Deplo.io\"\n          website: \"https://deplo.io/\"\n          slug: \"deplo-io\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/deploio.svg\"\n\n    - name: \"Travel Sponsors\"\n      description: |-\n        Travel sponsors of Helvetic Ruby 2025\n      level: 3\n      sponsors:\n        - name: \"thoughtbot\"\n          website: \"https://thoughtbot.com\"\n          slug: \"thoughtbot\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/thoughtbot.svg\"\n\n        - name: \"GitHub\"\n          website: \"https://github.com\"\n          slug: \"GitHub\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/github.png\"\n\n        - name: \"Scan.com\"\n          website: \"https://scan.com\"\n          slug: \"scancom\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/scan.svg\"\n\n        - name: \"Visuality\"\n          website: \"https://visuality.pl\"\n          slug: \"visualitypl\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/visuality.png\"\n\n        - name: \"Aha!\"\n          website: \"https://www.aha.io\"\n          slug: \"Aha\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/aha.svg\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"DNSimple\"\n          logo_url: \"https://helvetic-ruby.ch/images/sponsors/dnsimple.svg\"\n\n    # https://helvetic-ruby.ch/#sponsors\n    - name: \"Partners\"\n      description: |-\n        Partners\n      level: 5\n      sponsors: []\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2025/venue.yml",
    "content": "---\nname: \"Uptown Geneva\"\n\naddress:\n  street: \"Rue de la Servette 2\"\n  city: \"Geneva\"\n  region: \"Genève\"\n  postal_code: \"1201\"\n  country: \"Switzerland\"\n  country_code: \"CH\"\n  display: \"Rue de la Servette 2, 1201 Geneva, Switzerland\"\n\ncoordinates:\n  latitude: 46.2094841\n  longitude: 6.1393365\n\nmaps:\n  google: \"https://maps.app.goo.gl/n22VdjVmj9YNUfuG7\"\n  apple:\n    \"https://maps.apple.com/place?address=Rue%20du%20Cercle%206,%201201%20Geneva,%20Switzerland&coordinate=46.209535,6.139426&name=Uptown%20Geneva&place-id=IEDABB1B9EFD6BA6A&ma\\\n    p=transit\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=46.2094841&mlon=6.1393365&zoom=17\"\n\nlocations:\n  - name: \"Impact Hub Geneva\"\n    kind: \"Community Day & Workshops\"\n    url: \"https://geneva.impacthub.net\"\n    address:\n      street: \"1 Rue Fendt\"\n      city: \"Genève\"\n      region: \"Genève\"\n      postal_code: \"1201\"\n      country: \"Switzerland\"\n      country_code: \"CH\"\n      display: \"Rue Fendt 1, 1201 Geneva, Switzerland\"\n    coordinates:\n      latitude: 46.2105707\n      longitude: 6.1411865\n    maps:\n      google: \"https://www.google.com/maps/search/?api=1&query=46.2105707,6.1411865\"\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2025/videos.yml",
    "content": "# Website: https://helvetic-ruby.ch\n# Schedule: https://helvetic-ruby.ch/schedule/\n---\n## Day 1 - 2025-05-22\n\n- title: \"Workshop: Building a Live Kanban Board with Hotwire and Rails\"\n  raw_title: \"Building a Live Kanban Board with Hotwire and Rails\"\n  speakers:\n    - Piotr Witek\n    - Michał Łęcicki\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"piotr-witek-michal-lecicki-helvetic-ruby-2025\"\n  id: \"piotr-witek-michal-lecicki-helvetic-ruby-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GrpBVLsWsAAzMIy?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GrpBVLsWsAAzMIy?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GrpBVLsWsAAzMIy?format=jpg&name=large\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GrpBVLsWsAAzMIy?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GrpBVLsWsAAzMIy?format=jpg&name=large\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    We will build a fully functional Kanban board application with Rails and Hotwire. During the workshops, you will gain hands-on experience in using Hotwire: Turbo Drive and Frames, Turbo Streams with broadcasting, and Stimulus controllers fundamentals. More importantly, we will thoroughly explain the core concepts of Hotwire, giving you the knowledge and tools to build dynamic and modern applications with Rails.\n\n    The workshop session consists of short theoretical introductions with practical examples and tasks to implement. We will progressively improve the existing application by making it more dynamic and usable with Hotwire.\n\n    The workshop is ideal for those who have already heard about Hotwire, but didn’t have a chance to write a serious app with it! But if you know nothing - don’t worry, before each task, we will explain the theory. We promise to give you an inspiration to use the benefits of Hotwire whenever possible!\n\n    Repo: https://github.com/visualitypl/hotwire-kanban\n  additional_resources:\n    - name: \"visualitypl/hotwire-kanban\"\n      type: \"repo\"\n      url: \"https://github.com/visualitypl/hotwire-kanban\"\n\n- title: \"Workshop: Riffing on Ruby\"\n  raw_title: \"Riffing on Ruby\"\n  speakers:\n    - Kasper Timm Hansen\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"kasper-timm-hansen-helvetic-ruby-2025\"\n  id: \"kasper-timm-hansen-helvetic-ruby-2025\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    How’s your approach to software design doing? Do you get to feel creative? Do you get to use that creativity to build a shared understanding with your team and arrive at simpler code? You can with riffing! Riffing is a new approach that’s easy to pick up & can take you to the next level in your career.\n\n    When riffing we take full advantage of Ruby being a language, we use Ruby to speak and then program our mental model directly. We explore designs to get rapid feedback and then raise issues early. Riffing is really useful to derisk what we’re working on, ultimately leading to better communication and healthier codebases.\n\n    Repo: https://github.com/kaspth/riffing-on-rails\n\n    Used prompts: https://gist.github.com/kaspth/62138aa4783e38be94559dd05cdc705c\n  additional_resources:\n    - name: \"kaspth/riffing-on-rails\"\n      type: \"repo\"\n      url: \"https://github.com/kaspth/riffing-on-rails\"\n\n    - name: \"Used prompts\"\n      type: \"repo\"\n      url: \"https://gist.github.com/kaspth/62138aa4783e38be94559dd05cdc705c\"\n\n## Day 2 - 2025-05-23\n\n- title: \"Contributing to Ruby Core: From Local Development to Global Impact\"\n  raw_title: \"Contributing to Ruby Core: From Local Development to Global Impact\"\n  speakers:\n    - Jasveen Sandral\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"z4dRlJEhzQU\"\n  id: \"jasveen-sandral-helvetic-ruby-2025\"\n  # thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreicqotkejefvmv5hkfj3fzo4s6h6rnwhzzyi6xl7je7jjvlsv2vlja@jpeg\"\n  # thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreicqotkejefvmv5hkfj3fzo4s6h6rnwhzzyi6xl7je7jjvlsv2vlja@jpeg\"\n  # thumbnail_md: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreicqotkejefvmv5hkfj3fzo4s6h6rnwhzzyi6xl7je7jjvlsv2vlja@jpeg\"\n  # thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreicqotkejefvmv5hkfj3fzo4s6h6rnwhzzyi6xl7je7jjvlsv2vlja@jpeg\"\n  # thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreicqotkejefvmv5hkfj3fzo4s6h6rnwhzzyi6xl7je7jjvlsv2vlja@jpeg\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    Follow the journey of implementing TSV support in Ruby’s standard library, from initial concept to merged code. Through this real-world case study, learn about the Ruby core contribution process, API design considerations, and collaboration with maintainers. Discover how small improvements to Ruby’s standard library can have a significant impact on developers worldwide, while gaining practical insights for your own contributions to Ruby core.\n\n- title: \"The Test Pyramid and the Temple of Love\"\n  raw_title: \"The Test Pyramid and the Temple of Love\"\n  speakers:\n    - Ronan Limon Duparcmeur\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"eSsqnEzxvhY\"\n  id: \"ronan-limon-duparcmeur-helvetic-ruby-2025\"\n  # thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreihccscukx23ftmxq53s6l2vuckjvfey3srws7s3ptb45lmxlrpxmy@jpeg\"\n  # thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreihccscukx23ftmxq53s6l2vuckjvfey3srws7s3ptb45lmxlrpxmy@jpeg\"\n  # thumbnail_md: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreihccscukx23ftmxq53s6l2vuckjvfey3srws7s3ptb45lmxlrpxmy@jpeg\"\n  # thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreihccscukx23ftmxq53s6l2vuckjvfey3srws7s3ptb45lmxlrpxmy@jpeg\"\n  # thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreihccscukx23ftmxq53s6l2vuckjvfey3srws7s3ptb45lmxlrpxmy@jpeg\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    Come learn everything you need to know to give your Rails app a test suite worthy of the Seven Wonders of the Ancient World, thanks to a 1992 hit song by an English gothic rock band.\n\n- title: \"ActiveRecord Unveiled: Mastering Rails' ORM\"\n  raw_title: \"ActiveRecord Unveiled: Mastering Rails’ ORM\"\n  speakers:\n    - Jess Sullivan\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"B4gEyuEQaBM\"\n  id: \"jess-suillivan-helvetic-ruby-2025\"\n  # thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibbygam5df3lhyvuxk4yot45lhygza4b43diqc7u2r35kghvv6phy@jpeg\"\n  # thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibbygam5df3lhyvuxk4yot45lhygza4b43diqc7u2r35kghvv6phy@jpeg\"\n  # thumbnail_md: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibbygam5df3lhyvuxk4yot45lhygza4b43diqc7u2r35kghvv6phy@jpeg\"\n  # thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibbygam5df3lhyvuxk4yot45lhygza4b43diqc7u2r35kghvv6phy@jpeg\"\n  # thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibbygam5df3lhyvuxk4yot45lhygza4b43diqc7u2r35kghvv6phy@jpeg\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    ActiveRecord drives Rails’ seamless database interactions, but what really happens behind the scenes? In this talk, we’ll follow a developer’s journey to uncover how Rails’ ORM maps data between app and database, demystifying the key mechanisms that make Rails so powerful.\n\n- title: \"More feedback! Quantity becomes quality\"\n  raw_title: \"More feedback! Quantity becomes quality\"\n  speakers:\n    - Kyle d'Oliveira\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"w6Xr5mrszeg\"\n  id: \"kyley-d-oliveira-helvetic-ruby-2025\"\n  # thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiacayfl6vol5xumvhfdh7b3ethv7y36jtgcxvuwkg2skpu6ptumae@jpeg\"\n  # thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiacayfl6vol5xumvhfdh7b3ethv7y36jtgcxvuwkg2skpu6ptumae@jpeg\"\n  # thumbnail_md: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiacayfl6vol5xumvhfdh7b3ethv7y36jtgcxvuwkg2skpu6ptumae@jpeg\"\n  # thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiacayfl6vol5xumvhfdh7b3ethv7y36jtgcxvuwkg2skpu6ptumae@jpeg\"\n  # thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiacayfl6vol5xumvhfdh7b3ethv7y36jtgcxvuwkg2skpu6ptumae@jpeg\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    Can someone write a large quantity of high-quality code? Yes! The idea that speed sacrifices quality is a myth. The key lies in gathering ample feedback—both internal and external. Shifting focus to feedback quantity, while still prioritizing quality, enables consistent high-quality code. This talk explores supporting research and practical ways to gather feedback effectively.\n\n- title: \"Beyond Caching: Best Practices for Scaling your Rails Application\"\n  raw_title: \"Beyond Caching: Best Practices for Scaling your Rails Application\"\n  speakers:\n    - Kinsey Durham Grace\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"KM0VvqUsFXc\"\n  id: \"kinsey-durham-grace-helvetic-ruby-2025\"\n  # thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibdmh46xx4boee5ey7nk5ly4d5jzgqog2y7rcismaiqmzxnp3f6oq@jpeg\"\n  # thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibdmh46xx4boee5ey7nk5ly4d5jzgqog2y7rcismaiqmzxnp3f6oq@jpeg\"\n  # thumbnail_md: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibdmh46xx4boee5ey7nk5ly4d5jzgqog2y7rcismaiqmzxnp3f6oq@jpeg\"\n  # thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibdmh46xx4boee5ey7nk5ly4d5jzgqog2y7rcismaiqmzxnp3f6oq@jpeg\"\n  # thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibdmh46xx4boee5ey7nk5ly4d5jzgqog2y7rcismaiqmzxnp3f6oq@jpeg\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    Scaling Rails apps goes far beyond caching! Discover proven techniques to handle millions of users with confidence. We’ll dive into optimizing data, databases, dependencies, gems, and monitoring. Walk away with practical insights to elevate your Rails app to the next level.\n\n- title: \"Lightning Talk: Shaping a Great Engineering Culture & Crowing the Ruby Community\"\n  raw_title: \"Shaping a Great Engineering Culture & Crowing the Ruby Community\"\n  speakers:\n    - Magdalena Havlickova\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"tfqnqnValqk\"\n  id: \"magdalena-havlickova-helvetic-ruby-2025\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    How a Ruby-first culture was built by design at Better Stack — by embracing curiosity, not gatekeeping, investing in people over tools, and growing a team where Rails is learned and used daily (even by those who didn’t start there).\n\n- title: \"Lightning Talk: Custom RuboCop Rule\"\n  raw_title: \"Custom RuboCop Rule\"\n  speakers:\n    - Andreas Maierhofer\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"eOhoNKA8kZc\"\n  id: \"andreas-maierhofer-helvetic-ruby-2025\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    Rubocop as is a useful tool and used in a variety of ruby projects. This talk will show how to extend rubocop to surface [template methods](https://refactoring.guru/design-patte...)  in your code base. We will briefly dip into stdlib api (methods, source_location) to identify applicable methods and highlight them as rubocop warnings using a custom cop.\n\n- title: \"Lightning Talk: Bullshit Graphs\"\n  raw_title: \"Bullshit Graphs\"\n  speakers:\n    - Josua Schmid\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"4uZNjhFcyPg\"\n  id: \"josua-schmid-helvetic-ruby-2025\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    Quick ride through funny graph samples from the University of Washington lecture \"Calling Bullshit: Data Reasoning in a Digital World\"\n\n- title: \"Lightning Talk: RubyEvents.org - The platform for all things Ruby events\"\n  raw_title: \"RubyEvents.org - The platform for all things Ruby events\"\n  speakers:\n    - Marco Roth\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"1eC56s6-XKE\"\n  id: \"marco-roth-helvetic-ruby-2025\"\n  # thumbnail_xs: \"https://pbs.twimg.com/media/GrpEemrWAAAykUh?format=jpg\"\n  # thumbnail_sm: \"https://pbs.twimg.com/media/GrpEemrWAAAykUh?format=jpg\"\n  # thumbnail_md: \"https://pbs.twimg.com/media/GrpEemrWAAAykUh?format=jpg&name=large\"\n  # thumbnail_lg: \"https://pbs.twimg.com/media/GrpEemrWAAAykUh?format=jpg&name=large\"\n  # thumbnail_xl: \"https://pbs.twimg.com/media/GrpEemrWAAAykUh?format=jpg&name=large\"\n  language: \"english\"\n  slides_url: \"https://speakerdeck.com/marcoroth/rubyevents-dot-org-the-platform-for-all-things-ruby-events-at-helvetic-ruby-2025-geneva-switzerland\"\n  description: |-\n    Originally launched as RubyVideo.dev, the project has been rebranded as RubyEvents.org to better reflect its expanded mission.\n\n    RubyEvents.org aims to index all Ruby events and video talks, making them searchable, accessible, and easier to discover for the Ruby community.\n\n- title: \"Modelling the Cosmos in Ruby: Applying OOP and Domain-Driven Design to Astronomical Concepts\"\n  raw_title: \"Modelling the Cosmos in Ruby: Applying OOP and Domain-Driven Design to Astronomical Concepts\"\n  speakers:\n    - Rémy Hannequin\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"ZYWfiOM-zlY\"\n  id: \"remy-hannequin-helvetic-ruby-2025\"\n  # thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibks4vvbormcsxqzc6cjpljabapyqkcbivtlhlnuuldjsftrfxb4u@jpeg\"\n  # thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibks4vvbormcsxqzc6cjpljabapyqkcbivtlhlnuuldjsftrfxb4u@jpeg\"\n  # thumbnail_md: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibks4vvbormcsxqzc6cjpljabapyqkcbivtlhlnuuldjsftrfxb4u@jpeg\"\n  # thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibks4vvbormcsxqzc6cjpljabapyqkcbivtlhlnuuldjsftrfxb4u@jpeg\"\n  # thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreibks4vvbormcsxqzc6cjpljabapyqkcbivtlhlnuuldjsftrfxb4u@jpeg\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    Learn how to turn complex domains into elegant Ruby code! Using Astronoby (https://github.com/rhannequin/astronoby), a gem for astronomical calculations, this talk dives into applying Domain-Driven Design and OOP to model celestial phenomena. Discover practical techniques for tackling complexity, creating readable APIs, and building maintainable software. Whether you’re navigating scientific challenges or exploring new domains, this talk offers patterns for taking Ruby beyond its usual orbit.\n  additional_resources:\n    - name: \"rhannequin/astronoby\"\n      type: \"repo\"\n      url: \"https://github.com/rhannequin/astronoby\"\n\n- title: \"The art of code: Finding Aesthetics in logic. 🎨\"\n  raw_title: \"The art of code: Finding Aesthetics in logic. 🎨\"\n  speakers:\n    - Yara Debian\n  event_name: \"Helvetic Ruby 2025\"\n  date: \"2025-05-23\"\n  published_at: \"2025-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"phz2kCBv6OA\"\n  id: \"yara-debian-helvetic-ruby-2025\"\n  # thumbnail_xs: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreib23jk3lwgumlxzmhvhuxkkp5vstz6xcg3tz6eiiticrwy56rlwmi@jpeg\"\n  # thumbnail_sm: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreib23jk3lwgumlxzmhvhuxkkp5vstz6xcg3tz6eiiticrwy56rlwmi@jpeg\"\n  # thumbnail_md: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreib23jk3lwgumlxzmhvhuxkkp5vstz6xcg3tz6eiiticrwy56rlwmi@jpeg\"\n  # thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreib23jk3lwgumlxzmhvhuxkkp5vstz6xcg3tz6eiiticrwy56rlwmi@jpeg\"\n  # thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreib23jk3lwgumlxzmhvhuxkkp5vstz6xcg3tz6eiiticrwy56rlwmi@jpeg\"\n  language: \"english\"\n  slides_url: \"\"\n  description: |-\n    What if writing code and creating art aren’t as different as we think? From the blank canvas to the final product, both artists and coders follow a journey of exploration and iteration. Join us as we uncover the surprising similarities between the worlds of painting and programming—how creativity, rules, and tools shape both crafts. Could the same principles that guide an artist also guide a developer?\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2026/event.yml",
    "content": "---\nid: \"helveticruby-2026\"\ntitle: \"Helvetic Ruby 2026\"\ndescription: \"\"\nlocation: \"Zurich, Switzerland\"\nkind: \"conference\"\nstart_date: \"2026-11-19\"\nend_date: \"2026-11-20\"\nwebsite: \"https://helvetic-ruby.ch\"\nmastodon: \"https://ruby.social/@helvetic_ruby\"\nbanner_background: \"#F2EDE1\"\nfeatured_background: \"#F2EDE1\"\nfeatured_color: \"#810202\"\ncoordinates:\n  latitude: 47.3768866\n  longitude: 8.541694\n"
  },
  {
    "path": "data/helveticruby/helveticruby-2026/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://helvetic-ruby.ch\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/helveticruby/series.yml",
    "content": "---\nname: \"Helvetic Ruby\"\nwebsite: \"https://helvetic-ruby.ch\"\ntwitter: \"helvetic_ruby\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"CH\"\nyoutube_channel_name: \"HelveticRuby\"\nlanguage: \"english\"\nyoutube_channel_id: \"UChetoakh7nU0EXrKN8QFUUA\"\n"
  },
  {
    "path": "data/hirakatarb/hirakatarb-meetup/event.yml",
    "content": "---\nid: \"hirakatarb-meetup\"\ntitle: \"Hirakata.rb Meetup\"\nlocation: \"Hirakata, Japan\"\ndescription: |-\n  A Ruby community for people in and around Hirakata, Osaka. While it is rooted locally, many participants join online from across Japan, and events are currently held on an irregular basis.\nwebsite: \"https://hirakatarb.connpass.com\"\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 34.8144363\n  longitude: 135.6507278\n"
  },
  {
    "path": "data/hirakatarb/hirakatarb-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/hirakatarb/series.yml",
    "content": "---\nname: \"Hirakata.rb\"\nwebsite: \"https://hirakatarb.connpass.com\"\nkind: \"meetup\"\nfrequency: \"irregular\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/hokuriku-rubykaigi/hokuriku-rubykaigi-01/event.yml",
    "content": "---\nid: \"hokuriku-rubykaigi-01\"\ntitle: \"Hokuriku RubyKaigi 01\"\ndescription: |-\n  The inaugural Hokuriku Ruby Conference brings together three regional Ruby communities (Toyama.rb, Kanazawa.rb, and fukui.rb) to showcase diverse practical applications of Ruby, from web development to IoT systems and education.\nlocation: \"Kanazawa, Japan\"\nkind: \"conference\"\nstart_date: \"2025-12-06\"\nend_date: \"2025-12-06\"\nwebsite: \"https://regional.rubykaigi.org/hokuriku01/\"\nfeatured_background: \"#D3301E\"\nfeatured_color: \"#FFFFFF\"\nbanner_background: \"#FFFFFF\"\ncoordinates:\n  latitude: 36.5488311\n  longitude: 136.6806761\n"
  },
  {
    "path": "data/hokuriku-rubykaigi/hokuriku-rubykaigi-01/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsor\"\n      level: 1\n      sponsors:\n        - name: \"Ashita no Team\"\n          website: \"https://www.ashita-team.com/\"\n          slug: \"ashita-team\"\n          logo_url: \"https://regional.rubykaigi.org/hokuriku01/images/logo_ashitanoteam.svg\"\n\n        - name: \"Eiwa System Management Co., Ltd.\"\n          website: \"https://agile.esm.co.jp/\"\n          slug: \"esm\"\n          logo_url: \"https://regional.rubykaigi.org/hokuriku01/images/logo_esm.png\"\n\n        - name: \"Clwit Co., Ltd.\"\n          website: \"https://www.clwit.co.jp/\"\n          slug: \"clwit\"\n          logo_url: \"https://regional.rubykaigi.org/hokuriku01/images/logo_clwit.svg\"\n\n        - name: \"FJORD BOOT CAMP\"\n          website: \"https://bootcamp.fjord.jp/\"\n          slug: \"fjord\"\n          logo_url: \"https://regional.rubykaigi.org/hokuriku01/images/logo_fjord.svg\"\n\n    - name: \"Logo Production\"\n      level: 2\n      sponsors:\n        - name: \"15VISION\"\n          website: \"https://15vision.jp/\"\n          slug: \"15vision\"\n"
  },
  {
    "path": "data/hokuriku-rubykaigi/hokuriku-rubykaigi-01/venue.yml",
    "content": "---\nname: \"Ishikawa Prefectural Library\"\n\naddress:\n  street: \"2 Chome-43-1 Kodatsuno\"\n  city: \"Kanazawa\"\n  postal_code: \"920-0942\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"2 Chome-43-1 Kodatsuno, Kanazawa, Ishikawa 920-0942, Japan\"\n\ncoordinates:\n  latitude: 36.5488311\n  longitude: 136.6806761\n\nmaps:\n  google: \"https://maps.app.goo.gl/7mzCJLvkHxVkPdNV9\"\n  apple:\n    \"https://maps.apple.com/place?address=%E3%80%92920-0942,%20%E7%9F%B3%E5%B7%9D%E7%9C%8C%E9%87%91%E6%B2%A2%E5%B8%82,%20%E5%B0%8F%E7%AB%8B%E9%87%8E2%E4%B8%81%E7%9B%AE43-1&coor\\\n    dinate=36.548738,136.680302&name=Ishikawa%20Prefectural%20Library&place-id=IE374E86C57DC3BD0&map=transit\"\n"
  },
  {
    "path": "data/hokuriku-rubykaigi/hokuriku-rubykaigi-01/videos.yml",
    "content": "---\n# Keynote\n- id: \"masayoshi-takahashi-hokuriku-rubykaigi-01\"\n  title: \"Keynote: 日本Rubyの会の構造と実行とあと何か\"\n  speakers:\n    - Masayoshi Takahashi\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Overview of the 20+ year history of the Japan Ruby Association, its behind-the-scenes community support role, and recent Ruby code initiatives.\n  video_provider: \"scheduled\"\n  video_id: \"masayoshi-takahashi-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  slides_url: \"https://speakerdeck.com/takahashim/hokurikurk01\"\n\n# Regular Sessions\n- id: \"taketo-takashima-hokuriku-rubykaigi-01\"\n  title: \"Ruby で作る大規模イベントネットワーク構築・運用支援システム TTDB\"\n  speakers:\n    - Taketo Takashima\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Integrated web application managing ShowNet tasks, network equipment, IP addresses, and authentication for large-scale event network construction and operation support.\n  video_provider: \"scheduled\"\n  video_id: \"taketo-takashima-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  slides_url: \"https://speakerdeck.com/taketo1113/ruby-dezuo-ruda-gui-mo-ibentonetutowakugou-zhu-yun-yong-zhi-yuan-sisutemu-ttdb\"\n\n- id: \"yudai-takada-hokuriku-rubykaigi-01\"\n  title: \"計算機科学をRubyと歩む 〜DFA型正規表現エンジンをつくる～\"\n  speakers:\n    - Yudai Takada\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Building a DFA-type regex engine in approximately 400 lines of Ruby code, implementing finite automaton regex with focus on algorithm essentials.\n  video_provider: \"scheduled\"\n  video_id: \"yudai-takada-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  slides_url: \"https://speakerdeck.com/ydah/build-dfa-regex-engine-in-ruby-b97a5909-5b37-42bc-96ea-83f205303287\"\n\n- id: \"taiju-higashi-hokuriku-rubykaigi-01\"\n  title: \"Ruby DSLでMinecraftを改造できるようにする 〜パパのRuby、娘のMinecraft〜\"\n  speakers:\n    - Taiju Higashi\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Creating an intuitive Ruby DSL to manipulate Minecraft, bridging programming work with a child's gameplay.\n  video_provider: \"scheduled\"\n  video_id: \"taiju-higashi-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  additional_resources:\n    - name: \"taiju/mc-presentation\"\n      type: \"repo\"\n      url: \"https://github.com/taiju/mc-presentation\"\n\n- id: \"ken-muryoi-hokuriku-rubykaigi-01\"\n  title: \"Rubyで鍛える仕組み化プロヂュース力\"\n  speakers:\n    - Ken Muryoi\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Using Ruby for automation and culture development beyond product code implementation, strengthening systems design skills.\n  video_provider: \"scheduled\"\n  video_id: \"ken-muryoi-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  slides_url: \"https://speakerdeck.com/muryoimpl/rubydeduan-erushi-zu-mihua-purodiyusuli\"\n\n- id: \"okura-masafumi-hokuriku-rubykaigi-01\"\n  title: \"Rubyで作る静的サイト\"\n  speakers:\n    - OKURA Masafumi\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Comparison of Jekyll, Middleman, Nanoc, and Bridgetown static site generators with latest developments.\n  video_provider: \"scheduled\"\n  video_id: \"okura-masafumi-hokuriku-rubykaigi-01\"\n  slides_url: \"https://speakerdeck.com/okuramasafumi/developing-static-sites-with-ruby\"\n  language: \"japanese\"\n\n- id: \"yusuke-nakamura-hokuriku-rubykaigi-01\"\n  title: \"Kaigi on Rails 2025におけるsubscreenの実装について\"\n  speakers:\n    - Yusuke Nakamura\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Real-time transcription/translation display system using Falcon, configuration details, and operational challenges at Kaigi on Rails 2025.\n  video_provider: \"scheduled\"\n  video_id: \"yusuke-nakamura-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  slides_url: \"https://slide.rabbit-shocker.org/authors/unasuke/hokurikurk01/\"\n\n- id: \"moriyuki-hirata-hokuriku-rubykaigi-01\"\n  title: \"Ruby受託事業マネジメントの10年\"\n  speakers:\n    - Moriyuki Hirata\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Organizational management evolution, industry changes, and remote-first operations from a Fukui-based Ruby consulting firm over ten years.\n  video_provider: \"scheduled\"\n  video_id: \"moriyuki-hirata-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n\n# Lightning Talks\n- id: \"yukimitsu-izawa-hokuriku-rubykaigi-01\"\n  title: \"Lightning Talk: Rubyで守るわが家の安心：IoTセンサーネットワーク『ゆきそっく』の実践\"\n  speakers:\n    - Yukimitsu Izawa\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Smart home security system combining TWE-Lite wireless modules, reed switches, Raspberry Pi, and Rails integration.\n  video_provider: \"scheduled\"\n  video_id: \"yukimitsu-izawa-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  slides_url: \"https://speakerdeck.com/izawa/rubydeshou-ruwo-gajia-noan-xin-iotsensa-netutowaku-yukisotuku-noshi-jian\"\n\n- id: \"betachelsea-hokuriku-rubykaigi-01\"\n  title: \"Lightning Talk: 猫の健康を見守りたい！実践 Raspberry Pi + Ruby\"\n  speakers:\n    - betachelsea\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Multi-cat environment toilet tracking system using identification technology with Raspberry Pi and Ruby.\n  video_provider: \"scheduled\"\n  video_id: \"betachelsea-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  slides_url: \"https://speakerdeck.com/betachelsea/mao-nojian-kang-wojian-shou-ritai-shi-jian-raspberry-pi-plus-ruby\"\n\n- id: \"5hun-hokuriku-rubykaigi-01\"\n  title: \"Lightning Talk: 与信管理を形にする：Rubyの柔軟性が支える高速データ収集・自動化基盤\"\n  speakers:\n    - 5hun\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Enterprise financial evaluation system integrating dozens of public and proprietary data sources for credit risk analysis.\n  video_provider: \"scheduled\"\n  video_id: \"5hun-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  slides_url: \"https://speakerdeck.com/5hun/yu-xin-guan-li-woxing-nisuru-ruby-norou-ruan-xing-gazhi-erugao-su-detashou-ji-zi-dong-hua-ji-pan\"\n\n- id: \"pndcat-hokuriku-rubykaigi-01\"\n  title: \"Lightning Talk: rack-attack gemによるリクエスト制限の失敗と学び\"\n  speakers:\n    - Natsuko Nadoyama\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Public API rate-limiting implementation challenges and operational solutions using the rack-attack gem.\n  video_provider: \"scheduled\"\n  video_id: \"pndcat-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n\n- id: \"ahogappa-hokuriku-rubykaigi-01\"\n  title: \"Lightning Talk: Rubyで楽してタスクを書きたい！\"\n  speakers:\n    - ahogappa\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Introduction to \"taski\", a task runner gem featuring automatic dependency resolution for effortless task writing in Ruby.\n  video_provider: \"scheduled\"\n  video_id: \"ahogappa-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  slides_url: \"https://speakerdeck.com/ahogappa/rubydele-site-tasukuwoshu-kitai\"\n\n- id: \"koichi-ito-hokuriku-rubykaigi-01\"\n  title: \"Lightning Talk: STYLE\"\n  speakers:\n    - Koichi ITO\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Exploring diverse Ruby formatting conventions, RuboCop configuration philosophy, and team implementation strategies.\n  video_provider: \"scheduled\"\n  video_id: \"koichi-ito-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n  slides_url: \"https://speakerdeck.com/koic/style\"\n\n# Closing Keynote\n- id: \"wtnabe-hokuriku-rubykaigi-01\"\n  title: \"Keynote: 30歳を迎えたRubyの魅力と僕たちの今、そしてこれから\"\n  speakers:\n    - wtnabe\n  event_name: \"Hokuriku RubyKaigi 01\"\n  date: \"2025-12-06\"\n  description: |-\n    Retrospective on Ruby's 30-year history, its ecosystem and culture, with encouragement for current and prospective users.\n  video_provider: \"scheduled\"\n  video_id: \"wtnabe-hokuriku-rubykaigi-01\"\n  language: \"japanese\"\n"
  },
  {
    "path": "data/hokuriku-rubykaigi/series.yml",
    "content": "---\nname: \"Hokuriku RubyKaigi\"\nwebsite: \"https://regional.rubykaigi.org/hokuriku01/\"\ntwitter: \"hokurikurb01\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\naliases:\n  - \"北陸Ruby会議\"\n"
  },
  {
    "path": "data/isle-of-ruby/isle-of-ruby-2018/event.yml",
    "content": "---\nid: \"isle-of-ruby-2018\"\ntitle: \"Isle of Ruby 2018\"\ndescription: \"\"\nlocation: \"Exeter, UK\"\nkind: \"conference\"\nstart_date: \"2018-04-13\"\nend_date: \"2018-04-15\"\nwebsite: \"http://isleofruby.org/\"\ntwitter: \"isleofruby\"\nbanner_background: \"#0038FF\"\nfeatured_background: \"#0038FF\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 50.72603669999999\n  longitude: -3.5274889\n"
  },
  {
    "path": "data/isle-of-ruby/isle-of-ruby-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://isleofruby.org/\n# Videos: -\n---\n- id: \"nick-schwaderer-sheffield-ruby-meetup-june-2018-measuring-chronic-pain-outcome\"\n  title: \"Measuring Chronic Pain Outcomes with Ruby and Twilio\"\n  raw_title: \"Measuring Chronic Pain Outcomes with Ruby and Twilio - Sheffield Ruby - June 2018\"\n  event_name: \"Sheffield Ruby Meetup - June 2018\"\n  date: \"2018-04-17\"\n  description: |-\n    Nick Schwaderer unpacks a personal story and project that started in 2017 to track, monitor and potentially forecast chronic pain swings with the help of Ruby and Twilio.\n  video_provider: \"youtube\"\n  video_id: \"Qf0S29bJbPg\"\n  published_at: \"2018-04-17\"\n  speakers:\n    - Nick Schwaderer\n"
  },
  {
    "path": "data/isle-of-ruby/series.yml",
    "content": "---\nname: \"Isle of Ruby\"\nwebsite: \"http://isleofruby.org/\"\ntwitter: \"isleofruby\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/jrubyconf-eu/jrubyconf-eu-2012/event.yml",
    "content": "---\nid: \"jrubyconf-eu-2012\"\ntitle: \"JRubyConf EU 2012\"\ndescription: |-\n  JRubyConf's first European excursion\nlocation: \"Berlin, Germany\"\nkind: \"conference\"\nstart_date: \"2012-08-17\"\nend_date: \"2012-08-17\"\ngithub: \"https://github.com/eurucamp/2012.jrubyconf.eu\"\nwebsite: \"https://web.archive.org/web/20221024054102/http://2012.jrubyconf.eu/\"\noriginal_website: \"http://2012.jrubyconf.eu/\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/jrubyconf-eu/jrubyconf-eu-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2012.jrubyconf.eu/\n# Videos: http://media.eurucamp.org/\n---\n[]\n"
  },
  {
    "path": "data/jrubyconf-eu/jrubyconf-eu-2013/event.yml",
    "content": "---\nid: \"jrubyconf-eu-2013\"\ntitle: \"JRubyConf EU 2013\"\ndescription: |-\n  After a first successful European excursion in 2012, JRubyConf is back. Bigger and better — this year as a two-day, single track conference.\nlocation: \"Berlin, Germany\"\nkind: \"conference\"\nstart_date: \"2013-08-14\"\nend_date: \"2013-08-15\"\ngithub: \"https://github.com/eurucamp/2013.jrubyconf.eu\"\nwebsite: \"https://web.archive.org/web/20130917085339/http://2013.jrubyconf.eu/\"\noriginal_website: \"http://2013.jrubyconf.eu/\"\nplaylist: \"https://media.eurucamp.org/\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/jrubyconf-eu/jrubyconf-eu-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2013.jrubyconf.eu/\n# Videos: http://media.eurucamp.org/\n---\n[]\n"
  },
  {
    "path": "data/jrubyconf-eu/jrubyconf-eu-2014/event.yml",
    "content": "---\nid: \"jrubyconf-eu-2014\"\ntitle: \"JRubyConf EU 2014\"\ndescription: \"\"\nlocation: \"Potsdam, Germany\"\nkind: \"conference\"\nstart_date: \"2014-08-01\"\nend_date: \"2014-08-01\"\nwebsite: \"http://2014.jrubyconf.eu/\"\nplaylist: \"http://media.eurucamp.org/\"\ncoordinates:\n  latitude: 52.3905689\n  longitude: 13.0644729\n"
  },
  {
    "path": "data/jrubyconf-eu/jrubyconf-eu-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2014.jrubyconf.eu/\n# Videos: http://media.eurucamp.org/\n---\n[]\n"
  },
  {
    "path": "data/jrubyconf-eu/jrubyconf-eu-2015/event.yml",
    "content": "---\nid: \"jrubyconf-eu-2015\"\ntitle: \"JRubyConf EU 2015\"\ndescription: \"\"\nlocation: \"Potsdam, Germany\"\nkind: \"conference\"\nstart_date: \"2015-07-31\"\nend_date: \"2015-07-31\"\nwebsite: \"http://jrubyconf.eu\"\nplaylist: \"http://media.eurucamp.org/\"\ncoordinates:\n  latitude: 52.3905689\n  longitude: 13.0644729\n"
  },
  {
    "path": "data/jrubyconf-eu/jrubyconf-eu-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://jrubyconf.eu\n# Videos: http://media.eurucamp.org/\n---\n[]\n"
  },
  {
    "path": "data/jrubyconf-eu/series.yml",
    "content": "---\nname: \"JRubyConf EU\"\nwebsite: \"http://2014.jrubyconf.eu/\"\ntwitter: \"jrubyconfeu\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2020/event.yml",
    "content": "---\nid: \"PLiBdJz0juoHDq5dT-cfLiCYzlCptq61ZM\"\ntitle: \"Kaigi on Rails 2020\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  Kaigi on Rails is a yearly conference in Tokyo, focusing on Rails and Web development.\npublished_at: \"2020-10-07\"\nstart_date: \"2020-10-03\"\nend_date: \"2020-10-03\"\nchannel_id: \"UCKD7032GuzUjDWEoZsfnwoA\"\nyear: 2020\nbanner_background: \"#F8F8EE\"\nfeatured_background: \"#F8F8EE\"\nfeatured_color: \"#D83469\"\nwebsite: \"https://kaigionrails.org/2020\"\ncoordinates: false\naliases:\n  - Kaigi on Rails 2020 - Stay Home Edition\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2020/videos.yml",
    "content": "---\n- id: \"akira-matsuda-kaigi-on-rails-2020\"\n  title: \"Coming Soon...💎\"\n  raw_title: \"Coming Soon...💎 / Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#a_matsuda\n\n    ▼発表概要\n    coming soon\n\n\n    登壇者: Akira Matsuda\n    自己紹介: https://kaigionrails.org/2020/speakers#a_matsuda\n    GitHub: https://github.com/amatsuda\n    Twitter: https://twitter.com/a_matsuda\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"4POksL_VVGY\"\n\n- id: \"shunsuke-kokuyou-mori-kaigi-on-rails-2020\"\n  title: \"Rails パフォーマンス・チューニング入門\"\n  raw_title: \"Rails パフォーマンス・チューニング入門 / 黒曜\"\n  speakers:\n    - Shunsuke \"Kokuyou\" Mori\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-15\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable/#kokuyouwind\n\n    ▼発表概要\n    RailsではActiveRecordや各種のgemを活用することで、低レイヤーの挙動を意識することなくわかりやすいコードを書くことが可能です。\n    一方で、こうしたコードは実際の内部的な挙動が把握しづらく、パフォーマンス上の問題を意図せず抱え込む可能性も秘めています。これはユーザの体験を損なうのみならず、場合によっては大規模な障害を引き起こす原因にもなりえます。\n    このセッションでは、パフォーマンス上の問題を把握するための計測手法や、見つかった問題を解決するためのアプローチについて、実例を交えてご紹介します。\n\n    資料: https://slides.com/kokuyouwind/deck-d35f44\n\n\n    登壇者: 黒曜\n    自己紹介: https://kaigionrails.org/2020/speakers/#kokuyouwind\n    GitHub: https://github.com/kokuyouwind\n    Twitter: https://twitter.com/kokuyouwind\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"Ua1qbpwDJd4\"\n\n- id: \"toshimaru-kaigi-on-rails-2020\"\n  title: \"FactoryBot the Right Way\"\n  raw_title: \"FactoryBot the Right Way / toshimaru\"\n  speakers:\n    - toshimaru\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#toshimaru_e\n\n    ▼発表概要\n    これまで「正しいRuby/Rails/RSpecの書き方」は多く議論されてきましたが、「正しいFactoryBotの書き方」は十分に議論されていないと感じます。\n    本発表ではRSpecの要となるデータ生成ツール・FactoryBotに焦点をあて、正しいFactoryBotの使い方についてグッドプラクティスと共に発表したいと思います。\n\n    資料: https://speakerdeck.com/toshimaru/factorybot-the-right-way\n\n\n    登壇者: toshimaru\n    自己紹介: https://kaigionrails.org/2020/speakers#toshimaru_e\n    GitHub: https://github.com/toshimaru\n    Twitter: https://twitter.com/toshimaru_e\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"n0epZM-lZvw\"\n  slides_url: \"https://speakerdeck.com/toshimaru/factorybot-the-right-way\"\n\n- id: \"makicamel-kaigi-on-rails-2020\"\n  title: \"継承とメタプログラミング満載なアプリケーションコードでもアクションとフィルタに悩まないための Gem を作った話\"\n  raw_title: \"継承とメタプログラミング満載なアプリケーションコードでもアクションとフィルタに悩まないための Gem を作った話 / makicamel\"\n  speakers:\n    - makicamel\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-18\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#makicamel\n\n    ▼発表概要\n    Rails のアプリケーションコードを書いていて、誰しも一度は覚えのないフィルタに悩んだことがあるのではないでしょうか。\n    あるいは、継承やメタプログラミングを重ねたコントローラーのアクションの実装がどこにあるかわからず探したことや、\n    またはもっと端的に、リクエストが走る度にどのフィルタやアクションを経由したか一望したいと思ったことはないでしょうか。\n    TracePoint を使って解決する Gem を作っ(た|ている)ので、その Gem のお話と、作るのは楽しいというお話をします。\n    資料: https://speakerdeck.com/makicamel/lets-enjoy-creating-gems\n\n\n    登壇者: makicamel\n    自己紹介: https://kaigionrails.org/2020/speakers#makicamel\n    GitHub: https://github.com/makicamel\n    Twitter: https://twitter.com/makicamel\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"fTesufhojAU\"\n  slides_url: \"https://speakerdeck.com/makicamel/lets-enjoy-creating-gems\"\n\n- id: \"ryo-kajiwara-kaigi-on-rails-2020\"\n  title: \"Action Mailbox in Action\"\n  raw_title: \"Action Mailbox in Action / Ryo Kajiwara (sylph01)\"\n  speakers:\n    - Ryo Kajiwara\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-19\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#s01\n\n    ▼発表概要\n    Rails 6で追加されたAction Mailboxによってメールの送信だけでなく受信もRailsで扱えるようになりました。普段のRailsの延長でメールを扱えるため非常に便利な一方、これによってEメールの複雑性の最たる原因であるspamとの戦いに身を投じなくてはいけなくてはなります。\n    この発表では、RailsでEメールを扱う開発者が知っておきたいSMTPとドメイン認証技術(SPF, DKIM)の基礎とRailsでの扱い方の紹介、また実際に使ってみた例として電子書籍のソーシャルDRMシステムを組んだ例を紹介します。\n\n\n    登壇者: Ryo Kajiwara (sylph01)\n    自己紹介: https://kaigionrails.org/2020/speakers#s01\n    GitHub: https://github.com/sylph01\n    Twitter: https://twitter.com/s01\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"UkYxiGQT694\"\n\n- id: \"yuka-kato-kaigi-on-rails-2020\"\n  title: \"新ミドルウェア ActionDispatch::HostAuthorization と学ぶ DNS のしくみ\"\n  raw_title: \"新ミドルウェア ActionDispatch::HostAuthorization と学ぶ DNS のしくみ / yucao24hours\"\n  speakers:\n    - Yuka Kato\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#yucao24hours\n\n    ▼発表概要\n    Rails 6 から、新たに `ActionDispatch::HostAuthorization` というミドルウェアが追加されました。\n    DNS リバインディングという攻撃から Rails アプリケーションを守るためのものですが、そもそも「DNS リバインディング」という名前をあまり聞き慣れない方もいらっしゃるのではないでしょうか？\n    こちらの発表は DNS リバインディングのカラクリと Rails の `HostAuthorization` ミドルウェアのアプローチについてを知っていただくことができ、さらには DNS の基本的なしくみについても知れる、一口で三度おいしい！？技術トークです。\n    普段はもっぱらアプリケーションコードを書いている方へ、少しでも DNS のふるまいを理解するお手伝いができれば幸いです。\n    資料: https://speakerdeck.com/yucao24hours/understanding-dns-with-actiondispatch-hostauthorization\n\n\n    登壇者: yucao24hours\n    自己紹介: https://kaigionrails.org/2020/speakers#yucao24hours\n    GitHub: https://github.com/yucao24hours\n    Twitter: https://twitter.com/yucao24hours\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"ufUyNEgw-J8\"\n  slides_url: \"https://speakerdeck.com/yucao24hours/understanding-dns-with-actiondispatch-hostauthorization\"\n\n- id: \"osama-yu-kaigi-on-rails-2020\"\n  title: \"ActiveRecord の歩み方\"\n  raw_title: \"ActiveRecord の歩み方 / osyo\"\n  speakers:\n    - Osama Yu\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-24\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#pink_bangbi\n\n    ▼発表概要\n    皆さん ActiveRecord のコードは読んだことがありますか？\n    ActiveRecord は使っていても読んだことがない人が多いのではないでしょうか。\n    本発表では ActiveRecord の実装を読む上でのポイントや読む上で役に立つ Ruby の機能を解説しつつ、実際にライブコーディングをしながらコードリーディングを実演したいと思います。\n    この発表は ActiveRecord に限らず Ruby のコードを読むときにきっと役立つでしょう。\n\n    資料: https://speakerdeck.com/osyo/activerecord-falsebu-mifang\n\n\n    登壇者: osyo\n    自己紹介: https://kaigionrails.org/2020/speakers#pink_bangbi\n    GitHub: https://github.com/osyo-manga\n    Twitter: https://twitter.com/pink_bangbi\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"6b3bAipw0Yg\"\n  slides_url: \"https://speakerdeck.com/osyo/activerecord-falsebu-mifang\"\n\n- id: \"hiroshi-shimoju-kaigi-on-rails-2020\"\n  title: \"快適なリモートワークを実現するために〜RailsでSSOを実現する3パターン\"\n  raw_title: \"快適なリモートワークを実現するために〜RailsでSSOを実現する3パターン / 下重 博資\"\n  speakers:\n    - Hiroshi Shimoju\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-27\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#shimoju_\n\n    ▼発表概要\n    COVID-19の拡大によりリモートワークをすることになった会社もあると思いますが、そこで問題となるのが社内IPアドレスでアクセス制限を行っている管理画面や社内サービスです。この発表では複数のRailsアプリにSAML認証を実装してIP制限をなくしたり、oauth2-proxyを用いてアプリケーションロジックに踏み込まずに多要素認証を実現したことなど、セキュリティを保ちながらリモートワークを快適にするために実践したことをご紹介します。\n\n\n    登壇者: 下重 博資\n    自己紹介: https://kaigionrails.org/2020/speakers#shimoju_\n    GitHub: https://github.com/shimoju\n    Twitter: https://twitter.com/shimoju_\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"oLzylLlfKh0\"\n\n- id: \"koichi-ito-kaigi-on-rails-2020\"\n  title: \"TDD with git. Long live engineering.\"\n  raw_title: \"TDD with git. Long live engineering. / Koichi ITO\"\n  speakers:\n    - Koichi ITO\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-28\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#koic\n\n    ▼発表概要\n    TDD が世の中に登場しておよそ20年が経ちました。その間に世の中を取り巻くメジャーなバージョンコントロールシステム (SCM) は CVS → Subversion → Git へと変遷しています。\n\n    CVS 時代より、TDD は Red → Green → Refactor の基本的なリズムがあり、テストがグリーンになったらコミットするという考えがあります。分散 SCM の Git 時代でもこのリズムは有効でしょうか？\n\n    本講演では TDDとしてのコミット粒度と、Pull Request として開くコミット粒度の違いを示し、Git であたかも最初から綺麗なコードで仕上げたかのようにするという、SCM が積み重ねてきた歴史と実践技術の話です。本編ではさらにその根底にあるセルフレビューと小さなリファクタリングの回帰への実現にも触れます。\n    資料: https://speakerdeck.com/koic/tdd-with-git-long-live-engineering\n\n\n    登壇者: Koichi ITO\n    自己紹介: https://kaigionrails.org/2020/speakers#koic\n    GitHub: https://github.com/koic\n    Twitter: https://twitter.com/koic\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"fyvUDLJvpp8\"\n  slides_url: \"https://speakerdeck.com/koic/tdd-with-git-long-live-engineering\"\n\n- id: \"tomohiro-hashidate-kaigi-on-rails-2020\"\n  title: \"Sidekiq to Kafka 〜ストリームベースのmicroservices〜\"\n  raw_title: \"Sidekiq to Kafka 〜ストリームベースのmicroservices〜 / joker1007\"\n  speakers:\n    - Tomohiro Hashidate\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-29\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#joker1007\n\n    ▼発表概要\n    弊社のプロダクトであるReproはアプリケーションのイベントログやファーストパーティデータを収集しアプリ内マーケティングに活用するサービスです。大量のイベントデータがやってきますが、直接エンドユーザーに応答を返すことはありません。一方でReproの顧客がその機能を活用した結果はエンドユーザーに届くため、すぐに結果を確認することはありません。\n    こういった特徴のため、同期的なコールとレスポンスをベースにしたmicroservicesよりも非同期処理の複雑な連鎖を開発しやすくできるやり方を優先するべきだと考えました。Railsで非同期処理というとSidekiq(ActiveJob)が有名で弊社でも広範に活用されていましたが、弊社ではその役割をApache Kafkaを中心にしたmicroコンポーネントに置き換えようと計画しています。\n    まだ道半ばではありますが、この話では分散StreamBufferであるApache Kafkaを活用してRailsアプリケーションを分割していくにはどういった考え方が必要かを紹介します。\n\n\n    登壇者: joker1007\n    自己紹介: https://kaigionrails.org/2020/speakers#joker1007\n    GitHub: https://github.com/joker1007\n    Twitter: https://twitter.com/joker1007\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"OxUnoVvwftM\"\n\n- id: \"akiko-takano-kaigi-on-rails-2020\"\n  title: \"ひみつきちを作りたい 〜「こどもれっどまいん」テーマ作りでの学び\"\n  raw_title: \"ひみつきちを作りたい 〜「こどもれっどまいん」テーマ作りでの学び / 高野 明子\"\n  speakers:\n    - Akiko Takano\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-26\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#akiko_pusu\n\n    ▼発表概要\n    長年ユーザ視点で付き合っていたRedmine。そのおかげで、いつのまにかRailsを中心とした開発現場でのお仕事ができるようになりました。10年以上付き合ってみて、バージョンアップを乗り越えている稀有なOSSだと感じています。\n    若干UIが古いという意見がある中、まずは自分たちで変えていけないだろうか？そしてまた、前々から希望していた「こどもむけ」のシステムがつくれないか？\n    そんな気持ちで、テーマ開発に取り組んでみたお話をします。\n\n\n    登壇者: 高野 明子\n    自己紹介: https://kaigionrails.org/2020/speakers#akiko_pusu\n    GitHub: https://github.com/akiko-pusu\n    Twitter: https://twitter.com/akiko_pusu\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"FVDjsvPZ4wo\"\n\n- id: \"lulalala-kaigi-on-rails-2020\"\n  title: \"Rails 6.1's ActiveModel#errors Changes\"\n  raw_title: \"Rails 6.1's ActiveModel#errors Changes / lulalala\"\n  speakers:\n    - lulalala\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-16\"\n  language: \"english\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#lulalala_it\n\n    ▼発表概要\n    ActiveModel::Errors will undergo major changes in Rails 6.1. This talk presents the rationale and the new object-oriented architecture. The implementation and edge cases are explained, and the talk will showcase examples on how it can make your coding life easier.\n\n\n    登壇者: lulalala\n    自己紹介: https://kaigionrails.org/2020/speakers#lulalala_it\n    GitHub: https://github.com/lulalala\n    Twitter: https://twitter.com/lulalala_it\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"FGhZR4ns_tc\"\n\n- id: \"betachelsea-kaigi-on-rails-2020\"\n  title: \"Railsワンマン運転の手引き\"\n  raw_title: \"Railsワンマン運転の手引き / べーた\"\n  speakers:\n    - betachelsea\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-17\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#beta_chelsea\n\n    ▼発表概要\n    初学者の方向けに、Railsで作ったサービスを実際に運用するために必要な要素を紹介します。Railsは大変便利なので、一人でも開発をどんどん進められてしまうのですが、いざ外部公開となった際はサーバ周りの予備知識があるとスムーズです。これからサービス公開したい方の参考になればと思います。\n    資料: https://speakerdeck.com/betachelsea/rails-one-man-operation\n\n\n    登壇者: べーた\n    自己紹介: https://kaigionrails.org/2020/speakers#beta_chelsea\n    GitHub: https://github.com/betachelsea\n    Twitter: https://twitter.com/beta_chelsea\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"pV6dhWLoSy4\"\n  slides_url: \"https://speakerdeck.com/betachelsea/rails-one-man-operation\"\n\n- id: \"aaron-patterson-kaigi-on-rails-2020\"\n  title: \"Viewがレンダリングされるまでの技術とその理解\"\n  raw_title: \"Viewがレンダリングされるまでの技術とその理解 / Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-14\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable/#tenderlove\n\n    ▼発表概要\n    Railsの各部分とその仕組みがより理解できる話として、1リクエストを起点にブラウザからViewまで全ての流れを通し、どのようにRailsが1リクエストを解釈した後、適切なコントローラーを見つけ、Viewをレンダリングし、レスポンスの送信方法の説明とRack, Action Controller,Action Viewの各技術の説明をします。\n    資料: https://drive.google.com/file/d/1mugKOdIa5WCKWJmkCIG19X2OQtLofYlP/view\n\n    登壇者: Aaron Patterson\n    自己紹介: https://kaigionrails.org/2020/speakers/#tenderlove\n    GitHub: https://github.com/tenderlove\n    Twitter: https://twitter.com/tenderlove\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"QTv9MVRa_MM\"\n\n- id: \"aycabta-kaigi-on-rails-2020\"\n  title: \"Ruby 3.0におけるドキュメンテーションと端末制御の未来\"\n  raw_title: \"Ruby 3.0におけるドキュメンテーションと端末制御の未来 / aycabta（糸柳 茶蔵）\"\n  speakers:\n    - aycabta\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-25\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#aycabta\n\n    ▼発表概要\n    リリースが徐々に迫りつつある Ruby 3.0 において、どのようにライブラリのドキュメンテーションが行われるべきなのか、Ruby core team の RDoc メンテナから、YARD との共存も含めて説明します。また、ドキュメンテーションとの連携を果たした Ruby 2.7 以降の新生 IRB 及びそれら新機能がどのように Pry とも連携可能なものとして計画されているのか、合わせて説明します。そしてこれらが rails console にどう影響するのか、その実際についても解説いたします。\n\n\n    登壇者: aycabta（糸柳 茶蔵）\n    自己紹介: https://kaigionrails.org/2020/speakers#aycabta\n    GitHub: https://github.com/aycabta\n    Twitter: https://twitter.com/aycabta\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"BDYeW2I9Sm8\"\n\n- id: \"yutaro-taira-kaigi-on-rails-2020\"\n  title: \"コードレビュー100本ノックで学んだRailsリファクタリング\"\n  raw_title: \"コードレビュー100本ノックで学んだRailsリファクタリング / 9sako6\"\n  speakers:\n    - Yutaro Taira\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-20\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#9sako6\n\n    ▼発表概要\n    2020年4月に新卒で就職し、 Rails アプリ開発者になって数ヶ月が経ちました。長期間運用されている大規模なシステムのプロジェクトにアサインされ、ここへ至るまでに、歴戦の先輩方から数百ものコードレビューをいただきました。commit の意識改革から、命名、分割、設計、テストに至るまで、数多くの指摘を受けました。そうして学んだ、実務目線でのリファクタリング術をお伝えします。\n\n\n    登壇者: 9sako6\n    自己紹介: https://kaigionrails.org/2020/speakers#9sako6\n    GitHub: https://github.com/9sako6\n    Twitter: https://twitter.com/9sako6\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"cRjJOXlZgEo\"\n\n- id: \"takafumi-onaka-kaigi-on-rails-2020\"\n  title: \"育てるSinatra\"\n  raw_title: \"育てるSinatra / onk\"\n  speakers:\n    - Takafumi ONAKA\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-21\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#onk\n\n    ▼発表概要\n    Sinatra を Rails 風に育てることで、Rails のレールについての洞察を深めていきます。\n    フレームワークを作ってみたい人、Rails の良いところを再確認したい人にオススメです。\n\n\n    登壇者: onk\n    自己紹介: https://kaigionrails.org/2020/speakers#onk\n    GitHub: https://github.com/onk\n    Twitter: https://twitter.com/onk\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"emw7IPaxUgU\"\n\n- id: \"fukajun-kaigi-on-rails-2020\"\n  title: \"Rubyで書かれたソースコードを読む技術\"\n  raw_title: \"Rubyで書かれたソースコードを読む技術 / fukajun\"\n  speakers:\n    - fukajun\n  event_name: \"Kaigi on Rails 2020\"\n  date: \"2020-10-03\"\n  published_at: \"2020-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2020/timetable#fukajun\n\n    ▼発表概要\n    ソースコードを読むのがそんなに得意ではない人が、いかにしてソースコードを読むか？困ったときに生かせるいくつかのテクニックについて話します\n\n\n    登壇者: fukajun\n    自己紹介: https://kaigionrails.org/2020/speakers#fukajun\n    GitHub: https://github.com/fukajun\n    Twitter: https://twitter.com/fukajun\n\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"CvWFOYPc0f8\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2021/event.yml",
    "content": "---\nid: \"PLiBdJz0juoHD6LBhzv1--OtEdCBBRZv2l\"\ntitle: \"Kaigi on Rails 2021\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  Kaigi on Rails is a yearly conference in Tokyo, focusing on Rails and Web development.\npublished_at: \"2021-10-24\"\nstart_date: \"2021-10-22\"\nend_date: \"2021-10-23\"\nchannel_id: \"UCKD7032GuzUjDWEoZsfnwoA\"\nyear: 2021\nbanner_background: \"#E0E0E0\"\nfeatured_background: \"#E0E0E0\"\nfeatured_color: \"#494949\"\nwebsite: \"https://kaigionrails.org/2021\"\ncoordinates: false\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2021/videos.yml",
    "content": "---\n# Website: https://kaigionrails.org/2021\n# Schedule: https://kaigionrails.org/2021/timetable\n\n# Day 1 - 2021-10-22\n\n- id: \"ryuta-kamizono-kaigi-on-rails-2021\"\n  title: \"Q&A with kamipo\"\n  raw_title: \"Q&A with kamipo / kamipo\"\n  speakers:\n    - Ryuta Kamizono\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/kamipo/\n\n    Railsコミッターであるkamipoさんが皆さまからの質問に答えるQ&Aセッションです。モデレーターはRails/Rubyのコミッター @a_matsuda さんです。\n\n    発表者\n    kamipo\n    GitHub https://github.com/kamipo\n    Twitter https://twitter.com/kamipo\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"FWFyyObp1f4\"\n\n- id: \"shohei-mitani-kaigi-on-rails-2021\"\n  title: \"監視を通じたサービスの逐次的進化 ~B/43の決済サービスでの取り組み~\"\n  raw_title: \"監視を通じたサービスの逐次的進化 ~B/43の決済サービスでの取り組み~ / Shohei Mitani\"\n  speakers:\n    - Shohei Mitani\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/shohei1913/\n\n    昨今のシステム開発ではマイクロサービスを選択したり、複数の外部サービスを利用したりと複雑化しています。それに伴い、障害ポイントを適切に把握し抜け漏れなく異常を検知する方法を導入することが重要になっています。そのため、NewRelicやSentryなどの監視サービスを導入している企業も多いと思いますが、こうしたツールでは監視しにくいシステム固有の障害ポイントもあります。自社サービスの特徴を理解してどのように正常なシステム動作を定義し監視システムを構築していくか、テーブル設計とRedashを使ったダッシュボード作成方法についてご紹介します。\n\n    資料 https://speakerdeck.com/shoheimitani/kaigi-on-rails-2021\n\n\n    発表者\n    Shohei Mitani\n    GitHub https://github.com/ShoheiMitani\n    Twitter https://twitter.com/shohei1913\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"gQZrRFmunoM\"\n  slides_url: \"https://speakerdeck.com/shoheimitani/kaigi-on-rails-2021\"\n\n- id: \"yuya-fujiwara-kaigi-on-rails-2021\"\n  title: \"銀河スクラムマスター・ガイド -スクラムガイド 2020年版を添えて\"\n  raw_title: \"銀河スクラムマスター・ガイド -スクラムガイド 2020年版を添えて- / あそなす\"\n  speakers:\n    - Yuya Fujiwara\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/asonas/\n\n    スクラムを実践したことのない開発チームで少しずつスクラムを取り組んで行ったお話をします。\n    2021年6月に「9月に新しいサービスをリリースしたいです」と言われたのがすべての始まりでした。立ちはだかる荒ぶる四天王、超短期リリース、スコープやコストの調整...。それらをうまく手なづけどうやってチームが動き始めたのか。なぜスクラムを採用しようと思ったのか。うまくいったこといかなかったこと、どのようにイテレーティブにスクラムチームを改善していったか。\n    このトークでは、開発チームでスクラムを導入するまでとスクラムマスターをやったことがない方でもスクラムを始めるための道標を持ち帰ってもらえるようにします。\n\n    明日から使えるキーワードは「それスクラムガイドに書いてあるよ」です。\n\n    資料 https://speakerdeck.com/asonas/the-scrummasters-guide-to-the-galaxy\n\n\n    発表者\n    あそなす\n    GitHub https://github.com/asonas\n    Twitter https://twitter.com/asonas\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"6rTzUmpiHjU\"\n  slides_url: \"https://speakerdeck.com/asonas/the-scrummasters-guide-to-the-galaxy\"\n\n- id: \"hiroya-sakamoto-kaigi-on-rails-2021\"\n  title: \"ジュニアエンジニアが開発チームに貢献するためのTIPS\"\n  raw_title: \"ジュニアエンジニアが開発チームに貢献するためのTIPS / ヒロ\"\n  speakers:\n    - Hiroya Sakamoto\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/sa_tech0518/\n\n    他業種で7年働いた後、受託企業でwebエンジニアとして働きだし約8ヶ月が経過しました。\n    私という一人の人間に対して、「ジュニアエンジニア」と「社会人中途採用」という二つの肩書きが存在している、という感覚を持ちながら日々仕事をしています。\n    エンジニアとしてはジュニア扱いであり、日々周りの人からサポートしてもらいながら開発を行う一方で、「仕事」という側面においては「それなりの経験者」として振る舞うことが求められています。\n    自意識としても「お世話になっている分、周囲の人に貢献したい」という思いは絶えず持っているため、ジュニアエンジニアでありながらもバリューを発揮するために日々試行錯誤を繰り返してきました。\n    そうした自身の経験の中からチームのために有用であると感じた事柄について、「行動編」・「マインドセット編」としてまとめ、ご紹介できればと思います。\n\n    資料 https://speakerdeck.com/hirosaktech/kaigi-on-rails-2021\n\n\n    発表者\n    ヒロ\n    GitHub https://github.com/HiroyaSakamoto\n    Twitter https://twitter.com/sa_tech0518\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"EKY1mOxmfM0\"\n  slides_url: \"https://speakerdeck.com/hirosaktech/kaigi-on-rails-2021\"\n\n- id: \"yusuke-iwaki-kaigi-on-rails-2021\"\n  title: \"Railsのシステムテスト解剖学\"\n  raw_title: \"Railsのシステムテスト解剖学 / Yusuke Iwaki\"\n  speakers:\n    - Yusuke Iwaki\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/YusukeIwaki/\n\n    Railsには、ブラウザとRailsサーバーを対向させて自動試験するためのシステムテストという仕組みがあります。\n    システムテストは単なるE2Eテストのフレームワークとして認識されがちですが、一般的なE2Eテストのノウハウをもとに自動テストを組むと不安定なテストに悩まされ、運用負荷が高くなりがちです。\n    このセッションでは「システムテスト解剖学」と題し、システムテスト実行時に何がどう動いているのか、具体的にはCapybaraの構造や特性を明らかにしていきます。そのうえで、不安定なテストはなぜ生まれてしまうのか、どうすれば軽減できるのか、などシステムテストの運用改善のための知見を共有したいと思います。\n\n    資料 https://speakerdeck.com/yusukeiwaki/railsfalse-sisutemutesutojie-pou-xue\n\n\n    発表者\n    Yusuke Iwaki\n    GitHub https://github.com/YusukeIwaki\n    Twitter https://twitter.com/yi01imagination\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"mRSkL8gWcqw\"\n  slides_url: \"https://speakerdeck.com/yusukeiwaki/railsfalse-sisutemutesutojie-pou-xue\"\n\n- id: \"kenshi-shiode-kaigi-on-rails-2021\"\n  title: \"JSON Schema で複雑な仕様の入力フォームの実装に立ち向かった話\"\n  raw_title: \"JSON Schema で複雑な仕様の入力フォームの実装に立ち向かった話 / Kenshi Shiode\"\n  speakers:\n    - Kenshi Shiode\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/solt9029/\n\n    Ruby on Rails を用いたシステム上で入力フォームを実現する際、Rails が提供しているフォームヘルパーを利用した実装や、React や Vue によるコンポーネントの自前での実装が一般的に行われます。\n\n    ここで、職業で学生を選択した場合は学校名と学年、会社員を選択した場合は役職と年収を入力する...といった、条件分岐が大量に生まれる入力フォームを想像しましょう。\n    一般的な実装手法では、あるフォームの入力値が他のフォームに影響を与えるような、複雑で動的な入力フォームの実現をするために、大量の if 文を書く必要があります。\n    また、ユーザから送信された入力値の正しさをバリデーションするために、バックエンド側に同様の if 文を大量に書く必要が出てきます。\n\n    そこで私は、複雑な仕様の入力フォームの実装のための JSON Schema 活用方法および事例について紹介します。入力フォームの仕様を JSON Schema で定義すれば、大量の if 文を用いることなくフロントエンド側の入力フォームを自動生成することができます。また、その JSON Schema をバックエンド側のバリデーションのロジックにも使い回すことができるため、シンプルでメンテナンス性の高い実装を実現することができます。\n\n    資料 https://speakerdeck.com/solt9029/json-schema-tefu-za-nashi-yang-falseru-li-huomufalseshi-zhuang-nili-tixiang-katutahua\n\n\n    発表者\n    Kenshi Shiode\n    GitHub https://github.com/solt9029\n    Twitter https://twitter.com/solt9029\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"L-f4MwVbwWw\"\n  slides_url: \"https://speakerdeck.com/solt9029/json-schema-tefu-za-nashi-yang-falseru-li-huomufalseshi-zhuang-nili-tixiang-katutahua\"\n\n- id: \"leonard-chin-kaigi-on-rails-2021\"\n  title: \"Performance as Product Feature\"\n  raw_title: \"Performance as Product Feature / Leonard Chin (レオ)\"\n  speakers:\n    - Leonard Chin\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/lchin/\n\n    \"Performance is a feature\"と言われています。\n\n    スピードは機能だとしたら、それはプロダクトの様々な機能の一つに数えるということになる。その機能のオーナーとして、どのように事業にとって価値のある投資にできるのか？\n\n    このトークでは、パフォーマンスをプロダクト開発として捉えて改善に取り組むアプローチについて紹介します。\n\n    資料 https://speakerdeck.com/lchin/performance-as-a-product-feature\n\n\n    発表者\n    Leonard Chin (レオ)\n    GitHub https://github.com/l15n\n    Twitter https://twitter.com/lchin\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"ZAYNqDfi7og\"\n  slides_url: \"https://speakerdeck.com/lchin/performance-as-a-product-feature\"\n\n- id: \"kakutani-shintaro-kaigi-on-rails-2021\"\n  title: 'Polishing on \"Polished Ruby Programming\"'\n  raw_title: 'Polishing on \"Polished Ruby Programming\" / Kakutani Shintaro'\n  speakers:\n    - Shintaro Kakutani\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/kakutani/\n\n    Jeremy Evans著『Polished Ruby Programming』が出版されました。本書は「Ruby3のリリースにともなう仕様策定の議論やコミュニティの調停、実際の開発にいたるまで驚異的な活動量と熱意をもって取り組ん」だ成果からRuby Prize 2020を受賞した、RubyKaigi 2019のkeynote speakerでもある著者が、自身の圧倒的な活動実績を踏まえて書き下ろした一冊です。\n\n    日本のRubyistの皆さんにも是非読んでもらいたいので、このトークでは本書がどんな内容なのか、その読みどころをダイジェストでお伝えします。原著は英語ですが、Rubyが読めるなら恐れることはありません。「英語で読むのはしんどいな」というRubyistの皆さんは…しばらくお待ちください。話者が訳して日本語版をお届けします 🙃\n\n    本トークでは「Rubyの磨きかた」にもいろいろあるよね、という話をするつもりです。練度を上げたい初級中級Rubyistにとって日々の活動の何らかのヒントになるはずです。\n\n    資料 https://speakerdeck.com/kakutani/kaigionrails-2021\n\n\n    発表者\n    Kakutani Shintaro\n    GitHub https://github.com/kakutani\n    Twitter https://twitter.com/kakutani\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"EJuKeX7k2rY\"\n  slides_url: \"https://speakerdeck.com/kakutani/kaigionrails-2021\"\n\n- id: \"ryo-kajiwara-kaigi-on-rails-2021\"\n  title: \"Build and Learn Rails Authentication\"\n  raw_title: \"Build and Learn Rails Authentication / Ryo Kajiwara (sylph01)\"\n  speakers:\n    - Ryo Kajiwara\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/s01/\n\n    Railsにおけるユーザー認証というとDeviseがよく知られよく使われていますが、非常によくできてる故に我々は認証技術の内部をあまり気にせずに済んでいるのも事実です。この発表ではDeviseの機能の一部を自分で作ってみることや他の認証ライブラリとのアプローチの比較を行うことで認証技術に関する理解を深め、認証ライブラリの選定や検証を行う手助けをすることを目的としています。\n\n    資料 https://github.com/sylph01/touch-and-learn-rails-authn\n\n\n    発表者\n    Ryo Kajiwara (sylph01)\n    GitHub https://github.com/sylph01\n    Twitter https://twitter.com/s01\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"9K2hrw-L03A\"\n  slides_url: \"https://speakerdeck.com/sylph01/build-and-learn-rails-authentication\"\n\n- id: \"keiko-kaneko-kaigi-on-rails-2021\"\n  title: \"FactoryBotのbuild strategiesをいい感じに直してくれるgemを作った話\"\n  raw_title: \"FactoryBotのbuild strategiesをいい感じに直してくれるgemを作った話 / Keiko Kaneko\"\n  speakers:\n    - Keiko Kaneko\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/neko314/\n\n    FactoryBotを使ってテストを書いているとcreateしているところをbuild_stubbedやbuildに書き換えたくなることってありますよね。その時どうやってやっていますか？私は1つ1つ書き換えてはテストを実行し、落ちれば元に戻すという方法しか知らず、いたく面倒で非効率的なのでどうにかできないものかと思い、代わりにやってくれるgemを作ってみることにしました。そのお話をします。\n\n    資料 https://speakerdeck.com/neko314/introduce-my-gem-factory-strategist\n\n\n    発表者\n    Keiko Kaneko\n    GitHub https://github.com/neko314\n    Twitter https://twitter.com/neko314_\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"lZ9kg2vDPm0\"\n  slides_url: \"https://speakerdeck.com/neko314/introduce-my-gem-factory-strategist\"\n\n- id: \"takuya-matsumoto-kaigi-on-rails-2021\"\n  title: \"STORES へのID基盤の導入と、ユーザーアカウントの移行を振り返って\"\n  raw_title: \"STORES へのID基盤の導入と、ユーザーアカウントの移行を振り返って / Takuya Matsumoto\"\n  speakers:\n    - Takuya Matsumoto\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/upinetree/\n\n    私が携わっている STORES というネットショップ開設サービスでは、この4月にショップオーナー向けの認証プロセスを一新しました。それまでは Rails アプリケーション内に実装した認証機能を利用していましたが、今では新しく構築したID基盤と OpenID Connect 準拠でサービス連携して認証するようになっています。このリリースは大きなトラブルもなく完了し、今も元気に動いていますが、リリースまでにはいくつもの難しい課題がありました。\n\n    ・既存の仕様、データ、UXなどの整合性との戦い\n    ・技術的負債と考古学\n    ・サービス個別の事情と共通基盤としての普遍性の葛藤\n    ・専門性の高い認証・認可の技術領域の学習\n    ・ユーザーへの影響の最小化とサービス無停止でのリリース\n\n    本発表ではこれらの課題に対し私達がどのように乗り越え、ID基盤の導入をリリースしたのかを振り返ります。なお、今回は既存サービスへの導入の過程を主題としてお話するため、ID基盤自体の技術セットやアーキテクチャには深くは触れません。\n\n    資料 https://speakerdeck.com/upinetree/stores-hefalseidji-pan-falsedao-ru-to-yuzaakauntofalseyi-xing-wozhen-rifan-tute\n\n\n    発表者\n    Takuya Matsumoto\n    GitHub https://github.com/upinetree\n    Twitter https://twitter.com/upinetree\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"IX27ReQlTi8\"\n  slides_url: \"https://speakerdeck.com/upinetree/stores-hefalseidji-pan-falsedao-ru-to-yuzaakauntofalseyi-xing-wozhen-rifan-tute\"\n\n- id: \"kazuhito-hokamura-kaigi-on-rails-2021\"\n  title: \"RailsエンジニアのためのNext.js入門\"\n  raw_title: \"RailsエンジニアのためのNext.js入門 / Kazuhito Hokamura\"\n  speakers:\n    - Kazuhito Hokamura\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/hokaccha/\n\n    Next.jsはReactをベースとしたWebフロントエンドのためのアプリケーションフレームワークです。Railsとは同じレイヤーのフレームワークなのでRailsに組み込んで使うような関係ではありません。しかし、近年においてはRailsはAPIモードでAPIだけを提供し、フロントエンドは別アプリケーションとして作るという構成も珍しくありません。そういったケースでフロントエンドのフレームワークとして有力な候補となるのがNext.jsです。\n\n    Next.jsの特徴として、パスベースのルーティングや自動的なパフォーマンスの最適化、ゼロコンフィグな開発環境、Static Generation や Server-side Rendering を簡単にできる仕組みなどがあります。これらの特徴はRailsと共通するところもあれば全く異なる考え方のものもあります。そういったNext.jsの特徴をRailsの機能と比較しながら解説し、Railsと組み合わせて使う場合のアーキテクチャや実装方法についても説明します。\n\n    資料 https://speakerdeck.com/hokaccha/railsenziniafalsetamefalsenext-dot-jsru-men\n\n\n    発表者\n    Kazuhito Hokamura\n    GitHub https://github.com/hokaccha\n    Twitter https://twitter.com/hokaccha\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"NIEj9avGam4\"\n  slides_url: \"https://speakerdeck.com/hokaccha/railsenziniafalsetamefalsenext-dot-jsru-men\"\n\n- id: \"ryunosuke-sato-kaigi-on-rails-2021\"\n  title: \"クローズしたはずのサービスが知らぬ間に蘇っていたのでクローズしきった話\"\n  raw_title: \"クローズしたはずのサービスが知らぬ間に蘇っていたのでクローズしきった話 / Ryunosuke Sato\"\n  speakers:\n    - Ryunosuke Sato\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-22\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/tricknotes/\n\n    「あれ、このサービス、クローズしたはずなのになんかまだ動いているような…!?」\n    そんな経験をされた方はいらっしゃるでしょうか。\n    わたしは10数年プログラマをやっていますが、遭遇したのは初めてでした。\n\n    このトークは、クローズしたサイトをドメイン・コンテンツ含め流用の上で一部改ざんされてのっとられていたので、調査から完全クローズに向けて進めていったという実際の履歴をお話します。\n    N=1の事例の話ではありますが、今後近しい状況に遭遇した方の助けになれば幸いです。\n\n    資料 https://speakerdeck.com/tricknotes/kurozusitahazufalsesabisugazhi-ranujian-nisu-tuteitafalsedekurozusikitutahua\n\n\n    発表者\n    Ryunosuke Sato\n    GitHub https://github.com/tricknotes\n    Twitter https://twitter.com/tricknotes\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"Ly46qy7Pxtc\"\n  slides_url: \"https://speakerdeck.com/tricknotes/kurozusitahazufalsesabisugazhi-ranujian-nisu-tuteitafalsedekurozusikitutahua\"\n\n## Day 2 - 2021-10-23\n\n- id: \"yohei-yasukawa-kaigi-on-rails-2021\"\n  title: \"学習者に聴く！Ruby on Rails 学習者の「今」\"\n  raw_title: \"学習者に聴く！Ruby on Rails 学習者の「今」 / Yohei Yasukawa\"\n  speakers:\n    - Yohei Yasukawa\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/yasulab/\n\n    YouTube から公開している「Railsチュートリアル完走者に聴く」という対談動画シリーズ（各回２０分〜５０分の動画）やプログラミングスクール合同コンテスト「editch」（全３回）にゲスト参加した経験から、誰がどんな背景で Ruby on Rails を学んでいるのか、また、そういった方々が開発したプロダクトなどをまとめ、Rails 学習者の「今」を参加者と共有します。\n\n    参考リンク\n    ・📺 YouTube - Ruby on Rails チュートリアル https://www.youtube.com/channel/UCgSPCgA1ksSPKg1Jp99EEFw\n    ・🏆editch |プログラミングスクール合同ポートフォリオコンテスト https://editch.org/\n    ・📊 数字で見る！Ruby/Rails 学習者の動向 - note https://note.com/yasslab/n/n4a2cbbe64eca?magazine_key=md778735d3f77\n\n    音声の都合により再収録したものが公開されています。こちらもご参照ください。\n    https://youtu.be/9dG8NQBOjmA\n\n\n    資料 https://speakerdeck.com/yasslab/creative-learning-cycle-on-rails\n\n\n    発表者\n    Yohei Yasukawa\n    GitHub https://github.com/yasulab\n    Twitter https://twitter.com/yasulab\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"s0Grxre51Pk\"\n  slides_url: \"https://speakerdeck.com/yasslab/creative-learning-cycle-on-rails\"\n\n- id: \"hideaki-ishii-kaigi-on-rails-2021\"\n  title: \"事業に向き合い続けたい私は、それでもRailsを使い続ける\"\n  raw_title: \"事業に向き合い続けたい私は、それでもRailsを使い続ける / Hideaki Ishii\"\n  speakers:\n    - Hideaki Ishii\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/danimal141/\n\n    私はエンジニアの責任とは「ただ技術をマスターすることではなく、技術を使って事業上の課題を解決すること」であると考えています。そしてそのための手段としてRailsは「Rails Wayに乗ることで本来やるべきコアな機能開発に集中することができる」非常に素晴らしいフレームワークです。実際に私はこれまで創業期のスタートアップや現職と約8年間、様々な事業課題と向き合い、その度にRailsを使ってそれらの課題を乗り越えてきました。\n\n    しかし近年は世の中の技術トレンドの変化も激しくなり、以前と比べて技術選定の難易度も上がってきました。React.jsやVue.js、TypeScript、API設計としてもRailsが採用しているRESTと比較してGraphQLが登場する等、特にフロントエンドまわりの技術進化は顕著です。そしてプロダクトとして求められるUI/UXもよりリッチになり、Rails単体よりもRailsと他の技術を組み合わせることでより最短で目的を達成できるようなケースも増えてきました。\n\n    今回のトークではGraphQLやReact.js、TypeScriptといった比較的モダンな技術を採用しつつも、Railsの良さを活かした開発事例として私のプロダクト開発についてお話させていただきます。そしてそれを通じて、私が何を大切に考え、どのような軸で技術選定や設計を行ってきたかをお伝えします。\n\n    資料 https://speakerdeck.com/danimal141/shi-ye-nixiang-kihe-isok-ketaisi-ha-soredemorailswoshi-isok-keru\n\n\n    発表者\n    Hideaki Ishii\n    GitHub https://github.com/danimal141\n    Twitter https://twitter.com/danimal141\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"zFwj-4VIhX4\"\n  slides_url: \"https://speakerdeck.com/danimal141/shi-ye-nixiang-kihe-isok-ketaisi-ha-soredemorailswoshi-isok-keru\"\n\n- id: \"sohei-takeno-kaigi-on-rails-2021\"\n  title: \"マイクロサービス・アーキテクチャと共存する Ruby on Rails のアーキテクチャ的拡張 - その事例と可能性\"\n  raw_title: \"マイクロサービス・アーキテクチャと共存する Ruby on Rails のアーキテクチャ的拡張 - その事例と可能性 / Sohei Takeno\"\n  speakers:\n    - Sohei Takeno\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/Altech_2015/\n\n    近年、コンテナ技術やクラウドサービスの発展によって、必ずしも単一のプログラミング言語のみでシステムを構成しないケースも増えてきました。私たちのサービスにおいても、機械学習技術などの導入の必要から、5年前から Ruby 以外の言語と共存していく形で、マイクロサービス・アーキテクチャを段階的に導入してきました。\n\n    この取り組みの中で、Ruby on Rails 自体のアーキテクチャも見直しが必要になりました。例えば、通信に gRPC を採用する場合、HTTP を前提とした Rack の仕組みには乗ることができず、したがってコントローラー層も再定義する必要があります。ほかにも API スキーマの導入、API レスポンスの型付きの組み立て、ActiveRecord に依存しないデータのバッチローディング機構の導入などを行っています。\n\n    今回の発表では、これらの経験を踏まえて単一の統合システムとして設計された Ruby on Rails を Polyglot なマイクロサービス・アーキテクチャに適合させていくにあたって、どういった課題が一般的にあり、それを私たちのサービスにおいてはどのように解決したのかをお話しします。同じ課題を持っている方はもちろんのこと、アーキテクチャ拡張に対して開かれているという Rails の利点を見直す機会となり、今後の発展可能性の議論につながれば幸いです。\n\n    資料 https://speakerdeck.com/altech/the-architectural-extension-of-ruby-on-rails-to-fit-to-microservices\n\n\n    発表者\n    Sohei Takeno\n    GitHub https://github.com/Altech\n    Twitter https://twitter.com/Altech_2015\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"EqDue9R0qDw\"\n  slides_url: \"https://speakerdeck.com/altech/the-architectural-extension-of-ruby-on-rails-to-fit-to-microservices\"\n\n- id: \"shinkufencer-kaigi-on-rails-2021\"\n  title: \"before_actionとのつらくならない付き合い方\"\n  raw_title: \"before_actionとのつらくならない付き合い方 / しんくう\"\n  speakers:\n    - shinkufencer\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/shinkufencer/\n\n    before_actionは便利な機能が故に様々な使い方をしがちな機能の一つだと思っています。そのため安易に使ったbefore_actionが後々辛くなるケースというのも多いと思います。そのため、この発表では初級者から中級者の方向けに、 before_action :set_foo というscafoldで多くの人が見かける実装を切り口に辛くならないbefore_actionとのつらくならない付き合い方をご紹介できればと思っています。\n\n    資料 https://speakerdeck.com/shinkufencer/how-to-using-before-action-with-happy-in-rails\n\n    発表者\n    しんくう\n    GitHub https://github.com/shinkufencer\n    Twitter https://twitter.com/shinkuFencer\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"9d0ICyegG9Y\"\n  slides_url: \"https://speakerdeck.com/shinkufencer/how-to-using-before-action-with-happy-in-rails\"\n\n- id: \"masato-ohba-kaigi-on-rails-2021\"\n  title: \"Safe Retry with Idempotency-Key Header\"\n  raw_title: \"Safe Retry with Idempotency-Key Header / ohbarye\"\n  speakers:\n    - Masato Ohba\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/ohbarye/\n\n    商品を注文する、顧客にお金を請求する、他人の口座に送金する…。このような、不可逆で二重に行われてほしくない処理をネットワーク越しにリクエストすることがしばしばあります。もしこれらの処理のリクエストにて通信が失敗するとどうなるでしょうか？\n\n    通信エラーに直面したクライアントはリトライするかもしれません。しかし1回目のリクエストでサーバ側の処理が完了していた場合、リトライにより処理が複数回行われてしまう可能性があります。\n\n    この問題を解決する鍵は冪等性です。サービス呼び出しが冪等、つまり「同一リクエストを何度受け取っても結果が変わらない」仕組みをサーバが備えていれば、クライアントは通信が成功するまでリトライできるようになります。\n\n    その仕組みの1つがIETF draftとして提出されているIdempotency-Key Headerです。これはRFC7231にて冪等ではないとされるPOST/PATCHリクエストを冪等にするためのソリューションで、PayPalやStripeなど一部ベンダーは既に類似実装を各社のAPIに適用しています。\n\n    このセッションではIdempotency-Key Headerが解決する課題とコンセプトを解説し、Rubyアプリケーションにおける実装例を紹介します。例の一つは私が携わる金融サービスで設計・実装したものであり、運用を通じて得られた知見も交えてお話します。\n\n    資料 https://speakerdeck.com/ohbarye/safe-retry-with-idempotency-key-header\n\n\n    発表者\n    ohbarye\n    GitHub https://github.com/ohbarye\n    Twitter https://twitter.com/ohbarye\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"WS4pFZ_dd6M\"\n  slides_url: \"https://speakerdeck.com/ohbarye/safe-retry-with-idempotency-key-header\"\n\n- id: \"s4ichi-kaigi-on-rails-2021\"\n  title: \"メトリクス可視化から始める Rails ウェブサーバーのチューニング\"\n  raw_title: \"メトリクス可視化から始める Rails ウェブサーバーのチューニング / s4ichi\"\n  speakers:\n    - s4ichi\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/s4ichi/\n\n    Puma や Unicorn といったウェブサーバーは、Rails アプリケーションをハイパフォーマンスに運用するために欠かせない存在です。これらを適切に設定することはパフォーマンス面で利点がある他、アプリケーションが動作するホストのリソースを効率良く活用することができるため、コストの削減に繋がる可能性があります。しかしながら、サーバーのプロセスやスレッド数の設定ひとつをとっても、動作環境やサービスのアクセス傾向に応じて設定すべき値も変わってくるため、秘伝の設定ですべて事足りるとも限りません。\n\n    本セッションでは Puma や Unicorn からメトリクスを収集・可視化し、Rails アプリケーションをチューニングしていく事例を紹介します。CPU やメモリの状況といった標準的なメトリクスはもちろん、ウェブサーバー特有のメトリクスも利用してチューニングするプロセスを、アクセス傾向が異なる複数のアプリケーションや isucon の問題を実例に解説します。\n\n    資料 https://speakerdeck.com/s4ichi/metorikusuke-shi-hua-karashi-meru-rails-uebusabafalsetiyuningu-kaigi-on-rails-2021\n\n\n    発表者\n    s4ichi\n    GitHub https://github.com/s4ichi\n    Twitter https://twitter.com/s4ichi\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"rrQPyuIxG9I\"\n  slides_url: \"https://speakerdeck.com/s4ichi/metorikusuke-shi-hua-karashi-meru-rails-uebusabafalsetiyuningu-kaigi-on-rails-2021\"\n\n- id: \"imaharu-kaigi-on-rails-2021\"\n  title: \"真の要求を捉え、データベース設計に反映させた話\"\n  raw_title: \"真の要求を捉え、データベース設計に反映させた話 / imaharu\"\n  speakers:\n    - imaharu\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/imaharuTech/\n\n    RailsはActiveRecordパターンを採用しているため、データベース設計がアプリケーションコードの品質に大きく影響します。\n    ステークホルダーの要求を理解することで、データベース設計にどのような変化が生じるのか、実際に作成したER図交え紹介します。\n\n    資料 https://docs.google.com/presentation/d/e/2PACX-1vQMGWBxPMd9Owf_Sna9f1B6wrtmDf4DCaCaorJpzBSDzCID39VLLIthM6z693nZcTX1JrIXEXIITGXc/pub?start=false&loop=false&delayms=3000&slide=id.p\n\n    発表者\n    imaharu\n    GitHub https://github.com/imaharu\n    Twitter https://twitter.com/imaharuTech\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"eqPA5A7elp0\"\n  slides_url:\n    \"https://docs.google.com/presentation/d/e/2PACX-1vQMGWBxPMd9Owf_Sna9f1B6wrtmDf4DCaCaorJpzBSDzCID39VLLIthM6z693nZcTX1JrIXEXIITGXc/pub?start=false&loop=false&delayms=300\\\n    0&slide=id.p\"\n\n- id: \"masato-yamashita-kaigi-on-rails-2021\"\n  title: \"Webサービス開発者としてスタートしてからOSS Contributionまでの道のり\"\n  raw_title: \"Webサービス開発者としてスタートしてからOSS Contributionまでの道のり / Masato Yamashita\"\n  speakers:\n    - Masato Yamashita\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/M_Yamashii/\n\n    Webサービス開発者としてスタートして1年半が過ぎました。\n\n    何も分からなかった状態から、現在は仕事でサービスを改善しつつ、プライベートで記事やOSS Contributionを出すようになりました。\n    ここに至るまでどうやって学んでいったのか、Contributionするまでどんな道のりを歩いてきたのか、Rails初心者の方やOSS Contributionをしてみたい方にお届けします。\n\n    資料 https://speakerdeck.com/myamashii/websabisukai-fa-zhe-tositesutatositekaraoss-contributionmadefalsedao-falseri\n\n\n    発表者\n    Masato Yamashita\n    GitHub https://github.com/M-Yamashita01\n    Twitter https://twitter.com/M_Yamashii\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"zy_x3ewQU84\"\n  slides_url: \"https://speakerdeck.com/myamashii/websabisukai-fa-zhe-tositesutatositekaraoss-contributionmadefalsedao-falseri\"\n\n- id: \"shu-oogawara-kaigi-on-rails-2021\"\n  title: \"Railsバージョンを倍にしたサービスのそれまでとそれから\"\n  raw_title: \"Railsバージョンを倍にしたサービスのそれまでとそれから / Shu Oogawara\"\n  speakers:\n    - Shu Oogawara\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/expajp/\n\n    本発表は二部構成になっています。\n\n    【前半】\n    Rails 3で構築されたサービスが、Rails 4へのバージョンアップすら不可能な状態から、3年がかりのリファクタリングを経て一気にRails 6にするまでを話します。\n    なぜバージョンアップ不可能なサービスになってしまったのか、どのようにリファクタリングを進めたのか、を開発と運用の両面から検証します。\n\n    【後半】\n    前半の内容を足がかりとして、継続的に技術的負債を返却するチームにするまでを話します。\n    まず、大規模リファクタリングとRailsバージョンが上がったことのそれぞれについて、メリットを挙げていきます。\n    また、新機能開発および日々の機能改修を進める傍らで、いかに負債を増やさず、あるいは解消していっているかを説明します。\n\n    Railsバージョンが上げられない現場で苦しい思いをしている方々への事例の提供や、バージョンアップはしているけれど負債が放置されてもやもやしている方々への処方箋となることを目指して話します。\n\n    資料 https://speakerdeck.com/linkers_tech/till-and-from-that-time-of-a-web-service-whose-rails-version-was-doubled-number-kaigionrails\n\n\n    発表者\n    Shu Oogawara\n    GitHub https://github.com/expajp\n    Twitter https://twitter.com/expajp\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"g1jKTvFuuXM\"\n  slides_url: \"https://speakerdeck.com/linkers_tech/till-and-from-that-time-of-a-web-service-whose-rails-version-was-doubled-number-kaigionrails\"\n\n- id: \"yutaka-kamei-kaigi-on-rails-2021\"\n  title: \"logrageの次を考える — Ruby on Railsがデフォルトで出力するログの謎に迫る\"\n  raw_title: \"logrageの次を考える — Ruby on Railsがデフォルトで出力するログの謎に迫る / Yutaka Kamei\"\n  speakers:\n    - Yutaka Kamei\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/yykamei/\n\n    Ruby on Railsのアプリケーションをproductionで運用する場合、出力されるログをFluentdを介して、あるいは直接、Datadogなどの監視ツールに収集することが多いと思います。その際、どのようにログを収集するべきなのかについてドキュメントではlogrageを使った方法が紹介されることが多いです。logrageはRailsが出力するリクエストログなどを構造化されたデータ（多くの場合JSON）に整形してくれるので非常に便利なGemですが、現在logrageのrepositoryがあまり活発ではないのを少し心配しています。このままだと、Ruby on Railsのバージョンアップの際に、互換性などの観点でトラブルが発生するかもしれません。いざというときのために、「そもそもlogrageって何をやっているの？」ということを突き詰め、「logrageを使わないアプローチもあるのではないか？」という謎に迫っていきたいと思います。\n\n    資料 https://docs.google.com/presentation/d/e/2PACX-1vT7IpjvurfAeEatc0Nlq-eC9SXsmJcktxKBragCScJrfhCbudYKnOLtdHBchsqfK7EveHEE2bQS3UKf/pub?start=false&loop=false&delayms=3000&slide=id.p\n\n\n    発表者\n    Yutaka Kamei\n    GitHub https://github.com/yykamei\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"WYMDdBhnLck\"\n  slides_url:\n    \"https://docs.google.com/presentation/d/e/2PACX-1vT7IpjvurfAeEatc0Nlq-eC9SXsmJcktxKBragCScJrfhCbudYKnOLtdHBchsqfK7EveHEE2bQS3UKf/pub?start=false&loop=false&delayms=300\\\n    0&slide=id.p\"\n\n- id: \"masataka-pocke-kuwabara-kaigi-on-rails-2021\"\n  title: \"Cache on Rails\"\n  raw_title: \"Cache on Rails / Masataka Pocke Kuwabara\"\n  speakers:\n    - Masataka Pocke Kuwabara\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2021/talks/pocke/\n\n    We can use many cache mechanisms on Rails. You will know the cache mechanisms and be able to apply them to your application by this talk.\n    私達は様々なキャッシュをRailsで使っています。このトークを聞くと、そのようなキャッシュをあなたのRailsアプリケーションで使えるようになるでしょう。\n\n    I'll talk in Japanese, but the slides are written in English.\n\n    資料 https://docs.google.com/presentation/d/e/2PACX-1vR0xHJzkJ6kW26mROTebtOBGFHbMMEi9zFg69BOeSSZkDMqR5ONoMjZTjLeCPBpJH-yWKumEVuSkggR/pub?start=false&loop=false&delayms=3000&slide=id.p\n\n\n    発表者\n    Masataka Pocke Kuwabara\n    GitHub https://github.com/pocke\n    Twitter https://twitter.com/p_ck_\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"CZOXtWvo7jg\"\n  slides_url:\n    \"https://docs.google.com/presentation/d/e/2PACX-1vR0xHJzkJ6kW26mROTebtOBGFHbMMEi9zFg69BOeSSZkDMqR5ONoMjZTjLeCPBpJH-yWKumEVuSkggR/pub?start=false&loop=false&delayms=300\\\n    0&slide=id.p\"\n\n- id: \"rafael-mendona-frana-kaigi-on-rails-2021\"\n  title: \"Keynote: My road as a Rails Contributor\"\n  raw_title: 'Keynote \"My road as a Rails Contributor\" / Rafael França'\n  speakers:\n    - Rafael Mendonça França\n  event_name: \"Kaigi on Rails 2021\"\n  published_at: \"2021-10-30\"\n  date: \"2021-10-23\"\n  language: \"english\"\n  description: |-\n    https://kaigionrails.org/2021/talks/rafaelfranca/\n\n    RailsコアチームのメンバーであるRafaelさんによる基調講演です。\n    Rafaelさん自身がRailsへの最多コントリビューターになるまでの軌跡を語ります。\n    OSSに関わりたい人や自分のやりたいことを探している人など、全ての開発者に向けたトークです。\n\n    発表者\n    Rafael França\n    GitHub https://github.com/rafaelfranca\n    Twitter https://twitter.com/rafaelfranca\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"0NNhBIgtOzA\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2022/event.yml",
    "content": "---\nid: \"PLiBdJz0juoHC13MYoLxWTpG2aXMAymhVe\"\ntitle: \"Kaigi on Rails 2022\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  Kaigi on Rails is a yearly conference in Tokyo, focusing on Rails and Web development.\npublished_at: \"2022-10-30\"\nstart_date: \"2022-10-21\"\nend_date: \"2022-10-22\"\nchannel_id: \"UCKD7032GuzUjDWEoZsfnwoA\"\nyear: 2022\nbanner_background: \"#333355\"\nfeatured_background: \"#333355\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://kaigionrails.org/2022\"\ncoordinates: false\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2022/videos.yml",
    "content": "---\n- id: \"yasuo-honda-kaigi-on-rails-2022\"\n  title: \"あなたとRails\"\n  raw_title: \"あなたとRails / Yasuo Honda\"\n  speakers:\n    - Yasuo Honda\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/yahonda/\n\n    Railsのメンテナンスポリシーをありのままに理解し、Railsアプリケーションのアップグレードを通じた、Railsへのコントリビューションの可能性をお話しします。\n\n    資料 https://speakerdeck.com/yahonda/anatatorails\n\n    発表者\n    Yasuo Honda\n    GitHub https://github.com/yahonda\n    Twitter https://twitter.com/yahonda\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"q2CG9A677U8\"\n  slides_url: \"https://speakerdeck.com/yahonda/anatatorails\"\n\n- id: \"daisuke-aritomo-osyoyu-kaigi-on-rails-2022\"\n  title: \"お隣さんの API のデータを Rails らしく、しなやかに扱う\"\n  raw_title: \"お隣さんの API のデータを Rails らしく、しなやかに扱う / Daisuke Aritomo (@osyoyu)\"\n  speakers:\n    - Daisuke Aritomo (@osyoyu)\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/osyoyu/\n\n    ますます深まるマイクロサービス時代、APIを通じて取得するデータはドメインの周縁部に留まりません。コアな部分、たとえば「ユーザーの名前」ですら他サービスに問い合わせないと分からない、ということも普通になってきました。\n\n    しかし、Rails にはこれをうまく扱うための「解」はありません。Faraday をインストールし、取得用の Repository クラスを作ってみたり、取得したデータを Hash で渡してみたり、あるいはモデルっぽいクラスにマッピングしてみたり、という「あるある」はあるにせよ、です。\n\n    多くのデータを提供する多くのサービスと接続するアプリを例にとって、API 越しのデータを ActiveRecord の如きしなやかさで扱うための way を探求します。JOIN できないモデルや、ループ内でのリクエストとは別れのときです。\n\n    資料 https://speakerdeck.com/osyoyu/handling-next-door-api-data-in-rails\n\n    発表者\n    Daisuke Aritomo (@osyoyu)\n    GitHub https://github.com/osyoyu\n    Twitter https://twitter.com/osyoyu\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"PanUMkPLu3M\"\n  slides_url: \"https://speakerdeck.com/osyoyu/handling-next-door-api-data-in-rails\"\n\n- id: \"shunsuke-yamada-kaigi-on-rails-2022\"\n  title: \"RBSとSteepで始める型のあるRails開発とその運用\"\n  raw_title: \"RBSとSteepで始める型のあるRails開発とその運用 / Shunsuke Yamada\"\n  speakers:\n    - Shunsuke Yamada\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/yamashun/\n\n    Ruby3で静的型解析がサポートされてしばらく経ちましたが、周辺ツールやエコシステムが発展途上であることや導入事例などの情報が少ないなどの理由で、Railsを使ったアプリケーションへ導入してみたいけど見送るという場合も多いのではないでしょうか。\n    導入にあたっては、RBSを書いて型チェックや入力補完を動かすだけではなく、書いたRBSを修正していく必要があります。そのメンテナンスコストが未知数であることもプロダクトへの導入を躊躇する理由だと思います。\n\n    本セッションでは、静的型解析を導入したRailsアプリケーションで、どのようなルールでRBSを運用しているかやメンテナンスコストを下げるための工夫、発生した課題などについての事例を紹介していきます。\n\n    資料 https://speakerdeck.com/yamashun/rbstosteepdeshi-meruxing-noarurailskai-fa-tosonoyun-yong\n\n    発表者\n    Shunsuke Yamada\n    GitHub https://github.com/yamashun\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"VbXDuYA1sXE\"\n  slides_url: \"https://speakerdeck.com/yamashun/rbstosteepdeshi-meruxing-noarurailskai-fa-tosonoyun-yong\"\n\n- id: \"haruka-oguchi-kaigi-on-rails-2022\"\n  title: \"システム開発を支えるメタプログラミングの技術\"\n  raw_title: \"システム開発を支えるメタプログラミングの技術 / Haruka Oguchi\"\n  speakers:\n    - Haruka Oguchi\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/hogucc/\n\n    Rubyのメタプログラミングはその強力さゆえ、初級者からするといつ使ったらいいかわからない、と思われがちな技法ではないでしょうか。\n    しかし、時にはメタプログラミングについての知識が無いと読めないコードと出会うことがあります。\n    メソッド名で検索したけどヒットしない、なのにメソッドが呼び出せるのはなぜ？といった疑問を持ったことはありませんか？\n    この発表では初級者から中級者の方向けに、Rails本体や著名なgem、オープンソースのRailsアプリでどのようにメタプログラミングの技法が使われているのかコードを読みながらご紹介できればと思っています。\n\n    資料 https://speakerdeck.com/hogucc/kaigionrails-2022\n\n    発表者\n    Haruka Oguchi\n    GitHub https://github.com/hogucc\n    Twitter https://twitter.com/hogucc\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"3r0NzOdIldw\"\n  slides_url: \"https://speakerdeck.com/hogucc/kaigionrails-2022\"\n\n- id: \"shohei-mitani-kaigi-on-rails-2022\"\n  title: \"7つの入金外部サービスと連携して分かった実践的な”状態管理”設計パターン3選\"\n  raw_title: \"7つの入金外部サービスと連携して分かった実践的な”状態管理”設計パターン3選 / Shohei Mitani\"\n  speakers:\n    - Shohei Mitani\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/shohei1913/\n\n    決済・配送・eKYCなど、実装コストがかかる複雑な機能開発では、一部にSaaSを利用することあります。SaaSを利用する際には、自社側と相手側の両方でデータ状態を持ち、適切に同期することで処理を進めます。自社DB内だけにデータが存在する場合と比べて、複数システム間でのデータ管理は難易度がぐっと上がります。皆様の中でも、複数システム間でデータ不整合が起きたり、APIのリクエスト数とレコード数の不一致などの問題に直面したことがある方はいらっしゃるのではないでしょうか？\n\n    私が開発している家計簿プリカ B/43でも入出金にSaaSを利用しています。特にサービスの特性上、幅広い入金手段に対応することがUX向上に繋がるため、これまで7種類の入金手段に対応してきました。それぞれの手段で細部が異なるため、テーブル設計やコントローラーの作りは違うものの、大きく分けると「リアルタイム同期型」、「予約型」、「完全非同期型」の3つに分類することができます。\n\n    決済・入出金といった機能はお金を扱う性質上、一つの実装ミスによるデータ不整合がユーザーの損失に直結するため、細心の注意を払いながら実装しています。このセッションでは、可能な限り安全なシステムを構築するためのTIPSとして、パターン毎に必要なテーブル設計上の要件、バリデーションの実装方法、不整合に対する監視・リカバリの仕組みについて紹介します。\n\n    資料 https://speakerdeck.com/shoheimitani/7tunoru-jin-wai-bu-sabisutolian-xi-sitefen-katutashi-jian-de-na-zhuang-tai-guan-li-she-ji-patan3xuan\n\n    発表者\n    Shohei Mitani\n    Twitter https://twitter.com/shohei1913\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"dn2FsnZq1_g\"\n  slides_url: \"https://speakerdeck.com/shoheimitani/7tunoru-jin-wai-bu-sabisutolian-xi-sitefen-katutashi-jian-de-na-zhuang-tai-guan-li-she-ji-patan3xuan\"\n\n- id: \"natsuko-nadoyama-kaigi-on-rails-2022\"\n  title: \"森羅万象に「いいね」するためのデータ構造\"\n  raw_title: \"森羅万象に「いいね」するためのデータ構造 / Natsuko Nadoyama\"\n  speakers:\n    - Natsuko Nadoyama\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/pndcat/\n\n    サービス開発をしていると「いいね」の実装に対面することは多いでしょう。例えば EC サービスの場合、商品へのいいね、クチコミへのいいね、ブランドへのいいねなど、いろいろな対象に「いいね」をするケースが考えられます。さらには、ログインユーザーの「いいね」と、非ログインユーザーの「いいね」を作ることもあるかもしれません。\n\n    しかし、あらゆるものに「いいね」できるシステムを作るのは容易ならざることです。普通に実装するだけでは関連するコードは肥大化し、データベースのテーブルもどんどん増えていくばかりです。\n\n    似ているけど少し違う「いいね」を実装するにあたって、失敗してしまったデータ設計、そこにあった悩みや苦しみ、それらを解決していくリファクタリングの道すじを説明します。\n\n    資料 https://speakerdeck.com/pndcat/sen-luo-mo-xiang-ni-iine-surutamenodetagou-zao\n\n    発表者\n    Natsuko Nadoyama\n    Twitter https://twitter.com/pndcat\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"WLGCJGDIEJo\"\n  slides_url: \"https://speakerdeck.com/pndcat/sen-luo-mo-xiang-ni-iine-surutamenodetagou-zao\"\n\n- id: \"keita-urashima-kaigi-on-rails-2022\"\n  title: \"大量塩基配列登録申請システムができるまで\"\n  raw_title: \"大量塩基配列登録申請システムができるまで / Keita Urashima\"\n  speakers:\n    - Keita Urashima\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/ursm/\n\n    今日の生命科学研究には塩基配列データというものが欠かせません。これは生物の遺伝情報を特定のルールに従って表現したもので、ATTAAAGGTT... のような見た目をしています。\n\n    塩基配列データは科学の公共財であり、目的や国籍に関わらず誰でも利用できることが望ましいと考えられます。そのため日米欧の研究機関は連携して国際塩基配列データベースの共同運用をしています。この取り組みを INSDC (International Nucleotide Sequence Database Collaboration) と言います。\n\n    INSDC の一員として塩基配列データベースの構築・運用を行っている日本の組織が DDBJ (DNA Data Bank of Japan) センターです。国内の研究者は DDBJ センターに塩基配列データを提出することで世界中の研究者に自身の成果を共有できます。\n\n    さて、簡単に「データを提出する」と書きましたが、そのデータが例えば 10GB ある場合はどうしたらいいでしょうか。アップロードしてもらうだけなら何とかなるかもしれませんが、パースした結果をその場でユーザに提示したいとなったらどうでしょうか。今回はそんな Web システムの開発を請け負った話をします。\n\n    資料 https://speakerdeck.com/ursm/da-liang-yan-ji-pei-lie-deng-lu-shen-qing-sisutemugadekirumade\n\n    発表者\n    Keita Urashima\n    GitHub https://github.com/ursm\n    Twitter https://twitter.com/ursm\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"ZezjGxI5qM0\"\n  slides_url: \"https://speakerdeck.com/ursm/da-liang-yan-ji-pei-lie-deng-lu-shen-qing-sisutemugadekirumade\"\n\n- id: \"masatoshi-moritsuka-kaigi-on-rails-2022\"\n  title: \"実例で学ぶRailsアプリケーションデバッグ入門 〜ログインできちゃってました編〜\"\n  raw_title: \"実例で学ぶRailsアプリケーションデバッグ入門 〜ログインできちゃってました編〜 / Masatoshi Moritsuka\"\n  speakers:\n    - Masatoshi Moritsuka\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/sanfrecce_osaka/\n\n    Webアプリケーションに限らず実際の開発ではコードを書く時間よりもコードを読んだりデバッグしたりしている時間のほうが長いです\n    実務ではアプリケーションコード自体に加え多数のgemも絡み、さらにそのgemの中にはRailsも含めてメタプログラミングを多用してくるものもあり非常に複雑なソースコードを読み解いていかなければなりません\n    今回は弊社で実際にあった「サービスを退会したアカウントが退会後もログインできてサービスを利用できてしまっていた」という事例を通して、Railsアプリケーションを開発していく上で役立つデバッグやコードリーディングのテクニックを紹介していきます\n\n    資料 https://speakerdeck.com/sanfrecce_osaka/rails-application-debug-introduction\n\n    発表者\n    Masatoshi Moritsuka\n    GitHub https://github.com/sanfrecce-osaka\n    Twitter https://twitter.com/sanfrecce_osaka\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"XUNz2C5O0qg\"\n  slides_url: \"https://speakerdeck.com/sanfrecce_osaka/rails-application-debug-introduction\"\n\n- id: \"daisuke-fujimura-kaigi-on-rails-2022\"\n  title: \"既存Railsアプリ攻略法 - CTOが見ること・やること・考えること\"\n  raw_title: \"既存Railsアプリ攻略法 - CTOが見ること・やること・考えること / Daisuke Fujimura\"\n  speakers:\n    - Daisuke Fujimura\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/fujimura/\n\n    Railsで仕事をしていると、rails new するより既存のアプリケーションを触ることのほうが多いですよね。私も昨年、新しく自分が働いている会社に加わったプロダクトのRailsアプリケーションを触り改善するという仕事をしました。\n\n    そんなとき、一人のRailsエンジニアとして、また現在勤めているCTOという経営幹部として、どんな観点で何を見て、何を目指してどんなことをしているのか、を具体的にお話しすることで、みなさんが新たに既存のRailsリポジトリと出会うときに何をするとよいか？というベストプラクティスめいたものを提示できればと思います。\n\n    何をするにも目指すことは「プロダクト開発のアジリティが向上して、スムーズにお客さんに価値を提供し続けられること」なのですが、やることは多岐に渡ります。コードフォーマットの修正からリリース体制の開演、ほとんど使われていない機能の削除など本当にいろいろです。それぞれ、何が課題なのか？改善したいことは何か？具体的に何をしたのか？をお話しします。\n\n    また、既存のRailsアプリケーションとの付き合い方のベストプラクティスを提案するなかで、CTOがRailsエンジニアとして仕事をするときに何を考えているのか？という観点の紹介をスパイスとして散りばめようと思っています。ここも楽しんでいただけれたら幸いです。\n\n    資料 https://speakerdeck.com/fujimura/kaigi-on-rails-2022-ji-cun-railsapurigong-lue-fa-ctogajian-rukotoyarukotokao-erukoto\n\n    発表者\n    Daisuke Fujimura\n    GitHub https://github.com/fujimura\n    Twitter https://twitter.com/ffu_\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"VupPYilamMQ\"\n  slides_url: \"https://speakerdeck.com/fujimura/kaigi-on-rails-2022-ji-cun-railsapurigong-lue-fa-ctogajian-rukotoyarukotokao-erukoto\"\n\n- id: \"shia-kaigi-on-rails-2022\"\n  title: \"差分ベースで効率的にテストを実行してみる\"\n  raw_title: \"差分ベースで効率的にテストを実行してみる / Shia\"\n  speakers:\n    - Shia\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/riseshia/\n\n    テストは大事！テストがあれば安心！ということでテストをバリバリ書いていったn年後。\n    テストが重くなり、不要に Factory に紐付いてるすべてのアソシエーションを憎むようになったり、統合テストなんて無駄！という気持ちになったことはないですか？\n    この発表では CI を通っているコードを動的分析し、追加・変更されたファイルから実行すべきテストを計算し効率的にテストを実行する手法を試した結果と長所・短所などを解説します。\n\n    資料 https://speakerdeck.com/riseshia/chai-fen-besudexiao-lu-de-nitesutowoshi-xing-sitemiru\n\n    発表者\n    Shia\n    GitHub https://github.com/riseshia\n    Twitter https://twitter.com/riseshia\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"rSpe3k5WK0g\"\n  slides_url: \"https://speakerdeck.com/riseshia/chai-fen-besudexiao-lu-de-nitesutowoshi-xing-sitemiru\"\n\n- id: \"tomohiro-suwa-kaigi-on-rails-2022\"\n  title: \"3rd Party API on Rails\"\n  raw_title: \"3rd Party API on Rails / Tomohiro Suwa\"\n  speakers:\n    - Tomohiro Suwa\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/tsuwatch/\n\n    ファッションコーディネートアプリ「WEAR」はサービス内だけではなく、さまざまなサービスとのコーディネート画像の連携を通じて、より多くのユーザーにファッションの楽しさをお届けできるよう取り組んでいます。それを実現するために「WEAR」はサードパーティに提供するAPIをRuby on Railsで構築しました。サードパーティのAPIを利用することは多くても、提供することやどのように実現しているのか、どのような課題が発生したのかなど、リアルな情報をお伝えできればと思います\n\n    資料 https://speakerdeck.com/tsuwatch/3rd-party-api-on-rails\n\n    発表者\n    Tomohiro Suwa\n    GitHub https://github.com/tsuwatch\n    Twitter https://twitter.com/tsuwatch\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"qTuF_SFUFwk\"\n  slides_url: \"https://speakerdeck.com/tsuwatch/3rd-party-api-on-rails\"\n\n- id: \"masato-ohba-kaigi-on-rails-2022\"\n  title: \"Balance Security and Usability in the Field of 3D Secure\"\n  raw_title: \"Balance Security and Usability in the Field of 3D Secure / Masato Ohba\"\n  speakers:\n    - Masato Ohba\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/ohbarye/\n\n    ECサイトでクレジットカード決済を行う際にパスワードによる認証を求められたことはありませんか。\n\n    この仕組みは3Dセキュアと呼ばれる本人認証サービスであり、カードの盗用やなりすましなどの不正利用の防止に寄与しています。遡ると20年近い歴史がある3Dセキュアの本人認証ではパスワードによる知識認証が主流でしたが、近年はOTPを用いた所有物認証や指紋等による生体認証といった利便性の高い認証方法も導入されています。\n\n    一般的なWebサービスにおける認証と3Dセキュアの認証には類似点が多々ありますが、大きな違いもあります。VisaやMastercard等の持つ巨大な分散システムと連携して本人認証を行うこと、取引の金額や様々な情報をもとにリスクを判定して認証を省略するアプローチがあることです。特に後者の「セキュリティとユーザーの利便性を両立させる余地がある」というのは面白いポイントです。\n\n    このセッションでは登壇者が開発・運用を通じて知った3Dセキュアの裏側を覗き、「不正利用との戦い」とも言われるクレジットカードの歴史と創意工夫の一端に触れてみます。カード事業に携わることがなければ知ることがないであろう領域ですが、そこで活用されている技術は馴染み深いネットワークやセキュリティの応用であり、Webアプリケーション開発者にとって地続きの世界であることを実感いただけると思います。\n\n    資料 https://speakerdeck.com/ohbarye/balance-security-and-usability-in-the-field-of-3d-secure\n\n    発表者\n    Masato Ohba\n    GitHub https://github.com/ohbarye\n    Twitter https://twitter.com/ohbarye\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"K3BWiXqXuwI\"\n  slides_url: \"https://speakerdeck.com/ohbarye/balance-security-and-usability-in-the-field-of-3d-secure\"\n\n- id: \"makicamel-kaigi-on-rails-2022\"\n  title: \"歴史あるプロジェクトのとある技術的負債を隙間プロジェクトの 210 PullRequests で倒しきった話\"\n  raw_title: \"歴史あるプロジェクトのとある技術的負債を隙間プロジェクトの 210 PullRequests で倒しきった話 / makicamel\"\n  speakers:\n    - makicamel\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-21\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/makicamel/\n\n    技術的負債は事業の成長にあわせ、借り入れられ、返されます。歴史あるプロジェクトでは大なり小なり抱えているのではないでしょうか。\n    話者の勤める会社でも、開発初〜中期に取り入れられた独自フレームワークが技術的負債となっていました。\n    隙間プロジェクトとして負債を返し続けること約 11 ヶ月 210 PullRequests、ついに返しきりました。\n\n    本トークでは巨大な負債解消への取り組み方、変更リスクとコストを下げた方法についてお話します。\n    技術的負債と戦う人の一助に、あるいは戦いたい人の後押しになれば幸いです。\n\n    資料 https://speakerdeck.com/makicamel/how-to-say-goodbye-to-technical-debt\n\n    発表者\n    makicamel\n    GitHub https://github.com/makicamel\n    Twitter https://twitter.com/makicamel\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"moYVIwHYcnE\"\n  slides_url: \"https://speakerdeck.com/makicamel/how-to-say-goodbye-to-technical-debt\"\n\n- id: \"fu-ga-kaigi-on-rails-2022\"\n  title: '入社数ヶ月の newbie が稼働7年超のRailsプロジェクトに\"型\"を導入して見えた世界'\n  raw_title: '入社数ヶ月の newbie が稼働7年超のRailsプロジェクトに\"型\"を導入して見えた世界 / Fu-ga'\n  speakers:\n    - Fu-ga\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/fugakkbn/\n\n    私は数ヶ月前に異業種からWEBエンジニアにキャリアチェンジしたばかりの、いわゆる newbie です。\n    にも関わらず、サービスインから7年以上稼働している Rails アプリケーションに RBS, Steep を使用して型導入を主体的に進めています。\n\n    まだ完全に導入が完了しているわけではありませんが、現段階での私の結論は「newbie こそ型を書こう！」です。\n\n    型を書くことで得られるのは、「型を導入した」という事実のみに留まりません。多くの newbie が最初に苦労するであろうプロジェクトへの理解を後押ししますし、OSS へのコントリビューションをしたいけど何をしたらいいかわからない、という悩みをも解決します。\n    私自身の経験を通じて見えるようになった世界をお話しします。\n\n    また、この発表は newbie のみに向けたお話ではありません。大規模プロジェクトへの型導入は一筋縄ではいきませんが、相応のメリットがあります。\n    型を導入して享受できる恩恵は何か、どのように進めるのか、導入にあたっての障壁はどんなものか…。Rails における型の現状についても知っていただけたらと思います。\n\n    資料 https://speakerdeck.com/fugakkbn/ru-she-shu-keyue-nonewbiega-jia-dong-7nian-chao-nopuroziekutoni-xing-wodao-ru-sitejian-etashi-jie\n\n    発表者\n    Fu-ga\n    GitHub https://github.com/fugakkbn\n    Twitter https://twitter.com/fugakkbn\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"6QjrKkK-4pY\"\n  slides_url: \"https://speakerdeck.com/fugakkbn/ru-she-shu-keyue-nonewbiega-jia-dong-7nian-chao-nopuroziekutoni-xing-wodao-ru-sitejian-etashi-jie\"\n\n- id: \"hirotaka-miyagi-kaigi-on-rails-2022\"\n  title: \"sassc-railsを利用している我々は、Sassの@importの非推奨化をどのように乗り越えていくか\"\n  raw_title: \"sassc-railsを利用している我々は、Sassの@importの非推奨化をどのように乗り越えていくか / Hirotaka Miyagi\"\n  speakers:\n    - Hirotaka Miyagi\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/mh4gf/\n\n    RailsプロジェクトでSassを利用する際、今まではsassc-rails gemと@importを利用してアセットパイプラインに乗せていたプロジェクトが多いのではないでしょうか。\n    しかし、Sassの@import構文と、sassc-railsが内部的に利用しているSassコンパイラであるLibSassはdeprecatedになってしまいます。代替手段として@use構文に乗り換えていく必要がありますが、LibSassでは@use構文を使うことはできません。@useが使えるDart実装のDartSassに移行する必要があります。\n\n    このセッションでは、LibSass / DartSassなどの関連知識と、Rails7でRailsチームから提案されている複数のアセット管理方法も絡めて紹介し、技術選定や導入時の罠・QA方法まで含めて、@importから@useに移行していくための実践方法を紹介します。\n\n    資料 https://speakerdeck.com/mh4gf/sassc-railswoli-yong-siteiruwo-ha-sassno-at-importnofei-tui-jiang-hua-wodonoyounicheng-riyue-eteikuka\n\n    発表者\n    Hirotaka Miyagi\n    GitHub https://github.com/mh4gf\n    Twitter https://twitter.com/mh4gf\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"9J-V_p9A9PI\"\n  slides_url: \"https://speakerdeck.com/mh4gf/sassc-railswoli-yong-siteiruwo-ha-sassno-at-importnofei-tui-jiang-hua-wodonoyounicheng-riyue-eteikuka\"\n\n- id: \"kei-shiratsuchi-kaigi-on-rails-2022\"\n  title: \"実践 Rails アソシエーションリファクタリング\"\n  raw_title: \"実践 Rails アソシエーションリファクタリング / Kei Shiratsuchi\"\n  speakers:\n    - Kei Shiratsuchi\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/kei-s/\n\n    設計当初は妥当だと思っていたActiveRecordの関連付け（アソシエーション）、サービスが成長していくにつれて再設計・リファクタリングしたくなっていませんか？\n    当初は単純な has_many で良かったけど、中間モデルを導入した方がより良い設計になるのに...\n    ポリモーフィック関連がアンチパターンなのは知っているけど、どうやって直していったら...\n    そんなことを考えている間にもサービスは成長を続け、レコード数は日々増大し、開発も活発で利用箇所を網羅するのも一苦労...躊躇してしまうのは当然です。\n\n    このセッションでは、私が実際にRailsのアソシエーションをリファクタリングしている中で得た、様々なプラクティスをご紹介します。\n    メンテナンスタイムなしでリファクタリングを進めるためのステップ、リレーションの利用箇所を徹底的に洗い出すハックなど、実践的な知見をお伝えします。\n\n    資料 https://speakerdeck.com/kei_s/rails-association-refactoring-in-practice\n\n    発表者\n    Kei Shiratsuchi\n    GitHub https://github.com/kei-s\n    Twitter https://twitter.com/kei_s\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"Rfni8PMizJc\"\n  slides_url: \"https://speakerdeck.com/kei_s/rails-association-refactoring-in-practice\"\n\n- id: \"andrey-novikov-kaigi-on-rails-2022\"\n  title: \"ルビイストの目で見たPostgreSQLのデータ型\"\n  raw_title: \"ルビイストの目で見たPostgreSQLのデータ型 / Andrey NOVIKOV\"\n  speakers:\n    - Andrey Novikov\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/Envek/\n\n    最近10年間に、PostgreSQLはRubyコミュニティに最も人気のあるデータベース管理システムになりました。PostgreSQLには多数の機能やデータ型があります。Ruby標準ライブラリにも多くのデータ型のクラスがあって、Railsはさらに複数のデータ型を加えています\n    その際、あるデータ型はRubyとPostgreSQLの両方に含まれていますが、そのデータ型は本当に同一のものでしょうか？また、PostgreSQLとRubyの間でデータを移動するとき、どんな問題が発生する可能性があるのでしょうか？両方のシステムにある機能を比べながら、どうすればRubyのデータ型もPostgreSQLのデータ型も１００％に使えるようにできるかを、私はこの発表でお話ししたいと思います。\n\n    ※ イベント当日に時間の都合上カットした内容が含まれています\n\n    資料 https://envek.github.io/kaigionrails-postgresql-as-seen-by-rubyists/\n\n    発表者\n    Andrey Novikov\n    GitHub https://github.com/Envek\n    Twitter https://twitter.com/Envek\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"bwoNv_tAMkI\"\n\n- id: \"hiroya-shimamoto-kaigi-on-rails-2022\"\n  title: \"モノリシックRailsアプリケーションをモジュラモノリスへ移行しているnoteの事例\"\n  raw_title: \"モノリシックRailsアプリケーションをモジュラモノリスへ移行しているnoteの事例 / Hiroya Shimamoto\"\n  speakers:\n    - Hiroya Shimamoto\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/shshimamo/\n\n    私たちのサービス(note)のバックエンドは、Model 数が 800 以上と比較的大規模なモノリシックRailsアプリケーションで構成されています。\n    また関わるエンジニアの人数も40名程度のため、開発効率の低下、バグの増加といった課題が顕在化してきました。\n\n    このような課題に対しマイクロサービスアーキテクチャを検討しましたが、アーキテクチャ検討の前にまずはドメイン分割を進める必要があると考えました。\n    そこで Packwerk という Shopify が開発した gem を導入することにしました。\n\n    Packwerk は、モジュラーモノリス化を支援してくれる gem です。\n    設定したディレクトリをモジュールとみなし、モジュール間の依存関係を静的解析で検出してくれます。\n    モジュール化は基本的にはファイル移動だけなので、ドメイン分割を段階的に進めることができ、やり直しも容易にできます。\n\n    これらの特徴は、「機能開発と並行して進めたい」「試行錯誤しながら段階的に進めたい」という私たちの要望を満たしてくれるものでした。\n\n    今回の発表では、Packwerk の基本機能や導入方法のご紹介、実際に導入して見え始めた効果や、今後の課題などをお話しできればと思っています。\n\n    資料 https://speakerdeck.com/shshimamo/monorisitukurailsapurikesiyonwo-moziyuramonorisuheyi-xing-siteiru-notenoshi-li\n\n    発表者\n    Hiroya Shimamoto\n    GitHub https://github.com/shshimamo\n    Twitter https://twitter.com/shshimamo\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"-8R5bMbxgOM\"\n  slides_url: \"https://speakerdeck.com/shshimamo/monorisitukurailsapurikesiyonwo-moziyuramonorisuheyi-xing-siteiru-notenoshi-li\"\n\n- id: \"osyo-kaigi-on-rails-2022\"\n  title: \"ActiveRecord::Relation ってなに？\"\n  raw_title: \"ActiveRecord::Relation ってなに？ / osyo\"\n  speakers:\n    - osyo-manga\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/osyo/\n\n    皆さんは User.where(active: true).order(:age) の結果がなにを返すかご存知ですか。\n    User の配列が出力されるから配列が返ってくる？いいえ、違います。\n    普段なにげなく使っている ActiveRecord ですがこのセッションでは実際に内部でどのように動作しているのかを少し覗いてみましょう。\n    User.where(active: true).order(:age) がなにを返すのか、またどのようにして ActiveRecord が SQL 文を生成しているのかをライブコーディングを交えながら解説します。\n    普段 Rails を使っている人がもう1歩進んだ Rails の知識を一緒に学んで行きましょう。\n\n    資料 https://www.docswell.com/s/pink_bangbi/K88ELK-2022-10-22-133810\n\n    発表者\n    osyo\n    GitHub https://github.com/osyo-manga\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"gxaB96E-_GQ\"\n\n- id: \"sunao-hogelog-komuro-kaigi-on-rails-2022\"\n  title: \"十年ものアプリのセッションストレージをクッキーからRedisに移行するときに気にしたこと、それでも起きてしまったこと\"\n  raw_title: \"十年ものアプリのセッションストレージをクッキーからRedisに移行するときに気にしたこと、それでも起きてしまったこと / hogelog\"\n  speakers:\n    - Sunao Hogelog Komuro\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/hogelog/\n\n    rails new したばかりのアプリケーションのセッションストレージはなんでしょう。そう、特別なテンプレートを使わない限り CookieStore です。\n    Rails のデフォルト設定ですし追加インフラも不要で利用も容易なため採用しているアプリケーションも多いでしょう。\n\n    しかしセキュリティのベストプラクティスによると、セッションストレージをサーバサイドに寄せるよう推奨されることも多いです。さてそこでセッションストレージをクッキーから切り替えるとしましょう。\n\n    アプリケーションがリリース前だったら？ ストレージ切り替えを実装するだけですね。\n    リリース済みだがセッションのリセットが許容されるなら？ ストレージを切り替えてデプロイするだけですね。\n    アプリケーションはリリース済みだし、セッションを維持したままストレージを切り替えたいときは？ この場合なにをどうしていくべきか、Rails によるレールは敷かれていません。\n\n    私達は運用10年目となる1000万オーダーのセッションを持つ Rails アプリケーションのセッションストレージを、セッションを維持したまま Cookie から Redis (MemoryDB) に移行しました。\n    セッションストレージの移行をどんな方法で進めたか、どんな実装をしたか、どんなことを気にしていたか、それでも起きたトラブルや移行した結果についてお話しします。\n\n    資料 https://speakerdeck.com/hogelog/kaigi-on-rails-2022-talk-hogelog\n\n    発表者\n    hogelog\n    GitHub https://github.com/hogelog\n    Twitter https://twitter.com/hogelog\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"hKUm6i4j1hI\"\n  slides_url: \"https://speakerdeck.com/hogelog/kaigi-on-rails-2022-talk-hogelog\"\n\n- id: \"yuki-akamatsu-kaigi-on-rails-2022\"\n  title: \"今年できたチームの生産性を向上させたプラクティスの紹介\"\n  raw_title: \"今年できたチームの生産性を向上させたプラクティスの紹介 / Yuki Akamatsu\"\n  speakers:\n    - Yuki Akamatsu\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/ukstudio/\n\n    このトークでは今年あたらしく結成された開発チームがシンプルなプラクティスによってチームの技術ナレッジを底上げし、生産性を向上させることができたことについて話します。\n\n    私達の開発チームはバックエンド、モバイルあわせて10人を越える程度のチームで一般的なWeb開発のチームとしては大きくも小さくもない規模だと思います。とはいえチームとしては新しく、特にバックエンドエンジニアは今年配属された新卒や、数年以上の経験があるシニアが混在し、また自分達が開発するアプリケーションに関する知識も人によってバラつきがある状態で、チームのアウトプットがなかなか安定しない状態でした。\n\n    日々の開発の中でふりかえりを継続的に行ない、特に効果的だったプラクティスについて紹介します。またプラクティスの内容だけでなく、導入にあたってうまくいかなかったことなども紹介し、この発表を聞いた参加者がよりスムーズに自分達の開発チームに適用できる情報を提供します。\n\n    資料 https://speakerdeck.com/ukstudio/kaigi-on-rails-2022\n\n    発表者\n    Yuki Akamatsu\n    GitHub https://github.com/ukstudio\n    Twitter https://twitter.com/ukstudio\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"_L_sxSgzQP4\"\n  slides_url: \"https://speakerdeck.com/ukstudio/kaigi-on-rails-2022\"\n\n- title: \"Test code concepts to keep in mind for now with Rails\"\n  original_title: \"とりあえず抑えておきたい、Railsでの「テストの内容」の考えかた\"\n  raw_title: \"とりあえず抑えておきたい、Railsでの「テストの内容」の考えかた / しんくう\"\n  speakers:\n    - shinkufencer\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  id: \"test-code-concepts-to-keep-in-mind-for-now-with-rails\"\n  slug: \"test-code-concepts-to-keep-in-mind-for-now-with-rails\"\n  description: |-\n    https://kaigionrails.org/2022/talks/shinkufencer/\n\n    RSpecなどでテストコードを書くとき、ある程度書き方や書く対象に関しては理解できています。しかしながらテストコードで書くべき内容に関してはどこまで書いて良いかわからなくなるタイミングがあります。この発表ではテストコードを書く上で抑えておきたいテストで扱うべき「内容」に関してざっとご紹介できればと思っています。\n\n    資料 https://speakerdeck.com/shinkufencer/test-code-concepts-to-keep-in-mind-for-now-with-rails\n\n    発表者\n    しんくう\n    GitHub https://github.com/shinkufencer\n    Twitter https://twitter.com/shinkufencer\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"F3tV6xGb1Vc\"\n  slides_url: \"https://speakerdeck.com/shinkufencer/test-code-concepts-to-keep-in-mind-for-now-with-rails\"\n\n- id: \"ikuma-t-kaigi-on-rails-2022\"\n  title: \"自分だけの小さなSelenium「Olenium」を作って始める、ブラウザ自動化技術の理論と実践\"\n  raw_title: \"自分だけの小さなSelenium「Olenium」を作って始める、ブラウザ自動化技術の理論と実践 / ikuma-t\"\n  speakers:\n    - ikuma-t\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2022/talks/ikumatdkr/\n\n    E2Eテストの実行にはブラウザの自動化が必要不可欠ですが、アプリケーションコード内で完結するユニットテストやインテグレーションテストとは違って、ブラウザ自動化を利用したテストは登場人物や設定が多いです。そのためテストが実行できるようになっても、正直なところその詳細をいまいち理解しておらず、ブラウザ自動化は私にとって技術というより魔法でした。\n\n    今年業務未経験から学習を始めて晴れてWebエンジニアになることができました。職業プログラマとなったことは、Web技術の中核であるブラウザを自分がどう動かしているのかを理解していないことへのコンプレックスを強めると同時に、ブラウザ自動化技術への関心を高めるきっかけとなりました。\n\n    「誰かが作ったフレームワークで動くものはできるようになったけど、その先を理解できるようになりたい」\n    「プログラマとして技術を扱っていく以上、魔法で済ませるのではなく自分で使いこなせるようになりたい」\n\n    この発表では普段SeleniumやPlayWrightがいい感じに隠蔽してくれているブラウザ自動化の仕組みを、各仕様のドキュメントとシンプルなcurlコマンド等で読み解いていき、最終的に「Olenium」「OlayWright」というRubyを使ったオレオレ簡易実装につなげることで、その全体像を理解していきます。\n\n    資料 https://speakerdeck.com/ikumatadokoro/zi-fen-dakenoxiao-sanaselenium-olenium-wozuo-tuteshi-meru-burauzazi-dong-hua-ji-shu-noli-lun-toshi-jian\n\n    発表者\n    ikuma-t\n    GitHub https://github.com/IkumaTadokoro\n    Twitter https://twitter.com/ikumatdkr\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"q2wESM38i6M\"\n  slides_url: \"https://speakerdeck.com/ikumatadokoro/zi-fen-dakenoxiao-sanaselenium-olenium-wozuo-tuteshi-meru-burauzazi-dong-hua-ji-shu-noli-lun-toshi-jian\"\n- id: \"nate-berkopec-kaigi-on-rails-2022\"\n  title: \"All About Queueing In Rails Applications\"\n  raw_title: \"All About Queueing In Rails Applications / Nate Berkopec\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"Kaigi on Rails 2022\"\n  date: \"2022-10-22\"\n  published_at: \"2022-10-30\"\n  language: \"english\"\n  description: |-\n    https://kaigionrails.org/2022/talks/nateberkopec/\n\n    What's a queue? What's it for? And why do Rails apps have so many? Let's take a look at three of the most important queues in any Rails application, how to manage them, and how to design them for efficiency and ease of use. We'll talk about how requests queue for our web servers, how to manage unruly lists of Sidekiq queues, and how queueing for the GVL determines the optimal thread count for Puma and Sidekiq.\n\n    資料 https://speakerdeck.com/nateberkopec/kaigi-on-rails\n\n    発表者\n    Nate Berkopec\n    GitHub https://github.com/nateberkopec\n    Twitter https://twitter.com/nateberkopec\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"22dNif8d7uI\"\n  slides_url: \"https://speakerdeck.com/nateberkopec/kaigi-on-rails\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2023/event.yml",
    "content": "---\nid: \"PLiBdJz0juoHCzq2SMiZIJP5diigoNEuYl\"\ntitle: \"Kaigi on Rails 2023\"\nkind: \"conference\"\nlocation: \"Taito City, Tokyo, Japan\"\nhybrid: true\ndescription: |-\n  Kaigi on Rails is a yearly conference in Tokyo, focusing on Rails and Web development.\npublished_at: \"2023-11-02\"\nstart_date: \"2023-10-27\"\nend_date: \"2023-10-28\"\nchannel_id: \"UCKD7032GuzUjDWEoZsfnwoA\"\nyear: 2023\nbanner_background: \"#EBCFCA\"\nfeatured_background: \"#EBCFCA\"\nfeatured_color: \"#1A1919\"\nwebsite: \"https://kaigionrails.org/2023\"\ncoordinates:\n  latitude: 35.6764225\n  longitude: 139.650027\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2023/videos.yml",
    "content": "---\n- id: \"zachary-scott-kaigi-on-rails-2023\"\n  title: \"準備中\"\n  raw_title: \"準備中 / zzak - Kaigi on Rails 2023\"\n  speakers:\n    - Zachary Scott\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"english\"\n  description: |-\n    https://kaigionrails.org/2023/talks/zzak/\n\n    【発表者】\n    zzak\n    GitHub https://github.com/zzak\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"oFXCqRuvgds\"\n\n- id: \"makicamel-kaigi-on-rails-2023\"\n  title: \"Rails アプリの 5,000 件の N+1 問題と戦っている話\"\n  raw_title: \"Rails アプリの 5,000 件の N+1 問題と戦っている話 / makicamel - Kaigi on Rails 2023\"\n  speakers:\n    - makicamel\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/makicamel/\n\n    【発表概要】\n    話者の勤める会社のとある歴史あるリポジトリでは CI で約 5,000 件の N+1 問題が検知されていました。 N+1 問題はパフォーマンス劣化の代表的な要因のひとつです。 Rails にはこれを解決する includes というメソッドがあり、これを警告する Bullet という gem があります。 Bullet の警告箇所に includes を差し込めばよさそうですが、5,000 件の手修正は億劫なので実行時に N+1 クエリ発行箇所に includes を差し込む gem を作りました。\n\n    しかし現実のアプリケーションは複雑で、単純に includes すればよいというものではありません。 例えば以下のコードは alias が重複しエラーになります。\n\n    Play.joins(:actors).includes(actors: :company).joins('INNER JOIN companies force index(primary) ON companies.id = actors.company_id').load\n\n    エラーにならなくとも不要な includes はパフォーマンス劣化を招きます。 こうした意図しない変更を避けて includes を差し込む必要があります。\n\n    本セッションでは作った gem の解説と、この gem による修正をリリースする話をします。\n\n\n    【発表者】\n    makicamel\n    GitHub https://github.com/makicamel\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"LGtKlF2Nb9A\"\n\n- id: \"ikuma-tadokoro-kaigi-on-rails-2023\"\n  title: \"HTTPリクエストを手で書いて学ぶ ファイルアップロードの仕組み\"\n  raw_title: \"HTTPリクエストを手で書いて学ぶ ファイルアップロードの仕組み / ikuma-t - Kaigi on Rails 2023\"\n  speakers:\n    - Ikuma Tadokoro\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/ikuma-t/\n\n    【発表概要】\n    ファイルアップロードはWebアプリケーションにおいて基本的な機能です。Railsでプログラミングの学習を始めた場合、フォームヘルパーを設置してparamsからデータを取得する処理を書けば、あるいはActiveStorageを使えばファイルアップロード処理は簡単に作れるでしょう。\n\n    一方でその間を流れるHTTPリクエストを正しく理解できているでしょうか？\n\n    恥ずかしながらエンジニアになりたての頃、私はそれを理解せずに使っていました。既存のRailsアプリのためのデバッグで実際のリクエストを確認する際や、HTMLではなくJavaScriptでファイルアップロードを行う際に手間取ってしまうなど、「ファイルアップロード」という機能の単位でしか自分の書いた処理を理解できていませんでした。\n\n    ファイルアップロードの方法について、言語やフレームワーク、送り手側/受け手側の差異はあれど、基礎となる部分はいずれもHTTPリクエストです。とはいえファイルアップロードを行うためのリクエストにもいくつかの方法があります。\n\n    この発表ではファイルアップロード時に発行されるHTTPリクエストを、仕様を読み解きながら自分の手で組み立てていくことでその全体像を理解していきます。\n\n\n    【発表者】\n    ikuma-t\n    GitHub https://github.com/IkumaTadokoro\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"zUuaLufXY00\"\n\n- id: \"mizuki-asada-kaigi-on-rails-2023\"\n  title: \"生きた Rails アプリケーションへの delegated types の導入\"\n  raw_title: \"生きた Rails アプリケーションへの delegated types の導入 / mozamimy  - Kaigi on Rails 2023\"\n  speakers:\n    - Mizuki Asada\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/mozamimy/\n\n    【発表概要】\n    Rails では、あるモデルの属性を別のモデルに引き継ぐ、つまり継承を実現するための仕組みがいくつか用意されています。\n\n    そのひとつである STI は比較的古くから存在しているアプローチで、利便性と引き換えに課せられるデメリットも大きいとされています。いっぽう Rails 6.1 で実装された delegated types は、STI を利用した際に負うデメリットのいくつかを解消できるアプローチとなっています。\n\n    delegated types の基本的な利用方法やサンプルコードを使った例は API ドキュメントやその他記事で読めますが、生きている Rails アプリケーションにおいて、設計初期ではなく、ある程度開発が進んでから導入したという事例について気になる方も多いのではないでしょうか。初めて delegated types を知った方にとってもそのような情報は有用なはずです。\n\n    このセッションでは、hako-console という社内向け Rails アプリケーションで、デプロイ履歴のモデリングに delegated types を導入し、既存テーブルの移行方法や得られた知見、便利さはもちろん、メリットだけではなく落とし穴についても共有します。\n\n\n    【発表者】\n    mozamimy \n    GitHub https://github.com/mozamimy\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"c9k1OCLhkmQ\"\n\n- id: \"k0i-kaigi-on-rails-2023\"\n  title: \"Async Gem で始める ruby 非同期プログラミング\"\n  raw_title: \"Async Gem で始める ruby 非同期プログラミング / k0i - Kaigi on Rails 2023\"\n  speakers:\n    - k0i\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/k0i/\n\n    【発表概要】\n    ruby 1.9 から追加された Fiber ですが、ruby 3.0 で大きな機能追加がありました。 本セッションではFiberとは一体何であり、何を解決するための機能なのかについて言及します。 その後FiberSchedulerの実装であるAsync Gemを実際に見ていき、同Gemを用いた非同期プログラミングについてデモを行い、 パフォーマンス面やRuby On Railsにおける採用上の課題について言及します。\n\n\n    【発表者】\n    k0i\n    GitHub https://github.com/k0i\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"9jh5X0R_COs\"\n\n- id: \"shinichi-maeshima-kaigi-on-rails-2023\"\n  title: \"Exceptional Rails\"\n  raw_title: \"Exceptional Rails / Shinichi Maeshima - Kaigi on Rails 2023\"\n  speakers:\n    - Shinichi Maeshima\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/willnet/\n\n    【発表概要】\n    堅牢なRailsアプリケーションを書くのは難しいことです。実装時に想定していなかった事象が起きてもそれをうまくハンドリングして不整合がないようにアプリケーションを動かし続けなければなりません。そして、想定していない事象があったときにはそれに素早く気づき、アプリケーションの実装を変更する必要があります。\n\n    想定していなかった事象が起きたときのユーザに対する表示の仕方も大事です。エラーページもアプリケーションを構成するひとつの要素でありユーザ体験に影響します。エラーページを表示するところでエラーが発生して用意しているエラーページが表示できなかった、というのはよくある事ですができるだけ避けたいところです。\n\n    この発表では、Railsにおける「想定していない事象」とどのように付き合っていくと良いのかの指針を示します。また、Railsがエラーページを表示する仕組みと、それを利用した安定したエラーページをどうやって作るのかについても紹介します。\n\n\n    【発表者】\n    Shinichi Maeshima\n    GitHub https://github.com/willnet\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"zcT5GufiQ-0\"\n\n- id: \"kubo-ayumu-kaigi-on-rails-2023\"\n  title: \"やさしいActiveRecordのDB接続のしくみ\"\n  raw_title: \"やさしいActiveRecordのDB接続のしくみ / kubo - Kaigi on Rails 2023\"\n  speakers:\n    - Kubo Ayumu\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/kubo/\n\n    【発表概要】\n    私たちはdatabase.ymlに必要情報を記述し、適当なモデルのfind/whereメソッドを使うだけで、いつの間にかDB接続の確立がなされて、ほしいデータがいつでも簡単に取得できるようになっています。 さて、ActiveRecord内部ではどのような処理を以て、この簡単さを実現しているのでしょうか？普段あまり着目しない部分ですので、ブラックボックス化してる方も少なくないと思います。 そこで、本セッションではMySQLへの接続確立するまでのActiveRecord内部の動きについて紹介します。 具体的には、接続に関する各クラスの役割（active_record/connection_handler等）を適宜紹介しつつ、実際にfindメソッドをデバッグ実行した際のスタックトレースを通して、接続確立までのActiveRecordの内部処理の全容を持ち帰っていただきます。\n\n\n    【発表者】\n    kubo\n    GitHub https://github.com/boro1234\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"VZd21UsrSoU\"\n\n- id: \"ta1kt0me-kaigi-on-rails-2023\"\n  title: \"Update Billion Records\"\n  raw_title: \"Update Billion Records / ta1kt0me - Kaigi on Rails 2023\"\n  speakers:\n    - ta1kt0me\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/ta1kt0me/\n\n    【発表概要】\n    改善の繰り返しはデータモデルに多様な変化をもたらします。サービスの成長にあわせてユーザーアクセスやデータ量が増えていくと、当初は比較的行いやすかたったデータモデルの変更作業の難易度は徐々に上がっていきます。そして気付いた時には気軽に向き合えないほど大きな問題を抱える状況に陥ることもあります。\n\n    私たちが運営するTimeTreeというカレンダーアプリの開発でも、ニーズに合わせてデータモデルへの変更を頻繁に行っています。その一環として実施した数十億レコードを保有するテーブルに対するデータマイグレーションのアプローチを紹介します。\n\n\n    【発表者】\n    ta1kt0me\n    GitHub https://github.com/ta1kt0me\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"GjJZR5rhTOM\"\n\n- id: \"fu-ga-kaigi-on-rails-2023\"\n  title: \"初めてのパフォーマンス改善〜君たちはどう計測す(はか)るか〜\"\n  raw_title: \"初めてのパフォーマンス改善〜君たちはどう計測す(はか)るか〜 / Fu-ga - Kaigi on Rails 2023\"\n  speakers:\n    - Fu-ga\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/fugakkbn/\n\n    【発表概要】\n    エンジニアになって数ヶ月のころ、アプリケーション全体のパフォーマンス改善を任されることになりました。エンジニアとしての経験が浅い私は「パフォーマンス改善といってもどこをどうやって改善していけばいいのだろうか」と途方に暮れました。 そんな私が半年以上を掛けてパフォーマンス問題の把握の仕方、ボトルネックの特定方法、クエリ改善を続けてきた結果わかるようになったこと、できるようになったことを実例を交えてお話しします。 「明日からクエリ改善やって！」と急に言われても臆することなく対応できるような話をしたいと思います。\n\n\n    【発表者】\n    Fu-ga\n    GitHub https://github.com/fugakkbn\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"VMQewASPTrI\"\n\n- id: \"morohashi-kyosuke-kaigi-on-rails-2023\"\n  title: \"Simplicity on Rails - RDB, REST and Ruby\"\n  raw_title: \"Simplicity on Rails - RDB, REST and Ruby / MOROHASHI Kyosuke - Kaigi on Rails 2023\"\n  speakers:\n    - Kyosuke MOROHASHI\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/moro/\n\n    【発表概要】\n    実世界のRailsアプリケーションをシンプルに保つための方法を、Railsが提供する機能群をもとに考察します。\n\n    実世界の、特に仕事で開発するRailsアプリへの要求は様々のものがあり、Railsの豊富な機能群をもっても日々苦労して開発しているかと思います。 そんな中でも、Railsが得意とするような設計に落とし込むことで、複雑な要求をシンプルな実装で実現できると感じています。\n\n    本講演では、Railsが提供する機能のうち、「REST」「RDB」「Ruby」という要素を軸に、実世界の要求をシンプルに実装するための考え方を紹介します。\n\n\n    【発表者】\n    MOROHASHI Kyosuke\n    GitHub https://github.com/moro\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"3qcsNg52aEI\"\n\n- id: \"alpaca-tc-kaigi-on-rails-2023\"\n  title: \"TracePointを活用してモデル名変更の負債解消をした話\"\n  raw_title: \"TracePointを活用してモデル名変更の負債解消をした話  / alpaca-tc - Kaigi on Rails 2023\"\n  speakers:\n    - alpaca-tc\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/alpaca-tc/\n\n    【発表概要】\n    誰もが開発時に直面する「技術的負債」。 あなたもRailsの世界でこの大敵との戦いで手をこまねいていませんか？ 特にRubyのような動的言語では、一見シンプルな置換作業でも予期しない障壁が待ち受けています。\n\n    私たちのチームは、命名規則の誤りから生じたモデル名の技術的負債と向き合い、60,000行以上の変更を成功させました。 その成功のカギとなったのは「TracePoint」。 さまざまなイベント(メソッド呼び出しなど)をトレースすることができるRubyの強力な標準ライブラリでした。\n\n    このセッションでは、TracePointの基本的な使い方や、さらには技術的負債の解消のノウハウを実例とともに紹介します。 この機会に、巨大な技術的負債との戦いに悩むあなたの手札にTracePointという武器を加えてみませんか。\n\n\n\n    【発表者】\n    alpaca-tc\n    GitHub https://github.com/alpaca-tc\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"bi56PRhG7tk\"\n\n- id: \"ginkouno-kaigi-on-rails-2023\"\n  title: \"技術的負債の借り換え on Ruby and Rails update\"\n  raw_title: \"技術的負債の借り換え on Ruby and Rails update / ginkouno - Kaigi on Rails 2023\"\n  speakers:\n    - ginkouno\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/ginkouno/\n\n    【発表概要】\n    RubyやRailsのupdateにおけるノウハウは、信頼のおける記事がいくつか流通しており、日々助けられております。 その中の手順として「まず、gemを最新にする」と記載されていますが、そのgem updateに関する記事の分量はあまり多くありません。 それは各gemによって事情が異なったり、また日々gemのupdateを欠かさない体制である状況においては難易度が低かったりなど、様々な事情があると思われます。 では、普段gemのupdateが何らかの理由でできず、RubyやRailsのEOLに追い立てられ、慌ててgemのupdateを一気にしようとした場合、何が起こるのか。 その時に私が仲間とともに行った判断や対処の例を共有し、皆様の意見をお伺いしたいと思います。\n\n\n    【発表者】\n    ginkouno\n    GitHub https://github.com/ginkouno\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"DWW5JimA84U\"\n\n- id: \"lnit-kaigi-on-rails-2023\"\n  title: \"Turbolinksアレルギー患者に捧げるTurbo & Stimulusでの時短実装術 by lni_T\"\n  raw_title: \"Turbolinksアレルギー患者に捧げるTurbo & Stimulusでの時短実装術  / lni_T / ルニ - Kaigi on Rails 2023\"\n  speakers:\n    - lnit\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/lni_T/\n\n    【発表概要】\n    皆様、Railsのフロントエンドツール「Hotwire」は使っていますか？ Rails 7からはデフォルトで採用されており、「Turbo」や「Stimulus」といったライブラリが利用できます。\n\n    ですが、利用者があまり多くなかった「Turbolinks」のイメージに影響されて、利用を避けている方は居ませんか？\n\n    このトークでは、実際のバックエンドリプレイス案件において、 Turbo & Stimulusを採用することで開発工数を大幅に削減できた事例、および実装方法についてご紹介します。\n\n\n    【発表者】\n    lni_T / ルニ\n    GitHub https://github.com/lnit\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"8Rdxv7kk7-Y\"\n\n- id: \"gogutan-kaigi-on-rails-2023\"\n  title: \"seeds.rbを書かずに開発環境データを整備する\"\n  raw_title: \"seeds.rbを書かずに開発環境データを整備する / gogutan - Kaigi on Rails 2023\"\n  speakers:\n    - gogutan\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/gogutan/\n\n    【発表概要】\n    開発環境の初期データは、チーム全体の開発効率に関わる重要なデータです。しかし、seedファイルの記述に手間がかかるためメンテナンスが適切に行われなかったり、各エンジニアがローカルに独自のデータを持っているようなことはないでしょうか。 弊社ではこの問題を解決するため「ローカルのデータからCSVを出力してseedとして利用する」手法を導入しました。これはseedファイルを直接編集するのではなく、実際にローカルでアプリを操作して必要なデータを整備した後、スクリプトを実行して全テーブルのCSVを出力する手法で、「今この瞬間のローカルデータを、スナップショットのようにseed化したい！」という怠惰な願望を叶えるものです。 今回のトークでは、この手法の概要、導入にあたって直面した問題と解決アプローチ、及び導入前後のseedデータにおける質や量の比較についてお話しします。\n\n\n    【発表者】\n    gogutan\n    GitHub https://github.com/gogutan\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"GG6d2-BPQ5w\"\n\n- id: \"haruka-oguchi-kaigi-on-rails-2023\"\n  title: \"定数参照のトラップとそれを回避するために行う2つのこと\"\n  raw_title: \"定数参照のトラップとそれを回避するために行う2つのこと / Haruka Oguchi - Kaigi on Rails 2023\"\n  speakers:\n    - Haruka Oguchi\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/hogucc/\n\n    【発表概要】\n    Rubyの定数を参照する際、それが本当に意図した定数を参照しているかはコードを動かしてみるまではわかりません。\n\n    先頭に::をつけてすべての定数参照をトップレベルから強制するのがよいでしょうか？ 私はコードの書き方の強制よりも、コードを書いた時点でそれがどの定数を参照していて、トップレベルから検索したときに一致する定数の候補を出す機能が欲しくなり、エディタ上でそれらを表示してくれるgemを作ってみることにしました。 書き方の強制は影響範囲が広く、意図した定数参照をしていないことに気づくのが遅れた、という課題を解決するにはこの方法で十分と考えたからです。\n\n    この発表では、Railsのアプリケーションで定数が読み込まれる仕組みや定数探索の順番をお話しした上で、実装し(た|ている)gemの紹介をしたいと思います。\n\n\n    【発表者】\n    Haruka Oguchi\n    GitHub https://github.com/hogucc\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"DprMyMethws\"\n\n- id: \"masataka-kuwabara-kaigi-on-rails-2023\"\n  title: \"Active Record クエリクイズ\"\n  raw_title: \"Active Record クエリクイズ / Masataka Pocke Kuwabara - Kaigi on Rails 2023\"\n  speakers:\n    - Masataka Kuwabara\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/pocke/\n\n    【発表概要】\n    Active Record は便利なライブラリです。一方で、時としてどのようなクエリが発行されるのか分からなくなることもあるでしょう。 そんなちょっとむずかしい、Active Record が発行するクエリをクイズ形式で学びます。\n\n    このトークを聞いて、コードを見たらなんとなく発行されるクエリが見えるようになる力を手に入れましょう！\n\n\n    【発表者】\n    Masataka Pocke Kuwabara\n    GitHub https://github.com/pocke\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"f4yuWOXlGCo\"\n\n- id: \"andrey-novikov-kaigi-on-rails-2023\"\n  title: \"Rails Executor: フレームワークとあなたのコードとの境\"\n  raw_title: \"Rails Executor: フレームワークとあなたのコードとの境 / Andrey NOVIKOV - Kaigi on Rails 2023\"\n  speakers:\n    - Andrey Novikov\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-27\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/Envek/\n\n    【発表概要】\n    Railsがリクエストとバックグラウンドジョブの間にキャッシュとリソースをどのようにクリーンアップするか？ そして、リロード対象のコードをどうやって決定するかをご存知でしょうか?\n\n    これはあまり知られていないRailsの内部詳細です。通常のアプリケーション開発者であれば、決して気づくことはなくて、知る必要もありません。しかし、アプリケーションのコードをコールバックなどで呼び出すジェムを作成する場合、その知識は不可欠なことになります。\n\n\n    【発表者】\n    Andrey Novikov\n    GitHub https://github.com/Envek\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"ihlJu3wPJ5Q\"\n\n- id: \"yuki-kurihara-kaigi-on-rails-2023\"\n  title: \"Railsの型ファイル自動生成における課題と解決\"\n  raw_title: \"Railsの型ファイル自動生成における課題と解決 / Yuki Kurihara - Kaigi on Rails 2023\"\n  speakers:\n    - Yuki Kurihara\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/ksss/\n\n    【発表概要】\n    「Railsアプリケーションで型をあつかいたい。」これはコミュニティーにおいて未だベストプラクティスが見つかっていない、模索中の課題です。\n\n    ある程度の主要な情報は生成方法が見つかっているでしょう。\n\n    しかしながらコーナーケースはどうでしょうか？ Railsのプラグインgemを使っている場合は？ 個々のプロダクトの事情に合わせたカスタマイズ方法は？ 既存の資産を活かす方法は？\n\n    本セッションでは、これらの問題を解決する方法として、orthoses-railsを提案します。 orthoses-railsを使うことで、最初の導入、アプリケーションコードの解析、実行時解析とは何か、カスタマイズ方法や、独自のRailsプラグイン拡張であっても型を自動生成する方法など、実践的な課題に対する解決方法を提案します。\n\n\n    【発表者】\n    Yuki Kurihara\n    GitHub https://github.com/ksss\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"zbVmxcqQBck\"\n\n- id: \"zuckey-kaigi-on-rails-2023\"\n  title: \"事業の試行錯誤を支える、コードを捨てやすくしてシステムをシンプルに保つ設計と工夫\"\n  raw_title: \"事業の試行錯誤を支える、コードを捨てやすくしてシステムをシンプルに保つ設計と工夫  / zuckey - Kaigi on Rails 2023\"\n  speakers:\n    - zuckey\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/zuckey/\n\n    【発表概要】\n    サービスを運用していく過程で、事業の状況や取り巻く社会環境に応じて提供する機能や課金体系などを変える（ピボットする）必要に迫られることが多いです。 特にBtoBのサービスでは、少ない顧客企業と長期的な取り組みになることが多く、1社ごとの取引金額の大きくなりがちです。 それゆえに、特殊なケースに対応するためにシステムを作り込むという選択を選ばざるを得ないケースもあります。 過度な作り込みによって、システムの柔軟性は損なわれ、事業はピボットしづらくなります。 本トークでは、書いたコードを捨てやすくしてシステムをシンプルに保つための設計と、捨てる意思決定を後押しするための工夫についてお話します。 システムをシンプルにすることにより、作り込みをしつつも試行錯誤のスピード感を維持します。そういった動きをするためのRailsアプリケーションの設計を具体例を交えて紹介します。 また、開発者がコードや機能を削除したいと主張しても、工数をかけて作ったものを削除する意思決定をするのは難しいものです。 コード、機能の削除を進めるためにプロダクトのステークホルダーをうまく巻き込んだ議論をするためのTipsを紹介します。 本トークを通じて、急激に変化する社会の中でも柔軟に対応するプロダクトを作るために、Webアプリケーション開発者が普段から準備できることについて知ることができます。\n\n\n    【発表者】\n    zuckey\n    GitHub https://github.com/zuckeyM-17\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"0DndjNCJHUI\"\n\n- id: \"shogo-terai-kaigi-on-rails-2023\"\n  title: \"Fat Modelを解消するためのCQRSアーキテクチャ\"\n  raw_title: \"Fat Modelを解消するためのCQRSアーキテクチャ / Shogo Terai - Kaigi on Rails 2023\"\n  speakers:\n    - Shogo Terai\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/krpk1900/\n\n    【発表概要】\n    私が現在開発している比較的規模が大きなRailsアプリケーションでは、CQRS(Command and Query Responsibility Segregation)アーキテクチャを取り入れることによって、Fat ModelやFat Controller問題を解決し、ソースコードの見通しが良い状態を保つことができています。\n\n    本セッションでは、RailsアプリケーションでCQRSアーキテクチャを採用している事例として、私たちが導入しているUseCase・Query・Commandの役割と、Model・Controllerを含めた各層の関係を紹介します。\n\n\n    【発表者】\n    Shogo Terai\n    GitHub https://github.com/krpk1900\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"H_45FlMS6Kc\"\n\n- id: \"hiro-tateyama-kaigi-on-rails-2023\"\n  title: \"返金処理を通して学ぶ、カード決済電文の沼バトル\"\n  raw_title: \"返金処理を通して学ぶ、カード決済電文の沼バトル / hirotea - Kaigi on Rails 2023\"\n  speakers:\n    - Hiro Tateyama\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/hirotea/\n\n    【発表概要】\n    ECサイトでクレジットカード決済を行い、注文をキャンセルした経験はありますか？しばらくすると返金処理が行われ、カード会社からの請求がキャンセルされます。しかし、カード会社がどのようにして返金処理を行っているのか、気になったことはありませんか？\n\n    カード会社は、決済時と返金手続き時にお店から発行される電文をもとに決済・返金処理を行いますが、実はかなり混沌とした世界であったりします。\n\n    登壇者は、プリペイドカード発行会社で新規機能開発時にこの返金処理の沼にハマり、そのケアに苦労しました。 このセッションでは、決済電文をプリペイドカード発行会社（イシュアー）がどのように処理し、ユーザーの残高を変動させているのかに触れた後、登壇者が苦労した返金処理に関するケアについてカジュアルにお話しします。普段カード事業に携わることがなければ知ることができない、そして気にも留めないお話をみなさまに提供する予定です。\n\n\n    【発表者】\n    hirotea\n    GitHub https://github.com/hiro-teaaa\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"UwI41FIGP6E\"\n\n- id: \"yusuke-iwaki-kaigi-on-rails-2023\"\n  title: \"E2E testing on Rails 2023\"\n  raw_title: \"E2E testing on Rails 2023 / Yusuke Iwaki - Kaigi on Rails 2023\"\n  speakers:\n    - Yusuke Iwaki\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/YusukeIwaki/\n\n    【発表概要】\n    Rails 5.2でシステムテストが導入されて以来、Capybaraを使用したE2Eテストを書くことはとても容易になりましたが、実際にシステムテストをCIで運用すると「時々なぜか落ちるテスト」との戦いです。いっぽう世の中を見渡すと、CypressやPlaywrightといったNode.jsベースのテストランナーが成熟してきており、Flakyなテストに打ち克つための工夫が多くされています。この発表ではRailsのアプリケーション資産はそのままに、Node.jsベースのテストランナーを導入する方法を紹介し、その中の仕組みを詳しく説明します。\n\n\n    【発表者】\n    Yusuke Iwaki\n    GitHub https://github.com/YusukeIwaki\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"Ntimew78syU\"\n\n- id: \"shohei-mitani-kaigi-on-rails-2023\"\n  title: \"32個のPRでリリースした依存度の高いコアなモデルの安全な弄り方\"\n  raw_title: \"32個のPRでリリースした依存度の高いコアなモデルの安全な弄り方 / Shohei Mitani - Kaigi on Rails 2023\"\n  speakers:\n    - Shohei Mitani\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/ShoheiMitani/\n\n    【発表概要】\n    新しく機能を設計する際、将来的な仕様変更の可能性を踏まえて拡張性を持たせたり、簡単に変更ができるように工夫することは、経験を積んできたエンジニアにとって常に意識しているポイントかと思います。 しかし、時として思わぬ方向に機能のニーズが変化したり、予想外の事業領域へのチャレンジによって当初には意図してない形に設計を大きく変更せざるを得ないケースも生じます。\n\n     ・このテーブルを変更しないといけないけど参照箇所が多くて触りにくい...\n     ・新しくカラムを追加したいけどデータ量が多いからオンラインして良いのか不安...??\n     ・この仕様ってこれから先どう変わっていくんだろ... 拡張性とか考えなくてもいいかな...??\n\n    サービスが大きくなるほど既に動いている機能を障害なく変更していくことは難しくなりますし、変化の多い事業環境でどこまで拡張性や柔軟性を持たせるかの見極めは困難です。\n\n    このセッションでは、実際の事例に基づいてサービスのコアとなるモデルの仕様を大きく変え、テーブルの定義変更やモデルの機能拡張をしたお話をします。多くのモデルに依存していたり、Read/Writeが多いモデルをダウンタイムなしで変更していくための手順の決め方や具体的なテクニック、便利なgemなどについて紹介します。また、私たちのチームが将来像を考慮しながら設計する時に意識しているポイントについても紹介します。\n\n\n    【発表者】\n    Shohei Mitani\n    GitHub https://github.com/ShoheiMitani\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"M-E69IrKfps\"\n\n- id: \"naoto-yamaji-kaigi-on-rails-2023\"\n  title: \"テーブル分割で実現するdeviseの責務の分離と柔軟な削除機構\"\n  raw_title: \"テーブル分割で実現するdeviseの責務の分離と柔軟な削除機構 / Naoto - Kaigi on Rails 2023\"\n  speakers:\n    - Naoto Yamaji\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/naoto/\n\n    【発表概要】\n    deviseを使用してデフォルトの設定で認証機構を構築すると、ユーザーに関する多種多様な情報が一つのテーブルに集約されます。 これはモデルクラスの責務の増加につながり、拡張性の担保の難しさを招き、ひいてはセキュリティ面に多少の問題が発生することになると考えました。\n\n    この問題に対して、責務ごとにテーブルの分割を行うことで改善を試みる方法を提案します。 また関連して、「ユーザーの削除と関連情報の保持」というよく発生する課題について、テーブル分割でどのように対応していくかについても説明します。\n\n\n    【発表者】\n    Naoto\n    GitHub https://github.com/NaotoCoding\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"I29wMW2IepQ\"\n\n- id: \"imadoki-kaigi-on-rails-2023\"\n  title: \"Multiple Databasesを用いて2つのRailsプロジェクトを統合する\"\n  raw_title: \"Multiple Databasesを用いて2つのRailsプロジェクトを統合する / imadoki - Kaigi on Rails 2023\"\n  speakers:\n    - imadoki\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/imadoki/\n\n    【発表概要】\n    マンガサービスpixivコミックに姉妹サイトであるpixivノベルの機能の統合を進めている話をします。\n\n    pixivノベルは元々pixivコミックをクローンして作成されたという経緯もあり、この2つのサービスは非常によく似ています。また、一貫して同じチームが開発し、マンガ・小説それぞれの作品種別の違いを意識しつつ、同じ目的を持った機能を双方に実装してきました。 今後は読者がマンガ・小説に拘らず両方の作品を楽しめるよう、両サービスの良さを生かしながら、より多くのユーザーにコンテンツを提供し、作品を広めるため、この2つのサービスを統合していく予定です。\n\n    統合はpixivコミック側にpixivノベルの機能を移植していく形で実装されており、pixivコミックのAPIサーバーからRailsのMultiple Databases機能を用いてpixivノベルが使用するDBを直接参照することで実現する方針です。2つのRailsサービスを稼働しながら1つのRailsサービスに統合していくための開発の進め方や気にしたポイントについて話したいと思っています。\n\n\n    【発表者】\n    imadoki\n    GitHub https://github.com/imadoki\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"-tnFsqssKpg\"\n\n- id: \"yasuko-ohba-kaigi-on-rails-2023\"\n  title: \"Hotwire的な設計を追求して「Web紙芝居」に行き着いた話\"\n  raw_title: \"Hotwire的な設計を追求して「Web紙芝居」に行き着いた話 / Yasuko Ohba (nay3) - Kaigi on Rails 2023\"\n  speakers:\n    - Yasuko Ohba\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/nay3/\n\n    【発表概要】\n    私は昨年3月以降、Rails7でHotwireを活用して複数のアプリケーションを開発してきました。Hotwireは、SPAのような動きをRailsだけで実現できる良い道具だと思っています。開発体制やコードをコンパクトに保てる利点があります。\n\n    ただ、SPAではなくHotwireでやろうと決めるためには、Hotwireでどこまでできるのか？ Hotwireでできないことはあるのか？ が気になってくる点でしょう。この点について、今では私は以下のように感じています。\n\n    ・やりたいことは大体なんでも Hotwire で実現できる\n    ・最終的に実現できる機能の差よりも、どういう考え方で作るかにSPAとHotwireの大きな違いがある\n\n    SPAとHotwireでは、アプリを構成するための物の考え方が大きく異なります。Hotwireを縦横無尽に使い倒すためには、Hotwire的な考え方で作る必要があるのです。この、Hotwire的な考え方＝設計指針に私は「Web紙芝居」という名前をつけました。本トークでは、この「Web紙芝居」的な設計指針に行き着いた経緯や、指針の内容についてご紹介します。\n\n\n    【発表者】\n    Yasuko Ohba (nay3)\n    GitHub https://github.com/nay\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"xfjBsbT1L_M\"\n\n- id: \"masato-ohba-kaigi-on-rails-2023\"\n  title: \"管理機能アーキテクチャパターンの考察と実践\"\n  raw_title: \"管理機能アーキテクチャパターンの考察と実践 / ohbarye - Kaigi on Rails 2023\"\n  speakers:\n    - Masato Ohba\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/ohbarye/\n\n    【発表概要】\n    Webサービスの開発・運用に携わる者なら、管理機能の重要性について深く認識していることでしょう。ユーザーアカウント管理、システム設定、トラブルシューティング、レポート機能など、管理機能はサービスを安全かつ効率的に運用するための不可欠なツールです。\n\n    しかし、新規事業やスタートアップではユーザーに迅速に価値を提供し、ビジネスを軌道に乗せることが最優先されます。その結果、管理機能の開発は後回しになり、対ユーザー向けの機能を先にリリースして運用を始めてから管理機能を追加する、という開発ロードマップが多く見られます。このようなケースはままあるものの、管理機能追加の際に選ばれるアーキテクチャパターンについては十分に語られていないと感じています。\n\n    このセッションでは、単なるgem選定を超えて、管理画面や管理機能を後から追加する際のアーキテクチャパターンを深堀りします。それぞれの選択肢のメリットとデメリットを比較し、選択の視点を提供します。また、私が運用しているRailsアプリケーションでの管理機能設計の選択とその理由に加え、運用から得られた知見―特に監視やプロセス管理などのトピック―にも焦点を当てます。このセッションを通じて、管理機能設計と運用に対する理解と視野が広がれば幸いです。\n\n\n    【発表者】\n    ohbarye\n    GitHub https://github.com/ohbarye\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"bmKUvx1g_1A\"\n\n- id: \"shunsuke-kokuyou-mori-kaigi-on-rails-2023\"\n  title: \"APMをちゃんと使おうとしたら、いつのまにか独自gemを作っていた話\"\n  raw_title: \"APMをちゃんと使おうとしたら、いつのまにか独自gemを作っていた話 / kokuyouwind - Kaigi on Rails 2023\"\n  speakers:\n    - Shunsuke \"Kokuyou\" Mori\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/kokuyouwind/\n\n    【発表概要】\n    Active Recordは必要な処理が簡単に書ける一方で、N+1クエリやスロークエリなどパフォーマンスの問題が発生しやすい一面も持っています。 特にデータ量に依存する問題では、本番環境でしか再現しない問題も珍しくありません。APMツールを使うことで、こうしたパフォーマンスの追跡や原因の調査を行いやすくなります。 しかし、APMツールの導入自体は比較的簡単なものの、うまく活用するのは意外と難しいものです。「APMを導入しただけで放置してしまっている」という方も多いのではないでしょうか？\n\n    弊社ではAPMとしてDatadogを導入し、定期的な状況の確認とパフォーマンスチューニングに役立てています。 本セッションでは弊社でAPMをどのように使っているかを紹介し、より使いやすくするために独自のgemを作った話をします。\n\n\n    【発表者】\n    kokuyouwind\n    GitHub https://github.com/kokuyouwind\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"hlnorJ64UPY\"\n\n- id: \"takuya-mukohira-kaigi-on-rails-2023\"\n  title: \"自分の道具を自作してつくる喜びを体感しよう、Railsで。 〜4年続いたPodcastを実例に〜 by Takuya Mukohira\"\n  raw_title: \"自分の道具を自作してつくる喜びを体感しよう、Railsで。 〜4年続いたPodcastを実例に〜 / Takuya Mukohira / mktakuya - Kaigi on Rails 2023\"\n  speakers:\n    - Takuya Mukohira\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/mktakuya/\n\n    【発表概要】\n    学生時代からの友人たちとPodcast配信をはじめて4年。様々なゲストをお迎えしたり、3年連続の毎週更新を達成したりしながら、先日は第200回の節目を迎えることが出来ました。\n\n    数年に一度流行し、始める人が増えては意外と継続が大変で更新が途絶えてしまいがちなPodcast。続けることが出来た理由のひとつに、Webサイトや配信システム・CMSなど「自分の道具を自分でつくり改善し続けていたこと」があると思っています。\n\n    このトークでは、「業務外でもコードを書きたいけどつくりたいものがない」という状態だった私が、サイドプロジェクトで使う道具を自分でつくり改善することを通じて、楽しみながら技術的な成長とつくる喜びを得られたという経験談をします。\n\n    使える時間が限られている趣味やサイドプロジェクトとかけ合わせてのものづくりにこそ、Ruby on Railsとそのエコシステムがもたらす高い生産性がピッタリです。\n\n    トークを聞いたみなさんが、「自分もRailsでなにか作ってみよう！」と思い、つくる喜びを体感する一歩を踏み出していただければ幸いです。\n\n\n    【発表者】\n    Takuya Mukohira / mktakuya\n    GitHub https://github.com/mktakuya\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"diOkwNl1WrU\"\n\n- id: \"miyuki-tomiyama-kaigi-on-rails-2023\"\n  title: \"ペアプロしようぜ 〜3人で登壇!? 楽しくて速いペアプロ/モブプロ開発〜\"\n  raw_title: \"ペアプロしようぜ 〜3人で登壇!? 楽しくて速いペアプロ/モブプロ開発〜 / eatplaynap トミー & masuyama13 & あんすと - Kaigi on Rails 2023\"\n  speakers:\n    - Miyuki Tomiyama\n    - H Masuyama\n    - Makoto Onoue\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/tebiki/\n\n    【発表概要】\n    私たちが伝えたいのは、開発の速度を劇的に向上させ、開発に伴うストレスを激減させ、開発を楽しいものにする方法です。私たちのチームでは、昨年8月にペア/モブプロを本格的に導入し、ほぼ全ての開発をペア/モブプロで行うことで、平均リードタイムを24時間以内に保ち、継続的に速いリリースが行えるようになりました。ペア/モブプロの導入によって、どのような点がどれくらい向上したかを具体的なデータでお伝えするとともに、私たちが普段どのようにモブプロを行っているかを、実際のライブコーディングの様子からお伝えしたいと思います。\n\n\n    【発表者】\n    eatplaynap トミー\n    GitHub https://github.com/eatplaynap\n\n    masuyama13\n    GitHub https://github.com/masuyama13\n\n    あんすと\n    GitHub https://github.com/unstoppa61e\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"jlNSdXycpz8\"\n\n- id: \"knr-kaigi-on-rails-2023\"\n  title: \"数十億のレコードを持つ5年目サービスの設計と障害解決\"\n  raw_title: \"数十億のレコードを持つ5年目サービスの設計と障害解決 / KNR - Kaigi on Rails 2023\"\n  speakers:\n    - KNR\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/knr/\n\n    【発表概要】\n    アプリケーション運用において、時間が経つにつれて各種データも蓄積されていきパフォーマンスが劣化していくことがあります。\n\n    Palcyは今年で5周年を迎えたスマホアプリでそのバックエンドに蓄積されたデータもテーブルによっては数十億オーダーに乗っており安易な機能実装がはばかられます。この発表ではそうしたデータとどう向き合い、運用や機能の実装を続けてきたか発表します。\n\n\n    【発表者】\n    KNR\n    GitHub https://github.com/knr07\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"ygZFq3UxWdg\"\n\n- id: \"tora-kouno-kaigi-on-rails-2023\"\n  title: \"Railsアプリにパスワードレス認証を導入した知見\"\n  raw_title: \"Railsアプリにパスワードレス認証を導入した知見  / 河野裕隆 - Kaigi on Rails 2023\"\n  speakers:\n    - Tora Kouno\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/tora-kouno/\n\n    【発表概要】\n    ## 話すこと\n\n    Railsで作られたアプリにPasskey（パスワードレス認証）を導入した際の実装方法、注意点を共有します。\n\n    セキュリティ対策はアプリケーション開発を行う上で非常に重要な観点となっています。 特にログイン機構はあらゆるアプリケーションに実装され、UXを高めるとともにセキュアなサイトを作る上で非常に大切な要素です。 弊社が開発/運用している「クリエイティア」でPasskeyによるログインを導入したため、その際に得た知見をお話します。\n\n    ## 想定する対象者\n\n    ・Passkeyについて知りたい方\n    ・RailsアプリでPasskeyを導入したい方\n    ・ログインのUXを改善したい方\n\n    ## このセッションでわかるようになること（目次）\n\n    ・Passkeyとはなにか\n    ・Passkeyのメリット\n    ・Passkeyの導入経緯\n    ・実装方法\n    ・実装上の注意点（ハマりポイント）\n\n    ## Passkeyとは\n\n    端末に保存された指紋や顔、あるいはPINコードを利用して認証するものです。 ユーザーのメリットとして、サイトごとにパスワード（パスフレーズ）を管理する必要がなく、 安全性と利便性を両立できる認証方式です。\n\n    ## クリエイティアとは\n\n    クリエイターとファンを結ぶ月額会員制ファンクラブプラットフォームです。\n\n\n    【発表者】\n    河野裕隆\n    GitHub https://github.com/tora-kouno\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"Yj8NV2S0ydQ\"\n\n- id: \"sampo-kuokkanen-kaigi-on-rails-2023\"\n  title: \"ActiveSupport::CurrentAttributes: すっごく便利なのに嫌われ者？！\"\n  raw_title: \"ActiveSupport::CurrentAttributes: すっごく便利なのに嫌われ者？！ / Sampo Kuokkanen - Kaigi on Rails 2023\"\n  speakers:\n    - Sampo Kuokkanen\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/sampokuokkanen/\n\n    【発表概要】\n    ActiveSupport::CurrentAttributesを嫌う人がいますが、ものすごく便利、というのは言わざるを得ないです。 みんな大好きなグローバル変数を安全にリクエストの中で使える！本当に便利な優れものです。\n\n    なんで嫌われているのかについて話して、注意点など、これまでにあったセキュリティ欠陥（Pumaとrailsの組み合わせで、情報が漏洩されていたものがありまして。。。）の話などをして、みんなでActiveSupport::CurrentAttributesを使おう！とまではいかなくても、本当に使わないといけない時があれば一つの選択肢としてありますよ、ということを伝えたいです。\n\n\n    【発表者】\n    Sampo Kuokkanen\n    GitHub https://github.com/sampokuokkanen\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"9jYnRm1SjgU\"\n\n- id: \"duck-falcon-kaigi-on-rails-2023\"\n  title: \"コードカバレッジ計測ツールを導入したらテストを書くのが楽しくなった話\"\n  raw_title: \"コードカバレッジ計測ツールを導入したらテストを書くのが楽しくなった話 / duck-falcon - Kaigi on Rails 2023\"\n  speakers:\n    - duck-falcon\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/duck/\n\n    【発表概要】\n    レガシーなコードに対してテストを書くというのは挑戦であり、しばしば時間とリソース(それと精神力)を多く必要とします。 どうすればチーム全体で楽しく、効率的にこの問題に取り組むことができるのでしょうか？\n\n    本セッションでは、まずコードカバレッジの基本的な概念を説明します。 C0, C1, C2カバレッジの違いや、なぜ100％のカバレッジを追求するべきでないのか、その理由について簡単に説明します。\n\n    そして、コードカバレッジツール： SimpleCovの導入を通して、 実際のプロジェクトでテストを書く負荷を最小限にし、 チームメンバーがテストコーディングを楽しむことができる環境を整えた方法を紹介します。 また、新規開発の品質向上にもいい影響を与えた話も合わせて行います。\n\n\n    【発表者】\n    duck-falcon\n    GitHub https://github.com/duck-falcon\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"54sOl5qQMK0\"\n\n- id: \"takaharu-yamamoto-kaigi-on-rails-2023\"\n  title: \"Hotwireを使って管理画面を簡単にプチSPA化する\"\n  raw_title: \"Hotwireを使って管理画面を簡単にプチSPA化する / yamataka22 - Kaigi on Rails 2023\"\n  speakers:\n    - Takaharu Yamamoto\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"japanese\"\n  description: |-\n    https://kaigionrails.org/2023/talks/yamataka/\n\n    【発表概要】\n    Rails7が公開されてから1年半近くが経ち、Hotwireの導入によって、フロント周りはそれまでのRails開発と大きく変わりました。しかしながら、まだHotwireの実績や情報量が少ないなどの理由で、積極的に使うことを見送る場合も多いのではないでしょうか。このままでは、Rails4のTurbolinksの扱いと同じように「まず無効化する」がデフォルトになりえないかと懸念しています。\n\n    私自身、当初はHotwireの勘所がわからず、作りづらさを感じてだいぶ辛かったのですが、慣れてきた昨今では、Rails6以前よりも使い勝手の良いシステムを素早く導入することができていると実感しています。\n\n    そこで今回は、Hotwireを使って管理画面や社内向けシステムを簡単にプチSPA化する実践的な手法を紹介いたします。なお、ここで言う「プチSPA化」とは、具体的には、CRUDにおける #new, #edit, #show をモーダル表示することを指します。\n\n    Hotwire入門というよりも、StimulusとTurboを組み合わせてHTML片に動きをつける具体的方法を共有することで、皆様のHotwire開発ライフを少しでも後押しできたら幸いです。\n\n\n    【発表者】\n    yamataka22\n    GitHub https://github.com/yamataka22\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"HXoH93yMwPM\"\n\n- id: \"jean-boussier-kaigi-on-rails-2023\"\n  title: \"A Decade of Rails Bug Fixes\"\n  raw_title: \"A Decade of Rails Bug Fixes / byroot - Kaigi on Rails 2023\"\n  speakers:\n    - Jean Boussier\n  event_name: \"Kaigi on Rails 2023\"\n  date: \"2023-10-28\"\n  published_at: \"2023-11-03\"\n  language: \"english\"\n  description: |-\n    https://kaigionrails.org/2023/talks/byroot/\n\n    【発表概要】\n    In this talk we'll go over two Rails bugs I fixed 10 years appart. For both I will detail how the bug was found, how I debugged it and how I finally fixed it. I will as well reflect back on what I learned in the process. If you are a begginer you may learn some debugging techniques, if you are more confirmed you may enjoy the war stories and learn some gritty details about Ruby and Rails internals.\n\n\n    【発表者】\n    byroot\n    GitHub https://github.com/byroot\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  video_provider: \"youtube\"\n  video_id: \"foODcPk_JW8\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2024/cfp.yml",
    "content": "---\n- link: \"https://cfp.kaigionrails.org/events/2024\"\n  open_date: \"2024-07-01\"\n  close_date: \"2024-07-31\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2024/event.yml",
    "content": "---\nid: \"PLiBdJz0juoHC9hBr_Cce38yX4ANimvLOK\"\ntitle: \"Kaigi on Rails 2024\"\nkind: \"conference\"\nlocation: \"Koto City, Tokyo, Japan\"\nhybrid: true\ndescription: |-\n  Kaigi on Rails is a yearly conference in Tokyo, focusing on Rails and Web development.\npublished_at: \"2024-12-10\"\nstart_date: \"2024-10-25\"\nend_date: \"2024-10-26\"\nchannel_id: \"UCKD7032GuzUjDWEoZsfnwoA\"\nyear: 2024\nbanner_background: \"#D7D2D0\"\nfeatured_background: \"#D7D2D0\"\nfeatured_color: \"#000505\"\nwebsite: \"https://kaigionrails.org/2024\"\ncoordinates:\n  latitude: 35.6320541\n  longitude: 139.7936661\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2024/schedule.yml",
    "content": "# Schedule: https://kaigionrails.org/2024/schedule\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-10-25\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - 開場、受付\n\n      - start_time: \"11:00\"\n        end_time: \"11:05\"\n        slots: 1\n        items:\n          - オープニング\n\n      - start_time: \"11:05\"\n        end_time: \"11:10\"\n        slots: 1\n        items:\n          - スポンサーLT1\n\n      - start_time: \"11:10\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - スポンサーLT2\n\n      - start_time: \"11:15\"\n        end_time: \"11:20\"\n        slots: 1\n        items:\n          - スポンサーLT3\n\n      - start_time: \"11:20\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - お昼休憩 (お弁当提供有)\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 2\n\n      - start_time: \"14:00\"\n        end_time: \"14:10\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"14:10\"\n        end_time: \"14:25\"\n        slots: 2\n\n      - start_time: \"14:25\"\n        end_time: \"14:35\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"14:35\"\n        end_time: \"15:05\"\n        slots: 2\n\n      - start_time: \"15:05\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"15:45\"\n        end_time: \"16:00\"\n        slots: 2\n\n      - start_time: \"16:00\"\n        end_time: \"16:10\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"16:10\"\n        end_time: \"16:40\"\n        slots: 2\n\n      - start_time: \"16:40\"\n        end_time: \"16:50\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"16:50\"\n        end_time: \"17:05\"\n        slots: 2\n\n      - start_time: \"17:05\"\n        end_time: \"17:15\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"17:15\"\n        end_time: \"17:45\"\n        slots: 2\n\n      - start_time: \"17:45\"\n        end_time: \"17:55\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"17:55\"\n        end_time: \"18:10\"\n        slots: 2\n\n      - start_time: \"18:10\"\n        end_time: \"18:30\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"18:30\"\n        end_time: \"21:00\"\n        slots: 1\n        items:\n          - 懇親会\n\n  - name: \"Day 2\"\n    date: \"2024-10-26\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - 開場、受付\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 2\n\n      - start_time: \"10:30\"\n        end_time: \"10:40\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"10:40\"\n        end_time: \"10:55\"\n        slots: 2\n\n      - start_time: \"10:55\"\n        end_time: \"11:05\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"11:05\"\n        end_time: \"11:35\"\n        slots: 2\n\n      - start_time: \"11:35\"\n        end_time: \"13:05\"\n        slots: 2\n        items:\n          - お昼休憩 (お弁当提供有)\n          - \"ワークショップ: Rackを理解しRailsアプリケーション開発の足腰を鍛えよう\"\n\n      - start_time: \"13:05\"\n        end_time: \"13:20\"\n        slots: 2\n\n      - start_time: \"13:20\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 2\n\n      - start_time: \"14:00\"\n        end_time: \"14:10\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"14:10\"\n        end_time: \"14:25\"\n        slots: 2\n\n      - start_time: \"14:25\"\n        end_time: \"15:05\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"15:05\"\n        end_time: \"15:35\"\n        slots: 2\n\n      - start_time: \"15:35\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"15:45\"\n        end_time: \"16:00\"\n        slots: 2\n\n      - start_time: \"16:00\"\n        end_time: \"16:10\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"16:10\"\n        end_time: \"16:25\"\n        slots: 2\n\n      - start_time: \"16:25\"\n        end_time: \"16:35\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"16:35\"\n        end_time: \"17:05\"\n        slots: 2\n\n      - start_time: \"17:05\"\n        end_time: \"17:15\"\n        slots: 1\n        items:\n          - 休憩・移動\n\n      - start_time: \"17:15\"\n        end_time: \"17:20\"\n        slots: 1\n        items:\n          - スポンサーLT4\n\n      - start_time: \"17:20\"\n        end_time: \"17:25\"\n        slots: 1\n        items:\n          - スポンサーLT5\n\n      - start_time: \"17:25\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - スポンサーLT6\n\n      - start_time: \"17:30\"\n        end_time: \"18:10\"\n        slots: 1\n\n      - start_time: \"18:10\"\n        end_time: \"18:20\"\n        slots: 1\n        items:\n          - クロージング\n\ntracks:\n  - name: \"Hall Red\"\n    color: \"#FE4053\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Hall Blue\"\n    color: \"#02C5DA\"\n    text_color: \"#000505\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2024/venue.yml",
    "content": "---\nname: \"Ariake Central Tower Hall&Conference (有明セントラルタワーホール)\"\n\naddress:\n  street: \"Ariake Central Tower Hall, Ariake, Koto City, Tokyo 135-0063, Japan\"\n  city: \"Tokyo\"\n  region: \"Tokyo\"\n  postal_code: \"135-0063\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"Japan, 〒135-0063 Tokyo, Koto City, Ariake, 3-chōme−7−１８ 有明セントラルタワー 3F・4F\"\n\ncoordinates:\n  latitude: 35.6320541\n  longitude: 139.7936661\n\nmaps:\n  google: \"https://maps.google.com/?q=Ariake+Central+Tower+(有明セントラルタワー),35.6320541,139.7936661\"\n  apple: \"https://maps.apple.com/?q=Ariake+Central+Tower+(有明セントラルタワー)&ll=35.6320541,139.7936661\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=35.6320541&mlon=139.7936661\"\n\nurl: \"https://ariake-hall.jp\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2024/videos.yml",
    "content": "---\n# Website: https://kaigionrails.org/2024\n# Schedule: https://kaigionrails.org/2024/schedule\n\n## Day 1 - 2024-10-25\n\n- id: \"vladimir-dementyev-kaigi-on-rails-2024\"\n  title: \"Keynote: Rails Way, or the highway\"\n  raw_title: \"Rails Way, or the highway / Palkan - Kaigi on Rails 2024\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  track: \"Hall Red\"\n  slides_url: \"https://speakerdeck.com/palkan/kaigi-on-rails-2024-rails-way-or-the-highway\"\n  description: |-\n    https://kaigionrails.org/2024/talks/palkan/\n\n    【発表概要】\n    Rails Way is a software development paradigm that implies sticking to the framework architectural defaults as much as possible. Everyone starts with the Rails Way, but how far can you get without derailing from it? Let’s talk about the Rails Way core principles, how they evolved over time, and how you can embrace and enhanced it using the layered design techniques.\n\n\n    【発表者】\n    Palkan\n    GitHub https://github.com/palkan\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"english\"\n  video_provider: \"youtube\"\n  video_id: \"ZUtRyHeLq4M\"\n\n- id: \"workshop-kaigi-on-rails-2024\"\n  title: \"Workshop: Rackを理解しRailsアプリケーション開発の足腰を鍛えよう\"\n  raw_title: \"ワークショップ: Rackを理解しRailsアプリケーション開発の足腰を鍛えよう\"\n  speakers:\n    - Sunao Hogelog Komuro\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-10\"\n  description: |-\n    https://kaigionrails.org/2024/workshop/\n\n    【発表概要】\n    RailsアプリケーションはRackアプリケーションです。Railsでアプリケーションを書くということはすなわちRackアプリケーションを書いているということですが、普段Railsアプリケーション開発をする際にどこまでRackを意識しているでしょうか。\n    RailsはRackをそこまで意識しなくても開発できるフレームワークですが、Railsの足回りを支えるRackを理解していないと、Railsアプリケーションのチューニング、デプロイ、トラブルシューティングなど様々な場面で立ち止まることになってしまいます。\n    このワークショップでは一からRackを理解し、RackアプリケーションやRackミドルウェア、Rackサーバを自分で書いてみることでRackとはなんなのかしっかり理解しましょう。\n\n    https://github.com/hogelog/kaigionrails-2024-rack-workshop\n\n    【発表者】\n    hogelog\n    GitHub https://github.com/hogelog\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-kaigi-on-rails-2024\"\n  additional_resources:\n    - name: \"hogelog/kaigionrails-2024-rack-workshop\"\n      type: \"repo\"\n      url: \"https://github.com/hogelog/kaigionrails-2024-rack-workshop\"\n\n- id: \"yasuo-honda-kaigi-on-rails-2024\"\n  title: \"RailsのPull requestsのレビューの時に私が考えていること\"\n  raw_title: \"RailsのPull requestsのレビューの時に私が考えていること / Yasuo Honda - Kaigi on Rails 2024\"\n  speakers:\n    - Yasuo Honda\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/yahonda/railsnopull-requestsnorebiyunoshi-nisi-gakao-eteirukoto\"\n  slug: \"railsnopull-requestsnorebiyunoshi-nisi-gakao-eteirukoto\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/yahonda/\n\n    【発表概要】\n    Railsのpull Requestやissuesをレビューする際に、発表者がどのような考えを持っているか、またcontributorに何を期待しているかを、発表者が過去にレビューしたpull requestやissueを例に挙げて説明します。これにより、Railsへのcontributionの障壁を減らすとともに、Railsがより多くのユーザーからのフィードバックを受けるきっかけになることを期待しています。\n\n\n    【発表者】\n    Yasuo Honda\n    GitHub https://github.com/yahonda\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"90e7C4SB6jg\"\n\n- id: \"kuniaki-igarashi-kaigi-on-rails-2024\"\n  title: \"Railsの仕組みを理解してモデルを上手に育てる - モデルを見つける、モデルを分割する良いタイミング\"\n  raw_title: \"Railsの仕組みを理解してモデルを上手に育てる - モデルを見つける、モデルを分割する良いタイミング - / 五十嵐邦明 - Kaigi on Rails 2024\"\n  speakers:\n    - Kuniaki Igarashi\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/igaiga/kaigionrails2024/\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/igaiga/\n\n    【発表概要】\n    モデル群を上手に育てていく方法、特に「モデルの見つけ方」と「モデルを分割する良いタイミング」について、良い方法とその理由をRailsの考え方、仕組み、特徴から考察して話します。\n\n    モデルの見つけ方では、特にイベント型モデル、POROをつかったメンテナンスしやすいRailsアプリのつくり方を考えます。Rails wayから外れずに設計を進める方法と、Rails wayから外れていくときにRailsの仕組みを理解してできる限りなめらかに新しい設計ルールを入れていく方法を考えます。\n\n    モデルを分割する良いタイミングについては、バリデーションの条件分岐に着目します。一般に懸念されているモデルの肥大化を怖がりすぎないことを踏まえつつ、なぜそれが分割の良いタイミングであるのかをRailsの仕組みから考察します。また、分割の例としてフォームオブジェクトをつかった分割方法を考えます。\n\n    対象者として、Railsアプリでの機能実装に慣れてきたあと、メンテナンスしやすいコードを書くレベルへステップアップしたい人へ向けて、長期にわたり役立つ技術を持ち帰ってもらえるようお話しします。\n\n\n    【発表者】\n    五十嵐邦明\n    GitHub https://github.com/igaiga\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"2Ier_yHAnq8\"\n\n- id: \"sakahukamaki-kaigi-on-rails-2024\"\n  title: \"推し活としてのrails new\"\n  raw_title: \"推し活としてのrails new / sakahukamaki - Kaigi on Rails 2024\"\n  speakers:\n    - sakahukamaki\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/sakahukamaki/oshikatsu-ha-iizo\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/sakahukamaki/\n\n    【発表概要】\n    職業プログラマ。土日の趣味は観劇や遠征、家事のBGMは『雑談配信』、疲れた夜は『切り抜き動画』。読書のお供に『歌ってみた』、原稿のお供もまた、『歌ってみた』。プログラミングは平日の日中、仕事の間だけ。まかり間違っても土日にコードを書くなんて考えられない——そう思っていた時期もありました。私の推しが、利用中のサービスに見切りをつけ、次のサービスを探して迷走し始めるまでは。\n    類似サービスはこの世にごまんとあり、ただ、知る限り推しのニーズには絶妙にフィットしないものばかり。Railsを仕事で書いてきた私なら、そんなサービス一日で、いや、三日でリリースしてやれるのに——。\n    「そのサービスわいが作ってもええやろか」\n    「えっ作るって何？」\n    「一週間待ってくれよな」\n    「作るって何？？？？」\n    平日夜、仕事でもないのに bundle exec rails new . をしてから今日にいたるまで。実際に何を作ったのか、Railsアプリしかわからない人間が選んだインフラ、Discord開発鯖の運用、『職業プログラマ』だからこそ手の届かない悔しさについてお話します。「キリ番」に覚えのある方、新たなファンアートの形に興味のある方、「土日にコードを書いていない人間」に興味がある方を、お待ちしています。\n\n\n    【発表者】\n    sakahukamaki\n    GitHub https://github.com/sakahukamaki\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"SHZWrJwXq1w\"\n\n- id: \"asayama-kodai-kaigi-on-rails-2024\"\n  title: \"そのカラム追加、ちょっと待って！カラム追加で増えるActiveRecordのメモリサイズ、イメージできますか?\"\n  raw_title: \"そのカラム追加、ちょっと待って！カラム追加で増えるActiveRecordのメモリサイズ、イメージできますか? / Asayama Kodai - Kaigi on Rails 2024\"\n  speakers:\n    - Asayama Kodai\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/asayamakk/karamuzhui-jia-dezeng-eruactiverecordnomemorisaizu-imezidekimasuka\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/asayamakk/\n\n    【発表概要】\n    新機能の開発で、商品テーブルにタイムセールの価格を追加するという要件があるとします。\n    よし、 add_column :items, :sale_price, :integer するぞ!\n\n    ちょっと待ってください。そのテーブルは一度にたくさん取得されることはありませんか?\n    既にschema.rbを見ると1画面に収まらないほどのカラムを持ったテーブルに育っていないですか?\n\n    このセッションでは、カラム追加ではなくテーブル分割を選んだ方が良いのか、許容できる変更なのか、を設計ではなくメモリ使用量の観点から考えます。\n\n    バッチ処理を行うときに find_each で1000件ずつ取ってくるコードを書くけれども実際にはどれぐらいのメモリを使うのかな? といった疑問にも答えていきます。\n\n    Ruby・Railsはわかってきたけど、さらに下のレイヤーでどんなことが起きているのかを知りたい、\n    ひとつ下を歩けるRailsエンジニアになるための入口となるセッションを目指します。\n\n\n    【発表者】\n    Asayama Kodai\n    GitHub https://github.com/asayamakk\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"CBUJ1L9OAmA\"\n\n- id: \"yosuke-matsuda-kaigi-on-rails-2024\"\n  title: \"モノリスでも使える！OpenTelemetryでRailsアプリのパフォーマンス分析を始めてみよう\"\n  raw_title: \"モノリスでも使える！OpenTelemetryでRailsアプリのパフォーマンス分析を始めてみよう / ymtdzzz - Kaigi on Rails 2024\"\n  speakers:\n    - Yosuke Matsuda\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/ymtdzzz/opentelemetryderailsnopahuomansufen-xi-woshi-metemiyou-kor2024\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/ymtdzzz/\n\n    【発表概要】\n    このトークでは、あなたのRailsアプリケーション開発と運用の大きな武器となるOpenTelemetryを用いたパフォーマンス分析を始める方法についてご紹介します。\n\n    数年前まで、分散トレーシングを用いたパフォーマンス分析（APM）は導入・運用コストの高さから、大規模で複雑なマイクロサービスアーキテクチャでないと導入コストに見合わないという認識がありました。しかし昨今、技術仕様やSDK統一への動き（OpenTelemetry）や、各監視系SaaSベンダーの努力により、実装工数をはじめとする導入コストが大きく減少しました。\n\n    一見モノリシックなRailsアプリケーション（モジュラーモノリスを含む）は分散トレーシングにマッチしないように思われるかもしれませんが、私はそうは思いません。むしろ、低レイヤーを意識せずにアプリケーションを書くことができるこの優れたフレームワークの内部で何がおこっているのか、どの処理にどれくらい時間をかけているのかを「一目見て」理解できることは非常に有用だと考えています。\n\n    今回お話する内容を用いれば、皆さんはすぐにOpenTelemetryや各ベンダーが提供するライブラリを用いたパフォーマンス分析の検証を開始することができます。これにより、みなさんご自身が開発するRailsアプリケーションの運用が楽になれば嬉しいです。\n\n\n    【発表者】\n    ymtdzzz\n    GitHub https://github.com/ymtdzzz\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"KZMf1AveoDc\"\n\n- id: \"makoto-chiba-kaigi-on-rails-2024\"\n  title: \"Sidekiqで実現する長時間非同期処理の中断と再開\"\n  raw_title: \"Sidekiqで実現する長時間非同期処理の中断と再開 / hypermkt - Kaigi on Rails 2024\"\n  speakers:\n    - Makoto Chiba\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/hypermkt/pausing-and-resuming-long-running-asynchronous-jobs-with-sidekiq\"\n  slug: \"pausing-and-resuming-long-running-asynchronous-jobs-with-sidekiq\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/hypermkt/\n\n    【発表概要】\n    SmartHRでは非同期処理を効率的に実装するためにSidekiqを活用しています。従業員情報の一括登録やダウンロードなど、様々な用途に利用しています。\n\n    しかし、一部の非同期処理では長時間実行されるジョブがあり、デプロイの過程で以下のような問題が発生していました：\n\n    実行中のジョブを停止すると、想定外のタイミングで処理が中断される可能性がある\n    ジョブが最初から再実行されると、データの二重登録や実行時間の長期化が発生する可能性がある\n    これらの懸念がデプロイの妨げとなっていました。このため、SmartHRではSidekiqのワーカーで長時間にわたるジョブを安全に中断・再開できる仕組みを構築することで、安心してデプロイができるようになりました。\n\n    本セッションでは、デプロイの過程でSidekiqにおける長時間ジョブを安全に中断・再開する仕組みについて、実践的なアプローチを紹介し、実際の運用にどのように役立つかについて詳しく解説します。\n\n\n    【発表者】\n    hypermkt\n    GitHub https://github.com/hypermkt\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"0XG9Mjv0Z6s\"\n\n- id: \"yana-gi-kaigi-on-rails-2024\"\n  title: \"カスタムしながら理解するGraphQL Connection\"\n  raw_title: \"カスタムしながら理解するGraphQL Connection / yana-gi - Kaigi on Rails 2024\"\n  speakers:\n    - yana-gi\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/yanagii/kasutamusinagarali-jie-surugraphql-connection\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/yana-gi/\n\n    【発表概要】\n    GraphQLとは、クライアントが必要なデータだけを指定して取得できるデータクエリ言語及びランタイムです。Rubyではgraphql-rubyというライブラリを使うことでGraphQLを実装することができます。\n\n    ハンドメイドECサービスであるminneでは、主にAPIをRailsで実装しており、検索画面で表示される作品の取得をGraphQL APIで実装しています。また、minneでは検索エンジンにOpenSearchに加えて、別の検索エンジンも利用しており、検索結果を取得できるREST APIが提供されています。\n\n    今回はRailsアプリケーションでREST APIで返却される作品情報を取得し、クライアント用のGraphQL APIとして返却する実装しました。Active Recordから取得した結果をページネーションで返す実装に比べて、難しかった点・工夫した点を紹介します。\n\n    このセッションでは、実装するにあたってGraphQLの基本概念を説明した後、minneで検索エンジンのREST APIをバックエンドとしてGraphQLによるページネーションを実現した経験から、graphql-rubyを用いてこれを実装する方法を説明します。\n\n\n    【発表者】\n    yana-gi\n    GitHub https://github.com/yana-gi\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"AMWVsFtlkoU\"\n\n- id: \"phigasui-kaigi-on-rails-2024\"\n  title: \"cXML という電子商取引のトランザクションを支えるプロトコルと向きあっている話\"\n  raw_title: \"cXML という電子商取引のトランザクションを支えるプロトコルと向きあっている話 / phigasui - Kaigi on Rails 2024\"\n  speakers:\n    - phigasui\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/phigasui/cxml-toiudian-zi-shang-qu-yin-no-toranzakusiyonwozhi-eru-purotokorutoxiang-kiatuteiruhua\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/phigasui/\n\n    【発表概要】\n    みなさんECサイトはよく使いますか？\n    ECサイトでの購買は便利ですが、企業で物を買うときには複数の人が複数のECサイトで購買をします。そのため『どこで何を買ったかの把握や承認作業が難しい』という課題があります。我々が開発している購買管理システムは、さまざまなECサイトと連携して購買プロセスを一元化することでこの課題を解決しようとしています。\n    購買管理システムでは「パンチアウト連携」という仕組みと「cXML」というプロトコルおよびドキュメントが使われています。\n\n    ECサイトでのお買い物ではキャンセルや返品、価格変更など様々な例外ケースが存在します。\n    こういったリアルワールドの複雑さを仕様に落とし込み、外部システムとの接続に必要なパンチアウト連携・cXMLという聞きなじみのない仕組みに対応したプロダクトを開発するなかで、多くの課題や苦労がありました。\n    それらの課題とどう向きあって乗り越えてきたかお話しします。\n\n\n    【発表者】\n    phigasui\n    GitHub https://github.com/phigasui\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"IOhHO2Eug4g\"\n\n- title: \"Unlocking the Power of JRuby: Migrating Rails Apps for Enhanced Performance and Versatility\"\n  original_title: \"JRubyのパワーを解き放つ：パフォーマンスと多様性向上のためのRailsアプリ\"\n  raw_title: \"JRubyのパワーを解き放つ：パフォーマンスと多様性向上のためのRailsアプリ / Owaru Ryudo - Kaigi on Rails 2024\"\n  speakers:\n    - Mu-Fan Teng\n    # - Ryudo Awaru (japanese name)\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  id: \"unlocking-the-power-of-jruby-migrating-rails-apps-for-enhanced-performance-and-versatility\"\n  slug: \"unlocking-the-power-of-jruby-migrating-rails-apps-for-enhanced-performance-and-versatility\"\n  slides_url: \"https://gamma.app/docs/JRubyRails-38yg66zhnpfh7vc?mode=doc\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/ryudoawaru/\n\n    【発表概要】\n    既存のRuby on RailsアプリケーションをJRubyに移行する旅に出かけましょう。このトークでは、JRubyの隠れた可能性を明らかにし、特に高並行性シナリオにおけるメモリ使用効率の大幅な向上を示します。CRuby の GIL の制限を克服し、Javaのネイティブスレッドセーフティの利点を掘り下げます。\n    JRubyが豊富なJavaライブラリのエコシステムへの扉を開き、堅牢なWeb開発のためのツールキットを拡張する方法を発見しましょう。実際の事例研究と実践的な例を通じて、C-bindingのgemをJava版に適応させることを含む、移行の課題と成功を紹介します。\n    パフォーマンスの最適化、Javaライブラリの活用、またはJRubyの可能性に興味がある方に、JRubyをRailsプロジェクトに組み込むための情報に基づいた決定を行うための知識を提供します。\n\n\n    【発表者】\n    Owaru Ryudo\n    GitHub https://github.com/ryudoawaru\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"english\"\n  video_provider: \"youtube\"\n  video_id: \"7-vksWCWS3s\"\n\n- id: \"naoyuki-kataoka-kaigi-on-rails-2024\"\n  title: \"リリース8年目のサービスの1800個のERBファイルをViewComponentに移行した方法とその結果\"\n  raw_title: \"リリース8年目のサービスの1800個のERBファイルをViewComponentに移行した方法とその結果 / Naoyuki Kataoka - Kaigi on Rails 2024\"\n  speakers:\n    - Naoyuki Kataoka\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/katty0324/ririsu8nian-mu-nosabisuno1800ge-noerbhuairuwoviewcomponentniyi-xing-sitafang-fa-tosonojie-guo\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/katty0324/\n\n    【発表概要】\n    私たちはリリースから8年目になるRailsアプリケーションを運用しており、その過程で1800個ものERBビューファイルを持つ規模に成長しました。\n    Partial ERBによる運用は、パラメータ定義の曖昧さや、テンプレート内に多くのロジックが記述されること、記述の一貫性が低いことで、実行時エラーの発生や開発効率の低下を招いていました。\n    私たちはPartial ERBをViewComponentに移行する決断をし、既存のビューファイルを自動変換スクリプトにより、移行しました。\n\n    このセッションでは、私たちの具体的な移行戦略とその成果を共有し、同様の課題を抱える開発者にとって役に立つ情報を提供します。\n\n    まず私たちの抱えていた課題について紹介します。\n    Partial ERBとViewComponentの比較をしながら、ViewComponent gemについて解説します。\n    続いて、1800個のERBファイルをViewComponentに移行するために、移行スクリプトを実装した過程について紹介します。\n    最後に、ViweComponentの導入によって得られた効果や、レンダリング時間の計測結果について紹介します。\n\n\n    【発表者】\n    Naoyuki Kataoka\n    GitHub https://github.com/katty0324\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"HHP1kotYqww\"\n\n- id: \"kaibadash-kaigi-on-rails-2024\"\n  title: \"ActionCableなら簡単? 生成 AIの応答をタイピングアニメーションで表示。実装、コスト削減、テスト、運用まで。\"\n  raw_title: \"ActionCableなら簡単? 生成 AIの応答をタイピングアニメーションで表示。実装、コスト削減、テスト、運用まで。 / kaiba - Kaigi on Rails 2024\"\n  speakers:\n    - kaibadash\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://docs.google.com/presentation/d/1sPCFlWPKmnTcc11Nt99swIJ-M056JtdK2tqHYZ18QEs/edit#slide=id.g300fd7ef164_0_33\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/kaibadash/\n\n    【発表概要】\n    ChatGPT をはじめとする LLM API は、レスポンスを全て受け取るのには時間がかかりますが、ストリーミングでデータを受け取ることができます。ストリーミングで得た結果をタイピングアニメーション風に表示することで、Web API としては遅い LLM を使いつつも UX を向上させることができます。\n    Rails でこれを実現するには ActionCable を使うのが簡単そうな一方で、本番環境での運用例は少なく、以下のような不安が生まれてきました。\n\n    生成結果が数文字ごとに大量に渡されるがそのままフロントエンドに返して大丈夫か\n    LLM へのプロンプト作成が重い処理の場合、非同期で動作させたいがどんな構成にすべきか\n    コネクションを長時間占有するがアプリケーションサーバで ActionCable を動作させてよいのか\n    高い API なので開発環境のコストが気になる\n    テストしづらい\n    本トークでは、LLM と ActionCable を用いた実装、テスト、インフラ構成のポイントと、各フェーズでの課題解決方法について紹介します。\n\n\n    【発表者】\n    kaiba\n    GitHub https://github.com/kaibadash\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"VEZu2iLpXbo\"\n\n- id: \"takahiro-tsuchiya-kaigi-on-rails-2024\"\n  title: \"Rails APIモードのためのシンプルで効果的なCSRF対策\"\n  raw_title: \"Rails APIモードのためのシンプルで効果的なCSRF対策 / corocn - Kaigi on Rails 2024\"\n  speakers:\n    - Takahiro Tsuchiya\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/corocn/kaigionrails-2024-csrf\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/corocn/\n\n    【発表概要】\n    昨今のフロントエンドのリッチ化に伴い、 Rails を API モードで利用しフロントエンドとバックエンドを分離するアーキテクチャの採用が増えています。このような構成では、CSRF（クロスサイト・リクエスト・フォージェリ）対策に工夫が必要です。本セッションでは、伝統的なRailsアプリケーションのCSRF対策を振り返りながら、SPA + API構成でのCSRF対策の課題と、近年提案されている新しい対策方法について解説します。\n\n    特に、ブラウザのヘッダ情報（Origin, SameSite, Fetch Metadata など）を活用したシンプルなCSRF対策に焦点を当て、その実装方法について具体例を交えて紹介します。新しい対策の利点や、Railsでの実装手法を学ぶことで、アプリケーションのセキュリティを向上させるための知識をアップデートする機会となるでしょう。\n\n\n    【発表者】\n    corocn\n    GitHub https://github.com/corocn\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"t-X6n2k6d2A\"\n\n- id: \"yuichi-takeuchi-kaigi-on-rails-2024\"\n  title: \"現実のRuby/Railsアップグレード\"\n  raw_title: \"現実のRuby/Railsアップグレード / Yuichi Takeuchi - Kaigi on Rails 2024\"\n  speakers:\n    - Yuichi Takeuchi\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/takeyuweb/railsatupuguredo\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/takeyuweb/\n\n    【発表概要】\n    Railsのアップグレードにおいては、公式のアップグレードガイドに従って作業するのが基本となります。しかしながら現実のプロジェクトではRubyとRailsの互換性、gemの互換性、開発が終了したgem・・・といった問題に直面し、一筋縄ではいきません。\n\n    この発表では、Rails 5.0 だったアプリケーションを Rails 7.1 にアップグレードした事例を中心に、得られた知見を次のように章立てしてご紹介します。\n\n    当時の課題\n    アップグレードのための準備\n    アップグレードの手順\n    発生した問題とその解決\n    得られたもの\n    アップグレードしていくために\n    対象者は、『課題を感じているけどどのように対処すればよいかわからない中級者』並びに『課題に気づいていない初級者』です。それぞれ解決の糸口と、放置による問題の気づきに役立てていただけると思っています。上級者は「あるある」を楽しんでいただけることでしょう。\n\n    Railsは今後も素晴らしいフレームワークとして進化を続けていきますが、その恩恵を受け続けるにはアップグレードから逃れることはできません。この発表が皆さんのプロジェクトの一助となれば幸いです。\n\n\n    【発表者】\n    Yuichi Takeuchi\n    GitHub https://github.com/takeyuweb\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"zil0umJ1af0\"\n\n- id: \"izumitomo-kaigi-on-rails-2024\"\n  title: \"デプロイを任されたので、教わった通りにデプロイしたら障害になった件 〜俺のやらかしを越えてゆけ〜\"\n  raw_title: \"デプロイを任されたので、教わった通りにデプロイしたら障害になった件 〜俺のやらかしを越えてゆけ〜 / izumitomo - Kaigi on Rails 2024\"\n  speakers:\n    - izumitomo\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/techouse/depuroiworen-saretanode-jiao-watutatong-rinidepuroisitarazhang-hai-ninatutajian-an-noyarakasiwoyue-eteyuke\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/izumitomo/\n\n    【発表概要】\n    「大丈夫。PRをmainにMergeすればテストが走り、問題なければそのまま本番に反映される仕組みになってる。特に気にすることはないよ」\n\n    これは、mainへのMerge権限の引き継ぎの際にそう言われ、深く考えずにあの緑色のボタンを押したら──それが障害になった話。\n\n    本セッションでは、Rails + ECSのシンプルなアーキテクチャで、デプロイでやらかしてしまった実例とその対応策を、障害を起こした当時の状況を交えながらカジュアルにお話しします。\n    取り上げるやらかしは、以下の3つを予定しています。\n\n    ・カラムを追加するだけのデプロイで大量に例外が発生した件\n    ・Sidekiqのジョブがデプロイの度に消し飛んでいた件\n    ・社内のECS上で動かしている全サービスが、Graceful Shutdownできてなかった件\n\n    また、普段の業務ではあまり意識しないデプロイに目を向けることで、効率よく技術的知見を広げられる点も併せてお話しします。\n\n    俺のやらかしを越えてゆけ。\n\n\n    【発表者】\n    izumitomo\n    GitHub https://github.com/izumitomo\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"w0fqxSbo3yg\"\n\n- id: \"haruna-tsujita-kaigi-on-rails-2024\"\n  title: \"Hotwire or React? 〜Reactの録画機能をHotwireに置き換えて得られた知見〜\"\n  raw_title: \"Hotwire or React? 〜Reactの録画機能をHotwireに置き換えて得られた知見〜 / Haruna Tsujita - Kaigi on Rails 2024\"\n  speakers:\n    - Haruna Tsujita\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/harunatsujita/hotwire-or-react\"\n  slug: \"hotwire-or-react\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/haruna-tsujita/\n\n    【発表概要】\n    基本的なCRUD操作をSPA化するのにぴったりのHotwireと、リッチなUIを実現できるReact。それぞれに得意分野があり、チームの状況に合わせて適材適所な技術選定をできることが理想です。しかし、Hotwire便利！と言われますが、Turboに注目されることが多く、Stimulusが脚光を浴びている事例はあまり聞きません。\n\n    本トークでは、Railsアプリケーション内のviewの一部にReactで実装された録画機能をHotwire（Turbo + Stimulus）へ置き換えを試みた事例をもとに、特にStimulusを使った開発体験に着目しながら、HotwireとReactなどのフロントエンドフレームワークをどのように使い分けると幸せに開発できるのかを考察します。\n\n\n    【発表者】\n    Haruna Tsujita\n    GitHub https://github.com/haruna-tsujita\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"5ERM5lF8MSA\"\n\n- id: \"yusuke-iwaki-kaigi-on-rails-2024\"\n  title: \"Capybara+生成AIでどこまで本当に自然言語のテストを書けるか？\"\n  raw_title: \"Capybara+生成AIでどこまで本当に自然言語のテストを書けるか？ / Yusuke Iwaki - Kaigi on Rails 2024\"\n  speakers:\n    - Yusuke Iwaki\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-25\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/yusukeiwaki/capybara-plus-sheng-cheng-aidedokomadeben-dang-nizi-ran-yan-yu-notesutowoshu-keruka\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/YusukeIwaki/\n\n    【発表概要】\n    Railsには、システムテストとよばれるE2Eテストを簡単に実行できるフレームワークがあります。生成AIの登場によって、テストコードを書くことは昔ほど苦ではなくなってきました。しかしE2Eテストは作っておしまいではなく、Webサイトを改修するたびにメンテナンスをしなくてはいけません。なかなか面倒です。\n\n    これだけAIが賢くなったら、自然言語でシステムテストを書いて、サイトが変わっても自然言語の記載を変えたらそのまま動くようにはできるはずです。\n    まだまだ精度は出ないなど運用上の課題はありますが、Railsサーバーを起動してAIにWebサイトを読み取らせて自然言語でテスト内容を入力して結果を得る、というニッチな方法を、Capybaraドライバを拡張して実装する方法について解説します。\n\n\n    【発表者】\n    Yusuke Iwaki\n    GitHub https://github.com/YusukeIwaki\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"yrVIgFgjQ-Q\"\n\n## Day 2 - 2024-10-26\n- id: \"yudai-takada-kaigi-on-rails-2024\"\n  title: \"作って理解する RDBMSのしくみ\"\n  raw_title: \"作って理解する RDBMSのしくみ / Yudai Takada - Kaigi on Rails 2024\"\n  speakers:\n    - Yudai Takada\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/ydah/zuo-tuteli-jie-suru-rdbmsnosikumi\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/ydah/\n\n    【発表概要】\n    Webアプリケーションを開発する上で欠かせないRDBMS。\n    テーブル設計の手法やクエリの最適化などのテクニックについては、日々の業務を通じて理解を深めていると思います。\n    しかし、その内部構造がどうなっているのか、どのような仕組みで動いているのかについては、あまり知らない方も多いのではないでしょうか。\n\n    私も少し前まではその一人でした。\n    しかし、ふと「RDBMSも誰かが作っているのだから、自分でも作れるのではないか」と思い、　「楽しそうだから作ってみよう」 と実際に作ってみることにしました。\n    どのようなしくみで動いているのかを知ることは、その道具を存分に使うためにとても重要だと感じています。\n\n    このトークを通じて、RDBMSの内部構造やしくみを知ることで、明日からRDBMSをより効果的に使いこなすための気づきを得る一助となるようなお話をしたいと思います。\n    普段使っている道具がどのようなしくみや構造になっているか興味はありませんか？\n\n\n    【発表者】\n    Yudai Takada\n    GitHub https://github.com/ydah\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"VOeu7s5ifQQ\"\n\n- id: \"daisuke-aritomo-kaigi-on-rails-2024\"\n  title: \"都市伝説バスターズ「WebアプリのボトルネックはDBだから言語の性能は関係ない」\"\n  raw_title: \"都市伝説バスターズ「WebアプリのボトルネックはDBだから言語の性能は関係ない」 / Daisuke Aritomo (osyoyu) - Kaigi on Rails 2024\"\n  speakers:\n    - Daisuke Aritomo\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/osyoyu/du-shi-chuan-shuo-basutazu-webapurinobotorunetukuhadbdakarayan-yu-noxing-neng-haguan-xi-nai-kaigi-on-rails-2024\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/osyoyu/\n\n    【発表概要】\n    性能は重要です。性能とは機能です。性能とは競争力です。\n\n    Webアプリケーションの性能改善に取り組む際、最初に槍玉に上がるのはデータベース（SQL）の待ちに代表されるI/Oでしょう。これに手を入れることで大きな性能改善を得られることは少なくありません。\n\n    では、I/Oではない部分 ―Railsの処理、Rackサーバー、あるいはRuby自体の性能― は十分無視できるのでしょうか。答えは「否」。プロファイルであからさまなボトルネックとして表出しない、CPUによる処理の部分にも大きな宝が眠っています。\n\n    これは何も性能を最後の一滴まで絞り出す話や、Ruby/Railsにパッチを送ろうという話ではありません。CPU timeとI/O timeの関係の理解は、Pumaに代表されるマルチスレッドなサーバーを使いこなす上でも大変重要です。スレッド数は重要なパラメータですが、これを当て推量に頼らず調整するためには何を観察すれば良いのでしょう？\n\n    実は日常の開発に影響している、Rubyやフレームワークの性能設計を探求しましょう。「ボトルネックつぶし」ではない方法で性能を改善し、都市伝説をバスティングする様子をお見せします。\n\n\n    【発表者】\n    Daisuke Aritomo (osyoyu)\n    GitHub https://github.com/osyoyu\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"Ck3g4pIH9u0\"\n\n- id: \"toru-kawamura-kaigi-on-rails-2024\"\n  title: \"Cache to Your Advantage: フラグメントキャッシュの基本と応用\"\n  raw_title: \"Cache to Your Advantage: フラグメントキャッシュの基本と応用 / Toru Kawamura - Kaigi on Rails 2024\"\n  speakers:\n    - Toru Kawamura\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://drive.google.com/file/d/1Y3saUdJ98bLziDe94-4KTdughGqfAoHP/view\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/tkawa/\n\n    【発表概要】\n    キャッシュはRailsアプリケーションのパフォーマンス向上において非常に有効な手法ですが、不安からあまり利用していない方も多いのではないでしょうか。\n    このセッションでは、Railsのフラグメントキャッシュに焦点を当て、その基本的な概念、利用方法、そしてキャッシュ無効化戦略について詳しく解説します。\n    具体的には、DHHが提案した効率的なキーベースのキャッシュ無効化戦略やフラグメントキャッシュのキー決定方法について説明し、それがどのようにしてデータの一貫性を保ちながらキャッシュを管理するかを掘り下げます。\n    次に、私が開発した「レンダリングキャッシュ」gemを紹介し、フラグメントキャッシュとアクションキャッシュの利点を統合した新しいアプローチを提案します。さらに、Turbo Framesを活用して動的コンテンツを分離する方法を説明し、動的部分と静的部分を分離することで全体のキャッシュ効率を向上させる設計方法を提案します。このセッションを通じて、フラグメントキャッシュのしくみを理解し、Railsアプリケーションのパフォーマンスを向上させるための実践的な手法をお伝えします。自信を持ってキャッシュを使えるようになりましょう。\n\n\n    【発表者】\n    Toru Kawamura\n    GitHub https://github.com/tkawa\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"35ruNxFJGKw\"\n\n- id: \"koji-nakamura-kaigi-on-rails-2024\"\n  title: \"ActiveRecord SQLインジェクションクイズ (Rails 7.1.3.4)\"\n  raw_title: \"ActiveRecord SQLインジェクションクイズ (Rails 7.1.3.4) / Koji NAKAMURA - Kaigi on Rails 2024\"\n  speakers:\n    - Koji NAKAMURA\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/kozy4324/activerecord-sqlinziekusiyonkuizu-rails-7-dot-1-3-dot-4\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/kozy4324/\n\n    【発表概要】\n    あなたのRailsアプリケーションは完璧にSQLインジェクションを防げていますか？\n\n    もし新人プログラマがSQLインジェクションの可能性あるコードをプルリクエストしてきたら、あなたはそれをリジェクトできますか？\n\n    本トークではクイズも織り交ぜながら、RailsアプリケーションでSQLインジェクションを正しく防ぐための基礎知識、RailsがどのようにSQLインジェクションを防いでいるのか、Brakemanがどのように安全でないコードを検知しているのか等をコード解説を交えてお話しします。\n\n    またIPAの「安全なウェブサイトの作り方」に言及されている対策に対してRailsアプリケーションがどのように実装しているかも確認しながら、一般的なWebアプリケーションセキュリティについての基礎知識も得る機会になれば幸いです。\n\n\n    【発表者】\n    Koji NAKAMURA\n    GitHub https://github.com/kozy4324\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"jewA8tnPO-4\"\n\n- id: \"hayato-okumoto-kaigi-on-rails-2024\"\n  title: \"推し活のハイトラフィックに立ち向かうRailsとアーキテクチャ\"\n  raw_title: \"推し活のハイトラフィックに立ち向かうRailsとアーキテクチャ / Hayato OKUMOTO - Kaigi on Rails 2024\"\n  speakers:\n    - Hayato OKUMOTO\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/falcon8823/tui-sihuo-no-haitorahuitukunili-tixiang-kau-railstoakitekutiya-kaigi-on-rails-2024\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/falcon8823/\n\n    【発表概要】\n    ライブイベント会場でのグッズ販売(物販)では、当日の在庫に限りがあるため、グッズをどうしても手に入れたい熱狂的なファンが早朝から待機列を作り、数時間以上待つことがよくあります。このような物販現場を改善し、1人でも多くのファンが心地よい体験を持ち帰れるように、我々はイベント向けモバイルオーダーアプリ「caravan」を開発しました。\n\n    先着販売開始直後には、秒間400件近い決済リクエストが突発的に発生します。これは、通常のシステム構成では対応しきれない膨大なトラフィックです。さらに、サービスダウンや数量限定商品を在庫以上に販売してしまう問題は、サービスの信頼性に重大な影響を与えます。\n\n    このようなハイトラフィックでクリティカルな状況に、PostgreSQL、Redis、CDNを活用して、どのようにしてRuby on Railsで立ち向かっているのかについてお話しします。\n\n\n    【発表者】\n    Hayato OKUMOTO\n    GitHub https://github.com/falcon8823\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"SYEBAEPV0tk\"\n\n- id: \"ykpythemind-kaigi-on-rails-2024\"\n  title: \"OmniAuthから学ぶOAuth 2.0\"\n  raw_title: \"OmniAuthから学ぶOAuth 2.0 / ykpythemind - Kaigi on Rails 2024\"\n  speakers:\n    - ykpythemind\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/ykpythemind/omniauthkaraxue-buoauth2-dot-0-kaigi-on-rails-2024\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/ykpythemind/\n\n    【発表概要】\n    Railsで仕事をしていると、外部サービスを用いたログイン・ユーザー登録のためにOmniAuth gemを用いることがよくあります。OmniAuthは外部サービスとの接続を抽象化した「ストラテジ」として提供しており、外部サービスのことをよく知らなくとも認証部分を利用できるようになっています。\n    では、この裏側では実際には何が行われているのでしょうか。ここでは実際の開発において頻繁に利用されるストラテジであるOAuth2 StrategyおよびOpenID Connect Strategyについて掘り下げ、OmniAuthが隠蔽してくれている実装とは何か、またOAuth2やOpenID Connectの規格についてもお話します。\n\n\n    【発表者】\n    ykpythemind\n    GitHub https://github.com/ykpythemind\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"LDfefPahOYA\"\n\n- id: \"shinkufencer-kaigi-on-rails-2024\"\n  title: \"入門『状態』\"\n  raw_title: \"入門『状態』 / しんくう - Kaigi on Rails 2024\"\n  speakers:\n    - shinkufencer\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  track: \"Hall Red\"\n  slides_url: \"https://speakerdeck.com/shinkufencer/state-for-beginners-with-rails\"\n  description: |-\n    https://kaigionrails.org/2024/talks/shinkufencer/\n\n    【発表概要】\n    プログラムにおいて「状態」という言葉を聞くことがあると思います。この状態とは一体どういうものなのでしょうか？また状態が多いとよくないという話も紹介されますが、どのような側面においてよくないのでしょうか？\n\n    この発表では、主に初学者から中級者を対象に、プログラムの実装における「状態」とは何かについて説明します。また、実際のRuby on Railsでの開発において「状態」が複雑化しやすいケースと、その解決方法についての事例もご紹介します。\n\n    明日からすぐに実践できる、「状態」の適切な取り扱い方法をお伝えできればと思います。\n\n\n    【発表者】\n    しんくう\n    GitHub https://github.com/shinkufencer\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"NteFoikE8XU\"\n  slug: \"state-for-beginners-with-rails\"\n\n- id: \"hatsu38-kaigi-on-rails-2024\"\n  title: \"約9000個の自動テストの時間を50分から10分に短縮、偽陽性率(Flakyテスト)を1%以下に抑えるまでの道のり\"\n  raw_title: \"約9000個の自動テストの時間を50分から10分に短縮、偽陽性率(Flakyテスト)を1%以下に抑えるまでの道のり / hatsu - Kaigi on Rails 2024\"\n  speakers:\n    - hatsu38\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/hatsu38/yue-9000ge-nozi-dong-tesutono-shi-jian-wo50fen-10fen-niduan-suo-flakytesutowo1-percent-yi-xia-niyi-etahua\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/hatsu38/\n\n    【発表概要】\n    弊社の Rails アプリケーションは、7年間の開発を経て、自動テストの数が8871個、CIにかかる時間が50分、偽陽性(Flaky)によってCIが失敗する確率が15%という状況でした。 この状況から、CIの高速化 & 安定化のチームを発足し、CIの時間を10分、失敗率は1%程度と、大幅な改善を達成しました。\n    本セッションでは、この道のりを振り返り、以下のような観点から知見をお話しします。\n\n    CI・自動テストに関する根本課題の整理\n    改善に寄与した施策とその寄与度\n    効果がなかった施策とその理由\n    全員が機能開発を続けながら、サイドプロジェクトとして改善を達成するための工夫\n\n\n    【発表者】\n    hatsu\n    GitHub https://github.com/hatsu38\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"AF-2CZma30M\"\n\n- id: \"yasuko-ohba-kaigi-on-rails-2024\"\n  title: \"Hotwire光の道とStimulus\"\n  raw_title: \"Hotwire光の道とStimulus / Yasuko Ohba (nay3)  - Kaigi on Rails 2024\"\n  speakers:\n    - Yasuko Ohba\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/nay3/hotwireguang-nodao-tostimulus\"\n  slug: \"hotwireguang-nodao-tostimulus\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/nay/\n\n    【発表概要】\n    私はここ数年、Hotwireを使ってRailsアプリケーションを開発しています。Hotwireはとても強力な技術ですが、いろいろなことができるからこそ、かえって本質がクリアになっていないという思いを抱き、効果的な設計原則の言語化に努めてきました。Hotwireを使った開発を続ける中で、私の理想とする設計原則「Hotwire光の道」について、さらに言語化が進んできたので、それをご紹介したいと思います。\n\n    「Hotwire光の道」の核心は、サーバサイドですべてをコントロールできるようにすることです。今回は、Stimulusの使いこなしを題材に、この設計原則について話していきたいと思います。\n\n    Stimulusを用いると、クライアント側で動くJavaScriptを、手軽に、ある程度管理しやすい形で書くことができます。しかし、だからこそ、クライアント側にいろいろな処理を書いてしまいがちです。私自身も、開発のなかでうっかり「光の道」から外れて、クライアント側での実装をしてしまっていたことが何回もあります。そういう場合は、後になって道から外れていたことに気づき、リファクタリングをしています。今回のトークでは、そういった具体例を出しながら、Stimulusをどう使うと（または、どう使わないと）Hotwireの良さを活かしたアプリケーションを作れるのかについて、私の考えをご紹介したいと思います。\n\n\n    【発表者】\n    Yasuko Ohba (nay3)\n    GitHub https://github.com/nay\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"XWXGucFGZlI\"\n\n- id: \"shinichi-maeshima-kaigi-on-rails-2024\"\n  title: \"Sidekiq vs Solid Queue\"\n  raw_title: \"Sidekiq vs Solid Queue / Shinichi Maeshima - Kaigi on Rails 2024\"\n  speakers:\n    - Shinichi Maeshima\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/willnet/sidekiq-vs-solid-queue\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/willnet/\n\n    【発表概要】\n    Railsで時間のかかる処理はなんらかのバックグラウンドワーカーに委譲して、アプリケーションとは別で対応するのが一般的なプラクティスです。バックグラウンドワーカーの選択肢としては長らくSidekiqが高いシェアを維持していましたが、Rails8.0からSolid Queueという新しいバックグラウンドワーカーが標準として採用されることになり、今後勢力図が変わっていくことが予想されます。\n\n    Solid QueueはActive Jobのアダプタとして使うことが前提の、DBベースのバックグラウンドワーカーです。Active Jobのアダプタとして使えるバックグラウンドワーカーも、DBベースのバックグラウンドワーカーも特に珍しいものではありません。ではなぜ今になってSolid Queueが生まれ、Rails標準として採用されようとしているのでしょうか？\n\n    この発表では、Rails用のメジャーなバックグラウンドワーカーの変遷を紹介することでSolid Queueが生まれるまでの経緯を説明します。また、現在広く使われているSidekiqの機能や特性をSolid Queueと比較することで、今後どちらを選択したらよいかの指針を示します。\n\n\n    【発表者】\n    Shinichi Maeshima\n    GitHub https://github.com/willnet\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"6Z5c-cKvFwQ\"\n\n- id: \"yuya-fujiwara-kaigi-on-rails-2024\"\n  title: \"The One Person Framework 実践編\"\n  raw_title: \"The One Person Framework 実践編 / asonas - Kaigi on Rails 2024\"\n  speakers:\n    - Yuya Fujiwara\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/asonas/practical-the-one-person-framework\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/asonas/\n\n    【発表概要】\n    DHHが2021年に「The One Person Framework」という記事を書きました。\n    https://world.hey.com/dhh/the-one-person-framework-711e6318\n\n    私はkairanbanというWebアプリケーションをSinatra+React(Next.js)でつくっていました。少し前の私がアプリケーションを書くときはこのような構成になっていました。しかし、DHHの記事を読んだり、RailsConfのキーノートを視聴することで、小さなアプリケーションこそRailsで書いてもよいと感じるようになりました。\n    近年、Ruby on Railsが普遍的に仕事で使われるようになり、自分とRailsとの向き合い方や、そこから生じる忌避感をぬぐうべく私はKairanbanをRuby on Railsで書き直すことにしました。\n    書き直しをする上で、いくつかの点においてRuby on Railsの良さを改めて発見することができたのでお話します。\n\n\n    【発表者】\n    asonas\n    GitHub https://github.com/asonas\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"mBw5qcXmWEo\"\n\n- id: \"shunumata-kaigi-on-rails-2024\"\n  title: \"Importmapを使ったJavaScriptの読み込みとブラウザアドオンの影響\"\n  raw_title: \"Importmapを使ったJavaScriptの読み込みとブラウザアドオンの影響 / shu_numata - Kaigi on Rails 2024\"\n  speakers:\n    - shu_numata\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/swamp09/importmapwoshi-tutajavascriptno-du-miip-mitoburauzaadoonnoying-xiang\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/swamp09/\n\n    【発表概要】\n    Rails 7で標準となったimportmapとブラウザアドオンのAdBlockによる問題について解説します。\n    importmapを使用してJavaScriptライブラリを動的にインポートする際に、AdBlockが原因でライブラリの読み込みに失敗するユーザーが発生する問題に直面しました。\n\n    まず、importmapの仕組みと従来のJSバンドル手法との違い、利点について紹介します。DHHが推奨する「no build」の理念に触れつつ、実際のプロジェクトでの実践例や課題についても共有します。\n    次に、AdBlockがJavaScriptの読み込みをブロックする問題に直面した経緯を紹介します。私たちのアプリケーションで一部のユーザーが意図しない動作を経験していることに気づき、サーバーサイドエラーの調査を開始しました。ログ解析を通じて問題を特定し、具体的な解決策を見つけるまでのプロセスを解説します。\n\n    importmapを使用したアプリ開発の利点と落とし穴、その回避方法についてお話します。\n\n\n    【発表者】\n    shu_numata\n    GitHub https://github.com/swamp09\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"Yig0CKOOekQ\"\n\n- id: \"masato-ohba-kaigi-on-rails-2024\"\n  title: \"Data Migration on Rails\"\n  raw_title: \"Data Migration on Rails / ohbarye - Kaigi on Rails 2024\"\n  speakers:\n    - Masato Ohba\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/ohbarye/data-migration-on-rails\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/ohbarye/\n\n    【発表概要】\n    Railsアプリケーションの長期運用においてスキーマやデータの変更は不可避です。スキーマ変更（schema migration）にはRailsが公式に仕組みを提供していますが、データ変更（data migration）には決定的なデファクトスタンダードが存在しません。そのため、各現場で独自のdata migration管理方法を編み出したり、類似する多様なgemの選定に苦心した経験をお持ちの方も多いでしょう。\n\n    長年Railsに携わる開発者の多くがこうした経験をしているにも関わらず、これらのアプローチについて広く議論がなされていない現状があります。本セッションではこの状況を再考し、Railsにおけるdata migrationの既存アプローチ（SQLによる直接操作、Rakeタスク、gem利用など）を解説します。各手法のメリット・デメリット、発生しうるトレードオフ、実際のユースケースを紹介するとともに、migration scriptの実行環境やレビュープロセスなど、手法によらず考慮すべき運用課題についても視点を提供します。\n\n    本セッションを通じて、参加者がプロジェクトに応じた最適なアプローチを選択できるようになることはもちろん、既存の運用方法を見直す機会にもなるでしょう。data migrationに対する理解と視野を広げ、さらなる議論の発展につながることを期待しています。\n\n\n    【発表者】\n    ohbarye\n    GitHub https://github.com/ohbarye\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"8WgXr7lvU7c\"\n\n- id: \"kazuhiko-yamashita-kaigi-on-rails-2024\"\n  title: \"Tuning GraphQL on Rails\"\n  raw_title: \"Tuning GraphQL on Rails / Kazuhiko Yamashita - Kaigi on Rails 2024\"\n  speakers:\n    - Kazuhiko Yamashita\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/pyama86/tuning-graphql-on-rails\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/pyama86/\n\n    【発表概要】\n    話し手はモノリス構成のRuby on Railsのアプリにおいて、大量に発生していたN+1問題を多く解決してきました。そのときに利用した実践的なテクニック及び、バッチローダーの内部的な実装詳細について紹介します。\n    特にGraphQLのクエリがどのように実行されるか、バッチローダーがどのように実行されるかについては普段エンジニアが意識しづらい領域ではあるものの、認知の有無によって大きくパフォーマンスは異なります。このセッションを聞いたRubyistが書くGraphQLの実装が明日から速くなるようなセッションにします。\n\n\n    【発表者】\n    Kazuhiko Yamashita\n    GitHub https://github.com/pyama86\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"CcMEBD-C7f0\"\n\n- id: \"ryosuke-uchida-kaigi-on-rails-2024\"\n  title: \"30万人が利用するチャットをFirebase Realtime DatabaseからActionCableへ移行する方法\"\n  raw_title: \"30万人が利用するチャットをFirebase Realtime DatabaseからActionCableへ移行する方法 / Ryosuke Uchida - Kaigi on Rails 2024\"\n  speakers:\n    - Ryosuke Uchida\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/ryosk7/30mo-ren-gali-yong-surutiyatutowofirebase-realtime-databasekaraactioncableheyi-xing-surufang-fa\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/ryosk7/\n\n    【発表概要】\n    エンタメマッチングアプリ「pato」は、長らくFirebase Reailtime Databaseを使ってチャット機能を提供してきました。\n    しかしユーザー数増加に伴い、一斉送信への負荷が高まってきました。全ユーザーに送信するのに、時には1日以上かかることも。\n    そこで私はFirebase Realtime DatabaseからMySQLに移行し、Firebaseの制約を乗り越えつつ、ActionCableを使ってリアルタイム通信を実現しました。\n    本トークではRuby on RailsからFirebase Realtime Databaseを使う上での苦労と、乗り換えるに至った背景、実際にどのように移行作業を行なったのかをお話しし、\n    リアルタイムチャットアプリケーションを実装する上での知見を共有できると幸いです。\n\n    ※ 権利上、一部編集を加えています\n\n    【発表者】\n    Ryosuke Uchida\n    GitHub https://github.com/ryosk7\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"AASwXXBKFJU\"\n\n- id: \"satoshi-kobayashi-kaigi-on-rails-2024\"\n  title: \"大事なデータを守りたい！ActiveRecord Encryptionと、より安全かつ検索可能な暗号化手法の実装例の紹介\"\n  raw_title: \"大事なデータを守りたい！ActiveRecord Encryptionと、より安全かつ検索可能な暗号化手法の実装例の紹介 / 小林悟史（小林ノエル） - Kaigi on Rails 2024\"\n  speakers:\n    - Satoshi Kobayashi\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://www.docswell.com/s/free_world21/ZQRM4V-2024-10-26-165756\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/f-world21/\n\n    【発表概要】\n    近年WEBサービスに対する攻撃が増しており情報漏洩などが相次いでいますが、漏洩した場合の被害を抑える手法の1つにデータの暗号化があります。\n    RailsにはActiveRecord Encryptionという組み込みの暗号化機構がありますが、デフォルトの使い方では暗号鍵を人間が管理する必要があり依然として流出のリスクがあります。\n\n    暗号化の安全度を高めるためには\n    1）AWS等が提供するKMS(Key Management Service)などを使い暗号鍵の管理をオフロードする\n    2）個人情報やクレジットカード番号、マイナンバーのような最重要情報を保存する場合にはレコードごとに異なる暗号鍵を使う\n    といったさらなる工夫が必要ですが、現状のActiveRecord Encryptionでこれらを実現するにはかなりのカスタマイズが必要になります（2はそもそも実現できない）。\n    またビジネス要件として暗号化はしたいが検索もしたい場合もあります。\n\n    本発表ではRailsにおけるActiveRecord Encryptionを含めその他の暗号化手法を併せて紹介し、attr_encrypted gemを用いて上記のような複雑な要件を満たす方法や、永続化層では暗号化しつつ検索可能にする実装方法についても紹介します。\n    本発表を通じて各暗号化手法のメリット・デメリットや使い所を理解して頂くことを目的とします。\n\n\n    【発表者】\n    小林悟史（小林ノエル）\n    GitHub https://github.com/f-world21\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"H1QxWUo3Kbs\"\n\n- id: \"kota-kusama-kaigi-on-rails-2024\"\n  title: \"サイロ化した金融システムを、packwerk を利用して無事故でリファクタリングした話\"\n  raw_title: \"サイロ化した金融システムを、packwerk を利用して無事故でリファクタリングした話 / Kota Kusama - Kaigi on Rails 2024\"\n  speakers:\n    - Kota Kusama\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/coincheck_recruit/sairohua-sitajin-rong-sisutemuwo-packwerk-woli-yong-sitewu-shi-gu-derihuakutaringusitahua\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/cc-kusama/\n\n    【発表概要】\n    私たちが提供している金融系のサービスでは、既存動作を最大限に担保しながら品質を向上させることが強く求められます。サービス開始以来10年以上運用されているRailsアプリケーションはモノリシックな構造となっており、サイロ化による弊害が顕在化していました。例えば、複雑なロジックがアプリケーションの各所に散在していることが、品質向上の妨げとなっていました。\n\n    そうした背景の中で、複雑なロジックの共通化を行う際に、今後の改善に繋がるフレーム検討を行いました。検討の末、モジュラーモノリス構造を採用し、packwerk を使って段階的に移行を進めることとしました。結果として、無事故でリファクタリングを達成しています。\n\n    本セッションではサイロ化した金融システムをリファクタリングした事例を基に、安全な手段としてpackwerkを採用した経緯、packwerkだけでは防ぎきれない観点とその対策、現在検討している今後の展望についてお話ししたいと思います。\n\n\n    【発表者】\n    Kota Kusama\n    GitHub https://github.com/cc-kusama\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"1e96QDE3dO0\"\n\n- id: \"shu-oogawara-kaigi-on-rails-2024\"\n  title: \"omakaseしないためのrubocop.yml のつくりかた\"\n  raw_title: \"omakaseしないためのrubocop.yml のつくりかた / Shu Oogawara - Kaigi on Rails 2024\"\n  speakers:\n    - Shu Oogawara\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/linkers_tech/how-to-build-your-rubocop-dot-yml-to-avoid-omakase\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/expajp/\n\n    【発表概要】\n    お手元のRailsアプリにもきっと導入されているRubocop。Rails 7.2ではとうとうrails new した際にデフォルトで入るgemとなりました。\n\n    Rubocopは、コードスタイルをチームで統一するのに非常に便利なツールです。その一方で、自由度が非常に高いため「rubocop.yml をどう設定するか」はみなさんの悩みのタネになっているのではないでしょうか。実際、私たちのチームも同様の悩みを抱えていました。\n\n    本発表では、9ヶ月にわたってチームで少しずつ議論を進め、ToDo を解消しながらrubocop.ymlを作り上げていった過程をお話しします。\n\n\n    【発表者】\n    Shu Oogawara\n    GitHub https://github.com/expajp\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"ZFpL3-RdUys\"\n\n- id: \"kyosuke-morohashi-kaigi-on-rails-2024\"\n  title: \"Identifying User Identity\"\n  raw_title: \"Identifying User Identity / MOROHASHI Kyosuke - Kaigi on Rails 2024\"\n  speakers:\n    - Kyosuke MOROHASHI\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/moro/identifying-user-idenity\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/moro/\n\n    【発表概要】\n    Railsアプリケーションの多くには、サービスの利用者を表す \"User\" モデルが存在し、ユーザー登録したりログインしたりできます。ふだんは gem でサクッと実装したり、あるいはすでに開発済みで改めて手をいれることが少ないかもしれません。それでもサービス内でも重要なエンティティの一つであることは間違いありません。\n\n    そこで、本講演では「利用者」をあらわす「ユーザーのアイデンティティ」とは何か、そのデータをどう永続化させるか、ランタイムではどう見えるか、といったことを考察してみようと思います。\n\n    これから rails new する人はもちろん、既存サービスでユーザー周りの機能と向き合っている方々(たいへんですよね...)にとっても概念を整理する助けになれればと思います。\n\n\n    【発表者】\n    MOROHASHI Kyosuke\n    GitHub https://github.com/moro\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"55JgSAIivPk\"\n\n- id: \"kazuma-murata-kaigi-on-rails-2024\"\n  title: \"Type on Rails: Railsアプリケーションの安全性と開発体験を型で革新する\"\n  raw_title: \"Type on Rails: Railsアプリケーションの安全性と開発体験を型で革新する / kazzix - Kaigi on Rails 2024\"\n  speakers:\n    - Kazuma Murata\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/kazzix/type-on-rails-railsapurikesiyonnoan-quan-xing-tokai-fa-ti-yan-woxing-dege-xin-suru\"\n  track: \"Hall Blue\"\n  description: |-\n    https://kaigionrails.org/2024/talks/kazzix14/\n\n    【発表概要】\n    Rubyコミュニティにおいても型システムの導入というのは近年ホットな話題になっています。しかし、実際に型システムを導入するには至っていないチームも多いのではないでしょうか。\n    本発表では、ミッションクリティカルなものを含む複数のRailsアプリケーションに型チェッカーであるSorbetを導入し、1年以上運用して得られた知見を共有します。\n    実際にSorbetをRailsアプリケーションに導入するためのツールや具体的な手順、それにあたっての注意点などを紹介し、参加者が実際のアプリケーションに型システムを導入することができる状態を目指します。また、型システムをより活かしたRailsアプリケーションの設計・実装について、代数的データ型やその一種であるResult型などとともにRailsでの実例を交え紹介します。\n\n\n    【発表者】\n    kazzix\n    GitHub https://github.com/kazzix14\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"Y8aoAB0DBBI\"\n\n- id: \"koji-shimada-kaigi-on-rails-2024\"\n  title: \"Keynote: WHOLENESS, REPAIRING, AND TO HAVE FUN: 全体性、修復、そして楽しむこと\"\n  raw_title: \"WHOLENESS, REPAIRING, AND TO HAVE FUN: 全体性、修復、そして楽しむこと / 島田浩二 - Kaigi on Rails 2024\"\n  speakers:\n    - Koji Shimada\n  event_name: \"Kaigi on Rails 2024\"\n  date: \"2024-10-26\"\n  published_at: \"2024-12-11\"\n  slides_url: \"https://speakerdeck.com/snoozer05/wholeness-repairing-and-to-have-fun\"\n  track: \"Hall Red\"\n  description: |-\n    https://kaigionrails.org/2024/talks/snoozer05/\n\n    【発表概要】\n    本講演では、これからのアプリケーション開発者の方々に向けて、18年になるRailsとの旅の中で学んだ、ソフトウェアを設計する際に私が大事だと考えていることについてお話します。\n    具体的には、全体が機能するように設計すること、そして変化に向けて設計することの2点について、重要性やアプローチの仕方、Railsがどうそれをサポートしてくれているか、どこから始めると良いかといったことを説明します。\n    本講演を通じて、ソフトウェア設計という大変な仕事に楽しく向き合い続けていくための材料やヒント、糧を届けられればと思います。\n\n\n    【発表者】\n    島田浩二\n    GitHub https://github.com/snoozer05\n\n    Kaigi on Railsは、初学者から上級者までが楽しめるWeb系の技術カンファレンスです。\n    https://kaigionrails.org/\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"ilFyT5AJpv4\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2025/cfp.yml",
    "content": "---\n- link: \"https://kaigionrails.org/2025/cfp/\"\n  open_date: \"2025-06-01\"\n  close_date: \"2025-06-30\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2025/event.yml",
    "content": "---\nid: \"kaigi-on-rails-2025\"\ntitle: \"Kaigi on Rails 2025\"\ndescription: |-\n  Kaigi on Rails is an approachable, inclusive, web-focused tech conference, designed to lower the barrier of entry to participating in conferences.\nvenue: \"＠JP TOWER Hall & Conference\"\nlocation: \"Chiyoda City, Tokyo, Japan\"\nhybrid: true\nkind: \"conference\"\nstart_date: \"2025-09-26\"\nend_date: \"2025-09-27\"\npublished_at: \"2025-11-25\"\nwebsite: \"https://kaigionrails.org/2025/\"\nmastodon: \"https://ruby.social/@kaigionrails\"\nbanner_background: \"#292321\"\nfeatured_background: \"#292321\"\nfeatured_color: \"#EE633B\"\ncoordinates:\n  latitude: 35.6799708\n  longitude: 139.7645914\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2025/involvements.yml",
    "content": "---\n- name: \"Chief Organizer\"\n  users:\n    - OKURA Masafumi\n  organisations: []\n\n- name: \"Organizer\"\n  users:\n    - pupupopo88\n    - Yusuke Nakamura\n    - okayu\n    - katorie\n    - chiroru\n    - shimoju\n    - cobachie\n    - fugakkbn\n    - M-Yamashita\n    - Shogo Terai\n    - Yuta Onishi\n    - Horikoshi Yuki\n    - 4geru\n    - hachi\n    - sakahukamaki\n    - shiorin\n    - suzuka\n    - obregonia1\n    - Yla Aioi\n    - beta_chelsea\n    - PharaohKJ\n    - aiuhehe\n    - Shuta Mugikura\n    - nobu09\n    - mish\n    - mkmn\n  organisations: []\n\n- name: \"Designer\"\n  users:\n    - ksmxxxxxx\n    - sugiwe\n    - moegi\n    - machida\n  organisations: []\n\n- name: \"NOC\"\n  users:\n    - Sorah Fukumori\n    - Kasumi Hanazuki\n    - Nana Kugayama\n  organisations: []\n\n- name: \"Support\"\n  users: []\n  organisations:\n    - Ruby-no-Kai\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2025/schedule.yml",
    "content": "# Schedule: https://kaigionrails.org/2025/schedule\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2025-09-26\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Door open\n\n      - start_time: \"11:00\"\n        end_time: \"11:05\"\n        slots: 1\n        items:\n          - Opening talk\n\n      - start_time: \"11:05\"\n        end_time: \"11:10\"\n        slots: 1\n        items:\n          - Sponsor LT1\n\n      - start_time: \"11:10\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Sponsor LT2\n\n      - start_time: \"11:15\"\n        end_time: \"11:20\"\n        slots: 1\n        items:\n          - Sponsor LT3\n\n      - start_time: \"11:20\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch break\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 2\n\n      - start_time: \"14:00\"\n        end_time: \"14:10\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"14:10\"\n        end_time: \"14:25\"\n        slots: 2\n\n      - start_time: \"14:25\"\n        end_time: \"14:35\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"14:35\"\n        end_time: \"15:05\"\n        slots: 2\n\n      - start_time: \"15:05\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Afternoon break\n\n      - start_time: \"15:45\"\n        end_time: \"16:00\"\n        slots: 2\n\n      - start_time: \"16:00\"\n        end_time: \"16:10\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"16:10\"\n        end_time: \"16:40\"\n        slots: 2\n\n      - start_time: \"16:40\"\n        end_time: \"16:50\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"16:50\"\n        end_time: \"17:05\"\n        slots: 2\n\n      - start_time: \"17:05\"\n        end_time: \"17:15\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"17:15\"\n        end_time: \"17:45\"\n        slots: 2\n\n      - start_time: \"17:45\"\n        end_time: \"17:55\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"17:55\"\n        end_time: \"18:25\"\n        slots: 2\n\n      - start_time: \"18:30\"\n        end_time: \"21:00\"\n        slots: 1\n        items:\n          - Official Party\n\n  - name: \"Day 2\"\n    date: \"2025-09-27\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Door open\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 2\n\n      - start_time: \"10:30\"\n        end_time: \"10:40\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"10:40\"\n        end_time: \"10:55\"\n        slots: 2\n\n      - start_time: \"10:55\"\n        end_time: \"11:05\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"11:05\"\n        end_time: \"11:35\"\n        slots: 2\n\n      - start_time: \"11:35\"\n        end_time: \"13:05\"\n        slots: 1\n        items:\n          - Lunch break\n\n      - start_time: \"13:05\"\n        end_time: \"13:20\"\n        slots: 2\n\n      - start_time: \"13:20\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 2\n\n      - start_time: \"14:00\"\n        end_time: \"14:10\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"14:10\"\n        end_time: \"14:25\"\n        slots: 2\n\n      - start_time: \"14:25\"\n        end_time: \"15:25\"\n        slots: 1\n        items:\n          - Afternoon break\n\n      - start_time: \"15:25\"\n        end_time: \"15:55\"\n        slots: 2\n\n      - start_time: \"15:55\"\n        end_time: \"16:05\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"16:05\"\n        end_time: \"16:20\"\n        slots: 2\n\n      - start_time: \"16:20\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 2\n\n      - start_time: \"17:00\"\n        end_time: \"17:10\"\n        slots: 1\n        items:\n          - break\n\n      - start_time: \"17:10\"\n        end_time: \"17:15\"\n        slots: 1\n        items:\n          - Sponsor LT4\n\n      - start_time: \"17:15\"\n        end_time: \"17:20\"\n        slots: 1\n        items:\n          - Sponsor LT5\n\n      - start_time: \"17:20\"\n        end_time: \"17:25\"\n        slots: 1\n        items:\n          - Sponsor LT6\n\n      - start_time: \"17:25\"\n        end_time: \"18:05\"\n        slots: 1\n\n      - start_time: \"18:05\"\n        end_time: \"18:15\"\n        slots: 1\n        items:\n          - Closing\n\ntracks:\n  - name: \"Hall Red\"\n    color: \"#FE4053\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Hall Blue\"\n    color: \"#02C5DA\"\n    text_color: \"#000505\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2025/venue.yml",
    "content": "---\nname: \"JP TOWER Hall & Conference\"\ndescription: |-\n  4F / 5F\n\naddress:\n  street: \"JP TOWER Hall & Conference, 1-1 Marunouchi, Chiyoda City, Tokyo 100-7005, Japan\"\n  city: \"Tokyo\"\n  region: \"Tokyo\"\n  postal_code: \"100-7005\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"2-chōme-7-2 Marunouchi, Chiyoda City, Tokyo 100-0005, Japan\"\n\ncoordinates:\n  latitude: 35.6799708\n  longitude: 139.7645914\n\nmaps:\n  google: \"https://maps.google.com/?q=JP+TOWER+Hall+&+Conference,35.6799708,139.7645914\"\n  apple: \"https://maps.apple.com/?q=JP+TOWER+Hall+&+Conference&ll=35.6799708,139.7645914\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=35.6799708&mlon=139.7645914\"\n\nurl: \"https://www.jptower-hall.jp\"\n\nlocations:\n  - name: \"Tokyo International Forum Hall B7\"\n    kind: \"Official Party\"\n    description: |-\n      The official after-party on September 26th from 6:30 PM. Requires separate ticket purchase.\n    address:\n      street: \"3-chōme-5-1 Marunouchi\"\n      city: \"Chiyoda City\"\n      region: \"Tokyo\"\n      postal_code: \"100-0005\"\n      country: \"Japan\"\n      country_code: \"JP\"\n      display: \"3-chōme-5-1 Marunouchi, Chiyoda City, Tokyo 100-0005, Japan\"\n    url: \"https://ti.to/kaigionrails/2025-party\"\n\n    coordinates:\n      latitude: 35.6767429\n      longitude: 139.7637532\n\n    maps:\n      google: \"https://maps.google.com/?q=Tokyo+International+Forum,35.6767429,139.7637532\"\n      apple: \"https://maps.apple.com/?q=Tokyo+International+Forum&ll=35.6767429,139.7637532\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2025/videos.yml",
    "content": "# Website: https://kaigionrails.org/2025/\n# Videos: -\n---\n## Day 1 - 2025-09-26\n\n- title: \"Keynote: dynamic!\"\n  speakers:\n    - Kyosuke MOROHASHI\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"5lrPgXlgYwM\"\n  id: \"moro-dynamic-kaigi-on-rails-2025\"\n  slides_url: \"https://speakerdeck.com/moro/dynamic\"\n  description: \"\"\n\n- title: \"RailsのPostgreSQL 18対応\"\n  speakers:\n    - Yasuo Honda\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"72jNwKNqG1o\"\n  id: \"yasuo-honda-kaigi-on-rails-2025\"\n  description: |-\n    RailsはWebアプリケーションフレームワークとして、Active Recordやpg gemを通じてリレーショナルデータベースと密接に連携しています。\n    Rubyが年に1回リリースされるのと同様に、代表的なリレーショナルデータベースのひとつであるPostgreSQLも年に1回リリースされるため、\n    RailsではPostgreSQLの新機能や互換性の変更への対応が継続的に行われています。\n\n    本セッションでは、2025年にリリース予定のPostgreSQL 18対応に関するActive Recordとpg gemの変更について解説します。\n  slides_url: \"https://speakerdeck.com/yahonda/railsnopostgresql-18dui-ying\"\n\n- title: \"高度なUI/UXこそHotwireで作ろう\"\n  speakers:\n    - Naofumi Kagami\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"B8u9iEEIpwo\"\n  id: \"naofumi-kagami-kaigi-on-rails-2025\"\n  description: |-\n    簡単な画面ならHotwireで十分だけど、UI/UXが複雑なユーザ向け画面はReactが必要だと思っていませんか？\n\n    これは勘違いだと私は確信しています。\n\n    Hotwireは37signalsのBasecampやHeyで使われている他、日本の有名どころだとCookpadでも使用されています。ユーザ向けの複雑な画面において、Hotwireが十分に使えることはすでに立証済みです。\n\n    本セッションでは２つの角度からHotwireを深掘りします。\n\n    まずはEJSを使ってNext.js上でHotwireを動かし、同一UIを同一サーバ上でそれぞれ作成した上で、HotwireとNext.jsを直接比較します。意外かもしれませんが、実はHotwireの方が優れたUI/UXを作りやすいことをお見せし、その解説をします。\n\n    もう一つはHotwireの考え方の詳説です。\n    Hotwireを使えばJavaScriptを減らせると考えがちですが、高度なUI/UXを作るにはHotwire流のJavaScriptを理解する必要があります。本セッションではTurbo, Stimulusの責務を解説し、組み合わせ方を紹介します。加えて複雑なUI/UXを実現するために単一データフローやステートを活用したStimulus Controllerの設計方法をお見せします。最後にはステート管理ツール Zustandとの組み合わせ事例も紹介します。\n  slides_url: \"https://speakerdeck.com/naofumi/uxkosohotwiredezuo-rou-kaigi-on-rails-2025\"\n\n- title: \"そのpreloadは必要？──見過ごされたpreloadが技術的負債として爆発した日\"\n  speakers:\n    - Shuta Mugikura\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"Er27WWhhjFk\"\n  id: \"mugi-kaigi-on-rails-2025\"\n  description: |-\n    ActiveRecordのpreloadはN+1対策の常套手段です。しかしその便利さの裏で、いつしか誰もが見直さなくなった事前読み込みは静かに負債となり、私たちのRailsアプリケーションを全社的な障害に追い込みました。\n    私が所属している会社のアプリケーションでは、とある1リクエストが450MB超のメモリを消費し、サーバーはOut Of Memoryで実行停止に。原因は、プロダクトの成長過程で「見過ごされてきた」過剰な事前読み込みでした。\n    本セッションでは、Railsアプリケーションをより多くのユーザにスケールさせる中で生じたこのような技術的負債に対し、なぜ気付けなかったのか、そしてそれにどのように戦っていったのかを実例を元にご紹介します。\n  slides_url: \"https://speakerdeck.com/mugitti9/preload-memory-crash-fbece3e8-4fd7-48d8-abc0-6df528a05a2b\"\n\n- title: \"入門 FormObject\"\n  speakers:\n    - Shu Oogawara\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"9rGusPIx3C4\"\n  id: \"shu-oogawara-kaigi-on-rails-2025\"\n  description: |-\n    FormObjectをどんなときに使うか、または使わないか、あなたは説明できますか？\n\n    FormObjectは\"Rails Wayを延ばす方法\"としてよく紹介されます。一方でその使いどきには複数のパターンがあるためシンプルな説明が難しく、いつ使うべきか混乱している初心者の方もいるのではないでしょうか。\n\n    この発表では、まずFormObjectのユースケースを整理します。そのうえでRails Wayのどんな点に限界があってFormObjectがどう解決しているかを示しながら「いつがFormObjectの使いどきか」を提示していきます。\n  slides_url: \"https://speakerdeck.com/expajp/an-introduction-to-formobject\"\n\n- title: \"Railsアプリケーション開発者のためのブックガイド\"\n  speakers:\n    - Masayoshi Takahashi\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"QmK8uMDRdGo\"\n  id: \"masayoshi-takahashi-kaigi-on-rails-2025\"\n  description: |-\n    生成AIがRailsを含めたWeb開発についての詳しい情報を次々と吐き出してくれる現在、〈本〉を読む意味はどこにある（もっと言うと、まだ存在する）のでしょうか。\n    本発表ではRailsアプリケーションを日々開発されているみなさんが読まれると良さそうな書籍の紹介と合わせて、2025年現在における技術情報との付き合い方について改めて考えてみます。\n  slides_url: \"https://speakerdeck.com/takahashim/a-guide-to-japanese-books-for-rails-application-developers\"\n\n- title: \"もう並列実行は怖くない\"\n  speakers:\n    - katakyo\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"51z4hPZXMdM\"\n  id: \"katakyo-kaigi-on-rails-2025\"\n  description: |-\n    Ruby on Railsを使ったアプリケーションのサービス拡大により、大量データのバッチ処理をRakeタスクで書くという経験はみなさんにもあると思います。より高速化する上で並列処理というのはアプローチの一つとしてあると思いますが、 Rakeタスクの並列化で突如牙を剥くDBコネクションプール枯渇、そして気づかぬうちに忍び寄るデッドロックは多くの開発者を悩ませる根深い問題です。本セッションでは、取り扱う商品数が1000万点を超える弊社マイベストが実際に直面し、実際の案件、失敗例を元にActive Recordのコネクションプールとトランザクションの詳しい仕組みと、RAILS_MAX_THREADSやpoolサイズ、ロック取得順序がサービスにどのように影響するのかを説明します。ECS環境での具体的な設定例から、デッドロックを回避するコード戦略まで、試行錯誤とそこから得た実践的な知見やパラメータの設定方法など共有します。\n  slides_url: \"https://speakerdeck.com/katakyo/moubing-lie-shi-xing-habu-kunai-konekusiyonku-ke-jie-xiao-notamenoshi-jian-de-ahuroti\"\n\n- title: \"全問正解率約3%: RubyKaigiで出題したやりがちな危険コード5選\"\n  speakers:\n    - Yuta Nakashima\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"9G7wG3oArKM\"\n  id: \"yuta-nakashima-kaigi-on-rails-2025\"\n  description: |-\n    Ruby on Railsは、ジュニアからシニアのエンジニアまで幅広く親しまれ、今日まで様々なコードが書かれています。\n    しかし、その「誰でも書きやすい」特性ゆえに、気づかぬうちに「バグ」「パフォーマンスリスク」「セキュリティリスク」を含むコードを書いてしまうことも少なくありません。\n\n    このセッションでは、実際の現場で遭遇した「バグ」「パフォーマンスリスク」「セキュリティリスク」につながる“やりがちな危険コード”を5つ厳選して紹介します。\n    特に、この内容と同じ問題を以前RubyKaigiのブースで出題し、実務に近いコードにも関わらず100名中全問正解がわずか3人という“正答率3%”だった問題の解説に相当します。\n\n    「なぜそれが危険なのか」「どう直せばいいのか」を、インシデントや失敗談を交えて分かりやすく解説します。\n\n    このセッションを聞けば、明日から“危険な落とし穴”を避けて、もっと安心・安全なRails開発ができるようになるはず！\n  slides_url: \"https://speakerdeck.com/power3812/quan-wen-zheng-jie-lu-3-percent-rubykaigidechu-ti-sitayarigatina-wei-xian-kodo5xuan-kaigi-on-rais-2025\"\n\n- title: \"Web Componentsで実現する Hotwire\"\n  speakers:\n    - Daichi KUDO\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"nzpXMRd23y8\"\n  id: \"daichi-kudo-kaigi-on-rails-2025\"\n  description: |-\n    Hotwire を使って開発したい。しかし現実には、フロントエンドフレームワークで構築された社内デザインシステムが既に存在しており、それらを使わずにゼロから作り直すには大きなコストがかかる。だから踏み切れない──そんな悩みを抱えるチームも多いのではないでしょうか。\n\n    本トークでは、Web 標準である Web Components を使い、Angular 製の UI コンポーネントを Rails + Hotwire のサービスに段階的に組み込む事例を紹介します。既存の資産を活かしつつ、Hotwire の開発もできる、いわば\"いいとこ取り\"の構成をどう実現したのか。Rails アプリケーションにおける Web Components の活用方法を共有します。\n  slides_url: \"https://speakerdeck.com/da1chi/bridging-with-web-components\"\n\n- title: \"5 Years Fintech Rails Retrospective\"\n  original_title: \"5年間のFintech × Rails実践に学ぶ - 基本に忠実な運用で築く高信頼性システム\"\n  speakers:\n    - Masato Ohba\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"JawbjKIhzoA\"\n  id: \"ohbarye-kaigi-on-rails-2025\"\n  description: |-\n    金融サービスの開発といえば静的型付け言語による大規模エンタープライズアプリケーション...そんなイメージをお持ちの方も多いのではないでしょうか。しかし世界に目を向ければCoinbaseやStripeなど2010年代前半から急成長を遂げた金融サービスがRailsを採用しています。決済や残高管理を扱う金融サービスをRailsで5年間開発・運用した講演者の経験から言えるのは、特定の言語・フレームワークの利用ではなく\"まっとうな運用\"こそが求められる水準への近道だということです。\n\n    \"まっとうな運用\"とは監視・アラート・障害対応・パフォーマンス管理・ドキュメント化といった基本的な運用プラクティスを、妥協なく継続的に実践することです。本セッションでは1,000モデル超規模まで成長した金融サービスで実践してきた開発と運用の具体的手法を共有します。規制を考慮しつつ開発速度を維持するためのアーキテクチャやmodule設計といった「運用を見据えた開発上の工夫」を紹介し、そのうえで異常検知の仕組み・障害対応フロー・バッチドキュメンテーション・パフォーマンスモニタリング文化の醸成といった「運用面の工夫」を紹介します。\n\n    規制産業に従事する方々のみならず、Webサービスの品質向上や安定運用を目指すエンジニアが明日から使える実践的な知見と、サービスの将来を見据えた設計と運用の観点を提供します。\n  slides_url: \"https://speakerdeck.com/ohbarye/5-years-fintech-rails-retrospective\"\n\n- title: \"あなたのWebサービスはAIに自動テストしてもらえる？\"\n  speakers:\n    - Yusuke Iwaki\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"cLV_vuqIZQE\"\n  id: \"yusuke-iwaki-kaigi-on-rails-2025\"\n  description: |-\n    この1年で、生成AIが自然言語を解釈してブラウザを操作する、Browser UseやPlaywright MCPといった自動テストの仕組みが次々と登場しました。しかし、これらのツールは一体どのようにWebサイトを『見て』、私たちの指示を解釈しているのでしょうか？\n\n    本セッションでは、そのAIの『視点』の正体の1つであるアクセシビリティツリーに焦点を当てます。Playwright MCPのソースコードをベースに、自然言語の指示がどのように解釈され、どのUI要素が特定されるのか、その内部プロセスを見ていきます。また、実際にRailsのシステムテストで使用するCapybaraドライバを作って、Railsとのつなぎの部分についても解説していきます。\n\n    AI自動テストを単なる”魔法”で終わらせては面白くありません。エンジニアとしてその裏にある論理的な仕組みを理解し、生成AIがテストしやすいアプリケーションを自ら設計・実装するための基礎知識を身につけましょう。\n  slides_url: \"https://speakerdeck.com/yusukeiwaki/anatanowebsabisuhaainizi-dong-tesutositemoraeru-akusesibiriteituridedu-mijie-ku-aino-shi-dian\"\n\n- title: \"2分台で1500examples完走！爆速CIを支える環境構築術\"\n  speakers:\n    - Hayato OKUMOTO\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"j_KEXG5ncR8\"\n  id: \"hayato-okumoto-kaigi-on-rails-2025\"\n  description: |-\n    CI/CD環境が高速であることは、開発物の信頼性を維持しながら高速に成果をユーザに届けることを可能にします。CI/CD環境が遅いと、失敗に気づくのも遅くなり修正サイクルはどんどん重くなっていきます。特に我々のプロダクトを提供しているライブイベント業界においては、イベント当日に万が一問題があれば、本番環境への即時修正対応が求められるため、CI/CDの速度は開発体験だけではなく、ビジネス価値にも直結しています。\n    本セッションでは、Railsアプリケーションのrspecを2分台で1500examples以上を完了させるために、並列実行による工夫を中心に、CI/CD実行環境の最適化をどのように試行錯誤したかを紹介します。\n  slides_url: \"https://speakerdeck.com/falcon8823/2fen-tai-de1500exampleswan-zou-bao-su-ciwozhi-eruhuan-jing-gou-zhu-shu-kaigi-on-rails-2025\"\n\n- title: \"Kamalって便利？社内プロジェクト3つをKamal + AWSで運用した体験談\"\n  speakers:\n    - yappu0\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"3acQFnSHj5g\"\n  id: \"yappu0-kaigi-on-rails-2025\"\n  description: |-\n    Rails8でデフォルトのデプロイツールとなったKamal。\n    Kamal便利！と言われますが、実際に本格運用している事例はまだ少なく、特に複数アプリの同居運用となると情報が皆無でした。\n    気になるけど実際どうなの？という方もたくさんいらっしゃると思います。\n\n    本セッションでは社内プロジェクト3つをKamal+AWSで運用した体験談から、Kamal運用の罠にハマりながらも、なんとか3つのアプリを安定稼働させるまでの知見をお話しします。\n\n    Kamalの特性を活かしたAWS構成やRDSとSQLiteの使い分けから、複数人開発時のデプロイ権限問題まで、リアルな運用現場での試行錯誤をもとに、小規模チームがKamalとAWSをどのように組み合わせると楽に低コストで開発・運用できるのかもお話しします。\n\n- title: \"Railsによる人工的「設計」入門\"\n  speakers:\n    - Yasuko Ohba\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"UxzJ6zH-HBo\"\n  id: \"yasuko-ohba-kaigi-on-rails-2025\"\n  description: |-\n    「設計」ができるみなさんは、いつ、どうやって「設計」ができるようになったのでしょう？\n    \"これが設計のやり方です\" と教わって、それをなぞってできるようになりましたか？　私にはそういう経験はありません。経験を積むうちに、\"自然と\" できるようになりました。\n\n    ジュニアエンジニアの中には、まだ「設計」がよくわからないという方もいます。\n    「いきなりコードを書かないで、最初に設計すればいいんだよ！」\n    以前、私はこうアドバイスしていましたが、これではダメです。肝心の「設計」が何なのか、どうやればできるのかが分からないからです。\n    では、どうすれば？\n\n    AIの急速な進化の中、エンジニアとして生き残るには、設計スキルは当然の前提能力の一つといえるでしょう。「経験を詰めば、そのうち自然と設計できるようになるよ」と言って見守る時間がどれだけ残されているかわかりません。私たちには、人工的に「設計」を学んだり、教えたりする道筋が必要です。\n\n    本トークでは、「設計」に苦手感のある駆け出しエンジニアの方、そのようなエンジニアをサポートしたい先輩エンジニア、Railsのアーキテクチャの理解を確認したり広げたい方を対象に、次のようなことを話します。\n\n    ・「設計」とはなにか\n    ・一番最初に、完成したシステムを思い浮かべよう\n    ・デザインパーツを取捨選択して、仮ぎめする\n    ・Railsの代表的なデザインパーツたち\n  slides_url: \"https://speakerdeck.com/nay3/kaigi-on-rails-2025-she-ji\"\n\n- title: \"GraphQL×Railsアプリのデータベース負荷分散 - 月間3,000万人利用サービスを無停止で\"\n  speakers:\n    - Koya Masuda\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"NKv5gQdXhTE\"\n  id: \"koya-masuda-kaigi-on-rails-2025\"\n  description: |-\n    弊社のサービス「マイベスト」はテレビに取り上げられたことで、わずか1分間に40,000アクセスが発生し、データベースの処理がボトルネックとなりサービスダウンしました。これは予想を大きく上回るトラフィックで、DBをスケールアップしていても捌ききれないアクセス数でした。サービスのさらなる成長を見据えると、データベースのスケーラビリティは喫緊の課題です。\n\n    Railsは6.0以降では複数のデータベースを扱う仕組みとして、HTTP METHODによる自動的なロール切り替え機能を提供しています。しかし、GraphQLでは通信の大半がHTTP POSTで行われるため、この標準機能をそのまま利用することはできません。GraphQLがRDBMSやRailsと比較して新しい技術であるため、情報源が少なく、多くの開発者を悩ませています。\n\n    本セッションでは、月間3,000万人ユーザー/1.1億のGraphQLリクエストの負荷分散させた実際の取り組みを通じて、DBサーバーのCPU 利用率を67% → 17%に削減したプロセスを共有します。さらに、組織のリソース制約を踏まえた技術選定プロセスから実装、そして大規模サービスへの安全な導入戦略まで包括的に解説します。\n    参加者が自身のプロジェクトに適用可能な具体的なアプローチを得られるようなセッションになるはずです。\n  slides_url: \"https://speakerdeck.com/koxya/graphqlxrailsapurinodetabesufu-he-fen-san-yue-jian-3000mo-ren-li-yong-sabisuwowu-ting-zhi-de-f33e3449-ce80-45ec-9d3b-cb0e426a4f0f\"\n\n- title: \"今改めてServiceクラスについて考える 〜あるRails開発者の10年〜\"\n  speakers:\n    - Tomohiro Hashidate\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"fBNXy54CiDY\"\n  id: \"tomohiro-hashidate-kaigi-on-rails-2025\"\n  description: |-\n    アプリケーション開発のテクニックも様変わりし、Rubyに段階的に型検査が追加されLSPを活用した開発が一般化しました。\n    更にAIコーディングエージェントの活用が急速なスピードで普及し、更なる変化の予兆が見て取れます。\n\n    そんな中でも、Railsの基本スタイルは変わらずにMVCであり、ベストプラクティスは大きく変わっていないと考えています。\n    かつてファットモデルを避けるため、Serviceクラスというプラクティスが試される様になりそれなりに使われている話も耳にします。\n    自分自身は現在、余程のことがない限りServiceクラスというものを使わない立場です。\n    今迄の経験を元に、アーキテクチャトレンドの変化、当時と今で異なる開発環境、何故Serviceクラスから距離を置く様になったのか、Serviceクラスって何が困るのか、そしてドメイン知識をアプリケーションで表現するとはどういうことなのか、ということについて改めて言語化して解説したいと思います。\n  slides_url: \"https://speakerdeck.com/joker1007/jin-gai-meteservicekurasunituitekao-eru-arurailskai-fa-zhe-no10nian\"\n\n- title: \"Tackling Inevitable I/O Latency in Rails Apps with SSE and the async gem\"\n  original_title: \"避けられないI/O待ちに対処する: RailsアプリにおけるSSEとAsync gemの活用\"\n  speakers:\n    - moznion\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-26\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"CIan9qT2ISc\"\n  id: \"moznion-kaigi-on-rails-2025\"\n  description: |-\n    実用的・商業的なRailsアプリケーションを開発・運用していると、I/Oの遅さがエンドユーザー体験を損ねる場面にしばしば直面します。\n\n    その原因について考えると、オンラインで実行されるDBの参照・集計・更新処理が単純に遅かったり、micro servicesによるコンポーネント間のAPI通信であったり、あるいは昨今ではAI (LLM) サービスとの繋ぎ込みによる推論待ちであったりと様々です。\n    こうしたI/O待ちは多くの場合最適化の余地が限られており「避けられない待ち時間」としてシステムに組み込まれがちです。\n\n    本セッションでは、RailsとLLMをインテグレーションした複数の機能開発により得られた知見をもとに、I/Oがどうしても遅いアプリ（つまり速くできる余地がほぼない状況）であってもSSE (server-sent events) とAsync gemを併用してエンドユーザーの体験を犠牲にしない、あるいは良くするための具体的なTipsと実践的手法を紹介します。\n    I/O負荷の高い処理や外部サービスとの連携機能をRailsで扱う（ことに興味のある）エンジニアを主な対象とし、明日から応用可能な非同期アーキテクチャの導入手法をお届けします。\n\n    またこれらに加えて、一連の活動を通じて行ったOSSへの貢献・フィードバック等についても共有できればと思います。\n  slides_url: \"https://speakerdeck.com/moznion/o-latency-in-rails-apps-with-sse-and-the-async-gem\"\n\n## Day 2 - 2025-09-27\n\n- title: \"2重リクエスト完全攻略HANDBOOK\"\n  speakers:\n    - Shohei Mitani\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"YdO4XevKpL4\"\n  id: \"shohei-mitani-kaigi-on-rails-2025\"\n  description: |-\n    ユーザーが間違えて2回サブミットボタンを押したり、API連携している外部サービスがリトライで2回リクエストを送ってくるなどの「2重リクエスト問題」への対処法を紹介します。簡単な対策例を挙げると、1度目のリクエスト後にクライアントサイドでサブミットボタンを無効化する方法が挙げられます。ただし、これでは画面リロードに対処できなかったり、API連携で起こりうる2重リクエストの問題へは対処できません。様々な2重リクエストの発生要因に適切に対処するには、クライアントサイド、インフラレイヤ、アプリケーションレイヤのそれぞれで適切な防御策を講じる必要があります。\n\n    このトークでは、Idempotency-Keyやワンタイムトークン、レートリミットやロックでの対処など世の中で使われているテクニックを網羅的に説明し、あなたの開発するRailsアプリでも適切にデータ不整合を防ぎセキュアなAPIが開発できるように具体的なユースケースとともに紹介します。\n  slides_url: \"https://speakerdeck.com/shoheimitani/double-request-handbook\"\n\n- title: \"ActiveRecord使いが知るべき世界：Java/Go/TypeScriptのORMアプローチ比較\"\n  speakers:\n    - Tora Kouno # 河野裕隆\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"mQRXxi_eAFY\"\n  id: \"tora-kouno-kaigi-on-rails-2025\"\n  description: |-\n    Ruby on Rails開発に携わる多くの方にとって、データベースアクセスといえばActiveRecordが当たり前でしょう。\n    しかし、一歩外に目を向けると、ActiveRecordとは異なる設計思想やアプローチを持つORMが数多く存在します。\n    本セッションでは、Java (JPA, Doma2, MyBatis)、Go (sqlc)、TypeScript (Prisma)といった、Ruby以外の言語で広く使われている代表的なORMについて、ActiveRecordとの比較を交えながら解説します。\n\n    特に「クエリの書き方（DSL vs. SQL）」や「ORMの適用範囲（マイグレーションやスキーマ管理の有無）」といった観点に焦点を当て、それぞれのORMがどのような課題を解決し、どのようなトレードオフを伴うのかを深掘りします。ActiveRecordがいかに強力であるかを再認識するとともに、異なるパラダイムから得られる知見を通じて、今後のRails開発におけるデータアクセス層の設計や、より柔軟な技術選択のヒントを持ち帰っていただけるはずです。\n\n    [得られるもの]\n    ActiveRecordの設計思想や特徴を、異なるアプローチと比較することで深く理解できる\n    今後のプロジェクトにおけるデータアクセス層の設計や、技術選定の視野が広がるヒントを得られる\n\n- title: \"小規模から中規模開発へ、構造化ログからはじめる信頼性の担保\"\n  speakers:\n    - kakudooo\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"0le7e3OO4GM\"\n  id: \"kakudooo-kaigi-on-rails-2025\"\n  description: |-\n    私の所属するプロジェクトでは、社内外に向けて複数のプロダクトを開発・運用しています。サービスの成長に伴い、不具合による損失が大きくなってきたことや連携する外部サービスや扱うシステムの増加により、監視や調査用途でのログ収集の重要性が高まりました。\n    当時5~6名のアプリケーションエンジニアで構成されるチームということもあり、インフラに関しても専任者をアサインする余裕もなく、私を含むアプリケーションエンジニアがインフラに関する業務を兼任するような体制でした。また、これまでも監視ツール(Datadog)にログが送信されていましたが、非構造化ログが出力されていたことや、ログの出力にあたっての方針はなく、収集したログを十分に活用することができていない状態でした。\n\n    そこで、サービスが中規模化するタイミングでまずログの構造化に着手し、各サーバープロセス（Rackサーバー、非同期ジョブ、Rakeタスク）単位でのロギングや監視ツールとの連携を整備しました。\n    結果、ログからエラーを検出してアラートを送信したり、障害発生から復旧までの時間の短縮、ログとトレースの紐づけによる可観測性の向上を達成することができました。\n    この発表では、小規模→中規模に差し掛かったサービスで、アプリケーションエンジニア起点でできるRailsのロギングと監視の仕組みづくりについて事例を交えて紹介します。\n  slides_url: \"https://speakerdeck.com/kakudou3/xiao-gui-mo-karazhong-gui-mo-he-gou-zao-hua-rogukarahazimeruxin-lai-xing-nodan-bao\"\n\n- title: \"履歴 on Rails : Bitemporal Data Modelで実現する履歴管理\"\n  speakers:\n    - Makoto Chiba\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"xAxKNCBRVwQ\"\n  id: \"hypermkt-kaigi-on-rails-2025\"\n  description: |-\n    引っ越しによる住所変更や、所属部署の異動など、時間と共に変化する情報を正確に扱う「履歴管理」は、業務系アプリケーションで重要なテーマです。\n\n    SmartHRでは、従業員情報という特にクリティカルな領域でこの課題に対し、「いつから有効か」と「いつ記録されたか」の2つの時間軸を持つBitemporal Data Modelを採用しています。このモデルは強力な反面、データ構造が複雑で、調査やデータ修正といった運用が困難になるという「ツラミ」も存在しました。\n\n    本セッションでは、この「履歴 on Rails」とも言える実践の中で、私たちがBitemporal Data Modelと運用課題にどのように向き合っているか、その具体的なアプローチや得られた知見を共有します。\n  slides_url: \"https://speakerdeck.com/hypermkt/history-on-rails-with-bitemporal-data-model\"\n\n- title: \"Sidekiq その前に：Webアプリケーションにおける非同期ジョブ設計原則\"\n  speakers:\n    - morihirok\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"ebNTM8NXCjo\"\n  id: \"morihirok-kaigi-on-rails-2025\"\n  description: |-\n    非同期ジョブはWebアプリケーションにおいてメール送信や外部API連携、バッチ処理の分割などに活用され、ユーザー体験の向上やサーバー負荷の最適化に貢献します。しかしその一方で、非同期処理はシステムに複雑性をもたらし、原因の特定が困難なバグを発生させたり、デプロイフローに影響を与えてしまうなどといった問題も招きがちです。\n\n    非同期ジョブの設計には、「なぜ非同期にするのか」「ジョブの粒度はどれくらいか」「バッチや同期処理では代替できないか」といった判断とトレードオフの理解が欠かせません。本セッションでは、そうした意思決定に必要な設計観点やユースケースを、実務で得た知見をもとに整理して紹介します。\n\n    SidekiqやSolid Queueの使い方を学ぶ前に押さえておきたい、非同期ジョブの設計原則をお伝えします。\n    本セッションを通じて、非同期ジョブを安全かつスケーラブルに設計・運用するための判断基準と設計方針を持ち帰っていただければと思います。\n  slides_url: \"https://speakerdeck.com/morihirok/sidekiq-sonoqian-ni-webapurikesiyonniokerufei-tong-qi-ziyobushe-ji-yuan-ze\"\n\n- title: \"階層構造を表現するデータ構造とリファクタリング\"\n  speakers:\n    - Yuhi Sato\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"t_uclOjONEs\"\n  id: \"yuhi-kaigi-on-rails-2025\"\n  description: |-\n    私たちが日常的に利用するWebサービスには階層構造を利用した機能が数多く存在します。例えば、ECサイトの商品タグやクラウドストレージのフォルダなどです。では、開発において、こうした階層構造をRDBで表現する際、どのようなデータ構造を選択すべきでしょうか？\n\n    階層構造を表現するデータ構造を「なんとなく」で決めて実装してしまうと、N+1問題が大量に発生するといった課題に直面してしまうかもしれません。成長フェーズ、ワークロードの特性、そして要件に応じて適切なデータ構造を選択し、プロダクトの変化に応じたリファクタリングが重要です。\n\n    本セッションでは、各データ構造の特徴を詳しく解説するとともに、実際にプロダクトの階層化機能が直面したパフォーマンス課題を20倍高速化したリファクタリングについてご紹介します。セッションを通じて、参加者の階層構造を表現するデータ構造への理解を深めるとともに、既存の階層化機能の実装を見直すきっかけを提供します。\n  slides_url: \"https://speakerdeck.com/yuhisatoxxx/jie-ceng-gou-zao-wobiao-xian-surudetagou-zao-torihuakutaringu-1nian-de10bei-cheng-chang-sitapurodakutonobian-hua-toke-ti\"\n\n- title: \"Railsアプリから何を切り出す？機能分離の判断基準\"\n  speakers:\n    - yumu\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"-79CoXiN_ZI\"\n  id: \"yumu-kaigi-on-rails-2025\"\n  description: |-\n    「この機能、切り出した方がいいのかな？」そんな迷いを抱えたことはありませんか？\n\n    大規模ECサイトのRailsアプリケーション開発に携わる中で、様々なアプローチで機能を分離してきた実例と共に、実践的な判断基準を整理してお伝えします。小規模チームだからこそ見えてきた、機能分離の光と影も正直にお話しします。\n\n    明日の設計MTGで「あ、あの判断基準使えそう！」と思ってもらえる、そんなセッションを目指します。\n  slides_url: \"https://speakerdeck.com/yumu/railsapurikarahe-woqie-richu-su-ji-neng-fen-li-nopan-duan-ji-zhun-kaigi-on-rails-2025\"\n\n- title: \"Range on Rails ― 「多重範囲型」という新たな選択肢\"\n  speakers:\n    - umeda-rizap # 梅田智大\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"FjTkun7Sv78\"\n  id: \"umeda-rizap-kaigi-on-rails-2025\"\n  description: |-\n    多重範囲型（multirange）を活用し、「複雑なロジックをシンプルにする方法」を紹介します。\n    さらに、ActiveRecordで多重範囲型を扱うためのノウハウを余すことなくお伝えします。\n\n    今年、自社で予約システムをゼロから開発し、どの時間帯でも柔軟に予約ができる、自由度の高い設計を実現しました。\n    予約が可能かどうかを判定するには、「すでに予約が入っている」「店舗が休業中」「マシンがメンテナンス中」「枠自体は空いていても、前後に余白がなく予約できない」など、さまざまな条件を考慮する必要があり、開発当初はコードも複雑でパフォーマンスも悪かったです。\n\n    そこで採用したのが、PostgreSQLの多重範囲型（multirange）です。\n    予約ができない様々な期間を「範囲の集合」であると捉え、予約を確認したい対象範囲との\"差集合\"を求めることで、コードは劇的にシンプルになり、パフォーマンスも飛躍的に改善しました。\n\n    多重範囲型が威力を発揮するケースは、予約システムに限りません。\n    「連続した値の集まり」を扱う処理全般において、「範囲」という数理的な発想をコードに持ち込むことで、複雑になりがちなロジックを驚くほどシンプルに表現できます。\n\n- title: \"Introducing ReActionView: A new ActionView-Compatible ERB Engine\"\n  speakers:\n    - Marco Roth\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"english\"\n  video_provider: \"youtube\"\n  video_id: \"lPKBv0RJ8kQ\"\n  id: \"marco-roth-kaigi-on-rails-2025\"\n  description: |-\n    This talk is the conclusion of a journey I’ve been sharing throughout 2025. At RubyKaigi, I introduced Herb: a new HTML-aware ERB parser and tooling ecosystem. At RailsConf, I released developer tools built on Herb, including a formatter, linter, and language server, alongside a vision for modernizing and improving the Rails view layer.\n\n    Now, I’ll continue with ReActionView: a new ERB engine built on Herb, fully compatible with `.html.erb` but with HTML validation, better error feedback, reactive updates, and built-in tooling.\n  slides_url: \"https://speakerdeck.com/marcoroth/introducing-reactionview-a-new-actionview-compatible-erb-engine-at-kaigi-on-rails-2025-tokyo-japan\"\n\n- title: \"非同期処理実行基盤、Delayed脱出〜SolidQueue完全移行への旅路。\"\n  speakers:\n    - Shohei Kobayashi\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"e48h1Cfj0_8\"\n  id: \"shohei-kobayashi-kaigi-on-rails-2025\"\n  description: |-\n    長年のDelayedによる非同期処理基盤の運用を経て決断した大規模な非同期ジョブ基盤移行プロジェクトの全貌をお話します。\n    このプロジェクトによりこれまで利用してきた非同期処理基盤から、Rails標準であるSolidQueueへの「完全移行」プロジェクトを半年にわたって行い、無事に成し遂げることができました。\n    計画〜移行〜運用開始まで決して平坦ではなく、様々な技術的・運用的な課題に直面しましたが、開発者とSRE両方の視点で見つけた具体的な解決策ととチーム連携の力で乗り越えてきました。\n    まず移行に至った背景と、SolidQueueを選定した理由を簡潔に振り返ります。続いて、以下の「HOW（どうやったか）」に焦点を当てて深掘りします。\n    今回お話する内容を参考にしていただければSolidQueue本番投入の敷居が低くなるはずです。この発表がSolidQueue導入するためのヒントになれば嬉しいです。\n  slides_url: \"https://speakerdeck.com/srockstyle/fei-tong-qi-chu-li-shi-xing-ji-pan-delayedtuo-chu-solid-queuewan-quan-yi-xing-henolu-lu\"\n\n- title: \"非同期jobをtransaction内で呼ぶなよ！絶対に呼ぶなよ！\"\n  speakers:\n    - Yuto Urushima\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"MWoilESDfWM\"\n  id: \"yuto-urushima-kaigi-on-rails-2025\"\n  description: |-\n    Railsアプリケーションでは、ActiveRecordのtransaction内でperform_laterを呼び出すと、transactionのcommit前に非同期jobが実行され、DBの状態とジョブの実行タイミングがずれてエラーになることがあります。私たちのプロダクトでもこの問題に直面し、意図せぬエラーが発生するという事象がたまに発生するという状態に陥りました。再現性があまりなく、「たまに謎の非同期jobエラーが起こる」というデバッグもしづらい問題でした。\n\n    本セッションではこの問題の実例をもとに、どういった条件で再現するのか、どのような対策を取ったのかを紹介します。例えば、開発チーム内でコンセンサスを取った上での運用面で防ぐ工夫や、Rails7.2で新たに導入されたenqueue_after_transaction_commitオプションを使い、commit後にエンキューさせる方法などです。\n\n    「なぜかたまに非同期jobで謎のエラーが発生している」「うちも同様のことをやってるかも」「enqueue_after_transaction_commitオプションって実際にどうなの」と感じている方に向けて、明日から役立つ知識とチェックポイントをお届けします。\n\n- title: \"Railsだからできる、例外業務に禍根を残さない設定設計パターン\"\n  speakers:\n    - ei-ei-eiichi\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"rCC7pdfz_1I\"\n  id: \"ei-ei-eiichi-kaigi-on-rails-2025\"\n  description: |-\n    内製システム開発で頻発する「この顧客だけ」「この商品だけ」といった個別の例外要件。\n    安易に対応し続けるとコードは肥大化し、認知負荷と保守コストが増大。開発チームを混乱に巻き込みます。\n\n    では、私たちはこの“例外”駆動の複雑性と、どう向き合うべきなのでしょうか？\n\n    本セッションでは、増え続けるビジネスロジックをハードコーディングせず、「設定」として外部から管理可能にするアーキテクチャパターンを探求します。例外的な要件を柔軟に取り込む一方で、アプリケーションの持続可能性をどう維持するかがテーマです。\n\n    発表で扱うトピック\n    ビジネスロジックをコードから設定へ切り出す判断基準\n\n    設定がもたらす新たな複雑性と、それに対するUI/UX上の工夫\n\n    Railsで実践するための具体的な実装アプローチ\n\n    例外に強く、運用しやすく、拡張性のあるRailsアプリケーションを設計するための「引き出し」を、本セッションで持ち帰っていただければと思います。\n\n- title: \"マンガアプリAPIと共存するWeb体験版の作り方 〜 コンテンツ保護技術を添えて\"\n  speakers:\n    - baba\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"YM6ML8PDdi4\"\n  id: \"baba-kaigi-on-rails-2025\"\n  description: |-\n    マンガアプリのWeb体験版開発事例を通じて、既存のバックエンドAPIと共存するWebサイト構築の事例を紹介します。この事業ではRailsベースのバックエンドAPIを使用してモバイルアプリにサービスを提供していますが、アプリをインストールせずにWebブラウザから一部のコンテンツを閲覧できる「Web体験版」の提供に挑戦しました。\n\n    主な課題は、①APIサーバーへの負荷分散、②API実装の二重管理の回避、③マンガコンテンツの不正利用防止でした。\n\n    これらの解決策として、APIレスポンスをS3上の静的JSONファイルとして保存し、CloudFront経由で配信することでサーバー負荷の分散と既存リソースの活用を実現しました。また「GridShuffle」という独自の画像難読化処理によるコンテンツ保護施策についても紹介します。\n\n    本発表では、クラウドインフラの構成方法やコンテンツ保護のための技術的工夫など、コミック事業特有の課題解決アプローチを共有します。アプリとWebサイトの効果的な共存戦略について実践的な知見を提供します。\n\n- title: \"ドメイン指定Cookieとサービス間共有Redisで作る認証基盤サービス\"\n  speakers:\n    - Shunsuke \"Kokuyou\" Mori # 黒曜\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"W42Ke1v8icQ\"\n  id: \"kokuyouwind-kaigi-on-rails-2025\"\n  description: |-\n    複数の自社サービスを展開する企業にとって、シングルサインオンやサービス間連携を実現するための認証基盤サービスはほぼ必須といえます。\n    このような認証基盤サービスを構築する際に課題となるのが、「どうやって認証基盤から他のサービスに認証状態を共有するか」です。\n\n    オープンな規格として OpenID Connect がありますが、これは主にサードパーティーへのID受け渡しを想定しており、ファーストパーティーのみで利用するうえでは煩雑になりがちです。\n    また各種 IDaaS の利用も検討できますが、コストや機能面での制約を踏まえて選定する必要があります。\n\n    本セッションでは簡易的な認証基盤サービスを実現するために、ドメイン指定Cookieとサービス間共有Redisを組み合わせる方法を紹介します。\n    これにはいくつかの制限があるものの、単独の Rails アプリケーションと仕組みがほぼ変わらないため単純で扱いやすく、セキュリティ面でもアタックサーフェスが少ないというメリットがあります。\n    弊社の認証基盤でこの方法を採用した事例をもとに、運用上の工夫やメリットとデメリットなどを紹介します。\n  slides_url: \"https://slides.com/kokuyouwind/kaigi-on-rails-2025\"\n\n- title: \"Rails on SQLite: exciting new ways to cause outages\"\n  speakers:\n    - André Arko\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"english\"\n  video_provider: \"youtube\"\n  video_id: \"UN1_5TonU4I\"\n  id: \"andre-arko-kaigi-on-rails-2025\"\n  description: |-\n    Between Litestack and the Rails 8 trifecta of Solid Cable, Solid Cache, and Solid Queue, it's easier than ever to spin up a Rails app that doesn't need a database service or a redid service or a storage service. Just as easy are several new ways to break your app or lose your data, especially on containerized hosting services. Learn how to simplify your stack while avoiding new ways things break.\n  slides_url: \"https://speakerdeck.com/indirect/rails-on-sqlite-exciting-new-ways-to-cause-outages-36c8702d-e2ea-43bf-9fc6-a47a6caf7c84\"\n\n- title: \"A low-effort Rails workflow that combines “Complex Data Processing × Static Sites\"\n  original_title: '複雑なデータ処理 × 静的サイト\" を両立させる、楽をするRails運用'\n  speakers:\n    - Sunao Hogelog Komuro\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"Y8kEAJFymXw\"\n  id: \"hogelog-kaigi-on-rails-2025\"\n  description: |-\n    大量のデータをActiveRecordパターンのモデルに落とし込んで処理するのにRailsという道具は非常に強力です。\n    一方でメンテナンスの時間を多く割けない個人ウェブサービスの運用にRailsを使うのは「少し」体力が必要です。\n    そこで私はデータを処理して静的サイトを生成するRailsアプリケーションを作り、Railsの強力な力を用いながら、ウェブサイトそのものはランタイムなしの完全な静的サイトを個人で運営しています。\n\n    本発表では、Rails を使いたいが常時稼働サーバーを持ちたくない開発者、静的サイトジェネレータで処理させるにはデータ処理に限界を感じている人に、Railsを使った安心安全で継続可能なウェブサイト運用の話をお伝えします。\n  slides_url: \"https://speakerdeck.com/hogelog/a-low-effort-rails-workflow-that-combines-complex-data-processing-x-static-sites\"\n\n- title: \"rails g authenticationから学ぶRails8.0時代の認証\"\n  speakers:\n    - Shinichi Maeshima\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"MAoaqpCUZDM\"\n  id: \"shinichi-maeshima-kaigi-on-rails-2025\"\n  description: |-\n    Rails8.0からrails g authentication(以降認証ジェネレータと呼びます)でユーザ認証用のコードを生成できるようになりました。昔からRailsが提供するヘルパメソッドを組み合わせることで簡単に認証機能を構築できましたが、認証ジェネレータの登場によってそれがさらに容易になります。一方現場ではdeviseをはじめとした各種gemを活用して認証機能を実装するのが長らく一般的なやり方でした。Rails8.0以降、この状況は変わっていくのでしょうか？\n\n    この発表では最初に2025年時点での認証機能を取り巻く状況について解説します。その後Rails8の認証ジェネレータが生成するコードをベースにして、Railsが提供しているヘルパメソッドとジェネレータの設計思想についてひとつずつ説明していきます。この発表を聞いたあと、みなさんは認証について一段理解度が増した状態になることでしょう。\n  slides_url: \"https://speakerdeck.com/willnet/rails-g-authenticationkaraxue-hurails8-dot-0shi-dai-noren-zheng\"\n\n- title: \"「技術負債にならない・間違えない」権限管理の設計と実装\"\n  speakers:\n    - Yusuke Ishimi\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Blue\"\n  language: \"japanese\"\n  video_provider: \"youtube\"\n  video_id: \"KjeYjkPpL44\"\n  id: \"yusuke-ishimi-kaigi-on-rails-2025\"\n  description: |-\n    Webサービスの開発と運用に関わる方なら、権限管理の重要性については深く認識していることでしょう。運営アカウント、役割などの条件によって表示や操作を変えたい際に必要となります。権限は非常に繊細であり、1つの実装ミスがサービスや事業の大きな損失に繋がります。\n\n    しかし、条件をそのまま表現したadmin?のような簡易的な分岐による実装が多く見られます。そして、成長と共にadmin?やmanager?など権限の種類が増え、条件が複雑になり「レビュワーも条件を把握しきれない。」「実装を触るのが怖い。」「不具合の温床だ。」と技術負債になっているケースを多く目にしてきました。\n\n    このセッションでは、まず「なぜ権限管理は複雑になり、技術負債を生むのか」という根本原因を紐解きます。そして、その失敗から学んだ「実装・利用・理解、その全てで間違えない」というたった一つの原則に光を当てます。\n\n    私が辿り着いたのは、Rails Wayに沿ってModelとPolicyを1対1で対応させ「更に1つ軸を設ける」アプローチです。この設計によって、コードは驚くほど見通しが良くなり、エンジニア以外も誰が何をできるのかを正確に理解できるようになりました。\n\n    admin?を超えた先にある、明日からあなたのチームで実践できる「技術負債にならない・間違えない」権限管理の設計と実装。その全てをお伝えします。\n  slides_url: \"https://speakerdeck.com/naro143/ji-shu-fu-zhai-ninaranaijian-wei-enai-quan-xian-guan-li-noshe-ji-toshi-zhuang\"\n\n- title: \"Keynote: Building and Deploying Interactive Rails Applications with Falcon\"\n  speakers:\n    - Samuel Williams\n  event_name: \"Kaigi on Rails 2025\"\n  date: \"2025-09-27\"\n  published_at: \"2025-11-25\"\n  track: \"Hall Red\"\n  language: \"english\"\n  video_provider: \"youtube\"\n  video_id: \"8-o1XR070g0\"\n  id: \"samuel-williams-kaigi-on-rails-2025\"\n  slides_url: \"https://speakerdeck.com/ioquatix/building-deploying-and-monitoring-ruby-web-applications-with-falcon-kaigi-on-rails-2025\"\n  description: \"\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2026/event.yml",
    "content": "---\nid: \"kaigi-on-rails-2026\"\ntitle: \"Kaigi on Rails 2026\"\ndescription: \"\"\nlocation: \"Shibuya, Tokyo, Japan\"\nhybrid: true\nkind: \"conference\"\nstart_date: \"2026-10-16\"\nend_date: \"2026-10-17\"\nwebsite: \"https://kaigionrails.org/2026/\"\nmastodon: \"https://ruby.social/@kaigionrails\"\ncoordinates:\n  latitude: 35.65387810000001\n  longitude: 139.6938606\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2026/venue.yml",
    "content": "---\nname: \"Bellesalle Shibuya Garden\"\n\naddress:\n  street: \"\"\n  city: \"Shibuya, Tokyo\"\n  region: \"Tokyo\"\n  postal_code: \"150-0036\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"Japan, 〒150-0036 Tokyo, Shibuya, Nanpeidaichō, 16−１７ 住友不動産渋谷ガーデンタワー B1・1F\"\n\ncoordinates:\n  latitude: 35.65387810000001\n  longitude: 139.6938606\n\nmaps:\n  google: \"https://maps.google.com/?q=Bellesalle+Shibuya+Garden,35.65387810000001,139.6938606\"\n  apple: \"https://maps.apple.com/?q=Bellesalle+Shibuya+Garden&ll=35.65387810000001,139.6938606\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=35.65387810000001&mlon=139.6938606\"\n\nurl: \"https://www.bellesalle.co.jp/shisetsu/shibuya/bs_shibuyagarden/\"\n"
  },
  {
    "path": "data/kaigi-on-rails/kaigi-on-rails-2026/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/kaigi-on-rails/series.yml",
    "content": "---\nname: \"Kaigi on Rails\"\nwebsite: \"https://kaigionrails.org\"\ntwitter: \"kaigionrails\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Kaigi on Rails\"\ndefault_country_code: \"JP\"\nyoutube_channel_name: \"kaigionrails\"\nlanguage: \"japanese\"\nyoutube_channel_id: \"UCKD7032GuzUjDWEoZsfnwoA\"\n"
  },
  {
    "path": "data/kansai-rubykaigi/kansai-rubykaigi-08/cfp.yml",
    "content": "---\n- link: \"https://forms.gle/TrTJs5c7iJf6LwKD6\"\n  open_date: \"2025-02-06\"\n  close_date: \"2025-05-07\"\n"
  },
  {
    "path": "data/kansai-rubykaigi/kansai-rubykaigi-08/event.yml",
    "content": "---\nid: \"kansai-rubykaigi-08\"\ntitle: \"Kansai RubyKaigi 08\"\ndescription: \"\"\nlocation: \"Kyoto, Japan\"\nkind: \"conference\"\nstart_date: \"2025-06-28\"\nend_date: \"2025-06-28\"\nwebsite: \"https://regional.rubykaigi.org/kansai08/\"\nfeatured_background: \"#700002\"\nfeatured_color: \"#FFFFFF\"\nbanner_background: \"#700002\"\ncoordinates:\n  latitude: 35.011564\n  longitude: 135.7681489\naliases:\n  - KansaiRubyKaigi08\n"
  },
  {
    "path": "data/kansai-rubykaigi/kansai-rubykaigi-08/involvements.yml",
    "content": "---\n- name: \"Chief Organizer\"\n  users:\n    - Yudai Takada\n\n- name: \"Organizer\"\n  users:\n    - hachi\n    - ogomr\n    - luccafort\n    - Takafumi ONAKA\n    - smantani\n    - spring_kuma\n    - murajun1978\n    - uproad3\n    - Pasta-K\n    - youcune\n    - honeniq\n    - Kazuhiro NISHIYAMA\n    - toshima66\n    - khori\n    - k-yoshida\n    - nishi_okashi\n    - 107steps\n    - okeysea\n    - momoonga\n    - sanfrecce_osaka\n\n- name: \"Designer\"\n  users:\n    - reina\n    - Momoka\n    - Yudai Takada\n\n- name: \"NOC\"\n  users:\n    - uproad3\n    - murajun1978\n    - Yoshi\n\n- name: \"Support\"\n  organisations:\n    - Nihon Ruby no Kai\n"
  },
  {
    "path": "data/kansai-rubykaigi/kansai-rubykaigi-08/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Matz Sponsor\"\n      description: |-\n        Matz Sponsor tier and its sponsors\n      level: 1\n      sponsors:\n        - name: \"SmartHR\"\n          website: \"https://smarthr.co.jp/\"\n          slug: \"smarthr\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/smarthr.png\"\n\n        - name: \"Tebiki\"\n          website: \"https://tebiki.co.jp/\"\n          slug: \"tebiki\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/tebiki.png\"\n\n        - name: \"Timee, Inc.\"\n          website: \"https://corp.timee.co.jp/\"\n          slug: \"timee\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/timee.png\"\n\n        - name: \"freee K.K.\"\n          website: \"https://www.freee.co.jp\"\n          slug: \"freee\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/freee.png\"\n\n        - name: \"Knowledge Lab Co., Ltd.\"\n          website: \"https://knowledgelabo.com/\"\n          slug: \"knowledgelabo\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/knowledgelabo.png\"\n\n    - name: \"Take Sponsor\"\n      description: |-\n        Take Sponsor tier and its sponsors\n      level: 2\n      sponsors:\n        - name: \"Agileware\"\n          website: \"https://agileware.jp/\"\n          slug: \"agileware\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/agileware.png\"\n\n        - name: \"ANDPAD Inc.\"\n          website: \"https://engineer.andpad.co.jp/\"\n          slug: \"andpad\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/andpad.png\"\n\n        - name: \"KOMOJU\"\n          website: \"https://ja.komoju.com/company/\"\n          slug: \"komoju\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/degica.png\"\n\n        - name: \"ESM Inc.\"\n          website: \"https://esm.co.jp/\"\n          slug: \"esm\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/esm.png\"\n\n        - name: \"Hatena Co., Ltd.\"\n          website: \"https://hatena.co.jp/\"\n          slug: \"hatena\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/hatena.png\"\n\n        - name: \"INGAGE Inc.\"\n          website: \"https://ingage.co.jp/\"\n          slug: \"ingage\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/ingage.png\"\n\n        - name: \"Money Forward, Inc.\"\n          website: \"https://corp.moneyforward.com/\"\n          slug: \"moneyforward\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/moneyforward.png\"\n\n        - name: \"PONOS Corp.\"\n          website: \"https://www.ponos.jp/\"\n          slug: \"ponos\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/ponos.png\"\n\n        - name: \"Ruby Development Inc.\"\n          website: \"https://www.ruby-dev.jp/\"\n          slug: \"rubydevelopment\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/rubydevelopment.png\"\n\n        - name: \"6VOX CO.,LTD\"\n          website: \"https://6vox.com/\"\n          slug: \"sixvox\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/sixvox.png\"\n\n        - name: \"STMN.INC\"\n          website: \"https://stmn.co.jp/\"\n          slug: \"stmn\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/stmn.png\"\n\n    - name: \"Ume Sponsor\"\n      description: |-\n        Ume Sponsor tier and its sponsors\n      level: 3\n      sponsors:\n        - name: \"A's Child\"\n          website: \"https://www.as-child.com/\"\n          slug: \"as-child\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/aschild.png\"\n\n        - name: \"codeTakt Inc.\"\n          website: \"https://codetakt.com/\"\n          slug: \"codetakt\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/codetakt.png\"\n\n        - name: \"Gaji-Labo\"\n          website: \"https://www.gaji.jp/\"\n          slug: \"gajilabo\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/gajilabo.png\"\n\n        - name: \"#local_tech\"\n          website: \"https://localtechjp.notion.site\"\n          slug: \"localtech\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/localtech.png\"\n\n        - name: \"Lokka, Inc\"\n          website: \"https://lokka.jp/\"\n          slug: \"lokka\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/lokka.png\"\n\n        - name: \"mov inc.\"\n          website: \"https://mov.am/\"\n          slug: \"mov\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/mov.png\"\n\n        - name: \"Network Applied Communication Laboratory Ltd.\"\n          website: \"https://www.netlab.jp/\"\n          slug: \"nacl\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/nacl.png\"\n\n        - name: \"Tokyo Ruby Conference 12 Executive Committee\"\n          website: \"https://regional.rubykaigi.org/tokyo12/\"\n          slug: \"tokyorubykaigi\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/tokyorubykaigi.png\"\n\n        - name: \"TwoGate\"\n          website: \"https://twogate.com/\"\n          slug: \"twogate\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/twogate.png\"\n\n        - name: \"xalpha Inc.\"\n          website: \"https://xalpha.jp/\"\n          slug: \"xalpha\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/xalpha.png\"\n\n        - name: \"YouCube LLC.\"\n          website: \"https://youcube.jp/\"\n          slug: \"youcube\"\n          logo_url: \"https://regional.rubykaigi.org/kansai08/sponsors/youcube.png\"\n"
  },
  {
    "path": "data/kansai-rubykaigi/kansai-rubykaigi-08/videos.yml",
    "content": "# Website: https://regional.rubykaigi.org/kansai08/\n# Schedule: https://regional.rubykaigi.org/kansai08/schedule\n---\n### Pre-Party - 2025-06-27\n\n- title: \"Rubyでやりたい駆動開発\"\n  speakers:\n    - Miyuki Koshiba\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-27\"\n  language: \"japanese\"\n  slides_url: \"https://speakerdeck.com/chobishiba/ruby-driven-development\"\n  description: |-\n    気づけば「Rubyでやってみたい」と考えていた——そんな経験、Rubyistならあるのではないでしょうか。\n    私にとってそれは、クリエイティブコーディングや電子工作でした。最初に触れたときは別の言語でしたが、「Rubyでできたらもっと楽しいのに」と思わずにはいられなかったのです。\n    この発表では、そんな「Rubyでやりたい」という衝動からはじまり、試行錯誤の末に作品を形にした過程を紹介します。\n\n    完成した作品は短いコードで動いていますが、そこに至るまでの道のりには、紆余曲折ありました。挫折しかけたこともありましたが、やっぱり「Rubyでやりたい」この一心で乗り越えられました。だからこそRubyで動かせた時の喜びは大きなものでした。\n\n    紹介するのは、プログラムの動きが感じられるインタラクティブな作品や、LEDマトリクスを使った表現など。「何か作りたいけど、何から始めればいいかわからない」という人が、自分の“好き”を入り口にチャレンジしてみるヒントになるかもしれません。\n    聞いてくださったみなさんが、自分だけの世界をRubyで創るきっかけになれば嬉しいです。\n\n    https://regional.rubykaigi.org/kansai08/presentations/chobishiba\n  video_provider: \"scheduled\"\n  video_id: \"miyuki-koshiba-kansai-rubykaigi-08\"\n  id: \"miyuki-koshiba-kansai-rubykaigi-08\"\n\n- title: \"RubyGem開発で鍛えるソフトウェア設計力\"\n  speakers:\n    - joker1007\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-27\"\n  language: \"japanese\"\n  description: |-\n    より良いシステムより良いソフトウェアを開発するためには、目的を明確にしそれを実現する構造を思い描く力、つまり設計力というものが必要になります。\n\n    その力の源泉となるのは、要点を捉え言語化する力、そしてユースケースを想像する力、抽象と具体を行き来する力、などが挙げられます。\n\n    こういった力を育てるには日頃の経験の積み重ねが必要ですが、その中でもRubyGemを開発することで得られる経験にスポットを当て、設計力を鍛える上で自分にとって重要だと感じている考え方を紹介します。\n\n    また、実際にRubyGemを開発する上での取っ掛かりが得られる様に、世の中に存在するGemのパターンを分類し、自分がどういう発想の元で作ってきたかを紹介することで、この発表を聞いた人が、RubyGemの開発とOSS活動をより身近に感じられる様な話にしたいと考えています。\n\n    https://regional.rubykaigi.org/kansai08/presentations/joker1007\n  video_provider: \"scheduled\"\n  video_id: \"joker1007-kansai-rubykaigi-08\"\n  id: \"joker1007-kansai-rubykaigi-08\"\n\n- title: \"ruby.wasmで多人数リアルタイム通信ゲームを作ろう\"\n  speakers:\n    - lni_T\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-27\"\n  language: \"japanese\"\n  description: |-\n    Rubyはバージョン3.2.0にてWebAssemblyがサポートされ、ブラウザやCDNエッジ等、WebAssemblyが動作する環境でRuby(ruby.wasm)が動作するようになりました。\n\n    これにより、以前は別言語での実装が必要だった機能においても、Rubyコードで実装することが可能となりました。\n\n    そんなruby.wasmに、WebSocketの力が加わると、もっと楽しいものが作り出せるのではないでしょうか。\n\n    今回のトークは「ruby.wasmでのリアルタイム通信」をメインテーマに、ruby.wasm on Browser 環境での開発を始める方法の紹介と、実際に開発したアプリの解説を行います。\n\n    https://regional.rubykaigi.org/kansai08/presentations/lnit\n  video_provider: \"scheduled\"\n  video_id: \"lni_T-kansai-rubykaigi-08\"\n  id: \"lni_T-kansai-rubykaigi-08\"\n\n- title: \"ruby.DJ on Ruby Ver.0.1\"\n  speakers:\n    - Masaya Kudo\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-27\"\n  language: \"japanese\"\n  description: |-\n    2025年4月末よりRubyでDJソフトウェアの開発に着手し始めました。\n    PoC(Proof of Concept)版のデモ実演、工夫したポイントや技術的な課題、今後の展望をご紹介します。\n\n    私はエンジニア歴15年、DJ歴16年という二足の草鞋を履き続けています。DJはPCで回しており、Serato ITCHというDJソフトウェアを愛用し続けています。\n    RubyKaigi 2025にてRubyで音を鳴らすことをテーマにした発表が多く刺激を受け、DJソフトウェアの開発にチャレンジする決意をしました。\n\n    PoC版は、Ruby(gtk4)で実装したアプリケーションUIから、Rustで実装したオーディオエンジンをFFIで呼び出す構成で開発を試しています。2トラックでのWavファイルの再生、およびクロスフェードで曲を繋ぐ様子をデモでお届けする予定です。\n\n    https://regional.rubykaigi.org/kansai08/presentations/msykd/\n  video_provider: \"scheduled\"\n  video_id: \"masaya-kudo-kansai-rubykaigi-08\"\n  id: \"masaya-kudo-kansai-rubykaigi-08\"\n\n### Day 1 - 2025-06-28\n\n- title: \"Keynote: Witchcraft for Memory\"\n  speakers:\n    - Masataka Kuwabara\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-28\"\n  video_provider: \"scheduled\"\n  video_id: \"masataka-kuwabara-kansai-rubykaigi-08\"\n  id: \"masataka-kuwabara-kansai-rubykaigi-08\"\n  language: \"japanese\"\n  description: |-\n    https://regional.rubykaigi.org/kansai08/presentations/pocke\n\n- title: \"『富岳』と研究者をRubyでつなぐ：シミュレーション管理ツールOACIS\"\n  speakers:\n    - Yohsuke Murase\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-28\"\n  video_provider: \"scheduled\"\n  video_id: \"yohsuke-murase-kansai-rubykaigi-08\"\n  id: \"yohsuke-murase-kansai-rubykaigi-08\"\n  language: \"japanese\"\n  description: |-\n    スーパーコンピュータ「富岳」のような高性能計算機を使った科学技術計算では、大量のシミュレーションジョブを管理する必要があります。ところが、最先端の研究現場であっても、ジョブ投入や結果整理などの作業は意外\n\n    https://regional.rubykaigi.org/kansai08/presentations/yohm\n\n- title: \"『1ヶ月でWebサービスを作る会』で出会った rails new、そして今に至る rails new\"\n  speakers:\n    - kiryuanzu\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-28\"\n  video_provider: \"scheduled\"\n  video_id: \"kiryuanzu-kansai-rubykaigi-08\"\n  id: \"kiryuanzu-kansai-rubykaigi-08\"\n  language: \"japanese\"\n  description: |-\n    https://regional.rubykaigi.org/kansai08/presentations/kiryuanzu\n\n- title: \"mrubyとmicro-ROSが繋ぐロボットの世界\"\n  speakers:\n    - Katsuhiko Kageyama\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-28\"\n  video_provider: \"scheduled\"\n  video_id: \"kishima-kansai-rubykaigi-08\"\n  id: \"kishima-kansai-rubykaigi-08\"\n  language: \"japanese\"\n  description: |-\n    PicoRubyやMicroRubyの登場によってRubyでも物理的なデバイスをコントロールすることに注目が集まっている昨今、最近仕事でロボットを扱っている私は、ロボットもその仲間に加えることはできないかと考えるようになりました。\n\n    ロボットの制御の世界では、ROS（Robot Operating System）とよばれるOSSのフレームワークが広く使われています。通常はLinuxが前提となるROSなのですが、組み込みデバイス上でも動くmicro-ROSというものが存在します。\n\n    micro-ROSは、Cでの開発が前提となる環境ですが、それをRuby（mruby）で書けたらきっと楽しく開発できるだろうと思い、mrubyでmicro-ROSが使える環境を実装したいと考えています。\n\n    本発表では、そのプロトタイプの実装内容と技術的な課題、そして実際にロボット制御のデモの動画を紹介します。\n\n    https://regional.rubykaigi.org/kansai08/presentations/kishima\n\n- title: \"ふだんのWEB技術スタックだけでアート作品を作ってみる\"\n  speakers:\n    - Akira Yagi\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-28\"\n  video_provider: \"scheduled\"\n  video_id: \"akira888-kansai-rubykaigi-08\"\n  id: \"akira888-kansai-rubykaigi-08\"\n  language: \"japanese\"\n  description: |-\n    超絶技巧プログラミングやCreative Codingも楽しいけれど、普段の業務で書かれているロジックをうまく使ってあげるだけでも面白いことはいくらでもできます。すこしのひらめきとお手元の技術スタックを組み合わせれば、おやっと思わせるアート作品を作ることだってさほど難しくはありません。\n\n    またものづくりのためのコードも、課題解決のためのコードも本質的には同じものです。日々の業務スキルを活かし、磨き、学ぶことができます。今回はRails, Hotwire, HTML, CSSという馴染のある技術を用いて作成した、時計をモチーフにしたシンプルな動きが魅力的なアート作品を題材に、趣味のコーディングの楽しさやメリットなどについてのお話や、ちょっと踏み込んでWASMなどのWEBサーバーと異なる実行環境で実装したらどうなるかという実例をお見せしたいと思います。\n\n    https://regional.rubykaigi.org/kansai08/presentations/akira888\n\n- title: \"Rubyと💪を作り込む - PicoRubyとマイコンでの自作トレーニング計測装置を用いたワークアウトの理想と現実\"\n  speakers:\n    - Toshiaki \"bash\" KOSHIBA\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-28\"\n  video_provider: \"scheduled\"\n  video_id: \"bash-kansai-rubykaigi-08\"\n  id: \"bash-kansai-rubykaigi-08\"\n  language: \"japanese\"\n  description: |-\n    ウェイトトレーニングと Ruby の意外な共通点、それは「計測と改善の継続」です。本セッションではESP32を搭載したマイコンのATOM Matrix上で動くPicoRubyで開発した計測機構による、Velocity Based Training(VBT)に基づく重量設定のためのトレーニングの挙上速度・挙上加速度という客観的データをリアルタイムに計測・分析するシステムの開発ストーリーを共有します。\n\n    この分野では歴史的に「限界まで挙げる」的な主観的指標がもっぱら用いられてきました。ただそのような指標はコンディションや感覚の影響も大きく、適切な負荷設定には高度な勘と経験が必要でした。近年はセンサーの発展により「0.4m/秒で動く」的な動作を扱うことができるようになり、速度と重さの相関関係をもとにした的確な負荷設定が可能になり、スポーツ現場への適用が進んでいます。\n\n    しかしその装置は個人レベルで気軽に手に取れる状況にはありません。そこでRuby の柔軟性とマイコンの手軽さを組み合わせることで、高価な専用機器なしでもVBTは実現可能と考え、この開発過程と、そこから得られた知見を紹介します。\n\n    筋肉もRubyも計測して改善してこそ継続した強化が行えます。Rubyをたのしむ心と、健康寿命を支えるキーとなる筋肉作り。全くかけ離れた活動にみえますが、実は同じように高めることができるのです。\n\n    https://regional.rubykaigi.org/kansai08/presentations/bash\n\n- title: \"分散オブジェクトで遊ぼう！〜dRubyで作るマルチプレイヤー迷路ゲーム〜\"\n  speakers:\n    - yumu\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-28\"\n  video_provider: \"scheduled\"\n  video_id: \"yumu-kansai-rubykaigi-08\"\n  id: \"yumu-kansai-rubykaigi-08\"\n  language: \"japanese\"\n  description: |-\n    Ruby専用の分散オブジェクトシステムであるdRubyを使って、ブラウザで遊べる協力型マルチプレイヤー迷路ゲームを作りました！\n\n    このゲームでは、様々な役割を持つプレイヤーが力を合わせて迷路を攻略します。dRubyとWebSocketを組み合わせたリアルタイム通信や、マルチスレッドを使った効率的な処理など、Rubyならではの書きやすさと読みやすさを活かした実装のポイントをご紹介します。\n\n    たとえば、以下のようなシンプルなコードだけで、複数プレイヤーが同時に遊べるゲームの基盤が作れてしまいます。\n\n    # サーバー側\n    DRb.start_service('druby://localhost:8787', GameServer.new)\n\n    # クライアント側\n    game = DRbObject.new_with_uri('druby://localhost:8787')\n    game.join(player_id)\n\n    このゲームを通してRubyの魅力を再発見し、分散オブジェクトプログラミングの可能性を一緒に体験しましょう！\n\n    https://regional.rubykaigi.org/kansai08/presentations/yumu\n\n- title: \"Rubyで世界を作ってみる話\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-28\"\n  video_provider: \"scheduled\"\n  video_id: \"akira-matsuda-kansai-rubykaigi-08\"\n  id: \"akira-matsuda-kansai-rubykaigi-08\"\n  language: \"japanese\"\n  description: |-\n    オブジェクト指向プログラミング(OOP)を初めて学んだ時、OOPなら全てを表現できる！と教わったものです。たとえば、動物という抽象クラスを継承した犬クラスと猫クラスがあって、どっちも`鳴く`メソッドを呼ぶとポリモーフィックに\"ワン\"とか\"ニャー\"とか鳴かせれるんですよ！みたいな？確かに世界は全てオブジェクトでできてる気がするし、それらのデータと振る舞いとしてうまいことモデリングすれば作れないものはない！……気がしてきます。\n    実際、リンネ先生があらゆる生物をツリー構造で分類してみたところ、この体系は数百年経っても破綻せずに使い続けられてるわけです。つまり、生物は全てRubyのclassで表現できますよね。真無盲腸目ハリネズミ科とネズミ目ヤマアラシ科の生物はツリー上では全く違うところに居るのにめちゃ似てるじゃん？っていう疑問も、平行進化の過程で獲得した「トゲトゲ」moduleをincludeしてやれば、ほらでき上がり！\n    なんか界隈では近年OOPオワコン説みたいなのが聞かれますが、みんな窮屈なフレームワークに縛られすぎて、あるいはお仕事の業務アプリがプログラミングの全てだと思い込んでしまって、Rubyの表現力を過小評価してませんか？そこで、今日は初心に帰って素直に世界の全てを実装し直してみようと思います。とりあえず出発点は、このへんから始めてみましょうか。\n\n    class Atom\n    end\n\n    https://regional.rubykaigi.org/kansai08/presentations/amatsuda\n\n- title: \"Panel: Regional.rb and the Kyoto City関西地域.rb\"\n  speakers:\n    - Kansai.rb Organizers\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-28\"\n  video_provider: \"scheduled\"\n  video_id: \"kansairb-kansai-rubykaigi-08\"\n  id: \"kansairb-kansai-rubykaigi-08\"\n  language: \"japanese\"\n  description: |-\n    関西の地域.rbのオーガナイザーが関西Ruby会議に集結！\n\n    https://regional.rubykaigi.org/kansai08/presentations/kansairb\n\n- title: \"Keynote: Rubyを使った10年の個人開発でやってきたこと\"\n  speakers:\n    - Koji Shimba\n  event_name: \"Kansai RubyKaigi 08\"\n  date: \"2025-06-28\"\n  video_provider: \"scheduled\"\n  video_id: \"koji-shimba-kansai-rubykaigi-08\"\n  id: \"koji-shimba-kansai-rubykaigi-08\"\n  language: \"japanese\"\n  description: |-\n    https://regional.rubykaigi.org/kansai08/presentations/shimbaco\n"
  },
  {
    "path": "data/kansai-rubykaigi/kansai-rubykaigi-09/cfp.yml",
    "content": "---\n- link: \"https://forms.gle/hRjJabKiLXH5DreZ8\"\n  open_date: \"2026-02-20\"\n  close_date: \"2026-05-10\"\n"
  },
  {
    "path": "data/kansai-rubykaigi/kansai-rubykaigi-09/event.yml",
    "content": "---\nid: \"kansai-rubykaigi-09\"\ntitle: \"Kansai RubyKaigi 09\"\ndescription: \"\"\nlocation: \"Otsu, Japan\"\nkind: \"conference\"\nstart_date: \"2026-07-18\"\nend_date: \"2026-07-18\"\nwebsite: \"https://regional.rubykaigi.org/kansai09/\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#041D4F\"\nbanner_background: \"#FFFFFF\"\ncoordinates:\n  latitude: 35.01446057375976\n  longitude: 135.85252085110668\naliases:\n  - 関西Ruby会議09\n"
  },
  {
    "path": "data/kansai-rubykaigi/kansai-rubykaigi-09/involvements.yml",
    "content": "---\n- name: \"Chief Organizer\"\n  users:\n    - Yudai Takada\n\n- name: \"Organizer\"\n  users:\n    - ogomr\n    - luccafort\n    - Takafumi ONAKA\n    - smantani\n    - spring_kuma\n    - murajun1978\n    - uproad3\n    - Pasta-K\n    - youcune\n    - honeniq\n    - Kazuhiro NISHIYAMA\n    - haruguchi\n    - khori\n    - k-yoshida\n    - nishi_okashi\n    - 107steps\n    - momoonga\n    - sanfrecce_osaka\n    - KOSAKI Motohiro\n\n- name: \"Designer\"\n  users:\n    - reina\n    - Momoka\n    - Yudai Takada\n\n- name: \"NOC\"\n  users:\n    - uproad3\n    - murajun1978\n\n- name: \"Support\"\n  organisations:\n    - Nihon Ruby no Kai\n"
  },
  {
    "path": "data/kansai-rubykaigi/kansai-rubykaigi-09/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://regional.rubykaigi.org/kansai09/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/kansai-rubykaigi/series.yml",
    "content": "---\nname: \"Kansai RubyKaigi\"\ntwitter: \"rubykansai\"\nwebsite: \"https://regional.rubykaigi.org/kansai09/\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\nyoutube_channel_id: \"\"\naliases:\n  - \"関西Ruby会議\"\n"
  },
  {
    "path": "data/kashiwarb/kashiwarb-meetup/event.yml",
    "content": "---\nid: \"kashiwarb-meetup\"\ntitle: \"Kashiwa.rb Meetup\"\nlocation: \"Kashiwa, Japan\"\ndescription: |-\n  A Ruby technology community in the Kashiwa area where developers gather casually. The group meets approximately monthly at Palette Kashiwa, near JR Kashiwa Station. Everyone from programming beginners to experienced Ruby engineers is welcome for collaborative learning through various event formats including Lightning Talks, silent coding sessions, and open space technology sessions.\nwebsite: \"https://kashiwarb.connpass.com\"\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 35.8675958\n  longitude: 139.9757575\n"
  },
  {
    "path": "data/kashiwarb/kashiwarb-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/kashiwarb/series.yml",
    "content": "---\nname: \"Kashiwa.rb\"\nwebsite: \"https://kashiwarb.connpass.com\"\ntwitter: \"kashiwarb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/keeprubyweird/keep-ruby-weird-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZN30T1pcmNeO_hvCgYhnXY\"\ntitle: \"Keep Ruby Weird 2014\"\ndescription: \"\"\nlocation: \"Austin, TX, United States\"\nkind: \"conference\"\nstart_date: \"2014-10-24\"\nend_date: \"2014-10-24\"\npublished_at: \"2014-12-02\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2014\nwebsite: \"http://keeprubyweird.com/\"\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/keeprubyweird/keep-ruby-weird-2014/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"jeremy-flores-keep-ruby-weird-2014\"\n  title: \"Ten Years of Ruby Conferences: A Dramatic Revue\"\n  raw_title: \"Keep Ruby Weird 2014 - Ten Years of Ruby Conferences: A Dramatic Revue\"\n  speakers:\n    - Jeremy Flores\n  event_name: \"Keep Ruby Weird 2014\"\n  date: \"2014-12-08\"\n  published_at: \"2014-12-08\"\n  description: |-\n    By, Jeremy Flores, Carol Nichols and Brenna Flood\n\n    Many incredible people have given many amazing talks at Ruby or Rails conferences over the years, and we’d like to take a look back at some of the best. From _why the Lucky Stiff\n    to Sandi Metz, from Matz to DHH, from Tenderlove to Jim Weirich, we will be giving\n    you a whirlwind tour through the conference ages. You’ll learn where those important\n    ideas you take for granted got their start. You’ll laugh and you’ll cry as you\n    experience how the Ruby Community has grown over the years and how we’ve connected\n    through our shared conference experiences. Rain ponchos recommended for the front\n    row. This talk features creations by Brenna Flood.\n  video_provider: \"youtube\"\n  video_id: \"uQROQBbdeng\"\n\n- id: \"nickolas-means-keep-ruby-weird-2014\"\n  title: \"How to Code Like a Writer\"\n  raw_title: \"Keep Ruby Weird 2014 - How to Code Like a Writer\"\n  speakers:\n    - Nickolas Means\n  event_name: \"Keep Ruby Weird 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-02\"\n  description: |-\n    By, Nickolas Means\n    As developers, we spend more of our time writing than we do thinking about the nuances of computer science. What would happen if we approached code like a writing exercise instead of a technical pursuit? What if we applied patterns from elegant prose instead of Gang of Four? Let's try it!\n\n    We'll take some smelly Ruby and refactor it using only advice from Strunk and White's \"The Elements of Style\", the canonical text on writing beautiful, understandable English. You'll come away with a new approach to your craft and a new appreciation of the similarities between great writing and great code.\n\n  video_provider: \"youtube\"\n  video_id: \"uHASWCPMZ3k\"\n\n- id: \"coraline-ehmke-keep-ruby-weird-2014\"\n  title: \"He Doesn't Work Here Anymore\"\n  raw_title: \"Keep Ruby Weird 2014 - He Doesn't Work Here Anymore\"\n  speakers:\n    - Coraline Ehmke\n  event_name: \"Keep Ruby Weird 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-02\"\n  description: |-\n    By, Coraline Ehmke\n    What happens when a highly visible and successful developer announces to the world that they plan to transition from male to female?\n\n    In August of 2013 I stood with friends on the stage at a Ruby conference and told the world that I am transgender. I began the long process of my personal, social, professional, and physical transition from male to female.\n\n    I would like to share the lessons I'm learning, the perspective I'm gaining, and the inspiration I'm finding through the experience of living and working in two genders. How is this change impacting my career as a developer? Interactions with my peers? My relationship with the development community? Is it influencing how I create and appreciate code? My hope is to spark conversations and create opportunities for shared learning and growth by exploring the intersection of gender and technology.\n\n  video_provider: \"youtube\"\n  video_id: \"pnnFJiQsp8k\"\n\n- id: \"joanne-cheng-keep-ruby-weird-2014\"\n  title: \"Computer Art at Bell Labs\"\n  raw_title: \"Keep Ruby Weird 2014 - Computer Art at Bell Labs\"\n  speakers:\n    - Joanne Cheng\n  event_name: \"Keep Ruby Weird 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-05\"\n  description: |-\n    By, Joanne Cheng\n    During the 1960's, computer scientists at Bell Labs in Murray Hill, NJ explored the limits of computers through art and music. Some worked by themselves to discover push the boundaries of computer animation, others brought in visual artists and composers to collaborate on art experiments on Bell Lab's equipment after the work day.\n\n    In this talk, I'll talk about some of the experiments of computer scientists and artists during this time. We'll look at their influence on how we use computers today, and why we should embrace the spirit of experimentation and collaboration.\n\n  video_provider: \"youtube\"\n  video_id: \"TcHfJmN2rdo\"\n\n- id: \"brenna-flood-keep-ruby-weird-2014\"\n  title: \"Ten Years of Ruby Conferences: A Dramatic Revue\"\n  raw_title: \"Keep Ruby Weird 2014 - Ten Years of Ruby Conferences: A Dramatic Revue\"\n  speakers:\n    - Brenna Flood\n  event_name: \"Keep Ruby Weird 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-05\"\n  description: |-\n    Many incredible people have given many amazing talks at Ruby or Rails conferences over the years, and we’d like to take a look back at some of the best. From _why the Lucky Stiff to Sandi Metz, from Matz to DHH, from Tenderlove to Jim Weirich, we will be giving you a whirlwind tour through the conference ages. You’ll learn where those important ideas you take for granted got their start. You’ll laugh and you’ll cry as you experience how the Ruby Community has grown over the years and how we’ve connected through our shared conference experiences. Rain ponchos recommended for the front row. This talk features creations by Brenna Flood.\n\n  video_provider: \"youtube\"\n  video_id: \"wxswPdwI0DU\"\n\n- id: \"aaron-patterson-keep-ruby-weird-2014\"\n  title: \"Opening Keynote: Keep Ruby Weird\"\n  raw_title: \"Keep Ruby Weird 2014 - Opening Keynote\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Keep Ruby Weird 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-06\"\n  description: |-\n    By, Aaron Patterson\n\n  video_provider: \"youtube\"\n  video_id: \"9N31ay425GI\"\n\n- id: \"paul-battley-keep-ruby-weird-2014\"\n  title: \"What's That Supposed to Mean\"\n  raw_title: \"Keep Ruby Weird 2014 - What's That Supposed to Mean\"\n  speakers:\n    - Paul Battley\n  event_name: \"Keep Ruby Weird 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-05\"\n  description: |-\n    By, Paul Battley\n    Have you ever cursed at the symbols on a washing machine, puzzled at the pictorial navigation of a website, or panicked at that inscrutable symbol on the car dashboard that's flashing red? I have. Especially the last one. (I eventually discovered that I'd been driving with the parking brake on.)\n\n    All this has happened before, and all this will happen again. (Except for me driving with the parking brake on.) Throughout history, humanity has faced the challenge of putting complex and abstract concepts onto paper or clay or rock or skin or whatever. It usually starts out in the same way, but the end results have been very varied: We've ended up with alphabets, abjads, abugidas, logograms and syllabaries. Oh, and the symbols on modern industrial devices.\n\n    I'll describe the history of some of the more interesting writing systems and explain how Chinese works, that Japanese can be really hard, and why you should be really glad you're not an Akkadian. I hope that it will be enlightening and fascinating, but I also hope that it will help to inform the way that people approach pictorial communication in the future. I also hope that it will go some way towards explaining why there are so many hamburger menus, and inspire people to do better.\n\n  video_provider: \"youtube\"\n  video_id: \"bVCtNKJ3Xzs\"\n\n- id: \"jonan-schefler-keep-ruby-weird-2014\"\n  title: \"Ruby Monsters Go Bump in the Night\"\n  raw_title: \"Keep Ruby Weird 2014 - Ruby Monsters Go Bump in the Night\"\n  speakers:\n    - Jonan Schefler\n  event_name: \"Keep Ruby Weird 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-02\"\n  description: |-\n    By, Jonan Schefler\n    An exploration of the forgotten and dusty corners of Ruby, including a tour of some very unusual behaviors from threads, loops, exceptions and procs. This is a technical deep dive into some obscure features of Ruby that may someday crawl out from under your bed, and when they do you'll be glad you were prepared for the fight.\n\n  video_provider: \"youtube\"\n  video_id: \"TV74K_e_wrw\"\n\n- id: \"russ-olsen-keep-ruby-weird-2014\"\n  title: \"Closing Keynote: To The Moon\"\n  raw_title: \"Keep Ruby Weird 2014 - Closing Keynote\"\n  speakers:\n    - Russ Olsen\n  event_name: \"Keep Ruby Weird 2014\"\n  date: \"2014-12-02\"\n  published_at: \"2014-12-02\"\n  description: |-\n    By, Russ Olsen\n\n  video_provider: \"youtube\"\n  video_id: \"50ExWDcim5I\"\n"
  },
  {
    "path": "data/keeprubyweird/keep-ruby-weird-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybMGuZ9QIjkXulQE8ddcVx0\"\ntitle: \"Keep Ruby Weird 2015\"\nlocation: \"Austin, TX, United States\"\nkind: \"conference\"\nstart_date: \"2015-10-23\"\nend_date: \"2015-10-23\"\ndescription: \"\"\npublished_at: \"2015-11-02\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\nwebsite: \"http://keeprubyweird.com\"\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/keeprubyweird/keep-ruby-weird-2015/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"patrick-mckenzie-keep-ruby-weird-2015\"\n  title: \"Kill Your Inner Code Monkey\"\n  raw_title: \"t9 KRW 2015 -Kill Your Inner Code Monkey by Patrick McKenzie\"\n  speakers:\n    - Patrick McKenzie\n  event_name: \"Keep Ruby Weird 2015\"\n  date: \"2015-11-02\"\n  published_at: \"2015-11-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"X6qlDJBz55s\"\n\n- id: \"ernie-miller-keep-ruby-weird-2015\"\n  title: \"Choices\"\n  raw_title: \"KRW 2015 - Choices by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"Keep Ruby Weird 2015\"\n  date: \"2015-11-02\"\n  published_at: \"2015-11-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"_5D0rBIEsZc\"\n\n- id: \"will-leinweber-keep-ruby-weird-2015\"\n  title: \"A Collection of Fun with Ruby and Friends\"\n  raw_title: \"KRW 2015 - A Collection of Fun with Ruby and Friends by Will Leinweber\"\n  speakers:\n    - Will Leinweber\n  event_name: \"Keep Ruby Weird 2015\"\n  date: \"2015-11-02\"\n  published_at: \"2015-11-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Jcto0Bs1hIA\"\n\n- id: \"brandon-hays-keep-ruby-weird-2015\"\n  title: \"Your Career vs. the 4th Dimension: A Time Travel Story\"\n  raw_title: \"KRW 2015 - Your Career vs. the 4th Dimension: A Time Travel Story by Brandon Hays\"\n  speakers:\n    - Brandon Hays\n  event_name: \"Keep Ruby Weird 2015\"\n  date: \"2015-11-02\"\n  published_at: \"2015-11-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"UVbebpjzrHI\"\n\n- id: \"kerri-miller-keep-ruby-weird-2015\"\n  title: '\"Did you know the site is down?\": 20 Years of Mistakes, Failures, and Fuck-Ups'\n  raw_title: 'KRW 2015 - \"Did you know the site is down?\": 20 Years of Mistakes, Failures, and Fuck-Ups'\n  speakers:\n    - Kerri Miller\n  event_name: \"Keep Ruby Weird 2015\"\n  date: \"2015-11-02\"\n  published_at: \"2015-11-02\"\n  description: |-\n    By Kerri Miller\n\n  video_provider: \"youtube\"\n  video_id: \"lbpflcOVCFY\"\n\n- id: \"goose-mongeau-keep-ruby-weird-2015\"\n  title: \"At the Mountains of Madness: A Primer on Writing\"\n  raw_title: \"KRW 2015 -At the Mountains of Madness: A primer on Writing by Goose Mongeau\"\n  speakers:\n    - Goose Mongeau\n  event_name: \"Keep Ruby Weird 2015\"\n  date: \"2015-11-02\"\n  published_at: \"2015-11-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"viUeQQvDX4U\"\n\n- id: \"marcus-j-carey-keep-ruby-weird-2015\"\n  title: \"See Hacker Hack\"\n  raw_title: \"KRW 2015 - See Hacker Hack by Marcus J. Carey\"\n  speakers:\n    - Marcus J. Carey\n  event_name: \"Keep Ruby Weird 2015\"\n  date: \"2015-11-02\"\n  published_at: \"2015-11-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"tAk0jfkQDsM\"\n\n- id: \"sandi-metz-keep-ruby-weird-2015\"\n  title: \"Keynote: Authority, Conformity, Community\"\n  raw_title: \"KRW 2015 - Keynote by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"Keep Ruby Weird 2015\"\n  date: \"2015-11-02\"\n  published_at: \"2015-11-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"skG09s9S3Fc\"\n\n- id: \"christophe-philemotte-keep-ruby-weird-2015\"\n  title: \"Prepare yourself against the Zombie epidemic\"\n  raw_title: \"KRW 2015 -Prepare yourself against the Zombie epidemic by Christophe Philemotte\"\n  speakers:\n    - Christophe Philemotte\n  event_name: \"Keep Ruby Weird 2015\"\n  date: \"2015-11-02\"\n  published_at: \"2015-11-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ZCfoVQ5_WPE\"\n"
  },
  {
    "path": "data/keeprubyweird/keep-ruby-weird-2016/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyarDeXmyB9caus1O_g7YiJI\"\ntitle: \"Keep Ruby Weird 2016\"\ndescription: \"\"\nlocation: \"Austin, TX, United States\"\nkind: \"conference\"\nstart_date: \"2016-10-28\"\nend_date: \"2016-10-28\"\npublished_at: \"2016-11-04\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2016\nwebsite: \"https://2016.keeprubyweird.com/\"\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/keeprubyweird/keep-ruby-weird-2016/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"katrina-owen-keep-ruby-weird-2016\"\n  title: \"Keynote: Cultivating Instinct by Katrina Owen\"\n  raw_title: \"Keep Ruby Weird 2016 - Keynote: Cultivating Instinct by Katrina Owen\"\n  speakers:\n    - Katrina Owen\n  event_name: \"Keep Ruby Weird 2016\"\n  date: \"2016-11-04\"\n  published_at: \"2016-11-04\"\n  description: |-\n    Keynote: Cultivating Instinct by Katrina Owen\n  video_provider: \"youtube\"\n  video_id: \"SKlIQLb7U00\"\n\n- id: \"thomas-e-enebo-keep-ruby-weird-2016\"\n  title: \"Implementing An Esoteric Programming\"\n  raw_title: \"Keep Ruby Weird 2016 - Implementing An Esoteric Programming by Thomas E Enebo\"\n  speakers:\n    - Thomas E Enebo\n  event_name: \"Keep Ruby Weird 2016\"\n  date: \"2016-11-04\"\n  published_at: \"2016-11-04\"\n  description: |-\n    Implementing An Esoteric Programming by Tom Enebo\n  video_provider: \"youtube\"\n  video_id: \"uKGecSc-r1o\"\n\n- id: \"kylie-stradley-keep-ruby-weird-2016\"\n  title: \"A Practical Taxonomy of Bugs\"\n  raw_title: \"Keep Ruby Weird 2016 - A Practical Taxonomy of Bugs by Kylie Stradley\"\n  speakers:\n    - Kylie Stradley\n  event_name: \"Keep Ruby Weird 2016\"\n  date: \"2016-11-04\"\n  published_at: \"2016-11-04\"\n  description: |-\n    A Practical Taxonomy of Bugs by Kylie Stradley\n  video_provider: \"youtube\"\n  video_id: \"mE49u3hK2js\"\n\n- id: \"craig-kerstiens-keep-ruby-weird-2016\"\n  title: \"A Hands-on Experience with Complex SQL\"\n  raw_title: \"Keep Ruby Weird 2016 - A Hands-on Experience with Complex SQL by Craig Kerstiens\"\n  speakers:\n    - Craig Kerstiens\n  event_name: \"Keep Ruby Weird 2016\"\n  date: \"2016-11-04\"\n  published_at: \"2016-11-04\"\n  description: |-\n    A Hands-on Experience with Complex SQL by Craig Kerstiens\n  video_provider: \"youtube\"\n  video_id: \"0koLFAB4lAk\"\n\n- id: \"justin-searls-keep-ruby-weird-2016\"\n  title: \"Hot Takes Welcome: @searls\"\n  raw_title: \"Keep Ruby Weird 2016 - Hot takes welcome: @Searls  by Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"Keep Ruby Weird 2016\"\n  date: \"2016-11-04\"\n  published_at: \"2016-11-04\"\n  description: |-\n    Hot takes welcome: @Searls  by Justin Searls\n  video_provider: \"youtube\"\n  video_id: \"JueNkCiQYcc\"\n\n- id: \"marty-haught-keep-ruby-weird-2016\"\n  title: \"Make Better Decisions\"\n  raw_title: \"Keep Ruby Weird 2016 - Make Better Decisions by Marty Haught\"\n  speakers:\n    - Marty Haught\n  event_name: \"Keep Ruby Weird 2016\"\n  date: \"2016-11-04\"\n  published_at: \"2016-11-04\"\n  description: |-\n    Make Better Decisions by Marty Haught\n  video_provider: \"youtube\"\n  video_id: \"ZtqUdoqK5RM\"\n\n- id: \"nick-means-keep-ruby-weird-2016\"\n  title: \"Keynote: The Building Built on Stilts\"\n  raw_title: \"Keep Ruby Weird 2016 - Keynote: The Building Built on Stilts by Nick Means\"\n  speakers:\n    - Nick Means\n  event_name: \"Keep Ruby Weird 2016\"\n  date: \"2016-11-04\"\n  published_at: \"2016-11-04\"\n  description: |-\n    Keynote: The Building Built on Stilts by Nick Means\n  video_provider: \"youtube\"\n  video_id: \"_x1_ii16s-s\"\n"
  },
  {
    "path": "data/keeprubyweird/keep-ruby-weird-2017/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyb-ZR4SwWQ8Vu3PZxwpFHbG\"\ntitle: \"Keep Ruby Weird 2017\"\ndescription: \"\"\nlocation: \"Austin, TX, United States\"\nkind: \"conference\"\nstart_date: \"2017-10-01\"\nend_date: \"2017-10-01\"\npublished_at: \"2017-11-03\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2017\nwebsite: \"https://2017.keeprubyweird.com/\"\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/keeprubyweird/keep-ruby-weird-2017/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"yehuda-katz-keep-ruby-weird-2017\"\n  title: \"The Feedback Loop: Growing healthy open source projects\"\n  raw_title: \"Keep Ruby Weird 2017- The Feedback Loop... by Yehuda Katz & Dave Herman\"\n  speakers:\n    - Yehuda Katz\n    - Dave Herman\n  event_name: \"Keep Ruby Weird 2017\"\n  date: \"2017-11-03\"\n  published_at: \"2017-11-03\"\n  description: |-\n    Keep Ruby Weird 2017- The Feedback Loop: Growing healthy open source projects by Yehuda Katz & Dave Herman\n  video_provider: \"youtube\"\n  video_id: \"YrlsXq8gZdM\"\n\n- id: \"chris-arcand-keep-ruby-weird-2017\"\n  title: \"An Atypical 'Performance' Talk\"\n  raw_title: \"Keep Ruby Weird 2017- An Atypical 'Performance' Talk by Chris Arcand\"\n  speakers:\n    - Chris Arcand\n  event_name: \"Keep Ruby Weird 2017\"\n  date: \"2017-11-03\"\n  published_at: \"2017-11-03\"\n  description: |-\n    Keep Ruby Weird 2017- An Atypical 'Performance' Talk by Chris Arcand\n  video_provider: \"youtube\"\n  video_id: \"s_Yg1nxd2Lk\"\n\n- id: \"rolen-le-keep-ruby-weird-2017\"\n  title: \"Dungeons & Collaboration: A Player's Handbook on How To Work With a Distributed Team\"\n  raw_title: \"Keep Ruby Weird 2017- Dungeons & Collaboration... by Rolen Le\"\n  speakers:\n    - Rolen Le\n  event_name: \"Keep Ruby Weird 2017\"\n  date: \"2017-11-03\"\n  published_at: \"2017-11-03\"\n  description: |-\n    Keep Ruby Weird 2017- Dungeons & Collaboration: A Player’s Handbook on How To Work With a Distributed Team by Rolen Le\n  video_provider: \"youtube\"\n  video_id: \"3NMY0TfT87s\"\n\n- id: \"ben-scofield-keep-ruby-weird-2017\"\n  title: \"Learning To See\"\n  raw_title: \"Keep Ruby Weird 2017- Learning to see by Ben Scofield\"\n  speakers:\n    - Ben Scofield\n  event_name: \"Keep Ruby Weird 2017\"\n  date: \"2017-11-03\"\n  published_at: \"2017-11-03\"\n  description: |-\n    Keep Ruby Weird 2017- Learning to see by Ben Scofield\n  video_provider: \"youtube\"\n  video_id: \"d4NRZLVlRfw\"\n\n- id: \"bradley-grzesiak-keep-ruby-weird-2017\"\n  title: \"kerbal_space_program.rb\"\n  raw_title: \"Keep Ruby Weird 2017- kerbal_space_program.rb by Bradley Grzesiak\"\n  speakers:\n    - Bradley Grzesiak\n  event_name: \"Keep Ruby Weird 2017\"\n  date: \"2017-11-03\"\n  published_at: \"2017-11-03\"\n  description: |-\n    Keep Ruby Weird 2017- kerbal_space_program.rb by Bradley Grzesiak\n  video_provider: \"youtube\"\n  video_id: \"GuuACTd14uc\"\n\n- id: \"cecy-correa-keep-ruby-weird-2017\"\n  title: \"The Psychology of Fake News (and What Tech Can Do About It)\"\n  raw_title: \"Keep Ruby Weird 2017- The Psychology of Fake News (and What Tech Can Do About It) by Cecy Correa\"\n  speakers:\n    - Cecy Correa\n  event_name: \"Keep Ruby Weird 2017\"\n  date: \"2017-11-03\"\n  published_at: \"2017-11-03\"\n  description: |-\n    Keep Ruby Weird 2017- The Psychology of Fake News (and What Tech Can Do About It) by Cecy Correa\n  video_provider: \"youtube\"\n  video_id: \"FwR4JX6ulMw\"\n\n- id: \"lightning-talks-keep-ruby-weird-2017\"\n  title: \"Lightning Talks\"\n  raw_title: \"Keep Ruby Weird 2017- Lightning Talks by Various Speakers\"\n  event_name: \"Keep Ruby Weird 2017\"\n  date: \"2017-11-03\"\n  published_at: \"2017-11-03\"\n  description: |-\n    Keep Ruby Weird 2017- Lightning Talks by Various Speakers\n  video_provider: \"youtube\"\n  video_id: \"IbYKU8OpPVk\"\n  talks:\n    - title: \"Lightning Talk: Amanda Chang\"\n      start_cue: \"00:00\"\n      end_cue: \"07:22\"\n      id: \"amanda-chang-lighting-talk-keep-ruby-weird-2017\"\n      video_id: \"amanda-chang-lighting-talk-keep-ruby-weird-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Amanda Chang\n\n    - title: \"Lightning Talk: Dave Rupert\"\n      start_cue: \"07:22\"\n      end_cue: \"12:46\"\n      id: \"dave-rupert-lighting-talk-keep-ruby-weird-2017\"\n      video_id: \"dave-rupert-lighting-talk-keep-ruby-weird-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Dave Rupert\n\n    - title: \"Lightning Talk: Jordan Reuter\"\n      start_cue: \"12:46\"\n      end_cue: \"20:45\"\n      id: \"jordan-reuter-lighting-talk-keep-ruby-weird-2017\"\n      video_id: \"jordan-reuter-lighting-talk-keep-ruby-weird-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jordan Reuter\n\n    - title: \"Lightning Talk: Nickolas Means\"\n      start_cue: \"20:45\"\n      end_cue: \"30:06\"\n      id: \"nickolas-means-lighting-talk-keep-ruby-weird-2017\"\n      video_id: \"nickolas-means-lighting-talk-keep-ruby-weird-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Nickolas Means\n\n- id: \"elle-meredith-keep-ruby-weird-2017\"\n  title: \"Algorithms to live by and why should we care\"\n  raw_title: \"Keep Ruby Weird 2017- Algorithms to live by and why should we care by Elle Meredith\"\n  speakers:\n    - Elle Meredith\n  event_name: \"Keep Ruby Weird 2017\"\n  date: \"2017-11-03\"\n  published_at: \"2017-11-03\"\n  description: |-\n    Keep Ruby Weird 2017- Algorithms to live by and why should we care by Elle Meredith\n  video_provider: \"youtube\"\n  video_id: \"LCH2re51p7g\"\n"
  },
  {
    "path": "data/keeprubyweird/keep-ruby-weird-2018/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaxIbXihF5bRdMumqVtGrT4\"\ntitle: \"Keep Ruby Weird 2018\"\ndescription: \"\"\nlocation: \"Austin, TX, United States\"\nkind: \"conference\"\nstart_date: \"2018-11-09\"\nend_date: \"2018-11-09\"\npublished_at: \"2018-11-28\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2018\nwebsite: \"https://2018.keeprubyweird.com\"\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/keeprubyweird/keep-ruby-weird-2018/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"yukihiro-matz-matsumoto-keep-ruby-weird-2018\"\n  title: \"Keynote: Keep Ruby Weird\"\n  raw_title: \"Keep Ruby Weird 2018 - Keynote by Yukihiro Matsumoto 'Matz'\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Keep Ruby Weird 2018\"\n  date: \"2018-11-28\"\n  published_at: \"2018-11-28\"\n  description: |-\n    Keep Ruby Weird 2018 - Keynote by Yukihiro Matsumoto 'Matz'\n  video_provider: \"youtube\"\n  video_id: \"wDrmvmhABcg\"\n\n- id: \"nathan-ladd-keep-ruby-weird-2018\"\n  title: \"Distributed Fizz Buzz: Passing the Microservices Interview\"\n  raw_title: \"Keep Ruby Weird 2018 - Distributed Fizz Buzz... by Nathan Ladd & Scott Bellware\"\n  speakers:\n    - Nathan Ladd\n    - Scott Bellware\n  event_name: \"Keep Ruby Weird 2018\"\n  date: \"2018-11-28\"\n  published_at: \"2018-11-28\"\n  description: |-\n    Keep Ruby Weird 2018 - Distributed Fizz Buzz: Passing the Microservices Interview by Nathan Ladd & Scott Bellware\n\n    Scott Bellware is a short, bald man with 25 years of experience who works with development teams who have completely screwed themselves into an intractable mess of tightly-coupled monolithic madness by paying attention to cute people rather than smart people. Scott is a contributor to the Eventide toolkit for event-sourced, autonomous services in Ruby, but Scott does it better than Nathan, and he’s totally not bitter.\n  video_provider: \"youtube\"\n  video_id: \"B9HlY1SsBA0\"\n\n- id: \"louisa-barrett-keep-ruby-weird-2018\"\n  title: \"The Teenage Mutant Ninja Turtles Guide to Color Theory\"\n  raw_title: \"Keep Ruby Weird 2018 - The Teenage Mutant Ninja Turtles Guide to Color Theory by Louisa Barrett\"\n  speakers:\n    - Louisa Barrett\n  event_name: \"Keep Ruby Weird 2018\"\n  date: \"2018-11-28\"\n  published_at: \"2018-11-28\"\n  description: |-\n    Keep Ruby Weird 2018 - The Teenage Mutant Ninja Turtles Guide to Color Theory by Louisa Barrett\n\n    Louisa is the Director of the Front-End Engineering program at the Turing School of Software and Design. She is the former director of Colorado for Women Who Code and past chapter leader for Girl Develop It Denver/Boulder. She began her career as an illustrator/graphic designer, and a passion for understanding people lead her to programming. She has a soft spot for UX, typography, and correcting students when they refer to an assignment operator as an ‘equals sign’.\n  video_provider: \"youtube\"\n  video_id: \"Sq7RIQGzGNE\"\n\n- id: \"godfrey-chan-keep-ruby-weird-2018\"\n  title: \"Game Show\"\n  raw_title: \"Keep Ruby Weird 2018 - Game Show\"\n  speakers:\n    - Godfrey Chan\n    - Yukihiro \"Matz\" Matsumoto\n    - Kylie Stradley\n    - Matthew Draper\n  event_name: \"Keep Ruby Weird 2018\"\n  date: \"2018-11-28\"\n  published_at: \"2018-11-28\"\n  description: |-\n    Keep Ruby Weird 2018 - Game Show\n  video_provider: \"youtube\"\n  video_id: \"lLHG0Nxutbw\"\n\n- id: \"will-leinweber-keep-ruby-weird-2018\"\n  title: \"Using psql to \\\\watch Star Wars and other silly things!\"\n  raw_title: \"Keep Ruby Weird 2018 - Using psql to \\\\watch Star Wars And other silly things! by Will Leinweber\"\n  speakers:\n    - Will Leinweber\n  event_name: \"Keep Ruby Weird 2018\"\n  date: \"2018-11-28\"\n  published_at: \"2018-11-28\"\n  description: |-\n    Keep Ruby Weird 2018 - Using psql to \\watch Star Wars And other silly things! by Will Leinweber\n\n    Will doesn’t really want to think about how long he’s been working with Postgres. He is currently working on horizontally scalable Postgres at Citus Data, and before that was a principal member of the Heroku Postgres team. Please don’t try to right-click and steal the source for his WebSite bitfission.com.\n  video_provider: \"youtube\"\n  video_id: \"v32XHJxljKI\"\n\n- id: \"beth-haubert-keep-ruby-weird-2018\"\n  title: \"Cats, The Musical! Algorithmic Song Meow-ification\"\n  raw_title: \"Keep Ruby Weird 2018 - Cats, The Musical! Algorithmic Song Meow-ification by Beth Haubert\"\n  speakers:\n    - Beth Haubert\n  event_name: \"Keep Ruby Weird 2018\"\n  date: \"2018-11-28\"\n  published_at: \"2018-11-28\"\n  description: |-\n    Keep Ruby Weird 2018 - Cats, The Musical! Algorithmic Song Meow-ification by Beth Haubert\n\n    Beth is a software engineer at Flywheel, a web infrastructure startup in Omaha, Nebraska. She’s also a former airborne cryptologic linguist for the US Air Force, fluent in Mandarin. Things you can ask her about include Ruby, cats, board games, BSG, karaoke, and building applications that convert songs into auto-tuned cat meows. Things she’ll have to kill you if you ask her about: the airborne linguist part. Also, she likes to make emojis look like they’re farting.\n  video_provider: \"youtube\"\n  video_id: \"67OuTeRHmu4\"\n\n- id: \"andrew-louis-keep-ruby-weird-2018\"\n  title: \"Using Ruby To Build A Modern Memex!\"\n  raw_title: \"Keep Ruby Weird 2018 - Using Ruby to build a modern Memex! by Andrew Louis\"\n  speakers:\n    - Andrew Louis\n  event_name: \"Keep Ruby Weird 2018\"\n  date: \"2018-11-28\"\n  published_at: \"2018-11-28\"\n  description: |-\n    Keep Ruby Weird 2018 - Using Ruby to build a modern Memex! by Andrew Louis\n\n    Andrew is a software developer based in Toronto. He’s currently working on building a digital Memex as well as researching the history of similar projects. Previously, he was the co-founder and CTO of ShopLocket, an ecommerce startup acquired in 2014. When he’s not coding, he spends his time on obsessive projects such as attempting to bike on every street in Toronto, taking photos of only doors (instagram: @hyfen), and making voxel art.\n  video_provider: \"youtube\"\n  video_id: \"NTG5UMSQR8E\"\n\n- id: \"yusuke-endoh-keep-ruby-weird-2018\"\n  title: \"Transcendental Programming in Ruby\"\n  raw_title: \"Keep Ruby Weird 2018 - Transcendental Programming in Ruby by Yusuke Endoh\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"Keep Ruby Weird 2018\"\n  date: \"2018-11-28\"\n  published_at: \"2018-11-28\"\n  description: |-\n    Keep Ruby Weird 2018 - Transcendental Programming in Ruby by Yusuke Endoh\n\n    'A MRI committer at Cookpad Inc. He is an advocate of \"transcendental programming\" that creates a useless program like this bio (^_^)'.sub(?^){eval$_=%q{puts\"'#$`^_#$''.sub(?^){eval$_=%q{#$_}}\"}}\n  video_provider: \"youtube\"\n  video_id: \"IgF75PjxHHA\"\n\n- id: \"avdi-grimm-keep-ruby-weird-2018\"\n  title: \"Closing Keynote: OOPS\"\n  raw_title: \"Keep Ruby Weird 2018 - Closing Keynote by Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"Keep Ruby Weird 2018\"\n  date: \"2018-11-28\"\n  published_at: \"2018-11-28\"\n  description: |-\n    Keep Ruby Weird 2018 - Closing Keynote by Avdi Grimm\n\n    Avdi Grimm is a father, a Ruby Hero, the head chef at RubyTapas.com, and author of the books Confident Ruby and Exceptional Ruby. He splits his theoretical spare time between hiking the Smoky Mountains and dancing to oontz-oontz music.\n  video_provider: \"youtube\"\n  video_id: \"UJnsXUVsr7w\"\n"
  },
  {
    "path": "data/keeprubyweird/series.yml",
    "content": "---\nname: \"Keep Ruby Weird\"\nwebsite: \"https://keeprubyweird.com\"\ntwitter: \"keeprubyweird\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Keep Ruby Weird\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/kiwi-ruby/kiwi-ruby-2017/event.yml",
    "content": "---\nid: \"PLqR1aFtg6FQKivt1jMU-dotStXiTY11GT\"\ntitle: \"Kiwi Ruby 2017\"\ndescription: \"\"\nlocation: \"Wellington, New Zealand\"\nkind: \"conference\"\nstart_date: \"2017-11-02\"\nend_date: \"2017-11-03\"\nwebsite: \"http://kiwi.ruby.nz\"\ntwitter: \"kiwirubyconf\"\nplaylist: \"https://www.youtube.com/playlist?list=PLqR1aFtg6FQKivt1jMU-dotStXiTY11GT\"\ncoordinates:\n  latitude: -41.2923814\n  longitude: 174.7787463\n"
  },
  {
    "path": "data/kiwi-ruby/kiwi-ruby-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://kiwi.ruby.nz\n# Videos: https://www.youtube.com/playlist?list=PLqR1aFtg6FQKivt1jMU-dotStXiTY11GT\n---\n[]\n"
  },
  {
    "path": "data/kiwi-ruby/kiwi-ruby-2019/event.yml",
    "content": "---\nid: \"kiwi-ruby-2019\"\ntitle: \"Kiwi Ruby 2019\"\ndescription: \"\"\nlocation: \"Wellington, New Zealand\"\nkind: \"conference\"\nstart_date: \"2019-11-01\"\nend_date: \"2019-11-01\"\nwebsite: \"https://kiwi.ruby.nz\"\ntwitter: \"kiwirubyconf\"\ncoordinates:\n  latitude: -41.2904563\n  longitude: 174.7820894\n"
  },
  {
    "path": "data/kiwi-ruby/kiwi-ruby-2019/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Moa Sponsor\"\n      description: |-\n        Moa sponsor tier includes Buildkite, who provide lightning fast testing and delivery for software projects via a platform for running fast, secure, and scalable continuous integration pipelines on your own infrastructure.\n      level: 1\n      sponsors:\n        - name: \"Buildkite\"\n          website: \"https://buildkite.com/\"\n          slug: \"Buildkite\"\n          logo_url: \"https://kiwi.ruby.nz/img/sponsors/buildkite-logo-small.png\"\n\n    - name: \"Kiwi Sponsors\"\n      description: |-\n        Kiwi sponsors include Loyalty NZ, known for the Fly Buys programme, helping businesses know more about their customers, and Trineo, building world-class app ecosystems on Heroku, focusing on people and planet.\n      level: 2\n      sponsors:\n        - name: \"Loyalty NZ\"\n          website: \"https://www.loyalty.co.nz\"\n          slug: \"LoyaltyNZ\"\n          logo_url: \"https://kiwi.ruby.nz/img/sponsors/loyalty-nz-logo.png\"\n\n        - name: \"Trineo\"\n          website: \"https://www.trineo.co.nz/\"\n          slug: \"Trineo\"\n          logo_url: \"https://kiwi.ruby.nz/img/sponsors/trineo-logo.png\"\n\n    - name: \"Kererū sponsors\"\n      description: |-\n        Kererū sponsors include Flux, a software platform for energy retail business innovation, Boost, a Wellington-based technology professional team designing web and mobile apps, and Flick Electric Co., an electricity retailer offering transparent power solutions.\n      level: 3\n      sponsors:\n        - name: \"Flux\"\n          website: \"https://fluxfederation.com\"\n          slug: \"Flux\"\n          logo_url: \"https://kiwi.ruby.nz/img/sponsors/logo-flux.png\"\n\n        - name: \"Boost\"\n          website: \"https://www.boost.co.nz/\"\n          slug: \"Boost\"\n          logo_url: \"https://kiwi.ruby.nz/img/sponsors/boost-logo-black-99e0cbb5.png\"\n\n        - name: \"Flick Electric Co.\"\n          website: \"https://www.flickelectric.co.nz/\"\n          slug: \"FlickElectricCo\"\n          logo_url: \"https://kiwi.ruby.nz/img/sponsors/flick-lozenge-logo.png\"\n\n    - name: \"Supporter\"\n      description: |-\n        Supporter tier includes Optimal Workshop as a sponsor.\n      level: 4\n      sponsors:\n        - name: \"Optimal Workshop\"\n          website: \"https://www.optimalworkshop.com\"\n          slug: \"OptimalWorkshop\"\n          logo_url: \"https://kiwi.ruby.nz/img/sponsors/logo-optimal.png\"\n"
  },
  {
    "path": "data/kiwi-ruby/kiwi-ruby-2019/venue.yml",
    "content": "---\nname: \"Te Papa Museum\"\n\naddress:\n  street: \"55 Cable Street\"\n  city: \"Wellington\"\n  region: \"Wellington Region\"\n  postal_code: \"6011\"\n  country: \"New Zealand\"\n  country_code: \"NZ\"\n  display: \"55 Cable Street, Te Aro, Wellington 6011, New Zealand\"\n\ncoordinates:\n  latitude: -41.2904563\n  longitude: 174.7820894\n\nmaps:\n  google: \"https://maps.google.com/?q=Te+Papa+Museum,+Wellington,+New+Zealand,-41.2904563,174.7820894\"\n  apple: \"https://maps.apple.com/?q=Te+Papa+Museum,+Wellington,+New+Zealand&ll=-41.2904563,174.7820894\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=-41.2904563&mlon=174.7820894\"\n"
  },
  {
    "path": "data/kiwi-ruby/kiwi-ruby-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://kiwi.ruby.nz\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/kiwi-ruby/series.yml",
    "content": "---\nname: \"Kiwi Ruby\"\nwebsite: \"http://kiwi.ruby.nz\"\ntwitter: \"kiwirubyconf\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/koberb/koberb-meetup/event.yml",
    "content": "---\nid: \"koberb-meetup\"\ntitle: \"KOBE.rb Meetup\"\nlocation: \"Kobe, Japan\"\ndescription: |-\n  A meetup for Rubyists in Kobe and nearby areas, with room for newcomers and visitors from other regions. The community relaunched in 2024 and aims to gather monthly for learning, troubleshooting, and exchange around Ruby and Rails.\nwebsite: \"https://koberb.connpass.com\"\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 34.6932379\n  longitude: 135.1943764\n"
  },
  {
    "path": "data/koberb/koberb-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/koberb/series.yml",
    "content": "---\nname: \"KOBE.rb\"\nwebsite: \"https://koberb.connpass.com\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/krk-rb/krk-rb-2019/event.yml",
    "content": "---\nid: \"krk-rb-2019\"\ntitle: \"krk.rb 2019\"\ndescription: |-\n  THE RUBY CONFERENCE OF CRACOW - International line-up of speakers. Solid talks. Great people. Relaxed atmosphere. 14-15 May 2019 Browar Lubicz, Cracow, Poland\nlocation: \"Kraków, Poland\"\nkind: \"conference\"\nstart_date: \"2019-05-14\"\nend_date: \"2019-05-15\"\nwebsite: \"https://web.archive.org/web/20190501222558/https://krk-rb.pl/\"\noriginal_website: \"https://krk-rb.pl/\"\ncoordinates:\n  latitude: 50.06465009999999\n  longitude: 19.9449799\naliases:\n  - krk-rb.pl 2019\n"
  },
  {
    "path": "data/krk-rb/krk-rb-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://krk-rb.pl/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/krk-rb/series.yml",
    "content": "---\nname: \"krk.rb\"\nwebsite: \"https://krk-rb.pl/\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/kyobashirb/kyobashirb-meetup/event.yml",
    "content": "---\nid: \"kyobashirb-meetup\"\ntitle: \"Kyobashi.rb Meetup\"\nlocation: \"Osaka, Japan\"\ndescription: |-\n  An offline Ruby community for engineers interested in Ruby around Kyobashi, Osaka. People without a home or workplace in Kyobashi are also welcome to join.\nwebsite: \"https://kyobashirb.connpass.com\"\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 34.6960819\n  longitude: 135.5342674\n"
  },
  {
    "path": "data/kyobashirb/kyobashirb-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/kyobashirb/series.yml",
    "content": "---\nname: \"Kyobashi.rb\"\nwebsite: \"https://kyobashirb.connpass.com\"\nkind: \"meetup\"\nfrequency: \"irregular\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/kyotorb/kyotorb-meetup/event.yml",
    "content": "---\nid: \"kyotorb-meetup\"\ntitle: \"Kyoto.rb Meetup\"\nlocation: \"Kyoto, Japan\"\ndescription: |-\n  A community for Ruby engineers in and around Kyoto to hack, present, and talk together. It aims to be a place to recharge motivation and welcomes people from outside Kyoto as well.\nwebsite: \"https://kyotorb.connpass.com\"\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 35.0115754\n  longitude: 135.7681441\n"
  },
  {
    "path": "data/kyotorb/kyotorb-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/kyotorb/series.yml",
    "content": "---\nname: \"Kyoto.rb\"\nwebsite: \"https://kyotorb.connpass.com\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/la-conf/series.yml",
    "content": "---\nname: \"LA Conf\"\nwebsite: \"https://2014.la-conf.org\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"US\"\nlanguage: \"english\"\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2009/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZP7MRrHSiNtmjYtKc_Cc0B\"\ntitle: \"LA RubyConf 2009\"\nkind: \"conference\"\nlocation: \"Tustin, CA, United States\"\ndescription: \"\"\npublished_at: \"2009-04-04\"\nstart_date: \"2009-04-04\"\nend_date: \"2009-04-04\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2009\nbanner_background: \"linear-gradient(to bottom, #C93102, #E4B465)\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 33.7420005\n  longitude: -117.8236391\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2009/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: conference website\n\n# Schedule: https://web.archive.org/web/20140327142914/http://confreaks.com/events/larubyconf2009\n\n- id: \"dan-yoder-la-rubyconf-2009\"\n  title: \"Resource-Oriented Architecture, and Why it Matters, and How Waves Make it Easier\"\n  raw_title: \"LA RubyConf 2009 - Resource-Oriented Architecture, and Why it Matters, and How Waves Make it Easier\"\n  speakers:\n    - Dan Yoder\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Resource-Oriented Architecture, and Why it Matters, and How Waves Make it Easier by: Dan Yoder\n  video_provider: \"youtube\"\n  video_id: \"bGn_QRJzWy0\"\n\n- id: \"adam-blum-la-rubyconf-2009\"\n  title: \"Rhodes Framework for Mobile Client Development\"\n  raw_title: \"LA RubyConf 2009 - Rhodes Framework for Mobile Client Development\"\n  speakers:\n    - Adam Blum\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Rhodes Framework for Mobile Client Development by: Adam Blum\n  video_provider: \"youtube\"\n  video_id: \"eopOUqedWhU\"\n\n- id: \"brendan-lim-la-rubyconf-2009\"\n  title: \"Mobilize Your Rails Application\"\n  raw_title: \"LA RubyConf 2009 - Mobilize your Rails Application\"\n  speakers:\n    - Brendan Lim\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Mobilize your Rails Application by: Brendan Lim\n  video_provider: \"youtube\"\n  video_id: \"12jjv7PBrBo\"\n\n- id: \"pradeep-elankumaran-la-rubyconf-2009\"\n  title: \"Fast and Scalable Front / Back-end Services using Ruby, Rails and XMPP\"\n  raw_title: \"LA RubyConf 2009 - Fast and Scalable Front / Back-end Services using Ruby, Rails and XMPP\"\n  speakers:\n    - Pradeep Elankumaran\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Fast and Scalable Front / Back-end Services using Ruby, Rails and XMPP by: Pradeep Elankumaran\n  video_provider: \"youtube\"\n  video_id: \"9vUMHGOElbc\"\n\n- id: \"aaron-patterson-la-rubyconf-2009\"\n  title: \"Johnson\"\n  raw_title: \"LA RubyConf 2009 - Johnson\"\n  speakers:\n    - Aaron Patterson\n    - John Barnette\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Johnson by: Aaron Patterson and John Barnette\n  video_provider: \"youtube\"\n  video_id: \"3UzmGhv6mio\"\n\n- id: \"unknown-la-rubyconf-2009\"\n  title: \"Flying Robot: Unmanned Aerial Vehicles Using Ruby and Arduino\"\n  raw_title: \"LA RubyConf 2009 - Flying Robot: Unmanned Aerial Vehicles Using Ruby and Arduino\"\n  speakers:\n    - Unknown\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"NOuYAeOa6UA\"\n\n- id: \"bill-lapcevic-la-rubyconf-2009\"\n  title: \"Managing Ruby on Rails for High Performance\"\n  raw_title: \"LA RubyConf 2009 - Managing Ruby on Rails for High Performance\"\n  speakers:\n    - Bill Lapcevic\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Managing Ruby on Rails for High Performance by: Bill Lapcevic\n  video_provider: \"youtube\"\n  video_id: \"bn__0bMPtNs\"\n\n- id: \"ari-lerner-la-rubyconf-2009\"\n  title: \"Poolparty - Jump In The Pool, Get In The Clouds\"\n  raw_title: \"LA RubyConf 2009 - Poolparty - jump in the pool, get in the clouds\"\n  speakers:\n    - Ari Lerner\n    - Michael Fairchild\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Poolparty - jump in the pool, get in the clouds by: Ari Lerner and Michael Fairchild\n  video_provider: \"youtube\"\n  video_id: \"dTj-g2SrgSE\"\n\n- id: \"blake-mizerany-la-rubyconf-2009\"\n  title: \"Sinatra: The Ultimate Rack Citizen\"\n  raw_title: \"LA RubyConf 2009 - Sinatra: The ultimate rack citizen\"\n  speakers:\n    - Blake Mizerany\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Sinatra: The ultimate rack citizen by: Blake Mizerany\n  video_provider: \"youtube\"\n  video_id: \"Wlkq0qfS7JI\"\n\n- id: \"wolfram-arnold-la-rubyconf-2009\"\n  title: \"Scaling 'most popular' lists: a plugin solution\"\n  raw_title: \"LA RubyConf 2009 - Scaling 'most popular' lists: a plugin solution\"\n  speakers:\n    - Wolfram Arnold\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Scaling 'most popular' lists: a plugin solution by: Wolfram Arnold\n  video_provider: \"youtube\"\n  video_id: \"Q3uTrdXfgkw\"\n\n- id: \"danny-blitz-la-rubyconf-2009\"\n  title: \"Herding Tigers - Software Development and the Art of War\"\n  raw_title: \"LA RubyConf 2009 - Herding Tigers - Software Development and the Art of War\"\n  speakers:\n    - Danny Blitz\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Herding Tigers - Software Development and the Art of War by: Danny Blitz\n  video_provider: \"youtube\"\n  video_id: \"06LvK3FpV8M\"\n\n- id: \"jeremy-evans-la-rubyconf-2009\"\n  title: \"Sequel\"\n  raw_title: \"LA RubyConf 2009 - Sequel\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Sequel by: Jeremy Evans\n  video_provider: \"youtube\"\n  video_id: \"0Euba97UEdI\"\n\n- id: \"aaron-patterson-la-rubyconf-2009-journey-through-a-pointy-fores\"\n  title: \"Journey through a pointy forest: The state of XML parsing in Ruby\"\n  raw_title: \"LA RubyConf 2009 - Journey through a pointy forest: The state of XML parsing in Ruby\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Journey through a pointy forest: The state of XML parsing in Ruby by: Aaron Patterson\n  video_provider: \"youtube\"\n  video_id: \"QwTuYG73vHs\"\n\n- id: \"jim-weirich-la-rubyconf-2009\"\n  title: \"The Building Blocks of Modularity\"\n  raw_title: \"LA RubyConf 2009 - The Building Blocks of Modularity\"\n  speakers:\n    - Jim Weirich\n  event_name: \"LA RubyConf 2009\"\n  date: \"2009-04-04\"\n  published_at: \"2015-06-02\"\n  description: |-\n    The Building Blocks of Modularity by: Jim Weirich\n  video_provider: \"youtube\"\n  video_id: \"l780SYuz9DI\"\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2010/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZixHw-ivbA2bzu_TrTE8BZ\"\ntitle: \"LA RubyConf 2010\"\nkind: \"conference\"\nlocation: \"Burbank, CA, United States\"\ndescription: \"\"\npublished_at: \"2010-02-20\"\nstart_date: \"2010-02-19\"\nend_date: \"2010-02-20\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2010\nbanner_background: \"linear-gradient(to bottom, #C93102, #E4B465)\"\ncoordinates:\n  latitude: 34.1820605\n  longitude: -118.3074827\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2010/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"bjorn-freeman-benson-la-rubyconf-2010\"\n  title: \"New Relic: Web App Performance Monitoring / Paul MacCready - Gossamer Condor\"\n  raw_title: \"LA RubyConf 2010 - New Relic: Web App Performance Monitoring / Paul MacCready - Gossamer Condor\"\n  speakers:\n    - Bjorn Freeman-Benson\n  event_name: \"LA RubyConf 2010\"\n  date: \"2010-02-20\"\n  published_at: \"2015-06-02\"\n  description: |-\n    New Relic: Web App Performance Monitoring / Paul MacCready - Gossamer Condor by: Bjorn Freeman-Benson\n  video_provider: \"youtube\"\n  video_id: \"fFIQqsII3dM\"\n\n- id: \"joe-damato-la-rubyconf-2010\"\n  title: \"Everything You Ever Wanted To Know About Threads And Fibers But Were Afraid To Ask\"\n  raw_title: \"LA RubyConf 2010 - Everything you ever wanted to know about threads...\"\n  speakers:\n    - Joe Damato\n    - Aman Gupta\n  event_name: \"LA RubyConf 2010\"\n  date: \"2010-02-20\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Everything you ever wanted to know about threads and fibers but were afraid to ask by: Joe Damato and Aman Gupta\n  video_provider: \"youtube\"\n  video_id: \"sbOaxfCJB3A\"\n\n- id: \"sarah-mei-la-rubyconf-2010\"\n  title: \"Indoctrinating the Next Generation: Teaching Ruby to Kids\"\n  raw_title: \"LA RubyConf 2010 - Indoctrinating the Next Generation: Teaching Ruby to Kids\"\n  speakers:\n    - Sarah Mei\n  event_name: \"LA RubyConf 2010\"\n  date: \"2010-02-20\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Indoctrinating the Next Generation: Teaching Ruby to Kids by: Sarah Mei\n  video_provider: \"youtube\"\n  video_id: \"uvRb-Y5HdKg\"\n\n- id: \"tyler-mcmullen-la-rubyconf-2010\"\n  title: \"Alternative Data Structures in Ruby\"\n  raw_title: \"LA RubyConf 2010 - Alternative Data Structures in Ruby\"\n  speakers:\n    - Tyler McMullen\n  event_name: \"LA RubyConf 2010\"\n  date: \"2010-02-20\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Alternative Data Structures in Ruby by: Tyler McMullen\n  video_provider: \"youtube\"\n  video_id: \"Mti-bblDAek\"\n\n- id: \"tim-morgan-la-rubyconf-2010\"\n  title: \"Oh S***: How to bring a big Rails website down (and how not to)\"\n  raw_title: \"LA RubyConf 2010 - Oh S***: How to bring a big Rails website down (and how not to)\"\n  speakers:\n    - Tim Morgan\n  event_name: \"LA RubyConf 2010\"\n  date: \"2010-02-20\"\n  published_at: \"2015-06-02\"\n  description: |-\n    Oh S***: How to bring a big Rails website down (and how not to) by: Tim Morgan\n  video_provider: \"youtube\"\n  video_id: \"hqK4o7OIA54\"\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2011/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZQ5hO_VRRk7qxuaTV8TMq8\"\ntitle: \"LA RubyConf 2011\"\nkind: \"conference\"\nlocation: \"San Pedro, CA, United States\"\ndescription: \"\"\npublished_at: \"2011-02-05\"\nstart_date: \"2011-02-03\"\nend_date: \"2011-02-05\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2011\nbanner_background: \"#97B8D8\"\ncoordinates:\n  latitude: 33.7360696\n  longitude: -118.2923791\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2011/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: conference website\n# TODO: schedule website\n# TODO: talk dates\n\n- id: \"evan-phoenix-la-rubyconf-2011\"\n  title: \"Keynote: Developing a Language\"\n  raw_title: \"LA Ruby Conference 2011 - Keynote with Evan Phoenix\"\n  speakers:\n    - Evan Phoenix\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2014-09-15\"\n  description: |-\n    Developing a Language\n\n  video_provider: \"youtube\"\n  video_id: \"gN390RUDHag\"\n\n- id: \"jim-weirich-la-rubyconf-2011\"\n  title: \"Securing Your Rails App\"\n  raw_title: \"LA Ruby Conf 2011 Securing Your Rails App by Jim Weirich and Matt Yoho\"\n  speakers:\n    - Jim Weirich\n    - Matt Yoho\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2014-09-05\"\n  description: |-\n    \"Then it starts to scan the computer and transmit bits of information every time he clicks the mouse while he's surfing. After a while, [...] we've accumulated a complete mirror image of the content of his hard drive [...]. And then it's time for the hostile takeover.\"\n\n    -- Lisbeth Salander in Stieg Larsson's \"The Girl with the Dragon Tattoo\"\n\n    Hacker dramas like the Stieg Larrson book make for good fiction, but we know that real life rarely matches drama. And with all the security features that Rails 3 has added, surely it is difficult to hack a typical Rails web site.\n\n    Right?\n\n    Wrong! Without deliberate attention to the details of security, it almost certain that your site has flaws that a knowledgeable hacker can exploit. This talk will cover the ins and outs of web security and help you build a site that is protected from the real Lisbeth Salanders of the world.\n\n  video_provider: \"youtube\"\n  video_id: \"UcAGMpcQIwc\"\n\n- id: \"jonathan-dahl-la-rubyconf-2011\"\n  title: \"Advanced API design: how an awesome API can attract friends, make you rich, and change the world\"\n  raw_title: \"LA Ruby Conference 2011 - Advanced API design: how an awesome API can attract friends...\"\n  speakers:\n    - Jonathan Dahl\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2014-09-15\"\n  description: |-\n    APIs are becoming ubiquitous, but they are really hard to design well. In this talk, we'll discuss how to design and implement an API that isn't just functional, but makes people stand up and cheer. We'll also cover tips for integrating with other people's APIs.\n\n    LA Ruby Conference 2011 - Advanced API design: how an awesome API can attract friends, make you rich, and change the world by Jonathan Dahl\n\n    But an awesome API isn't just a feature. APIs are currently transforming the world, just like open source software has changed the world for the last decade. We'll talk about how this transformation impacts developers and changes the rules.\n\n  video_provider: \"youtube\"\n  video_id: \"D4XIIAplnUk\"\n\n- id: \"benjamin-sandofsky-la-rubyconf-2011\"\n  title: \"Twitter Mobile\"\n  raw_title: \"LA Ruby Conference 2011 - Twitter Mobile\"\n  speakers:\n    - Benjamin Sandofsky\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2014-09-15\"\n  description: |-\n    Twitter is one of the largest companies in the world running Ruby, and you can tell by its agile culture: fast, iterative development that finds a balance between people and process.\n\n    This presentation starts with a high level overview of Twitter's architecture, following a tweet from desktop to delivery on your mobile phone. Then we'll dive into specific Ruby apps, including mobile.twitter.com and the SMS delivery service. Finally, we'll cover the best practices that allow small teams to consistently deliver quality work.\n\n    Benjamin Sandofsky is an engineer on Twitter's mobile team. He works on mobile.twitter.com, Twitter for iPhone/iPad, Tweetie for Mac, and Twitter for Safari.\n\n  video_provider: \"youtube\"\n  video_id: \"VcsfDoIdY48\"\n\n- id: \"shane-becker-la-rubyconf-2011\"\n  title: \"Your Slides Suck\"\n  raw_title: \"LA Ruby Conference 2011 - Your Slides Suck\"\n  speakers:\n    - Shane Becker\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2014-09-15\"\n  description: |-\n    I've sat through years and years of bad slides and bad presentations. Often times the speaker and/or the content of the presentation is totally awesome, but the slides are horrible. Bad slides are bad. Bad slides bore, distract and confuse your audience. Bad slides even crash space shuttles. Srsly.\n\n    I'll enumerate a dozen ways that you can make your slides better for you, your audience and puppies. And space shuttles. We'll cover the good, the bad and the ugly. Names will be named. Punches will not be pulled.\n\n    And yes, I'm talking about you.\n\n  video_provider: \"youtube\"\n  video_id: \"NbSV6ThZAIQ\"\n\n- id: \"bryan-liles-la-rubyconf-2011\"\n  title: \"Active Support 3, It's finally getting interesting\"\n  raw_title: \"LA Ruby Conference 2011 - Active Support 3, It's finally getting interesting\"\n  speakers:\n    - Bryan Liles\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2014-09-15\"\n  description: |-\n    Since we've seen the ActiveModel Extravaganza, it is now time for the, \"The ActiveSupport Three - It is finally getting interesting.\" In this spectacle, Bryan Liles will highlight some of the more interesting features of ActiveSupport 3, while showing how you can use it write better (looking) Ruby code. A special emphasis will be placed on the new sections, but some of our old friends we've known for years will definitely get their time in the spotlight. Highlights from this talk will include Concerns, Load Paths, and other fun topics.\n\n  video_provider: \"youtube\"\n  video_id: \"7AqKuzQL0Y0\"\n\n- id: \"evan-dorn-la-rubyconf-2011\"\n  title: \"NinjaScript: JavaScript so unobtrusive, you won't see it coming.\"\n  raw_title: \"LA Ruby Conference 2011 - NinjaScript: JavaScript so unobtrusive, you won't see it coming.\"\n  speakers:\n    - Evan Dorn\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2014-09-15\"\n  description: |-\n    NinjaScript is a JS framework, built on jQuery with two principles in mind. #1: Enriching your website with JS behaviors should be as easy as specifying CSS styles. #2: Making your site degrade gracefully without JS shouldn't take any extra work.\n\n    NinjaScript provides a simple, CSS-like syntax for applying behaviors, including transformations and event handlers, to your elements. NS handles it from there: as a developer, you won't ever have to think about binding or event delegation again.\n\n    In addition, NinjaScript and its partner gem NinjaHelper make it trivial to build Rails applications that work perfectly with or without JavaScript. At last, true graceful degradation without the suffering.\n\n  video_provider: \"youtube\"\n  video_id: \"Rwa_u7yhgqc\"\n\n- id: \"ron-evans-la-rubyconf-2011\"\n  title: \"How to Jam in Code\"\n  raw_title: \"LA Ruby Conference 2011 - How to Jam in Code\"\n  speakers:\n    - Ron Evans\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2015-01-05\"\n  description: |-\n    \"Music is a world within itself, with a language we all understand\" said Stevie Wonder. That sounds a lot like programming! The parallels between music and software development are striking, and understanding how they intersect can teach us a lot about how we can improve our code, our craft, and our joy in how we approach our work.\n\n    In this talk, which will include some unique musical forms of live audience participation, we will experience some of the patterns that connect two of the most human of activities: creating code, and creating music.\n  video_provider: \"youtube\"\n  video_id: \"QDIv4HRqt9k\"\n\n- id: \"michael-hartl-la-rubyconf-2011\"\n  title: \"The Rails Tutorial Story\"\n  raw_title: \"LA Ruby Conference 2011 - The Rails Tutorial Story\"\n  speakers:\n    - Michael Hartl\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2015-01-05\"\n  description: |-\n    Conceived in the throes of the Y Combinator entrepreneur program, the Ruby on Rails Tutorial project was designed to \"solve my money problem\" without the roller-coaster ride of a Silicon Valley startup. This\n  video_provider: \"youtube\"\n  video_id: \"ple8ABsJnWc\"\n\n- id: \"mitchell-hashimoto-la-rubyconf-2011\"\n  title: \"Working in Virtual Machines, the Vagrant Way\"\n  raw_title: \"LA Ruby Conference 2011 - Working in Virtual Machines, the Vagrant Way\"\n  speakers:\n    - Mitchell Hashimoto\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2015-01-05\"\n  description: |-\n    Want to run Ubuntu on your OS/X or Windows machine? Recreate any production environment? Snapshots? All from the command line?\n\n    Virtualization technology is beginning to revolutionize development practices, just as it did with server infrastructure and \"the cloud.\" Imagine developing within the comfort of your own machine, but having the code run on hardware and software which directly matches production. Modern virtualization technology along with tools like Vagrant not only make this possible, but fun and easy.\n\n    In this talk, I'll present the advantages of working in a virtualized development environment both from the standpoint of an individual developer and a corporation. Then, I'll move onto introducing Vagrant and how it enables developers to work in virtualized environments with minimal effort.\n  video_provider: \"youtube\"\n  video_id: \"P2v1Z7NI3Jo\"\n\n- id: \"giles-bowkett-la-rubyconf-2011\"\n  title: \"Easy Node.js Apps With Lisp\"\n  raw_title: \"LA Ruby Conference 2011 - Easy Node.js Apps With Lisp\"\n  speakers:\n    - Giles Bowkett\n  event_name: \"LA RubyConf 2011\"\n  date: \"2011-02-05\"\n  published_at: \"2014-09-15\"\n  description: |-\n    Lisp is a programming language which allows you to manipulate its abstract syntax tree directly. The popular quote about every other language being a partial implementation of Lisp is not just snark; all programming languages use an abstract syntax tree, so Lisp is literally and mathematically either equal to, or a superset of, every other programming language. However, if you've wanted to build anything actually useful with Lisp, you've historically been in the position of having no vibrant, powerful open source community to draw on. Not many people enjoyed this tradeoff, but fortunately, it is no longer the case. Sibilant is a Lisp written on top of Node.js, a new server-side JavaScript library for writing servers. Node has an active open source community, and it runs on the lightning-fast V8 JavaScript interpreter (written and supported by Google). Thanks to V8, Node, and Sibilant, it is now trivially easy to write web servers, command-line utilities, and applications (server-side, client-side, or both) in a fast, well-supported Lisp. This talk will show you how.\n\n  video_provider: \"youtube\"\n  video_id: \"sru_ywjC2oo\"\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2012/event.yml",
    "content": "---\nid: \"PL5BDBA11D68D73050\"\ntitle: \"LA RubyConf 2012\"\nkind: \"conference\"\nlocation: \"Burbank, CA, United States\"\ndescription: \"\"\npublished_at: \"2012-02-04\"\nstart_date: \"2012-02-02\"\nend_date: \"2012-02-04\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2012\nbanner_background: \"#F1F1F1\"\nfeatured_color: \"#002448\"\nfeatured_background: \"#F1F1F1\"\ncoordinates:\n  latitude: 34.1820605\n  longitude: -118.3074827\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2012/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: conference website\n# TODO: schedule website\n# TODO: talk dates\n\n- id: \"joe-obrien-la-rubyconf-2012\"\n  title: \"Keynote: People the Missing Ingredient\"\n  raw_title: \"Keynote: People the Missing Ingredient by Joe O'Brien\"\n  speakers:\n    - Joe O'Brien\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-03-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"tVmZHqf7yPE\"\n\n- id: \"jeff-casimir-la-rubyconf-2012\"\n  title: \"Metric Driven Development with Ruby on Rails\"\n  raw_title: \"Metric Driven Development with Ruby on Rails by Jeff Casimir\"\n  speakers:\n    - Jeff Casimir\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-18\"\n  description: |-\n    \"Ruby can't scale.\"\n\n    Tell that to LivingSocial, GroupOn, Gowalla, Sony, and the rest of our community pushing millions of requests per day. Scaling an application isn't about piling up hardware and dropping in the newest database fad, it's the combination of design and refinement.\n\n    In this session, we'll look at refining Ruby code using tools to:\n\n    Find CPU-intensive hotspots Measure memory and object allocation Monitor query count and duration Isolate data-store bottlenecks This is not about info-porn. It's about finding the 1% of your code that, through optimization, can dramatically improve performance.\n\n  video_provider: \"youtube\"\n  video_id: \"_Iqb9n9O7a0\"\n\n- id: \"john-bender-la-rubyconf-2012\"\n  title: \"Rack Middleware as a General Purpose Abstraction\"\n  raw_title: \"Rack Middleware as a General Purpose Abstraction by John Bender\"\n  speakers:\n    - John Bender\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-20\"\n  description: |-\n    We've all seen the monolithic Rails model, pages and pages of methods all dumped into one class. Inevitably someone starts moving things around just to feel better about the loc count without making any real difference. How can we reify actions on an object and simplify our classes?\n\n    In this talk we'll examine Rack middleware as a general purpose method of object composition, see examples of it at work in Vagrant, and use these ideas to simplify an existing application.\n\n  video_provider: \"youtube\"\n  video_id: \"fcNaiP5tea0\"\n\n- id: \"jeremie-castagna-la-rubyconf-2012\"\n  title: \"How to Scale a Ruby Webservice\"\n  raw_title: \"How to scale a Ruby webservice by Jeremie Castagna\"\n  speakers:\n    - Jeremie Castagna\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-19\"\n  description: |-\n    In the wide world of web service development, Ruby is rarely the first pick as a platform to build on. Slowness and scalability are usually the reasons given to go with Java or something less friendly. However, language is rarely the bottleneck in a web application. Using a service at ATTi as an example, we'll look at how most service applications can be built and scaled in Ruby, and how to avoid common pitfalls.\n\n  video_provider: \"youtube\"\n  video_id: \"nfvD9UBh3XM\"\n\n- id: \"dan-yoder-la-rubyconf-2012\"\n  title: \"Kill! Kill! Die! Die! Load Testing With A Vengeance\"\n  raw_title: \"Kill! Kill! Die! Die! Load Testing With A Vengeance by Dan Yoder and Carlo Flores\"\n  speakers:\n    - Dan Yoder\n    - Carlo Flores\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-19\"\n  description: |-\n    We've all seen load tests of a single \"hello world\" HTTP server using tools like ab or httperf. But what about load testing for real world Web applications and testing architectures that go beyond a few processes on a single machine? What about testing elastic \"on-demand\" architectures that add capacity as load grows? How does testing in the cloud affect your results? At what point does bandwidth become a bottleneck instead of CPU or memory? And what are we really measuring? What is the difference between connections and request per second? And how do those ultimately relate to infrastructure cost, which is the real bottom line?\n\n  video_provider: \"youtube\"\n  video_id: \"TPOWB-PAWxA\"\n\n- id: \"steven-baker-la-rubyconf-2012\"\n  title: \"Maintainable Ruby on Rails\"\n  raw_title: \"LA Ruby Conf 2012 Maintainable Ruby on Rails by Steven Baker\"\n  speakers:\n    - Steven Baker\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-20\"\n  description: |-\n    As we enter a decade of applications developed with Ruby on Rails, many teams are starting to feel growing pains relating to design decisions that were made in the past. Development slows down, and morale declines. Fresh competitors without the cruft of legacy code slowing them down easily deliver new features.\n\n    This change of speed is not a natural part of the growth of a software project, but a common symptom of the design decisions made, and techniques practiced, to develop the software in the first place.\n\n    In this talk you will learn how to identify common (and not so common) issues that teams face as their applications age. You will learn about principles of software design, techniques, and practices to solve these problems. You will also gain valuable knowledge about how to make your software more maintainable and extensible to ensure you don't run into these problems in the future.\n  video_provider: \"youtube\"\n  video_id: \"S9PY-qZKXww\"\n\n- id: \"steve-klabnik-la-rubyconf-2012\"\n  title: \"Designing Hypermedia APIs\"\n  raw_title: \"LA Ruby Conf 2012 Designing Hypermedia APIs by Steve Klabnik\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-20\"\n  description: |-\n    Rails did a lot to bring REST to developers, but its conception leaves the REST devotee feeling a bit empty. \"Where's the hypermedia?\" she says. \"REST isn't RPC,\" he may cry. \"WTF??!?!\" you may think. \"I have it right there! resources :posts ! What more is there? RPC? Huh?\"\n\n    In this talk, Steve will explain how to design your APIs so that they truly embrace the web and HTTP. Just as there's an impedance mismatch between our databases, our ORMs, and our models, there's an equal mismatch between our applications, our APIs, and our clients. Pros and cons of this approach will be discussed, as well as why we aren't building things this way yet.\n  video_provider: \"youtube\"\n  video_id: \"x5ezCxo5sM4\"\n\n- id: \"shane-becker-la-rubyconf-2012\"\n  title: \"Quit Your Job. Srsly.\"\n  raw_title: \"LA Ruby Conf 2012 - Quit Your Job. Srsly.  by Shane Becker\"\n  speakers:\n    - Shane Becker\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-20\"\n  description: |-\n    \"The best minds of my generation are thinking about how to make people click ads.\" â€\" Jeff Hammerbacher http://buswk.co/eCdfFp We can rewrite Jeff's quote like this: \"The best programmers of my generation are working on solutions to problems that do not matter.\" The crux of it is you are better than your job. You have a greater potential than your job is realizing. You can do more than you think. You are worth more than your job is paying you. You can make the world a better place. You don't have to be limited to building mobile/geo-based/social/ad-driven/gamification-influence/fully-buzzword-compliant bullshit to get people to buy things they don't need while giving up more privacy to corporations and becoming less happy in the process. You're better than that. Quit your job. Build your dreams. Change the world. Srsly.\n\n  video_provider: \"youtube\"\n  video_id: \"0CMjiIqhvdQ\"\n\n- id: \"matt-aimonetti-la-rubyconf-2012\"\n  title: \"Time to Move Away from Ruby\"\n  raw_title: \"Time to Move Away from Ruby  Matt Aimonetti\"\n  speakers:\n    - Matt Aimonetti\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-25\"\n  description: |-\n    Let's be honest, Ruby became mainstream a few years back and it isn't the cool underground programming language it once was. It's quite likely that your cousin's boyfriend who's \"into computers\" knows what Ruby on Rails is. There are hundreds of books, conferences, training and meetups for Rubyists. Recruiters fight to hire whoever knows how to generate a scaffolded Rails app. But now cool kids can't stop talking about node.js, CoffeeScript, Clojure, Haskell and pushing code to the UI layer. What does it mean for the new, existing and prospecting Ruby developers? Is it time to jump ship and move on to something else?\n  video_provider: \"youtube\"\n  video_id: \"foOPsKQOQyw\"\n\n- id: \"xavier-shay-la-rubyconf-2012\"\n  title: \"Rails Sustainable Productivity\"\n  raw_title: \"LA Ruby Conf 2012 Rails Sustainable Productivity  Xavier Shay\"\n  speakers:\n    - Xavier Shay\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-25\"\n  description: |-\n    I've been writing Rails for near on five years, and there are some things that really grind my goat. Rails is great, but there are so many things we get wrong, both as a framework and a community. In particular, for applications that have grown beyond an initial prototype (if you earn a salary writing Rails, this is probably you), many Rails Best Practices are actively harmful to creating solid, robust, and enjoyable applications. I'll talk about testing, data modelling, code organisation, build systems, and more, drawing from a large pool of things I have seen done wrong and also personally failed at over the last half decade. Of course I'll be providing suggestions for fixing things, also.\n\n    It's more of a freight train, see.\n  video_provider: \"youtube\"\n  video_id: \"84ewfGEojsw\"\n\n- id: \"ben-scofield-la-rubyconf-2012\"\n  title: \"Great Developers Steal\"\n  raw_title: \"LA Ruby Conf 2012 Great Developers Steal by Ben Scofield\"\n  speakers:\n    - Ben Scofield\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-25\"\n  description: |-\n    If you take a look at software today, you'll see more smart people building things than there ever have been before. The problem? They're all working in different languages, on different platforms, with different concepts. To take advantage of the full breadth of work that's being done, we need to stay on top of things happening in other communities, and we need to bring good ideas back to Ruby. In this session, we'll look at how to identify great code and concepts, and how to bring them back to our community.\n  video_provider: \"youtube\"\n  video_id: \"QPY0uETQA-c\"\n\n- id: \"mike-moore-la-rubyconf-2012\"\n  title: \"Managing Success: We made it, now we're screwed.\"\n  raw_title: \"Managing Success: We made it, now we're screwed. by Mike Moore\"\n  speakers:\n    - Mike Moore\n  event_name: \"LA RubyConf 2012\"\n  date: \"2012-02-04\"\n  published_at: \"2012-04-19\"\n  description: |-\n    Life as a startup, whether a bootstrapped company or an experimental project within an enterprise, is hard. You have to struggle to earn success. Lean, pivots, minimal viable products, and other buzzwords all steps along this journey. The struggle makes the eventual success that much sweeter. But it can also lead to suboptimal code, confusing logic, and general friction to getting things done.\n\n  video_provider: \"youtube\"\n  video_id: \"VAex3QIrUB8\"\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZ09J3-EXxzX2yCgl4a5qUk\"\ntitle: \"LA RubyConf 2013\"\nkind: \"conference\"\nlocation: \"Burbank, CA, United States\"\ndescription: \"\"\npublished_at: \"2013-02-23\"\nstart_date: \"2013-02-21\"\nend_date: \"2013-02-23\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2013\nbanner_background: \"#F1F1F1\"\nfeatured_color: \"#002448\"\nfeatured_background: \"#F1F1F1\"\ncoordinates:\n  latitude: 34.1820605\n  longitude: -118.3074827\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2013/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: conference website\n# TODO: schedule website\n# TODO: talk dates\n\n- id: \"ron-evans-la-rubyconf-2013\"\n  title: \"Keynote: The Signal\"\n  raw_title: \"LA Ruby Conference 2013 Keynote by Ron Evans\"\n  speakers:\n    - Ron Evans\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-13\"\n  description: |-\n    Visit http://artoo.io for more details of the framework Ron presents in this talk!\n\n  video_provider: \"youtube\"\n  video_id: \"ciSs9x_Ogls\"\n\n- id: \"ryan-weald-la-rubyconf-2013\"\n  title: \"People who liked this talk also liked ... Building Recommendation Systems Using Ruby\"\n  raw_title: \"LA Ruby Conference 2013 People who liked this talk also liked ... Building Recommendation...\"\n  speakers:\n    - Ryan Weald\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-14\"\n  description: |-\n    Title: People who liked this talk also liked ... Building Recommendation Systems Using Ruby\n    Presented by: Ryan Weald\n\n    From Amazon, to Spotify, to thermostats, recommendation systems are everywhere. The ability to provide recommendations for your users is becoming a crucial feature for modern applications. In this talk I'll show you how you can use Ruby to build recommendation systems for your users. You don't need a PhD to build a simple recommendation engine -- all you need is Ruby. Together we'll dive into the dark arts of machine learning and you'll discover that writing a basic recommendation engine is not as hard as you might have imagined. Using Ruby I'll teach you some of the common algorithms used in recommender systems, such as: Collaborative Filtering, K-Nearest Neighbor, and Pearson Correlation Coefficient. At the end of the talk you should be on your way to writing your own basic recommendation system in Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"fh1y1BUTJxE\"\n\n- id: \"robbie-clutton-la-rubyconf-2013\"\n  title: \"It's not your test framework, it's you\"\n  raw_title: \"LA Ruby Conference 2013 It's not your test framework, it's you by Robbie Clutton, Matt Parker\"\n  speakers:\n    - Robbie Clutton\n    - Matt Parker\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-14\"\n  description: |-\n    The BDD hype cycle is over. Recently, there's been a lot of backlash against popular BDD libraries like Cucumber. Some developers blame their test frameworks for brittle test suites and long build times. Others go so far as to claim that acceptance testing is simply not sustainable, period. In this talk, we'll do some root cause analysis of this phenomenon with shocking results - it's not the test framework, it's not the methodology, it's you. You've abused your test framework, you've cargo-culted the methodology, and now you're feeling the pain. We'll show you a way out of the mess you've made. We'll discuss the main problems BDD was intended to solve. We'll show you how to groom your test suite into journey, functional, integration, and unit tests in order to address build times. We'll teach how to mitigate against brittleness and flickers, and how to let your tests reveal the intent of the application and actually become the executable documentation we've been waiting for.\n\n  video_provider: \"youtube\"\n  video_id: \"j7An19XQwBg\"\n\n- id: \"austin-fonacier-la-rubyconf-2013\"\n  title: \"LA Ruby Conference 2013 Backbone.js, Jasmine and Rails: The Lust Story\"\n  raw_title: \"LA Ruby Conference 2013 Backbone.js, Jasmine and Rails: The Lust Story by Austin Fonacier\"\n  speakers:\n    - Austin Fonacier\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-14\"\n  description: |-\n    I want to present on why, where, and when backbone would be beneficial to use. We went through the whole motion on our rails project and I want to share in detail how we came about utilizing backbone on our project and hopefully you can too! In the end, implementing Backbone and jasmine led to a cleaner, more organized and better tested code base.\n\n  video_provider: \"youtube\"\n  video_id: \"kzVHz60gRJM\"\n\n- id: \"mike-leone-la-rubyconf-2013\"\n  title: \"Python for Ruby Programmers\"\n  raw_title: \"LA Ruby Conference 2013 Python for Ruby Programmers by Mike Leone\"\n  speakers:\n    - Mike Leone\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-14\"\n  description: |-\n    You've probably heard of Python, the _other_ popular, dynamic, multi-paradigm programming language. It occupies much of the same space as Ruby, has many similar language features, and the syntax even looks pretty similar. But what are the specific strengths and weaknesses of Python when compared to Ruby? What use cases are conducive to one language versus the other? In this talk, we look at some of the differences in language design, exploring how they affect application development and maintenance. Later, we look at some specific scenarios and show how the strengths of each language apply.\n\n  video_provider: \"youtube\"\n  video_id: \"maSlTKMzR3Q\"\n\n- id: \"juan-pablo-genovese-la-rubyconf-2013\"\n  title: \"Where is my Scalable API?\"\n  raw_title: \"LA Ruby Conference 2013 Where is my scalable API? by Juan Pablo Genovese\"\n  speakers:\n    - Juan Pablo Genovese\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-14\"\n  description: |-\n    You have a good ol' Rails application that provides an API. That app is gaining momentum and getting tons of new users every day. You need to double the servers to accommodate the infrastructure to the demand. Then, you get the bill from your cloud service provider and... THE HORROR!! Is big enough to make you cry. Well, here comes Goliath. A very tiny, well designed and FAST non-blocking IO server that will put a big smile in your face, since you're going to need much less money to serve the same (or more!) requests per second. A real case scenario, a social gaming application for mobile devices, will serve as guide to show you how good it is and how much progress can you make with just a little bit of work. From development tools and gems to deployment strategies, balancing and more, we'll show you how a resource consuming Rails API turns into a nimble and fast Goliath API. The real time Internet is calling, and Goliath will hurry to make you more real time than ever.\n\n  video_provider: \"youtube\"\n  video_id: \"dcU7_LUme_M\"\n\n- id: \"bryan-helmkamp-la-rubyconf-2013\"\n  title: \"Refactoring Fat Models with Patterns\"\n  raw_title: \"LA Ruby Conference 2013 Refactoring Fat Models with Patterns by Bryan Helmkamp\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-14\"\n  description: |-\n    \"Fat models\" cause maintenance issues in large apps. Only incrementally better than cluttering controllers with domain logic, they usually represent a failure to apply the Single Responsibility Principle (SRP). \"Anything related to what a user does\" is not a single responsibility. Early on, SRP is easier to apply. ActiveRecord classes handle persistence, associations and not much else. But bit-by-bit, they grow. Objects that are inherently responsible for persistence become the de facto owner of all business logic as well. And a year or two later you have a User class with over 500 lines of code, and hundreds of methods in it's public interface. Callback hell ensues. This talk will explore patterns to smoothly deal with increasing intrinsic complexity (read: features!) of your application. Transform fat models into a coordinated set of small, encapsulated objects working together in a veritable symphony.\n\n  video_provider: \"youtube\"\n  video_id: \"5yX6ADjyqyE\"\n\n- id: \"robbie-clutton-la-rubyconf-2013-its-not-your-test-framework-it\"\n  title: \"It's not your test framework, it's you\"\n  raw_title: \"LA Ruby Conference 2013 It's not your test framework, it's you by Robbie Clutton, Matt Parker\"\n  speakers:\n    - Robbie Clutton\n    - Matt Parker\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-11\"\n  description: |-\n    The BDD hype cycle is over. Recently, there's been a lot of backlash against popular BDD libraries like Cucumber. Some developers blame their test frameworks for brittle test suites and long build times. Others go so far as to claim that acceptance testing is simply not sustainable, period. In this talk, we'll do some root cause analysis of this phenomenon with shocking results - it's not the test framework, it's not the methodology, it's you. You've abused your test framework, you've cargo-culted the methodology, and now you're feeling the pain. We'll show you a way out of the mess you've made. We'll discuss the main problems BDD was intended to solve. We'll show you how to groom your test suite into journey, functional, integration, and unit tests in order to address build times. We'll teach how to mitigate against brittleness and flickers, and how to let your tests reveal the intent of the application and actually become the executable documentation we've been waiting for.\n\n  video_provider: \"youtube\"\n  video_id: \"TRulBSydsDc\"\n\n- id: \"fiona-tay-la-rubyconf-2013\"\n  title: \"Why I like JRuby (and you should too)\"\n  raw_title: \"LA Ruby Conference 2013 Why I like JRuby (and you should too) by Fiona Tay\"\n  speakers:\n    - Fiona Tay\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-14\"\n  description: |-\n    If MRI is a potato peeler that does one thing very well, JRUby is the Swiss Army Knife that offers developers a multitude of tools. JRuby opens doors that MRI has closed, being highly performant and offers access to Java libraries. From the perspective of a former MRI'er, I'll discuss concrete examples of how to realize the benefits of the JRuby stack, drawing examples from my work on an open-source JRuby on Rails app.\n\n  video_provider: \"youtube\"\n  video_id: \"rY9oJaWu3Bg\"\n\n- id: \"austin-fonacier-la-rubyconf-2013-backbonejs-jasmine-and-rails-t\"\n  title: \"Backbone.js, Jasmine and Rails: The Lust Story\"\n  raw_title: \"LA Ruby Conference 2013 Backbone.js, Jasmine and Rails: The Lust Story by Austin Fonacier\"\n  speakers:\n    - Austin Fonacier\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-10\"\n  description: |-\n    I want to present on why, where, and when backbone would be beneficial to use. We went through the whole motion on our rails project and I want to share in detail how we came about utilizing backbone on our project and hopefully you can too! In the end, implementing Backbone and jasmine led to a cleaner, more organized and better tested code base.\n\n  video_provider: \"youtube\"\n  video_id: \"8BdYFMqtlSc\"\n\n- id: \"mike-leone-la-rubyconf-2013-python-for-ruby-programmers\"\n  title: \"Python for Ruby Programmers\"\n  raw_title: \"LA Ruby Conference 2013 Python for Ruby Programmers by Mike Leone\"\n  speakers:\n    - Mike Leone\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-10\"\n  description: |-\n    You've probably heard of Python, the _other_ popular, dynamic, multi-paradigm programming language. It occupies much of the same space as Ruby, has many similar language features, and the syntax even looks pretty similar. But what are the specific strengths and weaknesses of Python when compared to Ruby? What use cases are conducive to one language versus the other? In this talk, we look at some of the differences in language design, exploring how they affect application development and maintenance. Later, we look at some specific scenarios and show how the strengths of each language apply.\n\n  video_provider: \"youtube\"\n  video_id: \"PvMDPYSlki4\"\n\n- id: \"chris-hunt-la-rubyconf-2013\"\n  title: \"Impressive Ruby Productivity with Vim and Tmux\"\n  raw_title: \"LA Ruby Conference 2013 Impressive Ruby Productivity with Vim and Tmux by Chris Hunt\"\n  speakers:\n    - Chris Hunt\n  event_name: \"LA RubyConf 2013\"\n  date: \"2013-02-23\"\n  published_at: \"2013-04-15\"\n  description: |-\n    Impress your friends, scare your enemies, and boost your productivity 800% with this live demonstration of vim and tmux. You will learn how to build custom IDEs for each of your projects, navigate quickly between files, write and run tests, view and compare git history, create pull requests, publish gists, format and refactor your code with macros, remote pair program, and more, all without leaving the terminal. Come prepared to learn and ask questions; this is serious business.\n\n  video_provider: \"youtube\"\n  video_id: \"gB-JSh1EVME\"\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYidNh3m57hyDjjKGC9-rbj\"\ntitle: \"LA RubyConf 2014\"\nkind: \"conference\"\nlocation: \"Burbank, CA, United States\"\ndescription: |-\n  Los Angeles Ruby Conference, held annually in Southern California\npublished_at: \"2014-02-08\"\nstart_date: \"2014-02-06\"\nend_date: \"2014-02-08\"\nwebsite: \"https://web.archive.org/web/20140701152258/http://larubyconf.com/\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2014\nbanner_background: \"#F1F1F1\"\nfeatured_color: \"#002448\"\nfeatured_background: \"#F1F1F1\"\ncoordinates:\n  latitude: 34.1820605\n  longitude: -118.3074827\naliases:\n  - Los Angeles Ruby Conference 2014\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2014/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20140701152258/http://larubyconf.com/\n# Schedule: https://web.archive.org/web/20140921155306/http://larubyconf.com/schedule\n\n## Day 1 - Workshop - Thursday, February 6, 2014\n\n# TODO: Missing Workshop: Mike Moore - Rails Testing\n# TODO: Missing Workshop: Matthew Boston, Justin Searls - Real-world JavaScript Testing\n# TODO: Missing Workshop: Mark Menard - Introduction to Ruby and Ruby on Rails\n\n## Day 2 - Workshop - Friday, February 7, 2014\n\n# TODO: Missing Workshop: Mike Moore - Rails Testing Workshop (Day 2)\n# TODO: Missing Workshop: Mark Menard - Build Small Things\n\n## Day 3 - Conference - Saturday, February 8, 2014\n\n# Welcome and Introduction (Coby Randquist, JR Fent)\n\n- id: \"sebastian-sogamoso-la-rubyconf-2014\"\n  title: \"SOLID Principles Through Tests\"\n  raw_title: \"LA Ruby Conf 2014 - SOLID principles through tests by Sebastian Sogamoso\"\n  speakers:\n    - Sebastian Sogamoso\n  event_name: \"LA RubyConf 2014\"\n  date: \"2014-02-08\"\n  published_at: \"2014-04-11\"\n  description: |-\n    We care about writing quality code, we have read the definition of SOLID principles several times and we know how important they are for writing good OO code, but are we really following those principles? Is there a pragmatic way of following them in our day to day jobs or are they just some principles a few computer scientists wrote? Fortunately there is, SOLID principles are not just good ideas , they are intended to help us write better code, enjoy our jobs more and be happy programmers. But, where should we start? We should start where we always do. By writing tests, yes, for real. As Kent Beck says \"TDD doesn't drive good design. TDD gives you immediate feedback about what is likely to be bad design\", so we need to go a step further. In this talk we will see how writing tests is not just *doing TDD* is about having good test coverage, it's also about driving our code towards good design, one that follows SOLID principles.\n\n  video_provider: \"youtube\"\n  video_id: \"_4j0Bh-Qtrc\"\n\n- id: \"joe-moore-la-rubyconf-2014\"\n  title: \"I Have Pair Programmed for 27,000 Hours: Ask Me Anything!\"\n  raw_title: \"LA Ruby Conf 2014 - I Have Pair Programmed for 27,000 Hours: Ask Me Anything!\"\n  speakers:\n    - Joe Moore\n  event_name: \"LA RubyConf 2014\"\n  date: \"2014-02-08\"\n  published_at: \"2014-04-11\"\n  description: |-\n    By Joe Moore\n\n    Let's do this thing. What is pair programming? Won't software projects take twice as long or cost twice as much with pair programming? Do I pair with the same person every day? Who owns the code? How do performance reviews work? Do we pair on *everything?* What do I do if my pair goes home sick? What do I do if I can't stand my pair? What if my pair smells bad? What if my pair smells GOOD?! I've given presentations at many conferences, Meetups, and companies on topics ranging from Agile team management to Android messaging frameworks. My presentations inevitably grind to a halt once I mention that I pair program: I'm peppered with questions! I'll answer any and all questions about pair programming and remote pair programming, from the profound to the silly. I have no doubt that we will fill the allotted time with sage advice, educational anecdotes, and your own stories about pair programming.\n\n  video_provider: \"youtube\"\n  video_id: \"rIcUXcyC6BA\"\n\n# Break\n\n- id: \"andy-pliszka-la-rubyconf-2014\"\n  title: \"Introduction to CRuby Source Code\"\n  raw_title: \"LA Ruby Conf 2014 - Introduction to CRuby source code by Andy Pliszka\"\n  speakers:\n    - Andy Pliszka\n  event_name: \"LA RubyConf 2014\"\n  date: \"2014-02-08\"\n  published_at: \"2014-04-11\"\n  description: |-\n    Understanding of CRuby source code has profound effects on every Ruby developer. In my talk, I will show you how to build Ruby from source. I will explain how to install and configure your new Ruby build on Mac and Linux. I will walk you through CRuby source code and introduce you to a few of the most important CRuby files. I will show you how to hack CRuby and modify some of the fundament Ruby classes in C. I will demonstrate how to write complete Ruby classes in C. Finally, I will show you that CRuby code can run 100 times faster than Ruby code. I hope that this talk will inspire you to learn more about CRuby and hack it on your own.\n\n  video_provider: \"youtube\"\n  video_id: \"Chk9c8EwrCA\"\n\n- id: \"justin-searls-la-rubyconf-2014\"\n  title: \"As Easy As Rails\"\n  raw_title: \"LA Ruby Conf 2014 - As easy as Rails by Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"LA RubyConf 2014\"\n  date: \"2014-02-08\"\n  published_at: \"2014-04-12\"\n  description: |-\n    Rails came to prominence because it makes web development easy. So easy, in fact, that we're afraid to ask if Rails might be the wrong choice for our web application. Because before Rails, web development was so much more painful and difficult. It turns out that Rails is an awful choice for at least one type of web application: fat-client JavaScript user interfaces. We've been slow to admit this because it's hard to deny the comfort and convenience of the Rails ecosystem. But viewed more broadly, the Ruby ecosystem's client-side tooling has been completely outflanked in the past two years by the tremendous community focus on Node.js and Grunt. In this talk, we'll discuss why building single page apps with Rails isn't as easy as we might assume. We'll uncover the dangers of tangling our front-end UI with our backend-services in a single repository. Finally, I'll demonstrate some of the amazing things that development tools are capable of when JavaScript is treated as a first-class language and when (just like in Rails) we strive to make developers' work easier.\n\n  video_provider: \"youtube\"\n  video_id: \"LiajWwszsc0\"\n\n# Lunch\n\n- id: \"aaron-harpole-la-rubyconf-2014\"\n  title: \"Refactoring Your Team For Fun and Profit\"\n  raw_title: \"LA Ruby Conf 2014 - Refactoring Your Team For Fun and Profit by Aaron Harpole\"\n  speakers:\n    - Aaron Harpole\n  event_name: \"LA RubyConf 2014\"\n  date: \"2014-02-08\"\n  published_at: \"2014-04-12\"\n  description: |-\n    As Rubyists, we see the value in refactoring. When Fullscreen started experiencing serious growth and our team started to grow with it, the excitement and glamour of being a successful startup quickly wore off as a far-reaching engineering initiative began looking insurmountable. In this talk, I will discuss how applying software development best practices to how we ran our team turned it into one that runs at scale, shipping new things more frequently than ever before with less stress than ever.\n\n  video_provider: \"youtube\"\n  video_id: \"lg9EdYyiIeg\"\n\n- id: \"mark-menard-la-rubyconf-2014\"\n  title: \"Write Small Things\"\n  raw_title: \"LA Ruby Conf 2014 - Write Small Things by Mark Menard\"\n  speakers:\n    - Mark Menard\n  event_name: \"LA RubyConf 2014\"\n  date: \"2014-02-08\"\n  published_at: \"2014-04-12\"\n  description: |-\n    \"I didn't have time to write a short letter, so I wrote a long one instead.\" -Mark Twain Writing small classes is hard. You know you should, but how do you actually do it? It's so much easier to write a large class. In this talk we'll build up a set of small classes starting from nothing using a set of directed refactorings applied as we build. All while keeping our classes small. We'll identify abstractions yearning to be free of their big object cages. In the process we'll also see how basic patterns such as composition, delegation and dependency injection emerge from using small objects. We'll even write some tests too.\n\n  video_provider: \"youtube\"\n  video_id: \"A0aZLDaGozM\"\n\n# Break\n\n- id: \"hannah-howard-la-rubyconf-2014\"\n  title: \"Addressing Sexism To Build A Better Ruby Community\"\n  raw_title: \"LA Ruby Conf 2014 - Addressing sexism to build a better Ruby community\"\n  speakers:\n    - Hannah Howard\n    - Evan Dorn\n  event_name: \"LA RubyConf 2014\"\n  date: \"2014-02-08\"\n  published_at: \"2014-04-12\"\n  description: |-\n    By Hannah Howard and Evan Dorn\n\n    Despite programs like RailsBridge and RailsGirls, gender disparities remain a persistent problem in technology. In the last year the coding community has been rocked by several incidents of shockingly overt sexism. The topic is uncomfortable for everyone, and attempts to address it often create new unpleasant conflicts. We will discuss the experiences of women in our community, and address the understandable (but often unhelpful) reactions men have to the issues. We will offer practical strategies and tools to address these issues and create a healthier community. Co-presentation by Evan Dorn and Hannah Howard of Logical Reality Design, Inc.\n\n  video_provider: \"youtube\"\n  video_id: \"xxqIw_oL-Go\"\n\n- id: \"mike-moore-la-rubyconf-2014\"\n  title: \"Writing Games with Ruby\"\n  raw_title: \"LA Ruby Conf 2014 - Writing Games with Ruby by Mike Moore\"\n  speakers:\n    - Mike Moore\n  event_name: \"LA RubyConf 2014\"\n  date: \"2014-02-08\"\n  published_at: \"2014-04-12\"\n  description: |-\n    Creating games is crazy fun and dirt simple with Ruby. You will leave this session with a working game; no previous game development experience necessary. We will introduce basic concepts of game programming and show how to implement them using the Gosu library. This includes the game loop, sprites, animation, camera movement and hit detection. We will build a complete game, so you might want to bring your notebook and follow along.\n\n  video_provider: \"youtube\"\n  video_id: \"jJhbpY70miE\"\n\n# Break\n\n- id: \"mark-bates-la-rubyconf-2014\"\n  title: \"Go For The Rubyist\"\n  raw_title: \"LA Ruby Conf 2014 - Go for the Rubyist by Mark Bates\"\n  speakers:\n    - Mark Bates\n  event_name: \"LA RubyConf 2014\"\n  date: \"2014-02-08\"\n  published_at: \"2014-04-12\"\n  description: |-\n    Why are so many Rubyists buzzing about Go? This hot new language that grew out of Google just a few years ago is taking the world by storm and is generating a lot of buzz in the Ruby community. In this talk we'll look at the highlights of Go and try and figure out what the hype is all about, and we'll do with a keen Rubyist eye. We'll also look at where it would make sense in our Ruby/Rails projects to extend them with this highly concurrent, and performant language. What do you say my fellow Rubyists; are you up for the challenge of learning something a bit different?\n\n  video_provider: \"youtube\"\n  video_id: \"Ukqa5gSE0ig\"\n# Closing remarks (JR Fent, Coby Randquist)\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcya1YRmHi2CLsk6D4J3PhSw8\"\ntitle: \"LA RubyConf 2015\"\nkind: \"conference\"\nlocation: \"Burbank, CA, United States\"\ndescription: |-\n  At the the Holiday Inn Media Center in Burbank, California\npublished_at: \"2015-10-29\"\nstart_date: \"2015-10-10\"\nend_date: \"2015-10-10\"\nwebsite: \"https://web.archive.org/web/20150908052302/https://larubyconf.com/\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\nbanner_background: \"#F1F1F1\"\nfeatured_color: \"#002448\"\nfeatured_background: \"#F1F1F1\"\ncoordinates:\n  latitude: 34.1820605\n  longitude: -118.3074827\naliases:\n  - Los Angeles Ruby Conference 2015\n"
  },
  {
    "path": "data/la-rubyconf/la-rubyconf-2015/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20150928124321/https://larubyconf.com\n# Schedule: https://web.archive.org/web/20150928124321/https://larubyconf.com/schedules\n\n## Day 1 - October 10, 2015\n\n# Registration\n\n# Welcome and Introduction\n\n- id: \"mike-moore-la-rubyconf-2015\"\n  title: \"Build to Last: How to design rails apps to avoid a rewrite in 5 years\"\n  raw_title: \"LA RubyConf 2015- Build to Last... by Mike Moore\"\n  speakers:\n    - Mike Moore\n  event_name: \"LA RubyConf 2015\"\n  date: \"2014-10-10\"\n  published_at: \"2015-10-29\"\n  description: |-\n    Build to Last: How to design rails apps to avoid a rewrite in 5 years\n  video_provider: \"youtube\"\n  video_id: \"8YUed3l2BZY\"\n\n# Break\n\n- id: \"ylan-segal-la-rubyconf-2015\"\n  title: \"Practical Unix for Ruby & Rails\"\n  raw_title: \"LA RubyConf 2015- Practical Unix for Ruby & Rails by Ylan Segal\"\n  speakers:\n    - Ylan Segal\n  event_name: \"LA RubyConf 2015\"\n  date: \"2014-10-10\"\n  published_at: \"2015-10-29\"\n  description: |-\n    Practical Unix for Ruby & Rails\n\n    The Unix command-line interface is much more than a way to generate and run Rails migrations. It offers a myriad of tools that make it easy to work with text files, large and small. It is the original embodiment of the 'build small things' philosophy. Experience a boost in productivity by using the powerful tools already at your disposal.\n  video_provider: \"youtube\"\n  video_id: \"yptv5R5koeI\"\n\n# Break\n\n- id: \"michael-hartl-la-rubyconf-2015\"\n  title: \"Learn Enough Tutorial Writing to Be Dangerous\"\n  raw_title: \"LA RubyConf 2015- Learn Enough Tutorial Writing to Be Dangerous by Michael Hartl\"\n  speakers:\n    - Michael Hartl\n  event_name: \"LA RubyConf 2015\"\n  date: \"2014-10-10\"\n  published_at: \"2015-10-29\"\n  description: |-\n    Learn Enough Tutorial Writing to Be Dangerous\n\n    This talk discusses some time-tested techniques for producing effective tutorials, focusing on telling stories via long-form technical narrative. Topics include motivation & structure, the process of successive refinement (including the \"comb-over principle\"), and tricks of the trade for using neurological hacks and navigating large text files. The audience will leave with a stronger grasp of how to make tutorials that keep a reader's interest while instructing gracefully and effectively.\n  video_provider: \"youtube\"\n  video_id: \"TpmoxsYeap0\"\n\n# Break\n\n- id: \"adam-cuppy-la-rubyconf-2015\"\n  title: \"What If Shakespeare Wrote Ruby?\"\n  raw_title: \"LA RubyConf 2015- What If Shakespeare Wrote Ruby by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"LA RubyConf 2015\"\n  date: \"2014-10-10\"\n  published_at: \"2015-10-29\"\n  description: |-\n    What If Shakespeare Wrote Ruby\n\n    Did you know that Shakespeare wrote almost no direction into his plays? No fight direction. No staging. No notes to the songs. Of the 1700 words he created, there was no official dictionary. That’s right the author of some of the greatest literary works in history, which were filled with situational complexity, fight sequences and music, include NO documentation! How did he do it? In this talk, we're going \"thee and thou.\" I'm going to give you a crash course in how: Shakespeare writes software.\n\n  video_provider: \"youtube\"\n  video_id: \"nyx6YF4XSpE\"\n\n# Lunch\n\n- id: \"johnnyt-la-rubyconf-2015\"\n  title: \"Data Migrations with MagLev\"\n  raw_title: \"LA RubyConf 2015- Data Migrations with MagLev by JohnnyT\"\n  speakers:\n    - JohnnyT\n  event_name: \"LA RubyConf 2015\"\n  date: \"2014-10-10\"\n  published_at: \"2015-10-29\"\n  description: |-\n    Data Migrations with MagLev\n\n    MagLev is a Ruby implementation built on top of a VM which offers native object persistence - you are able to persist plain Ruby objects (including procs and lambdas) and then see and use them from any other connected VM. We are now using MagLev in production and have already learned some good lessons on working with and migrating these committed objects long term. Come and hear about recent MagLev updates and and appreciate the following quote on another level:  I always knew that one day Smalltalk would replace Java. I just didn't know it would be called Ruby. -- Kent Beck\n  video_provider: \"youtube\"\n  video_id: \"32gjrn3LPFQ\"\n\n# Break\n\n- id: \"aja-hammerly-la-rubyconf-2015\"\n  title: \"Stupid Ideas For Many Computers\"\n  raw_title: \"LA RubyConf 2015- Stupid Ideas For Many Computers by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"LA RubyConf 2015\"\n  date: \"2014-10-10\"\n  published_at: \"2015-10-29\"\n  slides_url: \"https://thagomizer.com/files/Stupid_LaRubyConf15.pdf\"\n  description: |-\n    Stupid Ideas For Many Computers\n\n    There are plenty of useful things you can do with Ruby and a bunch of servers. This talk isn't about useful things. This talk will show off asinine, amusing, and useless things you can do with Ruby and access to cloud computing. Sentiment analysis based on emoji? Why not? Hacky performance testing frameworks? Definitely! Multiplayer infinite battleship? Maybe? The world's most inefficient logic puzzle solver? Awesome! If you are interested in having some fun and laughing at reasonable code for unreasonable problems this talk is for you.\n\n  video_provider: \"youtube\"\n  video_id: \"wqkWKrNW68A\"\n\n# Break\n\n- id: \"austin-fonacier-la-rubyconf-2015\"\n  title: \"Hacking Development Culture: Treating Developers As People\"\n  raw_title: \"LA RubyConf 2015- Hacking Development Culture: Treating Developers As People by Austin Fonacier\"\n  speakers:\n    - Austin Fonacier\n  event_name: \"LA RubyConf 2015\"\n  date: \"2014-10-10\"\n  published_at: \"2015-10-29\"\n  description: |-\n    Hacking Development Culture: Treating Developers As People\n\n    I work at a growing company where the main \"money-making\" app was a monolithic and upgraded over time from a Ruby on Rails 1 codebase. Working in a fast moving startup where stopping for six months to rewrite is NOT an option. The development culture at the time revolved around simply passing QA and getting features out the door. On top of that, finding seasoned Rails developers to help mend the codebase are rare and hard to hire. All or any of this sound familiar? This is our story of how I balanced and satisfied management's requirements of getting new features out the door but at the same time shaping a rag tag group of developers and turned us into a well oiled machine where now code-quality, code reviews, pair programming, and test driven development are part of the development culture.\n\n  video_provider: \"youtube\"\n  video_id: \"z5zll50fRJA\"\n\n# Break\n\n- id: \"lito-nicolai-la-rubyconf-2015\"\n  title: \"Botany with Bytes\"\n  raw_title: \"LA RubyConf 2015- Botany with Bytes by Lito Nicolai\"\n  speakers:\n    - Lito Nicolai\n  event_name: \"LA RubyConf 2015\"\n  date: \"2014-10-10\"\n  published_at: \"2015-10-29\"\n  description: |-\n    Botany with Bytes\n\n    Plants are tiny computers. As they grow, the sprouts are computing from first principles how to be a plant. We’ll see how they do it! This talk uses Ruby and the ‘graphics’ gem to build models of all kinds of plants, from algae blooms to juniper branches. We’ll touch on rewriting systems, formal grammars, and Alan Turing’s contributions to botany. We’ll look at the shapes of euphorbia, artichoke, and oregon grape, and how these come from plants’ love of sunlight and greedy desire for growth. By the end, we'll have a series of great visual metaphors for fundamental computer science concepts!\n\n  video_provider: \"youtube\"\n  video_id: \"OzkZJTp9jNI\"\n\n# Break\n\n- id: \"ryan-davis-la-rubyconf-2015\"\n  title: \"Mind of a Hacker\"\n  raw_title: \"LA RubyConf 2015- Mind of a Hacker by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"LA RubyConf 2015\"\n  date: \"2014-10-10\"\n  published_at: \"2015-10-29\"\n  description: |-\n    Mind of a Hacker\n\n  video_provider: \"youtube\"\n  video_id: \"vcsKFsxAIOE\"\n# Closing Notes\n"
  },
  {
    "path": "data/la-rubyconf/series.yml",
    "content": "---\nname: \"Los Angeles RubyConf\"\nwebsite: \"https://web.archive.org/web/20180626035953/https://www.larubyconf.com/\"\ntwitter: \"larubyconf\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"LA RubyConf\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\naliases:\n  - LA RubyConf\n  - LA Ruby Conf\n  - Los Angeles Ruby Conf\n"
  },
  {
    "path": "data/latvian-ruby-community/latviarb-meetup/event.yml",
    "content": "---\nid: \"latviarb-meetup\"\ntitle: \"Latvia.rb Meetup\"\nlocation: \"Riga, Latvia\"\ndescription: |-\n  A meetup group centering around the Ruby programming language.\nkind: \"meetup\"\nyear: 2024\nbanner_background: |-\n  linear-gradient(to bottom, #FF0E2C, #FF0E2C 100%) left top / 50% 100% no-repeat, /* Left side */\n  linear-gradient(to bottom, #2A00D5, #2A00D5 100%) right top / 50% 100% no-repeat /* Right side */\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://lu.ma/latviarb\"\ncoordinates:\n  latitude: 56.9676941\n  longitude: 24.1056221\n"
  },
  {
    "path": "data/latvian-ruby-community/latviarb-meetup/videos.yml",
    "content": "---\n- id: \"latviarb-december-2024\"\n  title: \"Latvian Ruby Community Meetup December 2024\"\n  event_name: \"Latvian Ruby Community Meetup December 2024\"\n  date: \"2024-12-17\"\n  video_provider: \"children\"\n  video_id: \"latviarb-december-2024\"\n  description: |-\n    Save the date and get ready to celebrate! Join us on Tuesday, December 17th, at 5:00 PM for this year's final Latvian Ruby community meetup. This time, we're gathering at a different location - the Minox event space at Teikums. It will be a festive evening filled with insightful talks from guest speakers, a sneak peek into what's coming in 2025, and plenty of good cheer.\n\n    ​Agenda\n    5:00 PM: Networking\n    6:00 PM: Kick off\n    RubyEurope, Janis Baiza\n    Baltic Ruby news, Ali Krynitsky, Host of BalticRuby\n    6:15 PM: Rspec::Llama one tool to fit all your LLMs\n    Sergy Sergyenko, CEO at Cybergizer, AI + Ruby enthusiast\n    Rspec::Llama is a versatile testing framework designed to integrate AI model testing seamlessly into the RSpec ecosystem. Whether you're working with OpenAI's GPT models, Llama, or other AI models, RSpec::Llama simplifies the process of configuring, running, and validating your models' outputs, and implementing LLM-as-a-Judge pattern.\n    7:00 PM: Steven R. Baker\n    7:45 PM: Networking\n\n    ​Whether you're a Ruby enthusiast or just curious, this is the perfect chance to connect with fellow techies, share ideas, and enjoy some holiday spirit. So, dust off your favorite holiday sweater, bring your curiosity, and let's make this meetup a memorable one. See you there!\n\n    https://lu.ma/lzhx6jnz\n  talks:\n    - title: \"Rspec::Llama one tool to fit all your LLMs\"\n      event_name: \"Latvian Ruby Community Meetup December 2024\"\n      date: \"2024-12-17\"\n      speakers:\n        - Sergy Sergyenko\n      id: \"sergy-sergyenko-latviarb-december-2024\"\n      video_id: \"sergy-sergyenko-latviarb-december-2024\"\n      video_provider: \"not_recorded\"\n      description: \"\"\n\n    - title: \"Talk by Steven Baker\"\n      event_name: \"Latvian Ruby Community Meetup December 2024\"\n      date: \"2024-12-17\"\n      speakers:\n        - Steven Baker\n      id: \"steven-baker-latviarb-december-2024\"\n      video_id: \"steven-baker-latviarb-december-2024\"\n      video_provider: \"not_recorded\"\n      description: \"\"\n\n- id: \"latviarb-february-2025\"\n  title: \"Latvian Ruby Community Meetup February 2025\"\n  event_name: \"Latvian Ruby Community Meetup February 2025\"\n  date: \"2025-02-11\"\n  video_provider: \"children\"\n  video_id: \"latviarb-february-2025\"\n  description: |-\n    ​Hey, Ruby enthusiasts!\n\n    ​You are welcome to the first event of 2025 on Tuesday, February 11th, at 18:00, at Levelpath Office – Gustava Zemgala gatve 74, building Teodors, entrance A, 6th floor\n\n    ​Agenda:\n    18:00 Networking\n    18:30 Kickoff\n    18:40 Arturs Mekss will tell us about his journey in Rails boot profiling\n\n    ​Plus, we have an open spot for a speaker, so if you have some Ruby wisdom to share, let us know!\n\n    ​Whether you're a seasoned Rubyist or just starting your journey, this is the perfect chance to mingle with fellow developers, share insights, and maybe even pick up a few new tricks.\n\n    https://lu.ma/5oqjsofh\n  talks:\n    - title: \"My journey in Rails boot profiling\"\n      event_name: \"Latvian Ruby Community Meetup February 2025\"\n      date: \"2025-02-11\"\n      speakers:\n        - Arturs Mekss\n      id: \"arturs-mekss-latviarb-february-2025\"\n      video_id: \"arturs-mekss-latviarb-february-2025\"\n      video_provider: \"not_recorded\"\n      description: \"\"\n\n- id: \"latviarb-april-2025\"\n  title: \"Latvian Ruby Community Meetup April 2025\"\n  event_name: \"Latvian Ruby Community Meetup April 2025\"\n  date: \"2025-04-03\"\n  video_provider: \"children\"\n  video_id: \"latviarb-april-2025\"\n  description: |-\n    ​Hey, Ruby enthusiasts!\n\n    ​​You are welcome to the second event of 2025 on Thursday, April 3rd, at 18:15, at Levelpath Office – Gustava Zemgala gatve 74, building Teodors, entrance A, 6th floor\n\n    ​This event will be a new experience as we will have a cross-meetup broadcast with VilniusRB! Gathering, chatting, and discussions on the Riga side with beers and snacks as usually included! Entrance free!\n\n    ​There will be two deep-dive talks!\n\n    ​ \"A tale of three chat servers\"\n    Thijs Cadier (AppSignal, Netherlands) will unravel how Ruby handles multiple tasks at once, comparing Puma vs. Unicorn, explaining ActionCable’s event-driven approach, and breaking down the underlying mechanics.\n    ​​\"TDD 2.0: AI Brings Test-Driven Development Back on Track\"\n    Sergy Sergyenko (Cybergizer, Lithuania) will explore how AI is revolutionizing TDD, making testing faster and smarter with tools like RSpec-llama. Expect real-world insights, a live demo, and practical takeaways for integrating AI into your workflow.\n\n    We'll also hear the latest updates about the Baltic Ruby conference happening in June in Riga.\n    ​Join us and don’t forget to share the news with your friends and on your socials!\n\n    ​As usual, we're always looking for speakers on topics large or small, long or short. Please get in touch.\n\n    https://lu.ma/939q9twh\n  talks:\n    - title: \"A tale of three chat servers\"\n      event_name: \"Latvian Ruby Community Meetup April 2025\"\n      date: \"2025-04-03\"\n      speakers:\n        - Thijs Cadier\n      id: \"thijs-cadier-latviarb-april-2025\"\n      video_id: \"thijs-cadier-latviarb-april-2025\"\n      video_provider: \"not_recorded\"\n      description: \"\"\n\n    - title: \"TDD 2.0: AI Brings Test-Driven Development Back on Track\"\n      event_name: \"Latvian Ruby Community Meetup April 2025\"\n      date: \"2025-04-03\"\n      speakers:\n        - Sergy Sergyenko\n      id: \"sergy-sergyenko-latviarb-april-2025\"\n      video_id: \"sergy-sergyenko-latviarb-april-2025\"\n      video_provider: \"not_recorded\"\n      description: \"\"\n\n- id: \"latviarb-may-2025\"\n  title: \"Latvian Ruby Community Meetup May 2025\"\n  event_name: \"Latvian Ruby Community Meetup May 2025\"\n  date: \"2025-05-15\"\n  video_provider: \"children\"\n  video_id: \"latviarb-may-2025\"\n  thumbnail_xs: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=400,height=400/gallery-images/87/247532fb-2a79-4de4-91b1-752855f5b1b8\"\n  thumbnail_sm: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=400,height=400/gallery-images/87/247532fb-2a79-4de4-91b1-752855f5b1b8\"\n  thumbnail_md: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=400,height=400/gallery-images/87/247532fb-2a79-4de4-91b1-752855f5b1b8\"\n  thumbnail_lg: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=1280,height=1280/gallery-images/87/247532fb-2a79-4de4-91b1-752855f5b1b8\"\n  thumbnail_xl: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,background=white,quality=75,width=1280,height=1280/gallery-images/87/247532fb-2a79-4de4-91b1-752855f5b1b8\"\n  description: |-\n    ​Hello, dear Ruby friends!\n\n    ​Summer and Baltic Ruby in Riga are approaching very fast. Join us for the Baltic Ruby community meetup at Tallinas Kvartāla Angārs!\n\n    ​​Agenda\n    6:00 PM: Networking\n    6:30 PM: Kick off\n    Baltic Ruby news, Ali Krynitsky, Host of BalticRuby\n    6:45 PM: Marco Roth - Hotwire, Turbo, Stimulus - contributor and maintainer\n    7:45 PM: Sergy Sergyenko will lead an AI Coding workshop \"Test Driven Generation: VibeCoding for Unit Testing\".\n\n    ​Everyone is welcome - bring your questions, ideas, and good vibes. Don’t miss out on a friendly evening with Baltic Ruby enthusiasts. Sign up and be part of the community!\n\n    https://lu.ma/e34lm6hq\n  talks:\n    - title: \"Intro & BalticRuby News\"\n      event_name: \"Latvian Ruby Community Meetup May 2025\"\n      date: \"2025-05-15\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GrAGpuwXcAA4rPo?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GrAGpuwXcAA4rPo?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GrAGpuwXcAA4rPo?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GrAGpuwXcAA4rPo?format=jpg&name=4096x4096\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GrAGpuwXcAA4rPo?format=jpg&name=4096x4096\"\n      speakers:\n        - Ali Krynitsky\n      id: \"ali-krynitsky-latviarb-may-2025\"\n      video_id: \"ali-krynitsky-latviarb-may-2025\"\n      video_provider: \"not_recorded\"\n\n    - title: \"Empowering Developers with HTML-Aware ERB Tooling\"\n      event_name: \"Latvian Ruby Community Meetup May 2025\"\n      date: \"2025-05-15\"\n      speakers:\n        - Marco Roth\n      id: \"marco-roth-latviarb-may-2025\"\n      video_id: \"marco-roth-latviarb-may-2025\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GrAHWmqXQAA4NHD?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GrAHWmqXQAA4NHD?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GrAHWmqXQAA4NHD?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GrAHWmqXQAA4NHD?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GrAHWmqXQAA4NHD?format=jpg&name=large\"\n      slides_url: \"https://speakerdeck.com/marcoroth/empowering-developers-with-html-aware-erb-tooling-at-latvian-ruby-community-meetup-may-2025-riga-latvia\"\n      description: |-\n        ERB tooling has lagged behind modern web development needs, especially with the rise of Hotwire and HTML-over-the-wire. Discover a new HTML-aware ERB parser that unlocks advanced developer tools like formatters, linters, and LSP integrations, transforming how we build and ship HTML in our Ruby applications.\n\n    - title: \"Test Driven Generation: VibeCoding for Unit Testing\"\n      event_name: \"Latvian Ruby Community Meetup May 2025\"\n      date: \"2025-05-15\"\n      speakers:\n        - Sergy Sergyenko\n      id: \"sergey-sergyenko-latviarb-may-2025\"\n      video_id: \"sergey-sergyenko-latviarb-may-2025\"\n      video_provider: \"not_recorded\"\n      description: \"\"\n"
  },
  {
    "path": "data/latvian-ruby-community/series.yml",
    "content": "---\nname: \"Latvian Ruby Community\"\nwebsite: \"https://lu.ma/latviarb\"\ntwitter: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"LV\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/london-ruby-unconference/london-ruby-unconference-2016/event.yml",
    "content": "---\nid: \"london-ruby-unconference-2016\"\ntitle: \"London Ruby Unconference 2016\"\ndescription: \"\"\nlocation: \"London, UK\"\nkind: \"conference\"\nstart_date: \"2016-10-22\"\nend_date: \"2016-10-22\"\nwebsite: \"http://www.eventbrite.com/e/london-ruby-unconference-tickets-27663867372?aff=github\"\ntwitter: \"rubyunconf\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/london-ruby-unconference/london-ruby-unconference-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.eventbrite.com/e/london-ruby-unconference-tickets-27663867372?aff=github\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/london-ruby-unconference/london-ruby-unconference-2017/event.yml",
    "content": "---\nid: \"london-ruby-unconference-2017\"\ntitle: \"London Ruby Unconference 2017\"\ndescription: \"\"\nlocation: \"London, UK\"\nkind: \"conference\"\nstart_date: \"2017-10-07\"\nend_date: \"2017-10-07\"\nwebsite: \"https://www.eventbrite.com/e/london-ruby-unconference-tickets-36286901098?aff=rubyconferences\"\ntwitter: \"rubyunconf\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/london-ruby-unconference/london-ruby-unconference-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://www.eventbrite.com/e/london-ruby-unconference-tickets-36286901098?aff=rubyconferences\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/london-ruby-unconference/london-ruby-unconference-2019/event.yml",
    "content": "---\nid: \"london-ruby-unconference-2019\"\ntitle: \"London Ruby Unconference 2019\"\ndescription: \"\"\nlocation: \"London, UK\"\nkind: \"conference\"\nstart_date: \"2019-10-19\"\nend_date: \"2019-10-07\"\nwebsite: \"http://rubyunconf.uk\"\ntwitter: \"rubyunconf\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/london-ruby-unconference/london-ruby-unconference-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyunconf.uk\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/london-ruby-unconference/series.yml",
    "content": "---\nname: \"London Ruby Unconference\"\nwebsite: \"http://www.eventbrite.com/e/london-ruby-unconference-tickets-27663867372?aff=github\"\ntwitter: \"rubyunconf\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2008/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybMA_ncEV_0UYwollGNzopO\"\ntitle: \"LoneStarRuby Conf 2008\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: |-\n  September 4-6, 2008 - Austin, Texas\npublished_at: \"2008-09-04\"\nstart_date: \"2008-09-04\"\nend_date: \"2008-09-06\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2008\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2008/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"bruce-williams-lonestarruby-conf-2008\"\n  title: \"The Next Ruby\"\n  raw_title: \"LoneStarRuby Conf 2008 - The Next Ruby 960x368 by: Bruce Williams\"\n  speakers:\n    - Bruce Williams\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-04-14\"\n  description: |-\n    The Next Ruby 960x368 by: Bruce Williams\n\n  video_provider: \"youtube\"\n  video_id: \"q5Fe59o7VtY\"\n\n- id: \"james-edward-gray-ii-lonestarruby-conf-2008\"\n  title: \"Hidden Gems\"\n  raw_title: \"LoneStarRuby Conf 2009 - ii hidden gems 960x368 by: James Edward Gray\"\n  speakers:\n    - James Edward Gray II\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-04-14\"\n  description: |-\n    hidden gems 960x368 by: James Edward Gray II\n\n  video_provider: \"youtube\"\n  video_id: \"2j9jZu-72yY\"\n\n- id: \"rein-henrichs-lonestarruby-conf-2008\"\n  title: \"Ruby Best Practice Patterns\"\n  raw_title: \"LoneStarRuby Conf 2009 - ruby best practice patterns 960x368 by: Rein Henrichs\"\n  speakers:\n    - Rein Henrichs\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-04-14\"\n  description: |-\n    ruby best practice patterns 960x368 by: Rein Henrichs\n\n  video_provider: \"youtube\"\n  video_id: \"_nMZvXG3ZBU\"\n\n- id: \"jake-scruggs-lonestarruby-conf-2008\"\n  title: \"Using Metrics To Take a Hard Look at Your Code\"\n  raw_title: \"LoneStarRuby Conf 2008 - Using Metrics to Take a Hard look at your code by: Jake Scruggs\"\n  speakers:\n    - Jake Scruggs\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-04-14\"\n  description: |-\n    04 jake scruggs using metrics to take a hard look at your code 960x368\n\n  video_provider: \"youtube\"\n  video_id: \"FnDvacKHufU\"\n\n- id: \"wynn-netherland-lonestarruby-conf-2008\"\n  title: \"JavaScript Frameworks with Ruby\"\n  raw_title: \"LoneStarRuby Conf 2008 - JavaScript Frameworks with Ruby 960x368 by: Wynn Netherland\"\n  speakers:\n    - Wynn Netherland\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-04-14\"\n  description: |-\n    JavaScript Frameworks with Ruby 960x368 by: Wynn Netherland\n\n  video_provider: \"youtube\"\n  video_id: \"kb4XOImtshE\"\n\n- id: \"eric-mahurin-lonestarruby-conf-2008\"\n  title: \"Grammar a BNF Like Ruby DSL Parsing\"\n  raw_title: \"LoneStarRuby Conf 2008 - Grammar a BNF like Ruby DSL Parsing 960x368 by: Eric Mahurin\"\n  speakers:\n    - Eric Mahurin\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Grammar a BNF like Ruby DSL Parsing 960x368 by: Eric Mahurin\n\n  video_provider: \"youtube\"\n  video_id: \"QDho1BymBIQ\"\n\n- id: \"mike-subelsky-lonestarruby-conf-2008\"\n  title: \"Ruby in the Cloud\"\n  raw_title: \"LoneStarRuby Conf 2008 - Ruby in the Cloud by: Mike Subelsky\"\n  speakers:\n    - Mike Subelsky\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Ruby in the Cloud by: Mike Subelsky\n\n  video_provider: \"youtube\"\n  video_id: \"U3ByT_9OZgw\"\n\n- id: \"tod-beardsley-lonestarruby-conf-2008\"\n  title: \"Packet-Fu with Ruby\"\n  raw_title: \"LoneStar RubyConf 2008 -  Packet -Fu with Ruby\"\n  speakers:\n    - Tod Beardsley\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Packet -Fu with Ruby  by: Tod Beardsley\n  video_provider: \"youtube\"\n  video_id: \"CjsSunV-wVk\"\n\n- id: \"yehuda-katz-lonestarruby-conf-2008\"\n  title: \"Using jQuery with Ruby Web Frameworks\"\n  raw_title: \"LoneStar RubyConf 2008 - Using Jquery with Ruby Web Frameworks\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Using Jquery with Ruby Web Frameworks by: Yehuda Katz\n  video_provider: \"youtube\"\n  video_id: \"GJAa7qSfaIw\"\n\n- id: \"james-w-mcguffee-lonestarruby-conf-2008\"\n  title: \"Ruby in the Computer Science Classroom\"\n  raw_title: \"LoneStar RubyConf 2008 - Ruby in the Computer Science Classroom\"\n  speakers:\n    - James W. McGuffee\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Ruby in the Computer Science Classroom by: James W. McGuffee\n  video_provider: \"youtube\"\n  video_id: \"xTS3oBAQmoU\"\n\n- id: \"dan-yoder-lonestarruby-conf-2008\"\n  title: \"Resource Driven Web Development with Waves\"\n  raw_title: \"LoneStar RubyConf 2008 - Resource Driven Web Development with Waves\"\n  speakers:\n    - Dan Yoder\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Resource Driven Web Development with Waves by: Dan Yoder\n  video_provider: \"youtube\"\n  video_id: \"jmxbDT_rOos\"\n\n- id: \"francis-sullivan-lonestarruby-conf-2008\"\n  title: \"Tips and Tricks for Tweaking and Using Ruby and Rails for a Distributed Enterprise Application\"\n  raw_title: \"LoneStar RubyConf 2008 - Tips and Tricks for Tweaking and Using Ruby and Rails...\"\n  speakers:\n    - Francis Sullivan\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Tips and Tricks for Tweaking and Using Ruby and Rails for a Distributed Enterprise Application  by: Francis Sullivan\n  video_provider: \"youtube\"\n  video_id: \"uY5uSOfH5TM\"\n\n- id: \"lance-carlson-lonestarruby-conf-2008\"\n  title: \"Ruby Anvil - The Desktop Application Framework\"\n  raw_title: \"LoneStar RubyConf 2008 - Ruby Anvil the Desktop Application Framework\"\n  speakers:\n    - Lance Carlson\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Ruby Anvil the Desktop Application Framework by: Lance Carlson\n  video_provider: \"youtube\"\n  video_id: \"1fyFBEsozoY\"\n\n- id: \"mike-perham-lonestarruby-conf-2008\"\n  title: \"How Not to Build a Service\"\n  raw_title: \"LoneStar RubyConf 2008 - How Not to Build a Service\"\n  speakers:\n    - Mike Perham\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    How Not to Build a Service by: Mike Perham\n  video_provider: \"youtube\"\n  video_id: \"U8V9Vj0AsQ0\"\n\n- id: \"david-richards-lonestarruby-conf-2008\"\n  title: \"Scientific Computing with Ruby Tegu (formerly GSA)\"\n  raw_title: \"LoneStar RubyConf 2008 - Scientific Computing with Ruby Tegu (formerly GSA)\"\n  speakers:\n    - David Richards\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Scientific Computing with Ruby Tegu (formerly GSA) by: David Richards\n  video_provider: \"youtube\"\n  video_id: \"rSOvviv2L5s\"\n\n- id: \"yehuda-katz-lonestarruby-conf-2008-merb-the-pocket-rocket-framewo\"\n  title: \"Merb the Pocket Rocket Framework\"\n  raw_title: \"LoneStar RubyConf 2008 - Merb the Pocket Rocket Framework\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Merb the Pocket Rocket Framework by: Yehuda Katz\n  video_provider: \"youtube\"\n  video_id: \"G6Ygl8w2Jl8\"\n\n- id: \"jeffery-l-taylor-lonestarruby-conf-2008\"\n  title: \"What's Ruby Doing in a Java IDE like NetBeans? Lots!\"\n  raw_title: \"LoneStar RubyConf 2008 - What's Ruby Doing in a Java IDE like NetBeans? Lots!\"\n  speakers:\n    - Jeffery L. Taylor\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    What's Ruby Doing in a Java IDE like NetBeans? Lots! by: Jeffery L. Taylor\n  video_provider: \"youtube\"\n  video_id: \"VJfpLOzUY2w\"\n\n- id: \"jim-mulholland-lonestarruby-conf-2008\"\n  title: \"Ruby and Virtual Teams\"\n  raw_title: \"LoneStar RubyConf 2008 - Ruby and Virtual Teams\"\n  speakers:\n    - Jim Mulholland\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Ruby and Virtual Teams by: Jim Mulholland\n  video_provider: \"youtube\"\n  video_id: \"hf6gwplSqJ8\"\n\n- id: \"matthew-todd-lonestarruby-conf-2008\"\n  title: \"Ruby Without Borders\"\n  raw_title: \"LoneStar RubyConf 2008 - Ruby Wwithout Borders\"\n  speakers:\n    - Matthew Todd\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Ruby Wwithout Borders by: Matthew Todd\n  video_provider: \"youtube\"\n  video_id: \"gpkzz6rpLQs\"\n\n- id: \"glenn-vanderburg-lonestarruby-conf-2008\"\n  title: \"Tactical Design\"\n  raw_title: \"LoneStar RubyConf 2008 - Tactical Design\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Tactical Design by: Glenn Vanderburg\n  video_provider: \"youtube\"\n  video_id: \"LeZq6WoVzgY\"\n\n- id: \"steve-sanderson-lonestarruby-conf-2008\"\n  title: \"Care and Feeding of Ruby Developers\"\n  raw_title: \"LoneStar RubyConf 2008 - Care and Feeding of Ruby Developers\"\n  speakers:\n    - Steve Sanderson\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Care and Feeding of Ruby Developers by: Steve Sanderson\n  video_provider: \"youtube\"\n  video_id: \"hr6IEUhDDHw\"\n\n- id: \"brian-cooke-lonestarruby-conf-2008\"\n  title: \"Creating Desktop Applications with Ruby on Mac\"\n  raw_title: \"LoneStar RubyConf 2008 - Creating Desktop Applications with Ruby on Mac\"\n  speakers:\n    - Brian Cooke\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Creating Desktop Applications with Ruby on Mac by: Brian Cooke\n  video_provider: \"youtube\"\n  video_id: \"NzRe9k-8778\"\n\n- id: \"jeremy-hinegardner-lonestarruby-conf-2008\"\n  title: \"Building and Managing a Ruby Infrastructure\"\n  raw_title: \"LoneStar RubyConf 2008 -  Building and Managing a Ruby Infrastructure\"\n  speakers:\n    - Jeremy Hinegardner\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Building and Managing a Ruby Infrastructure by: Jeremy Hinegardner and Fernand Galiana\n  video_provider: \"youtube\"\n  video_id: \"RhQddyFY2fY\"\n\n- id: \"bruce-tate-lonestarruby-conf-2008\"\n  title: \"Unconventional Wisdom\"\n  raw_title: \"LoneStar RubyConf 2008 - Unconventional Wisdom\"\n  speakers:\n    - Bruce Tate\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Unconventional Wisdom by: Bruce Tate\n  video_provider: \"youtube\"\n  video_id: \"UTdxpYlyolA\"\n\n- id: \"evan-phoenix-lonestarruby-conf-2008\"\n  title: \"Double Click to Wow\"\n  raw_title: \"LoneStar RubyConf 2008 -  Double Click to Wow\"\n  speakers:\n    - Evan Phoenix\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Double Click to Wow by: Evan Phoenix\n  video_provider: \"youtube\"\n  video_id: \"SXNOdABrUFs\"\n\n- id: \"yukihiro-matz-matsumoto-lonestarruby-conf-2008\"\n  title: \"Ruby Past Present and Future\"\n  raw_title: \"LoneStar RubyConf 2008 -  Ruby Past Present and Future\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"LoneStarRuby Conf 2008\"\n  date: \"2008-09-04\"\n  published_at: \"2015-05-05\"\n  description: |-\n    Ruby Past Present and Future by: yukihiro Matsumoto 'Matz'\n  video_provider: \"youtube\"\n  video_id: \"2OvLO9jYeI8\"\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2009/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaLkdalB5pBAaDEFTFKQfXk\"\ntitle: \"LoneStarRuby Conf 2009\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: |-\n  August 27-29, 2009 - Norris Conference Center Austin, TX\npublished_at: \"2009-08-27\"\nstart_date: \"2009-08-27\"\nend_date: \"2009-08-29\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2009\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2009/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"tim-c-harper-lonestarruby-conf-2009\"\n  title: \"Spork\"\n  raw_title: \"Lone Star RubyConf 2009 - Spork by: Tim C. Harper\"\n  speakers:\n    - Tim C. Harper\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Spork by: Tim C. Harper\n\n  video_provider: \"youtube\"\n  video_id: \"Ck_q-JSoU7Q\"\n\n- id: \"glenn-vanderburg-lonestarruby-conf-2009\"\n  title: \"Programming Intuition\"\n  raw_title: \"Lone Star RubyConf 2009 - Programming Intuition by: Glenn Vanderburg\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Programming Intuition by: Glenn Vanderburg\n  video_provider: \"youtube\"\n  video_id: \"niHxocO6yb4\"\n\n- id: \"james-edward-gray-ii-lonestarruby-conf-2009\"\n  title: \"Module Magic\"\n  raw_title: \"Lone Star RubyConf 2009 - Module Magic by: James Edward Gray II\"\n  speakers:\n    - James Edward Gray II\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Module Magic by: James Edward Gray II\n  video_provider: \"youtube\"\n  video_id: \"IeR1FQ44h7s\"\n\n- id: \"fernand-galiana-lonestarruby-conf-2009\"\n  title: \"R-House\"\n  raw_title: \"Lone Star RubyConf 2009 - R-House by: Fernand Galiana\"\n  speakers:\n    - Fernand Galiana\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    R-House by: Fernand Galiana\n  video_provider: \"youtube\"\n  video_id: \"Nxa9t2R198o\"\n\n- id: \"mike-subelsky-lonestarruby-conf-2009\"\n  title: \"Ruby for Startups\"\n  raw_title: \"Lone Star RubyConf 2009 - Ruby for Startups by: Mike Subelsky\"\n  speakers:\n    - Mike Subelsky\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Ruby for Startups by: Mike Subelsky\n  video_provider: \"youtube\"\n  video_id: \"sOPiRx1gi88\"\n\n- id: \"mike-perham-lonestarruby-conf-2009\"\n  title: \"Checking Under The Hood: A Guide to Rails Engines\"\n  raw_title: \"Lone Star RubyConf 2009 - Checking under the Hood: A guide to Rails Engines by: Mike Perham\"\n  speakers:\n    - Mike Perham\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Checking under the Hood: A guide to Rails Engines by: Mike Perham\n  video_provider: \"youtube\"\n  video_id: \"tfSFEhuc8IU\"\n\n- id: \"ian-warshak-lonestarruby-conf-2009\"\n  title: \"Rails in the Cloud\"\n  raw_title: \"Lone Star RubyConf 2009 - Rails in the Cloud by: Ian Warshak\"\n  speakers:\n    - Ian Warshak\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Rails in the Cloud by: Ian Warshak\n\n  video_provider: \"youtube\"\n  video_id: \"-PdupLZ5q9Q\"\n\n- id: \"larry-diehl-lonestarruby-conf-2009\"\n  title: \"Dataflow: Declarative Concurrency in Rails\"\n  raw_title: \"Lone Star RubyConf 2009 - Dataflow: declarative concurrency in rails by: Larry Diehl\"\n  speakers:\n    - Larry Diehl\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Dataflow: declarative concurrency in rails by: Larry Diehl\n\n  video_provider: \"youtube\"\n  video_id: \"60UzE8_-V6E\"\n\n- id: \"grant-schofield-lonestarruby-conf-2009\"\n  title: \"Walking in the Clouds\"\n  raw_title: \"Lone Star RubyConf 2009 - Walking in the Clouds by: Grant Schofield\"\n  speakers:\n    - Grant Schofield\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Walking in the Clouds by: Grant Schofield\n\n  video_provider: \"youtube\"\n  video_id: \"F5l1bp7u_TA\"\n\n- id: \"jeremy-hinegardner-lonestarruby-conf-2009\"\n  title: \"Playing Nice with Others - Tools For Mixed Language Environments\"\n  raw_title: \"Lone Star RubyConf 2009 - Playing nice with others ...\"\n  speakers:\n    - Jeremy Hinegardner\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Playing nice with others - Tools for mixed language environments by: Jeremy Hinegardner\n\n  video_provider: \"youtube\"\n  video_id: \"hWjaXNtzFOQ\"\n\n- id: \"bruce-tate-lonestarruby-conf-2009\"\n  title: \"Rails, Search Engines, and Faceted Navigation\"\n  raw_title: \"Lone Star RubyConf 2009 - Rails, Search Engines, and Faceted Navigation by: Bruce Tate\"\n  speakers:\n    - Bruce Tate\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Rails, Search Engines, and Faceted Navigation by: Bruce Tate\n\n  video_provider: \"youtube\"\n  video_id: \"qMiT6v1Czy4\"\n\n- id: \"dana-grey-lonestarruby-conf-2009\"\n  title: \"So who wants to be a Munger?\"\n  raw_title: \"Lone Star RubyConf 2009 - So who wants to be a Munger? by: Dana Grey\"\n  speakers:\n    - Dana Grey\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    So who wants to be a Munger? by: Dana Grey\n\n  video_provider: \"youtube\"\n  video_id: \"i3MaKAdWi20\"\n\n- id: \"jim-mullholland-lonestarruby-conf-2009\"\n  title: \"MongoDB\"\n  raw_title: \"Lone Star RubyConf 2009 - MongoDB by: Jim Mullholland\"\n  speakers:\n    - Jim Mullholland\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    MongoDB by: Jim Mullholland\n\n  video_provider: \"youtube\"\n  video_id: \"hQ2xH2DHDNE\"\n\n- id: \"bheeshmar-redheendran-lonestarruby-conf-2009\"\n  title: \"XMPP and Application Messaging\"\n  raw_title: \"Lone Star RubyConf 2009 - XMPP and Application Messaging by: Bheeshmar Redheendran, Weston  Sewell\"\n  speakers:\n    - Bheeshmar Redheendran\n    - Weston Sewell\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    XMPP and Application Messaging by: Bheeshmar Redheendran, Weston  Sewell\n\n  video_provider: \"youtube\"\n  video_id: \"qwEyYNI0ulA\"\n\n- id: \"sarah-brookfield-lonestarruby-conf-2009\"\n  title: \"How To Get More Women To Conferences Like This\"\n  raw_title: \"Lone Star RubyConf 2009 - How to get more women to conferences like this by: Sarah Brookfield\"\n  speakers:\n    - Sarah Brookfield\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    How to get more women to conferences like this by: Sarah Brookfield\n\n  video_provider: \"youtube\"\n  video_id: \"0n7dxAw1DUE\"\n\n- id: \"gregory-brown-lonestarruby-conf-2009\"\n  title: \"Goals for Prawn 1.0\"\n  raw_title: \"Lone Star Ruby Conf 2009 - Goals for Prawn 1.0 by: Gregory Brown\"\n  speakers:\n    - Gregory Brown\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Goals for Prawn 1.0 by: Gregory Brown\n\n  video_provider: \"youtube\"\n  video_id: \"R2Uf2rcRigE\"\n\n- id: \"dallas-pool-lonestarruby-conf-2009\"\n  title: \"HTML 5 and CSS3\"\n  raw_title: \"Lone Star RubyConf 2009 - HTML 5 and CSS3 by: Dallas Pool\"\n  speakers:\n    - Dallas Pool\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    HTML 5 and CSS3 by: Dallas Pool\n\n  video_provider: \"youtube\"\n  video_id: \"dtgwx5dFXns\"\n\n- id: \"dave-thomas-lonestarruby-conf-2009\"\n  title: \"Something Interesting\"\n  raw_title: \"Lone Star RubyConf 2009 - Something Interesting by: Dave Thomas\"\n  speakers:\n    - Dave Thomas\n  event_name: \"LoneStarRuby Conf 2009\"\n  date: \"2009-08-27\"\n  published_at: \"2015-04-14\"\n  description: |-\n    Something Interesting by: Dave Thomas\n  video_provider: \"youtube\"\n  video_id: \"MwnVwqt0UwE\"\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2010/event.yml",
    "content": "---\nid: \"PL1BC12596233ACAFB\"\ntitle: \"LoneStarRuby Conf 2010\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: |-\n  August 26-28, 2010 - Norris Conference Center, Austin, TX\npublished_at: \"2010-08-26\"\nstart_date: \"2010-08-26\"\nend_date: \"2010-08-28\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2010\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2010/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"glenn-vanderburg-lonestarruby-conf-2010\"\n  title: \"Real Software Engineering\"\n  raw_title: \"Lone Star Ruby Conference 2010 Real Software Engineering by Glenn Vanderburg\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2011-10-24\"\n  description: |-\n    Software engineering as it's taught in universities simply doesn't work. It doesn't produce software systems of high quality, and it doesn't produce them for low\n    cost. Sometimes, even when practiced rigorously, it doesn't produce systems at all.\n\n    That's odd, because in every other field, the term \"engineering\" is reserved for methods that work.\n\n    What then, does real software engineering look like? How can we consistently deliver high-quality systems to our customers and employers in a timely fashion and for a\n    reasonable cost? In this session, we'll discuss where software engineering went wrong, and build the case that disciplined Agile methods, far from being \"anti-engineering\"\n    (as they are often described), actually represent the best of engineering principles applied to the task of software development.\n  video_provider: \"youtube\"\n  video_id: \"NP9AIUT9nos\"\n\n- id: \"bruce-tate-lonestarruby-conf-2010\"\n  title: \"Seven Languages in Seven Weeks\"\n  raw_title: \"LoneStarRuby Conf 2010 - Seven Languages in Seven Weeks by: Bruce Tate\"\n  speakers:\n    - Bruce Tate\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jBoU1JpFVIg\"\n\n- id: \"tom-preston-werner-lonestarruby-conf-2010\"\n  title: \"Keynote\"\n  raw_title: \"LoneStarRuby Conf 2010 - Keynote Address by: Tom Preston-Werner\"\n  speakers:\n    - Tom Preston-Werner\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"hwvMR-943qw\"\n\n- id: \"nick-gauthier-lonestarruby-conf-2010\"\n  title: \"Grease your Suite: Tips and Tricks for Faster Testing\"\n  raw_title: \"LoneStarRuby Conf 2010 - Grease your Suite: Tips and Tricks for Faster Testing by: Nick Gauthier\"\n  speakers:\n    - Nick Gauthier\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"mMp-nTDyP8M\"\n\n- id: \"wynn-netherland-lonestarruby-conf-2010\"\n  title: \"JSON and the Argonauts - Building Mashups with Ruby\"\n  raw_title: \"LoneStarRuby Conf 2010 - JSON and the Argonauts - Building Mashups with Ruby by: Wynn Netherland\"\n  speakers:\n    - Wynn Netherland\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8ojICo5cyUE\"\n\n- id: \"nick-sutterer-lonestarruby-conf-2010\"\n  title: \"Components in a Monolithic World\"\n  raw_title: \"LoneStarRuby Conf 2010 - Components in a Monolithic World by: Nick Sutterer, Kevin Triplett\"\n  speakers:\n    - Nick Sutterer\n    - Kevin Triplett\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jqtgQQAS4fg\"\n\n- id: \"ari-lerner-lonestarruby-conf-2010\"\n  title: \"Beehive, Scalable Application Deployment\"\n  raw_title: \"LoneStarRuby Conf 2010 - Beehive, scalable application deployment by: Ari Lerner\"\n  speakers:\n    - Ari Lerner\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Okay, your rack app is done and you are ready to deploy it. Now, instead of developing your application you have to switch gears and start thinking about how it should be deployed. What http server should you use? How do you scale it beyond a single instance, load-balance it? How do you even get your app on a server? This discussion happens every time that you finish an application to deploy!\n\n    There is no disputing it, deployment is hard and you either have to be great at both or hire someone who is great at one. At AT&T interactive, we deploy many different applications from many different developers all the time. Additionally, we have application support staff, release schedules, server management staff, etc. etc.\n\n    In this talk, I'll introduce Beehive, a new open-source application deployment framework helps address this problem. We'll discuss why it was developed, how it works and how to use it. Without introducing any new tools, application developers can deploy their applications with a single command git push. Written primarily in ruby, c and erlang, Beehive can run on any hardware supported by the erlang vm. It's written to be entirely distributed, fault-tolerant and maintain high availability for applications.\n  video_provider: \"youtube\"\n  video_id: \"fHO3K0FSWHs\"\n\n- id: \"jesse-wolgamott-lonestarruby-conf-2010\"\n  title: \"Battle of NoSQL stars: Amazon's SDB vs Mongoid vs CouchDB vs RavenDB\"\n  raw_title: \"LoneStarRuby Conf 2010 - Battle of NoSQL stars: Amazon's SDB vs Mongoid vs CouchDB vs RavenDB\"\n  speakers:\n    - Jesse Wolgamott\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: |-\n    by: Jesse Wolgamott\n\n    Dive into the target audiences and differences in NoSQL storage, how to implement them and what this NoSQL thing is all about.\n\n    Discuss how SQL has limits when you get to web-scale and how NoSQL bypasses these limits.\n\n    Deploy an example application using Rails 3 and Mongoid to see how CRUD differs from your MySQL and Postgres installs.\n  video_provider: \"youtube\"\n  video_id: \"NTJ8H9lrbzs\"\n\n- id: \"adam-keys-lonestarruby-conf-2010\"\n  title: \"Rails' Next Top Model: Using ActiveModel and ActiveRelation\"\n  raw_title: \"LoneStarRuby Conf 2010 - Rails' Next Top Model: Using ActiveModel and ActiveRelation by: Adam Keys\"\n  speakers:\n    - Adam Keys\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Rails jumped on the scene five years ago in part due to excellent support for connecting database tables to Ruby classes via ActiveRecord. Rails 3 makes two major improvements to this support. ActiveModel makes it easy to turn any old object into one that looks like ActiveRecord to your Rails app. ActiveRelation makes many kinds of queries easier and makes it possible to write some queries that were very difficult in the past.\n\n    In this talk, we'll learn how to build our own model layer using ActiveRelation and ActiveModel. We'll start by learning how ARel works and how to use it. Then we'll write an adapter for our own database. Next, we'll see what ActiveModel provides and how we use it through ActiveRecord. With this in mind, we'll add functionality to our models that make them look just like ActiveRecord to our Rails app.\n\n    In the end, we'll have a good grasp on the new options for modeling data in Rails 3 and how we can use that to write cleaner apps.\n  video_provider: \"youtube\"\n  video_id: \"Pu5V0SYbGc8\"\n\n- id: \"gregg-pollack-lonestarruby-conf-2010\"\n  title: \"Deciphering Yehuda\"\n  raw_title: \"LoneStarRuby Conf 2010 - Deciphering Yehuda by: Gregg Pollack\"\n  speakers:\n    - Gregg Pollack\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Yehuda Katz has done some great Ruby refactoring for Rails 3 over the past year, but do you really understand what he's done? In this talk, Gregg Pollack will attempt to examine Yehuda's work, identify and deconstruct each programming technique that he's applied, and then teach them in a way that everyone can understand.Some of the techniques to be discussed will include: Method Compilation vs Method Missing, Microkernel Architecture, alias_method_chain vs super, ActiveSupport Concern, Catch/Throw in Bundler, and increased Rack compatibility.Attendees should walk away with a greater understanding of some advanced Ruby design patterns and a better insight into the internals of Rails 3.\n  video_provider: \"youtube\"\n  video_id: \"ldxGXxZ1CCI\"\n\n- id: \"jim-remsik-lonestarruby-conf-2010\"\n  title: \"How to Build a Sustainably Awesome Development Team\"\n  raw_title: \"LoneStarRuby Conf 2010 - How to Build a Sustainably Awesome Development Team\"\n  speakers:\n    - Jim Remsik\n    - Les Hill\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: |-\n    by: Jim Remsik, Les Hill\n  video_provider: \"youtube\"\n  video_id: \"jVJr2ja1zRY\"\n\n- id: \"steve-sanderson-lonestarruby-conf-2010\"\n  title: \"Get Your Facts First, Then You Can Distort Them as You Please\"\n  raw_title: 'LoneStarRuby Conf 2010 -  \"Get your facts first...'\n  speakers:\n    - Steve Sanderson\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: |-\n    \"Get your facts first, then you can distort them as you please\", or why I love continuous learning with continuous deployment. by: Steve Sanderson\n\n    Most of us have worked where there's tremendous effort on planning, anticipating the needs of our customers, testing before release to our customers, re-thinking, re-considering and re-coding. To a developer, the only thing that may seem worse is when there's none of this. Regardless, we expect to know, in advance what's true about our customers.\n\n    What if both alternatives are wrong? What if, instead, we assume we're ignorant and use our creativity to learn? Then, we'd\n\n    continually run live experiments with our users to see what works; and\n    gather more metrics than we know what to do with; and\n    continually deploy changes to adapt those learnings.\n    Find out why we worked this way, the results we achieved and the specific tools and technologies we use.\n  video_provider: \"youtube\"\n  video_id: \"lRfY_hhqmHM\"\n\n- id: \"bernerd-schaefer-lonestarruby-conf-2010\"\n  title: \"Taking Mongoid into the Future\"\n  raw_title: \"LoneStarRuby Conf 2010 - Taking Mongoid into the Future by: Bernerd Schaefer\"\n  speakers:\n    - Bernerd Schaefer\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2015-04-07\"\n  description: |-\n    With a growing pool of ORMs innovating in the realm of NoSQL solutions and a new NoSQL database seemingly every week, it can be difficult to decide what is right for your app. We'll talk about the features of MongoDB that make it the best document database, and what's being done to keep Mongoid at the head of the pack as the best NoSQL library of them all.\n  video_provider: \"youtube\"\n  video_id: \"dbID_mUJQnU\"\n\n- id: \"adam-kalsey-lonestarruby-conf-2010\"\n  title: \"TROPO\"\n  raw_title: \"Lone Star Ruby Conference 2010 -  TROPO by Adam Kalsey\"\n  speakers:\n    - Adam Kalsey\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"-DB5RJT4pY4\"\n\n- id: \"john-crepezzi-lonestarruby-conf-2010\"\n  title: \"Recurring Dates\"\n  raw_title: \"Lone Star Ruby Conference 2010 - Recurring Dates by John Crepezzi\"\n  speakers:\n    - John Crepezzi\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"dOMW0WcvvRc\"\n\n- id: \"jim-remsik-lonestarruby-conf-2010-the-philosophy-of-vim\"\n  title: \"The Philosophy of VIM\"\n  raw_title: \"Lone Star Ruby Conference 2010 - The Philosophy of VIM\"\n  speakers:\n    - Jim Remsik\n    - Robert Pitts\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: |-\n    By Jim Remsik & Robert Pitts\n  video_provider: \"youtube\"\n  video_id: \"7MeZSkA7l2Y\"\n\n- id: \"jesse-crouch-lonestarruby-conf-2010\"\n  title: \"Building Fast, Lightweight Data-driven Apps Using The Infochimps API\"\n  raw_title: \"Lone Star Ruby Conference 2010 - Building Fast, Lightweight Data-driven Apps...\"\n  speakers:\n    - Jesse Crouch\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: |-\n    By Jesse Crouch\n  video_provider: \"youtube\"\n  video_id: \"QQIMwp_eY28\"\n\n- id: \"aman-gupta-lonestarruby-conf-2010\"\n  title: \"Debugging Ruby\"\n  raw_title: \"Lone Star Ruby Conference 2010 - Debugging Ruby by Aman Gupta\"\n  speakers:\n    - Aman Gupta\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"gEMnwRAUlKE\"\n\n- id: \"caleb-clausen-lonestarruby-conf-2010\"\n  title: \"What Every Ruby Programmer Should Know About Threads\"\n  raw_title: \"Lone Star Ruby Conference 2010 - What Every Ruby Programmer Should Know About Threads\"\n  speakers:\n    - Caleb Clausen\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: |-\n    By Caleb Clausen\n  video_provider: \"youtube\"\n  video_id: \"kbYRbQVShxE\"\n\n- id: \"zhao-lu-lonestarruby-conf-2010\"\n  title: \"OPENVOICE\"\n  raw_title: \"Lone Star Ruby Conference 2010 - OPENVOICE @LSRC by Zhao Lu\"\n  speakers:\n    - Zhao Lu\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FiobTjSskwY\"\n\n- id: \"gautam-rege-lonestarruby-conf-2010\"\n  title: \"Mobile Value Added Service (VAS)\"\n  raw_title: \"Lone Star Ruby Conference 2010 - Mobile Value Added Service (VAS) by Gautam Rege\"\n  speakers:\n    - Gautam Rege\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3hdUN00DEWE\"\n\n- id: \"jason-goecke-lonestarruby-conf-2010\"\n  title: \"Tropo\"\n  raw_title: \"Lone Star Ruby Conference 2010 - Tropo by Jason Goecke\"\n  speakers:\n    - Jason Goecke\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"4sSoGAfpQ0s\"\n\n- id: \"blake-mizerany-lonestarruby-conf-2010\"\n  title: \"Closing Keynote\"\n  raw_title: \"Lone Star Ruby Conference 2010 - Closing Keynote by Blake Mizerany\"\n  speakers:\n    - Blake Mizerany\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"LsTzE0BPybE\"\n\n- id: \"david-copeland-lonestarruby-conf-2010\"\n  title: \"Awesome Command Line Applications in Ruby\"\n  raw_title: \"Lone Star Ruby Conference 2010 - Awesome Command Line Applications in Ruby\"\n  speakers:\n    - David Copeland\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: |-\n    By David Copeland\n  video_provider: \"youtube\"\n  video_id: \"fJjRewOcjgM\"\n\n- id: \"nephi-johnson-lonestarruby-conf-2010\"\n  title: \"Less-Dumb Fuzzing & Ruby Metaprogramming\"\n  raw_title: \"Lone Star Ruby Conference 2010 - Less-Dumb Fuzzing & Ruby Metaprogramming\"\n  speakers:\n    - Nephi Johnson\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: |-\n    By Nephi Johnson\n  video_provider: \"youtube\"\n  video_id: \"jl5633Y9NQk\"\n\n- id: \"rogelio-j-samour-lonestarruby-conf-2010\"\n  title: \"No Sudo For You\"\n  raw_title: \"Lone Star Ruby Conference 2010 - NO SUDO FOR YOU by Rogelio J. Samour\"\n  speakers:\n    - Rogelio J. Samour\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"rh2DOYbnh98\"\n\n- id: \"joshua-hull-lonestarruby-conf-2010\"\n  title: \"Padrino The Elegant Web Framework\"\n  raw_title: \"Lone Star Ruby Conference 2010 - Padrino The Elegant Web Framework by Joshua Hull\"\n  speakers:\n    - Joshua Hull\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"XUMcW2sHiOo\"\n\n- id: \"charles-cornell-lonestarruby-conf-2010\"\n  title: \"Getting Started With C++ Extensions\"\n  raw_title: \"Lone Star Ruby Conference 2010 - Getting Started With C++ Extensions\"\n  speakers:\n    - Charles Cornell\n  event_name: \"LoneStarRuby Conf 2010\"\n  date: \"2010-08-26\"\n  published_at: \"2016-01-08\"\n  description: |-\n    By Charles Cornell\n\n  video_provider: \"youtube\"\n  video_id: \"oV2DyYaXAWo\"\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2011/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaUov1d_26VGMXVkjT2Fz00\"\ntitle: \"LoneStarRuby Conf 2011\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: |-\n  August 11-13, 2011 - Norris Conference Center, Austin, TX\npublished_at: \"2011-08-11\"\nstart_date: \"2011-08-11\"\nend_date: \"2011-08-13\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2011\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2011/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"adam-keys-lonestarruby-conf-2011\"\n  title: \"Chronologic and Cassandra at Gowalla\"\n  raw_title: \"Lone Star Ruby Conference 2011 - Chronologic and Cassandra at Gowalla by Adam Keys\"\n  speakers:\n    - Adam Keys\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-02\"\n  description: |-\n    The need to maintain social activity feeds is an increasingly useful thing in a variety of software. Whether its a project management app or a social site, many kinds of software can make use of a list of events that have happened in the system, filtered for each user and listed in reverse chronological order. However, this sort of data presents many storage and privacy challenges. Gowalla has built Chronologic to meet all these needs. Chronologic is an application built for dealing with events, timelines, and pushing those events to the right subscribers. It is a general service for dealing with activity feeds. On top of that, it implements privacy, a flexible follow model, and the ability to fetch incremental updates to a feed. Chronologic is built with Ruby, Sinatra, and Cassandra. We'll show how this trio played nicely together and how it could be improved. Most importantly, we'll show how to get started with Chronologic, how to adapt it to your own application, and how to deploy it in your datacenter.\n\n  video_provider: \"youtube\"\n  video_id: \"qB2HW7FXkK0\"\n\n- id: \"dave-mccrory-lonestarruby-conf-2011\"\n  title: \"Cloud Foundry Deep Dive\"\n  raw_title: \"Lone Star Ruby Conference 2011 Cloud Foundry Deep Dive by Dave McCrory\"\n  speakers:\n    - Dave McCrory\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    The session will dig into the internals of how Cloud Foundry the first Open PaaS, which is written entirely in Ruby works. We will walk through each component and how they communicate, how code gets bootstrapped, and why PaaS is so significant.\n\n  video_provider: \"youtube\"\n  video_id: \"Hv298TnFIjo\"\n\n- id: \"mike-hagedorn-lonestarruby-conf-2011\"\n  title: \"Building Virtual Development Envrionments with Vagrant\"\n  raw_title: \"Lone Star Ruby Conference 2011 Building Virtual Development Envrionments with Vagrant\"\n  speakers:\n    - Mike Hagedorn\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    Title: Building Virtual Development Envrionments with Vagrant\n    Presented by: Mike Hagedorn\n\n    Many of us deploy to systems which are completely different from the systems we develop on, and can be difficult to set up particularly if there are a lot of moving pieces in your setup. These could be things like message queuing systems, various databases or specific versions of scripting languages such as ruby. This makes it a very time intensive process to bring new people up to speed on your projects, and to get systems set up right the first time. What if you could have a system that would launch a virtual environment, provision and run all of your systems's various components, be repeatable and fit on a thumb drive? Vagrant allows this by putting a ruby DSL on top of Oracle's VirtualBox API. It allows you to set up and provision your servers using Chef or Puppet, and to reuse those scripts on your real production environment if you want. This makes your server infrastructure version controlled just like your application code. We will go through a setup of a Vagrant instance and show how using shared folders you can develop locally, but be developing on your \"local cloud\", your running Vagrant instance.\n\n  video_provider: \"youtube\"\n  video_id: \"kKXFZYAaWoc\"\n\n- id: \"phil-toland-lonestarruby-conf-2011\"\n  title: \"Polyglot Paralellism: A Case Study in Using Erlang and Ruby at Rackspace\"\n  raw_title: \"Lone Star Ruby Conference 2011 Polyglot Paralellism: A Case Study in Using Erlang and Ruby at...\"\n  speakers:\n    - Phil Toland\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    Title: Polyglot Paralellism: A Case Study in Using Erlang and Ruby at Rackspace\n    Presented by: Phil Toland\n\n    Two years ago Rackspace had a problem: how do we backup 20K network devices, in 8 datacenters, across 3 continents, with less than a 1% failure rate -- every single day? Many solutions were tried and found wanting: a pure Perl solution, a vendor solution and then one in Ruby, none worked well enough. They not fast enough or they were not reliable enough, or they were not transparent enough when things went wrong. Now we all love Ruby but good Rubyists know that it is not always the best tool for the job. After re-examining the problem we decided to rewrite the application in a mixture of Erlang and Ruby. By exploiting the strengths of both -- Erlang's astonishing support for parallelism and Ruby's strengths in web development -- the problem was solved. In this talk we'll get down and dirty with the details: the problems we faced and how we solved them. We'll cover the application architecture, how Ruby and Erlang work together, and the Erlang approach to asynchronous operations (hint: it does not involve callbacks). So come on by and find out how you can get these two great languages to work together.\n\n  video_provider: \"youtube\"\n  video_id: \"RGqg8CtQIfM\"\n\n- id: \"wesley-beary-lonestarruby-conf-2011\"\n  title: \"Fog or: How I Learned to Stop Worrying and Love the Cloud\"\n  raw_title: \"Lone Star Ruby Conference 2011 Fog or: How I Learned to Stop Worrying and Love the Cloud\"\n  speakers:\n    - Wesley Beary\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    Title: Fog or: How I Learned to Stop Worrying and Love the Cloud\n    Presented by: Wesley Beary\n\n    Cloud computing scared the crap out of me - the quirks and nightmares of provisioning cloud computing, dns, storage, ... on AWS, Terremark, Rackspace, ... - I mean, where do you even start? Since I couldn't find a good answer, I undertook the (probably insane) task of creating one. fog gives you a place to start by creating abstractions that work across many different providers, greatly reducing the barrier to entry (and the cost of switching later). The abstractions are built on top of solid wrappers for each api. So if the high level stuff doesn't cut it you can dig in and get the job done. On top of that, mocks are available to simulate what clouds will do for development and testing (saving you time and money). You'll get a whirlwind tour of basic through advanced as we create the building blocks of a highly distributed (multi-cloud) system with some simple Ruby scripts that work nearly verbatim from provider to provider. Get your feet wet working with cloud resources or just make it easier on yourself as your usage gets more complex, either way fog makes it easy to get what you need from the cloud.\n\n  video_provider: \"youtube\"\n  video_id: \"jRHNza-QTEo\"\n\n- id: \"lourens-naud-lonestarruby-conf-2011\"\n  title: \"In The Loop\"\n  raw_title: \"Lone Star Ruby Conference 2011 In The Loop by Lourens Naudé\"\n  speakers:\n    - Lourens Naudé\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    The Reactor Pattern's present in a lot of production infrastructure (Nginx, Eventmachine, 0mq, Redis), yet not very well understood by developers and systems fellas alike. In this talk we'll have a look at what code is doing at a lower level and also how underlying subsystems affect your event driven services. Below the surface : system calls, file descriptor behavior, event loop internals and buffer management Evented Patterns : handler types, deferrables and half sync / half async work Anti patterns : on CPU time, blocking system calls and protocol gotchas\n\n  video_provider: \"youtube\"\n  video_id: \"QUuJwqrH0Yo\"\n\n- id: \"steve-klabnik-lonestarruby-conf-2011\"\n  title: \"The Return of Shoes\"\n  raw_title: \"Lone Star Ruby Conference 2011 The Return of Shoes by Steve Klabnik\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    Everyone talks about writing web applications with Ruby, but it's great for applications of any kind. Shoes is a project that was started by _why the lucky stiff, and when he left, a plucky community of developers kept it alive. If you've never worked with Shoes, it's the only Ruby GUI toolkit that is truly Ruby, and not just a binding to another project, like QT or tk. It uses Ruby-only features like blocks heavily, and works on all three platforms. In this talk, Steve will do a small introduction to developing desktop apps with Shoes, talk about the challenges of maintaining a large polyglot project with an absent creator, and where Shoes is going in the future, as well as how you can get involved.\n\n  video_provider: \"youtube\"\n  video_id: \"1yq1ukEpCzo\"\n\n- id: \"ben-klang-lonestarruby-conf-2011\"\n  title: \"State of the Art Telephony with Ruby\"\n  raw_title: \"Lone Star Ruby Conference 2011 State of the Art Telephony with Ruby by Ben Klang\"\n  speakers:\n    - Ben Klang\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    The past 10 years has seen a revolution in the way we make phone calls and even the way we think about a telephone. Ruby is an ideal language to create power tools for building telephony applications. In this talk we will demonstrate how Ruby is the state of the art when it comes to interacting with the telephone network. Using the open source Adhearsion framework, we will demonstrate how you can easily integrate with existing Ruby applications or migrate legacy systems. We will cover how to get started immediately using cloud-based services, as well as how to build, deploy and manage your applications in-house. Network permitting, we will finish with a live demo designed to inspire ideas for ways you can integrate telephony into your application.\n\n  video_provider: \"youtube\"\n  video_id: \"iDzrFM8pN4I\"\n\n- id: \"tim-tyrrell-lonestarruby-conf-2011\"\n  title: \"Testing Javascript with Jasmine\"\n  raw_title: \"Lone Star Ruby Conference 2011 Testing Javascript with Jasmine by Tim Tyrrell\"\n  speakers:\n    - Tim Tyrrell\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    A lot of developers do an excellent job of unit testing their server-side logic but then leave their client-side javascript as the new \"spaghetti code\" dumping ground and it doesn't have to be that way! Jasmine is a simple DOM-less javascript testing framework with a familiar RSpec-like syntax that removes most excuses for not testing your code. You will get an overview of Jasmine and how to utilize it in a variety of project environments from vanilla javascript to Rails to jQuery plugins. We will also explore where CoffeeScript and some helper libraries fit into making the testing of your javascript as simple and pleasurable as possible.\n\n  video_provider: \"youtube\"\n  video_id: \"734wBQhf7Ok\"\n\n- id: \"eleanor-mchugh-lonestarruby-conf-2011\"\n  title: \"Google Go for Ruby Hackers\"\n  raw_title: \"Lone Star Ruby Conference 2011 Google Go for Ruby Hackers by Eleanor McHugh\"\n  speakers:\n    - Eleanor McHugh\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    Go is a statically-compiled systems language geared to developing scalable and type-safe applications with the light touch of a dynamic language. In this session we'll explore Go from a Rubyists perspective, examining the CSP-based concurrency model which has gained it wide-spread press coverage, it's inference-based approach to dynamic typing and the inheritance-free object model this supports. Where possible I'll tie these concepts back to familiar Ruby idioms. Along the way we'll meet gotest (Go's testing and benchmarking framework), CGO (for linking to C libraries), goinstall (the remote package installer) and Go's powerful reflection and type manipulation features. By the end of the session you'll be comfortable reading Go source code, have a basic feel for developing with the language and the necessary background to get started writing your own concurrent Go programs.\n\n  video_provider: \"youtube\"\n  video_id: \"97NC53hcrmk\"\n\n- id: \"ross-andrews-lonestarruby-conf-2011\"\n  title: \"Getting started with ZeroMQ\"\n  raw_title: \"Lone Star Ruby Conference 2011 Getting started with ZeroMQ by Ross Andrews\"\n  speakers:\n    - Ross Andrews\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    I'd like to go through some of the fundamental concepts of the messaging library ZeroMQ, and talk about how to use it to architect distributed applications.\n\n  video_provider: \"youtube\"\n  video_id: \"B0Ct5RMTPIw\"\n\n- id: \"charles-lowell-lonestarruby-conf-2011\"\n  title: \"The Ruby Racer: Under the Hood\"\n  raw_title: \"Lone Star Ruby Conference 2011 The Ruby Racer: Under the Hood by Charles Lowell\"\n  speakers:\n    - Charles Lowell\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    Have you ever had to implement the same validation logic twice: once in JavaScript for the browser and once in Ruby for the server? Has there ever been a JavaScript library like handlebars.js that you'd love to use server side, but can't because well... it's in JavaScript and not Ruby? Or perhaps a time or two you've been tempted to eval() some anonymous Ruby code, but you didn't dare because it's an unspeakably dangerous thing to do? The solutions to these and many other problems are suddenly and elegantly within your grasp when you've got the power of a JavaScript interpreter right there with you in your ruby process. Sound crazy? difficult? It's easier than you might think. This talk will focus on The Ruby Racer: a gem that brings the superb V8 interpteter to Ruby. We'll see how to call JavaScript functions directly from Ruby; how to call Ruby methods directly from JavaScript; how to extend Ruby classes with JavaScript; how to extend your JavaScript objects with Ruby, and a slew of other ways of managing their interaction that will bend your mind.\n\n  video_provider: \"youtube\"\n  video_id: \"01SJnppj_Uo\"\n\n- id: \"tom-brown-lonestarruby-conf-2011\"\n  title: \"Beautiful Payment Systems with OAuth\"\n  raw_title: \"Lone Star Ruby Conference 2011 Beautiful Payment Systems with OAuth by Tom Brown\"\n  speakers:\n    - Tom Brown\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    A simple OAuth based protocol called OpenTransact will be described. Payments made across financial service providers using the opentransact ruby gem will be demonstrated.\n\n  video_provider: \"youtube\"\n  video_id: \"yKJYPzidBoY\"\n\n- id: \"jeff-casimir-lonestarruby-conf-2011\"\n  title: \"Blow Up Your Views\"\n  raw_title: \"Lone Star Ruby Conference 2011 Blow Up Your Views by Jeff Casimir\"\n  speakers:\n    - Jeff Casimir\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    Whether you're new to Rails or have been around few years, chances are that your views are primitive. Detonate what you know about how views are written and let's start over. In this session we'll discuss... - Why your views suck - Instance variables are stupid - Kill helpers and work with objects - Drawing the line between \"C\" and \"V\" - Treating views as API customers - Rethinking templating By the end you'll be dying to blow up your views.\n\n  video_provider: \"youtube\"\n  video_id: \"VC5z8nadnQE\"\n\n- id: \"jesse-wolgamott-lonestarruby-conf-2011\"\n  title: \"JavaScript For People Who Didn't Learn JavaScript\"\n  raw_title: \"Lone Star Ruby Conference 2011 Javascript for people who didn't learn Javascript\"\n  speakers:\n    - Jesse Wolgamott\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: |-\n    Title: Javascript for people who didn't learn Javascript\n    Presented by: Jesse Wolgamott\n\n    Javascript is easy to get into, and jQuery made it easy to do powerful things. But what about prototype inheritance? Binding? What about all the things you should know about the language before building Node apps. We'll go over the concepts through code examples and figure this whole thing out together.\n\n  video_provider: \"youtube\"\n  video_id: \"TDGSFd7YnB4\"\n\n- id: \"brian-smith-lonestarruby-conf-2011\"\n  title: \"OPI (Other People's Infrastructure)\"\n  raw_title: \"Lone Star Ruby Conference 2011 OPI (Other people's infrastructure)\"\n  speakers:\n    - Brian Smith\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-22\"\n  description: |-\n    In business, OPM(other people's money), is the preferred way to start a business. In today's web economy it is now possible to get your app up and running quick by using OPI. This can include everything from server hosting to video processing.\n\n  video_provider: \"youtube\"\n  video_id: \"u2cOWApb5Co\"\n\n- id: \"evan-light-lonestarruby-conf-2011\"\n  title: \"More DSL, Less Pain\"\n  raw_title: \"Lone Star Ruby Conference 2011 More DSL, Less Pain by Evan Light\"\n  speakers:\n    - Evan Light\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-28\"\n  description: |-\n    One much loved feature of Ruby is the ease with which the object model allows for internal DSLs. However, \"metaprogramming\" code, in Ruby, can be hard on the eyes which written in large quantities. \"Lispy\", a gem by Ryan Allen, was a first step toward a generic decoupling of internal DSLs from their implementation. I forked it, took it a ways further, and used it in a significant refactoring of a gem. During this presentation, I'll demonstrate how the LISPish notion that code is data can go a long way toward easing the burden of implementing internal DSLs\n\n  video_provider: \"youtube\"\n  video_id: \"qF2x8rj3RzA\"\n\n- id: \"matt-thompson-lonestarruby-conf-2011\"\n  title: \"Much Ado About CoffeeScript\"\n  raw_title: \"Lone Star Ruby Conference 2011 Much Ado About CoffeeScript by Matt Thompson\"\n  speakers:\n    - Matt Thompson\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-28\"\n  description: |-\n    CoffeeScript will ship with Rails 3.1 to replace RJS as the preferred way to dynamically generate JavaScript. It's a new language that take the best parts of Ruby, Python, and others to ease the worst parts of JavaScript. More than being the new kid on the Rails block however, CoffeeScript is mind-expanding in ways that will make you remember the first time you ever gave Ruby a try. This presentation will take you through the basics of CoffeeScript, starting with a crash course in syntax, all the way to a working application.\n\n  video_provider: \"youtube\"\n  video_id: \"SJ2sHt17uo8\"\n\n- id: \"brandon-keepers-lonestarruby-conf-2011\"\n  title: \"The World Runs On Bad Software\"\n  raw_title: \"Lone Star Ruby Conference 2011 The world runs on bad software by Brandon Keepers\"\n  speakers:\n    - Brandon Keepers\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-28\"\n  description: |-\n    The world is full of poorly structured, overly verbose, untested code. But, a lot of people are doing amazing things and making insane amounts of money from bad software. As someone who might call himself a \"software architect\" or \"craftsman\", this is difficult reality for me to accept. This talk explores the balance between pragmatism and perfection. Ruby, being as expressive and versatile as it is, makes it easy for newbies to write alien code that looks more like Java than anything resembling our beloved language, while those versed in \"The Ruby Way\" spend their days and nights obsessing over how to refactor ten lines of working code into three. There is a cost to writing good software. It takes time to write automated tests, refactor code, and do things right. You may miss opportunities to get your software in front of real people, get essential feedback, or even launch at all. I have seen and often written both abysmal software that makes me want to cry and glorious code that would make any mother proud; both were perfectly adequate for the task at hand. Bad software that ships is better than good software that nobody uses. Learn how to strike a balance between pragmatism and perfection.\n\n  video_provider: \"youtube\"\n  video_id: \"RzHqz-nIxGk\"\n\n- id: \"wynn-netherland-lonestarruby-conf-2011\"\n  title: \"Accelerated Native Mobile App Development Titanium Gem\"\n  raw_title: \"Lone Star Ruby Conference 2011 Accelerated native mobile app development Titanium gem\"\n  speakers:\n    - Wynn Netherland\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-28\"\n  description: |-\n    Title: Accelerated native mobile app development Titanium gem\n    Presented by: Wynn Netherland\n\n    Titanium mobile is fast becoming the native platform of choice for Rubyists. This talk will show you how to put your Ruby skills to use to write native apps for iOS and Android faster than you ever thought possible including: - The Ti gem which offers Rails-like generators for views, models, and other project items - CoffeeScript to write JavaScript using idioms familiar to Rubyists - Compass and Sass to write JavaScript stylesheets - Rake to compile, build, and deploy your apps\n\n  video_provider: \"youtube\"\n  video_id: \"60dYpCxctvw\"\n\n- id: \"jeff-linwood-lonestarruby-conf-2011\"\n  title: \"Consuming the Twitter Streaming API with Ruby and MongoDB\"\n  raw_title: \"Lone Star Ruby Conference 2011 Consuming the Twitter Streaming API with Ruby and MongoDB\"\n  speakers:\n    - Jeff Linwood\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-28\"\n  description: |-\n    Title: Consuming the Twitter Streaming API with Ruby and MongoDB\n    Presented by: Jeff Linwood\n\n    Want to build your next application off of live Twitter updates? Twitter provides a streaming API that you can filter by username, keyword, or geo-location. Using a couple of great Ruby gems, we can store tweets from the streaming API into MongoDB, a NoSQL store that's perfect for analysis. I'll go over the basics of the Twitter API, MongoDB, the mongo and tweetstream ruby gems, and how to bring it all together into a sample application.\n\n  video_provider: \"youtube\"\n  video_id: \"qkhob0XkviA\"\n\n- id: \"hal-fulton-lonestarruby-conf-2011\"\n  title: \"Ten Things I Hate About Ruby\"\n  raw_title: \"Lone Star Ruby Conference 2011 Ten Things I Hate About Ruby by Hal Fulton\"\n  speakers:\n    - Hal Fulton\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-10\"\n  description: |-\n    We all love Ruby. But let's face it: It isn't perfect. We each may have a personal list of complaints. Yours will vary; this is mine. These are the things about Ruby semantics and the Ruby core that I find counter-intuitive, difficult to remember, incomplete, improperly designed, or not quite adequate. There might even be one or two notes here on syntax, the most fundamental level of any language. And \"hate\" may be too strong a word; but once in a while, we have to ask what is lacking in our favorite tool, so that someday when replace it, we will have something better (whether that thing is called \"Ruby 2.0\" or something else entirely).\n\n  video_provider: \"youtube\"\n  video_id: \"G4B-iiLvYpo\"\n\n- id: \"malcom-arnold-lonestarruby-conf-2011\"\n  title: \"As a Language, Can We Make Ruby as Signficant as Latin, Ancient Greek or Sanskrit?\"\n  raw_title: \"Lone Star Ruby Conference 2011 As a language, can we make Ruby as signficant as Latin, Ancient...\"\n  speakers:\n    - Malcom Arnold\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-10\"\n  description: |-\n    Title: As a language, can we make Ruby as signficant as Latin, Ancient Greek or Sanskrit?\n    Presented by: Malcom Arnold\n\n    Ruby is a dying language. The same as the ones that came before it. Eventually, it will deprecate and be relegated to the history books. Does anyone know what the cultures or values of Fortran, Cobol, Pascal or Basic were? Does anyone know what was specifically accomplished with them? If you do know, do you really think that anyone besides a small circle within the tech-geek world cares? Only a few uber geeks still speak Latin, Greek or Sanskit. Yet, the entire planet knows about these languages and what they contributed. They care not just because of the monuments built, most of which have turned to dust and have become fables, but because of the ideas, culture and values that were created and passed on through the generations. Each of these languages created a distinct culture whose memorable flame burns eternal and contributed to the planet. What culture, if any, will Ruby on Rails create? The efficiency of Ruby on Rails, the demand for it, the convergence of economic and technical forces provide the tools and incentives to create a culture of our choosing that could be memorable for decades and longer. Will we seize the opportunity to create lasting positive change? Within 8 months of Ruby Nuby's first meeting, it has grown to over 700 members with training locations in 3 countries and multiple university partners . Ruby Nuby will present a systematic plan of how we can make Ruby on Rails as memorable as Latin, Sanskrit or Ancient Greek due the culture, ideas and values we will create and pass on.\n\n  video_provider: \"youtube\"\n  video_id: \"W6SxFlf8xiA\"\n\n- id: \"avdi-grimm-lonestarruby-conf-2011\"\n  title: \"Exceptional Ruby\"\n  raw_title: \"Lone Star Ruby Conference 2011 - Exceptional Ruby by Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-09\"\n  description: |-\n    You know how to raise and rescue exceptions. But do you know how they work, and how how to structure a robust error handling strategy for your app? Starting out with an in-depth walk-through of Ruby's Ruby's rich failure handling mechanisms -- including some features you may not have known about -- we'll move on to present strategies for implementing a cohesive error-handling policy for your application, based on real-world experience.\n\n  video_provider: \"youtube\"\n  video_id: \"qEHn46YtRM8\"\n\n- id: \"ben-scheirman-lonestarruby-conf-2011\"\n  title: \"Rails 3.1 Whirlwind Tour\"\n  raw_title: \"Lone Star Ruby Conference 2011 - Rails 3.1 Whirlwind Tour by Ben Scheirman\"\n  speakers:\n    - Ben Scheirman\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-09\"\n  description: |-\n    Rails 3.1 introduces a lot of new changes. In this session we'll cover most of the changes, including how to take advantage of them. From Reversible Migrations, the new Asset Pipeline, Coffee Script, SASS, and even HTTP Streaming. This will be a code-heavy talk demonstrating many of the new features in Rails 3.1.\n\n  video_provider: \"youtube\"\n  video_id: \"A5CdXUnpbKA\"\n\n- id: \"glenn-vanderburg-lonestarruby-conf-2011\"\n  title: \"Misunderstanding\"\n  raw_title: \"Lone Star Ruby Conference 2011 - Misunderstanding by Glenn Vanderburg\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-04-09\"\n  description: |-\n    As programmers, we're familiar with complex logic and decisions: complex boolean expressions, long if/else cascades, and convoluted cases. But we quickly learn to avoid them as much as possible, finding ways to simplify. That's because even though computers can handle that complex stuff, we humans like simple logic. We have trouble internalizing complex lines of reasoning. Our bias toward simple explanations shows in all kinds of ways. It affects how we think about politics, science, economics, and yes, programming. And it can lead us astray. Some things really are complicated, and to understand them properly requires thinking about the complexities. If we insist on simple explanations—or just default to them because we don't think very hard about it—we can reach the wrong conclusions. This talk will explore how to think about some important programming topics that are often misunderstood. You may leave the talk with your mind changed. You may simply find your position strengthened. At the very least, I hope you'll learn some new, clear ways of explaining things to those around you, helping them to think clearly about complex issues.\n\n  video_provider: \"youtube\"\n  video_id: \"xQKUhOWSWIo\"\n\n- id: \"todo-lonestarruby-conf-2011\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lone Star Ruby Conference 2011 Lightning Talks by Various Presenters\"\n  speakers:\n    - TODO\n  event_name: \"LoneStarRuby Conf 2011\"\n  date: \"2011-08-11\"\n  published_at: \"2013-05-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"oTb1kutEEa8\"\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2012/event.yml",
    "content": "---\nid: \"\"\ntitle: \"LoneStarRuby Conf 2012\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: |-\n  August 9-11, 2012 - Norris Conference Center, Austin, TX\npublished_at: \"2012-08-09\"\nstart_date: \"2012-08-09\"\nend_date: \"2012-08-11\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2012\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybnOxObNbTbx6PyyWrTGJP9\"\ntitle: \"LoneStarRuby Conf 2013\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: |-\n  August 11-13, 2013 - Austin, TX\npublished_at: \"2013-08-11\"\nstart_date: \"2013-08-11\"\nend_date: \"2013-08-13\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2013\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2013/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20130829023207/http://www.lonestarruby.org/\n\n# Schedule: https://web.archive.org/web/20130821204939/http://www.lonestarruby.org/2013/lsrc#schedule\n\n# TODO: talks running order\n# TODO: talk date\n\n- id: \"avdi-grimm-lonestarruby-conf-2013\"\n  title: \"Closing Keynote: You Gotta Try This\"\n  raw_title: \"LoneStarRuby 2013 - Closing Keynote by Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-09-06\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"rx3Gz1E9El8\"\n\n- id: \"dr-nic-williams-lonestarruby-conf-2013\"\n  title: \"Give Cloud Foundry To Your Company\"\n  raw_title: \"LoneStarRuby Conf 2013 - Give Cloud Foundry to your Company by Dr. Nic Williams\"\n  speakers:\n    - Dr. Nic Williams\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-21\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"OZCIqFCVsdw\"\n\n- id: \"greg-knox-lonestarruby-conf-2013\"\n  title: \"Panel: Cloud\"\n  raw_title: \"LoneStarRuby Conf 2013 - Cloud Panel\"\n  speakers:\n    - Greg Knox\n    - Prashant Throughout\n    - Dr. Nic Williams\n    - Jay Austin Ewing\n    - Jim Meyer\n    # - TODO: MC\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"BL_yHui-80M\"\n\n- id: \"byron-reese-lonestarruby-conf-2013\"\n  title: \"Big Data and the Coming Golden Age of Humanity\"\n  raw_title: \"LoneStarRuby 2013 - Big Data and the Coming Golden Age of Humanity\"\n  speakers:\n    - Byron Reese\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-09-04\"\n  description: |-\n    By Byron Reese\n\n    This talk explores how the widespread proliferation of cheap sensors of all kinds will create a vast collective memory for the planet which will serve as a record of every cause and effect. This data will be scoured for associations that will be turned into algorithms which optimize every decision we have to make in life. And while we may not always choose to do those things, it will effectively make every person on the planet vastly wiser than the wisest person who has ever lived. In the future, no one will ever need to make a mistake again.\n\n  video_provider: \"youtube\"\n  video_id: \"WxUGrRQtG7Q\"\n\n- id: \"dave-thomas-lonestarruby-conf-2013\"\n  title: \"Elixir: Power of Erlang, Joy of Ruby\"\n  raw_title: \"LoneStarRuby Conf 2013 - Elixir: Power of Erlang, Joy of Ruby by Dave Thomas\"\n  speakers:\n    - Dave Thomas\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    Dave Thomas\n    Elixir: Power of Erlang, Joy of Ruby\n\n    I'm a language nut. I love trying them out, and I love thinking about their design and implementation. (I know, it's sad.)\n\n    I came across Ruby in 1998 because I was an avid reader of comp.lang.misc (ask your parents). I downloaded it, compiled it, and fell in love. As with any time you fall in love, it's difficult to explain why. It just worked the way I work, and it had enough depth to keep me interested.\n\n    Fast forward 15 years. All that time I'd been looking for something new that gave me the same feeling.\n\n    Then I came across Elixir, a language by José Valim, that puts a humane, Ruby-like syntax on the Erlang VM.\n\n    Now I'm dangerous. I want other people to see just how great this is. I want to evangelize. I won't try to convert you away from Ruby. But I might just persuade you to add Elixir to your toolset.\n\n    So come along and let me show you the things that I think make Elixir a serious alternative for writing highly reliable, scalable, and performant server code.\n\n    And, more important, let me show you some fun stuff.\n\n  video_provider: \"youtube\"\n  video_id: \"KQwEmdOH-GM\"\n\n- id: \"kyle-rames-lonestarruby-conf-2013\"\n  title: \"Cutting Through the Fog of Cloud\"\n  raw_title: \"LoneStarRuby Conf 2013 - Cutting Through the Fog of Cloud by Kyle Rames\"\n  speakers:\n    - Kyle Rames\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-16\"\n  description: |-\n    In this talk, I am going to briefly talk about \"what cloud is\" and highlight the various types of cloud (IaaS, PaaS, SaaS). The bulk of the talk will be about using the fog gem using IaaS. I will discuss fog concepts (collections, models, requests, services, providers) and supporting these with actual examples using fog.\n\n  video_provider: \"youtube\"\n  video_id: \"QbsDEUwwPVE\"\n\n- id: \"adam-keys-lonestarruby-conf-2013\"\n  title: \"The Mechanics of Ruby\"\n  raw_title: \"LoneStarRuby Conf 2013 - The Mechanics of Ruby by Adam Keys\"\n  speakers:\n    - Adam Keys\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    Ruby is a delightful language to work with. And yet, for years, we've been hearing about how MRI is too slow and inefficient for \"serious\" use. What does that mean? What would a \"serious\" Ruby runtime look like?\n\n    To understand these questions, we need to dig into the design of MRI. How does it work, and what are the underlying principles? What does common Ruby code look like as its executed by MRI? Once we've discovered what makes MRI tick, we can compare it to modern runtimes like Hotspot and V8 to understand why MRI is slower. From there we can take a look at JRuby and Rubinius and see how they seek to close the gap between Ruby runtimes and the competition.\n\n    In this talk, we'll dive into the internals of MRI, seeking to understand how it executes Ruby code. We'll look at ways to make our code faster, reduce garbage collection overhead, and find more concurrency in our programs. At the end, you will have a better understanding of how MRI works and how to write better code for it.\n\n  video_provider: \"youtube\"\n  video_id: \"aRM06L1L_74\"\n\n- id: \"coraline-ada-ehmke-lonestarruby-conf-2013\"\n  title: \"Refactoring Legacy Apps with APIs and Messages\"\n  raw_title: \"LoneStarRuby Conf 2013 - Refactoring Legacy Apps with APIs and Messages\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    By Corey Ehmke\n\n    Rails as a framework is famous for getting an application up and running quickly, but the very paradigms that make it so easy at the start can lead to maintenance nightmares down the road. Successful applications grow rapidly larger, more complex, and harder to extend and maintain. One way to approach refactoring a monolithic application is dividing it up into a series of smaller applications that organize the work of the system through internal APIs and message queues. In this presentation you will be introduced to tools to enable this architecture, gain insight on how best to use them, and explore the guiding principles behind the SOA approach to refactoring.\n\n  video_provider: \"youtube\"\n  video_id: \"zzv-uv39954\"\n\n- id: \"bryan-helmkamp-lonestarruby-conf-2013\"\n  title: \"Building a Culture of Quality\"\n  raw_title: \"LoneStarRuby Conf 2013 - Building a Culture of Quality by Bryan Helmkamp\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    Time and time again, skilled developers with good intentions set out into the green field of their new Rails app. Alas, as days turn to weeks, weeks to months and months to years, they find themselves with an ever increasing maintenance burden. Adding new features in a well-designed way starts to feel like an exercise in futility, so they resort to liberal use of conditionals to avoid breaking existing code.\n\n    This leads to more complexity, and on the cycle goes.\n\n    It doesn't need to be like this. There's no silver bullet that will save your project from this fate, but by practicing a holistic approach to code quality you can stave off the maintenance monsters and keep your app's code feeling fresh and clean. This talk will look at low ceremony, common sense approaches to taking control of the quality of your codebase. You'll leave with an expanded toolbox of techniques to build a culture of quality within your organization.\n\n  video_provider: \"youtube\"\n  video_id: \"YCugeqQuzh4\"\n\n- id: \"brandon-hays-lonestarruby-conf-2013\"\n  title: \"Ember on Rails: #REALTALK\"\n  raw_title: \"LoneStarRuby Conf 2013 - Ember on Rails: #REALTALK by Brandon Hays\"\n  speakers:\n    - Brandon Hays\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    If you work in Rails and have ever wondered about Ember.js, you should know that Ember and Rails go together like Nutella and pretzels. (Which is to say, quite well indeed.)\n\n    Get an inside look of the experience of going from having never tried Ember to shipping a production application in it. What makes Ember a good match for certain types of applications? What's so different about it compared to other frameworks? What are the drawbacks?\n\n    Using anecdotes, code, and crudely-drawn stick figures, we'll dive into using Ember and Rails, including war stories of climbing over some of the (often surprising) roadblocks encountered along the way.\n\n    With this quick tour, you'll be equipped to jump in and start seeing the kind of crazy-ambitious applications you can build when you've got Ember.js in your toolset.\n\n  video_provider: \"youtube\"\n  video_id: \"PdqbG71Dr84\"\n\n- id: \"charles-lowell-lonestarruby-conf-2013\"\n  title: \"Placing Things into Other Things\"\n  raw_title: \"LoneStarRuby Conf 2013 - Placing Things into Other Things by Charles Lowell\"\n  speakers:\n    - Charles Lowell\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    The world of Ruby is a big and beautiful one. Like Cane from Kung-Fu, you could spend a lifetime wandering it's surface and never lack for an abundance of wonder. But there is an even larger world outside its walls that is also filled with amazing things. Based on lessons learned writing C extensions, Java extensions as well embedding interpreters (v8) and applications (Jenkins) inside Ruby, This talk will take you through the best ways to dress up any citizen of the galaxy in order to make it indistiguishable from one of our beloved planet Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"LPCuUjs909Y\"\n\n- id: \"steve-klabnik-lonestarruby-conf-2013\"\n  title: \"Functional Reactive Programming with Frappuccino\"\n  raw_title: \"LoneStarRuby Conf 2013 - Functional Reactive Programming with Frappuccino\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    By Steve Klabnik\n\n  video_provider: \"youtube\"\n  video_id: \"rffDdYBpyYM\"\n\n- id: \"katrina-owens-lonestarruby-conf-2013\"\n  title: \"Hacking Passion\"\n  raw_title: \"LoneStarRuby Conf 2013 - Hacking Passion by Katrina Owens\"\n  speakers:\n    - Katrina Owens\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"rHLTltK1kss\"\n\n- id: \"reid-gillette-lonestarruby-conf-2013\"\n  title: \"Getting called up to the Majors\"\n  raw_title: \"LoneStarRuby Conf 2013 - Getting called up to the Majors by Reid Gillette\"\n  speakers:\n    - Reid Gillette\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    Shifting from an amateur web developer hacking away at my own projects in my living room to a professional Software Engineer at a startup in San Francisco was a huge change in the way I developed. After joining Mavenlink a year ago I went from tiny apps that were 100% my code, with fast test suites, hosted on Heroku to a giant Rails app with a complicated data model, a CI test suite that took an hour, and a legacy codebase touched by 30+ people. I've worked hard the last year to step up to the challenge and I've learned so much in the process. As the developer pool gets more and more junior there will be more people making the same journey as I did.\n\n    In this talk I will cover:\n\n    skills that are important (some I had, others I had to develop)\n    iteration planning\n    testing\n    debugging/support\n    polyglot skills\n    contributing to a team much more skilled than you\n    pair-programming with someone much more senior or junior than you\n    how culture at Mavenlink has helped me succeed\n    what you can do to help onboard and train up your Junior Developers\n    things you should look for in a Junior Developer candidate\n\n  video_provider: \"youtube\"\n  video_id: \"9nnh7zjLxFI\"\n\n- id: \"akira-matsuda-lonestarruby-conf-2013\"\n  title: \"Diary of a Mad Rails Engineer\"\n  raw_title: \"LoneStarRuby Conf 2013 - Diary of a Mad Rails Engineer by Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-20\"\n  description: |-\n    Rails Engines are useful. We can make our code well structured and reusable using Engines.\n\n    Rails Engines are fun. You can publish your Engine repo to the world, then make yourself and the world better and happier.\n\n    Rails Engine is a sophisticated system. Even though 猿人 (en-jin) in Japanese means \"ape-man\".\n\n    Rails Engine is zen. Everything in our Rails app is an Engine, and Engine is everything. Even the Rails app itself should also be an Engine.\n\n    During my talk, you will get to know what exactly Rails::Engine is, and you will see some of my crazy Engine tips, ideas, and implementations around Rails::Engine.\n\n  video_provider: \"youtube\"\n  video_id: \"0CtpXaYG9og\"\n\n- id: \"scott-bellware-lonestarruby-conf-2013\"\n  title: \"TDD in Tatters\"\n  raw_title: \"LoneStarRuby Conf 2013 - TDD in Tatters by Scott Bellware\"\n  speakers:\n    - Scott Bellware\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    TDD has been tattered, torn, twisted, stood on its head, and pounded into an pulp of techno-fetishism. TDD was a game-changer, but the focus in the interceding years has shifted from technique to tools, and TDD has been devolving into a lost art. By tearing TDD down to its bones, this presentation presents TDD in its essence, free of tools, and reinforcing the primary focus on design principles. It attempts to convince you to return to a simpler time when TDD was still about design, and software developers were dutifully steeped in the critical importance of design principles. To avoid being held to any particularly offensive positions, this talk liberally attacking the status quo of testing and contemporary tool-focused TDD in Ruby, while introducing yet-another testing library in Ruby. :)\n\n  video_provider: \"youtube\"\n  video_id: \"veYFV4maTyQ\"\n\n- id: \"sarah-mei-lonestarruby-conf-2013\"\n  title: \"The End of Fun\"\n  raw_title: \"LoneStarRuby Conf 2013 - The End of Fun by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    I hate to break it to you, guys, but Ruby is old enough to drink. What started out as a small community full of fun, silliness, and connection has been growing. Our small codebases are now large. Our small companies are now large. And the large companies have finally figured out that they want in, too.\n\n    So maybe it's time to start tackling Real Problems and Real Solutions in the world of Real Innovation. Maybe it's time for the community to grow up, stop playing around, and get Serious™.\n\n    But...that's not who we are. Our community thrives on creativity, play, and luck. And those things aren't just a weird perk like not having to wear shoes in the office -- creativity, play, and luck, when present, actually produce better software. As we grow our projects and our teams and invade the corporate cube farm, there are some things we can lay aside, and there are others we must hold on to as if our very identity depended on them.\n\n    Because it does.\n\n  video_provider: \"youtube\"\n  video_id: \"P4RA7NYyG24\"\n\n- id: \"josh-susser-lonestarruby-conf-2013\"\n  title: \"Panel: Ruby Rogues\"\n  raw_title: \"LoneStarRuby Conf 2013 - Ruby Rogues Panel\"\n  speakers:\n    - Josh Susser\n    - Avdi Grimm\n    - David Brady\n    - Charles Max Wood\n    - Katrina Owen\n    - James Edward Gray II\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Eg7IaRAnASM\"\n\n- id: \"evan-light-lonestarruby-conf-2013\"\n  title: \"If It Bleeds, It Leads\"\n  raw_title: \"LoneStarRuby Conf 2013 - If It Bleeds, It Leads by Evan Light\"\n  speakers:\n    - Evan Light\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    Many of us came to Ruby by way of Rails (including yours truly about six years ago). We came because our current solutions were clumsy and inconvenient. We came because we appreciated the relative simplicity that Rails offered. And we came because we believe that change is often a good thing.\n\n    But not all changes are beneficial.\n\n    Over several blog posts, books, and a couple of years, the Rails community has begun to choose complexity over simplicity. Let's talk about why. And let's talk about how we can try to recapture that simplicity that we so once adored.\n\n  video_provider: \"youtube\"\n  video_id: \"7F3M0qdmxwU\"\n\n- id: \"alan-skorkin-lonestarruby-conf-2013\"\n  title: \"Why You Should Love The Command-Line And Get Rid of Your Rake Tasks Once and For All\"\n  raw_title: \"LoneStarRuby Conf 2013 - Why You Should Love The Command Line -\"\n  speakers:\n    - Alan Skorkin\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    By Alan Skorkin - Why You Should Love The Command-Line And Get Rid of Your Rake Tasks Once and For All\n\n    Rake is ubiquitous in our community, it's in just about every project. But why is this so, it is awkward and inflexible (try passing some arguments to rake tasks), and the way we've come to use it almost encourages bad design. Interestingly we've had a better way, to handle the things that we use Rake for, since before Rake even existed - command-line apps. Apps that do one task and do it well, it's the unix philosophy.\n\n    The problem is that as far as most of us know, writing a good command-line app in Ruby is not easy. Fiddling with OptionParser to produce a hacky script is no better than Rake, if anything it is worse. But what if we had the technology to build excellent command-line apps simply and easily? Well, to some extent we already do, but most of the tools available don't go far enough and so never become a viable Rake alternative.\n\n    In this talk we'll try to figure out what features a command-line framework needs to become your go-to tool instead of Rake (and how close existing tools are to this ideal). We'll cover things like:\n\n    What exactly is so bad about Rake\n    What makes a good command-line interface\n    Configuring your command-line apps\n    What are your options for parsing options\n    Can a command-line framework encourage good code design?\n    Writing highly testable CLI apps\n    Etc.\n    And as an added bonus, while we talk about all this, we'll touch on good and bad code design as well as look at some of the unexpected corners of your app where 'bad' code is hiding.\n\n  video_provider: \"youtube\"\n  video_id: \"M-fJIWB5WgY\"\n\n- id: \"ethan-garofolo-lonestarruby-conf-2013\"\n  title: \"Neural Networks with RubyFANN\"\n  raw_title: \"LoneStarRuby Conf 2013 - Neural Networks with RubyFANN by Ethan Garofolo\"\n  speakers:\n    - Ethan Garofolo\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    Neural networks (NNs) not only sound really cool, but they can also solve some pretty interesting problems ranging from driving cars to spam detection to facial recognition.\n\n    Solving problems with NNs is challenging, because actually implementing a NN from scratch is difficult, and knowing how to apply it is more difficult. Fortunately, libraries, such as RubyFANN, exist to handle the first problem. Solving the second problem comes from experience.\n\n    This talk will show a few different approaches to applying NNs to such problems as spam detection and games, as well as discussing other areas where NNs might be a useful solution.\n\n  video_provider: \"youtube\"\n  video_id: \"M9w7OMxmRv4\"\n\n- id: \"matt-rogers-lonestarruby-conf-2013\"\n  title: \"Open Source Protips from the Trenches\"\n  raw_title: \"LoneStarRuby Conf 2013 - Open Source Protips from the Trenches\"\n  speakers:\n    - Matt Rogers\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    By Matt Rogers\n\n    Open Source projects can be hard to navigate for both new and old contributors alike. In this talk, we'll walk through some tips and tricks for dealing with the various pieces of open source projects. From dealing with trolls to nurturing one shot patch submitters into long time contributors we'll walk through various tips to get the most out of your open source experience\n\n  video_provider: \"youtube\"\n  video_id: \"yd9GLA1c9eg\"\n\n- id: \"ben-hamill-lonestarruby-conf-2013\"\n  title: \"I Made a Slow Thing Fast\"\n  raw_title: \"LoneStarRuby Conf 2013 - I Made a Slow Thing Fast by Ben Hamill\"\n  speakers:\n    - Ben Hamill\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-21\"\n  description: |-\n    The talk is a narrative retelling of how I took an application that needed to communicate with a slow external API and improved the user's experience in terms of speed. I'll talk about the situation that we started with, and then retell the story of measurement, and improvement and measurement and improvement.\n\n    I'll talk about perftools.rb, improving the perception of speed without having to actually make your code faster, MRI's Threads (when they're a good fit, and how and why we used them), a few strategies for managing threads, and a few other related topics. None of these topics will be discussed in great depth; the format is intended to be a retelling of the project, so I'll limit my discussion to the scope of how it applied to this specific project.\n\n    The talk will probably be of most interest to people who have little real-world experience with MRI's Threads and/or making users feel like an application is responding quickly. My hope is that showing these things in the context of a real project can help solidify understanding of topics that are often covered in contrived or theoretical examples (I know it did for me: I was totally new to a lot of this stuff when I started the project).\n\n  video_provider: \"youtube\"\n  video_id: \"oKQBgNebEOI\"\n\n- id: \"sam-livingston-gray-lonestarruby-conf-2013\"\n  title: \"Fluent Refactoring\"\n  raw_title: \"loneStarRuby Conf 2013 - Fluent Refactoring by Sam Livingston-Gray\"\n  speakers:\n    - Sam Livingston-Gray\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    Fluency is \"what you can say without having to think about how to say it.\" \"Refactoring\" is a language that describes ways to make your code better. I want to inspire you to learn more of that language, so you can make your code better without having to think about it.\n\n    I'll walk you through the process of reworking a 50-line controller action that's hard to comprehend, let alone refactor. We'll tease apart fiendishly intertwined structures, embrace duplication, use dirty tricks to our advantage, and uncover responsibilities—and bugs!—that weren't obvious at first glance.\n\n  video_provider: \"youtube\"\n  video_id: \"xJZrMbS2dDk\"\n\n- id: \"dave-kapp-lonestarruby-conf-2013\"\n  title: \"Asynchronous Workers to the Resque\"\n  raw_title: \"LoneStarRuby Conf 2013 - Asynchronous Workers to the Resque\"\n  speakers:\n    - Dave Kapp\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    By Dave Kapp\n\n    While Ruby is a terrific language, it doesn't offer a lot of ways to deal with\n    asynchronous tasks using the default libraries. Thankfully, the community has\n    come up with several great options for bringing asynchronicity to your applications.\n    Resque is one of the forerunners of this, and it offers a lot of functionality and\n    flexibility with an easily approachable API. Here, we'll go over several techniques\n    for utilizing asynchronous workers to benefit your projects.\n\n    We'll start off with a review of how asynchronous processing works, and then we'll\n    delve into three different things you can use Resque for:\n    speeding up your applications by processing slow operations on the side, performing\n    sequential updates with pipelining, and performing periodic maintenance tasks.\n    We'll go over example code for how to handle these different situations and ideas\n    for how to integrate them with existing applications.\n\n    While the examples will be given using Resque, the ideas and patterns discussed will\n    be applicable to other worker queues, such as delayed_job and Sidekiq.\n  video_provider: \"youtube\"\n  video_id: \"1zMcGagg_M8\"\n\n- id: \"ashe-dryden-lonestarruby-conf-2013\"\n  title: \"Programming Diversity\"\n  raw_title: \"LoneStarRuby Conf 2013 - Programming Diversity by Ashe Dryden\"\n  speakers:\n    - Ashe Dryden\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    It's been scientifically proven that more diverse communities and workplaces create better products and the solutions to difficult problems are more complete and diverse themselves. Companies are struggling to find adequate talent. So why do we see so few women, people of color, and LGBTQ people at our events and on the about pages of our websites? Even more curiously, why do 60% of women leave the tech industry within 10 years? Why are fewer women choosing to pursue computer science and related degrees than ever before? Why have stories of active discouragement, dismissal, harassment, or worse become regular news?\n\n    In this talk we'll examine the causes behind the lack of diversity in our communities, events, and workplaces. We'll discuss what we can do as community members, event organizers, and co-workers to not only combat this problem, but to encourage positive change by contributing to an atmosphere of inclusivity.\n\n    Objectives:\n\n    Educate about the lack of diversity and why it is a problem\n    Examine what is contributing to both the pipeline issue as well as attrition\n    Isolate what is and isn't working\n    Inspire direct action by examining our own behavior and learning more about the people around us so we can empathize better\n\n  video_provider: \"youtube\"\n  video_id: \"6qrkI5hhfnw\"\n\n- id: \"james-edward-gray-ii-lonestarruby-conf-2013\"\n  title: \"Ruby 2 Jeopardy\"\n  raw_title: \"LoneStarRuby Conf 2013 - Ruby 2 Jeopardy by James Edward Gray II\"\n  speakers:\n    - James Edward Gray II\n  event_name: \"LoneStarRuby Conf 2013\"\n  date: \"2013-08-11\"\n  published_at: \"2013-08-19\"\n  description: |-\n    I will host a game of Jeopardy with questions and answers based on Ruby's syntax, features, standard libraries, etc. Anything that ships with Ruby 2.0 is fair game, new or old.\n\n    Three contestants of high Ruby skill will compete to score points with their arcane knowledge of our favorite language. There will be a prize for the winner of the game\n\n  video_provider: \"youtube\"\n  video_id: \"E8YI7hUUSys\"\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyY_prUE739kR31k9bzY07zW\"\ntitle: \"LoneStarRuby Conf 2015\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: |-\n  August 15, 2015 - Austin, TX\npublished_at: \"2015-08-15\"\nstart_date: \"2015-08-15\"\nend_date: \"2015-08-15\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/lone-star-ruby-conf/lone-star-ruby-conf-2015/videos.yml",
    "content": "---\n- id: \"saron-yitbarek-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 - Code Club by Saron Yitbarek\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: \"\"\n  raw_title: \"LoneStarRuby 2015 - Code Club by Saron Yitbarek\"\n  speakers:\n    - Saron Yitbarek\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"sLAvSgcrgZM\"\n\n- id: \"dave-thomas-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 - My Dog Taught Me to Code by Dave Thomas\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: \"\"\n  raw_title: \"LoneStarRuby 2015 - My Dog Taught Me to Code by Dave Thomas\"\n  speakers:\n    - Dave Thomas\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"yCBUsd52a3s\"\n\n- id: \"brandon-hays-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 - Surviving the Framework Hype Cycle by Brandon Hays\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: |-\n    Baskin Robbins wishes it had as many flavors as there are JS frameworks, build tools, and cool new \"low-level\" languages. You just want to solve a problem, not have a 500-framework bake-off! And how will you know whether you picked the right one? Don't flip that table, because we'll use the \"hype cycle\" and the history of Ruby and Rails as a guide to help you understand which front-end and back-end technologies are a fit for your needs now and in the future.\n  raw_title: \"LoneStarRuby 2015 - Surviving the Framework Hype Cycle by Brandon Hays\"\n  speakers:\n    - Brandon Hays\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"0MojR1XUEc0\"\n\n- id: \"tom-brown-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 - Authentication for Websockets by Tom Brown\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: |-\n    Collaboration and gaming web software using websockets need a way to mitigate impersonation attacks. Using the togetherjs protocol as an example, we will see how a participant can tamper with messages to impersonate other collaborators and how to prevent these attacks.\n  raw_title: \"LoneStarRuby 2015 - Authentication for Websockets by Tom Brown\"\n  speakers:\n    - Tom Brown\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"tzRvCMfwBJ0\"\n\n- id: \"kyle-rames-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby - My Year In Open Source : 10 Lessons in 10 Minutes by Kyle Rames\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: |-\n    I was fortunate to spend a year and half working exclusively on open source software. Along the way, I learned that open source development requires a slightly different approach. In this talk, I will share my story along with some of the lessons I learned.\n  raw_title: \"LoneStarRuby - My Year In Open Source : 10 Lessons in 10 Minutes by Kyle Rames\"\n  speakers:\n    - Kyle Rames\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"kVhFDQO6v34\"\n\n- id: \"randy-coulman-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 - Shall We Play A Game? by Randy Coulman\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: |-\n    Teaching computers to play games has been a pursuit and passion for many programmers. Game playing has led to many advances in computing over the years, and the best computerized game players have gained a lot of attention from the general public (think Deep Blue and Watson). \n    Using the Ricochet Robots board game as an example, let's talk about what's involved in teaching a computer to play games. Along the way, we'll touch on graph search techniques, data representation, algorithms, heuristics, pruning, and optimization.\n  raw_title: \"LoneStarRuby 2015 - Shall We Play A Game? by Randy Coulman\"\n  speakers:\n    - Randy Coulman\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"aCpL-1yViv0\"\n\n- id: \"trevor-rosen-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 - Building a binary protocol client in Ruby: A magical journey!\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: |-\n    By Trevor Rosen and egypt\n    Sometimes we can forget that there's more under the (networking) sun than HTTP. Rapid7's Metasploit team has been working for awhile on a new, pure-Ruby library for Microsoft's SMB protocol. Doing work like this means analyzing wire traffic, working with binary structs, and wrapping everything up into a nice, clean set of abstractions. \n    We'd like to share the developer workflows and lessons learned. If you've ever wondered how to set about building a library for a binary protocol, how to reverse-engineer the byte-by-byte traffic on a network, or thought it would be cool to understand Ruby's networking capabilities from the ground up, this talk is for you!\n  raw_title: \"LoneStarRuby 2015 - Building a binary protocol client in Ruby: A magical journey!\"\n  speakers:\n    - Trevor Rosen\n    - egypt\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"JLoOAGEAAjo\"\n\n- id: \"chris-mccord-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 Phoenix - Productive. Reliable. Fast. by Chris McCord\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: |-\n    Phoenix is an Elixir web framework for building productive, reliable applications with the performance to take on the modern computing world. Together, we'll review what makes Phoenix great and how it uses Elixir to optimize code for performance – without sacrificing programmer productivity. Along the way, we'll see neat features like live-reload and generators and how Phoenix's realtime layer takes on the modern web.\n  raw_title: \"LoneStarRuby 2015 Phoenix - Productive. Reliable. Fast. by Chris McCord\"\n  speakers:\n    - Chris McCord\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"STO-uN0xHDQ\"\n\n- id: \"barrett-clark-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 Brisket Programming by Barrett Clark\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: |-\n    A juicy, melt in your mouth brisket. A beautifully orchestrated application. These don't just happen. They take experience, which is evolutionary. I have a technique for smoking a brisket, born out of iteration and experimentation, that makes a pretty good brisket. Software development and cooking have a lot like this: telling your story through food and code. I'll tell you about my brisket, but really I'll talk about learning to process information quicker and more efficiently. This not only gives answers a place to land, but tastes good too.\n  raw_title: \"LoneStarRuby 2015 Brisket Programming by Barrett Clark\"\n  speakers:\n    - Barrett Clark\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"_rnncRkM8U8\"\n\n- id: \"paul-stefan-ort-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 - Crashing on Autopilot by Paul Stefan Ort\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: |-\n    Software connects people and ideas, but what if your ideas are flawed? Cognitive biases derail software development efforts. This talk can help you recognize and overcome them. Gain the benefits of patterns and examples through thoughtful mastery, without being bound by them.\n  raw_title: \"LoneStarRuby 2015 - Crashing on Autopilot by Paul Stefan Ort\"\n  speakers:\n    - Paul Stefan Ort\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"xzSB0b0pRD8\"\n\n- id: \"abraham-sangha-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 TDD for Your Soul: Virtue and Web Development by Abraham Sangha\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: |-\n    Software engineering pushes us to our limits, not only of cognition, but, perhaps surprisingly, of character. Using the cardinal virtues as a framework, we can see that developers need courage to continue learning, temperance to prioritize goals, a sense of justice by which to discern obligations, and wisdom to optimize our path. By being honest about where we lack virtue, and implementing steps to develop character, we can perform test-driven development, or TDD, on ourselves. This process can help us grow not only as engineers, but as human beings.\n  raw_title: \"LoneStarRuby 2015 TDD for Your Soul: Virtue and Web Development by Abraham Sangha\"\n  speakers:\n    - Abraham Sangha\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"62phZDtpLyQ\"\n\n- id: \"avdi-grimm-lone-star-ruby-conf-2015\"\n  title: \"LoneStarRuby 2015 The Soul of Software by Avdi Grimm\"\n  event_name: \"LoneStarRuby Conf 2015\"\n  description: \"\"\n  raw_title: \"LoneStarRuby 2015 The Soul of Software by Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  date: \"2015-08-15\"\n  published_at: \"2015-08-28\"\n  video_provider: \"youtube\"\n  video_id: \"zs0E4E83_X8\"\n"
  },
  {
    "path": "data/lone-star-ruby-conf/series.yml",
    "content": "---\nname: \"LoneStarRuby Conf\"\nwebsite: \"http://lonestarruby.org\"\ntwitter: \"LoneStarRuby\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Lone Star Ruby Conf\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/lrug/lrug-meetup/cfp.yml",
    "content": "---\n- name: \"Want to speak at LRUG?\"\n  link: \"https://readme.lrug.org/#talks\"\n"
  },
  {
    "path": "data/lrug/lrug-meetup/event.yml",
    "content": "---\nid: \"lrug-meetup\"\ntitle: \"London Ruby User Group Meetup\"\nkind: \"meetup\"\nlocation: \"London, UK\"\ndescription: |-\n  LRUG is a London-based community for anyone who is interested in the Ruby programming language, especially beginners.\nfeatured_background: \"#FFF7B9\"\nfeatured_color: \"#c61300\"\nbanner_background: \"#FFF7B9\"\nwebsite: \"https://lrug.org/meetings/\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/lrug/lrug-meetup/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Alessandro Proserpio\n    - Chris Lowis\n    - Frederick Cheung\n    - Murray Steele\n    - Paolo Fabbri\n"
  },
  {
    "path": "data/lrug/lrug-meetup/videos.yml",
    "content": "# Generated at 2026-04-07 21:45:00 +0000 from LRUG.org version main#ae7a7c4b30b76817c79ed9eab8c73a0d1386b9c9\n---\n- id: \"lrug-january-2020\"\n  title: \"LRUG January 2020\"\n  event_name: \"LRUG January 2020\"\n  date: \"2020-01-13\"\n  announced_at: \"2019-12-22 21:48:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-january-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/january/\n  talks:\n    - id: \"steve-butterworth-lrug-january-2020\"\n      title: \"Ruby on the Big Screen\"\n      event_name: \"LRUG January 2020\"\n      date: \"2020-01-13\"\n      announced_at: \"2019-12-22 21:48:00 +0100\"\n      speakers:\n        - Steve Butterworth\n      description: |-\n        Using Ruby to crunch the numbers, read tv captions and drive a 30m long\n        LED screens at The Open Golf Championships. A whistle stop tour of the\n        setup, the architecture and the code that goes into making something\n        like this work and what can go wrong!\n      video_id: \"lrug-2020-01-13-ruby-on-the-big-screen\"\n      video_provider: \"not_published\"\n    - id: \"murray-steele-lrug-january-2020\"\n      title: \"Re-interpreting data\"\n      event_name: \"LRUG January 2020\"\n      date: \"2020-01-13\"\n      announced_at: \"2019-12-22 21:48:00 +0100\"\n      speakers:\n        - Murray Steele\n      description: |-\n        Some time ago I stumbled across the header description for WAV files\n        and wondered, what if I took a file and calculated the appropriate WAV\n        file header for it, could I _hear_ my data?  Yes, you can.  You probably\n        don't want to, but you can.  You can do something similar with BMP and\n        MIDI files too!\n      additional_resources:\n        - name: \"Transcript\"\n          type: \"transcript\"\n          title: \"Talks ∋ Re-interpreting Data\"\n          url: \"http://h-lame.com/talks/re-interpreting-data/\"\n      video_id: \"lrug-2020-01-13-re-interpreting-data\"\n      video_provider: \"not_published\"\n    - id: \"nuno-silva-lrug-january-2020\"\n      title: \"Ruby's a critic\"\n      event_name: \"LRUG January 2020\"\n      date: \"2020-01-13\"\n      announced_at: \"2019-12-22 21:48:00 +0100\"\n      speakers:\n        - Nuno Silva\n      description: |-\n        [RubyCritic](https://github.com/whitesmith/rubycritic/) provides a\n        report about code quality. You can run it locally to view how your\n        project is doing and what are the smelly spots. A way of getting sense\n        of how your code quality is evolving over time is by setting it up on\n        your CI and storing the reports artefacts.\n      video_id: \"lrug-2020-01-13-rubys-a-critic\"\n      video_provider: \"not_published\"\n    - id: \"frederick-cheung-lrug-january-2020\"\n      title: \"Getting started with mruby\"\n      event_name: \"LRUG January 2020\"\n      date: \"2020-01-13\"\n      announced_at: \"2019-12-22 21:48:00 +0100\"\n      speakers:\n        - Frederick Cheung\n      description: |-\n        find out what [mruby](https://github.com/mruby/mruby) is, why you might\n        want to use it and obstacles you might encounter along the way.\n      video_id: \"lrug-2020-01-13-getting-started-with-mruby\"\n      video_provider: \"not_published\"\n- id: \"lrug-february-2020\"\n  title: \"LRUG February 2020\"\n  event_name: \"LRUG February 2020\"\n  date: \"2020-02-10\"\n  announced_at: \"2020-01-24 19:27:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-february-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/february/\n  talks:\n    - id: \"elena-tanasoiu-lrug-february-2020\"\n      title: \"You don't know what you don't know\"\n      event_name: \"LRUG February 2020\"\n      date: \"2020-02-10\"\n      announced_at: \"2020-01-24 19:27:00 +0100\"\n      speakers:\n        - Elena Tănăsoiu\n      description: |-\n        How to start an investigation into transitioning from a monolith to a\n        microservice architecture. A number of issues to consider before you\n        start and how to make a list of blockers on the way.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/february/elena-tanasoiu-you-dont-know-what-you-dont-know-lrug-feb-2020.mp4\"\n    - id: \"alfredo-motta-lrug-february-2020\"\n      title: \"Designing Domain-Oriented Observability in your system\"\n      event_name: \"LRUG February 2020\"\n      date: \"2020-02-10\"\n      announced_at: \"2020-01-24 19:27:00 +0100\"\n      speakers:\n        - Alfredo Motta\n      description: |-\n        What does it mean to make a system observable? Too often this is translated\n        into simply installing technical tools to measure low-level concerns like\n        memory, CPU or background queues size. In this talk, I will present the\n        concept of Domain-Oriented Observability, explore how it affects the cost\n        of maintaining your system and finally show some of the tools and solutions\n        that can help you put it into practice.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/february/alfredo-motta-designing-domain-oriented-observability-in-your-system-lrug-feb-2020.mp4\"\n    - id: \"jon-rowe-lrug-february-2020\"\n      title: \"Semantic Versioning, Ruby Versoning, and the forward march of progress\"\n      event_name: \"LRUG February 2020\"\n      date: \"2020-02-10\"\n      announced_at: \"2020-01-24 19:27:00 +0100\"\n      speakers:\n        - Jon Rowe\n      description: |-\n        [Jon Rowe](https://twitter.com/JonRowe) is going to tell us about how ruby\n        versioning interprets semantic versioning, and the problems that brings\n        for maintainers of projects like rspec that support multiple versions of\n        ruby.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/february/jon-rowe-semantic-versioning-ruby-versioning-and-the-forward-march-of-progress-lrug-feb-2020.mp4\"\n    - id: \"mugurel-chirica-lrug-february-2020\"\n      title: \"Influence your company beyond code\"\n      event_name: \"LRUG February 2020\"\n      date: \"2020-02-10\"\n      announced_at: \"2020-01-24 19:27:00 +0100\"\n      speakers:\n        - Mugurel Chirica\n      description: |-\n        It's important for all the engineers to realise that individually they are\n        able to help shape a company's culture, tech excellence, and tech direction.\n\n        There are various ways to achieve this, in this talk I'll present some of\n        the common options while focusing on creating communities of practice -\n        groups of people that meet with a common goal in mind and relevant to the\n        company's interest, both sponsored by leadership or started by engineers.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/february/mugurel-chirica-influence-your-company-beyond-writing-code-lrug-feb-2020.mp4\"\n    - id: \"nitish-rathi-lrug-february-2020\"\n      title: \"From confusion to contribution\"\n      event_name: \"LRUG February 2020\"\n      date: \"2020-02-10\"\n      announced_at: \"2020-01-24 19:27:00 +0100\"\n      speakers:\n        - Nitish Rathi\n      description: |-\n        How I refactored my way into an open source codebase, starting from a\n        state of confusion and ending up contributing to mocha, and some things\n        I learned along the way.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/february/nitish-rathi-from-confusion-to-contribution-lrug-feb-2020.mp4\"\n    - id: \"ali-najaf-lrug-february-2020\"\n      title: \"How to manage happy remote development teams\"\n      event_name: \"LRUG February 2020\"\n      date: \"2020-02-10\"\n      announced_at: \"2020-01-24 19:27:00 +0100\"\n      speakers:\n        - Ali Najaf\n      description: |-\n        Things I learned about how to manage and work on distributed\n        software development teams while keeping everyone happy, at least some of\n        the time.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/february/ali-najaf-how-to-manage-happy-remote-development-teams-lrug-feb-2020.mp4\"\n- id: \"lrug-march-2020\"\n  title: \"LRUG March 2020\"\n  event_name: \"LRUG March 2020\"\n  date: \"2020-03-09\"\n  announced_at: \"2020-02-20 21:55:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-march-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/march/\n  talks:\n    - id: \"stuart-harrison-lrug-march-2020\"\n      title: \"I got an email from the Government the other day\"\n      event_name: \"LRUG March 2020\"\n      date: \"2020-03-09\"\n      announced_at: \"2020-02-20 21:55:00 +0100\"\n      speakers:\n        - Stuart Harrison\n      description: |-\n        Email has been around for a long time, predating even the Internet, and\n        despite the best efforts of big tech to monopolise our communications,\n        it's still the most popular way to for people to communicate online.\n        This ubiquity means it's a really easy wayf or Government to keep in\n        touch with us, but email is a tricky thing to manage, running\n        mailservers can be a faff, and email as a service solutions can be\n        expensive. In this talk I'll go through a potted history of email, talk\n        about a tool that the Government Digital Service have developed to make\n        email easier for goverment agencies, and a Ruby gem I've build to make\n        it even easier for Rails devs.\n      video_id: \"lrug-2020-03-09-i-got-an-email-from-the-government-the-other-day\"\n      video_provider: \"not_published\"\n    - id: \"alex-balhatchet-lrug-march-2020\"\n      title: \"My first Rails bug report\"\n      event_name: \"LRUG March 2020\"\n      date: \"2020-03-09\"\n      announced_at: \"2020-02-20 21:55:00 +0100\"\n      speakers:\n        - Alex Balhatchet\n      description: |-\n        Story time! Here's the bug I found, how we determined it was a bug in\n        Rails 6, how we dealt with it including working around it and submitting\n        the bug report, and finally getting to remove our workaround once the\n        bug was fixed and the new Rails was installed :)\n      video_id: \"lrug-2020-03-09-my-first-rails-bug-report\"\n      video_provider: \"not_published\"\n    - id: \"james-hand-alan-bridger-lrug-march-2020\"\n      title: \"Tech for good with Ruby on Rails\"\n      event_name: \"LRUG March 2020\"\n      date: \"2020-03-09\"\n      announced_at: \"2020-02-20 21:55:00 +0100\"\n      speakers:\n        - James Hand\n        - Alan Bridger\n      description: |-\n        Giki Social Enterprise uses Ruby on Rails to help people live\n        sustainably. We'll talk about what we do and why Rails is such a good\n        framework for helping people to make sustainable and healthy choices.\n      video_id: \"lrug-2020-03-09-tech-for-good-with-ruby-on-rails\"\n      video_provider: \"not_published\"\n    - id: \"jairo-diaz-lrug-march-2020\"\n      title: \"London Ruby Events\"\n      event_name: \"LRUG March 2020\"\n      date: \"2020-03-09\"\n      announced_at: \"2020-02-20 21:55:00 +0100\"\n      speakers:\n        - Jairo Diaz\n      description: |-\n        I am going to tell you about the Ruby events in London that I am\n        organising such as the [Ruby Hacknight](https://www.meetup.com/ruby-hacknight-london/)\n        and [Ruby London Jobs](https://www.meetup.com/Ruby-Jobs-London/) and\n        other events for the community that are the most common. I will also\n        mention different event formats which I have experienced and found\n        useful for different purposes.\n      video_id: \"lrug-2020-03-09-london-ruby-events\"\n      video_provider: \"not_published\"\n- id: \"lrug-april-2020\"\n  title: \"LRUG April 2020\"\n  event_name: \"LRUG April 2020\"\n  date: \"2020-04-06\"\n  announced_at: \"2020-03-24 19:27:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-april-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/april/\n  talks:\n    - id: \"joel-chippindale-lrug-april-2020\"\n      title: \"How to take control of code quality\"\n      event_name: \"LRUG April 2020\"\n      date: \"2020-04-06\"\n      announced_at: \"2020-03-24 19:27:00 +0100\"\n      speakers:\n        - Joel Chippindale\n      description: |-\n        We all know how valuable it is to keep the quality of your code high. Working on a high\n        quality codebase is more enjoyable and enables us to deliver value much more effectively for\n        our users and yet, time and again I hear engineers saying, “I am not allowed to spend\n        sufficient time on code quality”.\n\n        This talk clarifies the value of maintaining a high quality codebase, gives you guidance on\n        how to talk about this to help you get the support of your colleagues and managers for\n        spending time on this and also outlines some key practices that will help you achieve this.\n      additional_resources:\n        - name: \"Transcript\"\n          type: \"transcript\"\n          title: \"How to take control of code quality\"\n          url: \"https://blog.mocoso.co.uk/talks/2020/02/27/take-control-of-code-quality/\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/april/joel-chippindale-how-to-take-control-of-your-code-quality-lrug-apr-2020.mp4\"\n      slides_url: \"https://blog.mocoso.co.uk/assets/take-control-of-code-quality/take-control-of-code-quality--lrug-apr-2020.pdf\"\n    - id: \"rob-mckinnon-lrug-april-2020\"\n      title: \"Music Experiments in Sonic Pi\"\n      event_name: \"LRUG April 2020\"\n      date: \"2020-04-06\"\n      announced_at: \"2020-03-24 19:27:00 +0100\"\n      speakers:\n        - Rob McKinnon\n      description: |-\n        Let's celebrate Sonic Pi's v3.2 release, scheduled for 28 Feb!\n        Sonic Pi's an open source Ruby code-based music creation and performance tool.\n\n        Rob's presenting a few experiments in Sonic Pi, covering oddities such as:\n\n        * negative melody\n        * Jianpu (numbered musical notation)\n        * just intonation\n        * microtonal music - 19 EDO (Equal Division of the Octave)\n        * interfacing with MIDI controllers over USB and bluetooth BLE.\n\n        Also Rob will walk us through a memory management improvement PR to Sonic Pi - that may have\n        made it into the release.\n      video_id: \"lrug-2020-04-06-music-experiments-in-sonic-pi\"\n      video_provider: \"not_published\"\n- id: \"lrug-may-2020\"\n  title: \"LRUG May 2020\"\n  event_name: \"LRUG May 2020\"\n  date: \"2020-05-11\"\n  announced_at: \"2020-04-25 20:22:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-may-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/may/\n  talks:\n    - id: \"peter-bell-lrug-may-2020\"\n      title: \"Comparing the speed and elegance of different computer languages using a Hamiltonian curve algorithm as the comparator\"\n      event_name: \"LRUG May 2020\"\n      date: \"2020-05-11\"\n      announced_at: \"2020-04-25 20:22:00 +0100\"\n      speakers:\n        - Peter Bell\n      description: |-\n        My company (Trapeze) specialises in public transport including schedule\n        optimisation. Finding Hamiltonian curves is a sub-problem to the\n        travelling salesman problem and of the general problem of optimising\n        pickup and drop-offs in demand responsive public transport. This talk\n        will compare implementing a Hamiltonian curve finder in a number of\n        different languages. The talk looks both at the speed of the language\n        and the elegance. For Ruby, I compare a couple of different\n        implementations. Other languages that are compared are Elixir, Go,\n        Javascript, Java, C++, C# and Python.\n\n        The source code is in a public Github repository details of which I will\n        provide as part of my talk\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/may/peter-bell-comparing-the-speed-and-elegance-of-different-computer-languages-lrug-may-2020.mp4\"\n    - id: \"sam-joseph-lrug-may-2020\"\n      title: \"Debugging Ruby HTTP Library Surprises\"\n      event_name: \"LRUG May 2020\"\n      date: \"2020-05-11\"\n      announced_at: \"2020-04-25 20:22:00 +0100\"\n      speakers:\n        - Sam Joseph\n      description: |-\n        Some folks prefer 'puts' to debugging with something like\n        pry-byebug, but I'm a huge fan of debuggers, particularly stepping\n        through my own code and the code of the many libraries we all rely on.\n        In combination with `bundle open` to insert breakpoints into the code of\n        gems being used in your stack, debugging can expose really tricky\n        dependency bugs, as I aim to demonstrate with one that I found in the\n        way different ruby HTTP libraries can interact.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/may/sam-joseph-debugging-ruby-http-library-surprises-lrug-may-2020.mp4\"\n- id: \"lrug-june-2020\"\n  title: \"LRUG June 2020\"\n  event_name: \"LRUG June 2020\"\n  date: \"2020-06-08\"\n  announced_at: \"2020-05-18 14:25:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-june-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/june/\n  talks:\n    - id: \"panos-matsinopoulos-lrug-june-2020\"\n      title: \"Hanami, another Opinionated Rack-based Framework\"\n      event_name: \"LRUG June 2020\"\n      date: \"2020-06-08\"\n      announced_at: \"2020-05-18 14:25:00 +0100\"\n      speakers:\n        - Panos Matsinopoulos\n      description: |-\n        [Panos Matsinopoulos](http://www.linkedin.com/in/panayotismatsinopoulos):\n\n        > We present Hanami and its differences to Rails. Then\n        > we show an integration case between a Hanami and a Rails project. Finally,\n        > we close with a PR on the Hanami project.\n\n        Panos is a Senior Software Engineer at [Lavanda](https://getlavanda.com/).\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/june/panos-matsinopoulos-hanami-another-opinionated-rack-based-framework-lrug-jun-2020.mp4\"\n    - id: \"alfredo-motta-lrug-june-2020\"\n      title: \"Agile or Waterfall; a risk management perspective\"\n      event_name: \"LRUG June 2020\"\n      date: \"2020-06-08\"\n      announced_at: \"2020-05-18 14:25:00 +0100\"\n      speakers:\n        - Alfredo Motta\n      description: |-\n        Today Agile is the default choice for software development out there. Every\n        conference, book, or blog post is telling us we are doomed to fail if we\n        don’t follow this established convention. But isn't it surprising to think\n        that Agile is advocated as the right methodology for every possible company\n        doing software out there? Are we going to organize software development\n        exactly the same way if we are working for a startup, NASA, or FedEx? It\n        seems hard to believe. In this presentation, I will explore the mental\n        model to help you choose when you should (or sometimes should not) use\n        Agile using the lenses of risk management. My goal is to provide guidance\n        for the puzzled business owner, project manager, or software developer who\n        wants to pick what's right for their company or team.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/june/alfredo-motta-agile-or-waterfall-a-risk-management-perspective-lrug-jun-2020.mp4\"\n- id: \"lrug-july-2020\"\n  title: \"LRUG July 2020\"\n  event_name: \"LRUG July 2020\"\n  date: \"2020-07-13\"\n  announced_at: \"2020-07-01 14:25:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-july-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/july/\n  talks:\n    - id: \"jolyon-pawlyn-lrug-july-2020\"\n      title: \"Improved security for password authentication\"\n      event_name: \"LRUG July 2020\"\n      date: \"2020-07-13\"\n      announced_at: \"2020-07-01 14:25:00 +0100\"\n      speakers:\n        - Jolyon Pawlyn\n      description: |-\n        [Jolyon Pawlyn](https://twitter.com/jpawlyn):\n\n        > Devise is a great authentication solution and is standard in many Rails\n        > applications. I want to look at 2 easy improvements to the default password\n        > validation. Then let's see what it takes to implement bare bones two-factor\n        > authentication using Devise and Warden.\n        >\n        > The security features to be covered can be viewed in [an example\n        application](https://github.com/jpawlyn/secure-user-accounts#secure-user-accounts).\n\n        Jolyon is a volunteer at Crowdfrica, ex Contentful, Wunder Mobility and Unboxed\n        Consulting, and also an aspiring yardener.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/july/jolyon-pawlyn-improved-security-for-password-authentication-lrug-jul-2020.mp4\"\n    - id: \"nicky-thompson-lrug-july-2020\"\n      title: \"Perfect is the enemy of good\"\n      event_name: \"LRUG July 2020\"\n      date: \"2020-07-13\"\n      announced_at: \"2020-07-01 14:25:00 +0100\"\n      speakers:\n        - Nicky Thompson\n      description: |-\n        [Nicky Thompson](https://twitter.com/knotnicky):\n\n        > This talk is a rambling rag-tag collection of software engineering and\n        > problem-solving lessons learned over the course of *mumble* years as a\n        > developer and now an engineering manager. It includes practical tips,\n        > philosophical insights, or just advice that other people gave me that I\n        > found helpful. These ideas have helped me be better at my job over the\n        > years. They are tried and tested, things that I have actually done\n        > throughout my career. They might or might not help you.\n\n        Nicky is an Engineering Manager at FutureLearn, providing management and support to the\n        Technology Team. Offline, Nicky enjoys watching bad TV and learning new stuff: this year\n        it's a serious sewing/dressmaking habit.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/july/nicky-thompson-perfect-is-the-enemy-of-good-lrug-jul-2020.mp4\"\n- id: \"lrug-august-2020\"\n  title: \"LRUG August 2020\"\n  event_name: \"LRUG August 2020\"\n  date: \"2020-08-10\"\n  announced_at: \"2020-08-02 22:21:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-august-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/august/\n  talks:\n    - id: \"matt-bee-lrug-august-2020\"\n      title: \"Language doesn't matter: what makes a senior engineer?\"\n      event_name: \"LRUG August 2020\"\n      date: \"2020-08-10\"\n      announced_at: \"2020-08-02 22:21:00 +0100\"\n      speakers:\n        - Matt Bee\n      description: |-\n        What makes a senior engineer? What other aspects of\n        being a senior engineer are as important, if not more important, than\n        knowing a programming language inside out. What things can you work on to\n        become or be a better senior engineer (that won't have a new framework out\n        by next week!). This is a set of lessons learned in a journey from self\n        taught front end developer to senior polyglot developer (via ruby).\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/august/matt-bee-language-doesnt-matter-what-makes-a-senior-engineer-lrug-aug-2020.mp4\"\n    - id: \"chris-zetter-lrug-august-2020\"\n      title: \"Doing the right thing\"\n      event_name: \"LRUG August 2020\"\n      date: \"2020-08-10\"\n      announced_at: \"2020-08-02 22:21:00 +0100\"\n      speakers:\n        - Chris Zetter\n      description: |-\n        Ethics are the principles of right and wrong that govern\n        our behaviour. Using examples from my experience, i'll share some tools\n        that you can use to understand ethical decisions and ways to help\n        ourselves and our team make the right choices.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/august/chris-zetter-doing-the-right-thing-lrug-aug-2020.mp4\"\n- id: \"lrug-september-2020\"\n  title: \"LRUG September 2020\"\n  event_name: \"LRUG September 2020\"\n  date: \"2020-09-14\"\n  announced_at: \"2020-08-31 20:38:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-september-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/september/\n  talks:\n    - id: \"matt-swanson-lrug-september-2020\"\n      title: \"StimulusJS: Modest JS for the HTML you have\"\n      event_name: \"LRUG September 2020\"\n      date: \"2020-09-14\"\n      announced_at: \"2020-08-31 20:38:00 +0100\"\n      speakers:\n        - Matt Swanson\n      description: |-\n        An overview of [StimulusJS](https://stimulusjs.org) (a small framework from Basecamp) and\n        discussion on when you might (or might not!) want to use it\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/september/matt-swanson-stimulusjs-modest-js-for-the-html-you-have-lrug-sep-2020.mp4\"\n      slides_url: \"https://docs.google.com/presentation/d/1uPA7CX_SGZPY2hFcf0YIvsSvCQzN7OTHVsvQnv5vKnY/\"\n    - id: \"duncan-brown-lrug-september-2020\"\n      title: \"Wizards without magic\"\n      event_name: \"LRUG September 2020\"\n      date: \"2020-09-14\"\n      announced_at: \"2020-08-31 20:38:00 +0100\"\n      speakers:\n        - Duncan Brown\n      description: |-\n        Multi-step forms (a.k.a wizards) are fiddly to build and difficult to\n        test. (And not just in Rails). Why is that, and how can we make them\n        better?\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/september/duncan-brown-wizards-without-magic-lrug-sep-2020.mp4\"\n- id: \"lrug-october-2020\"\n  title: \"LRUG October 2020\"\n  event_name: \"LRUG October 2020\"\n  date: \"2020-10-12\"\n  announced_at: \"2020-10-05 10:40:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-october-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/october/\n  talks:\n    - id: \"dan-moore-lrug-october-2020\"\n      title: \"JWTs - what Rails developers need to know\"\n      event_name: \"LRUG October 2020\"\n      date: \"2020-10-12\"\n      announced_at: \"2020-10-05 10:40:00 +0100\"\n      speakers:\n        - Dan Moore\n      description: |-\n        What is a JSON Web Token (JWT) and why do you care? JWTs\n        are a stateless, standardized way to represent user data. This talk will\n        discuss why JWTs matter and the nuts and bolts of JWTs. We’ll also discuss\n        how you might use a JWT in your Rails or Ruby application.\n      additional_resources:\n        - name: \"Link\"\n          type: \"link\"\n          title: \"Building a Secure Signed JWT\"\n          url: \"https://fusionauth.io/learn/expert-advice/tokens/building-a-secure-jwt\"\n        - name: \"Repository\"\n          type: \"repo\"\n          title: \"Ruby JWT Examples\"\n          url: \"https://github.com/fusionauth/fusionauth-example-ruby-jwt\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/october/dan-moore-jwts-what-rails-developers-need-to-know-lrug-oct-2020.mp4\"\n      slides_url: \"https://docs.google.com/presentation/d/1Sr52vuZzUB2EgdOw_CZD1tgbs5e0amCbfQH_Wx7iagQ/\"\n    - id: \"michael-mazour-lrug-october-2020\"\n      title: \"Getting Past the Tech Test\"\n      event_name: \"LRUG October 2020\"\n      date: \"2020-10-12\"\n      announced_at: \"2020-10-05 10:40:00 +0100\"\n      speakers:\n        - Michael Mazour\n      description: |-\n        Sometimes people have great backgrounds and great skills, but have trouble\n        getting hired because they didn't approach the tech test the way the\n        company wanted. As someone who reviews a lot of tech tests at work, I'm\n        going to explain some of the unwritten rules and expectations that you\n        might not know if you've been out of circulation or are just entering the\n        job market, and help you level up your tech test game.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/october/michael-mazour-getting-past-the-tech-test-lrug-oct-2020.mp4\"\n      slides_url: \"https://speakerdeck.com/mmazour/getting-past-the-tech-test\"\n- id: \"lrug-november-2020\"\n  title: \"LRUG November 2020\"\n  event_name: \"LRUG November 2020\"\n  date: \"2020-11-09\"\n  announced_at: \"2020-11-02 11:10:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-november-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/november/\n  talks:\n    - id: \"denny-de-la-haye-lrug-november-2020\"\n      title: \"Patches Welcome!\"\n      event_name: \"LRUG November 2020\"\n      date: \"2020-11-09\"\n      announced_at: \"2020-11-02 11:10:00 +0000\"\n      speakers:\n        - Denny de la Haye\n      description: |-\n        [Denny de la Haye](https://denny.me) says:\n\n        > Everybody at LRUG probably uses open source software - unless they got lost on\n        > the way to another meeting - but it often surprises me how few developers take\n        > the extra step from using it, to contributing to (or releasing their own) open\n        > source software projects. I'm going to talk about how I got involved in the\n        > open source community, why I stay involved, and about my current open source\n        > projects\n\n        [Denny de la Haye](https://denny.me) has been a programmer for nearly 30 years\n        now - \"although my ZX81 code is thankfully all lost in the mists of time (AKA\n        audio cassettes and thermal printer paper)\", he says. He has spent most of the\n        last 4+ years writing Ruby, and most of the 15+ before that writing Perl. The\n        switch between the two was less traumatic than he expected, but it did lead to\n        starting another open source software project last year...\n      additional_resources:\n        - name: \"Link\"\n          type: \"link\"\n          title: 'Links to pages and projects mentioned in \"Patches Welcome!\"'\n          url: \"https://denny.me/LRUG\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/november/denny-de-la-haye-patches-welcome-lrug-nov-2020.mp4\"\n    - id: \"cameron-dutro-lrug-november-2020\"\n      title: \"Convention over Kubernetes: (Almost) Configless Deploys with Kuby\"\n      event_name: \"LRUG November 2020\"\n      date: \"2020-11-09\"\n      announced_at: \"2020-11-02 11:10:00 +0000\"\n      speakers:\n        - Cameron Dutro\n      description: |-\n        [Cameron Dutro](https://twitter.com/camertron) says:\n\n        > Rails' most well-known mantra is \"convention over configuration,\" i.e. sane\n        > defaults that limit the cognitive overhead of application development. It's\n        > easy to learn and easy to build with. The development experience is\n        > fantastic... right up until the point you want to deploy your app to\n        > production. It's at that point that the hand-holding stops.\n        >\n        > Heroku to the rescue, right? Just push your git repo to \"heroku master\" and\n        > never think about deployment again! Heroku is a great option for many small\n        > projects and the ease of deployment is exactly the kind of experience Rails\n        > developers are used to. To quote Aaron Patterson: \"but at what cost?\" You're\n        > tied to Heroku's stack and stuck within the limitations of their free tier.\n        > Heroku's add-ons can get pretty expensive too if you decide to upgrade later\n        > on.\n        >\n        > How can we, but humble Rails devs, achieve the same seamless, turnkey\n        > deployment experience affordably? Enter the Kuby gem, a\n        > convention-over-configuration approach to deploying Rails apps using\n        > industry-leading technologies. Come learn how, with almost no configuration,\n        > you too can use Kuby to leverage Docker and Kubernetes to deploy your Rails\n        > app cost-effectively on a variety of cloud platforms.\n\n        [Cameron Dutro](https://twitter.com/camertron) currently works on the Quip team\n        at Salesforce. He's been programming in Ruby and using Rails for ten years and\n        has held previous positions at Fluther, Twitter, and Lumos Labs. When he's not\n        reading about, using, or working on technology, Cameron can be found hiking in\n        the hills behind his house or hanging out at home with his wife, daughter, and\n        cat.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/november/cameron-dutro-convention-over-kubernetes-almost-configless-deploys-with-kuby-lrug-nov-2020.mp4\"\n- id: \"lrug-december-2020\"\n  title: \"LRUG December 2020\"\n  event_name: \"LRUG December 2020\"\n  date: \"2020-12-14\"\n  announced_at: \"2020-11-27 11:10:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-december-2020\"\n  description: |-\n    https://lrug.org/meetings/2020/december/\n  talks:\n    - id: \"jonas-jabari-lrug-december-2020\"\n      title: \"Create a Twitter clone in 15 minutes in pure Ruby with Matestack\"\n      event_name: \"LRUG December 2020\"\n      date: \"2020-12-14\"\n      announced_at: \"2020-11-27 11:10:00 +0000\"\n      speakers:\n        - Jonas Jabari\n      description: |-\n        Matestack enables you to implement reactive web UIs in pure Ruby, skipping\n        ERB, HTML and JavaScript. In a live coding session, we will create a Twitter\n        clone using Matestack's core features from scratch!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2020/december/jonas-jabari-create-a-twitter-clone-in-15-minutes-in-pure-ruby-with-matestack.lrug-dec-2020.mp4\"\n- id: \"lrug-january-2021\"\n  title: \"LRUG January 2021\"\n  event_name: \"LRUG January 2021\"\n  date: \"2021-01-11\"\n  announced_at: \"2020-12-22 21:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-january-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/january/\n  talks:\n    - id: \"thayer-prime-lrug-january-2021\"\n      title: \"Recruiting 101 instead of 404\"\n      event_name: \"LRUG January 2021\"\n      date: \"2021-01-11\"\n      announced_at: \"2020-12-22 21:30:00 +0000\"\n      speakers:\n        - Thayer Prime\n      description: |-\n        [Thayer Prime](https://twitter.com/teamPrimeLtd) says:\n\n        > Recruitment is one of the hardest problems in scaling your tech company.\n        > Everyone wants the best, everyone wants diversity in hires, everyone\n        > wants the most affordable people - but companies rarely have the time,\n        > money or ability to invest in creating a world class recruiting team. So\n        > what are some of the common questions we can review, and how do you\n        > navigate the pitfalls of bad hiring as a starter for ten? Come and find\n        > out from an LRUG community Q&A to address some of the most commonly\n        > asked questions, and get some starter tips on hiring humans, not\n        > resources.\n        >\n        > Your Qs will be A'd by [Thayer Prime, of Team\n        > Prime](https://team-prime.com/about/) who started life in the tech\n        > industry as a programmer twenty years ago, before turning to the dark\n        > arts of recruitment. She's been lucky enough to work with the likes of\n        > Sir Tim Berners-Lee, Jimmy Wales, Apple, Stripe and NASA to name just a\n        > few. She has founded three successful companies herself, and often acts\n        > as a strategic adviser to founders and C-level executives growing their\n        > tech capacity within their organisations.\n\n        For info on how to submit questions for the talk [check out Thayer's email\n        to the mailing list](http://lists.lrug.org/pipermail/chat-lrug.org/2020-December/025636.html)\n        explaining the situation.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/january/thayer-prime-recruiting-101-instead-of-404-lrug-jan-2021.mp4\"\n- id: \"lrug-february-2021\"\n  title: \"LRUG February 2021\"\n  event_name: \"LRUG February 2021\"\n  date: \"2021-02-08\"\n  announced_at: \"2021-01-24 21:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-february-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/february/\n  talks:\n    - id: \"ayush-newatia-lrug-february-2021\"\n      title: \"An intro to Bridgetown: A static site generator for the modern JAMStack era.\"\n      event_name: \"LRUG February 2021\"\n      date: \"2021-02-08\"\n      announced_at: \"2021-01-24 21:30:00 +0000\"\n      speakers:\n        - Ayush Newatia\n      description: |-\n        [Bridgetown](https://www.bridgetownrb.com) is a new Ruby-powered static\n        site generator that was forked from Jekyll 4.1. It has a focus on modern\n        ideas and includes Webpack as a first-class citizen. In this talk I'll\n        give a demo of what differentiates Bridgetown from Jekyll and some of\n        its best features; followed by a short Q&A.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/february/ayush-newatia-an-intro-to-bridgetown-a-static-site-generator-for-the-modern-jamstack-era-lrug-feb-2021.mp4\"\n    - id: \"frederick-cheung-lrug-february-2021\"\n      title: \"The Path(name) of least resistance\"\n      event_name: \"LRUG February 2021\"\n      date: \"2021-02-08\"\n      announced_at: \"2021-01-24 21:30:00 +0000\"\n      speakers:\n        - Frederick Cheung\n      description: |-\n        Ruby has many classes that deal with files, paths or directories, but\n        one that often doesn't get enough credit is\n        [Pathname](https://github.com/ruby/pathname). Pathname unifies the other\n        pretenders to the throne with a consistent, rubyish interface that is a\n        joy to work with.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/february/fred-cheung-the-pathname-of-least-resistance-lrug-feb-2021.mp4\"\n    - id: \"lorenzo-barasti-lrug-february-2021\"\n      title: \"Are we parallel yet? A first look at Ruby Ractors\"\n      event_name: \"LRUG February 2021\"\n      date: \"2021-02-08\"\n      announced_at: \"2021-01-24 21:30:00 +0000\"\n      speakers:\n        - Lorenzo Barasti\n      description: |-\n        A speedrun through actor-based concurrency, the Ractor API and the\n        future of parallel applications in Ruby.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/february/lorenzo-barasti-are-we-parallel-yet-a-first-look-at-ruby-ractors-lrug-feb-2021.mp4\"\n    - id: \"mark-burns-lrug-february-2021\"\n      title: \"Uncovering some ruby magic in `awesome_print`\"\n      event_name: \"LRUG February 2021\"\n      date: \"2021-02-08\"\n      announced_at: \"2021-01-24 21:30:00 +0000\"\n      speakers:\n        - Mark Burns\n      description: |-\n        `ap 1.methods` takes an `Array` of `Symbol`s as input and outputs\n        details it shouldn't know about the methods themselves. `ap\n        1.methods.dup` has the same behaviour, but `ap\n        1.methods.take(1.methods.length)` does not. I will peer into the magic\n        and divulge its secrets.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/february/mark-burns-uncovering-some-ruby-magic-in-awesome_print-lrug-feb-2021.mp4\"\n    - id: \"mike-rogers-lrug-february-2021\"\n      title: \"Taking Rails Offline\"\n      event_name: \"LRUG February 2021\"\n      date: \"2021-02-08\"\n      announced_at: \"2021-01-24 21:30:00 +0000\"\n      speakers:\n        - Mike Rogers\n      description: |-\n        Networks are unreliable & drop out all the time! Lets make our apps more\n        resilient to that!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/february/mike-rogers-taking-rails-offline-lrug-feb-2021.mp4\"\n- id: \"lrug-march-2021\"\n  title: \"LRUG March 2021\"\n  event_name: \"LRUG March 2021\"\n  date: \"2021-03-08\"\n  announced_at: \"2021-02-25 10:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-march-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/march/\n  talks:\n    - id: \"matt-patterson-lrug-march-2021\"\n      title: \"Data as a foreign language, or: A tale of two (or possibly three) type systems\"\n      event_name: \"LRUG March 2021\"\n      date: \"2021-03-08\"\n      announced_at: \"2021-02-25 10:30:00 +0000\"\n      speakers:\n        - Matt Patterson\n      description: |-\n        Working with XSLT/XPath’s XDM type system in Ruby requires learning how to\n        translate between two very different type systems in a way which allows for\n        idiomatic Ruby without ignoring the bits of XDM which aren’t quite Ruby-shaped.\n        Oh, and the only open-source implementation is in Java, so Java’s type system is\n        in the mix.\n\n        I’ll look at a couple of cases where the different approaches and\n        assumptions of Ruby and XDM (and Java, which just can’t help sticking\n        its nose in) interact in an interesting way.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/march/matt-patterson-data-as-a-foreign-language-or-a-tale-of-two-or-possibly-three-type-systems-lrug-mar-2021.mp4\"\n    - id: \"max-shelley-lrug-march-2021\"\n      title: \"Sundae Club: Livestreaming Ruby on Rails\"\n      event_name: \"LRUG March 2021\"\n      date: \"2021-03-08\"\n      announced_at: \"2021-02-25 10:30:00 +0000\"\n      speakers:\n        - Max Shelley\n      description: |-\n        I host a [weekly livestream](https://www.youtube.com/c/sundaeclub) where\n        each week I work on a Ruby on Rails app and, along with those watching, we\n        plan then build different features and discuss different possible\n        approaches. It’s casual, aimed very loosely at learners, hopefully useful\n        and receives positive feedback from those that watch or interact.\n\n        When I mention livestreaming to others, they’re often interested in how it\n        works, what I get from doing it, what those who interact with the streams\n        get out of it and how they could potentially get involved in streaming.\n        This talk aims to answer those questions, along with any others you may\n        have, come and say hello!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/march/max-shelley-sundae-club-livestreaming-ruby-on-rails-lrug-mar-2021.mp4\"\n- id: \"lrug-april-2021\"\n  title: \"LRUG April 2021\"\n  event_name: \"LRUG April 2021\"\n  date: \"2021-04-12\"\n  announced_at: \"2021-03-15 22:44:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-april-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/april/\n  talks:\n    - id: \"brooke-kuhlmann-lrug-april-2021\"\n      title: \"Git Rebase\"\n      event_name: \"LRUG April 2021\"\n      date: \"2021-04-12\"\n      announced_at: \"2021-03-15 22:44:00 +0000\"\n      speakers:\n        - Brooke Kuhlmann\n      description: |-\n        Git is the dominant tool for version management. Misunderstanding and\n        misusing Git can cost development teams time, energy, and money. Few\n        better examples exist than Git's default merge workflow which creates\n        repositories that are hard to read, debug, and maintain. In this\n        talk, I'll show how to use the [Git Rebase\n        Workflow](https://www.alchemists.io/articles/git_rebase) instead,\n        which puts Git to work for you to produce quality code that's easy to\n        handle and kicks your team into high gear.\n\n        Your questions will be answered by [Brooke\n        Kuhlmann](https://www.alchemists.io/team/brooke_kuhlmann) who is the\n        founder of the [Alchemists](https://www.alchemists.io) where the\n        mission is to create an inclusive and thoughtful collective focused\n        on the craft, quality, ethics, and security of software engineering.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/april/brooke-kuhlmann-git-rebase-lrug-apr-2021.mp4\"\n      slides_url: \"https://www.alchemists.io/presentations/git_rebase/\"\n- id: \"lrug-may-2021\"\n  title: \"LRUG May 2021\"\n  event_name: \"LRUG May 2021\"\n  date: \"2021-05-10\"\n  announced_at: \"2021-04-25 16:40:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-may-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/may/\n  talks:\n    - id: \"ayush-newatia-lrug-may-2021\"\n      title: \"Your fortified cookie jar: Demystifying cookie security in Rails\"\n      event_name: \"LRUG May 2021\"\n      date: \"2021-05-10\"\n      announced_at: \"2021-04-25 16:40:00 +0000\"\n      speakers:\n        - Ayush Newatia\n      description: |-\n        You may have heard that cookie security is hard with the need to worry\n        special flags and encryption. Actually, Ruby on Rails makes it super\n        simple to securely store data in cookies. In this talk I'll explain the\n        different types of cookies supported by Rails and what Rails does under\n        the hood to secure the data they contain.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/may/ayush-newatia-your-fortified-cookie-jar-lrug-may-2021.mp4\"\n    - id: \"tom-lord-lrug-may-2021\"\n      title: \"Is this feature a waste of time?\"\n      event_name: \"LRUG May 2021\"\n      date: \"2021-05-10\"\n      announced_at: \"2021-04-25 16:40:00 +0000\"\n      speakers:\n        - Tom Lord\n      description: |-\n        Sometimes a new feature may be objectively worthwhile; but often one\n        might be left wondering “Does this actually make our product better?”,\n        or “Is this making the business more money?”.\n\n        In this talk, I will explore the virtues of defining North Star metrics,\n        AB testing product variations to statistical significance, and using\n        funnel analysis to quantify a feature's value.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/may/tom-lord-is-this-feature-a-waste-of-time-lrug-may-2021.mp4\"\n- id: \"lrug-july-2021\"\n  title: \"LRUG July 2021\"\n  event_name: \"LRUG July 2021\"\n  date: \"2021-07-12\"\n  announced_at: \"2021-06-22 22:05:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-july-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/july/\n  talks:\n    - id: \"hemal-varambhia-lrug-july-2021\"\n      title: \"Breaking Up Monoliths With CRC cards\"\n      event_name: \"LRUG July 2021\"\n      date: \"2021-07-12\"\n      announced_at: \"2021-06-22 22:05:00 +0100\"\n      speakers:\n        - Hemal Varambhia\n      description: |-\n        Rapid iteration and feedback is key to enhancing agility. This is an\n        experience report on how we appealed to a modelling technique from the\n        1980s, CRC cards, to figure out how we might break away part of a monolith\n        at the architectural level and guide refactorings at the softer design\n        level.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/july/hemal-varambhia-breaking-up-monoliths-with-crc-cards-lrug-jul-2021.mp4\"\n    - id: \"alex-rudall-lrug-july-2021\"\n      title: \"Ruby on Rails for Fun and Social Good\"\n      event_name: \"LRUG July 2021\"\n      date: \"2021-07-12\"\n      announced_at: \"2021-06-22 22:05:00 +0100\"\n      speakers:\n        - Alex Rudall\n      description: |-\n        Beam is the world's first crowdfunding platform for homelessness. Alex\n        will talk about what Beam does and how Beam uses Ruby on Rails,\n        Airtable, Vue.js and Tailwind to help them change the lives of homeless\n        people.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/july/alex-rudall-ruby-on-rails-for-fun-and-social-good-lrug-jul-2021.mp4\"\n    - id: \"rob-faldo-lrug-july-2021\"\n      title: \"Improving Rails scalability using modularity with enforced boundaries\"\n      event_name: \"LRUG July 2021\"\n      date: \"2021-07-12\"\n      announced_at: \"2021-06-22 22:05:00 +0100\"\n      speakers:\n        - Rob Faldo\n      description: |-\n        One of the aspects of Ruby & Rails that gives it the reputation for not\n        scaling well is that unlike some languages/frameworks it has no way to\n        enforce modularity. Over time and with many developers this usually\n        leads to 'spaghetti code'. This talk will introduce a solution to this\n        problem called [packwerk](https://github.com/Shopify/packwerk) (a ruby\n        gem by Shopify), as well as touch on some alternatives.\n      additional_resources:\n        - name: \"Link\"\n          type: \"link\"\n          title: 'Blog post on \"Improving Rails scalability using modularity with enforced boundaries\"'\n          url: \"https://robertfaldo.medium.com/improving-rails-scalability-using-the-modular-monolith-approach-with-enforced-boundaries-f8cea89e85b9\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/july/rob-faldo-improving-rails-scalability-using-modularity-with-enforced-boundaries-lrug-jul-2021.mp4\"\n      slides_url: \"https://docs.google.com/presentation/d/12EjD9OtIOtFpRqBaFKWmu4y1ogJK-WsO8l5TgTt1EmI/edit?usp=sharing\"\n- id: \"lrug-august-2021\"\n  title: \"LRUG August 2021\"\n  event_name: \"LRUG August 2021\"\n  date: \"2021-08-09\"\n  announced_at: \"2021-07-21 17:35:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-august-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/august/\n  talks:\n    - id: \"tom-blomfield-lrug-august-2021\"\n      title: \"10 years on - building startups with Ruby on Rails\"\n      event_name: \"LRUG August 2021\"\n      date: \"2021-08-09\"\n      announced_at: \"2021-07-21 17:35:00 +0100\"\n      speakers:\n        - Tom Blomfield\n      description: |-\n        Tom was the founder of GoCardless (built in Ruby) and Monzo.\n        He recently joined the board of Generation Home (also Ruby) - a\n        London-based mortgage provider. He's come back to talk about the evolution\n        of the London startup community and how successful fintechs are still\n        building on Ruby on Rails\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/august/tom-blomfield-10-years-on-building-startups-with-ruby-on-rails-lrug-aug-2021.mp4\"\n    - id: \"daniel-magliola-lrug-august-2021\"\n      title: \"Do regex dream of Turing Completeness?\"\n      event_name: \"LRUG August 2021\"\n      date: \"2021-08-09\"\n      announced_at: \"2021-07-21 17:35:00 +0100\"\n      speakers:\n        - Daniel Magliola\n      description: |-\n        We're used to using Regular Expressions every day for pattern matching and\n        text replacement, but... What can Regexes actually do? How far can we push\n        them? Can we implement actual logic with them?\n\n        What if I told you... You can actually implement Conway's Game of Life with\n        just a Regex? What if I told you... You can actually implement ANYTHING with\n        just a Regex?\n\n        Join me on a wild ride exploring amazing Game of Life patterns, unusual Regex\n        techniques, Turing Completeness, programatically generating complex Regexes\n        with Ruby, and what all this means for ou understanding of what a Regex can\n        do.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/august/daniel-magliola-do-regex-dream-of-turing-completeness-lrug-aug-2021.mp4\"\n- id: \"lrug-september-2021\"\n  title: \"LRUG September 2021\"\n  event_name: \"LRUG September 2021\"\n  date: \"2021-09-13\"\n  announced_at: \"2021-08-24 20:39:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-september-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/september/\n  talks:\n    - id: \"jade-dickinson-lrug-september-2021\"\n      title: \"How to use flamegraphs to find performance problems\"\n      event_name: \"LRUG September 2021\"\n      date: \"2021-09-13\"\n      announced_at: \"2021-08-24 20:39:00 +0100\"\n      speakers:\n        - Jade Dickinson\n      description: |-\n        [Jade Dickinson](https://twitter.com/_jadedickinson) will be running an interactive workshop:\n\n        > Slow Ruby code can be a puzzle, but it doesn’t have to be that way. In this\n        > talk you will see how fun it can be to use flamegraphs to find performance\n        > problems. You’ll enjoy this talk if you know you have slow areas in your\n        > Ruby application\\*, and would like to learn how to find the code responsible.\n\n        You can find out more about what you need to prepare for the workshop via [Jade's mailing\n        list post about it][mailing-list-post].\n\n        [mailing-list-post]: http://lists.lrug.org/pipermail/chat-lrug.org/2021-September/025800.html\n      video_id: \"lrug-2021-09-13-how-to-use-flamegraphs-to-find-performance-problems\"\n      video_provider: \"not_published\"\n- id: \"lrug-october-2021\"\n  title: \"LRUG October 2021\"\n  event_name: \"LRUG October 2021\"\n  date: \"2021-10-11\"\n  announced_at: \"2021-09-20 22:04:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-october-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/october/\n  talks:\n    - id: \"fritz-meissner-lrug-october-2021\"\n      title: \"Solargraph: A Ruby language server to make your editor smart\"\n      event_name: \"LRUG October 2021\"\n      date: \"2021-10-11\"\n      announced_at: \"2021-09-20 22:04:00 +0100\"\n      speakers:\n        - Fritz Meissner\n      description: |-\n        Language servers like [Solargraph](https://solargraph.org) can give code\n        editing superpowers to your favourite editor (Emacs, Vim, VSCode, etc.).\n        I'll talk about the Language Server Protocol and its advantages over\n        editor-specific plugins, as well as how Solargraph learns about your\n        Ruby. I'll also talk about the challenges that Rails poses for such\n        tooling and how solargraph-rails attempts to overcome them.\n      additional_resources:\n        - name: \"Write-Up\"\n          type: \"write-up\"\n          title: \"If The Shoe Fritz - A conversation between your editor and a language server\"\n          url: \"http://iftheshoefritz.com/lsp/intellisense/solargraph/2021/07/24/conversation-editor-lsp.html\"\n        - name: \"Source Code\"\n          type: \"code\"\n          title: \"The solargraph-rails plugin\"\n          url: \"https://github.com/iftheshoefritz/solargraph-rails\"\n        - name: \"Source Code\"\n          type: \"code\"\n          title: \"The solargraph project\"\n          url: \"https://github.com/castwide/solargraph\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/october/fritz-meissner-your-editor-language-server-protocol-and-solargraph-lrug-oct-2021.mp4\"\n      slides_url: \"http://iftheshoefritz.com/lsp/intellisense/solargraph/lrug/2021/10/11/lrug-solargraph.html\"\n    - id: \"thierry-deo-lrug-october-2021\"\n      title: \"How denormalizing our Postgres turned great\"\n      event_name: \"LRUG October 2021\"\n      date: \"2021-10-11\"\n      announced_at: \"2021-09-20 22:04:00 +0100\"\n      speakers:\n        - Thierry Deo\n      description: |-\n        It's often considered best practice to normalize the database structure\n        to avoid data redundancy and incoherence. In Pennylane's accounting\n        platform we've found that this actually does not always help with data\n        coherence, and even introduces additional complexity in managing data\n        access. Our combination of denormalizing some of our data, enhancing\n        some of ActiveRecord's methods, and introducing default behaviors in our\n        application models has enabled us to greatly simplify access control\n        management and given us confidence that our production data is in a\n        consistent state.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/october/thierry-deo-how-denormalizing-our-postgres-turned-great-lrug-oct-2021.mp4\"\n    - id: \"joel-biffin-lrug-october-2021\"\n      title: \"Memoization: My Favourite Antipattern\"\n      event_name: \"LRUG October 2021\"\n      date: \"2021-10-11\"\n      announced_at: \"2021-09-20 22:04:00 +0100\"\n      speakers:\n        - Joel Biffin\n      description: |-\n        As Rubyists we love to use built-in language features to set ourselves\n        apart for the rest. It's part of what makes programming in Ruby so\n        enjoyable! **Memoization** is no exception to this. But, *what if we\n        don't really need all of that memoization*? *Is memoization an\n        anti-pattern in its own right?*\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/october/joel-biffin-memoization-my-favourite-antipattern-lrug-oct-2021.mp4\"\n- id: \"lrug-november-2021\"\n  title: \"LRUG November 2021\"\n  event_name: \"LRUG November 2021\"\n  date: \"2021-11-08\"\n  announced_at: \"2021-10-28 09:40:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-november-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/november/\n  talks:\n    - id: \"christian-gregg-lrug-november-2021\"\n      title: \"Failing better w/ Load Shedding & Deadline Propagation across services\"\n      event_name: \"LRUG November 2021\"\n      date: \"2021-11-08\"\n      announced_at: \"2021-10-28 09:40:00 +0100\"\n      speakers:\n        - Christian Gregg\n      description: |-\n        As services start to split off from your majestic monolith, cascading\n        failures as a single service or endpoint slows down can become a\n        recurring problem which very quickly can lead to service unavailability.\n        Implementing load-shedding and deadline propagation across your services\n        is a technique which can help you provide a more resilient service to\n        your customers. This talk will introduce some of the concepts explored\n        in [CGA1123/loadshedding-experiment-ruby][experiment]\n        & [CGA1123/shed][shed].\n\n        [experiment]: https://github.com/CGA1123/loadshedding-experiment-ruby\n        [shed]: https://github.com/CGA1123/shed\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/november/christian-gregg-failing-better-with-load-shedding-and-deadline-propagation-across-services-lrug-nov-2021.mp4\"\n      slides_url: \"https://github.com/lrug/lrug.org/files/7529520/presentation.pdf\"\n    - id: \"chris-parsons-lrug-november-2021\"\n      title: \"Why Rails is still relevant for startups in 2021\"\n      event_name: \"LRUG November 2021\"\n      date: \"2021-11-08\"\n      announced_at: \"2021-10-28 09:40:00 +0100\"\n      speakers:\n        - Chris Parsons\n      description: |-\n        With the rise of single page JavaScript apps, lo-code, and mobile-first,\n        is Rails consigned to the legacy dustbin of frameworks last cool in\n        2008? The answer is emphatically “no” - Rails is as relevant as ever for\n        startups in 2021. Chris will talk about how Rails has supercharged the\n        early stage of his new startup, LollipopAI, and how Rails gave them\n        quick experiments, good-enough domain modelling and tooling that just\n        works.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/november/chris-parsons-why-rails-is-still-relevant-for-startups-in-2021-lrug-nov-2021.mp4\"\n      slides_url: \"https://speakerdeck.com/chrismdp/why-rails-is-still-relevant-for-startups-in-2021\"\n    - id: \"patricia-cupueran-lrug-november-2021\"\n      title: \"Service Objects and Domain objects differences\"\n      event_name: \"LRUG November 2021\"\n      date: \"2021-11-08\"\n      announced_at: \"2021-10-28 09:40:00 +0100\"\n      speakers:\n        - Patricia Cupueran\n      description: |-\n        Understanding what a service and domain objects are. Distinguishing the\n        difference between procedures and objects. Why using service objects is\n        a bad idea. Advantages of using modules, concerns and PORO's instead of\n        service objects.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/november/patricia-cupueran-service-objects-and-domain-objects-differences-lrug-nov-2021.mp4\"\n- id: \"lrug-december-2021\"\n  title: \"LRUG December 2021\"\n  event_name: \"LRUG December 2021\"\n  date: \"2021-12-13\"\n  announced_at: \"2021-11-28 19:39:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-december-2021\"\n  description: |-\n    https://lrug.org/meetings/2021/december/\n  talks:\n    - id: \"kevin-murphy-lrug-december-2021\"\n      title: \"Enough coverage to beat the band\"\n      event_name: \"LRUG December 2021\"\n      date: \"2021-12-13\"\n      announced_at: \"2021-11-28 19:39:00 +0100\"\n      speakers:\n        - Kevin Murphy\n      description: |-\n        The lights cut out. The crowd roars. It’s time. The band takes the stage.\n        They’ve practiced the songs, particularly the *covers*. They’ve sound\n        checked the *coverage* of the speakers. They know the lighting rig has the\n        proper colored gels *covering* the lamps. They’re nervous, but they’ve got\n        it all __covered__.\n      additional_resources:\n        - name: \"Link\"\n          type: \"link\"\n          title: \"Presentation Resources\"\n          url: \"https://kevinjmurphy.com/coverage\"\n        - name: \"Link\"\n          type: \"link\"\n          title: \"Blog post: Ruby's Got You Covered\"\n          url: \"https://dev.to/kevin_j_m/rubys-got-you-covered-2c6k\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/december/kevin-murphy-enough-coverage-to-beat-the-band-lrug-dec-2021.mp4\"\n    - id: \"johnson-zhan-lrug-december-2021\"\n      title: \"When ActiveRecord meets CTE!?\"\n      event_name: \"LRUG December 2021\"\n      date: \"2021-12-13\"\n      announced_at: \"2021-11-28 19:39:00 +0100\"\n      speakers:\n        - Johnson Zhan\n      description: |-\n        CTE (`Common Table Expression`) is one of the ways we handle complicated\n        SQL queries. However, ActiveRecord does not support CTE directly so I used\n        to write some raw SQL to implement CTE. Now, I found there is a useful gem\n        called `activerecord-cte` which makes things different.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/december/johnson-zhan-when-activerecord-meets-cte-lrug-dec-2021.mp4\"\n    - id: \"alex-balhatchet-lrug-december-2021\"\n      title: \"Finding, hiring and onboarding junior Ruby developers\"\n      event_name: \"LRUG December 2021\"\n      date: \"2021-12-13\"\n      announced_at: \"2021-11-28 19:39:00 +0100\"\n      speakers:\n        - Alex Balhatchet\n      description: |-\n        The Ruby community in London has a huge number of junior\n        developers, largely thanks to bootcamps like Le Wagon and Makers Academy.\n        This talk describes my experiences finding, hiring and onboarding junior\n        devs. The aim is for the hiring managers in the room to feel more confident\n        hiring junior devs for their teams, and for the junior devs in the room to\n        feel more confident asking for support and learning opportunities.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2021/december/alex-balhatchet-finding-hiring-and-onboarding-junior-ruby-developers-lrug-dec-2021.mp4\"\n      slides_url: \"https://alex.balhatchet.net/slides/2021-12-13-Hiring-Junior-Ruby-Devs.pdf\"\n- id: \"lrug-january-2022\"\n  title: \"LRUG January 2022\"\n  event_name: \"LRUG January 2022\"\n  date: \"2022-01-10\"\n  announced_at: \"2021-12-24 20:30:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-january-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/january/\n  talks:\n    - id: \"-lrug-january-2022\"\n      title: \"LRUG Pub quiz\"\n      event_name: \"LRUG January 2022\"\n      date: \"2022-01-10\"\n      announced_at: \"2021-12-24 20:30:00 +0100\"\n      speakers:\n        - \"\"\n      description: |-\n        > Are you proud of your knowledge of Ruby and Ruby on Rails? Invite your\n        > friends, and win bragging rights. Or simply invite them and enjoy spending\n        > time with them.\n\n        The quiz will have 4 categories, and each category will have between 20 and 30\n        questions. The 4 categories are:\n\n        - Ruby\n        - Ruby on Rails\n        - General computing\n        - London\n      video_id: \"lrug-2022-01-10-pub-quiz\"\n      video_provider: \"not_published\"\n- id: \"lrug-february-2022\"\n  title: \"LRUG February 2022\"\n  event_name: \"LRUG February 2022\"\n  date: \"2022-02-21\"\n  announced_at: \"2022-01-13 21:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-february-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/february/\n  talks:\n    - id: \"frederick-cheung-lrug-february-2022\"\n      title: \"Javascript in Rails: A New Hope\"\n      event_name: \"LRUG February 2022\"\n      date: \"2022-02-21\"\n      announced_at: \"2022-01-13 21:30:00 +0000\"\n      speakers:\n        - Frederick Cheung\n      description: |-\n        Tired of slow webpack builds and daunting configuration files?\n        Find out how the new css-bundling and js-bundling gems can roll back the years\n        and make javascript in rails fast and simple again.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/february/speaker-frederick-cheung-javascript-in-rails-a-new-hope-lrug-feb-2022.mp4\"\n    - id: \"pablo-dejuan-lrug-february-2022\"\n      title: \"Getting past enemy images\"\n      event_name: \"LRUG February 2022\"\n      date: \"2022-02-21\"\n      announced_at: \"2022-01-13 21:30:00 +0000\"\n      speakers:\n        - Pablo Dejuan\n      description: |-\n        Enemy images hinder our communication with people when we need them\n        the most: to agree with another colleague over a code review, to interview\n        a third party, to have an important conversation with our boss or direct\n        report (technical or non-technical topic).\n        In this talk we will raise awareness and cover one way of overcoming the\n        initial enemy image to get a better outcome for us and our team.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/february/speaker-pablo-dejuan-getting-past-enemy-images-lrug-feb-2022.mp4\"\n    - id: \"jared-turner-lrug-february-2022\"\n      title: \"The tale of the 60+ second page loads\"\n      event_name: \"LRUG February 2022\"\n      date: \"2022-02-21\"\n      announced_at: \"2022-01-13 21:30:00 +0000\"\n      speakers:\n        - Jared Turner\n      description: |-\n        A monstrous mystery and a head-scratching hunt. Follow along to discover\n        why, just why, is that darn page so slow!?\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/february/speaker-jared-turner-the-tale-of-the-60-plus-second-page-loads-lrug-feb-2022.mp4\"\n      slides_url: \"https://docs.google.com/presentation/d/1-vodmNcE930xHAjb5kyCiI3eJyZFPuUL48njnoPNlvM\"\n    - id: \"fritz-meissner-lrug-february-2022\"\n      title: \"solargraph-dead_end\"\n      event_name: \"LRUG February 2022\"\n      date: \"2022-02-21\"\n      announced_at: \"2022-01-13 21:30:00 +0000\"\n      speakers:\n        - Fritz Meissner\n      description: |-\n        The awesome dead_end gem gives really good feedback on where that elusive\n        missing `end` keyword is hiding in your Ruby file.\n        At a thoughtbot hackathon a few of us worked on a solargraph plugin\n        for it so you can get this feedback in your editor. Come hear about\n        the results!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/february/speaker-fritz-meissner-solargraph-dead-end-lrug-feb-2022.mp4\"\n    - id: \"simon-fish-lrug-february-2022\"\n      title: \"Introducing ViewComponent\"\n      event_name: \"LRUG February 2022\"\n      date: \"2022-02-21\"\n      announced_at: \"2022-01-13 21:30:00 +0000\"\n      speakers:\n        - Simon Fish\n      description: |-\n        The view layer is the Wild West of Rails. Let's look at how ViewComponent\n        helps you break down and test your Rails views.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/february/speaker-simon-fish-introducing-viewcomponent-lrug-feb-2022.mp4\"\n    - id: \"marija-mandic-lrug-february-2022\"\n      title: \"A Little Pessimism Never Killed Nobody\"\n      event_name: \"LRUG February 2022\"\n      date: \"2022-02-21\"\n      announced_at: \"2022-01-13 21:30:00 +0000\"\n      speakers:\n        - Marija Mandić\n      description: |-\n        Come join and hear my experience on a real life example of concurrency problem\n        and different approaches to fixing it.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/february/speaker-marija-mandic-a-little-pessimism-never-killed-nobody-lrug-feb-2022.mp4\"\n    - id: \"pj-johnstone-lrug-february-2022\"\n      title: \"Metaprogramming I Do In My Side Projects That My Colleagues Won't Let Me Do In The Real App At Work :-(\"\n      event_name: \"LRUG February 2022\"\n      date: \"2022-02-21\"\n      announced_at: \"2022-01-13 21:30:00 +0000\"\n      speakers:\n        - PJ Johnstone\n      description: |-\n        Metaprogramming is fun but, more importantly, makes you feel *really*\n        clever. However, it's not always the best fit for codebases with multiple\n        contributors. Let's take a few minutes to explore some neat tricks you can\n        do when you don't need to worry about other people understanding your code 😀\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/february/speaker-pj-metaprogramming-my-colleagues-wont-let-me-do-at-work-lrug-feb-2022.mp4\"\n    - id: \"hywel-carver-lrug-february-2022\"\n      title: \"How to think about Learning\"\n      event_name: \"LRUG February 2022\"\n      date: \"2022-02-21\"\n      announced_at: \"2022-01-13 21:30:00 +0000\"\n      speakers:\n        - Hywel Carver\n      description: |-\n        Why do we learn? How do we learn? How do we learn well?\n        3 mental models that will answer the first 3 of those questions and change how you think\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/february/speaker-hywel-carver-how-to-think-about-learning-lrug-feb-2022.mp4\"\n- id: \"lrug-march-2022\"\n  title: \"LRUG March 2022\"\n  event_name: \"LRUG March 2022\"\n  date: \"2022-03-14\"\n  announced_at: \"2022-03-06 21:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-march-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/march/\n  talks:\n    - id: \"christian-gregg-lrug-march-2022\"\n      title: \"Running full builds after merging? 🥱: Ship faster with git tree based caching\"\n      event_name: \"LRUG March 2022\"\n      date: \"2022-03-14\"\n      announced_at: \"2022-03-06 21:30:00 +0000\"\n      speakers:\n        - Christian Gregg\n      description: |-\n        Fast deploy pipelines are an important facet of a fast moving engineering team; allowing you\n        to ship smaller, safer units of value to production, [faster](https://xkcd.com/303/), and\n        more often.\n\n        In this talk we'll be covering how using [git tree\n        objects](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects#_tree_objects) can allow\n        you to run CI less or potentially not at all (in a not scary manner :) after merging your\n        changes into your default branch, allowing you to get straight to deploying! 🚂\n\n        In cases where your team can precompile deployment artefacts your changes could make it into\n        production in under 60s. If your team uses Heroku or Buildpacks to deploy your code, I'll\n        point you to [some](https://buildpacks.io/docs/app-developer-guide/build-an-app/)\n        [tricks](https://github.com/CGA1123/slugcmplr) to help you do just that by detaching\n        building and releasing your application to production!\n      additional_resources:\n        - name: \"Write-Up\"\n          type: \"write-up\"\n          title: \"🚢 Ship faster with git-tree based caching\"\n          url: \"https://blog.bissy.io/posts/merge_to_deploy_in_a_minute/\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/march/christian-gregg-running-full-builds-after-merging-ship-faster-with-git-tree-based-caching-lrug-mar-2022.mp4\"\n    - id: \"eleanor-mchugh-lrug-march-2022\"\n      title: \"The Browser Environment - A Systems Programmer's Perspective\"\n      event_name: \"LRUG March 2022\"\n      date: \"2022-03-14\"\n      announced_at: \"2022-03-06 21:30:00 +0000\"\n      speakers:\n        - Eleanor McHugh\n      description: |-\n        A quirky introduction to writing realtime web systems with Sinatra as\n        the backend. The highlight will be WebSockets but there'll also be\n        coverage of DOM manipulation, AJAX/fetch, and timer events.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/march/eleanor-mchugh-the-browser-environment-a-system-programmer-perspective-lrug-mar-2022.mp4\"\n- id: \"lrug-april-2022\"\n  title: \"LRUG April 2022\"\n  event_name: \"LRUG April 2022\"\n  date: \"2022-04-11\"\n  announced_at: \"2022-04-04 21:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-april-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/april/\n  talks:\n    - id: \"panos-matsinopoulos-lrug-april-2022\"\n      title: \"Using React in a Ruby Project to Dynamically Generate PDF Documents\"\n      event_name: \"LRUG April 2022\"\n      date: \"2022-04-11\"\n      announced_at: \"2022-04-04 21:30:00 +0000\"\n      speakers:\n        - Panos Matsinopoulos\n      description: |-\n        In the Ruby world, we traditionally address the PDF generation problem using gems like\n        [Prawn](https://github.com/prawnpdf/prawn) and [PDFKit](https://github.com/pdfkit/pdfkit)\n        or libraries like [whtmltopdf](https://wkhtmltopdf.org/).\n\n        Recently, in one of our Ruby on Rails projects in which we wanted to generate PDF documents\n        for invoices, we decided to use another programming language and technology: React and AWS\n        Lambda.\n\n        In this talk, we will be covering how we did it, what were\n        the challenges and what pros and cons over the incumbent tools for Ruby.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/april/panos-matsinopoulos-using-react-in-a-ruby-project-to-dynamically-generate-pdf-documents-lrug-apr-2022.mp4\"\n    - id: \"winston-ferguson-lrug-april-2022\"\n      title: \"A parse parse pitch: using JSON and custom parsers to create efficient flexible data structures.\"\n      event_name: \"LRUG April 2022\"\n      date: \"2022-04-11\"\n      announced_at: \"2022-04-04 21:30:00 +0000\"\n      speakers:\n        - Winston Ferguson\n      description: |-\n        JSON and custom parsers let you do neat things like: \\ncomplex pricing,\n        map data to 3D models, auto generate images…\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/april/winston-ferguson-a-parse-parse-pitch-using-json-and-custom-parsers-to-create-efficient-flexible-data-structures-lrug-apr-2022.mp4\"\n- id: \"lrug-may-2022\"\n  title: \"LRUG May 2022\"\n  event_name: \"LRUG May 2022\"\n  date: \"2022-05-09\"\n  announced_at: \"2022-04-22 20:10:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-may-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/may/\n  talks:\n    - id: \"duncan-brown-lrug-may-2022\"\n      title: \"Mining a gem: how to safely discover, extract and share useful code from your Rails app\"\n      event_name: \"LRUG May 2022\"\n      date: \"2022-05-09\"\n      announced_at: \"2022-04-22 20:10:00 +0000\"\n      speakers:\n        - Duncan Brown\n      description: |-\n        We recently extracted a [gem for talking to Google\n        BigQuery](https://github.com/DFE-Digital/dfe-analytics) from 5 different Rails applications\n        at the Department for Education I'll talk through the process of pulling the code out, how to\n        test gems that work with Rails, figuring out how to deal with divergence among existing\n        implementations of the same functionality, and how we're driving adoption of internal open\n        source at DfE.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/may/duncan-brown-mining-a-gem-how-to-safely-discover-extract-and-share-useful-code-from-your-rails-app-lrug-may-2022.mp4\"\n    - id: \"leena-gupte-rosa-fox-lrug-may-2022\"\n      title: \"[GOV.UK][]’s response to COVID-19\"\n      event_name: \"LRUG May 2022\"\n      date: \"2022-05-09\"\n      announced_at: \"2022-04-22 20:10:00 +0000\"\n      speakers:\n        - Leena Gupte\n        - Rosa Fox\n      description: |-\n        Leena and Rosa have been Senior Developers/Tech Leads on the [GOV.UK][]\n        Coronavirus team. The team’s work began in March 2020 when a service\n        they built over a weekend had nearly 50,000 registrations on the day it\n        launched. Two years later, after building lots more services (using\n        Ruby… of course) and serving millions of users, the [GOV.UK][]\n        Coronavirus team finally disbanded.\n\n        Rosa and Leena will take LRUG through a timeline of [GOV.UK][]’s\n        response to the pandemic. We will discuss what we delivered, our\n        successes, failures and how the team supported each other to cope. We\n        will share how Ruby/Rails and tools such as the [GOV.UK][] Design System\n        enabled us to build and deploy critical services at pace.\n      video_id: \"lrug-2022-05-09-gov-uks-response-to-covid-19\"\n      video_provider: \"not_published\"\n- id: \"lrug-june-2022\"\n  title: \"LRUG June 2022\"\n  event_name: \"LRUG June 2022\"\n  date: \"2022-06-13\"\n  announced_at: \"2022-05-15 13:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-june-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/june/\n  talks:\n    - id: \"daniel-magliola-lrug-june-2022\"\n      title: \"Get your PRs merged, rebasing like a Pro\"\n      event_name: \"LRUG June 2022\"\n      date: \"2022-06-13\"\n      announced_at: \"2022-05-15 13:00:00 +0000\"\n      speakers:\n        - Daniel Magliola\n      description: |-\n        You have a complex PR to submit. You've tried to keep it small, but sadly\n        you need to make many different changes all at once. Getting there took a\n        lot of effort and your branch has more than 30 commits with fixes and\n        reverting of dead ends.\n\n        You know reviewing this will be a nightmare for your colleagues, and more\n        importantly, it will be almost impossible for someone in the future to\n        understand what happened if they ever look at the history.\n\n        In this talk we will look at how Git branches work, and how to manicure\n        them using Rebase to build a commit history your colleagues will love you\n        for.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/june/daniel-magliola-get-your-prs-merged-rebasing-like-a-pro-lrug-jun-2022.mp4\"\n    - id: \"alfredo-motta-lrug-june-2022\"\n      title: \"The messy middle – 5 Software Engineering lessons from a 5 years startup journey\"\n      event_name: \"LRUG June 2022\"\n      date: \"2022-06-13\"\n      announced_at: \"2022-05-15 13:00:00 +0000\"\n      speakers:\n        - Alfredo Motta\n      description: |-\n        These are some of the lessons that I have learned over my 5 years at a\n        Fintech startup that went from 0 to 100k customers and grew the team from 4\n        to 50 people. I will present some of the software architecture tradeoffs I\n        have been presented with and I am still puzzled about today.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/june/alfredo-motta-the-messy-middle-5-software-engineering-lessons-from-a-5-years-startup-journey-lrug-jun-2022.mp4\"\n- id: \"lrug-july-2022\"\n  title: \"LRUG July 2022\"\n  event_name: \"LRUG July 2022\"\n  date: \"2022-07-11\"\n  announced_at: \"2022-07-04 13:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-july-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/july/\n  talks:\n    - id: \"andre-barbosa-lrug-july-2022\"\n      title: \"Building a Mortgage Lender at Generation Home\"\n      event_name: \"LRUG July 2022\"\n      date: \"2022-07-11\"\n      announced_at: \"2022-07-04 13:00:00 +0000\"\n      speakers:\n        - André Barbosa\n      description: |-\n        It’s not often that you hear about a startup doings things differently in the mortgages\n        world. And there’s some good reasons for it, the cost of entry is super high!\n\n        It’s not just funding and regulations either. You also need to back it up with the right\n        technology and tools to manage a highly complex business where mistakes can be very costly.\n        On top of that, startups need to move fast to out-innovate the incumbents with only a\n        fraction of the resources.\n\n        At Generation Home Ruby has been a catalyst to help us deliver a product we’re proud of in\n        a short time-scale. We’ll talk about some of the challenges we faced early on, how Ruby,\n        Rails and the whole ecosystem helped us deliver and what still lays ahead of us.\n      video_id: \"lrug-2022-07-11-building-a-mortgage-lender-at-generation-home\"\n      video_provider: \"not_published\"\n- id: \"lrug-august-2022\"\n  title: \"LRUG August 2022\"\n  event_name: \"LRUG August 2022\"\n  date: \"2022-08-08\"\n  announced_at: \"2022-08-02 13:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-august-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/august/\n  talks:\n    - id: \"javier-honduvilla-coto-lrug-august-2022\"\n      title: \"Low overhead Ruby profiling and tracing with rbperf\"\n      event_name: \"LRUG August 2022\"\n      date: \"2022-08-08\"\n      announced_at: \"2022-08-02 13:00:00 +0000\"\n      speakers:\n        - Javier Honduvilla Coto\n      description: |-\n        Understanding our applications' performance can be tricky. Some of the readily available\n        performance tools introduce a big overhead which makes them not suitable for use in\n        production environments, where in many cases, it's the best place to troubleshoot performance\n        issues.\n\n        [rbperf](https://github.com/javierhonduco/rbperf/) is a low-overhead on-CPU profiler and\n        tracer that is suitable for usage in production environments. It doesn't require the\n        application under investigation to be restarted or disturbed in any way.\n\n        We will discuss some of the tradeoffs in its design, its architecture, the features that make\n        it unique, as well as its limitations compared to other tools. We will also take a look at\n        how the Ruby stack is laid out in memory and the role BPF plays in rbperf.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/august/javier-honduvilla-coto-low-overhead-ruby-profiling-and-tracing-with-rbperf-lrug-aug-2022.mp4\"\n- id: \"lrug-september-2022\"\n  title: \"LRUG September 2022\"\n  event_name: \"LRUG September 2022\"\n  date: \"2022-09-12\"\n  announced_at: \"2022-08-18 20:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-september-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/september/\n  talks:\n    - id: \"thijs-cadier-lrug-september-2022\"\n      title: \"How music works, using Ruby\"\n      event_name: \"LRUG September 2022\"\n      date: \"2022-09-12\"\n      announced_at: \"2022-08-18 20:30:00 +0000\"\n      speakers:\n        - Thijs Cadier\n      description: |-\n        That strange phenomenon where air molecules bounce against each other in a way that somehow\n        comforts you, makes you cry, or makes you dance all night: music. Since the advent of\n        recorded audio, a musician doesn't even need to be present anymore for this to happen (which\n        makes putting \"I will always love you\" on repeat a little less awkward).\n\n        Musicians and sound engineers have found many ways of creating music, and making music sound\n        good when played from a record. Some of their methods have become industry staples used on\n        every recording released today.\n\n        Let's look at what they do and reproduce some of their methods in Ruby!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/september/thijs-cadier-how-music-works-using-ruby-lrug-sep-2022.mp4\"\n    - id: \"andre-barbosa-lrug-september-2022\"\n      title: \"Building a Mortgage Lender at Generation Home\"\n      event_name: \"LRUG September 2022\"\n      date: \"2022-09-12\"\n      announced_at: \"2022-08-18 20:30:00 +0000\"\n      speakers:\n        - André Barbosa\n      description: |-\n        It’s not often that you hear about a startup doings things differently in the mortgages\n        world. And there’s some good reasons for it, the cost of entry is super high!\n\n        It’s not just funding and regulations either. You also need to back it up with the right\n        technology and tools to manage a highly complex business where mistakes can be very costly.\n        On top of that, startups need to move fast to out-innovate the incumbents with only a\n        fraction of the resources.\n\n        At Generation Home Ruby has been a catalyst to help us deliver a product we’re proud of in\n        a short time-scale. We’ll talk about some of the challenges we faced early on, how Ruby,\n        Rails and the whole ecosystem helped us deliver and what still lays ahead of us.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/september/andre-barbosa-buildin-a-mortgage-lender-at-generation-home-lrug-sep-2022.mp4\"\n    - id: \"shen-sat-lrug-september-2022\"\n      title: \"Fixing flaky tests, using RSpec's `--seed` option\"\n      event_name: \"LRUG September 2022\"\n      date: \"2022-09-12\"\n      announced_at: \"2022-08-18 20:30:00 +0000\"\n      speakers:\n        - Shen Sat\n      description: |-\n        Fixing a flaky test in the build pipeline of your application often\n        requires first replicating the failing test locally. I'm going to show you\n        how I used RSpec's `--seed` to help me do this for a flaky test I was\n        recently grappling with, and how it led led me to a fix ✨\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/september/shen-sat-fixing-flaky-tests-using-rspecs-seed-option-lrug-sep-2022.mp4\"\n- id: \"lrug-october-2022\"\n  title: \"LRUG October 2022\"\n  event_name: \"LRUG October 2022\"\n  date: \"2022-10-10\"\n  announced_at: \"2022-09-18 08:25:00 +0100\"\n  video_provider: \"children\"\n  video_id: \"lrug-october-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/october/\n  talks:\n    - id: \"paul-battley-lrug-october-2022\"\n      title: \"How to be completely ignorant\"\n      event_name: \"LRUG October 2022\"\n      date: \"2022-10-10\"\n      announced_at: \"2022-09-18 08:25:00 +0100\"\n      speakers:\n        - Paul Battley\n      description: |-\n        How much does a bit of code need to know to do its job? I'll show how I\n        transformed a bit of complicated, untested, flaky, and poorly understood code\n        into something pleasant to deal with and easy to test by applying the\n        principle of making it know as little as possible.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/october/paul-battley-how-to-be-completely-ignorant-lrug-oct-2022.mp4\"\n    - id: \"murray-steele-lrug-october-2022\"\n      title: \"The long road to ruby 3 vs. the short road to ruby 3.1\"\n      event_name: \"LRUG October 2022\"\n      date: \"2022-10-10\"\n      announced_at: \"2022-09-18 08:25:00 +0100\"\n      speakers:\n        - Murray Steele\n      description: |-\n        I'll share how the team at [Cleo](https://www.meetcleo.com/)\n        meticulously planned and delivered the upgrade to ruby 3.0 on our rails\n        app so smoothly that we became drunk on our own competence and totally\n        messed up our upgrade to ruby 3.1 the following week.  A rare talk\n        where you will learn some best _and_ worst practices.\n      additional_resources:\n        - name: \"Transcript\"\n          type: \"transcript\"\n          title: \"Talks ∋ The long road to ruby 3.0 vs. the short road to ruby 3.1\"\n          url: \"http://h-lame.com/talks/the-long-road-to-ruby-3-0-vs-the-short-road-to-ruby-3-1/\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/october/murray-steele-the-long-road-to-ruby-3-0-vs-the-short-road-to-ruby-3-1-lrug-oct-2022.mp4\"\n- id: \"lrug-november-2022\"\n  title: \"LRUG November 2022\"\n  event_name: \"LRUG November 2022\"\n  date: \"2022-11-14\"\n  announced_at: \"2022-10-20 18:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-november-2022\"\n  description: |-\n    https://lrug.org/meetings/2022/november/\n  talks:\n    - id: \"benji-lewis-lrug-november-2022\"\n      title: \"Data Indexing with RGB (Ruby, Graphs and Bitmaps)\"\n      event_name: \"LRUG November 2022\"\n      date: \"2022-11-14\"\n      announced_at: \"2022-10-20 18:00:00 +0000\"\n      speakers:\n        - Benji Lewis\n      description: |-\n        In this talk, we will go on a journey through Zappi’s data history and how\n        we are using Ruby, a graph database, and a bitmap store to build a unique\n        data engine. A journey that starts with the problem of a disconnected data\n        set and serialised data frames, and ends with the solution of an in-memory\n        index.\n\n        We will explore how we used RedisGraph to model the relationships in our\n        data, connecting semantically equal nodes. Then delve into how a query\n        layer was used to index a bitmap store and, in turn, led to us being able\n        to interrogate our entire dataset orders of magnitude faster than before.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/november/benji-lewis-data-indexing-with-rgb-ruby-graphs-and-bitmaps-lrug-nov-2022.mp4\"\n    - id: \"stan-lo-lrug-november-2022\"\n      title: \"`ruby/debug` - The best investment for your productivity\"\n      event_name: \"LRUG November 2022\"\n      date: \"2022-11-14\"\n      announced_at: \"2022-10-20 18:00:00 +0000\"\n      speakers:\n        - Stan Lo\n      description: |-\n        In this talk, I will demonstrate 3 powerful debugging techniques using Ruby's new debugger\n        [`ruby/debug`](https://github.com/ruby/debug):\n\n        * Step-debugging\n        * Frame navigation\n        * Breakpoint commands\n\n        By using them together, we can reduce unnecessary context switching and make our debugging\n        sessions more efficient. You will also learn more about `ruby/debug` while we walk through\n        these techniques with its commands and console.\n\n        And finally, I will show you how to level up our productivity even further by automating\n        debugging steps using `ruby/debug`'s scriptable breakpoints.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/november/stan-lo-ruby-debug-the-best-investment-for-your-productivity-lrug-nov-2022.mp4\"\n      slides_url: \"https://github.com/st0012/slides/blob/main/2022-11-14-lrug/Ruby%20debugger%20-%20The%20best%20investment%20for%20your%20productivity%20-%20LRUG.pdf\"\n    - id: \"christian-bruckmayer-lrug-november-2022\"\n      title: \"Keeping developers happy with a fast CI\"\n      event_name: \"LRUG November 2022\"\n      date: \"2022-11-14\"\n      announced_at: \"2022-10-20 18:00:00 +0000\"\n      speakers:\n        - Christian Bruckmayer\n      description: |-\n        When talking about performance, most developers think application speed,\n        faster algorithms or better data structures. But what about your test\n        suite? CI time is developer waiting time!\n\n        At Shopify we have more than 170,000 Ruby tests and we add 30,000 more\n        annually. The sheer amount of tests and their growth requires some\n        aggressive methods. We will illustrate some of our techniques including\n        monitoring, test selection, timeouts and the 80/20 rule. If you have\n        experience in writing tests and want to learn tricks on how to speed up\n        your test suite, this talk is for you!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2022/november/christian-bruckmayer-keeping-developers-happy-with-a-fast-ci-lrug-nov-2022.mp4\"\n      slides_url: \"https://bruckmayer.net/ruby-conf-2021\"\n- id: \"lrug-january-2023\"\n  title: \"LRUG January 2023\"\n  event_name: \"LRUG January 2023\"\n  date: \"2023-01-09\"\n  announced_at: \"2022-12-13 21:26:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-january-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/january/\n  talks:\n    - id: \"matt-valentine-house-lrug-january-2023\"\n      title: \"Heaping on the Complexity\"\n      event_name: \"LRUG January 2023\"\n      date: \"2023-01-09\"\n      announced_at: \"2022-12-13 21:26:00 +0000\"\n      speakers:\n        - Matt Valentine-House\n      description: |-\n        Join me on a journey through Ruby's Garbage Collector!\n\n        In this talk I'll teach you some of the details about how the Ruby\n        interpreter manages memory. I'll introduce a project my team and I are\n        working on that aims to make Ruby faster by improving its memory\n        efficiency, and then we'll talk about how our implementation broke\n        Garbage Collection.\n\n        After that we'll go on a journey together, through some weeds, and\n        taking a few bad turns until we finally emerge with a few PR's that\n        not only Fix GC, but make our project better too.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/january/matt-valentine-house-heaping-on-the-complexity-lrug-jan-2023.mp4\"\n    - id: \"daniel-magliola-lrug-january-2023\"\n      title: 'What does \"high priority\" mean? The secret to happy queues'\n      event_name: \"LRUG January 2023\"\n      date: \"2023-01-09\"\n      announced_at: \"2022-12-13 21:26:00 +0000\"\n      speakers:\n        - Daniel Magliola\n      description: |-\n        Like most web applications, you run important jobs in the background. And\n        today, some of your urgent jobs are running late. Again. No matter how many\n        changes you make to how you enqueue and run your jobs, the problem keeps\n        happening. The good news is you're not alone. Most teams struggle with this\n        problem, try more or less the same solutions, and have roughly the same\n        result. In the end, it all boils down to one thing: keeping latency low. In\n        this talk I will present a latency-focused approach to managing your queues\n        reliably, keeping your jobs flowing and your users happy.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/january/daniel-magliola-what-does-high-priority-mean-the-secret-to-happy-queues-lrug-jan-2023.mp4\"\n    - id: \"fritz-meissner-lrug-january-2023\"\n      title: \"Solargraph-rails in 2022\"\n      event_name: \"LRUG January 2023\"\n      date: \"2023-01-09\"\n      announced_at: \"2022-12-13 21:26:00 +0000\"\n      speakers:\n        - Fritz Meissner\n      description: |-\n        From chewing-gum-and-regex to 35,000 lines of code and YAML! Come hear\n        about the past year of work on the solargraph-rails gem. You'll see new\n        features, mostly from merging with the solargraph-ARC gem, and hear about\n        the lessons learned along the way: more code means more to maintain and\n        understand, but there's a surprising amount that can be done just by\n        putting one foot in front of the other.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/january/fritz-meissner-solargraph-rails-in-2022-lrug-jan-2023.mp4\"\n- id: \"lrug-february-2023\"\n  title: \"LRUG February 2023\"\n  event_name: \"LRUG February 2023\"\n  date: \"2023-02-13\"\n  announced_at: \"2023-01-18 10:13:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-february-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/february/\n  talks:\n    - id: \"tom-stuart-lrug-february-2023\"\n      title: \"A Supposedly Fun Thing I’ll Never Stream Again: live coding a Ruby project\"\n      event_name: \"LRUG February 2023\"\n      date: \"2023-02-13\"\n      announced_at: \"2023-01-18 10:13:00 +0000\"\n      speakers:\n        - Tom Stuart\n      description: |-\n        Last September I began regularly livestreaming my work on a side project to\n        build a WebAssembly interpreter in Ruby. In this talk I’ll tell you how it’s\n        going and what I’ve learned so far.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/february/tom-stuart-a-supposedly-fun-thing-ill-never-stream-again-live-coding-a-ruby-project-lrug-feb-2023.mp4\"\n    - id: \"matt-bee-lrug-february-2023\"\n      title: \"To mentor or to mentee - that is the question\"\n      event_name: \"LRUG February 2023\"\n      date: \"2023-02-13\"\n      announced_at: \"2023-01-18 10:13:00 +0000\"\n      speakers:\n        - Matt Bee\n      description: |-\n        I started out 2022 looking for a mentor to help me on my ruby career\n        adventure. After reflection (and some interesting insights) I realised that\n        perhaps that was the wrong way round, and I would get more from being the\n        mentor - here I'll share a journey, lessons learned and why maybe you\n        should mentor someone too.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/february/matt-bee-to-mentor-or-to-mentee-that-is-the-question-lrug-feb-2023.mp4\"\n    - id: \"frank-kair-lrug-february-2023\"\n      title: \"Data Structures in 3 Paradigms: Ruby Spotlight\"\n      event_name: \"LRUG February 2023\"\n      date: \"2023-02-13\"\n      announced_at: \"2023-01-18 10:13:00 +0000\"\n      speakers:\n        - Frank Kair\n      description: |-\n        Using a simple data structure as a starting point, we discuss three\n        different programming paradigms (imperative, object oriented and\n        functional), not only in terms of implementation, but also as a broader\n        framework for learning and having a richer mental model for problem solving.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/february/frank-kair-data-structures-in-3-paradigms-ruby-spotlight-lrug-feb-2023.mp4\"\n    - id: \"chris-zetter-lrug-february-2023\"\n      title: \"Using the 'mob' tool for productive pairing\"\n      event_name: \"LRUG February 2023\"\n      date: \"2023-02-13\"\n      announced_at: \"2023-01-18 10:13:00 +0000\"\n      speakers:\n        - Chris Zetter\n      description: |-\n        My team started using the opinionated 'mob' tool for our\n        remote mob and pair programming sessions. I'll explain what the tool does\n        and how I've found it helps us to maintain momentum while pairing.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/february/chris-zetter-using-the-mob-tool-for-productive-pairing-lrug-feb-2023.mp4\"\n    - id: \"matt-valentine-house-lrug-february-2023\"\n      title: \"Strings: Interpolation, Optimisations and bugs\"\n      event_name: \"LRUG February 2023\"\n      date: \"2023-02-13\"\n      announced_at: \"2023-01-18 10:13:00 +0000\"\n      speakers:\n        - Matt Valentine-House\n      description: |-\n        In this talk we'll explore a bit about how string interpolation works in\n        Ruby. We'll do this while investigating and fixing a bug arising from an\n        assumption made as part of an optimisation many years\n        ago that is no longer true.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/february/matt-valentine-house-strings-interpolation-optimisation-and-bugs-lrug-feb-2023.mp4\"\n    - id: \"fell-sunderland-lrug-february-2023\"\n      title: \"WET: Why DRY isn't always best\"\n      event_name: \"LRUG February 2023\"\n      date: \"2023-02-13\"\n      announced_at: \"2023-01-18 10:13:00 +0000\"\n      speakers:\n        - fell sunderland\n      description: |-\n        An opinionated look at the pros and cons of\n        choosing abstractions early vs. waiting and duplicating effort\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/february/fell-sunderland-wet-why-dry-isnt-always-best-lrug-feb-2023.mp4\"\n    - id: \"jairo-diaz-lrug-february-2023\"\n      title: \"Using ChatGPT to Program in Ruby\"\n      event_name: \"LRUG February 2023\"\n      date: \"2023-02-13\"\n      announced_at: \"2023-01-18 10:13:00 +0000\"\n      speakers:\n        - Jairo Diaz\n      description: |-\n        The talk will be about using ChatGPT, an advanced language model developed\n        by OpenAI, to explore programming with a bot. The aim is to show how\n        developers can use ChatGPT to learn, write, and debug code in the Ruby\n        programming language.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/february/jairo-diaz-using-chatgpt-to-program-in-ruby-lrug-feb-2023.mp4\"\n    - id: \"dmitry-non-lrug-february-2023\"\n      title: \"“Pure” OOP in Ruby\"\n      event_name: \"LRUG February 2023\"\n      date: \"2023-02-13\"\n      announced_at: \"2023-01-18 10:13:00 +0000\"\n      speakers:\n        - Dmitry Non\n      description: |-\n        What if Ruby had NOTHING except classes and objects?\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/february/dmitry-non-pure-oop-in-ruby-lrug-feb-2023.mp4\"\n- id: \"lrug-march-2023\"\n  title: \"LRUG March 2023\"\n  event_name: \"LRUG March 2023\"\n  date: \"2023-03-13\"\n  announced_at: \"2023-02-18 10:13:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-march-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/march/\n  talks:\n    - id: \"ayush-newatia-lrug-march-2023\"\n      title: \"Native apps are dead, long live native apps: Using Turbo Native to make hybrid apps that don’t suck.\"\n      event_name: \"LRUG March 2023\"\n      date: \"2023-03-13\"\n      announced_at: \"2023-02-18 10:13:00 +0000\"\n      speakers:\n        - Ayush Newatia\n      description: |-\n        You’ve heard it hundreds of times: Hybrid apps suck. That may have\n        been true in the past, but things have changed significantly in the last decade.\n        With tools like Turbo Native working in conjunction with Ruby on Rails, it’s\n        possible to mix web technologies with native APIs to build slick hybrid mobile\n        apps. We’ll take a look at why the hybrid approach gets such a bad rap, why\n        that reputation is undeserved, and how we can build hybrid apps that don’t\n        suck.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/march/ayush-newatia-native-apps-are-dead-long-live-native-apps-lrug-mar-2023.mp4\"\n    - id: \"frederick-cheung-lrug-march-2023\"\n      title: \"End to End typing for web applications\"\n      event_name: \"LRUG March 2023\"\n      date: \"2023-03-13\"\n      announced_at: \"2023-02-18 10:13:00 +0000\"\n      speakers:\n        - Frederick Cheung\n      description: |-\n        Ever had a bug because the frontend made incorrect assumptions about the shape\n        of response data from the backend? Or maybe you trod nervously during a refactor?\n        Or perhaps you broke an app by changing the backend data in a way you didn’t\n        think would matter?\n\n        Learn how avoid this type of mistake, enabling you to keep moving fast, by\n        having a single source of truth for your data types, checked both on the frontend\n        and the backend.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/march/frederick-cheung-end-to-end-typing-for-web-applications-lrug-mar-2023.mp4\"\n- id: \"lrug-april-2023\"\n  title: \"LRUG April 2023\"\n  event_name: \"LRUG April 2023\"\n  date: \"2023-04-17\"\n  announced_at: \"2023-03-23 00:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-april-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/april/\n  talks:\n    - id: \"alex-chan-lrug-april-2023\"\n      title: \"Making a working upwards assignment operator\"\n      event_name: \"LRUG April 2023\"\n      date: \"2023-04-17\"\n      announced_at: \"2023-03-23 00:00:00 +0000\"\n      speakers:\n        - Alex Chan\n      description: |-\n        Ruby has leftward assignment. It has rightward assignment. But what about upward assignment?\n\n        In this talk, we’ll misuse Ruby’s internals to build an arrow operator that lets us assign\n        upwards. We’ll see some powerful Ruby metaprogramming features that allow us to bend Ruby\n        to our will – and we’ll talk about why it’s good to write code that’s just plain daft.\n      additional_resources:\n        - name: \"Write-Up\"\n          type: \"write-up\"\n          title: \"Upward assignment in Ruby\"\n          url: \"https://alexwlchan.net/2023/upward-assignment/\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/april/alex-making-a-working-upwards-assignment-operator-lrug-apr-2023.mp4\"\n    - id: \"stan-lo-lrug-april-2023\"\n      title: \"Build a mini Ruby debugger in under 300 lines\"\n      event_name: \"LRUG April 2023\"\n      date: \"2023-04-17\"\n      announced_at: \"2023-03-23 00:00:00 +0000\"\n      speakers:\n        - Stan Lo\n      description: |-\n        As developers, we know that the best way to learn is by doing. Many of us have\n        built mini-rails, mini-sinatra, and even mini-rubies. But have you ever built\n        your own debugger?\n\n        In this talk, I'll show you how to create a mini Ruby debugger that's both\n        powerful and fun to use. You'll learn how to:\n        - Run your program with debugger with a simple command\n        - Set breakpoints and through debugger commands\n        - Step through your code to find bugs\n\n        And best of all, you'll do it all in under 300 lines of code!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/april/stan-lo-build-a-mini-ruby-debugger-in-under-300-lines-lrug-apr-2023.mp4\"\n- id: \"lrug-may-2023\"\n  title: \"LRUG May 2023\"\n  event_name: \"LRUG May 2023\"\n  date: \"2023-05-15\"\n  announced_at: \"2023-04-25 10:13:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-may-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/may/\n  talks:\n    - id: \"gus-shaw-stewart-lrug-may-2023\"\n      title: \"GitHub Actions: an introduction\"\n      event_name: \"LRUG May 2023\"\n      date: \"2023-05-15\"\n      announced_at: \"2023-04-25 10:13:00 +0000\"\n      speakers:\n        - Gus Shaw Stewart\n      description: |-\n        An introductory talk about GitHub Actions - what they are, why they are\n        important, and how you can get started with them.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/may/gus-shaw-stewart-github-actions-an-introduction-lrug-may-2023.mp4\"\n- id: \"lrug-june-2023\"\n  title: \"LRUG June 2023\"\n  event_name: \"LRUG June 2023\"\n  date: \"2023-06-12\"\n  announced_at: \"2023-05-16 20:10:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-june-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/june/\n  talks:\n    - id: \"alfredo-motta-lrug-june-2023\"\n      title: \"Tech debt for the rest of us\"\n      event_name: \"LRUG June 2023\"\n      date: \"2023-06-12\"\n      announced_at: \"2023-05-16 20:10:00 +0000\"\n      speakers:\n        - Alfredo Motta\n      description: |-\n        Tech Debt can be messy, but it doesn't have to be. In this short talk\n        I'll present a simple approach to identify your Tech Debt, monitor it\n        over time and make it actionable.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/june/alfredo-motta-tech-debt-for-the-rest-of-us-lrug-jun-2023.mp4\"\n    - id: \"adam-piotrowski-lrug-june-2023\"\n      title: \"Mutation testing - study case\"\n      event_name: \"LRUG June 2023\"\n      date: \"2023-06-12\"\n      announced_at: \"2023-05-16 20:10:00 +0000\"\n      speakers:\n        - Adam Piotrowski\n      description: |-\n        Let's talk about why and how we measure our test coverage. If you are\n        using line test coverage measurement and you are happy with it, please let\n        me show you some differences and examples of line TC vs mutation TC.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/june/adam-piotrowski-mutation-testing-study-case-lrug-jun-2023.mp4\"\n    - id: \"shenthuran-satkunarasa-lrug-june-2023\"\n      title: \"How we used CQRS to structure our new Borrower Portal\"\n      event_name: \"LRUG June 2023\"\n      date: \"2023-06-12\"\n      announced_at: \"2023-05-16 20:10:00 +0000\"\n      speakers:\n        - Shenthuran Satkunarasa\n      description: |-\n        Funding Circle recently built a new application that allows borrowers to\n        manage their loans themselves. We structured the application using a\n        (new-to-me!) design principle called Command Query Responsibility Segregation.\n        Join me as I give a brief definition of what CQRS is before showing you the\n        practical application of it via our new borrower portal 💻\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/june/shenthuran-satkunarasa-how-we-used-cqrs-to-structure-our-new-borrower-portal-lrug-jun-2023.mp4\"\n- id: \"lrug-july-2023\"\n  title: \"LRUG July 2023\"\n  event_name: \"LRUG July 2023\"\n  date: \"2023-07-10\"\n  announced_at: \"2023-06-28 20:10:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-july-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/july/\n  talks:\n    - id: \"dan-hough-lrug-july-2023\"\n      title: \"Ruby to solve homelessness and the refugee crises\"\n      event_name: \"LRUG July 2023\"\n      date: \"2023-07-10\"\n      announced_at: \"2023-06-28 20:10:00 +0000\"\n      speakers:\n        - Dan Hough\n      description: |-\n        Social impact startup Beam (named by LinkedIn as one of the UK’s Top 15\n        Startups) has built pioneering products for government, social care workers -\n        and homeless people and refugees themselves. Together, Beam is proving that\n        tech can solve these problems for good. Hear about how a small Engineering\n        team has built software that has transformed the lives of thousands of\n        homeless people and refugees. And hear about the fun, meaning and challenge in\n        Tech for Good.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/july/dan-hough-ruby-to-solve-homelessness-and-the-refugee-crises.mp4\"\n- id: \"lrug-august-2023\"\n  title: \"LRUG August 2023\"\n  event_name: \"LRUG August 2023\"\n  date: \"2023-08-14\"\n  announced_at: \"2023-07-12 20:10:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-august-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/august/\n  talks:\n    - id: \"lorin-thwaits-lrug-august-2023\"\n      title: \"Gain insight and better accessibility into your application's data by using The Brick\"\n      event_name: \"LRUG August 2023\"\n      date: \"2023-08-14\"\n      announced_at: \"2023-07-12 20:10:00 +0000\"\n      speakers:\n        - Lorin Thwaits\n      description: |-\n        Remarkable visibility into the structure of your application and its data\n        is available by using the open-source Rails gem \"[The Brick](\n        https://github.com/lorint/brick)\". Come meet the author of this gem, and\n        experience the cornucopia of usefulness it can provide to teams who\n        architect, elaborate upon, and then support Rails applications.\n      video_id: \"lrug-2023-08-14-the-brick\"\n      video_provider: \"not_published\"\n- id: \"lrug-september-2023\"\n  title: \"LRUG September 2023\"\n  event_name: \"LRUG September 2023\"\n  date: \"2023-09-11\"\n  announced_at: \"2023-08-17 09:10:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-september-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/september/\n  talks:\n    - id: \"ju-liu-lrug-september-2023\"\n      title: \"The Functional Alternative\"\n      event_name: \"LRUG September 2023\"\n      date: \"2023-09-11\"\n      announced_at: \"2023-08-17 09:10:00 +0000\"\n      speakers:\n        - Ju Liu\n      description: |-\n        We'll start with a simple Ruby Kata and solve it together, live, with\n        imperative programming.\n\n        We'll then fix the many, many, many things we got wrong. Then we'll solve\n        the problem again using patterns from functional programming. You'll leave\n        this talk with a clear and concrete example of why functional programming\n        matters, why immutable code matters, and why it can help you writing\n        bug-free code.\n\n        The next time you find yourself writing imperative code, you might\n        consider... the functional alternative.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/september/ju-liu-the-functional-alternative-lrug-sep-2023.mp4\"\n    - id: \"paul-battley-lrug-september-2023\"\n      title: \"Back in my day...\"\n      event_name: \"LRUG September 2023\"\n      date: \"2023-09-11\"\n      announced_at: \"2023-08-17 09:10:00 +0000\"\n      speakers:\n        - Paul Battley\n      description: |-\n        I've been working with Ruby since the early 2000s. Ruby has changed a lot in that time,\n        but we don't always remember how much. Let's rewrite a short program so that it runs in\n        a twenty-year-old version of Ruby and see how much syntax and performance has changed for\n        the better in twenty years\n      additional_resources:\n        - name: \"Transcript\"\n          type: \"transcript\"\n          title: \"Back in my day... - transcript from the Brighton Ruby 2023 version of this talk\"\n          url: \"https://po-ru.com/2023/07/05/back-in-my-day\"\n        - name: \"Source Code\"\n          type: \"code\"\n          title: \"Supporting git repo for the code used in Back in my day...\"\n          url: \"https://github.com/threedaymonk/back-in-my-day\"\n      video_id: \"lrug-2023-09-11-back-in-my-day\"\n      video_provider: \"not_published\"\n- id: \"lrug-october-2023\"\n  title: \"LRUG October 2023\"\n  event_name: \"LRUG October 2023\"\n  date: \"2023-10-09\"\n  announced_at: \"2023-09-25 21:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-october-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/october/\n  talks:\n    - id: \"rikke-rosenlund-lrug-october-2023\"\n      title: \"BorrowMyDoggy - Connecting dogs and people via Ruby\"\n      event_name: \"LRUG October 2023\"\n      date: \"2023-10-09\"\n      announced_at: \"2023-09-25 21:00:00 +0000\"\n      speakers:\n        - Rikke Rosenlund\n      description: |-\n        BorrowMyDoggy connects dog owners with local borrowers for walks,\n        weekends and holidays. Via BorrowMyDoggy, borrowers get happy dog time,\n        owners get help with taking care of their dogs, and dogs get more love\n        and attention (it's a win-win scenario). We started by winning the Lean\n        Startup Machine, then received a crazy amount of media attention and by\n        now have built a community of +1 million members in the UK and Ireland,\n        and are working with some of the biggest players in the pet space. Come\n        and listen to how a simple idea has now turned into a well known brand.\n      video_id: \"lrug-2023-10-09-borrow-my-doggy-connecting-dogs-and-people-via-ruby\"\n      video_provider: \"not_published\"\n- id: \"lrug-november-2023\"\n  title: \"LRUG November 2023\"\n  event_name: \"LRUG November 2023\"\n  date: \"2023-11-13\"\n  announced_at: \"2023-10-18 23:33:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-november-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/november/\n  talks:\n    - id: \"naomi-christie-lrug-november-2023\"\n      title: \"Outside Technology: Building bridges between engineers and everyone else\"\n      event_name: \"LRUG November 2023\"\n      date: \"2023-11-13\"\n      announced_at: \"2023-10-18 23:33:00 +0000\"\n      speakers:\n        - Naomi Christie\n      description: |-\n        Naomi will take you on a journey from her previous career outside\n        technology to her current career as a software engineer highlighting some\n        of the (many) things she had to learn along the way, providing insight into\n        why misunderstandings are common between engineers and their stakeholders\n        and offering some ideas on how we can bridge that gap.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/november/naomi-christie-outside-technology-building-bridges-between-engineers-and-everyone-else.mp4\"\n    - id: \"melinda-seckington-lrug-november-2023\"\n      title: \"The Art of Talk Design\"\n      event_name: \"LRUG November 2023\"\n      date: \"2023-11-13\"\n      announced_at: \"2023-10-18 23:33:00 +0000\"\n      speakers:\n        - Melinda Seckington\n      description: |-\n        Everywhere you look, stories surround us, and everyone has something that’s worth sharing\n        with others. As speakers, we need to understand how to structure our talks so they can have\n        the best effect on the audiences we are trying to reach. How do you discover the right angle\n        and the right story for a talk? How do you frame your story?\n\n        Within tech we know how to approach building a new product: we research our user base, we\n        figure out what and for who we’re trying to create something for and we make sure we\n        constantly iterate on what we’ve come up with. So why aren’t we taking the same approach\n        for our talks?\n\n        This talk will examine how to get in the right mindset of examining your talk ideas, and will\n        introduce a framework of how to design and iterate on your talk. It will focus on several\n        exercises and questions to help you create the best talk for the story you’re trying to tell.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2023/november/melinda-seckington-the-art-of-talk-design.mp4\"\n- id: \"lrug-december-2023\"\n  title: \"LRUG December 2023\"\n  event_name: \"LRUG December 2023\"\n  date: \"2023-12-11\"\n  announced_at: \"2023-11-09 12:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-december-2023\"\n  description: |-\n    https://lrug.org/meetings/2023/december/\n  talks:\n    - id: \"christian-bruckmayer-lrug-december-2023\"\n      title: \"Test Smarter, Not Harder - Crafting a Test Selection Framework from Scratch\"\n      event_name: \"LRUG December 2023\"\n      date: \"2023-12-11\"\n      announced_at: \"2023-11-09 12:00:00 +0000\"\n      speakers:\n        - Christian Bruckmayer\n      description: |-\n        [Christian Bruckmayer](https://twitter.com/bruckmayer) says:\n\n        > The simplest way of running tests is to run all of them, regardless of what changes you\n        > are testing. However, depending on the size of your test suite, this will either get slow\n        > or expensive. At Shopify we have almost 300,000 Rails tests and we add 50,000 more\n        > annually. The sheer amount of tests and their growth makes it impossible to run all tests,\n        > all the time! Hence we implemented a framework to only run tests relevant to your code\n        > changes.\n        >\n        > We will build a test selection framework from scratch in this workshop. We will begin by\n        > exploring the fundamentals of such a framework: code analysis. After that we will dive into\n        > minitest reporters, how they work and how we can use them to generate a test map. Finally\n        > we will use the generated test map to only run tests relevant to your code changes.\n        > Attendees will walk away with a solid understanding of what test selection is, how it works\n        > and how to implement it.\n\n        This is a workshop, so bring your laptop!\n      video_id: \"lrug-2023-12-11-test-smarter-not-harder-crafting-a-test-selection-framework-from-scratch\"\n      video_provider: \"not_published\"\n- id: \"lrug-january-2024\"\n  title: \"LRUG January 2024\"\n  event_name: \"LRUG January 2024\"\n  date: \"2024-01-08\"\n  announced_at: \"2023-12-18 12:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-january-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/january/\n  talks:\n    - id: \"kevin-sedgley-lrug-january-2024\"\n      title: \"Sky Computing\"\n      event_name: \"LRUG January 2024\"\n      date: \"2024-01-08\"\n      announced_at: \"2023-12-18 12:00:00 +0000\"\n      speakers:\n        - Kevin Sedgley\n      description: |-\n        What comes after cloud computing? Cloud computing is convenient,\n        ubiquitous and relatively cheap. But it also locks developers into proprietary\n        solutions that make migrating to another provider or bringing your solutions\n        back in-house difficult and expensive. If AWS, Google Cloud Computing, Azure\n        and all the others are clouds, then we also need a sky. Researchers at Berkeley\n        and other institutions have proposed sky computing: an interoperability layer\n        that removes technological lock-in and enables multi cloud application development.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/january/kevin-sedgley-sky-computing-lrug-jan-2024.mp4\"\n    - id: \"joel-biffin-lrug-january-2024\"\n      title: \"Leveraging Localised Gems (LLGems): Re-using Code the Ruby Way, Safely\"\n      event_name: \"LRUG January 2024\"\n      date: \"2024-01-08\"\n      announced_at: \"2023-12-18 12:00:00 +0000\"\n      speakers:\n        - Joel Biffin\n      description: |-\n        The talk takes a look under the hood of our Rails monolith, our Rails\n        Engines, and how we share code between them. It's a bit like a kitchen\n        experiment – blending the best of both worlds to enhance the Separation of\n        Concerns, while still keeping our favorite code recipes within reach. I'll\n        share our adventure of moving some Kafka infrastructure code from the main\n        Rails app into a local gem (with zero downtime!). Think of it as giving the\n        code a new home where it can be shared across our Rails Engines. We've also\n        managed to preserve our unique, in-house testing infrastructure in the\n        process which is a serious Brucie bonus!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/january/joel-biffin-leveraging-localised-gems-llgems-re-using-code-the-ruby-way-safely-lrug-jan-2024.mp4\"\n      slides_url: \"https://github.com/joelbiffin/talks/blob/main/llgems/slides.pdf\"\n- id: \"lrug-february-2024\"\n  title: \"LRUG February 2024\"\n  event_name: \"LRUG February 2024\"\n  date: \"2024-02-12\"\n  announced_at: \"2024-01-14 22:51:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-february-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/february/\n  talks:\n    - id: \"jay-caines-gooby-lrug-february-2024\"\n      title: \"Data pagination for jekyll-paginate-v2\"\n      event_name: \"LRUG February 2024\"\n      date: \"2024-02-12\"\n      announced_at: \"2024-01-14 22:51:00 +0000\"\n      speakers:\n        - Jay Caines-Gooby\n      description: |-\n        A quick dive into getting data-pagination (`.csv`, `.json`, `.tsv` & `.yaml` files in your\n        `_data` directory) working with the\n        [jekyll-paginate-v2](https://github.com/sverrirs/jekyll-paginate-v2) gem. After deciding that\n        I wanted to archive my posts to a Slack `#music-we-like` channel, I wanted to also make the\n        archived posts paginatible...\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/february/jay-caines-gooby-data-pagination-for-jekyll-paginate-v2-lrug-feb-2024.mp4\"\n    - id: \"jonathan-james-lrug-february-2024\"\n      title: \"Using devcontainers with Ruby\"\n      event_name: \"LRUG February 2024\"\n      date: \"2024-02-12\"\n      announced_at: \"2024-01-14 22:51:00 +0000\"\n      speakers:\n        - Jonathan James\n      description: |-\n        When an engineer joins your organisation, how long does it take for them to configure their\n        development environment? I will discuss using [devcontainers with\n        VSCode](https://code.visualstudio.com/docs/devcontainers/containers) to reduce this time from\n        \"days\" to \"minutes\".\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/february/jonathan-james-using-devcontainers-with-ruby-lrug-feb-2024.mp4\"\n      slides_url: \"https://github.com/jonathanjames1729/talks/blob/main/2024-02-12-lrug/devcontainers.pdf\"\n    - id: \"katya-essina-sarah-o-grady-lrug-february-2024\"\n      title: \"Contract testing between Ruby applications\"\n      event_name: \"LRUG February 2024\"\n      date: \"2024-02-12\"\n      announced_at: \"2024-01-14 22:51:00 +0000\"\n      speakers:\n        - Katya Essina\n        - Sarah O'Grady\n      description: |-\n        - what is contract testing & how it works\n        - why we need contract testing at Funding Circle\n        - what a contract test looks like for a Ruby application\n        - how contract testing works in practice\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/february/katya-essina-and-sarah-o-grady-contract-testing-between-ruby-applications-lrug-feb-2024.mp4\"\n    - id: \"fell-sunderland-lrug-february-2024\"\n      title: \"What is ruby really capable of?\"\n      event_name: \"LRUG February 2024\"\n      date: \"2024-02-12\"\n      announced_at: \"2024-01-14 22:51:00 +0000\"\n      speakers:\n        - fell sunderland\n      description: |-\n        I'd like to do a whistlestop tour of a few different gems I've written over the years, with\n        the aim of talking about having fun whilst learning what ruby is capable of. I'd like to\n        showcase things like [aspectual](https://github.com/AgentAntelope/aspectual) for bringing\n        aspect oriented programming to ruby,\n        [cherry-pick](https://github.com/AgentAntelope/cherry_pick) for when you miss `import foo\n        from bar`, [overload](https://github.com/AgentAntelope/overload) for when you want to\n        *really* have optional arguments do something different, and more!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/february/fell-sunderland-what-is-ruby-really-capable-of-lrug-feb-2024.mp4\"\n      slides_url: \"https://docs.google.com/presentation/d/1GNzpKWO6aqqbfo4eOTixIL_r1GI08bFYWjyRhBOUmBk/edit?usp=sharing\"\n    - id: \"martin-tomov-lrug-february-2024\"\n      title: \"Phlex for a happy developer!\"\n      event_name: \"LRUG February 2024\"\n      date: \"2024-02-12\"\n      announced_at: \"2024-01-14 22:51:00 +0000\"\n      speakers:\n        - Martin Tomov\n      description: |-\n        More than 100 lines files are bad? Not if you have the right tools! Inline\n        your templates, JavaScript, business & controller logic for maximum\n        productivity!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/february/martin-tomov-phlex-for-a-happy-developer-lrug-feb-2024.mp4\"\n    - id: \"scott-matthewman-lrug-february-2024\"\n      title: \"Be More GARY: How to up your RSpec Game\"\n      event_name: \"LRUG February 2024\"\n      date: \"2024-02-12\"\n      announced_at: \"2024-01-14 22:51:00 +0000\"\n      speakers:\n        - Scott Matthewman\n      description: |-\n        Elevate your RSpec tests by questioning common DRY practices. Enter the GARY\n        method, where strategic repetition enhances test clarity and maintainability.\n        Resist premature refactoring and convoluted logic, leaving yourself with\n        clearer tests that document your code. Go ahead, repeat yourself.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/february/scott-matthewman-be-more-gary-how-to-up-your-rspec-game-lrug-feb-2024.mp4\"\n    - id: \"paolo-fabbri-lrug-february-2024\"\n      title: \"Making games with ruby\"\n      event_name: \"LRUG February 2024\"\n      date: \"2024-02-12\"\n      announced_at: \"2024-01-14 22:51:00 +0000\"\n      speakers:\n        - Paolo Fabbri\n      description: |-\n        Learn how the Dragonruby game engine makes game development faster and simpler for\n        everyone, from beginners to pros. Explore its key features, and jumpstart\n        your journey into the world of game creation.\n        Join us to transform your ideas into reality with ease!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/february/paolo-fabbri-making-games-with-ruby-lrug-feb-2024.mp4\"\n- id: \"lrug-march-2024\"\n  title: \"LRUG March 2024\"\n  event_name: \"LRUG March 2024\"\n  date: \"2024-03-11\"\n  announced_at: \"2024-02-18 16:32:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-march-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/march/\n  talks:\n    - id: \"luke-thomas-lrug-march-2024\"\n      title: \"How to Stop Being a Subject Matter Expert\"\n      event_name: \"LRUG March 2024\"\n      date: \"2024-03-11\"\n      announced_at: \"2024-02-18 16:32:00 +0000\"\n      speakers:\n        - Luke Thomas\n      description: |-\n        Tactics for helping that stressed-out single point of failure in your life\n        become a happier member of a team...of multiple points of failure.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/march/luke-thomas-how-to-stop-being-a-subject-matter-export-lrug-mar-2024.mp4\"\n    - id: \"laurie-young-lrug-march-2024\"\n      title: \"WTF is Technical Strategy\"\n      event_name: \"LRUG March 2024\"\n      date: \"2024-03-11\"\n      announced_at: \"2024-02-18 16:32:00 +0000\"\n      speakers:\n        - Laurie Young\n      description: |-\n        The phrase \"Technical Strategy\" is often used by senior leaders when they want\n        something from their tech teams. However, it's an unclear phrase that doesn't\n        explain what is needed or why. In this talk, you will learn what's behind the\n        phrase, but also how anyone from a CTO to a new developer can use that\n        knowledge to drive conversations that will help not just the leadership but\n        the whole organisation.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/march/laurie-young-wtf-is-technical-strategry-lrug-mar-2024.mp4\"\n- id: \"lrug-april-2024\"\n  title: \"LRUG April 2024\"\n  event_name: \"LRUG April 2024\"\n  date: \"2024-04-08\"\n  announced_at: \"2024-03-15 20:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-april-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/april/\n  talks:\n    - id: \"murray-steele-lrug-april-2024\"\n      title: \"Do you want a flake with that?\"\n      event_name: \"LRUG April 2024\"\n      date: \"2024-04-08\"\n      announced_at: \"2024-03-15 20:30:00 +0000\"\n      speakers:\n        - Murray Steele\n      description: |-\n        Flaky tests are awful, in this talk we'll explore why tests flake and look at\n        some techniques and tools you can use to discover why your tests are flaking.\n      additional_resources:\n        - name: \"Transcript\"\n          type: \"transcript\"\n          title: \"Talks ∋ Do you want a flake with that?\"\n          url: \"http://h-lame.com/talks/do-you-want-a-flake-with-that/\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/april/murray-steele-do-you-want-a-flake-with-that-lrug-apr-2024.mp4\"\n    - id: \"frederick-cheung-lrug-april-2024\"\n      title: \"What the Chernobyl disaster can teach us about incident response\"\n      event_name: \"LRUG April 2024\"\n      date: \"2024-04-08\"\n      announced_at: \"2024-03-15 20:30:00 +0000\"\n      speakers:\n        - Frederick Cheung\n      description: |-\n        What does the worst nuclear disaster ever have in common with a web application being down?\n        On the face of it, vanishingly little, but the incredible series of events before, during and\n        after the disaster have plenty of insights to teach us about more mundane situations\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/april/frederick-cheung-what-the-chernobyl-disaster-can-teach-us-about-incident-response-lrug-apr-2024.mp4\"\n- id: \"lrug-may-2024\"\n  title: \"LRUG May 2024\"\n  event_name: \"LRUG May 2024\"\n  date: \"2024-05-13\"\n  announced_at: \"2024-04-16 20:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-may-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/may/\n  talks:\n    - id: \"enrico-teotti-lrug-may-2024\"\n      title: \"Build and maintain large Ruby applications\"\n      event_name: \"LRUG May 2024\"\n      date: \"2024-05-13\"\n      announced_at: \"2024-04-16 20:30:00 +0000\"\n      speakers:\n        - Enrico Teotti\n      description: |-\n        This presentation will be about the challenges of building large\n        Ruby web applications and how to maintain existing ones. I will use examples\n        adapted from real applications that I worked on during my 10 years of experience\n        with Ruby outlining: technical limitations of the language, how to use a modular\n        dependency structure to enforce boundaries in complex domains.\n      video_id: \"lrug-2024-05-13-build-and-maintain-large-ruby-applications\"\n      video_provider: \"not_published\"\n    - id: \"winston-ferguson-lrug-may-2024\"\n      title: \"Building modern eCommerce applications using Rails 7\"\n      event_name: \"LRUG May 2024\"\n      date: \"2024-05-13\"\n      announced_at: \"2024-04-16 20:30:00 +0000\"\n      speakers:\n        - Winston Ferguson\n      description: |-\n        With the newest Rails version, we can create platforms that offer the\n        modern features customers and sellers expect, with less complexity. Combine\n        it with an established open-source gem like Spree, and you've got a\n        comprehensive commerce system. I'll share my learnings from three real-life\n        examples: a music label selling limited edition vinyl LPs, a wholesaler\n        shedding enterprise SaaS for a tailor-made setup, and my furniture startup,\n        where CAD brings bespoke pieces to life.\n      video_id: \"lrug-2024-05-13-building-modern-ecommerce-applications-using-rails-7\"\n      video_provider: \"not_published\"\n- id: \"lrug-june-2024\"\n  title: \"LRUG June 2024\"\n  event_name: \"LRUG June 2024\"\n  date: \"2024-06-10\"\n  announced_at: \"2024-05-20 21:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-june-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/june/\n  talks:\n    - id: \"andy-allan-lrug-june-2024\"\n      title: \"Things I've learned maintaining OpenStreetMap\"\n      event_name: \"LRUG June 2024\"\n      date: \"2024-06-10\"\n      announced_at: \"2024-05-20 21:00:00 +0000\"\n      speakers:\n        - Andy Allan\n      description: |-\n        Maintaining one of the world's largest non-commercial websites,\n        [OpenStreetMap](https://openstreetmap.org), is a unique challenge. We're a\n        small, volunteer-based development team, not professional software\n        developers. I will illustrate some of these challenges with a mixture of\n        technical and organisational tips, tricks and recommendations, that you might\n        find useful for your own teams and projects too.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/june/andy-allan-things-ive-learned-maintaining-openstreetmap-lrug-jun-2024.mp4\"\n    - id: \"yevhenii-kurtov-lrug-june-2024\"\n      title: \"LiveView: stateful, server-rendered HTML\"\n      event_name: \"LRUG June 2024\"\n      date: \"2024-06-10\"\n      announced_at: \"2024-05-20 21:00:00 +0000\"\n      speakers:\n        - Yevhenii Kurtov\n      description: |-\n        LiveView is  Elixir's analogue to Hotwire that also helps to keep it closer\n        to the server and contributes to the One Person Framework movement.  In this talk,\n        we will explore how the stateful model makes it different from similar technologies\n        and what optimisations the Phoenix team did to make it feel snappy and deliver a\n        world-class UX\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/june/yevhenii-kurtov-liveview-stateful-server-rendered-html-lrug-jun-2024.mp4\"\n- id: \"lrug-july-2024\"\n  title: \"LRUG July 2024\"\n  event_name: \"LRUG July 2024\"\n  date: \"2024-07-08\"\n  announced_at: \"2024-06-23 08:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-july-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/july/\n  talks:\n    - id: \"fell-sunderland-lrug-july-2024\"\n      title: \"That smells like time\"\n      event_name: \"LRUG July 2024\"\n      date: \"2024-07-08\"\n      announced_at: \"2024-06-23 08:00:00 +0000\"\n      speakers:\n        - fell sunderland\n      description: |-\n        How does an experienced programmer solve problems? It's simpler (and more\n        complicated) than you might think!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/july/fell-sunderland-that-smells-like-time-lrug-jul-2024.mp4\"\n      slides_url: \"https://docs.google.com/presentation/d/1eAdmyQVROnJzcLfC1rOo7RjwsABFR21AqVKgg-9irdE/edit?usp=sharing\"\n    - id: \"joel-biffin-lrug-july-2024\"\n      title: \"Finding unused Ruby methods\"\n      event_name: \"LRUG July 2024\"\n      date: \"2024-07-08\"\n      announced_at: \"2024-06-23 08:00:00 +0000\"\n      speakers:\n        - Joel Biffin\n      description: |-\n        Whether code is safe to delete or not is a bit of a murky question in\n        Ruby - especially in untyped Ruby. Fear not though, as dangling unused\n        methods are a pretty safe place to start deleting things. Let's start there\n        and see where we get to.  Introducing [the Thanatos\n        gem](https://github.com/joelbiffin/thanatos) to help you find those unused\n        methods lurking in your code.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/july/joel-biffin-finding-unused-ruby-methods-lrug-jul-2024.mp4\"\n- id: \"lrug-august-2024\"\n  title: \"LRUG August 2024\"\n  event_name: \"LRUG August 2024\"\n  date: \"2024-08-12\"\n  announced_at: \"2024-07-20 08:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-august-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/august/\n  talks:\n    - id: \"ayush-newatia-lrug-august-2024\"\n      title: \"Turn Left for Bridgetown: An overview of a next-generation static(ish) site generator\"\n      event_name: \"LRUG August 2024\"\n      date: \"2024-08-12\"\n      announced_at: \"2024-07-20 08:00:00 +0000\"\n      speakers:\n        - Ayush Newatia\n      description: |-\n        Bridgetown is a modern progressive site generator with Jekyll ancestry.\n        Allow me to be your guide as I take you on a whistle-stop tour of its biggest\n        and best features; and show you how it brings Ruby-powered site generation into\n        2024.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/august/ayush-newatia-turn-left-for-bridgetown-an-overview-of-a-next-generation-static-ish-site-generator-lrug-aug-2024.mp4\"\n- id: \"lrug-september-2024\"\n  title: \"LRUG September 2024\"\n  event_name: \"LRUG September 2024\"\n  date: \"2024-09-09\"\n  announced_at: \"2024-08-16 08:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-september-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/september/\n  talks:\n    - id: \"rachel-bingham-boaz-yehezkel-lrug-september-2024\"\n      title: \"B&W Rewards - Domains, Events & Ledgers\"\n      event_name: \"LRUG September 2024\"\n      date: \"2024-09-09\"\n      announced_at: \"2024-08-16 08:00:00 +0000\"\n      speakers:\n        - Rachel Bingham\n        - Boaz Yehezkel\n      description: |-\n        How we developed the B&W Rewards system.\n\n        Starting from event storming with stakeholders and technical planning across squads to clear\n        domain boundaries how we used an event bus and agnostic accounting system to keep things\n        clear, concise and extendable.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/september/rachel-bingham-b-and-w-rewards-domains-events-and-ledgers-lrug-sep-2024.mp4\"\n    - id: \"lily-stoney-lrug-september-2024\"\n      title: \"From Spaghetti to Lasagna: Layering your code with DDD\"\n      event_name: \"LRUG September 2024\"\n      date: \"2024-09-09\"\n      announced_at: \"2024-08-16 08:00:00 +0000\"\n      speakers:\n        - Lily Stoney\n      description: |-\n        How to apply DDD to a monolithic codebase, the benefits and reasons why it can\n        be beneficial, and how the event storming process can make the process of\n        defining domain boundaries a simpler task!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/september/lily-stoney-from-spaghetti-to-lasagna-layering-your-code-with-ddd-lrug-sep-2024.mp4\"\n- id: \"lrug-october-2024\"\n  title: \"LRUG October 2024\"\n  event_name: \"LRUG October 2024\"\n  date: \"2024-10-14\"\n  announced_at: \"2024-09-09 12:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-october-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/october/\n  talks:\n    - id: \"james-smith-lrug-october-2024\"\n      title: \"Fighting Enshittification with ActivityPub\"\n      event_name: \"LRUG October 2024\"\n      date: \"2024-10-14\"\n      announced_at: \"2024-09-09 12:00:00 +0000\"\n      speakers:\n        - James Smith\n      description: |-\n        ActivityPub is the protocol that powers the Fediverse, a web of social sites\n        like Mastodon, PixelFed, and a host of other free and open source tools. I’ll\n        explain what ActivityPub is, how it works, and discuss the Federails Rails\n        engine which allows you to add federation into your existing Rails web apps.\n        By breaking open the silos of existing social media like this, we can fight\n        the enshittification of the web and reclaim a bit of power from the massive\n        companies that own our online lives.\n      additional_resources:\n        - name: \"Source Code\"\n          type: \"code\"\n          title: \"Federails, a Rails engine to add ActivityPub to your app\"\n          url: \"https://gitlab.com/experimentslabs/federails\"\n        - name: \"Source Code\"\n          type: \"code\"\n          title: \"Caber, a simple ReBAC / Zanzibar gem\"\n          url: \"https://github.com/manyfold3d/caber\"\n        - name: \"Source Code\"\n          type: \"code\"\n          title: \"Mittsu, a Ruby port of Three.js\"\n          url: \"https://github.com/danini-the-panini/mittsu\"\n        - name: \"Link\"\n          type: \"link\"\n          title: \"And the reason behind all this: Manyfold, a Rails app for managing and sharing 3d models\"\n          url: \"https://manyfold.app\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/october/james-smith-fighting-enshittification-with-activity-pub-lrug-oct-2024.mp4\"\n      slides_url: \"https://floppy.org.uk/activitypub-talk/\"\n    - id: \"jade-dickinson-lrug-october-2024\"\n      title: \"Plan to scale or plan to fail: an evidence-based approach for improving systems performance\"\n      event_name: \"LRUG October 2024\"\n      date: \"2024-10-14\"\n      announced_at: \"2024-09-09 12:00:00 +0000\"\n      speakers:\n        - Jade Dickinson\n      description: |-\n        In this talk, I will present a methodology for replicating most standard\n        Rails systems, for the purpose of load testing.\n\n        You can use this to find out how your system performs with more traffic than\n        you currently encounter. This will be useful if you are on a Rails team that\n        is starting to see scaling challenges.\n\n        At Theta Lake we operate at scale and are applying this methodology to\n        proactively find ways to bring down our server costs. You don’t want to leave\n        it until either your server costs soar out of control, or your entire system\n        is about to fail. By seeing into the future just a little bit, you can find\n        bottlenecks in your system and so find where you can improve its scalability.\n      video_id: \"lrug-2024-10-14-plan-to-scale-or-plan-to-fail\"\n      video_provider: \"not_published\"\n- id: \"lrug-december-2024\"\n  title: \"LRUG December 2024\"\n  event_name: \"LRUG December 2024\"\n  date: \"2024-12-09\"\n  announced_at: \"2024-11-18 21:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-december-2024\"\n  description: |-\n    https://lrug.org/meetings/2024/december/\n  talks:\n    - id: \"adam-dawkins-lrug-december-2024\"\n      title: \"Saving My Relationship with Rails\"\n      event_name: \"LRUG December 2024\"\n      date: \"2024-12-09\"\n      announced_at: \"2024-11-18 21:00:00 +0000\"\n      speakers:\n        - Adam Dawkins\n      description: |-\n        Setting healthy boundaries for a happy app. Our apps inevitably get more\n        complex over time, and Rails isn't always helpful when that happens. In this\n        talk we'll explore what a Rails app can look like with a 'functional core',\n        and where to draw the boundaries between the core and Rails to stop things\n        getting out of control.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/december/adam-dawkins-saving-my-relationship-with-rails-lrug-dec-2024.mp4\"\n    - id: \"clem-capel-bird-lrug-december-2024\"\n      title: \"Mistakes Were Made: Lessons from Failure\"\n      event_name: \"LRUG December 2024\"\n      date: \"2024-12-09\"\n      announced_at: \"2024-11-18 21:00:00 +0000\"\n      speakers:\n        - Clem Capel-Bird\n      description: |-\n        This is a story of failure: the things I broke delivering a big project, the\n        lessons those mistakes taught me, and why breaking things can be an\n        engineer’s best tool for learning.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2024/december/clem-capel-bird-mistakes-were-made-lessons-from-failure-lrug-dec-2024.mp4\"\n- id: \"lrug-january-2025\"\n  title: \"LRUG January 2025\"\n  event_name: \"LRUG January 2025\"\n  date: \"2025-01-13\"\n  announced_at: \"2024-12-18 21:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-january-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/january/\n  talks:\n    - id: \"pablo-dejuan-calzolari-lrug-january-2025\"\n      title: \"Shape-up: the best parts\"\n      event_name: \"LRUG January 2025\"\n      date: \"2025-01-13\"\n      announced_at: \"2024-12-18 21:00:00 +0000\"\n      speakers:\n        - Pablo Dejuan Calzolari\n      description: |-\n        A talk about the 37 signals famous methodology and how we apply to 8 teams of\n        development which work in Ruby on Rails.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/january/pablo-dejuan-calzolari-shape-up-the-best-parts-jan-2025.mp4\"\n    - id: \"yevhenii-kurtov-lrug-january-2025\"\n      title: \"They're not right, you're not wrong\"\n      event_name: \"LRUG January 2025\"\n      date: \"2025-01-13\"\n      announced_at: \"2024-12-18 21:00:00 +0000\"\n      speakers:\n        - Yevhenii Kurtov\n      description: |-\n        We are going to look into the essence of what DDD is and why it came to\n        be in plain English, without any consultant lingo. We will also\n        evaluate its advantages, indicators of the possibility of successful\n        adoption, and reasons to do so.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/january/yevhenii-kurtov-they-re-not-right-you-re-not-wrong-jan-2025.mp4\"\n- id: \"lrug-february-2025\"\n  title: \"LRUG February 2025\"\n  event_name: \"LRUG February 2025\"\n  date: \"2025-02-10\"\n  announced_at: \"2025-01-15 18:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-february-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/february/\n  talks:\n    - id: \"fell-sunderland-lrug-february-2025\"\n      title: \"AI tools for programmers\"\n      event_name: \"LRUG February 2025\"\n      date: \"2025-02-10\"\n      announced_at: \"2025-01-15 18:00:00 +0000\"\n      speakers:\n        - fell sunderland\n      description: |-\n        Why I don't use AI programming tools, and I don't think you should either.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/february/fell-sunderland-ai-tools-for-programmers-lrug-feb-2025.mp4\"\n    - id: \"david-lantos-lrug-february-2025\"\n      title: \"Why our schema files kept changing\"\n      event_name: \"LRUG February 2025\"\n      date: \"2025-02-10\"\n      announced_at: \"2025-01-15 18:00:00 +0000\"\n      speakers:\n        - David Lantos\n      description: |-\n        Tale of an investigation why a local `db:schema:load` would change our\n        `db/schema.rb` for seemingly no reason. Spoiler: varchar index\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/february/david-lantos-why-our-schema-files-kept-changing-lrug-feb-2025.mp4\"\n    - id: \"jon-rowe-lrug-february-2025\"\n      title: \"10 years of RSpec in 10 minutes\"\n      event_name: \"LRUG February 2025\"\n      date: \"2025-02-10\"\n      announced_at: \"2025-01-15 18:00:00 +0000\"\n      speakers:\n        - Jon Rowe\n      description: |-\n        A brief look into the history of [RSpec](https://rspec.info) and a glance into the future.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/february/jon-rowe-10-years-of-rspec-in-10-minutes-lrug-feb-2025.mp4\"\n    - id: \"zhiqiang-bian-lrug-february-2025\"\n      title: \"Rails 8 + AI = Happy Life for Lazy Engineer to Create a Walking Skeleton\"\n      event_name: \"LRUG February 2025\"\n      date: \"2025-02-10\"\n      announced_at: \"2025-01-15 18:00:00 +0000\"\n      speakers:\n        - Zhiqiang Bian\n      description: |-\n        In this talk, I’ll explore how Rails 8, combined with AI-assisted\n        tools, can help engineers rapidly spin up a walking skeleton—a minimal\n        yet functional end-to-end system—with minimal effort.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/february/zhiqiang-bian-rails-8-ai-happy-life-for-lazy-engineer-lrug-feb-2025.mp4\"\n    - id: \"eleanor-mchugh-lrug-february-2025\"\n      title: 'Never say, \"Never say die!\"'\n      event_name: \"LRUG February 2025\"\n      date: \"2025-02-10\"\n      announced_at: \"2025-01-15 18:00:00 +0000\"\n      speakers:\n        - Eleanor McHugh\n      description: |-\n        Ruby is a high-level language, and there's a general assumption that\n        it's ill-suited to low-level shenanigans. But is this true?\n\n        In this lightning talk I'll introduce some basic Ruby tools for\n        accessing low-level system features, concentrating on *nix platforms,\n        and see if it's possible to replicate tenderlove's Never Say Die gem\n        for recovering from segfaults.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/february/eleanor-mchugh-never-say-never-say-die-lrug-feb-2025.mp4\"\n    - id: \"jaehurn-nam-lrug-february-2025\"\n      title: \"The tag tale\"\n      event_name: \"LRUG February 2025\"\n      date: \"2025-02-10\"\n      announced_at: \"2025-01-15 18:00:00 +0000\"\n      speakers:\n        - Jaehurn Nam\n      description: |-\n        How we refactored Intercom's conversation tagging service to not fake\n        tag and made customers happy.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/february/jaehurn-nam-the-tag-tale-lrug-feb-2025.mp4\"\n    - id: \"yevhenii-kurtov-lrug-february-2025\"\n      title: \"Beyond current state: capturing how and why things changed\"\n      event_name: \"LRUG February 2025\"\n      date: \"2025-02-10\"\n      announced_at: \"2025-01-15 18:00:00 +0000\"\n      speakers:\n        - Yevhenii Kurtov\n      description: |-\n        Introduction into managing state for objects with complex lifecycle\n        when auditability is a must.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/february/yevhenii-kurtov-beyond-current-state-capturing-how-and-why-things-changed-lrug-feb-2025.mp4\"\n    - id: \"james-smith-lrug-february-2025\"\n      title: \"Self-Assessing against the Web Sustainability Guidelines\"\n      event_name: \"LRUG February 2025\"\n      date: \"2025-02-10\"\n      announced_at: \"2025-01-15 18:00:00 +0000\"\n      speakers:\n        - James Smith\n      description: |-\n        Sustainability is important, but it's also hard, especially when\n        building web projects. How do you know you're doing it right? This\n        quick talk will explain a tool I made for self-assessments against the\n        Web Sustainability Guidelines, which you can use too!\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/february/james-smith-self-assessing-against-the-web-sustainability-guidelines-lrug-feb-2025.mp4\"\n- id: \"lrug-march-2025\"\n  title: \"LRUG March 2025\"\n  event_name: \"LRUG March 2025\"\n  date: \"2025-03-10\"\n  announced_at: \"2025-02-14 16:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-march-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/march/\n  talks:\n    - id: \"gavin-morrice-lrug-march-2025\"\n      title: \"Objects talking to objects\"\n      event_name: \"LRUG March 2025\"\n      date: \"2025-03-10\"\n      announced_at: \"2025-02-14 16:00:00 +0000\"\n      speakers:\n        - Gavin Morrice\n      description: |-\n        A review on what makes OOP such an effective paradigm to work in,\n        followed by a critical discussion on some of the newer design trends in\n        the Ruby space. We will discuss the concerns of relying too heavily on\n        these patterns, and alternative approaches.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/march/gavin-morrice-objects-talking-to-objects-lrug-mar-2025.mp4\"\n    - id: \"hemal-varambhia-lrug-march-2025\"\n      title: \"Unlocking the Awesome Power of Refactoring at Work\"\n      event_name: \"LRUG March 2025\"\n      date: \"2025-03-10\"\n      announced_at: \"2025-02-14 16:00:00 +0000\"\n      speakers:\n        - Hemal Varambhia\n      description: |-\n        In this talk, I recount and discuss how I refactored some legacy ruby\n        code using the Simple Design Dynamo and ideas from \"Tidy First\" to make\n        it more agile, and then, using Domain-Driven Design, take that agility\n        to the next level.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/march/hemal-varambhia-unlocking-the-awesome-power-of-refactoring-at-work-lrug-mar-2025.mp4\"\n      slides_url: \"https://assets.lrug.org/slides/2025/march/hemal-varambhia-unlocking-the-awesome-power-of-refactoring-at-work.pdf\"\n- id: \"lrug-april-2025\"\n  title: \"LRUG April 2025\"\n  event_name: \"LRUG April 2025\"\n  date: \"2025-04-14\"\n  announced_at: \"2025-03-12 18:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-april-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/april/\n  talks:\n    - id: \"maciej-korsan-lrug-april-2025\"\n      title: \"From React to Hotwire – An Unexpected Journey\"\n      event_name: \"LRUG April 2025\"\n      date: \"2025-04-14\"\n      announced_at: \"2025-03-12 18:00:00 +0000\"\n      speakers:\n        - Maciej Korsan\n      description: |-\n        For years, React has been the go-to choice for building frontend applications\n        — but is it always the best solution? In this talk, I’ll share my journey from\n        working extensively with React to discovering Hotwire, a radically different\n        approach that enables dynamic applications without heavy JavaScript or complex\n        state management.\n\n        Rather than a theoretical comparison, I’ll walk through real-world examples,\n        demonstrating how I’ve implemented interactive features using Hotwire. I’ll\n        also discuss my experiences, the challenges I faced, and some surprising\n        discoveries along the way.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/april/maciej-korsan-from-react-to-hotwire-an-unexpected-journey-lrug-apr-2025.mp4\"\n    - id: \"mario-gintili-lrug-april-2025\"\n      title: \"AI has many applications in our industry, we are just getting started\"\n      event_name: \"LRUG April 2025\"\n      date: \"2025-04-14\"\n      announced_at: \"2025-03-12 18:00:00 +0000\"\n      speakers:\n        - Mario Gintili\n      description: |-\n        AI has many applications in our industry, we are just getting started.\n\n        In this talk, I'll explore an approach to AI-powered observability\n        tooling that knows everything about you and your codebase.\n\n        I'll demo some of the most recent tooling in AI-assisted development,\n        show you how to enrich an LLM with highly relevant contextual information and\n        display a little workflow that shows how to use AI to fix bugs faster as\n        they happen in production.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/april/mario-gintili-ai-has-many-applications-in-our-industry-we-are-just-getting-started-lrug-apr-2025.mp4\"\n- id: \"lrug-may-2025\"\n  title: \"LRUG May 2025\"\n  event_name: \"LRUG May 2025\"\n  date: \"2025-05-12\"\n  announced_at: \"2025-04-23 18:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-may-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/may/\n  talks:\n    - id: \"ismael-celis-lrug-may-2025\"\n      title: \"An event-sourced programming model for Ruby\"\n      event_name: \"LRUG May 2025\"\n      date: \"2025-05-12\"\n      announced_at: \"2025-04-23 18:00:00 +0000\"\n      speakers:\n        - Ismael Celis\n      description: |-\n        Exploring how Event Sourcing and Ruby can provide a cohesive programming\n        model where auditable data, durable workflows and reactive UIs are the default.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/may/ismael-celis-an-event-sourced-programming-model-for-ruby-lrug-may-2025.mp4\"\n    - id: \"andy-croll-lrug-may-2025\"\n      title: \"Mistakes were made, and definitely by me\"\n      event_name: \"LRUG May 2025\"\n      date: \"2025-05-12\"\n      announced_at: \"2025-04-23 18:00:00 +0000\"\n      speakers:\n        - Andy Croll\n      description: |-\n        [CoverageBook](https://coveragebook.com/) is a decade-old Rails codebase\n        which has seen at least one full internal rewrite.\n\n        Let’s have a walk through of perfectly “reasonable” decisions we made\n        at the time that we’re now unravelling, and the new Rails-y-ness we’re\n        using as we do it.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/may/andy-croll-mistakes-were-made-and-definitely-by-me-lrug-may-2025.mp4\"\n    - id: \"lorenzo-barasti-lrug-may-2025\"\n      title: \"Practical AI in Ruby: What LLMs Can (and Can't) Do For Your Projects Today\"\n      event_name: \"LRUG May 2025\"\n      date: \"2025-05-12\"\n      announced_at: \"2025-04-23 18:00:00 +0000\"\n      speakers:\n        - Lorenzo Barasti\n      description: |-\n        A no-nonsense exploration of integrating LLM capabilities into Ruby applications using\n        ruby_llm and similar libraries, highlighting real-world use cases without the Silicon\n        Valley hyperbole.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/may/lorenzo-barasti-practical-ai-in-ruby-what-llms-can-and-cant-do-for-your-projects-today-may-2025.mp4\"\n- id: \"lrug-june-2025\"\n  title: \"LRUG June 2025\"\n  event_name: \"LRUG June 2025\"\n  date: \"2025-06-09\"\n  announced_at: \"2025-05-27 21:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-june-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/june/\n  talks:\n    - id: \"vladimir-gorodulin-lrug-june-2025\"\n      title: \"Rethinking Service Objects in Ruby\"\n      event_name: \"LRUG June 2025\"\n      date: \"2025-06-09\"\n      announced_at: \"2025-05-27 21:30:00 +0000\"\n      speakers:\n        - Vladimir Gorodulin\n      description: |-\n        Service Objects in Ruby can feel a bit off to use, so I’ll share some\n        experiments insights on some pragmatic ways to make them work better by\n        shifting toward a more procedural approach.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/june/vladimir-gorodulin-rethinking-service-objects-in-ruby-lrug-jun-2025.mp4\"\n- id: \"lrug-july-2025\"\n  title: \"LRUG July 2025\"\n  event_name: \"LRUG July 2025\"\n  date: \"2025-07-14\"\n  announced_at: \"2025-06-24 12:30:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-july-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/july/\n  talks:\n    - id: \"fritz-meissner-lrug-july-2025\"\n      title: \"If you wish it was better, change it!\"\n      event_name: \"LRUG July 2025\"\n      date: \"2025-07-14\"\n      announced_at: \"2025-06-24 12:30:00 +0000\"\n      speakers:\n        - Fritz Meissner\n      description: |-\n        Wish you worked with understandable and easily changeable\n        code? Practice fixing the incomprehensible in an interactive,\n        zero-background-required exercise on the career-changing topic of\n        refactoring.\n      additional_resources:\n        - name: \"Source Code\"\n          type: \"code\"\n          title: \"The Noisy Animal code kata\"\n          url: \"https://github.com/thoughtbot/noisy-animals-kata\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/july/fritz-meissner-if-you-wish-it-was-better-change-it-lrug-jul-2025.mp4\"\n- id: \"lrug-august-2025\"\n  title: \"LRUG August 2025\"\n  event_name: \"LRUG August 2025\"\n  date: \"2025-08-11\"\n  announced_at: \"2025-07-26 20:31:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-august-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/august/\n  talks:\n    - id: \"julik-tarkhanov-lrug-august-2025\"\n      title: \"`stepper_motor`: effortless long-running workflows for Rails\"\n      event_name: \"LRUG August 2025\"\n      date: \"2025-08-11\"\n      announced_at: \"2025-07-26 20:31:00 +0000\"\n      speakers:\n        - Julik Tarkhanov\n      description: |-\n        Lately, there has been a lot of development in durable workflows in\n        Rails with tools like `active_job_continuation` and `acidic_job`.\n        [`stepper_motor`](https://github.com/stepper-motor/stepper_motor) is a\n        new tool allowing for identifiable, associable, orchestrated step\n        workflows for Rails applications - without gRPC, extra tools or data\n        stores. Let's explore where such a system comes from, why every durable\n        execution system is secretly a DAG, and how the `stepper_motor`\n        architecture is informed by VFX software instead of the imperative\n        `ActiveJob` methods.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/august/julik-tarkhanov-stepper-motor-effortless-long-running-workflows-for-rails-lrug-aug-2025.mp4\"\n    - id: \"james-edwards-jones-lrug-august-2025\"\n      title: \"No Browser Required: Dynamic OpenGraph Images with Rails and Rust\"\n      event_name: \"LRUG August 2025\"\n      date: \"2025-08-11\"\n      announced_at: \"2025-07-26 20:31:00 +0000\"\n      speakers:\n        - James Edwards-Jones\n      description: |-\n        How would you convert a `<div>` to a PNG? A technical deep dive into\n        how [`Himg`](https://github.com/Jamedjo/himg) generates images from\n        HTML without using a browser.\n\n        Our journey will include:\n\n        * How a browser works: from CSS parsing to image rendering\n        * Practical tips: like how to call Rust from Ruby\n        * Rails internals: how rails calls render without you needing to ask\n        * Using the [Himg](https://github.com/Jamedjo/himg/) library\n        * Server side request forgery and injection attacks\n        * What OpenGraph images are and how they can help you go viral 🦋\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/august/james-edwards-jones-no-browser-required-dynamic-opengraph-images-with-rails-and-rust-lrug-aug-2025.mp4\"\n- id: \"lrug-september-2025\"\n  title: \"LRUG September 2025\"\n  event_name: \"LRUG September 2025\"\n  date: \"2025-09-15\"\n  announced_at: \"2025-08-13 12:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-september-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/september/\n  talks:\n    - id: \"karl-lingiah-lrug-september-2025\"\n      title: \"Inheriting Gems\"\n      event_name: \"LRUG September 2025\"\n      date: \"2025-09-15\"\n      announced_at: \"2025-08-13 12:00:00 +0000\"\n      speakers:\n        - Karl Lingiah\n      description: |-\n        As Ruby developers we all rely on the vast RubyGem ecosystem, but as gem users we're not\n        necessarily aware of everything that goes into maintaining the gems that make up that\n        ecosystem. When I became a developer advocate at Vonage, I went from gem user to gem\n        maintainer overnight. In this talk I would like to share that journey, and some of the\n        lessons I learned along the way.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/september/karl-lingiah-inheriting-gems-lrug-sep-2025.mp4\"\n    - id: \"joel-chippindale-lrug-september-2025\"\n      title: \"Get on the same side of the table\"\n      event_name: \"LRUG September 2025\"\n      date: \"2025-09-15\"\n      announced_at: \"2025-08-13 12:00:00 +0000\"\n      speakers:\n        - Joel Chippindale\n      description: |-\n        Imagine the following situation. You disagree with your colleague (or your manager) but are\n        unable to change their minds. You feel stuck and frustrated. The only options you feel you\n        have available are to repeat your argument more forcefully or give up. Neither feels like a\n        good option.\n\n        Does this situation sound familiar to you?\n\n        In this talk, we will explore how to get unstuck, have more effective discussions with your\n        colleagues, and increase your influence.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/september/joel-chippindale-get-on-the-same-side-of-the-table-lrug-sep-2025.mp4\"\n      slides_url: \"https://blog.mocoso.co.uk/assets/get-on-the-same-side-of-the-table/get-on-the-same-side-of-the-table-lrug-2025-09.pdf\"\n- id: \"lrug-october-2025\"\n  title: \"LRUG October 2025\"\n  event_name: \"LRUG October 2025\"\n  date: \"2025-10-13\"\n  announced_at: \"2025-09-16 22:50:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-october-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/october/\n  talks:\n    - id: \"harry-lascelles-lrug-october-2025\"\n      title: \"Extreme Versioning\"\n      event_name: \"LRUG October 2025\"\n      date: \"2025-10-13\"\n      announced_at: \"2025-09-16 22:50:00 +0000\"\n      speakers:\n        - Harry Lascelles\n      description: |-\n        An exploration into the world of Software Versioning, with an emphasis on the RubyGems\n        ecosystem. This talk will cover extreme real-world examples from Rubyland and beyond,\n        including code examples, footguns and award winners, as well as tips for developers\n        navigating version management. It will get quite technical, so bring your regex hard hat.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/october/harry-lascelles-extreme-versioning-lrug-oct-2025.mp4\"\n    - id: \"josh-bebbington-lrug-october-2025\"\n      title: \"De-mystifying the GVL\"\n      event_name: \"LRUG October 2025\"\n      date: \"2025-10-13\"\n      announced_at: \"2025-09-16 22:50:00 +0000\"\n      speakers:\n        - Josh Bebbington\n      description: |-\n        The Global VM Lock is one of Ruby’s more mysterious 'under the hood' features. This talk\n        explores new ways to peer inside it, using Ruby's modern instrumentation to reveal how it\n        actually performs work. I'll demonstrate how we've applied those learnings at Carwow, to\n        optimise the performance and reliability of our Sidekiq workers.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/october/josh-bebbington-demystifying-the-gvl-lrug-oct-2025.mp4\"\n- id: \"lrug-november-2025\"\n  title: \"LRUG November 2025\"\n  event_name: \"LRUG November 2025\"\n  date: \"2025-11-10\"\n  announced_at: \"2025-10-16 18:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-november-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/november/\n  talks:\n    - id: \"ismael-celis-lrug-november-2025\"\n      title: \"Durable messaging and related patterns in Ruby, for fun and profit. But mostly just fun.\"\n      event_name: \"LRUG November 2025\"\n      date: \"2025-11-10\"\n      announced_at: \"2025-10-16 18:00:00 +0000\"\n      speakers:\n        - Ismael Celis\n      description: |-\n        I’ll explore how architecting Ruby apps around a durable message log enables different\n        patterns, from asynchronous processing, to event sourcing and durable execution\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/november/ismael-celis-durable-messaging-and-related-patterns-for-fun-and-profit-lrug-nov-2025.mp4\"\n    - id: \"james-smith-lrug-november-2025\"\n      title: \"How do you solve a problem like DHH?\"\n      event_name: \"LRUG November 2025\"\n      date: \"2025-11-10\"\n      announced_at: \"2025-10-16 18:00:00 +0000\"\n      speakers:\n        - James Smith\n      description: |-\n        In September, DHH, the creator of Rails and community figurehead, wrote a factually incorrect\n        post bemoaning the state of London these days, claiming that it’s no longer “native British”,\n        and promoting far right agitator Tommy Robinson.\n\n        At a time when the far right is rising in the UK, is this the figurehead our community needs?\n        Can we separate technology and political views? Should we?\n\n        This is less of a talk, and more of an opportunity for discussion - does something need to\n        change, and if so, how? And if not, what does that mean for the Ruby and Rails communities?\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2025/november/james-smith-how-do-you-solve-a-problem-like-dhh-lrug-nov-2025.mp4\"\n- id: \"lrug-december-2025\"\n  title: \"LRUG December 2025\"\n  event_name: \"LRUG December 2025\"\n  date: \"2025-12-08\"\n  announced_at: \"2025-11-19 21:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-december-2025\"\n  description: |-\n    https://lrug.org/meetings/2025/december/\n  talks:\n    - id: \"eleanor-mchugh-lrug-december-2025\"\n      title: \"Implementing Software Machines in Ruby\"\n      event_name: \"LRUG December 2025\"\n      date: \"2025-12-08\"\n      announced_at: \"2025-11-19 21:00:00 +0000\"\n      speakers:\n        - Eleanor McHugh\n      description: |-\n        This will be a quirky dive into the rudiments of virtual machine and emulator implementation.\n\n        When you're working with Ruby you’re relying on a software machine written by a small but\n        dedicated team of virtual machine enthusiasts. And unless you’ve taken a course in\n        programming language implementation you probably have only a loose idea of what this is, how\n        it works, or how easy it is to write your own machines.\n\n        In this fast-paced introduction I’ll use code written in Ruby to explain the basic\n        building-blocks with which we can model computing machines in software, covering as many of\n        the main architectural features as possible in the time: stacks; heaps; dispatchers; clocks;\n        registers; instruction sets.\n\n        Then I'll put them to a somewhat different use than you might expect.\n\n        This talk contains a lot of code (possibly including a smidgeon of gnarly C) but regardless\n        of you current skill level it will reveal a little of the magic which makes tools like Ruby\n        possible. The examples should also be sufficient to kickstart your own adventures in this\n        fascinating field.\n      video_id: \"lrug-2025-12-08-implementing-software-machines-in-ruby\"\n      video_provider: \"not_published\"\n      slides_url: \"https://www.slideshare.net/slideshow/implementing-software-machines-in-ruby-rough-cut/284563205\"\n    - id: \"yevhenii-kurtov-lrug-december-2025\"\n      title: \"Distributed Systems' Golden Ratio\"\n      event_name: \"LRUG December 2025\"\n      date: \"2025-12-08\"\n      announced_at: \"2025-11-19 21:00:00 +0000\"\n      speakers:\n        - Yevhenii Kurtov\n      description: |-\n        We'll spend our time interactively solving a distributed systems design challenge that will\n        gradually grow in complexity, taking participants on a journey to discover the golden rule\n        of distributed systems design: think globally, act locally.\n      video_id: \"lrug-2025-12-08-distributed-systems-golden-ration\"\n      video_provider: \"not_published\"\n- id: \"lrug-january-2026\"\n  title: \"LRUG January 2026\"\n  event_name: \"LRUG January 2026\"\n  date: \"2026-01-12\"\n  announced_at: \"2025-12-22 17:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-january-2026\"\n  description: |-\n    https://lrug.org/meetings/2026/january/\n  talks:\n    - id: \"stephen-creedon-lrug-january-2026\"\n      title: \"Rails Was Off the Rails - But It’s Back!\"\n      event_name: \"LRUG January 2026\"\n      date: \"2026-01-12\"\n      announced_at: \"2025-12-22 17:00:00 +0000\"\n      speakers:\n        - Stephen Creedon\n      description: |-\n        Rails lost its way during versions 4, 5, and 6 - becoming overly complex and slow as it\n        leaned heavily into JavaScript. But the story doesn’t end there. With Rails 8.1 introducing\n        features like Stimulus, Action Cable, and Solid Cable, the framework is returning to its\n        roots: simplicity, speed, and developer joy.\n\n        Join us for a deep dive into why Rails has its mojo back and what this means for the future\n        of Ruby development\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2026/january/stephen-creedon-rails-was-off-the-rails-but-its-back-lrug-jan-2026.mp4\"\n    - id: \"sebastian-siemianowski-lrug-january-2026\"\n      title: \"RSpec Craftsmanship and Refactoring with Junie\"\n      event_name: \"LRUG January 2026\"\n      date: \"2026-01-12\"\n      announced_at: \"2025-12-22 17:00:00 +0000\"\n      speakers:\n        - Sebastian Siemianowski\n      description: |-\n        In this talk, Sebastian will dive into RSpec as a craft — showing how thoughtful test\n        design can make refactoring less terrifying. You’ll see real-world examples of\n        transforming low-signal specs into readable, behaviour-driven tests, and learn how Junie, an\n        IDE-native AI assistant, can act as a second pair of eyes to improve naming, structure, and\n        guarantees.\n\n        This is a practical, opinionated look at using AI to support test quality—while keeping\n        human judgment firmly in control.\n\n        Why join?\n\n        - Many test suites pass—and still make refactoring terrifying. Why?\n        - Explore clarity, intent, and refactor safety in RSpec.\n        - See how AI can enhance craftsmanship without replacing developers.\n      video_id: \"lrug-2026-01-12-rspec-craftmanship-and-refactoring-with-junie\"\n      video_provider: \"not_published\"\n- id: \"lrug-february-2026\"\n  title: \"LRUG February 2026\"\n  event_name: \"LRUG February 2026\"\n  date: \"2026-02-09\"\n  announced_at: \"2026-01-22 17:17:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-february-2026\"\n  description: |-\n    https://lrug.org/meetings/2026/february/\n  talks:\n    - id: \"niall-mullally-lrug-february-2026\"\n      title: \"Automating Feature Flag Cleanup with AI\"\n      event_name: \"LRUG February 2026\"\n      date: \"2026-02-09\"\n      announced_at: \"2026-01-22 17:17:00 +0000\"\n      speakers:\n        - Niall Mullally\n      description: |-\n        At [BBB](https://www.british-business-bank.co.uk/), we use feature flags extensively in one\n        of our Rails applications.\n\n        Removing fully rolled-out feature flags is always a chore that’s easy to ignore and\n        eventually becomes a source of tech debt. In the talk, I’ll show how we use GitHub Actions\n        and GitHub Copilot to automatically generate PRs that remove obsolete flags and their\n        associated code paths.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2026/february/niall-mullally-automating-feature-flag-cleanup-with-ai-lrug-feb-2026.mp4\"\n    - id: \"lorenzo-barasti-lrug-february-2026\"\n      title: \"Why you might like some Truffle with your Ruby\"\n      event_name: \"LRUG February 2026\"\n      date: \"2026-02-09\"\n      announced_at: \"2026-01-22 17:17:00 +0000\"\n      speakers:\n        - Lorenzo Barasti\n      description: |-\n        An overview of [TruffleRuby](https://truffleruby.dev)’s latest release and some of the\n        perks of running on [GraalVM](https://www.graalvm.org)\n      additional_resources:\n        - name: \"Source Code\"\n          type: \"code\"\n          title: \"Github repository for the truffle ruby demo used in the talk\"\n          url: \"https://github.com/lbarasti/truffleruby-jfr-demo\"\n        - name: \"Link\"\n          type: \"link\"\n          title: \"Benchmarking blog post by Benoit Daloze mentioned in the talk\"\n          url: \"https://eregon.me/blog/2022/01/06/benchmarking-cruby-mjit-yjit-jruby-truffleruby.html\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2026/february/lorenzo-barasti-why-you-might-like-some-truffle-with-your-ruby-lrug-feb-2026.mp4\"\n      slides_url: \"https://docs.google.com/presentation/d/1UGQLaQ8JjGjpPkwoWC5Zw_jcQ78e4CyL9oOOJoT49go/edit?usp=sharing\"\n    - id: \"scott-matthewman-lrug-february-2026\"\n      title: \"THE BLOB MUST DIE! – How we destroyed a 1400-line monster\"\n      event_name: \"LRUG February 2026\"\n      date: \"2026-02-09\"\n      announced_at: \"2026-01-22 17:17:00 +0000\"\n      speakers:\n        - Scott Matthewman\n      description: |-\n        A lightning talk about how we are replacing an all-consuming User object with domain-specific\n        roles, delegated types and a smattering of metaprogramming – presented with a 1950s B-movie\n        vibe\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2026/february/scott-matthewman-the-blob-must-die-how-we-destroyed-a-1400-line-monster-lrug-feb-2026.mp4\"\n    - id: \"david-smith-lrug-february-2026\"\n      title: \"Junior Developers need your help\"\n      event_name: \"LRUG February 2026\"\n      date: \"2026-02-09\"\n      announced_at: \"2026-01-22 17:17:00 +0000\"\n      speakers:\n        - David Smith\n      description: |-\n        Raising awareness on how the junior/graduate developer market has collapsed - not sure on\n        this yet, will probably be more apparent as I write it.\n      additional_resources:\n        - name: \"Write-Up\"\n          type: \"write-up\"\n          title: \"Blog post - The Junior Developer Crisis by David Smith\"\n          url: \"https://open.substack.com/pub/davidrec/p/the-junior-developer-crisis?r=2xxv7&utm_campaign=post&utm_medium=web\"\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2026/february/david-smith-junior-developers-need-your-help-lrug-feb-2026.mp4\"\n    - id: \"jade-dickinson-lrug-february-2026\"\n      title: \"Managing a job search efficiently\"\n      event_name: \"LRUG February 2026\"\n      date: \"2026-02-09\"\n      announced_at: \"2026-01-22 17:17:00 +0000\"\n      speakers:\n        - Jade Dickinson\n      description: |-\n        How to manage a job search and interview prep\n      additional_resources:\n        - name: \"Write-Up\"\n          type: \"write-up\"\n          title: 'Jade Dickinson: ~# /blog/lrug/ \"Managing a job search efficiently\"'\n          url: \"https://jadedickinson.com/blog/lrug/\"\n      video_id: \"lrug-2026-02-09-managing-a-job-search-efficiently\"\n      video_provider: \"not_published\"\n    - id: \"eleanor-mchugh-lrug-february-2026\"\n      title: \"Shayk.online - anonymous chat with Sinatra and websockets\"\n      event_name: \"LRUG February 2026\"\n      date: \"2026-02-09\"\n      announced_at: \"2026-01-22 17:17:00 +0000\"\n      speakers:\n        - Eleanor McHugh\n      description: |-\n        A quick peek at one of my research projects and why Sinatra is a great tool for prototyping.\n      video_provider: \"mp4\"\n      video_id: \"https://assets.lrug.org/videos/2026/february/eleanor-mchugh-shayk-online-anonymous-chat-with-sinatra-and-websockets-lrug-feb-2026.mp4\"\n      slides_url: \"https://www.slideshare.net/slideshow/shayk-online-anonymous-chat-with-sinatra-and-websockets/285948608\"\n- id: \"lrug-march-2026\"\n  title: \"LRUG March 2026\"\n  event_name: \"LRUG March 2026\"\n  date: \"2026-03-09\"\n  announced_at: \"2026-02-15 17:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-march-2026\"\n  description: |-\n    https://lrug.org/meetings/2026/march/\n  talks:\n    - id: \"andy-walker-lrug-march-2026\"\n      title: \"If agentic coding is the tool shift, what's the role shift?\"\n      event_name: \"LRUG March 2026\"\n      date: \"2026-03-09\"\n      announced_at: \"2026-02-15 17:00:00 +0000\"\n      speakers:\n        - Andy Walker\n      description: |-\n        In this talk I'll compare today's AI moment to past tech S-curves, and argue it's not only a\n        toolset change that's required (learning to code agentically) but a deeper change in how we\n        work.\n\n        I'll cover the mindset and capability shifts this demands: outcome ownership, faster feedback\n        loops, more autonomy. I'll cover what engineers can do to meet the moment.\n\n        I'll also share how this is changing the way I think about hiring and scaling teams: what\n        signals matter now, and how we're adapting interview loops to find people who thrive in an\n        agentic world\n      video_id: \"lrug-2026-03-09-if-agentic-coding-is-the-tool-shift-whats-the-role-shift\"\n      video_provider: \"not_published\"\n    - id: \"neil-cameron-lrug-march-2026\"\n      title: \"RAG on Rails\"\n      event_name: \"LRUG March 2026\"\n      date: \"2026-03-09\"\n      announced_at: \"2026-02-15 17:00:00 +0000\"\n      speakers:\n        - Neil Cameron\n      description: |-\n        A brief guide to building out a retrieval augmented generation system on Rails.\n\n        We'll cover some of the basic (chunking, embeddings) and some not so basic things (why bother\n        re-ranking). You'll come away with an understanding of the different moving parts of a RAG\n        system and some tactical recommendations of gems and services to use.\n      video_id: \"lrug-2026-03-09-rag-on-rails\"\n      video_provider: \"not_published\"\n- id: \"lrug-april-2026\"\n  title: \"LRUG April 2026\"\n  event_name: \"LRUG April 2026\"\n  date: \"2026-04-13\"\n  announced_at: \"2026-03-23 12:00:00 +0000\"\n  video_provider: \"children\"\n  video_id: \"lrug-april-2026\"\n  description: |-\n    https://lrug.org/meetings/2026/april/\n  talks:\n    - id: \"hemal-varambhia-lrug-april-2026\"\n      title: \"The Hottest New Programming Language Is Ubiquitous (Within A Bounded Context Window)\"\n      event_name: \"LRUG April 2026\"\n      date: \"2026-04-13\"\n      announced_at: \"2026-03-23 12:00:00 +0000\"\n      speakers:\n        - Hemal Varambhia\n      description: |-\n        The title is a play on Andrey Karpathy's tweet.\n\n        This talk is a continuation of the one I gave at LRUG in March 2025.\n\n        Later that year I really started to reap the benefits of DDD and Ports and Adapters: refining\n        the programmer tests (no more Docker for unit tests!) and bringing the ubiquitous language to\n        life, which made writing tests cheap, and more importantly, fun.\n\n        Towards the end of 2025, I gave in to FOMO and started exploring AI-assisted programming. I\n        was particularly interested to see if it was now possible to prompt the LLM entirely in the\n        ubiquitous language and produce well-structured code.\n\n        Is the future of programming DDD's ubiquitous language?\n      video_id: \"lrug-2026-04-13-the-hottest-new-programming-language-is-ubiquitous-within-a-bounded-context-window\"\n      video_provider: \"not_published\"\n"
  },
  {
    "path": "data/lrug/series.yml",
    "content": "---\nname: \"London Ruby User Group\"\nwebsite: \"https://lrug.org\"\ngithub: \"https://github.com/lrug\"\nmastodon: \"https://ruby.social/@lrug\"\ntwitter: \"lrug\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nlanguage: \"english\"\ndefault_country_code: \"UK\"\naliases:\n  - LRUG\n  - El Rug\n"
  },
  {
    "path": "data/lyon-rb/lyon-rb-meetup/event.yml",
    "content": "---\nid: \"lyon-rb-meetup\"\ntitle: \"Lyon.rb Meetup\"\nkind: \"meetup\"\nlocation: \"Lyon, France\"\ndescription: |-\n  Les vidéos des talks réalisés par les membres de la communauté Lyon.rb, comme si vous y étiez !\npublished_at: \"2014-03-12\"\nyear: 2014\nchannel_id: \"UCFqRbkEEaM4w1iEK1ovBXxg\"\nwebsite: \"https://www.lyonrb.fr\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#930C10\"\ncoordinates:\n  latitude: 45.764043\n  longitude: 4.835659\n"
  },
  {
    "path": "data/lyon-rb/lyon-rb-meetup/videos.yml",
    "content": "---\n- id: \"lyon-rb-meetup-september-2019\"\n  title: \"Lyon.rb Meetup September 2019\"\n  event_name: \"Lyon.rb Meetup September 2019\"\n  date: \"2019-09-18\"\n  published_at: \"2019-11-06\"\n  description: |-\n    Bande annonce du 4ème meetup Lyon.rb de l'année 2019 (mercredi 18 septembre 2019 de 18:30 à 21:30).\n\n    Stranger Ruby... ou venez découvrir la magie, les étrangetés et les ambiguïtés de Ruby au travers de présentations réalisées par les membres de la communauté (programmation en cours).\n\n    Au programme :\n    - 18h30 : Début du meetup, faisons connaissance\n    - 19h00 : Présentations par les membres de la communauté Lyon.rb\n    - 20h00 : Débats et échanges entre participants\n    - 21h30 : Fin du meetup\n\n    L'évènement sera généreusement accueilli par le Coding Bootcamp | Le Wagon Lyon, à deux pas de l'Hôtel de Ville.\n\n    Inscrivez-vous sur l'application Meetup : https://www.meetup.com/fr-FR/LyonRB/events/263402616/\n\n    Trailer: https://www.youtube.com/watch?v=vxBLdeLLWUc\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-september-2019\"\n  language: \"french\"\n  thumbnail_xs: \"https://img.youtube.com/vi/vxBLdeLLWUc/default.jpg\"\n  thumbnail_sm: \"https://img.youtube.com/vi/vxBLdeLLWUc/mqdefault.jpg\"\n  thumbnail_md: \"https://img.youtube.com/vi/vxBLdeLLWUc/mqdefault.jpg\"\n  thumbnail_lg: \"https://img.youtube.com/vi/vxBLdeLLWUc/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/vxBLdeLLWUc/hqdefault.jpg\"\n  talks:\n    - title: \"Pourquoi utiliser un langage de débutants ?\"\n      raw_title: \"Pourquoi utiliser un langage de débutants ? - François Ferrandis - Lyon.rb\"\n      speakers:\n        - \"François Ferrandis\"\n      event_name: \"Lyon.rb Meetup September 2019\"\n      published_at: \"2020-01-01\"\n      date: \"2019-09-18\"\n      description: |-\n        François Ferrandis vous présente son talk intitulé : Pourquoi utiliser un langage de débutants ?\n\n        Meetup : 2019.4 / Stranger Ruby\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/263402616\n      video_provider: \"youtube\"\n      id: \"franois-ferrandis-lyonrb-meetup-september-2019\"\n      video_id: \"5Qutu4xPxe0\"\n      language: \"french\"\n\n    - title: \"Magic, Weird, Stranger Ruby\"\n      raw_title: \"Magic, Weird, Stranger Ruby - Gabriel Terrien - Lyon.rb\"\n      speakers:\n        - \"Gabriel Terrien\"\n      event_name: \"Lyon.rb Meetup September 2019\"\n      published_at: \"2019-12-01\"\n      date: \"2019-09-18\"\n      description: |-\n        Gabriel Terrien vous présente son talk intitulé : Magic, Weird, Stranger Ruby\n\n        Meetup : 2019.4 / Strange Ruby\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/263402616/\n      video_provider: \"youtube\"\n      id: \"gabriel-terrien-lyonrb-meetup-september-2019\"\n      video_id: \"zmGtszlrEX0\"\n      language: \"french\"\n\n    - title: \"Comment Ruby différencie les Constantes, les Variables et les méthodes\"\n      raw_title: \"Comment Ruby différencie les Constantes, les Variables et les méthodes - Guillaume Briday - Lyon.rb\"\n      speakers:\n        - \"Guillaume Briday\"\n      event_name: \"Lyon.rb Meetup April 2019\"\n      date: \"2019-09-18\"\n      published_at: \"2019-11-06\"\n      description: |-\n        Guillaume Briday vous présente son talk intitulé : Comment Ruby différencie les Constantes, les Variables et les méthodes\n        Retrouvez les slides ici : https://stranger-ruby.netlify.com/\n\n        Meetup : 2019.4 / Strange Ruby\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/263402616/\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-lyonrb-meetup-april-2019\"\n      video_id: \"MvgbOtEGpP0\"\n      language: \"french\"\n\n    - title: \"Module, Class et namespace\"\n      event_name: \"Lyon.rb Meetup September 2019\"\n      date: \"2019-09-18\"\n      published_at: \"2019-11-06\"\n      video_provider: \"not_published\"\n      id: \"joseph-lyon-rb-meetup-september-2019\"\n      video_id: \"joseph-lyon-rb-meetup-september-2019\"\n      language: \"french\"\n      thumbnail_xs: \"https://img.youtube.com/vi/vxBLdeLLWUc/default.jpg\"\n      thumbnail_sm: \"https://img.youtube.com/vi/vxBLdeLLWUc/mqdefault.jpg\"\n      thumbnail_md: \"https://img.youtube.com/vi/vxBLdeLLWUc/mqdefault.jpg\"\n      thumbnail_lg: \"https://img.youtube.com/vi/vxBLdeLLWUc/hqdefault.jpg\"\n      thumbnail_xl: \"https://img.youtube.com/vi/vxBLdeLLWUc/hqdefault.jpg\"\n      speakers:\n        - Joseph Blanchard\n\n- id: \"lyon-rb-meetup-cctober-2019\"\n  title: \"Lyon.rb Meetup October 2019\"\n  event_name: \"Lyon.rb Meetup October 2019\"\n  published_at: \"2019-12-01\"\n  date: \"2019-10-30\"\n  video_id: \"lyon-rb-meetup-cctober-2019\"\n  video_provider: \"children\"\n  description: |-\n    Bienvenue au 5ème meetup de l'année 2019 ! Cette fois-ci nous nous retrouverons pour une édition spéciale Lyon.rb x Vue.js en partenariat avec la communauté Meetup lyonnaise \"Vue.js Lyon\".\n\n    Après le succès du meetup de rentrée Stranger Ruby, ne ratez surtout pas cette édition qui s'annonce riche :-)\n\n    Venez découvrir avec nous les sujets suivants :\n\n    L'intégration de Vue dans un framework backend tel que Rails\n    Aperçu des nouveautés de Vue 3\n    Aperçu des nouveautés de Rails 6\n    Le programme de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres des communautés Lyon.rb / Vue.js Lyon\n    20h30 : Débats et échanges entre participants\n    21h30 : Fin du meetup\n    L'évènement sera généreusement accueilli par le Coding Bootcamp | Le Wagon Lyon, à deux pas de l'Hôtel de Ville.\n\n    Nous recherchons des speakers... Ne soyez pas timide ! Que vous veniez de découvrir un sujet intéressant ou que vous le maitrisiez déjà et souhaitez le partager, merci de contacter Jean-Michel :-)\n\n    https://www.meetup.com/fr-FR/LyonRB/events/265178775/\n\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/b/5/d/600_485379773.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/b/5/d/600_485379773.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/b/5/d/600_485379773.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/b/5/d/600_485379773.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/b/5/d/600_485379773.webp?w=750\"\n  talks:\n    - title: \"One Day In Rails 6 World\"\n      raw_title: \"One Day In Rails 6 World - François Belle et Jean-Michel Gigault - Lyon.rb\"\n      speakers:\n        - \"François Belle\"\n        - \"Jean-Michel Gigault\"\n      event_name: \"Lyon.rb Meetup October 2019\"\n      published_at: \"2019-12-01\"\n      date: \"2019-10-30\"\n      description: |-\n        François Belle et Jean-Michel Gigault vous présentent leur talk intitulé : One Day In Rails 6 World\n        Retrouvez le dépôt git ici : https://github.com/perangusta/one-day-in-rails6-world\n\n        Meetup : 2019.5 / Spéciale Lyon.rb x Vue.js\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/265178775/\n      video_provider: \"youtube\"\n      id: \"franois-belle-lyonrb-meetup-october-2019\"\n      video_id: \"GjzSCqVs1P4\"\n      language: \"french\"\n      additional_resources:\n        - name: \"perangusta/one-day-in-rails6-world\"\n          type: \"repo\"\n          url: \"https://github.com/perangusta/one-day-in-rails6-world\"\n\n    - title: \"L'intégration de Vue.js dans un framework backend\"\n      raw_title: \"L'intégration de Vue.js dans un framework backend - Guillaume Briday - Lyon.rb\"\n      speakers:\n        - \"Guillaume Briday\"\n      event_name: \"Lyon.rb Meetup October 2019\"\n      published_at: \"2019-12-08\"\n      date: \"2019-10-30\"\n      description: |-\n        Guillaume Briday vous présente son talk intitulé : L'intégration de Vue.js dans un framework backend\n        Retrouvez les slides ici : https://speciale-lyon-rb-x-vue-js.netlify.com/\n\n        Meetup : 2019.5 / Spéciale Lyon.rb x Vue.js\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/265178775/\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-lyonrb-meetup-october-2019\"\n      video_id: \"J4uTv2dg4Yg\"\n      language: \"french\"\n      slides_url: \"https://speciale-lyon-rb-x-vue-js.netlify.com/\"\n\n    - title: \"Les nouveautés de Vue.js 3.0\"\n      raw_title: \"Les nouveautés de Vue.js 3.0 - Adrien Montagu - Lyon.rb\"\n      speakers:\n        - \"Adrien Montagu\"\n      event_name: \"Lyon.rb Meetup October 2019\"\n      published_at: \"2019-12-11\"\n      date: \"2019-10-30\"\n      description: |-\n        Adrien Montagu vous présente son talk intitulé : Les nouveautés de Vue.js 3.0\n\n        Meetup : 2019.5 / Spéciale Lyon.rb x Vue.js\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/265178775/\n      video_provider: \"youtube\"\n      id: \"adrien-montagu-lyonrb-meetup-october-2019\"\n      video_id: \"Xv_XjCBRgO4\"\n      language: \"french\"\n\n- id: \"lyon-rb-meetup-november-2019\"\n  title: \"Lyon.rb Meetup November 2019\"\n  event_name: \"Lyon.rb Meetup November 2019\"\n  published_at: \"2019-12-11\"\n  date: \"2019-11-27\"\n  description: |-\n    Bienvenue au 6ème et dernier meetup de l'année 2019 !\n\n    Les sujets des présentations :\n\n    Un aperçu du protocole d'authentification OAuth 2.0 avec un focus sur le grant type \"Client Credentials\", dans quelle situation l'utiliser, quelles paramètres envoyer et à quoi ils correspondent\n    La différence String/Symbol, comment et pourquoi choisir entre les deux, les performances et pourquoi on peut appeler une méthode ou une variable avec un symbole\n    L'audit des données, qu'est-ce que c'est et pourquoi c'est important, exemple avec la gem paper_trail et exploitation des données avec PostgreSQL, le format jsonb et les CTE pour réaliser des snapshots de collections ActiveRecord\n    La rétrospective de l'année 2019 : La parole sera donnée aux membres en vue d'améliorer l'organisation des meetups de l'année 2020 !\n    Le programme de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants\n    21h30 : Fin du meetup\n    L'évènement sera généreusement accueilli par le Coding Bootcamp | Le Wagon Lyon, à deux pas de l'Hôtel de Ville.\n\n    Nous recherchons des speakers... Ne soyez pas timide ! Que vous veniez de découvrir un sujet intéressant ou que vous le maitrisiez déjà et souhaitez le partager, merci de contacter Jean-Michel :-)\n\n    https://www.meetup.com/fr-FR/LyonRB/events/266198856/\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-november-2019\"\n  language: \"french\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/c/a/1/d/600_486411741.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/c/a/1/d/600_486411741.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/c/a/1/d/600_486411741.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/c/a/1/d/600_486411741.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/c/a/1/d/600_486411741.webp?w=750\"\n  talks:\n    - title: \"Le framework d'autorisation OAuth 2.0\"\n      raw_title: \"Le framework d'autorisation OAuth 2.0 - Halil Bagdadi - Lyon.rb\"\n      speakers:\n        - \"Halil Bagdadi\"\n      event_name: \"Lyon.rb Meetup November 2019\"\n      published_at: \"2019-12-11\"\n      date: \"2019-11-27\"\n      description: |-\n        Halil Bagdadi vous présente son talk intitulé : Le framework d'autorisation OAuth 2.0, avec focus sur le grant type \"Client Credentials\"\n\n        Meetup : 2019.6 / Last, but not least\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/266198856/\n      video_provider: \"youtube\"\n      id: \"halil-bagdadi-lyonrb-meetup-november-2019\"\n      video_id: \"FJUEMVXKC_0\"\n      language: \"french\"\n\n    - title: \"La différence String / Symbol\"\n      raw_title: \"La différence String / Symbol - Maxime Personnic - Lyon.rb\"\n      speakers:\n        - \"Maxime Personnic\"\n      event_name: \"Lyon.rb Meetup November 2019\"\n      published_at: \"2019-12-16\"\n      date: \"2019-11-27\"\n      description: |-\n        Maxime Personnic vous présente son talk intitulé : La différence String / Symbol, comment et pourquoi choisir entre les deux, les performances et pourquoi on peut appeler une méthode ou une variable avec un symbole.\n\n        Meetup : 2019.6 / Last, but not least\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/266198856/\n      video_provider: \"youtube\"\n      id: \"maxime-personnic-lyonrb-meetup-november-2019\"\n      video_id: \"t_gBOhVSyzg\"\n      language: \"french\"\n\n- id: \"lyon-rb-meetup-january-2020\"\n  title: \"Lyon.rb Meetup January 2020\"\n  event_name: \"Lyon.rb Meetup January 2020\"\n  published_at: \"2020-02-22\"\n  date: \"2020-01-22\"\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-january-2020\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/5/c/b/600_488045579.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/5/c/b/600_488045579.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/5/c/b/600_488045579.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/5/c/b/600_488045579.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/5/c/b/600_488045579.webp?w=750\"\n  description: |-\n    Bienvenue au 1er meetup de l'année 2020 !\n\n    Durant cet évènement vous aurez l'occasion d'assister à 2 présentations et rencontrer les membres de la communauté Ruby lyonnaise.\n\n    Dette technique, par Mehdi Lahmam (environ 25 min)\n    Le terme \"dette technique\" est devenu fourre-tout dès qu'on veut décrire un bout de code qui mérite d'être repris. Cette mauvaise interprétation de la métaphore et confusion mène à des décisions désastreuses sur nos projets. Qu'est-ce qui est dette technique ? Qu'est ce qui ne l'est pas ? Pourquoi devrions-nous nous en préoccuper ? Quel est le coût de la confusion ? Que faire ? Cette présentation me permettra de discuter des origines de la métaphore, expliquer ce qu'est la dette technique, et comment l'identifier au sein d'un projet et la gérer.\n\n    Scaling teams with gRPC & Ruby, par Bryan Frimin (environ 25 min)\n    Comment laisser de l'autonomie aux équipes dans un environnement OKR ? Dans notre cas, nous avons choisi gRPC. Nous sommes passés de 3 à 15 squads en Ruby, Go et Elixir. Au menu : Concepts, Live coding Ruby, et retour d'expérience.\n\n    Le déroulé de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants\n    21h30 : Fin du meetup\n    L'évènement sera généreusement accueilli par La Cordée Opéra, à deux pas de l'Hôtel de Ville. Il sera sponsorisé par JobTeaser, Per Angusta et Studio HB.\n\n    Vous souhaitez présenter ou proposer un sujet à la communauté ? Contactez Jean-Michel ou Guillaume.\n\n    https://www.meetup.com/fr-FR/LyonRB/events/267283385/\n  talks:\n    - title: \"Dette technique\"\n      raw_title: \"Dette technique - Mehdi Lahmam - Lyon.rb\"\n      speakers:\n        - \"Mehdi Lahmam\"\n      event_name: \"Lyon.rb Meetup January 2020\"\n      published_at: \"2020-02-22\"\n      date: \"2020-01-22\"\n      description: |-\n        Le terme \"dette technique\" est devenu fourre-tout dès qu'on veut décrire un bout de code qui mérite d'être repris. Cette mauvaise interprétation de la métaphore et confusion mène à des décisions désastreuses sur nos projets. Qu'est-ce qui est dette technique ? Qu'est ce qui ne l'est pas ? Pourquoi devrions-nous nous en préoccuper ? Quel est le coût de la confusion ? Que faire ? Cette présentation me permettra de discuter des origines de la métaphore, expliquer ce qu'est la dette technique, et comment l'identifier au sein d'un projet et la gérer.\n\n        Meetup : 2020.1 / New Year, New Ruby\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/267283385\n      video_provider: \"youtube\"\n      id: \"mehdi-lahmam-lyonrb-meetup-january-2020\"\n      video_id: \"xRQjgVcsKh8\"\n      language: \"french\"\n\n    - title: \"Scaling teams with gRPC & Ruby\"\n      raw_title: \"Scaling teams with gRPC & Ruby - Bryan Frimin - Lyon.rb\"\n      speakers:\n        - \"Bryan Frimin\"\n      event_name: \"Lyon.rb Meetup January 2020\"\n      published_at: \"2020-02-24\"\n      date: \"2020-01-22\"\n      description: |-\n        Comment laisser de l'autonomie aux équipes dans un environnement OKR ? Dans notre cas, nous avons choisi gRPC. Nous sommes passés de 3 à 15 squads en Ruby, Go et Elixir. Au menu : Concepts, Live coding Ruby, et retour d'expérience.\n\n        Meetup : 2020.1 / New Year, New Ruby\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/267283385\n      video_provider: \"youtube\"\n      id: \"bryan-frimin-lyonrb-meetup-january-2020\"\n      video_id: \"jVzb3oySKdY\"\n      language: \"french\"\n\n- id: \"lyon-rb-meetup-february-2020\"\n  title: \"Lyon.rb Meetup February 2020\"\n  event_name: \"Lyon.rb Meetup February 2020\"\n  published_at: \"2020-02-28\"\n  date: \"2020-02-19\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/e/3/9/b/600_488278267.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/e/3/9/b/600_488278267.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/e/3/9/b/600_488278267.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/e/3/9/b/600_488278267.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/e/3/9/b/600_488278267.webp?w=750\"\n  description: |-\n    Bienvenue au 2ème meetup de l'année 2020 !\n\n    Durant cet évènement vous aurez l'occasion d'assister à des présentations et rencontrer les membres de la communauté Ruby lyonnaise.\n\n    \"Un aperçu de Postman\", par François Belle (environ 25 minutes)\n    Feedback d'un workshop aux API Days. Si vous pensez connaître Postman, peut être que vous n'avez en réalité touché qu'à la partie émergée de l'iceberg de ses fonctionnalités.\n\n    \"Bonne ou mauvaise pratique ? Sortons de cette logique et parlons plutôt de contexte\", par Guillaume Briday et Jean-Michel Gigault (environ 30 minutes)\n    Sur la base de nos expériences personnelles, nous allons vous partager des clés de compréhension pour vous aider à déterminer si vos pratiques de code sont adéquates ou non selon le contexte. Nous parlerons du contexte de votre code en tant que solution à des problématiques de vrais utilisateurs, mais aussi le votre en tant que développeur Web apprenant ou expérimenté.\n\n    Le déroulé de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants\n    21h30 : Fin du meetup\n    L'évènement sera généreusement accueilli par Niji Lyon, sur le quai Rambaud. Il sera sponsorisé par Per Angusta et Studio HB.\n\n    Vous souhaitez présenter ou proposer un sujet à la communauté ? Contactez Jean-Michel ou Guillaume.\n\n    https://www.meetup.com/fr-FR/LyonRB/events/268033713\n\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-february-2020\"\n  language: \"french\"\n  talks:\n    - title: \"Bonnes ou mauvaises pratiques ? Parlons plutôt de contexte\"\n      raw_title: \"Bonnes ou mauvaises pratiques ? Parlons plutôt de contexte - Guillaume B. & Jean-Michel G. - Lyon.rb\"\n      speakers:\n        - \"Guillaume Briday\"\n        - \"Jean-Michel Gigault\"\n      event_name: \"Lyon.rb Meetup February 2020\"\n      published_at: \"2020-02-28\"\n      date: \"2020-02-19\"\n      description: |-\n        Présenté par Guillaume Briday et Jean-Michel Gigault : Bonne ou mauvaise pratique ? Sortons de cette logique et parlons plutôt de contexte.\n        Sur la base de nos expériences personnelles, nous allons vous partager des clés de compréhension pour vous aider à déterminer si vos pratiques de code sont adéquates ou non selon le contexte. Nous parlerons du contexte de votre code en tant que solution à des problématiques de vrais utilisateurs, mais aussi le votre en tant que développeur Web apprenant ou expérimenté.\n\n        Meetup : 2020.2 / Ruby at the docks\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/268033713\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-lyonrb-meetup-february-2020\"\n      video_id: \"aWv9NWQPvu4\"\n      language: \"french\"\n\n    - title: \"Un aperçu de Postman\"\n      raw_title: \"Un aperçu de Postman - François Belle - Lyon.rb\"\n      speakers:\n        - \"François Belle\"\n      event_name: \"Lyon.rb Meetup February 2020\"\n      published_at: \"2020-03-04\"\n      date: \"2020-02-19\"\n      description: |-\n        Feedback d'un workshop aux API Days. Si vous pensez connaître Postman, peut être que vous n'avez en réalité touché qu'à la partie émergée de l'iceberg de ses fonctionnalités.\n\n        Meetup : 2020.2 / Ruby at the docks\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/LyonRB/events/268033713\n      video_provider: \"youtube\"\n      id: \"franois-belle-lyonrb-meetup-february-2020\"\n      video_id: \"UVSTxuHfqUA\"\n      language: \"french\"\n\n- id: \"lyon-rb-meetup-april-2020\"\n  title: \"Lyon.rb Meetup April 2020\"\n  event_name: \"Lyon.rb Meetup April 2020\"\n  published_at: \"2020-02-23\"\n  date: \"2020-04-15\"\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-april-2020\"\n  language: \"french\"\n  thumbnail_xs: \"https://img.youtube.com/vi/1Vzjp1x16Gk/default.jpg\"\n  thumbnail_sm: \"https://img.youtube.com/vi/1Vzjp1x16Gk/sddefault.jpg\"\n  thumbnail_md: \"https://img.youtube.com/vi/1Vzjp1x16Gk/mqdefault.jpg\"\n  thumbnail_lg: \"https://img.youtube.com/vi/1Vzjp1x16Gk/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/1Vzjp1x16Gk/hqdefault.jpg\"\n  speakers:\n    - TODO\n  description: |-\n    Bienvenue au 4ème meetup de l'année 2020 !\n\n    🎥 Regardez la BA ici : https://www.youtube.com/watch?v=1Vzjp1x16Gk\n\n    Stranger Ruby... épisode 2 ! Venez découvrir la magie, les étrangetés et les ambiguïtés de Ruby au travers de présentations réalisées par les membres de la communauté :-)\n\n    [programmation en cours]\n\n    Le déroulé de la soirée :\n\n    18h45 : Début du meetup, faisons connaissance\n    19h15 : Présentations par les membres de la communauté Lyon.rb\n    20h15 : Débats et échanges entre participants\n    21h30 : Fin du meetup\n\n    L'évènement sera généreusement accueilli par Le Wagon Lyon, à deux pas de l'Hôtel de Ville. Il sera sponsorisé par vpTech (La communauté Tech de Veepee), Studio HB et Per Angusta.\n\n    Vous souhaitez présenter ou proposer un sujet à la communauté ? Contactez Jean-Michel ou Guillaume.\n\n    https://www.meetup.com/fr-FR/LyonRB/events/268034312\n\n- id: \"lyon-rb-meetup-june-2022\"\n  title: \"Lyon.rb Meetup June 2022\"\n  event_name: \"Lyon.rb Meetup June 2022\"\n  published_at: \"2022-06-26\"\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-june-2022\"\n  date: \"2022-04-14\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/b/0/b/600_504211499.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/b/0/b/600_504211499.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/b/0/b/600_504211499.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/b/0/b/600_504211499.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/b/0/b/600_504211499.webp?w=750\"\n  description: |-\n    We are back!\n\n    Quel plaisir de pouvoir préparer un événement Lyon.rb à nouveau ! Après 2 ans d'absence à cause du Covid, on revient plus motivé que jamais.\n\n    Durant cet évènement vous aurez l'occasion d'assister à des présentations et rencontrer les membres de la communauté Ruby lyonnaise.\n\n    \"Performance Web, de quoi parle-t-on ?\", par Guillaume Briday (environ 20 minutes). On compare souvent les langages et frameworks entre eux. Mais de quoi parle-t-on quand on parle de performance Web ? Quel impact réel pour les utilisateurs ?\n    \"Threads et Ractors : concurrence et parallélisme en Ruby\" par Gabriel Terrien (environ 20 minutes). Ruby 3 a diversifié la façon de lancer des tâches en parallèle. Cette première présentation abordera de manière simple et basique, en pure Ruby, ces abstractions désormais à notre disposition.\n    \"Postgres FDW FTW\" par Mehdi Lahmam (environ 20 minutes). Aviez-vous déjà eu envie de croiser des données de plusieurs bases de données PG différentes, voire une base de données et une feuille Excel de l'équipe marketing ou finance ? Découvrez les Foreign Data Wrapper de Postgres et comment vous pourriez fabriquer un data warehouse assez facilement sans sortir l'artillerie lourde.\n    Le déroulé de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants avec à boire et à manger\n    21h30 : Fin du meetup\n\n    L'évènement sera généreusement accueilli par Per Angusta dans leurs nouveaux locaux à Lyon/Villeurbanne, à côté du parc de la tête d'Or. Il sera sponsorisé par Per Angusta et Stimulus Components.\n\n    Dernière chose : L'évènement sera retransmis en direct sur les Internet, vous n'avez donc aucune excuse de ne pas y participer 🤣 Les informations vous seront transmises quelques jours avant.\n\n    Vous souhaitez présenter ou proposer un sujet à la communauté ? Contactez Jean-Michel ou Guillaume.\n\n    https://www.meetup.com/fr-FR/lyonrb/events/285961962/\n  talks:\n    - title: \"Performance Web, de quoi parle-t-on ?\"\n      raw_title: \"Performance Web, de quoi parle-t-on ? - Guillaume Briday - Lyon.rb\"\n      speakers:\n        - \"Guillaume Briday\"\n      event_name: \"Lyon.rb Meetup June 2022\"\n      published_at: \"2024-08-21\"\n      date: \"2022-04-14\"\n      description: |-\n        Guillaume Briday vous présente son talk intitulé : Performance Web, de quoi parle-t-on ?\n        On compare souvent les langages et frameworks entre eux. Mais de quoi parle-t-on quand on parle de performance Web ? Quel impact réel pour les utilisateurs ?\n\n        Meetup : 2022.1 / Post-Pandemic Ruby\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/lyonrb/events/285961962/\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-lyonrb-meetup-june-2022\"\n      video_id: \"zXYwNEk1ZvQ\"\n      language: \"french\"\n      thumbnail_xs: \"https://img.youtube.com/vi/zXYwNEk1ZvQ/default.jpg\"\n      thumbnail_sm: \"https://img.youtube.com/vi/zXYwNEk1ZvQ/mqdefault.jpg\"\n      thumbnail_md: \"https://img.youtube.com/vi/zXYwNEk1ZvQ/mqdefault.jpg\"\n      thumbnail_lg: \"https://img.youtube.com/vi/zXYwNEk1ZvQ/hqdefault.jpg\"\n      thumbnail_xl: \"https://img.youtube.com/vi/zXYwNEk1ZvQ/hqdefault.jpg\"\n\n    - title: \"Threads et Ractors : concurrence et parallélisme en Ruby\"\n      raw_title: \"Threads et Ractors : concurrence et parallélisme en Ruby - Gabriel Terrien - Lyon.rb\"\n      speakers:\n        - \"Gabriel Terrien\"\n      event_name: \"Lyon.rb Meetup June 2022\"\n      published_at: \"2022-06-26\"\n      date: \"2022-04-14\"\n      description: |-\n        Gabriel Terrien vous présente son talk intitulé : Threads et Ractors : concurrence et parallélisme en Ruby\n        Ruby 3 a diversifié la façon de lancer des tâches en parallèle. Cette première présentation abordera de manière simple et basique, en pure Ruby, ces abstractions désormais à notre disposition.\n\n        Meetup : 2022.1 / Post-Pandemic Ruby\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/lyonrb/events/285961962/\n      video_provider: \"youtube\"\n      id: \"gabriel-terrien-lyonrb-meetup-june-2022\"\n      video_id: \"AVIt2wSxNwM\"\n      language: \"french\"\n\n    - title: \"Postgres FDW FTW\"\n      raw_title: \"Postgres FDW FTW - Mehdi Lahmam - Lyon.rb\"\n      speakers:\n        - \"Mehdi Lahmam\"\n      event_name: \"Lyon.rb Meetup June 2022\"\n      published_at: \"2022-06-26\"\n      date: \"2022-04-14\"\n      description: |-\n        Mehdi Lahmam vous présente son talk intitulé : Postgres FDW FTW\n        Aviez-vous déjà eu envie de croiser des données de plusieurs bases de données PG différentes, voire une base de données et une feuille Excel de l'équipe marketing ou finance ? Découvrez les Foreign Data Wrapper de Postgres et comment vous pourriez fabriquer un data warehouse assez facilement sans sortir l'artillerie lourde.\n\n        Meetup : 2022.1 / Post-Pandemic Ruby\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/lyonrb/events/285961962/\n      video_provider: \"youtube\"\n      id: \"mehdi-lahmam-lyonrb-meetup-june-2022\"\n      video_id: \"IxaLhF3hcy0\"\n      language: \"french\"\n      thumbnail_xs: \"https://img.youtube.com/vi/IxaLhF3hcy0/default.jpg\"\n      thumbnail_sm: \"https://img.youtube.com/vi/IxaLhF3hcy0/mqdefault.jpg\"\n      thumbnail_md: \"https://img.youtube.com/vi/IxaLhF3hcy0/mqdefault.jpg\"\n      thumbnail_lg: \"https://img.youtube.com/vi/IxaLhF3hcy0/hqdefault.jpg\"\n      thumbnail_xl: \"https://img.youtube.com/vi/IxaLhF3hcy0/hqdefault.jpg\"\n\n- id: \"lyon-rb-meetup-march-2024\"\n  title: \"Lyon.rb Meetup March 2024\"\n  event_name: \"Lyon.rb Meetup March 2024\"\n  published_at: \"2024-10-17\"\n  date: \"2024-03-12\"\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-march-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/e/1/7/2/600_506277714.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/e/1/7/2/600_506277714.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/e/1/7/2/600_506277714.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/e/1/7/2/600_506277714.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/e/1/7/2/600_506277714.webp?w=750\"\n  description: |-\n    SpendHQ (anciennement Per Angusta) et Studio HB ont le plaisir de vous inviter à un nouveau meetup Lyon.RB !\n\n    Durant cet évènement vous aurez l'occasion d'assister à des présentations et rencontrer les membres de la communauté Ruby lyonnaise.\n\n    \"Rails: The One Person Framework.\", par Guillaume Briday (environ 45 minutes). Comment Rails 7 accompagné de Hotwire et Stimulus-components vous évite de tomber dans le piège de la sur-complexité sans compromis sur les performances et l'interactivité de vos apps, au contraire ! On reviendra sur le fonctionnement interne de Hotwire et on verra comment shipper de la valeur rapidement à vos utilisateurs quasiment sans effort, même en étant tout seul ! On détaillera également les différences avec les SPA en React ou Vue.js.\n    Le déroulé de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants avec à boire et à manger\n    21h30 : Fin du meetup\n    L'évènement sera généreusement accueilli par le Wagon Lyon, juste derrière l'hôtel de ville.\n\n    Il sera accompagné d'un buffet et de boisons pour profiter au mieux de la soirée !\n\n    Vous souhaitez présenter ou proposer un sujet à la communauté ? Contactez Jean-Michel ou Guillaume.\n\n    https://www.meetup.com/lyonrb/events/287815581/\n\n  talks:\n    - title: \"Why You Really Don't Need SPA with Hotwire\"\n      raw_title: \"Why You Really Don't Need SPA with Hotwire - Guillaume Briday - Lyon.rb Meetup 03/2024\"\n      speakers:\n        - \"Guillaume Briday\"\n      event_name: \"Lyon.rb Meetup March 2024\"\n      published_at: \"2024-10-17\"\n      date: \"2024-03-12\"\n      description: |-\n        ► Liens\n\n        Slides: https://why-you-really-dont-need-spa.guillaumebriday.fr/\n\n        Meetup Lyon.rb: https://www.meetup.com/lyonrb/events/287815581/\n\n        ► Mes réseaux sociaux\n\n        Instagram: https://www.instagram.com/guillaumebriday​\n        Twitter: https://www.twitter.com/guillaumebriday\n        GitHub: https://github.com/guillaumebriday\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-lyonrb-meetup-march-2024\"\n      video_id: \"JzxZSs161oU\"\n      language: \"french\"\n      slides_url: \"https://why-you-really-dont-need-spa.guillaumebriday.fr/\"\n\n- id: \"lyon-rb-meetup-july-2024\"\n  title: \"Lyon.rb Meetup July 2024\"\n  event_name: \"Lyon.rb Meetup July 2024\"\n  published_at: \"2024-08-29\"\n  date: \"2024-07-09\"\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-july-2024\"\n  language: \"french\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/c/f/4/1/600_521693057.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/c/f/4/1/600_521693057.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/c/f/4/1/600_521693057.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/c/f/4/1/600_521693057.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/c/f/4/1/600_521693057.webp?w=750\"\n  description: |-\n    SpendHQ (anciennement Per Angusta) et Studio HB ont le plaisir de vous inviter à un nouveau meetup Lyon.RB !\n\n    Le format change un peu cette fois ! On va essayer de faire des talks plus court mais avec plus de sujets !!\n\n    Durant cet évènement vous aurez l'occasion d'assister à des présentations et rencontrer les membres de la communauté Ruby lyonnaise.\n\n    * **\"TypeScript en Ruby? .rbs, Sorbet, quésaco?\"**, par Guillaume Briday (environ 15/20 minutes). Si vous utilisez JavaScript, vous connaissez sans doute le TypeScript, si vous utilisez PHP, vous avez vu beaucoup de nouveautés sur les types récemment, mais quid de Ruby ?! Voyons ensemble les nouveautés de Ruby 3 et que Stripe nous propose et comment s'en servir dans vos projets !\n    * **\"Les 12 facteurs dans une application SaaS\"**, par Geoffroy Dubruel (environ 20 minutes). En 2012, Heroku a défini les « Twelve Factor-App », 12 règles à suivre pour le développement d'applications modernes robustes et scalable. Mais quels avantages concrets apportent-elles à nos applications ? Dans cette présentation, nous allons challenger ces idées, rappeler les bonnes pratiques et questionner leur impact actuel.\n    * **\"C'est quoi une Content Security Policy (CSP) ?\"**, par Mathieu Eustachy (environ 20 minutes). XSS, clickjacking, data injection attacks ou encore packet sniffing : personne n'est à l'abri de ce genre d'attaque, surtout si vous n'avez pas de CSP sur votre application web. Heureusement, Rails nous facilite encore une fois la tâche ici !\n    Le déroulé de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants avec à boire et à manger\n    21h30 : Fin du meetup\n\n    L'évènement sera généreusement accueilli par le Wagon Lyon, juste derrière l'hôtel de ville.\n\n    Il sera accompagné d'un buffet et de boisons pour profiter au mieux de la soirée !\n\n    Vous souhaitez présenter ou proposer un sujet à la communauté ? Contactez Jean-Michel ou Guillaume.\n\n    https://www.meetup.com/lyonrb/events/301316102/\n\n  talks:\n    - title: \"TypeScript en Ruby 3 ? .rbs, Sorbet, quésaco?\"\n      raw_title: \"TypeScript en Ruby 3 ? .rbs, Sorbet, quésaco? - Guillaume Briday - Lyon.rb Meetup 07/2024\"\n      speakers:\n        - \"Guillaume Briday\"\n      event_name: \"Lyon.rb Meetup July 2024\"\n      published_at: \"2024-07-14\"\n      date: \"2024-07-09\"\n      description: |-\n        ► Liens\n\n        Slides: https://types-in-ruby.guillaumebriday.fr/\n        Meetup Lyon.rb: https://www.meetup.com/lyonrb/events/301316102/\n\n        ► Mes réseaux sociaux\n\n        Instagram : https://www.instagram.com/guillaumebriday​\n        Twitter  : https://www.twitter.com/guillaumebriday\n        GitHub: https://github.com/guillaumebriday\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-lyonrb-meetup-july-2024\"\n      video_id: \"c0i1YYGhJ-M\"\n      language: \"french\"\n      slides_url: \"https://types-in-ruby.guillaumebriday.fr/\"\n\n    - title: \"Les 12 facteurs dans une application SaaS\"\n      raw_title: \"Les 12 facteurs dans une application SaaS - Geoffroy Dubruel - Lyon.rb 2024.6\"\n      speakers:\n        - \"Geoffroy Dubruel\"\n      event_name: \"Lyon.rb Meetup July 2024\"\n      published_at: \"2024-08-28\"\n      date: \"2024-07-09\"\n      description: |-\n        En 2012, Heroku a défini les « Twelve Factor-App », 12 règles à suivre pour le développement d'applications modernes robustes et scalable. Mais quels avantages concrets apportent-elles à nos applications ? Dans cette présentation, nous allons challenger ces idées, rappeler les bonnes pratiques et questionner leur impact actuel.\n\n        Meetup : 2024.6 / Lightning talks\n        Lien vers l'évènement Meetup :https://www.meetup.com/lyonrb/events/301316102\n      video_provider: \"youtube\"\n      id: \"geoffroy-dubruel-lyonrb-meetup-july-2024\"\n      video_id: \"Iuwt_wntVrs\"\n      language: \"french\"\n\n    - title: \"C'est quoi une Content Security Policy (CSP) ?\"\n      raw_title: \"C'est quoi une Content Security Policy (CSP) ? - Mathieu Eustachy - Lyon.rb 2024.6\"\n      speakers:\n        - \"Mathieu Eustachy\"\n      event_name: \"Lyon.rb Meetup July 2024\"\n      published_at: \"2024-08-29\"\n      date: \"2024-07-09\"\n      description: |-\n        XSS, clickjacking, data injection attacks ou encore packet sniffing : personne n'est à l'abri de ce genre d'attaque, surtout si vous n'avez pas de CSP sur votre application web. Heureusement, Rails nous facilite encore une fois la tâche ici !\n\n        Meetup : 2024.6 / Lightning talks\n        Lien vers l'évènement Meetup :https://www.meetup.com/lyonrb/events/301316102\n      video_provider: \"youtube\"\n      id: \"mathieu-eustachy-lyonrb-meetup-july-2024\"\n      video_id: \"-XulJV-Bwss\"\n      language: \"french\"\n\n- id: \"lyon-rb-meetup-october-2024\"\n  title: \"Lyon.rb Meetup October 2024\"\n  event_name: \"Lyon.rb Meetup October 2024\"\n  published_at: \"2024-10-31\"\n  date: \"2024-10-29\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/5/3/d/3/600_524001459.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/5/3/d/3/600_524001459.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/5/3/d/3/600_524001459.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/5/3/d/3/600_524001459.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/5/3/d/3/600_524001459.webp?w=750\"\n  description: |-\n    SpendHQ (anciennement Per Angusta) et Studio HB ont le plaisir de vous inviter à un nouveau meetup Lyon.RB !\n\n    Nous allons reprendre le format utilisé la dernière fois avec des lightning talks, c'est-à-dire 2 ou 3 présentations de 20 à 25 minutes, puisque cela semblait vous avoir bien plu !\n\n    📢 Durant cet évènement vous aurez l'occasion d'assister à des présentations et rencontrer les membres de la communauté Ruby lyonnaise.\n\n    \"Kamal 2: Why and how you should leave the cloud?\", par Guillaume Briday (environ 20/25 minutes). Après plus d'un an sur Kamal, je vous ferai un retour d'expérience sur mon cloud exit avec ses avantages et inconvénients. Et pourquoi vous ne devriez plus avoir peur de déployer vos applications vous même !\n    \"Ruby, Rails et les dates\", par Goulven Champenois (environ 20/25 minutes). Trop vite ou trop lent, le temps passe, une seconde à la fois. Parfois pourtant, une seconde, une heure, ou une journée est ajoutée, et les logiciels craquent. Tour d'horizon des subtilités temporelles et des outils de Ruby et de Rails pour éviter les pièges.\n    \"À SpendHQ nous hébergons notre SaaS chez 3 fournisseurs PaaS différents : Heroku, Scalingo et GCP.\", par Jean-Michel Gigault (environ 20/25 minutes). À quels besoins cette architecture multi-cloud répond t-elle et comment est-elle opérée pour répondre aux besoins des grands comptes ?\n    🗓️ Le déroulé de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants avec à boire et à manger\n    21h30 : Fin du meetup\n    📍 L'évènement sera généreusement accueilli par le Wagon Lyon, juste derrière l'hôtel de ville.\n\n    🥗 🍕 Il sera accompagné d'un buffet et de boissons pour profiter au mieux de la soirée !\n\n    Vous souhaitez présenter ou proposer un sujet à la communauté ? Contactez Guillaume Briday ou Jean-Michel Gigault.\n\n    https://www.meetup.com/lyonrb/events/303824727\n\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-october-2024\"\n  language: \"french\"\n  talks:\n    - title: \"Kamal: Why and how you should leave the cloud?\"\n      raw_title: \"Kamal: Why and how you should leave the cloud? - Guillaume Briday - Lyon.rb Meetup 10/2024\"\n      speakers:\n        - \"Guillaume Briday\"\n      event_name: \"Lyon.rb Meetup October 2024\"\n      published_at: \"2024-10-30\"\n      date: \"2024-10-29\"\n      description: |-\n        ► Liens\n\n        Slides: https://kamal-2-why-and-how-you-should-leave-the-cloud.guillaumebriday.fr/\n        Meetup Lyon.rb: https://www.meetup.com/lyonrb/events/303824727\n\n        ► Mes réseaux sociaux\n\n        Instagram : https://www.instagram.com/guillaumebriday​\n        Twitter  : https://www.twitter.com/guillaumebriday\n        GitHub: https://github.com/guillaumebriday\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-lyonrb-meetup-october-2024\"\n      video_id: \"mYXfPPlVwpQ\"\n      language: \"french\"\n      slides_url: \"https://kamal-2-why-and-how-you-should-leave-the-cloud.guillaumebriday.fr/\"\n\n    - title: \"Pourquoi fait-on du multi-cloud Heroku, Scalingo et GCP ?\"\n      raw_title: \"Pourquoi fait-on du multi-cloud Heroku, Scalingo et GCP ? - Jean-Michel Gigault - Lyon.rb\"\n      speakers:\n        - \"Jean-Michel Gigault\"\n      event_name: \"Lyon.rb Meetup October 2024\"\n      published_at: \"2024-11-22\"\n      date: \"2024-10-29\"\n      description: |-\n        À SpendHQ nous hébergons notre SaaS chez 3 fournisseurs PaaS différents : Heroku, Scalingo et GCP. À quels besoins cette architecture multi-cloud répond-elle et comment est-elle opérée pour répondre aux besoins des grands comptes ?\n\n        Présenté par Jean-Michel Gigault.\n        Meetup : 2024.10 / The Spooky Rails Edition\n        Lien vers l'évènement Meetup : https://www.meetup.com/fr-FR/lyonrb/events/303824727\n      video_provider: \"youtube\"\n      id: \"jean-michel-gigault-lyonrb-meetup-october-2024\"\n      video_id: \"LZO6LiuMgWA\"\n      language: \"french\"\n\n    - title: \"Ruby, Rails et les dates\"\n      raw_title: \"Ruby, Rails et les dates - Goulven Champenois - Lyon.rb 2024.10\"\n      speakers:\n        - \"Goulven Champenois\"\n      event_name: \"Lyon.rb Meetup October 2024\"\n      published_at: \"2024-11-03\"\n      date: \"2024-10-29\"\n      description: |-\n        Trop vite ou trop lent, le temps passe, une seconde à la fois. Parfois pourtant, une seconde, une heure, ou une journée est ajoutée, et les logiciels craquent. Tour d'horizon des subtilités temporelles et des outils de Ruby et de Rails pour éviter les pièges.\n\n        Meetup : The Spooky Rails Edition 🎃 👻\n        Lien vers l'évènement Meetup : https://www.meetup.com/lyonrb/events/303824727\n        Lien vers les slides : https://speakerdeck.com/goulvench/ruby-rails-et-les-dates\n      video_provider: \"youtube\"\n      id: \"goulven-champenois-lyonrb-meetup-october-2024\"\n      video_id: \"-aEM7U1T8wI\"\n      language: \"french\"\n      slides_url: \"https://speakerdeck.com/goulvench/ruby-rails-et-les-dates\"\n\n- id: \"Lyon-rb-Meetup-november-2024\"\n  title: \"Lyon.rb Meetup November 2024\"\n  event_name: \"Lyon.rb Meetup November 2024\"\n  published_at: \"2024-10-31\"\n  date: \"2024-11-26\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/8/7/4/8/600_524554632.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/8/7/4/8/600_524554632.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/8/7/4/8/600_524554632.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/8/7/4/8/600_524554632.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/8/7/4/8/600_524554632.webp?w=750\"\n  description: |-\n    SpendHQ (anciennement Per Angusta) et Studio HB ont le plaisir de vous inviter à un nouveau meetup Lyon.RB !\n\n    Date: Tuesday, November 26, 2024\n    Time: 6:30 PM to 9:30 PM CET\n    Location: Le Wagon Lyon, 20 Rue des Capucins, Lyon\n\n    Nous allons reprendre le format utilisé la dernière fois avec des lightning talks, c'est-à-dire 2 ou 3 présentations de 20 à 25 minutes, puisque cela semblait vous avoir bien plu !\n\n    📢 Durant cet évènement vous aurez l'occasion d'assister à des présentations et rencontrer les membres de la communauté Ruby lyonnaise.\n\n    \"TDD : Quand et pourquoi l'utiliser vraiment ?\", par Geoffroy Dubruel (environ 20/25 minutes). Le Test Driven Development est souvent présenté comme une méthode incontournable, mais est-il toujours pertinent ? Je vous propose un retour aux bases pour mieux comprendre quand il est vraiment utile, et comment l'adopter efficacement dans vos projets Rails.\n    \"In app Styleguide, une autre vision de la 'source unique de vérité' pour le design\", par Pierre-Alexandre Pierulli (environ 5/10 minutes). Que ce soit l'app d'un personne ou une app qui existe depuis 10ans. Savoir entre les capture d'écran, les fichiers photoshop ou figma quelle est la bonne version du design, voila qui pose parfois bien des souci. Notamment lorsque certain composant sont visible uniquement sous certaine condition particulière.\n    Les styleguide inapp ou parfois appellé (interactive styleguide), sont une solution à cela. Après avoir implémenté cela sous plus de 5 projets je vous propose une petite introduction au concept. Avec avantage inconvénients. De quoi bien discuté par la suite.\n\n    🗓️ Le déroulé de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants avec à boire et à manger\n    21h30 : Fin du meetup\n    📍 L'évènement sera généreusement accueilli par le Wagon Lyon, 20 Rue des Capucins, Lyon.\n\n    🥗 🍕 Il sera accompagné d'un buffet et de boissons pour profiter au mieux de la soirée !\n\n    Sponsors: SpendHQ (formerly Per Angusta) and Studio HB\n    Hosts: Jean-Michel Gigault and Guillaume Briday\n\n    https://www.meetup.com/lyonrb/events/304303057/\n\n  video_provider: \"children\"\n  video_id: \"Lyon-rb-Meetup-november-2024\"\n  language: \"french\"\n  talks:\n    - title: \"TDD : Quand et pourquoi l'utiliser vraiment ?\"\n      raw_title: \"TDD : Quand et pourquoi l'utiliser vraiment ? - Geoffroy Dubruel - Lyon.rb\"\n      speakers:\n        - \"Geoffroy Dubruel\"\n      event_name: \"Lyon.rb Meetup November 2024\"\n      published_at: \"2024-12-01\"\n      date: \"2024-11-26\"\n      description: |-\n        Geoffroy Dubruel vous présente son talk intitulé : TDD : Quand et pourquoi l'utiliser vraiment ?\n\n        Meetup : 2024.11 / The Pumpkin-Spiced Edition 🎃 🍁\n        Lien vers l'évènement Meetup : https://www.meetup.com/lyonrb/events/304303057\n\n        00:00 Présentation\n        21:30 Questions/Réponses\n      video_provider: \"youtube\"\n      id: \"geoffroy-dubruel-lyonrb-meetup-november-2024\"\n      video_id: \"DP5kcRih5Ro\"\n      language: \"french\"\n\n    - title: \"In app Styleguide, une autre vision de la 'source unique de vérité' pour le design\"\n      raw_title: \"In app Styleguide, une autre vision de la 'source unique de vérité' pour le design - Pierre-Alexandre Pierulli - Lyon.rb\"\n      speakers:\n        - \"Pierre-Alexandre Pierulli\"\n      event_name: \"Lyon.rb Meetup November 2024\"\n      date: \"2024-11-26\"\n      description: |-\n        Pierre-Alexandre Pierulli vous présente son talk intitulé : In app Styleguide, une autre vision de la 'source unique de vérité' pour le design\n\n        Que ce soit l'app d'un personne ou une app qui existe depuis 10ans. Savoir entre les capture d'écran, les fichiers photoshop ou figma quelle est la bonne version du design, voila qui pose parfois bien des souci. Notamment lorsque certain composant sont visible uniquement sous certaine condition particulière.\n        Les styleguide inapp ou parfois appellé (interactive styleguide), sont une solution à cela. Après avoir implémenté cela sous plus de 5 projets je vous propose une petite introduction au concept. Avec avantage inconvénients.\n\n        Meetup : 2024.11 / The Pumpkin-Spiced Edition 🎃 🍁\n        Lien vers l'évènement Meetup : https://www.meetup.com/lyonrb/events/304303057\n      video_provider: \"scheduled\"\n      id: \"pierre-alexandre-pierulli-lyon-rb-november-2024\"\n      video_id: \"pierre-alexandre-pierulli-lyon-rb-november-2024\"\n      language: \"french\"\n\n- title: \"Lyon.rb Meetup February 2025\"\n  raw_title: \"Lyon.rb Meetup February 2025\"\n  event_name: \"Lyon.rb Meetup February 2025\"\n  date: \"2025-02-25\"\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-february-2025\"\n  id: \"lyon-rb-meetup-february-2025\"\n  language: \"french\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/c/0/6/a/highres_526069258.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/c/0/6/a/highres_526069258.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/c/0/6/a/highres_526069258.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/c/0/6/a/highres_526069258.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/c/0/6/a/highres_526069258.webp?w=750\"\n  description: |-\n    SpendHQ (anciennement Per Angusta) et Studio HB ont le plaisir de vous inviter à un nouveau meetup Lyon.RB !\n\n    Date: Tuesday, February 25, 2025\n    Time: 6:30 PM to 9:30 PM CET\n    Location: Le Wagon Lyon, 20 Rue des Capucins, Lyon\n\n    Lightning talk format avec des présentations de 20 à 25 minutes.\n\n    📢 Durant cet évènement vous aurez l'occasion d'assister à des présentations et rencontrer les membres de la communauté Ruby lyonnaise.\n\n    \"Reprise de projet Rails : Défis et bonnes pratiques\", par Laurent Buffevant\n    \"Lost in History: Debugging with git bisect\", par Carmen Alvarez\n    \"Réflexions sur les jobs asynchrones\", par Thibault Villard\n\n    🗓️ Le déroulé de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants avec à boire et à manger\n    21h30 : Fin du meetup\n    📍 L'évènement sera généreusement accueilli par le Wagon Lyon, 20 Rue des Capucins, Lyon.\n\n    🥗 🍕 Il sera accompagné d'un buffet et de boissons pour profiter au mieux de la soirée !\n\n    Sponsors: SpendHQ (formerly Per Angusta) and Studio HB\n    Hosts: Jean-Michel Gigault and Guillaume Briday\n\n    https://www.meetup.com/lyonrb/events/305971307/\n  talks:\n    - title: \"Reprise de projet Rails : Défis et bonnes pratiques\"\n      raw_title: \"Reprise de projet Rails : Défis et bonnes pratiques - Laurent Buffevant - Lyon.rb\"\n      speakers:\n        - \"Laurent Buffevant\"\n      event_name: \"Lyon.rb Meetup February 2025\"\n      date: \"2025-02-25\"\n      video_provider: \"scheduled\"\n      video_id: \"laurent-buffevant-lyon-rb-february-2025\"\n      id: \"laurent-buffevant-lyon-rb-february-2025\"\n      language: \"french\"\n\n    - title: \"Lost in History: Debugging with git bisect\"\n      raw_title: \"Lost in History: Debugging with git bisect - Carmen Alvarez - Lyon.rb\"\n      speakers:\n        - \"Carmen Alvarez\"\n      event_name: \"Lyon.rb Meetup February 2025\"\n      date: \"2025-02-25\"\n      video_provider: \"scheduled\"\n      video_id: \"carmen-alvarez-lyon-rb-february-2025\"\n      id: \"carmen-alvarez-lyon-rb-february-2025\"\n      language: \"french\"\n\n    - title: \"Réflexions sur les jobs asynchrones\"\n      raw_title: \"Réflexions sur les jobs asynchrones - Thibault Villard - Lyon.rb\"\n      speakers:\n        - \"Thibault Villard\"\n      event_name: \"Lyon.rb Meetup February 2025\"\n      date: \"2025-02-25\"\n      video_provider: \"scheduled\"\n      video_id: \"thibault-villard-lyon-rb-february-2025\"\n      id: \"thibault-villard-lyon-rb-february-2025\"\n      language: \"french\"\n\n- title: \"Lyon.rb Meetup June 2025\"\n  raw_title: \"Lyon.rb Meetup June 2025\"\n  event_name: \"Lyon.rb Meetup June 2025\"\n  date: \"2025-06-17\"\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-june-2025\"\n  id: \"lyon-rb-meetup-june-2025\"\n  language: \"french\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/e/3/9/8/highres_482638264.jpeg?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/e/3/9/8/highres_482638264.jpeg?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/e/3/9/8/highres_482638264.jpeg?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/e/3/9/8/highres_482638264.jpeg?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/e/3/9/8/highres_482638264.jpeg?w=750\"\n  description: |-\n    SpendHQ (anciennement Per Angusta) et Studio HB ont le plaisir de vous inviter à un nouveau meetup Lyon.RB !\n\n    Date: Tuesday, June 17, 2025\n    Time: 6:30 PM to 9:30 PM CEST\n    Location: Le Wagon Lyon, 20 Rue des Capucins, Lyon\n\n    Lightning talk format avec des présentations de 20 à 25 minutes.\n\n    📢 Durant cet évènement vous aurez l'occasion d'assister à des présentations et rencontrer les membres de la communauté Ruby lyonnaise.\n\n    \"Smarter Rails apps with AI, how to use LLM in real life\", par Guillaume Briday - Focus on bringing practical AI value to Rails applications and demonstrating LLM deployment with Kamal\n    \"Possible to measure developer productivity?\", par Mehdi - Exploring holistic approaches to evaluating developer contributions and analyzing traditional metrics and collaborative development assessment\n\n    🗓️ Le déroulé de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants avec à boire et à manger\n    21h30 : Fin du meetup\n    📍 L'évènement sera généreusement accueilli par le Wagon Lyon, 20 Rue des Capucins, Lyon.\n\n    🥗 🍕 Il sera accompagné d'un buffet et de boissons pour profiter au mieux de la soirée !\n\n    Sponsors: SpendHQ (formerly Per Angusta) and Studio HB\n    Contact for Presentations: Guillaume Briday (guillaumebriday@gmail.com), Jean-Michel Gigault (jean-michel@spendhq.com)\n\n    https://www.meetup.com/lyonrb/events/307419621/\n  talks:\n    - title: \"Smarter Rails apps with AI, how to use LLM in real life\"\n      raw_title: \"Smarter Rails apps with AI, how to use LLM in real life - Lyon.rb Meetup - 06/2025\"\n      speakers:\n        - \"Guillaume Briday\"\n      event_name: \"Lyon.rb Meetup June 2025\"\n      date: \"2025-06-17\"\n      published_at: \"2025-06-18\"\n      id: \"guillaume-briday-lyon-rb-june-2025\"\n      description: |-\n        Guillaume Briday vous présente son talk intitulé : Smarter Rails apps with AI, how to use LLM in real life\n\n        Focus on bringing practical AI value to Rails applications and demonstrating LLM deployment with Kamal.\n\n        Slides: https://smarter-rails-apps-with-ai-how-to-use-llm-in-real-life.guillaumebriday.fr/\n        Meetup Lyon.rb: https://www.meetup.com/lyonrb/events/307419621/\n\n        0:00 Talk\n        30:36 Questions\n      video_provider: \"youtube\"\n      video_id: \"DViNFIomFVk\"\n      language: \"french\"\n      slides_url: \"https://smarter-rails-apps-with-ai-how-to-use-llm-in-real-life.guillaumebriday.fr/\"\n\n    - title: \"Possible to measure developer productivity?\"\n      raw_title: \"Possible to measure developer productivity? - Mehdi - Lyon.rb\"\n      speakers:\n        - \"Mehdi Lahmam\"\n      event_name: \"Lyon.rb Meetup June 2025\"\n      date: \"2025-06-17\"\n      published_at: \"2025-06-18\"\n      id: \"mehdi-lahmam-lyon-rb-june-2025\"\n      description: |-\n        Mehdi vous présente son talk intitulé : Possible to measure developer productivity?\n\n        Exploring holistic approaches to evaluating developer contributions and analyzing traditional metrics and collaborative development assessment.\n\n        Meetup : https://www.meetup.com/lyonrb/events/307419621\n\n        00:00 Talk\n        19:00 Questions\n      video_provider: \"youtube\"\n      video_id: \"Nmq8yH4W7Tc\"\n      language: \"french\"\n\n- title: \"Lyon.rb Meetup September 2025\"\n  raw_title: \"Lyon.rb Meetup September 2025\"\n  event_name: \"Lyon.rb Meetup September 2025\"\n  date: \"2025-09-30\"\n  video_provider: \"children\"\n  video_id: \"lyon-rb-meetup-september-2025\"\n  id: \"lyon-rb-meetup-september-2025\"\n  language: \"french\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/c/d/5/1/highres_530212561.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/c/d/5/1/highres_530212561.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/c/d/5/1/highres_530212561.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/c/d/5/1/highres_530212561.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/c/d/5/1/highres_530212561.webp?w=750\"\n  description: |-\n    SpendHQ (anciennement Per Angusta) et Studio HB ont le plaisir de vous inviter à un nouveau meetup Lyon.RB !\n\n    Nous allons reprendre le format utilisé la dernière fois avec des lightning talks, c’est-à-dire 2 ou 3 présentations de 20 à 25 minutes, puisque cela semblait vous avoir bien plu !\n\n    📢 Durant cet évènement vous aurez l’occasion d’assister à des présentations et rencontrer les membres de la communauté Ruby lyonnaise.\n\n    \"Beyond Code: Becoming a Product Engineer\" Par Medhi Lahman. Et si le rôle du développeur ne se limitait pas à livrer des tickets ?\n    Ce talk invite les devs à adopter la posture de Product Engineer : un·e dev qui s’implique dans les décisions produit, challenge les specs, et maximise l’impact utilisateur. À travers des exemples concrets et des bonnes pratiques d’équipe, on verra comment contribuer à la discovery aussi bien qu’à la delivery, sans changer de métier, juste d'état d'esprit.\n\n    \"From Local to Global: Making Rails apps resilient\", Par Guillaume Briday. Aller en production, c’est simple. Y rester, c’est une autre histoire. À travers des exemples concrets, on verra ce qui fait une application résiliente et performante, où que vous soyez dans le monde.\n\n    \"Understanding Puma : The Low-Level Side of concurrency in Rails\", Par Geoffroy Dubruel. Plongeons dans les coulisses de Rails et de son serveur web Puma tout en suivant le parcours d’une requête et découvrons ensemble ce que sont les threads, processus et la concurrence. Un talk accessible, pensé pour démystifier les processus internes que l'on croise tous les jours dans nos applications.\n\n    🗓️ Le déroulé de la soirée :\n\n    18h30 : Début du meetup, faisons connaissance\n    19h00 : Présentations par les membres de la communauté Lyon.rb\n    20h00 : Débats et échanges entre participants avec à boire et à manger\n    21h30 : Fin du meetup\n    📍 L’évènement sera généreusement accueilli par le Wagon Lyon, juste derrière l'hôtel de ville.\n\n    🥗 🍕 Il sera accompagné d'un buffet et de boissons pour profiter au mieux de la soirée !\n\n    🎥 Retrouvez nos replays des précédentes éditions sur notre chaine YouTube:\n    https://www.youtube.com/playlist?list=PLWO0_50XhBj9zScZBHL_Dn13OrSJQ2lKt\n\n    Vous souhaitez présenter ou proposer un sujet à la communauté ? Contactez Guillaume Briday ([guillaumebriday@gmail.com](http://mailto:guillaumebriday@gmail.com/)) ou Jean-Michel Gigault ([jean-michel@spendhq.com](http://mailto:jean-michel@per-angusta.com/)).\n\n    https://www.meetup.com/lyonrb/events/310984224/\n  talks:\n    - title: \"Beyond Code: Becoming a Product Engineer\"\n      raw_title: \"Beyond Code: Becoming a Product Engineer - Mehdi Lahmam - Lyon.rb\"\n      speakers:\n        - Mehdi Lahmam\n      event_name: \"Lyon.rb Meetup September 2025\"\n      date: \"2025-09-30\"\n      video_provider: \"scheduled\"\n      video_id: \"mehdi-lahmam-lyon-rb-september-2025\"\n      id: \"mehdi-lahmam-lyon-rb-september-2025\"\n      language: \"french\"\n      description: |-\n        Et si le rôle du développeur ne se limitait pas à livrer des tickets ?\n        Ce talk invite les devs à adopter la posture de Product Engineer : un·e dev qui s'implique dans les décisions produit, challenge les specs, et maximise l'impact utilisateur. À travers des exemples concrets et des bonnes pratiques d'équipe, on verra comment contribuer à la discovery aussi bien qu'à la delivery, sans changer de métier, juste d'état d'esprit.\n\n    - title: \"Understanding Puma: The Low-Level Side of concurrency in Rails\"\n      raw_title: \"Understanding Puma: The Low-Level Side of concurrency in Rails - Geoffroy Dubruel - Lyon.rb\"\n      speakers:\n        - Geoffroy Dubruel\n      event_name: \"Lyon.rb Meetup September 2025\"\n      date: \"2025-09-30\"\n      video_provider: \"scheduled\"\n      video_id: \"geoffroy-dubruel-lyon-rb-september-2025\"\n      id: \"geoffroy-dubruel-lyon-rb-september-2025\"\n      language: \"french\"\n      description: |-\n        Plongeons dans les coulisses de Rails et de son serveur web Puma tout en suivant le parcours d'une requête et découvrons ensemble ce que sont les threads, processus et la concurrence. Un talk accessible, pensé pour démystifier les processus internes que l'on croise tous les jours dans nos applications.\n\n    - title: \"From Local to Global: Making Rails apps resilient\"\n      raw_title: \"From Local to Global: Making Rails apps resilient - Guillaume Briday - Lyon.rb\"\n      speakers:\n        - Guillaume Briday\n      event_name: \"Lyon.rb Meetup September 2025\"\n      date: \"2025-09-30\"\n      video_provider: \"scheduled\"\n      video_id: \"guillaume-briday-lyon-rb-september-2025\"\n      id: \"guillaume-briday-lyon-rb-september-2025\"\n      language: \"french\"\n      description: |-\n        Aller en production, c'est simple. Y rester, c'est une autre histoire. À travers des exemples concrets, on verra ce qui fait une application résiliente et performante, où que vous soyez dans le monde.\n"
  },
  {
    "path": "data/lyon-rb/series.yml",
    "content": "---\nname: \"Lyon.rb Meetup\"\nwebsite: \"https://www.meetup.com/LyonRB\"\ntwitter: \"lyonrb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"FR\"\nyoutube_channel_name: \"Lyonrb\"\nlanguage: \"french\"\nyoutube_channel_id: \"UCFqRbkEEaM4w1iEK1ovBXxg\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2011/event.yml",
    "content": "---\nid: \"madison-ruby-2011\"\ntitle: \"Madison+ Ruby 2011\"\ndescription: |-\n  Discover a hidden gem in Madison, Wisconsin. A more than one track conference committed to bringing together two great communities.\nlocation: \"Madison, WI, United States\"\nvenue: \"Overture Center for the Arts\"\nkind: \"conference\"\nstart_date: \"2011-08-18\"\nend_date: \"2011-08-20\"\nwebsite: \"https://web.archive.org/web/20110903120722/http://madisonruby.org/\"\ntwitter: \"madisonruby\"\ncoordinates:\n  latitude: 43.0721661\n  longitude: -89.4007501\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2011/schedule.yml",
    "content": "# Schedule: https://web.archive.org/web/20110917055732/http://madisonruby.org/\n---\ndays:\n  - name: \"Workshops\"\n    date: \"2011-08-18\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"17:30\"\n        slots: 1\n\n  - name: \"Conference Day 1\"\n    date: \"2011-08-19\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Registration and Welcome\n\n      - start_time: \"09:15\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening Keynote\n\n      - start_time: \"10:00\"\n        end_time: \"10:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:15\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:15\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:00\"\n        end_time: \"13:45\"\n        slots: 1\n\n      - start_time: \"13:45\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:00\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"15:45\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 1\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Closing Remarks\n\n  - name: \"Conference Day 2\"\n    date: \"2011-08-20\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Registration and Welcome\n\n      - start_time: \"09:15\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening Keynote\n\n      - start_time: \"10:00\"\n        end_time: \"10:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:15\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:15\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:00\"\n        end_time: \"13:45\"\n        slots: 1\n\n      - start_time: \"13:45\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:00\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"15:45\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 1\n        items:\n          - Closing Keynote\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Conference Closing\n\n      - start_time: \"19:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Killer After Party at Museum of Contemporary Art\n\ntracks: []\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2011/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Getty Images\"\n          website: \"https://www.gettyimages.com/\"\n          slug: \"getty-images\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_getty_images.png?1313849499\"\n\n        - name: \"Engine Yard\"\n          website: \"https://www.engineyard.com/\"\n          slug: \"engine-yard\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_engine-yard.png?1313849499\"\n\n    - name: \"Gold Sponsors\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Tropo\"\n          website: \"https://www.tropo.com/\"\n          slug: \"tropo\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_tropo.png?1313849499\"\n\n        - name: \"Brighter Planet\"\n          website: \"https://www.brighterplanet.com/\"\n          slug: \"brighter-planet\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_brighter_planet.png?1313849499\"\n\n        - name: \"Blue Box Group\"\n          website: \"https://www.bluebox.net/\"\n          slug: \"blue-box-group\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_blue_box_group.png?1313849499\"\n\n        - name: \"Relevance\"\n          website: \"https://www.thinkrelevance.com/\"\n          slug: \"relevance\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_relevance.png?1313849499\"\n\n    - name: \"Silver Sponsors\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"Harvest\"\n          website: \"https://www.getharvest.com/\"\n          slug: \"harvest\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_harvest.jpg?1313849499\"\n\n        - name: \"Bendyworks\"\n          website: \"https://www.bendyworks.com/\"\n          slug: \"bendyworks\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_bendyworks.png?1313849499\"\n\n        - name: \"New Relic\"\n          website: \"https://www.newrelic.com/\"\n          slug: \"new-relic\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_newrelic.png?1313849499\"\n\n        - name: \"Zencoder\"\n          website: \"https://www.zencoder.com/\"\n          slug: \"zencoder\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_zencoder.png?1313849499\"\n\n        - name: \"DNSimple\"\n          website: \"https://www.dnsimple.com/\"\n          slug: \"dnsimple\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_dnsimple.png?1313849499\"\n\n    - name: \"Bronze Sponsors\"\n      description: \"\"\n      level: 4\n      sponsors:\n        - name: \"O'Reilly\"\n          website: \"https://www.oreilly.com/\"\n          slug: \"oreilly\"\n          logo_url: \"\"\n\n        - name: \"PeepCode Screencasts\"\n          website: \"https://www.peepcode.com/\"\n          slug: \"peepcode-screencasts\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_peepcode.png?1313849499\"\n\n        - name: \"Sticker Mule\"\n          website: \"https://www.stickermule.com/\"\n          slug: \"sticker-mule\"\n          logo_url: \"https://web.archive.org/web/20111122074014im_/http://madisonruby.org/images/logo_stickermule.png?1313849499\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2011/videos.yml",
    "content": "# Schedule: https://web.archive.org/web/20110917055732/http://madisonruby.org/\n---\n## Workshops - August 18, 2011\n\n- id: \"scott-chacon-madison-ruby-2011\"\n  title: \"Workshop: Working Effectively with Git\"\n  speakers:\n    - Scott Chacon\n  description: |-\n    A workshop on working effectively with Git.\n  video_provider: \"not_recorded\"\n  video_id: \"scott-chacon-madison-ruby-2011\"\n  date: \"2011-08-18\"\n\n- id: \"desi-mcadam-madison-ruby-2011\"\n  title: \"Workshop: RailsBridge Women's Outreach\"\n  speakers:\n    - Desi McAdam\n  description: |-\n    A RailsBridge workshop focused on women's outreach in the Ruby community.\n  video_provider: \"not_recorded\"\n  video_id: \"desi-mcadam-madison-ruby-2011\"\n  date: \"2011-08-18\"\n\n## Conference Day 1 - August 19, 2011\n\n- id: \"renee-de-voursney-madison-ruby-2011\"\n  title: \"Talk by Renee De Voursney\"\n  speakers:\n    - Renee De Voursney\n  description: |-\n    A talk by Renee De Voursney at Madison Ruby 2011.\n  video_provider: \"not_recorded\"\n  video_id: \"renee-de-voursney-madison-ruby-2011\"\n  date: \"2011-08-19\"\n\n- id: \"rick-bradley-madison-ruby-2011\"\n  title: \"Talk by Rick Bradley\"\n  speakers:\n    - Rick Bradley\n  description: |-\n    A talk by Rick Bradley at Madison Ruby 2011.\n  video_provider: \"not_recorded\"\n  video_id: \"rick-bradley-madison-ruby-2011\"\n  date: \"2011-08-19\"\n\n- id: \"rogelio-samour-madison-ruby-2011\"\n  title: \"Talk by Rogelio Samour\"\n  speakers:\n    - Rogelio Samour\n  description: |-\n    A talk by Rogelio Samour at Madison Ruby 2011.\n  video_provider: \"not_recorded\"\n  video_id: \"rogelio-samour-madison-ruby-2011\"\n  date: \"2011-08-19\"\n\n- id: \"matt-yoho-madison-ruby-2011\"\n  title: \"Talk by Matt Yoho\"\n  speakers:\n    - Matt Yoho\n  description: |-\n    A talk by Matt Yoho at Madison Ruby 2011.\n  video_provider: \"not_recorded\"\n  video_id: \"matt-yoho-madison-ruby-2011\"\n  date: \"2011-08-19\"\n\n- id: \"bryan-liles-madison-ruby-2011\"\n  title: \"Talk by Bryan Liles\"\n  speakers:\n    - Bryan Liles\n  description: |-\n    A talk by Bryan Liles at Madison Ruby 2011.\n  video_provider: \"not_recorded\"\n  video_id: \"bryan-liles-madison-ruby-2011\"\n  date: \"2011-08-19\"\n\n- id: \"scott-parker-madison-ruby-2011\"\n  title: \"Talk by Scott Parker\"\n  speakers:\n    - Scott Parker\n  description: |-\n    A talk by Scott Parker at Madison Ruby 2011.\n  video_provider: \"not_recorded\"\n  video_id: \"scott-parker-madison-ruby-2011\"\n  date: \"2011-08-19\"\n\n## Conference Day 2 - August 20, 2011\n\n- id: \"lori-olson-madison-ruby-2011\"\n  title: \"Talk by Lori Olson\"\n  speakers:\n    - Lori M Olson\n  description: |-\n    A talk by Lori Olson at Madison Ruby 2011.\n  video_provider: \"not_recorded\"\n  video_id: \"lori-olson-madison-ruby-2011\"\n  date: \"2011-08-20\"\n\n- id: \"barry-hess-madison-ruby-2011\"\n  title: \"Talk by Barry Hess\"\n  speakers:\n    - Barry Hess\n  description: |-\n    A talk by Barry Hess at Madison Ruby 2011.\n  video_provider: \"not_recorded\"\n  video_id: \"barry-hess-madison-ruby-2011\"\n  date: \"2011-08-20\"\n\n- id: \"giles-bowkett-madison-ruby-2011\"\n  title: \"Talk by Giles Bowkett\"\n  speakers:\n    - Giles Bowkett\n  description: |-\n    A talk by Giles Bowkett at Madison Ruby 2011.\n  video_provider: \"not_recorded\"\n  video_id: \"giles-bowkett-madison-ruby-2011\"\n  date: \"2011-08-20\"\n\n- id: \"sven-fuchs-madison-ruby-2011\"\n  title: \"Talk by Sven Fuchs\"\n  speakers:\n    - Sven Fuchs\n  description: |-\n    A talk by Sven Fuchs at Madison Ruby 2011.\n  video_provider: \"not_recorded\"\n  video_id: \"sven-fuchs-madison-ruby-2011\"\n  date: \"2011-08-20\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2012/event.yml",
    "content": "---\nid: \"madison-ruby-2012\"\ntitle: \"Madison+ Ruby 2012\"\ndescription: \"\"\nlocation: \"Madison, WI, United States\"\nkind: \"conference\"\nstart_date: \"2012-08-24\"\nend_date: \"2012-08-25\"\nwebsite: \"https://web.archive.org/web/20120702083720/http://madisonruby.org/\"\ntwitter: \"madisonruby\"\ncoordinates:\n  latitude: 43.0721661\n  longitude: -89.4007501\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2012/schedule.yml",
    "content": "# Schedule: https://web.archive.org/web/20120615230121/http://madisonruby2012.sched.org/\n---\ndays:\n  - name: \"Workshops\"\n    date: \"2012-08-23\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"08:30\"\n        slots: 1\n        items:\n          - Registration and Coffee Social\n\n      - start_time: \"09:00\"\n        end_time: \"12:00\"\n        slots: 4\n\n      - start_time: \"12:00\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:00\"\n        end_time: \"17:00\"\n        slots: 4\n        items:\n          - Workshop continues\n          - Workshop continues\n          - Workshop continues\n          - Workshop continues\n\n      - start_time: \"17:00\"\n        end_time: \"18:30\"\n        slots: 1\n        items:\n          - Terrace Reception\n\n      - start_time: \"18:30\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - Dinner - On Your Own\n\n  - name: \"Conference Day 1\"\n    date: \"2012-08-24\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration and Coffee Social\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Welcome Address\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Playnote - Improv Kickoff\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"10:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:50\"\n        end_time: \"11:20\"\n        slots: 1\n\n      - start_time: \"11:20\"\n        end_time: \"11:50\"\n        slots: 1\n        items:\n          - TBA\n\n      - start_time: \"11:50\"\n        end_time: \"13:20\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:20\"\n        end_time: \"13:50\"\n        slots: 1\n\n      - start_time: \"13:50\"\n        end_time: \"14:20\"\n        slots: 1\n\n      - start_time: \"14:20\"\n        end_time: \"14:40\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 1\n\n      - start_time: \"15:40\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 1\n        items:\n          - Lightning Talk\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"17:00\"\n        end_time: \"17:45\"\n        slots: 1\n        items:\n          - Local Flavor\n\n      - start_time: \"17:45\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - End of Day Announcements\n\n      - start_time: \"18:00\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - Dinner - On Your Own\n\n      - start_time: \"20:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - After Party\n\n  - name: \"Conference Day 2\"\n    date: \"2012-08-25\"\n    grid:\n      - start_time: \"06:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Farmer's Market\n\n      - start_time: \"09:30\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Coffee Social\n\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Morning Announcements\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"10:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:50\"\n        end_time: \"11:20\"\n        slots: 1\n\n      - start_time: \"11:20\"\n        end_time: \"11:50\"\n        slots: 1\n\n      - start_time: \"11:50\"\n        end_time: \"13:20\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:20\"\n        end_time: \"13:50\"\n        slots: 1\n\n      - start_time: \"13:50\"\n        end_time: \"14:20\"\n        slots: 1\n\n      - start_time: \"14:20\"\n        end_time: \"14:40\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 1\n\n      - start_time: \"15:40\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"17:15\"\n        end_time: \"17:45\"\n        slots: 1\n\n      - start_time: \"17:45\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - Closing Address\n\n      - start_time: \"18:00\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - Dinner - On Your Own\n\n      - start_time: \"20:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Whisky Tasting\n\ntracks: []\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2012/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Getty Images\"\n          website: \"https://www.gettyimages.com/\"\n          slug: \"getty-images\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_getty_images.png\"\n\n        - name: \"Engine Yard\"\n          website: \"https://www.engineyard.com/\"\n          slug: \"engine-yard\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_engine-yard.png\"\n\n        - name: \"Enova\"\n          website: \"https://www.enova.com/\"\n          slug: \"enova\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_enova.png\"\n\n        - name: \"Blue Box Group\"\n          website: \"https://www.bluebox.net/\"\n          slug: \"blue-box-group\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_blue_box_group.jpg\"\n\n        - name: \"Madison College\"\n          website: \"https://matcmadison.edu/\"\n          slug: \"madison-college\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_madison_college.png\"\n\n        - name: \"Groupon\"\n          website: \"https://www.engineering.groupon.com/\"\n          slug: \"groupon\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_groupon.png\"\n\n        - name: \"Bendyworks\"\n          website: \"https://www.bendyworks.com/\"\n          slug: \"bendyworks\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_bendyworks.png\"\n\n        - name: \"New Relic\"\n          website: \"https://www.newrelic.com/\"\n          slug: \"new-relic\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_newrelic.png\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"dnsimple\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_dnsimple.png\"\n\n        - name: \"Less Films\"\n          website: \"https://www.lessfilms.com/\"\n          slug: \"less-films\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_lessfilms.png\"\n\n        - name: \"Flatt Cola\"\n          website: \"https://www.flattcola.com/\"\n          slug: \"flatt-cola\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_flatt_cola.png\"\n\n        - name: \"Orange Tree Imports\"\n          website: \"https://www.orangetreeimports.com/\"\n          slug: \"orange-tree-imports\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_orangetree.png\"\n\n        - name: \"Sticker Mule\"\n          website: \"https://www.stickermule.com/\"\n          slug: \"sticker-mule\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_stickermule.png\"\n\n        - name: \"O'Reilly\"\n          website: \"https://www.oreilly.com/\"\n          slug: \"oreilly\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_oreilly.png\"\n\n        - name: \"PeepCode Screencasts\"\n          website: \"https://www.peepcode.com/\"\n          slug: \"peepcode-screencasts\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_peepcode.png\"\n\n        - name: \"Smart Solutions\"\n          website: \"https://www.smart-solutions.com/\"\n          slug: \"smart-solutions\"\n          logo_url: \"https://web.archive.org/web/20120626181147im_/http://madisonruby.org/images/logo_smart_solutions.png\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2012/videos.yml",
    "content": "# Schedule: https://web.archive.org/web/20120615230121/http://madisonruby2012.sched.org/\n---\n## Workshops - August 23, 2012\n\n- id: \"adam-stacoviak-wynn-netherland-madison-ruby-2012\"\n  title: \"Workshop: Design Eye for the Dev Guy or Gal\"\n  speakers:\n    - Adam Stacoviak\n    - Wynn Netherland\n  description: |-\n    A workshop on design principles for developers.\n  video_provider: \"not_recorded\"\n  video_id: \"adam-stacoviak-wynn-netherland-madison-ruby-2012\"\n  date: \"2012-08-23\"\n\n- id: \"jeff-casimir-madison-ruby-2012\"\n  title: \"Workshop: RubyJumpstart\"\n  speakers:\n    - Jeff Casimir\n  description: |-\n    A RubyJumpstart workshop by JumpstartLab.\n  video_provider: \"not_recorded\"\n  video_id: \"jeff-casimir-madison-ruby-2012\"\n  date: \"2012-08-23\"\n\n- id: \"matthew-mccullough-madison-ruby-2012\"\n  title: \"Workshop: Understanding Git\"\n  speakers:\n    - Matthew McCullough\n  description: |-\n    A workshop on understanding Git by Matthew McCullough of GitHub.\n  video_provider: \"not_recorded\"\n  video_id: \"matthew-mccullough-madison-ruby-2012\"\n  date: \"2012-08-23\"\n\n- id: \"desi-mcadam-madison-ruby-2012\"\n  title: \"Workshop: RailsBridge\"\n  speakers:\n    - Desi McAdam\n  description: |-\n    A RailsBridge workshop for women's outreach in the Ruby community.\n  video_provider: \"not_recorded\"\n  video_id: \"desi-mcadam-madison-ruby-2012\"\n  date: \"2012-08-23\"\n\n## Conference Day 1 - August 24, 2012\n\n- id: \"simulating-the-world-with-ruby-madison-ruby-2012\"\n  title: \"Simulating the World with Ruby\"\n  speakers:\n    - TODO\n  description: |-\n    A talk about simulating the world with Ruby.\n  video_provider: \"not_recorded\"\n  video_id: \"simulating-the-world-with-ruby-madison-ruby-2012\"\n  date: \"2012-08-24\"\n\n- id: \"anti-oppression-101-madison-ruby-2012\"\n  title: \"Anti-Oppression 101\"\n  speakers:\n    - TODO\n  description: |-\n    A talk on anti-oppression principles and practices.\n  video_provider: \"not_recorded\"\n  video_id: \"anti-oppression-101-madison-ruby-2012\"\n  date: \"2012-08-24\"\n\n- id: \"gonzo-madison-ruby-2012\"\n  title: \"Gonzo - Exploration of Culture, Innovation and the Weird in Software\"\n  speakers:\n    - TODO\n  description: |-\n    An exploration of culture, innovation and the weird in software.\n  video_provider: \"not_recorded\"\n  video_id: \"gonzo-madison-ruby-2012\"\n  date: \"2012-08-24\"\n\n- id: \"how-to-contribute-to-open-source-madison-ruby-2012\"\n  title: \"How to Contribute to Open Source: Extensibility from Simplicity\"\n  speakers:\n    - TODO\n  description: |-\n    A talk on contributing to open source through extensibility from simplicity.\n  video_provider: \"not_recorded\"\n  video_id: \"how-to-contribute-to-open-source-madison-ruby-2012\"\n  date: \"2012-08-24\"\n\n- id: \"behind-the-curtain-madison-ruby-2012\"\n  title: \"Behind the Curtain: Applying lessons learned from years in the Theatre to crafting software applications\"\n  speakers:\n    - TODO\n  description: |-\n    Applying lessons learned from years in the theatre to crafting software applications.\n  video_provider: \"not_recorded\"\n  video_id: \"behind-the-curtain-madison-ruby-2012\"\n  date: \"2012-08-24\"\n\n- id: \"integrating-hadoop-batch-data-processing-madison-ruby-2012\"\n  title: \"Integrating Hadoop Batch Data Processing into your App\"\n  speakers:\n    - TODO\n  description: |-\n    A talk on integrating Hadoop batch data processing into your application.\n  video_provider: \"not_recorded\"\n  video_id: \"integrating-hadoop-batch-data-processing-madison-ruby-2012\"\n  date: \"2012-08-24\"\n\n## Conference Day 2 - August 25, 2012\n\n- id: \"revenge-of-method-missing-madison-ruby-2012\"\n  title: \"The Revenge of method_missing()\"\n  speakers:\n    - TODO\n  description: |-\n    A talk about the power and pitfalls of Ruby's method_missing.\n  video_provider: \"not_recorded\"\n  video_id: \"revenge-of-method-missing-madison-ruby-2012\"\n  date: \"2012-08-25\"\n\n- id: \"sand-piles-and-software-madison-ruby-2012\"\n  title: \"Sand Piles and Software\"\n  speakers:\n    - TODO\n  description: |-\n    A talk exploring the parallels between sand piles and software systems.\n  video_provider: \"not_recorded\"\n  video_id: \"sand-piles-and-software-madison-ruby-2012\"\n  date: \"2012-08-25\"\n\n- id: \"async-everything-madison-ruby-2012\"\n  title: \"Async Everything\"\n  speakers:\n    - TODO\n  description: |-\n    A talk on asynchronous programming patterns and techniques.\n  video_provider: \"not_recorded\"\n  video_id: \"async-everything-madison-ruby-2012\"\n  date: \"2012-08-25\"\n\n- id: \"enterprise-strikes-back-madison-ruby-2012\"\n  title: \"The Enterprise Strikes Back: Using Rails to compete with startups\"\n  speakers:\n    - TODO\n  description: |-\n    How enterprises can use Rails to compete with startups.\n  video_provider: \"not_recorded\"\n  video_id: \"enterprise-strikes-back-madison-ruby-2012\"\n  date: \"2012-08-25\"\n\n- id: \"making-a-difference-madison-ruby-2012\"\n  title: \"Making a difference, right off the bat!\"\n  speakers:\n    - TODO\n  description: |-\n    A talk on making an impact in software development from the start.\n  video_provider: \"not_recorded\"\n  video_id: \"making-a-difference-madison-ruby-2012\"\n  date: \"2012-08-25\"\n\n- id: \"modular-reusable-frontend-code-madison-ruby-2012\"\n  title: \"Modular & reusable front-end code with HTML5, Sass and CoffeeScript\"\n  speakers:\n    - TODO\n  description: |-\n    Building modular and reusable front-end code with HTML5, Sass, and CoffeeScript.\n  video_provider: \"not_recorded\"\n  video_id: \"modular-reusable-frontend-code-madison-ruby-2012\"\n  date: \"2012-08-25\"\n\n- id: \"building-the-web-for-everyone-madison-ruby-2012\"\n  title: \"Building the web for everyone\"\n  speakers:\n    - TODO\n  description: |-\n    A talk on building accessible and inclusive web applications.\n  video_provider: \"not_recorded\"\n  video_id: \"building-the-web-for-everyone-madison-ruby-2012\"\n  date: \"2012-08-25\"\n\n- id: \"teaching-rails-panel-madison-ruby-2012\"\n  title: \"Teaching Rails Panel\"\n  speakers:\n    - TODO\n  description: |-\n    A panel discussion on teaching Rails.\n  video_provider: \"not_recorded\"\n  video_id: \"teaching-rails-panel-madison-ruby-2012\"\n  date: \"2012-08-25\"\n\n- id: \"your-user-the-animal-madison-ruby-2012\"\n  title: \"Your User: The Animal\"\n  speakers:\n    - TODO\n  description: |-\n    Understanding user behavior and psychology in software design.\n  video_provider: \"not_recorded\"\n  video_id: \"your-user-the-animal-madison-ruby-2012\"\n  date: \"2012-08-25\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZRH9W43CQaZy_9qkg6BjiI\"\ntitle: \"Madison+ Ruby 2013\"\ndescription: |-\n  Discover a hidden gem in Madison, Wisconsin\nlocation: \"Madison, WI, United States\"\nkind: \"conference\"\nstart_date: \"2013-08-23\"\nend_date: \"2013-08-24\"\nwebsite: \"https://web.archive.org/web/20130821043429/http://madisonruby.org/\"\nplaylist: \"https://www.youtube.com/playlist?list=PLE7tQUdRKcyZRH9W43CQaZy_9qkg6BjiI\"\ntwitter: \"madisonruby\"\ncoordinates:\n  latitude: 43.0721661\n  longitude: -89.4007501\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2013/schedule.yml",
    "content": "# Schedule: https://web.archive.org/web/20130820165943/http://madisonruby.org/schedule\n---\ndays:\n  - name: \"Wednesday, August 21, 2013\"\n    date: \"2013-08-21\"\n    grid:\n      - start_time: \"18:30\"\n        end_time: \"20:30\"\n        slots: 1\n\n  - name: \"Thursday, August 22, 2013\"\n    date: \"2013-08-22\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - \"Workshop Check In\"\n          - \"Coffee Service\"\n\n      - start_time: \"09:00\"\n        end_time: \"12:00\"\n        slots: 4\n\n      - start_time: \"12:00\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:00\"\n        end_time: \"17:00\"\n        slots: 4\n        items:\n          - Workshop continues\n          - Workshop continues\n          - Workshop continues\n          - Workshop continues\n\n      - start_time: \"19:00\"\n        end_time: \"21:00\"\n        slots: 1\n        items:\n          - \"Hype Harvest\"\n\n  - name: \"Friday, August 23, 2013\"\n    date: \"2013-08-23\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - \"Coffee Service\"\n          - \"Conference Check-In\"\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - \"Welcome Address with Robert Pitts and Big Tiger\"\n\n      - start_time: \"09:15\"\n        end_time: \"09:45\"\n        slots: 1\n\n      - start_time: \"09:45\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - \"Break\"\n          - \"Yoga with Lark Paulson\"\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - \"Lunch (Sponsored by Engine Yard)\"\n\n      - start_time: \"13:30\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:15\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n        items:\n          - \"Snack Break\"\n          - \"Yoga with Lark Paulson\"\n\n      - start_time: \"15:15\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - \"Snack Break\"\n\n      - start_time: \"17:00\"\n        end_time: \"17:45\"\n        slots: 1\n        items:\n          - \"Local Flavor with Andrew Wilson from The Madison Club and Danielle Lee from Madison Circus Space\"\n\n      - start_time: \"17:45\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - \"End of Day Remarks with Robert Pitts and Big Tiger\"\n\n      - start_time: \"18:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - \"Live on King Street (Sponsored by Bendyworks)\"\n          - \"Quiet & Cool Down Rooms (Sponsored by Bendyworks)\"\n\n      - start_time: \"19:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - \"Madison Ruby After Party at Live on King Street (Sponsored by Bendyworks)\"\n\n  - name: \"Saturday, August 24, 2013\"\n    date: \"2013-08-24\"\n    grid:\n      - start_time: \"06:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - \"Dane County Farmers' Market\"\n\n      - start_time: \"10:00\"\n        end_time: \"10:15\"\n        slots: 1\n        items:\n          - \"Start of Day Remarks with Robert Pitts and Big Tiger\"\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - \"Lunch (Sponsored by Engine Yard)\"\n\n      - start_time: \"13:30\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:15\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n        items:\n          - \"Yoga with Lark Paulson\"\n          - \"Snack Break\"\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - \"Snack Break\"\n\n      - start_time: \"17:00\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - \"Iron Coder with Robert Pitts\"\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - \"Closing Address with Robert Pitts and Big Tiger\"\n\n      - start_time: \"19:30\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - \"Trio Tasting: Cocktails, Cheese, & Chocolate\"\n\n  - name: \"Sunday, August 25, 2013\"\n    date: \"2013-08-25\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - \"Madison's KidsCodeCamp\"\n\ntracks: []\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2013/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Pluralsight\"\n          website: \"https://www.pluralsight.com/training\"\n          slug: \"pluralsight\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/pluralsightPNG.png\"\n\n        - name: \"AppSignal\"\n          website: \"https://appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/appsignalPNG.png\"\n\n        - name: \"Table XI\"\n          website: \"https://www.tablexi.com/\"\n          slug: \"table-xi\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/tablexiPNG.png\"\n\n        - name: \"Sticker Mule\"\n          website: \"https://www.stickermule.com/\"\n          slug: \"sticker-mule\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/stickermulepng.png\"\n\n        - name: \"DevMynd Software, Inc.\"\n          website: \"https://www.devmynd.com/\"\n          slug: \"devmynd-software-inc\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/DevMyndPNG.png\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"dnsimple\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/dnsimplePNG.png\"\n\n        - name: \"Code School\"\n          website: \"https://www.codeschool.com/\"\n          slug: \"code-school\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/CodeSchoolPNG.png\"\n\n        - name: \"Engine Yard\"\n          website: \"https://www.engineyard.com/\"\n          slug: \"engine-yard\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/EngineYardPNG.png\"\n\n        - name: \"O'Reilly Media\"\n          website: \"https://www.oreilly.com/\"\n          slug: \"oreilly-media\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/OReillyPNG.png\"\n\n        - name: \"GitHub\"\n          website: \"https://github.com/\"\n          slug: \"github\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/githubPNG.png\"\n\n        - name: \"Madison College\"\n          website: \"https://madisoncollege.edu/\"\n          slug: \"madison-college\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/sponsor_matc.png\"\n\n        - name: \"Instructure\"\n          website: \"https://instructure.com/\"\n          slug: \"instructure\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/canvas_byinstructurePNG.png\"\n\n        - name: \"Neo\"\n          website: \"https://www.neo.com/\"\n          slug: \"neo\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/neoPNG.png\"\n\n        - name: \"Enova\"\n          website: \"https://www.enova.com/\"\n          slug: \"enova\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/logo_enova.png\"\n\n        - name: \"Ian's Pizza\"\n          website: \"https://ianspizza.com/\"\n          slug: \"ians-pizza\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/IansPNG.png\"\n\n        - name: \"Intridea, Inc.\"\n          website: \"https://www.intridea.com/\"\n          slug: \"intridea-inc\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/intridea.png\"\n\n        - name: \"Nextpoint\"\n          website: \"https://www.nextpoint.com/\"\n          slug: \"nextpoint\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/nextpoint.png\"\n\n        - name: \"New Relic\"\n          website: \"https://newrelic.com/\"\n          slug: \"new-relic\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/newrelic_color_PNG.png\"\n\n        - name: \"Thunderbolt Labs\"\n          website: \"https://www.thunderboltlabs.com/\"\n          slug: \"thunderbolt-labs\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/tbl_blk_madruby.png\"\n\n        - name: \"Bendyworks\"\n          website: \"https://bendyworks.com/\"\n          slug: \"bendyworks\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/bendyworks.png\"\n\n        - name: \"Yahara Software\"\n          website: \"https://yaharasoftware.com/\"\n          slug: \"yahara-software\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/yahara.png\"\n\n        - name: \"Not Invented Here\"\n          website: \"https://notinventedhe.re/\"\n          slug: \"not-invented-here\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/nih_logo.png\"\n\n        - name: \"Gail Ambrosius Chocolatier\"\n          website: \"https://gailambrosius.com/\"\n          slug: \"gail-ambrosius-chocolatier\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/logo_gailambrosiusPNG.png\"\n\n        - name: \"Honeybadger.io\"\n          website: \"https://www.honeybadger.io/\"\n          slug: \"honeybadger-io\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/honeybadgerPNG.png\"\n\n        - name: \"Getty Images\"\n          website: \"https://www.gettyimages.com/\"\n          slug: \"getty-images\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/gettyPNG.png\"\n\n        - name: \"G5\"\n          website: \"https://www.getg5.com/\"\n          slug: \"g5\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/G5PNG.png\"\n\n        - name: \"Klarbrunn Vita ICE\"\n          website: \"https://www.klarbrunn.com/\"\n          slug: \"klarbrunn-vita-ice\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/kalrbrunnPNG.png\"\n\n        - name: \"Chariot Solutions\"\n          website: \"https://chariotsolutions.com/\"\n          slug: \"chariot-solutions\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/chariotsolutionsPNG.png\"\n\n        - name: \"Sapling Events\"\n          website: \"https://www.saplingevents.com/\"\n          slug: \"sapling-events\"\n          logo_url: \"https://web.archive.org/web/20130820154602im_/http://madisonruby.org/images/saplingeventsPNG.png\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2013/videos.yml",
    "content": "# Schedule: https://web.archive.org/web/20130820165943/http://madisonruby.org/schedule\n---\n## Workshops - August 22, 2013\n\n- id: \"desi-mcadam-madison-ruby-2013\"\n  title: \"Workshop: Madison Railsbridge - Outreach for Women\"\n  speakers:\n    - Desi McAdam\n  description: |-\n    A RailsBridge workshop focused on women's outreach in the Ruby community.\n  video_provider: \"not_recorded\"\n  video_id: \"desi-mcadam-madison-ruby-2013\"\n  date: \"2013-08-22\"\n\n- id: \"elisabeth-hendrickson-pat-maddox-madison-ruby-2013\"\n  title: \"Workshop: Don't Despair - Pairing with team members possessing disparate skills\"\n  speakers:\n    - Elisabeth Hendrickson\n    - Pat Maddox\n  description: |-\n    A workshop on effective pairing with team members who have different skill sets.\n  video_provider: \"not_recorded\"\n  video_id: \"elisabeth-hendrickson-pat-maddox-madison-ruby-2013\"\n  date: \"2013-08-22\"\n\n- id: \"noel-rappin-madison-ruby-2013\"\n  title: \"Workshop: Objects, Rails, and Long-Living Code\"\n  speakers:\n    - Noel Rappin\n  description: |-\n    A workshop on building maintainable object-oriented code in Rails.\n  video_provider: \"not_recorded\"\n  video_id: \"noel-rappin-madison-ruby-2013\"\n  date: \"2013-08-22\"\n\n- id: \"bermon-painter-madison-ruby-2013\"\n  title: \"Workshop: Rapid Prototyping with Middleman, Slim, Sass & Compass\"\n  speakers:\n    - Bermon Painter\n  description: |-\n    A workshop on rapid prototyping using Middleman, Slim, Sass, and Compass.\n  video_provider: \"not_recorded\"\n  video_id: \"bermon-painter-madison-ruby-2013\"\n  date: \"2013-08-22\"\n\n## Conference Day 1 - August 23, 2013\n\n- id: \"jessie-shternshus-playnote-madison-ruby-2013\"\n  title: \"Playnote\"\n  speakers:\n    - Jessie Shternshus\n  description: |-\n    An interactive playnote session to kick off the conference.\n  video_provider: \"not_recorded\"\n  video_id: \"jessie-shternshus-playnote-madison-ruby-2013\"\n  date: \"2013-08-23\"\n\n- id: \"bryan-liles-madison-ruby-2013\"\n  title: \"Interview with your App\"\n  speakers:\n    - Bryan Liles\n  description: |-\n    A talk on understanding and communicating with your application.\n  video_provider: \"not_recorded\"\n  video_id: \"bryan-liles-madison-ruby-2013\"\n  date: \"2013-08-23\"\n\n- id: \"bryan-powell-madison-ruby-2013\"\n  title: \"Rethinking the view\"\n  speakers:\n    - Bryan Powell\n  description: |-\n    A talk on rethinking the view layer in web applications.\n  video_provider: \"not_recorded\"\n  video_id: \"bryan-powell-madison-ruby-2013\"\n  date: \"2013-08-23\"\n\n- id: \"aaron-patterson-madison-ruby-2013\"\n  title: \"Yak shaving is best shaving\"\n  speakers:\n    - Aaron Patterson\n  description: |-\n    Aaron Patterson discusses the art and value of yak shaving in software development.\n  video_provider: \"not_recorded\"\n  video_id: \"aaron-patterson-madison-ruby-2013\"\n  date: \"2013-08-23\"\n\n- id: \"carina-zona-madison-ruby-2013\"\n  title: \"Schemas for the Real World\"\n  speakers:\n    - Carina C. Zona\n  description: |-\n    A talk on designing database schemas that reflect real-world complexity and human diversity.\n  video_provider: \"not_recorded\"\n  video_id: \"carina-zona-madison-ruby-2013\"\n  date: \"2013-08-23\"\n\n- id: \"jessie-shternshus-improv-madison-ruby-2013\"\n  title: '\"Improv\"e Your Organization'\n  speakers:\n    - Jessie Shternshus\n  description: |-\n    Using improv techniques to improve your organization and team dynamics.\n  video_provider: \"not_recorded\"\n  video_id: \"jessie-shternshus-improv-madison-ruby-2013\"\n  date: \"2013-08-23\"\n\n- id: \"steve-klabnik-madison-ruby-2013\"\n  title: \"CLOSURE\"\n  speakers:\n    - Steve Klabnik\n  description: |-\n    Steve Klabnik delivers a talk on closures and functional programming concepts.\n  video_provider: \"not_recorded\"\n  video_id: \"steve-klabnik-madison-ruby-2013\"\n  date: \"2013-08-23\"\n\n- id: \"margaret-pagel-madison-ruby-2013\"\n  title: \"Communication Roadmap Gems\"\n  speakers:\n    - Margaret Pagel\n  description: |-\n    A talk on improving communication within development teams.\n  video_provider: \"not_recorded\"\n  video_id: \"margaret-pagel-madison-ruby-2013\"\n  date: \"2013-08-23\"\n\n## Conference Day 2 - August 24, 2013\n\n- id: \"jason-garber-madison-ruby-2013\"\n  title: \"The Eight-fingered Chef\"\n  speakers:\n    - Jason Garber\n  description: |-\n    Jason Garber shares lessons from the kitchen applied to software development.\n  video_provider: \"not_recorded\"\n  video_id: \"jason-garber-madison-ruby-2013\"\n  date: \"2013-08-24\"\n\n- id: \"leon-gersing-madison-ruby-2013\"\n  title: \"Psyche and Eros\"\n  speakers:\n    - Leon Gersing\n  description: |-\n    A talk exploring the intersection of psychology and software development.\n  video_provider: \"not_recorded\"\n  video_id: \"leon-gersing-madison-ruby-2013\"\n  date: \"2013-08-24\"\n\n- id: \"ed-finkler-madison-ruby-2013\"\n  title: \"Open Sourcing Mental Illness\"\n  speakers:\n    - Ed Finkler\n  description: |-\n    Ed Finkler discusses mental health awareness in the tech community.\n  video_provider: \"not_recorded\"\n  video_id: \"ed-finkler-madison-ruby-2013\"\n  date: \"2013-08-24\"\n\n- id: \"michael-fairley-madison-ruby-2013\"\n  title: \"Rapid Game Prototyping with Ruby\"\n  speakers:\n    - Michael Fairley\n  description: |-\n    A talk on using Ruby for rapid game prototyping and development.\n  video_provider: \"not_recorded\"\n  video_id: \"michael-fairley-madison-ruby-2013\"\n  date: \"2013-08-24\"\n\n- id: \"justin-searls-madison-ruby-2013\"\n  title: \"Office Politics for the Thin-Skinned\"\n  speakers:\n    - Justin Searls\n  description: |-\n    Justin Searls shares strategies for navigating office politics.\n  video_provider: \"not_recorded\"\n  video_id: \"justin-searls-madison-ruby-2013\"\n  date: \"2013-08-24\"\n\n- id: \"fiona-tay-madison-ruby-2013\"\n  title: \"Service-oriented JRuby\"\n  speakers:\n    - Fiona Tay\n  description: |-\n    A talk on building service-oriented architectures with JRuby.\n  video_provider: \"not_recorded\"\n  video_id: \"fiona-tay-madison-ruby-2013\"\n  date: \"2013-08-24\"\n\n- id: \"martin-atkins-madison-ruby-2013\"\n  title: \"PUNK\"\n  speakers:\n    - Martin Atkins\n  description: |-\n    Martin Atkins explores punk philosophy and its application to software.\n  video_provider: \"not_recorded\"\n  video_id: \"martin-atkins-madison-ruby-2013\"\n  date: \"2013-08-24\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2014/event.yml",
    "content": "---\nid: \"PLJ-cEwTSAyZ6gLSWt1Mnq7vxqB6qiEzMz\"\ntitle: \"Madison+ Ruby 2014\"\ndescription: |-\n  A conference in Madison, WI more or less about Ruby.\nlocation: \"Madison, WI, United States\"\nkind: \"conference\"\nstart_date: \"2014-08-22\"\nend_date: \"2014-08-23\"\ntwitter: \"madisonruby\"\nplaylist: \"https://www.youtube.com/playlist?list=PLJ-cEwTSAyZ6gLSWt1Mnq7vxqB6qiEzMz\"\nwebsite: \"https://web.archive.org/web/20140817183232/http://madisonpl.us/ruby/\"\ncoordinates:\n  latitude: 43.0721661\n  longitude: -89.4007501\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2014/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Level 1\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Bendyworks\"\n          website: \"https://bendyworks.com/\"\n          slug: \"bendyworks\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/bendyworks-200.png\"\n\n        - name: \"Enova\"\n          website: \"https://www.enova.com/\"\n          slug: \"enova\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/enova-200w.png\"\n\n    - name: \"Level 2\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Engine Yard\"\n          website: \"https://www.engineyard.com/\"\n          slug: \"engine-yard\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/ey-200.png\"\n\n        - name: \"DigitalOcean\"\n          website: \"https://www.digitalocean.com/\"\n          slug: \"digitalocean\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/digital-ocean-200.png\"\n\n        - name: \"Mandrill\"\n          website: \"https://www.mandrill.com/\"\n          slug: \"mandrill\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/mandrill-200.png\"\n\n        - name: \"GitHub\"\n          website: \"https://github.com/\"\n          slug: \"github\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/GitHub-200w.png\"\n\n        - name: \"BIMvid\"\n          website: \"https://www.bimvid.com/\"\n          slug: \"bimvid\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/bimvid_200.png\"\n\n        - name: \"Braintree\"\n          website: \"https://www.braintreepayments.com/\"\n          slug: \"braintree\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/Braintree_Logo200w.png\"\n\n    - name: \"Level 3\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"adorable.io\"\n          website: \"https://adorable.io/\"\n          slug: \"adorable-io\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/adorable220.png\"\n\n        - name: \"Instructure / Canvas\"\n          website: \"https://www.instructure.com/\"\n          slug: \"instructure-canvas\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/canvaslogo-200.png\"\n\n        - name: \"Table XI\"\n          website: \"https://www.tablexi.com/\"\n          slug: \"table-xi\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/table-xi-200.png\"\n\n        - name: \"Bugsnag\"\n          website: \"https://bugsnag.com/\"\n          slug: \"bugsnag\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/bugsnaglogo-200.png\"\n\n        - name: \"Wellbe\"\n          website: \"https://www.wellbe.me/\"\n          slug: \"wellbe\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/wellbelogo-200.png\"\n\n        - name: \"Ten Forward Consulting, Inc.\"\n          website: \"https://tenforwardconsulting.com/\"\n          slug: \"ten-forward-consulting-inc\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/tenforward-200.png\"\n\n        - name: \"ConfPlus\"\n          website: \"https://www.confplusapp.com/\"\n          slug: \"confplus\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/ConfPlus-Logo-200w.png\"\n\n        - name: \"Madison College\"\n          website: \"https://madisoncollege.edu/\"\n          slug: \"madison-college\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/madison-college-150h.png\"\n\n        - name: \"Backflip Films\"\n          website: \"https://www.backflipfilms.com/\"\n          slug: \"backflip-films\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/BackFlipFilms-200.png\"\n\n    - name: \"Level 4\"\n      description: \"\"\n      level: 4\n      sponsors:\n        - name: \"WayPaver\"\n          website: \"https://waypaver.co/\"\n          slug: \"waypaver\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/waypaver-200.png\"\n\n        - name: \"Yammer, Inc.\"\n          website: \"https://www.yammer.com/\"\n          slug: \"yammer-inc\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/yammer-200.png\"\n\n        - name: \"Google\"\n          website: \"https://www.google.com/intl/en/about/\"\n          slug: \"google\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/google-200.png\"\n\n        - name: \"Madison+\"\n          website: \"https://madisonpl.us/\"\n          slug: \"madison-plus\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/madison-ploos-logo-200wide.png\"\n\n        - name: \"Sapling Events\"\n          website: \"https://www.saplingevents.com/\"\n          slug: \"sapling-events\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/saplingeventsPNG.png\"\n\n    - name: \"Level 5\"\n      description: \"\"\n      level: 5\n      sponsors:\n        - name: \"Your Mix Entertainment\"\n          website: \"https://www.yourmixentertainment.com/\"\n          slug: \"your-mix-entertainment\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/ymphotobig-200.png\"\n\n        - name: \"Zendesk\"\n          website: \"https://www.zendesk.com/simple-customer-service\"\n          slug: \"zendesk\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/zendesk-200.png\"\n\n        - name: \"Murfie\"\n          website: \"https://www.murfie.com/\"\n          slug: \"murfie\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/murfie-200.png\"\n\n        - name: \"Uber\"\n          website: \"https://www.uber.com/cities/madison\"\n          slug: \"uber\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/uber-logo-200_0.png\"\n\n        - name: \"AppSignal\"\n          website: \"https://appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/appsignal-200w.png\"\n\n        - name: \"Sticker Mule\"\n          website: \"https://www.stickermule.com/\"\n          slug: \"sticker-mule\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/stickermule-200w.png\"\n\n        - name: \"Code School\"\n          website: \"https://www.codeschool.com/\"\n          slug: \"code-school\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/Code-School-logo-200w.png\"\n\n        - name: \"Honeybadger\"\n          website: \"https://www.honeybadger.io/\"\n          slug: \"honeybadger\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/honeybadger200w.png\"\n\n        - name: \"O'Reilly Media\"\n          website: \"https://oreilly.com/\"\n          slug: \"oreilly-media\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/OReilly200_0.png\"\n\n        - name: \"Pluralsight\"\n          website: \"https://pluralsight.com/\"\n          slug: \"pluralsight\"\n          logo_url: \"https://web.archive.org/web/20140918081431im_/http://madisonpl.us/ruby/images/pluralsightPNG.png\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: https://www.youtube.com/playlist?list=PLJ-cEwTSAyZ6gLSWt1Mnq7vxqB6qiEzMz\n---\n[]\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2015/event.yml",
    "content": "---\nid: \"madison-ruby-2015\"\ntitle: \"Madison+ Ruby 2015\"\ndescription: \"\"\nlocation: \"Madison, WI, United States\"\nkind: \"conference\"\nstart_date: \"2015-08-20\"\nend_date: \"2015-08-22\"\ntwitter: \"madisonruby\"\nwebsite: \"https://web.archive.org/web/20151031095128/http://madisonpl.us/ruby/\"\ncoordinates:\n  latitude: 43.0721661\n  longitude: -89.4007501\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2015/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Level 1\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Stitch Fix\"\n          website: \"https://www.stitchfix.com/\"\n          slug: \"stitch-fix\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/stitch_fix_logo250.png\"\n\n        - name: \"HealthFinch\"\n          website: \"https://www.healthfinch.com/\"\n          slug: \"healthfinch\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/HealthFinch-250.png\"\n\n    - name: \"Level 2\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Zendesk\"\n          website: \"https://www.zendesk.com/\"\n          slug: \"zendesk\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/zendesk_logo-225.png\"\n\n        - name: \"Mandrill\"\n          website: \"https://www.mandrill.com/\"\n          slug: \"mandrill\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/Mandrill_Shield225x225.png\"\n\n        - name: \"Backflip Films\"\n          website: \"https://www.backflipfilms.com/\"\n          slug: \"backflip-films\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/BackFlipFilms-200.png\"\n\n    - name: \"Level 3\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"ConfPlus\"\n          website: \"https://www.confplusapp.com/\"\n          slug: \"confplus\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/ConfPlus-Logo-200w.png\"\n\n        - name: \"Engine Yard\"\n          website: \"https://www.engineyard.com/\"\n          slug: \"engine-yard\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/ey-200.png\"\n\n        - name: \"Table XI\"\n          website: \"https://www.tablexi.com/\"\n          slug: \"table-xi\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/table-xi-200.png\"\n\n        - name: \"Bendyworks\"\n          website: \"https://bendyworks.com/\"\n          slug: \"bendyworks\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/bendyworks-200.png\"\n\n        - name: \"Honeybadger\"\n          website: \"https://www.honeybadger.io/\"\n          slug: \"honeybadger\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/honeybadger200w.png\"\n\n    - name: \"Level 4\"\n      description: \"\"\n      level: 4\n      sponsors:\n        - name: \"Google\"\n          website: \"https://www.google.com/intl/en/about/\"\n          slug: \"google\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/google-200.png\"\n\n        - name: \"NIRD LLC\"\n          website: \"https://nird.us/\"\n          slug: \"nird-llc\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/nirdlogo-200.png\"\n\n        - name: \"adorable.io\"\n          website: \"https://adorable.io/\"\n          slug: \"adorable-io\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/adorable220.png\"\n\n    - name: \"Level 5\"\n      description: \"\"\n      level: 5\n      sponsors:\n        - name: \"Heroku\"\n          website: \"https://www.heroku.com/\"\n          slug: \"heroku\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/herokulogotypehorizontalpurple_heroku-logotype-horizontal-purple.png\"\n\n        - name: \"OSS Madison\"\n          website: \"https://ossmadison.com/\"\n          slug: \"oss-madison\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/SherlockLogo150.png\"\n\n        - name: \"Sticker Mule\"\n          website: \"https://www.stickermule.com/\"\n          slug: \"sticker-mule\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/stickermule-200w.png\"\n\n        - name: \"StandStand\"\n          website: \"https://www.standstand.com/\"\n          slug: \"standstand\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/standstand200_0.png\"\n\n        - name: \"DigitalOcean\"\n          website: \"https://www.digitalocean.com/\"\n          slug: \"digitalocean\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/digital-ocean-200.png\"\n\n        - name: \"AppSignal\"\n          website: \"https://appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/appsignal-200w.png\"\n\n        - name: \"O'Reilly Media\"\n          website: \"https://oreilly.com/\"\n          slug: \"oreilly-media\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/OReilly200_0.png\"\n\n        - name: \"Pluralsight\"\n          website: \"https://pluralsight.com/\"\n          slug: \"pluralsight\"\n          logo_url: \"https://web.archive.org/web/20150915103808im_/http://madisonpl.us/ruby/images/pluralsightPNG.png\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2016/event.yml",
    "content": "---\nid: \"madison-ruby-2016\"\ntitle: \"Madison+ Ruby 2016\"\ndescription: \"\"\nlocation: \"Madison, WI, United States\"\nkind: \"conference\"\nstart_date: \"2016-07-08\"\nend_date: \"2016-07-08\"\ntwitter: \"madisonruby\"\nwebsite: \"https://web.archive.org/web/20161115011740/http://madisonruby.org\"\ncoordinates:\n  latitude: 43.0721661\n  longitude: -89.4007501\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2016/schedule.yml",
    "content": "# Schedule: https://web.archive.org/web/20161110025444/http://www.madisonruby.org/\n---\ndays:\n  - name: \"Friday, July 8, 2016\"\n    date: \"2016-07-08\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - \"Check In\"\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n\n      - start_time: \"09:15\"\n        end_time: \"09:45\"\n        slots: 1\n\n      - start_time: \"09:45\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - \"Break\"\n\n      - start_time: \"10:45\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n        items:\n          - \"Local Flavor: Go behind the scenes of the Capitol Theater\"\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - \"Lunch\"\n\n      - start_time: \"13:30\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:15\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - \"Local Flavor: Mad Urban Bees\"\n\n      - start_time: \"14:30\"\n        end_time: \"14:45\"\n        slots: 1\n        items:\n          - 'Local Flavor: In The City: Art, Technology and the \"Pop Up\" Economy'\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n        items:\n          - \"Snack Break\"\n\n      - start_time: \"15:15\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 1\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - \"Snack Break\"\n\n      - start_time: \"17:00\"\n        end_time: \"17:45\"\n        slots: 1\n\n      - start_time: \"17:45\"\n        end_time: \"18:15\"\n        slots: 1\n\n      - start_time: \"18:15\"\n        end_time: \"18:30\"\n        slots: 1\n\ntracks: []\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2016/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Ten Forward Consulting\"\n          website: \"https://tenforward.consulting/\"\n          slug: \"ten-forward\"\n          logo_url: \"https://web.archive.org/web/20161110025444im_/http://www.madisonruby.org/assets/images/e6ef4b60-3e1b-11e6-a6d8-1dde3e46edfc-tenforward.jpg\"\n\n        - name: \"Smart Solutions\"\n          website: \"https://www.smart-solutions.com/\"\n          slug: \"smart-solutions\"\n          logo_url: \"https://web.archive.org/web/20161110025444im_/http://www.madisonruby.org/assets/images/d56ba390-29a6-11e6-8937-2bcb1dbb3272-smart-solutions.jpg\"\n\n        - name: \"Zendesk\"\n          website: \"https://www.zendesk.com/\"\n          slug: \"zendesk\"\n          logo_url: \"https://web.archive.org/web/20161110025444im_/http://www.madisonruby.org/assets/images/75f639f0-2804-11e6-9319-cbc85635dfe9-zendesk.jpg\"\n\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://web.archive.org/web/20161110025444im_/http://www.madisonruby.org/assets/images/6d0197e0-2804-11e6-9319-cbc85635dfe9-appsignal.jpg\"\n\n        - name: \"Adorable\"\n          website: \"https://adorable.io/\"\n          slug: \"adorable\"\n          logo_url: \"https://web.archive.org/web/20161110025444im_/http://www.madisonruby.org/assets/images/f7090500-2835-11e6-9319-cbc85635dfe9-adorable-rubysite.jpg\"\n\n        - name: \"Digital Ocean\"\n          website: \"https://www.digitalocean.com/\"\n          slug: \"digital-ocean\"\n          logo_url: \"https://web.archive.org/web/20161110025444im_/http://www.madisonruby.org/assets/images/4d2c78f0-43c4-11e6-aa17-c78156676f52-digital-ocean-logo-4x3.png\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2016/videos.yml",
    "content": "# Schedule: https://web.archive.org/web/20161110025444/http://www.madisonruby.org/\n---\n- id: \"jim-remsik-madison-ruby-2016\"\n  title: \"Welcome Address\"\n  speakers:\n    - Jim Remsik\n  description: |-\n    Opening welcome address for Madison+ Ruby 2016.\n  video_provider: \"not_recorded\"\n  video_id: \"jim-remsik-madison-ruby-2016\"\n  date: \"2016-07-08\"\n\n- id: \"noel-rappin-madison-ruby-2016\"\n  title: \"I Was A Developer Running HR For A Year: AMA\"\n  speakers:\n    - Noel Rappin\n  description: |-\n    Noel Rappin shares his experience running HR for a year as a developer, offering insights and answering questions about the intersection of technology and human resources.\n  video_provider: \"not_recorded\"\n  video_id: \"noel-rappin-madison-ruby-2016\"\n  date: \"2016-07-08\"\n\n- id: \"erica-naughton-savance-ford-madison-ruby-2016\"\n  title: \"Building the Madison+Ruby Website\"\n  speakers:\n    - Erica Naughton\n    - SaVance Ford\n  description: |-\n    Erica Naughton and SaVance Ford discuss the process of building the Madison+Ruby website, sharing insights about web development and conference organization.\n  video_provider: \"not_recorded\"\n  video_id: \"erica-naughton-savance-ford-madison-ruby-2016\"\n  date: \"2016-07-08\"\n\n- id: \"iheanyi-ekechukwu-madison-ruby-2016\"\n  title: \"DevOps, Ember.js, and You\"\n  speakers:\n    - Iheanyi Ekechukwu\n  description: |-\n    Iheanyi Ekechukwu explores the intersection of DevOps practices and Ember.js development, providing insights for modern web development workflows.\n  video_provider: \"not_recorded\"\n  video_id: \"iheanyi-ekechukwu-madison-ruby-2016\"\n  date: \"2016-07-08\"\n\n- id: \"lori-olson-madison-ruby-2016\"\n  title: \"Do The Work\"\n  speakers:\n    - Lori M Olson\n  description: |-\n    Have you ever run into that problem you are trying to solve, that is tangential to your core business? It's easy to run off, look for a gem, and use it. What is harder is when that gem isn't quite right. Maybe you should look for an alternative. Maybe you should fix the gem. Or if your problem is different enough, you can fork the gem. Or maybe you should just stop wasting so much time looking for the \"easy\" solution, and just DO THE WORK.\n  video_provider: \"not_recorded\"\n  video_id: \"lori-olson-madison-ruby-2016\"\n  slides_url: \"https://speakerdeck.com/wndxlori/do-the-work-madison-ruby-the-epilogue\"\n  date: \"2016-07-08\"\n\n- id: \"mark-yoon-madison-ruby-2016\"\n  title: \"Pairing for real\"\n  speakers:\n    - Mark Yoon\n  description: |-\n    Mark Yoon discusses effective pair programming practices and how to make the most of collaborative development sessions.\n  video_provider: \"not_recorded\"\n  video_id: \"mark-yoon-madison-ruby-2016\"\n  date: \"2016-07-08\"\n\n- id: \"jonan-scheffler-madison-ruby-2016\"\n  title: \"Dream\"\n  speakers:\n    - Jonan Scheffler\n  description: |-\n    Jonan Scheffler shares thoughts on dreaming big in software development and pursuing ambitious goals in technology.\n  video_provider: \"not_recorded\"\n  video_id: \"jonan-scheffler-madison-ruby-2016\"\n  date: \"2016-07-08\"\n\n- id: \"coraline-ada-ehmke-madison-ruby-2016\"\n  title: \"The Broken Promise of Open Source\"\n  speakers:\n    - Coraline Ada Ehmke\n  description: |-\n    Coraline Ada Ehmke examines the challenges and broken promises in the open source community, discussing issues of sustainability, inclusion, and the future of open source software.\n  video_provider: \"not_recorded\"\n  video_id: \"coraline-ada-ehmke-madison-ruby-2016\"\n  date: \"2016-07-08\"\n\n- id: \"martin-atkins-madison-ruby-2016\"\n  title: \"There is no straight line from a to b\"\n  speakers:\n    - Martin Atkins\n  description: |-\n    Martin Atkins discusses the non-linear nature of software development and career paths, sharing insights about navigating the complex journey of building software and growing as a developer.\n  video_provider: \"not_recorded\"\n  video_id: \"martin-atkins-madison-ruby-2016\"\n  date: \"2016-07-08\"\n\n- id: \"jim-remsik-closing-madison-ruby-2016\"\n  title: \"Closing Address\"\n  speakers:\n    - Jim Remsik\n  description: |-\n    Closing address for Madison+ Ruby 2016, wrapping up the conference.\n  video_provider: \"not_recorded\"\n  video_id: \"jim-remsik-closing-madison-ruby-2016\"\n  date: \"2016-07-08\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2018/event.yml",
    "content": "---\nid: \"madison-ruby-2018\"\ntitle: \"Madison+ Ruby: Chicago 2018\"\ndescription: \"\"\nlocation: \"Chicago, IL, United States\"\nkind: \"conference\"\nstart_date: \"2018-05-10\"\nend_date: \"2018-05-11\"\nwebsite: \"https://ti.to/adorable/madison-ruby-chicago/en\"\ntwitter: \"MadisonRuby\"\ncoordinates:\n  latitude: 41.88325\n  longitude: -87.6323879\naliases:\n  - Madison+ Ruby 2018\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://ti.to/adorable/madison-ruby-chicago/en\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2024/cfp.yml",
    "content": "---\n- link: \"https://cfp.madisonruby.com/events/2024/\"\n  open_date: \"2024-03-15\"\n  close_date: \"2024-04-30\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2024/event.yml",
    "content": "---\nid: \"madison-ruby-2024\"\ntitle: \"Madison+ Ruby 2024\"\nkind: \"conference\"\nlocation: \"Madison, WI, United States\"\ndescription: |-\n  Join us to explore the weird & wonderful world all around us - August 1 - 2, 2024 - Madison, WI – Overture Center\nstart_date: \"2024-08-01\"\nend_date: \"2024-08-02\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nwebsite: \"https://web.archive.org/web/20241014192334/https://www.madisonruby.com/\"\nbanner_background: |-\n  linear-gradient(to bottom, #BACED4, #BACED4 40%, #658994 40%) left top / 50% 100% no-repeat, /* Left side */\n  linear-gradient(to bottom, #BACED4, #BACED4 66.57%, #658994 66.57%) right top / 50% 100% no-repeat /* Right side */\nfeatured_background: \"#32454A\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 43.0741048\n  longitude: -89.38828459999999\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2024/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jim Remsik\n  organisations:\n    - Flagrant\n\n- name: \"Volunteer\"\n  users: []\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2024/schedule.yml",
    "content": "# Schedule: https://www.madisonruby.com/schedule/\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-08-01\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"08:45\"\n        slots: 1\n        items:\n          - Registration & Check-In\n\n      - start_time: \"08:45\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Welcome Announcements\n\n      - start_time: \"09:00\"\n        end_time: \"09:45\"\n        slots: 1\n\n      - start_time: \"09:45\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"13:15\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:15\"\n        end_time: \"13:45\"\n        slots: 1\n\n      - start_time: \"13:45\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:15\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 1\n        items:\n          - Local Flavor\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - End of Day Announcements\n\n  - name: \"Day 2\"\n    date: \"2024-08-02\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration & Check-In\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Welcome Announcements\n\n      - start_time: \"09:15\"\n        end_time: \"09:45\"\n        slots: 1\n\n      - start_time: \"09:45\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"13:15\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:15\"\n        end_time: \"13:45\"\n        slots: 1\n\n      - start_time: \"13:45\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:15\"\n        end_time: \"14:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"15:45\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Closing Announcements\n\ntracks: []\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: |-\n        Madison Ruby 2024 Sponsors\n      level: 1\n      sponsors:\n        - name: \"Transistor.fm\"\n          website: \"https://transistor.fm/\"\n          slug: \"transistor-fm\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/transistor-vertical-logo-dark-ALTERNATE.svg\"\n\n        - name: \"Ten Forward Consulting\"\n          website: \"https://tenforward.consulting/\"\n          slug: \"ten-forward\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/ten-forward-vertical-logo-high-res.png\"\n\n        - name: \"Honeybadger\"\n          website: \"https://www.honeybadger.io/tour/logging-observability/\"\n          slug: \"honeybadger\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/honeybadger_logo.svg\"\n\n        - name: \"GroupCollect\"\n          website: \"https://groupcollect.com/\"\n          slug: \"groupcollect\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/groupcollect-logo-no-padding_single-color-green-rgb.png\"\n\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/Appsignal-vertical-black.svg\"\n\n        - name: \"WyeWorks\"\n          website: \"https://www.wyeworks.com/\"\n          slug: \"wyeworks\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/wyeworks-logo-black-red.png\"\n\n        - name: \"Echobind\"\n          website: \"https://echobind.com/services\"\n          slug: \"echobind\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/eb-black.svg\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"dnsimple\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/dns-simple-logomark-classic.svg\"\n\n        - name: \"Chime\"\n          website: \"https://www.chime.com/\"\n          slug: \"chime\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/chime-wordmark-chime-green-rgb.svg\"\n\n        - name: \"8th Light\"\n          website: \"https://8thlight.com/\"\n          slug: \"8th-light\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/8L_Logo_Primary_Black.png\"\n\n        - name: \"Flox\"\n          website: \"https://flox.dev/\"\n          slug: \"flox\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/symbol_07.png\"\n\n        - name: \"Rooftop Ruby\"\n          website: \"https://www.rooftopruby.com/\"\n          slug: \"rooftop-ruby\"\n          logo_url: \"https://www.madisonruby.com/images/uploads/vtk48pugd7f1zb2mgicocfq6g89r-1-.jpeg\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2024/venue.yml",
    "content": "# https://www.madisonruby.com/locations\n---\nname: \"Overture Center for the Arts\"\n\naddress:\n  street: \"201 State St\"\n  city: \"Madison\"\n  region: \"WI\"\n  postal_code: \"53703\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"201 State St, Madison, WI 53703, USA\"\n\ncoordinates:\n  latitude: 43.0741048\n  longitude: -89.38828459999999\n\nmaps:\n  google: \"https://maps.google.com/?q=Overture+Center+for+the+Arts,43.0741048,-89.38828459999999\"\n  apple: \"https://maps.apple.com/?q=Overture+Center+for+the+Arts&ll=43.0741048,-89.38828459999999\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=43.0741048&mlon=-89.38828459999999\"\n\nhotels:\n  - name: \"DoubleTree by Hilton Madison Downtown\"\n    address:\n      street: \"525 West Johnson Street\"\n      city: \"Madison\"\n      region: \"Wisconsin\"\n      postal_code: \"53703\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"525 W Johnson St, Madison, WI 53703, USA\"\n\n    coordinates:\n      latitude: 43.0713935\n      longitude: -89.3942311\n\n    maps:\n      google: \"https://www.google.com/maps/search/?api=1&query=43.0713935,-89.3942311\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=43.0713935&mlon=-89.3942311&zoom=17\"\n"
  },
  {
    "path": "data/madison-ruby/madison-ruby-2024/videos.yml",
    "content": "---\n# Website: https://www.madisonruby.com\n# Schedule: https://www.madisonruby.com/schedule\n\n## Day 1\n\n- id: \"madison-ruby-2024-saron-yitbarek\"\n  title: \"Keynote: Our Superpower\"\n  raw_title: \"Madison Ruby 2024 - Our Superpower\"\n  speakers:\n    - \"Saron Yitbarek\"\n  video_id: \"madison-ruby-2024-saron-yitbarek\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GQTxm1AbwAApD3f?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GQTxm1AbwAApD3f?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GQTxm1AbwAApD3f?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GQTxm1AbwAApD3f?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GQTxm1AbwAApD3f?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    A keynote reflecting on a decade in the Ruby community, emphasizing mentorship and the essence of being a Rubyist.\n  date: \"2024-08-01\"\n\n- id: \"madison-ruby-2024-chantelle-isaacs\"\n  title: \"Dungeons and Developers: Uniting Experience Levels in Engineering Teams\"\n  raw_title: \"Madison Ruby 2024 - Dungeons and Developers: Uniting Experience Levels in Engine\"\n  speakers:\n    - Chantelle Isaacs\n  video_id: \"madison-ruby-2024-chantelle-isaacs\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GQ2izw3W8AAtsR_?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GQ2izw3W8AAtsR_?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GQ2izw3W8AAtsR_?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GQ2izw3W8AAtsR_?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GQ2izw3W8AAtsR_?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  date: \"2024-08-01\"\n  description: |-\n    \"Dungeons and Developers\" is an exploration of team dynamics through the lens of Dungeons & Dragons. Discover how the roles and skills in D&D can enlighten the way we build and nurture diverse engineering teams. Whether you’re a manager constructing a formidable team (Constitution) or an individual seeking to self-assess and advance your career (Charisma), this talk will guide you in leveraging technical and transferable talents. Identify your developer archetype and complete a 'Developer Character Sheet' to highlight your abilities, proficiencies, and alignment in a fun, D&D-inspired format.\n\n- id: \"madison-ruby-2024-scott-werner\"\n  title: \"Going Postel\"\n  raw_title: \"Madison Ruby 2024 - Going Postel\"\n  speakers:\n    - \"Scott Werner\"\n  video_id: \"madison-ruby-2024-scott-werner\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GPUzTZoXsAAhrpE?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GPUzTZoXsAAhrpE?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GPUzTZoXsAAhrpE?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GPUzTZoXsAAhrpE?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GPUzTZoXsAAhrpE?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    A discussion on applying Postel’s Law to code generated from Large Language Models (LLMs) and Ruby's role in AI code generation.\n  date: \"2024-08-01\"\n\n- id: \"madison-ruby-2024-senem-soy\"\n  title: \"Lessons From The Sky\"\n  raw_title: \"Madison Ruby 2024 - Lessons From The Sky\"\n  speakers:\n    - \"Senem Soy\"\n  video_id: \"madison-ruby-2024-senem-soy\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GQsWhXrWcAATPmk?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GQsWhXrWcAATPmk?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GQsWhXrWcAATPmk?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GQsWhXrWcAATPmk?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GQsWhXrWcAATPmk?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    Insights on how paragliding experiences can influence programming, focusing on handling fear and stress effectively.\n  date: \"2024-08-01\"\n\n- id: \"madison-ruby-2024-evan-keller\"\n  title: \"Visual Regression Testing with Storybook and Backstop\"\n  raw_title: \"Madison Ruby 2024 - Visual Regression Testing with Storybook and Backstop\"\n  speakers:\n    - \"Evan Keller\"\n  video_id: \"madison-ruby-2024-evan-keller\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GPt0CssWMAAeS-a?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GPt0CssWMAAeS-a?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GPt0CssWMAAeS-a?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GPt0CssWMAAeS-a?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GPt0CssWMAAeS-a?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    Essentials of visual regression testing using Storybook and Backstop, with practical advice for integration into development cycles.\n  date: \"2024-08-01\"\n\n- id: \"madison-ruby-2024-craig-buchek\"\n  title: \"Architecture Big and Small\"\n  raw_title: \"Madison Ruby 2024 - Architecture Big and Small\"\n  speakers:\n    - \"Craig Buchek\"\n  video_id: \"madison-ruby-2024-craig-buchek\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GQxbWHBXMAEZfjS?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GQxbWHBXMAEZfjS?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GQxbWHBXMAEZfjS?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GQxbWHBXMAEZfjS?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GQxbWHBXMAEZfjS?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    A comparative analysis of building architecture and software architecture, exploring patterns and considerations at various scales.\n  date: \"2024-08-01\"\n  slides_url: \"https://craigbuchek.com/arch\"\n\n- id: \"madison-ruby-2024-john-sawers\"\n  title: \"Hacking Your Emotional Firewall\"\n  raw_title: \"Madison Ruby 2024 - Hacking Your Emotional Firewall\"\n  speakers:\n    - \"John Sawers\"\n  video_id: \"madison-ruby-2024-john-sawers\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GPkCjEpXwAANMDY?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GPkCjEpXwAANMDY?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GPkCjEpXwAANMDY?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GPkCjEpXwAANMDY?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GPkCjEpXwAANMDY?format=jpg&name=medium\"\n  slides_url: \"https://speakerdeck.com/johnksawers/hacking-your-emotionhal-firewall-1-dot-0\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    Firewalls are great, they filter out traffic you don't want from the internet. In this talk I'll take a look at what's inside us, at the connection between our body and mind, and imagine a firewall that sits in between. What if we could use the magic of TCP to find disconnected parts of ourselves and connect to them? We would end up experiencing greater wholeness and increased understanding of our minds, bodies, emotions, and motivations.\n  date: \"2024-08-01\"\n\n- id: \"madison-ruby-2024-mark-yoon\"\n  title: \"Designing Resilient APIs: Balancing Stability & Flexibility\"\n  raw_title: \"Madison Ruby 2024 - Designing Resilient APIs: Balancing Stability & Flexibility\"\n  speakers:\n    - \"Mark Yoon\"\n  video_id: \"madison-ruby-2024-mark-yoon\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GP9OVajWoAAIB5C?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GP9OVajWoAAIB5C?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GP9OVajWoAAIB5C?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GP9OVajWoAAIB5C?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GP9OVajWoAAIB5C?format=jpg&name=medium\"\n  slides_url: \"https://speakerdeck.com/markyoon/designing-resilient-apis-balancing-stability-and-flexibility\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    Strategies for crafting robust APIs in Ruby tailored for mobile clients, focusing on stability, flexibility, and collaboration.\n  date: \"2024-08-01\"\n\n## Day 2\n\n- id: \"madison-ruby-2024-paolo-perrotta\"\n  title: \"Refactoring English\"\n  raw_title: \"Madison Ruby 2024 - Refactoring English\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  video_id: \"madison-ruby-2024-paolo-perrotta\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GPZxoCAXoAQmjfV?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GPZxoCAXoAQmjfV?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GPZxoCAXoAQmjfV?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GPZxoCAXoAQmjfV?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GPZxoCAXoAQmjfV?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    Techniques to enhance writing clarity for developers, drawing parallels between code refactoring and prose improvement.\n  date: \"2024-08-02\"\n\n- id: \"madison-ruby-2024-andrew-atkinson\"\n  title: \"Mastering Query Performance With Active Record\"\n  raw_title: \"Madison Ruby 2024 - Mastering Query Performance With Active Record\"\n  speakers:\n    - Andrew Atkinson\n  video_id: \"madison-ruby-2024-andrew-atkinson\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GTXYaJkagAAYnDw?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GTXYaJkagAAYnDw?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GTXYaJkagAAYnDw?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GTXYaJkagAAYnDw?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GTXYaJkagAAYnDw?format=jpg&name=medium\"\n  description: |-\n    Attendees will learn fundamentals of good database query performance. With live demonstrations of app queries that aren't optimized, we’ll step through optimizations, query planning, and index design. A public Rails app will be used. Examples will move back and forth between Active Record and SQL using both a SQL client and the Rails Console. Audience members will be polled and questioned for suggestions to make the content more engaging. Attendees will leave with knowledge of fundamentals and real-world optimization tactics they can apply to their Active Record code and relational databases.\n\n    https://andyatkinson.com/blog/2024/08/13/madison-plus-ruby-conference-recap\n  date: \"2024-08-02\"\n\n- id: \"madison-ruby-2024-allison-mcmillan\"\n  title: \"Effective Discussions for Technical Decision-Making\"\n  raw_title: \"Madison Ruby 2024 - Effective Discussions for Technical Decision-Making\"\n  speakers:\n    - Allison McMillan\n  video_id: \"madison-ruby-2024-allison-mcmillan\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GSSUzTXXUAEU8ei?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GSSUzTXXUAEU8ei?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GSSUzTXXUAEU8ei?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GSSUzTXXUAEU8ei?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GSSUzTXXUAEU8ei?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  slides_url: \"https://speakerdeck.com/asheren/effective-discussions-for-technical-decision-making\"\n  description: |-\n    Whiteboards. Pairing. Spikes. These are the tools we use to have high-level technical conversations about ideas or approaches. How you conduct and lead these conversations involves articulating a vision and securing buy-in, while also valuing and integrating diverse perspectives and feedback from others. The goal is to foster an environment where ideas can be exchanged, discussed, enhanced, and decided on. You’ll walk away from this talk with some new approaches to get your technical ideas across and also solicit thoughts and opinions in ways that engage different points of view.\n  date: \"2024-08-02\"\n\n- id: \"madison-ruby-2024-hilary-stohs-krause\"\n  title: \"How to Accessibility if You're Mostly Back-End\"\n  raw_title: \"Madison Ruby 2024 - How to Accessibility if You’re Mostly Back-End\"\n  speakers:\n    - \"Hilary Stohs-Krause\"\n  video_id: \"madison-ruby-2024-hilary-stohs-krause\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GPpn4_SWUAApz5S?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GPpn4_SWUAApz5S?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GPpn4_SWUAApz5S?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GPpn4_SWUAApz5S?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GPpn4_SWUAApz5S?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    Guidance for back-end developers on impacting accessibility through APIs, specs, Ruby code, and documentation.\n  date: \"2024-08-02\"\n\n- id: \"madison-ruby-2024-marco-roth\"\n  title: \"Developer Tooling For The Modern Rails & Hotwire Era\"\n  raw_title: \"Madison Ruby 2024 - Developer Tooling For The Modern Rails & Hotwire Era\"\n  speakers:\n    - \"Marco Roth\"\n  video_id: \"madison-ruby-2024-marco-roth\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://files.speakerdeck.com/presentations/b954afca5cb34d2980aa6364a4dc6a99/slide_0.jpg\"\n  thumbnail_sm: \"https://files.speakerdeck.com/presentations/b954afca5cb34d2980aa6364a4dc6a99/slide_0.jpg\"\n  thumbnail_md: \"https://files.speakerdeck.com/presentations/b954afca5cb34d2980aa6364a4dc6a99/slide_0.jpg\"\n  thumbnail_lg: \"https://files.speakerdeck.com/presentations/b954afca5cb34d2980aa6364a4dc6a99/slide_0.jpg\"\n  thumbnail_xl: \"https://files.speakerdeck.com/presentations/b954afca5cb34d2980aa6364a4dc6a99/slide_0.jpg\"\n  description: |-\n    Exploration of advanced developer experience tools in the Rails ecosystem, including Language Server Protocols for Stimulus and Turbo.\n  date: \"2024-08-02\"\n  slides_url: \"https://speakerdeck.com/marcoroth/developer-tooling-for-the-modern-rails-and-hotwire-era-at-madison-ruby-2024\"\n\n- id: \"madison-ruby-2024-ajina-slater\"\n  title: \"Zen and the Art of Incremental Automation\"\n  raw_title: \"Madison Ruby 2024 - Zen and the Art of Incremental Automation\"\n  speakers:\n    - Christopher \"Aji\" Slater\n  video_id: \"madison-ruby-2024-ajina-slater\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GQDALWXWsAEzSMi?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GQDALWXWsAEzSMi?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GQDALWXWsAEzSMi?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GQDALWXWsAEzSMi?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GQDALWXWsAEzSMi?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    Automation doesn’t have to be all or nothing. Automating manual processes is a practice that one can employ via simple principles. Broad enough to be applied to a range of workflows, flexible enough to be tailored to an individual’s personal development routines; these principles are not in themselves complex, and can be performed regularly in the day to day of working in a codebase. Learn how to cultivate habits and a culture of incremental automation so even if the goal is not a full self-service suite of automated tools, your team can begin a journey away from friction and manual tasks.\n  date: \"2024-08-02\"\n\n- id: \"madison-ruby-2024-landon-gray\"\n  title: \"Ruby on RAG: Building AI Use Cases for Fun and Profit\"\n  raw_title: \"Madison Ruby 2024 - Ruby on RAG: Building AI Use Cases for Fun and Profit\"\n  speakers:\n    - \"Landon Gray\"\n  video_id: \"madison-ruby-2024-landon-gray\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GSIFESPaUAkro38?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GSIFESPaUAkro38?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GSIFESPaUAkro38?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GSIFESPaUAkro38?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GSIFESPaUAkro38?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  slides_url: \"https://speakerdeck.com/thedayisntgray/ruby-on-rag-building-ai-use-cases-for-fun-and-profit\"\n  description: |-\n    This talk will cover what RAG is, how it works, and why we should be building RAG applications in Ruby and Rails. I'll share some code examples of what a toy RAG pipeline looks like in native Ruby and do a live demo of a simple RAG application. I'll also share a perspective as to why Ruby and Rails are great tools for building LLM applications and that the future languages for building such applications are whatever languages are most natural to you.\n  date: \"2024-08-02\"\n\n- id: \"madison-ruby-2024-coraline-ada-ehmke\"\n  title: \"Four Reasons Not to Care about Ethics in Open Source\"\n  raw_title: \"Madison Ruby 2024 - Four Reasons Not to Care about Ethics in Open Source\"\n  speakers:\n    - \"Coraline Ada Ehmke\"\n  video_id: \"madison-ruby-2024-coraline-ada-ehmke\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GPze7qOWoAAt5T0?format=jpg&name=small\" # TODO: get rectangle version for speaker posters\n  thumbnail_sm: \"https://pbs.twimg.com/media/GPze7qOWoAAt5T0?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GPze7qOWoAAt5T0?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GPze7qOWoAAt5T0?format=jpg&name=medium\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GPze7qOWoAAt5T0?format=jpg&name=medium\"\n  thumbnail_classes: \"object-bottom\"\n  description: |-\n    A provocative discussion on the role of ethics in open source, challenging common perceptions and encouraging critical thought.\n  date: \"2024-08-02\"\n"
  },
  {
    "path": "data/madison-ruby/series.yml",
    "content": "---\nname: \"Madison+ Ruby\"\nwebsite: \"https://madisonruby.com\"\ntwitter: \"madisonruby\"\nyoutube_channel_name: \"confreaks\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Madison+ Ruby\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/madrid-rb/madrid-rb-meetup/event.yml",
    "content": "---\nid: \"madrid-rb-meetup\"\ntitle: \"Madrid.rb Meetup\"\nlocation: \"Madrid, Spain\"\ndescription: |-\n  Madrid Ruby User Group\nkind: \"meetup\"\npublished_at: \"2024-11-26\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://www.madridrb.com\"\ncoordinates:\n  latitude: 40.41672790000001\n  longitude: -3.7032905\n"
  },
  {
    "path": "data/madrid-rb/madrid-rb-meetup/videos.yml",
    "content": "---\n# Website: https://www.madridrb.com\n\n# 2024\n\n- id: \"madrid-rb-meetup-november-2024\"\n  title: \"Madrid.rb November 2024\"\n  event_name: \"Madrid.rb November 2024\"\n  date: \"2024-11-07\"\n  video_provider: \"children\"\n  video_id: \"madrid-rb-meetup-november-2024\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GajqNFcWkAQGTpb?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GajqNFcWkAQGTpb?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GajqNFcWkAQGTpb?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GajqNFcWkAQGTpb?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GajqNFcWkAQGTpb?format=jpg&name=large\"\n  description: |-\n    Anunciando la edición para Madrid del Spain Triangle Project, una iniciativa the Ruby Europe en la que participa Madrid.rb\n\n    Importante: Todas las intervenciones tendrán lugar en Inglés - All presentations will be held in English\n\n    The Spain Triangle Project\n    Get ready for an unforgettable Ruby meetup as we wrap up the Ruby Europe: Spain Triangle Project - a pioneering initiative to unite and invigorate the Ruby community across Spain!\n\n    What sets this event apart:\n\n    As the final stop in our Ruby journey across Spain, this meetup is your chance to be part of a historic moment. Let's make Madrid a beacon for Ruby developers!\n\n    Speakers:\n\n    🎤 Mariusz Kozieł - 'Beyond Meetups: Creating Ruby Ecosystem’\n    🎤 Egor Iskrenkov - ‘Code review automation: getting rid of \"you forgot to...\" comments’\n    🎤 Paweł Strzałkowski - ‘My LLM is smarter than yours - RAG and Vector Search in Ruby’\n    The Spain Triangle Project\n\n    We're thrilled to host the final event of the Spain Triangle Project, an initiative by Ruby Europe. Catch up on what you missed:\n\n    Barcelona.rb on November 5th\n    Valencia.rb on November 6th Postponed due to recent tragic events\n    Madrid.rb on November 7th\n    🚂 Join the Ruby Train! We're inviting a group of enthusiasts to travel together to all three events. More Ruby, more networking, more fun! Train group: https://forms.gle/aRyoxWaji5s55F1e6\n\n    With support from Ligokids\n\n    Lingokids generously offers their brand new offices to host this event. Thanks!\n\n    About Ruby Europe\n\n    Ruby Europe is uniting Ruby enthusiasts across the continent to build a thriving community. Join us on Discord and visit rubyeurope.com to learn more!\n\n    Join us in celebrating Ruby, forging new connections, and charting the course for Spain's Ruby future!\n\n    https://www.madridrb.com/events/ruby-europe-madrid-1046\n  talks:\n    - title: \"Beyond Meetups: Creating Ruby Ecosystem\"\n      event_name: \"Madrid.rb November 2024\"\n      date: \"2024-11-07\"\n      video_provider: \"not_published\"\n      id: \"madrid-rb-meetup-november-2024-mariusz-koziel\"\n      video_id: \"madrid-rb-meetup-november-2024-mariusz-koziel\"\n      description: \"\"\n      speakers:\n        - Mariusz Kozieł\n\n    - title: 'Code Review Automation: Getting Rid of \"You Forgot To...\" Comments'\n      event_name: \"Madrid.rb November 2024\"\n      date: \"2024-11-07\"\n      video_provider: \"youtube\"\n      id: \"egor-iskrenkov-madridrb-november-2024\"\n      video_id: \"NDlpphmB1VU\"\n      published_at: \"2024-11-26\"\n      description: |-\n        Egor Iskrenkov presentation at the Madrid.rb meetup, which took place on November 7th, 2024.\n\n        ► Find us here:\n\n        Linkedin: https://www.linkedin.com/company/ruby-europe/posts/?feedView=all\n        X: https://x.com/RubyEurope\n      speakers:\n        - Egor Iskrenkov\n\n    - title: \"My LLM is smarter than yours - RAG and Vector Search in Ruby\"\n      event_name: \"Madrid.rb November 2024\"\n      date: \"2024-11-07\"\n      video_provider: \"youtube\"\n      video_id: \"U1iixGneX5w\"\n      published_at: \"2024-11-27\"\n      id: \"madrid-rb-meetup-november-2024-pawel-strzalkowski\"\n      speakers:\n        - Paweł Strzałkowski\n\n# 2025\n\n- id: \"madrid-rb-meetup-january-2025\"\n  title: \"Madrid.rb January 2025\"\n  event_name: \"Madrid.rb January 2025\"\n  date: \"2025-01-30\"\n  video_provider: \"children\"\n  video_id: \"madrid-rb-meetup-january-2025\"\n  description: |-\n    hosted by Josep Egea Sánchez by SNGULAR StageONE (www.sngular.com) - 30.01.2025 at 19:30\n\n    Madrid.rb - January 2025\n\n    https://www.madridrb.com/events/january-2025-solid-queue-internals-externals-and-all-the-things-in-between-1145\n  talks:\n    - title: \"Solid Queue internals, externals and all the things in between\"\n      event_name: \"Madrid.rb January 2025\"\n      date: \"2025-01-30\"\n      video_provider: \"scheduled\"\n      id: \"madrid-rb-meetup-january-2024-rosa-gutierrez\"\n      video_id: \"madrid-rb-meetup-january-2024-rosa-gutierrez\"\n      description: |-\n        We’ve used Resque and Redis to run background jobs in multiple apps for many years at 37signals.\n\n        However, performance, reliability, and our own apps’ idiosyncrasies led us to use a lot of different gems, some developed by us, some forked or patched to address our struggles.\n\n        After multiple war stories with background jobs, looking at our increasingly complex setup, we wanted something we could use out-of-the-box without having to port our collection of hacks to every new app and with fewer moving pieces.\n\n        After exploring existing alternatives, we decided to build our own and aim to make it the default for Rails 8.\n\n        In this talk, I’ll present Solid Queue, explain some of the problems we had over the years, how we designed Solid Queue to address them, and all the Fun™ we had doing that.\n      speakers:\n        - Rosa Gutiérrez\n"
  },
  {
    "path": "data/madrid-rb/series.yml",
    "content": "---\nname: \"Madrid.rb\"\nwebsite: \"https://www.madridrb.com\"\ntwitter: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"ES\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/magic-ruby/magic-ruby-2011/event.yml",
    "content": "---\nid: \"magic-ruby-2011\"\ntitle: \"Magic Ruby 2011\"\nkind: \"conference\"\nlocation: \"Orlando, FL, United States\"\ndescription: \"\"\npublished_at: \"2011-02-05\"\nstart_date: \"2011-02-04\"\nend_date: \"2011-02-05\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2011\nbanner_background: \"#0C1421\"\nwebsite: \"https://web.archive.org/web/20110208061529/http://magic-ruby.com/\"\ncoordinates:\n  latitude: 28.4157423\n  longitude: -81.5985175\n"
  },
  {
    "path": "data/magic-ruby/magic-ruby-2011/venue.yml",
    "content": "# https://web.archive.org/web/20110208061529/http://magic-ruby.com/\n---\nname: \"Disney's Contemporary Resort and Convention Center\"\n\naddress:\n  street: \"4600 World Drive\"\n  city: \" Lake Buena Vista\"\n  region: \"FL\"\n  postal_code: \"32830\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"4600 World Dr, Lake Buena Vista, FL 32830, United States\"\n\ncoordinates:\n  latitude: 28.4157423\n  longitude: -81.5985175\n\nmaps:\n  google: \"https://maps.google.com/?q=Disney's+Contemporary+Resort+and+Convention+Center,28.4148847,-81.57468709999999\"\n  apple: \"https://maps.apple.com/?q=Disney's+Contemporary+Resort+and+Convention+Center&ll=28.4148847,-81.57468709999999\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=28.4148847&mlon=-81.57468709999999\"\n"
  },
  {
    "path": "data/magic-ruby/magic-ruby-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/magic-ruby/magic-ruby-2012/event.yml",
    "content": "---\nid: \"magic-ruby-2012\"\ntitle: \"Magic Ruby 2012\"\nkind: \"conference\"\nlocation: \"Orlando, FL, United States\"\ndescription: \"\"\npublished_at: \"2012-10-05\"\nstart_date: \"2012-10-04\"\nend_date: \"2012-10-05\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2012\nbanner_background: \"repeating-linear-gradient( 90deg, #B16712, #B16712 20px, #AD630E 20px, #AD630E 40px )\"\ncoordinates:\n  latitude: 28.3580628\n  longitude: -81.5616724\n"
  },
  {
    "path": "data/magic-ruby/magic-ruby-2012/venue.yml",
    "content": "---\nname: \"Disney's Hollywood Studios® theme park\"\n\naddress:\n  street: \"\"\n  city: \"Orlando\"\n  region: \"FL\"\n  postal_code: \"34747\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"Bay Lake, FL 34747, USA\"\n\ncoordinates:\n  latitude: 28.3580628\n  longitude: -81.5616724\n\nmaps:\n  google: \"https://maps.google.com/?q=Disney's+Hollywood+Studios®+theme+park,28.3580628,-81.5616724\"\n  apple: \"https://maps.apple.com/?q=Disney's+Hollywood+Studios®+theme+park&ll=28.3580628,-81.5616724\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=28.3580628&mlon=-81.5616724\"\n"
  },
  {
    "path": "data/magic-ruby/magic-ruby-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/magic-ruby/series.yml",
    "content": "---\nname: \"Magic Ruby\"\nwebsite: \"https://magic-ruby.com\"\ntwitter: \"magirubyconf\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Magic Ruby\"\ndefault_country_code: \"US\"\nlanguage: \"english\"\nyoutube_channel_name: \"\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-01/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-01\"\ntitle: \"Matsue RubyKaigi 01\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2009-02-02\"\nend_date: \"2009-02-02\"\nwebsite: \"http://regional.rubykaigi.org/matsue01\"\ncoordinates:\n  latitude: 35.4639783\n  longitude: 133.0622438\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-01/venue.yml",
    "content": "---\nname: \"Matsue Open Source Lab\"\naddress:\n  street: \"478-18 Asahimachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0003\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"478-18 Asahimachi, Matsue, Shimane 690-0003, Japan\"\ncoordinates:\n  latitude: 35.4639783\n  longitude: 133.0622438\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.4639783,133.0622438\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-01/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://regional.rubykaigi.org/matsue01\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-02/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-02\"\ntitle: \"Matsue RubyKaigi 02\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2010-02-13\"\nend_date: \"2010-02-13\"\nwebsite: \"http://regional.rubykaigi.org/matsue02\"\ncoordinates:\n  latitude: 35.4642189\n  longitude: 133.0622036\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-02/venue.yml",
    "content": "---\nname: \"Matsue Tersa\"\naddress:\n  street: \"478-18 Asahimachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0003\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"478-18 Asahimachi, Matsue, Shimane 690-0003, Japan\"\ncoordinates:\n  latitude: 35.4642189\n  longitude: 133.0622036\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.4642189,133.0622036\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-02/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://regional.rubykaigi.org/matsue02\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-03/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-03\"\ntitle: \"Matsue RubyKaigi 03\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2011-07-03\"\nend_date: \"2011-07-03\"\nwebsite: \"http://regional.rubykaigi.org/matsue03\"\ncoordinates:\n  latitude: 35.4642189\n  longitude: 133.0622036\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-03/venue.yml",
    "content": "---\nname: \"Matsue Tersa\"\naddress:\n  street: \"478-18 Asahimachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0003\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"478-18 Asahimachi, Matsue, Shimane 690-0003, Japan\"\ncoordinates:\n  latitude: 35.4642189\n  longitude: 133.0622036\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.4642189,133.0622036\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-03/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://regional.rubykaigi.org/matsue03\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-04/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-04\"\ntitle: \"Matsue RubyKaigi 04\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2012-09-01\"\nend_date: \"2012-09-01\"\nwebsite: \"http://regional.rubykaigi.org/matsue04\"\ncoordinates:\n  latitude: 35.4642189\n  longitude: 133.0622036\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-04/venue.yml",
    "content": "---\nname: \"Matsue Tersa\"\naddress:\n  street: \"478-18 Asahimachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0003\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"478-18 Asahimachi, Matsue, Shimane 690-0003, Japan\"\ncoordinates:\n  latitude: 35.4642189\n  longitude: 133.0622036\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.4642189,133.0622036\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-04/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://regional.rubykaigi.org/matsue04\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-05/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-05\"\ntitle: \"Matsue RubyKaigi 05\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2014-03-15\"\nend_date: \"2014-03-15\"\nwebsite: \"https://matsue.rubyist.net/matrk05/\"\nfeatured_background: \"#eb1d15\"\nfeatured_color: \"#ffffff\"\nbanner_background: \"#eb1d15\"\ncoordinates:\n  latitude: 35.4639783\n  longitude: 133.0622438\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-05/venue.yml",
    "content": "---\nname: \"Matsue Open Source Lab\"\naddress:\n  street: \"478-18 Asahimachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0003\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"478-18 Asahimachi, Matsue, Shimane 690-0003, Japan\"\ncoordinates:\n  latitude: 35.4639783\n  longitude: 133.0622438\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.4639783,133.0622438\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-05/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://matsue.rubyist.net/matrk05/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-06/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-06\"\ntitle: \"Matsue RubyKaigi 06\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2014-12-20\"\nend_date: \"2014-12-20\"\nwebsite: \"https://matsue.rubyist.net/matrk06/\"\nfeatured_background: \"#eb1d15\"\nfeatured_color: \"#ffffff\"\nbanner_background: \"#eb1d15\"\ncoordinates:\n  latitude: 35.4639783\n  longitude: 133.0622438\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-06/venue.yml",
    "content": "---\nname: \"Matsue Open Source Lab\"\naddress:\n  street: \"478-18 Asahimachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0003\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"478-18 Asahimachi, Matsue, Shimane 690-0003, Japan\"\ncoordinates:\n  latitude: 35.4639783\n  longitude: 133.0622438\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.4639783,133.0622438\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-06/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://matsue.rubyist.net/matrk06/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-07/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-07\"\ntitle: \"Matsue RubyKaigi 07\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2015-09-26\"\nend_date: \"2015-09-26\"\nwebsite: \"https://matsue.rubyist.net/matrk07/\"\nfeatured_background: \"#eb1d15\"\nfeatured_color: \"#ffffff\"\nbanner_background: \"#eb1d15\"\ncoordinates:\n  latitude: 35.4642189\n  longitude: 133.0622036\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-07/venue.yml",
    "content": "---\nname: \"Matsue Tersa\"\naddress:\n  street: \"478-18 Asahimachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0003\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"478-18 Asahimachi, Matsue, Shimane 690-0003, Japan\"\ncoordinates:\n  latitude: 35.4642189\n  longitude: 133.0622036\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.4642189,133.0622036\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-07/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://matsue.rubyist.net/matrk07/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-08/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-08\"\ntitle: \"Matsue RubyKaigi 08\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2016-12-17\"\nend_date: \"2016-12-17\"\nwebsite: \"https://matsue.rubyist.net/matrk08/\"\nfeatured_background: \"#eb1d15\"\nfeatured_color: \"#ffffff\"\nbanner_background: \"#eb1d15\"\ncoordinates:\n  latitude: 35.4642189\n  longitude: 133.0622036\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-08/venue.yml",
    "content": "---\nname: \"Matsue Tersa\"\naddress:\n  street: \"478-18 Asahimachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0003\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"478-18 Asahimachi, Matsue, Shimane 690-0003, Japan\"\ncoordinates:\n  latitude: 35.4642189\n  longitude: 133.0622036\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.4642189,133.0622036\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-08/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://matsue.rubyist.net/matrk08/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-09/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-09\"\ntitle: \"Matsue RubyKaigi 09\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2018-06-30\"\nend_date: \"2018-06-30\"\nwebsite: \"https://matsue.rubyist.net/matrk09/\"\nfeatured_background: \"#eb1d15\"\nfeatured_color: \"#ffffff\"\nbanner_background: \"#eb1d15\"\ncoordinates:\n  latitude: 35.4639783\n  longitude: 133.0622438\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-09/venue.yml",
    "content": "---\nname: \"Matsue Open Source Lab\"\naddress:\n  street: \"478-18 Asahimachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0003\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"478-18 Asahimachi, Matsue, Shimane 690-0003, Japan\"\ncoordinates:\n  latitude: 35.4639783\n  longitude: 133.0622438\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.4639783,133.0622438\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-09/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://matsue.rubyist.net/matrk09/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-10/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-10\"\ntitle: \"Matsue RubyKaigi 10\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2023-09-16\"\nend_date: \"2023-09-16\"\nwebsite: \"https://matsue.rubyist.net/matrk10/\"\nfeatured_background: \"#eb1d15\"\nfeatured_color: \"#ffffff\"\nbanner_background: \"#eb1d15\"\ncoordinates:\n  latitude: 35.4639783\n  longitude: 133.0622438\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-10/venue.yml",
    "content": "---\nname: \"Matsue Open Source Lab\"\naddress:\n  street: \"478-18 Asahimachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0003\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"478-18 Asahimachi, Matsue, Shimane 690-0003, Japan\"\ncoordinates:\n  latitude: 35.4639783\n  longitude: 133.0622438\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.4639783,133.0622438\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-10/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://matsue.rubyist.net/matrk10/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-11/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-11\"\ntitle: \"Matsue RubyKaigi 11\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2024-10-05\"\nend_date: \"2024-10-05\"\nwebsite: \"https://matsue.rubyist.net/matrk11/\"\nfeatured_background: \"#eb1d15\"\nfeatured_color: \"#ffffff\"\nbanner_background: \"#eb1d15\"\ncoordinates:\n  latitude: 35.4681908\n  longitude: 133.0484055\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-11/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://matsue.rubyist.net/matrk11/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-12/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://forms.gle/eah7Wb7BzZyZ9mUq8\"\n  open_date: \"2026-01-21\"\n  close_date: \"2026-03-31\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-12/event.yml",
    "content": "---\nid: \"matsue-rubykaigi-12\"\ntitle: \"Matsue RubyKaigi 12\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2026-06-06\"\nend_date: \"2026-06-06\"\nwebsite: \"https://matsue.rubyist.net/matrk12/\"\nfeatured_background: \"#eb1d15\"\nfeatured_color: \"#ffffff\"\nbanner_background: \"#eb1d15\"\ncoordinates:\n  latitude: 35.473575\n  longitude: 133.0504452\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-12/venue.yml",
    "content": "---\nname: \"Kounkaku\"\nurl: \"https://www.matsue-castle.jp/kounkaku/\"\naddress:\n  street: \"1-59 Tonomachi\"\n  city: \"Matsue\"\n  region: \"Shimane\"\n  postal_code: \"690-0887\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"1-59 Tonomachi, Matsue, Shimane 690-0887, Japan\"\ncoordinates:\n  latitude: 35.473575\n  longitude: 133.0504452\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.473575,133.0504452\"\n"
  },
  {
    "path": "data/matsue-rubykaigi/matsue-rubykaigi-12/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://matsue.rubyist.net/matrk12/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/matsue-rubykaigi/series.yml",
    "content": "---\nname: \"Matsue RubyKaigi\"\nwebsite: \"https://matsue.rubyist.net/\"\ntwitter: \"matsuerb\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\nyoutube_channel_name: \"\"\nyoutube_channel_id: \"\"\nplaylist_matcher: \"\"\naliases:\n  - \"松江Ruby会議\"\n"
  },
  {
    "path": "data/merseyrails/merseyrails/event.yml",
    "content": "---\nid: \"merseyrails\"\ntitle: \"MerseyRails Meetup\"\nkind: \"meetup\"\nlocation: \"Liverpool, UK\"\ndescription: |-\n  We are a community of full stack Ruby on Rails developers who believe in a better way to build web-based software; one that's simple, productive, and joyful.\n\n  We know that great software doesn't have to be cobbled together with countless libraries, volatile dependencies and spread across a dozen microservices. Rails offers a powerful, elegant alternative and we’re here to make the most of it.\n\n  Whether you're working on your own side project, learning Rails for the first time, or looking for a break from the complexity of modern frontend-heavy stacks; you’ve found your people.\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#212519\"\nwebsite: \"https://merseyrails.com\"\ncoordinates:\n  latitude: 53.4083714\n  longitude: -2.9915726\n"
  },
  {
    "path": "data/merseyrails/merseyrails/videos.yml",
    "content": "---\n- id: \"merseyrails-meetup-june-2025\"\n  title: \"MerseyRails Meetup June 2025\"\n  raw_title: \"MerseyRails Meetup June 2025\"\n  event_name: \"MerseyRails Meetup June 2025\"\n  date: \"2025-06-03\"\n  published_at: \"\"\n  announced_at: \"2025-05-26 15:53:00 UTC\"\n  description: |-\n    Join us for the inaugural meetup on 3rd June 2025\n  video_provider: \"scheduled\"\n  video_id: \"merseyrails-meetup-june-2025\"\n  talks: []\n"
  },
  {
    "path": "data/merseyrails/series.yml",
    "content": "---\nname: \"MerseyRails\"\nwebsite: \"https://merseyrails.com\"\ntwitter: \"therubyhound\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"UK\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/montreal-rb/montreal-rb-meetup/event.yml",
    "content": "---\nid: \"PLRAf4zt5oEjc2mqmEN9m_O0JovQCXxvxt\"\ntitle: \"Montreal.rb Meetup\"\nkind: \"meetup\"\nlocation: \"Montréal, Canada\"\ndescription: |-\n  Montreal.rb talks managed at https://www.meetup.com/montrealrb\npublished_at: \"2023-05-04\"\nchannel_id: \"UCVGtTNLJjB35j-RgD62B9Zw\"\nyear: 2024\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 45.5018869\n  longitude: -73.56739189999999\n"
  },
  {
    "path": "data/montreal-rb/montreal-rb-meetup/videos.yml",
    "content": "---\n- id: \"andy-maleh-montrealrb-meetup-july-2022\"\n  title: \"How I Built My Code Editor in Ruby\"\n  raw_title: \"How I Built My Code Editor in Ruby by Andy Maleh (Montreal.rb Ruby Talk 2022/07)\"\n  speakers:\n    - Andy Maleh\n  event_name: \"Montreal.rb Meetup July 2022\"\n  date: \"2022-07-06\"\n  published_at: \"2022-07-09\"\n  slides_url: \"https://www.slideshare.net/AndyMaleh/how-i-built-my-code-editor-in-ruby\"\n  description: |-\n    Gladiator is a code editor that was built completely in Ruby. It supports syntax highlighting for over 30 programming languages, split pane, file name lookup, a variety of keyboard shortcuts, undo/redo, find and replace, line jumping, monitoring external file system changes, ignoring uneditable files, expanding to fill the screen, running Ruby code, remembering the last open files, and multi-project support. In fact, I have been using Gladiator for all my code editing needs since May of 2020.\n\n    In this talk, I will present Gladiator's features, and then dig into the implementation of every feature in Ruby, covering things like the Model-View-Controller and Model-View-Presenter architectural patterns, how to build custom widgets, how to implement file editing commands, and how to support undo/redo.\n\n    Attendees should walk out of this talk with rudimentary knowledge of how to build a code editor in Ruby.\n\n    Related links:\n\n    Gladiator: https://github.com/AndyObtiva/glimmer-cs-gladiator\n    Glimmer DSL for SWT: https://github.com/AndyObtiva/glimmer-dsl-swt\n    Glimmer Process: https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md\n  video_provider: \"youtube\"\n  video_id: \"PdH1GtEMJi8\"\n  additional_resources:\n    - name: \"Gladiator\"\n      type: \"repo\"\n      url: \"https://github.com/AndyObtiva/glimmer-cs-gladiator\"\n\n    - name: \"Glimmer DSL for SWT\"\n      type: \"repo\"\n      url: \"https://github.com/AndyObtiva/glimmer-dsl-swt\"\n\n    - name: \"Glimmer Process\"\n      type: \"repo\"\n      url: \"https://github.com/AndyObtiva/glimmer/blob/master/PROCESS.md\"\n\n- id: \"andy-maleh-montrealrb-meetup-october-2022\"\n  title: \"Glimmer DSL for SWT Ruby Desktop Development GUI Framework\"\n  raw_title: \"Glimmer DSL for SWT Ruby Desktop Development GUI Framework by Andy Maleh (Montreal.rb Talk 2022/10)\"\n  speakers:\n    - Andy Maleh\n  event_name: \"Montreal.rb Meetup October 2022\"\n  date: \"2022-10-05\"\n  published_at: \"2022-10-10\"\n  slides_url: \"https://docs.google.com/presentation/d/e/2PACX-1vQPN1MXcnIMcY5ptEp6EgNTiwouSE_3gneaFbZB6Sq-cKlSBQX17kari2LrXvSMtapSSm_Ws-dHcdo_/pub?start=false&loop=false&delayms=60000\"\n  description: |-\n    Resources:\n    - Project: https://github.com/AndyObtiva/glimmer-dsl-swt\n    - GitHub: https://github.com/AndyObtiva\n    - Blog: https://andymaleh.blogspot.com\n    - Twitter: https://twitter.com/AndyObtiva\n\n  video_provider: \"youtube\"\n  video_id: \"oIHzdwfQDoQ\"\n  additional_resources:\n    - name: \"AndyObtiva/glimmer-dsl-swt\"\n      type: \"repo\"\n      url: \"https://github.com/AndyObtiva/glimmer-dsl-swt\"\n\n- id: \"andy-maleh-montrealrb-meetup-april-2023\"\n  title: \"Rails Already Supports View Components!\"\n  raw_title: \"Rails Already Supports View Components! by Andy Maleh (Montreal.rb Ruby Talk 2023/04)\"\n  speakers:\n    - Andy Maleh\n  event_name: \"Montreal.rb Meetup April 2023\"\n  date: \"2023-04-05\"\n  published_at: \"2023-08-18\"\n  slides_url: \"https://docs.google.com/presentation/d/e/2PACX-1vQowSZBS309iZ7NMKl7HJrv-_hNea2_UAsk6nJmUrrpQ-R8FAE-azg7AMZARm4roDEsIKF3n3YpX0rK/pub?start=false&loop=false&delayms=60000\"\n  description: |-\n    There are several view component Ruby gems out there that were created and used by Rails developers in order to decompose application views into view components. Little did they know, Rails already supports view components!!! This talk will explain the various ways Rails already supports view components out of the box. And as part of that, it will demonstrate that the built-in Rails view component options are simpler, more Rails-idiomatic, and more conformant to the MVC pattern (Model-View-Controller). As such, they offer higher maintainability and productivity by avoiding the big great evil of Over-Engineering and NIH-Syndrome (Not Invented Here).\n  video_provider: \"youtube\"\n  video_id: \"9aT_ATtends\"\n\n- id: \"miller-levert-montrealrb-meetup-may-2023\"\n  title: \"Integrating with REST APIs using Microsoft Kiota\"\n  raw_title: \"Integrating with REST APIs using Microsoft Kiota by Miller & Levert (Montreal.rb Ruby Talk 2023/05)\"\n  speakers:\n    - Miller Levert\n  event_name: \"Montreal.rb Meetup May 2023\"\n  date: \"2023-05-03\"\n  published_at: \"2023-05-04\"\n  description: |-\n    Montreal.rb Ruby Talk 2023/05 - Integrating with REST APIs using Microsoft Kiota - Darrel Miller, Microsoft Graph API Architect, Microsoft & Sébastien Levert, Senior Product Manager, Microsoft\n\n    Your application integration with 3rd party APIs can be difficult if your application platform does not offer SDKs for calling the APIs. Implementation of authentication, authorization, serialization, and exception handling for calling APIs adds a lot of work and risk to your project. Join us for a session filled with demos that showcase how to generate your own personalized SDK client for a complete OpenAPI spec in multiple programming languages with the help of Microsoft Kiota. By using your new personalized client that is generated by Kiota, all the complex aspects of calling APIs get handled for you automatically so that you could concentrate on what really counts: creating value for your end users.\n  video_provider: \"youtube\"\n  video_id: \"bCox68tBVMw\"\n\n- id: \"andy-maleh-montrealrb-meetup-july-2023\"\n  title: \"Import Spreadsheets in Ruby on Rails with Flatfile.com\"\n  raw_title: \"Import Spreadsheets in Ruby on Rails with Flatfile.com by Andy Maleh (Montreal.rb Ruby Talk 2023/07)\"\n  speakers:\n    - Andy Maleh\n  event_name: \"Montreal.rb Meetup July 2023\"\n  date: \"2023-07-05\"\n  published_at: \"2023-07-06\"\n  slides_url: \"https://docs.google.com/presentation/d/e/2PACX-1vSjaB33oBW6z0NUD3GYqv1KPoX9gwHSiJSXZAbEbnSls0xftX2HmCcICmihhiBVkU-YbrB_NyUF4xvK/pub?start=false&loop=false&delayms=60000\"\n  description: |-\n    Software systems require input in order to compute data and produce output. And, one of the ways to provide input to a software system is by uploading a flat file that contains information about various entities (e.g customers or products) in the form of a spreadsheet, following the CSV or XLSX format.\n\n    In order for a software system to properly accept a spreadsheet file as input and effectively process it into output, it usually needs to map spreadsheet columns to entity attributes to store the data in a database. And, often, there is a requirement to validate the data before accepting it (e.g. ensure a column value is within a certain range), and to apply transformations to the data before storing on records in the database. That is in addition to performance, security, usability, and reliability non-functional requirements that ensure that a user could upload a spreadsheet quickly enough while seeing progress indicators in a user-friendly experience and getting their data processed and transformed in the backend without any data loss.\n\n    Enter Flatfile.com! A SAAS product (Software As A Service) that automates the handling of all the concerns and requirements mentioned above and more in a Ruby on Rails web application.\n\n    This talk will provide a brief overview of the Flatfile.com SAAS product features while demonstrating a real world example of using it in a Ruby on Rails web application.\n  video_provider: \"youtube\"\n  video_id: \"Du2crnz2PLg\"\n\n- id: \"andy-maleh-montrealrb-meetup-september-2023\"\n  title: \"Intro to Ruby in the Browser\"\n  raw_title: \"Intro to Ruby in the Browser by Andy Maleh (Montreal.rb Ruby Talk 2023/09)\"\n  speakers:\n    - Andy Maleh\n  event_name: \"Montreal.rb Meetup September 2023\"\n  date: \"2023-09-06\"\n  published_at: \"2023-09-07\"\n  slides_url: \"https://docs.google.com/presentation/d/e/2PACX-1vRWAklgMdwrRPWDi1Y2wpG3ajENBNVCMpmM3NL4HevMM3bv4gbTy8osTHxz_wRudkvf4iQIs1m-y4nM/pub?start=false&loop=false&delayms=3000\"\n  description: |-\n    Matz mentioned in his RubyConf 2022 keynote speech that in the future of Ruby, maybe we could start replacing JavaScript with Ruby in the browser. Especially given that today, we have new options like Ruby WASM and Opal Ruby (Fukuoka Ruby 2023 Winner: https://opalrb.com/blog/2023/03/30/opal-won-fukuoka-ruby-award-for-outstanding-performance/ ), as demonstrated by the TryRuby Playground on Ruby's home page. Using them will achieve the ultimate dream of being able to write Ruby code on both the frontend and backend, resulting in great software engineering benefits such as better code maintainability and higher productivity. That said, how do we get started with Ruby in the browser in a Rails app? What are the trade-offs compared to using JavaScript? How do we make frontend Ruby talk to backend Ruby while reusing some of its Ruby code? This talk will help Ruby on Rails software engineers get started with Ruby in the browser while providing demos along the way via an actual Rails app.\n  video_provider: \"youtube\"\n  video_id: \"4AdcfbI6A4c\"\n\n- id: \"parham-ashraf-montrealrb-meetup-october-2023\"\n  title: \"Elevate Your RoR Views w/ ViewComponent & Lookbook\"\n  raw_title: \"Elevate Your RoR Views w/ ViewComponent & Lookbook by Parham Ashraf (Montreal.rb Ruby Talk 2023/10)\"\n  speakers:\n    - Parham Ashraf\n  event_name: \"Montreal.rb Meetup October 2023\"\n  date: \"2023-10-04\"\n  published_at: \"2023-11-03\"\n  slides_url: \"https://docs.google.com/presentation/d/e/2PACX-1vT7VOxx52eP14BSz8YO5vFGUfMyKaa0mWMFrn_vzx239YalKZPuhKkFGAJCzWGXemiEfLYLN5pn6k94/pub?start=false&loop=false&delayms=60000\"\n  description: |-\n    In the ever-evolving landscape of web development, providing a seamless user experience is paramount. Ruby on Rails has been a steadfast choice for building web applications, but as our applications grow in complexity, so do our views and the challenges associated with them. In this presentation, we'll explore two powerful tools that can significantly improve your Rails views: ViewComponent and Lookbook. By the end of this session, you'll be well-equipped to incorporate ViewComponent and Lookbook into your Rails projects, leveraging generators, slots, collections, and visual design to create more efficient, modular, and visually appealing web applications.\n  video_provider: \"youtube\"\n  video_id: \"vyO07H8chUE\"\n\n- id: \"michel-jamati-montrealrb-meetup-november-2023\"\n  title: \"Anatomy of a Payment\"\n  raw_title: \"Anatomy of a Payment by Michel Jamati (Montreal.rb Ruby Talk 2023/11)\"\n  speakers:\n    - Michel Jamati\n  event_name: \"Montreal.rb Meetup November 2023\"\n  date: \"2023-11-01\"\n  published_at: \"2023-11-08\"\n  slides_url: \"https://docs.google.com/presentation/d/e/2PACX-1vRbkntSxjQa_vZvVl5lvnkLbHvkObHZ_CJq_jVflq1I0w_zi7X5D0lSSPvTqYotszuSELzKzt83dK23/pub?start=false&loop=false&delayms=3000\"\n  description: |-\n    This talk will provide an overview of the business payment world. Attendees will become familiar with the actors and economics of the payment ecosystem, learn about the major regulations in the payment space that need to be complied with, and understand the Lexop approach to navigating these different challenges. Ruby on Rails examples will be demonstrated along the way to illustrate various types of payments that can be made with different payment processors.\n  video_provider: \"youtube\"\n  video_id: \"tbkVH0q3Vik\"\n\n- id: \"andrei-bondarev-montrealrb-meetup-december-2023\"\n  title: \"Building LLM powered Applications\"\n  raw_title: \"Building LLM powered Applications by Andrei Bondarev (Montreal.rb Ruby Talk 2023/12)\"\n  speakers:\n    - Andrei Bondarev\n  event_name: \"Montreal.rb Meetup December 2023\"\n  date: \"2023-12-06\"\n  published_at: \"2023-12-09\"\n  description: |-\n    Montreal.rb Ruby Talk 2023/12 - Building LLM powered Applications - Andrei Bondarev - Solutions Architect / Owner at Source Labs LLC\n\n    The 2023 breakthroughs in Generative AI (Artificial Intelligence) have been taking the software development world by storm. We'll take a look at a few components of what is quickly becoming the modern stack for building LLM (Large Language Model) powered applications. Andrei will build a case for Ruby in the emerging AI trend, and show how some of the AI capabilities can be leveraged today!\n  video_provider: \"youtube\"\n  video_id: \"KQlgWT6y5QY\"\n\n- id: \"jean-sebastien-boulanger-montrealrb-meetup-january-2024\"\n  title: \"Building an AI Medical Scribe in Ruby\"\n  raw_title: \"Building an AI Medical Scribe in Ruby by Jean-Sebastien Boulanger (Montreal.rb Ruby Talk 2024/01)\"\n  speakers:\n    - Jean-Sebastien Boulanger\n  event_name: \"Montreal.rb Meetup January 2024\"\n  date: \"2024-01-10\"\n  published_at: \"2024-01-12\"\n  description: |-\n    Montreal.rb Ruby Talk 2024/01 - Building an AI Medical Scribe in Ruby - Jean-Sebastien Boulanger - CTO of Circle Medical\n\n    In this talk, I'll share insights from our experience creating an AI medical scribe using Ruby at Circle Medical (https://www.circlemedical.com/), a hybrid primary care provider seeing over 50,000 patients monthly. We leveraged Large Language Models (LLMs) to create a scribe to enhance clinical documentation and save doctors' time.\n  video_provider: \"youtube\"\n  video_id: \"BJwILlX0svw\"\n\n- id: \"andy-maleh-montrealrb-meetup-march-2024\"\n  title: \"Frontend Ruby with Glimmer DSL for Web\"\n  raw_title: \"Frontend Ruby with Glimmer DSL for Web by Andy Maleh (Montreal.rb Ruby Talk 2024/03)\"\n  speakers:\n    - Andy Maleh\n  event_name: \"Montreal.rb Meetup March 2024\"\n  date: \"2024-03-06\"\n  published_at: \"2024-03-07\"\n  slides_url: \"https://docs.google.com/presentation/d/e/2PACX-1vQVihtMktOEJ-AJWb1a-uyJfpyn7q92xstcx7QLIUOFONzG5TmKD7_2hSLdwijgw-l6LdK6OLbQPP61/pub?start=false&loop=false&delayms=60000\"\n  description: |-\n    Montreal.rb Ruby Talk 2024/03 - Frontend Ruby with Glimmer DSL for Web - Andy Maleh - Senior Software Engineer at Lexop\n\n    GitHub: https://github.com/AndyObtiva/glimmer-dsl-web\n\n    Rubyists would rather leverage the productivity, readability, and maintainability benefits of Ruby in Frontend Web Development than JavaScript to cut down development cost and time by half compared to using popular yet inferior JavaScript frameworks with bloated JavaScript code as per Matz's suggestion in his RubyConf 2022 keynote speech to replace JavaScript with Ruby. Fortunately, this is possible in 2024!\n\n    This talk is a continuation of the previous Montreal.rb talk \"Intro to Ruby in the Browser\", which ended by promising a new way in the future for developing Web Frontends that would completely revolutionize the way we think about and do Frontend Development using Ruby instead of JavaScript. The future is now!!! The simplest, most intuitive, most straight-forward, and most productive Frontend Framework in existence is here! It is an open-source Ruby gem called Glimmer DSL for Web.\n\n    Think of Glimmer DSL for Web as the Rails of Frontend Frameworks. With it, you can finally live in Rubyland in both the Frontend and Backend on the Web! That opens up the door to ideas like rendering Frontend Components in the Backend as Server Components in the future, eliminating the conflict between ERB and JS frontend rendering technologies by leveraging highly readable, maintainable, and productive Ruby code isomorphically.\n\n  video_provider: \"youtube\"\n  video_id: \"rIZ-ILUv9ME\"\n  additional_resources:\n    - name: \"AndyObtiva/glimmer-dsl-web\"\n      type: \"repo\"\n      url: \"https://github.com/AndyObtiva/glimmer-dsl-web\"\n\n- id: \"jrme-parent-lvesque-montrealrb-meetup-april-2024\"\n  title: \"React Server Components... in Rails?\"\n  raw_title: \"React Server Components... in Rails? by Jérôme Parent-Lévesque (Montreal.rb Ruby Talk 2024/04)\"\n  speakers:\n    - Jérôme Parent-Lévesque\n  event_name: \"Montreal.rb Meetup April 2024\"\n  date: \"2024-04-03\"\n  published_at: \"2024-04-15\"\n  slides_url: \"https://docs.google.com/presentation/d/1zikF4SZL7M9yXl-r_ANuY6lDMSOuR5IYqWqdqu7Z3DA/edit#slide=id.p\"\n  description: |-\n    Montreal.rb Ruby Talk 2024/04 - React Server Components... in Rails? - Jérôme Parent-Lévesque - Engineering Lead at Potloc\n\n    React Server Components are the next milestone in the React core team's initiative to ease web development (and are the hot new thing!). They aim to greatly improve the user experience by lowering the number of roundtrips necessary between the client and server and by streaming data as soon as it becomes available. However, they are currently only usable in the Next.js framework with a Node backend... But couldn't we mimic what this backend does in Rails and leverage this to modernize React development in Rails?\n\n    In this talk we will explain some of the inner workings of React Server Components, their benefits and how they can be implemented in any backend.\n  video_provider: \"youtube\"\n  video_id: \"SekchVgLuuo\"\n\n- id: \"helmer-davila-montrealrb-meetup-may-2024\"\n  title: \"Hotwire Turbo in Rails: Drive, Frames and Streams\"\n  raw_title: \"Hotwire Turbo in Rails: Drive, Frames and Streams by Helmer Davila (Montreal.rb Ruby Talk 2024/05)\"\n  speakers:\n    - Helmer Davila\n  event_name: \"Montreal.rb Meetup May 2024\"\n  date: \"2024-05-01\"\n  published_at: \"2024-10-13\"\n  description: |-\n    Montreal.rb Ruby Talk 2024/05 - Hotwire Turbo in Rails: Drive, Frames and Streams - Helmer Davila - Senior Software Developer\n\n    In this talk, we will be exploring Hotwire Turbo in Rails, focusing specifically on Drive, Frames, and Streams. We will dive deep into how Hotwire Turbo enhances the speed and performance of Rails applications, providing users with a smoother and more interactive experience. We will also shed light on the concepts of Drive, Frames, and Streams, discussing their roles and how they contribute to the overall functionality of a Rails application. Whether you're a seasoned Rails developer or just getting started, this talk will offer valuable insights into optimizing your applications with Hotwire Turbo.\n  video_provider: \"youtube\"\n  video_id: \"rmsBVsZUHzI\"\n\n- id: \"david-cornu-montrealrb-meetup-october-2024\"\n  title: \"Tame Complex Queries with Database Views\"\n  raw_title: \"Tame Complex Queries with Database Views by David Cornu  (Montreal.rb Ruby Talk 2024/10)\"\n  speakers:\n    - David Cornu\n  event_name: \"Montreal.rb Meetup October 2024\"\n  date: \"2024-10-02\"\n  published_at: \"2024-10-03\"\n  slides_url: \"https://davidcornu.github.io/views-demo/\"\n  description: |-\n    Montreal.rb Ruby Talk 2024/10 - Tame Complex Queries with Database Views by David Cornu - David Cornu - Staff Developer at Patch.io\n\n    PostgreSQL views are a useful tool to make query logic reusable and maintainable. This talk will cover their pros and cons, a couple of real-world use cases, and how to use them in Rails apps using the Scenic gem.\n\n    GitHub Repo: https://github.com/davidcornu/views-demo\n  video_provider: \"youtube\"\n  video_id: \"gdrscLBNvDo\"\n  additional_resources:\n    - name: \"davidcornu/views-demo\"\n      type: \"repo\"\n      url: \"https://github.com/davidcornu/views-demo\"\n# TODO: Missing event: https://www.meetup.com/montrealrb/events/303804858\n# TODO: Missing event: https://www.meetup.com/montrealrb/events/304095501\n- id: \"montreal-rb-ruby-version-managers-in-2026\"\n  title: \"Ruby Version Managers in 2026\"\n  date: \"2026-04-15\"\n  video_id: \"montreal-rb-ruby-version-managers-in-2026\"\n  video_provider: \"children\"\n  description: |-\n    It is often useful to install more than one Ruby version on one's machine, whether to explore newer Ruby versions before committing to them on a Rails project, or to support multiple Rails projects running on multiple Rubies. Additionally, being able to scope gems by a Ruby project can be very helpful in ensuring the safety of running a Ruby app in complete isolation from other Ruby apps. The Ruby ecosystem contains multiple Ruby Version Managers that help with installing Ruby and scoping Ruby gems by project. This talk will cover the common Ruby Version Manager options in 2025, such as RVM, RBENV, CHRUBY, and ASDF.\n\n    https://www.meetup.com/montrealrb/events/312488656/\n  talks: []\n"
  },
  {
    "path": "data/montreal-rb/series.yml",
    "content": "---\nname: \"Montreal.rb\"\nwebsite: \"https://www.meetup.com/montrealrb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"Montreal.rb\"\ndefault_country_code: \"CA\"\nyoutube_channel_name: \"montreal-rb\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCVGtTNLJjB35j-RgD62B9Zw\"\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2007/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyadeTFH6784Vclvaco-HCIB\"\ntitle: \"MountainWest RubyConf 2007\"\nkind: \"conference\"\nlocation: \"Salt Lake City, UT, United States\"\ndescription: \"\"\nstart_date: \"2007-03-16\"\nend_date: \"2007-03-17\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2007\nwebsite: \"https://web.archive.org/web/20160331211609/http://mtnwestrubyconf.org/2007/\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2007/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"charles-nutter-mountainwest-rubyconf-2007\"\n  title: \"JRuby: Not Just Another Ruby Implementation\"\n  raw_title: \"MWRC 2007 - JRuby: Not Just Another Ruby Implementation by Charles Nutter and Thomas Enebo\"\n  speakers:\n    - Charles Nutter\n    - Thomas E Enebo\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"vF0xwYBD9mI\"\n  thumbnail_lg: \"https://img.youtube.com/vi/vF0xwYBD9mI/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/vF0xwYBD9mI/hqdefault.jpg\"\n\n- id: \"gregory-brown-mountainwest-rubyconf-2007\"\n  title: \"Pragmatic Community Driven Development in Ruby\"\n  raw_title: \"Pragmatic Community Driven Development in Ruby by Gregory Brown - MWRC 2007\"\n  speakers:\n    - Gregory Brown\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3pE9ty6V8-c\"\n  thumbnail_lg: \"https://img.youtube.com/vi/3pE9ty6V8-c/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/3pE9ty6V8-c/hqdefault.jpg\"\n\n- id: \"carl-youngblood-mountainwest-rubyconf-2007\"\n  title: \"Simple Bayesian Networks with Ruby\"\n  raw_title: \"MWRC 2007 - Simple Bayesian Networks with Ruby by Carl Youngblood\"\n  speakers:\n    - Carl Youngblood\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"tEVvpRMhJHk\"\n  thumbnail_lg: \"https://img.youtube.com/vi/tEVvpRMhJHk/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/tEVvpRMhJHk/hqdefault.jpg\"\n\n- id: \"john-lam-mountainwest-rubyconf-2007\"\n  title: \"Panel: Ruby Implementers\"\n  raw_title: \"MWRC 2007 - Ruby Implementers Panel\"\n  speakers:\n    - John Lam\n    - Thomas E Enebo\n    - Charles Nutter\n    - Evan Phoenix\n    - Kevin Tew\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Q1sX4h0DIKQ\"\n  thumbnail_lg: \"https://img.youtube.com/vi/Q1sX4h0DIKQ/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/Q1sX4h0DIKQ/hqdefault.jpg\"\n\n- id: \"jeff-barczewski-mountainwest-rubyconf-2007\"\n  title: \"Masterview\"\n  raw_title: \"Masterview by Jeff Barczewski - MWRC 2007\"\n  speakers:\n    - Jeff Barczewski\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"bh3VYzkdcfo\"\n  thumbnail_lg: \"https://img.youtube.com/vi/bh3VYzkdcfo/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/bh3VYzkdcfo/hqdefault.jpg\"\n\n- id: \"james-britt-mountainwest-rubyconf-2007\"\n  title: \"Black-boxing with Ruby\"\n  raw_title: \"Black-boxing with Ruby by James Britt - MWRC 2007\"\n  speakers:\n    - James Britt\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"7iCdrDFh6oU\"\n  thumbnail_lg: \"https://img.youtube.com/vi/7iCdrDFh6oU/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/7iCdrDFh6oU/hqdefault.jpg\"\n\n- id: \"lightning-talks-mountainwest-rubyconf-2007\"\n  title: \"Lightning Talks\"\n  raw_title: \"MWRC 2007 - Lightning Talks by Various Presenters\"\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"EmELW0e9Y5A\"\n  thumbnail_lg: \"https://img.youtube.com/vi/EmELW0e9Y5A/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/EmELW0e9Y5A/hqdefault.jpg\"\n  talks:\n    - title: \"Lightning Talk: BinaryLottery\"\n      start_cue: \"00:07\"\n      end_cue: \"03:48\"\n      id: \"mike-moore-lighting-talk-mountainwest-rubyconf-2007\"\n      video_id: \"mike-moore-lighting-talk-mountainwest-rubyconf-2007\"\n      video_provider: \"parent\"\n      speakers:\n        - Mike Moore\n\n    - title: \"Lightning Talk: WAX - Web Application X\"\n      start_cue: \"03:48\"\n      end_cue: \"10:35\"\n      id: \"dan-fitzpatrick-lighting-talk-mountainwest-rubyconf-2007\"\n      video_id: \"dan-fitzpatrick-lighting-talk-mountainwest-rubyconf-2007\"\n      video_provider: \"parent\"\n      speakers:\n        - Dan Fitzpatrick\n\n    - title: \"Lightning Talk: Managing SSH keys with Capistrano - or - How my life is easier thanks to Jamis Buck\"\n      start_cue: \"10:35\"\n      end_cue: \"13:34\"\n      id: \"jade-meskill-lighting-talk-mountainwest-rubyconf-2007\"\n      video_id: \"jade-meskill-lighting-talk-mountainwest-rubyconf-2007\"\n      video_provider: \"parent\"\n      speakers:\n        - Jade Meskill\n\n    - title: \"Lightning Talk: Kobe Rehnquist\"\n      start_cue: \"13:34\"\n      end_cue: \"20:17\"\n      id: \"kobe-rehnquist-lighting-talk-mountainwest-rubyconf-2007\"\n      video_id: \"kobe-rehnquist-lighting-talk-mountainwest-rubyconf-2007\"\n      video_provider: \"parent\"\n      speakers:\n        - Kobe Rehnquist # TODO: missing talk title\n\n    - title: \"Lightning Talk: CruiseControl.rb\"\n      start_cue: \"20:17\"\n      end_cue: \"23:42\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2007-1\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2007-1\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name https://cln.sh/fV8Fff9t\n\n    - title: \"Lightning Talk: nfjs2\"\n      start_cue: \"23:42\"\n      end_cue: \"27:10\"\n      id: \"charles-nutter-lighting-talk-mountainwest-rubyconf-2007\"\n      video_id: \"charles-nutter-lighting-talk-mountainwest-rubyconf-2007\"\n      video_provider: \"parent\"\n      speakers:\n        - Charles Nutter\n\n    - title: \"Lightning Talk: LogWatchR - A simple system for syslog (and other log) analysis\"\n      start_cue: \"27:10\"\n      end_cue: \"TODO\"\n      id: \"pat-eyler-lighting-talk-mountainwest-rubyconf-2007\"\n      video_id: \"pat-eyler-lighting-talk-mountainwest-rubyconf-2007\"\n      video_provider: \"parent\"\n      speakers:\n        - Pat Eyler\n\n- id: \"chad-fowler-mountainwest-rubyconf-2007\"\n  title: \"Keynote: ...then what?\"\n  raw_title: \"MWRC 2007 - Keynote: '...then what?' by Chad Fowler\"\n  speakers:\n    - Chad Fowler\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: |-\n    Chad Fowler's Keynote at Mountain West Ruby Conference - 2007 - the first edition.\n  video_provider: \"youtube\"\n  video_id: \"89f1G03jVO8\"\n  thumbnail_lg: \"https://img.youtube.com/vi/89f1G03jVO8/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/89f1G03jVO8/hqdefault.jpg\"\n\n- id: \"john-lam-mountainwest-rubyconf-2007-ruby-clr-and-rubynet\"\n  title: \"Ruby CLR and Ruby.NET\"\n  raw_title: \"MWRC 2007 - Ruby CLR and Ruby.NET by John Lam\"\n  speakers:\n    - John Lam\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"noqRNG-CgSg\"\n  thumbnail_lg: \"https://img.youtube.com/vi/noqRNG-CgSg/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/noqRNG-CgSg/hqdefault.jpg\"\n\n- id: \"michael-hewner-mountainwest-rubyconf-2007\"\n  title: \"Ruby USB\"\n  raw_title: \"MWRC 2007 - Ruby USB by Michael Hewner\"\n  speakers:\n    - Michael Hewner\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"i90PfkapMtc\"\n  thumbnail_lg: \"https://img.youtube.com/vi/i90PfkapMtc/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/i90PfkapMtc/hqdefault.jpg\"\n\n- id: \"jamis-buck-mountainwest-rubyconf-2007\"\n  title: \"Rails Code Review\"\n  raw_title: \"MWRC 2007 - Rails Code Review by Jamis Buck and Marcel Molina\"\n  speakers:\n    - Jamis Buck\n    - Marcel Molina\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"bMWoZ2_KhCM\"\n  thumbnail_lg: \"https://img.youtube.com/vi/bMWoZ2_KhCM/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/bMWoZ2_KhCM/hqdefault.jpg\"\n\n- id: \"ara-t-howard-mountainwest-rubyconf-2007\"\n  title: \"Ruby Queue\"\n  raw_title: \"Ruby Queue by Ara T. Howard - MWRC 2007\"\n  speakers:\n    - Ara T. Howard\n  event_name: \"MountainWest RubyConf 2007\"\n  date: \"2007-03-16\"\n  published_at: \"2012-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DvRSLUktog4\"\n  thumbnail_lg: \"https://img.youtube.com/vi/DvRSLUktog4/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/DvRSLUktog4/hqdefault.jpg\"\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2008/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyY6qiiM02iD1Rl5xm8Yfa3A\"\ntitle: \"MountainWest RubyConf 2008\"\nkind: \"conference\"\nlocation: \"Salt Lake City, UT, United States\"\ndescription: \"\"\nstart_date: \"2008-03-28\"\nend_date: \"2008-03-29\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2008\nwebsite: \"https://web.archive.org/web/20160331211609/http://mtnwestrubyconf.org/2008/\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2008/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"jim-weirich-mountainwest-rubyconf-2008\"\n  title: \"Shaving with Ockham\"\n  raw_title: \"Shaving with Occam by Jim Weirich\"\n  speakers:\n    - Jim Weirich\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"At0Os4SEhmM\"\n\n- id: \"jonathan-younger-mountainwest-rubyconf-2008\"\n  title: \"Using Amazon's Web Services from Ruby\"\n  raw_title: \"Using Amazon's Web Services from Ruby\"\n  speakers:\n    - Jonathan Younger\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"rWgMuziPWEg\"\n\n- id: \"lightning-talks-part-1-mountainwest-rubyconf-2008\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"MXhQks-YEQc\"\n  talks:\n    - title: \"Lightning Talk: Binary Lottery in Shoes\"\n      start_cue: \"00:17\"\n      end_cue: \"04:35\"\n      id: \"mike-moore-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"mike-moore-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Mike Moore\n\n    - title: \"Lightning Talk: Guessmethod\"\n      start_cue: \"04:35\"\n      end_cue: \"12:39\"\n      id: \"chris-shea-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"chris-shea-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Shea\n\n    - title: \"Lightning Talk: Migration Concordance\"\n      start_cue: \"12:39\"\n      end_cue: \"18:06\"\n      id: \"josh-susser-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"josh-susser-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Josh Susser\n\n    - title: \"Lightning Talk: Framework Components\"\n      start_cue: \"18:06\"\n      end_cue: \"20:44\"\n      id: \"jeremy-mcanally-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"jeremy-mcanally-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeremy McAnally\n\n    - title: \"Lightning Talk: Systems Building Systems with Puppet\"\n      start_cue: \"20:44\"\n      end_cue: \"27:15\"\n      id: \"andrew-shafer-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"andrew-shafer-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Shafer\n\n    - title: \"Lightning Talk: Multi-Image Uploading with SWFUpload & Rails\"\n      start_cue: \"27:15\"\n      end_cue: \"31:56\"\n      id: \"david-south-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"david-south-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - David South\n\n    - title: \"Lightning Talk: RubyAmp: Ruby Dev in TextMate Amplified\"\n      start_cue: \"31:56\"\n      end_cue: \"37:47\"\n      id: \"tim-harper-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"tim-harper-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Tim Harper\n\n    - title: \"Lightning Talk: Build a GUI App in 5 Minutes\"\n      start_cue: \"37:47\"\n      end_cue: \"TODO\"\n      id: \"david-koontz-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"david-koontz-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - David Koontz\n\n- id: \"jeremy-mcanally-mountainwest-rubyconf-2008\"\n  title: \"Deep Ruby\"\n  raw_title: \"Deep Ruby\"\n  speakers:\n    - Jeremy McAnally\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3nrdHK1O_ts\"\n\n- id: \"joe-obrien-mountainwest-rubyconf-2008\"\n  title: \"Domain Specific Languages: Molding Ruby\"\n  raw_title: \"Domain Specific Languages: Molding Ruby\"\n  speakers:\n    - Joe O'Brien\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jkUFF7ikY3Q\"\n\n- id: \"devlin-daley-mountainwest-rubyconf-2008\"\n  title: \"Enough Statistics So That Zed Won't Yell At You\"\n  raw_title: \"Enough statistics so that Zed won't yell at you\"\n  speakers:\n    - Devlin Daley\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"EDMMrB0s2z8\"\n\n- id: \"jan-lehnardt-mountainwest-rubyconf-2008\"\n  title: \"Next Generation Data Storage with CouchDB\"\n  raw_title: \"Next Generation Data Storage with CouchDB\"\n  speakers:\n    - Jan Lehnardt\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"XK7C9JDrOtI\"\n\n- id: \"patrick-farley-mountainwest-rubyconf-2008\"\n  title: \"Ruby Internals\"\n  raw_title: \"MountainWest RubyConf 2008 - Ruby Internals by Patrick Farley\"\n  speakers:\n    - Patrick Farley\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"NlPxvRSUVQI\"\n\n- id: \"tammer-saleh-mountainwest-rubyconf-2008\"\n  title: \"BDD with Shoulda\"\n  raw_title: \"MountainWest Ruby Conf 2008 - BDD with Shoulda by Tammer Saleh\"\n  speakers:\n    - Tammer Saleh\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"NyLFcWKiMrw\"\n\n- id: \"lightning-talks-part-2-mountainwest-rubyconf-2008\"\n  title: \"Lightning Talks\"\n  raw_title: \"MountainWest RubyConf 2008 - Lightning Talks - Various Presenters\"\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"NdSPWtmJ6FM\"\n  talks:\n    - title: \"Lightning Talk: GemInstaller\"\n      start_cue: \"00:00\"\n      end_cue: \"09:00\"\n      id: \"chad-wooley-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"chad-wooley-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Chad Woolley\n\n    - title: \"Lightning Talk: Twitter + XMPP + Ruby == ZOMG\"\n      start_cue: \"09:00\"\n      end_cue: \"13:35\"\n      id: \"jade-meskill-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"jade-meskill-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Jade Meskill\n\n    - title: \"Lightning Talk: Distributed Applications with CouchDB\"\n      start_cue: \"13:35\"\n      end_cue: \"21:24\"\n      id: \"jane-lenhardt-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"jane-lenhardt-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Jane Lenhardt\n\n    - title: \"Lightning Talk: duck\"\n      start_cue: \"21:24\"\n      end_cue: \"24:07\"\n      id: \"pat-eyler-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"pat-eyler-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Pat Eyler\n\n    - title: \"Lightning Talk: RubyCocoa\"\n      start_cue: \"24:07\"\n      end_cue: \"31:28\"\n      id: \"brian-cooke-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"brian-cooke-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Brian Cooke\n\n    - title: \"Lightning Talk: I/O and Ruby\"\n      start_cue: \"31:28\"\n      end_cue: \"40:41\"\n      id: \"brian-mitcheel-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"brian-mitcheel-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Brian Mitcheel\n\n    - title: \"Lightning Talk: Making Fixtures Suck Less\"\n      start_cue: \"40:41\"\n      end_cue: \"46:28\"\n      id: \"jeremy-stell-smith-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"jeremy-stell-smith-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeremy Stell-Smith\n\n    - title: \"Lightning Talk: Punch & Main\"\n      start_cue: \"46:28\"\n      end_cue: \"52:20\"\n      id: \"dan-fitzpatrick-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"dan-fitzpatrick-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Dan Fitzpatrick\n\n    - title: \"Lightning Talk: JRuby with Java Web Start\"\n      start_cue: \"52:20\"\n      end_cue: \"56:38\"\n      id: \"logan-barnett-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"logan-barnett-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Logan Barnett\n\n    - title: \"Lightning Talk: Autosaving Fields with Rails\"\n      start_cue: \"56:38\"\n      end_cue: \"1:01:21\"\n      id: \"mark-josef-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"mark-josef-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Mark Josef\n\n    - title: \"Lightning Talk: Blueprint Form Builder\"\n      start_cue: \"1:01:21\"\n      end_cue: \"1:05:44\"\n      id: \"jim-lindley-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"jim-lindley-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Jim Lindley\n\n    - title: \"Lightning Talk: GitHub\"\n      start_cue: \"1:05:44\"\n      end_cue: \"1:13:54\"\n      id: \"pj-heyett-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"pj-heyett-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - PJ Heyett\n\n    - title: \"Lightning Talk: Sequel\"\n      start_cue: \"1:13:54\"\n      end_cue: \"1:19:52\"\n      id: \"aman-gupta-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"aman-gupta-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Aman Gupta\n\n    - title: \"Lightning Talk: Migration Branches\"\n      start_cue: \"1:19:52\"\n      end_cue: \"1:27:05\"\n      id: \"wayne-e-sequin-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"wayne-e-sequin-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Wayne E. Sequin\n\n    - title: \"Lightning Talk: Granular Rails Testing\"\n      start_cue: \"1:27:05\"\n      end_cue: \"TODO\"\n      id: \"jacob-fugal-lighting-talk-mountainwest-rubyconf-2008\"\n      video_id: \"jacob-fugal-lighting-talk-mountainwest-rubyconf-2008\"\n      video_provider: \"parent\"\n      speakers:\n        - Jacob Fugal\n\n- id: \"philippe-hanrigou-mountainwest-rubyconf-2008\"\n  title: \"What to do when Mongrel stops responding...\"\n  raw_title: \"MountainWest Ruby Conf 2008 - What to do when Mongrel stops responding... by Philippe Hanrigou\"\n  speakers:\n    - Philippe Hanrigou\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"1dZ0l19zEsw\"\n\n- id: \"giles-bowkett-mountainwest-rubyconf-2008\"\n  title: \"Code Generation: The Safety Scissors of Metaprogramming\"\n  raw_title: \"Code Generation: The Safety Scissors of Metaprogramming\"\n  speakers:\n    - Giles Bowkett\n  event_name: \"MountainWest RubyConf 2008\"\n  date: \"2008-09-09\"\n  published_at: \"2012-09-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"HWeQYcAc-eM\"\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2009/event.yml",
    "content": "---\nid: \"PLB3ABD9A8B27F76D8\"\ntitle: \"MountainWest RubyConf 2009\"\nkind: \"conference\"\nlocation: \"Salt Lake City, UT, United States\"\ndescription: \"\"\nstart_date: \"2009-03-13\"\nend_date: \"2009-03-14\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2009\nwebsite: \"https://web.archive.org/web/20160331205937/http://mtnwestrubyconf.org/2009/\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2009/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"danny-blitz-mountainwest-rubyconf-2009\"\n  title: \"Herding Tigers - Software Development and the Art of War\"\n  raw_title: \"Mountain West Ruby Conf 2009 Herding Tigers - Software Development and the Art of War by Danny Blitz\"\n  speakers:\n    - Danny Blitz\n  event_name: \"MountainWest RubyConf 2009\"\n  date: \"2012-08-07\"\n  published_at: \"2012-08-07\"\n  description: |-\n    My good friend Danny Blitz did this presentation at Mountain West Ruby Conference 2009.  It has some really good insights on software development, teams, and life.\n\n    It's with great sadness that I have to tell you that Danny Blitz passed away on August 11, 2012.\n\n    http://obits.dignitymemorial.com/dignity-memorial/obituary.aspx?n=Daniel-Blitz&lc=7484&pid=159080122&mid=5201518&locale=en_US\n\n    He was a man who had little fear of rejection.  You could sit him down and tell him all the negative things in a given situation and he'd find a way to pick up a positive aspect of it and trumpet the good news.\n\n    He will be missed!\n\n  video_provider: \"youtube\"\n  video_id: \"HUOWKqeoFxQ\"\n\n- id: \"james-edward-gray-ii-mountainwest-rubyconf-2009\"\n  title: \"LittleBIGRuby\"\n  raw_title: \"LittleBIGRuby by James Edward Gray II\"\n  speakers:\n    - James Edward Gray II\n  event_name: \"MountainWest RubyConf 2009\"\n  date: \"2012-08-07\"\n  published_at: \"2012-08-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"_xz7gPHKGxs\"\n\n- id: \"jon-crosby-mountainwest-rubyconf-2009\"\n  title: \"In a World of Middleware, Who Needs Monolithic Applications\"\n  raw_title: \"In a World of Middleware, Who Needs Monolithic Applications by Jon Crosby\"\n  speakers:\n    - Jon Crosby\n  event_name: \"MountainWest RubyConf 2009\"\n  date: \"2012-08-07\"\n  published_at: \"2012-08-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"H-mctufxiQ4\"\n\n- id: \"yehuda-katz-mountainwest-rubyconf-2009\"\n  title: \"The Great Rails Refactor\"\n  raw_title: \"The Great Rails Refactor by Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"MountainWest RubyConf 2009\"\n  date: \"2012-08-07\"\n  published_at: \"2012-08-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"xVGP1dlQ6hc\"\n\n- id: \"jeremy-evans-mountainwest-rubyconf-2009\"\n  title: \"Sequel\"\n  raw_title: \"Sequel by Jeremy Evans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"MountainWest RubyConf 2009\"\n  date: \"2012-08-07\"\n  published_at: \"2012-08-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"yCjtdfv9Z_0\"\n\n- id: \"kirk-haines-mountainwest-rubyconf-2009\"\n  title: \"Vertebra\"\n  raw_title: \"Vertebra by Kirk Haines\"\n  speakers:\n    - Kirk Haines\n  event_name: \"MountainWest RubyConf 2009\"\n  date: \"2012-08-07\"\n  published_at: \"2012-08-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"q2X3Kbf1Diw\"\n\n- id: \"andrew-shafer-mountainwest-rubyconf-2009\"\n  title: \"Practical Puppet: Systems Building Systems\"\n  raw_title: \"Practical Puppet: Systems Building Systems by Andrew Shafer\"\n  speakers:\n    - Andrew Shafer\n  event_name: \"MountainWest RubyConf 2009\"\n  date: \"2012-08-07\"\n  published_at: \"2012-08-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"HicDzhDmQ-s\"\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2010/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYk99N95TtGtLoeZJQwbWEc\"\ntitle: \"MountainWest RubyConf 2010\"\nkind: \"conference\"\nlocation: \"Salt Lake City, UT, United States\"\ndescription: \"\"\npublished_at: \"2010-xx-xx\"\nstart_date: \"2010-03-11\"\nend_date: \"2010-03-12\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2010\nwebsite: \"https://web.archive.org/web/20160331205937/http://mtnwestrubyconf.org/2010/\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2010/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"giles-bowkett-mountainwest-rubyconf-2010\"\n  title: \"Archaeopteryx: Lambdas in Detail\"\n  raw_title: \"MountainWest RubyConf 2010 - Archaeopteryx: Lambdas in Detail by Giles Bowkett\"\n  speakers:\n    - Giles Bowkett\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zw1V6dZ1_j0\"\n\n- id: \"aman-gupta-mountainwest-rubyconf-2010\"\n  title: \"EventMachine\"\n  raw_title: \"MountainWest RubyConf 2010 - EventMachine by Aman Gupta\"\n  speakers:\n    - Aman Gupta\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"GEd3KQEGj0Q\"\n\n- id: \"pat-maddox-mountainwest-rubyconf-2010\"\n  title: \"A Tale of Two Codebases\"\n  raw_title: \"MountainWest RubyConf 2010 - A Tale of Two Codebases by Pat Maddox\"\n  speakers:\n    - Pat Maddox\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"HznXiuTAi6g\"\n\n- id: \"joe-damato-mountainwest-rubyconf-2010\"\n  title: \"Decent into Darkness: Understanding Your System's Binary Interface Is The Only Way Out\"\n  raw_title: \"MountainWest RubyConf 2010 - Decent into Darkness: Understanding Your System's Binary Interface...\"\n  speakers:\n    - Joe Damato\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: |-\n    is the Only Way Out\n\n    by Joe Damato\n\n  video_provider: \"youtube\"\n  video_id: \"g8A0Wa7REZI\"\n\n- id: \"kyle-banker-mountainwest-rubyconf-2010\"\n  title: \"MongoDB Rules\"\n  raw_title: \"MountainWest RubyConf 2010 - MongoDB Rules by Kyle Banker\"\n  speakers:\n    - Kyle Banker\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"V3hUrEYYyuY\"\n\n- id: \"sarah-allen-mountainwest-rubyconf-2010\"\n  title: \"Mobile Rubyby\"\n  raw_title: \"MountainWest RubyConf 2010 - Mobile Rubyby Sarah Allen\"\n  speakers:\n    - Sarah Allen\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"xUVLtgSj0Hs\"\n\n- id: \"james-britt-mountainwest-rubyconf-2010\"\n  title: \"Hubris: The Ruby/Haskell Bridge\"\n  raw_title: \"MountainWest RubyConf 2010 - Hubris: The Ruby/Haskell Bridge by James Britt\"\n  speakers:\n    - James Britt\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"UqUGBKaehq4\"\n\n- id: \"jeremy-evans-mountainwest-rubyconf-2010\"\n  title: \"Ruby Techniques by Example\"\n  raw_title: \"MountainWest RubyConf 2010 - Ruby Techniques by Example by Jeremy Evans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"F2NGGrLhYKw\"\n\n- id: \"caleb-clausen-mountainwest-rubyconf-2010\"\n  title: \"Ruby Macros\"\n  raw_title: \"MountainWest RubyConf 2010 - Ruby Macros by Caleb Clausen\"\n  speakers:\n    - Caleb Clausen\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"s7qot98I54A\"\n\n- id: \"yukihiro-matz-matsumoto-mountainwest-rubyconf-2010\"\n  title: \"Ruby 124c41+\"\n  raw_title: \"MountainWest RubyConf 2010 - Ruby 124c41+ by Yukihio 'Matz' Matsumoto\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"N0hnS6UNFo0\"\n\n- id: \"lightning-talks-part-1-mountainwest-rubyconf-2010\"\n  title: \"Lightning Talks Part 1\"\n  raw_title: \"MountainWest RubyConf 2010 - Lightning Talks Part 1\"\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"lKwIKXv0GOY\"\n  talks:\n    - title: \"Lightning Talk: David Brady\"\n      start_cue: \"0:15\"\n      end_cue: \"5:10\"\n      video_provider: \"parent\"\n      id: \"david-brady-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"david-brady-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - David Brady\n\n    - title: \"Lightning Talk: Observations\"\n      start_cue: \"5:10\"\n      end_cue: \"9:20\"\n      video_provider: \"parent\"\n      id: \"jeremy-observations-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"jeremy-observations-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - TODO # Jeremy TODO: missing last name\n\n    - title: \"Lightning Talk: Chad Woolley\"\n      start_cue: \"9:20\"\n      end_cue: \"14:18\"\n      video_provider: \"parent\"\n      id: \"chad-woolley-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"chad-woolley-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - Chad Woolley\n\n    - title: \"Lightning Talk: Memberof.com Demo\"\n      start_cue: \"14:18\"\n      end_cue: \"23:42\"\n      video_provider: \"parent\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2010-1\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2010-1\"\n      speakers:\n        - TODO # TODO: missing name\n\n    - title: \"Lightning Talk: HTML5 Offline\"\n      start_cue: \"23:42\"\n      end_cue: \"29:04\"\n      video_provider: \"parent\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2010-2\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2010-2\"\n      speakers:\n        - TODO # TODO: missing name\n\n    - title: \"Lightning Talk: E-Commerce\"\n      start_cue: \"29:04\"\n      end_cue: \"34:44\"\n      video_provider: \"parent\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2010-3\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2010-3\"\n      speakers:\n        - TODO # TODO: missing name\n\n    - title: \"Lightning Talk: Screen Manager\"\n      start_cue: \"34:44\"\n      end_cue: \"38:29\"\n      video_provider: \"parent\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2010-4\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2010-4\"\n      speakers:\n        - TODO # TODO: missing name\n\n    - title: \"Lightning Talk: SimpleGeo\"\n      start_cue: \"38:29\"\n      end_cue: \"42:49\"\n      video_provider: \"parent\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2010-5\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2010-5\"\n      speakers:\n        - TODO # TODO: missing name\n\n    - title: \"Lightning Talk: Rails Gin\"\n      start_cue: \"42:49\"\n      end_cue: \"45:02\"\n      video_provider: \"parent\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2010-6\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2010-6\"\n      speakers:\n        - TODO # TODO: missing name\n\n    - title: \"Lightning Talk: Chris Smith\"\n      start_cue: \"45:02\"\n      end_cue: \"50:31\"\n      video_provider: \"parent\"\n      id: \"chris-smith-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"chris-smith-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - Chris Smith\n\n    - title: \"Lightning Talk: CoffeeScript\"\n      start_cue: \"50:31\"\n      end_cue: \"TODO\"\n      video_provider: \"parent\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2010-7\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2010-7\"\n      speakers:\n        - TODO # TODO: missing name\n\n- id: \"jeff-casimir-mountainwest-rubyconf-2010\"\n  title: \"Dynamic Generation of Images and Video with Ruby-Processing\"\n  raw_title: \"MountainWest RubyConf 2010 - Dynamic Generation of Images and Video with Ruby-Processing\"\n  speakers:\n    - Jeff Casimir\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: |-\n    by Jeff Casimir\n\n  video_provider: \"youtube\"\n  video_id: \"ud6xttMyoJ4\"\n\n- id: \"loren-segal-mountainwest-rubyconf-2010\"\n  title: \"Documentation and the Whole nine YARDs\"\n  raw_title: \"MountainWest RubyConf 2010 - Documentation and the Whole nine YARDs by Loren Segal\"\n  speakers:\n    - Loren Segal\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"yFRuneIwybQ\"\n\n- id: \"gregory-brown-mountainwest-rubyconf-2010\"\n  title: \"I was wrong about ruport\"\n  raw_title: \"MountainWest RubyConf 2010 - I was wrong about ruport by Gregory Brown\"\n  speakers:\n    - Gregory Brown\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"O6HjLxAzXxs\"\n\n- id: \"paul-sadauskas-mountainwest-rubyconf-2010\"\n  title: \"How HTTP Already Solved All Your Performance Problems 10 Years Ago\"\n  raw_title: \"MountainWest RubyConf 2010 - How HTTP already solved all your performance problems 10 years ago\"\n  speakers:\n    - Paul Sadauskas\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: |-\n    by Paul Sadauskas\n\n  video_provider: \"youtube\"\n  video_id: \"11Cc7NZVMTQ\"\n\n- id: \"yehuda-katz-mountainwest-rubyconf-2010\"\n  title: \"Writing Modular Ruby Code: Lessons Learned from Rails 3\"\n  raw_title: \"MountainWest RubyConf 2010 - Writing Modular Ruby Code: Lessons Learned from Rails 3 by Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"NWpICBV6ceY\"\n\n- id: \"michael-j-i-jackson-mountainwest-rubyconf-2010\"\n  title: \"Rack For Web Developers\"\n  raw_title: \"MountainWest RubyConf 2010 - Rack for web developers by Michael J. I. Jackson\"\n  speakers:\n    - Michael J. I. Jackson\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"PoiYZd8qkqg\"\n\n- id: \"wayne-e-seguin-mountainwest-rubyconf-2010\"\n  title: \"Managing Ruby Projects with RVM\"\n  raw_title: \"MountainWest RubyConf 2010 - Managing Ruby Projects with RVM by Wayne E. Seguin\"\n  speakers:\n    - Wayne E. Seguin\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"O7M0tTJc9mY\"\n\n- id: \"james-golick-mountainwest-rubyconf-2010\"\n  title: \"Cooking with Chef - Your Servers Will Thank You\"\n  raw_title: \"MountainWest RubyConf 2010 - Cooking with Chef - Your servers will thank you by James Golick\"\n  speakers:\n    - James Golick\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"xmGurcJ1rUA\"\n\n- id: \"lightning-talks-day-2-mountainwest-rubyconf-2010\"\n  title: \"Lightning Talks (Day 2)\"\n  raw_title: \"MountainWest RubyConf 2010 - Lightning Talks 2 by Various Presenters\"\n  event_name: \"MountainWest RubyConf 2010\"\n  date: \"2015-02-11\"\n  published_at: \"2015-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"_mN4HJIhpYo\"\n  talks:\n    - title: \"Lightning Talk: Testing Queries\"\n      start_cue: \"0:15\"\n      end_cue: \"5:10\"\n      video_provider: \"parent\"\n      id: \"ginny-hendry-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"ginny-hendry-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - Ginny Hendry\n\n    - title: \"Lightning Talk: Git and GitHub\"\n      start_cue: \"5:10\"\n      end_cue: \"6:27\"\n      video_provider: \"parent\"\n      id: \"john-woodell-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"john-woodell-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - John Woodell\n\n    - title: \"Lightning Talk: ruby-fs-stack\"\n      start_cue: \"6:27\"\n      end_cue: \"11:33\"\n      video_provider: \"parent\"\n      id: \"jimmy-zimmerman-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"jimmy-zimmerman-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - Jimmy Zimmerman\n\n    - title: \"Lightning Talk: RubyMine\"\n      start_cue: \"11:33\"\n      end_cue: \"16:45\"\n      video_provider: \"parent\"\n      id: \"mark-lighting-talk-mountainwest-rubyconf-2010-1\"\n      video_id: \"mark-lighting-talk-mountainwest-rubyconf-2010-1\"\n      speakers:\n        - Mark # TODO: missing last name https://cln.sh/ZJmbRdQH\n\n    - title: \"Lightning Talk: Geo Tweeter\"\n      start_cue: \"16:45\"\n      end_cue: \"20:55\"\n      video_provider: \"parent\"\n      id: \"nora-howard-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"nora-howard-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - Nora Howard\n\n    - title: \"Lightning Talk: Hexagonal Architecture\"\n      start_cue: \"20:55\"\n      end_cue: \"20:52\"\n      video_provider: \"parent\"\n      id: \"alistair-coburn-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"alistair-coburn-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - Alistair Coburn\n\n    - title: \"Lightning Talk: Bash Deployment & Server Manager\"\n      start_cue: \"20:52\"\n      end_cue: \"30:17\"\n      video_provider: \"parent\"\n      id: \"wayne-e-seguin-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"wayne-e-seguin-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - Wayne E. Seguin\n\n    - title: \"Lightning Talk: Unobtrusively Extending Git with Gitty\"\n      start_cue: \"30:17\"\n      end_cue: \"35:45\"\n      video_provider: \"parent\"\n      id: \"tim-harper-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"tim-harper-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - Tim Harper\n\n    - title: \"Lightning Talk: Agile - Back To The Future\"\n      start_cue: \"35:45\"\n      end_cue: \"41:01\"\n      video_provider: \"parent\"\n      id: \"andrew-clay-shafer-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"andrew-clay-shafer-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - Andrew Clay Shafer\n\n    - title: \"Lightning Talk: Donkey\"\n      start_cue: \"41:01\"\n      end_cue: \"TODO\"\n      video_provider: \"parent\"\n      id: \"howard-yeh-lighting-talk-mountainwest-rubyconf-2010\"\n      video_id: \"howard-yeh-lighting-talk-mountainwest-rubyconf-2010\"\n      speakers:\n        - Howard Yeh\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2011/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcya5OgHPof3Jrq0VNmvxMEWX\"\ntitle: \"MountainWest RubyConf 2011\"\nkind: \"conference\"\nlocation: \"Salt Lake City, UT, United States\"\ndescription: \"\"\nstart_date: \"2011-03-17\"\nend_date: \"2011-03-18\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2011\nwebsite: \"https://web.archive.org/web/20171022163315/http://mtnwestrubyconf.org/2011/\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2011/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"joshua-timberman-mountainwest-rubyconf-2011\"\n  title: \"Chef Cookbook Design Patterns\"\n  raw_title: \"MWRC 2011 - Chef Cookbook Design Patterns\"\n  speakers:\n    - Joshua Timberman\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-17\"\n  published_at: \"2015-02-17\"\n  description: |-\n    By, Joshua Timberman\n    This talk will teach you how Opscode designs and writes Chef cookbooks to be sharable - not only in the Open Source sense, but sharable between various internal infrastructures and environments. Come to this talk if you want to learn more about: How Chef uses attributes How to dynamically build configuration with search Accessing internal Chef objects within recipes\n\n  video_provider: \"youtube\"\n  video_id: \"A3pzIZJpDYg\"\n\n- id: \"wesley-beary-mountainwest-rubyconf-2011\"\n  title: \"Fog or: How I Learned to Stop Worrying and Love the Cloud\"\n  raw_title: 'MWRC 2011 - fog or: How I Learned to Stop Worrying and Love the Cloud\"'\n  speakers:\n    - Wesley Beary\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-17\"\n  published_at: \"2015-02-17\"\n  description: |-\n    Cloud computing scared the crap out of me - the quirks and nightmares of provisioning cloud computing, dns, storage, ... on AWS, Terremark, Rackspace, ... - I mean, where do you even start?\n\n    Since I couldn't find a good answer, I undertook the (probably insane) task of creating one. fog (http://github.com/geemus/fog) gives you a place to start by creating abstractions that work across many different providers, greatly reducing the barrier to entry (and the cost of switching later). The abstractions are built on top of solid wrappers for each api. So if the high level stuff doesn't cut it you can dig in and get the job done. On top of that, mocks are available to simulate what clouds will do for development and testing (saving you time and money).\n\n    You'll get a whirlwind tour of basic through advanced as we create the building blocks of a highly distributed (multi-cloud) system with some simple Ruby scripts that work nearly verbatim from provider to provider. Get your feet wet working with cloud resources or just make it easier on yourself as your usage gets more complex, either way fog makes it easy to get what you need from the cloud.\n\n  video_provider: \"youtube\"\n  video_id: \"PTfulYN4ctA\"\n  additional_resources:\n    - name: \"geemus/fog\"\n      type: \"repo\"\n      url: \"http://github.com/geemus/fog\"\n\n- id: \"preston-lee-mountainwest-rubyconf-2011\"\n  title: \"Ruby Supercomputing: Using The GPU For Massive Performance Speedup\"\n  raw_title: \"MWRC 2011 - Ruby Supercomputing: Using The GPU For Massive Performance Speedup\"\n  speakers:\n    - Preston Lee\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-17\"\n  published_at: \"2015-02-17\"\n  description: |-\n    By, Preston Lee\n    Applications typically measure processing throughput as a function of CPU-bound algorithm performance. Most modern production systems will contain 2-16 processor cores, but highly concurrent, compute-heavy algorithms may still reach hard limits. Within recent years, vendors such as Nvidia and Apple have formalized specifications and APIs that allow every developer to run potentially 1,000s of concurrent threads using a piece of hardware already present in the machine: the GPU.\n\n  video_provider: \"youtube\"\n  video_id: \"C6y4YkpaT_I\"\n\n- id: \"nick-quaranto-mountainwest-rubyconf-2011\"\n  title: \"Behind the Keys: Redis Oyster Cult\"\n  raw_title: \"MWRC 2011 - Behind the Keys: Redis Oyster Cult\"\n  speakers:\n    - Nick Quaranto\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-17\"\n  published_at: \"2015-02-17\"\n  description: |-\n    By, Nick Quaranto\n    Redis is an \"advanced key-value store\" but really, it's much more than that. Redis goes above and beyond GET and SET, and it's time for you to learn how that can help you write faster Ruby apps. We'll explore the rest that Redis has to offer, such as sorted sets, publish/subscribe, transactions, and more with real-world use cases of each.\n\n  video_provider: \"youtube\"\n  video_id: \"NOs-SX05Y3g\"\n\n- id: \"chris-wyckoff-mountainwest-rubyconf-2011\"\n  title: \"SOA and the Monolithic Rails App Anti-Pattern\"\n  raw_title: \"MWRC 2011 - SOA and the Monolithic Rails App Anti-Pattern\"\n  speakers:\n    - Chris Wyckoff\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-17\"\n  published_at: \"2015-02-17\"\n  description: |-\n    By, Chris Wyckoff\n    Ruby on Rails is a wonderful framework that makes creating websites simple and fun. But, perhaps because it is a pleasure to work with, Rails can be overused. A simple CRUD application can quickly become a behemoth, it's responsibilities encompassing far more functionality than one application should. In the startup world, one such app can run an entire business. Monolithic Rails applications are an anti-pattern that hamper productivity, increase bugs, and, if you are a startup, can threaten your business. How do you fix the problem? Decompose your application into several independent, reusable services. This talk relates my experience leading a team of developers who re-architected a monolithic Rails app -- an app that effectively was the business -- into a service-oriented architecture (SOA). Using targeted code examples, it seeks to describe not only the advantages of a service-oriented approach, but also techniques for refactoring a production application into a more distributed architecture without destroying the business in the process. Finally, this talk highlights some common SOA pitfalls and describes effective ways to avoid or remedy them. Attendees will walk away with a clear demonstration of how to refactor or think about building their app with SOA in mind.\n\n  video_provider: \"youtube\"\n  video_id: \"XuGupkgRiNY\"\n\n- id: \"bryan-helmkamp-mountainwest-rubyconf-2011\"\n  title: \"Service Oriented Design in Practice\"\n  raw_title: \"MWRC 2011 - Service Oriented Design in Practice\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-17\"\n  published_at: \"2015-02-17\"\n  description: |-\n    By, Bryan Helmkamp\n    Implementing a Service Oriented Design with Ruby can lower maintenance costs by increasing isolation, scalability and code reuse. That's the theory, anyway. It's true, but in practice there are lots of nitty gritty details of rolling out a service oriented design that can reduce the expected benefits -- or even leave you worse off than you started.\n\n    This talk will shed light on what it takes to successfully leverage a service oriented architecture. Emphasis will be on less discussed considerations like testing strategies, dependency and release management, operations and developer tools rather than the happy path of how to implement and consume services. Examples will be provided from our experience building tool to analyze home energy use in order to help people save on their power bills.\n\n    In the end, you'll walk away with a deeper understanding of how to weigh the pros and cons of introducing services into your architecture, and you'll have learned some techniques to make the transition smoother if you decide it's right for you.\n\n  video_provider: \"youtube\"\n  video_id: \"MNRi5zmZGVk\"\n\n- id: \"sam-rawlins-mountainwest-rubyconf-2011\"\n  title: \"The State of C Extensions: Alive and Well, so Learn to Deal\"\n  raw_title: \"MWRC 2011 - The State of C Extensions: Alive and Well, so Learn to Deal\"\n  speakers:\n    - Sam Rawlins\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-17\"\n  published_at: \"2015-02-17\"\n  description: |-\n    By, Sam Rawlins\n    Ruby C Extensions have been a roller coaster ride over the last few years. While many Rubyists shy away from such non-Ruby code, its hard to imagine our Ruby ecosystem without them. Many of the most popular gems are C extensions. They are thriving today, and can play nice everywhere that Ruby plays nice! C extensions are not a drag on the community, but instead an exciting path that exposes Ruby to a greater computing landscape.\n\n  video_provider: \"youtube\"\n  video_id: \"tmMJx_WD4r0\"\n\n- id: \"andy-maleh-mountainwest-rubyconf-2011\"\n  title: \"Whatever Happened to Desktop Development in Ruby?\"\n  raw_title: \"MWRC 2011 - Whatever Happened to Desktop Development in Ruby?\"\n  speakers:\n    - Andy Maleh\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-18\"\n  description: |-\n    By, Andy Maleh\n    While web development is thriving in the Ruby world with Rails, Sinatra, and other frameworks, desktop development is still not very common as a lot of developers rely on Java technologies like Eclipse or straight .NET technologies such as Windows Forms. This talk will walk attendees through some Ruby desktop development frameworks/libraries, contrasting the pros and cons of each, and mentioning what is missing that discourages developers from relying on Ruby to build desktop applications. Frameworks/libraries covered will include MacRuby, Shoes, Limelight, and Glimmer.\n\n  video_provider: \"youtube\"\n  video_id: \"2LK3cZiP9AU\"\n\n- id: \"ilya-grigorik-mountainwest-rubyconf-2011\"\n  title: \"Modeling Concurrency in Ruby and Beyond\"\n  raw_title: \"MWRC 2011 - Modeling concurrency in Ruby and beyond\"\n  speakers:\n    - Ilya Grigorik\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-18\"\n  description: |-\n    By, Ilya Grigorik\n    The world of concurrent computation is a complicated one. We have to think about the hardware, the runtime, and even choose between half a dozen different models and primitives: fork/wait, threads, shared memory, message passing, semaphores, and transactions just to name a few. And that's only the beginning.\n\n    What's the state of the art for dealing with concurrency & parallelism in Ruby? We'll take a quick look at the available runtimes, what they offer, and their limitations. Then, we'll dive into the concurrency models and ask are threads really the best we can do to design, model, and test our software? What are the alternatives, and is Ruby the right language to tackle these problems?\n\n    Spoiler: out with the threads. Seriously.\n\n  video_provider: \"youtube\"\n  video_id: \"OWZR__Bmkvs\"\n\n- id: \"jim-weirich-mountainwest-rubyconf-2011\"\n  title: \"Securing Your Rails App\"\n  raw_title: \"MWRC 2011 - Securing Your Rails App\"\n  speakers:\n    - Jim Weirich\n    - Matt Yoho\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-18\"\n  description: |-\n    By, Jim Weirich & Matt Yoho\n    Then it starts to scan the computer and transmit bits of information every time he clicks the mouse while he's surfing. After a while, [...] we've accumulated a complete mirror image of the content of his hard drive [...]. And then it's time for the hostile takeover. -- Lisbeth Salander in Stieg Larsson's \"The Girl with the Dragon Tattoo\" Hacker dramas like the Stieg Larrson book make for good fiction, but we know that real life rarely matches drama. And with all the security features that Rails 3 has added, surely it is difficult to hack a typical Rails web site. Right? Wrong! Without deliberate attention to the details of security, it almost certain that your site has flaws that a knowledgeable hacker can exploit. This talk will cover the ins and outs of web security and help you build a site that is protected from the real Lisbeth Salanders of the world.\n\n  video_provider: \"youtube\"\n  video_id: \"Ki8Qa_ArTP4\"\n\n- id: \"david-brady-mountainwest-rubyconf-2011\"\n  title: \"Monkeypatching Your Brain\"\n  raw_title: \"MWRC 2011 - Monkeypatching Your Brain\"\n  speakers:\n    - David Brady\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-18\"\n  description: |-\n    By, David Brady\n    Your entire nervous systems literally wired to be reprogrammed. Are you working with its strengths? Do you know how to tell if you're not? In this session we'll explore some exciting discoveries in neuroscience and psychology, and then immediately put this knowledge to use creating iterative change inside our brains. Or maybe we'll just monkeypatch some stuff and see what happens. If you want to start or break new habit instantly, start unit testing your own behavior, or if you just think it would be fun to know how to hack a debug breakpoint into somebody else's brain, this talk is for you!\n\n  video_provider: \"youtube\"\n  video_id: \"wWv45N9zzx8\"\n\n- id: \"zed-a-shaw-mountainwest-rubyconf-2011\"\n  title: \"Fascism and Faux-pen Source\"\n  raw_title: \"MWRC 2011 - Fascism and Faux-pen Source\"\n  speakers:\n    - Zed A. Shaw\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-18\"\n  description: |-\n    By, Zed A. Shaw\n    Everything you need to know to run your very own Faux-pen Source project in the Fascist style. I'll cover the history of Fascism, how it works, relevant scholarly research, and how you can leverage fascist tactics and \"the community\" to further your own goals.\n\n  video_provider: \"youtube\"\n  video_id: \"EvfLPXUHfVc\"\n\n- id: \"nate-peel-mountainwest-rubyconf-2011\"\n  title: \"Using Ruby with Xbox Kinect for Fun and Profit\"\n  raw_title: \"MWRC 2011 - Using Ruby with Xbox Kinect for fun and profit\"\n  speakers:\n    - Nate Peel\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-18\"\n  description: |-\n    By Nate Peel\n    The Xbox Kinect is an exciting new way to interact with not only your Xbox 360, but your computer. In this segment Nate will show you how to use Ruby to interact with a Kinect, and gather skeleton sequences for an animation that can be imported into a 3d program for use in a game or movie.\n\n  video_provider: \"youtube\"\n  video_id: \"CJcxkzVe0XQ\"\n\n- id: \"joe-obrien-mountainwest-rubyconf-2011\"\n  title: \"Ruby on Android\"\n  raw_title: \"MWRC 2011 - Ruby on Android\"\n  speakers:\n    - Joe O'Brien\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-18\"\n  description: |-\n    By, Joe O'Brien\n    With the advent of JRuby many doors have been opened that were not before for Ruby. One particular place is the android platform. Using Ruby, we can easily leverage the Android platform and API's to create incredible applications. Since we are using Ruby, testing becomes a trivial exercise. I'll walk through the options we have for developing full feature-rich applications for both the Android tablet and the phone. I'll show how we can use JRuby to sidestep the complexity and configuration-heavy frameworks that are traditionally for Android development.\n\n  video_provider: \"youtube\"\n  video_id: \"9I8oBMWVjo4\"\n\n- id: \"evan-light-mountainwest-rubyconf-2011\"\n  title: \"Tiny Tools Tidy Tests\"\n  raw_title: \"MWRC 2011 - Tiny Tools Tidy Tests\"\n  speakers:\n    - Evan Light\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-18\"\n  description: |-\n    By, Evan Light\n    I admit it. I like my code to read like English when possible. I am not unique in that regard. But, at least as importantly, I like my tools to be tractable; I'm unhappy if a quick trip to a gem's /lib results in confusion and frustration. If I can't understand my tools, I can't extend them. I can't truly make them *my* tools.\n\n    In this regard, it is possible to have your cake and eat it too.\n\n    Because I, and many Rubyists, are test-obsessed, this talk will focus on testing tools. We'll discuss lesser known gems (in many senses of the word) that build on Test::Unit. Yes, we will compare them to the twin juggernauts of RSpec and Cucumber. Finally, if none of the existing tools quite scratch your itch, we will discsus how you can build tools that meet your particular needs without resorting to \"Swiss Army Knife\" tools.\n\n    By the end of this talk, you will develop an appreciation for tiny tools, some sympathy for Test::Unit, reach enlightenment, add a schizophrenic/demonic voice to your mind constantly asking you \"why are you using THAT?\", save a kitten, and just maybe learn a few things to change your testing practices for the better.\n\n  video_provider: \"youtube\"\n  video_id: \"rRgcZOO5Sxk\"\n\n- id: \"michael-jackson-mountainwest-rubyconf-2011\"\n  title: \"Parsing Expressions in Ruby\"\n  raw_title: \"MWRC 2011 - Parsing Expressions in Ruby\"\n  speakers:\n    - Michael Jackson\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-19\"\n  description: |-\n    By, Michael Jackson\n    As a programmer one of your most useful tools is the regular expression. Like a trusty old hammer, Regexp is always ready and willing to parse your random bits of text with brutal precision and accuracy.\n\n    But there are some tasks for which regular expressions are not the best tool for the job. Parsing expressions are a relative newcomer in the field of text analysis. Libraries like Treetop and Citrus make it easy to use parsing expressions with Ruby. In this talk, we'll discuss potential applications for parsing expressions and how to use and test them in your Ruby code.\n\n  video_provider: \"youtube\"\n  video_id: \"_6h16aGz_eo\"\n\n- id: \"devlin-daley-mountainwest-rubyconf-2011\"\n  title: \"Essentials for Tech Startups\"\n  raw_title: \"MWRC 2011 - Essentials for Tech Startups\"\n  speakers:\n    - Devlin Daley\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-19\"\n  description: |-\n    By, Devlin Daley\n    Many in our community want to blaze their own trails with their own company. We'll cover the essentials for software startups: how to tell if you've got a viable idea, funding options, do's and dont's, business models and how to get things off the ground. These essentials apply to founders as well as those thinking of working for a startup.\n\n  video_provider: \"youtube\"\n  video_id: \"1KQ0v5uOog4\"\n\n- id: \"yehuda-katz-mountainwest-rubyconf-2011\"\n  title: \"Ruby: The Challenges Ahead\"\n  raw_title: \"MWRC 2011 - Ruby: The Challenges Ahead\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-19\"\n  description: |-\n    By, Yehuda Katz\n    Through Rails, Ruby has been thrust upon an adoring public. Over the past several years, Ruby has matured, with two world-class alternative implementation, a library for just about anything, and a community that values software engineering. There are still some challenges ahead, most notably concurrency, library maturity and language development itself.\n\n  video_provider: \"youtube\"\n  video_id: \"ZDgdwL3dE6E\"\n\n- id: \"bobby-wilson-mountainwest-rubyconf-2011\"\n  title: \"Confessions of a Data Junkie: Fetching, Parsing, and Visualization\"\n  raw_title: \"MWRC 2011 - Confessions of a Data Junkie: Fetching, Parsing, and Visualization\"\n  speakers:\n    - Bobby Wilson\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-19\"\n  description: |-\n    By, Bobby Wilson\n    This is not a scientific talk. It's a survey of each step in my process of creating something meaningful out of a pile of data. The talk will be a blend of anecdotes, process, data sources, tools available, and good ol' hacks. We live in a world filled with recorded data. Lots of that data is online, and retrievable in some fashion. Unfortunately, that data is often sparse, poorly labeled, and uninsured. Enter Ruby, with a wide variety of gems and libraries to help us trudge through funky data, store it, sort it out, and spit shine it for the masses.\n\n  video_provider: \"youtube\"\n  video_id: \"MC6j11rpcoY\"\n\n- id: \"wayne-e-seguin-mountainwest-rubyconf-2011\"\n  title: \"Ruby.is_a? Community # = true\"\n  raw_title: \"MWRC 2011 - Ruby.is_a? Community # = true\"\n  speakers:\n    - Wayne E. Seguin\n  event_name: \"MountainWest RubyConf 2011\"\n  date: \"2011-03-18\"\n  published_at: \"2015-02-19\"\n  description: |-\n    By, Wayne E. Seguin\n    The single most important driving force that has kept me going since I started working with Ruby is the community itself. I will discuss various aspects of why I love the Ruby community and present my thoughts on our unique and awesome community with it's rosy effervescent essence.\n\n  video_provider: \"youtube\"\n  video_id: \"wUa8HTT67Fo\"\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2012/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZ0cXIcLlmsFfhjAzg5uP0b\"\ntitle: \"MountainWest RubyConf 2012\"\nkind: \"conference\"\nlocation: \"Salt Lake City, UT, United States\"\ndescription: \"\"\npublished_at: \"2012-08-16\"\nstart_date: \"2012-03-15\"\nend_date: \"2012-03-17\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2012\nwebsite: \"https://web.archive.org/web/20140117085320/http://mtnwestrubyconf.org/2012/\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2012/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"will-leinweber-mountainwest-rubyconf-2012\"\n  title: \"Schemaless SQL - The Best of Both Worlds\"\n  raw_title: \"Schemaless SQL - The Best of Both Worlds\"\n  speakers:\n    - Will Leinweber\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-09-18\"\n  published_at: \"2012-09-17\"\n  description: |-\n    Schemaless database are a joy to use because they make it easy to iterate on your app, especially early on. The relational model isn't always the best fit for evolving and messy data in the real world. And let's be honest—it's painful to persist rich domain models across millions of little tables. However as your data model stabilizes, the lack of well-defined schemas becomes painful. On the other hand, relational databases are proven, robust, and powerful. How are we supposed to pick one or the other? Simple: pick both.\n\n    Recent advances in Postgres allow for a new hybrid approach. The hstore datatype brings key/value pairs to Postgres, and PLV8 embeds the super-fast V8 JavaScript engine into Postgres. These in turn make Postgres the best document database in the world. This talk will explore when and how to take advantage of them, and how we use these techniques at Heroku.\n\n  video_provider: \"youtube\"\n  video_id: \"r4lE4bxMJmk\"\n\n- id: \"bracken-mosbacker-mountainwest-rubyconf-2012\"\n  title: \"Hacking Education\"\n  raw_title: \"Hacking Education by Bracken Mosbacker\"\n  speakers:\n    - Bracken Mosbacker\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-09-18\"\n  published_at: \"2012-09-16\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zJVZpDFjGVk\"\n\n- id: \"ted-omeara-mountainwest-rubyconf-2012\"\n  title: \"UXDD (User Experience Driven Development): Build For Your Users, Not Your Tests\"\n  raw_title: \"UXDD (User Experience Driven Development): Build for your users, not your tests\"\n  speakers:\n    - Ted O'Meara\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-09-18\"\n  published_at: \"2012-09-15\"\n  description: |-\n    All too often programmers get into a productive rhythm where they receive their requirements, write tests aligned to those requirements, and then look for the green and red. While this process is proven to be highly effective, it can lead to developers missing the mark, as they aim for functional completeness and not the polish that an end user requires.\n\n    We should start proposing breakpoints for developers to step away from their automated tests, and play with the features they are working on. It's too easy for developers to get caught up in their process and forget about the end user experience. In this presentation you will learn several techniques for developing for the user experience, even when you're buried in code.\n\n  video_provider: \"youtube\"\n  video_id: \"JaJdNh9MeG0\"\n\n- id: \"matthew-kocher-mountainwest-rubyconf-2012\"\n  title: \"Devops for Developers - Why You Want To Run Your Own Site, And How\"\n  raw_title: \"Devops for Developers - Why you want to run your own site, and how by Matthew Kocher\"\n  speakers:\n    - Matthew Kocher\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-09-18\"\n  published_at: \"2012-09-15\"\n  description: |-\n    Devops is a buzzword, but in reduction it means putting the people who are responsible for new features in charge of getting them out there. At Pivotal Labs we work with 30 startups at a time, and have seen what works well and what makes developers cringe and slows down progress. I'd like to convince every developer to start running the sites they work on, embrace change throughout their infrastructure, and give some tips for how to do it along the way.\n\n  video_provider: \"youtube\"\n  video_id: \"KMZYow3clsU\"\n\n- id: \"angela-harms-mountainwest-rubyconf-2012\"\n  title: \"Does Pair Programming Have to Suck?\"\n  raw_title: \"Does Pair Programming Have to Suck?\"\n  speakers:\n    - Angela Harms\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-09-18\"\n  published_at: \"2012-09-15\"\n  description: |-\n    On some teams pairing is the norm; developers enjoy the collaboration & experience enhanced productivity. Others, though, work on teams where pairing is shunned, avoided, or just faked. Why do some craftsmen thrive with pairing while others want nothing to do with it? Why does coach- enforced pairing turn into something dry, distracted, imbalanced & ineffective? Effective pairing can increase creativity, energy, speed & quality. What factors make that possible? Learn how to take action on your team to put an end to soul-sucking, miserable, fake pair programming, and begin teaching your team to collaborate effectively on code.\n  video_provider: \"youtube\"\n  video_id: \"FLcfN9IBxyc\"\n\n- id: \"evan-d-light-mountainwest-rubyconf-2012\"\n  title: \"Frustration Driven Development\"\n  raw_title: \"Frustration Driven Development By Evan D. Light\"\n  speakers:\n    - Evan D. Light\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-09-18\"\n  published_at: \"2012-09-13\"\n  description: |-\n    Everyone draws inspiration and motivation from different sources.\n\n    For most, it's often frustration.\n\n    We make life decisions, define new features, or refactor code when we get too annoyed by current circumstances. This is where I admit that I have a low tolerance for frustration. Having been frustrated a great deal during my career, I'm going to discuss several anti-patterns that I've seen in code and how to use the Dark Side of the Force (frustration, anger, and rage) to escape from them.\n  video_provider: \"youtube\"\n  video_id: \"9oCjrlKXf4U\"\n\n- id: \"matt-white-mountainwest-rubyconf-2012\"\n  title: \"Continuous Deployment\"\n  raw_title: \"Continuous Deployment\"\n  speakers:\n    - Matt White\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-09-18\"\n  published_at: \"2012-09-13\"\n  description: |-\n    When you write code, how long is it before that code makes it to production? Days? Weeks? Months? LONGER?!?! Deploying code to production multiple times a day as automatically as possible will make all your dreams of green grassy meadows filled with rainbows and prancing unicorns and ponies come true. Or at least one or two of them.\n  video_provider: \"youtube\"\n  video_id: \"aYclrqk3gnU\"\n\n- id: \"michael-ji-jackson-mountainwest-rubyconf-2012\"\n  title: \"MiniTest: Write Awesome Tests\"\n  raw_title: \"MiniTest: Write Awesome Tests by Michael J.I. Jackson\"\n  speakers:\n    - Michael J.I. Jackson\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-08-16\"\n  published_at: \"2012-08-16\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6hBghQ-Ic_o\"\n\n- id: \"david-brady-mountainwest-rubyconf-2012\"\n  title: \"What's Wrong With Ruby's Object Model (And Why That's a Good Thing)\"\n  raw_title: \"What's Wrong With Ruby's Object Model (And Why That's a Good Thing) by David Brady\"\n  speakers:\n    - David Brady\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-08-16\"\n  published_at: \"2012-08-16\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"LmtcDFnOYj4\"\n\n- id: \"jack-danger-canty-mountainwest-rubyconf-2012\"\n  title: \"Keeping Your Code Strong\"\n  raw_title: \"Keeping your code strong by Jack Danger Canty\"\n  speakers:\n    - Jack Danger Canty\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-08-16\"\n  published_at: \"2012-08-16\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"7UP5aa4Zbmw\"\n\n- id: \"xavier-shay-mountainwest-rubyconf-2012\"\n  title: \"Business Intelligence with Ruby\"\n  raw_title: \"Business Intelligence with Ruby by Xavier Shay\"\n  speakers:\n    - Xavier Shay\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-08-16\"\n  published_at: \"2012-08-16\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"iOxKY32pxB8\"\n\n- id: \"mitchell-hashimoto-mountainwest-rubyconf-2012\"\n  title: \"Rack Middleware as a General Purpose Abstraction\"\n  raw_title: \"Rack Middleware as a General Purpose Abstraction by Mitchell Hashimoto\"\n  speakers:\n    - Mitchell Hashimoto\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-08-16\"\n  published_at: \"2012-08-15\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"i6pyhq3ZvyI\"\n\n- id: \"corey-woodcox-mountainwest-rubyconf-2012\"\n  title: \"Prying Into Your App's Private Life\"\n  raw_title: \"Prying into your app's private life by Corey Woodcox\"\n  speakers:\n    - Corey Woodcox\n  event_name: \"MountainWest RubyConf 2012\"\n  date: \"2012-08-16\"\n  published_at: \"2012-08-15\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"7-9oyOePKPE\"\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyazvc4Ib-TRyGirwi1z1ywc\"\ntitle: \"MountainWest RubyConf 2013\"\nkind: \"conference\"\nlocation: \"Salt Lake City, UT, United States\"\ndescription: \"\"\nstart_date: \"2013-04-03\"\nend_date: \"2013-04-05\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2013\nwebsite: \"https://web.archive.org/web/20171022010216/http://mtnwestrubyconf.org/2013/\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2013/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"sarah-mei-mountainwest-rubyconf-2013\"\n  title: \"Work, Play, & Code\"\n  raw_title: \"MountainWest RubyConf 2013 TBA by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"vyIKQlRz0FA\"\n\n- id: \"james-turnbull-mountainwest-rubyconf-2013\"\n  title: \"Hell Has Frozen Over: DevOps & Security\"\n  raw_title: \"MountainWest RubyConf 2013 Hell Has Frozen Over: DevOps & Security by James Turnbull\"\n  speakers:\n    - James Turnbull\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    A lot of Dev and Ops people look at their security teams with disdain: \"Those guys are arseholes. All they ever do is sit in meetings and tell us no.\" They know there's no way Security will ever embrace DevOps. In turn many security folks see the emergence of DevOps as the inmates being put in charge of the asylum. It'll all end in chaos and disaster.\n    So who's right? Can DevOps and security co-exist? Can they be friends? We will take a deeper look at:\n    What DevOps means for Security\n    How DevOps can be sold to Security\n    How DevOps changes the risk landscape for the better\n    How those Security folks might know some things that could make DevOps better\n    You'll see how DevOps and Security can have a long and prosperous friendship that makes more awesome.\n\n  video_provider: \"youtube\"\n  video_id: \"SsQF6zqzHKw\"\n\n- id: \"jason-roelofs-mountainwest-rubyconf-2013\"\n  title: \"Keep Ops Happy, Designing for Production\"\n  raw_title: \"MountainWest RubyConf 2013 Keep Ops Happy, Designing for Production by Jason Roelofs\"\n  speakers:\n    - Jason Roelofs\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    Building applications in Ruby is fast and fun. Features fly, progress is quick and everyone's happy, until you have to deploy. While services like Heroku make deployment easier than it ever has been before, there's only so much they can do for you, and no-one is happy when customers can't use your application!\n    This talk will go over steps developers can take to protect against common production errors as well as more advanced techniques to keep your application running smoothly over the long term.\n\n  video_provider: \"youtube\"\n  video_id: \"n7mtYj3dHt4\"\n\n- id: \"will-farrington-mountainwest-rubyconf-2013\"\n  title: \"Boxen: How to Manage an Army of Laptops and Live to Talk About It\"\n  raw_title: \"MountainWest RubyConf 2013 Boxen: How to Manage an Army of Laptops and Live to Talk About It\"\n  speakers:\n    - Will Farrington\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    Title: Boxen: How to Manage an Army of Laptops and Live to Talk About It\n    Presented by: Will  Farrington\n\n    At GitHub, we've been growing pretty quickly and that sort of growth presents a lot of challenges. We were feeling the pain of trying to teach everyone (developers and designers alike) how to get GitHub and all our other projects running on their laptops. The process was failure-prone, complex, and time-consuming. So, last summer, we created the first iteration of The Setup — GitHub's method of managing laptops without getting all authoritarian about it. We quickly realized that other organizations needed and wanted this environment, so we started back with the basics and re-architected The Setup into Boxen. The same tool, the same method, but written for modularity and general consumption.\n    We've since released Boxen (as of January 2013) and other organizations are using it to great success. This talk explores our design choices with Boxen, how we use Boxen internally, our recommended design patterns for managing Boxen-driven automation, and some new goodies coming down the pipeline for Boxen.\n\n  video_provider: \"youtube\"\n  video_id: \"4PDNK-eWjG4\"\n\n- id: \"lindsay-holmwood-mountainwest-rubyconf-2013\"\n  title: \"Escalating Complexity: DevOps Learnings From Air France 447\"\n  raw_title: \"MountainWest RubyConf 2013 Escalating complexity: DevOps learnings from Air France 447\"\n  speakers:\n    - Lindsay Holmwood\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    Title: Escalating complexity: DevOps learnings from Air France 447\n    Presented by: Lindsay Holmwood\n\n    On June 1, 2009 Air France 447 crashed into the Atlantic ocean killing all 228 passengers and crew. The 15 minutes leading up to the impact were a terrifying demonstration of the how thick the fog of war is in complex systems.\n    Mainstream reports of the incident put the blame on the pilots - a common motif in incident reports that conveniently ignore a simple fact: people were just actors within a complex system, doing their best based on the information at hand.\n    While the systems you build and operate likely don't control the fate of people's lives, they share many of the same complexity characteristics. Dev and Ops can learn an abundance from how the feedback loops between these aviation systems are designed and how these systems are operated.\n    In this talk Lindsay will cover what happened on the flight, why the mainstream explanation doesn't add up, how design assumptions can impact people's ability to respond to rapidly developing situations, and how to improve your operational effectiveness when dealing with rapidly developing failure scenarios.\n\n  video_provider: \"youtube\"\n  video_id: \"WqxzpGJbzmI\"\n\n- id: \"drew-blas-mountainwest-rubyconf-2013\"\n  title: \"Migrating a Live Site Across The Country Without Downtime\"\n  raw_title: \"MountainWest RubyConf 2013 Migrating a live site across the country without downtime\"\n  speakers:\n    - Drew Blas\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    Title: Migrating a live site across the country without downtime\n    Presented by: Drew Blas\n\n    Chargify.com's customers rely on us to process payments for them 24 hours a day. We do not have any planned maintenance windows: we're simply expected to be up all the time. We recently migrated from a private datacenter to EC2, moving all our operations and data across the country with zero downtime. All thanks to a combination of highly-automated configuration with Chef and specialized DB tools like Tungsten.\n    You'll learn about our pain points in planning the switchover, like:\n    Synchronizing data\n    Cross DC communication & VPNs\n    Redirecting traffic\n    Redundancy\n    Migrating Redis/Resque\n    Automation\n    And most importantly, how we addressed every one! I'll demonstrate how we rebuilt our entire infrastructure platform from the ground up: New system images with all new cookbooks that were deployed into our existing operation without any interruption. Finally, I'll discuss testing our stack and how we replicate it among various environments and plan for future expansion.\n\n  video_provider: \"youtube\"\n  video_id: \"3YqBeWjaaPM\"\n\n- id: \"paul-biggar-mountainwest-rubyconf-2013\"\n  title: \"The Many Ways to Deploy Continuously\"\n  raw_title: \"MountainWest RubyConf 2013 The Many Ways to Deploy Continuously by Paul  Biggar\"\n  speakers:\n    - Paul Biggar\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    So...Continuous Deployment. You hear that you should be practicing continuous deployment, but nobody every pointed out that there are many different ways to do it!\n    This talk compares and contrasts different kinds of continuous deployment strategies. Implementation, requirements, tradeoffs will be covered. Case-studies, examining different strategies practiced at companies such as Facebook, GitHub, IMVU, Heroku and CircleCI.\n\n  video_provider: \"youtube\"\n  video_id: \"9wgsDosgWhE\"\n\n- id: \"seth-vargo-mountainwest-rubyconf-2013\"\n  title: \"TDDing tmux\"\n  raw_title: \"MountainWest RubyConf 2013 TDDing tmux by Seth Vargo\"\n  speakers:\n    - Seth Vargo\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    You want to test your cookbooks? Cool. Where do you start? In this talk, I'll walk you through step-by-step the process for executing test-driven development on a cookbook. From real-time feedback with guard and terminal-notifier, to chefspec, fauxhai, and foodcritic, quickly learn how to apply both basic and advanced tests in your infrastructure.\n\n  video_provider: \"youtube\"\n  video_id: \"ZC91gZv-Uao\"\n\n- id: \"joshua-timberman-mountainwest-rubyconf-2013\"\n  title: \"You Should Be On Call, too\"\n  raw_title: \"MountainWest RubyConf 2013 You Should Be On Call, too by Joshua Timberman\"\n  speakers:\n    - Joshua Timberman\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    One of the reasons for the DevOps movement is that all developers should carry pagers and be on call, right?\n    Well, not quite. However, there is a common area of conflict between operations and development teams about site outages related to application-related issues that developers know how to debug and fix much faster than operations typically does.\n    In this talk, I'll discuss some companies that have successfully implemented developers on call\" policies and what that means. I'll also discuss the business value, why it matters, and how it helps create a collaborative culture of sharing.\n\n  video_provider: \"youtube\"\n  video_id: \"ac_M_7jZAwc\"\n\n- id: \"jesse-newland-mountainwest-rubyconf-2013\"\n  title: \"ChatOps at GitHub\"\n  raw_title: \"MountainWest RubyConf 2013 ChatOps at GitHub by Jesse Newland\"\n  speakers:\n    - Jesse Newland\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    Ops at GitHub has a unique challenge - keeping up with the rabid pace of features and products that the GitHub team develops. In this talk, we'll focus on tools and techniques we use to rapidly and confidently ship infrastructure changes using Campfire and Hubot as our primary interface, and the benefits we've seen from this approach.\n\n  video_provider: \"youtube\"\n  video_id: \"-LxavzqLHj8\"\n\n- id: \"yukihiro-matz-matsumoto-mountainwest-rubyconf-2013\"\n  title: \"Keynote: Ruby 2.0\"\n  raw_title: \"MountainWest RubyConf 2013 Ruby 2.0 by Yukihiro 'Matz' Matsumoto\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-05-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zQvmgN-0imY\"\n\n- id: \"john-pignata-mountainwest-rubyconf-2013\"\n  title: \"Code Smells: Your Refactoring Cheat Codes\"\n  raw_title: \"MountainWest RubyConf 2013 Code Smells: Your Refactoring Cheat Codes by John Pignata\"\n  speakers:\n    - John Pignata\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    Sure, the TDD cycle is red-green-refactor but what exactly are we refactoring? We just wrote the code, it's green, and it seems reasonable to us. Let's move onto the next test. We're have a deadline, remember?\n    Whether we're working with code we just wrote or opening up a project for the first time, being able to listen to the hints the code is trying to give you about how it wants to be constructed is the most direct path toward successful refactoring. What the code is telling you nuanced however: no code smell is absolute and none in itself is an indication of a problem. How do we know we need to refactor? What are the code smells telling us to do? How do we balance our short terms needs of shipping our software with the long term maintainability of the code base? In this talk we'll talk through some of the classical code smells and dive into examples of how to put these smells to work for you.\n\n  video_provider: \"youtube\"\n  video_id: \"q_qdWuCAkd8\"\n\n- id: \"michael-fairley-mountainwest-rubyconf-2013\"\n  title: \"Immutable Ruby\"\n  raw_title: \"MountainWest RubyConf 2013 Immutable Ruby by Michael Fairley\"\n  speakers:\n    - Michael Fairley\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    Most Ruby code makes heavy use of mutable state, which often contributes to long term maintenance problems. Mutability can lead to code that's difficult to understand, libraries and applications that aren't thread-safe, and tests that are slow and brittle. Immutability, on the other hand, can make code easy to reason about, safe to use in multi-threaded environments, and simple to test. Doesn't that sound nice?\n    This talk answers the question \"\"why immutability?\"\", covers the building blocks of immutable code, such as value objects and persistent data structures, as well as higher order concepts that make heavy use of immutability, such as event sourcing and pure functions, and finally discusses the tradeoffs involved in going immutable.\n\n  video_provider: \"youtube\"\n  video_id: \"VnC_JccUPkw\"\n\n- id: \"aja-hammerly-mountainwest-rubyconf-2013\"\n  title: \"Going on a Testing Anti-Pattern Safari\"\n  raw_title: \"MountainWest RubyConf 2013 Going on a Testing Anti-Pattern Safari by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    Wild test suites often contain inefficient or ineffective tests. Working with a code base full of these beasts is frustrating and time consuming. This safari will help you identify and hunt down common testing anti-patterns. Afterwards you'll know how to approach a test suite full of beasts without losing your mind or your life.\n\n  video_provider: \"youtube\"\n  video_id: \"VBgySRk0VKY\"\n\n- id: \"jason-clark-mountainwest-rubyconf-2013\"\n  title: \"DIY::Thread.profile -- Light-Weight Profiling in Pure Ruby\"\n  raw_title: \"MountainWest RubyConf 2013 DIY::Thread.profile -- Light-Weight Profiling in Pure Ruby\"\n  speakers:\n    - Jason Clark\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    Title: DIY::Thread.profile -- Light-Weight Profiling in Pure Ruby\n    Presented by: Jason Clark\n\n    Whether your application is concurrent or not, there's insight to be gained from Ruby's threading support.\n    This talk demonstrates building a light-weight sampling profiler in pure Ruby. The techniques are simple enough to integrate into almost any application, and fast enough for even a production environment. If you've ever wondered exactly what your application is doing at any given moment, this will show you how to find out.\n    Along the way we'll expose gotchas and pitfalls of thread introspection on the many versions and implementations of Ruby. Based on experience implementing thread profiling for New Relic, we'll also touch on how to debug and work around problems when they come up\n\n  video_provider: \"youtube\"\n  video_id: \"sOJaGIP03As\"\n\n- id: \"daniel-huckstep-mountainwest-rubyconf-2013\"\n  title: \"Ruby Batteries Included\"\n  raw_title: \"MountainWest RubyConf 2013 Ruby Batteries Included by Daniel Huckstep\"\n  speakers:\n    - Daniel Huckstep\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: |-\n    The ruby standard library is full of great code. It's also full of dragons. I'll show you some of fun parts, parts that you may not be using and may not even know about. I'll show you that you don't have to install everything on GitHub to build your application. I'll also look at some of nasty parts, and how to put a training collar on some of those dragons.\n\n  video_provider: \"youtube\"\n  video_id: \"BAfy3IgVpjY\"\n\n- id: \"corey-woodcox-mountainwest-rubyconf-2013\"\n  title: \"Ruby In My yard!\"\n  raw_title: \"MountainWest RubyConf 2013 Ruby in my yard! by Corey Woodcox\"\n  speakers:\n    - Corey Woodcox\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: |-\n    Look, I know you love your sprinkler timer, with its endearing little dials and simple, easy-to-use interface, and its killer dot-matrix LCD.\n    We thought we could do better, and we thought Ruby could help us. With the awesomeness of things like the Raspberry Pi and maybe a little Arduino, who's to say I can't use Ruby to water my lawn, remind me to fertilize, or let me know where I could save a little water?\n    We'll take you on a quick tour of the automated sprinkler system world and the problems it has, and how we're solving them with Ruby, Raspberry Pi, and about 24V of DC power. We promise not to electrocute you, but we can't guarantee you won't get a little bit wet.\n\n  video_provider: \"youtube\"\n  video_id: \"Fxtr7UstV1g\"\n\n- id: \"andy-pliszka-mountainwest-rubyconf-2013\"\n  title: \"Extending CRuby With Native Graph Data Type\"\n  raw_title: \"MountainWest RubyConf 2013 Extending CRuby with native Graph data type by Andy Pliszka\"\n  speakers:\n    - Andy Pliszka\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: |-\n    Reading of the CRuby source code can provide unparalleled insight into the Ruby language. During this talk we will add new native Graph data type to CRuby. The new Graph data structure will be simple but on par with other native types such as Array or Hash. This talk will demonstrate that it is easy to experiment with CRuby and extend it. We will also demonstrate the speed advantage of using C to boost Ruby performance. We will implement a few of the greatest hits of graph algorithms: Breath First Search, Dijkstra, and Minimum Spanning Tree.\n\n  video_provider: \"youtube\"\n  video_id: \"0ZzGhHdWJnY\"\n\n- id: \"matthew-kocher-mountainwest-rubyconf-2013\"\n  title: \"Ruby off the Rails: Building a Distributed System in Ruby\"\n  raw_title: \"MountainWest RubyConf 2013 Ruby off the Rails: Building a distributed system in Ruby\"\n  speakers:\n    - Matthew Kocher\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: |-\n    Title: Ruby off the Rails: Building a distributed system in Ruby\n    Presented by: Matthew Kocher\n\n    Devops Borat said \"is turtle all way down but at bottom is perl script, but in the case of Cloud Foundry there's Ruby at the bottom. Rails is the right choice for building a web site, but the elegance of ruby can be applied to many other things including a Platform as a Service. A full deploy of Cloud Foundry requires many different kinds of nodes, with multiple Sinatra apps, event machine based daemons, shared ruby gems, and small amounts of code in other languages like Lua, Go and C where it makes sense. I'd like to take you on a tour of an open source codebase and project that really shows where you can go with Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"G1VAjiesXio\"\n\n- id: \"eleanor-mchugh-mountainwest-rubyconf-2013\"\n  title: \"Adventures in Paranoia with Sinatra and Sequel\"\n  raw_title: \"MountainWest RubyConf 2013 Adventures in Paranoia with Sinatra and Sequel by Eleanor McHugh\"\n  speakers:\n    - Eleanor McHugh\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: |-\n    This session is a jolly romp through the realm of practical data privacy using pure Ruby. We'll start by looking at how to obfuscate data using Ruby's OpenSSL bindings, exploring the possibilities of symmetric and public key cryptography as well as the role of hashing algorithms.\n    Once the basic principles have been established we'll turn our attention to designing databases with a strong privacy component, using Sequel to demonstrate how encrypted keys can be used to support privacy in the relational model. There will be some meta-programming involved which should also be of interest to ActiveRecord users. This will naturally lead into a brief discussion of the seeming difficulty of searching encrypted data along with a strategy for making this practical.\n    We'll round out the session by turning our attention to the transport layer with a simple scheme for securing web application sessions using a custom Rack middleware.\n    The discussion will be backed by code examples inspired by real-world systems.\n\n  video_provider: \"youtube\"\n  video_id: \"entIQBaOTqA\"\n\n- id: \"ryan-davis-mountainwest-rubyconf-2013\"\n  title: \"Trolls of 2013\"\n  raw_title: \"MountainWest RubyConf 2013 Trolls of 2013 by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"r1JMxJ06I98\"\n\n- id: \"ward-cunningham-mountainwest-rubyconf-2013\"\n  title: \"Pounding Simplicity into Wiki\"\n  raw_title: \"MountainWest RubyConf 2013 Pounding Simplicity into Wiki by Ward Cunningham\"\n  speakers:\n    - Ward Cunningham\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-05-02\"\n  description: |-\n    I wrote the first wiki in a week. Why has it taken me a year to write another? Short answer: when something is already surprisingly simple its hard to make it simpler.\n    This last year I set out to do for numbers what I had done for words, give them depth and meaning that ordinary people can depend on every day. A wiki, like a glossary, defines the terms we choose to use. A data-wiki makes those choices more complex. Its no longer one click to check a definition. Its more like one more study to check a dataset, to see if the data says what we think it does. Not a simple process.\n    My quest has been to make knowing and using data an everyday thing. This means the study of data must be an everyday thing too. To this end I've pushed visualization, I've pushed domain specific markups, I've pushed streaming measurements. But through this I've retained wiki's greatest strength: the ability to create with those who we have just met and don't yet have reason to trust. Finding trust on the modern web may be this year's biggest accomplishment.\n\n  video_provider: \"youtube\"\n  video_id: \"mAM4_MUiCZQ\"\n\n- id: \"bill-chapman-mountainwest-rubyconf-2013\"\n  title: \"Think Twice, Code Once\"\n  raw_title: \"MountainWest RubyConf 2013 Think twice, code once by Bill Chapman\"\n  speakers:\n    - Bill Chapman\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: |-\n    The basic premise is that we should be spending significantly more time thinking than we do programming and there are wide reaching ramifications to this point. Subtleties in how our non programming coworkers perceive some of us wandering around the office pacing or arguing at the white board are all to be covered as well as discussing the body of research that supports the ideas behind thinking more and working less.\n\n  video_provider: \"youtube\"\n  video_id: \"Kiox36WH_lc\"\n\n- id: \"brandon-keepers-mountainwest-rubyconf-2013\"\n  title: \"Ruby at GitHub\"\n  raw_title: \"MountainWest RubyConf 2013 Ruby at GitHub by Brandon Keepers\"\n  speakers:\n    - Brandon Keepers\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: |-\n    GitHub loves Ruby. Many of our products, tools and infrastructure are built with Ruby.\n    In this talk, we will look at the libraries, practices and conventions that GitHub uses with Ruby. We will survey all of the repositories maintained by GitHub to get insight into how it is used, and we will also examine some of the areas where we opt to not use Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"5vUD9Zg7gp0\"\n\n- id: \"shai-rosenfeld-mountainwest-rubyconf-2013\"\n  title: \"Testing HTTP APIs with Ruby\"\n  raw_title: \"MountainWest RubyConf 2013 Testing HTTP APIs with Ruby by Shai Rosenfeld\"\n  speakers:\n    - Shai Rosenfeld\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: |-\n    Good integration tests are hard. There are many approaches for fully testing server and client libraries for those HTTP APIs - all with various tradeoffs and problems that come up. Some are obvious, some are a little more tricky.\n    I'll run through some approaches and problems I've come across developing server/client HTTP APIs while developing in a highly distributed systems setup at Engine Yard.\n\n  video_provider: \"youtube\"\n  video_id: \"Bz0KrmCrhIY\"\n\n- id: \"craig-kerstiens-mountainwest-rubyconf-2013\"\n  title: \"Postgres Demystified\"\n  raw_title: \"MountainWest RubyConf 2013 Postgres Demystified by Craig Kerstiens\"\n  speakers:\n    - Craig Kerstiens\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: |-\n    \"Postgres has long been known as a stable database product that reliably stores your data. However, in recent years it has picked up many features, allowing it to become a much sexier database.\n    We'll cover a whirlwind of Postgres features, which highlight why you should consider it for your next project. These include:\n    Datatypes\n    Using other languages within Postgres\n    Extensions including NoSQL inside your SQL database\n    Accessing your non-Postgres data (Redis, Oracle, MySQL) from within Postgres\n    Window Functions\n\n  video_provider: \"youtube\"\n  video_id: \"3TnVl97ZZL8\"\n\n- id: \"stephan-hagemann-mountainwest-rubyconf-2013\"\n  title: \"Component-based Architectures in Ruby and Rails\"\n  raw_title: \"MountainWest RubyConf 2013 Component-based Architectures in Ruby and Rails by Stephan Hagemann\"\n  speakers:\n    - Stephan Hagemann\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-29\"\n  description: |-\n    It's true that goods are better distributable when they are in packages. That is the common view of what Ruby gems and Rails engines are: packages for distribution. This perception misses the great value that comes from packaging without distribution. That is what makes component-based architectures: a helpful tool for organizing growing codebases. We'll talk about how to do this with (and without) Ruby on Rails.\n    Ruby makes it a bit hard to do packages right: you really can't hide anything. Rails doesn't want you to do it. I don't care. We'll do it anyways and it will be awesome!\n\n  video_provider: \"youtube\"\n  video_id: \"-54SDanDC00\"\n\n- id: \"lightning-talks-mountainwest-rubyconf-2013\"\n  title: \"Lightning Talks\"\n  raw_title: \"MountainWest RubyConf 2013 Lightning Talks\"\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"XYk1YkCRuKQ\"\n  talks:\n    - title: \"Lightning Talk: MountainWest RubyConf 5k\"\n      start_cue: \"00:20\"\n      end_cue: \"02:28\"\n      id: \"jon-jensen-lighting-talk-mountainwest-rubyconf-2013\"\n      video_id: \"jon-jensen-lighting-talk-mountainwest-rubyconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Jon Jensen\n\n    - title: \"Lightning Talk: On the Place You'll Code\"\n      start_cue: \"02:28\"\n      end_cue: \"03:35\"\n      id: \"aja-hammerly-lighting-talk-mountainwest-rubyconf-2013\"\n      video_id: \"aja-hammerly-lighting-talk-mountainwest-rubyconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Aja Hammerly\n\n    - title: \"Lightning Talk: dress_code - Styleguides\"\n      start_cue: \"03:35\"\n      end_cue: \"06:00\"\n      id: \"ryan-florence-lighting-talk-mountainwest-rubyconf-2013\"\n      video_id: \"ryan-florence-lighting-talk-mountainwest-rubyconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Ryan Florence\n\n    - title: \"Lightning Talk: oh_god_why_calculator\"\n      start_cue: \"06:00\"\n      end_cue: \"08:29\"\n      id: \"nora-howard-lighting-talk-mountainwest-rubyconf-2013\"\n      video_id: \"nora-howard-lighting-talk-mountainwest-rubyconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Nora Howard\n\n    - title: \"Lightning Talk: Hacking Ruby\"\n      start_cue: \"08:29\"\n      end_cue: \"13:06\"\n      id: \"pete-higgins-lighting-talk-mountainwest-rubyconf-2013\"\n      video_id: \"pete-higgins-lighting-talk-mountainwest-rubyconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Pete Higgins\n\n    - title: \"Lightning Talk: Help Me Name This Thing\"\n      start_cue: \"13:06\"\n      end_cue: \"19:30\"\n      id: \"don-morrison-lighting-talk-mountainwest-rubyconf-2013\"\n      video_id: \"don-morrison-lighting-talk-mountainwest-rubyconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Don Morrison\n\n    - title: \"Lightning Talk: Hexagonal Architecture with Rails\"\n      start_cue: \"19:30\"\n      end_cue: \"23:10\"\n      id: \"matthew-thorley-lighting-talk-mountainwest-rubyconf-2013\"\n      video_id: \"matthew-thorley-lighting-talk-mountainwest-rubyconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Matthew Thorley\n\n    - title: \"Lightning Talk: Take Back Your Mental RAM - The Strategy to Learn All The Things\"\n      start_cue: \"23:10\"\n      end_cue: \"31:40\"\n      id: \"tyler-bird-lighting-talk-mountainwest-rubyconf-2013\"\n      video_id: \"tyler-bird-lighting-talk-mountainwest-rubyconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Tyler Bird\n\n    - title: \"Lightning Talk: Wild Romance - A Tale of Digital Passion\"\n      start_cue: \"31:40\"\n      end_cue: \"43:17\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2013-1\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2013-1\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name https://cln.sh/gthmW3KX\n\n    - title: \"Lightning Talk: Developer Productivity\"\n      start_cue: \"43:17\"\n      end_cue: \"TODO\"\n      id: \"paul-biggar-lighting-talk-mountainwest-rubyconf-2013\"\n      video_id: \"paul-biggar-lighting-talk-mountainwest-rubyconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Paul Biggar\n\n- id: \"greg-baugues-mountainwest-rubyconf-2013\"\n  title: \"Devs and Depression\"\n  raw_title: \"MountainWest RubyConf 2013 Devs and Depression by Greg  Baugues\"\n  speakers:\n    - Greg Baugues\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-30\"\n  description: |-\n    I am a developer, and I have Type II BiPolar and ADHD.\n    It's not something we talk about, but BiPolar, depression, and ADHD runs rampant in the developer community - they tend to correlate with higher intelligence. Many of the symptoms of this conditions make for great developers, but also cause incredible damage. We recently lost one of our co-workers because of untreated mental illness.\n    I want to share my story - and let people know that it's okay to talk about these things, that it's nothing to be ashamed of, and how to get help, and how to help those around them.\n\n  video_provider: \"youtube\"\n  video_id: \"yFIa-Mc2KSk\"\n\n- id: \"gene-kim-mountainwest-rubyconf-2013\"\n  title: \"Why We Need DevOps Now: A Fourteen Year Study Of High Performing IT Organizations\"\n  raw_title: \"MountainWest RubyConf 2013 Why We Need DevOps Now: A Fourteen Year Study Of High Performing IT...\"\n  speakers:\n    - Gene Kim\n  event_name: \"MountainWest RubyConf 2013\"\n  date: \"2020-01-28\"\n  published_at: \"2013-04-27\"\n  description: |-\n    Title: Why We Need DevOps Now: A Fourteen Year Study Of High Performing IT Organizations\n    Presented by: Gene Kim\n\n    Gene Kim will present his findings from an ongoing study of how high-performing IT organizations simultaneously deliver stellar service levels and deliver fast flow of new features into the production environment. To successfully deliver against what on the surface appear to be conflicting objectives, (i.e. preserving service levels while introducing significant amounts of change into production), requires creating a highly-coordinated collection of teams where Development, QA, IT Operations, as well as Product Management and Information Security genuinely work together to solve business objectives.\n    Gene will describe what successful transformations look like, and how those transformations were achieved from a software development and service operations perspective. He will draw upon fourteen years of research of high-performing IT organizations, as well as work he's done since 2008 to help some of the largest Internet companies increase feature flow and production stability through applications of DevOps principles.\n\n  video_provider: \"youtube\"\n  video_id: \"disjFj4ruHg\"\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybwu-NByNoeOrDuBBxHDZ-q\"\ntitle: \"MountainWest RubyConf 2014\"\nkind: \"conference\"\nlocation: \"Salt Lake City, UT, United States\"\ndescription: \"\"\nstart_date: \"2014-03-20\"\nend_date: \"2014-03-21\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2014\nwebsite: \"https://web.archive.org/web/20171022010216/http://mtnwestrubyconf.org/2014/\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2014/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk date\n# TODO: schedule website\n\n- id: \"ryan-davis-mountainwest-rubyconf-2014\"\n  title: \"Nerd Party, v3.1\"\n  raw_title: \"MountainWest RubyConf 2014 - Nerd Party, v 3.1 by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-23\"\n  description: |-\n    Founded in 2002, Seattle.rb is the first and oldest ruby group in the world. We've evolved a lot over the years and have found a balance that I think works very well for many, if not most, groups. Seattle.rb has also had a study group off-and-on for a few years. We've tackled doozies like SICP but also programmed games in Racket (scheme). I will share the recipe for our user group and study group as well as the trade-offs we've made over the years and what they meant to us.\n\n  video_provider: \"youtube\"\n  video_id: \"AK-gVWh_vZ8\"\n\n- id: \"nick-howard-mountainwest-rubyconf-2014\"\n  title: \"Generate Parsers! Prevent Exploits!\"\n  raw_title: \"MountainWest RubyConf 2014 - Generate Parsers! Prevent Exploits! by Nick Howard\"\n  speakers:\n    - Nick Howard\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-22\"\n  description: |-\n    Exploits happen when attackers discover that your application is actually an interpreter for a weird programming language with operators like 'make admin', or 'consume all available memory'. Don't give them access to that kind of computational power! Stop them at the very boundaries of your application's input handling--the parser. By generating parsers tailored to the specific input formats of your app, you can prevent it from becoming a weird interpreter and make it harder to exploit.\n    When you use a parser specific to your input format, it's not only more secure, it's better specified and definite. When you have a grammar for your inputs, you can give your API consumers better error messages and better documentation based on that grammar.\n    Using Ruby's metaprogramming superpowers, doing this doesn't have to be a painful process. I've been working on a library called Muskox that aims to make generating parsers almost as simple as using Rails 4's Strong Parameters. Writing code to secure your app's inputs should be easy, fun and fast.\n\n  video_provider: \"youtube\"\n  video_id: \"4EwuuSLr2Lk\"\n\n- id: \"andy-pliszka-mountainwest-rubyconf-2014\"\n  title: \"Introduction to CRuby source code\"\n  raw_title: \"MountainWest RubyConf 2014 - Introduction to CRuby source code by Andy Pliszka\"\n  speakers:\n    - Andy Pliszka\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-22\"\n  description: |-\n    Understanding of CRuby source code has profound effects on every Ruby developer. In my talk, I will show you how to build Ruby from source. I will explain how to install and configure your new Ruby build on Mac and Linux. I will walk you through CRuby source code and introduce you to a few of the most important CRuby files. I will show you how to hack CRuby and modify some of the fundament Ruby classes in C. I will demonstrate how to write complete Ruby classes in C. Finally, I will show you that CRuby code can run 100 times faster than Ruby code. I hope that this talk will inspire you to learn more about CRuby and hack it on your own.\n\n  video_provider: \"youtube\"\n  video_id: \"9oH6sL2sKvw\"\n\n- id: \"sam-rawlins-mountainwest-rubyconf-2014\"\n  title: \"New Ruby 2.1 Awesomeness: Pro Object Allocation Tracing\"\n  raw_title: \"MountainWest RubyConf 2014 - New Ruby 2.1 Awesomeness: Pro Object Allocation Tracing\"\n  speakers:\n    - Sam Rawlins\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-22\"\n  description: |-\n    By Sam Rawlins\n\n    Ruby 2.1 is coming out soon with an amazing new feature under ObjectSpace: #trace_object_allocations. We are now able to trace the file and line number (as well as method) where any Ruby object is allocated from. This is a very welcome feature, as object-level tracing has been very difficult in Ruby, especially since the memprof gem could not support Ruby past 1.8.x.\n    This new Ruby 2.1 feature is really just exposing some raw (and vast) data, so it can be difficult to tease out meaningful information. Two gems are introduced in this talk to solve just that problem. The objspace-stats gem allows us to view and summarize new object allocations in meaningful ways. We'll look at how to filter, group, and sort new object allocations. The second gem is rack-objspace-stats. We'll see how this tool can intercept requests to a Rack stack, and measure new object allocations taking place during the request. (For those familiar, this works very similar to the rack-perftools_profiler gem.)\n    We'll look at various examples of how this new Ruby 2.1 feature, and these tools can help an organization reduce unnecessary memory allocations, and speed up their code, especially mature Rack applications.\n\n  video_provider: \"youtube\"\n  video_id: \"ViUvz4FCDxg\"\n\n- id: \"christopher-sexton-mountainwest-rubyconf-2014\"\n  title: \"The Other Junk Drawer: My Tests are a Mess\"\n  raw_title: \"MountainWest RubyConf 2014 - The Other Junk Drawer: My Tests are a Mess\"\n  speakers:\n    - Christopher Sexton\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-22\"\n  description: |-\n    By Christopher Sexton\n\n    Is your test suite comprehensible to someone new to the project? Can you find where you tested that last feature? Do you have to wade through dozens of files to deal with updated code?\n    Organizing tests are hard. It is easy to make things overly elaborate and complicated. Learn an approach to grouping the tests together in a way that makes sense. We can test drive without creating overly brittle tests. Lets build better designed projects by keeping our test suite clear and understandable.\n\n  video_provider: \"youtube\"\n  video_id: \"ZoT5qrAUkT0\"\n\n- id: \"mario-gonzalez-mountainwest-rubyconf-2014\"\n  title: \"Re-thinking Regression Testing\"\n  raw_title: \"MountainWest RubyConf 2014 - Re-thinking Regression Testing by Mario Gonzalez\"\n  speakers:\n    - Mario Gonzalez\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-22\"\n  description: |-\n    Regression testing is invaluable to knowing if changes to code have broken the software. However, it always seems to be the case that no matter how many tests you have in your regression buckets, bugs continue to happily creep in undetected. As a result, you are not sure if you can trust your tests anymore or your methodology, and you are ready to change that. I will present a powerful technique called mutation testing that will help make your tests capable of detecting future bugs. I will also give you a metric to assess the effectiveness of your tests in terms of regression, so that future changes in your software can be done with impunity.\n    Audience will learn:\n    What mutation testing is and why it works.\n    When and how to apply mutation testing.\n    How to improve their tests so they detect bugs that are introduced during the normal evolution of software.\n\n  video_provider: \"youtube\"\n  video_id: \"H8lBCI_TQ8E\"\n\n- id: \"sarah-mei-mountainwest-rubyconf-2014\"\n  title: \"Unpacking Technical Decisions\"\n  raw_title: \"MountainWest RubyConf 2014 - Unpacking Technical Decisions by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-22\"\n  description: |-\n    As engineers working on a team, we all make technical decisions. What's the best way to implement this? Where should this function live? Is this library worth using? Some decisions, though, are larger, riskier and more important than that. But generally, they're also far less frequent.\n    Right now, your team might be struggling to organize the client-side parts of your application. Ember? Angular? Backbone? Flip a coin? Uh...which one has the most...retweets? These choices don't need to be arbitrary or based on vague personal preference. Come learn a more useful and realistic approach that makes large-scale technical decisions less risky.\n\n  video_provider: \"youtube\"\n  video_id: \"FzzL_QDKv0c\"\n\n- id: \"nathan-long-mountainwest-rubyconf-2014\"\n  title: \"Big O in a Homemade Hash\"\n  raw_title: \"MountainWest RubyConf 2014 - Big O in a Homemade Hash by Nathan Long\"\n  speakers:\n    - Nathan Long\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-22\"\n  description: |-\n    Rubyists use hashes all the time. But could you build Ruby's Hash class from scratch?\n    In this talk, I'll walk you through it. We'll learn what it takes to get the interface we want and maintain O(1) performance as it grows.\n\n  video_provider: \"youtube\"\n  video_id: \"NMwyWBtSiGM\"\n\n- id: \"barrett-clark-mountainwest-rubyconf-2014\"\n  title: \"How to Prototype an Airport\"\n  raw_title: \"MountainWest RubyConf 2014 - How to Prototype an Airport by Barrett Clark\"\n  speakers:\n    - Barrett Clark\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-28\"\n  description: |-\n    I transformed my office building into an airport using a combination of Ruby, Objective-C, and a number of hardware hacks. The goal was to prototype a better in-airport experience using a mixture of GPS and iBeacon technology to establish precise indoor geolocation.\n    This talk will run down the various stages of the project, an overview of outdoor vs indoor location technologies, and how the iPhone (and Android) devices currently handle location. I'll also discuss how I built a robust Ruby backend, and how I hacked some hardware together to create iBeacons.\n\n  video_provider: \"youtube\"\n  video_id: \"Pxp6ukQFFb8\"\n\n- id: \"ernie-miller-mountainwest-rubyconf-2014\"\n  title: \"Dont.\"\n  raw_title: \"MountainWest RubyConf 2014 - Dont. by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-22\"\n  description: |-\n    We all know that intelligent species learn from mistakes, right?\n    There's just one problem: Life is too short to make every possible mistake! Also, some mistakes are more costly than others. What's the ambitious learner to do? I'm glad you asked! I'm an expert at making mistakes, and I'm happy to share as many of them as I can possibly fit into a 45-minute time slot with you, my dear conference attendee!\n    We'll discuss a variety of exciting mistakes, ranging from the misapplication of metaprogramming techniques to letting emotions become barriers to new technologies to why it's a horrible idea to stretch a gel keyboard wrist rest across a room, even if it seems like an awesome plan at the time.\n\n  video_provider: \"youtube\"\n  video_id: \"7UT3pDD7XK8\"\n\n- id: \"randy-coulman-mountainwest-rubyconf-2014\"\n  title: \"Affordance in Programming Languages\"\n  raw_title: \"MountainWest RubyConf 2014 - Affordance in Programming Languages by Randy Coulman\"\n  speakers:\n    - Randy Coulman\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-23\"\n  description: |-\n    A good design communicates the intended use of an object. In the physical world, this communication is accomplished by \"affordances\", as discussed by Donald Norman in \"The Psychology of Everyday Things\".\n    Programming languages also have affordances, and they influence the kinds of solutions we develop. The more languages we know, the more we \"expand our design space\" so that we can come up with better solutions to the problems we face every day.\n\n  video_provider: \"youtube\"\n  video_id: \"aQu18GXl74Q\"\n\n- id: \"aja-hammerly-mountainwest-rubyconf-2014\"\n  title: \"A World Without Assignment\"\n  raw_title: \"MountainWest RubyConf 2014 - A World Without Assignment by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-23\"\n  description: |-\n    In OO, assignment is one of our main tools. Most developers learn how to store values in variables shortly after learning \"Hello World\". By contrast, functional programming makes much less use of assignment and mutation. Instead techniques like function composition, recursion, and anonymous functions are used to produce the same results that OO programmers produce with side effects.\n    Despite being object oriented, Ruby easily accommodates pure functional approaches. This talk will demonstrate how common programming tasks can be accomplished without assignment or mutation. Ruby and Scheme (a Lisp dialect) will be used for examples. I'll also discuss some of the great resources available for those interested in digging deeper into functional programming.\n\n  video_provider: \"youtube\"\n  video_id: \"Qyn4NyeftUE\"\n\n- id: \"benjamin-curtis-mountainwest-rubyconf-2014\"\n  title: \"Five Machine Learning Techniques That You Can Use In Your Ruby Apps Today\"\n  raw_title: \"MountainWest RubyConf 2014 - Five machine learning techniques that....\"\n  speakers:\n    - Benjamin Curtis\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-23\"\n  description: |-\n    Five machine learning techniques that you can use in your Ruby apps today By Benjamin Curtis\n\n    Machine learning is everywhere these days. Features like search, voice recognition, recommendations - they've become so common that people have started to expect them. They're starting to expect the apps we build to be smarter.\n    Ten years ago, machine learning and data mining techniques were only available to the people dedicated enough to dig through the math. Now that's not the case.\n    The most common machine learning techniques are well known. Standard approaches have been developed. And, fortunately for us, many of these are available as ruby gems. Some are even easy to implement yourself.\n    In this presentation we'll cover five important machine learning techniques that can be used in a wide range of applications. It will be a wide and shallow introduction, for Rubyists, not mathematicians - we'll have plenty of simple code examples.\n    By the end of the presentation, you won't be an expert, but you'll know about a class of tools you may not have realized were available.\n\n  video_provider: \"youtube\"\n  video_id: \"crziu7dk6Vw\"\n\n- id: \"matthew-kirk-mountainwest-rubyconf-2014\"\n  title: \"Test Driven Neural Networks with Ruby\"\n  raw_title: \"MountainWest RubyConf 2014 - Test Driven Neural Networks with Ruby by Matthew Kirk\"\n  speakers:\n    - Matthew Kirk\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-23\"\n  description: |-\n    Neural networks are an excellent way of mapping past observations to a functional model. Many researchers have been able to build tools to recognize handwriting, or even jaundice detection. While Neural Networks are powerful they still are somewhat of a mystery to many. This talk aims to explain neural networks in a test driven way. We'll write tests first and go through how to build a neural network to determine what language a sentence is. By the end of this talk you'll know how to build neural networks with tests!\n\n  video_provider: \"youtube\"\n  video_id: \"mWZ1SPgx80g\"\n\n- id: \"john-athayde-mountainwest-rubyconf-2014\"\n  title: \"The Timeless Way of Building\"\n  raw_title: \"MountainWest RubyConf 2014 - The Timeless Way of Building by John Athayde\"\n  speakers:\n    - John Athayde\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-23\"\n  description: |-\n    \"Design patterns\" is a common phrase that is often spoken in the course of design and development of web applications. But it's genesis is not from programming, but Architecture. They come from a trio of books in the 1970s by Christopher Alexander, the most famous of which is the middle book: \"A Pattern Language\". The issue arises that Pattern Languages, much like spoken languages, are most effective when the speaker is fluent.\n    We'll look at the origin of pattern languages and why they can be dangerous and even detrimental tools in the hands of the inexperienced designer and developer through examples of bad grammar and poor idiomatic choices(aka antipatterns), and perhaps some architecture as well.\n\n  video_provider: \"youtube\"\n  video_id: \"DJJbIjlLmLM\"\n\n- id: \"noel-rappin-mountainwest-rubyconf-2014\"\n  title: \"But Really, You Should Learn Smalltalk\"\n  raw_title: \"MountainWest RubyConf 2014 - But Really, You Should Learn Smalltalk\"\n  speakers:\n    - Noel Rappin\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-28\"\n  description: |-\n    By Noel Rappin\n\n    Smalltalk has mystique. We talk about it more than we use it.\n    It seems like it should be so similar to Ruby. It has similar Object-Oriented structures, it even has blocks.\n    But everything is so slightly different, from the programming environment, to the 1-based arrays, to the simple syntax. Using Smalltalk will make you look at familiar constructs with new eyes.\n    We'll show you how to get started on Smalltalk, and walk through some sample code. Live coding may be involved.\n    You'll never look at objects the same way again.\n\n  video_provider: \"youtube\"\n  video_id: \"eGaKZBr0ga4\"\n\n- id: \"johnny-t-mountainwest-rubyconf-2014\"\n  title: \"MagLev - From Download to Deploy\"\n  raw_title: \"MountainWest RubyConf 2014 - MagLev - From Download to Deploy by Johnny T\"\n  speakers:\n    - Johnny T\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-23\"\n  description: |-\n    MagLev is a Ruby implementation built on top of a mature VM which offers native object persistence. Working with these live objects is awesome - but this image-based development is very different than traditional file-based development. MagLev uses both which has broad reaching effects - from design to deployment.\n    In traditional applications, data and code are separate. Deployments involve pulling new code, updating or migrating the data-store, and restarting or reloading the application which creates a new runtime with this new code.\n    MagLev's transient objects behave in this same manner, but committed objects are always there. Migrating these live, persistent objects is quite different. Your 'data' migrations involve things like instance variables, method definitions and class hierarchies, rather than creating tables or updating column definitions.\n    In this talk we will walk through a number of examples including a simple job and worker which use persisted blocks, and how to deploy an application and migrate persisted objects.\n\n  video_provider: \"youtube\"\n  video_id: \"-sH2lSW2BGo\"\n\n- id: \"eileen-m-uchitelle-mountainwest-rubyconf-2014\"\n  title: \"CRUD! The Consequences of Not Understanding How ActiveRecord Translates into MySQL\"\n  raw_title: \"MountainWest RubyConf 2014 - CRUD! The Consequences of Not Understanding How ActiveRecord ...\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-23\"\n  description: |-\n    By Eileen Uchitelle\n\n    The magic of ActiveRecord database interactions is easy to rely on and allows us assume it knows best. Without a solid understanding of how ActiveRecord translates into MySQL, however, significant issues can arise. This is particularly true with large data sets and complex model relationships. My talk explores an example for each CRUD function and shows how these queries can result in MySQL timeouts, memory issues or stack level too deep errors. The examples will examine the consequences of chaining large datasets, uses for Arel, and how to avoid encountering major problems and most importantly, how these queries can be rewritten to run more efficiently.\n\n  video_provider: \"youtube\"\n  video_id: \"lOpVcqiAIiI\"\n\n- id: \"julian-simioni-mountainwest-rubyconf-2014\"\n  title: \"Software Development Lessons from the Apollo Program\"\n  raw_title: \"MountainWest RubyConf 2014 - Software Development Lessons from the Apollo Program\"\n  speakers:\n    - Julian Simioni\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-23\"\n  description: |-\n    By Julian Simioni\n\n    In August 1961, the MIT Instrument Laboratory was awarded the contract for a guidance system to fly men to the moon, the first contract for the entire Apollo Program. The word software was not mentioned anywhere. Six years later, 400 engineers were employed on the project writing software.\n    The resulting Apollo Guidance Computer is to this day a marvel of engineering. It included a realtime operating system and even a software interpreter. Despite weighing 70 pounds, it ran on only 50W of power. Only one guidance computer was present in each Apollo spacecraft, with no backups: it never failed in thousands of hours of space flight. Before the first work on UNIX or the C programming language had begun, the Apollo Guidance Computer had already taken men to the moon.\n    NASA and MIT kept meticulous records, giving us the opportunity to look back today on some of the pioneers of our industry, relive their experiences, and maybe learn a few things ourselves.\n\n  video_provider: \"youtube\"\n  video_id: \"jYe2bF7tc2Q\"\n\n- id: \"aaron-patterson-mountainwest-rubyconf-2014\"\n  title: \"A Magical Gathering\"\n  raw_title: \"MountainWest RubyConf 2014 - A Magical Gathering by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"MountainWest RubyConf 2014\"\n  date: \"2014-03-17\"\n  published_at: \"2014-04-22\"\n  description: |-\n    Let's roll up our sleeves, and learn about Ruby and OpenCV. Let there be coding. Let there be learning. But most of all, let this be the most magical of all gatherings. I've put on my robe and my wizard hat, now lets make magic happen!\n\n  video_provider: \"youtube\"\n  video_id: \"pIC35tsfUmw\"\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybKenrGRnvqtCIsniljlpIp\"\ntitle: \"MountainWest RubyConf 2015\"\nkind: \"conference\"\nlocation: \"Salt Lake City, UT, United States\"\ndescription: \"\"\npublished_at: \"2015-03-29\"\nstart_date: \"2015-03-09\"\nend_date: \"2015-03-10\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\nwebsite: \"https://web.archive.org/web/20170804074306/http://mtnwestrubyconf.org/2015/\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2015/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"akira-matsuda-mountainwest-rubyconf-2015\"\n  title: \"A Quest for the Ultimate Template Engine\"\n  raw_title: \"MountainWest RubyConf 2015 - A Quest for the Ultimate Template Engine\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-29\"\n  published_at: \"2015-03-29\"\n  description: |-\n    by Akira Matsuda\n    I’m sure you have to choose a template engine when you’re working on a web app. So almost everyone here must have your favourite template engine, I guess.\n    Today I would like to tell a story about me and the Ruby template engines.\n    If you think you’re totally satisfied with your Ruby template engine, maybe you will learn that your template engine is not perfect. Or, for those who are already feeling unhappy with something in your template engine, I’ll tell you what you should do next.\n\n  video_provider: \"youtube\"\n  video_id: \"2Yx1x8Tl1KM\"\n\n- id: \"ryan-davis-mountainwest-rubyconf-2015\"\n  title: \"Standing on the Shoulders of Giants\"\n  raw_title: \"MountainWest RubyConf 2015 - Standing on the Shoulders of Giants\"\n  speakers:\n    - Ryan Davis\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-29\"\n  published_at: \"2015-03-29\"\n  description: |-\n    by Ryan Davis\n    Ruby is a fantastic language, but it could be better. While it has done a terrific job of taking ideas from languages like smalltalk, lisp, and (to an extent) perl, it hasn’t done nearly enough of it.\n    Big thinkers like Alan Kay & Dan Ingalls (smalltalk), David Ungar (self), Guy Steele & Gerald Sussman (scheme), and Matthias Felleisen (racket) have paved the way for so many programming language ideas that we should plunder the treasures that they’ve thought up. You might not know their names, but you’ve certainly used their technology.\n    I will survey a vast minority of these ideas and how they could help ruby. Ideas including: self-bootstrapping implementations and extensive collection and magnitude hierarchies from smalltalk, instance-based inheritance and JIT compilation from self, TCO and the overarching importance of lambdas from racket/scheme, and finally object level pattern matching and the combined object/lambda architecture from the View Points Research Institute.\n    Ruby is at its best when borrowing great ideas from other languages, but lately it has fallen behind in this. It’s time for ruby to step up and do more with these ideas, to keep pushing forward, to stand upon the shoulders of giants.\n\n  video_provider: \"youtube\"\n  video_id: \"lExm5LELpP4\"\n\n- id: \"matthew-clark-mountainwest-rubyconf-2015\"\n  title: \"The How and Why of Ruby\"\n  raw_title: \"MountainWest RubyConf 2015 - The How and Why of Ruby\"\n  speakers:\n    - Matthew Clark\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-29\"\n  published_at: \"2015-03-29\"\n  description: |-\n    by Matthew Clark\n    Ruby might be one of the easier languages for learning programming, but that doesn’t mean it holds the programmers hand in any way, or is somehow easy. Exactly the opposite. Ruby is flexible enough to allow coders to do just about anything the like, for better or worse. So why is it the language of choice at the coding bootcamps springing up across the country, when it allows new programmers to get into so much trouble? Are we doing these young programmers a disservice by teaching Ruby simply because we love our deliciously readable and expressive examples, or are we tapping into something better for students, an enlightened path that is more likely to propel them up and over the steeper learning curve Ruby demands? With Ruby, students are thrown into the deep end of a culture that believes strongly why we do things one way rather than another. There is a common goal to make the right way to do things also the easiest way. Collaboration is the norm, which is the best way to learn. I could go on, and I will, in the talk. I’ll expand on why Ruby is great as a first language because we are great as a community. We demand so much more from our junior programmers because the tooling is so good and the language is so approachable that students grasp advanced concepts much sooner on the path. We hold juniors to higher levels of quality, testing, and readability and they are better developers in the long run for it. Ruby is a great first language because discussions of the ‘how’ quickly give way to the ‘why’, and junior developers get it, and they don’t stay junior developers for long.\n\n  video_provider: \"youtube\"\n  video_id: \"5AJZ4EmdoHM\"\n\n- id: \"joe-mastey-mountainwest-rubyconf-2015\"\n  title: \"Building a Culture of Learning\"\n  raw_title: \"MountainWest RubyConf 2015 - Building a Culture of Learning\"\n  speakers:\n    - Joe Mastey\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-29\"\n  published_at: \"2015-03-29\"\n  description: |-\n    by Joe Mastey\n    Research shows that opportunities for learning and career growth within a company are hugely important for employee retention and engagement. We also know that in the software world our tools become obsolete every few years. And yet even the most enlightened employers leave it to their engineers to learn in their free time. We’ll discuss some relevant issues and approaches to the problem with an eye towards changes that work in the real, deadline-driven world of software development. We’ll also talk about several things that have or haven’t worked in my experience trying to build a culture of learning in a regulated financial services company. For example, a company that’s hesitant to delay critical projects for formal training may be fine with lunchtime workshops. Participants should walk away equipped to start building momentum at any level in their organization towards constant learning and improvement.\n\n  video_provider: \"youtube\"\n  video_id: \"V69Sinlp6Ew\"\n\n- id: \"mary-elizabeth-cutrali-mountainwest-rubyconf-2015\"\n  title: \"Meaningful Mentorship for Developers\"\n  raw_title: \"MountainWest RubyConf 2015 - Meaningful Mentorship for Developers\"\n  speakers:\n    - Mary Elizabeth Cutrali\n    - Danny Glunz\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-29\"\n  published_at: \"2015-03-29\"\n  description: |-\n    by Mary Elizabeth Cutrali and Danny Glunz\n    “The delicate balance of mentoring someone is not creating them in your own image, but giving them the opportunity to create themselves.” - Steven Spielberg\n    In our world of never ending Stack Overflow answers and Github code reviews, there still remains some knowledge that can only be found through experience. Mentoring relationships are an indispensable part of any developer’s career and allow for experiential knowledge transfer. Programming, as a culture, has an underdeveloped network of mentors. As a community, we need to turn mentorship from a wishful yearly resolution into a cultural reality.\n    We’ll use research from scholars like Kathy Kram and historical examples of mentor-protege pairs (think: Larry Page/Marissa Mayer ), to get to the bottom of what makes a successful pair tick. Finally, we’ll share some of our experience in putting this research into action so that you may join us in discovering what it takes to cultivate a meaningful mentorship.\n\n  video_provider: \"youtube\"\n  video_id: \"NdfLqbHETfg\"\n\n- id: \"john-paul-ashenfelter-mountainwest-rubyconf-2015\"\n  title: \"Learning Statistics Will Save Your Life\"\n  raw_title: \"MountainWest RubyConf 2015 - Learning Statistics Will Save Your Life\"\n  speakers:\n    - John Paul Ashenfelter\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-29\"\n  published_at: \"2015-03-29\"\n  description: |-\n    by John Paul Ashenfelter\n    Many of the greatest achievements in the history of computers are based on lies, or rather, the strategic sets of lies we generallly call “abstraction”. Operating systems lie to programs about hardware, multitasking systems lie to users about parallelism, Ruby lies to us about how easy it is to tell a CPU what to do… the list goes on and on.\n    One of the primary “strategic lies” of the internet is the presentation of each service as though it were a discrete, cohesive entity. When we use GitHub, we think of it as just “GitHub”, not a swarm of networked computers. This lie gives us the opportunity to build high availability applications: apps designed to never go down.\n    Let’s take a tour through the amazing stack of tools that helps us construct high availability applications. We’ll review some of the incredible technology underlying the internet: things like TCP, BGP, and DNS. Then we’ll talk about how these primitives combine into useful patterns at the application level. I hope you’ll leave with not only a renewed appreciation for the core innovations of the internet, but also some practical working knowledge of how to go about building and running a zero-downtime application.\n\n  video_provider: \"youtube\"\n  video_id: \"xsVF7BZTbU8\"\n\n- id: \"paul-hinze-mountainwest-rubyconf-2015\"\n  title: \"Smoke & Mirrors: The Primitives of High Availability\"\n  raw_title: \"MountainWest RubyConf 2015 - Smoke & Mirrors: The Primitives of High Availability\"\n  speakers:\n    - Paul Hinze\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-29\"\n  published_at: \"2015-03-29\"\n  description: |-\n    by Paul Hinze\n    Many of the greatest achievements in the history of computers are based on lies, or rather, the strategic sets of lies we generallly call “abstraction”. Operating systems lie to programs about hardware, multitasking systems lie to users about parallelism, Ruby lies to us about how easy it is to tell a CPU what to do… the list goes on and on.\n    One of the primary “strategic lies” of the internet is the presentation of each service as though it were a discrete, cohesive entity. When we use GitHub, we think of it as just “GitHub”, not a swarm of networked computers. This lie gives us the opportunity to build high availability applications: apps designed to never go down.\n    Let’s take a tour through the amazing stack of tools that helps us construct high availability applications. We’ll review some of the incredible technology underlying the internet: things like TCP, BGP, and DNS. Then we’ll talk about how these primitives combine into useful patterns at the application level. I hope you’ll leave with not only a renewed appreciation for the core innovations of the internet, but also some practical working knowledge of how to go about building and running a zero-downtime application.\n\n  video_provider: \"youtube\"\n  video_id: \"pF22enUhMXw\"\n\n- id: \"coraline-ada-ehmke-mountainwest-rubyconf-2015\"\n  title: \"Data-Driven Refactoring\"\n  raw_title: \"MountainWest RubyConf 2015 - Data-Driven Refactoring\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-29\"\n  published_at: \"2015-03-29\"\n  description: |-\n    by Coraline Ehmke\n    There are dozens of code metrics tools available to Rubyists, all eager to judge our codebases and tell us things that we probably already know. But when technical debt is piled high and feature friction really sets in, we need more than to know that our User class has a “D” grade. How can we use tools and tests to help us formulate a refactoring plan that amounts to more than just rearranging bricks in a crumbling building? Let’s explore some of the more interesting code analysis tools, take a look at our testing techniques, and find novel ways to combine them into a meaningful refactoring strategy.\n\n  video_provider: \"youtube\"\n  video_id: \"AcdliNixNhs\"\n\n- id: \"michael-ries-mountainwest-rubyconf-2015\"\n  title: \"Conventions Between Applications\"\n  raw_title: \"MountainWest RubyConf 2015 - Conventions Between Applications\"\n  speakers:\n    - Michael Ries\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-29\"\n  published_at: \"2015-03-29\"\n  description: |-\n    by Michael Ries\n    Rails gives us great conventions for building an application, but what conventions should we use when we are building a whole system that encompasses multiple applications? How should we name things? What abstraction layers should we enforce?\n    The MX team has been building a distributed system composed of Rails applications for the last 3 years. We’ll talk about failed ideas, conventions that have stood the test of time and some experiments that are underway.\n\n  video_provider: \"youtube\"\n  video_id: \"efwZwalqTP0\"\n\n- id: \"randy-coulman-mountainwest-rubyconf-2015\"\n  title: \"Solving Ricochet Robots\"\n  raw_title: \"MountainWest RubyConf 2015 - Solving Ricochet Robots\"\n  speakers:\n    - Randy Coulman\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-29\"\n  published_at: \"2015-03-29\"\n  description: |-\n    by Randy Coulman\n    Ricochet Robots is a puzzle board game for any number of players. While being a very fun game to play with some fascinating properties, it is also interesting to think about writing a program to play the game.\n    Let’s discuss a computerized player for Ricochet Robots that finds the optimal solution to any board in a reasonable amount of time. Along the way, we’ll learn about graph search techniques, data representation, algorithms, heuristics, pruning, and optimization.\n\n  video_provider: \"youtube\"\n  video_id: \"fvuK0Us4xC4\"\n\n- id: \"ernie-miller-mountainwest-rubyconf-2015\"\n  title: \"Humane Development\"\n  raw_title: \"MountainWest RubyConf 2015 - Humane Development\"\n  speakers:\n    - Ernie Miller\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-30\"\n  published_at: \"2015-03-30\"\n  description: |-\n    by Ernie Miller\n    Agile. Scrum. Kanban. Waterfall. TDD. BDD. OOP. FP. AOP. WTH?\n    As a software developer, I can adopt methodologies so that I feel there’s a sense of order in the world.\n    There’s a problem with this story: We are humans, developing software with humans, to benefit humans. And humans are messy.\n    We wrap ourselves in process, trying to trade people for personas, points, planning poker, and the promise of predictability. Only people aren’t objects to be abstracted away. Let’s take some time to think through the tradeoffs we’re making together.\n\n  video_provider: \"youtube\"\n  video_id: \"8ruIrbuh8Mg\"\n\n- id: \"jamis-buck-mountainwest-rubyconf-2015\"\n  title: \"Twisty Little Passages\"\n  raw_title: \"MountainWest RubyConf 2015 - Twisty Little Passages\"\n  speakers:\n    - Jamis Buck\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-30\"\n  published_at: \"2015-03-30\"\n  description: |-\n    by Jamis Buck\n    A live coding session. Real maze algorithms. 3D surfaces. Animations, first-person fly-throughs of spherical and toroidal mazes. Hexagons, octagons, and regular tilings. Mazes in shapes you never even dreamed of.\n    Coloring techniques. Rendering techniques. Visualization. HOLY MOTHER OF THESEUS! This is going to be so hot.\n    But bring a seat belt, because it’s going to move really, really fast. Don’t blink or you’ll miss something awesome. Maybe bring some eye drops, too, because your eyes will get really dry from all that NOT BLINKING.\n    Think I’m joking? Show up and call my bluff.\n\n  video_provider: \"youtube\"\n  video_id: \"qP9LTUrLcjA\"\n\n- id: \"starr-horne-mountainwest-rubyconf-2015\"\n  title: \"SVG Charts and Graphics with Ruby\"\n  raw_title: \"MountainWest RubyConf 2015 - SVG charts and graphics with Ruby\"\n  speakers:\n    - Starr Horne\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-30\"\n  published_at: \"2015-03-30\"\n  description: |-\n    by Starr Horne\n    Many people assume that the only way to add interesting charts and visualizations to their web applications is via JavaScript. But this isn’t true. You don’t need a 900 kB JavaScript library to generate simple charts. Instead you can use SVG and Ruby.\n    Once you learn how to build your own SVG graphics then it’s possible to do cool things like cache them, or use your own CSS and JavaScript to manipulate them. This presentation will show you how.\n\n  video_provider: \"youtube\"\n  video_id: \"_1c2rkSJYwk\"\n\n- id: \"ben-eggett-mountainwest-rubyconf-2015\"\n  title: \"Writing Music with Ruby: A Subtle Introduction to Music Theory\"\n  raw_title: \"MountainWest RubyConf 2015 - Writing Music with Ruby: A subtle introduction to music theory\"\n  speakers:\n    - Ben Eggett\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-30\"\n  published_at: \"2015-03-30\"\n  description: |-\n    by Ben Eggett\n    I want to teach you a bit about music theory and how to write music, using ruby. I’ll also walk you through some principles of audio engineering along the way.\n    I’ll teach you how to write notes, octaves, chromatic scales, major scales, minor scales, modes, thirds, chords, chord scales, chord progressions and more.\n\n  video_provider: \"youtube\"\n  video_id: \"ZEgqzOkGJ7U\"\n\n- id: \"brian-knapp-mountainwest-rubyconf-2015\"\n  title: \"Message Oriented Programming\"\n  raw_title: \"MountainWest RubyConf 2015 - Message Oriented Programming\"\n  speakers:\n    - Brian Knapp\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-30\"\n  published_at: \"2015-03-30\"\n  description: |-\n    by Brian Knapp\n    “I’m sorry that I long ago coined the term “objects” for this topic because it gets many people to focus on the lesser idea. The big idea is “messaging” - that is what the kernal of Smalltalk/Squeak is all about (and it’s something that was never quite completed in our Xerox PARC phase).” - Alan Kay\n    Object oriented programming is what gets a lot of attention, and it is often set in opposition to functional programming. However, it seems that OOP with its focus on classes, inheritence, and polymorphism missed what Alan Kay was really working on - messaging systems.\n    In this talk we will examine the fundamental pieces to what I am calling message oriented programming. We will look at the request/response message pattern, we will look at the structure of messages themselves, and we will look at how protocols can be created to enforce a sane message passing system.\n    We will also look at how this fits with Ruby, OOP, FP, and modern distributed computing patterns like REST, SOA and microservices. They are all related an it’s clear that message oriented programming has a place in the programmer’s toolbox. In fact, we are already using message oriented program to power modern applications, we just don’t know it yet.\n\n  video_provider: \"youtube\"\n  video_id: \"zN6eSf9I7Ck\"\n\n- id: \"jeremy-evans-mountainwest-rubyconf-2015\"\n  title: \"Better Routing Through Trees\"\n  raw_title: \"MountainWest RubyConf 2015 - Better Routing Through Trees\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-30\"\n  published_at: \"2015-03-30\"\n  description: |-\n    by Jeremy Evans\n    This presentation will describe an approach to routing web requests efficiently through the use of a routing tree. A routing tree usually routes requests by looking at the first segment in request path, and sending it to the routing tree branch that handles that segment, repeating until the entire path is processed.\n    At any point while handling a request, the routing tree can operate on the request, for things like enforcing access control or object retrieval from a database, where such behavior is common for the entire branch. In addition to considering the request path, a routing tree also usually considers the request method, and may consider information from the request headers or request body when deciding how to route a request.\n    A routing tree’s request handling is similar to how a file system processes requests for files, where it looks at the first segment of the path, sees if it is a directory, and if so, looks for the rest of the path inside that directory.\n    This presentation will describe what makes routing requests using a routing tree faster and simpler than the routing approaches used by the popular ruby web frameworks.\n\n  video_provider: \"youtube\"\n  video_id: \"PjnlsIJYkn0\"\n\n- id: \"aja-hammerly-mountainwest-rubyconf-2015\"\n  title: \"Forensic Log Analysis with BigQuery\"\n  raw_title: \"MountainWest RubyConf 2015 - Forensic Log Analysis with BigQuery\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-30\"\n  published_at: \"2015-03-30\"\n  description: |-\n    by Aja Hammerly\n    It is a fact of life: When you are running a website stuff goes wrong. Someone puts a dictionary on the keyboard and reloads your site a million times. Your mobile app hits an error state and sends messages that cause 500s on your server. An external service takes 5 times as long as normal to respond to a request.\n    When responding to problems logs are frequently our go to for investigating events but plain logs aren’t user friendly or efficient. Using BigQuery for log investigation lets you use familiar tools like SQL to dig into your logs, extract the interesting data, and even make charts of the data.\n\n  video_provider: \"youtube\"\n  video_id: \"2lSQxe9y84Y\"\n\n- id: \"john-crepezzi-mountainwest-rubyconf-2015\"\n  title: \"On Memory\"\n  raw_title: \"MountainWest RubyConf 2015 - On Memory\"\n  speakers:\n    - John Crepezzi\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-30\"\n  published_at: \"2015-03-30\"\n  description: |-\n    by John Crepezzi\n    Ruby doesn’t require developers to manage memory. It definitely makes our work less frustrating, but losing sight of the memory implications of our code, will get us into trouble! In this talk, I’ll go over common (and less common) memory pitfalls, why they work the way they do, and how to avoid them.\n\n  video_provider: \"youtube\"\n  video_id: \"yxhrYiqatdA\"\n\n- id: \"justin-campbell-mountainwest-rubyconf-2015\"\n  title: 'Make Up Your Own \"Hello, World!\"'\n  raw_title: 'MountainWest RubyConf 2015 - Make up your own \"Hello, World!\"'\n  speakers:\n    - Justin Campbell\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-30\"\n  published_at: \"2015-03-30\"\n  description: |-\n    by Justin Campbell\n    We all love Ruby. Maybe we’ve only been paid to write code in Ruby (and maybe JavaScript). But there are so many other languages out there, and they all have strengths, weaknesses, and very different communities surrounding them.\n    Let’s talk about language exploration. We’ll discuss how to learn a new language, considerations when introducing things to production, and come up with some ideas for Ruby and it’s ecosystem. Plan on dipping your toes in Elixir, Go, Haskell, Rust, and Scala during the session.\n\n  video_provider: \"youtube\"\n  video_id: \"lkVI4JmnMAM\"\n\n- id: \"barrett-clark-mountainwest-rubyconf-2015\"\n  title: \"Good Enough\"\n  raw_title: 'MountainWest RubyConf 2015 -  \"Good Enough\"'\n  speakers:\n    - Barrett Clark\n  event_name: \"MountainWest RubyConf 2015\"\n  date: \"2015-03-30\"\n  published_at: \"2015-03-30\"\n  description: |-\n    by Barrett Clark\n    As a programmer, work-life balance has always been a tricky thing for me. Steve Wozniak commented that “you can’t stop the steamroller of technology change.” That notion has been applied to software. If you rest you risk being squished.\n    I wrestle with impostor syndrome, and maybe this is just an extension of that. As a rubyist it’s difficult to keep up. Everything evolves quickly (ruby, rails, gems, related technologies, methodologies). I consider myself a full stack developer, and a stubborn one at that. I’ve fought with a Makefile for weeks just to get some package to compile on some *nix variant.\n    We are paid for our ability to solve problems. It requires a lot of practice. I’ve learned to be ok with not knowing how to do things, but I still “hear the footsteps.” I don’t really know what it means to be “good enough” yet, but this talk will explore those lines between work/life balance and how we keep our edge on the job while being present in the moments off the job.\n\n  video_provider: \"youtube\"\n  video_id: \"KawLiSRwJHo\"\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2016/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybjaXiRW_mjOuw1JGrWsCdt\"\ntitle: \"MountainWest RubyConf 2016\"\nkind: \"conference\"\nlocation: \"Salt Lake City, UT, United States\"\ndescription: \"\"\nstart_date: \"2016-03-21\"\nend_date: \"2016-03-22\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2016\nwebsite: \"https://web.archive.org/web/20170804074306/http://mtnwestrubyconf.org/2016/\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/mountainwest-rubyconf/mountainwest-rubyconf-2016/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"ernie-miller-mountainwest-rubyconf-2016\"\n  title: \"How to Build a Skyscraper\"\n  raw_title: \"Mountain West Ruby 2016 - How to Build a Skyscraper by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-12\"\n  published_at: \"2016-04-12\"\n  description: |-\n    How to Build a Skyscraper by Ernie Miller\n\n    Since 1884, humans have been building skyscrapers. This means that we had 6 decades\n    of skyscraper-building experience before we started building software (depending\n    on your definition of “software”). Maybe there are some lessons we can learn from\n    past experience?\\nThis talk won’t make you an expert skyscraper-builder, but you\n    might just come away with a different perspective on how you build software.\n\n  video_provider: \"youtube\"\n  video_id: \"DQTBmYI_XEE\"\n\n- id: \"davy-stevenson-mountainwest-rubyconf-2016\"\n  title: \"Orders of Magnitude\"\n  raw_title: \"Mountain West Ruby 2016 - Orders of Magnitude by Davy Stevenson\"\n  speakers:\n    - Davy Stevenson\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-12\"\n  published_at: \"2016-04-12\"\n  description: |-\n    Orders of Magnitude by Davy Stevenson\n\n    Up until the 17th century, the world was mostly limited to what we could see with the naked eye. Our understanding of things much smaller and much larger than us was limited. In the past 400 years our worldview has increased enormously, which has led to the advent of technology, space exploration, computers and the internet. However, our brains are ill equipped to handle dealing with numbers at these scales, and attempt to trick us at every turn.\n    Software engineers deal with computers every day, and thus we are subject to both incredibly tiny and massively large numbers all the time. Learn about how your brain is fooling you when you are dealing with issues of latency, scalability, and algorithm optimization, so that you can become a better programmer.\n\n  video_provider: \"youtube\"\n  video_id: \"ZihfySx4CWY\"\n\n- id: \"michael-ries-mountainwest-rubyconf-2016\"\n  title: \"Ruby is For Fun and Robots\"\n  raw_title: \"Mountain West Ruby 2016 - Ruby is For Fun and Robots by Michael Ries\"\n  speakers:\n    - Michael Ries\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-12\"\n  published_at: \"2016-04-12\"\n  description: |-\n    Ruby is For Fun and Robots by Michael Ries\n\n    Most of us use ruby for work, but do we still use it for fun? Is maximizing your webscale for optimal\n    synergy getting you down? Let’s talk about something fun you can do with ruby\n    and robots instead.\n\n  video_provider: \"youtube\"\n  video_id: \"kdIkSv1Gulk\"\n\n- id: \"brandon-hays-mountainwest-rubyconf-2016\"\n  title: \"Surviving the Framework Hype Cycle\"\n  raw_title: \"Mountain West Ruby 2016 - Surviving the Framework Hype Cycle by Brandon Hays test\"\n  speakers:\n    - Brandon Hays\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-12\"\n  published_at: \"2016-04-12\"\n  description: |-\n    Surviving the Framework Hype Cycle by  Brandon Hays test\n\n    Baskin Robbins wishes it had as many flavors as there are JS frameworks, build tools, and cool new “low-level” languages. You just want to solve a problem, not have a 500-framework bake-off! And how will you know whether you picked the right one? Don’t flip that table, because we’ll use the “hype cycle” and the history of Ruby and Rails as a guide to help you understand which front-end and back-end technologies are a fit for your needs, wants, and career now and in the future.\n\n  video_provider: \"youtube\"\n  video_id: \"9zc4DSTRGeM\"\n\n- id: \"ryan-davis-mountainwest-rubyconf-2016\"\n  title: \"Writing a Test Framework From Scratch\"\n  raw_title: \"Mountain West Ruby 2016 - Writing a Test Framework From Scratch by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-12\"\n  published_at: \"2016-04-12\"\n  description: |-\n    Writing a Test Framework From Scratch by Ryan Davis\n\n    Assertions (or expectations) are the most important part of any test framework. How are they written? What happens when one fails? How does a test communicate its results? Past talks have shown how test frameworks work from the very top: how they find, load, select, and run tests. Instead of reading code from the top, we’ll write code from scratch starting with assertions and building up a full test framework. By the end, you’ll know how every square inch of your testing framework works.\n\n  video_provider: \"youtube\"\n  video_id: \"56ZB3XBjMxc\"\n\n- id: \"eileen-m-uchitelle-mountainwest-rubyconf-2016\"\n  title: \"Security is Broken: Understanding Common Vulnerabilities\"\n  raw_title: \"Mountain West Ruby 2016 - Security is Broken: Understanding Common Vulnerabilities\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-12\"\n  published_at: \"2016-04-12\"\n  description: |-\n    Understanding Common Vulnerabilities by Eileen Uchitelle\n\n    The Internet is built on technology that was never meant to work together. Basic features in\n    seemingly simple and innocuous technologies, such as XML, resulted in these technologies\n    being insecure. In this session we’ll talk about how attackers exploit well known\n    vulnerabilities like XSS, XXE, and CSRF and how to make more secure software by\n    avoiding similar decisions that resulted in these exploits.\n  video_provider: \"youtube\"\n  video_id: \"b0_8zi7Mpi0\"\n\n- id: \"aja-hammerly-mountainwest-rubyconf-2016\"\n  title: \"Sharpening The Axe: Self-Teaching For Developers\"\n  raw_title: \"Mountain West Ruby 2016 - Sharpening The Axe: Self-Teaching For Developers Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-12\"\n  published_at: \"2016-04-12\"\n  description: |-\n    Sharpening The Axe: Self-Teaching For Developers Aja Hammerly\n\n    Many of us get a few years into our career and get stuck in a rut. Maybe we stop reading\n    about the latest and greatest in tech. Maybe we start managing and do less coding\n    than we’d like. Maybe life gets in the way and coding becomes drudgery.\\nOne way\n    to combat this feeling is to focus on learning. I’ll share what I’ve learned about\n    juggling self improvement with being a professional nerd. I’ll talk about the\n    courses, tools, books, and other resources I’ve found most useful. You’ll leave\n    this talk with several ideas for breaking out of your own developer rut.\n  video_provider: \"youtube\"\n  video_id: \"3Ee1WYl51TM\"\n\n- id: \"abraham-sangh-mountainwest-rubyconf-2016\"\n  title: \"TDD For Your Soul: Virtue Through Software Development\"\n  raw_title: \"Mountain West Ruby 2016 - TDD For Your Soul: Virtue Through Software Development by Abraham Sangh\"\n  speakers:\n    - Abraham Sangha\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-13\"\n  published_at: \"2016-04-13\"\n  description: |-\n    TDD For Your Soul: Virtue Through Software Development by Abraham Sangha\n\n    Web development pushes us to our limits, not only of cognition, but, perhaps surprisingly, of character. Using the cardinal virtues as a framework, we can see that developers need courage to learn, temperance to prioritize goals, a sense of justice by which to discern obligations, and wisdom to choose our path. By being honest about where we lack virtue, and implementing steps to develop character, we can perform test-driven development on ourselves. This process can help us grow not only as developers, but as human beings.\n\n  video_provider: \"youtube\"\n  video_id: \"rBkMubifO4I\"\n\n- id: \"kerri-miller-mountainwest-rubyconf-2016\"\n  title: \"The Minimum Viable Conference\"\n  raw_title: \"Mountain West Ruby 2016 - The Minimum Viable Conference by Kerri Miller & Jeremy Flores\"\n  speakers:\n    - Kerri Miller\n    - Jeremy Flores\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-13\"\n  published_at: \"2016-04-13\"\n  description: |-\n    The Minimum Viable Conference by Kerri Miller & Jeremy Flores\n\n    Ok, so, if nothing else, we’ve got one thing in common. We like conferences. The two of us like ‘em so much that we recently spent a large chunk of time and money organizing and hosting one, and are planning at least one more for next year, too. Ask us about it!\n    We’re here to spill the beans on what it takes to make these things happen. We’ll do our damndest to tell you everything you need to know to get your own conference off the ground. We’ll cover topics like:\n    How many people do you need? To attend? To organize?\n    Where’s the money come from?\n    How do you get sponsors?\n    How do you run a CFP?\n    What are the easy wins and hard losses?\n    For what services do you pay versus those you seek for free?\n    How do you protect yourself and your fellow organizers?\n    Who buys the beer?\n    Whether you’re planning a multi-day conference, a monthly meetup, or just a one-time get-together for your office, we’ll give you a handy list of DOs and DONTs, based on our own experiences and those of others in the community event game. Like Kerri’s Gramma once said, “If you want to go to a party, sometimes you have to throw it yourself.”\n\n  video_provider: \"youtube\"\n  video_id: \"6XYg9XNrfuQ\"\n\n- id: \"aaron-patterson-mountainwest-rubyconf-2016\"\n  title: \"How Are Method Calls Formed?\"\n  raw_title: \"Mountain West Ruby 2016 - How Are Method Calls Formed? by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-13\"\n  published_at: \"2016-04-13\"\n  description: |-\n    How Are Method Calls Formed? by Aaron Patterson\n\n    Today, we’ll dive in to optimizations we can make on method dispatch including various types of\n    inline method caching. Audience members should leave with a better understanding\n    of Ruby’s VM internals as well as ways to analyze and optimize their own code.\n\n  video_provider: \"youtube\"\n  video_id: \"6Dkjus07d9Y\"\n\n- id: \"jamis-buck-mountainwest-rubyconf-2016\"\n  title: \"Second Wind\"\n  raw_title: \"Mountain West Ruby 2016 -  Second Wind by Jamis Buck\"\n  speakers:\n    - Jamis Buck\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-14\"\n  published_at: \"2016-04-14\"\n  description: |-\n    Second Wind by Jamis Buck\n\n    Burnout is the professional’s palsy. It leaves you paralyzed, unable to do what you need to do, and it strikes without\n    warning. Or does it? Through story, metaphor, and perhaps even code sample, let’s\n    take a look at how to recognize, prepare for, and weather burnout, and hopefully\n    come through the other side stronger than ever!\n\n  video_provider: \"youtube\"\n  video_id: \"71suekjBV9Y\"\n\n- id: \"lightning-talks-mountainwest-rubyconf-2016\"\n  title: \"Lightning Talks\"\n  raw_title: \"Mountain West Ruby 2016 - Lightning Talks\"\n  event_name: \"MountainWest RubyConf 2016\"\n  date: \"2016-04-14\"\n  published_at: \"2016-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"PiXapH5zVcY\"\n  talks:\n    - title: \"Lightning Talk: RSpec Secrets\"\n      start_cue: \"00:24\"\n      end_cue: \"05:44\"\n      id: \"bradley-schafer-lighting-talk-mountainwest-rubyconf-2016\"\n      video_id: \"bradley-schafer-lighting-talk-mountainwest-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Bradley Schafer\n\n    - title: \"Lightning Talk: Reevaluating Value\"\n      start_cue: \"05:44\"\n      end_cue: \"11:00\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2016-1\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2016-1\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name https://cln.sh/GN0Zpzwl\n\n    - title: \"Lightning Talk: Learn To Play Dungeons & Dragons\"\n      start_cue: \"11:00\"\n      end_cue: \"15:12\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2016-2\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2016-2\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name https://cln.sh/q76S6SFB\n\n    - title: \"Lightning Talk: How To Be A Great Developer\"\n      start_cue: \"15:12\"\n      end_cue: \"19:48\"\n      id: \"ben-eggett-lighting-talk-mountainwest-rubyconf-2016\"\n      video_id: \"ben-eggett-lighting-talk-mountainwest-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Ben Eggett\n\n    - title: \"Lightning Talk: Crystal Lang - friendly, static, modern, compiled\"\n      start_cue: \"19:48\"\n      end_cue: \"24:51\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2016-3\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2016-3\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name https://cln.sh/hSHHf4BS\n\n    - title: \"Lightning Talk: NAME\"\n      start_cue: \"24:51\"\n      end_cue: \"28:37\"\n      id: \"todo-lighting-talk-mountainwest-rubyconf-2016-4\"\n      video_id: \"todo-lighting-talk-mountainwest-rubyconf-2016-4\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name https://cln.sh/DmFHqNZl\n\n    - title: \"Lightning Talk: Carrer.new\"\n      start_cue: \"28:37\"\n      end_cue: \"33:30\"\n      id: \"joey-fergmastaflex-lighting-talk-mountainwest-rubyconf-2016\"\n      video_id: \"joey-fergmastaflex-lighting-talk-mountainwest-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Joey @fergmastaflex\n\n    - title: \"Lightning Talk: IR?\"\n      start_cue: \"33:30\"\n      end_cue: \"38:44\"\n      id: \"nora-howard-lighting-talk-mountainwest-rubyconf-2016\"\n      video_id: \"nora-howard-lighting-talk-mountainwest-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Nora Howard\n\n    - title: \"Lightning Talk: petergate gem\"\n      start_cue: \"38:44\"\n      end_cue: \"43:50\"\n      id: \"isaac-sloan-lighting-talk-mountainwest-rubyconf-2016\"\n      video_id: \"isaac-sloan-lighting-talk-mountainwest-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Isaac Sloan\n\n    - title: \"Lightning Talk: In Search of the Unattainable\"\n      start_cue: \"43:50\"\n      end_cue: \"TODO\"\n      id: \"andrew-butterfield-lighting-talk-mountainwest-rubyconf-2016\"\n      video_id: \"andrew-butterfield-lighting-talk-mountainwest-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Butterfield\n"
  },
  {
    "path": "data/mountainwest-rubyconf/series.yml",
    "content": "---\nname: \"MountainWest RubyConf\"\nwebsite: \"https://web.archive.org/web/20160331205937/http://mtnwestrubyconf.org/\"\ntwitter: \"mwrc\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"MWRC\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/munich-rubyshift/munich-rubyshift/event.yml",
    "content": "---\nid: \"munich-rubyshift-meetup\"\ntitle: \"Munich Rubyshift Meetup\"\nlocation: \"Munich, Germany\"\npublished_at: \"2025-12-25\"\nkind: \"meetup\"\nbanner_background: \"#DE2810\"\nfeatured_background: \"#9A0100\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://www.meetup.com/de-de/munich-rubyshift-ruby-user-group/\"\noriginal_website: \"https://web.archive.org/web/20131020060833/http://munich.rubyshift.org/\"\ncoordinates:\n  latitude: 48.1351253\n  longitude: 11.5819806\n"
  },
  {
    "path": "data/munich-rubyshift/munich-rubyshift/videos.yml",
    "content": "---\n- id: \"munich-rubyshift-july-2025-meetup\"\n  title: \"Munich Rubyshift Meetup - July 2025\"\n  event_name: \"Munich Rubyshift Meetup - July 2025\"\n  date: \"2025-07-17\"\n  published_at: \"2025-12-25\"\n  video_provider: \"children\"\n  video_id: \"munich-rubyshift-july-2025\"\n  description: |-\n    Dear Munich Rubyists,\n\n    Summer's coming and so is our July meetup!\n\n    We're looking for a company to provide a location and food & drinks -- so if your company wants to host this edition of our meetup, please get in touch. We're also looking for 1 or 2 speakers -- so if you're up for a talk or know somebody who is, please let me know.\n\n    On a personal note: As I've said before, this event will be the last one that I'm organizing. It's time to pass on the baton to someone who's still (more) active in the Ruby ecosystem -- so if you're willing to step up, drop me a line or talk to me at the meetup.\n\n    Looking forward to seeing you all in July!\n\n    DATE & LOCATION\n\n    Date and Time: July 17, from 19:00 CEST\n    Location: Lanes & Planes GmbH, Kap West, Friedenheimer Bruecke 16, 80639 Munich\n\n    AGENDA\n\n        Welcome & Announcements\n        Location/Food & Drinks Sponsor Slot\n        Talk 1 incl. Q&A: Aron Wolf: \"Hotwire Native\"\n        Talk 2 incl. Q&A: Clemens Helm: \"Using database views in Rails and why you should (or shouldn't) do it\"\n        Food & Drinks (sponsored by TBD), Socializing (open end/as long as the location permits)\n  talks:\n    - id: \"aron-wolf-munich-rubyshift-july-2025\"\n      title: \"Hotwire Native\"\n      event_name: \"Munich Rubyshift Meetup - July 2025\"\n      speakers:\n        - Aron Wolf\n      date: \"2025-07-17\"\n      published_at: \"2025-12-25\"\n      video_provider: \"not_recorded\"\n      video_id: \"aron-wolf-munich-rubyshift-october-2025\"\n      description: |\n        An introduction about Hotwire Native. A tool from 37signal to convert your fullstack Rails application into a mobile app.\n\n        About our speaker:\n        https://www.meetup.com/members/264213499\n\n    - id: \"clemens-helm-munich-rubyshift-july-2025\"\n      title: \"Using database views in Rails and why you should (or shouldn't) do it\"\n      event_name: \"Munich Rubyshift Meetup - July 2025\"\n      speakers:\n        - Clemens Helm\n      date: \"2025-07-17\"\n      published_at: \"2025-12-25\"\n      video_provider: \"not_recorded\"\n      video_id: \"clemens-helm-munich-rubyshift-october-2025\"\n      description: |\n        Complex data filtering in Rails often leads us down a rabbit hole of custom scopes, service objects, and Arel acrobatics. But what if we let the database do what it’s best at? In this talk, you’ll see how SQL views paired with plain ActiveRecord and Ransack can turn messy logic into elegant, powerful queries — without giving up the Rails way.\n\n        About our speaker:\n        Clemens Helm is a seasoned Rails developer from Vienna who believes good code is boring — in the best way. At railscraft.de, he helps teams modernize legacy Rails apps with clean architecture, sharp tools, and zero-nonsense pragmatism.\n\n- id: \"munich-rubyshift-october-2025\"\n  title: \"Munich Rubyshift Meetup - October 2025\"\n  event_name: \"Munich Rubyshift Meetup - October 2025\"\n  date: \"2025-10-16\"\n  published_at: \"2025-12-25\"\n  video_provider: \"children\"\n  video_id: \"munich-rubyshift-october-2025\"\n  description: |-\n    Dear Munich Rubyists,\n\n    will be nice to see you all again on 16.10.\n\n    The meetup will take place at Lanes & Planes GmbH and the food is sponsored by Ruby Central.\n\n    We have two interesting talks. One from Chikahiro \"Is the monolith a problem?\" and another from Klaus - \"A resource-oriented file structure for Rails\".\n\n    On a personal note: This is the first event that I am organizing since I took over the group from Clemens. If anyone wants to help organize it or become a co-organizer of the group, please contact me.\n\n    Discord group: https://discord.gg/EKqHWmCxGZ\n\n    Looking forward to seeing you all in October!\n\n    DATE & LOCATION\n\n    Date and Time: October 16, from 19:00 CEST\n    Location: Lanes & Planes\n\n    AGENDA\n\n        Welcome & Announcements\n        Location/Food & Drinks Sponsor Slot\n        Talk 1 incl. Q&A: Chikahiro: \"Is the monolith a problem?\"\n        Talk 2 incl. Q&A: Klaus: Lightning Talk - \"A resource-oriented file structure for Rails\"\n        Food & Drinks (sponsored by Ruby Central), Socializing (open end/as long as the location permits)\n\n  talks:\n    - id: \"chikahiro-tokoro-munich-rubyshift-october-2025\"\n      title: \"Is the monolith a problem?\"\n      event_name: \"Munich Rubyshift Meetup - October 2025\"\n      speakers:\n        - Chikahiro Tokoro\n      date: \"2025-10-16\"\n      published_at: \"2025-12-25\"\n      video_provider: \"not_recorded\"\n      video_id: \"chikahiro-tokoro-munich-rubyshift-october-2025\"\n      description: |\n        Discover the truth about monoliths vs microservices! Debunk myths, uncover real architectural differences, and learn strategies to fix the real problems — not just follow trends.\n        About our speaker https://www.linkedin.com/in/chikahiro\n\n    - id: \"klaus-weidinger-munich-rubyshift-october-2025\"\n      title: 'Lightning Talk - \"A resource-oriented file structure for Rails\"'\n      event_name: \"Munich Rubyshift Meetup - October 2025\"\n      speakers:\n        - Klaus Weidinger\n      date: \"2025-10-16\"\n      published_at: \"2025-12-25\"\n      video_provider: \"not_recorded\"\n      video_id: \"klaus-weidinger-munich-rubyshift-october-2025\"\n      description: |-\n        About the speaker https://www.linkedin.com/in/klaus-weidinger-a37a27332/\n\n- id: \"munich-rubyshift-january-2026\"\n  title: \"Munich Rubyshift Meetup - January 2026\"\n  event_name: \"Munich Rubyshift Meetup - January 2026\"\n  date: \"2026-01-22\"\n  published_at: \"2025-12-25\"\n  video_provider: \"children\"\n  video_id: \"munich-rubyshift-january-2026\"\n  location: \"Augsburg, Germany\"\n  description: |-\n    Dear Rubyists,\n\n    our first Meetup in 2026 will take place on January 22nd in **AUGSBURG !!!**\n\n    After opening its gates at Rails World 2025 in Amsterdam, the Ruby embassy (a \"fun bureaucratic activity\") is opening a branch office at our local Meetup group. Take a photo, fill out your application forms, grab your Ruby passport and start collecting stamps.\n\n    The Ruby embassy will also issue passports at our future Meetups, although potentially with less bureaucracy (i.e. less fun).\n\n    More details about the Ruby passport: https://therubypassport.notion.site\n\n    After food & drinks we'll switch over to some talks.\n\n    CALL FOR SPEAKERS:\n    - We are still looking for a second talk. Please contact me if you have something in mind.\n\n    Looking forward to seeing you all in January!\n\n    Discord group: https://discord.gg/EKqHWmCxGZ\n\n    DATE & LOCATION\n\n    Date and Time: January 22nd 2026, 18:30 CEST\n    Location: **AUGSBURG !!!**  @makandra\n\n    AGENDA\n\n    - Welcome & Announcements\n    - 18:30 - 19:15 CEST: Office hours of the Ruby embassy (Außenstelle Augsburg)\n        - Apply for your Ruby passport and become an \"official\" member of the Ruby community\n    - Food & Drinks (thanks to makandra)\n    - Talk 1 incl. Q&A:\n        - To be announced\n    - Talk 2 incl. Q&A:\n        - Call for Speakers is OPEN\n    - Socializing (open end/as long as the location permits)\n  talks: []\n- id: \"munich-rubyshift-ruby-meetup-april-2026\"\n  title: \"Ruby Meetup April 2026\"\n  date: \"2026-04-23\"\n  video_id: \"munich-rubyshift-ruby-meetup-april-2026\"\n  video_provider: \"scheduled\"\n  description: |-\n    Dear Rubyists, the spring is coming closer and so our next meetup in April! The meetup will take place on Freeletics at 19:00. Here a big thanks to Khaled to be our contact person! Looking forward to see you all in April! Discord group: https://discord.gg/EKqHWmCxGZ **CALL FOR SPEAKERS:** We are still looking for a second talk. Please contact me if you have something in mind. **DATE & LOCATION** Date and Time: April 23nd 2026, 19:00 CEST Location: Freeletics **AGENDA** Welcome & Announcements Location/Food & Drinks Sponsor Slot Talk 1 incl. Q&A: to be revealed soon, Talk 2 incl. Q&A: call for speakers is open Food & Drinks (sponsored by TBD), Socializing (open end/as long as the location permits)\n\n    https://www.meetup.com/de-DE/munich-rubyshift-ruby-user-group/events/313838183/\n  talks: []\n"
  },
  {
    "path": "data/munich-rubyshift/series.yml",
    "content": "---\nname: \"Munich Rubyshift\"\nwebsite: \"https://www.meetup.com/de-de/munich-rubyshift-ruby-user-group/\"\nlinkedin: \"https://www.linkedin.com/groups/15477023/\"\nyoutube_channel_name: \"\"\nkind: \"meetup\"\nfrequency: \"quarterly\"\nlanguage: \"english\"\ndefault_country_code: \"DE\"\nyoutube_channel_id: \"\"\nplaylist_matcher: \"\"\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2015/event.yml",
    "content": "---\nid: \"rubyconf-kenya-2015\"\ntitle: \"RubyConf Kenya 2015\"\ndescription: \"\"\nlocation: \"Nairobi, Kenya\"\nkind: \"conference\"\nstart_date: \"2015-05-08\"\nend_date: \"2015-05-09\"\nwebsite: \"http://rubyconf.nairuby.org/2015\"\ntwitter: \"nairubyke\"\ncoordinates:\n  latitude: -1.2920659\n  longitude: 36.8219462\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.nairuby.org/2015\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2016/event.yml",
    "content": "---\nid: \"rubyconf-kenya-2016\"\ntitle: \"RubyConf Kenya 2016\"\ndescription: |-\n  On the 5th to 7th May 2016, leading Ruby developers from around the world will come together to share, inspire and learn. Theme: nurturing entrepreneurship through open source culture\nlocation: \"Nairobi, Kenya\"\nkind: \"conference\"\nstart_date: \"2016-05-05\"\nend_date: \"2016-05-07\"\nwebsite: \"https://web.archive.org/web/20160731012217/http://rubyconf.nairuby.org/2016\"\noriginal_website: \"http://rubyconf.nairuby.org/2016\"\ntwitter: \"nairubyke\"\ncoordinates:\n  latitude: -1.2920659\n  longitude: 36.8219462\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.nairuby.org/2016\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2017/event.yml",
    "content": "---\nid: \"PLb6Zr8jHuhjzIAKR7l2r81P-hxBUftT2-\"\ntitle: \"RubyConf Kenya 2017\"\ndescription: |-\n  THEME: AGILE, OPEN SOURCE AND ENTREPRENEURSHIP\nlocation: \"Nairobi, Kenya\"\nkind: \"conference\"\nstart_date: \"2017-06-08\"\nend_date: \"2017-06-10\"\nwebsite: \"https://web.archive.org/web/20170806114043/http://rubyconf.nairuby.org/2017\"\noriginal_website: \"http://rubyconf.nairuby.org/2017\"\ntwitter: \"nairubyke\"\nplaylist: \"https://www.youtube.com/playlist?list=PLb6Zr8jHuhjzIAKR7l2r81P-hxBUftT2-\"\ncoordinates:\n  latitude: -1.2920659\n  longitude: 36.8219462\naliases:\n  - RubyConf EA 2017\n  - RubyConf East Africa 2017\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2017/sponsors.yml",
    "content": "# docs/ADDING_SPONSORS.md\n---\n- tiers:\n    - name: \"Supporters\"\n      level: 1\n      sponsors:\n        - name: \"Riara\"\n          slug: \"riara\"\n          website: \"http://www.riarauniversity.ac.ke/\"\n        - name: \"GitLab\"\n          slug: \"gitlab\"\n          website: \"https://gitlab.com\"\n        - name: \"GitHub\"\n          slug: \"github\"\n          website: \"https://github.com\"\n        - name: \"Andela\"\n          slug: \"andela\"\n          website: \"https://andela.com/\"\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2017/videos.yml",
    "content": "---\n- id: \"welcome-speech-rubyconf-kenya-2017\"\n  title: \"Ruby Conference Kenya 2017 Welcome Speech\"\n  event_name: \"RubyConf Kenya 2017\"\n  description: |-\n    Ruby Conference Kenya 2017 Welcome Speech by Bernard Banta, Nairuby Chaurman #RubyConfKenya2017\n  raw_title: \"Ruby Conferece Kenya 2017 Welcome Speech by Bernard Banta\"\n  published_at: \"2017-07-17\"\n  date: \"2017-06-08\"\n  video_provider: \"youtube\"\n  video_id: \"mOFi4Mb7uYQ\"\n  speakers:\n    - Bernard Banta\n\n- id: \"building-a-growing-company-with-successful-products-rubyconf-kenya-2017\"\n  title: \"Building A Growing Company with Successful Products\"\n  event_name: \"RubyConf Kenya 2017\"\n  description: |-\n    Building A Growing Company with Successful Products - Bernard Banta #RubyconfKenya2017\n  raw_title: \"Building A Growing Company with Successful Products - Bernard Banta\"\n  published_at: \"2017-07-17\"\n  date: \"2017-06-08\"\n  video_provider: \"youtube\"\n  video_id: \"p5Oc7S_-JwE\"\n  speakers:\n    - Bernard Banta\n\n- id: \"the-curious-case-of-wikipedia-parsing-rubyconf-kenya-2017\"\n  title: \"The Curious Case of Wikipedia Parsing\"\n  event_name: \"RubyConf Kenya 2017\"\n  description: |-\n    Victor Shepelev is a Ukrainian programmer and poet with more than fifteen years of programming experience and ten years of Ruby programming. Working at Toptal, mentoring students (including Google Summer of Code 2016 and 2017, as a mentor for SciRuby organization), developing open source (Ruby Association Grant 2015)\n  raw_title: \"The Curious Case of Wikipedia Parsing - Victor Shepelev\"\n  published_at: \"2017-07-18\"\n  date: \"2017-06-08\"\n  video_provider: \"youtube\"\n  video_id: \"mAKMvHfIIiU\"\n  speakers:\n    - Victor Shepelev\n\n- id: \"opal-the-journey-from-javascript-to-ruby-rubyconf-kenya-2017\"\n  title: \"Opal: The Journey from JavaScript to Ruby\"\n  event_name: \"RubyConf Kenya 2017\"\n  description: |-\n    Bozhidar is the author of RuboCop and the editor of the community Ruby and Rails style guides. Most people would probably describe him as an Emacs zealot (and they would be right). He's also quite fond of the Lisp family of languages, functional programming in general and Clojure in particular. Believe it or not, Bozhidar has hobbies and interest outside the realm of computers, but we won’t bore with those here.\n  raw_title: \"Opal: The Journey from JavaScript to Ruby - Bozhidar Bastov\"\n  published_at: \"2017-07-18\"\n  date: \"2017-06-08\"\n  video_provider: \"youtube\"\n  video_id: \"c0IbkGrb3Wo\"\n  speakers:\n    - Bozhidar Batsov\n\n- id: \"panel-discussion-agility-in-entrepreneurship-rubyconf-kenya-2017\"\n  title: \"Panel Discussion: Agility in Entrepreneurship\"\n  event_name: \"RubyConf Kenya 2017\"\n  description: \"\"\n  raw_title: \"Panel Discussion: Agility in Entrepreneurship\"\n  published_at: \"2017-07-29\"\n  date: \"2017-06-08\"\n  video_provider: \"youtube\"\n  video_id: \"V1j8aawtjVE\"\n  speakers:\n    - Bernard Banta\n    - James Corey\n    - Joannah Nanjekye\n    - Mike McQuaid\n    - Victor Shepelev\n\n- id: \"coopetition-cooperation-in-todays-competitive-tech-consulting-marketplace-rubyconf-kenya-2017\"\n  title: \"Coopetition: Cooperation in Today's Competitive Tech Consulting Marketplace\"\n  event_name: \"RubyConf Kenya 2017\"\n  description: \"\"\n  raw_title: \"Coopetition: Cooperation in Today’s Competitive Tech Consulting Marketplace by James Corey\"\n  published_at: \"2017-07-29\"\n  date: \"2017-06-08\"\n  video_provider: \"youtube\"\n  video_id: \"DIZz2td3V8Y\"\n  speakers:\n    - James Corey\n\n- id: \"metaprogramming-the-ruby-way-rubyconf-kenya-2017\"\n  title: \"Metaprogramming the Ruby Way\"\n  event_name: \"RubyConf Kenya 2017\"\n  description: \"\"\n  raw_title: \"Metaprogrammingthe Ruby Way by Joannah Nanjekye\"\n  published_at: \"2017-07-30\"\n  date: \"2017-06-08\"\n  video_provider: \"youtube\"\n  video_id: \"ou-NeRKC9e4\"\n  speakers:\n    - Joannah Nanjekye\n\n- id: \"helping-yourself-with-open-source-software-rubyconf-kenya-2017\"\n  title: \"Helping Yourself with Open Source Software\"\n  event_name: \"RubyConf Kenya 2017\"\n  description: \"\"\n  raw_title: \"Helping Yourself with Open Source Software by Mike McQuaid\"\n  published_at: \"2017-07-30\"\n  date: \"2017-06-08\"\n  video_provider: \"youtube\"\n  video_id: \"u1jx48ztzgk\"\n  speakers:\n    - Mike McQuaid\n\n- id: \"when-the-whole-world-is-your-database-rubyconf-kenya-2017\"\n  title: \"When the Whole World is Your Database\"\n  event_name: \"RubyConf Kenya 2017\"\n  description: |-\n    The presentation used can be found on this link:\n    https://www.slideshare.net/AdamKabaka/when-the-whole-world-is-your-database\n  slides_url: \"https://www.slideshare.net/AdamKabaka/when-the-whole-world-is-your-database\"\n  raw_title: \"When theWhole World is Your Database by Victor Shepelev\"\n  published_at: \"2017-07-30\"\n  date: \"2017-06-08\"\n  video_provider: \"youtube\"\n  video_id: \"3oCA2E1U3N8\"\n  speakers:\n    - Victor Shepelev\n\n- id: \"mike-mcquaid-rubyconf-kenya-2017\"\n  title: \"Talk by Mike McQuaid\"\n  event_name: \"RubyConf Kenya 2017\"\n  description: \"\"\n  raw_title: \"Mike McQUAID\"\n  published_at: \"2017-08-28\"\n  date: \"2017-06-08\"\n  video_provider: \"youtube\"\n  video_id: \"6mpl7XDXWI8\"\n  speakers:\n    - Mike McQuaid\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2018/event.yml",
    "content": "---\nid: \"rubyconf-kenya-2018\"\ntitle: \"RubyConf Kenya 2018\"\ndescription: \"\"\nlocation: \"Nairobi, Kenya\"\nkind: \"conference\"\nstart_date: \"2018-06-22\"\nend_date: \"2018-06-22\"\nwebsite: \"http://rubyconf.nairuby.org/2018\"\ntwitter: \"nairubyke\"\ncoordinates:\n  latitude: -1.2920659\n  longitude: 36.8219462\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.nairuby.org/2018\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2019/event.yml",
    "content": "---\nid: \"rubyconf-kenya-2019\"\ntitle: \"RubyConf Kenya 2019\"\ndescription: \"\"\nlocation: \"Nairobi, Kenya\"\nkind: \"conference\"\nstart_date: \"2019-07-25\"\nend_date: \"2019-07-27\"\nwebsite: \"http://rubyconf.nairuby.org/2019\"\ntwitter: \"nairubyke\"\ncoordinates:\n  latitude: -1.2920659\n  longitude: 36.8219462\n"
  },
  {
    "path": "data/nairuby/rubyconf-kenya-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.nairuby.org/2019\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/nairuby/series.yml",
    "content": "---\nname: \"Nairuby\"\nwebsite: \"http://nairuby.org\"\ntwitter: \"nairubyke\"\nyoutube_channel_name: \"\"\nkind: \"organisation\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/naniwarb/naniwarb-meetup/event.yml",
    "content": "---\nid: \"naniwarb-meetup\"\ntitle: \"naniwa.rb Meetup\"\nlocation: \"Osaka, Japan\"\ndescription: |-\n  A maker-oriented community in Osaka where people build things ranging from electronics to accessories, including projects that drive microcontrollers with Ruby. Beginners are welcome.\nwebsite: \"https://naniwarb.doorkeeper.jp\"\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 34.6937569\n  longitude: 135.5014539\n"
  },
  {
    "path": "data/naniwarb/naniwarb-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/naniwarb/picorubyoverflowkaigi-2025/cfp.yml",
    "content": "---\n- link: \"https://forms.gle/NsRZHW6MTV6aYPkF9\"\n  close_date: \"2025-07-15\"\n"
  },
  {
    "path": "data/naniwarb/picorubyoverflowkaigi-2025/event.yml",
    "content": "---\nid: \"picorubyoverflowkaigi-2025\"\ntitle: \"PicoRuby Overflow Kaigi 2025\"\ndescription: \"\"\nlocation: \"Osaka, Japan\"\nkind: \"conference\"\nstart_date: \"2025-07-19\"\nend_date: \"2025-07-19\"\nwebsite: \"https://naniwarb.github.io/picorubyoverflowkaigi/\"\nfeatured_background: \"#B91857\"\nfeatured_color: \"#FFFFFF\"\nbanner_background: \"#0A0A0A\"\ncoordinates:\n  latitude: 34.6937249\n  longitude: 135.5022535\n"
  },
  {
    "path": "data/naniwarb/picorubyoverflowkaigi-2025/schedule.yml",
    "content": "---\n# https://naniwarb.github.io/picorubyoverflowkaigi/\n\ndays:\n  - name: \"Day 1\"\n    date: \"2025-07-19\"\n    grid:\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n        items:\n          - Door Open\n\n      - start_time: \"12:30\"\n        end_time: \"12:40\"\n        slots: 1\n        items:\n          - Opening\n\n      - start_time: \"12:40\"\n        end_time: \"13:00\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"13:20\"\n        slots: 1\n\n      - start_time: \"13:20\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"13:30\"\n        end_time: \"13:50\"\n        slots: 1\n\n      - start_time: \"13:50\"\n        end_time: \"14:10\"\n        slots: 1\n\n      - start_time: \"14:10\"\n        end_time: \"14:20\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:20\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Showcase Session\n\n      - start_time: \"15:00\"\n        end_time: \"15:10\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:10\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"15:50\"\n        slots: 1\n\n      - start_time: \"15:50\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:20\"\n        slots: 1\n\n      - start_time: \"16:20\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:30\"\n        end_time: \"16:50\"\n        slots: 1\n\n      - start_time: \"16:50\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Closing\n\n      - start_time: \"17:30\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - After Party\n"
  },
  {
    "path": "data/naniwarb/picorubyoverflowkaigi-2025/videos.yml",
    "content": "---\n# TODO: talk video IDs\n# TODO: talk descriptions\n# Website: https://naniwarb.github.io/picorubyoverflowkaigi/\n\n- id: \"yuhei-okazaki-picoruby-overflow-kaigi-2025\"\n  title: \"Porting filesystem-fat to Another Microcontroller: ESP32\"\n  raw_title: \"Porting filesystem-fat to Another Microcontroller: ESP32\"\n  speakers:\n    - Yuhei Okazaki\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"yuhei-okazaki-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"shunsuke-michii-picoruby-overflow-kaigi-2025\"\n  title: \"Write your own mrbgem, Create your own device\"\n  raw_title: \"Write your own mrbgem, Create your own device\"\n  speakers:\n    - Shunsuke Michii\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"shunsuke-michii-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"makicamel-picoruby-overflow-kaigi-2025\"\n  title: \"入門以前から始める PicoRubyのあそび方\"\n  raw_title: \"入門以前から始める PicoRubyのあそび方\"\n  speakers:\n    - makicamel\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"makicamel-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"ryo-kajiwara-picoruby-overflow-kaigi-2025\"\n  title: \"PicoRuby's Networking is Incomplete\"\n  raw_title: \"PicoRuby's Networking is Incomplete\"\n  speakers:\n    - Ryo Kajiwara\n    - sylph01\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"ryo-kajiwara-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"sago35-picoruby-overflow-kaigi-2025\"\n  title: \"PicoRubyでひらく組込みの世界\"\n  raw_title: \"PicoRubyでひらく組込みの世界\"\n  speakers:\n    - sago35\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"sago35-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"ryosk7-picoruby-overflow-kaigi-2025\"\n  title: \"実運用を目指す、PicoRubyとMQTT\"\n  raw_title: \"実運用を目指す、PicoRubyとMQTT\"\n  speakers:\n    - ryosk7\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"ryosk7-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"bash-picoruby-overflow-kaigi-2025\"\n  title: \"Microcontroller・組み込み未経験者が装置を作る中で得たpicoruby系mrbgems開発ストラテジー\"\n  raw_title: \"Microcontroller・組み込み未経験者が装置を作る中で得たpicoruby系mrbgems開発ストラテジー\"\n  speakers:\n    - bash\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"bash-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"hasumikin-picoruby-overflow-kaigi-2025\"\n  title: \"Keynote\"\n  raw_title: \"Keynote\"\n  speakers:\n    - Hitoshi Hasumi\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"hasumikin-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n# Showcase Session Talks\n\n- id: \"chobishiba-picoruby-overflow-kaigi-2025\"\n  title: \"センサーいろいろ比べてみた！PicoRubyでつくる操作体験\"\n  raw_title: \"センサーいろいろ比べてみた！PicoRubyでつくる操作体験\"\n  speakers:\n    - Miyuki Koshiba\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"chobishiba-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"hachi-picoruby-overflow-kaigi-2025\"\n  title: \"今更作るFMラジオ~実用電子工作ことはじめ~\"\n  raw_title: \"今更作るFMラジオ~実用電子工作ことはじめ~\"\n  speakers:\n    - hachi\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"hachi-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"kishima-picoruby-overflow-kaigi-2025\"\n  title: \"PicoRuby/R2P2で自分だけのコンピュータを作ろう\"\n  raw_title: \"PicoRuby/R2P2で自分だけのコンピュータを作ろう\"\n  speakers:\n    - kishima\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"kishima-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"kinoppyd-picoruby-overflow-kaigi-2025\"\n  title: \"Rubyでつくって子供と遊ぼう\"\n  raw_title: \"Rubyでつくって子供と遊ぼう\"\n  speakers:\n    - kinoppyd\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"kinoppyd-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n\n- id: \"uproad-picoruby-overflow-kaigi-2025\"\n  title: \"PicoRubyの表現力の拡張～アナログコンピュータとの出会い～\"\n  raw_title: \"PicoRubyの表現力の拡張～アナログコンピュータとの出会い～\"\n  speakers:\n    - uproad\n  event_name: \"PicoRuby Overflow Kaigi 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"uproad-picoruby-overflow-kaigi-2025\"\n  description: |-\n    TODO\n  language: \"japanese\"\n"
  },
  {
    "path": "data/naniwarb/series.yml",
    "content": "---\nname: \"naniwa.rb\"\nwebsite: \"https://github.com/naniwarb\"\ngithub: \"https://github.com/naniwarb\"\ntwitter: \"\"\nmastodon: \"\"\nkind: \"organisation\"\nfrequency: \"irregular\"\nmeetup: \"https://naniwarb.doorkeeper.jp\"\nplaylist_matcher: \"\"\ndefault_country_code: \"JP\"\nyoutube_channel_name: \"\"\nlanguage: \"japanese\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/nantes-rb/nantes-rb-meetup/event.yml",
    "content": "# docs/ADDING_EVENTS.md\n---\nid: \"nantes-rb-meetup\"\ntitle: \"Nantes.rb Meetup\"\nlocation: \"Nantes, France\"\nkind: \"meetup\"\ndescription: |-\n  Nantes.rb est un meetup mensuel pour les développeurs Ruby à Nantes, France.\n  Nous nous réunissons régulièrement pour discuter de Ruby, Rails et des technologies associées.\n\n  Nantes.rb is a monthly meetup for Ruby developers in Nantes, France.\n  We meet regularly to discuss Ruby, Rails, and related technologies.\npublished_at: \"2026-01-01\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#E23F52\"\nwebsite: \"https://rubynantes.org/\"\ncoordinates:\n  latitude: 47.2186371\n  longitude: -1.5541362\nfrequency: \"monthly\"\n"
  },
  {
    "path": "data/nantes-rb/nantes-rb-meetup/videos.yml",
    "content": "---\n- id: \"nantes-rb-meetup-january-2026\"\n  title: \"Nantes.rb Meetup January 2026\"\n  date: \"2026-01-27\"\n  video_id: \"nantes-rb-meetup-january-2026\"\n  video_provider: \"children\"\n  description: |-\n    🚀 Fans de Ruby, ne manquez pas notre prochain Meetup ! 🚀\n    Rejoignez-nous pour une soirée conviviale où vous pourrez rencontrer d'autres développeuses et développeurs passionnés, et cette fois-ci, on parlera aussi devops !\n    Quand: le mardi 27 janvier à partir de 18h30\n    Où ? dans les locaux du Wagon Nantes, 10 passage de la Poule Noire.\n    Agenda:\n    - 18h30 - 19h00 : Une application Rails pour partager trop de photos avec trop peu de gens (Stockage local, optimisation et rendu d'images dans une application Rails) par Louis\n    - 19h00 - 19h30 : Coolify une alternative aux PaaS par Francois\n    Après les présentations, place à l'apéro ! Une belle occasion pour échanger, rencontrer d'autres membres de la communauté Ruby et élargir votre réseau dans une ambiance détendue.\n    https://www.meetup.com/nantes-rb/events/312784976/\n  language: \"french\"\n  talks: []\n- id: \"nantes-rb-meetup-february-2026\"\n  title: \"Nantes.rb Meetup February 2026\"\n  date: \"2026-02-26\"\n  video_id: \"nantes-rb-meetup-february-2026\"\n  video_provider: \"children\"\n  description: |-\n    Fans de Ruby si vous n'êtes pas sur les pistes enneigées en février, venez plutôt glisser sur les pentes du code avec la communauté Ruby de Nantes! Venez rencontrer d'autres développeuses et développeurs Ruby lors de notre prochain rendez-vous convivial!\n    Quand: le jeudi 26 février à partir de 18h30\n    Où ? A l'Ouvre-Boites 20 allée de la Maison Rouge, 44000 Nantes.\n    Agenda:\n    - 18h30 - 18h40 : Accueil et présentation du lieu\n    - 18h40 - 19h10 : Ecoconception et accessibilité Web\n    - 19h10 - 19h40 : Comment construire ses images Docker plus rapidement\n    Après la conférence, nous vous proposons d'aller boire un verre dans le bar le plus proche. C'est une occasion idéale pour se connecter avec des professionnels du même domaine et élargir votre réseau.\n    https://www.meetup.com/nantes-rb/events/313202692/\n  language: \"french\"\n  talks: []\n- id: \"nantes-rb-meetup-march-2026\"\n  title: \"Nantes.rb Meetup mars 2026\"\n  date: \"2026-03-24\"\n  video_id: \"nantes-rb-meetup-march-2026\"\n  video_provider: \"children\"\n  description: |-\n    Ruby burger au Gigg's Irish pub\n\n    https://www.meetup.com/nantes-rb/events/313647438/\n  language: \"french\"\n  talks: []\n- id: \"nantes-rb-meetup-april-2026\"\n  title: \"Nantes.rb Meetup avril 2026\"\n  date: \"2026-04-30\"\n  video_id: \"nantes-rb-meetup-april-2026\"\n  video_provider: \"children\"\n  description: |-\n    Fans de Ruby pour ce premier Meetup du printemps venez nous retrouver dans la salle de conférences de Gina, 24 Boulevard Giséle Halimi, 44200 Nantes avec CleverCloud et Osponso! Ce sera l'occasion de rencontrer d'autres développeuses et développeurs Ruby lors de notre prochain rendez-vous convivial!\n    Quand : le jeudi 30 avril à partir de 18h30\n    Où : Gina, 24 Boulevard Giséle Halimi, 44200 Nantes.\n    Agenda :\n\n        18h30 - 18h40 : Accueil et présentation du lieu et échange sur le tampon NantesRB par Louis de Lasercats\n        18h40 - 19h10 : Clever Cloud news par Horacio de Clever Cloud\n        19h10 - 19h40 : Ruby on Rails dans une startup par Vincent de Osponso\n\n    Après la conférence, nous dans le bar le plus proche pour échanger avec d'autres membres de la communauté Ruby. C'est une occasion idéale pour se connecter avec des professionnels du même domaine et élargir votre réseau.\n\n    https://www.meetup.com/nantes-rb/events/314193140/\n  language: \"french\"\n  talks: []\n"
  },
  {
    "path": "data/nantes-rb/series.yml",
    "content": "---\nname: \"Nantes.rb Meetup\"\nwebsite: \"https://rubynantes.org/\"\nmeetup: \"https://www.meetup.com/nantes-rb/\"\nkind: \"meetup\"\ntwitter: \"\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"FR\"\nlanguage: \"french\"\nyoutube_channel_name: \"\"\nyoutube_channel_id: \"\"\naliases:\n  - Nantes Ruby Meetup\n  - Nantes Ruby\n  - NantesRb Meetup\n"
  },
  {
    "path": "data/nepal-ruby/nepal-ruby-meetup/event.yml",
    "content": "---\nid: \"nepal-ruby-meetup\"\ntitle: \"Nepal Ruby Meetup\"\nlocation: \"Kathmandu, Nepal\"\ndescription: |-\n  Join a group of fellow Rubyists to hang out for a quick chat, gather tips or engage in discussions.\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#6194BC\"\ncoordinates:\n  latitude: 27.7103145\n  longitude: 85.3221634\n"
  },
  {
    "path": "data/nepal-ruby/nepal-ruby-meetup/videos.yml",
    "content": "---\n- id: \"nepal-ruby-meetup-march-2025\"\n  title: \"Nepal Ruby Meetup March 2025\"\n  date: \"2025-03-28\"\n  video_id: \"nepal-ruby-meetup-march-2025\"\n  video_provider: \"not_recorded\"\n  description: |-\n    https://x.com/coolprobn/status/1905232642234331231\n    https://x.com/coolprobn/status/1905644883618209838\n    https://x.com/gkunwar1/status/1905582607385149808\n    https://gurzu.com/blog/ruby-community-meetup-in-kathmandu/\n  thumbnail_xs: \"https://pbs.twimg.com/media/GnC90cyaYAA-yKq?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GnC90cyaYAA-yKq?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GnC90cyaYAA-yKq?format=jpg&name=medium\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GnC90cyaYAA-yKq?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GnC90cyaYAA-yKq?format=jpg&name=large\"\n  talks:\n    - title: \"Solid Cache: A Game Changer in Rails 8\"\n      date: \"2025-03-28\"\n      id: \"george-maharjan-nepal-ruby-meetup-march-2025\"\n      video_id: \"george-maharjan-nepal-ruby-meetup-march-2025\"\n      video_provider: \"not_recorded\"\n      slides_url: \"https://speakerdeck.com/gurzu/solid-cache-a-game-changer-in-rails-8\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GnIJn8FbgAULplm?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GnIJn8FbgAULplm?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GnIJn8FbgAULplm?format=jpg&name=medium\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GnIJn8FbgAULplm?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GnIJn8FbgAULplm?format=jpg&name=large\"\n      description: |-\n        George Maharjan is a Ruby Developer at Gurzu. He talked about how Solid Cache enhances performance, scalability, and reliability with seamless integration in Rails 8. Find the slide here.\n      speakers:\n        - George Maharjan\n\n    - title: \"Unleashing the power of LLMs in Ruby\"\n      date: \"2025-03-28\"\n      id: \"santosh-shah-nepal-ruby-meetup-march-2025\"\n      video_id: \"santosh-shah-nepal-ruby-meetup-march-2025\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GnIFK6BaoAAGGPO?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GnIFK6BaoAAGGPO?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GnIFK6BaoAAGGPO?format=jpg&name=medium\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GnIFK6BaoAAGGPO?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GnIFK6BaoAAGGPO?format=jpg&name=large\"\n      description: |-\n        Santosh Shah is an expert in Ruby on Rails, known for his deep insights into backend development and performance optimization. In this talk, he highlighted how Ruby developers can tap into the capabilities of Large Language Models (LLMs) with their applications. This session sparked curiosity and offered a new perspective on combining the power of Ruby with AI.\n      speakers:\n        - Santosh Shah\n\n    - title: \"From Bottlenecks to Breakthroughs: Our Rails Horizontal Sharding Journey\"\n      date: \"2025-03-28\"\n      id: \"prepsa-kayastha-nepal-ruby-meetup-march-2025\"\n      video_id: \"prepsa-kayastha-nepal-ruby-meetup-march-2025\"\n      video_provider: \"not_recorded\"\n      slides_url: \"https://speakerdeck.com/gurzu/from-bottlenecks-to-breakthroughs-our-rails-horizontal-sharding-journey\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GnIJcJrbgAIyGVx?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GnIJcJrbgAIyGVx?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GnIJcJrbgAIyGVx?format=jpg&name=medium\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GnIJcJrbgAIyGVx?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GnIJcJrbgAIyGVx?format=jpg&name=large\"\n      description: |-\n        Prepsa Kayastha is a senior Ruby Developer at Gurzu, In this insightful talk, she shared how her team tackled database scaling challenges with horizontal sharding in Rails. Find the slide here.\n      speakers:\n        - Prepsa Kayastha\n\n- id: \"nepal-ruby-meetup-november-2025\"\n  title: \"Nepal Ruby Meetup November 2025\"\n  date: \"2025-11-07\"\n  video_id: \"nepal-ruby-meetup-november-2025\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Ruby on Rails Community Nepal successfully hosted a Ruby on Rails Meetup on November 7, 2025, bringing together Ruby developers, tech enthusiasts, and community members from across Nepal. The event kicked off at 4:45 PM with a warm welcome and introduction, followed by a technical session. A highlight of the evening was a special video message from Yukihiro Matsumoto (Matz), the creator of the Ruby programming language, sharing his thoughts and encouragement for the Nepalese Ruby community.\n\n    https://rorktm.com/news/ruby-on-rails-meetup-at-gurzu-november-7-2025\n    https://x.com/coolprobn/status/1986818156237902288\n  thumbnail_xs: \"https://pbs.twimg.com/media/G5KYlVJbsAEjJvp?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/G5KYlVJbsAEjJvp?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/G5KYlVJbsAEjJvp?format=jpg&name=medium\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/G5KYlVJbsAEjJvp?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/G5KYlVJbsAEjJvp?format=jpg&name=large\"\n  talks:\n    - title: \"Thinking in Components: Building Reusable UIs in Rails with ViewComponent\"\n      date: \"2025-11-07\"\n      id: \"prabin-poudel-nepal-ruby-meetup-november-2025\"\n      video_id: \"prabin-poudel-nepal-ruby-meetup-november-2025\"\n      video_provider: \"not_recorded\"\n      slides_url: \"https://speakerdeck.com/coolprobn/thinking-in-components-building-reusable-uis-in-rails-with-viewcomponent\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/G5O38_IbAAA32mw?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/G5O38_IbAAA32mw?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/G5O38_IbAAA32mw?format=jpg&name=medium\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/G5O38_IbAAA32mw?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/G5O38_IbAAA32mw?format=jpg&name=large\"\n      description: |-\n        Prabin Poudel delivered a technical session on \"Thinking in Components: Building Reusable UIs in Rails with ViewComponent.\" This talk explored how to build maintainable and reusable user interfaces in Rails applications using the ViewComponent library.\n      speakers:\n        - Prabin Poudel\n"
  },
  {
    "path": "data/nepal-ruby/series.yml",
    "content": "---\nname: \"Nepal Ruby Community\"\nwebsite: \"https://rubynepal.org\"\ngithub: \"https://github.com/rubynepal\"\nmeetup: \"https://www.meetup.com/nepal-ruby-users-group\"\ntwitter: \"ruby_nepal\"\nkind: \"organisation\"\nfrequency: \"monthly\"\nplaylist_matcher: \"RubyNepal\"\ndefault_country_code: \"NP\"\nyoutube_channel_name: \"RubyNepal\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCoRCDWyFmaby7F4qWRUHgAQ\"\n"
  },
  {
    "path": "data/nickel-city-ruby/nickel-city-ruby-2013/event.yml",
    "content": "---\nid: \"nickel-city-ruby-2013\"\ntitle: \"Nickel City Ruby 2013\"\ndescription: \"\"\nlocation: \"Buffalo, NY, United States\"\nkind: \"conference\"\nstart_date: \"2013-09-20\"\nend_date: \"2013-09-21\"\nwebsite: \"https://web.archive.org/web/20131002200835/http://nickelcityruby.com/\"\noriginal_website: \"http://nickelcityruby.com/\"\ntwitter: \"nickelcityruby\"\ncoordinates:\n  latitude: 42.88690039999999\n  longitude: -78.8788896\n"
  },
  {
    "path": "data/nickel-city-ruby/nickel-city-ruby-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://nickelcityruby.com/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/nickel-city-ruby/nickel-city-ruby-2014/event.yml",
    "content": "---\nid: \"nickel-city-ruby-2014\"\ntitle: \"Nickel City Ruby 2014\"\ndescription: \"\"\nlocation: \"Buffalo, NY, United States\"\nkind: \"conference\"\nstart_date: \"2014-10-02\"\nend_date: \"2014-10-04\"\nwebsite: \"https://web.archive.org/web/20140916044508/http://nickelcityruby.com/\"\noriginal_website: \"http://nickelcityruby.com/\"\ntwitter: \"nickelcityruby\"\nplaylist: \"http://www.confreaks.com/events/nickelcityruby2014\"\nfeatured_background: \"#00206C\"\nfeatured_color: \"#FFFFFF\"\nbanner_background: \"#00206C\"\ncoordinates:\n  latitude: 42.88690039999999\n  longitude: -78.8788896\naliases:\n  - Nickel City Ruby Conference 2014\n"
  },
  {
    "path": "data/nickel-city-ruby/nickel-city-ruby-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://nickelcityruby.com/\n# Videos: http://www.confreaks.com/events/nickelcityruby2014\n---\n[]\n"
  },
  {
    "path": "data/nickel-city-ruby/series.yml",
    "content": "---\nname: \"Nickel City Ruby Conference\"\nwebsite: \"http://nickelcityruby.com/\"\ntwitter: \"nickelcityruby\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/nordicruby/nordicruby-2010/event.yml",
    "content": "---\nid: \"nordicruby-2010\"\ntitle: \"Nordic Ruby 2010\"\ndescription: |-\n  Learn from and meet industry leaders and fellow rubyists. Both educational and inspirational. And fun! Right here in the center of the Nordic countries.\nlocation: \"Gothenburg, Sweden\"\nkind: \"conference\"\nstart_date: \"2010-05-21\"\nend_date: \"2010-05-23\"\nwebsite: \"https://web.archive.org/web/20100516160456/http://nordicruby.org/\"\noriginal_website: \"http://www.nordicruby.org/\"\ntwitter: \"nordicruby\"\ncoordinates:\n  latitude: 57.70887\n  longitude: 11.97456\n"
  },
  {
    "path": "data/nordicruby/nordicruby-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.nordicruby.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/nordicruby/nordicruby-2011/event.yml",
    "content": "---\nid: \"nordicruby-2011\"\ntitle: \"Nordic Ruby 2011\"\ndescription: |-\n  Come to Nordic Ruby 2011 and you will get a two day, single track Ruby conference, featuring the winning concept of 30 minute talks and 30 minute breaks.\nlocation: \"Gothenburg, Sweden\"\nkind: \"conference\"\nstart_date: \"2011-06-16\"\nend_date: \"2011-06-18\"\nwebsite: \"https://web.archive.org/web/20110501213810/http://nordicruby.org/\"\noriginal_website: \"http://www.nordicruby.org/\"\ntwitter: \"nordicruby\"\ncoordinates:\n  latitude: 57.70887\n  longitude: 11.97456\n"
  },
  {
    "path": "data/nordicruby/nordicruby-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.nordicruby.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/nordicruby/nordicruby-2012/event.yml",
    "content": "---\nid: \"nordicruby-2012\"\ntitle: \"Nordic Ruby 2012\"\ndescription: |-\n  Learn stuff. Meet people. Have fun.\nlocation: \"Stockholm, Sweden\"\nkind: \"conference\"\nstart_date: \"2012-06-15\"\nend_date: \"2012-06-16\"\nwebsite: \"https://web.archive.org/web/20120528085029/http://nordicruby.org/\"\noriginal_website: \"http://www.nordicruby.org/\"\ntwitter: \"nordicruby\"\ncoordinates:\n  latitude: 59.3327036\n  longitude: 18.0656255\n"
  },
  {
    "path": "data/nordicruby/nordicruby-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.nordicruby.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/nordicruby/nordicruby-2013/event.yml",
    "content": "---\nid: \"nordicruby-2013\"\ntitle: \"Nordic Ruby 2013\"\ndescription: |-\n  This June Nordic Ruby returns to the beautiful archipelago of Stockholm. Join us for two full conference days in combination with a relaxing spa retreat. A total of almost four days of inspiration.\nlocation: \"Stockholm, Sweden\"\nkind: \"conference\"\nstart_date: \"2013-06-06\"\nend_date: \"2013-06-09\"\nwebsite: \"https://web.archive.org/web/20130831061507/http://www.nordicruby.org/\"\noriginal_website: \"http://www.nordicruby.org/\"\ntwitter: \"nordicruby\"\ncoordinates:\n  latitude: 59.3327036\n  longitude: 18.0656255\n"
  },
  {
    "path": "data/nordicruby/nordicruby-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.nordicruby.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/nordicruby/nordicruby-2016/event.yml",
    "content": "---\nid: \"nordicruby-2016\"\ntitle: \"Nordic Ruby 2016\"\ndescription: |-\n  Nordic Ruby is back! Join us for a two day conference/spa retreat for developers and designers that care about their craft.\nlocation: \"Stockholm, Sweden\"\nkind: \"conference\"\nstart_date: \"2016-06-17\"\nend_date: \"2016-06-19\"\nwebsite: \"https://web.archive.org/web/20160702231350/http://www.nordicruby.org/\"\noriginal_website: \"http://www.nordicruby.org/\"\ntwitter: \"nordicruby\"\ncoordinates:\n  latitude: 59.3327036\n  longitude: 18.0656255\naliases:\n  - NordicRuby 2016\n"
  },
  {
    "path": "data/nordicruby/nordicruby-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.nordicruby.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/nordicruby/series.yml",
    "content": "---\nname: \"Nordic Ruby\"\nwebsite: \"http://www.nordicruby.org/\"\ntwitter: \"nordicruby\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/oedo-rubykaigi/oedo-rubykaigi-01/event.yml",
    "content": "---\nid: \"oedo-rubykaigi-01\"\ntitle: \"Oedo RubyKaigi 01\"\nkind: \"conference\"\nlocation: \"Koto City, Tokyo, Japan\"\ndescription: |-\n  Oedo RubyKaigi 01 is a regional Ruby conference organized by Asakusa.rb to commemorate their 100th meetup.\npublished_at: \"2011-04-10\"\nstart_date: \"2011-04-10\"\nend_date: \"2011-04-10\"\nchannel_id: \"UCRfl3SDwU9hw37QxhvfVRAA\"\nplaylist: \"PLkcX6PjCRhhob30EUxoZMBmo4wTDsgyn8\"\nyear: 2011\nwebsite: \"https://regional.rubykaigi.org/oedo01/\"\nvenue: \"Fukagawa Edo Museum\"\ncoordinates:\n  latitude: 35.6811859\n  longitude: 139.8005921\n"
  },
  {
    "path": "data/oedo-rubykaigi/oedo-rubykaigi-01/videos.yml",
    "content": "---\n- id: \"akira-matsuda-oedo-rubykaigi-01\"\n  title: \"100 times { Asakusa.rb.meetup! }\"\n  raw_title: \"100 times { Asakusa rb meetup! }   @a matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"Oedo RubyKaigi 01\"\n  date: \"2011-04-10\"\n  published_at: \"2011-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"Lc8fRxq9k3g\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"koichi-sasada-oedo-rubykaigi-01\"\n  title: \"Ruby 処理系の構想（妄想）\"\n  raw_title: \"Ruby 処理系の構想（妄想）  笹田耕一\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"Oedo RubyKaigi 01\"\n  date: \"2011-04-10\"\n  published_at: \"2011-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"tx-KxftG7cA\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"hiroshi-nakamura-oedo-rubykaigi-01\"\n  title: \"大江戸HTTPクライアント絵巻\"\n  raw_title: \"大江戸HTTPクライアント絵巻   @nahi\"\n  speakers:\n    - Hiroshi Nakamura\n  event_name: \"Oedo RubyKaigi 01\"\n  date: \"2011-04-10\"\n  published_at: \"2011-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"Iw3vMLWGYrM\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"daisuke-yamashita-oedo-rubykaigi-01\"\n  title: \"RailsとCで作る大量広告配信システム\"\n  raw_title: \"RailsとCで作る大量広告配信システム   @yamaz\"\n  speakers:\n    - Daisuke Yamashita\n  event_name: \"Oedo RubyKaigi 01\"\n  date: \"2011-04-10\"\n  published_at: \"2011-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"qUb_SdM9g3U\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"mayumi-emori-oedo-rubykaigi-01\"\n  title: \"mission critical なシステムでも使える Thread の作り方\"\n  raw_title: \"mission critical なシステムでも使える Thread の作り方   @emorima\"\n  speakers:\n    - Mayumi EMORI\n  event_name: \"Oedo RubyKaigi 01\"\n  date: \"2011-04-10\"\n  published_at: \"2011-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"_9WruaZcfsw\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yuuichi-tateno-oedo-rubykaigi-01\"\n  title: \"高速なテストサイクルを回すには\"\n  raw_title: \"高速なテストサイクルを回すには   id secondlife @hotchpotch\"\n  speakers:\n    - Yuuichi Tateno\n  event_name: \"Oedo RubyKaigi 01\"\n  date: \"2011-04-10\"\n  published_at: \"2011-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"5WFdH5NIvhA\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"hiroshi-shibata-oedo-rubykaigi-01\"\n  title: \"エンドツーエンドテストはCapybaraにお任せ!\"\n  raw_title: \"エンドツーエンドテストはCapybaraにお任せ!   @hsbt\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"Oedo RubyKaigi 01\"\n  date: \"2011-04-10\"\n  published_at: \"2011-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"TH1rHW8hqfI\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yuki-akamatsu-oedo-rubykaigi-01\"\n  title: \"RubyにおけるClean Code戦略\"\n  raw_title: \"RubyにおけるClean Code戦略   @ukstudio\"\n  speakers:\n    - Yuki Akamatsu\n  event_name: \"Oedo RubyKaigi 01\"\n  date: \"2011-04-10\"\n  published_at: \"2011-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"WRMsvIEQyWc\"\n  language: \"Japanese\"\n  description: \"\"\n"
  },
  {
    "path": "data/oedo-rubykaigi/oedo-rubykaigi-02/event.yml",
    "content": "---\nid: \"oedo-rubykaigi-02\"\ntitle: \"Oedo RubyKaigi 02\"\nkind: \"conference\"\nlocation: \"Koto City, Tokyo, Japan\"\ndescription: |-\n  Oedo RubyKaigi 02 is a regional Ruby conference organized by Asakusa.rb featuring Dave Thomas (Pragdave).\nstart_date: \"2012-03-17\"\nend_date: \"2012-03-17\"\nchannel_id: \"UCRfl3SDwU9hw37QxhvfVRAA\"\nyear: 2012\nwebsite: \"https://regional.rubykaigi.org/oedo02/\"\nvenue: \"Fukagawa Edo Museum\"\ncoordinates:\n  latitude: 35.6811859\n  longitude: 139.8005921\n"
  },
  {
    "path": "data/oedo-rubykaigi/oedo-rubykaigi-02/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/oedo-rubykaigi/oedo-rubykaigi-03/event.yml",
    "content": "# https://github.com/asakusarb/oedo03\n---\nid: \"oedo-rubykaigi-03\"\ntitle: \"Oedo RubyKaigi 03\"\nkind: \"conference\"\nlocation: \"Koto City, Tokyo, Japan\"\ndescription: |-\n  Oedo RubyKaigi 03 is a regional Ruby conference organized by Asakusa.rb to commemorate their 200th meetup.\nstart_date: \"2013-03-16\"\nend_date: \"2013-03-16\"\nchannel_id: \"UCRfl3SDwU9hw37QxhvfVRAA\"\nyear: 2013\nwebsite: \"https://regional.rubykaigi.org/oedo03/\"\ncoordinates:\n  latitude: 35.6812581\n  longitude: 139.8005678\n"
  },
  {
    "path": "data/oedo-rubykaigi/oedo-rubykaigi-03/venue.yml",
    "content": "---\nname: \"Fukagawa Edo Shiryoukan Small Theater\"\n\naddress:\n  street: \"1-chōme-3-28 Shirakawa\"\n  city: \"Koto City\"\n  region: \"Tokyo\"\n  postal_code: \"135-0021\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"1-chōme-3-28 Shirakawa, Koto City, Tokyo 135-0021, Japan\"\n\ncoordinates:\n  latitude: 35.6812581\n  longitude: 139.8005678\n\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.6812581,139.8005678\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=35.6812581&mlon=139.8005678&zoom=17\"\n"
  },
  {
    "path": "data/oedo-rubykaigi/oedo-rubykaigi-03/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/oedo-rubykaigi/oedo-rubykaigi-04/event.yml",
    "content": "# https://github.com/asakusarb/oedo04\n---\nid: \"oedo-rubykaigi-04\"\ntitle: \"Oedo RubyKaigi 04\"\nkind: \"conference\"\nlocation: \"Sumida City, Tokyo, Japan\"\ndescription: |-\n  Oedo RubyKaigi 04 is a regional Ruby conference organized by Asakusa.rb to commemorate their 256th meeting.\npublished_at: \"2014-04-25\"\nstart_date: \"2014-04-19\"\nend_date: \"2014-04-19\"\nchannel_id: \"UCRfl3SDwU9hw37QxhvfVRAA\"\nplaylist: \"PLkcX6PjCRhhoh8e9mctY5FgUAfyzwlsTY\"\nyear: 2014\nwebsite: \"http://regional.rubykaigi.org/oedo04\"\nvenue: \"Edo Tokyo Museum\"\ncoordinates:\n  latitude: 35.6965972\n  longitude: 139.7957336\n"
  },
  {
    "path": "data/oedo-rubykaigi/oedo-rubykaigi-04/videos.yml",
    "content": "---\n- id: \"minero-aoki-oedo-rubykaigi-04\"\n  title: \"Ruby会議でSQLの話をするのは間違っているだろうか\"\n  raw_title: \"[oedo04] Ruby会議でSQLの話をするのは間違っているだろうか / @mineroaoki\"\n  speakers:\n    - Minero Aoki\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"9db8BIuRiq0\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"akira-matsuda-oedo-rubykaigi-04\"\n  title: \"Hacking Home\"\n  raw_title: \"[oedo04] Hacking Home / @a_matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"yGWFljoVwK4\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yuki-kurihara-oedo-rubykaigi-04\"\n  title: \"mruby hacking guide\"\n  raw_title: \"[oedo04] mruby hacking guide / @_ksss_\"\n  speakers:\n    - Yuki Kurihara\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"KaXTe1pScJU\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"ken-nishimura-oedo-rubykaigi-04\"\n  title: \"Another language you should learn.\"\n  raw_title: \"[oedo04] Another language you should learn / @knsmr\"\n  speakers:\n    - Ken Nishimura\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"QsyAjIVWrOk\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"koichi-sasada-yuki-sasada-oedo-rubykaigi-04\"\n  title: \"Object Bouquet - 幸せの花束・RValue のきらめきを添えて\"\n  raw_title: \"[oedo04] Object Bouquet ～幸せの花束・RValue のきらめきを添えて～ / @_ko1 and @yotii23\"\n  speakers:\n    - Koichi Sasada\n    - Yuki Sasada\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"jjvrmWDGja0\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"terence-lee-oedo-rubykaigi-04\"\n  title: \"A History of Fetching Specs\"\n  raw_title: \"[oedo04] A History of Fetching Specs / @hone02\"\n  speakers:\n    - Terence Lee\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"j6JcGchGPKw\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"shyouhei-urabe-oedo-rubykaigi-04\"\n  title: \"RFC7159\"\n  raw_title: \"[oedo04] https://rubygems.org/gems/RFC7159 / @shyouhei\"\n  speakers:\n    - Shyouhei Urabe\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"9PMY78dN7Bk\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"kunihiko-ito-oedo-rubykaigi-04\"\n  title: \"1年かけてgemを1つ作りました\"\n  raw_title: \"[oedo04] 1年かけてgemを1つ作りました / @kunitoo\"\n  speakers:\n    - Kunihiko Ito\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"v9Zccln5ZPs\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"ebi-patterson-aaron-patterson-oedo-rubykaigi-04\"\n  title: \"Keynote\"\n  raw_title: \"[oedo04] Keynote / @ebiltwin and @tenderlove\"\n  speakers:\n    - Ebi Patterson\n    - Aaron Patterson\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"sOw3bmwRAho\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"shimpei-makimoto-oedo-rubykaigi-04\"\n  title: \"画像を壊すこと、OSS 活動をすること、その他\"\n  raw_title: \"[oedo04] 画像を壊すこと、OSS 活動をすること、その他 / @makimoto\"\n  speakers:\n    - Shimpei Makimoto\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"G-IbIqE1uH8\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"lori-chin-oedo-rubykaigi-04\"\n  title: \"How to survive and thrive as an engineer in a foreign land\"\n  raw_title: \"[oedo04] how to survice and thrive as an engineer in a foreign land / @lchin\"\n  speakers:\n    - Leonard Chin\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"6J5hiuIuEPc\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"zachary-scott-oedo-rubykaigi-04\"\n  title: \"Nobody Knows Nobu\"\n  raw_title: \"[oedo04] Nobody Knows Nobu / @_zzak\"\n  speakers:\n    - Zachary Scott\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"GkVxzVR3GKA\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"winston-teo-yong-wei-oedo-rubykaigi-04\"\n  title: \"Random Ruby Tips\"\n  raw_title: \"[oedo04] Random Ruby Tips / @winstonyw\"\n  speakers:\n    - Winston Teo Yong Wei\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"XzXTlHbsI9Y\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"ryota-arai-oedo-rubykaigi-04\"\n  title: \"Infrataster - Infra Testing Framework\"\n  raw_title: \"[oedo04] Infrataster - Infra Testing Framework / @ryot_a_rai\"\n  speakers:\n    - Ryota Arai\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"M2s8ieEH3PE\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"hiroshi-shibata-oedo-rubykaigi-04\"\n  title: \"From 'legacy' to the 'edge'\"\n  raw_title: '[oedo04] From \"legacy\" to the \"edge\" / @hsbt'\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"TysxXk_QUEc\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"shintaro-kakutani-oedo-rubykaigi-04\"\n  title: \"Closing\"\n  raw_title: \"[oedo04] closing / @kakutani\"\n  speakers:\n    - Shintaro Kakutani\n  event_name: \"Oedo RubyKaigi 04\"\n  date: \"2014-04-19\"\n  published_at: \"2014-04-25\"\n  video_provider: \"youtube\"\n  video_id: \"j8j5zsI0Waw\"\n  language: \"Japanese\"\n  description: \"\"\n"
  },
  {
    "path": "data/oedo-rubykaigi/series.yml",
    "content": "---\nname: \"Oedo RubyKaigi\"\ndescription: |-\n  Oedo RubyKaigi is a regional Ruby conference organized by Asakusa.rb in Tokyo, Japan.\nkind: \"conference\"\nfrequency: \"irregular\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\nyoutube_channel_id: \"UCRfl3SDwU9hw37QxhvfVRAA\"\nyoutube_channel_name: \"Oedo RubyKaigi\"\naliases:\n  - \"大江戸Ruby会議\"\n"
  },
  {
    "path": "data/osaka-rubykaigi/osaka-rubykaigi-01/event.yml",
    "content": "---\nid: \"osaka-rubykaigi-01\"\ntitle: \"Osaka RubyKaigi 01\"\ndescription: |-\n  Osaka Science & Technology Center\nlocation: \"Osaka, Japan\"\nkind: \"conference\"\nstart_date: \"2018-07-21\"\nend_date: \"2018-07-21\"\nwebsite: \"https://regional.rubykaigi.org/osaka01/\"\ntwitter: \"rubykansai\"\ncoordinates:\n  latitude: 34.6937249\n  longitude: 135.5022535\n"
  },
  {
    "path": "data/osaka-rubykaigi/osaka-rubykaigi-01/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://regional.rubykaigi.org/osaka01/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/osaka-rubykaigi/osaka-rubykaigi-02/event.yml",
    "content": "---\nid: \"osaka-rubykaigi-02\"\ntitle: \"Osaka RubyKaigi 02\"\ndescription: \"\"\nlocation: \"Osaka, Japan\"\nkind: \"conference\"\nstart_date: \"2019-09-15\"\nend_date: \"2019-09-15\"\nwebsite: \"https://regional.rubykaigi.org/osaka02/\"\ntwitter: \"rubykansai\"\ncoordinates:\n  latitude: 34.6937249\n  longitude: 135.5022535\n"
  },
  {
    "path": "data/osaka-rubykaigi/osaka-rubykaigi-02/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://regional.rubykaigi.org/osaka02/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/osaka-rubykaigi/osaka-rubykaigi-03/event.yml",
    "content": "---\nid: \"osaka-rubykaigi-03\"\ntitle: \"Osaka RubyKaigi 03\"\ndescription: \"\"\nlocation: \"Osaka, Japan\"\nkind: \"conference\"\nstart_date: \"2023-09-09\"\nend_date: \"2023-09-09\"\nwebsite: \"https://regional.rubykaigi.org/osaka03/\"\ntwitter: \"rubykansai\"\ncoordinates:\n  latitude: 34.6937249\n  longitude: 135.5022535\naliases:\n  - Osaka Ruby Kaigi 03\n"
  },
  {
    "path": "data/osaka-rubykaigi/osaka-rubykaigi-03/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://regional.rubykaigi.org/osaka03/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/osaka-rubykaigi/osaka-rubykaigi-04/event.yml",
    "content": "---\nid: \"osaka-rubykaigi-04\"\ntitle: \"Osaka RubyKaigi 04\"\ndescription: \"\"\nlocation: \"Osaka, Japan\"\nkind: \"conference\"\nstart_date: \"2024-08-24\"\nend_date: \"2024-08-24\"\nwebsite: \"https://regional.rubykaigi.org/osaka04/\"\ncoordinates:\n  latitude: 34.6937249\n  longitude: 135.5022535\n"
  },
  {
    "path": "data/osaka-rubykaigi/osaka-rubykaigi-04/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://regional.rubykaigi.org/osaka04/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/osaka-rubykaigi/series.yml",
    "content": "---\nname: \"Osaka RubyKaigi\"\nwebsite: \"https://regional.rubykaigi.org/osaka04/\"\ntwitter: \"rubykansai\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\nyoutube_channel_id: \"\"\naliases:\n  - \"大阪Ruby会議\"\n"
  },
  {
    "path": "data/oxente-rails/oxente-rails-2009/event.yml",
    "content": "---\nid: \"oxente-rails-2009\"\ntitle: \"Oxente Rails 2009\"\ndescription: \"\"\nlocation: \"Natal, Brazil\"\nkind: \"conference\"\nstart_date: \"2009-08-07\"\nend_date: \"2009-08-08\"\noriginal_website: \"http://oxenterails.com/en\"\ncoordinates:\n  latitude: -5.7841695\n  longitude: -35.1999708\n"
  },
  {
    "path": "data/oxente-rails/oxente-rails-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/oxente-rails/series.yml",
    "content": "---\nname: \"Oxente Rails\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"portuguese\"\ndefault_country_code: \"BR\"\n"
  },
  {
    "path": "data/paris-rb/paris-rb-meetup/event.yml",
    "content": "---\nid: \"paris-rb-meetup\"\ntitle: \"Paris.rb Meetup\"\nkind: \"meetup\"\ndescription: \"\"\nlocation: \"Paris, France\"\npublished_at: \"2024-11-23\"\nchannel_id: \"UCttFnyoHp4TdsTj1wcVs44A\"\nyear: 2024\nwebsite: \"https://paris-rb.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#E23F52\"\ncoordinates:\n  latitude: 48.8575475\n  longitude: 2.3513765\n"
  },
  {
    "path": "data/paris-rb/paris-rb-meetup/videos.yml",
    "content": "---\n- id: \"paris-rb-march-2016\"\n  title: \"Paris.rb Meetup March 2016\"\n  raw_title: \"Paris.rb Meetup March 2016\"\n  event_name: \"Paris.rb Meetup March 2016\"\n  date: \"2016-03-01\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-march-2016\"\n  description: |-\n    Bonjour,\n    bienvenue à notre rencontre entre rubyistes, tous les premiers mardis du mois !\n\n    • Le lineup est dispo 15j avant : https://rubyparis.org/lineup/#/2\n\n    • Vous cherchez un développeur (https://www.meetup.com/parisrb/pages/Vous_cherchez_un_dev/)\n\n    • Vous venez faire une présentation (https://www.meetup.com/fr-FR/parisrb/pages/Vous_venez_faire_une_prez/)\n\n    • Nous suivons et appliquons le Code of Conduct ParisRB (https://www.meetup.com/fr-FR/parisrb/pages/Code_of_Conduct_ParisRB/)\n\n    • Nous filmons et streamons sur le YouTube ParisRB (https://www.youtube.com/channel/UCttFnyoHp4TdsTj1wcVs44A)\n\n    • Nous pouvons discuter sur le Slack (http://parisrb-slack-invite.herokuapp.com/) ou le Forum (http://forum.rubyparis.org/) ParisRB\n\n    C'est avant tout votre meetup, annoncez ce que vous voudriez y trouver, et il y aura sûrement de bonnes volontés pour le lancer :)\n\n    Un grand merci à nos partenaires : Jobteaser et JobBoardMaker.com, pour nous sponsoriser vous aussi, contactez thibaut@milesrock.com\n\n    À bientôt !\n\n    With <3\n\n    DotScale nous fait une offre assez spécial : il nous font 30% sur leur conf ! Pour y accéder, visitez ce lien :\n\n    http://dotscale2016.eventbrite.com/?discount=PARISRB\n\n    Pour info :\n\n    La quatrième édition de dotScale (http://dotscale.io/), une conférence européenne pour développeurs autour de la Scalabilité, DevOps et des Systèmes Distribués, aura lieu le 25 avril au Théâtre de Paris (http://dotscale.io/venue).\n\n    11+ speakers, sélectionnés parmi les créateurs et contributeurs des projets open source les plus populaires, les CTOs des startups qui grossissent le plus vite, les architectes de plateformes à très large échelle, se succèderont sur la scène lors de cette journée. Parmi eux, le CTO de Mongo DB, le VP infrastructure de Google, le créateur de Gimp, ....\n\n    SI vous voulez savoir comment ces conférences se passent, vous pouvez regarder le récapitulatif de 2 min (https://www.youtube.com/watch?v=Unq0YH80R9s) de la précédente édition, ou visionner les talks (http://www.thedotpost.com/conference/dotscale-2015).\n\n    https://www.meetup.com/parisrb/events/220872045\n  talks:\n    - title: \"Fix - Simple, stupid testing framework for Ruby\"\n      raw_title: \"Fix - Simple, stupid testing framework for Ruby by Cyril Kato\"\n      speakers:\n        - Cyril Kato\n      event_name: \"Paris.rb Meetup March 2016\"\n      language: \"french\"\n      date: \"2016-03-01\"\n      published_at: \"2016-03-16\"\n      video_provider: \"youtube\"\n      id: \"cyril-kato-parisrb-meetup-march-2016\"\n      video_id: \"XV6tVZtKMfA\"\n      description: |-\n        Talk in French.\n\n        By Cyril Kato\n        Paris.rb @ Le Wagon, March 2016\n\n        A presentation of the Fix testing framework, as an alternative to RSpec.\n\n        Links:\n        Meetup: https://www.meetup.com/parisrb/events/220872045/\n        Slides: https://speakerdeck.com/cyril/fix-simple-stupid-testing-framework-for-ruby\n        Code in slides: https://github.com/cyril/parisrb\n        Fix project: https://fixrb.dev/\n        RSpec clone project: https://r-spec.dev/\n\n        Find Cyril Kato at:\n        https://github.com/cyril\n      slides_url: \"https://speakerdeck.com/cyril/fix-simple-stupid-testing-framework-for-ruby\"\n      additional_resources:\n        - name: \"cyril/parisrb\"\n          type: \"repo\"\n          url: \"https://github.com/cyril/parisrb\"\n\n- id: \"paris-rb-november-2021\"\n  title: \"Paris.rb Meetup November 2021\"\n  raw_title: \"Paris.rb Meetup November 2021\"\n  event_name: \"Paris.rb Meetup November 2021\"\n  date: \"2021-11-02\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-november-2021\"\n  description: \"\"\n  talks:\n    - title: \"Redis avec Heroku - Pourquoi et comment séparer son cache\"\n      raw_title: \"Redis avec Heroku - Pourquoi et comment séparer son cache\"\n      speakers:\n        - Amélie Certin\n      event_name: \"Paris.rb Meetup November 2021\"\n      language: \"french\"\n      date: \"2021-11-02\"\n      published_at: \"2022-06-07\"\n      video_provider: \"youtube\"\n      id: \"amelie-certin-parisrb-meetup-november-2021\"\n      video_id: \"lnfc61qjxME\"\n      description: |-\n        Redis avec Heroku - Pourquoi et comment séparer son cache - Amélie Certin\n\n        Paris.rb Novembre 2021\n\n    - title: \"Comment on a amélioré le lien back-front en utilisant des fichiers openAPI\"\n      raw_title: \"Comment on a amélioré le lien back-front en utilisant des fichiers openAPI\"\n      speakers:\n        - Émilie Paillous\n        - Guillaume Terral\n      event_name: \"Paris.rb Meetup November 2021\"\n      language: \"french\"\n      date: \"2021-11-02\"\n      published_at: \"2022-06-07\"\n      video_provider: \"youtube\"\n      id: \"emilie-paillous-parisrb-meetup-november-2021\"\n      video_id: \"2Vno981d2IU\"\n      description: |-\n        Comment on a amélioré le lien back-front en utilisant des fichiers openAPI - Émilie Paillous et Guillaume Terral\n\n        Paris.rb Novembre 2021\n\n- id: \"paris-rb-december-2021\"\n  title: \"Paris.rb Meetup December 2021\"\n  raw_title: \"Paris.rb Meetup December 2021\"\n  event_name: \"Paris.rb Meetup December 2021\"\n  date: \"2021-12-07\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-december-2021\"\n  description: \"\"\n  talks:\n    - title: \"Build a web app with Dry-System\"\n      raw_title: \"Build a web app with Dry-System\"\n      speakers:\n        - Alexandre Lairan\n      event_name: \"Paris.rb Meetup December 2021\"\n      language: \"french\"\n      date: \"2021-12-07\"\n      published_at: \"2022-06-07\"\n      video_provider: \"youtube\"\n      id: \"alexandre-lairan-parisrb-meetup-december-2021\"\n      video_id: \"74Wd_HueAJM\"\n      description: |-\n        Alexandre Lairan\n\n        Paris.rb Décembre 2021\n\n- id: \"paris-rb-january-2022\"\n  title: \"Paris.rb Meetup January 2022\"\n  raw_title: \"Paris.rb Meetup January 2022\"\n  event_name: \"Paris.rb Meetup January 2022\"\n  date: \"2022-01-04\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-january-2022\"\n  description: \"\"\n  talks:\n    - title: \"Comment écrire son code sur un ticket de métro?\"\n      raw_title: \"Comment écrire son code sur un ticket de métro?\"\n      speakers:\n        - Sébastien Faure\n        - Julien Marseille\n      event_name: \"Paris.rb Meetup January 2022\"\n      language: \"french\"\n      date: \"2022-01-04\"\n      published_at: \"2022-06-07\"\n      video_provider: \"youtube\"\n      id: \"sebastien-faure-parisrb-meetup-january-2022\"\n      video_id: \"pWxNtCa2atw\"\n      description: |-\n        Sébastien Faure & Julien Marseille\n\n        Paris.rb Janvier 2022\n\n    - title: \"React on Rails, le meilleur des deux mondes\"\n      raw_title: \"React on Rails, le meilleur des deux mondes\"\n      speakers:\n        - Pierre de Milly\n      event_name: \"Paris.rb Meetup January 2022\"\n      language: \"french\"\n      date: \"2022-01-04\"\n      published_at: \"2022-06-07\"\n      video_provider: \"youtube\"\n      id: \"pierre-de-milly-parisrb-meetup-january-2022\"\n      video_id: \"4aCYr7d-Fok\"\n      description: |-\n        Pierre de Milly\n\n        Paris.rb Janvier 2022\n\n- id: \"paris-rb-february-2022\"\n  title: \"Paris.rb Meetup February 2022\"\n  raw_title: \"Paris.rb Meetup February 2022\"\n  event_name: \"Paris.rb Meetup February 2022\"\n  date: \"2022-02-01\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-february-2022\"\n  description: \"\"\n  talks:\n    - title: \"Service Objects, la brique manquante de Rails\"\n      raw_title: \"Service Objects, la brique manquante de Rails\"\n      event_name: \"Paris.rb Meetup February 2022\"\n      language: \"french\"\n      date: \"2022-02-01\"\n      published_at: \"2022-06-07\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"service-objects-la-brique-manquante-de-rails-parisrb-meetup-february-2022\"\n      video_id: \"xVdDBpcvEYM\"\n      description: |-\n        Paris.rb Février 2022\n\n- id: \"paris-rb-march-2022\"\n  title: \"Paris.rb Meetup March 2022\"\n  raw_title: \"Paris.rb Meetup March 2022\"\n  event_name: \"Paris.rb Meetup March 2022\"\n  date: \"2022-03-01\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-march-2022\"\n  description: \"\"\n  talks:\n    - title: \"Better safe than sorry\"\n      raw_title: \"Better safe than sorry\"\n      speakers:\n        - Benjamin Combourieu\n      event_name: \"Paris.rb Meetup March 2022\"\n      language: \"french\"\n      date: \"2022-03-01\"\n      published_at: \"2022-06-07\"\n      video_provider: \"youtube\"\n      id: \"benjamin-combourieu-parisrb-meetup-march-2022\"\n      video_id: \"ioxG8mKR1zw\"\n      description: |-\n        Benjamin Combourieu\n\n        Paris.rb Mars 2022\n\n- id: \"paris-rb-may-2022\"\n  title: \"Paris.rb Meetup May 2022\"\n  raw_title: \"Paris.rb Meetup May 2022\"\n  event_name: \"Paris.rb Meetup May 2022\"\n  date: \"2022-05-03\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-may-2022\"\n  description: \"\"\n  talks:\n    - title: \"Implementing blackout period on Puma workers\"\n      raw_title: \"Implementing blackout period on Puma workers\"\n      speakers:\n        - Martin Chenu\n        - Maxime Deveaux\n      event_name: \"Paris.rb Meetup May 2022\"\n      language: \"french\"\n      date: \"2022-05-03\"\n      published_at: \"2022-06-07\"\n      video_provider: \"youtube\"\n      id: \"martin-chenu-parisrb-meetup-may-2022\"\n      video_id: \"l9ie8M3RhdE\"\n      description: |-\n        Martin Chenu & Maxime Deveaux\n\n        Paris.rb Mai 2022\n\n    - title: \"Lesson Learned from DB issues\"\n      raw_title: \"Lesson Learned from DB issues\"\n      speakers:\n        - Fabienne Bremond\n        - Juliette Audema\n        - Pauline Rousset\n      event_name: \"Paris.rb Meetup May 2022\"\n      language: \"french\"\n      date: \"2022-05-03\"\n      published_at: \"2022-06-07\"\n      video_provider: \"youtube\"\n      id: \"fabienne-bremond-parisrb-meetup-may-2022\"\n      video_id: \"OS7lsnN6j8U\"\n      description: |-\n        Fabienne Bremond, Juliette Audema, Pauline Rousset\n\n        Paris.rb Mai 2022\n\n- id: \"paris-rb-june-2022\"\n  title: \"Paris.rb Meetup June 2022\"\n  raw_title: \"Paris.rb Meetup June 2022\"\n  event_name: \"Paris.rb Meetup June 2022\"\n  date: \"2022-06-07\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-june-2022\"\n  description: \"\"\n  talks:\n    - title: \"Commit comme un hipster avec Gitmoji !\"\n      raw_title: \"Commit comme un hipster avec Gitmoji !\"\n      speakers:\n        - Sylvain Pontoreau\n      event_name: \"Paris.rb Meetup June 2022\"\n      language: \"french\"\n      date: \"2022-06-07\"\n      published_at: \"2022-06-08\"\n      video_provider: \"youtube\"\n      id: \"sylvain-pontoreau-parisrb-meetup-june-2022\"\n      video_id: \"1Lvr0Hr_ot0\"\n      description: |-\n        Sylvain Pontoreau\n        Paris.rb Juin 2022\n\n    - title: \"Industrialiser une API\"\n      raw_title: \"Industrialiser une API\"\n      speakers:\n        - Anthony Gaidot\n      event_name: \"Paris.rb Meetup June 2022\"\n      language: \"french\"\n      date: \"2022-06-07\"\n      published_at: \"2022-06-08\"\n      video_provider: \"youtube\"\n      id: \"anthony-gaidot-parisrb-meetup-june-2022\"\n      video_id: \"sX8ELUVHV0U\"\n      description: |-\n        Comment on a industrialisé le développement et le testing de notre API\n        Anthony Gaidot\n\n        Paris.rb Juin 2022\n\n    - title: \"On a recruté un.e dev junior ! AMA\"\n      raw_title: \"On a recruté un.e dev junior ! AMA\"\n      speakers:\n        - Adrien Poly\n      event_name: \"Paris.rb Meetup June 2022\"\n      language: \"french\"\n      date: \"2022-06-07\"\n      published_at: \"2022-06-08\"\n      video_provider: \"youtube\"\n      id: \"adrien-poly-parisrb-meetup-june-2022\"\n      video_id: \"pAmY8GJvqK0\"\n      description: |-\n        Par Adrien POLY\n        Paris.rb Juin 2022\n\n- id: \"paris-rb-september-2022\"\n  title: \"Paris.rb Meetup September 2022\"\n  raw_title: \"Paris.rb Meetup September 2022\"\n  event_name: \"Paris.rb Meetup September 2022\"\n  date: \"2022-09-06\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-september-2022\"\n  description: \"\"\n  talks:\n    - title: \"How music works, using Ruby [English]\"\n      raw_title: \"How music works, using Ruby [English]\"\n      speakers:\n        - Thijs Cadier\n      event_name: \"Paris.rb Meetup September 2022\"\n      language: \"english\"\n      date: \"2022-09-06\"\n      published_at: \"2022-10-17\"\n      video_provider: \"youtube\"\n      id: \"thijs-cadier-parisrb-meetup-september-2022\"\n      video_id: \"j5o9HbSaL8w\"\n      description: |-\n        Thijs Cadier - Paris.rb Septembre 2022\n\n        Merci à  @Squadracer qui a accueilli le meetup... sur une péniche !\n        https://squadracer.com\n\n    - title: \"Rails : XSS protection\"\n      raw_title: \"Rails : XSS protection\"\n      event_name: \"Paris.rb Meetup September 2022\"\n      language: \"french\"\n      date: \"2022-09-06\"\n      published_at: \"2022-09-11\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"rails-xss-protection-parisrb-meetup-september-2022\"\n      video_id: \"SFuGfTqSFvU\"\n      description: |-\n        0xdbe - Paris.rb Septembre 2022\n\n        Merci à @Squadracer  qui a accueilli le meetup... sur une péniche !\n        https://squadracer.com\n\n- id: \"paris-rb-october-2022\"\n  title: \"Paris.rb Meetup October 2022\"\n  raw_title: \"Paris.rb Meetup October 2022\"\n  event_name: \"Paris.rb Meetup October 2022\"\n  date: \"2022-10-04\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-october-2022\"\n  description: \"\"\n  talks:\n    - title: \"Produire du logiciel dans une coopérative ouvrière\"\n      raw_title: \"Produire du logiciel dans une coopérative ouvrière\"\n      event_name: \"Paris.rb Meetup October 2022\"\n      language: \"french\"\n      date: \"2022-10-04\"\n      published_at: \"2022-10-08\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"produire-du-logiciel-dans-une-cooperative-ouvriere-parisrb-meetup-october-2022\"\n      video_id: \"lNbCLgJvuFA\"\n      description: |-\n        Pourquoi Rails a été l'outil parfait pour concevoir Cyke\n        Paris.rb octobre 2022\n\n        Merci à Olvo d'avoir accueilli le metteup : https://www.olvo.fr\n\n- id: \"paris-rb-november-2022\"\n  title: \"Paris.rb Meetup November 2022\"\n  raw_title: \"Paris.rb Meetup November 2022\"\n  event_name: \"Paris.rb Meetup November 2022\"\n  date: \"2022-11-01\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-november-2022\"\n  description: \"\"\n  talks:\n    - title: \"Sorbet in practice\"\n      raw_title: \"Sorbet in practice\"\n      speakers:\n        - Benjamin Roth\n      event_name: \"Paris.rb Meetup November 2022\"\n      language: \"french\"\n      date: \"2022-11-01\"\n      published_at: \"2022-11-26\"\n      video_provider: \"youtube\"\n      id: \"benjamin-roth-parisrb-meetup-november-2022\"\n      video_id: \"DRrIDPzirzE\"\n      description: |-\n        Par Benjamin Roth\n        https://twitter.com/apneadiving\n\n        Paris.rb novembre 2022\n\n        Merci à Combo d'avoir accueilli le meeteup : https://combohr.com\n\n    - title: \"Business Logic and data integrity\"\n      raw_title: \"Business Logic and data integrity\"\n      speakers:\n        - Stéphanie Chhim\n        - Benjamin Robert\n      event_name: \"Paris.rb Meetup November 2022\"\n      language: \"french\"\n      date: \"2022-11-01\"\n      published_at: \"2022-11-26\"\n      video_provider: \"youtube\"\n      id: \"stephanie-chhim-parisrb-meetup-november-2022\"\n      video_id: \"JFPaJnahtH8\"\n      description: |-\n        Par Stéphanie Chhim et Benjamin Robert\n\n        Paris.rb novembre 2022\n\n        Merci à Combo d'avoir accueilli le meeteup : https://combohr.com\n\n    - title: \"Level up your Capybara acceptance tests using SitePrism\"\n      raw_title: \"Level up your Capybara acceptance tests using SitePrism\"\n      speakers:\n        - Dorian Lupu\n      event_name: \"Paris.rb Meetup November 2022\"\n      language: \"french\"\n      date: \"2022-11-01\"\n      published_at: \"2022-11-26\"\n      video_provider: \"youtube\"\n      id: \"dorian-lupu-parisrb-meetup-november-2022\"\n      video_id: \"Yf09FVj_hG4\"\n      description: |-\n        Par Dorian Lupu\n        https://twitter.com/dorianlupu\n\n        Paris.rb novembre 2022\n\n        Merci à Combo d'avoir accueilli le metteup : https://combohr.com\n\n    - title: \"Optimisation TCP: le clash\"\n      raw_title: \"Optimisation TCP: le clash\"\n      speakers:\n        - Gauthier Monserand\n      event_name: \"Paris.rb Meetup November 2022\"\n      language: \"french\"\n      date: \"2022-11-01\"\n      published_at: \"2022-11-26\"\n      video_provider: \"youtube\"\n      id: \"gauthier-monserand-parisrb-meetup-november-2022\"\n      video_id: \"GT-2P94U9-U\"\n      description: |-\n        Nagle algorithm et delayed ack\n        Par Gauthier Monserand\n        https://mastodon.social/@gmonserand\n\n        Paris.rb novembre 2022\n\n        Merci à Combo d'avoir accueilli le meeteup : https://combohr.com\n\n- id: \"paris-rb-december-2022\"\n  title: \"Paris.rb Meetup December 2022\"\n  raw_title: \"Paris.rb Meetup December 2022\"\n  event_name: \"Paris.rb Meetup December 2022\"\n  date: \"2022-12-06\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-december-2022\"\n  description: \"\"\n  talks:\n    - title: \"Comment nous avons divisé les bugs par 3.5 en un an\"\n      raw_title: \"Comment nous avons divisé les bugs par 3.5 en un an\"\n      speakers:\n        - Stéphane Hanser\n      event_name: \"Paris.rb Meetup December 2022\"\n      language: \"french\"\n      date: \"2022-12-06\"\n      published_at: \"2022-12-20\"\n      video_provider: \"youtube\"\n      id: \"stephane-hanser-parisrb-meetup-december-2022\"\n      video_id: \"Nuu_cWiuudI\"\n      description: |-\n        Par Stéphane Hanser\n        https://www.linkedin.com/in/stephane-hanser-developpeur\n\n        Paris.rb Meetup décembre 2022\n        Merci à kard.eu de nous avoir accueillis.\n\n    - title: \"L'archi d'un backoffice\"\n      raw_title: \"L'archi d'un backoffice\"\n      speakers:\n        - Romain Durritçague\n        - Aymeric Serradeil\n      event_name: \"Paris.rb Meetup December 2022\"\n      language: \"french\"\n      date: \"2022-12-06\"\n      published_at: \"2022-12-19\"\n      video_provider: \"youtube\"\n      id: \"romain-durritcague-parisrb-meetup-december-2022\"\n      video_id: \"9DvyzwjS4TA\"\n      description: |-\n        Par Romain Durritçague et Aymeric Serradeil.\n\n        0:00 Présentation de Kard\n        5:20 L'archi d'un backoffice\n        15:30 Q&A\n\n\n        Paris.rb Meetup décembre 2022\n        Merci à kard.eu de nous avoir accueillis.\n\n    - title: \"Le chaînage des scopes dans Active Record\"\n      raw_title: \"Le chaînage des scopes dans Active Record\"\n      speakers:\n        - Gauthier Monserand\n      event_name: \"Paris.rb Meetup December 2022\"\n      language: \"french\"\n      date: \"2022-12-06\"\n      published_at: \"2022-12-19\"\n      video_provider: \"youtube\"\n      id: \"gauthier-monserand-parisrb-meetup-december-2022\"\n      video_id: \"arxxp4CK-CU\"\n      description: |-\n        Par Gauthier Monserand\n        https://mastodon.social/@gmonserand\n\n        Paris.rb Meetup décembre 2022\n        Merci à kard.eu de nous avoir accueillis.\n\n- id: \"paris-rb-january-2023\"\n  title: \"Paris.rb Meetup January 2023\"\n  raw_title: \"Paris.rb Meetup January 2023\"\n  event_name: \"Paris.rb Meetup January 2023\"\n  date: \"2023-01-03\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-january-2023\"\n  description: \"\"\n  talks:\n    - title: \"Éliminer définitivement vos bugs grâce à la méthode PISCARE\"\n      raw_title: \"Éliminer définitivement vos bugs grâce à la méthode PISCARE\"\n      speakers:\n        - Stéphane Hanser\n      event_name: \"Paris.rb Meetup January 2023\"\n      language: \"french\"\n      date: \"2023-01-03\"\n      published_at: \"2023-01-12\"\n      video_provider: \"youtube\"\n      id: \"stephane-hanser-parisrb-meetup-january-2023\"\n      video_id: \"kL62x42LdpU\"\n      description: |-\n        Par Stéphane Hanser\n        https://www.linkedin.com/in/stephane-hanser-developpeur\n\n        Paris.rb Meetup janvier 2023\n        Merci à scaleway.com de nous avoir accueillis.\n\n        00:00 Talk\n        18:23 Questions\n\n    - title: \"Ajouter la visibilité des CVEs dans rubygems.org\"\n      raw_title: \"Ajouter la visibilité des CVEs dans rubygems.org\"\n      speakers:\n        - Yoann Lecuyer\n      event_name: \"Paris.rb Meetup January 2023\"\n      language: \"french\"\n      date: \"2023-01-03\"\n      published_at: \"2023-01-12\"\n      video_provider: \"youtube\"\n      id: \"yoann-lecuyer-parisrb-meetup-january-2023\"\n      video_id: \"E9lecF6gXek\"\n      description: |-\n        Par Yoann Lecuyer\n\n        La PR : https://github.com/rubygems/rubygems.org/pull/3264\n\n        Paris.rb Meetup Janvier 2023\n        Merci à scaleway.com de nous avoir accueillis.\n\n        00:00 Talk\n        09:52 Questions\n\n- id: \"paris-rb-february-2023\"\n  title: \"Paris.rb Meetup February 2023\"\n  raw_title: \"Paris.rb Meetup February 2023\"\n  event_name: \"Paris.rb Meetup February 2023\"\n  date: \"2023-02-07\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-february-2023\"\n  description: \"\"\n  talks:\n    - title: \"Migrer sereinement du Monolithe aux microservices\"\n      raw_title: \"Migrer sereinement du Monolithe aux microservices\"\n      speakers:\n        - Jean-Paul Bonnetouche\n      event_name: \"Paris.rb Meetup February 2023\"\n      language: \"french\"\n      date: \"2023-02-07\"\n      published_at: \"2023-02-09\"\n      video_provider: \"youtube\"\n      id: \"jean-paul-bonnetouche-parisrb-meetup-february-2023\"\n      video_id: \"3itItUYOFCE\"\n      description: |-\n        Par Jean-Paul Bonnetouche\n        Paris.rb Meetup février 2023\n        Merci à https://aircall.io de nous avoir accueillis.\n\n        0:00 Intro\n        2:03 Talk\n        37:55 Questions\n\n        Retrouvez Jean-Paul :\n        https://twitter.com/_jpb\n        https://www.linkedin.com/in/jean-paul-bonnetouche/\n        https://www.malt.fr/profile/madvoid\n\n    - title: \"Testing best practices\"\n      raw_title: \"Testing best practices\"\n      speakers:\n        - Stéphane Akkaoui\n      event_name: \"Paris.rb Meetup February 2023\"\n      language: \"french\"\n      date: \"2023-02-07\"\n      published_at: \"2023-02-09\"\n      video_provider: \"youtube\"\n      id: \"stephane-akkaoui-parisrb-meetup-february-2023\"\n      video_id: \"pkIn4o5Ktt4\"\n      description: |-\n        Par Stéphane Akkaoui\n        Paris.rb Meetup février 2023\n        Merci à https://aircall.io de nous avoir accueillis.\n\n        0:00 Intro\n        1:39 Talk\n        24:40 Questions\n\n        Librairies\n        - RSpec 2 https://rspec.info\n        - Factory Bot https://github.com/thoughtbot/factory_bot\n        - Shoulda Matchers https://matchers.shoulda.io/\n        - Timecop https://github.com/travisjeffery/timecop\n        - Webmock https://github.com/bblimke/webmock\n        - Autotest, Watchr and Test Notifier\n\n        Littérature\n        - The RSpec Book http://www.pragprog.com/titles/achbd/the-rspec-book\n        - Rails Test Prescriptions https://pragprog.com/titles/nrtest/rails-test-prescriptions\n        - Everyday rails spec https://leanpub.com/everydayrailsrspec\n        - Eggs on bread best practices https://eggsonbread.com/2010/03/28/my-rspec-best-practices-and-tips/\n        - Carbon Five best practices https://blog.carbonfive.com/2010/10/21/rspec-best-practices/\n        - Dmytro best practices https://kpumuk.info/ruby-on-rails/my-top-7-rspec-best-practices/\n\n        Retrouvez Stéphane :\n        - https://twitter.com/meuble\n        - https://www.linkedin.com/in/st%C3%A9phane-akkaoui\n        - https://commodat.com\n        - https://nanotrust.io\n\n- id: \"paris-rb-march-2023\"\n  title: \"Paris.rb Meetup March 2023\"\n  raw_title: \"Paris.rb Meetup March 2023\"\n  event_name: \"Paris.rb Meetup March 2023\"\n  date: \"2023-03-07\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-march-2023\"\n  description: \"\"\n  talks:\n    - title: \"Pourquoi quitter la tech ?\"\n      raw_title: \"Pourquoi quitter la tech ?\"\n      event_name: \"Paris.rb Meetup March 2023\"\n      language: \"french\"\n      date: \"2023-03-07\"\n      published_at: \"2023-03-06\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"pourquoi-quitter-la-tech-parisrb-meetup-march-2023\"\n      video_id: \"AuPewwPS6qM\"\n      description: |-\n        Par Sonia\n        Paris.rb Meetup Mars 2023\n        Merci à Doctolib de nous avoir accueillis.\n        https://doctolib.engineering\n\n        0:00 Intro\n        0:38 Talk\n        Malheureusement, les questions n'ont pas pu être enregistrées.\n\n        Liens :\n        https://patch-throne-fea.notion.site/Pourquoi-quitter-la-tech-Bibliographie-0ff3cc98facd4324b607972b3dc26a41\n\n        Retrouvez Sonia :\n        https://twitter.com/wondersonja\n\n    - title: \"Des espaces sûrs pour les développeuses\"\n      raw_title: \"Des espaces sûrs pour les développeuses\"\n      speakers:\n        - Juliette Audema\n      event_name: \"Paris.rb Meetup March 2023\"\n      language: \"french\"\n      date: \"2023-03-07\"\n      published_at: \"2023-03-06\"\n      video_provider: \"youtube\"\n      id: \"juliette-audema-parisrb-meetup-march-2023\"\n      video_id: \"ZFc4IaGDvsQ\"\n      description: |-\n        Par Juliette Audema\n        Paris.rb Meetup Mars 2023\n        Merci à Doctolib de nous avoir accueillis.\n        https://doctolib.engineering\n\n        0:00 Intro\n        0:49 Talk\n        28:06 Questions\n\n        Liens :\n        Slides :https://docs.google.com/presentation/d/1nGmGMHy3dGCCPVljarbvQgns75zxncxuDXNp6jHKLMk/edit?usp=sharing\n\n        Retrouvez Juliette Audema  :\n        https://www.twitter.com/ajuliettedev\n        https://www.linkedin.com/in/juliette-audema-46270a82\n\n    - title: \"Rails : Gérer ses migrations sans downtime\"\n      raw_title: \"Rails : Gérer ses migrations sans downtime\"\n      event_name: \"Paris.rb Meetup March 2023\"\n      language: \"french\"\n      date: \"2023-03-07\"\n      published_at: \"2023-03-06\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"rails-gerer-ses-migrations-sans-downtime-parisrb-meetup-march-2023\"\n      video_id: \"NX6bgyB01mk\"\n      description: |-\n        Par Thomas & Yann\n        Paris.rb Meetup Mars 2023\n        Merci à Doctolib de nous avoir accueillis.\n        https://doctolib.engineering\n\n        0:00 Intro\n        0:28 Talk\n        23:00 Questions\n\n        Liens :\n        - https://medium.com/doctolib/stop-worrying-about-postgresql-locks-in-your-rails-migrations-3426027e9cc9\n        - https://github.com/doctolib/safe-pg-migrations\n        - https://github.com/ThHareau/safe-pg-migrations-demo\n\n        Retrouvez Thomas & Yann :\n        - https://piaille.fr/@thhareau\n        - https://twitter.com/ThomasHareau\n        - https://twitter.com/yann120\n\n- id: \"paris-rb-april-2023\"\n  title: \"Paris.rb Meetup April 2023\"\n  raw_title: \"Paris.rb Meetup April 2023\"\n  event_name: \"Paris.rb Meetup April 2023\"\n  date: \"2023-04-04\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-april-2023\"\n  description: \"\"\n  talks:\n    - title: \"Numérique Responsable - Introduction\"\n      raw_title: \"Numérique Responsable - Introduction\"\n      speakers:\n        - Xavier Meunier\n      event_name: \"Paris.rb Meetup April 2023\"\n      language: \"french\"\n      date: \"2023-04-04\"\n      published_at: \"2023-04-28\"\n      video_provider: \"youtube\"\n      id: \"xavier-meunier-parisrb-meetup-april-2023\"\n      video_id: \"Xle9RmF_wCY\"\n      description: |-\n        Par Xavier Meunier\n        Paris.rb Meetup Avril 2023\n        Merci à Squadracer de nous avoir accueillis.\n        https://squadracer.com\n\n        0:00 Intro\n        1:15 Talk\n        31:13 Questions\n\n        Retrouvez Xavier Meunier :\n        https://twitter.com/XavierMeunier\n\n    - title: \"A Different Way to Think About Rails Models [EN]\"\n      raw_title: \"A Different Way to Think About Rails Models [EN]\"\n      speakers:\n        - Jason Swett\n      event_name: \"Paris.rb Meetup April 2023\"\n      language: \"english\"\n      date: \"2023-04-04\"\n      published_at: \"2023-04-28\"\n      video_provider: \"youtube\"\n      id: \"jason-swett-parisrb-meetup-april-2023\"\n      video_id: \"vKjwa8fie8E\"\n      description: |-\n        Par Jason Swett\n        Paris.rb Meetup Avril 2023\n        Merci à Squadracer de nous avoir accueillis.\n        https://squadracer.com\n\n        0:00 Intro\n        1:41 Talk\n\n        Retrouvez Jason :\n        https://twitter.com/JasonSwett\n        https://www.codewithjason.com\n\n    - title: \"RoRdle, Ruby on Rails wordle\"\n      raw_title: \"RoRdle, Ruby on Rails wordle\"\n      event_name: \"Paris.rb Meetup April 2023\"\n      language: \"french\"\n      date: \"2023-04-04\"\n      published_at: \"2023-04-27\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"rordle-ruby-on-rails-wordle-parisrb-meetup-april-2023\"\n      video_id: \"lc7Hp1lL3x4\"\n      description: |-\n        Par Julien et Sébastien\n        Paris.rb Meetup Avril 2023\n        Merci à Squadracer de nous avoir accueillis.\n        https://squadracer.com\n\n        0:00 Intro\n        0:37 Talk\n        6:35 Questions\n\n        Lien :\n        https://rordle.app\n\n        Retrouvez Julien et Sébastien :\n        https://twitter.com/julienmarseil\n        https://twitter.com/fauresebast\n\n- id: \"paris-rb-may-2023\"\n  title: \"Paris.rb Meetup May 2023\"\n  raw_title: \"Paris.rb Meetup May 2023\"\n  event_name: \"Paris.rb Meetup May 2023\"\n  date: \"2023-05-02\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-may-2023\"\n  description: \"\"\n  talks:\n    - title: \"Ruby vs Amendes de stationnement\"\n      raw_title: \"Ruby vs Amendes de stationnement\"\n      event_name: \"Paris.rb Meetup May 2023\"\n      language: \"french\"\n      date: \"2023-05-02\"\n      published_at: \"2023-06-29\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"ruby-vs-amendes-de-stationnement-parisrb-meetup-may-2023\"\n      video_id: \"ERLdFyoEL-A\"\n      description: |-\n        Par Tom\n        Paris.rb Meetup Mai 2023\n        Merci à Theodo de nous avoir accueillis.\n        https://www.theodo.fr\n\n        0:00 Intro\n        0:45 Talk\n        Liens :\n        https://www.pervenche.eu\n\n        Retrouvez Tom :\n        https://github.com/troptropcontent\n\n    - title: \"ROM-rb, a meta ORM\"\n      raw_title: \"ROM-rb, a meta ORM\"\n      event_name: \"Paris.rb Meetup May 2023\"\n      language: \"french\"\n      date: \"2023-05-02\"\n      published_at: \"2023-06-29\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"rom-rb-a-meta-orm-parisrb-meetup-may-2023\"\n      video_id: \"lot4pZztPwU\"\n      description: |-\n        Par Alexandre\n        Paris.rb Meetup Mai 2023\n        Merci à Theodo de nous avoir accueillis.\n        https://www.theodo.fr\n\n        0:00 Intro\n        1:51 Talk\n        17:09 Questions\n\n        Retrouvez Alexandre :\n        https://twitter.com/alexlairan\n        https://ruby.social/@alexandrelairan\n        https://github.com/alex-lairan\n\n        Suite à un problème technique, nous n'avons malheureusement pas de vidéo au début du talk.\n\n    - title: \"ViewComponent\"\n      raw_title: \"ViewComponent\"\n      speakers:\n        - Adrien Siami\n      event_name: \"Paris.rb Meetup May 2023\"\n      language: \"french\"\n      date: \"2023-05-02\"\n      published_at: \"2023-06-29\"\n      video_provider: \"youtube\"\n      id: \"adrien-siami-parisrb-meetup-may-2023\"\n      video_id: \"Gg3AZ-3Xj2o\"\n      description: |-\n        Par Adrien Siami\n        Paris.rb Meetup Mai 2023\n        Merci à Theodo de nous avoir accueillis.\n        https://www.theodo.fr\n\n        0:00 Intro\n        0:35 Talk\n        6:03 Questions\n\n        Retrouvez Adrien Siami :\n        https://twitter.com/Intrepidd\n\n        Suite à un problème technique, nous n'avons malheureusement pas de vidéo sur ce talk.\n\n- id: \"paris-rb-june-2023\"\n  title: \"Paris.rb Meetup June 2023\"\n  raw_title: \"Paris.rb Meetup June 2023\"\n  event_name: \"Paris.rb Meetup June 2023\"\n  date: \"2023-06-06\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-june-2023\"\n  description: \"\"\n  talks:\n    - title: \"8 astuces pour une app plus rapide\"\n      raw_title: \"8 astuces pour une app plus rapide\"\n      speakers:\n        - Dorian Becker\n      event_name: \"Paris.rb Meetup June 2023\"\n      language: \"french\"\n      date: \"2023-06-06\"\n      published_at: \"2023-08-24\"\n      video_provider: \"youtube\"\n      id: \"dorian-becker-parisrb-meetup-june-2023\"\n      video_id: \"lppgNnqxA3k\"\n      description: |-\n        Par Dorian Becker\n        Paris.rb Meetup Juin 2023\n        Merci à mobiskill de nous avoir accueillis.\n        https://mobiskill.fr\n\n        0:00 Intro\n        0:42 Talk\n        21:29 Questions\n\n        Liens :\n        - https://github.com/mhenrixon/sidekiq-unique-jobs\n        - https://github.com/ixti/sidekiq-throttled\n        - https://github.com/scenic-views/scenic\n        - https://hakibenita.com/postgresql-unused-index-size\n\n        Retrouvez Dorian :\n        https://twitter.com/blaked_84\n\n    - title: \"Migration d'Heroku à Scalingo\"\n      raw_title: \"Migration d'Heroku à Scalingo\"\n      speakers:\n        - Guillaume Wrobel\n      event_name: \"Paris.rb Meetup June 2023\"\n      language: \"french\"\n      date: \"2023-06-06\"\n      published_at: \"2023-08-24\"\n      video_provider: \"youtube\"\n      id: \"guillaume-wrobel-parisrb-meetup-june-2023\"\n      video_id: \"1rFvYj4oBSQ\"\n      description: |-\n        Par Guillaume\n        Paris.rb Meetup Juin 2023\n        Merci à mobiskill de nous avoir accueillis.\n        https://mobiskill.fr\n\n        0:00 Intro\n        0:41 Talk\n        17:05 Questions\n\n- id: \"paris-rb-september-2023\"\n  title: \"Paris.rb Meetup September 2023\"\n  raw_title: \"Paris.rb Meetup September 2023\"\n  event_name: \"Paris.rb Meetup September 2023\"\n  date: \"2023-09-05\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-september-2023\"\n  description: \"\"\n  talks:\n    - title: 'Jurassic Stack – \"Hello, world!\" en assembleur sur Z80'\n      raw_title: 'Jurassic Stack – \"Hello, world!\" en assembleur sur Z80'\n      speakers:\n        - Ronan Limon Duparcmeur\n      event_name: \"Paris.rb Meetup September 2023\"\n      language: \"french\"\n      date: \"2023-09-05\"\n      published_at: \"2023-12-29\"\n      video_provider: \"youtube\"\n      id: \"ronan-limon-duparcmeur-parisrb-meetup-september-2023\"\n      video_id: \"79lneqiaiP0\"\n      description: |-\n        Par Ronan Limon Duparcmeur\n        Paris.rb Meetup Septembre 2023\n        Merci à RingCentral de nous avoir accueillis.\n        https://www.ringcentral.com\n\n        0:00 Intro et Talk\n        24:39 Questions\n\n        Liens :\n        https://cpcrulez.fr/coding_menu-cours_et_initiations.htm\n        https://www.youtube.com/@ChibiAkumas\n        https://www.retrovirtualmachine.org\n\n        Retrouvez Ronan Limon Duparcmeur :\n        https://ruby.social/@r3trofitted\n        https://github.com/r3trofitted\n\n    - title: \"Crypto tools in Ruby\"\n      raw_title: \"Crypto tools in Ruby\"\n      speakers:\n        - Stéphane Akkaoui\n      event_name: \"Paris.rb Meetup September 2023\"\n      language: \"french\"\n      date: \"2023-09-05\"\n      published_at: \"2023-12-29\"\n      video_provider: \"youtube\"\n      id: \"stephane-akkaoui-parisrb-meetup-september-2023\"\n      video_id: \"7ZPoV7Wiapc\"\n      description: |-\n        Par Stéphane Akkaoui\n        Paris.rb Meetup Septembre 2023\n        Merci à RingCentral de nous avoir accueillis.\n        https://www.ringcentral.com\n\n        0:00 Intro\n        0:39 Talk\n        20:42 Questions\n\n        Liens :\n        http://foreverbije.com\n\n        Retrouvez Stéphane Akkaoui :\n        https://twitter.com/meuble\n        https://linkedin.com/in/stéphane-akkaoui\n\n    - title: \"Comment on a optimisé l'update des gems vulnérables avec dependabot\"\n      raw_title: \"Comment on a optimisé l'update des gems vulnérables avec dependabot\"\n      speakers:\n        - Yoann Lecuyer\n      event_name: \"Paris.rb Meetup September 2023\"\n      language: \"french\"\n      date: \"2023-09-05\"\n      published_at: \"2023-12-29\"\n      video_provider: \"youtube\"\n      id: \"yoann-lecuyer-parisrb-meetup-september-2023\"\n      video_id: \"1r3aWmzdUY4\"\n      description: |-\n        Par Yoann Lecuyer\n        Paris.rb Meetup Septembre 2023\n        Merci à RingCentral de nous avoir accueillis.\n        https://www.ringcentral.com\n\n        0:00 Talk\n        7:49 Questions\n\n        Liens :\n        https://github.com/dependabot/dependabot-script\n\n- id: \"paris-rb-november-2023\"\n  title: \"Paris.rb Meetup November 2023\"\n  raw_title: \"Paris.rb Meetup November 2023\"\n  event_name: \"Paris.rb Meetup November 2023\"\n  date: \"2023-11-07\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-november-2023\"\n  description: \"\"\n  talks:\n    - title: \"Prepare a rails monolith for scale [English]\"\n      raw_title: \"Prepare a rails monolith for scale [English]\"\n      event_name: \"Paris.rb Meetup November 2023\"\n      language: \"english\"\n      date: \"2023-11-07\"\n      published_at: \"2023-12-31\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"prepare-a-rails-monolith-for-scale-english-parisrb-meetup-november-2023\"\n      video_id: \"u-HDlDnFTBw\"\n      description: |-\n        Par Pierre & Samy\n        Paris.rb Meetup Novembre 2023\n        Merci à Hivebrite de nous avoir accueillis.\n        https://hivebrite.io\n        https://hivebrite.io/careers\n\n        0:00 Intro\n        0:14 Talk\n        18:35 Questions\n\n        Liens :\n        - Railway Oriented Programming - https://fsharpforfunandprofit.com/rop/\n        - dry-monads - https://dry-rb.org/gems/dry-monads/1.6/\n        - The Citadel Architecture - https://m.signalvnoise.com/the-majestic-monolith-can-become-the-citadel/\n        - DTO - https://martinfowler.com/eaaCatalog/dataTransferObject.html\n        - Under Deconstruction: The State of Shopify’s Monolith - https://shopify.engineering/shopify-monolith\n\n        Retrouvez Pierre & Samy :\n        - https://www.linkedin.com/in/pierrejolivet\n        - https://twitter.com/illiatdesdindes\n\n    - title: \"Creating a 2D game with Ruby [English]\"\n      raw_title: \"Creating a 2D game with Ruby [English]\"\n      event_name: \"Paris.rb Meetup November 2023\"\n      language: \"english\"\n      date: \"2023-11-07\"\n      published_at: \"2023-12-30\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"creating-a-2d-game-with-ruby-english-parisrb-meetup-november-2023\"\n      video_id: \"KwLzsWP1SAo\"\n      description: |-\n        Par Fabien\n        Paris.rb Meetup Novembre 2023\n        Merci à Hivebrite de nous avoir accueillis.\n        https://hivebrite.io\n\n        0:00 Intro\n        0:19 Talk\n        7:34 Questions\n\n        Liens :\n        Slides - https://slides.com/fabienchaynes/2d-game-rub\n        Gosu gem - https://github.com/gosu/gosu\n        Gosu Ruby tutorial - https://github.com/gosu/gosu/wiki/Ruby-Tutorial\n        Gosu rubydoc - https://www.rubydoc.info/gems/gosu/index\n\n        Retrouvez Fabien :\n        https://github.com/FabienChaynes\n        https://www.linkedin.com/in/fabienchaynes\n\n    - title: \"order_cop: Protect you from random UI [English]\"\n      raw_title: \"order_cop: Protect you from random UI [English]\"\n      speakers:\n        - Gauthier Monserand\n      event_name: \"Paris.rb Meetup November 2023\"\n      language: \"english\"\n      date: \"2023-11-07\"\n      published_at: \"2023-12-30\"\n      video_provider: \"youtube\"\n      id: \"gauthier-monserand-parisrb-meetup-november-2023\"\n      video_id: \"abqLyhuejBM\"\n      description: |-\n        Par Gauthier\n        Paris.rb Meetup Novembre 2023\n        Merci à Hivebrite de nous avoir accueillis.\n        https://hivebrite.io\n\n        Liens :\n        https://github.com/squadracer/order_cop\n\n        Retrouvez Gauthier :\n        https://twitch.tv/squadracer\n        https://twitter.com/squadracer\n        https://www.linkedin.com/company/squadracer\n\n- id: \"paris-rb-december-2023\"\n  title: \"Paris.rb Meetup December 2023\"\n  raw_title: \"Paris.rb Meetup December 2023\"\n  event_name: \"Paris.rb Meetup December 2023\"\n  date: \"2023-12-05\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-december-2023\"\n  description: \"\"\n  talks:\n    - title: \"L'art de maintenir son application\"\n      raw_title: \"L'art de maintenir son application\"\n      speakers:\n        - Stéphane Hanser\n      event_name: \"Paris.rb Meetup December 2023\"\n      language: \"french\"\n      date: \"2023-12-05\"\n      published_at: \"2024-01-27\"\n      video_provider: \"youtube\"\n      id: \"stephane-hanser-parisrb-meetup-december-2023\"\n      video_id: \"JyGZC56_dyE\"\n      description: |-\n        Par Stéphane\n        Paris.rb Meetup Décembre 2023\n        Merci à Mobiskill de nous avoir accueillis.\n        https://mobiskill.fr\n\n        0:00 Intro\n        3:56 Talk\n        31:21 Questions\n\n        Liens :\n        https://captive.notion.site/Investir-dans-l-invisible-l-art-de-maintenir-son-application-Rails-04472d90f1a24494a4a2c92a75ee2167?pvs=4\n\n        Retrouvez Stéphane :\n        https://www.linkedin.com/in/stephane-hanser-developpeur/\n        https://captive.fr/\n        https://www.lesvieuxpotsdelatech.fr/\n\n    - title: \"La nouvelle stack front de Rails (nobuild)\"\n      raw_title: \"La nouvelle stack front de Rails (nobuild)\"\n      speakers:\n        - Yoann Lecuyer\n      event_name: \"Paris.rb Meetup December 2023\"\n      language: \"french\"\n      date: \"2023-12-05\"\n      published_at: \"2024-01-14\"\n      video_provider: \"youtube\"\n      id: \"yoann-lecuyer-parisrb-meetup-december-2023\"\n      video_id: \"x9jWjF3yPLk\"\n      description: |-\n        Par Yoann Lecuyer\n        Paris.rb Meetup Décembre 2023\n        Merci à Mobiskill de nous avoir accueillis.\n        https://mobiskill.fr\n\n        0:00 Talk\n        12:32 Questions\n\n        Liens :\n        CSS variables: https://developer.chrome.com/blog/css-variables-why-should-you-care\n        CSS nesting: https://developer.chrome.com/docs/css-ui/css-nesting\n        What the heck are CJS, AMD, UMD, and ESM in Javascript?: https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm\n        Propshaft: https://github.com/rails/propshaft\n        js-bundling: https://github.com/rails/jsbundling-rails\n        css-bundling: https://github.com/rails/cssbundling-rails\n        hotwire: https://hotwired.dev/\n        turbo: https://turbo.hotwired.dev/handbook/introduction\n        stimulus: https://stimulus.hotwired.dev/handbook/origin\n        convert js packages to esm on the fly: https://esm.sh/\n\n        Retrouvez Yoann Lecuyer :\n        https://www.linkedin.com/in/ylecuyer/\n\n- id: \"paris-rb-january-2024\"\n  title: \"Paris.rb Meetup January 2024\"\n  raw_title: \"Paris.rb Meetup January 2024\"\n  event_name: \"Paris.rb Meetup January 2024\"\n  date: \"2024-01-02\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-january-2024\"\n  description: \"\"\n  talks:\n    - title: \"Le CTO à 2€\"\n      raw_title: \"Le CTO à 2€\"\n      event_name: \"Paris.rb Meetup January 2024\"\n      language: \"french\"\n      date: \"2024-01-02\"\n      published_at: \"2024-01-28\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"le-cto-a-2-parisrb-meetup-january-2024\"\n      video_id: \"m8iY5Udl_zs\"\n      description: |-\n        Par Sylvain\n        Paris.rb Meetup Janvier 2024\n        Merci à Memory de nous avoir accueillis.\n        https://www.inthememory.com\n\n        0:00 Intro\n        0:43 Talk\n        32:56 Questions\n\n        Liens :\n        http://maitre-du-monde.fr/talks/2e_tech_lead.html\n\n        Retrouvez Sylvain :\n        https://mamot.fr/@abelar_s\n\n    - title: \"Résoudre les N+1 Queries\"\n      raw_title: \"Résoudre les N+1 Queries\"\n      speakers:\n        - Clément Prod'homme\n      event_name: \"Paris.rb Meetup January 2024\"\n      language: \"french\"\n      date: \"2024-01-02\"\n      published_at: \"2024-01-28\"\n      video_provider: \"youtube\"\n      id: \"clement-prod-homme-parisrb-meetup-january-2024\"\n      video_id: \"Y7tXtkfrBDI\"\n      description: |-\n        Par Clément Prod'homme\n        Paris.rb Meetup Janvier 2024\n        Merci à Memory de nous avoir accueillis.\n        https://www.inthememory.com\n\n        0:00 Talk\n        11:56 Questions\n\n        Liens :\n        Les liens utiles : https://captive.notion.site/R-soudre-les-N-1-Query-liens-utiles-60c57f4d5ec247368f8caba00726ad28?pvs=4\n        (qui comprend le standard, notre Tech Radar, les slides)\n\n        Retrouvez Clément Prod'homme :\n        Linkedin : https://www.linkedin.com/in/clementprodhomme/\n\n    - title: \"Flash message et UX\"\n      raw_title: \"Flash message et UX\"\n      event_name: \"Paris.rb Meetup January 2024\"\n      language: \"french\"\n      date: \"2024-01-02\"\n      published_at: \"2024-01-28\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"flash-message-et-ux-parisrb-meetup-january-2024\"\n      video_id: \"ToUDekCKdX0\"\n      description: |-\n        Par David\n        Paris.rb Meetup Janvier 2024\n        Merci à Memory de nous avoir accueillis.\n        https://www.inthememory.com\n\n        Liens :\n        Hiérarchisation du rendu des messages : https://www.thirdwunder.com/blog/ui-ux-design-alerts-notifications/\n        Documentation officielle sur les messages flash : https://guides.rubyonrails.org/action_controller_overview.html#the-flash\n        Accessibilité des messages toasts : https://getbootstrap.com/docs/5.3/components/toasts/#accessibility\n        Accessibilité des formulaires : https://www.smashingmagazine.com/2023/02/guide-accessible-form-validation/\n\n        Retrouvez David :\n        https://twitter.com/bdavidxyz\n        https://www.linkedin.com/in/bdavidxyz/\n        https://bootrails.com\n\n- id: \"paris-rb-february-2024\"\n  title: \"Paris.rb Meetup February 2024\"\n  raw_title: \"Paris.rb Meetup February 2024\"\n  event_name: \"Paris.rb Meetup February 2024\"\n  date: \"2024-02-06\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-february-2024\"\n  description: \"\"\n  talks:\n    - title: \"Live Coding en TDD\"\n      raw_title: \"Live Coding en TDD\"\n      event_name: \"Paris.rb Meetup February 2024\"\n      language: \"french\"\n      date: \"2024-02-06\"\n      published_at: \"2024-03-09\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"live-coding-en-tdd-parisrb-meetup-february-2024\"\n      video_id: \"kqpHL_V1pUU\"\n      description: |-\n        Par Marion et Stéphane\n        Paris.rb Meetup Février 2024\n        Merci à Captive de nous avoir accueillis.\n        https://www.captive.fr\n\n        0:00 Talk\n        20:15 Questions\n\n        Retrouvez Marion et Stéphane :\n        https://www.linkedin.com/in/marion-velard/\n        https://www.linkedin.com/in/stephane-hanser-developpeur/\n\n    - title: \"1,2,3 Turbo\"\n      raw_title: \"1,2,3 Turbo\"\n      speakers:\n        - Adrien Poly\n      event_name: \"Paris.rb Meetup February 2024\"\n      language: \"french\"\n      date: \"2024-02-06\"\n      published_at: \"2024-03-09\"\n      video_provider: \"youtube\"\n      id: \"adrien-poly-parisrb-meetup-february-2024\"\n      video_id: \"DdIrdBI7AK8\"\n      description: |-\n        Par Adrien\n        Paris.rb Meetup Février 2024\n        Merci à Captive de nous avoir accueillis.\n        https://www.captive.fr\n\n        0:00 Intro\n        3:09 Talk\n        23:18 Questions\n\n        Liens :\n        Documentation : https://turbo.hotwired.dev/\n        Turbo morph demo app : https://dev.37signals.com/page-refreshes-with-morphing-demo/\n        Tuto Hotwire : https://www.hotrails.dev/\n        Newsletter de Bhumi : https://buttondown.email/bhumi/\n        Weekly Hotwire newsletter by Marco : https://hotwire.io/newsletter\n\n        Retrouvez Adrien :\n        https://adrienpoly.com/\n        https://twitter.com/adrienpoly\n        https://fr.linkedin.com/in/adrienpoly\n\n- id: \"paris-rb-march-2024\"\n  title: \"Paris.rb Meetup March 2024\"\n  raw_title: \"Paris.rb Meetup March 2024\"\n  event_name: \"Paris.rb Meetup March 2024\"\n  date: \"2024-03-05\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-march-2024\"\n  description: \"\"\n  talks:\n    - title: \"Devenir proactifs grace à l'observabilité\"\n      raw_title: \"Devenir proactifs grace à l'observabilité\"\n      event_name: \"Paris.rb Meetup March 2024\"\n      language: \"french\"\n      date: \"2024-03-05\"\n      published_at: \"2024-05-06\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"devenir-proactifs-grace-a-l-observabilite-parisrb-meetup-march-2024\"\n      video_id: \"f7U7HLAgElE\"\n      description: |-\n        Par Johann\n        Paris.rb Meetup Mars 2024\n        Merci à Code Busters de nous avoir accueillis.\n        https://codebusters.fr\n\n        0:00 Talk\n        25:43 Questions\n\n        Retrouvez Johann :\n        https://www.linkedin.com/in/johann-wilfrid-calixte/\n\n    - title: \"Faciliter les revues de code avec Rubocop\"\n      raw_title: \"Faciliter les revues de code avec Rubocop\"\n      speakers:\n        - Clément Prod'homme\n      event_name: \"Paris.rb Meetup March 2024\"\n      language: \"french\"\n      date: \"2024-03-05\"\n      published_at: \"2024-05-06\"\n      video_provider: \"youtube\"\n      id: \"clement-prod-homme-parisrb-meetup-march-2024\"\n      video_id: \"Il1DI9mgdvI\"\n      description: |-\n        Par Clément Prod'homme\n        Paris.rb Meetup Mars 2024\n        Merci à Code Busters de nous avoir accueillis.\n        https://codebusters.fr\n\n        0:00 Talk\n        10:20 Questions\n\n        Liens :\n        - *Le repo de la gem  :* https://github.com/Captive-Studio/rubocop-config\n        - *La documentation de la gem :* https://captive-studio.github.io/rubocop-config/\n        - *Les slides :* https://www.canva.com/design/DAF-okB64a4/AZmkDdBo9BtwuRvr26JGnw/edit?utm_content=DAF-okB64a4&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton\n\n        Retrouvez Clément Prod'homme :\n        Linkedin : https://www.linkedin.com/in/clementprodhomme/\n\n    - title: \"Debugger ses tests grace aux enregistrements d'écran\"\n      raw_title: \"Debugger ses tests grace aux enregistrements d'écran\"\n      speakers:\n        - Dorian Lupu\n      event_name: \"Paris.rb Meetup March 2024\"\n      language: \"french\"\n      date: \"2024-03-05\"\n      published_at: \"2024-05-06\"\n      video_provider: \"youtube\"\n      id: \"dorian-lupu-parisrb-meetup-march-2024\"\n      video_id: \"1Puywv2b-I8\"\n      description: |-\n        Par Dorian @Botyglot\n        Paris.rb Meetup Mars 2024\n        Merci à Code Busters de nous avoir accueillis.\n        https://codebusters.fr\n\n        Liens :\n        https://github.com/kapoorlakshya/screen-recorder\n        https://tech.botyglot.com/speed-up-debugging-of-feature-tests-using-screen-recordings\n        https://docs.google.com/presentation/d/1GXsxDVoFkHnCrQcRQ_CIaz9CE58Jfdbj5cVjn20XlKY/edit#slide=id.p\n\n        Retrouvez Dorian @Botyglot :\n        https://www.linkedin.com/in/dorianlupu/\n        https://ruby.social/@DorianLupu\n\n- id: \"paris-rb-april-2024\"\n  title: \"Paris.rb Meetup April 2024\"\n  raw_title: \"Paris.rb Meetup April 2024\"\n  event_name: \"Paris.rb Meetup April 2024\"\n  date: \"2024-04-02\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-april-2024\"\n  description: \"\"\n  talks:\n    - title: \"Opinionated Dependabot Distribution\"\n      raw_title: \"Opinionated Dependabot Distribution\"\n      speakers:\n        - Yoann Lecuyer\n      event_name: \"Paris.rb Meetup April 2024\"\n      language: \"french\"\n      date: \"2024-04-02\"\n      published_at: \"2024-11-03\"\n      video_provider: \"youtube\"\n      id: \"yoann-lecuyer-parisrb-meetup-april-2024\"\n      video_id: \"fDMIhhwqDg0\"\n      description: |-\n        Par Yoann Lecuyer\n        Paris.rb Meetup Avril 2024\n        Merci à Cardiologs de nous avoir accueillis.\n        https://cardiologs.com\n\n        0:00 Talk\n        4:20 Questions\n\n        Retrouvez Yoann Lecuyer :\n        https://www.linkedin.com/in/ylecuyer/\n\n    - title: \"Cadrages techniques, retours d'XP\"\n      raw_title: \"Cadrages techniques, retours d'XP\"\n      speakers:\n        - Pierre-Emmanuel Daigre\n      event_name: \"Paris.rb Meetup April 2024\"\n      language: \"french\"\n      date: \"2024-04-02\"\n      published_at: \"2024-11-03\"\n      video_provider: \"youtube\"\n      id: \"pierre-emmanuel-daigre-parisrb-meetup-april-2024\"\n      video_id: \"ESmWVeCGKuc\"\n      description: |-\n        Par Pierre-Emmanuel Daigre\n        Paris.rb Meetup Avril 2024\n        Merci à Cardiologs de nous avoir accueillis.\n        https://cardiologs.com\n\n        0:00 Intro\n        2:52 Talk\n        27:47 Questions\n\n        Liens :\n        https://medium.com/doctolib/the-two-kinds-of-tech-scoping-ab8d1915ec5a\n\n        Retrouvez Pierre-Emmanuel Daigre :\n        https://www.linkedin.com/in/pedaigre/\n        https://github.com/ioups\n\n    - title: \"Value Objects\"\n      raw_title: \"Value Objects\"\n      speakers:\n        - Rémy Hannequin\n      event_name: \"Paris.rb Meetup April 2024\"\n      language: \"french\"\n      date: \"2024-04-02\"\n      published_at: \"2024-11-03\"\n      video_provider: \"youtube\"\n      id: \"remy-hannequin-parisrb-meetup-april-2024\"\n      video_id: \"QyGnBrtopCo\"\n      description: |-\n        Par Rémy Hannequin\n        Paris.rb Meetup Avril 2024\n        Merci à Cardiologs de nous avoir accueillis.\n        https://cardiologs.com\n\n        0:00 Intro\n        1:30 Talk\n        15:25 Questions\n\n        Liens :\n        https://martinfowler.com/bliki/ValueObject.html\n        https://thoughtbot.com/blog/value-object-semantics-in-ruby\n        https://thoughtbot.com/upcase/videos/value-objects\n\n        Retrouvez Rémy Hannequin :\n        https://github.com/rhannequin\n        https://twitter.com/rhannequin\n        https://ruby.social/@rhannequin\n        https://www.linkedin.com/in/rhannequin/\n\n- id: \"paris-rb-may-2024\"\n  title: \"Paris.rb Meetup May 2024\"\n  raw_title: \"Paris.rb Meetup May 2024\"\n  event_name: \"Paris.rb Meetup May 2024\"\n  date: \"2024-05-07\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-may-2024\"\n  description: \"\"\n  talks:\n    - title: \"Rustifying Ruby - A Journey of Elegant Language Fusion\"\n      raw_title: \"Rustifying Ruby - A Journey of Elegant Language Fusion\"\n      speakers:\n        - Jean-Paul Bonnetouche\n      event_name: \"Paris.rb Meetup May 2024\"\n      language: \"french\"\n      date: \"2024-05-07\"\n      published_at: \"2024-11-07\"\n      video_provider: \"youtube\"\n      id: \"jean-paul-bonnetouche-parisrb-meetup-may-2024\"\n      video_id: \"HjvsFqqESoc\"\n      description: |-\n        Par Jean-Paul Bonnetouche\n        Paris.rb Meetup Mai 2024\n        Merci à Wecasa de nous avoir accueillis.\n        https://www.wecasa.fr\n\n        0:00 Intro\n        01:35 Enums\n        03:50 Enums in Rust\n        06:36 What about Ruby?\n        9:31 Build a Rust Enum in Modern Ruby\n        18:17 The Expression Problem\n        19:55 The Result Enum\n        24:50 Questions\n\n        Liens :\n        https://github.com/goodtouch/rustd\n\n        Retrouvez Jean-Paul Bonnetouche :\n        * https://twitter.com/_jpb\n        * https://www.linkedin.com/in/jean-paul-bonnetouche/\n        * https://www.malt.fr/profile/madvoid\n\n    - title: \"Dry-Monads\"\n      raw_title: \"Dry-Monads\"\n      event_name: \"Paris.rb Meetup May 2024\"\n      language: \"french\"\n      date: \"2024-05-07\"\n      published_at: \"2024-11-07\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"dry-monads-parisrb-meetup-may-2024\"\n      video_id: \"oazdZLJse2Y\"\n      description: |-\n        Par Antoine & JustTheV\n        Paris.rb Meetup Mai 2024\n        Merci à Wecasa de nous avoir accueillis.\n        https://www.wecasa.fr\n\n        0:00 Intro\n        01:07 What is a Monad?\n        07:09 Pattern Matching\n        08:05 Chain of Responsibility\n        09:38 Impact @ WeCasa\n        13:07 Questions\n\n        Liens :\n        Documentation Dry-Monads : https://dry-rb.org/gems/dry-monads/1.3/\n\n        Retrouvez Antoine & JustTheV :\n        Antoine : https://www.linkedin.com/in/antoine-braconnier1991/\n        JustTheV : https://www.linkedin.com/in/hugo-vast/\n\n        Offres d'emplois Wecasa : https://www.welcometothejungle.com/fr/companies/wecasa/jobs\n\n- id: \"paris-rb-june-2024\"\n  title: \"Paris.rb Meetup June 2024\"\n  raw_title: \"Paris.rb Meetup June 2024\"\n  event_name: \"Paris.rb Meetup June 2024\"\n  date: \"2024-06-04\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-june-2024\"\n  description: \"\"\n  talks:\n    - title: \"Scaling our Ruby on Rails monolith using Packwerk\"\n      raw_title: \"Scaling our Ruby on Rails monolith using Packwerk\"\n      event_name: \"Paris.rb Meetup June 2024\"\n      language: \"french\"\n      date: \"2024-06-04\"\n      published_at: \"2024-11-14\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"scaling-our-ruby-on-rails-monolith-using-packwerk-parisrb-meetup-june-2024\"\n      video_id: \"YTC4uiRa_co\"\n      description: |-\n        Par François\n        Paris.rb Meetup Juin 2024\n        Merci à Pennylane de nous avoir accueillis.\n        https://www.pennylane.com\n\n        0:00 Intro\n        01:09 Le monolithe à Pennylane\n        03:52 Les problèmes de scale avec notre monolithe\n        07:49 Les solutions envisagées\n        10:36 Packwerk\n        14:46 Un écosystème et des extensions\n        17:30 Notre retour d'expérience avec Packwerk\n        25:31 Q&A\n\n        Liens :\n        - Packwerk https://github.com/Shopify/packwerk/\n        - Ruby at Scale https://github.com/rubyatscale\n\n        Retrouvez François :\n        - www.linkedin.com/in/fpradel\n\n    - title: \"PostgreSQL: it's a trap\"\n      raw_title: \"PostgreSQL: it's a trap\"\n      speakers:\n        - Benoit Tigeot\n      event_name: \"Paris.rb Meetup June 2024\"\n      language: \"french\"\n      date: \"2024-06-04\"\n      published_at: \"2024-11-14\"\n      video_provider: \"youtube\"\n      id: \"benoit-tigeot-parisrb-meetup-june-2024\"\n      video_id: \"m-7qkt0EMnY\"\n      description: |-\n        Par Benoit Tigeot\n        Paris.rb Meetup Juin 2024\n        Merci à Pennylane de nous avoir accueillis.\n        https://www.pennylane.com\n\n        00:00 PostgreSQL It's a trap\n        01:21 WHERE... WHERE...\n        07:52 Index creation\n        08:50 Prepared statements and ActiveRecord less used operators\n        15:59 Prepared statements and query tags\n        18:17 Multiple IN / ANY operators\n        23:56 (Hot updates)\n\n        Liens :\n        https://docs.google.com/presentation/d/1Oiy6fOSl0773HOeTFhGaWuyQcQqvczyS0Rvdo8Tqn0A/edit?usp=sharing\n\n        Retrouvez Benoit Tigeot :\n        https://ruby.social/@benoit\n\n- id: \"paris-rb-october-2024\"\n  title: \"Paris.rb Meetup October 2024\"\n  raw_title: \"Paris.rb Meetup October 2024\"\n  event_name: \"Paris.rb Meetup October 2024\"\n  date: \"2024-10-01\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-october-2024\"\n  description: \"\"\n  talks:\n    - title: \"Hexagonal On Rails\"\n      raw_title: \"Hexagonal On Rails\"\n      event_name: \"Paris.rb Meetup October 2024\"\n      language: \"french\"\n      date: \"2024-10-01\"\n      published_at: \"2024-11-14\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"hexagonal-on-rails-parisrb-meetup-october-2024\"\n      video_id: \"CIdg1oFIwe8\"\n      description: |-\n        Par Johann\n        Paris.rb Meetup Octobre 2024\n        Merci à WeMoms de nous avoir accueillis.\n        https://www.wemoms.com\n\n        0:00 Talk\n        25:34 Questions\n\n        Il y a eu quelques problèmes de caméra. Merci pour votre compréhension.\n\n        Retrouvez Johann :\n        https://www.linkedin.com/in/johann-wilfrid-calixte\n\n    - title: \"Why You (really) Don't Need SPA\"\n      raw_title: \"Why You (really) Don't Need SPA\"\n      speakers:\n        - Guillaume Briday\n      event_name: \"Paris.rb Meetup October 2024\"\n      language: \"french\"\n      date: \"2024-10-01\"\n      published_at: \"2024-11-14\"\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-parisrb-meetup-october-2024\"\n      video_id: \"GQ61X5RV3aE\"\n      description: |-\n        Par Guillaume Briday\n        Paris.rb Meetup Octobre 2024\n        Merci à WeMoms de nous avoir accueillis.\n        https://www.wemoms.com\n\n        0:00 Intro\n        0:49 Talk\n        30:06 Questions\n\n        Liens :\n        https://guillaumebriday.fr\n\n        Retrouvez Guillaume Briday :\n        https://guillaumebriday.fr/links\n\n- id: \"paris-rb-november-2024\"\n  title: \"Paris.rb Meetup November 2024\"\n  raw_title: \"Paris.rb Meetup November 2024\"\n  event_name: \"Paris.rb Meetup November 2024\"\n  date: \"2024-11-05\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-november-2024\"\n  description: |-\n    Bonjour et bienvenue à toutes et à tous dans notre rencontre mensuelle autour du Ruby, Rails, web, tech, humains...\n\n    voici la liste des présentations (qui peut toujours évoluer)\n\n    nous demandons à chacun-e de suivre la Contributor Covenant (guide d'éthique et déontologie)\n\n    nos événements sont le plus souvent diffusés sur Twitch et le replay sur YouTube : https://youtube.com/@paris-rb et https://twitch.tv/paris_rb\n\n    pour chercher à embaucher, pour proposer un sujet : venez sur le Slack ou contactez les organisateur-ice-s\n\n    c'est avant tout le meetup d'une communauté, nous sommes là pour échanger, discuter, avancer ensemble ! Nos outils principaux sont ce meetup et le Slack https://join.slack.com/t/parisrb/shared_invite/zt-1l1u1gpp1-Qrq2_6LqSSpeG0I2TKv_lA\n\n    Un grand merci aux entreprises qui nous accueillent et nous aident. Pour nous sponsoriser vous aussi, contactez l'organisation.\n\n    À bientôt !\n\n    https://www.meetup.com/paris_rb/events/303637189\n  talks:\n    - title: \"Hotwire Native: Turn Your Rails App into a Mobile App\"\n      raw_title: \"Hotwire Native: Turn Your Rails App into a Mobile App\"\n      speakers:\n        - Yaroslav Shmarov\n      event_name: \"Paris.rb Meetup November 2024\"\n      language: \"english\"\n      date: \"2024-11-05\"\n      published_at: \"2024-11-23\"\n      video_provider: \"youtube\"\n      id: \"yaroslav-shmarov-parisrb-meetup-november-2024\"\n      video_id: \"25vqzypzTkQ\"\n      description: |-\n        Talk en anglais.\n\n        Par Yaroslav Shmarov\n        Paris.rb Meetup Novembre 2024\n        Merci à Algolia de nous avoir accueillis.\n        https://www.algolia.com\n\n        00:00 Intro\n        01:18 Turbo Native + Strada = Hotwire Native\n        04:16 Prepare your Rails app for Hotwire Native\n        15:22 App Review\n        15:57 Future\n        18:07 Conclusion\n        20:00 Q&A\n\n        Liens:\n        https://superails.com/playlists/turbo-native\n\n        Retrouvez Yaroslav Shmarov:\n        https://x.com/yarotheslav\n\n    - title: \"Kamal 2: Pourquoi Et Comment Quitter Le Cloud?\"\n      raw_title: \"Kamal 2: Pourquoi Et Comment Quitter Le Cloud?\"\n      speakers:\n        - Guillaume Briday\n      event_name: \"Paris.rb Meetup November 2024\"\n      language: \"french\"\n      date: \"2024-11-05\"\n      published_at: \"2024-11-23\"\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-parisrb-meetup-november-2024\"\n      video_id: \"3-sS_F6Ds2o\"\n      description: |-\n        Par Guillaume Briday\n        Paris.rb Meetup Novembre 2024\n        Merci à Algolia de nous avoir accueillis.\n        https://www.algolia.com\n\n        00:00 Intro\n        02:18 IaaS vs PaaS\n        06:09 Deploying on a IaaS\n        11:40 Hardening your server\n        16:21 What about the scalability?\n        19:46 Introducing Kamal 2\n        22:25 Conclusion\n        24:31 Q&A\n\n        Liens:\n        https://guillaumebriday.fr\n\n        Retrouvez Guillaume Briday:\n        https://guillaumebriday.fr/links\n\n    - title: \"Performances Active Record - Un Menu En 3 Étapes\"\n      raw_title: \"Performances Active Record - Un Menu En 3 Étapes\"\n      speakers:\n        - Gauthier Monserand\n      event_name: \"Paris.rb Meetup November 2024\"\n      language: \"french\"\n      date: \"2024-11-05\"\n      published_at: \"2024-11-23\"\n      video_provider: \"youtube\"\n      id: \"gauthier-monserand-parisrb-meetup-november-2024\"\n      video_id: \"Tu3MDbKviL4\"\n      description: |-\n        Par Gauthier\n        Paris.rb Meetup Novembre 2024\n        Merci à Algolia de nous avoir accueillis.\n        https://www.algolia.com\n\n        00:00 Intro\n        00:38 Mise en bouche\n        01:40 Entrée\n        04:20 Plat\n        09:17 Dessert\n        11:42 Q&A\n\n        Liens:\n        Le repo de code du talk — https://github.com/simkim/active-record-perf\n        Faut il un index pour un order by — https://www.postgresql.org/docs/current/indexes-ordering.html#INDEXES-ORDERING\n        PG Hero — https://github.com/ankane/pghero\n\n        Retrouvez Gauthier:\n        https://www.squadracer.com\n        https://www.linkedin.com/company/squadracer/\n      additional_resources:\n        - name: \"Le repo de code du talk\"\n          type: \"repo\"\n          url: \"https://github.com/simkim/active-record-perf\"\n\n        - name: \"Faut il un index pour un order by\"\n          type: \"documentation\"\n          url: \"https://www.postgresql.org/docs/current/indexes-ordering.html#INDEXES-ORDERING\"\n\n        - name: \"ankane/pghero\"\n          type: \"repo\"\n          url: \"https://github.com/ankane/pghero\"\n\n- id: \"paris-rb-december-2024\"\n  title: \"Paris.rb Meetup December 2024\"\n  raw_title: \"Paris.rb Meetup December 2024\"\n  event_name: \"Paris.rb Meetup December 2024\"\n  date: \"2024-12-03\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-december-2024\"\n  description: |-\n    Bonjour et bienvenue à toutes et à tous dans notre rencontre mensuelle autour du Ruby, Rails, web, tech, humains...\n\n    voici la liste des présentations (qui peut toujours évoluer)\n\n    nous demandons à chacun-e de suivre la Contributor Covenant (guide d'éthique et déontologie)\n\n    nos événements sont le plus souvent diffusés sur Twitch et le replay sur YouTube : https://youtube.com/@paris-rb et https://twitch.tv/paris_rb\n\n    pour chercher à embaucher, pour proposer un sujet : venez sur le Slack ou contactez les organisateur-ice-s\n\n    c'est avant tout le meetup d'une communauté, nous sommes là pour échanger, discuter, avancer ensemble ! Nos outils principaux sont ce meetup et le Slack https://join.slack.com/t/parisrb/shared_invite/zt-1l1u1gpp1-Qrq2_6LqSSpeG0I2TKv_lA\n\n    Un grand merci aux entreprises qui nous accueillent et nous aident. Pour nous sponsoriser vous aussi, contactez l'organisation.\n\n    À bientôt !\n\n    https://www.meetup.com/paris_rb/events/303637325\n  talks:\n    - title: \"Rails: The Missing Coverage (aka Stimulus Coverage OOTB)\"\n      raw_title: \"Rails: The Missing Coverage (aka Stimulus Coverage OOTB)\"\n      speakers:\n        - Yoann Lecuyer\n      event_name: \"Paris.rb Meetup December 2024\"\n      language: \"french\"\n      date: \"2024-12-03\"\n      published_at: \"2025-05-04\"\n      video_provider: \"youtube\"\n      id: \"yoann-lecuyer-parisrb-meetup-december-2024\"\n      video_id: \"3ejFewAZhWQ\"\n      slides_url: \"https://docs.google.com/presentation/d/1h21dC51zFCmZSuaQrqhtIRY5bBcrneBLLr5DDbwwNmM/view\"\n      description: |-\n        Par Yoann Lecuyer\n\n        Paris.rb Meetup Décembre 2024\n        Merci à Epicery de nous avoir accueillis.\n\n        Liens :\n        https://github.com/ylecuyer/propshaft-js-coverage\n        https://github.com/ylecuyer/sprockets-js-coverage\n      additional_resources:\n        - name: \"ylecuyer/propshaft-js-coverage\"\n          type: \"repo\"\n          url: \"https://github.com/ylecuyer/propshaft-js-coverage\"\n        - name: \"ylecuyer/sprockets-js-coverage\"\n          type: \"repo\"\n          url: \"https://github.com/ylecuyer/sprockets-js-coverage\"\n\n    - title: \"Ajoutez Des Badges Dynamiques À Vos Pull Requests Et Gagnez En Productivité\"\n      raw_title: \"Ajoutez Des Badges Dynamiques À Vos Pull Requests Et Gagnez En Productivité\"\n      speakers:\n        - Christopher Saez\n      event_name: \"Paris.rb Meetup December 2024\"\n      language: \"french\"\n      date: \"2024-12-03\"\n      published_at: \"2025-05-04\"\n      video_provider: \"youtube\"\n      id: \"christopher-saez-parisrb-meetup-december-2024\"\n      video_id: \"YVsJg7Uvk5A\"\n      slides_url: \"https://www.slideshare.net/slideshow/add-dynamic-badges-into-your-pull-request-and-increase-your-productivity/273826082\"\n      description: |-\n        Par Christopher\n        Paris.rb Meetup Décembre 2024\n        Merci à Epicery de nous avoir accueillis.\n\n        0:00 Intro\n        1:22 Talk\n        26:00 Questions\n\n        Retrouvez Christopher :\n        https://www.linkedin.com/in/saezchristopher\n        https://medium.com/@SaezChristopher\n      additional_resources:\n        - name: \"Blog Post\"\n          type: \"blog\"\n          url: \"https://medium.com/@SaezChristopher\"\n\n- id: \"paris-rb-january-2025\"\n  title: \"Paris.rb Meetup January 2025\"\n  raw_title: \"Paris.rb Meetup January 2025\"\n  event_name: \"Paris.rb Meetup January 2025\"\n  date: \"2025-01-07\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-january-2025\"\n  description: |-\n    Bonjour et bienvenue à toutes et à tous dans notre rencontre mensuelle autour du Ruby, Rails, web, tech, humains...\n\n    voici la liste des présentations (qui peut toujours évoluer)\n\n    nous demandons à chacun-e de suivre la Contributor Covenant (guide d'éthique et déontologie)\n\n    nos événements sont le plus souvent diffusés sur Twitch et le replay sur YouTube : https://youtube.com/@paris-rb et https://twitch.tv/paris_rb\n\n    pour chercher à embaucher, pour proposer un sujet : venez sur le Slack ou contactez les organisateur-ice-s\n\n    c'est avant tout le meetup d'une communauté, nous sommes là pour échanger, discuter, avancer ensemble ! Nos outils principaux sont ce meetup et le Slack https://join.slack.com/t/parisrb/shared_invite/zt-1l1u1gpp1-Qrq2_6LqSSpeG0I2TKv_lA\n\n    Un grand merci aux entreprises qui nous accueillent et nous aident. Pour nous sponsoriser vous aussi, contactez l'organisation.\n\n    À bientôt !\n\n    https://www.meetup.com/paris_rb/events/304758193\n  talks:\n    - title: \"Scalability 101\"\n      raw_title: \"Scalability 101\"\n      speakers:\n        - Hugo Vast\n      event_name: \"Paris.rb Meetup January 2025\"\n      language: \"french\"\n      date: \"2025-01-07\"\n      published_at: \"2025-06-04\"\n      video_provider: \"youtube\"\n      id: \"hugo-vast-parisrb-meetup-january-2025\"\n      video_id: \"c4_2WswMq38\"\n      slides_url: \"https://docs.google.com/presentation/d/18CvWZrdattHoq6GmoAOnvMmhF7CLVimBcE817XwlDeo/edit?slide=id.p#slide=id.p\"\n      description: |-\n        Par V\n        Paris.rb Meetup Janvier 2025\n        Merci à Simplébo de nous avoir accueillis.\n        https://www.simplebo.fr\n\n        Liens :\n        Lien des slides : https://docs.google.com/presentation/d/18CvWZrdattHoq6GmoAOnvMmhF7CLVimBcE817XwlDeo/edit?slide=id.p#slide=id.p\n\n        Retrouvez V :\n        LinkedIn : https://www.linkedin.com/in/hugo-vast/\n        Github : https://github.com/just-the-v\n\n    - title: \"Rails 8: Multi-db avec Solid Queue, Solid Cache et Kamal\"\n      raw_title: \"Rails 8: Multi-db avec Solid Queue, Solid Cache et Kamal\"\n      speakers:\n        - Guillaume Briday\n      event_name: \"Paris.rb Meetup January 2025\"\n      language: \"french\"\n      date: \"2025-01-07\"\n      published_at: \"2025-06-04\"\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-parisrb-meetup-january-2025\"\n      video_id: \"Qrx_pLr_ClM\"\n      slides_url: \"https://rails-8-multi-db-solid-queue-cache.guillaumebriday.fr/\"\n      description: |-\n        Par Guillaume Briday\n        Paris.rb Meetup Janvier 2025\n        Merci à Simplébo de nous avoir accueillis.\n        https://www.simplebo.fr\n\n        0:00 Intro\n        1:57 Talk\n        26:25 Questions\n\n        Liens :\n        https://guillaumebriday.fr\n        https://github.com/rails/solid_cache\n        https://github.com/rails/solid_queue\n        https://kamal-deploy.org/\n\n        Retrouvez Guillaume Briday :\n        https://guillaumebriday.fr/links\n      additional_resources:\n        - name: \"rails/solid_cache\"\n          type: \"repo\"\n          url: \"https://github.com/rails/solid_cache\"\n\n        - name: \"rails/solid_queue\"\n          type: \"repo\"\n          url: \"https://github.com/rails/solid_queue\"\n\n    - title: \"Des formulaires qui rendent heureux\"\n      raw_title: \"Des formulaires qui rendent heureux\"\n      speakers:\n        - Adrien Siami\n      event_name: \"Paris.rb Meetup January 2025\"\n      language: \"french\"\n      date: \"2025-01-07\"\n      published_at: \"2025-06-04\"\n      video_provider: \"youtube\"\n      id: \"adrien-siami-parisrb-meetup-january-2025\"\n      video_id: \"FT6Ab3uoAV4\"\n      slides_url: \"https://talks.siami.fr/forms-that-spark-joy/\"\n      description: |-\n        Par Adrien Siami\n        Paris.rb Meetup Janvier 2025\n        Merci à Simplébo de nous avoir accueillis.\n        https://www.simplebo.fr\n\n        0:00 Talk\n        17:40 Questions\n\n        Liens :\n        https://talks.siami.fr/forms-that-spark-joy/\n        https://github.com/Intrepidd/hyperactiveform\n        https://github.com/Intrepidd/forms-demo\n\n        Retrouvez Adrien Siami :\n        https://x.com/Intrepidd\n      additional_resources:\n        - name: \"Intrepidd/hyperactiveform\"\n          type: \"repo\"\n          url: \"https://github.com/Intrepidd/hyperactiveform\"\n\n        - name: \"Intrepidd/forms-demo\"\n          type: \"repo\"\n          url: \"https://github.com/Intrepidd/forms-demo\"\n- id: \"paris-rb-february-2025\"\n  title: \"Paris.rb Meetup February 2025\"\n  raw_title: \"Paris.rb Meetup February 2025\"\n  event_name: \"Paris.rb Meetup February 2025\"\n  date: \"2025-02-04\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-february-2025\"\n  description: \"\"\n  talks:\n    - title: \"Types numériques en Ruby\"\n      raw_title: \"Types numériques en Ruby\"\n      speakers:\n        - Rémy Hannequin\n      event_name: \"Paris.rb Meetup February 2025\"\n      language: \"french\"\n      date: \"2025-02-04\"\n      published_at: \"2025-09-13\"\n      video_provider: \"youtube\"\n      id: \"remy-hannequin-parisrb-meetup-february-2025\"\n      video_id: \"Qmz1HuVB3Xg\"\n      description: |-\n        Par Rémy Hannequin\n        Paris.rb Meetup Février 2025\n        Merci à Memory de nous avoir accueillis.\n        https://www.inthememory.com\n\n        0:00 Talk\n        21:00 Questions\n\n        Liens :\n        https://rhannequ.in/slides/ruby-numeric-types/fr/\n\n        Retrouvez Rémy Hannequin :\n        https://ruby.social/@rhannequin\n        https://bsky.app/profile/rhannequin.bsky.social\n        https://www.linkedin.com/in/rhannequin\n\n    - title: \"Rails Best Practices\"\n      raw_title: \"Rails Best Practices\"\n      event_name: \"Paris.rb Meetup February 2025\"\n      language: \"french\"\n      date: \"2025-02-04\"\n      published_at: \"2025-09-13\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"rails-best-practices-parisrb-meetup-february-2025\"\n      video_id: \"iM-4MPdBTuQ\"\n      description: |-\n        Par Leijun\n        Paris.rb Meetup Février 2025\n        Merci à Memory de nous avoir accueillis.\n        https://www.inthememory.com\n\n        0:00 Intro\n        1:26 Talk\n        12:35 Questions\n\n        Liens :\n        https://docs.google.com/presentation/d/1dqaMV25J0_j-LVSFtz8c06G2PYDyHZaduzAPjVN24Ag/edit#slide=id.p\n\n        http://www.leijun-jiang.com/jekyll/update/2024/12/24/rails-best-practices.html\n\n- id: \"paris-rb-march-2025\"\n  title: \"Paris.rb Meetup March 2025\"\n  raw_title: \"Paris.rb Meetup March 2025\"\n  event_name: \"Paris.rb Meetup March 2025\"\n  date: \"2025-03-04\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-march-2025\"\n  description: \"\"\n  talks:\n    - title: \"Créer un framework à partir de dry-rb\"\n      raw_title: \"Créer un framework à partir de dry-rb\"\n      event_name: \"Paris.rb Meetup March 2025\"\n      language: \"french\"\n      date: \"2025-03-04\"\n      published_at: \"2025-09-03\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"creer-un-framework-a-partir-de-dry-rb-parisrb-meetup-march-2025\"\n      video_id: \"_hT27qRrZEI\"\n      description: |-\n        Par Alexandre\n        Paris.rb Meetup Mars 2025\n        Merci à Enercoop de nous avoir accueillis.\n        https://www.enercoop.fr\n\n        0:00 Intro\n        0:45 Talk\n        33:00 Questions\n\n        Liens :\n        https://dry-rb.org/\n        https://rom-rb.org/\n        https://hanamirb.org/\n\n        Retrouvez Alexandre :\n        https://x.com/alex-lairan\n        https://github.com/alex-lairan/\n\n    - title: \"Bannir les nombres magiques\"\n      raw_title: \"Bannir les nombres magiques\"\n      speakers:\n        - Clément Prod'homme\n      event_name: \"Paris.rb Meetup March 2025\"\n      language: \"french\"\n      date: \"2025-03-04\"\n      published_at: \"2025-09-02\"\n      video_provider: \"youtube\"\n      id: \"clement-prod-homme-parisrb-meetup-march-2025\"\n      video_id: \"kUVuvz-GV0o\"\n      description: |-\n        Par Clément Prod'homme\n        Paris.rb Meetup Mars 2025\n        Merci à Enercoop de nous avoir accueillis.\n        https://www.enercoop.fr\n\n        0:00 Talk\n        10:50 Questions\n\n        Liens :\n        https://github.com/meetcleo/rubocop-magic_numbers\n\n        Retrouvez Clément Prod'homme :\n        https://www.linkedin.com/in/clementprodhomme/\n\n- id: \"paris-rb-june-2025\"\n  title: \"Paris.rb Meetup June 2025\"\n  raw_title: \"Paris.rb Meetup June 2025\"\n  event_name: \"Paris.rb Meetup June 2025\"\n  date: \"2025-06-03\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-june-2025\"\n  description: \"\"\n  talks:\n    - title: \"L2 Support AKA Bug Killer\"\n      raw_title: \"L2 Support AKA Bug Killer\"\n      event_name: \"Paris.rb Meetup June 2025\"\n      language: \"french\"\n      date: \"2025-06-03\"\n      published_at: \"2025-09-21\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"l2-support-aka-bug-killer-parisrb-meetup-june-2025\"\n      video_id: \"ScCNaAuAsyg\"\n      description: |-\n        Par Loic, Jules & Antoine\n        Paris.rb Meetup Juin 2025\n        Merci à Wecasa de nous avoir accueillis.\n        https://www.wecasa.fr\n\n        0:00 Talk\n        17:53 Questions\n\n        Liens :\n        ITIL Thinking : https://fr.wikipedia.org/wiki/Information_Technology_Infrastructure_Library\n\n        Retrouvez Loic, Jules & Antoine :\n        LinkedIn Loic : https://www.linkedin.com/in/lo%C3%AFc-monthorin/\n        LinkedIn Jules : https://www.linkedin.com/in/jules-pinsard/\n        LinkedIn Antoine : https://www.linkedin.com/in/antoine-braconnier1991/\n\n    - title: \"Recherche en plein texte avec PostgreSQL\"\n      raw_title: \"Recherche en plein texte avec PostgreSQL\"\n      speakers:\n        - Rémi Mercier\n      event_name: \"Paris.rb Meetup June 2025\"\n      language: \"french\"\n      date: \"2025-06-03\"\n      published_at: \"2025-09-15\"\n      video_provider: \"youtube\"\n      id: \"remi-mercier-parisrb-meetup-june-2025\"\n      video_id: \"cPY2M2XZv-0\"\n      description: |-\n        Par Rémi Mercier\n        Paris.rb Meetup Juin 2025\n        Merci à Wecasa de nous avoir accueillis.\n        https://www.wecasa.fr\n\n        0:00 Talk\n        17:02 Questions\n\n        Liens :\n        https://www.postgresql.org/docs/current/textsearch.html\n        https://remimercier.com/postgresql-full-text-search-for-beginners/\n\n        Retrouvez Rémi Mercier :\n        https://remimercier.com/\n        https://www.linkedin.com/in/remimercier/\n        https://ruby.social/@remi\n\n- id: \"paris-rb-september-2025\"\n  title: \"Paris.rb Meetup September 2025\"\n  raw_title: \"Paris.rb Meetup September 2025\"\n  event_name: \"Paris.rb Meetup September 2025\"\n  date: \"2025-09-02\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-september-2025\"\n  description: \"\"\n  talks:\n    - title: \"How we run RubyGems.org\"\n      raw_title: \"How we run RubyGems.org\"\n      speakers:\n        - Marty Haught\n      event_name: \"Paris.rb Meetup September 2025\"\n      language: \"english\"\n      date: \"2025-09-02\"\n      published_at: \"2026-02-14\"\n      video_provider: \"youtube\"\n      id: \"marty-haught-parisrb-meetup-september-2025\"\n      video_id: \"7AC1dHHtndg\"\n      description: |-\n        Par Marty Haught\n        Paris.rb Meetup Septembre 2025\n        Merci à Le Wagon de nous avoir accueillis.\n        https://www.lewagon.com\n\n    - title: \"What is the Cyber Resilience Act\"\n      raw_title: \"What is the Cyber Resilience Act\"\n      speakers:\n        - Marty Haught\n      event_name: \"Paris.rb Meetup September 2025\"\n      language: \"english\"\n      date: \"2025-09-02\"\n      published_at: \"2026-02-14\"\n      video_provider: \"youtube\"\n      id: \"marty-haught-cyber-resilience-act-parisrb-meetup-september-2025\"\n      video_id: \"eAMRqSXzkCc\"\n      description: |-\n        Par Marty Haught\n        Paris.rb Meetup Septembre 2025\n        Merci à Le Wagon de nous avoir accueillis.\n        https://www.lewagon.com\n\n    - title: \"Web performance myths busted\"\n      raw_title: \"Web performance myths busted\"\n      speakers:\n        - Guillaume Briday\n      event_name: \"Paris.rb Meetup September 2025\"\n      language: \"french\"\n      date: \"2025-09-02\"\n      published_at: \"2025-09-21\"\n      video_provider: \"youtube\"\n      id: \"guillaume-briday-parisrb-meetup-september-2025\"\n      video_id: \"9xhuBteWxwA\"\n      description: |-\n        Par Guillaume Briday\n        Paris.rb Meetup Septembre 2025\n        Merci à Le Wagon de nous avoir accueillis.\n        https://www.lewagon.com\n\n        Liens :\n        https://guillaumebriday.fr/\n\n        Retrouvez Guillaume Briday :\n        https://x.com/guillaumebriday\n        https://www.instagram.com/guillaumebriday\n        https://github.com/guillaumebriday\n\n- id: \"paris-rb-october-2025\"\n  title: \"Paris.rb Meetup October 2025\"\n  raw_title: \"Paris.rb Meetup October 2025\"\n  event_name: \"Paris.rb Meetup October 2025\"\n  date: \"2025-10-07\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-october-2025\"\n  description: \"\"\n  talks:\n    - title: \"2025 10 FastMCP\"\n      raw_title: \"2025 10 FastMCP\"\n      speakers:\n        - Yorick Jacquin\n      event_name: \"Paris.rb Meetup October 2025\"\n      language: \"french\"\n      date: \"2025-10-07\"\n      published_at: \"2026-02-17\"\n      video_provider: \"youtube\"\n      id: \"yorick-jacquin-parisrb-meetup-october-2025\"\n      video_id: \"W_I-5JJB48I\"\n      description: |-\n        Par Yorick Jacquin\n        Paris.rb Meetup Octobre 2025\n        Merci à Algolia de nous avoir accueillis.\n        www.algolia.com\n\n    - title: \"Claude Swarm\"\n      raw_title: \"Claude Swarm\"\n      speakers:\n        - Eric Proulx\n      event_name: \"Paris.rb Meetup October 2025\"\n      language: \"french\"\n      date: \"2025-10-07\"\n      published_at: \"2026-02-17\"\n      video_provider: \"youtube\"\n      id: \"eric-proulx-parisrb-meetup-october-2025\"\n      video_id: \"sjYPYlqBrjU\"\n      description: |-\n        Par Eric Proulx\n        Paris.rb Meetup Octobre 2025\n        Merci à Algolia de nous avoir accueillis.\n        www.algolia.com\n\n    - title: \"AI, offline\"\n      raw_title: \"AI, offline\"\n      speakers:\n        - Chris Hasiński\n      event_name: \"Paris.rb Meetup October 2025\"\n      language: \"english\"\n      date: \"2025-10-07\"\n      published_at: \"2026-02-17\"\n      video_provider: \"youtube\"\n      id: \"chris-hasinski-parisrb-meetup-october-2025\"\n      video_id: \"qGy8Rz0dMRE\"\n      description: |-\n        Par Chris Hasiński\n        Paris.rb Meetup Octobre 2025\n        Merci à Algolia de nous avoir accueillis.\n        www.algolia.com\n\n- id: \"paris-rb-november-2025\"\n  title: \"Paris.rb Meetup November 2025\"\n  raw_title: \"Paris.rb Meetup November 2025\"\n  event_name: \"Paris.rb Meetup November 2025\"\n  date: \"2025-11-04\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-november-2025\"\n  description: \"\"\n  talks:\n    - title: \"Papercraft: embracing the functional style in Ruby\"\n      raw_title: \"Papercraft: embracing the functional style in Ruby\"\n      event_name: \"Paris.rb Meetup November 2025\"\n      language: \"english\"\n      date: \"2025-11-04\"\n      published_at: \"2026-03-01\"\n      video_provider: \"youtube\"\n      speakers:\n        - TODO\n      id: \"papercraft-embracing-the-functional-style-in-ruby-parisrb-meetup-november-2025\"\n      video_id: \"WW5ww7gCFJs\"\n      description: |-\n        Par Sharon\n        Paris.rb Meetup Novembre 2025\n        Merci à My Job Glasses de nous avoir accueillis.\n        www.myjobglasses.com\n\n        Liens :\n        https://noteflakes.com/\n        https://github.com/noteflakes\n\n        Retrouvez Sharon :\n        https://bsky.app/profile/noteflakes.bsky.social\n\n    - title: \"Exploration de codebase avec codemaps\"\n      raw_title: \"Exploration de codebase avec codemaps\"\n      speakers:\n        - Cyril Duchon-Doris\n      event_name: \"Paris.rb Meetup November 2025\"\n      language: \"french\"\n      date: \"2025-11-04\"\n      published_at: \"2026-03-01\"\n      video_provider: \"youtube\"\n      id: \"cyril-duchon-doris-parisrb-meetup-november-2025\"\n      video_id: \"xcahtTZ6c4E\"\n      description: |-\n        Par Cyril Duchon-Doris\n        Paris.rb Meetup Novembre 2025\n        Merci à My Job Glasses de nous avoir accueillis.\n        www.myjobglasses.com\n\n    - title: \"Autodoc : la doc connectée à vos tests d'intégration\"\n      raw_title: \"Autodoc : la doc connectée à vos tests d'intégration\"\n      speakers:\n        - Victor Mours\n      event_name: \"Paris.rb Meetup November 2025\"\n      language: \"french\"\n      date: \"2025-11-04\"\n      published_at: \"2026-03-01\"\n      video_provider: \"youtube\"\n      id: \"victor-mours-parisrb-meetup-november-2025\"\n      video_id: \"6PwnPsVOQlw\"\n      description: |-\n        Par Victor Mours\n        Paris.rb Meetup Novembre 2025\n        Merci à My Job Glasses de nous avoir accueillis.\n        www.myjobglasses.com\n\n- id: \"paris-rb-december-2025\"\n  title: \"Paris.rb Meetup December 2025\"\n  raw_title: \"Paris.rb Meetup December 2025\"\n  event_name: \"Paris.rb Meetup December 2025\"\n  date: \"2025-12-02\"\n  video_provider: \"children\"\n  video_id: \"paris-rb-december-2025\"\n  description: \"\"\n  talks:\n    - title: \"Data for good\"\n      raw_title: \"Data for good\"\n      speakers:\n        - Paul Gabriel\n      event_name: \"Paris.rb Meetup December 2025\"\n      language: \"french\"\n      date: \"2025-12-02\"\n      published_at: \"2026-03-02\"\n      video_provider: \"youtube\"\n      id: \"paul-gabriel-parisrb-meetup-december-2025\"\n      video_id: \"iX2NNiO9MxE\"\n      description: |-\n        Par Paul Gabriel\n        Paris.rb Meetup Décembre 2025\n        Merci à Qonto de nous avoir accueillis.\n        qonto.com\n\n    - title: \"Cloud exit at 37signals\"\n      raw_title: \"Cloud exit at 37signals\"\n      speakers:\n        - Paul Gabriel\n      event_name: \"Paris.rb Meetup December 2025\"\n      language: \"french\"\n      date: \"2025-12-02\"\n      published_at: \"2026-03-02\"\n      video_provider: \"youtube\"\n      id: \"paul-gabriel-cloud-exit-parisrb-meetup-december-2025\"\n      video_id: \"RcII1stMhVs\"\n      description: |-\n        Par Paul Gabriel\n        Paris.rb Meetup Décembre 2025\n        Merci à Qonto de nous avoir accueillis.\n        qonto.com\n\n    - title: \"Ruby standards at Qonto\"\n      raw_title: \"Ruby standards at Qonto\"\n      speakers:\n        - Julien Perlot\n      event_name: \"Paris.rb Meetup December 2025\"\n      language: \"french\"\n      date: \"2025-12-02\"\n      published_at: \"2026-03-02\"\n      video_provider: \"youtube\"\n      id: \"julien-perlot-parisrb-meetup-december-2025\"\n      video_id: \"3myaIWgLMdA\"\n      description: |-\n        Par Julien Perlot\n        Paris.rb Meetup Décembre 2025\n        Merci à Qonto de nous avoir accueillis.\n        qonto.com\n"
  },
  {
    "path": "data/paris-rb/series.yml",
    "content": "---\nname: \"Paris.rb Meetup\"\nwebsite: \"https://paris-rb.org\"\nmeetup: \"https://www.meetup.com/paris_rb/\"\ntwitter: \"parisrb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"FR\"\nlanguage: \"french\"\nyoutube_channel_name: \"Parisrbmeetup\"\nyoutube_channel_id: \"UCttFnyoHp4TdsTj1wcVs44A\"\n"
  },
  {
    "path": "data/paris-rb-conf/paris-rb-conf-2018/event.yml",
    "content": "---\nid: \"PLjyiiigeVQV_mHcSnJnw_1LR4nzGrdF4l\"\ntitle: \"Paris.rb Conf 2018\"\nkind: \"conference\"\nlocation: \"Paris, France\"\ndescription: |-\n  Talks recorded in June 2018 during https://2018.rubyparis.org in Paris.\nstart_date: \"2018-06-28\"\nend_date: \"2018-06-29\"\npublished_at: \"2018-07-20\"\nchannel_id: \"UCttFnyoHp4TdsTj1wcVs44A\"\nyear: 2018\nwebsite: \"https://2018.rubyparis.org\"\ncoordinates:\n  latitude: 48.8575475\n  longitude: 2.3513765\n"
  },
  {
    "path": "data/paris-rb-conf/paris-rb-conf-2018/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"bozhidar-batsov-parisrb-conf-2018\"\n  title: \"Ruby 4.0: To Infinity and Beyond\"\n  raw_title: '\"Ruby 4.0: To Infinity and Beyond\" by Bozhidar Batsov'\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-20\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"eEspjdnUf3M\"\n\n- id: \"vladimir-dementyev-parisrb-conf-2018\"\n  title: \"99 Problems of Slow Tests\"\n  raw_title: '\"99 problems of slow tests\" by Vladimir Dementyev'\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-20\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"eDMZS_fkRtk\"\n  slides_url: \"https://speakerdeck.com/palkan/paris-dot-rb-2018-99-problems-of-slow-tests\"\n\n- id: \"rafael-mendona-frana-parisrb-conf-2018\"\n  title: \"Living on Rails Edge\"\n  raw_title: '\"Living on Rails edge\" by Rafael França'\n  speakers:\n    - Rafael Mendonça França\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-20\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"DMaeQTVU3qw\"\n\n- id: \"jenna-blumenthal-parisrb-conf-2018\"\n  title: \"Event Sourcing for Everyone\"\n  raw_title: '\"Event Sourcing for Everyone\" by Jenna Blumenthal'\n  speakers:\n    - Jenna Blumenthal\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-20\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"1h3_6ATnOTw\"\n\n- id: \"luis-lavena-parisrb-conf-2018\"\n  title: \"Crystal: How Using a Compiled Language Made Me Write Better Ruby\"\n  raw_title: '\"Crystal: How using a compiled language made me write better Ruby\" by Luis Lavena'\n  speakers:\n    - Luis Lavena\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-20\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"r_9UB8-hG7I\"\n\n- id: \"hiroshi-shibata-parisrb-conf-2018\"\n  title: \"RubyGems 3 & 4\"\n  raw_title: '\"RubyGems 3 & 4\" by Hiroshi Shibata'\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-20\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"8R23yMmCw9w\"\n\n- id: \"sylvain-ablard-parisrb-conf-2018\"\n  title: \"Clean Code Lessons From Messy Humans\"\n  raw_title: '\"Clean code lessons from messy humans\" by Sylvain Abélard'\n  speakers:\n    - Sylvain Abélard\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-20\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"9YAivor0BUw\"\n\n- id: \"eileen-m-uchitelle-parisrb-conf-2018\"\n  title: \"The Future of Rails 6: Scalable by Default\"\n  raw_title: '\"The Future of Rails 6: Scalable by Default\" by Eileen M. Uchitelle'\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-24\"\n  published_at: \"2018-08-21\"\n  slides_url: \"https://speakerdeck.com/eileencodes/paris-ruby-conference-2018-the-future-of-rails-6\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks on https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"PVCMLFH1ANU\"\n\n- id: \"lucas-tolchinsky-parisrb-conf-2018\"\n  title: \"Less Code, More Confidence\"\n  raw_title: '\"Less code, more confidence\" by Lucas Tolchinsky'\n  speakers:\n    - Lucas Tolchinsky\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-24\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"obDdNYZeQB4\"\n\n- id: \"damir-svrtan-parisrb-conf-2018\"\n  title: \"Building Serverless Ruby Bots\"\n  raw_title: '\"Building Serverless Ruby Bots\" by Damir Svrtan'\n  speakers:\n    - Damir Svrtan\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-24\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"BsfjzNG07aY\"\n\n- id: \"mai-nguyen-parisrb-conf-2018\"\n  title: \"Food, Wine and Machine Learning: Teaching a Bot to Taste\"\n  raw_title: '\"Food, Wine and Machine Learning: Teaching a Bot to Taste\" by Mai Nguyen'\n  speakers:\n    - Mai Nguyen\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-24\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"EUv8wYq26Ss\"\n\n- id: \"christophe-philemotte-parisrb-conf-2018\"\n  title: \"How To Onboard a Junior Developer\"\n  raw_title: '\"How to onboard a junior developer\" by Christophe Philemotte'\n  speakers:\n    - Christophe Philemotte\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-24\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"a2xTi9lHts0\"\n\n- id: \"kirk-haines-parisrb-conf-2018\"\n  title: \"It's Rubies All The Way Down!\"\n  raw_title: '\"It''s Rubies All The Way Down!\" by Kirk Haines'\n  speakers:\n    - Kirk Haines\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-24\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"E6s4uB0DBVk\"\n\n- id: \"koichiro-eto-parisrb-conf-2018\"\n  title: \"Ruby and Art: The Earliest Stage\"\n  raw_title: '\"Ruby and Art: The Earliest Stage\" by Koichiro Eto'\n  speakers:\n    - Koichiro Eto\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-24\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"YhLnDGNtSew\"\n\n- id: \"coraline-ehmke-parisrb-conf-2018\"\n  title: \"Aesthetics and the Evolution of Code\"\n  raw_title: '\"Aesthetics and the Evolution of Code\" by Coraline Ehmke'\n  speakers:\n    - Coraline Ehmke\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-07-24\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"TbFce4FuEKc\"\n\n- id: \"keith-bennett-parisrb-conf-2018\"\n  title: \"Writing a Command Line Utility in Ruby - Automation is Not Just For Your Users\"\n  raw_title: '\"Writing a Command Line Utility in Ruby - Automation is Not Just For Your Users\" by Keith Bennett'\n  speakers:\n    - Keith Bennett\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-08-21\"\n  published_at: \"2018-08-21\"\n  slides_url: \"https://speakerdeck.com/keithrbennett/command-line-applications-in-ruby\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"zMzzKOecvaA\"\n\n- id: \"paul-armand-assus-parisrb-conf-2018\"\n  title: \"GraphQL-DDD on Rails Architecture\"\n  raw_title: '\"GraphQL-DDD on Rails architecture\" by Paul-Armand Assus'\n  speakers:\n    - Paul-Armand Assus\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-08-21\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"THYVNLsjWqo\"\n\n- id: \"olivier-lacan-parisrb-conf-2018\"\n  title: \"Human Errors\"\n  raw_title: '\"Human Errors\" by Olivier Lacan'\n  speakers:\n    - Olivier Lacan\n  event_name: \"Paris.rb Conf 2018\"\n  date: \"2018-08-21\"\n  published_at: \"2018-08-21\"\n  description: |-\n    Recorded in June 2018 during https://2018.rubyparis.org in Paris. More talks at https://goo.gl/8egyWi\n  video_provider: \"youtube\"\n  video_id: \"pzdI7r2OJ84\"\n"
  },
  {
    "path": "data/paris-rb-conf/paris-rb-conf-2020/event.yml",
    "content": "---\nid: \"PLjyiiigeVQV-rqM4LD2SUbUfxXLuta1yU\"\ntitle: \"Paris.rb Conf 2020\"\nkind: \"conference\"\nlocation: \"Paris, France\"\ndescription: |-\n  Talks recorded in February 2020 during https://2020.rubyparis.org in Paris.\nstart_date: \"2020-02-18\"\nend_date: \"2020-02-19\"\npublished_at: \"2020-03-20\"\nchannel_id: \"UCttFnyoHp4TdsTj1wcVs44A\"\nyear: 2020\nwebsite: \"https://2020.rubyparis.org\"\ncoordinates:\n  latitude: 48.8575475\n  longitude: 2.3513765\n"
  },
  {
    "path": "data/paris-rb-conf/paris-rb-conf-2020/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"yukihiro-matz-matsumoto-parisrb-conf-2020\"\n  title: \"Keynote: How to Dominate the World\"\n  raw_title: \"Yukihiro Matsumoto: Keynote\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"9TB_EM9IfFo\"\n\n- id: \"luca-guidi-parisrb-conf-2020\"\n  title: \"Keynote: Why Hanami?\"\n  raw_title: \"Luca Guidi: Keynote\"\n  speakers:\n    - Luca Guidi\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"7DABLhbNy0I\"\n\n- id: \"andy-croll-parisrb-conf-2020\"\n  title: \"The Games Developers Play\"\n  raw_title: \"Andy Croll: The Games Developers Play\"\n  speakers:\n    - Andy Croll\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"W98aarCoEHE\"\n\n- id: \"getty-ritter-parisrb-conf-2020\"\n  title: \"Sorbet: Practical Gradual Type Checking For Ruby\"\n  raw_title: \"Getty Ritter: Sorbet: Practical Gradual Type Checking For Ruby\"\n  speakers:\n    - Getty Ritter\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"O154LCbFNOY\"\n\n- id: \"sunny-ripert-parisrb-conf-2020\"\n  title: 'A Poignant Look Back at \"why the lucky stiff''s\" Legacy'\n  raw_title: 'Sunny Ripert: A poignant look back at \"why the lucky stiff''s\" legacy'\n  speakers:\n    - Sunny Ripert\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"njr39cVU7d0\"\n\n- id: \"philip-poots-parisrb-conf-2020\"\n  title: \"Rediscovering Ruby\"\n  raw_title: \"Philip Poots: Rediscovering Ruby\"\n  speakers:\n    - Philip Poots\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"s5A4recPPC4\"\n\n- id: \"melanie-berard-parisrb-conf-2020\"\n  title: \"Managing Knowledge Among the Wildest Animals - Fullstack Developers - In Their Natural Habitat\"\n  raw_title: \"Mélanie Bérard, Alexandre Ignjatovic: Managing knowledge among the wildest animals   fullstack dev\"\n  speakers:\n    - Mélanie Bérard\n    - Alexandre Ignjatovic\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"hO_Fm23th5U\"\n\n- id: \"nicolas-zermati-parisrb-conf-2020\"\n  title: \"The First Feedback We Get\"\n  raw_title: \"Nicolas Zermati: The first feedback we get\"\n  speakers:\n    - Nicolas Zermati\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6vOl71zvK54\"\n\n- id: \"jeremy-evans-parisrb-conf-2020\"\n  title: \"Running a Government Department on a Roda Sequel Stack\"\n  raw_title: \"Jeremy Evans: Running a government department on a Roda Sequel stack\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"sUBgL_FYUlM\"\n\n- id: \"ekechi-iyke-ikenna-parisrb-conf-2020\"\n  title: \"Discovering the Magic of Software Development, and Helping Others Discover it\"\n  raw_title: \"Ekechi “Iyke” Ikenna: Discovering the magic of Software development, and helping others discover it\"\n  speakers:\n    - Ekechi \"Iyke\" Ikenna\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"2oSmi2G8df4\"\n\n- id: \"dmitry-vorotilin-parisrb-conf-2020\"\n  title: \"Modern Headless Testing in XXII Century\"\n  raw_title: \"Dmitry Vorotilin: Modern headless testing in XXII century\"\n  speakers:\n    - Dmitry Vorotilin\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"W1gRysJE5og\"\n\n- id: \"daniel-fone-parisrb-conf-2020\"\n  title: \"What Could Go Wrong? The Science of Coding For Failure\"\n  raw_title: \"Daniel Fone: What could go wrong? The science of coding for failure\"\n  speakers:\n    - Daniel Fone\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"VmURvpUnLeQ\"\n\n- id: \"anne-sophie-rouaux-parisrb-conf-2020\"\n  title: \"Story of an Haemorrhage\"\n  raw_title: \"Anne Sophie Rouaux: Story of an haemorrhage\"\n  speakers:\n    - Anne Sophie Rouaux\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"89ASJZrayaY\"\n\n- id: \"thibaut-barrre-parisrb-conf-2020\"\n  title: \"Kiba ETL: Feedback on OSS Open Core Sustainability for a Ruby Gem\"\n  raw_title: \"Thibaut Barrère: Kiba ETL: feedback on OSS  open core sustainability for a Ruby gem\"\n  speakers:\n    - Thibaut Barrère\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"yv1EnYTXIeA\"\n\n- id: \"salim-semaoune-parisrb-conf-2020\"\n  title: \"Scale Background Queues\"\n  raw_title: \"Salim Semaoune: Scale Background Queues\"\n  speakers:\n    - Salim Semaoune\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"w5ABH3mZAxU\"\n\n- id: \"ruan-brandao-parisrb-conf-2020\"\n  title: \"Ethics in Software Development\"\n  raw_title: \"Ruan Brandão: Ethics in software development\"\n  speakers:\n    - Ruan Brandão\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"mFz22c4N-Cs\"\n\n- id: \"raphaela-wrede-parisrb-conf-2020\"\n  title: \"Breaking Silos in Product Development\"\n  raw_title: \"Raphaela Wrede: Breaking Silos in Product Development\"\n  speakers:\n    - Raphaela Wrede\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"qqtU5zfIrv4\"\n\n- id: \"prakriti-gupta-parisrb-conf-2020\"\n  title: \"All in One Interactive Plotting Using Daru View\"\n  raw_title: \"Prakriti Gupta: All in one interactive plotting using daru view\"\n  speakers:\n    - Prakriti Gupta\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"gSKKqi0ncrc\"\n\n- id: \"paolo-nusco-perrotta-parisrb-conf-2020\"\n  title: \"Dreaming of Intelligent Machines\"\n  raw_title: 'Paolo \"Nusco\" Perrotta: Dreaming of intelligent machines'\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8fyOvdQQjeE\"\n\n- id: \"nathaly-villamor-parisrb-conf-2020\"\n  title: \"Monads as a Clean Solution To Our Messy Code\"\n  raw_title: \"Nathaly Villamor: Monads as a clean solution to our messy code\"\n  speakers:\n    - Nathaly Villamor\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Ynsg9vf9K94\"\n\n- id: \"moncef-belyamani-parisrb-conf-2020\"\n  title: \"Speeding up Tests With Creativity and Behavioral Science\"\n  raw_title: \"Moncef Belyamani: Speeding up tests with creativity and behavioral science\"\n  speakers:\n    - Moncef Belyamani\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Rs5HBkPkTSA\"\n\n- id: \"cyrille-courtiere-parisrb-conf-2020\"\n  title: \"Keep it Clean, For Years\"\n  raw_title: \"Cyrille Courtiere: Keep it clean, for years\"\n  speakers:\n    - Cyrille Courtiere\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FE6kJIuihcY\"\n\n- id: \"brittany-martin-parisrb-conf-2020\"\n  title: \"I am Altering the Deal\"\n  raw_title: \"Brittany Martin: I am Altering the Deal\"\n  speakers:\n    - Brittany Martin\n  event_name: \"Paris.rb Conf 2020\"\n  date: \"2020-03-30\"\n  published_at: \"2020-03-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"WKYUNN9I0C0\"\n"
  },
  {
    "path": "data/paris-rb-conf/series.yml",
    "content": "---\nname: \"Paris.rb Conf\"\nwebsite: \"https://paris-rb.org\"\ntwitter: \"parisrb\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"FR\"\nlanguage: \"english\"\nyoutube_channel_name: \"Parisrbmeetup\"\nyoutube_channel_id: \"UCttFnyoHp4TdsTj1wcVs44A\"\n"
  },
  {
    "path": "data/philly-rb/philly-rb/event.yml",
    "content": "---\nid: \"philly-rb-meetup\"\ntitle: \"Philly.rb Meetup\"\nkind: \"meetup\"\nlocation: \"Philadelphia, PA, United States\"\ndescription: |-\n  Philly.rb is the one and only user group in Philadelphia dedicated to helping Ruby enthusiasts learn, network, and socialize.\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://www.phillyrb.org/\"\ncoordinates:\n  latitude: 39.9533\n  longitude: -75.1636\n"
  },
  {
    "path": "data/philly-rb/philly-rb/videos.yml",
    "content": "---\n- id: \"philly-rb-meetup-april-2017\"\n  title: \"Philly.rb April 2017\"\n  event_name: \"Philly.rb April 2017\"\n  date: \"2017-04-18\"\n  video_provider: \"children\"\n  video_id: \"philly-rb-meetup-april-2017\"\n  description: |-\n    Come to PhillyRBs first Gem Day to hear short talks from several speakers who will share exciting tales of their most useful or exciting Ruby Gems.\n    https://www.meetup.com/phillyrb/events/238886348/\n  talks:\n    - title: \"VCR - A Gem used for caching HTTP requests during tests\"\n      event_name: \"Philly.rb April 2017\"\n      date: \"2017-04-18\"\n      speakers:\n        - Mike Dalton\n      id: \"mike-dalton-philly-rb-april-2017\"\n      video_id: \"mike-dalton-philly-rb-april-2017\"\n      video_provider: \"not_recorded\"\n      slides_url: \"https://speakerdeck.com/kcdragon/vcr-a-gem-used-for-caching-http-requests-during-tests\"\n      description: |-\n        Overview of the VCR gem which is used to cache http requests while running tests. Practical examples will be provided.\n    - title: \"Rack\"\n      event_name: \"Philly.rb April 2017\"\n      date: \"2017-04-18\"\n      speakers:\n        - Ernesto Tagwerker\n      id: \"ernesto-tagwerker-philly-rb-april-2017\"\n      video_id: \"ernesto-tagwerker-philly-rb-april-2017\"\n      video_provider: \"not_recorded\"\n      description: |-\n        Many Ruby developers use Rack, but don't interact with it or know how it works. We'll look at how we all use it and the middleware available for rack-based applications.\n- id: \"philly-rb-meetup-december-2025\"\n  title: \"Philly.rb December 2025\"\n  event_name: \"Philly.rb December 2025\"\n  date: \"2025-12-16\"\n  video_provider: \"children\"\n  video_id: \"philly-rb-meetup-december-2025\"\n  description: |-\n    https://www.meetup.com/phillyrb/events/312047297/\n  talks:\n    - title: \"Introduction to Hotwire Native\"\n      event_name: \"Philly.rb December 2025\"\n      date: \"2025-12-16\"\n      speakers:\n        - Mike Dalton\n      id: \"mike-dalton-philly-rb-december-2025\"\n      video_id: \"mike-dalton-philly-rb-december-2025\"\n      video_provider: \"not_recorded\"\n      slides_url: \"https://speakerdeck.com/kcdragon/introduction-to-hotwire-native\"\n      description: |-\n        Hotwire Native is a set of JavaScript, iOS and Android libraries that allow developers to build iOS and Android apps with native capabilities using mostly Ruby on Rails. Mike will introduce Hotwire Native and describe how a developer can quickly use it to transform their Rails app to a native app. He will then show how to write native code to support more advanced features like OAuth.\n- id: \"philly-rb-meetup-january-2026\"\n  title: \"Philly.rb January 2026\"\n  event_name: \"Philly.rb January 2026\"\n  date: \"2026-01-20\"\n  video_provider: \"children\"\n  video_id: \"philly-rb-meetup-january-2026\"\n  description: |-\n    https://www.meetup.com/phillyrb/events/312486770/\n  talks:\n    - title: \"Talking Shit About AI Agents\"\n      event_name: \"Philly.rb January 2026\"\n      date: \"2026-01-20\"\n      speakers:\n        - Scott Werner\n      id: \"scott-werner-philly-rb-january-2026\"\n      video_id: \"scott-werner-philly-rb-january-2026\"\n      video_provider: \"not_recorded\"\n      description: |-\n        Ask seven people what an \"AI agent\" is and you'll get nine answers. One person will change their mind twice.\n\n        When we can't name something, it usually means we're looking at something genuinely new.\n\n        In this talk, I'll argue that what we're calling 'agents' might actually be a new programming paradigm hiding in plain sight. Think about what makes up an agent: an LLM, a prompt, a loop, some tools, a way to talk to it. It's essentially a little computer that receives messages and interprets them. That's suspiciously close to the way Alan Kay describes objects.\n\n        We'll take a detour through Xerox PARC circa 1972, explore what Kay actually meant by \"object-oriented\" (spoiler: not what we've been doing), and discover how LLMs accidentally achieved something he was reaching for: semantic late binding, where the meaning of a message is negotiated at the moment of receipt.\n\n        Then I'll demo a minimal Ruby environment where markdown files are the program and Ruby is just the scaffolding. You'll see prompt-objects receive messages, interpret them, talk to each other, and even create new prompt-objects at runtime.\n- id: \"philly-rb-meetup-february-2026\"\n  title: \"Philly.rb February 2026\"\n  event_name: \"Philly.rb February 2026\"\n  date: \"2026-02-17\"\n  video_provider: \"children\"\n  video_id: \"philly-rb-meetup-february-2026\"\n  description: |-\n    https://www.meetup.com/phillyrb/events/312486772/\n  talks:\n    - title: \"Revealing Rails Magic with Enums\"\n      event_name: \"Philly.rb February 2026\"\n      date: \"2026-02-17\"\n      speakers:\n        - Meg Gutshall\n      id: \"meg-gutshall-philly-rb-february-2026\"\n      video_id: \"meg-gutshall-philly-rb-february-2026\"\n      video_provider: \"not_recorded\"\n      description: |-\n        “Rails magic” is a term many people use to describe the ease with which Rails helps you go from zero to working app so quickly. However, like all other frameworks, there’s no magic to be found – only code! In this talk, you’ll get a peek behind the curtain as we break down the ActiveRecord Enums module. You’ll learn what it is, how/when to use it, and some cool tricks it provides. Even if you’re not a Rails developer, you will still come away from this talk with new-found knowledge on how to traverse a codebase and gain a better understanding of features built into your language of choice.\n"
  },
  {
    "path": "data/philly-rb/series.yml",
    "content": "---\nname: \"Philly.rb\"\nwebsite: \"https://www.phillyrb.org/\"\nmeetup: \"https://www.meetup.com/phillyrb/\"\ntwitter: \"phillyrb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"US\"\nlanguage: \"english\"\n"
  },
  {
    "path": "data/pivorak/pivorak-conf-1/event.yml",
    "content": "---\nid: \"PLa4SYMEyNCu9BsDfI_e2y8vd8FVkeVvum\"\ntitle: \"Pivorak Conf 1.0\"\nkind: \"conference\"\nlocation: \"Lviv, Ukraine\"\ndescription: \"\"\npublished_at: \"2018-10-26\"\nstart_date: \"2018-10-26\"\nend_date: \"2018-10-26\"\nchannel_id: \"UCPsfLdQH_0CaDIe4imm7bMA\"\nyear: 2018\nbanner_background: \"#70AE81\"\nfeatured_background: \"#70AE81\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 49.839683\n  longitude: 24.029717\n"
  },
  {
    "path": "data/pivorak/pivorak-conf-1/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"miha-rekar-pivorak-conf-10\"\n  title: \"Software Developers Are People Too\"\n  raw_title: \"SOFTWARE DEVELOPERS ARE PEOPLE TOO by Miha Rekar\"\n  speakers:\n    - Miha Rekar\n  event_name: \"Pivorak Conf 1.0\"\n  date: \"2018-10-26\"\n  published_at: \"2018-11-12\"\n  description: |-\n    Developers have other stuff to do, not only coding. They have some exciting hobbies as well. Miha presents some of them and intertwines it with interesting software tips and tricks.\n    -------------------------------------\n    #pivorak is a Lviv Ruby Meetup\n\n    Join our Ruby meetups in Lviv:\n    Our official website - https://pivorak.com\n    Facebook -- https://www.facebook.com/pivorak\n    Twitter -- https://twitter.com/pivorakmeetup\n    Instagram -- https://www.instagram.com/pivorakmeetup\n\n    No crap. No crab. #pivorak.\n  thumbnail_xs: \"https://i3.ytimg.com/vi/CZIZPKpsXdo/default.jpg\"\n  thumbnail_sm: \"https://i3.ytimg.com/vi/CZIZPKpsXdo/default.jpg\"\n  thumbnail_md: \"https://i3.ytimg.com/vi/CZIZPKpsXdo/mqdefault.jpg\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/CZIZPKpsXdo/hqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/CZIZPKpsXdo/hqdefault.jpg\"\n  video_provider: \"youtube\"\n  video_id: \"CZIZPKpsXdo\"\n\n- id: \"artur-hebda-pivorak-conf-10\"\n  title: \"Product Engineer - A Perfect Technical Executor For Cross Functional Teams\"\n  raw_title: \"PRODUCT ENGINEER - A PERFECT TECHNICAL EXECUTOR FOR CROSS-FUNCTIONAL TEAMS by Artur Hebda\"\n  speakers:\n    - Artur Hebda\n  event_name: \"Pivorak Conf 1.0\"\n  date: \"2018-10-26\"\n  published_at: \"2018-11-12\"\n  description: |-\n    Artur is talking about the product-code relationship.\n    When is the code good? How to maintain tech debt?\n    What is the balance between business requirements and refactoring needs?\n    He explains the Power of input, sharing some useful tips and best practices.\n    -------------------------------------\n    #pivorak is a Lviv Ruby Meetup\n\n    Join our Ruby meetups in Lviv:\n    Our official website - https://pivorak.com\n    Facebook -- https://www.facebook.com/pivorak\n    Twitter -- https://twitter.com/pivorakmeetup\n    Instagram -- https://www.instagram.com/pivorakmeetup\n\n    No crap. No crab. #pivorak.\n  thumbnail_xs: \"https://i3.ytimg.com/vi/KFWiK8addO0/default.jpg\"\n  thumbnail_sm: \"https://i3.ytimg.com/vi/KFWiK8addO0/default.jpg\"\n  thumbnail_md: \"https://i3.ytimg.com/vi/KFWiK8addO0/mqdefault.jpg\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/KFWiK8addO0/hqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/KFWiK8addO0/hqdefault.jpg\"\n  video_provider: \"youtube\"\n  video_id: \"KFWiK8addO0\"\n\n- id: \"aaron-cruz-pivorak-conf-10\"\n  title: \"How Mining Works\"\n  raw_title: \"HOW MINING WORKS by Aaron Cruz\"\n  speakers:\n    - Aaron Cruz\n  event_name: \"Pivorak Conf 1.0\"\n  date: \"2018-10-26\"\n  published_at: \"2018-11-12\"\n  description: |-\n    Aaron explains crypto mining Proof of Work using Ruby examples: the problems it solves and how it solves them. He answers the question \"Why are we using so much electricity mining crypto?\".\n    -------------------------------------\n    #pivorak is a Lviv Ruby Meetup\n\n    Join our Ruby meetups in Lviv:\n    Our official website - https://pivorak.com\n    Facebook -- https://www.facebook.com/pivorak\n    Twitter -- https://twitter.com/pivorakmeetup\n    Instagram -- https://www.instagram.com/pivorakmeetup\n\n    No crap. No crab. #pivorak.\n  thumbnail_xs: \"https://i3.ytimg.com/vi/2ShCFVIw4uI/default.jpg\"\n  thumbnail_sm: \"https://i3.ytimg.com/vi/2ShCFVIw4uI/default.jpg\"\n  thumbnail_md: \"https://i3.ytimg.com/vi/2ShCFVIw4uI/mqdefault.jpg\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/2ShCFVIw4uI/hqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/2ShCFVIw4uI/hqdefault.jpg\"\n  video_provider: \"youtube\"\n  video_id: \"2ShCFVIw4uI\"\n\n- id: \"artur-hebda-pivorak-conf-10-ow-to-migrate-to-rails-from-no\"\n  title: \"Нow To Migrate To Rails From non-Rails\"\n  raw_title: \"Нow to migrate to Rails from non-Rails by Artur Hebda & Volodya Sveredyuk\"\n  speakers:\n    - Artur Hebda\n    - Volodya Sveredyuk\n  event_name: \"Pivorak Conf 1.0\"\n  date: \"2018-10-26\"\n  published_at: \"2018-11-20\"\n  description: \"\"\n  thumbnail_xs: \"https://i3.ytimg.com/vi/-oiK8MBRtgc/default.jpg\"\n  thumbnail_sm: \"https://i3.ytimg.com/vi/-oiK8MBRtgc/default.jpg\"\n  thumbnail_md: \"https://i3.ytimg.com/vi/-oiK8MBRtgc/mqdefault.jpg\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/-oiK8MBRtgc/hqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/-oiK8MBRtgc/hqdefault.jpg\"\n  video_provider: \"youtube\"\n  video_id: \"-oiK8MBRtgc\"\n"
  },
  {
    "path": "data/pivorak/pivorak-conf-2/event.yml",
    "content": "---\nid: \"PLa4SYMEyNCu_0s6TbyKQwRGz97gYVchQM\"\ntitle: \"Pivorak Conf 2.0\"\nkind: \"conference\"\nlocation: \"Lviv, Ukraine\"\ndescription: \"\"\npublished_at: \"2019-02-01\"\nstart_date: \"2019-02-01\"\nend_date: \"2019-02-01\"\nchannel_id: \"UCPsfLdQH_0CaDIe4imm7bMA\"\nyear: 2019\nbanner_background: \"#D35130\"\nfeatured_background: \"#D35130\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 49.839683\n  longitude: 24.029717\n"
  },
  {
    "path": "data/pivorak/pivorak-conf-2/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"arto-bendiken-pivorak-conf-20\"\n  title: \"Building A Home Security System With Elixir And Nerves\"\n  raw_title: \"BUILDING A HOME SECURITY SYSTEM WITH ELIXIR AND NERVES by Arto Bendiken\"\n  speakers:\n    - Arto Bendiken\n  event_name: \"Pivorak Conf 2.0\"\n  date: \"2019-02-01\"\n  published_at: \"2019-02-28\"\n  slides_url: \"https://speakerdeck.com/arto/building-a-home-security-system-with-elixir-and-nerves\"\n  description: |-\n    Nerves is a framework for crafting bulletproof embedded software written in Elixir and deployed onto the rock-solid, nine-nines Erlang/OTP platform running directly on top of the Linux kernel.\n    Arto will show how to get started with Nerves with the motivating example of a home security system running on a Raspberry Pi. To disarm the security system, you need to step in front of the camera and give a big smile.\n    In addition to Nerves and Elixir, we will use deep learning with TensorFlow for face recognition.\n\n    Slides here -  https://speakerdeck.com/arto/building-a-home-security-system-with-elixir-and-nerves\n  video_provider: \"youtube\"\n  video_id: \"oyNSmhkS7Dw\"\n\n- id: \"iryna-zayats-pivorak-conf-20\"\n  title: \"Lightning Talk: Writing That Works\"\n  raw_title: \"Writing that works. Lightning talk by Iryna Zayats\"\n  speakers:\n    - Iryna Zayats\n  event_name: \"Pivorak Conf 2.0\"\n  date: \"2019-02-01\"\n  published_at: \"2019-02-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"xOmr51X47RA\"\n\n- id: \"bohdan-varshchuk-pivorak-conf-20\"\n  title: \"Lightning Talk: How To Keep Funds In Place - Working With Money In Fintech Apps\"\n  raw_title: \"How to keep funds in place:working with money in fintech apps.Lightning talk by Bohdan Varshchuk\"\n  speakers:\n    - Bohdan Varshchuk\n  event_name: \"Pivorak Conf 2.0\"\n  date: \"2019-02-01\"\n  published_at: \"2019-02-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"bevgYZMMzCE\"\n\n- id: \"alex-peattie-pivorak-conf-20\"\n  title: \"Ruby Us Hagrid: Writing Harry Potter With Ruby\"\n  raw_title: \"RUBY-US HAGRID: WRITING HARRY POTTER WITH RUBY by Alex Peattie\"\n  speakers:\n    - Alex Peattie\n  event_name: \"Pivorak Conf 2.0\"\n  date: \"2019-02-01\"\n  published_at: \"2019-02-28\"\n  description: |-\n    We all know that Ruby can give us superpowers, but can we use it do something truly magical - write a brand new Harry Potter completely automatically?\n    It turns out that Ruby and the dark arts of Natural Language Programming are a match made in heaven! Using some basic NLP techniques, a dash of probability, and a few lines of simple Ruby code, we can create a virtual author capable of generating a very convincing Potter pastiche. And if the life of an author’s not for you, don’t worry. In the last part of the talk, we'll explore how we can apply what we've learned to everyday coding problems.\n  video_provider: \"youtube\"\n  video_id: \"aEWMKC59HXk\"\n\n- id: \"norbert-wojtowicz-pivorak-conf-20\"\n  title: \"Domain Modeling With Datalog\"\n  raw_title: \"DOMAIN MODELING WITH DATALOG by Norbert Wojtowicz\"\n  speakers:\n    - Norbert Wojtowicz\n  event_name: \"Pivorak Conf 2.0\"\n  date: \"2019-02-01\"\n  published_at: \"2019-02-28\"\n  description: |-\n    Datalog is a declarative logic programming language, which has in recent years found new uses as a graph query language in server and client applications. This talk introduces Datalog from its primitives and builds a mental model of how complicated queries can be resolved using simple data structures. This, in turn, will help you understand when and how you should apply Datalog in practice: on the client, on the server, as a graph database, as a communication protocol ala GraphQL/Falcor, or as an event-sourcing storage mechanism.\n  video_provider: \"youtube\"\n  video_id: \"oo-7mN9WXTw\"\n"
  },
  {
    "path": "data/pivorak/pivorak-conf-3/event.yml",
    "content": "---\nid: \"PLa4SYMEyNCu-hLU4bl6xn7J7PjQ8_uzyr\"\ntitle: \"Pivorak Conf 3.0\"\nkind: \"conference\"\nlocation: \"Lviv, Ukraine\"\ndescription: \"\"\npublished_at: \"2019-05-24\"\nstart_date: \"2019-05-24\"\nend_date: \"2019-05-24\"\nchannel_id: \"UCPsfLdQH_0CaDIe4imm7bMA\"\nyear: 2019\nbanner_background: \"#D35130\"\nfeatured_background: \"#D35130\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 49.839683\n  longitude: 24.029717\n"
  },
  {
    "path": "data/pivorak/pivorak-conf-3/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"sroop-sunar-pivorak-conf-30\"\n  title: \"The Life-Changing Magic of Tidying Technical Debt\"\n  raw_title: \"The life-changing magic of tidying technical debt - Sroop Sunar\"\n  speakers:\n    - Sroop Sunar\n  event_name: \"Pivorak Conf 3.0\"\n  date: \"2019-05-24\"\n  published_at: \"2019-06-10\"\n  description: |-\n    Sroop Sunar — The life-changing magic of tidying technical debt \n\n    Contents\n\n    1:03 Marie Kondo and her books \n    3:10 “Technical debt does not spark joy”\n    3:45 The Big Ball of Mud \n    6:10 Clean code vs Tidy code\n    11:54 Applying the konmari method\n    16:08 2019 is a year if the empathetic programmer\n    17:22 \"Deleting code is good, because all code is bad\"\n    22:50 Conclusion\n    24:00 Questions and Answers\n\n    Let's chat, meet, and share our ideas via all the social media:\n\n    Join us on Facebook: https://bit.ly/2WjAgVb \n    Tweet a bit with us there: https://bit.ly/2XmndyK \n    Follow us on LinkedIn: https://bit.ly/2MmSn8j \n    Hop in some cool articles here: https://bit.ly/2IcMgOx \n    Our Instagram account:  https://bit.ly/2QDZCaf \n    Become a register member on our site and get all the benefits: https://bit.ly/313cImj\n  video_provider: \"youtube\"\n  video_id: \"vKN3v3omJqM\"\n\n- id: \"tobias-pfeiffer-pivorak-conf-30\"\n  title: \"Do You Need That Validation?\"\n  raw_title: \"Do You Need That Validation? - Tobias Pfeiffer\"\n  speakers:\n    - Tobias Pfeiffer\n  event_name: \"Pivorak Conf 3.0\"\n  date: \"2019-05-24\"\n  published_at: \"2019-06-10\"\n  description: |-\n    Tobias Pfeiffer — Do You Need That Validation? Let Me Call You Back About It\n\n    Contents\n\n    0:24 Intro about Lviv and community\n    1:41 Let's build an app to organize an event\n    3:20 Let’s write an auditory test \n    5:45 What does a smell mean? \n    7:05 Let's talk about validations\n    8:45 The example of validation: doctor’s appointment\n    12:22 How many ways are there to change in email at gitlab?\n    14:03 Why are we doing this?\n    15:17 What is Rails Affordance?\n    15:33 “Fat Models Skinny Controllers”\n    18:15 Let's take a look at a user model\n    21:30 Do you need that validation? Let me call you back about it\n    22:23 What did we identify as problems?\n    22:00 What does Rails offer to us?\n    25:40 Form Objects and Plain ActiveModel\n    29:40 Changesets\n    34:58 Separate operations and validators\n    36:57 What can you take away from all of this?\n    40:20 Alternatives\n    41:53 Q&As\n\n    Let's chat, meet, and share our ideas via all the social media:\n\n    Join us on Facebook: https://bit.ly/2WjAgVb \n    Tweet a bit with us there: https://bit.ly/2XmndyK \n    Follow us on LinkedIn: https://bit.ly/2MmSn8j \n    Hop in some cool articles here: https://bit.ly/2IcMgOx \n    Our Instagram account:  https://bit.ly/2QDZCaf \n    Become a register member on our site and get all the benefits: https://bit.ly/313cImj\n  video_provider: \"youtube\"\n  video_id: \"Bm7XpipPU9g\"\n\n- id: \"aaron-patterson-pivorak-conf-30\"\n  title: \"Compacting GC in Ruby 2.7\"\n  raw_title: \"Compacting GC in Ruby 2.7 - Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Pivorak Conf 3.0\"\n  date: \"2019-05-24\"\n  published_at: \"2019-06-10\"\n  description: |-\n    Aaron Patterson — Compacting GC in Ruby 2.7\n\n    1:15 Hugging selfie\n    1:55 #Pivorak rules are…\n    3:19 Meet the speaker\n    7:43 Java vs Ruby\n    8:34 My First Serious Ruby Program\n    12:00 Moral of the story\n    12:20 Why do I love Rails?\n    15:38 Comparing GC for MRI\n    16:26 Compaction\n    18:00 CPU Caches\n    19:30 CoW Friendliness\n    21:18 Eliminating Fragmentation\n    22:00 Two Heaps (Ruby Heap and Malloc Heap)\n    25:14 Two Finger Compaction \n    29:45 Reference Updating\n    35:10 Allowing Movements in C Extensions\n    40:18 Pure Ruby shouldn't crash\n    44:38 Don’t Use Object ID!\n    46:30 Future Plans\n    48:28 Questions?\n\n    Let's chat, meet, and share our ideas via all the social media:\n\n    Join us on Facebook: https://bit.ly/2WjAgVb \n    Tweet a bit with us there: https://bit.ly/2XmndyK \n    Follow us on LinkedIn: https://bit.ly/2MmSn8j \n    Hop in some cool articles here: https://bit.ly/2IcMgOx \n    Our Instagram account:  https://bit.ly/2QDZCaf \n    Become a register member on our site and get all the benefits: https://bit.ly/313cImj\n  video_provider: \"youtube\"\n  video_id: \"H8iWLoarTZc\"\n"
  },
  {
    "path": "data/pivorak/pivorak-conf-4/event.yml",
    "content": "---\nid: \"PLa4SYMEyNCu_hJOA1zMpCliWx5YB2a3vP\"\ntitle: \"Pivorak Conf 4.0\"\nkind: \"conference\"\nlocation: \"Lviv, Ukraine\"\ndescription: \"\"\npublished_at: \"2019-10-19\"\nstart_date: \"2019-10-18\"\nend_date: \"2019-10-18\"\nchannel_id: \"UCPsfLdQH_0CaDIe4imm7bMA\"\nyear: 2019\nbanner_background: \"#D35130\"\nfeatured_background: \"#D35130\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 49.839683\n  longitude: 24.029717\n"
  },
  {
    "path": "data/pivorak/pivorak-conf-4/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"bozhidar-batsov-pivorak-conf-40\"\n  title: \"Ruby 3.0 Redux\"\n  raw_title: \"Ruby 3.0 Redux  by Bozhidar Batsov\"\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"Pivorak Conf 4.0\"\n  date: \"2019-10-19\"\n  published_at: \"2019-10-30\"\n  description: |-\n    For several years now Rubyists around the world have been fascinated by the plans for the next big Ruby release - namely Ruby 3.0. While a lot has been said about 3.0, there’s also a lot of confusion about it - the scope, the timeline,  backwards compatibility, etc.\n\n    This talk is an attempt to summarize everything that’s currently known about Ruby 3.0 and present it into an easily digestible format.\n  video_provider: \"youtube\"\n  video_id: \"BkExJYj0T0c\"\n\n- id: \"roman-dubrovsky-pivorak-conf-40\"\n  title: \"Life With GraphQL API: Good Practices And Unresolved Issues\"\n  raw_title: \"Life with GraphQL API: good practices and unresolved issues by Roman Dubrovsky\"\n  speakers:\n    - Roman Dubrovsky\n  event_name: \"Pivorak Conf 4.0\"\n  date: \"2019-10-19\"\n  published_at: \"2019-10-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ni0ZSeRoYq8\"\n\n- id: \"oleksiy-vasyliev-pivorak-conf-40\"\n  title: \"Serverless Use Cases For Web Projects\"\n  raw_title: \"Serverless use cases for Web projects by Oleksiy Vasyliev\"\n  speakers:\n    - Oleksiy Vasyliev\n  event_name: \"Pivorak Conf 4.0\"\n  date: \"2019-10-19\"\n  published_at: \"2019-10-30\"\n  description: |-\n    Serverless is very interesting technology, which provides for developer ability to execute a piece of code by dynamically allocating the resources in a cloud. But how exactly it can help you for web development? Wouldn't it be too expensive? Let's look at the practical use cases in this talk.\n  video_provider: \"youtube\"\n  video_id: \"PGvVglTLQv8\"\n\n- id: \"denys-medynskyi-pivorak-conf-40\"\n  title: \"Reliable Engineer: From Production Breaker To Enterprise Maker\"\n  raw_title: \"Reliable engineer: from production breaker to enterprise maker by Denys Medynskyi\"\n  speakers:\n    - Denys Medynskyi\n  event_name: \"Pivorak Conf 4.0\"\n  date: \"2019-10-19\"\n  published_at: \"2019-10-30\"\n  description: |-\n    What makes developer reliable? I will tell you about my own fuck-ups that forced me to change myself into a reliable developer. Also, what are the common mistakes and how we can prevent them. At the end of the talk, I want you to raise the bar of software quality.\n  video_provider: \"youtube\"\n  video_id: \"c250fs7Ybxw\"\n"
  },
  {
    "path": "data/pivorak/pivorak-conf-5/event.yml",
    "content": "---\nid: \"PLa4SYMEyNCu86K63M_slCEVVNTc1QAUWm\"\ntitle: \"Pivorak Conf 5.0\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: \"\"\npublished_at: \"2020-05-22\"\nstart_date: \"2020-05-22\"\nend_date: \"2020-05-22\"\nchannel_id: \"UCPsfLdQH_0CaDIe4imm7bMA\"\nyear: 2020\nbanner_background: \"#D35130\"\nfeatured_background: \"#D35130\"\nfeatured_color: \"#FFFFFF\"\ncoordinates: false\n"
  },
  {
    "path": "data/pivorak/pivorak-conf-5/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"jeremy-evans-pivorak-conf-50\"\n  title: \"Rodauth 2.0\"\n  raw_title: \"Rodauth 2.0 by Jeremy Evans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"Pivorak Conf 5.0\"\n  date: \"2020-05-22\"\n  published_at: \"2020-05-28\"\n  description: |-\n    Rodauth is Ruby's most advanced authentication framework, designed to work in any rack application”\n\n    Latest release adds WebAuthn support for MFA/passwordless auth, active_sessions feature allowing global logout, audit_logging feature, now fully translatable.\n\n    In this talk, Jeremy will guide you through all the new features!\n\n    Jeremy is a Ruby Committer. OpenBSD ruby ports maintainer. Lead developer of Sequel, Roda, and Rodauth.\n  thumbnail_xs: \"https://i3.ytimg.com/vi/5rjjCZmbB6c/default.jpg\"\n  thumbnail_sm: \"https://i3.ytimg.com/vi/5rjjCZmbB6c/default.jpg\"\n  thumbnail_md: \"https://i3.ytimg.com/vi/5rjjCZmbB6c/mqdefault.jpg\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/5rjjCZmbB6c/hqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/5rjjCZmbB6c/hqdefault.jpg\"\n  video_provider: \"youtube\"\n  video_id: \"5rjjCZmbB6c\"\n\n- id: \"cameron-dutro-pivorak-conf-50\"\n  title: \"Convention over Kubernetes: (Almost) Configless Deploys\"\n  raw_title: \"Convention over Kubernetes: (almost) configless deploys by Cameron Dutro\"\n  speakers:\n    - Cameron Dutro\n  event_name: \"Pivorak Conf 5.0\"\n  date: \"2020-05-22\"\n  published_at: \"2020-05-28\"\n  description: |-\n    Kubernetes has taken the ops world by storm. But for many, however, the learning curve is steep. Even a standard Rails app requires gobs of dense YAML configuration.\n\n    Wouldn't it be great if you, a humble Rails developer, could take advantage of this awesome technology?\n    Well now you can!\n\n    Come learn how, with almost no configuration, you too can leverage Kubernetes to deploy your Rails app cost-effectively on a variety of cloud platforms.\n\n    Cameron is the author of a number of rubygems, including TwitterCLDR, arel-helpers, and gelauto. He also wrote and still maintain Scuttle, a SQL to activerecord/arel converter.\n\n    Cameron works for Lumos Labs on the Core/Platform team, but going to be working for Quip starting June 15th. Previously, he worked for Twitter on the Twitter Translation Center!\n  thumbnail_xs: \"https://i3.ytimg.com/vi/nJqtItsC9qs/default.jpg\"\n  thumbnail_sm: \"https://i3.ytimg.com/vi/nJqtItsC9qs/default.jpg\"\n  thumbnail_md: \"https://i3.ytimg.com/vi/nJqtItsC9qs/mqdefault.jpg\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/nJqtItsC9qs/hqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/nJqtItsC9qs/hqdefault.jpg\"\n  video_provider: \"youtube\"\n  video_id: \"nJqtItsC9qs\"\n\n- id: \"luca-guidi-pivorak-conf-50\"\n  title: \"Hanami::API\"\n  raw_title: \"Hanami :: API by Luca Guidi\"\n  speakers:\n    - Luca Guidi\n  event_name: \"Pivorak Conf 5.0\"\n  date: \"2020-05-22\"\n  published_at: \"2020-05-28\"\n  description: |-\n    Hanami is a full-stack web framework for Ruby. With Luca we will learn what will be the major changes for 2.0 release.\n\n    Luca is the creator of Hanami and author of redis-store. Also a dry_rb core team member.\n\n    He also works as Back-end Architect at Toptal to envision a SOA architecture for the company.\n  thumbnail_xs: \"https://i3.ytimg.com/vi/tbyT-zhYMd4/default.jpg\"\n  thumbnail_sm: \"https://i3.ytimg.com/vi/tbyT-zhYMd4/default.jpg\"\n  thumbnail_md: \"https://i3.ytimg.com/vi/tbyT-zhYMd4/mqdefault.jpg\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/tbyT-zhYMd4/hqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/tbyT-zhYMd4/hqdefault.jpg\"\n  video_provider: \"youtube\"\n  video_id: \"tbyT-zhYMd4\"\n"
  },
  {
    "path": "data/pivorak/series.yml",
    "content": "---\nname: \"Pivorak Lviv Ruby Meetup\"\nwebsite: \"https://pivorak.com\"\ntwitter: \"pivorakmeetup\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Pivorak Conf\"\ndefault_country_code: \"UA\"\nyoutube_channel_name: \"pivorakLvivRubyMeetUp\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCPsfLdQH_0CaDIe4imm7bMA\"\n"
  },
  {
    "path": "data/polishrubyusergroup/ruby-warsaw-meetup/event.yml",
    "content": "---\nid: \"ruby-warsaw-meetup\"\ntitle: \"Ruby Warsaw Meetup\"\nkind: \"meetup\"\nlocation: \"Warsaw, Poland\"\ndescription: |-\n  Polish Ruby User Group (PLRUG)\npublished_at: \"2025-01-23\"\nwebsite: \"https://www.meetup.com/polishrubyusergroup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#E83531\"\ncoordinates:\n  latitude: 52.2296756\n  longitude: 21.0122287\n"
  },
  {
    "path": "data/polishrubyusergroup/ruby-warsaw-meetup/videos.yml",
    "content": "---\n# 2023\n\n- id: \"ruby-warsaw-meetup-december-2023\"\n  title: \"Ruby Warsaw Meetup December 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-04-20\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-december-2023\"\n  description: |-\n    We invite you to the last PLRUG Ruby Warsaw Meetup of this year. We'll meet on December 19th at the Visuality office.\n\n    Let's say goodbye to this year with a bang!\n\n    AGENDA:\n\n    🎙️ Illia Zub - When counting lines in Ruby randomly failed our deployments\n    🎙️ Tomasz Jóźwik - Programowanie matematyczne w Ruby\n    🎙️ Miron Marczuk - Christmas Rubying - Ruby gifts discovered during Advent of Code\n\n    Lightning Talk:\n    🎙️ Piotr Witek - Parameter Conflicts in Rails: URL vs. Body\n\n    After the meeting, there will be time for conversation, and who knows... maybe we'll even hear some Christmas carols.🎄🧑‍🎄 Join us!\n\n    Big thanks for this year! 🙌\n\n    https://www.meetup.com/polishrubyusergroup/events/297771313\n  talks:\n    - title: \"When counting lines in Ruby randomly failed our deployments\"\n      speakers:\n        - Illia Zub\n      event_name: \"Ruby Warsaw Meetup December 2023\"\n      date: \"2023-12-19\"\n      published_at: \"2024-04-20\"\n      video_provider: \"not_recorded\"\n      id: \"illia-zub-ruby-warsaw-meetup-december-2023\"\n      video_id: \"illia-zub-ruby-warsaw-meetup-december-2023\"\n\n    - title: \"Programowanie matematyczne w Ruby\"\n      speakers:\n        - Tomasz Jóźwik\n      event_name: \"Ruby Warsaw Meetup December 2023\"\n      date: \"2023-12-19\"\n      published_at: \"2024-04-20\"\n      video_provider: \"not_recorded\"\n      id: \"tomasz-jozwik-ruby-warsaw-meetup-december-2023\"\n      video_id: \"tomasz-jozwik-ruby-warsaw-meetup-december-2023\"\n      language: \"polish\"\n\n    - title: \"Christmas Rubying - Ruby gifts discovered during Advent of Code\"\n      speakers:\n        - Miron Marczuk\n      event_name: \"Ruby Warsaw Meetup December 2023\"\n      date: \"2023-12-19\"\n      published_at: \"2024-04-20\"\n      video_provider: \"not_recorded\"\n      id: \"miron-marczuk-ruby-warsaw-meetup-december-2023\"\n      video_id: \"miron-marczuk-ruby-warsaw-meetup-december-2023\"\n\n    - title: \"Lightning Talk: Parameter Conflicts in Rails: URL vs. Body\"\n      speakers:\n        - Piotr Witek\n      event_name: \"Ruby Warsaw Meetup December 2023\"\n      date: \"2023-12-19\"\n      published_at: \"2024-04-20\"\n      video_provider: \"youtube\"\n      id: \"piotr-witek-ruby-warsaw-meetup-december-2023\"\n      video_id: \"PzHOxYAJIWI\"\n      description: |-\n        This is a lightning talk about fighting a bug that occurs due to conflicting parameters passed in the URL and in the body. The lightning talk was given at the PLRUG Meetup @Visualitypl on December 19, 2023.\n\n        Here is the code that is overriding body params with url params:\n        https://github.com/rails/rails/blob/b7520a13adda46c0cc5f3fb4a4c1726633af2bba/actionpack/lib/action_dispatch/http/parameters.rb#L52\n      additional_resources:\n        - name: \"code that is overriding body params with url params\"\n          type: \"code\"\n          url: \"https://github.com/rails/rails/blob/b7520a13adda46c0cc5f3fb4a4c1726633af2bba/actionpack/lib/action_dispatch/http/parameters.rb#L52\"\n\n# 2024\n\n- id: \"ruby-warsaw-meetup-february-2024\"\n  title: \"Ruby Warsaw Meetup February 2024\"\n  date: \"2024-02-29\"\n  published_at: \"2024-03-11\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-february-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/5/3/b/3/600_519141427.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/5/3/b/3/600_519141427.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/5/3/b/3/600_519141427.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/5/3/b/3/600_519141427.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/5/3/b/3/600_519141427.webp?w=750\"\n  description: |-\n    Hi people!\n    See you on February 29th at the next PLRUG Warsaw meetup at the Visuality office. We're starting at 6:00 PM!\n\n    AGENDA:\n\n    ✔️ Illia Zub - Math and Web Scraping\n    ✔️ Mateusz Woźniczka - Pokedex - indexes strike back\n    ✔️ Piotr Wald - Resilient deployment on Amazon ECS\n\n    As usual, after the meetup, there will be time for conversations and networking. 🗣️🍻🍕\n    Who are we meeting with?\n\n  talks:\n    - title: \"Math and Web Scraping\"\n      speakers:\n        - Illia Zub\n      event_name: \"Ruby Warsaw Meetup February 2024\"\n      date: \"2024-02-29\"\n      published_at: \"2024-03-11\"\n      video_provider: \"youtube\"\n      id: \"illia-zub-ruby-warsaw-meetup-february-2024\"\n      video_id: \"FWN0tD6lnYw\"\n\n    - title: \"Pokedex - indexes strike back\"\n      speakers:\n        - Mateusz Woźniczka\n      event_name: \"Ruby Warsaw Meetup February 2024\"\n      date: \"2024-02-29\"\n      published_at: \"2024-03-11\"\n      video_provider: \"youtube\"\n      id: \"mateusz-woniczka-ruby-warsaw-meetup-february-2024\"\n      video_id: \"oOZv7DywW68\"\n\n    - title: \"Resilient deployment on Amazon ECS\"\n      speakers:\n        - Piotr Wald\n      event_name: \"Ruby Warsaw Meetup February 2024\"\n      date: \"2024-02-29\"\n      published_at: \"2024-03-11\"\n      video_provider: \"youtube\"\n      id: \"piotr-wald-ruby-warsaw-meetup-february-2024\"\n      video_id: \"rfzi5Cy2gGA\"\n\n- id: \"ruby-warsaw-meetup-march-2024\"\n  title: \"Ruby Warsaw Meetup March 2024\"\n  date: \"2024-03-21\"\n  published_at: \"2024-04-02\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-march-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/8/b/a/5/600_519695749.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/8/b/a/5/600_519695749.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/8/b/a/5/600_519695749.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/8/b/a/5/600_519695749.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/8/b/a/5/600_519695749.webp?w=750\"\n  description: |-\n    Hey there, Ruby on Rails enthusiasts! 💎\n    We are pleased to invite you to the upcoming PLRUG meetup #March!\n\n    📍Warsaw, ul. Odolańska 56, Visuality office\n    📆 18:00, March 21, 2024\n\n    What's on the agenda?\n\n    🔥Rostislav Zhuravsky - Sweet dreams with statically typed Ruby\n    🔥Michał Łęcicki - Showing progress of background jobs with Turbo\n    🔥Jakub Godawa - Petrol Station Simulator in Ruby\n    🔥Lightning talks\n\n    🔥NETWORKING!\n\n    Visit our Discord and join the Ruby community: https://discord.gg/qQV74zpg\n\n    The event is free! We look forward to seeing you there!🚀\n\n  talks:\n    - title: \"Sweet dreams with statically typed Ruby\"\n      speakers:\n        - Rostislav Zhuravsky\n      event_name: \"Ruby Warsaw Meetup March 2024\"\n      date: \"2024-03-21\"\n      published_at: \"2024-04-02\"\n      video_provider: \"youtube\"\n      id: \"rostislav-zhuravsky-ruby-warsaw-meetup-march-2024\"\n      video_id: \"15yZl_s83yI\"\n\n    - title: \"Showing progress of background jobs with Turbo\"\n      speakers:\n        - Michał Łęcicki\n      event_name: \"Ruby Warsaw Meetup March 2024\"\n      date: \"2024-03-21\"\n      published_at: \"2024-04-02\"\n      video_provider: \"youtube\"\n      id: \"micha-lcicki-ruby-warsaw-meetup-march-2024\"\n      video_id: \"t5GN2mMX3Fs\"\n\n    - title: \"Petrol Station Simulator in Ruby\"\n      speakers:\n        - Jakub Godawa\n      event_name: \"Ruby Warsaw Meetup March 2024\"\n      date: \"2024-03-21\"\n      published_at: \"2024-04-02\"\n      video_provider: \"youtube\"\n      id: \"jakub-godawa-ruby-warsaw-meetup-march-2024\"\n      video_id: \"mim5Mjq8T_0\"\n\n    - title: \"Lightning Talks\"\n      speakers:\n        - TODO\n      event_name: \"Ruby Warsaw Meetup March 2024\"\n      date: \"2024-03-21\"\n      published_at: \"\"\n      video_provider: \"not_recorded\"\n      id: \"lightning-talks-ruby-warsaw-meetup-march-2024\"\n      video_id: \"lightning-talks-ruby-warsaw-meetup-march-2024\"\n\n- id: \"ruby-warsaw-meetup-april-2024\"\n  title: \"Ruby Warsaw Meetup April 2024\"\n  date: \"2024-04-18\"\n  published_at: \"2024-04-24\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-april-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/b/f/6/600_520308118.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/b/f/6/600_520308118.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/b/f/6/600_520308118.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/b/f/6/600_520308118.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/b/f/6/600_520308118.webp?w=750\"\n  description: |-\n    Join us for the #April PLRUG Ruby Warsaw meetup!\n    This time the event promises to be exceptionally interesting! This time, Rafał Piekara vel Gruby Kodzi and Tomasz Stachewicz, the founder of WRUG, will visit us. Are you ready for this meeting?\n\n    📆 18.04.20024\n    ⏰ 18:00\n    📍Visuality office\n\n    Agenda\n\n    🎙️Rafał Piekara - There is no f**ck in refactoring!\n    🎙️Tomasz Stachewicz - SQLite: it's not a toy anymore. Tooling and scope for SQLite in production Rails applications.\n    🎙️TBA\n    🔥networking!\n\n    Meetup is sponsored by Softswiss and Prowly.\n    After a substantial dose of knowledge, we invite you to engage in discussions during the informal part. Hope to see you there!\n\n    https://www.meetup.com/polishrubyusergroup/events/300326352\n\n  talks:\n    - title: \"There is no f**ck in refactoring!\"\n      speakers:\n        - Rafał Piekara\n      event_name: \"Ruby Warsaw Meetup April 2024\"\n      date: \"2024-04-18\"\n      published_at: \"2024-04-24\"\n      video_provider: \"youtube\"\n      id: \"rafa-piekara-ruby-warsaw-meetup-april-2024\"\n      video_id: \"4iRxWraBimQ\"\n\n    - title: \"SQLite: it's not a toy anymore. Tooling and scope for SQLite in production Rails applications.\"\n      speakers:\n        - Tomasz Stachewicz\n      event_name: \"Ruby Warsaw Meetup April 2024\"\n      date: \"2024-04-18\"\n      published_at: \"2024-04-24\"\n      video_provider: \"youtube\"\n      id: \"tomasz-stachewicz-ruby-warsaw-meetup-april-2024\"\n      video_id: \"0vBCu8MEZD4\"\n\n    - title: \"TBA\"\n      speakers:\n        - TODO\n      event_name: \"Ruby Warsaw Meetup April 2024\"\n      date: \"2024-04-18\"\n      published_at: \"\"\n      video_provider: \"not_published\"\n      id: \"tba-ruby-warsaw-meetup-april-2024\"\n      video_id: \"tba-ruby-warsaw-meetup-april-2024\"\n\n- id: \"ruby-warsaw-meetup-may-2024\"\n  title: \"Ruby Warsaw Meetup May 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-05-23\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-may-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/d/a/4/b/600_520915883.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/d/a/4/b/600_520915883.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/d/a/4/b/600_520915883.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/d/a/4/b/600_520915883.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/d/a/4/b/600_520915883.webp?w=750\"\n  description: |-\n    Ready for the Ruby Warsaw Meetup #May? See you next week, as usual, on the third Thursday of the month!\n\n    📆 16.05.20024\n    ⏰ 18:00\n    📍Visuality office\n\n    Agenda\n\n    🎙️Bartosz Blimke - Webmock unmocked\n    🎙️How to check security of a Ruby on Rails app? - panel discussion conducted by Paweł Strzałkowski\n    🔥networking!\n\n    Meetup is sponsored by Prowly!\n    After the official part, we invite you to stay for further discussions in a more relaxed atmosphere. It's time to start the garden season⛱️☀️\n\n    https://www.meetup.com/polishrubyusergroup/events/300877678\n  talks:\n    - title: \"Webmock unmocked\"\n      speakers:\n        - Bartosz Blimke\n      event_name: \"Ruby Warsaw Meetup May 2024\"\n      date: \"2024-05-16\"\n      published_at: \"2024-05-23\"\n      video_provider: \"youtube\"\n      id: \"bartosz-blimke-ruby-warsaw-meetup-may-2024\"\n      video_id: \"rCvhGiebfK4\"\n\n    - title: \"Panel: How to Check Security of a Ruby on Rails App?\"\n      speakers:\n        - Paweł Strzałkowski\n      event_name: \"Ruby Warsaw Meetup May 2024\"\n      date: \"2024-05-16\"\n      published_at: \"2024-05-23\"\n      video_provider: \"youtube\"\n      id: \"pawe-strzakowski-ruby-warsaw-meetup-may-2024\"\n      video_id: \"Pv25FaAOAsI\"\n\n- id: \"ruby-warsaw-meetup-june-2024\"\n  title: \"Ruby Warsaw Meetup June 2024\"\n  date: \"2024-06-20\"\n  published_at: \"2024-06-28\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-june-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/d/7/f/1/600_521515281.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/d/7/f/1/600_521515281.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/d/7/f/1/600_521515281.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/d/7/f/1/600_521515281.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/d/7/f/1/600_521515281.webp?w=750\"\n  description: |-\n    Hello June!\n    We will meet again at the next PLRUG meetup on June 20th, as usual at 6 PM in the Visuality office.\n\n    What's on the agenda this time? 🤔\n\n    ✔️ Grzegorz Piwowarek - Embracing Microservices\n    ✔️ Andrei Kaleshka - ActualDbSchema: The creation story and purpose\n    ✔️ Artur Hebda - Training people & knowledge sharing\n\n    After the official part, as always during the summer season, we invite you to a barbecue and networking in our garden. 🥩🍆🏡\n\n    https://www.meetup.com/polishrubyusergroup/events/301436824\n  talks:\n    - title: \"Embracing Microservices\"\n      speakers:\n        - Grzegorz Piwowarek\n      event_name: \"Ruby Warsaw Meetup June 2024\"\n      date: \"2024-06-20\"\n      published_at: \"2024-06-28\"\n      video_provider: \"youtube\"\n      id: \"grzegorz-piwowarek-ruby-warsaw-meetup-june-2024\"\n      video_id: \"kY5p7sajX1k\"\n\n    - title: \"ActualDbSchema: The creation story and purpose\"\n      speakers:\n        - Andrei Kaleshka\n      event_name: \"Ruby Warsaw Meetup June 2024\"\n      date: \"2024-06-20\"\n      published_at: \"2024-06-28\"\n      video_provider: \"youtube\"\n      id: \"andrei-kaleshka-ruby-warsaw-meetup-june-2024\"\n      video_id: \"ie3i2tsDjS8\"\n\n    - title: \"Training People & Knowledge Sharing\"\n      speakers:\n        - Artur Hebda\n      event_name: \"Ruby Warsaw Meetup June 2024\"\n      date: \"2024-06-20\"\n      published_at: \"2024-06-28\"\n      video_provider: \"youtube\"\n      id: \"artur-hebda-ruby-warsaw-meetup-june-2024\"\n      video_id: \"Z1ANDo24ABo\"\n\n- id: \"ruby-warsaw-meetup-august-2024\"\n  title: \"Ruby Warsaw Meetup August 2024\"\n  date: \"2024-08-22\"\n  published_at: \"2024-09-20\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-august-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/6/c/1/600_522878593.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/6/c/1/600_522878593.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/6/c/1/600_522878593.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/6/c/1/600_522878593.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/6/c/1/600_522878593.webp?w=750\"\n  description: |-\n    Hi there!\n\n    The dust from the July Ruby Warsaw Community Conference is slowly settling, and we're returning to our tradition of meetups. Our last summer meeting is ahead of us. Let's meet on August 22, 2024, at 6:00 PM.\n\n    What will we hear about this time?\n\n    🎤 Sergy Sergyenko - How to run local AI model and connect it to Ruby application\n    🎤 Illia Zub - Enhance your health at work: boost concentration, productivity & wellbeing\n    🎤 TBA\n\n    After the meetup, there will be time for more relaxed discussions in the garden, with a barbecue and drinks, as usual. 🍻🍗\n    See you there! 🙌\n\n    https://www.meetup.com/polishrubyusergroup/events/302785548\n  talks:\n    - title: \"How to run local AI model and connect it to Ruby application\"\n      speakers:\n        - Sergy Sergyenko\n      event_name: \"Ruby Warsaw Meetup August 2024\"\n      date: \"2024-08-22\"\n      published_at: \"2024-09-20\"\n      video_provider: \"youtube\"\n      id: \"sergy-sergyenko-ruby-warsaw-meetup-august-2024\"\n      video_id: \"23q2IzGbvh4\"\n\n    - title: \"Enhance your health at work: boost concentration, productivity & wellbeing\"\n      speakers:\n        - Illia Zub\n      event_name: \"Ruby Warsaw Meetup August 2024\"\n      date: \"2024-08-22\"\n      published_at: \"\"\n      video_provider: \"not_published\"\n      id: \"illia-zub-ruby-warsaw-meetup-august-2024\"\n      video_id: \"illia-zub-ruby-warsaw-meetup-august-2024\"\n\n    - title: \"TBA\"\n      speakers:\n        - TODO\n      event_name: \"Ruby Warsaw Meetup August 2024\"\n      date: \"2024-08-22\"\n      published_at: \"\"\n      video_provider: \"not_published\"\n      id: \"tba-ruby-warsaw-meetup-august-2024\"\n      video_id: \"tba-ruby-warsaw-meetup-august-2024\"\n\n- id: \"ruby-warsaw-meetup-september-2024\"\n  title: \"Ruby Warsaw Meetup September 2024\"\n  date: \"2024-09-19\"\n  published_at: \"2024-09-30\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-september-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/5/4/e/f/600_523281743.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/5/4/e/f/600_523281743.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/5/4/e/f/600_523281743.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/5/4/e/f/600_523281743.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/5/4/e/f/600_523281743.webp?w=750\"\n  description: |-\n    Join us for the next September PLRUG Ruby Warsaw Meetup!\n\n    📆 19.09.2024\n    ⏰ 18:00\n    📍 Odolańska 56, Visuality office\n\n    This time, the presentation topics will be very diverse. What's on the agenda?\n\n    🎤 Barnaba Siegel - 28 lat CD-Action. Jak oldschoolowe medium radzi sobie wobec technologicznego postępu?\n    🎤 Tomasz Stachewicz - Self-hosting and Homelab in 2024\n    🎤 Urszula Sołogub - AI-assisted data extraction\n\n    Be sure to come and join our community! We especially encourage those who have been quietly following us to join us.\n\n    After the official part, as always, we encourage you to stay and get to know each other better.🗣️\n\n    Language notice: One of the presentations will be in Polish.🇵🇱\n\n    https://www.meetup.com/polishrubyusergroup/events/303197441\n  talks:\n    - title: \"28 lat CD-Action. Jak oldschoolowe medium radzi sobie wobec technologicznego postępu?\"\n      speakers:\n        - Barnaba Siegel\n      event_name: \"Ruby Warsaw Meetup September 2024\"\n      date: \"2024-09-19\"\n      published_at: \"2024-09-30\"\n      video_provider: \"youtube\"\n      id: \"barnaba-siegel-ruby-warsaw-meetup-september-2024\"\n      video_id: \"mlLGFyhm53Y\"\n      language: \"polish\"\n\n    - title: \"Self-hosting and Homelab in 2024\"\n      speakers:\n        - Tomasz Stachewicz\n      event_name: \"Ruby Warsaw Meetup September 2024\"\n      date: \"2024-09-19\"\n      published_at: \"2024-09-30\"\n      video_provider: \"youtube\"\n      id: \"tomasz-stachewicz-ruby-warsaw-meetup-september-2024\"\n      video_id: \"MRdiUBEzRKQ\"\n      language: \"english\"\n\n    - title: \"AI-assisted data extraction\"\n      speakers:\n        - Urszula Sołogub\n      event_name: \"Ruby Warsaw Meetup September 2024\"\n      date: \"2024-09-19\"\n      published_at: \"2024-09-30\"\n      video_provider: \"youtube\"\n      id: \"urszula-soogub-ruby-warsaw-meetup-september-2024\"\n      video_id: \"Y7GYO-RdyMk\"\n      language: \"english\"\n\n- id: \"ruby-warsaw-meetup-october-2024\"\n  title: \"Ruby Warsaw Meetup October 2024\"\n  date: \"2024-10-17\"\n  published_at: \"2024-10-29\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-october-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/4/8/0/600_523697536.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/4/8/0/600_523697536.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/4/8/0/600_523697536.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/4/8/0/600_523697536.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/4/8/0/600_523697536.webp?w=750\"\n  description: |-\n    This has never happened before!\n\n    On October 17th, join us for a groundbreaking PLRUG Ruby Warsaw Meetup dedicated entirely to AI.\n    We are thrilled to invite you to this unique event!\n\n    What makes this event so special? For the very first time, PLRUG is stepping outside the Visuality office. That's right! We'll be gathering at an exciting new venue that promises to inspire and engage.\n\n    📆 17.10.2024\n    ⏰ 18:00\n    📍 Browary Warszawskie, Budynek GH, wejście B.\n    ul. Grzybowska 56\n\n    Speakers:\n\n    🎤 Paweł Strzałkowski - My LLM is smarter than yours - How to build RAG applications and a guide to using embeddings\n    🎤 Chris Hasiński - Next token! (Or how to work with LLMs)\n    🎤 Sergy Sergyenko - How to integrate on premise LLM model with your application\n    🎤 W. Landon Gray - The Missing Piece: Effective Tooling for Building Robust AI and Data Science Applications in Ruby\n\n    IMPORTANT CHANGE\n    Unfortunately this time we will not have the pleasure of hosting Katarzyna Hewelt with the topic \"AI Agents: A Guide to Building Custom Chatbots\" but we hope we can make up for it in the future!\n\n    Please make sure to save the date in your calendar and confirm your attendance. The number of spots is limited, and we are counting on your presence!\n\n    We hope to see you at the afterparty at Browary Warszawskie after the event! 🍻\n\n    https://www.meetup.com/polishrubyusergroup/events/303621402\n\n  talks:\n    - title: \"My LLM is smarter than yours - How to build RAG applications and a guide to using embeddings\"\n      speakers:\n        - Paweł Strzałkowski\n      event_name: \"Ruby Warsaw Meetup October 2024\"\n      date: \"2024-10-17\"\n      published_at: \"2024-10-29\"\n      video_provider: \"youtube\"\n      id: \"pawe-strzakowski-ruby-warsaw-meetup-october-2024\"\n      video_id: \"KxGZv7Z4BQs\"\n\n    - title: \"Next token! (Or how to work with LLMs)\"\n      speakers:\n        - Chris Hasiński\n      event_name: \"Ruby Warsaw Meetup October 2024\"\n      date: \"2024-10-17\"\n      published_at: \"2024-10-29\"\n      video_provider: \"youtube\"\n      id: \"chris-hasiski-ruby-warsaw-meetup-october-2024\"\n      video_id: \"-pjS3osRRqo\"\n\n    - title: \"How to integrate on premise LLM model with your application\"\n      speakers:\n        - Sergy Sergyenko\n      event_name: \"Ruby Warsaw Meetup October 2024\"\n      date: \"2024-10-17\"\n      published_at: \"\"\n      video_provider: \"not_published\"\n      id: \"sergey-sergyenko-ruby-warsaw-meetup-october-2024\"\n      video_id: \"sergey-sergyenko-ruby-warsaw-meetup-october-2024\"\n\n    - title: \"The Missing Piece: Effective Tooling for Building Robust AI and Data Science Applications in Ruby\"\n      speakers:\n        - Landon Gray\n      event_name: \"Ruby Warsaw Meetup October 2024\"\n      date: \"2024-10-17\"\n      published_at: \"2024-10-29\"\n      video_provider: \"youtube\"\n      id: \"landon-gray-ruby-warsaw-meetup-october-2024\"\n      video_id: \"LxvMm59uB3A\"\n\n# 2025\n\n- id: \"ruby-warsaw-meetup-january-2025\"\n  title: \"Ruby Warsaw Meetup January 2025\"\n  raw_title: \"Polish Ruby User Group (PLRUG) Warsaw Meetup January 2025\"\n  event_name: \"Ruby Warsaw Meetup January 2025\"\n  date: \"2025-01-23\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-january-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/d/9/d/7/600_525715767.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/d/9/d/7/600_525715767.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/d/9/d/7/600_525715767.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/d/9/d/7/600_525715767.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/d/9/d/7/600_525715767.webp?w=750\"\n  description: |-\n    Join us for the first PLRUG Ruby Warsaw Meetup in 2025! 🚀\n\n    📆 23.01.2025\n    ⏰ 18:00\n    📍 Odolańska 56, Visuality office\n\n    What's on the agenda?\n\n    🎤 Piotr Szotkowski - Fantastic Tests and How to Write Them\n    🌩️ LIGHTNING TALKS!\n\n    Whether you're looking to learn, network, or simply have a great time with like-minded people, this is the place to be!\n\n    After the official part, there will be time for more relaxed discussions with drinks and pizza 🍕\n\n    https://www.meetup.com/polishrubyusergroup/events/305606762/\n  talks:\n    - title: \"Fantastic Tests and How to Write Them\"\n      speakers:\n        - Piotr Szotkowski\n      event_name: \"Polish Ruby User Group (PLRUG) Warsaw Meetup January 2025\"\n      date: \"2025-01-23\"\n      published_at: \"2025-03-17\"\n      video_provider: \"youtube\"\n      video_id: \"QV5eYU82U0k\"\n      id: \"fantastic-tests-and-how-to-write-them-ruby-warsaw-meetup-january-2025\"\n      slides_url: \"https://talks.chastell.net/plrug-2025-01\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/Ghu9z53XUAA8aMe?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/Ghu9z53XUAA8aMe?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/mraedia/Ghu9z53XUAA8aMe?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/Ghu9z53XUAA8aMe?format=jpg&name=4096x4096\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/Ghu9z53XUAA8aMe?format=jpg&name=4096x4096\"\n      description: \"\"\n\n    - title: \"Lightning Talks\"\n      speakers:\n        - TODO\n      event_name: \"Polish Ruby User Group (PLRUG) Warsaw Meetup January 2025\"\n      date: \"2025-01-23\"\n      published_at: \"\"\n      video_provider: \"not_published\"\n      id: \"lightning-talks-ruby-warsaw-meetup-january-2025\"\n      video_id: \"lightning-talks-ruby-warsaw-meetup-january-2025\"\n\n- id: \"ruby-warsaw-meetup-march-2025\"\n  title: \"Ruby Warsaw Meetup March 2025\"\n  raw_title: \"Polish Ruby User Group (PLRUG) Warsaw Meetup #March\"\n  event_name: \"Ruby Warsaw Meetup March 2025\"\n  date: \"2025-03-20\"\n  published_at: \"2025-04-07\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-march-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/9/0/a/highres_526719178.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/9/0/a/highres_526719178.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/9/0/a/highres_526719178.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/9/0/a/highres_526719178.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/9/0/a/highres_526719178.webp?w=750\"\n  description: |-\n    PLRUG Ruby Warsaw Meetup March - The Last One at Odolańska 56!\n\n    After a short break in February (due to our full focus on organizing Ruby Community Conference), we're back with the March edition of PLRUG! 🚀\n\n    This meetup is going to be a special one - it will be our last event at our current office on Odolańska 56.\n\n    At the end of March, we're moving to a new space, so this is a great chance to say goodbye to a place that has hosted so many amazing Ruby meetups over the years.\n\n    Join us on March 20th at 18:00 for a great evening of Ruby talks, discussions, and networking. Speaker lineup and agenda - TBA. Stay tuned!\n\n    📍 Location: Odolańska 56, Warsaw\n    ⏰ Time: 18:00\n    💬 Miron Marczuk - \"Real-time Analytics in Rails - Mission Impossible?\"\n    💬 Justyna Wojtczak - \"MultiVector Search czyli jak opanować chaos\"\n    🌩️ Lightning Talks!\n\n    Don't miss out - let's give our office a proper Ruby send-off! ❤️\n\n    Language notice: One of the presentations will be in Polish.🇵🇱\n  talks:\n    - title: \"Real-time Analytics in Rails - Mission Impossible?\"\n      speakers:\n        - Miron Marczuk\n      event_name: \"Ruby Warsaw Meetup March 2025\"\n      date: \"2025-03-20\"\n      published_at: \"2025-04-07\"\n      video_provider: \"youtube\"\n      id: \"miron-marczuk-ruby-warsaw-meetup-march-2025\"\n      video_id: \"1eWYAp-8o-8\"\n      language: \"english\"\n\n    - title: \"MultiVector Search czyli jak opanować chaos\"\n      speakers:\n        - Justyna Wojtczak\n      event_name: \"Ruby Warsaw Meetup March 2025\"\n      date: \"2025-03-20\"\n      published_at: \"2025-04-07\"\n      video_provider: \"youtube\"\n      id: \"justyna-wojtczak-ruby-warsaw-meetup-march-2025\"\n      video_id: \"bHHWRm8pXcw\"\n      language: \"polish\"\n\n    - title: \"Lightning Talks - Ruby Warsaw Meetup March 2025\"\n      speakers:\n        - TODO\n      event_name: \"Ruby Warsaw Meetup March 2025\"\n      date: \"2025-03-20\"\n      video_provider: \"not_published\"\n      id: \"lightning-talks-ruby-warsaw-meetup-march-2025\"\n      video_id: \"lightning-talks-ruby-warsaw-meetup-march-2025\"\n\n- id: \"ruby-warsaw-meetup-june-2025\"\n  title: \"Ruby Warsaw Meetup June 2025\"\n  raw_title: \"Polish Ruby User Group (PLRUG) Warsaw Meetup #JUNE\"\n  event_name: \"Ruby Warsaw Meetup June 2025\"\n  date: \"2025-06-05\"\n  published_at: \"2025-05-27\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-june-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/d/e/f/e/highres_528117086.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/d/e/f/e/highres_528117086.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/d/e/f/e/highres_528117086.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/d/e/f/e/highres_528117086.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/d/e/f/e/highres_528117086.webp?w=750\"\n  description: |-\n    We're back - and we've missed you! 🚀\n\n    After two months of silence (and one emotional office move), we're thrilled to announce that PLRUG meetups are back - and we're returning with fresh energy, a new venue, and the same old love for Ruby and the community that makes it shine.\n\n    📆 When? June 5th, 18:00\n    📍 Where? Południk Zero - a cozy travel-themed café in Warsaw (https://poludnikzero.pl/)\n\n    Our March meetup was the last one hosted at our beloved office on Odolańska Street. Since then, we've been settling into our new space - but unfortunately, it's no longer fit for meetups. So this time, we're heading into town and embracing a new vibe.\n\n    ### What's on the agenda?\n\n    We've already got some exciting stuff lined up:\n    🎤 Michał Łęcicki - “Shit Happens: Handling Mistakes 101”\n    ⚡️ Lightning talks by Paweł Strzałkowski and Mateusz Woźniczka\n    …and more talks are on the way - we're still finalizing the agenda, but rest assured: it's going to be a good one!\n\n    ### As always:\n\n    🍕 We'll bring snacks\n    🍺 There'll be drinks\n    💬 You bring the conversation\n\n    So come hang out, chat Ruby, meet old friends (and new ones), and let's get this community rolling again.\n\n    We couldn't wait to see you all again - and now, finally, it's happening.\n\n    See you on June 5th!\n\n    https://www.meetup.com/polishrubyusergroup/events/305606762\n  talks:\n    - title: \"Shit Happens: Handling Mistakes 101\"\n      raw_title: \"Shit Happens: Handling Mistakes 101 - Michał Łęcicki [EN]\"\n      speakers:\n        - Michał Łęcicki\n      event_name: \"Ruby Warsaw Meetup June 2025\"\n      date: \"2025-06-05\"\n      published_at: \"2025-07-08\"\n      video_provider: \"youtube\"\n      video_id: \"X1_-Z2DnFlo\"\n      id: \"michal-lecicki-ruby-warsaw-meetup-june-2025\"\n      description: |-\n        Video from PLRUG Ruby Warsaw Meetup 05.06.2025 with a presentation by Michał Łęcicki.\n      language: \"english\"\n\n    - title: \"Introduction to Model Context Protocol (MCP) in Ruby on Rails\"\n      raw_title: \"[EN] Introduction to Model Context Protocol (MCP) in Ruby on Rails - Paweł Strzalkowski\"\n      speakers:\n        - Paweł Strzałkowski\n      event_name: \"Ruby Warsaw Meetup June 2025\"\n      date: \"2025-06-05\"\n      published_at: \"2025-07-08\"\n      video_provider: \"youtube\"\n      video_id: \"-TEwb7k4FjE\"\n      id: \"pawe-strzalkowski-ruby-warsaw-meetup-june-2025\"\n      description: |-\n        Video from PLRUG Ruby Warsaw Meetup 05.06.2025 with a presentation by Paweł Strzałkowski.\n      language: \"english\"\n\n    - title: \"Can you fix a car with AI?\"\n      raw_title: \"Can you fix a car with AI - Mateusz Woźniczka [EN]\"\n      speakers:\n        - Mateusz Woźniczka\n      event_name: \"Ruby Warsaw Meetup June 2025\"\n      date: \"2025-06-05\"\n      published_at: \"2025-07-08\"\n      video_provider: \"youtube\"\n      video_id: \"2tb348iXsjI\"\n      id: \"mateusz-wozniczka-ruby-warsaw-meetup-june-2025\"\n      description: |-\n        Video from PLRUG Ruby Warsaw Meetup 05.06.2025 with a presentation by Mateusz Woźniczka.\n      language: \"english\"\n\n- id: \"ruby-warsaw-meetup-october-2025\"\n  title: \"Ruby Warsaw Meetup October 2025\"\n  raw_title: \"PLRUG Warsaw Meetup @ Behind The Code – October Edition\"\n  event_name: \"Ruby Warsaw Meetup October 2025\"\n  date: \"2025-10-13\"\n  published_at: \"2025-12-19\"\n  video_provider: \"children\"\n  video_id: \"ruby-warsaw-meetup-behind-the-code-october-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/2/a/7/a/600_530470874.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/2/a/7/a/600_530470874.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/2/a/7/a/600_530470874.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/2/a/7/a/600_530470874.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/2/a/7/a/600_530470874.webp?w=750\"\n  description: |-\n    We're back at Behind The Code! 🚀\n\n    On October 13 (Monday), 18:00–21:00, the Polish Ruby User Group (PLRUG) Warsaw Meetup will once again join forces with Venture Café Warsaw as part of Behind The Code – a unique evening where multiple developer communities come together under one roof.\n\n    📍 Location: CIC Warsaw, ul. Chmielna 73\n\n    What to expect?\n    ✅ Inspiring talks from Ruby practitioners\n    ✅ Cross-community networking with developers from different backgrounds\n\n    The last edition of Behind The Code was a great success – packed rooms, excellent talks, and countless conversations. We're excited to bring the Ruby community back into this unique format.\n\n    💡 Agenda:\n    Chris Hasiński - AI, offline\n    Alexander Repnikov - Change Ruby Code Order (lightning talk)\n    Paweł Strzałkowski - Live Demo: Adding MCP in 5 minutes (lightning talk)\n\n    🗓 Date: 13.10.2025\n    🕕 Time: 18:00–21:00\n    📍 Venue: CIC Warsaw, ul. Chmielna 73\n\n    This is a free event, open to all Rubyists, developers, and tech enthusiasts. Whether you're a regular at PLRUG or just curious to see what the Ruby community is about, this is the perfect opportunity to join us.\n\n    Come for Ruby, stay for the community.\n    See you at Behind The Code! ✨\n\n    https://www.meetup.com/polishrubyusergroup/events/311286454\n  talks:\n    - title: \"Introduction To Ruby Passports\"\n      raw_title: \"Introduction To Ruby Passports - Paweł Strzałkowski [EN]\"\n      speakers:\n        - Paweł Strzałkowski\n      event_name: \"Ruby Warsaw Meetup October 2025\"\n      date: \"2025-10-13\"\n      published_at: \"2025-12-19\"\n      video_provider: \"youtube\"\n      video_id: \"w57nq45eGck\"\n      id: \"pawel-strzalkowski-ruby-passports-ruby-warsaw-october-2025\"\n      description: |-\n        Video from PLRUG Ruby Warsaw Meetup at Behind The Code #2 13.10.2025 with an introduction to Ruby Passports initiative.\n      language: \"english\"\n\n    - title: \"AI, offline\"\n      raw_title: \"AI, offline - Chris Hasiński [EN]\"\n      speakers:\n        - Chris Hasiński\n      event_name: \"Ruby Warsaw Meetup October 2025\"\n      date: \"2025-10-13\"\n      published_at: \"2025-12-19\"\n      video_provider: \"youtube\"\n      video_id: \"R3EFCKrs6fM\"\n      id: \"chris-hasinski-ruby-warsaw-october-2025\"\n      description: |-\n        Video from PLRUG Ruby Warsaw Meetup at Behind The Code #2 13.10.2025 with a presentation by Chris Hasiński.\n      language: \"english\"\n\n    - title: \"Lightning Talk: Adding MCP in 5 minutes Live Demo\"\n      raw_title: \"Adding MCP in 5 minutes Live Demo - Paweł Strzałkowski [EN]\"\n      speakers:\n        - Paweł Strzałkowski\n      event_name: \"Ruby Warsaw Meetup October 2025\"\n      date: \"2025-10-13\"\n      published_at: \"2025-12-19\"\n      video_provider: \"youtube\"\n      video_id: \"S9DX52gaeic\"\n      id: \"pawel-strzalkowski-mcp-ruby-warsaw-october-2025\"\n      description: |-\n        Video from PLRUG Ruby Warsaw Meetup at Behind The Code #2 13.10.2025 with a lightning talk by Paweł Strzałkowski.\n      language: \"english\"\n\n    - title: \"Lightning Talk: Change Ruby Code Order\"\n      raw_title: \"Change Ruby Code Order - Alexander Repnikov [EN]\"\n      speakers:\n        - Alexander Repnikov\n      event_name: \"Ruby Warsaw Meetup October 2025\"\n      date: \"2025-10-13\"\n      published_at: \"2025-12-19\"\n      video_provider: \"youtube\"\n      video_id: \"v5b7h4y79jQ\"\n      id: \"alexander-repnikov-ruby-warsaw-october-2025\"\n      description: |-\n        Video from PLRUG Ruby Warsaw Meetup at Behind The Code #2 13.10.2025 with a lightning talk by Alexander Repnikov.\n      language: \"english\"\n"
  },
  {
    "path": "data/polishrubyusergroup/series.yml",
    "content": "---\nname: \"Polish Ruby User Group (PLRUG)\"\nwebsite: \"https://www.meetup.com/polishrubyusergroup\"\ntwitter: \"visualitypl\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"PL\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - PLRUG\n  - Polish Ruby\n  - PolishRubyUserGroup\n"
  },
  {
    "path": "data/poznanrubyusergroup/poznan-ruby-meetup/event.yml",
    "content": "---\nid: \"poznan-ruby-meetup\"\ntitle: \"Poznań Ruby Meetup\"\nkind: \"meetup\"\nlocation: \"Poznań, Poland\"\ndescription: |-\n  Poznań Ruby User Group (PRUG)\nwebsite: \"https://luma.com/prug\"\nbanner_background: \"#57595B\"\nfeatured_background: \"#57595B\"\nfeatured_color: \"#FFED0C\"\ncoordinates:\n  latitude: 52.40567859999999\n  longitude: 16.9312766\n"
  },
  {
    "path": "data/poznanrubyusergroup/poznan-ruby-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/poznanrubyusergroup/series.yml",
    "content": "---\nname: \"Poznań Ruby User Group (PRUG)\"\nwebsite: \"https://luma.com/prug\"\ntwitter: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"PL\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rails-at-scale-summit/rails-at-scale-summit-2025/event.yml",
    "content": "---\nid: \"rails-at-scale-summit-2025\"\ntitle: \"Rails at Scale Summit 2025\"\ndescription: |-\n  A gathering for engineers solving big challenges with Ruby on Rails.\nlocation: \"Amsterdam, Netherlands\"\nkind: \"conference\"\nstart_date: \"2025-09-03\"\nend_date: \"2025-09-03\"\nwebsite: \"https://rubyonrails.org/world/2025/rails_at_scale\"\nbanner_background: \"linear-gradient(#401d61, rgb(101, 20, 89) 83.61%, #771355)\"\nfeatured_background: \"#3B1D62\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 52.3838431\n  longitude: 4.9022709\n"
  },
  {
    "path": "data/rails-at-scale-summit/rails-at-scale-summit-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Amanda Perino\n"
  },
  {
    "path": "data/rails-at-scale-summit/rails-at-scale-summit-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Rails at Scale Sponsor\"\n      description: |-\n        Sponsor for the Rails at Scale Summit\n      level: 1\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://shopify.com\"\n          slug: \"shopify\"\n          logo_url: \"\"\n"
  },
  {
    "path": "data/rails-at-scale-summit/rails-at-scale-summit-2025/venue.yml",
    "content": "---\nname: \"A'DAM The Loft\"\n\naddress:\n  street: \"1 Overhoeksplein\"\n  city: \"Amsterdam\"\n  region: \"Noord-Holland\"\n  postal_code: \"1031 KS\"\n  country: \"Netherlands\"\n  country_code: \"NL\"\n  display: \"Overhoeksplein 1, 1031 KS Amsterdam, Netherlands\"\n\ncoordinates:\n  latitude: 52.3838431\n  longitude: 4.9022709\n\nmaps:\n  google: \"https://maps.google.com/?q=A'DAM+The+Loft,52.3838431,4.9022709\"\n  apple: \"https://maps.apple.com/?q=A'DAM+The+Loft&ll=52.3838431,4.9022709\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=52.3838431&mlon=4.9022709\"\n"
  },
  {
    "path": "data/rails-at-scale-summit/rails-at-scale-summit-2025/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyonrails.org/world/2025/rails_at_scale\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rails-at-scale-summit/rails-at-scale-summit-2026/event.yml",
    "content": "---\nid: \"rails-at-scale-summit-2026\"\ntitle: \"Rails at Scale Summit 2026\"\ndescription: |-\n  A gathering for engineers solving big challenges with Ruby on Rails.\nlocation: \"Austin, TX, United States\"\nkind: \"event\"\nstart_date: \"2026-09-22\"\nend_date: \"2026-09-22\"\nwebsite: \"https://rubyonrails.org/world\"\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/rails-at-scale-summit/series.yml",
    "content": "---\nname: \"Rails at Scale Summit\"\nwebsite: \"https://rubyonrails.org/foundation\"\ntwitter: \"rails\"\nyoutube_channel_name: \"\"\nkind: \"event\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rails-camp-south/rails-camp-south-2019/event.yml",
    "content": "---\nid: \"rails-camp-south-2019\"\ntitle: \"Rails Camp South 2019\"\ndescription: \"\"\nlocation: \"Bandera, TX, United States\"\nkind: \"retreat\"\nstart_date: \"2019-04-05\"\nend_date: \"2019-04-08\"\nwebsite: \"https://us-south.rails.camp/\"\ntwitter: \"railscampsouth\"\ncoordinates:\n  latitude: 29.7266131\n  longitude: -99.0736462\n"
  },
  {
    "path": "data/rails-camp-south/rails-camp-south-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://us-south.rails.camp/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rails-camp-south/series.yml",
    "content": "---\nname: \"Rails Camp South\"\nwebsite: \"https://us-south.rails.camp/\"\ntwitter: \"railscampsouth\"\nyoutube_channel_name: \"\"\nkind: \"retreat\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rails-camp-uk/rails-camp-uk-2009/event.yml",
    "content": "---\nid: \"rails-camp-uk-2009\"\ntitle: \"Rails Camp UK 2009\"\ndescription: \"\"\nlocation: \"Margate, UK\"\nkind: \"retreat\"\nstart_date: \"2009-10-16\"\nend_date: \"2009-10-19\"\noriginal_website: \"http://railscamps.com/#uk_october_2009\"\ncoordinates:\n  latitude: 51.38964600000001\n  longitude: 1.3868339\n"
  },
  {
    "path": "data/rails-camp-uk/rails-camp-uk-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rails-camp-uk/series.yml",
    "content": "---\nname: \"Rails Camp UK\"\nkind: \"retreat\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"GB\"\n"
  },
  {
    "path": "data/rails-camp-us/rails-camp-us-2009/event.yml",
    "content": "---\nid: \"rails-camp-us-2009\"\ntitle: \"Rails Camp US 2009\"\ndescription: \"\"\nlocation: \"Bryant Pond, Maine\"\nkind: \"retreat\"\nstart_date: \"2009-07-17\"\nend_date: \"2009-07-20\"\noriginal_website: \"http://railscamps.com/#ne_july_2009\"\ncoordinates:\n  latitude: 44.3784324\n  longitude: -70.6459429\n"
  },
  {
    "path": "data/rails-camp-us/rails-camp-us-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rails-camp-us/series.yml",
    "content": "---\nname: \"Rails Camp US\"\nwebsite: \"https://railscamp.us\"\nkind: \"retreat\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"US\"\naliases:\n  - Rails Camp USA\n  - Rails Camp America\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2022/event.yml",
    "content": "---\nid: \"rails-camp-west-2022\"\ntitle: \"Rails Camp West 2022\"\ndescription: \"\"\nlocation: \"Diablo Lake, WA, United States\"\nkind: \"retreat\"\nstart_date: \"2022-08-30\"\nend_date: \"2022-09-02\"\nwebsite: \"https://west.railscamp.us/2022\"\ntwitter: \"railscamp_usa\"\ncoordinates:\n  latitude: 48.7121596\n  longitude: -121.1133076\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2022/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://west.railscamp.us/2022\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2023/event.yml",
    "content": "---\nid: \"rails-camp-west-2023\"\ntitle: \"Rails Camp West 2023\"\ndescription: \"\"\nlocation: \"North Shore O’ahu, Hawaii, HI, United States\"\nkind: \"retreat\"\nstart_date: \"2023-09-15\"\nend_date: \"2023-09-18\"\nwebsite: \"https://west.railscamp.us/2023\"\ntwitter: \"railscamp_usa\"\ncoordinates:\n  latitude: 21.5616575\n  longitude: -158.0715983\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2023/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://west.railscamp.us/2023\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2024/event.yml",
    "content": "---\nid: \"rails-camp-west-2024\"\ntitle: \"Rails Camp West 2024 (Cancelled)\"\ndescription: \"\"\nlocation: \"Cascade, ID, United States\"\nkind: \"retreat\"\nstart_date: \"2024-08-27\"\nend_date: \"2024-08-30\"\nwebsite: \"https://west.railscamp.us/2024\"\nstatus: \"cancelled\"\ntwitter: \"railscamp_usa\"\ncoordinates:\n  latitude: 44.51628210000001\n  longitude: -116.0417983\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2024/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://west.railscamp.us/2024\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2025/event.yml",
    "content": "---\nid: \"rails-camp-west-2025\"\ntitle: \"Rails Camp West 2025\"\ndescription: \"\"\nlocation: \"Kenai Lake, Alaska, USA\"\nkind: \"retreat\"\nstart_date: \"2025-08-18\"\nend_date: \"2025-08-21\"\nwebsite: \"https://west.railscamp.us/2025\"\nfeatured_background: \"#F7F7F4\"\nfeatured_color: \"#013198\"\nbanner_background: \"#F7F7F4\"\ncoordinates:\n  latitude: 60.4591085\n  longitude: -149.7243543\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: |-\n        Packages Range from $800 - 4500, Reach out! Rails Camp is one of the most well-known Ruby community events in the world. Attendees walk away every summer with new connections in the engineering community, energized spirits and even new job opportunities. Let's give these developers a space to disconnect, explore the outdoors, and make new authentic connections without the distraction of their daily lives, cell phones, and the internet. This event series, just like all other Rails Camps around the world, is run by engineers working full-time jobs, making it a not-for-profit endeavor. We’re simply passionate about fostering community in tech and all tickets sales and sponsorship dollars go back into the event year after year!\n      level: 1\n      sponsors:\n        - name: \"Typesense\"\n          badge: \"\"\n          website: \"https://typesense.org\"\n          slug: \"typesense\"\n          logo_url: \"https://images.squarespace-cdn.com/content/v1/5d911933b6112e5465976502/d8528215-a7c6-465f-88b0-6ad7ec6c3455/typesense_logo+%281%29.png\"\n\n        - name: \"AppSignal\"\n          badge: \"\"\n          website: \"https://www.appsignal.com\"\n          slug: \"appsignal\"\n          logo_url: \"https://images.squarespace-cdn.com/content/v1/5d911933b6112e5465976502/efe30b70-df3b-44bc-bf03-86867e3fe6cf/horizontal-blue.png\"\n\n        - name: \"Patch Monkey\"\n          badge: \"\"\n          website: \"https://www.patchmonkey.io\"\n          slug: \"patch-monkey\"\n          logo_url: \"https://images.squarespace-cdn.com/content/v1/5d911933b6112e5465976502/18d1299b-3126-4df5-b466-544e3475e2b1/patchmonkey_logo_with_text_stacked_flat%403x.png\"\n\n        - name: \"Honeybadger\"\n          badge: \"\"\n          website: \"https://www.honeybadger.io\"\n          slug: \"honeybadger\"\n          logo_url: \"https://images.squarespace-cdn.com/content/v1/5d911933b6112e5465976502/e872c5ae-0d17-495a-baa0-dabdc7f86055/honeybadger_logo.png\"\n\n        - name: \"Lightward\"\n          badge: \"\"\n          website: \"https://lightward.com\"\n          slug: \"lightward\"\n          logo_url: \"https://images.squarespace-cdn.com/content/v1/5d911933b6112e5465976502/53a2e818-1e2a-4b4a-aae4-6e146048bb3f/lightward-for-railscamp-west.png\"\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2025/venue.yml",
    "content": "# https://www.wetravel.com/trips/rails-camp-2025-alaska-rails-camp-west-43266498\n---\nname: \"Camp K on Kenai Lake, Cooper Landing\"\n\naddress:\n  street: \"Snug Harbor Rd\"\n  city: \"Cooper Landing\"\n  region: \"\"\n  postal_code: \"99572\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"Snug Harbor Rd, Cooper Landing, AK 99572, USA\"\n\ncoordinates:\n  latitude: 60.4591085\n  longitude: -149.7243543\n\nmaps:\n  google: \"https://maps.app.goo.gl/WQzahqQ5CUb8S2hTA\"\n  apple: \"https://maps.apple.com/place?coordinate=60.459220,-149.724504&name=Rails%20Camp%202025&map=h\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=60.4591085&mlon=-149.7243543\"\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2025/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://west.railscamp.us/2025\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2026/event.yml",
    "content": "---\nid: \"rails-camp-west-2026\"\ntitle: \"Rails Camp West 2026\"\ndescription: \"\"\nlocation: \"Otis, OR, United States\"\nkind: \"retreat\"\nstart_date: \"2026-09-07\"\nend_date: \"2026-09-11\"\nwebsite: \"https://west.railscamp.us/2026\"\ntickets_url: \"https://www.wetravel.com/trips/rails-camp-2026-oregon-coast-rails-camp-west-20231135\"\nfeatured_background: \"#F7F7F4\"\nfeatured_color: \"#013198\"\nbanner_background: \"#F7F7F4\"\ncoordinates:\n  latitude: 45.038393945169204\n  longitude: -124.00299449821313\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2026/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum Sponsor\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Patch Monkey\"\n          website: \"https://www.patchmonkey.io\"\n          slug: \"patch-monkey\"\n\n    - name: \"Gold Sponsor\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Typesense\"\n          website: \"https://typesense.org\"\n          slug: \"typesense\"\n\n        - name: \"Honeybadger\"\n          website: \"https://www.honeybadger.io\"\n          slug: \"honeybadger\"\n\n    - name: \"Silver Sponsor\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com\"\n          slug: \"appsignal\"\n"
  },
  {
    "path": "data/rails-camp-west/rails-camp-west-2026/venue.yml",
    "content": "# https://www.wetravel.com/trips/rails-camp-2026-oregon-coast-rails-camp-west-20231135\n---\nname: \"Camp Westwind\"\nurl: \"https://www.wetravel.com/trips/rails-camp-2026-oregon-coast-rails-camp-west-20231135\"\n\naddress:\n  street: \"7500 N Fraser Road\"\n  city: \"Otis\"\n  region: \"Oregon\"\n  postal_code: \"97368\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"Camp Westwind, 7500 N Fraser Road, Otis, OR 97368, USA\"\n\ncoordinates:\n  latitude: 45.038393945169204\n  longitude: -124.00299449821313\n\nmaps:\n  google: \"https://maps.app.goo.gl/CFACYS4ua3ctnj4e6\"\n  apple: \"https://maps.apple.com/?q=Camp+Westwind&ll=45.038393945169204,-124.00299449821313\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=45.038393945169204&mlon=-124.00299449821313&zoom=17\"\n"
  },
  {
    "path": "data/rails-camp-west/series.yml",
    "content": "---\nname: \"Rails Camp West\"\nwebsite: \"https://west.railscamp.us/2022\"\ntwitter: \"railscamp_usa\"\nyoutube_channel_name: \"\"\nkind: \"retreat\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rails-girls-sao-paulo/rails-girls-sao-paulo-evolution-2026/event.yml",
    "content": "# docs/ADDING_EVENTS.md\n---\nid: \"rails-girls-sao-paulo-evolution-2026\"\ntitle: \"Rails Girls São Paulo Evolution 2026\"\nkind: \"workshop\"\ndescription: |-\n  Rails Girls is a non-profit project that offers an excellent introductory experience in software development for women of all ages, regardless of their level of programming experience.\nstart_date: \"2026-04-11\"\nend_date: \"2026-04-11\"\nyear: 2026\nwebsite: \"https://railsgirls.com.br\"\nlocation: \"São Paulo, SP, Brazil\"\ncoordinates:\n  latitude: -23.5728\n  longitude: -46.6935\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#E6312B\"\nfeatured_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/rails-girls-sao-paulo/rails-girls-sao-paulo-evolution-2026/schedule.yml",
    "content": "---\ndays:\n  - name: \"Rails Girls\"\n    date: \"2026-04-11\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - title: \"Doors Open\"\n            description: |-\n              Rails Girls São Paulo attendees are welcome to register, enter, and grab a coffee before the event begins.\n\n      - start_time: \"11:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - title: \"Workshop Session 1\"\n            description: |-\n              Let's start coding and building something amazing together!\n\n      - start_time: \"13:30\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:30\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - title: \"Workshop Session 2\"\n            description: |-\n              Let's continue coding and building something amazing together!\n\n      - start_time: \"17:00\"\n        end_time: \"18:30\"\n        slots: 1\n        items:\n          - title: \"Wrap up\"\n            description: |-\n              Let's wrap up the day's activities and reflect on what we've learned!\n"
  },
  {
    "path": "data/rails-girls-sao-paulo/rails-girls-sao-paulo-evolution-2026/venue.yml",
    "content": "# docs/ADDING_VENUES.md\n---\nname: \"Alice Saúde\"\nurl: \"https://alice.com.br/\"\n\naddress:\n  street: \"Av. Rebouças, 3515\"\n  city: \"São Paulo\"\n  region: \"São Paulo\"\n  postal_code: \"05401-400\"\n  country: \"Brazil\"\n  country_code: \"BR\"\n  display: \"Av. Rebouças, 3515, São Paulo, São Paulo, 05401-400, Brazil\"\n\ncoordinates:\n  latitude: -23.5728\n  longitude: -46.6935\n\nmaps:\n  google: \"https://maps.app.goo.gl/k2PP2Hs7XjyjZpva6\"\n  apple: \"\"\n  openstreetmap: \"\"\n\naccessibility:\n  wheelchair: true\n  elevators: true\n  accessible_restrooms: true\n  notes: \"\"\n"
  },
  {
    "path": "data/rails-girls-sao-paulo/series.yml",
    "content": "# TODO: https://www.youtube.com/@RailsGirls-SP add this\n---\nname: \"Rails Girls São Paulo\"\nwebsite: \"https://railsgirls.com.br\"\ntwitter: \"railsgirlssp\"\nyoutube_channel_name: \"railsgirlssp\"\nkind: \"workshop\" # conference, meetup, retreat, or hackathon\nfrequency: \"biyearly\" # yearly, monthly, quarterly, etc.\nlanguage: \"portuguese\"\ndefault_country_code: \"BR\"\nyoutube_channel_id: \"\" # Will be filled by prepare_series.rb\nplaylist_matcher: \"\" # Optional text to filter playlists\n"
  },
  {
    "path": "data/rails-hackathon/rails-hackathon-community/event.yml",
    "content": "---\nid: \"rails-hackathon-community\"\ntitle: \"Rails Hackathon - Supporting the Ruby on Rails Community\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"hackathon\"\nstart_date: \"2023-07-28\"\nend_date: \"2023-07-30\"\nwebsite: \"https://railshackathon.com\"\ntwitter: \"gorails\"\ncoordinates: false\n"
  },
  {
    "path": "data/rails-hackathon/rails-hackathon-community/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Organizer\"\n      description: |-\n        Event organizer and sponsors\n      level: 1\n      sponsors:\n        - name: \"GoRails\"\n          website: \"https://gorails.com/\"\n          slug: \"gorails\"\n          description: |-\n            Learn Ruby on Rails with screencasts and tutorials\n\n        - name: \"Jumpstart\"\n          website: \"https://jumpstartrails.com/\"\n          slug: \"jumpstart\"\n          description: |-\n            Ruby on Rails SaaS template\n\n        - name: \"Hatchbox\"\n          website: \"https://hatchbox.io/\"\n          slug: \"hatchbox\"\n          description: |-\n            Deploy your Rails apps with ease\n"
  },
  {
    "path": "data/rails-hackathon/rails-hackathon-community/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rails-hackathon/rails-hackathon-hotwire/event.yml",
    "content": "---\nid: \"rails-hackathon-hotwire\"\ntitle: \"Rails Hackathon - Hotwire\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"hackathon\"\nstart_date: \"2022-09-16\"\nend_date: \"2022-09-18\"\nwebsite: \"https://railshackathon.com\"\ntwitter: \"gorails\"\ncoordinates: false\n"
  },
  {
    "path": "data/rails-hackathon/rails-hackathon-hotwire/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Organizer\"\n      description: |-\n        Event organizer and sponsors\n      level: 1\n      sponsors:\n        - name: \"GoRails\"\n          website: \"https://gorails.com/\"\n          slug: \"gorails\"\n          description: |-\n            Learn Ruby on Rails with screencasts and tutorials\n\n        - name: \"Jumpstart\"\n          website: \"https://jumpstartrails.com/\"\n          slug: \"jumpstart\"\n          description: |-\n            Ruby on Rails SaaS template\n\n        - name: \"Hatchbox\"\n          website: \"https://hatchbox.io/\"\n          slug: \"hatchbox\"\n          description: |-\n            Deploy your Rails apps with ease\n"
  },
  {
    "path": "data/rails-hackathon/rails-hackathon-hotwire/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rails-hackathon/series.yml",
    "content": "---\nname: \"Rails Hackathon\"\nwebsite: \"https://railshackathon.com\"\ntwitter: \"gorails\"\nyoutube_channel_name: \"\"\nkind: \"hackathon\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rails-israel/rails-israel-2014/event.yml",
    "content": "---\nid: \"rails-israel-2014\"\ntitle: \"Rails Israel 2014\"\ndescription: \"\"\nlocation: \"Tel Aviv, Israel\"\nkind: \"conference\"\nstart_date: \"2014-11-04\"\nend_date: \"2014-11-05\"\nwebsite: \"http://railsisrael2014.events.co.il/\"\ntwitter: \"fogelmania\"\ncoordinates:\n  latitude: 32.0852999\n  longitude: 34.78176759999999\n"
  },
  {
    "path": "data/rails-israel/rails-israel-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://railsisrael2014.events.co.il/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rails-israel/rails-israel-2015/event.yml",
    "content": "---\nid: \"rails-israel-2015\"\ntitle: \"Rails Israel 2015\"\ndescription: \"\"\nlocation: \"Tel Aviv, Israel\"\nkind: \"conference\"\nstart_date: \"2015-11-24\"\nend_date: \"2015-11-24\"\nwebsite: \"http://railsisrael2015.events.co.il\"\ntwitter: \"railsisrael\"\ncoordinates:\n  latitude: 32.0852999\n  longitude: 34.78176759999999\n"
  },
  {
    "path": "data/rails-israel/rails-israel-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://railsisrael2015.events.co.il\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rails-israel/rails-israel-2016/event.yml",
    "content": "---\nid: \"rails-israel-2016\"\ntitle: \"Rails Israel 2016\"\ndescription: \"\"\nlocation: \"Tel Aviv, Israel\"\nkind: \"conference\"\nstart_date: \"2016-11-14\"\nend_date: \"2016-11-15\"\ntwitter: \"railsisrael\"\ncoordinates:\n  latitude: 32.0852999\n  longitude: 34.78176759999999\n"
  },
  {
    "path": "data/rails-israel/rails-israel-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rails-israel/rails-israel-2017/event.yml",
    "content": "---\nid: \"rails-israel-2017\"\ntitle: \"Rails Israel 2017\"\ndescription: \"\"\nlocation: \"Tel Aviv, Israel\"\nkind: \"conference\"\nstart_date: \"2017-11-28\"\nend_date: \"2017-11-30\"\ntwitter: \"railsisrael\"\ncoordinates:\n  latitude: 32.0852999\n  longitude: 34.78176759999999\n"
  },
  {
    "path": "data/rails-israel/rails-israel-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rails-israel/series.yml",
    "content": "---\nname: \"Rails Israel\"\nwebsite: \"http://railsisrael2014.events.co.il/\"\ntwitter: \"fogelmania\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rails-konferenz/rails-konferenz-2009/event.yml",
    "content": "---\nid: \"rails-konferenz-2009\"\ntitle: \"Rails Konferenz 2009\"\ndescription: \"\"\nlocation: \"Frankfurt, Germany\"\nkind: \"conference\"\nstart_date: \"2009-09-01\"\nend_date: \"2009-09-02\"\noriginal_website: \"http://rails-konferenz.de/\"\ncoordinates:\n  latitude: 50.1109221\n  longitude: 8.6821267\n"
  },
  {
    "path": "data/rails-konferenz/rails-konferenz-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rails-konferenz/series.yml",
    "content": "---\nname: \"Rails Konferenz\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"german\"\ndefault_country_code: \"DE\"\n"
  },
  {
    "path": "data/rails-outreach-workshop/rails-outreach-workshop-2009/event.yml",
    "content": "---\nid: \"rails-outreach-workshop-2009\"\ntitle: \"Rails Outreach Workshop for Women 2009\"\ndescription: \"\"\nlocation: \"San Francisco, CA, United States\"\nkind: \"workshop\"\nstart_date: \"2009-07-31\"\nend_date: \"2009-08-01\"\noriginal_website: \"http://www.sarahmei.com/blog/2009/07/06/julyaugust-ruby-workshop-registration-open/\"\ncoordinates:\n  latitude: 37.7749295\n  longitude: -122.4194155\n"
  },
  {
    "path": "data/rails-outreach-workshop/rails-outreach-workshop-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rails-outreach-workshop/series.yml",
    "content": "---\nname: \"Rails Outreach Workshop for Women\"\nkind: \"workshop\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"US\"\naliases:\n  - Rails Outreach\n  - Rails Outreach Workshop\n"
  },
  {
    "path": "data/rails-pacific/rails-pacific-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYIYgAh89k_iXjEREz2z5in\"\ntitle: \"Rails Pacific 2014\"\nkind: \"conference\"\nlocation: \"Taipei, Taiwan\"\nstart_date: \"2014-09-26\"\nend_date: \"2014-09-27\"\npublished_at: \"2019-01-30\"\ndescription: |-\n  Photos: https://www.flickr.com/people/railspacific/\nyear: 2014\nfeatured_background: \"#C03A2C\"\nfeatured_color: \"#FFFFFF\"\nbanner_background: \"#C03A2C\"\nwebsite: \"https://web.archive.org/web/20140928191827/http://railspacific.com/\"\ncoordinates:\n  latitude: 25.0329636\n  longitude: 121.5654268\n"
  },
  {
    "path": "data/rails-pacific/rails-pacific-2014/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"ding-ding-ye-rails-pacific-2014\"\n  title: \"Better Rails by Knowing Better Database\"\n  raw_title: \"Rails Pacific 2014   Better Rails by Knowing Better Database by Dingding Ye\"\n  speakers:\n    - Ding-ding Ye\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"R08dHi5k3YQ\"\n\n- id: \"richard-lee-rails-pacific-2014\"\n  title: \"Panel: Becoming A Senior Developer\"\n  raw_title: \"Becoming a senior developer\"\n  speakers:\n    - Richard Lee\n    - Prem Sichanugrist\n    - Richard Schneeman\n    - Ding-ding Ye\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"euJ4p0ByBz8\"\n\n- id: \"prem-sichanugrist-rails-pacific-2014\"\n  title: \"Zero Downtime Payment Platforms\"\n  raw_title: \"Rails Pacific 2014   Zero downtime payment platforms by Prem Sichanugrist\"\n  speakers:\n    - Prem Sichanugrist\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"N8sYlKheRrk\"\n\n- id: \"nick-sutterer-rails-pacific-2014\"\n  title: \"Trailblazer A New Architecture For Rails\"\n  raw_title: \"Rails Pacific 2014   Trailblazer   A New Architecture For Rails by Nick Sutterer\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ofC5RA-FmL8\"\n\n- id: \"christopher-rigor-rails-pacific-2014\"\n  title: \"Ten Years of Rails Deployment\"\n  raw_title: \"Rails Pacific 2014   Ten Years of Rails Deployment by Christopher Rigor\"\n  speakers:\n    - Christopher Rigor\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FpSRHaH3McA\"\n\n- id: \"akira-matsuda-rails-pacific-2014\"\n  title: \"Render It! A Deep Dive into ActionView and Template Engines\"\n  raw_title: \"Rails Pacific 2014   Render It!  A Deep Dive into ActionView and Template Engines by Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"fod_z7OFCfs\"\n\n- id: \"ryan-bigg-rails-pacific-2014\"\n  title: \"Multitenancy with Rails\"\n  raw_title: \"Rails Pacific 2014   Multitenancy with Rails by Ryan Bigg\"\n  speakers:\n    - Ryan Bigg\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"uwWBuqmQb0o\"\n\n- id: \"richard-schneeman-rails-pacific-2014\"\n  title: \"Going the Distance\"\n  raw_title: \"Rails Pacific 2014   Going the Distance by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"mJhY5b6y5VM\"\n\n- id: \"wen-tien-chang-rails-pacific-2014\"\n  title: \"Exception Handling Designing Robust Software\"\n  raw_title: \"Rails Pacific 2014   Exception Handling  Designing Robust Software by Wen Tien Chang\"\n  speakers:\n    - Wen Tien Chang\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"BU3jX5IVZGM\"\n\n- id: \"shibata-hiroshi-rails-pacific-2014\"\n  title: \"Crafting Rails Culture\"\n  raw_title: \"Rails Pacific 2014   Crafting Rails Culture by Shibata Hiroshi\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"eBgwduvi3Hw\"\n\n- id: \"ryan-bigg-rails-pacific-2014-panel-refactoring\"\n  title: \"Panel: Refactoring\"\n  raw_title: \"Panel Discussion   Refactoring\"\n  speakers:\n    - Ryan Bigg\n    - Nick Sutterer\n    - Hiroshi SHIBATA\n  event_name: \"Rails Pacific 2014\"\n  date: \"2019-01-30\"\n  published_at: \"2014-12-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"9TkdXkkhP_4\"\n"
  },
  {
    "path": "data/rails-pacific/rails-pacific-2016/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZbXgQvJTAu3umj90yGWyZb\"\ntitle: \"Rails Pacific 2016\"\nkind: \"conference\"\nlocation: \"Taipei, Taiwan\"\ndescription: |-\n  Asia's own Ruby on Rails conference | May 20 - May 21, 2016 | Taipei, Taiwan\nstart_date: \"2016-05-20\"\nend_date: \"2016-05-21\"\npublished_at: \"2016-06-09\"\nyear: 2016\nfeatured_background: \"#C31644\"\nfeatured_color: \"#FFFFFF\"\nbanner_background: \"#C31644\"\ncoordinates:\n  latitude: 25.0329636\n  longitude: 121.5654268\n"
  },
  {
    "path": "data/rails-pacific/rails-pacific-2016/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"lightning-talks-rails-pacific-2016\"\n  title: \"Lightning Talks\"\n  raw_title: \"Rails Pacific 2016 - Lightning Talks\"\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"k7HjIypXtl8\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: JavaScript\"\n      start_cue: \"00:12\"\n      end_cue: \"04:06\"\n      id: \"rick-liu-lighting-talk-rails-pacific-2016\"\n      video_id: \"rick-liu-lighting-talk-rails-pacific-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Rick Liu\n\n    - title: \"Lightning Talk: Helpers, Decorators, Exhibitors, Presenters\"\n      start_cue: \"04:06\"\n      end_cue: \"07:32\"\n      id: \"lulalala-lighting-talk-rails-pacific-2016\"\n      video_id: \"lulalala-lighting-talk-rails-pacific-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - lulalala\n\n    - title: \"Lightning Talk: Why Developers Should Eat Healthier (and how)\"\n      start_cue: \"07:32\"\n      end_cue: \"12:59\"\n      id: \"charlie-hua-lighting-talk-rails-pacific-2016\"\n      video_id: \"charlie-hua-lighting-talk-rails-pacific-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Charlie Hua\n\n    - title: \"Lightning Talk: Intro to RedPotion\"\n      start_cue: \"12:59\"\n      end_cue: \"17:58\"\n      id: \"xdite-lighting-talk-rails-pacific-2016\"\n      video_id: \"xdite-lighting-talk-rails-pacific-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Yi-Ting \"Xdite\" Cheng\n\n    - title: \"Lightning Talk: Unlock Dependency Between Client Teams and API Teams with API Mock and Proxy\"\n      start_cue: \"17:58\"\n      end_cue: \"23:02\"\n      id: \"bruce-li-lighting-talk-rails-pacific-2016\"\n      video_id: \"bruce-li-lighting-talk-rails-pacific-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Bruce Li\n\n    - title: \"Lightning Talk: Continuous Updates: Update Early & Update Often\"\n      start_cue: \"23:02\"\n      end_cue: \"27:39\"\n      id: \"juanito-fatas-lighting-talk-rails-pacific-2016\"\n      video_id: \"juanito-fatas-lighting-talk-rails-pacific-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Juanito Fatas\n\n    - title: \"Lightning Talk: High Five\"\n      start_cue: \"27:39\"\n      end_cue: \"31:31\"\n      id: \"adam-cuppy-lighting-talk-rails-pacific-2016\"\n      video_id: \"adam-cuppy-lighting-talk-rails-pacific-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Cuppy\n\n- id: \"sebastian-sogamoso-rails-pacific-2016\"\n  title: \"When Making Money Becomes a Headache Dealing with Payments\"\n  raw_title: \"Rails Pacific 2016 - When Making Money Becomes a Headache... by Sebastian Sogamoso\"\n  speakers:\n    - Sebastian Sogamoso\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    When Making Money Becomes a Headache. Dealing with Payments by Sebastian Sogamoso\n\n    When things go right and our product starts making money everyone is happy, but sometimes this means the start of the nightmare for people working with payments.\n\n    Let's not sugar coat it. In this talk you'll learn about some where thing went terribly wrong, some of them involved loosing money. Stories of stuff that can easily get overlooked, about the most common mistakes when working with payments and things you probably won't consider until shit hits the fan. All of this so that you don't run into the same problems and don't have to learn those lessons the hard way.\n\n  video_provider: \"youtube\"\n  video_id: \"pILdUMkOG3M\"\n\n- id: \"adam-cuppy-rails-pacific-2016\"\n  title: \"Workshop: Taming Chaotic Specs: RSpec Design Patterns\"\n  raw_title: \"Rails Pacific 2016 - Workshop / Taming Chaotic Specs: RSpec Design Patterns by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    Workshop / Taming Chaotic Specs: RSpec Design Patterns by Adam Cuppy\n\n    Don’t you hate when testing takes 3x as long because your specs are hard to understand? Following a few simple patterns, you can easily take a bloated spec and make it DRY and simple to extend. We will take a bloated sample spec and refactor it to something manageable, readable and concise.\n\n  video_provider: \"youtube\"\n  video_id: \"KjENZNjRCWM\"\n\n- id: \"richard-lee-rails-pacific-2016\"\n  title: \"Server Infrastructure for Rails in 2016\"\n  raw_title: \"Rails Pacific 2016 - Server Infrastructure for Rails in 2016 by Richard Lee\"\n  speakers:\n    - Richard Lee\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    Server Infrastructure for Rails in 2016 by Richard Lee\n\n    In this talk, I’ll share the recent trend about server infrastructure for your Rails application, and also our real world experiences:\n\n    1. Immutable infrastructure with Docker.\n\n    2. CI/CD flow for your containerized application.\n\n    3. Centralized logging & monitoring system.\n\n    4. Server performance tuning best practice.\n\n  video_provider: \"youtube\"\n  video_id: \"v6NA4_Np31k\"\n\n- id: \"luis-ferreira-rails-pacific-2016\"\n  title: \"Continuous Learning, Teaching and the Art of Improving Yourself\"\n  raw_title: \"Rails Pacific 2016 - Continuous Learning, Teaching and...  by Luis Ferreira\"\n  speakers:\n    - Luis Ferreira\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    Continuous Learning, Teaching and the Art of Improving Yourself by Luis Ferreira\n\n    If you have ever tried to learn how to code, you know how hard it is. If you succeeded at learning it, by now you should also be aware that it does not stop there.\n\n    This talk will cover my personal experience in learning new things, consolidating knowledge and giving some of it back to the community through teaching.\n\n    It provides many valuable lessons I have learned through years of making a concerted effort learn new subjects, from programming languages, to business practices you can apply at your own companies, to create a more welcoming environment for learners.\n\n    Key points:\n\n    * Learning how to learn\n\n    * Taking the time to learn\n\n    * Improving your personal productivity by being more organized\n\n    * How, where and at what point in your career can you help the community by teaching\n\n  video_provider: \"youtube\"\n  video_id: \"5r5pBg9RMdM\"\n\n- id: \"adam-cuppy-rails-pacific-2016-what-if-shakespeare-wrote-ruby\"\n  title: \"What if Shakespeare Wrote Ruby?\"\n  raw_title: \"Rails Pacific 2016 - What if Shakespeare Wrote Ruby? by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    What if Shakespeare Wrote Ruby? by Adam Cuppy\n\n    Did you know that Shakespeare wrote almost no direction into his plays? No fight direction. No staging. No notes to the songs. Of the 1700 words he created, there was no official dictionary. That’s right the author of some of the greatest literary works in history, which were filled with situational complexity, fight sequences and music, include NO documentation! How did he do it?\n\n    In this talk, we’re going “thee and thou.” I’m going to give you a crash course in how: Shakespeare writes software.\n\n  video_provider: \"youtube\"\n  video_id: \"mrdmHK6ogC0\"\n\n- id: \"max-hawkins-rails-pacific-2016\"\n  title: \"Robot on Rails\"\n  raw_title: \"Rails Pacific 2016 - Robot on Rails by Max Hawkins\"\n  speakers:\n    - Max Hawkins\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    This lecture-performance will be a collaboration between Max and a presentation generator bot trained on thousands of presentations about Ruby on Rails downloaded from SlideShare. The talk will begin with a description of the bot and its programming. At the end the bot will have complete control and decide the direction of the presentation!\n\n    Topics covered include:\n\n    * Text generation bots\n    * Recurrent neural networks\n    * Ruby on Rails\n    * Whatever the bot decides is relevant\n\n  video_provider: \"youtube\"\n  video_id: \"MPdYs6J-v34\"\n\n- id: \"yi-ting-xdite-cheng-rails-pacific-2016\"\n  title: \"Successful Speedy MVP Website Development\"\n  raw_title: \"Rails Pacific 2016 - Successful Speedy MVP Website Development by Xdite\"\n  speakers:\n    - Yi-Ting \"Xdite\" Cheng\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    Successful Speedy MVP Website Development by Xdite\n\n    Before learining Rails, you heard that it speeds up the development considerably. However, once you become a professional developer, you found things aren't what you think it should be.\n\n    That's right. Your development speed has increased, but even with project management, you still have to work overtime. When you finally finish and release the product, the result does not meet your goal or expectation.\n\n    So after listening to this talk, you should gain some insights about delivering the project in time and successfully, and the next Hackathon winner will be you.\n\n  video_provider: \"youtube\"\n  video_id: \"V3TWE5k3fnM\"\n\n- id: \"vipul-a-m-rails-pacific-2016\"\n  title: \"ActionCable, Rails API and React - Modern Single Page Apps\"\n  raw_title: \"Rails Pacific 2016 - ActionCable, Rails API and React - Modern Single Page Apps by Vipul A M\"\n  speakers:\n    - Vipul A M\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    ActionCable, Rails API and React - Modern Single Page Apps by Vipul A M\n\n    Rails 5, has been a stellar release moving Rails ahead in current Web ecosystem. With new introductions, like ActionCable, Rails API, Rails is embracing the new directions web is moving towards and has emerged as a good backend for Single Page Apps.\n\n    This advances coupled with currently popular ReactJS, has hit a sweet spot, for those who want a more manageable way for their complex views. Rails 5 complement it perfectly\n\n    Lets take a look at how ActionCable, Rails API, React powered by Redux(flux), helped us build a realtime App, and how it can help you build a modular Single Page App.\n\n  video_provider: \"youtube\"\n  video_id: \"NMXXpqX2yvg\"\n\n- id: \"hiroshi-shibata-rails-pacific-2016\"\n  title: \"Large-Scaled Deploy Over 100 Servers in 3 Minutes\"\n  raw_title: \"Rails Pacific 2016 - Large-Scaled Deploy Over 100 Servers in 3 Minutes by Hiroshi Shibata\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    Large-Scaled Deploy Over 100 Servers in 3 Minutes by Hiroshi Shibata\n\n    Our company have handmaid shopping service named minne (https://minne.com). It’s made by Ruby and Rails. We use Ruby with manipulation of infrastructure widely. Minne has over the 200 servers on 2 data centers. we need to deploy latest application code in short minutes. So I made 'pull deploy strategy' using capistrano, consul, stretcher. I will introduce these topics:\n\n    * How to make 'immutable infrastructure' from 'mutable infrastructure'\n\n    * How to rapidly deploy Rails application to large-scaled service.\n\n    * How to use blue-green deployment with Rails\n\n    Finally, I can deploy same code to our servers in 3 minutes completely.\n\n  video_provider: \"youtube\"\n  video_id: \"EUnUeYET-88\"\n\n- id: \"ryan-macinnes-rails-pacific-2016\"\n  title: \"Make Money and Enjoy Freedom Creating a Software Business\"\n  raw_title: \"Rails Pacific 2016 - Make Money and Enjoy Freedom Creating a Software Business by Ryan MacInnes\"\n  speakers:\n    - Ryan MacInnes\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    Make Money and Enjoy Freedom Creating a Software Business by Ryan MacInnes\n\n    I'm by no means the best programmer (Most people probably wouldn't even consider me an expert) but I've managed to build and run a few successful software businesses. I created juicer.io, a social media aggregator, and I've attended YCombinator for another business.\n\n    My talk will be about the history of Juicer: why I started it, how I got there, and how I grew it. I'll also focus on the benefits of business ownership as opposed to traditional software engineering jobs. Finally I'll give my advice that I've learned through brute force and trial and error about idea generation, building, and most importantly growing a software based business.\n\n  video_provider: \"youtube\"\n  video_id: \"Frnl49c2r50\"\n\n- id: \"miles-woodroffe-rails-pacific-2016\"\n  title: \"Going Global on Rails: Lessons Learned Taking Japan's Biggest Recipe Site International\"\n  raw_title: \"Rails Pacific 2016 - Going Global on Rails: Lessons Learned...  by Miles Woodroffe\"\n  speakers:\n    - Miles Woodroffe\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    Going Global on Rails: Lessons Learned Taking Japan's Biggest Recipe Site International by Miles Woodroffe\n\n    Cookpad is Japan’s biggest recipe site - and one of the biggest Rails sites in the world - with 50M unique browsers per month. 80% of women in Japan between 20 and 40 use Cookpad!\n\n    This talk will cover lessons learned launching our service outside of Japan for the first time, to 30 new regions with 8 languages in 12 months, with a globally distributed team spread across 7 countries.\n\n  video_provider: \"youtube\"\n  video_id: \"dTcpLmNBXDA\"\n\n- id: \"prathamesh-sonpatki-rails-pacific-2016\"\n  title: \"Secrets of Testing Rails 5 Apps\"\n  raw_title: \"Rails Pacific 2016 - Secrets of Testing Rails 5 Apps by Prathamesh Sonpatki\"\n  speakers:\n    - Prathamesh Sonpatki\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    Secrets of Testing Rails 5 Apps by Prathamesh Sonpatki\n\n    Testing Rails 5 apps has become better experience out of the box. Rails has also become smarter by introducing the test runner. Now we can't complain that about not able to run a single test or not getting coloured output. A lot of effort gone into making tests especially integration tests run faster.\n\n    The overall testing strategy is also moving from focussing testing internals to testing explicit parts of the whole system.\n\n    Come and join me as we will commence the journey to uncover the secrets of testing Rails 5 apps.\n\n  video_provider: \"youtube\"\n  video_id: \"8A1bx_VoArs\"\n\n- id: \"godfrey-chan-rails-pacific-2016\"\n  title: \"Keynote: Computer Science Education for the Next Generation by Godfrey Chan\"\n  raw_title: \"Rails Pacific 2016 - Keynote: Computer Science Education for the Next Generation by Godfrey Chan\"\n  speakers:\n    - Godfrey Chan\n  event_name: \"Rails Pacific 2016\"\n  date: \"2016-06-09\"\n  published_at: \"2016-06-09\"\n  description: |-\n    Keynote: Computer Science Education for the Next Generation by Godfrey Chan\n\n    Computer Science education has been undergoing rapid transformation in recent years. The rise of code schools, bootcamps, online courses and other self-learning resources on the Internet have opened up a variety of new avenues alongside the more traditional paths. In this talk, we will explore how good programmers think, the key skills that helps them do their job and how our education system could help our students get there.\n\n  video_provider: \"youtube\"\n  video_id: \"cAeIBMtNQY0\"\n"
  },
  {
    "path": "data/rails-pacific/series.yml",
    "content": "---\nname: \"Rails Pacific\"\nwebsite: \"https://x.com/railspacific\"\ntwitter: \"railspacific\"\nyoutube_channel_name: \"confreaks\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Rails Pacific\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/rails-remote-conf/rails-remote-conf-2016/event.yml",
    "content": "---\nid: \"rails-remote-conf-2016\"\ntitle: \"Rails Remote Conf 2016\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2016-10-12\"\nend_date: \"2016-10-14\"\nwebsite: \"https://web.archive.org/web/20170627065859/https://allremoteconfs.com/\"\noriginal_website: \"https://allremoteconfs.com/rails-2016\"\ncoordinates: false\n"
  },
  {
    "path": "data/rails-remote-conf/rails-remote-conf-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://web.archive.org/web/20170627065859/https://allremoteconfs.com/\n# Videos: -\n\n# https://medium.com/agileventures/rails-remote-conference-2016-6d292e80520a\n---\n[]\n"
  },
  {
    "path": "data/rails-remote-conf/series.yml",
    "content": "---\nname: \"Rails Remote Conf\"\nwebsite: \"https://web.archive.org/web/20170627065859/https://allremoteconfs.com/\"\ntwitter: \"\"\nkind: \"conference\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rails-saas-conference/rails-saas-conference-2022/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKX2KnlAxfgdTRDGFuSgzMlc\"\ntitle: \"The Rails SaaS Conference 2022\"\nkind: \"conference\"\nlocation: \"Los Angeles, CA, United States\"\ndescription: |-\n  A small, next-generation Ruby on Rails conference • Meeting at the intersection of Rails and business\npublished_at: \"2022-10-07\"\nstart_date: \"2022-10-06\"\nend_date: \"2022-10-07\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2022\nbanner_background: \"#466BB1\"\nfeatured_background: \"#466BB1\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://web.archive.org/web/20220927175525/https://railssaas.com/\"\ncoordinates:\n  latitude: 34.0999975\n  longitude: -118.3301556\n"
  },
  {
    "path": "data/rails-saas-conference/rails-saas-conference-2022/venue.yml",
    "content": "---\nname: \"Dream Hollywood\"\n\naddress:\n  street: \"6417 Selma Avenue\"\n  city: \"Los Angeles\"\n  region: \"California\"\n  postal_code: \"90028\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"6417 Selma Ave, Hollywood, CA 90028, USA\"\n\ncoordinates:\n  latitude: 34.0999975\n  longitude: -118.3301556\n\nmaps:\n  google: \"https://maps.google.com/?q=Dream+Hollywood,34.0999975,-118.3301556\"\n  apple: \"https://maps.apple.com/?q=Dream+Hollywood&ll=34.0999975,-118.3301556\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=34.0999975&mlon=-118.3301556\"\n"
  },
  {
    "path": "data/rails-saas-conference/rails-saas-conference-2022/videos.yml",
    "content": "---\n# TODO: running order\n# TODO: talk dates\n# TODO: talk titles\n# TODO: schedule website\n\n# Website: https://web.archive.org/web/20220927175525/https://railssaas.com/\n# Schedule: -\n\n- id: \"todd-dickerson-rails-saas-conference-2022\"\n  title: \"Talk by Todd Dickerson\"\n  raw_title: \"Talk by Todd Dickerson\"\n  speakers:\n    - Todd Dickerson\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"todd-dickerson-rails-saas-conference-2022\"\n\n- id: \"saron-yitbarek-rails-saas-conference-2022\"\n  title: \"Talk by Saron Yitbarek\"\n  raw_title: \"Talk by Saron Yitbarek\"\n  speakers:\n    - Saron Yitbarek\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"saron-yitbarek-rails-saas-conference-2022\"\n\n- id: \"don-pottinger-rails-saas-conference-2022\"\n  title: \"Talk by Don Pottinger\"\n  raw_title: \"Talk by Don Pottinger\"\n  speakers:\n    - Don Pottinger\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"don-pottinger-rails-saas-conference-2022\"\n\n- id: \"colleen-schnettler-rails-saas-conference-2022\"\n  title: \"Talk by Colleen Schnettler\"\n  raw_title: \"Talk by Colleen Schnettler\"\n  speakers:\n    - Colleen Schnettler\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"colleen-schnettler-rails-saas-conference-2022\"\n\n- id: \"michael-buckbee-the-rails-saas-conference-2022\"\n  title: \"Practical SaaS Security\"\n  raw_title: \"Practical SaaS Security — Michael Buckbee\"\n  speakers:\n    - Michael Buckbee\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  published_at: \"2023-04-07\"\n  description: |-\n    Mike joined us at The Rails SaaS Conference in Los Angeles, California to share practical lessons learned managing security for hundreds of businesses and also released a brand new Web Application Firewall (WAF) toolkit called Wafris!\n\n    You can join us in Athens on June 1–2, 2023. Details are available at https://railssaas.com. To follow announcements of future events, follow http://twitter.com/railssaas.\n\n    Thank you to our corporate sponsors who made the event and the production of this video possible:\n\n    EVENT SPONSOR\n    ClickFunnels (https://clickfunnels.com)\n\n    PRODUCTION SPONSORS\n    Buzzsprout (https://www.buzzsprout.com)\n    Geocodio (https://www.geocod.io)\n\n    POST-PRODUCTION SPONSORS\n    Render (https://render.com)\n    PlanetScale (https://planetscale.com)\n    Evil Martians (https://evilmartians.com) \n    Entri (https://www.entri.com)\n\n    0:00 — “The Incident”\n    1:52 — Threat Actors\n    6:20 — Web Application Firewalls (WAF)\n    8:37 — Real-World Incident 1\n    12:40 — Real-World Incident 2\n    16:43 — Real-World Incident 3\n    18:48 — Real-World Incident 4\n    23:17 — Survivorship Bias\n    27:27 — Vulnerabilities you don’t expect\n    29:53 — Introducing Wafris\n  video_provider: \"youtube\"\n  video_id: \"pM_NLmsQpoc\"\n\n- id: \"nadia-odunayo-the-rails-saas-conference-2022\"\n  title: \"Getting to One Million Users as a One-Woman Dev\"\n  raw_title: \"Getting to One Million Users as a One-Woman Dev — Nadia Odunayo\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  published_at: \"2022-11-30\"\n  description: |-\n    Nadia joined us at The Rails SaaS Conference in Los Angeles, California to share the details of her journey building and bootstrapping The StoryGraph, from the early beta buzz on Twitter to bringing on a co-founder and going viral with the mobile apps she built with Ruby on Rails tooling.\n\n    If you'd like to join us at our next event, follow http://twitter.com/railssaas and sign up for our mailing list at https://www.getrevue.co/profile/railssaas .\n\n    Thank you to our corporate sponsors who made the event and the production of this video possible:\n\n    EVENT SPONSOR\n    ClickFunnels (https://clickfunnels.com)\n\n    PRODUCTION SPONSORS\n    Buzzsprout (https://www.buzzsprout.com)\n    Geocodio (https://www.geocod.io)\n\n    POST-PRODUCTION SPONSORS\n    Render (https://render.com)\n    PlanetScale (https://planetscale.com)\n    Evil Martians (https://evilmartians.com) \n    Entri (https://www.entri.com)\n\n    0:00 — Introduction\n    4:33 — Growing buzz on Twitter\n    9:31 — Buckling under the load; “how did I get here?” \n    14:01 — “Keep the Tech Simple\" and \"Keep Talking to Customers\"\n    22:59 — Hiring help, adding a co-founder, and re-engineering\n    27:14 — “Keep Costs Low” and choosing a revenue model\n    35:03 — Going viral with mobile apps\n    39:28 — Migrating away from Heroku\n    42:37 — Today; the takeaways\n  video_provider: \"youtube\"\n  video_id: \"efCI1ByPT5s\"\n\n- id: \"mike-coutermarsh-rails-saas-conference-2022\"\n  title: \"Talk by Mike Coutermarsh\"\n  raw_title: \"Talk by Mike Coutermarsh\"\n  speakers:\n    - Mike Coutermarsh\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"mike-coutermarsh-rails-saas-conference-2022\"\n\n- id: \"joe-masilotti-the-rails-saas-conference-2022\"\n  title: \"Why Are We Afraid to Hire Junior Rails Developers?\"\n  raw_title: \"Why Are We Afraid to Hire Junior Rails Developers? — Joe Masilotti\"\n  speakers:\n    - Joe Masilotti\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  published_at: \"2023-01-18\"\n  description: |-\n    Joe, founder of RailsDevs, joined us at The Rails SaaS Conference in Los Angeles, California to talk about the benefits of hiring junior developers and to share tips on how companies and development teams can hire and work with juniors more effectively.\n\n    If you'd like to join us at our next event, follow http://twitter.com/railssaas and sign up for our mailing list at https://www.getrevue.co/profile/railssaas .\n\n    Thank you to our corporate sponsors who made the event and the production of this video possible:\n\n    EVENT SPONSOR\n    ClickFunnels (https://clickfunnels.com)\n\n    PRODUCTION SPONSORS\n    Buzzsprout (https://www.buzzsprout.com)\n    Geocodio (https://www.geocod.io)\n\n    POST-PRODUCTION SPONSORS\n    Render (https://render.com)\n    PlanetScale (https://planetscale.com)\n    Evil Martians (https://evilmartians.com) \n    Entri (https://www.entri.com)\n\n    3:25 — Why junior developers?\n    7:07 — Common objections\n    9:19 — What works: hiring\n    14:23 — What works once they’re hired\n    16:47 — Mentorship\n    20:14 — The power of pair programming\n    24:51 — My challenge for you\n  video_provider: \"youtube\"\n  video_id: \"NZionAE-Tj0\"\n\n- id: \"adam-pallozzi-rails-saas-conference-2022\"\n  title: \"Talk by Adam Pallozzi\"\n  raw_title: \"Talk by Adam Pallozzi\"\n  speakers:\n    - Adam Pallozzi\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"adam-pallozzi-rails-saas-conference-2022\"\n\n- id: \"jason-charnes-rails-saas-conference-2022\"\n  title: \"Talk by Jason Charnes\"\n  raw_title: \"Talk by Jason Charnes\"\n  speakers:\n    - Jason Charnes\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"jason-charnes-rails-saas-conference-2022\"\n\n- id: \"evan-phoenix-rails-saas-conference-2022\"\n  title: \"Talk by Evan Phoenix\"\n  raw_title: \"Talk by Evan Phoenix\"\n  speakers:\n    - Evan Phoenix\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"evan-phoenix-rails-saas-conference-2022\"\n\n- id: \"andrew-culver-rails-saas-conference-2022\"\n  title: \"Talk by Andrew Culver\"\n  raw_title: \"Talk by Andrew Culver\"\n  speakers:\n    - Andrew Culver\n  event_name: \"The Rails SaaS Conference 2022\"\n  date: \"2022-10-06\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"andrew-culver-rails-saas-conference-2022\"\n"
  },
  {
    "path": "data/rails-saas-conference/rails-saas-conference-2023/event.yml",
    "content": "---\nid: \"rails-saas-conference-2023\"\ntitle: \"The Rails SaaS Conference 2023\"\nkind: \"conference\"\nlocation: \"Athens, Greece\"\ndescription: |-\n  A small, next-generation Ruby on Rails conference • Meeting at the intersection of Rails and business\npublished_at: \"2023-06-02\"\nstart_date: \"2023-06-01\"\nend_date: \"2023-06-02\"\nyear: 2023\nbanner_background: \"#466BB1\"\nfeatured_background: \"#466BB1\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://web.archive.org/web/20230716113217/https://railssaas.com/\"\ncoordinates:\n  latitude: 37.9750964\n  longitude: 23.7321543\n"
  },
  {
    "path": "data/rails-saas-conference/rails-saas-conference-2023/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Production Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Clickfunnels\"\n          badge: \"\"\n          website: \"https://clickfunnels.com\"\n          slug: \"clickfunnels\"\n          logo_url: \"https://railssaas.com/images-event/clickfunnels.png\"\n\n    - name: \"Post-Production Sponsors\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Buzzsprout\"\n          badge: \"\"\n          website: \"https://www.buzzsprout.com\"\n          slug: \"buzzsprout-logo\"\n          logo_url: \"https://railssaas.com/images-event/buzzsprout.png\"\n\n        - name: \"Evil Martians\"\n          badge: \"\"\n          website: \"https://evilmartians.com\"\n          slug: \"evil-martians\"\n          logo_url: \"https://railssaas.com/images-event/martians.png\"\n\n    - name: \"Session Sponsors\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"FastRuby.io\"\n          badge: \"Session Sponsor\"\n          website: \"https://www.fastruby.io/\"\n          slug: \"fastruby-io\"\n          logo_url: \"https://railssaas.com/images-event/fastruby.png\"\n\n        - name: \"Avo\"\n          badge: \"Session Sponsor\"\n          website: \"https://avohq.io\"\n          slug: \"avo\"\n          logo_url: \"https://railssaas.com/images-event/avo.png\"\n"
  },
  {
    "path": "data/rails-saas-conference/rails-saas-conference-2023/venue.yml",
    "content": "---\nname: \"Electra Metropolis\"\n\naddress:\n  street: \"15 Mitropoleos\"\n  city: \"Athens\"\n  postal_code: \"105 57\"\n  country: \"Greece\"\n  country_code: \"GR\"\n  display: \"Mitropoleos 15, Athina 105 57, Greece\"\n\ncoordinates:\n  latitude: 37.9750964\n  longitude: 23.7321543\n\nmaps:\n  google: \"https://maps.google.com/?q=Electra+Metropolis,37.9750964,23.7321543\"\n  apple: \"https://maps.apple.com/?q=Electra+Metropolis&ll=37.9750964,23.7321543\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=37.9750964&mlon=23.7321543\"\n"
  },
  {
    "path": "data/rails-saas-conference/rails-saas-conference-2023/videos.yml",
    "content": "# Website: https://web.archive.org/web/20230716113217/https://railssaas.com/\n# Schedule Day 1: https://x.com/adrianthedev/status/1664157410770944000\n# Schedule Day 2: https://x.com/julian_rubisch/status/1664528428597428225\n\n## Day 1 - June 1, 2023\n---\n- id: \"tom-rossi-rails-saas-conference-2023\"\n  title: \"SaaS Lessons Learned\"\n  raw_title: \"SaaS Lessons Learned by Tom Rossi\"\n  speakers:\n    - Tom Rossi\n  date: \"2023-06-01\"\n  video_provider: \"not_published\"\n  video_id: \"tom-rossi-rails-saas-conference-2023\"\n  description: \"\"\n\n- id: \"benedikt-deicke-rails-saas-conference-2023\"\n  title: \"Reporting on Rails\"\n  raw_title: \"Reporting on Rails by Benedikt Deicke\"\n  speakers:\n    - Benedikt Deicke\n  date: \"2023-06-01\"\n  video_provider: \"not_published\"\n  video_id: \"benedikt-deicke-rails-saas-conference-2023\"\n  description: \"\"\n\n- id: \"jane-portman-rails-saas-conference-2023\"\n  title: \"Divide & Conquer\"\n  raw_title: \"Divide & Conquer by Jane Portman\"\n  speakers:\n    - Jane Portman\n  date: \"2023-06-01\"\n  video_provider: \"not_published\"\n  video_id: \"jane-portman-rails-saas-conference-2023\"\n  description: \"\"\n\n- id: \"andy-croll-rails-saas-conference-2023\"\n  title: \"Taylor's Guide to Big Rewrites\"\n  raw_title: \"Taylor's Guide to Big Rewrites by Andy Croll\"\n  speakers:\n    - Andy Croll\n  date: \"2023-06-01\"\n  video_provider: \"not_published\"\n  video_id: \"andy-croll-rails-saas-conference-2023\"\n  description: \"\"\n\n- id: \"adrian-marin-rails-saas-conference-2023\"\n  title: \"Build Rails Apps 10x Faster\"\n  raw_title: \"Build Rails Apps 10x Faster by Adrian Marin\"\n  speakers:\n    - Adrian Marin\n  date: \"2023-06-01\"\n  video_provider: \"not_published\"\n  video_id: \"adrian-marin-rails-saas-conference-2023\"\n  description: \"\"\n\n- id: \"dan-singerman-rails-saas-conference-2023\"\n  title: \"Domain Modeling in Rails\"\n  raw_title: \"Domain Modeling in Rails by Dan Singerman\"\n  speakers:\n    - Dan Singerman\n  date: \"2023-06-01\"\n  video_provider: \"not_published\"\n  video_id: \"dan-singerman-rails-saas-conference-2023\"\n  description: \"\"\n\n## Day 2 - June 2, 2023\n\n- id: \"emmanuel-hayford-rails-saas-conference-2023\"\n  title: \"Rails 7.1 Unwrapped\"\n  raw_title: \"Rails 7.1 Unwrapped by Emmanuel Hayford\"\n  speakers:\n    - Emmanuel Hayford\n  date: \"2023-06-02\"\n  video_provider: \"not_published\"\n  video_id: \"emmanuel-hayford-rails-saas-conference-2023\"\n  description: \"\"\n\n- id: \"adam-pallozzi-rails-saas-conference-2023\"\n  title: \"Ruby on Rasperry\"\n  raw_title: \"Ruby on Rasperry by Adam Pallozzi\"\n  speakers:\n    - Adam Pallozzi\n  date: \"2023-06-02\"\n  video_provider: \"not_published\"\n  video_id: \"adam-pallozzi-rails-saas-conference-2023\"\n  description: \"\"\n\n- id: \"irina-nazarova-rails-saas-conference-2023\"\n  title: \"Navigating Risk Like a Pro\"\n  raw_title: \"Navigating Risk Like a Pro by Irina Nazarova\"\n  speakers:\n    - Irina Nazarova\n  date: \"2023-06-02\"\n  video_provider: \"not_published\"\n  video_id: \"irina-nazarova-rails-saas-conference-2023\"\n  description: \"\"\n\n- id: \"yaroslav-shmarov-rails-saas-conference-2023\"\n  title: \"Empowering Your Journey\"\n  raw_title: \"Empowering Your Journey by Yaroslav Shmarov\"\n  speakers:\n    - Yaroslav Shmarov\n  date: \"2023-06-02\"\n  video_provider: \"not_published\"\n  video_id: \"yaroslav-shmarov-rails-saas-conference-2023\"\n  description: \"\"\n\n- id: \"julian-rubisch-rails-saas-conference-2023\"\n  title: \"The State of Reactive Rails\"\n  raw_title: \"The State of Reactive Rails by Julian Rubisch\"\n  speakers:\n    - Julian Rubisch\n  date: \"2023-06-02\"\n  video_provider: \"not_published\"\n  video_id: \"julian-rubisch-rails-saas-conference-2023\"\n  description: \"\"\n\n- id: \"xavier-noria-rails-saas-conference-2023\"\n  title: \"A Dateless Mindset\"\n  raw_title: \"A Dateless Mindset by Xavier Noria\"\n  speakers:\n    - Xavier Noria\n  date: \"2023-06-02\"\n  video_provider: \"not_published\"\n  video_id: \"xavier-noria-rails-saas-conference-2023\"\n  description: \"\"\n"
  },
  {
    "path": "data/rails-saas-conference/series.yml",
    "content": "---\nname: \"The Rails SaaS Conference\"\nwebsite: \"https://railssaas.com\"\ntwitter: \"railssaas\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"The Rails SaaS Conference\"\nyoutube_channel_name: \"railssaas\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCUG1xcJO0Dn571ftzgPpLPw\"\n"
  },
  {
    "path": "data/rails-studio/rails-studio-2006-pasadena/event.yml",
    "content": "# Pragmatic Rails Studio in Pasadena, California held January 26-28 2006.\n# https://www.flickr.com/photos/x180/albums/72057594055298824\n# https://billsaysthis.com/2006/01/18/pragmatic-rails-studio-pasadena/\n---\nid: \"rails-studio-2006-pasadena\"\ntitle: \"Rails Studio Pasadena 2006\"\nlocation: \"Pasadena, CA, United States\"\nstart_date: \"2006-01-26\"\nend_date: \"2006-01-28\"\nkind: \"workshop\"\ncoordinates:\n  latitude: 34.1476527\n  longitude: -118.144302\n"
  },
  {
    "path": "data/rails-studio/rails-studio-portland/event.yml",
    "content": "# Rails Studio Portland\n# https://www.flickr.com/photos/x180/albums/72057594106665943/\n---\nid: \"rails-studio-portland\"\ntitle: \"Rails Studio Portland\"\nlocation: \"Portland, OR, United States\"\nstart_date: \"2006-04-10\"\nend_date: \"2006-04-12\"\nkind: \"workshop\"\ncoordinates:\n  latitude: 45.515232\n  longitude: -122.6783853\n"
  },
  {
    "path": "data/rails-studio/series.yml",
    "content": "---\nname: \"Rails Studio\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"US\"\nlanguage: \"english\"\nwebsite: \"http://studio.pragprog.com/rails/locations.html\"\n"
  },
  {
    "path": "data/rails-summit-latin-america/rails-summit-latin-america-2009/event.yml",
    "content": "---\nid: \"rails-summit-latin-america-2009\"\ntitle: \"Rails Summit Latin America 2009\"\ndescription: \"\"\nlocation: \"São Paulo, Brazil\"\nkind: \"conference\"\nstart_date: \"2009-10-13\"\nend_date: \"2009-10-14\"\noriginal_website: \"http://railssummit.locaweb.com.br/en/pages/home\"\ncoordinates:\n  latitude: -23.5557714\n  longitude: -46.6395571\n"
  },
  {
    "path": "data/rails-summit-latin-america/rails-summit-latin-america-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rails-summit-latin-america/series.yml",
    "content": "---\nname: \"Rails Summit Latin America\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"portuguese\"\ndefault_country_code: \"BR\"\n"
  },
  {
    "path": "data/rails-to-italy/series.yml",
    "content": "# https://www.ruby-forum.com/t/rails-to-italy/127815/3\n# https://www.ruby-forum.com/t/railstoitaly-is-over/118593/2\n# http://blog.seesaw.it/articles/2007/10/29/railstoitaly-report\n---\nname: \"Rails to Italy\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"IT\"\nlanguage: \"english\"\nwebsite: \"https://web.archive.org/web/20080124194723/http://www.railstoitaly.org/\"\noriginal_website: \"http://www.railstoitaly.org/\"\n"
  },
  {
    "path": "data/rails-underground/rails-underground-2009/event.yml",
    "content": "---\nid: \"rails-underground-2009\"\ntitle: \"Rails Underground 2009\"\ndescription: \"\"\nlocation: \"London, UK\"\nkind: \"conference\"\nstart_date: \"2009-07-24\"\nend_date: \"2009-07-25\"\noriginal_website: \"http://www.rails-underground.com/\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/rails-underground/rails-underground-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rails-underground/series.yml",
    "content": "---\nname: \"Rails Underground\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"GB\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2023/event.yml",
    "content": "---\nid: \"PLHFP2OPUpCeY9IX3Ht727dwu5ZJ2BBbZP\"\ntitle: \"Rails World 2023\"\nkind: \"conference\"\nlocation: \"Amsterdam, Netherlands\"\ndescription: |-\n  Rails World was a two-day, two track community conference featuring technical talks, demos, workshops, networking, and keynotes about the latest features and best practices in Rails development. There were 700+ Rails developers in attendance, 29 speakers, and one big birthday celebration.\npublished_at: \"2023-10-05\"\nstart_date: \"2023-10-05\"\nend_date: \"2023-10-06\"\nchannel_id: \"UC9zbLaqReIdoFfzdUbh13Nw\"\nyear: 2023\nbanner_background: \"#BF281C\"\nfeatured_background: \"#BF281C\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubyonrails.org/world/2023\"\ncoordinates:\n  latitude: 52.3752\n  longitude: 4.8956\n"
  },
  {
    "path": "data/rails-world/rails-world-2023/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Amanda Perino\n\n  organisations:\n    - Rails Foundation\n\n- name: \"Website Developer\"\n  users:\n    - Shona Chan\n\n- name: \"Designer\"\n  users:\n    - Katya Sitko\n\n- name: \"Website Development Mentor\"\n  users:\n    - Ayush Newatia\n"
  },
  {
    "path": "data/rails-world/rails-world-2023/schedule.yml",
    "content": "# Schedule: https://rubyonrails.org/world/2023/agenda\n---\ndays:\n  - name: \"Day 0\"\n    date: \"2023-10-04\"\n    grid:\n      - start_time: \"16:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - title: \"Early Registration\"\n            description: |-\n              Registration opens for those who are in town early. Avoid the Thursday morning line and get your badge early.\n\n      - start_time: \"17:00\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - title: \"Drinks sponsored by Clear Code Wizards\"\n            description: |-\n              Pre-event drinks sponsored by Clear Code Wizards. The location of these drinks will be shared with registered attendees. Badge required.\n\n  - name: \"Day 1\"\n    date: \"2023-10-05\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - title: \"Doors Open\"\n            description: |-\n              Rails World attendees are welcome to register, enter, and get breakfast before the keynote begins.\n\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 2\n\n      - start_time: \"11:30\"\n        end_time: \"11:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:45\"\n        end_time: \"12:15\"\n        slots: 2\n\n      - start_time: \"12:30\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 2\n\n      - start_time: \"14:00\"\n        end_time: \"14:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:15\"\n        end_time: \"14:45\"\n        slots: 2\n\n      - start_time: \"14:45\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 2\n\n      - start_time: \"15:30\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 2\n\n      - start_time: \"16:15\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:30\"\n        end_time: \"17:15\"\n        slots: 1\n\n  - name: \"Day 2\"\n    date: \"2023-10-06\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - title: \"WNB.rb Breakfast sponsored by Shopify\"\n            description: |-\n              A networking breakfast for women and non-binary Rails World attendees. Hosted by WNB.rb and sponsored by Shopify. The location of this breafast will be shared with registered attendees. Badge required.\n\n      - start_time: \"09:00\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - title: \"Doors Open\"\n            description: |-\n              Rails World attendees are welcome to get breakfast and get settled before the day 2 keynote begins.\n\n      - start_time: \"09:45\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:40\"\n        slots: 2\n\n      - start_time: \"11:40\"\n        end_time: \"11:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:45\"\n        end_time: \"12:15\"\n        slots: 2\n\n      - start_time: \"12:30\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 2\n\n      - start_time: \"14:00\"\n        end_time: \"14:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:15\"\n        end_time: \"14:45\"\n        slots: 2\n\n      - start_time: \"14:45\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 2\n\n      - start_time: \"15:30\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 2\n\n      - start_time: \"16:15\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:30\"\n        end_time: \"17:30\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - title: \"Rails 20th Anniversary Celebration\"\n            description: |-\n              Join us for the closing party of the first edition of Rails World. Let’s celebrate the first 20 years of Ruby on Rails, and look into the future at the next 20 years and beyond.\n\ntracks:\n  - name: \"Track 1\"\n    color: \"#BF281C\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Track 2\"\n    color: \"#3B1D62\"\n    text_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2023/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum Sponsors\"\n      description: |-\n        Top tier sponsors of Rails World 2023\n      level: 1\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-appsignal.svg\"\n\n    - name: \"Gold Sponsors\"\n      description: |-\n        Second tier sponsors of Rails World 2023\n      level: 2\n      sponsors:\n        - name: \"Babbel\"\n          website: \"https://www.babbel.com/\"\n          slug: \"babbel\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-babbel.svg\"\n\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com/\"\n          slug: \"shopify\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-shopify.svg\"\n\n        - name: \"ViaEurope\"\n          website: \"https://www.viaeurope.com/\"\n          slug: \"viaeurope\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-viaeurope.svg\"\n\n    - name: \"Silver Sponsors\"\n      description: |-\n        Third tier sponsors of Rails World 2023\n      level: 3\n      sponsors:\n        - name: \"Crunchy Data\"\n          website: \"https://www.crunchydata.com/\"\n          slug: \"crunchydata\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-crunchydata.svg\"\n\n        - name: \"GitHub\"\n          website: \"https://www.github.com/\"\n          slug: \"github\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-github.svg\"\n\n        - name: \"MagmaLabs\"\n          website: \"https://www.magmalabs.io/\"\n          slug: \"magmalabs\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-magmalabs.svg\"\n\n        - name: \"Wafris\"\n          website: \"https://wafris.org/\"\n          slug: \"wafris\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-wafris.svg\"\n\n        - name: \"Zilverline\"\n          website: \"https://www.zilverline.com/\"\n          slug: \"zilverline\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-zilverline.svg\"\n\n        - name: \"Agency of Learning\"\n          website: \"https://agencyoflearning.com/\"\n          slug: \"agency-of-learning\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-agency-of-learning.png\"\n\n        - name: \"Buzzsprout\"\n          website: \"https://www.buzzsprout.com/\"\n          slug: \"buzzsprout\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-buzzsprout.svg\"\n\n        - name: \"LeWagon\"\n          website: \"https://www.lewagon.com/\"\n          slug: \"lewagon\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-lewagon.svg\"\n\n        - name: \"Dell\"\n          website: \"https://www.dell.com/\"\n          slug: \"dell\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-dell.svg\"\n\n        - name: \"Cedarcode\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"cedarcode\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-cedarcode.svg\"\n\n        - name: \"Zapfloor\"\n          website: \"https://www.zapfloor.com/\"\n          slug: \"zapfloor\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-zapfloor.svg\"\n\n        - name: \"GoRails\"\n          website: \"https://gorails.com/\"\n          slug: \"gorails\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-gorails.svg\"\n\n        - name: \"JetBrains\"\n          website: \"https://www.jetbrains.com/\"\n          slug: \"jetbrains\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-jetbrains1.svg\"\n\n        - name: \"Rompslomp\"\n          website: \"https://rompslomp.nl/\"\n          slug: \"rompslomp\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-rompslomp2.svg\"\n\n        - name: \"ClickFunnels\"\n          website: \"https://www.clickfunnels.com/\"\n          slug: \"clickfunnels\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-clickfunnels.svg\"\n\n        - name: \"Clear Code Wizards\"\n          website: \"https://clearcodewizards.com\"\n          slug: \"clear-code-wizards\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-clear-code-wizards.svg\"\n\n        - name: \"Gleam\"\n          website: \"https://gleam.io/\"\n          slug: \"gleam\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-gleam.svg\"\n\n        - name: \"Cookpad\"\n          website: \"https://cookpad.com/\"\n          slug: \"cookpad\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-cookpad.svg\"\n\n        - name: \"Doximity\"\n          website: \"https://www.doximity.com/\"\n          slug: \"doximity\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-doximity.svg\"\n\n        - name: \"Fleetio\"\n          website: \"https://www.fleetio.com/\"\n          slug: \"fleetio\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-fleetio.svg\"\n\n        - name: \"Intercom\"\n          website: \"https://www.intercom.com/\"\n          slug: \"intercom\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-intercom.svg\"\n\n        - name: \"Procore\"\n          website: \"https://procore.com/\"\n          slug: \"procore\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-procore.svg\"\n\n        - name: \"37signals\"\n          website: \"https://37signals.com/\"\n          slug: \"37signals\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-37signals.svg\"\n\n        - name: \"Planet Argon\"\n          website: \"https://www.planetargon.com/\"\n          slug: \"planetargon\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-planet-argon.png\"\n\n        - name: \"BigBinary\"\n          website: \"https://www.bigbinary.com/\"\n          slug: \"bigbinary\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-bigbinary.svg\"\n\n        - name: \"Renuo\"\n          website: \"https://www.renuo.ch/\"\n          slug: \"renuo\"\n          logo_url: \"https://rubyonrails.org/assets/images/logo-renuo.svg\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2023/venue.yml",
    "content": "---\nname: \"Beurs van Berlage\"\n\naddress:\n  street: \"Damrak 243\"\n  city: \"Amsterdam\"\n  region: \"North Holland\"\n  postal_code: \"1012 ZJ\"\n  country: \"Netherlands\"\n  country_code: \"NL\"\n  display: \"Damrak 243, 1012 ZJ Amsterdam, Netherlands\"\n\ncoordinates:\n  latitude: 52.3752\n  longitude: 4.8956\n\nmaps:\n  google: \"https://maps.google.com/?q=Beurs+van+Berlage,+Damrak+243,+Amsterdam\"\n  apple: \"https://maps.apple.com/?q=Beurs+van+Berlage,+Damrak+243,+Amsterdam\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=52.3752&mlon=4.8956\"\n\nhotels:\n  - name: \"The Hoxton, Lloyd\"\n    kind: \"Speaker Hotel\"\n    address:\n      street: \"34 Oostelijke Handelskade\"\n      city: \"Amsterdam\"\n      region: \"Noord-Holland\"\n      postal_code: \"1019 BN\"\n      country: \"Netherlands\"\n      country_code: \"NL\"\n      display: \"Oostelijke Handelskade 34, 1019 BN Amsterdam, Netherlands\"\n    description: |-\n      Official speaker hotel for Rails World 2023\n    distance: \"15 min by tram from venue\"\n    url: \"https://thehoxton.com/amsterdam/lloyd/\"\n    coordinates:\n      latitude: 52.374217\n      longitude: 4.934797\n    maps:\n      apple:\n        \"https://maps.apple.com/place?address=Oostelijke%20Handelskade%2034,%201019%20BN%20Amsterdam,%20Netherlands&coordinate=52.374217,4.934797&name=The%20Hoxton,%20Lloyd%20Amste\\\n        rdam&place-id=I55CB3A572C2A0BEF&map=transit\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2023/videos.yml",
    "content": "---\n# Website: https://rubyonrails.org/world/2023\n# Schedule: https://rubyonrails.org/world/2023/agenda\n\n## Day 1: October 5, 2023\n\n- id: \"david-heinemeier-hansson-rails-world-2023\"\n  title: \"Opening Keynote\"\n  raw_title: \"Rails World 2023 Opening Keynote - David Heinemeier Hansson\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-11\"\n  track: \"Track 1\"\n  description: |-\n    In the Opening Keynote of the first Rails World, Ruby on Rails creator and @37signals CTO David Heinemeier Hansson (@davidheinemeierhansson9989) covered a lot of ground, including introducing 7 major tools: Propshaft, Turbo 8, Strada, Solid Cache, Solid Queue, Mission Control, and Kamal.\n\n    Links:\n    https://rubyonrails.org/\n    https://hotwired.dev/\n    https://kamal-deploy.org/\n    https://github.com/rails/propshaft\n    https://rubyonrails.org/foundation\n\n    #RubyonRails #Rails #Rails7 #Propshaft #Turbo #Strada #SolidCache #SolidQueue #Kamal #missioncontrol #opensource #RailsWorld\n  video_provider: \"youtube\"\n  video_id: \"iqXjGiQ_D-A\"\n  additional_resources:\n    - name: \"rails/propshaft\"\n      type: \"repo\"\n      url: \"https://github.com/rails/propshaft\"\n\n- id: \"jay-ohms-rails-world-2023\"\n  title: \"Strada: Bridging The Web and Native Worlds\"\n  raw_title: \"Jay Ohms - Strada: Bridging the web and native worlds - Rails World 2023\"\n  speakers:\n    - Jay Ohms\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  description: |-\n    Strada is the missing library to take your Turbo Native apps to the next level. Turbo Native enables web developers to ship native apps, but the experience is limited to a WebView container within a native shell. The native app doesn’t have any knowledge about the web content that is being rendered, but Strada bridges that gap.\n    \\\n    As part of the Hotwire family, Strada leverages the HTML you already have to enable high-fidelity native interactions on iOS and Android that are driven by your web app. 37signals Mobile Lead & Principal Programmer Jay Ohms walks us through it.\n\n    Links:\n    https://rubyonrails.org/\n    https://strada.hotwired.dev/\n\n    #RailsWorld #RubyonRails #Hotwire #strada\n  video_provider: \"youtube\"\n  video_id: \"LKBMXqc43Q8\"\n\n- id: \"donal-mcbreen-rails-world-2023\"\n  title: \"Solid Cache: A Disk Backed Rails Cache\"\n  raw_title: \"Donal McBreen - Solid Cache: A disk backed Rails cache - Rails World 2023\"\n  speakers:\n    - Donal McBreen\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  description: |-\n    A disk cache can hold much more data than a memory one. But is it fast enough?\n\n    At @37signals they built Solid Cache, a database backed ActiveSupport cache, to test this out. Running in production on hey.com, they now cache months' rather than days' of data.\n    \\\n    The result: emails are 40% faster to display and it costs less to run.\n\n    Links:\n    https://rubyonrails.org/\n    https://github.com/rails/solid_cache\n    https://dev.37signals.com/solid-cache/\n\n    #RailsWorld #RubyonRails #SolidCache #database #ActiveSupport\n  video_provider: \"youtube\"\n  video_id: \"wYeVne3aRow\"\n  additional_resources:\n    - name: \"rails/solid_cache\"\n      type: \"repo\"\n      url: \"https://github.com/rails/solid_cache\"\n\n- id: \"jorge-manrubia-rails-world-2023\"\n  title: \"Making a Difference with Turbo\"\n  raw_title: \"Jorge Manrubia - Making a difference with Turbo - Rails World 2023\"\n  speakers:\n    - Jorge Manrubia\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  slides_url: \"https://dev.37signals.com/assets/files/a-happier-happy-path-in-turbo-with-morphing/rails-world-2023-making-difference-with-turbo.pdf\"\n  description: |-\n    Hotwire is about building snappy user interfaces while maximizing developer happiness, about bringing innovations while respecting how the web works. What if we could make a step forward on all those fronts?\n\n    At @37signals, they developed a little Turbo addition that they believe can make a big difference for everyone: morphing. Jorge Manrubia, Leader Programmer at 37signals walks us through it in his talk at Rails World.\n\n    Slides: https://dev.37signals.com/assets/files/a-happier-happy-path-in-turbo-with-morphing/rails-world-2023-making-difference-with-turbo.pdf\n\n    Links:\n    https://dev.37signals.com/a-happier-happy-path-in-turbo-with-morphing/\n    https://turbo.hotwired.dev/\n    https://rubyonrails.org/\n\n    #RubyonRails #Rails #turbo #hotwire #Rails7 #RailsWorld\n  video_provider: \"youtube\"\n  video_id: \"m97UsXa6HFg\"\n\n- id: \"kylie-stradley-rails-world-2023\"\n  title: \"Everything We Learned While Implementing ActiveRecord::Encryption\"\n  raw_title: \"Kylie Stradley - Everything We Learned While Implementing ActiveRecord::Encryption - Rails World\"\n  speakers:\n    - Kylie Stradley\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  description: |-\n    ‪@GitHub‬ encrypts your data at rest, as well as specific sensitive database columns. What you may not know is that they recently replaced their in-house db column encryption strategy with ActiveRecord::Encryption, in place. While they were able to complete this transition seamlessly for GitHub’s developers, the process was not quite seamless for our team and some of our customers, and mistakes were made along the way.\n\n    Senior Product Security Engineer Kylie Stradley shares why despite the mistakes they feel the migration was worth it for their team, GitHub developers and most importantly, GitHub customers.\n\n    Slides available here: https://speakerdeck.com/kyfast/railsw...\n\n    Links:\n    https://rubyonrails.org/\n    https://github.blog/changelog/2022-08-18-false-alert-flags-will-appear-in-users-security-log-due-to-a-bug-in-2fa-recovery-events/\n\n    #RailsWorld #RubyonRails #Rails7 #opensource #OSS #Rails #ActiveRecord #encryption #GitHub\n\n    Thank you Dell APEX for sponsoring the editing and post-production of these videos. Visit them at: https://dell.com/APEX\n  video_provider: \"youtube\"\n  video_id: \"IR2demNrMwQ\"\n  slides_url: \"https://speakerdeck.com/kyfast/railsworld-2023-everything-we-learned-the-hard-way-implementing-activerecord-encryption\"\n  additional_resources:\n    - name: \"False-alert flags will appear in users security log due to a bug in 2FA recovery events\"\n      type: \"blog\"\n      title: \"False-alert flags will appear in users security log due to a bug in 2FA recovery events\"\n      url: \"https://github.blog/changelog/2022-08-18-false-alert-flags-will-appear-in-users-security-log-due-to-a-bug-in-2fa-recovery-events/\"\n\n# Lunch\n\n- id: \"marco-roth-rails-world-2023\"\n  title: \"The Future of Rails as a Full-Stack Framework powered by Hotwire\"\n  raw_title: \"Marco Roth - The Future of Rails as a Full-Stack Framework powered by Hotwire - Rails World 2023\"\n  speakers:\n    - Marco Roth\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  slides_url: \"https://speakerdeck.com/marcoroth/the-future-of-rails-as-a-full-stack-framework-powered-by-hotwire\"\n  description: |-\n    Hotwire has revolutionized the way we build interactive web applications using Ruby on Rails. In this talk, Marco Roth, the maintainer of Stimulus, StimulusReflex and CableReady, takes an in-depth look at the recent advancements in Hotwire and shares guidance on how to effectively utilize Stimulus, Turbo, and other related frameworks.\n\n    Slides available at: https://speakerdeck.com/marcoroth/the-future-of-rails-as-a-full-stack-framework-powered-by-hotwire\n\n    Links:\n    https://rubyonrails.org/\n    https://hotwired.dev/\n    https://hotwire.io/\n    https://github.com/marcoroth/hotwire.io\n\n    #RailsWorld #RubyonRails #Hotwire #Turbo #Stimulus #Fullstack\n  video_provider: \"youtube\"\n  video_id: \"iRjei4nj41o\"\n  additional_resources:\n    - name: \"hotwire.io\"\n      type: \"link\"\n      url: \"https://hotwire.io\"\n\n    - name: \"marcoroth/hotwire.io\"\n      type: \"repo\"\n      url: \"https://github.com/marcoroth/hotwire.io\"\n\n- id: \"adrianna-chang-rails-world-2023\"\n  title: \"Migrating Shopify's Core Rails Monolith to Trilogy\"\n  raw_title: \"Adrianna Chang - Migrating Shopify’s Core Rails Monolith to Trilogy - Rails World 2023\"\n  speakers:\n    - Adrianna Chang\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  description: |-\n    Trilogy is a client library for MySQL-compatible database servers. It was open sourced along with an Active Record adapter by GitHub this past year. With promises of improved performance, better portability and compatibility, and fewer dependencies, Shopify’s Rails Infrastructure team decided to migrate our core Rails monolith from Mysql2 to Trilogy.\n\n    @shopify Senior Software Developer Adrianna Chang explores why the Trilogy client was built and why Shopify wanted to adopt it.\n\n    Links:\n    https://rubyonrails.org/\n\n    #RailsWorld #RubyonRails #rails #opensource #MySQL #ActiveRecord #Trilogy\n  video_provider: \"youtube\"\n  video_id: \"AUV3Xgy-zuE\"\n\n# 13:30 - 14:30 - Workshop - Test Smarter, Not Harder - Crafting a Test Selection Framework from Scratch  - Christian Bruckmayer, Staff Engineer, Shopify\n\n- id: \"alicia-rojas-rails-world-2023\"\n  title: \"Building an Offline Experience with a Rails-powered PWA\"\n  raw_title: \"Alicia Rojas - Building an offline experience with a Rails-powered PWA - Rails World 2023\"\n  speakers:\n    - Alicia Rojas\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  description: |-\n    Progressive web apps (PWAs) allow us to provide rich offline experiences as native apps would, while still being easy to use and share, as web apps are. Learn how to turn your regular Rails app into a PWA, taking advantage of the front-end tools that come with Rails by default since version 7.\n\n    Telos Labs Software Engineer Alicia Rojas covers exciting stuff such as: caching and providing an offline fallback, how to make your app installable, and performing offline CRUD actions with IndexedDB and Hotwire.\n\n    Note: Most code samples from this talk belong to a case study of an application conceived for rural people living in areas lacking stable internet access, such as farmers and agricultural technicians.\n\n    Links:\n    https://rubyonrails.org/\n    https://hotwired.dev/\n\n    #RailsWorld #RubyonRails #progressivewebapps  #Rails #Rails7 #Hotwire\n  video_provider: \"youtube\"\n  video_id: \"Gj8ov0cOuA0\"\n\n- id: \"miles-mcguire-rails-world-2023\"\n  title: \"Guardrails: Keeping Customer Data Separate in a Multi Tenant System\"\n  raw_title: \"Miles McGuire - Guardrails: Keeping customer data separate in a multi tenant system - Rails World\"\n  speakers:\n    - Miles McGuire\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  description: |-\n    @Intercominc Staff Engineer Miles McGuire shares the solution they created to ensure that they never “cross the streams” on customer data using ActiveRecord and Rails’ MemCacheStore, as well as the exciting knock-on benefits it offered for observability.\n\n    Links:\n    https://rubyonrails.org/\n    https://api.rubyonrails.org/classes/ActiveSupport/Cache/MemCacheStore.html\n\n    #RailsWorld #RubyonRails #Rails7 #security #datasecurity #observability #ActiveRecord\n  video_provider: \"youtube\"\n  video_id: \"5MLT-QP4S74\"\n\n# 14:45 - 16:15 -Workshop - AI Driven Development - Sean Marcia, Founder, Ruby for Good\n\n- id: \"nikita-vasilevsky-rails-world-2023\"\n  title: \"Implementing Native Composite Primary Key Support in Rails 7.1\"\n  raw_title: \"Nikita Vasilevsky - Implementing Native Composite Primary Key Support in Rails 7.1 - Rails World '23\"\n  speakers:\n    - Nikita Vasilevsky\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  slides_url: \"https://speakerdeck.com/nikitavasilevsky/rails-world-2023-composite-primary-keys-in-rails-7-dot-1\"\n  description: |-\n    Explore the new feature of composite primary keys in Rails 7.1! @shopify developer and member of the Rails triage team Nikita Vasilevsky provides a thorough understanding of composite primary keys, the significance of the “ID” concept in Rails, and the crucial role of the “query constraints” feature in making this powerful feature work seamlessly.\n\n    Slides are available at https://speakerdeck.com/nikitavasilevsky/rails-world-2023-composite-primary-keys-in-rails-7-dot-1\n\n    Links:\n    https://rubyonrails.org/\n\n    #RailsWorld #RubyonRails #Rails7 #compositeprimarykey\n  video_provider: \"youtube\"\n  video_id: \"aOD0bZfQvoY\"\n\n- id: \"xavier-noria-rails-world-2023\"\n  title: \"Zeitwerk Internals\"\n  raw_title: \"Xavier Noria - Zeitwerk Internals - Rails World 2023\"\n  speakers:\n    - Xavier Noria\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  slides_url: \"https://www.slideshare.net/fxn/zeitwerk-internals\"\n  description: |-\n    Zeitwerk is the Ruby gem responsible for autoloading code in modern Rails applications.\n\n    Rails Core member Xavier Noria walks you through how Zeitwerk works, from a conceptual overview down to implementation details and interface design.\n\n    This talk is geared towards both seasoned Ruby developers looking to have a deep undertanding of Zeitwerk, as well as Rails beginners curious to know how this aspect of Rails works.\n\n    Slides available at: https://www.slideshare.net/fxn/zeitwerk-internals\n\n    Other links:\n    https://rubyonrails.org/\n    https://rubyonrails.org/community\n    https://github.com/rails\n    https://hashref.com/\n    https://github.com/fxn/zeitwerk\n\n    #RailsWorld #RubyonRails #rails #Rails7 #opensource #oss #community #RailsCore #Zeitwerk #rubygem\n  video_provider: \"youtube\"\n  video_id: \"YTMS1N7jI78\"\n  additional_resources:\n    - name: \"fxn/zeitwerk\"\n      type: \"repo\"\n      url: \"https://github.com/fxn/zeitwerk\"\n\n- id: \"julia-lpez-rails-world-2023\"\n  title: \"Using Multiple Databases with Active Record\"\n  raw_title: \"Julia López - Using Multiple Databases with Active Record - Rails World 2023\"\n  speakers:\n    - Julia López\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  slides_url: \"https://speakerdeck.com/yukideluxe/using-multiple-databases-with-active-record\"\n  description: |-\n    ActiveRecord is one of the core modules of Rails. Not-so-well-known features like support for multiple databases added in Rails 6.0 are very easy to set up and customize.\n\n    Harvest Senior Software Engineer Julia López introduces some of the reasons why having multiple databases makes sense, and how you can extend Rails’ capabilities to match your application needs.\n\n    Slides available at: https://speakerdeck.com/yukideluxe/using-multiple-databases-with-active-record\n\n    Links:\n    https://rubyonrails.org/\n    https://guides.rubyonrails.org/active_record_basics.html\n    https://guides.rubyonrails.org/active_record_multiple_databases.html\n\n    #RubyonRails #Rails #database #ActiveRecord #multipledatabases\n  video_provider: \"youtube\"\n  video_id: \"XjCqiyYVypI\"\n\n- id: \"breno-gazzola-rails-world-2023\"\n  title: \"Propshaft and the Modern Asset Pipeline\"\n  raw_title: \"Breno Gazzola - Propshaft and the Modern Asset Pipeline - Rails World 2023\"\n  speakers:\n    - Breno Gazzola\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  description: |-\n    Breno Gazzola, Co-Founder & CTO of FestaLab, discusses Propshaft, the heart of the new asset pipeline introduced in Rails 7.\n\n    Rails 7 brought with it an overhauled asset pipeline that delivered a default “no-Node” approach to front end and improved support for modern bundlers like esbuild. This is great for developers as we are constantly searching for ways to make the development process more pleasant and to deliver better user experiences.\n\n    However, the introduction of multiple gems that seem to have overlapping features has left many of you confused about how to take advantage of everything that Rails 7 has to offer.\n\n    You want to make sure that when you create your next app, or update an existing one, you are making the correct choice and will not have to go back and redo a large part of your frontend. But to make that decision we have to understand what makes the new asset pipeline so different from the previous one.\n\n    Links:\n    https://rubyonrails.org/\n    https://github.com/rails/propshaft\n    https://world.hey.com/dhh/introducing-propshaft-ee60f4f6\n    https://github.com/rails/propshaft/blob/main/UPGRADING.md\n    https://discuss.rubyonrails.org/t/guide-to-rails-7-and-the-asset-pipeline/80851\n\n    #RailsWorld #RubyonRails #rails #Rails7 #opensource #propshaft #asssetpipeline #Rubygem\n  video_provider: \"youtube\"\n  video_id: \"yFgQco_ccgg\"\n  additional_resources:\n    - name: \"rails/propshaft\"\n      type: \"repo\"\n      url: \"https://github.com/rails/propshaft\"\n\n    - name: \"Upgrading Guide\"\n      title: \"Upgrading Guide\"\n      type: \"repo\"\n      url: \"https://github.com/rails/propshaft/blob/main/UPGRADING.md\"\n\n    - name: \"Introducing Propshaft\"\n      title: \"Introducing Propshaft\"\n      type: \"link\"\n      url: \"https://world.hey.com/dhh/introducing-propshaft-ee60f4f6\"\n\n    - name: \"Guide to Rails 7 and the Asset Pipeline\"\n      title: \"Guide to Rails 7 and the Asset Pipeline\"\n      type: \"link\"\n      url: \"https://discuss.rubyonrails.org/t/guide-to-rails-7-and-the-asset-pipeline/80851\"\n\n- id: \"eileen-m-uchitelle-rails-world-2023\"\n  title: \"Keynote: The Magic of Rails\"\n  raw_title: \"Eileen Uchitelle - The Magic of Rails - Rails World 2023\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-05\"\n  published_at: \"2023-10-17\"\n  track: \"Track 1\"\n  slides_url: \"https://speakerdeck.com/eileencodes/rails-world-2023-day-1-closing-keynote-the-magic-of-rails\"\n  description: |-\n    Rails Core member and @shopify Senior Staff Software Engineer Eileen Uchitelle explores the magic of Rails in her keynote at Rails World. From taking a look at the philosophy behind the framework to exploring some of the common patterns that Rails uses to build agnostic and beautiful interfaces, Eileen helps you navigate the Rails codebase to better understand the patterns it uses to create the framework we all know and love.\n\n    But Rails is so much more than its design and architecture. Eileen also shares her motivation for working on the framework and why the community is so important to the long term success of Rails.\n\n    Slides available at: https://speakerdeck.com/eileencodes/rails-world-2023-day-1-closing-keynote-the-magic-of-rails\n\n    Other links:\n    https://rubyonrails.org/\n    https://github.com/rails\n    https://rubyonrails.org/community\n\n    #RailsWorld #RubyonRails #rails #Rails7 #opensource #oss #community #RailsCore\n  video_provider: \"youtube\"\n  video_id: \"nvuPisDQ1hI\"\n\n## Day 2 - October 6, 2023\n\n- id: \"aaron-patterson-rails-world-2023\"\n  title: \"Rails Core AMA\"\n  raw_title: \"Rails Core AMA - Rails World 2023\"\n  speakers:\n    - Aaron Patterson\n    - Carlos Antonio Da Silva\n    - David Heinemeier Hansson\n    - Eileen M. Uchitelle\n    - Jean Boussier\n    - Jeremy Daer\n    - John Hawthorn\n    - Matthew Draper\n    - Rafael Mendonça França\n    - Xavier Noria\n    - Robby Russell\n  event_name: \"Rails World 2023\"\n  published_at: \"2023-10-16\"\n  date: \"2023-10-06\"\n  track: \"Track 1\"\n  description: |-\n    Ten of the current 12 Rails Core members sat down to answer questions submitted by the Rails World audience in Amsterdam, such as: How do they decide on which features to add? How should Rails evolve in the future? What does it take to join the Core team?\n\n    Rails Core members present were: Aaron Patterson, Carlos Antonio Da Silva, David Heinemeier Hansson, Eileen M. Uchitelle, Jean Boussier, Jeremy Daer, John Hawthorn, Matthew Draper, Rafael Mendonça França, and Xavier Noria.\n\n    Hosted by @Planetargon founder and CEO @RobbyRussell.\n\n    Links:\n    https://rubyonrails.org/community\n    https://rubyonrails.org/\n    https://github.com/rails\n    https://www.planetargon.com/\n\n    #RubyonRails #Rails #RailsCore #AMA #RailsWorld #opensource\n  video_provider: \"youtube\"\n  video_id: \"9GzYoUFIkwE\"\n\n- id: \"chris-oliver-rails-world-2023\"\n  title: \"Powerful Rails Features You Might Not Know\"\n  raw_title: \"Chris Oliver - Powerful Rails Features You Might Not Know - Rails World 2023\"\n  speakers:\n    - Chris Oliver\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  slides_url: \"https://speakerdeck.com/excid3/powerful-rails-features-you-might-not-know\"\n  description: |-\n    An unbelievable amount of features are packed into Rails making it one of the most powerful web frameworks you can use. @GorailsTV creator Chris Oliver takes a look at some little known, underused, and new things in Rails 7.\n\n    A few of the topics covered:\n    - ActiveRecord features like “excluding”, strict_loading, virtual columns, with_options, attr_readonly, etc\n    - ActiveStorage named variants\n    - ActionText embedding any database record\n    - Custom Turbo Stream Actions with Hotwire\n    - Turbo Native authentication with your Rails backend\n    - ActiveSupport features like truncate_words\n    - Rails 7.1’s new features: authentication, normalizes, logging background enqueue callers, and more.\n\n    Links:\n    https://rubyonrails.org/\n    https://rubyonrails.org/2023/10/5/Rails-7-1-0-has-been-released\n\n    #RailsWorld #RubyonRails #Rails7 #opensource #OSS #Rails #ActiveRecord #ActiveStorage #ActiveSupport\n  video_provider: \"youtube\"\n  video_id: \"iPCqwZ9Ouc4\"\n\n- id: \"peter-zhu-rails-world-2023\"\n  title: \"Rails and the Ruby Garbage Collector: How to Speed Up Your Rails App\"\n  raw_title: \"Peter Zhu - Rails and the Ruby Garbage Collector: How to Speed Up Your Rails App - Rails World 2023\"\n  speakers:\n    - Peter Zhu\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  slides_url: \"https://blog.peterzhu.ca/assets/rails_world_2023_slides.pdf\"\n  description: |-\n    The Ruby garbage collector is a highly configurable component of Ruby. However, it’s a black box to most Rails developers.\n\n    In this talk, @shopify Senior Developer & member of the Ruby Core team Peter Zhu shows you how Ruby's garbage collector works, ways to collect garbage collector metrics, how Shopify sped up their highest traffic app, Storefront Renderer, by 13%, and finally, introduces Autotuner, a new tool designed to help you tune the garbage collector of your Rails app.\n\n    Slides available at: https://blog.peterzhu.ca/assets/rails_world_2023_slides.pdf\n\n    Links:\n    https://rubyonrails.org/\n    https://railsatscale.com/2023-08-08-two-garbage-collection-improvements-made-our-storefronts-8-faster/\n    https://github.com/shopify/autotuner\n    https://blog.peterzhu.ca/notes-on-ruby-gc/\n    https://shopify.engineering/adventures-in-garbage-collection\n\n    #RailsWorld #RubyonRails #rails #rubygarbagecollection #autotuner\n  video_provider: \"youtube\"\n  video_id: \"IcN7yFTS8jY\"\n  additional_resources:\n    - name: \"shopify/autotuner\"\n      type: \"repo\"\n      url: \"https://github.com/shopify/autotuner\"\n\n    - name: \"Blog Post\"\n      type: \"blog\"\n      title: \"Garbage Collection in Ruby\"\n      url: \"https://blog.peterzhu.ca/notes-on-ruby-gc/\"\n\n    - name: \"Blog Post\"\n      type: \"blog\"\n      title: \"Adventures in Garbage Collection: Improving GC Performance in our Massive Monolith\"\n      url: \"https://shopify.engineering/adventures-in-garbage-collection\"\n\n- id: \"mike-dalessio-rails-world-2023\"\n  title: \"Rails::HTML5: The Strange and Remarkable Three-Year Journey\"\n  raw_title: \"Mike Dalessio - Rails::HTML5: the strange and remarkable three-year journey - Rails World 2023\"\n  speakers:\n    - Mike Dalessio\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  slides_url: \"https://mike.daless.io/prez/2023/10/06/rails-world-rails-html5\"\n  description: |-\n    Rails 7.1 improved Rails’s security posture and made Rails more friendly with modern browsers by shipping HTML5-compliant sanitizers by default. Great! But the journey there was no a straight road…\n\n    @shopify Director of Engineering Mike Dalessio shares the story of planning and executing a complex migration task on a major open-source project, a multi-year journey that started in 2015 with a security vulnerability and ended after coordinating major changes upstream to Action View, Rails::HTML::Sanitizer, Loofah, and Nokogiri, and taking over maintenance of libgumbo.\n\n    Slides are online at http://mike.daless.io/prez/2023/10/06/rails-world-rails-html5/\n\n    Links:\n    https://rubyonrails.org/\n    https://github.com/rails/rails-html-sanitizer\n    https://api.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html\n\n    #RailsWorld #RubyonRails #rails #Rails7 #opensource #security #HTML5 #nokogiri #libgumbo #actionview\n  video_provider: \"youtube\"\n  video_id: \"USPLEASZ0Dc\"\n  additional_resources:\n    - name: \"rails/rails-html-sanitizer\"\n      type: \"repo\"\n      url: \"https://github.com/rails/rails-html-sanitizer\"\n\n- id: \"jenny-shen-rails-world-2023\"\n  title: \"Demystifying the Ruby Package Ecosystem\"\n  raw_title: \"Jenny Shen - Demystifying the Ruby package ecosystem - Rails World 2023\"\n  speakers:\n    - Jenny Shen\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  slides_url: \"https://github.com/jenshenny/demystifying-ruby-ecosystem\"\n  description: |-\n    RubyGems is the Ruby community’s go to package manager. It hosts over 175 thousand gems – one of which is Rails and others that we use to customize our applications. RubyGems and Bundler do an excellent job in removing the complexities of gem resolution and installation so developers can focus on building great software.\n\n    In this talk, @shopify Senior Developer Jenny Shen takes a look at the inner workings of the Ruby package ecosystem, including:\n    - The processes involved in installing gems from a Gemfile\n    - Insights into debugging gems within a Rails application\n    - Ensuring you’re selecting the right gems to avoid security risks\n\n    Slides available at: https://github.com/jenshenny/demystifying-ruby-ecosystem\n\n    Links:\n    https://rubyonrails.org/\n    https://rubygems.org/\n\n    #RailsWorld #RubyonRails #rails #opensource #OSS #community#Rubygems\n  video_provider: \"youtube\"\n  video_id: \"kaRhg3QDzFY\"\n\n# Lunch\n\n- id: \"joe-masilotti-rails-world-2023\"\n  title: \"Just enough Turbo Native to be dangerous\"\n  raw_title: \"Joe Masilotti - Just enough Turbo Native to be dangerous - Rails World 2023\"\n  speakers:\n    - Joe Masilotti\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  slides_url: \"https://speakerdeck.com/joemasilotti/just-enough-turbo-native-to-be-dangerous\"\n  description: |-\n    Turbo Native gives Rails developers superpowers, enabling us to launch low maintenance but high-fidelity hybrid apps across multiple platforms. All while keeping the core business logic where it matters - in the Ruby code running on the server.\n\n    @joemasilotti, ‘The Turbo Native guy’ will walk you through how to build a Turbo Native iOS app from scratch along with the benefits and pain points that come with it. You’ll dive into ways to make the app feel more native, and how to integrate with native Swift SDKs, and more.\n\n    Slides available at: https://masilotti.com/slides/rails-world-2023/\n\n    Links:\n    https://rubyonrails.org/\n    https://masilotti.com/\n\n    #RailsWorld #RubyonRails #rails #turbo #turbonative #ios #swift #xcode\n  video_provider: \"youtube\"\n  video_id: \"hAq05KSra2g\"\n\n- id: \"ryan-singer-rails-world-2023\"\n  title: \"Applying Shape Up in the Real World\"\n  raw_title: \"Ryan Singer - Applying Shape Up in the Real World - Rails World 2023\"\n  speakers:\n    - Ryan Singer\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  description: |-\n    Teams everywhere are tired of scrum and curious about Shape Up. But very few of them are able to apply it by-the-book, because their companies are structured differently than 37signals, where Shape Up was created.\n\n    That hasn’t reduced the demand, however. People understand that estimating story points and writing better tickets isn’t going to solve their problems. There are disconnects between the vision of what to do and what actually gets built. Building takes longer than expected and scope gets out of control. Programmers are treated like ticket-takers when what they really want is to see the whole problem and creatively solve it.\n\n    Over the last couple years, Ryan Singer, author of ‘Shape Up’, has worked with a wider variety of companies with very different structures — teams with big gaps between junior and senior, where programmers far out-number designers, and where external pressures make six-week cycles out of the question. The result is new language, new techniques, and some broken rules, that will help you apply Shape Up in a way that’s custom-fit to your team.\n\n    Links:\n    https://rubyonrails.org/\n    https://basecamp.com/shapeup\n\n    #RailsWorld #RubyonRails #rails #shapeup #scrum\n  video_provider: \"youtube\"\n  video_id: \"mYbxQwQAkes\"\n\n# 13:30 - 15:00 Workshop - AI Driven Development - Cynthia Lo, Program Manager, GitHub\n\n- id: \"vladimir-dementyev-rails-world-2023\"\n  title: \"Untangling Cables and Demystifying Twisted Transistors\"\n  raw_title: \"Vladimir Dementyev - Untangling cables and demystifying twisted transistors - Rails World 2023\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  slides_url: \"https://speakerdeck.com/palkan/railsworld-2023-untangling-cables-and-demystifying-twisted-transistors\"\n  description: |-\n    More and more Rails applications adopt real-time features, and it’s not surprising - Action Cable and Hotwire brought development experience to the next level regarding dealing with WebSockets. You need zero knowledge of the underlying tech to start crafting a new masterpiece of web art.\n\n    However, you will need this knowledge later to deal with ever-sophisticated feature requirements and security and scalability concerns. @evil.martians Cable Engineer Vladimir Dementyev helps you understand Rails’ real-time component, Action Cable so you can work with it efficiently and confidently.\n\n    Slides available at: https://speakerdeck.com/palkan/railsworld-2023-untangling-cables-and-demystifying-twisted-transistors\n\n    Links:\n    https://rubyonrails.org/\n\n    #RailsWorld #RubyonRails #rails #actioncable\n  video_provider: \"youtube\"\n  video_id: \"GrHpop5HtxM\"\n\n- id: \"adam-wathan-rails-world-2023\"\n  title: \"Tailwind CSS: It looks awful, and it works\"\n  raw_title: \"Adam Wathan - Tailwind CSS: It looks awful, and it works - Rails World 2023\"\n  speakers:\n    - Adam Wathan\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  description: |-\n    In his talk at #RailsWorld, Tailwind CSS creator @AdamWathan of @TailwindLabs will explain why “separation of concerns” isn’t the right way to think about the relationship between HTML and CSS, why presentational class names lead to code that’s so much easier to maintain, as well as loads of tips, tricks, and best practices for getting the most out of Tailwind CSS.\n\n    Links:\n    https://rubyonrails.org/\n    https://tailwindcss.com/\n\n    #RailsWorld #RubyonRails #Rails #railwindcss #tailwind #frontend\n  video_provider: \"youtube\"\n  video_id: \"TNXM4bqGqek\"\n\n- id: \"yaroslav-shmarov-rails-world-2023\"\n  title: \"Hotwire Cookbook: Common Uses, Essential Patterns & Best Practices\"\n  raw_title: \"Yaroslav Shmarov - Hotwire Cookbook: Common Uses, Essential Patterns & Best Practices  - Rails World\"\n  speakers:\n    - Yaroslav Shmarov\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  slides_url: \"https://www.icloud.com/keynote/031WsmVqF1yJVtjl2riyTgw_A#RailsWorld_2023_Hotwire_Cookbook_Yaroslav_Shmarov\"\n  description: |-\n    @SupeRails creator and Rails mentor Yaroslav Shmarov shares how some of the most common frontend problems can be solved with Hotwire.\n\n    He covers:\n    - Pagination, search and filtering, modals, live updates, dynamic forms, inline editing, drag & drop, live previews, lazy loading & more\n    - How to achieve more by combining tools (Frames + Streams, StimulusJS, RequestJS, Kredis & more)\n    - What are the limits of Hotwire?\n    - How to write readable and maintainable Hotwire code\n    - Bad practices\n\n    Slides available at: https://www.icloud.com/keynote/031WsmVqF1yJVtjl2riyTgw_A#RailsWorld_2023_Hotwire_Cookbook_Yaroslav_Shmarov\n\n    Links:\n    https://rubyonrails.org/\n    https://superails.com/\n    https://hotwired.dev/\n\n    #RailsWorld #RubyonRails #rails #hotwire #stimulusjs #turbo #turbolinks #domid #kredis #turboframes #turbostreams\n  video_provider: \"youtube\"\n  video_id: \"F75k4Oc6g9Q\"\n\n- id: \"irina-nazarova-rails-world-2023\"\n  title: \"Wildest Dreams of Making Profit on Open Source\"\n  raw_title: \"Irina Nazarova - Wildest Dreams of Making Profit on Open Source - Rails World 2023\"\n  speakers:\n    - Irina Nazarova\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  slides_url: \"https://speakerdeck.com/irinanazarova/wildest-dreams-of-making-profit-on-open-source-rails-world-2023-irina-nazarova\"\n  description: |-\n    Commercialized open source has effectively supported authors while also maintaining the benefits that open principles have on the industry. By obtaining an adequate share of the value we create, we’ll be able to work on industry-changing projects we’re passionate about for years to come.\n\n    Yet, achieving success in this domain is not without its challenges. We must be willing to learn, experiment, and overcome obstacles along the way. In this talk, @evil.martians CEO Irina Nazarova will unveil her insights on navigating this journey, harnessing the power of Rails at every stage.\n\n    Links:\n    https://rubyonrails.org/\n    https://evilmartians.com/\n\n    #RailsWorld #RubyonRails #rails #opensource #OSS\n  video_provider: \"youtube\"\n  video_id: \"gHUSoXJtatc\"\n\n# 15:00 - 16:00 - Workshop - Test Smarter, Not Harder - Crafting a Test Selection Framework from Scratch - Christian Bruckmayer, Staff Engineer, Shopify\n\n- id: \"jason-charnes-rails-world-2023\"\n  title: \"Don't Call It a Comeback\"\n  raw_title: \"Jason Charnes - Don't Call It a Comeback - Rails World 2023\"\n  speakers:\n    - Jason Charnes\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 1\"\n  slides_url: \"https://railsworld2023.jasoncharnes.com\"\n  description: |-\n    Jason Charnes, Staff Product Developer at Podia, encourages you to celebrate Rails and contribute to the movement. But don’t call it a comeback, because Rails never left.\n\n    Slides available at: https://railsworld2023.jasoncharnes.com\n\n    Links:\n    https://rubyonrails.org/\n\n    #RailsWorld #RubyonRails #rails #opensource #OSS #community\n  video_provider: \"youtube\"\n  video_id: \"Dj8VGizRT6E\"\n\n- id: \"brian-scalan-rails-world-2023\"\n  title: \"Monolith-ifying Perfectly Good Microservices\"\n  raw_title: \"Brian Scalan - Monolith-ifying perfectly good microservices - Rails World 2023\"\n  speakers:\n    - Brian Scalan\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-19\"\n  track: \"Track 2\"\n  description: |-\n    Many conference talks have been created from engineers splitting services out of dusty old monolith apps. However, @Intercominc did the exact opposite - they moved multiple services back into their monolith and got huge productivity and reliability wins, allowing them to ship better features to their customers.\n\n    Senior Principal Systems Engineer Brian Scanlan covers the reasons why these services existed in the first place, why they felt the need to move them into their monolith, whether the moves back into the monolith were successful and what they learned along the way, including which parts of Ruby on Rails helped or hindered them!\n\n    Links:\n    https://rubyonrails.org/\n\n    #RailsWorld #RubyonRails #rails #Rails7 #opensource #monolith #microservices\n  video_provider: \"youtube\"\n  video_id: \"wV1Yva-Dp4Y\"\n\n- id: \"aaron-patterson-rails-world-2023-keynote-future-of-developer-ac\"\n  title: \"Keynote: Future of Developer Acceleration with Rails\"\n  raw_title: \"Aaron Patterson - Future of Developer Acceleration with Rails - Rails World 2023\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Rails World 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-10-18\"\n  track: \"Track 1\"\n  description: |-\n    What would development be like if Rails had tight integration with Language Servers? Rails Core member and Shopify Senior Staff Engineer Aaron Patterson takes a look at how language servers work, how we can improve language server support in Rails, and how this will increase our productivity as Rails developers.\n\n    #RailsWorld #RubyonRails #Rails #languageserver #LSP #opensource\n\n    Links:\n    https://rubyonrails.org/\n  video_provider: \"youtube\"\n  video_id: \"GnqRMQ0iQTg\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2024/cfp.yml",
    "content": "---\n- link: \"https://docs.google.com/forms/d/e/1FAIpQLSdTKiwbhAo4leeOl-HPIG2gFVzvmWjEtBFV6mC4ueY2Gso44g/viewform\"\n  open_date: \"2024-08-30\"\n  close_date: \"2024-09-10\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2024/event.yml",
    "content": "---\nid: \"PLHFP2OPUpCeb182aDN5cKZTuyjn3Tdbqx\"\ntitle: \"Rails World 2024\"\nkind: \"conference\"\nlocation: \"Toronto, Canada\"\ndescription: |-\n  Rails World was a two-day, two track community conference where more than 1,000 Rails developers from 57 countries gathered to hear technical talks, demos, networking, and keynotes about the latest features and best practices in Rails development.\npublished_at: \"2024-10-16\"\nstart_date: \"2024-09-26\"\nend_date: \"2024-09-27\"\nchannel_id: \"UC9zbLaqReIdoFfzdUbh13Nw\"\nyear: 2024\nbanner_background: \"#4E2A73\"\nfeatured_background: \"#4E2A73\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubyonrails.org/world/2024\"\ncoordinates:\n  latitude: 43.6847\n  longitude: -79.365\n"
  },
  {
    "path": "data/rails-world/rails-world-2024/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Amanda Perino\n\n  organisations:\n    - Rails Foundation\n\n- name: \"Website Developer\"\n  users:\n    - John Farina\n"
  },
  {
    "path": "data/rails-world/rails-world-2024/schedule.yml",
    "content": "# Schedule: https://rubyonrails.org/world/2024/agenda\n---\ndays:\n  - name: \"Day 0\"\n    date: \"2024-09-25\"\n    grid:\n      - start_time: \"16:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - title: \"Early registration, sponsored by Shopify\"\n            description: |-\n              Registration opens for those who are already in town. Avoid the Thursday morning line, get your badge, and grab a drink with other attendees. Sponsored by Shopify, Rails World City Host.\n\n      - start_time: \"16:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - title: \"WNB.rb pre-Rails World meetup, sponsored by Shopify\"\n            description: |-\n              A chance for women and non-binary Rails World attendees to meet up before Rails World. Hosted by WNB.rb and sponsored by Shopify. The location and time of this event will be shared with registered attendees via the event app.\n\n  - name: \"Day 1\"\n    date: \"2024-09-26\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - title: \"Doors Open\"\n            description: |-\n              Rails World attendees are welcome to register, enter, and grab a coffee before the keynote begins.\n\n      - start_time: \"09:45\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Break\n\n      # TODO: Lightning Talk slot is not exactly correct\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 3\n\n      - start_time: \"11:45\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      # TODO: Workshop slot is not exactly correct\n      - start_time: \"13:00\"\n        end_time: \"13:30\"\n        slots: 3\n\n      - start_time: \"13:30\"\n        end_time: \"13:45\"\n        slots: 1\n        items:\n          - Break\n\n      # TODO: Lightning Talk slot is not exactly correct\n      - start_time: \"13:45\"\n        end_time: \"14:15\"\n        slots: 3\n\n      - start_time: \"14:15\"\n        end_time: \"14:45\"\n        slots: 1\n        items:\n          - Break\n\n      # TODO: Lightning Talk slot is not exactly correct\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 3\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 2\n\n      - start_time: \"16:15\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:30\"\n        end_time: \"17:30\"\n        slots: 1\n\n      - start_time: \"18:30\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - title: \"Toronto Ruby Drinks sponsored by Clio\"\n            description: |-\n              Come hang out with the local Toronto Ruby meetup group. Grab a beer and have a bite, and recharge for Day 2.\n\n              This evening event wouldn’t be possible without the generous support and sponsorship of our Gold sponsor, Clio. Stop by their booth for a ticket to the event. Badges still required.\n\n  - name: \"Day 2\"\n    date: \"2024-09-27\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - title: \"Doors Open\"\n            description: |-\n              Rails World attendees are welcome to register, enter, and grab a coffee and light breakfast before the keynote begins.\n\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Break\n\n      # TODO: Lightning Talk slot is not exactly correct\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 3\n\n      - start_time: \"11:45\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      # TODO: Workshop slot is not exactly correct\n      - start_time: \"13:00\"\n        end_time: \"13:30\"\n        slots: 3\n\n      - start_time: \"13:30\"\n        end_time: \"13:45\"\n        slots: 1\n        items:\n          - Break\n\n      # TODO: Lightning Talk slot is not exactly correct\n      - start_time: \"13:45\"\n        end_time: \"14:15\"\n        slots: 3\n\n      - start_time: \"14:15\"\n        end_time: \"14:45\"\n        slots: 1\n        items:\n          - Break\n\n      # TODO: Lightning Talk slot is not exactly correct\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 3\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 2\n\n      - start_time: \"16:15\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:30\"\n        end_time: \"17:30\"\n        slots: 1\n\n      - start_time: \"18:30\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - title: \"Shopify Closing Party\"\n            description: |-\n              Join us as we close out Rails World with a takeover at the Shopify Port. Three floors of music, games, food, drink, and fun, with plenty of space for pair programming if you have any code you need to tackle. Pre-registration will be required (attendees will be sent more details). Don’t forget your badge!\n\ntracks:\n  - name: \"Track 1 (Hosted by GitHub)\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n\n  - name: \"Track 2 (Hosted by AppSignal)\"\n    color: \"#04246E\"\n    text_color: \"#ffffff\"\n\n  - name: \"Lightning Talk Track (Hosted by Shopify)\"\n    color: \"#95BF47\"\n    text_color: \"#ffffff\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum\"\n      description: |-\n        Top tier sponsors\n      level: 1\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com/\"\n          slug: \"shopify\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-shopify.svg\"\n\n        - name: \"GitHub\"\n          website: \"https://www.github.com/\"\n          slug: \"github\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-github.svg\"\n\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-appsignal.svg\"\n\n    - name: \"Gold\"\n      description: |-\n        Second tier sponsors\n      level: 2\n      sponsors:\n        - name: \"Clio\"\n          website: \"https://www.clio.com/\"\n          slug: \"clio\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-clio.svg\"\n\n        - name: \"Huntress\"\n          website: \"https://www.huntress.com/\"\n          slug: \"huntress\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-huntress.svg\"\n\n        - name: \"Valkey\"\n          website: \"https://valkey.io/\"\n          slug: \"valkey\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-valkey.svg\"\n\n        - name: \"Crunchy Data\"\n          website: \"https://www.crunchydata.com/\"\n          slug: \"crunchydata\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-crunchydata.svg\"\n\n        - name: \"Framework\"\n          website: \"https://frame.work/\"\n          slug: \"framework\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-framework.png\"\n\n        - name: \"Happy Scribe\"\n          website: \"https://www.happyscribe.com/\"\n          slug: \"happyscribe\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-happyscribe.svg\"\n\n        - name: \"MongoDB\"\n          website: \"https://www.mongodb.com/\"\n          slug: \"mongodb\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-mongodb.svg\"\n\n        - name: \"Paraxial\"\n          website: \"https://paraxial.io/\"\n          slug: \"paraxial\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-paraxial.svg\"\n\n        - name: \"Sentry\"\n          website: \"https://sentry.io/\"\n          slug: \"sentry\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-sentry.svg\"\n\n        - name: \"Buzzsprout\"\n          website: \"https://www.buzzsprout.com/\"\n          slug: \"buzzsprout\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-buzzsprout.svg\"\n\n        - name: \"Test Double\"\n          website: \"https://link.testdouble.com/bp8\"\n          slug: \"testdouble\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-testdouble.svg\"\n\n        - name: \"Fullscript\"\n          website: \"https://fullscript.com/\"\n          slug: \"fullscript\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-fullscript.png\"\n\n        - name: \"Telos Labs\"\n          website: \"https://hi.teloslabs.co/\"\n          slug: \"teloslabs\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-teloslabs.svg\"\n\n        - name: \"Cedarcode\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"cedarcode\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-cedarcode.svg\"\n\n        - name: \"Coder\"\n          website: \"https://coder.com/\"\n          slug: \"coder\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-coder.svg\"\n\n        - name: \"ODDS\"\n          website: \"https://odds.team/\"\n          slug: \"odds\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-odds.svg\"\n\n        - name: \"Saeloun\"\n          website: \"https://www.saeloun.com/\"\n          slug: \"saeloun\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-saeloun.svg\"\n\n        - name: \"Cookpad\"\n          website: \"https://cookpad.com/uk\"\n          slug: \"cookpad\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-cookpad.svg\"\n\n        - name: \"Doximity\"\n          website: \"https://www.doximity.com/\"\n          slug: \"doximity\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-doximity.svg\"\n\n        - name: \"Fleetio\"\n          website: \"https://www.fleetio.com/\"\n          slug: \"fleetio\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-fleetio.svg\"\n\n        - name: \"Intercom\"\n          website: \"https://www.intercom.com/\"\n          slug: \"intercom\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-intercom.svg\"\n\n        - name: \"Procore\"\n          website: \"https://procore.com/\"\n          slug: \"procore\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-procore.svg\"\n\n        - name: \"37signals\"\n          website: \"https://37signals.com/\"\n          slug: \"37signals\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-37signals.svg\"\n\n        - name: \"BigBinary\"\n          website: \"https://www.bigbinary.com/\"\n          slug: \"bigbinary\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-bigbinary.svg\"\n\n        - name: \"makandra\"\n          website: \"https://makandra.de/\"\n          slug: \"makandra\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-makandra.svg\"\n\n        - name: \"Planet Argon\"\n          website: \"https://www.planetargon.com/\"\n          slug: \"planetargon\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-planet-argon.png\"\n\n        - name: \"Renuo\"\n          website: \"https://www.renuo.ch/\"\n          slug: \"renuo\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-renuo.svg\"\n\n        - name: \"TableCheck\"\n          website: \"https://www.tablecheck.com/en/join/\"\n          slug: \"tablecheck\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-tablecheck.svg\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2024/venue.yml",
    "content": "---\nname: \"Evergreen Brick Works\"\n\naddress:\n  street: \"550 Bayview Avenue\"\n  city: \"Toronto\"\n  region: \"Ontario\"\n  postal_code: \"M4W 3X8\"\n  country: \"Canada\"\n  country_code: \"CA\"\n  display: \"550 Bayview Avenue, Toronto, ON M4W 3X8, Canada\"\n\ncoordinates:\n  latitude: 43.6847\n  longitude: -79.365\n\nmaps:\n  google: \"https://maps.google.com/?q=Evergreen+Brick+Works,+550+Bayview+Avenue,+Toronto\"\n  apple: \"https://maps.apple.com/?q=Evergreen+Brick+Works,+550+Bayview+Avenue,+Toronto\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=43.6847&mlon=-79.3650\"\n\nhotels:\n  - name: \"W Toronto\"\n    kind: \"Speaker Hotel\"\n    address:\n      street: \"90 Bloor Street East\"\n      city: \"Toronto\"\n      region: \"Ontario\"\n      postal_code: \"M4W 1A7\"\n      country: \"Canada\"\n      country_code: \"CA\"\n      display: \"90 Bloor St E, Toronto, ON M4W 1A7, Canada\"\n    coordinates:\n      latitude: 43.671344\n      longitude: -79.384691\n    maps:\n      apple:\n        \"https://maps.apple.com/place?address=90%20Bloor%20St%20E,%20Toronto%20ON%20M4W%201A7,%20Canada&coordinate=43.671344,-79.384691&name=W%20Toronto&place-id=I3BADFE9A4FC24A65&\\\n        map=transit\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2024/videos.yml",
    "content": "---\n## Day 1\n\n- id: \"david-heinemeier-hansson-rails-world-2024\"\n  title: \"Opening Keynote\"\n  raw_title: \"Rails World 2024 Opening Keynote - David Heinemeier Hansson\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    During DHH's Opening Keynote of Rails World 2024 in Toronto, Rails 8 beta was shipped with Authentication, Propshaft, Solid Cache, Solid Queue, Solid Cable, Kamal 2, and Thruster. No PaaS needed when building with the One Person Framework.\n\n    Links:\n    https://rubyonrails.org/\n    https://github.com/rails/solid_cache\n    https://github.com/rails/solid_cable\n    https://github.com/rails/solid_queue\n    https://kamal-deploy.org/\n\n    #RubyonRails #Rails #Rails8 #propshaft #SolidCache #SolidQueue #SolidCable #Kamal2 #thruster #opensource #RailsWorld\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n  video_provider: \"youtube\"\n  video_id: \"-cEn_83zRFw\"\n  published_at: \"2024-09-27\"\n  additional_resources:\n    - name: \"rails/solid_cache\"\n      type: \"repo\"\n      url: \"https://github.com/rails/solid_cache\"\n\n    - name: \"rails/solid_cable\"\n      type: \"repo\"\n      url: \"https://github.com/rails/solid_cable\"\n\n    - name: \"rails/solid_queue\"\n      type: \"repo\"\n      url: \"https://github.com/rails/solid_queue\"\n\n    - name: \"Kamal\"\n      type: \"link\"\n      url: \"https://kamal-deploy.org/\"\n\n- id: \"rosa-gutirrez-rails-world-2024\"\n  title: \"Solid Queue Internals, Externals and all the things in between\"\n  raw_title: \"Rosa Gutiérrez - Solid Queue internals, externals and all the things in between - Rails World 2024\"\n  speakers:\n    - Rosa Gutiérrez\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    After years of tackling background job complexities with Resque and Redis at 37signals, the team finally decided to build an out-of-the-box solution. Enter #SolidQueue, a default now in Rails 8. Rosa Gutiérrez presented Solid Queue at Rails World and shared the journey and the challenges they faced to get it live.\n\n    Note: Rosa lost her voice the morning of this presentation but put on her game face and delivered the talk anyway.\n\n    #Rails #Rails8 #solidqueue #resque #redis\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"sEv2AYJiz1U\"\n  published_at: \"2024-11-01\"\n\n- id: \"mostafa-abdelraouf-rails-world-2024\"\n  title: \"Going Beyond a Single Postgres Instance with Rails\"\n  raw_title: \"Mostafa Abdelraouf - Going beyond a Single Postgres Instance with Rails - Rails World 2024\"\n  speakers:\n    - Mostafa Abdelraouf\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 2 (Hosted by AppSignal)\"\n  description: |-\n    Mostafa Abdelraouf shares the journey of evolving Instacart's Rails application beyond a single Postgres instance. He discusses how they managed the added complexity from adding read replicas, and later vertically and horizontally sharding, and also touched on the topics of query routing, connection pooling, and load balancing at Instacart's scale.\n\n    #railsatscale #postgres #sharding\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"aPsstRiNocY\"\n  published_at: \"2024-11-06\"\n\n- id: \"lightning-talks-1-rails-world-2024\"\n  title: \"Lightning Talks (Block 1)\"\n  raw_title: \"Lightning Talks 1 - Rails World 2024\"\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-1-rails-world-2024\"\n  date: \"2024-09-26\"\n  track: \"Lightning Talk Track (Hosted by Shopify)\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: An Intern's Guide to Tackling Tech Debt\"\n      raw_title: \"An intern's guide to tackling tech debt (Mathyas Papp)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Mathyas Papp\n      id: \"mathyas-papp-rails-world-2024\"\n      video_id: \"mathyas-papp-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-26\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        Maintenance is not as bad as it sounds, follow this guide to give your web app a second life!\n\n    - title: \"Lightning Talk: Speeding up CI at Framework: From 21 to 7 Minutes\"\n      raw_title: \"Speeding up CI at Framework: from 21 to 7 minutes (Zach Feldman)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Zach Feldman\n      id: \"zach-feldman-rails-world-2024\"\n      video_id: \"zach-feldman-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-26\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        21 minutes isn't *terrible* for a full CI run, but what if we could get our build times down to 1/3 of that?\n\n    - title: \"Lightning Talk: Writing Tests That Fail\"\n      raw_title: \"Writing tests that fail (Thomas Marshall)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Thomas Marshall\n      id: \"thomas-marshall-rails-world-2024\"\n      video_id: \"thomas-marshall-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-26\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        Why failing tests are much more useful than passing ones, and how to write them.\n      slides_url: \"https://www.thomasmarshall.com/talks/writing-tests-that-fail\"\n\n- id: \"donal-mcbreen-rails-world-2024\"\n  title: \"Kamal 2.0: Deploy Web Apps Anywhere\"\n  raw_title: \"Donal McBreen - Kamal 2.0: Deploy web apps anywhere - Rails World 2024\"\n  speakers:\n    - Donal McBreen\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    Kamal is an imperative deployment tool from 37signals for running your apps with Docker. Donal McBreen, from the Security, Infrastructure and Performance team at 37signals will run through how it works, what they've learned from v1.0 and the changes they've made for v2.0 at his talk at #RailsWorld.\n\n    #Kamal2 #rails #rubyonrails #deployment #Rails8\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"nsgwFWvye8I\"\n  published_at: \"2024-11-12\"\n\n- id: \"jamis-buck-rails-world-2024\"\n  title: \"Repurposing the Rails CLI\"\n  raw_title: \"Jamis Buck - Repurposing the Rails CLI - Rails World 2024\"\n  speakers:\n    - Jamis Buck\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 2 (Hosted by AppSignal)\"\n  description: |-\n    At MongoDB, they wanted to add a tighter integration between Rails and Mongoid (their ODM), so they created their our own CLI tool that extends the Rails CLI, adding the additional functionality they seeked. Former Rails core alumnus and Capistrano-creator Jamis Buck shows how they did it at #RailsWorld, and how you can do it yourself.\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"A2NnemrKHNI\"\n  published_at: \"2024-11-01\"\n\n- id: \"workshop-neovim-zellij-day-1-rails-world-2024\"\n  title: \"Workshop: The Modern Programmer's Guide to Neovim and Zellij\"\n  raw_title: \"The Modern Programmer's Guide to Neovim and Zellij - Chris Power and Robert Beene - Rails World 2024\"\n  speakers:\n    - Chris Power\n    - Robert Beene\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Lightning Talk Track (Hosted by Shopify)\"\n  description: |-\n    Are you ready to revolutionize your coding environment? In a world dominated by VS Code and other Electron-based editors, there’s a hidden gem that developers are rediscovering: Vim. Or rather, Neovim. Just as Rails transformed web development, Neovim is redefining how we write code, blending decades-old technology with modern tooling for an unparalleled experience.\n\n    **Workshop overview** In this hands-on workshop, we dive into the world of Neovim and Zellij — showing you how to streamline your development process and achieve a true flow state.\n\n    **Here's what you can expect**\n    * Introduction to Neovim: Understand the core principles that make Neovim a game-changer in the modern programming landscape.\n    * Learn how to effortlessly manage and customize plugins to suit your unique workflow, shedding the bloat of heavier editors.\n    * Combine the power of Neovim and Zellij to increase developer productivity by achieving your optimal flow state.\n\n    **Key takeaways** By the end of this 75-minute workshop, you will:\n    * Have a solid understanding of Neovim's capabilities and how it can enhance your productivity.\n    * Manage workspaces using Zellij to jump in and out of projects with ease.\n    * Walk away with a Neovim setup that empowers you to code with minimal distractions, maximizing your efficiency and creativity.\n\n    **Why Attend?** This workshop is perfect for developers of all levels (with some familiarity with Vim) who are looking to optimize their workflow and embrace a lightweight, powerful, and highly customizable editor. Whether you’re new to Neovim or looking to deepen your understanding, this session will provide you with practical skills and insights that you can apply immediately.\n\n    **Thank you Coder!** This workshop is brought to you by [Coder](https://coder.com/), and will be repeated on both days. It will be first-come, first-served.\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-neovim-zellij-day-1-rails-world-2024\"\n\n- id: \"kevin-mcconnell-rails-world-2024\"\n  title: \"Introducing Kamal Proxy\"\n  raw_title: \"Kevin McConnell - Introducing Kamal Proxy - Rails World 2024\"\n  speakers:\n    - Kevin McConnell\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    Kamal Proxy is a new, purpose-built HTTP proxy service that powers Kamal 2.0. It is designed to make zero-downtime deployments simpler, and comes with additional features to make your Rails applications faster and easier to operate. Kevin McConnell explains what Kamal Proxy does, why they built it, and how it works in his talk at #RailsWorld.\n\n    #Kamalproxy #kamal2 #rails #rubyonrails #rails8\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"hQXjbnh18XM\"\n  published_at: \"2024-11-12\"\n\n- id: \"greg-molnar-rails-world-2024\"\n  title: \"The State of Security in Rails 8\"\n  raw_title: \"Greg Molnar - The state of security in Rails 8 - Rails World 2024\"\n  speakers:\n    - Greg Molnar\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 2 (Hosted by AppSignal)\"\n  description: |-\n    In his #RailsWorld talk, Greg Molnar highlights the recent security related improvements in Rails and why Rails is one of the best options for an application with high security standards.\n\n    #rails #rubyonrails #rails8 #applicationsecurity\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\"\n  video_provider: \"youtube\"\n  video_id: \"Z3DgOix0rIg\"\n  published_at: \"2024-11-01\"\n\n- id: \"lightning-talks-2-rails-world-2024\"\n  title: \"Lightning Talks (Block 2)\"\n  raw_title: \"Lightning Talks 2 - Rails World 2024\"\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-2-rails-world-2024\"\n  date: \"2024-09-26\"\n  track: \"Lightning Talk Track (Hosted by Shopify)\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Rails as a Real-Time, Multiplayer Game Engine\"\n      raw_title: \"Rails as a real-time, multiplayer game engine (Pawel Strzalkowski)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Paweł Strzałkowski\n      id: \"pawel-strzalkowski-rails-world-2024\"\n      video_id: \"pawel-strzalkowski-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-26\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        Shows how pure Rails with Hotwire can be used to create beautiful, multiplayer, real-time games.\n\n    - title: \"Lightning Talk: How to Keep Rails App Development Fast\"\n      raw_title: \"How to keep Rails app development fast (Gannon McGibbon)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Gannon McGibbon\n      id: \"gannon-mcgibbon-rails-world-2024\"\n      video_id: \"gannon-mcgibbon-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-26\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        Tips and tricks on optimizing Rails application startup in development and test.\n      slides_url: \"https://gmcgibbon.github.io/how-to-keep-rails-app-development-fast\"\n\n- id: \"jenny-shen-rails-world-2024\"\n  title: \"An Upgrade Handbook to Rails 8\"\n  raw_title: \"Jenny Shen - An upgrade handbook to Rails 8 - Rails World 2024\"\n  speakers:\n    - Jenny Shen\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    Rails 8 is here, and in her talk at #RailsWorld, Jenny Shen explores how to get your Rails app upgraded to the latest version in no time! Have too many applications to upgrade? She will also share how Shopify was able to automate the Rails upgrade process for hundreds of their applications.\n\n    #Rails #Rails8 #rubyonrails #upgrade\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"HTRNa-U_KKk\"\n  published_at: \"2024-11-11\"\n\n- id: \"justin-searls-rails-world-2024\"\n  title: \"The Empowered Programmer\"\n  raw_title: \"Justin Searls - The Empowered Programmer - Rails World 2024\"\n  speakers:\n    - Justin Searls\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 2 (Hosted by AppSignal)\"\n  description: |-\n    In 2019, Justin Searls gave a talk, \"The Selfish Programmer\" all about building a Rails 5 app as a one-man show. Now, he is back to share how he made a new app that's twice the size but felt like half the work. You'll learn how Rails includes more batteries than ever, when sticking with omakase pays off, and why scaling back a team doesn't have to mean slowing down.\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"mhqf2uK0doU\"\n  published_at: \"2024-11-01\"\n\n- id: \"lightning-talks-3-rails-world-2024\"\n  title: \"Lightning Talks (Block 3)\"\n  raw_title: \"Lightning Talks 3 - Rails World 2024\"\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-3-rails-world-2024\"\n  date: \"2024-09-26\"\n  track: \"Lightning Talk Track (Hosted by Shopify)\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: How to Run a Ruby Meetup and Get Inspired By It\"\n      raw_title: \"How to run a Ruby meetup and get inspired by it (Irina Nazarova)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Irina Nazarova\n      id: \"irina-nazarova-rails-world-2024\"\n      video_id: \"irina-nazarova-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-26\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        I re-started the SF Ruby Meetup and it brought the local community together: here's my how-to.\n\n    - title: \"Lightning Talk: Tips for AI Augmented Web Dev with Cursor\"\n      raw_title: \"Tips for AI Augmented web dev with cursor (Ignacio Alonso)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Ignacio Alonso\n      id: \"ignacio-alonso-rails-world-2024\"\n      video_id: \"ignacio-alonso-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-26\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        How I use Cursor for Ultra Fast Ruby Development.\n\n- id: \"rafael-mendona-frana-rails-world-2024\"\n  title: \"Frontiers of Development Productivity in Rails\"\n  raw_title: \"Rafael França - Frontiers of development productivity in Rails - Rails World 2024\"\n  speakers:\n    - Rafael Mendonça França\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    Rails is known to be one of the best frameworks in terms of empowering developers to build great products, and has kept this place for 20 years. But...can we do better? In his talk at #RailsWorld, Rails Core member Rafael França shows how they are pushing Rails to continue making developers lives easier across new frontiers.\n\n    #RubyonRails #Rails #Rails8 #productivity #devcontainers #lsp #developerhappiness\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"G9xwfEOXnb0\"\n  published_at: \"2024-11-11\"\n\n- id: \"emmanuel-hayford-rails-world-2024\"\n  title: \"Progressive Web Apps for Rails Developers\"\n  raw_title: \"Emmanuel Hayford - Progressive Web Apps for Rails developers - Rails World 2024\"\n  speakers:\n    - Emmanuel Hayford\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 2 (Hosted by AppSignal)\"\n  slides_url: \"https://speakerdeck.com/siaw23/progressive-web-apps-for-rails-developers\"\n  description: |-\n    Rails 8 will simplify PWA development by generating essential PWA scaffolding by default. In his #RailsWorld talk, Emmanuel Hayford covers PWA basics, the service worker lifecycle, offline strategies via background sync, and the CacheStorage API for cross-device performance.\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"Oh1mlNJJonE\"\n  published_at: \"2024-11-01\"\n\n- id: \"david-heinemeier-hansson-rails-world-2024-fireside-chat\"\n  title: \"Fireside Chat\"\n  raw_title: \"Fireside Chat with DHH, Matz and Tobias Lütke - Rails World 2024\"\n  speakers:\n    - David Heinemeier Hansson\n    - Yukihiro \"Matz\" Matsumoto\n    - Tobias Lütke\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-26\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    In a special #RailsWorld session, DHH (creator of Rails), Matz (creator of Ruby), and Shopify CEO Tobias Lütke sat down for a fireside chat about #Ruby, #Rails, and all things #opensource.\n\n    This is the first time that Matz and DHH shared a stage, and it would not have been possible without Tobi, who not only donated his keynote spot to make this session happen, but also led the discussion.\n\n    **\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"zPBbHu-BKpQ\"\n  published_at: \"2024-10-08\"\n\n## Day 2\n\n- id: \"eileen-m-uchitelle-rails-world-2024\"\n  title: \"Opening Keynote: The Myth of the Modular Monolith\"\n  raw_title: \"Eileen Uchitelle - The Myth of the Modular Monolith - Rails World 2024\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  slides_url: \"https://speakerdeck.com/eileencodes/the-myth-of-the-modular-monolith-day-2-keynote-rails-world-2024\"\n  description: |-\n    As Rails applications grow over time, organizations ask themselves: 'What’s next? Should we stay the course with a monolith or migrate to microservices?' At @Shopify they chose to modularize their monolith, but after 6 years they are asking: 'Did we fix what we set out to fix? Is this better than before?' Join Rails Core member Eileen Uchitelle as she poses these questions during her #RailsWorld Day 2 Opening Keynote.\n\n    #RubyonRails #Rails #Rails8 #monolith #microservices #modularization #scaling\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"olxoNDBp6Rg\"\n  published_at: \"2024-10-10\"\n\n- id: \"stephen-margheim-rails-world-2024\"\n  title: \"SQLite on Rails: Supercharging the One-Person Framework\"\n  raw_title: \"Stephen Margheim - SQLite on Rails: Supercharging the One-Person Framework - Rails World 2024\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  slides_url: \"https://fractaledmind.github.io/2024/10/16/sqlite-supercharges-rails\"\n  description: |-\n    The Rails 8 feature set perfectly complements SQLite's power in creating resilient, high-performance production apps, but still the question lingers: Can I really go all-in on #SQLite? Stephen Margheim illustrates how to leverage Rails and SQLite's full potential in your next venture, and when SQLite does and doesn't make sense for your application.\n\n    Find the slides here: https://fractaledmind.github.io/2024/10/16/sqlite-supercharges-rails/\n\n    #Rails #Rails8 #rubyonrails #sqlite\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"wFUy120Fts8\"\n  published_at: \"2024-11-11\"\n\n- id: \"ridhwana-khan-rails-world-2024\"\n  title: \"Demystifying Some of The Magic Behind Rails\"\n  raw_title: \"Ridhwana Khan - Demystifying some of the magic behind Rails - Rails World 2024\"\n  speakers:\n    - Ridhwana Khan\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 2 (Hosted by AppSignal)\"\n  slides_url: \"https://speakerdeck.com/ridhwana/demystifying-some-of-the-magic-behind-rails\"\n  description: |-\n    Rails is renowned for its elegance, productivity, and \"magic\" which simplifies web development. As a recent technical writer for the official Ruby on Rails guides, Ridhwana Khan has had the opportunity to dive into the \"magic\" of Rails to understand the source code and translate that into clear explanations in the guides. At #RailsWorld, she shared insights gained from her experience demystifying the framework's inner workings for the good of the greater community.\n\n    Slides: https://speakerdeck.com/ridhwana/demystifying-some-of-the-magic-behind-rails\n    Rails Guides: Lhttps://guides.rubyonrails.org/\n\n    #rails #documentation\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"DuPQYYWlhAY\"\n  published_at: \"2024-11-01\"\n\n- id: \"lightning-talks-4-rails-world-2024\"\n  title: \"Lightning Talks (Block 4)\"\n  raw_title: \"Lightning Talks 4 - Rails World 2024\"\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-4-rails-world-2024\"\n  date: \"2024-09-27\"\n  track: \"Lightning Talk Track (Hosted by Shopify)\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: AI-Enabled Marketplace Built on Monolithic Rails\"\n      raw_title: \"AI-Enabled Marketplace Built on Monolithic Rails (Avinash Joshi)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Avinash Joshi\n      id: \"avinash-joshi-rails-world-2024\"\n      video_id: \"avinash-joshi-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-27\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        Sharing insights from building a marketplace web app using Rails, including integrating AI features to enhance functionality.\n\n    - title: \"Lightning Talk: You Don't Need a Static Site Generator\"\n      raw_title: \"You Don't Need a Static Site Generator (Adam McCrea)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Adam McCrea\n      id: \"adam-mccrea-rails-world-2024\"\n      video_id: \"adam-mccrea-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-27\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        Rails might feel like overkill for a basic website, but I'll show you why it's actually perfect.\n\n    - title: \"Lightning Talk: React to Hotwire Migration\"\n      raw_title: \"React to Hotwired migration (Carlos Marchal)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Carlos Marchal\n      id: \"carlos-marchal-rails-world-2024\"\n      video_id: \"carlos-marchal-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-27\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        Migrating a complex, interactive UI from React to Hotwire taught us some useful tricks and patterns.\n\n- id: \"miles-mcguire-rails-world-2024\"\n  title: \"Making The Best of a Bad Situation - Lessons from one of Intercom's most painful outages\"\n  raw_title: \"Miles McGuire - Making the best of a bad situation - Rails World 2024\"\n  speakers:\n    - Miles McGuire\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    Incidents are an opportunity to level up, and on 22 Feb 2024 Intercom had one of its most painful outages in recent memory. The root cause? A 32-bit foreign key referencing a 64-bit primary key. Miles McGuire shared what happened, why it happened, and what they are doing to ensure it won't happen again (including some changes you can make to your own Rails apps to help make sure you don’t make the same mistakes.)\n\n    #outage #lessonslearned\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"xMICEHWkp58\"\n  published_at: \"2024-11-11\"\n\n- id: \"andrea-fomera-rails-world-2024\"\n  title: \"Pushing the Boundaries with ActiveStorage\"\n  raw_title: \"Andrea Fomera - Pushing the boundaries with ActiveStorage - Rails World 2024\"\n  speakers:\n    - Andrea Fomera\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 2 (Hosted by AppSignal)\"\n  slides_url: \"https://docs.google.com/presentation/d/1CXN9yAh4o_rmc85WfTHGyH-MchHS-ZM4YAwmroCdSBc\"\n  description: |-\n    In her talk at #RailsWorld, Andrea Fomera showed how she works with #ActiveStorage using custom services for external providers.\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\"\n  video_provider: \"youtube\"\n  video_id: \"20TwZvuvg2Q\"\n  published_at: \"2024-10-29\"\n\n- id: \"workshop-neovim-zellij-day-2-rails-world-2024\"\n  title: \"Workshop: The Modern Programmer's Guide to Neovim and Zellij\"\n  raw_title: \"The Modern Programmer's Guide to Neovim and Zellij - Chris Power and Robert Beene - Rails World 2024\"\n  speakers:\n    - Chris Power\n    - Robert Beene\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Lightning Talk Track (Hosted by Shopify)\"\n  description: |-\n    Are you ready to revolutionize your coding environment? In a world dominated by VS Code and other Electron-based editors, there’s a hidden gem that developers are rediscovering: Vim. Or rather, Neovim. Just as Rails transformed web development, Neovim is redefining how we write code, blending decades-old technology with modern tooling for an unparalleled experience.\n\n    **Workshop overview** In this hands-on workshop, we dive into the world of Neovim and Zellij — showing you how to streamline your development process and achieve a true flow state.\n\n    **Here's what you can expect**\n    * Introduction to Neovim: Understand the core principles that make Neovim a game-changer in the modern programming landscape.\n    * Learn how to effortlessly manage and customize plugins to suit your unique workflow, shedding the bloat of heavier editors.\n    * Combine the power of Neovim and Zellij to increase developer productivity by achieving your optimal flow state.\n\n    **Key takeaways** By the end of this 75-minute workshop, you will:\n    * Have a solid understanding of Neovim's capabilities and how it can enhance your productivity.\n    * Manage workspaces using Zellij to jump in and out of projects with ease.\n    * Walk away with a Neovim setup that empowers you to code with minimal distractions, maximizing your efficiency and creativity.\n\n    **Why Attend?** This workshop is perfect for developers of all levels (with some familiarity with Vim) who are looking to optimize their workflow and embrace a lightweight, powerful, and highly customizable editor. Whether you’re new to Neovim or looking to deepen your understanding, this session will provide you with practical skills and insights that you can apply immediately.\n\n    **Thank you Coder!** This workshop is brought to you by [Coder](https://coder.com/), and will be repeated on both days. It will be first-come, first-served.\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-neovim-zellij-day-2-rails-world-2024\"\n\n- id: \"bruno-prieto-rails-world-2024\"\n  title: \"Making Accessible Web Apps with Rails and Hotwire\"\n  raw_title: \"Bruno Prieto - Making accessible web apps with Rails and Hotwire - Rails World 2024\"\n  speakers:\n    - Bruno Prieto\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    Is your web app accessible? In his talk at #RailsWorld, Bruno Prieto shares his first-hand perspective as a blind developer on building accessible web apps with real-world examples taking advantage of tools provided by Rails, Hotwire, and the browser. It's easier than you think!\n\n    #rails #accessibility #webaccessibility\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"zqBNEBnjzXM\"\n  published_at: \"2024-11-11\"\n\n- id: \"robby-russell-rails-world-2024\"\n  title: \"Prepare to Tack: Steering Rails Apps Out of Technical Debt\"\n  raw_title: \"Robby Russell - Prepare to tack: Steering Rails apps out of technical debt - Rails World 2024\"\n  speakers:\n    - Robby Russell\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 2 (Hosted by AppSignal)\"\n  slides_url: \"https://maintainablerails.com/railsworld-2024-talk-resources\"\n  description: |-\n    If your Rails app is drowning in a sea of compromises and quick fixes, making it difficult to update and slowing you down, it's high time to redefine \"technical debt\" - perhaps even time to ditch the term altogether. In his #RailsWorld talk, Planet Argon foundr and CEO Robby Russell explores the common issues facing our Rails apps, uncovering roadblocks, blind spots, and comfort zones that lead us to rationalize away the need for necessary changes. It's time to confront these issues head on and work towards a more maintainable, efficient codebase.\n\n    Find the slides for this talk here: https://maintainablerails.com/railsworld-2024-talk-resources\n\n    #technicaldebt #Rails\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"eT7hJz_GXGo\"\n  published_at: \"2024-11-06\"\n\n- id: \"lightning-talks-5-rails-world-2024\"\n  title: \"Lightning Talks (Block 5)\"\n  raw_title: \"Lightning Talks 5 - Rails World 2024\"\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-5-rails-world-2024\"\n  date: \"2024-09-27\"\n  track: \"Lightning Talk Track (Hosted by Shopify)\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Ruby on Rails on WebAssembly\"\n      raw_title: \"Ruby on Rails on WebAssembly (Vladimir Dementyev)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Vladimir Dementyev\n      id: \"vladimir-dementyev-rails-world-2024\"\n      video_id: \"vladimir-dementyev-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-27\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        Bring your Rails application right into the browser for the win!\n\n    - title: \"Lightning Talk: Callbacks: A Code-pendent Love Affair\"\n      raw_title: \"Callbacks: A Code-pendent Love Affair (Daniela Velasquez)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Daniela Velasquez\n      id: \"daniela-velasquez-rails-world-2024\"\n      video_id: \"daniela-velasquez-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-27\"\n      description: |-\n        Journey through the highs and lows of working with Rails callbacks, from initial excitement to frustration, leading to a deeper appreciation.\n\n- id: \"xavier-noria-rails-world-2024\"\n  title: \"The Rails Boot Process\"\n  raw_title: \"Xavier Noria - The Rails Boot Process - Rails World 2024\"\n  speakers:\n    - Xavier Noria\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    What happens when a Rails application boots? When is the logger ready? When is $LOAD_PATH set? When do initializers run or when are the autoloaders are set up? Rails Core member Xavier Noria covered all this and more in his talk at #RailsWorld.\n\n    #Rails #Rails8 #internals #boot #railties #engines #initialization\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"Kx0ihLCTEgE\"\n  published_at: \"2024-11-11\"\n\n- id: \"julia-lpez-rails-world-2024\"\n  title: \"Testing Integrations: The Good, the Bad, and the Ugly\"\n  raw_title: \"Julia López - Testing Integrations: The Good, the Bad, and the Ugly - Rails World 2024\"\n  speakers:\n    - Julia López\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 2 (Hosted by AppSignal)\"\n  slides_url: \"https://speakerdeck.com/yukideluxe/testing-integrations-the-good-the-bad-and-the-ugly\"\n  description: |-\n    Enhancing your app's features through third-party APIs can be so powerful, but testing these integrations can be so cumbersome. At #RailsWorld Julia López sharaed practical strategies for testing integrations, drawing from real-life experiences at Harvest, where they implemented several integrations – Braintree, Stripe, CustomerIO, Hubspot, Xero, QuickBooks, and more.\n\n    #tesing #Rails #api\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"j0FDwx4P-WU\"\n  published_at: \"2024-11-01\"\n\n- id: \"lightning-talks-6-rails-world-2024\"\n  title: \"Lightning Talks (Block 6)\"\n  raw_title: \"Lightning Talks 6 - Rails World 2024\"\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-6-rails-world-2024\"\n  date: \"2024-09-27\"\n  track: \"Lightning Talk Track (Hosted by Shopify)\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Hotwire Native - Turn any Rails App into a Mobile (iOS/Android) App\"\n      raw_title: \"Turbo Native: turn any Rails app into a mobile (iOS/Android) app (Yaroslav Shmarov)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Yaroslav Shmarov\n      id: \"yaroslav-shmarov-rails-world-2024\"\n      video_id: \"kLPw34FQomI\"\n      published_at: \"2024-11-17\"\n      video_provider: \"youtube\"\n      date: \"2024-09-27\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        Learn to make your Rails app Hotwire Native & App Store compatible.\n      slides_url: \"https://speakerdeck.com/yshmarov/yaroslav-shmarov-hotwire-native-rails-world-2024-lightning-talk\"\n\n    - title: \"Lightning Talk: Beyond Meetups - Creating a Ruby Ecosystem\"\n      raw_title: \"Beyond Meetups: Creating a Ruby Ecosystem (Mariusz Kozieł)\"\n      event_name: \"Rails World 2024\"\n      speakers:\n        - Mariusz Kozieł\n      id: \"mariusz-koziel-rails-world-2024\"\n      video_id: \"mariusz-koziel-rails-world-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-09-27\"\n      track: \"Lightning Talk Track (Hosted by Shopify)\"\n      description: |-\n        Discover how Ruby Europe is revolutionizing developer communities and learn how to apply these strategies globally.\n\n- id: \"obie-fernandez-rails-world-2024\"\n  title: \"Empowering the Individual: Rails on AI\"\n  raw_title: \"Obie Fernandez - Empowering the Individual: Rails on AI - Rails World 2024\"\n  speakers:\n    - Obie Fernandez\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    Integrating AI with Ruby on Rails can transform a solo developer's workflow into an incredibly potent force, capable of competing at an unprecedented scale, bringing the dream of the \"One Person Framework\" even closer. At #RailsWorld Obie Fernandez shared a roadmap for integrating AI tools and techniques into your projects, insights into the potential pitfalls and best practices, and inspiration to explore the boundaries of what a single developer or a small team can achieve with the right tools.\n\n    #rails #AI #rubyonrails\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"Me_USd1TeYM\"\n  published_at: \"2024-11-11\"\n\n- id: \"david-henner-rails-world-2024\"\n  title: \"Level Up Performance With Simple Coding Changes\"\n  raw_title: \"David Henner - Level up performance with simple coding changes - Rails World 2024\"\n  speakers:\n    - David Henner\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 2 (Hosted by AppSignal)\"\n  description: |-\n    David Henner highlights some of the major improvements Zendesk has achieved using straightforward #Ruby techniques to get even better performance out of Rails, including data which illustrates how they saved thousands of years of processing time annually, leading to increased customer satisfaction and cost-effectiveness, as reflected in their AWS bills.\n\n    #railsatscale #rails #scaling\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"tBRBFcCWqcg\"\n  published_at: \"2024-11-11\"\n\n- id: \"aaron-patterson-rails-world-2024\"\n  title: \"Closing Keynote\"\n  raw_title: \"Aaron Patterson - Rails World 2024 Closing Keynote\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Rails World 2024\"\n  date: \"2024-09-27\"\n  track: \"Track 1 (Hosted by GitHub)\"\n  description: |-\n    Rails Core member Aaron Patterson (@TenderlovesCoolStuff)  delivered the Closing Keynote at this year's #RailsWorld about speeding up the Rails Router. With his unique blend of humor and presentation style (a little bit technical, a lot of tomfoolery) he also introduced a new feature that may or may not* be in Rails 8: LamboRoutes.\n\n    * This is not a real feature in Rails 8.\n\n    #RubyonRails #Rails #Rails8 #router #railsrouter #websterweb\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Stay tuned: all 2024 Rails World videos will be subtitled in Japanese and Brazilian Portuguese soon thanks to our sponsor Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  video_provider: \"youtube\"\n  video_id: \"ZE6F3drGhA8\"\n  published_at: \"2024-10-11\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2025/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://sessionize.com/rails-world-2025/\"\n  open_date: \"2025-03-07\"\n  close_date: \"2025-04-10\"\n\n- name: \"Lightning Talks CFP\"\n  link: \"https://docs.google.com/forms/d/e/1FAIpQLSff0xJbDwKiIj6Q5Se5DnuIIpnrKwRBhDqV1KuMS1wRJkQ9mA/viewform\"\n  open_date: \"2025-08-05\"\n  close_date: \"2025-08-15\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2025/event.yml",
    "content": "---\nid: \"rails-world-2025\"\ntitle: \"Rails World 2025\"\nkind: \"conference\"\nlocation: \"Amsterdam, Netherlands\"\ndescription: |-\n  Rails World is a two-day, two track community conference featuring technical talks, demos, networking, and keynotes about the latest features and best practices in Rails development.\npublished_at: \"2025-09-16\"\nstart_date: \"2025-09-04\"\nend_date: \"2025-09-05\"\nchannel_id: \"UC9zbLaqReIdoFfzdUbh13Nw\"\nyear: 2025\nbanner_background: \"linear-gradient(180deg, #3B1D62, #3B1D62, #880C51, #880C51)\"\nfeatured_background: \"#3B1D62\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubyonrails.org/world/2025\"\ncoordinates:\n  latitude: 52.3752\n  longitude: 4.8956\n"
  },
  {
    "path": "data/rails-world/rails-world-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Amanda Perino\n    - Gaia Putrino\n\n  organisations:\n    - Rails Foundation\n\n- name: \"Website Developer\"\n  users:\n    - Ines Alvergne\n\n- name: \"Designer\"\n  users:\n    - Jomiro Eming\n\n- name: \"Emcee\"\n  users:\n    - Chris Power\n    - Harriet Oughton\n\n- name: \"Lightning Talk Emcee\"\n  users:\n    - Greg Molnar\n    - Claudio Baccigalupo\n\n- name: \"Volunteer\"\n  users:\n    - Amani Jones\n    - Beatriz Mitre\n    - Theodora Ntoka\n    - Bram Janssen\n# https://rubyonrails.org/2025/12/24/2025-wrap-up-rails-foundation\n"
  },
  {
    "path": "data/rails-world/rails-world-2025/schedule.yml",
    "content": "# Schedule: https://rubyonrails.org/world/2025/agenda\n---\ndays:\n  - name: \"Day 0\"\n    date: \"2025-09-03\"\n    grid:\n      - start_time: \"16:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - title: \"Pre-registration & badge pickup\"\n            description: |-\n              Registration opens for those who are already in town. Avoid the Thursday morning line and get your badge.\n\n  - name: \"Day 1\"\n    date: \"2025-09-04\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Doors Open\n\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 2\n\n      - start_time: \"11:45\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch sponsored by Codeminer42\n\n      - start_time: \"13:00\"\n        end_time: \"13:30\"\n        slots: 2\n\n      - start_time: \"13:45\"\n        end_time: \"14:15\"\n        slots: 2\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 2\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 2\n\n      - start_time: \"16:30\"\n        end_time: \"17:30\"\n        slots: 1\n\n  - name: \"Day 2\"\n    date: \"2025-09-05\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Doors Open\n\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 2\n\n      - start_time: \"11:45\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch sponsored by Codeminer42\n\n      - start_time: \"13:00\"\n        end_time: \"13:30\"\n        slots: 2\n\n      - start_time: \"13:45\"\n        end_time: \"14:15\"\n        slots: 2\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 2\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 2\n\n      - start_time: \"16:30\"\n        end_time: \"17:30\"\n        slots: 1\n\n      - start_time: \"18:30\"\n        end_time: \"22:30\"\n        slots: 1\n        items:\n          - title: \"Closing party\"\n            description: |-\n              Location to be determined\n\ntracks:\n  - name: \"Track 1\"\n    color: \"#DC2626\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Track 2\"\n    color: \"#2563EB\"\n    text_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum\"\n      description: |-\n        Top tier sponsors with the highest level of sponsorship.\n      level: 1\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-appsignal.svg\"\n\n    - name: \"Gold\"\n      description: |-\n        Gold tier sponsors, important contributors to the event.\n      level: 2\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com/\"\n          slug: \"shopify\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-shopify.svg\"\n\n        - name: \"GitHub\"\n          website: \"https://www.github.com/\"\n          slug: \"github\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-github.svg\"\n\n        - name: \"Framework\"\n          website: \"https://frame.work/\"\n          slug: \"framework\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-framework.png\"\n\n        - name: \"JetBrains\"\n          website: \"https://www.jetbrains.com/\"\n          slug: \"jetbrains\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-jetbrains1.svg\"\n\n        - name: \"Basecamp\"\n          website: \"https://basecamp.com/\"\n          slug: \"basecamp\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-basecamp.svg\"\n\n    - name: \"Silver\"\n      description: |-\n        Silver tier sponsors supporting the event.\n      level: 3\n      sponsors:\n        - name: \"Codeminer42\"\n          website: \"https://www.codeminer42.com/?utm_source=railsworld2025&utm_medium=website&utm_campaign=sponsor\"\n          slug: \"codeminer42\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-codeminer42.png\"\n\n        - name: \"Buzzsprout\"\n          website: \"https://www.buzzsprout.com/\"\n          slug: \"buzzsprout\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-buzzsprout.svg\"\n\n        - name: \"Crunchy Data\"\n          website: \"https://www.crunchydata.com/\"\n          slug: \"crunchydata\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-crunchydata.png\"\n\n        - name: \"GitLab\"\n          website: \"https://about.gitlab.com/\"\n          slug: \"gitlab\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-gitlab.svg\"\n\n        - name: \"Huntress\"\n          badge: \"Lightning Track Sponsor\"\n          website: \"https://www.huntress.com/\"\n          slug: \"huntress\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-huntress.svg\"\n\n        - name: \"Intercom\"\n          website: \"https://www.intercom.com/\"\n          slug: \"intercom\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-intercom.svg\"\n\n        - name: \"makandra\"\n          website: \"https://makandra.de/en\"\n          slug: \"makandra\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-makandra.svg\"\n\n        - name: \"Heroku\"\n          website: \"https://www.heroku.com/salesforce/\"\n          slug: \"heroku\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-salesforce-heroku.svg\"\n\n        - name: \"Sentry\"\n          website: \"https://sentry.io/\"\n          slug: \"sentry\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-sentry.svg\"\n\n        - name: \"Wyeworks\"\n          website: \"https://www.wyeworks.com/\"\n          slug: \"wyeworks\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-wyeworks.svg\"\n\n    - name: \"Members\"\n      description: |-\n        Members sponsors supporting the event.\n      level: 4\n      sponsors:\n        - name: \"Cedarcode\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"cedarcode\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-cedarcode.svg\"\n\n        - name: \"Typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"typesense\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-typesense.svg\"\n\n        - name: \"Avo\"\n          website: \"https://avohq.io/rails-admin\"\n          slug: \"avo\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-avo.svg\"\n\n        - name: \"Aha!\"\n          website: \"https://www.aha.io/\"\n          slug: \"aha\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-aha.png\"\n\n        - name: \"Telos Labs\"\n          website: \"https://hi.teloslabs.co/\"\n          slug: \"teloslabs\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-teloslabs.svg\"\n\n        - name: \"ODDS\"\n          website: \"https://odds.team/\"\n          slug: \"odds\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-odds.svg\"\n\n        - name: \"Rompslomp\"\n          website: \"https://rompslomp.nl/\"\n          slug: \"rompslomp\"\n          logo_url: \"https://rubyonrails.org/assets/world/2023/images/sponsors/RW-logo-rompslomp2.svg\"\n\n        - name: \"TRMNL\"\n          website: \"https://usetrmnl.com/\"\n          slug: \"trmnl\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-trmnl.png\"\n\n        - name: \"IQ Lab\"\n          website: \"https://www.iqlab.us/\"\n          slug: \"iqlab\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-iqlab.png\"\n\n        - name: \"ANDPAD Inc.\"\n          website: \"https://andpad.co.jp/\"\n          slug: \"andpad\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-andpad.png\"\n\n        - name: \"Cookpad\"\n          website: \"https://cookpad.com/uk\"\n          slug: \"cookpad\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-cookpad.svg\"\n\n        - name: \"Doximity\"\n          website: \"https://www.doximity.com/\"\n          slug: \"doximity\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-doximity.svg\"\n\n        - name: \"Fleetio\"\n          website: \"https://www.fleetio.com/\"\n          slug: \"fleetio\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-fleetio.svg\"\n\n        - name: \"Judge.me\"\n          website: \"https://judge.me/\"\n          slug: \"judgeme\"\n          logo_url: \"https://rubyonrails.org/assets/images/logo-judgeme.svg\"\n\n        - name: \"Procore\"\n          website: \"https://www.procore.com/en-gb\"\n          slug: \"procore\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-procore.svg\"\n\n        - name: \"1password\"\n          website: \"https://1password.com/\"\n          slug: \"1password\"\n          logo_url: \"https://rubyonrails.org/assets/images/logo-1password.svg\"\n\n        - name: \"37signals\"\n          website: \"https://37signals.com/\"\n          slug: \"37signals\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-37signals.svg\"\n\n        - name: \"BigBinary\"\n          website: \"https://www.bigbinary.com/\"\n          slug: \"bigbinary\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-bigbinary.svg\"\n\n        - name: \"Clio\"\n          website: \"https://www.clio.com/\"\n          slug: \"clio\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-clio.svg\"\n\n        - name: \"Gusto\"\n          website: \"https://gusto.com/\"\n          slug: \"gusto\"\n          logo_url: \"https://rubyonrails.org/assets/images/logo-gusto.svg\"\n\n        - name: \"Planet Argon\"\n          website: \"https://www.planetargon.com/\"\n          slug: \"planetargon\"\n          logo_url: \"https://rubyonrails.org/assets/world/2025/images/sponsors/RW-logo-planet-aragon.svg\"\n\n        - name: \"Renuo\"\n          website: \"https://www.renuo.ch/\"\n          slug: \"renuo\"\n          logo_url: \"https://rubyonrails.org/assets/images/logo-renuo.svg\"\n\n        - name: \"Saeloun\"\n          website: \"https://www.saeloun.com/\"\n          slug: \"saeloun\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-saeloun.svg\"\n\n        - name: \"Tablecheck\"\n          website: \"https://www.tablecheck.com/en/join/\"\n          slug: \"tablecheck\"\n          logo_url: \"https://rubyonrails.org/assets/world/2024/images/sponsors/RW-logo-tablecheck.svg\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2025/venue.yml",
    "content": "---\nname: \"Beurs van Berlage\"\n\naddress:\n  street: \"Damrak 243\"\n  city: \"Amsterdam\"\n  region: \"North Holland\"\n  postal_code: \"1012 ZJ\"\n  country: \"Netherlands\"\n  country_code: \"NL\"\n  display: \"Damrak 243, 1012 ZJ Amsterdam, Netherlands\"\n\ncoordinates:\n  latitude: 52.3752\n  longitude: 4.8956\n\nmaps:\n  google: \"https://maps.google.com/?q=Beurs+van+Berlage,+Damrak+243,+Amsterdam\"\n  apple: \"https://maps.apple.com/?q=Beurs+van+Berlage,+Damrak+243,+Amsterdam\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=52.3752&mlon=4.8956\"\n\nhotels:\n  - name: \"Sir Adam Hotel\"\n    kind: \"Speaker Hotel\"\n    address:\n      street: \"7 Overhoeksplein\"\n      city: \"Amsterdam\"\n      region: \"Noord-Holland\"\n      postal_code: \"1031 KS\"\n      country: \"Netherlands\"\n      country_code: \"NL\"\n      display: \"Overhoeksplein 7, 1031 KS Amsterdam, Netherlands\"\n    coordinates:\n      latitude: 52.383836\n      longitude: 4.902287\n    maps:\n      apple:\n        \"https://maps.apple.com/place?address=Overhoeksplein%207,%201031%20KS%20Amsterdam,%20Netherlands&coordinate=52.383836,4.902287&name=Sir%20Adam%20Hotel,%20part%20of%20Sircle\\\n        %20Collection&place-id=I666AE7C9C5413781&map=transit\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2025/videos.yml",
    "content": "---\n- title: \"Opening Keynote\"\n  speakers:\n    - David Heinemeier Hansson\n  description: |-\n    At the Rails World 2025 Opening Keynote in Amsterdam, Ruby on Rails creator David Heinemeier Hansson announced Rails 8.1 beta, Active Job Continuations, Markdown Rendering, Local CI, Action Text Lexxy, Beamer, Active Record Tenating, Kamal Geo Proxy, booted up a new Framework laptop to install the Omarchy OS and launch a Rails app (all in 6 minutes), before closing with a call to fully own every part of your development workflow, end to end.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"gcwzWzC7gUA\"\n  id: \"dhh-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-04\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n- title: \"Multi-Tenant Rails: Everybody Gets a Database!\"\n  speakers:\n    - Mike Dalessio\n  description: |-\n    As Rails's SQLite support has improved, it's finally possible to have truly multi-tenant Rails applications - isolated data for each account! - without sacrificing performance or ease of use. This talk describes a novel, production-vetted approach to isolating tenant data everywhere in Rails: the database, fragment caches, background jobs, Active Storage, Turbo Stream broadcasts, Action Mailer, and even the testing framework.\n\n    You'll learn how to build a new multi-tenant app or migrate an existing one. You'll learn the technical details of how Rails can support multiple tenants and strict data isolation. You'll see a live demonstration of a multi-tenant app. And you'll learn why a deployment topology like this might make sense for you, and how it scales up and out.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"Sc4FJ0EZTAg\"\n  id: \"mike-dalessio-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Startup Speed, Enterprise Scale: Rails Powers 3k Events/Sec Throughput\"\n  speakers:\n    - Austin Story\n  description: |-\n    Ditch vendor lock-in!\n\n    Doximity, like many mid-sized innovators, needed rapid iteration and cost-effective scale. We replaced a slow, expensive analytics vendor with a custom Rails pipeline, achieving 3k events/second scale with Rails.\n\n    Learn how Rails' integrated power—Kafka (Karafka), Action Cable for real-time debugging, and optimized request handling—enabled our small team to build a high-throughput system, slashing latency from hours to seconds and saving hundreds of thousands of dollars per year.\n\n    Learn how Rails' conventions and ecosystem offer startup agility with enterprise-level performance, proving it's the ideal toolkit for rapid growth and reclaiming control. See how your team can leverage Rails to conquer data challenges and achieve massive ROI.\n  track: \"Track 2\"\n  video_provider: \"youtube\"\n  video_id: \"YUaE4niST-k\"\n  id: \"austin-story-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"SQLite Replication with Beamer\"\n  speakers:\n    - Kevin McConnell\n  description: |-\n    SQLite is an increasingly popular choice for powering Rails applications. It's fast, simple to use, and has an impressive feature set. But without a conventional database server, scaling beyond a single application server can be challenging.\n\n    Beamer is a lightweight replication tool for SQLite, designed to make it easy to add read-only replicas to your writable databases. In this talk, we'll cover how Beamer works and how you can use it to build multi-server, geographically distributed SQLite-based Rails applications.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"lcved9uEV5U\"\n  id: \"kevin-mcconnell-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Teaching Rails with the Real Thing: Onboarding Engineers into a (Massive) Monolith\"\n  speakers:\n    - Katarina Rossi\n  description: |-\n    At Procore, our Rails monolith is massive - among the largest in the world - and intimidating to newcomers. I designed and taught a course that helped over 900 engineers of varying skill levels stop fearing it by teaching Rails and our monolith at the same time. Rather than using generic tutorials, we grounded everything in the actual product they'd be working on - layering Rails fundamentals with the domain-specific knowledge they really needed. In this talk, I'll share how learning science, product context, and deep app knowledge came together to make our course work—and how you can adapt it for your team.\n  track: \"Track 2\"\n  video_provider: \"youtube\"\n  video_id: \"xIc99XOlxE4\"\n  id: \"katarina-rossi-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"The Rise of the Agent: Rails in the AI Era\"\n  speakers:\n    - Kinsey Durham Grace\n  description: |-\n    Prompting is a start, but agents are the future. In this talk, we'll explore how intelligent agents are changing how we build software — and how we can bring them to life in the Rails ecosystem. From early CLI bots to multi-tool agents powered by LLMs, we'll trace the evolution, show what's working in production, and give you practical patterns for building agents with a Rails mindset.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"_4_wNaf_714\"\n  id: \"kinsey-durham-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Resumable Jobs with Active Job Continuations\"\n  speakers:\n    - Donal McBreen\n  description: |-\n    Long-running jobs can cause problems. They can delay deployments and leave old versions of your code running longer than expected. Interrupting them can leave data in an inconsistent state or cause redundant rework.\n\n    Active Job Continuations let you define multi-step workflows or checkpoint iterations to track your progress, and they're easy to integrate with your existing jobs. From there, they handle interrupting and resuming jobs across application restarts.\n\n    We built Active Job Continuations at 37signals to make Basecamp's jobs container-friendly for deploying with Kamal. Come to this talk to learn more about how it works.\n  track: \"Track 2\"\n  video_provider: \"youtube\"\n  video_id: \"xbyRJtWbWyM\"\n  id: \"donal-mcbreen-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Taming the Beast: Safely Managing Database Operations in Rails in a Team of 100s\"\n  speakers:\n    - Miles McGuire\n  description: |-\n    Intercom leverages Rails to empower hundreds of engineers to move fast and make the changes they need in production without a lengthy centralized review process. But allowing arbitrary migrations to run across hundreds of tables and hundreds of terabytes of data in MySQL comes with inherent risks. In this session, we'll look at where we came from, what changes we've made to reduce risk and enable people to move fast while safely leveraging Rails' power, and where we're going in the future.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"aiYJFq2hRTU\"\n  id: \"miles-mcguire-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"From Chaos to Clarity: Structured Event Reporting in Rails\"\n  speakers:\n    - Adrianna Chang\n  description: |-\n    Events in Rails applications are like the heartbeat of your code - whether it's a log, a telemetry signal, or a business event, they tell us when something interesting is happening. To truly harness he power of these events for observability and data analysis, we need high-quality, contextualized data. The human-readable lines that Rails.logger provides is great for manual inspection but falls short in production and analytics contexts.\n\n    At Shopify, we recognized the need for a unified approach to events. After years of managing various in-house solutions for structured logging, we built support for structured events into the Rails framework itself. This talk will unveil the Structured Event Reporter, Rails' new approach to structured events, and showcase how we're using it to power events in our monolith.\n  track: \"Track 2\"\n  video_provider: \"youtube\"\n  video_id: \"JK90_2L_NUM\"\n  id: \"adrianna-chang-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"The $1B Rails Startup: Scaling from 0 to Unicorn in Four Years\"\n  speakers:\n    - Jack Sharkey\n  description: |-\n    We started when Rails was \"dead.\" Everyone said it wouldn't scale, wasn't fast enough, and that no one used it anymore. Four years later, we've processed $1B+, handle 150k RPM, and run a feature-complete marketplace with real-time chat, notifications, payments, and live streaming - all on a Rails monolith with just 15 engineers.\n\n    This talk breaks down how Rails gave us a competitive edge, the technical and hiring challenges we faced, and what Rails needs to improve to stay the best framework for startups.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"Ur6HPg33dUc\"\n  id: \"jack-sharkey-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Active Record 8: Resilient by Default\"\n  speakers:\n    - Hartley McGuire\n  description: |-\n    Databases crash, connections drop, and queries timeout at the worst possible moments. Rather than writing custom rescue code everywhere, Rails is revolutionizing how Active Record handles these inevitable hiccups.\n\n    This technical deep dive explores key improvements in connection management, error handling, and recovery strategies introduced in Rails 7 and optimized in Rails 8. You'll learn how Active Record intelligently manages connection pools and retries failed queries.\n\n    Whether you're running a massive production app or building a new side project, you'll walk away knowing how to leverage these features to build applications that bend instead of break when database chaos strikes.\n  track: \"Track 2\"\n  video_provider: \"youtube\"\n  video_id: \"cjKaMRFBX0E\"\n  id: \"hartley-mcguire-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Keynote: Hotwire Native - A Rails Developer's Secret Tool for Building Mobile Apps\"\n  speakers:\n    - Joe Masilotti\n  description: |-\n    Hotwire Native lowers the barrier to launching native apps on the App Store and Google Play. Rails developers can now ship to iOS and Android without rewriting their entire stack. By reusing your existing HTML and CSS, you can keep your business logic on the server and stay productive in Rails - without needing to become a mobile expert.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"VbMt_4STWIo\"\n  id: \"joe-masilotti-rails-world-2025\"\n  date: \"2025-09-04\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Ruby & Rails - a Chat with Maintainers\"\n  speakers:\n    - Hiroshi Shibata\n    - Aaron Patterson\n    - Jean Boussier\n    - Robby Russell\n  description: |-\n    Join maintainers of Ruby and Rails for an insightful conversation about the current state and future direction of both projects. This panel discussion will cover recent developments, upcoming features, and the collaborative efforts between the Ruby and Rails core teams.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"QaQ9rF9sYHQ\"\n  id: \"ruby-rails-maintainers-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Ruby Stability at Scale\"\n  speakers:\n    - Peter Zhu\n  description: |-\n    There are many talks, articles, and tutorials on how to monitor your Rails app for stability. These assume the source of the bug comes from your application code, from Rails itself, or from a gem. But what if the source of instability comes from Ruby or a native gem? If Ruby crashes, do you have any monitoring or ways to debug it?\n\n    In this talk, we'll look at how we deal with Ruby crashes in the Shopify monolith, the world's largest Ruby on Rails application, and how you can use some of our techniques. We'll cover topics such as how we monitor crashes, capture core dumps for debugging, prevent crashes, and minimize the impact of crashes on production.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"9r0xmX0oK5Y\"\n  id: \"peter-zhu-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Rails Under a Microscope: Diagnosing Slowness at the Byte Level\"\n  speakers:\n    - Snehal Ahire\n  description: |-\n    We realized our legacy code didn't need a rewrite, it needed a performance plan.\n\n    This talk shares how we tackled real production issues like memory bloat, slow queries, and Sidekiq queues piling up under load, where simple fixes like batching jobs or tweaking retries didn't help much.\n\n    We thought Active Record was the bottleneck, but fixing it only scratched the surface. We optimised query access patterns, chose more efficient data structures, restructured background jobs, and introduced smarter database caching and indexing strategies.\n\n    I'll share how we analysed query plans, fine-tuned database performance, and replaced slow, fragile logic with leaner, more explicit code paths that scaled better and failed less while Rails stayed right at the center of it all.\n  track: \"Track 2\"\n  video_provider: \"youtube\"\n  video_id: \"Jv2N_A1OaHI\"\n  id: \"snehal-ahire-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Make Rails AI-Ready by Design with the Model Context Protocol\"\n  speakers:\n    - Paweł Strzałkowski\n  description: |-\n    Remember the joy of Rails scaffold creating web interfaces in DHH's demos? Let's make it just as simple for AI integrations!\n\n    Imagine Rails scaffolding not just views for humans, but a parallel, AI interaction layer - out of the box!\n\n    How? By embracing convention over configuration with the Model Context Protocol (MCP), the emerging standard (backed by Google & OpenAI) for AI-app interactions.\n    Example: Scaffold a ReservationsController and instantly let an AI agent book a room via MCP - just like agents may use it with GitHub or JIRA today.\n\n    I'll show:\n    - A full-stack AI-ready app scaffolded live\n    - An AI agent using it\n    - How backend, frontend, and AI layers cooperate\n    - How to make your app speak AI natively\n\n    Ultimately, this talk shows Rails' competitive advantage for the AI era.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"IYAWJQ_HSQs\"\n  id: \"pawel-strzalkowski-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Reading Rails 1.0 Source Code\"\n  speakers:\n    - OKURA Masafumi\n  description: |-\n    Rails is great. In fact, Rails has been great since the very beginning. However, in terms of technical details, Rails 1.0 was very different from Rails 8. Lots of things have changed, many frameworks have been introduced and overall quality has been polished.\n    This leads to an interesting question. What makes Rails Rails itself? What core parts of Rails still remain after 20 years?\n    In this anthropological talk, we dive into the source code of Rails 1.0 and explore internals.\n  track: \"Track 2\"\n  video_provider: \"youtube\"\n  video_id: \"IaUXMYR5MRg\"\n  id: \"masafumi-okura-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Beyond the Basics: Advanced Rails Techniques\"\n  speakers:\n    - Chris Oliver\n  description: |-\n    This talk showcases ways to take a traditional Rails app and shape it around your product domain—while also using Rails tools in ways you might not have considered.\n\n    Topics include:\n    - Creating your own app/ folders for domain concepts\n    - Creating your own generators\n    - Organizing features by modules and concerns (e.g., the User model may have teams, billing, etc., organized under app/models/user/)\n    - Adding domainwording and class methods, like allow_unauthenticated_access or rate_limit\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"lut2stH9-DI\"\n  id: \"chris-oliver-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Coming Soon: Offline Mode to Hotwire with Service Workers\"\n  speakers:\n    - Rosa Gutierrez\n  description: |-\n    At #RailsWorld, Rosa Gutiérrez shared how @37signals tackled one of Hotwire's most requested features: offline mode. After years of custom workarounds, each with varying degrees of challenges, her team took on the challenge using service workers. Long used in PWAs, they're full of gotchas, and making them work correctly in Hotwire Native apps was not an easy task. Hear what worked, what didn’t, and what ‘s next for Hotwire offline.\n\n    #RubyOnRails #RailsWorld #Hotwire #frontend #PWAs #offlinemode\n\n    Thank you Shopify for sponsoring the editing and post-production of these videos. Check out insights from the Engineering team at: https://shopify.engineering/\n\n    Subtitles (Japanese, Spanish, and Brazilian Portuguese) thanks to Happy Scribe, a transcription service built on Rails. https://www.happyscribe.com/\n  track: \"Track 2\"\n  video_provider: \"youtube\"\n  video_id: \"aeIb3sa3D3M\"\n  id: \"rosa-gutierrez-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Introducing ReActionView: An ActionView-Compatible ERB Engine\"\n  speakers:\n    - Marco Roth\n  description: |-\n    This talk is the conclusion of a journey I've been sharing throughout 2025. At RubyKaigi, I introduced Herb: a new HTML-aware ERB parser and tooling ecosystem. At RailsConf, I released developer tools built on Herb, including a formatter, linter, and language server, alongside a vision for modernizing and improving the Rails view layer. At Rails World, I'll debut ReActionView: a new ERB engine built on Herb, fully compatible with `.html.erb` but with HTML validation, better error feedback, reactive updates, and built-in tooling.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"su8CJeVRYps\"\n  id: \"marco-roth-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-08-04\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n  slides_url: \"https://speakerdeck.com/marcoroth/introducing-reactionview-a-new-actionview-compatible-erb-engine-at-rails-world-2025-amsterdam\"\n\n- title: \"Passkeys Have Problems, but So Will You If You Ignore Them\"\n  speakers:\n    - Jason Meller\n  description: |-\n    Back in 2024, many of us in the Rails community dismissed passkeys as hype rather than a real password replacement. But now we're facing a serious problem - a newer and more sophisticated attack called Real-Time Phishing is gaining popularity and effortlessly defeating nearly all popular 2FA methods, except one: passkeys. Even security experts are getting fooled, and AI makes these attacks frighteningly scalable. In this session, I'll demo exactly how attackers execute real-time phishing live. Then we'll turn the tables: I'll guide you step-by-step through adding secure, user-friendly passkey authentication as an MFA option to your Rails 8 apps. Come on, Rails! Let's give passkeys one more chance.\n  track: \"Track 2\"\n  video_provider: \"youtube\"\n  video_id: \"XP-76tYy2m4\"\n  id: \"jason-meller-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"LLM Evaluations & Reinforcement Learning for Shopify Sidekick on Rails\"\n  speakers:\n    - Andrew Mcnamara\n    - Charlie Lee\n  description: |-\n    This talk explores building production LLM systems through Shopify Sidekick's Rails architecture, covering orchestration patterns and tool integration strategies. We'll establish statistically rigorous LLM-based evaluation frameworks that move beyond subjective 'vibe testing.' Finally, we'll demonstrate how robust evaluation systems become critical infrastructure for reinforcement learning pipelines, while exploring how RL can learn to hack evaluations and strategies to mitigate this.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"xFW-oCpLa3w\"\n  id: \"andrew-mcnamara-charlie-lee-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Lessons from Migrating a Legacy Frontend to Hotwire\"\n  speakers:\n    - Radan Skorić\n  description: |-\n    Is Hotwire just for `rails new` scenarios and not worth it for mature applications? Absolutely not.\n\n    I share my learnings from leading a migration of Halalbooking.com, a large hotel booking website, from a mix of technologies centered on React to Hotwire.\n\n    Even though we couldn't enable Turbo Drive, we got a huge DX and performance boost from using other parts of Hotwire, making the migration more than worth it.\n\n    I'll share specific examples and lessons learned along the way. You'll leave optimistic about introducing Hotwire to a mature codebase.\n\n    As a bonus, you'll see:\n    - When it's beneficial\n    - How fast it pays back\n    - How to introduce it gradually\n    - Two concrete examples of complex Hotwire UIs\n  track: \"Track 2\"\n  video_provider: \"youtube\"\n  video_id: \"kWFYc6qrXIo\"\n  id: \"radan-skoric-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-15\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n\n- title: \"Closing Keynote\"\n  speakers:\n    - Aaron Patterson\n  description: |-\n    In the #RailsWorld Closing Keynote, Aaron Patterson (Ruby core team member since 2009, Rails core since 2011, and Senior Staff Engineer at Shopify) talks about the work that Shopify’s Ruby & Rails Infrastructure team is tackling in Ruby core, including Ractors for better parallelism and a new method-based JIT compiler, ZJIT, and shares some pro tips for Rails developers on writing JIT-friendly code.\n  track: \"Track 1\"\n  video_provider: \"youtube\"\n  video_id: \"tiuW0JvPa7k\"\n  id: \"aaron-patterson-rails-world-2025\"\n  date: \"2025-09-05\"\n  published_at: \"2025-09-13\"\n  announced_at: \"2025-05-20\"\n  event_name: \"Rails World 2025\"\n  language: \"english\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2026/event.yml",
    "content": "---\nid: \"rails-world-2026\"\ntitle: \"Rails World 2026\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: |-\n  Rails World is a two-day, two track community conference featuring technical talks, demos, networking, and keynotes about the latest features and best practices in Rails development.\nstart_date: \"2026-09-23\"\nend_date: \"2026-09-24\"\nchannel_id: \"UC9zbLaqReIdoFfzdUbh13Nw\"\nyear: 2026\nbanner_background: \"#3B1D62\"\nfeatured_background: \"#3B1D62\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubyonrails.org/world\"\ncoordinates:\n  latitude: 30.260513\n  longitude: -97.752989\n"
  },
  {
    "path": "data/rails-world/rails-world-2026/venue.yml",
    "content": "---\nname: \"Palmer Event Center\"\n\naddress:\n  street: \"900 Barton Springs Rd\"\n  city: \"Austin\"\n  region: \"Texas\"\n  postal_code: \"78704\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"900 Barton Springs Rd, Austin, TX 78704, United States\"\n\ncoordinates:\n  latitude: 30.260513\n  longitude: -97.752989\n\nmaps:\n  google: \"https://maps.app.goo.gl/UWRLPgUbpD7jS6YW7\"\n  apple:\n    \"https://maps.apple.com/place?address=900%20Barton%20Springs%20Rd,%20Austin,%20TX%20%2078704,%20United%20States&coordinate=30.260513,-97.752989&name=Palmer%20Events%20Cente\\\n    r&place-id=I34A31827DB721CB8&map=transit\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=30.260513&mlon=-97.752989\"\n"
  },
  {
    "path": "data/rails-world/rails-world-2026/videos.yml",
    "content": "# TODO: add talks\n---\n[]\n"
  },
  {
    "path": "data/rails-world/series.yml",
    "content": "---\nname: \"Rails World\"\nwebsite: \"https://rubyonrails.org/world\"\ntwitter: \"rails\"\nkind: \"conference\"\nfrequency: \"yearly\"\nyoutube_channel_name: \"railsofficial\"\nlanguage: \"english\"\nyoutube_channel_id: \"UC9zbLaqReIdoFfzdUbh13Nw\"\naliases:\n  - RailsWorld\n"
  },
  {
    "path": "data/railsberry/railsberry-2012/event.yml",
    "content": "---\nid: \"PL036AC827C6995617\"\ntitle: \"Railsberry 2012\"\nkind: \"conference\"\nlocation: \"Kraków, Poland\"\ndescription: |-\n  European Rails Conference Railsberry 2012\npublished_at: \"2012-05-25\"\nstart_date: \"2012-04-19\"\nend_date: \"2012-04-20\"\nchannel_id: \"UC8dsjHz_0WVzHjAANKiAqGw\"\nyear: 2012\nwebsite: \"https://web.archive.org/web/20120623201143/http://railsberry.com/\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F02556\"\ncoordinates:\n  latitude: 50.06465009999999\n  longitude: 19.9449799\n"
  },
  {
    "path": "data/railsberry/railsberry-2012/schedule.yml",
    "content": "# Schedule: Railsberry 2012\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2012-04-19\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:40\"\n        slots: 1\n        items:\n          - Registration & Welcome Muffins\n\n      - start_time: \"09:40\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - title: \"Hello and welcome\"\n            description: |-\n              Ela Madej\n\n      - start_time: \"10:00\"\n        end_time: \"10:50\"\n        slots: 1\n\n      - start_time: \"10:50\"\n        end_time: \"11:40\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:10\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"12:10\"\n        end_time: \"13:00\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"13:30\"\n        slots: 1\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 1\n\n      - start_time: \"14:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Yummy Lunch Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"18:30\"\n        slots: 1\n\n      - start_time: \"21:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - title: \"OMG! GitHub Drinkup\"\n            description: |-\n              GitHub Drinkup\n\n  - name: \"Day 2\"\n    date: \"2012-04-20\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Coffee & Croissants\n\n      - start_time: \"09:30\"\n        end_time: \"10:20\"\n        slots: 1\n\n      - start_time: \"10:20\"\n        end_time: \"10:50\"\n        slots: 1\n\n      - start_time: \"10:50\"\n        end_time: \"11:40\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:10\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"12:10\"\n        end_time: \"13:10\"\n        slots: 1\n\n      - start_time: \"13:10\"\n        end_time: \"13:40\"\n        slots: 1\n\n      - start_time: \"13:40\"\n        end_time: \"15:10\"\n        slots: 1\n        items:\n          - Yummy Lunch Break\n\n      - start_time: \"15:10\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"18:30\"\n        slots: 1\n\n      - start_time: \"18:30\"\n        end_time: \"19:00\"\n        slots: 1\n\n      - start_time: \"21:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - title: \"YAY! Wooga Party\"\n            description: |-\n              Wooga Party\n\ntracks: []\n"
  },
  {
    "path": "data/railsberry/railsberry-2012/videos.yml",
    "content": "---\n- id: \"jos-valim-railsberry-2012\"\n  title: \"Let's talk concurrency\"\n  raw_title: \"José Valim - Let's talk concurrency (Railsberry 2012)\"\n  speakers:\n    - José Valim\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-28\"\n  date: \"2012-04-19\"\n  video_provider: \"youtube\"\n  video_id: \"ojU4O2CMeSc\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 1\n\n- id: \"zach-holman-railsberry-2012\"\n  title: \"Aggressively Probing Ruby Projects\"\n  raw_title: \"Zach Holman - Aggressively Probing Ruby Projects (Railsberry 2012)\"\n  speakers:\n    - Zach Holman\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-28\"\n  date: \"2012-04-19\"\n  video_provider: \"youtube\"\n  video_id: \"7GStXCabFXw\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 1\n\n- id: \"patrick-huesler-railsberry-2012\"\n  title: \"Treasure Island - Concurrency in JRuby\"\n  raw_title: \"Patrick Huesler and Tim Lossen - Treasure Island - Concurrency in JRuby (Railsberry 2012)\"\n  speakers:\n    - Patrick Huesler\n    - Tim Lossen\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-31\"\n  date: \"2012-04-19\"\n  video_provider: \"youtube\"\n  video_id: \"oBv1U2slBFY\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 1\n\n- id: \"ben-orenstein-railsberry-2012\"\n  title: \"Write code faster: expert-level vim\"\n  raw_title: \"Ben Orenstein - Write code faster: expert-level vim (Railsberry 2012)\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-31\"\n  date: \"2012-04-19\"\n  video_provider: \"youtube\"\n  video_id: \"SkdrYWhh-8s\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 1\n\n- id: \"konstantin-haase-railsberry-2012\"\n  title: \"Something About Pull Request\" # Message in a bottle\n  raw_title: \"Konstantin Haase - Something About Pull Request (Railsberry 2012)\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-30\"\n  date: \"2012-04-19\"\n  video_provider: \"youtube\"\n  video_id: \"YFzloW8F-nE\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 1\n\n- id: \"marcin-bunsch-railsberry-2012\"\n  title: \"Building fast APIs with Rails\"\n  raw_title: \"Marcin Bunsch - Building fast APIs with Rails (Railsberry 2012)\"\n  speakers:\n    - Marcin Bunsch\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-30\"\n  date: \"2012-04-19\"\n  video_provider: \"youtube\"\n  video_id: \"iYhf_fcqg-0\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 1\n\n- id: \"randall-thomas-railsberry-2012\"\n  title: \"Take the PITA out of SOA: Building Lean Service Oriented Architectures\"\n  raw_title: \"Tammer Saleh - SOA AntiPatterns (Railsberry 2012)\"\n  speakers:\n    - Randall Thomas\n    - Tammer Saleh\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-06-02\"\n  date: \"2012-04-19\"\n  video_provider: \"youtube\"\n  video_id: \"Z-R__2DO9lw\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 1\n\n- id: \"linda-liukas-railsberry-2012\"\n  title: \"Rails Girls – agenda-what every girl* needs to know about programming\"\n  raw_title: \"Linda Liukas - What every girl needs to know about programming (Railsberry 2012)\"\n  speakers:\n    - Linda Liukas\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-30\"\n  date: \"2012-04-19\"\n  video_provider: \"youtube\"\n  video_id: \"_rkkFdQeBlA\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 1\n\n- id: \"corey-donohoe-railsberry-2012\"\n  title: \"Enterprise Me: Hurdles involved in taking a SaaS app to the next level\"\n  raw_title: \"Corey Donohoe - Enterprise Me: Hurdles involved in taking a SaaS app to the next level\"\n  speakers:\n    - Corey Donohoe\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-06-02\"\n  date: \"2012-04-19\"\n  video_provider: \"youtube\"\n  video_id: \"NxN6d4Azh7A\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 1\n\n- id: \"lightning-talks-day-1-railsberry-2012\"\n  title: \"Lightning Talks Day 1\"\n  raw_title: \"Lightning Talks Day 1\"\n  speakers:\n    - TODO\n  event_name: \"Railsberry 2012\"\n  date: \"2012-04-19\"\n  video_provider: \"children\"\n  video_id: \"lightning-talks-day-1-railsberry-2012\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 1\n\n## Day 2\n\n- id: \"yehuda-katz-railsberry-2012\"\n  title: \"Why Rails is Hard\"\n  raw_title: \"Yehuda Katz - Why Rails is Hard (Railsberry 2012)\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-28\"\n  date: \"2012-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"2Ex8EEv-WPs\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n\n- id: \"mariusz-usiak-railsberry-2012\"\n  title: \"Solid foundations for Rails apps\"\n  raw_title: \"Mariusz Łusiak - Solid foundations for Rails apps (Railsberry 2012)\"\n  speakers:\n    - Mariusz Łusiak\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-25\"\n  date: \"2012-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"_cf8SsKzXCA\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n\n- id: \"aaron-patterson-railsberry-2012\"\n  title: \"Code Charcuterie\"\n  raw_title: \"Aaron Patterson - Code Charcuterie (Railsberry 2012)\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-28\"\n  date: \"2012-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"KAspsnLW3so\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n\n- id: \"josh-kalderimis-railsberry-2012\"\n  title: \"Funding Open Source with Peace, Love and Happiness\"\n  raw_title: \"Josh Kalderimis - Funding Open Source with Peace, Love and Happiness (Railsberry 2012)\"\n  speakers:\n    - Josh Kalderimis\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-06-02\"\n  date: \"2012-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"F8Hq6ga7vH8\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n\n- id: \"sebastian-deutsch-railsberry-2012\"\n  title: \"All about CoffeeScript\"\n  raw_title: \"Sebastian Deutsch - All about CoffeeScript (Railsberry 2012)\"\n  speakers:\n    - Sebastian Deutsch\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-29\"\n  date: \"2012-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"7-Y3wP9lLg0\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n\n- id: \"elliott-kember-railsberry-2012\"\n  title: \"Rails and Friends\"\n  raw_title: \"Elliott Kember - Rails and Friends (Railsberry 2012)\"\n  speakers:\n    - Elliott Kember\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-29\"\n  date: \"2012-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"OmJNmLcVvQ4\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n\n- id: \"eric-redmond-railsberry-2012\"\n  title: \"Down the NoSQL Rabbit Hole\"\n  raw_title: \"Eric Redmond - Down the NoSQL Rabbit Hole (Railsberry 2012)\"\n  speakers:\n    - Eric Redmond\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-31\"\n  date: \"2012-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"ZEE8S5A6gJs\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n\n- id: \"xavier-noria-railsberry-2012\"\n  title: \"Rails Contributors\"\n  raw_title: \"Xavier Noria - Rails Contributors (Railsberry 2012)\"\n  speakers:\n    - Xavier Noria\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-29\"\n  date: \"2012-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"3sR23_fCadY\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n\n- id: \"tom-stuart-railsberry-2012\"\n  title: \"Stop using development mode\"\n  raw_title: \"Tom Stuart - Stop using development mode (Railsberry 2012)\"\n  speakers:\n    - Tom Stuart\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-28\"\n  date: \"2012-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"TQrEKwb5lR0\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n\n- id: \"jon-leighton-railsberry-2012\"\n  title: \"You hate your codebase and it's your fault\"\n  raw_title: \"Jon Leighton - You hate your codebase and it's your fault (Railsberry 2012)\"\n  speakers:\n    - Jon Leighton\n  event_name: \"Railsberry 2012\"\n  published_at: \"2012-05-28\"\n  date: \"2012-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"C7KdY2M5l5Q\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n\n- id: \"lightning-talks-day-2-railsberry-2012\"\n  title: \"Lightning Talks Day 2\"\n  raw_title: \"Lightning Talks Day 2\"\n  speakers:\n    - TODO\n  event_name: \"Railsberry 2012\"\n  date: \"2012-04-20\"\n  video_provider: \"children\"\n  video_id: \"lightning-talks-day-2-railsberry-2012\"\n  description: |-\n    European Rails Conference Railsberry 2012, Day 2\n"
  },
  {
    "path": "data/railsberry/series.yml",
    "content": "---\nname: \"Railsberry\"\nwebsite: \"https://web.archive.org/web/20120623201143/http://railsberry.com/\"\ntwitter: \"railsberry\"\nyoutube_channel_name: \"applicake\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Railsberry\"\ndefault_country_code: \"PL\"\nlanguage: \"english\"\nyoutube_channel_id: \"UC8dsjHz_0WVzHjAANKiAqGw\"\nended: true\n"
  },
  {
    "path": "data/railsclub/railsclub-2014/event.yml",
    "content": "---\nid: \"railsclub-2014\"\ntitle: \"RailsClub 2014\"\ndescription: \"\"\nlocation: \"Moscow, Russia\"\nkind: \"conference\"\nstart_date: \"2014-09-27\"\nend_date: \"2014-09-27\"\nwebsite: \"https://rubyrussia.club\"\ntwitter: \"railsclub_ru\"\nplaylist: \"https://www.youtube.com/watch?v=i6mTsTpOi2Y&list=UU0W9Gjw4JzUcC2BfFf1MDHA\"\ncoordinates:\n  latitude: 55.7568721\n  longitude: 37.6150527\n"
  },
  {
    "path": "data/railsclub/railsclub-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyrussia.club\n# Videos: https://www.youtube.com/watch?v=i6mTsTpOi2Y&list=UU0W9Gjw4JzUcC2BfFf1MDHA\n---\n[]\n"
  },
  {
    "path": "data/railsclub/railsclub-2015/event.yml",
    "content": "---\nid: \"railsclub-2015\"\ntitle: \"RailsClub 2015\"\ndescription: \"\"\nlocation: \"Moscow, Russia\"\nkind: \"conference\"\nstart_date: \"2015-09-26\"\nend_date: \"2015-09-26\"\nwebsite: \"https://web.archive.org/web/20150929062002/http://railsclub.ru/\"\ntwitter: \"railsclub_ru\"\nplaylist: \"https://www.youtube.com/playlist?list=PLiWUIs1hSNeOiwKkEcdRU7NvQr2IKaMBw\"\nfeatured_color: \"#FFFFFF\"\nfeatured_background: \"#FF0000\"\nbanner_background: \"#FF0000\"\ncoordinates:\n  latitude: 55.7568721\n  longitude: 37.6150527\n"
  },
  {
    "path": "data/railsclub/railsclub-2015/videos.yml",
    "content": "---\n# Website: https://rubyrussia.club/\n# Videos: https://www.youtube.com/playlist?list=PLiWUIs1hSNeOiwKkEcdRU7NvQr2IKaMBw\n\n- id: \"claudio-baccigalupo-railsclub-2015\"\n  title: \"Rails 5: awesome features and breaking changes\"\n  raw_title: \"Claudio Baccigalipo. Rails 5: awesome features and breaking changes\"\n  speakers:\n    - Claudio Baccigalupo\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Each major release of Rails brings shiny new features and mild headaches for developers required to upgrade their applications and gems.\n\n    Rails API, ActionCable, Turbolinks 3 are only a few of the changes announced for Rails 5. How can programmers get ready for the future without breaking their legacy code?\n\n    In this talk, I will cover the improvements brought by Rails 5, explain the Core team's motivations behind each feature, and illustrate the upgrade process to smoothly transition gems and apps from Rails 4.2 to Rails 5.0.\n  video_provider: \"youtube\"\n  video_id: \"GbtepoRfH60\"\n  language: \"English\"\n\n- id: \"bozhidar-batsov-railsclub-2015\"\n  title: \"Volt: Ruby web development recharged\"\n  raw_title: \"Bozhidar Batsov. Volt: Ruby web development recharged\"\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Volt is a reactive web framework where your Ruby code runs both on the server and the client. Sounds crazy, right? Trust me, though, this is pretty amazing and will blow your minds.\n\n    Volt is probably the most exciting web framework in the land of Ruby since Rails. In this talk we'll go over the core ideas and principles of Volt, the advantages of Volt over traditional web apps and we'll play with a few basic examples. We'll wrap with a look towards Volt's bright future. Above all else - we'll have fun!\n  video_provider: \"youtube\"\n  video_id: \"wDone3jQz0U\"\n  language: \"English\"\n\n- id: \"samat-galimov-railsclub-2015\"\n  title: \"Microservices and Elixir for Rails developers\"\n  original_title: \"Микросервисы и Elixir для Rails-разработчиков\"\n  raw_title: \"Самат Галимов и Борис Горячев. Микросервисы и Elixir для Rails-разработчиков\"\n  speakers:\n    - Samat Galimov\n    - Boris Goryachev\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Рассказ пойдет о том, как мы разделяем наше основное rails приложение и создаем микросервис-архитектуру. Как за год было написано более 10-ти проектов разных уровней сложности, и чем мы руководствовались, когда это затевали.\n\n    Для нас зачастую выбор языка/фреймворка под проект чуть ли не сложнее, чем написание самого проекта, и в докладе мы постараемся объяснить целесообразность того или иного выбора(заранее признаюсь - в некоторых местах мы славно напортачили).\n\n    Также расскажем о случаях, когда лучше заблаговременно сойти с рельс и как себя при этом обезопасить. В конце доклада мы постараемся убедить вас попробовать elixir - прекрасный молодой функциональный язык программирования. На десерт несколько примеров, где он стал для нас right tool for the job.\n  video_provider: \"youtube\"\n  video_id: \"AG_QHHi01j4\"\n  language: \"Russian\"\n\n- id: \"sam-phippen-railsclub-2015\"\n  title: \"Mocking language\"\n  raw_title: \"Sam Phippen. Mocking language\"\n  speakers:\n    - Sam Phippen\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    This talk is an investigation into the different kinds of ways we isolate objects from their collaborators. They all seem to provide similar capabilities but there is an underlying language that talks to us about different kinds of design smells that we might have in our applications.\n\n    This talk will cover the different kinds of test doubles that we use in our applications and what they indicate about the designs of our software.\n  video_provider: \"youtube\"\n  video_id: \"9bWQfTG3Uzg\"\n  language: \"English\"\n\n- id: \"koichi-sasada-railsclub-2015\"\n  title: \"Performance in the details: a way to make faster Ruby\"\n  raw_title: \"Koichi Sasada. Performance in the details: a way to make faster Ruby\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Heroku Matz team is working to improve quality of CRuby/MRI. Quality has several meanings, such as stability, low resource consumption, and of course speed. My main goal is to make faster Ruby.\n\n    However, we don't have one absolute solution to speed up Ruby interpreter. Instead of one solution, we introduce variety of techniques to improve Ruby's performance. In this talk, I will show you recent achievements by techniques in details.\n  video_provider: \"youtube\"\n  video_id: \"JpiioISI_2I\"\n  language: \"English\"\n\n- id: \"andrey-deryabin-railsclub-2015\"\n  title: \"Microservices at Gett: launching new verticals and working under load\"\n  original_title: \"Микросервисы в Gett: открытие новых направлений и работа под нагрузкой\"\n  raw_title: \"Андрей Дерябин. Микросервисы в Gett: открытие новых направлений и работа под нагрузкой\"\n  speakers:\n    - Andrey Deryabin\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Gett (ранее известный как GetTaxi), популярнейший сервис для заказа такси, в этом году не только вырос по бизнес-показателям, но и открыл новые направления деятельности (вертикали) — например, доставку еды и проведение работ на дому. Чтобы отвечать требованиям бизнеса по росту, и особенно — для возможности строить новые вертикали на существующих мощностях, архитекторы Gett начали перевод сервиса на микросервисную архитектуру.\n\n    В этом Gett помогала команда марсиан под руководством Андрея. За короткий срок у Gett получилось перейти от монолитной архитектуре к использованию микросервисов — в боевом режиме, в четырех странах (США, Великобритания, Россия, Израиль). Это позволило существенно ускорить и упростить работу над разработкой новых направлений.\n\n    Вместо теоретических рассказов о том, как здорово использовать микросервисы и почему все якобы непременно должны это делать, Андрей сконцентрируется на практике и боевом опыте. В докладе он расскажет про сложности, с которыми пришлось столкнуться при разработке микросервисов и способами их решения — реализация взаимодействия сервисов (средствами REST API), версионирование состояния системы, логирование изменений (стратегия COW), распределенное конфигурирование (ZooKeeper), работа с shared-частями микросервисов, развертвывание (Chef) и тестирование. Отдельно Андрей подробно остановится на реализации паттерна Circuit Breaker для решения проблем в канале связи между сервисами.\n  video_provider: \"youtube\"\n  video_id: \"XkKKW8BsICc\"\n  language: \"Russian\"\n\n- id: \"andrey-kumanyaev-railsclub-2015\"\n  title: \"Finding where and why your production app is slow\"\n  original_title: \"Ищем где и почему production приложение тормозит\"\n  raw_title: \"Андрей Куманяев. Ищем где и почему production приложение тормозит\"\n  speakers:\n    - Andrey Kumanyaev\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Многие из разработчиков мира Ruby on Rails знакомы с богатым набором инструментов для профилировали приложения в development среде. Зачастую, работа с этими инструментами заканчивается до/после выкатки фичи в production. Сначала все может работать хорошо и быстро, ну а дальше... как повезет.\n\n    В докладе я расскажу о том, как можно в production среде следить за показателями производительности приложений и отлавливать те самые кейсы, когда оно начинает вести себя не так, как хотелось бы.\n  video_provider: \"youtube\"\n  video_id: \"P85K6U6M6mQ\"\n  language: \"Russian\"\n\n- id: \"egor-homakov-railsclub-2015\"\n  title: \"Authentication of the future\"\n  original_title: \"Аутенфикация будущего\"\n  raw_title: \"Егор Хомяков. Аутенфикация будущего\"\n  speakers:\n    - Egor Homakov\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Я расскажу про массу проблем современной аутенфикации по логинам и паролям, про минусы существующей \"двух факторной аутенфикации\" и про то как я пытаюсь это решить своим продуктом Труфактор.\n  video_provider: \"youtube\"\n  video_id: \"tcl6gchsoxA\"\n  language: \"Russian\"\n\n- id: \"alexander-kirillov-railsclub-2015\"\n  title: \"Ruby Object Mapper: revolution\"\n  raw_title: \"Александр Кириллов. Ruby Object Mapper: revolution\"\n  speakers:\n    - Alexander Kirillov\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Ruby Object Mapper (ROM) - экспериментальная Ruby библиотека для реализации отображения «чистых» Ruby объектов, позволяющая без лишних ограничений использовать всю мощь выбранного хранилища данных.\n\n    ROM основан на нескольких концепциях, отличающихся от «нормальной» Ruby ORM. Я расскажу об этих концепциях, разберу особенности библиотеки и покажу как жить без Active Record.\n  video_provider: \"youtube\"\n  video_id: \"NYsnTEcoq9Y\"\n  language: \"Russian\"\n\n- id: \"nikolai-ryzhikov-railsclub-2015\"\n  title: \"Functional programming for Rubyists\"\n  original_title: \"ФП для рубистов\"\n  raw_title: \"Николай Рыжиков. ФП для рубистов\"\n  speakers:\n    - Nikolai Ryzhikov\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Мульти-парадигменности не существует по определению! Ruby существенно объектно ориентированный и императивный язык, а значит он автоматически \"наследует\" все системные проблемы объектно-ориентированных и императивных языков: отсутствие теоретической основы, слабая модульность, сложная декомпозиция, плохая конкурентность. Многие ruby инженеры испытывают болезненные ощущения и фрустрацию, сталкиваясь с ними. Я поделюсь с вами своими мыслями о том, почему функциональная парадигма с подобными вопросами справляется лучше.\n  video_provider: \"youtube\"\n  video_id: \"niuimUxGXAE\"\n  language: \"Russian\"\n\n- id: \"timofey-tsvetkov-railsclub-2015\"\n  title: \"Lambda and Kappa architectures in Ruby on Rails\"\n  raw_title: \"Тимофей Цветков. Lambda and Kappa architectures in Ruby on Rails\"\n  speakers:\n    - Timofey Tsvetkov\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Nowadays it's absolutely clear that data is one of the most valuable assets and thoughtful data analysis plays essential role in any company's success. Whether you run machine learning algorithms to build smarter and more user friendly applications or to build financial and marketing reports for stake holders, you need to perform data transformations and calculations. Such applications can't be designed in a classical Ruby on Rails way. Lambda and Kappa architectures are common patterns for building data processing applications.\n\n    Toptal is a constantly growing company and is on track for $100M in revenue in 2015. To archive this in Toptal, we're constantly improving our processes, KPIs and of course, our application. We're searching for pitfalls and places to improve by monitoring our processes and by analysing our data.\n\n    In this talk we will discuss main principles of Lambda and Kappa architectures and their implementations using Ruby on Rails based on Toptal's analytics team experience.\n  video_provider: \"youtube\"\n  video_id: \"Kawe6Mtrz1w\"\n  language: \"English\"\n\n- id: \"kir-shatrov-railsclub-2015\"\n  title: \"Building RailsPerf, a toolkit to detect performance regressions in Ruby on Rails core\"\n  raw_title: \"Кирилл Шатров. Building RailsPerf, a toolkit to detect performance regressions in Ruby on Rails core\"\n  speakers:\n    - Kir Shatrov\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    На примере бета-версий Rails 4.2 мы убедились, как часто в фреймворке Rails могут случаться регрессии производительности, и как легко они могут остаться незамеченными.\n\n    Проблема производительности и ее регрессий становится все более острой в Ruby-сообществе. Это подтолкнуло меня и других контрибьюторов Rails к разработке Rubybench, сервиса для поиска регрессий производительности в Ruby и Rails.\n\n    В своем докладе я рассмотрю регрессии производительности на примерах коммитов из Rails, расскажу о построении бенчмарков для Ruby приложений, и продемонстрирую Rubybench и его архитектуру.\n  video_provider: \"youtube\"\n  video_id: \"xNgjEzLW4pA\"\n  language: \"Russian\"\n\n- id: \"semen-bagreev-railsclub-2015\"\n  title: \"Testing and 'software writer' a year later\"\n  original_title: 'Тестирование и \"software writer\" год спустя'\n  raw_title: 'Семен Багреев. Тестирование и \"software writer\" год спустя'\n  speakers:\n    - Semen Bagreev\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-23\"\n  date: \"2015-09-26\"\n  description: |-\n    Год назад, во время открытия RailsConf 2014, David Heinemeier Hansson поделился с нами своими мыслями по поводу профессии инженера-­разработчика ПО (или \"писателя ПО\", по его версии) и по поводу TDD. Вкратце, DHH высказался довольно резко в сторону TDD, аргументируя это тем, что TDD ломает дизайн, делая его необоснованно сложным для понимания, давая при этом ложное чувство уверенности, основанное на выдуманных показателях (coverage, ratio, speed).\n\n    Я примерил роль \"Писателя ПО\". Следуя советам Дэвида, я старался тестировать всю систему, а не отдельные юниты, фокусируясь на интеграционных и \"frontend\" тестах. В процессе я столкнулся с непониманием некоторых коллег и бизнес лидеров. Мне пришлось развеять несколько мифов о тестировании, и я поделюсь этим опытом с другими разработчиками.\n\n    Кроме того, я узнал несколько трюков для ускорения тестов, освоил несколько новых инструментов для тестирования, которые и упомяну в своем докладе.\n  video_provider: \"youtube\"\n  video_id: \"ppO59eP8W5E\"\n  language: \"Russian\"\n\n- id: \"anna-shcherbinina-railsclub-2015\"\n  title: \"Lightning Talk: Crystal\"\n  raw_title: \"Анна Щербинина. LT: Crystal.\"\n  speakers:\n    - Anna Shcherbinina\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-11-24\"\n  date: \"2015-09-26\"\n  description: |-\n    Crystal - компилируемый в нативный код язык. Как говорят сами разработчики, его синтаксис вдохновлен Ruby. Поэтому порог вождения для ruby разработчика не высок, и, действительно, глядя на код невольно возникает вопрос: это Crystal или Ruby?\n\n    Расскажу о реализации микросервиса на Crystal: сходстве и различи c Ruby, плюсах, минусах и использовании в production.\n  video_provider: \"youtube\"\n  video_id: \"_dmo1p95QpI\"\n  language: \"Russian\"\n\n- id: \"nikolay-bienko-railsclub-2015\"\n  title: \"Lightning Talk: How to start diving into a large Rails project\"\n  original_title: \"Как начать погружение в большой проект на Rails\"\n  raw_title: \"Николай Биенко. LT: Как начать погружение в большой проект на Rails\"\n  speakers:\n    - Nikolay Bienko\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-12-02\"\n  date: \"2015-09-26\"\n  description: |-\n    Во время разработки большую часть времени мы не пишем, а читаем код, поэтому необходимо уметь делать это эффективно, а это особенно сложно, когда вы еще не знакомы с проектом.\n\n    Я шаг за шагом расскажу как войти в проект максимально быстро и эффективно, куда нужно смотреть в первую очередь, какие выводы можно cделать на основе увиденного и какие инструменты могут быть полезны на каждом из этапов.\n  video_provider: \"youtube\"\n  video_id: \"XLdZu6Khncc\"\n  language: \"Russian\"\n\n- id: \"kirill-gorin-railsclub-2015\"\n  title: \"Lightning Talk: Active Support Instrumentation\"\n  raw_title: \"Кирилл Горин. LT: Active Support Instrumentation\"\n  speakers:\n    - Kirill Gorin\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-12-02\"\n  date: \"2015-09-26\"\n  description: |-\n    Все пользуются средствами мониторинга для Rails приложений, но не все знают, что они работают на основе встроенных в Rails инструментов. Active Support Instrumentation один из них. В этом докладе я расскажу как его использовать и как можно самому написать конкурента New Relic.\n  video_provider: \"youtube\"\n  video_id: \"nIHxutrp6wE\"\n  language: \"Russian\"\n\n- id: \"anton-davydov-railsclub-2015\"\n  title: \"Lightning Talk: Sidekiq Under the Hood\"\n  raw_title: \"Антон Давыдов. LT: SIDEKIQ UNDER HOOD\"\n  speakers:\n    - Anton Davydov\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-12-02\"\n  date: \"2015-09-26\"\n  description: |-\n    Все мы знаем про sidekiq. Кто-то больше, кто-то меньше, но все, кто его использовал, могут сказать, что это надежный и быстрый инструмент для обработки фоновых задач. Кроме всего прочего, для sidekiq невероятно просто создавать различные плагины и всячески расширять его функционал.\n\n    Но вы когда-нибудь заглядывали под его капот?\n\n    Во время своего выступления я расскажу про архитектуру sidekiq, какая магия происходит между клиентским вызовом джоба и его выполнением. Расскажу, как работает мой плагин, собирающий всю необходимую статистику, и как вы можете быстро добавить любой недостающий вам функционал.\n  video_provider: \"youtube\"\n  video_id: \"t4QJ0kB9o9E\"\n  language: \"Russian\"\n\n- id: \"stanislav-german-railsclub-2015\"\n  title: \"Lightning Talk: Command Query Responsibility Segregation in Rails applications\"\n  raw_title: \"Станислав Герман. LT: Command Query Responsibility Segregation в Rails приложениях.\"\n  speakers:\n    - Stanislav German\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-12-02\"\n  date: \"2015-09-26\"\n  description: |-\n    CQRS - подход к разработке, когда изменяющие состояние системе cущности, commans, отделены от не меняющих состояние, query.\n\n    Такой подход нельзя назвать только лишь паттерном, так как он влияет и на архитектуру приложения.\n\n    В данном докладе мы рассмотрим каким образом достигается разделение команд и запросов. Какой уровень разделения необходим в каком случае. Рассмотрим на примерах как мы используем CQRS в продуктах Рамблера.\n  video_provider: \"youtube\"\n  video_id: \"CbafCkThYts\"\n  language: \"Russian\"\n\n- id: \"vladimir-yartsev-railsclub-2015\"\n  title: \"Lightning Talk: Personal Heroku add-on with Docker\"\n  raw_title: \"Владимир Ярцев. LT: Personal Heroku add-on with Docker\"\n  speakers:\n    - Vladimir Yartsev\n  event_name: \"RailsClub 2015\"\n  published_at: \"2015-12-02\"\n  date: \"2015-09-26\"\n  description: |-\n    В каталоге аддонов Heroku более 100 готовых микросервисов, но иногда подходящего аддона нет, а с Heroku уходить не хочется.\n\n    Одно из решений — Docker, который позволяет собрать микросервис, взяв за основу образ с Docker Hub. Вот только поддержка инфраструктуры микросервиса в этом случае ложится на плечи разработчика.\n\n    Я расскажу, как совместить удобство Heroku с гибкостью Docker, заставив микросервис вести себя как аддон Heroku.\n  video_provider: \"youtube\"\n  video_id: \"mxL7KGr6Www\"\n  language: \"Russian\"\n\n- id: \"ivan-nemytchenko-railsclub-2015\"\n  title: \"How to stop being a Rails developer\"\n  original_title: \"Как перестать быть Rails-разработчиком\"\n  raw_title: \"Иван Немытченко. Как перестать быть Rails-разработчиком\"\n  speakers:\n    - Ivan Nemytchenko\n  event_name: \"RailsClub 2015\"\n  published_at: \"2016-01-26\"\n  date: \"2015-09-26\"\n  description: |-\n    Долгое время мы думали, что мы другие. Что подход Rails настолько крут, что у нас нет целого класса проблем, с которыми возятся несчастные джависты.Но почему-то Rails-приложения с завидной регулярностью превращаются в неподдерживаемых монстров через полгода, а то и меньше. Выходит что мы не очень-то мы и другие :\\Я поделюсь опытом переключения мозга из режима Rails-only-mode.\n\n    Как только перестаешь принимать на веру дефолтный способ организации кода в Rails, происходят замечательные вещи. В моем случае, новые роли объектов(Form objects, Services, Repositories) появились в коде естественным образом - как решения конкретных проблем, а не потому-что так завещал нам Мартин Фаулер. В итоге я получил гибкий(модульный, если хотите) код, который несложно поддерживать и модифицировать.\n\n    Коллеги, хватит перекладывать вину за бардак в коде на DHH! 2015 год - отличное время, чтобы стать кем-то большим, чем программист-на-фрэймворке.\n  video_provider: \"youtube\"\n  video_id: \"0v-24qM6LNI\"\n  language: \"Russian\"\n"
  },
  {
    "path": "data/railsclub/railsclub-2016/event.yml",
    "content": "---\nid: \"railsclub-2016\"\ntitle: \"RailsClub 2016\"\ndescription: \"\"\nlocation: \"Moscow, Russia\"\nkind: \"conference\"\nstart_date: \"2016-10-22\"\nend_date: \"2016-10-22\"\nwebsite: \"https://rubyrussia.club/\"\ntwitter: \"railsclub_ru\"\nplaylist: \"https://www.youtube.com/playlist?list=PLiWUIs1hSNeOXZhotgDX7Y7qBsr24cu7o\"\ncoordinates:\n  latitude: 55.7568721\n  longitude: 37.6150527\n"
  },
  {
    "path": "data/railsclub/railsclub-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyrussia.club/\n# Videos: https://www.youtube.com/playlist?list=PLiWUIs1hSNeOXZhotgDX7Y7qBsr24cu7o\n---\n[]\n"
  },
  {
    "path": "data/railsclub/railsclub-2017/event.yml",
    "content": "---\nid: \"railsclub-2017\"\ntitle: \"RailsClub 2017\"\ndescription: \"\"\nlocation: \"Moscow, Russia\"\nkind: \"conference\"\nstart_date: \"2017-09-23\"\nend_date: \"2017-09-23\"\nwebsite: \"https://rubyrussia.club/\"\ntwitter: \"railsclub_ru\"\nplaylist: \"https://www.youtube.com/playlist?list=PLiWUIs1hSNeMBqHPF7HcO6O2WBjzfiUQw\"\ncoordinates:\n  latitude: 55.7568721\n  longitude: 37.6150527\n"
  },
  {
    "path": "data/railsclub/railsclub-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyrussia.club/\n# Videos: https://www.youtube.com/playlist?list=PLiWUIs1hSNeMBqHPF7HcO6O2WBjzfiUQw\n---\n[]\n"
  },
  {
    "path": "data/railsclub/series.yml",
    "content": "---\nname: \"RailsClub\"\nwebsite: \"https://rubyrussia.club\"\ntwitter: \"railsclub_ru\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2006/event.yml",
    "content": "---\nid: \"railsconf-2006\"\ntitle: \"RailsConf 2006\"\nkind: \"conference\"\nlocation: \"Chicago, IL, United States\"\ndescription: \"\"\nstart_date: \"2006-06-22\"\nend_date: \"2006-06-25\"\nyear: 2006\nwebsite: \"https://railsconf.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F4554E\"\ncoordinates:\n  latitude: 41.88325\n  longitude: -87.6323879\n"
  },
  {
    "path": "data/railsconf/railsconf-2006/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/railsconf/railsconf-2007/event.yml",
    "content": "# https://www.flickr.com/photos/x180/albums/72157600225783815\n---\nid: \"railsconf-2007\"\ntitle: \"RailsConf 2007\"\nkind: \"conference\"\nlocation: \"Portland, OR, United States\"\ndescription: \"\"\nstart_date: \"2007-05-17\"\nend_date: \"2007-05-20\"\nyear: 2007\nwebsite: \"https://railsconf.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F4554E\"\ncoordinates:\n  latitude: 45.515232\n  longitude: -122.6783853\n"
  },
  {
    "path": "data/railsconf/railsconf-2007/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://www.flickr.com/photos/x180/albums/72157600225783815\n---\n[]\n"
  },
  {
    "path": "data/railsconf/railsconf-2008/event.yml",
    "content": "# https://www.flickr.com/photos/x180/albums/72157605325511779/with/2535145405\n---\nid: \"railsconf-2008\"\ntitle: \"RailsConf 2008\"\nkind: \"conference\"\nlocation: \"Portland, OR, United States\"\ndescription: \"\"\nstart_date: \"2008-05-29\"\nend_date: \"2008-06-01\"\nyear: 2008\nwebsite: \"https://railsconf.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F4554E\"\ncoordinates:\n  latitude: 45.515232\n  longitude: -122.6783853\n"
  },
  {
    "path": "data/railsconf/railsconf-2008/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://www.flickr.com/photos/x180/albums/72157605325511779\n---\n[]\n"
  },
  {
    "path": "data/railsconf/railsconf-2009/event.yml",
    "content": "# https://www.flickr.com/photos/x180/albums/72157617654734959\n---\nid: \"railsconf-2009\"\ntitle: \"RailsConf 2009\"\nkind: \"conference\"\nlocation: \"Las Vegas, NV, United States\"\ndescription: \"\"\nstart_date: \"2009-05-04\"\nend_date: \"2009-05-07\"\nyear: 2009\nwebsite: \"https://railsconf.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F4554E\"\ncoordinates:\n  latitude: 36.171563\n  longitude: -115.1391009\n"
  },
  {
    "path": "data/railsconf/railsconf-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://www.flickr.com/photos/x180/sets/72157617654734959/\n---\n[]\n"
  },
  {
    "path": "data/railsconf/railsconf-2010/event.yml",
    "content": "---\nid: \"PL393ECE649BB3813D\"\ntitle: \"RailsConf 2010\"\nkind: \"conference\"\nlocation: \"Baltimore, MD, United States\"\ndescription: |-\n  RailsConf is the largest official event for the Ruby on Rails community. If you're passionate about Rails and what it helps you achieve—or are curious about how Rails can help you create web applications better and faster—RailsConf is the place to be.\npublished_at: \"2010-06-10\"\nchannel_id: \"UC3BGlwmI-Vk6PWyMt15dKGw\"\nyear: 2010\nstart_date: \"2010-06-07\"\nend_date: \"2010-06-10\"\nbanner_background: \"#91181C\"\nfeatured_background: \"#91181C\"\nfeatured_color: \"#DC9771\"\nwebsite: \"https://web.archive.org/web/20100809223242/http://en.oreilly.com/rails2010\"\ncoordinates:\n  latitude: 39.2905023\n  longitude: -76.6104072\n"
  },
  {
    "path": "data/railsconf/railsconf-2010/videos.yml",
    "content": "# https://www.flickr.com/photos/paulmartincampbell/albums/72157624466013836/\n# https://www.flickr.com/photos/jetbrains/albums/72157624156660223/\n---\n- id: \"chad-fowler-railsconf-2010\"\n  title: \"Welcome and Announcements\"\n  speakers:\n    - Chad Fowler\n    - Ben Scofield\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\"\n  video_id: \"JwYD3vzxfDU\"\n  published_at: \"2010-06-09\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/JwYD3vzxfDU/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/JwYD3vzxfDU/default.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/JwYD3vzxfDU/mqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/JwYD3vzxfDU/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/JwYD3vzxfDU/hqdefault.jpg\"\n  video_provider: \"youtube\"\n  description: |-\n    Welcome and announcements by Chad Fowler and Ben Scofield.\n\n- id: \"chad-fowler-railsconf-2010-welcome-and-announcements\"\n  title: \"Welcome and Announcements\"\n  speakers:\n    - Chad Fowler\n    - Ben Scofield\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-08\"\n  video_id: \"yaIWUJazJYU\"\n  published_at: \"2010-06-10\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/yaIWUJazJYU/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/yaIWUJazJYU/default.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/yaIWUJazJYU/mqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/yaIWUJazJYU/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/yaIWUJazJYU/hqdefault.jpg\"\n  description: |-\n    Welcome and announcements by Chad Fowler and Ben Scofield.\n\n- id: \"elise-huard-railsconf-2010\"\n  title: \"12 Hours to Rate a Rails Application\"\n  speakers:\n    - Elise Huard\n  event_name: \"RailsConf 2010\"\n  video_id: \"elise-huard-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  date: \"2010-06-07\" # TODO: check date\n  description: |-\n    We've all found ourselves in situations where we had to evaluate very quickly what the quality was of a Rails codebase.  In some cases it's to evaluate an acquisition, in other cases to put an estimate on maintenance and evolution of an existing application.\n    My talk will describe how to smell out,in one day, hour by hour, whether there are any pain points,and where they are.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/12%20Hours%20to%20Rate%20a%20Rails%20Application%20Presentation.pdf\"\n  additional_resources:\n    - name: \"Summary Write-Up\"\n      title: \"RailsConf 2010 Rate a Rails Application: Day One, Session One\"\n      type: \"write-up\"\n      url: \"https://www.endpointdev.com/blog/2010/06/railsconf-2010-review-rails-application/\"\n\n- id: \"david-chelimsky-aslak-hellesoy-railsconf-2010\"\n  title: \"Acceptance Testing with Cucumber\"\n  speakers:\n    - David Chelimsky\n    - Aslak Hellesøy\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"david-chelimsky-aslak-hellesoy-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Cucumber is all the rage these days, but many developers struggle to\n    understand how and when to use it. It is designed to be an Acceptance\n    Testing tool in the context of BDD, but that explanation tends to\n    bring up even more questions.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Acceptance%20Testing%20with%20Cucumber%20Presentation.pdf\"\n\n- id: \"ian-mcfarland-railsconf-2010\"\n  title: \"Agile the Pivotal Way\"\n  speakers:\n    - Ian McFarland\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"ian-mcfarland-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    In this presentation we'll share our insights into how to develop agile, robust, industrial strength code reliably and repeatably, through the application of our own flavor of XP-style agile development. We've been doing Agile for over 10 years, and Rails for over 4. We've delivered over 80 Rails apps to customers, and have learned a thing or two about how to do that sustainably and well.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.pivotallabs.com/talks/Agile%20the%20Pivotal%20Way.pdf\"\n\n- id: \"blythe-dunham-railsconf-2010\"\n  title: \"Analyze This!\"\n  speakers:\n    - Blythe Dunham\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"blythe-dunham-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Web site metrics are a must have as they provide valuable business insight. This discussion describes how to best leverage 3rd party tools such as google, and when, how, and what to track within your own rails application.\n\n    2 large rails implementations are presented as case studies:\n    * Tracking over 2.5 mil hits/hr via nginx logs\n    * Leveraging Mongodb in the clouds to store iphone request info\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Analyze%20This_%20Presentation.pdf\"\n\n- id: \"sarah-mei-railsconf-2010\"\n  title: \"Beyond (No)SQL\"\n  speakers:\n    - Sarah Mei\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"sarah-mei-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    SQL databases are awesome at certain problems. But most Rails apps encounter data challenges that make traditional databases look seriously puny. So...is SQL over? In this talk, we'll dig into the guts of the relational model, look at the problems SQL doesn't solve well, and - crucially - understand why. Then we'll answer the million-dollar question: is NoSQL the only alternative?\n  slides_url: \"https://web.archive.org/web/20100721132621/http://\"\n\n- id: \"adam-blum-railsconf-2010\"\n  title: \"Building Native Mobile Apps with Rhodes\"\n  speakers:\n    - Adam Blum\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"adam-blum-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    In this session, attendees will learn how to build native applications for all leading smartphones using Rhodes, the only Ruby-based smartphone app framework.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Building%20Native%20Mobile%20Apps%20with%20Rhodes%20Presentation.ppt\"\n\n- id: \"andre-arko-railsconf-2010\"\n  title: \"Bundler: Painless Dependency Management\"\n  speakers:\n    - André Arko\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"andre-arko-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Why Bundler exists, what it can do, and how to manage your project's dependencies with it, whether your project is a pure ruby library, a tiny Sinatra app, or a giant Rails app.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Bundler_%20Painless%20Dependency%20Management%20Presentation.pdf\"\n\n- id: \"jesse-newland-railsconf-2010\"\n  title: \"Continuous (Production) Integration: Ruby on Rails Application Monitoring with Cucumber\"\n  speakers:\n    - Jesse Newland\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"jesse-newland-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    In order to ensure continuous application availability without dealing with antiquated monitoring tools a Rails developer should be able to assert the correct behavior of a production application from the outside in using familiar tools to protect revenue.\n  slides_url: \"\"\n\n- id: \"neal-ford-railsconf-2010\"\n  title: \"Creativity & Constraint\"\n  speakers:\n    - Neal Ford\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"neal-ford-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Most people think that freedom engenders creativity, but the opposite is true. But too much constraint makes it hard to get stuff done. It turns out that you need just enough constraint, and figuring out what gives you that perfect level is harder than you think. This keynote investigates the relationship between creativity and constraint as it applies to software development in the modern world.\n  slides_url: \"\"\n\n- id: \"john-athayde-railsconf-2010\"\n  title: \"Curing DIV-itis with Semantic HTML, CSS and Presenters\"\n  speakers:\n    - John Athayde\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"john-athayde-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Views are still the wild west of the web application area. A sea of DIV after DIV with tables tossed in for non-tabular data creates a sea of messy code that hurts the product both in performance and bandwidth. We'll look at the common pitfalls of view code, how to refactor that code into lean, semantic HTML, CSS and presnters that is not only pretty, but also correct and proper.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Curing%20DIV-itis%20with%20Semantic%20HTML,%20CSS%20and%20Presenters%20Presentation%201.zip\"\n\n- id: \"dirkjan-bussink-railsconf-2010\"\n  title: \"DataMapper 1.0\"\n  speakers:\n    - Dirkjan Bussink\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"dirkjan-bussink-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    We would like to announce DataMapper 1.0 here at Railsconf 2010. DataMapper 1.0 marks an important release that has seen a lot of development over the last two years. DataMapper is storage engine agnostic and also allows for mixing for example SQL and No-SQL engines, using the best tools for the job.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/DataMapper%201_0%20Presentation.pdf\"\n\n- id: \"david-heinemeier-hansson-railsconf-2010\"\n  title: \"Keynote: Rails 3.0 - the selfish bastard rundown\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"b0iKYRKtAsA\"\n  published_at: \"2010-06-09\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/b0iKYRKtAsA/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/b0iKYRKtAsA/default.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/b0iKYRKtAsA/mqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/b0iKYRKtAsA/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/b0iKYRKtAsA/hqdefault.jpg\"\n  description: |-\n    Keynote by David Heinemeier Hansson, 37signals.\n  slides_url: \"\"\n\n- id: \"derek-sivers-railsconf-2010\"\n  title: \"Derek Sivers\"\n  speakers:\n    - Derek Sivers\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"derek-sivers-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Keynote by Derek Sivers, founder of CD Baby.\n  slides_url: \"\"\n\n- id: \"pat-maddox-railsconf-2010\"\n  title: \"Domain-Driven Rails Redux\"\n  speakers:\n    - Pat Maddox\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"pat-maddox-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Over the last 5 years, Rails apps have increased in size, complexity, and value provided to businesses.  A few years back all we had to do was customize some generated code and sprinkle on a bit of AJAX, and the rapid pace of development meant that we could launch products and add features way faster than our competitors could.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Domain-Driven%20Rails%20Redux%20Presentation.pdf\"\n\n- id: \"john-nunemaker-railsconf-2010\"\n  title: \"Don't Repeat Yourself, Repeat Others\"\n  speakers:\n    - John Nunemaker\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"john-nunemaker-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    \"Don't repeat yourself.\" \"Don't reinvent the wheel.\" Phrases like this are thrown around like crazy in the programming world, but one is missing. Repeat others. The best way to learn is to imitate those that are better than us.\n  slides_url: \"https://speakerdeck.com/jnunemaker/dont-repeat-yourself-repeat-others\"\n\n- id: \"evan-phoenix-railsconf-2010\"\n  title: \"Engine Yard's Open Source Love Affair\"\n  speakers:\n    - Evan Phoenix\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"tmsCxaaK92o\"\n  published_at: \"2010-06-10\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/tmsCxaaK92o/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/tmsCxaaK92o/default.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/tmsCxaaK92o/mqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/tmsCxaaK92o/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/tmsCxaaK92o/hqdefault.jpg\"\n  description: |-\n    Engine Yard was founded to help deploy, manage and scale Ruby and Rails applications. We built our company with a focus on supporting and cultivating the Ruby and Rails community and ecosystem. Join us as we walk through some open source work we've dedicated our time to, including Rails, Ruby, Rubinius and JRuby.  We'll also discuss community efforts we're excited to be involved with.\n  slides_url: \"\"\n\n- id: \"paul-campbell-railsconf-2010\"\n  title: \"From 'Rails' to 'Release'\"\n  speakers:\n    - Paul Campbell\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"paul-campbell-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    In this session I'll share my experience, tips and tricks I've learned, and stories I've come across while building Rails apps for clients and myself.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/From%20_Rails_%20to%20_Release_%20Presentation.pdf\"\n\n- id: \"jonathan-palley-lei-guo-railsconf-2010\"\n  title: \"From 1 to 30: How to Refactor 1 Monolithic Application into 30 Independently Maintainable Applications\"\n  speakers:\n    - Jonathan Palley\n    - Lei Guo\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"jonathan-palley-lei-guo-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    This talk shares the experience, process and best practices of splitting a single monolithic rails application into many smaller independently-developable but integrated system of applications.  The result is lower development time, greater stability and scalability and higher developer productivity.\n  slides_url:\n    \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/From%201%20to%2030_%20How%20to%20Refactor%201%20Monolithic%20Application%20into%203\\\n    0%20Independently%20Maintainable%20Applications%20Presentation.pdf\"\n\n- id: \"aman-gupta-joe-damato-railsconf-2010\"\n  title: \"Garbage Collection and the Ruby Heap\"\n  speakers:\n    - Aman Gupta\n    - Joe Damato\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"aman-gupta-joe-damato-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Everything in Ruby is an object.. but what is a ruby object? What does it look like? Where does it live? How is it born and when does it die?\n\n    This talk will cover the implementation of the object heap and garbage collector in Ruby 1.8, with a focus on tools and techniques to understand memory usage, find reference leaks, and improve the performance of your ruby applications.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Garbage%20Collection%20and%20the%20Ruby%20Heap%20Presentation.pdf\"\n\n- id: \"gary-vaynerchuk-railsconf-2010\"\n  title: \"Keynote\"\n  speakers:\n    - Gary Vaynerchuk\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"-QWHkcCP3tA\"\n  published_at: \"2010-06-11\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/-QWHkcCP3tA/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/-QWHkcCP3tA/default.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/-QWHkcCP3tA/mqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/-QWHkcCP3tA/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/-QWHkcCP3tA/hqdefault.jpg\"\n  description: |-\n    Gary Vaynerchuk (VaynerMedia; Wine Library TV) delivers the keynote address at the Baltimore RailsConf on June 10th, 2010.\n  slides_url: \"\"\n\n- id: \"marty-haught-railsconf-2010\"\n  title: \"Get Lean: Slimming Down with Rails\"\n  speakers:\n    - Marty Haught\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"marty-haught-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Many tenets of agile development have been present in the Rails\n    ecosystem from the beginning. There has been a evolution of practices\n    stemming from Lean principles in the software world, especially in the\n    realm of startups. This tutorial will focus on these techniques and\n    approaches and how they can be applied to the Rails stack to make your\n    development more focused and efficient.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Get%20Lean_%20Slimming%20Down%20with%20Rails%20Presentation.pdf\"\n\n- id: \"jim-weirich-railsconf-2010\"\n  title: \"Git Immersion\"\n  speakers:\n    - Jim Weirich\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"jim-weirich-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Git is a wonderful distributed source control tool with a reputation for being hard to learn. This workshop will sidestep the hard to learn reputation by explaining git in an easy to learn, bottom-up approach; and then reinforcing that lesson by immersing the attendee into a number of practical hands-on applications of git.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Git%20Immersion%20Presentation.pdf\"\n\n- id: \"michael-koziarski-railsconf-2010\"\n  title: \"Introduction to Cassandra and CassandraObject\"\n  speakers:\n    - Michael Koziarski\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"michael-koziarski-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    This talk will provide you with an overview of cassandra itself and cover the\n    differences between ActiveRecord and CassandraObject. It'll also\n    provide some lessons learned from working with ActiveModel for people\n    who are interested in creating their own custom object mappers.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Introduction%20to%20Cassandra%20and%20CassandraObject%20Presentation.pdf\"\n\n- id: \"mikel-lindsaar-railsconf-2010\"\n  title: \"Itch Scratching the ActionMailer API\"\n  speakers:\n    - Mikel Lindsaar\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"mikel-lindsaar-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Itch scratching is at the core of any hacker.\n\n    But how does it apply in the real world?  This talk goes over the steps I took from scratching an itch by patching the TMail library, taking over maintenance of it, upgrading ActionMailer 2.x, writing the Mail library and then finally helping rewrite the ActionMailer API for Rails 3.0\n\n    I'll go over the tools I used, and how it all worked.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Itch%20Scratching%20the%20ActionMailer%20API%20Presentation.pdf\"\n\n- id: \"nick-quaranto-railsconf-2010\"\n  title: \"Lapidary: the Art of Gemcutting\"\n  speakers:\n    - Nick Quaranto\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"nick-quaranto-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Learn why Gemcutter won the great RubyGem hosting battle of 2009 and about the challenges the site faces in 2010 and beyond. Discover how instant code deployment with Gemcutter is changing the way not only Rubyists develop and release software, but other open source communities as well.\n  slides_url: \"\"\n\n- id: \"jess-martin-railsconf-2010\"\n  title: \"Learn to Speak Interface: Creating Conversations Between Developers and Designers\"\n  speakers:\n    - Jess Martin\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"jess-martin-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    You're a developer. You write code. But your users don't see your\n    code. They only see the user interface. We're going to have a\n    conversation about how to think through your product's user interface.\n    We'll focus on a few analytical techniques you can use to analyze your\n    user interface and to communicate with a designer.\n  slides_url:\n    \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Learn%20to%20Speak%20Interface_%20Creating%20Conversations%20Between%20Developers%2\\\n    0and%20Designers%20Presentation.pdf\"\n\n- id: \"fabio-akita-railsconf-2010\"\n  title: \"Making Rails really RESTful with Restfulie\"\n  speakers:\n    - Fabio Akita\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"fabio-akita-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Mapping CRUD operations to friendly URLs is hardly the end of the story around Restful. We came a long way since Roy Fielding seminal dissertation on REST. Inspired by Jim Webber, Savas Parastatidis and Ian Robinson upcoming book on REST, Hypermedia and HATEOAS (Hypermedia as the Engine of Application State), we came down to the \"Restfulie\" gem.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Making%20Rails%20really%20RESTful%20with%20Restfulie%20Presentation.pdf\"\n\n- id: \"michael-feathers-railsconf-2010\"\n  title: \"Keynote\"\n  speakers:\n    - Michael Feathers\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"L9ccnRixyMg\"\n  published_at: \"2015-01-05\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/L9ccnRixyMg/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/L9ccnRixyMg/default.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/L9ccnRixyMg/mqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/L9ccnRixyMg/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/L9ccnRixyMg/hqdefault.jpg\"\n  description: |-\n    Keynote by Michael Feathers, Object Mentor.\n  slides_url: \"\"\n\n- id: \"ilya-grigorik-dan-sinclair-railsconf-2010\"\n  title: \"No Callbacks, No Threads: Async & Cooperative Web Servers with Ruby 1.9\"\n  speakers:\n    - Ilya Grigorik\n    - Dan Sinclair\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"ilya-grigorik-dan-sinclair-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    No threads, no callbacks, just pure IO scheduling with Ruby 1.9, Fibers, and Eventmachine. All the nice things we love about writing synchronous code, but completely asynchronous under the covers – the best of both worlds. A hands on look at the architecture, mechanics, and involved libraries towards creating the next generation Ruby web-servers.\n  slides_url:\n    \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/No%20Callbacks,%20No%20Threads_%20Async%20_%20Cooperative%20Web%20Servers%20with%20\\\n    Ruby%201_9%20Presentation.pdf\"\n\n- id: \"flip-sass-railsconf-2010\"\n  title: \"Persistence Smoothie: Blending SQL and NoSQL in Rails Applications\"\n  speakers:\n    - Flip Sasser\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"flip-sass-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    With such a vibrant and emerging economy of new persistence options for web applications it can be diffcult to know when and how to use them in your applications. Worse yet, you don't want to lose mountains of existing infrastructure and support for RDBMS systems in Rails. What's a developer to do? Blend it! Learn new techniques for using multiple persistence engines in a single application.\n  slides_url:\n    \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Persistence%20Smoothie_%20Blending%20SQL%20and%20NoSQL%20in%20Rails%20Applications%\\\n    20Presentation%201\"\n\n- id: \"jeremy-mcanally-railsconf-2010\"\n  title: \"Rails 3 Deep Dive\"\n  speakers:\n    - Jeremy McAnally\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"jeremy-mcanally-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    This workshop will tour through a number of advanced, in-depth topics on Rails 3. We'll look take a tour of many of the new additions to Rails 3, talk about how to exploit Rails' new focus on Rack to your advantage, dig around in the source to really understand how many of the pieces work, and take a look at how to bring some common, advanced patterns used in Rails 2.x into the world of Rails 3.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Rails%203%20Deep%20Dive%20Presentation.pdf\"\n\n- id: \"adam-keys-railsconf-2010\"\n  title: \"Rails' Next Top Model: Using ActiveModel and ActiveRelation\"\n  speakers:\n    - Adam Keys\n  event_name: \"RailsConf 2010\"\n  video_id: \"adam-keys-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  date: \"2010-06-07\" # TODO: check date\n  description: |-\n    ActiveRelation and ActiveModel bring a lot of interesting features to\n    Rails 3. These new libraries make it easier to write complex queries\n    and to extend Rails to work with non-ActiveRecord objects. Learn to\n    use ActiveRelation and ActiveModel to clean up your code. See how you\n    can use ARel and AMo to build your own data layer or to connect to new\n    datastores.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Rails_%20Next%20Top%20Model_%20Using%20ActiveModel%20and%20ActiveRelation%20Presentation.pdf\"\n\n- id: \"glenn-vanderburg-railsconf-2010\"\n  title: \"Real Software Engineering\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"RailsConf 2010\"\n  video_id: \"glenn-vanderburg-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  date: \"2010-06-07\" # TODO: check date\n  description: |-\n    Software engineering as it's taught in universities simply doesn't work.  It doesn't\n    produce software systems of high quality, and it doesn't produce them for low cost.\n    Sometimes, even when practiced rigorously, it doesn't produce systems at all.\n\n    That's odd, because in every other field, the term \"engineering\" is reserved for\n    methods that work.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Real%20Software%20Engineering%20Presentation.pdf\"\n\n- id: \"joseph-wilk-railsconf-2010\"\n  title: \"Rocket Fueled Cucumbers\"\n  speakers:\n    - Joseph Wilk\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"joseph-wilk-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Tools like Cucumber encourage driving new pieces of functionality through tests which cut through the entire Rails web stack, including the database. As a consequence these Acceptance tests can be quite slow. This leaves us in a dichotomy, you want to keep adding new features to your product and you want to maintain rapid test feedback. Somethings got to give. So how do we scale Acceptance tests?\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Rocket%20Fueled%20Cucumbers%20Presentation%201.pdf\"\n\n- id: \"aaron-patterson-railsconf-2010\"\n  title: \"Ruby on Rails: Tasty Burgers\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-08\"\n  video_id: \"aaron-patterson-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    We all know that Rails is made of Tasty Burgers, but what are those Tasty\n    Burgers made from? We're going to take a look inside the bun to discover\n    what makes up Rails, how the software gets to our plate, and how we can\n    improve it. We'll discuss some of the lower level libraries used to make up\n    Rails, and what makes them tick. Better Ingredients, Better Burgers.\n    Guaranteed.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Ruby%20on%20Rails_%20Tasty%20Burgers%20Presentation.pdf\"\n\n- id: \"wayne-seguin-railsconf-2010\"\n  title: \"Ruby Version Manager (rvm) - An Overview\"\n  speakers:\n    - Wayne E. Seguin\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"wayne-seguin-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    RVM is a command line tool which allows us to easily work with multiple ruby interpreters and sets of gems. We will explore the use of rvm to manage rubies for development needs like coding, continuous integration, quality assurance, and production on a per project basis.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Ruby%20Version%20Manager%20_rvm_%20-%20An%20Overview%20Presentation.pdf\"\n\n- id: \"ryan-brown-david-masover-john-woodell-railsconf-2010\"\n  title: \"Scaling Rails on App Engine with JRuby and Duby\"\n  speakers:\n    - Ryan Brown\n    - David Masover\n    - John Woodell\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"ryan-brown-david-masover-john-woodell-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    More and more Rails apps are being deployed to App Engine. Generated AR scaffolding works unaltered with DataMapper, and critical gems like redcloth and mechanize are working too. Spin-up time is less of an issue, and Duby has matured to provide unprecedented performance. Our latest development tools make the development process painless. Best of all, it's free to get started.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Scaling%20Rails%20on%20App%20Engine%20with%20JRuby%20and%20Duby%20Presentation.pdf\"\n\n- id: \"kyle-banker-railsconf-2010\"\n  title: \"The MongoDB Metamorphosis: Thinking about Data as Documents\"\n  speakers:\n    - Kyle Banker\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"kyle-banker-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    We'd mastered it all: join tables, polymorphic associations, nested sets, all neatly normalized. Then we awoke to the haze of NoSQL, where the data-modeling rules had changed. This presentation attempts to correct that by exploring document-oriented modeling with MongoDB. We'll cover common design patterns and contrast strategies for modeling product data in an RDBMS and a document store.\n  slides_url:\n    \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/The%20MongoDB%20Metamorphosis_%20Thinking%20about%20Data%20as%20Documents%20%20Pres\\\n    entation.pdf\"\n\n- id: \"michael-bleigh-railsconf-2010\"\n  title: \"The Present Future of OAuth\"\n  speakers:\n    - Michael Bleigh\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"michael-bleigh-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    If you're building a RESTful API for your application you need to know about the latest standards in open authentication. With a new, modular approach and providing much greater flexibility than ever, the OAuth standard has evolved into a mature, open, and intelligent way to provide access to your application. Learn what it is, how to use it, and how to implement it on your application today!\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/The%20Present%20Future%20of%20OAuth%20Presentation.pdf\"\n\n- id: \"gregg-pollack-nathaniel-bibler-thomas-meeks-jacob-swanner-railsconf-2010\"\n  title: \"The Rails 3 Ropes Course\"\n  speakers:\n    - Gregg Pollack\n    - Nathaniel Bibler\n    - Thomas Meeks\n    - Jacob Swanner\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"gregg-pollack-nathaniel-bibler-thomas-meeks-jacob-swanner-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    For this ropes course, members of the Envy Labs team will march you through the core concepts of Rails 3 while taking you through the development of a new Rails application. At the end of this course you will come away with a better understanding what's new in Rails 3, and equally as important, what has changed since Rails 2.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/The%20Rails%203%20Ropes%20Course%20Presentation.pdf\"\n\n- id: \"robert-martin-railsconf-2010\"\n  title: \"Twenty-Five Zeros\"\n  speakers:\n    - Robert Martin\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"mslMLp5bQD0\"\n  published_at: \"2010-06-12\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/mslMLp5bQD0/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/mslMLp5bQD0/default.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/mslMLp5bQD0/mqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/mslMLp5bQD0/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/mslMLp5bQD0/hqdefault.jpg\"\n  description: |-\n    Up till now, computer hardware technology has been advancing by orders of magnitude every year; has software technology been keeping up?  Now that headlong advance of hardware shows signs of slowing.  Moore's law may be dead.  Does that mean that software technology will have to pick up the slack?  Can it?  Is Ruby/Rails a hint of the future solution?  If not, what is?\n  slides_url: \"\"\n\n- id: \"tony-pitale-railsconf-2010\"\n  title: \"User Behavior Tracking with Google Analytics, Garb, and Vanity\"\n  speakers:\n    - Tony Pitale\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"tony-pitale-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    User behavior tracking can be difficult. If done properly, it can be invaluable in helping to shape the evolution of your product. Done poorly, and it can lead to expensive mistakes. Learn the tools and techniques that will help you make the right choices.\n  slides_url: \"\"\n\n- id: \"alberto-morales-railsconf-2010\"\n  title: \"Using Rails - A CIO's Perspective\"\n  speakers:\n    - Alberto Morales\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"alberto-morales-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    In today's challenging economic environment, being nimble is key. Enterprises large and small are busy adapting their business models to match the environment. More and more, IT is being asked to help with this transformation. Fortunately, over the past few years, movements like open source, social networking and virtualization have given IT powerful tools to help with the transformation.\n  slides_url: \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/Using%20Rails%20-%20A%20CIO_s%20Perspective%20Presentation.pdf\"\n\n- id: \"brian-doll-railsconf-2010\"\n  title: \"What Should We Work On Next? Tuning Apps Without Getting Bogged Down in Maintenance\"\n  speakers:\n    - Brian Doll\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"brian-doll-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    If you lead or work on a development team, you know that applications need to be tuned and tweaked continuously or their performance degrades. Changing load, new features, growing databases, all contribute to application slowing. Learn how to prioritize the work for your team so you're making improvements that make a difference.\n  slides_url:\n    \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/What%20Should%20We%20Work%20On%20Next_%20Tuning%20Apps%20Without%20Getting%20Bogged\\\n    %20Down%20in%20Maintenance%20Presentation.pdf\"\n\n- id: \"benjamin-orenstein-railsconf-2010\"\n  title: \"Write Code Faster: Expert-level vim\"\n  speakers:\n    - Benjamin Orenstein\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"benjamin-orenstein-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    You will write code faster after this talk!  Learn how to create and edit Rails code at maximum speed using the vim editor.  Jump from intermediate to expert with my battle-tested techniques.\n  slides_url: \"\"\n\n- id: \"yehuda-katz-railsconf-2010\"\n  title: \"Keynote: The Ruby Community\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"mo-lMdQMsdw\"\n  published_at: \"2010-06-12\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/mo-lMdQMsdw/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/mo-lMdQMsdw/default.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/mo-lMdQMsdw/mqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/mo-lMdQMsdw/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/mo-lMdQMsdw/hqdefault.jpg\"\n  description: |-\n    Keynote by Yehuda Katz, Engine Yard Inc.\n  slides_url: \"\"\n\n- id: \"matthew-deiters-railsconf-2010\"\n  title: \"You May Also Be Interested in: Implementing User Recommendations in Rails\"\n  speakers:\n    - Matthew Deiters\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"matthew-deiters-railsconf-2010\"\n  video_provider: \"not_recorded\"\n  description: |-\n    From friend suggestions in Facebook to product recommendations on Amazon the industry is moving to more intelligent systems. We'll discuss how to discover the relationships in your app and start personalizing the experience of your users. We'll discuss different design approaches to recommendations and how to leverage various libraries in novel ways in your rails application.\n  slides_url:\n    \"https://web.archive.org/web/20100721132621/http://assets.en.oreilly.com/1/event/40/You%20May%20Also%20Be%20Interested%20in_%20Implementing%20User%20Recommendations%20\\\n    in%20Rails%20Presentation.pdf\"\n\n- id: \"gregg-pollack-railsconf-2010\"\n  title: \"Ruby Heroes Awards Ceremony 2010\"\n  speakers:\n    - Gregg Pollack\n    - Nathaniel Bibler\n    - José Valim\n    - Nick Quaranto\n    - Xavier Noria\n    - Aaron Patterson\n    - Wayne Seguin\n    - Gregory Brown\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-07\" # TODO: check date\n  video_id: \"ffCxpBD-_Rs\"\n  published_at: \"2010-06-12\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/ffCxpBD-_Rs/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/ffCxpBD-_Rs/default.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/ffCxpBD-_Rs/mqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/ffCxpBD-_Rs/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/ffCxpBD-_Rs/hqdefault.jpg\"\n  description: |-\n    Ruby Heroes Awards Ceremony\n  slides_url: \"\"\n\n- id: \"chad-fowler-railsconf-2010-conference-ending\"\n  title: \"Conference Ending\"\n  speakers:\n    - Chad Fowler\n    - Ben Scofield\n  event_name: \"RailsConf 2010\"\n  date: \"2010-06-10\"\n  video_id: \"84O-6EOctvA\"\n  published_at: \"2010-06-12\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/84O-6EOctvA/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/84O-6EOctvA/default.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/84O-6EOctvA/mqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/84O-6EOctvA/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/84O-6EOctvA/hqdefault.jpg\"\n  video_provider: \"youtube\"\n  description: |-\n    Chad Fowler (InfoEther, Inc.) &\n    Ben Scofield (Viget Labs),\n    \"Welcome and Announcements\"\n  talks:\n    - title: \"Remembering why the lucky stiff\"\n      speakers:\n        - Glenn Vanderburg\n      start_cue: \"01:13\"\n      end_cue: \"03:32\"\n      thumbnail_cue: \"01:25\"\n      event_name: \"RailsConf 2010\"\n      date: \"2010-06-10\"\n      id: \"glenn-vanderburg-why-railsconf-2010\"\n      video_id: \"glenn-vanderburg-why-railsconf-2010\"\n      video_provider: \"parent\"\n      description: |-\n        https://whyday.org\n"
  },
  {
    "path": "data/railsconf/railsconf-2011/event.yml",
    "content": "---\nid: \"PL379EA9290474C86C\"\ntitle: \"RailsConf 2011\"\nkind: \"conference\"\nlocation: \"Baltimore, MD, United States\"\ndescription: |-\n  RailsConf 2011 was held in Baltimore, Maryland on May 16-19, 2011.\npublished_at: \"2011-05-16\"\nchannel_id: \"UC3BGlwmI-Vk6PWyMt15dKGw\"\nyear: 2011\nstart_date: \"2011-05-16\"\nend_date: \"2011-05-19\"\nbanner_background: \"#91181C\"\nfeatured_background: \"#91181C\"\nfeatured_color: \"#DC9771\"\nwebsite: \"https://web.archive.org/web/20110810144924/http://en.oreilly.com/rails2011\"\ncoordinates:\n  latitude: 39.2905023\n  longitude: -76.6104072\n"
  },
  {
    "path": "data/railsconf/railsconf-2011/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"david-heinemeier-hansson-railsconf-2011\"\n  title: \"Keynote: The Asset Pipeline and Our Postmodern Hybrid JavaScript Future\"\n  raw_title: \"RailsConf 2011, David Heinemeier Hansson\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"RailsConf 2011\"\n  date: \"2011-05-18\"\n  published_at: \"2011-05-18\"\n  description: |-\n    RailsConf 2011, David Heinemeier Hansson\n  video_provider: \"youtube\"\n  video_id: \"cGdCI2HhfAU\"\n\n- id: \"eric-ries-railsconf-2011\"\n  title: \"Lessons Learned\"\n  raw_title: 'RailsConf 2011: Eric Ries, \"Lessons Learned\"'\n  speakers:\n    - Eric Ries\n  event_name: \"RailsConf 2011\"\n  date: \"2011-05-18\"\n  published_at: \"2011-05-18\"\n  description: |-\n    RailsConf 2011: Eric Ries, \"Lessons Learned\"\n  video_provider: \"youtube\"\n  video_id: \"IVBVZGfzkVM\"\n\n- id: \"aaron-patterson-railsconf-2011\"\n  title: \"Double Dream Hands: So Intense!\"\n  raw_title: 'RailsConf 2011: Aaron Patterson, \"Double Dream Hands: So Intense!\"'\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2011\"\n  date: \"2011-05-18\"\n  published_at: \"2011-05-18\"\n  description: |-\n    RailsConf 2011: Aaron Patterson, \"Double Dream Hands: So Intense!\"\n  video_provider: \"youtube\"\n  video_id: \"kWOAHIpmLAI\"\n\n- id: \"gregg-pollack-railsconf-2011\"\n  title: \"Ruby Heroes Awards 2011\"\n  raw_title: \"RailsConf 2011: Ruby Heroes Awards\"\n  speakers:\n    - Gregg Pollack\n    - Nathaniel Bibler\n    - Darcy Laycock\n    - Jonas Nicklas\n    - Ryan Bigg\n    - Loren Segal\n    - Steve Klabnik\n    - Michael Hartl\n  event_name: \"RailsConf 2011\"\n  date: \"2011-05-18\"\n  published_at: \"2011-05-18\"\n  description: |-\n    RailsConf 2011: Ruby Heroes Awards\n  video_provider: \"youtube\"\n  video_id: \"EqZFMaN6Vx0\"\n\n- id: \"corey-haines-railsconf-2011\"\n  title: \"I'm Awesome - You're Awesome\"\n  raw_title: \"RailsConf 2011: Corey Haines\"\n  speakers:\n    - Corey Haines\n  event_name: \"RailsConf 2011\"\n  date: \"2011-05-19\"\n  published_at: \"2011-05-20\"\n  description: |-\n    RailsConf 2011: Corey Haines\n  video_provider: \"youtube\"\n  video_id: \"5OFxsarfSxI\"\n\n- id: \"dan-melton-railsconf-2011\"\n  title: \"Code for America\"\n  raw_title: 'RailsConf 2011: Dan Melton, \"Code for America\"'\n  speakers:\n    - Dan Melton\n  event_name: \"RailsConf 2011\"\n  date: \"2011-05-19\"\n  published_at: \"2011-05-20\"\n  description: |-\n    RailsConf 2011: Dan Melton, \"Code for America\"\n  video_provider: \"youtube\"\n  video_id: \"CrjUts20bsU\"\n\n- id: \"chad-dickerson-railsconf-2011\"\n  title: \"Etsy\"\n  raw_title: 'RailsConf 2011, Chad Dickerson, \"Etsy\"'\n  speakers:\n    - Chad Dickerson\n  event_name: \"RailsConf 2011\"\n  date: \"2011-05-20\"\n  published_at: \"2011-05-20\"\n  description: |-\n    RailsConf 2011, Chad Dickerson, \"Etsy\"\n  video_provider: \"youtube\"\n  video_id: \"22EECFEk9Xs\"\n\n- id: \"glenn-vanderburg-railsconf-2011\"\n  title: \"Craft, Engineering, and the Essence of Programming\"\n  raw_title: 'RailsConf 2011, Glenn Vanderburg, \"Craft, Engineering, and the Essence of Programming\"'\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"RailsConf 2011\"\n  date: \"2011-05-20\"\n  published_at: \"2011-05-20\"\n  description: |-\n    RailsConf 2011, Glenn Vanderburg, \"Craft, Engineering, and the Essence of Programming\"\n  video_provider: \"youtube\"\n  video_id: \"LlTiMUzLMgM\"\n\n- id: \"aaron-batalion-railsconf-2011\"\n  title: \"The LivingSocial Story\"\n  raw_title: 'RailsConf 2011, Aaron Batalion, \"The LivingSocial Story\"'\n  speakers:\n    - Aaron Batalion\n  event_name: \"RailsConf 2011\"\n  date: \"2011-05-20\"\n  published_at: \"2011-05-23\"\n  description: |-\n    RailsConf 2011, Aaron Batalion, \"The LivingSocial Story\"\n  video_provider: \"youtube\"\n  video_id: \"I-WLTQa4pGo\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2012/event.yml",
    "content": "---\nid: \"PLF16D2F3A8469021E\"\ntitle: \"RailsConf 2012\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription:\n  \"Rails Conf 2012 was held in Austin, Texas on April 23 - 25, 2012.\\r\n\n  \\r\n\n  It brought over 1200 developers from all of the world to discuss topics related to software development utilizing Ruby and the web framework Rails, as well as related and\n  surrounding technologies and practices.  The organizers had the event recorded by Confreaks and the presenters agreed to release the videos of the presentations under a Creative\n  Commons license.  If you enjoy these videos be sure and let the presenters and the folks at Ruby Central know.\"\npublished_at: \"2012-05-01\"\nstart_date: \"2012-04-23\"\nend_date: \"2012-04-25\"\nyear: 2012\nbanner_background: \"#8A1A17\"\nfeatured_background: \"#8A1A17\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/railsconf/railsconf-2012/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: schedule website\n\n# Website: https://web.archive.org/web/20140105002431/http://railsconf2012.com/\n# Reference: https://github.com/newhavenrb/conferences/wiki/RailsConf-2012\n\n- id: \"david-heinemeier-hansson-railsconf-2012\"\n  title: \"Keynote: Progress\"\n  raw_title: \"Rails Conf 2012 Keynote: Progress by David Heinemeier Hansson\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-05-01\"\n  description: |-\n    David Heinemeier Hansson is a partner at 37signals, a privately-held Chicago-based company committed to building the best web-based tools possible with the least number of features necessary.\n\n    37signals' products include Basecamp, Highrise, Backpack, Campfire, Ta-da List, and Writeboard. 37signals' products do less than the competition -- intentionally.\n\n    He is also the creator of Ruby on Rails.\n  video_provider: \"youtube\"\n  video_id: \"VOFTop3AMZ8\"\n\n- id: \"pedro-belo-railsconf-2012\"\n  title: \"Zero downtime deploys for Rails apps\"\n  raw_title: \"Zero downtime deploys for Rails apps\"\n  speakers:\n    - Pedro Belo\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-08-20\"\n  description: |-\n    What does it take to deploy an application without any downtime?\n\n    More than most Ruby developers would expect, turns out; what is aggravated by the lack of documentation and other resources on this topic.\n\n    In this talk we'll dive into both development practices (hot compatibility, database migrations, caching) and deployment setup (Heroku, Unicorn, HAProxy), covering everything you need to know in order to ship code without affecting a single customer.\n  video_provider: \"youtube\"\n  video_id: \"R6bVTthtnZ0\"\n\n- id: \"nathan-bibler-railsconf-2012\"\n  title: \"How to Find Valuable Gems\"\n  raw_title: \"How to Find Valuable Gems by Nathan Bibler\"\n  speakers:\n    - Nathan Bibler\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-08-14\"\n  description: |-\n    There's no need to reinvent the wheel. There are over 30,000 RubyGems available on just RubyGems.org, alone. But with so many out there, it must be impossible to find the right one, right? In this talk we'll learn about some resources which help you find the right gems, as well as how to intelligently decide if a library is right for your project.\n\n  video_provider: \"youtube\"\n  video_id: \"SbOmrlVG5Ik\"\n\n- id: \"lightning-talks-part-ii-railsconf-2012\"\n  title: \"Lightning Talks - Part II\"\n  raw_title: \"Lightning Talks - Part II\"\n  event_name: \"RailsConf 2012\"\n  date: \"2012-08-22\"\n  published_at: \"2012-08-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"KFO-hPBzzII\"\n  talks:\n    - title: \"Lightning Talk: Seven Tips for running an Open Source Project\"\n      date: \"2012-08-22\"\n      start_cue: \"00:25\"\n      end_cue: \"01:27\"\n      id: \"greg-belt-lighting-talk-railsconf-2012\"\n      video_id: \"greg-belt-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Greg Belt\n\n    - title: \"Lightning Talk: Integration testing engines\"\n      date: \"2012-08-22\"\n      start_cue: \"01:27\"\n      end_cue: \"04:55\"\n      id: \"ryan-biggs-lighting-talk-railsconf-2012\"\n      video_id: \"ryan-biggs-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Ryan Biggs\n\n    - title: \"Lightning Talk: Tokaido\"\n      date: \"2012-08-22\"\n      start_cue: \"04:55\"\n      end_cue: \"09:25\"\n      id: \"yehuda-katz-lighting-talk-railsconf-2012\"\n      video_id: \"yehuda-katz-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Yehuda Katz\n\n    - title: \"Lightning Talk: Seven reasons why you should help organizer your local user group\"\n      date: \"2012-08-22\"\n      start_cue: \"09:25\"\n      end_cue: \"14:20\"\n      id: \"ryan-brunner-lighting-talk-railsconf-2012\"\n      video_id: \"ryan-brunner-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Ryan Brunner\n\n    - title: \"Lightning Talk: Railcar\"\n      date: \"2012-08-22\"\n      start_cue: \"14:20\"\n      end_cue: \"16:27\"\n      id: \"mike-scalnik-lighting-talk-railsconf-2012\"\n      video_id: \"mike-scalnik-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Mike Scalnik\n\n    - title: \"Lightning Talk: Why you don't get hired\"\n      date: \"2012-08-22\"\n      start_cue: \"16:27\"\n      end_cue: \"20:53\"\n      id: \"felix-dominguez-lighting-talk-railsconf-2012\"\n      video_id: \"felix-dominguez-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Felix Dominguez\n\n    - title: \"Lightning Talk: Rails Encryption\"\n      date: \"2012-08-22\"\n      start_cue: \"20:53\"\n      end_cue: \"26:11\"\n      id: \"reid-morrison-lighting-talk-railsconf-2012\"\n      video_id: \"reid-morrison-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Reid Morrison\n\n    - title: \"Lightning Talk: Ninjascript\"\n      date: \"2012-08-22\"\n      start_cue: \"26:11\"\n      end_cue: \"27:00\"\n      id: \"evan-dorn-lighting-talk-railsconf-2012\"\n      video_id: \"evan-dorn-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Evan Dorn\n\n    - title: \"Lightning Talk: tddium\"\n      date: \"2012-08-22\"\n      start_cue: \"27:00\"\n      end_cue: \"31:44\"\n      id: \"jay-moorthi-lighting-talk-railsconf-2012\"\n      video_id: \"jay-moorthi-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Jay Moorthi\n\n    - title: \"Lightning Talk: How I saved the World with Ruby and Nokogiri\"\n      date: \"2012-08-22\"\n      start_cue: \"31:44\"\n      end_cue: \"34:15\"\n      id: \"rod-paddock-lighting-talk-railsconf-2012\"\n      video_id: \"rod-paddock-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Rod Paddock\n\n    - title: \"Lightning Talk: Wizards from WTF to Wicked\"\n      date: \"2012-08-22\"\n      start_cue: \"34:15\"\n      end_cue: \"36:42\"\n      id: \"richard-schneeman-lighting-talk-railsconf-2012\"\n      video_id: \"richard-schneeman-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Richard Schneeman\n\n    - title: \"Lightning Talk: flash_s3_rails\"\n      date: \"2012-08-22\"\n      start_cue: \"36:42\"\n      end_cue: \"40:36\"\n      id: \"sam-woodard-lighting-talk-railsconf-2012\"\n      video_id: \"sam-woodard-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Sam Woodard\n\n    - title: \"Lightning Talk: One Man in the name of Embedding Javascript into Ruby\"\n      date: \"2012-08-22\"\n      start_cue: \"40:36\"\n      end_cue: \"44:37\"\n      id: \"charles-lowell-lighting-talk-railsconf-2012\"\n      video_id: \"charles-lowell-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Charles Lowell\n\n    - title: \"Lightning Talk: Hacking the Airlines\"\n      date: \"2012-08-22\"\n      start_cue: \"44:37\"\n      end_cue: \"49:08\"\n      id: \"matt-rogish-lighting-talk-railsconf-2012\"\n      video_id: \"matt-rogish-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Matt Rogish\n\n    - title: \"Lightning Talk: Top 10 Reasons you should probably quit your job\"\n      date: \"2012-08-22\"\n      start_cue: \"49:08\"\n      end_cue: \"54:08\"\n      id: \"brad-wilkening-lighting-talk-railsconf-2012\"\n      video_id: \"brad-wilkening-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Brad Wilkening\n\n    - title: \"Lightning Talk: Monitoring with Graphite\"\n      date: \"2012-08-22\"\n      start_cue: \"54:08\"\n      end_cue: \"58:51\"\n      id: \"matt-conway-lighting-talk-railsconf-2012\"\n      video_id: \"matt-conway-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Matt Conway\n\n    - title: \"Lightning Talk: It's a Wrap!\"\n      date: \"2012-08-22\"\n      start_cue: \"58:51\"\n      end_cue: \"01:00:48\"\n      id: \"dr-nic-williams-evan-phoenix-lighting-talk-railsconf-2012\"\n      video_id: \"dr-nic-williams-evan-phoenix-lighting-talk-railsconf-2012\"\n      video_provider: \"parent\"\n      speakers:\n        - Dr. Nic Williams\n        - Evan Phoenix\n\n- id: \"joseph-ruscio-railsconf-2012\"\n  title: \"It's Not in Production Unless it's Monitored\"\n  raw_title: \"Rails Conf 2012 It's Not in Production Unless it's Monitored by Joseph Ruscio (improved audio)\"\n  speakers:\n    - Joseph Ruscio\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-07-28\"\n  description: |-\n    In the 21st century successful teams are data-driven. We'll present a complete introduction to everything you need to start monitoring your service at every level from business drivers to per-request metrics in Rails/Rack, down to server memory/cpu. Provides a high-level overview of the fundamental components that comprise a holistic monitoring system and then drills into real-world examples with tools like ActiveSupport::Notifications, statsd/rack-statsd, and CollectD. Also covers best practices for active alerting on custom monitoring data.\n\n  video_provider: \"youtube\"\n  video_id: \"0spo9hvDz_4\"\n  alternative_recordings:\n    - title: \"It's not in Production Unless it's Monitored\"\n      video_provider: \"youtube\"\n      video_id: \"YXEdd7_IbEc\"\n      date: \"2012-04-25\"\n\n- id: \"michael-fairley-railsconf-2012\"\n  title: \"Extending Ruby with Ruby\"\n  raw_title: \"Rails Conf 2012 Extending Ruby with Ruby by Michael Fairley\"\n  speakers:\n    - Michael Fairley\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-07-15\"\n  description: |-\n    Other programming languages have powerful features that are often enviable while working in Ruby: Python's function decorators, Scala's partial evaluation, and Haskell's lazy evaluation, among others. Fortunately, Ruby's metaprogramming facilities give us the ability to add these features to Ruby ourselves, without the need for the core language to be changed.\n\n    This talk will walk through adding simple (yet functional) versions of the previously mentioned features to Ruby, using Ruby, and discuss the dos and don'ts of responsible Ruby metaprogramming.\n\n  video_provider: \"youtube\"\n  video_id: \"ZjYgNnCtpg4\"\n\n- id: \"jared-ning-railsconf-2012\"\n  title: \"MiniTest: Refactoring Test Unit and RSpec back to version 0.0.1\"\n  raw_title: \"MiniTest: Refactoring Test  Unit and RSpec back to version 0.0.1 by Jared Ning\"\n  speakers:\n    - Jared Ning\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-07-13\"\n  description: |-\n    MiniTest is the no-nonsense testing framework you already know how to use. If we strive for cleaner and simpler code in our own work, wouldn't it be nice to have that in our test framework too? Whether you're a Test Unit fan or RSpec fan, you'll feel right at home using MiniTest. Its simplicity makes it fast, easy to use, extendable, and maybe most importantly, easy to understand. Plus, Rails 4 uses MiniTest.\n\n  video_provider: \"youtube\"\n  video_id: \"IHB__duBuT0\"\n\n- id: \"nick-quaranto-railsconf-2012\"\n  title: \"Code spelunking in the All New Basecamp\"\n  raw_title: \"Code spelunking in the All New Basecamp by Nick Quaranto\"\n  speakers:\n    - Nick Quaranto\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-07-13\"\n  description: |-\n    Heard about the big Basecamp launch this March? Wondering what's new, how it's shaping Rails, and the tech behind it? We're going to go over some the practices and patterns in the new Basecamp's code base and you can learn how to improve your app with them.\n\n    Some of what we'll go over:\n\n    Employing concerns to share code across models/controllers Stacker, the CoffeeScript component behind the \"page\" based layout Why polling for updates still works at scale Client side testing without the hassle Using jbuilder to keep view data out of models Keeping your team's sanity with a single setup script Debugging painful JavaScript performance slowdowns How to keep your app alive even if external dependencies like Redis are down Why tagged request logging and action/controller SQL query logging can make finding bugs easier\n\n  video_provider: \"youtube\"\n  video_id: \"oXTzFCXE66M\"\n\n- id: \"obie-fernandez-railsconf-2012\"\n  title: \"Redis Application Patterns in Rails\"\n  raw_title: \"Redis Application Patterns in Rails by Obie Fernandez\"\n  speakers:\n    - Obie Fernandez\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-07-02\"\n  description: |-\n    Redis is a darling of the NoSQL crowd and for good reasons. It's easy to setup and has blazing fast performance. In this talk, drawn on real production experience and real code straight out of the DueProps codebase, Obie will introduce and demonstrate key Redis application patterns vital to today's Rails developer. Emphasis will be placed on real-world constraints and how to leverage Redis to improve scaling and performance over plain-vanilla ActiveRecord applications.\n\n    Concepts covered: * Adding Redis-based flags and other properties to ActiveRecord objects * Event tracking with Redis sets * Graphing relationships between (User) objects with Redis sets * Time-ordered activity feeds with Redis sorted sets * Applying security restrictions to display of activity feeds with intersection of Redis sorted sets * Aggregating group activity feeds with union of Redis sorted sets * Applying Redis sorted sets to scoring and leaderboard programming * Integrating Redis with Rspec and Cucumber * Debugging tactics for when things go wrong or are unclear\n\n  video_provider: \"youtube\"\n  video_id: \"dH6VYRMRQFw\"\n\n- id: \"ezra-zygmuntowicz-railsconf-2012\"\n  title: \"What a long Strange Trip it has been.\"\n  raw_title: \"What a long Strange Trip it has been. by Ezra Zygmuntowicz\"\n  speakers:\n    - Ezra Zygmuntowicz\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-06-21\"\n  description: |-\n    This talk will explore the story of Ezra's travels through the history of ancient Rails 0.6 when he first picked it up in 2004 all the way through current times and extrapolate out to the future of the Rails and Ruby platform and how much of a success it has been. We will talk about the twisting path from way back then to now and beyond and explore what Rails was, is and will be as time keeps on slipping into the future.\n\n    This talk will be chock full of aqdvancxed tech as well as ramblings of a Rails industry Vet who has been \"On the Rails\" for 8 long years now and has played a major part in shaping what has been, is and will be(at least in his own mind where he is absolutely a legend, in reality he's just a schmuck who hacks ruby)\n\n    I want to share with the Rails community my story and experiences and hopefully impart some wisdom and some hard learned lessons about life, liberty and the pursuit of a rails app that doesn't use 400Mb of RAM per process ;)\n\n  video_provider: \"youtube\"\n  video_id: \"Alko6wQo8mk\"\n\n- id: \"jim-weirich-railsconf-2012\"\n  title: \"Basic Rake\"\n  raw_title: \"Basic Rake by Jim Weirich\"\n  speakers:\n    - Jim Weirich\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-06-20\"\n  description: |-\n    Anyone who develops with Rails uses the Rake tool all the time. Rake will run your tests, migrate your database, and precompile your assets. But did you know you can define and build your own Rake tasks? This short talk will cover the basics of using Rake and writing simple automation tasks to make your development process smother.\n\n  video_provider: \"youtube\"\n  video_id: \"AFPWDzHWjEY\"\n\n- id: \"andrew-carter-railsconf-2012\"\n  title: \"Building Asynchronous Communication Layer w XMPP, Ruby, Javascript\"\n  raw_title: \"Building Asynchronous Communication Layer w XMPP, Ruby, Javascript by Andrew Carter and Steve Jang\"\n  speakers:\n    - Andrew Carter\n    - Steve Jang\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-06-20\"\n  description: |-\n    Although XMPP is most often used as a chat protocol, it can also provide a robust asynchronous communication channel in other application scenarios. In this presentation, we will provide introduction to Strophe.js, XMPP4R, and ejabberd, which are the XMPP components that we use to integrate our device automation framework and living room devices under test. By using these off-the-shelf components, we addressed our needs for getting around internal firewalls, application security (based on SASL), and asynchronous command-response handling.\n\n  video_provider: \"youtube\"\n  video_id: \"3ZynQ04BuN8\"\n\n- id: \"patrick-leonard-railsconf-2012\"\n  title: \"Preparing for Rapid Growth - Tips for Enabling Your App and Team to Grow\"\n  raw_title: \"Preparing for Rapid Growth - Tips for Enabling Your App and Team to Grow by Patrick Leonard\"\n  speakers:\n    - Patrick Leonard\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-06-20\"\n  description: |-\n    Every young company expects to grow quickly, but is your engineering team really ready for it? In 3 years, iTriage went from a kitchen table to one of the leading mobile consumer healthcare apps with over 5 million downloads. Staying ahead of this growth didn't just mean hiring more Rails engineers.\n\n    Patrick will discuss what iTriage did (and continues to do) to stay ahead of our growth, including: - Technical architecture, including use of Rails Engines to enable a modular, RESTful service-based design - Enabling high quality iPhone, Android and Web apps - Development and release management processes - Recruiting and hiring approaches\n\n  video_provider: \"youtube\"\n  video_id: \"kVNA6X6OD9k\"\n\n- id: \"dr-nic-williams-railsconf-2012\"\n  title: \"Engine Yard - The Cloud, Application Support, and You - Ask Me Anything\"\n  raw_title: \"Engine Yard - The Cloud, Application Support, and You - Ask Me Anything\"\n  speakers:\n    - Dr. Nic Williams\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-20\"\n  description: |-\n    This panel is made up of EY Support Engineers and Developers and they are ready to answer your questions! Want to know more about deploying to the cloud? What does PaaS mean to you? What is the EY Stack?\n\n  video_provider: \"youtube\"\n  video_id: \"eVHLTxpolcA\"\n\n- id: \"terence-lee-railsconf-2012\"\n  title: \"A Polygot Heroku\"\n  raw_title: \"A Polygot Heroku by Terence Lee\"\n  speakers:\n    - Terence Lee\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-06-20\"\n  description: |-\n    Over the past year, Heroku has expanded by going polyglot and supporting languages like Java, Clojure, Python, Node.js, and Scala in addition to Ruby. In this session, we will discuss major updates to the platform and our emphasis on making the Ruby developer experience even better. We'll leave plenty of time at the end for any questions.\n\n  video_provider: \"youtube\"\n  video_id: \"jXnljOVEGKw\"\n\n- id: \"masahiro-ihara-railsconf-2012\"\n  title: \"How Rails helps make cooking more fun in Japan\"\n  raw_title: \"How Rails helps make cooking more fun in Japan by Masahiro Ihara\"\n  speakers:\n    - Masahiro Ihara\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-06-20\"\n  description: |-\n    With more than a million user submitted recipes and an active user base of 15 million monthly unique users, cookpad.com is the world's largest recipe website, and an essential tool for the 50% of all Japanese women in their 20's and 30's who use the site regularly.\n\n    The Cookpad.com service is built on Rails and is running entirely on AWS in Tokyo, where more than 30 engineers are working in small agile teams to bring more value to users every day.\n\n    As you know, Japan had a huge earthquake and tsunami last year, and some of those affected didn't have cooking facilities, water or basic foods for long time. Many Cookpad users immediately uploaded simple recipes that could be made without the basics in adverse conditions, and helped those in hardship immensely allowing them to enjoy food with their families at that difficult time.\n\n    In this session, I'll talk about the COOKPAD way of creating services and the technologies behind them, and how we improve peoples lives through cooking every day.\n\n  video_provider: \"youtube\"\n  video_id: \"w2HXbFd7QJI\"\n\n- id: \"jacob-swanner-railsconf-2012\"\n  title: \"Active Record Scopes and Arel\"\n  raw_title: \"Active Record Scopes and Arel by Jacob Swanner\"\n  speakers:\n    - Jacob Swanner\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-19\"\n  description: |-\n    Scopes are a great way of encapsulating query logic in a granular, reusable way. This talk will cover some techniques you can use to keep those scopes as composable and portable as possible. We'll cover how to use Arel directly, while avoiding the common practice of using SQL fragments, and show you how this can make your scopes more reusable, while at the same time preventing you from using database vendor specific operators, such as ILIKE.\n\n  video_provider: \"youtube\"\n  video_id: \"V-Kmy8IQii0\"\n\n- id: \"bryan-liles-railsconf-2012\"\n  title: \"ActiveSupport and ActiveModel\"\n  raw_title: \"ActiveSupport and ActiveModel by Bryan Liles\"\n  speakers:\n    - Bryan Liles\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-18\"\n  description: |-\n    Have you ever wondered what makes Rails tick? Bryan Liles will cover two of the pillars of the Rails foundation: ActiveSupport and ActiveModel. Together we will discover where some of Rails' ease and power originates and how make use of it in your projects.\n\n  video_provider: \"youtube\"\n  video_id: \"2Km8OVT20mY\"\n\n- id: \"olivier-lacan-railsconf-2012\"\n  title: \"RVM & Essential Rails Development Tools\"\n  raw_title: \"RVM & Essential Rails Development Tools by Olivier Lacan\"\n  speakers:\n    - Olivier Lacan\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-18\"\n  description: |-\n    Working with Rails often means switching between several Ruby versions\n    back and forth which is made almost seamless by RVM. It also involves several\n    simple command line tools like Pry, Guard, and Pow and that will make your development\n    life so much easier.\n\n    3:42 Homebrew\n    7:50 RVM\n    14:52 POW & Powder\n    18:47 Pry\n    20:45 Bundler\n\n  video_provider: \"youtube\"\n  video_id: \"GtB6cwgm2fE\"\n\n- id: \"michael-hartl-railsconf-2012\"\n  title: \"Rails Flavored Ruby\"\n  raw_title: \"Rails Flavored Ruby by Michael Hartl\"\n  speakers:\n    - Michael Hartl\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-18\"\n  description: |-\n    Based on Chapter 4 of the Ruby on Rails Tutorial by Michael Hartl, \"Rails-flavored Ruby\" covers the aspects of the Ruby programming language most important for developing Rails applications. Topics include hashes, arrays, and other objects; blocks; functions; and classes.\n\n  video_provider: \"youtube\"\n  video_id: \"ARMgU6Prfws\"\n\n- id: \"andy-maleh-railsconf-2012\"\n  title: \"Rails Engines Patterns\"\n  raw_title: \"Rails Engines Patterns by Andy Maleh\"\n  speakers:\n    - Andy Maleh\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-18\"\n  description: |-\n    This talk covers a successful utilization of Rails Engines to share features that cut across the layers of MVC in different Rails 3 projects. Rails Engines thus provide the best of both worlds: improved productivity by reusing MVC code (including assets like Javascript, CSS, and Images) and better flexibility by allowing different applications to customize behavior as needed without reliance on application-dependent conditionals. Rails Engine patterns will be provided to guide developers on how to leverage Rails Engines' reusability and flexibility without sacrificing maintainability.\n\n    Outline:\n\n    Basics of Rails Engines Rails Engine Patterns Improved Productivity Tips Summary of Benefits and Trade-Offs Attendees should walk away with an overview of Rails Engines and guidelines on how to utilize them effectively.\n  video_provider: \"youtube\"\n  video_id: \"pm94BsoMGik\"\n\n- id: \"thomas-pomfret-railsconf-2012\"\n  title: \"Securing Your Site\"\n  raw_title: \"Securing Your Site by Thomas Pomfret\"\n  speakers:\n    - Thomas Pomfret\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-18\"\n  description: |-\n    Rails makes it very easy to rapidly develop web applications, but doesn't always make it so simple to deploy or secure them.\n\n    This talk is going to focus on best practices to secure your rails application, learnt through multiple high profile projects and penetration tests. The talk will be practical and show that this isn't necessarily hard if thought about from the start.\n\n    We'll also touch on getting the right balance of security without it getting in the way of the users.\n\n  video_provider: \"youtube\"\n  video_id: \"1bUGy-E10Zo\"\n\n- id: \"mikel-lindsaar-railsconf-2012\"\n  title: \"From Rails Rumble to 50,000,000 results\"\n  raw_title: \"From Rails Rumble to 50,000,000 results by Mikel Lindsaar\"\n  speakers:\n    - Mikel Lindsaar\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-17\"\n  description: |-\n    StillAlive.com was born from the 48 hour intense 2010 Rails Rumble and has grown! Having recently passed our 50,000,000th site result, this talk discusses the real world challenges and optimisations required to take a code base born from the fires of YAGNI to a production system.\n\n    This talk isn't about how you can scale from 0 requests to 500 billion requests per microsecond, but give a practical view to some of the performance problems we faced as the application steadily grew from a hack job into a functioning system.\n\n    The journey will go through the mistakes we made, challenges faced and real world optimisations discovered, including some tricks we learnt along the way from concurrent index creation to using the ZeroMQ messaging framework with Rails\n  video_provider: \"youtube\"\n  video_id: \"KORzSXfp1pY\"\n\n- id: \"brad-gessler-railsconf-2012\"\n  title: \"Realtime web applications with streaming REST\"\n  raw_title: \"Realtime web applications with streaming REST by Brad Gessler\"\n  speakers:\n    - Brad Gessler\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-17\"\n  description: |-\n    As more people collaborate on the web with your applications, its not enough to just persist data to the database; it needs to be pushed out to your users web browsers so that they're always working with the freshest data.\n\n    In this session, Brad will show how to build a real-time layer on top of an existing Rails application's authorization and resource logic so that you can build on top of the hard work already invested in your Rails application.\n\n    Topics that will be discussed include:\n\n    Why I didn't choose Socket.IO Stream application resources into Backbone.js models to keep data fresh Hook into ActiveRecord to push representations of data into a message queue Message queue naming conventions public/private resource streams Exposing message queues to HTTP Securing streams with existing application authorization logic Considerations for streaming in a production environment\n  video_provider: \"youtube\"\n  video_id: \"N6kHjXtLspw\"\n\n- id: \"keith-gaddis-railsconf-2012\"\n  title: \"Use the Source, Luke: High-fidelity history with event-sourced data\"\n  raw_title: \"Use the Source, Luke: High-fidelity history with event-sourced data by Keith Gaddis\"\n  speakers:\n    - Keith Gaddis\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-16\"\n  description: |-\n    Ever run into a really gnarly data problem and wished you had a do-over? Tired of wrestling with ActiveRecord to model a really complex domain? Looking for a good way to echo state changes to external systems? Then grab a cup of joe and settle in for a look at event-sourcing your data.\n\n    Event-sourced data uses Plain Old Ruby Objects (POROs) to model your data and exclusively uses events to mutate state on those objects. By serializing the events, the state of your data can be recreated for any point in time, and outside listeners can create specialized purposeful datastores of the data, enabling complex business requirements with fewer hassles. We'll also touch on other architectural patterns like DCI and CQRS that play well with this idea.\n  video_provider: \"youtube\"\n  video_id: \"gwgEyHvk__E\"\n\n- id: \"charles-abbott-railsconf-2012\"\n  title: \"RoRoRoomba - Ruby on Rails on Roomba\"\n  raw_title: \"RoRoRoomba - Ruby on Rails on Roomba by Charles Abbott\"\n  speakers:\n    - Charles Abbott\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-16\"\n  description: |-\n    RoR makes an excellent framework for off-the-beaten-path type of projects, like hacking Roombas and other robots. In this presentation, I'll demonstrate how our soon to be robot overlords will be happy when we gift them with RoR and a connection to the internet. The presentation will include working examples and demonstrations of:\n\n    communicating with an Arduino chip via Ruby tethered serial and wireless bluetooth control of a Roomba via Ruby and Arduino two-way communication with our robot friends over the web using Ruby on Rails and popular web services useful applications of robots controlled over the web 3 RoRoR pitfalls to watch-out for live performance of \"Chiron Beta Prime\" by Jonathan Coulton* The presentation will close with an argument for why hacking on fun, often eccentric, projects in your spare time is essential for staying motivated, habitual improvement, and tangential learning -- i.e., being a real pragmatic programmer.\n\n    *not included, perhaps\n  video_provider: \"youtube\"\n  video_id: \"hW71mfdUJFo\"\n\n- id: \"steve-klabnik-railsconf-2012\"\n  title: \"Designing Hypermedia APIs\"\n  raw_title: \"Designing Hypermedia APIs by Steve Klabnik\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-15\"\n  description: |-\n    Rails did a lot to bring REST to developers, but its conception leaves the REST devotee feeling a bit empty. \"Where's the hypermedia?\" she says. \"REST isn't RPC,\" he may cry. \"WTF??!?!\" you may think. \"I have it right there! resources :posts ! What more is there? RPC? Huh?\"\n\n    In this talk, Steve will explain how to design your APIs so that they truly embrace the web and HTTP. Just as there's an impedance mismatch between our databases, our ORMs, and our models, there's an equal mismatch between our applications, our APIs, and our clients. Pros and cons of this approach will be discussed, as well as why we aren't building things this way yet.\n  video_provider: \"youtube\"\n  video_id: \"g4sqydY3hHU\"\n\n- id: \"andrew-cantino-railsconf-2012\"\n  title: \"Practical Machine Learning and Rails\"\n  raw_title: \"Practical Machine Learning and Rails by Andrew Cantino and Ryan Stout\"\n  speakers:\n    - Andrew Cantino\n    - Ryan Stout\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-15\"\n  description: |-\n    Many people know that machine learning techniques can facilitate learning from, and adapting to, noisy, real-world data, but aren't sure how to begin using them. Starting with two real-world examples, we will introduce you to some libraries that bring machine learning techniques to your Rails applications. We will then dive into the art of feature design, one of the first practical roadblocks that many people encounter when applying machine learning. Feature design is the challenging, subtle, and often trail-and-error process of selecting and transforming the data you provide for your learning algorithm, and it is often the hardest part of using these techniques. Our goal is for you to come out of this talk with the tools necessary to think about machine learning and how to apply it to your problems.\n  video_provider: \"youtube\"\n  video_id: \"vy_zQ1-F0JI\"\n\n- id: \"piotr-sarnacki-railsconf-2012\"\n  title: \"Using Rails without Rails\"\n  raw_title: \"Using Rails without Rails by Piotr Sarnacki\"\n  speakers:\n    - Piotr Sarnacki\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-06-14\"\n  description: |-\n    Rails got much more modular after 3.0 rewrite. But do you know how to use specific rails elements outside Rails? What if you would like to use ActionView with some other library (like webmachine)? Have you ever needed to render view with layouts outside of the rails stack? Or maybe you wanted to build some kind of system that fetches templates from database rather than from files? Router anyone? You know that you can use it outside rails too?\n\n    In this talk I will dive into Rails internals and will show you what's there and how you can use it outside rails.\n\n    Although I will focus on using those parts standalone, this knowledge will most likely help you also build your apps if you ever need something sophisticated that requires modification of regular rails behavior.\n  video_provider: \"youtube\"\n  video_id: \"ssJuHxHsS5o\"\n\n- id: \"jerry-cheung-railsconf-2012\"\n  title: \"Evented Ruby vs Node.js\"\n  raw_title: \"RailsConf 2012 Evented Ruby vs Node.js by Jerry Cheung\"\n  speakers:\n    - Jerry Cheung\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-06-14\"\n  description: |-\n    While Node.js is the hot new kid on the block, evented libraries like EventMachine for Ruby and Twisted for Python have existed for a long time. When does it make sense to use one over the other? What are the advantages and disadvantages to using node over ruby? In this talk, you will learn how to get the same power of concurrency enjoyed by Node.js while continuing to write in the language you know and love. Topics covered will include pubsub with redis or faye, building evented rack applications, and running evented applications alongside existing Rails apps.\n  video_provider: \"youtube\"\n  video_id: \"4iFBC-xbE9I\"\n\n- id: \"will-leinweber-railsconf-2012\"\n  title: \"Schemaless SQL The Best of Both Worlds\"\n  raw_title: \"Schemaless SQL The Best of Both Worlds by Will Leinweber\"\n  speakers:\n    - Will Leinweber\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-06-14\"\n  description: |-\n    Schemaless database are a joy to use because they make it easy to iterate on your app, especially early on. And to be honest, the relational model isn't always the best fit for real-world evolving and messy data.\n\n    On the other hand, relational databases are proven, robust, and powerful. Also, over time as your data model stabilizes, the lack of well-defined schemas becomes painful.\n\n    How are we supposed to pick one or the other? Simple: pick both. Fortunately recent advances in Postgres allow for a hybrid approach that we've been using at Heroku. The hstore datatype gives you key/value in a single column, and PLV8 enables JavaScript and JSON in Postgres. These and others in turn make Postgres the best document database in the world.\n\n    We will explore the power of hstore and PLV8, explain how to use them in your project today, and examine their role in the future of data.\n  video_provider: \"youtube\"\n  video_id: \"OHz6A023YNI\"\n\n- id: \"richard-huang-railsconf-2012\"\n  title: \"Semi Automatic Code Review\"\n  raw_title: \"Semi Automatic Code Review by Richard Huang\"\n  speakers:\n    - Richard Huang\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-06-13\"\n  description: |-\n    Rails is so popular to be used to fast build a website, at the beginning we sometimes write codes too fast without considering code quality, but after your company grows fast, you have to pay more attentions on code review to make your website more robust and more maintainable.\n\n    In this talk I will introduce you a way to build a semi automatic code review process, in this process a tool will analyze the source codes of your rails project, then give you some suggestions to refactor your codes according to rails best practices. It can also check your codes according to your team's rails code guideline. So engineers can focus on implementation performance, scalability, etc. when they do code review.\n  video_provider: \"youtube\"\n  video_id: \"900BvuBzINI\"\n\n- id: \"mike-moore-railsconf-2012\"\n  title: \"Presenters and Decorators: A Code Tour\"\n  raw_title: \"Presenters and Decorators: A Code Tour by Mike Moore\"\n  speakers:\n    - Mike Moore\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-06-13\"\n  description: |-\n    Presenter and Decorators are design approaches that can be used in Rails applications outside of the standard Models, Views and Controllers. These approaches are becoming more and more popular as teams search for new ways to identify and manage the complexity within their applications.\n\n    In this session Mike Moore will defined the Presenter and Decorator approaches using simple and clear terminology. Common design problems in Rails applications will be shown using real-life code examples and refactored toward Presenters and Decorators. Code will be improved and strengthened by identifying and respecting the dependencies within large applications.\n  video_provider: \"youtube\"\n  video_id: \"xf7i44HJ_1o\"\n\n- id: \"mark-bates-railsconf-2012\"\n  title: \"CoffeeScript for the Rubyist\"\n  raw_title: \"CoffeeScript for the Rubyist by Mark Bates\"\n  speakers:\n    - Mark Bates\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-04\"\n  description: |-\n    CoffeeScript is taking the world, and particularly the Rails eco system, by storm. This little language has provided an almost Ruby like abstraction onto of JavaScript. CoffeeScript is trying to make writing front end code as much fun as Ruby makes writing backend code.\n\n    In this talk we start with the basic concepts of CoffeeScript and move on to the more powerful and fun features of the language. While we're looking at CoffeeScript we'll see how it relates to the Ruby code we write everyday. What do Ruby 1.9 lambdas and CoffeeScript functions have in common? Which of the two languages supports splats, default arguments, and ranges? The answers may surprise you.\n  video_provider: \"youtube\"\n  video_id: \"aER4_AP3S4E\"\n\n- id: \"sarah-mei-railsconf-2012\"\n  title: \"Using Backbone.js with Rails: Patterns from the Wild\"\n  raw_title: \"Using Backbone.js with Rails: Patterns from the Wild by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-06-04\"\n  description: |-\n    Backbone.js is a flexible, lightweight tool for structuring the JavaScript in a modern web application. It goes great with Rails! But beware - \"flexible and lightweight\" are code words for \"you build your own plumbing.\" Backbone is new enough that we haven't established strong patterns for that plumbing yet, so different Backbone codebases look very different, and when you're new to the idea of structuring your JavaScript, it can be tough to tell where the win is.\n\n    So in this talk I'll demystify Backbone. I'll show several very different ways I've used it on real Rails apps. You'll get a feel for the circumstances when Backbone makes sense, and moreover, when each of the different approaches to Backbone make sense.\n  video_provider: \"youtube\"\n  video_id: \"lPiM4T1lR58\"\n\n- id: \"josh-kalderimis-railsconf-2012\"\n  title: \"Deconstructing Travis\"\n  raw_title: \"Deconstructing Travis by Josh Kalderimis\"\n  speakers:\n    - Josh Kalderimis\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-05-29\"\n  description: |-\n    Unless you have been living under a rock for the past year you might know of Travis CI, the continuous integration service for the open source community.\n\n    Travis started as a single GitHub project which was a rails app and a resque background task. Compare that to 12 months later where Travis is now four separate deployable apps, uses two different rubies (1.9.2 and jruby), and comprises a total of 10 GitHub projects.\n\n    Apart from looking at how Travis works now, we will also look at how it got there, and how we broke Travis up into smaller more manageable, more concise encapsulated services.\n  video_provider: \"youtube\"\n  video_id: \"huFeH5BRhUo\"\n\n- id: \"lance-ball-railsconf-2012\"\n  title: \"Complex Made Simple: Sleep Better with TorqueBox\"\n  raw_title: \"Complex Made Simple: Sleep Better with TorqueBox by Lance Ball\"\n  speakers:\n    - Lance Ball\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-05-28\"\n  description: |-\n    Even the simplest of Rails applications can eventually grow into a twisted mess of complexity. At some point you will need a background task, or a long-running service, or a scheduled job, or all of the above and more. All of these little bits of functionality added to an application ad hoc can keep you up at night with cold sweats and nightmares. But it doesn't have to be that way.\n\n    In this presentation, we will examine a complex Rails application - complexity that is eventually common to most modern Rails apps: background tasks, scheduled jobs, WebSockets, long-running services, caching and more. We will look at the challenges inherent in these features for both development and deployment. Then we'll look to TorqueBox for simple solutions to these complex problems. You'll never have that long-runing service using the wrong Ruby code again; no more environment variable nightmares in your cron jobs. You can sleep better now.\n\n    TorqueBox is a Ruby application server that is built on JRuby and JBoss AS7. It provides asynchronous messaging, scheduled jobs, long-running processes, caching, simple deployment, and much more. TorqueBox is designed to bring the power, scalability and stability of these time-tested JavaEE services to Ruby applications through a simple and expressive Ruby interface.\n  video_provider: \"youtube\"\n  video_id: \"YgU3Ai54Udc\"\n\n- id: \"kenta-murata-railsconf-2012\"\n  title: \"Chanko - How Cookpad safely releases multiple feature prototypes - in production\"\n  raw_title: \"Chanko - How Cookpad safely releases multiple feature prototypes - in production by Kenta Murata\"\n  speakers:\n    - Kenta Murata\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-05-28\"\n  description: |-\n    Chanko provides a simple framework for rapidly and safely prototyping new features in your production Rails app, and exposing these prototypes to specified segments of your user base.\n\n    With Chanko, you can release many concurrent features and independently manage which users see them. If there are errors with any chanko, it will be automatially removed, without impacting your site.\n\n    Chanko was extracted from Cookpad.com where the team uses it daily to test new features live, in production, on the largest Rails site in Japan which serves 500 million page views a month to a user based of over 15 million highly engaged uses.\n  video_provider: \"youtube\"\n  video_id: \"wikJl1VjKko\"\n\n- id: \"yehuda-katz-railsconf-2012\"\n  title: \"Rails: The Next Five Years\"\n  raw_title: \"Rails: The Next Five Years by Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-05-14\"\n  description: |-\n    When Ruby on Rails burst onto the scene in 2004, it excited web developers by showing that you could build next generation apps quickly and efficiently. Rails was one of the first frameworks to embrace Ajax, giving everyone the power to do partial page updates and whiz-bang effects in a conventional, effortless way.\n\n    In 2007, the Rails team embraced RESTful conventions, making API development a no-brainer for new applications. Because RESTful JSON is so easy in Rails, Rails applications tend to implement APIs on balance.\n\n    Then it was time to polish. Both the 2.0 and 3.0 releases cleaned up the code-base and found ways to take emerging conventions and make them easier to use.\n\n    But now, like in 2004, another revolution is brewing. Increasingly, developers are moving their view layer from the server into the client, using RESTful JSON and client-side templating to increase responsiveness and bring applicable aspects of desktop applications to the web.\n\n    Like last time, not every application needs to jump head-first into this new world. But just as in 2004, Rails has an opportunity to embrace the future, and bring its ruthless insistence on convention over configuration to bear on this problem.\n\n    Rails already has the plumbing to be a fantastic conventional JSON server. The question is: will we take the challenge, or will we desperately cling to the past, hoping that the future will never come?\n\n  video_provider: \"youtube\"\n  video_id: \"UlMpIHH1K5s\"\n\n- id: \"david-czarnecki-railsconf-2012\"\n  title: \"Stack Smashing\"\n  raw_title: \"Rails Conf 2012 Stack Smashing by David Czarnecki\"\n  speakers:\n    - David Czarnecki\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-05-12\"\n  description: |-\n    \"Stack Smashing\" refers to an internal project where I took our production Rails application environment down from over 100 virtual machines to 2 physical machines. Our application environment for Major League Gaming consists of 13+ inter-connected applications with millions of users to provide functionality such as single-sign on, online video (both video on demand and UGC), news and live competition information, photo galleries, profiles, and much more. We simply needed a simpler infrastructure in which to develop and deploy our applications. In this talk, we will cover the following:\n\n    Network topology before and after, as well as the makeup of our virtual and physical machines. Detailed discussion of Chef recipes, NGINX, HAProxy configurations and updates to standard configurations. Application and service monitoring and configuration. Application migration from the old stack to the new stack. Rails 3 to Rails 3.1 upgrade insights. Unicorns! Strategies for service configuration to handle failure. Offline processing with queueing and queue management. Simplifying, standardizing and sexy-fying your Capistrano-based deployment tasks into a reusable gem. Behavior driven infrastructure monitoring and validation. Adopting an opt-in continuous deployment strategy that is integrated with our continuous integration environment. This will be a very code and example-focused talk. Come and learn about the ways that you can simplify your existing infrastructure.\n\n  video_provider: \"youtube\"\n  video_id: \"p-uWNZdK7Gs\"\n\n- id: \"matt-sanders-railsconf-2012\"\n  title: \"Digging Deep with ActiveSupport::Notifications\"\n  raw_title: \"Digging Deep with ActiveSupport::Notifications by Matt Sanders\"\n  speakers:\n    - Matt Sanders\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-05-11\"\n  description: |-\n    Rails 3 and above includes a powerful instrumentation system, ActiveSupport::Notifications, which can be used to track performance and event information for all aspects of your application. Notifications are light-weight, easy to setup, and can be consumed by multiple subscribers (logs, audit trails, consolidated metrics, other parts of your application).\n\n    In this session we'll start with the basics of ActiveSupport::Notifications and work our way to powerful advanced use cases. Topics we'll explore include:\n\n    How to set up and use notifications Logging what you want from any tier of your system How to capture and aggregate performance/business data for the metrics you care about most Conditional monitoring in production: flag on and off data by system or customer to get to the root of problems more quickly Using ActiveSupport::Notifications in non-Rails applications and your own libraries\n  video_provider: \"youtube\"\n  video_id: \"sKrrsF0MZ7Q\"\n\n- id: \"james-edward-gray-ii-railsconf-2012\"\n  title: \"Ten Things You Didn't Know Rails Could Do\"\n  raw_title: \"Ten Things You Didn't Know Rails Could Do by James Edward Gray II\"\n  speakers:\n    - James Edward Gray II\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-05-11\"\n  description: |-\n    Rails is huge. Even if you have worked with it for a long time, it's unlikely that you have stumbled across everything yet.\n\n    Do you really know what all of the built-in Rake tasks do? Have you seen all of the methods ActiveSupport makes available to you? Are you aware of all the queries ActiveRecord is capable of?\n\n    In this talk, I'll dig into the extras of Rails and see if I can't turn up some features that you don't see all of the time, but that might just be handy to know about anyway. I'll make sure you come out of this able to impress your friends at the hackfest.\n  video_provider: \"youtube\"\n  video_id: \"GRfJ9lni4QA\"\n\n- id: \"ilya-grigorick-railsconf-2012\"\n  title: \"Let's make the web faster - tips from trenches @ Google\"\n  raw_title: \"Let's make the web faster - tips from trenches @ Google by Ilya Grigorick\"\n  speakers:\n    - Ilya Grigorick\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-05-03\"\n  description: |-\n    Google loves speed, and we want to make the entire web faster - yes, that includes your Rails app! We'll explore what we've learned from running our own services at scale, as well as cover the research, projects, and open sourced tools we've developed in the process.\n\n    We'll start at the top with website optimization best practices, take a look at what the browser and HTML5 can do for us, take a detour into the optimizations for the mobile web, and finally dive deep into the SPDY and TCP protocol optimizations.\n\n    We'll cover a lot of ground, so bring a coffee. By the end of the session, you should have a good checklist to help you optimize your own site.\n  video_provider: \"youtube\"\n  video_id: \"pxrj1a1PS94\"\n\n- id: \"nathen-harvey-railsconf-2012\"\n  title: \"Taming the Kraken - How Operations enables developer productivity\"\n  raw_title: \"Taming the Kraken - How Operations enables developer productivity by Nathen Harvey\"\n  speakers:\n    - Nathen Harvey\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-05-03\"\n  description: |-\n    Are you having trouble launching new features because of friction between development and operations? At CustomInk, we've reduced this friction by making changes to our teams, processes, and tools. Come find out what we've been up to and learn how you can implement similar changes in your own environment.\n\n    There's always a bit of tension when getting features from idea to production. In this talk, we'll look at some of the changes CustomInk has made to reduce this friction and keep the new features coming. Gone are the days of bi-monthly deploys, office pools dedicated to guessing when this deploy will be rolled back, and the ceremony surrounding the deploy-rollback-fix-deploy cycle. Today, ideas flow from product managers to developers to production with ease thanks to a number of changes that we've made to our teams, processes and tools.\n\n    During this talk, we'll look at:\n\n    How product managers drive the release cycle\n\n    Ideas and customer feedback\n    Prioritizing development requests\n    Managing branch merges and deployments (yes, product managers can help here!)\n    How operations enables developer productivity\n\n    Spinning up development environments - Vagrant, Chef\n    Infrastructure Automation - Chef\n    Enabling Continuous Deployment - Capistrano and caphub\n    Failing gracefully - Fault-tolerant load balancing with ldirectord\n    How developers get their code running in production\n\n    Staging environments\n    Continuous Integration - Jenkins, Green Screen\n    Staying on topic: Deploying changes when they're ready\n    Getting rid of the over-the-wall mentality - Dev & Ops working together\n\n    Enabling developers to do it themselves\n    Pair programing infrastructure automation\n    Keeping the process light and the communication flowing\n  video_provider: \"youtube\"\n  video_id: \"5vzNzQzmAk0\"\n\n- id: \"hampton-catlin-railsconf-2012\"\n  title: \"The Future of Sass\"\n  raw_title: \"The Future of Sass by Hampton Catlin\"\n  speakers:\n    - Hampton Catlin\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-05-03\"\n  description: |-\n    A glimpse of some of the features coming to Sass in the pending 3.2 release. Plus, a huge announcement about the project that's been months in the making as we have secretly toiled away on something that we think will be awesome. Hear it first at this talk. Repositories will be made public when the talk is over. Shh! Its a secret!\n  video_provider: \"youtube\"\n  video_id: \"MFwId6xSh2o\"\n\n- id: \"john-bender-railsconf-2012\"\n  title: \"Progressive Enhancement on the Mobile Web\"\n  raw_title: \"Progressive Enhancement on the Mobile Web by John Bender\"\n  speakers:\n    - John Bender\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-05-03\"\n  description: |-\n    Progressive Enhancement isn't important on the mobile web because it's all Webkit right? Not so fast. Even among Webkit implementations events, css, and performance vary widely. We'll talk about the darker corners of the mobile web and show how jQuery Mobile can help you build Rails applications that are reliable, accessible, and support more devices.\n  video_provider: \"youtube\"\n  video_id: \"mEivOr3fcMs\"\n\n- id: \"lori-m-olson-railsconf-2012\"\n  title: \"Mobile Rage - What causes it & how to fix it.\"\n  raw_title: \"Mobile Rage - What causes it & how to fix it. by Lori Olson\"\n  speakers:\n    - Lori M Olson\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-05-03\"\n  description: |-\n    Most of us have been there. That website you want to use, from your mobile device, that just refuses to cooperate. From the Flash-only, to the can't f**king log in, to the redirect-to-mobile-and-stay-there sites, there's more than enough websites out there to invoke Mobile Rage.\n\n    Although we all know that the best mobile development strategy is \"mobile-first\", we also all know how many sites and applications out there were designed and built by people who didn't imagine how fast mobile would take over.\n\n    Come learn about the common mistakes most people make for mobile, and some of the simple solutions you can use to help reduce Mobile Rage, without having to do a complete rewrite.\n  video_provider: \"youtube\"\n  video_id: \"qev9PSaNLSA\"\n\n- id: \"daniel-azuma-railsconf-2012\"\n  title: \"Getting Down To Earth: Geospatial Analysis With Rails\"\n  raw_title: \"Rails Conf 2012 Getting Down To Earth: Geospatial Analysis With Rails by Daniel Azuma\"\n  speakers:\n    - Daniel Azuma\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-05-03\"\n  description: |-\n    It is no secret that location has become ubiquitous. Mobile GPS, available data sets, and easy-to-use mapping services have brought geospatial information within reach of web developers. Location already plays a significant role in many of the major services such as Twitter, Facebook, and Google, not to mention legions of startups.\n\n    However, for those of us implementing more than the most trivial features, it is also true that location is challenging. A significant learning curve awaits us, involving spatial databases, coordinate systems, interchange formats, and plenty of math. Our Ruby-based tools lag a bit behind those available to our Java- and Python-oriented colleagues, and effective documentation is scarce.\n\n    This presentation aims to jump-start Rails developers hoping to go beyond putting a few pushpins on a Google Map. Rather than spending a lot of time explaining the many concepts involved, we'll bypass the learning curve and jump straight into walking through code for a few nontrivial applications. The hope is that the conceptual knowledge will come naturally as a result of seeing it in action, but pointers to online resources will also be provided to fill in any gaps.\n\n    A thorough understanding of Ruby, Rails, ActiveRecord, and SQL will be assumed. No prior knowledge of GIS or computational geometry will be required, though it may be helpful.\n  video_provider: \"youtube\"\n  video_id: \"QI0e2jkUbkk\"\n\n- id: \"david-cohen-railsconf-2012\"\n  title: \"Keynote: 12 Tips Learned From Doing More Faster at TechStars\"\n  raw_title: \"Keynote by David Cohen of TechStars\"\n  speakers:\n    - David Cohen\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-05-03\"\n  description: |-\n    David Cohen is the founder and CEO of TechStars. Previously, David was a founder of several software and web technology companies. He was the founder and CTO of Pinpoint Technologies which was acquired by ZOLL Medical Corporation (NASDAQ: ZOLL) in 1999. You can read about it in No Vision, All Drive [Amazon]. David was also the founder and CEO of earFeeder.com, a music service which was sold to SonicSwap.com in 2006. He also had what he likes to think of as a \"graceful failure\" in between.\n\n    David is a active startup advocate, advisor, board member, and technology advisor who comments on these topics on his blog at DavidGCohen.com. He recently co-authored Do More Faster with Brad Feld. He is also very active at the University of Colorado, serving as a member of the Board of Advisors of the Computer Science Department, the Entrepreneurial Advisory Board at Silicon Flatirons, and the Board of Advisors of the Deming Center Venture Fund. He is a member of the selection committee for Venture Capital in the Rockies, and runs the Colorado chapter of the Open Angel Forum. His hobbies are technology, software/web startups, business history, and tennis. He is married to the coolest girl he's ever met and has three amazing kids who always seem to be teaching him something new.\n  video_provider: \"youtube\"\n  video_id: \"Ok7YH8_48pc\"\n\n- id: \"gregg-pollack-railsconf-2012\"\n  title: \"Ruby Hero Awards 2012\"\n  raw_title: \"2012 Ruby Hero Awards\"\n  speakers:\n    - Gregg Pollack\n    - Aaron Patterson\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-05-02\"\n  description: |-\n    This is the presentation of the 2012 Ruby Hero Awards\n  video_provider: \"youtube\"\n  video_id: \"tWmh4m2a4FI\"\n\n- id: \"aaron-patterson-railsconf-2012\"\n  title: \"Keynote: I've made a huge mistake\"\n  raw_title: \"Keynote: I've made a huge mistake by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-24\"\n  published_at: \"2012-05-02\"\n  description: |-\n    When he isn't ruining people's lives by writing software like phuby, enterprise, and neversaydie, Aaron can be found writing slightly more useful software like nokogiri. To keep up his Gameboy Lifestyle, Aaron spends his weekdays writing high quality software for ATTi. Be sure to catch him on Karaoke night, where you can watch him sing his favorite smooth rock hits of the 70's and early 80's.\n  video_provider: \"youtube\"\n  video_id: \"8kSfGgiFk48\"\n\n- id: \"rich-hickey-railsconf-2012\"\n  title: \"Keynote: Simplicity Matters\"\n  raw_title: \"Rails Conf 2012 Keynote: Simplicity Matters by Rich Hickey\"\n  speakers:\n    - Rich Hickey\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-23\"\n  published_at: \"2012-05-01\"\n  description: |-\n    Rich Hickey, the author of Clojure and designer of Datomic, is a software developer with over 20 years of experience in various domains. Rich has worked on scheduling systems, broadcast automation, audio analysis and fingerprinting, database design, yield management, exit poll systems, and machine listening, in a variety of languages.\n  video_provider: \"youtube\"\n  video_id: \"rI8tNMsozo0\"\n\n- id: \"james-edward-gray-ii-railsconf-2012-ruby-rogues-live-podcast\"\n  title: \"Ruby Rogues - Live Podcast!\"\n  raw_title: \"RailsConf 2012 - Ruby Rogues - Live Podcast!\"\n  speakers:\n    - James Edward Gray II\n    - Charles Max Wood\n    - Josh Susser\n    - David Brady\n    - Avdi Grimm\n  event_name: \"RailsConf 2012\"\n  date: \"2012-04-25\"\n  published_at: \"2012-08-22\"\n  description: |-\n    This presentation was recorded on April 25, 2012 in Austin, Texas at RailsConf 2012.\n\n    The presenters are James Edward Gray, Charles Max Wood, Josh Susser, David Brady and Avdi Grimm.\n\n    Ruby's favorite podcast comes to RailsConf! Join the Ruby Rogues (David Brady, James Edward Gray II, Avdi Grimm, Josh Susser, and Charles Max Wood) for this live episode on What Rails Developers Should Care About.\n\n    If you've listened to the show, you probably know that the Rogues favor:\n\n    Good Object Oriented design\n    Patterns\n    Test Driven Development\n    The Law of Demeter and Tell, Don't Ask\n    Open source\n    Beautiful code\n    Pair programming\n    Code metrics\n    Scaling performant code\n    and more\n    Since this is a live episode, we want to interact with the audience. Each Rogue will give a brief introduction on what's important to him as a Rubyist on Rails, then we will turn the session over to your questions. We will take them over the Internet and/or live, before and during the show.\n\n    All that AND we promise to wear amazing hats!\n\n  video_provider: \"youtube\"\n  video_id: \"pM_ak1KsBKI\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybxgqVTwuOA12wr5Gn2M2Pp\"\ntitle: \"RailsConf 2013\"\nkind: \"conference\"\nlocation: \"Portland, OR, United States\"\ndescription: |-\n  RailsConf Portland - April 29-May 2, 2013\npublished_at: \"2013-06-25\"\nstart_date: \"2013-04-29\"\nend_date: \"2013-05-02\"\nyear: 2013\nbanner_background: \"#55B2AE\"\nfeatured_background: \"#55B2AE\"\nfeatured_color: \"#FEF7E5\"\ncoordinates:\n  latitude: 45.515232\n  longitude: -122.6783853\n"
  },
  {
    "path": "data/railsconf/railsconf-2013/videos.yml",
    "content": "# TODO: talks running order\n# TODO: talk dates\n\n# Website: https://web.archive.org/web/20130818201623/http://www.railsconf.com/\n# Schedule: https://web.archive.org/web/20130817161430/http://railsconf.com/2013/schedule\n\n# https://ericbrooke.blog/2013/04/30/ruby-on-rails-conference/\n---\n- id: \"brian-gugliemetti-railsconf-2013\"\n  title: \"Using Elasticsearch with Rails Apps\"\n  raw_title: \"Rails Conf 2013 Using Elasticsearch with Rails Apps by Brian Gugliemetti\"\n  speakers:\n    - Brian Gugliemetti\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Elasticsearch is a powerful text search engine that's easy to configure and to integrate into your Rails and Ruby applications. But it's more than just a general text search engine--elasticsearch stores data in JSON format allowing for faceting and complex searches. There are gems that integrate it with ActiveRecord, but it can also be used easily outside of ActiveRecord. Learn from the real-world application of elasticsearch for general text searches to specific catalog-type searches.\n\n    We'll cover the elasticsearch basics, the existing gems you can use to integrate, and the lessons learned from integrating into existing projects. Examples include: how to index existing ActiveRecord models for general text searches, how to use elasticsearch for autocomplete, and how to use for complex queries.\n  video_provider: \"youtube\"\n  video_id: \"U-LrUN6jal8\"\n\n- id: \"bryan-helmkamp-railsconf-2013\"\n  title: \"Rails' Insecure Defaults\"\n  raw_title: \"Rails Conf 2013 Rails' Insecure Defaults by Bryan Helmkamp\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: |-\n    Out of the box, Rails provides facilities for preventing attacks like SQL injection, cross-site scripting (XSS), cross-site request forgery (CSRF), and more. As a result, it's considered one of the most secure web application frameworks available.\n    Digging deeper, however, you can find a number of places where Rails' default behavior is not as secure as it could be. This talk will focus on longstanding, known weak spots that create risks for your application and business if you are not aware of them.\n  video_provider: \"youtube\"\n  video_id: \"4MCfEb0R7ow\"\n\n- id: \"david-heinemeier-hansson-railsconf-2013\"\n  title: \"Patterns of Basecamp's Application Architecture\"\n  raw_title: \"Rails Conf 2013 Patterns of Basecamp's Application Architecture by David Heinemeier Hansson\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"yhseQP52yIY\"\n\n- id: \"andr-arko-railsconf-2013\"\n  title: \"Security is hard, but we can't go shopping\"\n  raw_title: \"Rails Conf 2013 Security is hard, but we can't go shopping by André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: |-\n    The last few months have been pretty brutal for anyone who depends on Ruby libraries in production. Ruby is really popular now, and that's exciting! But it also means that we are now square in the crosshairs of security researchers, whether whitehat, blackhat, or some other hat. Only the Ruby and Rails core teams have meaningful experience with vulnerabilites so far. It won't last. Vulnerabilities are everywhere, and handling security issues responsibly is critical if we want Ruby (and Rubyists) to stay in high demand.\n    Using Bundler's first CVE as a case study, I'll discuss responsible disclosure, as well as repsonsible ownership of your own code. How do you know if a bug is a security issue, and how do you report it without tipping off someone malicious? As a Rubyist, you probably have at least one library of your own. How do you handle security issues, and fix them without compromising apps running on the old code? Don't let your site get hacked, or worse yet, let your project allow someone else's site to get hacked! Learn from the hard-won wisdom of the security community so that we won't repeat the mistakes of others.\n  video_provider: \"youtube\"\n  video_id: \"tV7IPygjseI\"\n\n- id: \"zach-briggs-railsconf-2013\"\n  title: \"Nobody will Train You but You\"\n  raw_title: \"Rails Conf 2013 Nobody will Train You but You by Zach Briggs\"\n  speakers:\n    - Zach Briggs\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: |-\n    Why do we all know a developer who has been pounding out unmaintainable code for a decade or more? Why do people \"believe in TDD but I don't have time to write tests during crunch?\" How is it that we have an entire industry based around rescuing teams from acutely awful Rails apps?\n    It's because on the job experience is a poor teacher; plateauing as soon as the developer is able to ship code that meets requirements. Schools teach Computer Science which is only tangentially related to being a developer and most kata's are approached incorrectly, giving no value at best, and reinforcing poor practices at worst. On top of all this, our pairs (for the lucky ones who pair program) probably have not shown us anything new in months.\n    This presentation will give specific, concrete steps on how to slowly and steadily improve our game through practice and hard work. I'll identify what skill Rails developers should be focusing on and walk the audience through how to target and eliminate these weaknesses so that nothing but white hot joy streams out of our fingers and into our apps. There's no magic here, no secrets, and no hacks; just you and me working our butts off until we suck a little less.\n  video_provider: \"youtube\"\n  video_id: \"-0yajJLVbzw\"\n\n- id: \"john-duff-railsconf-2013\"\n  title: \"How Shopify Scales Rails\"\n  raw_title: \"Rails Conf 2013 How Shopify Scales Rails by John Duff\"\n  speakers:\n    - John Duff\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: |-\n    Tobias Lutke wrote the first line of code for Shopify nearly 10 years ago to power his own Snowboard shop. Two years later Shopify launched to the public on a single webserver using Rails 0.13.1. Today Shopify powers over 40k online stores and processes up to half a million product sales per day across the platform. Over 30 people actively work on Shopify which makes it the longest developed and likely largest Rails code base out there.\n    This is the story of how Shopify has evolved to handle its immense growth over the years. This is what getting big is all about: evolving to meet the needs of your customers. You don't start out with a system and infrastructure that can handle a billion dollar in GMV. You evolve to it. You evolve by adding caching layers, hardware, queuing systems and splitting your application to services.\n    This is the story of how we have tackled the various scaling pain points that Shopify has hit and what we have done to surpass them, what we are doing to go even further.\n  video_provider: \"youtube\"\n  video_id: \"xh4GPjCmmbY\"\n\n- id: \"fletcher-nicol-railsconf-2013\"\n  title: \"Automation in Deployment on Hybrid Hosting and Private Cloud Environments\"\n  raw_title: \"Rails Conf 2013 Automation in Deployment on Hybrid Hosting and Private Cloud Environments\"\n  speakers:\n    - Fletcher Nicol # Host\n    - Matthew Cooker\n    - Dr. Nic Williams\n    - James Casey\n    - Andy Camp\n    - Eric Lindvall\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: |-\n    In a world of public and private clouds, API-driven load balancers, and bare metal servers there has never been more choice when building your next scalable killer application. As the complexity of your application's deployment environment increases, the economics of automation start to pay off. In this session we'll discuss the challenges facing complex application deployments, strategies to make development environments mirror production, and how you can manage architectural changes with your application over time. Automate all the things? Let's find out!\n  video_provider: \"youtube\"\n  video_id: \"11eqsPfEbr8\"\n\n- id: \"allan-grant-railsconf-2013\"\n  title: \"The War For Talent: How To Succeed As an Employer or Engineer\"\n  raw_title: \"Rails Conf 2013 The War For Talent: How To Succeed As an Employer or Engineer by Allan Grant\"\n  speakers:\n    - Allan Grant\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"9L_jiJddLPo\"\n\n- id: \"carl-lerche-railsconf-2013\"\n  title: \"Monitoring the Health of Your App\"\n  raw_title: \"Rails Conf 2013 Monitoring the Health of Your App by Carl Lerche and Yehuda Katz\"\n  speakers:\n    - Carl Lerche\n    - Yehuda Katz\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: |-\n    Your app is your business, so keeping it healthy is important. Unfortunately, most of the tools available today are more like your doctor verifying the fact that you've had a heart attack—after it's happened.\n    You can do better. In this session, you'll learn how to use metrics to be more proactive about monitoring your applications health, and to suss out the subtle but important warning signs that can help you prioritize developer time and improve the developer experience. We'll talk about how to instrument your code, what to measure, how to interpret the data, as well as how you can use the data to streamline your development process.\n  video_provider: \"youtube\"\n  video_id: \"--uFArE8YUk\"\n\n- id: \"brian-cardarella-railsconf-2013\"\n  title: \"Real-Time Rails\"\n  raw_title: \"RailsConf 2013 Real-Time Rails by Brian Cardarella\"\n  speakers:\n    - Brian Cardarella\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-17\"\n  description: |-\n    The future is real time! With the Rails 4.0 Live Streaming API we finally have the ability to easily add real time functionality to our apps. Learn all about the live streaming API, how best to take advantage of this in the browser, and how to deploy a real-time ready Rails app. Get ready to open your apps to a whole new world of interaction and functionality. Topics we will cover:\n    * Live Streaming API\n    * EventMachine vs Rails 4.0\n    * Node.js vs Rails 4.0\n    * Polling vs Live Streaming\n    * Websockets & Rails 4.0\n    * Puma\n  video_provider: \"youtube\"\n  video_id: \"fOI3EjsUEww\"\n\n- id: \"michael-hartl-railsconf-2013\"\n  title: \"Ruby Libraries Important for Rails\"\n  raw_title: \"Rails Conf 2013 Ruby Libraries Important for Rails by Michael Hartl\"\n  speakers:\n    - Michael Hartl\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-23\"\n  description: |-\n    This talk+workshop highlights some Ruby libraries that are particularly useful when developing Rails applications. In the talk portion, we'll give an overview of some specific classes and modules, and then in the workshop we'll break into groups to dive deeper into libraries of each participant's choice, with a focus on developing the skills needed to read and understand the Ruby documentation. Time and interest permitting, we'll incorporate test-driven development into our investigations.\n  video_provider: \"youtube\"\n  video_id: \"noWORpSTQGE\"\n\n- id: \"noel-rappin-railsconf-2013\"\n  title: \"Testing Complex Systems: Creating data and limiting scope\"\n  raw_title: \"Rails Conf 2013 Testing Complex Systems: Creating data and limiting scope by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-23\"\n  description: |-\n    In this workshop, we'll focus on two specific problems that plague testing complex systems: how do I create useful test data, and how do I limit my test to only the part of the system that I want tested. We'll cover data creation tools like factories and fixtures. We will also talk about how to effectively use mock objects. And we'll do all that against some code that shows off potental testing problems.\n  video_provider: \"youtube\"\n  video_id: \"RdTt9kA-O5Q\"\n\n- id: \"harlow-ward-railsconf-2013\"\n  title: \"TDD Workshop: Mocking, Stubbing, and Faking External Services\"\n  raw_title: \"Rails Conf 2013 TDD Workshop: Mocking, Stubbing, and Faking External Services\"\n  speakers:\n    - Harlow Ward\n    - Adarsh Pandit\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8368hGNIJMQ\"\n\n- id: \"harlow-ward-railsconf-2013-tdd-workshop-outward-in-develo\"\n  title: \"TDD Workshop: Outward-in Development, Unit Tests, and Fixture Data\"\n  raw_title: \"Rails Conf 2013 TDD Workshop: Outward-in Development, Unit Tests, and Fixture Data\"\n  speakers:\n    - Harlow Ward\n    - Adarsh Pandit\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-23\"\n  description: |-\n    thoughtbot are creators of the open-sourced testing tools FactoryGirl and Shoulda Matchers.\n    We recognize Test-Driven Development (TDD) can be difficult to practice as features increase in complexity. Testing is often skipped when developers feel uncomfortable with TDD or have not yet seen certain approaches in practice.\n    We'll describe specific techniques used in TDD which touch on: Integration testing with RSpec+Capybara, Model Associations and Data Validations, Asynchronous Jobs, Emails, 3rd Party Services, and JSON API endpoints.\n  video_provider: \"youtube\"\n  video_id: \"sj5TXzgZ1Sk\"\n\n- id: \"adam-sanderson-railsconf-2013\"\n  title: \"Postgres, the Best Tool You're Already Using\"\n  raw_title: \"Rails Conf 2013 Postgres, the Best Tool You're Already Using by Adam Sanderson\"\n  speakers:\n    - Adam Sanderson\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-23\"\n  description: |-\n    Your fledgling social network for hedgehogs is starting to gain traction, but now new feature requests are pouring in. How you can you meet the demands of an ambitious product team within your existing stack? There's no time to waste, so we will look at how to leverage the venerable Postgres workhorse.\n    We will look at some of Postgres' unique features that lend themselves to solving the problems Rails developers face when moving from v1 products to v2 and beyond. We will focus on SQL and ActiveRecord, and talk about pragmatic solutions to hairy problems. Get practical, hands-on advice about using Postgres with ActiveRecord to support tagging, model hierarchical data, store arbitrary metadata, and add full text search to your application.\n    By the end of this talk, you'll be able to go to your next meeting armed with confidence in your ability to build the ultimate hedgehog destination online.\n  video_provider: \"youtube\"\n  video_id: \"YWj8ws6jc0g\"\n\n- id: \"jon-dahl-railsconf-2013\"\n  title: \"Designing great APIs: Learning from Jony Ive, Orwell, and the Kano Model\"\n  raw_title: \"Rails Conf 2013 Designing great APIs: Learning from Jony Ive, Orwell, and the Kano Model\"\n  speakers:\n    - Jon Dahl\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-23\"\n  description: |-\n    By Jon Dahl\n\n    APIs are interfaces, just like UIs. But while a website or a mobile app is designed to be used by a consumer, an API has two very specific audiences in mind: other systems, and the programmers who build them.\n    A well-designed API can make or break an application. So how do developers build great APIs? What design principles should be followed? We will discuss these questions based on the work of thinkers in the areas of industrial design, writing, and product design theory.\n  video_provider: \"youtube\"\n  video_id: \"RfueDq8-Wwg\"\n\n- id: \"andrew-cantino-railsconf-2013\"\n  title: \"Introducing Brainstem, your companion for rich Rails APIs\"\n  raw_title: \"Rails Conf 2013 Introducing Brainstem, your companion for rich Rails APIs\"\n  speakers:\n    - Andrew Cantino\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-23\"\n  description: |-\n    Backbone applications.\n    All of this is designed to reduce network requests and simplify development of HTML5 applications, especially mobile ones. With Backbone + Brainstem, loading a hierarchy of objects from your server can be reduced to one line of code and one network request.\n    This talk will survey Brainstem usage in Rails, then dive into how it can enable rich mobile HTML5 applications.\n  video_provider: \"youtube\"\n  video_id: \"MDNbcpHrVJk\"\n\n- id: \"bryan-woods-railsconf-2013\"\n  title: \"Split Testing for Product Discovery\"\n  raw_title: \"Rails Conf 2013 Split Testing for Product Discovery by Bryan Woods\"\n  speakers:\n    - Bryan Woods\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    In this talk, we'll explore split testing as a way to not only increase revenue and conversion through simple, surface-level changes, but also to dig deeper in order to help guide a product's roadmap by discovering which features customers really want and how much they're willing to pay.\n  video_provider: \"youtube\"\n  video_id: \"5hgNaSVDkEs\"\n\n- id: \"kevin-burke-railsconf-2013\"\n  title: \"How to Write Documentation for People That Don't Read\"\n  raw_title: \"Rails Conf 2013 How to Write Documentation for People That Don't Read\"\n  speakers:\n    - Kevin Burke\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    Usability researchers have known for years that people browsing the Internet\n    don't read things word by word - they scan pages for the content they want. Yet\n    many API's and documentation resources are written as though users are reading\n    every word. If busy users can't find what they are looking for, you'll have\n    more support tickets (an expense), or more frustration (lost revenue).\n    Writing effective documentation requires knowing who your users are and how\n    they are finding answers to their questions. In this presentation, we'll\n    examine practical techniques to make your documentation work for busy users.\n    Looking at examples and user testing from our experience at Twilio, attendees will learn:\n    - how users find (or fail to find) your documentation\n    - how users view and get started (or fail to get started) with your product\n    - how to take advantage of underused documentation tools like your error messages, your API, and SEO.\n  video_provider: \"youtube\"\n  video_id: \"cC67PzBgRYE\"\n\n- id: \"thomas-meeks-railsconf-2013\"\n  title: \"Delicious Controversy: Docs & Tests\"\n  raw_title: \"Rails Conf 2013 Delicious Controversy: Docs & Tests by Thomas Meeks\"\n  speakers:\n    - Thomas Meeks\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    Self-documenting code is a pipe dream. TDD (or BDD) is not the panacea of testing. In the pursuit of test coverage we've forgotten what really matters: getting things done. Lets talk about putting documentation and testing into their proper place. Tools that ease maintenance, help other developers join a project, and reduce bugs.\n    I'm going to go over lessons learned in writing, maintaining, and introducing new developers to 20,000 lines of code. Specifically, how we are testing, documenting, and refactoring our code to stay sane, make the team happier, and get more done.\n\n  video_provider: \"youtube\"\n  video_id: \"9md-GTF_Th8\"\n\n- id: \"lionel-barrow-railsconf-2013\"\n  title: \"What Ruby Developers Can Learn From Go\"\n  raw_title: \"Rails Conf 2013 What Ruby Developers Can Learn From Go by Lionel Barrow\"\n  speakers:\n    - Lionel Barrow\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    Go has rapidly built a reputation as a great language for web development. But as Rails developers, we already have a really, really great language for web development -- why should we be interested in Go?\n    I'm convinced that every web developer would benefit from exposure to the Go approach to programming, which places a strong emphasis on up-front error handling and modular, namespaced libraries. Let's sit down and compare some code!\n    In this talk, we will:\n    * Compare idiomatic approaches to common problems such as error handling, dependency management and testing in Go and Ruby.\n    * Think carefully about tradeoffs between different programming styles and examine how programming languages encourage one style or another.\n    * Tease out common ideas and best practices that apply to all web applications, regardless of language or framework.\n    * Read a bunch of code.\n    We will not:\n    * Try to convince anyone to ditch Ruby/Rails and embrace Go.\n    * Make vague, unsubstantiated claims about the benefits of static or dynamic typing.\n    * Assume any prior knowledge of Go.\n  video_provider: \"youtube\"\n  video_id: \"-zz-byus8DA\"\n\n- id: \"george-brocklehurst-railsconf-2013\"\n  title: \"Sleeping with the enemy..\"\n  raw_title: \"Rails Conf 2013 Sleeping with the enemy.. by George Brocklehurst\"\n  speakers:\n    - George Brocklehurst\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    In this session we'll go off the Rails and take a look at what our Pythonista cousins are doing with Django.\n    I'll start with some live coding: recreating DHH's infamous 15 minute blog demo using Django and explaining the building blocks of a Django app along the way. I'll then take that app and use it to look at some design decisions Django makes, and how they compare to Rails. You'll see convention over configuration in places you didn't expect it, why Django doesn't need attr_accessible or strong parameters, and how the template method pattern could change your life.\n    Why talk about Python at a Rails conference? Seeing another way of doing things forces us to think about what we're doing, challenges or validates the assumptions we make about our work, and inspires us to try new things.\n\n  video_provider: \"youtube\"\n  video_id: \"K6sRwQuWNLg\"\n\n- id: \"stefan-wintermeyer-railsconf-2013\"\n  title: \"Cache=Cash!\"\n  raw_title: \"Rails Conf 2013 Cache=Cash! by Stefan Wintermeyer\"\n  speakers:\n    - Stefan Wintermeyer\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    Snappiness is an important key for any successful webpage. Most companies try to achieve responsive webshops by scaling their hardware big time. But Rails in combination with Nginx, Memcached and Redis is the key to deliver webpages very fast with a minimal amount of hardware. This talk will start with the basics of DHH's russian doll idea but will raise the bar than quite a bit. How can we combine fragment caching, page caching and HTTP caching to deliver personalized webshop pages for logged in users? How much brain can be delegated to Redis or the Webbrowser? Harddrive space is cheap. So use it! You'll get to know how to plan your data structure and where to use Memcached vs. Redis. Include the cache in the beginning of your development and not in the end. To make things a bit more interesting everything is replayed on a Raspberry Pi to show how much difference intelligent caching can make on any hardware. Save big time and get more clients with a faster web application!\n\n  video_provider: \"youtube\"\n  video_id: \"7uKxDVflXdI\"\n\n- id: \"sebastian-delmont-railsconf-2013\"\n  title: \"Of Buyers And Renters and keeping a roof over our heads\"\n  raw_title: \"Rails Conf 2013 Of Buyers And Renters and keeping a roof over our heads by Sebastian Delmont\"\n  speakers:\n    - Sebastian Delmont\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    What do home ownership and leveraged buyouts can teach us about how to use technical debt to our advantage? How can we sleep soundly at night when we have accumulated mountains and mountains of technical debt? When is good enough good enough and when are we just deceiving ourselves?\n\n  video_provider: \"youtube\"\n  video_id: \"XakfJ2spb3w\"\n\n- id: \"conrad-irwin-railsconf-2013\"\n  title: \"Pry-- The Good Parts!\"\n  raw_title: \"Rails Conf 2013 Pry-- The Good Parts! by Conrad Irwin\"\n  speakers:\n    - Conrad Irwin\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    Pry is the featureful development console for Ruby. From its humble roots as an irb replacement, Pry has grown into an indispensable tool for any Ruby or Rails programmer.\n    Using some real-life examples, I'll explain how to use Pry effectively.\n    We'll start from the beginning, with simple features for exploring libraries and source-code in glorious technicolor. Then we'll move up a level and discuss how to inspect, debug and even modify a program while it is still running. Finally we'll touch on some of Pry's more advanced plugins that can really help you get a feel for what your code is doing.\n\n  video_provider: \"youtube\"\n  video_id: \"jDXsEzOHb2M\"\n\n- id: \"casey-rosenthal-railsconf-2013\"\n  title: \"Data Storage: NoSQL Toasters and a Cloud of Kitchen Sinks\"\n  raw_title: \"Rails Conf 2013 Data Storage: NoSQL Toasters and a Cloud of Kitchen Sinks\"\n  speakers:\n    - Casey Rosenthal\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    What is the best data storage option for your application? We have an abundance of conventional wisdom when it comes to building applications on top of a relational database in the Ruby world. Building an application on top of a NoSQL database is a different story. I will present a conceptual framework for understanding Access Patterns that jives with properties of databases, then review common NoSQL databases and propose considerations for choosing one over another. I will also review some uncommon NoSQL databases that address common use cases, and suggest that perhaps some of these should be used more often. Most importantly, I will describe the different state of mind that you should have when building applications on top of these NoSQL options, and provide visualization of non-relational concerns like: fault tolerance, availability, consistency, capacity planning, and horizontal vs vertical scaling. Whether or not you choose a NoSQL option for a future project, you won't look at data storage options in the same way after this presentation. ;-)\n  video_provider: \"youtube\"\n  video_id: \"zw050fRE0ek\"\n\n- id: \"ernie-miller-railsconf-2013\"\n  title: \"An Intervention for ActiveRecord\"\n  raw_title: \"Rails Conf 2013 An Intervention for ActiveRecord by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    Let's be honest: ActiveRecord's got issues, and it's not going to deal with them on its own. It needs our help.\n    Don't think so? Let's take a closer look together. We'll examine the myriad of perils and pitfalls that await newbie and veteran alike, ranging from intentionally inconsistent behavior to subtle oddities arising from implementation details.\n    Of course, as with any intervention, we're only doing this because we care. At the very least, you'll learn something you didn't know about ActiveRecord, that helps you avoid these gotchas in your applications. But I hope that you'll leave inspired to contribute to ActiveRecord, engage in discussion about its direction with the core team, and therefore improve the lives of your fellow Rails developers.\n    WARNING: We will be reading the ActiveRecord code in this talk. Not for the faint of heart.\n  video_provider: \"youtube\"\n  video_id: \"yuh9COzp5vo\"\n\n- id: \"david-padilla-railsconf-2013\"\n  title: \"From Rails to the Web Server to the Browser\"\n  raw_title: \"Rails Conf 2013 From Rails to the Web Server to the Browser by David Padilla\"\n  speakers:\n    - David Padilla\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    Most of us know how to build beautiful web applications with Rails. With the help of templating tools like ERB and HAML our web apps create HTML documents, but, do you know exactly how those HTML documents end up in a browser?\n    During this talk I will show you the bits that make it all happen. We will dissect the relevant code within Rails, Rack and the thin web server to discover exactly how the web server starts and listens to a TCP port, communicates with Rails and returns the HTML document that your browser parses.\n    Why? Because we're curious about it, that's why.\n\n    https://github.com/dabit/rails-server-browser\n  video_provider: \"youtube\"\n  video_id: \"A0M4BwYrYiA\"\n  slides_url: \"https://speakerdeck.com/dabit/from-rails-to-the-webserver-to-the-browser\"\n  additional_resources:\n    - name: \"dabit/rails-server-browser\"\n      type: \"repo\"\n      url: \"https://github.com/dabit/rails-server-browser\"\n\n- id: \"sandi-metz-railsconf-2013\"\n  title: \"The Magic Tricks of Testing\"\n  raw_title: \"Rails Conf 2013 The Magic Tricks of Testing by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  slides_url: \"https://speakerdeck.com/skmetz/magic-tricks-of-testing-railsconf\"\n  description: |-\n    Tests are supposed to save us money. How is it, then, that many times they become millstones around our necks, gradually morphing into fragile, breakable things that raise the cost of change?\n    We write too many tests and we test the wrong kinds of things. This talk strips away the veil and offers simple, practical guidelines for choosing what to test and how to test it. Finding the right testing balance isn't magic, it's a magic trick; come and learn the secret of writing stable tests that protect your application at the lowest possible cost.\n\n  video_provider: \"youtube\"\n  video_id: \"URSWYvyc42M\"\n\n- id: \"noel-rappin-railsconf-2013-rails-vs-the-client-side\"\n  title: \"Rails Vs. The Client Side\"\n  raw_title: \"Rails Conf 2013 Rails Vs. The Client Side by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-22\"\n  description: |-\n    Two completely different ways have emerged for using Rails as the back end to a rich client-side JavaScript application.\n    * The 37Signals \"Russian Doll\" approach, where the server generally returns HTML to the client. This approach uses aggressive caching and a little bit of JavaScript glue to keep the application fast.\n    * The \"Rails API\" approach, where the server generally returns JSON to the client, and a JavaScript MVC framework handles the actual display.\n    Which of these will work for you?\n    We will look at code to see the structural difference between these two approaches and see what the speed, extensibility, and maintainability trade-offs are. At the end of the talk, you will be better equipped to chose a structure for your next rich-client application.\n  video_provider: \"youtube\"\n  video_id: \"qeI25OjHyDA\"\n\n- id: \"jesse-wolgamott-railsconf-2013\"\n  title: \"Rails is Just Ruby\"\n  raw_title: \"Rails Conf 2013 Rails is Just Ruby by Jesse Wolgamott\"\n  speakers:\n    - Jesse Wolgamott\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-21\"\n  description: |-\n    Rails: the result of magical incantations, voodoo, and wizardry? Or: a collection of patterns from the most awesomest language in the world (Ruby)? We'll show three different areas of Rails that seem to be the most magical: before_filters and callbacks, Procs, and inheritance. In the workshop, participants will create their own Ruby object implementing these magical powers.\n  video_provider: \"youtube\"\n  video_id: \"Nqr_j4j26Uk\"\n\n- id: \"brian-sam-bodden-railsconf-2013\"\n  title: \"BDD and Acceptance Testing with RSpec & Capybara\"\n  raw_title: \"Rails Conf 2013 BDD and Acceptance Testing with RSpec & Capybara\"\n  speakers:\n    - Brian Sam-Bodden\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-21\"\n  description: |-\n    Behavior-Driven Development and Acceptance Testing are heavily intertwined and in many aspects are one and the same. Both focus on starting at the outer layers of your application by concentrating on what matter to users; behavior. In this session/workshop we'll talk about how testing can be used both for specifying your application yet to be develop expected behavior and as accurate, running documentation that can be used to validate your stakeholder's acceptance criteria. We'll talk about the different types of testing and do a few hands-on exercises to flesh out a Rails application with RSpec and Capybara.\n  video_provider: \"youtube\"\n  video_id: \"BG_DDUD4M9E\"\n\n- id: \"christopher-greene-railsconf-2013\"\n  title: \"Rails for Zombies: Parts 1 & 2\"\n  raw_title: \"Rails Conf 2013 Rails for Zombies: Parts 1 & 2\"\n  speakers:\n    - Christopher Greene\n    - Aimee Simone\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-21\"\n  description: |-\n    Workshop with Christopher Greene & Aimee Simone\n  video_provider: \"youtube\"\n  video_id: \"4Vk4W767lak\"\n\n- id: \"christopher-greene-railsconf-2013-how-a-request-becomes-a-respon\"\n  title: \"How a Request Becomes a Response\"\n  raw_title: \"Rails Conf 2013 How a Request Becomes a Response\"\n  speakers:\n    - Christopher Greene\n    - Aimee Simone\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-21\"\n  description: |-\n    By Christopher Greene & Aimee Simone\n\n    Ever wondered what Rails is doing behind the scenes? What happens to an HTTP request after it leaves your browser? How does Rails process the response?\n    In this beginner talk, Aimee Simone and Christopher Green break down the request/response cycle of a web application, navigating through the magestic internals of Rails. We'll outline the responsibilities of each Rails component, including its MVC framework and RESTful routing concepts. By following the flow from a client HTTP request to a completed server response, you'll gain a better understanding of the anatomy of a Rails application.\n\n  video_provider: \"youtube\"\n  video_id: \"Cj2VDSugHM8\"\n\n- id: \"patrick-robertson-railsconf-2013\"\n  title: \"Building Extractable Libraries in Rails\"\n  raw_title: \"Rails Conf 2013 Building Extractable Libraries in Rails by Patrick Robertson\"\n  speakers:\n    - Patrick Robertson\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-20\"\n  description: |-\n    The Ruby on Rails developer faces an interesting duality. Their inner Rubyist is driven by a sense of beauty and explores a wide range of ways to solve a problem. The inner Railser is driven by a strong set of conventions and is guided by the Rails Way™. The /lib directory is where these developers meet and end result is a junk drawer of awkward code.\n    In this talk, I go over a few ways to keep this junk drawer problem from happening by adding some conventions I've created from building Rails in anger:\n    * Treat /lib as a temple (keep /lib in a state to extract to a gem in minutes)\n    * Avoid autoloading everything in /lib\n    * Use configuration to hide credentials from your library code\n    * Isolate your Domain Objects from library concerns through DCI\n  video_provider: \"youtube\"\n  video_id: \"xXLijKrPMv4\"\n\n- id: \"brandon-black-railsconf-2013\"\n  title: \"Natural Language Processing with Ruby\"\n  raw_title: \"Rails Conf 2013 Natural Language Processing with Ruby by Brandon Black\"\n  speakers:\n    - Brandon Black\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-20\"\n  description: |-\n    The field of natural language processing and the many topics encompassed within it (summarization, full-text search, sentiment analysis, content categorization, etc.) is one of fastest growing, most complex and most highly demanded knowledge sets in the software industry today.\n    From spell checking in your SMS client to programmatically evaluating what your Twitter followers think of you, there is no shortage of real-world text processing and linguistic analysis problems all around us waiting to be solved. As Rubyists and software engineers, its important for us to know what tools related to NLP are available to us and how we can make use of them most effectively.\n\n    While there are a number of really great open-source libraries for natural language processing in Ruby and many great strides have been made in recent years, there's still often a need to leverage tools and libraries externally from the Ruby ecosystem. Some of the best open-source NLP frameworks available rely very heavily on contributions from the academic world where Ruby as a language doesn't have the same presence as other languages like Python or Java.\n    In this talk, I'll provide a beginner friendly introduction to NLP in general and I'll give a quick overview of the tools and related projects that are currently available in the Ruby community. In addition, using real-world examples I'll demonstrate how to painlessly leverage high performance, mature and well-established NLP libraries directly from your Ruby application using JRuby and JDK 7.\n  video_provider: \"youtube\"\n  video_id: \"JznIgC5_h4M\"\n\n- id: \"luke-francl-railsconf-2013\"\n  title: \"Front-end Testing for Skeptics\"\n  raw_title: \"Rails Conf 2013 Front-end Testing for Skeptics By Luke Francl\"\n  speakers:\n    - Luke Francl\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-20\"\n  description: |-\n    Paul Graham once quipped that \"Web 2.0\" really meant \"JavaScript now works\". Nearly ten years later, more and more functionality of our web applications is written in JavaScript. But for those of us who came of age when JavaScript was unreliable, it's been preferable to test the server-side, while leaving the UI a thin-as-possible shell. Testing the front-end was error prone and brittle.\n    However, when you're delivering a JavaScript widget hundreds of thousands of times a day on diverse third party websites, it needs to work. So: we need to test it, and those tests need to be as painless as possible to write and maintain.\n    This is a session for front-end testing skeptics (like me): It is possible to create tests that drive your web UI (JavaScript and all) that are automated, fast, reliable, headless -- no browser required -- and written in pure Ruby instead of some obtuse syntax. We'll explore the challenges and gotchas of testing the front-end and walk through an example that meets the above goals.\n  video_provider: \"youtube\"\n  video_id: \"9GO7XGmv5gk\"\n\n- id: \"shai-rosenfeld-railsconf-2013\"\n  title: \"Testing HTTP APIs in Ruby\"\n  raw_title: \"Rails Conf 2013 Testing HTTP APIs in Ruby by Shai Rosenfeld\"\n  speakers:\n    - Shai Rosenfeld\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: |-\n    Good integration tests are hard. There are many approaches for testing server/client HTTP libraries - all with various tradeoffs and problems that come up. Some are obvious, some are a little more tricky.\n    I'll run through some approaches and problems I've come across developing server/client APIs, while developing these in a highly distributed systems setup at Engine Yard.\n  video_provider: \"youtube\"\n  video_id: \"lTSl7IwbrvI\"\n\n- id: \"brendan-loudermilk-railsconf-2013\"\n  title: \"Maintainable Templates\"\n  raw_title: \"Rails Conf 2013 Maintainable Templates by Brendan Loudermilk\"\n  speakers:\n    - Brendan Loudermilk\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: |-\n    Unwieldy templates (a.k.a. views) are all too common in Rails apps, even among teams that otherwise craft high-quality code. Being brought into or having to maintain a project with poorly-crafted templates leads to extreme frustration and less than-adequite-velocity. At philosophie, we have started to use a few simple patterns that result in templates that are easier to maintain. By investing a small amount of time up-front learning and applying these patterns we have saved countless hours in the long run.\n    Topics include:\n    * The Decorator Pattern\n    * Using View objects\n    * Sanely building forms\n    * And more!\n  video_provider: \"youtube\"\n  video_id: \"elRlAjtaFsg\"\n\n- id: \"andrew-bloomgarden-railsconf-2013\"\n  title: \"Changing the wheels on the bus at 80 mph: Upgrading to Rails 3 on an active master branch\"\n  raw_title: \"Rails Conf 2013 Changing the wheels on the bus at 80 mph: Upgrading to Rails 3\"\n  speakers:\n    - Andrew Bloomgarden\n    - Julian Giuca\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: |-\n    Long-running branches are painful, but upgrading to Rails 3 requires one if you can't stop development, right? Wrong! At New Relic, we worked on upgrading to Rails 3 on master while letting development continue in Rails 2. We patched Bundler, built a backwards-compatible boot sequence, and punched ActiveScaffold in the face. Other developers, meanwhile, released 1400 commits worth of work without noticing any changes. We'll talk about what we did, why we did it, and why we think this approach can help developers get over the hurdle into the Rails 3 promised land.\n  video_provider: \"youtube\"\n  video_id: \"xi7z-vGNNGw\"\n\n- id: \"pat-allan-railsconf-2013\"\n  title: \"A Guide to Crafting Gems\"\n  raw_title: \"Rails Conf 2013 Crafting Gems by Pat Allan\"\n  speakers:\n    - Pat Allan\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-06-03\"\n  description: |-\n    You understand Ruby and Rails, and you've gotten the hang of using other peoples' gems - but what about writing your own? Gems underpin almost every piece of Ruby code we write - and so, being able to craft your own gems is not only incredibly useful, it provides an avenue for code reuse and open source sharing. During this session, Pat will first discuss the ecosystem around gems and the knowledge required to write your own, plus a few tools available to assist with this, and some approaches for how to structure gems that integrate with Rails itself. The workshop will then put this knowledge into practice by building our own gems from scratch.\n  video_provider: \"youtube\"\n  video_id: \"Mmm1cVvPEYU\"\n\n- id: \"jim-jones-railsconf-2013\"\n  title: \"No Traffic, No Users, No Problem! - Usability Testing for New Apps\"\n  raw_title: \"Rails Conf 2013 No Traffic, No Users, No Problem! - Usability Testing for New Apps\"\n  speakers:\n    - Jim Jones\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-31\"\n  description: |-\n    Building a web app consists of stressful choices. Should the signup button be red or blue? Does my site's sales pitch sound awkward? What will the user think about my site the first five seconds they visit?\n    Using Rails and Amazon's Mechanical Turk service, I will show you how you can perform usability tests, A/B testing and gain valuable feedback on your site BEFORE launching your app to a single real user.\n\n    I'll walk you through:\n\n    1) Sample code for quickly integrating your Rails site with Mechanical Turk\n    2) How to structure your HITs (Human Intelligence Tasks) so that you solicit detailed feedback from the workers.\n    3) Integrating A/B testing so that you can quickly decide which design component is better\n    4) Tactics for stopping automated bots from ruining your usability tests\n  video_provider: \"youtube\"\n  video_id: \"pCOuOxFRajQ\"\n\n- id: \"chris-kelly-railsconf-2013\"\n  title: \"Object-Oriented Lessons for a Service-Oriented World\"\n  raw_title: \"Rails Conf 2013 Object-Oriented Lessons for a Service-Oriented World\"\n  speakers:\n    - Chris Kelly\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-30\"\n  description: |-\n    The dreams of developers working on monolithic Rails applications are frequently filled with sugar plums and service-oriented architectures--but like any kind of software design, SOA can easily become a tangled mess. Many of the same principles that guide our software design can guide our architecture design. We apply SOLID principles to applications to keep them loosely coupled, we design interfaces so we can send logical messages to our domain objects. We hide our databases behind abstractions because how we access our data shouldn't matter to how we consume it. Rarely, though, do we see the same practices applied to our services and APIs, leaving us with tightly coupled and difficult to extend service-oriented architectures. If you are facing the monorail to SOA challenge, consider looking at your services as objects and your APIs as messages. Service-oriented applications are complex, and the best way to fend off complexity is though object-oriented design.\n  video_provider: \"youtube\"\n  video_id: \"sk2PXKsQNug\"\n\n- id: \"rebecca-miller-webster-railsconf-2013\"\n  title: \"Incremental Design - A conversation with a designer and a developer\"\n  raw_title: \"Rails Conf 2013 Incremental Design - A conversation with a designer and a developer\"\n  speakers:\n    - Rebecca Miller-Webster\n    - Savannah Wolf\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-30\"\n  description: |-\n    Developers: how many times have you had to completely rip out your hard earned code for a totally new site design?\n    Designers: how many times has a re-design taken 4 times as long as the developer said it would and not looked good in the end?\n    Change all that by using an incremental approach to design. Set up your code to change all the buttons at once or prioritize design changes to make each small change good enough for production.\n    A designer and developer will talk about the challenges and joys of making this process work in two production sites.\n    Topics covered:\n    * What is incremental design?\n    * How to design with incremental changes in mind\n    * How to develop for incremental design, including utilizing SASS, structuring your mark-up and CSS, and structuring your Rails views and partials\n  video_provider: \"youtube\"\n  video_id: \"t97ePwSk_wc\"\n\n- id: \"daniel-azuma-railsconf-2013\"\n  title: \"Humanity On Rails\"\n  raw_title: \"Rails Conf 2013 Humanity On Rails by Daniel Azuma\"\n  speakers:\n    - Daniel Azuma\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-30\"\n  description: |-\n    We hear the stories every so often. A study concludes that internet usage is making us \"dumber\", while another connects online activity to anxiety or depression. A respected journalist questions whether our advanced technology is really improving our lives. A mass movement of people deleting their Facebook or Twitter accounts sweeps through the community.\n    As developers, we hear these stories, and we shrug. Luddites and fearmongers, we call them. But don't they have a point? Do we truly understand what technology is, and how it impacts our society, the way we think and what we value? An important conversation is taking place. As Rails developers, as professionals working on the cutting edge of consumer technology, we should be involved.\n    This talk is a brief introduction to the philosophy of technology. We'll examine a few of the major views-- the writings of the philosophers, academics, and engineers who are asking questions regarding technology and society. We'll also explore what these questions mean for us as developers, what they can tell us about our profession, and what we can uniquely contribute to the conversation. We may not find a lot of solid answers, but we'll plow a rich field for discussion, and maybe gain a new perspective into just what it is that we spend our time doing.\n\n    https://daniel-azuma.com/articles/talks/railsconf-2013\n  video_provider: \"youtube\"\n  video_id: \"elxE-WBXs_k\"\n  slides_url: \"https://speakerdeck.com/dazuma/humanity-on-rails\"\n\n- id: \"aaron-patterson-railsconf-2013\"\n  title: \"Closing Keynote: A ♭\"\n  raw_title: \"Rails Conf 2013 Closing Keynote by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5kgUL_FfUZY\"\n\n- id: \"emily-stolfo-railsconf-2013\"\n  title: \"Hacking the academic experience\"\n  raw_title: \"Rails Conf 2013 Hacking the academic experience by Emily Stolfo\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-29\"\n  description: |-\n    Coming from a hacker background, I've continually been surprised by how frequently new grads lacked the skills needed, particularly in community learning. When I was asked to teach Ruby on Rails at Columbia University I observed that a significant number of the skills required to become successful professionals in the industry are acquired on the job and aren't being taught in school.\n    This presentation will review:\n    - Lessons learned from the experience teaching in my alma mater's CS program.\n    - How I developed a hacker-centric curriculum teaching not only the algorithms, but the keys to being a successful developer in the modern open source driven Rails community.\n    - How we as hackers can fix this.\n  video_provider: \"youtube\"\n  video_id: \"a0teD9ynuTM\"\n\n- id: \"jesse-wolgamott-railsconf-2013-the-long-ball-upgrading-long-l\"\n  title: \"The Long Ball - Upgrading long lived Rails apps from 1.x-4.0\"\n  raw_title: \"Rails Conf 2013 The Long Ball - Upgrading long lived Rails apps from 1.x-4.0\"\n  speakers:\n    - Jesse Wolgamott\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-29\"\n  description: |-\n    Explore tips to upgrade from each major version to the other, and how to efficiently tackle a 1.2 to 4.0 upgrade through two different case studies.\n    The velocity of change for Rails versions has a side effect -- businesses hesitate to update to the latest version until their productivity drops and they're forced to update. What happens then? Let's explore a case study of a Rails app that followed this pattern.\n  video_provider: \"youtube\"\n  video_id: \"97fpzfRGTcs\"\n\n- id: \"brian-sam-bodden-railsconf-2013-tdding-ios-apps-for-fun-and-pr\"\n  title: \"TDDing iOS Apps for fun and profit with RubyMotion\"\n  raw_title: \"Rails Conf 2013 TDDing iOS Apps for fun and profit with RubyMotion\"\n  speakers:\n    - Brian Sam-Bodden\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-29\"\n  description: |-\n    As Ruby Developer I've had a pretty involved relationship with my Mac. I own iPads and iPhones since Apple started to make them. A few years back I told myself I was going to build apps for the Mac/iPhone/iPad but then reality sunk in when I started learning Objective-C and using XCode. The environment (and the language) felt like a trip back to 1995.\n    If you are a Web developer used to working with dynamically-typed, lightweight languages, following agile practices like Test-Driven Development, and comfortable with a Unix Shell, then jumping into a development world with an ugly cousin of C++ and an IDE that looks like an F16 cockpit just doesn't seem appealing.\n    Luckily for us there is an alternative in RubyMotion, a Ruby-based toolchain for iOS that brings a Ruby on Rails style of development to the world of iOS application development.\n    In this talk I will show you how you can use well engrained Ruby practices like TDD to build iOS Apps with RubyMotion.\n  video_provider: \"youtube\"\n  video_id: \"7v3_t5SK8DM\"\n\n- id: \"yoko-harada-railsconf-2013\"\n  title: \"Datomic, from Ruby, from Rails\"\n  raw_title: \"Rails Conf 2013 Datomic, from Ruby, from Rails by Yoko Harada\"\n  speakers:\n    - Yoko Harada\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-29\"\n  description: |-\n    Datomic is a new database categorized as NewSQL and was created by Rich Hickey. Everybody knows this big name and thinks of Clojure. It is true Datomic fits well to Clojure programming. However, it is not only for Clojure people.\n    Absolutely, Rubyists can use it. We have Diametric gem (https://github.com/relevance/diametric). Using Diametric, we can dive into Datomic from Ruby, from Rails.\n    On Diametric, Datomic's entity is an ActiveModel compliant. Diametric supports Rails' scaffolding. Its usage might look like Datamapper or MongoDB. Eventually, Diametric's API design settled in a bit far from Ruby, Rails style. In another word, it is not ORM-like. Even though the API design may puzzle Rubyists, Diametric chose the one to expose Datomic's intrinsic properties. It is to leverage a good side of Datomic for us. I believe the more Rubyists use Diametric, the more they like it.\n    In my talk, I'll introduce Diametric gem and how to use it as well as why its API design is good for us. Also, I will cover how Ruby helped to integrate Datomic API in Diametric gem.\n  video_provider: \"youtube\"\n  video_id: \"1E_n47ct280\"\n  additional_resources:\n    - name: \"relevance/diametric\"\n      type: \"repo\"\n      url: \"https://github.com/relevance/diametric\"\n\n- id: \"richard-schneeman-railsconf-2013\"\n  title: \"Dissecting Ruby with Ruby\"\n  raw_title: \"Rails Conf 2013 Dissecting Ruby with Ruby by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-29\"\n  description: |-\n    Underneath the beautiful veneer of our Ruby libraries lies a twisted tangle of writhing guts. Maybe you're curious how the pieces fit together or maybe you're tracking down a bug, either way it's easy to get lost in the blood and bile that ties our code together. In this talk you'll learn how to use simple and sharp Ruby tools to slice into large libraries with surgical precision. We'll do some live hacking on Rails on the stage and cover useful code probing techniques. Turn your impossible bugs into pull requests, and level up your programming skills by Dissecting Ruby with Ruby.\n  video_provider: \"youtube\"\n  video_id: \"Zd2oUU4qDnY\"\n  slides_url: \"https://speakerdeck.com/schneems/dissecting-ruby-with-ruby\"\n\n- id: \"ben-orenstein-railsconf-2013\"\n  title: \"How to Talk to Developers\"\n  raw_title: \"Rails Conf 2013 How to Talk to Developers by Ben Orenstein\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-29\"\n  description: |-\n    Nearly every developer will be asked to present to his or her peers at some point. Those that do it well will tend to have an outsized influence on their team, company, and community.\n    This talk will demonstrate (mostly by example) the straightforward techniques for giving excellent presentations, from a veteran conference speaker and teacher.\n    Topics to cover include:\n    * Phrases that turn your audience against you.\n    * Basic body language tips that affect perception.\n    * How to be more interesting than the internet.\n    * The power of live coding and demos.\n    * Being funny without resorting to reddit memes.\n    * How to get plenty of questions during Q&A.\n    * How to get an unfair amount of talk acceptances (aka 'Bribing conference organizers').\n  video_provider: \"youtube\"\n  video_id: \"l9JXH7JPjR4\"\n\n- id: \"gregg-pollack-railsconf-2013\"\n  title: \"Ruby Hero Awards 2013\"\n  raw_title: \"Rails Conf 2013 Ruby Hero Awards\"\n  speakers:\n    - Gregg Pollack # Host\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-29\"\n  description: |-\n    We believe great work deserves recognition. The Ruby/Rails dev community is full of amazing contributors and unsung heroes who are busy producing educational content, developing plugins and gems, contributing to open-source projects, or putting on events to help developers learn and grow.\n\n    The Ruby Hero Award gives recognition to influential devs in the Ruby/Rails community and announces the winners at RailsConf.\n  video_provider: \"youtube\"\n  video_id: \"wfy_ctBaU2o\"\n\n- id: \"lightning-talks-railsconf-2013\"\n  title: \"Lightning Talks\"\n  raw_title: \"Rails Conf 2013 Lightning Talks\"\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"4T24oUPPaFI\"\n  talks:\n    - title: \"Lightning Talk: Nick Quaranto\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"nick-quaranto-lighting-talk-railsconf-2013\"\n      video_id: \"nick-quaranto-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Nick Quaranto\n\n    - title: \"Lightning Talk: Dr. Nic Williams\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"dr-nic-williams-lighting-talk-railsconf-2013\"\n      video_id: \"dr-nic-williams-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Dr. Nic Williams\n\n    - title: \"Lightning Talk: Chris Morris\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"chris-morris-lighting-talk-railsconf-2013\"\n      video_id: \"chris-morris-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Morris\n\n    - title: \"Lightning Talk: Jon McCartie\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jon-mccartie-lighting-talk-railsconf-2013\"\n      video_id: \"jon-mccartie-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Jon McCartie\n\n    - title: \"Lightning Talk: Bryan Helmkamp\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"bryan-helmkamp-lighting-talk-railsconf-2013\"\n      video_id: \"bryan-helmkamp-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Bryan Helmkamp\n\n    - title: \"Lightning Talk: RailsFactory\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"sandal-lighting-talk-railsconf-2013\"\n      video_id: \"sandal-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: Sandal? https://cln.sh/gkL7KTfr\n\n    - title: \"Lightning Talk: Miles Forrest\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"miles-forrest-lighting-talk-railsconf-2013\"\n      video_id: \"miles-forrest-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Miles Forrest\n\n    - title: \"Lightning Talk: Andrew Harvey\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"andrew-harvey-lighting-talk-railsconf-2013\"\n      video_id: \"andrew-harvey-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Harvey\n\n    - title: \"Lightning Talk: Benjamin Fleischer\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"benjamin-fleischer-lighting-talk-railsconf-2013\"\n      video_id: \"benjamin-fleischer-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Benjamin Fleischer\n\n    - title: \"Lightning Talk: Adam Cuppy\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"adam-cuppy-lighting-talk-railsconf-2013\"\n      video_id: \"adam-cuppy-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Cuppy\n\n    - title: \"Lightning Talk: Hector Miguel Rodriguez Muñiz\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"hector-miguel-rodriguez-muniz-lighting-talk-railsconf-2013\"\n      video_id: \"hector-miguel-rodriguez-muniz-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Hector Miguel Rodriguez Muñiz\n\n    - title: \"Lightning Talk: Mario Chavez\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"mario-chavez-lighting-talk-railsconf-2013\"\n      video_id: \"mario-chavez-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Mario Chavez\n\n    - title: \"Lightning Talk: Mike Virata-Stone\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"mike-virata-stone-lighting-talk-railsconf-2013\"\n      video_id: \"mike-virata-stone-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Mike Virata-Stone\n\n    - title: \"Lightning Talk: rking\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"rking-lighting-talk-railsconf-2013\"\n      video_id: \"rking-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: actual name\n\n    - title: \"Lightning Talk: Nathan Ladd\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"nathan-ladd-lighting-talk-railsconf-2013\"\n      video_id: \"nathan-ladd-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Nathan Ladd\n\n    - title: \"Lightning Talk: Dylan Lacey\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"dylan-lacey-lighting-talk-railsconf-2013\"\n      video_id: \"dylan-lacey-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Dylan Lacey\n\n    - title: \"Lightning Talk: JC Grubbs\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jc-grubbs-lighting-talk-railsconf-2013\"\n      video_id: \"jc-grubbs-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - JC Grubbs\n\n    - title: \"Lightning Talk: TODO\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"dev-mynd-lighting-talk-railsconf-2013\"\n      video_id: \"dev-mynd-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO somebody at Dev Mynd https://cln.sh/2hLbl5Qr\n\n    - title: \"Lightning Talk: Jeremy Green\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jeremy-green-lighting-talk-railsconf-2013\"\n      video_id: \"jeremy-green-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeremy Green\n\n    - title: \"Lightning Talk: Ron Evans\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"ron-evans-lighting-talk-railsconf-2013\"\n      video_id: \"ron-evans-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Ron Evans\n\n    - title: \"Lightning Talk: Eoin Coffey\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"eoin-coffey-lighting-talk-railsconf-2013\"\n      video_id: \"eoin-coffey-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Eoin Coffey\n\n    - title: \"Lightning Talk: Doug Smith\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"doug-smith-lighting-talk-railsconf-2013\"\n      video_id: \"doug-smith-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Doug Smith\n\n    - title: \"Lightning Talk: Andrew Cantino\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"andrew-cantino-lighting-talk-railsconf-2013\"\n      video_id: \"andrew-cantino-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Cantino\n\n    - title: \"Lightning Talk: Tanin Na Nakorn\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tanin-na-nakorn-lighting-talk-railsconf-2013\"\n      video_id: \"tanin-na-nakorn-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Tanin Na Nakorn\n\n    - title: \"Lightning Talk: Philippe Creux\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"philippe-creux-lighting-talk-railsconf-2013\"\n      video_id: \"philippe-creux-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Philippe Creux\n\n    - title: \"Lightning Talk: Alex Sharp\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"alex-sharp-lighting-talk-railsconf-2013\"\n      video_id: \"alex-sharp-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Alex Sharp\n\n    - title: \"Lightning Talk: Beau Harrington\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"beau-harrington-lighting-talk-railsconf-2013\"\n      video_id: \"beau-harrington-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Beau Harrington\n\n    - title: \"Lightning Talk: TODO\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-lighting-talk-railsconf-2013-1\"\n      video_id: \"todo-lighting-talk-railsconf-2013-1\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO https://cln.sh/lNq3QwVl\n\n    - title: \"Lightning Talk: TODO\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-lighting-talk-railsconf-2013-2\"\n      video_id: \"todo-lighting-talk-railsconf-2013-2\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO https://cln.sh/522tdVd4\n\n    - title: \"Lightning Talk: Yoshiori Shoji\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"yoshiori-shoji-lighting-talk-railsconf-2013\"\n      video_id: \"yoshiori-shoji-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Yoshiori Shoji\n\n    - title: \"Lightning Talk: Winfred Nadeau\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"winfred-nadeau-lighting-talk-railsconf-2013\"\n      video_id: \"winfred-nadeau-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Winfred Nadeau\n\n    - title: \"Lightning Talk: David Padilla\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"david-padilla-lighting-talk-railsconf-2013\"\n      video_id: \"david-padilla-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - David Padilla\n\n    - title: \"Lightning Talk: Gabe Scholz\" # TODO: Missing title\n      date: \"2013-06-25\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"gabe-scholz-lighting-talk-railsconf-2013\"\n      video_id: \"gabe-scholz-lighting-talk-railsconf-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Gabe Scholz\n\n- id: \"attila-domokos-railsconf-2013\"\n  title: \"Simple and Elegant Rails Code with Functional Style\"\n  raw_title: \"Rails Conf 2013 Simple and Elegant Rails Code with Functional Style\"\n  speakers:\n    - Attila Domokos\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-29\"\n  description: |-\n    Do you have to look at Rails models with 2500 lines of code? Or 200 line methods loaded with iterators, conditionals and instance variables? Not only you, even the code author does not understand what's going on in there.\n    I'll show you how you can craft simple and beautiful Rails application by adopting functional programming inspired ideas. Say goodbye to the mess you have by constructing tiny classes and functions that you can use to build up a complex system.\n  video_provider: \"youtube\"\n  video_id: \"glU_I3Xiooc\"\n\n- id: \"james-duncan-davidson-railsconf-2013\"\n  title: \"Keynote: In a place far far away...\"\n  raw_title: \"Rails Conf 2013 Keynote by James Duncan Davidson\"\n  speakers:\n    - Duncan Davidson\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jOvWDlmufcw\"\n\n- id: \"katrina-owen-railsconf-2013\"\n  title: \"Properly Factored MVC\"\n  raw_title: \"Rails Conf 2013 Properly Factored MVC in Rails Applications\"\n  speakers:\n    - Katrina Owen\n    - Jeff Casimir\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-25\"\n  description: |-\n    Starting Rails applications is one thing, but how you apply the priciples of MVC as an application grows determine whether your application is modular and maintainable or a convoluted mess. In this session, we'll use an existing application to explore and practice some of the common mistakes, correct techniques, and concepts behind the techniques to improve your development patterns.\n  video_provider: \"youtube\"\n  video_id: \"KaBrHBlMHBI\"\n\n- id: \"beau-harrington-railsconf-2013\"\n  title: \"Configuration Management Patterns\"\n  raw_title: \"Rails Conf 2013 Configuration Management Patterns by Beau Harrington\"\n  speakers:\n    - Beau Harrington\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-25\"\n  description: |-\n    As your simple Rails app grows into a larger system or set of systems, using simple constants and Yaml files for configuration may no longer suffice. The meaning of 'configuration' expands to include business logic alongside the customary hostnames and timeout intervals; the rate at which configuration changes are required increases; non-engineers begin to require the ability to make configuration changes themselves; different environments require different configurations. This presentation will examine several patterns that can be applied to handle these issues, keeping iteration team high and reducing the burden on your engineering team. We'll create and iterate on a simple game as a case study to illustrate the value of these principles in practice, and also look at a few open source projects that integrate some of these concepts.\n    Topics:\n    * moving configuration values out of source\n    * sharing configuration across multiple applications/services\n    * working with sensitive configuration data (eg API keys)\n    * dynamically updating configuration without deployments or restarts\n    * cascading/overlaying configuration values based on environment and context\n    * running experiments and A/B tests\n    * change control\n    * testing and multi-stage deployment of configuration changesets\n    * allowing non-developers to change configuration values\n  video_provider: \"youtube\"\n  video_id: \"MDeUgHHTiyg\"\n\n- id: \"prem-sichanugrist-railsconf-2013\"\n  title: \"Zero-downtime payment platforms\"\n  raw_title: \"Rails Conf 2013 Zero-downtime payment platforms by Prem Sichanugrist & Ryan Twomey\"\n  speakers:\n    - Prem Sichanugrist\n    - Ryan Twomey\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-25\"\n  description: |-\n    When you're building a payment platform, you want to make sure that your system is always available to accept orders. However, the complexity of the platform introduces the potential for it to go down when any one of the moving parts fails. In this talk, I will show you the approaches that we've taken and the risks that we have to take to ensure that our platform will always be available for our customers. Even if you're not building a payment platform, these approaches can be applied to ensure a high availability for your platform or service as well.\n  video_provider: \"youtube\"\n  video_id: \"uJ_38moGKGY\"\n\n- id: \"brian-morton-railsconf-2013\"\n  title: \"Services and Rails: The Sh*t They Don't Tell You\"\n  raw_title: \"Rails Conf 2013 Services and Rails: The Sh*t They Don't Tell You by Brian Morton\"\n  speakers:\n    - Brian Morton\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-25\"\n  description: |-\n    Building services and integrating them into Rails is hard. We want smaller Rails apps and nicely encapsulated services, but services introduce complexity. If you go overboard in the beginning, you're doing extra work and getting some of it wrong. If you wait too long, you've got a mess.\n    At Yammer, we constantly clean up the mess that worked well in the early days, but has become troublesome to maintain and scale. We pull things out of the core Rails app, stand them up on their own, and make sure they work well and are fast. With 20+ services, we've learned some lessons along the way. Services that seem clean in the beginning can turn into development environment nightmares. Temporary double-dispatching solutions turn into developer confusion. Monitoring one app turns into monitoring a suite of apps and handling failure between them.\n    This talk looks at our mistakes and solutions, the tradeoffs, and how we're able to keep moving quickly. Having services and a smaller Rails codebase makes for scalable development teams, happier engineers, and predictable production environments. Getting there is full of hard decisions -- sometimes we get it right, sometimes we get it wrong, but we usually have a story to tell.\n  video_provider: \"youtube\"\n  video_id: \"o5u87SZ6S9M\"\n\n- id: \"trevor-rowe-railsconf-2013\"\n  title: \"Describing Your World with Seahorse\"\n  raw_title: \"Rails Conf 2013 Describing Your World with Seahorse by Trevor Rowe\"\n  speakers:\n    - Trevor Rowe\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-25\"\n  description: |-\n    So you've just added a suite of RESTful APIs to your web service. Now you need to generate documentation and build Ruby, Python, and JavaScript clients to consume those new APIs. With so many moving parts, how do you keep your service, documentation and clients in sync?\n    We all know how to describe data using ActiveRecord models. Have you considered using a model to describe your service?\n    A service model provides a number of benefits including: easy to generate API documentation, consistent server side parameter validation, versioned APIs, easy to build clients, and more. It also represents a unified view of your API which helps to keep your code and documentation DRY. But what does a service model look like? For instance, did you know that your APIs can be described using just four parameter types? What if your could express your APIs using a Rails DSL?\n    This talk will introduce Seahorse, a DSL for describing API operations for just about any web service. It provides all of the above functionality, allowing you to describe your service model in a single place with Ruby code. We will demonstrate how to use Seahorse to generate clients, model existing real-world APIs, and even build one of our own\n  video_provider: \"youtube\"\n  video_id: \"NFhL7RhwnFU\"\n\n- id: \"mark-mcspadden-railsconf-2013\"\n  title: \"Your First Rails Pull Request\"\n  raw_title: \"Rails Conf 2013 Your First Rails Pull Request by Mark McSpadden\"\n  speakers:\n    - Mark McSpadden\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-24\"\n  description: |-\n    You have been doing this Rails thing for a while and you're starting to feel like it's time to give back. Great! Now what?\n    In this session we'll walk through the technical aspects of getting started with contributing back to Rails as well as the non-technical tips, tricks, and considerations to keep in mind along the way.\n  video_provider: \"youtube\"\n  video_id: \"UEB6H8jAzIg\"\n\n- id: \"ethan-vizitei-railsconf-2013\"\n  title: \"Firefighting on Rails\"\n  raw_title: \"Rails Conf 2013 Firefighting on Rails by Ethan Vizitei\"\n  speakers:\n    - Ethan Vizitei\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-24\"\n  description: |-\n    It's always inspiring to me to hear about how the technology stack I'm familiar with has been used to solve interesting problems; this is one of the extreme versions of that experience. Over the last few years, Rails has been used to solve several of the logistical pain points of the third largest fire service organization in the state of Missouri, and in this talk we're going to look at how it happened. Along the way we'll look at some of the challenges of working with such an out-of-the-ordinary organization and how Rails fit into addressing some fairly unique requirements and constraints. This is one Rails-in-the-wild case study that you won't want to pass up.\n  video_provider: \"youtube\"\n  video_id: \"ynLsBa0zqrU\"\n\n- id: \"aaron-pfeifer-railsconf-2013\"\n  title: \"Keeping the lights on: Application monitoring with Sensu and BatsD\"\n  raw_title: \"Rails Conf 2013 Keeping the lights on: Application monitoring with Sensu and BatsD\"\n  speakers:\n    - Aaron Pfeifer\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-24\"\n  description: |-\n    The good news: you're quickly signing up new customers, you've scaled your Rails app to a growing cluster of 10+ servers, and the business is really starting to take off. Great! The bad news: Just 30m of failures is starting to be measured in hundreds or even thousands of dollars. Who's going to make sure the lights stay on when your app is starting to fall over? Or worse, what if your app is up, but sign-ups, payments, or some other critical function is broken?\n\n    Learn how you can build a robust monitoring infrastructure using the Sensu platform: track business metrics in all of your applications, any system metric on your servers, and do so all with the help of BatsD - a time series data store for real-time needs. We'll also talk about how to look at trending data and how you can integrate Sensu against PagerDuty, RabbitMQ, or any other third-party service. Oh, and of course - everything's written in Ruby, so you can even use your favorite gems!\n  video_provider: \"youtube\"\n  video_id: \"b76GfS7x_j8\"\n\n- id: \"michael-murphy-railsconf-2013\"\n  title: \"Flattening The Cloud Learning Curve Using Rails\"\n  raw_title: \"Rails Conf 2013 Flattening The Cloud Learning Curve Using Rails by Michael Murphy\"\n  speakers:\n    - Michael Murphy\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-24\"\n  description: |-\n    We've all heard how great the cloud is - but no one likes learning a new proprietary API if they don't need to. In this session, I'll demonstrate how you can develop, test and deploy ROR apps faster to HP's public cloud based on OpenStack technology. If you are new to the cloud or if you're just a CLI commando, I'll run through HP's Ruby CLI, spin up cloud servers and attach block storage faster than you thought possible. And, for Ruby Fog fans, I'll show you the HP Ruby Fog extensions that let you easily provision and manage cloud servers and storage using your favorite environment.\n  video_provider: \"youtube\"\n  video_id: \"PbBPOG--gqI\"\n\n- id: \"terence-lee-railsconf-2013\"\n  title: \"Forget Scaling: Focus on Performance\"\n  raw_title: \"Rails Conf 2013 Forget Scaling: Focus on Performance by Terence Lee\"\n  speakers:\n    - Terence Lee\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Your customers care about how fast your application works, you should too.... At Heroku we see millions of apps deploy and we know what it takes to get serious performance out of your code and Rails. In this talk we'll cover backend tips and frontend tricks that will help your Rails app go faster than ever before.\n  video_provider: \"youtube\"\n  video_id: \"e_2s3kN0ZSE\"\n\n- id: \"edward-chiu-railsconf-2013\"\n  title: \"Engine Yard Cloud\"\n  raw_title: \"Rails Conf 2013 Engine Yard Cloud by Edward Chiu & PJ Hagerty\"\n  speakers:\n    - Edward Chiu\n    - PJ Hagerty\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-24\"\n  description: |-\n    New developments, interesting use cases and future plans. Edward will walk attendees through the dashboard and demonstrate the uses of new features such as Engine Yard Local. Whether you're a long-time Engine Yard user or just curious, this session will show you how to optimize your deployment experience.\n  video_provider: \"youtube\"\n  video_id: \"Wq0gDAi3KEk\"\n\n- id: \"john-downey-railsconf-2013\"\n  title: \"DevOps for the Rubyist Soul\"\n  raw_title: \"Rails Conf 2013 DevOps for the Rubyist Soul by John Downey\"\n  speakers:\n    - John Downey\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Ruby developers have many great options for simply hosting their web applications. But what happens when your product outgrows Heroku? Managing your own servers can be an intimidating task for the average developer. This session will cover the lessons we've learned at Braintree from building and maintaining our infrastructure. It will cover how we leverage Ruby to automate and control all of our environments. Some specific topics we'll cover:\n    * Orchestrating servers with capistrano\n    * Using puppet for configuration management\n    * Our cap and puppet workflow using git\n    * How vagrant can provide a sane test environment\n    * Some pitfalls you should avoid\n  video_provider: \"youtube\"\n  video_id: \"KmUq-SIFmgE\"\n\n- id: \"patrick-peak-railsconf-2013\"\n  title: \"Creating Mountable Engines\"\n  raw_title: \"Rails Conf 2013 Creating Mountable Engines by Patrick Peak\"\n  speakers:\n    - Patrick Peak\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-24\"\n  description: |-\n    With Rails 4.0 killing off the humble plugin, there is never a better time to learn how to create reusable code using Engines. Creating an engine can be as simple as adding a model, or a complex as an entire content management system. Using the Asset Pipeline, even javascript and css files can be packaged and shared, making projects cleaner and more maintainable than ever before.\n    This talk will cover how developers can create their own engines, to add new controllers/models/views, rake tasks and/or generators. It will cover how engines can interact with Rails having their own initializers and middleware. Finally, based on our experiences converting BrowserCMS and its entire module ecosystem to work as mountable engines, this talk will cover how to make engines that are designed to work together, extend each other engine's behavior and make it easy for developers to upgrade when you release new versions.\n  video_provider: \"youtube\"\n  video_id: \"s3NJ15Svq8U\"\n\n- id: \"jos-valim-railsconf-2013\"\n  title: \"You've got a Sinatra on your Rails\"\n  raw_title: \"Rails Conf 2013 You've got a Sinatra on your Rails by José Valim\"\n  speakers:\n    - José Valim\n  event_name: \"RailsConf 2013\"\n  date: \"2013-06-25\"\n  published_at: \"2013-05-19\"\n  description: |-\n    One of the best ways to learn is to experiment with seemingly crazy ideas. When Rails 3 first came out, it became easier than ever to embed a Sinatra application inside your Rails application. But what if you wanted to implement parts of Sinatra in Rails?\n    Have you ever wished your controllers had Sinatra style routes? Have you ever wondered if you could render a template in the same context as your controllers? What about one single-file Rails applications?\n    In this talk, we are going to build all those functionalities into a Rails application, making sure we learn about Rails internals and have fun while doing it.\n  video_provider: \"youtube\"\n  video_id: \"TslkdT3PfKc\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZ5jfnbS_osIoWzK_FrwKz5\"\ntitle: \"RailsConf 2014\"\nkind: \"conference\"\nlocation: \"Chicago, IL, United States\"\ndescription: \"\"\npublished_at: \"2014-05-05\"\nstart_date: \"2014-04-22\"\nend_date: \"2014-04-25\"\nyear: 2014\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 41.88325\n  longitude: -87.6323879\n"
  },
  {
    "path": "data/railsconf/railsconf-2014/videos.yml",
    "content": "# TODO: talks running order\n# TODO: talk dates\n\n# Website: https://web.archive.org/web/20141221191737/http://www.railsconf.com/\n# Schedule: https://web.archive.org/web/20141221191737/http://www.railsconf.com/program\n\n# https://ericbrooke.blog/2014/04/29/railsconf-2014/\n---\n- id: \"david-heinemeier-hansson-railsconf-2014\"\n  title: \"Keynote: Writing Software\"\n  raw_title: \"RailsConf 2014 - Keynote: Writing Software by David Heinemeier Hansson\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-05\"\n  published_at: \"2014-05-05\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"9LfmrkyP81M\"\n\n- id: \"justin-gordon-railsconf-2014\"\n  title: \"Concerns, Decorators, Presenters, Service Objects, Helpers, Help Me Decide!\"\n  raw_title: \"RailsConf 2014 - Concerns, Decorators, Presenters, Service Objects, Helpers, Help Me Decide!\"\n  speakers:\n    - Justin Gordon\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-05\"\n  published_at: \"2014-05-05\"\n  description: |-\n    By Justin Gordon\n\n    Let's take some tangled code and untangle it together! We'll improve some model, controller and view code by applying view concerns, helpers, Draper decorators, presenters, and service objects. In doing so, you'll better understand where and when to use these techniques to make your code DRY'er, simpler, and easier to test. As a bonus, you'll also see how RubyMine with VIM bindings boosts refactoring productivity.\n\n    Justin, aka @railsonmaui, is freelance Rails programmer and the technical evangelist for RubyMine. Passionately writing software since 1985, and focusing on Rails since 2011, he has a popular technical blog at http://www.railsonmaui.com. Degrees include a BA, Harvard and a MBA, UC Berkeley.\n\n  video_provider: \"youtube\"\n  video_id: \"bHpVdOzrvkE\"\n\n- id: \"todd-schneider-railsconf-2014\"\n  title: \"Demystifying Data Science: A Live Tutorial\"\n  raw_title: \"RailsConf 2014 - Demystifying Data Science: A Live Tutorial by Todd Schneider\"\n  speakers:\n    - Todd Schneider\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-05\"\n  published_at: \"2014-05-05\"\n  description: |-\n    To get a grip on what \"data science\" really is, we'll work through a real text mining problem live on stage. Our mission? Trace the evolution of popular words and phrases in RailsConf talk abstracts over the years! We'll cover all aspects of the problem, from gathering and cleaning our data, to performing analysis and creating a compelling visualization of our results. People often overlook Ruby as a choice for scientific computing, but the Rails ecosystem is surprisingly suited to the problem.\n\n    Originally a \"math guy\", Todd spent six years working for a hedge fund building models to value mortgage-backed securities before a fortuitous foray into web programming got him tangled up with Rap Genius. His recent Rails work includes Rap Stats, Wedding Crunchers, and Gambletron 2000.\n\n  video_provider: \"youtube\"\n  video_id: \"2ZDCxwB29Bg\"\n\n- id: \"nitin-dhaware-railsconf-2014\"\n  title: \"Empowering Rich Internet Applications (RIAs) with Accessibility\"\n  raw_title: \"RailsConf 2014 - Empowering Rich Internet Applications (RIAs) with Accessibility\"\n  speakers:\n    - Nitin Dhaware\n    - Nerkar Dnyaneshwar\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-05\"\n  published_at: \"2014-05-05\"\n  description: |-\n    By Nitin Dhaware and Nerkar Dnyaneshwar\n\n    Did you know that there are many web users all over the universe with different impairments and they could not use the web apps we develop just because they are not accessible? Being blind, Nitin and his colleagues have experienced this and hence in this talk, they underline the importance of Web Accessibility by discussing aspects of WAI-ARIA guidelines, along with the practical demonstrations of accessible forms, tab panels, grids etc., while developing RIAs in Rails.\n\n    Nitin is a Rails programmer working at Techvision - a team of MAD (Motivated and Dedicated) people and a company run by him and his visually challenged mates. They are based in India and love programming. Web accessibility is their expertise and passion. Do visit their website (http://techvision.net.in).\n\n    Gyani is a Java/J2EE professional and Ruby/Rails newbie. Having worked as a Technical Specialist in IT industry for more than 9 years, 9 months back he decided to join Techvision -- a small start-up run by visually challenged Rubyists. Currently he is playing the role of Technical Mentor cum facilitator for the Techvision team and helping Techvision grow in all the domains, one among them is Accessibility which is their niche.\n  video_provider: \"youtube\"\n  video_id: \"c2AKsQki7H0\"\n\n- id: \"erik-michaels-ober-railsconf-2014\"\n  title: \"Mutation Testing with Mutant\"\n  raw_title: \"RailsConf 2014 - Mutation Testing with Mutant by Erik Michaels-Ober\"\n  speakers:\n    - Erik Michaels-Ober\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-05\"\n  published_at: \"2014-05-05\"\n  description: |-\n    Tests are a good tool to verify your code but how do you verify your tests? Mutation testing is a technique to evaluate the quality of your tests by programmatically mutating (i.e. making a series of small modifications to) your code and ensuring that the tests no longer pass. This talk will attempt to demonstrate the value of mutation testing and show you how to use Mutant to improve the quality of your tests and your code.\n\n    Erik Michaels-Ober is a programmer.\n\n  video_provider: \"youtube\"\n  video_id: \"WccaOMuf01Y\"\n\n- id: \"jess-szmajda-railsconf-2014\"\n  title: \"Rack-AMQP: Ditch HTTP Inside SOA!\"\n  raw_title: \"RailsConf 2014 - Rack-AMQP: Ditch HTTP Inside SOA! by Jess Szmajda\"\n  speakers:\n    - Jess Szmajda\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-06\"\n  published_at: \"2014-05-06\"\n  description: |-\n    We're comfortable with HTTP, but using it for communication in your SOA isn't simple. You need load balancers, URL discovery, SSL, and there's a cost to set up and tear down that HTTP window.\n\n    Rack-AMQP lets you serve your rack (and rails) apps over AMQP, a robust, open protocol for messaging. You get simple queues, load balancing, security, and persistent connections for free (plus pub-sub!)—without changing your app.\n\n    Learn the pitfalls of HTTP and why you should use AMQP in your SOA!\n\n    Josh is the host of the Ruby Hangout, an online Ruby meetup. Josh also coorganizes DCRUG and is the CTO at Optoro, a Washington, DC startup in the reverse logistics industry. Josh has been developing web applications with HTTP for 16 years and thinks that SOAs should think differently.\n\n  video_provider: \"youtube\"\n  video_id: \"cINCWpn-LQM\"\n\n- id: \"keith-pitt-railsconf-2014\"\n  title: \"Keith and Mario's Guide to Continuous Deployment with Rails\"\n  raw_title: \"RailsConf 2014 - Keith and Mario's Guide to Continuous Deployment with Rails\"\n  speakers:\n    - Keith Pitt\n    - Mario Visic\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-06\"\n  published_at: \"2014-05-06\"\n  description: |-\n    By Keith Pitt and Mario Visic\n\n    Recently it has become common practise for development teams to deploy their code several times a day, as well as encouraging new developers to deploy on their first day at work.\n\n    In our talk Mario and I will discuss how we use continous deployment to push these practises to the extreme. Automatically deploying the master branch on new changes is an awesome way to improve your development process.\n\n    Automatically deploying master will fundamentally change how you work.\n\n    Keith is a Ruby Developer from Adelaide living in Melbourne. By day he works at Pin Payments and by night he works on Buildbox.\n\n    In Keith's spare time, he watches many scary movies, and wins Magic Competitons.\n\n    Mario is a Ruby on Rails developer from Perth Australia, he currently works on the Microlancer team at Envato in Melbourne. As well as being a Co-Founder of Desktoppr he has also worked on some cool projects such as iMeducate and Airtasker\n\n    In his spare time he enjoys eating different types of cheeses.\n\n  video_provider: \"youtube\"\n  video_id: \"DazHGyb7Gqg\"\n\n- id: \"andrew-warner-railsconf-2014\"\n  title: \"Where did the OO go? Views Should be Objects Too!\"\n  raw_title: \"RailsConf 2014 - Where did the OO go? Views Should be Objects Too!\"\n  speakers:\n    - Andrew Warner\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-06\"\n  published_at: \"2014-05-06\"\n  description: |-\n    By Andrew Warner\n\n    Is app/views the worst part of your codebase? Have you ever told someone on your team \"remember to update the client-side views too\"? Too long has the node.js community touted their advantage of using the same code on the client and the server. It's time that Rails got a few punches in.\n\n    We should think of views as objects, not template files. In this talk I show how that lets us tease apart presentation from data, and build logic-less templates that are shared between client and server.\n\n    Andrew Warner studied CS and Psychology at Wesleyan. He has worked at companies large and small and with tech stacks ranging from Java/Spring to Ruby on Rails. He is currently a developer at Rap Genius, where he helps build and scale a Rails backend so that all of text can be annotated.\n\n  video_provider: \"youtube\"\n  video_id: \"WAN_P1m76GQ\"\n\n- id: \"carl-lerche-railsconf-2014\"\n  title: \"Supercharge Your Workers with Storm\"\n  raw_title: \"RailsConf 2014 - Supercharge Your Workers with Storm by Carl Lerche\"\n  speakers:\n    - Carl Lerche\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-06\"\n  published_at: \"2014-05-06\"\n  description: |-\n    If you have ever needed to scale background jobs, you might have noticed that using the database to share information between tasks incurs a serious performance penalty. Trying to process large amounts of data in real-time using the database for coordination will quickly bring your servers to their knees.\n\n    This talk will show you how to use Apache Storm, a distributed, realtime computation system, to solve these types of problems in a fast, consistent, and fault-tolerant way.\n\n    Carl is currently working at Tilde, a small company he co-founded, where he spends most of his day hacking on Skylight and drinking too much coffee. In the past, he has worked on a number of ruby open source projects, such as Bundler and Ruby on Rails.\n\n  video_provider: \"youtube\"\n  video_id: \"qjZnezdSKnw\"\n\n- id: \"nicholas-henry-railsconf-2014\"\n  title: \"Modeling on the Right Side of the Brain\"\n  raw_title: \"RailsConf 2014 - Modeling on the Right Side of the Brain by Nicholas Henry\"\n  speakers:\n    - Nicholas Henry\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-07\"\n  published_at: \"2014-05-07\"\n  description: |-\n    Since your first web application, you have struggled with identifying domain objects. Assigning business rules and services appears to be a talent that only other developers are born with. Fear not! Object Modeling is a learnable, teachable skill. This talk demonstrates the five essential skills you need for modeling objects and their responsibilities. Think beyond ActiveRecord and your database, and learn how color and patterns will help you explain, maintain and extend your application.\n\n    Nicholas Henry is an independent Rails developer and object modeling enthusiast. Passionate about developer education, he is an active teacher at Rails Bridge workshops in his home town. Originally from New Zealand, he is now living and coding in Montreal, Canada.\n\n  video_provider: \"youtube\"\n  video_id: \"ABIvpz50cKU\"\n\n- id: \"liana-leahy-railsconf-2014\"\n  title: \"Let Me Code\"\n  raw_title: \"RailsConf 2014 - Let Me Code by Liana Leahy\"\n  speakers:\n    - Liana Leahy\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-07\"\n  published_at: \"2014-05-07\"\n  description: |-\n    LYRICS:\n\n    The screen glows white on my laptop tonight\n    And my rSpec won't go green\n    I'm coding in isolation\n    So my PRs are obscene\n\n    My doubts are howling\n    Like this swirling storm inside\n    Couldn't keep it in\n    Heaven knows I've tried\n\n    Don't let them in\n    Don't let them see\n    My GitHub repo's\n    Mortifying me\n\n    Conceal, don't feel\n    Don't let them know!\n    Oh god, you know!\n\n    Let me code!\n    Let me code!\n    Can't hold it back anymore\n    Let me code!\n    Let me code!\n    I want to play with Rails 4.0.4\n\n    I don't care\n    What they're going to say\n    Let the nerds rage on\n    The trolls never bothered me anyway\n\n    It's funny how some distance\n    Makes everything seem small\n    And the imposter syndrome\n    Can't get to me at all\n\n    It's time to see what I can do\n    To test the limits and break through\n    No right, no wrong Sandi's rules for me\n    I'm free!\n\n    Let me code!\n    Let me code!\n    Matz is my favorite guy\n    Let me code!\n    Let me code!\n    DHH will never see me cry\n\n    Here I stand\n    And here I'll stay\n    Let the nerds rage on\n\n    I'm watching SQL queries\n    data from top down\n    I'm using Ruby\n    to draw frozen fractals all around\n    And one thought solidifying\n    Like an icy blast\n\n    I'm never going back\n    The past is in the past\n\n    Let me code!\n    Let me code!\n    When I'll rise like the break of dawn\n    Let me code!\n    Let me code!\n    That perfect girl is gone\n\n    Here I stand\n    With the apps I've made\n    Let the nerds rage on\n    The trolls never bothered me anyway\n\n  video_provider: \"youtube\"\n  video_id: \"kRUS8Zvg3sg\"\n\n- id: \"eric-roberts-railsconf-2014\"\n  title: \"Domain Driven Design and Hexagonal Architecture with Rails\"\n  raw_title: \"RailsConf 2014 - Domain Driven Design and Hexagonal Architecture with Rails\"\n  speakers:\n    - Eric Roberts\n    - Declan Whelan\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-07\"\n  published_at: \"2014-05-07\"\n  description: |-\n    By Eric Roberts and Declan Whelan\n\n    You know that Domain Driven Design, Hexagonal Architecture, and the Single Responsibility Principle are important but it's hard to know how to best apply them to Rails applications. Following the path of least-resistance will get you in trouble. In this session you will learn a way out of the \"fat model, skinny controller\" hell. You will leave with a roadmap to guide your design based on concepts from Domain Driven Design and Hexagonal Architecture.\n\n    Declan loves to code and help others get joy from their code. When not coding he is the CTO at Printchomp, an agile coach at Leanintuit and an Agile Alliance Board Member.\n\n    Eric Roberts is a software developer at Boltmade and co-founder at 20Skaters. He is enthusiastic about creating maintainable software.\n\n  video_provider: \"youtube\"\n  video_id: \"_rbF97T4480\"\n\n- id: \"luke-melia-railsconf-2014\"\n  title: \"Lightning Fast Deployment of Your Rails-backed JavaScript app\"\n  raw_title: \"RailsConf 2014 - Lightning Fast Deployment of Your Rails-backed JavaScript app\"\n  speakers:\n    - Luke Melia\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-07\"\n  published_at: \"2014-05-07\"\n  description: |-\n    By Luke Melia\n\n    Are you restarting your Rails server every time you deploy JavaScript? Are you waiting 5 minutes or more to deploy static JavaScript? Stop! We were able to cut our JavaScript front-end deployment times from more than 5 minutes to less than 15 seconds with zero downtime. As a bonus, we can preview new releases on production before making them live. I will share all the details of an approach you can implement on your Rails-backed Javascript app to make deploying JavaScript updates a joy.\n\n    Luke Melia is Co-founder & CTO of Yapp & Yapp Labs. Luke discovered Ruby in 2005, is an active member of NYC.rb, co-organized the first GoRuCo, and was a co-author of Manning's \"Ruby in Practice\". He contributes regularly to Ember.js and organizes the Ember.js NYC Meetup .\n\n  video_provider: \"youtube\"\n  video_id: \"QZVYP3cPcWQ\"\n\n- id: \"cameron-dutro-railsconf-2014\"\n  title: \"Advanced aRel: When ActiveRecord Just Isn't Enough\"\n  raw_title: \"RailsConf 2014 -Advanced aRel: When ActiveRecord Just Isn't Enough\"\n  speakers:\n    - Cameron Dutro\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-07\"\n  published_at: \"2014-05-07\"\n  description: |-\n    By Cameron Dutro\n\n    We all love Rails, and lots of us love ActiveRecord. It's intuitive and easy to use in small apps that don't have lots of models. You can select, join, and where your way into a great, working app in no time. Then your app starts to grow, you add more models, and you need to start building more and more complex queries. This talk describes how to harness the awesomeness of aRel, ActiveRecord's powerful relational algebra system, to perform arbitrarily complex queries using nothing but pure Ruby.\n\n    Cameron Dutro works on Twitter's International Engineering team, primarily on the Twitter Translation Center, a large Rails application. He's been building stuff in Ruby for the past three years, including the TwitterCLDR internationalization library, and loving every minute of it.\n\n  video_provider: \"youtube\"\n  video_id: \"ShPAxNcLm3o\"\n\n- id: \"javier-ramirez-railsconf-2014\"\n  title: \"What is REST? Why is it Part of the Rails Way?\"\n  raw_title: \"RailsConf 2014 - What is REST? Why is it Part of the Rails Way?\"\n  speakers:\n    - Javier Ramirez\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-08\"\n  published_at: \"2014-05-08\"\n  description: |-\n    By Javier Ramirez\n\n    When David Heinemeier Hansson started talking about REST in 2006, little could we suspect it'd become such a central part of Rails (and of web development in general). Back then a web service meant something you coded using XML and SOAP. Those were dark times. REST changed it all.\n\n    In this talk, I'll explain REST for beginners, I'll talk about why it is such an important architecture, and I'll show all the nice things Rails offers you for building a RESTful application or a RESTful API.\n\n    Web developer, daydreamer and all around happy person.\n\n    Founder of https://teowaki.com where we try to make developers happier by helping them share technical information, best practices, gossip and lifehacks with their developer friends.\n\n  video_provider: \"youtube\"\n  video_id: \"HTi-UIHNouE\"\n\n- id: \"chris-maddox-railsconf-2014\"\n  title: \"Too Big to Fail\"\n  raw_title: \"RailsConf 2014 - Too Big to Fail by Chris Maddox\"\n  speakers:\n    - Chris Maddox\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-08\"\n  published_at: \"2014-05-08\"\n  description: |-\n    It's 5am and a multi-million dollar process fails halfway through. Hours of nightmarish, manual brain surgery later, enough is enough.\n\n    What happens when background jobs grow as bloated as the MonoRail™ that begot them?\n\n    Rather than reach for the latest fad off of HackerNews, we'll user Ruby and Rails to automate error-recovery, concurrent processing, and catch corrupt data before it brings everything down.\n\n    Typist, Philosopher at ZenPayroll. Humanist with a penchant for dystopian novels, St. George gin enthusiast, and wearer of colorful pants.\n\n  video_provider: \"youtube\"\n  video_id: \"MOTpwIwQMTI\"\n\n- id: \"ben-dixon-railsconf-2014\"\n  title: \"Deploying Rails is Easier Than it Looks\"\n  raw_title: \"RailsConf 2014 - Deploying Rails is Easier Than it Looks by Ben Dixon\"\n  speakers:\n    - Ben Dixon\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-08\"\n  published_at: \"2014-05-08\"\n  description: |-\n    Heroku makes it quick and easy to get your app up and running without worrying about \"server stuff\". But that server stuff is a lot simpler than it seems and once you know it, can make your projects more flexible (and save a lot of money!).\n\n    I'll start by looking at the basics of what's happening behind the scenes when you deploy a Rails app and why you might want to setup your own server. Then I'll look at the tools you'll need to do so and some common gotchas when getting started.\n\n    Rails Developer, author of 'Reliably Deploying Rails Applications'. Avid indoor climber. Believer in \"Small Steps Taken Quickly\".\n\n  video_provider: \"youtube\"\n  video_id: \"hTofBnxyBUU\"\n\n- id: \"yehuda-katz-railsconf-2014\"\n  title: \"Keynote: 10 Years!\"\n  raw_title: \"RailsConf 2014 - Keynote: 10 Years! by Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-08\"\n  published_at: \"2014-05-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"9naDS3r4MbY\"\n\n- id: \"saron-yitbarek-railsconf-2014\"\n  title: \"Reading Code Good\"\n  raw_title: \"RailsConf 2014 - Reading Code Good by Saron Yitbarek\"\n  speakers:\n    - Saron Yitbarek\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-08\"\n  published_at: \"2014-05-08\"\n  description: |-\n    As a new programmer, everyone tells you to build. But just as important is reading. Reading code is a powerful exercise - dissecting the source code of gems and libraries used in Rails offers the opportunity to examine patterns and design choices, while building confidence in new developers. But good code reading isn't as simple as scanning the source. The concrete guidelines outlined in this talk can maximize the benefits of your future code reading sessions and help you grow as a developer.\n\n    Hacker-in-Residence at the New York Tech Meetup. Graduate of the Flatiron School.\n\n  video_provider: \"youtube\"\n  video_id: \"mW_xKGUKLpk\"\n\n- id: \"akira-matsuda-railsconf-2014\"\n  title: \"Ruby on Rails Hacking Guide\"\n  raw_title: \"RailsConf 2014 - Ruby on Rails Hacking Guide by Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-08\"\n  published_at: \"2014-05-08\"\n  description: |-\n    Rails is a platform to serve your Ruby applications, and yet is a very well crafted open-source product written in the language that composes your apps. So, if you're curious to know how things work underneath your app, you can read everything!\n\n    This talk will be a good guide to step into the Rails internal. We'll cover these topics:\n\n        How Rails loads itself, libraries, and application when booting\n        How Rails deals with HTTP requests and databases\n        How to debug, patch, and extend Rails\n\n    Rails committer, Ruby committer, Haml committer, creator of widely used Rails plugins such as Kaminari, activedecorator, actionargs, html5validators, erd, databaserewinder, etc. Founder of \"Asakusa.rb\", the most active Ruby community in Japan.\n\n  video_provider: \"youtube\"\n  video_id: \"iACG4Dn_51w\"\n\n- id: \"david-padilla-railsconf-2014\"\n  title: \"Web Applications with Ruby (not Rails)\"\n  raw_title: \"RailsConf 2014 - Web Applications with Ruby (not Rails) by David Padilla\"\n  speakers:\n    - David Padilla\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-08\"\n  published_at: \"2014-05-08\"\n  description: |-\n    Whenever you say that you're building a web application with Ruby, its almost implied that you will be using Rails to do so.\n\n    But imagine for a second that Rails does not exist at all. What kind of Ruby code would you write to make a web application work from scratch?\n\n    During this talk we will think about and implement some of the MVC patterns that are taken for granted when using a framework like Rails, while at the same time write a web application with only a little help from Rack\n\n    David Padilla is CEO at Crowd Interactive, a leader Ruby on Rails consultancy based in Mexico.\n\n    Through his career, he has been devoted to promoting the Ruby on Rails community in Mexico through rails.mx and the organization of the only Ruby conference in the area: Magma Conf.\n\n  video_provider: \"youtube\"\n  video_id: \"TqiuMn1acV8\"\n\n- id: \"kate-heddleston-railsconf-2014\"\n  title: \"Technical Onboarding, Training, and Mentoring\"\n  raw_title: \"RailsConf 2014 - Technical Onboarding, Training, and Mentoring by Kate Heddleston\"\n  speakers:\n    - Kate Heddleston\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-09\"\n  published_at: \"2014-05-09\"\n  description: |-\n    With the increase of code academies training new engineers there is an increase in junior engineers on the market. A lot of companies are hesitant to hire too many young engineers because they lack sufficient resources to train them. This is a talk about how to make junior engineers into independent and productive members of your engineering team faster and cheaper by outlining a plan for how to onboard engineers effectively based on data and anecdotes gathered from companies in San Francisco.\n\n    I am a web applications developer from the bay area who builds full-stack web applications. I got my MSCS at Stanford but did my undergrad degree in Communication. I am active in the community with organizations like Hackbright Academy, PyLadies, and Girl Geek Dinners.\n\n  video_provider: \"youtube\"\n  video_id: \"Lpg4jRSH7EE\"\n\n- id: \"bradly-feeley-railsconf-2014\"\n  title: \"Surviving the Big Rewrite\"\n  raw_title: \"RailsConf 2014 - Surviving the Big Rewrite by Bradly Feeley\"\n  speakers:\n    - Bradly Feeley\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-09\"\n  published_at: \"2014-05-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"LRXaN0Wdl4U\"\n\n- id: \"coraline-ada-ehmke-railsconf-2014\"\n  title: \"Artisans and Apprentices\"\n  raw_title: \"RailsConf 2014 - Artisans and Apprentices by Coraline Ada Ehmke\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-09\"\n  published_at: \"2014-05-09\"\n  description: |-\n    Inspired by the medieval guild-and-apprentice system, the increasing popularity of bootcamps and apprenticeship programs in software development has great promise but may also bring with it some serious negative side effects. Let's explore the benefits of applying 12th century best practices to the challenge of preparing a new generation of developers, and discuss ways to avoid the mistakes of the past: technologically conservative monocultures comprising and serving a privileged few.\n\n    Coraline Ada Ehmke is a speaker, author, teacher, open source advocate and technologist with 20 years of experience in developing apps for the web. As a co-founder of LGBTech.org and founder of OpenSourceForWomen.org, she works diligently to promote diversity and inclusivity in the tech industry. Her current interests include small-application ecosystems, services and APIs, business intelligence, machine learning, and predictive analytics.\n\n  video_provider: \"youtube\"\n  video_id: \"96cqqEfGSFg\"\n\n- id: \"chuck-lauer-vose-railsconf-2014\"\n  title: \"Building kick-ass internal education programs (for large and small budgets)\"\n  raw_title: \"RailsConf 2014 - Building kick-ass internal education programs (for large and small budgets)\"\n  speakers:\n    - Chuck Lauer Vose\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-09\"\n  published_at: \"2014-05-09\"\n  description: |-\n    By Chuck Lauer Vose\n\n    There are not enough senior programmers in the world to satisfy the needs of our organizations; but educating your own developers is crazy expensive and hard, right?\n\n    It turns out there lots of effective, low-cost, low commitment ways to inject education into your organization, I'll show you some of the low commitment ways to engage your peers, how to evaluate your needs, how to measure your progress, and how to plan for future ed needs.\n\n    Chuck has been programming for the last 10 years, but recently switched full-time to a lifelong passion of teaching and education. Formerly he founded the Portland Code School, and now he's working with New Relic to build an incredible internal education program for incredible engineers.\n\n  video_provider: \"youtube\"\n  video_id: \"LPZmNfhPPOs\"\n\n- id: \"brad-gessler-railsconf-2014\"\n  title: \"Middleman: the Missing View in the Rails API Stack\"\n  raw_title: \"RailsConf 2014 - Middleman: the Missing View in the Rails API Stack\"\n  speakers:\n    - Brad Gessler\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-13\"\n  published_at: \"2014-05-13\"\n  description: |-\n    By Brad Gessler\n\n  video_provider: \"youtube\"\n  video_id: \"-q_oUyEHiEw\"\n\n- id: \"carlos-antonio-da-silva-railsconf-2014\"\n  title: \"Tricks That Rails Didn't Tell You About\"\n  raw_title: \"RailsConf 2014 - Tricks That Rails Didn't Tell You About by Carlos Antonio da Silva\"\n  speakers:\n    - Carlos Antonio da Silva\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-13\"\n  published_at: \"2014-05-13\"\n  description: |-\n    Rails allows us to write very concise code hiding a lot of the complexity. However, it's common to face situations that require us to write more complex code on our own, and sometimes we forget a little about what Rails can do for us. We are going through some Rails features that people might not be aware of, talking about Active Record queries, custom template handlers, routing niceties, view helpers and more, to learn how these tricks can help simplifying complex code on our apps.\n\n    Carlos (@cantoniodasilva) hacks beautiful code at Plataformatec, a consultancy firm based in Brazil, and is member of the Rails Core Team. He enjoys writing about a variety of subjects at the company's blog, and helping maintaining open source projects like Simple Form and Devise.\n\n  video_provider: \"youtube\"\n  video_id: \"YKm0v_weFZs\"\n\n- id: \"noel-rappin-railsconf-2014\"\n  title: \"Panel: Teaching the Next Great Developers\"\n  raw_title: \"RailsConf 2014 - Panel: Teaching the Next Great Developers by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n    - Jeff Casimir\n    - Bree Thomas\n    - Jen Meyers\n    - Liz Abinante\n    - Kathryn Exline\n    - Ben Orenstein\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-13\"\n  published_at: \"2014-05-13\"\n  description: |-\n    This is a panel discussion featuring Dave Hoover, co-founder of DevBootcamp Chicago, Jeff Casimir of Jumpstart Labs, and Ben Orenstein of Thoughtbot about how best to bring new developers into the field, and what kind of knowledge they will need to be successful. What can we, as a community, do to improve our management of new developers? What can new developers do to give themselves the best chance of success?\n\n    Noel Rappin is a Senior Developer and Table XI's Agile Coach. Noel has authored multiple technical books, including \"Rails Test Prescriptions\" and \"Master Space and Time With JavaScript.\"\n\n  video_provider: \"youtube\"\n  video_id: \"dYkFnxUzc0I\"\n\n- id: \"starr-horne-railsconf-2014\"\n  title: \"Biggish Data With Rails and Postgresql\"\n  raw_title: \"RailsConf 2014 - Biggish Data With Rails and Postgresql by Starr Horne\"\n  speakers:\n    - Starr Horne\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-13\"\n  published_at: \"2014-05-13\"\n  description: |-\n    Once your database hits a few hundred million rows normal ActiveRecord conventions don't work so well.\n\n    ...you find yourself in a new world. One where calling count() can bring your app to its knees. One where migrations can take all day.\n\n    This talk will show you how to work with big datasets in Rails and Postgresql. We'll show how normal conventions break down, and offer practical real-world advice on maintaining performance, doing maintenance, and tuning rails for optimal DB performance.\n\n    Starr likes building things that make people happy, usually with Ruby and Javascript. (He once built a bookshelf, but it was crooked and made noone happy.) He's the cofounder of Honeybadger.io. He lives in Guadalajara, Mexico and speaks very bad Spanish.\n\n  video_provider: \"youtube\"\n  video_id: \"40xq1jXM7GY\"\n\n- id: \"simon-krger-railsconf-2014\"\n  title: \"What the Cache?!\"\n  raw_title: \"RailsConf 2014 - What the Cache?! by Simon Kröger\"\n  speakers:\n    - Simon Kröger\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-13\"\n  published_at: \"2014-05-13\"\n  description: |-\n    \".. and then cache the hell out of it!\" This is usually how the talk ends when it comes to rails performance tips, but in reality it is where the fun starts. This talk goes way beyond Rails.cache, it explores layered caches, discusses the CPU cost of marshaling, the latency even Memcache adds and how to dodge the unavoidable stampedes that invalidating your caches will cause. This is the tale of how to survive half a billion requests per day with Rails and MySQL (hint: don't query it).\n\n    Simon took his experience from 12 years of freelancing for various companies around the globe and working with a very diverse set of technologies to build his dream team at SponsorPay and work with the language he loves - Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"atr8qv7wzPM\"\n\n- id: \"stephan-hagemann-railsconf-2014\"\n  title: \"Refactoring Towards Component-based Rails Architectures\"\n  raw_title: \"RailsConf 2014 - Refactoring Towards Component-based Rails Architectures\"\n  speakers:\n    - Stephan Hagemann\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-14\"\n  published_at: \"2014-05-14\"\n  description: |-\n    By Stephan Hagemann\n\n    You have a big Rails app and are feeling the pains? Stories are hard to deliver, code is hard to refactor, and your tests take a looong time? Getting you and your codebase out of this situation requires you to stop developing a \"Rails application\" and start refactoring towards your domain. I will discuss how and where you refactor towards a more structured and manageable application, a component-based Rails architecture.\n\n    For his day job Stephan is a Pivot - developing software at Pivotal Labs. With every project he especially enjoys the continuous search for doing the right thing, and doing that right. Outside of that he enjoys more work: on his old house or his rock climbing skills.\n\n  video_provider: \"youtube\"\n  video_id: \"MIhlAiMc7tU\"\n\n- id: \"pete-hodgson-railsconf-2014\"\n  title: \"Rails as an SOA Client\"\n  raw_title: \"RailsConf 2014 - Rails as an SOA Client by Pete Hodgson\"\n  speakers:\n    - Pete Hodgson\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-14\"\n  published_at: \"2014-05-14\"\n  description: |-\n    Our monolithic apps are evolving into ecosystems of connected services. It's becoming quite common for Rails apps to be working mainly as clients to other services. In this talk we'll cover tools and techniques for a happy and productive existence when your Rails app is acting as a front end to other services.\n\n    Pete Hodgson is a lead consultant with ThoughtWorks. He helps teams get more awesome by delivering quality maintainable software at a sustainable pace, using agile practices like test-driven design, pairing and continuous delivery.\n\n  video_provider: \"youtube\"\n  video_id: \"CzF3g_JM1YQ\"\n\n- id: \"jeremy-green-railsconf-2014\"\n  title: \"Service Oriented Authenication\"\n  raw_title: \"RailsConf 2014 - Service Oriented Authenication by Jeremy Green\"\n  speakers:\n    - Jeremy Green\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-14\"\n  published_at: \"2014-05-14\"\n  description: |-\n    Getting started with authentication in SOA environments can seem like a daunting subject, but it doesn't need to be difficult. This talk will cover everything you need to know to get started building your own SOA systems. We'll look at the details of building a centralized authentication service and allowing other apps to delegate their authentication needs to the service.\n\n    Jeremy is a full stack engineer who has been creating web apps for over 15 years. He's an organizer of the OkcRuby developer group and an active open source contributor. You might also find him drumming, shooting photos, or brewing.\n\n  video_provider: \"youtube\"\n  video_id: \"L1B_HpCW8bs\"\n\n- id: \"alan-cohen-railsconf-2014\"\n  title: \"Authorization in a Service-Oriented Environment\"\n  raw_title: \"RailsConf 2014 - Authorization in a Service-Oriented Environment by Alan Cohen\"\n  speakers:\n    - Alan Cohen\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-14\"\n  published_at: \"2014-05-14\"\n  description: |-\n    In a SOA environment users can interact with multiple parts of your system, and the rules for authorization become dispersed across applications. The task of maintaining rules becomes complex. The challenge compounds further in a heterogeneous environment, with services built in different languages. In this talk, I focus on the topic of authorization, specifically how we can scale and grow our services with confidence. I'll walk through a new framework we've developed to approach this problem.\n\n    Alan Cohen is a Software Engineer at Climate Corporation working on the Insurance product back-end and other core pieces of their risk management platform.\n\n  video_provider: \"youtube\"\n  video_id: \"6tQTwmIgclE\"\n\n- id: \"gregg-pollack-railsconf-2014\"\n  title: \"Ruby Heroes Awards 2014\"\n  raw_title: \"RailsConf 2014 - Ruby Heroes\"\n  speakers:\n    - Gregg Pollack\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-14\"\n  published_at: \"2014-05-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"qoc21UvC3p4\"\n\n- id: \"alberto-leal-railsconf-2014\"\n  title: \"Designing the APIs for an Internal Set of Services\"\n  raw_title: \"RailsConf 2014 - Designing the APIs for an Internal Set of Services by Alberto Leal\"\n  speakers:\n    - Alberto Leal\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    By Alberto Leal\n\n    The success of an API is measured by how fast and easy developers can integrate with that.\n\n    In the micro-services environment, where each service has a well-defined responsibility, it's not enough to have a well designed API, it's necessary to establish a contract between the APIs, so the integration between them may be feasible.\n\n    In this talk, I will go through a set of best practices that will help to design APIs and define a communication service contract.\n\n    From skateboarder to runner, photographer to full stack developer, Alberto loves writing beautiful code at Globo.com, Brazil, the internet branch of the largest mass media group in South America. He works in an environment of micro services, with lots of Ruby, Rails, Python, Tornado Web Server, Nginx, Javascript and Java.\n\n  video_provider: \"youtube\"\n  video_id: \"LuyAuXwA4rY\"\n\n- id: \"baratunde-thurston-railsconf-2014\"\n  title: \"Humor in The Code\"\n  raw_title: \"RailsConf 2014 - Humor in The Code by Baratunde Thurston\"\n  speakers:\n    - Baratunde Thurston\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    Humor In The Code The Future Of Everything Humbly Stated\n\n  video_provider: \"youtube\"\n  video_id: \"Oax1R1S6LI4\"\n\n- id: \"rosie-hoyem-railsconf-2014\"\n  title: \"Build The API First\"\n  raw_title: \"RailsConf 2014 - Build The API First by Rosie Hoyem and Sonja Hall\"\n  speakers:\n    - Rosie Hoyem\n    - Sonja Hall\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    By Rosie Hoyem and Sonja Hall\n\n    The next five years of web development are all about data applications and APIs. Learn how to leverage Rails-API to build them. This modular subset of a normal Rails application streamlines the process of building a standardized API that can easily be consumed by a wide-array of applications. We'll explore example applications using Rails API, demonstrating the expanding utility of this framework as user interfaces extend beyond HTML into native applications and APIs.\n\n    Rosie writes code in Minneapolis at the Minnesota Population Center, a leading developer and disseminator of demographic data. She's a designer turned city planner turned energy policy nerd turned web developer and proud 2013 graduate of the Flatiron School in NYC.\n\n    Sonja is a U.S. Fulbright Scholar and recent graduate of the Flatiron School in NYC who is a developer at Venga in Washington, D.C. Inspired by design and the great outdoors, you can find her commuting on her road bike or hanging out with dogs when not mastering the art of Rails.\n\n  video_provider: \"youtube\"\n  video_id: \"xlZ1A-d5x5U\"\n\n- id: \"joel-turnbull-railsconf-2014\"\n  title: \"Debugger Driven Developement with Pry\"\n  raw_title: \"RailsConf 2014 - Debugger Driven Developement with Pry by Joel Turnbull\"\n  speakers:\n    - Joel Turnbull\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    When our tests fail all we get is output in a terminal. Testing is core to the culture of Ruby, and the tools are sophisticated, but something big is missing from the workflow. Namely, a powerful debugger.\n\n    Integrating Pry creates an interactive, enjoyable TDD workflow. In this talk, I'll recount the somewhat unique development experience that made me a believer. I'll demonstrate with Pry a responsive and immersive TDD cycle, taking a test to green before it exits its first run.\n\n    Joel Turnbull is a Code Designer at Gaslight. He's been a staple in the Cincinnati development community for over 10 years. This is his first presentation at a Rails Conf.\n\n  video_provider: \"youtube\"\n  video_id: \"4hfMUP5iTq8\"\n\n- id: \"austin-putman-railsconf-2014\"\n  title: \"Eliminating Inconsistent Test Failures\"\n  raw_title: \"RailsConf 2014 - Eliminating Inconsistent Test Failures by Austin Putman\"\n  speakers:\n    - Austin Putman\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    Does your test suite fail randomly now and then? Maybe your cucumbers are a little flakey. Maybe you're busy and just kick off the build again... and again. If you've had a week or two where the build just won't pass, you know how fragile a TDD culture is. Keep yours healthy, or start bringing it back to par today. Why do tests fail randomly? How do we hunt down the causes? We'll review known sources of \"randomness\", with extra focus on test pollution and integration suites.\n\n    I empower people to make a difference with appropriate technology. Now I'm working to turn around the diabetes epidemic.\n\n    I was a founding partner and lead dev in a tech cooperative for nonprofits, and a team anchor for Pivotal Labs, training and collaborating with earth's best agile engineers.\n\n  video_provider: \"youtube\"\n  video_id: \"Z6Xk5JWVrcA\"\n\n- id: \"neal-kemp-railsconf-2014\"\n  title: \"Effectively Testing Services\"\n  raw_title: \"RailsConf 2014 - Effectively Testing Services by Neal Kemp\"\n  speakers:\n    - Neal Kemp\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    Our Ruby world is becoming increasingly service oriented. Even in trivial applications, we often glue on multiple services ranging from Twitter to AWS. Services can, however, be confusing to test.\n\n    Many questions arise such as: How thoroughly should I test a service? Should I stub out responses or consume an API in test mode? How do I know a service is returning what I believe it returns?\n\n    In this talk, I answer these questions and more so that you may test services more effectively.\n\n    I am an independent consultant who slings Ruby code for a variety of clients. In the past, I have worked as a developer at thoughtbot and ZURB. I was developing on the web back when marquees were cool.\n\n  video_provider: \"youtube\"\n  video_id: \"sMWthvdWS-w\"\n\n- id: \"roy-tomeij-railsconf-2014\"\n  title: \"Front-End: Fun, Not Frustration\"\n  raw_title: \"RailsConf 2014 - Front-End: Fun, Not Frustration by Roy Tomeij\"\n  speakers:\n    - Roy Tomeij\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    Writing front-end code can be frustrating. That sidebar won't stay on the left, no matter how much CSS you throw at it. The logo looks ugly on your smartphone, but after fixing it, it's broken in browser X. And why encode video in four different formats for that HTML5 player (Flash was so much easier)?!\n\n    It's time to fix the most common issues back-end developers have. Front-end coding should be fun!\n\n    Roy Tomeij (@roy) is co-founder of AppSignal in Amsterdam. He has been writing front-end code for Rails since early 2005. He previously co-founded 80beans, one of the earliest and well known Ruby consultancies in Europe. Critically acclaimed banjo player.\n\n  video_provider: \"youtube\"\n  video_id: \"Ljl_7wRVrPo\"\n\n- id: \"jenn-scheer-railsconf-2014\"\n  title: \"Elements of Design: A Developer's Primer\"\n  raw_title: \"RailsConf 2014 - Elements of Design: A Developer's Primer by Jenn Scheer\"\n  speakers:\n    - Jenn Scheer\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    \"Oh, don't ask me, I'm a terrible designer.\" That's something I've heard from Rails developers ever since I started working with them. But it's never true. It's just that most Rails devs don't have the scaffolding (no, not that scaffolding) around which to structure their designs.\n\n    In this talk we'll cover the things every developer should know about design: contrast, repetition, proximity, hierarchy, flow, typography, and color.\n\n    Jenn Scheer is a designer & developer who began designing for web but was frustrated with the inability to build it herself. She's taught design at General Assembly, to students who were clearly arming themselves for the web. She is currently at Rap Genius, helping users annotate the world.\n\n  video_provider: \"youtube\"\n  video_id: \"fN1MTmJeLew\"\n\n- id: \"jessica-eldredge-railsconf-2014\"\n  title: \"Sketchnothing: Creative Notes for Technical Content\"\n  raw_title: \"RailsConf 2014 - Sketchnothing: Creative Notes for Technical Content by Jessica Eldredge\"\n  speakers:\n    - Jessica Eldredge\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    By Jessica Eldredge\n\n    As developers, most of our time is spent on computers; but sometimes pen and paper is the best way to explore and develop our ideas. Sketchnoting uses hand-drawn elements to enhance focus, improve memory, and visualize important concepts. This talk will cover techniques to visually capture ideas, how to approach the mental multitasking required to sketch during technical talks and meetings, and explain why \"I can't draw\" is just a mental barrier to embracing creativity in your notes.\n\n    I am a web designer and front end developer at Shopify. I love UX and web development, Sass, and riding my refactor tractor through views and CSS. I love talking about comic books, wine, cats, and how cold it is in Canada. You can often find me with my nose buried in a sketchbook at conferences.\n\n  video_provider: \"youtube\"\n  video_id: \"VJq-5EHN7J4\"\n\n- id: \"john-athayde-railsconf-2014\"\n  title: \"How They Work Better Together: Lean UX, Agile Development and User-Centered Design\"\n  raw_title: \"RailsConf 2014 - How They Work Better Together: Lean UX, Agile Development and User-Centered Design\"\n  speakers:\n    - John Athayde\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    How They Work Better Together: Lean UX, Agile Development and User-Centered Design by John Athayde\n\n    Design has often been cut off from the development side of the house, creating static images that are then handed off to developers to build. Invariably, this waterfall approach leads to unhappy designers and frustrated programmers, and often a product that misses the mark. We'll study successes and failures from both consultancies (InfoEther, Hyphenated People, Meticulous) and product companies both large and small (LivingSocial, CargoSense).\n\n    John Athayde is a designer and developer who spends a lot of time fighting bad coding practices in the Rails view layer. He is currently the VP of Design for CargoSense, a logistics product company. Prior to this he was the Lead for UI/UX and Front-end Development--Internal Apps at LivingSocial.\n\n  video_provider: \"youtube\"\n  video_id: \"zdwnogUMtc4\"\n\n- id: \"cameron-daigle-railsconf-2014\"\n  title: \"Discovering User Interactions\"\n  raw_title: \"RailsConf 2014 - Discovering User Interactions by Cameron Daigle\"\n  speakers:\n    - Cameron Daigle\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    There's no magic mojo that helps a designer notice bad design; there's no secret compendium of design mysteries that developers just don't have access to. Good interaction design is about keeping your senses honed -- noticing the little things and respecting user intuition. In this talk I won't be showing code -- I'll be breaking down the usability of the world around you, and preaching the virtues of interaction awareness. Trust me: you'll never look at a microwave the same way again.\n\n    Cameron Daigle is a senior designer/consultant/purveyor-of-common-sense at Hashrocket. He works with Ruby and iOS, and has been building for the web since long before that -- but through it all has maintained a deep and steadfast love for beautiful user experiences.\n\n  video_provider: \"youtube\"\n  video_id: \"Rf0NhjMAVoY\"\n\n- id: \"charles-lowell-railsconf-2014\"\n  title: \"The Power of M\"\n  raw_title: \"RailsConf 2014 - The Power of M by Charles Lowell\"\n  speakers:\n    - Charles Lowell\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    Client-side MVC is a different beast from the one we're used to in Rails. On the client, more than anywhere else, the M is the key to creating powerful user experiences.\n\n    To demonstrate this principle in action, we'll first create an in-memory model of what a color is, and then use it to build an interactive 3D color chooser that is both beautiful and intuitive.\n\n    Sound hard? Not with when you're armed with well defined models... not when you've got the Power of M on your side.\n\n    Charles is a rubyist and entrepreneur who has been building software human interfaces for over ten years.\n\n    A founder at The Frontside, he is also the creator of several open source projects that bridge together the worlds of Ruby and JavaScript including The Ruby Racer and The Ruby Rhino.\n\n  video_provider: \"youtube\"\n  video_id: \"gD2HRyPHjUc\"\n\n- id: \"joe-moore-railsconf-2014\"\n  title: \"I Have Pair Programmed for 27,000 Hours: Ask Me Anything!\"\n  raw_title: \"RailsConf 2014 - I've Pair Programmed for 27,000 Hours. Ask Me Anythings! by Joe moore\"\n  speakers:\n    - Joe Moore\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    By Joe Moore\n\n    I've pair programmed almost every work day for 13 1/2 years. You've got questions. I've got answers.\n\n    Presentations I give, regardless of topic, grind to a halt once I mention pairing. Do we pair all day? Who owns the code? How do I convince my boss to let us pair? When do you take bathroom breaks? What about remote pairing? Pairing is a scam!\n\n    I'll answer all questions, from the poignant to the silly, and want you to share your own pair programming experiences. Ask me anything!\n\n    Joe began writing software in the late '90s, soon joining eXtreme Programming pioneer Evant in 2000. He joined Pivotal Labs in 2005 as a founding member of their Rails consulting practice. Joe remote pairs full time for Pivotal and blogs at http://remotepairprogramming.com. His Ward Number is 1.\n\n  video_provider: \"youtube\"\n  video_id: \"156LdcEjfhs\"\n\n- id: \"brandon-hays-railsconf-2014\"\n  title: \"Bring Fun Back to JS: Step-by-Step Refactoring Toward Ember\"\n  raw_title: \"RailsConf 2014 - Bring Fun Back to JS: Step-by-Step Refactoring Toward Ember by Brandon Hays\"\n  speakers:\n    - Brandon Hays\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    By Brandon Hays\n\n    You just wanted to add some nice interactive functionality to your Rails app. But then one jQuery plugin turns to three, add a dash of statefulness, some error handling, and suddenly you can't sleep at night.\n\n    We'll walk through using Ember Components to test-drive a refactor until your front-end code is understandable, usable, and extensible. Armed with TDD and components, you can start to get excited, not exasperated, when asked to add advanced client-side interactions to your website.\n\n    Brandon left the world of marketing to find that creating software made him happy. Brandon lives in Austin, TX, where he helps run The Frontside, a Rails and Ember.js consultancy. Brandon's lifelong mission is to hug every developer.\n\n  video_provider: \"youtube\"\n  video_id: \"VMmaKj8hCR4\"\n\n- id: \"justin-searls-railsconf-2014\"\n  title: 'The \"Rails of JavaScript\" Won''t be a Framework'\n  raw_title: 'RailsConf 2014 - The \"Rails of JavaScript\" Won''t be a Framework by Justin Searls'\n  speakers:\n    - Justin Searls\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    Last year, DHH said \"good frameworks are extractions, not inventions.\" The success of Rails lets us forget its roots as an extraction from an HTML-based UI. The failure of Rails has been its perception as \"best web framework ever\" instead of \"best web framework for apps like Basecamp\". Given that, it's clear why Rails makes writing a UI in HTML a joy but does few favors for JavaScript-heavy apps. Joy can be had in JavaScript, and we'll show how with Lineman.js & tools extracted to help find it!\n\n    Justin Searls has two professional passions: writing great software and sharing what he's learned in order to help others write even greater software. He and his team at Test Double have the pleasure of living out both passions every day, working closely with clients to find simple solutions to complex problems.\n\n  video_provider: \"youtube\"\n  video_id: \"Ylrm-mWALGI\"\n\n- id: \"eric-saxby-railsconf-2014\"\n  title: \"An Iterative Approach to Service Oriented Architecture\"\n  raw_title: \"RailsConf 2014 - An Iterative Approach to Service Oriented Architecture by Eric Saxby\"\n  speakers:\n    - Eric Saxby\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    By Eric Saxby\n\n    While there are resources on why other companies have made the transition to SOA, and end-game service boundaries may be clear, there are few resources on how to make progress towards SOA without sinking an entire team or stopping concurrent product development. Faced with a growing codebase, slower tests and performance issues, we've extracted services from our large Rails app the way we do everything else: iteratively. I'll walk through what we did right, and what we almost did wrong.\n\n    It took a while for Eric to come around to programming, trying a few other careers first. Now he focuses on the intersection of code and process, using buzzwords such as TDD, agile and devops to describe his ham-fisted hammering on keyboards. He finds it most interesting when code fails, and why.\n\n  video_provider: \"youtube\"\n  video_id: \"886iF1tNLZ4\"\n\n- id: \"alexander-dymo-railsconf-2014\"\n  title: \"Improve Performance Quick and Cheap: Optimize Memory and Upgrade to Ruby 2.1\"\n  raw_title: \"RailsConf 2014 - Improve Performance Quick and Cheap: Optimize Memory and Upgrade to Ruby 2.1\"\n  speakers:\n    - Alexander Dymo\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    By Alexander Dymo\n\n    You spend big money on servers or Heroku dynos? Your app exceeds hosting's memory limit? Your background processes can't keep up with the work? Your cache invalidation code is too complex? Then it's time to optimize the code.\n\n    Join this session to learn why memory optimization is the #1 thing you can do to improve performance. Understand how to optimize memory. Find out what difference Ruby 2.1 makes and what to do if you can't upgrade. Get to know optimization tools and processes.\n\n    Alexander is an entrepreneur, Y Combinator alum and free software developer. He has 9 years of experience of Rails application development and performance optimization. Alexander contributed performance-related patches and optimizations to both Ruby and Rails. His website and blog: www.alexdymo.com.\n\n  video_provider: \"youtube\"\n  video_id: \"pZ_BcEcFGj0\"\n\n- id: \"sam-livingston-gray-railsconf-2014\"\n  title: \"Cognitive Shortcuts: Models, Visualizations, Metaphors, and Other Lies\"\n  raw_title: \"RailsConf 2014 - Cognitive Shortcuts: Models, Visualizations, Metaphors, and Other Lies\"\n  speakers:\n    - Sam Livingston-Gray\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    By Sam Livingston-Gray\n\n    Experienced developers tend to build up a library of creative problem-solving tools: rubber ducks, code smells, anthropomorphizing code, &c.\n\n    These tools map abstract problems into forms our brains are good at solving. But our brains are also good at lying to us.\n\n    We'll talk about some of these tools, when to use them (or not), and how their biases can lead us astray.\n\n    \"A change in perspective is worth 80 IQ points.\" -Alan Kay\n\n    New developers very welcome: we don't teach this in school!\n\n    A developer from sunny* Portland, Oregon, Sam's been working in code since 1998, in Ruby since 2006, and at LivingSocial since 2012. He likes TDD/BDD/TATFT, pair programming, and refactoring—but finds that long walks on the beach tend to result in sandy keyboards.\n\n        YMMV\n\n  video_provider: \"youtube\"\n  video_id: \"__qEkyJipX0\"\n\n- id: \"jessie-link-railsconf-2014\"\n  title: \"How to be a Boss Without the B-S\"\n  raw_title: \"RailsConf 2014 - How to be a Boss Without the B-S by Jessie Link\"\n  speakers:\n    - Jessie Link\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    I think a lot of developers secretly harbor the desire to start their own company, but don't realize that running a business means a lot more than just cutting great code all day long. Others may be at a point in their career where they feel stalled out and might want to see if management is right for them. Moving from a software role to a management role doesn't mean you have to sacrifice all your technical/coding skills, but it does mean you need to cultivate some new ones.\n\n    Jessie is the Director of Engineering at Lookingglass Cyber Solutions. She enjoys mentoring young developers and is an active coach and participant with RailsGirls. Though she mostly spends her day herding cats, on occasion her devs let her into the code repo to do some damage.\n\n  video_provider: \"youtube\"\n  video_id: \"10_6gWK6t18\"\n\n- id: \"aaron-patterson-railsconf-2014\"\n  title: \"Closing Keynote\"\n  raw_title: \"RailsConf 2014 - Closing Keynote by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"BTTygyxuGj8\"\n\n- id: \"kenny-hoxworth-railsconf-2014\"\n  title: \"Distributed Request Tracing\"\n  raw_title: \"RailsConf 2014 - Distributed Request Tracing by Kenny Hoxworth\"\n  speakers:\n    - Kenny Hoxworth\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-16\"\n  published_at: \"2014-05-16\"\n  description: |-\n    Twilio's distributed architecture makes manually tracking down a communication bottleneck or failure almost impossible. By utilizing a distributed tracing system, Twilio can follow any request through each service layer and each host. In this talk, we will demonstrate how a Rails application can gain the same insights by instrumenting a multi-tier application and investigate tracing integration into a larger distributed ecosystem.\n\n    Kenny Hoxworth is a software engineer at Twilio dedicated to the reliable delivery of messaging communication. He previously co-founded a cyber-security company in Baltimore, Maryland, where he helped design and build the company's Rails flagship application and backend technology stack.\n\n  video_provider: \"youtube\"\n  video_id: \"L9HiJrR2RQY\"\n\n- id: \"katherine-wu-railsconf-2014\"\n  title: \"How to be a Better Junior Developer\"\n  raw_title: \"RailsConf 2014 - How to be a Better Junior Developer by Katherine Wu\"\n  speakers:\n    - Katherine Wu\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-20\"\n  published_at: \"2014-05-20\"\n  description: |-\n    Are you from a non-C.S. background? What about someone you mentor? Many junior devs' top focus is building technical knowledge. However, they already have other skills that can help them in their roles immediately! Some of these include helping their team focus on the right tasks and working well with stakeholders like PM and support. This talk will discuss the non-technical contributions junior devs can make now and how their senior dev mentors can help them ramp up more quickly as a result.\n\n    I studied Biology in college and was all set to attend medical school and fulfill my mother's dream of my becoming a doctor. Instead, I got a job at Google in tech support. After five years at Google, I took a sabbatical to attend Hackbright Academy. Now I'm a junior developer at New Relic.\n\n  video_provider: \"youtube\"\n  video_id: \"GJW46x27W1w\"\n\n- id: \"leah-silber-railsconf-2014\"\n  title: \"Building an OSS-Centric Company (and Why You Want To)\"\n  raw_title: \"RailsConf 2014 - Building an OSS-Centric Company (and Why You Want To) by Leah Silber\"\n  speakers:\n    - Leah Silber\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-20\"\n  published_at: \"2014-05-20\"\n  description: |-\n    Open source is the bread and butter of the community; it also makes us happy, but can it sustain a company? Execu-types will happily leech off OSS without contributing back, but there's a better way! In this talk I'll walk through how you can build an OSS-centric company. How to fund it, run it, and use it to build your project and community. Whether you're looking to build a new company around open source, or simply integrate more OSS-love into your existing business, this talk is for you.\n\n    Leah is an all-around OSS advocate, & Co-founder of Tilde, a successful OSS-centric business. She's a member of the Ember Core Team, and works on annual events like GoGaRuCo, EmberConf and RailsConf. She's spent years supporting OSS projects however she could, all while maintaining real paying jobs.\n\n  video_provider: \"youtube\"\n  video_id: \"zD26LvYbfms\"\n\n- id: \"sean-marcia-railsconf-2014\"\n  title: \"Saving the World (Literally) with Ruby on Rails\"\n  raw_title: \"RailsConf 2014 - Saving the World (Literally) with Ruby on Rails by Sean Marcia\"\n  speakers:\n    - Sean Marcia\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-20\"\n  published_at: \"2014-05-20\"\n  description: |-\n    Two thirds of honeybee hives have died out in Virginia. Is it possible for us to devise a way of monitoring beehives in remote locations to find the cause? Enter a raspberry pi + rails. Using a combination of this robust hardware and software solution, we were able to successfully track, monitor and provide real time reporting on the well-being of hives from across the county. Find out how we used ruby, rails, solar panels and other libraries to provide insight into this problem.\n\n    Sean is rubyist who works at George Mason University and he has the extreme pleasure of being one of the founders/organizers of the best meetup group out there, Arlington Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"J8i3mKJyjbQ\"\n\n- id: \"nickolas-means-railsconf-2014\"\n  title: \"You are Not an Impostor\"\n  raw_title: \"RailsConf 2014 - You are Not an Impostor by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-20\"\n  published_at: \"2014-05-20\"\n  description: |-\n    Despite the attention that impostor syndrome has gotten in the Ruby community recently, so many amazing developers still hide in fear of being discovered as frauds. These developers chalk their achievements up to everything except their own talent and don't believe they deserve their success. I know, because I've struggled with impostor syndrome my whole career. In this talk, I'll show you what makes impostor syndrome so powerful and how you can break free from the grip it has on your life.\n\n    Nickolas Means is a software engineer at WellMatch Health and spends his days remote pairing from Austin, TX. He's an advocate for all things pairing, and thinks vulnerability and egolessness are the two most important virtues in software development.\n\n  video_provider: \"youtube\"\n  video_id: \"l_Vqp1dPuPo\"\n\n- id: \"jason-clark-railsconf-2014\"\n  title: \"Make an Event of It\"\n  raw_title: \"RailsConf 2014 - Make an Event of It by Jason Clark\"\n  speakers:\n    - Jason Clark\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  description: |-\n    Are your controllers jumbled with seemingly unrelated steps? Does testing any bit of application logic require fixtures and setup helpers a mile long?\n\n    Evented patterns create a vocabulary of what happens in your system, and a way to separate code triggering events from code that responds to them. That helps tame the sprawl by setting clean boundaries, simplifying tests, and keeping your dependencies isolated.\n\n    This talk reveals the power of events and what's already in Rails to help you.\n\n    I fell in love with programming watching my dad work in Clipper and dBase III (no, really). That obsession continues today. My current language crushes are Ruby and Haskell, and I work for New Relic on the Ruby Agent. When not at work, I enjoy cycling, homebrewing, and hanging out with my family.\n\n  video_provider: \"youtube\"\n  video_id: \"dgUhP606F9w\"\n\n- id: \"mike-moore-railsconf-2014\"\n  title: \"Real-time Rails with Sync\"\n  raw_title: \"RailsConf 2014 - Real-time Rails with Sync by Mike Moore\"\n  speakers:\n    - Mike Moore\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  description: |-\n    Cutting-edge web interfaces surprise and delight users with their interactivity. Can we somehow enable this next-generation user experience with our current rails templates and not rewriting our presentation layer in JavaScript?\n\n    Sync enables your rails partials to update on the client in real time. It can match the user experience of JavaScript MVC frameworks. This session will explain how Sync works and how to integrate Sync in an existing application. Prepare to have your mind blown.\n\n    Mike Moore believes software is written for humans first and computers second. He is a living breathing person with many quirks and interests.\n\n  video_provider: \"youtube\"\n  video_id: \"L1YcCNcWUMs\"\n\n- id: \"luke-francl-railsconf-2014\"\n  title: \"Looking Backward: Ten Years on Rails\"\n  raw_title: \"RailsConf 2014 - Looking Backward: Ten Years on Rails by Luke Francl\"\n  speakers:\n    - Luke Francl\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  description: |-\n    In Edward Bellamy's utopian novel \"Looking Backward\", a man from the 1890s awakens after 100 years and sees the wonders of the new age. What would a programmer from 2004 think if they woke up in 2014's web development utopia?\n\n    When you work with Rails every day, it's easy to forget how much it changed web development. But the influence of Rails is still being felt today in the Ruby world and beyond. Let's rediscover the Rails revolution by looking backward at its impact on how we work now.\n\n    Luke Francl is a developer at Swiftype, which provides search engines as a service. His career has focused on web application development using a variety of technologies, including Tcl (seriously). He has been working with Ruby on Rails professionally since 2006.\n\n  video_provider: \"youtube\"\n  video_id: \"VnhVkzop1_w\"\n\n- id: \"tute-costa-railsconf-2014\"\n  title: \"Workshop: Simplifying Code - Monster to Elegant in Less Than 5 steps\"\n  raw_title: \"RailsConf 2014 - Workshop - Simplifying Code: Monster to Elegant in Less Than 5 steps by Tute Costa\"\n  speakers:\n    - Tute Costa\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  description: |-\n    In this workshop we'll learn how to transform complex, highly coupled code into a simpler, more readable and maintainable shape. We'll target known software anomalies with Refactoring Patterns‎, following steps with a confined scope, assuring that we stay distant from \"changed everything\" commits while achieving quick design improvements.\n\n    We'll talk different solutions for Fat Models, God Objects, long method chains, NoMethodError on nils, long methods, bad naming and cold coffee.\n\n  video_provider: \"youtube\"\n  video_id: \"ozWzehOEeuI\"\n\n- id: \"carlos-souza-railsconf-2014\"\n  title: \"Workshop: Ruby Coding Dojo\"\n  raw_title: \"RailsConf 2014 - Workshop - Ruby Coding Dojo by Carlos Souza and David Rogers\"\n  speakers:\n    - Carlos Souza\n    - David Rogers\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  description: |-\n    The ultimate goal of the Coding Dojo is to share knowledge and improve the technical and social skills required in software development. This is a hands on Coding Dojo using Ruby as the language of choice. Participants will pair program with each other trying to solve a simple problem.\n\n  video_provider: \"youtube\"\n  video_id: \"d-Yc7XpELRg\"\n\n- id: \"tom-dale-railsconf-2014\"\n  title: \"How to Build a Smart Profiler for Rails\"\n  raw_title: \"RailsConf 2014 - How to Build a Smart Profiler for Rails by Tom Dale and Yehuda Katz\"\n  speakers:\n    - Tom Dale\n    - Yehuda Katz\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"pYaCcA07adI\"\n\n- id: \"leena-s-n-railsconf-2014\"\n  title: \"Culture of Continue Delivery\"\n  raw_title: \"RailsConf 2014 - Culture of Continue Delivery by Leena S N and Vaidy Bala\"\n  speakers:\n    - Leena S N\n    - Vaidy Bala\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  description: |-\n    The first principle written in the Agile Manifesto reads: \"Our highest priority is to satisfy the customer through early and continuous delivery of valuable software\". But how do we do that? This talk focuses on a key part of Continuous Delivery [CD] i.e. \"culture of collaboration\", and tips and tricks for building the same. We'll also touch upon important CD practices such as Feature Toggles, Automated tests and Automated build & deployment scripts.\n\n    Leena is the Head of Engineering @ Multunus Software, Bangalore. She is a Pragmatic & Passionate Programmer, Lean Thinker and XP Evangelist who's now hooked onto Continuous Delivery. She's also a mother of 2 lovely angels.\n\n    Vaidy is the founder and CEO @Multunus, Bangalore. His interests include lean startups, continuous delivery, great workplaces and entrepreneurship. He's also a geek, dad & husband.\n\n  video_provider: \"youtube\"\n  video_id: \"cuRyW0FfBiM\"\n\n- id: \"mark-menard-railsconf-2014\"\n  title: \"Writing Small Code\"\n  raw_title: \"RailsConf 2014 - Writing Small Code by Mark Menard\"\n  speakers:\n    - Mark Menard\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  description: |-\n    Writing small classes is hard. You know you should, but how? It's so much easier to write a large class. In this talk we'll build up a set of small classes starting from nothing using a set of directed refactorings applied as we build, all while keeping our tests green. We'll identify abstractions yearning to be free of their big class cages. In the process we'll also see how basic patterns such as composition, delegation and dependency inversion emerge from using small objects.\n\n    Mark Menard is president of Enable Labs, a consulting firm, in Troy, NY specializing in large scale web and mobile app dev. Mark talks about Ruby and coding at conferences and user groups. Mark also gets his hands dirty doing construction work from time-to-time, and is a happy husband and father.\n\n  video_provider: \"youtube\"\n  video_id: \"Y2dllXkUlu8\"\n\n- id: \"sandi-metz-railsconf-2014\"\n  title: \"All the Little Things\"\n  raw_title: \"RailsConf 2014 - All the Little Things by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  slides_url: \"https://speakerdeck.com/skmetz/all-the-little-things-railsconf\"\n  description: |-\n    Theory tells us to build applications out of small, interchangeable objects but reality often supplies the exact opposite. Many apps contain huge classes of long methods and hair-raising conditionals; they're hard to understand, difficult to reuse and costly to change. This talk takes an ugly section of conditional code and converts it into a few simple objects. It bridges the gap between OO theory and practice and teaches straightforward strategies that all can use to improve their code.\n\n    Sandi Metz, author of \"Practical Object-Oriented Design in Ruby\", believes in simple code and straightforward explanations. She prefers working software, practical solutions and lengthy bicycle trips (not necessarily in that order) and consults and teaches on all things OOP.\n\n  video_provider: \"youtube\"\n  video_id: \"8bZh5LMaSmE\"\n\n- id: \"andy-maleh-railsconf-2014\"\n  title: \"Ultra Light and Maintainable Rails Wizards\"\n  raw_title: \"RailsConf 2014 - Ultra Light and Maintainable Rails Wizards by Andy Maleh\"\n  speakers:\n    - Andy Maleh\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  description: |-\n    Wizards have been common in web applications since the dawn of the Internet, with the most popular example being the Shopping Cart, yet many struggle with writing wizard code effectively, resulting in a huge untraceable rat's nest of copy/paste code. In fact, many implementations violate REST and include Fat Controllers as well as overly complicated wizard-step management, data, session, and validation code. This talk covers a better way that yields Ultra Light and Maintainable Rails Wizards!\n\n    Andy Maleh leads at Big Astronaut by embracing agile practices and software craftsmanship while perfecting software products. He helped Groupon develop their 33M-user-website by working on user subscription and personalization features. Andy likes to drum, snowboard, and longboard in his free time.\n\n  video_provider: \"youtube\"\n  video_id: \"muyfoiKHMMA\"\n\n- id: \"aaron-suggs-railsconf-2014\"\n  title: \"Rack::Attack: Protect your app with this one weird gem!\"\n  raw_title: \"RailsConf 2014 - Rack::Attack: Protect your app with this one weird gem! by Aaron Suggs\"\n  speakers:\n    - Aaron Suggs\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-21\"\n  published_at: \"2014-05-21\"\n  description: |-\n    Mature apps face problems with abusive requests like misbehaving users, malicious hackers, and naive scrapers. Too often they drain developer productivity and happiness.\n\n    Rack::Attack is middleware to easily throttle abusive requests.\n\n    At Kickstarter, we built it to keep our site fast and reliable with little effort. Learn how Rack::Attack works through examples from kickstarter.com. Spend less time dealing with bad apples, and more time on the fun stuff.\n\n    Aaron Suggs is the Operations Engineer at Kickstarter, where he backs too many video game projects.\n\n    He enjoys writing code that makes developers' lives easier, especially while wearing his grizzly bear coat.\n\n  video_provider: \"youtube\"\n  video_id: \"m1UwxsZD6sw\"\n\n- id: \"terence-lee-railsconf-2014\"\n  title: \"Heroku 2014: A Year in Review\"\n  raw_title: \"RailsConf 2014 - Heroku 2014: A Year in Review by Terence Lee & Richard Schneeman\"\n  speakers:\n    - Terence Lee\n    - Richard Schneeman\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-22\"\n  published_at: \"2014-05-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"pu-ZWR8UISc\"\n\n- id: \"julian-simioni-railsconf-2014\"\n  title: \"Software Development Lessons from the Apollo Program\"\n  raw_title: \"RailsConf 2014 - Software Development Lessons from the Apollo Program by Julian Simioni\"\n  speakers:\n    - Julian Simioni\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-22\"\n  published_at: \"2014-05-22\"\n  description: |-\n    In 1961, MIT was awarded the contract for a guidance system to fly to the moon, the first for the entire Apollo Program. Software was not mentioned. Six years later, the project had 400 engineers writing code.\n\n    The Apollo Guidance Computer flew men to the moon before UNIX or C were created, and is to this day a marvel of engineering.\n\n    NASA and MIT records of its creation allow us to look back on some pioneers of our industry, relive their experiences, and maybe learn a few things ourselves.\n\n    Julian Simioni is a software developer at 42floors in San Francisco, CA. When not working tirelessly to bring technology to the world of commercial real estate, he can be found riding his bicycle, flying planes, and eating spaghetti.\n\n  video_provider: \"youtube\"\n  video_id: \"hrsT9wmPVoo\"\n\n- id: \"edward-chiu-railsconf-2014\"\n  title: \"Engine Yard's New and Improved Cloud Platform\"\n  raw_title: \"RailsConf 2014 - Engine Yard's New and Improved Cloud Platform by Edward Chiu & Will Luongo\"\n  speakers:\n    - Edward Chiu\n    - Will Luongo\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-22\"\n  published_at: \"2014-05-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"kNM4cnF4vrw\"\n\n- id: \"toby-hede-railsconf-2014\"\n  title: \"An Ode to 17 Databases in 33 Minutes\"\n  raw_title: \"RailsConf 2014 - An Ode to 17 Databases in 33 Minutes by Toby Hede\"\n  speakers:\n    - Toby Hede\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-22\"\n  published_at: \"2014-05-22\"\n  description: |-\n    A detailed, deep-diving, in-the-deep-end and occasionally humorous whirlwind introduction and analysis of a suite of modern (and sometimes delightfully archaic) database technologies. How they work, why they work, and when you might want them to work in your Rails application.\n\n    Including but not limited to:\n\n        PostgreSQL (now with JSON!)\n        Redis\n        Cassandra\n        Hyperdex\n        MongoDb\n        Riak\n        Animated Gifs\n\n    Toby is a mild-mannered Rails Developer & occasionally Polyglot Programmer, based in Sydney, Australia.\n\n    He really likes databases.\n\n    Toby's hobbies include collecting programming languages and databases, playing the drums, cutting code and pondering the nature of existence.\n\n  video_provider: \"youtube\"\n  video_id: \"lzwAJxIESNU\"\n\n- id: \"chris-hunt-railsconf-2014\"\n  title: \"Secrets of a World Memory Champion\"\n  raw_title: \"RailsConf 2014 - Secrets of a World Memory Champion by Chris Hunt\"\n  speakers:\n    - Chris Hunt\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-22\"\n  published_at: \"2014-05-22\"\n  description: |-\n    You don't have a bad memory, you were just never taught how to use it. We are going to practice several powerful memory techniques that have been perfected by memory contest champions over the last hundred years. By the end of this talk, you will know how to quickly memorize a foreign language, driving directions, phone conversations, the entire Chuck Norris filmography, your friend's credit card number, a shuffled deck of playing cards, and the name of every person you meet at RailsConf.\n\n    Chris Hunt works for GitHub from a standing desk in Portland, Oregon. Prior to GitHub, Chris worked on Rails applications for Square, Apple, Department of Defense, and his very critical mother. You can find him on Twitter as @chrishunt\n\n  video_provider: \"youtube\"\n  video_id: \"OfTryhTC8wY\"\n\n- id: \"obie-fernandez-railsconf-2014\"\n  title: \"Panel Discussion: The Future of Rails Jobs\"\n  raw_title: \"RailsConf 2014 - Panel Discussion: The Future of Rails Jobs\"\n  speakers:\n    - Obie Fernandez\n    - Jess Casimir\n    - Allan Grant\n    - Chad Pytel\n    - Corey Haines\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-22\"\n  published_at: \"2014-05-22\"\n  description: |-\n\n    Panel: Jess Casimi\n    - Allan Gran\n    - ad Pytel and Corey Haines\n\n  video_provider: \"youtube\"\n  video_id: \"g3pM6bVPZsQ\"\n\n- id: \"michael-norton-railsconf-2014\"\n  title: \"Workshop: Teamwork Ain't Always Easy\"\n  raw_title: \"RailsConf 2014 - Workshop - Teamwork Ain't Always Easy by Michael Norton\"\n  speakers:\n    - Michael Norton\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-22\"\n  published_at: \"2014-05-23\"\n  description: |-\n    Teamwork ain't always easy. From meetings where everybody has something to say but nothing gets done to poor decisions being made because the most senior or most forceful team member won the argument; sometimes you long for the days of high-walled cubicles and lone ranger coding. Long no more.\n\n    In this workshop, you will learn a few simple techniques that drastically improve a team's ability to work together toward common goals with less conflict and more genuine collaboration.\n\n  video_provider: \"youtube\"\n  video_id: \"l4eujsVPvtI\"\n\n- id: \"xavier-noria-railsconf-2014\"\n  title: \"Class Reloading in Ruby on Rails: The Whole Story\"\n  raw_title: \"RailsConf 2014 - Class Reloading in Ruby on Rails: The Whole Story by Xavier Noria\"\n  speakers:\n    - Xavier Noria\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-22\"\n  published_at: \"2014-05-22\"\n  description: |-\n    Ruby on Rails applications do not need to require the files that define their classes and modules. In development mode, code changes take effect without restarting the server. How's that possible? This talk explains how this works in depth.\n\n    You'll come out with a deep understanding of how constants work in Ruby, constant autoloading in Rails, how and why does it differ from Ruby's builtin algorithms, and how class reloading is implemented.\n\n    Xavier Noria is an everlasting student and father of the most wonderful girl. An independent Ruby on Rails consultant from Barcelona, Xavier is a member of the Ruby on Rails core team, Ruby Hero 2010, and proud author of Rails Contributors.\n\n  video_provider: \"youtube\"\n  video_id: \"4sIU8PxJEEk\"\n\n- id: \"aaron-bedra-railsconf-2014\"\n  title: \"Tales from the Crypt\"\n  raw_title: \"RailsConf 2014 - Tales from the Crypt by Aaron Bedra, Justin Collins and Matt Konda\"\n  speakers:\n    - Aaron Bedra\n    - Justin Collins\n    - Matt Konda\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-22\"\n  published_at: \"2014-05-22\"\n  description: |-\n    In this talk, three Rails security specialists will take a journey through a terrifying Rails application to illustrate common security problems we have seen in the real world. The discussion will include how to identify, fix, and prevent the issues with an emphasis on practical advice. Along the way we will share our experiences and perspectives concerning securely implementing applications. We hope it is a bit scary, and yet fun ... like a horror movie!\n\n    Aaron is a Principal Consultant at Cigital where he helps drive better secure programming practices. Aaron is the creator of Repsheet, an open source framework for web application attack prevention. He is a co-author of Programming Clojure and a previous member of Clojure/core.\n\n    Justin is a PhD candidate at UCLA, a member of the application security team at Twitter, and primary author of Brakeman, a static analysis security tool for Rails.\n\n    Matt is a veteran agile software developer with a focus on security. His mission is to empower developers to build code more securely through training, secure agile process adoption (Security in SDLC) and technical solutions. He enjoys soccer, reading and spending time with family.\n\n  video_provider: \"youtube\"\n  video_id: \"zZtDOX9kXRU\"\n\n- id: \"lightning-talks-day-1-railsconf-2014\"\n  title: \"Lightning Talks (Day 1)\"\n  raw_title: \"RailsConf 2014 - Lightning Talks by Many People\"\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-05-23\"\n  description: |-\n    Sean Marcia\n    00:01:24 - Josh\n    00:05:00 - Sachin Shintre\n    00:08:52 - Gyani & Siddant\n    00:12:00 - Andrew Nordman\n    00:17:26 - Justin Love\n    00:21:47 - Matthew Nielsen\n    00:25:58 - Andrew Cantino\n    00:29:34 - Yehuda Katz\n    00:34:18 - Ryan Alyea\n    00:37:29 - Adam Cuppy\n    00:40:32 - Mark Lorenz & Mike Gee\n    00:44:28 - Trever yarrish\n    00:49:34 - Mike Bourgeous\n    00:54:15 - Gustavo Robles\n    00:57:16 - Hector Bustillos\n    01:02:00 - Victor Velazquez\n    01:06:03 - Kay Rhodes\n    01:10:31 - Kevin Fallon\n    01:15:50 - Andrew Vit\n    01:20:53 - Brian Garside\n    01:25:37 - Mike Virata-Stone\n    01:30:36 - Kiyoto Tamura\n    01:35:41 - David Padilla\n  video_provider: \"youtube\"\n  video_id: \"o1qbP7RxPOw\"\n  talks:\n    - title: \"Lightning Talk: Sean Marcia\" # TODO: missing talk title\n      start_cue: \"00:01:24\"\n      end_cue: \"00:05:00\"\n      id: \"sean-marcia-lighting-talk-railsconf-2014\"\n      video_id: \"sean-marcia-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Sean Marcia\n\n    - title: \"Lightning Talk: Josh\" # TODO: missing talk title\n      start_cue: \"00:05:00\"\n      end_cue: \"00:08:52\"\n      id: \"josh-lighting-talk-railsconf-2014\"\n      video_id: \"josh-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Josh # TODO: missing last name\n\n    - title: \"Lightning Talk: Sachin Shintre\" # TODO: missing talk title\n      start_cue: \"00:08:52\"\n      end_cue: \"00:12:00\"\n      id: \"sachin-shintre-lighting-talk-railsconf-2014\"\n      video_id: \"sachin-shintre-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Sachin Shintre\n\n    - title: \"Lightning Talk: Gyani & Siddhant Chothe\" # TODO: missing talk title\n      start_cue: \"00:12:00\"\n      end_cue: \"00:17:26\"\n      id: \"gyani-siddhant-chothe-lighting-talk-railsconf-2014\"\n      video_id: \"gyani-siddhant-chothe-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Gyani\n        - Siddhant Chothe\n\n    - title: \"Lightning Talk: Andrew Nordman\" # TODO: missing talk title\n      start_cue: \"00:17:26\"\n      end_cue: \"00:21:47\"\n      id: \"andrew-nordman-lighting-talk-railsconf-2014\"\n      video_id: \"andrew-nordman-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Nordman\n\n    - title: \"Lightning Talk: Justin Love\" # TODO: missing talk title\n      start_cue: \"00:21:47\"\n      end_cue: \"00:25:58\"\n      id: \"justin-love-lighting-talk-railsconf-2014\"\n      video_id: \"justin-love-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Justin Love\n\n    - title: \"Lightning Talk: Matthew Nielsen\" # TODO: missing talk title\n      start_cue: \"00:25:58\"\n      end_cue: \"00:29:34\"\n      id: \"matthew-nielsen-lighting-talk-railsconf-2014\"\n      video_id: \"matthew-nielsen-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Matthew Nielsen\n\n    - title: \"Lightning Talk: Andrew Cantino\" # TODO: missing talk title\n      start_cue: \"00:29:34\"\n      end_cue: \"00:34:18\"\n      id: \"andrew-cantino-lighting-talk-railsconf-2014\"\n      video_id: \"andrew-cantino-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Cantino\n\n    - title: \"Lightning Talk: Yehuda Katz\" # TODO: missing talk title\n      start_cue: \"00:34:18\"\n      end_cue: \"00:37:29\"\n      id: \"yehuda-katz-lighting-talk-railsconf-2014\"\n      video_id: \"yehuda-katz-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Yehuda Katz\n\n    - title: \"Lightning Talk: Ryan Alyea\" # TODO: missing talk title\n      start_cue: \"00:37:29\"\n      end_cue: \"00:40:32\"\n      id: \"ryan-alyea-lighting-talk-railsconf-2014\"\n      video_id: \"ryan-alyea-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Ryan Alyea\n\n    - title: \"Lightning Talk: Adam Cuppy\" # TODO: missing talk title\n      start_cue: \"00:40:32\"\n      end_cue: \"00:44:28\"\n      id: \"adam-cuppy-lighting-talk-railsconf-2014\"\n      video_id: \"adam-cuppy-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Cuppy\n\n    - title: \"Lightning Talk: Mark Lorenz & Mike Gee\" # TODO: missing talk title\n      start_cue: \"00:44:28\"\n      end_cue: \"00:49:34\"\n      id: \"mark-lorenz-mike-gee-lighting-talk-railsconf-2014\"\n      video_id: \"mark-lorenz-mike-gee-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Mark Lorenz\n        - Mike Gee\n\n    - title: \"Lightning Talk: Trever Yarrish\" # TODO: missing talk title\n      start_cue: \"00:49:34\"\n      end_cue: \"00:54:15\"\n      id: \"trever-yarrish-lighting-talk-railsconf-2014\"\n      video_id: \"trever-yarrish-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Trever Yarrish\n\n    - title: \"Lightning Talk: Mike Bourgeous\" # TODO: missing talk title\n      start_cue: \"00:54:15\"\n      end_cue: \"00:57:16\"\n      id: \"mike-bourgeous-lighting-talk-railsconf-2014\"\n      video_id: \"mike-bourgeous-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Mike Bourgeous\n\n    - title: \"Lightning Talk: Gustavo Robles\" # TODO: missing talk title\n      start_cue: \"00:57:16\"\n      end_cue: \"01:02:00\"\n      id: \"gostavo-robles-lighting-talk-railsconf-2014\"\n      video_id: \"gostavo-robles-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Gustavo Robles\n\n    - title: \"Lightning Talk: Hector Bustillos\" # TODO: missing talk title\n      start_cue: \"01:02:00\"\n      end_cue: \"01:06:03\"\n      id: \"hector-bustillos-lighting-talk-railsconf-2014\"\n      video_id: \"hector-bustillos-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Hector Bustillos\n\n    - title: \"Lightning Talk: Victor Velazquez\" # TODO: missing talk title\n      start_cue: \"01:06:03\"\n      end_cue: \"01:10:31\"\n      id: \"victor-velazquez-lighting-talk-railsconf-2014\"\n      video_id: \"victor-velazquez-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Victor Velazquez\n\n    - title: \"Lightning Talk: Kay Rhodes\" # TODO: missing talk title\n      start_cue: \"01:10:31\"\n      end_cue: \"01:15:50\"\n      id: \"kay-rhodes-lighting-talk-railsconf-2014\"\n      video_id: \"kay-rhodes-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Kay Rhodes\n\n    - title: \"Lightning Talk: Kevin Fallon\" # TODO: missing talk title\n      start_cue: \"01:15:50\"\n      end_cue: \"01:20:53\"\n      id: \"kevin-fallon-lighting-talk-railsconf-2014\"\n      video_id: \"kevin-fallon-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Kevin Fallon\n\n    - title: \"Lightning Talk: Andrew Vit\" # TODO: missing talk title\n      start_cue: \"01:20:53\"\n      end_cue: \"01:25:37\"\n      id: \"andrew-vit-lighting-talk-railsconf-2014\"\n      video_id: \"andrew-vit-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Vit\n\n    - title: \"Lightning Talk: Brian Garside\" # TODO: missing talk title\n      start_cue: \"01:25:37\"\n      end_cue: \"01:30:36\"\n      id: \"brian-garside-lighting-talk-railsconf-2014\"\n      video_id: \"brian-garside-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Brian Garside\n\n    - title: \"Lightning Talk: Mike Virata-Stone\" # TODO: missing talk title\n      start_cue: \"01:30:36\"\n      end_cue: \"01:35:41\"\n      id: \"mike-virata-stone-lighting-talk-railsconf-2014\"\n      video_id: \"mike-virata-stone-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Mike Virata-Stone\n\n    - title: \"Lightning Talk: Kiyoto Tamura\" # TODO: missing talk title\n      start_cue: \"01:35:41\"\n      end_cue: \"01:40:00\"\n      id: \"kiyoto-tamura-lighting-talk-railsconf-2014\"\n      video_id: \"kiyoto-tamura-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Kiyoto Tamura\n\n    - title: \"Lightning Talk: David Padilla\" # TODO: missing talk title\n      start_cue: \"01:40:00\"\n      end_cue: \"TODO\"\n      id: \"david-padilla-lighting-talk-railsconf-2014\"\n      video_id: \"david-padilla-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - David Padilla\n\n- id: \"ernie-miller-railsconf-2014\"\n  title: \"Curmudgeon: An Opinionated Framework\"\n  raw_title: \"RailsConf 2014 - Curmudgeon: An Opinionated Framework by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-05-23\"\n  description: |-\n    Rails has opinions about how we should organize code, interact with a database, write tests, format URLs... just about everything. These conventions, the wisdom goes, free us up to focus on the specifics of our application. \"Convention over configuration\" becomes our mantra as development hurtles forward with startling speed.\n\n    At some point, we stop. We take stock of what we've built, and it's a mess. How did we get here?\n\n    Turns out, the decisions that Rails made for us had consequences.\n\n    Ernie's been writing code since he was 6 years old, but only getting paid to do so for the past 16 years or so. Sometimes he still can't believe people actually pay us to have this much fun.\n\n  video_provider: \"youtube\"\n  video_id: \"uDLtgjx5_Ss\"\n\n- id: \"luigi-montanez-railsconf-2014\"\n  title: \"You'll Never Believe Which Web Framework Powers Upworthy\"\n  raw_title: \"RailsConf 2014 - You'll Never Believe Which Web Framework Powers Upworthy\"\n  speakers:\n    - Luigi Montanez\n    - Ryan Resella\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-26\"\n  published_at: \"2014-05-26\"\n  description: |-\n    By Luigi Montanez & Ryan Resella\n\n    Launched just two years ago, Upworthy has quickly become one of the most popular sites on the Web. According to Quantcast, it's a Top 40 site in the U.S. and is the most visited site hosted on Heroku. And yes, it's powered by Ruby on Rails! Hear the story of how Upworthy started out as a modest Sinatra app, then moved to a monolithic Rails app, and has now been broken up into a set of services powered by Rails. Technical decision-making in the midst of massive growth will be described in detail.\n\n    Luigi is the founding engineer at Upworthy, a viral media site that aims to drive massive amounts of attention to the topics that matter most. Before Upworthy, Luigi was a software developer at the Sunlight Foundation. He also co-organizes Code for Atlanta.\n\n    Ryan is a Senior Engineer at Upworthy. In 2012 Ryan was an Engineer on the Technology Team at Obama For America that helped re-elect the President of the United States. Prior to OFA, Ryan was a 2011 Inaugural Code for America Fellow and then went on to become Technical Lead at Code for America.\n\n  video_provider: \"youtube\"\n  video_id: \"r56wJMk8QCg\"\n\n- id: \"lightning-talks-living-social-railsconf-2014\"\n  title: \"Lightning Talks (Living Social)\"\n  raw_title: \"RailsConf 2014 - Living Social Lightning Talks\"\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-26\"\n  published_at: \"2014-05-26\"\n  description: |-\n    By\n\n    Ed Weng\n    Dan Meyer\n    Tyler Montgomery\n    Nick Sieger\n    Rodrigo Franco\n\n  video_provider: \"youtube\"\n  video_id: \"pFhPEguxqSI\"\n  talks:\n    - title: \"Lightning Talk: Ed Weng\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"ed-weng-lighting-talk-railsconf-2014\"\n      video_id: \"ed-weng-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Ed Weng\n\n    - title: \"Lightning Talk: Dan Meyer\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"dan-meyer-lighting-talk-railsconf-2014\"\n      video_id: \"dan-meyer-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Dan Meyer\n\n    - title: \"Lightning Talk: Tyler Montgomery\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tyler-montgomery-lighting-talk-railsconf-2014\"\n      video_id: \"tyler-montgomery-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Tyler Montgomery\n\n    - title: \"Lightning Talk: Nick Sieger\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"nick-sieger-lighting-talk-railsconf-2014\"\n      video_id: \"nick-sieger-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Nick Sieger\n\n    - title: \"Lightning Talk: Rodrigo Franco\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"rodrigo-franco-lighting-talk-railsconf-2014\"\n      video_id: \"rodrigo-franco-lighting-talk-railsconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Rodrigo Franco\n\n- id: \"manik-juneja-railsconf-2014\"\n  title: \"Get More Hands on Your Keyboard\"\n  raw_title: \"RailsConf 2014 - Get More Hands on Your Keyboard by Manik Juneja\"\n  speakers:\n    - Manik Juneja\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-26\"\n  published_at: \"2014-05-26\"\n  description: |-\n    VinSol has been developing on Ruby on Rails since November 2005. Over the years we have created hundreds of great products for the world's best known brands and most innovative start-ups. Whether you are a Solo Developer, a Development Shop, an Agency or a Company of any size - VinSol has something to offer for everyone - Augment your team, Incubate your team or get your product developed by us. Manik will be talking about all our offerings, including our super successful Partnership Program for the Busy Developer.\n\n  video_provider: \"youtube\"\n  video_id: \"DndoNihAzv8\"\n\n- id: \"greg-baugues-railsconf-2014\"\n  title: \"WebRTC Change Communications Forever\"\n  raw_title: \"RailsConf 2014 - WebRTC Change Communications Forever by Greg Baugues\"\n  speakers:\n    - Greg Baugues\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-26\"\n  published_at: \"2014-05-26\"\n  description: |-\n    WebRTC (Real Time Communications) is revolutionizing the way we handle voice, video and data communication by providing native peer-to-peer communication inside the browser. In this talk we'll discuss: - History: How has WebRTC evolved since it's birth just three years ago? - Applications: How are developers using WebRTC beyond video conferencing? (Such as a peer distributed CDN and \"bittorrent in the browser\"). - Getting Started: What is the WebRTC Hello World?\n\n  video_provider: \"youtube\"\n  video_id: \"ImCJxCb3RFg\"\n\n- id: \"adam-hawkins-railsconf-2014\"\n  title: \"Workshop: Applications First, Frameworks Second - Better Systems through Design\"\n  raw_title: \"RailsConf 2014 - Workshop - Applications First, Frameworks Second: Better Systems through Design\"\n  speakers:\n    - Adam Hawkins\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-26\"\n  published_at: \"2014-05-26\"\n  description: |-\n    By Adam Hawkins\n\n    Rails applications come together quickly in the beginning. Drop all these gems in and voila! Overtime test slow down and the productivity is gone. Have you ever questioned why? The framework was used incorrectly. Rails is not your application. It's a delivery mechanism. This talk is about leveraging different design patterns, roles, and boundaries to implement the business logic before even thinking about rails new.\n\n  video_provider: \"youtube\"\n  video_id: \"6JD0VzPIYAg\"\n\n- id: \"jason-sisk-railsconf-2014\"\n  title: \"Service Extraction at Groupon Scale\"\n  raw_title: \"RailsConf 2014 - Service Extraction at Groupon Scale by Jason Sisk & Abhishek Pillai\"\n  speakers:\n    - Jason Sisk\n    - Abhishek Pillai\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-26\"\n  published_at: \"2014-05-26\"\n  description: |-\n    You've probably heard it over and over that extracting services from Rails monoliths is tricky business. But we're here to assure you—it's even trickier when you've got 40+ million active global customers and development teams distributed across the world. So to help illustrate the work that goes into that process, two Groupon engineers are here to talk about the lessons they've learned along the way.\n\n  video_provider: \"youtube\"\n  video_id: \"13SV7MjJugo\"\n\n- id: \"shiv-kumar-railsconf-2014\"\n  title: \"Using Software Analytics to Help Make Better Business Decisions\"\n  raw_title: \"RailsConf 2014 -  Using Software Analytics to Help Make Better Business Decisions\"\n  speakers:\n    - Shiv Kumar\n    - Vince Foley\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-26\"\n  published_at: \"2014-05-26\"\n  description: |-\n    By Shiv Kumar and Vince Foley\n\n    Join New Relic and learn how to make sense of the millions of metrics your software generates. Take a tour of New Relic's extensive product suite and learn how to monitor your software from the front end to the back. Come see how we collect and analyze business metrics in seconds so you can make better data-driven decisions.\n\n  video_provider: \"youtube\"\n  video_id: \"KdmuHgpHJVE\"\n\n- id: \"john-paul-ashenfelter-railsconf-2014\"\n  title: \"Workshop: Machine Learning For Fun and Profit\"\n  raw_title: \"RailsConf 2014 - Workshop - Machine Learning For Fun and Profit by John Paul Ashenfelter\"\n  speakers:\n    - John Paul Ashenfelter\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-26\"\n  published_at: \"2014-05-26\"\n  description: |-\n    Your Rails app is full of data that can (and should!) be turned into useful information with some simple machine learning technqiues. We'll look at basic techniques that are both immediately applicable and the foundation for more advanced analysis -- starting with your Users table.\n\n    We will cover the basics of assigning users to categories, segmenting users by behavior, and simple recommendation algorithms. Come as a Rails dev, leave a data scientist.\n\n  video_provider: \"youtube\"\n  video_id: \"E6CjE0M20jk\"\n\n- id: \"chris-mccord-railsconf-2014\"\n  title: \"Workshop: All Aboard The Elixir Express!\"\n  raw_title: \"RailsConf 2014 - Workshop - All Aboard The Elixir Express! by Chris McCord\"\n  speakers:\n    - Chris McCord\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-26\"\n  published_at: \"2014-05-26\"\n  description: |-\n    Elixir provides the joy and productivity of Ruby with the concurrency and fault-tolerance of Erlang. Together, we'll take a guided tour through the language, going from the very basics to macros and distributed programming. Along the way, we'll see how Elixir embraces concurrency and how we can construct self-healing programs that restart automatically on failure. Attendees should leave with a great head-start into Elixir, some minor language envy, and a strong desire to continue exploration.\n\n  video_provider: \"youtube\"\n  video_id: \"5kYmOyJjGDM\"\n\n- id: \"zach-briggs-railsconf-2014\"\n  title: \"Workshop: Test Drive a Browser Game With JavaScript\"\n  raw_title: \"RailsConf 2014 - Workshop - Test Drive a Browser Game With JavaScript\"\n  speakers:\n    - Zach Briggs\n    - Todd Kaufman\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-27\"\n  published_at: \"2014-05-27\"\n  description: |-\n    By Zach Briggs and Todd Kaufman\n\n    This workshop will cover modern JavaScript development practices through improving an existing browser game. Students will gain hands on experience with JavaScript testing, writing modular software, and building a thick client web app.\n\n    Technologies used will include Jasmine, Lineman, Rails, and Angular; but they do not define the workshop. Skills earned here are applicable to any Web project.\n\n  video_provider: \"youtube\"\n  video_id: \"GzChuWBfA_w\"\n\n- id: \"adam-cuppy-railsconf-2014\"\n  title: \"Workshop: Taming Chaotic Specs - RSpec Design Patterns\"\n  raw_title: \"RailsConf 2014 - Workshop - Taming Chaotic Specs: RSpec Design Patterns by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-27\"\n  published_at: \"2014-05-27\"\n  description: |-\n    Don't you hate when testing takes 3x as long because your specs are hard to understand? Or when testing conditional permutation leads to a ton of duplication? Following a few simple patterns, you can easily take a bloated spec and make it readable, DRY and simple to extend. This workshop is a refactor kata. We will take a bloated sample spec and refactor it to something manageable, readable and concise.\n\n  video_provider: \"youtube\"\n  video_id: \"d2gL6CYaYwQ\"\n\n- id: \"adam-sanderson-railsconf-2014\"\n  title: \"Unreasonable Estimates and Improbable Goals\"\n  raw_title: \"RailsConf 2014 - Unreasonable Estimates and Improbable Goals by Adam Sanderson\"\n  speakers:\n    - Adam Sanderson\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-27\"\n  published_at: \"2014-05-27\"\n  description: |-\n    Your job doesn't start when your fingers touch the keyboard. It starts when someone utters the words: \"How hard would it be?\"\n\n    This is a crash course in estimating work, identifying hidden costs, and dealing with constraints. Along the way we will also learn how to defend against tricks from the Dark Side such as estimation bargaining, ego manipulation, and crunch time.\n\n    They taught me Big-O notation, I wish they taught me this.\n\n    I'm a full stack Rails developer at LiquidPlanner, and have been writing software that helps people get work done for the past dozen years. You'll find me running, walking, biking and eating about town.\n\n  video_provider: \"youtube\"\n  video_id: \"h6Q2dQZ6GlY\"\n\n- id: \"bree-thomas-railsconf-2014\"\n  title: \"Branding for Open Source Success\"\n  raw_title: \"RailsConf 2014 - Branding for Open Source Success by Bree Thomas\"\n  speakers:\n    - Bree Thomas\n  event_name: \"RailsConf 2014\"\n  date: \"2014-05-27\"\n  published_at: \"2014-05-27\"\n  description: |-\n    If you build it, they might come. We all want our open source projects to be widely adopted, but competition in the open source landscape is fierce. Reaching levels of notoriety and adoption akin to the likes of Linux, Rails, or WordPress is increasingly challenging amongst today's volume of seemingly never-ending options. How do you differentiate in a way that is meaningful? It's really about building a 'who', not just a 'what'.\n\n    Bree Thomas (@BreeThomas33) is a Developer at iTriage, and a recent graduate of gSchool by Jumpstartlab. She has a background in Brand Strategy/Marketing and blogs about experiences in both development and marketing at: http://www.nooblife.com/ and http://www.thebratblog.com/.\n\n  video_provider: \"youtube\"\n  video_id: \"ZxHiXIJTaxE\"\n\n- id: \"farrah-bostic-railsconf-2014\"\n  title: \"Keynote: What Happens to Everyone, When Everyone Learns to Code?\"\n  raw_title: \"Rails Conf 2014 - Keynote: What Happens to Everyone, When Everyone Learns to Code?\"\n  speakers:\n    - Farrah Bostic\n  event_name: \"RailsConf 2014\"\n  date: \"2014-07-28\"\n  published_at: \"2014-07-28\"\n  description: |-\n    By Farrah Bostic\n\n  video_provider: \"youtube\"\n  video_id: \"sgoYBNj5xk0\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybf82pLlMnPZjAMMMV5DJsK\"\ntitle: \"RailsConf 2015\"\nkind: \"conference\"\nlocation: \"Atlanta, GA, United States\"\ndescription: |-\n  April 21 - 23, 2015\npublished_at: \"2015-04-21\"\nstart_date: \"2015-04-21\"\nend_date: \"2015-04-23\"\nyear: 2015\nbanner_background: \"#481A4F\"\nfeatured_background: \"#481A4F\"\nfeatured_color: \"#EE9121\"\ncoordinates:\n  latitude: 33.7501275\n  longitude: -84.3885209\n"
  },
  {
    "path": "data/railsconf/railsconf-2015/videos.yml",
    "content": "# TODO: talks running order\n# TODO: talk dates\n\n# Website: https://web.archive.org/web/20150707002816/http://railsconf.com/\n# Schedule: https://web.archive.org/web/20150707002816/http://railsconf.com/schedule\n\n# https://ericbrooke.blog/2015/04/28/rail-2015-being-a-human-atlanta-race-and-community/\n---\n- id: \"david-heinemeier-hansson-railsconf-2015\"\n  title: \"Opening Keynote\"\n  raw_title: \"RailsConf 2015 - Opening Keynote\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  description: |-\n    By, David Heinemeier Hansson\n  video_provider: \"youtube\"\n  video_id: \"KJVTM7mE1Cc\"\n\n- id: \"eduard-koller-railsconf-2015\"\n  title: \"Leveraging Microsoft Azure from Ruby\"\n  raw_title: \"RailsConf 2015 - Leveraging Microsoft Azure from Ruby\"\n  speakers:\n    - Eduard Koller\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    Leveraging Microsoft Azure from Ruby by: Eduard Koller\n\n    Through practical examples and demos, learn how to utilize the various aspects of Microsoft Azure through Ruby. Dive into the Ruby SDK for Azure as well as the Azure gem for fog. Explore cloud storage, virtual machines, and networks among others. Also, learn about the upcoming Spartan browser, and remotely test your site on it from any platform at http://remote.modern.IE\n\n  video_provider: \"youtube\"\n  video_id: \"EncjV-lKwLc\"\n\n- id: \"terence-lee-railsconf-2015\"\n  title: \"Heroku: A Year in Review\"\n  raw_title: \"RailsConf 2015 - Heroku: A Year in Review\"\n  speakers:\n    - Terence Lee\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    Heroku: A Year in Review by: Terence Lee\n\n    If you missed a few days of the Heroku's changelog, not to worry! We're here to fill you in with all the critical info and killer tips. In this session, we will discuss major updates to the Heroku platform and the ways you can use it to make developing your app even easier. We'll leave plenty of time at the end for any questions.\n\n  video_provider: \"youtube\"\n  video_id: \"kCzWZbGHiZE\"\n\n- id: \"aaron-patterson-railsconf-2015\"\n  title: \"Keynote\"\n  raw_title: \"RailsConf 2015 - Keynote: Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  slides_url: \"https://speakerdeck.com/tenderlove/railsconf-2015-keynote\"\n  description: |-\n    By, Aaron Patterson\n\n  video_provider: \"youtube\"\n  video_id: \"B3gYklsN9uc\"\n\n- id: \"koichi-sasada-railsconf-2015\"\n  title: \"What's happening in your Rails app? Introduction to Introspection features of Ruby\"\n  raw_title: \"RailsConf 2015 - What’s happening in your Rails app? Introduction to Introspection features of Ruby\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    By, Koichi Sasada\n    We will talk about introspection features of Ruby interpreter (MRI) to solve troubles on your Ruby on Rails application. Rails application development with Ruby is basically fast and easy. However, when you have trouble such as tough bugs in your app, performance issues and memory consumption issues, they are difficult to solve without tooling. In this presentation, I will show you what kind of introspection features MRI has and how to use them with your Rails application.\n\n  video_provider: \"youtube\"\n  video_id: \"4YtBS0tvkjw\"\n\n- id: \"kir-shatrov-railsconf-2015\"\n  title: \"Building RailsPerf, a toolkit to detect performance regressions\"\n  raw_title: \"RailsConf 2015 - Building RailsPerf, a toolkit to detect performance regressions\"\n  speakers:\n    - Kir Shatrov\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    By, Kir Shatrov\n    Performance regressions in edge Rails versions happen quite often, and are sometimes introduced even by experienced Core commiters. The Rails team doesn’t have any tools to get notified about this kind of regressions yet. This is why I’ve built RailsPerf, a regression detection tool for Rails. It resembles a continuous integration service in a way: it runs benchmarks after every commit in Rails repo to detect any performance regressions. I will speak about building a right set of benchmarks, isolating build environments, and I will also analyze some performance graphs for major Rails versions\n\n  video_provider: \"youtube\"\n  video_id: \"BvUsy_Qb9Es\"\n\n- id: \"noel-rappin-railsconf-2015\"\n  title: \"RSpec: It's Not Actually Magic\"\n  raw_title: \"RailsConf 2015 - RSpec: It's Not Actually Magic\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    By, Noel Rappin\n    RSpec is often described with the word “magic” by both its users and its detractors.\n\n    Understanding how RSpec matchers, doubles, and specifications work will help you as an RSpec user. You will be able to take advantage of RSpec’s flexibility to make your tests clearer and more expressive. You’ll also get some exposure to new RSpec features, like compound matchers.\n\n    Walking through a typical RSpec example, we’ll show the RSpec internals as RSpec evaluates matchers and uses doubles. You’ll leave with a better understanding of how to harness RSpec in your own tests.\n\n  video_provider: \"youtube\"\n  video_id: \"Libc0-0TRg4\"\n\n- id: \"ryan-davis-railsconf-2015\"\n  title: \"Ruby on Rails on Minitest\"\n  raw_title: \"RailsConf 2015 - Ruby on Rails on Minitest\"\n  speakers:\n    - Ryan Davis\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    By, Ryan Davis \\nThe rails \\\"official stack\\\" tests with minitest.\n    Each revision of rails peels back the testing onion and encourages better testing\n    practices. Rails 4.0 switched to minitest 4, Rails 4.1 switched to minitest 5,\n    and Rails 4.2 switched to randomizing the test run order. I'll explain what has\n    happened, explain the motivation behind the changes, and how to diagnose and solve\n    problems you may have as you upgrade. Whether you use minitest already, are considering\n    switching, or just use rspec and are curious what's different, this talk will\n    have something for you.\n  video_provider: \"youtube\"\n  video_id: \"MA4jJNUG_dI\"\n\n- id: \"chakri-uddaraju-railsconf-2015\"\n  title: \"Interviewing like a Unicorn: How Great Teams Hire\"\n  raw_title: \"RailsConf 2015 - Interviewing like a Unicorn: How Great Teams Hire\"\n  speakers:\n    - Chakri Uddaraju\n    - Alaina Percival\n    - Aline Lerner\n    - Allan Grant\n    - Obie Fernandez\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    Interviewing like a Unicorn: How Great Teams Hire by Chakri Uddaraju, Alaina Percival, Aline Lerner, & Allan Grant - Moderated by Obie Fernandez\n\n    Every interview you conduct is bi-directional and creating a bad candidate experience means you'll fail to hire the team that you want to work on – you can't hire great people with a mediocre hiring process. The experts in this session have analyzed thousands of interviews and will share how to create a great candidate experience in your company and how to scale your teams effectively. Candidates can use these same lessons to prepare for interviews and evaluate the companies interviewing them.\n\n  video_provider: \"youtube\"\n  video_id: \"V5b65sHieUw\"\n\n- id: \"gregg-pollack-railsconf-2015\"\n  title: \"Ruby Heroes Awards\"\n  raw_title: \"RailsConf 2015 - Ruby Heroes Awards\"\n  speakers:\n    - Gregg Pollack\n    - Oliver Lacan\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    Presented by, Gregg Pollack & Oliver Lacan\n\n  video_provider: \"youtube\"\n  video_id: \"3bcBNsec-Aw\"\n\n- id: \"evan-phoenix-railsconf-2015\"\n  title: \"Panel: Rails Core\"\n  raw_title: \"RailsConf 2015 - Rails Core Panel Discussion\"\n  speakers:\n    - Evan Phoenix\n    - Aaron Patterson\n    - Santiago Pastorino\n    - Godfrey Chan\n    - Jeremy Kemper\n    - Guillermo Iguaran\n    - Andrew White\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    With,  Aaron Patterson, Santiago Pastorino, Godfrey Chan, Jeremy Kemper, Guillermo Iguaran, and Andrew White\n\n  video_provider: \"youtube\"\n  video_id: \"PdUj8HoH_eA\"\n\n- id: \"peter-bhat-harkins-railsconf-2015\"\n  title: \"What Comes After MVC\"\n  raw_title: \"RailsConf 2015 - What Comes After MVC\"\n  speakers:\n    - Peter Bhat Harkins\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    By, Peter Harkins\n    Rails apps start out quickly and beautifully, but after a year features are a struggle, tests are slow, developers are grinding, and stakeholders are unhappy. \"Skinny controllers and fat models\" hasn't worked, and \"use service objects!\" is awfully vague.\n\n    This talk explains how to compact the \"big ball of mud\" at the heart of your app into a bedrock of reliable code. It gives the steps to incrementally refactor models into a functional core and gives explicit rules for how to write light, reliable tests.\n\n    https://push.cx/talks/railsconf2015\n\n  video_provider: \"youtube\"\n  video_id: \"uFpXKLSREQo\"\n  slides_url: \"https://push.cx/talks/railsconf2015/What%20Comes%20After%20MVC%20-%20Peter%20Harkins,%20RailsConf%202015%20slides.pdf\"\n\n- id: \"greg-baugues-railsconf-2015\"\n  title: \"Passwords are not Enough\"\n  raw_title: \"RailsConf 2015 - Passwords are not Enough\"\n  speakers:\n    - Greg Baugues\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-29\"\n  published_at: \"2015-04-29\"\n  description: |-\n    Passwords are not Enough by: Greg Baugues\n\n    Every week we hear news of another security breach. We’ve learned that retailers aren’t safe from their HVAC vendors, Seth Rogen can stir an international cybersecurity incident, and not even the venerable OpenSSL can be trusted.\n\n    If you're concerned about the security of your Rails app but don't feel like you can spare the time or effort to implement two factor authentication, this talk is for you. We'll discuss the best ways to protect your users' accounts and live code the integration of two factor authentication into your Rails app in less than 15 minutes using Authy.\n\n  video_provider: \"youtube\"\n  video_id: \"i8WpShCXZOE\"\n\n- id: \"joe-mastey-railsconf-2015\"\n  title: \"Bringing UX to Your Code\"\n  raw_title: \"RailsConf 2015 - Bringing UX to Your Code\"\n  speakers:\n    - Joe Mastey\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  description: |-\n    By, Joe Mastey\n    User Centered Design as a process is almost thirty years old now. The philosophy has permeated our products and the way we build our interfaces. But this philosophy is rarely extended to the code we write. We'll take a look at some principles of UX and Interface Design and relate them back to our code. By comparing code that gets it right to code that gets it desperately wrong, we'll learn some principles that we can use to write better, more usable code.\n\n  video_provider: \"youtube\"\n  video_id: \"PI7g4TqLaTY\"\n\n- id: \"derek-prior-railsconf-2015\"\n  title: \"Implementing a Strong Code-Review Culture\"\n  raw_title: \"RailsConf 2015 - Implementing a Strong Code-Review Culture\"\n  speakers:\n    - Derek Prior\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  description: |-\n    By Derek Prior\n\n    Code reviews are not about catching bugs. Modern code reviews are about socialization, learning, and teaching.\n\n    How can you get the most out of a peer's code review and how can you review code without being seen as overly critical? Reviewing code and writing easily-reviewed features are skills that will make you a better developer and a better teammate.\n\n    You will leave this talk with the tools to implement a successful code-review culture. You'll learn how to get more from the reviews you're already getting and how to have more impact with the reviews you leave.\n\n  video_provider: \"youtube\"\n  video_id: \"PJjmw9TRB7s\"\n\n- id: \"aaron-suggs-railsconf-2015\"\n  title: \"Teaching GitHub for Poets\"\n  raw_title: \"RailsConf 2015 - Teaching GitHub for Poets\"\n  speakers:\n    - Aaron Suggs\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  description: |-\n    By Aaron Suggs\n\n    Discover the benefits of training your entire organization to contribute code. Kickstarter teaches GitHub for Poets, a one-hour class that empowers all staff to make improvements to our site, and fosters a culture of transparency and inclusivity.\n\n    Learn about how we’ve made developing with GitHub fun and safe for everyone, and the surprising benefits of having more contributors to our code.\n\n  video_provider: \"youtube\"\n  video_id: \"_DOKUvitb4o\"\n\n- id: \"ernie-miller-railsconf-2015\"\n  title: \"Humane Development\"\n  raw_title: \"RailsConf 2015 - Humane Development\"\n  speakers:\n    - Ernie Miller\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  description: |-\n    By Ernie Miller\n\n    Agile. Scrum. Kanban. Waterfall. TDD. BDD. OOP. FP. AOP. WTH?\n\n    As a software developer, I can adopt methodologies so that I feel there's a sense of order in the world.\n\n    There's a problem with this story: We are humans, developing software with humans, to benefit humans. And humans are messy.\n\n    We wrap ourselves in process, trying to trade people for personas, points, planning poker, and the promise of predictability. Only people aren't objects to be abstracted away. Let's take some time to think through the trade offs we're making together.\n\n  video_provider: \"youtube\"\n  video_id: \"-ZLYxLjwNWo\"\n\n- id: \"liz-certa-railsconf-2015\"\n  title: \"What We Can Learn about Diversity from the Liberal Arts\"\n  raw_title: \"RailsConf 2015 - What We Can Learn about Diversity from the Liberal Arts\"\n  speakers:\n    - Liz Certa\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  description: |-\n    By Liz Certa\n\n    Fostering diversity is a commonly cited goals for the tech community, and - let's be honest - the liberal arts are kicking our butts at it. This was not always the case, though; until very recently, the faces of the liberal arts were exclusively white and male. This changed thanks to distinct strategies and deliberate cultural shifts brought about in the late 20th century, some of which the tech community has copied and others we can use more effectively. In this talk, we will explore some of those strategies by examining the education, history, and culture of the liberal arts.\n\n  video_provider: \"youtube\"\n  video_id: \"VAYbUEViW-I\"\n\n- id: \"lillie-chilen-railsconf-2015\"\n  title: \"Don't Be A Hero: Sustainable Open Source\"\n  raw_title: \"RailsConf 2015 - Don't Be A Hero: Sustainable Open Source\"\n  speakers:\n    - Lillie Chilen\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  description: |-\n    By Lillie Chilen\n\n    We know that low bus numbers, silos, and grueling hours can make hiring a dev nigh impossible. So why are bad conditions accepted as facts of life for open source software maintainers? Let's stop.\n\n    Come learn about how maintainers can become leaders instead of heroes, techniques for building an awesome team for your project, and the ways that everyone else can jump in and support open source software in an effective and sustainable way.\n\n  video_provider: \"youtube\"\n  video_id: \"KpMC8z8r73g\"\n\n- id: \"ben-dixon-railsconf-2015\"\n  title: \"Docker isn’t just for deployment\"\n  raw_title: \"RailsConf 2015 - Docker isn’t just for deployment\"\n  speakers:\n    - Ben Dixon\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  description: |-\n    By, Ben Dixon\n    Docker has taken the world by storm as a tool for deploying applications, but it can be used for much more than that. We wanted to provide our students with fully functioning cloud development environments, including shells, to make teaching Ruby easier.\n\n    Learn how we orchestrate the containers running these development environments and manage the underlying cluster all using a pure ruby toolchain and how deep integration between Rails and Docker has allowed us to provide a unique experience for people learning Ruby online.\n\n  video_provider: \"youtube\"\n  video_id: \"NGcT0dGivoM\"\n\n- id: \"aja-hammerly-railsconf-2015\"\n  title: \"DevOps for The Lazy\"\n  raw_title: \"RailsConf 2015 - DevOps for The Lazy\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  slides_url: \"https://thagomizer.com/files/RailsConf2015.pdf\"\n  description: |-\n    By, Aja Hammerly\n    Like most programmers I am lazy. I don't want to do something by hand if I can automate it. I also think DevOps can be dreadfully dull. Luckily there are now tools that support lazy DevOps. I'll demonstrate how using Docker containers and Kubernetes allows you to be lazy and get back to building cool features (or watching cat videos). I'll go over some of the pros and cons to the \"lazy\" way and I'll show how these tools can be used by both simple and complex apps.\n\n  video_provider: \"youtube\"\n  video_id: \"CVO_imNSw2o\"\n\n- id: \"sebastian-sogamoso-railsconf-2015\"\n  title: \"Microservices, a Bittersweet Symphony\"\n  raw_title: \"RailsConf 2015 - Microservices, a bittersweet symphony\"\n  speakers:\n    - Sebastian Sogamoso\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  description: |-\n    By, Sebastian Sogamoso\n    Like an espresso, code is better served in small portions. Unfortunately most of the time we build systems consisting of a monolithic application that gets bigger and scarier by the day. Fortunately there are a few ways to solve this problem.\n\n    Everyone talks about how good microservices are. At a first glance an architecture of small independently deployable services seems ideal, but it's no free lunch, it comes with some drawbacks.\n\n    In this talk we'll see how microservices help us think differently about writing code and solving problems, and why they are not always the right answer.\n\n  video_provider: \"youtube\"\n  video_id: \"mU4BMf0wS7Q\"\n\n- id: \"smit-shah-railsconf-2015\"\n  title: \"Resilient by Design\"\n  raw_title: \"RailsConf 2015 - Resilient by Design\"\n  speakers:\n    - Smit Shah\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  description: |-\n    By, Smit Shah\n    Modern distributed systems have aggressive requirements around uptime and performance, they need to face harsh realities such as sudden rush of visitors, network issues, tangled databases and other unforeseen bugs.\n\n    With so many moving parts involved even in the simplest of services, it becomes mandatory to adopt defensive patterns which would guard against some of these problems and identify anti-patterns before they trigger cascading failures across systems.\n\n    This talk is for all those developers who hate getting a oncall at 4 AM in the morning.\n\n  video_provider: \"youtube\"\n  video_id: \"_yEz9-Vu8YM\"\n\n- id: \"sandi-metz-railsconf-2015\"\n  title: \"Nothing is Something\"\n  raw_title: \"RailsConf 2015 - Nothing is Something\"\n  speakers:\n    - Sandi Metz\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-30\"\n  published_at: \"2015-04-30\"\n  slides_url: \"https://speakerdeck.com/skmetz/nothing-is-something-railsconf\"\n  description: |-\n    By, Sandi Metz\n\n    Our code is full of hidden assumptions, things that seem like nothing, secrets that we did not name and thus cannot see. These secrets\n    represent missing concepts and this talk shows you how to expose those concepts\n    with code that is easy to understand, change and extend. Being explicit about\n    hidden ideas makes your code simpler, your apps clearer and your life better.\n    Even very small ideas matter. Everything, even nothing, is something.\n\n  video_provider: \"youtube\"\n  video_id: \"OMPfEXIlTVE\"\n\n- id: \"louisa-barrett-railsconf-2015\"\n  title: \"Strategies for being the Junior on the Team\"\n  raw_title: \"RailsConf 2015 - Strategies for being the Junior on the Team\"\n  speakers:\n    - Louisa Barrett\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-01\"\n  published_at: \"2015-05-01\"\n  description: |-\n    By, Louisa Barrett\n    Bootcamps and other non-traditional education options are producing junior developers that can't wait to jump into their first\n    jobs, but many teams are still figuring out how to successfully onboard people\n    whose skills are solidifying and may be hesitant to add a junior to the group.\n    As a junior, how do you go about finding a place for yourself? From thinking through\n    what type of company may be the best fit to strategizing how to find a mentor\n    to help guide you, this talk will discuss what you can do to make sure you get\n    your career off on the right foot.\n  video_provider: \"youtube\"\n  video_id: \"SaNlfSeTWwI\"\n\n- id: \"andr-arko-railsconf-2015\"\n  title: \"How Does Bundler Work, Anyway?\"\n  raw_title: \"RailsConf 2015 - How Does Bundler Work, Anyway?\"\n  speakers:\n    - André Arko\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-01\"\n  published_at: \"2015-05-01\"\n  slides_url: \"https://speakerdeck.com/indirect/how-does-bundler-work-anyway-railsconf-2015\"\n  description: |-\n    By,  Andre Arko\n\n  video_provider: \"youtube\"\n  video_id: \"GvFfd_MCJq0\"\n\n- id: \"sam-phippen-railsconf-2015\"\n  title: \"Understanding Rails Test Types in RSpec\"\n  raw_title: \"RailsConf 2015 - Understanding Rails test types in RSpec\"\n  speakers:\n    - Sam Phippen\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-01\"\n  published_at: \"2015-05-01\"\n  description: |-\n    By, Sam Phippen\n    Getting started with testing Rails applications can be a frought process. There are a range of different test types that one can\n    write. It's often not clear which type one wants. Without care your tests can\n    begin testing the same behaviour. This is problematic.\n\n    In this talk we'll cover the most common types of test you'll encounter in your Rails applications: feature,\n    controller and model. We'll also talk about ways you can design your tests to\n    ensure your suite is robust to changes in your system. If you'd love to learn\n    more about RSpec, Rails, and testing this talk will be great for you.\n  video_provider: \"youtube\"\n  video_id: \"SOi_1reKn8M\"\n\n- id: \"courteney-ervin-railsconf-2015\"\n  title: \"Level Up with OSS: Develop Your Rails Dev Skills Through Open Source Contributions\"\n  raw_title: \"RailsConf 2015 - Level Up with OSS: Develop Your Rails Dev ...\"\n  speakers:\n    - Courteney Ervin\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-01\"\n  published_at: \"2015-05-01\"\n  description: |-\n    By, Courteney Ervin\n    Whether it’s through bootcamps or sheer willpower, hundreds of freshly-minted developers have used Rails to begin their careers. But all of the well-formed Twitter clones in the world are not a replacement for experience working on an active project.\n\n    Enter open source. Open source contributions hone crucial web development skills, like version control; comprehension of an full code base; and even an understanding of agile processes--not to mention being a clear indicator of your hirability. Join us to learn how to push through any intimidation and strengthen your portfolio with open source!\n\n  video_provider: \"youtube\"\n  video_id: \"QJpkRZn2p9k\"\n\n- id: \"kylie-stradley-railsconf-2015\"\n  title: \"Amelia Bedelia Learns to Code\"\n  raw_title: \"RailsConf 2015 - Amelia Bedelia Learns to Code\"\n  speakers:\n    - Kylie Stradley\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-01\"\n  published_at: \"2015-05-01\"\n  slides_url: \"https://speakerdeck.com/kyfast/amelia-bedelia-learns-to-code\"\n  description: |-\n    By, Kylie Stradley\n    \"Did you really think you could make changes to the database by editing the schema file? Who are you, Amelia Bedelia?\"\n\n    The silly mistakes we all made when first learning Rails may be funny to us now, but\n    we should remember how we felt at the time. New developers don't always realize\n    senior developers were once beginners too and may assume they are the first and\n    last developer to mix up when to use the rails and rake commands.\n\n    This talk is a lighthearted examination of the kinds of common errors many Rails developers\n    is a lighthearted examination of the kinds of common errors many Rails developers\n    make and will dig into why so many of us make the same mistakes.\n  video_provider: \"youtube\"\n  video_id: \"bSbla50tqZE\"\n\n- id: \"jillian-foley-railsconf-2015\"\n  title: \"So You Want to Start Refactoring?\"\n  raw_title: \"RailsConf 2015 - So You Want to Start Refactoring?\"\n  speakers:\n    - Jillian Foley\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-01\"\n  published_at: \"2015-05-01\"\n  description: |-\n    By, Jillian Foley\n    New programmers often react with dread when the word \"refactoring\" starts getting thrown around at standup. Maybe you've seen fellow Rubyists struggle with old code, or a colleague spend days on one module only to end up with exactly zero changes to functionality. What exactly is refactoring, and why would anyone want to do it? What are some tips for approaching a refactor, both generally and in Rails?\n  video_provider: \"youtube\"\n  video_id: \"HFaXuMQTnOc\"\n\n- id: \"william-jeffries-railsconf-2015\"\n  title: \"Civic Hacking on Rails\"\n  raw_title: \"RailsConf 2015 - Civic Hacking on Rails\"\n  speakers:\n    - William Jeffries\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-04\"\n  published_at: \"2015-05-04\"\n  description: |-\n    Civic Hacking on Rails by William Jeffries\n\n    Do you want to use your coding skills for good rather than for evil? Did you ever want to build something to make your city or your community suck less? Here are some lessons from a civic hacker on how to kickstart your project. Hint: it's nothing like writing a gem.\n\n  video_provider: \"youtube\"\n  video_id: \"BlFtNc76x9Q\"\n\n- id: \"pete-holiday-railsconf-2015\"\n  title: \"Workshop: Do Users Love Your API? Developer-focused API Design\"\n  raw_title: \"RailsConf 2015 - Workshop: Do Users Love Your API? Developer-focused API Design\"\n  speakers:\n    - Pete Holiday\n    - Kate Harlan\n    - Nate Ranson\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-04\"\n  published_at: \"2015-05-04\"\n  description: |-\n    By Pete Holiday, Kate Harlan and Nate Ranson\n\n    Do Users Love Your API? Developer-focused API Design\n\n  video_provider: \"youtube\"\n  video_id: \"8p10bGFM9dg\"\n\n- id: \"starr-horne-railsconf-2015\"\n  title: \"SVG Charts and Graphics with Ruby\"\n  raw_title: \"RailsConf 2015 - SVG Charts and Graphics with Ruby\"\n  speakers:\n    - Starr Horne\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-05\"\n  published_at: \"2015-05-05\"\n  description: |-\n    By Starr Horne\n\n    Many people assume that the only way to add interesting charts and visualizations to their web applications is via JavaScript. But this isn't true. You don't need a 900 kB JavaScript library to generate simple charts. Instead you can use SVG and Ruby. Once you learn how to build your own SVG graphics then it's possible to do cool things like cache them, or use your own CSS and JavaScript to manipulate them. This presentation will show you how.\n\n  video_provider: \"youtube\"\n  video_id: \"yCCtDpW_apk\"\n\n- id: \"eileen-m-uchitelle-railsconf-2015\"\n  title: \"Breaking Down the Barrier: Demystifying Contributing to Rails\"\n  raw_title: \"RailsConf 2015 - Breaking Down the Barrier: Demystifying Contributing to Rails\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-05\"\n  published_at: \"2015-05-05\"\n  slides_url: \"https://speakerdeck.com/eileencodes/railsconf-2015-breaking-down-the-barrier-demystifying-contributing-to-rails\"\n  description: |-\n    by Eileen Uchitelle\n\n    Contributing to Rails for the first time can be terrifying. In this lab I’ll make contributing to Rails more approachable by going over the contributing guidelines and technical details you need to know. We’ll walk through traversing the source code with tools such as CTags, source_location and TracePoint. Additionally, we’ll create reproduction scripts for reporting issues and learn advanced git commands like bisect and squash. At the end of this session you’ll have the confidence to fix bugs and add features to Ruby on Rails\n\n  video_provider: \"youtube\"\n  video_id: \"7zoD6NZy6vY\"\n\n- id: \"jessica-dillon-railsconf-2015\"\n  title: \"Implementing a Visual CSS Testing Framework\"\n  raw_title: \"RailsConf 2015 - Implementing a Visual CSS Testing Framework\"\n  speakers:\n    - Jessica Dillon\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-06\"\n  published_at: \"2015-05-06\"\n  description: |-\n    by Jessica Dillon\n\n    Working with large CSS codebases can be hard. Large-scale refactors, or even just tweaking styles on our more general elements, could end up having unintended consequences on the rest of the site. To catch these problems, we manually check every page on our site, which is a slow and error-prone approach. We need a better way to test our CSS. This talk will walk through how we implemented a visual CSS testing framework using RSpec & Selenium, using automatic screenshot comparison to catch style regressions.\n\n  video_provider: \"youtube\"\n  video_id: \"Q4ttqkIEM7g\"\n\n- id: \"jeremy-fairbank-railsconf-2015\"\n  title: \"Dynamically Sassy\"\n  raw_title: \"RailsConf 2015 - Dynamically Sassy\"\n  speakers:\n    - Jeremy Fairbank\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-06\"\n  published_at: \"2015-05-06\"\n  description: |-\n    by Jeremy Fairbank\n\n    When we want to offer customizability to the users of our applications, things can get tricky. How do we allow users to customize the look of the user interface while reusing the static CSS we’ve already designed?\n\n    There is a way, but it is fraught with many dangers. Learn about the power of dynamically generating CSS from Sass files. Tackle the foes of dynamic content injection, rendering, caching, and background processing. In the end, we will look triumphantly at our ability to reuse our application styles to create customizable interfaces for our end users.\n\n  video_provider: \"youtube\"\n  video_id: \"ouGWyZfGZ8M\"\n\n- id: \"daniel-schierbeck-railsconf-2015\"\n  title: \"Curly — Rethinking the View Layer\"\n  raw_title: \"RailsConf 2015 - Curly — Rethinking the View Layer\"\n  speakers:\n    - Daniel Schierbeck\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-06\"\n  published_at: \"2015-05-06\"\n  description: |-\n    by Daniel Schierbeck\n\n    While most parts of Rails have been thoroughly overhauled during the past few years, one part has stubbornly refused improvement. The view layer is still by default using ERB to transform your app’s objects into HTML. While trying to solve a seemingly unrelated problem we discovered a design that suddenly enabled us to move past the limitations of ERB while still integrating closely with Rails. We could now separate presentation logic from display structure; reason about our views and how they relate; and dramatically improve our code. We called the library Curly, and it's pretty awesome.\n  video_provider: \"youtube\"\n  video_id: \"JsZ3YmdVMxo\"\n\n- id: \"bree-thomas-railsconf-2015\"\n  title: \"Burn Rubber Does Not Mean Warp Speed\"\n  raw_title: \"RailsConf 2015 - Burn Rubber Does Not Mean Warp Speed\"\n  speakers:\n    - Bree Thomas\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    By, Bree Thomas\n    We talk about bringing new developers \"up to speed quickly.\" Imposter syndrome is bad enough, but often junior developers feel pressured to learn faster and produce more. Developers often focus on velocity as the critical measure of success. The need for speed actually amplifies insecurities, magnifies imposter syndrome, and hinders growth. Instead let's talk about how we can track and plan progress using meaningful goals and metrics.\n  video_provider: \"youtube\"\n  video_id: \"9Xyc708VV1g\"\n\n- id: \"daniel-spector-railsconf-2015\"\n  title: \"Crossing the Bridge: Connecting Rails and Your Front-End Framework\"\n  raw_title: \"RailsConf 2015 - Crossing the Bridge: Connecting Rails and Your Front-End Framework\"\n  speakers:\n    - Daniel Spector\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    by Daniel Spector\n\n    Javascript front-end frameworks like Ember, React and Angular are really useful tools for building out beautiful and seamless UIs. But how do you make it work with Rails? How do you include the framework, share data, avoid expensive repeated network calls in a consistent way?\n\n    In this talk we will review a variety of different approaches and look at real world cases for creating a seamless bridge between your Javascript and Rails\n  video_provider: \"youtube\"\n  video_id: \"VsVwMrEuaoY\"\n\n- id: \"dennis-ushakov-railsconf-2015\"\n  title: \"Ruby Debugger Internals\"\n  raw_title: \"RailsConf 2015 - Ruby Debugger Internals\"\n  speakers:\n    - Dennis Ushakov\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    by Dennis Ushakov\n\n    How does a Ruby debugger look and work on the inside? Is it difficult to write a debugger? Hear the full story of supporting Ruby 2.0 straight from the maintainer of the RubyMine debugger. In this session we'll expose debugger internals, including different APIs used by debuggers; review how they evolved; and look at what it takes to keep the performance of a debugged application at a reasonable level. We'll also talk about alternative implementations including JRuby and Rubinius.\n  video_provider: \"youtube\"\n  video_id: \"ikhoXFyy85w\"\n\n- id: \"nick-sutterer-railsconf-2015\"\n  title: \"Trailblazer: A new Architecture for Rails\"\n  raw_title: \"RailsConf 2015 - Trailblazer: A new Architecture for Rails\"\n  speakers:\n    - Nick Sutterer\n    - J Austin Hughey\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    by Nick Sutterer and J Austin Hughey\n\n    Trailblazer introduces several new abstraction layers into Rails. It gives developers structure and architectural guidance and finally answers the question of \"Where do I put this kind of code?\" in Rails. This talk walks you through a realistic development of a Rails application with Trailblazer and discusses every bloody aspect of it.\n  video_provider: \"youtube\"\n  video_id: \"qSxN4mlyQO8\"\n\n- id: \"nick-merwin-railsconf-2015\"\n  title: \"Delivering Autonomous Rails Apps behind Corporate Firewalls\"\n  raw_title: \"RailsConf 2015 - Delivering Autonomous Rails Apps behind Corporate Firewalls\"\n  speakers:\n    - Nick Merwin\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    by Nick Merwin\n\n    When a Fortune 500 company wants to use your app but can't risk sharing sensitive data in the cloud, you'll need to package and deploy an autonomous version of it behind their firewall (aka the Fog). We’ll explore some methods to make this possible including standalone VM provisioning, codebase security, encrypted package distribution, seat based licensing and code updates.\n  video_provider: \"youtube\"\n  video_id: \"V6e_A9VzPy8\"\n\n- id: \"steve-kinney-railsconf-2015\"\n  title: \"Using JavaScript from the Future in Your Rails App Today\"\n  raw_title: \"RailsConf 2015 - Using JavaScript from the Future in Your Rails App Today\"\n  speakers:\n    - Steve Kinney\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    By, Steve Kinney\n    ECMAScript 6 has a metric ton of new Ruby-friendly features that make working with JavaScript less painful—including but not limited to: classes, implicitly returning functions, string interpolation, and modules. In this session, we'll take a look at how you can use these features today in your Rails applications.\n  video_provider: \"youtube\"\n  video_id: \"Ayj1kgQNhAg\"\n\n- id: \"jim-jones-railsconf-2015\"\n  title: \"Your Front End Framework is Overkill - Server Side Javascript w/ Rails\"\n  raw_title: \"RailsConf 2015 -  Your Front End Framework is Overkill - Server Side Javascript w/ Rails\"\n  speakers:\n    - Jim Jones\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    By, Jim Jones\n    For dynamic apps, Rails has taken a backseat to client side frameworks such as AngularJS, Ember and Backbone.\n\n    Learn how to use server side javascript effectively to greatly simplify your code base and reuse your view logic. We'll implement parallel apps with vanilla Rails js responses, AngularJS and Ember.js so that we can contrast the implementations and evaluate the tradeoffs.\n  video_provider: \"youtube\"\n  video_id: \"7YLYZQJZB0E\"\n\n- id: \"michael-chan-railsconf-2015\"\n  title: \"React.js on Rails\"\n  raw_title: \"RailsConf 2015 - React.js on Rails\"\n  speakers:\n    - Michael Chan\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    By, Michael Chan\n    React is the best way to bring interactive UIs to your Rails apps. But using React.js on Rails can be hard. NPM libraries are difficult to include, JSX seems nonsensical, and “can we still use CoffeeScript?”\n\n    There’s not one obvious path for working with React.js on Rails. In this talk, we’ll review the sordid past of Rails and JavaScript, explore the complementarity of React and Rails, and navigate the woes of integrating with NPM. We’ll discover why React is a natural fit for Rails today and how to make Rails love React in the future.\n  video_provider: \"youtube\"\n  video_id: \"kTSsZrub5iE\"\n\n- id: \"jonathan-jackson-railsconf-2015\"\n  title: \"Rails and EmberCLI: an integration love story\"\n  raw_title: \"RailsConf 2015 - Rails and EmberCLI: an integration love story\"\n  speakers:\n    - Jonathan Jackson\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    By, Jonathan Jackson\n    With the \"Path to 2.0\" CFP EmberCLI was and is projected to become a first class citizen in the Ember world. And there was much joy. However, it placed a question mark on the Rails integration story. First we had globals, then ember-rails, then Ember App Kit. Just as a bead was being drawn on the proper way... EmberCLI. EmberCLI Rails is a new gem which facilitates an integration story we can love.\n\n    Full stack testing (no \"Air gap\")\n    simple installation\n    Sustainability\n    Configurable setup\n    Potential for simple deployments\n    Let's learn how easy integration can be.\n  video_provider: \"youtube\"\n  video_id: \"NnquHUlh0Pk\"\n\n- id: \"karim-butt-railsconf-2015\"\n  title: \"Internet of Things: Connecting Rails with the Real World\"\n  raw_title: \"RailsConf 2015 - Internet of Things: Connecting Rails with the Real World\"\n  speakers:\n    - Karim Butt\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    By, Karim Butt\n    According to Gartner, there will be nearly 26 billion devices on the Internet of Things (IoT) by 2020. ABI Research estimates that more than 30 billion devices will be wirelessly connected to the IoT by 2020. This discussion provides examples examples, ideas, tools and best-practices for Rails developers to start building IoT applications that connect their web applications to the real world.\n  video_provider: \"youtube\"\n  video_id: \"4FtnvyH0qq4\"\n\n- id: \"jaime-lyn-schatz-railsconf-2015\"\n  title: \"Beyond Hogwarts: A Half-Blood's Perspective on Inclusive Magical Education\"\n  raw_title: \"RailsConf 2015 - Beyond Hogwarts: A Half-Blood's Perspective on Inclusive Magical Education\"\n  speakers:\n    - Jaime Lyn Schatz\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    By, Jaime Lyn Schatz\n    When Voldemort and his forces threatened us all, two of the three wizards (and witch) who led his defeat were not raised in the magical world. Schools like Hogwarts can help us identify and train those with innate magical talents and interests whom we might otherwise never discover. But how to find and teach those beyond the reach of our owls? This talk explores our options and will serve as a call to action for the Magical world. As we will see, these challenges are almost magically mirrored by the Rails community as we seek to find and train developers from non-traditional paths.\n  video_provider: \"youtube\"\n  video_id: \"ZHlEw0ZYStY\"\n\n- id: \"pamela-o-vickers-railsconf-2015\"\n  title: \"Crossing the Canyon of Cognizance: A Shared Adventure\"\n  raw_title: \"RailsConf 2015 - Crossing the Canyon of Cognizance: A Shared Adventure\"\n  speakers:\n    - Pamela O. Vickers\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-07\"\n  published_at: \"2015-05-07\"\n  description: |-\n    By, Pamela O. Vickers\n    Most of the four learning stages - unconscious incompetence, conscious incompetence, conscious competence and unconscious competence - are bridged by acquiring experience. But the gap between unconscious incompetence to conscious competence is where the most discomfort and discouragement occurs.\n\n    Helping new developers bridge the void ensures a vibrant, accessible community, and having visible members/mentors in each stage encourages newcomers' learning. This talk illustrates (literally!) how to help new colleagues build this bridge and prevent losing them in the what-do-I-even-Google abyss.\n  video_provider: \"youtube\"\n  video_id: \"1GEVTl084C4\"\n\n- id: \"barrett-clark-railsconf-2015\"\n  title: \"Making Data Dance\"\n  raw_title: \"RailsConf 2015 - Making Data Dance\"\n  speakers:\n    - Barrett Clark\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-08\"\n  published_at: \"2015-05-08\"\n  description: |-\n    by Barrett Clark\n\n    Rails and the ActiveRecord gem are really handy tools to get work done, and do it quickly. They aren't a silver bullet, though. Sometimes the database is the best place to run a complicated query. Especially when you have big transactional or time-series data. Databases are also incredibly powerful, and can do remarkable things at scale. Why not take advantage of that power?\n\n    This talk will discuss some of the things that you can do with PostgreSQL that will both blow your mind and also help you transform data into knowledge. Let's have some fun playing with data together!\n  video_provider: \"youtube\"\n  video_id: \"3CUTl7vELL4\"\n\n- id: \"raimonds-simanovskis-railsconf-2015\"\n  title: \"Data Warehouses and Multi-Dimensional Data Analysis\"\n  raw_title: \"RailsConf 2015 - Data Warehouses and Multi-Dimensional Data Analysis\"\n  speakers:\n    - Raimonds Simanovskis\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-08\"\n  published_at: \"2015-05-08\"\n  description: |-\n    by Raimonds Simanovskis\n\n    Typical Rails applications have database schemas that are designed for on-line transaction processing. But when the data volumes grow then they are not well suited for effective data analysis. You probably need a data warehouse and specialized data analysis tools for that. This presentation will cover * an introduction to a data warehouse and multi-dimensional schema design, * comparison of traditional and analytical databases, * extraction, transformation and load (ETL) of data, * On-Line Analytical Processing (OLAP) tools, Mondrian OLAP engine in particular and how to use it from Ruby.\n  video_provider: \"youtube\"\n  video_id: \"mURhRy9plrY\"\n\n- id: \"charles-wood-railsconf-2015\"\n  title: \"What I've Learned in 7 Years of Podcasting about Ruby\"\n  raw_title: \"RailsConf 2015 - What I've Learned in 7 Years of Podcasting about Ruby\"\n  speakers:\n    - Charles Wood\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-08\"\n  published_at: \"2015-05-08\"\n  description: |-\n    by Charles Wood\n\n    You may be surprised to know that the things that you learn after talking to hundreds of programmers (mostly about Ruby) is that the lessons you learn are mostly lessons about people. The oddest thing about this is that it's had a very profound effect on the way I write code.\n\n    We will walk through the years of podcasting and screencasting shows like Ruby Rogues, Rails Coach, and Teach Me To Code and discuss what we can learn from each other, what I've learned from you, and how that changes who we are and how we code.\n  video_provider: \"youtube\"\n  video_id: \"Pkf-wN-fDHw\"\n\n- id: \"pamela-o-vickers-railsconf-2015-railconf-2015-crossing-the-can\"\n  title: \"RailConf 2015 - Crossing the Canyon of Cognizance: A Shared Adventure\"\n  raw_title: \"RailConf 2015 - Crossing the Canyon of Cognizance: A Shared Adventure\"\n  speakers:\n    - Pamela O. Vickers\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-08\"\n  published_at: \"2015-05-08\"\n  description: |-\n    By, Pamela O. Vickers\n    Most of the four learning stages - unconscious incompetence, conscious incompetence, conscious competence and unconscious competence - are bridged by acquiring experience. But the gap between unconscious incompetence to conscious competence is where the most discomfort and discouragement occurs. Helping new developers bridge the void ensures a vibrant, accessible community, and having visible members/mentors in each stage encourages newcomers' learning. This talk illustrates (literally!) how to help new colleagues build this bridge and prevent losing them in the what-do-I-even-Google abyss.\n  video_provider: \"youtube\"\n  video_id: \"_HoaAIYcihY\"\n\n- id: \"stephan-hagemann-railsconf-2015\"\n  title: \"Get Started with Component-based Rails Applications!\"\n  raw_title: \"RailsConf 2015 - Get started with Component-based Rails applications!\"\n  speakers:\n    - Stephan Hagemann\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-08\"\n  published_at: \"2015-05-08\"\n  description: |-\n    by Stephan Hagemann\n\n    Component-based Rails helps you regain control over your sprawling Rails application. It helps you structure your new Rails application in a way that it will stay more manageable longer. It helps you think completely differently about writing applications - not just in Ruby and Rails!\n\n    This session will help you pass the initial hurdle of getting started with component-based Rails. While there is nothing really new, there is a lot that is just a little different. We will go over those differences so your start with component-based Rails is a smooth one.\n  video_provider: \"youtube\"\n  video_id: \"MsRPxS7Cu_Q\"\n\n- id: \"justin-searls-railsconf-2015\"\n  title: \"Sometimes a Controller is Just a Controller\"\n  raw_title: \"RailsConf 2015 - Sometimes a Controller is Just a Controller\"\n  speakers:\n    - Justin Searls\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-11\"\n  published_at: \"2015-05-11\"\n  description: |-\n    By, Justin Searls\n    You grok SOLID. You practice TDD. You've read Sandi's book…twice. You rewatch Destroy All Software monthly. You can pronounce GOOS. You know your stuff!\n\n    But some of your coworkers say your code is too complex or confusing for them. You might rush to conclude that must be a them problem.\n\n    But doubt lingers: what if they're right?\n\n    After all, the more thought we put into a bit of code, the more information that code carries. Others must extract that embedded meaning, either by careful reading or shared experience. Sometimes boring code is better. Let's figure out when to be dull.\n  video_provider: \"youtube\"\n  video_id: \"MSgR-hJjdTo\"\n  alternative_recordings:\n    - title: \"Sometimes a Controller is Just a Controller\"\n      raw_title: \"RailsConf 2015 - Sometimes a Controller is Just a Controller\"\n      speakers:\n        - Justin Searls\n      event_name: \"RailsConf 2015\"\n      date: \"2015-05-12\"\n      description: |-\n        By, Justin Searls\n        You grok SOLID. You practice TDD. You've read Sandi's book…twice. You rewatch Destroy All Software monthly. You can pronounce GOOS. You know your stuff!\n\n        But some of your coworkers say your code is too complex or confusing for them. You might rush to conclude that must be a them problem.\n\n        But doubt lingers: what if they're right?\n\n        After all, the more thought we put into a bit of code, the more information that code carries. Others must extract that embedded meaning, either by careful reading or shared experience. Sometimes boring code is better. Let's figure out when to be dull.\n      video_provider: \"youtube\"\n      video_id: \"a6gel0eVeNw\"\n\n- id: \"james-dabbs-railsconf-2015\"\n  title: \"Processes and Threads - Resque vs. Sidekiq\"\n  raw_title: \"RailsConf 2015 - Processes and Threads - Resque vs. Sidekiq\"\n  speakers:\n    - James Dabbs\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, James Dabbs\n    Background job processing is an important component of most large Rails applications. Two of the most common solutions - Resque and Sidekiq - are largely differentiated by one underlying architectural decision: processes or threads?\n\n    Is this talk, we'll provide a gentle introduction to threads and processes, and then crack open the Resque and Sidekiq gems to see how they work. Along the way, we'll learn a bit about concurrency at the OS and Ruby layers, and about how some of the tools we rely on every day are written.\n  video_provider: \"youtube\"\n  video_id: \"_8X96hMaRXI\"\n\n- id: \"stan-ng-railsconf-2015\"\n  title: \"5 Secrets We Learned While Building a Bank in 16 Months\"\n  raw_title: \"RailsConf 2015 - 5 Secrets We Learned While Building a Bank in 16 Months\"\n  speakers:\n    - Stan Ng\n    - John Phamvan\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    by Stan Ng and John Phamvan\n\n    Payoff has a crazy goal; we want to solve America’s credit card debt problem. After a risky 8-week Ruby rewrite of our 500k line C# personal finance website, we decided that wasn’t audacious enough. So we set out to become a financial institution in order to help folks get out of credit card debt. In the past 16-months, we taught the rest of the engineers Ruby, figured out how to lend money, wrote all the systems and automation needed for a small bank, and hired 70 more super nice people to make it real. If you have a crazy goal to change the world, come listen to our story.\n  video_provider: \"youtube\"\n  video_id: \"s3zorwIjPL0\"\n\n- id: \"nadia-odunayo-railsconf-2015\"\n  title: \"Playing Games In The Clouds\"\n  raw_title: \"RailsConf 2015 - Playing Games In The Clouds\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, Nadia Odunayo\n    What does haggling at a garage sale have to do with load balancing in distributed systems? How does bidding in an art auction relate to cloud service orchestration? Familiarity with the ideas and technologies involved in cloud computing is becoming ever more important for developers. This talk will demonstrate how you can use game theory — the study of strategic decision making — to design more efficient, and innovative, distributed systems.\n  video_provider: \"youtube\"\n  video_id: \"1hl20hpOxpo\"\n\n- id: \"dan-kozlowski-railsconf-2015\"\n  title: \"High performance APIs in Ruby using ActiveRecord and Goliath\"\n  raw_title: \"RailsConf 2015 - High performance APIs in Ruby using ActiveRecord and Goliath\"\n  speakers:\n    - Dan Kozlowski\n    - Colin Kelley\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, Dan Kozlowski & Colin Kelley\n    We had a real-time API in Rails that needed much lower latency and massive throughput. We wanted to preserve our investment in business logic inside ActiveRecord models while scaling up to 1000X throughput and cutting latency in half. Conventional wisdom would say this was impossible in Ruby, but we succeeded and actually surpassed our expectations. We'll discuss how we did it, using Event-Machine for the reactor pattern, Synchrony to avoid callback hell and to make testing easy, Goliath as the non-blocking web server, and sharding across many cooperative processes.\n  video_provider: \"youtube\"\n  video_id: \"U8An88L5nBk\"\n\n- id: \"scott-feinberg-railsconf-2015\"\n  title: \"Why Your New API Product Will Fail\"\n  raw_title: \"RailsConf 2015 - Why Your New API Product Will Fail\"\n  speakers:\n    - Scott Feinberg\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, Scott Feinberg\n    Congrats! You've built the one API to control them all, and it's amazing. It's fast, well-architected, and Level 3 Hypermedia. However everyone is still using your competitors sub-par product... Why? We developers are lazy and you're making it hard for us to use. We're diving into your SDKs tests to solve basic tasks, your SDK + API errors annoy and don't help us fix our mistakes, and the lack of logical defaults leaves us playing parameter roulette.\n\n    Let's explore how to build API-enabled products that fellow developers will love using with great docs, tooling, support, and community.\n  video_provider: \"youtube\"\n  video_id: \"HVNEG1TR2S8\"\n\n- id: \"julian-simioni-railsconf-2015\"\n  title: \"You, Too, Can Be A Webserver\"\n  raw_title: \"RailsConf 2015 - You, Too, Can Be A Webserver\"\n  speakers:\n    - Julian Simioni\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, Julian Simioni\n    What actually happens when we visit a website? As developers, we're supposed to know all about this, but when our browsers have millions of lines of code, and our backends have fancy service-oriented-architectures with dozens of components, it's hard to keep it all in our heads.\n\n    Fortunately, we have amazing tools to help us. We can bypass the complexity of browsers and servers, and simply examine the communication between them. Let's use these tools and look at the underlying patterns shared across the entire web, from the simplest static pages to the most sophisticated web apps.\n  video_provider: \"youtube\"\n  video_id: \"Nq84_XSS5iQ\"\n\n- id: \"joo-moura-railsconf-2015\"\n  title: \"AMS, API, Rails and a developer, a Love Story\"\n  raw_title: \"RailsConf 2015 - AMS, API, Rails and a developer, a Love Story\"\n  speakers:\n    - João Moura\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, João Moura\n    A lot of people have being using Rails to develop both their internal or external API, but building a high quality API can be hard, and performance is a key point to achieve it.\n\n    I'll share my stories with APIs, and tell you how Active Model Serializer, component of Rails-API, helped me. AMS have being used across thousands of applications bringing convention over configuration to JSON generation.\n\n    This talk will give you a sneak peek of a new version of AMS that we have being working on, it's new cache conventions, and how it's being considered to be shipped by default in new Rails 5.\n  video_provider: \"youtube\"\n  video_id: \"PqgQNgWdUB8\"\n\n- id: \"christian-joudrey-railsconf-2015\"\n  title: \"Scaling Rails for Black Friday and Cyber Monday\"\n  raw_title: \"RailsConf 2015 - Scaling Rails for Black Friday and Cyber Monday\"\n  speakers:\n    - Christian Joudrey\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    by Christian Joudrey\n\n    Shopify is an e-commerce platform that powers over 150,000 online shops such as Tesla and GitHub. During the weekend of Black Friday and Cyber Monday, the platform gets hit with over a million requests per minute resulting in over 6,000 orders per minute (~50 million dollars.)\n\n    Learn how we scale our Rails app and the measures we take (load testing, monitoring, caching, etc.) to ensure that there are no hiccups during this important weekend.\n  video_provider: \"youtube\"\n  video_id: \"O1UxbZVP6N8\"\n\n- id: \"eric-weinstein-railsconf-2015\"\n  title: \"So Long, Hoboken: Migrating a Huge Production Codebase from Sinatra to Rails\"\n  raw_title: \"RailsConf 2015 - So Long, Hoboken: Migrating a Huge Production Codebase from Sinatra to Rails\"\n  speakers:\n    - Eric Weinstein\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, Eric Weinstein\n    Software is grown, not built, and that becomes clearest when we need to change it. This talk will discuss the motivations behind a framework migration, how to divide that migration into soluble subproblems, and how to conquer those subproblems in a test-driven way, all while ensuring the new codebase is designed with further growth in mind. We'll touch on mounting Rack applications inside Rails, SOA architecture, and how to map components of one framework to another.\n  video_provider: \"youtube\"\n  video_id: \"5SDWBLV3tSg\"\n\n- id: \"richard-schneeman-railsconf-2015\"\n  title: \"Speed Science\"\n  raw_title: \"RailsConf 2015 - Speed Science\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, Richard Schneeman\n    Run your app faster, with less RAM and a quicker boot time today. How? With science! In this talk we'll focus on the process of turning performance problems into reproducible bugs we can understand and squash. We'll look at real world use cases where small changes resulted in huge real world performance gains. You'll walk away with concrete and actionable advice to improve the speed of your app, and with the tools to equip your app for a lifetime of speed. Live life in the fast lane, with science!\n  video_provider: \"youtube\"\n  video_id: \"m2nj5sUE3hg\"\n\n- id: \"katherine-wu-railsconf-2015\"\n  title: \"Slightly Less Painful Time Zones\"\n  raw_title: \"RailsConf 2015 - Slightly Less Painful Time Zones\"\n  speakers:\n    - Katherine Wu\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, Katherine Wu\n    For developers, there are two things that are certain for time zones: you can’t avoid having to deal with them, and you will screw them up at some point. There are, however, some ways to mitigate the pain. This talk will discuss tactics for avoiding time zone mayhem, using a feature to send out weekly email reports in a customer’s local time zone as a case study. It will cover idiosyncrasies of how time zones are handled in Ruby and Rails, how to write tests to avoid false positives, and advice on how to release time zone-related code changes more safely.\n  video_provider: \"youtube\"\n  video_id: \"VFDurYw6aZ8\"\n\n- id: \"claudio-baccigalupo-railsconf-2015\"\n  title: \"Better callbacks in Rails 5\"\n  raw_title: \"RailsConf 2015 - Better callbacks in Rails 5\"\n  speakers:\n    - Claudio Baccigalupo\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, Claudio Baccigalupo\n    In Rails 5, the old way of returning false to implicitly halt a callback chain will not work anymore.\n\n    This change will impact any codebase using ActiveSupport, ActiveRecord, ActiveModel or ActiveJob.\n\n    Methods like before_action, before_save, before_validation will require developers to explicitly throw an exception in order the halt the chain.\n\n    This talk will explain the motivations behind the new default, will delve into the internals of Rails to show the actual code, and will help developers and gem maintainers safely upgrade their apps to Rails 5.\n  video_provider: \"youtube\"\n  video_id: \"X5WJ-v4MLzw\"\n\n- id: \"lance-gleason-railsconf-2015\"\n  title: \"Adventures in Federating Authorization and Authentication with OAuth\"\n  raw_title: \"RailsConf 2015 - Adventures in Federating Authorization and Authentication with OAuth\"\n  speakers:\n    - Lance Gleason\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-12\"\n  published_at: \"2015-05-12\"\n  description: |-\n    By, Lance Gleason\n    With projects like Doorkeeper, OAuth has pretty solid support in Rails when dealing with one application. However, when Rails applications get larger, many project teams break up their monolithic application into services. Some suggest installing Doorkeeper on every service, whereas others recommend routing all traffic through a single service.\n\n    Recently, we worked on a project where neither of these solutions seemed right. Join us as we talk about our experience in federating OAuth in order to handle over 30,000 concurrent users.\n  video_provider: \"youtube\"\n  video_id: \"c1ikzPLUPFA\"\n\n- id: \"yehuda-katz-railsconf-2015\"\n  title: \"Bending the Curve: How Rust Helped Us Write Better Ruby\"\n  raw_title: \"RailsConf 2015 - Bending the Curve: How Rust Helped Us Write Better Ruby\"\n  speakers:\n    - Yehuda Katz\n    - Tom Dale\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-13\"\n  published_at: \"2015-05-13\"\n  description: |-\n    by Yehuda Katz and Tom Dale\n\n    Ruby is a productive language that developers love. When Ruby isn't fast enough, they often fall back to writing C extensions. But C extensions are scary for a number of reasons; it's easy to leak memory, or segfault the entire process. When we started to look at writing parts of the Skylight agent using native code, Rust was still pretty new, but its promise of low-level control with high-level safety intrigued us. We'll cover the reasons we went with Rust, how we structured our code, and how you can do it too. If you're looking to expand your horizons, Rust may be the language for you.\n  video_provider: \"youtube\"\n  video_id: \"j9J7dLaxyog\"\n\n- id: \"chandra-carney-railsconf-2015\"\n  title: \"How to Program with Accessibility in Mind\"\n  raw_title: \"RailsConf 2015 - How to Program with Accessibility in Mind\"\n  speakers:\n    - Chandra Carney\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-13\"\n  published_at: \"2015-05-13\"\n  description: |-\n    by Chandra Carney\n\n    What does accessibility entail as it is related to the web? Most developers don't consider that someone with visual impairments may use the web and don't think about what this experience may be like for someone who has a visual impairment. The current trend is to push access-driven design to the end of feature building, but we will explore why this needs to be a top priority.\n  video_provider: \"youtube\"\n  video_id: \"lmbT-QyCTZM\"\n\n- id: \"chase-douglas-railsconf-2015\"\n  title: \"Metasecurity: Beyond Patching Vulnerabilities\"\n  raw_title: \"RailsConf 2015 - Metasecurity: Beyond Patching Vulnerabilities\"\n  speakers:\n    - Chase Douglas\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-13\"\n  published_at: \"2015-05-13\"\n  description: |-\n    by Chase Douglas\n\n    Rails comes with many powerful security protections out of the box, but no code is perfect. This talk will highlight a new approach to web app security, one focusing on a higher level of abstraction than current techniques. We will take a look at current security processes and tools and some common vulnerabilities still found in many Rails apps. Then we will investigate novel ways to protect against these vulnerabilities.\n  video_provider: \"youtube\"\n  video_id: \"dof0EspDPlU\"\n\n- id: \"david-furber-railsconf-2015\"\n  title: \"Rapid Data Modeling Using ActiveRecord and the JSON Data Type\"\n  raw_title: \"RailsConf 2015 - Rapid Data Modeling Using ActiveRecord and the JSON Data Type\"\n  speakers:\n    - David Furber\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-13\"\n  published_at: \"2015-05-13\"\n  description: |-\n    by David Furber\n\n    So you are building an app that has a ton of forms each with tons of fields. Your heart sinks as you think of writing and managing all those models, migrations and associations. PostgreSQL JSON column and ActiveRecord::Store to the rescue! This talk covers a way to wrap these Rails 4 features to simplify the building of extensive hierarchical data models. You will learn to expressively declare schema-less attributes on your model that act much like “real\" columns, meaning they are typecast, validated, query able, embeddable, and behave with Rails form builders.\n  video_provider: \"youtube\"\n  video_id: \"7cYjoguB-n0\"\n\n- id: \"sharon-steed-railsconf-2015\"\n  title: \"How to Talk to Humans: a Different Approach to Soft Skills\"\n  raw_title: \"RailsConf 2015 - How to Talk to Humans: a Different Approach to Soft Skills\"\n  speakers:\n    - Sharon Steed\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-13\"\n  published_at: \"2015-05-13\"\n  description: |-\n    by Sharon Steed\n\n    Developers are trained to communicate to things with a goal in mind. When you're talking to something like, say a computer, you type in your code and it responds by giving you back what you want. Simple and straight-forward. Talking to humans? That's more of a challenge. Why? Because communicating with people requires a special set of skills - namely, empathy and a little bit of storytelling. In an industry filled with brilliant minds, great ideas and mass disruption, so few of the best and brightest know how to tell their compelling story. This workshop will teach you how.\n  video_provider: \"youtube\"\n  video_id: \"S1F8rVKyqGU\"\n\n- id: \"ben-klang-railsconf-2015\"\n  title: \"Now Hear This! Putting Real-Time Voice, Video and Text into Rails\"\n  raw_title: \"RailsConf 2015 - Now Hear This! Putting Real-Time Voice, Video and Text into Rails\"\n  speakers:\n    - Ben Klang\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-13\"\n  published_at: \"2015-05-13\"\n  description: |-\n    By, Ben Klang\n    When you want to talk to someone, where do you turn? Skype? Slack or HipChat? Maybe even an old-fashioned telephone? As great (or not) as these are, they all fail in one important way: Context. As developers, why don’t we enable our users to communicate where they are doing everything else, right inside the browser or mobile app? The technology to make contextual communications is evolving quickly with exciting technologies like WebRTC, speech recognition and natural language processing. This talk is about how to apply those building blocks and bring contextual communication to your apps.\n  video_provider: \"youtube\"\n  video_id: \"5JF4EKm9Evk\"\n\n- id: \"andy-croll-railsconf-2015\"\n  title: \"ActiveJob: A Service Oriented Architecture\"\n  raw_title: \"RailsConf 2015 - ActiveJob: A Service Oriented Architecture\"\n  speakers:\n    - Andy Croll\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-13\"\n  published_at: \"2015-05-13\"\n  description: |-\n    By, Andy Croll\n    Running tasks outside the request-response loop is a must in modern web apps.\n\n    ActiveJob is a great addition to Rails (in 4.2) providing a standard interface to various asynchronous gems (Delayed_Job/Sidekiq etc). Has it also ushered in something else? A way to do 'Service Objects' the 'Rails Way'?\n  video_provider: \"youtube\"\n  video_id: \"60LH3em78V8\"\n\n- id: \"justin-collins-railsconf-2015\"\n  title: \"The World of Rails Security\"\n  raw_title: \"RailsConf 2015 - The World of Rails Security\"\n  speakers:\n    - Justin Collins\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-13\"\n  published_at: \"2015-05-13\"\n  description: |-\n    By, Justin Collins\n    Learning to keep your Rails application secure is an often-overlooked part of learning Rails, so let's take a trip through the world of Ruby on Rails security! The journey will start with an overview of security features offered by the popular web framework, then we'll detour through dangerous pitfalls and unsafe defaults, and finally end with suggestions for improving security in Rails itself. As a bonus, we'll talk about how to integrate security into the development process.\n  video_provider: \"youtube\"\n  video_id: \"AFOlxqQCTxs\"\n\n- id: \"michael-may-railsconf-2015\"\n  title: \"The power of cache in a slow world\"\n  raw_title: \"RailsConf 2015 - The power of cache in a slow world\"\n  speakers:\n    - Michael May\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-13\"\n  published_at: \"2015-05-13\"\n  description: |-\n    By, Michael May\n    Most of us have some form of cache anxiety. We’re good at caching static content like images and scripts, but taking the next step - caching dynamic and user-specific content - is confusing and often requires a leap of faith. In this talk you’ll learn new and old strategies for caching dynamic content, HTTP performance rules to live by, and a better understanding of how to accelerate any application. This is just what the doctor ordered: a prescription for cache money.\n  video_provider: \"youtube\"\n  video_id: \"AuKn65E8T3w\"\n\n- id: \"michel-weksler-railsconf-2015\"\n  title: \"(Re)Building a large scale payments system on Rails\"\n  raw_title: \"RailsConf 2015 - (Re)Building a large scale payments system on Rails\"\n  speakers:\n    - Michel Weksler\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-14\"\n  published_at: \"2015-05-14\"\n  description: |-\n    By, Michel Weksler\n    Payments applications typically require a strong audit trail, very predictable failure behavior and strong transactional integrity. In Ruby/Rails, ActiveRecord allows any part of the code to modify anything in the database, failures are often silently ignored, and database transactions are hidden for convenience by default. In this talk I'll explore how to solve those problems and use RoR to build a large scale payments system.\n  video_provider: \"youtube\"\n  video_id: \"3pskVqOenoM\"\n\n- id: \"adam-cuppy-railsconf-2015\"\n  title: \"What If Shakespeare Wrote Ruby?\"\n  raw_title: \"RailsConf 2015 - What If Shakespeare Wrote Ruby?\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-14\"\n  published_at: \"2015-05-14\"\n  description: |-\n    By, Adam Cuppy\n    Did you know that Shakespeare wrote almost no direction into his plays? No fight direction. No staging. No notes to the songs. Of the 1700 words he created, there was no official dictionary. That’s right the author of some of the greatest literary works in history, which were filled with situational complexity, fight sequences and music, include NO documentation! How did he do it?\n\n    In this talk, we're going \"thee and thou.\" I'm going to give you a crash course in how: Shakespeare writes software.\n  video_provider: \"youtube\"\n  video_id: \"aeSTsMEKxkY\"\n\n- id: \"godfrey-chan-railsconf-2015\"\n  title: \"Prying Open The Black Box\"\n  raw_title: \"RailsConf 2015 - Prying Open The Black Box\"\n  speakers:\n    - Godfrey Chan\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-14\"\n  published_at: \"2015-05-14\"\n  slides_url: \"https://speakerdeck.com/chancancode/prying-open-the-black-box\"\n  description: |-\n    By, Godfrey Chan\n    Every once a while, Rails might behave in strange ways that you did not expect, and it could be difficult to figure out what is really going on. Was it a bug in the framework? Could it be one of the gems I am using? Did I do something wrong? In this session, we will look at some tips, tricks and tools to help you debug your Rails issues. Along the way, you will also learn how to dive into the Rails codebase without getting lost. The next time you a mysterious bug finds its way into your Rails applications, you will be well-equipped to pry open the black box yourself!\n  video_provider: \"youtube\"\n  video_id: \"IjbYhE9mWuk\"\n\n- id: \"ben-klang-railsconf-2015-now-hear-this-putting-real-tim\"\n  title: \"Now Hear This! Putting Real-Time Voice, Video and Text into Rails\"\n  raw_title: \"RailsConf 2015 - Now Hear This! Putting Real-Time Voice, Video and Text into Rails\"\n  speakers:\n    - Ben Klang\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-14\"\n  published_at: \"2015-05-14\"\n  description: |-\n    By, Ben Klang\n    When you want to talk to someone, where do you turn? Skype? Slack or HipChat? Maybe even an old-fashioned telephone? As great (or not) as these are, they all fail in one important way: Context. As developers, why don’t we enable our users to communicate where they are doing everything else, right inside the browser or mobile app? The technology to make contextual communications is evolving quickly with exciting technologies like WebRTC, speech recognition and natural language processing. This talk is about how to apply those building blocks and bring contextual communication to your apps.\n  video_provider: \"youtube\"\n  video_id: \"Umve48uvlWc\"\n\n- id: \"sean-griffin-railsconf-2015\"\n  title: \"Designing a Great Ruby API - How We're Simplifying Rails 5\"\n  raw_title: \"RailsConf 2015 - Designing a Great Ruby API - How We're Simplifying Rails 5\"\n  speakers:\n    - Sean Griffin\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-14\"\n  published_at: \"2015-05-14\"\n  description: |-\n    By, Sean Griffin\n    The most useful APIs are simple and composeable. Omnipotent DSLs can be great, but sometimes we want to just write Ruby. We're going to look at the process of designing a new API for attributes and type casting in Rails 5.0, and why simpler is better. We'll unravel some of the mysteries behind the internals of Active Record. After all, Rails is ultimately just a large legacy code base. In this talk you'll learn about the process of finding those simple APIs which are begging to be extracted, and the refactoring process that can be used to tease them out slowly.\n  video_provider: \"youtube\"\n  video_id: \"PUuYAksQWg4\"\n\n- id: \"joe-mastey-railsconf-2015-bringing-ux-to-your-code\"\n  title: \"Bringing UX to Your Code\"\n  raw_title: \"RailsConf 2015 - Bringing UX to Your Code\"\n  speakers:\n    - Joe Mastey\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-14\"\n  published_at: \"2015-05-14\"\n  description: |-\n    By, Joe Mastey\n    User Centered Design as a process is almost thirty years old now. The philosophy has permeated our products and the way we build our interfaces. But this philosophy is rarely extended to the code we write. We'll take a look at some principles of UX and Interface Design and relate them back to our code. By comparing code that gets it right to code that gets it desperately wrong, we'll learn some principles that we can use to write better, more usable code.\n  video_provider: \"youtube\"\n  video_id: \"RZolYCvdn4o\"\n\n- id: \"emily-xie-railsconf-2015\"\n  title: \"Coding: Art or Craft?\"\n  raw_title: \"RailsConf 2015 - Coding: Art or Craft?\"\n  speakers:\n    - Emily Xie\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-14\"\n  published_at: \"2015-05-14\"\n  description: |-\n    By, Emily Xie\n    Developers often refer to their trade as both “art” and “craft,\" using the two interchangeably. Yet, the terms traditionally refer to different ends of the creative spectrum. So what is code? Art or craft?\n\n    Come explore these questions in this interdisciplinary talk: What is art versus craft? How does coding fit in once we make this distinction? Is the metaphor we use to describe coding even important––and why? You’ll walk away from this discussion with a better understanding of what creating and programming means to you, and what it could mean to others.\n  video_provider: \"youtube\"\n  video_id: \"ZPob24tpPNI\"\n\n- id: \"sandi-metz-railsconf-2015-nothing-is-something\"\n  title: \"Nothing is Something\"\n  raw_title: \"RailsConf 2015 - Nothing is Something\"\n  speakers:\n    - Sandi Metz\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-14\"\n  published_at: \"2015-05-14\"\n  description: |-\n    By, Sandi Metz\n    Our code is full of hidden assumptions, things that seem like nothing, secrets that we did not name and thus cannot see. These secrets represent missing concepts and this talk shows you how to expose those concepts with code that is easy to understand, change and extend. Being explicit about hidden ideas makes your code simpler, your apps clearer and your life better. Even very small ideas matter. Everything, even nothing, is something.\n  video_provider: \"youtube\"\n  video_id: \"29MAL8pJImQ\"\n\n- id: \"sara-chipps-railsconf-2015\"\n  title: \"Keynote - Day 1 Closing\"\n  raw_title: \"RailsConf 2015 - Keynote - Day 1 Closing\"\n  speakers:\n    - Sara Chipps\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-14\"\n  published_at: \"2015-05-01\"\n  description: |-\n    By, Sara Chipps\n\n  video_provider: \"youtube\"\n  video_id: \"_OOZfod2rC4\"\n\n- id: \"lightning-talks-day-1-railsconf-2015\"\n  title: \"Lightning Talks (Day 1)\"\n  raw_title: \"RailsConf 2015 - Day 1 Lightning TALKS\"\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-14\"\n  published_at: \"2015-05-14\"\n  description: |-\n    00:12 - Obie Fernandez\n    01:28 - Gustavo Robles\n    02:21 - Lance Gleason @lgleasain\n    07:10 - Claudio Baccigalupo\n    12:10 - Christopher Rigor @crigor\n    15:30 - Chris Kibble @ckib16\n    17:53 - Reid Morrison @reidmorrison\n    23:17 - Joshua Quick\n    24:34 - Jason Charnes\n    25:50 - Amy @sailorhg\n    27:59 - André Arko @indirect\n    31:04 - Shane Defazio -\n    33:16 - Jeremy Evans @jeremyevans0\n    37:53 - Isaac Sloan @elorest\n    43:05 - Joe Dean @joeddean\n    48:40 - Nitie Sharma\n    52:12 - Mike Virata-Stone @smellsblue\n    56:45 - Gabriel Halley @ghalley\n    01:00:55 - Aaron Harpole @harpaa01\n    01:03:05 - Ryan Davis @the_zenspider\n    01:06:47 - Elle Meredith @aemerdith\n    01:12:04 - Gonzalo Maldonado @elg0nz\n    01:17:43 - Peter Degen-Portnoy @PDegenPortnoy\n    01:21:56 - Jeff Casimir @j3\n    01:27:30 - Ivan Tse @ivan_tse\n    01:32:11 - Hsing-Hui Hsu @SoManyHs\n    01:36:57 - Adam Cuppy @adamcuppy\n  video_provider: \"youtube\"\n  video_id: \"N92aD4mNUFA\"\n  talks:\n    - title: \"Lightning Talk: Andela\"\n      start_cue: \"00:12\"\n      end_cue: \"01:28\"\n      video_provider: \"parent\"\n      id: \"obie-fernandez-lighting-talk-railsconf-2015\"\n      video_id: \"obie-fernandez-lighting-talk-railsconf-2015\"\n      speakers:\n        - Obie Fernandez\n\n    - title: \"Lightning Talk: MagmaConf\"\n      start_cue: \"01:28\"\n      end_cue: \"02:21\"\n      video_provider: \"parent\"\n      id: \"gustavo-robles-lighting-talk-railsconf-2015\"\n      video_id: \"gustavo-robles-lighting-talk-railsconf-2015\"\n      speakers:\n        - Gustavo Robles\n\n    - title: \"Lightning Talk: Chick Tracts\"\n      start_cue: \"02:22\"\n      end_cue: \"07:10\"\n      thumbnail_cue: \"03:28\"\n      video_provider: \"parent\"\n      id: \"lance-gleason-lighting-talk-railsconf-2015\"\n      video_id: \"lance-gleason-lighting-talk-railsconf-2015\"\n      speakers:\n        - Lance Gleason\n\n    - title: \"Lightning Talk: Collection Routing in Rails 5\"\n      start_cue: \"07:10\"\n      end_cue: \"12:10\"\n      thumbnail_cue: \"07:15\"\n      video_provider: \"parent\"\n      id: \"claudio-baccigalupo-lighting-talk-railsconf-2015\"\n      video_id: \"claudio-baccigalupo-lighting-talk-railsconf-2015\"\n      speakers:\n        - Claudio Baccigalupo\n\n    - title: \"Lightning Talk: Underwater Ruby\"\n      start_cue: \"12:10\"\n      end_cue: \"15:30\"\n      thumbnail_cue: \"12:12\"\n      video_provider: \"parent\"\n      id: \"christopher-rigor-lighting-talk-railsconf-2015\"\n      video_id: \"christopher-rigor-lighting-talk-railsconf-2015\"\n      speakers:\n        - Christopher Rigor\n\n    - title: \"Lightning Talk: CodeNewbie\"\n      start_cue: \"15:30\"\n      end_cue: \"17:53\"\n      thumbnail_cue: \"16:10\"\n      video_provider: \"parent\"\n      id: \"chris-kibble-lighting-talk-railsconf-2015\"\n      video_id: \"chris-kibble-lighting-talk-railsconf-2015\"\n      speakers:\n        - Chris Kibble\n\n    - title: \"Lightning Talk: Reid Morrison\"\n      start_cue: \"17:53\"\n      end_cue: \"23:17\"\n      thumbnail_cue: \"18:00\"\n      video_provider: \"parent\"\n      id: \"reid-morrison-lighting-talk-railsconf-2015\"\n      video_id: \"reid-morrison-lighting-talk-railsconf-2015\"\n      speakers:\n        - Reid Morrison\n\n    - title: \"Lightning Talk: Joshua Quick\"\n      start_cue: \"23:19\"\n      end_cue: \"24:34\"\n      thumbnail_cue: \"24:17\"\n      video_provider: \"parent\"\n      id: \"joshua-quick-lighting-talk-railsconf-2015\"\n      video_id: \"joshua-quick-lighting-talk-railsconf-2015\"\n      speakers:\n        - Joshua Quick\n\n    - title: \"Lightning Talk: Anxiety and Depression\"\n      start_cue: \"24:34\"\n      end_cue: \"25:50\"\n      thumbnail_cue: \"TODO\"\n      video_provider: \"parent\"\n      id: \"jason-charnes-lighting-talk-railsconf-2015\"\n      video_id: \"jason-charnes-lighting-talk-railsconf-2015\"\n      speakers:\n        - Jason Charnes\n\n    - title: \"Lightning Talk: Bubble Sort Zines\"\n      start_cue: \"25:50\"\n      end_cue: \"27:59\"\n      thumbnail_cue: \"26:15\"\n      video_provider: \"parent\"\n      id: \"amy-wibowo-lighting-talk-railsconf-2015\"\n      video_id: \"amy-wibowo-lighting-talk-railsconf-2015\"\n      speakers:\n        - Amy Wibowo\n\n    - title: \"Lightning Talk: Ruby Infrastructure\"\n      start_cue: \"27:59\"\n      end_cue: \"31:04\"\n      thumbnail_cue: \"28:16\"\n      video_provider: \"parent\"\n      id: \"andre-arko-lighting-talk-railsconf-2015\"\n      video_id: \"andre-arko-lighting-talk-railsconf-2015\"\n      speakers:\n        - André Arko\n\n    - title: \"Lightning Talk: Move is hiring\"\n      start_cue: \"31:04\"\n      end_cue: \"33:16\"\n      thumbnail_cue: \"31:27\"\n      video_provider: \"parent\"\n      id: \"shane-defazio-lighting-talk-railsconf-2015\"\n      video_id: \"shane-defazio-lighting-talk-railsconf-2015\"\n      speakers:\n        - Shane Defazio\n\n    - title: \"Lightning Talk: Roda\"\n      start_cue: \"33:16\"\n      end_cue: \"37:53\"\n      thumbnail_cue: \"33:17\"\n      video_provider: \"parent\"\n      id: \"jeremy-evans-lighting-talk-railsconf-2015\"\n      video_id: \"jeremy-evans-lighting-talk-railsconf-2015\"\n      speakers:\n        - Jeremy Evans\n\n    - title: \"Lightning Talk: Authorization and Petergate\"\n      start_cue: \"37:53\"\n      end_cue: \"43:05\"\n      thumbnail_cue: \"38:18\"\n      video_provider: \"parent\"\n      id: \"isaac-sloan-lighting-talk-railsconf-2015\"\n      video_id: \"isaac-sloan-lighting-talk-railsconf-2015\"\n      speakers:\n        - Isaac Sloan\n\n    - title: \"Lightning Talk: Help Teach Kids To Code!\"\n      start_cue: \"43:05\"\n      end_cue: \"48:40\"\n      thumbnail_cue: \"43:08\"\n      video_provider: \"parent\"\n      id: \"joe-dean-lighting-talk-railsconf-2015\"\n      video_id: \"joe-dean-lighting-talk-railsconf-2015\"\n      speakers:\n        - Joe Dean\n\n    - title: \"Lightning Talk: Nitie Sharma\"\n      start_cue: \"48:41\"\n      end_cue: \"52:12\"\n      thumbnail_cue: \"48:47\"\n      video_provider: \"parent\"\n      id: \"nitie-sharma-lighting-talk-railsconf-2015\"\n      video_id: \"nitie-sharma-lighting-talk-railsconf-2015\"\n      speakers:\n        - Nitie Sharma\n\n    - title: \"Lightning Talk: <% reading rails %>\"\n      start_cue: \"52:12\"\n      end_cue: \"56:45\"\n      thumbnail_cue: \"52:34\"\n      video_provider: \"parent\"\n      id: \"mike-virata-stone-lighting-talk-railsconf-2015\"\n      video_id: \"mike-virata-stone-lighting-talk-railsconf-2015\"\n      speakers:\n        - Mike Virata-Stone\n\n    - title: \"Lightning Talk: When does one feel like a Rails Expert?\"\n      start_cue: \"56:45\"\n      end_cue: \"01:00:55\"\n      thumbnail_cue: \"56:55\"\n      video_provider: \"parent\"\n      id: \"gabriel-halley-lighting-talk-railsconf-2015\"\n      video_id: \"gabriel-halley-lighting-talk-railsconf-2015\"\n      speakers:\n        - Gabriel Halley\n\n    - title: \"Lightning Talk: Bh - Bootstrap helpers for Ruby\"\n      start_cue: \"01:00:55\"\n      end_cue: \"01:03:05\"\n      thumbnail_cue: \"01:01:00\"\n      video_provider: \"parent\"\n      id: \"aaron-harpole-lighting-talk-railsconf-2015\"\n      video_id: \"aaron-harpole-lighting-talk-railsconf-2015\"\n      speakers:\n        - Aaron Harpole\n\n    - title: \"Lightning Talk: debride & minitest-bisect\"\n      start_cue: \"01:03:05\"\n      end_cue: \"01:06:47\"\n      thumbnail_cue: \"01:03:10\"\n      video_provider: \"parent\"\n      id: \"ryan-davis-lighting-talk-railsconf-2015\"\n      video_id: \"ryan-davis-lighting-talk-railsconf-2015\"\n      speakers:\n        - Ryan Davis\n\n    - title: \"Lightning Talk: Rails Camp 'merica\"\n      start_cue: \"01:06:47\"\n      end_cue: \"01:12:04\"\n      thumbnail_cue: \"01:06:52\"\n      video_provider: \"parent\"\n      id: \"elle-meredith-lighting-talk-railsconf-2015\"\n      video_id: \"elle-meredith-lighting-talk-railsconf-2015\"\n      speakers:\n        - Elle Meredith\n\n    - title: \"Lightning Talk: 5 ways we screwed up Microservices\"\n      start_cue: \"01:12:04\"\n      end_cue: \"01:17:43\"\n      thumbnail_cue: \"01:12:09\"\n      video_provider: \"parent\"\n      id: \"gonzalo-maldonado-lighting-talk-railsconf-2015\"\n      video_id: \"gonzalo-maldonado-lighting-talk-railsconf-2015\"\n      speakers:\n        - Gonzalo Maldonado\n\n    - title: \"Lightning Talk: Mars One\"\n      start_cue: \"01:17:44\"\n      end_cue: \"01:21:56\"\n      thumbnail_cue: \"01:17:45\"\n      video_provider: \"parent\"\n      id: \"peter-degen-lighting-talk-railsconf-2015\"\n      video_id: \"peter-degen-lighting-talk-railsconf-2015\"\n      speakers:\n        - Peter Degen\n\n    - title: \"Lightning Talk: Remarkable Technical Mentorship\"\n      start_cue: \"01:21:56\"\n      end_cue: \"01:27:30\"\n      thumbnail_cue: \"01:22:01\"\n      video_provider: \"parent\"\n      id: \"jeff-casimir-lighting-talk-railsconf-2015\"\n      video_id: \"jeff-casimir-lighting-talk-railsconf-2015\"\n      speakers:\n        - Jeff Casimir\n\n    - title: \"Lightning Talk: Linters - Integrating them into our workflows\"\n      start_cue: \"01:27:30\"\n      end_cue: \"01:32:11\"\n      thumbnail_cue: \"01:27:35\"\n      video_provider: \"parent\"\n      id: \"ivan-tse-lighting-talk-railsconf-2015\"\n      video_id: \"ivan-tse-lighting-talk-railsconf-2015\"\n      speakers:\n        - Ivan Tse\n\n    - title: \"Lightning Talk: Measles\"\n      start_cue: \"01:32:11\"\n      end_cue: \"01:36:57\"\n      thumbnail_cue: \"01:33:19\"\n      video_provider: \"parent\"\n      id: \"hsing-hui-hsu-lighting-talk-railsconf-2015\"\n      video_id: \"hsing-hui-hsu-lighting-talk-railsconf-2015\"\n      speakers:\n        - Hsing-Hui Hsu\n\n    - title: \"Lightning Talk: Highfives\"\n      start_cue: \"01:36:57\"\n      end_cue: \"1:40:35\"\n      thumbnail_cue: \"01:37:03\"\n      video_provider: \"parent\"\n      id: \"adam-cuppy-lighting-talk-railsconf-2015\"\n      video_id: \"adam-cuppy-lighting-talk-railsconf-2015\"\n      speakers:\n        - Adam Cuppy\n\n- id: \"paola-moretto-railsconf-2015\"\n  title: \"A New Kind of Analytics: Actionable Performance Analysis\"\n  raw_title: \"RailsConf 2015 -  A New Kind of Analytics: Actionable Performance Analysis\"\n  speakers:\n    - Paola Moretto\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-19\"\n  published_at: \"2015-05-19\"\n  description: |-\n    by Paola Moretto\n\n    Applications today are spidery and include thousands of possible optimization points. No matter how deep performance testing data are, developers are still at a loss when asked to derive meaningful and actionable data that pinpoint to bottlenecks in the application. You know things are slow, but you are left with the challenge of figuring out where to optimize. This presentation describes a new kind of analytics, called performance analytics, that provide tangible ways to root cause performance problems in today’s applications and clearly identify where and what to optimize.\n  video_provider: \"youtube\"\n  video_id: \"72zRL4LYd7g\"\n\n- id: \"randy-coulman-railsconf-2015\"\n  title: \"Getting a Handle on Legacy Code\"\n  raw_title: \"RailsConf 2015 - Getting a Handle on Legacy Code\"\n  speakers:\n    - Randy Coulman\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-20\"\n  published_at: \"2015-05-20\"\n  description: |-\n    By, Randy Coulman\n    We all run into legacy code. Sometimes, we even write it ourselves. Working with legacy code can be a daunting challenge, but there are ways to tackle it without taking on the risk of a full rewrite.\n\n    There is a deep satisfaction that comes from conquering a nasty piece of legacy code. The ability to achieve this goal depends on both testing and refactoring.\n\n    We'll learn how baby-step refactoring techniques lead to a better understanding of the code and a high-quality design while always keeping the code running.\n  video_provider: \"youtube\"\n  video_id: \"lsFFjFp7mEE\"\n\n- id: \"paola-moretto-railsconf-2015-a-new-kind-of-analytics-action\"\n  title: \"A New Kind of Analytics: Actionable Performance Analysis\"\n  raw_title: \"RailsConf 2015 - A New Kind of Analytics: Actionable Performance Analysis\"\n  speakers:\n    - Paola Moretto\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-20\"\n  published_at: \"2015-05-20\"\n  description: |-\n    By, Paola Moretto\n    Applications today are spidery and include thousands of possible optimization points. No matter how deep performance testing data are, developers are still at a loss when asked to derive meaningful and actionable data that pinpoint to bottlenecks in the application. You know things are slow, but you are left with the challenge of figuring out where to optimize. This presentation describes a new kind of analytics, called performance analytics, that provide tangible ways to root cause performance problems in today’s applications and clearly identify where and what to optimize.\n  video_provider: \"youtube\"\n  video_id: \"gtFcClubNXw\"\n\n- id: \"alex-wood-railsconf-2015\"\n  title: \"Deploy and Manage Ruby on Rails Apps on AWS\"\n  raw_title: \"RailsConf 2015 - Deploy and Manage Ruby on Rails Apps on AWS\"\n  speakers:\n    - Alex Wood\n    - Trevor Rowe\n    - Loren Segal\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-20\"\n  published_at: \"2015-05-20\"\n  description: |-\n    By, Alex Wood, Trevor Rowe, and Loren Segal\n    In this hands-on lab, we will get you started with running your Rails applications on AWS. Starting with a simple sample application, we will walk you through deploying to AWS, then enhancing your application with features from the AWS SDK for Ruby's Rails plugin.\n  video_provider: \"youtube\"\n  video_id: \"OQoYTeGJYf4\"\n\n- id: \"jamis-buck-railsconf-2015\"\n  title: \"Voila, Indexes! A Look at Some Simple Preventative Magick\"\n  raw_title: \"RailsConf 2015 - Voila, Indexes! A Look at Some Simple Preventative Magick\"\n  speakers:\n    - Jamis Buck\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-20\"\n  published_at: \"2015-05-20\"\n  description: |-\n    By Jamis Buck\n    A gentleman wizard and his sarcastic manservant examine a common anti-pattern in schema design, in which indexes are “left for later”. The pitfalls and dangers of this approach are set forth. Right incantations (which is to say, scenarios and sample code) for battling this devious tendency will be presented, with all magic (that is, “buzz”) words thoroughly demystified and clearly explained. Walk away with a new understanding of why your application tables deserve indexes from day one, and how to make sure you’ve got them covered.\n  video_provider: \"youtube\"\n  video_id: \"nYfMDnmmitY\"\n\n- id: \"craig-buchek-railsconf-2015\"\n  title: \"http://exploration\"\n  raw_title: \"RailsConf 2015 - http://exploration\"\n  speakers:\n    - Craig Buchek\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-20\"\n  published_at: \"2015-05-20\"\n  description: |-\n    By, Craig Buchek\n    We're web developers. But how well do we know the web's core protocol, HTTP? In this lab, we'll explore the protocol to see exactly what's going on between the browser and the web server. We'll cover: HTTP basics HTTP methods (GET, POST, PUT, etc.) HTTPS Troubleshooting tools Proxies Caching HTTP/2 We'll investigate how we can take advantage of HTTP features to troubleshoot problems, and to improve the performance of our Rails apps.\n  video_provider: \"youtube\"\n  video_id: \"kmfUfjpDpz0\"\n\n- id: \"caleb-hearth-railsconf-2015\"\n  title: \"What is this PGP thing, and how can I use it?\"\n  raw_title: \"RailsConf 2015 - What is this PGP thing, and how can I use it?\"\n  speakers:\n    - Caleb Hearth\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-20\"\n  published_at: \"2015-05-20\"\n  description: |-\n    By, Caleb Thompson\n    The need to keep your personal information, sensitive or nonsensitive, secure from prying eyes isn't new, but recent events have brought it back into the public eye. In this workshop, we'll build and upload public keys, explore Git commit signing, and learn to sign others' PGP keys. If we have time, we'll exchange key fingerprints and show IDs, then discuss signing and verifying gems. You'll need a photo ID and your own computer for this workshop.\n  video_provider: \"youtube\"\n  video_id: \"7xz2P4i34ic\"\n\n- id: \"nathen-harvey-railsconf-2015\"\n  title: \"Test Driving your Rails Infrastructure with Chef\"\n  raw_title: \"RailsConf 2015 - Test Driving your Rails Infrastructure with Chef\"\n  speakers:\n    - Nathen Harvey\n    - Nell Shamrell-Harrington\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-21\"\n  published_at: \"2015-05-21\"\n  description: |-\n    by Nathen Harvey and Nell Shamrell-Harrington\n\n    Managing your infrastructure with configuration management tools like Chef melds the practices of development and operations together. This workshop will focus on a development practice - Test Driven Development - and how that method can be applied to managing your Rails infrastructure and deployments. You will learn how to: Analyze your application and define your infrastructure needs (databases, load balancers, etc.), define unique infrastructure requirements for Rails applications (i.e. asset pipeline), capture your requirements in tests using Test Kitchen, ServerSpec, and other frameworks\n  video_provider: \"youtube\"\n  video_id: \"vvc2mWGvwE0\"\n\n- id: \"eduardo-gutierrez-railsconf-2015\"\n  title: \"Ambitious Capybara\"\n  raw_title: \"RailsConf 2015 - Ambitious Capybara\"\n  speakers:\n    - Eduardo Gutierrez\n  event_name: \"RailsConf 2015\"\n  date: \"2015-05-26\"\n  published_at: \"2015-05-26\"\n  description: |-\n    By, Eduardo Gutierrez\n    Capybara has allowed us to build complex and ambitious applications with the confidence that everything comes together in the user experience we're targeting. As the capabilities of the web have grown, interactions and behavior in our applications have become more complex and harder to test. Our tests become coupled to CSS selectors, fail intermittently, take longer and our confidence dwindles. In this talk, I'll go over best practices for working with a large Capybara test suite and dig into APIs and options we can use to handle complex apps such as a chat app not written in Ruby.\n  video_provider: \"youtube\"\n  video_id: \"BvLJDr6RkCI\"\n\n- id: \"kent-beck-railsconf-2015\"\n  title: \"Closing Keynote: Ease at Work\"\n  raw_title: \"RailsConf 2015 - Closing Keynote\"\n  speakers:\n    - Kent Beck\n  event_name: \"RailsConf 2015\"\n  date: \"2015-04-28\"\n  published_at: \"2015-04-28\"\n  description: |-\n    By, Kent Beck\n\n  video_provider: \"youtube\"\n  video_id: \"aApmOZwdPqA\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2016/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZGYLfj6oRQWPxB6ijg1YsC\"\ntitle: \"RailsConf 2016\"\nkind: \"conference\"\nlocation: \"Kansas City, MO, United States\"\ndescription: \"\"\npublished_at: \"2016-05-04\"\nstart_date: \"2016-05-04\"\nend_date: \"2016-05-05\"\nyear: 2016\nbanner_background: \"#012B41\"\nfeatured_background: \"#012B41\"\nfeatured_color: \"white\"\ncoordinates:\n  latitude: 39.0997265\n  longitude: -94.5785667\n"
  },
  {
    "path": "data/railsconf/railsconf-2016/videos.yml",
    "content": "---\n# https://web.archive.org/web/20160527184114/http://railsconf.com/schedule\n\n## Day 1 - 2016-05-04\n\n- id: \"jeremy-daer-railsconf-2016\"\n  title: \"Opening Keynote\"\n  raw_title: \"RailsConf 2016 - Opening Keynote - Jeremy Daer\"\n  speakers:\n    - Jeremy Daer\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-11\"\n  published_at: \"2016-05-11\"\n  description: |-\n    Intro by David Heinemeier Hansson (DHH).  Jeremy is an app builder and software steward at Basecamp and a Rails core team member.\n  video_provider: \"youtube\"\n  video_id: \"nUVsZ4vS1Y8\"\n\n# ---\n\n# Morning Break\n\n# ---\n\n# Track: Hiring & Retaining\n- id: \"joe-mastey-railsconf-2016\"\n  title: \"Hiring Developers, with Science!\"\n  raw_title: \"RailsConf 2016 - Hiring Developers, with Science! by Joe Mastey\"\n  speakers:\n    - Joe Mastey\n  event_name: \"RailsConf 2016\"\n  track: \"Hiring & Retaining\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Hiring Developers, with Science! by Joe Mastey\n\n    Nothing makes or breaks our teams like the members they hire. And so we rate and quiz, assign homework and whiteboard algorithms until candidates are blue in the face. But does it work? In this session, we’ll unpack common interviews and how they stack up with research into predicting performance. We’ll learn to design interviews that work, what kinds don’t work at all, and how to tell the difference, with science!\n\n  video_provider: \"youtube\"\n  video_id: \"ZCGGMxcJMZk\"\n\n# Track: Junior Developer\n- id: \"coraline-ada-ehmke-railsconf-2016\"\n  title: \"Your First Legacy Codebase\"\n  raw_title: \"RailsConf 2016 - Your First Legacy Codebase by Coraline Ehmke\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"RailsConf 2016\"\n  track: \"Junior Developer\"\n  date: \"2016-05-29\"\n  published_at: \"2016-05-29\"\n  description: |-\n    Your First Legacy Codebase by Coraline Ehmke\n\n    So you've just graduated from a bootcamp and you're starting your first real job in software development. You've got several Rails apps under your belt and you're excited to get started. But few jobs offer the opportunity to build new apps; it's much more likely that you will be part of a team charged with maintaining and growing a legacy application. How can you get started working on an aging codebase when the sum of your experience so far was with greenfield apps?\n\n  video_provider: \"youtube\"\n  video_id: \"D6I__S3krbA\"\n\n- id: \"amy-unger-railsconf-2016\"\n  title: \"Stuck in the Middle: Leverage the power of Rack Middleware\"\n  raw_title: \"RailsConf 2016 -Stuck in the Middle: Leverage the power of Rack Middleware by Amy Unger\"\n  speakers:\n    - Amy Unger\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-23\"\n  published_at: \"2016-05-23\"\n  description: |-\n    Before a request ever hits your Rails application, it winds its way through a series of pieces of Rack middleware. Middleware sets session cookies, writes your logs, and enables the functionality in many gems such as Warden.\n\n    With Rails or any Rack app, you can easily insert your own custom middleware, allowing you to log, track, redirect, and alter the incoming request before it hits your application.\n\n    You will leave this talk confident in writing your own custom middleware, better able to troubleshoot gems that rely on middleware and with an understanding of how your Rails app functions.\n  video_provider: \"youtube\"\n  video_id: \"WeXpka50tHY\"\n\n# Track: Sponsored\n- id: \"terence-lee-railsconf-2016\"\n  title: \"I Can't Believe It's Not A Queue: Using Kafka with Rails\"\n  raw_title: \"RailsConf 2016 - I Can’t Believe It’s Not A Queue: Using Kafka with Rails by Terence Lee\"\n  speakers:\n    - Terence Lee\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-25\"\n  published_at: \"2016-05-25\"\n  description: |-\n    I Can’t Believe It’s Not A Queue: Using Kafka with Rails by Terence Lee\n\n    Your existing message system is great, until it gets overloaded. Then what? That's when you should try Kafka.\n\n    Kafka's designed to be resilient. It takes the stress out of moving from a Rails monolith into a scalable system of microservices. Since you can capture every event that happens in your app, it's great for logging. You can even use Kafka's distributed, ordered log to simulate production load in your staging environment.\n\n    Come and learn about Kafka, where it fits in your Rails app, and how to make it do the things that message queues simply can't.\n\n  video_provider: \"youtube\"\n  video_id: \"s3VQIGD5iGo\"\n\n# Track: Behind The Magic\n- id: \"mario-alberto-chavez-railsconf-2016\"\n  title: \"Rediscovering Active Record\"\n  raw_title: \"RailsConf 2016 - Rediscovering ActiveRecord By Mario Chavez\"\n  speakers:\n    - Mario Alberto Chavez\n  event_name: \"RailsConf 2016\"\n  track: \"Behind The Magic\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    Being a Rails developer is more than just understanding how to use the Framework to develop applications.\n\n    To become an efficient developer, you should learn how the Framework works; how deep this understanding should be is up to you. Exploring the Framework code is something that everyone should do at least once.\n\n    Not only may you learn how it works but also, you might learn new tricks from the code itself or discover small features that are not widely publicized.\n  video_provider: \"youtube\"\n  video_id: \"VMKsZn0-Es4\"\n\n# ---\n\n# Track: Hiring & Retaining\n- id: \"lillie-chilen-railsconf-2016\"\n  title: \"Internships: Good for the Intern, Great for the Team\"\n  raw_title: \"RailsConf 2016 - Internships: Good for the Intern, Great for the Team by Lillie Chilen\"\n  speakers:\n    - Lillie Chilen\n  event_name: \"RailsConf 2016\"\n  track: \"Hiring & Retaining\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Internships: Good for the Intern, Great for the Team by Lillie Chilen\n\n    You might think that hiring interns is charity work. Your company is bringing on less-than-baked engineers and spending precious engineering resources to train them and bring them up to speed on your technologies.\n\n    Surprise! Interns actually help your team, too. Running a successful internship program helps your team level up its teaching skills, discourages silos, and encourages writing maintainable code. I’ll talk about mistakes, successes, and specific processes to keep your team and interns productive, and you’ll leave this talk with plenty of fodder for hiring interns at your company.\n\n  video_provider: \"youtube\"\n  video_id: \"75LK0MOvyjQ\"\n\n# Track: Junior Developer\n- id: \"jeremy-fairbank-railsconf-2016\"\n  title: \"Pat Packet Visits Ruby Rails\"\n  raw_title: \"RailsConf 2016 - Pat Packet Visits Ruby Rails by Jeremy fairbank\"\n  speakers:\n    - Jeremy Fairbank\n  event_name: \"RailsConf 2016\"\n  track: \"Junior Developer\"\n  date: \"2016-05-29\"\n  published_at: \"2016-05-29\"\n  description: |-\n    Pat Packet Visits Ruby Rails by Jeremy fairbank\n\n    The eager Pat Packet just started his first job at KPS (Kernel Parcel Service). He knows an important package is coming through from Firechrome Industries destined for the Puma Kingdom for Ruby Rails herself! Pat’s boss acquiesces to Pat’s pleas to deliver the package. Come follow Pat’s journey as he delivers this very important package to Ruby Rails!\n\n    Whether we realize it or not, a lot of magic goes behind the scenes to deliver an HTTP request from a browser to a Rails server. In this talk, learn about TCP/IP, DNS, HTTP, routers, and much more as they help Pat Packet deliver his package.\n\n  video_provider: \"youtube\"\n  video_id: \"5N--xAEtGbo\"\n\n- id: \"caleb-hearth-railsconf-2016\"\n  title: \"Multi-Table Full Text Search with Postgres\"\n  raw_title: \"RailsConf 2016 -  Multi-table Full Text Search with Postgres By Caleb Thompson\"\n  speakers:\n    - Caleb Hearth\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    Searching content across multiple database tables and columns doesn't have to suck. Thanks to Postgres, rolling your own search isn't difficult. Following an actual feature evolution I worked on for a client, we will start with a search feature that queries a single column with LIKE and build up to a SQL-heavy solution for finding results across multiple columns and tables using database views. We will look at optimizing the query time and why this could be a better solution over introducing extra dependencies which clutter your code and need to be stubbed in tests.\n  video_provider: \"youtube\"\n  video_id: \"OzHhJPlgZaw\"\n\n# Track: Sponsored\n- id: \"kat-drobnjakovic-railsconf-2016\"\n  title: \"How We Deploy Shopify\"\n  raw_title: \"RailsConf 2016 - How We Deploy Shopify by Kat Drobnjakovic\"\n  speakers:\n    - Kat Drobnjakovic\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-31\"\n  published_at: \"2016-05-31\"\n  description: |-\n    How We Deploy Shopify by Kat Drobnjakovic\n\n    Shopify is one of the largest Rails apps in the world and yet remains to be massively scalable and reliable. The platform is able to manage large spikes in traffic that accompany events such as new product releases, holiday shopping seasons and flash sales, and has been benchmarked to process over 25,000 requests per second, all while powering more than 243,000 businesses. Even at such a large scale, all our developers still get to push to master and deploy Shopify in 3 minutes. Let's break down everything that can happen when deploying Shopify or any really big Rails app.\n  video_provider: \"youtube\"\n  video_id: \"HNH7El_BEsw\"\n\n# Track: Behind The Magic\n- id: \"jerry-dantonio-railsconf-2016\"\n  title: \"Inside Active Job\"\n  raw_title: \"RailsConf 2016 - Inside ActiveJob By Jerry D'Antonio\"\n  speakers:\n    - Jerry D'Antonio\n  event_name: \"RailsConf 2016\"\n  track: \"Behind The Magic\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    ActiveJob made a huge impact when it landed Rails 4.2. Most job processors support it and many developers use it. But few ever need to dig into the internals. How exactly does ActiveJob allow us to execute performant, thread-safe, asynchronous jobs in a language not known for concurrency? This talk will answer that question. We'll build our own asynchronous job processor from scratch and along the way we'll take a deep dive into queues, job serialization, scheduled tasks, and Ruby's memory model.\n  video_provider: \"youtube\"\n  video_id: \"E-1ICY8DMh4\"\n\n# Lunch\n\n# Track: Hiring & Retaining\n- id: \"eric-weinstein-railsconf-2016\"\n  title: \"Booting Up: Hiring and Growing Boot Camp Graduates\"\n  raw_title: \"RailsConf 2016 - Booting Up: Hiring and Growing Boot Camp Graduates by Eric Weinstein\"\n  speakers:\n    - Eric Weinstein\n  event_name: \"RailsConf 2016\"\n  track: \"Hiring & Retaining\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Booting Up: Hiring and Growing Boot Camp Graduates by Eric Weinstein\n\n    In 2015, nearly a hundred programming boot camps produced thousands of graduates in North America alone. While boot camps help address a need for professional software developers, their graduates have different skill sets and require different interview assessment and career management than fresh college graduates with degrees in computer science. In this talk, we'll look at how boot camps prepare their students, how to interview graduates, and how to help them continually learn during their careers, developing a holistic model for hiring and growing boot camp graduates in the process.\n\n  video_provider: \"youtube\"\n  video_id: \"RlnA9IXmDQ0\"\n\n# Track: Junior Developer\n- id: \"ryan-dlugosz-railsconf-2016\"\n  title: \"Level-up Your Active Record Skills: Learn SQL!\"\n  raw_title: \"RailsConf 2016 - Level-up Your ActiveRecord Skills: Learn SQL! by Ryan Dlugosz\"\n  speakers:\n    - Ryan Dlugosz\n  event_name: \"RailsConf 2016\"\n  track: \"Junior Developer\"\n  date: \"2016-05-25\"\n  published_at: \"2016-05-25\"\n  description: |-\n    Level-up Your ActiveRecord Skills: Learn SQL! by Ryan Dlugosz\n\n    ActiveRecord is a great tool, but knowing SQL can help you to build better, faster applications and quickly find answers to common business questions. In this talk you'll see an overview of basic-to-intermediate SQL techniques that you can use to: learn about unfamiliar data sets, identify and resolve slow query problems, quickly build ad-hoc reports, combine multiple tables and perform calculations.\n\n    Specifically targeted to the Junior Rails Developer, we will explore with non-trivial yet approachable examples and see how learning SQL can help you become a better software developer.\n\n  video_provider: \"youtube\"\n  video_id: \"4xjSXp-oBvc\"\n\n- id: \"konstantin-tennhard-railsconf-2016\"\n  title: \"Foreign API Simulation with Sinatra\"\n  raw_title: \"RailsConf 2016 - Foreign API Simulation with Sinatra by Konstantin Tennhard\"\n  speakers:\n    - Konstantin Tennhard\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-29\"\n  published_at: \"2016-05-29\"\n  description: |-\n    Foreign API Simulation with Sinatra by Konstantin Tennhard\n\n    Nowadays, we often rely on third party services that we integrate into our product, instead of building every aspect of an application. In many cases, well written API clients exist, but on occasion you run into the issue that there isn't a ready to use client or it simply doesn't fit your needs. How do you write a good API client and more importantly how do you test it without hitting the remote API. So far, the standard approach has been replaying requests with VCR or stubbing them with Webmock. There is a third option: simulating foreign APIs with Sinatra from within your test suite!\n\n  video_provider: \"youtube\"\n  video_id: \"LAR7foT9kUE\"\n\n# Track: Sponsored\n- id: \"nathan-beyer-railsconf-2016\"\n  title: \"Pragmatic Lessons of Rails & Ruby in the Enterprise\"\n  raw_title: \"RailsConf 2016 -  Pragmatic Lessons of Rails & Ruby in the Enterprise by Nathan Beyer\"\n  speakers:\n    - Nathan Beyer\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-28\"\n  published_at: \"2016-05-28\"\n  description: |-\n    Pragmatic Lessons of Rails & Ruby in the Enterprise by Nathan Beyer\n\n    Adopting Rails and Ruby for use within a large development organization was and continues to be an adventure. Rails and Ruby have been in use at Cerner for 7 years and over that time, their use has gone from niche technology used by a handful of people to a core platform used by hundreds. Along this adventure, we have learned many lessons and gained lots of experience. In this talk, we’ll share the interesting up and downs of this adventure in an effort to share our experiences and knowledge.\n\n  video_provider: \"youtube\"\n  video_id: \"6BI5RFi_A0M\"\n\n# Track: Behind The Magic\n- id: \"xavier-noria-railsconf-2016\"\n  title: \"The Rails Boot Process\"\n  raw_title: \"RailsConf 2016 - The Rails Boot Process by Xavier Noria\"\n  speakers:\n    - Xavier Noria\n  event_name: \"RailsConf 2016\"\n  track: \"Behind The Magic\"\n  date: \"2016-05-12\"\n  published_at: \"2016-05-12\"\n  description: |-\n    Rails ships as a number of components, Active Record, Active Support, ..., largely independent of each other, but somehow something orchestrates them and presents a unified view of the system. Then we have config/boot.rb, config/application.rb... what do they do? Application initializers, environment configuration, what runs when? Understanding how that works becomes an inflection point in any Rails programmer that goes through it. You go from that cloudy idea of an initialization that sets things up for a certain definition of \"things\", to a well-understood process.\n  video_provider: \"youtube\"\n  video_id: \"vSza2FZucV8\"\n\n# ---\n\n# Track: Hiring & Retaining\n- id: \"jamie-riedesel-railsconf-2016\"\n  title: \"Reduce Small-Team Culture Shock with Agile\"\n  raw_title: \"RailsConf 2016 -  Reduce Small-Team Culture Shock with Agile by Jamie Riedesel\"\n  speakers:\n    - Jamie Riedesel\n  event_name: \"RailsConf 2016\"\n  track: \"Hiring & Retaining\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Reduce Small-Team Culture Shock with Agile by Jamie Riedesel\n\n    Ever hire someone from a traditional IT organization who seemed like a great person, only to have them end up a sucking pit of negativity that had to be fired? Traditional IT can be an incredibly hostile environment, leading to survival strategies that aren’t always compatible with small agile-based teams. In this session, I will show how these survival strategies came to be, and ways to deprogram them to reduce your recruiting churn. Better yet, the tools to do so are already in agile.\n\n  video_provider: \"youtube\"\n  video_id: \"qHTKw6Djhbw\"\n\n# Track: Junior Developer\n- id: \"cecy-correa-railsconf-2016\"\n  title: \"From Zero to API Hero: Consuming APIs Like a Pro\"\n  raw_title: \"RailsConf 2016 - From Zero to API Hero: Consuming APIs like a Pro by Cecy Correa\"\n  speakers:\n    - Cecy Correa\n  event_name: \"RailsConf 2016\"\n  track: \"Junior Developer\"\n  date: \"2016-05-25\"\n  published_at: \"2016-05-25\"\n  description: |-\n    Just like there’s an app for that, there’s an API for that! But not all APIs are created equal, and some APIs are harder to work with than others. In this talk, I will walk through some common gotchas developers encounter when consuming a 3rd party API. I will explain why it’s important to familiarize yourself with the API you’re consuming prior to coding, as well as share tools to help you get acquainted with an API much faster. Lastly, I will go over debugging and testing the API you’re consuming, because testing is not just for the provider of the API!\n\n  video_provider: \"youtube\"\n  video_id: \"Af5HDgvGuXk\"\n\n- id: \"akira-matsuda-railsconf-2016\"\n  title: \"3x Rails: Tuning the Framework Internals\"\n  raw_title: \"RailsConf 2016 - 3x Rails: Tuning the Framework Internals by Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-29\"\n  published_at: \"2016-05-29\"\n  description: |-\n    3x Rails: Tuning the Framework Internals by Akira Matsuda\n\n    Topics to be covered:\n\n    Speeding up DB queries and model initialization\n    View rendering and template lookup\n    Routes and URLs\n    Object allocations and GC pressure\n    Faster Rails boot and testing\n    Asset Pipeline tweaks\n\n  video_provider: \"youtube\"\n  video_id: \"hVXsxhHV1yY\"\n\n# Track: Sponsored\n- id: \"aja-hammerly-railsconf-2016\"\n  title: \"Postcards from GorbyPuff\"\n  raw_title: \"RailsConf 2016 - Postcards from GorbyPuff by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-28\"\n  published_at: \"2016-05-28\"\n  slides_url: \"https://thagomizer.com/files/RailsConf2016.pdf\"\n  description: |-\n    Postcards from GorbyPuff by Aja Hammerly\n\n    GorbyPuff is setting off on a grand world tour and leaving us clues so we can follow him. Using Google Cloud tools such as Cloud Vision, BigQuery, Google Translate we'll track down Gorby at all his stops. While we're at it we'll learn some tools you can use to add awesome functionality to your web applications.\n\n  video_provider: \"youtube\"\n  video_id: \"_lQIwkjXE0Y\"\n\n# Track: Behind The Magic\n- id: \"nate-berkopec-railsconf-2016\"\n  title: \"Making a Rails App with 140 Characters (or less)\"\n  raw_title: \"RailsConf 2016 - Making a Rails App with 140 Characters (or less) by Nate Berkopec\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"RailsConf 2016\"\n  track: \"Behind The Magic\"\n  date: \"2016-05-13\"\n  published_at: \"2016-05-13\"\n  description: |-\n    Ever felt jealous of \"other\" Ruby web frameworks whose applications can be run from a single file? Did you know Rails can do this too? Starting from a fresh \"rails new\" install, we'll gradually delete and pare away to find the beautiful, light, modular and object-oriented web framework underneath. Eventually we'll end up with a tweet-size Rails application! We'll learn about Rails' initialization process and default \"stack\", and investigate the bare-bones required to get a Rails app up and running.\n  video_provider: \"youtube\"\n  video_id: \"SXV-RRsjsFc\"\n\n# ---\n\n# Afternoon Break\n\n# ---\n\n- id: \"brad-urani-railsconf-2016\"\n  title: \"Active Record vs. Ecto: A Tale of Two ORMs\"\n  raw_title: \"RailsConf 2016 - ActiveRecord vs. Ecto: A Tale of Two ORMs by Brad Urani\"\n  speakers:\n    - Brad Urani\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    ActiveRecord vs. Ecto: A Tale of Two ORMs by Brad Urani\n\n    They bridge your application and your database. They're object-relational mappers, and no two are alike. Join us as we compare ActiveRecord from Rails with Ecto from Phoenix, a web framework for Elixir. Comparing the same app implemented in both, we'll see why even with two different web frameworks in two different programming languages, it's the differing ORM designs that most affect the result. This tale of compromises and tradeoffs, where no abstraction is perfect, will teach you how to pick the right ORM for your next project, and how to make the best of the one you already use.\n\n  video_provider: \"youtube\"\n  video_id: \"_wD25uHx_Sw\"\n\n# Track: Junior Developer\n- id: \"michael-kelly-railsconf-2016\"\n  title: \"Zen and the Art of the Controller\"\n  raw_title: \"RailsConf 2016 - Zen and the Art of the Controller by Michael Kelly\"\n  speakers:\n    - Michael Kelly\n  event_name: \"RailsConf 2016\"\n  track: \"Junior Developer\"\n  date: \"2016-05-25\"\n  published_at: \"2016-05-25\"\n  description: |-\n    Zen and the Art of the Controller by Michael Kelly\n\n    So you’re fresh out of boot camp or just off a month long binge on RoR tutorials/examples and you’re feeling pretty good about MVC and how controllers fit into the whole framework. But projects in the wild are often far more complicated than you’ve been exposed to. In this talk, we’re going to discuss several techniques used by seasoned engineers to build and refactor controllers for features you’ll actually be working on.\n\n  video_provider: \"youtube\"\n  video_id: \"KVkQ9UEQk0Y\"\n\n- id: \"michael-rau-railsconf-2016\"\n  title: \"Storytelling with Code\"\n  raw_title: \"RailsConf 2016 - Storytelling with Code by Michael Rau\"\n  speakers:\n    - Michael Rau\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-29\"\n  published_at: \"2016-05-29\"\n  description: |-\n    Storytelling with Code by Michael Rau\n\n    How can you tell a story using only email, a laser printer, voicemail? Last year I created an immersive experience for one audience member in a standard office cubicle. The piece used a rails app and some other custom software and no live actors to tell a story about office culture. This talk focuses on the techniques of digital storytelling, my process of developing the story as I wrote the code, and the strategies I used to create an emotional connection with a user. If you are interested in the intersection between stories, software, game design and narrative design, this talk is for you!\n\n  video_provider: \"youtube\"\n  video_id: \"B3Bu22XaKGg\"\n\n- id: \"joseph-dean-railsconf-2016\"\n  title: \"Riding The Latest Rails for Charity\"\n  raw_title: \"RailsConf 2016 - Riding the Latest Rails for Charity by Joseph Dean\"\n  speakers:\n    - Joseph Dean\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    As developers we often forget that with our development skills we have the power to change the world. This talk describes how our company organized a hackathon to create three open source projects that helped charitable organizations become more efficient at helping people. Bringing our team together around a shared philanthropic goal created more team unity, improved team communication and most importantly allowed us to apply our development skills to do good in the world.\n\n  video_provider: \"youtube\"\n  video_id: \"CgQ_NEzNJss\"\n\n# Track: Behind The Magic\n- id: \"rafael-mendona-frana-railsconf-2016\"\n  title: \"How Sprockets Works\"\n  raw_title: \"RailsConf 2016 - How Sprockets works by Rafael França\"\n  speakers:\n    - Rafael Mendonça França\n  event_name: \"RailsConf 2016\"\n  track: \"Behind The Magic\"\n  date: \"2016-05-13\"\n  published_at: \"2016-05-13\"\n  description: |-\n    Almost all applications have assets like CSS, JavaScript and others. That means the asset pipeline is an integral part of the Ruby on Rails framework. In this talk we'll show you how the asset pipeline works, and how you can take full advantage of the asset pipeline's features. Ever wondered how to convert an SVG to PNG automatically? Wanted to know what exactly happens to your CoffeeScript files? We'll explore that, and more.\n  video_provider: \"youtube\"\n  video_id: \"CzFFYelG7WY\"\n\n# ---\n\n- id: \"emil-stolarsky-railsconf-2016\"\n  title: \"Testing Rails at Scale\"\n  raw_title: \"RailsConf 2016 - Testing Rails at Scale by Emil Stolarsky\"\n  speakers:\n    - Emil Stolarsky\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Testing Rails at Scale by Emil Stolarsky\n\n    It's impossible to iterate quickly on a product without a reliable, responsive CI system. At a certain point, traditional CI providers don't cut it. Last summer, Shopify outgrew its CI solution and was plagued by 20 minute build times, flakiness, and waning trust from developers in CI statuses.\n\n    Now our new CI builds Shopify in under 5 minutes, 700 times a day, spinning up 30,000 docker containers in the process. This talk will cover the architectural decisions we made and the hard lessons we learned so you can design a similar build system to solve your own needs.\n\n  video_provider: \"youtube\"\n  video_id: \"zWR477ypEsc\"\n\n# Track: Junior Developer\n- id: \"jon-mccartie-railsconf-2016\"\n  title: \"Facepalm to Foolproof: Avoiding Common Production Pitfalls\"\n  raw_title: \"RailsConf 2016 - Facepalm to Foolproof: Avoiding Common Production Pitfalls by Jon McCartie\"\n  speakers:\n    - Jon McCartie\n  event_name: \"RailsConf 2016\"\n  track: \"Junior Developer\"\n  date: \"2016-05-25\"\n  published_at: \"2016-05-25\"\n  description: |-\n    Facepalm to Foolproof: Avoiding Common Production Pitfalls by Jon McCartie\n    \"WTF asset pipeline?\"\n    \"What are all these errors?\"\n    \"Why is\n    my app running so slow?\"\n    If you're new to Rails development, or just want some tips on deploying and running in production, this is the talk for you. Relying\n    on real-world experience as part of the Heroku support team, we'll talk through\n    common issues (and a few funny ones) we see when people take their \"but it works in development!\" app to a production environment.\n  video_provider: \"youtube\"\n  video_id: \"yDJV9mr--Yo\"\n\n- id: \"helio-cola-railsconf-2016\"\n  title: \"Tweaking Ruby GC Parameters for Fun, Speed, and Profit\"\n  raw_title: \"RailsConf 2016 - Tweaking Ruby GC Parameters for Fun, Speed, and Profit by Helio Cola\"\n  speakers:\n    - Helio Cola\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-29\"\n  published_at: \"2016-05-29\"\n  description: |-\n    Tweaking Ruby GC Parameters for Fun, Speed, and Profit by Helio Cola\n\n    Whether you are building a Robot, controlling a Radar, or creating a Web App, the Ruby Garbage Collector (GC) can help you. The stats exposed by the Garbage Collector since Ruby v2.1 caught my attention and pushed me to dig deeper. Both Ruby 2.1 and 2.2 brought great performance improvements. From a practical point of view, we will discuss how to use the GC to enhance the performance of your software, from configuration parameters to different approaches on how you can change them yourself.\n\n  video_provider: \"youtube\"\n  video_id: \"0nUV9MXlcwo\"\n\n# Track: Sponsored\n- id: \"andreas-fast-railsconf-2016\"\n  title: \"Excellence Through Diversity\"\n  raw_title: \"RailsConf 2016 - Excellence Through Diversity by Andreas Fast\"\n  speakers:\n    - Andreas Fast\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Excellence Through Diversity by Andreas Fast\n\n    Great individuals often outperform their peers, and when going through school and applying for jobs this seems to be the most important aspect. But who is really outperforming whom? Also, what are we using to measure people? How do you know you’re being fair? Hiring is such a subjective topic and of utmost importance when building a team.\n\n    Let’s explore how our strengths and weaknesses affect ourselves and the team and, how we need to look past ourselves when building a team.\n\n  video_provider: \"youtube\"\n  video_id: \"_mwcreHuqNA\"\n\n# Track: Behind The Magic\n- id: \"ryan-davis-railsconf-2016\"\n  title: \"Writing a Test Framework from Scratch\"\n  raw_title: \"RailsConf 2016   Writing a Test Framework from Scratch by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"RailsConf 2016\"\n  track: \"Behind The Magic\"\n  date: \"2016-05-13\"\n  published_at: \"2016-05-13\"\n  description: |-\n    Assertions (or expectations) are the most important part of any test framework. How are they written? What happens when one fails? How does a test communicate its results? Past talks have shown how test frameworks work from the very top: how they find, load, select, and run tests. Instead of reading code from the top, we’ll write code from scratch starting with assertions and building up a full test framework. By the end, you'll know how every square inch of your testing framework works.\n  video_provider: \"youtube\"\n  video_id: \"VPr5pmlAq20\"\n\n# ---\n\n- id: \"nickolas-means-railsconf-2016\"\n  title: \"Closing Keynote: Skunk Works\"\n  raw_title: \"RailsConf 2016 - Day 1 Closing Keynote: Skunk Works by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-12\"\n  published_at: \"2016-05-12\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ggPE-JHzfAM\"\n\n## Day 2 - 2016-05-05\n\n- id: \"chanelle-henry-railsconf-2016\"\n  title: \"Opening Keynote: UX, Rails & Awesomeness\"\n  raw_title: \"RailsConf 2016 - Day 2 Opening Keynote by Chanelle Henry\"\n  speakers:\n    - Chanelle Henry\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-13\"\n  published_at: \"2016-05-13\"\n  description: |-\n    With a background in Psychology, Computer Science and Cybersecurity, Art Direction & Design, Chanelle Henry has an intense passion for problem-solving and creating methodologies; helping outline, encourage, and propel the UX Process. Currently serving as a Director of User Experience at Bluewolf, she uses creative and innovative solutions to execute ideas to consult with everyone from startups to Fortune 50 companies to help refine their goals, make progress, spread the gospel of UX.\n  video_provider: \"youtube\"\n  video_id: \"f3RcrToGIEQ\"\n\n# ---\n\n# Morning Break\n\n# ---\n\n# Track: Building Rails Teams\n- id: \"jessica-roper-railsconf-2016\"\n  title: \"Building Applications Better the First Time\"\n  raw_title: \"RailsConf 2016 -  Building Applications Better the First Time by Jessica Roper\"\n  speakers:\n    - Jessica Roper\n  event_name: \"RailsConf 2016\"\n  track: \"Building Rails Teams\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    Building Applications Better the First Time by Jessica Roper\n\n    Feature creep is a common problem in many projects. When you have to take into account customer requests and the ideas of designers and developers, how do you finish all of the features on time? Setting expectations and keeping customers happy can be impossible without the right focus, good communications and proper design. This talk will cover tools and tricks that you can use to prioritize what to complete first and help you iterate through the design process more quickly.\n\n  video_provider: \"youtube\"\n  video_id: \"MA3f7aWCTL4\"\n\n# Track: New In Rails 5\n- id: \"jesse-wolgamott-railsconf-2016\"\n  title: \"Action Cable for Not-Another-Chat-App-Please\"\n  raw_title: \"RailsConf 2016 - ActionCable for Not-Another-Chat-App-Please by Jesse Wolgamott\"\n  speakers:\n    - Jesse Wolgamott\n  event_name: \"RailsConf 2016\"\n  track: \"New In Rails 5\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    ActionCable for Not-Another-Chat-App-Please by Jesse Wolgamott\n\n    RealTime updates using WebSockets are so-hot-right-now, and Rails 5 introduces ActionCable to let the server talk to the browser. Usually, this is shown as a Chat application -- but very few services actually use chats.\n\n    Instead, Rails Apps want to be able to update pages with new inventory information, additional products, progress bars, and the rare notification. How can we make this happen in the real world? How can we handle this for unauthenticated users? How can we deploy this?\n\n  video_provider: \"youtube\"\n  video_id: \"IeYGfM32Iqs\"\n\n- id: \"koichi-sasada-railsconf-2016\"\n  title: \"Precompiling Ruby Scripts - Myth and Fact\"\n  raw_title: \"RailsConf 2016 - Precompiling Ruby scripts - Myth and Fact By Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    Ruby 2.3 introduced the precompilation feature which compiles Ruby scripts to a binary data format. You can store them to storage (file systems and so on) and then load from them.\n\n    Many people believe a myth: precompilation is a silver bullet to reduce long boot times. However, our initial evaluations do not show impressive reduction of boot times. We faced the fact that we need more effort to achieve short boot times.\n\n    This talk will introduce this new feature and detailed analysis of Rails application loading time. Also, I will show you our new tricks to reduce loading time.\n  video_provider: \"youtube\"\n  video_id: \"aBhygk4c1PY\"\n\n# Track: Sponsored\n- id: \"tatiana-vasilyeva-railsconf-2016\"\n  title: \"Power up Your Development with RubyMine\"\n  raw_title: \"RailsConf 2016 - Power up Your Development with RubyMine by Tatiana Vasilyeva\"\n  speakers:\n    - Tatiana Vasilyeva\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-17\"\n  published_at: \"2016-05-17\"\n  description: |-\n    There are many development tricks and habits that lie at the root of productive coding. IDEs, like RubyMine, are a big one. Adopting a new tool does require an initial investment of time though, as you customize your environment and learn the shortcuts.\n  video_provider: \"youtube\"\n  video_id: \"issom99iWDs\"\n\n# Track: Your Tech Career\n- id: \"molly-black-railsconf-2016\"\n  title: \"How to Get and Love Your First Rails Job\"\n  raw_title: \"RailsConf 2016 -  How to Get and Love Your First Rails Job By Molly Black\"\n  speakers:\n    - Molly Black\n  event_name: \"RailsConf 2016\"\n  track: \"Your Tech Career\"\n  date: \"2016-05-25\"\n  published_at: \"2016-05-25\"\n  description: |-\n    RailsConf 2016 -  How to Get and Love Your First Rails Job By Molly BlackHalfway through a dev bootcamp? Straight out of college with a CS degree? Hacking away at Hartl after your day job? Now what?\n\n    With articles about how employable you are and how much money you can make printed daily, it can be hard to stay focused on the most important tangibles – the job search, interview readiness, and your early career goals.\n\n    In this talk, we’ll cover how to prepare yourself and your projects for the interview process, and how to adequately vet the companies interested in you, allowing you to not only secure a rails job, but one that you love.\n\n  video_provider: \"youtube\"\n  video_id: \"-4KKqYuYHno\"\n\n# ---\n\n# Track: Building Rails Teams\n- id: \"nadia-odunayo-railsconf-2016\"\n  title: \"The Guest: A Guide To Code Hospitality\"\n  raw_title: \"RailsConf 2016 - The Guest: A Guide To Code Hospitality by Nadia Odunayo\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"RailsConf 2016\"\n  track: \"Building Rails Teams\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    The Guest: A Guide To Code Hospitality by Nadia Odunayo\n\n    You were living alone in the town of Ruby-on-Rails until you decided to open up your spare room to guests. Now your first visitor has booked in. Her arrival is imminent.\n\n    How do you prepare? How can you make sure she has a great visit?\n\n    Let’s explore the art of code hospitality — working on codebases in a way that respects your teammates and provides for their needs. By working hospitably, we can facilitate team productivity and help new members quickly feel at home.\n\n  video_provider: \"youtube\"\n  video_id: \"hHzWG1FltaE\"\n\n# Track: New In Rails 5\n- id: \"sean-griffin-railsconf-2016\"\n  title: \"Rails 5 Features You Haven't Heard About\"\n  raw_title: \"RailsConf 2016 - Rails 5 Features You Haven't Heard About by Sean Griffin\"\n  speakers:\n    - Sean Griffin\n  event_name: \"RailsConf 2016\"\n  track: \"New In Rails 5\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Rails 5 Features You Haven't Heard About by Sean Griffin\n\n    We've all heard about Action Cable, Turbolinks 5, and Rails::API. But Rails 5 was almost a thousand commits! They included dozens of minor features, many of which will be huge quality of life improvements even if you aren't using WebSockets or Turbolinks.\n\n    This will be a deep look at several of the \"minor\" features of Rails 5. You won't just learn about the features, but you'll learn about why they were added, the reasoning behind them, and the difficulties of adding them from someone directly involved in many of them.\n\n  video_provider: \"youtube\"\n  video_id: \"b010Nh-A0vY\"\n\n- id: \"miki-rezentes-railsconf-2016\"\n  title: \"Quit Frustrating Your New Developers - Tips From a Teacher\"\n  raw_title: \"RailsConf 2016 - Quit Frustrating Your New Developers - Tips From a Teacher By Miki Rezentes\"\n  speakers:\n    - Miki Rezentes\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    Your team gains a new developer. You are responsible for bringing them up to speed. While not everyone is a natural teacher, everyone can be taught basic teaching fundamentals. We will take a look at principles anyone can use to become a more effective trainer/teacher. Better teaching technique makes the training process more effective and enjoyable. Effective training reduces new developer frustration and increases job satisfaction for everyone.\n  video_provider: \"youtube\"\n  video_id: \"L0cYUD0-XNs\"\n\n# Track: Sponsored\n- id: \"nick-reavill-railsconf-2016\"\n  title: \"From Excel to Rails: A Path to Enlightened Internal Software\"\n  raw_title: \"RailsConf 2016 - From Excel to Rails: A Path to Enlightened Internal Software by Nick Reavill\"\n  speakers:\n    - Nick Reavill\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-25\"\n  published_at: \"2016-05-25\"\n  description: |-\n    From Excel to Rails: A Path to Enlightened Internal Software by Nick Reavill\n\n    Rails is the ideal framework for creating software to run successful new businesses.\n\n  video_provider: \"youtube\"\n  video_id: \"8vV8SvQARuU\"\n\n# Track: Your Tech Career\n- id: \"james-edward-gray-ii-railsconf-2016\"\n  title: \"Implementing the LHC on a Whiteboard\"\n  raw_title: \"RailsConf 2016 - Implementing the LHC on a Whiteboard by James Edward Gray II\"\n  speakers:\n    - James Edward Gray II\n  event_name: \"RailsConf 2016\"\n  track: \"Your Tech Career\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-13\"\n  description: |-\n    If you apply for a programming job, you may be asked to complete a take home code challenge, \"pair program\" with another developer, and/or sketch out some code on a whiteboard. A lot has been said of the validity and fairness of these tactics, but, company ethics aside, what if you just need a job? In this talk, I'll show you a series of mistakes I have seen in these interview challenges and give you strategies for avoiding them. I'll give recommendations for how you can impress the programmers grading your work and I'll tell you which rules you should bend in your solutions.\n  video_provider: \"youtube\"\n  video_id: \"g5lWfHEeibs\"\n\n# ---\n\n# Lunch\n\n# ---\n\n# Track: Building Rails Teams\n- id: \"rebecca-miller-webster-railsconf-2016\"\n  title: \"Frameworks for Feedback\"\n  raw_title: \"RailsConf 2016 - Frameworks for Feedback by Rebecca Miller-Webster\"\n  speakers:\n    - Rebecca Miller-Webster\n  event_name: \"RailsConf 2016\"\n  track: \"Building Rails Teams\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    Frameworks for Feedback by Rebecca Miller-Webster\n\n    Code reviews, stand ups, retros, and performance reviews acknowledge the importance of communication and feedback, but they don’t help you give negative feedback or ensure that you hear the small things before they become big things.\n\n    Let’s talk about feedback and examine frameworks for how to ask for and frame feedback effectively. Not all situations call for the same type of feedback and some are more sensitive than others. We will look at Non-Violent Communication, techniques from family and marriage therapy, as well as more traditional frameworks for feedback.\n\n  video_provider: \"youtube\"\n  video_id: \"q8K_66PA2qw\"\n\n# Track: New In Rails 5\n- id: \"sam-stephenson-railsconf-2016\"\n  title: \"Turbolinks 5: I Can't Believe It's Not Native!\"\n  raw_title: \"RailsConf 2016 -  Turbolinks 5: I Can’t Believe It’s Not Native! by Sam Stephenson\"\n  speakers:\n    - Sam Stephenson\n  event_name: \"RailsConf 2016\"\n  track: \"New In Rails 5\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Turbolinks 5: I Can’t Believe It’s Not Native! by Sam Stephenson\n\n    Learn how Turbolinks 5 enables small teams to deliver lightning-fast Rails applications in the browser, plus high-fidelity hybrid apps for iOS and Android, all using a shared set of web views.\n\n    SAM STEPHENSON\n\n  video_provider: \"youtube\"\n  video_id: \"SWEts0rlezA\"\n\n- id: \"brandon-hays-railsconf-2016\"\n  title: \"Surviving the Framework Hype Cycle\"\n  raw_title: \"RailsConf 2016 - Surviving the Framework Hype Cycle by Brandon Hays\"\n  speakers:\n    - Brandon Hays\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    Baskin-Robbins wishes it had as many flavors as there are JS frameworks, build tools, and cool new \"low-level\" languages. You just want to solve a problem, not have a 500-framework bake-off! And how will you know whether you picked the right one? Don't flip that table, because we'll use the \"hype cycle\" and the history of Ruby and Rails as a guide to help you understand which front-end and back-end technologies are a fit for your needs now and in the future.\n  video_provider: \"youtube\"\n  video_id: \"O6TtfK9gGvA\"\n\n# Track: Sponsored\n- id: \"allan-espinosa-railsconf-2016\"\n  title: \"Packaging and Shipping Rails Applications in Docker\"\n  raw_title: \"RailsConf 2016 - Packaging and Shipping Rails Applications in Docker By Allan Espinosa\"\n  speakers:\n    - Allan Espinosa\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Packaging and Shipping Rails Applications in Docker By Allan Espinosa\n\n    You’re very happy as a Rails developer for drinking the Docker Kool-aid. You just need to toss a Docker image to your Ops team and you're done! However, like all software projects, your Docker containers start to decay. Deployment takes days to occur as you download your gigantic Docker image to production. Everything’s on fire and you can’t launch the rails console inside your Docker container. Isn’t Docker supposed to take all these things away?\n\n    In this talk, I will discuss some Docker optimizations and performance tuning techniques to keep your Rails packaging and shipping pipeline in shape.\n\n  video_provider: \"youtube\"\n  video_id: \"lpHgNC5bCbo\"\n\n- id: \"thijs-cadier-railsconf-2016\"\n  title: \"Introduction to Concurrency in Ruby\"\n  raw_title: \"RailsConf 2016 - Introduction to Concurrency in Ruby by Thijs Cadier\"\n  speakers:\n    - Thijs Cadier\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-14\"\n  published_at: \"2016-05-14\"\n  description: |-\n    In this talk we'll learn about the options we have to let a computer running Ruby do multiple things simultaneously. We'll answer questions such as: What's the difference between how Puma and Unicorn handle serving multiple Rails HTTP requests at the same time? Why does ActionCable use Eventmachine? How do these underlying mechanism actually work if you strip away the complexity?\n  video_provider: \"youtube\"\n  video_id: \"5AxtY4dfuwc\"\n\n# ---\n\n# Track: Building Rails Teams\n- id: \"jon-arnold-railsconf-2016\"\n  title: \"Managing Growing Pains: Thinking Big While Being Small\"\n  raw_title: \"RailsConf 2016 - Managing Growing Pains: Thinking Big While Being Small by Jon Arnold\"\n  speakers:\n    - Jon Arnold\n  event_name: \"RailsConf 2016\"\n  track: \"Building Rails Teams\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    Managing Growing Pains: Thinking Big While Being Small by Jon Arnold\n\n    This talk is for anyone who's had to promise new features to a client when they weren't actually sure how they'd deliver on the promise.\n\n    We all have big visions and big ideas, but our teams and abilities are finite resources. We'll talk about how to manage expectations, growth, technical debt and delivery (and still be able to sleep at night despite that last wonky commit). We'll talk about the never-ending product roadmap, product reality and how what we create falls somewhere in between.\n\n  video_provider: \"youtube\"\n  video_id: \"7H-Cy-80ynM\"\n\n# Track: New In Rails 5\n- id: \"prathamesh-sonpatki-railsconf-2016\"\n  title: \"Secrets of Testing Rails 5 Apps\"\n  raw_title: \"RailsConf 2016 - Secrets of Testing Rails 5 apps by Prathamesh Sonpatki\"\n  speakers:\n    - Prathamesh Sonpatki\n  event_name: \"RailsConf 2016\"\n  track: \"New In Rails 5\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Secrets of Testing Rails 5 apps by Prathamesh Sonpatki\n\n    Testing Rails 5 apps has become a better experience out of the box. Rails has also become smarter by introducing the test runner. Now we can't complain about not being able to run a single test or not getting coloured output. A lot of effort has gone into making tests -- especially integration tests -- run faster.\n\n    Come and join me as we commence the journey to uncover the secrets of testing Rails 5 apps.\n\n  video_provider: \"youtube\"\n  video_id: \"_qG7A9LxBPw\"\n\n- id: \"richard-schneeman-railsconf-2016\"\n  title: \"Saving Sprockets\"\n  raw_title: \"RailsConf 2016 -  Saving Sprockets by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    What do you do when a maintainer leaves a project with over 44 million downloads? That is what we had to consider this year when Sprockets lost the developer responsible for more than 70% of the commits. In this talk we will look at recent efforts to revive Sprockets, and make it more maintainable. We will look into how your projects can be structured to avoid burnout and survive a change of maintainers. Let's save Sprockets.\n  video_provider: \"youtube\"\n  video_id: \"imE397wVWgY\"\n\n# Track: Sponsored\n- id: \"yehuda-katz-railsconf-2016\"\n  title: \"Small Details, Big Impact\"\n  raw_title: \"RailsConf 2016 -  Small Details, Big Impact By Yehuda Katz and Liz Baillie\"\n  speakers:\n    - Yehuda Katz\n    - Liz Baillie\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Small Details, Big Impact By Yehuda Katz and Liz Baillie\n\n    Most people are on the lookout for the Next Big Thing™, but at Skylight we know it’s #allthelittlethings that make for the best possible user experience. From the many not-so-happy paths of authentication to the challenge of guessing a user’s preferred name, we’ll dig deep into all those tiny details that will surprise and delight your customers. If you were hoping to hear more about how we use Rust, don't worry—we've got you covered! We’ll be sharing many of our finer implementation details as well as the thought processes behind them.\n\n  video_provider: \"youtube\"\n  video_id: \"533rIdxPF10\"\n\n- id: \"tony-wieczorek-railsconf-2016\"\n  title: \"5 Practical Ways to Advocate for Diversity\"\n  raw_title: \"RailsConf 2016 - 5 Practical Ways to Advocate for Diversity by Tony Wieczorek\"\n  speakers:\n    - Tony Wieczorek\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-17\"\n  published_at: \"2016-05-17\"\n  description: |-\n    This is a talk for anyone who wants a more diverse engineering culture at work. If you've ever been frustrated by the sameness of your engineering peers, you'll hear practical advice you can use immediately. Creating a diverse team is more than a moral issue - it makes business sense. Diverse engineering teams recruit the best talent, are more innovative, better reflect the needs of their users and make for incredibly fun places to work.\n  video_provider: \"youtube\"\n  video_id: \"zi335PDgL7A\"\n\n# ---\n\n- id: \"david-copeland-railsconf-2016\"\n  title: \"Can Time-Travel Keep You From Blowing Up The Enterprise?\"\n  raw_title: \"RailsConf 2016 - Can Time-Travel Keep You From Blowing Up The Enterprise? by David Copeland\"\n  speakers:\n    - David Copeland\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    Can Time-Travel Keep You From Blowing Up The Enterprise? by David Copeland\n\n    Hindsight is 20/20, and there's a lot of advice out there telling you to do what the author wishes they had done at their last company to avoid disaster. Let's try to follow their advice and see where it lands us.\n\n    We'll take four journeys from rails new into a reasonable future. The first three, “dedicated team pulling apart the monolith a year later than hoped”, \"nothin' beats a monolith\", \"services from day one\" will blow up the Enterprise, while the fourth, “take reasonable steps to let the system evolve”, won't.\n\n  video_provider: \"youtube\"\n  video_id: \"23NhP4x3AAE\"\n\n# Track: New In Rails 5\n- id: \"justin-searls-railsconf-2016\"\n  title: \"RSpec and Rails 5\"\n  raw_title: \"RSpec and Rails 5 (Justin Searls)\"\n  speakers:\n    - Justin Searls\n    - Sam Phippen\n  event_name: \"RailsConf 2016\"\n  track: \"New In Rails 5\"\n  date: \"2016-05-04\"\n  published_at: \"2020-03-10\"\n  description: |-\n    Only a few days before RailsConf, I was asked by to fill in for this talk because of illnesss. The only catch: I would have to speak on the original topic, covering the same content, and without much in the way of ready-to-use prepared content. I stared at my white board for a few hours and agreed to do it.\n\n    The title of talk, as a result, is necessarily “RSpec and Rails 5”, but don’t let its name lead you to assume the scope of the talk is so narrow. By using the upcoming, perfunctory changes to both libraries as a jumping off point, the discussion quickly broadens to how developers relate to their tools over time, essentially asking “why should RSpec continue existing in 2016?”\n\n    More here: https://testdouble.com/insights/make-ruby-great-again\n  video_provider: \"youtube\"\n  video_id: \"2Ia4kVL53KA\"\n\n- id: \"andr-arko-railsconf-2016\"\n  title: \"Don't Forget the Network: Your App is Slower Than You Think\"\n  raw_title: \"RailsConf 2016 - Don't Forget the Network: Your App is Slower Than You Think By Andre Arko\"\n  speakers:\n    - André Arko\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    When you look at your response times, satisfied that they are \"fast enough\", you're forgetting an important thing: your users are on the other side of a network connection, and their browser has to process and render the data that you sent so quickly. This talk examines some often overlooked parts of web applications that can destroy your user experience even when your response times seem fantastic. We'll talk about networks, routing, client and server-side VMs, and how to measure and mitigate their issues.\n  video_provider: \"youtube\"\n  video_id: \"KP1nKRprj0Q\"\n\n# Track: Sponsored\n- id: \"jp-phillips-railsconf-2016\"\n  title: \"How Compose uses Rails to Scale Work, Now Open-Sourced\"\n  raw_title: \"RailsConf 2016 - How Compose uses Rails to Scale Work, Now Open-Sourced By JP Phillips\"\n  speakers:\n    - JP Phillips\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    How Compose uses Rails to Scale Work, Now Open-Sourced By JP Phillips\n\n    Compose is committed to making remote work work. Our biggest hurdle is communication and teamwork. When we joined forces with IBM, we added a new issue - how to scale. So, our devs built an app we’re open-sourcing called Fizz. Built on Rails, Fizz helps us empower our team to do great work, feel like family, and operate happily and efficiently as an international, remote, self-managing organization. We work transparently, commit to open-source, wear sweatpants, and genuinely enjoy each other and we’re committed to keeping it that way. We harnessed the power of Rails to make that happen.\n\n  video_provider: \"youtube\"\n  video_id: \"_3L5k_zozzw\"\n\n- id: \"teresa-martyny-railsconf-2016\"\n  title: \"From Director to Intern: Changing Careers as a Single Mom\"\n  raw_title: \"RailsConf 2016 - From Director to Intern: Changing Careers as a Single Mom by Teresa Martyny\"\n  speakers:\n    - Teresa Martyny\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-14\"\n  published_at: \"2016-05-14\"\n  description: |-\n    At the beginning of 2015 I was a Director in the non-profit sector, 13 years into my career. My days revolved around crisis intervention and violence prevention. I kept people alive and was well respected in my field. A mom of two, flying solo, people thought I was brave, stubborn... and a little insane... to step out on the ledge of career change. Come on out on the ledge and humble yourself with me. It'll make you a better engineer.\n  video_provider: \"youtube\"\n  video_id: \"hZLz9p58ZqU\"\n\n# ---\n\n# Happy Hour/Reception\n\n# ---\n\n- id: \"lightning-talks-day-1-railsconf-2016\"\n  title: \"Lightning Talks (Day 1)\"\n  raw_title: \"RailsConf 2016 - Lightning Talks\"\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DHHHnPwSY5I\"\n  talks:\n    - title: \"Lightning Talk: Tim Oliver\"\n      start_cue: \"1:05\"\n      end_cue: \"3:02\"\n      id: \"tim-oliver-lighting-talk-railsconf-2016\"\n      video_id: \"tim-oliver-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Tim Oliver\n\n    - title: \"Lightning Talk: Patel Alun\"\n      start_cue: \"3:02\"\n      end_cue: \"4:26\"\n      id: \"patel-alun-lighting-talk-railsconf-2016\"\n      video_id: \"patel-alun-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Patel Alun\n\n    - title: \"Lightning Talk: Thomas Witt\"\n      start_cue: \"4:26\"\n      end_cue: \"9:10\"\n      id: \"thomas-witt-lighting-talk-railsconf-2016\"\n      video_id: \"thomas-witt-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Thomas Witt\n\n    - title: \"Lightning Talk: Claudio Baccigalupo\"\n      start_cue: \"9:10\"\n      end_cue: \"12:42\"\n      id: \"claudio-baccigalupo-lighting-talk-railsconf-2016\"\n      video_id: \"claudio-baccigalupo-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Claudio Baccigalupo\n\n    - title: \"Lightning Talk: Michael Hartl\"\n      start_cue: \"12:42\"\n      end_cue: \"17:53\"\n      id: \"michael-hartl-lighting-talk-railsconf-2016\"\n      video_id: \"michael-hartl-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Hartl\n\n    - title: \"Lightning Talk: Reid Morrison\"\n      start_cue: \"17:53\"\n      end_cue: \"27:39\"\n      id: \"reid-morrison-lighting-talk-railsconf-2016\"\n      video_id: \"reid-morrison-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Reid Morrison\n\n    - title: \"Lightning Talk: Haley Anderson\"\n      start_cue: \"27:39\"\n      end_cue: \"32:27\"\n      id: \"haley-anderson-lighting-talk-railsconf-2016\"\n      video_id: \"haley-anderson-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Haley Anderson\n\n    - title: \"Lightning Talk: Mike Virata-Ston\"\n      start_cue: \"32:27\"\n      end_cue: \"37:33\"\n      id: \"mike-virata-ston-lighting-talk-railsconf-2016\"\n      video_id: \"mike-virata-ston-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Mike Virata-Ston\n\n    - title: \"Lightning Talk: John Sawers\"\n      start_cue: \"37:33\"\n      end_cue: \"43:00\"\n      id: \"john-sawers-lighting-talk-railsconf-2016\"\n      video_id: \"john-sawers-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - John Sawers\n\n    - title: \"Lightning Talk: Matthew Nielsen\"\n      start_cue: \"43:00\"\n      end_cue: \"47:37\"\n      id: \"matthew-nielsen-lighting-talk-railsconf-2016\"\n      video_id: \"matthew-nielsen-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Matthew Nielsen\n\n    - title: \"Lightning Talk: Adam Cuppy\"\n      start_cue: \"47:37\"\n      end_cue: \"51:14\"\n      id: \"adam-cuppy-lighting-talk-railsconf-2016\"\n      video_id: \"adam-cuppy-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Cuppy\n\n    - title: \"Lightning Talk: Godfrey Chan\"\n      start_cue: \"51:14\"\n      end_cue: \"55:02\"\n      id: \"godfrey-chan-lighting-talk-railsconf-2016\"\n      video_id: \"godfrey-chan-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Godfrey Chan\n\n    - title: \"Lightning Talk: Justin Collins\"\n      start_cue: \"55:02\"\n      end_cue: \"58:42\"\n      id: \"justin-collins-lighting-talk-railsconf-2016\"\n      video_id: \"justin-collins-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Justin Collins\n\n    - title: \"Lightning Talk: Nadia Odunayo & Saron Yitbarek\"\n      start_cue: \"58:42\"\n      end_cue: \"1:02:30\"\n      id: \"nadia-odunayo-saron-yitbarek-lighting-talk-railsconf-2016\"\n      video_id: \"nadia-odunayo-saron-yitbarek-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Nadia Odunayo\n        - Saron Yitbarek\n\n    - title: \"Lightning Talk: Saron Yitbarek\"\n      start_cue: \"1:02:30\"\n      end_cue: \"1:07:45\"\n      id: \"saron-yitbarek-lighting-talk-railsconf-2016\"\n      video_id: \"saron-yitbarek-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Saron Yitbarek\n\n    - title: \"Lightning Talk: Stephanie Nemeth\"\n      start_cue: \"1:07:45\"\n      end_cue: \"1:10:44\"\n      id: \"stephanie-nemeth-lighting-talk-railsconf-2016\"\n      video_id: \"stephanie-nemeth-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Stephanie Nemeth\n\n    - title: \"Lightning Talk: Jose Castro\"\n      start_cue: \"1:10:44\"\n      end_cue: \"1:15:42\"\n      id: \"jose-castro-lighting-talk-railsconf-2016\"\n      video_id: \"jose-castro-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Jose Castro\n\n    - title: \"Lightning Talk: Tianwen (Tian) Chen\"\n      start_cue: \"1:15:42\"\n      end_cue: \"1:22:29\"\n      id: \"tianwen-chen-lighting-talk-railsconf-2016\"\n      video_id: \"tianwen-chen-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Tianwen (Tian) Chen\n\n    - title: \"Lightning Talk: Benjamin Fleischer\"\n      start_cue: \"1:22:29\"\n      end_cue: \"1:27:39\"\n      id: \"benjamin-fleischer-lighting-talk-railsconf-2016\"\n      video_id: \"benjamin-fleischer-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Benjamin Fleischer\n\n    - title: \"Lightning Talk: Stephanie Marx\"\n      start_cue: \"1:27:39\"\n      end_cue: \"1:33:14\"\n      id: \"stephanie-marx-lighting-talk-railsconf-2016\"\n      video_id: \"stephanie-marx-lighting-talk-railsconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Stephanie Marx\n\n## Day 3 - 2016-05-06\n\n- id: \"aaron-patterson-railsconf-2016\"\n  title: \"Opening Keynote: Make Rails Great Again\"\n  raw_title: \"RailsConf 2016 - Opening Day 3 Keynote by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-13\"\n  description: |-\n    Aaron was born and raised on the mean streets of Salt Lake City. His only hope for survival was to join the local gang of undercover street ballet performers known as the Tender Tights. As a Tender Tights member, Aaron learned to perfect the technique of self-defense pirouettes so that nobody, not even the Parkour Posse could catch him. Between vicious street dance-offs, Aaron taught himself to program. He learned to combine the art of street ballet with the craft of software engineering. Using these unique skills, he was able to leave his life on the streets and become a professional software engineer. He is currently Pirouetting through Processes, and Couruing through code for GitHub. Sometimes he thinks back fondly on his life in the Tender Tights, but then he remembers that it is better to have Tender Loved and Lost than to never have Tender Taught at all.\n  video_provider: \"youtube\"\n  video_id: \"xMFs9DTympQ\"\n\n# ---\n\n# Morning Break\n\n# ---\n\n# Track: Designer/Developer\n- id: \"ryan-r-hughes-railsconf-2016\"\n  title: \"Bridging The Gap Between Designers and Developers\"\n  raw_title: \"RailsConf 2016 - Bridging the Gap between Designers and Developers by Ryan R Hughes\"\n  speakers:\n    - Ryan R Hughes\n  event_name: \"RailsConf 2016\"\n  track: \"Designer/Developer\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    Bridging the Gap between Designers and Developers by Ryan R Hughes\n\n    Every project...well most projects...begin in a great kumbaya where everyone is great friends and has high hopes for the future. About halfway through the project, an epic Braveheart style clash begins, with designers firmly lined up on one side and developers on the other.\n\n    In this talk, I'll share some of the things we've discovered over years of working on projects for over 100 clients that have helped to better define requirements and meet the needs of designers and developers throughout the life of a project.\n  video_provider: \"youtube\"\n  video_id: \"mweTM1hsn84\"\n\n- id: \"valerie-woolard-railsconf-2016\"\n  title: \"Finding Translations: Localization and Internationalization\"\n  raw_title: \"RailsConf 2016 - Finding Translations: Localization and Internationalization by Valerie Woolard\"\n  speakers:\n    - Valerie Woolard\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-13\"\n  description: |-\n    Translation, be it a word, sentence, concept, or idea, for different audiences has always been a challenge. This talk tackles problems of translation, especially those that tend to crop up in building software. We'll dive into the eminently practical—how to design apps for easier localization, common pitfalls, solutions for managing translations, approaches to version control with translations—and the more subjective—possible impacts of cultural differences, and what makes a \"good\" translation.\n  video_provider: \"youtube\"\n  video_id: \"uFOwICzjrvU\"\n\n# Track: Alternative Frameworks\n- id: \"bryan-powell-railsconf-2016\"\n  title: \"Build Realtime Apps with Ruby & Pakyow\"\n  raw_title: \"RailsConf 2016 -  Build Realtime Apps with Ruby & Pakyow By Bryan Powell\"\n  speakers:\n    - Bryan Powell\n  event_name: \"RailsConf 2016\"\n  track: \"Alternative Frameworks\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    Client-side frameworks dominate the conversation about the future of web apps. Where does that leave us Ruby developers? Let's explore a way to build realtime apps driven by a traditional backend, without writing a single line of JavaScript! You’ll walk away with a new way to build modern, realtime apps employing client-side patterns.\n  video_provider: \"youtube\"\n  video_id: \"ttnlh_Y0XJM\"\n\n# Track: Sponsored\n- id: \"bradley-herman-railsconf-2016\"\n  title: \"Step 1) Hack, Step 2) ?, Step 3) Profit\"\n  raw_title: \"RailsConf 2016 - Step 1) Hack, Step 2) ?, Step 3) Profit By Bradley Herman\"\n  speakers:\n    - Bradley Herman\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Step 1) Hack, Step 2) ?, Step 3) Profit By Bradley Herman\n\n    Hired's mission is to get everyone a job they love. As a transparent marketplace, Hired connects companies and engineers using technology and a personal touch. Initially a weekend hack project, it's grown to help thousands find their dream jobs/teams in 16 cities in 6 countries. From that origin, Hired has regularly focused efforts in hackathons, which have spurred much of the company's innovation.\n\n    Hiten & Brad will talk about their culture of empowerment, creativity, and trust and highlight several core features that have grown from small experiments to foundational parts of the experience.\n\n  video_provider: \"youtube\"\n  video_id: \"rktRuNfmW9I\"\n\n# Track: Security\n- id: \"mike-milner-railsconf-2016\"\n  title: \"The State of Web Security\"\n  raw_title: \"RailsConf 2016 - The State of Web Security by Mike Milner\"\n  speakers:\n    - Mike Milner\n  event_name: \"RailsConf 2016\"\n  track: \"Security\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    Join me for a wild ride through the dizzying highs and terrifying lows of web security in 2015. Take a look at some major breaches of the year, from Top Secret clearances, to medical records, all the way to free beer. We’ll look at how attack trends have changed over the past year and new ways websites are being compromised. We’ve pulled together data from all the sites we protect to show you insights on types and patterns of attacks, and sophistication and origin of the attackers. After the bad, we’ll look at the good - new technologies like U2F and RASP that are helping secure the web.\n  video_provider: \"youtube\"\n  video_id: \"UoiCylwUoq4\"\n\n# ---\n\n# Track: Designer/Developer\n- id: \"mike-fotinakis-railsconf-2016\"\n  title: \"Continuous Visual Integration for Rails\"\n  raw_title: \"RailsConf 2016 - Continuous Visual Integration for Rails by Mike Fotinakis\"\n  speakers:\n    - Mike Fotinakis\n  event_name: \"RailsConf 2016\"\n  track: \"Designer/Developer\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    Continuous Visual Integration for Rails by Mike Fotinakis\n\n    Unit testing is mostly a solved problem, but how do you write tests for the visual side of your app—the part that your users actually see and interact with? How do you stop visual bugs from reaching your users?\n\n    We will dive deep into visual regression testing, a fast-growing technique for testing apps pixel-by-pixel. We will integrate perceptual diffs in Rails feature specs, and learn how to visually test even complex UI states. We will show tools and techniques for continuous visual integration on every commit, and learn how to introduce team visual reviews right alongside code reviews.\n  video_provider: \"youtube\"\n  video_id: \"5h-JJ2wqiIw\"\n\n- id: \"stella-cotton-railsconf-2016\"\n  title: \"Site Availability is for Everybody\"\n  raw_title: \"RailsConf 2016 - Site Availability is for Everybody by Stella Cotton\"\n  speakers:\n    - Stella Cotton\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-13\"\n  description: |-\n    Your phone rings in the middle of the night and the site is down—- do you know what to do? Whether it's Black Friday or a DDoS attack, our Ruby apps and Ruby devs have to be prepared for the best and the worst. Don't let a crisis catch you off guard! Fortunately, you can sharpen your skills ahead of time with load testing. Learn tips and common pitfalls when simulating application load, as well as key metrics and graphs to understand when site availability is compromised.\n  video_provider: \"youtube\"\n  video_id: \"hgpNRhQWWNw\"\n\n# Track: Alternative Frameworks\n- id: \"jeremy-green-railsconf-2016\"\n  title: \"Going Serverless\"\n  raw_title: \"RailsConf 2016 - Going Serverless By Jeremy Green\"\n  speakers:\n    - Jeremy Green\n  event_name: \"RailsConf 2016\"\n  track: \"Alternative Frameworks\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    Serverless is a new framework that allows developers to easily harness AWS Lambda and Api Gateway to build and deploy full fledged API services without needing to deal with any ops level overhead or paying for servers when they're not in use. It's kinda like Heroku on-demand for single functions.\n  video_provider: \"youtube\"\n  video_id: \"stOpBNo5l-E\"\n\n# Track: Sponsored\n- id: \"james-smith-railsconf-2016\"\n  title: \"Your Software is Broken — Pay Attention\"\n  raw_title: \"RailsConf 2016 - Your Software is Broken — Pay Attention by James Smith\"\n  speakers:\n    - James Smith\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Your Software is Broken — Pay Attention by James Smith\n\n    Your team has been tasked with releasing new and better versions of your product at record speed. But the risk of moving quickly is things break in production and users abandon your buggy app. To stay competitive, you can't just ship fast - you also have to solve for quality.\n\n    We'll rethink what it means to actively monitor your application in production so your team can ship fast with confidence. With the right tooling, workflow, and organizational structures, you don't have to sacrifice release times or stability. When things break, you'll be able to fix errors before they impact your users.\n\n  video_provider: \"youtube\"\n  video_id: \"F6g_Fx8qqCU\"\n\n# Track: Security\n- id: \"justin-collins-railsconf-2016\"\n  title: \"...But Doesn't Rails Take Care of Security for Me?\"\n  raw_title: \"RailsConf 2016 - ...But Doesn't Rails Take Care of Security for Me? by Justin Collins\"\n  speakers:\n    - Justin Collins\n  event_name: \"RailsConf 2016\"\n  track: \"Security\"\n  date: \"2016-05-13\"\n  published_at: \"2016-05-13\"\n  description: |-\n    Rails comes with protection against SQL injection, cross site scripting, and cross site request forgery. It provides strong parameters and encrypted session cookies out of the box. What else is there to worry about? Unfortunately, security does not stop at the well-known vulnerabilities and even the most secure web framework cannot save you from everything. Let's take a deep dive into real world examples of security gone wrong!\n  video_provider: \"youtube\"\n  video_id: \"3P9naxOfUC4\"\n\n# ---\n\n# Lunch\n\n# ---\n\n# Track: Designer/Developer\n- id: \"roy-tomeij-railsconf-2016\"\n  title: \"Make Them Click\"\n  raw_title: \"RailsConf 2016 - Make Them Click by Roy Tomeij\"\n  speakers:\n    - Roy Tomeij\n  event_name: \"RailsConf 2016\"\n  track: \"Designer/Developer\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    Make Them Click by Roy Tomeij\n\n    Whether you want it or not, you're the constant victim of neuro-marketing. By tapping into your \"reptile brain\", you are unconsciously made to click, like and buy. We'll look at scarcity, social validation, reciprocity and much more. All web apps have customers of some sort, and it's your job to guide them, either for usability or profit. You'll learn how to see others' influence on you, and maybe to exert some influence of your own.\n\n  video_provider: \"youtube\"\n  video_id: \"vsc4HmLCxY4\"\n\n- id: \"ernie-miller-railsconf-2016\"\n  title: \"How to Build a Skyscraper\"\n  raw_title: \"RailsConf 2016 - How to Build a Skyscraper by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-28\"\n  published_at: \"2016-05-28\"\n  description: |-\n    How to Build a Skyscraper by Ernie Miller\n\n    Since 1884, humans have been building skyscrapers. This means that we had 6 decades of skyscraper-building experience before we started building software (depending on your definition of \"software\"). Maybe there are some lessons we can learn from past experience?\n\n    This talk won't make you an expert skyscraper-builder, but you might just come away with a different perspective on how you build software.\n\n  video_provider: \"youtube\"\n  video_id: \"x8mSR9iAm74\"\n\n# Track: Alternative Frameworks\n- id: \"simone-carletti-railsconf-2016\"\n  title: \"Developing and Maintaining a Platform With Rails and Lotus\"\n  raw_title: \"RailsConf 2016 - Developing and Maintaining a Platform With Rails and Lotus By Simone Carletti\"\n  speakers:\n    - Simone Carletti\n  event_name: \"RailsConf 2016\"\n  track: \"Alternative Frameworks\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    This talk illustrates the development techniques, Ruby patterns and best practices we adopt at DNSimple to develop new features and ensure long-term maintainability of our codebase. It also features how we used Lotus to develop the new API as a standalone Rack app mounted under the Rails router.\n\n    Two years ago we started a major redesign of our REST API with the goal to decouple it from our main Rails application and expose all the main features via API. It was not a trivial task, but still feasible due to the guidelines we adopted in the last 6 years to structure our Rails application.\n  video_provider: \"youtube\"\n  video_id: \"FkWt7ep5XRM\"\n\n- id: \"barrett-clark-railsconf-2016\"\n  title: \"Crushing It With Rake Tasks\"\n  raw_title: \"RailsConf 2016 - Crushing It With Rake Tasks By Barrett Clark\"\n  speakers:\n    - Barrett Clark\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Crushing It With Rake Tasks By Barrett Clark\n\n    Although bundle exec rake db:migrate is probably the single biggest killer feature in Rails, there is a lot more to rake.\n\n    Rails offers several rake tasks to help with everyday project management, like redoing a migration because you changed your mind on one of the columns, clearing your log files because they get so big, and listing out the TODOs and FIXMEs.\n\n    What's even more awesome that all that is that you can create your own rake tasks. Got a tedious command-line process? Write a rake task for it!\n\n  video_provider: \"youtube\"\n  video_id: \"8HRJQUr2Y3Q\"\n\n# Track: Security\n- id: \"jessica-rudder-railsconf-2016\"\n  title: \"Will It Inject? A Look at SQL injections and Active Record\"\n  raw_title: \"RailsConf 2016 - Will It Inject? A Look at SQL injections and ActiveRecord by Jessica Rudder\"\n  speakers:\n    - Jessica Rudder\n  event_name: \"RailsConf 2016\"\n  track: \"Security\"\n  date: \"2016-05-13\"\n  published_at: \"2016-05-13\"\n  description: |-\n    If you've struggled through writing complex queries in raw SQL, ActiveRecord methods are a helpful breath of fresh air. If you're not careful though, those methods could potentially leave your site open to a nasty SQL Injection attack. We'll take a look at the most common ActiveRecord methods (and some of the lesser known ones!) with one question in mind....will it inject? If it's vulnerable to a SQL injection attack, we'll cover how to structure your query to keep your data secure.\n  video_provider: \"youtube\"\n  video_id: \"2GHWAYys1is\"\n\n# ---\n\n# Track: Designer/Developer\n- id: \"betsy-haibel-railsconf-2016\"\n  title: \"Style Documentation for the Resource-Limited\"\n  raw_title: \"RailsConf 2016 - Style Documentation for the Resource-Limited by Betsy Haibel\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"RailsConf 2016\"\n  track: \"Designer/Developer\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    Style Documentation for the Resource-Limited by Betsy Haibel\n\n    Application view layers are always hard to manage. Usually we handwave this as the natural consequence of views being where fuzzy user experience and designer brains meet the cleaner, neater logic of computers and developers. But that handwave can be misleading. View layers are hard to manage because they’re the part of a system where gaps in a team’s interdisciplinary collaboration become glaring. A comprehensive, well-documented styleguide and component library is a utopian ideal. Is it possible to actually get there? It is, and we can do it incrementally with minimal refactor hell.\n  video_provider: \"youtube\"\n  video_id: \"wR0h5RyeSGQ\"\n\n- id: \"katrina-owen-railsconf-2016\"\n  title: \"Succession\"\n  raw_title: \"RailsConf 2016 - Succession by Katrina Owen\"\n  speakers:\n    - Katrina Owen\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-28\"\n  published_at: \"2016-05-28\"\n  description: |-\n    Succession by Katrina Owen\n\n    Refactoring sometimes devolves into an appalling mess. You're chasing a broken test suite, and every change just makes it worse. An even more insidious antipattern is the slow, perfectly controlled process culminating in dreadful design.\n\n    This talk presents an end-to-end refactoring that demonstrates simple strategies to avoid such misadventures.\n\n  video_provider: \"youtube\"\n  video_id: \"59YClXmkCVM\"\n\n# Track: Alternative Frameworks\n- id: \"brian-cardarella-railsconf-2016\"\n  title: \"Rails to Phoenix\"\n  raw_title: \"RailsConf 2016 - Rails to Phoenix by Brian Cardarella\"\n  speakers:\n    - Brian Cardarella\n  event_name: \"RailsConf 2016\"\n  track: \"Alternative Frameworks\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    You may have heard about Phoenix and Elixir. It is a language and framework that give you performance without sacrificing productivity. Learn why Phoenix is a great choice for Rails developers and how you can introduce it into your organization.\n  video_provider: \"youtube\"\n  video_id: \"OxhTQdcieQE\"\n\n# Track: Sponsored\n- id: \"mark-mcdonald-railsconf-2016\"\n  title: \"Priming You for Your Job Search\"\n  raw_title: \"RailsConf 2016 -  Priming You for Your Job Search\"\n  speakers:\n    - Mark McDonald\n    - MiMi Moore\n    - Travis Hillery\n    - Kim Lambright\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Priming You for Your Job Search by Mark McDonald, MiMi Moore and Travis\n    Hillery \\n\\nIndeed Prime is the job-search industry’s newest disruptive product.\n    Prime takes the best job-seekers, works hard to make sure their profiles are perfectly\n    polished, and puts them on the Prime platform, where our exclusive group of clients\n    come to them. With Indeed Prime, jobs come to the job-seeker.\\n\\nIn this session,\n    join Indeed Prime’s expert group of talent specialists as they set time aside\n    to help you practice interview questions, edit your resume, and prep for the next\n    step in your career.\n    n\\n\n  video_provider: \"youtube\"\n  video_id: \"RrN0NA4rRbU\"\n\n- id: \"godfrey-chan-railsconf-2016\"\n  title: \"Turbo Rails with Rust\"\n  raw_title: \"RailsConf 2016 - Turbo Rails with Rust by Godfrey Chan\"\n  speakers:\n    - Godfrey Chan\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-13\"\n  published_at: \"2016-05-13\"\n  slides_url: \"https://speakerdeck.com/chancancode/turbo-rails-with-rust\"\n  description: |-\n    Ruby is not the fastest language in the world, there is no doubt about it. This doesn't turn out to matter all that much – Ruby and its ecosystem has so much more to offer, making it a worthwhile tradeoff a lot of the times. However, you might occasionally encounter workloads that are simply not suitable for Ruby. This is especially true for frameworks like Rails, where the overhead wants to be as little as possible. In this talk, we will explore building a native Ruby extension with Rust to speed up parts of Rails. What does Rust have to offer here over plain-old C? Let's find out!\n  video_provider: \"youtube\"\n  video_id: \"PbJI8yCsEkA\"\n\n# ---\n\n- id: \"jason-clark-railsconf-2016\"\n  title: \"Real World Docker for the Rubyist\"\n  raw_title: \"RailsConf 2016 -  Real World Docker for the Rubyist by Jason Clark\"\n  speakers:\n    - Jason Clark\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-27\"\n  published_at: \"2016-05-27\"\n  description: |-\n    Real World Docker for the Rubyist by Jason Clark\n\n    Docker’s gotten a lot of press, but how does it fare in the real world Rubyists inhabit every day?\n\n    Together we’ll take a deep dive into how a real company transformed itself to run on Docker. We’ll see how to build and maintain Docker images tailored for Ruby. We’ll dig into proper configuration and deployment options for containerized applications. Along the way we’ll highlight the pitfalls, bugs and gotchas that come with such a young, fast moving platform like Docker.\n\n    Whether you’re in production with Docker or just dabbling, come learn how Docker and Ruby make an awesome combination.\n\n  video_provider: \"youtube\"\n  video_id: \"DyBvMrNX1ZY\"\n\n- id: \"sandi-metz-railsconf-2016\"\n  title: \"Get a Whiff of This\"\n  raw_title: \"RailsConf 2016 - Get a Whiff of This by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-28\"\n  published_at: \"2016-05-28\"\n  description: |-\n    Get a Whiff of This by Sandi Metz\n\n    Most code is a mess. Most new requirements change existing code. Ergo, much our work involves altering imperfect code.\n\n    That's the bad news.\n\n    The good news is that every big mess consists of many small ones. Certain small problems occur so frequently that they've been given names, and are collectively known as \"Code Smells\".\n\n    This talk shows how to take a pile of perplexing code, identify the \"smells\", and surgically apply the curative refactorings. It breaks a messy problem into clear-cut pieces, and proves that you can fix anything without being forced to understand everything.\n\n  video_provider: \"youtube\"\n  video_id: \"PJjHfa5yxlU\"\n\n- id: \"minqi-pan-railsconf-2016\"\n  title: \"How We Scaled GitLab For a 30k-employee Company\"\n  raw_title: \"RailsConf 2016 - How We Scaled GitLab For a 30k-employee Company By Minqi Pan\"\n  speakers:\n    - Minqi Pan\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    GitLab, the open source alternative to GitHub written in Rails, does not scale automatically out of the box, as it stores its git repositories on a single filesystem, making storage capabilities hard to expand. Rather than attaching a NAS server, we decided to use a cloud-based object storage (such as S3) to replace the FS. This introduced changes to both the Ruby layer and the deeper C layers. In this talk, we will show the audience how we did the change and overcame the performance loss introduced by network I/O. We will also show how we achieved high-availability after the changes.GitLab, the open source alternative to GitHub written in Rails, does not scale automatically out of the box, as it stores its git repositories on a single filesystem, making storage capabilities hard to expand. Rather than attaching a NAS server, we decided to use a cloud-based object storage (such as S3) to replace the FS. This introduced changes to both the Ruby layer and the deeper C layers. In this talk, we will show the audience how we did the change and overcame the performance loss introduced by network I/O. We will also show how we achieved high-availability after the changes.\n  video_provider: \"youtube\"\n  video_id: \"byZcOH92CiY\"\n\n# Track: Sponsored\n- id: \"nathan-smith-railsconf-2016\"\n  title: \"Strong Practices for Rails Applications Continuous Delivery\"\n  raw_title: \"RailsConf 2016 - Strong Practices for Rails Applications Continuous Delivery\"\n  speakers:\n    - Nathan Smith\n    - Robb Kidd\n  event_name: \"RailsConf 2016\"\n  track: \"Sponsored\"\n  date: \"2016-05-26\"\n  published_at: \"2016-05-26\"\n  description: |-\n    Strong Practices for Rails Applications Continuous Delivery by Nathan Smith & Robb Kidd\n\n    High-velocity organizations deliver change to their customers quickly in a repeatable and predictable way. This talk will explore some pre-requisites and best practices that will help your team move to safe, continuous delivery of your Rails applications. We will demonstrate the path from code commit, to packaged application, to an updated production environment. All of the necessary steps along the way will be fully automated using Chef Delivery. You will leave with some new ideas, practices, and techniques your team can adopt, continuously delivering value to your customers.\n\n  video_provider: \"youtube\"\n  video_id: \"zX3Kggw1Y-c\"\n\n- id: \"mike-groseclose-railsconf-2016\"\n  title: \"Client/Server Architecture: Past, Present, & Future\"\n  raw_title: \"RailsConf 2016 - Client/Server Architecture: Past, Present, & Future By Mike Groseclose\"\n  speakers:\n    - Mike Groseclose\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-24\"\n  published_at: \"2016-05-24\"\n  description: |-\n    Client/Server Architecture: Past, Present, & Future By Mike Groseclose The client/server architecture that powers much of the web is evolving. Full stack, monolithic, apps are becoming a thing of the past as new requirements have forced us to think differently about how we build apps. New client/server architectures create a clear separation of concerns between the server and the client.\n\n    As developers, we have the ability to create the new abstractions that will power the web. Understanding the past, present, and future of the client/server help us to become more active participants in the future ecosystem for building web applications.\n\n  video_provider: \"youtube\"\n  video_id: \"-ZqQRUWkomk\"\n\n# ---\n\n# Afternoon Break\n\n# ---\n\n- id: \"paul-lamere-railsconf-2016\"\n  title: \"Closing Keynote: Data Mining Music\"\n  raw_title: \"RailsConf 2016 - Closing Keynote: Paul Lamere\"\n  speakers:\n    - Paul Lamere\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-29\"\n  published_at: \"2016-05-29\"\n  description: |-\n    Closing Keynote: Paul Lamere\n\n    Paul Lamere works at Spotify, where he spends all his time building machines to figure out what song you really want to listen to next.\n\n    When not at work, Paul spends much of his spare time hacking on music apps. Paul's work and hacks are world-renowned including the 'The Infinite Jukebox', and 'Girl Talk in a Box'.  Paul is a four-time nominee and twice winner of the MTV O Music Award for Best Music Hack (Winning hacks: 'Bohemian Rhapsichord' and 'The Bonhamizer')  and is the first inductee into the Music Hacker's Hall of Fame.  Paul also authors a popular blog about music technology called 'Music Machinery'.\n  video_provider: \"youtube\"\n  video_id: \"f7XN3RuDzmc\"\n\n# ---\n\n## Not in schedule:\n\n- id: \"coraline-ada-ehmke-railsconf-2016-ruby-hero-awards\"\n  title: \"Ruby Hero Awards\"\n  raw_title: \"RailsConf 2016 - Ruby Hero Awards\"\n  speakers:\n    # TODO: name of MC\n    - Coraline Ada Ehmke\n    - Akira Matsuda\n    - Anika Lindtner\n    - Laura Gaetano\n    - Sara Regan\n    - Koichi Sasada\n    - Richard Schneeman\n    - Avdi Grimm\n    - Charles Nutter\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-13\"\n  published_at: \"2016-05-13\"\n  description: |-\n    The Ruby Hero Awards recognize everyday heroes of the Ruby community. The Ruby community is full of good people who help each other in diverse ways to make the community a better place.\n    Once a year at RailsConf, we take a moment to appreciate their contributions and hopefully encourage others to make a difference.\n  video_provider: \"youtube\"\n  video_id: \"JSNogJGaMms\"\n\n- id: \"bradley-herman-railsconf-2016-sponsored-50-30-hired\"\n  title: \"Sponsored: 5.0 / 30 (Hired)\"\n  raw_title: \"RailsConf 2016 - Sponsor: Hired by Bradley Herman\"\n  speakers:\n    - Bradley Herman\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-28\"\n  published_at: \"2016-05-28\"\n  description: |-\n    Sponsor: Hired by Bradley Herman\n\n  video_provider: \"youtube\"\n  video_id: \"7-apgRR5O5k\"\n\n- id: \"chris-coln-railsconf-2016\"\n  title: \"Sponsored: Indeed Prime (Indeed)\"\n  raw_title: \"RailsConf 2016 - Sponsor: Indeed by Chris Colòn\"\n  speakers:\n    - Chris Colòn\n  event_name: \"RailsConf 2016\"\n  date: \"2016-05-28\"\n  published_at: \"2016-05-28\"\n  description: |-\n    Sponsor: Indeed by Chris Colòn\n\n  video_provider: \"youtube\"\n  video_id: \"Zt4euou1r1U\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2017/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyarr-2jYCnnlb7wl-aEz4xt\"\ntitle: \"RailsConf 2017\"\nkind: \"conference\"\nlocation: \"Phoenix, AZ, United States\"\ndescription: \"\"\npublished_at: \"2017-05-05\"\nstart_date: \"2017-04-25\"\nend_date: \"2017-04-27\"\nyear: 2017\nbanner_background: \"#C8EAF4\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#5F1F7C\"\ncoordinates:\n  latitude: 33.4482948\n  longitude: -112.0725488\n"
  },
  {
    "path": "data/railsconf/railsconf-2017/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"michael-swieton-railsconf-2017\"\n  title: \"The Art & Craft of Secrets: Using the Cryptographic Toolbox\"\n  raw_title: \"RailsConf 2017: The Art & Craft of Secrets: Using the Cryptographic Toolbox by Michael  Swieton\"\n  speakers:\n    - Michael Swieton\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-05\"\n  published_at: \"2017-05-05\"\n  description: |-\n    RailsConf 2017: The Art & Craft of Secrets: Using the Cryptographic Toolbox by Michael  Swieton\n\n    Picking an encryption algorithm is like choosing a lock for your door. Some are better than others - but there's more to keeping burglars out of your house (or web site) than just the door lock. This talk will review what the crypto tools are and how they fit together with our frameworks to provide trust and privacy for our applications. We'll look under the hood of websites like Facebook, at game-changing exploits like Firesheep, and at how tools from our application layer (Rails,) our protocol layer (HTTP,) and our transport layer (TLS) combine build user-visible features like single sign-on.\n  video_provider: \"youtube\"\n  video_id: \"6KAYq9vw_pY\"\n\n- id: \"haseeb-qureshi-railsconf-2017\"\n  title: \"Why Software Engineers Disagree About Everything\"\n  raw_title: \"RailsConf 2017: Why Software Engineers Disagree About Everything by Haseeb Qureshi\"\n  speakers:\n    - Haseeb Qureshi\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-05\"\n  published_at: \"2017-05-05\"\n  description: |-\n    RailsConf 2017: Why Software Engineers Disagree About Everything by Haseeb Qureshi\n\n    Why are there are so many disagreements in software? Why don’t we all converge on the same beliefs or technologies? It might sound obvious that people shouldn't agree, but I want to convince you it’s weird that we don't. This talk will be a philosophical exploration of how knowledge converges within subcultures, as I explore this question through the worlds of software, online fraud, and poker.\n  video_provider: \"youtube\"\n  video_id: \"x07q6V4VXC8\"\n\n- id: \"david-heinemeier-hansson-railsconf-2017\"\n  title: \"Keynote: The Best Tool For The Job!\"\n  raw_title: \"RailsConf 2017: Opening Keynote by David Heinemeier Hansson\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-05\"\n  published_at: \"2017-05-05\"\n  description: |-\n    RailsConf 2017: Opening Keynote by David Heinemeier Hansson\n  video_provider: \"youtube\"\n  video_id: \"Cx6aGMC6MjU\"\n\n- id: \"eileen-m-uchitelle-railsconf-2017\"\n  title: \"Building Rails ActionDispatch::SystemTestCase Framework\"\n  raw_title: \"RailsConf 2017: Building Rails ActionDispatch::SystemTestCase Framework by Eileen Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-05\"\n  published_at: \"2017-05-05\"\n  description: |-\n    RailsConf 2017: Building Rails ActionDispatch::SystemTestCase Framework by Eileen M. Uchitelle\n\n    At the 2014 RailsConf DHH declared system testing would be added to Rails. Three years later, Rails 5.1 makes good on that promise by introducing a new testing framework: ActionDispatch::SystemTestCase. The feature brings system testing to Rails with zero application configuration by adding Capybara integration. After a demonstration of the new framework, we'll walk through what's uniquely involved with building OSS features & how the architecture follows the Rails Doctrine. We'll take a rare look at what it takes to build a major feature for Rails, including goals, design decisions, & roadblocks.\n  video_provider: \"youtube\"\n  video_id: \"sSn4B8orX70\"\n\n- id: \"alex-kitchens-railsconf-2017\"\n  title: \"Perusing the Rails Source Code - A Beginners Guide\"\n  raw_title: \"RailsConf 2017: Perusing the Rails Source Code - A Beginners Guide by Alex Kitchens\"\n  speakers:\n    - Alex Kitchens\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-05\"\n  published_at: \"2017-05-05\"\n  description: |-\n    RailsConf 2017: Perusing the Rails Source Code - A Beginners Guide by Alex Kitchens\n\n    Open source projects like Rails are intimidating, especially as a beginner. It’s hard to look at the code and know what it does. But Ruby on Rails is more than just code. Written into it are years of research, discussions, and motivations. Also written into it are bugs, typos, and all of the pieces that make the code human. This talk outlines steps you can take to explore the inner workings of Rails and gain context on its design. Understanding how Rails works will allow you to write better Rails applications and better Ruby code. You will leave with many resources and tips on perusing Rails.\n  video_provider: \"youtube\"\n  video_id: \"Q_MpGRfnY5s\"\n\n- id: \"sam-phippen-railsconf-2017\"\n  title: \"Teaching RSpec to Play nice with Rails\"\n  raw_title: \"RailsConf 2017: Teaching RSpec to Play nice with Rails by Sam Phippen\"\n  speakers:\n    - Sam Phippen\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-05\"\n  published_at: \"2017-05-05\"\n  description: |-\n    RailsConf 2017: Teaching RSpec to Play nice with Rails by Sam Phippen\n\n    RSpec gives you many ways to test your Rails app. Controller, view, model, and so on. Often, it's not clear which to use. In this talk, you'll get some practical advice to improve your testing by understanding how RSpec integrates with Rails. To do this we'll look through some real world RSpec bugs, and with each one, clarify our understanding of the boundaries between RSpec and Rails.\n\n    If you're looking to level up your testing, understand RSpec's internals a little better, or improve your Rails knowledge, this talk will have something for you. Some knowledge of RSpec's test types will be assumed.\n  video_provider: \"youtube\"\n  video_id: \"jyPfrK1y1nc\"\n\n- id: \"krista-nelson-railsconf-2017\"\n  title: \"Uncertain Times: Securing Rails Apps and User Data\"\n  raw_title: \"RailsConf 2017: Uncertain Times: Securing Rails Apps and User Data by Krista Nelson\"\n  speakers:\n    - Krista Nelson\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-05\"\n  published_at: \"2017-05-05\"\n  description: |-\n    RailsConf 2017: Uncertain Times: Securing Rails Apps and User Data by Krista Nelson\n\n    It’s what everyone is talking about: cyber security, hacking and the safety of our data. Many of us are anxiously asking what can do we do? We can implement security best practices to protect our user’s personal identifiable information from harm. We each have the power and duty to be a force for good.\n\n    Security is a moving target and a full team effort, so whether you are a beginner or senior level Rails developer, this talk will cover important measures and resources to make sure your Rails app is best secured.\n  video_provider: \"youtube\"\n  video_id: \"rSuya_TFYso\"\n\n- id: \"nickolas-means-railsconf-2017\"\n  title: \"Warning: May Be Habit Forming\"\n  raw_title: \"RailsConf 2017: Warning: May Be Habit Forming by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-09\"\n  published_at: \"2017-05-09\"\n  description: |-\n    RailsConf 2017: Warning: May Be Habit Forming by Nickolas Means\n\n    Over the past year, I’ve spoken at several conferences, lost 30 pounds, and worked up to running my first 5K, all while leading an engineering team and spending significant time with my family. I also have less willpower than just about everyone I know. So how’d I accomplish those things?\n\n    Let’s talk about how to build goals the right way so that you’ll be all but guaranteed to hit them. We’ll work through the process of creating systems and nurturing habits to turn your brain into your biggest ally, no matter what you want to accomplish!\n  video_provider: \"youtube\"\n  video_id: \"xT_YaduPYlk\"\n\n- id: \"justin-searls-railsconf-2017\"\n  title: \"Keynote: How To Program\"\n  raw_title: \"RailsConf 2017: Keynote by Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-09\"\n  published_at: \"2017-05-09\"\n  description: |-\n    RailsConf 2017: Keynote by Justin Searls\n  video_provider: \"youtube\"\n  video_id: \"V4fnzHxHXMI\"\n\n- id: \"mark-simoneau-railsconf-2017\"\n  title: \"Rough to Fine: Programming Lessons from Woodworking\"\n  raw_title: \"RailsConf 2017: Rough to Fine: Programming Lessons from Woodworking by Mark Simoneau\"\n  speakers:\n    - Mark Simoneau\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-09\"\n  published_at: \"2017-05-09\"\n  description: |-\n    RailsConf 2017: Rough to Fine: Programming Lessons from Woodworking by Mark Simoneau\n\n    Woodworking has experienced quite a renaissance as of late, and a very popular style involves using power tools for rough work and hand tools for detail and precision work. Using both defines each woodworker's speed and ability to produce beautiful/functional pieces. The same can be true of developers. Automation, convention, powerful IDEs, generators and libraries can make each developer go from nothing to something very quickly, but what about diving deeper to get the precision, performance and beauty you need out of your applications? Come find out.\n  video_provider: \"youtube\"\n  video_id: \"962UBsaLjtw\"\n\n- id: \"rafael-mendona-frana-railsconf-2017\"\n  title: \"Upgrading a big application to Rails 5\"\n  raw_title: \"RailsConf 2017: Upgrading a big application to Rails 5 by Rafael França\"\n  speakers:\n    - Rafael Mendonça França\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-09\"\n  published_at: \"2017-05-09\"\n  description: |-\n    RailsConf 2017: Upgrading a big application to Rails 5 by Rafael Mendonça França\n\n    In this talk we would take a look in different strategies to upgrade Rails application to the newest version taking as example a huge monolithic Rails application. We will learn what were the biggest challenges and how they could be avoided. We will also learn why the changes were made in Rails and how they work.\n  video_provider: \"youtube\"\n  video_id: \"I-2Xy3RS1ns\"\n\n- id: \"brad-urani-railsconf-2017\"\n  title: \"The Arcane Art of Error Handling\"\n  raw_title: \"RailsConf 2017: The Arcane Art of Error Handling by Brad Urani\"\n  speakers:\n    - Brad Urani\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-09\"\n  published_at: \"2017-05-09\"\n  description: |-\n    RailsConf 2017: The Arcane Art of Error Handling by Brad Urani\n\n    With complexity comes errors, and unexpected errors lead to unexpected unhappiness. Join us and learn how to add contextual data to errors, design error hierarchies, take charge of control flow, create re-usable error handlers, and integrate with error reporting solutions. We'll talk about recoverable versus irrecoverable errors and discuss how and how not to use exceptions. From internationalization to background jobs, we'll cover the gamut. Regardless of your Rail proficiency, you'll learn why expecting the unexpected makes for happier developers, happier businesses and happier users.\n  video_provider: \"youtube\"\n  video_id: \"9R4wlyWBP1k\"\n\n- id: \"lightning-talks-railsconf-2017\"\n  title: \"Lightning Talks\"\n  raw_title: \"RailsConf 2017: Lightning Talks by Various Speakers\"\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-09\"\n  published_at: \"2017-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"KGi9wRHWvB0\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Benjamin Fleischer\" # TODO: missing talk title\n      start_cue: \"00:00\"\n      end_cue: \"01:23\"\n      id: \"benjamin-fleischer-lighting-talk-railsconf-2017\"\n      video_id: \"benjamin-fleischer-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Benjamin Fleischer\n\n    - title: \"Lightning Talk: Heather Herrington\" # TODO: missing talk title\n      start_cue: \"01:23\"\n      end_cue: \"06:39\"\n      id: \"heather-herrington-lighting-talk-railsconf-2017\"\n      video_id: \"heather-herrington-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Heather Herrington\n\n    - title: \"Lightning Talk: Casey Maucaulay\" # TODO: missing talk title\n      start_cue: \"06:39\"\n      end_cue: \"10:56\"\n      id: \"casey-maucaulay-lighting-talk-railsconf-2017\"\n      video_id: \"casey-maucaulay-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Casey Maucaulay\n\n    - title: \"Lightning Talk: Kristen Ruben\" # TODO: missing talk title\n      start_cue: \"10:56\"\n      end_cue: \"17:44\"\n      id: \"kristen-ruben-lighting-talk-railsconf-2017\"\n      video_id: \"kristen-ruben-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Kristen Ruben\n\n    - title: \"Lightning Talk: Lucas Fittl\" # TODO: missing talk title\n      start_cue: \"17:44\"\n      end_cue: \"18:40\"\n      id: \"lucas-fittl-lighting-talk-railsconf-2017\"\n      video_id: \"lucas-fittl-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Lucas Fittl\n\n    - title: \"Lightning Talk: Justin Collins\" # TODO: missing talk title\n      start_cue: \"18:40\"\n      end_cue: \"19:36\"\n      id: \"justin-collins-lighting-talk-railsconf-2017\"\n      video_id: \"justin-collins-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Justin Collins\n\n    - title: \"Lightning Talk: Ernesto Tagwerker\" # TODO: missing talk title\n      start_cue: \"19:36\"\n      end_cue: \"20:55\"\n      id: \"ernesto-tagwerker-lighting-talk-railsconf-2017\"\n      video_id: \"ernesto-tagwerker-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Ernesto Tagwerker\n\n    - title: \"Lightning Talk: Chris Sexton\" # TODO: missing talk title\n      start_cue: \"20:55\"\n      end_cue: \"24:07\"\n      id: \"chris-sexton-lighting-talk-railsconf-2017\"\n      video_id: \"chris-sexton-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Sexton\n\n    - title: \"Lightning Talk: Michael Toppa\" # TODO: missing talk title\n      start_cue: \"24:07\"\n      end_cue: \"29:55\"\n      id: \"michael-toppa-lighting-talk-railsconf-2017\"\n      video_id: \"michael-toppa-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Toppa\n\n    - title: \"Lightning Talk: Isaac Sloan\" # TODO: missing talk title\n      start_cue: \"29:55\"\n      end_cue: \"34:39\"\n      id: \"isaac-sloan-lighting-talk-railsconf-2017\"\n      video_id: \"isaac-sloan-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Isaac Sloan\n\n    - title: \"Lightning Talk: Ried Morrison\" # TODO: missing talk title\n      start_cue: \"34:39\"\n      end_cue: \"38:14\"\n      id: \"ried-morrison-lighting-talk-railsconf-2017\"\n      video_id: \"ried-morrison-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Ried Morrison\n\n    - title: \"Lightning Talk: Alejandro Corpeño\" # TODO: missing talk title\n      start_cue: \"38:14\"\n      end_cue: \"43:44\"\n      id: \"alejandro-corpeno-lighting-talk-railsconf-2017\"\n      video_id: \"alejandro-corpeno-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Alejandro Corpeño\n\n    - title: \"Lightning Talk: Michael Hartl\" # TODO: missing talk title\n      start_cue: \"43:44\"\n      end_cue: \"50:09\"\n      id: \"michael-hartl-lighting-talk-railsconf-2017\"\n      video_id: \"michael-hartl-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Hartl\n\n    - title: \"Lightning Talk: Ariel Caplan\" # TODO: missing talk title\n      start_cue: \"50:09\"\n      end_cue: \"55:12\"\n      id: \"ariel-caplan-lighting-talk-railsconf-2017\"\n      video_id: \"ariel-caplan-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Ariel Caplan\n\n    - title: \"Lightning Talk: aws-record\"\n      start_cue: \"55:12\"\n      end_cue: \"58:53\"\n      id: \"alex-wood-lighting-talk-railsconf-2017\"\n      video_id: \"alex-wood-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Alex Wood\n\n    - title: \"Lightning Talk: Waiters in AWS SDK for Ruby\"\n      start_cue: \"58:53\"\n      end_cue: \"01:03:17\"\n      id: \"jingyi-chen-lighting-talk-railsconf-2017\"\n      video_id: \"jingyi-chen-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jingyi Chen\n\n    - title: \"Lightning Talk: Lew Parker\" # TODO: missing talk title\n      start_cue: \"01:03:17\"\n      end_cue: \"01:08:12\"\n      id: \"lew-parker-lighting-talk-railsconf-2017\"\n      video_id: \"lew-parker-lighting-talk-railsconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Lew Parker\n\n- id: \"joe-mastey-railsconf-2017\"\n  title: \"An Optimistic Proposal for Making Horrible Code... Bearable\"\n  raw_title: \"RailsConf 2017: An Optimistic Proposal for Making Horrible Code... Bearable by Joe Mastey\"\n  speakers:\n    - Joe Mastey\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-10\"\n  published_at: \"2017-05-10\"\n  description: |-\n    RailsConf 2017: An Optimistic Proposal for Making Horrible Code... Bearable by Joe Mastey\n\n    The attempted rewrite is over, the dust has settled, and the monolith isn’t going away. After all, it’s still the app that makes all the money. On the other hand, nobody wants to work on it, every new feature takes forever, and your entire team is afraid of making any change for fear of the whole thing collapsing in on itself.\n\n    In this session, we’ll walk through some of the technical and social problems that arise from difficult codebases. We’ll learn to stop making things worse, to measure what we need to change, and start making progress.\n\n    In the thousand mile journey, here are the first steps.\n  video_provider: \"youtube\"\n  video_id: \"hFuzIWz6Ynk\"\n\n- id: \"andrew-hao-railsconf-2017\"\n  title: \"Built to last: A domain-driven approach to beautiful systems\"\n  raw_title: \"RailsConf 2017: Built to last: A domain-driven approach to beautiful systems by Andrew Hao\"\n  speakers:\n    - Andrew Hao\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-10\"\n  published_at: \"2017-05-10\"\n  description: |-\n    RailsConf 2017: Built to last: A domain-driven approach to beautiful systems by Andrew Hao\n\n    Help! Despite following refactoring patterns by the book, your aging codebase is messier than ever. If only you had a key architectural insight to cut through the noise.\n\n    Today, we'll move beyond prescriptive recipes and learn how to run a Context Mapping exercise. This strategic design tool helps you discover domain-specific system boundaries, leading to highly-cohesive and loosely-coupled outcomes. With code samples from real production code, we'll look at a domain-oriented approach to organizing code in a Rails codebase, applying incremental refactoring steps to build stable, lasting systems!\n  video_provider: \"youtube\"\n  video_id: \"52qChRS4M0Y\"\n\n- id: \"taylor-jones-railsconf-2017\"\n  title: \"Architecture: The Next Generation\"\n  raw_title: \"RailsConf 2017: Architecture: The Next Generation by Taylor Jones\"\n  speakers:\n    - Taylor Jones\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-10\"\n  published_at: \"2017-05-10\"\n  description: |-\n    RailsConf 2017: Architecture: The Next Generation by Taylor Jones\n\n    As our applications grow, we start thinking of better ways to organize and scale our growing codebases. We've recently seen Microservices start to emerge as a prominent response to Monoliths, but is it all really worth it? What about our other options? We often romanticize leaving our current architecture situation because we believe it will cure what ails us. However, architecture certainly has no silver bullet . Beam up with me as we explore the past, present, and future of reconsidering architecture.\n  video_provider: \"youtube\"\n  video_id: \"lEVsTVp7UtQ\"\n\n- id: \"christoph-gockel-railsconf-2017\"\n  title: \"Breaking Bad - What Happens When You Defy Conventions?\"\n  raw_title: \"RailsConf 2017: Breaking Bad - What Happens When You Defy Conventions? by Christoph Gockel\"\n  speakers:\n    - Christoph Gockel\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-10\"\n  published_at: \"2017-05-10\"\n  description: |-\n    RailsConf 2017: Breaking Bad - What Happens When You Defy Conventions? by Christoph Gockel\n\n    With Rails being over ten years old now, we know that the Rails way works well. It's battle tested and successful. But not all problems we try to solve fit into its idea on how our application should be structured.\n\n    Come along to find out what happens when you don't want to have an app directory anymore. We will see what is needed in order to fight parts of the Rails convention and if it's worth it.\n  video_provider: \"youtube\"\n  video_id: \"gLHaa5oeyLc\"\n\n- id: \"patrick-joyce-railsconf-2017\"\n  title: \"Managing Unmanageable Complexity\"\n  raw_title: \"RailsConf 2017: Managing Unmanageable Complexity by Patrick Joyce\"\n  speakers:\n    - Patrick Joyce\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-10\"\n  published_at: \"2017-05-10\"\n  description: |-\n    RailsConf 2017: Managing Unmanageable Complexity by Patrick Joyce\n\n    As systems get more complex they inevitably fail. Many of those failures are preventable.\n\n    We’re not lazy, stupid, or careless. The complexity of our systems simply exceeds our cognitive abilities. Thankfully, we’re not alone. People have successfully managed complex systems long before software came along.\n\n    In this session, we’ll see how surgeons, pilots, and builders have developed techniques to safely manage increasingly complex systems in life and death situations. We will learn how simple checklists improve communication, reduce preventable errors, and drive faster recovery time.\n  video_provider: \"youtube\"\n  video_id: \"yVgrNtz7KpA\"\n\n- id: \"aaron-patterson-railsconf-2017\"\n  title: \"Closing Keynote\"\n  raw_title: \"RailsConf 2017: Keynote by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-10\"\n  published_at: \"2017-05-10\"\n  slides_url: \"https://speakerdeck.com/tenderlove/railsconf-2017\"\n  description: |-\n    RailsConf 2017: Keynote by Aaron Patterson\n  video_provider: \"youtube\"\n  video_id: \"GnCJO8Ax1qg\"\n\n- id: \"michael-cain-railsconf-2017\"\n  title: \"Bebop to the Top - The Jazz Band As A Guide To Leadership\"\n  raw_title: \"RailsConf 2017: Bebop to the Top - The Jazz Band As A Guide To Leadership by Michael Cain\"\n  speakers:\n    - Michael Cain\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-12\"\n  published_at: \"2017-05-12\"\n  description: |-\n    RailsConf 2017: Bebop to the Top - The Jazz Band As A Guide To Leadership by Michael Cain\n\n    The ideal workplace, with motivated employees, supportive managers and a clear vision in the \"C-suite\", is where we'd all like to work, isn't it? The question then, is, how do we create it? How do managers walk the fine line of \"micromanaging\" and \"anarchy\"? How can we, as employees, maximize our contribution to our company and love what we do at the same time?\n\n    The secret is in the big band.\n\n    Inspired by Max Dupree's Leadership Jazz, this talk will show you how to apply the principles of improvisation to your company/team and make your workplace more efficient, effective and fun!\n  video_provider: \"youtube\"\n  video_id: \"R0AY4ILjJQo\"\n\n- id: \"jess-rudder-railsconf-2017\"\n  title: \"The Good Bad Bug: Learning to Embrace Mistakes\"\n  raw_title: \"RailsConf 2017: The Good Bad Bug: Learning to Embrace Mistakes by Jess Rudder\"\n  speakers:\n    - Jess Rudder\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-12\"\n  published_at: \"2017-05-12\"\n  description: |-\n    RailsConf 2017: The Good Bad Bug: Learning to Embrace Mistakes by Jess Rudder\n\n    The history of programming is filled with examples of bugs that actually turned out to be features and limitations that pushed developers to make an even more interesting product. We’ll journey through code that was so ‘bad’ it was actually good. Then we’ll learn to tame our inner perfectionists so our code will be even better than it is today.\n  video_provider: \"youtube\"\n  video_id: \"NgGloe7hLBU\"\n\n- id: \"polly-schandorf-railsconf-2017\"\n  title: \"Panel: Developer Happiness through Getting Involved\"\n  raw_title: \"RailsConf 2017: Panel: Developer Happiness through Getting Involved\"\n  speakers:\n    - Polly Schandorf\n    - Sarah Mei\n    - Sean Marcia\n    - Terian Koscik\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-12\"\n  published_at: \"2017-05-12\"\n  description: |-\n    RailsConf 2017: Panel: Developer Happiness through Getting Involved with Polly Schandorf, Sarah Me,  Sean Marcia, &Terian Koscik\n\n    We have amazing skills and abilities, but for a lot of us the missing piece is finding a way to give back. We have an amazing panel of people who have used their skills and talents from both previous careers and current to make the world a better place. Learn how they got involved, and in turn what you can do to get involved in areas you’re passionate about to fill this missing piece that will keep you happy throughout your career.\n  video_provider: \"youtube\"\n  video_id: \"GOSla2Nl0Es\"\n\n- id: \"jameson-hampton-railsconf-2017\"\n  title: \"Understanding ‘Spoon Theory’ and Preventing Burnout\"\n  raw_title: \"RailsConf 2017: Understanding ‘Spoon Theory’ and Preventing Burnout by Jameson Hampton\"\n  speakers:\n    - Jameson Hampton\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-12\"\n  published_at: \"2017-05-12\"\n  description: |-\n    RailsConf 2017: Understanding ‘Spoon Theory’ and Preventing Burnout by Jameson Hampton\n\n    Spoon theory is a metaphor about the finite energy we each have to do things in a day. While a healthy, advantaged person may not have to worry about running out of ‘spoons,’ people with chronic illnesses or disabilities and members of marginalized communities often have to consider how they must ration their energy in order to get through the day. Understanding how 'spoons' can affect the lives of your developers and teammates can help companies lessen the everyday burdens on their underrepresented employees, leaving them more spoons to do their best work, avoid burnout and lead fulfilling lives.\n  video_provider: \"youtube\"\n  video_id: \"rPtUR4kDXeY\"\n\n- id: \"don-werve-railsconf-2017\"\n  title: \"To Code Is Human\"\n  raw_title: \"RailsConf 2017: To Code Is Human by Don Werve\"\n  speakers:\n    - Don Werve\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-12\"\n  published_at: \"2017-05-12\"\n  description: |-\n    RailsConf 2017: To Code Is Human by Don Werve\n\n    Programming is a deeply mental art. As programmers, we invest large amounts of time in mastering new languages, new techniques, and new tools. But all too often, we neglect our understanding of the most important tool in the developer's toolbox: the programmer's brain itself.\n\n    In this talk, we will combine the art of programming with the science of cognitive psychology, and emerge with a deeper understanding of how to leverage the limits of the human mind to sustainably craft software that is less buggy, easier to understand, and more adaptive in the face of change.\n  video_provider: \"youtube\"\n  video_id: \"yc8rYrBABTQ\"\n\n- id: \"cecy-correa-railsconf-2017\"\n  title: \"Panel: Better Hiring Practices for Fun and Profit\"\n  raw_title: \"RailsConf 2017: Panel: Better Hiring Practices for Fun and Profit\"\n  speakers:\n    - Cecy Correa\n    - Pamela O. Vickers\n    - Heather Corallo\n    - Justin Herrick\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-12\"\n  published_at: \"2017-05-12\"\n  description: |-\n    RailsConf 2017: Panel: Better Hiring Practices for Fun and Profit With Cecy Correa, Pamela O. Vickers, Heather Corallo & Justin Herrick\n\n    The average American worker will have 10 jobs before the age of 40. There's a great deal of opportunity and mobility in our industry, and yet, our hiring process is anything but pleasant or streamlined. The hiring process is time consuming for both candidates and employers, but we can do better! Let's explore the ways we can improve the hiring process by writing better job descriptions, utilizing systems that free us from unconscious biases, focusing beyond culture fit, and using better (more fun) technical interviewing methods.\n  video_provider: \"youtube\"\n  video_id: \"nv94h-1n3FY\"\n\n- id: \"hilary-stohs-krause-railsconf-2017\"\n  title: \"We've Always Been Here: Women Changemakers in Tech\"\n  raw_title: \"RailsConf 2017: We've Always Been Here: Women Changemakers in Tech by Hilary Stohs-Krause\"\n  speakers:\n    - Hilary Stohs-Krause\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-12\"\n  published_at: \"2017-05-12\"\n  description: |-\n    RailsConf 2017: We've Always Been Here: Women Changemakers in Tech by Hilary Stohs-Krause\n\n    Steve Jobs. Linus Torvalds. Alan Turing.\n\n    Been there, done that.\n\n    The interesting stories often aren’t the ones we grew up with; they’re the ones we’ve left behind. When it comes to tech, that means its women, and especially its women of color. And while there’s been a greater emphasis lately on rediscovering women’s contributions to technology, we need to expand our focus beyond just Grace Hopper and Ada Lovelace.\n\n    From Radia Perlman to Sophie Wilson to Erica Baker, let's explore both tech’s forgotten heroes and its modern-day pioneers, and help end the silent erasure of women in technology.\n  video_provider: \"youtube\"\n  video_id: \"T3ojRN4CT7I\"\n\n- id: \"scott-lesser-railsconf-2017\"\n  title: \"Leading When You're Not in Charge\"\n  raw_title: \"RailsConf 2017: Leading When You're Not in Charge by Scott Lesser\"\n  speakers:\n    - Scott Lesser\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-12\"\n  published_at: \"2017-05-12\"\n  description: |-\n    RailsConf 2017: Leading When You're Not in Charge by Scott Lesser\n\n    Just because you don't have lead / senior / manager / owner in your title, doesn't mean there isn't plenty of opportunity to lead. No matter where you are in your career, come discover how to communicate more effectively, embrace self-awareness, and influence those leading you. Don't wait for a title to tell you to lead. Take responsibility where you are, and let the titles come to you.\n  video_provider: \"youtube\"\n  video_id: \"m-WDmNoQmkg\"\n\n- id: \"shay-howe-railsconf-2017\"\n  title: \"Panel: Becoming an engineering leader\"\n  raw_title: \"RailsConf 2017: Panel: Becoming an engineering leader\"\n  speakers:\n    - Shay Howe\n    - Rebecca Miller-Webster\n    - Neha Batra\n    - Abel Martin\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-15\"\n  published_at: \"2017-05-15\"\n  description: |-\n    RailsConf 2017: Panel: Becoming an engineering leader with Shay Howe, Rebecca Miller-Webster, Neha Batra & Abel Martin\n\n    Are you a new manager? Have you been asked to lead a project? Do you want to see change in your company but don't feel you have the position to enact it? Are you terrified or nervous or unsure where to start? Has a recent situation left you questioning what you did wrong and how to be a better leader?\n\n    Software development doesn't prepare us for taking on everyday or official leadership and yet, leadership is what every team and company desperately need.\n\n    Let talk with a group of folks at various stages of the leadership hierarchy about what they have and want to learn.\n  video_provider: \"youtube\"\n  video_id: \"3wzCTUdaiwg\"\n\n- id: \"christopher-sexton-railsconf-2017\"\n  title: \"Panel: Ruby's Killer Feature: The Community\"\n  raw_title: \"RailsConf 2017: Panel: Ruby's Killer Feature: The Community\"\n  speakers:\n    - Christopher Sexton\n    - Sean Marcia\n    - Latoya Allen\n    - Zuri Hunter\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-15\"\n  published_at: \"2017-05-15\"\n  description: |-\n    RailsConf 2017: Panel: Ruby's Killer Feature: The Community with Christopher Sexton, Sean Marcia, Latoya Allen, & Zuri Hunter\n\n    What makes Ruby so wonderful? The Community.\n\n    The community around Ruby is really what sets it apart, and the cornerstone of it is the small local meetups. Come learn how to get involved, help out, or step up and start a local group of your own. We will discuss how to develop and nurture the group. Share our experiences in expanding a small group to larger events like unconferences or workshops. Find out how community leaders can help everyone build a solid network, assist newbies in kick-starting their career, and most importantly ensure that everyone feels welcome and safe.\n  video_provider: \"youtube\"\n  video_id: \"6w_cSs9weWw\"\n\n- id: \"thijs-cadier-railsconf-2017\"\n  title: \"Processing Streaming Data at a Large Scale with Kafka\"\n  raw_title: \"RailsConf 2017: Processing Streaming Data at a Large Scale with Kafka by Thijs Cadier\"\n  speakers:\n    - Thijs Cadier\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-15\"\n  published_at: \"2017-05-15\"\n  description: |-\n    RailsConf 2017: Processing Streaming Data at a Large Scale with Kafka by Thijs Cadier\n\n    Using a standard Rails stack is great, but when you want to process streams of data at a large scale you'll hit the stack's limitations. What if you want to build an analytics system on a global scale and want to stay within the Ruby world you know and love?\n\n    In this talk we'll see how we can leverage Kafka to build and painlessly scale an analytics pipeline. We'll talk about Kafka's unique properties that make this possible, and we'll go through a full demo application step by step. At the end of the talk you'll have a good idea of when and how to get started with Kafka yourself.\n  video_provider: \"youtube\"\n  video_id: \"-NMDqqW1uCE\"\n\n- id: \"braulio-carreno-railsconf-2017\"\n  title: \"High Performance Political Revolutions\"\n  raw_title: \"RailsConf 2017: High Performance Political Revolutions by Braulio Carreno\"\n  speakers:\n    - Braulio Carreno\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-15\"\n  published_at: \"2017-05-15\"\n  description: |-\n    RailsConf 2017: High Performance Political Revolutions by Braulio Carreno\n\n    Bernie Sanders popularized crowdfunding in politics by raising $220 million in small donations.\n\n    An example of the challenges with handling a high volume of donations is the 2016 New Hampshire primary night, when Sanders asked a national TV audience to donate $27. Traffic peaked at 300K requests/min and 42 credit card transactions/sec.\n\n    ActBlue is the company behind the service used not only by Sanders, but also 16,600 other political organizations and charities for the past 12 years.\n\n    This presentation is about the lessons we learned building a high performance fundraising platform in Rails.\n  video_provider: \"youtube\"\n  video_id: \"fMcSPXMt0o0\"\n\n- id: \"sam-saffron-railsconf-2017\"\n  title: \"Panel: Performance... performance\"\n  raw_title: \"RailsConf 2017: Panel: Performance... performance\"\n  speakers:\n    - Sam Saffron\n    - Richard Schneeman\n    - Eileen M. Uchitelle\n    - Nate Berkopec\n    - Rafael Mendonça França\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-15\"\n  published_at: \"2017-05-15\"\n  description: |-\n    RailsConf 2017: Panel: Performance... performance with Sam Saffron, Richard Schneeman, Eileen M. Uchitelle, Nate Berkopec & Rafael Mendonça França\n\n    Is your application running too slow? How can you make it run leaner and faster? Is Ruby 2.4 going to make anything faster or better? Should you be upgrading to the latest version of Rails? Is your Rails application being weighed down by a large swarm of dependencies?\n\n    In this panel the panelists will discuss their favorite performance related tools and guidelines. Expect to learn about changes in Ruby 2.4 and beyond that may help make your applications snappy and lean.\n  video_provider: \"youtube\"\n  video_id: \"SMxlblLe_Io\"\n\n- id: \"colin-fleming-railsconf-2017\"\n  title: \"It's Dangerous to go Alone: Building Teams like an Organizer\"\n  raw_title: \"RailsConf 2017: Its Dangerous to go Alone: Building Teams like an Organizer by Colin Fleming\"\n  speakers:\n    - Colin Fleming\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-15\"\n  published_at: \"2017-05-15\"\n  description: |-\n    RailsConf 2017: It's Dangerous to go Alone: Building Teams like an Organizer by Colin Fleming\n\n    Leading an open source or community project means dealing with people challenges in addition to technical challenges -- how do we take a scattering of interested people and build a team with them? Turns out, we can adapt a bunch of practices we already use! Using a collaboration between a nonprofit and a civic group as a case study, we'll talk about ways to apply best practices from community organizers to our work. In particular, we'll talk about similarities between contemporary organizing and agile models, ways to build relationships with other team members, and making our work more sustainable.\n  video_provider: \"youtube\"\n  video_id: \"T3gEORIjKQo\"\n\n- id: \"jesse-james-railsconf-2017\"\n  title: \"Supporting Mental Health as an Effective Leader\"\n  raw_title: \"RailsConf 2017: Supporting Mental Health as an Effective Leader by Jesse James\"\n  speakers:\n    - Jesse James\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-15\"\n  published_at: \"2017-05-15\"\n  description: |-\n    RailsConf 2017: Supporting Mental Health as an Effective Leader by Jesse James\n\n    As the stigma of speaking out about mental health conditions declines, leaders in the programming community are are being given many new opportunities to support their teams. In this session you will learn about the issues some of your team may face both in dealing with their own potential mental health difficulties and that of other team members. We will go over ways to support both the individual and team, how to advocate for team members with mental health conditions, and resources for further information and outreach for you and your team.\n  video_provider: \"youtube\"\n  video_id: \"UR-J7O5ZJ4Q\"\n\n- id: \"jonan-scheffler-railsconf-2017\"\n  title: \"Inventing Friends: ActionCable + AVS = 3\"\n  raw_title: \"RailsConf 2017: Inventing Friends: ActionCable + AVS = 3 by Jonan  Scheffler & Julian Cheal\"\n  speakers:\n    - Jonan Scheffler\n    - Julian Cheal\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-16\"\n  published_at: \"2017-05-16\"\n  description: |-\n    RailsConf 2017: Inventing Friends: ActionCable + AVS = 3 by Jonan  Scheffler & Julian Cheal\n\n    Chatbots, ActionCable, A.I. and you. And many more buzzwords will enthral you in this talk.\n\n    We'll learn how to create a simple chatroom in Rails using ActionCable, then how to talk to your colleagues in the office or remote locations using text to speech and Amazon Voice Service.\n\n    Using the power of ActionCable we will explore how its possible to create an MMMOC: massively multiplayer online chatroom, that you can use TODAY to see your; Travis Build status, or deploy code to your favourite PAAS, let you know when the latest release of Rails is out. Using nothing but your voice and ActionCable.\n  video_provider: \"youtube\"\n  video_id: \"7sqYy8G0Hrg\"\n\n- id: \"marco-rogers-railsconf-2017\"\n  title: \"Keynote\"\n  raw_title: \"RailsConf 2017: Keynote by Marco Rogers\"\n  speakers:\n    - Marco Rogers\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-16\"\n  published_at: \"2017-05-16\"\n  description: |-\n    RailsConf 2017: Keynote by Marco Rogers\n  video_provider: \"youtube\"\n  video_id: \"g6fBRwi6cqc\"\n\n- id: \"richard-schneeman-railsconf-2017\"\n  title: \"Bayes is BAE\"\n  raw_title: \"RailsConf 2017: Bayes is BAE by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-16\"\n  published_at: \"2017-05-16\"\n  description: |-\n    RailsConf 2017: Bayes is BAE by Richard Schneeman\n\n    Before programming, before formal probability there was Bayes. He introduced the notion that multiple uncertain estimates which are related could be combined to form a more certain estimate. It turns out that this extremely simple idea has a profound impact on how we write programs and how we can think about life. The applications range from machine learning and robotics to determining cancer treatments. In this talk we'll take an in depth look at Bayses rule and how it can be applied to solve problems in programming and beyond.\n  video_provider: \"youtube\"\n  video_id: \"bQSzZrDDV80\"\n\n- id: \"matthew-mongeau-railsconf-2017\"\n  title: \"Is it Food? An Introduction to Machine Learning\"\n  raw_title: \"RailsConf 2017: Is it Food? An Introduction to Machine Learning by Matthew Mongeau\"\n  speakers:\n    - Matthew Mongeau\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-16\"\n  published_at: \"2017-05-16\"\n  description: |-\n    RailsConf 2017: Is it Food? An Introduction to Machine Learning by Matthew Mongeau\n\n    Machine Learning is no longer just an academic study. Tools like Tensorflow have opened new doorways in the world of application development. Learn about the current tools available and how easy it is to integrate them into your rails application. We'll start by looking at a real-world example currently being used in the wild and then delve into creating a sample application that utilizes machine learning.\n  video_provider: \"youtube\"\n  video_id: \"8G709hKkthY\"\n\n- id: \"katie-walsh-railsconf-2017\"\n  title: \"Accessibility (when you don't have time to read the manual)\"\n  raw_title: \"RailsConf 2017: Accessibility (when you don't have time to read the manual) by Katie Walsh\"\n  speakers:\n    - Katie Walsh\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-16\"\n  published_at: \"2017-05-16\"\n  description: |-\n    RailsConf 2017: Accessibility (when you don't have time to read the manual) by Katie Walsh\n\n    For some, making web applications accessible is a must; Government websites fall under Section 508 and retail sites need to reduce legal risk.\n\n    But for others it seems like a luxury; Consultants are expensive, and so are the developer hours spent trying to parse the notoriously hard-to-read WCAG 2.0 docs.\n\n    There is an easier way to start!\n\n    In this session, we will demystify the WCAG 2.0 basics. We’ll use Chrome Accessibility Dev Tools to discover and fix common issues. You will leave with a set of free and easy-to-use resources to start improving the accessibility of your application today.\n  video_provider: \"youtube\"\n  video_id: \"5PTCbwzhwug\"\n\n- id: \"vaidehi-joshi-railsconf-2017\"\n  title: \"Goldilocks And The Three Code Reviews\"\n  raw_title: \"RailsConf 2017: Goldilocks And The Three Code Reviews by Vaidehi Joshi\"\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-16\"\n  published_at: \"2017-05-16\"\n  description: |-\n    RailsConf 2017: Goldilocks And The Three Code Reviews by Vaidehi Joshi\n\n    Once upon a time, Goldilocks had a couple extra minutes to spare before morning standup. She logged into Github and saw that there were three pull requests waiting for her to review.\n\n    We've probably all heard that peer code reviews can do wonders to a codebase. But not all type of code reviews are effective. Some of them seem to go on and on forever, while others pick at syntax and formatting but miss bugs. This talk explores what makes a strong code review and what makes a painful one. Join Goldilocks as she seeks to find a code review process that's neither too long nor too short, but just right!\n  video_provider: \"youtube\"\n  video_id: \"-6EzycFNwzY\"\n\n- id: \"ju-liu-railsconf-2017\"\n  title: \"Predicting Titanic Survivors with Machine Learning\"\n  raw_title: \"RailsConf 2017: Predicting Titanic Survivors with Machine Learning by Ju Liu\"\n  speakers:\n    - Ju Liu\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-16\"\n  published_at: \"2017-05-16\"\n  description: |-\n    RailsConf 2017: Predicting Titanic Survivors with Machine Learning by Ju Liu\n\n    What's a better way to understand machine learning than a practical example? And who hasn't watched the 1997 classic with Jack and Rose? In this talk we will first take a look at some real historical data of the event. Then we will use amazing Python libraries to live code several of the most well known algorithms. This will help us understand some fundamental concepts of how machine learning works. When we're done, you should have a good mental framework to make sense of it in the modern world.\n  video_provider: \"youtube\"\n  video_id: \"4l-aB_Sk41Y\"\n\n- id: \"dave-tapley-railsconf-2017\"\n  title: \"Whose turn is it anyway? Augmented reality board games.\"\n  raw_title: \"RailsConf 2017: Whose turn is it anyway? Augmented reality board games. by Dave Tapley\"\n  speakers:\n    - Dave Tapley\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-16\"\n  published_at: \"2017-05-16\"\n  description: |-\n    RailsConf 2017: Whose turn is it anyway? Augmented reality board games. by Dave Tapley\n\n    Board games are great, but who has time to keep track of what's going on when you just want to have fun? In the spirit of over-engineering we'll look at PitchCar -- probably one of the simplest games in the world -- and see how far we can go with web tech, image processing, and a bunch of math. Expect to see plenty of code, some surprising problems and solutions, and of course: A live demo.\n  video_provider: \"youtube\"\n  video_id: \"01CFyu3SuIo\"\n\n- id: \"simon-eskildsen-railsconf-2017\"\n  title: \"5 Years of Rails Scaling to 80k RPS\"\n  raw_title: \"RailsConf 2017: 5 Years of Rails Scaling to 80k RPS by Simon Eskildsen\"\n  speakers:\n    - Simon Eskildsen\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-17\"\n  published_at: \"2017-05-17\"\n  description: |-\n    RailsConf 2017: 5 Years of Rails Scaling to 80k RPS by Simon Eskildsen\n\n    Shopify has taken Rails through some of the world's largest sales: Superbowl, Celebrity Launches, and Black Friday. In this talk, we will go through the evolution of the Shopify infrastructure: from re-architecting and caching in 2012, sharding in 2013, and reducing the blast radius of every point of failure in 2014. To 2016, where we accomplished running our 325,000+ stores out of multiple datacenters. It'll be whirlwind tour of the lessons learned scaling one of the world's largest Rails deployments for half a decade.\n  video_provider: \"youtube\"\n  video_id: \"4dWJahMi5NI\"\n\n- id: \"pamela-pavliscak-railsconf-2017\"\n  title: \"Keynote: Gen Z and the Future of Technology\"\n  raw_title: \"RailsConf 2017: Keynote: Gen Z and the Future of Technology by Pamela Pavliscak\"\n  speakers:\n    - Pamela Pavliscak\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-17\"\n  published_at: \"2017-05-17\"\n  description: |-\n    RailsConf 2017: Keynote: Gen Z and the Future of Technology by Pamela Pavliscak\n  video_provider: \"youtube\"\n  video_id: \"iN1nOTQgmCY\"\n\n- id: \"aja-hammerly-railsconf-2017\"\n  title: \"Syntax Isn't Everything: NLP for Rubyists\"\n  raw_title: \"RailsConf 2017: Syntax Isn't Everything: NLP for Rubyists by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-17\"\n  published_at: \"2017-05-17\"\n  slides_url: \"https://thagomizer.com/files/NLP_RailsConf2017.pdf\"\n  description: |-\n    RailsConf 2017: Syntax Isn't Everything: NLP for Rubyists by Aja Hammerly\n\n    Natural Language Processing is an interesting field of computing. The way humans use language is nuanced and deeply context sensitive. For example, the word work can be both a noun and a verb. This talk will give an introduction to the field of NLP using Ruby. There will be demonstrations of how computers fail and succeed at human language. You'll leave the presentation with an understanding of both the challenges and the possibilities of NLP and some tools for getting started with it.\n  video_provider: \"youtube\"\n  video_id: \"Mmn20irnaS8\"\n\n- id: \"john-backus-railsconf-2017\"\n  title: \"How to Write Better Code Using Mutation Testing\"\n  raw_title: \"RailsConf 2017: How to Write Better Code Using Mutation Testing by John Backus\"\n  speakers:\n    - John Backus\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-17\"\n  published_at: \"2017-05-17\"\n  description: |-\n    RailsConf 2017: How to Write Better Code Using Mutation Testing by John Backus\n\n    Mutation testing is a silver bullet for assessing test quality. Mutation testing will help you:\n\n    Write better tests\n    Produce more robust code that better handles edge cases\n    Reveal what parts of your legacy application are most likely to break before you dive in to make new changes\n    Learn about features in Ruby and your dependencies that you didn’t previously know about\n    This talk assumes a basic knowledge of Ruby and testing. The examples in this talk will almost certainly teach you something new about Ruby!\n  video_provider: \"youtube\"\n  video_id: \"uB7m9T7ymn8\"\n\n- id: \"glenn-vanderburg-railsconf-2017\"\n  title: \"A Clear-Eyed Look at Distributed Teams\"\n  raw_title: \"RailsConf 2017: A Clear-Eyed Look at Distributed Teams by Glenn Vanderburg & Maria Gutierrez\"\n  speakers:\n    - Glenn Vanderburg\n    - Maria Gutierrez\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-17\"\n  published_at: \"2017-05-17\"\n  description: |-\n    RailsConf 2017: A Clear-Eyed Look at Distributed Teams by Glenn Vanderburg & Maria Gutierrez\n\n    Distributed teams can have big benefits for both employers and employees. But there are many challenges. Being successful requires changes to work practices, communication, and style — and not just from the remote people. Everyone will experience changes. It helps to be prepared … and most of what we see being written and discussed is focused on remote workers, not the organization that supports them.\n\n    In this talk, we will look at the challenges and rewards of working in a distributed team setting based on several years of experience growing large distributed engineering teams.\n  video_provider: \"youtube\"\n  video_id: \"h8MLXbdOyNs\"\n\n- id: \"ben-klang-railsconf-2017\"\n  title: \"Distributed & Local: Getting the Best of Both Worlds\"\n  raw_title: \"RailsConf 2017: Distributed & Local: Getting the Best of Both Worlds by Ben Klang\"\n  speakers:\n    - Ben Klang\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-17\"\n  published_at: \"2017-05-17\"\n  description: |-\n    RailsConf 2017: Distributed & Local: Getting the Best of Both Worlds by Ben Klang\n\n    Our company is traditional in many ways, one of which being the need to come into the office each day. Our team of software developers bucks that trend, spreading across 6 states and 4 countries. Dev teams consider themselves \"Remote First\", while DevOps and Application Support are \"Local First.\" Each has adopted tools, habits, and practices to maximize their configuration. Each style has learned valuable lessons from the other. This presentation is about how our teams have evolved: the tools, the compromises, the wins and losses, and how we successfully blend Distributed and Concentrated teams.\n  video_provider: \"youtube\"\n  video_id: \"BdH8znxkNjI\"\n\n- id: \"david-copeland-railsconf-2017\"\n  title: \"The Effective Remote Developer\"\n  raw_title: \"RailsConf 2017: The Effective Remote Developer by David Copeland\"\n  speakers:\n    - David Copeland\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-17\"\n  published_at: \"2017-05-17\"\n  description: |-\n    RailsConf 2017: The Effective Remote Developer by David Copeland\n\n    Being on a distributed team, working from your home or coffee shop isn't easy, but it can be incredibly rewarding. Making it work requires constant attention, as well as support from your team and organization. It's more than just setting up Slack and buying a webcam.\n\n    We'll learn what you can do to be your best self as a remote team member, as well as what you need from your environment, team, and company. It's not about technical stuff—it's the human stuff. We'll learn how can you be present and effective when you aren't physically there.\n  video_provider: \"youtube\"\n  video_id: \"zW7_AteiM4o\"\n  slides_url: \"https://speakerdeck.com/davetron5000/the-effective-remote-developer\"\n\n- id: \"stella-cotton-railsconf-2017\"\n  title: \"Distributed Tracing: From Theory to Practice\"\n  raw_title: \"RailsConf 2017: Distributed Tracing: From Theory to Practice by Stella Cotton\"\n  speakers:\n    - Stella Cotton\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-17\"\n  published_at: \"2017-05-17\"\n  description: |-\n    RailsConf 2017: Distributed Tracing: From Theory to Practice by Stella Cotton\n\n    Application performance monitoring is great for debugging inside a single app. However, as a system expands into multiple services, how can you understand the health of the system as a whole? Distributed tracing can help! You’ll learn the theory behind how distributed tracing works. But we’ll also dive into other practical considerations you won’t get from a README, like choosing libraries for Ruby apps and polyglot systems, infrastructure considerations, and security.\n  video_provider: \"youtube\"\n  video_id: \"-7i02Faw_KU\"\n\n- id: \"caleb-hearth-railsconf-2017\"\n  title: \"Sorting Rubyists\"\n  raw_title: \"RailsConf 2017: Sorting Rubyists by Caleb Thompson\"\n  speakers:\n    - Caleb Hearth\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-18\"\n  published_at: \"2017-05-18\"\n  description: |-\n    RailsConf 2017: Sorting Rubyists by Caleb Thompson\n\n    Let's take a peek under the hood of the magical \"sort\" method, learning algorithms... by sorting audience members wearing numbers! Intimidated by the word \"algorithm? Not sure what performance means? Confused by \"Big O Notation\"? Haven't even heard of best-, worst-, and average-case time complexities? No problem: we'll learn together! You can expect to come out knowing new things and with Benny Hill stuck in your head.\n  video_provider: \"youtube\"\n  video_id: \"KWoEt64UG_A\"\n\n- id: \"david-padilla-railsconf-2017\"\n  title: \"Tricks and treats for new developers\"\n  raw_title: \"RailsConf 2017: Tricks and treats for new developers by David Padilla\"\n  speakers:\n    - David Padilla\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-18\"\n  published_at: \"2017-05-18\"\n  description: |-\n    RailsConf 2017: Tricks and treats for new developers by David Padilla\n\n    Are you ready to begin building applications with Ruby on Rails? It's very easy to follow a tutorial and learn how to build a blog in 15 minutes, but there's a lot more to it in real life when you try to code a big web app.\n\n    During this talk I will give you a bunch of tips and tricks for Rails development that almost everyone follows but rarely anyone talks about.\n\n    If you are about to join this fantastic community, this talk is for you.\n  video_provider: \"youtube\"\n  video_id: \"BZbW8FAvf00\"\n\n- id: \"jason-clark-railsconf-2017\"\n  title: \"Rack ‘em, Stack ‘em Web Apps\"\n  raw_title: \"RailsConf 2017: Rack ‘em, Stack ‘em Web Apps by Jason Clark\"\n  speakers:\n    - Jason Clark\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-18\"\n  published_at: \"2017-05-18\"\n  description: |-\n    RailsConf 2017: Rack ‘em, Stack ‘em Web Apps by Jason Clark\n\n    While Rails is the most common Ruby web framework, it’s not the only option. Rack is a simple, elegant HTTP library, ideal for microservices and high performance applications.\n\n    In this talk, you’ll see Rack from top to bottom. Starting from the simplest app, we’ll grow our code into a RESTful HTTP API. We’ll test our code, write reusable middleware, and dig through what Rack provides out of the box. Throughout, we’ll balance when Rack is a good fit, and when larger tools are needed.\n\n    If you’ve heard of Rack but wondered where it fits in the Ruby web stack, here’s your chance!\n  video_provider: \"youtube\"\n  video_id: \"3PnUV9QzB0g\"\n\n- id: \"kevin-newton-railsconf-2017\"\n  title: \"Practical Debugging\"\n  raw_title: \"RailsConf 2017: Practical Debugging by Kevin Deisz\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-18\"\n  published_at: \"2017-05-18\"\n  description: |-\n    RailsConf 2017: Practical Debugging by Kevin Newton\n\n    People give ruby a bad reputation for speed, efficiency, weak typing, etc. But one of the biggest benefits of an interpreted language is the ability to debug and introspect quickly without compilation. Oftentimes developers reach for heavy-handed libraries to debug their application when they could just as easily get the information they need by using tools they already have.\n\n    In this talk you will learn practical techniques to make debugging easier. You will see how simple techniques from the ruby standard library can greatly increase your ability to keep your codebase clean and bug-free.\n  video_provider: \"youtube\"\n  video_id: \"oi4h30chCz8\"\n\n- id: \"derek-prior-railsconf-2017\"\n  title: \"In Relentless Pursuit of REST\"\n  raw_title: \"RailsConf 2017: In Relentless Pursuit of REST by Derek Prior\"\n  speakers:\n    - Derek Prior\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-18\"\n  published_at: \"2017-05-18\"\n  description: |-\n    RailsConf 2017: In Relentless Pursuit of REST by Derek Prior\n\n    \"That's not very RESTful.\" As a Rails developer you've probably heard or even spoken that proclamation before, but what does it really mean? What's so great about being RESTful anyway?\n\n    RESTful architecture can narrow the responsibilities of your Rails controllers and make follow-on refactorings more natural. In this talk, you'll learn to refactor code to follow RESTful principles and to identify the positive impact those changes have throughout your application stack.\n  video_provider: \"youtube\"\n  video_id: \"HctYHe-YjnE\"\n\n- id: \"daniel-azuma-railsconf-2017\"\n  title: \"What’s my App *Really* Doing in Production?\"\n  raw_title: \"RailsConf 2017: What’s my App *Really* Doing in Production? by Daniel Azuma\"\n  speakers:\n    - Daniel Azuma\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-18\"\n  published_at: \"2017-05-18\"\n  description: |-\n    RailsConf 2017: What’s my App *Really* Doing in Production? by Daniel Azuma\n\n    When your Rails app begins serving public traffic, your users will make it behave in mysterious ways and find code paths you never knew existed. Understanding, measuring, and troubleshooting its behavior in production is a tough but crucial part of running a successful Rails app. In this talk, you’ll learn how to instrument, debug, and profile your app, using the capabilities of the Rails framework and the Ruby VM. You'll also study techniques for safely instrumenting a live running system, keeping latency to a minimum and avoiding side effects.\n  video_provider: \"youtube\"\n  video_id: \"92CoJhv3tPU\"\n\n- id: \"amy-unger-railsconf-2017\"\n  title: \"Beyond validates_presence_of: Ensuring Eventual Consistency\"\n  raw_title: \"RailsConf 2017: Beyond Validates_Presence_of: Ensuring Eventual Consistency by Amy Unger\"\n  speakers:\n    - Amy Unger\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: Beyond Validates_Presence_of: Ensuring Eventual Consistency by Amy Unger\n\n    You've added background jobs. You have calls to external services that perform actions asynchronously. Your data is no longer always in one perfect state-- it's in one of tens or hundreds of acceptable states.\n\n    How can you confidently ensure that your data is valid without validations?\n\n    In this talk, I’ll introduce some data consistency issues you may see in your app when you begin introducing background jobs and external services. You’ll learn some patterns for handling failure so your data never gets out of sync and we’ll talk about strategies to detect when something is wrong.\n  video_provider: \"youtube\"\n  video_id: \"QpbQpwXhrSI\"\n\n- id: \"bryana-knight-railsconf-2017\"\n  title: \"The Secret Life of SQL: How to Optimize Database Performance\"\n  raw_title: \"RailsConf 2017: The Secret Life of SQL: How to Optimize Database Performance by Bryana Knight\"\n  speakers:\n    - Bryana Knight\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: The Secret Life of SQL: How to Optimize Database Performance by Bryana Knight\n\n    There are a lot of database index and query best practices that sometimes aren't best practices at all. Need all users created this year? No problem! Slap an index over created_at! What about this year's active OR pending users, sorted by username? Are we still covered index-wise? Is the query as fast with 20 million users? Common rules of thumb for indexing and query crafting aren’t black and white. We'll discuss how to track down these exceptional cases and walk through some real examples. You'll leave so well equipped to improve performance, you won't be able to optimize fast enough!\n  video_provider: \"youtube\"\n  video_id: \"BuDWWadCqIw\"\n\n- id: \"tony-drake-railsconf-2017\"\n  title: \"Reporting on Rails - ActiveRecord and ROLAP Working Together\"\n  raw_title: \"RailsConf 2017: Reporting on Rails - ActiveRecord and ROLAP Working Together by Tony Drake\"\n  speakers:\n    - Tony Drake\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: Reporting on Rails - ActiveRecord and ROLAP Working Together by Tony Drake\n\n    It'll happen eventually. Someone will come down with a feature request for your app to \"create dashboards and reporting on our data\". So how do you go about doing it? What parts of your database should you start thinking about differently? What is \"reporting\" anyway? Is ActiveRecord enough to pull this off?\n\n    Let's go on a journey through the world of Relational Online Analytical Processing (ROLAP) and see how this can apply to Rails. We'll also look at database considerations and finish with looking at a light DSL that works with ActiveRecord to help make your data dance.\n  video_provider: \"youtube\"\n  video_id: \"MczzCfTQGfU\"\n\n- id: \"jason-charnes-railsconf-2017\"\n  title: \"Do Your Views Know Too Much?\"\n  raw_title: \"RailsConf 2017: Do Your Views Know Too Much? by Jason Charnes\"\n  speakers:\n    - Jason Charnes\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: Do Your Views Know Too Much? by Jason Charnes\n\n    The logical place to put view-related logic is... inside your view, right? \"A little logic here... a little logic there...\" but all of a sudden we hardly recognize our views. A quick glance through our code and we can't tell our Ruby apart from our HTML. Don't worry; this is a fun opportunity for some refactoring! Come see several approaches you can start using today to clean up your views.\n  video_provider: \"youtube\"\n  video_id: \"9Hq9kL9pXuI\"\n\n- id: \"lance-ivy-railsconf-2017\"\n  title: \"Portable Sessions with JSON Web Tokens\"\n  raw_title: \"RailsConf 2017: Portable Sessions with JSON Web Tokens by Lance Ivy\"\n  speakers:\n    - Lance Ivy\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: Portable Sessions with JSON Web Tokens by Lance Ivy\n\n    Ever wonder why applications use sessions and APIs use tokens? Must there really be a difference? JSON Web Tokens are an emerging standard for portable secure messages. We'll talk briefly about how they're built and how they earn your trust, then dig into some practical examples you can take back and apply to your own majestic monolith or serious services.\n  video_provider: \"youtube\"\n  video_id: \"s7G2VnuMVEw\"\n\n- id: \"jake-worth-railsconf-2017\"\n  title: \"Observing Chance: A Gold Master Test in Practice\"\n  raw_title: \"RailsConf 2017: Observing Chance: A Gold Master Test in Practice by Jake Worth\"\n  speakers:\n    - Jake Worth\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: Observing Chance: A Gold Master Test in Practice by Jake Worth\n\n    Tests try to observe change. But are some systems too big to observe them all? What if we need to test a function with a very complex output?\n\n    In this talk, we'll explore a Gold Master test– a special test for evaluating complicated legacy systems. We'll look at how this test takes an input, such as a production database, runs it through a transformative function, and then compares the output to an approved version of the output.\n\n    Testers of every experience level will leave this talk with a new technique for evaluating complex environments, and a broader conception of what a test can be.\n  video_provider: \"youtube\"\n  video_id: \"D9awDBUQvr4\"\n\n- id: \"ariel-caplan-railsconf-2017\"\n  title: \"What Comes After SOLID? Seeking Holistic Software Quality\"\n  raw_title: \"RailsConf 2017: What Comes After SOLID? Seeking Holistic Software Quality by Ariel Caplan\"\n  speakers:\n    - Ariel Caplan\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: What Comes After SOLID? Seeking Holistic Software Quality by Ariel Caplan\n\n    You care deeply about code quality and constantly strive to learn more. You devour books and blogs, watch conference talks, and practice code katas.\n\n    That's excellent! But immaculately factored code and clean architecture alone won't guarantee quality software.\n\n    As a developer, your job isn't to write Good Code. It's to deliver value for people. In that light, we'll examine the effects of a host of popular coding practices. What do they accomplish? Where do they fall short?\n\n    We'll set meaningful goals for well-rounded, high-quality software that solves important problems for real people.\n  video_provider: \"youtube\"\n  video_id: \"5wYcD1nfnWw\"\n\n- id: \"kevin-yank-railsconf-2017\"\n  title: \"Developer Happiness on the Front End with Elm\"\n  raw_title: \"RailsConf 2017: Developer Happiness on the Front End with Elm by Kevin Yank\"\n  speakers:\n    - Kevin Yank\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: Developer Happiness on the Front End with Elm by Kevin Yank\n\n    Ruby and Rails famously prioritised developer happiness, and took the world by storm. Elm, a new language that compiles to JavaScript, proves that putting developer happiness first can produce very different results on the front end! Born out of Haskell, Elm is as unlike Ruby as programming languages get, but in this session we’ll see how its particular blend of design decisions tackles everything that’s painful about front-end development, making it an excellent choice for the curious Rubyist’s next favorite language.\n  video_provider: \"youtube\"\n  video_id: \"C2npla7DwVk\"\n\n- id: \"christian-koch-railsconf-2017\"\n  title: \"Rails to Phoenix: How Elixir can level-you-up in Rails\"\n  raw_title: \"RailsConf 2017: Rails to Phoenix: How Elixir can level-you-up in Rails by Christian Koch\"\n  speakers:\n    - Christian Koch\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: Rails to Phoenix: How Elixir can level-you-up in Rails by Christian Koch\n\n    Elixir has rapidly developed into a mature language with an ever-growing library of packages that excels at running web apps. And because both Elixir and Phoenix were developed by Ruby / Rails programmers, the ease with which you can learn Elixir as a Ruby developer, is much greater than many other languages. With numerous code examples, this talk will discuss how learning a functional approach to handling web requests can improve what we do every day with Rails. This talk is aimed at people who have some familiarity with Rails but no experience with Elixir is necessary.\n  video_provider: \"youtube\"\n  video_id: \"fjrD0_OempI\"\n\n- id: \"jo-cranford-railsconf-2017\"\n  title: \"React on Rails\"\n  raw_title: \"RailsConf 2017: React on Rails by Jo Cranford\"\n  speakers:\n    - Jo Cranford\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: React on Rails by Jo Cranford\n\n    Eighteen months ago, our fairly typical Ruby on Rails app had some mundane client side interactions managed by a tangle of untested JQuery spaghetti.\n\n    Today, new features are built with React, CSS modules, and a far better UX. With ES6 front end code, processed with Babel, compiled (and hot-reloaded in development) with Webpack, and tested with Jest – all within the same Rails application.\n\n    Come along to this talk to hear how we migrated our app a piece at a time to use technologies that don’t always sit naturally alongside Rails. I will cover technical implementations and lessons learned.\n  video_provider: \"youtube\"\n  video_id: \"GW9qgIYfzEI\"\n\n- id: \"ben-dixon-railsconf-2017\"\n  title: \"React Native & Rails, A Single Codebase for Web & Mobile\"\n  raw_title: \"RailsConf 2017: React Native & Rails, A Single Codebase for Web & Mobile by Ben Dixon\"\n  speakers:\n    - Ben Dixon\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: React Native & Rails, A Single Codebase for Web & Mobile by Ben Dixon\n\n    Rails made building CRUD apps efficient and fun. React Native, for the first time, does this for mobile Apps. Learn how to create a single React codebase for Android, iOS and Mobile Web, backed by a common Rails API.\n  video_provider: \"youtube\"\n  video_id: \"Q66tYU6ni48\"\n\n- id: \"alex-boster-railsconf-2017\"\n  title: \"A Survey of Surprisingly Difficult Things\"\n  raw_title: \"RailsConf 2017: A Survey of Surprisingly Difficult Things by Alex Boster\"\n  speakers:\n    - Alex Boster\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-19\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RailsConf 2017: A Survey of Surprisingly Difficult Things by Alex Boster\n\n    Many seemingly simple \"real-world\" things end up being much more complicated than anticipated, especially if it's a developer's first time dealing with that particular thing. Classic examples include money and currency, time, addresses, human names, and so on. We will survey a number of these common areas and the state of best practices, or lack thereof, for handling them in Rails.\n  video_provider: \"youtube\"\n  video_id: \"aUk9981C-fQ\"\n\n- id: \"cameron-jacoby-railsconf-2017\"\n  title: \"Implementing the Web Speech API for Voice Data Entry\"\n  raw_title: \"RailsConf 2017: Implementing the Web Speech API for Voice Data Entry by Cameron Jacoby\"\n  speakers:\n    - Cameron Jacoby\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-26\"\n  published_at: \"2017-05-26\"\n  description: |-\n    RailsConf 2017: Implementing the Web Speech API for Voice Data Entry by Cameron Jacoby\n\n    We live in a world where you can schedule a meeting by talking to your watch or turn off your lights by asking Alexa as if she were your roommate. But would voice dictation work for something more intensive, like a web app used for hours of data entry?\n\n    In this talk, I’ll show you how to implement the Web Speech API in a few simple steps. I’ll also walk through a case study of using the API in a production Rails app. You’ll leave with an understanding of how to implement voice dictation on the web as well as criteria to evaluate if voice is a viable solution to a given problem.\n  video_provider: \"youtube\"\n  video_id: \"e5dR05QGzXA\"\n\n- id: \"nathan-walls-railsconf-2017\"\n  title: \"Exploring the History of a 12-year-old Rails Application\"\n  raw_title: \"RailsConf 2017: Exploring the History of a 12-year-old Rails Application by Nathan Walls\"\n  speakers:\n    - Nathan Walls\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-26\"\n  published_at: \"2017-05-26\"\n  description: |-\n    RailsConf 2017: Exploring the History of a 12-year-old Rails Application by Nathan Walls\n\n    Come on a journey backward through time from the present all the way to August 2005 to see how a living and evolving Rails application started, changed, and continues.\n\n    Find out some of the challenges and temptations in maintaining this application. See how different influences have coursed through the application as the team changed, the business grew and as Rails and Ruby evolved.\n\n    We'll explore history through code and learn from some of the developers involved in the application over its lifecycle to build an understanding of where the application is now and how it became what it is.\n  video_provider: \"youtube\"\n  video_id: \"oh3OZ7GYuK0\"\n\n- id: \"andrew-markle-railsconf-2017\"\n  title: \"Decouple Your Models with Form Objects\"\n  raw_title: \"RailsConf 2017: Decouple Your Models with Form Objects by Andrew Markle\"\n  speakers:\n    - Andrew Markle\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-26\"\n  published_at: \"2017-05-26\"\n  description: |-\n    Forms are a crucial part of every app and Rails has good defaults for building them—unless you need something complicated. Maybe you want a multi-step wizard? Or maybe you'd like to pluck attributes from any model? Validation becomes a pain point. So you introduce a state machine, or nest your models, or do some other calisthenic to get everything working. Thankfully there's a better way! This talk takes a complicated wizard and converts it into a few simple form objects—it's a deep dive on decoupling models and how you can leverage Trailblazer's Reform gem to make it even easier.\n  video_provider: \"youtube\"\n  video_id: \"d9vMENoqxEE\"\n\n- id: \"claudio-baccigalupo-railsconf-2017\"\n  title: \"Rails 5.1: Awesome Features and Breaking Changes\"\n  raw_title: \"RailsConf 2017: Rails 5.1: Awesome Features and Breaking Changes by Claudio B\"\n  speakers:\n    - Claudio Baccigalupo\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-26\"\n  published_at: \"2017-05-26\"\n  description: |-\n    RailsConf 2017: Rails 5.1: awesome features and breaking changes by Claudio B\n\n    Each minor release of Rails brings shiny new features and mild headaches for developers required to upgrade their applications and gems.\n\n    Rails 5.1 will support Yarn and modern Javascript transpilers, remove jQuery from the default stack, integrate system testing and a concurrent test runner, introduce a new helper to create forms, provide encrypted secrets and more.\n\n    In this talk, I will cover the improvements brought by Rails 5.1, explain the Core team’s motivations behind each feature, and illustrate the upgrade process to smoothly transition gems and apps from Rails 5.0 to Rails 5.1.\n  video_provider: \"youtube\"\n  video_id: \"9CWjFtCbrrM\"\n\n- id: \"jonathan-wallace-railsconf-2017\"\n  title: \"Tailoring Mentorship: Achieving the Best Fit\"\n  raw_title: \"RailsConf 2017: Tailoring Mentorship: Achieving the Best Fit by Jonathan Wallace\"\n  speakers:\n    - Jonathan Wallace\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-26\"\n  published_at: \"2017-05-26\"\n  description: |-\n    RailsConf 2017: Tailoring Mentorship: Achieving the Best Fit by Jonathan Wallace\n\n    Are you a Rails expert? To someone just learning Rails, yes, you are. And you can mentor the next generation of experts.  What new skills will you develop by mentoring? And how does one find a mentee or mentor? In this talk, you'll learn how to establish effective, quality mentoring relationships where both parties grow their skills—and their career.  Mentoring accelerates your personal and career growth. Come learn how much you'll grow by sharing your knowledge and experience using practices like inquiry based learning, differentiated learning, and active listening.\n  video_provider: \"youtube\"\n  video_id: \"a9RiUIfIdx8\"\n\n- id: \"nate-berkopec-railsconf-2017\"\n  title: \"Your App Server Config is Wrong\"\n  raw_title: \"RailsConf 2017: Your App Server Config is Wrong by Nate Berkopec\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-26\"\n  published_at: \"2017-05-26\"\n  description: |-\n    RailsConf 2017: Your App Server Config is Wrong by Nate Berkopec\n\n    As developers we spend hours optimizing our code, often overlooking a simpler, more efficient way to make quick gains in performance: application server configuration.\n\n    Come learn about configuration failures that could be slowing down your Rails app. We’ll use tooling on Heroku to identify configuration that causes slower response times, increased timeouts, high server bills and unnecessary restarts.\n\n    You’ll be surprised by how much value you can deliver to your users by changing a few simple configuration settings.\n  video_provider: \"youtube\"\n  video_id: \"itbExaPqNAE\"\n\n- id: \"andreas-fast-railsconf-2017\"\n  title: \"​Recurring Background Jobs with Sidekiq-scheduler\"\n  raw_title: \"RailsConf 2017: ​Recurring Background Jobs with Sidekiq-scheduler by Andreas Fast & Gianfranco Zas\"\n  speakers:\n    - Andreas Fast\n    - Gianfranco Zas\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-26\"\n  published_at: \"2017-05-26\"\n  description: |-\n    RailsConf 2017: ​Recurring Background Jobs with Sidekiq-scheduler by Andreas Fast & Gianfranco Zas\n\n    When background job processing needs arise, Sidekiq is the de facto choice. It's a great tool which has been around for years, but it doesn't provide recurring job processing out of the box. sidekiq-scheduler fills that gap, it's a Sidekiq extension to run background jobs in a recurring manner.\n\n    In this talk, we'll cover how sidekiq-scheduler does its job, different use cases, challenges when running on distributed environments, its future, how we distribute capacity over open source initiatives, and as a bonus, how to write your own Sidekiq extensions.\n  video_provider: \"youtube\"\n  video_id: \"OU4jFXoVjZo\"\n\n- id: \"danielle-adams-railsconf-2017\"\n  title: \"Outside the (Web) Box: Using Ruby for Other Protocols\"\n  raw_title: \"RailsConf 2017: Outside the (Web) Box: Using Ruby for Other Protocols by Danielle Adams\"\n  speakers:\n    - Danielle Adams\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-26\"\n  published_at: \"2017-05-26\"\n  description: |-\n    RailsConf 2017: Outside the (Web) Box: Using Ruby for Other Protocols by Danielle Adams\n\n    Ruby on Rails is a widely used web framework, using HTTP to serve users web pages and store data to databases. But what about serving different types of clients? Is it possible to integrate Rails with other protocol types to talk to other machines? Is it efficient? How would it work? I'm going to share my team's approach integrating a Ruby on Rails application with automation and warehouse hardware, such as barcode scanners and Zebra printers.\n  video_provider: \"youtube\"\n  video_id: \"3tfMzhxYK2M\"\n\n- id: \"justin-weiss-railsconf-2017\"\n  title: \"A Deep Dive Into Sessions\"\n  raw_title: \"RailsConf 2017: A Deep Dive Into Sessions by Justin Weiss\"\n  speakers:\n    - Justin Weiss\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-26\"\n  published_at: \"2017-05-26\"\n  description: |-\n    RailsConf 2017: A Deep Dive Into Sessions by Justin Weiss\n\n    What if your Rails app couldn’t tell who was visiting it? If you had no idea that the same person requested two different pages? If all the data you stored vanished as soon as you returned a response? The session is the perfect place to put this kind of data.\n\n    But sessions can be a little magical. What is a session? How does Rails know to show the right data to the right person? And how do you decide where you keep your session data?\n  video_provider: \"youtube\"\n  video_id: \"mqUbnZIY3OQ\"\n\n- id: \"betsy-haibel-railsconf-2017\"\n  title: \"Data Corruption: Stop the Evil Tribbles\"\n  raw_title: \"RailsConf 2017: Data Corruption: Stop the Evil Tribbles by Betsy Haibel\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-27\"\n  published_at: \"2017-05-27\"\n  description: |-\n    Data Corruption: Stop the Evil Tribbles by Betsy Haibel\n\n    Ever had a production bug that you fixed by changing production data? Ever felt like a bad developer for it? Don't. Bad data has countless causes: Weird user input. Race conditions under load. Heck, even changing business needs. We can't fully prevent data corruption, so what matters is how we recover. In this talk, you'll learn how to prevent and fix bad data at every level of your system. You'll learn UX techniques for incremental, mistake-reducing input. You'll learn how to future-proof validations. And you'll learn auditing techniques to catch bad data -- before your users do.\n  video_provider: \"youtube\"\n  video_id: \"kA8aR1ffoOg\"\n\n- id: \"derek-carter-railsconf-2017\"\n  title: \"​Rails APIs: The Next Generation\"\n  raw_title: \"RailsConf 2017:  ​Rails APIs: The Next Generation by Derek Carter\"\n  speakers:\n    - Derek Carter\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-27\"\n  published_at: \"2017-05-27\"\n  description: |-\n    Rails APIs: The Next Generation by Derek Carter\n\n    This is a sponsored talk by Procore.\n\n    Building a consistent API for a large and long-running monolithic API on a tool-segmented engineering team can sometimes feel like herding cats. REST, serializers, and Swagger: Oh my! Learn what worked (and didn’t!) as we go behind the scenes building Procore’s first open API.\n  video_provider: \"youtube\"\n  video_id: \"iTbTz8_ztIM\"\n\n- id: \"christopher-rigor-railsconf-2017\"\n  title: \"Deep Dive into Docker Containers for Rails Developers\"\n  raw_title: \"RailsConf 2017: Deep Dive into Docker Containers for Rails Developers by Christopher Rigor\"\n  speakers:\n    - Christopher Rigor\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-27\"\n  published_at: \"2017-05-27\"\n  description: |-\n    Deep Dive into Docker Containers for Rails Developers by Christopher Rigor\n\n    This is a sponsored talk by Engine Yard.\n\n    Containers have gained popularity the past few years but they have been around much longer than that. In this talk, we'll dive into the internals of a container. If you have used or heard about Docker containers but are unsure how they work, this talk is for you.\n\n    You’ll also learn how to run Rails in production-ready container environments like Kubernetes.\n  video_provider: \"youtube\"\n  video_id: \"2c4fvXKec7Q\"\n\n- id: \"godfrey-chan-railsconf-2017\"\n  title: \"​Introducing Helix: High-Performance Ruby Made Easy\"\n  raw_title: \"RailsConf 2017: ​Introducing Helix: High-Performance Ruby Made Easy by Godfrey Chan and Yehuda Katz\"\n  speakers:\n    - Godfrey Chan\n    - Yehuda Katz\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-27\"\n  published_at: \"2017-05-27\"\n  description: |-\n    ​Introducing Helix: High-Performance Ruby Made Easy by Godfrey Chan and Yehuda Katz\n\n    This is a sponsored talk by Skylight.\n\n    We got a good productivity boost by writing the original Skylight agent in Ruby, but over time, we couldn't implement all the desired features with its overhead. Ruby is fast enough... until it isn't.\n\n    Introducing Helix — an open-source toolkit for writing native Ruby extensions in Rust, extracted from our Featherweight Agent's DNA. Fast, reliable, productive — pick three. Come join us to find out how you can leverage this power in your Ruby apps and even help make Rails faster!\n\n    (This is not a re-run of Godfrey's talk from last year.)\n  video_provider: \"youtube\"\n  video_id: \"lBapt5YDDvg\"\n\n- id: \"andrew-evans-railsconf-2017\"\n  title: \"Open Sourcing: Real Talk\"\n  raw_title: \"RailsConf 2017: Open Sourcing: Real Talk by Andrew Evans\"\n  speakers:\n    - Andrew Evans\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-27\"\n  published_at: \"2017-05-27\"\n  description: |-\n    Open Sourcing: Real Talk by Andrew Evans\n\n    This is a sponsored talk by Hired.\n\n    Hired open-sources some useful abstractions from our Majestic Monolith® and we've learned a lot. Some tough lessons, and some cool knowledge. We'll cover: When & where should you pull something out of the code? Does it really help? What things are important to think about? What if it never takes off? We'll also look at some design patterns from our open-source work.\n  video_provider: \"youtube\"\n  video_id: \"aOyaYmUTzZI\"\n\n- id: \"remi-taylor-railsconf-2017\"\n  title: \"Google Cloud Love Ruby\"\n  raw_title: \"RailsConf 2017: Google Cloud Love Ruby by Remi Taylor\"\n  speakers:\n    - Remi Taylor\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-27\"\n  published_at: \"2017-05-27\"\n  description: |-\n    Google Cloud Love Ruby by Remi Taylor\n\n    This is a sponsored talk by Google Cloud Platform.\n\n    Ruby developers welcome! Our dedicated Google Cloud Platform Ruby team has built a great experience for Ruby developers using GCP. In this session, we'll walk through the steps to deploy, debug and scale a Ruby on Rails application on Google App Engine. You'll also learn about some of the exciting Ruby libraries available today for adding features to your app with GCP services like BigQuery and Cloud Vision API.\n  video_provider: \"youtube\"\n  video_id: \"MgJlwg2BrgY\"\n\n- id: \"will-leinweber-railsconf-2017\"\n  title: \"​Postgres at Any Scale​\"\n  raw_title: \"RailsConf 2017: ​Postgres at Any Scale​ by Will Leinweber\"\n  speakers:\n    - Will Leinweber\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-27\"\n  published_at: \"2017-05-27\"\n  description: |-\n    ​Postgres at Any Scale​ by Will Leinweber\n\n    This is a sponsored talk by Citus Data.\n\n    Postgres has powerful datatypes and a general emphasis on correctness which makes it a great choice for apps small and medium. Growing to very large sizes has been challenging—until now!\n\n    First you'll learn how to take advantage of all PG has to offer for small scales, especially when it comes to keeping data consistent. Next you'll learn techniques for keeping apps running well at medium scales. And finally you'll learn how to take advantage of the open-source Citus extension that makes PG a distributed db, when your app joins the big leagues.\n  video_provider: \"youtube\"\n  video_id: \"_wU2dglywAU\"\n\n- id: \"dave-ott-railsconf-2017\"\n  title: \"Cultivating a Culture of Continuous Learning\"\n  raw_title: \"RailsConf 2017: Cultivating a Culture of Continuous Learning by Dave Ott and Dennis Eusebio\"\n  speakers:\n    - Dave Ott\n    - Dennis Eusebio\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-27\"\n  published_at: \"2017-05-27\"\n  description: |-\n    Cultivating a Culture of Continuous Learning by Dave Ott and Dennis Eusebio\n\n    This is a sponsored talk by Tuft & Needle.\n\n    Tuft & Needle is a bootstrapped, Phoenix-based company that pioneered the disruption of a the mattress industry using a software startup’s mindset when it was founded in 2012 and has grown to over $100 million in annual revenue. A commitment to skill acquisition has led to a happier and more productive team, and is a core to the company’s success. In this session, learn how to cultivate a culture of continuous learning and skill acquisition through apprenticeships and group learning sessions.\n  video_provider: \"youtube\"\n  video_id: \"awTIU0K6nb4\"\n\n- id: \"gabi-stefanini-railsconf-2017\"\n  title: \"​Keeping Code Style Sanity in a 10-year-old Codebase\"\n  raw_title: \"RailsConf 2017: ​Keeping Code Style Sanity in a 10-year-old Codebase by Gabi Stefanini\"\n  speakers:\n    - Gabi Stefanini\n  event_name: \"RailsConf 2017\"\n  date: \"2017-05-27\"\n  published_at: \"2017-05-27\"\n  description: |-\n    Keeping Code Style Sanity in a 10-year-old Codebase by Gabi Stefanini\n\n    This is a sponsored talk by Shopify.\n\n    Conversations around code consistency seem to spark either cheers or jeers from developers. In this talk, I'll explore the good, bad, and the ugly of code style consistency as illustrated by the (sometimes drama-filled) history of Shopify's 10-year-old codebase. Highlighting strategies to help you evaluate when to push for better code consistency; you will hear about our techniques, tools and guides to enrich developer experience without compromising productivity and how to ultimately make code consistency important across the organization.\n  video_provider: \"youtube\"\n  video_id: \"84upQG0Ilq8\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2018/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyak-yFKj5IN3tDYOh5omMrH\"\ntitle: \"RailsConf 2018\"\nkind: \"conference\"\nlocation: \"Pittsburgh, PA, United States\"\ndescription: \"\"\npublished_at: \"2018-05-15\"\nstart_date: \"2018-04-17\"\nend_date: \"2018-04-19\"\nyear: 2018\nbanner_background: \"#B74735\"\nfeatured_background: \"#B74735\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 40.4386612\n  longitude: -79.99723519999999\n"
  },
  {
    "path": "data/railsconf/railsconf-2018/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n\n# Website: https://web.archive.org/web/20181103192434/http://rubyconf.org/\n# Schedule: https://web.archive.org/web/20181103192434/http://rubyconf.org/schedule\n\n- id: \"nick-quaranto-railsconf-2018\"\n  title: \"The GraphQL Way: A new path for JSON APIs\"\n  raw_title: \"RailsConf 2018: The GraphQL Way: A new path for JSON APIs by Nick Quaranto\"\n  speakers:\n    - Nick Quaranto\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  slides_url: \"https://speakerdeck.com/qrush/the-graphql-way-a-new-path-for-json-apis\"\n  description: |-\n    RailsConf 2018: The GraphQL Way: A new path for JSON APIs by Nick Quaranto\n\n    Have you written JSON APIs in Rails a few times? Even if you’re escaped implementing a “render: :json” call, some day soon you’ll need to get JSON data out to a native client or your front-end framework. Your Rails apps might change, but the pitfalls for JSON APIs stay the same: They’re hard to discover, difficult to change from the client side, and documenting them is a pain. For your next app, or your current one, let’s consider GraphQL. I'll show you how to implement it in your app and offer real-world advice from making it work in an existing Rails app.\n  video_provider: \"youtube\"\n  video_id: \"QHoddukdqf0\"\n\n- id: \"michael-cain-railsconf-2018\"\n  title: \"Candy on Rails: Polymorphism & Rails 5\"\n  raw_title: \"RailsConf 2018: Candy on Rails: Polymorphism & Rails 5 by Michael Cain\"\n  speakers:\n    - Michael Cain\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: Candy on Rails: Polymorphism & Rails 5 by Michael Cain\n\n    Polymorphism is a mainstay of the Ruby on Rails stack, affording us a lean, concise way of relating objects in a dynamic way. Using a candy shop application, this presentation will pragmatically explain and demonstrate polymorphism and its benefits/usefulness in Rails.\n  video_provider: \"youtube\"\n  video_id: \"CD_ye_9lvEM\"\n\n- id: \"liz-certa-railsconf-2018\"\n  title: \"Why We Never Get to Web Accessibility 102\"\n  raw_title: \"RailsConf 2018: Why We Never Get to Web Accessibility 102 by Liz Certa\"\n  speakers:\n    - Liz Certa\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: Why We Never Get to Web Accessibility 102 by Liz Certa\n\n    Creating truly 100% accessible websites often requires specialized knowledge of the ins and outs of screen reader settings, browser defaults and HTML quirks, yet most of us still need to google how to turn on a screen reader. We attend \"Web Accessibility 101\" seminars and workshops over and over but very few of us end up with the kind of specialized knowledge necessary to make truly accessible websites. In this talk, we'll discuss why this is, and how we can eventually get to accessibility 102.\n  video_provider: \"youtube\"\n  video_id: \"gE8S4cUJFUo\"\n\n- id: \"david-mcdonald-railsconf-2018\"\n  title: \"Dropping Into B-Trees\"\n  raw_title: \"RailsConf 2018: Dropping Into B-Trees by David McDonald\"\n  speakers:\n    - David McDonald\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: Dropping Into B-Trees by David McDonald\n\n    Understanding indexes is key to demystifying database performance, and will have huge impact on one's ability to plan, contribute, and troubleshoot as one progresses in their career. Having said all that: many engineers still don’t really know what indexes ARE. Most simply know what indexes can DO. This presentation takes a look at the most commonly used index for any RDBMS: the B-tree. We will pull apart the data structure, discuss how it works, and briefly touch on some of the algorithms they use. With this baseline established, we will revisit a few common assumptions about indexes.\n  video_provider: \"youtube\"\n  video_id: \"17XecHy9Pzg\"\n\n- id: \"mike-calhoun-railsconf-2018\"\n  title: \"Continuous Deployments and Data Sovereignty: A Case Study\"\n  raw_title: \"RailsConf 2018: Continuous Deployments and Data Sovereignty: A Case Study by Mike Calhoun\"\n  speakers:\n    - Mike Calhoun\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: Continuous Deployments and Data Sovereignty: A Case Study by Mike Calhoun\n\n    In any production rails application’s simplest form, there is one version of the app deployed to a single host or cloud provider of your choice, but what if there were laws and regulations in place that required your application to be replicated and maintained within the geographical boundaries of other countries. This is a requirement of countries that have data sovereignty laws and a regular hurdle to overcome when dealing with sensitive data such as protected health information. This talk provides a case study of how we devised an automatic deployment strategy to deploy to multiple countries.\n  video_provider: \"youtube\"\n  video_id: \"K27AZ-_PH0A\"\n\n- id: \"ryan-laughlin-railsconf-2018\"\n  title: \"The Doctor Is In: Using checkups to find bugs in production\"\n  raw_title: \"RailsConf 2018: The Doctor Is In: Using checkups to find bugs in production by Ryan Laughlin\"\n  speakers:\n    - Ryan Laughlin\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: The Doctor Is In: Using checkups to find bugs in production by Ryan Laughlin\n\n    A good test suite can help you catch errors in development, but how do you know if your code starts misbehaving in production?\n\n    In this talk, we’ll learn about checkups: a powerful and flexible way to ensure that your code continues to work as intended after you deploy. Through real-world examples, we’ll see how adding a simple suite of checkups to your app can help you detect unforeseen issues, including tricky problems like race conditions and data corruption. We’ll even look at how checkups can mitigate much larger disasters in real-time. Come give your app’s health a boost!\n  video_provider: \"youtube\"\n  video_id: \"gEAlhKaK2I4\"\n\n- id: \"david-heinemeier-hansson-railsconf-2018\"\n  title: \"Opening Keynote: FIXME\"\n  raw_title: \"RailsConf 2018: Opening Keynote: FIXME by David Heinemeier Hansson\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: Opening Keynote: FIXME by David Heinemeier Hansson\n  video_provider: \"youtube\"\n  video_id: \"zKyv-IGvgGE\"\n\n- id: \"eric-hodel-railsconf-2018\"\n  title: \"Devly, a multi-service development environment\"\n  raw_title: \"RailsConf 2018: Devly, a multi-service development environment by Eric Hodel & Ezekiel Templin\"\n  speakers:\n    - Eric Hodel\n    - Ezekiel Templin\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: Devly, a multi-service development environment by Eric Hodel & Ezekiel Templin\n\n    Devly, a multi-service development environment\n    Writing a system alone is hard. Building many systems with many people is harder.\n\n    As our company has grown, we tried many approaches to user-friendly, shared development environments and learned what works and what doesn't. We incorporated what we learned into a tool called devly. Devly is used to develop products at Fastly that span many services written in different languages.\n\n    We learned that the design of our tools must be guided by how teams work and communicate. To respond to these needs, Devly allows self-service, control, and safety so that developers can focus on their work.\n  video_provider: \"youtube\"\n  video_id: \"Zfv30fSpHBI\"\n\n- id: \"kir-shatrov-railsconf-2018\"\n  title: \"Operating Rails in Kubernetes\"\n  raw_title: \"RailsConf 2018: Operating Rails in Kubernetes by Kir Shatrov\"\n  speakers:\n    - Kir Shatrov\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: Operating Rails in Kubernetes by Kir Shatrov\n\n    Moving from operations powered by scripts like Capistrano to containers orchestrated by Kubernetes requires a shift in practices. We'll talk about things beyond \"Getting started with Kubernetes\" guides, and cover such aspects of operations as gradual deployments, capacity planning, job workers and their safety, and how cloud environments like Kubernetes drastically change how we solve them.\n\n    This presentation is about the lessons we learned while migrating hundreds of Rails apps within the organization to Kubernetes.\n  video_provider: \"youtube\"\n  video_id: \"KKtS0QD5ERM\"\n\n- id: \"akira-matsuda-railsconf-2018\"\n  title: \"Turbo Boosting Real-world Applications\"\n  raw_title: \"RailsConf 2018: Turbo Boosting Real-world Applications by Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: Turbo Boosting Real-world Applications by Akira Matsuda\n\n    One day I joined a team maintaining a huge, legacy, and slow Rails app. We thought that we have to optimize the application throughput for the user happiness, and so we formed a task force that focuses on the performance.\n\n    Now, here's the record of the team's battle, including how we inspected and measured the app, how we found the bottlenecks, and how we tackled each real problem, about the following topics:\n\n    Tuning Ruby processes\n    Finding slow parts inside Rails, and significantly improving them\n    Fixing existing slow libraries, or crafting ultimately performant alternatives\n  video_provider: \"youtube\"\n  video_id: \"y-wqo6LiqMo\"\n\n- id: \"vladimir-dementyev-railsconf-2018\"\n  title: \"Access Denied: the missing guide to authorization in Rails\"\n  raw_title: \"RailsConf 2018: Access Denied: the missing guide to authorization in Rails by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: Access Denied: the missing guide to authorization in Rails by Vladimir Dementyev\n\n    Rails brings us a lot of useful tools out-of-the-box, but there are missing parts too. For example, for such essential tasks as authorization we are on our own. Even if we choose a trending OSS solution, we still have to care about the way to keep our code maintainable, efficient, and, of course, bug-less. Working on Rails projects, I've noticed some common patterns in designing access systems as well as useful code techniques I'd like to share with you in this talk.\n  video_provider: \"youtube\"\n  video_id: \"NVwx0DARDis\"\n\n- id: \"craig-buchek-railsconf-2018\"\n  title: \"Booleans are Easy - True or False?\"\n  raw_title: \"RailsConf 2018: Booleans are Easy - True or False? by Craig Buchek\"\n  speakers:\n    - Craig Buchek\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-15\"\n  description: |-\n    RailsConf 2018: Booleans are Easy - True or False? by Craig Buchek\n\n    Booleans are pretty simple — they're either true or false. But that doesn't mean that they're always easy to use, or that they're always the right choice when they appear to be the obvious choice.\n\n    We'll cover several anti-patterns in the use of booleans. We'll discuss why they're problematic, and explore some better alternatives.\n  video_provider: \"youtube\"\n  video_id: \"PkXTIfVN-3E\"\n\n- id: \"ariel-caplan-railsconf-2018\"\n  title: \"Automating Empathy: Test Your Docs with Swagger and Apivore\"\n  raw_title: \"RailsConf 2018: Automating Empathy: Test Your Docs with Swagger and Apivore by Ariel Caplan\"\n  speakers:\n    - Ariel Caplan\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: Automating Empathy: Test Your Docs with Swagger and Apivore by Ariel Caplan\n\n    Ugh, documentation.\n\n    It's the afterthought of every system, scrambled together in the final days before launch, updated sparingly, generally out of date.\n\n    What if we could programmatically verify that our API documentation was accurate? What if this helped us build more intuitive APIs by putting our users first? What if documentation came first, and helped us write our code?\n\n    With Swagger and Apivore as our weapons of choice, we'll write documentation that will make your APIs better, your clients more satisfied, and you happier.\n  video_provider: \"youtube\"\n  video_id: \"lqPZdvg49GU\"\n\n- id: \"aja-hammerly-railsconf-2018\"\n  title: \"Testing in Production\"\n  raw_title: \"RailsConf 2018: Testing in Production by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  slides_url: \"https://thagomizer.com/files/TestingInProd.pdf\"\n  description: |-\n    RailsConf 2018: Testing in Production by Aja Hammerly\n\n    Test All the F***ing Time is one of the values of the Ruby community. But how many of us test in production in addition to running our test suites as part of CI? This talk will discuss a variety of approaches to testing in prod including canaries, blue-green deployment, beta and A/B tests, and general functional tests. I'll share a few times these techniques have found bugs before our users did and how you can use them today with your Rails Application.\n  video_provider: \"youtube\"\n  video_id: \"BZeylB8XCxg\"\n\n- id: \"nickolas-means-railsconf-2018\"\n  title: \"Who Destroyed Three Mile Island?\"\n  raw_title: \"RailsConf 2018: Who Destroyed Three Mile Island? by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: Who Destroyed Three Mile Island? by Nickolas Means\n\n    On March 28, 1979 at exactly 4:00am, control rods flew into the reactor core of Three Mile Island Unit #2. A fault in the cooling system had tripped the reactor. At 4:02, the emergency cooling system automatically kicked in as reactor temperature continued to climb. At 4:04, one of the operators switched the emergency cooling system off, dooming the reactor to partial meltdown. Why?\n\n    Let’s let the incredibly complex failure at Three Mile Island teach us how to dig into our own incidents. We'll learn how the ideas behind just culture can help us learn from our mistakes and build stronger teams.\n  video_provider: \"youtube\"\n  video_id: \"YBRiffheLXE\"\n\n- id: \"sean-griffin-railsconf-2018\"\n  title: \"Debugging Rails Itself\"\n  raw_title: \"RailsConf 2018: Debugging Rails Itself by Sean Griffin\"\n  speakers:\n    - Sean Griffin\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: Debugging Rails Itself by Sean Griffin\n\n    Tracking down bugs can be hard. Tracking down bugs in a codebase touched by 5000 people is even harder. Making heads or tails of an inheritance-happy codebase like Rails can be a nightmare. How do you find where the bug in save is when save is overridden by 15 different modules?!\n\n    In this talk, we'll look at the process that goes into fixing a bug in Rails itself. You'll learn about every step from the initial report to when the fix is eventually committed. You'll learn how to navigate Rails' internals, and how to find the source of the problem -- even if you've never committed to Rails.\n  video_provider: \"youtube\"\n  video_id: \"IKOLEKxMRa0\"\n\n- id: \"loren-crawford-railsconf-2018\"\n  title: \"Down The Rabbit Hole: An Adventure in Legacy Code\"\n  raw_title: \"RailsConf 2018: Down The Rabbit Hole: An Adventure in Legacy Code by Loren Crawford\"\n  speakers:\n    - Loren Crawford\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: Down The Rabbit Hole: An Adventure in Legacy Code by Loren Crawford\n\n    Legacy code is unpredictable and difficult to understand. Most of us will work with legacy code, so it’s important for us to understand its major pain points and their underlying causes. You’ ll come away from this talk with practical strategies to help you understand, improve, and even love legacy code.\n  video_provider: \"youtube\"\n  video_id: \"Dm2LdXLFrxw\"\n\n- id: \"olivier-lacan-railsconf-2018\"\n  title: \"The Life and Death of a Rails App\"\n  raw_title: \"RailsConf 2018: The Life and Death of a Rails App by Olivier Lacan\"\n  speakers:\n    - Olivier Lacan\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: The Life and Death of a Rails App by Olivier Lacan\n\n    Now that it has become a mature web development framework, Rails is no longer the exclusive realm of burgeoning startups. Healthy small and large businesses have grown with Rails for years. Shrinking and dying companies too. In this talk we'll look at how Rails and its ecosystem of libraries and services can support both newborn and aging apps, and when it struggles to do so.\n  video_provider: \"youtube\"\n  video_id: \"zrR181LhOv4\"\n\n- id: \"taylor-jones-railsconf-2018\"\n  title: \"Webpacking for the Journey Ahead\"\n  raw_title: \"RailsConf 2018: Webpacking for the Journey Ahead by Taylor Jones\"\n  speakers:\n    - Taylor Jones\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: Webpacking for the Journey Ahead by Taylor Jones\n\n    Webpack integration landed in Rails 5.1 to a bit of excitement and confusion. On one hand, folks who had been using Javascript frameworks like Angular and React now have a clearer way to tie in their client-side application into the asset pipeline. Yet, why would we want to do this? What’s the purpose of adding Webpack to Rails, and what’s the advantage of utilizing it? How does this affect javascript frameworks that aren’t Webpack friendly? In this talk, we’ll explore these ideas as well as the future of client side integrations into Rails.\n  video_provider: \"youtube\"\n  video_id: \"NeZ9aAH1Lp4\"\n\n- id: \"ernie-miller-railsconf-2018\"\n  title: \"Stating the Obvious\"\n  raw_title: \"RailsConf 2018: Stating the Obvious by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: Stating the Obvious by Ernie Miller\n\n    Throughout much of this conference you're going to hear people state obvious things. Sometimes, they'll even tell you that they think what they're saying is obvious. Why are they saying them at all, then?\n\n    It's obvious there must be more to the story, so let's examine what we mean by \"obvious\". You'll leave this talk encouraged and ready to apply what you've learned to better empathize with others. Through application, you'll see growth in both your professional and personal life.\n  video_provider: \"youtube\"\n  video_id: \"3P8McQwe1Rg\"\n\n- id: \"mark-imbriaco-railsconf-2018\"\n  title: \"Keynote: Rails Doesn't Scale\"\n  raw_title: \"RailsConf 2018: Keynote: Rails Doesn't Scale by Mark Imbriaco\"\n  speakers:\n    - Mark Imbriaco\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: Keynote: Rails Doesn't Scale by Mark Imbriaco\n  video_provider: \"youtube\"\n  video_id: \"G2MdBtXonew\"\n\n- id: \"harisankar-p-s-railsconf-2018\"\n  title: \"Using Databases to pull your applications weight\"\n  raw_title: \"RailsConf 2018: Using Databases to pull your applications weight by Harisankar P S\"\n  speakers:\n    - Harisankar P S\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: Using Databases to pull your applications weight by Harisankar P S\n\n    Most Rails applications out there in the world deal with the manipulation and presentation of data. So the speed of our application is proportional to how fast we can work with data. Rails is good with presenting data. And our Database is the one who is good at processing data. But we sometimes make the mistake of just using the database as a file cabinet, and using ruby to process. The database is built for crunching data and returning to us the results that we need. This talk is about how to optimize your database so as to speed up your existing Rails application.\n  video_provider: \"youtube\"\n  video_id: \"3hYlghzakow\"\n\n- id: \"emily-freeman-railsconf-2018\"\n  title: \"The Intelligence of Instinct\"\n  raw_title: \"RailsConf 2018: The Intelligence of Instinct by Emily Freeman\"\n  speakers:\n    - Emily Freeman\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: The Intelligence of Instinct by Emily Freeman\n\n    Content warning: This talk includes brief stories about sexual assault and IEDs in Iraq.\n\n    Fear is not a gut feeling. Fear is your brain delivering critical information derived from countless cues that have added up to one conclusion. Stop. Get out. Run.\n\n    But sometimes fear isn’t life or death. Often, it’s code smell. It’s a bad feeling before a deploy. This talk will explore fear, instinct and denial. We’ll focus on our two brains — what Daniel Kahneman describes as System 1 and System 2. And we’ll look at how we can start to view “feelings” as pre-incident indicators.\n  video_provider: \"youtube\"\n  video_id: \"l0JtgRiaS4M\"\n\n- id: \"alistair-mckinnell-railsconf-2018\"\n  title: \"Don't Settle for Poor Names (or for Poor Design)\"\n  raw_title: \"RailsConf 2018: Don't Settle for Poor Names (or for Poor Design) by Alistair McKinnell\"\n  speakers:\n    - Alistair McKinnell\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: Don't Settle for Poor Names (or for Poor Design) by Alistair McKinnell\n\n    Have you ever been frustrated with code that is sprinkled with poorly named classes, methods, and variables?\n\n    One of the most valuable things you can do as a developer is to choose good names and to sensitize your teammates to the benefits of improving names.\n\n    It turns out that improving names is deeply connected to improving design. And vice-versa. You will see and experience this deep connection as we explore a real world example.\n\n    By the end of this talk, you will have learned a process to get you started with improving names and improving design—a process simple enough for you to teach others.\n  video_provider: \"youtube\"\n  video_id: \"j5o-lUF_nJs\"\n\n- id: \"ben-halpern-railsconf-2018\"\n  title: \"How We Made Our App So Fast it Went Viral in Japan\"\n  raw_title: \"RailsConf 2018: How We Made Our App So Fast it Went Viral in Japan by Ben Halpern\"\n  speakers:\n    - Ben Halpern\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-16\"\n  description: |-\n    RailsConf 2018: How We Made Our App So Fast it Went Viral in Japan by Ben Halpern\n\n    We put a lot of effort into web speed for our website dev.to. One day in November we woke to our greatest traffic day ever, and the source was Japanese Dev-Twitter catching wind of just how fast a site could be. American websites don't typically give so much care to global performance, but it pays off if you do. In this talk I will describe how we think about performance.\n  video_provider: \"youtube\"\n  video_id: \"Afy7H04X9Us\"\n\n- id: \"tess-griffin-railsconf-2018\"\n  title: \"Keeping Moms Around for the Long Term\"\n  raw_title: \"RailsConf 2018: Keeping Moms Around for the Long Term by Tess Griffin\"\n  speakers:\n    - Tess Griffin\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Keeping Moms Around for the Long Term by Tess Griffin\n\n    Being a mom is awesome! You finally get to be the one to post a million cute pictures of your adorable baby. It is also one of most challenging and hard things a woman can go through, especially if they're in software.\n\n    In this talk you'll hear stories from women in the programming community, struggles they have gone through, and why many of them left their jobs after or during maternity leave (including me). If you want to help your mom friends stick around and feel included, or if you are from a company who wants to support the growth of your mom employees, then this talk is for you.\n  video_provider: \"youtube\"\n  video_id: \"tX1SuRZ6zpk\"\n\n- id: \"roy-tomeij-railsconf-2018\"\n  title: \"Empathy through Acting\"\n  raw_title: \"RailsConf 2018: Empathy through Acting by Roy Tomeij\"\n  speakers:\n    - Roy Tomeij\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Empathy through Acting by Roy Tomeij\n\n    Individuals can only advance when they know they are valued, listened to, and understood. Without having lived the same life as them, it's often hard to understand why people do what they do. It requires empathy, and practicing empathy can be tough when someone differs greatly from you, personally or professionally. But, being empathetic can be learned, for instance through method acting.\n\n    Let's talk about the fascinating acting techniques of Stanislavski, Strasberg, Adler & Meisner, and learn how you too can employ the Method to better understand (and work with) the people in your life.\n  video_provider: \"youtube\"\n  video_id: \"tZFeIk1-zOw\"\n\n- id: \"jameson-hampton-railsconf-2018\"\n  title: \"Lessons in Ethical Development I Learned From Star Wars\"\n  raw_title: \"RailsConf 2018: Lessons in Ethical Development I Learned From Star Wars by Jameson Hampton\"\n  speakers:\n    - Jameson Hampton\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Lessons in Ethical Development I Learned From Star Wars by Jameson Hampton\n\n    Star Wars fans may have been excited about 2016’s release of Rogue One because of the courageous new rebel characters it introduced, but it also provided a lot more insight into the Empire's Corp of Engineers and how they ended up building the Death Star. As developers, we have a responsibility to think about the ethical implications of our work and how it might be used. This session will discuss ways of deciding for yourself what kinds of projects you are or aren't comfortable working and tips for self-accountability in your career - through the lens of characters we know and love from Star Wars.\n  video_provider: \"youtube\"\n  video_id: \"XcgJeeCpK4s\"\n\n- id: \"yi-ting-xdite-cheng-railsconf-2018\"\n  title: \"Blitzbuilding product with Rails - a crypto journey\"\n  raw_title: 'RailsConf 2018: Blitzbuilding product with Rails - a crypto journey by YiTing \"Xdite\" Cheng'\n  speakers:\n    - Yi-Ting \"Xdite\" Cheng\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    OTCBTC, a cryptocurrency exchange founded in Oct 2017, was developed with Rails. It grows rapidly and has reached hundreds million of dollars of GMV and millions of pageviews within only two months after being launched.And quickly become the largest OTC exchange in Asia. Its ICO had successfully raised the amount equivalent to series B funding.\n\n    In this talk, Xdite will share how she and her team members struggled through the rapid growth of OTCBTC, the future opportunity in blockchain industry, and the challenge in developing such level of project.\n\n    This is a sponsored talk by OTCBTC.\n  video_provider: \"youtube\"\n  video_id: \"onX_0ngn3G4\"\n\n- id: \"christopher-rigor-railsconf-2018\"\n  title: \"Encrypted Credentials on Rails 5.2: Secrets to Success\"\n  raw_title: \"RailsConf 2018: Encrypted Credentials on Rails 5.2: Secrets to Success by Christopher Rigor\"\n  speakers:\n    - Christopher Rigor\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Encrypted Credentials on Rails 5.2: Secrets to Success by Christopher Rigor\n\n    Secrets are out. Credentials are in. This new Rails 5.2 feature offers a number of advantages over the old way of managing secrets. You get atomic deploys, you avoid putting sensitive data on environment variables, and your data is always encrypted.\n\n    This talk will reveal the secrets to success in using Credentials and EncryptedConfiguration, the API it uses internally.\n\n    This is a sponsored talk by Engine Yard.\n  video_provider: \"youtube\"\n  video_id: \"fS92ZDfLhng\"\n\n- id: \"coraline-ada-ehmke-railsconf-2018\"\n  title: \"Scaling the Software Artisan\"\n  raw_title: \"RailsConf 2018: Scaling the Software Artisan by Coraline Ada Ehmke\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Scaling the Software Artisan by Coraline Ada Ehmke\n\n    In the late 1700s the discovery of the principle of interchangeable parts shifted the demand for the expertise of artisans from production to design and invention. This shift transformed Western civilization and opened the way for the industrial revolution. We face a similar opportunity now as one generation of software developers reaches its professional peak and a new wave of developers enter the field. This talk will trace the historical evolution of the artisan and explore how understanding this history can help us to maximize and multiply the impact of senior software developers.\n  video_provider: \"youtube\"\n  video_id: \"tHxssXfymOE\"\n\n- id: \"gretchen-ziegler-railsconf-2018\"\n  title: \"All Onboard: Cruising on the Mentorship\"\n  raw_title: \"RailsConf 2018: All Onboard: Cruising on the Mentorship by Gretchen Ziegler\"\n  speakers:\n    - Gretchen Ziegler\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: All Onboard: Cruising on the Mentorship by Gretchen Ziegler\n\n    Last summer, two high school juniors with very little coding experience joined Vitals as software engineering interns. Over the course of six weeks, they attempted to level up their programming skills while also learning the Vitals domain. They struggled through obstacles and experienced thrilling code highs, and ultimately emerged as more confident developers.\n\n    Using their story as a guide, this talk will explore practical ways of structuring mentoring and onboarding processes. Whether your next hires are newbies or seasoned pros, you’ll walk away with strategies to help them code confidently.\n  video_provider: \"youtube\"\n  video_id: \"S7cYJumzuL4\"\n\n- id: \"andr-arko-railsconf-2018\"\n  title: \"Pairing: a guide to fruitful collaboration 🍓🍑🍐\"\n  raw_title: \"RailsConf 2018: Pairing: a guide to fruitful collaboration 🍓🍑🍐 by André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Pairing: a guide to fruitful collaboration 🍓🍑🍐 by André Arko\n\n    Despite general consensus that pairing is good, the desire to pair doesn’t come with instructions. Come to this talk to learn how to pair with someone more experienced, how (and why) to pair with your peers, and how to pair productively with someone less experienced. (Hint: productivity isn’t about the speed of new features.) Pairing is a fantastic tool for your professional toolbox: let’s design, refine, and refactor, together.\n  video_provider: \"youtube\"\n  video_id: \"km7uGUEd4fk\"\n\n- id: \"adam-cuppy-railsconf-2018\"\n  title: \"Mechanically Confident\"\n  raw_title: \"RailsConf 2018: Mechanically Confident by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Mechanically Confident by Adam Cuppy\n\n    The idea that confidence is solely the result of positive self-talk is circular: If I believed in my ability to talk myself up, I would. But if I did, I wouldn't need to talk myself up. It's not as simple as having faith.\n\n    There's a thread amongst all peak performers and skilled practitioners: specific habits, routines, and processes that wrap uncertainty and create confidence. Oscar-winning actors rehearse, pro-drivers do laps, chefs prep.\n\n    This talk will help you recognize and design habits, routines, and practices that embed confidence into the body.\n  video_provider: \"youtube\"\n  video_id: \"6xnealmhEnM\"\n\n- id: \"max-tiu-railsconf-2018\"\n  title: \"The Practical Guide to Building an Apprenticeship\"\n  raw_title: \"RailsConf 2018: The Practical Guide to Building an Apprenticeship by Max Tiu\"\n  speakers:\n    - Max Tiu\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: The Practical Guide to Building an Apprenticeship by Max Tiu\n\n    Currently, our industry has a surplus of bright junior developers, but a lack of open junior positions. Building a developer apprenticeship in your organization is a great way to provide a haven for these talented devs, while simultaneously making your team more productive and easing the pain of hiring.\n\n    In this talk, you'll learn from the mistakes I've made and wins I've had in creating an apprenticeship. From pitching the idea to growing your apprentices, you'll gain a step-by-step guide to successfully building your own apprenticeship program.\n  video_provider: \"youtube\"\n  video_id: \"5sVg7DtZ0zk\"\n\n- id: \"stella-cotton-railsconf-2018\"\n  title: \"So You’ve Got Yourself a Kafka: Event-Powered Rails Services\"\n  raw_title: \"RailsConf 2018: So You’ve Got Yourself a Kafka: Event-Powered Rails Services by Stella Cotton\"\n  speakers:\n    - Stella Cotton\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: So You’ve Got Yourself a Kafka: Event-Powered Rails Services by Stella Cotton\n\n    It’s easier than ever to integrate a distributed commit log system like Kafka into your stack. But once you have it, what do you do with it? Come learn the basics about Kafka and event-driven systems and how you can use them to power your Rails services. We’ll also venture beyond the theoretical to talk about practical considerations and unusual operational challenges that your event-driven Rails services might face, like monitoring, queue processing, and scaling slow consumers.\n  video_provider: \"youtube\"\n  video_id: \"Rzl4O1oaVy8\"\n\n- id: \"chris-hoffman-railsconf-2018\"\n  title: \"Some Funny Things Happened on The Way to A Service Ecosystem\"\n  raw_title: \"RailsConf 2018: Some Funny Things Happened on The Way to A Service Ecosystem by Chris Hoffman\"\n  speakers:\n    - Chris Hoffman\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Some Funny Things Happened on The Way to A Service Ecosystem by Chris Hoffman\n\n    So this one time we ran Rails services over AMQP (instead of HTTP). You may be thinking “Why? Was that their first mistake?” It was not. From handling shared models poorly to deploying & operating services with inadequate tooling, we've made...so many mistakes. I'm glad we did; they helped us grow. We have patterns & practices for everything we’ve seen so far, from API contracts to distributed consensus protocols. Over this talk’s 40 minutes, you'll learn things it took us 3 years to grasp. Whether you have a monolith or pine for when you did, you'll be more prepared and better armed than we were.\n  video_provider: \"youtube\"\n  video_id: \"WtZUVzDGkTM\"\n\n- id: \"alex-wood-railsconf-2018\"\n  title: \"Broken APIs Break Trust: Tips for Creating and Updating APIs\"\n  raw_title: \"RailsConf 2018: Broken APIs Break Trust: Tips for Creating and Updating APIs by Alex Wood\"\n  speakers:\n    - Alex Wood\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Broken APIs Break Trust: Tips for Creating and Updating APIs by Alex Wood\n\n    For many of us, APIs and their client libraries are the face of our applications to the world. We need to innovate with new features, but breaking changes are toxic to customer trust.\n\n    In this session you will pick-up concrete design patterns that you can use and anti-patterns that you can recognize so that your service API or library can continue to grow without breaking the world. Using real APIs and open source libraries as a case study, we’ll look at actual examples of specific strategies that you can employ to keep your API backwards compatible without painting yourself into a corner.\n  video_provider: \"youtube\"\n  video_id: \"4McL54Pd2Cs\"\n\n- id: \"leonardo-tegon-railsconf-2018\"\n  title: \"Warden: the building block behind Devise\"\n  raw_title: \"RailsConf 2018: Warden: the building block behind Devise by Leonardo Tegon\"\n  speakers:\n    - Leonardo Tegon\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Warden: the building block behind Devise by Leonardo Tegon\n\n    Authentication is one of the most common features of web applications, so it makes sense to have libraries that provide solutions for this problem. You've probably heard of or maybe used Devise: all you have to do is add it to your Gemfile and run a generator, and you have a robust authentication system.\n\n    Behind the scenes, Devise uses Warden to handle authentication. In this talk, I'll explain what Warden is, why it's useful and how Devise takes advantage of it to build the most popular authentication gem for Rails.\n  video_provider: \"youtube\"\n  video_id: \"QBJ3G40fxHg\"\n\n- id: \"justin-weiss-railsconf-2018\"\n  title: \"Building a Collaborative Text Editor\"\n  raw_title: \"RailsConf 2018: Building a Collaborative Text Editor by Justin Weiss\"\n  speakers:\n    - Justin Weiss\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Building a Collaborative Text Editor by Justin Weiss\n\n    Have you ever clicked \"Save\" on a document, and caused a coworker to lose hours of work? Or spent more time coordinating \"Who has permission to edit\" in Slack than you did actually writing the document?\n\n    Google-Docs-style collaboration used to be nice to have. Now, it's expected. Companies like Quip and Coda have based their business on real-time collaboration features. Atom and Sublime Text have collaborative editing plugins. Even Confluence now supports collaborative editing!\n\n    In this talk, you'll learn how to build a great collaborative experience, based on solid fundamental ideas.\n  video_provider: \"youtube\"\n  video_id: \"lmjMC2FRF-A\"\n\n- id: \"michael-hartl-railsconf-2018\"\n  title: \"Ten Years of Rails Tutorials\"\n  raw_title: \"RailsConf 2018: Ten Years of Rails Tutorials by Michael Hartl\"\n  speakers:\n    - Michael Hartl\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Ten Years of Rails Tutorials by Michael Hartl\n\n    Come see how Rails has evolved over the years through the lens of introductory Rails tutorials. Marvel at Rails pre-REST, survive the merger with Merb, feel the joy & pain of the then-new asset pipeline, and watch testing techniques grow, evolve, and simplify. Leave with a deeper appreciation for where Rails came from and where it is today.\n  video_provider: \"youtube\"\n  video_id: \"MBL2jRL9crI\"\n\n- id: \"justin-collins-railsconf-2018\"\n  title: \"The Evolution of Rails Security\"\n  raw_title: \"RailsConf 2018: The Evolution of Rails Security by Justin Collins\"\n  speakers:\n    - Justin Collins\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: The Evolution of Rails Security by Justin Collins\n\n    Rails has a reputation for being secure by default, but how deserved is that reputation? Let's take a look back at some of the low points in Rails security history: from the first Rails CVE, to the controversial GitHub mass assignment, the 2013 Rails apocalypse, and more recent remote code execution issues. Then we'll cheer ourselves up with the many cool security features Rails has added over the years! We'll cover auto-escaping, strong parameters, default security headers, secret storage, and less well-known features like per-form CSRF tokens and upcoming Content Security Policy support.\n  video_provider: \"youtube\"\n  video_id: \"Btrmc1wO3pc\"\n\n- id: \"pete-holiday-railsconf-2018\"\n  title: \"The Code-Free Developer Interview\"\n  raw_title: \"RailsConf 2018: The Code-Free Developer Interview by Pete Holiday\"\n  speakers:\n    - Pete Holiday\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: The Code-Free Developer Interview by Pete Holiday\n\n    When it comes to evaluating candidates for software engineering roles, it's hard to keep up with the latest and greatest techniques. We know logic puzzles don't work. Writing pseudocode on a white board is so tired and cliche at this point that companies brag about not doing that. Teams have resorted to what seems like an obvious choice at first blush: just have the candidate write some code. This new trend may have some unintended consequences, though.\n\n    In this talk, you'll learn how to design an interview process which allows you to evaluate candidates without making them code for you.\n  video_provider: \"youtube\"\n  video_id: \"O3XRE0HvzJ8\"\n\n- id: \"laura-mosher-railsconf-2018\"\n  title: \"Harry the Hedgehog Learns You A Communication\"\n  raw_title: \"RailsConf 2018: Harry the Hedgehog Learns You A Communication by Laura Mosher\"\n  speakers:\n    - Laura Mosher\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Harry the Hedgehog Learns You A Communication by Laura Mosher\n\n    We know how to communicate — we do it on a daily basis, so why spend time perfecting something you feel you already know how to do? Well, what you say and how you say it impacts how you are understood and how others perceive you. In written communication, a single missing comma can wildly change the meaning of what you said. In this talk, we'll walk through 5 tips that improve how you communicate. Using real world examples, we'll show how common these pitfalls are and how to overcome them. You'll leave armed with the ability to positively impact your relationships through how you communicate.\n  video_provider: \"youtube\"\n  video_id: \"uT1ovJqIjt4\"\n\n- id: \"brittany-martin-railsconf-2018\"\n  title: \"Draw a Crowd\"\n  raw_title: \"RailsConf 2018: Draw a Crowd by Brittany Martin\"\n  speakers:\n    - Brittany Martin\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Draw a Crowd by Brittany Martin\n\n    Contextual Camouflage is an open-source gallery art installation built in RoR that guides visitors to anonymously report mental health disorders that affect themselves or their relationships. After users submit a disorder, they have the option to include anecdotes and demographic data for intervention researchers. The data is molded into an interactive real-time display using ActionCable. Come see how code can double as art and an educational tool.\n  video_provider: \"youtube\"\n  video_id: \"S9z-qRPdBac\"\n\n- id: \"ben-shippee-railsconf-2018\"\n  title: \"Ales on Rails: Making a Smarter Brewery with Ruby\"\n  raw_title: \"RailsConf 2018: Ales on Rails: Making a Smarter Brewery with Ruby by Ben Shippee\"\n  speakers:\n    - Ben Shippee\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Ales on Rails: Making a Smarter Brewery with Ruby by Ben Shippee\n\n    Rails is a great framework to empower people to work smarter, not harder. I'll be sharing the evolution of technology in a Pittsburgh brewery, from a simple MVP to a production application. This talk will explore how Ruby and Rails was leveraged to help manage brewery data, control aspects of the taproom environment, and automate the tedious parts of the job to a few clicks.\n  video_provider: \"youtube\"\n  video_id: \"f7pHXYw7Z1Q\"\n\n- id: \"andy-glass-railsconf-2018\"\n  title: \"Human Powered Rails: Automated Crowdsourcing In Your RoR App\"\n  raw_title: \"RailsConf 2018: Human Powered Rails: Automated Crowdsourcing In Your RoR App by Andy Glass\"\n  speakers:\n    - Andy Glass\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  description: |-\n    RailsConf 2018: Human Powered Rails: Automated Crowdsourcing In Your RoR App by Andy Glass\n\n    Machine learning and AI are all the rage, but there’s often no replacement for real human input. This talk will explore how to automate the integration of human-work directly into a RoR app, by enabling background workers to request and retrieve data from actual human workers. The secret is Amazon Mechanical Turk, a crowdsourcing marketplace connecting ‘requesters’ who post tasks with ‘workers’ who complete them. Attendees will learn how to automate the completion of human tasks (e.g. price research, image tagging, sentiment analysis, etc) with impressive speed, accuracy and scalability.\n  video_provider: \"youtube\"\n  video_id: \"ZF4862NLzfA\"\n\n- id: \"eileen-m-uchitelle-railsconf-2018\"\n  title: \"Keynote: The Future of Rails 6: Scalable by Default\"\n  raw_title: \"RailsConf 2018: Keynote: The Future of Rails 6: Scalable by Default by Eileen Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-17\"\n  slides_url: \"https://speakerdeck.com/eileencodes/railsconf-2018-the-future-of-rails-6-scalable-by-default\"\n  description: |-\n    RailsConf 2018: Keynote: The Future of Rails 6: Scalable by Default by Eileen M. Uchitelle\n  video_provider: \"youtube\"\n  video_id: \"8evXWvM4oXM\"\n\n- id: \"todd-kaufman-railsconf-2018\"\n  title: \"Running a Business, Demystified\"\n  raw_title: \"RailsConf 2018: Running a Business, Demystified by Todd Kaufman & Justin Searls\"\n  speakers:\n    - Todd Kaufman\n    - Justin Searls\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Running a Business, Demystified by Todd Kaufman\n\n    Building a business is both mysterious and hard. We can't do much to make it easier, but after 6 years running Test Double, we can make it less mysterious. This talk is a slow-motion Q & A: submit a question to http://testdouble.com/business and we'll build a slide deck that gives as many practical (and colorful) answers we can fit in a 45 minute session.\n\n    This talk is for anyone whose interest in starting a software company has ever been held back by fear, uncertainty or doubt. It assumes no knowledge of business jargon and will strive to explain each financial concept covered.\n  video_provider: \"youtube\"\n  video_id: \"kJEN5Dt2kKU\"\n\n- id: \"michael-herold-railsconf-2018\"\n  title: \"What's in a price? How to price your products and services\"\n  raw_title: \"RailsConf 2018: What's in a price? How to price your products and services by Michael Herold\"\n  speakers:\n    - Michael Herold\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    What's in a price? How to price your products and services by Michael Herold\n\n    So you have something new to sell: maybe your first book or a hip new SaaS. How do you decide the price? How do you know you're not overpricing? Or underpricing? Why, oh why, did you ever think to sell something?!\n\n    Instead of choosing a number by looking inward at your costs, you can use what programmers use best: an abstraction! You'll learn a model for picking the right price for your product and what that price communicates so you can confidently price your next great invention. You'll leave with an actionable list of next steps for pricing your future projects.\n  video_provider: \"youtube\"\n  video_id: \"DldgNBbH9aU\"\n\n- id: \"thijs-cadier-railsconf-2018\"\n  title: \"Reporting Live from the Ramp of Death\"\n  raw_title: \"RailsConf 2018: Reporting Live from the Ramp of Death by Thijs Cadier\"\n  speakers:\n    - Thijs Cadier\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Reporting Live from the Ramp of Death by Thijs Cadier\n\n    Lying on the beach and enjoying the 4-hour work week: who wouldn't like the recurring revenue stream of a SaaS business? It's why many start building a SaaS company \"on the side\", only to find out they don't make enough money to buy a latte and fall back to getting paid by the hour. They're stuck on the long, slow Ramp of Death.\n\n    Coming to you live from the trenches of running an organically growing SaaS for five years, this is an honest –and sometimes brutal– story of perseverance, sacrifice and reward. Find out how to overcome the ramp, and why it isn't as bad as you might think.\n  video_provider: \"youtube\"\n  video_id: \"5_ZhUCMxQ8M\"\n\n- id: \"cecy-correa-railsconf-2018\"\n  title: \"Taking the Pain Out of Support Engineering\"\n  raw_title: \"RailsConf 2018: Taking the Pain Out of Support Engineering by Cecy Correa\"\n  speakers:\n    - Cecy Correa\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Taking the Pain Out of Support Engineering by Cecy Correa\n\n    Production support is not a priority. No one on the team wants to work on support cards. Being on-call is a pain. Does this ring a bell? We've all been there! There is a better way to handle Support Engineering for your product. A way that will level up your team, and create positive support experiences for your customers. Drawing on 3+ years of Support Engineering at two different companies, I will share successful Support patterns and tools you can start using today to improve your product support.\n  video_provider: \"youtube\"\n  video_id: \"RvkM17lFxpA\"\n\n- id: \"aly-fulton-railsconf-2018\"\n  title: \"Leveling Up a Heroic Team\"\n  raw_title: \"RailsConf 2018:  Leveling Up a Heroic Team by Aly Fulton\"\n  speakers:\n    - Aly Fulton\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Leveling Up a Heroic Team by Aly Fulton\n\n    Your application is a dragon and here’s how we’re going to form a successful raiding party to come out victorious (with minimal casualties!). When entering the field of web development, I discovered that the parallels of building a strong multiplayer gaming community and optimizing companies for success were undeniable. Your quest, should you choose to accept it, is to listen to these parallels and use the lessons to strengthen your biggest asset-–your team–-to build a better company and a better web.\n  video_provider: \"youtube\"\n  video_id: \"mpnNiTuVSyw\"\n\n- id: \"graham-conzett-railsconf-2018\"\n  title: \"Old-school Javascript in Rails\"\n  raw_title: \"RailsConf 2018: Old-school Javascript in Rails by Graham Conzett\"\n  speakers:\n    - Graham Conzett\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Old-school Javascript in Rails by Graham Conzett\n\n    Sometimes vanilla Javascript and Rails out-of-the box UJS is good enough, especially when it comes to building things like admin panels and other types of content management. We'll discuss strategies for building rich user interfaces using minimal vanilla Javascript that leverages as much of Rails UJS as we can.\n  video_provider: \"youtube\"\n  video_id: \"lh5qfV2iP80\"\n\n- id: \"sarah-mei-railsconf-2018\"\n  title: \"Keynote: Livable Code\"\n  raw_title: \"RailsConf 2018: Keynote - Livable Code by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Keynote - Livable Code by Sarah Mei\n  video_provider: \"youtube\"\n  video_id: \"lI77oMKr5EY\"\n\n- id: \"sam-phippen-railsconf-2018\"\n  title: \"Quick and easy browser testing using RSpec and Rails 5.1\"\n  raw_title: \"RailsConf 2018:  Quick and easy browser testing using RSpec and Rails 5.1 by Sam Phippen\"\n  speakers:\n    - Sam Phippen\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Quick and easy browser testing using RSpec and Rails 5.1 by Sam Phippen\n\n    Traditionally doing a full stack test of a Rails app with RSpec has been problematic. The browser wouldn't automate, capybara configuration would be a nightmare, and cleaning up your DB was difficult. In Rails 5.1 the new 'system test' type was added to address this. With modern RSpec and Rails, testing every part of your stack including Javascript from a browser is now a breeze.\n\n    In this talk, you'll learn about the new system specs in RSpec, how to set them up, and what benefits they provide. If you want to improve your RSpec suite with full stack testing this talk is for you!\n  video_provider: \"youtube\"\n  video_id: \"JD-28Oi7fxI\"\n\n- id: \"sasha-grodzins-railsconf-2018\"\n  title: \"Build A Blog in 15 (more like 30) Minutes: Webpacker Edition\"\n  raw_title: \"RailsConf 2018: Build A Blog in 15 (more like 30) Minutes: Webpacker Edition by Sasha Grodzins\"\n  speakers:\n    - Sasha Grodzins\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Build A Blog in 15 (more like 30) Minutes: Webpacker Edition by Sasha Grodzins\n\n    An ode to DHH's classic, let's build a blog with a Rails backend using a graphQL API and a React frontend. Through this live-coding session, you will learn how to set up an isomorphic app, the basic concepts of each library, and at the end have a fully functioning blog application! Follow along on your computer or clone the repo.\n  video_provider: \"youtube\"\n  video_id: \"f-qY37JIdg0\"\n\n- id: \"michael-crismali-railsconf-2018\"\n  title: \"6 degrees of JavaScript on Rails\"\n  raw_title: \"RailsConf 2018: 6 degrees of JavaScript on Rails by Michael Crismali\"\n  speakers:\n    - Michael Crismali\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    6 degrees of JavaScript on Rails by Michael Crismali\n\n    How much JavaScript you include in your Rails application can feel like a choice between basically none or a full JavaScript single page application backed by a Rails API. When you have a team of people whose confidence with JavaScript is all over the place, this can feel like an impossible choice. Fortunately, there are many options in the middle that can allow those with less JavaScript confidence to stretch and grow while those with more confidence can build UI components with fewer constraints.\n  video_provider: \"youtube\"\n  video_id: \"hXdJU2lpfsE\"\n\n- id: \"ross-kaffenberger-railsconf-2018\"\n  title: \"Look Before You Import: A Webpack Survival Guide\"\n  raw_title: \"RailsConf 2018: Look Before You Import: A Webpack Survival Guide by Ross Kaffenberger\"\n  speakers:\n    - Ross Kaffenberger\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Look Before You Import: A Webpack Survival Guide by Ross Kaffenberger\n\n    Perhaps you've thought about switching to Webpack. Then you open a Webpack config file and your heart sinks; it looks like an alien life-form. You try to get it working, but your old jQuery plugins won't even load in the browser.\n\n    Moving from Webpack basics to using it in production means understanding how it works. We'll demystify how Webpack bundles assets for the browser, how it differs from the Rails asset pipeline, and highlight common challenges that may occur coming from Sprockets.\n\n    This is the talk we would have wanted to see before recently adopting Webpack in our own Rails app.\n  video_provider: \"youtube\"\n  video_id: \"fKOq5_2qj54\"\n\n- id: \"aaron-patterson-railsconf-2018\"\n  title: \"Closing Keynote\"\n  raw_title: \"RailsConf 2018: Closing Keynote by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  slides_url: \"https://speakerdeck.com/tenderlove/railsconf-2018-keynote\"\n  description: |-\n    Closing Keynote by Aaron Patterson\n  video_provider: \"youtube\"\n  video_id: \"cBFuZivrdT0\"\n\n- id: \"emil-ong-railsconf-2018\"\n  title: \"Putting Rails in a corner: Understanding database isolation\"\n  raw_title: \"RailsConf 2018: Putting Rails in a corner: Understanding database isolation by Emil Ong\"\n  speakers:\n    - Emil Ong\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Putting Rails in a corner: Understanding database isolation by Emil Ong\n\n    If you've ever had inconsistent data show up in your app even though you wrapped the relevant code in a transaction, you're not alone! Database isolation levels might be the solution...\n\n    This talk will discuss what database isolation levels are, how to set them in Rails applications, and Rails-specific situations where not choosing the right isolation level can lead to faulty behavior. We'll also talk about how testing code that sets isolation levels requires special care and what to expect to see when monitoring your apps.\n  video_provider: \"youtube\"\n  video_id: \"qwmviS2g1lA\"\n\n- id: \"jordan-raine-railsconf-2018\"\n  title: \"Ten years of Rails upgrades\"\n  raw_title: \"RailsConf 2018: Ten years of Rails upgrades by Jordan Raine\"\n  speakers:\n    - Jordan Raine\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Ten years of Rails upgrades by Jordan Raine\n\n    Upgrading Rails can go from easy-to-hard quickly. If you've struggled to upgrade to a new version of Rails, you're not alone. And yet, with useful deprecation warnings and extensive beta periods, Rails has never made it easier to upgrade. So what makes it hard?\n\n    By looking at the past ten years of Rails upgrades at Clio (and other notable apps), let's see what we can learn. Gain insight into the tradeoffs between different timelines and approaches and learn practical ways to keep your app up-to-date.\n  video_provider: \"youtube\"\n  video_id: \"6aCfc0DkSFo\"\n\n- id: \"mike-schutte-railsconf-2018\"\n  title: \"Stop Testing, Start Storytelling\"\n  raw_title: \"RailsConf 2018: Stop Testing, Start Storytelling by Mike Schutte\"\n  speakers:\n    - Mike Schutte\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Stop Testing, Start Storytelling by Mike Schutte\n\n    Stop trying to be a computer; you're a human! You know what humans are good at? Storytelling. Stop trying to write tests just to get a green test suite, and start telling rich, descriptive stories. Once you have a good story, then you can worry about the implementation details (wait, is testing a form of abstraction and encapsulation?!). In this talk, we look at writing tests as simply telling stories to the test suite. By telling stories about the application (methods, controllers, features, &c.) the suite holds the storyteller accountable for making those stories become, and stay, true.\n  video_provider: \"youtube\"\n  video_id: \"-vTZzOssR7A\"\n\n- id: \"khash-sajadi-railsconf-2018\"\n  title: \"Deploying any Rails application to any cloud in minutes\"\n  raw_title: \"RailsConf 2018: Deploying any Rails application to any cloud in minutes by Khash Sajadi\"\n  speakers:\n    - Khash Sajadi\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Deploying any Rails application to any cloud in minutes by Khash Sajadi\n\n    Let us show you the easiest way to build, deploy and manage any Rails application on any cloud provider and under your own cloud account. We will also show you how to scale your databases, setup database replication and add off-site backups to your databases with extreme simplicity. Find out how to spend less time configuring boxes, and more time developing great web apps!\n\n    This is a sponsored talk by Cloud 66.\n  video_provider: \"youtube\"\n  video_id: \"DOmTzBRcFT8\"\n\n- id: \"vietor-davis-railsconf-2018\"\n  title: \"Engineering Engineering: More than the sum of our parts\"\n  raw_title: \"RailsConf 2018: Engineering Engineering: More than the sum of our parts by Vietor Davis\"\n  speakers:\n    - Vietor Davis\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Engineering Engineering: More than the sum of our parts by Vietor Davis\n\n    Applying the tried and true answers of “It depends.”, “Maybe?”, and “It works for me, what if you try …” to our engineering organizations themselves turns out to work better than trying to find the One True Way. We all know that every engineering project is full of trade-offs, caveats, surprising complexities, and hidden depths; so it should be no surprise that we, the engineers who build such systems, are at least as complicated.\n\n    This is a sponsored talk by Procore.\n  video_provider: \"youtube\"\n  video_id: \"7vTtOoCiKao\"\n\n- id: \"ryan-davis-railsconf-2018\"\n  title: \"Minitest 6: test feistier!\"\n  raw_title: \"RailsConf 2018: Minitest 6: test feistier! by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Minitest 6: test feistier! by Ryan Davis\n\n    Minitest 5 ships with ruby and is the standard test framework for rails. It already provides a traditional unit test framework, spec DSL, mocks, stubs, test randomization, parallelization, machine agnostic benchmarking, and tons of assertions all in under 2kloc. So what would Minitest 6 do differently? Hopefully to the end user, not much will change, and yet it will be worlds apart from Minitest 5. Come see how you can massively speed up your rails test runs and improve your testing practices by upgrading your test framework.\n  video_provider: \"youtube\"\n  video_id: \"l-ZNxvFo4lw\"\n\n- id: \"chris-arcand-railsconf-2018\"\n  title: \"An Atypical 'Performance' Talk\"\n  raw_title: \"RailsConf 2018: An Atypical 'Performance' Talk by Chris Arcand\"\n  speakers:\n    - Chris Arcand\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    An Atypical 'Performance' Talk by Chris Arcand\n\n    A mixture of a talk on programming and a live classical music recital. Listen to a former-orchestral-clarinetist-turned-developer talk about parallelisms between music performance and programming - such as complexity, imposter syndrome, and true concentration - with live performances throughout!\n  video_provider: \"youtube\"\n  video_id: \"0Lllf9OjO4k\"\n\n- id: \"jake-varghese-railsconf-2018\"\n  title: \"Giving your Heroku App highly-available PostgreSQL\"\n  raw_title: \"RailsConf 2018: Giving your Heroku App highly-available PostgreSQL by Jake Varghese\"\n  speakers:\n    - Jake Varghese\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Giving your Heroku App highly-available PostgreSQL by Jake Varghese\n\n    As you’re building out your app, you know how important it is to have your database up at all times. You need your PostgreSQL database to be HA. Jake from Compose is going to show you how to migrate your data to a HA PG service in less than 20 minutes.\n\n    This is a sponsored talk by Compose, an IBM company\n  video_provider: \"youtube\"\n  video_id: \"GJK5CimW0Kw\"\n\n- id: \"sam-aarons-railsconf-2018\"\n  title: \"“API?” – How LendingHome Approaches “Legacy” Technologies\"\n  raw_title: \"RailsConf 2018: “API?” – How LendingHome Approaches “Legacy” Technologies by Sam Aarons\"\n  speakers:\n    - Sam Aarons\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    “API?” – How LendingHome Approaches “Legacy” Technologies by Sam Aarons\n\n    LendingHome is on a mission to simplify the mortgage process, but that’s not always easy in a world where we hear “API? What’s that?” from our third-party vendors. For the ones that do have technology solutions the phrases “FTP” and “Fixed-Width” are frequently thrown around.\n\n    This talk will dive into the solutions we’ve built that abstract away some of these concepts and how we provide clean interfaces for these services to the rest of the organization. If you’ve ever wanted to learn how modern companies interface with the old, this is the talk for you.\n\n    This is a sponsored talk by LendingHome.\n  video_provider: \"youtube\"\n  video_id: \"sKGoWVykxa0\"\n\n- id: \"vaidehi-joshi-railsconf-2018\"\n  title: \"Re-graphing The Mental Model of The Rails Router\"\n  raw_title: \"RailsConf 2018: Re-graphing The Mental Model of The Rails Router by Vaidehi Joshi\"\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Re-graphing The Mental Model of The Rails Router by Vaidehi Joshi\n\n    Rails is incredibly powerful because of its abstractions. For years, developers have been able to hit the ground running and be productive without having to know the in's and out's of the core computer science concepts that fuel this framework. But just because something is hidden away doesn't mean that it's not worth knowing! In this talk, we'll unpack the CS fundamentals that are used in the Rails router. Together, we'll demystify the graph data structure that lies under the hood of the router in order to understand how a simple structure allows for routing to actually work in a Rails app.\n  video_provider: \"youtube\"\n  video_id: \"lEC-QoZeBkM\"\n\n- id: \"claudio-baccigalupo-railsconf-2018\"\n  title: \"Inside Active Storage: a code review of Rails' new framework\"\n  raw_title: \"RailsConf 2018: Inside Active Storage: a code review of Rails' new framework by Claudio Baccigalupo\"\n  speakers:\n    - Claudio Baccigalupo\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Inside Active Storage: a code review of Rails' new framework by Claudio Baccigalupo\n\n    Rails 5.2 ships with a new library to support file uploads: Active Storage.\n\n    In this talk, we will analyze its internal code, learning how it integrates with Active Record and Action Pack to supply amazing features out of the box, from image previews to cloud storage.\n\n    We will review its class architecture and delve into the implementation of several Active Storage methods, such as has_one_attached and upload. On the way, we will better understand some Ruby patterns frequently used within Rails: meta-programming, macros, auto-loading, initializers, class attributes.\n  video_provider: \"youtube\"\n  video_id: \"-_w4uqoVSpw\"\n\n- id: \"shawn-herman-railsconf-2018\"\n  title: \"Engine Yard\"\n  raw_title: \"RailsConf 2018: Engine Yard - Shawn Herman\"\n  speakers:\n    - Shawn Herman\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"42fRu7C1qWU\"\n\n- id: \"tal-safran-railsconf-2018\"\n  title: \"GitHub and Rails - 10 Years Together\"\n  raw_title: \"RailsConf 2018: GitHub - Tal Safran\"\n  speakers:\n    - Tal Safran\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"0we4EHpMCMM\"\n\n- id: \"yiting-xdite-cheng-railsconf-2018\"\n  title: \"What's going on in the crypto world?\"\n  raw_title: 'RailsConf 2018: OTCBTC - Yiting \"Xdite\" Cheng'\n  speakers:\n    - Yi-Ting Cheng\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"hZ2-Vsq8ZCU\"\n\n- id: \"derek-prior-railsconf-2018\"\n  title: \"Up And Down Again: A Migration's Tale\"\n  raw_title: \"RailsConf 2018: Up And Down Again: A Migration's Tale by Derek Prior\"\n  speakers:\n    - Derek Prior\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: |-\n    Up And Down Again: A Migration's Tale by Derek Prior\n\n    You run rake db:migrate and rake db:schema:load regularly, but what do they actually do? How does rake db:rollback automatically reverse migrations and why can't it reverse all of them? How can you teach these tasks new tricks to support additional database constructs?\n\n    We'll answer all of this and more as we explore the world of schema management in Rails. You will leave this talk with a deep understanding of how Rails manages schema, a better idea of its pitfalls, and ready to bend it to your will.\n  video_provider: \"youtube\"\n  video_id: \"_wR4NIQNmOI\"\n\n- id: \"lightning-talks-railsconf-2018\"\n  title: \"Lightning Talks\"\n  raw_title: \"RailsConf 2018: Lightning Talks\"\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Ld414EypQzg\"\n  talks:\n    - title: \"Lightning Talk: Teck & Mike\"\n      start_cue: \"00:00:00\"\n      end_cue: \"00:01:00\"\n      id: \"teck-mike-lighting-talk-railsconf-2018\"\n      video_id: \"teck-mike-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Teck # TODO: missing last name\n        - Mike # TODO: missing last name\n\n    - title: \"Lightning Talk: LA Ruby Meetup\"\n      start_cue: \"00:01:00\"\n      end_cue: \"00:01:31\"\n      id: \"claudio-baccigalupo-lighting-talk-railsconf-2018\"\n      video_id: \"claudio-baccigalupo-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Claudio Baccigalupo\n      slides_url: \"https://www.meetup.com/laruby/\"\n\n    - title: \"Lightning Talk: Fiona\"\n      start_cue: \"00:01:31\"\n      end_cue: \"00:06:06\"\n      id: \"fiona-lighting-talk-railsconf-2018\"\n      video_id: \"fiona-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Fiona Voss\n\n    - title: \"Lightning Talk: Nynne Just Christoffersen\"\n      start_cue: \"00:06:06\"\n      end_cue: \"00:07:59\"\n      id: \"nynne-just-christoffersen-lighting-talk-railsconf-2018\"\n      video_id: \"nynne-just-christoffersen-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Nynne Just Christoffersen\n\n    - title: \"Lightning Talk: Jacklyn Ma\"\n      start_cue: \"00:07:59\"\n      end_cue: \"00:09:36\"\n      id: \"jacklyn-ma-lighting-talk-railsconf-2018\"\n      video_id: \"jacklyn-ma-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Jacklyn Ma\n\n    - title: \"Lightning Talk: Jingyi Chen\"\n      start_cue: \"00:09:36\"\n      end_cue: \"00:14:51\"\n      id: \"jingyi-chen-lighting-talk-railsconf-2018\"\n      video_id: \"jingyi-chen-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Jingyi Chen\n\n    - title: \"Lightning Talk: Front-end web apps in Ruby (Opal)\"\n      start_cue: \"00:14:51\"\n      end_cue: \"00:19:41\"\n      id: \"jamie-gaskins-lighting-talk-railsconf-2018\"\n      video_id: \"jamie-gaskins-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Jamie Gaskins\n      slides_url: \"http://clearwaterrb.org/\"\n\n    - title: \"Lightning Talk: Samay Sharma\"\n      start_cue: \"00:19:41\"\n      end_cue: \"00:24:38\"\n      id: \"samay-sharma-lighting-talk-railsconf-2018\"\n      video_id: \"samay-sharma-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Samay Sharma\n\n    - title: \"Lightning Talk: JSONAPI Suite alternative to GraphQL\"\n      start_cue: \"00:24:38\"\n      end_cue: \"00:29:38\"\n      id: \"lee-richmond-lighting-talk-railsconf-2018\"\n      video_id: \"lee-richmond-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Lee Richmond\n      description: |-\n        https://jsonapi-suite.github.io/jsonapi_suite/\n\n    - title: \"Lightning Talk: Free software for citizen participation\"\n      start_cue: \"00:29:38\"\n      end_cue: \"00:35:08\"\n      id: \"raimond-garcia-lighting-talk-railsconf-2018\"\n      video_id: \"raimond-garcia-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Raimond Garcia\n      description: |-\n        http://consulproject.org/en/\n\n    - title: \"Lightning Talk: Ruby for Good 2018\"\n      start_cue: \"00:35:08\"\n      end_cue: \"00:39:28\"\n      id: \"chris-lighting-talk-railsconf-2018\"\n      video_id: \"chris-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Christopher Sexton\n      description: |-\n        https://rubyforgood.org/2018\n\n    - title: \"Lightning Talk: Chris Lawrence - Why Is Chunky So We Are Chunky\"\n      start_cue: \"00:39:28\"\n      end_cue: \"00:44:45\"\n      id: \"chris-lawrence-lighting-talk-railsconf-2018\"\n      video_id: \"chris-lawrence-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Lawrence\n      description: |-\n        http://wicswac.org/\n\n    - title: \"Lightning Talk: Memex\"\n      start_cue: \"00:44:45\"\n      end_cue: \"00:51:14\"\n      id: \"andrew-louis-lighting-talk-railsconf-2018\"\n      video_id: \"andrew-louis-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Louis\n      description: |-\n        https://hyfen.net/memex/\n\n    - title: \"Lightning Talk: sqlite as a reference datastore\"\n      start_cue: \"00:51:14\"\n      end_cue: \"00:55:20\"\n      id: \"thomas-mcgoey-smith-lighting-talk-railsconf-2018\"\n      video_id: \"thomas-mcgoey-smith-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Thomas McGoey-Smith\n\n    - title: \"Lightning Talk: Heidi Waterhouse\"\n      start_cue: \"00:55:20\"\n      end_cue: \"01:00:59\"\n      id: \"heidi-waterhouse-lighting-talk-railsconf-2018\"\n      video_id: \"heidi-waterhouse-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Heidi Waterhouse\n\n    - title: \"Lightning Talk: Adam Cuppy\"\n      start_cue: \"01:00:59\"\n      end_cue: \"01:04:12\"\n      id: \"adam-cuppy-lighting-talk-railsconf-2018\"\n      video_id: \"adam-cuppy-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Cuppy\n\n    - title: \"Lightning Talk: Rails Camp South 2018\"\n      start_cue: \"01:04:12\"\n      end_cue: \"01:08:19\"\n      id: \"barret-clark-brittany-alexander-lighting-talk-railsconf-2018\"\n      video_id: \"barret-clark-brittany-alexander-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      description: |-\n        https://us-south.rails.camp/\n\n        May 7-9, 2018 - Dahlonaga, GA - @railscampsouth\n      speakers:\n        - Barret Clark\n        - Brittany Alexander\n\n    - title: \"Lightning Talk: Jordan Byron\"\n      start_cue: \"01:08:19\"\n      end_cue: \"01:10:41\"\n      id: \"jordan-byron-lighting-talk-railsconf-2018\"\n      video_id: \"jordan-byron-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Jordan Byron\n\n    - title: \"Lightning Talk: Mike Wheeler\"\n      start_cue: \"01:10:41\"\n      end_cue: \"01:14:24\"\n      id: \"mike-wheeler-lighting-talk-railsconf-2018\"\n      video_id: \"mike-wheeler-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Mike Wheeler\n\n    - title: \"Lightning Talk: Kenny Browne\"\n      start_cue: \"01:14:24\"\n      end_cue: \"01:19:42\"\n      id: \"kenny-browne-lighting-talk-railsconf-2018\"\n      video_id: \"kenny-browne-lighting-talk-railsconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Kenny Browne\n\n- id: \"edouard-chin-railsconf-2018\"\n  title: \"Upgrading Rails at Scale\"\n  raw_title: \"RailsConf 2018: Upgrading Rails at Scale by Edouard Chin\"\n  speakers:\n    - Edouard Chin\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-19\"\n  description: |-\n    Upgrading Rails at Scale by Edouard Chin\n\n    Upgrading Rails at Shopify has always been a tedious and slow process. One full upgrade cycle was taking as much time as it takes to release a new Rails version. Having a full time dedicated team working solely on upgrading our platform wasn’t the solution but instead a proper process and toolkit. In this talk I’d like to share the different techniques and strategies that allowed to perform our smoothest and fastest Rails upgrade ever.\n  video_provider: \"youtube\"\n  video_id: \"N2B5V4ozc6k\"\n\n- id: \"gabe-enslein-railsconf-2018\"\n  title: \"Postgres 10, Performance, and You\"\n  raw_title: \"RailsConf 2018: Postgres 10, Performance, and You by Gabe Enslein\"\n  speakers:\n    - Gabe Enslein\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-19\"\n  description: |-\n    Postgres 10, Performance, and You by Gabe Enslein\n\n    Postgres 10 is out this year, with a whole host of features you won't want to miss. Join the Heroku data team as we take a deep dive into parallel queries, native json\n  video_provider: \"youtube\"\n  video_id: \"8gXdLAM6B1w\"\n\n- id: \"chris-lopresto-railsconf-2018\"\n  title: \"Hot Swapping Our Rails Front End In Secret - A Rebrand Story\"\n  raw_title: \"RailsConf 2018: Hot Swapping Our Rails Front End In Secret - A Rebrand Story by Chris LoPresto\"\n  speakers:\n    - Chris LoPresto\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-19\"\n  description: |-\n    Hot Swapping Our Rails Front End In Secret - A Rebrand Story by Chris LoPresto\n\n    “Everything looks like this, but we want it to look like that.” This is the story of how the team at Betterment replaced our front end code base to launch our new brand. Across all our apps. In secret. And make everything responsive. In 8 weeks.\n\n    Rails conventions come in handy when a wholesale UI transformation is called for. Learn how we launched a design system, dark deployed an all-new view layer, and unveiled our new brand identity right on schedule.\n\n    We shipped a lot of code extremely quickly yet managed to elevate code quality and capabilities in the process.\n\n    Constraint breeds creativity.\n  video_provider: \"youtube\"\n  video_id: \"Egumr5KiTNI\"\n\n- id: \"sumeet-jain-railsconf-2018\"\n  title: \"Actionable Tactics for Leveling Up Junior Devs\"\n  raw_title: \"RailsConf 2018: Actionable Tactics for Leveling Up Junior Devs by Sumeet Jain\"\n  speakers:\n    - Sumeet Jain\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-19\"\n  description: |-\n    Actionable Tactics for Leveling Up Junior Devs by Sumeet Jain\n\n    We are told that junior developers are a secret weapon, but this alleged \"competitive advantage\" is so elusive! Typical advice about evolving talent can be broad, un-relatable, and impractical. Aren't there any specific and actionable tactics that teams can employ for leveling up new devs? (Yes, there are!)\n  video_provider: \"youtube\"\n  video_id: \"K0vxOBIyhF0\"\n\n- id: \"dinah-shi-railsconf-2018\"\n  title: \"Your first contribution (and beyond)\"\n  raw_title: \"RailsConf 2018: Your first contribution (and beyond) by Dinah Shi\"\n  speakers:\n    - Dinah Shi\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-19\"\n  description: |-\n    Your first contribution (and beyond) by Dinah Shi\n\n    Do you keep telling yourself you want to get into open source? Have you been thinking about contributing to Rails? Don’t know where to get started? Right here! Come learn about how to find an interesting issue to work on, set up your dev environment, and ask for help when you get stuck. We’ll also talk about what happens after the first patch and where to go from there.\n  video_provider: \"youtube\"\n  video_id: \"SUD9rj0rRxg\"\n\n- id: \"geoffrey-litt-railsconf-2018\"\n  title: \"Ruby: A Family History\"\n  raw_title: \"RailsConf 2018: Ruby: A Family History by Geoffrey Litt\"\n  speakers:\n    - Geoffrey Litt\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-19\"\n  description: |-\n    Ruby: A Family History by Geoffrey Litt\n\n    Rails is made possible by Ruby’s unique combination of deep dynamism and pragmatic elegance. In turn, Ruby inherited many of its core ideas from older languages including Lisp, Smalltalk, and Perl.\n\n    In this talk, we’ll take a tour of these languages and their myriad influences on Ruby, to better understand the foundations of our tools, improve our ability to use them to their full potential, and imagine how they might be further improved.\n  video_provider: \"youtube\"\n  video_id: \"ELMbK8aHo7w\"\n\n- id: \"craig-kerstiens-railsconf-2018\"\n  title: \"Five Sharding Data Models and Which is Right\"\n  raw_title: \"RailsConf 2018: Five Sharding Data Models and Which is Right by Craig Kerstiens\"\n  speakers:\n    - Craig Kerstiens\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-19\"\n  description: |-\n    Five Sharding Data Models and Which is Right by Craig Kerstiens\n\n    Sharding is a heated topic and many who have tried it have come away with a bad taste in their mouth. But it's also well proven that sharding your database is the true way to scale the data layer. From Instagram to Google to Salesforce, with large-enough data and with sufficiently demanding performance requirements, you need to shard in order to scale out. Using the lens of the Postgres open source database, I'll walk you through things to keep in mind to be successful with sharding, and which data model is the right approach for you.\n\n    This is a sponsored talk by Citus Data.\n  video_provider: \"youtube\"\n  video_id: \"RO6lIW5KQkw\"\n\n- id: \"yehuda-katz-railsconf-2018\"\n  title: \"Using Skylight to Solve Real-World Performance Problems\"\n  raw_title: \"RailsConf 2018: Using Skylight to Solve Real-World Performance Problems by Yehuda, Godfrey & Krystan\"\n  speakers:\n    - Yehuda Katz\n    - Godfrey Chan\n    - Krystan HuffMenne\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-19\"\n  description: |-\n    Using Skylight to Solve Real-World Performance Problems by Yehuda Katz, Godfrey Chan & Krystan HuffMenne\n\n    This is a sponsored talk by Skylight\n  video_provider: \"youtube\"\n  video_id: \"QlMqObmQCrI\"\n\n- id: \"daniel-azuma-railsconf-2018\"\n  title: \"Containerizing Rails: Techniques, Pitfalls, & Best Practices\"\n  raw_title: \"RailsConf 2018: Containerizing Rails: Techniques, Pitfalls, & Best Practices by Daniel Azuma\"\n  speakers:\n    - Daniel Azuma\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-19\"\n  description: |-\n    Techniques, Pitfalls, & Best Practices by Daniel Azuma\n\n    Ready to containerize your Rails application? Then this session is for you. We'll walk through the process of deploying a nontrivial Rails app to Kubernetes, focusing on effective container design. You'll learn techniques and best practices for constructing images and orchestrating your deployment, and you'll come away understanding how to optimize the performance, flexibility, and security of your containerized application.\n\n    This is a sponsored talk by Google Cloud Platform.\n  video_provider: \"youtube\"\n  video_id: \"kG2vxYn547E\"\n\n- id: \"eleanor-kiefel-haggerty-railsconf-2018\"\n  title: \"Here's to history: programming through archaeology\"\n  raw_title: \"RailsConf 2018: Here's to history: programming through archaeology by Eleanor Kiefel Haggerty\"\n  speakers:\n    - Eleanor Kiefel Haggerty\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-22\"\n  description: |-\n    RailsConf 2018: Here's to history: programming through archaeology by Eleanor Kiefel Haggerty\n\n    Does your git log output resemble an archaeological site from 500BC? Ransacked by Persians with some Spartan conflict? When we code and commit, our decisions, for better or worse, are preserved. As though in an archaeological record. Thanks to the archaeological record we can understand entire human cultures, but how much do we understand about the decisions developers are making today? Applying the same practices archaeologists utilise can help us understand the decisions developers are making in 2018.\n  video_provider: \"youtube\"\n  video_id: \"zXas0xT5JGA\"\n\n- id: \"amy-unger-railsconf-2018\"\n  title: \"Knobs, buttons & switches: Operating your application at scale\"\n  raw_title: \"RailsConf 2018: Knobs, buttons & switches: Operating your application at scale by Amy Unger\"\n  speakers:\n    - Amy Unger\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-05-22\"\n  description: |-\n    RailsConf 2018:Knobs, buttons & switches: Operating your application at scale by Amy Unger\n\n    Pilots have the flight deck, Captain Kirk had his bridge, but what do you have for managing failure in your application?\n\n    Every app comes under stress, whether it's from downstream failures to unmaintainable high load to a spike in intensive requests. We'll cover code patterns you can use to change the behavior of your application on the fly to gracefully fail.\n\n    You’ll walk away from this talk with tools you can have on hand to ensure you remain in control even when your application is under stress.\n  video_provider: \"youtube\"\n  video_id: \"KjfYoHxmCmI\"\n\n- id: \"james-adam-railsconf-2018\"\n  title: \"Here’s to the crazy ones\"\n  raw_title: \"RailsConf 2018: Here’s to the crazy ones by James Adam\"\n  speakers:\n    - James Adam\n  event_name: \"RailsConf 2018\"\n  date: \"2018-04-17\"\n  published_at: \"2018-06-06\"\n  description: |-\n    RailsConf 2018: Here’s to the crazy ones by James Adam\n\n    Have you ever had a crazy idea that you were quietly convinced was great, but that everyone else thought was dumb? Well guess what: the future of Rails is depending on you.\n\n    I’d like rewind time by more than ten years, to tell you about one particular crazy idea that almost everyone hated, until it quietly became one of the core architectural components of Rails.\n\n    At the same time, we’ll meet the crazy ones, the misfits, the rebels and the trouble makers that ended up shaping Rails as we know it… and maybe, just maybe, we will realise that we can be one of them too.\n  video_provider: \"youtube\"\n  video_id: \"h3xe-Rf4A6k\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2019/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaOq3HlRm9h_Q_WhWKqm5xc\"\ntitle: \"RailsConf 2019\"\nkind: \"conference\"\nlocation: \"Minneapolis, MN, United States\"\ndescription: \"\"\npublished_at: \"2019-05-20\"\nstart_date: \"2019-04-03\"\nend_date: \"2019-05-02\"\nyear: 2019\nbanner_background: \"#FEE683\"\nfeatured_background: \"#FEE683\"\nfeatured_color: \"#07243D\"\ncoordinates:\n  latitude: 44.977753\n  longitude: -93.2650108\n"
  },
  {
    "path": "data/railsconf/railsconf-2019/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"jameson-hampton-railsconf-2019\"\n  title: \"Walking A Mile In Your Users' Shoes\"\n  raw_title: \"RailsConf 2019 - Walking A Mile In Your Users' Shoes by Jameson Hampton\"\n  speakers:\n    - Jameson Hampton\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-20\"\n  published_at: \"2019-05-20\"\n  description: |-\n    RailsConf 2019 - Walking A Mile In Your Users' Shoes by Jameson Hampton\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Developing apps for users in different demographics is inherently differently than developing apps just for ourselves and for other programmers. Understanding the needs of our users and learning to foster empathy for them is just as much of a skill as learning Rails or ActiveRecord — and it’s a skill that’s relevant to all developers, regardless of their ability level or rung of the career ladder.\n\n    #railsconf #confreaks\n  video_provider: \"youtube\"\n  video_id: \"iu149MG-5ec\"\n\n- id: \"joel-hawksley-railsconf-2019\"\n  title: \"Rethinking the View Layer with Components\"\n  raw_title: \"RailsConf 2019 - Rethinking the View Layer with Components by Joel Hawksley\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-20\"\n  published_at: \"2019-05-20\"\n  description: |-\n    RailsConf 2019 - Rethinking the View Layer with Components by Joel Hawksley\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    While most of Rails has evolved over time, the view layer hasn’t changed much. At GitHub, we are incorporating the lessons of the last decade into a new paradigm: components. This approach has enabled us to leverage traditional object-oriented techniques to test our views in isolation, avoid side-effects, refactor with confidence, and perhaps most importantly, make our views first-class citizens in Rails.\n\n    #railsconf #confreaks\n  video_provider: \"youtube\"\n  video_id: \"y5Z5a6QdA-M\"\n\n- id: \"justin-searls-railsconf-2019\"\n  title: \"The Selfish Programmer\"\n  raw_title: \"RailsConf 2019 - The Selfish Programmer by Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-20\"\n  published_at: \"2019-05-20\"\n  description: |-\n    RailsConf 2019 - The Selfish Programmer by Justin Searls\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Using Ruby at work is great… but sometimes it feels like a job!\n\n    This year, I rediscovered the joy of writing Ruby apps for nobody but myself—and you can, too! Solo development is a great way to learn skills, find inspiration, and distill what matters most about software.\n\n    Building a real app on your own can be overwhelming, but this talk will make it easier. From development to monitoring, you'll build a toolset you can maintain yourself. You'll learn a few \"bad\" practices that will make your life easier. You may even find that selfish coding will make you a better team member at work!\n\n    #railsconf #confreaks\n  video_provider: \"youtube\"\n  video_id: \"k5thkp4ZXSI\"\n\n- id: \"james-dabbs-railsconf-2019\"\n  title: \"Refactoring Live: Primitive Obsession\"\n  raw_title: \"RailsConf 2019 - Refactoring Live: Primitive Obsession by James Dabbs\"\n  speakers:\n    - James Dabbs\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-20\"\n  published_at: \"2019-05-20\"\n  description: |-\n    RailsConf 2019 - Refactoring Live: Primitive Obsession by James Dabbs\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Let's roll up our sleeves and clean up some smelly code. In this session, we'll dig in to Primitive Obsession - what happens when our domain logic is all wrapped up in primitive data types? And most importantly, how do we untangle it?\n\n    #railsconf #confreaks\n  video_provider: \"youtube\"\n  video_id: \"LhX5COR8WXc\"\n\n- id: \"danielle-gordon-railsconf-2019\"\n  title: \"Webpacker vs Asset Pipeline\"\n  raw_title: \"RailsConf 2019 - Webpacker vs Asset Pipeline by Danielle Gordon\"\n  speakers:\n    - Danielle Gordon\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-20\"\n  published_at: \"2019-05-20\"\n  description: |-\n    RailsConf 2019 -Webpacker vs Asset Pipeline by Danielle Gordon\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n\n    Have you started using Webpacker or are you still doing everything with the asset pipeline? Do you not know what to expect if you start using Webpacker? Do you even need Webpacker? See what it's like to develop and maintain a Rails app with Webpacker or with just the asset pipeline side by side.\n\n    #railsconf #confreaks\n  video_provider: \"youtube\"\n  video_id: \"2v4ySqyua1s\"\n\n- id: \"david-heinemeier-hansson-railsconf-2019\"\n  title: \"Opening Keynote\"\n  raw_title: \"RailsConf 2019 - Opening Keynote by David Heinemeier Hansson\"\n  speakers:\n    - David Heinemeier Hansson\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-20\"\n  published_at: \"2019-05-20\"\n  description: |-\n    RailsConf 2019 - Opening Keynote by David Heinemeier Hansson\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    #railsconf #confreaks\n  video_provider: \"youtube\"\n  video_id: \"VBwWbFpkltg\"\n\n- id: \"ariel-caplan-railsconf-2019\"\n  title: \"Keynote: The Stories We Tell Our Children\"\n  raw_title: \"RailsConf 2019 - Keynote: The Stories We Tell Our Children by Ariel Caplan\"\n  speakers:\n    - Ariel Caplan\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-20\"\n  published_at: \"2019-05-20\"\n  description: |-\n    RailsConf 2019 - Keynote: The Stories We Tell Our Children by Ariel Caplan\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    #railsconf #confreaks\n  video_provider: \"youtube\"\n  video_id: \"XKqvtAxGQOs\"\n\n- id: \"molly-struve-railsconf-2019\"\n  title: \"Cache is King\"\n  raw_title: \"RailsConf 2019 - Cache is King by Molly Struve\"\n  speakers:\n    - Molly Struve\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-22\"\n  published_at: \"2019-05-22\"\n  description: |-\n    RailsConf 2019 - Cache is King by Molly Struve\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Sometimes your fastest queries can cause the most problems. I will take you beyond the slow query optimization and instead zero in on the performance impacts surrounding the quantity of your datastore hits. Using real world examples dealing with datastores such as Elasticsearch, MySQL, and Redis, I will demonstrate how many fast queries can wreak just as much havoc as a few big slow ones. With each example I will make use of the simple tools available in Ruby and Rails to decrease and eliminate the need for these fast and seemingly innocuous datastore hits.\n  video_provider: \"youtube\"\n  video_id: \"yN1rGZbwn9k\"\n\n- id: \"takashi-kokubun-railsconf-2019\"\n  title: \"Performance Improvement of Ruby 2.7 JIT in Real World\"\n  raw_title: \"RailsConf 2019 - Performance Improvement of Ruby 2.7 JIT in Real World by Takashi Kokubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-22\"\n  published_at: \"2019-05-22\"\n  description: |-\n    RailsConf 2019 - Performance Improvement of Ruby 2.7 JIT in Real World by Takashi Kokubun\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Have you ever tried MRI's JIT compiler in Ruby 2.6? Unfortunately it had not improved Rails application performance while it achieved a good progress on some other benchmarks.\n\n    Beyond the progress at Ruby 2.6, JIT development on Ruby 2.7 will be dedicated to improve performance of real-world applications, especially Ruby on Rails. Come and join this talk to figure out how it's going well and what you should care about when you use it on production.\n  video_provider: \"youtube\"\n  video_id: \"s4ACyFD8ES0\"\n\n- id: \"james-thompson-railsconf-2019\"\n  title: \"Building for Gracious Failure\"\n  raw_title: \"RailsConf 2019 - Building for Gracious Failure by James Thompson\"\n  speakers:\n    - James Thompson\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-22\"\n  published_at: \"2019-05-22\"\n  description: |-\n    RailsConf 2019 - Building for Gracious Failure by James Thompson\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Everything fails at some level, in some way, some of the time. How we deal with those failures can ruin our day, or help us learn and grow. Together we will explore some tools and techniques for dealing with failure in our software graciously. Together we'll gain insights on how to get visibility into failures, how to assess severity, how to prioritize action, and hear a few stories on some unusual failure scenarios and how they were dealt with.\n  video_provider: \"youtube\"\n  video_id: \"mWaev36MPdg\"\n\n- id: \"michael-toppa-railsconf-2019\"\n  title: \"Applying Omotenashi (Japanese customer service) to your work\"\n  raw_title: \"RailsConf 2019 - Applying Omotenashi (Japanese customer service) to your work by Michael Toppa\"\n  speakers:\n    - Michael Toppa\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-22\"\n  published_at: \"2019-05-22\"\n  description: |-\n    RailsConf 2019 - Applying Omotenashi (Japanese customer service) to your work by Michael Toppa\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    “There is customer service, and then there is Japanese customer service.” - Tadashi Yanai, CEO, Uniqlo\n\n    Americans visiting Japan are often dazzled by the quality of customer service they experience, but usually mistakenly perceive it as a well-executed form of customer service as they understand it from Western culture. The American notion of “the customer is always right,” does not apply in Japan, yet customer dissatisfaction is much less common. We’ll explore why this is, with some entertaining real-life examples, and discover lessons from it that we can apply to our work in the software industry.\n  video_provider: \"youtube\"\n  video_id: \"WJFdyqLo-pM\"\n\n- id: \"brady-kriss-railsconf-2019\"\n  title: \"Keynote: How we make good\"\n  raw_title: \"RailsConf 2019 - Keynote: How we make good by Brady Kriss\"\n  speakers:\n    - Brady Kriss\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-22\"\n  published_at: \"2019-05-22\"\n  description: |-\n    RailsConf 2019 - Keynote: How we make good by Brady Kriss\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    #railsconf #confreaks\n  video_provider: \"youtube\"\n  video_id: \"YyUa6_4cX-w\"\n\n- id: \"lightning-talks-railsconf-2019\"\n  title: \"Lightning Talks\"\n  raw_title: \"RailsConf 2019 - Lightning Talks by Various Speakers\"\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-22\"\n  published_at: \"2019-05-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"AI5wmnzzBqc\"\n  talks:\n    - title: \"Lightning Talk: Chat Etiquette\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:00:05\"\n      end_cue: \"00:01:21\"\n      id: \"jason-meller-lighting-talk-railsconf-2019\"\n      video_id: \"jason-meller-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Jason Meller\n\n    - title: \"Lightning Talk: Matthew Nielson\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:01:21\"\n      end_cue: \"00:02:28\"\n      id: \"matthew-nielson-lighting-talk-railsconf-2019\"\n      video_id: \"matthew-nielson-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Matthew Nielson\n\n    - title: \"Lightning Talk: Minneapolis Climate Action\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:02:28\"\n      end_cue: \"00:03:16\"\n      id: \"jonathan-slate-lighting-talk-railsconf-2019\"\n      video_id: \"jonathan-slate-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Jonathan Slate\n\n    - title: \"Lightning Talk: Why You Should Hire Me\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:03:16\"\n      end_cue: \"00:08:41\"\n      id: \"morgan-fogarty-lighting-talk-railsconf-2019\"\n      video_id: \"morgan-fogarty-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Morgan Fogarty\n\n    - title: \"Lightning Talk: Coinbase Service Framework (CSF) - Strong API Contracts in Rails\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:08:41\"\n      end_cue: \"00:12:51\"\n      id: \"michael-de-hoog-lighting-talk-railsconf-2019\"\n      video_id: \"michael-de-hoog-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael de Hoog\n\n    - title: \"Lightning Talk: Confreaks\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:12:51\"\n      end_cue: \"00:17:54\"\n      id: \"cindy-backman-lighting-talk-railsconf-2019\"\n      video_id: \"cindy-backman-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Cindy Backman\n\n    - title: \"Lightning Talk: Learn Enough Scholarship Program\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:17:54\"\n      end_cue: \"00:22:53\"\n      id: \"michael-hartl-lighting-talk-railsconf-2019\"\n      video_id: \"michael-hartl-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Hartl\n\n    - title: \"Lightning Talk: Graphiti.dev Alternative to GraphQL Honoring the Concept of RESTful Resource\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:22:53\"\n      end_cue: \"00:27:56\"\n      id: \"lee-richmond-lighting-talk-railsconf-2019\"\n      video_id: \"lee-richmond-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Lee Richmond\n\n    - title: \"Lightning Talk: Madrid's consulproject.org for participatory democracy\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:27:56\"\n      end_cue: \"00:32:59\"\n      id: \"raimond-garcia-lighting-talk-railsconf-2019\"\n      video_id: \"raimond-garcia-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Raimond Garcia\n\n    - title: \"Lightning Talk: ActionCable Testing PR #23211\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:32:59\"\n      end_cue: \"00:37:08\"\n      id: \"vladimir-dementyev-lighting-talk-railsconf-2019\"\n      video_id: \"vladimir-dementyev-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Vladimir Dementyev\n\n    - title: \"Lightning Talk: kirillian/shiplane\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:37:08\"\n      end_cue: \"00:42:09\"\n      id: \"john-epperson-lighting-talk-railsconf-2019\"\n      video_id: \"john-epperson-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - John Epperson\n\n    - title: \"Lightning Talk: rubymap.com\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:42:09\"\n      end_cue: \"00:43:47\"\n      id: \"lewis-buckley-lighting-talk-railsconf-2019\"\n      video_id: \"lewis-buckley-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Lewis Buckley\n\n    - title: \"Lightning Talk: AWS SDK streaming APIs\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:43:47\"\n      end_cue: \"00:48:39\"\n      id: \"jing-yi-chen-lighting-talk-railsconf-2019\"\n      video_id: \"jing-yi-chen-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Jing yi Chen\n\n    - title: \"Lightning Talk: trace_location gem based on TracePoint\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:48:39\"\n      end_cue: \"00:53:04\"\n      id: \"yoskiyaki-hirano-lighting-talk-railsconf-2019\"\n      video_id: \"yoskiyaki-hirano-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Yoskiyaki Hirano\n\n    - title: \"Lightning Talk: Computer Vision\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:53:04\"\n      end_cue: \"00:58:04\"\n      id: \"steve-crow-lighting-talk-railsconf-2019\"\n      video_id: \"steve-crow-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Steve Crow\n\n    - title: \"Lightning Talk: Nexmo APIs Example\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"00:58:04\"\n      end_cue: \"01:02:57\"\n      id: \"ben-greenberg-lighting-talk-railsconf-2019\"\n      video_id: \"ben-greenberg-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Ben Greenberg\n\n    - title: \"Lightning Talk: Stoicism for Developers, an Introduction\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"01:02:57\"\n      end_cue: \"01:07:26\"\n      id: \"andrew-neely-lighting-talk-railsconf-2019\"\n      video_id: \"andrew-neely-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Neely\n\n    - title: \"Lightning Talk: Rover on Rails - Bad Jokes and Good Dogs\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"01:07:26\"\n      end_cue: \"01:10:11\"\n      id: \"andrea-wayte-lighting-talk-railsconf-2019\"\n      video_id: \"andrea-wayte-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrea Wayte\n\n    - title: \"Lightning Talk: Finding Diversity\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"01:10:11\"\n      end_cue: \"01:14:48\"\n      id: \"tricia-ball-lighting-talk-railsconf-2019\"\n      video_id: \"tricia-ball-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Tricia Ball\n\n    - title: \"Lightning Talk: rspec bisect to find randomly failing test dependencies\"\n      event_name: \"RailsConf 2019\"\n      date: \"2019-05-22\"\n      start_cue: \"01:14:48\"\n      end_cue: \"1:18:53\"\n      id: \"dylan-andrews-lighting-talk-railsconf-2019\"\n      video_id: \"dylan-andrews-lighting-talk-railsconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Dylan Andrews\n\n- id: \"justin-collins-railsconf-2019\"\n  title: \"The Unreasonable Struggle of Commercializing Open Source\"\n  raw_title: \"RailsConf 2019 - The Unreasonable Struggle of Commercializing Open Source by Justin Collins\"\n  speakers:\n    - Justin Collins\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-22\"\n  published_at: \"2019-05-22\"\n  description: |-\n    RailsConf 2019 - The Unreasonable Struggle of Commercializing Open Source by Justin Collins\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    With at least $55 billion in open source-related acquisitions in 2018, you might think we finally figured out how to fund and monetize open source software. Unfortunately, we have only reached an awkward stage of growing pains! With conflicting goals, people are struggling to turn their OSS work into revenue while not losing the powerful open source effects which made the software successful in the first place.\n\n    From the perspective of someone who has gone through the pain of commercializing open source, let’s take a deeper look at the unexpected challenges and potential solutions.\n  video_provider: \"youtube\"\n  video_id: \"mCrOi9QQCwU\"\n\n- id: \"sam-phippen-railsconf-2019\"\n  title: \"Cleaning house with RSpec Rails 4\"\n  raw_title: \"RailsConf 2019 - Cleaning house with RSpec Rails 4 by Sam Phippen\"\n  speakers:\n    - Sam Phippen\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-22\"\n  published_at: \"2019-05-22\"\n  description: |-\n    RailsConf 2019 - Cleaning house with RSpec Rails 4 by Sam Phippen\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    RSpec Rails is RSpec's wrapper around Rails' testing infrastructure. The current stable version, 3.8, supports Rails  = 3.0, and Ruby  = 1.8.7, that's a lot of versions to support! With RSpec Rails 4, we're fundamentally changing how RSpec is versioned.\n\n    In this talk you'll see a pragmatic comparison of ways to version open source. You'll see how we ended up with RSpec's new strategy. You'll learn what's coming next : Rails 6.0 parallel testing and ActionCable tests. This talk focuses heavily on open source process, and is less technical, so should be accessible to folks of all levels.\n  video_provider: \"youtube\"\n  video_id: \"aPYNMsXju_A\"\n\n- id: \"john-beatty-railsconf-2019\"\n  title: \"Yes, Rails does support Progressive Web Apps\"\n  raw_title: \"RailsConf 2019 - Yes, Rails does support Progressive Web Apps by John Beatty\"\n  speakers:\n    - John Beatty\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-23\"\n  published_at: \"2019-05-23\"\n  description: |-\n    RailsConf 2019 - Yes, Rails does support Progressive Web Apps by John Beatty\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Progressive Web Apps are a constellation of conventions. Those conventions fit neatly into Rails, without the need to introduce a complicated Javascript front end. By embracing core Rails technologies like ActiveJob, ActionCable, Russian Doll Caching, and sprinkles of Stimulus, you can deliver powerful and immersive front end web apps.\n  video_provider: \"youtube\"\n  video_id: \"JOcs__ofsps\"\n\n- id: \"cecy-correa-railsconf-2019\"\n  title: \"The Joy of CSS\"\n  raw_title: \"RailsConf 2019 - The Joy of CSS by Cecy Correa\"\n  speakers:\n    - Cecy Correa\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-23\"\n  published_at: \"2019-05-23\"\n  description: |-\n    RailsConf 2019 - The Joy of CSS by Cecy Correa\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    “I try to avoid it” or “just use !important” are things I hear developers say when it comes to CSS. Writing CSS that yields beautiful websites is an art, just as writing well-organized, reusable CSS is a science. In this talk, we’ll mix both art and science to level up your knowledge of CSS. We’ll revisit the basics to build a stronger CSS foundation. Then, we’ll step it up to SCSS, Flex, and pseudo-classes to build more advanced logic. And lastly, we’ll take a peek at what’s coming next with CSS Variables, Grid, and Houdini. By the end of the talk, you’ll be excited to work on CSS again!\n  video_provider: \"youtube\"\n  video_id: \"J6foxlI3gfo\"\n\n- id: \"charles-nutter-railsconf-2019\"\n  title: \"JRuby on Rails: From Zero to Scale\"\n  raw_title: \"RailsConf 2019 - JRuby on Rails: From Zero to Scale by Charles Oliver Nutter & Thomas E Enebo\"\n  speakers:\n    - Charles Nutter\n    - Thomas E Enebo\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-23\"\n  published_at: \"2019-05-23\"\n  description: |-\n    RailsConf 2019 - JRuby on Rails: From Zero to Scale by Charles Oliver Nutter & Thomas E Enebo\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    JRuby is deployed by hundreds of companies around the world, running Rails and other services at higher speeds and with better scalability than any other runtime. With JRuby you get better utilization of system resources, the performance and tooling of the JVM, and a massive collection of libraries to add to your toolbox, all without leaving Ruby behind.\n\n    In this talk, we'll walk you through the early stages of using JRuby, whether for a new app or a migration from CRuby. We will show how to deploy your JRuby app using various services. We'll cover the basics of troubleshooting performance and configuring your system for concurrency. By the end of this talk, you’ll have the knowledge you need to save money and time by building on JRuby.\n  video_provider: \"youtube\"\n  video_id: \"hFs24XfNCF0\"\n\n- id: \"kyle-doliveira-railsconf-2019\"\n  title: \"Death by a thousand commits\"\n  raw_title: \"RailsConf 2019 - Death by a thousand commits by Kyle d'Oliveira\"\n  speakers:\n    - Kyle d'Oliveira\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-23\"\n  published_at: \"2019-05-23\"\n  description: |-\n    RailsConf 2019 - Death by a thousand commits by Kyle d'Oliveira\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    On the 1st commit, things are getting started. On the 10th commit, the feature is live and users are giving feedback. On the 100th commit, users are delighted to be using the application. But on the 1000th commit, users are unhappy with the responsiveness of the application and the developers are struggling to move at the velocity they once were. Does this sound familiar?\n\n    We will go over some of the pieces of technical debt that can accumulate and can cause application performance and development velocity issues, and the strategies Clio uses to keep these kinds of technical debt under control.\n  video_provider: \"youtube\"\n  video_id: \"-zIT_OEXhE4\"\n\n- id: \"mina-slater-railsconf-2019\"\n  title: \"Filling the Knowledge Gap: Debugging Edition\"\n  raw_title: \"RailsConf 2019 - Filling the Knowledge Gap: Debugging Edition by Mina Slater\"\n  speakers:\n    - Mina Slater\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-23\"\n  published_at: \"2019-05-23\"\n  description: |-\n    RailsConf 2019 - Filling the Knowledge Gap: Debugging Edition by Mina Slater\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    We’re generally never officially taught to debug. No one tells us at bootcamp or in online tutorials what to do when our code doesn’t work. It’s one of those learn-it-on-the-job sort of things and comes with experience. As early-career developers, we get a lot of syntax thrown at us when we’re first learning, but in actuality, the majority of our time is spent trying to fix broken code. But why should we slog through it alone? Let’s explore some Rails debugging techniques together!\n  video_provider: \"youtube\"\n  video_id: \"g1PxL1T4Z4s\"\n\n- id: \"aaron-patterson-railsconf-2019\"\n  title: \"Closing Keynote\"\n  raw_title: \"RailsConf 2019 - Closing Keynote by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-23\"\n  published_at: \"2019-05-23\"\n  description: |-\n    RailsConf 2019 - Closing Keynote by Aaron Patterson\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    #railsconf #confreaks\n  video_provider: \"youtube\"\n  video_id: \"8Dld5kFWGCc\"\n\n- id: \"leonardo-tegon-railsconf-2019\"\n  title: \"Maintaining a big open source project: lessons learned\"\n  raw_title: \"RailsConf 2019 - Maintaining a big open source project: lessons learned by Leonardo Tegon\"\n  speakers:\n    - Leonardo Tegon\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-23\"\n  published_at: \"2019-05-23\"\n  description: |-\n    RailsConf 2019 - Maintaining a big open source project: lessons learned by Leonardo Tegon\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    About a year ago, I started to maintain Devise - one of the most popular Ruby Gems available. I had no knowledge of the code and a little experience with open source from a side project I developed myself.\n\n    Obviously, this was a very challenging task and I made a lot of mistakes in the process. The good thing is I learned a lot too.\n\n    In this talk, I will share with you some of the lessons I learned that I think can be valuable not only for open source but for our day-to-day work too.\n  video_provider: \"youtube\"\n  video_id: \"rnOcDH_sgxg\"\n\n- id: \"chris-salzberg-railsconf-2019\"\n  title: \"The Elusive Attribute\"\n  raw_title: \"RailsConf 2019 - The Elusive Attribute by Chris Salzberg\"\n  speakers:\n    - Chris Salzberg\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-24\"\n  published_at: \"2019-05-24\"\n  description: |-\n    RailsConf 2019 - The Elusive Attribute by Chris Salzberg\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Is it a method? A database column? Over here, it's a field in a form. Over there, it's a parameter in a request. It's the thing we decorate in our views. It's the thing we filter in our controllers.\n\n    We call it an “attribute”, and it's all these things and more. We take it for granted, but this innocent little idea is a window into the beating heart of our web framework. Behind its magic are valuable lessons to be learned.\n\n    Join me as we delve beneath the surface of ActiveModel and ActiveRecord, to the complex abstractions that make attributes so powerful, and so elusive.\n  video_provider: \"youtube\"\n  video_id: \"PNNrmNTQx2s\"\n\n- id: \"lyle-mullican-railsconf-2019\"\n  title: \"No Such Thing as a Secure Application\"\n  raw_title: \"RailsConf 2019 - No Such Thing as a Secure Application by Lyle Mullican\"\n  speakers:\n    - Lyle Mullican\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-24\"\n  published_at: \"2019-05-24\"\n  description: |-\n    RailsConf 2019 - No Such Thing as a Secure Application by Lyle Mullican\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    A developer's primary responsibility is to ship working code, and by the way, it's also expected to be secure code. The definition of \"working\" may be quite clear, but the definition of \"secure\" is often surprisingly hard to pin down. This session will explore a few ways to help you define what application security means in your own context, how to build security testing and resilience into your development processes, and how to have more productive conversations about security topics with product and business owners.\n  video_provider: \"youtube\"\n  video_id: \"Ima3D7q8qCg\"\n\n- id: \"karl-entwistle-railsconf-2019\"\n  title: \"Automate your Home with Ruby\"\n  raw_title: \"RailsConf 2019 - Automate your Home with Ruby by Karl Entwistle\"\n  speakers:\n    - Karl Entwistle\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-24\"\n  published_at: \"2019-05-24\"\n  description: |-\n    RailsConf 2019 - Automate your Home with Ruby by Karl Entwistle\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    With the increasing number of home automation devices, our homes are getting smarter and smarter. How can Ruby help?\n\n    Instead of installing separate apps to control my many devices, I wanted to use HomeKit via Siri and the pre-installed Home app on any iOS device, for one unified experience.\n\n    This is a talk about how I created the first ever Ruby library for the HomeKit accessory protocol to bridge the gap between different platforms and just some of the exciting possibilities this could unleash.\n  video_provider: \"youtube\"\n  video_id: \"blsQhAqHVhE\"\n\n- id: \"genadi-samokovarov-railsconf-2019\"\n  title: \"Resolve Errors Straight from the Error Pages\"\n  raw_title: \"RailsConf 2019 - Resolve Errors Straight from the Error Pages by Genadi Samokovarov\"\n  speakers:\n    - Genadi Samokovarov\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-24\"\n  published_at: \"2019-05-24\"\n  description: |-\n    RailsConf 2019 - Resolve Errors Straight from the Error Pages by Genadi Samokovarov\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Raised exceptions in Rails 6 can hint the error pages to display a button that can invoke a resolving action. We call them actionable errors!\n\n    In this talk, we'll take a deep dive into what actionable errors are, and how they are dispatched through the Rails application errors handling mechanism.\n\n    We'll also write a small Rails plugin and use actionable errors to guide our users with better errors, and actions to resolve them. We'll learn how to define custom actionable errors and strategies around when and how to raise them to help our users to set up the plugin from the comfort of the error pages.\n  video_provider: \"youtube\"\n  video_id: \"ArqsmnCh-pE\"\n\n- id: \"jordan-raine-railsconf-2019\"\n  title: \"Code Spelunking: teach yourself how Rails works\"\n  raw_title: \"RailsConf 2019 - Code Spelunking: teach yourself how Rails works by Jordan Raine\"\n  speakers:\n    - Jordan Raine\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-24\"\n  published_at: \"2019-05-24\"\n  description: |-\n    RailsConf 2019 - Code Spelunking: teach yourself how Rails works by Jordan Raine\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Have you ever wondered how something works deep in the guts of Rails or been stuck when a README says one thing but the code acts another way? Guides and docs are often the best way to get started but when they fall short, you may need to get your hands dirty.\n\n    Using method introspection, this talk will show you ways to confidently explore Rails code. By looking at common problems inspired by real-world situations, learn how to dive into Rails and teach yourself how any feature works under-the-hood.\n\n    Let’s go spelunking!\n  video_provider: \"youtube\"\n  video_id: \"LiyLXklIQHc\"\n\n- id: \"shane-becker-railsconf-2019\"\n  title: \"From test && commit || revert to LIMBO\"\n  raw_title: \"RailsConf 2019 -  From test && commit || revert to LIMBO by Shane Becker\"\n  speakers:\n    - Shane Becker\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-05-25\"\n  description: |-\n    RailsConf 2019 -  From test && commit || revert to LIMBO by Shane Becker\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Kent Beck (TDD, eXtreme Programming, Agile Manifesto) has a couple new ideas. They both sound so terrible and impossible that they just might be totally amazing.\n\n    1. test && commit || revert If tests pass, commit everything. If they fail, revert everything. Automatically. Wild.\n\n    2. LIMBO. Anything that's committed is pushed. Anything that's committed by teammates is automatically pulled in while you work. So wild.\n\n    Does this work? Does it scale? Will I always be losing important progress because of a typo? Will this make me a better / faster / happier programmer?\n\n    We'll cover tools, process, deficiencies, mental models, and experiences. Show up and see what happens.\n  video_provider: \"youtube\"\n  video_id: \"Z_LoGqMugN0\"\n\n- id: \"brandon-weaver-railsconf-2019\"\n  title: \"The Action Cable Symphony - An Illustrated Musical Adventure\"\n  raw_title: \"RailsConf 2019 - The Action Cable Symphony - An Illustrated Musical Adventure by Brandon Weaver\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-05-25\"\n  description: |-\n    RailsConf 2019 - The Action Cable Symphony - An Illustrated Musical Adventure by Brandon Weaver\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Do you want to know what ActionCable is and how it works, but don't want to build another chat application to learn it? Well buckle up, because we've got a treat for you. You're going to learn with lemurs and classical music.\n\n    The ActionCable Symphony is an illustrated and musical talk that will explore how websockets work by using classical music. We'll be using select audience member phones to play it. Learn about ActionCable, websockets, latency concerns, client interfaces, JWT authentication, and more in this once-in-a-lifetime experience.\n\n    You haven't lived until you've experienced lemurs playing a symphony orchestra on your phone using Rails.\n  video_provider: \"youtube\"\n  video_id: \"tmJlos2CST4\"\n\n- id: \"john-feminella-railsconf-2019\"\n  title: \"Scalable Observability for Rails Applications\"\n  raw_title: \"RailsConf 2019 - Scalable Observability for Rails Applications by John Feminella\"\n  speakers:\n    - John Feminella\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-05-25\"\n  description: |-\n    RailsConf 2019 - Scalable Observability for Rails Applications by John Feminella\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Do you measure and monitor your Rails applications by alerting on metrics like CPU, memory usage, and request latency? Do you get large numbers of false positives, and wish you had fewer useless messages cluttering up your inbox? What if there were a better way to monitor your Rails applications that resulted in far more signal — and much less noise?\n\n    In this talk, we'll share an approach that's effective at measuring and monitoring distributed applications and systems. Through the application of a few simple core principles and a little bit of mathematical elbow grease, firms we've tried this with have seen significant results. By the end, you'll have the tools to ensure your applications will be healthier, more observable, and a lot less work to monitor.\n  video_provider: \"youtube\"\n  video_id: \"Z2OOAORL4KY\"\n\n- id: \"john-schoeman-railsconf-2019\"\n  title: \"Sprinkles of Functional Programming\"\n  raw_title: \"RailsConf 2019 - Sprinkles of Functional Programming by John Schoeman\"\n  speakers:\n    - John Schoeman\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-05-25\"\n  description: |-\n    RailsConf 2019 - Sprinkles of Functional Programming by John Schoeman\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Often in Rails apps there is a need to accomplish tasks where we are less interested in modeling domain concepts as collections of related objects and more interested in transforming or aggregating data. Instead of forcing object oriented design into a role that it wasn’t intended for, we can lean into ruby’s functional capabilities to create Rails apps with sprinkles of functional code to accomplish these tasks.\n  video_provider: \"youtube\"\n  video_id: \"toSedSFnzOE\"\n\n- id: \"philippe-creux-railsconf-2019\"\n  title: \"Event Sourcing made Simple\"\n  raw_title: \"RailsConf 2019 -  Event Sourcing made Simple by Philippe Creux\"\n  speakers:\n    - Philippe Creux\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-05-25\"\n  description: |-\n    RailsConf 2019 -  Event Sourcing made Simple by Philippe Creux\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Event Sourcing provides a full history of actions allowing us to understand how we get got there. Events can be replayed to backfill a new column, to fix a bug or to travel back in time. It is often described as a complex pattern that requires immutable databases, micro services and asynchronous communication.\n\n    In this talk, I will introduce you to Event Sourcing and present the simple framework we’ve built at Kickstarter. It runs on our Rails monolith, uses ActiveRecord models and a SQL database. And yet, it gives us super powers.\n  video_provider: \"youtube\"\n  video_id: \"ulF6lEFvrKo\"\n\n- id: \"kevin-newton-railsconf-2019\"\n  title: \"Pre-evaluation in Ruby\"\n  raw_title: \"RailsConf 2019 - Pre-evaluation in Ruby by Kevin Deisz\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-05-25\"\n  description: |-\n    RailsConf 2019 - Pre-evaluation in Ruby by Kevin Deisz\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Ruby is historically difficult to optimize due to features that improve flexibility and productivity at the cost of performance. Techniques like Ruby's new JIT compiler and deoptimization code help, but still are limited by techniques like monkey-patching and binding inspection.\n\n    Pre-evaluation is another optimization technique that works based on user-defined contracts and assumptions. Users can opt in to optimizations by limiting their use of Ruby's features and thereby allowing further compiler work.\n\n    In this talk we'll look at how pre-evaluation works, and what benefits it enables.\n  video_provider: \"youtube\"\n  video_id: \"7GqhHmfjemY\"\n\n- id: \"david-padilla-railsconf-2019\"\n  title: \"Localize your Rails application like a pro\"\n  raw_title: \"RailsConf 2019 - Localize your Rails application like a pro by David Padilla\"\n  speakers:\n    - David Padilla\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - Localize your Rails application like a pro by David Padilla\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    If you have ever worked in a Rails applications that needs to be available in more than one language you probably know how hard to maintain it can become over time, specially if more than one developer is involved in the process.\n\n    If you have never worked with localizations you probably will at some point in the future.\n\n    I want to share with you my experience. As a Spanish speaking developer I have worked in many multi-language apps, I have advice and a list of good practices that can help you in future localized projects.\n  video_provider: \"youtube\"\n  video_id: \"YqgLQ70K7uU\"\n\n- id: \"david-copeland-railsconf-2019\"\n  title: \"Database Design for Beginners\"\n  raw_title: \"RailsConf 2019 - Database Design for Beginners by David Copeland\"\n  speakers:\n    - David Copeland\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - Database Design for Beginners by David Copeland\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Rails’ migrations were a revelation when Rails came out, as it provided a way to manage your database schema, but also included many wonderful defaults that made all Rails developers pretty good at database schema design! But these defaults are just the beginning. Properly modeling your database can bring many benefits, such as fewer bugs, more reliable insights about your users or business, and developer understanding. We’ll talk about what makes a good database design by understanding the concept of normalization and why a properly normalized database yields benefits.\n  video_provider: \"youtube\"\n  video_id: \"1VsSXRPEBo0\"\n  slides_url: \"https://speakerdeck.com/davetron5000/database-design-for-beginners\"\n\n- id: \"hilary-stohs-krause-railsconf-2019\"\n  title: \"What I learned my first year as a full-time programmer\"\n  raw_title: \"RailsConf 2019 - What I learned my first year as a full-time programmer by Hilary Stohs Krause\"\n  speakers:\n    - Hilary Stohs-Krause\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - What I learned my first year as a full-time programmer by Hilary Stohs Krause\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    If you’re a junior developer who’s ever wondered if joining tech was a terrible idea, this is the talk for you!\n\n    I was equally exhilarated and terrified to start my first job in tech. The road to success is often zigzaggy, and my view as to whether it was worth it - and whether I would make it - varied from one day to the next. Four years later, those fears have been dispelled, as have several key misconceptions I had about tech (and being a programmer). In this talk, we’ll explore them together (plus a few badass Rails tricks to help you level up).\n  video_provider: \"youtube\"\n  video_id: \"227pgCnO05E\"\n\n- id: \"craig-buchek-railsconf-2019\"\n  title: \"ActiveRecord, the Repository Pattern, and You\"\n  raw_title: \"RailsConf 2019 - ActiveRecord, the Repository Pattern, and You by Craig Buchek\"\n  speakers:\n    - Craig Buchek\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - ActiveRecord, the Repository Pattern, and You by Craig Buchek\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    ActiveRecord is big. You just won't believe how vastly, hugely, mind-bogglingly big it is. It does a lot. Many would say it does too much. For me, the biggest issue is that it combines 2 distinct pieces of functionality — modeling the domain, and abstracting database access.\n\n    For years, I've dreamed of separating these 2, while still staying on Rails' golden path. I finally found a way to do that. The benefits are high: faster tests, simpler code, decoupling from the database, automatic schema migrations — without much downside. Let's take a look and see if it might be for you and your project.\n  video_provider: \"youtube\"\n  video_id: \"36LB8bfEeVc\"\n\n- id: \"richard-schneeman-railsconf-2019\"\n  title: \"The Life-Changing Magic of Tidying Active...\"\n  raw_title: \"RailsConf 2019 - The Life-Changing Magic of Tidying Active... by Richard Schneeman & Caleb Thompson\"\n  speakers:\n    - Richard Schneeman\n    - Caleb Hearth\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - The Life-Changing Magic of Tidying Active Record Allocations by Richard Schneeman & Caleb Thompson\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Your app is slow. It does not spark joy. In this talk, we will use memory allocation profiling tools to discover performance hotspots, even when they're coming from inside a library. We will use this technique with a real-world application to identify a piece of optimizable code in Active Record that ultimately leads to a patch with a substantial impact on page speed.\n  video_provider: \"youtube\"\n  video_id: \"WjhxAg2Y_5M\"\n\n- id: \"will-leinweber-railsconf-2019\"\n  title: \"When it all goes Wrong (with Postgres)\"\n  raw_title: \"RailsConf 2019 - When it all goes Wrong (with Postgres) by Will Leinweber\"\n  speakers:\n    - Will Leinweber\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - When it all goes Wrong (with Postgres) by Will Leinweber\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Your phone wakes you up in the middle of the night. Your app is down and you're on call to fix it. Eventually you track it down to \"something with the db,\" but what's wrong exactly? And of course, you're sure that nothing changed recently…\n\n    Knowing what to fix, and even where to start looking, is a skill that takes a while to develop. Especially since Postgres normally works very well most of the time, not giving you get practice!\n\n    In this talk, you'll learn not only the common failure cases and how to fix them, but also how to quickly figuring out what's wrong in the first place.\n  video_provider: \"youtube\"\n  video_id: \"B-iq4iHLnJU\"\n\n- id: \"chris-waters-railsconf-2019\"\n  title: \"Reset Yourself Free (The Joy of Destroying your DB Daily)\"\n  raw_title: \"RailsConf 2019 - Reset Yourself Free (The Joy of Destroying your DB Daily) by Chris Waters\"\n  speakers:\n    - Chris Waters\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - Reset Yourself Free (The Joy of Destroying your DB Daily) by Chris Waters\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    When was the last time you ran rake db:reset locally?\n\n    My guess is not recently. Nor do you think of doing it frequently. And I want to persuade you that deleting your precious local environment this way is a Very Good Thing Indeed.\n\n    Because, friends, db:reset will not only delete your database, but it will seed it too.\n\n    And by spending quality time with your seeds file, I believe you’ll make your entire development team more productive.\n\n    You’ll give your project the opportunity to grow its own shared development environment – a beautiful, idealistic place where all devs can talk through the same problem in the same context.\n\n    Ready to reset with me?\n  video_provider: \"youtube\"\n  video_id: \"8QvoCpRxbzI\"\n\n- id: \"alexandra-millatmal-railsconf-2019\"\n  title: \"Mentoring the way to a more diverse and inclusive workplace\"\n  raw_title: \"RailsConf 2019 - Mentoring the way to a more diverse and inclusive workplace by Alexandra Millatmal\"\n  speakers:\n    - Alexandra Millatmal\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - Mentoring the way to a more diverse and inclusive workplace by Alexandra Millatmal\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Often, the endeavors of hiring and mentoring junior engineers and of bolstering diversity and inclusion efforts are seen as “nice to haves” at best and “extraneous” (or even “impossible”!) at worst. But in reality, building diversity and inclusivity and fostering the ability to incorporate junior engineers go hand-in-hand. Engineering teams should approach each of these efforts in service of the other.\n\n    Together, we'll articulate the value of investing in mentorship efforts in terms of their impact on the ability to attract and retain diversity. You will walk away with a clearer understanding of the connection between the two efforts, and ideas for incorporating mentorship and D&I processes at your place of work.\n  video_provider: \"youtube\"\n  video_id: \"l2yKpQ1vo7A\"\n\n- id: \"steven-hicks-railsconf-2019\"\n  title: \"Getting Unstuck: Strategies For Solving Difficult Problems\"\n  raw_title: \"RailsConf 2019 - Getting Unstuck: Strategies For Solving Difficult Problems by Steven Hicks\"\n  speakers:\n    - Steven Hicks\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - Getting Unstuck: Strategies For Solving Difficult Problems by Steven Hicks\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Even with the simplest of problems, we can get stuck on code. It happens to engineers of all experience levels. This session will show you many strategies for getting unstuck.\n\n    We'll start by reframing the act of getting stuck as a positive. Then we'll talk about many strategies for identifying the problem and moving on. We'll discuss the psychology behind these strategies, and answer questions like \"Why do my best ideas come to me in the shower?\" Finally, we'll look at ways to harden yourself for the next time you get stuck.\n\n    Getting unstuck is a skill. This session will help you sharpen that skill, and prepare you for the next time you want to throw your keyboard out a window.\n  video_provider: \"youtube\"\n  video_id: \"3XscuivvUzI\"\n\n- id: \"amy-newell-railsconf-2019\"\n  title: \"Failure, Risk, and Shame: Approaching Suffering at Work\"\n  raw_title: \"RailsConf 2019 - Failure, Risk, and Shame: Approaching Suffering at Work by Amy Newell\"\n  speakers:\n    - Amy Newell\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - Failure, Risk, and Shame: Approaching Suffering at Work by Amy Newell\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    “Life is pain, highness. Anyone who says differently is selling something.” - The Dread Pirate Roberts\n\n    Are you dreading an email from work while you’re at this conference? Ruminating over last week’s outage? Worried you’re not learning enough because you can’t stay focused on the talks?\n\n    These are three kinds of suffering we all experience at work: uncertainty, failure, and insufficiency. All three are an inevitable part of our work. But more than that: they are necessary. Join me to learn some ways to approach suffering that can make you happier, healthier, and even a better developer.\n  video_provider: \"youtube\"\n  video_id: \"BRG6uIkHH8c\"\n\n- id: \"rufo-sanchez-railsconf-2019\"\n  title: \"Mindfulness and Meditation for the Uncertain Mind\"\n  raw_title: \"RailsConf 2019 - Mindfulness and Meditation for the Uncertain Mind by Rufo Sanchez\"\n  speakers:\n    - Rufo Sanchez\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - Mindfulness and Meditation for the Uncertain Mind by Rufo Sanchez\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    In recent years, mindfulness and meditation have both become capital-B Buzzwords. It’s hard to read anything about mental health or “wellness” without a mention, and meditation apps and services are a dime a dozen. Are you curious what they mean?… but also not really sure if they’re for you, or worried they’re for hippies or otherwise, y’know, not actually real?\n\n    Trust me, I wondered the same thing. In this talk, we’ll go over what mindfulness and meditation can be: effective tools to help observe the emotional reactions and thought patterns that rule our day - and our interactions with other humans - without us even realizing it. We’ll cover the basics in an objective, non-judgmental way, you’ll finally figure out what mindfulness and meditation are, and you’ll come away with resources to start becoming more mindful in your own life.\n  video_provider: \"youtube\"\n  video_id: \"qpvOlXXQ4tk\"\n\n- id: \"jennifer-tu-railsconf-2019\"\n  title: \"You Can’t Bubblebath The Burnout Away\"\n  raw_title: \"RailsConf 2019 - You Can’t Bubblebath The Burnout Away by Jennifer Tu\"\n  speakers:\n    - Jennifer Tu\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - You Can’t Bubblebath The Burnout Away by Jennifer Tu\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Ugh. Management. Agile was supposed to free us from that, right? Self-organized, cross-functional teams who get stuff done without that old-guard hierarchy. In this fauxtopia, some developers were more equal than others. Can we get the healthy parts back without the Lumberghs?\n\n    To bring back healthy engineering management we first must de-mystify and de-stigmatize the concept of management. In this talk we will: * Explore the context of management * Learn the responsibilities of management * Discuss the techniques of management\n\n    As a developer, you'll be equipped to understand, empathize with, and influence your boss. As a manager, you'll build a foundation to help you better serve your team.\n  video_provider: \"youtube\"\n  video_id: \"ccLbdZeaWl4\"\n\n- id: \"joel-quenneville-railsconf-2019\"\n  title: \"Beyond the whiteboard interview\"\n  raw_title: \"RailsConf 2019 - Beyond the whiteboard interview by Joel Quenneville & Rachel Mathew\"\n  speakers:\n    - Joel Quenneville\n    - Rachel Mathew\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-05-26\"\n  description: |-\n    RailsConf 2019 - Beyond the whiteboard interview by Joel Quenneville & Rachel Mathew\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    You've spent a lot of time preparing for this moment. Your palms are sweaty. You take a deep breath, walk into the room, and shake hands with the candidate. Welcome to the interview!\n\n    Interviewing can be intimidating and our industry is notorious for interviews that are arbitrary, academic, and adversarial. How can we do better?\n\n    Come be a fly on the wall for a real interview! At thoughtbot, we've put a lot of thought into crafting an interview that is both humane and allows us to accurately capture a candidate's strengths and weaknesses relative to the real-life work they will be doing.\n  video_provider: \"youtube\"\n  video_id: \"8FkkMkeJKU8\"\n\n- id: \"gabe-enslein-railsconf-2019\"\n  title: \"Postgres & Rails 6 Multi-DB: Pitfalls, Patterns, Performance\"\n  raw_title: \"RailsConf 2019 - Postgres & Rails 6 Multi-DB: Pitfalls, Patterns, Performance by Gabe Enslein\"\n  speakers:\n    - Gabe Enslein\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-28\"\n  published_at: \"2019-05-28\"\n  description: |-\n    RailsConf 2019 - Postgres & Rails 6 Multi-DB: Pitfalls, Patterns, Performance by Gabe Enslein\n    _________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________\n    This is a sponsored talk by Heroku.\n\n    Rails 6 has officially added Multiple database support, and the options are overwhelming. We're here to help you make the right architecture decisions for your app. In this talk, we will look at performance gains and pitfalls to some common patterns including: separation of concerns, high-load tables, and data segmentation. We'll talk about read replicas, eventual consistency, and real-time (or near real-time) requirements for a Rails application using multiple Postgres databases.\n  video_provider: \"youtube\"\n  video_id: \"a4OBp6edNaM\"\n\n- id: \"yehuda-katz-railsconf-2019\"\n  title: \"Inside Rails: The Lifecycle of a Request\"\n  raw_title: \"RailsConf 2019 - Inside Rails... by Yehuda Katz, Vaidehi Joshi, Godfrey Chan, & Krystan HuffMenne\"\n  speakers:\n    - Yehuda Katz\n    - Vaidehi Joshi\n    - Godfrey Chan\n    - Krystan HuffMenne\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-28\"\n  published_at: \"2019-05-28\"\n  description: |-\n    RailsConf 2019 - Inside Rails: The Lifecycle of a Request by Yehuda Katz, Vaidehi Joshi, Godfrey Chan, & Krystan HuffMenne\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    This is a sponsored talk by Skylight.\n\n    This breathtaking documentary series combines rare action, unimaginable scale, impossible locations and intimate moments captured from the depths of Rails' deepest internals. Together we will follow the lives of Rails' best loved, wildest and most elusive components. From the towering peaks of Rack to the lush green of Action Dispatch and the dry-sculpted crescents of Action Controller, our world is truly spectacular. Join the Skylight team on this incredible Journey to unearth the lifecycle of a Rails request.\n  video_provider: \"youtube\"\n  video_id: \"eK_JVdWOssI\"\n\n- id: \"william-horton-railsconf-2019\"\n  title: \"We Don't Code Alone: Building Learning Communities\"\n  raw_title: \"RubyConf 2019 - We Don't Code Alone: Building Learning Communities by William Horton\"\n  speakers:\n    - William Horton\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-28\"\n  published_at: \"2019-05-28\"\n  description: |-\n    RubyConf 2019 - We Don't Code Alone: Building Learning Communities by William Horton\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    How can we build communities that learn together? I owe my career to learning, starting from when I signed up for a bootcamp and plunged headfirst into Rails. I did not learn alone--I was surrounded by a group of people who came together around a set of educational goals.\n\n    After three years of working on software teams, I find myself intrigued by questions that take me back to my undergrad studies in the social sciences. In this talk I will weave together my personal experience in tech with social science research to start a conversation about creating inclusive, knowledge-sharing communities.\n  video_provider: \"youtube\"\n  video_id: \"aNtpucNPRr4\"\n\n- id: \"vladimir-dementyev-railsconf-2019\"\n  title: \"Terraforming legacy Rails applications\"\n  raw_title: \"RailsConf 2019 - Terraforming legacy Rails applications by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-28\"\n  published_at: \"2019-05-28\"\n  description: |-\n    RailsConf 2019 - Terraforming legacy Rails applications by Vladimir Dementyev\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Rails has been around for (can you imagine!) about 15 years. Most Rails applications are no longer MVPs, but they grew from MVPs and usually contain a lot of legacy code that \"just works.\"\n\n    And this legacy makes shipping new features harder and riskier: the new functionality have to co-exist with the code written years ago, and who knows what will blow up next?\n\n    I've been working on legacy codebases for the last few years, and I found turning legacy code into a legendary code to be a very exciting and challenging process.\n\n    I want to share the ideas and techniques I apply to make legacy codebases habitable and to prepare a breeding ground for the new features.\n  video_provider: \"youtube\"\n  video_id: \"-NKpMn6XSjU\"\n\n- id: \"ylan-segal-railsconf-2019\"\n  title: \"Bug-Driven Development\"\n  raw_title: \"RailsConf 2019 - Bug-Driven Development by Ylan Segal\"\n  speakers:\n    - Ylan Segal\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-28\"\n  published_at: \"2019-05-28\"\n  description: |-\n    RailsConf 2019 - Bug-Driven Development by Ylan Segal\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    This is a sponsored talk by Procore.\n\n    Have you ever gotten a bug report that is hard to believe and seemingly impossible to reproduce? Fixing these type of bugs can be draining, but often improves your understanding of the system. Come and learn the nuts and bolts of writing a good regression test that exposes the bug at the right level of abstraction. We will pay close attention to the structure of our code after the bug fix. Through incremental changes, we will drive improvement. I’ll show you how you can have code that is simpler to understand, follows project conventions, and is easier to test.\n  video_provider: \"youtube\"\n  video_id: \"vplY1cUCZ3w\"\n\n- id: \"shannon-skipper-railsconf-2019\"\n  title: \"Learn to Make an API-Backed Model with Square’s Ruby SDK\"\n  raw_title: \"RailsConf 2019 - Learn to Make an API-Backed Model with Square’s Ruby SDK by Shannon Skipper\"\n  speakers:\n    - Shannon Skipper\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-28\"\n  published_at: \"2019-05-28\"\n  description: |-\n    RailsConf 2019 - Learn to Make an API-Backed Model with Square’s Ruby SDK by Shannon Skipper\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    This is a sponsored talk by Square.\n\n    Active Model is flexible enough to provide a model interface to APIs, not just databases! We’ll look at how to go beyond just including ActiveModel::Model to implement a rich set of Active Model features, including the recently-added Rails 5 Attributes API. How does this compare to Active Resource? What does it look like in your controller? We’ll answer these questions by exploring an example that wraps Square’s Customers API in a full-featured Rails model.\n  video_provider: \"youtube\"\n  video_id: \"6h5TbKBnLws\"\n\n- id: \"jack-mccracken-railsconf-2019\"\n  title: \"Rails Security at Scale\"\n  raw_title: \"RailsConf 2019 - Rails Security at Scale by Jack McCracken\"\n  speakers:\n    - Jack McCracken\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-28\"\n  published_at: \"2019-05-28\"\n  description: |-\n    RailsConf 2019 - Rails Security at Scale by Jack McCracken\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    This is a sponsored talk by Shopify.\n\n    At Shopify we ship code. A lot of it. 1000 PRs a day. This means that our security team can’t reasonably take a look at every change that goes out to Shopify’s core product, let alone the hundreds of other projects deploying every day. Our team has developed some awesome tools and techniques for keeping Rails safe at scale, and we’d like to share them with you.\n  video_provider: \"youtube\"\n  video_id: \"MpsrQKieytY\"\n\n- id: \"samay-sharma-railsconf-2019\"\n  title: \"Optimizing your app by understanding your PostgreSQL database\"\n  raw_title: \"RailsConf 2019 - Optimizing your app by understanding your PostgreSQL database by Samay Sharma\"\n  speakers:\n    - Samay Sharma\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-28\"\n  published_at: \"2019-05-28\"\n  description: |-\n    RailsConf 2019 - Optimizing your app by understanding your PostgreSQL database by Samay Sharma\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    This is a sponsored talk by Citus Data.\n\n    I’m a Postgres person. Period. After talking to many Rails developers about their application performance, I realized many performance issues can be solved by understanding your database a bit better. So I thought I’d share the statistics Postgres captures for you and how you can use them to find slow queries, un-used indexes, or tables which are not getting vacuumed correctly. This talk will cover Postgres tools and tips for the above, including pgstatstatements, useful catalog tables, and recently added Postgres features such as CREATE STATISTICS.\n  video_provider: \"youtube\"\n  video_id: \"vfiz1J8mWEs\"\n\n- id: \"alex-reiff-railsconf-2019\"\n  title: \"Keeping Throughput High on Green Saturday\"\n  raw_title: \"RailsConf 2019 - Keeping Throughput High on Green Saturday by Alex Reiff\"\n  speakers:\n    - Alex Reiff\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-28\"\n  published_at: \"2019-05-28\"\n  description: |-\n    RailsConf 2019 - Keeping Throughput High on Green Saturday by Alex Reiff\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    This is a sponsored talk by Weedmaps.\n\n    Every April, we observe Earth Day and celebrate our planet’s beauty and resources, its oceans and trees. But only days earlier, another kind of tree is celebrated, and Weedmaps experiences its highest traffic of the year. Come see techniques we’ve used recently to lighten the latency on our most requested routes ahead of the elevated demand. Do you cache your API responses but want a lift in your hit ratio? Does that Elasticsearch best practice you know you’re ignoring cause nerves? We’ll pass our solutions to these problems — on the left-hand side.\n  video_provider: \"youtube\"\n  video_id: \"4WqQAFZcvu0\"\n\n- id: \"paul-zaich-railsconf-2019\"\n  title: \"How Checkr uses gRPC\"\n  raw_title: \"RailsConf 2019 - How Checkr uses gRPC by Paul Zaich & Ben Jacobson\"\n  speakers:\n    - Paul Zaich\n    - Ben Jacobson\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-28\"\n  published_at: \"2019-05-28\"\n  description: |-\n    RailsConf 2019 - How Checkr uses gRPC by Paul Zaich & Ben Jacobson\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    This is a sponsored talk by Checkr.\n\n    Checkr’s mission is to build a fairer future by improving understanding of the past. We are based in San Francisco and Denver. We have found some limitations in only using JSON-based RESTful APIs to communicate between services. Moving to gRPC has allowed us to better document interfaces and enforce stronger boundaries between services. In this session we will share the lessons we have learned while incorporating gRPC into our application, walkthrough setting up a new rails project with gRPC support, and how we plan to expand our usage of gRPC in the future.\n  video_provider: \"youtube\"\n  video_id: \"CtYNKOOZgsA\"\n\n- id: \"ben-bleything-railsconf-2019\"\n  title: \"Background Processing, Serverless Style\"\n  raw_title: \"RailsConf 2019 - Background Processing, Serverless Style by Ben Bleything\"\n  speakers:\n    - Ben Bleything\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  description: |-\n    RailsConf 2019 - Background Processing, Serverless Style by Ben Bleything\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Background processing is a critical component of many applications. The serverless programming model offers an alternative to traditional job systems that can reduce overhead while increasing productivity and happiness. We'll look at some typical background processing scenarios and see how to modify them to run as serverless functions. You'll see the advantages and trade-offs, as well as some situations in which you might not want to go serverless. We'll also talk about the serverless ecosystem, and you'll walk away with the knowledge and tools you need to experiment on your own.\n  video_provider: \"youtube\"\n  video_id: \"bcgxq8UvtyE\"\n\n- id: \"christopher-aji-slater-railsconf-2019\"\n  title: \"Commit Messages to the rescue!\"\n  raw_title: 'RailsConf 2019 - Commit Messages to the rescue! by Christopher \"Aji\" Slater'\n  speakers:\n    - Christopher \"Aji\" Slater\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  slides_url: \"https://speakerdeck.com/doodlingdev/commit-messages-to-the-rescue\"\n  description: |-\n    RailsConf 2019 - Commit Messages to the rescue! by Christopher \"Aji\" Slater\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    What if I told you there is more to a commit message than \"-m\"? Like source code time capsules, those pesky formalities can deliver wisdom and perspective about any code from the best possible source, the developer who just wrote it! Explore new facets of these time traveling rubber duck opportunities to increase their usefulness tenfold. Tools like templates, linters, hooks, and automation. Hear what Dr. Seuss can teach us about git, and don't miss the most helpful morsel of git customization around... how to open a new message in an editor other than vim!\n  video_provider: \"youtube\"\n  video_id: \"m9d1bsko4SE\"\n\n- id: \"eric-allen-railsconf-2019\"\n  title: \"New HotN+1ness -Hard lessons migrating from REST to GraphQL\"\n  raw_title: \"RailsConf 2019 - New HotN+1ness -Hard lessons migrating from REST to GraphQL by Eric Allen\"\n  speakers:\n    - Eric Allen\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  description: |-\n    RailsConf 2019 - New HotN+1ness -Hard lessons migrating from REST to GraphQL by Eric Allen\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Our desire to use new tools and learn new technologies backfires when we don't take the time to fully understand them.\n\n    In 2018, we migrated from a REST API to GraphQL. Patterns were introduced, copied, pasted, and one day we woke up with queries taking 6s and page load times less than 10s. Customers were complaining. How did we get here?\n\n    In this talk, we will discuss why we chose GraphQL, show practical examples of the mistakes we made in our implementation, and demonstrate how we eliminated all N+1 queries.\n\n    I'll answer the question, \"if I knew then what I know now... Would I stick with a REST API?\"\n  video_provider: \"youtube\"\n  video_id: \"gMm4andQdh0\"\n\n- id: \"braulio-carreno-railsconf-2019\"\n  title: \"From 0.10 to 5.2. The story of a 13 year old Rails app\"\n  raw_title: \"RailsConf 2019 - From 0.10 to 5.2. The story of a 13 year old Rails app by Braulio Carreno\"\n  speakers:\n    - Braulio Carreno\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  description: |-\n    RailsConf 2019 - From 0.10 to 5.2. The story of a 13 year old Rails app by Braulio Carreno\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Small-dollar donations were critical in the last election. The first version of the software that powers ActBlue, the main player in the space, was written in Rails 0.10.\n\n    During 13 years, 30K organizations have used the platform to raise $3 billion.\n\n    Some lessons we'll be sharing on this presentation: how to scale a monolith to process 1.5M RPM and 250 payments/sec, how to be productive with a 110K line code base, how to minimize the pain of Ruby/Rails upgrades and technical debt.\n\n    Intended for beginner to intermediate developers, managers, and anyone interested in building a lasting system.\n  video_provider: \"youtube\"\n  video_id: \"6RBCk5YTKFk\"\n\n- id: \"glenn-vanderburg-railsconf-2019\"\n  title: \"The 30-Month Migration\"\n  raw_title: \"RailsConf 2019 - The 30-Month Migration by Glenn Vanderburg\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  description: |-\n    RailsConf 2019 - The 30-Month Migration by Glenn Vanderburg\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    This talk describes how our team made deep changes to the data model of our production system over a period of 2.5 years.\n\n    Changing your data model is hard. Taking care of existing data requires caution. Exploring and testing possible solutions can be slow. Your new data model may require data completeness or correctness that hasn't been enforced for the existing data.\n\n    To manage the risk and minimize disruption to the product roadmap, we broke the effort into four stages, each with its own distinct challenges. I'll describe our rationale, process ... and the lessons we learned along the way.\n  video_provider: \"youtube\"\n  video_id: \"Nz-aU3vOFbw\"\n\n- id: \"nathan-l-walls-railsconf-2019\"\n  title: \"Growing internal tooling from the console up\"\n  raw_title: \"RailsConf 2019 - Growing internal tooling from the console up by Nathan L  Walls\"\n  speakers:\n    - Nathan L Walls\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  description: |-\n    RailsConf 2019 - Growing internal tooling from the console up by Nathan L  Walls\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Your site was built for your external customers first. Data or workflow problems are solved on the Rails console.\n\n    But, two years in, your app has grown. Identifying, researching, and fixing those data and workflow problems takes more of your time and attention. It frustrates your business stakeholders, your customers and, of course, you.\n\n    This talk will look at a Rails-based web store–including inventory, payment processing, fraud mitigation and customer notifications–and explore how we can build tools into our apps to discover when things go sideways and then help get things back on track.\n  video_provider: \"youtube\"\n  video_id: \"HkVfGhkw9QA\"\n\n- id: \"eileen-m-uchitelle-railsconf-2019\"\n  title: \"The Past, Present, and Future of Rails at GitHub\"\n  raw_title: \"RailsConf 2019 - The Past, Present, and Future of Rails at GitHub by Eileen M  Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  slides_url: \"https://speakerdeck.com/eileencodes/railsconf-and-balkan-ruby-2019-the-past-present-and-future-of-rails-at-github\"\n  description: |-\n    RailsConf 2019 - The Past, Present, and Future of Rails at GitHub by Eileen M  Uchitelle\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    On August 15, 2018 GitHub was deployed to production running Rails 5.2. This was a historic event; for years GitHub had been behind Rails and dependent on a custom fork of Rails 2.3. This talk will visit GitHub's past, including our tumultuous relationship with the Rails framework, and the grueling effort it took to get our application on the latest version. You’ll learn what mistakes to avoid and the reasons why such a difficult upgrade was worth it. We’ll explore what tracking master means for the future and establish that GitHub and Rails are in it together for the long haul.\n  video_provider: \"youtube\"\n  video_id: \"vIScxVu00bs\"\n\n- id: \"christopher-sexton-railsconf-2019\"\n  title: \"Unraveling the Cable: How ActionCable works\"\n  raw_title: \"RailsConf 2019 - Unraveling the Cable: How ActionCable works by Christopher Sexton\"\n  speakers:\n    - Christopher Sexton\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  description: |-\n    RailsConf 2019 - Unraveling the Cable: How ActionCable works by Christopher Sexton\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Rails ships with some handy features, and most of that functionality is there because we have common problems; and those problems need a default solution. You need quick two-way communication between your client and server. Action Cable can solve that quickly, and get you up and productive with out setting up expensive external add-ons and complex integrations.\n\n    This magic is wonderful until you need to untangle how websockets, connections, channels, consumers, and clients all fit together. Let's look under the hood and see how everything is woven together.\n  video_provider: \"youtube\"\n  video_id: \"XeqLONJsHkY\"\n\n- id: \"jeffrey-cohen-railsconf-2019\"\n  title: \"Modern Cryptography for the Absolute Beginner\"\n  raw_title: \"RailsConf 2019 - Modern Cryptography for the Absolute Beginner by Jeffrey Cohen\"\n  speakers:\n    - Jeffrey Cohen\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  description: |-\n    RailsConf 2019 - Modern Cryptography for the Absolute Beginner by Jeffrey Cohen\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Modern life depends on cryptography. Did you get cash from an ATM this week? Buy something online? Or pick up a prescription? A cryptographic algorithm was needed to make it happen!\n\n    Increasingly, developers need to become familiar with the essentials of encryption. But MD5, bcrypt, DES, AES, SSL, digital signatures, public keys - what are they for, and why do we care?\n\n    Armed with only a vanilla Rails application and beginner-level Ruby code, this talk will demonstrate the key ideas in modern cryptography. We will also take a peek ahead to quantum computing and its implications on cryptography.\n  video_provider: \"youtube\"\n  video_id: \"-cqD_SVXyEo\"\n\n- id: \"xavier-noria-railsconf-2019\"\n  title: \"Zeitwerk: A new code loader\"\n  raw_title: \"RailsConf 2019 - Zeitwerk: A new code loader by Xavier Noria\"\n  speakers:\n    - Xavier Noria\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  description: |-\n    RailsConf 2019 - Zeitwerk: A new code loader by Xavier Noria\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    In this talk we'll introduce Zeitwerk, the new code loader for gems and apps that is going to be the default in Rails 6.\n\n    We'll cover what motivated me to work on it, which are the issues in Rails autoloading and why is it fundamentally limited, usage by gems, and interesting aspects of the implementation.\n  video_provider: \"youtube\"\n  video_id: \"ulCBLpCU6aY\"\n\n- id: \"colleen-schnettler-railsconf-2019\"\n  title: \"How to migrate to Active Storage without losing your mind\"\n  raw_title: \"RailsConf 2019 - How to migrate to Active Storage without losing your mind by Colleen Schnettler\"\n  speakers:\n    - Colleen Schnettler\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-29\"\n  published_at: \"2019-05-29\"\n  description: |-\n    RailsConf 2019 - How to migrate to Active Storage without losing your mind by Colleen Schnettler\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Active storage works seamlessly in new rails applications - but how many of us only work on new applications? Migrating to Active Storage can be a daunting task on a production application. This talk will explain active storage, why you might want to use it, how it modifies your database, and the benefits and drawbacks of migrating your existing application. I’ll walk you through my painful journey migrating an existing application. You will leave this talk with a better understanding of the inner workings of active storage and with the confidence to tackle your own migration. This talk is appropriate for all levels of skill and no prior experience or knowledge of active storage is required.\n  video_provider: \"youtube\"\n  video_id: \"tZ_WNUytO9o\"\n\n- id: \"bari-a-williams-railsconf-2019\"\n  title: \"Keynote: Ethical Issues in the Law and Tech with Production Ideation, Creation & Shipping\"\n  raw_title: \"RailsConf 2019 - Keynote: Ethical Issues in the Law and Tech... by Bari A  Williams\"\n  speakers:\n    - Bari A Williams\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Keynote: Ethical Issues in the Law and Tech with Production Ideation, Creation & Shipping by Bari A  Williams\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n  video_provider: \"youtube\"\n  video_id: \"HBAra5J5c90\"\n\n- id: \"david-mcdonald-railsconf-2019\"\n  title: \"UserMailer.with(user: myself).life_advice.deliver(5.years.ago)...\"\n  raw_title: \"RailsConf 2019 - UserMailer.with(user: myself).life_advice.deliver(5.years.ago)... by David McDonald\"\n  speakers:\n    - David McDonald\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - UserMailer.with(user: myself).life_advice.deliver(5.years.ago)\n    Some Tips and Encouragement for Newcomers  by David McDonald\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n  video_provider: \"youtube\"\n  video_id: \"xDmPcClzqsw\"\n\n- id: \"jennifer-tu-railsconf-2019-congressive-management-techniq\"\n  title: \"Congressive Management Techniques: Gardening Your Team\"\n  raw_title: \"RailsConf 2019 - Congressive Management Techniques: Gardening Your Team by Jennifer Tu & Zee Spencer\"\n  speakers:\n    - Jennifer Tu\n    - Zee Spencer\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Congressive Management Techniques: Gardening Your Team by Jennifer Tu & Zee Spencer\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Ugh. Management. Agile was supposed to free us from that, right? Self-organized, cross-functional teams who get stuff done without that old-guard hierarchy. In this fauxtopia, some developers were more equal than others. Can we get the healthy parts back without the Lumberghs?\n\n    To bring back healthy engineering management we first must de-mystify and de-stigmatize the concept of management. In this talk we will: * Explore the context of management * Learn the responsibilities of management * Discuss the techniques of management\n\n    As a developer, you'll be equipped to understand, empathize with, and influence your boss. As a manager, you'll build a foundation to help you better serve your team.\n  video_provider: \"youtube\"\n  video_id: \"Pj4xBfJd9Mw\"\n\n- id: \"ryan-alexander-railsconf-2019\"\n  title: \"Hacking Verbal Communication Systems\"\n  raw_title: \"RailsConf 2019 - Hacking Verbal Communication Systems by Ryan Alexander\"\n  speakers:\n    - Ryan Alexander\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Hacking Verbal Communication Systems by Ryan Alexander\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Our native systems of conversational flow control might work fine for talking face to face, but they start to have problems when put into many of the conversational scenarios that arise as part of working on a modern development team. Other groups have faced similar challenges and come up with ways to facilitate and improve communication. I'm going to focus on a simple system of hand signals used by the Occupy movement who adapted them from the Quakers. These hand signals mitigate a number of problems with group discussions, including problems of communication over a laggy connection, and working with remotees.\n  video_provider: \"youtube\"\n  video_id: \"T7ykWqMjDsk\"\n\n- id: \"eric-tillberg-railsconf-2019\"\n  title: \"Communicate Like You're Remote\"\n  raw_title: \"RailsConf 2019 - Communicate Like You're Remote by Eric Tillberg\"\n  speakers:\n    - Eric Tillberg\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Communicate Like You're Remote by Eric Tillberg\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    This talk explores the benefits of purposefully choosing when to type and when to talk, using remote work as an example that promotes very different communication skills than in-office work. We will examine our default modes of communication (typing vs talking) and what biases they involve and then use that knowledge to talk in a more nuanced way about how to make the most of remote work and how to avoid the well-known pitfalls.\n  video_provider: \"youtube\"\n  video_id: \"5MCN54yvUCA\"\n\n- id: \"betsy-haibel-railsconf-2019\"\n  title: \"Teach by Learning; Lead by Teaching\"\n  raw_title: \"RailsConf 2019 - Teach by Learning; Lead by Teaching by Betsy Haibel\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Teach by Learning; Lead by Teaching by Betsy Haibel\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Have you ever caught yourself dictating code to a junior dev, rather than pairing? Or resorted to saying “best practice” because you knew you were right, but couldn’t articulate why? We can solve both these problems with “dialogic teaching,” a cornerstone of modern adult-education theory. In this talk, you’ll learn how to go from monologue to dialogue. You’ll learn how to teach developers of all skill levels in ways that center their goals and let you learn from them too. You’ll learn how to practice technical leadership when you’re right – and how to practice it when you’re wrong.\n  video_provider: \"youtube\"\n  video_id: \"AeyToE6f39U\"\n\n- id: \"jesse-belanger-railsconf-2019\"\n  title: \"Plays Well with Others: How to Stop Being a Jerk Today\"\n  raw_title: \"RailsConf 2019 - Plays Well with Others: How to Stop Being a Jerk Today by Jesse Belanger\"\n  speakers:\n    - Jesse Belanger\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Plays Well with Others: How to Stop Being a Jerk Today by Jesse Belanger\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Society acts as though jerks are incapable of changing their bad behavior, as though somebody called .freeze on them. We devise all kinds of strategies for avoiding or placating them, even at the expense of others' happiness.\n\n    What if it didn't have to be that way?\n\n    This talk approaches jerks as the mutable objects all people are. If you think you might be a jerk, or if you're looking for a new approach to the jerks in your life, this talk is for you! We'll cover what makes a jerk and what the positive alternative looks like. You'll leave with a set of practical ways to defuse negative urges, hold yourself accountable, and transform your behavior in a variety of situations, such as meetings, disagreements, or when things go wrong.\n  video_provider: \"youtube\"\n  video_id: \"plvnZmX774Q\"\n\n- id: \"vince-cabansag-railsconf-2019\"\n  title: \"Enter the Danger\"\n  raw_title: \"RailsConf 2019 - Enter the Danger by Vince Cabansag\"\n  speakers:\n    - Vince Cabansag\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Enter the Danger by Vince Cabansag\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    By entering the danger, you become the change the world needs. Do you know how to foster a culture of psychological safety? What are you doing to be inclusive for folks who identify as trans or gender non-conforming? What about people with a disability? Or women of color?\n\n    It’s well-known that our industry has poor racial and gender representation, yet we need more action from that awareness. This talk is about leaning in, being an ally, and making an impact. It takes courage to be a champion of diversity, equity, and inclusion.\n  video_provider: \"youtube\"\n  video_id: \"CT0fdA7MkFg\"\n\n- id: \"julien-fitzpatrick-railsconf-2019\"\n  title: \"Trans Eye for the Cis Ally: Ensuring an Inclusive Community\"\n  raw_title: \"RailsConf 2019 - Trans Eye for the Cis Ally: Ensuring an Inclusive Community by Julien Fitzpatrick\"\n  speakers:\n    - Julien Fitzpatrick\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Trans Eye for the Cis Ally: Ensuring an Inclusive Community by Julien Fitzpatrick\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Trans and non-binary people are becoming increasingly visible in the workplace, as well as in community spaces such as meetups and conferences. Most managers and event organizers want to be inclusive and welcoming but frequently, in spite of their best intentions, often come up short. Wouldn’t it be nice to have an actual non-binary trans person just tell you what you should be doing and why? VOILA! Allow me to swoop in and fix your interview process, your community event, even your office space! Can you believe? Shamazing!\n  video_provider: \"youtube\"\n  video_id: \"EtouMNnLIzM\"\n\n- id: \"eric-weinstein-railsconf-2019\"\n  title: \"Interview Them Where They Are\"\n  raw_title: \"RailsConf 2019 - Interview Them Where They Are by Eric Weinstein\"\n  speakers:\n    - Eric Weinstein\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Interview Them Where They Are by Eric Weinstein\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    As engineers, we've spent years mastering the art of conducting technical interviews—or have we? Despite being on both sides of the table dozens of times, how often have we come away feeling that the interview didn't work as well as it could have? How many of our interviews have been just plain bad? How much time do we spend designing and improving our own interview processes, and what signals should we be looking for when it comes to making those improvements? In this talk, we'll examine the technical interview in depth, developing a framework for interviewing candidates \"where they are\" by focusing on answering two major questions: how can we ensure our interview process identifies the people and skillsets we need to grow our teams, and how can we interview candidates in an inclusive way that maximizes their ability to demonstrate their competencies? By the end, we'll have built out a rich new set of tools you can immediately apply to the hiring process in your own organization.\n  video_provider: \"youtube\"\n  video_id: \"UrqIgMxLKkw\"\n\n- id: \"yoshinori-kawasaki-railsconf-2019\"\n  title: \"Troubleshoot Your RoR Microservices with Distributed Tracing\"\n  raw_title: \"RailsConf 2019 - Troubleshoot Your RoR Microservices with Distributed Tracing by Yoshinori Kawasaki\"\n  speakers:\n    - Yoshinori Kawasaki\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Troubleshoot Your RoR Microservices with Distributed Tracing by Yoshinori Kawasaki\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    In microservices architecture, it is often challenging to understand interaction and dependencies between individual components involved in an end-user request. Distributed tracing is a technique to improve observability of such microservices behaviors and to help understand performance bottlenecks, to investigate cascaded failures, or in general, to troubleshoot.\n\n    In this talk, I will show how we’ve implemented distributed tracing in Rails apps using OpenCensus, a set of vendor-neutral libraries to collect and export metrics and traces, and real world examples from our system that consists of about 100 microservices built with Ruby, Go, Python, Node and Rust. I will also discuss other methodologies to improve “observability” of Rails apps in microservices and future direction.\n\n    If you feel pain in troubleshooting microservices of Rails, you’ll love distributed tracing.\n  video_provider: \"youtube\"\n  video_id: \"osG78hxKY_g\"\n\n- id: \"jamie-gaskins-railsconf-2019\"\n  title: \"Service Architectures for Mere Mortals\"\n  raw_title: \"RailsConf 2019 - Service Architectures for Mere Mortals by Jamie Gaskins\"\n  speakers:\n    - Jamie Gaskins\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 -Service Architectures for Mere Mortals by Jamie Gaskins\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    You may have heard the terms \"Microservices\" and \"Service-Oriented Architecture\" in the past, but you've tried to understand them by googling and asking people and that only resulted in either an incomplete picture of how it works or, more likely, a bunch of wildly varied and even conflicting information. Or maybe you do understand them, but getting from your Rails monolith to that structure is a fuzzy path at best.\n\n    During this presentation, you will learn the basics of these ideas, the problems they solve, the tradeoffs they impose, and some ways to migrate to them.\n  video_provider: \"youtube\"\n  video_id: \"ZwS1NAlLHIQ\"\n\n- id: \"kevin-murphy-railsconf-2019\"\n  title: \"I Know I Can, But Should I? Evaluating Alternatives\"\n  raw_title: \"RailsConf 2019 - I know I can, but should I? Evaluating Alternatives by Kevin Murphy\"\n  speakers:\n    - Kevin Murphy\n  event_name: \"RailsConf 2019\"\n  slides_url: \"https://speakerdeck.com/kevinmurphy/i-know-i-can-but-should-i-evaluating-alternatives\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - I know I can, but should I? Evaluating Alternatives by Kevin Murphy\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    You can use a hammer to drive a screw into wood, but I’d recommend a screwdriver. Why? And when is a hammer the better option? This talk will propose a framework to use when comparing alternative technical choices. I won’t decide for you, but will leave you with a structure to apply in your decision-making process.\n\n    The ruby toolbox is vast. While Rails provides a default experience, it leaves plenty of room for alternatives. In learning how to do something, you may uncover different ways to accomplish the same goal. Determine which tool fits best in your situation with these lessons.\n  video_provider: \"youtube\"\n  video_id: \"2NiePLJVjNI\"\n\n- id: \"nate-berkopec-railsconf-2019\"\n  title: \"Profiling and Benchmarking 101\"\n  raw_title: \"RailsConf 2019 - Profiling and Benchmarking 101 by Nate Berkopec\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Profiling and Benchmarking 101 by Nate Berkopec\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    You know your Rails application is slow. Customers are complaining, and your ops teams are provisioning even more servers but it just isn't helping. What now? In order to fix a performance problem, you have to be able to measure it and diagnose where it is. Profiling and benchmarking are our two tools for doing just that. In this talk, you'll get an introduction to the tools available for benchmarking Ruby code, and how to use a profiler to figure out where your program spends its time.\n  video_provider: \"youtube\"\n  video_id: \"XL51vf-XBTs\"\n\n- id: \"sonja-peterson-railsconf-2019\"\n  title: \"Fixing Flaky Tests Like a Detective\"\n  raw_title: \"RailsConf 2019 - Fixing Flaky Tests Like a Detective by Sonja Peterson\"\n  speakers:\n    - Sonja Peterson\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Fixing Flaky Tests Like a Detective by Sonja Peterson\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Every test suite has them: a few tests that usually pass but sometimes mysteriously fail when run on the same code. Since they can’t be reliably replicated, they can be tough to fix. The good news is there’s a set of usual suspects that cause them: test order, async code, time, sorting and randomness. While walking through examples of each type, I’ll show you methods for identifying a culprit that range from capturing screenshots to traveling through time. You’ll leave with the skills to fix any flaky test fast, and with strategies for monitoring and improving your test suite's reliability overall.\n  video_provider: \"youtube\"\n  video_id: \"qTyoMg_rmrQ\"\n\n- id: \"matt-duszynski-railsconf-2019\"\n  title: \"rails db:migrate:safely\"\n  raw_title: \"RailsConf 2019 - rails db:migrate:safely by Matt Duszynski\"\n  speakers:\n    - Matt Duszynski\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - rails db:migrate:safely by Matt Duszynski\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    When you're dealing with fifty million records, simple migrations can become very dangerous. Come and learn from my mistakes instead of making your own. We'll talk about what's going on behind the scenes in your database, and how to safely write and run some common migrations. Remember, uptime begins at $HOME.\n  video_provider: \"youtube\"\n  video_id: \"KROgsx5zosA\"\n\n- id: \"jason-swett-railsconf-2019\"\n  title: \"Coding with an Organized Mind\"\n  raw_title: \"RailsConf 2019 - Coding with an Organized Mind by Jason Swett\"\n  speakers:\n    - Jason Swett\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Coding with an Organized Mind by Jason Swett\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Many developers fail to reach their productivity not due to lack of technical ability but for lack of mental organization and discipline. It's extremely helpful to always hold in one's mind the answer to the question: \"What exactly am I trying to achieve at this particular moment?\" It may sound like a no-brainer. However, many developers often can't answer this question. Here's how you can make sure that you always can.\n  video_provider: \"youtube\"\n  video_id: \"qUNuGqVQ-FI\"\n\n- id: \"coraline-ada-ehmke-railsconf-2019\"\n  title: \"Programming Empathy: Emotional State Machines\"\n  raw_title: \"RailsConf 2019 - Programming Empathy: Emotional State Machines by Coraline Ada Ehmke\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"RailsConf 2019\"\n  date: \"2019-05-31\"\n  published_at: \"2019-05-31\"\n  description: |-\n    RailsConf 2019 - Programming Empathy: Emotional State Machines by Coraline Ada Ehmke\n    _______________________________________________________________________________________________\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n    Empathy is the ability to understand and share the feelings of others. As developers, empathy for our users, our coworkers, and members of our community is an undervalued skill, since expressing emotions is often perceived as a weakness. But responding to the emotions of others is critical to working successfully on a team. This talk will frame emotions as neurological programs, with distinct triggers and multiple terminal states. The goal is to help us understand that when we act as fully realized human beings, and treat others the same way, the quality of our software will improve.\n  video_provider: \"youtube\"\n  video_id: \"-OMQ2SWNax4\"\n\n- id: \"marla-brizel-zeschin-railsconf-2019\"\n  title: \"Things I Wish I Knew Before Going Remote\"\n  raw_title: \"RailsConf 2019 - Things I Wish I Knew Before Going Remote by Marla Brizel Zeschin\"\n  speakers:\n    - Marla Brizel Zeschin\n  event_name: \"RailsConf 2019\"\n  date: \"2019-06-03\"\n  published_at: \"2019-05-22\"\n  description: |-\n    RailsConf 2019 - Things I Wish I Knew Before Going Remote by Marla Brizel Zeschin\n\n    _______________________________________________________________________________________________\n\n    Cloud 66 - Pain Free Rails Deployments\n    Cloud 66 for Rails acts like your in-house DevOps team to build, deploy and maintain your Rails applications on any cloud or server.\n\n    Get $100 Cloud 66 Free Credits with the code: RailsConf-19\n    ($100 Cloud 66 Free Credits, for the new user only, valid till 31st December 2019)\n\n    Link to the website: https://cloud66.com/rails?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    Link to sign up: https://app.cloud66.com/users/sign_in?utm_source=-&utm_medium=-&utm_campaign=RailsConf19\n    _______________________________________________________________________________________________\n\n    Remote work is just like working in an office - minus the soul-crushing commute. How hard could it be?\n\n    Spoiler: it's actually pretty hard.\n\n    When I went remote, I was so excited to not pack a lunch that I didn't consider the implications of a quasi-reliable Internet connection or the psychological impact of spending so much time at home.\n\n    As it turns out, going remote isn't just trading a highway commute for a hallway one. It requires new skills and a mindset shift. In this talk, you'll learn how to assess your needs as a remote worker and gain a set of tools to help you succeed for the long term.\n  video_provider: \"youtube\"\n  video_id: \"nUQ41-vBtdg\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2020/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZ-TzxlxdLvh6tDUfZHqm76\"\ntitle: \"RailsConf 2020 CE\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  RailsConf 2020.2\n  COUCH EDITION\n  Bringing some of RailsConf 2020 to your couch\npublished_at: \"2020-04-24\"\nstart_date: \"2020-05-05\"\nend_date: \"2020-05-05\"\nyear: 2020\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates: false\naliases:\n  - RailsConf 2020\n"
  },
  {
    "path": "data/railsconf/railsconf-2020/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"vladimir-dementyev-railsconf-2020-ce\"\n  title: \"Between Monoliths & Microservices\"\n  raw_title: \"RailsConf 2020 CE - Between Monoliths & Microservices by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Between Monoliths & Microservices by Vladimir Dementyev\n\n    \"Rails applications tend to turn into giant monoliths. Keeping the codebase maintainable usually requires architectural changes. Microservices? A distributed monolith is still a monolith. What about breaking the code into pieces and rebuild a monolithic puzzle out of them?\n\n    In Rails, we have the right tool for the job: engines. With engines, you can break your application into components—the same way as Rails combines all its parts, which are engines, too.\n\n    This path is full of snares and pitfalls. Let me be your guide in this journey and share the story of a monolith engine-ification.\"\n\n    __________\n\n    Vladimir is a mathematician who found his happiness in programming Ruby and Erlang, contributing to open source and being an Evil Martian. Author of AnyCable, TestProf and many yet unknown ukulele melodies.\n  video_provider: \"youtube\"\n  video_id: \"P6IXPM3zFTw\"\n\n- id: \"eileen-m-uchitelle-railsconf-2020-ce\"\n  title: \"Keynote: Technically, a Talk\"\n  raw_title: \"RailsConf 2020 CE - Keynote: Technically, a Talk by Eileen Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  slides_url: \"https://speakerdeck.com/eileencodes/technically-a-talk-railsconf-2020\"\n  description: |-\n    Keynote: Technically, a Talk by Eileen M. Uchitelle\n\n    \"Peer deep into Rails’ database handling and you may find the code overly complex, hard to follow, and full of technical debt. On the surface you’re right - it is complex, but that complexity represents the strong foundation that keeps your applications simple and focused on your product code. In this talk we’ll look at how to use multiple databases, the beauty (and horror) of Rails connection management, and why we built this feature for you.\n    \"\n    __________\n\n    Eileen M. Uchitelle is a Staff Software Engineer on the Ruby Architecture Team at GitHub and a member of the Rails Core team. She's an avid contributor to open source focusing on the Ruby on Rails framework and its dependencies. Eileen is passionate about scalability, performance, and making open source communities more sustainable and welcoming.\n  video_provider: \"youtube\"\n  video_id: \"vebtTRXAznU\"\n\n- id: \"aaron-patterson-railsconf-2020-ce\"\n  title: \"Aaron Patterson's Variety Show\"\n  raw_title: \"RailsConf 2020 CE - Aaron Patterson's Variety Show!\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Aaron Patterson's Variety Show!\n\n    I will talk about a variety of things related to puns, Rails, and puns on Rails\n\n    __________\n\n    Aaron is on the Ruby core team, the Rails core team, and the team that takes care of his cat, Gorby puff.  During the day he works for a small technology company.  Someday he will find the perfect safety gear to wear while extreme programming.\n  video_provider: \"youtube\"\n  video_id: \"9JEEabL90AA\"\n\n- id: \"alec-clarke-railsconf-2020-ce\"\n  title: \"Measure Twice, Cut Once\"\n  raw_title: \"RailsConf 2020 CE - Measure Twice, Cut Once by Alec Clarke\"\n  speakers:\n    - Alec Clarke\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Measure Twice, Cut Once by Alec Clarke\n\n    \"Woodworking and writing code go hand in hand, right?\n\n    On the surface these two activities may seem different, but the skills, tools, and mindset required to create quality furniture are consistent with the qualities required to write code that delights both the customer and developer.\n\n    As a woodworking hobbyist and software developer, I was amazed at how learning to build a table taught me to be a more impactful developer. In this talk we’ll discover how woodworking can teach us to move fast and not break things, be more consistent in our execution, and deliver lasting value to customers.\"\n\n    __________\n\n    Alec is a software developer and woodworking enthusiast who works remotely from Kingston, Ontario for Clio where he focuses on creating an enjoyable and effortless experience between law firms and their clients.\n  video_provider: \"youtube\"\n  video_id: \"7zW_BBiTLAY\"\n\n- id: \"alex-kitchens-railsconf-2020-ce\"\n  title: \"Building a Rails Controller From Scratch\"\n  raw_title: \"RailsConf 2020 CE - Building a Rails Controller From Scratch by Alex Kitchens\"\n  speakers:\n    - Alex Kitchens\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Building a Rails Controller From Scratch by Alex Kitchens\n\n\n    If you replaced ActionController with an implementation of your own, what would you have to build to get your app working again? In this talk, we'll do just that. We'll see how the controller interacts with the router to receive a request, process it, and return a response. We'll also rebuild controller features like Params, Controller Callbacks, and Rendering. In the end, we'll have a new functioning controller class called AwesomeController, and we will have seen what it takes to process a request in Rails.\n\n    __________\n\n    Alex Kitchens (@alexcameron89) is a software engineer at Stitch Fix, where he gets to embrace his love of Rails as a backend developer.\n  video_provider: \"youtube\"\n  video_id: \"jne5VFK-K_M\"\n\n- id: \"anna-rankin-railsconf-2020-ce\"\n  title: \"Deeper Understanding & Better Communication through Art\"\n  raw_title: \"RailsConf 2020 CE - Deeper Understanding & Better Communication through Art by Anna Rankin\"\n  speakers:\n    - Anna Rankin\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Deeper Understanding & Better Communication through Art by Anna Rankin\n\n    \"Understanding new concepts and complex systems is hard. Explaining them? That’s even harder.\n    Like anyone in a highly specialized career, software engineers may struggle to convey information concisely, confidently, and clearly to their technical and non-technical teammates. As a former illustrator and graphic designer, has found that visual art can be the key to both deeper understanding and clearer, more accessible communication. In this talk, we’ll explore why the ability to clearly communicate is so vital to mastering a complex topic, how to choose the right abstractions to present to a specific audience, and how a different medium can provide a new lens through which to view a familiar topic.\"\n\n    __________\n\n    As a tech lead, Anna spends her days at General Assembly helping a team of engineers deliver reliable, useful software that helps adults learn the skills they need to pursue a career that inspires them. Before transitioning to software, she was an undercover tech enthusiast working in roles ranging from graphic designer to ESL tutor — and even community relations for a small island! In her free time, she makes pixel art, designs punny stickers, and hangs out in dog parks with her pup.\n  video_provider: \"youtube\"\n  video_id: \"f2LcZqT1rZA\"\n\n- id: \"chelsea-troy-railsconf-2020-ce\"\n  title: \"Debugging: Techniques for Uncertain Times\"\n  raw_title: \"RailsConf 2020 CE - Debugging: Techniques for Uncertain Times by Chelsea Troy\"\n  speakers:\n    - Chelsea Troy\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Debugging: Techniques for Uncertain Times by Chelsea Troy\n\n    \"When we learn to code, we focus on writing features while we understand what the code is doing. When we debug, we don't understand what our code is doing. The less we understand, the less likely it is that our usual programming mindset—the one we use for feature development—can solve the problem.\n\n    It turns out, the skills that make us calmer, more effective debuggers also equip us to deal with rapid, substantial changes to our lives.\n\n    Whether you're uncertain about what's going on in your code, your life, or both, in this talk you'll learn debugging techniques to get you moving forward safely.\"\n\n    __________\n\n    \"Chelsea writes code on projects like the Zooniverse Citizen Science Mobile App and the NASA Landsat Image Processing Pipeline. She looks for clients who are saving the planet, advancing basic scientific research, or providing resources to underserved communities. She streams some programming sessions to YouTube, so you can watch her code (and narrate!) in real time. \n    Chelsea also teaches Mobile Software Development at the Master’s Program in Computer Science at the University of Chicago.\n\n    Chelsea flings barbells around for fun. She drives an electric cafe cruiser named Gigi.\"\n  video_provider: \"youtube\"\n  video_id: \"XqWJ5nKrZpY\"\n\n- id: \"brynn-gitt-railsconf-2020-ce\"\n  title: \"Enterprise Identity Management on Rails\"\n  raw_title: \"RailsConf 2020 CE -  Enterprise Identity Management on Rails by Brynn Gitt & Oliver Sanford\"\n  speakers:\n    - Brynn Gitt\n    - Oliver Sanford\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Enterprise Identity Management on Rails by Brynn Gitt & Oliver Sanford\n\n    Your team’s just inked that enterprise deal: 5000 seats at a well-known brand. But wait! Every week 100 people get hired or leave. Soon the customer's HR is complaining to the CEO and their engineers are hacking scripts against your undocumented API. Want to avoid this situation? We did too! Join us and learn how to automate identity management in Rails. We’ll demystify SCIM, peer under the hood of key Ruby auth and identity gems, and share insights to help you anticipate the twists in the road.\n\n    __________\n\n    \"Brynn Gitt has been working on Ruby on Rails apps for five years. She has a BSE in electrical engineering from the University of Iowa. She is a senior software engineer at Mode (http://mode.com/), and led Mode’s implementation of the SCIM API. Previously, she worked at Academia.edu\n\n    Oliver Sanford has been developing Ruby and JavaScript apps for over a decade. He holds a PhD in anthropology from Berkeley and works as a senior software engineer at Mode (http://mode.com/), where he helps enterprises of all sizes understand the stories in their data.\"\n  video_provider: \"youtube\"\n  video_id: \"hMdvur0YqQY\"\n\n- id: \"ufuk-kayserilioglu-railsconf-2020-ce\"\n  title: \"Peeling Away the Layers of the Network Stack\"\n  raw_title: \"RailsConf 2020 CE - Peeling Away the Layers of the Network Stack by Ufuk Kayserilioglu\"\n  speakers:\n    - Ufuk Kayserilioglu\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Peeling Away the Layers of the Network Stack by Ufuk Kayserilioglu\n\n    \"As Rails developers, we depend on network protocols to ensure the products we build are available and accessible to our users. Despite this, many of us are poorly aware of how the layers of the network stack actually work, or why they are there.\n\n    Understanding the things that happen between physical signals on the wire and your Rails application will help you hone your craft and level you up. Fortunately, the basic concepts of network protocols are easy to grasp, with a little guidance. So let's walk together through these concepts, and peel away the layers of the network stack one by one.\"\n\n    __________\n\n    Ufuk is a Physics PhD turned polyglot software developer. He is currently working as a Senior Production Engineer on the Ruby and Rails Infrastructure Team at Shopify. He has over 20 years of experience working with statically and dynamically typed languages and he brings that to Shopify for the adoption of better Ruby tooling and practices. He currently works remotely from Cyprus where he lives with his beloved wife and wonderful daughter. In his free time, he teaches computer science to high-school students.\n  video_provider: \"youtube\"\n  video_id: \"xPJgSca6TJc\"\n\n- id: \"david-heinemeier-hansson-railsconf-2020-ce\"\n  title: \"Keynote: Interview with David Heinemeier Hansson\"\n  raw_title: \"RailsConf 2020 CE - Keynote Interview with David Heinemeier Hansson\"\n  speakers:\n    - David Heinemeier Hansson\n    - Evan Phoenix\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Keynote Interview with David Heinemeier Hansson\n\n    David and Evan talk about Rails, work, and the world.\n\n    __________\n\n    David is the creator of Ruby on Rails, founder & CTO at Basecamp (formerly 37signals), best-selling author, Le Mans class-winning racing driver, public speaker, hobbyist photographer, and family man.\n  video_provider: \"youtube\"\n  video_id: \"OltCr8AWpWw\"\n\n- id: \"christian-bruckmayer-railsconf-2020-ce\"\n  title: \"Building a Performance Analytics Tool with ActiveSupport\"\n  raw_title: \"RailsConf 2020 CE - Building a Performance Analytics Tool with ActiveSupport by Christian Bruckmayer\"\n  speakers:\n    - Christian Bruckmayer\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Building a Performance Analytics Tool with ActiveSupport by Christian Bruckmayer\n\n    \"Setting up a performance analytics tool like NewRelic or Skylight is one of the first things many developers do in a new project. However, have you ever wondered how these tools work under the hood?\n\n    In this talk, we will build a basic performance analytics tool from scratch. We will deep dive into ActiveSupport instrumentations to collect, group and normalise metrics from your app. To persist these metrics, we will use a time series database and visualise the data on a dashboard. By the end of the talk, you will know how your favourite performance analytics tool works.\"\n\n    __________\n\n    \"Christian Bruckmayer originally from Nuremberg, Germany, but now calls Bristol, UK, his home. In his day job, he makes everyday cooking fun at Cookpad, the best place to find and share home cooked recipes. Since 2014 he is an avid open source contributor hacking for instance on JRuby, openSUSE Linux or various gems.\n\n    If he's not hacking Ruby, he's out doing what 'young' people do: traveling the world, skiing in the alps or going to concerts of his favourite band.\"\n  video_provider: \"youtube\"\n  video_id: \"2yc_kWJGLW8\"\n\n- id: \"elayne-juten-railsconf-2020-ce\"\n  title: \"Blank Page Panic! Creating Confidence with Test Driven Development\"\n  raw_title: \"RailsConf 2020 CE - Blank Page Panic! Creating Confidence with Test Driven ... by Elayne Juten\"\n  speakers:\n    - Elayne Juten\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Blank Page Panic! Creating Confidence with Test Driven Development by Elayne Juten\n\n    Have you ever stared at a blank feature spec file hoping for tests to magically appear? Well, you’re not alone! In this talk we’ll take a look at how the combination of Test-Driven Development, pseudocode and RSpec can help get you to your initial commit with confidence, one RSpec error at a time!\n\n    __________\n\n    Elayne Juten is a Software Engineer at Getty Images. As an early-career developer, she is passionate about finding ways to help build confidence in Ruby, Rails and RSpec.\n  video_provider: \"youtube\"\n  video_id: \"hrZktRv1XR4\"\n\n- id: \"emily-giurleo-railsconf-2020-ce\"\n  title: \"Successfully Onboarding a Junior Engineer in Three Steps\"\n  raw_title: \"RailsConf 2020 CE - Successfully Onboarding a Junior Engineer in Three Steps by Emily Giurleo\"\n  speakers:\n    - Emily Giurleo\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  slides_url: \"https://docs.google.com/presentation/d/1IKHnxYJ_z1C2Bk5qgeGzIvq4KCaJWbSv/edit#slide=id.p1\"\n  description: |-\n    Successfully Onboarding a Junior Engineer in Three Steps by Emily Giurleo\n\n    How you onboard someone to your team can have lasting effects on their professional success, growth, and happiness, but many teams treat onboarding as an afterthought. In this talk, you will learn how to successfully onboard a junior engineer in three steps, with the goals of building their trust, instilling confidence in their technical abilities, and enabling them to be an autonomous contributor to your team.\n\n    __________\n\n    Emily Giurleo is a software engineer and avid Rubyist. After graduating from MIT with a degree in computer science, she spent two years working as a Ruby developer at Codecademy. She now works at MongoDB, where she helps maintain the Ruby Driver and Mongoid Object-Document Mapper. In her spare time, she enjoys building tech for good causes, reading fantasy novels, and petting cats.\n  video_provider: \"youtube\"\n  video_id: \"q473dYrJiMQ\"\n\n- id: \"eric-hayes-railsconf-2020-ce\"\n  title: \"Wrangle Your SQL With Arel\"\n  raw_title: \"RailsConf 2020 CE - Wrangle Your SQL With Arel by Eric Hayes\"\n  speakers:\n    - Eric Hayes\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Wrangle Your SQL With Arel by Eric Hayes\n\n    \"You wanted to use those fancy Postgres features so you wrote raw SQL. Some time and a few more features go by and now your app is littered with SQL strings. Keep the power and lose the mess by building composable query objects that leverage Arel, the query builder under the hood of ActiveRecord.\n\n    Come to this talk and learn what Arel is, how to construct complex SQL with Ruby, and how to wrap it all up in model-like classes that play nice with Rails.\"\n\n    __________\n\n    Eric Hayes started using Ruby while working at a school district in 2006. He's been social distancing since 2016 working remotely for Red Hat. In 2017 he became the CTO of a small, all-remote business where he gets to play with everything from design to databases.\n  video_provider: \"youtube\"\n  video_id: \"8pQGzsDzYEo\"\n\n- id: \"hung-harry-doan-railsconf-2020-ce\"\n  title: \"Static Type Checking in Rails with Sorbet\"\n  raw_title: \"RailsConf 2020 CE - Static Type Checking in Rails with Sorbet by Hung Harry Doan\"\n  speakers:\n    - Hung Harry Doan\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Static Type Checking in Rails with Sorbet by Hung Harry Doan\n\n    \"Sorbet is a powerful static type-checking tool for Ruby. Type checking can catch errors early and improve the developer experience—and with the right tools, it can even be used with dynamic methods in Rails.\n\n    In this talk, we’ll cover the basics of type checking and share the lessons learned from our adoption of Sorbet type checking across our 2,500-file codebase in just six months. We’ll talk about the technical challenges we faced and how we solved them with a new Sorbet-Rails gem, which makes it easy to gradually integrate type checking into your Rails app & improve your team’s efficiency.\"\n\n    __________\n\n    Harry Doan is a Staff Software Engineer at the Chan Zuckerberg Initiative. He’s passionate about building great developer productivity tools and applications for the community. He created Sorbet-Rails to help Rails developers benefit from static type checking. In his free time, he can be found meditating or studying Buddhism teachings.\n  video_provider: \"youtube\"\n  video_id: \"APkKh40CF-8\"\n\n- id: \"hilary-stohs-krause-railsconf-2020-ce\"\n  title: \"Why we Worry About all the Wrong Things\"\n  raw_title: \"RailsConf 2020 CE - Why we Worry About all the Wrong Things by Hilary Stohs-Krause\"\n  speakers:\n    - Hilary Stohs-Krause\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Why we Worry About all the Wrong Things by Hilary Stohs-Krause\n\n    \"Modern humans aren’t great at risk assessment.\n\n    We often blithely ignore that which could harm us, and are conversely intimidated by things that are quite safe. This inability to recognize threat has vast implications for many aspects of our lives, including our careers.\n\n    Do you want to be less stressed? Make better decisions? Learn strategies for identifying (and dealing with!) unnecessary worry? Let's explore the root causes of fear and anxiety together, and discover how we can start to deliberately rewrite our instincts.\"\n\n    __________\n\n    \"Hilary Stohs-Krause is currently based in Madison, WI, where she's co-owner and software developer at Ten Forward Consulting. She came to tech by way of childhood website-building (a \"\"Buffy the Vampire Slayer\"\" fansite, to be exact).\n\n    She volunteers regularly with several tech and community organizations, and co-runs Madison Women in Tech, a local group with more than 2,000 members. She loves sci-fi/fantasy, board games and bourbon barrel-aged stouts. She tweets at @hilarysk.\"\n  video_provider: \"youtube\"\n  video_id: \"FgqnJIrR-mU\"\n\n- id: \"jameson-hampton-railsconf-2020-ce\"\n  title: \"Achieving Inclusivity Through Remote Work\"\n  raw_title: \"RailsConf 2020 CE - Achieving Inclusivity Through Remote Work by Jameson Hampton\"\n  speakers:\n    - Jameson Hampton\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Achieving Inclusivity Through Remote Work by Jameson Hampton\n\n    \"A strength of the tech industry is its ability to facilitate remote work. Remote work helps people — particularly people who are part of marginalized communities, such as folks who are undergoing a gender transition. We often talk about how to foster inclusive teams and remote work can be a big factor in that!\n\n    In this talk, you’ll learn about barriers that disproportionately affect underrepresented folks in tech, like health concerns, financial/geographical logistics and emotional burnout, as well as the ways working remotely can ease those burdens, and how to promote healthy distributed teams.\"\n\n    __________\n\n    Jamey is a non-binary adventurer from Buffalo, NY who wishes they were immortal so they’d have time to visit every coffee shop in the world. They’re a Rails engineer who recently took the plunge into DevRel, and they're a panelist on the podcast Greater than Code. In their free time, they do advocacy in the transgender community, write comics and travel as much as they can (which isn't very much right now)! They tweet at @jameybash.\n  video_provider: \"youtube\"\n  video_id: \"cZYPNPDzvYw\"\n\n- id: \"jason-meller-railsconf-2020-ce\"\n  title: \"Inoculating Rails Auth Against Bug Bounty Hunters\"\n  raw_title: \"RailsConf 2020 CE - Inoculating Rails Auth Against Bug Bounty Hunters by Jason Meller\"\n  speakers:\n    - Jason Meller\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Inoculating Rails Auth Against Bug Bounty Hunters by Jason Meller\n\n    You’ve rolled up your sleeves and built the most secure custom auth ever conceived by a dev team. Suddenly, your CTO informs you that your app will be participating in the Org's new Bug Bounty program. Terror fills your heart as you imagine security experts making mince-meat of your beautiful auth system. If only you knew their game plan... Kolide’s CEO, Jason Meller has been rolling his own Rails auth for over a decade and has the bug bounty receipts to prove it. In this talk, he will walk you through Kolide's actual bounty reports so you can level up your team’s auth system.\n\n    __________\n\n    Jason Meller is the CEO and Founder of Kolide, a security focused infrastructure analytics company. Jason has spent the majority of his 11 year career building tools and products in Ruby on Rails to aid cyber security professionals with the goal of ultimately making the field more accessible to newcomers.\n  video_provider: \"youtube\"\n  video_id: \"K7zo-wnvcLs\"\n\n- id: \"jesse-spevack-railsconf-2020-ce\"\n  title: \"Mistakes Were Made\"\n  raw_title: \"RailsConf 2020 CE - Mistakes Were Made by Jesse Spevack\"\n  speakers:\n    - Jesse Spevack\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Mistakes Were Made by Jesse Spevack\n\n    We picked the wrong technology. We worked in silos. We prematurely optimized. We introduced too many changes at once. And yet somehow we delivered a system that is integral to a shopping rewards app used by millions across the United States. I want to tell you the story of how the best of intentions led to crucial blunders. In this public, honest, and vulnerable post-mortem I will share the missteps I made so that you can avoid them.\n\n    __________\n\n    Jesse Spevack is a father of twins, skier, marathoner, and Senior Platform Engineer at Ibotta, a cash back for shopping app whose mission is to make every purchase rewarding. Before getting into the tech world, Jesse worked in public K-12 education for 11 years in teaching, school leadership, and consulting. Jesse transitioned from education into technology by way of the Turing School of Software Design, a Denver based code school with a Ruby-centric curriculum.\n  video_provider: \"youtube\"\n  video_id: \"2-m4_srVuNY\"\n\n- id: \"joel-hawksley-railsconf-2020-ce\"\n  title: \"Encapsulating Views\"\n  raw_title: \"RailsConf 2020 CE - Encapsulating Views by Joel Hawksley\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Encapsulating Views by Joel Hawksley\n\n    Unlike models and controllers, Rails views are not encapsulated. This makes them hard to reason about and difficult to test, leading us to use abstractions such as presenters and decorators. In this talk, we'll explore the inner workings of how Rails compiles and executes views today, the lessons we've learned building encapsulated views at GitHub over the past year, and how you can do the same with the support for 3rd-party component frameworks coming in Rails 6.1.\n\n    __________\n\n    Joel is a software engineer at GitHub. He works on the Design Systems team, leading the development of ViewComponent.\n  video_provider: \"youtube\"\n  video_id: \"YVYRus_2KZM\"\n\n- id: \"kent-beck-railsconf-2020-ce\"\n  title: \"Tidy First?\"\n  raw_title: \"RailsConf 2020 CE - Tidy First? by Kent Beck\"\n  speakers:\n    - Kent Beck\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Tidy First? by Kent Beck\n\n    \"Software design is an exercise in human relationships. \n\n    You have to change some ugly code. Should you tidy it first before you change it? Reflected in this simple, daily-repeated question are all the elements of software design: coupling/cohesion, economics, psychology, and sociology.\"\n\n    __________\n\n    In 45 years of programming, Kent hasn't been satisfied for more than a day at a time. Not with the tools, the techniques, the outcomes, and most of all not with his own understanding. These days he works at Gusto, the small business payroll and benefits provider.\n  video_provider: \"youtube\"\n  video_id: \"BFFY9Zor6zw\"\n\n- id: \"kevin-murphy-railsconf-2020-ce\"\n  title: \"Fake It While You Make It\"\n  raw_title: \"RailsConf 2020 CE - Fake It While You Make It by Kevin Murphy\"\n  speakers:\n    - Kevin Murphy\n  event_name: \"RailsConf 2020 CE\"\n  slides_url: \"https://speakerdeck.com/kevinmurphy/fake-it-while-you-make-it\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Fake It While You Make It by Kevin Murphy\n\n    \"We all write code to interface with external systems, like a web service or a message queue. Can you confidently write tests without requiring the system as a dependency? How can you shield users of your code from the inner workings of the interface? Explore one attempt to answer these questions.\n\n    There's no shortage of tools at your disposal to solve these problems. This talk will introduce some available options, provide guidance on when one approach may be more appropriate than another, and discuss how to use these tools together to ease the testing process.\"\n\n    __________\n\n    \"Kevin spent more time investigating, refactoring, and rewriting tests for the project that prompted this talk than he did writing the actual implementation.\n\n    Kevin lives near Boston, where he is a Software Developer at The Gnar Company.\"\n  video_provider: \"youtube\"\n  video_id: \"iEfpAp2sqiw\"\n\n- id: \"krystan-huffmenne-railsconf-2020-ce\"\n  title: \"Inside Rails: The Lifecycle of a Response\"\n  raw_title: \"RailsConf 2020 CE - Inside Rails: The Lifecycle of a Response by Krystan HuffMenne\"\n  speakers:\n    - Krystan HuffMenne\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Inside Rails: The Lifecycle of a Response by Krystan HuffMenne\n\n    This breathtaking documentary series combines rare action, unimaginable scale, impossible locations and intimate moments captured from the deepest depths of Rails internals. Last year, we followed the lifecycle of best loved, wildest and most elusive Rails components through a request, from the browser to a controller action. This year, our journey takes us across the great text/plain, following the flow of HTTP streams, taking in the spectacular Action View as we find our way back to the browser. Join us to unearth the amazing lifecycle of a Rails response.\n\n    __________\n\n    Krystan HuffMenne is an engineer at Tilde, where she works on Skylight, the smart Rails profiler. She writes code in Ruby, JavaScript, and Instant Pot. She’s a Florida-native living in Portland, OR with her husband and two kids.\n  video_provider: \"youtube\"\n  video_id: \"edjzEYMnrQw\"\n\n- id: \"kyle-doliveira-railsconf-2020-ce\"\n  title: \"Communicating with Cops\"\n  raw_title: \"RailsConf 2020 CE - Communicating with Cops by Kyle d'Oliveira\"\n  speakers:\n    - Kyle d'Oliveira\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Communicating with Cops by Kyle d'Oliveira\n\n    \"As the number of developers grows within an organization, how do you keep others informed of best practices, or patterns that caused problems in the past? Is there a lot of tribal knowledge or documentation that developers need to memorize? That is a recipe for cognitive overload.\n\n    Alternatively, we can use Rubocop to codify some best practices or common traps to avoid. This talk will dive into how Rubocop can be used to not only enforce styling but also keep problematic patterns out, while also providing the motivation and context for enforcing it.\"\n\n    __________\n\n    Based in Vancouver, Canada, Kyle is a jack of all trades and a master of some; at least he thinks so. He works as a staff software developer to readily turn abstract ideas into working pieces of software. He has worked on every major Rails version, and remembers the days when everyone implemented their own authentication system. When not developing, he enjoys picking up really heavy objects so that they can be put back down again.\n  video_provider: \"youtube\"\n  video_id: \"ws_8ie6TMtA\"\n\n- id: \"mark-hutter-railsconf-2020-ce\"\n  title: \"Can ActiveStorage Serve Images for the Modern Web?\"\n  raw_title: \"RailsConf 2020 CE - Can ActiveStorage Serve Images for the Modern Web? by Mark Hutter\"\n  speakers:\n    - Mark Hutter\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Can ActiveStorage Serve Images for the Modern Web? by Mark Hutter\n\n    \"It’s a simple question: can ActiveStorage be used for image serving in your modern web apps? The answer is not so simple. Can it handle the speed requirements and size specifications of images that the modern web browsers deems as “fast”?\n\n    We’ll look at the out-of-the-box approach ActiveStorage takes on asset serving, where it works well - resizing, usability, and security, and where we run into rough edges - image load times, CDN integration, and next gen image format storage. And then we’ll look at one pattern working in production today.\"\n\n    __________\n\n    I am 11 years into my career in the software development industry. This adventure has allowed me to pursue a range of technology specialties from SQL, Java, Ruby, Javascript, and Go. I am a husband and father, and there is nothing more important to me than family. I love food. All food. I have an eternal ongoing pursuit of the best quality audio experience I can find in headphones.\n  video_provider: \"youtube\"\n  video_id: \"MfaWl2-U_Zw\"\n\n- id: \"nelson-wittwer-railsconf-2020-ce\"\n  title: \"The Circle Of Lifecycle Events\"\n  raw_title: \"RailsConf 2020 CE - The Circle Of Lifecycle Events by Nelson Wittwer\"\n  speakers:\n    - Nelson Wittwer\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    The Circle Of Lifecycle Events by Nelson Wittwer\n\n    \"To the new software developer wanting to build a web app with Rails, callbacks and associations are gifts from the gods. As your application grows in complexity however, you may notice your favorite tools have actually turned on you. New users suddenly aren't getting welcome emails and you've somehow orphaned associations. Come learn proven patterns for managing lifecycle events for associated records in a way that sparks joy.\"\n\n    __________\n\n    Nelson has spent most of his career working within Rails typically building new startups/products but has also maintained and iterated on platforms at scale supporting tens of millions of users. Nelson is a personable guy who loves to make people laugh.  Nelson currently lives in the Raleigh/Durham area and works for MX.com building banking/fintech products.\n  video_provider: \"youtube\"\n  video_id: \"db-FEuSLIyc\"\n\n- id: \"nikolay-sverchkov-railsconf-2020-ce\"\n  title: \"Authorization in the GraphQL era\"\n  raw_title: \"RailsConf 2020 CE - Authorization in the GraphQL era by Nikolay Sverchkov\"\n  speakers:\n    - Nikolay Sverchkov\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Authorization in the GraphQL era by Nikolay Sverchkov\n\n    \"More and more teams choose GraphQL as the transport protocol for their projects. Switching the paradigm brings many benefits but comes at the price of figuring out how to deal with the well-known problems in this new world. Let’s talk about a particular one—access control organization.\n\n    In this talk, I’d like to discuss the differences between graph nodes and controller actions when dealing with user permissions, the pattern of crafting authentication, and authorization in Rails applications with GraphQL API and demonstrate the options we have in our ecosystem.\"\n\n    __________\n\n    Creative Back-end developer at Evil Martians\n  video_provider: \"youtube\"\n  video_id: \"WuvlXZvqIMg\"\n\n- id: \"noel-rappin-railsconf-2020-ce\"\n  title: \"Building a Mentorship Program\"\n  raw_title: \"RailsConf 2020 CE - Building a Mentorship Program by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Building a Mentorship Program by Noel Rappin\n\n    Mentorship is a great way for a newer developer to benefit from the experience of a more senior developer. While there are lots of available resources on how to be a good mentor or mentee, there are far fewer guidelines on how to set up a mentoring program within your engineering organization. I'm doing this now, and I'll share the process with you: why we decided to start a team-wide mentorship program, how we got volunteers and how we matched them, and how we followed up and what worked and what didn't. You'll get everything you need to start a mentorship program at your organization.\n\n    __________\n\n    Noel Rappin is a Staff Engineer at Root Insurance. Noel has authored multiple technical books, including \"Modern Front End Development For Rails\" and \"Rails 5 Test Prescriptions\". He also hosted the podcast Tech Done Right. Follow Noel on Twitter @noelrap, and online at http://www.noelrappin.com.\n  video_provider: \"youtube\"\n  video_id: \"aovuLQm75Vw\"\n\n- id: \"paul-zaich-railsconf-2020-ce\"\n  title: \"The Sounds of Silence: Lessons from an 18 hour API outage\"\n  raw_title: \"RailsConf 2020 CE - The Sounds of Silence: Lessons from an 18 hour API outage by Paul Zaich\"\n  speakers:\n    - Paul Zaich\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    The Sounds of Silence: Lessons from an 18 hour API outage by Paul Zaich\n\n    Sometimes applications are behaving “normally” along strict definitions of HTTP statuses but under the surface, something is terribly wrong. In 2017, Checkr’s most important API endpoint went down for 12 hours without detection. In this talk I’ll talk about this incident, how we responded (what went well and what could have gone better) and explore how we’ve hardened our systems today with simple monitoring patterns.\n\n    ___________\n\n    Paul hails from Denver, CO where he works as an Engineering Manager at Checkr. He’s passionate about building technology for the new world of work. In a former life, Paul was a competitive swimmer. He now spends most of his free time on dry land with his wife and three children.\n  video_provider: \"youtube\"\n  video_id: \"bSPvuaFtN6M\"\n\n- id: \"seyed-nasehi-railsconf-2020-ce\"\n  title: \"Why You Should Avoid Identity Sync Like Wildfire?\"\n  raw_title: \"RailsConf 2020 CE - Why You Should Avoid Identity Sync Like Wildfire? by Seyed Nasehi\"\n  speakers:\n    - Seyed Nasehi\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-04-24\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Why You Should Avoid Identity Sync Like Wildfire? by Seyed Nasehi\n\n    When we built our single sign-on service, we learned that syncing identity changes among applications can be deceptively complex. This is because we had to iteratively deploy the SSO service while supporting our existing applications that used the service. In this talk, we discuss lessons learned and recommendations on three key identity sync problems: 1) using editable fields such as email as an ID, 2) relying on unproven promises by standards such as SCIM, and 3) split-tenant situation. This talk will help developers avoid some pitfalls while building or working with an identity service.\n\n    __________\n\n    Seyed M Nasehi is a software engineer at Cisco with a decade of software development experience. He's been building Ruby on Rails applications in the past 3 years to help customers who are using Cisco security products. His latest involvement was building a single sign-on service to be used by multiple security products within Cisco.\n  video_provider: \"youtube\"\n  video_id: \"huJtiA_wOtc\"\n\n- id: \"chris-oliver-railsconf-2020-ce\"\n  title: \"Advanced ActionText: Attaching any Model in rich text\"\n  raw_title: \"RailsConf 2020 CE - Advanced ActionText: Attaching any Model in rich text by Chris Oliver\"\n  speakers:\n    - Chris Oliver\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-05-04\"\n  published_at: \"2020-05-04\"\n  description: |-\n    Advanced ActionText: Attaching any Model in rich text by Chris Oliver\n\n    Whether it's @ mentions for users, hashtags, or other resources, many application these days need rich text fields. ActionText allows you to embed rich snippets for any model in your Rails app, but it requires a bit of communication with the backend. You'll learn how to add @ mentions for users and YouTube embeds as ActionText attachments and see how it all works together.\n\n    __________\n\n    Chris is the founder of GoRails, host of the Remote Ruby podcast, and creator of Jumpstart and Hatchbox.io. He loves building tools to make developers' lives easier and helping people learn to code.\n  video_provider: \"youtube\"\n  video_id: \"2iGBuLQ3S0c\"\n\n- id: \"justin-gordon-railsconf-2020-ce\"\n  title: \"Webpacker, It-Just-Works, But How?\"\n  raw_title: \"RailsConf 2020 CE - Webpacker, It-Just-Works, But How? by Justin Gordon\"\n  speakers:\n    - Justin Gordon\n  event_name: \"RailsConf 2020 CE\"\n  date: \"2020-05-05\"\n  published_at: \"2020-05-05\"\n  description: |-\n    Webpacker, It-Just-Works, But How? by Justin Gordon\n\n    How does the Webpacker gem provide \"it-just-works\" webpack integration with Rails? That simplicity did not come easily. The rich functionality, complexity, and rapid evolution of the webpack ecosystem necessitated extension points beyond a simple Ruby config file.\n\n    Yet you need to know almost nothing about webpack to leverage the modern JavaScript ecosystem. But what if you want to extend the standard configuration? What information might help you upgrade webpack and webpacker in the future?\n\n    This talk will explain the magical plumbing of Webpacker so you can leverage the webpack ecosystem on your terms.\n\n    For the talk slides, email Justin at justin@shakacode.com\n\n    _________\n\n    Justin has been a passionate user of webpack since early 2014 when he just could not stand copy-pasting one more jQuery file into his Rails project. In 2015, he created the gem \"React on Rails,\" which integrated server-side rendered React and Webpack with Rails long before the Webpacker gem. These days, as CEO of ShakaCode.com, he helps companies optimize their Rails websites. He and his ShakaCode team also build Rails apps with modern front-ends, including their startup app, HiChee.com.\n  video_provider: \"youtube\"\n  video_id: \"sJLoOpc5LD8\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2021/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyan3isUPgB_fER4eM9Js6pA\"\ntitle: \"RailsConf 2021\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: \"\"\npublished_at: \"2021-09-27\"\nstart_date: \"2021-04-12\"\nend_date: \"2021-04-15\"\nyear: 2021\nbanner_background: \"#ECF3FB\"\nfeatured_background: \"#ECF3FB\"\nfeatured_color: \"#2468BD\"\ncoordinates: false\n"
  },
  {
    "path": "data/railsconf/railsconf-2021/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"eileen-m-uchitelle-railsconf-2021\"\n  title: \"Keynote: All the Things I Thought I Couldn't Do\"\n  raw_title: \"RailsConf 2021: Keynote: Eileen Uchitelle - All the Things I Thought I Couldn't Do\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5bWE6GpN938\"\n\n- id: \"adam-cuppy-railsconf-2021\"\n  title: \"Game Show: Syntax Error\"\n  raw_title: \"Game Show: Adam Cuppy - Syntax Error\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"vD08qTNYO9c\"\n\n- id: \"aja-hammerly-railsconf-2021\"\n  title: \"Hiring is Not Hazing\"\n  raw_title: \"RailsConf 2021: Hiring is Not Hazing - Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  slides_url: \"https://thagomizer.com/files/HiringIsNotHazingForDevRelCon.pdf\" # TODO: these might not be 100% right\n  description: |-\n    Tech hiring has a bad reputation for a reason - it's usually awful. But it doesn't have to be that way. In this talk, we'll dive into what is wrong with many current tech hiring practices and what you can do instead. You'll learn ways to effectively assess technical ability, what makes a great interview question, how to be more inclusive, the pros and cons of giving homework assignments, and much more. You'll leave with ideas to improve your interviews, and ways to influence your company to change their hiring practices.\n  video_provider: \"youtube\"\n  video_id: \"ZzWRdAPjEgY\"\n\n- id: \"andrew-ek-railsconf-2021\"\n  title: \"What Poetry Workshops Teach Us about Code Review\"\n  raw_title: \"RailsConf 2021: What Poetry Workshops Teach Us about Code Review - Andrew Ek\"\n  speakers:\n    - Andrew Ek\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: |-\n    Code review is ostensibly about ensuring quality code and preventing errors, bugs, and/or vulnerabilities from making their way to production systems. Code review, as practiced, is often top-down, didactic, and in many cases not particularly useful or effective. By looking at the creative writing workshop model (and strategies for teaching and providing feedback on writing), we can extract patterns that help us to have more effective, more efficient, and more enjoyable code reviews. Not only can we make our code better, we can also help our teams better understand the codebase and communicate better, and thus do more effective and enjoyable work (with perhaps better team cohesion).\n  video_provider: \"youtube\"\n  video_id: \"AQg_XZ5b5HU\"\n\n- id: \"ariel-caplan-railsconf-2021\"\n  title: \"The Trail to Scale Without Fail: Rails?\"\n  raw_title: \"RailsConf 2021: The Trail to Scale Without Fail: Rails? - Ariel Caplan\"\n  speakers:\n    - Ariel Caplan\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: |-\n    Let's be blunt: Most web apps aren’t so computation-heavy and won't hit scaling issues.\n\n    What if yours is the exception? Can Rails handle it?\n\n    Cue Exhibit A: Cloudinary, which serves billions of image and video requests daily, including on-the-fly edits, QUICKLY, running on Rails since Day 1. Case closed?\n    https://cloudinary.com/\n\n    Not so fast. Beyond the app itself, we needed creative solutions to ensure that, as traffic rises and falls at the speed of the internet, we handle the load gracefully, and no customer overwhelms the system.\n\n    The real question isn't whether Rails is up to the challenge, but rather: Are you?\n  video_provider: \"youtube\"\n  video_id: \"4F8hOebREe4\"\n\n- id: \"austin-story-railsconf-2021\"\n  title: \"Effective Data Synchronization between Rails Microservices\"\n  raw_title: \"RailsConf 2021: Effective Data Synchronization between Rails Microservices - Austin Story\"\n  speakers:\n    - Austin Story\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: |-\n    Data consistency in a microservice architecture can be a challenge, especially when your team grows to include data producers from data engineers, analysts, and others.\n\n    How do we enable external processes to load data onto data stores owned by several applications while honoring necessary Rails callbacks? How do we ensure data consistency across the stack?\n\n    Over the last five years, Doximity has built an elegant system that allows dozens of teams across our organization to independently load transformed data through our rich domain models while maintaining consistency. I'd like to show you how!\n  video_provider: \"youtube\"\n  video_id: \"1qrWYcdnrik\"\n\n- id: \"ben-greenberg-railsconf-2021\"\n  title: \"Self-Care on Rails\"\n  raw_title: \"RailsConf 2021: Self-Care on Rails - Ben Greenberg\"\n  speakers:\n    - Ben Greenberg\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: |-\n    This past year has been one of the most challenging years in recent memory. The pandemic has taken a toll, including on children.\n\n    Adults used their professional skills to help make the year a little better for the kids in our lives: Therapists counseled, entertainers delighted, teachers educated... and Rails developers developed!\n\n    In this talk, I'll share the apps I built on Rails that helped my kids and me cope, celebrate and persevere through the year.\n\n    In 2020, tech was pivotal in keeping us going, and for my kids, Rails made the year a little more manageable.\n  video_provider: \"youtube\"\n  video_id: \"7uuRV17e8gg\"\n\n- id: \"chelsea-troy-railsconf-2021\"\n  title: \"Techniques for Uncertain Times\"\n  raw_title: \"RailsConf 2021: Debugging: Techniques for Uncertain Times - Chelsea Troy\"\n  speakers:\n    - Chelsea Troy\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: |-\n    When we learn to code, we focus on writing features while we understand what the code is doing. When we debug, we don’t understand what our code is doing. The less we understand, the less likely it is that our usual programming mindset—the one we use for feature development—can solve the problem.\n\n    It turns out, the skills that make us calmer, more effective debuggers also equip us to deal with rapid, substantial changes to our lives.\n\n    Whether you’re uncertain about what’s going on in your code, your life, or both, in this talk you’ll learn debugging techniques to get you moving forward safely.\n  video_provider: \"youtube\"\n  video_id: \"yhogm8HAd3o\"\n\n- id: \"chris-oliver-railsconf-2021\"\n  title: \"Realtime Apps with Hotwire & ActionMailbox\"\n  raw_title: \"RailsConf 2021: Realtime Apps with Hotwire & ActionMailbox - Chris Oliver\"\n  speakers:\n    - Chris Oliver\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: |-\n    Realtime Apps with Hotwire & ActionMailbox - Chris Oliver\n  video_provider: \"youtube\"\n  video_id: \"ItB848u3QR0\"\n\n- id: \"damir-svrtan-railsconf-2021\"\n  title: \"Designing APIs: Less Data is More\"\n  raw_title: \"RailsConf 2021: Designing APIs: Less Data is More - Damir Svrtan\"\n  speakers:\n    - Damir Svrtan\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: |-\n    Often developers design APIs that expose more than is needed - unnecessary fields, redundant relationships, and endpoints that no one asked for.\n    These kinds of practices later on introduce communication overhead, extra maintenance costs, negative performance impacts, and waste time that could have been spent better otherwise.\n    We'll walk through how to design minimal APIs that are straight forward to use, and that are exactly what our consumers need!\n  video_provider: \"youtube\"\n  video_id: \"GbKOajKO46Y\"\n\n- id: \"stefanni-brasil-railsconf-2021\"\n  title: \"Lightning Talk: Should you create a new Rails app as API-only?\"\n  raw_title: \"RailsConf 2021: Lightning Talks: Steffani Brasil\"\n  speakers:\n    - Stefanni Brasil\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"H6MPMtf-Hd0\"\n\n- id: \"evan-phoenix-railsconf-2021\"\n  title: \"Keynote: Chatting with David\"\n  raw_title: \"RailsConf 2021: Keynote: Chatting with David\"\n  speakers:\n    - Evan Phoenix\n    - David Heinemeier Hansson\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FzK0iHyQR0k\"\n\n- id: \"bryan-cantrill-railsconf-2021\"\n  title: \"Keynote: Hardware/Software Co-design: The Coming Golden Age\"\n  raw_title: \"RailsConf 2021_ Keynote: Bryan Cantrill - Hardware/Software Co-design: The Coming Golden Age\"\n  speakers:\n    - Bryan Cantrill\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jSE9fXgiqig\"\n\n- id: \"gannon-mcgibbon-railsconf-2021\"\n  title: \"Profiling to make your Rails app faster\"\n  raw_title: \"RailsConf 2021: Profiling to make your Rails app faster - Gannon McGibbon\"\n  speakers:\n    - Gannon McGibbon\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    As you grow your Rails app, is it starting to slow down? Let’s talk about how to identify slow code, speed it up, and verify positive change within your application. In this talk, you’ll learn about rack-mini-profiler, benchmark/ips, and performance optimization best practices.\n  video_provider: \"youtube\"\n  video_id: \"97d3f8r2qZ8\"\n\n- id: \"henning-koch-railsconf-2021\"\n  title: \"Why I'm Closing Your GitHub Issue\"\n  raw_title: \"RailsConf 2021: Why I'm Closing Your GitHub Issue - Henning Koch\"\n  speakers:\n    - Henning Koch\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Do you feel panic when receiving a notification from your open-source project? Is a backlog of unanswered issues wearing you down?\n\n    You wanted to put something out there for others to use, but now it feels like a second job. Keep stressing out like this and you will burn out and leave another project abandoned on GitHub.\n\n    In my talk we will rediscover your personal reasons for doing open source in the first place. We will practice dealing with issues effectively to free up time for the work that motivates you.\n  video_provider: \"youtube\"\n  video_id: \"veSRJUb8yuI\"\n\n- id: \"jamie-gaskins-railsconf-2021\"\n  title: \"Hotwire Demystified\"\n  raw_title: \"RailsConf 2021: Hotwire Demystified - Jamie Gaskins\"\n  speakers:\n    - Jamie Gaskins\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    DHH stunned the Rails world with his announcement of Hotwire from Basecamp. Even folks in the non-Rails web-development community took notice.\n\n    In this talk, you will learn about the building blocks of Hotwire and how they compose to create a streamlined development experience while writing little to no JavaScript.\n  video_provider: \"youtube\"\n  video_id: \"gllwoSoD5mk\"\n\n- id: \"jeannie-evans-railsconf-2021\"\n  title: \"Engineer in Diversity & Inclusion - Tangible Steps for Teams\"\n  raw_title: \"RailsConf 2021: Engineer in Diversity & Inclusion - Tangible Steps for Teams - Jeannie Evans\"\n  speakers:\n    - Jeannie Evans\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    When it comes to implementing Diversity, Equity, and Inclusion (“DEI”), where do software engineers fit in? The technology we build is used by diverse groups of people, so our role is to build platforms for that diversity. At this talk, you will learn why and how to make DEI a priority in your work with tangible steps, goals, and examples. While the scope of these topics can feel overwhelming, you will leave this talk empowered with the tools to attend your next standup or write that next line of code as a better community member, ally, and software engineer.\n  video_provider: \"youtube\"\n  video_id: \"GRl5EWXM96o\"\n\n- id: \"jemma-issroff-railsconf-2021\"\n  title: \"A day in the life of a Ruby object\"\n  raw_title: \"RailsConf 2021: A Day in the Life of a Ruby Object - Jemma Issroff\"\n  speakers:\n    - Jemma Issroff\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Your code creates millions of Ruby objects every day, but do you actually know what happens to these objects?\n\n    In this talk, we’ll walk through the lifespan of a Ruby object from birth to the grave: from .new to having its slot reallocated. We’ll discuss object creation, the Ruby object space, and an overview of garbage collection.\n\n    Along the way, we’ll learn how to make our apps more performant, consume less memory, and have fewer memory leaks. We’ll learn specific tips and pointers for how to see what the garbage collector is doing and how to take advantage of the strategies it employs.\n  video_provider: \"youtube\"\n  video_id: \"NGOuPxqoPOs\"\n\n- id: \"jesse-spevack-railsconf-2021\"\n  title: \"Stimulating Events\"\n  raw_title: \"RailsConf 2021: Stimulating Events - Jesse Spevack\"\n  speakers:\n    - Jesse Spevack\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Stimulus JS bills itself as a framework with modest ambitions that fits nicely into the Rails as \"omakase\" paradigm. At its core, Stimulus gives Rails developers a new set of low effort, high impact tools that can add much more than the sheen of modernization to an everyday Rails application. Join me as I live code three Stimulus JS examples that will help you save time, impress your friends, and win new clients and opportunities. This will be great for JS newbies and experts alike along with anyone interested in the potential schadenfreude that watching me live code will likely elicit.\n  video_provider: \"youtube\"\n  video_id: \"XM9A53WUnN4\"\n\n- id: \"jessica-hilt-railsconf-2021\"\n  title: \"Strategic Storytelling\"\n  raw_title: \"RailsConf 2021: Strategic Storytelling - Jessica Hilt\"\n  speakers:\n    - Jessica Hilt\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    We come from a world of facts and metrics so obviously the people with the most data wins, right? Engineering comes from a place of logic but telling the story behind that information is how the best leaders get buy-in and support for their plans. In this talk, we'll examine the how and why of storytelling, develop a framework of putting an idea into a narrative, and what tools you’ll need to complement a good story. By the end, you’ll be able to break out a story whenever you need to generate excitement, find advocates, or more budget. Is there anything more irresistible than a good story?\n  video_provider: \"youtube\"\n  video_id: \"rTEbYehXhdk\"\n\n- id: \"joel-hawksley-railsconf-2021\"\n  title: \"ViewComponents in the Real World\"\n  raw_title: \"RailsConf 2021: ViewComponents in the Real World - Joel Hawksley\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    With the release of 6.1, Rails added support for rendering objects that respond to render_in, a feature extracted from the GitHub application. This change enabled the development of ViewComponent, a framework for building reusable, testable & encapsulated view components. In this talk, we’ll share what we’ve learned scaling to hundreds of ViewComponents in our application, open sourcing a library of ViewComponents, and nurturing a thriving community around the project, both internally and externally.\n  video_provider: \"youtube\"\n  video_id: \"xabosHqjOlM\"\n\n- id: \"jonas-jabari-railsconf-2021\"\n  title: \"Beautiful reactive web UIs, Ruby and you\"\n  raw_title: \"RailsConf 2021: Beautiful reactive web UIs, Ruby and you - Jonas Jabari\"\n  speakers:\n    - Jonas Jabari\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    A lot of life changing things have happened in 2020. And I'm obviously speaking about Stimulus Reflex and Hotwire and how we as Rails devs are finally enabled to skip a lot of JS while implementing reactive web UIs. But what if I told you, there's room for even more developer happiness? Imagine crafting beautiful UIs in pure Ruby, utilizing a library reaching from simple UI components representing basic HTML tags over styled UI concepts based on Bootstrap to something like a collection, rendering reactive data sets. Beautiful, reactive web UIs implemented in pure Ruby are waiting for you!\n  video_provider: \"youtube\"\n  video_id: \"VhIXLNIfk5s\"\n\n- id: \"jordan-raine-railsconf-2021\"\n  title: \"Refactoring: A developer's guide to writing well\"\n  raw_title: \"RailsConf 2021: Refactoring: A developer's guide to writing well - Jordan Raine\"\n  speakers:\n    - Jordan Raine\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    As a developer, you're asked to write an awful lot: commit messages, code review, achitecture docs, pull request write-ups, and more. When you write, you have the power to teach and inspire your teammates—the reader—or leave them confused. Like refactoring, it's a skill that can elevate you as a developer but it is often ignored.\n\n    In this session, we'll use advice from fiction authors, book editors, and technical writers to take a pull request write-up from unhelpful to great. Along the way, you'll learn practical tips to make your code, ideas, and work more clear others.\n  video_provider: \"youtube\"\n  video_id: \"jfK5miM5ZMs\"\n\n- id: \"josh-thompson-railsconf-2021\"\n  title: '\"Junior\" Devs are the Solution to Many of Your Problems'\n  raw_title: 'RailsConf 2021: \"Junior\" Devs are the Solution to Many of Your Problems - Josh Thompson'\n  speakers:\n    - Josh Thompson\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Our industry telegraphs: \"We don't want (or know how to handle) 'junior developers*'.\"\n\n    Early-career Software Developers, or ECSDs, have incredible value if their team/company/manager doesn't \"lock themselves out\" of accessing this value.\n\n    Whoever figures out how to embrace the value of ECSDs will outperform their cohort. 📈💰🤗\n\n    I will speak to:\n\n    Executives (CTOs/Eng VPs)\n    Senior Developers/Dev Managers\n    ECSDs themselves\n    About how to:\n\n    Identify which problems are solvable because of ECSDs\n    Get buy-in for these problem/solution sets\n    Start solving these problems with ECSDs\n  video_provider: \"youtube\"\n  video_id: \"SQh-wqmuFxg\"\n\n- id: \"justin-bowen-railsconf-2021\"\n  title: \"Exploring Real-time Computer Vision Using ActionCable\"\n  raw_title: \"RailsConf 2021: Exploring Real-time Computer Vision Using ActionCable - Justin Bowen\"\n  speakers:\n    - Justin Bowen\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Learn about combining Rails and Python for Computer Vision. We'll be analyzing images of cannabis plants in real-time and deriving insights from changes in leaf area & bud site areas. We'll explore when to use traditional statistical analysis versus ML approaches, as well as other ways CV has been deployed. We’ll cover integrating OpenCV with ActionCable & Sidekiq for broadcasting camera analysis to Rails and creating time-lapse style renderings with graphs. You will gain an understanding of what tools to use and where to start if you’re interested in using ML or CV with your Rails project!\n  video_provider: \"youtube\"\n  video_id: \"VsTLXiv0H-g\"\n\n- id: \"justin-gordon-railsconf-2021\"\n  title: \"Implicit to Explicit: Decoding Ruby's Magical Syntax\"\n  raw_title: \"RailsConf 2021: Implicit to Explicit: Decoding Ruby's Magical Syntax - Justin Gordon\"\n  speakers:\n    - Justin Gordon\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Does a Rails model or config file seem like a magical syntax? Or can you read any Ruby code and understand it as the interpreter does?\n\n    Ruby's implicitness makes it great for readability and DSLs. But that also gives Ruby a \"magical\" syntax compared to JavaScript.\n\n    In this talk, let's convert the implicit to explicit in some familiar Rails code. What was \"magic\" will become simple, understandable code.\n\n    After this talk, you'll see Ruby through a new lens, and your Ruby reading comprehension will improve. As a bonus, I'll share a few Pry tips to demystify any Ruby code.\n  video_provider: \"youtube\"\n  video_id: \"9ubmyfEdlMs\"\n\n- id: \"kerri-miller-railsconf-2021\"\n  title: \"The History of Making Mistakes\"\n  raw_title: \"RailsConf 2021: The History of Making Mistakes - Kerri Miller\"\n  speakers:\n    - Kerri Miller\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    We sometimes say “computers were a mistake”, as if clay tablets were any better. From the very beginning, humans have been screwing up, and it’s only gotten worse from there. Each time, though, we’ve learned something and moved forward. Sometimes we forget those lessons, so let’s look through the lens of software engineering at a few of these oopsie-daisies, and see the common point of failure - humans themselves.\n  video_provider: \"youtube\"\n  video_id: \"ecUDTUihlPc\"\n\n- id: \"kevin-gilpin-railsconf-2021\"\n  title: \"How to teach your code to describe its own architecture\"\n  raw_title: \"RailsConf 2021: How to teach your code to describe its own architecture - Kevin Gilpin\"\n  speakers:\n    - Kevin Gilpin\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Architecture documents and diagrams are always out of date. Unfortunately, lack of accurate, up-to-date information about software architecture is really harmful to developer productivity and happiness. Historically, developers have overcome other frustrations by making code the “source of truth”, and then using the code as a foundation for automated tools and processes. In this talk, I will describe how to automatically generate docs and diagrams of code architecture, and discuss how to use to use this information to improve code understanding and code quality.\n  video_provider: \"youtube\"\n  video_id: \"SZHFnRkAcU0\"\n\n- id: \"kerstin-puschke-railsconf-2021\"\n  title: \"High availability by offloading work\"\n  raw_title: \"RailsConf 2021: High availability by offloading work - Kerstin Puschke\"\n  speakers:\n    - Kerstin Puschke\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Unpredictable traffic spikes, slow requests to a third party, and time-consuming tasks like image processing shouldn’t degrade the user facing availability of an application. In this talk, you’ll learn about different approaches to maintain high availability by offloading work into the background: background jobs, message oriented middleware based on queues, and event logs like Kafka. I’ll explain their foundations and how they compare to each other, helping you to choose the right tool for the job.\n  video_provider: \"youtube\"\n  video_id: \"AWe70zT2z_c\"\n\n- id: \"kevin-murphy-railsconf-2021\"\n  title: \"Engineering MBA: Be The Boss of Your Own Work\"\n  raw_title: \"RailsConf 2021: Engineering MBA: Be The Boss of Your Own Work - Kevin Murphy\"\n  speakers:\n    - Kevin Murphy\n  event_name: \"RailsConf 2021\"\n  slides_url: \"https://speakerdeck.com/kevinmurphy/engineering-mba\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Improve your work as a developer with an introduction to strategic planning, situational leadership, and process management. No balance sheets or income statements here; join me to learn the MBA skills valuable to developers without the opportunity costs of lost wages or additional student loans.\n\n    Demystify the strategic frameworks your management team may use to make decisions and learn how you can use those same concepts in your daily work. Explore the synergy one developer achieved by going to business school (sorry, the synergy comment slipped out - old habit).\n  video_provider: \"youtube\"\n  video_id: \"HMppLTUyewE\"\n\n- id: \"lyle-mullican-railsconf-2021\"\n  title: \"Who Are You? Delegation, Federation, Assertions and Claims\"\n  raw_title: \"RailsConf 2021: ho Are You? Delegation, Federation, Assertions and Claims - Lyle Mullican\"\n  speakers:\n    - Lyle Mullican\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Identity management? Stick a username and (hashed) password in a database, and done! That's how many apps get started, at least. But what happens once you need single sign-on across multiple domains, or if you'd rather avoid the headache of managing those passwords to begin with? This session will cover protocols (and pitfalls) for delegating the responsibility of identity management to an outside source. We'll take a look at SAML, OAuth, and OpenID Connect, considering both the class of problems they solve, and some new ones they introduce!\n  video_provider: \"youtube\"\n  video_id: \"oktaIPZqD0E\"\n\n- id: \"maciek-rzasa-railsconf-2021\"\n  title: \"API Optimization Tale: Monitor, Fix and Deploy (on Friday)\"\n  raw_title: \"RailsConf 2021: API Optimization Tale: Monitor, Fix and Deploy (on Friday) - Maciek Rzasa\"\n  speakers:\n    - Maciek Rzasa\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    I saw a green build on a Friday afternoon. I knew I need to push it to production before the weekend. My gut told me it was a trap. I had already stayed late to revert a broken deploy. I knew the risk.\n\n    In the middle of a service extraction project, we decided to migrate from REST to GraphQL and optimize API usage. My deploy was a part of this radical change.\n\n    Why was I deploying so late? How did we measure the migration effects? And why was I testing on production? I'll tell you a tale of small steps, monitoring, and old tricks in a new setting. Hope, despair, and broken production included.\n  video_provider: \"youtube\"\n  video_id: \"8DKo5jefJeM\"\n\n- id: \"martin-jaime-railsconf-2021\"\n  title: \"Using Rails to communicate with the New York Stock Exchange\"\n  raw_title: \"RailsConf 2021: Using Rails to communicate with the New York Stock Exchange - Martin Jaime\"\n  speakers:\n    - Martin Jaime\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    This is a timely talk because of what happened with Gamestop/Robinhood, introducing a case of a high-frequency trading app like Robinhood, built on top of Rails, and how it proves it can scale, managing not only over a complex HTTP API but also communicating over an internal protocol TCP with one New York Stock Exchange server by making use of Remote Procedure Calls (RPC) with RabbitMQ to be able to manage transactional messages (orders).\n\n    So, how can we make use of Rails to deliver a huge amount of updates (through WSS) and have solid transactions (through HTTPS)?\n  video_provider: \"youtube\"\n  video_id: \"sPLngvzOuqE\"\n\n- id: \"matt-duszynski-railsconf-2021\"\n  title: \"rails db:migrate:even_safer\"\n  raw_title: \"RailsConf 2021: rails db:migrate:even_safer - Matt Duszynski\"\n  speakers:\n    - Matt Duszynski\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    It's been a few years, your Rails app is wildly successful, and your database is bigger than ever. With that, comes new challenges when making schema changes. You have types to change, constraints to add, and data to migrate... and even an entire table that needs to be replaced.\n\n    Let's learn some advanced techniques for evolving your database schema in a large production application, while avoiding errors and downtime. Remember, uptime begins at $HOME!\n    Play\n  video_provider: \"youtube\"\n  video_id: \"uMcRCSiNzuc\"\n\n- id: \"mercedes-bernard-railsconf-2021\"\n  title: \"Rescue Mission Accomplished\"\n  raw_title: \"RailsConf 2021: Rescue Mission Accomplished - Mercedes Bernard\"\n  speakers:\n    - Mercedes Bernard\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    \"Your mission, should you choose to accept it...\" A stakeholder has brought you a failing project and wants you to save it.\n\n    Do you accept your mission? Do you scrap the project and rewrite it? Deciding to stabilize a failing project can be a scary challenge. By the end of this talk, you will have tangible steps to take to incrementally refactor a failing application in place. We will also be on the lookout for warning signs of too much tech debt, learn when tech debt is OK, and walk away with useful language to use when advocating to pay down the debt.\n  video_provider: \"youtube\"\n  video_id: \"_8BklZo-FC0\"\n\n- id: \"michele-titolo-railsconf-2021\"\n  title: \"Writing design docs for wide audiences\"\n  raw_title: \"RailsConf 2021: Writing design docs for wide audiences - Michele Titolo\"\n  speakers:\n    - Michele Titolo\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    What would you do to convince a large audience, who has little context, to use your solution to a problem? One way is to write a design document, which helps scale technical communication and build alignment among stakeholders. The wider the scope of the problem, the more important alignment is. A design document achieves this by addressing three key questions: “what is the goal?”, “how will we achieve it?” and “why are we doing it this way?”. This talk will cover identifying your audience, effectively writing answers to these questions, and involving the right people at the right time.\n  video_provider: \"youtube\"\n  video_id: \"TxBPuAzFkHE\"\n\n- id: \"mike-calhoun-railsconf-2021\"\n  title: \"How Reference Librarians Can Help Us Help Each Other\"\n  raw_title: \"RailsConf 2021: How Reference Librarians Can Help Us Help Each Other - Mike Calhoun\"\n  speakers:\n    - Mike Calhoun\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    In 1883, The Boston Public Library began hiring librarians for reference services. Since then, a discipline has grown around personally meeting the needs of the public, as Library Science has evolved into Information Science. Yet, the goal of assisting with information needs remains the same. There is disciplinary overlap between programming and information science, but there are cultural differences that can be addressed. In other words, applying reference library practices to our teams can foster environments where barriers to asking for and providing help are broken down.\n    Play\n  video_provider: \"youtube\"\n  video_id: \"joZYMpoHrao\"\n\n- id: \"nate-berkopec-railsconf-2021\"\n  title: \"A Third Way For Open-Source Maintenance\"\n  raw_title: \"RailsConf 2021: A Third Way For Open-Source Maintenance - Nate Berkopec\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Drawing on my experiences maintaining Puma and other open-source projects, both volunteer and for pay, I'd like to share what I think is a \"third way\" for sustainable open source, between the extremes of \"everyone deserves to be paid\" and \"everyone's on their own\". Instead of viewing maintainers as valuable resources, this third way posits that maintainers are blockers to a potentially-unlimited pool of contributors, and a maintainer's #1 job is encouraging contribution.\n  video_provider: \"youtube\"\n  video_id: \"gvW0htMx_2o\"\n\n- id: \"nathan-griffith-railsconf-2021\"\n  title: \"Can I break this?: Writing resilient “save” methods\"\n  raw_title: \"RailsConf 2021: Can I break this?: Writing resilient “save” methods - Nathan Griffith\"\n  speakers:\n    - Nathan Griffith\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    An alert hits your radar, leaving you and your team perplexed. An “update” action that had worked for years suddenly ... didn't. You dig in to find that a subtle race condition had been hiding in plain sight all along. How could this happen? And why now?\n\n    In this talk, we'll discover that seemingly improbable failures happen all the time, leading to data loss, dropped messages, and a lot of head-scratching. Plus, we'll see that anyone can become an expert in spotting these errors before they occur. Join us as we learn to write resilient save operations, without losing our minds.\n  video_provider: \"youtube\"\n  video_id: \"jbOM_tvWv3o\"\n\n- id: \"nicole-carpenter-railsconf-2021\"\n  title: \"How to be a great developer without being a great coder\"\n  raw_title: \"RailsConf 2021: How to be a great developer without being a great coder - Nicole Carpenter\"\n  speakers:\n    - Nicole Carpenter\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Learning to code is an individual journey filled with highs and lows, but for some, the lows seem far more abundant. For some learning to code, and even for some professionals, it feels like we're struggling to tread water while our peers swim laps around us. Some developers take more time to build their technical skills, and that’s ok, as being a great developer is about far more than writing code.\n\n    This talk looks at realistic strategies for people who feel like they are average-or-below coding skill level, to keep their head above water while still excelling in their career as a developer.\n  video_provider: \"youtube\"\n  video_id: \"U6DlbMuHgoQ\"\n\n- id: \"aaron-patterson-railsconf-2021\"\n  title: \"Keynote\"\n  raw_title: \"RailsConf 2021: Keynote: Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"TNFljhcoHvQ\"\n\n- id: \"riaz-virani-railsconf-2021\"\n  title: \"Missing Guide to Service Objects in Rails\"\n  raw_title: \"RailsConf 2021: Missing Guide to Service Objects in Rails - Riaz Virani\"\n  speakers:\n    - Riaz Virani\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    What happens with Rails ends and our custom business logic begins? Many of us begin writing \"service objects\", but what exactly is a service object? How do we break down logic within the service object? What happens when a step fails? In this talk, we'll go over some of the most common approaches to answering these questions. We'll survey options to handle errors, reuse code, organize our directories, and even OO vs functional patterns. There isn't a perfect pattern, but by the end, we'll be much more aware of the tradeoffs between them.\n  video_provider: \"youtube\"\n  video_id: \"MCTwjE-vp2s\"\n\n- id: \"ryan-boone-railsconf-2021\"\n  title: \"Accessibility is a Requirement\"\n  raw_title: \"RailsConf 2021: Accessibility is a Requirement - Ryan Boone\"\n  speakers:\n    - Ryan Boone\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Accessible web applications reach wider audiences, ensure businesses are in compliance with the law, and, most importantly, remove barriers for the one in seven worldwide living with a permanent disability. But limited time, lack of knowledge, and even good intentions get in the way of building them.\n\n    Come hear my personal journey toward accessibility awareness. You will learn what accessibility on the web means, how to improve the accessibility of your applications today, and how to encourage an environment where accessibility is seen as a requirement, not simply a feature.\n  video_provider: \"youtube\"\n  video_id: \"0r1rBNM3Wao\"\n\n- id: \"ryan-brushett-railsconf-2021\"\n  title: \"You are Your Own Worst Critic\"\n  raw_title: \"RailsConf 2021: You Are Your Own Worst Critic - Ryan Brushett\"\n  speakers:\n    - Ryan Brushett\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Advancing through one's career can be challenging. As we experience setbacks, impostor syndrome, and uncertainty at various points of our career, we may develop some habits which, when taken too far, could see us sabotaging our own progress. You are your own worst critic.\n\n    Despite my own experience with anxiety, a bullying internal critic, and “self-deprecating humour”, I'm now a senior engineer and I've noticed these habits in people I mentor. I hope to help you identify signs of these bad habits in yourself and others, and to talk about what has helped me work through it.\n  video_provider: \"youtube\"\n  video_id: \"EHZzyVmOrGI\"\n\n- id: \"santiago-bartesaghi-railsconf-2021\"\n  title: \"All you need to know to build Dynamic Forms (JS FREE)\"\n  raw_title: \"RailsConf 2021: All you need to know to build Dynamic Forms (JS FREE) - Santiago Bartesaghi\"\n  speakers:\n    - Santiago Bartesaghi\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Working with forms is pretty common in web apps, but this time my team was requested to give support for dynamic forms created by admins in an admin panel and used in several places (real story). There are many ways to implement it, but our goal was to build it in a way that felt natural in Rails.\n\n    This talk is for you if you’d like to learn how we used the ActiveModel's API together with the Form Objects pattern to support our dynamic forms feature, and the cherry on top is the usage of Hotwire to accomplish some more advanced features. And all of this is done without a single line of JS :)\n  video_provider: \"youtube\"\n  video_id: \"6WlFjFOuYGM\"\n\n- id: \"sumana-harihareswara-railsconf-2021\"\n  title: \"How To Get A Project Unstuck\"\n  raw_title: \"RailsConf 2021: How To Get A Project Unstuck - Sumana Harihareswara\"\n  speakers:\n    - Sumana Harihareswara\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    When an open source project has gotten stuck, how do you get it unstuck? Especially if you aren't already its maintainer? My teams have done this with several projects. A new contributor, who's never worked on a project before, can be the catalyst that revives a project or gets a long-delayed release out the door. I'll share a few case studies, principles, & gotchas.\n\n    More than developer time, coordination & leadership are a bottleneck in software sustainability. You'll come away from this talk with steps you can take, in the short and long runs, to address this for projects you care about.\n  video_provider: \"youtube\"\n  video_id: \"olqhg0aNfZc\"\n\n- id: \"sweta-sanghavi-railsconf-2021\"\n  title: \"Growing Software From Seed\"\n  raw_title: \"RailsConf 2021: Growing Software From Seed - Sweta Sanghavi\"\n  speakers:\n    - Sweta Sanghavi\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Pam Pierce writes, “Look at your garden every day. Study a plant or a square foot of ground until you’ve learned something new\". In debugging my own garden, the practice of daily observation has revealed signals previously overlooked. This practice has followed me to the work of tending to our growing application.\n\n    This talk visits some familiar places, code that should work, or seems unnecessarily complicated, and digs deeper to find what we missed at first glance. Let’s explore how we can learn to hear all our application tells us and cultivate a methodical approach to these sticky places.\n  video_provider: \"youtube\"\n  video_id: \"HiByvxqvH-8\"\n\n- id: \"takumasa-ochi-railsconf-2021\"\n  title: \"Scaling Rails API to Write\"\n  raw_title: \"RailsConf 2021: Scaling Rails API to Write-Heavy Traffic - Takumasa Ochi\"\n  speakers:\n    - Takumasa Ochi\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Tens of millions of people can download and play the same game thanks to mobile app distribution platforms. Highly scalable and reliable API backends are critical to offering a good game experience. Notable characteristics here is not only the magnitude of the traffic but also the ratio of write traffic. How do you serve millions of database transactions per minute with Rails?\n\n    The keyword to solve this issue is \"multiple databases,\" especially sharding. From system architecture to coding guidelines, we'd like to share the practical techniques derived from our long-term experience.\n  video_provider: \"youtube\"\n  video_id: \"R6EkPSo_7PA\"\n\n- id: \"tim-tyrrell-railsconf-2021\"\n  title: \"What is Developer Empathy?\"\n  raw_title: \"RailsConf 2021: What is Developer Empathy? - Tim Tyrrell\"\n  speakers:\n    - Tim Tyrrell\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Dev teams should employ empathetic patterns of behavior at all levels from junior developer to architect. Organizations can create the safety and security necessary to obtain a high functioning team environment that values courageous feedback if they simply have the language and tools to do so. How can leadership provide a framework for equitable practices and empathetic systems that promotes learning fluency across the team?\n\n    I have ideas. Find out what I've learned through countless hours of mentorship, encouragement, and support both learning from and teaching others to code.\n  video_provider: \"youtube\"\n  video_id: \"PvoGihwh0Ao\"\n\n- id: \"ufuk-kayserilioglu-railsconf-2021\"\n  title: \"The Curious Case of the Bad Clone\"\n  raw_title: \"RailsConf 2021: The Curious Case of the Bad Clone - Ufuk Kayserilioglu\"\n  speakers:\n    - Ufuk Kayserilioglu\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    On Sept 4th 2020, I got pinged on a revert PR to fix a 150% slowdown on the Shopify monolith. It was a two-line change reverting the addition of a Sorbet signature on a Shop method, implicating Sorbet as the suspect.\n\n    That was the start of a journey that took me through a deeper understanding of the Sorbet, Rails and Ruby codebases. The fix is in Ruby 3.0 and I can sleep better now.\n\n    This talk will take you on that journey with me. Along the way, you will find tools and tricks that you can use for debugging similar problems. We will also delve into some nuances of Ruby, which is always fun.\n  video_provider: \"youtube\"\n  video_id: \"eTAXHmBSlxs\"\n\n- id: \"vaidehi-joshi-railsconf-2021\"\n  title: \"The Cost of Data\"\n  raw_title: \"RailsConf 2021: The Cost of Data - Vaidehi Joshi\"\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    The internet grows every day. Every second, one of us is making calls to an API, uploading some images, or streaming the latest video content. But what is the cost of all this?\n\n    Every day, a data center stores information on our behalf. As engineers, it's easy to focus on the code and forget the tangible impact of our work. This talk explores the physical reality of creating and storing data today, as well as the challenges and technological advancements currently being made in this part of the tech sector. Together, we'll see how our code affects the physical world, and what we can do about it.\n    Play\n  video_provider: \"youtube\"\n  video_id: \"EfTZXvif9hg\"\n\n- id: \"vladimir-dementyev-railsconf-2021\"\n  title: \"Frontendless Rails frontend\"\n  raw_title: \"RailsConf 2021: Frontendless Rails frontend - Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Everything is cyclical, and web development is not an exception: ten years ago, we enjoyed developing Rails apps using HTML forms, a bit of AJAX, and jQuery—our productivity had no end! As interfaces gradually became more sophisticated, the \"classic\" approach began to give way to frontend frameworks, pushing Ruby into an API provider's role.\n\n    The situation started to change; the \"new wave\" is coming, and ViewComponent, StimulusReflex, and Hotwire are riding the crest.\n\n    In this talk, I'd like to demonstrate how we can develop modern \"frontend\" applications in the New Rails Way.\n  video_provider: \"youtube\"\n  video_id: \"UylEOXuAmo0\"\n\n- id: \"will-jordan-railsconf-2021\"\n  title: \"What the fork()?\"\n  raw_title: \"RailsConf 2021: What the fork()? - Will Jordan\"\n  speakers:\n    - Will Jordan\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    How does Spring boot your Rails app instantly, or Puma route requests across many processes? How can you fine-tune your app for memory efficiency, or simply run Ruby code in parallel? Find out with a deep dive on that staple Unix utensil, the fork() system call!\n\n    After an operating systems primer on children, zombies, processes and pipes, we'll dig into how exactly Spring and Puma use fork() to power Rails in development and production. We'll finish by sampling techniques for measuring and maximizing copy-on-write efficiency, including a new trick that can reduce memory usage up to 80%.\n  video_provider: \"youtube\"\n  video_id: \"Cq3Vd4KIvFk\"\n\n- id: \"yechiel-kalmenson-railsconf-2021\"\n  title: \"Talmudic Gems For Rails Developers\"\n  raw_title: \"RailsConf 2021: Talmudic Gems For Rails Developers - Yechiel Kalmenson\"\n  speakers:\n    - Yechiel Kalmenson\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Am I my colleague’s keeper? To what extent are we responsible for the consequences of our code?\n\n    More than two thousand years ago conversations on central questions of human ethics were enshrined in one of the primary ancient wisdom texts, the Talmud.\n\n    Now, as the tech industry is beginning to wake up to the idea that we can not separate our work from its ethical and moral ramifications these questions take on a new urgency.\n\n    In this talk, we will delve into questions of our responsibility to our teammates, to our code, and to the world through both the ancient texts and modern examples.\n  video_provider: \"youtube\"\n  video_id: \"7bPFm1CWaws\"\n\n- id: \"darren-broemmer-railsconf-2021\"\n  title: \"Turning DevOps Inside\"\n  raw_title: \"RailsConf 2021: Turning DevOps Inside-Out - Darren Broemmer\"\n  speakers:\n    - Darren Broemmer\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    We often think of automation and deployment scripts when we discuss DevOps, however the true value is in reacting to how customers use your application and incorporating this feedback into your development lifecycle. In this talk, we will discuss how you can turning DevOps around to increase your feature velocity, including some Rails specific strategies and gems you can use to get things done faster.\n  video_provider: \"youtube\"\n  video_id: \"sJ-Be85vCcc\"\n\n- id: \"carmen-huidobro-railsconf-2021\"\n  title: \"New dev, old codebase: A series of mentorship stories\"\n  raw_title: \"RailsConf 2021: New dev, old codebase: A series of mentorship stories - Ramón Huidobro\"\n  speakers:\n    - Carmen Huidobro\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Mentorship in software development carries a lot of responsibility, but plays an integral part in making tech communities as well as individuals thrive.\n\n    In this talk, we'll go over some of my mentorship experiences, adopting techniques and learning to teach, so we can teach to learn.\n\n    Anyone can be a great mentor!\n\n    The excellent mentorship.guide (also cited in the resources section) has an even more detailed answer to “Why be a mentor?” — here's the relevant section: https://mentorship.gitbook.io/guide/m...\n  video_provider: \"youtube\"\n  video_id: \"NcQqEurV4vo\"\n\n- id: \"robson-port-railsconf-2021\"\n  title: \"Lightning Talks: Robson Port\"\n  raw_title: \"RailsConf 2021: Lightning Talks: Robson Port\"\n  speakers:\n    - Robson Port\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"LWa465inCxQ\"\n\n- id: \"emily-harber-railsconf-2021\"\n  title: \"Lightning Talk: Pair Programming and Mentorship\"\n  raw_title: \"RailsConf 2021: Lightning Talks: Emily Harber\"\n  speakers:\n    - Emily Harber\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"teyMgaqg-1M\"\n\n- id: \"dorian-marie-railsconf-2021\"\n  title: \"Lightning Talk: Isolate Packages with Packwerk\"\n  raw_title: \"RailsConf 2021: Lightning Talks: Dorian Marie\"\n  speakers:\n    - Dorian Marie\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"lpfEnIsF1QM\"\n\n- id: \"brandon-shar-railsconf-2021\"\n  title: \"Lightning Talk: Inertia.js for Rails\"\n  raw_title: \"RailsConf 2021: Lightning Talks: Brandon Shar\"\n  speakers:\n    - Brandon Shar\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"-JT1RF-IhKs\"\n\n- id: \"sarah-sausan-railsconf-2021\"\n  title: \"Lightning Talk: Renewables + Rails: A Love Story\"\n  raw_title: \"RailsConf 2021: Lightning Talks: Sarah Sausan\"\n  speakers:\n    - Sarah Sausan\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5LBzWDbLu1I\"\n\n- id: \"lauren-billington-railsconf-2021\"\n  title: \"Lightning Talk: My Team's recent Gitastrophy - a PERFECT example!\"\n  raw_title: \"RailsConf 2021: Lightning Talks: Lauren Billington\"\n  speakers:\n    - Lauren Billington\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"GOmTVqH-eZE\"\n\n- id: \"daniel-azuma-railsconf-2021\"\n  title: \"Serverless Rails: Understanding the pros and cons\"\n  raw_title: \"RailsConf 2021: Serverless Rails: Understanding the pros and cons - Daniel Azuma\"\n  speakers:\n    - Daniel Azuma\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    Serverless is widely lauded as the ops-free future of deployment. Serverless is widely panned as a gimmick with little utility for the price. Who’s right? And what does it mean for my Rails app?\n\n    This session takes a critical look at serverless hosting. We’ll consider the abstractions underlying environments such as AWS Lambda and Google Cloud Run, their assumptions and trade-offs, and their implications for Ruby apps and frameworks. You’ll come away better prepared to decide whether or not to adopt serverless deployment, and to understand how your code might need to change to accommodate it.\n  video_provider: \"youtube\"\n  video_id: \"C3LMNdhVS2U\"\n\n- id: \"danielle-gordon-railsconf-2021\"\n  title: \"Make a Difference with Simple A/B Testing\"\n  raw_title: \"RailsConf 2021: Make a Difference with Simple A/B Testing - Danielle Gordon\"\n  speakers:\n    - Danielle Gordon\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    There are a lot of myths around A/B testing. They’re difficult to implement, difficult to keep track of, difficult to remove, and the costs don’t seem to outweigh the benefits unless you’re at a large company. But A/B tests don’t have to be a daunting task. And let’s be honest, how can you say you’ve made positive changes in your app without them?\n\n    A/B tests are a quick way to gain more user insight. We'll first start with a few easy A/B tests, then create a simple system to organise them. By then end, we'll see how easy it is to convert to a (A/B) Test Driven Development process.\n  video_provider: \"youtube\"\n  video_id: \"MnYmZKtj9Lc\"\n\n- id: \"daniel-magliola-railsconf-2021\"\n  title: \"Speed up your test suite by throwing computers at it\"\n  raw_title: \"RailsConf 2021: Speed up your test suite by throwing computers at it - Daniel Magliola\"\n  speakers:\n    - Daniel Magliola\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    You've probably experienced this. CI times slowly creep up over time and now it takes 20, 30, 40 minutes to run your suite. Multi-hour runs are not uncommon.\n\n    All of a sudden, all you're doing is waiting for CI all day, trying to context switch between different PRs. And then, a flaky test hits, and you start waiting all over again.\n\n    It doesn't have to be like this. In this talk I'll cover several strategies for improving your CI times by making computers work harder for you, instead of having to painstakingly rewrite your tests.\n  video_provider: \"youtube\"\n  video_id: \"ntTT64hK1no\"\n\n- id: \"denise-yu-railsconf-2021\"\n  title: \"The Power of Visual Narrative\"\n  raw_title: \"RailsConf 2021: The Power of Visual Narrative - Denise Yu\"\n  speakers:\n    - Denise Yu\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    As technologists, we spend a great deal of time trying to become better communicators. One secret to great communication is... to actually say less. And draw more!\n\n    I've been using sketchnotes, comics, and abstractly-technical doodles for the last few years to teach myself and others about technical concepts. Lo-fi sketches and lightweight storytelling devices can create unlikely audiences for any technical subject matter. I'll break down how my brain translates complex concepts into approachable art, and how anyone can start to do the same, regardless of previous artistic experience.\n  video_provider: \"youtube\"\n  video_id: \"a36JR0-rxz0\"\n\n- id: \"espartaco-palma-railsconf-2021\"\n  title: \"When words are more than just words: Don't BlackList us\"\n  raw_title: \"RailsConf 2021: When words are more than just words: Don't BlackList us - Espartaco Palma\"\n  speakers:\n    - Espartaco Palma\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    ow we communicate words is important, the code, test and documentation needs to be part of the ongoing process to treat better our coworkers, be clear on what we do without the need of established words as \"blacklist\". Do you mean restricted? rejected? undesirable? think again.\n\n    Master, slave, fat, archaic, blacklist are just a sample of actions you may not be aware of hard are for underrepresented groups. We, your coworkers can't take it anymore because all the suffering it create on us, making us unproductive, feeling second class employee or simply sad.\n\n    Let's make our code, a better code.\n  video_provider: \"youtube\"\n  video_id: \"nLGvYfeLMbM\"\n\n- id: \"frederick-cheung-railsconf-2021\"\n  title: \"How to A/B test with confidence\"\n  raw_title: \"RailsConf 2021: How to A/B test with confidence - Frederick Cheung\"\n  speakers:\n    - Frederick Cheung\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    A/B tests should be a surefire way to make confident, data-driven decisions about all areas of your app - but it's really easy to make mistakes in their setup, implementation or analysis that can seriously skew results!\n\n    After a quick recap of the fundamentals, you'll learn the procedural, technical and human factors that can affect the trustworthiness of a test. More importantly, I'll show you how to mitigate these issues with easy, actionable tips that will have you A/B testing accurately in no time!\n  video_provider: \"youtube\"\n  video_id: \"IsgQ9RJ0rJE\"\n\n- id: \"coraline-ada-ehmke-railsconf-2021\"\n  title: \"The Rising Storm of Ethics in Open Source\"\n  raw_title: \"RailsConf 2021: The Rising Storm of Ethics in Open Source - Coraline Ada Ehmke\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: |-\n    The increased debate around ethical source threatens to divide the OSS community. In his book \"The Structure of Scientific Revolutions\", philosopher Thomas Kuhn posits that there are three possible solutions to a crisis like the one we're facing: procrastination, assimilation, or revolution. Which will we choose as we prepare for the hard work of reconciling ethics and open source?\n  video_provider: \"youtube\"\n  video_id: \"CX3htKOeB14\"\n\n- id: \"corey-martin-railsconf-2021\"\n  title: \"Processing data at scale with Rails\"\n  raw_title: \"RailsConf 2021: Processing data at scale with Rails - Corey Martin\"\n  speakers:\n    - Corey Martin\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: |-\n    More of us are building apps to make sense of massive amounts of data. From public datasets like lobbying records and insurance data, to shared resources like Wikipedia, to private data from IoT, there is no shortage of large datasets. This talk covers strategies for ingesting, transforming, and storing large amounts of data, starting with familiar tools and frameworks like ActiveRecord, Sidekiq, and Postgres. By turning a massive data job into successively smaller ones, you can turn a data firehose into something manageable.\n  video_provider: \"youtube\"\n  video_id: \"8zTbcGDEDz4\"\n\n- id: \"john-athayde-railsconf-2021\"\n  title: \"Type Is Design: Fix Your UI with Better Typography and CSS\"\n  raw_title: \"RailsConf 2021: Type Is Design:Fix Your UI with Better Typography and CSS - John Athayde\"\n  speakers:\n    - John Athayde\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-28\"\n  description: |-\n    The written word is the medium through which most information exchanges hands in the tools we build. Digital letterforms can help or hinder the ability for people to communicate and understand. We'll work through some typographic principles and then apply them to the web with HTML and CSS for implementation. We'll look at some of the newer OpenType features and touch on the future of digital type, variable fonts, and more.\n  video_provider: \"youtube\"\n  video_id: \"1Pe7oGIKkqc\"\n\n- id: \"anthony-eden-railsconf-2021\"\n  title: \"10 Years In - The Realities of Running a Rails App Long Term\"\n  raw_title: \"RailsConf 2021: 10 Years In - The Realities of Running a Rails App Long Term - Anthony Eden\"\n  speakers:\n    - Anthony Eden\n  event_name: \"RailsConf 2021\"\n  date: \"2021-04-12\"\n  published_at: \"2022-09-27\"\n  description: |-\n    The first commit for the DNSimple application was performed in April 2010, when Ruby on Rails was on version 2.3. Today DNSimple still runs Ruby on Rails, version 6.0. The journey from of the DNSimple application to today's version is a study in iterative development. In this talk I will walk through the evolution of the DNSimple application as it has progressed in step with the development of Ruby on Rails. I'll go over what's changed, what's stayed the same, what worked, and where we went wrong.\n  video_provider: \"youtube\"\n  video_id: \"BWNWOxU8KCo\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2022/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyb2Mjtd1RBjeP3Jt9RukU7G\"\ntitle: \"RailsConf 2022\"\nkind: \"conference\"\nlocation: \"Portland, OR, United States\"\ndescription: |-\n  RailsConf, hosted by Ruby Central, is the world’s largest and longest-running gathering of Ruby on Rails enthusiasts, practitioners, and companies.\npublished_at: \"2022-11-09\"\nstart_date: \"2022-05-17\"\nend_date: \"2022-05-19\"\nyear: 2022\nbanner_background: \"#E8DED5\"\nfeatured_background: \"#E8DED5\"\nfeatured_color: \"#5A5655\"\ncoordinates:\n  latitude: 45.52853469999999\n  longitude: -122.6630046\n"
  },
  {
    "path": "data/railsconf/railsconf-2022/venue.yml",
    "content": "---\nname: \"Oregon Convention Center\"\n\naddress:\n  street: \"777 Northeast Martin Luther King Junior Boulevard\"\n  city: \"Portland\"\n  region: \"Oregon\"\n  postal_code: \"97232\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"777 NE Martin Luther King Jr Blvd, Portland, OR 97232, USA\"\n\ncoordinates:\n  latitude: 45.52853469999999\n  longitude: -122.6630046\n\nmaps:\n  google: \"https://maps.google.com/?q=Oregon+Convention+Center,45.52853469999999,-122.6630046\"\n  apple: \"https://maps.apple.com/?q=Oregon+Convention+Center&ll=45.52853469999999,-122.6630046\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=45.52853469999999&mlon=-122.6630046\"\n\nhotels:\n  - name: \"DoubleTree by Hilton Hotel Portland\"\n    kind: \"Speaker Hotel\"\n    address:\n      street: \"1000 Northeast Multnomah Street\"\n      city: \"Portland\"\n      region: \"Oregon\"\n      postal_code: \"97232\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"1000 NE Multnomah St, Portland, OR 97232, USA\"\n\n    coordinates:\n      latitude: 45.53075990000001\n      longitude: -122.6555863\n\n    maps:\n      google: \"https://maps.google.com/?q=DoubleTree+by+Hilton+Hotel+Portland,45.53075990000001,-122.6555863\"\n      apple: \"https://maps.apple.com/?q=DoubleTree+by+Hilton+Hotel+Portland&ll=45.53075990000001,-122.6555863\"\n\n  - name: \"Hotel Eastlund\"\n    address:\n      street: \"1021 Northeast Grand Avenue\"\n      city: \"Portland\"\n      region: \"Oregon\"\n      postal_code: \"97232\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"1021 NE Grand Ave, Portland, OR 97232, USA\"\n\n    coordinates:\n      latitude: 45.5304118\n      longitude: -122.660861\n\n    maps:\n      google: \"https://maps.google.com/?q=Hotel+Eastlund,45.5304118,-122.660861\"\n      apple: \"https://maps.apple.com/?q=Hotel+Eastlund&ll=45.5304118,-122.660861\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2022/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"aaron-patterson-railsconf-2022\"\n  title: \"Keynote: It's been a minute!\"\n  raw_title: \"RailsConf 2022 - Keynote: RailsConf 2022 - It's been a minute! by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  slides_url: \"https://speakerdeck.com/tenderlove/railsconf-2022-keynote\"\n  description: |-\n    Keynote: RailsConf 2022 - It's been a minute! by Aaron Patterson\n  video_provider: \"youtube\"\n  video_id: \"qqTFm2ZtRHg\"\n\n- id: \"sweta-sanghavi-railsconf-2022\"\n  title: \"`rails c` with me - turbocharge your use of the interactive console\"\n  raw_title: \"RailsConf 2022 - `rails c` with meturbocharge your use of the interactive console by Sweta Sanghavi\"\n  speakers:\n    - Sweta Sanghavi\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Spinning up the rails console can be a quick way to answer a question with a back of the envelope calculation. But, what else can we use it for, and how does it work? Allow me to show you new ways to leverage the console's features and become an even more expert debugger. You'll leave with some simple tactics to save you time and write more performant code. While you're here, we'll look under the hood to see how the features of the console are encoded and we'll trace back the history of these libraries to see how they arrived in our Rails application.\n  video_provider: \"youtube\"\n  video_id: \"AZquxGaSjGo\"\n\n- id: \"andy-glass-railsconf-2022\"\n  title: \"ELI5: A Game Show on Rails\"\n  raw_title: \"RailsConf 2022 - ELI5: A Game Show on Rails by Andy Glass\"\n  speakers:\n    - Andy Glass\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    ‘Those who know, do. Those that understand, teach.’\n\n    We might know our way around the classic conventions of our beloved Ruby on Rails, but do we understand them enough to explain those concepts to our peers? In this interactive (participation optional!) game show session, let’s find out!\n\n    After we quickly discuss some of the philosophies of teaching, we’ll divide up into teams and play a Jeopardy! meets Catchphrase hybrid game… with a few surprises along the way! Beginner, intermediate and advanced Rails-devs are welcome, and Portland-themed prizes will be awarded to the winners.\n  video_provider: \"youtube\"\n  video_id: \"kDmvIWv_9M8\"\n\n- id: \"chuck-lauer-vose-railsconf-2022\"\n  title: \"Don't page me! How we limit pager noise at New Relic\"\n  raw_title: \"RailsConf 2022 - Don't page me! How we limit pager noise at New Relic by Chuck Lauer Vose\"\n  speakers:\n    - Chuck Lauer Vose\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    New Relic's largest monolith handles 200k req/min and communicates with more than 40 external services and 11 mysql databases; this should result in constant downtime. Being mindful and alerting on the right things has been critical for us.\n\n    This talk will cover a successful process for identifying trustworthy data, refining alert conditions, and what kinds of checks to page on.\n  video_provider: \"youtube\"\n  video_id: \"uxWqX1KZAH8\"\n\n- id: \"nathan-griffith-railsconf-2022\"\n  title: \"RAILS_ENV=demo\"\n  raw_title: \"RailsConf 2022 - RAILS_ENV=demo by Nathan Griffith\"\n  speakers:\n    - Nathan Griffith\n  kind: \"talk\"\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Today’s the day. You’ve prepared your pitch, deployed a special copy of your app, and confirmed—in a trial run—that your walkthrough is ready for a live audience. But, now, when you attempt to log in, something breaks. Flustered, you debug, apologize, and debug some more, before finally calling it quits. Next time, you’ll bring a prerecorded screencast... 😮‍💨\n\n    What could’ve been done to make the app more reliably \"demoable\"? Join us, as we use \"stateful fakes\" and \"personas\" to produce a testable, maintainable, and failure-resistant \"demo\" deployment, with production-like uptime guarantees!\n  video_provider: \"youtube\"\n  video_id: \"N_2idFNGlkk\"\n\n- id: \"jamie-gaskins-railsconf-2022\"\n  title: \"If You Know Heroku, You Can Use Kubernetes\"\n  raw_title: \"RailsConf 2022 - If You Know Heroku, You Can Use Kubernetes by Jamie Gaskins\"\n  speakers:\n    - Jamie Gaskins\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    You've probably heard \"Kubernetes is overcomplicated! Just use Heroku!\" But it turns out that, while Kubernetes can be complicated, it doesn't have to be. In this talk, you'll learn how to deploy with Kubernetes in a way that is nearly as friendly as with Heroku.\n  video_provider: \"youtube\"\n  video_id: \"mN-BedLhkKQ\"\n\n- id: \"colin-loretz-railsconf-2022\"\n  title: '\"Build vs Buy\" on Rails'\n  raw_title: 'RailsConf 2022 - \"Build vs Buy\" on Rails by Colin Loretz'\n  speakers:\n    - Colin Loretz\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Your SaaS app is adding new engaged users every day and your roadmap is growing with features to delight them! Users are requesting new 3rd party integrations, more powerful search, reporting capabilities, and live chat, oh my!\n\n    Should you try and build all of these features? Should you work with partner services to add these features? The answer: it depends!\n\n    In 2022, the classic \"Build vs Buy\" question is more nuanced than ever and we'll dig into the pros and cons when building (or buying) on Rails.\n  video_provider: \"youtube\"\n  video_id: \"IbWkO1aljyE\"\n\n- id: \"xavier-noria-railsconf-2022\"\n  title: \"Opening Keynote: The Journey to Zeitwerk\"\n  raw_title: \"RailsConf 2022 - Opening Keynote: The Journey to Zeitwerk by Xavier Noria\"\n  speakers:\n    - Xavier Noria\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Opening Keynote: The Journey to Zeitwerk by Xavier Noria\n  video_provider: \"youtube\"\n  video_id: \"57AsQrxjLEs\"\n\n- id: \"joel-hawksley-railsconf-2022\"\n  title: \"Breaking up with the bundle\"\n  raw_title: \"RailsConf 2022 - Breaking up with the bundle by Joel Hawksley\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Breaking up with the bundle by Joel Hawksley\n\n    Over the course of 14 years, the GitHub.com CSS bundle grew to over 40,000 lines of custom CSS. It became almost impossible to refactor. Visual regressions were common. In this talk, we'll share an honest picture of our successes and failures as we've worked to break up with our CSS bundle by moving towards a component-driven UI architecture.\n  video_provider: \"youtube\"\n  video_id: \"LMmKEfjW468\"\n\n- id: \"annie-lydens-railsconf-2022\"\n  title: \"Spacecraft! The Care and Keeping of a Legacy Application\"\n  raw_title: \"RailsConf 2022 - Spacecraft! The care and keeping of a legacy ... by Annie Lydens & Jenny Allar\"\n  speakers:\n    - Annie Lydens\n    - Jenny Allar\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Spacecraft! The care and keeping of a legacy application\n    Annie Lydens & Jenny Allar\n\n    Join us for an allegorical journey aboard the spacecraft Legacy, where the astronauts desperately need to update their aging infrastructure. Their leader, a brave spaceperson named Yuki, knows these repairs must be completed before the team gets hit by a series of feature request asteroids. This talk is an ELI5 journey through the various strategies around assessing, improving, and bullet-proofing Rails apps in need of some cosmic maintenance.\n  video_provider: \"youtube\"\n  video_id: \"nE1xzf8tE9Y\"\n\n- id: \"chris-salzberg-railsconf-2022\"\n  title: \"Caching Without Marshal\"\n  raw_title: \"RailsConf 2022 - Caching Without Marshal by Chris Salzberg\"\n  speakers:\n    - Chris Salzberg\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Marshal is Ruby's ultimate sharp knife, able to transform any object into a binary blob and back. This makes it a natural match for the diverse needs of a cache.\n\n    But Marshal's magic comes with risks. Code changes can break deploys; user input can trigger an RCE.\n\n    We recently decided these risks were not worth it. Breaking with convention, we migrated the cache on our core monolith to MessagePack, a more compact binary serialization format with stricter typing and less magic.\n\n    In this talk, I'll pry Marshal open to show how it works, how we replaced it, and why you might want to do the same.\n  video_provider: \"youtube\"\n  video_id: \"fhnpaFRZ4Kw\"\n\n- id: \"brad-urani-railsconf-2022\"\n  title: \"Event Streaming on Rails\"\n  raw_title: \"RailsConf 2022 - Event Streaming on Rails by Brad Urani\"\n  speakers:\n    - Brad Urani\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Pop quiz: How do you best make one Rails app communicate with another? How do you split one big Rails app into two smaller ones? How do you switch from a Rails app to a constellation of Rails services? Event streaming provides the most robust answer. Simple but powerful Kafka streams unlock a world of capabilities with their durability and consistency, but integrating with Rails poses challenges. Join us and learn simple reading and writing to Kafka with Rails, broader distributed systems design, and the magical transactional outbox. You'll leave with the knowledge you need to make the switch.\n  video_provider: \"youtube\"\n  video_id: \"meJwkdaRnHw\"\n\n- id: \"cameron-dutro-railsconf-2022\"\n  title: \"Kuby: Active Deployment for Rails Apps\"\n  raw_title: \"RailsConf 2022 - Kuby: Active Deployment for Rails Apps by Cameron Dutro\"\n  speakers:\n    - Cameron Dutro\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    One of the Rails mantras is \"convention over configuration,\" sane defaults that limit the cognitive overhead of application development. It's easy to learn and easy to build with... right up until you want to deploy your app to production. At that point, the hand-holding ends. Like the Roadrunner, Rails stops right before the cliff and lets you, Wile E. Coyote, sail over the edge. We have active record for interacting with databases, active storage for storing files, etc, but where's active deployment? Come learn how Kuby, a new deployment tool, is trying to bridge the gap.\n  video_provider: \"youtube\"\n  video_id: \"PJeET-SZssM\"\n\n- id: \"thomas-countz-railsconf-2022\"\n  title: \"Leveling Up from Planning to Production\"\n  raw_title: \"RailsConf 2022 - Leveling Up from Planning to Production by Thomas Countz\"\n  speakers:\n    - Thomas Countz\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    The biggest difference between a mid-level engineer and a senior engineer is the scale and scope of the work they're responsible for. How do you dive into complex tasks, report progress to project leadership, and stay focused with so many unknowns?\n\n    These are the questions I've continued to ask myself as I grow in my career. In this session, we'll explore the tools myself and other senior-level individual contributors use to shape our work from project inception to delivery.\n  video_provider: \"youtube\"\n  video_id: \"AtW4gNzFpms\"\n\n- id: \"casey-watts-railsconf-2022\"\n  title: \"Evaluating Cultural Fit + Culturesmithing: Everyone Influences...\"\n  raw_title: \"RailsConf 2022 - Evaluating Cultural Fit + Culturesmithing: Everyone Influences... by Casey Watts\"\n  speakers:\n    - Casey Watts\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Evaluating Cultural Fit + Culturesmithing: Everyone Influences Culture\n    Casey Watts\n\n    “Toxic culture” is, by far, the number one reason that people are quitting their jobs. People are no longer willing to work at organizations where they don’t feel valued, respected, and included. Economists have dubbed this “The Great Resignation.” In this talk you will learn how this situation applies to you and what you can do to make things better. You will learn a framework for evaluating whether an organization’s culture meets your personal needs, and you will learn 20 immediately implementable techniques to improve this culture.\n  video_provider: \"youtube\"\n  video_id: \"SJ1f-LEf1X4\"\n\n- id: \"john-dewyze-railsconf-2022\"\n  title: \"Do You Trust Me? A look at Trust, Time, and Teams\"\n  raw_title: \"RailsConf 2022 - Do You Trust Me? A look at Trust, Time, and Teams by John DeWyze\"\n  speakers:\n    - John DeWyze\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    I've got a deal for you. You give me some trust, I'll give you some time back. No strings attached.\n\n    Trust is core to working on a team. We give a little trust, so we can save time. We use systems to create/protect/and outsource trust: PRs, pairing, code cov, type systems, etc. Join me for an exploration of trust in engineering, the psychology of trust, its relationship to time, and how we can have better trust rituals when we reframe the goal. So give me a little of your time and I'll teach you a little about trust. Do we have a deal?\n  video_provider: \"youtube\"\n  video_id: \"EqyBLQHLMgE\"\n\n- id: \"mina-slater-railsconf-2022\"\n  title: \"The Little Engines That Could\"\n  raw_title: \"RailsConf 2022 - The Little Engines That Could by Mina Slater\"\n  speakers:\n    - Mina Slater\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Rails Engines. It’s more than just a cute name made up of two words both related to trains.\n\n    Are they plug-ins? Are they microservices? When do we use them? How do we implement them? Why aren’t they used more often?\n\n    Those are the questions I wish were answered for me when I first learned about Rails Engines. Inspired by Wired’s Explain In 5 Levels series, we will explore Rails Engines and address these quandaries using a variety of techniques, breaking down what engines are and how and when to use them.\n  video_provider: \"youtube\"\n  video_id: \"EMKIJTricf4\"\n\n- id: \"charles-nutter-railsconf-2022\"\n  title: \"Scaling Rails with JRuby in 2022\"\n  raw_title: \"RailsConf 2022 - Scaling Rails with JRuby in 2022 by Charles Oliver Nutter\"\n  speakers:\n    - Charles Nutter\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    JRuby is back in 2022 with Ruby 3.1 support and new work on performance and scaling. For over a decade, Ruby users have turned to JRuby to get access to world-class garbage collection, native JIT compilation for increased performance, and true parallel threading. Today, you can take your Rails app and reduce both latency and resource costs by hosting a single JRuby process for all your concurrent users. JRuby is the only alternative Ruby deployed at scale, powering companies all over the world in mission critical areas. Come see how JRuby can help you scale today!\n  video_provider: \"youtube\"\n  video_id: \"Y4Jt1I8lCK4\"\n\n- id: \"david-hill-railsconf-2022\"\n  title: \"React-ing to Hotwire\"\n  raw_title: \"RailsConf 2022 - React-ing to Hotwire by David Hill\"\n  speakers:\n    - David Hill\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    I was fully onboard with React as my front-end Javascript framework of choice for years. That all changed when I suddenly had to support a stand-alone React app that I had no hand in building. Thankfully Hotwire had just been released, and my manager was aware of how painful maintaining this application was going to be. So I started the process of migrating the React app into the Rails app, using Hotwire as the new front-end framework. How did it go, what lessons were learned, and would I do it again?\n  video_provider: \"youtube\"\n  video_id: \"SS7LoJKkmYs\"\n\n- id: \"thijs-cadier-railsconf-2022\"\n  title: \"How music works, using Ruby\"\n  raw_title: \"RailsConf 2022 - How music works, using Ruby by Thijs Cadier\"\n  speakers:\n    - Thijs Cadier\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    That strange phenomenon where air molecules bounce against each other in a way that somehow comforts you, makes you cry, or makes you dance all night: music. Since the advent of recorded audio, a musician doesn't even need to be present anymore for this to happen (which makes putting \"I will always love you\" on repeat a little less awkward).\n\n    Sound engineers have found many ways of making music sound good when played from a record. Some of their methods have become industry staples used on every recording released today.\n\n    Let's look at what they do and reproduce some of their methods in Ruby!\n  video_provider: \"youtube\"\n  video_id: \"Qi3kEj41NwA\"\n\n- id: \"kevin-menard-railsconf-2022\"\n  title: \"Service Denied! Understanding How Regex DoS Attacks Work\"\n  raw_title: \"RailsConf 2022 - Service Denied! Understanding How Regex DoS Attacks Work by Kevin Menard\"\n  speakers:\n    - Kevin Menard\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Did you know that people can knock your Rails application offline just by submitting specially formatted strings in a form or API request? In this talk, we’ll take a look at what’s really going on with a regex denial of service (DoS) attack. We’ll take a peek into the CRuby regex engine to see what it’s really doing when we ask it to match against a string. With a basic understanding of how regular expressions work, we can better understand what these attacks do, why they tie up so much CPU, and what we can do to guard against them.\n  video_provider: \"youtube\"\n  video_id: \"XpF3H6w1NSY\"\n\n- id: \"ifat-ribon-railsconf-2022\"\n  title: \"Call me back, Postgres\"\n  raw_title: \"RailsConf 2022 - Call me back, Postgres by Ifat Ribon\"\n  speakers:\n    - Ifat Ribon\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Rails' Active Record callbacks provide a simple interface for executing a process when something happens to a database record. However, sometimes Active Record callbacks aren’t the best solution available. For those cases, this talk introduces a great alternative: Postgres' trigger functionality, a way of implementing callbacks at the database level. Coupled with Postgres' listen and notify features, you can develop creative solutions for making your Rails app the center of an otherwise complex system, managing data syncing and other processes seamlessly, regardless of consumers of the app.\n  video_provider: \"youtube\"\n  video_id: \"ZwxX58q1a5A\"\n\n- id: \"crystal-tia-martin-railsconf-2022\"\n  title: \"Keynote: A tech görl origin story\"\n  raw_title: \"RailsConf 2022 - Keynote: A tech görl origin story by Crystal Tia Martin\"\n  speakers:\n    - Crystal Tia Martin\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Keynote: A tech görl origin story by Crystal Tia Martin\n  video_provider: \"youtube\"\n  video_id: \"4dLqPN7ozpo\"\n\n- id: \"stephen-prater-railsconf-2022\"\n  title: \"O(1), O(n) and O(#$*&!)\"\n  raw_title: \"RailsConf 2022 - O(1), O(n) and O(#$*&!) by Stephen Prater\"\n  speakers:\n    - Stephen Prater\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Reasoning about the performance of your code doesn't need to require a PhD in computer science or specialized tooling - We'll learn how to quickly recognize and diagnose common performance issues like excessive algorithmic complexity and IO waiting using OpenTelemetry compatible tools. Then we'll fix those issues, and ensure that they stay fixed using automated performance testing, even as your application grows.\n  video_provider: \"youtube\"\n  video_id: \"c7CHdAhf85g\"\n\n- id: \"daniel-magliola-railsconf-2022\"\n  title: \"Git your PR accepted. Rebase your changes like a pro\"\n  raw_title: \"RailsConf 2022 - Git your PR accepted. Rebase your changes like a pro by Daniel Magliola\"\n  speakers:\n    - Daniel Magliola\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    You want to contribute to an Open Source project, and you have a complex PR to submit. You've tried to keep it small, but sadly getting there took a lot of effort and your branch has more than 30 commits with fixes and reverting of dead ends.\n\n    You know reviewing this will be a nightmare for the project maintainers, and more importantly, it will be almost impossible for anyone in the future to understand what you did by looking at the history.\n\n    In this talk we will look at how Git branches work, and how to manicure them using Rebase to build a commit history your colleagues will love you for.\n  video_provider: \"youtube\"\n  video_id: \"KNtwDdUEXRw\"\n\n- id: \"fernando-petrales-railsconf-2022\"\n  title: \"Open the gate a little: strategies to protect and share data\"\n  raw_title: \"RailsConf 2022 - Open the gate a little: strategies to protect and share data by Fernando Perales\"\n  speakers:\n    - Fernando Perales\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Open the gate a little: strategies to protect and share data\n    Can you name a more terrifying set of three words in software development than \"HIPAA violation fines\"? I bet you can't.\n\n    We know we know we must protect access to our information at all costs, sometimes we need to provide access for legitimate reasons to our production data and this brings a dilemma to us: how to do it while minimizing the risks of data leakage.\n\n    In this talk I'll share some strategies that can give you some guidance on when to close the door, when to open the door and when to open the door to your information a little\n  video_provider: \"youtube\"\n  video_id: \"TYgwg33E81c\"\n\n- id: \"daniel-colson-railsconf-2022\"\n  title: \"Reflecting on Active Record Associations\"\n  raw_title: \"RailsConf 2022 - Reflecting on Active Record Associations by Daniel Colson\"\n  speakers:\n    - Daniel Colson\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  slides_url: \"https://speakerdeck.com/dodecadaniel/railsconf-2022-reflecting-on-active-record-associations\"\n  description: |-\n    Active Record associations seem magical—add a has_many here, a belongs_to there, and suddenly your models are loaded with behavior. Could it be magic, or is it plain old Ruby with some thoughtful design and a bit of metaprogramming? In this talk we'll study Active Record associations by writing our own belongs_to and has_many macros. We'll dynamically define methods, cache query results, replace a a Relation with a CollectionProxy, and automatically prevent N+1 queries with inverses. You'll leave with a deeper understanding of associations, and a new appreciation for their magic.\n  video_provider: \"youtube\"\n  video_id: \"ImwNMYjRMSg\"\n\n- id: \"john-crepezzi-railsconf-2022\"\n  title: \"Experimental Patterns in ActiveRecord\"\n  raw_title: \"RailsConf 2022 - Experimental Patterns in ActiveRecord by John Crepezzi\"\n  speakers:\n    - John Crepezzi\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    ActiveRecord provides a great deal of flexibility and speed of implementation for developers making new apps. As our teams and codebase grow and our services need to continue to scale, some of the patterns we use can start to get in our way. We've seen a bit of that at GitHub, and as a result have been experimenting with some new ways to work with ActiveRecord queries, reduce N+1s, and isolate model details.\n\n    In this talk, I'll go over some the problems we've been facing, cover how we've been addressing them so far, and show some new experiments & patterns I've been working through.\n  video_provider: \"youtube\"\n  video_id: \"-nrQDbRK5TM\"\n\n- id: \"vaidehi-joshi-railsconf-2022\"\n  title: \"Keynote: Meditations on Software\"\n  raw_title: \"RailsConf 2022 - Keynote: Meditations on Software by Vaidehi Joshi\"\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Keynote: Meditations on Software by Vaidehi Joshi\n  video_provider: \"youtube\"\n  video_id: \"t46d9GUXy0A\"\n\n- id: \"andy-croll-railsconf-2022\"\n  title: \"The Mrs Triggs Problem\"\n  raw_title: \"RailsConf 2022 - The Mrs Triggs Problem by Andy Croll\"\n  speakers:\n    - Andy Croll\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    \"That's a good suggestion Mrs Triggs, perhaps one of the men in the room would like to make it?\"\n\n    As a society we have an attribution problem. People who look like me get it easy. Join me to explore how we can push back on the default stories & myths of who is providing value in our community.\n\n    Warning, may contain content that will make you uncomfortable about your own past behaviour. But you'll leave better able to provide a better industry for your fellow humans.\n  video_provider: \"youtube\"\n  video_id: \"rj1Mqly3XI4\"\n\n- id: \"adam-cuppy-railsconf-2022\"\n  title: \"Don't touch that!\"\n  raw_title: \"RailsConf 2022 - Don't touch that! by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Ruby on Rails is a huge framework. There are modules, classes, established conventions, and a slew of code that's meant to be off-limits. But, what if we took our ornery childish self and played around? This is a talk about strategies for debugging, taught through the lens of experimentation and childish play. In this talk, we will override, extend, and disable all sorts of Rails internals and see what happens.\n  video_provider: \"youtube\"\n  video_id: \"GAtCF44yufw\"\n\n- id: \"christopher-aji-slater-railsconf-2022\"\n  title: \"Your TDD Treasure Map\"\n  raw_title: 'RailsConf 2022 - Your TDD Treasure Map by Christopher \"Aji\" Slater'\n  speakers:\n    - Christopher \"Aji\" Slater\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  slides_url: \"https://speakerdeck.com/doodlingdev/your-tdd-treasure-map\"\n  description: |-\n    We know testing is vital and makes refactoring painless. But how to set sail to that TDD treasure? Yarr, we need to test to get experience, but need experience to test. Let’s draw a map with simple strategies for identifying test cases and building a robust test suite. X marks the spot w/ TDD tools for newbies and seasoned pirates alike.\n  video_provider: \"youtube\"\n  video_id: \"jCgb4JjqQVA\"\n\n- id: \"jol-quenneville-railsconf-2022\"\n  title: \"Your test suite is making too many database calls!\"\n  raw_title: \"RailsConf 2022 - Your test suite is making too many database calls! by Joël Quenneville\"\n  speakers:\n    - Joël Quenneville\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  slides_url: \"https://speakerdeck.com/joelq/your-test-suite-is-making-too-many-database-calls\"\n  description: |-\n    On a recent project, I sped up a test suite 15% by making a change to a single factory. This suite, like many others (including yours!), was making way too many database calls. It’s so easy to accidentally add extra queries to factories and test setup and these can compound to shockingly large numbers.\n\n    The chaos is your opportunity! Learn to profile and fix hot spots, build big-picture understanding through diagrams, and write code that is resistant to extraneous queries. This talk will equip you to take back control of your build times and maybe impress your teammates in the process.\n  video_provider: \"youtube\"\n  video_id: \"QeuVM0zai60\"\n\n- id: \"maeve-revels-railsconf-2022\"\n  title: \"Testing legacy code when you dislike tests (and legacy code)\"\n  raw_title: \"RailsConf 2022 - Testing legacy code when you dislike tests (and legacy code) by Maeve Revels\"\n  speakers:\n    - Maeve Revels\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Are you supporting legacy code? Would you like to stop? A good testing strategy can transform legacy code into living code that is resilient and easy to evolve.\n\n    Learn why legacy code is so difficult to maintain and identify where tests can make the most impact. Not just any tests, though! We'll dive into the characteristics of high-value versus low-value tests and learn techniques for writing tests that minimize the cost of change.\n\n    Developers of any experience level can benefit from these concepts. Familiarity with Rails and an automated testing framework is helpful but not required.\n  video_provider: \"youtube\"\n  video_id: \"ufIGaySoQWY\"\n\n- id: \"alex-evanczuk-railsconf-2022\"\n  title: \"Laying the Cultural and Technical Foundation for Big Rails\"\n  raw_title: \"RailsConf 2022 - Laying the Cultural and Technical Foundation for Big Rails by Alex Evanczuk\"\n  speakers:\n    - Alex Evanczuk\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    As applications built on Rails get larger and larger, and more and more engineers work in the same monolith, our community needs to think more about what sort of tooling and architectural changes will help us continue to scale. This talk shares ideas around a toolchain, and more importantly, the social and cultural programs needed to support that toolchain, that can be used to help engineers in an ever-growing Rails codebase continue to have high velocity, manage their complexity, and claim ownership over their own business subdomains.\n  video_provider: \"youtube\"\n  video_id: \"xBFUVl91JtI\"\n\n- id: \"david-copeland-railsconf-2022\"\n  title: \"Your Service Layer Needn't be Fancy, It Just Needs to Exist\"\n  raw_title: \"RailsConf 2022 - Your Service Layer Needn't be Fancy, It Just Needs to Exist by David Copeland\"\n  speakers:\n    - David Copeland\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Where would you put your business logic if not in Active Records? The answer is a service layer. Your service layer provides a seam between your user interface and your database that contains all the code that makes your app your app. This single design decision will buoy your app's sustainability for years. You'll learn why this is and how to start a service layer today without any patterns, principles, or fancy libraries.\n  video_provider: \"youtube\"\n  video_id: \"xFDn4TxKDrQ\"\n  slides_url: \"https://davetron5000.github.io/service-layer-railsconf-2022/\"\n\n- id: \"sean-marcia-railsconf-2022\"\n  title: \"Pictures Of You, Pictures Of Me, Crypto Steganography\"\n  raw_title: \"RailsConf 2022 - Pictures Of You, Pictures Of Me, Crypto Steganography by Sean Marcia\"\n  speakers:\n    - Sean Marcia\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    I was puzzled when a friend sent me a Buffy the Vampire Slayer picture out of the blue but, knowing that friend is an oddball, thought nothing of it. Days later, again without warning, a Babylon 5 picture. A few days after that a picture from Firefly. Then he repeated the pictures. A cryptic comment led me to understand that there was more to them than met the eye. Come learn the history, applications, and math behind crypto steganography how unravelling the mystery of the pictures culminated in the resolution of a 15 year rivalry when the US Olympic men’s curling team won the gold in 2018.\n  video_provider: \"youtube\"\n  video_id: \"GQgnUHF2SNE\"\n\n- id: \"mercedes-bernard-railsconf-2022\"\n  title: \"Come on in! Making yourself at home in a new codebase\"\n  raw_title: \"RailsConf 2022 - Come on in! Making yourself at home in a new codebase by Mercedes Bernard\"\n  speakers:\n    - Mercedes Bernard\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    \"Welcome! We're so excited to have you 🤗 please excuse the mess.\" – if a codebase could talk\n\n    When we join a new team or start a new project, we have to onboard to the codebase. Diving into code that we're unfamiliar with can be stressful or make us feel like we don't know what we're doing. And the longer the codebase has been around, the more intense those feelings can be. But there are steps we can take to understand new code and start contributing quickly. In this talk, we'll cover how to build our code comprehension skills and how to make our own code welcoming to guests in the future.\n  video_provider: \"youtube\"\n  video_id: \"-Fpb4c7_vcU\"\n\n- id: \"maple-ong-railsconf-2022\"\n  title: \"A Rails Developer’s Guide To The Ruby VM\"\n  raw_title: \"RailsConf 2022 - A Rails Developer’s Guide To The Ruby VM by Maple Ong\"\n  speakers:\n    - Maple Ong\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    What happens under the hood when you run a Ruby script as simple as puts “Hello World!”?\n\n    Time to switch gears from the Rails-level of abstraction to a lower one and dive into some Ruby internals. We’ll be learning about how the Ruby code you write gets compiled and executed, then zoom in to the VM-level – what VMs are and what they do, and how the Ruby VM works. You’ll walk away with a better understanding of how Ruby and Rails works as a whole. No low-level systems knowledge needed!\n  video_provider: \"youtube\"\n  video_id: \"1LTM3KPiruo\"\n\n- id: \"justin-powers-railsconf-2022\"\n  title: \"You have 2 seconds to respond\"\n  raw_title: \"RailsConf 2022 - You have 2 seconds to respond - Atob - Justin Powers\"\n  speakers:\n    - Justin Powers\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    You have 2 seconds to respond - Atob - Justin Powers\n  video_provider: \"youtube\"\n  video_id: \"oCN-uA2oeeY\"\n\n- id: \"noel-rappin-railsconf-2022\"\n  title: \"More Engineers, More Problems: Solutions for Big Teams\"\n  raw_title: \"RailsConf 2022 - More Engineers, More Problems: Solutions for Big Teams - Chime -\"\n  speakers:\n    - Noel Rappin\n    - David Trejo\n    - Brian Lesperance\n    - Chris Dwan\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    More Engineers, More Problems: Solutions for Big Teams\n     - Chime - Noel Rappin, David Trejo, Brian Lesperance, Chris Dwan\n  video_provider: \"youtube\"\n  video_id: \"BJWeKT7H7EA\"\n\n- id: \"kayla-reopelle-railsconf-2022\"\n  title: \"Finding the Needle in the Stack Trace: APM Logs-in-Context\"\n  raw_title: \"RailsConf 2022 - Finding the Needle in the Stack Trace: APM Logs-in-Context - New Relic -\"\n  speakers:\n    - Kayla Reopelle\n    - Mike Neville-O'Neill\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Finding the Needle in the Stack Trace: APM Logs-in-Context\n    - New Relic - Kayla Reopelle and Mike Neville-O'Neill\n  video_provider: \"youtube\"\n  video_id: \"J-KFRqA_SPY\"\n\n- id: \"eric-weinstein-railsconf-2022\"\n  title: \"Functional Programming in Plain Terms\"\n  raw_title: \"RailsConf 2022 - Functional Programming in Plain Terms by Eric Weinstein\"\n  speakers:\n    - Eric Weinstein\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Have you ever wanted to know what a monad is? How about a functor? What about algebraic data types and parametric polymorphism? If you've been interested in these ideas but scared off by the language, you're not alone: for an approach that champions composing simple pieces, functional programming is full of complex jargon. In this talk, we'll cover these topics from a Ruby and Rails perspective, composing small ideas in everyday language. Before we're through, you'll have a rich new set of FP ideas to apply to your projects—and you'll finally learn what a monad is (hint: it's not a burrito).\n  video_provider: \"youtube\"\n  video_id: \"ffvOnr4TbAg\"\n\n- id: \"vladimir-dementyev-railsconf-2022\"\n  title: \"The pitfalls of realtime-ification\"\n  raw_title: \"RailsConf 2022 - The pitfalls of realtime-ification by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Building realtime applications with Rails has become a no-brainer since Action Cable came around. With Hotwire, we don't even need to leave the comfort zone of HTML and controllers to introduce live updates to a Rails app. Realtime-ification in every house!\n\n    Switching to realtime hides many pitfalls you'd better learn beforehand. How to broadcast personalized data? How not to miss updates during connection losses? Who's online? Does it scale?\n\n    Let me dig into these problems and demonstrate how to resolve them for Action Cable and Hotwire.\n  video_provider: \"youtube\"\n  video_id: \"p54ejYrGYEg\"\n\n- id: \"jason-charnes-railsconf-2022\"\n  title: \"Start Your Ruby Podcast Today! No Experience Required\"\n  raw_title: \"RailsConf 2022 - Start Your Ruby Podcast Today! No Experience Required by Jason Charnes\"\n  speakers:\n    - Jason Charnes\n    - Chris Oliver\n    - Andrew Mason\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    In 2018 a hot new Ruby meetup appeared online. 🔥 Three meetups later, it was gone. 😭\n\n    This failed experiment paved the way for a new Ruby podcast: Remote Ruby. 170 episodes later, we've learned a lot! We had no previous experience podcasting before the first episode. Along the way we've learned things like what kind of gear to use, how to perform interviews, and affirmed just how lovely the Ruby community is.\n\n    It's your turn! Come to learn from our mistakes, leave ready to start a podcast!\n  video_provider: \"youtube\"\n  video_id: \"OVH9vmiFY2g\"\n\n- id: \"brandon-weaver-railsconf-2022\"\n  title: \"Behind the Lemurs - Creating an Illustrated Talk\"\n  raw_title: \"RailsConf 2022 - Behind the Lemurs - Creating an Illustrated Talk by Brandon Weaver\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Perhaps you've heard of a magical band of cartoon lemurs with a love for teaching Ruby, but what exactly goes into making one of these talks? We'll look at my entire toolset and process for creating illustrated conference talks including ideation, storyboarding, art, code tie-ins, and more. Perhaps you'll even learn to make a few lemurs of your own!\n  video_provider: \"youtube\"\n  video_id: \"_8nXpuYPaHo\"\n\n- id: \"chelsea-kaufman-railsconf-2022\"\n  title: \"Learn it, Do it, Teach it: How to Unstick Our Middle Devs\"\n  raw_title: \"RailsConf 2022 - Learn it, Do it, Teach it: How to Unstick Our Middle Devs by Chelsea Kaufman\"\n  speakers:\n    - Chelsea Kaufman\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    One definition of the middle: a difficult or unpleasant position. Yuck! It certainly can feel that way for mid-level developers. Fortunately, we've uncovered a model that will help managers create an environment where their devs can thrive. Our Learn it Do it Teach it (LDT) model will foster more learning, while keeping their hands on the code, and adding in the magic touch, teaching. This talk will demonstrate how managers can implement a LDT model into a developer’s day to day. Growth plans like this model will allow your team to move from mids into seniors both faster and more confidently.\n  video_provider: \"youtube\"\n  video_id: \"TQ3o1fXANtQ\"\n\n- id: \"zaid-zawaideh-railsconf-2022\"\n  title: \"Building a diverse engineering team\"\n  raw_title: \"RailsConf 2022 - Building a diverse engineering team - Wrapbook - Zaid Zawaideh & Jessica Lawrence\"\n  speakers:\n    - Zaid Zawaideh\n    - Jessica Lawrence\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Building a diverse engineering team - Wrapbook -  Zaid Zawaideh & Jessica Lawrence\n  video_provider: \"youtube\"\n  video_id: \"55KN3d_VVs0\"\n\n- id: \"jake-anderson-railsconf-2022\"\n  title: \"Growing Your Background Job Knowledge\"\n  raw_title: \"RailsConf 2022 - Growing Your Background Job Knowledge - Weedmaps - Jake Anderson\"\n  speakers:\n    - Jake Anderson\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Growing Your Background Job Knowledge\n    - Weedmaps - Jake Anderson\n  video_provider: \"youtube\"\n  video_id: \"DaRj3DkVWyE\"\n\n- id: \"mike-dalessio-railsconf-2022\"\n  title: \"The Future of Ruby on Rails at Shopify\"\n  raw_title: \"RailsConf 2022 - Shopify\"\n  speakers:\n    - Mike Dalessio\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Shopify\n  video_provider: \"youtube\"\n  video_id: \"yfEJxRtIOEw\"\n\n- id: \"eileen-m-uchitelle-railsconf-2022\"\n  title: \"Keynote: The Success of Ruby on Rails - Ensuring Growth for the Next 100 Years\"\n  raw_title: \"RailsConf 2022 - Keynote: The Success of Ruby on Rails by Eileen Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  slides_url: \"https://speakerdeck.com/eileencodes/the-success-of-rails-ensuring-growth-for-the-next-100-years\"\n  description: |-\n    Keynote: The Success of Ruby on Rails by Eileen M. Uchitelle\n  video_provider: \"youtube\"\n  video_id: \"p17xn05zc9c\"\n\n- id: \"cristian-planas-railsconf-2022\"\n  title: \"A Rails Performance Guidebook: from 0 to 1B requests/day\"\n  raw_title: \"RailsConf 2022 - A Rails Performance Guidebook: from 0 to 1B requests/day by Cristian Planas\"\n  speakers:\n    - Cristian Planas\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Building a feature is not good enough anymore: all your work won't be of use if it's not performant enough. So how to improve performance? After all, performance is not an easy discipline to master: all slow applications are slow in their own way, meaning that there is no silver bullet for these kinds of problems.\n\n    In this presentation, we will guide you across patterns, strategies, and little tricks to improve performance. We will do that by sharing real stories of our daily experience facing and solving real performance issues in an application that daily serves billions of requests per day.\n  video_provider: \"youtube\"\n  video_id: \"Suz-R3LfFCk\"\n\n- id: \"claudio-baccigalupo-railsconf-2022\"\n  title: \"Unboxing Rails 7: What's new in the latest major version\"\n  raw_title: \"RailsConf 2022 - Unboxing Rails 7What's new in the latest major version by Claudio Baccigalupo\"\n  speakers:\n    - Claudio Baccigalupo\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Rails 7.0 removes webpacker and spring from the default stack, adds encrypted attributes, allows for asynchronous query loading, changes autoloading defaults, attaches comments to Active Record queries, and introduces new tools for front-end development.\n\n    Learn about these and many other Pull Requests that were merged in rails/rails in 2021. Understand the motivation behind some architectural decisions. Review the process to upgrade from Rails 6.1 to Rails 7.\n  video_provider: \"youtube\"\n  video_id: \"lBBiOmqnNCs\"\n\n- id: \"gui-vieira-railsconf-2022\"\n  title: \"GraphQL and Rails beyond HTTP APIs\"\n  raw_title: \"RailsConf 2022 - GraphQL and Rails beyond HTTP APIs by Gui Vieira\"\n  speakers:\n    - Gui Vieira\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Are you considering building a GraphQL API for your Rails project or already have one? Do you know GraphQL can be leveraged beyond HTTP APIs?\n\n    We will explore how GraphQL does not depend on HTTP and can be used as a secure and structured data layer for Rails projects. You will learn to deliver real-time GGraphQL through Websockets, Webhooks containing all the data you need, provide data for WebAssembly code and parallelize queries exporting large amounts of data. Every Rails project needs consistent access to data and GraphQL brings solutions beyond the typical HTTP API.\n  video_provider: \"youtube\"\n  video_id: \"BR1B9vR8d2w\"\n\n- id: \"ian-norris-railsconf-2022\"\n  title: \"Ooops! You named it wrong. What now?\"\n  raw_title: \"RailsConf 2022 - Ooops! You named it wrong. What now? by Ian Norris & Melissa Hunt Glickman\"\n  speakers:\n    - Ian Norris\n    - Melissa Hunt Glickman\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    You hear everybody talk about the newest feature to Widgets but you can’t find a single model reference to that in the code. What happened? Sometimes the business changes aren’t reflected in the code. Sometimes, you're missing information or the code grows into something different. What do you do? ‘Cuz you still gotta ship.\n\n    Buckle up for a fast paced ride through the opportunities and pitfalls faced when you find yourself in this position. Through success and failure stories, learn how to leave space for names to breathe, make changes safely, and walking that fine line of changing just in time.\n  video_provider: \"youtube\"\n  video_id: \"52Qzgf2Xvi4\"\n\n- id: \"kevin-murphy-railsconf-2022\"\n  title: \"Browser History Confessional: Searching My Recent Searches\"\n  raw_title: \"RailsConf 2022 - Browser History Confessional: Searching My Recent Searches by Kevin Murphy\"\n  speakers:\n    - Kevin Murphy\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  slides_url: \"https://speakerdeck.com/kevinmurphy/browser-history-confessional-searching-my-recent-searches\"\n  description: |-\n    We all only have so much working memory available in our brains. Developers may joke about spending their day composing search engine queries. The reason it's a joke is because of the truth behind it. Search-driven development is a reality.\n\n    Join me, and my actual search history, on a journey to solve recent challenges I faced. I'll categorize the different types of information I often search for. You'll leave with tips on retrieving the knowledge you need for your next bug, feature, or pull request.\n  video_provider: \"youtube\"\n  video_id: \"UVvC6shN83U\"\n\n- id: \"andy-andrea-railsconf-2022\"\n  title: \"Computer science you might (not) want to know\"\n  raw_title: \"RailsConf 2022 - Computer science you might (not) want to know by Andy Andrea\"\n  speakers:\n    - Andy Andrea\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    One common recommendation for aspiring software developers is to pursue a degree in Computer Science (CS). While CS curricula do often cover practical software development skills, many departments heavily prioritize more academic and theoretical topics. This begs the question: how relevant is a CS degree to the day-to-day work of a professional developer?\n\n    We’ll look at a few topics that are often included in the first half of an undergraduate CS curriculum. We’ll examine this information through two lenses: why it can be helpful and why it might not be all that relevant for a typical Rails dev.\n  video_provider: \"youtube\"\n  video_id: \"b7R9CFAZV2E\"\n\n- id: \"ashley-ellis-pierce-railsconf-2022\"\n  title: \"Gem install: What could go wrong?\"\n  raw_title: \"RailsConf 2022 - Gem install: What could go wrong? by Ashley Ellis Pierce & Betty Li\"\n  speakers:\n    - Ashley Ellis Pierce\n    - Betty Li\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    The open source gem ecosystem is a major strength of Ruby and it’s not uncommon for a production Rails application to depend upon hundreds of gems. But what are the risks of installing a gem and having it in your Gemfile?\n\n    In this talk, we’ll cover what “bad things” can actually happen when you install a gem. We’ll also talk about the ways of preventing these attacks from occurring in your application dependencies (so you can sleep well at night).\n  video_provider: \"youtube\"\n  video_id: \"e5_3kL0SdzM\"\n\n- id: \"justin-bowen-railsconf-2022\"\n  title: \"The Queue Continuum: Applied Queuing Theory\"\n  raw_title: \"RailsConf 2022 - The Queue Continuum: Applied Queuing Theory by Justin Bowen\"\n  speakers:\n    - Justin Bowen\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    A Star Trek themed exploration of queuing theory and scaling applications with parallelism and concurrency. A general overview of the differences between parallelism and concurrency as well as when to apply more threads or more processes. We’ll go over examples of sidekiq and puma with different concurrency settings in various IO scenarios.\n  video_provider: \"youtube\"\n  video_id: \"N6LxQkyky3w\"\n\n- id: \"nick-schwaderer-railsconf-2022\"\n  title: \"Ruby Archaeology\"\n  raw_title: \"RailsConf 2022 - Ruby Archaeology by Nick Schwaderer\"\n  speakers:\n    - Nick Schwaderer\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    In 2009 _why tweeted: \"programming is rather thankless. you see your works become replaced by superior works in a year. unable to run at all in a few more.\"\n    I take this as a call to action to run old code. In this talk we dig, together, through historical Ruby. We will have fun excavating interesting gems from the past.\n\n    Further, I will answer the following questions:\n\n    What code greater than 12 years old still runs in Ruby 3.1?\n    What idioms have changed?\n    And for the brave: how can you set up an environment to run Ruby 1.8 code from ~2008 on a modern machine?\n  video_provider: \"youtube\"\n  video_id: \"53ueEIS0cng\"\n\n- id: \"andrea-fomera-railsconf-2022\"\n  title: \"Upgrading Rails: Everyone can do it and here’s how\"\n  raw_title: \"RailsConf 2022 - Upgrading Rails: Everyone can do it and here’s how by Andrea Fomera\"\n  speakers:\n    - Andrea Fomera\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Ever felt overwhelmed when figuring out how to upgrade a Rails app? Unsure where you should begin? We’ll talk about how upgrading should be treated as a feature, and how you can get buy-in from management for upgrading Rails. Have you heard about how GitHub or Shopify uses dual-booting to run two versions of Rails at once and wondered how that works? We’ll talk about three approaches you can use to upgrade your app. You’ll leave this talk with takeaways you can put into practice for your next Rails upgrade.\n  video_provider: \"youtube\"\n  video_id: \"NHZCQeh91p0\"\n\n- id: \"amy-newell-railsconf-2022\"\n  title: \"Let Your Body Lead: Career Planning With Somatics\"\n  raw_title: \"RailsConf 2022 - Let Your Body Lead: Career Planning With Somatics by Amy Newell\"\n  speakers:\n    - Amy Newell\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    How do you build a career you love? As engineers we try to make choices based on data, metrics, research. We make spreadsheets and “Compare Features.” And yet...so often we end up unhappy. All that careful research somehow doesn’t help.\n\n    But what if you made decisions a different way? What if you had a sophisticated decision-making apparatus to guide you, built precisely to your needs -- an always-available guide?\n\n    You do! It’s called your somatic intelligence. With practice you can learn to tune into it and let your body lead the way to satisfaction and fulfillment -- in every area of your life.\n  video_provider: \"youtube\"\n  video_id: \"W7Im8VjLEEg\"\n\n- id: \"kevin-lesht-railsconf-2022\"\n  title: \"Geolocation EXPLAINed\"\n  raw_title: \"RailsConf 2022 - Geolocation EXPLAINed by Kevin Lesht\"\n  speakers:\n    - Kevin Lesht\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    How do you find the location of someone visiting your site? And, how do you do it fast? If you've ever been curious about how analytics services can place your site visitors on a map, or about how to analyze and improve a slow running query, then this talk is for you!\n\n    In this session, you'll learn about IP address networking, fundamental database operations, and query performance tuning. We'll develop a geolocation system from the ground up, and make sure it's running lightning fast along the way.\n  video_provider: \"youtube\"\n  video_id: \"i1hFVA-dwvU\"\n\n- id: \"maya-toussaint-railsconf-2022\"\n  title: \"Diversity in Engineering; a community perspective\"\n  raw_title: \"RailsConf 2022 - Diversity in Engineering; a community perspective\"\n  speakers:\n    - Maya Toussaint\n    - Caterina Paun\n    - Stephanie Minn\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Diversity in Engineering; a community perspective\n    Maya Toussaint, Caterina Paun & Stephanie Minn\n  video_provider: \"youtube\"\n  video_id: \"d0pE0HNNX4Y\"\n\n- id: \"carrick-rogers-railsconf-2022\"\n  title: \"Bringing Your Rails Monolith Along As The Business Grows\"\n  raw_title: \"RailsConf 2022 - Bringing Your Rails Monolith Along As The Business Grows - Ontra - Carrick Rogers\"\n  speakers:\n    - Carrick Rogers\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    Bringing Your Rails Monolith Along As The Business Grows - Ontra - Carrick Rogers\n  video_provider: \"youtube\"\n  video_id: \"ihkBemw3tPk\"\n\n- id: \"andrew-atkinson-railsconf-2022\"\n  title: \"Puny to Powerful PostgreSQL Rails Apps\"\n  raw_title: \"RailsConf 2022 - Puny to Powerful PostgreSQL Rails Apps by Andrew Atkinson\"\n  speakers:\n    - Andrew Atkinson\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2023-01-16\"\n  description: |-\n    This talk covers 5 challenging areas when scaling Rails applications on PostgreSQL databases. From identifying symptoms to applying solutions and understanding trade-offs, this talk will equip you with practical working knowledge you can apply immediately. This talk covers topics like safe migrations, understanding database connections, query optimization, database maintenance, and database replication and partitioning.\n  video_provider: \"youtube\"\n  video_id: \"QshRTj2f3hE\"\n\n- id: \"live-podcast-panel-railsconf-2022\"\n  title: \"Live Podcast Panel\"\n  raw_title: \"Live(ish) Podcast Panel from Railsconf 2022!\"\n  speakers:\n    - Jemma Issroff\n    - Brittany Martin\n    - Robby Russell\n    - Andrew Culver\n    - Nick Schwaderer\n    - Andrew Mason\n    - Jason Charnes\n    - Chris Oliver\n    - Colleen Schnettler\n  event_name: \"RailsConf 2022\"\n  date: \"2022-05-17\"\n  published_at: \"2022-06-01\"\n  description: |-\n    Railsconf is back in person! We sat down live to record with Jemma Issroff, Brittany Martin, Robby Russell, Andrew Culver, Nicholas Schwaderer, and Colleen Schnettler to discuss everything Ruby on Rails.\n  video_provider: \"youtube\"\n  video_id: \"bX5G3FVHDnw\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/FS_EkquUcAAYDfX?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/FS_EkquUcAAYDfX?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/FS_EkquUcAAYDfX?format=jpg&name=medium\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/FS_EkquUcAAYDfX?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/FS_EkquUcAAYDfX?format=jpg&name=large\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2023/event.yml",
    "content": "---\nid: \"PLbHJudTY1K0cOM1jfOsQLYPTLxQf1Ui1C\"\ntitle: \"RailsConf 2023\"\nkind: \"conference\"\nlocation: \"Atlanta, GA, United States\"\ndescription: |-\n  RailsConf, hosted by Ruby Central, is the world’s largest and longest-running gathering of Ruby on Rails enthusiasts, practitioners, and companies.\npublished_at: \"2023-07-14\"\nstart_date: \"2023-04-24\"\nend_date: \"2023-04-26\"\nyear: 2023\nbanner_background: \"#F5A6C1\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://web.archive.org/web/20230602005937/https://railsconf.org\"\ncoordinates:\n  latitude: 33.7501275\n  longitude: -84.3885209\n"
  },
  {
    "path": "data/railsconf/railsconf-2023/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Shopify\"\n          badge: \"\"\n          website: \"https://www.shopify.com\"\n          slug: \"shopify\"\n          logo_url: \"https://framerusercontent.com/images/gm8gVlKt1h1h0nWWV5YmLIawBxI.png\"\n\n        - name: \"Cisco Meraki\"\n          badge: \"\"\n          website: \"https://meraki.cisco.com/careers/\"\n          slug: \"meraki\"\n          logo_url: \"https://framerusercontent.com/images/XrUfvgOhr6ws5E3GpejwlVfFCA.png\"\n\n    - name: \"Silver\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Crunchy Data\"\n          badge: \"\"\n          website: \"https://www.crunchydata.com\"\n          slug: \"crunchy-data\"\n          logo_url: \"https://framerusercontent.com/images/WopZh3NdEMxRmnYEGh9TrrTLuo.svg\"\n\n        - name: \"Chime\"\n          badge: \"\"\n          website: \"https://www.chime.com\"\n          slug: \"chime\"\n          logo_url: \"https://framerusercontent.com/images/YgFTjg4dqTXIzjVTrPDg0bBqSk.png\"\n\n        - name: \"TrueCar\"\n          badge: \"\"\n          website: \"https://www.truecar.com\"\n          slug: \"truecar\"\n          logo_url: \"https://framerusercontent.com/images/Qeqy4zc8pFyh9FThUKGJMrFBk8c.png\"\n\n        - name: \"JetBrains\"\n          badge: \"\"\n          website: \"https://www.jetbrains.com\"\n          slug: \"jetbrains\"\n          logo_url: \"https://framerusercontent.com/images/TxhCdzoD94shoRM9wEIuQg0s8.png\"\n\n        - name: \"Procore\"\n          badge: \"\"\n          website: \"https://www.procore.com\"\n          slug: \"procore\"\n          logo_url: \"https://framerusercontent.com/images/XO5CFczyX6Z9m5uXKf684Q4vtGs.png\"\n\n    - name: \"Bronze\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"Ontra\"\n          badge: \"\"\n          website: \"https://www.ontra.ai/\"\n          slug: \"ontra\"\n          logo_url: \"https://framerusercontent.com/images/NaRzVKo8vQ3FfKI7wyo2nqik9Hs.png\"\n\n        - name: \"Cedarcode\"\n          badge: \"\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"cedarcode\"\n          logo_url: \"https://framerusercontent.com/images/dc223cm715ASCKTexnniCbF73Pg.png\"\n\n        - name: \"Weedmaps\"\n          badge: \"\"\n          website: \"https://weedmaps.com\"\n          slug: \"weedmaps\"\n          logo_url: \"https://framerusercontent.com/images/UZjJ2rDkZ4GS0bch28ntg3YqPg.png\"\n\n        - name: \"RailsFactory\"\n          badge: \"\"\n          website: \"https://railsfactory.com/\"\n          slug: \"railsfactory\"\n          logo_url: \"https://framerusercontent.com/images/zleTmMZcWYJNKc1yvzGOv15FaxY.png\"\n\n        - name: \"Scout APM\"\n          badge: \"\"\n          website: \"https://scoutapm.com\"\n          slug: \"scout-apm\"\n          logo_url: \"https://framerusercontent.com/images/7qWKEisfPElVagcmVf0LUc59O4c.png\"\n\n        - name: \"Release\"\n          badge: \"\"\n          website: \"https://release.com\"\n          slug: \"release\"\n          logo_url: \"https://framerusercontent.com/images/6djrnB7JoZvheUYtenGwIX8n0.png\"\n\n        - name: \"Retool\"\n          badge: \"\"\n          website: \"https://www.retool.com/\"\n          slug: \"retool\"\n          logo_url: \"https://framerusercontent.com/images/qDViTsbN97i3oZeFpKkuoVaAQFQ.jpg\"\n\n    - name: \"Other\"\n      description: \"\"\n      level: 4\n      sponsors:\n        - name: \"Wyeworks\"\n          badge: \"Conference Bag Sponsor\"\n          website: \"https://www.wyeworks.com/\"\n          slug: \"wyeworks\"\n          logo_url: \"https://framerusercontent.com/images/brW5VXprJs3WI8maifBZyA1Q.svg\"\n\n        - name: \"AppSignal\"\n          badge: \"Relax Lounge Sponsor\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://framerusercontent.com/images/2JKUoKjqYfqfsCvDKzJ3Uj2qmR0.png\"\n\n        - name: \"TestDouble\"\n          badge: \"TestDouble\"\n          website: \"https://link.testdouble.com/railsconf23\"\n          slug: \"testdouble\"\n          logo_url: \"https://framerusercontent.com/images/3qkzoxrHVkNXZ0UyXDJcewc6G4.png\"\n\n        - name: \"Cloud 66\"\n          badge: \"Video Sponsor\"\n          website: \"https://www.cloud66.com/frameworks/rails\"\n          slug: \"cloud-66\"\n          logo_url: \"https://framerusercontent.com/images/uReCJPUiHVq8wS8yuLWJVGT6Rg.svg\"\n\n        - name: \"PostgreSQL\"\n          badge: \"Community Table\"\n          website: \"https://www.postgresql.org\"\n          slug: \"postgresql\"\n          logo_url: \"https://framerusercontent.com/images/FgBXEodZqC5Mw0I1cO7rwLgGE.jpg\"\n\n        - name: \"Honeybadger\"\n          badge: \"Lounge Sponsor\"\n          website: \"https://www.honeybadger.io/\"\n          slug: \"honeybadger\"\n          logo_url: \"https://framerusercontent.com/images/cunLxGusSziGRgSHTmlSLPrDRA.svg\"\n\n        - name: \"Bearer\"\n          badge: \"Community Table\"\n          website: \"https://www.bearer.com/bearer-oss\"\n          slug: \"bearer\"\n          logo_url: \"https://framerusercontent.com/images/1CsfT7aGcMvrYGtMFzg2nRtdfI.png\"\n\n        - name: \"Infield\"\n          badge: \"Community Table\"\n          website: \"https://www.infield.ai\"\n          slug: \"infield\"\n          logo_url: \"https://framerusercontent.com/images/GsmqxA7Gi9zly8WfMyEYBmBbppQ.png?scale-down-to=1024\"\n\n        - name: \"thoughtbot\"\n          badge: \"Supporter\"\n          website: \"https://thoughtbot.com/\"\n          slug: \"thoughtbot\"\n          logo_url: \"https://framerusercontent.com/images/tPpWdy654nDjGqsIxKNZ6oyv0.svg\"\n\n        - name: \"FastRuby.io\"\n          badge: \"Supporter\"\n          website: \"https://www.fastruby.io/\"\n          slug: \"fastruby-io\"\n          logo_url: \"https://framerusercontent.com/images/EUYzZFcouHnhLmtAlzc5zGr9MH0.png\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"john-crepezzi-railsconf-2023\"\n  title: \"Functional Patterns in Ruby\"\n  raw_title: \"RailsConf 2023 - Functional Patterns in Ruby by John Crepezzi\"\n  speakers:\n    - John Crepezzi\n  description: |-\n    I recently started working primarily in a statically-typed functional programming language (OCaml). While learning, I spent a lot of time trying to fit OCaml into a Ruby-shaped box. While there are plenty of things that I miss about Ruby day-to-day, there are also a lot of good lessons to take away! No, I’m not talking about static typing, or some rant on how nil is an anti-pattern. This talk instead will dig into concepts from around the functional world and how they can be modeled in Ruby for cleaner, more future-proof code.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"3ndcqh9fTGA\"\n\n- id: \"drew-bragg-railsconf-2023\"\n  title: \"Who Wants to be a Ruby Engineer?\"\n  raw_title: \"RailsConf 2023 - Who Wants to be a Ruby Engineer? by Drew Bragg\"\n  speakers:\n    - Drew Bragg\n  description: |-\n    Welcome to the Ruby game show where contestants try to guess the output of a small bit of Ruby code. Sound easy? Here's the challenge: the snippets come from some of the weirdest parts of the Ruby language.  The questions aren't easy, but et enough right to be crowned a \"Strange\" Ruby Engineer and win a fabulous prize.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"4VT0aDEDd28\"\n\n- id: \"alicia-rojas-railsconf-2023\"\n  title: \"Building an offline experience with a Rails-powered PWA\"\n  raw_title: \"RailsConf 2023 - Building an offline experience with a Rails-powered PWA by Alicia Rojas\"\n  speakers:\n    - Alicia Rojas\n  description: |-\n    Progressive web applications (PWAs) allow us to provide rich offline experiences as native apps would, while still being easy to use and share, as web apps are. Come to learn how to turn your regular Rails application into a PWA, taking advantage of the new front-end tools that come with Rails by default since version 7. Entry-level developers are welcome!\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"4cQuxQdWkPE\"\n\n- id: \"joel-hawksley-railsconf-2023\"\n  title: \"Accessible by default\"\n  raw_title: \"RailsConf 2023 - Accessible by default by Joel Hawksley\"\n  speakers:\n    - Joel Hawksley\n  description: |-\n    It's one thing to build a new application that meets the latest accessibility standards, but it's another thing to update an existing application to meet them. In this talk, we'll share how we're using automated accessibility scanning, preview-driven development, and an accessibility-first form builder to make GitHub's 15-year-old, 1,400-controller Ruby on Rails monolith accessible.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"4j2zlvE_Yj8\"\n\n- id: \"matthew-langlois-railsconf-2023\"\n  title: \"ActiveRecord::Encryption; Stop Hackers from Reading your Data\"\n  raw_title: \"RailsConf 2023 - ActiveRecord::Encryption; Stop Hackers from... by Matthew Langlois, Kylie Stradley\"\n  speakers:\n    - Matthew Langlois\n    - Kylie Stradley\n  description: |-\n    ActiveRecord::Encryption; Stop Hackers from Reading your Data by Matthew Langlois, Kylie Stradley\n\n    Have you ever wondered how to encrypt data in your Rails application but weren’t sure where to get started? We’ll briefly talk about why you would want to encrypt data, and then discuss how you can get started with encrypting columns in your Rails application including pitfalls and successes we encountered while implementing ActiveRecord::Encryption at GitHub. Attendees will be confident in making a decision to implement ActiveRecord::Encryption in their application.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"4mZNP_Dgi2w\"\n\n- id: \"guillermo-aguirre-railsconf-2023\"\n  title: \"Applying microservices patterns to a modular monolith\"\n  raw_title: \"RailsConf 2023 - Applying microservices patterns to a modular monolith by Guillermo Aguirre\"\n  speakers:\n    - Guillermo Aguirre\n  description: |-\n    Dealing with legacy monoliths can be challenging due to accumulated technical debt. When faced with this situation, we usually start looking at different strategies to solve this, like microservices, engines, and modularization, just to name a few.\n\n    When choosing to follow a modular approach, I explored applying microservices patterns to our modular monolith. In this talk, I’ll share my experience in adopting this approach, focusing on ensuring data consistency and distributed transactions, as well as the pitfalls and insights I discovered along the way.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"4zrQAJ0RlI4\"\n\n- id: \"kevin-gorham-railsconf-2023\"\n  title: \"Bridging the Gap: Creating Trust Between Non-Technical Stakeholders and Engineering Teams\"\n  raw_title: \"RailsConf 2023 - Bridging the Gap: Creating Trust Between Non-Technical... by Kevin Gorham\"\n  speakers:\n    - Kevin Gorham\n  description: |-\n    Bridging the Gap: Creating Trust Between Non-Technical Stakeholders and Engineering Teams by Kevin Gorham\n\n    In this talk, we'll explore how to build trust between non-technical stakeholders and engineering teams, using data and analysis to effectively communicate progress. We'll discuss practical tactics for leveraging the Pivotal Tracker API and Google Apps Scripts to extract relevant metrics, analyze data, and provide insightful analysis, as well as how to communicate that information. Join us to learn how to build trust, and how it can improve project success and create better outcomes for all parties involved.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"5gSRKyuO7qY\"\n\n- id: \"landon-gray-railsconf-2023\"\n  title: \"Forecasting the Future: An Introduction to Machine Learning for Weather Prediction\"\n  raw_title: \"RailsConf 2023 - Forecasting the Future: An Introduction to Machine Learning for... by Landon Gray\"\n  speakers:\n    - Landon Gray\n  description: |-\n    Forecasting the Future: An Introduction to Machine Learning for Weather Prediction in Native Ruby by Landon Gray\n\n    Have you ever considered building a machine learning model in Ruby? It may surprise you to learn that you can train, build, and deploy ML models in Ruby. But what are the benefits of using Ruby over other languages?\n\n    One of the biggest advantages of using Ruby for machine learning is accessibility. You're no longer limited to specific languages or tools when exploring AI and ML concepts. It's time for Rubyists to dive into the world of machine learning! -\n\n    In this talk, we'll build a model that predicts the weather and explore the tools and libraries available for your own native Ruby Machine Learning projects.\n\n    Whether you're a seasoned Rubyist or just starting out, don't miss this opportunity to discover the possibilities of machine learning in Ruby.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"656z7Hu0HtY\"\n\n- id: \"daniel-huss-railsconf-2023\"\n  title: \"The End of Legacy Code\"\n  raw_title: \"RailsConf 2023 -  The End of Legacy Code by Daniel Huss\"\n  speakers:\n    - Daniel Huss\n  description: |-\n    Legacy code. Did you just shiver with dread?\n\n    We know it when we see it, but we don't know how it got there, or why it looks like... this.\n\n    What if we could change our relationship with legacy code, and shed the weight the name brings with it? What if legacy code disappeared?\n\n    Throw away everything you've ever learned, embrace the mindset of Eternal Onboarding, and watch as our problems with \"Legacy Code\" melt away.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"6msn5oGT7Q8\"\n\n- id: \"colin-fleming-railsconf-2023\"\n  title: \"Demystifying the Unionizing Process\"\n  raw_title: \"RailsConf 2023 - Demystifying the Unionizing Process by Colin Fleming\"\n  speakers:\n    - Colin Fleming\n  description: |-\n    Unionization has come up among workers at both the largest and smallest companies in the USA, especially post-pandemic. In this talk, we'll talk about why workplaces decide to unionize or not, learn more about the actual process, and think about what this means for software developers in particular.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"8qSmTXFG2Pc\"\n\n- id: \"hartley-mcguire-railsconf-2023\"\n  title: \"How to Upstream Your Code to Rails\"\n  raw_title: \"RailsConf 2023 - How to Upstream Your Code to Rails by Hartley McGuire\"\n  speakers:\n    - Hartley McGuire\n  description: |-\n    Contributing to Rails for the first time can be intimidating! What makes a good contribution? What does the review process look like? Why should I even bother in the first place? In this talk, we will answer all of these questions and more as we learn about contributing to the Rails framework. We will follow along with a real story of upstreaming a new feature, and learning about the hurdles encountered along the way, both expected and unexpected.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"Ai64DuHt4CU\"\n\n- id: \"justin-daniel-railsconf-2023\"\n  title: \"A custom design pattern for building dynamic ActiveRecord queries\"\n  raw_title: \"RailsConf 2023 - A custom design pattern for building dynamic ActiveRecord queries by Justin Daniel\"\n  speakers:\n    - Justin Daniel\n  description: |-\n    The pain is familiar to long-time developers of enterprise Rails applications. Database queries through ActiveRecord are an essential part of our application. And making these queries performant, dynamic, and readable is hard.\n\n    We can solve the above problems. With the right abstractions we can write code that composes queries that are performant, dynamic, and readable. Our approach uses a domain specific language built on top of ActiveRecord that you can adapt to your own application. We do not need a whole new library or framework. We just need query objects and builders.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"CWqISNM1RfY\"\n\n- id: \"rich-steinmetz-railsconf-2023\"\n  title: \"A Picture Is Worth a 1000 Lines of Code\"\n  raw_title: \"RailsConf 2023 - A Picture Is Worth a 1000 Lines of Code by Rich Steinmetz\"\n  speakers:\n    - Rich Steinmetz\n  description: |-\n    Let me show you how I turned my \"two left hands\" into eight superpower tentacles, going from \"I can't draw\" to visualizing more and less abstract concepts all over the internet.\n\n    A simple visual framework can let you do the same rather quickly because this is what your brain is wired to do: process and generate images.\n\n    The coding education industry and workplace communication mainly consist of simplified code examples, boring text walls, and sometimes never-ending speeches from the loudest people in meetings.\n\n    All it takes to make abstract concepts visible is identifying your visual thinking type and empowering yourself with a reproducible process to make your communication more understandable, memorable, unique, collaborative, and fun.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"ChsqAlhnjsI\"\n\n- id: \"noel-rappin-railsconf-2023\"\n  title: \"Rails on Ruby: How Ruby Makes Rails Great\"\n  raw_title: \"RailsConf 2023 - Rails on Ruby: How Ruby Makes Rails Great by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  description: |-\n    Ruby puts the Ruby in “Ruby on Rails”! It’s the Ruby language that makes Rails flexible, powerful, and with a developer-friendly API. How does Rails take advantage of Ruby’s flexibility and metaprogramming to make it so useful? And how can you take advantage of those features in your Rails app? We’ll go over a few specific Ruby features, like how Rails uses Modules, or `define_method` or `instance_eval`. You’ll be able to use these features to make your app as powerful as Rails itself.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"EBFWAGkIFZM\"\n\n- id: \"aaron-patterson-railsconf-2023\"\n  title: \"Closing Keynote: Modern Dev Environments\"\n  raw_title: \"RailsConf 2023 - Keynote: Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  description: |-\n    Keynote: Aaron Patterson\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  slides_url: \"https://speakerdeck.com/tenderlove/railsconf-2023\"\n  video_provider: \"youtube\"\n  video_id: \"LcDNedD-8mU\"\n\n- id: \"jordan-trevino-railsconf-2023\"\n  title: \"How Rails fosters a diverse and competitive tech ecosystem in the era of big tech\"\n  raw_title: \"RailsConf 2023 - How Rails fosters a diverse and competitive tech ecosystem in... by Jordan Trevino\"\n  speakers:\n    - Jordan Trevino\n  description: |-\n    How Rails fosters a diverse and competitive tech ecosystem in the era of big tech by Jordan Trevino\n\n    Join us for a discussion on how Rails technology patterns and practices help foster a more diverse and competitive tech ecosystem amidst the proliferation of patterns popularized by big tech. We develop an economic and organizational critique of such approaches as microservices and single-page apps.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"Lo1rn0XCSDw\"\n\n- id: \"ebun-segun-railsconf-2023\"\n  title: \"An imposter's guide to growth in engineering\"\n  raw_title: \"RailsConf 2023 - An imposter's guide to growth in engineering by Ebun Segun\"\n  speakers:\n    - Ebun Segun\n  description: |-\n    This session will explore the imposter syndrome that hits mid to upper level engineers when thrust into a new project, show how this can be useful for moving to the growth zone, and walk through practical steps to apply when facing imposter syndrome.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"MH8j1_uthhk\"\n\n- id: \"rishi-jain-railsconf-2023\"\n  title: \"Rails Performance Monitoring 101: A Primer for Junior Developers\"\n  raw_title: \"RailsConf 2023 - Rails Performance Monitoring 101: A Primer for Junior Developers by Rishi Jain\"\n  speakers:\n    - Rishi Jain\n  description: |-\n    Congratulations! You are fresh off your Rails boot camp and you just got hired by a startup that just went viral. Your first task is to figure out why their Rails application is slow. Now what?\n\n    This talk will give you the tools you need to quickly find what's wrong in your application. You will learn a top-down approach for triaging performance issues and scaling your hot Rails app.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"OF5YhG-91ao\"\n\n- id: \"shayon-mukherjee-railsconf-2023\"\n  title: \"Beyond CRUD: the PostgreSQL techniques your Rails app is missing.  Shayon Mukherjee\"\n  raw_title: \"RailsConf 2023 - Beyond CRUD: the PostgreSQL techniques your Rails app is missing.  Shayon Mukherjee\"\n  speakers:\n    - Shayon Mukherjee\n  description: |-\n    Being part of gnarly production outages isn’t uncommon. In this talk, I will share short entertaining stories about a few head scratching production outages we faced and how we used efficient and simple PostgreSQL features in Rails to build scalable solutions.\n\n    I will also discuss how and when to use certain PostgreSQL concepts in Rails, such as optimistic and pessimistic locking, using real-life examples that power core customer features.\n\n    Finally, I will discuss uses of Postgres mutex to manage concurrent access to shared resources and wrap up by sharing our own experiences and lessons from other production outages. This will help you avoid common operational pitfalls and improve your application's reliability and query patterns.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"OQUTBLhP2QI\"\n\n- id: \"juan-pablo-balarini-railsconf-2023\"\n  title: \"Faster websites: integrating next-gen images in your Rails apps\"\n  raw_title: \"RailsConf 2023 - Faster websites: integrating next-gen images in your... by JP Balarini\"\n  speakers:\n    - Juan Pablo Balarini\n  description: |-\n    Faster and cheaper websites: integrating next-gen images in your Rails apps by JP Balarini\n\n    Did you know loading images accounts for nearly 50% of your website’s total load time? Also, every additional second of load time results in a 5% decrease in conversion rates, which directly impacts your business. What if I told you there’s a simple way to decrease loading time?\n\n    This talk will explore the latest and most effective options for web images that significantly reduce website size without compromising quality. We’ll discuss how using next-gen images can significantly impact website loading times, user conversion, and SEO.\n\n    We’ll also go through the different challenges that I faced while integrating next-gen images into a Rails project and how I solved them. A new gem will be presented that streamlines the process of using WebP images with Ruby on Rails.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"Pdnpen6jPDM\"\n\n- id: \"christopher-aji-slater-railsconf-2023\"\n  title: \"Hotwiring My React Brain\"\n  raw_title: \"RailsConf 2023 - Hotwiring My React Brain by Aji Slater\"\n  speakers:\n    - Christopher \"Aji\" Slater\n  description: |-\n    Hi. Have you been writing Rails API-mode json backends for React front ends for the last few years? Me too.\n\n    Have you been daydreaming about the days when you could just write a view template and render some html server-side? Me too.\n\n    Have you been wondering if it's possible to have rich, snappy UIs with only Rails, and very little js? Me too.\n\n    Are you now working on a fully Hotwire and Turbo app, having to re-learn everything you've grown comfortable with in front-end development? Me.. huh? no?\n\n    Well come along and I'll show you how I re-implemented my conception of the client side with Rails' Hotwire view layer.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"PvAf3vZp1b8\"\n\n- id: \"justin-searls-railsconf-2023\"\n  title: \"Let's Standardize Rails, Once and For All!\"\n  raw_title: \"RailsConf 2023 - Let's Standardize Rails, Once and For All! by Justin Searls, Meagan Waller\"\n  speakers:\n    - Justin Searls\n    - Meagan Waller\n  description: |-\n    Four years ago, I arbitrarily configured every RuboCop rule and published it as a gem called \"standard\". 135 releases later, feedback from the community has gradually transformed Standard into a linter & formatter ruleset that most Rubyists can get behind. Today, Standard is delivering on its promise: helping teams stay focused on their work instead of arguing over syntax.\n\n    The time has come to once again configure the unconfigurable by creating a standard-rails based on rubocop-rails. But this time, we'll skip the years of debating rules on GitHub. Instead, we're holding a community straw poll at RailsConf!\n\n    Join us for a town hall-style event where we'll review what each rubocop-rails rule does, hear its pros and cons, and put it to a vote. We'll enshrine the consensus picks in the first public release of standard-rails. By showing up, you'll not only be establishing conventions to promote safe and consistent code, you'll be sharpening the focus of Rails developers around the world!\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"QVilOzkLdlI\"\n\n- id: \"shane-becker-railsconf-2023\"\n  title: \"Building a world class engineering organization — learning from cave paintings and horsey land art\"\n  raw_title: \"RailsConf 2023 - Building a world class engineering organization — learning from... by Shane Becker\"\n  speakers:\n    - Shane Becker\n  description: |-\n    Building a world class engineering organization — learning from cave paintings and horsey land art by Shane Becker\n\n    Human built things survive for a Very Long Time™ by one of two ways: materials or maintenance.\n\n    What we can learn from Stonehenge, Lascaux cave paintings, Brewarrina Aboriginal Fish Traps, the White Horse of Uffington, Iranian windmills, and Japanese Shinto shrines?\n\n    If we knew for certain that our Rails apps would be in use in ten years (or a hundred!), what would future us wish that we would've done now to build a better future?\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"R7JqiVPuKD8\"\n\n- id: \"jordan-burke-railsconf-2023\"\n  title: \"Terms of Deployment: The Process of Evaluating Hatchbox, Fly and Render for Developers\"\n  raw_title: \"RailsConf 2023 - Terms of Deployment: The Process of Evaluating Hatchbox, Fly and... by Jordan Burke\"\n  speakers:\n    - Jordan Burke\n  description: |-\n    Terms of Deployment: The Process of Evaluating Hatchbox, Fly, and Render for Developers by Jordan Burke\n\n    Heroku has long been the mainstay deployment platform for Rails developers and agencies, but with several new options for hosting out there, is it still the best solution? We take a quick look  at how we evaluated switching some of our clients’ applications to Hatchbox.io, Render, and fly.io. how we made those decisions, and how we will make those determinations in the future.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"RHv7hJGOUr0\"\n\n- id: \"allison-hill-railsconf-2023\"\n  title: \"Deep End Diving: Getting Up to Speed on New Codebases\"\n  raw_title: \"RailsConf 2023 - Deep End Diving: Getting Up to Speed on New Codebases by Allison Hill\"\n  speakers:\n    - Allison Hill\n  description: |-\n    One of the beautiful things about software engineering is that we’re always learning. At all career stages, there are always new gems, open source tools, and company-specific tech stacks to get up to speed on. It can be overwhelming sometimes! The good news is that there are concrete strategies you can use to make plunging into a new project an exciting rush (rather than a panic-inducing nightmare). With a little bit of focus put into the right areas, you can help every new team member- from the most junior dev to top dog seniors- jump in and contribute faster.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"RxgHgzByNPs\"\n\n- id: \"kevin-liebholz-railsconf-2023\"\n  title: \"Exploring the Power of Turbo Streams and ActionCable\"\n  raw_title: \"RailsConf 2023 - Exploring the Power of Turbo Streams and ActionCable by Kevin Liebholz\"\n  speakers:\n    - Kevin Liebholz\n  description: |-\n    Dive into the world of Turbo Streams and ActionCable with the Dragon Rider Eragon and his majestic dragon, Saphira, as we build a real-time tic-tac-toe game. We will utilize Turbo Stream broadcasting and ActionCable customization to create the game for our heroes, adding constraints of rising difficulty one after the other. Are you an advanced coder? Or are you a beginner? As long as you are looking to explore new applications of Hotwire’s Turbo or simply learn about it, we’re a match!\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"S--B3BGIk3M\"\n  slides_url: \"https://speakerdeck.com/kevinliebholz/exploring-the-power-of-turbo-streams-and-action-cable\"\n\n- id: \"john-sawers-railsconf-2023\"\n  title: \"Hacking Your Emotional API\"\n  raw_title: \"RailsConf 2023 - Hacking Your Emotional API by John Sawers\"\n  speakers:\n    - John Sawers\n  description: |-\n    Feelings are messy and uncomfortable, so why can't we just ignore them? Because emotional skills are critical for working well on a team, and for the quality of our work.\n\n    In this talk you’ll learn how emotions are affecting you by modeling them as an API and looking at the code.\n\n    I cover how poor handling of emotions impacts cognition, memory, and communication.\n\n    Then I dive into my toolkit for handling emotions, full of practical advice and new ways of thinking.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"UftGecVyvSk\"\n\n- id: \"andy-andrea-railsconf-2023\"\n  title: \"Building a more effective, bidirectional mentor-mentee relationship\"\n  raw_title: \"RailsConf 2023 - Building a more effective, bidirectional mentor-... by Andy Andrea, William Frey\"\n  speakers:\n    - Andy Andrea\n    - William Frey\n  description: |-\n    Building a more effective, bidirectional mentor-mentee relationship by Andy Andrea, William Frey\n\n    Mentorship is such a key part of our industry that most of us will act as both mentor and mentee many times over the course of our careers. However, unlike our other important skills that get honed through processes like code review or retrospectives, there are often few mechanisms to help us grow as mentors and mentees.\n\n    We’ll cover common problems that occur as both a mentee and mentor and cover strategies, skills and concepts for how to deal with them that originate not only from our own experiences but from research in the fields of education, psychology and business. We’ll cover concepts that won’t only build your skills but improve the value you get from being a mentor or mentee and show you how to make an evidence-backed business case for expanding mentorship at your place of work.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"Uv2I3ECnzuY\"\n\n- id: \"michael-milewski-railsconf-2023\"\n  title: \"10x your teamwork through pair programming\"\n  raw_title: \"RailsConf 2023 - 10x your teamwork through pair programming by Michael Milewski, Selena Small\"\n  speakers:\n    - Michael Milewski\n    - Selena Small\n  description: |-\n    A roller coaster journey of how to get the most out of pair programming. Live on stage acting out highs, lows, do’s and don’ts of pair programming. Laughs and tears are guaranteed as the audience connect on the difficulties and ultimately the rewards that can be reaped through effective pairing.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"W8y0odUwks8\"\n\n- id: \"rafael-mendona-frana-railsconf-2023\"\n  title: \"Keynote: Investing in the Ruby community\"\n  raw_title: \"RailsConf 2023 -  Keynote: Investing in the Ruby community by Rafael Mendonça França\"\n  speakers:\n    - Rafael Mendonça França\n  description: |-\n    This is a tale of how a developer's passion for Ruby lead them to assist companies make investments in the Ruby community. Come and watch a captivating love story featuring gems, train tracks and ice cream.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"XohX3nlVIdc\"\n\n- id: \"austin-story-railsconf-2023\"\n  title: \"Using Rails Engines to Supercharge Your Team\"\n  raw_title: \"RailsConf 2023 - Using Rails Engines to Supercharge Your Team by Austin Story\"\n  speakers:\n    - Austin Story\n  description: |-\n    Rails engines are self-contained modules that can be used inside of a larger Ruby on Rails application to encapsulate complex functionality and expose it with a tight, well defined API.\n\n    When implemented properly on the right domains, they can give your team a major speed boost.\n\n    In this talk we will break down how Doximity used a Rails engine as a key ingredient to successfully rollout GraphQL Federation to our organizations.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"ZE9dKoBIr48\"\n\n- id: \"braulio-martinez-railsconf-2023\"\n  title: \"Go Passwordless with WebAuthn in Ruby\"\n  raw_title: \"RailsConf 2023 - Go Passwordless with WebAuthn in Ruby by Braulio Martinez\"\n  speakers:\n    - Braulio Martinez\n  description: |-\n    Nowadays, passwords are still our most common authentication method. However, they are not secure enough and have terrible UX.\n\n    Therefore, big industry players in the FIDO Alliance like Google, Mozilla, Apple, Amazon (among others) collaborated together to find a solution. WebAuthn was born and eventually became a W3C standard enabling users to authenticate on the web using public-key cryptography together with biometrics.\n\n    This talk will allow you to learn what WebAuthn is and how it works. You’ll also see how any Ruby app can easily get the level of authentication security and UX users deserve.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"ZsGphXQ9kfw\"\n\n- id: \"elle-meredith-railsconf-2023\"\n  title: \"Strategies for saying no\"\n  raw_title: \"RailsConf 2023 - Strategies for saying no by Elle Meredith\"\n  speakers:\n    - Elle Meredith\n  description: |-\n    You have been working hard to meet a deadline and then you receive an email from your boss, asking you to take on a new project. You're at capacity with your time, resources, and focus, but you still feel obliged to say \"yes\". This scenario is common for most of us. We don't want to say \"no\" because we don't want to disappoint people or let them down. This is even a bigger problem when you start leading people. Saying no enables you to focus on what's important and prevent burnout. In this talk, you will take away tools and strategies to become more confident around saying no.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"_2zWwwjnuUA\"\n\n- id: \"maple-ong-railsconf-2023\"\n  title: \"Building Ruby Head for your Rails App\"\n  raw_title: \"RailsConf 2023 - Building Ruby Head for your Rails App by Maple Ong\"\n  speakers:\n    - Maple Ong\n  description: |-\n    Tired of upgrading to the latest Ruby version every new year? Just have the latest Ruby version already running! Ruby head is the latest commit to the main branch of Ruby on Github. It’s dangerous to run our Rails app on Ruby head, but we can run Ruby head on application tests.\n\n    We'll build Ruby head on a Docker image and run it with tests on Buildkite. Along the way, we'll learn about using Docker, jemalloc (an an alternate malloc implementation) and why it's important to your team and the Ruby community to do this work.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"bLTqSh3Jon0\"\n\n- id: \"ole-michaelis-railsconf-2023\"\n  title: \"Breaking the Grind: Crafting Your Ideal Software Engineering Career Build\"\n  raw_title: \"RailsConf 2023 - Breaking the Grind: Crafting Your Ideal Software Engineering... by Ole Michaelis\"\n  speakers:\n    - Ole Michaelis\n  description: |-\n    Breaking the Grind: Crafting Your Ideal Software Engineering Career Build by Ole Michaelis\n\n    Explore the world of software engineering skills through the lens of role-playing games to find the most effective builds for advancing your career. This talk metaphorically approaches (MMO)RPG skill trees by looking at different career paths in software engineering, unlocking new skills, and leveling up existing ones to branch out into new areas of expertise. We'll examine a variety of paths — including programming paradigms, software delivery, organizational development, and team management. LFG for adventure, and uncover the vast possibilities of building a career as a software engineer!\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"bhagIbz3T0A\"\n\n- id: \"vincent-rolea-railsconf-2023\"\n  title: \"A pragmatic and simple approach to fixing a memory leak\"\n  raw_title: \"RailsConf 2023 - A pragmatic and simple approach to fixing a memory leak by Vincent Rolea\"\n  speakers:\n    - Vincent Rolea\n  description: |-\n    Memory leaks do not come by often in modern Rails applications. But when they do, the road to a fix can be tortuous: it often requires extensive knowledge of memory management in Ruby, experience on profiling tools as well as properly setup application monitoring.\n\n    As a developer working on Product, one does not always have the bandwidth to learn about the subject, and setup custom tools: project deadlines could be nearing, or your expertise needed on a shiny new project that just came in.  In this talk, I’ll walk you through a real memory leak issue we encountered on one of our background worker, and how we fixed it with no custom tooling using simple technics.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"bvdWPGQ8cEA\"\n\n- id: \"shana-moore-railsconf-2023\"\n  title: \"Don’t be afraid of the scary red error messages; they’re actually our friends\"\n  raw_title: \"RailsConf 2023 - Don’t be afraid of the scary red error messages;... by Shana Moore, Kait Sewell\"\n  speakers:\n    - Shana Moore\n    - Kait Sewell\n  description: |-\n    Don’t be afraid of the scary red error messages; they’re actually our friends. by Shana Moore, Kait Sewell\n\n    How to use failures, errors and tests to enhance understanding and deliver quality code to clients.  By not restricting ourselves to always perform perfectly we give ourselves the ability to discover new solutions.  In this beginner-friendly talk we’ll walk through our missteps with light hearted reflection and share how to make a habit of growing from failure. Additionally, we hope to help the audience walk away with an actionable framework for handling the errors they'll encounter along the way.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"eS7OMjZaGoQ\"\n\n- id: \"vladimir-dementyev-railsconf-2023\"\n  title: \"Rails as a piece of birthday cake\"\n  raw_title: \"RailsConf 2023 - Rails as a piece of birthday cake by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  description: |-\n    Ruby on Rails as a framework follows the Model-View-Controller design pattern. Three core elements, like the number of layers in a traditional birthday cake, are enough to “cook” web applications. However, on the long haul, the Rails cake often resembles a crumble cake with the layers smeared and crumb-bugs all around the kitchen-codebase.\n    \\\n    Similarly to birthday cakes, adding new layers is easier to do and maintain as the application grows than increasing the existing layers in size.\n    \\\n    How to extract from or add new layers to a Rails application? What considerations should be taken into account? Why is rainbow cake the king of layered cakes? Join my talk to learn about the layering Rails approach to keep applications healthy and maintainable.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"fANjY7Hn_ig\"\n\n- id: \"shani-boston-railsconf-2023\"\n  title: \"Keynote: Leading through Change - When two cultures combine\"\n  raw_title: \"RailsConf 2023 - Keynote: Leading through Change - When two cultures combine by Shani Boston\"\n  speakers:\n    - Shani Boston\n  description: |-\n    Keynote: Leading through Change - When two cultures combine by Shani Boston\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"hYFdPM3dUbk\"\n\n- id: \"kyle-doliveira-railsconf-2023\"\n  title: \"Off to the races\"\n  raw_title: \"RailsConf 2023 - Off to the races by Kyle d'Oliveira\"\n  speakers:\n    - Kyle d'Oliveira\n  description: |-\n    Race conditions are a natural hazard whenever working with shared resources. If you have multiple processes such as using a database, or a microservice architecture, there are likely some race conditions that are hiding in your code. As usage scales up, they will become more and more common. They are difficult to detect, challenging to reproduce and test, and sometimes downright hard to prove that it is fixed. In this talk, we will dive into what a race condition is, how it can show up in Rails applications, and some strategies on how to test them to give confidence that they are fixed.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"jEDX3yswrcM\"\n\n- id: \"lightning-talks-railsconf-2023\"\n  title: \"Lightning Talks\"\n  raw_title: \"RailsConf 2023 - Lightning Talks\"\n  date: \"2023-04-26\"\n  event_name: \"RailsConf 2023\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"k55B4ydueGE\"\n  description: |-\n    A lightning talk is a short presentation (up to 5 mins) on your chosen topic.\n  talks:\n    - title: \"Lightning Talk: Let's Do Some Research in < 5 mins (That's some lightning fast science): An Intro to the Zooniverse\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"01:21\"\n      end_cue: \"05:29\"\n      thumbnail_cue: \"01:26\"\n      id: \"michelle-yuen-lighting-talk-railsconf-2023\"\n      video_id: \"michelle-yuen-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Michelle Yuen\n\n    - title: \"Lightning Talk: Katya Sarmiento\" # No talk title\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"05:29\"\n      end_cue: \"10:41\"\n      thumbnail_cue: \"08:45\"\n      id: \"katya-sarmiento-lighting-talk-railsconf-2023\"\n      video_id: \"katya-sarmiento-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Katya Sarmiento\n\n    - title: \"Lightning Talk: Tim Carey\" # No official title. Topic: \"How I Supercharged My Career With My Prior Experience Being An Auto Mechanic\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"10:41\"\n      end_cue: \"14:09\"\n      thumbnail_cue: \"10:46\"\n      id: \"tim-carey-lighting-talk-railsconf-2023\"\n      video_id: \"tim-carey-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Tim Carey\n\n    - title: \"Lightning Talk: Traversing the depths of Gem source code\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"14:09\"\n      end_cue: \"18:39\"\n      thumbnail_cue: \"14:20\"\n      id: \"dominic-lizarraga-lighting-talk-railsconf-2023\"\n      video_id: \"dominic-lizarraga-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Dominic Lizarraga\n\n    - title: \"Lightning Talk: Kaylah Rose Mitchell\" # No official title. Topic: Data Minimization & Data Privacy\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"18:39\"\n      end_cue: \"21:14\"\n      thumbnail_cue: \"18:44\"\n      id: \"kaylah-rose-mitchell-lighting-talk-railsconf-2023\"\n      video_id: \"kaylah-rose-mitchell-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Kaylah Rose Mitchell\n\n    - title: \"Lightning Talk: Secure Passwords\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"21:14\"\n      end_cue: \"24:45\"\n      thumbnail_cue: \"21:19\"\n      id: \"angela-choi-lighting-talk-railsconf-2023\"\n      video_id: \"angela-choi-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Angela Choi\n\n    - title: \"Lightning Talk: Cellist to GitHub Software Developer\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"24:45\"\n      end_cue: \"29:10\"\n      thumbnail_cue: \"24:49\"\n      id: \"greta-parks-lighting-talk-railsconf-2023\"\n      video_id: \"greta-parks-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Greta Parks\n\n    - title: \"Lightning Talk: Rock Davenport\" # No official title. Topic: Resilience\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"29:10\"\n      end_cue: \"33:07\"\n      thumbnail_cue: \"29:15\"\n      id: \"rock-davenport-lighting-talk-railsconf-2023\"\n      video_id: \"rock-davenport-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Rock Davenport\n\n    - title: \"Lightning Talk: 5-Minute Survival Guide... for Parents with Wanderlust\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"33:07\"\n      end_cue: \"38:19\"\n      thumbnail_cue: \"33:12\"\n      id: \"mia-szinek-lighting-talk-railsconf-2023\"\n      video_id: \"mia-szinek-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Mia Szinek\n        - Peter Szinek\n\n    - title: \"Lightning Talk: Qiwei Lin\" # No official title. Topic: \"How To Solve A Rubik's Cube\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"38:19\"\n      end_cue: \"43:24\"\n      thumbnail_cue: \"38:57\"\n      id: \"kiwi-lighting-talk-railsconf-2023\"\n      video_id: \"kiwi-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Qiwei Lin\n\n    - title: \"Lightning Talk: Jack Permenter\" # No official title. Topic: Historical Determinism\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"43:24\"\n      end_cue: \"48:27\"\n      thumbnail_cue: \"43:29\"\n      id: \"jack-permenter-lighting-talk-railsconf-2023\"\n      video_id: \"jack-permenter-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Jack Permenter\n\n    - title: \"Lightning Talk: Main Quests & Side Quests\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"48:27\"\n      end_cue: \"53:27\"\n      thumbnail_cue: \"48:32\"\n      id: \"rachael-wright-munn-lighting-talk-railsconf-2023\"\n      video_id: \"rachael-wright-munn-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Rachael Wright-Munn\n\n    - title: \"Lightning Talk: Jonan Scheffler\" # No official title. Topic: Decentralization\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"53:27\"\n      end_cue: \"57:42\"\n      thumbnail_cue: \"53:28\"\n      id: \"jonan-scheffler-lighting-talk-railsconf-2023\"\n      video_id: \"jonan-scheffler-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Jonan Scheffler\n\n    - title: \"Lightning Talk: Many to Many: Love your Join Tables\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"57:42\"\n      end_cue: \"1:02:43\"\n      thumbnail_cue: \"57:47\"\n      id: \"naofumi-kagami-lighting-talk-railsconf-2023\"\n      video_id: \"naofumi-kagami-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Naofumi Kagami\n\n    - title: \"Lightning Talk: What is OpenTelemetry (and why should you implement traces in your Rails app)?\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:02:43\"\n      end_cue: \"1:07:45\"\n      thumbnail_cue: \"1:02:48\"\n      id: \"samantha-holstine-lighting-talk-railsconf-2023\"\n      video_id: \"samantha-holstine-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Samantha Holstine\n\n    - title: \"Lightning Talk: Financial app on Rails: For fun and nonprofit!\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:07:45\"\n      end_cue: \"1:12:53\"\n      thumbnail_cue: \"1:07:49\"\n      id: \"max-wofford-lighting-talk-railsconf-2023\"\n      video_id: \"max-wofford-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Max Wofford\n\n    - title: \"Lightning Talk: A Crash Course in Crashing Ruby\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:12:53\"\n      end_cue: \"1:16:16\"\n      thumbnail_cue: \"1:12:58\"\n      id: \"gary-tou-lighting-talk-railsconf-2023\"\n      video_id: \"gary-tou-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Gary Tou\n\n    - title: \"Lightning Talk: Caleb Denio\" # No official title.\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:16:16\"\n      end_cue: \"1:19:32\"\n      thumbnail_cue: \"1:17:25\"\n      id: \"caleb-denio-lighting-talk-railsconf-2023\"\n      video_id: \"caleb-denio-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Caleb Denio\n\n    - title: \"Lightning Talk: MagmaChat\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:19:32\"\n      end_cue: \"1:24:22\"\n      thumbnail_cue: \"1:19:37\"\n      id: \"obie-fernandez-lighting-talk-railsconf-2023\"\n      video_id: \"obie-fernandez-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Obie Fernandez\n        - Peter Szinek\n\n    - title: \"Lightning Talk: mruby on the Arduino Uno (Kinda janky)\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:24:22\"\n      end_cue: \"1:29:27\"\n      thumbnail_cue: \"1:24:27\"\n      id: \"mason-meirs-lighting-talk-railsconf-2023\"\n      video_id: \"mason-meirs-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Mason Meirs\n\n    - title: \"Lightning Talk: activerecord-summarize: For dashboards and reports\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:29:27\"\n      end_cue: \"1:33:58\"\n      thumbnail_cue: \"1:29:32\"\n      id: \"joshua-paine-lighting-talk-railsconf-2023\"\n      video_id: \"joshua-paine-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Joshua Paine\n\n    - title: \"Lightning Talk: Using Your Software Skills to Make a Difference: Helping Non-Profit Organizations with Custom Software\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:33:58\"\n      end_cue: \"1:38:40\"\n      thumbnail_cue: \"1:33:59\"\n      id: \"eric-saupe-lighting-talk-railsconf-2023\"\n      video_id: \"eric-saupe-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Eric Saupe\n\n    - title: \"Lightning Talk: Flamegraphs\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:38:40\"\n      end_cue: \"1:43:52\"\n      thumbnail_cue: \"1:38:45\"\n      id: \"josh-nichols-lighting-talk-railsconf-2023\"\n      video_id: \"josh-nichols-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Josh Nichols\n\n    - title: \"Lightning Talk: Captioners: How DO You DO That???\"\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:43:52\"\n      end_cue: \"1:47:54\"\n      thumbnail_cue: \"1:43:57\"\n      id: \"amanda-lundberg-lighting-talk-railsconf-2023\"\n      video_id: \"amanda-lundberg-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Amanda Lundberg\n\n    - title: \"Lightning Talk: Vagmi Mudumbai\" # No official title. Topic: Rust and Ruby\n      event_name: \"RailsConf 2023\"\n      date: \"2023-04-26\"\n      start_cue: \"1:47:54\"\n      end_cue: \"1:52:13\"\n      thumbnail_cue: \"1:47:59\"\n      id: \"vagmi-mudumbai-lighting-talk-railsconf-2023\"\n      video_id: \"vagmi-mudumbai-lighting-talk-railsconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Vagmi Mudumbai\n\n- id: \"allison-mcmillan-railsconf-2023\"\n  title: \"Offsite planning for Everyone\"\n  raw_title: \"RailsConf 2023 - Offsite planning for Everyone by Allison McMillan\"\n  speakers:\n    - Allison McMillan\n  description: |-\n    Over the past couple of years, we’ve all needed to sharpen the tools in our virtual toolbelt. More companies than ever are providing employees with the opportunity to work remotely… but how can we keep those individuals connected - to each other and to the mission of the company and their team? Effective in-person offsites are challenging and now we’re working to achieve the same alignment, engagements, and happiness for our employees virtually as well. It may seem impossible, but it’s not! In this session, you’ll learn about how to plan an effective offsite (in-person or remote) and what specific planning considerations can be made to make your virtual offsite just as good, if not better, than an in-person one. Skeptics welcome!!\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"ofqnAOiRwOw\"\n\n- id: \"adrianna-chang-railsconf-2023\"\n  title: \"Migrating Shopify’s Core Rails Monolith to Trilogy\"\n  raw_title: \"RailsConf 2023 - Migrating Shopify’s Core Rails Monolith to Trilogy by Adrianna Chang\"\n  speakers:\n    - Adrianna Chang\n  description: |-\n    Trilogy is a client library for MySQL-compatible databases. It was open sourced along with an Active Record adapter by GitHub this past year. With promises of improved performance, better portability and compatibility, and fewer dependencies, Shopify’s Rails Infrastructure team decided to migrate our core Rails monolith from Mysql2 to Trilogy.\n\n    In this talk, we’ll embark on a journey with database clients, Active Record adapters, and open source contributions. We’ll learn about MySQL protocols, dig into how the Active Record adapter manages the Trilogy client under the hood, and look at some of the missing features we implemented as we moved from Mysql2 to Trilogy. Finally, we’ll discuss the end result of migrating to Trilogy, and the impact it had on Shopify’s monolith in production.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"tHiIhZPKClI\"\n\n- id: \"brittany-martin-railsconf-2023\"\n  title: \"Podcast: A Ruby Community Podcast Live!\"\n  raw_title: \"RailsConf 2023 - A Ruby Community Podcast Live! by Brittany Martin, Jason Charnes & Paul Bahr\"\n  speakers:\n    - Brittany Martin\n    - Jason Charnes\n    - Paul Bahr\n    - Aaron Patterson\n    - Irina Nazarova\n    - Justin Searls\n    - Britni Alexander\n    - Collin Donnell\n    - Victoria Guido\n  description: |-\n    Join Brittany Martin (The Ruby on Rails Podcast), Jason Charnes (Remote Ruby) and Paul Bahr (Peachtree Sound) as they interview guests from the community on a live podcast.\n\n    Guest #1: Aaron Patterson, Senior Staff Engineer at Shopify\n    Guest #2: Irina Nazarova, CEO of Evil Martians\n    Guest #3: Voted on by the community in an online poll\n    Guest #4: Voted on by the community live at this session\n\n    Audience questions and voting are welcome and encouraged!\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"tNiqYktR8xo\"\n\n- id: \"ifat-ribon-railsconf-2023\"\n  title: \"Forging Your Path to Senior Developer\"\n  raw_title: \"RailsConf 2023 - Forging Your Path to Senior Developer by Ifat Ribon\"\n  speakers:\n    - Ifat Ribon\n  description: |-\n    You've mastered syntax and conventions, your team trusts your code, and you're working on more complicated features. On more challenging tasks, you often pair with your team lead, a senior developer who seems to know everything. You think to yourself, that's who I want to be, how do I get there? Fear not, mid-developer, that senior developer you admire was once in your shoes! This talk will illuminate the path you're on, providing you guidance on following those footsteps, or trailblazing your own, to achieve your objective of becoming a senior developer.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"v0OLIzH3UAc\"\n\n- id: \"kinsey-durham-grace-railsconf-2023\"\n  title: \"Building Workplaces for Caregivers: Supporting Parents in Tech\"\n  raw_title: \"RailsConf 2023 - Building Workplaces for Caregivers: Supporting Parents in Tech, Kinsey Durham Grace\"\n  speakers:\n    - Kinsey Durham Grace\n  description: |-\n    We need to support parents in our organizations and ensure we keep working parents happy and in the workplace. When parents are supported at work, it’s better for them, their families and for our businesses. This talk walks through the environment we are currently in and what tangible steps that we can all take on our teams and for ourselves as parents in order to ensure that we are supported in the workplace. The Rails community is always a leader in this space, so let’s ensure our workplaces are the best that they can be.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"vMn4LGLNc4M\"\n\n- id: \"thomas-countz-railsconf-2023\"\n  title: \"Merged PRs: An Untapped Resource for Practice and Exploration\"\n  raw_title: \"RailsConf 2023 - Merged PRs: An Untapped Resource for Practice and Exploration by Thomas Countz\"\n  speakers:\n    - Thomas Countz\n  description: |-\n    Debugging is one of the most powerful and necessary tools in a developer's toolkit, and what better way to hone our Rails debugging skills than by using real-world examples from the Rails codebase itself?\n\n    In this talk, we'll explore how using merged PRs from the Rails codebase can help improve your debugging skills, increase your familiarity with the framework, and build your confidence in navigating complex issues. By leveraging the wealth of knowledge and experience within the Rails community, you'll come away from this talk with a newfound appreciation for the power of collaboration and the importance of community-driven development.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"vdZbQHz4pfk\"\n\n- id: \"brandon-weaver-railsconf-2023\"\n  title: \"Teaching Capybara Testing - An Illustrated Adventure\"\n  raw_title: \"RailsConf 2023 - Teaching Capybara Testing - An Illustrated Adventure by  Brandon Weaver\"\n  speakers:\n    - Brandon Weaver\n  description: |-\n    100%! Red the lemur was so excited to have 100% test coverage, finally, after unit testing all of his Ruby code. With that, he was done, the code was tested, and he could call it a day.\n\n    That was until a magical Capybara entered through his window and asked a question that changed his perceptions forever more:\n\n    \"But what about your end to end tests?\"\n\n    ...and when he did, everything broke, and he was enlightened.\n\n    Join us on an illustrated adventure through the basics of end to end testing with Capybara.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"wWPxLJJlnmU\"\n\n- id: \"jol-quenneville-railsconf-2023\"\n  title: \"The Math Every Programmer Needs\"\n  raw_title: \"RailsConf 2023 - The Math Every Programmer Needs by Joël Quenneville\"\n  speakers:\n    - Joël Quenneville\n  description: |-\n    Leave your fear of math behind along with the equations and symbols, we're headed to Ruby-land! On this whirlwind tour, we’ll explore how to write better conditionals with Boolean algebra, figure out how many test cases we need with combinatorics, a mental model for breaking down large tasks with graph theory, and more.\n\n    You’ll leave this talk equipped to better do your job with some ideas, techniques, and mental models from the wonderfully practical world of discrete math.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  slides_url: \"https://speakerdeck.com/joelq/the-math-every-programmer-needs\"\n  video_provider: \"youtube\"\n  video_id: \"wzYYT40T8G8\"\n\n- id: \"ali-ibrahim-railsconf-2023\"\n  title: \"Zero downtime Rails upgrades\"\n  raw_title: \"RailsConf 2023 - Zero downtime Rails upgrades by Ali Ibrahim\"\n  speakers:\n    - Ali Ibrahim\n  description: |-\n    No one likes working on Rails upgrades, and who can blame them? They can be thankless, time-consuming, and—worst of all—unpredictable. How long will they take? When can we get back to feature work? What’ll break when they’re deployed? It’s tempting to say, “Let’s do it later,” but later is usually never. Instead of living in fear of the big, scary Rails upgrade, your team can set up systems for incremental change that let you:\n\n    * continue feature work\n    * deliver predictable results\n    * seamlessly jump into the next upgrade (because there’s always a next upgrade)\n\n    And I’m gonna show you how.\n\n    In the years since I’ve worked on upgrading Rails at GitHub, I’ve refined this approach to Rails upgrades and successfully implemented it at several organizations. In this talk, you’ll learn everything you need to burn down uncertainty and boldly go into your next Rails upgrade.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"zHK-quUz-5M\"\n\n- id: \"pat-allan--upgrading-the-ruby-community\"\n  title: \"Upgrading the Ruby Community\"\n  raw_title: \"RailsConf 2023 - Upgrading the Ruby Community by Pat Allan\"\n  speakers:\n    - Pat Allan\n  description: |-\n    From MINASWAN to Rails Camps, conference guides to Ruby Together, there’s a long history of the Ruby community being wonderfully welcoming, thoughtful, fun and supportive. Let’s make it even better, and discuss ways to have a persistent, positive impact in the wider tech industry and beyond.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"10evYV5qT7c\"\n\n- id: \"anjuan-simmons-railsconf-2023\"\n  title: \"Managing the Burnout Burndown\"\n  raw_title: \"RailsConf 2023 - Managing the Burnout Burndown by Anjuan Simmons\"\n  speakers:\n    - Anjuan Simmons\n  description: |-\n    In addition to managing backlogs and burndown charts, technology leaders have to follow an ever-changing software landscape, manage team dynamics, and navigate office politics. It’s no surprise that this leads to burnout. This talk will provide tools to help manage stress and reduce burnout.\n\n    Developers are, almost by definition, highly capable and strongly driven individuals. These traits are indispensable to success in creating working code, but they are also the very traits that makes developers susceptible to burn out. People who can get things done often find themselves overwhelmed by their to-do lists.\n\n    This talk will combine the understanding from the trenches of Anjuan Simmons (who has been a developer and engineering manager for more than 20 years) with the academic understanding of his wife, Dr. Aneika Simmons. Together, they will provide a framework for reducing burnout and consistently keeping stress levels in a managed state.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"BDnWcZobdrA\"\n\n- id: \"andy-croll-railsconf-2023\"\n  title: \"Taylor’s Guide to Big Rewrites\"\n  raw_title: \"RailsConf 2023 - Taylor’s Guide to Big Rewrites by Andy Croll\"\n  speakers:\n    - Andy Croll\n  description: |-\n    Taylorism, is a system of management advocated by Fred W. Taylor. The task of management, as he saw it, is to find the best way for the worker to do the job, with proper tools and training, and to provide incentives for good performance.\n\n    There are certain things you’re meant to do in software projects and business. And certain things you’re not. A big rewrite of your app is one of the things you aren’t meant to do.\n\n    Except that’s what we did with a team of 4 engineers, over an 18 month period, successfully migrating 2,500 customer’s data.\n\n    How can we apply the learnings of Taylor, to a massive application rewrite? What did we do and what can you learn when you’re faced with a wild and woolly project? What about our business practises as well as our code helped us make a success of one of software’s shibboleths?\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"G1QbH2QZX08\"\n\n- id: \"hilary-stohs-krause--how-we-implemented-internal-sa\"\n  title: \"How We Implemented Internal Salary Transparency (And Why It Matters)\"\n  raw_title: \"RailsConf 2023 - How We Implemented Internal Salary Transparency ... by  Hilary Stohs Krause\"\n  speakers:\n    - Hilary Stohs-Krause\n  description: |-\n    How We Implemented Internal Salary Transparency (And Why It Matters) by\n    Hilary Stohs-Krause\n\n    Money can be a prickly topic in the workplace, but data shows it’s a conversation that many employees actively want started. Salary transparency increases trust and job satisfaction, but getting there is easier said than done. Here’s how we took the plunge, and what we learned along the way.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"MfGRm8Dm68g\"\n\n- id: \"eileen-m-uchitelle-railsconf-2023\"\n  title: \"Keynote: The Magic of Rails\"\n  raw_title: \"RailsConf 2023 - Keynote by Eileen Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  description: |-\n    Keynote by Eileen M. Uchitelle\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  slides_url: \"https://speakerdeck.com/eileencodes/the-magic-of-rails\"\n  video_provider: \"youtube\"\n  video_id: \"TKulocPqV38\"\n\n- id: \"gary-ware-railsconf-2023\"\n  title: \"Keynote: The Power of Improv: Unlocking Your Creative Potential as a Developer\"\n  raw_title: \"RailsConf 2023 - Keynote: The Power of Improv: Unlocking Your Creative Potential as a.. by Gary Ware\"\n  speakers:\n    - Gary Ware\n  description: |-\n    Keynote: The Power of Improv: Unlocking Your Creative Potential as a Developer by Gary Ware\n\n    This interactive keynote will explore how improvisation can help you maximize your strengths as a developer. We'll discuss the key elements of improvisation and how they can be used in your day to day life. We will also do a few quick activities to allow you to practice in real time in a low-stakes environment. By the end of this session, you will have gained valuable insight into how embracing an improvisational mindset can supercharge your ability to be more creative, collaborate with others, and get more enjoyment from your career.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"g6wrSpFFgmQ\"\n\n- id: \"shana-moore--panel-mentorship\"\n  title: \"Panel: Mentorship\"\n  raw_title: \"RailsConf 2023 - Mentorship Panel - Shana Moore, John Sawers, Ebun Segun, Erik Guzman & Adam Cuppy\"\n  speakers:\n    - Shana Moore\n    - John Sawers\n    - Ebun Segun\n    - Erik Guzman\n    - Adam Cuppy\n  description: |-\n    Join us for a mentorship panel featuring four seasoned software developers sharing their personal experiences as mentors and mentees. Attendees can expect to gain insights on building mentor-mentee relationships and practical tips for maximizing them while discovering the benefits of mentorship, how to approach potential mentors, and effective communication strategies.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"lXhTh3BUuJE\"\n\n- id: \"adam-cuppy-railsconf-2023\"\n  title: \"Mentorship in Three Acts\"\n  raw_title: \"RailsConf 2023 - Mentorship in Three Acts by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  description: |-\n    \"Mentorship (ˈmɛntɔːˌʃɪp) Noun. a period during which a person receives guidance from a mentor.\" Yeah, it seems clear enough.\n\n    More and more, teams rely on mentorship to raise the skills of their under-experienced people. But mentorship is not a catch-all solution and has its risks. Without training, poorly structured mentorship can hurt the culture and stifle growth more than help.\n\n    So, we need a model—a system. A process to lean into that makes it a helpful tool and not a blunt hammer. This talk will cover the three stages of integrating a mentorship program and how to help a hesitant team.\n  date: \"2023-07-10\"\n  published_at: \"2023-07-14\"\n  video_provider: \"youtube\"\n  video_id: \"nOhGMcjL0jk\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2024/cfp.yml",
    "content": "---\n- link: \"https://sessionize.com/railsconf2024\"\n  open_date: \"2024-01-24\"\n  close_date: \"2024-02-13\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2024/event.yml",
    "content": "---\nid: \"PLbHJudTY1K0chrs_E_XFz2pOJ3d8jCayh\"\ntitle: \"RailsConf 2024\"\nkind: \"conference\"\nlocation: \"Detroit, MI, United States\"\ndescription: |-\n  RailsConf, hosted by Ruby Central, is the world’s largest and longest-running gathering of Ruby on Rails enthusiasts, practitioners, and companies.\npublished_at: \"2024-07-10\"\nstart_date: \"2024-05-07\"\nend_date: \"2024-05-09\"\nyear: 2024\nwebsite: \"https://2024.railsconf.org\"\nbanner_background: \"#DB525A\"\nfeatured_background: \"#231F20\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 42.3261\n  longitude: -83.0571\n"
  },
  {
    "path": "data/railsconf/railsconf-2024/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users: []\n  organisations:\n    - Ruby Central\n\n- name: \"Co-Chair\"\n  users:\n    - Ufuk Kayserilioglu\n    - Andy Croll\n\n- name: \"Volunteer\"\n  users: []\n"
  },
  {
    "path": "data/railsconf/railsconf-2024/schedule.yml",
    "content": "# Schedule: https://railsconf.org/schedule/\n# Embed: https://sessionize.com/api/v2/zu53k32c/view/GridSmart?under=True\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-05-07\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Registration & Breakfast\n\n      - start_time: \"09:30\"\n        end_time: \"09:50\"\n        slots: 1\n        items:\n          - Introduction\n\n      - start_time: \"09:50\"\n        end_time: \"10:50\"\n        slots: 1\n\n      - start_time: \"10:50\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:45\"\n        slots: 4\n\n      - start_time: \"11:45\"\n        end_time: \"12:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"12:00\"\n        end_time: \"12:45\"\n        slots: 4\n\n      - start_time: \"12:45\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:45\"\n        slots: 4\n\n      - start_time: \"14:45\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:45\"\n        slots: 4\n\n      - start_time: \"15:45\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 4\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"17:00\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"18:05\"\n        slots: 1\n\n  - name: \"Day 2\"\n    date: \"2024-05-08\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Breakfast\n\n      - start_time: \"09:00\"\n        end_time: \"09:20\"\n        slots: 1\n        items:\n          - Introduction\n\n      - start_time: \"09:20\"\n        end_time: \"10:20\"\n        slots: 1\n\n      - start_time: \"10:20\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:30\"\n        end_time: \"12:30\"\n        slots: 3\n\n      - start_time: \"12:20\"\n        end_time: \"14:20\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:30\"\n        end_time: \"16:30\"\n        slots: 3\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"17:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - Happy Hour\n\n      - start_time: \"19:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - title: \"Game Night\"\n            description: |-\n              Game night is ON! This is a B.Y.O.G. (Bring Your Own Game) special event space where you can get together, drink, snack, and play with #RubyFriends for the night.\n\n              **Please NO games that include throwing or kicking objects!**\n\n              Marriott - 42 Degree room, 3rd Floor Sponsored by Mike Perham (Sidekiq)\n\n  - name: \"Day 3\"\n    date: \"2024-05-09\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Breakfast\n\n      - start_time: \"09:00\"\n        end_time: \"09:45\"\n        slots: 3\n\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:00\"\n        end_time: \"10:45\"\n        slots: 3\n\n      - start_time: \"10:45\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:45\"\n        slots: 3\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"14:15\"\n        slots: 4\n\n      - start_time: \"14:15\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:30\"\n        end_time: \"15:15\"\n        slots: 4\n\n      - start_time: \"15:15\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"18:30\"\n        slots: 1\n        items:\n          - Closing Reception\n\ntracks:\n  - name: \"Supporter Talk\"\n    color: \"#E1CD00\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum\"\n      description: |-\n        Top level sponsors with highest sponsorship tier.\n      level: 1\n      sponsors:\n        - name: \"Revela\"\n          website: \"https://www.revela.co/\"\n          slug: \"Revela\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/revela.png\"\n\n    - name: \"Gold\"\n      description: |-\n        Second level sponsors with gold tier sponsorship.\n      level: 2\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com/\"\n          slug: \"Shopify\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/shopify_logo_black.png\"\n\n        - name: \"Gusto\"\n          website: \"https://gusto.com/\"\n          slug: \"Gusto\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/gusto-logo_f45d48-1-.png\"\n\n        - name: \"Cisco Meraki\"\n          website: \"https://meraki.cisco.com/\"\n          slug: \"CiscoMeraki\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/cisco-meraki-logo-full-color-digital.png\"\n\n    - name: \"Silver\"\n      description: |-\n        Third level sponsors with silver tier sponsorship.\n      level: 3\n      sponsors:\n        - name: \"Weedmaps\"\n          website: \"https://weedmaps.com/\"\n          slug: \"Weedmaps\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/weedmaps_logo_2020_transparentbgrd.png\"\n\n        - name: \"Flagrant\"\n          website: \"https://www.beflagrant.com/\"\n          slug: \"Flagrant\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/flagrant.webp\"\n\n        - name: \"Chime\"\n          website: \"https://www.chime.com/\"\n          slug: \"Chime\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/chime.png\"\n\n        - name: \"Beyond\"\n          website: \"https://www.beyondfinance.com/about/\"\n          slug: \"Beyond\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/600x300_beyond_logo.png\"\n\n    - name: \"Bronze\"\n      description: |-\n        Fourth level sponsors with bronze tier sponsorship.\n      level: 4\n      sponsors:\n        - name: \"Rezoomex\"\n          website: \"https://rezoomex.com/\"\n          slug: \"Rezoomex\"\n\n          logo_url: \"https://2024.railsconf.org/images/uploads/rezoomex.jpg\"\n        - name: \"ID.me\"\n          website: \"https://www.id.me/\"\n          slug: \"ID.me\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/id.me-logo-color.png\"\n\n        - name: \"Cedarcode\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"Cedarcode\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/cedarcodelogo-horizontal-dark-1080x164.png\"\n\n    - name: \"Other\"\n      description: |-\n        Other sponsors not fitting in main tiers.\n      level: 5\n      sponsors:\n        - name: \"WyeWorks\"\n          website: \"https://www.wyeworks.com/\"\n          slug: \"WyeWorks\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/wyeworks.png\"\n\n        - name: \"Tito\"\n          website: \"https://ti.to/home\"\n          slug: \"Tito\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/tito.webp\"\n\n        - name: \"thoughtbot\"\n          website: \"https://thoughtbot.com/\"\n          slug: \"thoughtbot\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/thoughtbot_horizontal.png\"\n\n        - name: \"Sidekiq\"\n          website: \"https://sidekiq.org/\"\n          slug: \"Sidekiq\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/sidekiq.png\"\n\n        - name: \"Scout Monitoring\"\n          website: \"https://www.scoutapm.com/\"\n          slug: \"ScoutMonitoring\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/scout-logo.png\"\n\n        - name: \"Render\"\n          website: \"https://render.com/\"\n          slug: \"Render\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/render.png\"\n\n        - name: \"GitLab\"\n          website: \"https://gitlab.com/\"\n          slug: \"GitLab\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/gitlab.png\"\n\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"AppSignal\"\n          logo_url: \"https://2024.railsconf.org/images/uploads/appsignal_2022.png\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2024/venue.yml",
    "content": "---\nname: \"Huntington Place\"\n\naddress:\n  street: \"1 Washington Blvd\"\n  city: \"Detroit\"\n  region: \"Michigan\"\n  postal_code: \"48226\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"1 Washington Blvd, Detroit, MI 48226, USA\"\n\ncoordinates:\n  latitude: 42.3261\n  longitude: -83.0571\n\nmaps:\n  google: \"https://maps.google.com/?q=Huntington+Place,+Detroit\"\n  apple: \"https://maps.apple.com/?q=Huntington+Place,+Detroit\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=42.3261&mlon=-83.0571\"\n\nhotels:\n  - name: \"Detroit Marriott at the Renaissance Center\"\n    kind: \"Conference Hotel\"\n    address:\n      street: \"400 Renaissance Drive West\"\n      city: \"Detroit\"\n      region: \"Michigan\"\n      postal_code: \"48243\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"400 Renaissance Dr, Detroit, MI 48243, United States\"\n    coordinates:\n      latitude: 42.328581\n      longitude: -83.040622\n    maps:\n      apple:\n        \"https://maps.apple.com/place?address=400%20Renaissance%20Dr,%20Detroit,%20MI%2048243,%20United%20States&coordinate=42.328581,-83.040622&name=Detroit%20Marriott%20at%20the%\\\n        20Renaissance%20Center&place-id=IB38F7DA065975371&map=transit\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2024/videos.yml",
    "content": "---\n# TODO: conference website\n# TODO: schedule website\n\n## Day 1\n\n- id: \"nadia-odunayo-railsconf-2024\"\n  title: \"Keynote: Getting to Two Million Users as a One Woman Dev Team\"\n  raw_title: \"RailsConf 2024 - Opening Conference Keynote by Nadia Odunayo\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"TWi-cSHNr5s\"\n\n- id: \"youssef-boulkaid-railsconf-2024\"\n  title: \"Ask your logs\"\n  raw_title: \"RailsConf 2024 -  Ask your logs by Youssef Boulkaid\"\n  speakers:\n    - Youssef Boulkaid\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Logging is often an afterthought when we put our apps in production. It's there, it's configured by default and it's... good enough?\n\n    If you have ever tried to debug a production issue by digging in your application logs, you know that it is a challenge to find the information you need in the gigabyte-sized haystack that is the default rails log output.\n\n    In this talk, let's explore how we can use structured logging to turn our logs into data and use dedicated tools to ask — and answer — some non-obvious questions of our logs.\n  video_provider: \"youtube\"\n  video_id: \"y-VMajyrQnU\"\n\n- id: \"stephanie-minn-railsconf-2024\"\n  title: \"So writing tests feels painful. What now?\"\n  raw_title: \"RailsConf 2024 - So writing tests feels painful. What now? by Stephanie Minn\"\n  speakers:\n    - Stephanie Minn\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    When you write tests, you are interacting with your code. Like any user experience, you may encounter friction. Stubbing endless methods to get to green. Fixing unrelated spec files after a minor change. Rather than push on, let this tedium guide you toward better software design.\n\n    With examples in RSpec, this talk will take you step-by-step from a troublesome test to an informed refactor. Join me in learning how to attune to the right signals and manage complexity familiar to any Rails developer. You’ll leave with newfound inspiration to write clear, maintainable tests in peace. Your future self will thank you!\n  video_provider: \"youtube\"\n  video_id: \"VmWCJFiU1oM\"\n\n- id: \"hilary-stohs-krause-railsconf-2024\"\n  title: \"How to Accessibility if You’re Mostly Back-End\"\n  raw_title: \"RailsConf 2024 - How to Accessibility if You’re Mostly Back-End by Hilary Stohs-Krause\"\n  speakers:\n    - Hilary Stohs-Krause\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    If you work mostly on the back-end of the tech stack, it’s easy to assume that your role is disengaged from accessibility concerns. After all, that’s the front-end’s job! However, there are multiple, specific ways back-end devs can impact accessibility - not just for users, but also for colleagues.\n  video_provider: \"youtube\"\n  video_id: \"GyUxe7PMD4A\"\n\n- id: \"supporter-talk-revela-railsconf-2024\"\n  title: \"Supporter Talk by Revela: Scenic Views: Using the Scenic Gem to Leverage Database Views in ActiveRecord\"\n  raw_title: \"RailsConf 2024 - Scenic Views: Using the Scenic Gem to Leverage Database Views in ActiveRecord by John DeSilva and Grant Drzyzga\"\n  speakers:\n    - John DeSilva\n    - Grant Drzyzga\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  track: \"Supporter Talk\"\n  description: |-\n    Learn how to take the Scenic Gem route for enterprise reporting. In this talk, you'll learn how to transform the complex terrain of database reporting into\n    much more pleasant views.\n\n    John DeSilva and Grant Drzyzga, co-founders of Revela, will provide insight into their startup success and how Ruby on Rails helped them overcome a variety of challenges they faced in building a next-gen enterprise real estate software that is rapidly disrupting the market. The Revela platform now manages billions of dollars in real estate assets.\n\n    John will discuss how database views can be leveraged in ActiveRecord to optimize reporting performance and other challenges you will encounter when faced with ever-expanding datasets and requirements.\n  video_provider: \"not_recorded\"\n  video_id: \"supporter-talk-revela-railsconf-2024\"\n\n- id: \"manu-janardhanan-railsconf-2024\"\n  title: \"Look Ma, No Background Jobs: A Peek into the Async Future\"\n  raw_title: \"RailsConf 2024 - Look Ma, No Background Jobs: A Peek into the Async Future by Manu J\"\n  speakers:\n    - Manu Janardhanan\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Executing a long running task like external API requests in the request-response cycle is guaranteed to bring your Rails app to its knees sooner or later. We have relied on background jobs to offload long running tasks due to this.\n\n    But it doesn't always have to be. Learn how you can leverage Falcon and the Async gem to unlock the full potential of ruby fibers and eliminate background jobs for IO-bound tasks and execute them directly with clean, simple, performant and scalable code.\n  video_provider: \"youtube\"\n  video_id: \"QeYcKw7nOkg\"\n\n- id: \"talysson-oliveira-cassiano-railsconf-2024\"\n  title: \"Ruby on Fails: effective error handling with Rails conventions\"\n  raw_title: \"RailsConf 2024 -  Ruby on Fails: effective error handling with... by Talysson Oliveira Cassiano\"\n  speakers:\n    - Talysson Oliveira Cassiano\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Ruby on Fails - effective error handling with Rails conventions by Talysson Oliveira Cassiano\n\n    You ask 10 different developers how they handle errors in their applications, you get 10 very different answers or more, that’s wild. From never raising errors to using custom errors, rescue_from, result objects, monads, we see all sorts of opinions out there. Is it possible that all of them are right? Maybe none of them? Do they take advantage of Rails conventions? In this talk, I will show you error-handling approaches based on patterns we see on typical everyday Rails applications, what their tradeoffs are, and which of them are safe defaults to use as a primary choice when defining the architecture of your application\n  video_provider: \"youtube\"\n  video_id: \"qFZb9fMz8bs\"\n\n- id: \"joel-hawksley-railsconf-2024\"\n  title: \"How to make your application accessible (and keep it that way!)\"\n  raw_title: \"RailsConf 2024 - How to make your application accessible (and keep it that way!) by Joel Hawksley\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Our industry is shockingly bad at accessibility: by some estimates, over 70% of websites are effectively unavailable to blind users! Making your app accessible isn’t just the right thing to do, it’s the law. In this talk, we’ll share what it’s taken to scale GitHub’s accessibility program and equip you to do the same at your company.\n  video_provider: \"youtube\"\n  video_id: \"ZRUn-yRH0ks\"\n\n- id: \"supporter-talk-shopify-railsconf-2024\"\n  title: \"Supporter Talk by Shopify: Meet the Shopify Engineering Team\"\n  raw_title:\n    \"RailsConf 2024 - Meet the Shopify Engineering team by Aaron Patterson, Adrianna Chang, Andrew Novoselac, Andy Waite, Eileen Uchitelle, Betty Li, Gabi Stefanini, Gannon\n    McGibbon, George Ma, Jenny Shen, Nikita Vasilevsky\"\n  speakers:\n    - Aaron Patterson\n    - Adrianna Chang\n    - Andrew Novoselac\n    - Andy Waite\n    - Eileen M. Uchitelle\n    - Betty Li\n    - Gabi Stefanini\n    - Gannon McGibbon\n    - George Ma\n    - Jenny Shen\n    - Nikita Vasilevsky\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  track: \"Supporter Talk\"\n  description: |-\n    Interested in Shopify's Rails-related projects this past year? Join our Meet the Team session!\n\n    We'll have folks ready to chat about:\n    * Trilogy: Migrating our monolith to the Trilogy database client.\n    * Composite Primary Keys: Adopting composite primary keys in our monolith.\n    * Rails upgrades: Running our monolith on Rails edge and our tooling for automating Rails upgrades.\n    * devcontainer: Creating a convenient and consistent dev env for working on Rails apps.\n    * Packwerk 3: Evolving how we use Packwerk based on our learnings. (https://railsatscale.com/2024-01-26-a-packwerk-retrospective/)\n\n    Stop by to get and offer feedback, ask a question, or to pair program!\n  video_provider: \"not_recorded\"\n  video_id: \"supporter-talk-shopify-railsconf-2024\"\n\n# Lunch\n\n- id: \"chris-oliver-railsconf-2024\"\n  title: \"Crafting Rails Plugins\"\n  raw_title: \"RailsConf 2024 - Crafting Rails Plugins by Chris Oliver\"\n  speakers:\n    - Chris Oliver\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  slides_url: \"https://speakerdeck.com/excid3/crafting-rails-plugins\"\n  description: |-\n    Ever wanted to build a plugin for Rails to add new features? Rails plugins allow you to hook into the lifecycle of a Rails application to add routes, configuration, migrations, models, controllers, views and more. In this talk, we'll learn how to do this by looking at some examples Rails gems to see how they work.\n  video_provider: \"youtube\"\n  video_id: \"LxTCpTXhpzw\"\n\n- id: \"karynn-ikeda-railsconf-2024\"\n  title: \"What's in a Name: From Variables to Domain-Driven Design\"\n  raw_title: \"RailsConf 2024 - What's in a Name: From Variables to Domain-Driven Design by Karynn Ikeda\"\n  speakers:\n    - Karynn Ikeda\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Join me on a crash course in semantic theory to unpack one of the hardest problems in software engineering: naming things. Dive into how names act as a linguistic front-end, masking a more complex backend of unseen associations. We’ll start from a single variable name and zoom out to the vantage point of domain-driven design, and track how consequential naming is at each stage to help you improve your code, no matter your level of experience.\n  video_provider: \"youtube\"\n  video_id: \"1flw60hwcLg\"\n\n- id: \"george-ma-railsconf-2024\"\n  title: \"Ruby & Rails Versioning at Scale\"\n  raw_title: \"RailsConf 2024 - Ruby & Rails Versioning at Scale by George Ma\"\n  speakers:\n    - George Ma\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    In this talk we will dive into how Shopify automated Rails upgrades as well as leveraged Dependabot, Rubocop, and Bundler to easily upgrade and maintain 300+ Ruby Services at Shopify to be on the latest Ruby & Rails versions. You'll learn how you can do the same!\n  video_provider: \"youtube\"\n  video_id: \"XBdsKmxS2lw\"\n\n- id: \"supporter-talk-gusto-railsconf-2024\"\n  title: \"Supporter Talk by Gusto: Gusto Spark Sessions - Lighting Talks by Gusto Engineering\"\n  raw_title: \"RailsConf 2024 - Gusto Spark Sessions - Lighting Talks by Gusto Engineering\"\n  speakers:\n    - Ivy Evans\n    - Junji Zhi\n    - Gusto Engineering Team\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  track: \"Supporter Talk\"\n  description: |-\n    Lighting Talks hosted by Gusto will feature talks from members of the Gusto engineering team. Talks will cater to attendees of all experience levels.\n  video_provider: \"not_recorded\"\n  video_id: \"supporter-talk-gusto-railsconf-2024\"\n\n- id: \"andy-waite-railsconf-2024\"\n  title: \"A Rails server in your editor: Using Ruby LSP to extract runtime information\"\n  raw_title: \"RailsConf 2024 - A Rails server in your editor: Using Ruby LSP to extract runtime... by Andy Waite\"\n  speakers:\n    - Andy Waite\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    A Rails server in your editor: Using Ruby LSP to extract runtime information by Andy Waite\n\n    Language servers, like the Ruby LSP, typically use only static information about the code to provide editor features. But Ruby is a dynamic language and Rails makes extensive use of its meta-programming features. Can we get information from the runtime instead and use that to increase developer happiness?\n\n    In this talk, we're going to explore how the Ruby LSP connects with the runtime of your Rails application to expose information about the database, migrations, routes and more. Join us for an in-depth exploration of Ruby LSP Rails, and learn how to extend it to support the Rails features most important to your app.\n  video_provider: \"youtube\"\n  video_id: \"oYTwUHAdH_A\"\n\n- id: \"sweta-sanghavi-railsconf-2024\"\n  title: \"Plain, Old, but Mighty: Leveraging POROs in Greenfield and Legacy Code\"\n  raw_title: \"RailsConf 2024 - Plain, Old, but Mighty: Leveraging POROs in Greenfield and... by Sweta Sanghavi\"\n  speakers:\n    - Sweta Sanghavi\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Plain, Old, but Mighty: Leveraging POROs in Greenfield and Legacy Code by Sweta Sanghavi\n\n    Applications exist in changing ecosystems, but over time, they can become less responsive. Controllers actions slowly grow in responsibilities. Models designed for one requirement, no longer fit the bill, and require multi-step deploy processes to change.\n\n    The plain old Ruby object, the mighty PORO, provides flexibility in both new domain and legacy code.\n\n    Pair with me on how! We'll explore how we can leverage POROs in our application through some real world examples. We'll use objects as a facade for domain logic in development, and refactor objects out of legacy code to increase readability, ease of testing, and flexibility. You'll leave this session with some strategies to better leverage Ruby objects in your own application.\n  video_provider: \"youtube\"\n  video_id: \"KQHD-0y8tDw\"\n\n- id: \"collin-jilbert-railsconf-2024\"\n  title: \"From Cryptic Error Messages To Rails Contributor\"\n  raw_title: \"RailsConf 2024 - From Cryptic Error Messages To Rails Contributor by Collin Jilbert\"\n  speakers:\n    - Collin Jilbert\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Discover how encountering perplexing and misleading error messages in Ruby on Rails can lead to opportunities for contribution by delving into a real-world example. Join me as we dissect a perplexing Ruby on Rails error by navigating the source code. Discover how seemingly unrelated errors can be intertwined. As responsible community members, we'll explore turning this into an opportunity for contribution. Learn to navigate Rails, leverage Ruby fundamentals, and make impactful changes. From local experiments to contribution submission, empower yourself to enhance the experience of building with Rails for yourself and the community.\n  video_provider: \"youtube\"\n  video_id: \"7EpJQn6ObEw\"\n\n- id: \"supporter-talk-cisco-meraki-railsconf-2024\"\n  title: \"Supporter Talk by Cisco Meraki: You Could Learn a Lot from a Dummy\"\n  raw_title: \"RailsConf 2024 - You Could Learn a Lot from a Dummy by Kevin Hurley and Fito Von Zastrow\"\n  speakers:\n    - Kevin Hurley\n    - Fito von Zastrow\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  track: \"Supporter Talk\"\n  description: |-\n    The automotive industry has learned a great deal and significantly improved the design of their safety systems through baseline regression testing, otherwise known as crash testing. Manufacturers use sophisticated dummies to record how a collision affects the occupants of a vehicle, then analyze the data to help create improved designs which can be evaluated in another test. What can Rails developers learn from this technique? How can and when should we leverage baseline regression tests to safely improve the design of our mission critical systems? What exactly can we learn from crash test dummies?\n  video_provider: \"not_recorded\"\n  video_id: \"supporter-talk-cisco-meraki-railsconf-2024\"\n\n- id: \"garrett-dimon-railsconf-2024\"\n  title: \"Save Time with Custom Rails Generators\"\n  raw_title: \"RailsConf 2024 - Save Time with Custom Rails Generators by Garrett Dimon\"\n  speakers:\n    - Garrett Dimon\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  slides_url: \"https://speakerdeck.com/garrettdimon/save-time-by-creating-custom-rails-generators\"\n  description: |-\n    Become skilled at quickly creating well-tested custom generators and turn those tedious and repetitive ten-minute distractions into ten-second commands—not just for you but for your entire team. With some curated knowledge and insights about custom generators and some advanced warning about the speed bumps, it can save time in far more scenarios than you might think.\n  video_provider: \"youtube\"\n  video_id: \"kKhzSge226g\"\n\n- id: \"kasper-timm-hansen-railsconf-2024\"\n  title: \"Riffing on Rails: sketch your way to better designed code\"\n  raw_title: \"RailsConf 2024 - Riffing on Rails: sketch your way to better designed code by  Kasper Timm Hansen\"\n  speakers:\n    - Kasper Timm Hansen\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  slides_url: \"https://speakerdeck.com/kaspth/railsconf-2024-riffing-on-rails-sketch-your-way-to-better-designed-code\"\n  description: |-\n    Say you've been tasked with building a feature or subsystem in a Rails app. How do you get started? How do you plan out your objects? How do you figure out the names, responsibilities, and relationships? While some reach for pen & paper and others dive straight into implementation, there's a third option: Riffing on Rails.\n\n    When you riff, you work with Ruby code in a scratch file to help drive your design. This way you get rapid feedback and can revise as quickly as you had the idea — try out alternative implementations too! It's great for building shared understanding by pairing with a coworker.\n\n    Walk away with new ideas for improving your software making process: one where code is less daunting & precious. Riffing gives you space & grace to try more approaches & ideas. Let's riff!\n  video_provider: \"youtube\"\n  video_id: \"vH-mNygyXs0\"\n\n- id: \"nikita-vasilevsky-railsconf-2024\"\n  title: \"Implementing Native Composite Primary Key Support in Rails 7.1\"\n  raw_title: \"RailsConf 2024 - Implementing Native Composite Primary Key Support in Rails 7.1 by Nikita Vasilevsky\"\n  speakers:\n    - Nikita Vasilevsky\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Explore the new feature of composite primary keys in Rails! Learn how to harness this powerful feature to optimize your applications, and gain insights into the scenarios where it can make a significant difference in database performance. Elevate your Rails expertise and stay ahead of the curve!\n  video_provider: \"youtube\"\n  video_id: \"Gm5Aiai368Y\"\n\n- id: \"supporter-talk-weedmaps-railsconf-2024\"\n  title: \"Supporter Talk by Weedmaps: Local Dev Automation & Orchestration\"\n  raw_title: \"RailsConf 2024 - Local Dev Automation & Orchestration by Brad Leslie\"\n  speakers:\n    - Brad Leslie\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  track: \"Supporter Talk\"\n  description: |-\n    Level up your local development! Explore automation & orchestration with Docker, Makefiles, and bash scripts. Learn how to integrate apps seamlessly, tackle dependency challenges, and supercharge local development & testing.\n  video_provider: \"not_recorded\"\n  video_id: \"supporter-talk-weedmaps-railsconf-2024\"\n\n- id: \"irina-nazarova-railsconf-2024\"\n  title: \"Keynote: Startups on Rails in 2024\"\n  raw_title: \"RailsConf 2024 - Keynote: Startups on Rails in 2024 by Irina Nazarova\"\n  speakers:\n    - Irina Nazarova\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  slides_url: \"https://speakerdeck.com/irinanazarova/railsconf-2024-keynote-startups-on-rails-in-2024\"\n  description: |-\n    Let's hear from startups that chose Rails in recent years. Would you be surprised to hear that Rails is quietly recommended founder to founder in the corridors of Y Combinator? But it’s not only the praise that is shared.\n\n    Rails is a 1-person framework, and the framework behind giants like Shopify. Airbnb, Twitter and Figma started on Rails back in the days, but those are stories of the past. As the new businesses switched to prioritizing productivity and pragmatism again, Rails 7 had stepped up its game with Hotwire. But is the startup community ready to renew the vows with Rails and commit to each other again? The answer is: Maybe!\n\n    Let's use feedback from those founders to discuss how Rails has aided their growth and what improvements would help more founders start-up on Rails!\n  video_provider: \"youtube\"\n  video_id: \"-sFYiyFQMU8\"\n\n- id: \"andy-croll-railsconf-2024\"\n  title: \"Closing Day 1\"\n  raw_title: \"RailsConf 2024 - Closing Day 1 with Andy Croll\"\n  speakers:\n    - Andy Croll\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-07\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Closing Day 1 with Andy Croll\n  video_provider: \"youtube\"\n  video_id: \"1-cPB5Ft9Kk\"\n\n## Day 2\n\n- id: \"john-hawthorn-railsconf-2024\"\n  title: \"Keynote: Vernier - A next Generation Ruby Profiler\"\n  raw_title: \"RailsConf 2024 - Day 2 Keynote by John Hawthorn\"\n  speakers:\n    - John Hawthorn\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-08\"\n  published_at: \"2024-07-10\"\n  description: |-\n    This talk introduces Vernier: a new sampling profiler for Ruby 3.2+ which is able to capture more details than existing tools including threads, ractors, the GVL, Garbage Collection, idle time, and more!\n  video_provider: \"youtube\"\n  video_id: \"WFtZjGT8Ih0\"\n\n# TODO: missing hackday\n\n- id: \"stephen-margheim-railsconf-2024\"\n  title: \"Workshop: SQLite on Rails: From rails new to 50k concurrent users and everything in between\"\n  raw_title: \"RailsConf 2024 - SQLite on Rails: From rails new to 50k concurrent... by Stephen Margheim\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-08\"\n  published_at: \"2024-07-10\"\n  description: |-\n    SQLite on Rails: From rails new to 50k concurrent users and everything in between by Stephen Margheim \n\n    Learn how to build and deploy a Rails application using SQLite with hands-on exercises! Together we will take a brand new Rails application and walk through various features and enhancements to make a production-ready, full-featured application using only SQLite. We will take advantage of SQLite's lightweight database files to create separate databases for our data, job queue, cache, error monitoring, etc. We will install and use a SQLite extension to build vector similarity search. We will setup point-in-time backups with Litestream. We will also explore how to deploy your application. By the end of this workshop, you will understand what kinds of applications are a good fit for SQLite, how to build a resilient SQLite on Rails application, and how to scale to 50k+ concurrent users.\n  video_provider: \"youtube\"\n  video_id: \"cPNeWdaJrL0\"\n\n- id: \"jason-swett-railsconf-2024\"\n  title: \"Workshop: TDD for Absolute Beginners\"\n  raw_title: \"RailsConf 2024 - TDD for Absolute Beginners by Jason Swett\"\n  speakers:\n    - Jason Swett\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-08\"\n  published_at: \"2024-07-10\"\n  description: |-\n    We're often taught that test-driven development is all about red-green-refactor. But WHY do we do it that way? And could it be that they way TDD is usually taught is actually misleading, and that there's a different and better way? In this workshop you'll discover a different, easier way to approach test-driven development.\n  video_provider: \"youtube\"\n  video_id: \"I5KnvTttfOM\"\n\n- id: \"vladimir-dementyev-railsconf-2024\"\n  title: \"Workshop: From slow to go: Rails test profiling hands-on\"\n  raw_title: \"RailsConf 2024 - From slow to go: Rails test profiling hands-on by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-08\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Ever wished your Rails test suite to complete faster so you don't waste your time procrastinating while waiting for the green light (or red, who knows—it’s still running)? Have you ever tried increasing the number of parallel workers on CI to solve the problem and reached the limit so there is no noticeable difference anymore?\n\n    If these questions catch your eye, come to my workshop on test profiling and learn how to identify and fix test performance bottlenecks in the most efficient way. And let your CI providers not complain about the lower bills afterward.\n\n    I will guide you through the test profiling upside-down pyramid, from trying to apply common Ruby profilers (Stackprof, Vernier) and learn from flamegrpahs to identifying test-specific performance issues via the TestProf toolbox.\n  video_provider: \"youtube\"\n  video_id: \"PvZw0CnZNPc\"\n\n- id: \"andrew-atkinson-railsconf-2024\"\n  title: \"Workshop: Build High Performance Active Record Apps\"\n  raw_title: \"RailsConf 2024 - Build High Performance Active Record Apps by Andrew Atkinson\"\n  speakers:\n    - Andrew Atkinson\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-08\"\n  published_at: \"2024-07-10\"\n  description: |-\n    In this workshop, you'll learn to leverage powerful Active Record capabilities to bring your applications to the next level. We'll start from scratch and focus on two major areas. We’ll work with high performance queries and we’ll configure and use multiple databases.\n\n    You'll learn how to write efficient queries with good visibility from your Active Record code. You'll use a variety of index types to lower the cost and improve the performance of your queries. You'll use query planner info with Active Record.\n\n    Next we'll shift gears into multi-database application design. You'll introduce a second database instance, set up replication between them, and configure Active Record for writer and reader roles. With that in place, you’ll configure automatic role switching.\n  video_provider: \"youtube\"\n  video_id: \"4SERkjBF-es\"\n\n- id: \"noel-rappin-railsconf-2024\"\n  title: \"Workshop: Let's Extend Rails With A Gem\"\n  raw_title: \"RailsConf 2024 - Let's Extend Rails With A Gem by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-08\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Rails is powerful, but it doesn't do everything. Sometimes you want to build your own tool that adds functionality to Rails. If it's something that might be useful for other people, you can write a Ruby Gem and distribute it. In this workshop, we will go through the entire process of creating a gem, starting with `bundle gem` and ending with how to publish it with `gem push`. Along the way, we'll show how to get started, how to manage configuration, how to be part of Rails configuration, whether you want to be a Rails Engine, and how to test against multiple versions of Rails. After this workshop, you will have all the tools you need to contribute your own gem to the Rails community.\n  video_provider: \"youtube\"\n  video_id: \"eQvwn8p4HnE\"\n\n- id: \"vision-for-inclusion-workshop-railsconf-2024\"\n  title: \"Workshop: Vision for Inclusion\"\n  raw_title: \"RailsConf 2024 - Vision for Inclusion workshop by Todd Sedano\"\n  speakers:\n    - Todd Sedano\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-08\"\n  description: |-\n    Please arrive on time, we will close the workshop after the first 10 minutes.\n\n    This interactive workshop will be centered around real, personal stories from across the industry pertaining to feelings of inclusion or exclusion. Several of the stories describe how discrimination affected the author of the story. The goal is to challenge ourselves to continue to create an inclusive engineering culture. We hope to shine a light on some of the subtle behaviors that can unknowingly lead to others feeling excluded.\n  video_provider: \"not_recorded\"\n  video_id: \"vision-for-inclusion-workshop-railsconf-2024\"\n\n## Day 3\n\n- id: \"jared-norman-railsconf-2024\"\n  title: \"Undervalued: The Most Useful Design Pattern\"\n  raw_title: \"RailsConf 2024 - Undervalued: The Most Useful Design Pattern by Jared Norman\"\n  speakers:\n    - Jared Norman\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Value objects are one of the most useful but underused object-oriented software design patterns. Now that Ruby has first class support for them, let’s explore what we can do with them! Learn not just how and when to use value objects, but also how they can be used to bridge different domains, make your tests faster and more maintainable, and even make your code more performant. I’ll even show how to combine value objects with the factory pattern to create the most useful design pattern out there.\n  video_provider: \"youtube\"\n  video_id: \"4r6D0niRszw\"\n\n- id: \"marco-roth-railsconf-2024\"\n  title: \"Revisiting the Hotwire Landscape after Turbo 8\"\n  raw_title: \"RailsConf 2024 - Revisiting the Hotwire Landscape after Turbo 8 by Marco Roth\"\n  speakers:\n    - Marco Roth\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  slides_url: \"https://speakerdeck.com/marcoroth/revisiting-the-hotwire-landscape-after-turbo-8\"\n  description: |-\n    Hotwire has significantly altered the landscape of building interactive web applications with Ruby on Rails, marking a pivotal evolution toward seamless Full-Stack development.\n\n    With the release of Turbo 8, the ecosystem has gained new momentum, influencing how developers approach application design and interaction.\n\n    This session, led by Marco, a core maintainer of Stimulus, StimulusReflex, and CableReady, delves into capabilities introduced with Turbo 8, reevaluating its impact on the whole Rails and Hotwire ecosystem.\n  video_provider: \"youtube\"\n  video_id: \"eh2joX5n58o\"\n\n- id: \"andy-andrea-railsconf-2024\"\n  title: \"This or that? Similar methods & classes in Ruby && Rails\"\n  raw_title: \"RailsConf 2024 - This or that? Similar methods & classes in Ruby && Rails by Andy Andrea\"\n  speakers:\n    - Andy Andrea\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Working with Ruby and Rails affords access to a wealth of convenience, power and productivity. It also gives us a bunch of similar but distinct ways for checking objects' equality, modeling datetimes, checking strings against regular expressions and accomplishing other common tasks. Sometimes, this leads to confusion; other times, we simply pick one option that works and might miss out something that handles a particular use case better.\n\n    In this talk, we'll take a look at groups of patterns, classes and methods often seen in Rails code that might seem similar or equivalent at first glance. We’ll see how they differ and look at any pros, cons or edge cases worth considering for each group so that we can make more informed decisions when writing our code.\n  video_provider: \"youtube\"\n  video_id: \"tfxJyya6P6A\"\n\n- id: \"alistair-norman-railsconf-2024\"\n  title: \"Pairing with Intention: A Guide for Mentors\"\n  raw_title: \"RailsConf 2024 - Pairing with Intention: A Guide for Mentors by Alistair Norman\"\n  speakers:\n    - Alistair Norman\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Learning as a new developer is difficult and sometimes overwhelming. As mentors, we’re tasked with teaching newer developers everything they need to know. Mentees can struggle to learn when presented with bigger picture concepts like design patterns, testing practices, and complicated application structures along with the details and basic syntax needed to write code all at once. We’ll explore how to be intentional with your pair programming to help your mentee with their desired learning outcomes while keeping them feeling engaged and empowered.\n  video_provider: \"youtube\"\n  video_id: \"aEqMNVbUzew\"\n\n- id: \"john-pollard-railsconf-2024\"\n  title: \"Insights Gained from Developing a Hybrid Application Using Turbo Native and Strada\"\n  raw_title: \"RailsConf 2024 - Insights Gained from Developing a Hybrid Application Using... by John Pollard\"\n  speakers:\n    - John Pollard\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  slides_url: \"https://www.slideshare.net/slideshow/johnpollard-hybrid-app-railsconf2024-pptx/268167413\"\n  description: |-\n    Insights Gained from Developing a Hybrid Application Using Turbo-Native and Strada by John Pollard\n\n    In this session, we delve into the complexities and benefits of hybrid app development with Turbo-Native and Strada. We cover implementation intricacies, emphasizing strategic decisions and technical nuances. Key topics include crafting seamless mobile navigation and integrating native features for enhanced functionality. We also discuss the decision-making process for rendering pages, considering performance, user interaction, and feature complexity. Additionally, we explore creating usable native components that maintain app standards. Join us for practical insights learned from our hybrid app development journey.\n  video_provider: \"youtube\"\n  video_id: \"fi9wytUSAYY\"\n\n- id: \"daniel-colson-railsconf-2024\"\n  title: \"The Very Hungry Transaction\"\n  raw_title: \"RailsConf 2024 - The Very Hungry Transaction by Daniel Colson\"\n  speakers:\n    - Daniel Colson\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  slides_url: \"https://speakerdeck.com/dodecadaniel/the-very-hungry-transaction\"\n  description: |-\n    The story begins with a little database transaction. As the days go by, more and more business requirements cause the transaction to grow in size. We soon discover that it isn't a little transaction anymore, and it now poses a serious risk to our application and business. What went wrong, and how can we fix it?\n\n    In this talk we'll witness a database transaction gradually grow into a liability. We'll uncover some common but problematic patterns that can put our data integrity and database health at risk, and then offer strategies for fixing and preventing these patterns.\n  video_provider: \"youtube\"\n  video_id: \"L1gQL_nw73s\"\n\n- id: \"cody-norman-railsconf-2024\"\n  title: \"Attraction Mailbox - Why I love Action Mailbox\"\n  raw_title: \"RailsConf 2024 - Attraction Mailbox - Why I love Action Mailbox by Cody Norman\"\n  speakers:\n    - Cody Norman\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Email is a powerful and flexible way to extend the capabilities of your Rails application. It’s a familiar and low friction way for users to interact with your app.\n\n    As much as you may want your users to access your app, they may not need to. Email is a great example of focusing on the problem at hand instead of an over-complicated solution.\n\n    We’ll take a deeper look at Action Mailbox and how to route and process your inbound emails.\n  video_provider: \"youtube\"\n  video_id: \"i-RwxAVMP-k\"\n\n- id: \"jol-quenneville-railsconf-2024\"\n  title: \"Dungeons & Dragons & Rails\"\n  raw_title: \"RailsConf 2024 - Dungeons & Dragons & Rails by Joël Quenneville\"\n  speakers:\n    - Joël Quenneville\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  slides_url: \"https://speakerdeck.com/joelq/dungeons-and-dragons-and-rails\"\n  description: |-\n    You’ve found your way through the dungeon, charmed your way past that goblin checkpoint, and even slain a dragon. Now you face your biggest challenge yet - building a digital character sheet in Rails. Normally taking on an interactive beast like this requires a powerful spell like “react” but you’re all out of spell slots. Luckily you found an unlikely weapon in the dragon’s lair. They call it Turbo. Attune to your keyboards and roll for initiative! This task is no match for us!\n  video_provider: \"youtube\"\n  video_id: \"T7GdshXgQZE\"\n\n- id: \"kevin-lesht-railsconf-2024\"\n  title: \"From Request To Response And Everything In Between\"\n  raw_title: \"RailsConf 2024 - From Request To Response And Everything In Between by Kevin Lesht\"\n  speakers:\n    - Kevin Lesht\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    How does a web request make it through a Rails app? And, what happens when a lot of them are coming in, all at once? If you've ever been curious about how requests are handled, or about how to analyze and configure your infrastructure for optimally managing throughput, then this talk is for you!\n\n    In this session, you'll learn about the makeup of an individual web request, how Rails environments can best be setup to handle many requests at once, and how to keep your visitors happy along the way. We'll start by following a single request to its response, and scale all the way up through navigating high traffic scenarios.\n  video_provider: \"youtube\"\n  video_id: \"ExHNp0LGCVs\"\n\n# TODO: missing panel: Ruby Central Board\n\n- id: \"louis-antonopoulos-railsconf-2024\"\n  title: \"Glimpses of Humanity: My Game-Building AI Pair\"\n  raw_title: \"RailsConf 2024 - Glimpses of Humanity: My Game-Building AI Pair by Louis Antonopoulos\"\n  speakers:\n    - Louis Antonopoulos\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    I built a Rails-based game with a partner...an AI partner!\n\n    Come see how I worked with my associate, Atheniel-née-ChatGPT, and everything we achieved.\n\n    Leave with an improved understanding of how to talk to that special machine in your life ❤️❤️❤️ and an increased sense of wonder at how magical an extended machine-human conversation can be.\n\n    I'll be taking you through our entire shared experience, from discovering and iterating on our initial goals, to coming up with a project plan, to developing a working product.\n\n    This is not \"AI wrote a game\" -- this is \"Learn how to pair with an artificial intelligence as if they were a human partner, and push the boundaries of possibility!\"\n  video_provider: \"youtube\"\n  video_id: \"tOhJ-OHmQRs\"\n\n- id: \"stefanni-brasil-railsconf-2024\"\n  title: \"From RSpec to Jest: JavaScript testing for Rails devs\"\n  raw_title: \"RailsConf 2024 - From RSpec to Jest: JavaScript testing for Rails devs by Stefanni Brasil\"\n  speakers:\n    - Stefanni Brasil\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Do you want to write JavaScript tests but feel stuck transferring your testing skills to the JavaScript world? Do you wish that one day you could write JS tests as confidently as you write Ruby tests? If so, this talk is for you.\n    Let’s face it: JavaScript isn’t going anywhere. One way to become more productive is to be confident with writing JavaScript automated tests.\n    Learn how to use Jest, a popular JavaScript testing framework. Let's go through the basics of JavaScript Unit testing with Jest, gotchas, and helpful tips to make your JS testing experience more joyful.\n    By the end of this talk, you’ll have added new skills to your JS tests toolbox. How to set up test data, mock HTTP requests, assert elements in the DOM, and more helpful bites to cover your JavaScript code confidently.\n  video_provider: \"youtube\"\n  video_id: \"9ewZf4gK_Gg\"\n\n- id: \"chantelle-isaacs-railsconf-2024\"\n  title: \"Dungeons and Developers: Uniting Experience Levels in Engineering Teams\"\n  raw_title: \"RailsConf 2024 - Dungeons and Developers: Uniting Experience Levels in... by Chantelle Isaacs\"\n  speakers:\n    - Chantelle Isaacs\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Dungeons and Developers: Uniting Experience Levels in Engineering Teams by Chantelle Isaacs\n\n    Join us in “Dungeons and Developers,” a unique exploration of team dynamics through the lens of Dungeons & Dragons. Discover how the roles and skills in D&D can enlighten the way we build, manage, and nurture diverse engineering teams. Whether you’re a manager aiming to construct a formidable team (Constitution) or an individual seeking to self-assess and advance your career (Charisma), this talk will guide you in leveraging technical and transferable talents. Together we’ll identify your developer archetype and complete a 'Developer Character Sheet'—our tool for highlighting abilities, proficiencies, and alignment in a fun, D&D-inspired format. Developers and managers alike will leave this talk with a newfound appreciation for the varied skills and talents each person brings to the table.\n  video_provider: \"youtube\"\n  video_id: \"NHuJNDB8Dt8\"\n\n- id: \"lightning-talks-part-1-railsconf-2024\"\n  title: \"Lightning Talks Part 1\"\n  raw_title: \"RailsConf 2024 - Lightning Talks Part 1\"\n  speakers:\n    - TODO\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  description: |-\n    A lightning talk is a short presentation (up to 5 mins) on your chosen topic. Talks will take place in 2 time blocks - 45 minutes each with 15 minute break in between. Signups are required for presenting. There will be an announcement on the conference Slack when signups will begin. There will be 18 slots total.\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-part-1-railsconf-2024\"\n\n- id: \"chris-winslett-railsconf-2024\"\n  title: \"Using Postgres + OpenAI to power your AI Recommendation Engine\"\n  raw_title: \"RailsConf 2024 - Using Postgres + OpenAI to power your AI Recommendation... by Chris Winslett\"\n  speakers:\n    - Chris Winslett\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Using Postgres + OpenAI to power your AI Recommendation Engine by Chris Winslett\n\n    Did you know that Postgres can easily power a recommendation engine using data from OpenAI? It's so simple, it will blow your mind.\n\n    For this talk, we will use Rails, ActiveRecord + Postgres, and OpenAI to build a recommendation engine. Then, in the second half, we'll present optimization and scaling techniques because AI data is unique for the scaling needs.\n  video_provider: \"youtube\"\n  video_id: \"eG_vFj5x4Aw\"\n\n- id: \"avi-flombaum-railsconf-2024\"\n  title: \"Progressive Web Apps with Ruby on Rails\"\n  raw_title: \"RailsConf 2024 - Progressive Web Apps with Ruby on Rails by Avi Flombaum\"\n  speakers:\n    - Avi Flombaum\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Progressive Web Apps (PWAs) have emerged as a solution for offering the seamless experience of native apps combined with the reach and accessibility of the web. This talk will dive into building an offline-first RSS feed reader that leverages the full potential of PWAs such as Service Workers, Background Sync,\n\n    We'll explore how to register, install, and activate a service worker in a Rails application.\n\n    We'll delve into the Push API integrated with service workers, discussing how to subscribe users to notifications.\n\n    We'll cover setting up background sync in our service worker, creating a system that automatically updates the cached RSS feeds and articles.\n\n    The talk will not only solidify the concepts discussed but also provide attendees with a clear roadmap to developing their PWAs.\n  video_provider: \"youtube\"\n  video_id: \"g_0OaFreX3U\"\n\n- id: \"dawn-richardson-railsconf-2024\"\n  title: \"Beyond Senior: Lessons From the Technical Career Path\"\n  raw_title: \"RailsConf 2024 - Beyond senior: lessons from the technical career path by  Dawn Richardson\"\n  speakers:\n    - Dawn Richardson\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: |-\n    Staff, principal, distinguished engineer - there is an alternate path to people management if continuing up the \"career ladder\" into technical leadership. As a relatively new 'Principal Engineer', I want to report back on my learnings so far; things I wish I had known before stepping into this role 3 years ago.\n  video_provider: \"youtube\"\n  video_id: \"r7g6XicVZ1c\"\n\n- id: \"lightning-talks-part-2-railsconf-2024\"\n  title: \"Lightning Talks Part 2\"\n  raw_title: \"RailsConf 2024 - Lightning Talks Part 2\"\n  speakers:\n    - TODO\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  description: |-\n    A lightning talk is a short presentation (up to 5 mins) on your chosen topic. Talks will take place in 2 time blocks - 45 minutes each with 15 minute break in between. Signups are required for presenting. There will be an announcement on the conference Slack when signups will begin. There will be 18 slots total.\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-part-2-railsconf-2024\"\n\n- id: \"aaron-patterson-railsconf-2024\"\n  title: \"Closing Keynote\"\n  raw_title: \"RailsConf 2024 - Closing Keynote by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"--0pXVadtII\"\n\n- id: \"ufuk-kayserilioglu-railsconf-2024\"\n  title: \"Day 3 Closing\"\n  raw_title: \"RailsConf 2024 -  Day 3 Closing with Ufuk Kayserilioglu and Andy Croll\"\n  speakers:\n    - Ufuk Kayserilioglu\n    - Andy Croll\n  event_name: \"RailsConf 2024\"\n  date: \"2024-05-09\"\n  published_at: \"2024-07-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"gHANy_j0nEQ\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2025/cfp.yml",
    "content": "---\n- link: \"https://sessionize.com/railsconf-2025\"\n  open_date: \"2025-01-31\"\n  close_date: \"2025-02-28\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2025/event.yml",
    "content": "---\nid: \"PLbHJudTY1K0fOQPBF0uTwFIGuMVEKnV1p\"\ntitle: \"RailsConf 2025\"\nkind: \"conference\"\nlocation: \"Philadelphia, PA, United States\"\ndescription: \"\"\npublished_at: \"2025-07-23\"\nstart_date: \"2025-07-08\"\nend_date: \"2025-07-10\"\nyear: 2025\nbanner_background: \"#FFFFFA\"\nfeatured_background: \"#FFFFFA\"\nfeatured_color: \"#000000\"\nwebsite: \"https://railsconf.org\"\nlast_edition: true\ncoordinates:\n  latitude: 39.957582\n  longitude: -75.166872\n"
  },
  {
    "path": "data/railsconf/railsconf-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users: []\n  organisations:\n    - Ruby Central\n\n- name: \"Co-Chair\"\n  users:\n    - Ufuk Kayserilioglu\n    - Chris Oliver\n\n- name: \"Program Committee member\"\n  users:\n    - Drew Bragg\n    - Bhumi Shah\n    - David Hill\n    - Adrianna Chang\n    - Rosa Gutiérrez\n    - Noel Rappin\n\n- name: \"CFP coach\"\n  users:\n    - Mayra Navarro\n    - Noel Rappin\n    - Brandon Weaver\n\n- name: \"Volunteer\"\n  users: []\n"
  },
  {
    "path": "data/railsconf/railsconf-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby\"\n      description: |-\n        Sponsors who are experts, developers, and community members passionate about Ruby on Rails. They help educate and grow the Rails community by providing financial support, speakers, and other resources.\n      level: 1\n      sponsors:\n        - name: \"Power Home Remodeling\"\n          website: \"https://www.powerhrg.com/\"\n          slug: \"powerhomeremodeling\"\n          logo_url: \"https://railsconf.org/images/uploads/power_logo_navy.png\"\n\n        - name: \"Cisco Meraki\"\n          website: \"https://meraki.cisco.com/\"\n          slug: \"ciscomeraki\"\n          logo_url: \"https://railsconf.org/images/uploads/cisco_logo_blue_2016.svg.png\"\n\n        - name: \"Chime\"\n          website: \"https://www.chime.com/\"\n          slug: \"chime\"\n          logo_url: \"https://railsconf.org/images/uploads/chime.png\"\n\n    - name: \"Platinum\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com/\"\n          slug: \"shopify\"\n          logo_url: \"https://railsconf.org/images/uploads/shopify_logo_black-1.png\"\n\n    - name: \"Gold\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"Gusto\"\n          website: \"https://gusto.com/\"\n          slug: \"gusto\"\n          logo_url: \"https://railsconf.org/images/uploads/gusto-logo_f45d48-1.png\"\n\n        - name: \"Beyond Finance\"\n          website: \"https://www.beyondfinance.com/\"\n          slug: \"beyondfinance\"\n          logo_url: \"https://railsconf.org/images/uploads/600x300_beyond_logo-2-.png\"\n\n    - name: \"Silver\"\n      description: \"\"\n      level: 4\n      sponsors:\n        - name: \"Sentry\"\n          website: \"https://sentry.io/welcome/\"\n          slug: \"sentry\"\n          logo_url: \"https://railsconf.org/images/uploads/sentry-wordmark-dark-400x119.png\"\n\n        - name: \"Planetscale\"\n          website: \"https://planetscale.com/\"\n          slug: \"planetscale\"\n          logo_url: \"https://railsconf.org/images/uploads/pslogo.png\"\n\n        - name: \"PG Analyze\"\n          website: \"https://pganalyze.com/\"\n          slug: \"pganalyze\"\n          logo_url: \"https://railsconf.org/images/uploads/pga_rect_dark.png\"\n\n        - name: \"Persona\"\n          website: \"https://withpersona.com/\"\n          slug: \"persona\"\n          logo_url: \"https://railsconf.org/images/uploads/persona-logo_full-color_light.png\"\n\n        - name: \"Mutations Limited\"\n          website: \"https://mutations.ltd/\"\n          slug: \"mutationslimited\"\n          logo_url: \"https://railsconf.org/images/uploads/ml-logo-rgb-horiz-3x.png\"\n\n        - name: \"Mudflap\"\n          website: \"https://www.mudflapinc.com/\"\n          slug: \"mudflap\"\n          logo_url: \"https://railsconf.org/images/uploads/mudflap_logo_horizontal_fullcolor_rgb_300dpi-14-.png\"\n\n        - name: \"Judoscale\"\n          website: \"https://judoscale.com/\"\n          slug: \"judoscale\"\n          logo_url: \"https://railsconf.org/images/uploads/judoscale-logo-horizontal-color-2x.png\"\n\n        - name: \"JDAQA\"\n          website: \"https://jdaqa.com/\"\n          slug: \"jdaqa\"\n          logo_url: \"https://railsconf.org/images/uploads/logo-2-.svg\"\n\n        - name: \"Honeybadger\"\n          website: \"https://www.honeybadger.io/\"\n          slug: \"honeybadger\"\n          logo_url: \"https://railsconf.org/images/uploads/honeybadger_logo-2024.png\"\n\n        - name: \"FusionAuth\"\n          website: \"https://fusionauth.io/\"\n          slug: \"fusionauth\"\n          logo_url: \"https://railsconf.org/images/uploads/fa_horizontal_text_purple_orange.png\"\n\n        - name: \"Flagrant\"\n          website: \"https://www.beflagrant.com/\"\n          slug: \"flagrant\"\n          logo_url: \"https://railsconf.org/images/uploads/flagrant_logo_horiz_1c_orange_rgb.png\"\n\n        - name: \"CubeSmart\"\n          website: \"https://www.cubesmart.com/\"\n          slug: \"cubesmart\"\n          logo_url: \"https://railsconf.org/images/uploads/cubesmart_vert_red.svg\"\n\n        - name: \"Cedarcode\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"cedarcode\"\n          logo_url: \"https://railsconf.org/images/uploads/cedarcode1003.png\"\n\n    - name: \"Other\"\n      description: \"\"\n      level: 5\n      sponsors:\n        - name: \"typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"typesense\"\n          logo_url: \"https://railsconf.org/images/uploads/typesense-2-.png\"\n\n        - name: \"Sidekiq\"\n          website: \"https://sidekiq.org/\"\n          slug: \"sidekiq\"\n          logo_url: \"https://railsconf.org/images/uploads/sidekiq.png\"\n\n        - name: \"Scout Monitoring\"\n          website: \"https://www.scoutapm.com/\"\n          slug: \"scoutmonitoring\"\n          logo_url: \"https://railsconf.org/images/uploads/orangegradiant.png\"\n\n        - name: \"Go Rails\"\n          website: \"https://gorails.com/\"\n          slug: \"gorails\"\n          logo_url: \"https://railsconf.org/images/uploads/logo.svg\"\n\n        - name: \"Gitlab\"\n          website: \"https://about.gitlab.com/\"\n          slug: \"gitlab\"\n          logo_url: \"https://railsconf.org/images/uploads/gitlab-logo-100.svg\"\n\n        - name: \"FastRuby.io\"\n          website: \"https://www.fastruby.io/\"\n          slug: \"fastruby-io\"\n          logo_url: \"https://railsconf.org/images/uploads/fast-ruby-io-rails-maintenance-services.png\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2025/venue.yml",
    "content": "---\nname: \"Sheraton Philadelphia Downtown\"\n\naddress:\n  street: \"201 N 17th St\"\n  city: \"Philadelphia\"\n  region: \"PA\"\n  postal_code: \"19103\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"201 N 17th St, Philadelphia, PA 19103, United States\"\n\ncoordinates:\n  latitude: 39.957582\n  longitude: -75.166872\n\nmaps:\n  apple:\n    \"https://maps.apple.com/place?address=201%20N%2017th%20St,%20Philadelphia,%20PA%20%2019103,%20United%20States&coordinate=39.957229,-75.166998&name=Sheraton%20Philadelphia%2\\\n    0Downtown&place-id=I1B5386B3F741F78A&map=transit\"\n\nhotels:\n  - name: \"Sheraton Philadelphia Downtown\"\n    kind: \"Conference Hotel\"\n    address:\n      street: \"201 North 17th Street\"\n      city: \"Philadelphia\"\n      region: \"Pennsylvania\"\n      postal_code: \"19103\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"201 N 17th St, Philadelphia, PA 19103, United States\"\n    coordinates:\n      latitude: 39.957582\n      longitude: -75.166872\n    maps:\n      apple:\n        \"https://maps.apple.com/place?address=201%20N%2017th%20St,%20Philadelphia,%20PA%20%2019103,%20United%20States&coordinate=39.957229,-75.166998&name=Sheraton%20Philadelphia%2\\\n        0Downtown&place-id=I1B5386B3F741F78A&map=transit\"\n"
  },
  {
    "path": "data/railsconf/railsconf-2025/videos.yml",
    "content": "---\n- id: \"shan-cureton-railsconf-2025\"\n  title: \"Opening Ceremony\"\n  raw_title: \"Opening Ceremony with Shan Cureton\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    We welcome all of you to RailsConf 2025 and to Philadelphia! We are so excited to celebrate together the stories of Ruby on Rails and RailsConf through the ages. Join us in kicking off our event together!\n\n    Sponsor welcomes from Cisco Meraki and Power Home Remodeling. Also hear Chris Oliver and Ufuk Kayserilioglu talk about how the event will run for the day.\n  speakers:\n    - Shan Cureton\n    - Marty Haught\n    - Rhiannon Payne\n    - Ally Vogel\n    - Tom Chambers\n    - Samuel Giddins\n    - Diesha Cooper\n    - Alan Ridlehoover\n    - Fito von Zastrow\n    - Jenny Gray\n    - Chris Oliver\n    - Ufuk Kayserilioglu\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  video_provider: \"youtube\"\n  video_id: \"vG3v_FHcbSE\"\n\n- title: \"Keynote: 365 Days Later: Moving From Java To RoR And How It Changed Everything\"\n  raw_title: \"365 Days Later: Moving From Java To RoR And How It Changed Everything\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Last year at RailsConf Detroit, keynote speaker Irina Nasarova announced that Flexcar was launching on Rails that very day— in the middle of the conference. Now, one year later, I’m here to share the full story of how that transition unfolded, how things played out, and what life has been like for us after a full year on Ruby on Rails.\n\n    Flexcar made the bold decision to move from a Java-based architecture with 80 micro-services to a monolithic Ruby on Rails application in just four months. While this transition would have been aggressive to do in four months with an experienced Rails team, our team was brand new to RoR. This shift has had far-reaching effects—not just on our tech stack, but on our workflow, team dynamics, and company culture.\n\n    In this talk, I’ll take you through our journey, sharing lessons learned, challenges we overcame, and what I wish I had known before embarking on this path. We’ll dive into how the transition affected our development process, how we gained company-wide support, and the unexpected successes (and a few surprises) that came after the launch.\n\n    If you’re an engineering leader considering a similar move or a switch to Ruby on Rails, you’ll leave this session with:\n\n    - Insights into managing a successful tech stack migration and avoiding common pitfalls\n    - Strategies for securing buy-in from leadership, product, and support teams\n    - How the shift to Rails reshaped our team, processes, and products\n\n    Join me for a candid reflection on a year of change, growth, and lessons learned, and take away actionable tips to ensure your own transition is as smooth and successful as possible.\n  speakers:\n    - John Dewsnap\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  announced_at: \"2025-05-07 14:00:00 UTC\"\n  track: \"Main Stage - Liberty\"\n  id: \"keynote-day-1-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"vOweZ0vFcVk\"\n\n- title: \"Startups on Rails in Past, Present and Future\"\n  raw_title: \"Startups on Rails in Past, Present and Future\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    In 2025 Ruby on Rails continues to power successful startups: during the last 12 months one of them became the leading AI-powered app builder, another raised $150M, and another filed for IPO. But let’s put things into perspective and explore how the essence of Rails’ appeal to founders since the beginning and into the future.\n\n    We'll journey through Rails history with pivotal stories from Intercom, Gusto, and Y Combinator - companies that leveraged Rails' productivity to achieve remarkable growth. These legendary examples demonstrate which aspects of Rails and its ecosystem were key for bringing products to market and sustaining explosive growth.\n\n    Then we'll celebrate recent Rails success stories—such as Bolt.new, Whop, Chime and Uscreen—examining the tremendous success these startups have posted recently. We'll explore the key factors behind Rails' resurgence among founders who are choosing the framework in recent years, including Hotwire, Inertia, Kamal and more.\n\n    Finally, we'll take these learnings and look into the future by identifying what we can all do to ensure Rails continues being the choice for tomorrow's entrepreneurs. We'll discuss tooling, open source, educational resources, and community voices that could catalyze even more startup success stories on Rails.\n  speakers:\n    - Irina Nazarova\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"irina-nazarova-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"iB0J7nNMapc\"\n  slides_url: \"https://speakerdeck.com/irinanazarova/startups-on-rails-in-past-present-and-future-irina-nazarova-railsconf-2025\"\n\n- title: \"Development Speed Optimizations in Rails 8\"\n  raw_title: \"Development Speed Optimizations in Rails 8\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    The release of Rails 8 included several speed optimizations for development, especially for larger applications. Let’s talk about what they are, and why they matter. In this talk, you’ll learn about why the Rails boot process is so important, and the changes my team and I made to initializers, file watching, and route drawing.\n  speakers:\n    - Gannon McGibbon\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"gannon-mcgibbon-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"I4PqCz3P4tk\"\n\n- title: \"Derailing Our Application: How and Why We Are Decoupling Our Code from Rails\"\n  raw_title: \"Derailing Our Application: How and Why We Are Decoupling Our Code from Rails\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Cisco Meraki is probably the largest Rails shop you’ve never heard of. Our 2 million line Rails monolith has been under continuous development since 2007. As with any large codebase, ours is not without challenges. In “Derailing Our Application,” we share how our architecture has evolved to decouple 800,000 lines of Ruby code from Rails constructs in order to enable us to scale our team to 1,000 engineers and beyond without losing the benefits of Rails. Join us on the track less traveled! All aboard!\n  speakers:\n    - Fito von Zastrow\n    - Alan Ridlehoover\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  id: \"fito-von-zastrow-alan-ridlehoover-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"iXFGy5R39ds\"\n  slides_url: \"https://speakerdeck.com/aridlehoover/derailing-our-application-how-and-why-we-are-decoupling-ourselves-from-rails\"\n\n- title: \"Yes, You Can Work on Rails & any other Gem\"\n  raw_title: \"Yes, You Can Work on Rails & any other Gem\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Have you ever wanted to dig into the Rails source, but it just seems too daunting?\n\n    Good news! In this session, we'll look at practical tools to level you up, so you can make it happen. Even better, these navigation tools work for any gem & your day-to-day codebase too.\n\n    We'll use live demos to engage with real code from gems & Rails. We'll improve our ability to sight-read code & identify patterns within swiftly. You'll see how to refine your learning process so it yields compounding results to make you a better developer & teammate.\n  speakers:\n    - Kasper Timm Hansen\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"kasper-timm-hansen-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"g1mfTukK79s\"\n  slides_url: \"https://speakerdeck.com/kaspth/yes-you-can-work-on-rails-and-any-other-gem\"\n\n- title: \"The Ghosts of Action View Cache\"\n  raw_title: \"The Ghosts of Action View Cache\"\n  event_name: \"RailsConf 2025\"\n  description: |\n    It's Railsconf Eve and you're trying to sleep, but you keep being awoken by ghosts trying to tell you about Action View! You're taken to the past, where you learn about Russian Doll Caching. You're shown the present, where brand new tools are built on Action View's foundations. And finally you're shown the future, where Rails applications are more powerful than ever.\n\n    Through this journey, you’ll gain a deep understanding of Action View and how its primitives can help you solve a wide range of problems. Whether you’re optimizing an existing app or building the future of Rails, you’ll leave knowing how to make your views faster, leaner, and more maintainable.\n  speakers:\n    - Hartley McGuire\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"hartley-mcguire-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"fKCLUe-hnJ8\"\n\n- title: \"Rails Frontend Evolution: It Was a Setup All Along\"\n  raw_title: \"Rails Frontend Evolution: It Was a Setup All Along\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Remember when Rails dominated the frontend, then seemingly retreated to API-only mode? Plot twist: that wasn't Rails giving up—it was setting the stage for a triumphant return.\n\n    This talk traces Rails' frontend journey from its revolutionary MVC beginnings through the Asset Pipeline glory days and the Webpacker wilderness, revealing how each phase was actually building toward today's renaissance. While we were lamenting Rails' frontend \"decline\", frontend frameworks themselves began reinventing server-side rendering and fullstack ideas—essentially rediscovering what Rails knew all along.\n\n    Now we've come full circle with Hotwire's elegant HTML-over-the-wire approach and Inertia.js bridging modern JavaScript frameworks with Rails conventions. What looked like Rails losing the frontend battle was actually a strategic retreat before a decisive counterattack.\n\n    Join us to explore how Rails' frontend evolution was never about abandonment but patient reinvention—and how its \"setup\" has positioned it perfectly for the future of web development.\n  speakers:\n    - Svyatoslav Kryukov\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"svyatoslav-kryukov-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"WcmGZIGEGSY\"\n  slides_url: \"https://speakerdeck.com/skryukov/rails-frontend-evolution-it-was-a-setup-all-along\"\n\n- title: \"Cache = Cash! 2.0\"\n  raw_title: \"Cache = Cash! 2.0\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Back in 2013, I gave a talk at RailsConf titled \"Cache = Cash!\", where I explored how caching can dramatically improve Rails performance. A decade later, caching has only become more powerful — but also more dangerous. In this updated session, we’ll go beyond the official Rails documentation and explore advanced caching techniques that can significantly boost performance — if used wisely.\n\n    Start with the Basics: Rails Caching 101\n\n    To make sure everyone can follow along, we’ll begin with a clear introduction to Rails' built-in caching strategies, including:\n\n    - Fragment Caching – Storing reusable view fragments to speed up rendering.\n    - Russian Doll Caching – Nesting caches effectively to prevent unnecessary recomputation.\n    - Low-Level Caching (Rails.cache) – Directly caching arbitrary data for optimized reads.\n    - SQL Query Caching – Reducing database load by storing query results efficiently.\n    - Cache Store Options – Choosing between memory store, file store, Memcached, and Redis.\n\n    This will give attendees — even those with no prior caching experience — a solid foundation before we dive into the advanced techniques that aren’t covered in the official Rails guides.\n\n    The Closer, the Faster: Understanding Cache Hierarchies 🚀\n\n    Not all caches are created equal! The further away your data is stored, the slower your application becomes. If you want truly high-performance caching, you need to understand where to cache data and how access speeds compare.\n\n    Here's how different caches stack up in terms of access speed:\n\n    - L1 Cache (CPU Internal Cache) → ~1 nanosecond\n    L2/L3 Cache → ~3–10 nanoseconds\n    - RAM (Memory Access) → ~100 nanoseconds\n    - SSD (Local Disk Cache) → ~100 microseconds (1000× slower than RAM!)\n    - Network Call (e.g., Redis, Database Query) → ~1–10 milliseconds\n    - Spinning Disk (HDD Cache Access) → ~10 milliseconds\n\n    That’s a 10-million-fold difference between CPU cache and an HDD!\n\n    Practical Takeaways\n\n    ✅ Cache as close to the CPU as possible – Learn how to use in-memory caches and CPU-friendly data structures.\n    ✅ Optimize ActiveRecord for caching efficiency – Instead of always caching full ActiveRecord objects, consider caching only essential attributes as JSON, arrays, or hashes. This reduces deserialization overhead and keeps frequently accessed data lightweight.\n    ✅ Minimize unnecessary cache retrievals – Just because Redis is fast doesn’t mean it’s the right cache for every scenario. Consider database-level caching via materialized views or denormalized tables when appropriate.\n    ✅ Leverage cache preloading and warming – Reduce performance bottlenecks by anticipating cache misses before they happen.\n\n    When Caching Goes Wrong: Debugging and Avoiding Traps\n\n    Caching is powerful, but it can turn into a nightmare if you don’t handle it properly. We’ll cover:\n\n    - Cache Invalidation Challenges – “There are only two hard things in computer science: naming things, and cache invalidation.” Learn how to keep caches fresh without unnecessary complexity.\n    - Debugging Stale Data Issues – Identify and resolve issues caused by outdated or inconsistent cache entries.\n    - Knowing When NOT to Cache – Some things shouldn’t be cached! Learn when AI-driven caching decisions (or even Rails defaults) might cause more harm than good.\n\n    What You’ll Walk Away With\n\n    - A solid understanding of Rails caching fundamentals — perfect for beginners.\n    - Advanced caching techniques that go beyond the Rails guides.\n    - Performance insights on CPU, memory, and distributed caches.\n    - A clear strategy for debugging and maintaining cache integrity.\n\n    A decade ago, \"Cache = Cash!\" was all about making Rails apps faster and more efficient. This time, we’re taking it even further — with new techniques, new pitfalls, and even bigger performance gains.\n\n    Are you ready to push Rails caching to the next level?\n  speakers:\n    - Stefan Wintermeyer\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"stefan-wintermeyer-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"MVHfdblm7uU\"\n  slides_url: \"https://speakerdeck.com/wintermeyer/cache-equals-cash-2-dot-0\"\n\n- title: \"Evolution of Rails within RubyGems.org\"\n  raw_title: \"Evolution of Rails within RubyGems.org\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    As a 16 year old open source Rails app, Rubygems.org can tell a story of how building and maintaining a Rails app has changed over the years.  Join us as we progress from its creation in 2009 until today, exploring how things have changed and what we've learned. We dig into deploying, handling gem dependencies, background processing, web servers, security, and the frontend approaches.  We'll wrap up with our thoughts on the future of security and compliance.\n  speakers:\n    - Samuel Giddins\n    - Nick Quaranto\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"samuel-giddins-nick-quaranto-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"LdRRGacycME\"\n  slides_url: \"https://speakerdeck.com/segiddins/evolution-of-rails-within-rubygems-dot-org\"\n\n- title: \"Understanding Ruby Web Server Internals: Puma, Falcon, and Pitchfork Compared\"\n  raw_title: \"Understanding Ruby Web Server Internals: Puma, Falcon, and Pitchfork Compared\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    As Ruby developers, we often focus on our application code, but the choice of web server can significantly impact performance, scalability, and resource efficiency.\n\n    In this talk, we’ll explore Puma, Falcon, and Pitchfork - three modern Ruby web servers with distinct execution models. We’ll cover:\n\n    * How pre-forking and copy-on-write help in minimizing boot time and memory usage.\n    * How Falcon eliminates the traditional challenges of blocking I/O in Ruby, enabling new approaches to IO bound workloads\n    * Why Puma’s hybrid model balances concurrency, performance, and memory usage.\n    * How Pitchfork optimizes for latency and memory efficiency and why it’s a good choice for CPU-bound applications.\n\n    By the end, you’ll understand how to choose, tune, and optimize your web server for your specific use case\n  speakers:\n    - Manu Janardhanan\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"manu-janardhanan-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"gLYx83CaCNw\"\n\n- title: \"Keeping the Rails Magic Alive After 18 Years\"\n  raw_title: \"Keeping the Rails Magic Alive After 18 Years\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Hear from someone who wrote the first line of code for a Rails app started in 2007 that's over 3 million lines of code today. Learn from our journey migrating to a Component Based Rails Application (CBRA) and tools we've open sourced along the way which you may not have heard about, but can help with any Rails application.\n\n    Our mantra is Build vs Buy. Learn what that means and if it makes sense for you. We've built our own messenger app, telephony services, support ticket system, project management software, and other apps. Why would we build stuff rather than buy or subscribe to existing apps? We even built our own cloud. I'll explain the experiences that set us on that path.\n\n    Our ongoing journey towards a Component Based Rails Application (CBRA). An application of fully gem/engine-based components. I'll discuss lessons learned and why we persist with CBRA when everyone else with a Rails monolith app is going with Packwerk.\n\n    Open source tools we've built and how they can help any Rails application. We have a number of public gems and tools like cobra_commander, which helps manage Component Based Rails apps, power-tools, a collection of utility gems useful in any Rails app, and, last but not least, our Playbook Design System which is full design system for Rails, Swift, and React. RailConf will be the first place we've ever talked about these publicly.\n    At the end, hopefully attendees walk out more confident in choosing Rails for the long haul, armed with knowledge and tools that helped our company go big and keep up with the scale of our growth.\n  speakers:\n    - Wade Winningham\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  id: \"wade-winningham-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"HyDTDCxuWg4\"\n  slides_url: \"https://filedn.com/lmbFhCqwqzsklDbehoQDnr5/RailsConf2025/WadeWinningham_KeepingTheRailsMagicAliveAfter18Years.pdf\"\n\n- title: \"Master the Rails Asset Pipeline: Best Practices for Apps & Gems\"\n  raw_title: \"Master the Rails Asset Pipeline: Best Practices for Apps & Gems\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    We've all faced it - asset pipeline issues blocking that Friday deploy. From mysterious JavaScript loads to incorrect asset paths in your gems, these roadblocks are frustrating. Learn to master Rails assets from development to production, with practical tips for managing all asset types. Walk away with debugging techniques and optimization strategies you can apply instantly to your apps and gems.\n\n    ---\n\n    Asset management (JS and CSS) is not easy.\n    Rails' docs are full of jargon and expect the reader to know a lot about JS and how the browser works.\n    This leads to not understanding the different bits and pieces of the asset pipeline.\n    \"Is it just one?\", \"What is Sprockets\", \"Is Propshaft enough?\", \"Is my app locked if I used Webpacker in the past?\", \"Is Vite bad for my app?\"\n    These are some of the questions that pop up in people's heads lately and there's a bit hesitation of upgrading based on all this missed knowledge.\n    When we start talking about outside gems that need to ship external assets, there's a whole other can of worms. There's no documented way of doing it, developers duplicate dependencies (37signals included), and there's no silver bullet.\n\n    In my talk I'm going to touch on:\n    - what is the DOM and how the browser loads and runs JS\n    - what is the `defer` argument\n    - bundling vs not bundling\n    - what is this whole \"Asset Pipeline\" and the various bits and pieces\n    - the current modern alternatives (js-bundling, importmaps, Vite)\n    - how to ship assets in gems. I'm going to present three ways with their pros and cons\n\n    The talk will have snippets (with gists attached for future reference) and sample repos for the viewers' reference.\n    It's going to be technical but guided so the viewers will have a good progression of understanding.\n  speakers:\n    - Adrian Marin\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"adrian-marin-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"jPsz-cPo7Wc\"\n\n- title: \"Ruby Internals: A Guide For Rails Developers\"\n  raw_title: \"Ruby Internals: A Guide For Rails Developers\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Ever wondered how Ruby takes your code and runs it? It’s time to go on a journey into Ruby internals designed especially for Rails developers! We’ll learn about all the parts of an interpreter, and how their inner-workings affect our Rails apps! No experience with C is required!\n  speakers:\n    - Matheus Richard\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"matheus-richard-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"ozayFBNKO2M\"\n\n- title: \"The Rails Features We Loved, Lost, and Laughed At\"\n  raw_title: \"The Rails Features We Loved, Lost, and Laughed At\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Rails has always moved fast. Sometimes too fast. It gave us bold ideas, best practices that weren't, and features that felt like magic – until they didn't.\n\n    Before database migrations, SQL changes were a manual mess. Before REST, routing conventions were a free-for-all. Before AJAX, entire pages refreshed just to update a single field. Some features transformed how we build apps. Others were left at the station. A few refuse to stay gone.\n\n    This session takes a fast-paced, slightly irreverent ride through the features that shaped Rails, the ones we hyped up only to abandon, and the ones that just won't quit. Rails keeps moving forward, but history has a way of repeating itself. Let's see what we can learn from the features we built, broke, and buried.\n\n    Some ideas never left the station. Others keep coming back for another ride. See you onboard. 🚂\n  speakers:\n    - Robby Russell\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"robby-russell-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"sjvsBvugcf4\"\n\n- title: \"10 Costly Database Performance Mistakes (and How to Fix Them)\"\n  raw_title: \"10 Costly Database Performance Mistakes (and How to Fix Them)\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    After working with countless Rails and Postgres applications as a consultant and backend engineer, I’ve seen firsthand how database mistakes can cause big costs and headaches. Poor data types, inefficient queries, and flawed schema designs slow down operations, and result in excessive costs through over-provisioned servers, downtime, lost users, and engineering hours spent restructuring features.\n\n    How do we prevent these pitfalls? Awareness is the first step. And if your database is already serving tons of woefully inefficient queries, where should you focus for the biggest wins?\n\n    In this talk, we'll break down 10 real-world Rails database mistakes, including how they happened, the impact they had, and most importantly, how to fix them. Topics include query design, indexing, schema optimization, and how the CPU, memory, and IOPS resources tie into Active Record SQL performance.\n\n    Expect practical takeaways, real examples, and solutions you can apply immediately. Slides and blog posts will be available at GitHub.\n  speakers:\n    - Andrew Atkinson\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"andrew-atkinson-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"MJ8RGExUp-s\"\n\n- title: \"Fireside Chat With David Heinemeier Hansson\"\n  raw_title: \"Fireside Chat With David Heinemeier Hansson\"\n  event_name: \"RailsConf 2025\"\n  description: \"\"\n  speakers:\n    - David Heinemeier Hansson\n    - Elise Shaffer\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  announced_at: \"2025-05-28 14:25:00 UTC\"\n  track: \"Main Stage - Liberty\"\n  id: \"closing-keynote-day-1-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"lVVnC6n-v-M\"\n\n- title: \"Panel: Rails Then, Now, And Next: A Conversation With Our Community\"\n  raw_title: \"Rails Then, Now, And Next: A Conversation With Our Community\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Rails has been evolving for over two decades, shaping the modern web development landscape while fostering one of the most passionate and tight-knit communities in tech. This panel brings together influential voices from different eras of Rails to reflect on its past, discuss its present, and envision its future.\n\n    Join us for a lively, insightful conversation with seasoned contributors and community leaders as we explore:\n\n    How Rails has changed over the years—both technically and culturally\n    Pivotal moments in the framework’s history and lessons learned\n    The current state of Rails and its place in the modern web ecosystem\n    What’s next for Rails and how we, as a community, can shape its future\n    Whether you’re a long-time Rails developer or just starting your journey, this panel offers valuable perspectives and stories from those who have helped shape the framework and its community.\n\n    Some Potential Curated Questions:\n\n    Past:\n    - What drew you to Rails initially, and what kept you engaged?\n    - What were some of the most defining moments in Rails history?\n    - What lessons can newer developers learn from the early days of Rails?\n    - What is your favorite memory from RailsConf?\n\n    Present:\n    - What excites you most about Rails today?\n    - How has the community evolved over the years?\n    - What are the biggest challenges Rails developers face in today’s tech landscape?\n\n    Future:\n    - Where do you see Rails in the next 5–10 years?\n    - What should the Rails community focus on to ensure long-term sustainability?\n    - How can we make Rails an even more welcoming and innovative space?\n\n    Format & Audience Engagement:\n    - 60-minute panel discussion with a moderator guiding the conversation\n    - 10-15 minutes reserved for audience Q&A\n    - Interactive Slido or similar tool to collect questions in real time\n\n    This panel is designed to be both reflective and forward-looking, offering insights for developers at all levels. It will provide a rare opportunity to hear directly from those who have shaped Rails, making it a must-attend session for anyone invested in its future.\n  speakers:\n    - Aaron Patterson\n    - Sarah Mei\n    - Evan Phoenix\n    - Nadia Odunayo\n    - Chad Fowler\n    - Eileen M. Uchitelle\n    - Marty Haught\n  date: \"2025-07-09\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"keynote-day-2-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"JLPPHX6khbo\"\n\n- title: \"Workshop: Hotwire Native - A Rails developer’s secret tool to building mobile apps\"\n  raw_title: \"Hotwire Native: A Rails developer’s secret tool to building mobile apps\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Building native mobile apps is time-consuming and expensive. Each screen must be built three times: once for web, again for iOS, and a third time for Android.\n\n    But with Hotwire Native you only need to build your screens once, in HTML and CSS, and then reuse them across all three platforms. If you already have a Hotwire-enabled Rails app, you can use the screens you've already built!\n\n    And you don't need to be an expert in Swift or Kotlin. A thin wrapper for each platform enables continuous updates by only making changes to your Rails codebase. Deploy your code and all three platforms get your changes immediately.\n\n    Join me as I build iOS and Android apps from scratch, live. Learn the essentials, practical tips, and common pitfalls I’ve picked up since working with Hotwire Native since 2016.\n  speakers:\n    - Joe Masilotti\n  date: \"2025-07-09\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"joe-masilotti-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"gIOkC44_dA8\"\n\n- id: \"stephanie-minn-railsconf-2025\"\n  title: \"Workshop: What can we do together? A facilitated community-building workshop\"\n  raw_title: \"What can we do together? A facilitated community-building workshop\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Community is one of the best parts of attending in-person conferences. But meeting people and socializing can be daunting. Maybe you want to join a conversation in the hallway but can’t break into the impenetrable group circle. Perhaps it’s your first conference, and everyone seems to already know each other. Or you might be looking for collaborators in a particular Rails subject matter and don’t seem to know where to find them.\n\n    For the very last RailsConf, join this guided interactive workshop to make the meaningful connections you’re seeking. We’ll learn about each other, reflect on ways to find and offer support, and leave with a more resilient network to enter the next phase of our community, together.\n  speakers:\n    - Stephanie Minn\n  date: \"2025-07-09\"\n  track: \"Breakout 2 - Freedom\"\n  video_provider: \"scheduled\"\n  video_id: \"stephanie-minn-railsconf-2025\"\n\n- title: \"Workshop: How to instrument your Rails app with OpenTelemetry\"\n  raw_title: \"How to instrument your Rails app with OpenTelemetry\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Join an OpenTelemetry maintainer to learn how to instrument your Rails application with this growing open source project. We'll cover the basics of observability and the benefits you can receive from each of OpenTelemetry's three core signals: Traces, Metrics, and Logs. We'll talk about Active Support Notifications and how OpenTelemetry leverages them for automatic instrumentation, as well as the instrumentation strategies in other popular Rails-related libraries. Together, we'll configure the OpenTelemetry SDK in a minimal Rails application, add custom instrumentation to core methods within our application, and export the results to an observability backend.\n  speakers:\n    - Kayla Reopelle\n  date: \"2025-07-09\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"kayla-reopelle-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"iF1q1dns840\"\n\n- title: \"Panel: Ruby Podcast\"\n  raw_title: \"Ruby Podcast Panel\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    The Ruby Podcast Panel will feature a collection of Rubyists with active podcasts, engaging in conversation about Ruby, Rails, and the community that has grown up around our favorite tech stack.\n  speakers:\n    - David Hill\n    - Drew Bragg\n    - Chris Oliver\n    - Stephanie Minn\n  date: \"2025-07-09\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  id: \"ruby-podcast-panel-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"0VO8bYkeUUg\"\n\n- title: \"Panel: The Past, Present and Future of Background Jobs\"\n  raw_title: \"The Past, Present and Future of Background Jobs according to Mike, Rosa, Maciej, and Ben\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Join a discussion between Sidekiq’s Mike Perham, Solid Queue’s Rosa Gutiérrez, Karafka and Shoryuken’s Maciej Mensfeld, and GoodJob’s Ben Sheldon.\n\n    This panel hosts the maintainers of the four most well-known Active Job backends. They’ll discuss and reflect on their different approaches, philosophies, capabilities, and challenges to powering background jobs and integrating with Active Job.\n\n    The discussion will cover a range of topics including performance, feature-sets, support, commercialization, regrets, visions of the future, questions from the audience, and more!\n  speakers:\n    - Ben Sheldon\n    - Mike Perham\n    - Rosa Gutierrez\n    - Maciej Mensfeld\n  date: \"2025-07-09\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  id: \"background-jobs-panel-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"xf5mrEu5190\"\n\n- title: \"Keynote: The Keynote of Keynotes\"\n  raw_title: \"The Keynote of Keynotes\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Nearly 20 years of RailsConf, nearly 20 years of RailsConf talks and workshops, nearly 20 years of RailsConf keynotes. Talks that loom a little larger than the typical session, that leave behind more of an impact, that have kept us thinking over the years.\n\n    Have you attended every RailsConf?\n\n    That's the only way you could have walked away with nearly 20 years of wisdom and learning from RailsConf keynotes.\n\n    ...until now.\n  speakers:\n    - Christopher \"Aji\" Slater\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"aji-slater-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"T-lqK2SR8vk\"\n\n- title: \"How 10 years of RailsConfs can inform the next 10 years of your career\"\n  raw_title: \"How 10 years of RailsConfs can inform the next 10 years of your career\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    RailsConf has played an important role in my professional and personal life. I've learned about technology in ways I wouldn't have otherwise at RailsConf. I've learned about myself in ways I wouldn't have otherwise thanks to RailsConf. I've met people that changed the course of my career thanks to RailsConf. I've met others who have become dear friends thanks to RailsConf. I've done things I've never done before thanks to RailsConf.\n\n    The same may be true for you. We should celebrate and reflect on that. Where do we go from here? Let's talk about it together.\n  speakers:\n    - Kevin Murphy\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"kevin-murphy-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"2WkBHoGAlpY\"\n  slides_url: \"https://speakerdeck.com/kevinmurphy/how-10-years-of-railsconfs-can-inform-the-next-10-years-of-your-career\"\n\n- title: \"The Front-end is Omakase\"\n  raw_title: \"The Front-end is Omakase\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    \"Rails is omakase.\" DHH's classic 2012 blog post is still great reading in 2025. Here's a quote from the article that sums up his main point:\n\n    \"A team of chefs picked out the ingredients, designed the APIs, and arranged the order of consumption on your behalf according to their idea of what would make for a tasty full-stack framework.\"\n\n    Right! And we have all benefitted enormously from the Rails core team sharing those tastes with the rest of us. The ingredients and API design decisions he's referring to fit the shape of a great deal of the web applications we might want to build. Just as we trust the omakase chef to serve a great unagi and sake pairing, we lean on the years of industry experience baked into Rails to build web applications with fewer resources.\n\n    If Rails and the Rails philosophy are omakase, the front-end world is the opposite: \"okonomi,\" meaning \"choosing what to order.\" Rather than picking a set of technologies, smart defaults, and conventions on your behalf, most front-end frameworks and tools expect the developer to cobble together a bunch of tools that were not necessarily designed to work with one another. The decision points are endless: Typescript or Javascript? Vite, webpack, or importmaps? SASS or Less? PostCSS or dart-sass? Tailwind, Bootstrap, or Bulma? BEM, SMACSS, OOCSS, CUBE, or HECS? Maybe CSS modules? And what about React, Vue, Angular, Svelte, or HTMX? The list goes on and on.\n\n    For understandable reasons, Rails has gradually retracted its opinions around front-end development over the last 10 years. In practice this has meant the Rails front-end is much less omakase and much more okonomi than the rest of the framework. Need a Javascript bundler? Bring your own. Want to use Typescript? Configure it yourself. While at first glance the high degree of flexibility might seem freeing, it's quite contrary to how Rails was originally designed. As Leonardo Da Vinci said, \"Art lives from constraints and dies from freedom.\" The constraints Rails places on its developers are, somewhat counterintuitively, the same things that make it such a productive framework.\n\n    In my opinion, Rails needs an omakase front-end. We need a set of strong front-end opinions like we have on the back-end.\n\n    During my talk, I'd like to share my opinions for configuring the front-end of a Rails application, and provide a look at the libraries, configurations, and tools I've found to be the most productive. The talk will include a brief history of front-end tooling in Rails, what we've learned along the way, and what a more opinionated future could look like. I'll introduce a Rails generator I'm working on that configures a fully-baked and opinionated front-end setup - like Jumpstart or Bullet Train, but specifically for the front-end. I'd like to finish up by touching on future innovations like rendering ViewComponents in the browser.\n\n    So, why am I qualified to give this talk? I work on an open-source design system for a large company that runs a number of complex Rails apps. I've been around for most of the big front-end shifts in Rails, including the introduction of the asset pipeline, CoffeeScript, webpacker, and now js/cssbundling, importmaps, and ViewComponent. I've written code using all of these tools, and now my design systems work is giving me an even broader look at the front-end ecosystem. I recently re-wrote the documentation for getting started with our gems and Javascript packages, including a guide for adding it to a Rails app. I wanted to be thorough, so I covered configuring every tool supported by cssbundling-rails and jsbundling-rails, as well as Sprockets, vite, and importmaps. It was... a lot. Imagine how overwhelming all these choices must be for a beginner coming to Rails for the first time. Hell, I barely have a handle them, and I've been in the industry for 15 years.\n  speakers:\n    - Cameron Dutro\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"cameron-dutro-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"4deGaTJ-t14\"\n  slides_url: \"https://speakerdeck.com/camertron/the-front-end-is-omakase\"\n\n- title: \"The future of Rails begins in the browser\"\n  raw_title: \"The future of Rails begins in the browser\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    With a mature community and adoption by prominent tech veterans, Ruby on Rails already has a strong foundation, and these elements define both the present state of the framework, as well as its short-term future. But the long-term future of the framework is an equation that will depend heavily on the opposite end of the equation: namely, the newcomers, those who will take their first steps on Rails.\n\n    But will those first steps look like? Imagine being able to learn and play with Rails without the need to deal with installations or development environments. What if the next generation of Rails developers could start using something easily accessible to everyone: the browser!\n    Sounds like science fiction? Hardly! The fact is, interactive web-based tutorials, learning materials, and playgrounds play a critical role in wider technology adoption. We’re certain this is the future–and Rails must be a part of that future.\n\n    Join us on our journey to bring the “Getting Started with Rails” experience right into your browser. We’ll do this with the help of some new technologies: WebAssembly, WebContainers and in-browser databases!\n  speakers:\n    - Vladimir Dementyev\n    - Albert Pazderin\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"vladimir-dementyev-albert-pazderin-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"S_NKftfM1T4\"\n  slides_url: \"https://speakerdeck.com/aface/the-future-of-rails-begins-in-the-browser\"\n\n- title: \"Not Invented Here: Things Rails Didn't Innovate\"\n  raw_title: \"Not Invented Here: Things Rails Didn't Innovate\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Rails is a mixture of design patterns, practices, and magic. In this talk, we'll explore how Rails embraces ideas from other frameworks and projects.\n\n    Active Record was born of Martin Fowler. MVC was the brainchild of Trygve Reenskaug. Rails 3 completely absorbed the Merb project, gaining modularity and extensibility that it previously lacked.\n\n    We all learn by standing on the shoulders of giants, even Rails. By understanding the inception of design patterns, we are more likely to be able to create ideas of our own. This helps us to not only grow in our own ability, but to help others improve as well.\n  speakers:\n    - Caleb Hearth\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"caleb-hearth-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"IxrZmfebEE4\"\n\n- title: 'UX & Design for Rails Devs: Elevating the \"One Person Framework\" Experience'\n  raw_title: 'UX & Design for Rails Devs: Elevating the \"One Person Framework\" Experience'\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Rails 8's positioning as the \"one-person framework\" empowers developers to build complete applications independently, but many struggle with creating interfaces that are both functional and visually appealing. We will blitz through a variety of techniques and applications, pulling from recent examples such as the Rails Guides redesign. This talk will provide actionable UX assessment methods, fundamental visual design principles, and a live redesign demonstration using paper and Figma—equipping Rails developers with essential skills to create applications that are not just functional, but delightful to use.\n  speakers:\n    - John Athayde\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  id: \"john-athayde-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"ybUhVeTqGN4\"\n  slides_url: \"https://drive.google.com/file/d/1KOCAlYzXCMLjFMZXWiwKmTvxLZ-mSTnm/view\"\n\n- title: \"From FTP to Kamal: 20 Years of Deploying Rails\"\n  raw_title: \"From FTP to Kamal: 20 Years of Deploying Rails\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    RailsConf 2025 marks the end of an era—so let's take a ride through Rails history, deployment-style! From the Wild West days of FTP and CGI to the golden age of Capistrano, Passenger, and Heroku, all the way to Docker and Kamal, Rails deployment has been a journey of innovation, frustration, and occasional existential dread.\n\n    In this talk, we’ll revisit the tools, hacks, and battle scars of Rails deployment over the last 20 years. Remember Mongrel? FastCGI? The magical experience you had the first time you ran 'git push heroku'? We’ll celebrate the evolution of Rails ops, the community that shaped it, and what lessons we should take into the next 20 years.\n\n    Whether you deployed your first Rails app last week or you've been around since script/server, this talk is for you. Expect nostalgia, war stories, and callouts to the projects that paved the way to (and give some background on) what we have today. No grand lessons. No deep takeaways. Just a celebration of how far we’ve come.\n  speakers:\n    - Ben Curtis\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"ben-curtis-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"Fa2f9jUvL2Y\"\n\n- title: \"The Future of: PWAs on Rails\"\n  raw_title: \"The Future of: PWAs on Rails\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Rails is one of the best frameworks for building web applications. It's simple, yet powerful. Core Rails is always adding new features that increase productivity and make the developer's life easier.\n\n    Since version 7.2, Rails has added PWA components to the default setup. DHH himself said that he will be pushing hard for PWAs: \"No native apps, just the very best PWAs you can build.\"\n\n    There are lots of HTML APIs that can make your app behave like a native app. Device-native features like Geocoding, Device Motion, Battery status, and more can be accessed through the browser.\n\n    PWA implementations are evolving. The new `ActionNotifier` gem is on its way to make it easier to send push notifications. But PWAs have a lot more to offer and you can start using them today in a Rails way so you can be ready for when Rails is indeed, full PWA-ready.\n  speakers:\n    - Edigleysson Silva\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"edy-silva-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"AvdATDk0fSw\"\n\n- title: \"Rails Framework Defaults: Defusing the Time Bomb in Your Upgraded App\"\n  raw_title: \"Rails Framework Defaults: Defusing the Time Bomb in Your Upgraded App\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Yay, you did it: you upgraded Rails and it's live in production! All done, right? Not so fast: most upgrade talks and tutorials skip over the important step of upgrading Rails framework defaults. Your Rails upgrade isn't really done until you've disarmed the time bomb of outdated defaults. It can be tricky and isn't well documented, but you can do it with these steps.\n  speakers:\n    - Josh Puetz\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  id: \"josh-puetz-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"R9_2YUUrQ-g\"\n\n- title: \"Silent Killers: Lessons from the Brink\"\n  raw_title: \"Silent Killers: Lessons from the Brink\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Every Rails app starts with a solid foundation, but as features evolve and teams change, even the best projects can drift toward complexity. Over time, code that once felt effortless can become tangled, slow, and hard to maintain. This talk dives deep into what truly degrades a Rails application over time. We’ll explore practical ways to diagnose the health of a codebase, including underutilized metrics beyond test coverage and churn. Along the way, I’ll share battle-tested strategies for bringing struggling Rails apps back to life without a painful rewrite.\n  speakers:\n    - Joe Leo\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"joe-leo-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"OIOU7p4HUQM\"\n\n- title: \"Unraveling the black box: past, present and future of authentication in Rails\"\n  raw_title: \"Unraveling the black box: past, present and future of authentication in Rails\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    We often treat authentication as a black box because we’ve been standing on the shoulders of giants (aka Devise). Recently, a long-awaited feature has shipped with Rails 8: a built-in authentication generator! Let’s explore how the new default works and what we can learn from history and precedents when creating our authN flows.\n  speakers:\n    - Alicia Rojas\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"alicia-rojas-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"ITFbA2QEHNs\"\n\n- title: \"Internationalization on Rails: Unpacking the Rails I18n Toolkit\"\n  raw_title: \"Internationalization on Rails: Unpacking the Rails I18n Toolkit\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Building an app that's \"just in English\" might feel sufficient, but what if your next user prefers Spanish, German, or Chinese? Localization and internationalization are often an afterthought for many developers, if they are thought of at all. But it’s not only big, global companies that can benefit from them. They’re essential for startups and solo developers, too. In this talk, I’ll demystify internationalization and show you how Rails makes it easy to bake internationalization into your app from the start. You’ll learn how to use tools built into Rails and from gems in the wider ecosystem to easily support multilingual users, and make your app available to more people, wherever they are!\n  speakers:\n    - Chris Fung\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  id: \"chris-fung-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"Icd3pIvtoeA\"\n  slides_url: \"https://speakerdeck.com/aergonaut/unpacking-the-rails-i18n-toolkit\"\n\n- title: \"The History of Rails in 10 Blog Posts\"\n  raw_title: \"The History of Rails in 10 Blog Posts\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Calling nostalgic veterans and newbies alike! We're traveling through time on a tour of some of the most influential blog posts to hit the Rails community over the past two decades. With stops at iconic locations including in testing, service objects, and JavaScript, you won't want to miss it! Bring your chrono-passport and see you in 2003!\n  speakers:\n    - Joël Quenneville\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"joel-quenneville-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"HbmkzAuL_RM\"\n  slides_url: \"https://speakerdeck.com/joelq/the-history-of-rails-in-10-blog-posts\"\n\n- title: \"The ActiveRecord Tapes\"\n  raw_title: \"The ActiveRecord Tapes\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    In this talk, we'll dig deep into the design decisions of the Attributes API. We'll talk to its author and hear their experience from \"I think this would help with the current project I'm on!\" to \"Oh no, I'm rewriting all of ActiveRecord!\".\n\n    This will be a peek under the hood to a foundational part of ActiveRecord. You'll learn about the difficult technical constraints and tradeoffs that were made in development. Even if you don't know anything about the Attributes API, if you've used ActiveRecord, you've used it! No prior knowledge needed.\n  speakers:\n    - Tess Griffin\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"tess-griffin-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"HMqbBno22_s\"\n\n- title: \"Off the Rails: Validating non-model classes with…ActiveModel?\"\n  raw_title: \"Off the Rails: Validating non-model classes with…ActiveModel?\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Have you ever wished you could run Rails validators to check that a Hash, Struct or Data instance is properly formatted? Have you ever wanted to be able to compose complex validation logic on the fly rather than registering them at a class level with complicated conditionals? Did you ever have a use case for a single, generic validation and thought it’d be overkill to create a new ActiveModel class?\n\n    In this talk, we'll explore how to build a single class that’ll accept almost any kind of argument and let you register and run both built-in and custom validations against that argument’s key/value pairs and methods. Through test-driven development and examining the source code for ActiveModel validations and ActiveSupport callbacks, we’ll gradually build a robust solution to support custom and built-in validators and their various options like `if` and `allow_blank`.\n\n    Whether you want to validate a JSON field in a model, ensure that an incoming API request is properly formatted, check for valid events in an event-sourced application or run a validator against a class from a third-party library without monkey-patching, this talk will help you use some of Rails’ most classic features in a new and powerful way.\n  speakers:\n    - Andy Andrea\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  id: \"andy-andrea-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"4JiNCgPn5HY\"\n\n- title: \"The Modern View Layer Rails Deserves: A Vision for 2025 and Beyond\"\n  raw_title: \"The Modern View Layer Rails Deserves: A Vision for 2025 and Beyond\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Rails revolutionized web development and continues to evolve, but its view layer has remained largely unchanged while frontend needs have evolved dramatically. Rails has maintained its relevance by adopting technologies like Turbolinks and now Turbo/Hotwire while preserving its core principles.\n\n    But today's developers face challenges the current view layer wasn't designed to solve: complex UI interactions, reactivity, robust tooling for large codebases, intergration with modern UI kits, and modern tooling expectations.\n\n    This talk explores how a new HTML-aware ERB parser (Herb) could enable a truly reactive Rails view layer, bringing LiveView-style reactivity while preserving the \"HTML-over-the-wire\" philosophy. It will integrate with existing LSPs, unlock powerful tooling, and enable reactive server-rendered templates that could be reused client-side.\n\n    I'll demonstrate what's possible through proof-of-concepts and early prototypes, showing how we can collectively advance Rails views for modern development.\n  speakers:\n    - Marco Roth\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  id: \"marco-roth-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"lTL2-ERM_yY\"\n  slides_url: \"https://speakerdeck.com/marcoroth/the-modern-view-layer-rails-deserves-a-vision-for-2025-and-beyond-at-railsconf-2025-philadelphia-pa\"\n\n- title: \"From Resque to SolidQueue - Rethinking our background jobs for modern times\"\n  raw_title: \"From Resque to SolidQueue - Rethinking our background jobs for modern times\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    If your Rails app has been around for a while, you might still be using Resque for background jobs. We were too—until scaling issues, missing features, and increasing maintenance costs made it clear that Resque was no longer working for us.\n\n    This year we migrated to SolidQueue, Rails’ new default job runner and haven't looked back. This talk will walk you through how we did it—what worked, what didn’t, and what we learned along the way.\n\n    Key takeaways:\n    • Why we left Resque\n    • How we migrated with minimal disruption using a parallel rollout\n    • Why we went through the effort to re-name all our queues so that they were SLO-based  (within_1_minute) and why this matters\n    • Lessons learned, pitfalls to avoid, and how SolidQueue made our jobs (and jobs!) easier\n\n    If your background jobs are from a previous era, this talk will give you a practical, real-world migration playbook to modernize with SolidQueue—without breaking anything.\n  speakers:\n    - Andrew Markle\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  id: \"andrew-markle-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"lWMYPHPj1NI\"\n\n- title: \"The Rails Story: Two Decades of Design and Decisions\"\n  raw_title: \"The Rails Story: Two Decades of Design and Decisions\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Ever wondered why Rails is built the way it is? This talk explores the thoughtful design decisions behind Ruby on Rails, tracing how its features evolved over the past two decades. We'll uncover the historical context and reasoning behind Rails' choices, such as \"Convention over Configuration,\" and why some features have evolved or disappeared entirely. Beginners will clearly understand Rails’ fundamentals, while experienced developers will gain a deeper appreciation of the framework they use every day.\n  speakers:\n    - Ratnadeep Deshmane\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  id: \"ratnadeep-deshmane-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"NOXeX8_kscg\"\n\n- id: \"chris-oliver-railsconf-2025\"\n  title: \"The Closing of RailsConf\"\n  raw_title: \"RailsConf 2025 - The Closing of RailsConf with Chris Oliver and Ufuk Kayserilioglu\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    The end of RailsConf\n  speakers:\n    - Chris Oliver\n    - Ufuk Kayserilioglu\n  date: \"2025-07-09\"\n  published_at: \"2025-07-29\"\n  video_provider: \"youtube\"\n  video_id: \"ARfpwJ1Ut70\"\n\n- title: \"Closing Keynote: Why is Aaron Patterson?\"\n  raw_title: \"Keynote\"\n  event_name: \"RailsConf 2025\"\n  description: \"\"\n  speakers:\n    - Aaron Patterson\n  date: \"2025-07-10\"\n  published_at: \"2025-07-24\"\n  announced_at: \"2025-06-04 15:05:00 UTC\"\n  track: \"Main Stage - Liberty\"\n  id: \"closing-keynote-day-3-railsconf-2025\"\n  video_provider: \"youtube\"\n  video_id: \"lxIvWG85Nlk\"\n\n- id: \"lightning-talks-railsconf-2025\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Rapid fire talks in under 5 minutes from the community. So much to inspire in so little time!\n  date: \"2025-07-09\"\n  published_at: \"2025-07-24\"\n  track: \"Main Stage - Liberty\"\n  video_provider: \"youtube\"\n  video_id: \"XucQAvZanfM\"\n  talks:\n    - title: \"Lightning Talks Intro\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"00:15\"\n      end_cue: \"01:23\"\n      thumbnail_cue: \"00:21\"\n      id: \"noel-rappin-lightning-talks-railsconf-2025\"\n      video_id: \"noel-rappin-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Noel Rappin\n\n    - title: \"Lightning Talk: Open source Ruby gem analytics with ClickHouse\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"01:25\"\n      end_cue: \"07:29\"\n      thumbnail_cue: \"01:33\"\n      id: \"zoe-steinkamp-lightning-talks-railsconf-2025\"\n      video_id: \"zoe-steinkamp-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Zoe Steinkamp\n\n    - title: \"Lightning Talk: Programming in the Low Memory Environment of Your Brain\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"07:32\"\n      end_cue: \"13:01\"\n      thumbnail_cue: \"07:37\"\n      id: \"jeremy-smith-lightning-talks-railsconf-2025\"\n      video_id: \"jeremy-smith-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeremy Smith\n\n    - title: \"Lightning Talk: A crash course in Linguistics w/ Ruby & Rails\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"13:06\"\n      end_cue: \"18:05\"\n      thumbnail_cue: \"13:12\"\n      id: \"sam-poder-lightning-talks-railsconf-2025\"\n      video_id: \"sam-poder-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Sam Poder\n\n    - title: \"Lightning Talk: Terminus: A Hanami application for e-ink displays\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"18:19\"\n      end_cue: \"23:02\"\n      thumbnail_cue: \"18:24\"\n      id: \"brook-kuhlmann-lightning-talks-railsconf-2025\"\n      video_id: \"brook-kuhlmann-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Brooke Kuhlmann\n\n    - title: \"Lightning Talk: What is `Data` class?\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"23:04\"\n      end_cue: \"28:05\"\n      thumbnail_cue: \"23:09\"\n      id: \"kelly-popko-lightning-talks-railsconf-2025\"\n      video_id: \"kelly-popko-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Kelly Popko\n\n    - title: \"Lightning Talk: Peace, Love, and CRUD: A Rails Journey to Calm\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"28:14\"\n      end_cue: \"34:27\"\n      thumbnail_cue: \"28:19\"\n      id: \"tia-anderson-lightning-talks-railsconf-2025\"\n      video_id: \"tia-anderson-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Tia Anderson\n\n    - title: \"Lightning Talk: Build AI in Rails: Now Agents are Controller; Makes Code Tons of Fun!\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"34:38\"\n      end_cue: \"40:13\"\n      thumbnail_cue: \"34:43\"\n      id: \"justin-bowen-lightning-talks-railsconf-2025\"\n      video_id: \"justin-bowen-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Justin Bowen\n\n    - title: \"Lightning Talk: 10 years of Rails Girls São Paulo\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"40:16\"\n      end_cue: \"43:10\"\n      thumbnail_cue: \"40:21\"\n      id: \"debora-fernandes-lightning-talks-railsconf-2025\"\n      video_id: \"debora-fernandes-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Débora Fernandes\n\n    - title: \"Lightning Talk: Playing with Memory: Manual Management in C\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"43:19\"\n      end_cue: \"48:45\"\n      thumbnail_cue: \"43:24\"\n      id: \"shardly-romelus-lightning-talks-railsconf-2025\"\n      video_id: \"shardly-romelus-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Shardly Romelus\n\n    - title: \"Lightning Talk: Gamified Developer Experiences\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"48:48\"\n      end_cue: \"54:15\"\n      thumbnail_cue: \"48:53\"\n      id: \"rachael-wright-munn-lightning-talks-railsconf-2025\"\n      video_id: \"rachael-wright-munn-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Rachael Wright-Munn\n\n    - title: \"Lightning Talk: Ugly Colors: How I Built a Web App to Rank Ugly Colors\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"54:22\"\n      end_cue: \"57:55\"\n      thumbnail_cue: \"54:27\"\n      id: \"lucy-chen-lightning-talks-railsconf-2025\"\n      video_id: \"lucy-chen-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Lucy Chen\n\n    - title: \"Lightning Talk: The Other Side of Fear\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"58:01\"\n      end_cue: \"01:02:55\"\n      thumbnail_cue: \"58:01\"\n      id: \"alan-ridlehoover-lightning-talks-railsconf-2025\"\n      video_id: \"alan-ridlehoover-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      slides_url: \"https://speakerdeck.com/aridlehoover/railsconf-2025-the-other-side-of-fear\"\n      speakers:\n        - Alan Ridlehoover\n\n    - title: \"Lightning Talk: Save your coffee money: Jemalloc in 5 minutes\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"01:03:03\"\n      end_cue: \"01:07:12\"\n      thumbnail_cue: \"01:03:08\"\n      id: \"yasar-celep-lightning-talks-railsconf-2025\"\n      video_id: \"yasar-celep-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Yaşar Celep\n\n    - title: \"Lightning Talk: Ruby UI - From React to Hotwire\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"01:07:20\"\n      end_cue: \"01:12:24\"\n      thumbnail_cue: \"01:07:25\"\n      id: \"cirdes-henrique-lightning-talks-railsconf-2025\"\n      video_id: \"cirdes-henrique-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Cirdes Henrique\n\n- id: \"alex-coomans-railsconf-2025\"\n  title: \"Simplifying at Scale: 7 Years of Rails Architecture at Persona\"\n  raw_title: \"Simplifying at Scale: 7 Years of Rails Architecture at Persona\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    What does it really take to scale a Ruby on Rails architecture to power a global identity platform trusted by businesses around the world? From our early days on Google App Engine to a globally distributed, multi-cluster Kubernetes deployment, this talk takes you through the evolution of Persona's architecture.\n\n    We'll dive into the architectural turning points that shaped our journey: the trade-offs we faced, the mistakes we made, and the surprising ways complexity crept in. Most importantly, we'll share why simplicity might be the key to scaling successfully without losing your mind. Whether you're just starting out or wrangling scale yourself, you'll leave with battle-tested insights on system design, technical decision-making, and building for the long haul that'll help you build best-in-class Rails applications.\n  speakers:\n    - Alex Coomans\n  date: \"2025-07-08\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  video_provider: \"youtube\"\n  video_id: \"vNyxiNh8Q7k\"\n\n- id: \"lightning-talks-new-and-improved-features-in-rails-81-railsconf-2025\"\n  title: \"Lightning Talks: New and Improved Features in Rails 8.1\"\n  raw_title: \"New and Improved Features in Rails 8.1\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    The Ruby & Rails Infrastructure team at Shopify are stewards of Ruby and Rails within the company, and our mission is to ensure they remain Shopify's tools of choice for building great software. Sometimes that means building big new features into Rails. But often it means finding gaps and making improvements to existing features in the framework.\n\n    Join us for a series of lightning talks about new features that we have added to Rails over the last year, to be released as part of Rails 8.1.\n  date: \"2025-07-09\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  video_provider: \"youtube\"\n  video_id: \"gAHlLqnLM1o\"\n  talks:\n    - title: \"Shopify Lightning Talks Intro\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"00:15\"\n      end_cue: \"01:23\"\n      thumbnail_cue: \"00:18\"\n      id: \"andrew-novoselac-intro-lightning-talks-railsconf-2025\"\n      video_id: \"andrew-novoselac-intro-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Novoselac\n\n    - title: \"Lightning Talk: A Story of Eliminating Postgres Not Null Violations\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"01:30\"\n      end_cue: \"06:23\"\n      thumbnail_cue: \"01:35\"\n      id: \"jenny-shen-lightning-talks-railsconf-2025\"\n      video_id: \"jenny-shen-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Jenny Shen\n\n    - title: \"Lightning Talk: Structured Event Reporter\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"06:28\"\n      end_cue: \"10:32\"\n      thumbnail_cue: \"06:33\"\n      id: \"george-ma-lightning-talks-railsconf-2025\"\n      video_id: \"george-ma-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - George Ma\n\n    - title: \"Lightning Talk: When Logs Betray Sensitive Secrets\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"10:35\"\n      end_cue: \"15:48\"\n      thumbnail_cue: \"10:42\"\n      id: \"jill-klang-lightning-talks-railsconf-2025\"\n      video_id: \"jill-klang-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Jill Klang\n\n    - title: \"Lightning Talk: Do you test your tests?\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"15:48\"\n      end_cue: \"23:10\"\n      thumbnail_cue: \"15:53\"\n      id: \"nikita-vasilevsky-lightning-talks-railsconf-2025\"\n      video_id: \"nikita-vasilevsky-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Nikita Vasilevsky\n\n    - title: \"Lightning Talk: Rails Error Reporter Middleware\"\n      event_name: \"RailsConf 2025\"\n      start_cue: \"23:12\"\n      end_cue: \"29:37\"\n      thumbnail_cue: \"23:28\"\n      id: \"andrew-novoselac-lightning-talks-railsconf-2025\"\n      video_id: \"andrew-novoselac-lightning-talks-railsconf-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Novoselac\n\n- id: \"yasuo-honda-railsconf-2025\"\n  title: \"Contributing to Rails? Start with the Gems You Already Use\"\n  raw_title: \"Contributing to Rails? Start with the Gems You Already Use\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    Contributing to Ruby on Rails might seem difficult, especially if you're new to open source. But the first step is ensuring that the gems your application depends on are compatible with new Ruby and Rails versions. Many gems power your Rails app, and improving them is a great way to get comfortable with open-source development.\n\n    This session is designed for developers who are interested in open source but don't know where to begin. We'll explore why contributing to gems is an ideal first step—it helps ensure compatibility, improves your understanding of Rails, and makes a meaningful impact. You'll learn how to find issues, interact with maintainers, and submit your first pull request with confidence.\n\n    We'll also discuss best practices for running CI across different Rails and Ruby versions and how to address compatibility issues. By the end of this talk, you'll have a clear roadmap to start contributing and making an impact in the Rails ecosystem.\n  speakers:\n    - Yasuo Honda\n  date: \"2025-07-09\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 2 - Freedom\"\n  video_provider: \"youtube\"\n  video_id: \"HsW25iZD70M\"\n  slides_url: \"https://speakerdeck.com/yahonda/contributing-to-rails-start-with-the-gems-you-already-use\"\n\n- id: \"justin-wienckowski-railsconf-2025\"\n  title: \"Chime Presents: Getting More Out of LLMs for Ruby Developers\"\n  raw_title: \"Chime Presents: Getting More Out of LLMs for Ruby Developers\"\n  event_name: \"RailsConf 2025\"\n  description: |-\n    We're all hearing about LLM tools that are changing on a daily, if not hourly, basis. How can you navigate these tools as a developer to improve your code and your impact.\n\n    Justin Wienckowski will share lessons and advice from Chime's programs piloting tools for developer use, and Jake Gribschaw will talk about lessons learned building an AI code review bot.\n  speakers:\n    - Justin Wienckowski\n    - Jake Gribschaw\n  date: \"2025-07-09\"\n  published_at: \"2025-07-24\"\n  track: \"Breakout 1 - Independence\"\n  video_provider: \"youtube\"\n  video_id: \"xWDhBqNuA7A\"\n  slides_url: \"https://docs.google.com/presentation/d/1Hz3P5rsdPqUMziviD7Lla78LB0ChrtmEbwPBkEy9dEU/view\"\n"
  },
  {
    "path": "data/railsconf/series.yml",
    "content": "---\nname: \"RailsConf\"\nwebsite: \"https://railsconf.org/\"\ntwitter: \"railsconf\"\nyoutube_channel_name: \"confreaks\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"rails\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nended: true\naliases:\n  - Rails Conf\n  - Rails Conference\n"
  },
  {
    "path": "data/railsconf-europe/railsconf-europe-2006/event.yml",
    "content": "# https://www.flickr.com/photos/x180/albums/72157594287410226\n---\nid: \"railsconf-europe-2006\"\ntitle: \"RailsConf Europe 2006\"\nkind: \"conference\"\nlocation: \"London, UK\"\ndescription: \"\"\nstart_date: \"2006-09-14\"\nend_date: \"2006-09-15\"\nyear: 2006\nwebsite: \"https://web.archive.org/web/20060829205801/http://europe.railsconf.org/\"\noriginal_website: \"http://europe.railsconf.org\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/railsconf-europe/railsconf-europe-2006/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://www.flickr.com/photos/x180/albums/72157594287410226\n# https://www.flickr.com/photos/jarkko/albums/72157594378666750/\n---\n[]\n"
  },
  {
    "path": "data/railsconf-europe/railsconf-europe-2007/event.yml",
    "content": "# https://www.flickr.com/photos/x180/albums/72157602045833613/\n---\nid: \"railsconf-europe-2007\"\ntitle: \"RailsConf Europe 2007\"\nkind: \"conference\"\nlocation: \"Berlin, Germany\"\ndescription: \"\"\nstart_date: \"2007-09-17\"\nend_date: \"2007-09-19\"\nyear: 2007\nwebsite: \"https://rubyonrails.org/2007/6/15/railsconf-europe-2007-in-berlin\"\noriginal_website: \"http://www.railsconfeurope.com/\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/railsconf-europe/railsconf-europe-2007/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://www.flickr.com/photos/x180/albums/72157602045833613\n---\n[]\n"
  },
  {
    "path": "data/railsconf-europe/railsconf-europe-2008/event.yml",
    "content": "# https://www.flickr.com/photos/x180/albums/72157607077916014\n---\nid: \"railsconf-europe-2008\"\ntitle: \"RailsConf Europe 2008\"\nkind: \"conference\"\nlocation: \"Berlin, Germany\"\ndescription: \"\"\nstart_date: \"2008-09-02\"\nend_date: \"2008-09-04\"\nyear: 2008\nwebsite: \"https://web.archive.org/web/20080630052603/http://en.oreilly.com/railseurope2008/public/content/home\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/railsconf-europe/railsconf-europe-2008/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Schedule: https://web.archive.org/web/20080730010325mp_/http://en.oreilly.com/railseurope2008/public/schedule/grid\n# https://www.flickr.com/photos/x180/sets/72157607077916014/\n---\n[]\n"
  },
  {
    "path": "data/railsconf-europe/series.yml",
    "content": "---\nname: \"RailsConf Europe\"\nwebsite: \"http://www.railsconfeurope.com/\"\ntwitter: \"railsconf\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/railswaycon/railswaycon-2009/event.yml",
    "content": "---\nid: \"railswaycon-2009\"\ntitle: \"RailsWayCon 2009\"\ndescription: \"\"\nlocation: \"Berlin, Germany\"\nkind: \"conference\"\nstart_date: \"2009-05-25\"\nend_date: \"2009-05-27\"\nwebsite: \"https://web.archive.org/web/20090517030616/http://it-republik.de/conferences/railswaycon/\"\noriginal_website: \"http://it-republik.de/conferences/railswaycon/\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/railswaycon/railswaycon-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://web.archive.org/web/20090517030616/http://it-republik.de/conferences/railswaycon/\n# Schedule: https://web.archive.org/web/20090502115807/http://it-republik.de/konferenzen/planer/railswaycon_timetable.html\n---\n[]\n"
  },
  {
    "path": "data/railswaycon/railswaycon-2010/event.yml",
    "content": "---\nid: \"railswaycon-2010\"\ntitle: \"RailsWayCon 2010\"\ndescription: \"\"\nlocation: \"Berlin, Germany\"\nkind: \"conference\"\nstart_date: \"2010-05-31\"\nend_date: \"2010-06-02\"\nwebsite: \"https://web.archive.org/web/20100616094045/http://it-republik.de/conferences/railswaycon2010/\"\noriginal_website: \"http://it-republik.de/conferences/railswaycon2010/\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/railswaycon/railswaycon-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://web.archive.org/web/20100616094045/http://it-republik.de/conferences/railswaycon2010/\n# Schedule: https://web.archive.org/web/20100422195425/http://entwickler.com/konferenzen/planer/railswaycon2010_timetable.html\n---\n[]\n"
  },
  {
    "path": "data/railswaycon/railswaycon-2011/event.yml",
    "content": "---\nid: \"railswaycon-2011\"\ntitle: \"RailsWayCon 2011\"\ndescription: \"\"\nlocation: \"Berlin, Germany\"\nkind: \"conference\"\nstart_date: \"2011-05-30\"\nend_date: \"2011-06-01\"\nwebsite: \"https://web.archive.org/web/20110524121943/http://railswaycon.com/\"\noriginal_website: \"http://railswaycon.com/\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/railswaycon/railswaycon-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://web.archive.org/web/20110524121943/http://railswaycon.com/\n# Schedule: https://web.archive.org/web/20110523014740/http://railswaycon.com/2011/timetable\n---\n[]\n"
  },
  {
    "path": "data/railswaycon/railswaycon-2012/event.yml",
    "content": "---\nid: \"railswaycon-2012\"\ntitle: \"RailsWayCon 2012\"\ndescription: \"\"\nlocation: \"Berlin, Germany\"\nkind: \"conference\"\nstart_date: \"2012-06-04\"\nend_date: \"2012-06-06\"\nwebsite: \"https://web.archive.org/web/20120604100414/http://railswaycon.com/\"\noriginal_website: \"http://railswaycon.com/\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/railswaycon/railswaycon-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://web.archive.org/web/20120604100414/http://railswaycon.com/\n# Schedule: https://web.archive.org/web/20120604045159/http://railswaycon.com/2012/timetable\n---\n[]\n"
  },
  {
    "path": "data/railswaycon/series.yml",
    "content": "---\nname: \"RailsWayCon\"\nwebsite: \"https://www.railswaycon.org\"\ntwitter: \"\"\nmastodon: \"\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rbqconf/rbqconf-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://docs.google.com/forms/d/e/1FAIpQLScZiWKKW_0lWe8C59p2mwk6U0YVh0hFuMYLtKLYVO9hQ_f7Kw/viewform\"\n  open_date: \"2025-11-23\"\n  close_date: \"2026-01-08\"\n\n- name: \"Lightning Talks\"\n  link: \"https://docs.google.com/forms/d/e/1FAIpQLSdVIotL2KY-ZLSCAa6tZfsYZGctnWBKwEfuAtrL4JDqmq6xOg/viewform\"\n  open_date: \"2026-02-20\"\n  close_date: \"2026-03-26\"\n"
  },
  {
    "path": "data/rbqconf/rbqconf-2026/event.yml",
    "content": "---\nid: \"rbqconf-2026\"\ntitle: \"RBQ Conf 2026\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: |-\n  RBQ Conf is a regional Ruby gathering where code meets community, with meaty talks, saucy insights, and plenty of time to connect.\nstart_date: \"2026-03-26\"\nend_date: \"2026-03-27\"\nyear: 2026\nwebsite: \"https://rbqconf.com\"\ntickets_url: \"https://ti.to/convivial-tech/rbqconf-2026\"\nfeatured_color: \"#FFFFFF\"\nfeatured_background: \"#884057\"\nbanner_background: \"#884057\"\ncoordinates:\n  latitude: 30.268889\n  longitude: -97.740556\n"
  },
  {
    "path": "data/rbqconf/rbqconf-2026/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Nathan Hessler\n  organisations:\n    - ConvivialTech\n"
  },
  {
    "path": "data/rbqconf/rbqconf-2026/schedule.yml",
    "content": "# docs/ADDING_SCHEDULES.md\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2026-03-26\"\n    grid:\n      # Time slots for unrecorded events (not in videos.yml)\n      # Items replaces the talk\n      - start_time: \"08:00\"\n        end_time: \"08:55\"\n        slots: 1\n        items:\n          - Breakfast & Registration\n      # Time slots for talks/sessions - NO \"items\" field\n      # These are automatically filled from videos.yml in order\n      - start_time: \"08:55\"\n        end_time: \"09:15\"\n        slots: 1\n      - start_time: \"09:20\"\n        end_time: \"10:00\"\n        slots: 1\n      - start_time: \"10:05\"\n        end_time: \"10:35\"\n        slots: 1\n      - start_time: \"10:35\"\n        end_time: \"11:05\"\n        slots: 1\n        items:\n          - Morning Stretch\n      - start_time: \"11:05\"\n        end_time: \"11:35\"\n        slots: 1\n      - start_time: \"11:40\"\n        end_time: \"12:10\"\n        slots: 1\n      - start_time: \"12:10\"\n        end_time: \"13:40\"\n        slots: 1\n        items:\n          - Lunch\n      - start_time: \"13:40\"\n        end_time: \"14:05\"\n        slots: 1\n      - start_time: \"14:10\"\n        end_time: \"14:40\"\n        slots: 1\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Afternoon Stretch\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 1\n      - start_time: \"16:20\"\n        end_time: \"16:50\"\n        slots: 1\n      - start_time: \"16:50\"\n        end_time: \"17:00\"\n        slots: 1\n      - start_time: \"17:30\"\n        end_time: \"20:30\"\n        slots: 1\n        items:\n          - title: \"Happy Hour @ Higbies\"\n            description: |-\n              sponsored by GitButler - across from Capital Factory\n  - name: \"Day 2\"\n    date: \"2026-03-27\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"08:55\"\n        slots: 1\n        items:\n          - Breakfast & Registration\n      - start_time: \"08:55\"\n        end_time: \"09:05\"\n        slots: 1\n      - start_time: \"09:05\"\n        end_time: \"09:35\"\n        slots: 1\n      - start_time: \"09:40\"\n        end_time: \"10:10\"\n        slots: 1\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Morning Stretch\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n      - start_time: \"11:50\"\n        end_time: \"12:20\"\n        slots: 1\n      - start_time: \"12:20\"\n        end_time: \"13:50\"\n        slots: 1\n        items:\n          - Lunch\n      - start_time: \"13:50\"\n        end_time: \"14:15\"\n        slots: 1\n      - start_time: \"14:20\"\n        end_time: \"14:50\"\n        slots: 1\n      - start_time: \"14:50\"\n        end_time: \"15:20\"\n        slots: 1\n        items:\n          - Afternoon Stretch\n      - start_time: \"15:20\"\n        end_time: \"15:50\"\n        slots: 1\n      - start_time: \"15:55\"\n        end_time: \"16:35\"\n        slots: 1\n      - start_time: \"16:40\"\n        end_time: \"17:00\"\n        slots: 1\n"
  },
  {
    "path": "data/rbqconf/rbqconf-2026/sponsors.yml",
    "content": "# docs/ADDING_SPONSORS.md\n---\n- tiers:\n    - name: \"Gold\"\n      level: 1\n      sponsors:\n        - name: \"typesense\"\n          slug: \"typesense\"\n          website: \"https://typesense.org\"\n          badge: \"Lanyard Sponsor\"\n\n    - name: \"Silver\"\n      level: 2\n      sponsors:\n        - name: \"GitButler\"\n          website: \"https://gitbutler.com\"\n          slug: \"gitbutler\"\n          badge: \"Happy Hour Sponsor\"\n        - name: \"AppSignal\"\n          website: \"https://appsignal.com\"\n          slug: \"appsignal\"\n        - name: \"Judoscale\"\n          website: \"https://judoscale.com\"\n          slug: \"judoscale\"\n\n    - name: \"Bronze\"\n      level: 3\n      sponsors:\n        - name: \"dnsimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"dnsimple\"\n          logo_url: \"https://rbqconf.com/sponsors/dnsimple-logo.png\"\n\n    - name: \"Speaker\"\n      level: 4\n      sponsors:\n        - name: \"GitHub\"\n          website: \"https://github.com\"\n          slug: \"github\"\n        - name: \"Headius Enterprises\"\n          website: \"https://headius.com\"\n          slug: \"headius-enterprises\"\n        - name: \"Penn Medicine\"\n          website: \"https://www.pennmedicine.org\"\n          slug: \"penn-medicine\"\n        - name: \"Arkency\"\n          website: \"https://arkency.com\"\n          slug: \"arkency\"\n        - name: \"Hubstaff\"\n          website: \"https://hubstaff.com\"\n          slug: \"hubstaff\"\n"
  },
  {
    "path": "data/rbqconf/rbqconf-2026/venue.yml",
    "content": "---\nname: \"Capital Factory\"\ndescription: |-\n  We're hosting RBQ at Capital Factory, the center of gravity for entrepreneurs in Texas. Located in the heart of downtown Austin, Capital Factory is a modern, tech-forward space that's home to countless startups, meetups, and developer communities.\n  You'll be steps from Texas-style smoked brisket, cold drinks, live music, and the weird, wonderful energy that makes Austin... Austin.\n\naddress:\n  street: \"701 Brazos St\"\n  city: \"Austin\"\n  region: \"Texas\"\n  postal_code: \"78701\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"701 Brazos St, Austin, TX 78701, United States\"\n\ncoordinates:\n  latitude: 30.268889\n  longitude: -97.740556\n\nmaps:\n  google: \"https://maps.google.com/?q=Capital+Factory,+Austin\"\n  apple:\n    \"https://maps.apple.com/place?address=701%20Brazos%20St,%20Austin,%20TX%2078701,%20United%20States&coordinate=30.268908,-97.740437&name=Capital%20Factory&place-id=I1CDEBB03\\\n    E62968BD&map=transit\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=30.268889&mlon=-97.740556\"\n\nhotels:\n  - name: \"Omni Austin\"\n    description: |-\n      High end, located in same building\n    address:\n      street: \"700 San Jacinto Blvd\"\n      city: \"Austin\"\n      region: \"Texas\"\n      postal_code: \"78701\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"700 San Jacinto At, E 8th St, Austin, TX 78701\"\n    distance: \"0.0mi from venue\"\n    maps:\n      google: \"https://maps.app.goo.gl/qhMWJz6teziMDD959\"\n    coordinates:\n      latitude: 30.26914032642583\n      longitude: -97.74027480099309\n  - name: \"Aloft Austin Downtown\"\n    description: |-\n      Mid Range, close to 6th St.\n    distance: \"0.1mi from venue\"\n    address:\n      street: \"109 East 7th Street\"\n      city: \"Austin\"\n      region: \"Texas\"\n      postal_code: \"78701\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"109 E 7th St, Austin, TX 78701\"\n    maps:\n      google: \"https://maps.app.goo.gl/Y7Y3CgRVPQfoHSKf8\"\n    coordinates:\n      latitude: 30.268840866048542\n      longitude: -97.74200688934701\n  - name: \"Hyatt House\"\n    description: |-\n      Low end, 2 blocks from Franklins BBQ\n    distance: \"0.4mi from venue\"\n    address:\n      street: \"901 Neches Street\"\n      city: \"Austin\"\n      region: \"Texas\"\n      postal_code: \"78701\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"901 Neches St, Austin, TX 78701\"\n    maps:\n      google: \"https://maps.app.goo.gl/ncgsyWBciw9mkmCC8\"\n    coordinates:\n      latitude: 30.269862067783436\n      longitude: -97.73678510468854\n"
  },
  {
    "path": "data/rbqconf/rbqconf-2026/videos.yml",
    "content": "---\n- id: \"opening-remarks-rbqconf-2026\"\n  title: \"Opening Remarks\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-26\"\n  description: \"\"\n  speakers:\n    - TODO # RBQ MC\n  video_provider: \"scheduled\"\n  video_id: \"opening-remarks-rbqconf-2026\"\n\n- id: \"kinsey-durham-grace-rbqconf-2025\"\n  title: \"Keynote: Kinsey Durham Grace\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-26\"\n  announced_at: \"2025-12-24\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"kinsey-durham-grace-rbqconf-2025\"\n  speakers:\n    - \"Kinsey Durham Grace\"\n\n- id: \"daniel-colson-rbqconf-2026\"\n  title: \"Regex as Easy as /(abc)?/\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-26\"\n  announced_at: \"2026-01-23\"\n  description: |-\n    What really happens when Ruby sees a regular expression like /abc/? While many of us use regular expressions regularly, we don’t necessarily think much about how they really work. In this talk we’ll trace a regular expression through Ruby’s internals, from parsing the pattern into a syntax tree, to compiling into bytecode, to executing that bytecode on a small virtual machine. You’ll come away with a deeper understanding and appreciation for Ruby’s regular expression engine, and hopefully an increased confidence in working with regular expressions in Ruby.\n  speakers:\n    - \"Daniel Colson\"\n  video_provider: \"scheduled\"\n  video_id: \"daniel-colson-rbqconf-2026\"\n\n- id: \"alex-yarotsky-rbqconf-2026\"\n  title: \"A Hands-On Guide to Postgres Partitioning for Rails Developers\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-26\"\n  announced_at: \"2026-01-21\"\n  description: |-\n    Partitioning is one of the most powerful features in Postgres, but most Rails developers never use it because it feels confusing, risky, or too \"enterprise.\" In this talk, we will walk through a hands-on and practical approach to table partitioning that you can actually use in a real Rails application.\n\n    We will start with the problems that usually appear as your tables grow, such as slow queries, long autovacuum runs, and painful migrations. From there, we will explore how partitioning works, when it is the right choice, and how to apply it step by step without downtime or major rewrites. You will see examples of how to route inserts, how to manage old partitions, and how to keep your database healthy as data grows.\n\n    If you have ever wondered whether partitioning is worth the effort, this talk will give you the confidence and clear instructions to do it safely.\n  speakers:\n    - \"Alex Yarotsky\"\n  video_provider: \"scheduled\"\n  video_id: \"alex-yarotsky-rbqconf-2026\"\n\n- id: \"szymon-fiedler-rbqconf-2026\"\n  title: \"Would Your Tests Catch This Bug? A Mutation Testing Story\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-26\"\n  announced_at: \"2026-01-24\"\n  description: |-\n    Your tests pass, but do they actually test anything? With AI agents now writing tests, mutation testing becomes critical. Learn how Mutant exposes gaps in your test coverage by introducing bugs. If tests still pass, you've found a blind spot. Real code. Real mutations. Real insights.\n  speakers:\n    - \"Szymon Fiedler\"\n  video_provider: \"scheduled\"\n  video_id: \"szymon-fiedler-rbqconf-2026\"\n\n- id: \"burnt-ends-rbqconf-2026\"\n  title: \"Burnt Ends (Lightning Talks Day 1)\"\n  raw_title: \"Burnt Ends\"\n  description: |-\n    Got a hot take, a cool hack, or a quick demo? Each day after lunch we open the stage for lightning talks — short, 5-minute presentations on anything Ruby, tech, or community related.\n  date: \"2025-07-09\"\n  video_provider: \"scheduled\"\n  video_id: \"burnt-ends-rbqconf-2026\"\n  talks: []\n\n- id: \"amir-rajan-rbqconf-2026\"\n  title: \"Building a Cross Platform Game Engine with Ruby: Deep Dive\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-26\"\n  announced_at: \"2026-01-25\"\n  description: |-\n    DragonRuby Game Toolkit is a cross-platform commercial game engine that exports to Web, Steam, Mobile, and Console. We'll take a deep dive into DragonRuby's C internals and see what it takes to build a zero-dependency game engine powered by libSDL with Ruby as the scripting layer.\n  speakers:\n    - \"Amir Rajan\"\n  video_provider: \"scheduled\"\n  video_id: \"amir-rajan-rbqconf-2026\"\n\n- id: \"david-paluy-rbqconf-2026\"\n  title: \"LLM Telemetry as a First-Class Rails Concern\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-26\"\n  announced_at: \"2026-01-24\"\n  description: |-\n    Rubyist Entrepreneur: Bootstrapping with Agents\n\n    LLM features in Rails apps should be logged, reviewed, and costed with the same discipline as any other production dependency, not treated as a spooky black box bolted onto your controllers. This talk shows how to make TraceBook-style telemetry a first-class concern in your Rails architecture: part of your domain, not just sprinkled Rails.logger.info calls.\n  speakers:\n    - \"David Paluy\"\n  video_provider: \"scheduled\"\n  video_id: \"david-paluy-rbqconf-2026\"\n\n- id: \"ariel-valentin-rbqconf-2026\"\n  title: \"Practical Observability for Ruby\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-26\"\n  announced_at: \"2026-01-23\"\n  description: |-\n    You’ve seen the buzzwords Observability, SRE, SLOs, traces, metrics, logs, and profiling, but what do they really mean, and why is everyone talking about them? In this session, we’ll cut through the noise and dive into what observability actually looks like in the real world. You’ll discover how these tools and practices can transform the way you and your team build, operate, and troubleshoot Ruby applications. Expect clear explanations, actionable insights, and a fresh perspective on why observability isn’t just a trend - it’s a superpower waiting to be unlocked.\n  speakers:\n    - \"Ariel Valentin\"\n  video_provider: \"scheduled\"\n  video_id: \"ariel-valentin-rbqconf-2026\"\n\n- id: \"yarik-rbqconf-2026\"\n  title: \"Two Requests, One Record: Concurrency in Rails\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-26\"\n  announced_at: \"2026-01-22\"\n  description: |-\n    You wrap your code in a transaction, add validations, and ship it. Everything works perfectly in development and passes all tests... until two requests arrive at the same time in production.\n\n    This talk explores the database concurrency problems most Rails apps silently ignore: check-then-act races, lost updates in nested associations, and the deadlocks that follow. We'll examine how default isolation levels provide less protection than you think, why API calls inside transactions amplify these issues, and how coordination primitives like row locks and named locks can protect your data.\n\n    Through real production failures and live demonstrations of race conditions, you'll learn practical patterns to handle concurrent access safely.\n  speakers:\n    - \"Yarik\"\n  video_provider: \"scheduled\"\n  video_id: \"yarik-rbqconf-2026\"\n\n- id: \"day-one-notes-rbqconf-2026\"\n  title: \"Day One Notes\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-26\"\n  description: \"\"\n  speakers:\n    - TODO # RBQ MC\n  video_provider: \"scheduled\"\n  video_id: \"day-one-notes-rbqconf-2026\"\n\n- id: \"day-two-notes-rbqconf-2026\"\n  title: \"Day Two Notes\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-27\"\n  description: \"\"\n  speakers:\n    - TODO # RBQ MC\n  video_provider: \"scheduled\"\n  video_id: \"day-two-notes-rbqconf-2026\"\n\n- id: \"bart-de-water-rbqconf-2026\"\n  title: \"How to quit your job (and come back later)\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-27\"\n  announced_at: \"2026-01-25\"\n  description: |-\n    Your background job ran for six hours, processed 2 million records, then died 94% of the way through a deploy. Sound familiar?\n\n    Retries with exponential backoff don't help when your job was aborted, not failed. The Ruby ecosystem has evolved multiple answers to this problem: Shopify's job-iteration and Rails 8.1's new Active Job continuations. Outside of pure-Ruby solutions, Temporal brings a workflow-based approach.\n\n    This talk surveys the 2026 landscape of resilient background job options in Ruby. We'll dig into the history, compare the tradeoffs between iteration-based, step-based, and workflow-based approaches, and explore when you need to graduate from \"resilient jobs\" to \"orchestrated workflows.\" You'll leave with a framework for choosing the right tool for your workload.\n  speakers:\n    - \"Bart de Water\"\n  video_provider: \"scheduled\"\n  video_id: \"bart-de-water-rbqconf-2026\"\n\n- id: \"pj-hagerty-rbqconf-2026\"\n  title: \"Why Git Still Matters\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-27\"\n  announced_at: \"2026-01-21\"\n  description: |-\n    With more and more tools abstracting from a developers workflows, understanding how git visualization tools help - not simply using it - is more important than ever. In this article, we take a look at the history of git workflows, the basics of git, and the renaissance of understanding version control in a world gone mad for \"vibe coding\"\n  speakers:\n    - \"PJ Hagerty\"\n  video_provider: \"scheduled\"\n  video_id: \"pj-hagerty-rbqconf-2026\"\n\n- id: \"tom-brown-rbqconf-2026\"\n  title: \"Webfinger Reverse Discovery\"\n  date: \"2026-03-27\"\n  description: |-\n    The fediverse is a welcome alternative to billionaire owned social networks. We know that design decisions have tradeoffs and, on the fediverse, people should consider the possibility of being put into the unenviable position of losing their presence because their server suddenly disappears. This is not common but losing your identifier and data can be a real pain if it happens. In the spirit of the indieweb, one way to mitigate this threat is owning your own domain. Mastodon, the most popular fediverse software, and other fediverse applications interoperate with remote servers with users who have identifiers whose domain is different than the server they reside on through Webfinger Reverse Discovery. In this talk, lessons learned from 2 years of dogfooding a ruby fediverse application will be shared.\n  speakers:\n    - Tom Brown\n  video_provider: \"scheduled\"\n  video_id: \"tom-brown-rbqconf-2026\"\n\n- id: \"meghan-gutshall-rbqconf-2026\"\n  title: \"Revealing Rails Magic with Enums\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-27\"\n  announced_at: \"2026-01-25\"\n  description: |-\n    \"Rails magic\" is a term many people use to describe the ease with which Rails helps you go from zero to working app so quickly. However, like all other frameworks, there's no magic to be found – only code!\n\n    In this talk, you'll get a peek behind the curtain as we break down the ActiveRecord Enums module. First, you'll learn what it is, how/when to use it, and some cool tricks it provides. Then, we'll examine the codebase together and unravel the mystery behind the magic. Rails developers of all skill levels will come away from this talk with new-found knowledge on how to traverse a codebase and gain a better understanding of the ActiveRecord Enums module.\n  speakers:\n    - \"Meghan Gutshall\"\n  video_provider: \"scheduled\"\n  video_id: \"meghan-gutshall-rbqconf-2026\"\n\n- id: \"chris-gratigny-rbqconf-2026\"\n  title: \"Lessons Learned from my first AI implementation\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-27\"\n  announced_at: \"2026-01-25\"\n  description: |-\n    This talk shares lessons from my initial journey building AI functionality into a Ruby on Rails application. I'll show the evolution of the system, starting with a direct integration using the Anthropic API before transitioning to a using the RubyLLM gem and the niceness it provides. I have the unique experience of building an AI tool in an organization where accuracy is paramount, and have learned how to dial the temperature to get just what we need.\n\n    A key take-a-way should be how prompt versioning can work with a prompt being changed 100+ times during experimentation. I'll demonstrate the power of tool calls (function calling) not just for executing actions, but as a critical pattern for structuring reliable, machine-readable AI responses. Attendees will leave with practical, code-level advice for moving beyond simple text generation to building robust, production-ready AI features in a Rails environment.\n  speakers:\n    - \"Chris Gratigny\"\n  video_provider: \"scheduled\"\n  video_id: \"chris-gratigny-rbqconf-2026\"\n\n- id: \"burnt-end-2-rbqconf-2026\"\n  title: \"Burnt Ends (Lightning Talks Day 2)\"\n  raw_title: \"Burnt Ends, Day 2\"\n  description: |-\n    Got a hot take, a cool hack, or a quick demo? Each day after lunch we open the stage for lightning talks — short, 5-minute presentations on anything Ruby, tech, or community related.\n  date: \"2026-03-27\"\n  video_provider: \"scheduled\"\n  video_id: \"burnt-end-2-rbqconf-2026\"\n  talks: []\n\n- id: \"charles-oliver-nutter-rbqconf-2026\"\n  title: \"Expand Your Ruby with JRuby\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-27\"\n  announced_at: \"2026-01-21\"\n  description: |-\n    JRuby more than Ruby for JVM! Optimize your code, max out cores, deploy single-file apps, build portable GUIs and more. It's fun and easy with JRuby!\n  speakers:\n    - \"Charles Oliver Nutter\"\n  video_provider: \"scheduled\"\n  video_id: \"charles-oliver-nutter-rbqconf-2026\"\n\n- id: \"cristian-planas-rbqconf-2026\"\n  title: \"The Three Villains of Rails Scalability — and How to Defeat Them\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-27\"\n  announced_at: \"2026-01-24\"\n  description: |-\n    Teams often hit scaling walls with Rails and assume the framework is the problem. In reality, growth failures usually come from three structural traps that only appear once traction arrives. The difference between startups that stall and companies that reach planetary scale lies in how they confront them.\n\n    In this talk, Cristian Planas (former startup founder/CTO, former Group Tech Lead for performance at Zendesk, and author of \"Rails Scales! Practical Techniques for Performance and Growth\") reveals the three villains that silently limit your app's ability to scale. He will show how they surfaced in his own startup, why naive fixes make them worse, and what the companies operating Rails at planetary scale do differently. You'll leave with a mental model and a set of tools to defeat them before they defeat you.\n  video_provider: \"scheduled\"\n  video_id: \"cristian-planas-rbqconf-2026\"\n  speakers:\n    - \"Cristian Planas\"\n\n- id: \"nickolas-means-rbqconf-2025\"\n  title: \"Keynote: Nickolas Means\"\n  event_name: \"RBQConf 2026\"\n  date: \"2026-03-27\"\n  announced_at: \"2025-12-24\"\n  description: \"\"\n  speakers:\n    - \"Nickolas Means\"\n  video_provider: \"scheduled\"\n  video_id: \"nickolas-means-rbqconf-2025\"\n\n- id: \"closing-remarks-rbqconf-2026\"\n  title: \"Closing Remarks\"\n  date: \"2026-03-27\"\n  description: \"\"\n  speakers:\n    - TODO # RBQ MC\n  video_provider: \"scheduled\"\n  video_id: \"closing-remarks-rbqconf-2026\"\n"
  },
  {
    "path": "data/rbqconf/series.yml",
    "content": "---\nname: \"RBQ Conf\"\nwebsite: \"https://rbqconf.com\"\ntwitter: \"\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"US\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/red-dirt-rubyconf/red-dirt-rubyconf-2010/event.yml",
    "content": "---\nid: \"red-dirt-rubyconf-2010\"\ntitle: \"Red Dirt RubyConf 2010\"\nkind: \"conference\"\nlocation: \"Oklahoma City, OK, United States\"\ndescription: |-\n  Red Dirt RubyConf featured keynotes from Dave Thomas and Jim Weirich, along with tracks covering Ruby, Rails 3, NoSQL databases, and server infrastructure.\nstart_date: \"2010-05-06\"\nend_date: \"2010-05-07\"\nyear: 2010\nwebsite: \"https://web.archive.org/web/20100415015400/http://reddirtrubyconf.com\"\ncoordinates:\n  latitude: 35.4688692\n  longitude: -97.519539\n"
  },
  {
    "path": "data/red-dirt-rubyconf/red-dirt-rubyconf-2010/videos.yml",
    "content": "# Announcemnt: https://www.ruby-lang.org/en/news/2010/03/17/red-dirt-rubyconf-2010/\n---\n- id: \"jim-weirich-red-dirt-rubyconf-2010\"\n  title: \"(Parenthetically Speaking)\"\n  raw_title: \"Red Dirt RubyConf 2010 - (Parenthetically Speaking) by Jim Weirich\"\n  speakers:\n    - Jim Weirich\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Opening keynote presentation by Jim Weirich from EdgeCase.\n  video_provider: \"scheduled\"\n  video_id: \"jim-weirich-red-dirt-rubyconf-2010\"\n\n- id: \"dave-thomas-red-dirt-rubyconf-2010\"\n  title: \"Living here in hell—Ruby and the search for perfection\"\n  raw_title: \"Red Dirt RubyConf 2010 - Living here in hell—Ruby and the search for perfection by Dave Thomas\"\n  speakers:\n    - Dave Thomas\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Closing keynote presentation by Dave Thomas from The Pragmatic Programmers.\n  video_provider: \"scheduled\"\n  video_id: \"dave-thomas-red-dirt-rubyconf-2010\"\n\n# Ruby Track\n- id: \"matt-yoho-red-dirt-rubyconf-2010\"\n  title: \"Ruby and the Unix Philosophy\"\n  raw_title: \"Red Dirt RubyConf 2010 - Ruby and the Unix Philosophy by Matt Yoho\"\n  speakers:\n    - Matt Yoho\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Exploring how Ruby embodies and extends the Unix philosophy of building simple, composable tools.\n  video_provider: \"scheduled\"\n  video_id: \"matt-yoho-red-dirt-rubyconf-2010\"\n\n- id: \"tim-gourley-red-dirt-rubyconf-2010\"\n  title: \"Sinatra: Microapps Running on Rack\"\n  raw_title: \"Red Dirt RubyConf 2010 - Sinatra: Microapps Running on Rack by Tim Gourley\"\n  speakers:\n    - Tim Gourley\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Introduction to building lightweight web applications using Sinatra framework.\n  video_provider: \"scheduled\"\n  video_id: \"tim-gourley-red-dirt-rubyconf-2010\"\n\n- id: \"charles-lowell-red-dirt-rubyconf-2010\"\n  title: \"Javascript and Friends: Scripting Ruby with JavaScript for Fun and Profit\"\n  raw_title: \"Red Dirt RubyConf 2010 - Javascript and Friends: Scripting Ruby with JavaScript for Fun and Profit by Charles Lowell\"\n  speakers:\n    - Charles Lowell\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Exploring the integration of JavaScript and Ruby for enhanced application functionality.\n  video_provider: \"scheduled\"\n  video_id: \"charles-lowell-red-dirt-rubyconf-2010\"\n\n- id: \"glenn-vanderburg-red-dirt-rubyconf-2010\"\n  title: \"Design and Modularity in Ruby\"\n  raw_title: \"Red Dirt RubyConf 2010 - Design and Modularity in Ruby by Glenn Vanderburg\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Best practices for designing modular Ruby applications and managing complexity.\n  video_provider: \"scheduled\"\n  video_id: \"glenn-vanderburg-red-dirt-rubyconf-2010\"\n\n# Rails 3 Track\n- id: \"neal-ford-red-dirt-rubyconf-2010\"\n  title: \"Rails in the Large: How We're Building One of the Largest Rails Apps\"\n  raw_title: \"Red Dirt RubyConf 2010 - Rails in the Large: How We're Building One of the Largest Rails Apps by Neal Ford\"\n  speakers:\n    - Neal Ford\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Lessons learned from building enterprise-scale Rails applications at ThoughtWorks.\n  video_provider: \"scheduled\"\n  video_id: \"neal-ford-red-dirt-rubyconf-2010\"\n\n- id: \"andre-arko-red-dirt-rubyconf-2010\"\n  title: \"Bundler: Painless Dependency Management\"\n  raw_title: \"Red Dirt RubyConf 2010 - Bundler: Painless Dependency Management by Andr� Arko\"\n  speakers:\n    - André Arko\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Introduction to Bundler for managing Ruby gem dependencies in applications.\n  video_provider: \"scheduled\"\n  video_id: \"andre-arko-red-dirt-rubyconf-2010\"\n\n- id: \"marty-haught-red-dirt-rubyconf-2010\"\n  title: \"Active Record Makeover: Rekindle the relationship\"\n  raw_title: \"Red Dirt RubyConf 2010 - Active Record Makeover: Rekindle the relationship by Marty Haught\"\n  speakers:\n    - Marty Haught\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Improving your relationship with Active Record through better practices and patterns.\n  video_provider: \"scheduled\"\n  video_id: \"marty-haught-red-dirt-rubyconf-2010\"\n\n- id: \"ben-scofield-red-dirt-rubyconf-2010\"\n  title: \"With a Mighty Hammer\"\n  raw_title: \"Red Dirt RubyConf 2010 - With a Mighty Hammer by Ben Scofield\"\n  speakers:\n    - Ben Scofield\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Exploring powerful Rails techniques and when to apply them appropriately.\n  video_provider: \"scheduled\"\n  video_id: \"ben-scofield-red-dirt-rubyconf-2010\"\n\n# NoSQL Track\n- id: \"ryan-king-red-dirt-rubyconf-2010\"\n  title: \"Scaling with Cassandra\"\n  raw_title: \"Red Dirt RubyConf 2010 - Scaling with Cassandra by Ryan King\"\n  speakers:\n    - Ryan King\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    How Twitter uses Cassandra for scaling their infrastructure and handling massive data loads.\n  video_provider: \"scheduled\"\n  video_id: \"ryan-king-red-dirt-rubyconf-2010\"\n\n- id: \"kyle-banker-john-taber-red-dirt-rubyconf-2010\"\n  title: \"Data Driven Applications with Ruby and MongoDB\"\n  raw_title: \"Red Dirt RubyConf 2010 - Data Driven Applications with Ruby and MongoDB by Kyle Banker & John Taber\"\n  speakers:\n    - Kyle Banker\n    - John Taber\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Building modern data-driven applications using Ruby with MongoDB document database.\n  video_provider: \"scheduled\"\n  video_id: \"kyle-banker-john-taber-red-dirt-rubyconf-2010\"\n\n- id: \"will-leinweber-red-dirt-rubyconf-2010\"\n  title: \"CouchDB, Ruby, and You\"\n  raw_title: \"Red Dirt RubyConf 2010 - CouchDB, Ruby, and You by Will Leinweber\"\n  speakers:\n    - Will Leinweber\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Introduction to using CouchDB with Ruby for document-oriented data storage.\n  video_provider: \"scheduled\"\n  video_id: \"will-leinweber-red-dirt-rubyconf-2010\"\n\n- id: \"jeremy-hinegardner-red-dirt-rubyconf-2010\"\n  title: \"Plain Old Tokyo Storage\"\n  raw_title: \"Red Dirt RubyConf 2010 - Plain Old Tokyo Storage by Jeremy Hinegardner\"\n  speakers:\n    - Jeremy Hinegardner\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Exploring Tokyo Cabinet/Tyrant for high-performance key-value storage in Ruby applications.\n  video_provider: \"scheduled\"\n  video_id: \"jeremy-hinegardner-red-dirt-rubyconf-2010\"\n\n# Servers/Hosting Track\n- id: \"john-woodell-red-dirt-rubyconf-2010\"\n  title: \"JRuby on Google App Engine\"\n  raw_title: \"Red Dirt RubyConf 2010 - JRuby on Google App Engine by John Woodell\"\n  speakers:\n    - John Woodell\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Running JRuby applications on Google's App Engine platform.\n  video_provider: \"scheduled\"\n  video_id: \"john-woodell-red-dirt-rubyconf-2010\"\n\n- id: \"fernand-galiana-red-dirt-rubyconf-2010\"\n  title: \"Rumble in the Jungle...\"\n  raw_title: \"Red Dirt RubyConf 2010 - Rumble in the Jungle... by Fernand Galiana\"\n  speakers:\n    - Fernand Galiana\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Performance comparisons and battle testing of different Ruby deployment strategies.\n  video_provider: \"scheduled\"\n  video_id: \"fernand-galiana-red-dirt-rubyconf-2010\"\n\n- id: \"jade-meskill-red-dirt-rubyconf-2010\"\n  title: \"Redis To The Resque\"\n  raw_title: \"Red Dirt RubyConf 2010 - Redis To The Resque by Jade Meskill\"\n  speakers:\n    - Jade Meskill\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Using Redis with Resque for background job processing in Ruby applications.\n  video_provider: \"scheduled\"\n  video_id: \"jade-meskill-red-dirt-rubyconf-2010\"\n\n- id: \"corey-donohoe-red-dirt-rubyconf-2010\"\n  title: \"The Rise of DevOps\"\n  raw_title: \"Red Dirt RubyConf 2010 - The Rise of DevOps by Corey Donohoe\"\n  speakers:\n    - Corey Donohoe\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-06\"\n  language: \"en\"\n  description: |-\n    Understanding the emerging DevOps culture and its impact on Ruby development workflows.\n  video_provider: \"scheduled\"\n  video_id: \"corey-donohoe-red-dirt-rubyconf-2010\"\n\n# Training Sessions (Day 2)\n- id: \"james-gray-glenn-vanderburg-red-dirt-rubyconf-2010\"\n  title: \"The Ruby Your Mother Warned You About\"\n  raw_title: \"Red Dirt RubyConf 2010 - The Ruby Your Mother Warned You About by James Edward Gray II & Glenn Vanderburg\"\n  speakers:\n    - James Edward Gray II\n    - Glenn Vanderburg\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-07\"\n  language: \"en\"\n  description: |-\n    Training session examining scary Ruby code patterns and how to improve them through better Ruby practices.\n  video_provider: \"scheduled\"\n  video_id: \"james-gray-glenn-vanderburg-red-dirt-rubyconf-2010\"\n\n- id: \"gregg-pollack-red-dirt-rubyconf-2010\"\n  title: \"The Rails 3 Ropes Course\"\n  raw_title: \"Red Dirt RubyConf 2010 - The Rails 3 Ropes Course by Gregg Pollack\"\n  speakers:\n    - Gregg Pollack\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-07\"\n  language: \"en\"\n  description: |-\n    Hands-on training covering the core concepts and new features in Rails 3.\n  video_provider: \"scheduled\"\n  video_id: \"gregg-pollack-red-dirt-rubyconf-2010\"\n\n- id: \"sean-cribbs-red-dirt-rubyconf-2010\"\n  title: \"Introduction to Riak\"\n  raw_title: \"Red Dirt RubyConf 2010 - Introduction to Riak by Sean Cribbs\"\n  speakers:\n    - Sean Cribbs\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-07\"\n  language: \"en\"\n  description: |-\n    Training session on Riak, a distributed document-oriented database with map/reduce capabilities.\n  video_provider: \"scheduled\"\n  video_id: \"sean-cribbs-red-dirt-rubyconf-2010\"\n\n- id: \"jim-mulholland-jason-derrett-red-dirt-rubyconf-2010\"\n  title: \"Living Among the Clouds\"\n  raw_title: \"Red Dirt RubyConf 2010 - Living Among the Clouds by Jim Mulholland & Jason Derrett\"\n  speakers:\n    - Jim Mulholland\n    - Jason Derrett\n  event_name: \"Red Dirt RubyConf 2010\"\n  date: \"2010-05-07\"\n  language: \"en\"\n  description: |-\n    Training on deploying Ruby applications to cloud platforms including Heroku, EngineYard, and Amazon EC2.\n  video_provider: \"scheduled\"\n  video_id: \"jim-mulholland-jason-derrett-red-dirt-rubyconf-2010\"\n"
  },
  {
    "path": "data/red-dirt-rubyconf/red-dirt-rubyconf-2011/event.yml",
    "content": "---\nid: \"red-dirt-rubyconf-2011\"\ntitle: \"Red Dirt RubyConf 2011\"\nkind: \"conference\"\nlocation: \"Oklahoma City, OK, United States\"\ndescription: |-\n  A content-rich two-day conference featuring tracks on Ruby Implementations, Rails Extensions, Rails Redux, and JavaScript, plus training sessions and open source contribution tracks.\nstart_date: \"2011-04-21\"\nend_date: \"2011-04-22\"\nyear: 2011\nwebsite: \"https://web.archive.org/web/20110323065201/http://reddirtrubyconf.com\"\nfeatured_background: \"#EE4538\"\nbanner_background: \"#EE4538\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 35.4688692\n  longitude: -97.519539\n"
  },
  {
    "path": "data/red-dirt-rubyconf/red-dirt-rubyconf-2011/videos.yml",
    "content": "---\n# Red Dirt RubyConf 2011\n# April 21-22, 2011 - Oklahoma City, OK\n# Website: https://web.archive.org/web/20110323065201/http://reddirtrubyconf.com/\n\n# Day 1 - April 21, 2011\n\n# Keynotes\n- id: \"aaron-patterson-red-dirt-rubyconf-2011-keynote\"\n  title: \"Opening Keynote\"\n  raw_title: \"Red Dirt RubyConf 2011 - Opening Keynote by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Opening keynote presentation by Aaron Patterson from AT&T Interactive.\n  video_provider: \"not_recorded\"\n  video_id: \"aaron-patterson-red-dirt-rubyconf-2011-keynote\"\n\n# Ruby Implementations Track\n- id: \"wayne-seguin-red-dirt-rubyconf-2011\"\n  title: \"wayneeseguin on Rubinius\"\n  raw_title: \"Red Dirt RubyConf 2011 - wayneeseguin on Rubinius by Wayne E. Seguin\"\n  speakers:\n    - Wayne E. Seguin\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Deep dive into Rubinius, an implementation of Ruby designed for concurrency.\n  video_provider: \"not_recorded\"\n  video_id: \"wayne-seguin-red-dirt-rubyconf-2011\"\n\n- id: \"matt-kirk-red-dirt-rubyconf-2011\"\n  title: \"Katy Perry and Trend Detection Using JRuby\"\n  raw_title: \"Red Dirt RubyConf 2011 - Katy Perry and Trend Detection Using JRuby by Matt Kirk\"\n  speakers:\n    - Matt Kirk\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Using JRuby for trend detection and analysis in social media and pop culture.\n  video_provider: \"not_recorded\"\n  video_id: \"matt-kirk-red-dirt-rubyconf-2011\"\n\n- id: \"erik-michaels-ober-macruby-red-dirt-rubyconf-2011\"\n  title: \"GUI Programming with MacRuby\"\n  raw_title: \"Red Dirt RubyConf 2011 - GUI Programming with MacRuby by Erik Michaels-Ober\"\n  speakers:\n    - Erik Michaels-Ober\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Building graphical user interfaces for Mac applications using MacRuby.\n  video_provider: \"not_recorded\"\n  video_id: \"erik-michaels-ober-macruby-red-dirt-rubyconf-2011\"\n\n- id: \"jeremy-mcanally-red-dirt-rubyconf-2011\"\n  title: \"2,412 Things You Were Not Aware MacRuby Could Do\"\n  raw_title: \"Red Dirt RubyConf 2011 - 2,412 Things You Were Not Aware MacRuby Could Do by Jeremy McAnally\"\n  speakers:\n    - Jeremy McAnally\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Exploring the extensive capabilities and hidden features of MacRuby.\n  video_provider: \"not_recorded\"\n  video_id: \"jeremy-mcanally-red-dirt-rubyconf-2011\"\n\n# Rails 3 Extensions Track\n- id: \"michael-bleigh-red-dirt-rubyconf-2011\"\n  title: \"OmniAuth From The Ground Up\"\n  raw_title: \"Red Dirt RubyConf 2011 - OmniAuth From The Ground Up by Michael Bleigh\"\n  speakers:\n    - Michael Bleigh\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Building authentication systems with OmniAuth from scratch.\n  video_provider: \"not_recorded\"\n  video_id: \"michael-bleigh-red-dirt-rubyconf-2011\"\n\n- id: \"karmajunkie-red-dirt-rubyconf-2011\"\n  title: \"Formtastic: Lose the zero and get with the hero!\"\n  raw_title: \"Red Dirt RubyConf 2011 - Formtastic: Lose the zero and get with the hero! by karmajunkie\"\n  speakers:\n    - karmajunkie\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Simplifying Rails form creation with Formtastic.\n  video_provider: \"not_recorded\"\n  video_id: \"karmajunkie-red-dirt-rubyconf-2011\"\n\n- id: \"gerred-dillon-red-dirt-rubyconf-2011\"\n  title: \"Reimagining Rails Messaging\"\n  raw_title: \"Red Dirt RubyConf 2011 - Reimagining Rails Messaging by Gerred Dillon\"\n  speakers:\n    - Gerred Dillon\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Rethinking messaging and communication patterns in Rails applications.\n  video_provider: \"not_recorded\"\n  video_id: \"gerred-dillon-red-dirt-rubyconf-2011\"\n\n- id: \"bradley-grzesiak-red-dirt-rubyconf-2011\"\n  title: \"Haml and Compass: Pure, Uncut Awesome\"\n  raw_title: \"Red Dirt RubyConf 2011 - Haml and Compass: Pure, Uncut Awesome by Bradley Grzesiak\"\n  speakers:\n    - Bradley Grzesiak\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Leveraging Haml and Compass for cleaner markup and stylesheets.\n  video_provider: \"not_recorded\"\n  video_id: \"bradley-grzesiak-red-dirt-rubyconf-2011\"\n\n# Rails Redux Track\n- id: \"adam-keys-red-dirt-rubyconf-2011\"\n  title: \"Mixing a tasty persistence cocktail\"\n  raw_title: \"Red Dirt RubyConf 2011 - Mixing a tasty persistence cocktail by Adam Keys\"\n  speakers:\n    - Adam Keys\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Combining different persistence strategies for optimal data storage.\n  video_provider: \"not_recorded\"\n  video_id: \"adam-keys-red-dirt-rubyconf-2011\"\n\n- id: \"avdi-grimm-red-dirt-rubyconf-2011\"\n  title: \"Cheating on ActiveRecord with DataMapper\"\n  raw_title: \"Red Dirt RubyConf 2011 - Cheating on ActiveRecord with DataMapper by Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Exploring DataMapper as an alternative ORM for Ruby applications.\n  video_provider: \"not_recorded\"\n  video_id: \"avdi-grimm-red-dirt-rubyconf-2011\"\n\n- id: \"jeff-casimir-red-dirt-rubyconf-2011\"\n  title: \"Fat Models Aren't Enough\"\n  raw_title: \"Red Dirt RubyConf 2011 - Fat Models Aren't Enough by Jeff Casimir\"\n  speakers:\n    - Jeff Casimir\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Going beyond fat models to create maintainable Rails applications.\n  video_provider: \"not_recorded\"\n  video_id: \"jeff-casimir-red-dirt-rubyconf-2011\"\n\n- id: \"james-coglan-red-dirt-rubyconf-2011\"\n  title: \"Never sweep your cache again!\"\n  raw_title: \"Red Dirt RubyConf 2011 - Never sweep your cache again! by James Coglan\"\n  speakers:\n    - James Coglan\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Advanced caching strategies for Rails applications.\n  video_provider: \"not_recorded\"\n  video_id: \"james-coglan-red-dirt-rubyconf-2011\"\n\n# JavaScript Track\n- id: \"ryan-mcgeary-red-dirt-rubyconf-2011\"\n  title: \"Introduction to CoffeeScript\"\n  raw_title: \"Red Dirt RubyConf 2011 - Introduction to CoffeeScript by Ryan McGeary\"\n  speakers:\n    - Ryan McGeary\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Getting started with CoffeeScript for cleaner JavaScript code.\n  video_provider: \"not_recorded\"\n  video_id: \"ryan-mcgeary-red-dirt-rubyconf-2011\"\n\n- id: \"kevin-whinnery-titanium-red-dirt-rubyconf-2011\"\n  title: \"Titanium on Rails\"\n  raw_title: \"Red Dirt RubyConf 2011 - Titanium on Rails by Kevin Whinnery\"\n  speakers:\n    - Kevin Whinnery\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Building mobile applications with Titanium and Rails backends.\n  video_provider: \"not_recorded\"\n  video_id: \"kevin-whinnery-titanium-red-dirt-rubyconf-2011\"\n\n- id: \"noel-rappin-red-dirt-rubyconf-2011\"\n  title: \"Using BDD in JavaScript from Ruby\"\n  raw_title: \"Red Dirt RubyConf 2011 - Using BDD in JavaScript from Ruby by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Applying behavior-driven development practices to JavaScript with Ruby tools.\n  video_provider: \"not_recorded\"\n  video_id: \"noel-rappin-red-dirt-rubyconf-2011\"\n\n- id: \"tim-caswell-red-dirt-rubyconf-2011\"\n  title: \"Ruby/JavaScript Synergy on the Server\"\n  raw_title: \"Red Dirt RubyConf 2011 - Ruby/JavaScript Synergy on the Server by Tim Caswell\"\n  speakers:\n    - Tim Caswell\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Combining Ruby and JavaScript for server-side development.\n  video_provider: \"not_recorded\"\n  video_id: \"tim-caswell-red-dirt-rubyconf-2011\"\n\n# Day 2 - April 22, 2011\n\n# Morning Training Sessions\n- id: \"ryan-smith-red-dirt-rubyconf-2011\"\n  title: \"The Worker Pattern: Scaling Horizontally\"\n  raw_title: \"Red Dirt RubyConf 2011 - The Worker Pattern: Scaling Horizontally by ryan smith\"\n  speakers:\n    - Ryan Smith\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-22\"\n  language: \"en\"\n  description: |-\n    Training session on using worker patterns for horizontal scaling in Ruby applications.\n  video_provider: \"not_recorded\"\n  video_id: \"ryan-smith-red-dirt-rubyconf-2011\"\n\n- id: \"gregory-brown-red-dirt-rubyconf-2011\"\n  title: \"module Ruby; extend self; end\"\n  raw_title: \"Red Dirt RubyConf 2011 - module Ruby; extend self; end by Gregory Brown\"\n  speakers:\n    - Gregory Brown\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-22\"\n  language: \"en\"\n  description: |-\n    Deep dive into Ruby modules and metaprogramming techniques.\n  video_provider: \"not_recorded\"\n  video_id: \"gregory-brown-red-dirt-rubyconf-2011\"\n\n- id: \"kevin-whinnery-training-red-dirt-rubyconf-2011\"\n  title: \"From Zero-to-App with Titanium and CoffeeScript\"\n  raw_title: \"Red Dirt RubyConf 2011 - From Zero-to-App with Titanium and CoffeeScript by Kevin Whinnery\"\n  speakers:\n    - Kevin Whinnery\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-22\"\n  language: \"en\"\n  description: |-\n    Training session on building mobile apps from scratch with Titanium and CoffeeScript.\n  video_provider: \"not_recorded\"\n  video_id: \"kevin-whinnery-training-red-dirt-rubyconf-2011\"\n\n# Afternoon Training Sessions\n- id: \"james-gray-red-dirt-rubyconf-2011\"\n  title: \"Optimizing Rails 3 Applications\"\n  raw_title: \"Red Dirt RubyConf 2011 - Optimizing Rails 3 Applications by James Edward Gray II\"\n  speakers:\n    - James Edward Gray II\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-22\"\n  language: \"en\"\n  description: |-\n    Training session on performance optimization techniques for Rails 3 applications.\n  video_provider: \"not_recorded\"\n  video_id: \"james-gray-red-dirt-rubyconf-2011\"\n\n- id: \"wesley-beary-red-dirt-rubyconf-2011\"\n  title: \"Ruby + Cloud = Fog\"\n  raw_title: \"Red Dirt RubyConf 2011 - Ruby + Cloud = Fog by Wesley Beary\"\n  speakers:\n    - Wesley Beary\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-22\"\n  language: \"en\"\n  description: |-\n    Using the Fog library for cloud computing with Ruby.\n  video_provider: \"not_recorded\"\n  video_id: \"wesley-beary-red-dirt-rubyconf-2011\"\n\n- id: \"tyler-jennings-red-dirt-rubyconf-2011\"\n  title: \"JRuby for the Ruby Developer\"\n  raw_title: \"Red Dirt RubyConf 2011 - JRuby for the Ruby Developer by Tyler Jennings\"\n  speakers:\n    - Tyler Jennings\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-22\"\n  language: \"en\"\n  description: |-\n    Training session on JRuby for Ruby developers.\n  video_provider: \"not_recorded\"\n  video_id: \"tyler-jennings-red-dirt-rubyconf-2011\"\n\n# Open Source Contribution Sessions\n- id: \"erik-michaels-ober-opensource-red-dirt-rubyconf-2011\"\n  title: \"Cultivating an open-source community\"\n  raw_title: \"Red Dirt RubyConf 2011 - Cultivating an open-source community by Erik Michaels-Ober\"\n  speakers:\n    - Erik Michaels-Ober\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-22\"\n  language: \"en\"\n  description: |-\n    Building and nurturing open source communities around Ruby projects.\n  video_provider: \"not_recorded\"\n  video_id: \"erik-michaels-ober-opensource-red-dirt-rubyconf-2011\"\n\n- id: \"dan-lucraft-red-dirt-rubyconf-2011\"\n  title: \"Redcar: Hacking your editor in Ruby\"\n  raw_title: \"Red Dirt RubyConf 2011 - Redcar: Hacking your editor in Ruby by Dan Lucraft\"\n  speakers:\n    - Dan Lucraft\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-22\"\n  language: \"en\"\n  description: |-\n    Contributing to Redcar, a Ruby-based text editor.\n  video_provider: \"not_recorded\"\n  video_id: \"dan-lucraft-red-dirt-rubyconf-2011\"\n\n- id: \"brian-ford-red-dirt-rubyconf-2011\"\n  title: \"The Joy of Rubinius, the Agony of RubySpec\"\n  raw_title: \"Red Dirt RubyConf 2011 - The Joy of Rubinius, the Agony of RubySpec by Brian Ford\"\n  speakers:\n    - Brian Ford\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-22\"\n  language: \"en\"\n  description: |-\n    Contributing to Rubinius and RubySpec for Ruby implementation testing.\n  video_provider: \"not_recorded\"\n  video_id: \"brian-ford-red-dirt-rubyconf-2011\"\n\n- id: \"nick-quaranto-red-dirt-rubyconf-2011\"\n  title: \"2011: A Gemcutter Odyssey\"\n  raw_title: \"Red Dirt RubyConf 2011 - 2011: A Gemcutter Odyssey by Nick Quaranto\"\n  speakers:\n    - Nick Quaranto\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-22\"\n  language: \"en\"\n  description: |-\n    The evolution and future of RubyGems.org (Gemcutter).\n  video_provider: \"not_recorded\"\n  video_id: \"nick-quaranto-red-dirt-rubyconf-2011\"\n\n- id: \"dr-nic-williams-red-dirt-rubyconf-2011-keynote\"\n  title: \"Closing Keynote\"\n  raw_title: \"Red Dirt RubyConf 2011 - Closing Keynote by Dr Nic Williams\"\n  speakers:\n    - Dr. Nic Williams\n  event_name: \"Red Dirt RubyConf 2011\"\n  date: \"2011-04-21\"\n  language: \"en\"\n  description: |-\n    Closing keynote presentation by Dr Nic Williams from Engine Yard.\n  video_provider: \"not_recorded\"\n  video_id: \"dr-nic-williams-red-dirt-rubyconf-2011-keynote\"\n"
  },
  {
    "path": "data/red-dirt-rubyconf/series.yml",
    "content": "---\nname: \"Red Dirt RubyConf\"\nwebsite: \"http://reddirtrubyconf.com\"\ntwitter: \"reddirtrubyconf\"\nyoutube_channel_name: \"Confreaks\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Red Dirt RubyConf\"\ndefault_country_code: \"US\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2011/event.yml",
    "content": "---\nid: \"red-dot-ruby-conference-2011\"\ntitle: \"Red Dot Ruby Conference 2011\"\nkind: \"conference\"\nlocation: \"Singapore, Singapore\"\ndescription: |-\n  south east asia’s first ruby & rails conference… because it’s about time • April 22nd–23rd 2011 • Singapore\npublished_at: \"2011-04-23\"\nstart_date: \"2011-04-22\"\nend_date: \"2011-04-23\"\nchannel_id: \"UCjRZr5HQKHVKP3SZdX8y8Qw\"\nyear: 2011\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#282F39\"\nwebsite: \"https://web.archive.org/web/20110818192535/http://reddotrubyconf.com/\"\ncoordinates:\n  latitude: 1.352083\n  longitude: 103.819836\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2011/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20110818192535/http://reddotrubyconf.com/\n# Schedule: https://web.archive.org/web/20110818192535/http://reddotrubyconf.com/\n\n## Day 1 - \"2011-04-22\"\n\n# Registration\n\n- id: \"andy-croll-red-dot-ruby-conference-2011\"\n  title: \"Welcome\"\n  raw_title: \"Welcome by Andy Croll, Anideo\"\n  speakers:\n    - Andy Croll\n  date: \"2011-04-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"andy-croll-red-dot-ruby-conference-2011\"\n  description: \"\"\n\n- id: \"yukihiro-matsumoto-red-dot-ruby-conference-2011\"\n  title: \"Keynote: The Future of Ruby\"\n  raw_title: \"The Future of Ruby by Matz\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  date: \"2011-04-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"yukihiro-matsumoto-red-dot-ruby-conference-2011\"\n  description: \"\"\n\n# Quick Break\n\n- id: \"ian-mcfarland-red-dot-ruby-conference-2011\"\n  title: \"Agile the Pivotal Way\"\n  raw_title: \"Agile the Pivotal Way by Ian McFarland, Pivotal Labs\"\n  speakers:\n    - Ian McFarland\n  date: \"2011-04-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"ian-mcfarland-red-dot-ruby-conference-2011\"\n  description: \"\"\n\n- id: \"mikel-lindsaar-red-dot-ruby-conference-2011\"\n  title: \"Ruby can haz everyone\"\n  raw_title: \"Ruby can haz everyone by Mikel Lindsaar, RubyX\"\n  speakers:\n    - Mikel Lindsaar\n  date: \"2011-04-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"mikel-lindsaar-red-dot-ruby-conference-2011\"\n  description: \"\"\n\n# Lunch\n\n- id: \"sau-sheong-chang-red-dot-ruby-conference-2011\"\n  title: \"Ruby & R\"\n  raw_title: \"Ruby & R by Sau Sheong Chang, HP Labs\"\n  speakers:\n    - Sau Sheong Chang\n  date: \"2011-04-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"sau-sheong-chang-red-dot-ruby-conference-2011\"\n  description: \"\"\n\n- id: \"nate-clark-red-dot-ruby-conference-2011\"\n  title: \"Testing the Right Stuff\"\n  raw_title: \"Testing the Right Stuff by Nate Clark, Pivotal Labs\"\n  speakers:\n    - Nate Clark\n  date: \"2011-04-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"nate-clark-red-dot-ruby-conference-2011\"\n  description: \"\"\n\n- id: \"robert-berger-red-dot-ruby-conference-2011\"\n  title: \"Deploying Infrastructure with Opscode Chef\"\n  raw_title: \"Deploying Infrastructure with Opscode Chef by Robert Berger, Runa\"\n  speakers:\n    - Robert Berger\n  date: \"2011-04-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"robert-berger-red-dot-ruby-conference-2011\"\n  description: \"\"\n\n# Break\n\n- id: \"paul-gallagher-red-dot-ruby-conference-2011\"\n  title: \"Houseparty, slumlord, or mogul? Multi-tenancy with Rails\"\n  raw_title: \"Houseparty, slumlord, or mogul? Multi-tenancy with Rails by Paul Gallagher, Evendis\"\n  speakers:\n    - Paul Gallagher\n  date: \"2011-04-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"paul-gallagher-red-dot-ruby-conference-2011\"\n  description: \"\"\n\n- id: \"gautam-rege-red-dot-ruby-conference-2011\"\n  title: \"Outsourcing & Rails\"\n  raw_title: \"Outsourcing & Rails by Gautam Rege, Josh Software\"\n  speakers:\n    - Gautam Rege\n  date: \"2011-04-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"gautam-rege-red-dot-ruby-conference-2011\"\n  description: \"\"\n\n- id: \"andras-kristof-red-dot-ruby-conference-2011\"\n  title: \"Agile IRL\"\n  raw_title: \"Agile IRL by Andras Kristof, ViKi\"\n  speakers:\n    - Andras Kristof\n  date: \"2011-04-22\"\n  video_provider: \"not_recorded\"\n  video_id: \"andras-kristof-red-dot-ruby-conference-2011\"\n  description: \"\"\n\n# Pecha Kucha SG\n\n## Day 2 - \"2011-04-23\"\n\n- id: \"jason-ong-red-dot-ruby-conference-2011\"\n  title: \"Welcome Back\"\n  raw_title: \"Welcome Back by Jason Ong\"\n  speakers:\n    - Jason Ong\n  date: \"2011-04-23\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"jason-ong-red-dot-ruby-conference-2011\"\n\n- id: \"dave-thomas-red-dot-ruby-conference-2011\"\n  title: \"Keynote\"\n  raw_title: \"Keynote by Dave Thomas, Pragmatic Programmers\"\n  speakers:\n    - Dave Thomas\n  date: \"2011-04-23\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"dave-thomas-red-dot-ruby-conference-2011\"\n\n# Quick Break\n\n- id: \"tom-preston-werner-red-dot-ruby-conference-2011\"\n  title: \"Advanced Git Techniques\"\n  raw_title: \"Advanced Git Techniques by Tom Preston-Werner, GitHub\"\n  speakers:\n    - Tom Preston-Werner\n  date: \"2011-04-23\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"tom-preston-werner-red-dot-ruby-conference-2011\"\n\n- id: \"gregg-pollack-red-dot-ruby-conference-2011\"\n  title: \"Under the Covers with Rails 3\"\n  raw_title: \"Under the Covers with Rails 3 by Gregg Pollack, Envy Labs\"\n  speakers:\n    - Gregg Pollack\n  date: \"2011-04-23\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"gregg-pollack-red-dot-ruby-conference-2011\"\n\n# Lunch\n\n- id: \"ryan-bigg-red-dot-ruby-conference-2011\"\n  title: \"How to be Awesome at Rails\"\n  raw_title: \"How to be Awesome at Rails by Ryan Bigg, RubyX\"\n  speakers:\n    - Ryan Bigg\n  date: \"2011-04-23\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"ryan-bigg-red-dot-ruby-conference-2011\"\n\n- id: \"tze-yang-ng-red-dot-ruby-conference-2011\"\n  title: \"A Rubyist’s Guide to Smalltalk\"\n  raw_title: \"A Rubyist’s Guide to Smalltalk by Tze Yang Ng\"\n  speakers:\n    - Tze Yang Ng\n  date: \"2011-04-23\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"tze-yang-ng-red-dot-ruby-conference-2011\"\n\n- id: \"matt-jacobs-red-dot-ruby-conference-2011\"\n  title: \"Building a Financial App in Rails\"\n  raw_title: \"Building a Financial App in Rails by Matt Jacobs, Thoughtsauce\"\n  speakers:\n    - Matt Jacobs\n  date: \"2011-04-23\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"matt-jacobs-red-dot-ruby-conference-2011\"\n\n# Break\n\n- id: \"alex-nguyen-red-dot-ruby-conference-2011\"\n  title: \"Flexible & Adaptable to Change: MongoDB\"\n  raw_title: \"Flexible & Adaptable to Change: MongoDB by Alex Nguyen, Vinova\"\n  speakers:\n    - Alex Nguyen\n  date: \"2011-04-23\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"alex-nguyen-red-dot-ruby-conference-2011\"\n\n- id: \"alam-kasenally-red-dot-ruby-conference-2011\"\n  title: \"Customer Development with Rails\"\n  raw_title: \"Customer Development with Rails by Alam Kasenally, PlayMoolah\"\n  speakers:\n    - Alam Kasenally\n  date: \"2011-04-23\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"alam-kasenally-red-dot-ruby-conference-2011\"\n\n- id: \"chris-boesch-red-dot-ruby-conference-2011\"\n  title: \"Programming Competition (with prizes!)\"\n  raw_title: \"Programming Competition (with prizes!) by Chris Boesch, SMU\"\n  speakers:\n    - Chris Boesch\n  date: \"2011-04-23\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"chris-boesch-red-dot-ruby-conference-2011\"\n# Hiring Fair\n\n# Afterparty (sponsored by GitHub)\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2012/event.yml",
    "content": "---\nid: \"red-dot-ruby-conference-2012\"\ntitle: \"Red Dot Ruby Conference 2012\"\nkind: \"conference\"\nlocation: \"Singapore, Singapore\"\ndescription: |-\n  May 18th—19th 2012 • Singapore\npublished_at: \"2012-05-19\"\nstart_date: \"2012-05-18\"\nend_date: \"2012-05-19\"\nchannel_id: \"UCjRZr5HQKHVKP3SZdX8y8Qw\"\nyear: 2012\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#282F39\"\nwebsite: \"https://web.archive.org/web/20120921204836/http://reddotrubyconf.com/\"\ncoordinates:\n  latitude: 1.352083\n  longitude: 103.819836\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2012/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20120921204836/http://reddotrubyconf.com/\n# Schedule: https://web.archive.org/web/20120921204836/http://reddotrubyconf.com/\n\n## Day 1 - May 18th 2012\n\n- id: \"andy-croll-welcome-red-dot-ruby-conf-2012\"\n  title: \"Welcome\"\n  raw_title: \"Welcome by Andy Croll\"\n  speakers:\n    - Andy Croll\n  date: \"2012-05-18\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"andy-croll-welcome-red-dot-ruby-conf-2012\"\n\n- id: \"ilya-grigorik-red-dot-ruby-conf-2012\"\n  title: \"Building a Faster Web, at Google and Beyond\"\n  raw_title: \"Building a Faster Web, at Google and Beyond by Ilya Grigorik\"\n  speakers:\n    - Ilya Grigorik\n  date: \"2012-05-18\"\n  description: |-\n    Learn from running Google services at scale, including the research, projects, and open sourced tools we've developed in the process: HTTP Archive, SPDY, PageSpeed services, Closure and more.\n  video_provider: \"not_recorded\"\n  video_id: \"ilya-grigorik-red-dot-ruby-conf-2012\"\n\n- id: \"richard-schneeman-red-dot-ruby-conf-2012\"\n  title: \"The 12 Factor App\"\n  raw_title: \"The 12 Factor App by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  date: \"2012-05-18\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"richard-schneeman-red-dot-ruby-conf-2012\"\n\n- id: \"thorben-schroder-red-dot-ruby-conf-2012\"\n  title: \"Building Web Services with a PUBSUB Infrastructure\"\n  raw_title: \"Building Web Services with a PUBSUB Infrastructure by Thorben Schroder\"\n  speakers:\n    - Thorben Schroder\n  date: \"2012-05-18\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"thorben-schroder-red-dot-ruby-conf-2012\"\n\n- id: \"andras-kristof-continuous-performance-testing-red-dot-ruby-conf-2012\"\n  title: \"Continuous Performance Testing\"\n  raw_title: \"Continuous Performance Testing by Andras Kristof\"\n  speakers:\n    - Andras Kristof\n  date: \"2012-05-18\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"andras-kristof-continuous-performance-testing-red-dot-ruby-conf-2012\"\n\n# Lunch\n\n- id: \"danish-khan-red-dot-ruby-conf-2012\"\n  title: \"The Γυβψ Community\"\n  raw_title: \"The Γυβψ Community by Danish Khan\"\n  speakers:\n    - Danish Khan\n  date: \"2012-05-18\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"danish-khan-red-dot-ruby-conf-2012\"\n\n- id: \"sau-sheong-chang-red-dot-ruby-conf-2012\"\n  title: \"Ruby, Rock & Roll\"\n  raw_title: \"Ruby, Rock & Roll by Sau Sheong Chang\"\n  speakers:\n    - Sau Sheong Chang\n  date: \"2012-05-18\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"sau-sheong-chang-red-dot-ruby-conf-2012\"\n\n- id: \"winston-teo-red-dot-ruby-conf-2012\"\n  title: \"CSS Testing: Designs Can Be Tested Too\"\n  raw_title: \"CSS Testing: Designs Can Be Tested Too by Winston Teo\"\n  speakers:\n    - Winston Teo\n  date: \"2012-05-18\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"winston-teo-red-dot-ruby-conf-2012\"\n\n- id: \"hemant-kumar-red-dot-ruby-conf-2012\"\n  title: \"Dive inside Ruby 1.9\"\n  raw_title: \"Dive inside Ruby 1.9 by Hemant Kumar\"\n  speakers:\n    - Hemant Kumar\n  date: \"2012-05-18\"\n  description: |-\n    Ruby 1.9 from inside: how has the VM changed? How it does GC, how it does Object allocation, how it does threading. The works.\n  video_provider: \"not_recorded\"\n  video_id: \"hemant-kumar-red-dot-ruby-conf-2012\"\n\n- id: \"tim-oxley-red-dot-ruby-conf-2012\"\n  title: \"Client-side Templating for Reactive UI\"\n  raw_title: \"Client-side Templating for Reactive UI by Tim Oxley\"\n  speakers:\n    - Tim Oxley\n  date: \"2012-05-18\"\n  description: |-\n    Explore the implic­a­tions & philosophy of client-side ren­der­ing & templating: such as jQuery tem­plates, EJS, Under­score and Handle­bars\n  video_provider: \"not_recorded\"\n  video_id: \"tim-oxley-red-dot-ruby-conf-2012\"\n\n- id: \"wei-lu-red-dot-ruby-conf-2012\"\n  title: \"A Journey into Pair Programming\"\n  raw_title: \"A Journey into Pair Programming by Wei Lu\"\n  speakers:\n    - Wei Lu\n  date: \"2012-05-18\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"wei-lu-red-dot-ruby-conf-2012\"\n\n## Day 2 - May 19th 2012\n\n- id: \"andy-croll-welcome-back-red-dot-ruby-conf-2012\"\n  title: \"Welcome Back\"\n  raw_title: \"Welcome Back by Andy Croll\"\n  speakers:\n    - Andy Croll\n  date: \"2012-05-19\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"andy-croll-welcome-back-red-dot-ruby-conf-2012\"\n\n- id: \"obie-fernandez-red-dot-ruby-conf-2012\"\n  title: \"Redis on Ruby\"\n  raw_title: \"Redis on Ruby by Obie Fernandez\"\n  speakers:\n    - Obie Fernandez\n  date: \"2012-05-19\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"obie-fernandez-red-dot-ruby-conf-2012\"\n\n- id: \"zach-holman-red-dot-ruby-conf-2012\"\n  title: \"Git Secrets\"\n  raw_title: \"Git Secrets by Zach Holman\"\n  speakers:\n    - Zach Holman\n  date: \"2012-05-19\"\n  description: |-\n    About five million tiny pieces of source-control awesome.\n  video_provider: \"not_recorded\"\n  video_id: \"zach-holman-red-dot-ruby-conf-2012\"\n\n- id: \"terence-lee-red-dot-ruby-conf-2012\"\n  title: \"`bundle install`: Y U SO SLOW\"\n  raw_title: \"`bundle install`: Y U SO SLOW by Terence Lee\"\n  speakers:\n    - Terence Lee\n  date: \"2012-05-19\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"terence-lee-red-dot-ruby-conf-2012\"\n\n# Lunch\n\n- id: \"carl-coryell-martin-red-dot-ruby-conf-2012\"\n  title: \"Computer Scientist, Developer, or Engineer?\"\n  raw_title: \"Computer Scientist, Developer, or Engineer? by Carl Coryell-Martin\"\n  speakers:\n    - Carl Coryell-Martin\n  date: \"2012-05-19\"\n  description: |-\n    Getting paid to build human civilization.\n  video_provider: \"not_recorded\"\n  video_id: \"carl-coryell-martin-red-dot-ruby-conf-2012\"\n\n- id: \"sebastian-burkhard-red-dot-ruby-conf-2012\"\n  title: \"Complex Calculations Within a Web Request\"\n  raw_title: \"Complex Calculations Within a Web Request by Sebastian Burkhard\"\n  speakers:\n    - Sebastian Burkhard\n  date: \"2012-05-19\"\n  description: |-\n    Ruby is slow; therefore, we let complex calculations run outside a web request using tools like delayed_job or extract them to C/Java code. But what if these two options are not available?\n  video_provider: \"not_recorded\"\n  video_id: \"sebastian-burkhard-red-dot-ruby-conf-2012\"\n\n- id: \"gabe-hollombe-red-dot-ruby-conf-2012\"\n  title: \"Level Up and Switch from JS to CoffeeScript\"\n  raw_title: \"Level Up and Switch from JS to CoffeeScript by Gabe Hollombe\"\n  speakers:\n    - Gabe Hollombe\n  date: \"2012-05-19\"\n  description: |-\n    These days, if you're working on anything web-related, you're almost certainly going to need to write some JavaScript. But if you're still writing vanilla JS, you're missing out on a lot of really compelling features that will help you write better code.\n  video_provider: \"not_recorded\"\n  video_id: \"gabe-hollombe-red-dot-ruby-conf-2012\"\n\n- id: \"darcy-laycock-red-dot-ruby-conf-2012\"\n  title: \"API-Driven Development\"\n  raw_title: \"API-Driven Development by Darcy Laycock\"\n  speakers:\n    - Darcy Laycock\n  date: \"2012-05-19\"\n  description: |-\n    A guide to modern approaches for building APIs as the core of an application for use behind things such as mobile apps.\n  video_provider: \"not_recorded\"\n  video_id: \"darcy-laycock-red-dot-ruby-conf-2012\"\n\n- id: \"michael-koziarski-red-dot-ruby-conf-2012\"\n  title: \"Lessons From the Other Side: Effectively Contributing to Open Source\"\n  raw_title: \"Lessons From the Other Side: Effectively Contributing to Open Source by Michael Koziarski\"\n  speakers:\n    - Michael Koziarski\n  date: \"2012-05-19\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"michael-koziarski-red-dot-ruby-conf-2012\"\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2013/event.yml",
    "content": "---\nid: \"red-dot-ruby-conference-2013\"\ntitle: \"Red Dot Ruby Conference 2013\"\nkind: \"conference\"\nlocation: \"Singapore, Singapore\"\ndescription: |-\n  June 7-8, 2013 • Singapore\npublished_at: \"2013-06-08\"\nstart_date: \"2013-06-07\"\nend_date: \"2013-06-08\"\nchannel_id: \"UCjRZr5HQKHVKP3SZdX8y8Qw\"\nyear: 2013\nbanner_background: \"#E58581\"\nfeatured_background: \"#E58581\"\nfeatured_color: \"#282F39\"\nwebsite: \"https://web.archive.org/web/20161015140654/https://rdrc2013.herokuapp.com/\"\ncoordinates:\n  latitude: 1.352083\n  longitude: 103.819836\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2013/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20161015140654/https://rdrc2013.herokuapp.com/\n# Schedule: https://web.archive.org/web/20161015140654/https://rdrc2013.herokuapp.com/\n# Slides: https://web.archive.org/web/20161011211754/http://winstonyw.com/2013/06/12/reddotrubyconf_2013_-_thank_you/\n\n## Day 1 - 7 June, Friday\n\n- id: \"aaron-patterson-refactoring-rails-red-dot-ruby-conf-2013\"\n  title: \"Refactoring Rails\"\n  raw_title: \"Refactoring Rails by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://speakerdeck.com/tenderlove/reddotrubyconf\"\n  description: |-\n    In this presentation we will look at some refactoring techniques used to transform difficult code in to something maintainable. Along the way we will learn about some internals of Rails, including design concepts and potential speed improvements. We'll learn about Rails internals and refactoring techniques, and how we can apply lessons learned to our own applications.\n  video_provider: \"not_recorded\"\n  video_id: \"aaron-patterson-refactoring-rails-red-dot-ruby-conf-2013\"\n\n- id: \"ola-bini-jruby-for-the-win-red-dot-ruby-conf-2013\"\n  title: \"JRuby For The Win\"\n  raw_title: \"JRuby For The Win by Ola Bini\"\n  speakers:\n    - Ola Bini\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"http://winstonyw.com/assets/downloads/JRubyForTheWin.pdf\"\n  description: |-\n    JRuby is an implementation of Ruby for the JVM. It gives you unprecedented integration with the Java ecosystem while still having access to great Ruby libraries such as Rails, RSpec and many more.\n\n    JRuby has gone from being an alternative implementation of Ruby, to a battle hardened tool that many enterprises are using in production. The update in the community means that most gems now are released with outstanding JRuby compatibility, and JRuby can still be counted as the fastest implementation of Ruby.\n\n    In this presentation we will take a look at the reasons for using JRuby, how to get started and what things you can do with JRuby that no other platform gives you.\n\n  video_provider: \"not_recorded\"\n  video_id: \"ola-bini-jruby-for-the-win-red-dot-ruby-conf-2013\"\n\n# Break\n\n- id: \"pablo-astigarraga-50-shades-of-mvc-red-dot-ruby-conf-2013\"\n  title: \"50 Shades Of MVC\"\n  raw_title: \"50 Shades Of MVC by Pablo Astigarraga\"\n  speakers:\n    - Pablo Astigarraga\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://speakerdeck.com/pote/50-shades-of-mvc\"\n  description: |-\n    We at the Rails world are very proud of embracing the Model-View-Controller design pattern, it is integral to the way we build web applications and there is a general consensus that all of us generally know what we are talking about in regards to it, hell , most of our code files are under a model, controller or views directories! We've got to know what we are doing, right?\n\n    Much like Object Orientation the Model-View-Controller pattern is one of the most popular-yet-heavily-altered concepts in modern computer science, what were the original propositions of the pattern? How was it applied back in the 70's, when it was proposed as a part of Smalltalk? How much have we changed it to adapt it to the web application scene? How can we apply this to our day to day work in 2013? is altering the original pattern necessarily a bad thing?\n\n    On this talk I present different aspects of the MVC pattern and its changes from its inception to modern day use, what to keep in mind about the pattern as opposed to a single framework's implementation of it and how knowing this should make us all around better programmers.\n  video_provider: \"not_recorded\"\n  video_id: \"pablo-astigarraga-50-shades-of-mvc-red-dot-ruby-conf-2013\"\n\n- id: \"alexey-gaziev-rails-and-javascript-using-gon-red-dot-ruby-conf-2013\"\n  title: \"Rails And Javascript: Brothers In Arms Using Gon\"\n  raw_title: \"Rails And Javascript: Brothers In Arms Using Gon by Alexey Gaziev\"\n  speakers:\n    - Alexey Gaziev\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://www.slideshare.net/slideshow/gon-rdrc/22611974\"\n  description: |-\n    Did you ever want to integrate your Ruby code in controllers and JavaScript code in the frontend? Gon is here to help with seamless serialization, DRY code and live reloading. Organize your frontend the way it deserves!\n\n    This talk will describe several strategies of transporting data between backend and frontend with the gon gem. It covers:\n    - simple variable transfer\n    - complex serialization with Rabl and JBuilder templates\n    - transparent synchronization of JavaScript variables with their server-side counterparts\n    - easy way to set initial or global data for whole application\n    - real-life examples\n    - nice mood with a set of nifty pics\n    - and a bit of spice: Gon internals!\n  video_provider: \"not_recorded\"\n  video_id: \"alexey-gaziev-rails-and-javascript-using-gon-red-dot-ruby-conf-2013\"\n\n# Lunch\n\n- id: \"luismi-cavalle-keep-activerecord-models-manageable-red-dot-ruby-conf-2013\"\n  title: \"Keep Your ActiveRecord Models Manageable The Rails Way\"\n  raw_title: \"Keep Your ActiveRecord Models Manageable The Rails Way by Luismi Cavallé\"\n  speakers:\n    - Luismi Cavallé\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://speakerdeck.com/cavalle/keep-your-activerecord-models-manageable-the-rails-way\"\n  description: |-\n    Rails is awesome! It makes it very easy and enjoyable to start a new project. However, as your application grows, you will eventually have to come off the Rails or your codebase will become completely unmanageable. Everyone knows that.\n\n    You'll need presenters and a service layer, including role and use-case objects. DCI will be great too or, alternatively, you can go Hexagonal. After all, the web is just a delivery mechanism, the database is a mere persistence strategy and, of course, Rails is a detail.\n\n    But… Wait a minute! Is that really true? Does the _Rails way_ no longer work when your application becomes large? How is it, then, that Rails claims to be “optimised for sustainable productivity”?\n\n    In this talk, we'll revisit the patterns and conventions that Rails encourages. We'll push them to the limit and see how the maintainers of large Rails applications keep their models manageable without needing to derail. We'll also discuss the trade-offs of being on and off the Rails. And, maybe, you'll finally learn how to stop worrying and love the Rails way!\n\n  video_provider: \"not_recorded\"\n  video_id: \"luismi-cavalle-keep-activerecord-models-manageable-red-dot-ruby-conf-2013\"\n\n- id: \"richard-huang-building-asynchronous-apis-red-dot-ruby-conf-2013\"\n  title: \"Building Asynchronous APIs\"\n  raw_title: \"Building Asynchronous APIs by Richard Huang\"\n  speakers:\n    - Richard Huang\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://speakerdeck.com/flyerhzm/building-asynchronous-apis\"\n  description: |-\n    I have built API services on high-traffic platforms using different techniques - multi-processors, multi-threads and evented servers. In this talk, I will share the pros and cons of each technique, and introduce why async non-blocking API service is important for high-traffic websites. I will also show how to easily migrate a Rails synchronous API service to an asynchronous API service.\n  video_provider: \"not_recorded\"\n  video_id: \"richard-huang-building-asynchronous-apis-red-dot-ruby-conf-2013\"\n\n- id: \"paul-gallagher-ruby-the-hard-bits-red-dot-ruby-conf-2013\"\n  title: \"Ruby - The Hard Bits\"\n  raw_title: \"Ruby - The Hard Bits by Paul Gallagher\"\n  speakers:\n    - Paul Gallagher\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://www.slideshare.net/slideshow/ruby-the-hard-bits/22683215\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"paul-gallagher-ruby-the-hard-bits-red-dot-ruby-conf-2013\"\n\n# Break\n\n- id: \"sakchai-siripanyawuth-better-ujs-for-rails-red-dot-ruby-conf-2013\"\n  title: \"A Better UJS For Rails\"\n  raw_title: \"A Better UJS For Rails by Sakchai Siripanyawuth\"\n  speakers:\n    - Sakchai Siripanyawuth\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://www.slideshare.net/slideshow/better-ujsforrails/22536945\"\n  description: |-\n    Javascript and FrontEnd programming is an integral part of developing a rails application, DHH has blessed us with Turbolinks, however turbolinks doesn't give us fine grained control over our page.\n\n    I will be talking about some of the techniques that we've developed at Artellectual to better manage javascript in a Rails application. We will also be releasing a gem that help people get started with the techniques I will be talking about.\n  video_provider: \"not_recorded\"\n  video_id: \"sakchai-siripanyawuth-better-ujs-for-rails-red-dot-ruby-conf-2013\"\n\n- id: \"max-gorin-ext-js-and-rails-red-dot-ruby-conf-2013\"\n  title: \"Lightning Talk: Client-Server GUI Web Components With Ext JS And Rails\"\n  raw_title: \"Client-Server GUI Web Components With Ext JS And Rails by Max Gorin\"\n  speakers:\n    - Max Gorin\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://speakerdeck.com/nomadcoder/client-server-gui-web-components-with-ext-js-and-rails\"\n  description: |-\n    Modular approach to complex RIA (rich internet applications) gives considerable advantages over the commonly used MVC: structuring code into well defined components provides for high scalability, reusability and testability of the code. Besides, with components being a Ruby class, developers have full access to such OOP techniques as inheritance and mixins.\n\n    The Netzke open source framework takes all the hard work of enabling these techniques to create web components using Ruby for the server-side, and Sencha Ext JS for the client-side code. This talk will give you an introduction to rationale behind Netzke, as well as show you some very cool code, which will make you want to give it a try in your next project.\n  video_provider: \"not_recorded\"\n  video_id: \"max-gorin-ext-js-and-rails-red-dot-ruby-conf-2013\"\n\n- id: \"bartosz-knapik-meet-angularjs-red-dot-ruby-conf-2013\"\n  title: \"Lightning Talk: Meet Angular.js And Fall In Love\"\n  raw_title: \"Meet AngularJs And Fall In Love by Bartosz Knapik\"\n  speakers:\n    - Bartosz Knapik\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://speakerdeck.com/bartes/meet-angularjs-and-fall-in-love\"\n  description: |-\n    Have you ever wondered about a javascript framework for your ruby webapp which is easy to extend, easy to test, with auto UI-data binding and separated MVC layers\n\n    I have a proposal for you - angular.js. In this talk I will show what angular.js is and how it is structured. Then I will explain how to build mvc components and test them. Additionally I will provide recipes and guidelines from my 3 years of experience using it.\n  video_provider: \"not_recorded\"\n  video_id: \"bartosz-knapik-meet-angularjs-red-dot-ruby-conf-2013\"\n\n- id: \"matthew-rudy-jacobs-make-me-a-better-rubyist-red-dot-ruby-conf-2013\"\n  title: \"Lightning Talk: Make Me A Better Rubyist!\"\n  raw_title: \"Make Me A Better Rubyist! by Matthew Rudy Jacobs\"\n  speakers:\n    - Matthew Rudy Jacobs\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://speakerdeck.com/matthewrudy/make-me-a-better-rubyist\"\n  description: |-\n    If only there were a magic wand we could wave, and we would suddenly become wise, efficient, and passionate. In reality it takes years of hard work to build the skills and experience necessary. In this talk I'll speak about ways to improve learning, both as an individual, and as a community.\n  video_provider: \"not_recorded\"\n  video_id: \"matthew-rudy-jacobs-make-me-a-better-rubyist-red-dot-ruby-conf-2013\"\n\n- id: \"kentaro-kuribayashi-glint-tcp-server-tests-red-dot-ruby-conf-2013\"\n  title: \"Lightning Talk: Glint - Fires Arbitrary TCP Server Processes For Tests\"\n  raw_title: \"Glint: Fires Arbitrary TCP Server Processes For Tests by Kentaro Kuribayashi\"\n  speakers:\n    - Kentaro Kuribayashi\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://speakerdeck.com/kentaro/glint\"\n  description: |-\n    We use many middlewares like memcached, redis, and some other TCP servers. When we test our app, stubbing out connections to such servers can be useful. However, we can't confirm if our code works actually fine in real situation.\n\n    Glint is a library which allows users to fire up arbitrary TCP servers and test against those real servers without stubbing. While it's a very tiny tool, it can be used in various way combined with many servers. I'll provide a way to solve the problem described above using Glint and show you some examples how to use it.\n  video_provider: \"not_recorded\"\n  video_id: \"kentaro-kuribayashi-glint-tcp-server-tests-red-dot-ruby-conf-2013\"\n\n- id: \"robert-roach-emberjs-red-dot-ruby-conf-2013\"\n  title: \"Lightning Talk: EmberJS\"\n  raw_title: \"EmberJS by Robert Roach\"\n  speakers:\n    - Robert Roach\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://rjayroach.wordpress.com/wp-content/uploads/2013/06/ember_reddot_ruby_conf.pdf\"\n  description: |-\n    Introduction to using EmberJS in Rails projects\n  video_provider: \"not_recorded\"\n  video_id: \"robert-roach-emberjs-red-dot-ruby-conf-2013\"\n\n- id: \"jim-weirich-code-kata-analysis-red-dot-ruby-conf-2013\"\n  title: \"Code Kata And Analysis\"\n  raw_title: \"Code Kata And Analysis by Jim Weirich\"\n  speakers:\n    - Jim Weirich\n  event_name: \"Red Dot Ruby Conference 2013\"\n  date: \"2013-06-07\"\n  slides_url: \"https://github.com/jimweirich/presentation_kata_and_analysis/blob/master/pdf/KataAndAnalysis.key.pdf\"\n  description: |-\n    A Code Kata is a simple programming exercise, practiced repeatably by a developer. Much like a musician practices scales and finger exercises to develop his musical skills, a developer will practice code katas to develop his programming skills.\n\n    This talk will be a live performance of a simple TDD-based code Kata, followed by an analysis of the forces and choices involved in the feedback loop between the code and the tests encountered during the kata. By examining this interaction of tests and code, we come to a better understanding of how to use tests to actively affect the direction of our design. By reflecting on the process, we understand how to pick 'what to test next'.\n\n    This talk is targeted for developers who have started using Test Driven Design (TDD) and feel that they don't quite 'get it' yet, and are looking for guidance in the technique.\n  video_provider: \"not_recorded\"\n  video_id: \"jim-weirich-code-kata-analysis-red-dot-ruby-conf-2013\"\n\n## Day 2 - 8 June, Saturday\n\n- id: \"jose-valim-concurrency-in-ruby-red-dot-ruby-conf-2013\"\n  title: \"Concurrency In Ruby: Tools Of The Trade\"\n  raw_title: \"Concurrency In Ruby: Tools Of The Trade by José Valim\"\n  speakers:\n    - José Valim\n  date: \"2013-06-08\"\n  slides_url: \"https://speakerdeck.com/plataformatec/concurrency-in-ruby-tools-of-the-trade\"\n  description: |-\n    Concurrency has been a popular topic in the programming community in the latest decade and has received special attention in the Ruby community in the latest years. In this talk, José Valim will showcase the tools we have available in Ruby and in the community today, focusing on common pitfalls. This is a great opportunity to discuss why concurrency matters and how we could move forward.\n  video_provider: \"not_recorded\"\n  video_id: \"jose-valim-concurrency-in-ruby-red-dot-ruby-conf-2013\"\n\n- id: \"akira-matsuda-ruby-2-0-on-rails-red-dot-ruby-conf-2013\"\n  title: \"Ruby 2.0 On Rails In Production\"\n  raw_title: \"Ruby 2.0 On Rails In Production by Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  date: \"2013-06-08\"\n  slides_url: \"https://speakerdeck.com/a_matsuda/ruby-2-dot-0-on-rails-in-production\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"akira-matsuda-ruby-2-0-on-rails-red-dot-ruby-conf-2013\"\n\n- id: \"simon-robson-optimising-self-red-dot-ruby-conf-2013\"\n  title: \"Optimising Self\"\n  raw_title: \"Optimising Self by Simon Robson\"\n  speakers:\n    - Simon Robson\n  date: \"2013-06-08\"\n  slides_url: \"https://speakerdeck.com/shr/optimising-self-at-reddotrubyconf-2013\"\n  description: |-\n    If you were building a system that was going to be in production for 10 or 20 years, you'd be pretty serious about your development processes. As a programmer, you will likely be in production *yourself* for considerably longer than that. So how is your self-development process looking? Are you optimising yourself for current performance and long-term viability?\n\n    In this talk we'll consider some aspects - both mental and physical - you may want to be thinking about to make sure personal and professional growth continues smoothly. And also ask if these ideas could be more prominent in how we teach and mentor other programmers.\n  video_provider: \"not_recorded\"\n  video_id: \"simon-robson-optimising-self-red-dot-ruby-conf-2013\"\n\n- id: \"hiroshi-shibata-continuous-upgrades-red-dot-ruby-conf-2013\"\n  title: \"From 'Legacy' To 'Edge': Continuous Upgrades For Rails Apps\"\n  raw_title: \"From 'Legacy' To 'Edge': Continuous Upgrades For Rails Apps by Hiroshi Shibata\"\n  speakers:\n    - Hiroshi Shibata\n  date: \"2013-06-08\"\n  slides_url: \"https://speakerdeck.com/hsbt/from-legacy-to-edge\"\n  description: |-\n    We have a lot of Rails 2.x applications with Ruby 1.8 in production, and engineers feel incredible pain because they can't use a lot of gems and Ruby 1.9 features.\n\n    In this talk, I'll share my thoughts on the following:\n    - Why do we need to upgrade Ruby and Rails?\n    - What are the strategies available to upgrade Ruby and Rails?\n    - How do we reduce technical debt?\n    - How do we upgrade Rails while adding new features?\n    - How do we do continuous delivery while simuluteously migrating the database?\n\n    I'll also talk about how web companies in Japan work. If you are interested in continuous maintenance and continuous delivery, this is a talk for you.\n  video_provider: \"not_recorded\"\n  video_id: \"hiroshi-shibata-continuous-upgrades-red-dot-ruby-conf-2013\"\n\n# Lunch Break\n\n- id: \"chang-sau-sheong-ruby-playing-red-dot-ruby-conf-2013\"\n  title: \"Ruby Playing\"\n  raw_title: \"Ruby Playing by Chang Sau Sheong\"\n  speakers:\n    - Sau Sheong Chang\n  date: \"2013-06-08\"\n  slides_url: \"https://speakerdeck.com/sausheong/playing-with-ruby\"\n  description: |-\n    Ruby is a versatile and powerful programming language and platform, something all participants of this conference would already know. However today Ruby is still mostly used together with Ruby on Rails as the platform for developing web applications.\n\n    In this talk I would like to show how easily Ruby can be used in another way -- to develop a real-time, online and multi-player game. This 2D game will be written with Ruby only -- from the client, to the server to the management console will be entirely in Ruby.\n  video_provider: \"not_recorded\"\n  video_id: \"chang-sau-sheong-ruby-playing-red-dot-ruby-conf-2013\"\n\n- id: \"yi-ting-cheng-secure-your-rails-application-red-dot-ruby-conf-2013\"\n  title: \"Secure Your Rails Application: The Basics\"\n  raw_title: \"Secure Your Rails Application: The Basics by Yi-Ting Cheng\"\n  speakers:\n    - Yi-Ting \"Xdite\" Cheng\n  date: \"2013-06-08\"\n  slides_url: \"https://xdite.github.io/security-basic\"\n  description: |-\n    Security is hard. Everyone wants their sites to be hacker-free. But the truth is: If your sites were hacked, the causes are often because you forgot the basics.\n\n    In this talk I will show you:\n    - Common application design mistakes people make and are not aware of.\n    - The most vulnerable controller actions that hackers seek.\n    - The default security mechanism of Rails for these issues and reasons why you should not bypass them.\n    - And how to write secure codes by default.\n\n  video_provider: \"not_recorded\"\n  video_id: \"yi-ting-cheng-secure-your-rails-application-red-dot-ruby-conf-2013\"\n\n- id: \"christopher-rigor-identical-environments-red-dot-ruby-conf-2013\"\n  title: \"Identical Production, Staging And Development Environments Using Chef, AWS And Vagrant\"\n  raw_title: \"Identical Production, Staging And Development Environments Using Chef, AWS And Vagrant by Christopher Rigor\"\n  speakers:\n    - Christopher Rigor\n  date: \"2013-06-08\"\n  description: |-\n    Learn how Engine Yard uses Amazon Web Services and Chef to bring up any number of servers ranging from a solo instance to a cluster of instances with multiple app instances, database instances and utility instances for memcached, resque, sphinx, and everything your app needs.\n\n    Snapshots are used to create a clone of your production environment where you can test all the changes before making them in production.\n\n    Vagrant and VirtualBox are used to provide a development environment with the same OS you use in production. Chef is used to install the same packages. In fact you use the same chef recipes everywhere.\n  video_provider: \"not_recorded\"\n  video_id: \"christopher-rigor-identical-environments-red-dot-ruby-conf-2013\"\n\n# Break\n\n- id: \"prem-sichanugrist-dependencies-testing-red-dot-ruby-conf-2013\"\n  title: \"Dependencies Testing With Appraisal And Bundler\"\n  raw_title: \"Dependencies Testing With Appraisal And Bundler by Prem Sichanugrist\"\n  speakers:\n    - Prem Sichanugrist\n  date: \"2013-06-08\"\n  slides_url: \"https://speakerdeck.com/sikachu/dependencies-testing-with-appraisal-and-bundler\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"prem-sichanugrist-dependencies-testing-red-dot-ruby-conf-2013\"\n\n- id: \"nigel-rausch-view-testing-red-dot-ruby-conf-2013\"\n  title: \"Fast & Effective View Testing\"\n  raw_title: \"Fast & Effective View Testing by Nigel Rausch\"\n  speakers:\n    - Nigel Rausch\n  date: \"2013-06-08\"\n  description: |-\n    Too many people use integration tests to check if an element is displayed or not, this is slow and cumbersome. Another solution is to use rspec view specs which end up creating a lot of duplicated code and scenarios.\n\n    In this presentation I will show you a fast and consistent way of testing multiple elements are (or are not) displayed based on a context.\n  video_provider: \"not_recorded\"\n  video_id: \"nigel-rausch-view-testing-red-dot-ruby-conf-2013\"\n\n- id: \"steve-klabnik-functional-reactive-programming-red-dot-ruby-conf-2013\"\n  title: \"Functional Reactive Programming in Ruby\"\n  raw_title: \"Functional Reactive Programming in Ruby by Steve Klabnik\"\n  speakers:\n    - Steve Klabnik\n  date: \"2013-06-08\"\n  description: |-\n    Ruby's strengths lie in its ability to blend styles. We all know about OOP and Ruby, but it often leans functional, as well. There's a style of writing programs called 'Functional Reactive Programming' that is extremely useful in the Haskell world, but isn't really used in Ruby at all.\n\n    In this talk, Steve will show you FRP, an implementation of it in Ruby, and how to write programs in this style.\n  video_provider: \"not_recorded\"\n  video_id: \"steve-klabnik-functional-reactive-programming-red-dot-ruby-conf-2013\"\n# After Party\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZ7quxtkav1TYj8zOMqQQQV\"\ntitle: \"Red Dot Ruby Conference 2014\"\nkind: \"conference\"\nlocation: \"Singapore, Singapore\"\ndescription: |-\n  June 26 - 27, 2014 • Singapore\npublished_at: \"2014-06-27\"\nstart_date: \"2014-06-26\"\nend_date: \"2014-06-27\"\nchannel_id: \"UCjRZr5HQKHVKP3SZdX8y8Qw\"\nyear: 2014\nbanner_background: \"#B66F6D\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#282F39\"\nwebsite: \"https://web.archive.org/web/20161025023554/https://rdrc2014.herokuapp.com/\"\ncoordinates:\n  latitude: 1.352083\n  longitude: 103.819836\naliases:\n  - RedDotRubyConf 2014\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2014/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20161025023554/https://rdrc2014.herokuapp.com/\n# Schedule: https://web.archive.org/web/20161025023554/https://rdrc2014.herokuapp.com/\n\n## Day 1 - 26 June 2014\n\n# Registration + Breakfast\n\n# Opening Address for Day 1\n\n- id: \"koichi-sasada-red-dot-ruby-conference-2014\"\n  title: \"Ruby.inspect\"\n  raw_title: \"RedDotRuby 2014 - Ruby.inspect by Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-07-22\"\n  published_at: \"2014-07-22\"\n  slides_url: \"https://www.atdot.net/~ko1/activities/2014_reddotrubyconf_pub.pdf\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"eNTIOotQ0Ug\"\n\n- id: \"tj-schuck-red-dot-ruby-conference-2014\"\n  title: \"80,000 Plaintext Passwords: An Open Source Love Story in 3 Acts\"\n  raw_title: \"RedDotRuby 2014 -  80,000 Plaintext Passwords: An Open Source Love Story in 3 Acts by T.J. Schuck\"\n  speakers:\n    - T.J. Schuck\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-24\"\n  slides_url: \"https://speakerdeck.com/tjschuck/80-000-plaintext-passwords-an-open-source-love-story-in-three-acts\"\n  description: |-\n    fluffmuffin, peppercorn, gilligan — those are just a few of our users' plain text passwords.\n\n    I have 80,000 more, and it only took me 87 seconds to gather them from our customer database in a white-hat attack.\n\n    In Act I, we'll cover the history of secure password storage, examine the hack, and mitigate the threat. Act II will address the difficulties of working on libraries with complicated external dependencies (like bcrypt-ruby, of which I'm now a maintainer). In Act III, we'll celebrate the power of global collaboration via OSS.\n\n    [Scene.]\n\n  video_provider: \"youtube\"\n  video_id: \"GDuSAnMYXFU\"\n\n# Break\n\n- id: \"brandon-keepers-red-dot-ruby-conference-2014\"\n  title: \"Tending Your Open Source Garden\"\n  raw_title: \"RedDotRuby 2014 - Tending Your Open Source Garden\"\n  speakers:\n    - Brandon Keepers\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-21\"\n  slides_url: \"https://speakerdeck.com/bkeepers/tending-your-open-source-garden\"\n  description: |-\n    Like a garden, open source projects require cultivation, diligent maintenance, and pruning to sustainably produce a harvest. Without proper care, they become a burden that smothers your reputation, causes harm to your product, and kills your morale.\n\n    Tending the open source garden is not easy, and it's not for everyone. At GitHub, we have released a lot of open source code over the years and we have experienced both the benefits and the costs. This talk will examine the lessons I have learned in cultivating and maintaining open source projects.\n\n  video_provider: \"youtube\"\n  video_id: \"PWcCdvbXHkU\"\n\n- id: \"gautam-rege-red-dot-ruby-conference-2014\"\n  title: \"The Dark Side of Ruby\"\n  raw_title: \"RedDotRuby 2014 -  The Dark Side of Ruby by Gautam Rege\"\n  speakers:\n    - Gautam Rege\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-21\"\n  slides_url: \"http://www.slideshare.net/gautamrege/reddot-ruby-conf-2014-dark-side-of-ruby\"\n  description: |-\n    I love Ruby! But as in any relationship, to love means that you (often) have to accept the \"dark side\" too! Ruby is human in nature and has a lot of gotchas, tricks, weirdness and sometimes scary features that I plan to highlight. This talk aims to provide the \"Ah-ha!\" moments when working in Ruby.\n\n    This talk is for beginners and experts alike - in fact, I tag slides to mark their level and beginners can choose to tune out of the heavy stuff! My talk shall cover the dark side of the following features of Ruby (in no particular order)\n\n    Keyword wierdness\n    method missing\n    Module inheritance! (huh?)\n    Accessor righteousness\n    Curried Procs for the hungry\n    Base Conversions\n    Cherry picking module methods\n    Oniguruma games\n    Object id weirdness\n    procs, blocks and our friend stabby.\n    ==, ===, eql? and equal?\n    and more...\n    As with most of my talks, humor plays an important role and I shall aim to get everyone high on Ruby with a deep dive!\n\n  video_provider: \"youtube\"\n  video_id: \"_KgcQMXIqM4\"\n\n# Lunch\n\n- id: \"keith-pitt-red-dot-ruby-conference-2014\"\n  title: \"Guide to Continuous Deployment with Rails\"\n  raw_title: \"RedDotRuby 2014 -  Guide to Continuous Deployment with Rails by Keith Pitt\"\n  speakers:\n    - Keith Pitt\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-21\"\n  description: |-\n    Recently it has become common practise for development teams to deploy their code several times a day, as well as encouraging new developers to deploy on their first day at work.\n\n    In this talk, I will discuss how I use continuous deployment to push these practises to the extreme. Automatically deploying the master branch on new changes is an awesome way to improve your development process.\n\n    Automatically deploying master will fundamentally change how you work. Gone are the days of the epic pull request. You'll quickly find yourself writing smaller more manageable chunks of code, that overall have a great impact on the quality of the software you produce.\n\n    By the end of the talk you'll know how to change the GitHub merge pull request button into a deploy button - and have the confidence to do so.\n\n    Some things I'll go over in the talk:\n\n    How to setup your CI environment for deployments\n    Why having fast tests are important\n    How to use your Staging environment for testing deployments\n    How to use feature flags to hide deployed features from some users\n    Zero downtime deploys, even when there are database migrations\n    Your new deploy button, AKA The GitHub merge pull request button\n    What to do when deployment goes wrong\n\n  video_provider: \"youtube\"\n  video_id: \"bp7CKPsJJJ0\"\n\n- id: \"benjamin-tan-red-dot-ruby-conference-2014\"\n  title: \"Ruby + Elixir: Polyglotting FTW!\"\n  raw_title: \"RedDotRuby 2014 - Ruby + Elixir: Polyglotting FTW! by Benjamin Tan\"\n  speakers:\n    - Benjamin Tan\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-21\"\n  slides_url: \"https://speakerdeck.com/benjamintan/ruby-plus-elixir-polyglottin-ftw\"\n  description: |-\n    As developers, we know that we should use the right tool for the right job. While we may love Ruby, there are also many interesting technologies that may complement our favourite programming language.\n\n    This talk introduces Elixir, a programming language that is built on the legendary Erlang virtual machine. I will first give a quick walk through of the language, focusing on core concepts such as concurrency and fault tolerance - areas where Elixir shines.\n\n    After that, we will dive straight in to an example application to see how Ruby can exploit the powerful features of Elixir. More importantly, the audience would realise that there's more to Ruby than just Ruby.\n\n    It will be a fun ride!\n\n  video_provider: \"youtube\"\n  video_id: \"2X1J1lVzRuQ\"\n\n- id: \"vipul-a-m-red-dot-ruby-conference-2014\"\n  title: \"ActiveRecord can't do it? Arel can!\"\n  raw_title: \"RedDotRuby 2014 -  ActiveRecord can't do it? Arel can! by Vipul Amler & Prathamesh Sonpatki\"\n  speakers:\n    - Vipul A M\n    - Prathamesh Sonpatki\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-21\"\n  slides_url: \"https://web.archive.org/web/20161025023554/https://docs.google.com/presentation/d/1O4jYDnq8d0lSu3D2c_khKPkQ2GKCm1Fw0y1nQacmwVc/pub#slide=id.p\"\n  description: |-\n    Active Record is awesome. But how does ActiveRecord handle generating complex SQL queries? Under the hood it's handled by Arel. Most of the time, Rails developers don't have to know about how Arel works.\n\n    But sometimes Active Record can't satisfy our needs. Also Arel has many strengths not exposed through Active Record.\n\n    Let's experiment with Arel directly and wield great SQL power in database agnostic way.\n\n  video_provider: \"youtube\"\n  video_id: \"Trwhl1FpveE\"\n\n# Break\n\n- id: \"hiroshi-shibata-red-dot-ruby-conference-2014\"\n  title: \"Lightning Talk: How to improve experiences of Ruby\"\n  raw_title: \"RedDotRuby 2014 - Lightning Talk - How to improve experiences of Ruby by Hiroshi Shibata\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-22\"\n  slides_url: \"https://speakerdeck.com/hsbt/how-to-improve-experiences-of-ruby\"\n  description: |-\n    How can we make Ruby programming more pleasant? The most common (and easiest) methods are to make RubyGems or fix Rails defects. How about contributing to Ruby? Most people think that it's difficult to contribute or fix Ruby. Well, it is actually easy to contribute to or fix Ruby and many more people would be affected by your effort!\n\n    How can you start fixing Ruby? I'll introduce the methods to get started in improving Ruby, such as proposals of new features, writing documents, fixing websites, reporting defects and more.\n\n    Furthermore, there are techniques to help get your proposals accepted, and I'll talk about those too. You can improve the world by contributing to Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"izc6QL6h5Z8\"\n\n- id: \"william-notowidagdo-red-dot-ruby-conference-2014\"\n  title: \"Lightning Talk: Building REST API with Grape by\"\n  raw_title: \"RedDotRuby 2014 - Lightning Talks - Building REST API with Grape by William Notowidagdo\"\n  speakers:\n    - William Notowidagdo\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-22\"\n  description: |-\n    How to use grape to build a REST API that applying best-practices patterns.\n\n    Handling errors\n    Versioning\n    Pagination and partial response\n    Multiple formats\n    Handling exceptions\n    Logging\n    Authentication\n    Testing\n\n  video_provider: \"youtube\"\n  video_id: \"lNXa-fjTroE\"\n\n- id: \"sayanee-basu-red-dot-ruby-conference-2014\"\n  title: \"Lightning Talk: 5 Tips in 5 mins on Podcasting With Jekyll\"\n  raw_title: \"RedDotRuby 2014 - Lightning Talk - 5 Tips in 5 mins on Podcasting With Jekyll by Sayanee Basu\"\n  speakers:\n    - Sayanee Basu\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-22\"\n  slides_url: \"https://web.archive.org/web/20161025023554/https://speakerdeck.com/sayanee/podcasting-with-jekyll\"\n  description: |-\n    We will learn how to generate static html pages with Jekyll and host them effortlessly on Github Pages and run automated continuous integrated with Travis CI.\n\n    Podcasting needs additional features along with a blogging site. With Jekyll we will learn how to generate feeds file for iTunes or an RSS reader, sitemap and post meta info for each episode.\n\n  video_provider: \"youtube\"\n  video_id: \"KAddrblLlp4\"\n\n- id: \"satoshi-moris-tagomori-red-dot-ruby-conference-2014\"\n  title: \"Fluentd: Data Streams in Ruby World\"\n  raw_title: \"RedDotRuby 2014 - Fluentd: Data Streams in Ruby World by Satoshi Tagomori\"\n  speakers:\n    - Satoshi \"moris\" Tagomori\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-07-22\"\n  published_at: \"2014-07-22\"\n  slides_url: \"http://www.slideshare.net/tagomoris/fluentd-data-streams-in-ruby-world-rdrc2014\"\n  description: |-\n    Data streams (ex: logs) are becoming larger, while analytics in (semi-) real time is also becoming more important today. We want to collect huge data sets from many sources, and analyze these data in various way to gain valuable business insights. For these purposes, software on jvm (Hadoop, Flume, Storm, ...) works well, but we (Rubyists!) need more Ruby-like, scriptable, ease-to-deploy and extensible software. That is Fluentd.\n\n    I'll introduce Fluentd, a famous log collector in Japan, and its plugin systems. Fluentd is a very simple and well-designed software that have various plugins to collect/convert/aggregate/write stream data, which are already used in many production environments. And I will also talk about Fluentd's development plans, newly implemented features and case studies in LINE.\n\n  video_provider: \"youtube\"\n  video_id: \"BwqAtvEln2M\"\n\n- id: \"lucas-dohmen-red-dot-ruby-conference-2014\"\n  title: \"Domain Driven Design & NoSQL\"\n  raw_title: \"RedDotRuby 2014 - Domain Driven Design & NoSQL by Lucas Dohmen\"\n  speakers:\n    - Lucas Dohmen\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-23\"\n  slides_url: \"https://speakerdeck.com/moonglum/domain-driven-design-and-nosql-at-reddotruby-conf\"\n  description: |-\n    Domain Driven Design is a software development process that focuses on the finding a common language for the involved parties. This language and the resulting models are taken from the domain rather than the technical details of the implementation. The goal is to improve the communication between customers, developers and all other involved groups. Even if Eric Evan's book about this topic was written almost ten years ago, this topic remains important because a lot of projects fail for communication reasons.\n\n    Relational databases have their own language and influence the design of software into a direction further away from the Domain: Entities have to be created for the sole purpose of adhering to best practices of relational database. Two kinds of NoSQL databases are changing that: Document stores and graph databases. In a document store you can model a contains relation in a more natural way and thereby express if this entity can exist outside of its surrounding entity. A graph database allows you to model relationships between entities in a straight forward way that can be expressed in the language of the domain.\n\n    I want to look at the way a multi model database that combines a document store and a graph database can help you model your problems in a way that is understandable for all parties involved.\n\n  video_provider: \"youtube\"\n  video_id: \"2_9Fd0Rqb5k\"\n\n- id: \"konstantin-haase-red-dot-ruby-conference-2014\"\n  title: \"Magenta is a Lie - and Other Tales of Abstraction\"\n  raw_title: \"RedDotRuby 2014 - Magenta is a Lie - and Other Tales of Abstraction by Konstantin Haase\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-26\"\n  published_at: \"2014-07-22\"\n  slides_url: \"https://speakerdeck.com/rkh/reddotrubyconf-2014-magenta-is-a-lie-and-other-tales-of-abstraction\"\n  description: |-\n    Abstraction is a fundamental approach in programming. It shapes how we solve problems, it is a defining factor in how we view the internals of software and even the world surrounding it and us. The questions of when, how and what to abstract are some of the biggest in computer science and can make the difference between good and bad code. This talk is a fresh take on different facets of abstractions we encounter, build on and have to fight with.\n\n  video_provider: \"youtube\"\n  video_id: \"st0mk7BsPi8\"\n\n## Day 2 - 27 June 2014\n\n# Breakfast\n\n# Opening Address for Day 2\n\n- id: \"bryan-helmkamp-red-dot-ruby-conference-2014\"\n  title: \"Shipping Ruby Apps with Docker\"\n  raw_title: \"RedDotRuby 2014 - Shipping Ruby Apps with Docker by Bryan Helmkamp\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-23\"\n  description: |-\n    Docker is \"an open source project to pack, ship and run any application as a lightweight container\". In this talk, we'll explore the basics of Docker, the advantages of container-based virtualization, and how to setup Rails deployments using both.\n\n  video_provider: \"youtube\"\n  video_id: \"mVN7aTqr550\"\n\n- id: \"zachary-scott-red-dot-ruby-conference-2014\"\n  title: \"ruby-core for tenderfeet\"\n  raw_title: \"RedDotRuby 2014 - Ruby-Core for Tenderfeet by Zachary Scott\"\n  speakers:\n    - Zachary Scott\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-23\"\n  slides_url: \"https://web.archive.org/web/20161025023554/https://speakerdeck.com/zzak/reddotrubyconf-2014-ruby-core-for-tenderfeet\"\n  description: |-\n    It's my personal goal to introduce as many people as possible to open-source and make it dead simple for them to contribute.\n\n    What happens if you have something specific you want to contribute?\n\n    This talk will show you the best practices for discussing features and ideas with ruby-core. We'll show you how to get your high-level concepts imagined through efficient channels of discussion to implementation.\n\n    We should talk about how fear and language barriers play a role in getting the right kind of feedback. We'll also talk about how ruby-core operates with the vast distance between its members.\n\n    Most importantly, we'll give you the confidence to work effectively with ruby-core and how we can improve Ruby together.\n\n  video_provider: \"youtube\"\n  video_id: \"wHW7yMTDlYA\"\n\n# Break\n\n- id: \"piotr-solnica-red-dot-ruby-conference-2014\"\n  title: \"Convenience vs Simplicity\"\n  raw_title: \"RedDotRuby 2014 - Convenience vs Simplicity by Piotr Solnica\"\n  speakers:\n    - Piotr Solnica\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-23\"\n  slides_url: \"https://speakerdeck.com/solnic/convenience-vs-simplicity\"\n  description: |-\n    Avoiding complexity is one of the greatest goals in programming. The tools we use, libraries and frameworks, must be helping us in achieving that goal. There must be a reasonable balance between convenience and simplicity as growing complexity is the price we pay for that convenience.\n\n    This talk is about seeking simplicity when dealing with data and behavior showing alternative approaches to object relational mapping and persistence concerns.\n\n  video_provider: \"youtube\"\n  video_id: \"cCD7QJB4HHs\"\n\n- id: \"anil-wadghule-red-dot-ruby-conference-2014\"\n  title: \"SOLID Design Principles in Ruby\"\n  raw_title: \"RedDotRuby 2014 - SOLID Design Principles in Ruby by Anil Wadghule\"\n  speakers:\n    - Anil Wadghule\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-23\"\n  slides_url: \"https://speakerdeck.com/anildigital/solid-design-principles-in-ruby\"\n  description: |-\n    This talk covers following SOLID design principles in Ruby with live code examples.\n\n    Single responsibility principle: an object should have only a single responsibility. Open/closed principle: an object should be open for extension, but closed for modification. Liskov substitution principle: objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program Interface segregation principle: many client specific interfaces are better than one general purpose interface. Dependency inversion principle: depend upon abstractions, do not depend upon concretions Talk will have live code example which will be evolved step by step to use all SOLID principles. This talk will also answer the question why just following these principles will make your code more clean readable, extensible and better. Also make you better programmer.\n\n  video_provider: \"youtube\"\n  video_id: \"QqBb4gb7PM0\"\n\n# Lunch\n\n- id: \"jon-rowe-red-dot-ruby-conference-2014\"\n  title: \"RSpec 3 and why I `expect(you).to care`\"\n  raw_title: \"RedDotRuby 2014 - RSpec 3 and why I `expect(you).to care` by Jon Rowe\"\n  speakers:\n    - Jon Rowe\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-24\"\n  description: |-\n    RSpec, like it or loathe it is a widely used testing framework and this year will reach it's latest major version. Version 3. Why is this a big deal?\n\n    It's the product of many months of work by the core team and makes a lot of changes to improve its code base both internally and externally. Some of the changes are contentious and some are just cool, but why did we make those decisions?\n\n    Let me take you thought the major changes in RSpec3 and detail why we took that decision you don't like, why did we deprecate that feature or why do we recommend this way of doing things. Hopefully you'll be encouraged to write better specs or maybe just understand this little piece of the Ruby ecosystem a bit better.\n\n  video_provider: \"youtube\"\n  video_id: \"5D4UbNui3rE\"\n\n- id: \"anand-agrawal-red-dot-ruby-conference-2014\"\n  title: \"Adventures with Micro Services in Rails\"\n  raw_title: \"RedDotRuby 2014 - Adventures with Micro Services in Rails by Anand Agrawal\"\n  speakers:\n    - Anand Agrawal\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-23\"\n  description: |-\n    I have spent some time working on a project where we've built 8 micro services and 2 applications, and planned to carve out a few more. Deployment was carried out in a farm of 25 servers in production with a single click in less than 3 minutes.\n\n    In this talk I will share our experiences with building a micro service based architecture - the good, the bad and the ugly.\n\n    What are micro services?\n    When/Why/How micro services?\n    Why NOT micro services?\n    Managing Continuous Integration and Continuous Delivery with micro services\n    A few design principles that we followed and that worked for us\n\n  video_provider: \"youtube\"\n  video_id: \"-5QEnbpFp3Q\"\n\n- id: \"matthew-delves-red-dot-ruby-conference-2014\"\n  title: \"ActiveSupport::Notifications and Live Status Pages\"\n  raw_title: \"RedDotRuby 2014 - ActiveSupport::Notifications and Live Status Pages by Matthew Delves\"\n  speakers:\n    - Matthew Delves\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-24\"\n  description: |-\n    An overview of ActiveSupport::Notifications and how they form the backbone of a live status page to tell you exactly what is going on with your site.\n\n  video_provider: \"youtube\"\n  video_id: \"m6ohHPK7ApQ\"\n\n# Break\n\n- id: \"sheng-loong-su-red-dot-ruby-conference-2014\"\n  title: \"Lightning Talk: Algorithmic Trading for Fun and Profit\"\n  raw_title: \"RedDotRuby 2014 - Lightning Talk - Algorithmic Trading for Fun and Profit by Sheng Loong Su\"\n  speakers:\n    - Sheng Loong Su\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-23\"\n  slides_url: \"https://speakerdeck.com/sushengloong/algorithmic-trading-for-fun-and-profit-red-dot-ruby-conf-2014\"\n  description: |-\n    From an engineer's perspective, algorithmic (or quantitative/systematic) trading is about developing a trading system that applies mathematical and computer models for making transaction decisions in the financial markets. This talk will explore the algorithmic trading process and how we can use Ruby for research and development of profitable stock trading strategies.\n\n  video_provider: \"youtube\"\n  video_id: \"_NrPT8IS5Ag\"\n\n- id: \"grzegorz-witek-red-dot-ruby-conference-2014\"\n  title: \"Lightning Talk: Nomadic Programmer\"\n  raw_title: \"RedDotRuby 2014 - Lightning Talk - Nomadic Programmer by Grzegorz Witek\"\n  speakers:\n    - Grzegorz Witek\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-23\"\n  slides_url: \"https://speakerdeck.com/arnvald/nomadic-programmer\"\n  description: |-\n    In December 2013 I quit my job, bought a ticket to the other end of the world, took my backpack and and went to the airport. Since then I've been travelling from country to country, visiting new places, experiencing new cultures, attending meetups and conferences, and working as a freelance Ruby developer. This is not another \"I quit corporation\" talk. What I want to tell you is: why it's exciting to become a nomadic programmer even just for a few months, what problems you can expect when you change your place once a week, and how to work effectively without your own office, big screen and fast, reliable internet connection.\n\n  video_provider: \"youtube\"\n  video_id: \"1ThXL5q5zgA\"\n\n- id: \"shuwei-fang-red-dot-ruby-conference-2014\"\n  title: \"Lightning Talk: Advantages of Development Environment Setup with Vagrant\"\n  raw_title: \"RedDotRuby 2014 - Lightning Talk -  Advantages of Development Environment Setup with Vagrant\"\n  speakers:\n    - Shuwei Fang\n    - Arathi Premadevi\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-07-23\"\n  published_at: \"2014-07-23\"\n  description: |-\n    By Shuwei Fang & Arathi Premadevi\n\n    A complex application usually uses a number of external dependencies. Installing these on every developer's machine individually can be quite a hassle. How can you simplify this process and make sure everyone has the same configuration? Join us in the talk to understand how this can be done in a matter of seconds with the help of Vagrant!\n\n  video_provider: \"youtube\"\n  video_id: \"B32Y3yHOaIM\"\n\n- id: \"nicholas-simmons-red-dot-ruby-conference-2014\"\n  title: \"To a Single Page Web App and Back Again\"\n  raw_title: \"RedDotRuby 2014 -  To a Single Page Web App and Back Again by Nicholas Simmons\"\n  speakers:\n    - Nicholas Simmons\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-24\"\n  slides_url: \"https://speakerdeck.com/fullstackcoder/reddotrubyconf2014\"\n  description: |-\n    Single page web applications have been all the rage recently. At Shopify, we wanted to make our admin interface a dynamic and fluid experience for our users. We created our own JS MVC framework and used it to rebuild our admin. Now we have decided to change course. What fueled this decision? What lessons have we learned? What worked and what didn’t? This talk will share our experiences, as well as our new hybrid approach: A modified version of Turbolinks combined with a lightweight binding system.\n\n  video_provider: \"youtube\"\n  video_id: \"c-YxItuiwgQ\"\n\n- id: \"christophe-philemotte-red-dot-ruby-conference-2014\"\n  title: \"Safety Nets: Learn to Code With Confidence\"\n  raw_title: \"RedDotRuby 2014 - Safety Nets: Learn to Code With Confidence by Christophe Philemotte\"\n  speakers:\n    - Christophe Philemotte\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-24\"\n  slides_url: \"https://speakerdeck.com/toch/rdrc-2014-safety-nets-learn-to-code-with-confidence\"\n  description: |-\n    Ruby gives you a great power, such as easy Duck Typing. As the saying goes, \"With great power there must also comes great responsibility!\" It comes at a price. We cannot afford to blow off everything when shipping. That's why it's important to put in place different strategies to help us to catch errors asap, but also to avoid the cruft long term. Like a safety net, they allow you to go forward with more confidence.\n\n  video_provider: \"youtube\"\n  video_id: \"W06qYx2ouSQ\"\n\n- id: \"aaron-patterson-red-dot-ruby-conference-2014\"\n  title: \"Speed up Rails, Speed up Your Code\"\n  raw_title: \"RedDotRuby 2014 SpeedupRails, Speedup Your Code by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Red Dot Ruby Conference 2014\"\n  date: \"2014-06-27\"\n  published_at: \"2014-07-24\"\n  slides_url: \"https://speakerdeck.com/tenderlove/speed-up-rails-speed-up-your-code\"\n  description: |-\n    Let's talk about speed! In this talk, we'll examine ways that we've been speeding up Rails for the next release. We'll look at techniques used for speeding up database interaction as well as view processing. Techniques for finding bottlenecks and eliminating them will be presented, and we'll talk about how these techniques work with regard to Rails applications themselves. The presenter will also be discussing ways to speak in first person.\n\n  video_provider: \"youtube\"\n  video_id: \"d2QdITRRMHg\"\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZdMYKatu_nics8Pkjxl3-F\"\ntitle: \"Red Dot Ruby Conference 2015\"\nkind: \"conference\"\nlocation: \"Singapore, Singapore\"\ndescription: |-\n  RedDotRubyConf is the largest Ruby conference in South East Asia - a two day single-track event that brings together renowned international and local speakers • June 4 and 5, 2015 • Singapore\npublished_at: \"2015-06-05\"\nstart_date: \"2015-06-04\"\nend_date: \"2015-06-05\"\nchannel_id: \"UCjRZr5HQKHVKP3SZdX8y8Qw\"\nyear: 2015\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#282F39\"\nwebsite: \"https://web.archive.org/web/20161005135435/http://rdrc2015.herokuapp.com/\"\ncoordinates:\n  latitude: 1.352083\n  longitude: 103.819836\naliases:\n  - RedDotRubyConf 2015\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2015/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20161005135435/http://rdrc2015.herokuapp.com/\n# Schedule: https://web.archive.org/web/20161005135435/http://rdrc2015.herokuapp.com/\n\n## Day 1 - 4 June (Thursday)\n\n# Registration + Breakfast\n\n# Opening Address for Day 1\n\n- id: \"yukihiro-matz-matsumoto-red-dot-ruby-conference-2015\"\n  title: \"Keynote: Super Dry Ruby\"\n  raw_title: \"RedDotRuby 2015 - Keynote: Super Dry Ruby by Yukihiro 'Matz' Matsumoto\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Keynote: Super Dry Ruby by Yukihiro 'Matz' Matsumoto\n  video_provider: \"youtube\"\n  video_id: \"bqWBB8-iEac\"\n\n- id: \"andr-arko-red-dot-ruby-conference-2015\"\n  title: \"Security Is Hard, But We Can't Go Shopping\"\n  raw_title: \"RedDotRuby 2015 - Security Is Hard, But We Can't Go Shopping by André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Security Is Hard, But We Can't Go Shopping by André Arko\n\n    Security is really important, and a lot of rubyists are unfamiliar with how it works, why it's important, how to explain it to bosses and managers, and most importantly, how to handle security vulnerabilities in code they use (or code they wrote). Let's talk about why security is important, even though Matz is nice. We'll also about what to do when vulnerabilities show up, since they always will.\n  video_provider: \"youtube\"\n  video_id: \"eHmXar6TNUo\"\n\n# Break\n\n- id: \"sau-sheong-chang-red-dot-ruby-conference-2015\"\n  title: \"Rollicking Ruby Robots Rule the World\"\n  raw_title: \"RedDotRuby 2015 -  Rollicking Ruby Robots Rule the World by Sau Sheong Chang and Shipeng Xu\"\n  speakers:\n    - Sau Sheong Chang\n    - Shipeng Xu\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Rollicking Ruby Robots Rule the World by Sau Sheong Chang and Shipeng Xu\n    We don't see it all the time but robots that make our lives easier are already\n    here with us. While they look nothing like the Transformers (cool!) or the Terminator\n    (cool but scary), they affect our lives just as deeply. They assemble our cars,\n    package our goods, manufacture our electronics, harvest our crops, clean our floors,\n    drive our cars and even fight our wars (scary again).\n    In this talk, we want to show you how you can create and program your own autonomous robots using Ruby.\n    We will show you how we built an inexpensive hexapod spider robot and how we wrote\n    the software to control it, using Ruby.\n    This talk is inspired by Jim Weirich, who showed us Friendly Flying Robots with Ruby in 2013.\n  video_provider: \"youtube\"\n  video_id: \"ROPktEju3M0\"\n- id: \"prathamesh-sonpatki-red-dot-ruby-conference-2015\"\n  title: \"Rethinking the View using React.js\"\n  raw_title: \"RedDotRuby 2015 - Rethinking the View using React.js by Prathamesh Sonpatki\"\n  speakers:\n    - Prathamesh Sonpatki\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Rethinking the View using React.js by Prathamesh Sonpatki\n    Complex web interfaces is the need of the hour. The interactions should be smooth, pages\n    should load fast, changes should happen without reloading page that too as fast\n    as possible. Users must feel great while using the app. But with so much complexity,\n    its becoming harder and harder to keep the frontend codebase clear, predictable\n    and reusable. Time to rethink!\n\n    In this talk, I will first give an overview of React.js, a JavaScript library from Facebook for building user interfaces,\n    covering core concepts such as building and composing components, virtual DOM,\n    immutable data structures, one way data flow - which makes React really shine.\n\n    After that, we will dive straight into an example where I will show how Rails\n    can leverage power of React. Most importantly, audience will understand power\n    of rethinking existing best practices.\n\n    Lets start (re)thinking!\n  video_provider: \"youtube\"\n  video_id: \"9iFCJFALWn0\"\n\n# Lunch\n\n- id: \"laurent-sansonetti-red-dot-ruby-conference-2015\"\n  title: \"RubyMotion: Cross-Platform Mobile Development the Right Way\"\n  raw_title: \"RedDotRuby 2015 - RubyMotion: Cross-Platform Mobile Development the Right Way by Laurent Sansonetti\"\n  speakers:\n    - Laurent Sansonetti\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-11\"\n  description: |-\n    RubyMotion: Cross-Platform Mobile Development the Right Way by Laurent Sansonetti\n\n    RubyMotion is a toolchain to write cross-platform mobile apps for iOS and Android using the Ruby language. In this session we will cover how RubyMotion works, check out some of the high-level gems that can be used to speed up development, and finally discover that RubyMotion can also build cross-platform mobile games!\n  video_provider: \"youtube\"\n  video_id: \"ZV5zCXHIqNY\"\n\n- id: \"laura-eck-red-dot-ruby-conference-2015\"\n  title: \"Working Remotely as a Junior Developer\"\n  raw_title: \"RedDotRuby 2015 - Working Remotely as a Junior Developer by Laura Eck\"\n  speakers:\n    - Laura Eck\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-12\"\n  description: |-\n    Working remotely is one of the legendary opportunities that being\n    a web developer brings along. The freedom to work from wherever you want is, despite\n    certain tradeoffs, pretty awesome and something many developers enjoy.\n    For many less experienced developers, however, there’s a lot of open questions: Isn’t\n    it much harder for a junior? Will I be able to learn from my co-workers when I’m\n    remote? How the heck do I get my company to agree to this? And even if they agree,\n    how do I make it work?\n    I’m going to share from personal experience how, yes, it is harder for a junior, but it’s definitely possible and can even be a great\n    personal and professional experience. Starting out with how to negotiate a remote\n    work agreement with your company in the first place, this talk will then continue\n    with important issues and strategies that will help both junior devs that want\n    to work remotely as well as their companies to make remote work a success.\n  video_provider: \"youtube\"\n  video_id: \"XdFY-zpT4JY\"\n\n- id: \"juanito-fatas-red-dot-ruby-conference-2015\"\n  title: \"Lightning Talk: How Emoji Changed My Life\"\n  raw_title: \"RedDotRuby 2015 - Lightning Talk: How Emoji Changed My Life by Juanito Fatas\"\n  speakers:\n    - Juanito Fatas\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-11\"\n  description: |-\n    Lightning Talk: How Emoji Changed My Life by Juanito Fatas\n\n    What is Emoji? Why Emoji is important? How many kinds of emojis are there? Why should I use Emoji? How to use Emoji? How to use Emoji in Ruby? What can I do with Emoji? How Emoji affects meaning? How Emoji affects technology? How Emoji affects the society? How Emoji affects my life? Why I give a talk on Emoji? I will answer these questions and introduce you to the brand new emoji world.\n  video_provider: \"youtube\"\n  video_id: \"-ZW9kP4bJqY\"\n\n- id: \"hiroaki-iwase-red-dot-ruby-conference-2015\"\n  title: \"Lightning Talk: Ruby based Distributed Key Value Store 'ROMA'\"\n  raw_title: \"RedDotRuby 2015 - Ruby based Distributed Key Value Store 'ROMA' by Hiroaki Iwase\"\n  speakers:\n    - Hiroaki Iwase\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Ruby based Distributed Key Value Store 'ROMA' by Hiroaki Iwase\n\n    I am going to introduce ROMA(Ruby/Rakuten On-Memory Architecture). ROMA is one of the data storing systems for distributed key-value stores. It is a completely decentralized distributed system that consists of multiple processes, called nodes, on several machines. It is based on pure P2P architecture like a distributed hash table, thus it provides high availability and scalability. This has been developed as an OSS product written in Ruby from 2007. \n\n    I will also share a GUI management tool named 'Gladiator', which is developed for Ruby on Rails, enabling developers to control ROMA more easily and intuitively.\n  video_provider: \"youtube\"\n  video_id: \"AGHTYZ3B0gU\"\n\n- id: \"christopher-rigor-red-dot-ruby-conference-2015\"\n  title: \"Lightning Talk: How Docker Can Change Rails Deployments\"\n  raw_title: \"RedDotRuby 2015 - Lightning Talk: How Docker Can Change Rails Deployments by Christopher Rigor\"\n  speakers:\n    - Christopher Rigor\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-11\"\n  description: |-\n    How Docker Can Change Rails Deployments by Christopher Rigor\n\n    A typical Rails deployment involves using a tool like Capistrano to pull the code from your Git repository, symlink configuration files and restart the app server. \n\n    Docker offers improvements to this workflow but it's not all roses. Hear about the triumphs and challenges when moving from Capistrano deployments to Docker.\n  video_provider: \"youtube\"\n  video_id: \"9-l4tzPmAzU\"\n\n- id: \"joy-paas-red-dot-ruby-conference-2015\"\n  title: \"Lightning Talk: Values from Puzzles, Math, and Code\"\n  raw_title: \"RedDotRuby 2015 - Lightning Talk: Values from Puzzles, Math, and Code by Joy Paas\"\n  speakers:\n    - Joy Paas\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-11\"\n  description: |-\n    Lightning Talk: Values from Puzzles, Math, and Code by Joy Paas\n\n    This talk is about how my experiences from childhood doing puzzles and Maths help me as a professional developer. As a child, I loved puzzles. I used to hate Math and coding before but looking back at my childhood, I remembered how fun it is to solve problems and always remind myself about it.\n  video_provider: \"youtube\"\n  video_id: \"QIDtG1ikhLo\"\n\n- id: \"vaidehi-joshi-red-dot-ruby-conference-2015\"\n  title: \"Lightning Talk: Refactoring of Self\"\n  raw_title: \"RedDotRuby 2015 - Lightning Talk: Refactoring of Self by Vaidehi Joshi\"\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-11\"\n  description: |-\n    Lightning Talk: Refactoring of Self by Vaidehi Joshi\n\n    As new programmers, we don't always write beautiful code. In fact, most of our early code is quite bad. So we try to refactor it. \n\n    But refactoring also plays a significant role in our personal lives. As programmers, we 'refactor' ourselves on a daily basis. We implement different technologies, learn new skills, and confront our own mistakes every day -- all in an effort to become better at what we do. And in the process, we become better iterations of ourselves. \n\n    This talk will explore how programming challenges us to not only refactor our own code, but also our very own sense of self.\n  video_provider: \"youtube\"\n  video_id: \"-gAAhWfyh8Q\"\n\n# Break\n\n- id: \"yukihiro-matz-matsumoto-red-dot-ruby-conference-2015-panel-ruby\"\n  title: \"Panel: Ruby\"\n  raw_title: \"RedDotRuby 2015 - Ruby Panel\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n    - Hiroshi Shibata\n    - Aaron Patterson\n    - Aman Gupta\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-11\"\n  description: |-\n    Panel discussion with Matz, Hiroshi Shibata, Aaron Patterson and Aman Gupta\n\n  video_provider: \"youtube\"\n  video_id: \"HeWkqYelc7o\"\n\n- id: \"jesse-toth-red-dot-ruby-conference-2015\"\n  title: \"Tackling Large Ruby Refactorings with Confidence (and Science!)\"\n  raw_title: \"RedDotRuby 2015 - Tackling Large Ruby Refactorings with Confidence (and Science!) by Jesse Toth\"\n  speakers:\n    - Jesse Toth\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-04\"\n  published_at: \"2015-06-11\"\n  description: |-\n    Tackling Large Ruby Refactorings with Confidence (and Science!) by Jesse Toth\n\n    At GitHub, we recently replaced a large subsystem of our application – the permissions code – with a faster and more flexible version. In this talk, I’ll share our approach to this large-scale rewrite of a critical piece of our Rails application, and how we accomplished this feat while both preserving the performance of our app and proving the new technology over the course of the project.\n\n  video_provider: \"youtube\"\n  video_id: \"Kr82hUeI_qI\"\n\n## Day 2 - 5 June (Friday)\n\n# Registration + Breakfast\n\n# Opening Address for Day 2\n\n- id: \"sam-saffron-red-dot-ruby-conference-2015\"\n  title: \"Keynote: Off the Rails by Sam Saffron\"\n  raw_title: \"RedDotRuby 2015 - Keynote: Off the Rails by Sam Saffron\"\n  speakers:\n    - Sam Saffron\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Discourse is a rich JavaScript application with hundreds of assets.\n    To cater for it we occasionally need to go off the beaten track by amending and\n    extending Rails. This talk will cover diagnostic techniques, performance optimizations\n    and other general extensions and libraries that help make Discourse fast, fun\n    to develop and feature rich.\n  video_provider: \"youtube\"\n  video_id: \"aP5NNkzb4og\"\n\n- id: \"paolo-nusco-perrotta-red-dot-ruby-conference-2015\"\n  title: \"Refinements - the Worst Feature You Ever Loved\"\n  raw_title: \"RedDotRuby 2015 - Refinements - the Worst Feature You Ever Loved by Paolo Perrotta\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Refinements - the Worst Feature You Ever Loved by Paolo Perrotta\n\n    Refinements are cool. They are the biggest new language feature in Ruby 2. They help you avoid some of Ruby's most dangerous pitfalls. They make your code cleaner and safer. \n\n    Oh, and some people really hate them. \n\n    We're talking important people here. A few prominent community members tried to convince Matz to remove Refinements from Ruby. The latest JRuby is compatible with Matz's Ruby 2... except that it lacks Refinements. This innocent feature might end up splitting the Ruby ecosystem. \n\n    Are Refinements the best idea since blocks and modules, or a terrible mistake? Decide for yourself. In twenty minutes, I'll tell you the good, the bad and the ugly about refinements. At the end of this speech, you'll understand the trade-offs of this controversial feature – and know what all the fuss is about.\n  video_provider: \"youtube\"\n  video_id: \"_27-4-dbnA8\"\n\n# Break\n\n- id: \"hiroshi-shibata-red-dot-ruby-conference-2015\"\n  title: \"HTTP Programming with mruby\"\n  raw_title: \"RedDotRuby 2015 - HTTP Programming with mruby by Hiroshi Shibata\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-10\"\n  description: |-\n    HTTP Programming with mruby by Hiroshi Shibata\n\n    mruby is the lightweight implementation of the Ruby language and was released about a year ago. Can we use mruby to write web services? \n\n    This answer is YES - our company used mruby in large scaled web services. Even with mruby, we were able to create web services with tests and gems, and it also helped to solve some problems using Ruby code outside of a Rails application. In essence, mruby also provides programming features like HTTP to us web programmers.\n  video_provider: \"youtube\"\n  video_id: \"O9OqP-vmUKA\"\n\n- id: \"sofia-tania-red-dot-ruby-conference-2015\"\n  title: \"Collaborating with Contracts\"\n  raw_title: \"RedDotRuby 2015 - Collaborating with Contracts by Sofia Tania\"\n  speakers:\n    - Sofia Tania\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Collaborating with Contracts by Sofia Tania\n\n    In the real world, when two parties collaborate, there often needs to be a shared understanding - a 'contract'. So is the case when two components of a system collaborate. \n\n    In this talk, I will share about contract tests, when they become useful, and some tools to help.\n  video_provider: \"youtube\"\n  video_id: \"9_rjXgM4oec\"\n\n# Lunch\n\n- id: \"linda-liukas-red-dot-ruby-conference-2015\"\n  title: \"Principles of Play\"\n  raw_title: \"RedDotRuby 2015 - Principles of Play by Linda Liukas\"\n  speakers:\n    - Linda Liukas\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Principles of Play by Linda Liukas\n\n    If code is the colouring pens and lego blocks of our times - the tools of creation - how do we teach the curiosity, joy and wonder to our kids? I spent last summer looking at programming and play: how to create experiences that go deeper than just learning logic. \n\n    So, just like Alice, I swallowed the blue pill and fell down inside the machine. This talk summarises my three principles of play and a few experiments I’ve learned with little Ruby and the journey I’ve been on with her.\n  video_provider: \"youtube\"\n  video_id: \"vbboehbgAN8\"\n\n- id: \"guo-xiang-tan-red-dot-ruby-conference-2015\"\n  title: \"Starting & Contributing to Open Source Projects for Beginners\"\n  raw_title: \"RedDotRuby 2015 - Starting & Contributing to Open Source Projects for Beginners by Guo Xiang Tan\"\n  speakers:\n    - Guo Xiang Tan\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Starting & Contributing to Open Source Projects for Beginners by Guo Xiang Tan\n\n    Contributing to Open Source projects can be daunting for beginners but at the same time extremely rewarding. Before I started contributing, I was asking myself these questions: \n\n    * Rails is such a huge and complex code base, how can I contribute anything? \n\n    * I might be wrong, so I better not raise the issue or apply a \"lousy\" patch. \n\n    Having gone through the process, I hope to help answer those questions and give confidence to new developers that have yet to contribute to open source projects because of such fears. There are tools and techniques which I have learnt and picked up that can help new developers understand a foreign code base better which I would like to demonstrate as well. \n\n    In addition, I will like to talk about RubyBench.org, a long running Ruby benchmark that I helped to revitalized and launched. I will talk about why RubyBench.org matters to the community and how it is being structured. Following which, I will talk about my experience starting RubyBench.org and how rewarding it can be.\n  video_provider: \"youtube\"\n  video_id: \"0OQg42gSol4\"\n\n- id: \"radamanthus-batnag-red-dot-ruby-conference-2015\"\n  title: \"Lightning Talk: Doodling for Great Success\"\n  raw_title: \"RedDotRuby 2015 - Lightning Talk: Doodling for Great Success by Radamanthus Batnag\"\n  speakers:\n    - Radamanthus Batnag\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Lightning Talk: Doodling for Great Success by Radamanthus Batnag\n\n    As coders, we are very familiar with how to communicate using written words. But words exercise only half of our brain. Using sketches to enhance our message leads to more effective communication. It is fun, too! \n\n    I will discuss sketching tips that everyone - even those who think they have no drawing skills - can use right away. These can be applied to blog posts, open-source documentation, bug reports, and even emails.\n  video_provider: \"youtube\"\n  video_id: \"tyNrAzTbx3I\"\n\n- id: \"elisha-tan-red-dot-ruby-conference-2015\"\n  title: \"Lightning Talk: Non-tech Contributions to The Tech Community\"\n  raw_title: \"RedDotRuby 2015 - Lightning Talk: Non-tech Contributions to The Tech Community by Elisha Tan\"\n  speakers:\n    - Elisha Tan\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Lightning Talk: Non-tech Contributions to The Tech Community by Elisha Tan\n\n    \"I'm not skilled enough a programmer to contribute\" is a common response I get when I ask programmers why don't they contribute to the open source community. In this lightning talk, I share some ways that you can contribute to the community (hint: it's all non-technical and anyone can do it) even if you're half a decent coder like me.\n  video_provider: \"youtube\"\n  video_id: \"lrqhNYZn-3o\"\n\n- id: \"grzegorz-witek-red-dot-ruby-conference-2015\"\n  title: \"Lightning Talk: My Web Application Goes to China!\"\n  raw_title: \"RedDotRuby 2015 - Lightning Talk: My Web Application Goes to China! by Grzegorz Witek\"\n  speakers:\n    - Grzegorz Witek\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-10\"\n  description: |-\n    Lightning Talk: My Web Application Goes to China! by Grzegorz Witek\n\n    When your web application launches in Japan, you translate the product, you launch another server, and there you go! When your web application launches in France, you translate the product, you launch another server, and there you go. When your web application launches in China, you translate the product, you launch another server, and then… then you learn about plenty of other things that you need to do if you want to avoid failure!\n  video_provider: \"youtube\"\n  video_id: \"gfVEOD612tM\"\n\n- id: \"tomoya-kawanishi-red-dot-ruby-conference-2015\"\n  title: \"Lightning Talk: Kansai Regional Rubyist Meetups\"\n  raw_title: \"RedDotRuby 2015 - Lightning Talk: Kansai Regional Rubyist Meetups by Tomoya Kawanishi\"\n  speakers:\n    - Tomoya Kawanishi\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-10\"\n  description: |-\n    I would like to tell the story about Ruby Kansai and Kansai Regional Rubyist Meetups. \n\n    The first part describes Ruby Kansai and myself. Ruby Kansai is one of the oldest Ruby Meetup in Japan, that is born in 2004. I am the founder of Ruby Kansai and now the chairman of Ruby Kansai. \n\n    I would like to share what I have learned through the experience of organizing Ruby Kansai and what motivates me to do so. \n\n    The second part is about the story of regional Ruby meetups in Kansai. Recently many people have founded Ruby meetups in Kansai. Now over 10 Ruby meetups are active in Kansai. I also founded one regional, small Ruby meetup -- Amagasaki.rb. \n\n    I would like to share with everyone the differences between big meetup like Ruby Kansai where over 80 people attend and small meetup like amagasaki.rb where less than 10 people attend. Both styles of meetup have good and bad parts. \n\n    Lightning Talk: Kansai Regional Rubyist Meetups by Tomoya Kawanishi\n\n    The last part is the future of Ruby Kansai. As the oldest and biggest Kansai Ruby community, Ruby Kansai would like to be hub, which connects beginners and experts, local and remote Rubyists, Ruby and other languages, suits and geeks.\n  video_provider: \"youtube\"\n  video_id: \"5QVOtEqIBXk\"\n\n# Break\n\n- id: \"yuki-nishijima-red-dot-ruby-conference-2015\"\n  title: \"'Did you mean?' experience in Ruby and beyond\"\n  raw_title: \"RedDotRuby 2015 - 'Did you mean?' experience in Ruby and beyond by Yuki Nishijima\"\n  speakers:\n    - Yuki Nishijima\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-11\"\n  description: |-\n    'Did you mean?' experience in Ruby and beyond by Yuki Nishijima\\n\\ndid_you_mean\n    gem is a gem that adds a Google-like suggestion feature to Ruby. Whenever you\n    mis-spell a method name, it'll read your mind and tell you the right one. \\n\\nAlthough\n    the history of the gem isn't long, it got so many improvements since it's first\n    released back in February 2014. In this talk, I'll talk about what improvements\n    have been made after a quick introduction of how it works. \\n\\nHave a custom Exception\n    class and want to make it 'correctable'? Let's learn how to create your own finder\n    so you can improve your coding experience in Ruby.\n  video_provider: \"youtube\"\n  video_id: \"sca1C0Qk6ZE\"\n\n- id: \"aaron-patterson-red-dot-ruby-conference-2015\"\n  title: \"Code is Required\"\n  raw_title: \"RedDotRuby 2015 - Code is Required by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Red Dot Ruby Conference 2015\"\n  date: \"2015-06-05\"\n  published_at: \"2015-06-11\"\n  description: |-\n    Code is Required by Aaron Patterson\n\n    You can't talk about running code without talk about loading code. Part of improving the performance of Rails applications is looking at parts that impact Rails from outside of your application. In this talk, we'll look at the different ways Ruby loads code and how this impacts our applications. This talk will be more than you ever wanted to know about how Ruby loads files, and how we can speed it up.\n\n  video_provider: \"youtube\"\n  video_id: \"_bDRR_zfmSk\"\n# After Party\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2016/event.yml",
    "content": "---\nid: \"PLECEw2eFfW7iiJpXtb_cYeKv5_A6Pd1tl\"\ntitle: \"Red Dot Ruby Conference 2016\"\nkind: \"conference\"\nlocation: \"Singapore, Singapore\"\ndescription: |-\n  Two Days • Single Track • June 23 and 24, 2016 • Singapore\npublished_at: \"2016-06-26\"\nstart_date: \"2016-06-23\"\nend_date: \"2016-06-24\"\nchannel_id: \"UCjRZr5HQKHVKP3SZdX8y8Qw\"\nyear: 2016\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#282F39\"\nwebsite: \"https://web.archive.org/web/20160704212007/http://www.reddotrubyconf.com/\"\ncoordinates:\n  latitude: 1.352083\n  longitude: 103.819836\naliases:\n  - RedDotRubyConf 2016\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2016/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20160704212007/http://www.reddotrubyconf.com/\n# Schedule: https://web.archive.org/web/20160704212007/http://www.reddotrubyconf.com/\n\n## Day 1 - June 23 (Thursday)\n\n# Registration\n\n# Opening Address\n\n- id: \"yukihiro-matz-matsumoto-red-dot-ruby-conference-2016\"\n  title: \"Keynote: Ruby Typing\"\n  raw_title: \"Keynote: Ruby Typing - RedDotRubyConf 2016\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Yukihiro (Matz) Matsumoto, Creator of Ruby, Heroku\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"EB8j-i5x6Hc\"\n\n- id: \"jason-yeo-red-dot-ruby-conference-2016\"\n  title: \"Slaying the Dragon\"\n  raw_title: \"Slaying the Dragon - RedDotRubyConf 2016\"\n  speakers:\n    - Jason Yeo\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Jason Yeo, Software Engineer, SourceClear\n    Learning to\n    write a programming language is considered a rite of passage for some programmers.\n    And, it is also the most rewarding exercise as you will learn a whole lot about\n    programming languages in general. Many might think it's a daunting task but I\n    will show you otherwise by showing how to implement a simple language in Ruby\n    and compile it to Rubinius bytecode. Be warned, only the brave and true will survive.\n    Don't you worry though, no prior knowledge of parsing, lexing and programming\n    language theory required. And of course, don't forget to have fun.\n    Speaker's\n    Bio\\nJason Yeo flips bits and smashes stacks at SourceClear. Some of his interests\n    include participating in pointless discussions about type systems, writing interpreters\n    for languages that has no real world application, bashing languages that has real\n    world applications and embedding Easter Eggs in talk descriptions.\\U0001F61D\n    Event\n    Page: http://www.reddotrubyconf.com/\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"oVVnaJ6ZZm0\"\n\n# Break\n\n- id: \"kristine-joy-paas-red-dot-ruby-conference-2016\"\n  title: \"Let's Play Ruby Golf\"\n  raw_title: \"Let's Play Ruby Golf - RedDotRubyConf 2016\"\n  speakers:\n    - Kristine Joy Paas\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Kristine Joy Paas, Web Developer, Quipper\n\n    Professional coding means writing clear, readable, maintainable code. 'Golf' in programming means implementing something with as short as possible code. Golf code is everything that a professional code shouldn't be. However, there are so many things that we can only discover by playing Ruby golf. In this talk, I will share the Ruby secrets I discovered from Ruby golf, and also the extreme ingenuity that comes into play when trying to write the shortest code to solve a problem.\n\n    Speaker's Bio\n    Joy is a cat-loving Rubyist and 'student of life' based in Manila. She is currently works as a web develop at Quipper, an EdTech company. When not into coding, she engages in other enjoyable activities where she can learn new things. Recently, she into watching anime and reading manga to improve her Japanese language skills.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"ccMafa0wlow\"\n\n- id: \"prathamesh-sonpatki-red-dot-ruby-conference-2016\"\n  title: \"Secrets of Testing Rails 5 Apps\"\n  raw_title: \"Secrets of Testing Rails 5 Apps - RedDotRubyConf 2016\"\n  speakers:\n    - Prathamesh Sonpatki\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Prathamesh Sonpatki, Director, BigBinary LLC\n\n    Testing Rails 5 apps has become better experience out of the box. Rails has also become smarter by introducing the test runner. Now we can't complain that about not able to run a single test or not getting coloured output. A lot of effort gone into making tests especially integration tests run faster. Come and join me as we will commence the journey to uncover the secrets of testing Rails 5 apps.\n\n    Speaker's Bio\n    Prathamesh is Director at BigBinary. He builds web apps using Rails and React.js!. He is interested in open source and contribute to many Ruby and Rails related projects. He likes Emacs operating system a lot and can be found constantly tweaking his .emacs.d\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"WAznFdX1O4g\"\n\n# Lunch\n\n- id: \"godfrey-chan-red-dot-ruby-conference-2016\"\n  title: \"Keynote: Rethinking Computer Science Education\"\n  raw_title: \"Keynote: Rethinking Computer Science Education - RedDotRubyConf 2016\"\n  speakers:\n    - Godfrey Chan\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Godfrey Chan, Rails Core, Tilde\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"jDYLsHKx4CA\"\n\n- id: \"grzegorz-witek-red-dot-ruby-conference-2016\"\n  title: \"Your API is Too Slow!\"\n  raw_title: \"Your API is Too Slow! - RedDotRubyConf 2016\"\n  speakers:\n    - Grzegorz Witek\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Grzegorz Witek, Lead Software Engineer, Kaligo\n\n    While premature optimization might be the root of all evil, at some point, whether you want it or not, you must look at your beautiful (and of course fully tested) code, and make it a bit less pretty, but much, much faster. API performance optimization does not need to be scary, though. To start you just need some benchmarking tools and a few optimization techniques. In my talk I'm going to present example problems and solutions that will make speeding up API much easier.\n\n    Speaker's Bio\n    I boost economy by making bugs here and there, so that others always have something to fix and they can keep their jobs. Constantly afraid of stack overflows, I work as an empty-stack developer.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"3w_2Cx28lcE\"\n\n- id: \"jo-cranford-red-dot-ruby-conference-2016\"\n  title: \"Lightning Talk: Where Did Everybody Go?\"\n  raw_title: \"Where Did Everybody Go? - RedDotRubyConf 2016\"\n  speakers:\n    - Jo Cranford\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Jo Cranford, Lead Developer, Culture Amp\n\n    In our current market, almost of half of our employers are hiring for experienced developers. Many people move jobs every couple of years, leaving teams in an ongoing state of forming or storming, unable to find their rhythm. Company culture is a major influence on people deciding to stay in their jobs. This talk uses data gathered from over 100,000 responses to engagement and exit surveys from fast growing, successful tech companies to analyse why people leave, and how we can encourage our team members to stay (hint: it's not pay!)\n\n    Speaker's Bio\n    Jo is lead developer at Culture Amp, the world’s leading culture analytics platform. Before her current role, Jo worked at the likes of Lonely Planet, Atlasssian, ThoughtWorks and Expedia, in roles such as Product Planner, Senior Business Analyst, Development Manager and Chief Technical Officer. She was also a CTO of an Australian startup accepted into Telstra’s Muru-D program.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"eOHr_yp793M\"\n\n- id: \"hiroshi-shibata-red-dot-ruby-conference-2016\"\n  title: \"Lightning Talk: How to Begin Developing Ruby Core\"\n  raw_title: \"How to Begin Developing Ruby Core - RedDotRubyConf 2016\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: SHIBATA Hiroshi, Chief Engineer, GMO Pepabo, Inc.\n\n    When you need to contribute a new library or framework, you might try to write test and invoke the test suite with “rake test” or “rake spec”. CRuby also has a test suite like many libraries and frameworks, written in Ruby. But, It's different from typical ruby libraries. Therefore many Rubyists don't know how to run the CRuby test suite. In this talk, I explain the details of the CRuby test suite and contribution protips for CRuby's development for beginners.\n\n    Speaker's Bio\n    Ruby core team, Chief engineer at GMO Pepabo, Inc.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"1flEEFrqy34\"\n\n- id: \"ankita-gupta-red-dot-ruby-conference-2016\"\n  title: \"Lightning Talk: Speeding Up Your Test Suite\"\n  raw_title: \"Speeding Up Your Test Suite - RedDotRubyConf 2016\"\n  speakers:\n    - Ankita Gupta\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Ankita Gupta, Full-Stack Software Engineer, Honestbee\n\n    We often hear about Test Driven Development (TDD), and RSpec is a great aid in doing so. However what could be one of the biggest disadvantages of writing tests? The answer is slow tests. Yes, its true that if there were no tests then there would not be a slow test suite. But that's not the point. Tests are a developer's friend, and in this talk I will talk more about how to use FactoryGirl appropriately to speed up your RSpecs.\n\n    Speaker's Bio\n    Ankita is working as a full-stack software engineer at honestbee. In her free time, she works on her non-profit project Jugnuu, a low-cost, mobile-based English language solution for children.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"XcupLVUZx4Q\"\n\n- id: \"giovanni-sakti-red-dot-ruby-conference-2016\"\n  title: \"Lightning Talk: Flexible Authorization - Storing and Managing Rules in DB\"\n  raw_title: \"Flexible Authorization:Storing and Managing Rules in DB - RedDotRubyConf 2016\"\n  speakers:\n    - Giovanni Sakti\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Giovanni Sakti, CEO and Software Developer, Starqle\n\n    Many excellent authorization system already exist as gems, however most of them left the implementation detail of storing authorization rules in database up for grabs. Storing them in database is important because it enables end user to configure it by themselves rather than depending on the developers to manage them. Learn how you can effectively store and manage authorization rules on database, effectively utilize policy-based authorization system such as Pundit for this purpose and learn about database design that can handle authorization better.\n\n    Speaker's Bio\n    Gio is software developer from Jakarta, Indonesia whom currently works for two startups; Starqle and Virkea that mostly do enterprise software developments. He also co-organizes local Ruby and Javascript developers community. When not coding, he loves doing sports, such as watching live football and tennis on TV, playing football games on PC and obviously reading fans banter on twitter.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"3MbHQoqI4Jo\"\n\n# Break\n\n- id: \"tim-riley-red-dot-ruby-conference-2016\"\n  title: \"Next Generation Ruby Web Appswith dry-rb, ROM, and Roda\"\n  raw_title: \"Next Generation Ruby Web Appswith dry-rb, ROM, and Roda - RedDotRubyConf 2016\"\n  speakers:\n    - Tim Riley\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Tim Riley, Partner, Icelab\n\n    If you’ve ever yearned for more than the Rails way, come along and learn how a small set of tools and techniques can bring joy to your Ruby web app development, from the smallest beginnings through to the most complex of codebases. Discover how concepts like functional programming, immutability, strict typing, dependency injection and object composition can actually be easy and natural in Ruby (yes, really!), and how they will make your web app a pleasure to build, test and extend.\n\n    Speaker's Bio\n    Tim is a partner at Australian design agency Icelab, and a core developer of dry-rb. He’s excited about advancing the state of web development in Ruby.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"6ecNAjVWqaI\"\n\n- id: \"sau-sheong-chang-red-dot-ruby-conference-2016\"\n  title: \"Keynote: Programming Complexity - Modeling Complex Systems with Ruby and React\"\n  raw_title: \"Programming Complexity: Modeling Complex Systems with Ruby and React - RedDotRubyConf 2016\"\n  speakers:\n    - Sau Sheong Chang\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-23\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Sau Sheong Chang, Managing Director, Digital Technology, Singapore Power\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"UJEwS4_fILQ\"\n\n## Day 2 - June 24 (Friday)\n\n# Registration\n\n# Opening Address\n\n- id: \"aaron-patterson-red-dot-ruby-conference-2016\"\n  title: \"Keynote: Taking Out The Trash\"\n  raw_title: \"Keynote: Taking Out The Trash - RedDotRubyConf 2016\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Aaron Patterson, Ruby & Rails Core, GitHub\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"-cCTB49AqvM\"\n\n- id: \"sameer-deshmukh-red-dot-ruby-conference-2016\"\n  title: \"Scientific Computing in Ruby\"\n  raw_title: \"Scientific Computing in Ruby - RedDotRubyConf 2016\"\n  speakers:\n    - Sameer Deshmukh\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Sameer Deshmukh, Undergraduate, University of Pune, India\n\n    Most Scientific Computing was restricted to languages like FORTRAN and Python, until now. The Ruby Science Foundation (SciRuby) aims to change that by creating tools for Scientific Computation in Ruby by leveraging Ruby’s elegance to reduce the inherent complexity that comes with Scientific Computing. In this talk you will be introduced to several gems developed by SciRuby for Scientific Computing. You will get a glimpse into powerful libraries like nmatrix, nyaplot and daru, that can be used for performing super fast computations and beautiful visualizations, all the while keeping code sane, simple and readable.\n\n    Speaker's Bio\n    Sameer is an undergraduate student at University of Pune, India. He is a contributor to the Ruby Science Foundation, where he helps build scientific computation tools in Ruby. He is currently maintaining daru, a library for data analysis and manipulation in Ruby. He enjoys spending spare time with friends, books and his bass guitar.\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"3JWZMT46FSI\"\n\n# Break\n\n- id: \"konstantin-hasse-red-dot-ruby-conference-2016\"\n  title: \"How We Replaced Salary Negotiations with a Sinatra App\"\n  raw_title: \"How We Replaced Salary Negotiations with a Sinatra App - RedDotRubyConf 2016\"\n  speakers:\n    - Konstantin Hasse\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Konstantin Hasse, Co-Founder and CTO, Travis CI\n\n    Let's talk about salaries, diversity, career development, getting compensated in gold and silver, paying taxes in livestock and Ruby code. For the last year, we at Travis CI have been working on a new salary system to determine how much we pay whom, when employees get raises and a whole range of other things. After lots of back and forth, we ended up with a Sinatra application to solve salary questions. Expect to explore the topic from many different angles and levels. We'll look at decisions, realisations and implications, as well as interesting parts of the implementation.\n\n    Speaker's Bio\n    Co-Founder and CTO at Travis CI, former opera star\n\n    Slides: https://speakerdeck.com/rkh/how-we-replaced-salary-negotiations-with-a-sinatra-app\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"N8u9H6JDAzo\"\n  slides_url: \"https://speakerdeck.com/rkh/how-we-replaced-salary-negotiations-with-a-sinatra-app\"\n\n- id: \"vipul-a-m-red-dot-ruby-conference-2016\"\n  title: \"Speeding Up Your Front-End: 2016 Version\"\n  raw_title: \"Speeding Up Your Front-End: 2016 Version - RedDotRubyConf 2016\"\n  speakers:\n    - Vipul A M\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Vipul Amler, Director, BigBinary LLC\n\n    Rails 5 and Sprockets 3/4, have made amazing strides in terms of performance, and dev-experience. Sprockets adds various resolution fixes to speed it up by more that 12x, allows to use ES6/ES2015, adopts good approaches from npm, and adds experimental features like Subresource Integrity. On Rails too, there are many improvements for speeding up front-end resources- Custom HTTP headers for static assets, Fragment caching improvements, ETag improvements, http_cache_forever and more. In this talk, we will see how to harness many of these to speed up page loads/cache and Google Pagespeed.\n\n    Speaker's Bio\n    Vipul is Director at BigBinary LLC. He is part of Rails Team, and helps triaging issues. His spare time is spent exploring and contributing to many Open Source ruby projects, when not dabbling with React JS. He has recently authored ReactJS by Example, that does a deep walk-through of using ReactJS. Vipul loves Ruby's vibrant community and helps in building PuneRb, is the founder of and runs RubyIndia Community. He also organizes DeccanRubyConf in Pune.\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"8NzPKuUm0fI\"\n\n# Lunch\n\n- id: \"sayanee-basu-red-dot-ruby-conference-2016\"\n  title: \"Sense and Sensibility\"\n  raw_title: \"Sense and Sensibility - RedDotRubyConf 2016\"\n  speakers:\n    - Sayanee Basu\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Sayanee Basu, Technology Consultant, Ricoh Singapore\n\n    As the era of tiny low-powered connected sensors beckons, how can Ruby and Rails developers come to play a pivotal role? In this talk, we will explore the backend functionalities and features that a connected sensor will talk to and make sense of the data collected. Through the open source Rails-based framework ThingSpeak, we will explore the 3 key features such a platform requires and give practical hardware demos and code snippets. Audience participation is all welcome! So hey, let's explore and make sense together!\n\n    Speaker's Bio\n    Sayanee is an engineer with a focus on electronics and web technologies. She curates the developer and design community of Singapore through We Build SG and creates screencasts on developer tools with Build Podcast. At other times, she enjoys a good workout, reading her eBooks and slowly drinking some tea.\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"c7JHVgJWJgc\"\n\n- id: \"yasuko-ohba-red-dot-ruby-conference-2016\"\n  title: \"Our Fight Against Super Bad Patterns in Legacy Rails Apps\"\n  raw_title: \"Our Fight Against Super Bad Patterns in Legacy Rails Apps - RedDotRubyConf 2016\"\n  speakers:\n    - Yasuko Ohba\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Yasuko Ohba, President, Everyleaf Corporation\n\n    In 2014-2015 my team migrated a series of applications from Rails 2.3.5 to 4.2.1, and Ruby 1.8 to 2.1. Our goal was to add large features, while substantially refactoring the whole system. It was a big challenge!This talk will cover the timeline of the project and talk about all the things a team performing a large migration of Ruby and Rails will need to do. Secondly, you will learn about some \"super bad\" Rails code patterns we encountered and how we refactored them. Real life experience distilled!\n\n    Speaker's Bio\n    A Ruby / Rails programmer in Tokyo, Japan. President of Everyleaf Corporation, which provides software development service mostly with Rails for clients since 2007. I have written 2 books on Ruby in Japan. A mother of a 3 year old girl.\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"1ZfWHNXIDmE\"\n\n- id: \"kenji-mori-red-dot-ruby-conference-2016\"\n  title: \"Lightning Talk: Learning Through Blogging: Ruby Blogging Benefits\"\n  raw_title: \"Learning Through Blogging: Ruby Blogging Benefits - RedDotRubyConf 2016\"\n  speakers:\n    - Kenji Mori\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Kenji Mori, Software Developer, M3 Inc\n\n    Sharing one's own knowledge is very important. I have been writing a blog which is fairly well-known in the Japanese Ruby community, and received many benefits in doing so. Blog-writing supports the accumulation of my own knowledge. Giving presentations provides many opportunities. Sharing ideas with our coworkers provides positive motivation to learn. I would like to talk about my positive experience!\n\n    Speaker's Bio\n    I am Japanese software developer and a passionate Rubyist since 2012 / Ruby 1.9.3. I write a blog which is fairly well-known in the Japanese Ruby community: http://morizyun.github.io/ Recently I sometimes present at local events in Japan, a few of my presentations include: https://speakerdeck.com/morizyun I work at M3, Inc. a Japan-based global company focused on improving medicine in Japan and worldwide, developing services for doctors.\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"QFo2VbjwGSs\"\n  slides_url: \"https://speakerdeck.com/morizyun/learning-through-blogging-ruby-blogging-benefits\"\n\n- id: \"jack-chen-songyong-red-dot-ruby-conference-2016\"\n  title: \"Lightning Talk: Grow from Small Simple Steps Forward\"\n  raw_title: \"Grow from Small Simple Steps Forward - RedDotRubyConf 2016\"\n  speakers:\n    - Jack Chen Songyong\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Jack Chen Songyong, Technical Director, Skymatters Limited\n\n    Many great developers love to contribute to open source code base. But you don't have to be very experienced before doing so. This short talk is to take one of my pull requests to a Ruby gem library as an example, from the incentive, the conversations between maintainers and me, to what I learnt.\n\n    Speaker's Bio\n    Jack works at Skymatters Limited as the technical director. He is keen to open-source projects and gave talks at tech conferences (esp. Codeaholics HK). He also believes running a marathon and coding a project have so many in common.\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"1RTukd7j_UE\"\n\n- id: \"yuki-nishijima-red-dot-ruby-conference-2016\"\n  title: \"Lightning Talk: 20 Tools and Techniques that Make You More Creative\"\n  raw_title: \"20 Tools and Techniques that Make You More Creative - RedDotRubyConf 2016\"\n  speakers:\n    - Yuki Nishijima\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Yuki Nishijima, Software Engineer, Pivotal\n\n    Have you ever been frustrated because you needed to do many things to get a small task done? Here are tools and techniques that can make you more creative! In this talk, I'll share with you ways to speed you up, from Ruby and Rails features, command line tools, shell scripting, browser extensions, keyboard shortcuts, to Mac apps. You are a beginner? Or have more than a decade of experience? No problem! You'll learn at least one technique you don't know yet that you can start using right away!\n\n    Speaker's Bio\n    Yuki was raised in Tokyo and has worked for Pivotal Labs in New York since 2013. He moved back to Tokyo in August 2015 as one of the founding members of Pivotal Labs Tokyo. He is a Ruby committer, the creator of the did_you_mean gem, a maintainer of the kaminari gem, and a frequent contributor to many open source projects including Rails.\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"AsNfud9Y704\"\n\n- id: \"steven-yap-red-dot-ruby-conference-2016\"\n  title: \"Lightning Talk: Building Real-Time App with React/Redux/Rails/RethinkDB\"\n  raw_title: \"Building Real-Time App with React/Redux/Rails/RethinkDB - RedDotRubyConf 2016\"\n  speakers:\n    - Steven Yap\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Steven Yap, Founder, Futureworkz\n\n    Building real-time app is painful for the frontend, painful for the backend and even painful for the database. We will share how we build a real-time CRM app using React, Redux, Rails and RethinkDB (we call it the R4 framework) that is easy to reason and easy to build. Put fun back into real-time app development!\n\n    Speaker's Bio\n    Steven Yap is a full-stack coder, agile coach and development consultant. He balances his life with Buddhism teachings and seeks enlightenment through coding and the work he is involved in. He founded and runs Futureworkz, a Singapore Agile agency since 2005. Steven Yap hosts the monthly Ruby Meetup in Ho Chi Minh, Vietnam - Saigon.rb.\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"CwF44oMOvJs\"\n\n- id: \"xin-tian-red-dot-ruby-conference-2016\"\n  title: \"Lightning Talk: Journey to becoming a techlady\"\n  raw_title: \"Journey to becoming a techlady - RedDotRubyConf 2016\"\n  speakers:\n    - Xin Tian\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Xin Tian, Graduate of TechLadies Bootcamp\n\n    A lot of developers see the gender imbalance in the tech community and are actively volunteering their time and resources to teach more women how to code. In this talk, I will share my experiences learning how to code through the TechLadies Bootcamp, what challenges I’ve faced, and how you can help newbies pick up Ruby and Rails.\n\n    Speaker's Bio\n    Xin Tian is a Masters dropout, customer service rep, and a graduate from the TechLadies Bootcamp. She now also co-organises the TechLadies Tech Talks and TechLadies Code Pairadise, providing a newbie-friendly environment for women to learn coding.\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"KH9VVYA_U6c\"\n\n# Break\n\n- id: \"kir-shatrov-red-dot-ruby-conference-2016\"\n  title: \"Building a ChatOps framework\"\n  raw_title: \"Building a ChatOps framework - RedDotRubyConf 2016\"\n  speakers:\n    - Kir Shatrov\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Kir Shatrov, Production Engineer, Shopify\n\n    At Shopify, we run a massive ChatOps deployment that ties out Internal tools together. We’re developing a platform for the useful scripts written by developers around the company to be discoverable. The platform makes it simple for any employee to automate workflow by writing a script. I will talk about the history of ChatOps and its culture at Shopify, about the reasons behind creating our own chat framework, building the DSL and grammar rules parser, scaling ChatOps and providing the better chat experience than other frameworks have.\n\n    Speaker's Bio\n    Kir Shatrov is a Production Engineer at Shopify, a current maintainer of Capistrano and a Rails contributor. He coaches RailsGirls and hosts the RubyNoName Podcast.\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"bnwrkVXu-cw\"\n\n- id: \"terence-lee-red-dot-ruby-conference-2016\"\n  title: \"Closing Keynote: After a Decade, Still a Rubyist\"\n  raw_title: \"Closing Keynote: After a Decade, Still a Rubyist - RedDotRubyConf 2016\"\n  speakers:\n    - Terence Lee\n  event_name: \"Red Dot Ruby Conference 2016\"\n  date: \"2016-06-24\"\n  published_at: \"2016-06-26\"\n  description: |-\n    Speaker: Terence Lee, Ruby Core, Heroku\n\n    Event Page: http://www.reddotrubyconf.com\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"5WZmE3uXRWw\"\n# After Party\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2017/event.yml",
    "content": "# https://github.com/reddotrubyconf/rdrc2017-website\n---\nid: \"PLECEw2eFfW7i2QFhenTaVFON6sbEhcSSa\"\ntitle: \"Red Dot Ruby Conference 2017\"\nkind: \"conference\"\nlocation: \"Singapore, Singapore\"\ndescription: |-\n  Two Days • Single Track • June 22 and 23, 2017 • Singapore\npublished_at: \"2017-06-26\"\nstart_date: \"2017-06-22\"\nend_date: \"2017-06-23\"\nchannel_id: \"UCjRZr5HQKHVKP3SZdX8y8Qw\"\nyear: 2017\nbanner_background: \"#F1C056\"\nfeatured_background: \"#F1C056\"\nfeatured_color: \"#7A212E\"\nwebsite: \"https://web.archive.org/web/20170702090129/http://www.reddotrubyconf.com/\"\ncoordinates:\n  latitude: 1.352083\n  longitude: 103.819836\naliases:\n  - RedDotRubyConf 2017\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2017/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20170702090129/http://www.reddotrubyconf.com/\n# Schedule: https://web.archive.org/web/20170702090129/http://www.reddotrubyconf.com#schedule\n\n## Day 1 - June 22 (Thursday)\n\n# Registration || Breakfast\n\n# Opening Address\n\n- id: \"yukihiro-matz-matsumoto-red-dot-ruby-conference-2017\"\n  title: \"Keynote: Simple goal. Hard to accomplish\"\n  raw_title: \"Keynote: Simple goal. Hard to accomplish - RedDotRubyConf 2017\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-22\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Yukihiro (Matz) Matsumoto\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"3NRTzTccoI0\"\n\n- id: \"tim-riley-red-dot-ruby-conference-2017\"\n  title: \"Functional Architecture for the Practical Rubyist\"\n  raw_title: \"Functional Architecture for the Practical Rubyist - RedDotRubyConf 2017\"\n  speakers:\n    - Tim Riley\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-22\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Tim Riley, Partner and Developer, Icelab\n\n    We build our Ruby apps with the best of intentions, but it's all too easy for them to become tangled and hard to maintain. If you've reached for object-oriented design principles as your path forward, and found them elusive or hard to apply, there is still hope! It turns out that some of our best OO code may live behind an FP curtain. Come along and discover how a functional architecture can make your Ruby apps not only SOLID, but a real joy to build, test, and extend.\n\n    Speaker's Bio\n\n    Tim Riley is a partner at Australian design agency Icelab, and a core developer of dry-rb. He's excited by small libraries, first-class functions, and pushing forward web app development with Ruby.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"7qnsRejCyEQ\"\n\n# Break\n\n- id: \"daniel-bovensiepen-red-dot-ruby-conference-2017\"\n  title: \"Ruby on Wheelchair\"\n  raw_title: \"Ruby on Wheelchair - RedDotRubyConf 2017\"\n  speakers:\n    - Daniel Bovensiepen\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-22\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Daniel Bovensiepen, Senior Research Scientist, Siemens\n\n    What would you do if you end up in a Wheelchair after an accident and you are not satisfied with the feature-set of the chair? You could buy a better one... Or you put Ruby on it and add the features you are missing. This talk will show you how you can hack your Wheelchair by using mruby, Microcontrollers and many other things never seen on a Wheelchair before. Let's put Ruby on a Wheelchair!\n\n    Speaker's Bio\n\n    Daniel is a research scientist in the field of industrial automation and manufacturing. He empowers Ruby in areas nobody has seen it before. At night he is contributing to mruby to push it to even more areas of his daily job.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"b5DFKEYA7AU\"\n\n- id: \"jun-qi-tan-red-dot-ruby-conference-2017\"\n  title: \"All I'd Wanted to Know about Ruby's Object Model Starting Out...and Mooar!!!\"\n  raw_title: \"All I'd Wanted to Know about Ruby's Object Model Starting Out...and Mooar!!! - RedDotRubyConf 2017\"\n  speakers:\n    - Jun Qi Tan\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-22\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Jun Qi Tan, Final-year Student, SUTD\n\n    One of the most fun yet confusing things about Ruby is its object model. It's something that can seem highly cryptic to beginners, and perhaps not even that well understood by experienced Rubyists. Not too far into my Ruby journey, I began to get a taste of metaprogramming, but even as I learnt and grew more familiar with common idioms, I always had a nagging feeling that my underlying mental model didn't quite cut it, so I decided to iron it out. The more I read, the more intrigued I became, until I ended up diving into the CRuby source itself! Here's the story of what I learnt about Ruby's object model, in a way that's both digestible for beginner/intermediates and also insightful for the more experienced. It will also be the story of my journey from feeling like a newbie lacking confidence in my ability to understand something as complex as CRuby, to taking the plunge and learning how to fearlessly read the source!\n\n    Speaker's Bio\n\n    Jun Qi is currently a final year student at the Singapore University of Technology and Design. She was introduced to the world of Ruby, Rails, and web development slightly more than a year ago, and has enjoyed digging deeper and playing around with various web technologies since.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"268UU4EpTew\"\n\n# Lunch\n\n- id: \"betsy-haibel-red-dot-ruby-conference-2017\"\n  title: \"Better code through boring(er) tests\"\n  raw_title: \"Better code through boring(er) tests - RedDotRubyConf 2017\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-22\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Betsy Haibel\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"u30qyBRuFXY\"\n\n- id: \"weiqing-toh-red-dot-ruby-conference-2017\"\n  title: \"Meta-programming for Dummies\"\n  raw_title: \"Meta-programming for Dummies - RedDotRubyConf 2017\"\n  speakers:\n    - Weiqing Toh\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-22\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Weiqing Toh, Software Engineer, Ministry of Education\n\n    The construct of the Ruby language allows for meta-programming, or 'code which modifies code at runtime'. However, meta-programming is a double-edged sword; as much as it is useful, it could very easily be misused by teams as well. In this talk, I will cover the benefits of meta-programming and some (basic) fundamentals (in the context of Ruby on Rails) and discuss pitfalls, anti-patterns, and considerations by teams before adopting meta-programming. Don't worry, this is easily digestible for rubyists of all levels!\n\n    Speaker's Bio\n\n    Weiqing is a software engineer at Experimental Systems and Technology Lab, an engineering team from Singapore's Ministry of Education. He works on prototyping and building apps to help Singapore schools be better at what they do. In his spare time, he enjoys doing yoga and getting a good dose of overseas hikes.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"XggXhLalnkk\"\n\n- id: \"juanito-fatas-red-dot-ruby-conference-2017\"\n  title: \"Data Migration With Confidence\"\n  raw_title: \"Data Migration With Confidence - RedDotRubyConf 2017\"\n  speakers:\n    - Juanito Fatas\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-22\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Juanito Fatas, Software Engineer, Cookpad\n\n    Finally convinced your new client to switch from X to Rails? Did your company acquire a non-rails site? Then you probably need to migrate their data to your existing system. In this talk, I will share some false starts, lessons, tips, optimisations and decisions from a recent data migration I performed. How to migrate large amount of photos and records? What tools will you need and how to test the data migration. What do you need to do before & after the data migration. What I tried and how I migrated large amounts of data while kept the site up and running.\n\n    Speaker's Bio\n\n    Juanito is a developer at Cookpad, based in Tokyo, Japan. He spends most of his time programming in Ruby, choosing which emoji to use, and seeking for good ramen.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"pEXZpuHKyJc\"\n\n# Break\n\n- id: \"laura-eck-red-dot-ruby-conference-2017\"\n  title: \"Writing Better Errors\"\n  raw_title: \"Writing Better Errors - RedDotRubyConf 2017\"\n  speakers:\n    - Laura Eck\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-22\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Laura Eck, Software Engineer, TenTen Ltd\n\n    At their core, all errors trigger the same question, no matter who encounters them: What went wrong, and how do I make it work? At the same time, every error has specific target audiences that are interested in answering exactly that question - but possibly in very different ways. In this talk, we will explore how to design errors so they give each stakeholder the information they need to fix the issue at hand, and how we can use them to make our software even better. Errors might never be something you look forward to seeing - but when they crash your party, they'll at least know how to chat with the guests.\n\n    Speaker's Bio\n\n    Laura is a web developer living in Tokyo and working for Berlin. One of her favorite pastimes is learning something new, be it a technology, a language or anything else. When she’s not busy coding, you can usually find her reading things, making things, climbing on or jumping over things, or trying out another martial art.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"9buxKRmaNbc\"\n\n- id: \"nick-sutterer-red-dot-ruby-conference-2017\"\n  title: \"Keynote: Ruby is Dead\"\n  raw_title: \"Keynote: Ruby is Dead - RedDotRubyConf 2017\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-22\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Nick Sutterer\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"4q3sycRJ5bs\"\n\n# Closing For Day One\n\n## Day 2 - June 23 (Friday)\n\n# Registration || Breakfast\n\n# Opening Address\n\n- id: \"emily-stolfo-red-dot-ruby-conference-2017\"\n  title: \"Keynote: Refactoring Humpty Dumpty back together again\"\n  raw_title: \"Keynote: Refactoring Humpty Dumpty back together again  - RedDotRubyConf 2017\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Emily Stolfo\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"r1dwnffGkqc\"\n\n- id: \"don-werve-red-dot-ruby-conference-2017\"\n  title: \"To Code is Human\"\n  raw_title: \"To Code is Human - RedDotRubyConf 2017\"\n  speakers:\n    - Don Werve\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Don Werve, Consultant, Minimum Viable\n\n    Programming is a deeply mental art. And as programmers, we invest large amounts of time in mastering new languages and new tools. But all too often, we neglect understanding of the most important tool in the developer's toolbox: the programmer's brain itself. In this talk, we will combine the art of programming with the science of cognitive psychology, and emerge with a deeper understanding of how to leverage the limits of the human mind to sustainably craft software that is less buggy, easier to understand, and more adaptive in the face of change.\n\n    Speaker's Bio\n\n    Don is from California, lives in Tokyo, and divides his time between cooking and training to survive the impending zombie apocalypse. He has spent the past seven years working around the world as a back-pocket CTO and software engineer, helping companies solve tough team management and scaling issues, and today he joins us to chat about the human infrastructure of software engineering.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"OqeImHnoJTo\"\n\n# Break\n\n- id: \"florian-weingarten-red-dot-ruby-conference-2017\"\n  title: \"Shitlist-driven development and other tricks for working on large codebases\"\n  raw_title: \"Shitlist-driven development and other tricks for working on large codebases - RedDotRubyConf 2017\"\n  speakers:\n    - Florian Weingarten\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Florian Weingarten, Production Engineering Lead, Shopify\n\n    Working on large codebases is hard. Doing so with 700 people is even harder. Deploying it 50 times a day is almost impossible. We will look at productivity tricks and automations that we use at Shopify to get stuff done. We will learn how we fix the engine while the plane is running, how to quickly change code that lots of people depend on, how to automatically track down productivity killers like unreliable tests, how to maintain a level of agility that keeps developers happy and allows them to ship fast, and most importantly what the heck a \"shitlist\" is.\n\n    Speaker's Bio\n\n    Florian is originally from Germany, where he studied mathematics and computer science. Since moving to Canada, he is now working as Production Engineer at Shopify in Ottawa, spending most of his time on refactoring large Ruby on Rails codebases and thinking about scalability and performance problems.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"20pj_ajDBOg\"\n\n- id: \"ankita-gupta-red-dot-ruby-conference-2017\"\n  title: \"Lightning Talk: Spinning up micro-services using Ruby/Kafka\"\n  raw_title: \"Spinning up micro-services using Ruby/Kafka - RedDotRubyConf 2017\"\n  speakers:\n    - Ankita Gupta\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Ankita Gupta, Software Engineer, honestbee\n\n    As organisations get bigger, handling large application(s) gets harder - long release and test cycles, higher chances of a small change affecting other parts of the system. Micro-services solve some of these problems, albeit with their own set of challenges. Apache Kafka allows setting up event-driven architectures, wherein the concern of each service can be cleanly separated, and communication among services can happen asynchronously. The transition form a large rails application to smaller applications can be made more seamless with a few easy steps. I will be elaborating steps developers can take to make this process easier.\n\n    Speaker's Bio\n\n    Ankita is working as a full-stack software engineer at honestbee. In her free time, she works on her non-profit project Jugnuu, a low-cost, mobile-based English language solution for children.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"jGoVOJl7vZ4\"\n\n- id: \"takayuki-matsubara-red-dot-ruby-conference-2017\"\n  title: \"Lightning Talk: One Way to Encourage the Open Source Community\"\n  raw_title: \"One Way to Encourage the Open Source Community - RedDotRubyConf 2017\"\n  speakers:\n    - Takayuki Matsubara\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Takayuki Matsubara, Software Engineer, M3 Inc\n\n    From the conclusion, it is to put a star on projects at GitHub. I'm very happy someone putting a star on my project. So if you already put a star on any projects, it encourage the open source community. But have you put a star on projects developed as oss used in your project? All of them? This talk proposes a solution that activates open source community by putting a star on projects which you depend.\n\n    Speaker's Bio\n\n    Takayuki Matsubara is a software engineer at M3, Inc. His day job is building and maintaining web apps. He loves open source community, has created chrono_logger, Power Assert in Elixir and other various.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"XpFrk4V3eyQ\"\n\n- id: \"marion-schleifer-red-dot-ruby-conference-2017\"\n  title: \"Lightning Talk: Plan of action - we need more women in programming!\"\n  raw_title: \"Plan of action: we need more women in programming! - RedDotRubyConf 2017\"\n  speakers:\n    - Marion Schleifer\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Marion Schleifer, Junior Software Developer, Simplificator AG\n\n    It is no news that there are not enough women in programming. As a (female) career changer, I know how a lot of people (and especially women) think about programming. I am now a Ruby programmer and programming is completely different than i imagined it would be. And I love it! Therefore, I am putting a lot of my time and energy into educating women about programming. I want to talk about why we don't have enough women in programming, why we need more, and what we all can do to achieve that goal.\n\n    Speaker's Bio\n\n    Marion is a career changer. She has a Bachelor in Translation, a Master in Economics and just finished a Master in Software Engineering. Changing careers to programming is the best decision she has made. Apart from her job as Junior Developer, she is spending her time encouraging women to program and as a member of the Hanami core team.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"tyMaqrhWTP0\"\n\n- id: \"jinny-wong-red-dot-ruby-conference-2017\"\n  title: \"Lightning Talk: One Blind Weekend\"\n  raw_title: \"One Blind Weekend - RedDotRubyConf 2017\"\n  speakers:\n    - Jinny Wong\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Jinny Wong, Engineering Manager, Carousell\n\n    This talk is about the time when I was temporarily blind for a weekend, and how suddenly, web accessibility became both a boon and an annoyance to me. In this lightning talk I share about what I went through while \"blind\", and tips to improve your website's accessibility in order to enable more people to easily access and use your website, regardless of ability.\n\n    Speaker's Bio\n\n    Jinny is an Engineering Manager at Carousell, and provides strategic and technical guidance to the engineering team. She graduated with a bachelors degree in computer science from Monash university. When she is not serious at work, Jinny owns two cats with her husband. She also enjoys music, photography and running.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"7u8vQV-7I_4\"\n\n# Lunch\n\n- id: \"akira-matsuda-red-dot-ruby-conference-2017\"\n  title: \"Keynote: Ruby 2 in Ruby on Rails\"\n  raw_title: \"Ruby 2 in Ruby on Rails - RedDotRubyConf 2017\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Akira Matsuda\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"RBV4Mg34DR0\"\n\n- id: \"anton-davydov-red-dot-ruby-conference-2017\"\n  title: \"Hanami - New Ruby Web Framework\"\n  raw_title: \"Hanami - New Ruby Web Framework - RedDotRubyConf 2017\"\n  speakers:\n    - Anton Davydov\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Anton Davydov, Indie OSS Developer\n\n    Hanami is quite new and interesting framework which you are unlikely to write complex applications. But this does not mean that this framework is not worth your attention. Besides old approaches, you can also find new interesting solutions. In my presentation, I'm going to talk about Hanami framework and why you should look on this. We give consideration about advantages and disadvantages. And also I talk about future with Hanami.\n\n    Speaker's Bio\n\n    Anton is an indie developer from Russia. He works on some side projects and builds Space-Rocket ships at night. Also, he loves open source, cats and collecting stereotypes.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"EAv2PLjTN_g\"\n\n# Break\n\n- id: \"vaidehi-joshi-red-dot-ruby-conference-2017\"\n  title: \"Goldilocks and the Three Code Reviews\"\n  raw_title: \"Goldilocks and the Three Code Reviews - RedDotRubyConf 2017\"\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Vaidehi Joshi, Staff Engineer, Tilde Inc\n\n    Once upon a time, Goldilocks had a couple extra minutes to spare before morning standup. She logged into Github and saw that there were three pull requests waiting for her to review. We’ve probably all heard that peer code reviews can do wonders to a codebase. But not all type of code reviews are effective. Some of them seem to go on and on forever, while others pick at syntax and formatting but miss bugs. This talk explores what makes a strong code review and what makes a painful one. Join Goldilocks as she seeks to find a code review process that’s neither too long nor too short, but just right!\n\n    Speaker's Bio\n\n    Vaidehi is an engineer at Tilde, in Portland, Oregon, where she works on Skylight, your favorite Rails profiler! She enjoys building and breaking code, but loves creating empathetic engineering teams a whole lot more. In her spare time, she runs basecs, a weekly writing series that explores the fundamentals of computer science.\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"lge345hJKJk\"\n\n- id: \"aaron-patterson-red-dot-ruby-conference-2017\"\n  title: \"Keynote: Mark/Compact GC in MRI\"\n  raw_title: \"Keynote: Mark/Compact GC in MRI - RedDotRubyConf 2017\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Red Dot Ruby Conference 2017\"\n  date: \"2017-06-23\"\n  published_at: \"2017-06-26\"\n  description: |-\n    Speaker: Aaron Patterson, GitHub\n\n    Event Page: http://www.reddotrubyconf.com/\n\n    Produced by Engineers.SG\n\n  video_provider: \"youtube\"\n  video_id: \"EPpWMoA6_Pc\"\n# Closing Address\n\n# After Party\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2024/cfp.yml",
    "content": "---\n- link: \"https://reddotrubyconf.com/papers/new\"\n  open_date: \"2024-03-22\"\n  close_date: \"2024-06-01\"\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2024/event.yml",
    "content": "---\nid: \"red-dot-ruby-conference-2024\"\ntitle: \"Red Dot Ruby Conference 2024\"\nkind: \"conference\"\nlocation: \"Singapore, Singapore\"\ndescription: |-\n  Red Dot Ruby Conference (RDRC) is the only Ruby programming language conference in Singapore, bringing together the brightest minds in the Ruby community in the region since 2011. July 25-26, 2024, Singapore\npublished_at: \"2024-07-25\"\nstart_date: \"2024-07-25\"\nend_date: \"2024-07-26\"\nyear: 2024\nbanner_background: \"#F2FEFB\"\nfeatured_background: \"#F2FEFB\"\nfeatured_color: \"#64748B\"\nwebsite: \"https://reddotrubyconf.com/\"\ncoordinates:\n  latitude: 1.318903\n  longitude: 103.894049\naliases:\n  - RedDotRubyConf 2024\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: |-\n        Main sponsors with highest sponsorship tier\n      level: 1\n      sponsors:\n        - name: \"CoinGecko\"\n          website: \"https://www.coingecko.com/\"\n          slug: \"coingecko\"\n          logo_url: \"https://reddotrubyconf.com/assets/images/sponsors/coin_gecko.png\"\n\n        - name: \"STACK by GovTech\"\n          website: \"https://www.tech.gov.sg/\"\n          slug: \"stackbygovtech\"\n          logo_url: \"https://reddotrubyconf.com/assets/images/sponsors/stack.png\"\n\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://reddotrubyconf.com/assets/images/sponsors/appsignal.svg\"\n\n        - name: \"Ascenda\"\n          website: \"https://www.ascenda.com/\"\n          slug: \"ascenda\"\n          logo_url: \"https://reddotrubyconf.com/assets/images/sponsors/ascenda.png\"\n\n    - name: \"Ruby Friends\"\n      description: |-\n        Ruby Friends sponsor tier with individual contributors\n      level: 2\n      sponsors:\n        - name: \"Mohit Sindhwani\"\n          website: \"\"\n          slug: \"mohitsindhwani\"\n          logo_url: \"https://reddotrubyconf.com/assets/images/sponsors/mohit.jpg\"\n\n        - name: \"Kang Sheng\"\n          website: \"\"\n          slug: \"kangsheng\"\n          logo_url: \"https://github.com/TayKangSheng.png\"\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2024/venue.yml",
    "content": "---\nname: \"SingPost Centre\"\ndescription: |-\n  Level 5 Auditorium\n\naddress:\n  street: \"10 Eunos Road 8\"\n  city: \"Singapore\"\n  postal_code: \"408600\"\n  country: \"Singapore\"\n  country_code: \"SG\"\n  display: \"10 Eunos Rd 8, Singapore 408600\"\n\ncoordinates:\n  latitude: 1.318903\n  longitude: 103.894049\n\nmaps:\n  google: \"https://maps.google.com/?q=SingPost+Centre,+Level+5+Auditorium,1.318903,103.894049\"\n  apple: \"https://maps.apple.com/?q=SingPost+Centre,+Level+5+Auditorium&ll=1.318903,103.894049\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=1.318903&mlon=103.894049\"\n"
  },
  {
    "path": "data/red-dot-ruby-conference/red-dot-ruby-conference-2024/videos.yml",
    "content": "# Website: https://reddotrubyconf.com\n# Schedule: https://reddotrubyconf.com/#speakers\n\n## Day 1 - 2024-07-25\n\n# Registration opens\n\n# Opening address\n---\n- id: \"yukihiro-matz-matsumoto-red-dot-ruby-conference-2024\"\n  title: \"Keynote: Second system syndrome\"\n  raw_title: 'Keynote by Yukihiro \"Matz\" Matsumoto'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-25\"\n  description: \"\"\n  video_id: \"yukihiro-matz-matsumoto-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n- id: \"cristian-planas-red-dot-ruby-conference-2024\"\n  title: \"2,000 Engineers, 2 Million Lines of Code: The History of a Rails Monolith\"\n  raw_title: \"2,000 Engineers, 2 Million Lines of Code: The History of a Rails Monolith by Cristian Planas\"\n  speakers:\n    - Cristian Planas\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-25\"\n  description: \"\"\n  video_id: \"cristian-planas-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n# Break\n\n- id: \"hiroshi-shibata-red-dot-ruby-conference-2024\"\n  title: \"Introduction to Cybersecurity with Ruby\"\n  raw_title: \"Introduction to Cybersecurity with Ruby by Hiroshi Shibata\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-25\"\n  slides_url: \"https://speakerdeck.com/andpad/introduction-of-cybersecurity-with-oss-rdrc2024\"\n  description: \"\"\n  video_id: \"hiroshi-shibata-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n# Lunch\n\n- id: \"eriko-sugiyama-red-dot-ruby-conference-2024\"\n  title: \"Connecting Dots: Rails Girls & RubyKaigi\"\n  raw_title: \"Connecting Dots: Rails Girls & RubyKaigi by Eriko Sugiyama\"\n  speakers:\n    - Eriko Sugiyama\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-25\"\n  slides_url: \"https://speakerdeck.com/ericgpks/connecting-dots-rails-girls-and-rubykaigi-red-dot-ruby-conference-2024\"\n  description: \"\"\n  video_id: \"eriko-sugiyama-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n- id: \"marco-roth-red-dot-ruby-conference-2024\"\n  title: \"Leveling Up Developer Tooling for the Modern Rails & Hotwire Era\"\n  raw_title: \"Leveling Up Developer Tooling for the Modern Rails & Hotwire Era by Marco Roth\"\n  speakers:\n    - Marco Roth\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-25\"\n  slides_url: \"https://speakerdeck.com/marcoroth/developer-tooling-for-the-modern-hotwire-and-rails-era-at-reddotrubyconf-2024-singapore\"\n  description: |-\n    The evolution of developer experience tooling has been a game-changer in how we build and debug web applications.\n\n    This talk aims to showcase the path toward enriching the Ruby on Rails ecosystem with advanced DX tools, focusing on the implementation of Language Server Protocols (LSP) for Stimulus and Turbo.\n\n    Drawing inspiration from the rapid advancements in JavaScript tooling, we explore the horizon of possibilities for Rails developers.\n\n    The session will extend beyond LSPs, to explore the potential of browser extensions and development tools tailored specifically for Turbo, Stimulus, and Hotwire.\n  video_id: \"marco-roth-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n# Break\n\n- id: \"adrian-goh-red-dot-ruby-conference-2024\"\n  title: \"1 Engineer, 300 Thousand Users\"\n  raw_title: \"1 Engineer, 300 Thousand Users by Adrian Goh\"\n  speakers:\n    - Adrian Goh\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-25\"\n  description: \"\"\n  video_id: \"adrian-goh-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n- id: \"hieu-nguyen-red-dot-ruby-conference-2024\"\n  title: \"Rack From Scratch!\"\n  raw_title: \"Rack From Scratch! by Hieu Nguyen\"\n  speakers:\n    - Hieu Nguyen\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-25\"\n  description: \"\"\n  video_id: \"hieu-nguyen-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n- id: \"tim-riley-red-dot-ruby-conference-2024\"\n  title: \"Livin' La Vida Hanami\"\n  raw_title: \"Livin' La Vida Hanami by Tim Riley\"\n  speakers:\n    - Tim Riley\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-25\"\n  description: |-\n    Upside, inside out, Hanami 2.0 is out!\n\n    This release brings new levels of polish and power to a framework that you can use for Ruby apps of all shapes and sizes.\n\n    Together we’ll take a first look at Hanami, then build our very own app, and discover how Hanami apps can remain a joy to develop even as they grow.\n\n    Once you’ve had a taste of it you’ll never be the same!\n  video_id: \"tim-riley-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n# End of Day 1\n\n## Day 2 - 2024-07-26\n\n# Doors open\n\n- id: \"charles-oliver-nutter-red-dot-ruby-conference-2024\"\n  title: \"Ruby on the Modern JVM with JRuby\"\n  raw_title: \"Ruby on the Modern JVM with JRuby by Charles Oliver Nutter\"\n  speakers:\n    - Charles Nutter\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-26\"\n  slides_url: \"https://speakerdeck.com/headius/jruby-ruby-on-the-modern-jvm\"\n  description: |-\n    A talk on JRuby 10 and how we are leaping forward with Ruby 3.4 support, modern JVM features, and next-gen optimizations.\n  video_id: \"charles-oliver-nutter-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n- id: \"dave-aronson-red-dot-ruby-conference-2024\"\n  title: \"Tight Genes: Intro to Genetic Algorithms\"\n  raw_title: \"Tight Genes: Intro to Genetic Algorithms by Dave Aronson\"\n  speakers:\n    - Dave Aronson\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-26\"\n  slides_url: \"https://speakerhub.com/sites/default/files/genetic-algos_1.pdf\"\n  description: \"\"\n  video_id: \"dave-aronson-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n# Break\n\n- id: \"giovanni-sakti-red-dot-ruby-conference-2024\"\n  title: \"Revisiting Patterns of Error Handling in Ruby\"\n  raw_title: \"Revisiting Patterns of Error Handling in Ruby by Giovanni Sakti\"\n  speakers:\n    - Giovanni Sakti\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-26\"\n  description: \"\"\n  video_id: \"giovanni-sakti-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n- id: \"okura-masafumi-red-dot-ruby-conference-2024\"\n  title: \"How Not to Make Your DSL Terrible\"\n  raw_title: \"How Not to Make Your DSL Terrible by Okura Masafumi\"\n  speakers:\n    - OKURA Masafumi\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-26\"\n  slides_url: \"https://speakerdeck.com/okuramasafumi/how-not-to-make-your-dsl-terrible\"\n  description: \"\"\n  video_id: \"okura-masafumi-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n# Lunch\n\n- id: \"mario-arias-red-dot-ruby-conference-2024\"\n  title: \"Writing an Interpreter in Ruby\"\n  raw_title: \"Writing an Interpreter in Ruby by Mario Arias\"\n  speakers:\n    - Mario Arias\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-26\"\n  description: \"\"\n  video_id: \"mario-arias-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n- id: \"colby-swandale-red-dot-ruby-conference-2024\"\n  title: \"Scaling RubyGems.org to 1 Trillion Downloads\"\n  raw_title: \"Scaling RubyGems.org to 1 Trillion Downloads by Colby Swandale\"\n  speakers:\n    - Colby Swandale\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-26\"\n  description: \"\"\n  video_id: \"colby-swandale-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n# Break\n\n- id: \"mu-fan-teng-red-dot-ruby-conference-2024\"\n  title: \"Ruby & Party Politics: How to Quickly Refactor a Political Party's Election System\"\n  raw_title: \"Ruby & Party Politics: How to Quickly Refactor a Political Party's Election System by Mu-Fan Teng\"\n  speakers:\n    - Mu-Fan Teng\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-26\"\n  description: \"\"\n  video_id: \"mu-fan-teng-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n\n- id: \"aaron-patterson-red-dot-ruby-conference-2024\"\n  title: \"Speeding Up Delegate Methods\"\n  raw_title: \"Speeding Up Delegate Methods by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Red Dot Ruby Conference 2024\"\n  date: \"2024-07-26\"\n  description: \"\"\n  video_id: \"aaron-patterson-red-dot-ruby-conference-2024\"\n  video_provider: \"not_published\"\n# Closing address\n\n# End of Day 2\n"
  },
  {
    "path": "data/red-dot-ruby-conference/series.yml",
    "content": "---\nname: \"Red Dot Ruby Conference\"\nwebsite: \"https://reddotrubyconf.com\"\ntwitter: \"reddotrubyconf\"\nyoutube_channel_name: \"EngineersSG\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"RedDotRuby\"\ndefault_country_code: \"SG\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCjRZr5HQKHVKP3SZdX8y8Qw\"\naliases:\n  - Red Dot Ruby\n  - Red Dot Ruby Conf\n  - RedDotRubyConf\n  - RedDotRubyConference\n  - RDRC\n"
  },
  {
    "path": "data/redfrogconf/redfrogconf-2014/event.yml",
    "content": "---\nid: \"redfrogconf-2014\"\ntitle: \"RedFrogConf 2014\"\ndescription: \"\"\nlocation: \"Sankt Augustin, Germany\"\nkind: \"conference\"\nstart_date: \"2014-08-23\"\nend_date: \"2014-08-24\"\nwebsite: \"http://ruby.froscon.org/\"\ntwitter: \"redfrogconf\"\ncoordinates:\n  latitude: 50.773458\n  longitude: 7.185113699999999\n"
  },
  {
    "path": "data/redfrogconf/redfrogconf-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://ruby.froscon.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/redfrogconf/series.yml",
    "content": "---\nname: \"RedFrogConf\"\nwebsite: \"http://ruby.froscon.org/\"\ntwitter: \"redfrogconf\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2011/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybz6z9E0IIppIFIwatM29Us\"\ntitle: \"Rocky Mountain Ruby 2011\"\nkind: \"conference\"\ndescription: \"\"\nlocation: \"Boulder, CO, United States\"\npublished_at: \"2011-09-02\"\nstart_date: \"2011-08-31\"\nend_date: \"2011-09-02\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2011\nbanner_background: \"#3F425D\"\nfeatured_background: \"#3F425D\"\nfeatured_color: \"#ECDDC8\"\nwebsite: \"https://web.archive.org/web/20110927200359/http://rockymtnruby.com/\"\ncoordinates:\n  latitude: 40.0189728\n  longitude: -105.2747406\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2011/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: schedule website\n\n# Website: https://web.archive.org/web/20110927200359/http://rockymtnruby.com\n\n# this blog post seems to have the schedule\n# https://athega.se/blogg/2011/09/12/rocky-mountain-ruby-2011\n\n# There also seems to be some information on the archive confreaks.tv website:\n# https://web.archive.org/web/20220706071320/https://confreaks.tv/events/rockymtnruby2011\n\n- id: \"michael-feathers-rocky-mountain-ruby-2011\"\n  title: \"Opening Keynote: Code Blindness\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Opening Keynote: Code Blindness by: Michael Feathers\"\n  speakers:\n    - Michael Feathers\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-01\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Michael Feathers will be giving the opening keynote this year at Rocky Mountain Ruby. Michael is well known in the software community for his work with XP/Agile, improving software development and working on large legacy codebases. Don't miss his opening remarks which will definitely be thought provoking.\n  video_provider: \"youtube\"\n  video_id: \"B31QrNFyRyc\"\n\n- id: \"anthony-eden-rocky-mountain-ruby-2011\"\n  title: \"API Design Matters\"\n  raw_title: \"Rocky Mountain Ruby 2011 - API Design Matters by: Anthony Eden\"\n  speakers:\n    - Anthony Eden\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-01\"\n  published_at: \"2015-04-07\"\n  description: |-\n    The effects of API design will likely live with your project for a long time, often beyond your tenure with the project. Yet good API design is very rarely discussed and often leads developers to the conclusion that good APIs are something that \"we know when we see them.\"\n\n    This talk will attempt to layout a set of fundamentals for good API design so that we can begin to really understand the difference between well-designed APIs and those that are mediocre. It will also explain about various trade-offs that are made when designing APIs and some of the pros and cons that come with each trade-off. Finally we'll take a look at some good APIs and bad APIs in Ruby.\n  video_provider: \"youtube\"\n  video_id: \"GZxN51eAZzE\"\n\n- id: \"nick-sutterer-rocky-mountain-ruby-2011\"\n  title: \"CRUD is not REST - Hypermedia for Y'All!\"\n  raw_title: \"Rocky Mountain Ruby 2011 - CRUD is not REST - Hypermedia for Y'All! by: Nick Sutterer\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-01\"\n  published_at: \"2015-04-07\"\n  description: |-\n    REST is an architectural style for distributed systems. However, many implementations forget about the distributed part of REST and simply map CRUD operations to HTTP verbs in a monolithic application. We're gonna go further and learn why hypermedia is the crucial part of REST architectures and how machines can browse resources just like humans using self-describing representations.\n\n    Monolithic applications are boring, so let's separate things and create a REST system as it is intended to be. Let's build a simple system using the Roar gem, Rails and Sinatra and discuss the benefits and drawbacks we get from distributed hypermedia systems.\n  video_provider: \"youtube\"\n  video_id: \"RNcM5J76y2A\"\n\n- id: \"grant-blakeman-rocky-mountain-ruby-2011\"\n  title: \"If You See the Mountain Lion, It's Too Late\"\n  raw_title: \"Rocky Mountain Ruby 2011 - If You See the Mountain Lion, It's Too Late by: Grant Blakeman\"\n  speakers:\n    - Grant Blakeman\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-01\"\n  published_at: \"2015-04-07\"\n  description: |-\n    People often think of design as something that helps solve problems, but design should actually prevent problems in the first place. While you may not be a designer, applying tenets of design thinking to your life and work will help you make better decisions, build better stuff, and give you a framework to keep life and work moving forward.\n  video_provider: \"youtube\"\n  video_id: \"HYxf9v50B1U\"\n\n- id: \"avdi-grimm-rocky-mountain-ruby-2011\"\n  title: \"Things You Didn't Know About Exceptions\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Things You Didn't Know About Exceptions by: Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-01\"\n  published_at: \"2015-04-07\"\n  description: |-\n    You know how to raise and rescue exceptions. But do you know how they work, and how how to structure a robust error handling strategy for your app? Starting out with an in-depth walk-through of Ruby's Ruby's rich failure handling mechanisms -- including some features you may not have known about -- we'll move on to present strategies for implementing a cohesive error-handling policy for your application, based on real-world experience.\n  video_provider: \"youtube\"\n  video_id: \"NZx4phN7q_w\"\n\n- id: \"mastering-the-ruby-debugger\"\n  title: \"Mastering the Ruby Debugger\"\n  raw_title: \"Mastering the Ruby Debugger\"\n  speakers:\n    - TODO # Jim\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-01\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"mastering-the-ruby-debugger\"\n\n- id: \"jay-zeschin-rocky-mountain-ruby-2011\"\n  title: \"Cognitive Psychology and the Zen of Code\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Cognitive Psychology and the Zen of Code by: Jay Zeschin\"\n  speakers:\n    - Jay Zeschin\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-01\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Many of us are familiar with the old adage about writing code \"for people to read, and only incidentally for machines to execute\" (thanks, Abelson and Sussman) - but it's easier said than done. The fields of object-oriented design, patterns, and software architecture are vast, but primarily concerned with the mechanical structure of code - what if we took a step back from the nuts and bolts of the code and look at the way we as humans read and write it? Can we use our understanding of the psychology of human cognition to better understand our target audience, and in turn write code that is more intuitive, readable, and maintainable? This talk will walk through some of the basics of cognitive psychology and relate them back to concrete ways that we as developers can optimize our code for high performance in the interpreter between our ears.\n  video_provider: \"youtube\"\n  video_id: \"ar4QzWJ87RQ\"\n\n- id: \"jim-weirich-rocky-mountain-ruby-2011\"\n  title: \"Ruby Coding High\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Ruby Coding High by: Jim Weirich, Zef Houssney\"\n  speakers:\n    - Jim Weirich\n    - Zef Houssney\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-01\"\n  published_at: \"2015-04-07\"\n  description: |-\n    A musical selection for your enjoyment.\n\n  video_provider: \"youtube\"\n  video_id: \"3QNZLneA0kA\"\n\n- id: \"tim-clem-rocky-mountain-ruby-2011\"\n  title: \"Code First, Ask Questions Later\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Code First, Ask Questions Later by: Tim Clem\"\n  speakers:\n    - Tim Clem\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-01\"\n  published_at: \"2015-04-07\"\n  slides_url: \"https://speakerdeck.com/tclem/code-first-ask-questions-later\"\n  description: |-\n    Ever wonder how software is designed and developed at GitHub? Are you curious about how new features are deployed to the site? (Hint: ask the robot.) Want to know why we don't have any managers and don't track vacation days?\n\n    This talk will explore running your company like an open source project and give some insight into how GitHub continues to leverage ruby and other open source tools to keep up with massive data loads and a growing community of users.\n  video_provider: \"youtube\"\n  video_id: \"8G51GrNpEyM\"\n\n- id: \"suzan-bond-rocky-mountain-ruby-2011\"\n  title: \"Using Your Intuition for Innovation and Decision Making\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Using Your Intuition for Innovation and Decision Making by: Suzan Bond\"\n  speakers:\n    - Suzan Bond\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-01\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Learn how to go inside out vs. outside in so you can tap into your intuition to make strong decisions and come up with innovative solutions. It might just help you invent the next big thing rather than being the next Groupon clone.\n  video_provider: \"youtube\"\n  video_id: \"twoQjXLie7Y\"\n\n# 2011-09-02\n- id: \"konstantin-haase-rocky-mountain-ruby-2011\"\n  title: \"Real Time Rack\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Real Time Rack by: Konstantin Haase\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: |-\n    At least since node.js everyone knows that real time HTTP responses are the next big thing. The secrets of handling incoming requests asynchronously with Ruby is not yet far spread among Rubyists, as the internals needed for such responses are neither specified nor documented and there is a lack of tools. Still, it is possible to use Server-Sent Events, WebSockets and akin with Rack today. This talk will demonstrate the underlying technologies and how to use them in your Ruby application.\n  video_provider: \"youtube\"\n  video_id: \"R84ersKcKFc\"\n\n- id: \"gerred-dillon-rocky-mountain-ruby-2011\"\n  title: \"Ruby Messaging Patterns\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Ruby Messaging Patterns by: Gerred Dillon\"\n  speakers:\n    - Gerred Dillon\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: |-\n    As Ruby continues to mature as a language, its use in large scale (enterprise!) codebases is expanding - and the need to integrate into larger architectures is already here. It is tempting to build networks of APIs in order to integrate applications, but there is an answer - messaging. This talk will reveal the benefits of messaging, and describe patterns that can be implemented at any level - from workers on single applications, to integrating separate codebases, all the way up to massive, concurrent service-oriented architectures that rely on messaging as the backbone. Prepare to be assaulted with an inspiring way to integrate and scale - and leave armed with the tools required to do so.\n\n  video_provider: \"youtube\"\n  video_id: \"lt4DX-QLlOI\"\n\n- id: \"charles-max-wood-rocky-mountain-ruby-2011\"\n  title: \"Cloning Twitter: Rails + Cassandra = Scalable Sharing\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Cloning Twitter: Rails + Cassandra = Scalable Sharing\"\n  speakers:\n    - Charles Max Wood\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: |-\n    by: Charles Max Wood\n\n    Cassandra is a highly scalable and fast database engine based on its column architecture. It's a powerful alternative to most RDMS systems. Adding it to Rails gives you a great way to get a scalable system with many rows that can grow to meet your needs.\n\n  video_provider: \"youtube\"\n  video_id: \"RL7EL1oC6kY\"\n\n- id: \"zach-holman-rocky-mountain-ruby-2011\"\n  title: \"A Documentation Talk\"\n  raw_title: \"Rocky Mountain Ruby 2011 - A Documentation Talk by: Zach Holman\"\n  speakers:\n    - Zach Holman\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  slides_url: \"https://speakerdeck.com/holman/a-documentation-talk\"\n  description: |-\n    \"A Documentation Talk\" sounds pretty boring, right? Wouldn't it be scandalously titillating if this talk's title included detailed analysis of the expectations and results of the talk itself? Jeez it's like someone's making an overt metaphor for how Rubyists document their code.\n\n    At GitHub, we add docs to every single method we write, and we couldn't be more excited about it. It means faster and simpler code. It means stronger tests. It means your developers can pay attention to new commits without stressing about them. Documentation will make your project so very happy.\n\n  video_provider: \"youtube\"\n  video_id: \"lJd7nlysZeg\"\n\n- id: \"justin-searls-rocky-mountain-ruby-2011\"\n  title: \"Start using Jasmine.  Write better JavaScript.  Profit.\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Start using Jasmine.  Write better JavaScript.  Profit.\"\n  speakers:\n    - Justin Searls\n    - Cory Flanigan\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  slides_url: \"https://speakerdeck.com/searls/jasmine-for-rubyists-rockymtnruby-with-cory-flanigan-justin-searls\"\n  description: |-\n    by: Justin Searls, Cory Flanigan\n\n    As practitioners who comprise the Ruby software community, we have made great strides to establish testing as a best practice. We have done so in order to build quality into our processes and systems.\n\n    It seems, however, that we have a blind spot when it comes to one of the most important parts of our applications: rich user interaction written in JavaScript.\n\n    It used to be the case that we could blame this disregard for JavaScript tests on a lack of good testing tools, or having very limited amounts of JS in our applications.\n\n    Now more than ever before, rich user interfaces are prevalent, and testing tools have made great strides; specifically with regard to Jasmine.\n\n    We will briefly discuss reasons why JavaScript tests are critical, and easier than ever before.\n\n    The purpose of our presentation is to provide fellow software developers with actionable knowledge of how to:\n\n    * Add Jasmine to your a\n\n  video_provider: \"youtube\"\n  video_id: \"GeqPTG8dps8\"\n\n- id: \"ryan-mcgeary-rocky-mountain-ruby-2011\"\n  title: \"Lightning Talk: Do Your Commit Messages Suck\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Lightning Talk: Do Your Commit Messages Suck by: Ryan McGeary\"\n  speakers:\n    - Ryan McGeary\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  slides_url: \"https://speakerdeck.com/rmm5t/do-your-commit-messages-suck\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8YjSty6bfog\"\n\n- id: \"mike-gehard-rocky-mountain-ruby-2011\"\n  title: \"Lightning Talk: Developing Developers\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Lightning Talk: Developing Developers by: Mike Gehard\"\n  speakers:\n    - Mike Gehard\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"LatNKij7AHY\"\n\n- id: \"rod-cope-rocky-mountain-ruby-2011\"\n  title: \"Implementing Rails 3.1...\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Implementing Rails 3.1...\"\n  speakers:\n    - Rod Cope\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Implementing Rails 3.1, Backbone.js, CoffeeScript, jQuery, Sass, and CouchDB on EC2 by: Rod Cope\n\n    In under two months, my team: * Learned all about Rails 3.1, Backbone.js, CoffeeScript, Sass, and CouchDB * Wrote a new application that deploys open source stacks in the cloud * Created some stacks (e.g., Rails, Tomcat, BIRT) * Went to production on Amazon EC2\n\n    Come to this session to see what went right, what went wrong, and how this all compares to one of our other production stacks based on Rails 2.3, JavaScript, jQuery, Redis, and MySQL. In particular, you'll learn how to take advantage of some hot new tools while avoiding many of their pitfalls.\n  video_provider: \"youtube\"\n  video_id: \"-YnvvVm9_0A\"\n\n- id: \"jeff-casimir-rocky-mountain-ruby-2011\"\n  title: \"There Are No Tests\"\n  raw_title: \"Rocky Mountain Ruby 2011 - There Are No Tests by: Jeff Casimir\"\n  speakers:\n    - Jeff Casimir\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: |-\n    The Ruby community is obsessed with testing, supposedly. In my experience about four out of five applications have either zero or completely ineffective test coverage.\n\n    Have the courage to change it. Whether your own projects or recovering someone else's mess, let's talk strategy:\n\n    * Starting with metrics\n    * Refactoring for understanding\n    * Comment-driven development\n    * The unit testing foundation\n    * Bug reports are your best integration tests\n    * Focusing on value\n\n    Rescue projects are popping up everywhere, and a strategic testing approach can save the day.\n\n  video_provider: \"youtube\"\n  video_id: \"0u3NpGhxBq0\"\n\n- id: \"mike-gehard-rocky-mountain-ruby-2011-focus-why-do-i-need-more-stink\"\n  title: \"Focus? Why Do I Need More Stinkin' Focus?\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Focus? Why Do I Need More Stinkin' Focus? by: Mike Gehard\"\n  speakers:\n    - Mike Gehard\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Ever have one of those days where you sit back at the end of the day and realize that you didn't get anything tangible done? Why do those days happen? Many times is it because we lack focus during the day to complete even the simplest of tasks. Our modern lives don't allow us to practice focus; in fact they conspire against us being focused. This talk will explain why focus is important to productivity and teach one way you can practice focus through meditation.\n  video_provider: \"youtube\"\n  video_id: \"-JAQnLsFJMg\"\n\n- id: \"jeremy-hinegardner-rocky-mountain-ruby-2011\"\n  title: \"Lightning Talk: Deprecatable\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Lightning Talk: Deprecatable by: Jeremy Hinegardner\"\n  speakers:\n    - Jeremy Hinegardner\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"UVqMN3xIFl8\"\n\n- id: \"spike-ilacqua-rocky-mountain-ruby-2011\"\n  title: \"Lightning Talk: In Defense of Unless\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Lightning Talk: In Defense of Unless by: Spike Ilacqua\"\n  speakers:\n    - Spike Ilacqua\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"aDzGLc1C3Ps\"\n\n- id: \"wayne-e-seguin-rocky-mountain-ruby-2011\"\n  title: \"Lightning Talk: BDSM Project SM Framework\"\n  raw_title: \"Rocky Mountain Ruby 2011 - BDSM Project SM Framework by: Wayne E.Wayne E. Seguin\"\n  speakers:\n    - Wayne E. Seguin\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"_CtI8f60xOk\"\n\n- id: \"anthony-navarre-rocky-mountain-ruby-2011\"\n  title: \"Lightning Talk: Be Moar Ridiculous\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Be Moar Ridiculous by: Anthony Navarre\"\n  speakers:\n    - Anthony Navarre\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"fjR3iT3gnxo\"\n\n- id: \"jeff-dean-rocky-mountain-ruby-2011\"\n  title: \"Lightning Talk: Active Hash\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Active Hash by: Jeff Dean\"\n  speakers:\n    - Jeff Dean\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"l9oGzOqEd88\"\n\n- id: \"jim-holmes-rocky-mountain-ruby-2011\"\n  title: \"Surviving Growing from Zero to 15,000 Selenium Tests\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Surviving Growing from Zero to 15,000 Selenium Tests\"\n  speakers:\n    - Jim Holmes\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  published_at: \"2015-04-07\"\n  description: |-\n    by: Jim Holmes\n\n    Selenium is a wonderful tool for automating acceptance and functional tests; however, real-world implementations bring a lot of pain. I suffered all that pain, and more, as I piloted an effort that started out with Selenium IDE, moved through RC, and ended up with WebDriver. This talk covers things like setting up baseline data, creating backing test frameworks, dealing with brittle tests, and figuring out how to appropriately manage all those incredibly slow Selenium tests so that you actually get effective, useful testing in. Learn from my pain (and successes!) so that you donâ€™t have to suffer it in your own projects!\n\n  video_provider: \"youtube\"\n  video_id: \"QWp4PbUhGXg\"\n\n- id: \"testing-panel-rocky-mountain–ruby-2011\"\n  title: \"Testing Panel\"\n  raw_title: \"Rocky Mountain Ruby 2011 - Testing Panel by: Jeff Casimir, Justin Searls,Cory Flanigan, Jim Holmes\"\n  speakers:\n    - Jeff Casimir\n    - Cory Flanigan\n    - Justin Searls\n    - Jim Holmes\n  event_name: \"Rocky Mountain Ruby 2011\"\n  date: \"2011-09-02\"\n  description: |-\n    Jeff Casimir will lead a follow-up panel focusing on testing topics with Justin Searls, Cory Flanigan and Jim Holmes.\n\n  video_provider: \"not_published\"\n  video_id: \"testing-panel-rocky-mountain–ruby-2011\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2012/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYHiVRVRu5-fKpdRszKyi12\"\ntitle: \"Rocky Mountain Ruby 2012\"\nkind: \"conference\"\nlocation: \"Boulder, CO, United States\"\ndescription: \"\"\nstart_date: \"2012-09-19\"\nend_date: \"2012-09-21\"\npublished_at: \"2012-10-26\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2012\nwebsite: \"https://web.archive.org/web/20120920022433/http://rockymtnruby.com/\"\ncoordinates:\n  latitude: 40.0189728\n  longitude: -105.2747406\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2012/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: schedule website\n\n# Website: https://web.archive.org/web/20120920022433/http://rockymtnruby.com/\n\n- id: \"angela-harms-rocky-mountain-ruby-2012\"\n  title: \"Enhance your code with rainbows!\"\n  raw_title: \"Enhance your code with rainbows! by Angela Harms\"\n  speakers:\n    - Angela Harms\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: |-\n    I hear sometimes that good things come from carrots and sticks, from fear, from doing what you're told. But what if there's a better way to get the stuff we want? Stuff like money, working software, the geek joy of a solved problem. What if choosing love (and more specifically, curiosity, vulnerability, and kindness) gets us geeks what we want most?\n\n  video_provider: \"youtube\"\n  video_id: \"o0Zci00Y3ak\"\n\n- id: \"cameron-pope-rocky-mountain-ruby-2012\"\n  title: \"Lightning Talk: Ack\"\n  raw_title: \"Rocky Mountain Ruby 2012 Lightning Talk: Ack by Cameron Pope\"\n  speakers:\n    - Cameron Pope\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"sKmyl5D8Da8\"\n\n- id: \"dave-woodall-rocky-mountain-ruby-2012\"\n  title: \"Lightning Talk: Learning to Program\"\n  raw_title: \"Lightning Talk: Learning to Program by Dave Woodall\"\n  speakers:\n    - Dave Woodall\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Ot5JBMXo7AM\"\n\n- id: \"colin-thomas-arnold-rocky-mountain-ruby-2012\"\n  title: \"Lightning Talk: RubyMotion\"\n  raw_title: \"Lightning Talk: RubyMotion by Colin Thomas-Arnold\"\n  speakers:\n    - Colin Thomas-Arnold\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"gBj5Sgsda9I\"\n\n- id: \"derrick-ko-rocky-mountain-ruby-2012\"\n  title: \"Building in Rails, Backbone, and CoffeeScript\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Building in Rails, Backbone, and CoffeeScript by Derrick Ko\"\n  speakers:\n    - Derrick Ko\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: |-\n    Realtime, rich client applications are extremely popular. This is reflected in a new generation of frameworks like node.js and meteor. That said, the maturity of Rails and Backbone combined with real time services like XMPP or Pushr, still makes it a very compelling backend stack to use, especially when developing cross platform (web, desktop, mobile) applications.\n\n    In this talk, I will discuss the foundation and best practices of a Rails/Backbone/Coffeescript real time stack, as we do it at Kicksend.\n  video_provider: \"youtube\"\n  video_id: \"g6sKZALxozE\"\n\n- id: \"mike-gehard-rocky-mountain-ruby-2012\"\n  title: \"Growing Developers - Panel\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Growing Developers - Panel\"\n  speakers:\n    - Mike Gehard\n    - Elain Marina\n    - Jim Denton\n    - Thomas Frey\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: |-\n    There is a shortage of software developers today. Programs like CodeAcademy, HungryAcademy and DaVinci Coders are looking to help with that shortage. Mike Gehard will lead a panel on learning, what are the strengths are weaknesses of these programs are and how we all can help alleviate the shortage of quality software developers. If you want to be part of the solution, please join us.\n  video_provider: \"youtube\"\n  video_id: \"sjeS7eXB1rE\"\n\n- id: \"jose-valim-rocky-mountain-ruby-2012\"\n  title: \"Let's talk concurrency\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Let's talk concurrency by Jose Valim\"\n  speakers:\n    - Jose Valim\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: |-\n    For a long time, the de facto way of doing multi-core concurrency was using threads. However, the complexity of manipulating threads and state affected negatively how developers perceive concurrency. Fortunately, languages like Clojure and Erlang implement new paradigms that aim to make concurrency easier.\n\n    In this talk, José Valim is going to discuss the role state play in concurrency and introduce different paradigms for multi-core concurrency, like Actors and Software Transactional Memory, explaining their trade-offs and why they matter to us developers.\n  video_provider: \"youtube\"\n  video_id: \"4o89mWFL-2A\"\n\n- id: \"justin-searls-rocky-mountain-ruby-2012\"\n  title: \"To Mock or Not to Mock\"\n  raw_title: \"Rocky Mountain Ruby 2012 - To Mock or Not to Mock by Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"TU3glG08BJI\"\n\n- id: \"paul-elliott-rocky-mountain-ruby-2012\"\n  title: \"Expert Consulting\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Expert Consulting by Paul Elliott\"\n  speakers:\n    - Paul Elliott\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"7t7Ms-CMaSE\"\n\n- id: \"stephan-hagemann-rocky-mountain-ruby-2012\"\n  title: \"Wrangling Large Rails Codebases\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Wrangling Large Rails Codebases by Stephan Hagemann\"\n  speakers:\n    - Stephan Hagemann\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FElnETSIMuo\"\n\n- id: \"roy-tomeij-rocky-mountain-ruby-2012\"\n  title: \"Modular & reusable front end code\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Modular & reusable front end code by Roy Tomeij\"\n  speakers:\n    - Roy Tomeij\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"qNY8FFP5KhQ\"\n\n- id: \"josh-nichols-rocky-mountain-ruby-2012\"\n  title: \"ChatOps\"\n  raw_title: \"Rocky Mountain Ruby 2012 - ChatOps by Josh Nichols\"\n  speakers:\n    - Josh Nichols\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"cIhkj0hu_a0\"\n\n- id: \"simon-chiang-rocky-mountain-ruby-2012\"\n  title: \"Ruby on the Command Line\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Ruby on the Command Line by Simon Chiang\"\n  speakers:\n    - Simon Chiang\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6I2FyAmOMgM\"\n\n- id: \"nick-howard-rocky-mountain-ruby-2012\"\n  title: \"Ruby on Android\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Ruby on Android by Nick Howard\"\n  speakers:\n    - Nick Howard\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"xFgLTw3x97M\"\n\n- id: \"derrick-ko-rocky-mountain-ruby-2012-keeping-it-simple\"\n  title: \"Keeping it Simple\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Keeping it Simple by Derrick Ko\"\n  speakers:\n    - Derrick Ko\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"-UJ0Jwd2y4w\"\n\n- id: \"johannes-tuchscherer-rocky-mountain-ruby-2012\"\n  title: \"Dependency Injection\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Dependency Injection by Johannes Tuchscherer\"\n  speakers:\n    - Johannes Tuchscherer\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"QvSvSS8Ou4c\"\n\n- id: \"frederic-jean-rocky-mountain-ruby-2012\"\n  title: \"CleanShaved\"\n  raw_title: \"Rocky Mountain Ruby 2012 - CleanShaved by Frederic Jean\"\n  speakers:\n    - Frederic Jean\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"PEiuc3y0kwk\"\n\n- id: \"tony-navarre-rocky-mountain-ruby-2012\"\n  title: \"A model walks into a JavaScript framework\"\n  raw_title: \"Rocky Mountain Ruby 2012 - A model walks into a JavaScript framework by Tony Navarre\"\n  speakers:\n    - Tony Navarre\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"9Uu8ktgB5gQ\"\n\n- id: \"mike-gehard-rocky-mountain-ruby-2012-on-the-shoulders-of-giants\"\n  title: \"On the shoulders of giants\"\n  raw_title: \"Rocky Mountain Ruby 2012 - On the shoulders of giants by Mike Gehard\"\n  speakers:\n    - Mike Gehard\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Qq9oxtpUfX4\"\n\n- id: \"drew-neil-rocky-mountain-ruby-2012\"\n  title: \"This is the problem\"\n  raw_title: \"Rocky Mountain Ruby 2012 - This is the problem by Drew Neil\"\n  speakers:\n    - Drew Neil\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"91A_Cmf0OH8\"\n\n- id: \"thomas-frey-rocky-mountain-ruby-2012\"\n  title: \"Teacherless Education\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Teacherless Education by Thomas Frey\"\n  speakers:\n    - Thomas Frey\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"aFv0Ul6h9RM\"\n\n- id: \"gordon-diggs-rocky-mountain-ruby-2012\"\n  title: \"Algorithms\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Algorithms by Gordon Diggs\"\n  speakers:\n    - Gordon Diggs\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"1g-VbdDRtXs\"\n\n- id: \"john-foley-rocky-mountain-ruby-2012\"\n  title: \"Project Grok\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Project Grok by John Foley\"\n  speakers:\n    - John Foley\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2012-10-26\"\n  published_at: \"2012-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"dHh4FRNu_vs\"\n\n- id: \"sandi-metz-rocky-mountain-ruby-2012\"\n  title: \"Go Ahead, Make a Mess\"\n  raw_title: \"Rocky Mountain Ruby 2012 - Go Ahead, Make a Mess by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"Rocky Mountain Ruby 2012\"\n  date: \"2013-01-12\"\n  published_at: \"2012-11-29\"\n  description: |-\n    Software is always a mess. You can't avoid this mess, and if hubris goads you into attempting to achieve perfection, you'll just make things worse. Perfection is a distant, dim land on the unreachable horizon. You'll not be going there today.\n\n    What you can do, however, is use the techniques of object-oriented design (OOD) to make your messes manageable. OOD is good at messes. It understands their origins, predicts their courses, and foresees their outcomes. It shines a light down the dusty nooks and crannies of your app, showing you what to do and what to avoid.\n\n    This talk shows you how to use OOD to create the best kinds of messes, those that let you get software out the door today without regretting your actions tomorrow.\n  video_provider: \"youtube\"\n  video_id: \"f5I1iyso29U\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZA5A7PJ1_K9Ug5ydgtxd-q\"\ntitle: \"Rocky Mountain Ruby 2013\"\nkind: \"conference\"\nlocation: \"Boulder, CO, United States\"\ndescription: \"\"\nstart_date: \"2013-09-25\"\nend_date: \"2013-09-27\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2013\nwebsite: \"https://web.archive.org/web/20131104193908/http://rockymtnruby.com/\"\ncoordinates:\n  latitude: 40.0189728\n  longitude: -105.2747406\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2013/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n# Website: https://web.archive.org/web/20131104193908/http://rockymtnruby.com/\n\n- id: \"glenn-vanderburg-rocky-mountain-ruby-2013\"\n  title: \"Befriending the Turtles\"\n  raw_title: \"Rocky Mountain Ruby 2013 Befriending the Turtles by Glenn Vanderburg\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-31\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"AN6pCA4qjyg\"\n\n- id: \"toby-hede-rocky-mountain-ruby-2013\"\n  title: \"An ode to 17 databases in 29 minutes\"\n  raw_title: \"Rocky Mountain Ruby 2013 An ode to 17 databases in 29 minutes by Toby Hede\"\n  speakers:\n    - Toby Hede\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-13\"\n  description: |-\n    A detailed, deep-diving, in-the-deep-end and occasionally humorous whirlwind introduction and analysis of a suite of modern (and delightfully archaic) database technologies. How they work, why they work, and when you might want them to work. For no extra charge I will attempt to explain the oft-misunderstood CAP theorem, using databases as a device for understanding the trade offs and compromises inherent in building complex distributed systems.\n\n    Including but not limited to:\n\n    PostgreSQL Redis Cassandra Hyperdex MongoDb Riak\n\n  video_provider: \"youtube\"\n  video_id: \"OmpsGuQTMs0\"\n\n- id: \"andy-delcambre-rocky-mountain-ruby-2013\"\n  title: \"Ruby Systems Programming\"\n  raw_title: \"Rocky Mountain Ruby 2013 Ruby Systems Programming by Andy Delcambre\"\n  speakers:\n    - Andy Delcambre\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-13\"\n  description: |-\n    We as rubyists tend to write software that runs on the web, without a deep understanding of what it would take to write the plumbing for that same software. I think it's useful to have a basic understanding of how some of the lower level components of a system work.\n\n    I'll discuss the basics of systems programming, using Ruby. I'll talk about syscalls and kernel space vs user space. I'll cover a bit about file descriptors and what they're for. And hopefully I'll walk through a small example of a working webserver using those primitive syscalls.\n\n  video_provider: \"youtube\"\n  video_id: \"XNP0b6ykfFw\"\n\n- id: \"patrick-leonard-rocky-mountain-ruby-2013\"\n  title: \"iTriage\"\n  raw_title: \"Rocky Mountain Ruby 2013 iTriage by Patrick Leonard\"\n  speakers:\n    - Patrick Leonard\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3ZiXmeTRxnQ\"\n\n- id: \"fred-jean-rocky-mountain-ruby-2013\"\n  title: \"Go Static My Friend\"\n  raw_title: \"Rocky Mountain Ruby 2013 Go Static My Friend by Fred Jean\"\n  speakers:\n    - Fred Jean\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-13\"\n  description: |-\n    In the beginning was the static resource, and it was good. It was easy to reason about. It was easy to host, once you got over the hurdle of getting an internet connection and installing a web server. It just wasn't very... dynamic. So we started a journey to build increasingly dynamic web sites. This leads to increasingly complex infrastructure used to host what are basically content-only web sites.\n\n    Middleman allows us to return to simpler days by building data driven sites. It provides elements that Ruby on Rails developers are familiar and comfortable with such as layouts, templates and partials. Amazon S3 gives us a great, highly available and very cost effective way to host the resulting site.\n\n    This talk will focus on how to use Middleman to build a data driven site and publish it to S3.\n\n  video_provider: \"youtube\"\n  video_id: \"wijS-Qlhdf0\"\n\n- id: \"thomas-frey-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: The Increasing Need for Software Developers\"\n  raw_title: \"Rocky Mountain Ruby 2013 Lightning Talk: The Increasing Need for Software Developers by Thomas Frey\"\n  speakers:\n    - Thomas Frey\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"bthXzlCan6s\"\n\n- id: \"jeff-casimir-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: Building Colorado Developers\"\n  raw_title: \"Rocky Mountain Ruby 2013 Building Colorado Developers by Jeff Casimir\"\n  speakers:\n    - Jeff Casimir\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Q8hdDShvNto\"\n\n- id: \"kevin-stevens-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: Lessons from Theater and Software\"\n  raw_title: \"Rocky Mountain Ruby 2013 Lightning Talk Lessons from Theater and Software by Kevin Stevens\"\n  speakers:\n    - Kevin Stevens\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-31\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"1-8WyIZBkAQ\"\n\n- id: \"ryan-angilly-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: Social Grader\"\n  raw_title: \"Rocky Mountain Ruby 2013 Lightning Talk Social Grader by Ryan Angilly\"\n  speakers:\n    - Ryan Angilly\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"rFXvHJGYp7Y\"\n\n- id: \"nick-howard-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: Muskox\"\n  raw_title: \"Rocky Mountain Ruby 2013 Muskox by Nick Howard\"\n  speakers:\n    - Nick Howard\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8odQQ8lfSn8\"\n\n- id: \"stafford-brunk-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: Booster\"\n  raw_title: \"Rocky Mountain Ruby 2013 Lightning Talk Booster by Stafford Brunk\"\n  speakers:\n    - Stafford Brunk\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-31\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"-DHbZEhYCXI\"\n\n- id: \"weston-platter-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: Better Communication\"\n  raw_title: \"Rocky Mountain Ruby 2013 Lightning Talk Better Communication by Weston Platter\"\n  speakers:\n    - Weston Platter\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"nhp4dDWRp3Y\"\n\n- id: \"eloy-duran-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: Apprenticeships\"\n  raw_title: \"Rocky Mountain Ruby 2013 Lightning Talk: Apprenticeships by Eloy Duran\"\n  speakers:\n    - Eloy Duran\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"WLtNXWxq2oY\"\n\n- id: \"enrico-teotti-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: JSON Schema\"\n  raw_title: \"Rocky Mountain Ruby 2013 Lightning Talk JSON Schema by Enrico Teotti\"\n  speakers:\n    - Enrico Teotti\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"lGrq8lzbtu8\"\n\n- id: \"dan-sharp-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: DRYing up RSpec\"\n  raw_title: \"Rocky Mountain Ruby 2013 Lightning Talk DRYing up RSpec by Dan Sharp\"\n  speakers:\n    - Dan Sharp\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Ma12X8dj5z8\"\n\n- id: \"stephan-hagemann-rocky-mountain-ruby-2013\"\n  title: \"Lightning Talk: Keyboard-driven Window Management for Mac\"\n  raw_title: \"Rocky Mountain Ruby 2013 Lightning Talk Keyboard-driven Window Management for Mac\"\n  speakers:\n    - Stephan Hagemann\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-31\"\n  description: |-\n    by Stephan Hagemann\n\n  video_provider: \"youtube\"\n  video_id: \"kVX1PE6QQcM\"\n\n- id: \"ben-smith-rocky-mountain-ruby-2013\"\n  title: \"How I architected my big Rails app for success!\"\n  raw_title: \"Rocky Mountain Ruby 2013 How I architected my big Rails app for success! by Ben Smith\"\n  speakers:\n    - Ben Smith\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-31\"\n  description: |-\n    Rails is a great framework for creating web apps... for awhile. What do you do when your codebase grows large? How do you handle large teams of developers? When performance becomes an issue, how do you scale? Most importantly, how do you write code which can easily be refactored later?\n\n    This is a story of a real life project built from day 1 with all these questions in mind. Learn about the problems we solved and lessons we learned: how to partition your Rails app into distinct modular engines, how to speed up your test suite by only running code effected by your changes, how to add a layer on top of ActiveRecord to enforce loose coupling, and many other patterns that can be applied to your own Rails apps!\n\n  video_provider: \"youtube\"\n  video_id: \"uDaBtqEYNBo\"\n\n- id: \"eugene-kalenkovich-rocky-mountain-ruby-2013\"\n  title: \"Rails: Shadow Facets of Concurrency\"\n  raw_title: \"Rocky Mountain Ruby 2013 Rails: Shadow Facets of Concurrency by Eugene Kalenkovich\"\n  speakers:\n    - Eugene Kalenkovich\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-28\"\n  description: |-\n    Rails is a framework well known for ease of development. This ease is achieved by a lot of 'magic' that happens behind the scenes. One of pitfalls of such magic is a false sense of safety it gives, including sense of safety from concurrency issues for single-threaded environments. You may never discover any problems before the launch, or even after, while your site traffic is pretty sparse. But here comes a glorious moment of popularity - and together with more traffic it brings more and more concurrency-related problems.\n\n    In this talk we will look at different aspects of concurrency, from simple ones that are even mentioned in Rails documentation, to more complex problems that even seasoned developers tend to miss or fail to pay sufficient attention to.\n\n  video_provider: \"youtube\"\n  video_id: \"TV5LEjN6d1U\"\n\n- id: \"matt-wilson-rocky-mountain-ruby-2013\"\n  title: \"Minecart - A story of Ruby at a growing company\"\n  raw_title: \"Rocky Mountain Ruby 2013 Minecart - A story of Ruby at a growing company by Matt Wilson\"\n  speakers:\n    - Matt Wilson\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-30\"\n  description: |-\n    This is the story of Ruby at Square. As Square grew, we invested heavily in a service oriented architecture (SOA) and mainly used Java as our language of choice for new service development. Recently we finished a project, named Minecart, to deeply tie Ruby applications into our Java service infrastructure. To accomplish this we had to dive into the bowels of JRuby. To date, Square is roughly around 50/50 Java services vs Ruby services and everyone enjoys the benefits of a standard ecosystem. I will share many of our learnings along with a couple of practical examples and pitfalls for integrating Ruby into a custom Java framework.\n\n  video_provider: \"youtube\"\n  video_id: \"wk7uq4K7dzI\"\n\n- id: \"katrina-owen-rocky-mountain-ruby-2013\"\n  title: \"Here be Dragons\"\n  raw_title: \"Rocky Mountain Ruby 2013 Here be Dragons by Katrina Owen\"\n  speakers:\n    - Katrina Owen\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-29\"\n  description: |-\n    It's not your fault. Code rots. We don't hold entropy against you, but we expect you to give a damn.\n\n    This story is about code that brings new meaning to the word 'legacy'. The accidental discovery of this body of code provoked a moral crisis. I wanted to pretend I hadn't seen it, yet I couldn't justify tiptoeing quietly away.\n\n    This talk examines the dilemmas we face when balancing our choices today with their cost tomorrow.\n\n    It's not your fault. Even so, it is your responsibility.\n\n  video_provider: \"youtube\"\n  video_id: \"FvrZrwR5Flc\"\n\n- id: \"jason-noble-rocky-mountain-ruby-2013\"\n  title: \"From Junior Engineer to Productive Engineer\"\n  raw_title: \"Rocky Mountain Ruby 2013 From Junior Engineer to Productive Engineer by Jason Noble\"\n  speakers:\n    - Jason Noble\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-29\"\n  description: |-\n    At Rocky Mountain Ruby 2012, Mike Gehard hosted a Growing Developers Panel which discussed how senior engineers, companies and code schools can help alleviate the shortage of quality software developers.\n\n    Two to three months before the conference, Comverge had one Junior engineer on staff, but no formal training/mentorship program. Since that conference, we have hired an additional junior engineer and put both of them through our Junior Engineer program.\n\n    This talk will cover the process Comverge uses when bringing on Junior software engineers, from interviewing techniques to on boarding and the first couple months of on the job training. This training includes Pivotal Tracker, Git branching strategies, learning to love pull requests, TDD, BDD and learning our products.\n\n  video_provider: \"youtube\"\n  video_id: \"aFVrYynz7pI\"\n\n- id: \"lional-barrow-rocky-mountain-ruby-2013\"\n  title: \"Ruby and Go\"\n  raw_title: \"Rocky Mountain Ruby 2013 Ruby and Go by Lional Barrow\"\n  speakers:\n    - Lional Barrow\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2014-02-04\"\n  description: |-\n    Go has rapidly built a reputation as a great language for web development. But as Rubyists, we already have a great web development language -- why should we be interested in Go?\n\n    After using Go at Braintree, I'm convinced that every web developer would benefit from exposure to the Go programming style, which emphasizes small, composable packages and up-front error handling.\n\n    In this talk, we will:\n\n    Compare idiomatic approaches to common problems such as error handling and program organization in Go and Ruby.\n    Tease out common ideas and best practices that apply to all web applications, regardless of language or framework.\n    Read a bunch of code.\n    We will not:\n\n    Try to convince anyone to ditch Ruby and embrace Go.\n    Make vague, unsubstantiated claims about the benefits of static or dynamic typing.\n    Assume prior knowledge of Go. In order to make informed comparisons with Ruby, I'll go over the basics of the Go language, but explaining Go won't be the focus of this talk.\n\n  video_provider: \"youtube\"\n  video_id: \"AR9Q6UgxEuY\"\n\n- id: \"ashe-dryden-rocky-mountain-ruby-2013\"\n  title: \"Programming Diversity\"\n  raw_title: \"Rocky Mountain Ruby 2013 Programming Diversity by Ashe Dryden\"\n  speakers:\n    - Ashe Dryden\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-31\"\n  description: |-\n    It's been scientifically proven that more diverse communities and workplaces create better products and the solutions to difficult problems are more complete and diverse themselves. Companies are struggling to find adequate talent. So why do we see so few women, people of color, and LGBTQ people at our events and on the about pages of our websites? Even more curiously, why do 60% of women leave the tech industry within 10 years? Why are fewer women choosing to pursue computer science and related degrees than ever before? Why have stories of active discouragement, dismissal, harassment, or worse become regular news?\n\n    In this talk we'll examine the causes behind the lack of diversity in our communities, events, and workplaces. We'll discuss what we can do as community members, event organizers, and co-workers to not only combat this problem, but to encourage positive change by contributing to an atmosphere of inclusivity.\n\n    Objectives: -Educate about the lack of diversity and why it is a problem -Examine what is contributing to both the pipeline issue as well as attrition -Isolate what is and isn't working -Inspire direct action by examining our own behavior and learning more about the people around us so we can empathize better\n\n  video_provider: \"youtube\"\n  video_id: \"Ylmvg7JnCjc\"\n\n- id: \"mike-nicholaides-rocky-mountain-ruby-2013\"\n  title: \"SOLID and TDD, Sitting in a\"\n  raw_title: \"Rocky Mountain Ruby 2013 SOLID and TDD, Sitting in a  by Mike Nicholaides\"\n  speakers:\n    - Mike Nicholaides\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-31\"\n  description: |-\n    You've heard the claims or know from experience that test-driven development (TDD) produces better code. Perhaps you've also heard that to write better code you should be following the SOLID principles. Is there a connection between practicing TDD and writing SOLID code?\n\n    In this talk, I'll use examples gleaned from real life to demonstrate how TDD prompts us to produce code that conforms to the SOLID principles, and how the SOLID principles are where we should turn when our tests are causing us pain. In doing so, we'll learn what each principle really means and why it's valuable.\n\n    Mike Nicholaides has been a Rails consultant since 2006 and has always obsessed about writing clean, clear, and concise code. He organizes the Code Retreat in Philadelphia where the focus is on learning TDD, communicating with code, and of course, having fun.\n\n  video_provider: \"youtube\"\n  video_id: \"FidRcixHQos\"\n\n- id: \"brian-marrick-rocky-mountain-ruby-2013\"\n  title: \"Programming with that Disreputable Part of your Brain\"\n  raw_title: \"Rocky Mountain Ruby 2013 Programming with that Disreputable Part of your Brain\"\n  speakers:\n    - Brian Marrick\n  event_name: \"Rocky Mountain Ruby 2013\"\n  date: \"2013-09-25\"\n  published_at: \"2013-10-12\"\n  description: |-\n    by  Brian Marrick\n\n    When smoothing wood with a hand plane, you should always work with the grain rather than against the grain.\n\n    It's becoming increasingly clear that what we normally think of as rationality is fairly rare. Much of what we do is governed by our brain operating on autopilot. Reasoning is the expensive stop-gap our brain uses (sometimes!) when the cheaper solution isn't working right.\n\n    Programming is typically seen as an occupation that requires thoughtful precision and rationality: we will work against the grain of our brain. The resulting nicks and chips are only evidence that we should try harder!\n\n    What if we try to work with the automatic part of the brain, rather than against it? In this talk, Brian Marick will discuss how he tries to do just that.\n\n  video_provider: \"youtube\"\n  video_id: \"kLLwJws1nfw\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYcpjBPDgGW03ZpA9gk0AnR\"\ntitle: \"Rocky Mountain Ruby 2014\"\nkind: \"conference\"\nlocation: \"Boulder, CO, United States\"\ndescription: \"\"\nstart_date: \"2014-09-24\"\nend_date: \"2014-09-26\"\npublished_at: \"2014-10-18\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2014\nwebsite: \"https://web.archive.org/web/20140724170911/http://rockymtnruby.com/\"\nplaylist: \"http://www.confreaks.com/events/rmr2014\"\ncoordinates:\n  latitude: 40.0189728\n  longitude: -105.2747406\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2014/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"jeffery-matthias-rocky-mountain-ruby-2014\"\n  title: \"Future-proofing Your 3rd Party Services\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Future-proofing Your 3rd Party Services by Jeffery Matthias\"\n  speakers:\n    - Jeffery Matthias\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-20\"\n  published_at: \"2014-10-20\"\n  description: |-\n    It's 2015... your stakeholders have decided that PayPal is out and Stripe is in. Fortunately, you're a planner. You have all of your PayPal interactions isolated in an adapter gem and your interface is clearly defined, easy to re-implement and enforce. Rewriting your adapter isn't small, but it is surmountable and can be estimated accurately so it won't lead to surprises. You win.\n\n    Larger Rails apps are moving towards Service Oriented Architecture with adapters (typically custom gems) abstracting 3rd party services. This talk will cover defining, enforcing and test-driving the interface for your 3rd party service to provide easier flexibility in the future.\n\n  video_provider: \"youtube\"\n  video_id: \"CXdULnPpMsc\"\n\n- id: \"john-paul-ashenfelter-rocky-mountain-ruby-2014\"\n  title: \"Machine Learning for Fun and Profit\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Machine Learning for Fun and Profit by John Paul Ashenfelter\"\n  speakers:\n    - John Paul Ashenfelter\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-20\"\n  published_at: \"2014-10-20\"\n  description: |-\n    Your Rails app is full of data that can (and should!) be turned into useful information with some simple machine learning techniques. We'll look at basic techniques that are both immediately applicable and the foundation for more advanced analysis -- starting with your Users table.\n\n    We will cover the basics of assigning users to categories, segmenting users by behavior, and simple recommendation algorithms. Come as a Rails dev, leave a data scientist.\n\n  video_provider: \"youtube\"\n  video_id: \"KC5MtKHm1O4\"\n\n- id: \"tj-schuck-rocky-mountain-ruby-2014\"\n  title: \"80,00 Plaintext Passwords\"\n  raw_title: \"Rocky Mountain Ruby 2014 - 80,00 Plaintext Passwords\"\n  speakers:\n    - T.J. Schuck\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-20\"\n  published_at: \"2014-10-20\"\n  description: |-\n    fluffmuffin, peppercorn, gilligan — those are just a few of our users' plaintext passwords.\n\n    I have 80,000 more, and it only took me 87 seconds to gather them from our customer database in a white-hat attack.\n\n    In Act I, we'll cover the history of secure password storage, examine the hack, and mitigate the threat. Act II will address the difficulties of working on libraries with complicated external dependencies (like bcrypt-ruby, of which I'm now a maintainer). In Act III, we'll celebrate the power of global collaboration via OSS.\n\n    [Scene.]\n\n  video_provider: \"youtube\"\n  video_id: \"9u54O6vARK8\"\n\n- id: \"sarah-mei-rocky-mountain-ruby-2014\"\n  title: \"Unpacking Technical Decisions\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Unpacking Technical Decisions by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-20\"\n  published_at: \"2014-10-20\"\n  description: |-\n    As engineers working on a team, we all make technical decisions. What’s the best way to implement this? Where should this function live? Is this library worth using? Some decisions, though, are larger, riskier and more important than that. But generally, they’re also far less frequent.\n\n    Right now, your team might be struggling to organize the client-side parts of your application. Ember? Angular? Backbone? Flip a coin? Uh…which one has the most…retweets? These choices don’t need to be arbitrary or based on vague personal preference. Come learn a more useful and realistic approach that makes large-scale technical decisions less risky.\n\n  video_provider: \"youtube\"\n  video_id: \"F7D5ZGlioj4\"\n\n- id: \"arjun-sharma-rocky-mountain-ruby-2014\"\n  title: \"What it Means to Have Good Test Covearage...\"\n  raw_title: \"Rocky Mountain Ruby 2014 - What it Means to Have Good Test Covearage...\"\n  speakers:\n    - Arjun Sharma\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-20\"\n  published_at: \"2014-10-20\"\n  description: |-\n    What it Means to Have Good Test Covearage, and why it Matters by Arjun Sharma\n\n    One of the greatest themes the Ruby community has embraced is testing. Countless words have been written, and tools coded, to make it as easy and painless as possible to write almost any kind of test imaginable. And yet despite all of the time we spend writing tests, we still end up with bugs in production, and we still curse our test suites for being too large, too slow, or too complicated.\n\n    In this talk I will not provide you with a single source of truth about how to test your application. What I will provide is a better understanding of how to get the most mileage out of your test suite. Using examples from my own experience of testing Rails, plain old Ruby, JavaScript, and even Objective-C and Java, we will explore the pros and cons of unit testing versus integrated or system testing, what makes a test valuable, and what it means to really have good test coverage.\n\n  video_provider: \"youtube\"\n  video_id: \"rbWUxRNawIw\"\n\n- id: \"lightning-talks-day-1-rocky-mountain-ruby-2014\"\n  title: \"Lightning Talks (Day 1)\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Lightning Talks (Day 1)\"\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-21\"\n  published_at: \"2014-10-21\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"iYvm_5z0mZQ\"\n  talks:\n    - title: \"Lightning Talk: Teen Hackathons\"\n      date: \"2014-10-21\"\n      start_cue: \"00:00\"\n      end_cue: \"04:06\"\n      id: \"anna-fowles-winkler-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"anna-fowles-winkler-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Anna Fowles-Winkler\n\n    - title: \"Lightning Talk: Speed Up Your Database\"\n      date: \"2014-10-21\"\n      start_cue: \"04:06\"\n      end_cue: \"08:11\"\n      id: \"starr-horne-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"starr-horne-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Starr Horne\n\n    - title: \"Lightning Talk: Go Code Colorado\"\n      date: \"2014-10-21\"\n      start_cue: \"08:11\"\n      end_cue: \"10:38\"\n      id: \"jessica-goulding-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"jessica-goulding-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Jessica Goulding\n\n    - title: \"Lightning Talk: Documenting and Exploring your APIs\"\n      date: \"2014-10-21\"\n      start_cue: \"10:38\"\n      end_cue: \"17:07\"\n      id: \"tim-schmelmer-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"tim-schmelmer-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Tim Schmelmer\n\n    - title: \"Lightning Talk: Dashboard Dashing\"\n      date: \"2014-10-21\"\n      start_cue: \"17:07\"\n      end_cue: \"21:44\"\n      id: \"jon-mccartie-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"jon-mccartie-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Jon McCartie\n\n- id: \"marcos-castilho-rocky-mountain-ruby-2014\"\n  title: \"Micro Testing Pains\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Micro Testing Pains by Marcos Castilho\"\n  speakers:\n    - Marcos Castilho\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-21\"\n  published_at: \"2014-10-21\"\n  description: |-\n    Micro services are a wonderful thing! Until you try to test them in integration. Do you write a stub for each service? Point them to a test environment? Raise local instances for every dependency? I've tried all these approaches and they are all painful. Can't we can do better?\n\n    Yes we can! On this talk we will discuss Consumer Driven Contracts, a better way to deal with integration tests in a micro services environment.\n\n  video_provider: \"youtube\"\n  video_id: \"L22NNcfrbYI\"\n\n- id: \"jen-diamond-rocky-mountain-ruby-2014\"\n  title: \"Feats of Daring with the Ruby Standard Library\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Feats of Daring with the Ruby Standard Library\"\n  speakers:\n    - Jen Diamond\n    - Stephanie Betancourt\n    - Omowale Oniyide\n    - Josh Loper\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-21\"\n  published_at: \"2014-10-21\"\n  description: |-\n    Feats of Daring with the Ruby Standard Libaray by Jen Diamond, Stephanie Betancourt, Omowale Oniyide and Josh Loper\n\n    The Standard Librarians are working to make the Ruby Standard Library more accessible to it's users, beginner through advanced. The basis for it is existing ruby-docs. The Stand Librarians have taken it further with explanations that are easier to parse, libraries grouped into categories, examples to try, links aggregated for further study and similar gems listed. This talk will demonstrate the new site, how it was made it and how RGSoC helped make that happen. Ruby's Standard Libraries have a lot of tricks up it's sleeves. Want to see some?\n\n  video_provider: \"youtube\"\n  video_id: \"yc0hjFgSQN0\"\n\n- id: \"sarah-allen-rocky-mountain-ruby-2014\"\n  title: \"Let's Pretend\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Let's Pretend by Sarah Allen\"\n  speakers:\n    - Sarah Allen\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-22\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Playing is simple, even a child can do it, but designing something simple is hard. How can we combine prototyping with production software to get our ideas in front of real people? How can we evolve our software over time? How do we measure if something is fun?\n\n    I will talk about how Ruby’s flexibility and a strong testing ethos can bring some sanity to this uncertain world. And when I say testing, I’m not just talking about RSpec, Cucumber or Capybara, I’ll share stories from Mightyverse about how we test whether our software actually “works” for the people who use it — sharing failures, I mean, learning, as well as success.\n\n  video_provider: \"youtube\"\n  video_id: \"EZO0Udty9bY\"\n\n- id: \"doc-norton-rocky-mountain-ruby-2014\"\n  title: \"The Technical Debt Trap\"\n  raw_title: \"Rocky Mountain Ruby 2014 - The Technical Debt Trap by Doc Norton\"\n  speakers:\n    - Doc Norton\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-22\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Technical Debt has become a catch-all phrase for any code that needs to be re-worked. Much like Refactoring has become a catch-all phrase for any activity that involves changing code. These fundamental misunderstandings and comfortable yet mis-applied metaphors have resulted in a plethora of poor decisions. What is technical debt? What is not technical debt? Why should we care? What is the cost of misunderstanding? What do we do about it? Doc discusses the origins of the metaphor, what it means today, and how we properly identify and manage technical debt.\n\n  video_provider: \"youtube\"\n  video_id: \"S2pS9hN2Fws\"\n\n- id: \"hemant-kumar-rocky-mountain-ruby-2014\"\n  title: \"Under the Hood of Ruby's Generational Garbage Collector\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Under the Hood of Ruby's Generational Garbage Collector by Hemant Kumar\"\n  speakers:\n    - Hemant Kumar\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-22\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Ruby - 2.1 brought generational GC to Ruby and instrumentation support. In this talk, I am going explain:\n\n    How it works? How it affects users and C extension authors? Visualize object allocation/deallocation in realtime, demonstrate how different GC tuning options affect your app.\n\n  video_provider: \"youtube\"\n  video_id: \"hcaYjiAIres\"\n\n- id: \"lightning-talks-day-2-rocky-mountain-ruby-2014\"\n  title: \"Lightning Talks (Day 2)\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Lightning Talks (Day 2)\"\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-22\"\n  published_at: \"2014-10-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DqoKIKWf2HM\"\n  talks:\n    - title: \"Lightning Talk: Asset Pipeline Tips and Tricks\"\n      date: \"2014-10-22\"\n      start_cue: \"00:00\"\n      end_cue: \"05:08\"\n      id: \"risa-batta-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"risa-batta-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Risa Batta\n\n    - title: \"Lightning Talk: Alfred is Awesome\"\n      date: \"2014-10-22\"\n      start_cue: \"05:08\"\n      end_cue: \"08:08\"\n      id: \"cory-leistikow-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"cory-leistikow-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Cory Leistikow\n\n    - title: \"Lightning Talk: The Human Connection\"\n      date: \"2014-10-22\"\n      start_cue: \"08:08\"\n      end_cue: \"12:20\"\n      id: \"george-apitz-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"george-apitz-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - George Apitz\n\n    - title: \"Lightning Talk: Methan Hydrate\"\n      date: \"2014-10-22\"\n      start_cue: \"12:20\"\n      end_cue: \"15:50\"\n      id: \"joe-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"joe-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Joe\n\n    - title: \"Lightning Talk: State Machines\"\n      date: \"2014-10-22\"\n      start_cue: \"15:50\"\n      end_cue: \"18:58\"\n      id: \"marcus-morrison-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"marcus-morrison-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Marcus Morrison\n\n    - title: \"Lightning Talk: Rails as Static Content Compile\"\n      date: \"2014-10-22\"\n      start_cue: \"18:58\"\n      end_cue: \"23:16\"\n      id: \"ara-t-howard-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"ara-t-howard-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Ara T. Howard\n\n    - title: \"Lightning Talk: Teams Decision Making Tools\"\n      date: \"2014-10-22\"\n      start_cue: \"23:16\"\n      end_cue: \"30:15\"\n      id: \"doc-norton-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"doc-norton-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Doc Norton\n\n    - title: \"Lightning Talk: Qtbindings - GUIs in Ruby\"\n      date: \"2014-10-22\"\n      start_cue: \"30:15\"\n      end_cue: \"31:00\"\n      id: \"ryan-melton-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"ryan-melton-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Ryan Melton\n\n    - title: \"Lightning Talk: Rocky Mountain Ruby Rap\"\n      date: \"2014-10-22\"\n      start_cue: \"31:00\"\n      end_cue: \"35:11\"\n      id: \"shelby-kelly-lighting-talk-rocky-mountain-ruby-2014\"\n      video_id: \"shelby-kelly-lighting-talk-rocky-mountain-ruby-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Shelby Kelly\n\n- id: \"pamela-vickers-rocky-mountain-ruby-2014\"\n  title: 'Your Company is \"Awesome\" (But is \"Company Culture\" a lie?)'\n  raw_title: 'Rocky Mountain Ruby 2014 - Your Company is \"Awesome\" (But is \"Company Culture\" a lie?)'\n  speakers:\n    - Pamela Vickers\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-27\"\n  published_at: \"2014-10-27\"\n  description: |-\n    Your Company is \"Awesome\" (But is \"Company Culture\" a lie?) by Pamela Vickers\n\n    We all want to work for a company that cares about and promotes a balanced, fun, and, in a word, \"awesome\" culture, but unless you have safeguards in place against bad clients, bad projects, and bad apples, your company culture only exists on paper.\n\n    What can we do as developers, team leaders, and mentors to protect ourselves and others from cultural failure? What are successful companies doing to maintain their workers' happiness? Is it ever okay to \"fire\" a bad client? What separates healthy internal pride and corporate propaganda?\n\n    This talk attempts to define the amorphous term while exploring the difficult task of owning your company culture and protecting it when things go wrong.\n\n  video_provider: \"youtube\"\n  video_id: \"h1UayuSXBcg\"\n\n- id: \"nikolay-nemshilov-rocky-mountain-ruby-2014\"\n  title: \"Native iOS Development with RubyMotion and  UnderOS\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Native iOS Development with RubyMotion and UnderOS\"\n  speakers:\n    - Nikolay Nemshilov\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-27\"\n  published_at: \"2014-10-27\"\n  description: |-\n    Native iOS Development with RubyMotion and UnderOS by Nikolay Nemshilov\n\n    RubyMotion is a project that allows you to create native iOS apps in ruby. It is basically a compiler of Ruby into Objective-C which gives you access to all the iOS system environment.\n\n    UnderOS is a new exciting project on top of RubyMotion that creates a new, ruby and web developers friendly environment around the native iOS framework. It converts all the native mobile development concepts into web-development concepts and allows you to create native iOS applications with HTML, CSS and Ruby (instead of JavaScript).\n\n    This talk will give you a basic overview of RubyMotion/UnderOS concepts and I'm also going to livehack an application on stage to give you a sense of how it looks and feels like.\n\n  video_provider: \"youtube\"\n  video_id: \"6UTcz-_WvXk\"\n\n- id: \"julian-cheal-rocky-mountain-ruby-2014\"\n  title: \"Dancing with Robots\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Dancing with Robots by Julian Cheal\"\n  speakers:\n    - Julian Cheal\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-28\"\n  published_at: \"2014-10-28\"\n  description: |-\n    Web apps are great and everything, but imagine using Ruby to fly drones and make them dance to the sounds of dubstep! Or to control disco lights and other robots! Sounds fun, right? In this talk, we will not only explore how we can write code to make this possible, but it will also be full of exciting, interactive (and possibly dangerous ;) ) demos!\n\n  video_provider: \"youtube\"\n  video_id: \"7I0jumEv_ns\"\n\n- id: \"mike-abiezzi-rocky-mountain-ruby-2014\"\n  title: \"Build Complex Domains in Rails\"\n  raw_title: \"Rocky Mountain Ruby 2014 - Build Complex Domains in Rails by Mike AbiEzzi\"\n  speakers:\n    - Mike AbiEzzi\n  event_name: \"Rocky Mountain Ruby 2014\"\n  date: \"2014-10-28\"\n  published_at: \"2014-10-28\"\n  description: |-\n    Rails models are simple, but your domain’s models might not be as simple as Rails would like them to be.\n\n    Modeling large, complex domains \"the Rails way” can cause some serious pain. Ruby and Rails are supposed to make developers happy. Let's not allow “the Rails way” and complex domains to take the “happy” out of ruby development.\n\n    Join me as I’ll walk through a set of easy to implement Domain Driven Design (DDD) pointers. The goal is to make sure your model’s business logic stay under control no matter how complex your domain is or gets. Your application will be able to sustain steady growth and dramatically reduce business rule related defects, all the while, staying easy to grok.\n\n    I'll walk you through:\n\n    How communicating the domain properly will make an imprint on your codebase and product. How creating boundaries around clusters of models will make your code easier to understand, manage, and interact with. How immutable objects eliminate unnecessary complexities. How data store access expresses the domain's intentions. How to represent natural business transactions between models.\n\n  video_provider: \"youtube\"\n  video_id: \"B7pXxMJAze0\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaiBPK0LLwNDlLOm_RKS20c\"\ntitle: \"Rocky Mountain Ruby 2015\"\nkind: \"conference\"\nlocation: \"Boulder, CO, United States\"\ndescription: \"\"\nstart_date: \"2015-09-23\"\nend_date: \"2015-09-25\"\npublished_at: \"2015-09-30\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\nwebsite: \"https://web.archive.org/web/20150920111952/http://rockymtnruby.com/\"\nplaylist: \"https://www.confreaks.tv/events/rmr2015\"\ncoordinates:\n  latitude: 40.0189728\n  longitude: -105.2747406\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2015/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"bradley-grzesiak-rocky-mountain-ruby-2015\"\n  title: \"Simplify Challenging Software Problems with Rocket Science\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Simplify Challenging Software Problems with Rocket Science\"\n  speakers:\n    - Bradley Grzesiak\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-02\"\n  published_at: \"2015-10-02\"\n  description: |-\n    By, Bradley Grzesiak\n    Aerospace engineering is really no more magical than programming, and yet it's shrouded in such mystery and mysticism that practically\n    no one bothers to study it. I'll show you how to apply concepts from rocket science\n    to challenging software problems, allowing you to spend more time coming up with\n    answers rather than interpreting inputs. We'll also learn to control the universe\n    outside our glowing rectangles.\n  video_provider: \"youtube\"\n  video_id: \"h1g1YyVO6j8\"\n\n- id: \"dan-quan-rocky-mountain-ruby-2015\"\n  title: \"Policing and Pairing: An Unlikely Preparation\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Policing and Pairing: An Unlikely Preparation\"\n  speakers:\n    - Dan Quan\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-02\"\n  published_at: \"2015-10-02\"\n  description: |-\n    Pairing is intimidating, hard, and exhausting for most people when they start. It provides countless benefits, but it can be daunting for even seasoned developers. Braintree has a culture and significant tooling around improving the pairing experience, but my experience as a cop gave me the skills needed to thrive at pairing. This talk will briefly cover the tooling of how we pair at Braintree and talk about how my experience as a cop taught me to pair.\n\n  video_provider: \"youtube\"\n  video_id: \"NgGaO92oIGg\"\n\n- id: \"aaron-grey-rocky-mountain-ruby-2015\"\n  title: \"Implications of the Realtime Web\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Implications of the Realtime Web by Aaron Grey\"\n  speakers:\n    - Aaron Grey\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-02\"\n  published_at: \"2015-10-02\"\n  description: |-\n    As the demand for a realtime web is met with our ability to build it, Rails 4.0 introduces realtime as a default option and makes reactive, live applications more attainable than ever.\n\n    We'll discuss the implications of realtime software, the technologies that support it, and how frameworks like Rails, Volt, and Meteor help your team implement better, realtime apps in less time.\n\n  video_provider: \"youtube\"\n  video_id: \"z33Kq2ZibaQ\"\n\n- id: \"christophe-philemotte-rocky-mountain-ruby-2015\"\n  title: \"Prepare Yourself Against Zombie Epidemic\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Prepare yourself against Zombie epidemic by Christophe Philemotte\"\n  speakers:\n    - Christophe Philemotte\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-02\"\n  published_at: \"2015-10-02\"\n  description: |-\n    The news is everywhere: some weird disease makes the dead walking. We do not know yet if it is highly contagious. What should we do? What we do everyday: writing code. We can develop an agent based model, simulate the disease, and hopefully find the best strategy to survive. We can code, we'll be prepared ... or not.\n\n  video_provider: \"youtube\"\n  video_id: \"E0b3K-dO5rk\"\n\n- id: \"andrew-carmer-rocky-mountain-ruby-2015\"\n  title: \"Ruby on Robots\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Ruby on Robots by Andrew Carmer\"\n  speakers:\n    - Andrew Carmer\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-02\"\n  published_at: \"2015-10-02\"\n  description: |-\n    Ruby was designed to be enjoyable and to make its programmer's life easier. You know what makes life easier in the short term? Robot servants. In the long term, there are problems like the singularity and the inevitable robot uprising. But in the mean time, we can all sit back, relax, and control the lights in our home with our favorite programming language. In this talk, we'll explore how to get started using Ruby with Arduino and the Raspberry Pi. We'll bend some hardware to our whim and look at how we can use Ruby to improve our everyday life.\n\n  video_provider: \"youtube\"\n  video_id: \"S7oAljqWUNA\"\n\n- id: \"shelby-switzer-rocky-mountain-ruby-2015\"\n  title: \"API in a box\"\n  raw_title: \"Rocky Mountain Ruby 2015 - API in a box by Shelby Switzer\"\n  speakers:\n    - Shelby Switzer\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-02\"\n  published_at: \"2015-10-02\"\n  description: |-\n    Open data at the local scale is even more of a mess than at the national level, but while there are increasing efforts to improve things nationally, cities, towns, counties, and even states are being left behind. These smaller entities don't have the resources to implement APIs for their data, and community tech groups and developers who want to use this data constantly hit walls — from fragmented, non-uniform data to finding API hosting and maintenance. But what if we could throw all that data in a box that’s easy to open, close, and move around — bypassing traditional solutions requiring infrastructure for hosting and maintenance. Enter Docker and ElasticSearch, and a simple three-layer API-in-a-box solution that any developer can immediately turn on with docker-compose up.\n\n  video_provider: \"youtube\"\n  video_id: \"88mVXnnmWrI\"\n\n- id: \"terence-lee-rocky-mountain-ruby-2015\"\n  title: \"mruby: a Packaging Story Filled with Freedom\"\n  raw_title: \"Rocky Mountain Ruby 2015 - mruby: a Packaging Story Filled with Freedom\"\n  speakers:\n    - Terence Lee\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-02\"\n  published_at: \"2015-10-02\"\n  description: |-\n    By Terence Lee\n    Ruby is a great language for building CLIs. There’s an amazing selection of existing libraries like Thor, GLI, or even OptionParser. You probably use a number of Ruby tools everyday like chef, the heroku toolbelt, , and of course the rails command line tool. Though it’s easy to build a Ruby CLI, distributing it to end users is much more complicated because it requires a Ruby runtime. One option is to rely on Ruby being already installed on the end user’s computer. The other is to bundle ruby as part of the distribution package. Both of these are problematic so much that Vagrant, CloudFoundry and hub (Github command-line tool) have all switched over to Go. But there’s still hope! In 2012, Matz started working on a lightweight embeddable ruby called mruby. Since mruby is designed for being embedded in other compiled languages, it also solves the distribution problem. In this talk we’ll look how we can write CLI tools using mruby to produce a self-contained binary that can be shipped to end users.\n\n  video_provider: \"youtube\"\n  video_id: \"XZNfQTw1IVw\"\n\n- id: \"vipul-a-m-rocky-mountain-ruby-2015\"\n  title: \"Carriers, Services and views on a diet\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Carriers, Services and views on a diet by Vipul A M\"\n  speakers:\n    - Vipul A M\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-05\"\n  published_at: \"2015-10-05\"\n  description: |-\n    Anyone who has done any Rails development knows that views gets complicated very fast. Conditional styling, violating laws of delimiter by double dots, complex business logic deciding view context, skewing and much more plague typical rails views.\n\n    In this talk we'll explore use of simple ruby classes to clean up views, models, controllers, by use of services. We'll delve deeper into 'View Carriers', extracting away complexity out of views, take a look at when rails view helpers fail us, testing strategies, and comparing existing approaches like Trailblazer.\n\n    Because views need to be beautiful too!\n  video_provider: \"youtube\"\n  video_id: \"VGynJM3RqeA\"\n\n- id: \"adam-forsyth-rocky-mountain-ruby-2015\"\n  title: \"Safely Decomposing a Highly Available Rails App\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Safely Decomposing a Highly Available Rails App by Adam Forsyth\"\n  speakers:\n    - Adam Forsyth\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-05\"\n  published_at: \"2015-10-05\"\n  description: |-\n    The Braintree Payment Gateway dates to 2008, and was built as a \"monorail\"\n    -- a monolithic rails application that does everything. Over time, outward-facing\n    features had to be built into it rather than as separate services because identity\n    management, authorization, and authentication were tightly coupled to the rest\n    of the application. Last year, we decided to fix that. We built a new, modern\n    Rails API app, and I'll discuss the many differences from the old platform and\n    why we decided to stick with rails. We also used some nontraditional methods such\n    as running reads and writes through both applications to give us confidence in\n    the new code and help us find missing test coverage. I'll talk about what we learned,\n    what went well and poorly, and how we eventually switched over and split the two\n    applications' databases without downtime.\n  video_provider: \"youtube\"\n  video_id: \"MM2qrG-Ba3E\"\n\n- id: \"jillian-rosile-rocky-mountain-ruby-2015\"\n  title: \"Black Box Testing with RSpec and Capybara\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Black Box Testing with RSpec and Capybara by Jillian Rosile\"\n  speakers:\n    - Jillian Rosile\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-05\"\n  published_at: \"2015-10-05\"\n  description: |-\n    Capybara is a fantastic tool for testing user interactions with our applications. All too often, though, our specs use only Capybara's basic features and get littered with confusing and repetitive code. Instead, we can use the page object pattern and Capybara's more advanced features to write readable and maintainable tests. Come learn how to design a black box testing framework for your web application that turns a website into a clean, readable Ruby API.\n\n  video_provider: \"youtube\"\n  video_id: \"A3ITg4lLv58\"\n\n- id: \"frank-rietta-rocky-mountain-ruby-2015\"\n  title: \"Defending Against Data Breaches, as a Practicing Ruby Developer\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Defending Against Data Breaches, as a Practicing Ruby Developer\"\n  speakers:\n    - Frank Rietta\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-05\"\n  published_at: \"2015-10-05\"\n  description: |-\n    By, Frank Rietta\n    You've been hearing about big data breaches in the news. As a developer who doesn't specialize in security, knowing how to protect your application from getting hacked may seem like a daunting task. However, fundamentals in the design and development process will greatly increase the security that protects your users from harm.\n\n  video_provider: \"youtube\"\n  video_id: \"3JPBqu68Iqg\"\n\n- id: \"mark-gelband-rocky-mountain-ruby-2015\"\n  title: \"Use your super powers for good!\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Use your super powers for good! by Mark Gelband\"\n  speakers:\n    - Mark Gelband\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-05\"\n  published_at: \"2015-10-05\"\n  description: |-\n    Are you doing everything you can to make the world a better place? As a developer you've got the skill to make amazing things, but who are you making them for? Do people need another dating app, or another way to compare uber and lyft pricing? If you want to take your development skills and do something transformational, where do you begin?\n\n  video_provider: \"youtube\"\n  video_id: \"uSWDZv2AHMM\"\n\n- id: \"tara-scherner-de-la-fuente-rocky-mountain-ruby-2015\"\n  title: \"I Like My Params Like I Like My Coffee\"\n  raw_title: \"Rocky Mountain Ruby 2015 - I Like My Params Like I Like My Coffee by Tara Scherner De La Fuente\"\n  speakers:\n    - Tara Scherner de la Fuente\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-05\"\n  published_at: \"2015-10-05\"\n  description: |-\n    Anyone moving to Rails 4 has seen the documented examples like this: params.require(:coffee).permit(:all, :the, :things). But if the codebase has multiple controllers (including a few over 1000 lines long), some api endpoints, nested attributes nesting inside attributes that are named things like additional_attributes_attributes, and robust test coverage that has likely caused forbidden attribute grief, then this talk about some of the little/not documented details of the parameters we call strong might be your cup of...coffee.\n\n  video_provider: \"youtube\"\n  video_id: \"Nry6RCyTmXU\"\n\n- id: \"steve-klabnik-rocky-mountain-ruby-2015\"\n  title: \"Rust for Rubyists\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Rust for Rubyists by Steve Klabnik\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-05\"\n  published_at: \"2015-10-05\"\n  description: |-\n    Rubyists are famously polyglot. I've heard people joke that there are more JavaScript talks at some Ruby conferences than there are Ruby talks. But there's one area in which most Rubyists don't go: low-level programming. We often say 'Ruby is slow, but that doesn't matter. I'll just drop down to C when I need performance.' But C is pretty scary, so we never actually do it. In this talk, Steve will show off Rust, a new programming language from Mozilla. Steve will show you how that saying should change: 'drop down to Rust,' and why it's better for Rubyists than C.\n\n  video_provider: \"youtube\"\n  video_id: \"NaIXIKVxg3M\"\n\n- id: \"bree-thomas-rocky-mountain-ruby-2015\"\n  title: \"Burn Rubber Does Not Mean Warp Speed\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Burn Rubber Does Not Mean Warp Speed by Bree Thomas\"\n  speakers:\n    - Bree Thomas\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-06\"\n  published_at: \"2015-10-06\"\n  description: |-\n    We talk about bringing new developers \"up to speed quickly.\" Imposter syndrome is bad enough, but often junior developers feel pressured to learn faster and produce more. Developers often focus on velocity as the critical measure of success. The need for speed actually amplifies insecurities and hinders growth. Instead let's talk about how we can more effectively structure, implement, and track apprenticeships with the right kind of framework and focus.\n\n  video_provider: \"youtube\"\n  video_id: \"wCvikMfa93k\"\n\n- id: \"adam-cuppy-rocky-mountain-ruby-2015\"\n  title: 'Culture (Only Three Letters Away from “Cult\")'\n  raw_title: 'Rocky Mountain Ruby 2015 - Culture (Only Three Letters Away from “Cult\") by Adam Cuppy'\n  speakers:\n    - Adam Cuppy\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-06\"\n  published_at: \"2015-10-06\"\n  description: |-\n    \"I’m a cross between a night dragon, code wizard and a unique damn butterfly. I am not your ‘resource’ to pimp out!” said every rage-quit prone engineer, ever. As a team leader, the line between diverse culture and a dogmatic cult is thin. Embracing individuality, yet finding alignment as a collective, is tough. Understanding what defines one over another is critical so everyone can bring 100% of themselves to table.\n\n    In this talk I’m going to walk through our journey as a team: finding alignment, embracing individuality and discovering our shared values. I’ll identify our faulty pitfalls, red-flags and a set of questions to ask yourself everyday to make sure that what you have a is “Culture of Talent” and not a “Cult of Conformity.\"\n\n  video_provider: \"youtube\"\n  video_id: \"nN_rc2BovLA\"\n\n- id: \"ian-whitney-rocky-mountain-ruby-2015\"\n  title: \"Even Hemingway Wasn't Hemingway\"\n  raw_title: \"Rocky Mountain Ruby 2015 - Even Hemingway Wasn't Hemingway by Ian Whitney\"\n  speakers:\n    - Ian Whitney\n  event_name: \"Rocky Mountain Ruby 2015\"\n  date: \"2015-10-06\"\n  published_at: \"2015-10-06\"\n  description: |-\n    “The first draft of anything is **.” - Ernest Hemingway\n\n    Ernest Hemingway didn't write first drafts of sparse, clear prose. He wrote terrible first drafts and then rewrote them, over and over, until the design of the prose was right.\n\n    For Hemingway, and every good writer, Writing is Rewriting.\n\n    As programmers our first drafts are terrible as well. Perhaps we clean up that first draft with some stylistic tweaks that make it look nicer but that don't affect the underlying design. But how often do we really dig in to that first draft and tear it apart, redesigning it until it is sparse and clear? Not often enough. And that's to our detriment.\n\n    For good developers, Design is Refactoring.\n\n    That sounds easy, but all too frequently refactoring doesn't lead to appreciable changes in the code's design. How do you use refactoring to improve code design? And how do you identify when you're just changing the surface style of your code? What's the difference between coding style and design, anyway? I'll answer all of these questions, hopefully, and show you how to take your code from a first draft to a clear, sparse design.\n\n  video_provider: \"youtube\"\n  video_id: \"2KqQhlYIfTs\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2016/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybyoywtp2XxiPaBDnKgD5gk\"\ntitle: \"Rocky Mountain Ruby 2016\"\nkind: \"conference\"\nlocation: \"Denver, CO, United States\"\ndescription: \"\"\nstart_date: \"2016-09-30\"\nend_date: \"2016-09-30\"\npublished_at: \"2016-10-19\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2016\nwebsite: \"https://web.archive.org/web/20161004143513/http://rockymtnruby.com/\"\nplaylist: \"http://confreaks.tv/events/rockymountainruby2016\"\ncoordinates:\n  latitude: 39.7392358\n  longitude: -104.990251\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2016/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"dave-thomas-rocky-mountain-ruby-2016\"\n  title: \"Stop Writing Web Apps and Change the World\"\n  raw_title: \"Rocky Mountain Ruby 2016 - Stop Writing Web Apps and Change the World by Dave Thomas\"\n  speakers:\n    - Dave Thomas\n  event_name: \"Rocky Mountain Ruby 2016\"\n  date: \"2016-10-19\"\n  published_at: \"2016-10-19\"\n  description: |-\n    Stop Writing Web Apps and Change the World by Dave Thomas\n  video_provider: \"youtube\"\n  video_id: \"bCSOCodWjt0\"\n\n- id: \"erika-carlson-rocky-mountain-ruby-2016\"\n  title: \"10 Lessons for Growing Junior Developers\"\n  raw_title: \"Rocky Mountain Ruby 2016 - 10 Lessons for Growing Junior Developers by Erika Carlson\"\n  speakers:\n    - Erika Carlson\n  event_name: \"Rocky Mountain Ruby 2016\"\n  date: \"2016-10-20\"\n  published_at: \"2016-10-20\"\n  description: |-\n    10 Lessons for Growing Junior Developers by Erika Carlson\n  video_provider: \"youtube\"\n  video_id: \"6YQsdjfny1Q\"\n\n- id: \"kinsey-ann-durham-rocky-mountain-ruby-2016\"\n  title: \"Becoming a MID: Two Perspectives on Leveling Up\"\n  raw_title: \"Rocky Mountain Ruby 2016 - Becoming a MID: Two Perspectives on Leveling Up\"\n  speakers:\n    - Kinsey Ann Durham\n    - Kim Barnes\n  event_name: \"Rocky Mountain Ruby 2016\"\n  date: \"2016-10-20\"\n  published_at: \"2016-10-20\"\n  description: |-\n    Becoming a MID: Two Perspectives on Leveling Up by Kinsey Ann Durham and Kim Barnes\n  video_provider: \"youtube\"\n  video_id: \"hSJZWg-7hgc\"\n\n- id: \"ingrid-alongi-rocky-mountain-ruby-2016\"\n  title: \"Fireside Chat\"\n  raw_title: \"Rocky Mountain Ruby 2016 - Fireside Chat with Ingrid Alongi\"\n  speakers:\n    - Ingrid Alongi\n  event_name: \"Rocky Mountain Ruby 2016\"\n  date: \"2016-10-20\"\n  published_at: \"2016-10-20\"\n  description: |-\n    Fireside Chat with Ingrid Alongi\n  video_provider: \"youtube\"\n  video_id: \"z9bRcuIBh1s\"\n\n- id: \"sarah-allen-rocky-mountain-ruby-2016\"\n  title: \"Communication is a Technical Skill\"\n  raw_title: \"Rocky Mountain Ruby 2016 - Communication is a Technical Skill by Sarah Allen\"\n  speakers:\n    - Sarah Allen\n  event_name: \"Rocky Mountain Ruby 2016\"\n  date: \"2016-10-20\"\n  published_at: \"2016-10-20\"\n  description: |-\n    Communication is a Technical Skill by Sarah Allen\n  video_provider: \"youtube\"\n  video_id: \"coye0AllVuY\"\n\n- id: \"andi-rugg-rocky-mountain-ruby-2016\"\n  title: \"Community Spotlight: Andi Rugg (Skillful / Markle Foundation)\"\n  raw_title: \"Rocky Mountain Ruby 2016 - Community Spotlight: Andi Rugg (Skillful / Markle Foundation)\"\n  speakers:\n    - Andi Rugg\n  event_name: \"Rocky Mountain Ruby 2016\"\n  date: \"2016-10-20\"\n  published_at: \"2016-10-20\"\n  description: |-\n    Community Spotlight: Andi Rugg (Skillful / Markle Foundation)\n  video_provider: \"youtube\"\n  video_id: \"0mg6fDAQo0o\"\n\n- id: \"jackie-ros-rocky-mountain-ruby-2016\"\n  title: \"Community Spotlight: Jackie Ros (Revolar)\"\n  raw_title: \"Rocky Mountain Ruby 2016 - Community Spotlight: Jackie Ros (Revolar)\"\n  speakers:\n    - Jackie Ros\n  event_name: \"Rocky Mountain Ruby 2016\"\n  date: \"2016-10-20\"\n  published_at: \"2016-10-20\"\n  description: |-\n    Community Spotlight: Jackie Ros (Revolar)\n  video_provider: \"youtube\"\n  video_id: \"hCOsUVDNVLY\"\n\n- id: \"chad-fowler-rocky-mountain-ruby-2016\"\n  title: 'Kill \"Microservices\" before its too late'\n  raw_title: 'Rocky Mountain Ruby 2016 - Kill \"Microservices\" before its too late by Chad Fowler'\n  speakers:\n    - Chad Fowler\n  event_name: \"Rocky Mountain Ruby 2016\"\n  date: \"2016-10-20\"\n  published_at: \"2016-10-20\"\n  description: |-\n    Kill \"Microservices\" before its too late by Chad Fowler\n  video_provider: \"youtube\"\n  video_id: \"-UKEPd2ipEk\"\n\n- id: \"saron-yitbarek-rocky-mountain-ruby-2016\"\n  title: \"Lucky\"\n  raw_title: \"Rocky Mountain Ruby 2016 - Lucky by Saron Yitbarek\"\n  speakers:\n    - Saron Yitbarek\n  event_name: \"Rocky Mountain Ruby 2016\"\n  date: \"2016-10-20\"\n  published_at: \"2016-10-20\"\n  description: |-\n    Lucky by Saron Yitbarek\n  video_provider: \"youtube\"\n  video_id: \"WnOfezStmmg\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2017/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybY7O3XEVqxUeeXQeXqiVpH\"\ntitle: \"Rocky Mountain Ruby 2017\"\nkind: \"conference\"\nlocation: \"Denver, CO, United States\"\ndescription: \"\"\nstart_date: \"2017-09-29\"\nend_date: \"2017-09-29\"\npublished_at: \"2017-10-12\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2017\nwebsite: \"https://web.archive.org/web/20170920035229/http://rockymtnruby.com/\"\ncoordinates:\n  latitude: 39.7392358\n  longitude: -104.990251\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2017/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"anjuan-simmons-rocky-mountain-ruby-2017\"\n  title: \"Leadership Lessons from the Agile Manifesto\"\n  raw_title: \"Rocky Mountain Ruby 2017 -  Leadership Lessons from the Agile Manifesto by Anjuan Simmons\"\n  speakers:\n    - Anjuan Simmons\n  event_name: \"Rocky Mountain Ruby 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-10-12\"\n  description: |-\n    Rocky Mountain Ruby 2017 -  Leadership Lessons from the Agile Manifesto by Anjuan Simmons\n  video_provider: \"youtube\"\n  video_id: \"ng8JrBvkqm0\"\n\n- id: \"amy-chen-rocky-mountain-ruby-2017\"\n  title: \"Building Helm Charts From the Ground Up...\"\n  raw_title: \"Rocky Mountain Ruby 2017 - Building Helm Charts From the Ground Up... by Amy Chen\"\n  speakers:\n    - Amy Chen\n  event_name: \"Rocky Mountain Ruby 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-10-12\"\n  description: |-\n    Rocky Mountain Ruby 2017 - Building Helm Charts From the Ground Up: An Introduction to Kubernetes by Amy Chen\n  video_provider: \"youtube\"\n  video_id: \"r3FMW9PCQ7k\"\n\n- id: \"carrie-simon-rocky-mountain-ruby-2017\"\n  title: \"Community Spotlight: Carrie Simon from Defy Venture\"\n  raw_title: \"Rocky Mountain Ruby 2017 - Community Spotlight: Carrie Simon from Defy Venture by Carrie Simon\"\n  speakers:\n    - Carrie Simon\n  event_name: \"Rocky Mountain Ruby 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-10-12\"\n  description: |-\n    Rocky Mountain Ruby 2017 - Community Spotlight: Carrie Simon from Defy Venture by Carrie Simon\n  video_provider: \"youtube\"\n  video_id: \"kfXAIHMYdn0\"\n\n- id: \"adam-cuppy-rocky-mountain-ruby-2017\"\n  title: \"Trust Me\"\n  raw_title: \"Rocky Mountain Ruby 2017 - Trust Me by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"Rocky Mountain Ruby 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-10-12\"\n  description: |-\n    Rocky Mountain Ruby 2017 - Trust Me by Adam Cuppy\n  video_provider: \"youtube\"\n  video_id: \"HJp07lXlx5U\"\n\n- id: \"elaine-marino-rocky-mountain-ruby-2017\"\n  title: \"Community Spotlight: Elaine Marino from Equili\"\n  raw_title: \"Rocky Mountain Ruby 2017 - Community Spotlight: Elaine Marino from Equili BY Elaine Marino\"\n  speakers:\n    - Elaine Marino\n  event_name: \"Rocky Mountain Ruby 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-10-12\"\n  description: |-\n    Rocky Mountain Ruby 2017 - Community Spotlight: Elaine Marino from Equili BY Elaine Marino\n  video_provider: \"youtube\"\n  video_id: \"nEt9LLXGp_o\"\n\n- id: \"brittany-storoz-rocky-mountain-ruby-2017\"\n  title: \"Comparative Error Handling...\"\n  raw_title: \"Rocky Mountain Ruby 2017 - Comparative Error Handling... by Brittany Storoz\"\n  speakers:\n    - Brittany Storoz\n  event_name: \"Rocky Mountain Ruby 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-10-12\"\n  description: |-\n    Rocky Mountain Ruby 2017 - Comparative Error Handling: Learning from Minor Mistakes with Terrible Error Messages by Brittany Storoz\n  video_provider: \"youtube\"\n  video_id: \"9gSC0Dl50D4\"\n\n- id: \"ben-orenstein-rocky-mountain-ruby-2017\"\n  title: \"Trust, But Verify (Programmatically)\"\n  raw_title: \"Rocky Mountain Ruby 2017 - Trust, But Verify (Programmatically) by Ben Orenstein\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"Rocky Mountain Ruby 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-10-12\"\n  description: |-\n    Rocky Mountain Ruby 2017 - Trust, But Verify (Programmatically) by Ben Orenstein\n  video_provider: \"youtube\"\n  video_id: \"dEC5cRvoeZw\"\n\n- id: \"vaidehi-joshi-rocky-mountain-ruby-2017\"\n  title: \"The (Non-Perfect) Mathematics of Trust\"\n  raw_title: \"Rocky Mountain Ruby 2017 - The (Non-Perfect) Mathematics of Trust by Vaidehi Joshi\"\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"Rocky Mountain Ruby 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-10-12\"\n  description: |-\n    Rocky Mountain Ruby 2017 - The (Non-Perfect) Mathematics of Trust by Vaidehi Joshi\n  video_provider: \"youtube\"\n  video_id: \"R9iHVv7v4_o\"\n\n- id: \"april-wensel-rocky-mountain-ruby-2017\"\n  title: \"A Discussion on Responsible Hiring & Team Building\"\n  raw_title: \"Rocky Mountain Ruby 2017 -  A Discussion on Responsible Hiring & Team Building by April Wensel\"\n  speakers:\n    - April Wensel\n  event_name: \"Rocky Mountain Ruby 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-10-12\"\n  description: |-\n    Rocky Mountain Ruby 2017 -  A Discussion on Responsible Hiring & Team Building by April Wensel\n  video_provider: \"youtube\"\n  video_id: \"UBN18wRRLlg\"\n\n- id: \"sarah-mei-rocky-mountain-ruby-2017\"\n  title: \"Livable Code\"\n  raw_title: \"Rocky Mountain Ruby 2017 - Livable Code by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"Rocky Mountain Ruby 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-10-12\"\n  description: |-\n    Rocky Mountain Ruby 2017 - Livable Code by Sarah Mei\n  video_provider: \"youtube\"\n  video_id: \"8_UoDmJi7U8\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2023/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybyMod_mAVQzlX7SmzmNWaJ\"\ntitle: \"Rocky Mountain Ruby 2023\"\nkind: \"conference\"\nlocation: \"Boulder, CO, United States\"\ndescription: |-\n  Rocky Mountain Ruby is a single track conference devoted to the Ruby programming language which features technical presentations, community events and outdoor experiences in beautiful Boulder, Colorado at one of the best times of year.\npublished_at: \"2023-10-26\"\nstart_date: \"2023-10-05\"\nend_date: \"2023-10-06\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2023\nbanner_background: \"#AC0D0E\"\nfeatured_background: \"#AC0D0E\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2023.rockymtnruby.dev\"\ncoordinates:\n  latitude: 40.0189728\n  longitude: -105.2747406\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"dustin-haefele-tschanz-rocky-mountain-ruby-2023\"\n  title: \"The pursuit of happiness.\"\n  raw_title: \"The pursuit of happiness. by Dustin Haefele-Tschanz\"\n  speakers:\n    - Dustin Haefele-Tschanz\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - The pursuit of happiness. by Dustin Haefele-Tschanz\n\n    Who in this world would say ‘no’ to being a little happier? Luckily for us there has been a lot of wonderful scientific studies done on human happiness. This talk will cover a number of my favorite studies in this field, and how they can be applied to life and careers in tech.\n  video_provider: \"youtube\"\n  video_id: \"gh2qo1qZxdc\"\n\n- id: \"joel-hawksley-rocky-mountain-ruby-2023\"\n  title: \"Accessible by default\"\n  raw_title: \"Accessible by default by Joel Hawksley\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - Accessible by default by Joel Hawksley\n\n    It’s one thing to build a new application that meets the latest accessibility standards, but it’s another thing to update an existing application to meet them. In this talk, we’ll share how we’re using automated accessibility scanning, preview-driven development, and an accessibility-first form builder to make GitHub’s 15-year-old, 1,400-controller Ruby on Rails monolith accessible.\n  video_provider: \"youtube\"\n  video_id: \"8tR3LJ2cEsE\"\n\n- id: \"marc-reynolds-rocky-mountain-ruby-2023\"\n  title: \"Modularizing Rails Monoliths One Bite at a Time\"\n  raw_title: \"Modularizing Rails Monoliths One Bite at a Time by Marc Reynolds\"\n  speakers:\n    - Marc Reynolds\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - Modularizing Rails Monoliths One Bite at a Time by Marc Reynolds\n\n    As Rails monoliths grow, coupling becomes increasingly difficult to manage. Many have reached for hope in microservices but instead found higher complexity. The Modular Monolith approach is a proven, lightweight alternative that offers the benefits of enforced boundaries without being cumbersome. This talk proposes a phased approach to refactoring toward this style using the packwerk gem.\n  video_provider: \"youtube\"\n  video_id: \"qxKuvR08EUc\"\n\n- id: \"ifat-ribon-rocky-mountain-ruby-2023\"\n  title: \"Go Pro with POROs\"\n  raw_title: \"Go Pro with POROs by Ifat Ribon\"\n  speakers:\n    - Ifat Ribon\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - Go Pro with POROs by Ifat Ribon\n\n    Plain Old Ruby Objects (POROs) are having a moment. Maybe you’ve heard a whisper in the corner about the jack-of-all trades Service Object, or a glimmering echo of advocacy for non-database-backed domain models? Think you’re using them right? Afraid you’re using them wrong? Then this is the talk for you! We’re going to explore the wonderful world of “convention plus choose-your-own configuration” of Rails codebases and the shining role of POROs (with their ride or dies, the Module). Come hear about the diversity of design patterns out in the wild so you too can confidently tell your coworkers “let’s just use a PORO for that”.\n  video_provider: \"youtube\"\n  video_id: \"rMhxGAAJFbM\"\n\n- id: \"jon-evans-rocky-mountain-ruby-2023\"\n  title: \"Let’s Extract a Class: The Single Responsibility Principle and Design Patterns\"\n  raw_title: \"Let’s Extract a Class: The Single Responsibility Principle and Design Patterns by Jon Evans\"\n  speakers:\n    - Jon Evans\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - Let’s Extract a Class: The Single Responsibility Principle and Design Patterns by Jon Evans\n\n    We’ll talk about going beyond “fat model, skinny controller” and the importance of following the Single Responsibility Principle. Several common design patterns will be discussed, but the emphasis will be on the importance of encapsulating your logic in whatever way you choose that makes the code readable and maintainable. Finally, how do you get your team on board?\n  video_provider: \"youtube\"\n  video_id: \"tqG23aWuPa4\"\n\n- id: \"drew-bragg-rocky-mountain-ruby-2023\"\n  title: \"Who Wants to be a Ruby Engineer?\"\n  raw_title: \"Who Wants to be a Ruby Engineer? by Drew Bragg\"\n  speakers:\n    - Drew Bragg\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - Who Wants to be a Ruby Engineer? by Drew Bragg\n\n    Welcome to the Ruby game show where contestants tries to guess the output of a small bit of Ruby code. Sound easy? Here's the challenge: the snippets come from some of the weirdest parts of the Ruby language. The questions aren't easy but get enough right to win a fabulous prize.\n  video_provider: \"youtube\"\n  video_id: \"wdVNBVxLou8\"\n\n- id: \"ridhwana-khan-rocky-mountain-ruby-2023\"\n  title: \"Caching strategies on https://dev.to\"\n  raw_title: \"Caching strategies on https://dev.to by Ridhwana Khan\"\n  speakers:\n    - Ridhwana Khan\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - Caching strategies on https://dev.to by Ridhwana Khan\n\n    We've always put a lot of effort into performance at Dev (https://dev.to/). We want our users to be able to see their content almost instantaneously when interacting with our site. In order to do so we've placed emphasis on caching. We've had to ask ourselves questions like what are the right things to cache? Which layer in the stack would be best to cache it? And how will this effect the overall performance? During this presentation, I'd like to show you some of the caching strategies we have in place and discuss how they've sped up the interactions within our site.\n  video_provider: \"youtube\"\n  video_id: \"BuxrL8W_EaE\"\n\n- id: \"brooke-kuhlmann-rocky-mountain-ruby-2023\"\n  title: \"Return To Simplicity: Architect Hypermedia REST applications using Hanami + HTMX\"\n  raw_title: \"Return To Simplicity: Architect Hypermedia REST applications using Hanami + HTMX by Brooke Kuhlmann\"\n  speakers:\n    - Brooke Kuhlmann\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - A Return To Simplicity: Architect Hypermedia REST applications using Hanami + HTMX by Brooke Kuhlmann\n\n    Have you grown tired of overly complex web applications with massive frontend and backend teams? What if you could do all of this with one team of Ruby engineers using only a Hypermedia RESTful design? Well you can and I'll show you how!\n  video_provider: \"youtube\"\n  video_id: \"vVMZ6qhdxkg\"\n\n- id: \"moncef-belyamani-rocky-mountain-ruby-2023\"\n  title: \"Licensing and Distributing a Paid CLI With Ruby, Rails, and SwiftUI\"\n  raw_title: \"Licensing and Distributing a Paid CLI With Ruby, Rails, and SwiftUI by Moncef Belyamani\"\n  speakers:\n    - Moncef Belyamani\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - Licensing and Distributing a Paid CLI With Ruby, Rails, and SwiftUI by Moncef Belyamani\n\n    Distributing licenses and enforcing limitations for my \"Ruby on Mac\" CLI was a super interesting and fun problem to solve. It involved tools such as ruby-packer, shc, Apple's DeviceCheck API, and creating a .pkg installer. I'll take you on that journey with me, with lessons learned and code samples. You'll learn tactics for thinking through similar problems, and for writing testable code.\n  video_provider: \"youtube\"\n  video_id: \"taaVciVdNQg\"\n\n- id: \"lightning-talks-rocky-mountain-ruby-2023\"\n  title: \"Lightning Talks\"\n  raw_title: \"Rocky Mountain Ruby 2023 - Lightning Talks\"\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    A series of lightning talks from Rocky Mountain Ruby 2023.\n  video_provider: \"youtube\"\n  video_id: \"lmAPQuUrhFw\"\n  talks:\n    - title: \"Lightning Talk: The SuperSpreader gem\"\n      date: \"2023-10-26\"\n      start_cue: \"00:00\"\n      end_cue: \"05:18\"\n      id: \"ben-oakes-lighting-talk-rocky-mountain-ruby-2023\"\n      video_id: \"ben-oakes-lighting-talk-rocky-mountain-ruby-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Ben Oakes\n\n    - title: \"Lightning Talk: First Follower\"\n      date: \"2023-10-26\"\n      start_cue: \"05:18\"\n      end_cue: \"09:08\"\n      id: \"melony-erin-franchini-lighting-talk-rocky-mountain-ruby-2023\"\n      video_id: \"melony-erin-franchini-lighting-talk-rocky-mountain-ruby-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Melony Erin Franchini\n\n    - title: \"Lightning Talk: Building Broken Gems\"\n      date: \"2023-10-26\"\n      start_cue: \"09:08\"\n      end_cue: \"12:48\"\n      id: \"samuel-giddins-lighting-talk-rocky-mountain-ruby-2023\"\n      video_id: \"samuel-giddins-lighting-talk-rocky-mountain-ruby-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Samuel Giddins\n\n    - title: \"Lightning Talk: Immutability in Ruby POROs\"\n      date: \"2023-10-26\"\n      start_cue: \"12:48\"\n      end_cue: \"17:49\"\n      id: \"eric-mueller-lighting-talk-rocky-mountain-ruby-2023\"\n      video_id: \"eric-mueller-lighting-talk-rocky-mountain-ruby-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Eric Mueller\n\n    - title: \"Lightning Talk: The excited References, Extensions, Explorations Section to Marc's Talk\"\n      date: \"2023-10-26\"\n      start_cue: \"17:49\"\n      end_cue: \"22:07\"\n      id: \"stephan-lighting-talk-rocky-mountain-ruby-2023\"\n      video_id: \"stephan-lighting-talk-rocky-mountain-ruby-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Stephan\n\n    - title: \"Lightning Talk: Makefiles\"\n      date: \"2023-10-26\"\n      start_cue: \"22:07\"\n      end_cue: \"25:14\"\n      id: \"blake-gearin-lighting-talk-rocky-mountain-ruby-2023\"\n      video_id: \"blake-gearin-lighting-talk-rocky-mountain-ruby-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Blake Gearin\n\n    - title: \"Lightning Talk: Code & Coffee\"\n      date: \"2023-10-26\"\n      start_cue: \"25:14\"\n      end_cue: \"26:22\"\n      id: \"jeremy-hinegardner-lighting-talk-rocky-mountain-ruby-2023\"\n      video_id: \"jeremy-hinegardner-lighting-talk-rocky-mountain-ruby-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeremy Hinegardner\n\n- id: \"jon-sullivan-rocky-mountain-ruby-2023\"\n  title: \"Turbo Frames Explored... for Fun and Profit\"\n  raw_title: \"Turbo Frames Explored... for Fun and Profit by Jon Sullivan\"\n  speakers:\n    - Jon Sullivan\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - Turbo Frames Explored... for Fun and Profit by Jon Sullivan\n\n    The ‘new magic’ came at the end of 2020: ✨Hotwire⚡️: Stimulus, Turbo Streams, Strada, Turbo Drive, and Turbo Frames. Each extremely capable and powerful in its own right, but with a wide spread of functions and some overlaps, it can be tough to see what’s what. Let’s explore just one avenue: Turbo Frames. Let’s see what it can _really_ do.\n  video_provider: \"youtube\"\n  video_id: \"bru8S3PttLY\"\n\n- id: \"davy-stevenson-rocky-mountain-ruby-2023\"\n  title: \"A blueprint for making scary choices\"\n  raw_title: \"A blueprint for making scary choices by Davy Stevenson\"\n  speakers:\n    - Davy Stevenson\n  event_name: \"Rocky Mountain Ruby 2023\"\n  date: \"2023-10-26\"\n  published_at: \"2023-10-26\"\n  description: |-\n    Rocky Mountain Ruby 2023 - A blueprint for making scary choices by Davy Stevenson\n\n    In early 2021 I made the scariest decision of my life — I decided that I was going to stop waiting to find a partner and instead I would have a child by myself. My little boy is now 1 year old, and my life path looks completely different than I ever thought. We all are faced with overwhelming decisions in our lives. How do we know what choice is right for us? Through my own journey I've developed a rubric for evaluating these scary choices — whether professional or personal — and I hope that sharing these lessons might be helpful for you.\n  video_provider: \"youtube\"\n  video_id: \"fzKCobWzCxo\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2024/cfp.yml",
    "content": "---\n- link: \"https://sessionize.com/rocky-mountain-ruby\"\n  open_date: \"2024-05-15\"\n  close_date: \"2024-06-30\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2024/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybTVAqwUME6Jafmyx6o5CUg\"\ntitle: \"Rocky Mountain Ruby 2024\"\nkind: \"conference\"\nlocation: \"Boulder, CO, United States\"\ndescription: |-\n  Rocky Mountain Ruby is a single track conference devoted to the Ruby programming language which features technical presentations, community events and outdoor experiences in beautiful Boulder, Colorado at one of the best times of year.\npublished_at: \"2024-11-06\"\nstart_date: \"2024-10-07\"\nend_date: \"2024-10-08\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2024\nbanner_background: \"#0A0F34\"\nfeatured_background: \"#0A0F34\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2024.rockymtnruby.dev\"\ncoordinates:\n  latitude: 40.0201669\n  longitude: -105.275401\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2024/schedule.yml",
    "content": "# Schedule: https://rockymtnruby.dev/schedule\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-10-07\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Check-in/Breakfast\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n\n      - start_time: \"09:15\"\n        end_time: \"09:50\"\n        slots: 1\n\n      - start_time: \"09:50\"\n        end_time: \"10:25\"\n        slots: 1\n\n      - start_time: \"10:25\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Open Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:35\"\n        slots: 1\n\n      - start_time: \"14:35\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 1\n        items:\n          - Break/Snacks\n\n      - start_time: \"15:40\"\n        end_time: \"16:15\"\n        slots: 1\n\n      - start_time: \"16:15\"\n        end_time: \"16:50\"\n        slots: 1\n\n      - start_time: \"16:50\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Wrap up\n\n  - name: \"Day 2\"\n    date: \"2024-10-08\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Breakfast\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Welcome\n\n      - start_time: \"09:15\"\n        end_time: \"09:50\"\n        slots: 1\n\n      - start_time: \"09:50\"\n        end_time: \"10:25\"\n        slots: 1\n\n      - start_time: \"10:25\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Open Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 1\n        items:\n          - Break/Snacks\n\n      - start_time: \"15:40\"\n        end_time: \"16:15\"\n        slots: 1\n\n      - start_time: \"16:15\"\n        end_time: \"17:00\"\n        slots: 1\n\ntracks: []\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sapphire Sponsors\"\n      description: |-\n        Top level sponsorship category\n      level: 1\n      sponsors:\n        - name: \"Honeybadger\"\n          website: \"https://www.honeybadger.io/\"\n          slug: \"Honeybadger\"\n          logo_url: \"https://2024.rockymtnruby.dev/images/sponsors/honeybadger_logo.svg\"\n\n    - name: \"Emerald Sponsors\"\n      description: |-\n        Second level sponsorship category\n      level: 2\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"AppSignal\"\n          logo_url: \"https://2024.rockymtnruby.dev/images/sponsors/Appsignal-original-azure.png\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"DNSimple\"\n          logo_url: \"https://2024.rockymtnruby.dev/images/sponsors/dnsimple-logo-blue.png\"\n\n    - name: \"Community Sponsors\"\n      description: |-\n        Third level sponsorship category\n      level: 3\n      sponsors:\n        - name: \"Flagrant\"\n          website: \"https://www.beflagrant.com/\"\n          slug: \"Flagrant\"\n          logo_url: \"https://2024.rockymtnruby.dev/images/sponsors/FlagrantLogo_Color.svg\"\n\n    - name: \"Podcast Sponsors\"\n      description: |-\n        Fourth level sponsorship category\n      level: 4\n      sponsors:\n        - name: \"Remote Ruby\"\n          website: \"https://www.remoteruby.com\"\n          slug: \"RemoteRuby\"\n          logo_url: \"https://2024.rockymtnruby.dev/images/sponsors/remote-ruby.jpeg\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2024/venue.yml",
    "content": "---\nname: \"eTown Hall\"\n\naddress:\n  street: \"1535 Spruce Street\"\n  city: \"Boulder\"\n  region: \"Colorado\"\n  postal_code: \"80302\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"1535 Spruce St, Boulder, CO 80302, USA\"\n\ncoordinates:\n  latitude: 40.0201669\n  longitude: -105.275401\n\nmaps:\n  google: \"https://maps.google.com/?q=eTown+Hall,40.0201669,-105.275401\"\n  apple: \"https://maps.apple.com/?q=eTown+Hall&ll=40.0201669,-105.275401\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=40.0201669&mlon=-105.275401\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2024/videos.yml",
    "content": "---\n# Website: https://rockymtnruby.dev\n# Schedule: https://rockymtnruby.dev/schedule\n\n## Day 1 - Monday, October 7, 2024\n\n# Check-in/Breakfast\n\n- id: \"spike-ilacqua-rocky-mountain-ruby-2024\"\n  title: \"Opening Remarks\"\n  raw_title: \"Opening Remarks with Spike Ilacqua and Bekki Freeman\"\n  speakers:\n    - Spike Ilacqua\n    - Bekki Freeman\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-07\"\n  published_at: \"2024-11-06\"\n  description: |-\n    Opening Remarks with Spike Ilacqua and Bekki Freeman\n  video_provider: \"youtube\"\n  video_id: \"SGskS0ePogc\"\n\n- id: \"alan-ridlehoover-rocky-mountain-ruby-2024\"\n  title: \"A Brewer's Guide to Filtering out Complexity and Churn\"\n  raw_title: \"A Brewer's Guide to Filtering out Complexity and... by Alan Ridlehoover and Fito von Zastrow Alfonso\"\n  speakers:\n    - Alan Ridlehoover\n    - Fito von Zastrow\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-07\"\n  published_at: \"2024-11-06\"\n  slides_url: \"https://speakerdeck.com/aridlehoover/rocky-mountain-ruby-2024-a-brewers-guide-to-filtering-out-complexity-and-churn\"\n  description: |-\n    A Brewer's Guide to Filtering out Complexity and Churn by Alan Ridlehoover and Fito von Zastrow\n\n    Mechanical coffee machines are amazing! You drop in a coin, listen for the clink, make a selection, and the machine springs to life, hissing, clicking, and whirring. Then the complex mechanical ballet ends, splashing that glorious, aromatic liquid into the cup. Ah! C’est magnifique! There’s just one problem. Our customers also want soup! And, our machine is not extensible. So, we have a choice: we can add to the complexity of our machine by jamming in a new dispenser with each new request; or, we can pause to make our machine more extensible before development slows to a halt.\n  video_provider: \"youtube\"\n  video_id: \"4b4Ew_BUdrY\"\n\n- id: \"tay-deherrera-jimenez-rocky-mountain-ruby-2024\"\n  title: \"Pry Until You Die\"\n  raw_title: \"Pry Until You Die by Tay DeHerrera Jimenez\"\n  speakers:\n    - Tay DeHerrera Jimenez\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-07\"\n  published_at: \"2024-11-06\"\n  description: |-\n    In this talk, I will dive into the ins and outs of Pry, the powerful runtime developer console for Ruby. Many developers know about Pry, but do they understand how it works under the hood? How does `binding.pry` halt code execution and inject itself into the process?\n\n    We'll explore the mechanics of Pry, revealing how it integrates seamlessly with your code. Additionally, I'll share essential tips and tricks to maximize your productivity within Pry sessions, including:\n\n    - Customizing your Pry environment\n    - Navigating and debugging code efficiently\n    - Utilizing advanced Pry features and plugins\n\n    Whether you're a Pry novice or a seasoned user, this session will enhance your debugging and development skills, enabling you to harness Pry's full potential.\n  video_provider: \"youtube\"\n  video_id: \"PnYcxZzd1So\"\n\n# Break\n\n- id: \"amir-rajan-rocky-mountain-ruby-2024\"\n  title: \"DragonRuby Game Toolkit: Lessons Learned\"\n  raw_title: \"DragonRuby Game Toolkit: Lessons Learned by Amir Rajan\"\n  speakers:\n    - Amir Rajan\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-07\"\n  published_at: \"2024-11-06\"\n  description: |-\n    DragonRuby Game Toolkit recently celebrated its 5 year anniversary. Over that time it’s become one of the highest rated and most popular game engines on Itch.io. Amir will share lessons he learned over that period: everything from the low level architecture, to the more human aspects of creating a community around Ruby and the joy it's brought to new devs.\n  video_provider: \"youtube\"\n  video_id: \"rCLxORAKDWs\"\n\n- id: \"alberto-coln-viera-rocky-mountain-ruby-2024\"\n  title: \"From Zero to App with Bridgetown: The Rapid Prototyping Framework\"\n  raw_title: \"From Zero to App with Bridgetown: The Rapid Prototyping Framework by Alberto Colón Viera\"\n  speakers:\n    - Alberto Colón Viera\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-07\"\n  published_at: \"2024-11-06\"\n  description: |-\n    Have you ever struggled to communicate a complex user experience to a diverse team of engineers, designers, or product managers? Static mockups and design tools can only take you so far.\n\n    Join me to learn how you can use Bridgetown – the next-generation progressive site generator – as a rapid prototyping framework to solve these problems. I’ll show you how to harness Bridgetown’s Roda-powered server-side rendering capabilities to build fully functional prototypes that integrate with external APIs.\n\n    Whether you're an engineer looking to communicate your ideas more effectively, a product manager seeking to validate complex flows, or simply curious about Bridgetown's capabilities beyond static sites, this talk will inspire you to leverage this powerful tool for your next project.\n  video_provider: \"youtube\"\n  video_id: \"5Q0NtSWYI-s\"\n\n# Lunch\n\n- id: \"joel-hawksley-rocky-mountain-ruby-2024\"\n  title: \"How to make your application accessible (and keep it that way!)\"\n  raw_title: \"How to make your application accessible (and keep it that way!) by Joel Hawksley\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-07\"\n  published_at: \"2024-11-06\"\n  slides_url: \"https://hawksley.org/2024/05/07/how-to-make-your-app-accessible-and-keep-it-that-way.html\"\n  description: |-\n    Our industry is shockingly bad at accessibility: by some estimates, over 70% of websites are effectively unavailable to blind users! Making your app accessible isn’t just the right thing to do, it’s the law. In this talk, we’ll share what it’s taken to scale GitHub’s accessibility program and equip you to do the same at your company.\n  video_provider: \"youtube\"\n  video_id: \"9e2CsMMLf4U\"\n\n- id: \"craig-buchek-rocky-mountain-ruby-2024\"\n  title: \"Laziness is a Virtue: Lazy, Functional, Immutable Ruby\"\n  raw_title: \"Laziness is a Virtue: Lazy, Functional, Immutable Ruby by Craig Buchek\"\n  speakers:\n    - Craig Buchek\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-07\"\n  published_at: \"2024-11-06\"\n  slides_url: \"https://craigbuchek.com/laziness\"\n  description: |-\n    We can write Ruby code in any number of styles, but the community has some accepted norms. For example, almost nobody uses `for` loops any more. We've decided that some styles are \"better\" than others. And we can keep finding \"better\" styles.\n\n    In this talk, we'll dig into a more functional \"lazy\" style. Instead of setting up variables ahead of time, we'll call methods as needed. Instead of thinking about how to compute things, we'll think about properties of objects. This style has improved the readability of my code, and it will help you too.\n  video_provider: \"youtube\"\n  video_id: \"e_UxdfqaPAg\"\n\n# Break/Snacks\n\n- id: \"marco-roth-rocky-mountain-ruby-2024\"\n  title: \"Leveling Up Developer Tooling For The Modern Rails & Hotwire Era\"\n  raw_title: \"Leveling Up Developer Tooling For The Modern Rails & Hotwire Era by Marco Roth\"\n  speakers:\n    - Marco Roth\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-07\"\n  published_at: \"2024-11-06\"\n  slides_url: \"https://speakerdeck.com/marcoroth/developer-tooling-for-the-modern-rails-and-hotwire-era-at-rocky-mountain-ruby-2024-boulder-co\"\n  description: |-\n    The evolution of developer experience (DX) tooling has been a game-changer in how we build, debug, and enhance web applications.\n\n    This talk aims to illuminate the path toward enriching the Ruby on Rails ecosystem with advanced DX tools, focusing on the implementation of Language Server Protocols (LSP) for Stimulus and Turbo.\n\n    Drawing inspiration from the rapid advancements in JavaScript tooling, we explore the horizon of possibilities for Rails developers, including how advanced browser extensions and tools specifically designed for the Hotwire ecosystem can level up your developer experience.\n  video_provider: \"youtube\"\n  video_id: \"hKaIN-n1B-A\"\n\n- id: \"irina-nazarova-rocky-mountain-ruby-2024\"\n  title: \"Evolution of real-time, AnyCable Pro and... me\"\n  raw_title: \"Evolution of Real-Time and AnyCable Pro and ... me by Irina Nazarova\"\n  speakers:\n    - Irina Nazarova\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-07\"\n  published_at: \"2024-11-06\"\n  slides_url: \"https://speakerdeck.com/irinanazarova/evolution-of-realtime-and-anycable-pro-rocky-mountain-ruby-2024-irina-nazarova\"\n  description: |-\n    When we launched AnyCable Pro at Evil Martians in 2021, our goal was to simplify real-time functionality for all Rails developers while making it commercially successful for our company. We aimed to build what people wanted and saw their priorities shift from GraphQL to Hotwire, from chats to collaboration, and to AI-powered voice apps. Initially focused on performance, we soon tackled WebSocket reliability and developer productivity, culminating in the launch of Managed AnyCable earlier this year. Our journey, fueled by consulting revenue, is not without valuable insights. Let’s reflect on our story, share our learnings, and glimpse into the future of AnyCable and real-time applications.\n  video_provider: \"youtube\"\n  video_id: \"7WJFTvgnmWA\"\n\n# Wrap up\n\n## Day 2 - Tuesday, October 8, 2024\n\n# Breakfast\n\n# Welcome\n\n- id: \"andrei-bondarev-rocky-mountain-ruby-2024\"\n  title: \"Building AI Agents in Ruby\"\n  raw_title: \"Building AI Agents in Ruby by Andrei Bondarev\"\n  speakers:\n    - Andrei Bondarev\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-08\"\n  published_at: \"2024-11-06\"\n  slides_url: \"https://speakerdeck.com/andreibondarev/building-ai-agents-in-ruby\"\n  description: |-\n    The Coatue AI report is putting AI models at the centerpiece of all modern tech stacks going forward that Application Devs will be using to build on top of. It would not be controversial to say that the Ruby ecosystem lacks in its support and adoption of AI, ML and DS libraries. If we’d like to stay relevant in the future, we need to start building the foundations now. We’ll look at what Generative AI is, what kind of applications developers in other communities are building and how Ruby can be used to build similar applications today. We’ll cover Retrieval Augmented Generation (RAG), vector embeddings and semantic search, prompt engineering, and what the state of art (SOTA) in evaluating LLM output looks like today. We will also cover AI Agents, semi-autonomous general purpose LLM-backed applications, and what they’re capable of today. We'll make a case why Ruby is a great language to build these applications because of its strengths and its incredible ecosystem. After the slides, we'll build an AI Agent in 15 min.\n\n    Demo: https://github.com/patterns-ai-core/ecommerce-ai-assistant-demo\n  video_provider: \"youtube\"\n  video_id: \"dRBJxshD05E\"\n  additional_resources:\n    - name: \"patterns-ai-core/ecommerce-ai-assistant-demo\"\n      type: \"repo\"\n      url: \"https://github.com/patterns-ai-core/ecommerce-ai-assistant-demo\"\n\n- id: \"jeff-cohen-rocky-mountain-ruby-2024\"\n  title: \"Closing the Gap: How to Leap from Bootcamp to Job\"\n  raw_title: \"Closing the Gap: How to Leap from Bootcamp to Job by Jeff Cohen\"\n  speakers:\n    - Jeff Cohen\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-08\"\n  published_at: \"2024-11-06\"\n  slides_url: \"https://www.purpleworkshops.com/closing-the-gap\"\n  description: |-\n    Been to a bootcamp but still trying to land that first real job? Perhaps you've landed an apprenticeship or entry-level job but anxious to move up?\n\n    Or perhaps you lead a team and wish you knew how to acclimate junior developers seamlessly into your organization?\n\n    This session is geared for you.\n\n    Bootcamps can be helpful as a place to start, but there's always a gap between a bootcamp skillset and the skills required for a real job as a Ruby developer.\n\n    In this talk, I'll lay out a practical guide to acquiring the skills and knowledge you'll need to get your foot into the industry or reach that next rung on your career ladder.\n\n    I'll cover the areas of computer science most applicable to beginning Ruby programmers, highlight top programming skills that most bootcamps won't cover, and tactics for finding a position that suits you the best.\n\n    I'll also cover the top three things every senior developer should keep in mind when hiring, training, and mentoring new developers.\n\n    Along the way, we'll learn about this history of the Ruby community and tackle the most important skill of all: to learn how to learn more.\n  video_provider: \"youtube\"\n  video_id: \"y7bWhCiHZSs\"\n\n# Break\n\n- id: \"liz-heym-rocky-mountain-ruby-2024\"\n  title: \"Catching Waves with Time-Series Data\"\n  raw_title: \"Catching Waves with Time-Series Data by Liz Heym\"\n  speakers:\n    - Liz Heym\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-08\"\n  published_at: \"2024-11-06\"\n  description: |-\n    Time-series data is remarkably common, with applications ranging from IoT to finance. Effectively storing, reading, and presenting this time-series data can be as finicky as catching the perfect wave.\n\n    In order to understand the best-practices of time-series data, we’ll follow a surfer’s journey as she attempts to record every wave she’s ever caught. We’ll discover how to structure the time-series data, query for performant access, aggregate data over timespans, and present the data via an API endpoint. Surf’s up!\n\n    Paper: https://meraki.cisco.com/lib/pdf/trust/lt-paper.pdf\n  video_provider: \"youtube\"\n  video_id: \"_KBnYcM5pCE\"\n\n- id: \"allison-mcmillan-rocky-mountain-ruby-2024\"\n  title: \"Beyond Code: Crafting effective discussions to further technical decision-making\"\n  raw_title: \"Beyond Code: Crafting effective discussions to further technical decision-making by Allison McMillan\"\n  speakers:\n    - Allison McMillan\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-08\"\n  published_at: \"2024-11-06\"\n  slides_url: \"https://speakerdeck.com/asheren/effective-discussions-for-technical-decision-making\"\n  description: |-\n    Whiteboards. Proof of Concepts. Pairing. Spikes. These are all tools we use every day to have high-level technical conversations about ideas we propose or approaches we think are the “right” way. As someone advances in their career into more experienced levels of software engineering, however, a critical skill becomes how you conduct and lead these conversations. It involves clearly articulating a vision and securing buy-in, while also valuing and integrating the diverse perspectives and feedback from your peers. The goal beyond each individual conversation is to foster an environment where ideas can be exchanged, discussed, enhanced, and decided on. You’ll walk away from this talk with some new, innovative approaches to try out that not only help get your technical ideas across but also solicit additional thoughts and opinions in ways that engage and effectively address different points of view.\n  video_provider: \"youtube\"\n  video_id: \"uPK_rM8-bNI\"\n\n# Lunch\n\n- id: \"lightning-talks-rocky-mountain-ruby-2024\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-08\"\n  published_at: \"2024-11-06\"\n  description: |-\n    Rocky Mountain Ruby 2024\n  video_provider: \"youtube\"\n  video_id: \"Rq9EHxPh3ZE\"\n  talks:\n    - title: \"Lightning Talk: Rails Oracle to Postgres w/ Marshal & Avro\"\n      date: \"2024-10-08\"\n      start_cue: \"00:13\"\n      end_cue: \"03:47\"\n      video_provider: \"parent\"\n      id: \"cosmo-martinez-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"cosmo-martinez-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Cosmo Martinez\n\n    - title: \"Lightning Talk: Nothing New Under the Sun\"\n      date: \"2024-10-08\"\n      start_cue: \"03:47\"\n      end_cue: \"08:54\"\n      video_provider: \"parent\"\n      id: \"jim-remsik-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"jim-remsik-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Jim Remsik\n\n    - title: \"Lightning Talk: VIA\"\n      date: \"2024-10-08\"\n      start_cue: \"08:54\"\n      end_cue: \"14:08\"\n      video_provider: \"parent\"\n      id: \"will-carey-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"will-carey-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Will Carey\n\n    - title: \"Lightning Talk: Dapper Ruby\"\n      date: \"2024-10-08\"\n      start_cue: \"14:08\"\n      end_cue: \"16:47\"\n      video_provider: \"parent\"\n      id: \"tjv-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"tjv-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - TjV\n\n    - title: \"Lightning Talk: Linting Docs with JSON & Ruby\"\n      date: \"2024-10-08\"\n      start_cue: \"16:47\"\n      end_cue: \"20:20\"\n      video_provider: \"parent\"\n      id: \"dan-moore-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"dan-moore-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Dan Moore\n\n    - title: \"Lightning Talk: Turbo Morphing - Making the Jump\"\n      date: \"2024-10-08\"\n      start_cue: \"20:20\"\n      end_cue: \"25:08\"\n      video_provider: \"parent\"\n      id: \"ron-shinall-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"ron-shinall-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Ron Shinall\n\n    - title: \"Lightning Talk: WAXX - Web Application X(x) & Functional Ruby\"\n      date: \"2024-10-08\"\n      start_cue: \"25:08\"\n      end_cue: \"29:00\"\n      video_provider: \"parent\"\n      id: \"dan-fitzpatrick-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"dan-fitzpatrick-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Dan Fitzpatrick\n\n    - title: \"Lightning Talk: PR's as children\"\n      date: \"2024-10-08\"\n      start_cue: \"29:00\"\n      end_cue: \"34:04\"\n      video_provider: \"parent\"\n      id: \"ryan-stemmle-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"ryan-stemmle-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Ryan Stemmle\n\n    - title: \"Lightning Talk: Rails & Docker Development - Basic Containerization for Development w/ Compose\"\n      date: \"2024-10-08\"\n      start_cue: \"34:04\"\n      end_cue: \"38:04\"\n      video_provider: \"parent\"\n      id: \"davis-weimer-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"davis-weimer-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Davis Weimer\n\n    - title: \"Lightning Talk: Refactor Legacy Code\"\n      date: \"2024-10-08\"\n      start_cue: \"38:04\"\n      end_cue: \"41:44\"\n      video_provider: \"parent\"\n      id: \"bekki-freeman-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"bekki-freeman-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Bekki Freeman\n\n    - title: \"Lightning Talk: Confreaks Started because of Ruby =)\"\n      date: \"2024-10-08\"\n      start_cue: \"41:44\"\n      end_cue: \"47:35\"\n      video_provider: \"parent\"\n      id: \"cindy-backman-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"cindy-backman-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Cindy Backman\n\n    - title: \"Lightning Talk: The Gardener's Reward\"\n      date: \"2024-10-08\"\n      start_cue: \"47:35\"\n      end_cue: \"51:16\"\n      video_provider: \"parent\"\n      id: \"alan-ridlehoover-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"alan-ridlehoover-lighting-talk-rocky-mountain-ruby-2024\"\n      slides_url: \"https://speakerdeck.com/aridlehoover/rocky-mountain-ruby-2024-a-gardeners-reward\"\n      speakers:\n        - Alan Ridlehoover\n\n    - title: \"Lightning Talk: Things That Do Stuff\"\n      date: \"2024-10-08\"\n      start_cue: \"51:16\"\n      end_cue: \"56:05\"\n      video_provider: \"parent\"\n      id: \"erie-mueller-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"erie-mueller-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Erie Mueller\n\n    - title: \"Lightning Talk: Once upon a time in the Ruby ecosystem\"\n      date: \"2024-10-08\"\n      start_cue: \"56:05\"\n      end_cue: \"1:00:42\"\n      video_provider: \"parent\"\n      id: \"ben-oakes-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"ben-oakes-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Ben Oakes\n\n    - title: \"Lightning Talk: Working as a Civic Technologist\"\n      date: \"2024-10-08\"\n      start_cue: \"1:00:42\"\n      end_cue: \"1:05:54\"\n      video_provider: \"parent\"\n      id: \"alberto-colon-viera-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"alberto-colon-viera-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Alberto Colón Viera\n\n    - title: \"Lightning Talk: How to shoot yourself in the foot with ActiveRecord\"\n      date: \"2024-10-08\"\n      start_cue: \"1:05:54\"\n      end_cue: \"1:11:08\"\n      video_provider: \"parent\"\n      id: \"warren-lyndes-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"warren-lyndes-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Warren Lyndes\n\n    - title: \"Lightning Talk: Yscape\"\n      date: \"2024-10-08\"\n      start_cue: \"1:11:08\"\n      end_cue: \"1:14:40\"\n      video_provider: \"parent\"\n      id: \"jason-nochlin-lighting-talk-rocky-mountain-ruby-2024\"\n      video_id: \"jason-nochlin-lighting-talk-rocky-mountain-ruby-2024\"\n      speakers:\n        - Jason Nochlin\n\n# Break/Snack\n\n- id: \"cody-norman-rocky-mountain-ruby-2024\"\n  title: \"Attraction Mailbox - Why I love Action Mailbox\"\n  raw_title: \"Attraction Mailbox - Why I love Action Mailbox by Cody Norman\"\n  speakers:\n    - Cody Norman\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-08\"\n  published_at: \"2024-11-06\"\n  slides_url: \"https://speakerdeck.com/codynorman/rocky-mountian-ruby-2024\"\n  description: |-\n    Email is a powerful and flexible way to extend the capabilities of your Rails application. It’s a familiar and low friction way for users to interact with your app.\n\n    As much as you may want your users to access your app, they may not need to. Email is a great example of focusing on the problem at hand instead of an over-complicated solution.\n\n    We’ll take a deeper look at Action Mailbox and how to route and process your inbound emails.\n  video_provider: \"youtube\"\n  video_id: \"t4RwECVtZ3E\"\n\n- id: \"spike-ilacqua-rocky-mountain-ruby-2024-game-show-and-closing-remarks\"\n  title: \"Game Show and Closing Remarks\"\n  raw_title: \"Game Show and Closing Remarks with Spike Ilacqua and Bekki Freeman\"\n  speakers:\n    - Spike Ilacqua\n    - Bekki Freeman\n  event_name: \"Rocky Mountain Ruby 2024\"\n  date: \"2024-10-08\"\n  published_at: \"2024-11-06\"\n  description: |-\n    Game Show and Closing Remarks with Spike Ilacqua and Bekki Freeman\n  video_provider: \"youtube\"\n  video_id: \"YK-fnF-CNxc\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2025/cfp.yml",
    "content": "---\n- link: \"https://sessionize.com/rocky-mountain-ruby-2025/\"\n  open_date: \"2025-05-30\"\n  close_date: \"2025-06-30\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2025/event.yml",
    "content": "---\nid: \"rocky-mountain-ruby-2025\"\ntitle: \"Rocky Mountain Ruby 2025\"\ndescription: |-\n  A two day, single track conference in the heart of Boulder, Colorado.\nlocation: \"Boulder, CO, United States\"\nkind: \"conference\"\nstart_date: \"2025-10-06\"\nend_date: \"2025-10-07\"\npublished_at: \"2025-10-26\"\nwebsite: \"https://rockymtnruby.dev\"\nmastodon: \"https://ruby.social/@rockymtnruby\"\nbanner_background: \"linear-gradient(180deg,#998aff,#ffebe5 95%)\"\nfeatured_background: \"#100747\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 40.0201669\n  longitude: -105.275401\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2025/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 1\"\n    date: \"2025-10-06\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Check-in/Breakfast\n\n      - start_time: \"09:00\"\n        end_time: \"09:10\"\n        slots: 1\n\n      - start_time: \"09:10\"\n        end_time: \"09:55\"\n        slots: 1\n\n      - start_time: \"09:55\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:35\"\n        slots: 1\n\n      - start_time: \"11:35\"\n        end_time: \"12:10\"\n        slots: 1\n\n      - start_time: \"12:10\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Open Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:35\"\n        slots: 1\n\n      - start_time: \"14:35\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:40\"\n        end_time: \"16:15\"\n        slots: 1\n\n      - start_time: \"16:15\"\n        end_time: \"16:50\"\n        slots: 1\n\n      - start_time: \"16:50\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Wrap Up\n\n      - start_time: \"17:30\"\n        end_time: \"19:30\"\n        slots: 1\n        items:\n          - Sponsored Happy Hour\n\n  - name: \"Day 2\"\n    date: \"2025-10-07\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Breakfast\n\n      - start_time: \"09:00\"\n        end_time: \"09:10\"\n        slots: 1\n\n      - start_time: \"09:10\"\n        end_time: \"09:45\"\n        slots: 1\n\n      - start_time: \"09:45\"\n        end_time: \"10:20\"\n        slots: 1\n\n      - start_time: \"10:20\"\n        end_time: \"10:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:50\"\n        end_time: \"11:25\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Open Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:15\"\n        end_time: \"16:15\"\n        slots: 1\n\n      - start_time: \"16:15\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:30\"\n        end_time: \"17:30\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"17:35\"\n        slots: 1\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsors\"\n      description: |-\n        Highest sponsorship level with $8,000 price. Includes recognition in conference opening and closing, logo on site-wide footer, top position on Sponsor Page, logo on all videos (if funding goal reached), LinkedIn and Mastodon promotion, 8 complimentary conference tickets, 2 job ads on conference website, 6' table sponsor space in the Café & Bar at eTown Hall, sponsored email to conference attendees, and sponsor description on home page.\n      level: 1\n      sponsors:\n        - name: \"Cisco\"\n          website: \"https://meraki.cisco.com/\"\n          slug: \"cisco\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/Cisco_Color.svg\"\n\n    - name: \"Sapphire Sponsors\"\n      description: |-\n        Mid-level sponsorship with $4,000 price. Includes recognition in conference opening and closing, logo on site-wide footer, middle position on Sponsor Page, logo on all videos (if funding goal reached), LinkedIn and Mastodon promotion, 4 complimentary conference tickets, 1 job ad on conference website, shared 6' table sponsor space in the Café & Bar at eTown Hall.\n      level: 2\n      sponsors:\n        - name: \"Gusto\"\n          website: \"https://gusto.com\"\n          slug: \"gusto\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/Gusto_logo_color.svg\"\n\n        - name: \"Caribou\"\n          website: \"https://caribou.com/\"\n          slug: \"caribou\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/Caribou_Color.svg\"\n\n    - name: \"Emerald Sponsors\"\n      description: |-\n        Entry-level sponsorship with $2,000 price. Includes recognition in conference opening and closing, logo on site-wide footer, bottom position on Sponsor Page, logo on all videos (if funding goal reached), LinkedIn and Mastodon promotion, 2 complimentary conference tickets.\n      level: 3\n      sponsors:\n        - name: \"TypeSense\"\n          website: \"https://typesense.org\"\n          slug: \"typesense\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/typesense_logo.svg\"\n\n        - name: \"Checkr\"\n          website: \"https://checkr.com\"\n          slug: \"checkr\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/Checkr_Aqua.svg\"\n\n    - name: \"Community Sponsors\"\n      description: |-\n        Community Sponsors\n      level: 4\n      sponsors:\n        - name: \"Flagrant\"\n          website: \"https://www.beflagrant.com/\"\n          slug: \"flagrant\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/FlagrantLogo_Color.svg\"\n\n        - name: \"Avo\"\n          website: \"https://avohq.io/\"\n          slug: \"avo\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/AvoHQ-logo-colored.png\"\n\n        - name: \"Recurly\"\n          website: \"https://recurly.com/\"\n          slug: \"recurly\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/Recurly_Brandmark_Yellow.png\"\n\n    - name: \"Podcast Sponsors\"\n      description: |-\n        Podcast Sponsors\n      level: 5\n      sponsors:\n        - name: \"The Bike Shed\"\n          website: \"https://www.bikeshed.fm/\"\n          slug: \"the-bike-shed\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/the-bike-shed.png\"\n\n        - name: \"Code and the Coding Coders who Code it\"\n          website: \"https://podcast.drbragg.dev/\"\n          slug: \"code-and-the-coding-coders-who-code-it\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/code-and-the-coding-coders-who-code-it.png\"\n\n        - name: \"Remote Ruby\"\n          website: \"https://www.remoteruby.com\"\n          slug: \"remote-ruby\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/remote-ruby.jpeg\"\n\n        - name: \"The Ruby Gems Podcast\"\n          website: \"https://www.buzzsprout.com/2509083\"\n          slug: \"the-ruby-gems-podcast\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/Ruby-Gems-Podcast.jpeg\"\n\n    - name: \"Travel Sponsors\"\n      description: |-\n        Travel Sponsors\n      level: 6\n      sponsors:\n        - name: \"BetaCraft Technologies\"\n          website: \"https://betacraft.com/\"\n          slug: \"betacraft-technologies\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/BetaCraft-Technologies.png\"\n\n        - name: \"Podia\"\n          website: \"https://podia.com\"\n          slug: \"podia\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/podia-transparent.svg\"\n\n        - name: \"Spinel Cooperative\"\n          website: \"https://spinel.coop/\"\n          slug: \"spinel-cooperative\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/Spinel-Cooperative.svg\"\n\n        - name: \"SOFware\"\n          website: \"https://sofwarellc.com/\"\n          slug: \"sofware\"\n          logo_url: \"https://rockymtnruby.dev/images/sponsors/SOFware.png\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2025/venue.yml",
    "content": "---\nname: \"eTown Hall\"\n\naddress:\n  street: \"1535 Spruce Street\"\n  city: \"Boulder\"\n  region: \"Colorado\"\n  postal_code: \"80302\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"1535 Spruce St, Boulder, CO 80302, USA\"\n\ncoordinates:\n  latitude: 40.0201669\n  longitude: -105.275401\n\nmaps:\n  google: \"https://maps.google.com/?q=eTown+Hall,40.0201669,-105.275401\"\n  apple: \"https://maps.apple.com/?q=eTown+Hall&ll=40.0201669,-105.275401\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=40.0201669&mlon=-105.275401\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2025/videos.yml",
    "content": "# Website: https://rockymtnruby.dev\n---\n## Day 1\n\n- title: \"Opening Remarks, Monday\"\n  raw_title: \"Rocky Mountain Ruby 2025 Opening Remarks with Spike and Bekki\"\n  speakers:\n    - Spike Ilacqua\n    - Bekki Freeman\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-06\"\n  published_at: \"2025-10-22\"\n  language: \"en\"\n  description: |-\n    Rocky Mountain Ruby 2025 Opening Remarks with Spike and Bekki\n  video_provider: \"youtube\"\n  video_id: \"eK0YK5y4fOo\"\n  id: \"rocky-mountain-ruby-2025-opening-remarks-monday\"\n\n- title: \"Keynote: We Who Remember Magic\"\n  raw_title: \"Rocky Mountain Ruby 2025 - We Who Remember Magic by Brandon Weaver\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-06\"\n  published_at: \"2025-10-22\"\n  language: \"en\"\n  description: |-\n    There was a time when Ruby felt like magic. It gave an entire generation of developers wings; tools to ship fast, dream big, and start companies from anywhere. It wasn't just code; it was a movement built on empathy, simplicity, and joy. Ruby taught us that developer happiness wasn't a luxury; it was a revolution.\n\n    Now, a new kind of magic is emerging: AI. It's promising, powerful, and most importantly it's perilous. As the world rushes to automate, optimize, and amplify, we in the Ruby community have a chance to pause and ask better questions—not just *can we*, but *should we*?\n\n    This talk isn't a demo reel. It's a conversation about responsibility, creativity, and care. About how we bring our whole selves to this moment, with wonder and with skepticism. We'll reflect on what AI means not just for our tools, but for our teams, our values, and the future we're quietly writing together.\n\n    Ruby taught us to be kind and to focus on people over technology, and that lesson is more important today than ever.\n  video_provider: \"youtube\"\n  video_id: \"IQQtnttsI5A\"\n  id: \"brandon-weaver-rocky-mountain-ruby-2025-keynote\"\n\n- title: \"Learning Empathy From Pokémon Blue\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Learning Empathy From Pokémon Blue by Tess Griffin\"\n  speakers:\n    - Tess Griffin\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-06\"\n  published_at: \"2025-10-22\"\n  language: \"en\"\n  description: |-\n    Have you ever looked at a bug and wondered why it actually happens? It's easy to chalk it up to sloppy coding, but that's almost never the case.\n\n    In this talk, we'll be dissecting an exploit from Pokémon Blue known as the \"Missingno\" glitch. We'll explore the details of each seemingly random bug behind this exploit, examining why these bugs occurred and what lessons we can apply to our Ruby code almost 30 years later.\n\n    If you've never played or even heard of Pokémon, that's ok! As long as you're interested in a deep dive into a fascinating set of bugs, this talk is for you.\n  video_provider: \"youtube\"\n  video_id: \"rUDVsDJG088\"\n  id: \"tess-griffin-rocky-mountain-ruby-2025\"\n\n- title: \"Lessons from 5 years of UI architecture at GitHub\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Lessons from 5 years of UI architecture at GitHub by Joel Hawksley\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-06\"\n  published_at: \"2025-10-23\"\n  language: \"en\"\n  description: |-\n    A reflection on lessons from five years of UI architecture at GitHub, focusing on three lessons: native is the new baseline, design systems are victims of their own success, and frontend costs 10x backend.\n  video_provider: \"youtube\"\n  video_id: \"4ck9ZUXwuio\"\n  id: \"joel-hawksley-rocky-mountain-ruby-2025\"\n\n- title: \"Sidekiq at Gusto: The Parts Where People's Jaw Drops\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Sidekiq at Gusto: The Parts Where People's Jaw Drops by Phillip Campbell\"\n  speakers:\n    - Phillip Campbell\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-06\"\n  published_at: \"2025-10-23\"\n  language: \"en\"\n  description: |-\n    At Gusto, we run over 100 million Sidekiq jobs a day across a complex Rails ecosystem and every time I explain how it works, someone's jaw drops. This talk is a tour through the most surprising, \"wait, seriously?\" parts of how we scale background jobs to support 600+ engineers and millions of users.\n\n    We'll cover real patterns we've built around queue SLAs, autoscaling, Redis usage, job repair, and how we package Sidekiq infrastructure into gems used across all our apps. Along the way, I'll share the gotchas, hacks, and lessons learned from scaling async workloads way past the comfort zone.\n\n    Whether you're running Sidekiq at scale or just curious how far you can push it, this talk will leave you laughing, wincing, and maybe rethinking your retry settings.\n  video_provider: \"youtube\"\n  video_id: \"aY_yKeZYzko\"\n  id: \"phillip-campbell-rocky-mountain-ruby-2025\"\n\n- title: \"Ruby on Rails is a Game Engine\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Ruby on Rails is a Game Engine by Jonathan Woodard\"\n  speakers:\n    - Jonathan Woodard\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-06\"\n  published_at: \"2025-10-23\"\n  language: \"en\"\n  description: |-\n    Developing a turn-based web MMO using Ruby on Rails has led me through some outrageous corners of the framework's capabilities, plus required building a few fun hacks and some HTML tricks I've never seen anywhere else.\n\n    My game, Galactic Impact [https://www.galacticimpact.com], is styled on 90s \"Space Empire 4X\" games: \"Master of Orion\", \"Pax Imperia\", and their ilk. It invites Users to command a fleet of ships across a two-dimensional map of stars to explore, populate, and develop worlds, while engaging in diplomacy or hostilities with other players.\n\n    To power \"game-like\" user experience expectations, here are a few places I've left the beaten path of standard CRUD Apps, where Rails has cheerfully followed, often with very little hackery:\n    • Extensive use of dynamic svg, both as an ActionController return format, but also setting svg elements as StimulusJS controller targets (for an application-wide PickWhip…??)\n    • Storing YAML serialization of Units before and after 'combat' situations combined with Rails' built-in attribute dirty tracking to display after-action reports.\n    • Sidekiq 'batching' to manage game-turn resolution sequencing for game mechanics while also parallelizing for speed.\n    • A blend of integer and uuid PKs from Model to Model to distinguish and manage internal system objects v. Player-generated objects.\n    • The 'new hotness' tools applied in several ways: multiple turbo-streams in form/REST responses to make snappy UI changes as a player impacts game state; lazy turbo-frames inside details/summary blocks.\n    • PostGIS! Geometry-based DB for efficiently querying for ranges of Units on a 2d map.\n    • Many more… (modular \"Behavior\" mechanism! Polymorphic \"user-feature unlocking\"! Redis tricks to protect existing user state during update while not blocking new user signup!)\n\n    In this talk, we'll take a journey exploring how a series of game-oriented \"Product Needs\" led to each \"Unexpected, but still Railsy, solution\". Hopefully you'll leave with a newfound appreciation for Rails' flexibility, and if you've ever been interested in developing games, maybe it will inspire you to build with the tools you already know, instead of needing to learn another entire toolchain to bring something to life.\n  video_provider: \"youtube\"\n  video_id: \"-HkSk1VhuSE\"\n  id: \"jonathan-woodard-rocky-mountain-ruby-2025\"\n\n- title: \"The Mutation Game: Cracking the Enigma of Mutation Testing\"\n  raw_title: \"Rocky Mountain Ruby 2025 - The Mutation Game: Cracking the Enigma of Mutation Testing by Tyler Lemburg\"\n  speakers:\n    - Tyler Lemburg\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-06\"\n  published_at: \"2025-10-24\"\n  language: \"en\"\n  description: |-\n    Can your application's Ruby code achieve complete perfection? If you join Professor X's School for Gifted Mutation Testers, it can get pretty dang close. Discover the Mystique of transforming your code in silly (and not-so-silly) ways, and seeing if this makes your tests fail. If your tests do fail, they are solid as a Colossus! If your tests passed, then you have discovered a Rogue mutant! But do not worry: I will teach you the ins and outs of squashing that mutant like a Blob and making your code stronger than Wolverine.\n\n    Storm into this session and learn what mutation testing is all about, see if it may be right for your Ruby codebase, and explore the tools that make it possible. We will use the `mutant` gem and delve into an example Ruby app and bring it to full mutation testing coverage through simplifying code and improving tests. Even if this technique is not right for your project, you will come away from this session with a deeper understanding of Ruby, code parsing, test-driven development, and writing clean, beautiful code.\n  video_provider: \"youtube\"\n  video_id: \"sFgRNMt_VQM\"\n  id: \"tyler-lemburg-rocky-mountain-ruby-2025\"\n\n- title: \"Reading Rails: A Visual Walkthrough of the Source Code\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Reading Rails: A Visual Walkthrough of the Source Code by Ratnadeep Deshmane\"\n  speakers:\n    - Ratnadeep Deshmane\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-06\"\n  published_at: \"2025-10-24\"\n  language: \"en\"\n  description: |-\n    Want to contribute to Rails or simply understand its internals without getting lost in the vast codebase? This talk, provides a guided tour into the Rails source code. We'll visually map key components (like Active Record, Action Pack) and explore how they are connected, offering practical starting points for navigating the code yourself. Learn how major framework pieces interact by looking at relevant source snippets (explained clearly, no deep dives required). Build a strong mental model, enhance your debugging skills, and gain the confidence to explore the Rails source. Aimed at Rails devs ready to look under the hood. Finally, we'll touch upon how modern AI assistants can supplement your exploration, helping to navigate and summarize complex sections of the Rails source code.\n  video_provider: \"youtube\"\n  video_id: \"F7UB3zZGqbA\"\n  id: \"ratnadeep-deshmane-rocky-mountain-ruby-2025\"\n\n- title: \"We Were Voyagers. We Can Voyage Again!\"\n  raw_title: \"Rocky Mountain Ruby 2025 - We Were Voyagers. We Can Voyage Again! by Scott Werner\"\n  speakers:\n    - Scott Werner\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-06\"\n  published_at: \"2025-10-24\"\n  language: \"en\"\n  description: |-\n    Do you remember Ruby's \"Golden Age\"? The era of why the lucky stiff, when frameworks like Camping and Sinatra felt like artistic expressions, and every week brought a new, delightful experiment. Ruby was the language of developer happiness, defined by a magical duality: rock-solid productivity on one hand, and playful, creative exploration on the other.\n\n    In our collective journey to maturity, building stable, mission-critical applications, has some of that original spark been lost? Have we become so focused on the practical that we've forgotten the \"kind of silly\"?\n\n    This talk argues that the rise of Generative AI isn't just a new wave of productivity tools; it's a chance to reclaim our heritage as voyagers. It's an opportunity to bring back the magic, the art, and the sheer fun of creation.\n  video_provider: \"youtube\"\n  video_id: \"0Wmaunyx3tQ\"\n  id: \"scott-werner-rocky-mountain-ruby-2025\"\n\n## Day 2\n\n- title: \"Opening Remarks, Tuesday\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Opening Remarks, Tuesday with Bekki and Spike\"\n  speakers:\n    - Bekki Freeman\n    - Spike Ilacqua\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-07\"\n  published_at: \"2025-10-25\"\n  language: \"en\"\n  description: |-\n    Rocky Mountain Ruby 2025 Opening Remarks, Tuesday with Bekki and Spike\n  video_provider: \"youtube\"\n  video_id: \"vAw19VzzhnY\"\n  id: \"rocky-mountain-ruby-2025-opening-remarks-tuesday\"\n\n- title: \"Learning How to Learn: A Framework for Lifelong Rubyists\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Learning How to Learn: A Framework for Lifelong Rubyists by Jeff Cohen\"\n  speakers:\n    - Jeff Cohen\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-07\"\n  published_at: \"2025-10-25\"\n  language: \"en\"\n  description: |-\n    If you've ever felt overwhelmed by how much there is to learn in software—or frustrated that something just isn't clicking—this talk is for you. In 40 minutes, I'll share a practical framework for learning how to learn, developed through years of hands-on coding, mentoring, and formal teaching. You'll walk away with a set of ideas and practices to help you get better at getting better—no matter where you are in your career.\n\n    Software development is more than just coding: it's really about how to solve problems that appear in a variety of shapes and forms.\n\n    We'll start with a quick tour of 10 core learning principles, like \"Context is Everything,\" \"Spike to Learn, Build to Remember,\" and \"The Spiral Staircase.\" These aren't buzzwords—they're mental models that help you tackle unfamiliar codebases, debug faster, and retain what you study. Think of it as a way to organize your learning, so you spend less time spinning your wheels and more time leveling up.\n\n    Then we'll dig into a few specific practices you can try right away—like \"Tiny Steps\" to reduce cognitive load and build confidence, or \"Broken Code Puzzles\" to sharpen your skills through play and failure. These techniques are lightweight but powerful, and they work whether you're self-teaching a new gem or mentoring someone else.\n\n    This won't be a lecture on neuroscience nor a random grab-bag of tips. It's a coherent framework of ideas and examples that will help you learn more efficiently, stay curious, and grow sustainably in a field that never stops changing. You'll leave with both high-level insight and concrete tools you can use immediately.\n\n    Especially at a time where AI clickbait can cause fear and uncertainty, this talk will instill confidence we remain in control of our own destiny as professional developers.\n  video_provider: \"youtube\"\n  video_id: \"DIZvFMHr3dI\"\n  id: \"jeff-cohen-rocky-mountain-ruby-2025\"\n\n- title: \"Slicing and Dicing Through Complexity with Hanami\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Slicing and Dicing Through Complexity with Hanami by Sean Collins\"\n  speakers:\n    - Sean Collins\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-07\"\n  published_at: \"2025-10-25\"\n  language: \"en\"\n  description: |-\n    As a Rails app grows, complexity tends to scatter across loosely defined layers, leaking through porous boundaries. Hanami 2 is a flexible Ruby framework that helps you organize complexity with clear, intentional boundaries. At the core of its philosophy is a first-class concept called slices: optional, modular boundaries that let you organize your application by feature, not just by layer. Your billing logic can live in its own world, completely isolated from onboarding or authentication, yet still integrate cleanly through explicit, well-defined interfaces. Slices can even be deployed independently, making them a strong fit for scaling both teams and infrastructure.\n\n    Hanami chops up the traditional MVC stack into small, single-purpose layers. Each action gets its own class to handle parameters and orchestration with the rest of your system. Views are plain Ruby objects that prepare data for rendering, cleanly separated from templates. And the persistence layer, powered by ROM, encourages immutability and composability through simple data structs and repositories which access and modify data through relations.\n\n    The result is a framework that feels lightweight but powerful: one that lets you spend your days writing Ruby, with clear straightforward APIs. Hanami doesn't dictate architecture, it gives you the freedom and tools to structure your application as you see fit. The modular monolith is not a myth: it's just that the framework for building modular Ruby apps is Hanami, not Rails. With Hanami, you spend less time bending Rails to your architecture, and more time writing focused, testable Ruby.\n  video_provider: \"youtube\"\n  video_id: \"5-Ajpoq-5eE\"\n  id: \"sean-collins-rocky-mountain-ruby-2025\"\n\n- title: \"Learning to Code Without a Map: Mentorship and Entry Paths in the Post-Bootcamp Era\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Learning to Code Without a Map: Mentorship and Entry Paths in the Post-Bootcamp Era by Erin Pintozzi\"\n  speakers:\n    - Erin Pintozzi\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-07\"\n  published_at: \"2025-10-26\"\n  language: \"en\"\n  description: |-\n    Bootcamps once offered a fast, accessible path into tech—especially for career changers, people from nontraditional backgrounds, and folks historically excluded from the industry. As the industry shifts and many programs close or scale back, the landscape for learning and mentorship is changing fast. So where does that leave aspiring developers, and the folks trying to support them?\n\n    In this talk, we'll explore how the loss of bootcamps is reshaping the journey into software development—especially for those who relied on them to break in—and what's emerging in their place. We'll look at the evolving entry paths, how mentorship is adapting without a structured pipeline, and how the Ruby community can step up to fill the gaps. Whether you're a hiring manager, an engineer (aspiring or otherwise!), or someone who loves to mentor, you'll walk away with a clearer picture of what's working, what's missing, and how we can all build more sustainable, inclusive pathways into tech—bootcamp or no bootcamp.\n  video_provider: \"youtube\"\n  video_id: \"2XJX_vur37E\"\n  id: \"erin-pintozzi-rocky-mountain-ruby-2025\"\n\n- title: \"Thoughtful AI for the Rubyist\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Thoughtful AI for the Rubyist by Christine Seeman\"\n  speakers:\n    - Christine Seeman\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-07\"\n  published_at: \"2025-10-26\"\n  language: \"en\"\n  description: |-\n    As a Rubyist, you like to put intention into your code for a clear, readable, and inviting result, just like our MINASWAN community…so how can we bring that to AI? How can we get that intention while leveraging AI tools to create our Ruby solutions? Let's have a frank discussion about what can and can't help us with our coding and how, in the end, we have a better solution that allows us to work faster without losing that special spark that Ruby can have. This talk will discuss AI coding tools and prompts with purpose. The AI solution isn't always idiomatic ruby, so you know better what works for your codebase than the robots.\n  video_provider: \"youtube\"\n  video_id: \"hOdB4YGmp0s\"\n  id: \"christine-seeman-rocky-mountain-ruby-2025\"\n\n- title: \"Upgrading Rails: The Non-Technical Parts\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Upgrading Rails: The Non-Technical Parts by Max VelDink\"\n  speakers:\n    - Max VelDink\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-07\"\n  published_at: \"2025-10-26\"\n  language: \"en\"\n  description: |-\n    Upgrading Rails is often viewed through a technical lens, focusing on version changes, migration paths, and code refactoring. Numerous talks, guides, and videos dive into this process. However, how do you navigate the organizational complexity of accomplishing the upgrade, from buy-in to review cycles? What about the soft skills aspect of inspiring a team to accomplish what seems like a Herculean effort? In this talk, we will explore the non-technical aspects of upgrading Rails that are vital for success.\n\n    We will discuss the importance of stakeholder communication, ensuring all team members understand the reasons for the upgrade and its benefits. You'll hear strategies for managing team expectations and fostering a culture of collaboration and combined ownership. You'll even hear how to be more direct and lay out reasonable timelines for accomplishing the upgrade in weeks, not months.\n\n    Join us to unpack the often-overlooked elements of upgrading Rails. You'll leave with actionable insights to tackle the upgrade process holistically, ensuring that both your codebase and your team are ready for the future.\n  video_provider: \"youtube\"\n  video_id: \"YIBjSQ3FT-Y\"\n  id: \"max-veldink-rocky-mountain-ruby-2025\"\n\n- title: \"Operating Rails: what about after you deploy?\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Operating Rails: what about after you deploy? by André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-07\"\n  published_at: \"2025-10-27\"\n  language: \"en\"\n  description: |-\n    There are a million tutorials out there showing you how to build a blog in Rails (in just 15 minutes!) and how to deploy that Rails app to some cloud provider (in just 5 minutes!), but what about after that first half-hour? When the guide says \"this tutorial of course isn't production ready\", what actually is production-ready? Let's talk about operating Rails apps in production.\n\n    Running a web service requires you to do so many things that aren't included in any programming books or tutorials. We need more developers able to ship services that work, rather than expecting each developer to figure out the entire list by trial and error, one at a time, by themselves. This talk covers what you need for reliable services:\n    - what environments you should have, and how they work?\n    - how will you notice downtime or exceptions?\n    - how are you going to debug issues reported by users?\n    - for that matter, how are users going to report issues?\n    - how will you back up and restore your databases and files?\n    - are you ready to ship changes while preserving user data?\n    - even more important, how are you keeping user data secure?\n    - are you ready for hostile attention, with a plan for security incidents?\n    - preparing doesn't prevent downtime, but it can make the costs in time and reputation much smaller\n  video_provider: \"youtube\"\n  video_id: \"WP2fWUBPGfI\"\n  slides_url: \"https://speakerdeck.com/indirect/operating-rails-what-about-after-you-deploy\"\n  id: \"andre-arko-rocky-mountain-ruby-2025\"\n\n- title: \"Lightning Talks\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Lightning talks\"\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-07\"\n  published_at: \"2025-10-27\"\n  language: \"en\"\n  video_provider: \"youtube\"\n  video_id: \"tn-xv7XssbM\"\n  id: \"rocky-mountain-ruby-2025-lightning-talks\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Not Another AI Talk\"\n      start_cue: \"00:13\"\n      end_cue: \"04:04\"\n      thumbnail_cue: \"00:15\"\n      date: \"2025-10-07\"\n      published_at: \"2025-10-27\"\n      video_provider: \"parent\"\n      video_id: \"ted-tash-rocky-mountain-ruby-2025-lightning-talk\"\n      id: \"ted-tash-rocky-mountain-ruby-2025-lightning-talk\"\n      language: \"en\"\n      speakers:\n        - Ted Tash\n\n    - title: \"Lightning Talk: Your next Sr. Software Engineer works in support\"\n      start_cue: \"04:04\"\n      end_cue: \"08:05\"\n      thumbnail_cue: \"04:09\"\n      date: \"2025-10-07\"\n      published_at: \"2025-10-27\"\n      video_provider: \"parent\"\n      video_id: \"zack-mariscal-rocky-mountain-ruby-2025-lightning-talk\"\n      id: \"zack-mariscal-rocky-mountain-ruby-2025-lightning-talk\"\n      language: \"en\"\n      speakers:\n        - Zack Mariscal\n\n    - title: \"Lightning Talk: Know a Jujitsu\"\n      start_cue: \"08:05\"\n      end_cue: \"13:28\"\n      thumbnail_cue: \"08:11\"\n      date: \"2025-10-07\"\n      published_at: \"2025-10-27\"\n      video_provider: \"parent\"\n      video_id: \"nathan-witmer-rocky-mountain-ruby-2025-lightning-talk\"\n      id: \"nathan-witmer-rocky-mountain-ruby-2025-lightning-talk\"\n      language: \"en\"\n      speakers:\n        - Nathan Witmer\n\n    - title: \"Lightning Talk: Tidewave Web Demo\"\n      start_cue: \"13:28\"\n      end_cue: \"19:15\"\n      thumbnail_cue: \"13:43\"\n      date: \"2025-10-07\"\n      published_at: \"2025-10-27\"\n      video_provider: \"parent\"\n      video_id: \"don-barlow-rocky-mountain-ruby-2025-lightning-talk\"\n      id: \"don-barlow-rocky-mountain-ruby-2025-lightning-talk\"\n      language: \"en\"\n      speakers:\n        - Don Barlow\n\n    - title: \"Lightning Talk: rv - a ruby manager for the future\"\n      start_cue: \"19:15\"\n      end_cue: \"23:53\"\n      thumbnail_cue: \"19:20\"\n      date: \"2025-10-07\"\n      published_at: \"2025-10-27\"\n      video_provider: \"parent\"\n      video_id: \"andre-arko-rocky-mountain-ruby-2025-lightning-talk\"\n      id: \"andre-arko-rocky-mountain-ruby-2025-lightning-talk\"\n      language: \"en\"\n      speakers:\n        - André Arko\n\n    - title: \"Lightning Talk: Oh My Claude, What have I done\"\n      start_cue: \"23:53\"\n      end_cue: \"29:44\"\n      thumbnail_cue: \"23:57\"\n      date: \"2025-10-07\"\n      published_at: \"2025-10-27\"\n      video_provider: \"parent\"\n      video_id: \"travis-dockter-rocky-mountain-ruby-2025-lightning-talk\"\n      id: \"travis-dockter-rocky-mountain-ruby-2025-lightning-talk\"\n      language: \"en\"\n      speakers:\n        - Travis Dockter\n\n    - title: \"Lightning Talk: From Haskell to Ruby\"\n      start_cue: \"29:44\"\n      end_cue: \"35:06\"\n      thumbnail_cue: \"29:47\"\n      date: \"2025-10-07\"\n      published_at: \"2025-10-27\"\n      video_provider: \"parent\"\n      video_id: \"shawn-bachlet-rocky-mountain-ruby-2025-lightning-talk\"\n      id: \"shawn-bachlet-rocky-mountain-ruby-2025-lightning-talk\"\n      language: \"en\"\n      speakers:\n        - Shawn Bachlet\n\n    - title: \"Lightning Talk: The Other Side of Fear\"\n      start_cue: \"35:06\"\n      end_cue: \"39:53\"\n      thumbnail_cue: \"35:10\"\n      date: \"2025-10-07\"\n      published_at: \"2025-10-27\"\n      video_provider: \"parent\"\n      video_id: \"alan-ridlehoover-rocky-mountain-ruby-2025-lightning-talk\"\n      id: \"alan-ridlehoover-rocky-mountain-ruby-2025-lightning-talk\"\n      language: \"en\"\n      speakers:\n        - Alan Ridlehoover\n\n    - title: \"Lightning Talk: Temporal Ruby SDK\"\n      start_cue: \"39:53\"\n      end_cue: \"43:30\"\n      thumbnail_cue: \"40:12\"\n      date: \"2025-10-07\"\n      published_at: \"2025-10-27\"\n      video_provider: \"parent\"\n      video_id: \"jason-brown-rocky-mountain-ruby-2025-lightning-talk\"\n      id: \"jason-brown-rocky-mountain-ruby-2025-lightning-talk\"\n      language: \"en\"\n      speakers:\n        - Jason Brown\n\n- title: \"Keynote: Who Wants to be a Ruby Engineer?\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Who Wants to be a Ruby Engineer? with Drew Bragg\"\n  speakers:\n    - Drew Bragg\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-07\"\n  published_at: \"2025-10-27\"\n  language: \"en\"\n  description: |-\n    Welcome to the Ruby game show where contestants try to guess the output of a small bit of Ruby code. Sound easy? Here's the challenge: the snippets come from some of the weirdest parts of the Ruby language.\n  video_provider: \"youtube\"\n  video_id: \"IhKQ_BJ1x5Q\"\n  id: \"drew-bragg-rocky-mountain-ruby-2025-keynote\"\n\n- title: \"Closing Remarks\"\n  raw_title: \"Rocky Mountain Ruby 2025 - Closing Remarks with Spike and Bekki\"\n  speakers:\n    - Spike Ilacqua\n    - Bekki Freeman\n  event_name: \"Rocky Mountain Ruby 2025\"\n  date: \"2025-10-07\"\n  published_at: \"2025-10-27\"\n  language: \"en\"\n  description: |-\n    Rocky Mountain Ruby 2025 Closing Remarks with Spike and Bekki\n  video_provider: \"youtube\"\n  video_id: \"_Z-qo84zHOU\"\n  id: \"rocky-mountain-ruby-2025-closing-remarks\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2026/event.yml",
    "content": "---\nid: \"rocky-mountain-ruby-2026\"\ntitle: \"Rocky Mountain Ruby 2026\"\ndescription: |-\n  A two day, single track conference in the heart of Boulder, Colorado.\nlocation: \"Boulder, CO, United States\"\nkind: \"conference\"\nstart_date: \"2026-09-28\"\nend_date: \"2026-09-29\"\nyear: 2026\nwebsite: \"https://rockymtnruby.dev\"\nmastodon: \"https://ruby.social/@rockymtnruby\"\nbanner_background: \"linear-gradient(180deg,#998aff,#ffebe5 95%)\"\nfeatured_background: \"#100747\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 40.0201669\n  longitude: -105.275401\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2026/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsors\"\n      description: |-\n        Highest sponsorship level with $8,000 price. Includes recognition in conference opening and closing, logo on site-wide footer, top position on Sponsor Page, logo on all videos (if funding goal reached), LinkedIn and Mastodon promotion, 8 complimentary conference tickets, 2 job ads on conference website, 6' table sponsor space in the Café & Bar at eTown Hall, sponsored email to conference attendees, and sponsor description on home page.\n      level: 1\n      sponsors: []\n\n    - name: \"Sapphire Sponsors\"\n      description: |-\n        Mid-level sponsorship with $4,000 price. Includes recognition in conference opening and closing, logo on site-wide footer, middle position on Sponsor Page, logo on all videos (if funding goal reached), LinkedIn and Mastodon promotion, 4 complimentary conference tickets, 1 job ad on conference website, shared 6' table sponsor space in the Café & Bar at eTown Hall.\n      level: 2\n      sponsors: []\n\n    - name: \"Emerald Sponsors\"\n      description: |-\n        Entry-level sponsorship with $2,000 price. Includes recognition in conference opening and closing, logo on site-wide footer, bottom position on Sponsor Page, logo on all videos (if funding goal reached), LinkedIn and Mastodon promotion, 2 complimentary conference tickets.\n      level: 3\n      sponsors: []\n\n    - name: \"Community Sponsors\"\n      description: |-\n        Community Sponsors\n      level: 4\n      sponsors: []\n\n    - name: \"Podcast Sponsors\"\n      description: |-\n        Podcast Sponsors\n      level: 5\n      sponsors: []\n\n    - name: \"Travel Sponsors\"\n      description: |-\n        Travel Sponsors\n      level: 6\n      sponsors: []\n"
  },
  {
    "path": "data/rocky-mountain-ruby/rocky-mountain-ruby-2026/venue.yml",
    "content": "---\nname: \"eTown Hall\"\n\naddress:\n  street: \"1535 Spruce Street\"\n  city: \"Boulder\"\n  region: \"Colorado\"\n  postal_code: \"80302\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"1535 Spruce St, Boulder, CO 80302, USA\"\n\ncoordinates:\n  latitude: 40.0201669\n  longitude: -105.275401\n\nmaps:\n  google: \"https://maps.google.com/?q=eTown+Hall,40.0201669,-105.275401\"\n  apple: \"https://maps.apple.com/?q=eTown+Hall&ll=40.0201669,-105.275401\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=40.0201669&mlon=-105.275401\"\n"
  },
  {
    "path": "data/rocky-mountain-ruby/series.yml",
    "content": "---\nname: \"Rocky Mountain Ruby\"\nwebsite: \"http://rockymtnruby.dev\"\ntwitter: \"rmrubyconf\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Rocky Mountain Ruby\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\naliases:\n  - Rocky Mountain Ruby\n  - Rocky Mountain Ruby Conf\n  - Rocky Mountain Ruby Conference\n  - RMR\n  - rmrubyconf\n  - rockymtnruby\n  - rockymountainruby\n"
  },
  {
    "path": "data/rossconf/rossconf-2015/event.yml",
    "content": "---\nid: \"rossconf-2015\"\ntitle: \"ROSSConf 2015\"\ndescription: \"\"\nlocation: \"Vienna, Austria\"\nkind: \"conference\"\nstart_date: \"2015-04-25\"\nend_date: \"2015-04-25\"\nwebsite: \"http://www.rossconf.io/\"\ntwitter: \"rossconf\"\ncoordinates:\n  latitude: 48.20806959999999\n  longitude: 16.3713095\n"
  },
  {
    "path": "data/rossconf/rossconf-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rossconf.io/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rossconf/rossconf-2015-berlin/event.yml",
    "content": "---\nid: \"rossconf-2015-berlin\"\ntitle: \"ROSSConf Berlin 2015\"\ndescription: \"\"\nlocation: \"Berlin, Germany\"\nkind: \"conference\"\nstart_date: \"2015-09-26\"\nend_date: \"2015-09-26\"\nwebsite: \"http://www.rossconf.io/\"\ntwitter: \"rossconf\"\ncoordinates:\n  latitude: 52.52000659999999\n  longitude: 13.404954\n"
  },
  {
    "path": "data/rossconf/rossconf-2015-berlin/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rossconf.io/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rossconf/rossconf-2018/event.yml",
    "content": "---\nid: \"rossconf-2018\"\ntitle: \"ROSSConf 2018\"\ndescription: \"\"\nlocation: \"Amsterdam, Netherlands\"\nkind: \"conference\"\nstart_date: \"2018-05-11\"\nend_date: \"2018-05-12\"\nwebsite: \"https://rossconfams.eventbrite.co.uk\"\ntwitter: \"rossconf\"\ncoordinates:\n  latitude: 52.3675734\n  longitude: 4.9041389\n"
  },
  {
    "path": "data/rossconf/rossconf-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rossconfams.eventbrite.co.uk\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rossconf/rossconf-2020/event.yml",
    "content": "---\nid: \"rossconf-2020\"\ntitle: \"ROSSConf 2020\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2020-10-23\"\nend_date: \"2020-10-23\"\nwebsite: \"https://www.rossconf.io/event/remote/\"\ntwitter: \"rossconf\"\nplaylist: \"https://www.youtube.com/playlist?list=PL9_A7olkztLkFMYU2ZgpL5XZ6UKlqFZrB\"\ncoordinates: false\n"
  },
  {
    "path": "data/rossconf/rossconf-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://www.rossconf.io/event/remote/\n# Videos: https://www.youtube.com/playlist?list=PL9_A7olkztLkFMYU2ZgpL5XZ6UKlqFZrB\n---\n[]\n"
  },
  {
    "path": "data/rossconf/series.yml",
    "content": "---\nname: \"ROSSConf\"\nwebsite: \"http://www.rossconf.io/\"\ntwitter: \"rossconf\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rs-on-rails/rs-on-rails-2009/event.yml",
    "content": "---\nid: \"rs-on-rails-2009\"\ntitle: \"RS on Rails 2009\"\ndescription: \"\"\nlocation: \"Porto Alegre, Brazil\"\nkind: \"conference\"\nstart_date: \"2009-08-29\"\nend_date: \"2009-08-29\"\noriginal_website: \"http://www.rsrails.com.br\"\ncoordinates:\n  latitude: -30.0368176\n  longitude: -51.2089887\n"
  },
  {
    "path": "data/rs-on-rails/rs-on-rails-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rs-on-rails/series.yml",
    "content": "---\nname: \"RS on Rails\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"portuguese\"\ndefault_country_code: \"BR\"\n"
  },
  {
    "path": "data/ruby-argentina/rubysur-meetup/event.yml",
    "content": "---\nid: \"rubysur\"\ntitle: \"RubySur Meetup\"\nlocation: \"Buenos Aires, Argentina\"\ndescription: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nwebsite: \"https://ruby.com.ar\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: -34.6036739\n  longitude: -58.3821215\n"
  },
  {
    "path": "data/ruby-argentina/rubysur-meetup/videos.yml",
    "content": "---\n- id: \"rubysur-meetup-august-2023\"\n  title: \"RubySur Meetup August 2023\"\n  raw_title: \"RubySur Meetup August 2023\"\n  event_name: \"RubySur Meetup August 2023\"\n  date: \"2023-08-14\"\n  video_id: \"rubysur-meetup-august-2023\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/cVysEUIxYMc/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/cVysEUIxYMc/mqdefault.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/cVysEUIxYMc/hqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/cVysEUIxYMc/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/cVysEUIxYMc/hqdefault.jpg\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on August 14th, 2023.\n  talks:\n    - title: \"Forms on Rails\"\n      raw_title: \"Ruby Meetup Agosto 2023 - Ariel Juodziukynas\"\n      speakers:\n        - Ariel Juodziukynas\n      date: \"2023-08-14\"\n      event_name: \"RubySur Meetup August 2023\"\n      published_at: \"2024-05-31\"\n      language: \"spanish\"\n      description: |-\n        Ariel Juodziukynas nos cuenta sobre el manejo de formularios con Rails y el uso de features nativas de HTML que no mucha gente conoce\n\n        00:00 Introducción - Formularios en Rails\n        00:56 Múltiples submit\n        04:55 Múltiples action/method\n        09:21 Inputs afuera de formularios\n        11:41 Custom form builder\n        15:12 Formularios anidados\n        28:17 Agregar/quitar elementos sin recargar el form\n        34:49 Fin de la charla, links\n        35:41 Preguntas y respuestas\n        40:57 Hack CSS para agregar interacciones sin javascript\n      video_provider: \"youtube\"\n      id: \"ariel-juodziukynas-rubysur-meetup-august-2023\"\n      video_id: \"cVysEUIxYMc\"\n      slides_url: \"https://tinyurl.com/formsonrails\"\n\n- id: \"rubysur-meetup-october-2023\"\n  title: \"RubySur Meetup October 2023\"\n  raw_title: \"RubySur Meetup October 2023\"\n  event_name: \"RubySur Meetup October 2023\"\n  date: \"2023-10-21\"\n  video_id: \"rubysur-meetup-october-2023\"\n  video_provider: \"children\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held in the month of October.\n  talks:\n    - title: \"Setting up VS Code for Ruby on Rails development\"\n      raw_title: \"Viktor Fonic: Setting up VS Code for Ruby on Rails development\"\n      speakers:\n        - Viktor Fonic\n      date: \"2023-10-21\"\n      event_name: \"RubySur Meetup October 2023\"\n      published_at: \"2024-05-31\"\n      description: |-\n        Viktor Fonic describe su experiencia customizando Visual Studio Code para trabajar de manera más eficiente. Nos cuenta sobre algunas de las extensiones más populares y otras no tan conocidas (como Bust a gem, Custom CSS and JS loader), como hacer macros y configurar los keybindings para realizar acciones con pocos tecleos.\n\n        Gist con todos los settings/ajustes, keybindings y link de las extensiones: https://bit.ly/vs-ruby\n\n        00:00 Introducción\n        05:59 UI - Organizando los elementos de la interfaz\n        16:36 Editor - Realizando cambios en el código\n        29:49 HTML/CSS/JS\n        38:28 Extensiones para Ruby on Rails\n        59:16 Debugging\n        1:12:50 Testing\n      video_provider: \"youtube\"\n      id: \"viktor-fonic-rubysur-meetup-october-2023\"\n      video_id: \"uKzAT3EtG5s\"\n      language: \"spanish\"\n      slides_url: \"https://docs.google.com/presentation/d/1JJcZ-uF-t6yWhzOBZxk8qA92WbrOSo6NUIym-9AQZGQ/view\"\n\n    - title: \"Internet of Things con Ruby\"\n      raw_title: \"Santiago Merlo: Internet of Things con Ruby\"\n      speakers:\n        - Santiago Merlo\n      date: \"2023-10-19\"\n      event_name: \"RubySur Meetup October 2023\"\n      published_at: \"2024-05-31\"\n      description: |-\n        ¿Cómo se lleva Ruby con Internet of Things (IoT) en la Raspberry Pi? Santiago Merlo nos muestra algunos ejemplos básicos y nos cuenta sobre lo bueno, lo malo y lo no tan bonito de usar Ruby para el Internet de las Cosas.\n        ¿Es realmente práctico o sólo es para entusiastas del lenguaje?\n\n        Código y Powerpoint: https://github.com/smerlo/RubyIoT\n\n        00:00 Introducción\n        01:44 Gemas disponibles\n        02:26 Led/Relay\n        04:23 Servo\n        06:24 Ultrasonic Sensor\n        08:21 Motion Sensor\n        09:28 Limitaciones\n        11:41 Conclusiones\n        13:05 Preguntas y respuestas\n      video_provider: \"youtube\"\n      id: \"santiago-merlo-rubysur-meetup-october-2023\"\n      video_id: \"8bZ0Br9Sz1c\"\n      language: \"spanish\"\n      additional_resources:\n        - name: \"smerlo/RubyIoT\"\n          type: \"repo\"\n          url: \"https://github.com/smerlo/RubyIoT\"\n\n- id: \"rubysur-meetup-march-2024\"\n  title: \"RubySur Meetup March 2024\"\n  raw_title: \"RubySur Meetup March 2024\"\n  event_name: \"RubySur Meetup March 2024\"\n  date: \"2024-03-14\"\n  video_id: \"rubysur-meetup-march-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/3qyTOEVSeog/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/3qyTOEVSeog/mqdefault.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/3qyTOEVSeog/hqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/3qyTOEVSeog/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/3qyTOEVSeog/hqdefault.jpg\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on March 14th, 2024.\n  talks:\n    - title: \"Debugging\"\n      raw_title: \"Rubysur - Marzo 2024: Debugging\"\n      speakers:\n        - Fernando E. Silva Jacquier\n      date: \"2024-03-14\"\n      event_name: \"RubySur Meetup March 2024\"\n      language: \"spanish\"\n      published_at: \"2024-05-31\"\n      description: |-\n        \"Iluminando el Camino: Perspectivas sobre Debugging de un Recién Llegado\", nuestro orador, Fernando E. Silva Jacquier, inspirado por el libro \"Are your lights on?\", nos ofrece una perspectiva única sobre cómo abordar el debugging como un problema más, brindando herramientas simples pero efectivas para diagnosticar y resolver errores.\n        La charla abarca desde fundamentos teóricos y estrategias prácticas para reducir el alcance de los problemas, a alternativas, que nos ayuden a mejorar el proceso de debugging.\n      video_provider: \"youtube\"\n      id: \"fernando-e-silva-jacquier-rubysur-meetup-march-2024\"\n      video_id: \"3qyTOEVSeog\"\n\n- title: \"RubySur Meetup April 2024\"\n  raw_title: \"RubySur Meetup April 2024\"\n  event_name: \"RubySur Meetup April 2024\"\n  date: \"2024-04-16\"\n  id: \"rubysur-meetup-april-2024\"\n  video_id: \"vRVeNSejGKA\"\n  published_at: \"2024-04-17\"\n  video_provider: \"youtube\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on April 16th, 2024.\n\n    Charla 1: \"Speed up CI in your Ruby applications\" por Enzo Fabbiani\n    ¿Te gustaría acelerar tus procesos de Integración Continua (CI) en tus aplicaciones Ruby? En esta charla, Enzo Fabbiani, experto en desarrollo de software, compartirá estrategias y mejores prácticas para optimizar tus flujos de CI y mejorar la eficiencia en el desarrollo de tus aplicaciones Ruby. Descubre cómo implementar técnicas efectivas para reducir los tiempos de construcción y despliegue, y aumenta la productividad de tu equipo de desarrollo.\n\n    Slides: https://docs.google.com/presentation/d/1UeuwW41J2xWRClRok4zuR7plMI-rwgIRupc99m50e24/edit?usp=sharing\n\n    Charla 2: \"How to Prepare Your First Meetup Talk\" por Santiago Merlo\n    ¿Te gustaría compartir tus conocimientos y experiencias en un meetup pero no sabes por dónde empezar? En esta charla, Santiago Merlo, experimentado orador en eventos técnicos, te guiará a través de los pasos claves para preparar y presentar tu primera charla en un meetup. Desde la elección del tema hasta la entrega efectiva, aprenderás técnicas prácticas para cautivar a tu audiencia y dejar una impresión duradera en tu comunidad.\n\n    Slides: https://docs.google.com/presentation/d/10JZ94l-oZvOf5GmJ_trsBn75uqojb98pTtA6WuthUm8/edit#slide=id.p\n  talks:\n    - title: \"Speed up CI in your Ruby applications\"\n      speakers:\n        - Enzo Fabbiani\n      date: \"2024-04-16\"\n      event_name: \"RubySur Meetup April 2024\"\n      language: \"spanish\"\n      published_at: \"2024-05-31\"\n      description: |-\n        ¿Te gustaría acelerar tus procesos de Integración Continua (CI) en tus aplicaciones Ruby? En esta charla, Enzo Fabbiani, experto en desarrollo de software, compartirá estrategias y mejores prácticas para optimizar tus flujos de CI y mejorar la eficiencia en el desarrollo de tus aplicaciones Ruby. Descubre cómo implementar técnicas efectivas para reducir los tiempos de construcción y despliegue, y aumenta la productividad de tu equipo de desarrollo.\n      video_provider: \"parent\"\n      id: \"enzo-fabbiani-rubysur-meetup-april-2024\"\n      video_id: \"enzo-fabbiani-rubysur-meetup-april-2024\"\n      slides_url: \"https://docs.google.com/presentation/d/1UeuwW41J2xWRClRok4zuR7plMI-rwgIRupc99m50e24/edit?usp=sharing\"\n      start_cue: \"00:04\"\n      end_cue: \"18:45\"\n      thumbnail_cue: \"00:03\"\n\n    - title: \"How to Prepare Your First Meetup Talk\"\n      speakers:\n        - Santiago Merlo\n      date: \"2024-04-16\"\n      event_name: \"RubySur Meetup April 2024\"\n      language: \"spanish\"\n      published_at: \"2024-05-31\"\n      description: |-\n        ¿Te gustaría compartir tus conocimientos y experiencias en un meetup pero no sabes por dónde empezar? En esta charla, Santiago Merlo, experimentado orador en eventos técnicos, te guiará a través de los pasos claves para preparar y presentar tu primera charla en un meetup. Desde la elección del tema hasta la entrega efectiva, aprenderás técnicas prácticas para cautivar a tu audiencia y dejar una impresión duradera en tu comunidad.\n      video_provider: \"parent\"\n      id: \"santiago-merlo-rubysur-meetup-april-2024\"\n      video_id: \"santiago-merlo-rubysur-meetup-april-2024\"\n      slides_url: \"https://docs.google.com/presentation/d/10JZ94l-oZvOf5GmJ_trsBn75uqojb98pTtA6WuthUm8/edit#slide=id.p\"\n      start_cue: \"19:47\"\n      end_cue: \"31:01\"\n\n- id: \"rubysur-meetup-may-2024\"\n  title: \"RubySur Meetup May 2024\"\n  raw_title: \"RubySur Meetup May 2024\"\n  event_name: \"RubySur Meetup May 2024\"\n  date: \"2024-05-14\"\n  video_id: \"rubysur-meetup-may-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/zbp_2VqAxDQ/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/zbp_2VqAxDQ/mqdefault.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/zbp_2VqAxDQ/hqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/zbp_2VqAxDQ/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/zbp_2VqAxDQ/hqdefault.jpg\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on May 14th, 2024.\n  talks:\n    - title: \"Hotwire\"\n      raw_title: \"Ruby Meetup - Mayo 2024 - Hotwire\"\n      speakers:\n        - Filipe Mendez\n      date: \"2024-05-14\"\n      event_name: \"RubySur Meetup May 2024\"\n      language: \"spanish\"\n      published_at: \"2024-05-31\"\n      description: |-\n        Filipe Mendez nos da una presentación sobre las distintas partes de Hotwire y como lo están utilizando en su trabajo.\n      video_provider: \"youtube\"\n      id: \"filipe-mendez-rubysur-meetup-may-2024\"\n      video_id: \"zbp_2VqAxDQ\"\n      slides_url: \"https://docs.google.com/presentation/d/1YkL7JPyQUfdAoe85u3DLs-tajjKoCOifHzFpdSOBOqg/edit?slide=id.p#slide=id.p\"\n\n- id: \"rubysur-meetup-june-2024\"\n  title: \"RubySur Meetup June 2024\"\n  raw_title: \"RubySur Meetup June 2024\"\n  event_name: \"RubySur Meetup June 2024\"\n  date: \"2024-06-13\"\n  video_id: \"rubysur-meetup-june-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/IroDPuj_b8o/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/IroDPuj_b8o/mqdefault.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/IroDPuj_b8o/hqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/IroDPuj_b8o/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/IroDPuj_b8o/hqdefault.jpg\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on June 13th, 2024.\n  talks:\n    - title: \"La Evolución del Assets Pipeline\"\n      raw_title: \"La Evolución del Assets Pipeline\"\n      speakers:\n        - Ariel Juodziukynas\n      date: \"2024-06-13\"\n      event_name: \"RubySur Meetup June 2024\"\n      language: \"spanish\"\n      published_at: \"2025-03-14\"\n      description: |-\n        En esta cuarta edición, Ariel Juodziukynas nos dará un repaso sobre las distintas formas de manejar assets en Rails a través del tiempo. Desde el principio hasta\n        Rails 8\n\n        No te la pierdas! Recordá que podés acompañarnos presencialmente y compartir unas birras.\n      video_provider: \"youtube\"\n      id: \"ariel-juodziukynas-rubysur-meetup-june-2024\"\n      video_id: \"IroDPuj_b8o\"\n\n- id: \"rubysur-meetup-july-2024\"\n  title: \"RubySur Meetup July 2024\"\n  raw_title: \"RubySur Meetup July 2024\"\n  event_name: \"RubySur Meetup July 2024\"\n  date: \"2024-07-18\"\n  video_id: \"rubysur-meetup-july-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/svst2V6kVVA/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/svst2V6kVVA/mqdefault.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/svst2V6kVVA/hqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/svst2V6kVVA/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/svst2V6kVVA/hqdefault.jpg\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on July 18th, 2024.\n  talks:\n    - title: \"Rails | Lo que hay y lo que viene\"\n      raw_title: \"Rails | Lo que hay y lo que viene con Fernando E. Silva Jacquier\"\n      speakers:\n        - Fernando E. Silva Jacquier\n      date: \"2024-07-18\"\n      event_name: \"RubySur Meetup July 2024\"\n      language: \"spanish\"\n      published_at: \"2025-03-14\"\n      description: |-\n        Descubrí las últimas novedades de Rails y Turbo en nuestra próxima meetup, de la mano de Fernando E. Silva Jacquier. ⭐️\n\n        ¿Alguna vez has escuchado sobre la nueva versión de Turbo y sus características de morphing e instant click? Si no es así, ¡no te preocupes! Esta meetup es para vos.\n\n        ¿Qué puedes esperar de esta charla?\n\n        ● Una demostración en vivo (live coding) de la característica de Turbo que más me fascina: el morphing.\n\n        ● Un vistazo a las próximas novedades en Rails 8.\n\n        ● Más live coding, enfocándonos en una de las características que más expectativas genera: PWA.\n\n        Mantenerse actualizado es crucial. Rails está en constante evolución, con nuevas funcionalidades y mejoras añadidas regularmente.\n\n        Seguir el menú omakase de Rails tiene mucho valor. Está diseñado para ser fácil de usar y permitirte lograr mucho con poco.\n\n        ¡No te pierdas esta oportunidad de aprender y mantenerte al día con las últimas innovaciones en Ruby on Rails!\n      video_provider: \"youtube\"\n      id: \"fernando-e-silva-jacquier-rubysur-meetup-july-2024\"\n      video_id: \"svst2V6kVVA\"\n\n- id: \"rubysur-meetup-august-2024\"\n  title: \"RubySur Meetup August 2024\"\n  raw_title: \"RubySur Meetup August 2024\"\n  event_name: \"RubySur Meetup August 2024\"\n  date: \"2024-08-14\"\n  video_id: \"rubysur-meetup-august-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/xU7LBW8tmKI/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/xU7LBW8tmKI/mqdefault.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/xU7LBW8tmKI/hqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/xU7LBW8tmKI/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/xU7LBW8tmKI/hqdefault.jpg\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on August 14th, 2024.\n  talks:\n    - title: \"Refactoring en Ruby: Elevating Code Quality Through Community And Practice\"\n      raw_title: \"Refactoring en Ruby: Elevating Code Quality Through Community And Practice\"\n      speakers:\n        - Julio Agustin Lucero\n      date: \"2024-08-14\"\n      event_name: \"RubySur Meetup August 2024\"\n      language: \"spanish\"\n      published_at: \"2025-03-14\"\n      description: |-\n        Julio Agustin Lucero es nuestro speaker de la fecha y va a estar abordando:\n\n        Refactoring en Ruby: Elevating Code Quality Through Community And Practice\n\n        Unite a nosotros en esta charla donde exploraremos cómo la programación va más allá de simples líneas de código, convirtiéndose en un proceso colaborativo y creativo.\n        Inspirados por figuras como Kent Beck y DHH, discutiremos la importancia de producir código limpio, mantenible y eficiente.\n\n        Nos centraremos en el libro “Refactoring: Ruby Edition” de Jay Fields, Shane Harvie y Martin Fowler, y cómo ha guiado el desarrollo de muchos programadores. Descubrí\n        valiosas estrategias y consejos para mejorar tu práctica de programación y llevar tu código al siguiente nivel.\n\n        ¡No te pierdas esta oportunidad de aprender y mantenerte al día con las últimas innovaciones en Ruby on Rails!\n      video_provider: \"youtube\"\n      id: \"julio-agustin-lucero-rubysur-meetup-august-2024\"\n      video_id: \"xU7LBW8tmKI\"\n\n- id: \"rubysur-meetup-september-2024\"\n  title: \"RubySur Meetup September 2024\"\n  raw_title: \"RubySur Meetup September 2024\"\n  event_name: \"RubySur Meetup September 2024\"\n  date: \"2024-09-12\"\n  video_id: \"rubysur-meetup-september-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/F-CnVCJQLKI/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/F-CnVCJQLKI/mqdefault.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/F-CnVCJQLKI/hqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/F-CnVCJQLKI/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/F-CnVCJQLKI/hqdefault.jpg\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on September 12th, 2024.\n  talks:\n    - title: \"Actualizar tu aplicación con Dual Booting\"\n      raw_title: \"Actualizar tu aplicación con Dual Booting | Septiembre 2024\"\n      speakers:\n        - Ariel Juodziukynas\n      date: \"2024-09-12\"\n      event_name: \"RubySur Meetup September 2024\"\n      language: \"spanish\"\n      published_at: \"2025-03-14\"\n      description: |-\n        Ariel Juodziukynas vuelve a compartirnos como Actualizar tu aplicación con Dual Booting ✨\n\n        Vamos a ver cómo actualizar Ruby, Rails, o cualquier otra gema, usando la técnica de Dual Booting para actualizar nuestras aplicaciones gradualmente y ayudarnos a prepara\n        la app para futuras versiones. Vamos a ver ejemplos y conceptos para luego poder adaptar la técnica a diferentes aplicaciones.\n      video_provider: \"youtube\"\n      id: \"ariel-juodziukynas-rubysur-meetup-september-2024\"\n      video_id: \"F-CnVCJQLKI\"\n\n- id: \"rubysur-meetup-october-2024\"\n  title: \"RubySur Meetup October 2024\"\n  raw_title: \"RubySur Meetup October 2024\"\n  event_name: \"RubySur Meetup October 2024\"\n  date: \"2024-10-16\"\n  video_id: \"rubysur-meetup-october-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/2nZsZ4_lx7w/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/2nZsZ4_lx7w/mqdefault.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/2nZsZ4_lx7w/hqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/2nZsZ4_lx7w/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/2nZsZ4_lx7w/hqdefault.jpg\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on October 16th, 2024.\n  talks:\n    - title: \"View Components the Right Way\"\n      raw_title: \"View components the right way\"\n      speakers:\n        - Jorge Leites\n      date: \"2024-10-16\"\n      event_name: \"RubySur Meetup October 2024\"\n      language: \"spanish\"\n      published_at: \"2025-03-14\"\n      description: |-\n        Jorge Leites es nuestro speaker del mes de Octubre y va a presentar una charla sobre View Components.\n\n        Hablará la gema de view components, y recomendaciones sobre el correcto, estos para conseguir componentes altamente reusables.\n      video_provider: \"youtube\"\n      id: \"jorge-leites-rubysur-meetup-october-2024\"\n      video_id: \"2nZsZ4_lx7w\"\n\n- id: \"rubysur-meetup-november-2024\"\n  title: \"RubySur Meetup November 2024\"\n  raw_title: \"RubySur Meetup November 2024\"\n  event_name: \"RubySur Meetup November 2024\"\n  date: \"2024-11-12\"\n  video_id: \"rubysur-meetup-november-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/fZIhFXQb2Sw/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/fZIhFXQb2Sw/mqdefault.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/fZIhFXQb2Sw/hqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/fZIhFXQb2Sw/hqdefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/fZIhFXQb2Sw/hqdefault.jpg\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on November 12th, 2024.\n\n    Noviembre 2024 - IA + Testing\n\n    Para cerrar el año con todo, en RubySur vamos a tirar la casa por la ventana con dos charlas imperdibles sobre inteligencia artificial y buenas prácticas de testing. Este último evento del año promete y queremos que seas parte. ¡No te lo pierdas!\n\n    “Ruby + IA: de la teoría a la práctica”\n    Speaker: Juan Pablo Balarini, CTO de eagerworks\n    Exploraremos el potencial de la inteligencia artificial, desde los conceptos clave hasta ejemplos prácticos en una aplicación de Ruby on Rails.\n\n    “Testing: Buenas prácticas y performance”\n    Speaker: Joaquín Vicente, de Razor y miembro activo de la comunidad de RubySur\n    Una charla sobre cómo escribir y organizar tests eficientes, equilibrando la calidad del código, la practicidad y la performance. Joaquín compartirá estrategias para optimizar tiempos de ejecución y reducir la complejidad de las pruebas, asegurando una suite de testing confiable para el desarrollo de aplicaciones.\n\n    📅 Fecha: 12 de Noviembre, 19:00 - presencial\n\n    Sumate y seguí aprendiendo con la comunidad RubySur. ¡Nos vemos ahí!\n\n    🎤 Si tenés ganas de dar una charla, podés inscribirte acá: https://forms.gle/SgLJmfsawaBjNUAm6\n\n    🎖️ Si tenés ganas de sponsorear o sumar tu apoyo en un evento, ya sea por difusión u otro canal, podés anotarte acá:\n    https://forms.gle/JS696JWcUgFCZWGH7\n  talks:\n    - title: \"Ruby + IA: de la teoría a la práctica\"\n      speakers:\n        - Juan Pablo Balarini\n      date: \"2024-11-12\"\n      event_name: \"RubySur Meetup November 2024\"\n      language: \"spanish\"\n      published_at: \"2025-03-14\"\n      description: |-\n        Exploraremos el potencial de la inteligencia artificial, desde los conceptos clave hasta ejemplos prácticos en una aplicación de Ruby on Rails.\n      video_provider: \"youtube\"\n      id: \"juan-pablo-balarini-rubysur-meetup-november-2024\"\n      video_id: \"fZIhFXQb2Sw\"\n\n    - title: \"Testing: Buenas prácticas y performance\"\n      speakers:\n        - Joaquín Vicente\n      date: \"2024-11-12\"\n      event_name: \"RubySur Meetup November 2024\"\n      language: \"spanish\"\n      published_at: \"2025-03-14\"\n      description: |-\n        Una charla sobre cómo escribir y organizar tests eficientes, equilibrando la calidad del código, la practicidad y la performance. Joaquín compartirá estrategias para optimizar tiempos de ejecución y reducir la complejidad de las pruebas, asegurando una suite de testing confiable para el desarrollo de aplicaciones.\n      video_provider: \"youtube\"\n      id: \"joaqun-vicente-rubysur-meetup-november-2024\"\n      video_id: \"4IkPjUdssNI\"\n\n- title: \"RubySur Meetup March 2025\"\n  raw_title: \"RubySur Meetup March 2025\"\n  event_name: \"RubySur Meetup March 2025\"\n  date: \"2025-03-14\"\n  id: \"rubysur-meetup-march-2025\"\n  video_id: \"tMxMVAQkBZs\"\n  published_at: \"2025-03-13\"\n  video_provider: \"youtube\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on March 14th, 2025.\n\n    Acompañanos a ver estas dos charlas en vivo que arrancan el año con toda!\n\n    Recordá que si estas en Buenos Aires podes acercarte a verlas en vivo y hacer tus preguntas.\n\n    Jaime Zuberbuhler, Co-Founder de MoonyApp, va a adentrarnos en como implementar adapters y mappers en Rails para interactuar con distintas APIs.\n\n    Patricio Mac Adden, Co-Founder de Sinaptia, nos comparte sobre Instrumentación y Observabilidad. Vamos a aprender conceptos generales y diferentes formas de implementarla en Rails.\n\n    Conocé Moony: https://moonyapp.site/\n\n    Conocé Sinaptia: https://sinaptia.dev/\n\n  talks:\n    - title: \"Implementando ll APIs en Rails sin volverse Loco\"\n      raw_title: \"Primera MeetUp 2025 | Edición Founders On Rails\"\n      speakers:\n        - Jaime Zuberbuhler\n      date: \"2025-03-14\"\n      event_name: \"RubySur Meetup March 2025\"\n      language: \"spanish\"\n      published_at: \"2025-03-14\"\n      description: \"\"\n      video_provider: \"parent\"\n      id: \"jamie-zuberbuhler-rubysur-meetup-march-2025\"\n      video_id: \"jamie-zuberbuhler-rubysur-meetup-march-2025\"\n      start_cue: \"06:40\"\n      end_cue: \"44:23\"\n\n    - title: \"El Camino de la Instrumentación\"\n      raw_title: \"Instrumentación y Observabilidad\"\n      speakers:\n        - Patricio Mac Adden\n      date: \"2025-03-14\"\n      event_name: \"RubySur Meetup March 2025\"\n      language: \"spanish\"\n      published_at: \"2025-03-14\"\n      description: \"\"\n      video_provider: \"parent\"\n      id: \"patricio-mac-adden-rubysur-meetup-march-2025\"\n      video_id: \"patricio-mac-adden-rubysur-meetup-march-2025\"\n      start_cue: \"49:10\"\n      end_cue: \"1:45:45\"\n      thumbnail_cue: \"49:39\"\n\n- title: \"RubySur Meetup April 2025\"\n  raw_title: \"RubySur Meetup April 2025\"\n  event_name: \"RubySur Meetup April 2025\"\n  date: \"2025-04-10\"\n  id: \"rubysur-meetup-april-2025\"\n  video_id: \"dc9D9NeDJLk\"\n  published_at: \"2025-04-11\"\n  video_provider: \"youtube\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on April 10th, 2025.\n\n    RubySur v2025 se viene lleno de charlas y cosas nuevas ✨💬. Así que para que nadie se quede afuera, en esta oportunidad vamos a tener dos charlas sobre como actualizar tu app 🔄.\n\n    🗓️ Fecha: 10/Abril 19hs\n\n    Charla 1: “De cero contexto a full upgrade: cómo actualizar una app ajena”\n    🎙️ Speaker: Gastón Ginestet\n    🤔 ¿Qué pasa si de un día para el otro te piden actualizar una aplicación que no conocés?\n    ❓ ¿Qué hacés? ¿Por dónde empezás?\n    🛠️ ¿Cómo podés hacer para actualizar una aplicación sin romper nada en el camino?\n    Gastón nos va a contar su experiencia en este arduo trabajo 🧗‍♂️.\n\n    Charla 2: “Zeit-what? Autoloading en ruby”\n    🎙️ Speaker: Joaquín Vicente\n    🍽️ ¿Qué es el autoloading y con qué se come?\n    Esta charla nos va a presentar un tema que suele aparecer solo 🧙‍♂️, cada vez se habla de upgrades.\n    Joaquín nos va a contar qué es y cómo podemos sacar provecho de este feature, tanto dentro, como fuera de Rails 🚂.\n    🔁 Qué diferencias hay entre los modos classic y zeitwerk, y cuáles son los problemas comunes a la hora de actualizar a Rails 7 ⚙️.\n\n    Sumate y seguí aprendiendo con la comunidad RubySur. ¡Nos vemos ahí!\n\n  talks:\n    - title: \"De cero contexto a full upgrade: cómo actualizar una app ajena\"\n      speakers:\n        - Gastón Ginestet\n      date: \"2025-04-10\"\n      event_name: \"RubySur Meetup April 2025\"\n      language: \"spanish\"\n      published_at: \"2025-05-13\"\n      video_provider: \"parent\"\n      id: \"gaston-ginestet-joaquin-vicente-rubysur-meetup-april-2025\"\n      video_id: \"gaston-ginestet-joaquin-vicente-rubysur-meetup-april-2025\"\n      description: |-\n        🤔 ¿Qué pasa si de un día para el otro te piden actualizar una aplicación que no conocés?\n        ❓ ¿Qué hacés? ¿Por dónde empezás?\n        🛠️ ¿Cómo podés hacer para actualizar una aplicación sin romper nada en el camino?\n        Gastón nos va a contar su experiencia en este arduo trabajo 🧗‍♂️.\n\n    - title: \"Zeit-what? Autoloading en ruby\"\n      speakers:\n        - Joaquín Vicente\n      date: \"2025-04-10\"\n      event_name: \"RubySur Meetup April 2025\"\n      language: \"spanish\"\n      published_at: \"2025-05-13\"\n      video_provider: \"parent\"\n      id: \"joaquin-vicente-rubysur-meetup-april-2025\"\n      video_id: \"joaquin-vicente-rubysur-meetup-april-2025\"\n      description: |-\n        🍽️ ¿Qué es el autoloading y con qué se come?\n        Esta charla nos va a presentar un tema que suele aparecer solo 🧙‍♂️, cada vez se habla de upgrades.\n        Joaquín nos va a contar qué es y cómo podemos sacar provecho de este feature, tanto dentro, como fuera de Rails 🚂.\n        🔁 Qué diferencias hay entre los modos classic y zeitwerk, y cuáles son los problemas comunes a la hora de actualizar a Rails 7 ⚙️.\n\n- title: \"RubySur Meetup May 2025\"\n  raw_title: \"RubySur Meetup May 2025\"\n  event_name: \"RubySur Meetup May 2025\"\n  date: \"2025-05-14\"\n  id: \"rubysur-meetup-may-2025\"\n  video_id: \"6SNnDvneIMw\"\n  published_at: \"2025-05-15\"\n  video_provider: \"youtube\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on May 14th, 2025.\n\n    No te pierdas nuestro siguiente encuentro! será presencial en Palermo! inscripción por Meetup.\n\n    Multi-tenancy en Rails: De 0 a SaaS con acts_as_tenant | Santiago Díaz\n\n    ¿Alguna vez surgió la duda de cómo se gestionan miles de tiendas en una sola aplicación? En esta charla, se explora cómo implementar multi-tenancy en Rails utilizando acts_as_tenant. Se muestra cómo transformar una aplicación monolítica en una plataforma SaaS escalable, con experiencias reales y buenas prácticas aplicadas a una plataforma de e-commerce.\n\n    Service Objects en Rails | Fernando E. Silva Jacquier\n\n    Se analiza por qué el patrón de Service Objects en Rails genera tanta controversia y por qué, a pesar de las críticas, sigue siendo una herramienta útil para encapsular lógica de negocio. También se presentan ejemplos concretos y convenciones prácticas para aplicarlo de forma efectiva sin perder la cabeza.\n  talks:\n    - title: \"Multi-tenancy en Rails: De 0 a SaaS con acts_as_tenant\"\n      raw_title: \"Multi-tenancy en Rails: De 0 a SaaS con acts_as_tenant\"\n      speakers:\n        - Santiago Díaz\n      date: \"2025-05-14\"\n      event_name: \"RubySur Meetup May 2025\"\n      language: \"spanish\"\n      published_at: \"2025-05-14\"\n      description: \"\"\n      video_provider: \"parent\"\n      id: \"santiago-diaz-rubysur-meetup-may-2025\"\n      video_id: \"santiago-diaz-rubysur-meetup-may-2025\"\n      start_cue: \"14:45\"\n      end_cue: \"43:50\"\n\n    - title: \"Service Objects en Rails\"\n      raw_title: \"Mayo | Escalabilidad y Service Objects\"\n      speakers:\n        - Fernando E. Silva Jacquier\n      date: \"2025-05-14\"\n      event_name: \"RubySur Meetup May 2025\"\n      language: \"spanish\"\n      published_at: \"2025-05-14\"\n      description: |-\n        Se analiza por qué el patrón de Service Objects en Rails genera tanta controversia y por qué, a pesar de las críticas, sigue siendo una herramienta útil para encapsular lógica de negocio. También se presentan ejemplos concretos y convenciones prácticas para aplicarlo de forma efectiva sin perder la cabeza.\n      video_provider: \"parent\"\n      id: \"fernando-e-silva-jacquier-rubysur-meetup-may-2025\"\n      video_id: \"fernando-e-silva-jacquier-rubysur-meetup-may-2025\"\n      start_cue: \"58:22\"\n      end_cue: \"1:47:16\"\n      thumbnail_cue: \"59:38\"\n\n- title: \"RubySur Meetup June 2025\"\n  raw_title: \"RubySur Meetup June 2025\"\n  event_name: \"RubySur Meetup June 2025\"\n  date: \"2025-06-12\"\n  id: \"rubysur-meetup-june-2025\"\n  video_id: \"i0pwQoR1VgM\"\n  published_at: \"2025-06-13\"\n  video_provider: \"youtube\"\n  description: |-\n    This is a collection of talks from the RubySur Meetup held on June 12th, 2025.\n\n    Join us for an evening of live discussions with two industry experts who will share their knowledge with us!\n\n    Sebastián Buffo Sempé - Le Wagon Latam Founder\n    When Business meets Technology | The Digital Transformation of a Company\n\n    Sebastián will explore the crucial premise that technology should adapt to business needs, not the other way around. Through two real-life case studies—one successful and one not so much—he'll provide valuable insights for those who make tech decisions, lead products, or want to understand how to strategically align tech and business.\n\n    Jason Swett - codewithjason.com\n    \"The Meaningful Test: Grasping the Practice of Automated Testing\"\n\n    Testing is a hot topic in the Ruby community, but what does it really mean? What makes a test meaningful? Jason Swett will tackle these questions to help us better understand the vital practice of automated testing and how it can benefit our development processes.\n\n    Don't miss out on these insightful talks! Join us to learn from these experts and take your understanding of tech and business alignment and automated testing to the next level.\n  talks:\n    - title: \"The Meaningful Test: Grasping the Practice of Automated Testing\"\n      raw_title: \"The Meaningful Test: Grasping the Practice of Automated Testing\"\n      speakers:\n        - Jason Swett\n      date: \"2025-06-12\"\n      event_name: \"RubySur Meetup June 2025\"\n      published_at: \"2025-06-11\"\n      description: \"\"\n      video_provider: \"parent\"\n      id: \"jason-swett-rubysur-meetup-june-2025\"\n      video_id: \"jason-swett-rubysur-meetup-june-2025\"\n      language: \"english\"\n      start_cue: \"11:02\"\n      end_cue: \"48:00\"\n      thumbnail_cue: \"15:01\"\n\n    - title: \"When Business meets Technology | The Digital Transformation of a Company\"\n      raw_title: \"When Business meets Technology | The Digital Transformation of a Company\"\n      speakers:\n        - Sebastián Buffo Sempé\n      date: \"2025-06-12\"\n      event_name: \"RubySur Meetup June 2025\"\n      published_at: \"2025-06-11\"\n      description: |-\n        Missing the rest of the talk.\n      video_provider: \"parent\"\n      id: \"sebastian-buffo-sempe-rubysur-meetup-june-2025\"\n      video_id: \"sebastian-buffo-sempe-rubysur-meetup-june-2025\"\n      language: \"spanish\"\n      start_cue: \"50:28\"\n      end_cue: \"52:40\"\n      thumbnail_cue: \"50:36\"\n"
  },
  {
    "path": "data/ruby-argentina/series.yml",
    "content": "---\nname: \"Ruby Argentina\"\nwebsite: \"https://ruby.com.ar\"\ntwitter: \"\"\nyoutube_channel_name: \"rubysur\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nlanguage: \"spanish\"\ndefault_country_code: \"ARG\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-australia/ruby-australia-meetup/event.yml",
    "content": "---\nid: \"ruby-australia-meetup\"\ntitle: \"Ruby Australia Meetup\"\nlocation: \"Australia\"\ndescription: |-\n  Videos from Ruby meetups around Australia\npublished_at: \"2017-05-22\"\nchannel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nkind: \"meetup\"\nbanner_background: \"#E3342E\"\nfeatured_background: \"#E3342E\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: -25.274398\n  longitude: 133.775136\n"
  },
  {
    "path": "data/ruby-australia/ruby-australia-meetup/videos.yml",
    "content": "---\n- id: \"carl-woodward-ruby-australia-sydney-meetup-august-2012\"\n  title: \"Fog and Chef Solo\"\n  raw_title: \"Fog and Chef Solo by Carl Woodward\"\n  speakers:\n    - Carl Woodward\n  event_name: \"Ruby Australia Sydney Meetup August 2012\"\n  date: \"2012-08-31\" # TODO: day unknown\n  published_at: \"2017-05-22T21:58:45Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"bsU6AwIzQc0\"\n  thumbnail_xs: \"https://img.youtube.com/vi/bsU6AwIzQc0/default.jpg\"\n  thumbnail_sm: \"https://img.youtube.com/vi/bsU6AwIzQc0/mqdefault.jpg\"\n  thumbnail_md: \"https://img.youtube.com/vi/bsU6AwIzQc0/mqdefault.jpg\"\n  thumbnail_lg: \"https://img.youtube.com/vi/bsU6AwIzQc0/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/bsU6AwIzQc0/hqdefault.jpg\"\n\n- id: \"ivan-vanderbyl-ruby-australia-sydney-meetup-august-2012\"\n  title: \"Building REST APIs with Grape\"\n  raw_title: \"Building REST APIs with Grape by Ivan Vanderbyl\"\n  speakers:\n    - Ivan Vanderbyl\n  event_name: \"Ruby Australia Sydney Meetup August 2012\"\n  date: \"2012-08-31\" # TODO: day unknown\n  published_at: \"2017-05-22T21:59:11Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ntpT0vIv3bA\"\n  thumbnail_xs: \"https://img.youtube.com/vi/ntpT0vIv3bA/default.jpg\"\n  thumbnail_sm: \"https://img.youtube.com/vi/ntpT0vIv3bA/mqdefault.jpg\"\n  thumbnail_md: \"https://img.youtube.com/vi/ntpT0vIv3bA/mqdefault.jpg\"\n  thumbnail_lg: \"https://img.youtube.com/vi/ntpT0vIv3bA/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/ntpT0vIv3bA/hqdefault.jpg\"\n\n- id: \"leonard-garvey-ruby-australia-sydney-meetup-september-2012\"\n  title: \"Active Record ain't your mum\"\n  raw_title: \"AR ain't your mum by Leonard Garvey\"\n  speakers:\n    - Leonard Garvey\n  event_name: \"Ruby Australia Sydney Meetup September 2012\"\n  date: \"2012-09-30\" # TODO: day unknown\n  published_at: \"2017-05-22T21:59:36Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"shLl2fSSmo4\"\n  thumbnail_xs: \"https://img.youtube.com/vi/shLl2fSSmo4/default.jpg\"\n  thumbnail_sm: \"https://img.youtube.com/vi/shLl2fSSmo4/mqdefault.jpg\"\n  thumbnail_md: \"https://img.youtube.com/vi/shLl2fSSmo4/mqdefault.jpg\"\n  thumbnail_lg: \"https://img.youtube.com/vi/shLl2fSSmo4/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/shLl2fSSmo4/hqdefault.jpg\"\n\n- id: \"toby-hede-ruby-australia-sydney-meetup-september-2012\"\n  title: \"PostgreSQL, V8, and JSON for fun and profit\"\n  raw_title: \"PostgreSQL, V8, and JSON for fun and profit by Toby Hede\"\n  speakers:\n    - Toby Hede\n  event_name: \"Ruby Australia Sydney Meetup September 2012\"\n  date: \"2012-09-30\" # TODO: day unknown\n  published_at: \"2017-05-22T22:01:23Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"gRPVc_Gt-7s\"\n  thumbnail_xs: \"https://img.youtube.com/vi/gRPVc_Gt-7s/default.jpg\"\n  thumbnail_sm: \"https://img.youtube.com/vi/gRPVc_Gt-7s/mqdefault.jpg\"\n  thumbnail_md: \"https://img.youtube.com/vi/gRPVc_Gt-7s/mqdefault.jpg\"\n  thumbnail_lg: \"https://img.youtube.com/vi/gRPVc_Gt-7s/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/gRPVc_Gt-7s/hqdefault.jpg\"\n\n- id: \"janko-marohnic-ruby-australia-melbourne-meetup-february-2017\"\n  title: \"Shrine - Handle file uploads like it's 2017\"\n  raw_title: \"Shrine - Handle file uploads like it's 2017\"\n  speakers:\n    - Janko Marohnić\n  event_name: \"Ruby Australia Melbourne Meetup February 2017\"\n  date: \"2017-02-22\"\n  published_at: \"2017-03-22T03:28:32Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"wACURf0U0Pk\"\n\n- id: \"silvio-montanari-ruby-australia-melbourne-meetup-february-2017\"\n  title: \"Code Forensic Analysis\"\n  raw_title: \"Silvio Montanari - Code forensic analysis\"\n  speakers:\n    - Silvio Montanari\n  event_name: \"Ruby Australia Melbourne Meetup February 2017\"\n  date: \"2017-02-22\"\n  published_at: \"2017-03-22T03:28:45Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"WRVPEKHOxuM\"\n\n- id: \"richard-mcgain-ruby-australia-melbourne-meetup-february-2017\"\n  title: \"Building Development Environments\"\n  raw_title: \"Building development environments - Richard Mcgain\"\n  speakers:\n    - Richard McGain\n  event_name: \"Ruby Australia Melbourne Meetup February 2017\"\n  date: \"2017-02-22\"\n  published_at: \"2017-03-22T03:28:20Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6KFeBYhE6aY\"\n\n- id: \"elle-meredith-ruby-australia-melbourne-meetup-may-2017\"\n  title: \"Product Design Sprints\"\n  raw_title: \"Elle Meredith - Product Design Sprints\"\n  speakers:\n    - Elle Meredith\n  event_name: \"Ruby Australia Melbourne Meetup May 2017\"\n  date: \"2017-05-03\"\n  published_at: \"2017-05-04T03:33:08Z\"\n  description: |-\n    Ruby meetup on 03/05/2017\n  video_provider: \"youtube\"\n  video_id: \"9J2nvU36vpE\"\n\n- id: \"john-sherwood-ruby-australia-melbourne-meetup-may-2017\"\n  title: \"Quitting Your Job as a Responsible Melbourne Rubyist\"\n  raw_title: \"Quitting your job as a responsible Melbourne rubyist - John Sherwood\"\n  speakers:\n    - John Sherwood\n  event_name: \"Ruby Australia Melbourne Meetup May 2017\"\n  date: \"2017-05-03\"\n  published_at: \"2017-05-04T07:20:02Z\"\n  description: |-\n    Melbourne Ruby 03/05/2017\n  video_provider: \"youtube\"\n  video_id: \"jSJD2He23-U\"\n\n- id: \"julian-doherty-ruby-australia-sydney-meetup\"\n  title: \"Fresh Redis\"\n  raw_title: \"Ruby Sydney: Fresh Redis by Julian Doherty\"\n  speakers:\n    - Julian Doherty\n  event_name: \"Ruby Australia Sydney Meetup\" # TODO: month/year\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T21:54:36Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Rs3j3nex9ws\"\n\n- id: \"steve-ringo-ruby-australia-sydney-meetup-january-2013\"\n  title: \"Being the Middleman\"\n  raw_title: \"Being the Middleman by Steve Ringo\"\n  speakers:\n    - Steve Ringo\n  event_name: \"Ruby Australia Sydney Meetup January 2013\"\n  date: \"2013-01-15\"\n  published_at: \"2017-05-22T21:55:46Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"hH2cNHJx1gw\"\n\n- id: \"julio-ody-ruby-australia-meetup\"\n  title: \"Build Smart\"\n  raw_title: \"Build Smart by Julio Ody\"\n  speakers:\n    - Julio Ody\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T21:56:07Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"s6kcHjlQiQs\"\n\n- id: \"andrew-grimm-ruby-australia-sydney-meetup\"\n  title: \"Memoirs of a Programmer\"\n  raw_title: \"Memoirs of a Programmer by Andrew Grimm\"\n  speakers:\n    - Andrew Grimm\n  event_name: \"Ruby Australia Sydney Meetup\" # TODO: month/year\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T21:56:50Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"1lH5ZGEAOR4\"\n\n- id: \"ben-hoskings-ruby-australia-meetup\"\n  title: \"Zeus\"\n  raw_title: \"Zeus by Ben Hoskings\"\n  speakers:\n    - Ben Hoskings\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T21:57:21Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"T2P2kCEFFho\"\n\n- id: \"mario-visic-ruby-australia-meetup\"\n  title: \"Cucumber\"\n  raw_title: \"Cucumber by Mario Visic\"\n  speakers:\n    - Mario Visic\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T22:00:02Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"aUzChRac_-8\"\n\n- id: \"jon-rowe-ruby-australia-meetup\"\n  title: \"Abusing the Router\"\n  raw_title: \"Abusing the Router by Jon Rowe\"\n  speakers:\n    - Jon Rowe\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T22:00:24Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"eaNsjOZIkrA\"\n\n- id: \"ivan-vanderbyl-ruby-australia-meetup\"\n  title: \"Building Crashlog.io\"\n  raw_title: \"Building Crashlog.io by Ivan Vanderbyl\"\n  speakers:\n    - Ivan Vanderbyl\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T22:01:02Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"xyay1EQYWes\"\n\n- id: \"andrew-grimm-ruby-australia-meetup\"\n  title: \"Wisp\"\n  raw_title: \"Wisp by Andrew Grimm\"\n  speakers:\n    - Andrew Grimm\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T22:01:50Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"SoOMFLMcnB8\"\n\n- id: \"gareth-townsend-ruby-australia-meetup\"\n  title: \"Rails 4\"\n  raw_title: \"Rails 4 by Gareth Townsend\"\n  speakers:\n    - Gareth Townsend\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T21:58:10Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"aH18NRuU5QE\"\n\n- id: \"andrei-gridnev-ruby-australia-melbourne-meetup\"\n  title: \"Best practices for testing in Rails\"\n  raw_title: \"Ruby Melbourne: Best practices for testing in Rails by Andrei Gridnev\"\n  speakers:\n    - Andrei Gridnev\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month/year\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T21:50:01Z\"\n  description: |-\n    March 2014\n  video_provider: \"youtube\"\n  video_id: \"SmADs6JyObI\"\n\n- id: \"matthew-delves-ruby-australia-melbourne-meetup\"\n  title: \"ActiveSupport Notifications\"\n  raw_title: \"Ruby Melbourne: ActiveSupport Notifications by Matthew Delves\"\n  speakers:\n    - Matthew Delves\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month/year\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T21:50:43Z\"\n  description: |-\n    March 2014\n  video_provider: \"youtube\"\n  video_id: \"b8b-Hj6b_NE\"\n\n- id: \"chris-daloisio-ruby-australia-melbourne-meetup\"\n  title: \"Rails and the client\"\n  raw_title: \"Ruby Melbourne: Rails and the client by Chris D'Aloisio\"\n  speakers:\n    - Chris D'Aloisio\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month/year\n  date: \"2017-05-22\" # TODO: use real date\n  published_at: \"2017-05-22T21:51:10Z\"\n  description: |-\n    March 2014\n  video_provider: \"youtube\"\n  video_id: \"3GmYW-d6Oew\"\n\n- id: \"ben-taylor-ruby-australia-sydney-meetup-september-2012\"\n  title: \"Location Based Gaming Platform\"\n  raw_title: \"Ruby Sydney: Location Based Gaming Platform by Ben Taylor\"\n  speakers:\n    - Ben Taylor\n  event_name: \"Ruby Australia Sydney Meetup September 2012\"\n  date: \"2012-09-01\" # TODO: use real date\n  published_at: \"2017-05-22T21:52:57Z\"\n  description: |-\n    September 2012\n  video_provider: \"youtube\"\n  video_id: \"FiDPT8VubTc\"\n\n- id: \"adam-rice-ruby-australia-meetup\"\n  title: \"Step away from Active Record\"\n  raw_title: \"Adam Rice -  Step away from Active Record\"\n  speakers:\n    - Adam Rice\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-06-01\" # TODO: use real date\n  published_at: \"2017-06-01T05:08:11Z\"\n  description: |-\n    Ruby meetup on 31/05/2017\n  video_provider: \"youtube\"\n  video_id: \"_S3mAnfGqGQ\"\n\n- id: \"simon-hildebrandt-ruby-australia-meetup\"\n  title: \"Grape with Swagger\"\n  raw_title: \"Simon Hildebrandt - Grape with Swagger\"\n  speakers:\n    - Simon Hildebrandt\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month May 2017\n  date: \"2017-05-01\" # TODO: use real date\n  published_at: \"2017-06-01T06:14:04Z\"\n  description: |-\n    Ruby meetup 31/05/2017\n  video_provider: \"youtube\"\n  video_id: \"-agspVmHrKg\"\n\n- id: \"lauren-hennessy-ruby-australia-meetup\"\n  title: \"Something totally unprepared and random\"\n  raw_title: \"Lauren Hennessy - Something totally unprepared and random\"\n  speakers:\n    - Lauren Hennessy\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month May 2017\n  date: \"2017-05-01\" # TODO: use real date\n  published_at: \"2017-06-01T05:24:19Z\"\n  description: |-\n    Ruby meetup 31/05/2017\n  video_provider: \"youtube\"\n  video_id: \"wAMryNKuSIY\"\n\n- id: \"anton-katunin-ruby-australia-meetup\"\n  title: \"Meta Presentation\"\n  raw_title: \"Anton Katunin - Meta Presentation\"\n  speakers:\n    - Anton Katunin\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month June 2017\n  date: \"2017-06-01\" # TODO: use real date\n  published_at: \"2017-07-03T01:28:40Z\"\n  description: |-\n    Ruby meetup - June 2017\n  video_provider: \"youtube\"\n  video_id: \"UEqm8lAaF8s\"\n\n- id: \"tom-adams-ruby-australia-meetup\"\n  title: \"GraphQL for fun & Profit\"\n  raw_title: \"Tom Adams - Graphql for fun & Profit\"\n  speakers:\n    - Tom Adams\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month June 2017\n  date: \"2017-06-01\" # TODO: use real date\n  published_at: \"2017-07-03T01:30:51Z\"\n  description: |-\n    Ruby meetup June 2017\n  video_provider: \"youtube\"\n  video_id: \"Tub3XMumQvA\"\n\n- id: \"michael-dawson-ruby-australia-meetup\"\n  title: \"The biggest cause of bugs in your application: `git commit`\"\n  raw_title: \"Michael Dawson - The biggest cause of bugs in your application: `git commit`\"\n  speakers:\n    - Michael Dawson\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month June 2017\n  date: \"2017-06-01\" # TODO: use real date\n  published_at: \"2017-07-03T01:30:14Z\"\n  description: |-\n    Ruby meetup June 2017\n  video_provider: \"youtube\"\n  video_id: \"JSfjV6-IAjQ\"\n\n- id: \"jaya-wijono-ruby-australia-melbourne-meetup-august-2017\"\n  title: \"Functional affairs in Ruby\"\n  raw_title: \"Jaya Wijono - Functional affairs in Ruby\"\n  speakers:\n    - Jaya Wijono\n  event_name: \"Ruby Australia Melbourne Meetup August 2017\"\n  date: \"2017-08-01\" # TODO: use real date\n  published_at: \"2017-09-08T00:50:06Z\"\n  description: |-\n    Ruby meetup - Melbourne August 2017\n  video_provider: \"youtube\"\n  video_id: \"TMCzv1fJ8yU\"\n\n- id: \"tom-ridge-ruby-australia-meetup\"\n  title: \"Your story matters\"\n  raw_title: \"Tom Ridge - Your story matters\"\n  speakers:\n    - Tom Ridge\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month August 2017\n  date: \"2017-08-01\" # TODO: use real date\n  published_at: \"2017-09-08T00:01:18Z\"\n  description: |-\n    Melbourne Ruby meetup - August 2017\n  video_provider: \"youtube\"\n  video_id: \"nChKjkG2NDw\"\n\n- id: \"ryan-bigg-ruby-australia-meetup\"\n  title: \"Designing the perfect coding test\"\n  raw_title: \"Ryan Bigg - Designing the perfect coding test\"\n  speakers:\n    - Ryan Bigg\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-10-30\" # TODO: use real date\n  published_at: \"2017-10-30T23:40:41Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DiYjDHKSH-Q\"\n\n- id: \"tom-gamon-ruby-australia-meetup\"\n  title: \"Dyslexia and Development\"\n  raw_title: \"Tom Gamon - Dyslexia and Development\"\n  speakers:\n    - Tom Gamon\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-10-31\" # TODO: use real date\n  published_at: \"2017-10-31T00:10:27Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"MO3TJsQ_hQo\"\n\n- id: \"melissa-kaulfuss-ruby-australia-meetup\"\n  title: \"Regex in Ruby\"\n  raw_title: \"Melissa Kaulfuss - Regex in Ruby\"\n  speakers:\n    - Melissa Kaulfuss\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-12-28\" # TODO: use real date\n  published_at: \"2017-12-28T05:13:00Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"dU97L1Jrji8\"\n\n- id: \"chen-zhao-ruby-australia-meetup\"\n  title: \"A programer's guide to Van Life\"\n  raw_title: \"Chen Zhao - A programer's guide to Van Life\"\n  speakers:\n    - Chen Zhao\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-12-28\" # TODO: use real date\n  published_at: \"2017-12-28T23:00:40Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"TvY7LJ6l3Mo\"\n\n- id: \"elle-meredith-ruby-australia-meetup\"\n  title: \"Rails anti-patterns\"\n  raw_title: \"Elle Meredith - Rails anti-patterns\"\n  speakers:\n    - Elle Meredith\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2017-12-28\" # TODO: use real date\n  published_at: \"2017-12-28T05:21:24Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"fU-mPNd-3AI\"\n\n- id: \"phil-nash-ruby-australia-melbourne-meetup-february-2018\"\n  title: \"Smaller is always better\"\n  raw_title: \"Phil Nash - Smaller is always better\"\n  speakers:\n    - Phil Nash\n  event_name: \"Ruby Australia Melbourne Meetup February 2018\"\n  date: \"2018-02-01\" # TODO: use real date\n  published_at: \"2018-03-14T06:16:44Z\"\n  description: |-\n    Ruby meetup. melbourne, Feb 2018\n  video_provider: \"youtube\"\n  video_id: \"mmtwp8RPPAA\"\n\n- id: \"andre-vidic-ruby-australia-melbourne-meetup-february-2018\"\n  title: \"Story telling for your codebase with Git\"\n  raw_title: \"Andre Vidic - Story telling for your codebase with Git\"\n  speakers:\n    - Andre Vidic\n  event_name: \"Ruby Australia Melbourne Meetup February 2018\"\n  date: \"2018-02-01\" # TODO: use real date\n  published_at: \"2018-03-14T06:36:40Z\"\n  description: |-\n    Melbourne ruby. Feb 2018\n  video_provider: \"youtube\"\n  video_id: \"7Zv3-h2AFKw\"\n\n- id: \"jaya-wijono-ruby-australia-melbourne-meetup-february-2018\"\n  title: \"Functional affairs in Ruby part II\"\n  raw_title: \"Jaya Wijono - Functional affairs in Ruby part II\"\n  speakers:\n    - Jaya Wijono\n  event_name: \"Ruby Australia Melbourne Meetup February 2018\"\n  date: \"2018-02-01\" # TODO: use real date\n  published_at: \"2018-03-15T04:11:09Z\"\n  description: |-\n    Ruby meetup. Melbourne Feb 2018\n  video_provider: \"youtube\"\n  video_id: \"OoXLy5tg9rw\"\n\n- id: \"rhiana-heath-ruby-australia-meetup\"\n  title: \"Presenting SVG graphs\"\n  raw_title: \"Rhiana Heath - Presenting SVG graphs\"\n  speakers:\n    - Rhiana Heath\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-05-30\" # TODO: use real date\n  published_at: \"2018-05-30T01:30:51Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"dDrdH_0BKLc\"\n\n- id: \"jeremy-kirkham-ruby-australia-meetup\"\n  title: \"GraphQL in Rails\"\n  raw_title: \"Jeremy Kirkham - GraphQL in Rails\"\n  speakers:\n    - Jeremy Kirkham\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-05-30\" # TODO: use real date\n  published_at: \"2018-05-30T01:42:55Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"CA5feVQ3bJI\"\n\n- id: \"selena-small-ruby-australia-meetup\"\n  title: \"Breaking builds & Breaking bones\"\n  raw_title: \"Selena Small - Breaking builds & Breaking bones\"\n  speakers:\n    - Selena Small\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-07-02\" # TODO: use real date\n  published_at: \"2018-07-02T00:02:45Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"7bTXuIBhwGI\"\n\n- id: \"michael-milewski-ruby-australia-meetup\"\n  title: \"Vi everywhere, what's your superpower?\"\n  raw_title: \"Michael Milewski - Vi everywhere, what's your superpower?\"\n  speakers:\n    - Michael Milewski\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-07-02\" # TODO: use real date\n  published_at: \"2018-07-02T00:05:14Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"l6dwu6cCfkM\"\n\n- id: \"anton-katunin-ruby-australia-meetup-2\"\n  title: \"Rails in real time\"\n  raw_title: \"Anton Katunin - Rails in real time\"\n  speakers:\n    - Anton Katunin\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-07-27\" # TODO: use real date\n  published_at: \"2018-07-27T04:24:37Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"hHYTC5cPhms\"\n\n- id: \"elle-meredith-ruby-australia-meetup-2\"\n  title: \"Composition over inheritance\"\n  raw_title: \"Elle Meredith - Composition over inheritance\"\n  speakers:\n    - Elle Meredith\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-07-27\" # TODO: use real date\n  published_at: \"2018-07-27T04:06:01Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"QKkyq1UE9eU\"\n\n- id: \"brendan-weibrecht-ruby-australia-meetup\"\n  title: \"Applied Event Sourcing in deX\"\n  raw_title: \"Brendan Weibrecht  - Applied Event Sourcing in deX\"\n  speakers:\n    - Brendan Weibrecht\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-10-12\" # TODO: use real date\n  published_at: \"2018-10-12T05:55:34Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"KOfG3BK2Ue8\"\n\n- id: \"phil-nash-ruby-australia-meetup\"\n  title: \"Fantastic Passwords and where to find them\"\n  raw_title: \"Phil Nash - Fantastic Passwords and where to find them\"\n  speakers:\n    - Phil Nash\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-10-12\" # TODO: use real date\n  published_at: \"2018-10-12T06:43:25Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"fu8zxwr7kNk\"\n\n- id: \"tom-dalling-ruby-australia-meetup\"\n  title: \"What are blocks\"\n  raw_title: \"Tom Dalling - What are blocks\"\n  speakers:\n    - Tom Dalling\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-10-12\" # TODO: use real date\n  published_at: \"2018-10-12T03:38:45Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"HR8iA4Hk1Ck\"\n\n- id: \"selena-small-ruby-australia-meetup-2\"\n  title: \"Pondering MVC\"\n  raw_title: \"Selena Small - Pondering MVC\"\n  speakers:\n    - Selena Small\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-10-12\" # TODO: use real date\n  published_at: \"2018-10-12T03:50:18Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Pw_w5vO1ZWg\"\n\n- id: \"tristan-penman-ruby-australia-meetup\"\n  title: \"Writing a Gem with native extensions\"\n  raw_title: \"Tristan Penman -  Writing a Gem with native extensions\"\n  speakers:\n    - Tristan Penman\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-10-12\" # TODO: use real date\n  published_at: \"2018-10-12T03:59:08Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"O9GjC5oh0o0\"\n\n- id: \"selena-small-ruby-australia-meetup-3\"\n  title: \"Failing for the right reason\"\n  raw_title: \"Selena Small and Michael Milewski - Failing for the right reason\"\n  speakers:\n    - Selena Small\n    - Michael Milewski\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-11-01\" # TODO: use real date\n  published_at: \"2018-11-01T01:46:05Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"p72EPNXbjiU\"\n\n- id: \"lachie-cox-ruby-australia-meetup\"\n  title: \"Know Thy App\"\n  raw_title: \"Lachie Cox - Know Thy App\"\n  speakers:\n    - Lachie Cox\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-12-18\" # TODO: use real date\n  published_at: \"2018-12-18T06:36:23Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"z0pfFSNIVJc\"\n\n- id: \"olga-goloshapova-ruby-australia-meetup\"\n  title: \"Testing Ruby Microservices - A War Story\"\n  raw_title: \"Olga Goloshapova - Testing Ruby Microservices - A War Story\"\n  speakers:\n    - Olga Goloshapova\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2018-12-18\" # TODO: use real date\n  published_at: \"2018-12-18T06:29:23Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"YvpbcVbXHUc\"\n\n- id: \"vanessa-nimmo-ruby-australia-meetup\"\n  title: \"Unpacking Rails Helpers magic\"\n  raw_title: \"Vanessa Nimmo -  Unpacking Rails Helpers magic\"\n  speakers:\n    - Vanessa Nimmo\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-02-28\" # TODO: use real date\n  published_at: \"2019-02-28T07:02:58Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"A6JQ9fUhtcA\"\n\n- id: \"nick-wolf-ruby-australia-meetup\"\n  title: \"Prying open Pry\"\n  raw_title: \"Nick Wolf - Prying open Pry\"\n  speakers:\n    - Nick Wolf\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-02-28\" # TODO: use real date\n  published_at: \"2019-02-28T06:52:31Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"TgC6YyKiWnI\"\n\n- id: \"drew-ruby-australia-meetup\"\n  title: \"Arguing with Ruby\"\n  raw_title: \"Drew - Arguing with Ruby\"\n  speakers:\n    - Drew\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-02-28\" # TODO: use real date\n  published_at: \"2019-02-28T07:11:32Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"me8CK_4TPpo\"\n\n- id: \"celia-king-ruby-australia-meetup\"\n  title: \"Knitting and TDD\"\n  raw_title: \"Celia King - Knitting and TDD\"\n  speakers:\n    - Celia King\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-02-28\" # TODO: use real date\n  published_at: \"2019-02-28T07:23:58Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Xhyn9YcwM1o\"\n\n- id: \"david-carlin-ruby-australia-meetup\"\n  title: \"Refactoring in Ruby\"\n  raw_title: \"David Carlin - Refactoring in Ruby\"\n  speakers:\n    - David Carlin\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-02-28\" # TODO: use real date\n  published_at: \"2019-02-28T07:31:06Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"HzxHBgsrBVY\"\n\n- id: \"ryan-bigg-ruby-australia-meetup-2\"\n  title: \"Magic Tricks in Ruby\"\n  raw_title: \"Ryan Bigg - Magic Tricks in Ruby\"\n  speakers:\n    - Ryan Bigg\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-02-28\" # TODO: use real date\n  published_at: \"2019-02-28T07:39:47Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"lSiD3LZanPI\"\n\n- id: \"michael-milewski-ruby-australia-meetup-2\"\n  title: \"Actionable Errors in Rails 6\"\n  raw_title: \"Michael Milewski - Actionable Errors in Rails 6\"\n  speakers:\n    - Michael Milewski\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-06-21\" # TODO: use real date\n  published_at: \"2019-06-21T06:45:14Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"f65Eu_vl7OI\"\n\n- id: \"xavier-shay-ruby-australia-meetup\"\n  title: \"Tiny Turing Toys: Tapes, States and Breaks\"\n  raw_title: \"Xavier Shay - Tiny Turing Toys: Tapes, States and Breaks\"\n  speakers:\n    - Xavier Shay\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-09-05\" # TODO: use real date\n  published_at: \"2019-09-05T08:22:07Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"JJ5oQ6bya-I\"\n\n- id: \"anton-katunin-ruby-australia-meetup-3\"\n  title: \"Rails as a static site generator\"\n  raw_title: \"Anton Katunin - Rails as a static site generator\"\n  speakers:\n    - Anton Katunin\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-09-05\" # TODO: use real date\n  published_at: \"2019-09-05T08:56:25Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"wgz2-zpyLvM\"\n\n- id: \"nick-wolf-ruby-australia-meetup-2\"\n  title: \"Avoiding arrest with Rubocop\"\n  raw_title: \"Nick Wolf  - Avoiding arrest with Rubocop\"\n  speakers:\n    - Nick Wolf\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-09-05\" # TODO: use real date\n  published_at: \"2019-09-05T07:24:37Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"PkZTlvLmpvw\"\n\n- id: \"michael-morris-ruby-australia-meetup\"\n  title: \"Making a game for Railscamp\"\n  raw_title: \"Michael Morris  - Making a game for Railscamp\"\n  speakers:\n    - Michael Morris\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-09-05\" # TODO: use real date\n  published_at: \"2019-09-05T07:52:52Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"L8Ql70FOWhE\"\n\n- id: \"michael-milewski-ruby-australia-meetup-3\"\n  title: \"My experience with TCR\"\n  raw_title: \"Michael Milewski - My experience with TCR\"\n  speakers:\n    - Michael Milewski\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-09-05\" # TODO: use real date\n  published_at: \"2019-09-05T08:12:21Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"OvtkD4O2dcE\"\n\n- id: \"chris-aitchison-ruby-australia-meetup\"\n  title: \"10 non code tips to be a better team member\"\n  raw_title: \"Chris Aitchison - 10 non code tips to be a better team member\"\n  speakers:\n    - Chris Aitchison\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-09-05\" # TODO: use real date\n  published_at: \"2019-09-05T08:21:34Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"kdJzevi0aMQ\"\n\n- id: \"phil-nash-ruby-australia-meetup-2\"\n  title: \"Servers? We don't need them\"\n  raw_title: \"Phil Nash - Servers? We don't need them\"\n  speakers:\n    - Phil Nash\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-11-11\" # TODO: use real date\n  published_at: \"2019-11-11T05:34:33Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8HcImvJpMEE\"\n\n- id: \"toby-nieboer-ruby-australia-meetup\"\n  title: \"Working Remotely\"\n  raw_title: \"Toby Nieboer - Working Remotely\"\n  speakers:\n    - Toby Nieboer\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-11-11\" # TODO: use real date\n  published_at: \"2019-11-11T05:29:57Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"P01gclPahxo\"\n\n- id: \"todo-ruby-australia-meetup\"\n  title: \"The Milewski family: How I created an interactive slide show\"\n  raw_title: \"The Milewski family - How I created an interactive slide show\"\n  speakers:\n    - TODO\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-11-11\" # TODO: use real date\n  published_at: \"2019-11-11T05:31:55Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"uIj-ipbPI3A\"\n\n- id: \"chris-aitchison-ruby-australia-meetup-2\"\n  title: \"Data democratisation at UP\"\n  raw_title: \"Chris Aitchison - Data democratisation at UP\"\n  speakers:\n    - Chris Aitchison\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2019-11-11\" # TODO: use real date\n  published_at: \"2019-11-11T05:34:06Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Rk31iOgJhJM\"\n\n- id: \"david-allen-ruby-australia-meetup\"\n  title: \"Enter the matrix\"\n  raw_title: \"David Allen - Enter the matrix\"\n  speakers:\n    - David Allen\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-03-05\" # TODO: use real date\n  published_at: \"2020-03-05T22:35:44Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"JAaSsZf7iuE\"\n\n- id: \"nick-wolf-ruby-australia-meetup-3\"\n  title: \"Committing to Overcommit\"\n  raw_title: \"Nick Wolf  - Committing to Overcommit\"\n  speakers:\n    - Nick Wolf\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-03-05\" # TODO: use real date\n  published_at: \"2020-03-05T23:31:11Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ECBfynL_BzU\"\n\n- id: \"celia-ruby-australia-meetup\"\n  title: \"Some historical things about time\"\n  raw_title: \"Celia - Some historical things about time\"\n  speakers:\n    - Celia\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-03-05\" # TODO: use real date\n  published_at: \"2020-03-05T23:40:16Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"91s0BMS5Jm0\"\n\n- id: \"dawn-e-collett-ruby-australia-meetup\"\n  title: \"This talk has been disabled (a talk on accessibility)\"\n  raw_title: \"Dawn E. Collett - This talk has been disabled (a talk on accessibility)\"\n  speakers:\n    - Dawn E. Collett\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-03-06\" # TODO: use real date\n  published_at: \"2020-03-06T00:43:30Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"vNj8ItVcwsE\"\n\n- id: \"pat-allan-ruby-australia-meetup\"\n  title: \"How to Make a Gem\"\n  raw_title: \"Pat Allan - How to Make a Gem\"\n  speakers:\n    - Pat Allan\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-03-25\" # TODO: use real date\n  published_at: \"2020-03-25T21:13:31Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jGQTP3gqQ1U\"\n\n- id: \"dawn-e-collett-ruby-australia-meetup-2\"\n  title: \"This Talk Has Been Disabled (with CC)\"\n  raw_title: \"Dawn E. Collett - This Talk Has Been Disabled (with CC)\"\n  speakers:\n    - \"Dawn E. Collett\"\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-03-31\" # TODO: use real date\n  published_at: \"2020-03-31T23:47:08Z\"\n  description: |-\n    A closed captioned version of Dawn Collett's talk from the February 2020 Melbourne Ruby Meetup\n  video_provider: \"youtube\"\n  video_id: \"wPlDNZtQ6QM\"\n\n- id: \"tracymusung-ruby-australia-sydney-meetup-june-2020\"\n  title: \"The most fun way to level up your team\"\n  raw_title: \"The most fun way to level up your team - ROROSyd June 2020\"\n  speakers:\n    - \"Tracy Mu Sung\"\n  event_name: \"Ruby Australia Sydney Meetup June 2020\"\n  date: \"2020-06-01\" # TODO: use real date\n  published_at: \"2020-06-21T02:53:59Z\"\n  description: |-\n    @TracyMuSung talking to us about running your own conference to help \"level up\" your team.\n  video_provider: \"youtube\"\n  video_id: \"_OFU-6_sOCk\"\n\n- id: \"hhemanth-ruby-australia-sydney-meetup-june-2020\"\n  title: \"Preparing for the AWS Solutions Architect Exam\"\n  raw_title: \"Why I started preparing for the AWS Solutions Architect Exam - ROROSyd June 2020\"\n  speakers:\n    - \"Hemanth Haridas\"\n  event_name: \"Ruby Australia Sydney Meetup June 2020\"\n  date: \"2020-06-01\" # TODO: use real date\n  published_at: \"2020-06-21T03:25:42Z\"\n  description: |-\n    Hemanth Haridas talks us through why he's preparing for the AWS Solutions Architect Exam\n  video_provider: \"youtube\"\n  video_id: \"rtMXLMeqMiA\"\n\n- id: \"rossandrewbaker-ruby-australia-sydney-meetup-june-2020\"\n  title: \"Exercism Challenge: Protein Translation\"\n  raw_title: \"Exercism Challenge: Protein Translation - ROROSyd June 2020\"\n  speakers:\n    - \"Ross A. Baker\"\n  event_name: \"Ruby Australia Sydney Meetup June 2020\"\n  date: \"2020-06-01\" # TODO: use real date\n  published_at: \"2020-06-21T03:31:26Z\"\n  description: |-\n    Ross Baker accepted the challenge of solving June's exercism challenge \"Protein Translation\"\n    https://exercism.io/tracks/ruby/exercises/protein-translation\n  video_provider: \"youtube\"\n  video_id: \"w9ajQhnTpJk\"\n\n- id: \"julian-pinzon-eslava-ruby-australia-meetup\"\n  title: \"View Component 101\"\n  raw_title: \"View Component 101 by Julián Pinzón Eslava\"\n  speakers:\n    - Julián Pinzón Eslava\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-07-21\" # TODO: use real date\n  published_at: \"2020-07-21T07:45:38Z\"\n  description: |-\n    Do you wish you could write React/Vue-like components without a single line of JS?\n\n    Introducing the View Component gem by the team at Github!\n\n    This 10-15 minute talk contains a quick intro to what view component is and how you can use it to clean up, preview and test components using plain, old and boring Ruby on Rails.\n  video_provider: \"youtube\"\n  video_id: \"Lzsb-Q5Lm9g\"\n\n- id: \"josh-price-ruby-australia-meetup\"\n  title: \"Working with Tailwind and SVG\"\n  raw_title: \"Working with Tailwind and SVG by Josh Price\"\n  speakers:\n    - Josh Price\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-07-22\" # TODO: use real date\n  published_at: \"2020-07-22T02:03:31Z\"\n  description: |-\n    I'm really loving Tailwind CSS for working server side without writing any CSS at all.\n\n    Inline SVGs are a real game changer for icons and vector drawings.\n\n    I've been doing this with Elixir and Phoenix but it applies just the same in a Rails app (or any other server side rendered web framework for that matter).\n  video_provider: \"youtube\"\n  video_id: \"o9Y_uL18wZ4\"\n\n- id: \"gael-jerop-ruby-australia-sydney-meetup-july-2020\"\n  title: \"Exercism Challenge: RNA Transcription\"\n  raw_title: \"Exercism Challenge: RNA Transcription - Gael Jerop - ROROSyd July 2020\"\n  speakers:\n    - Gael Jerop\n  event_name: \"Ruby Australia Sydney Meetup July 2020\"\n  date: \"2020-07-01\" # TODO: use real date\n  published_at: \"2020-07-26T02:59:31Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"B3fB6-4Fy7E\"\n\n- id: \"mathew-button-ruby-australia-sydney-meetup-july-2020\"\n  title: \"StimulusReflex - Insert Snappy Title Here\"\n  raw_title: \"Stimulus Reflex - Insert Snappy Title Here - Mathew Button - ROROSyd July 2020\"\n  speakers:\n    - Mathew Button\n  event_name: \"Ruby Australia Sydney Meetup July 2020\"\n  date: \"2020-07-01\" # TODO: use real date\n  published_at: \"2020-08-08T05:28:15Z\"\n  description: |-\n    A brief introduction to using stimulus reflex\n  video_provider: \"youtube\"\n  video_id: \"sawnSXFkDng\"\n\n- id: \"rafael-nunes-ruby-australia-sydney-meetup-august-2020\"\n  title: \"Circuit Breaker in Ruby with Circuitbox\"\n  raw_title: \"Circuit Breaker in Ruby with Circuitbox  - Rafael Nunes - ROROSyd August 2020\"\n  speakers:\n    - Rafael Nunes\n  event_name: \"Ruby Australia Sydney Meetup August 2020\"\n  date: \"2020-08-01\" # TODO: use real date\n  published_at: \"2020-08-22T07:43:29Z\"\n  description: |-\n    Rafael takes us through the circuit breaker design pattern, and it's implementation in ruby with the gem \"Circuit Box\"\n    https://github.com/yammer/circuitbox\n  video_provider: \"youtube\"\n  video_id: \"33l9ROqmapk\"\n\n- id: \"paul-tagell-ruby-australia-meetup\"\n  title: \"Automating your finances (and the Up API)\"\n  raw_title: \"Automating your finances (and the Up API)\"\n  speakers:\n    - Paul Tagell\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-09-15\" # TODO: use real date\n  published_at: \"2020-09-15T06:25:16Z\"\n  description: |-\n    A totally unsolicited bucket of tips relating specifically to managing money automatically by Paul Tagell\n  video_provider: \"youtube\"\n  video_id: \"AQVw0i-5tRc\"\n\n- id: \"nick-wolf-ruby-australia-meetup-4\"\n  title: \"Minimalism in your Home(directory)\"\n  raw_title: \"Minimalism in your Home(directory)\"\n  speakers:\n    - Nick Wolf\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-09-16\" # TODO: use real date\n  published_at: \"2020-09-16T23:27:48Z\"\n  description: |-\n    A short talk (5 - 10 minutes) about reducing the number of hidden files in your home directory by Nick Wolf\n  video_provider: \"youtube\"\n  video_id: \"NzvbcBaPhXc\"\n\n- id: \"dan-cheail-ruby-australia-meetup\"\n  title: \"A Request for Comments\"\n  raw_title: \"A Request for Comments\"\n  speakers:\n    - Dan Cheail\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-09-16\" # TODO: use real date\n  published_at: \"2020-09-16T07:07:21Z\"\n  description: |-\n    When did comments become a bad thing? A short exploration of why the tide of public opinion has turned against comments, why I believe it's unhelpful and a light smattering of opinion about how to leverage them to help you and your team succeed.\n\n     by Dan Cheail\n  video_provider: \"youtube\"\n  video_id: \"OEQkgZfMoZw\"\n\n- id: \"dan-draper-ruby-australia-meetup\"\n  title: \"Debugging Diversity in the Tech Industry\"\n  raw_title: \"Debugging Diversity in the Tech Industry\"\n  speakers:\n    - Dan Draper\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-09-16\" # TODO: use real date\n  published_at: \"2020-09-16T03:18:43Z\"\n  description: |-\n    The talk covers:\n\n    Defining the problem of diversity in tech\n    Defining what we mean by diversity\n    What folks can do to help improve diversity and inclusion (belonging even!) in tech\n    Its targetted more towards men as a sort of practical guide.\n\n    by Dan Draper\n  video_provider: \"youtube\"\n  video_id: \"n9nZmNmEutk\"\n\n- id: \"thesneakerdev-ruby-australia-sydney-meetup-october-2020\"\n  title: \"Twelve Days\"\n  raw_title: \"Exercism Challenge: Twelve Days - ROROSyd October 2020\"\n  speakers:\n    - Fin George\n  event_name: \"Ruby Australia Sydney Meetup October 2020\"\n  date: \"2020-10-01\" # TODO: use real date\n  published_at: \"2020-10-18T05:59:40Z\"\n  description: |-\n    @The_Sneaker_Dev took us through his solution to the \"twelve days\" exercism challenge\n  video_provider: \"youtube\"\n  video_id: \"rvuUWVHGXeA\"\n\n- id: \"waldowthedev-ruby-australia-sydney-meetup\"\n  title: \"Exercism Challenge: Matrix\"\n  raw_title: \"Exercism Challenge: Matrix - ROROSyd October 2020\"\n  speakers:\n    - Waldowthedev\n  event_name: \"Ruby Australia Sydney Meetup\" # TODO: month/year\n  date: \"2020-10-18\" # TODO: use real date\n  published_at: \"2020-10-18T06:02:05Z\"\n  description: |-\n    @Waldowthedev takes us through his solution to the \"Matrix\" exercism challenge\n  video_provider: \"youtube\"\n  video_id: \"uE_FGwPjvi8\"\n\n- id: \"nathan-othedev-ruby-australia-sydney-meetup-october-2020\"\n  title: \"Binary Search Tree\"\n  raw_title: \"Exercism Challenge: Binary Search Tree - ROROSyd October 2020\"\n  speakers:\n    - Nathan OtheDev\n  event_name: \"Ruby Australia Sydney Meetup October 2020\"\n  date: \"2020-10-01\" # TODO: use real date\n  published_at: \"2020-10-18T05:52:16Z\"\n  description: |-\n    @NathanOtheDev takes us through his solution to the Binary Search Tree exercism challenge\n  video_provider: \"youtube\"\n  video_id: \"-m4UvFDy3Hw\"\n\n- id: \"carlos-rojas-ruby-australia-meetup\"\n  title: \"Handling errors in Ruby using functional programming\"\n  raw_title: \"Handling errors in Ruby using functional programming by Carlos Rojas\"\n  speakers:\n    - Carlos Rojas\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-11-25\" # TODO: use real date\n  published_at: \"2020-11-25T04:11:17Z\"\n  description: |-\n    A beginner-friendly talk with a brief description of monads in the Ruby ecosystem.\n  video_provider: \"youtube\"\n  video_id: \"aKGxvwnD9Lw\"\n\n- id: \"michael-milewski-ruby-australia-meetup-4\"\n  title: \"Arduino on Rails\"\n  raw_title: \"Arduino on Rails by Michael Milewski\"\n  speakers:\n    - Michael Milewski\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-11-25\" # TODO: use real date\n  published_at: \"2020-11-25T03:56:25Z\"\n  description: |-\n    So what has Arduino, an open-source electronics hardware platform that reads and sets things using electrical voltages, got to do with *Rails, a web-application framework that includes everything for database-baked web apps, got to do with each other?\n\n    well nothing, but I will present some of my experiments bringing them together.\n  video_provider: \"youtube\"\n  video_id: \"ASWD4EZqylU\"\n\n- id: \"maedi-ruby-australia-meetup\"\n  title: \"Reflective testing\"\n  raw_title: \"Reflective testing by maedi\"\n  speakers:\n    - Maedi Prichard\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-11-25\" # TODO: use real date\n  published_at: \"2020-11-25T03:59:14Z\"\n  description: |-\n    Introduce the concept of reflective testing and demo Reflekt, a new gem which makes it possible:\n    https://github.com/refIekt/reflekt\n  video_provider: \"youtube\"\n  video_id: \"yO_0JdcOND8\"\n\n- id: \"amit-gaur-ruby-australia-meetup\"\n  title: \"Intro to Crystal\"\n  raw_title: \"Intro to Crystal - Amit Gaur\"\n  speakers:\n    - Amit Gaur\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-11-29\" # TODO: use real date\n  published_at: \"2020-11-29T11:52:51Z\"\n  description: |-\n    Amit Gaur - @websymphony, takes us through an intro to the Crystal programming language using ruby as a comparison.\n  video_provider: \"youtube\"\n  video_id: \"1TLSC16Hf_4\"\n\n- id: \"clint-gibler-ruby-australia-meetup\"\n  title: \"Code-base specific lints for correctness and security\"\n  raw_title: \"How to write code-base specific lints for correctness and security using Semgrep - Clint Gibler\"\n  speakers:\n    - Clint Gibler\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-11-29\" # TODO: use real date\n  published_at: \"2020-11-29T06:38:56Z\"\n  description: |-\n    Clint Gibler - @clintgibler\n  video_provider: \"youtube\"\n  video_id: \"IfXxV1nzfJA\"\n\n- id: \"mike-rogers-ruby-australia-meetup\"\n  title: \"Exercism Challenge: Darts\"\n  raw_title: \"Exercism Challenge: Darts - Mike Rogers\"\n  speakers:\n    - Mike Rogers\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-11-29\" # TODO: use real date\n  published_at: \"2020-11-29T06:38:53Z\"\n  description: |-\n    Mike Rogers - @MikeRogers0 takes on the \"Darts\" Exercism Challenge\n  video_provider: \"youtube\"\n  video_id: \"LRbHT9Th7ZM\"\n\n- id: \"jacin-yan-ruby-australia-meetup\"\n  title: \"Exercism Challenge: Acronym\"\n  raw_title: \"Exercism Challenge: Acronym - Jacin Yan\"\n  speakers:\n    - Jacin Yan\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2020-11-29\" # TODO: use real date\n  published_at: \"2020-11-29T06:41:18Z\"\n  description: |-\n    Jacin Yan - @jacinjiyan takes on the \"Acronym\" Exercism challenge\n  video_provider: \"youtube\"\n  video_id: \"m3AOpnpqDVI\"\n\n- id: \"bence-fulop-ruby-australia-meetup\"\n  title: \"Exercism Challenge: Space Age\"\n  raw_title: \"Exercism Challenge: Space Age - Bence Fulop\"\n  speakers:\n    - Bence Fulop\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-01-15\" # TODO: use real date\n  published_at: \"2021-01-15T10:55:58Z\"\n  description: |-\n    Bence Fulop takes us through his solution to the Exercism challenge Space Age\n  video_provider: \"youtube\"\n  video_id: \"rQ-JFE1mE74\"\n\n- id: \"nathan-odonnell-ruby-australia-meetup\"\n  title: \"Pokemon Ruby In Ruby\"\n  raw_title: \"Pokemon Ruby In Ruby - Nathan ODonnell\"\n  speakers:\n    - Nathan ODonnell\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-01-15\" # TODO: use real date\n  published_at: \"2021-01-15T11:02:20Z\"\n  description: |-\n    Take a look at how Nathan has attempted to recreate Pokemon Ruby in Ruby. This game is entirely made in ruby and played entirely in the terminal using emojis!\n  video_provider: \"youtube\"\n  video_id: \"OpBo5NZQsmc\"\n\n- id: \"sam-hammond-ruby-australia-meetup\"\n  title: \"Exercism Challenge: The Tournament\"\n  raw_title: \"Exercism Challenge: The Tournament - Sam Hammond\"\n  speakers:\n    - Sam Hammond\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-01-15\" # TODO: use real date\n  published_at: \"2021-01-15T11:06:53Z\"\n  description: |-\n    Sam Hammon takes us through his solution to the Exercism challenge \"The Tournament\"\n  video_provider: \"youtube\"\n  video_id: \"fceyL62py1E\"\n\n- id: \"lang-sharpe-ruby-australia-meetup\"\n  title: \"Introduction To TimeZones\"\n  raw_title: \"Introduction To TimeZones - Lang Sharpe\"\n  speakers:\n    - Lang Sharpe\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-01-15\" # TODO: use real date\n  published_at: \"2021-01-15T11:10:57Z\"\n  description: |-\n    Lang Sharpe helps clear the air about how to work with timezones\n  video_provider: \"youtube\"\n  video_id: \"FfUay3iBSOc\"\n\n- id: \"bence-fulop-ruby-australia-meetup-2\"\n  title: \"Exercism Challenge: ISBN Verifier\"\n  raw_title: \"Exercism Challenge: ISBN Verifier by Bence Fulop\"\n  speakers:\n    - Bence Fulop\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-01-26\" # TODO: use real date\n  published_at: \"2021-01-26T22:03:19Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"OFym5QlfalU\"\n\n- id: \"mathieu-longe-ruby-australia-meetup\"\n  title: \"Exercism Challenge: Tournament\"\n  raw_title: \"Exercism Challenge: Tournament by Mathieu Longe\"\n  speakers:\n    - Mathieu Longe\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-01-26\" # TODO: use real date\n  published_at: \"2021-01-26T22:11:38Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"GnLMSTG8v08\"\n\n- id: \"elle-meredith-ruby-australia-meetup-3\"\n  title: \"Work-life balance - what it is and how to get it\"\n  raw_title: \"Work-life balance - what it is and how to get it by Elle Meredith\"\n  speakers:\n    - Elle Meredith\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-01-26\" # TODO: use real date\n  published_at: \"2021-01-26T22:31:45Z\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"l5o9gq50ZcE\"\n\n- id: \"rafael-nunes-ruby-australia-meetup\"\n  title: \"N+1 & Eager loading & Beyond\"\n  raw_title: \"N+1 & Eager loading & Beyond - Rafael Nunes\"\n  speakers:\n    - Rafael Nunes\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-03-14\" # TODO: use real date\n  published_at: \"2021-03-14T05:59:49Z\"\n  description: |-\n    Rafael walks us through what the N+1 problem, how to identify it and most importantly, how to fix it. As well as some gems that can help stop the problem before it goes to production\n  video_provider: \"youtube\"\n  video_id: \"5ou4kZtgnoY\"\n\n- id: \"sugendran-ganess-ruby-australia-meetup\"\n  title: \"Exercism: Simple Linked List\"\n  raw_title: \"Exercism: Simple Linked List - Sugendran Ganess\"\n  speakers:\n    - Sugendran Ganess\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-03-21\" # TODO: use real date\n  published_at: \"2021-03-21T05:36:57Z\"\n  description: |-\n    An implementation of a linked list in ruby\n  video_provider: \"youtube\"\n  video_id: \"igZt_W-AZ1U\"\n\n- id: \"lang-sharpe-ruby-australia-meetup-2\"\n  title: \"What is CrystalBall\"\n  raw_title: \"What is CrystalBall - Lang Sharpe\"\n  speakers:\n    - Lang Sharpe\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-03-21\" # TODO: use real date\n  published_at: \"2021-03-21T05:36:56Z\"\n  description: |-\n    Lang talks about the CrystalBall gem and how it might help speed up your unit tests\n  video_provider: \"youtube\"\n  video_id: \"3NleoGVrDQ0\"\n\n- id: \"mike-rogers-ruby-australia-meetup-2\"\n  title: \"Docker for Developer Happiness\"\n  raw_title: \"Docker for Developer Happiness - Mike Rogers\"\n  speakers:\n    - Mike Rogers\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-03-21\" # TODO: use real date\n  published_at: \"2021-03-21T05:36:56Z\"\n  description: |-\n    Mike shows us how to be productive as a developer using Docker to run your development environment\n  video_provider: \"youtube\"\n  video_id: \"FGEcfRE58Ag\"\n\n- id: \"michael-milewski-ruby-australia-meetup-5\"\n  title: \"View Components in the Wild\"\n  raw_title: \"View Components in the Wild by Michael Milewski\"\n  speakers:\n    - Michael Milewski\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-03-28\" # TODO: use real date\n  published_at: \"2021-03-28T10:26:57Z\"\n  description: |-\n    Just some examples of how we at Fresho are using View Components to test rails views and help us decompose the front end, it will be wild! With the better design through composability, leading to simplifying testing and more consistent front ends.\n\n    presented from https://github.com/failure-driven/view-components-in-the-wild\n  video_provider: \"youtube\"\n  video_id: \"ISWuPcCoChw\"\n\n- id: \"mike-rogers-ruby-australia-meetup-3\"\n  title: \"Ruby on Rails & Service Workers (PWA)\"\n  raw_title: \"Ruby on Rails & Service Workers (PWA) by Mike Rogers\"\n  speakers:\n    - Mike Rogers\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-03-28\" # TODO: use real date\n  published_at: \"2021-03-28T11:04:01Z\"\n  description: |-\n    I've been messing about a little recently with Service Workers & Rails, the end result is you can have your app enter a \"read-only\" mode when the user goes offline (e.g. they lose network coverage). The cool thing, is it'll work without requiring converting to an SPA, so you can do when you're setup using Server Side Rendering (e.g. turbolinks + ERB templates).\n\n    The main gist of the talk will be use webpacker-pwa & Workbox, or if you're using sprokets serviceworker-rails.\n  video_provider: \"youtube\"\n  video_id: \"FjNDrPDjm4o\"\n\n- id: \"dana-scheider-ruby-australia-meetup\"\n  title: \"The Joy of Docs: Technical Writing for Developers and Engineers\"\n  raw_title: \"The Joy of Docs: Technical Writing for Developers and Engineers by Dana Scheider\"\n  speakers:\n    - Dana Scheider\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-04-13\" # TODO: use real date\n  published_at: \"2021-04-13T23:42:03Z\"\n  description: |-\n    In this talk, I discuss communication, specifically technical writing, why it's important, and how to improve your skills. Emphasis is on identifying and empathising with your audience. The talk does not strictly cover the writing process as it is taught in schools, but rather focusses on orienting oneself towards readers' needs when writing technical documents or producing other technical writing. The information in this talk is applicable to any kind of technical writing, from commit messages to requests for comment (RFCs), as well as technical writing that is not strictly a part of a technical document (e.g., writing in an email to stakeholders about the status of development on a project).\n\n\n    Why It's Important\n\n    Bad technical writing is a huge waste of time. Every developer who's worked in the industry for any length of time has encountered vague and unhelpful documentation and seen how much time they spend trying to find information that should've been in the docs in the first place. Engineers who read RFCs and other longer-form documents may notice these documents often don't give adequate context or define terms, leading to more time spent on research rather than focussing on the tasks at hand.\n  video_provider: \"youtube\"\n  video_id: \"l8pFr1y14f8\"\n\n- id: \"michael-morris-ruby-australia-meetup-2\"\n  title: \"How (and why) to write a GraphQL API in ruby\"\n  raw_title: \"How (and why) to write a GraphQL API in ruby by Michael Morris\"\n  speakers:\n    - Michael Morris\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-04-14\" # TODO: use real date\n  published_at: \"2021-04-14T00:18:07Z\"\n  description: |-\n    How (and why) to write a GraphQL API in ruby\n    Choose Your Own Adventure edition.\n\n    Michael leads us through:\n    - Pros and cons of RESTful API vs GraphQL\n    - What it looks like\n    - What you can do with it\n    - Authentication\n    - Handling validation\n    - Pagination\n  video_provider: \"youtube\"\n  video_id: \"D9Ng7QXsBo4\"\n\n- id: \"mike-rogers-ruby-australia-meetup-4\"\n  title: \"Seeding Data in Ruby on Rails\"\n  raw_title: \"Seeding Data in Ruby on Rails - Mike Rogers\"\n  speakers:\n    - Mike Rogers\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-05-05\" # TODO: use real date\n  published_at: \"2021-05-05T12:58:55Z\"\n  description: |-\n    Mike will walk us through what rails seeds are and why they're important, and more importantly how to do them well\n  video_provider: \"youtube\"\n  video_id: \"ZSZVUUQvyKI\"\n\n- id: \"hemanth-haridas-ruby-australia-meetup\"\n  title: \"Github Actions & Rails\"\n  raw_title: \"Github Actions & Rails - Hemanth Haridas\"\n  speakers:\n    - Hemanth Haridas\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-05-05\" # TODO: use real date\n  published_at: \"2021-05-05T12:56:16Z\"\n  description: |-\n    Hemanth will introduce Github actions and show us how to get started with a rails app using Github actions\n  video_provider: \"youtube\"\n  video_id: \"iq0SfgKLIvY\"\n\n- id: \"akash-chhetri-ruby-australia-meetup\"\n  title: \"React On Rails\"\n  raw_title: \"React On Rails - Akash Chhetri\"\n  speakers:\n    - Akash Chhetri\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-05-18\" # TODO: use real date\n  published_at: \"2021-05-18T22:49:23Z\"\n  description: |-\n    Akash shows us how to integrate ReactJS with Rails using a REST api, he talks about the benefit and drawback of using React compared to a templating languages like ERB\n\n\n\n    @akash_research\n  video_provider: \"youtube\"\n  video_id: \"7c-nMTpl2E0\"\n\n- id: \"ceels-ruby-australia-meetup\"\n  title: \"Indexes\"\n  raw_title: \"Indexes - Ceels\"\n  speakers:\n    - Ceels\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-05-19\" # TODO: use real date\n  published_at: \"2021-05-19T23:57:57Z\"\n  description: |-\n    in this lightning talk, Ceels rants about an octopus and show us her way to think about array indexes\n  video_provider: \"youtube\"\n  video_id: \"K1G1iqDAzU8\"\n\n- id: \"debbie-teakle-ruby-australia-meetup\"\n  title: \"Making the most of the developer market\"\n  raw_title: \"Making the most of the developer market - Debbie Teakle\"\n  speakers:\n    - Debbie Teakle\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-06-14\" # TODO: use real date\n  published_at: \"2021-06-14T12:52:43Z\"\n  description: |-\n    Whether you're job searching or not! Debbie takes us through a detailed look at the current job market and shows us how we as developers can take advantage of it.\n  video_provider: \"youtube\"\n  video_id: \"Tq2_6_ndLqU\"\n\n- id: \"hemanth-haridas-ruby-australia-meetup-2\"\n  title: \"Exercism: Robot Simulator\"\n  raw_title: \"Exercism: Robot Simulator - Hemanth Haridas\"\n  speakers:\n    - Hemanth Haridas\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-06-29\" # TODO: use real date\n  published_at: \"2021-06-29T11:34:09Z\"\n  description: |-\n    Hemanth has done the robot simulator Exercism challenge from https://exercism.io/\n  video_provider: \"youtube\"\n  video_id: \"vkncK9MYIG0\"\n\n- id: \"adam-rice-ruby-australia-meetup-2\"\n  title: \"Introduction to Mutation Testing\"\n  raw_title: \"Introduction to Mutation Testing - Adam Rice\"\n  speakers:\n    - Adam Rice\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-06-29\" # TODO: use real date\n  published_at: \"2021-06-29T11:32:23Z\"\n  description: |-\n    A brief intro into mutation testing using the Mutant gem https://github.com/mbj/mutant\n  video_provider: \"youtube\"\n  video_id: \"rRWWKAygZEg\"\n\n- id: \"nick-wolf-ruby-australia-meetup-5\"\n  title: \"Talking Tech to the Not Technical\"\n  raw_title: \"Talking Tech to the Not Technical - Nick Wolf\"\n  speakers:\n    - Nick Wolf\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-07-05\" # TODO: use real date\n  published_at: \"2021-07-05T11:02:58Z\"\n  description: |-\n    Nick wolf show us the benefit of breaking down hard concepts using analogy by walking us through an example on how one could explain to their uncle Bob how how a web page loads without using any technical jargon\n  video_provider: \"youtube\"\n  video_id: \"x2BAHxT11io\"\n\n- id: \"pat-allan-ruby-australia-meetup-2\"\n  title: \"Altering DNS with Ruby is a Terrible Idea... But Let's Do It Anyway\"\n  raw_title: \"Altering DNS with Ruby is a Terrible Idea... But Let's Do It Anyway - Pat Allan\"\n  speakers:\n    - Pat Allan\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-07-05\" # TODO: use real date\n  published_at: \"2021-07-05T11:23:22Z\"\n  description: |-\n    Pat Allan demonstrate how you can alter DNS using some of the new Ruby features... You might need it someday\n  video_provider: \"youtube\"\n  video_id: \"3H6YUi68mdA\"\n\n- id: \"akash-chhetri-ruby-australia-meetup-2\"\n  title: \"How to Give a Coding Challenge\"\n  raw_title: \"How to Give a Coding Challenge - Akash Chhetri\"\n  speakers:\n    - Akash Chhetri\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-07-05\" # TODO: use real date\n  published_at: \"2021-07-05T11:08:25Z\"\n  description: |-\n    Akash uses his recent experience in interviewing for a new position to show us the mental modal he developed to complete coding challenges and explain what examiners want to see.\n  video_provider: \"youtube\"\n  video_id: \"gfPQcWgMng4\"\n\n- id: \"david-carlin-ruby-australia-meetup-2\"\n  title: \"How to Stop i18n Getting Messy\"\n  raw_title: \"How to Stop i18n Getting Messy - David Carlin\"\n  speakers:\n    - David Carlin\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-07-05\" # TODO: use real date\n  published_at: \"2021-07-05T11:24:28Z\"\n  description: |-\n    David shares with us what he has learnt over the years working with internationalization and what new tricks he is using to enforce good practice around i18n in his new team.\n  video_provider: \"youtube\"\n  video_id: \"t6ZMVW1FHes\"\n\n- id: \"nadia-vu-ruby-australia-meetup\"\n  title: \"Tips on how to get more from your salary negotiation\"\n  raw_title: \"Tips on how to get more from your salary negotiation - Nadia Vu\"\n  speakers:\n    - Nadia Vu\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-08-14\" # TODO: use real date\n  published_at: \"2021-08-14T07:26:21Z\"\n  description: |-\n    Nadia & Co tell us how you can negotiate a higher salary, sometime it's not just about money.\n    A Great Q&A follows\n  video_provider: \"youtube\"\n  video_id: \"Kbh7xkKAOR8\"\n\n- id: \"micheal-millewski-ruby-australia-meetup\"\n  title: \"Data pipelines in Rails and Postgres\"\n  raw_title: \"Data pipelines in Rails and Postgres - Micheal Millewski\"\n  speakers:\n    - Micheal Millewski\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-08-14\" # TODO: use real date\n  published_at: \"2021-08-14T07:10:06Z\"\n  description: |-\n    The nuts and bolts of how to insert and upsert data quickly in Rails and Postgresql using both the gem activerecord-import and Rails 6 new insert_all and upsert_all command. Also some thoughts on how to do data processing in Ruby using the chaining then to compose data transformations.\n  video_provider: \"youtube\"\n  video_id: \"cCm7-zagbwY\"\n\n- id: \"david-smith-ruby-australia-meetup\"\n  title: \"Action Cable 101\"\n  raw_title: \"Action Cable 101 - David Smith\"\n  speakers:\n    - David Smith\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-08-29\" # TODO: use real date\n  published_at: \"2021-08-29T10:49:26Z\"\n  description: |-\n    David shares some of the main concepts in action cable, how it can be used and what to consider if you want to implement action cable\n  video_provider: \"youtube\"\n  video_id: \"XDR9Jf1HEZk\"\n\n- id: \"dan-solo-ruby-australia-meetup\"\n  title: \"A Rails Journey: From Paramedicine to Surfing Mountains\"\n  raw_title: \"A Rails Journey: From Paramedicine to Surfing Mountains - Dan Solo\"\n  speakers:\n    - Dan Solo\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-08-29\" # TODO: use real date\n  published_at: \"2021-08-29T10:57:23Z\"\n  description: |-\n    Dan takes us on his adventure to becoming a developer, from EMT to Ski Resort Manager/Recruiter\n  video_provider: \"youtube\"\n  video_id: \"rTx51yiirVM\"\n\n- id: \"david-carlin-ruby-australia-meetup-3\"\n  title: \"Being the Most Valuable Engineer in your Team\"\n  raw_title: \"Being the Most Valuable Engineer in your Team - David Carlin & co\"\n  speakers:\n    - David Carlin\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-08-30\" # TODO: use real date\n  published_at: \"2021-08-30T09:23:55Z\"\n  description: |-\n    David Carlin leads on discussion on how one can be the most valuable engineer in their team, and it's not just about code!\n    This is an open discussion with the group  floating a few ideas and takeaways.\n  video_provider: \"youtube\"\n  video_id: \"Ht9YsXrM-D8\"\n\n# TODO: Add event entry and talk without video recording\n# - id: \"private-video-ruby-australia-meetup\"\n#   title: \"Private video\"\n#   raw_title: \"Private video\"\n#   speakers:\n#     - Private video\n#   event_name: \"Ruby Australia Meetup\" # TODO: city/month\n#   date: \"TODO\"\n#   published_at: \"2021-09-03\"\n#   description: |-\n#     This video is private.\n#   video_provider: \"youtube\"\n#   video_id: \"iWtecg-eQxI\"\n\n- id: \"akash-chhetri-ruby-australia-meetup-3\"\n  title: \"Stripe Integration for Dummies\"\n  raw_title: \"Stripe Integration for Dummies - Akash Chhetri\"\n  speakers:\n    - Akash Chhetri\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-09-30\" # TODO: use real date\n  published_at: \"2021-09-30T23:32:45Z\"\n  description: |-\n    Akash shows us how to integrate Stripe with Rails and explains the pitfall he fell into whilst trying to do it himself\n  video_provider: \"youtube\"\n  video_id: \"DJupgTe0rIs\"\n\n- id: \"julian-pinzon-eslava-ruby-australia-meetup-2\"\n  title: \"7+ ActiveModel Magic Tricks You Didn't Know About\"\n  raw_title: \"7+ ActiveModel Magic Tricks You Didn't Know About - Julián Pinzón Eslava\"\n  speakers:\n    - Julián Pinzón Eslava\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-09-30\" # TODO: use real date\n  published_at: \"2021-09-30T23:40:18Z\"\n  description: |-\n    Julian reveals to us how some of the Rails magic works by diving into the activeModel gem and related modules. Whilst doing so, he unearth 7+ tricks that you can also use to make your code better and explains the one thing that single-handedly made him a better developer\n  video_provider: \"youtube\"\n  video_id: \"h0HF5-OiMqE\"\n\n- id: \"michael-milewski-ruby-australia-meetup-6\"\n  title: \"Stop Rubocop Fix-up Commits - Like Ever!\"\n  raw_title: \"Stop Rubocop Fix-up Commits - Like Ever! - Michael Milewski\"\n  speakers:\n    - Michael Milewski\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-09-30\" # TODO: use real date\n  published_at: \"2021-09-30T23:49:08Z\"\n  description: |-\n    We all love rubocop ❤️ - to keep consistent ruby styling\n    Like Nick Wolf told us back in https://www.youtube.com/watch?v=PkZTlvLmpvw\n\n    but breaking the build for a missing comma costs companies millions 💵\n    why not be the developer who builds tools for other developers and prevents this from 📣 \"ever happening again! like ever!\"\n\n    In this 5-minute lightning talk, I will show you how to safeguard your team from ever wasting time on broken builds due to a rubocop linting failure - almost ever. I will also include some real examples of how cool rubocop is as well as how to get started in a legacy codebase adding rubocop for the first time. Finishing it off with another \"classic fixup commit\" you can fix for your team!\n  video_provider: \"youtube\"\n  video_id: \"G-vhAwVo0Ns\"\n\n- id: \"simon-hildebrandt-ruby-australia-meetup-2\"\n  title: \"Live Query Streams in RethinkDB\"\n  raw_title: \"Live Query Streams in RethinkDB - Simon Hildebrandt\"\n  speakers:\n    - Simon Hildebrandt\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-11-02\" # TODO: use real date\n  published_at: \"2021-11-02T03:18:08Z\"\n  description: |-\n    Simon explains to us the shortcomings he has encounter with traditional databases when it comes to live querying. Using RethinkDB, he is able to unlock new potentials and he shows us how you would do live queries in RethinkDB\n  video_provider: \"youtube\"\n  video_id: \"k0t5FbGfH6k\"\n\n- id: \"tom-dalling-ruby-australia-meetup-2\"\n  title: \"Nailing Your Live Coding Job Interview in Ruby\"\n  raw_title: \"Nailing Your Live Coding Job Interview in Ruby - Tom Dalling\"\n  speakers:\n    - Tom Dalling\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-11-02\" # TODO: use real date\n  published_at: \"2021-11-02T03:00:22Z\"\n  description: |-\n    Live coding over Zoom has become a popular way to do technical interviews with job candidates these days. This talk covers how I would handle this kind of interview, with tips and suggestions.\n  video_provider: \"youtube\"\n  video_id: \"7cyx_88m2CM\"\n\n- id: \"nick-wolf-ruby-australia-meetup-6\"\n  title: \"Unpacking the Committee\"\n  raw_title: \"Unpacking the Committee - Nick Wolf\"\n  speakers:\n    - Nick Wolf\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-11-02\" # TODO: use real date\n  published_at: \"2021-11-02T03:01:06Z\"\n  description: |-\n    Nick Wolf, current president of Ruby Australia, talks to us about what the committee does and how YOU can be involved\n  video_provider: \"youtube\"\n  video_id: \"iCJzzH5-DAw\"\n\n- id: \"dan-moore-ruby-australia-meetup\"\n  title: \"JWTs, what ruby developers need to know\"\n  raw_title: \"JWTs, what ruby developers need to know - Dan Moore\"\n  speakers:\n    - Dan Moore\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-11-22\" # TODO: use real date\n  published_at: \"2021-11-22T11:38:06Z\"\n  description: |-\n    Dan Moore takes us through JSON Web Tokens (JWTs). JWTs are portable, stateless identifiers. They are often used to control access to APIs, but can be used in other contexts as well. The problem they solve is how to share identity details in a scalable, secure way.\n\n    In this talk, Dan will dive deep into that problem, as well as how JWTs should be used, both in generation and in consumption. He'll also cover what kind of signing algorithms are available, when you should avoid a JWT and how to revoke them. He'll also include working code samples showing how to generate or consume JWTs as well as some common Ruby libraries that can be used.\n  video_provider: \"youtube\"\n  video_id: \"W2NHW6BVzz8\"\n\n- id: \"pat-allan-ruby-australia-meetup-3\"\n  title: \"A Random Assortment of Code\"\n  raw_title: \"A Random Assortment of Code - Pat Allan\"\n  speakers:\n    - Pat Allan\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-12-17\" # TODO: use real date\n  published_at: \"2021-12-17T10:43:15Z\"\n  description: |-\n    Pat shares some code snippets from different project's he's worked. They range from adding type checking and validation to ENV Vars to adding helper methods when using web mock.\n\n    - Settings initializer using dry-system: https://gist.github.com/pat/5feba9bf0c122ec5f9c2bf6de5f24c21\n    - Webmock helper methods: https://gist.github.com/pat/faa47847a89dc2bf1cb257ed35715164\n    - Gem for the Render API: https://github.com/pat/render_api\n  video_provider: \"youtube\"\n  video_id: \"N4FfH6sPMs8\"\n\n- id: \"elle-meredith-ruby-australia-meetup-4\"\n  title: 'A blessing in default/\"So Fetch\"'\n  raw_title: 'A blessing in default/\"So Fetch\" - Elle Meredith'\n  speakers:\n    - Elle Meredith\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-12-17\" # TODO: use real date\n  published_at: \"2021-12-17T10:44:43Z\"\n  description: |-\n    Elle shows us the benefits of using defaults to help reduce the number of parameters we need for method definitions but also to help simply code by way of reducing code branches.\n  video_provider: \"youtube\"\n  video_id: \"ynJqPdQBx_k\"\n\n- id: \"anthony-langhorne-ruby-australia-meetup\"\n  title: \"Up's Monolith Story\"\n  raw_title: \"Up's Monolith Story - Anthony Langhorne\"\n  speakers:\n    - Anthony Langhorne\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2021-12-17\" # TODO: use real date\n  published_at: \"2021-12-17T10:40:53Z\"\n  description: |-\n    Anthony takes us through how Up have structured their monolith's codebase to make it easier to approach and build out new features.\n  video_provider: \"youtube\"\n  video_id: \"Og8KsKmUo_8\"\n\n- id: \"matt-wang-ruby-australia-meetup\"\n  title: \"Introduction to ROD\"\n  raw_title: \"Introduction to ROD - Matt Wang\"\n  speakers:\n    - Matt Wang\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-03-06\" # TODO: use real date\n  published_at: \"2022-03-06T11:19:56Z\"\n  description: |-\n    Matt takes us through a tool he's been developing to help deploy applications to the cloud with ease. ROD helps deploying apps to kubernetes but also handles scaffolding new rails apps to be read to deploy out of the box.\n  video_provider: \"youtube\"\n  video_id: \"BM1Dymafsi0\"\n\n- id: \"group-discussion-ruby-australia-meetup\"\n  title: \"How to nurture your career as a ruby developer\"\n  raw_title: \"How to nurture your career as a ruby developer - Group Discussion\"\n  speakers:\n    - Group Discussion\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-03-06\" # TODO: use real date\n  published_at: \"2022-03-06T11:21:47Z\"\n  description: |-\n    ROROMelb opened the floor for a group discussion to chat about \"How to nuture your career as a ruby developer\"\n  video_provider: \"youtube\"\n  video_id: \"-_0__lMTpts\"\n\n- id: \"david-carlin-ruby-australia-meetup-4\"\n  title: \"Image Compression\"\n  raw_title: \"Image Compression - David Carlin\"\n  speakers:\n    - David Carlin\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-03-06\" # TODO: use real date\n  published_at: \"2022-03-06T11:23:21Z\"\n  description: |-\n    David digs into different image formats and what they're good for. A bit of a deep dive into how some of the formats work (DCT, chroma-subsampling etc). And the future of images on the web.\n  video_provider: \"youtube\"\n  video_id: \"VvQb_jf7Zhs\"\n\n- id: \"julian-pizon-ruby-australia-meetup\"\n  title: \"Building apps with turbo and stimulus\"\n  raw_title: \"Building apps with turbo and stimulus - Julián Pizon\"\n  speakers:\n    - Julián Pizon\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-03-07\" # TODO: use real date\n  published_at: \"2022-03-07T09:15:41Z\"\n  description: |-\n    Juli takes us through what's involved when you want to build an app with Hotwire. Juli discusses the various pieces of turbo, Turbo Drive, Turbo Frames and Turbo Streams. As well as where stimulus JS fits into all of it.\n  video_provider: \"youtube\"\n  video_id: \"bmELTNa04p0\"\n\n- id: \"allen-hsu-ruby-australia-meetup\"\n  title: \"It's dangerous to go alone\"\n  raw_title: \"It's dangerous to go alone - Allen Hsu\"\n  speakers:\n    - Allen Hsu\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-05-02\" # TODO: use real date\n  published_at: \"2022-05-02T12:08:07Z\"\n  description: |-\n    Allen shows us some techniques to help us find our way around a new code base.\n  video_provider: \"youtube\"\n  video_id: \"UsDlzCFVi_U\"\n\n- id: \"todo-ruby-australia-meetup-2\"\n  title: \"ROROnline - Round Table Discussion\"\n  raw_title: \"ROROnline - Round Table Discussion\"\n  speakers:\n    - TODO\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-05-25\" # TODO: use real date\n  published_at: \"2022-05-25T11:08:54Z\"\n  description: |-\n    ROROnline organised a round table discussion, the topics include:\n\n    - What's important for you in your manager?\n    - What things do you ask to change in a contract?\n    - What's the next thing you want to do with your career, and what do you think you have to do to get there?\n    - Chat about your side projects\n  video_provider: \"youtube\"\n  video_id: \"9_LvFrIXpYY\"\n\n- id: \"adel-smee-ruby-australia-meetup\"\n  title: \"How to pick a new employer\"\n  raw_title: \"How to pick a new employer - Adel Smee\"\n  speakers:\n    - Adel Smee\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-06-05\" # TODO: use real date\n  published_at: \"2022-06-05T10:05:26Z\"\n  description: |-\n    Adel shows us some of the qualities to consider when you're thinking of changing jobs. From \"Did you meet anyone in the interview process you can learn from\" to asking about the potential company's \"Money Pressures\" there will be something to take away for everyone in this talk.\n  video_provider: \"youtube\"\n  video_id: \"G_TW5LaM6S0\"\n\n- id: \"dan-draper-ruby-australia-meetup-2\"\n  title: \"Encrypting Activerecord Models\"\n  raw_title: \"Encrypting Activerecord Models - Dan Draper\"\n  speakers:\n    - Dan Draper\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-06-05\" # TODO: use real date\n  published_at: \"2022-06-05T03:47:31Z\"\n  description: |-\n    Dan share's how to set up ActiveRecord EncryptedRecord in Rails 7, what security considerations to make and some bonus tips including how to encrypt non-string fields.\n  video_provider: \"youtube\"\n  video_id: \"Hc52LTZx5kI\"\n\n- id: \"yasmin-archibald-ruby-australia-meetup\"\n  title: \"Was this a terrible terrible mistake?\"\n  raw_title: \"Was this a terrible terrible mistake? - Yasmin Archibald\"\n  speakers:\n    - Yasmin Archibald\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-10-25\" # TODO: use real date\n  published_at: \"2022-10-25T11:33:20Z\"\n  description: |-\n    Yasmin shares her ongoing journey in becoming a jr developer.\n  video_provider: \"youtube\"\n  video_id: \"K6RJzkKTqNg\"\n\n- id: \"michael-milewski-ruby-australia-meetup-7\"\n  title: \"Experimental Methods in Sidekiq\"\n  raw_title: \"Experimental Methods in Sidekiq - Michael Milewski\"\n  speakers:\n    - Michael Milewski\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-11-16\" # TODO: use real date\n  published_at: \"2022-11-16T05:16:23Z\"\n  description: |-\n    Michael Milewski sharing his experimental methods in a jobs system and processes called Sidekiq\n  video_provider: \"youtube\"\n  video_id: \"bnoaiBXsWok\"\n\n- id: \"justin-tan-ruby-australia-meetup\"\n  title: \"Of Errors and Memes\"\n  raw_title: \"Of Errors and Memes  - Justin Tan\"\n  speakers:\n    - Justin Tan\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-11-16\" # TODO: use real date\n  published_at: \"2022-11-16T05:35:39Z\"\n  description: |-\n    Justin Tan shares some of his valuable lessons from a General Assembly Software Engineering Immersive course. Yes, it involves errors and memes.\n  video_provider: \"youtube\"\n  video_id: \"lQ26rWCQdhI\"\n\n- id: \"igor-kapkov-ruby-australia-meetup\"\n  title: \"Testing in Production: there is a better way\"\n  raw_title: \"Testing in Production: there is a better way - Igor Kapkov\"\n  speakers:\n    - Igor Kapkov\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2022-12-16\" # TODO: use real date\n  published_at: \"2022-12-16T05:42:04Z\"\n  description: |-\n    Testing and refactoring! Igor Kapkov discusses these two core topics of the world of software.\n  video_provider: \"youtube\"\n  video_id: \"MkUs2EB65rQ\"\n\n- id: \"katie-mclaughlin-ruby-australia-meetup\"\n  title: \"Present like a pro\"\n  raw_title: \"Present like a pro - Katie McLaughlin\"\n  speakers:\n    - Katie McLaughlin\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2023-02-13\" # TODO: use real date\n  published_at: \"2023-02-13T07:44:27Z\"\n  description: |-\n    Katie McLaughlin on how to be a professional (and a superstar) on giving public talks!\n  video_provider: \"youtube\"\n  video_id: \"kHneB15WhXc\"\n\n- id: \"john-sherwood-ruby-australia-meetup\"\n  title: \"Running an app in 30 languages\"\n  raw_title: \"Running an app in 30 languages - John Sherwood\"\n  speakers:\n    - John Sherwood\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2023-02-13\" # TODO: use real date\n  published_at: \"2023-02-13T07:31:45Z\"\n  description: |-\n    John Sherwood sharing his experiences in creating and running an app in 30 languages!\n  video_provider: \"youtube\"\n  video_id: \"46jjEpvWxZE\"\n\n- id: \"justin-ruby-australia-meetup\"\n  title: \"Faster Rails\"\n  raw_title: '\"Faster Rails\" - Justin'\n  speakers:\n    - Justin\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2023-04-17\" # TODO: use real date\n  published_at: \"2023-04-17T02:59:06Z\"\n  description: |-\n    Justin shares his tips for performance monitoring and the most common ways to improve response times.\n  video_provider: \"youtube\"\n  video_id: \"HLwEgSzK7So\"\n\n- id: \"tarun-ruby-australia-meetup\"\n  title: \"The Multiverse of Madness\"\n  raw_title: '\"The Multiverse of Madness\" - Tarun'\n  speakers:\n    - Tarun\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2023-04-17\" # TODO: use real date\n  published_at: \"2023-04-17T02:44:22Z\"\n  description: |-\n    Tarun teaches us how to manage state complexity across multiple databases like a true sorcerer supreme.\n  video_provider: \"youtube\"\n  video_id: \"QZnLmpeXRi0\"\n\n- id: \"paul-ruby-australia-sydney-meetup-april-2023\"\n  title: \"Intro to Stenography Coding\"\n  raw_title: '\"Intro to Stenography Coding\" - Paul'\n  speakers:\n    - Paul Fioravanti\n  event_name: \"Ruby Australia Sydney Meetup April 2023\"\n  date: \"2023-04-11\"\n  published_at: \"2023-04-17T03:24:48Z\"\n  description: |-\n    Paul introduces us to stenography: shorthand writing that you may have seen used by court reporters and captioners. He shows us how steno can be used for coding in Ruby.\n  video_provider: \"youtube\"\n  video_id: \"3W9_k2CXrXE\"\n\n- id: \"anton-panteleev-ruby-australia-meetup\"\n  title: \"How to make an Awesome GitHub Landing Page\"\n  raw_title: \"How to make an awesome github landing page - Anton Panteleev\"\n  speakers:\n    - Anton Panteleev\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2023-04-25\" # TODO: use real date\n  published_at: \"2023-04-25T06:42:43Z\"\n  description: |-\n    Anton Panteleev shares some tips and tricks to make your GitHub landing page stand out and making it look awesome!\n  video_provider: \"youtube\"\n  video_id: \"oDmt4_xcVf0\"\n\n- id: \"dave-allie-ruby-australia-meetup\"\n  title: \"Black hat Ruby - creating a malicious ruby gem\"\n  raw_title: \"Black hat Ruby - creating a malicious ruby gem - Dave Allie\"\n  speakers:\n    - Dave Allie\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2023-04-25\" # TODO: use real date\n  published_at: \"2023-04-25T06:59:15Z\"\n  description: |-\n    Dave Allie on demonstrating the process of making a (for fun only) malicious ruby gem.\n\n    Note that this is strictly for educational and entertainment purposes only!\n  video_provider: \"youtube\"\n  video_id: \"Ywx3fEogb1k\"\n\n- id: \"adam-rice-ruby-australia-melbourne-meetup-may-2023\"\n  title: \"10 Minutes with YJIT\"\n  raw_title: \"10 Minutes with YJIT - Adam Rice\"\n  speakers:\n    - Adam Rice\n  event_name: \"Ruby Australia Melbourne Meetup May 2023\"\n  date: \"2023-05-05\"\n  published_at: \"2023-05-28T07:21:38Z\"\n  description: |-\n    Want to know what YJIT is all about? Adam Rice will give you a run down on it!\n  video_provider: \"youtube\"\n  video_id: \"JQmOIjrLruQ\"\n\n- id: \"tristan-penman-ruby-australia-melbourne-meetup-may-2023\"\n  title: \"Roll your own Ruby type checking\"\n  raw_title: \"Roll your own Ruby type checking - Tristan Penman\"\n  speakers:\n    - Tristan Penman\n  event_name: \"Ruby Australia Melbourne Meetup May 2023\"\n  date: \"2023-05-05\"\n  published_at: \"2023-05-28T07:30:05Z\"\n  description: |-\n    Tristan Penman on how to roll your very own Ruby type check!\n  video_provider: \"youtube\"\n  video_id: \"ghpn8m1odwI\"\n\n- id: \"michael-milewski-ruby-australia-melbourne-meetup-may-2023\"\n  title: \"A collection of RubyConf talks experiences\"\n  raw_title: \"A collection of RubyConf talks experiences - Michael Milewski\"\n  speakers:\n    - Michael Milewski\n  event_name: \"Ruby Australia Melbourne Meetup May 2023\"\n  date: \"2023-05-31\"\n  published_at: \"2023-06-25T02:10:45Z\"\n  description: |-\n    Ever wondered how does it feels like to deliver a streak of successful RubyConf talks? Michael Milewski is here to share some of this views, experiences, and pearls of wisdom on RubyConf talks journey.\n  video_provider: \"youtube\"\n  video_id: \"XzkGg5ddfEo\"\n\n- id: \"adam-rice-ruby-australia-melbourne-meetup\"\n  title: \"The Commit Narrative\"\n  raw_title: \"The Commit Narrative - Adam Rice\"\n  speakers:\n    - Adam Rice\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month\n  date: \"2023-06-25\" # TODO: use real date\n  published_at: \"2023-06-25T02:01:03Z\"\n  description: |-\n    Often the diary of git histories explains the what, but not much of why, which often puzzles developers with the mystery of commit reasons.\n\n    Here Adam Rice will talk on ways to penn the chronicles of your code.\n  video_provider: \"youtube\"\n  video_id: \"J3yu8VgWLO0\"\n\n- id: \"anton-panteleev-ruby-australia-melbourne-meetup-june-2023\"\n  title: \"Observability and OpenTelemetry\"\n  raw_title: \"Observability and OpenTelemetry - Anton Panteleev\"\n  speakers:\n    - Anton Panteleev\n  event_name: \"Ruby Australia Melbourne Meetup June 2023\"\n  date: \"2023-06-28\"\n  published_at: \"2023-07-25T07:23:20Z\"\n  description: |-\n    Anton Panteleev is back again presenting why observability in programming is a hot and important topic, and how does OpenTelemetry enables effective observability for developers.\n  video_provider: \"youtube\"\n  video_id: \"kmnyIO--rbE\"\n\n- id: \"selena-small-ruby-australia-melbourne-meetup-june-2023\"\n  title: \"Dev vs Dev Smackdown\"\n  raw_title: \"Dev vs Dev Smackdown - Selena Small and Michael Milewski\"\n  speakers:\n    - Selena Small\n    - Michael Milewski\n  event_name: \"Ruby Australia Melbourne Meetup June 2023\"\n  date: \"2023-06-28\"\n  published_at: \"2023-07-25T07:17:38Z\"\n  description: |-\n    A fun and interactive talk that engages the audiences on voting for their favourite programming practices / paradigm!\n  video_provider: \"youtube\"\n  video_id: \"LiWpQS9XfI4\"\n\n- id: \"daniel-nguyen-ruby-australia-meetup\"\n  title: \"Hanami 2.0 an alternative to Rails\"\n  raw_title: \"Hanami 2.0 an alternative to Rails - Daniel Nguyen\"\n  speakers:\n    - Daniel Nguyen\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2023-08-10\" # TODO: use real date\n  published_at: \"2023-08-10T04:35:29Z\"\n  description: |-\n    Danniel walks us through his early learnings of the Hanami framework and how it differs from Rails. He looks at how Hanami handles providers, dependency injection and the repository pattern.\n  video_provider: \"youtube\"\n  video_id: \"PEU2XcnGdlw\"\n\n- id: \"winston-lau-ruby-australia-meetup-august-2023\"\n  title: \"Minimax for Ultimate Tic Tac Toe\"\n  raw_title: \"Minimax for Ultimate Tic Tac Toe - Winston Lau\"\n  speakers:\n    - Winston Lau\n  event_name: \"Ruby Australia Meetup August 2023\" # TODO: city\n  date: \"2023-08-08\"\n  published_at: \"2023-08-10T02:31:16Z\"\n  description: |-\n    Winston Lau is back again sharing with us his take on the minimax algorithm with alpha-beta pruning in ruby.\n  video_provider: \"youtube\"\n  video_id: \"ZxOpnW3olfs\"\n\n- id: \"matt-hood-ruby-australia-melbourne-meetup\"\n  title: \"How FHIR is tackling a wicked problem with technical, social and political solution\"\n  raw_title: \"How FHIR is tackling a wicked problem with technical, social and political solution - Matt Hood\"\n  speakers:\n    - Matt Hood\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month\n  date: \"2023-08-20\" # TODO: use real date\n  published_at: \"2023-08-20T04:48:45Z\"\n  description: |-\n    There is a big problem in the healthcare industry, and FHIR is making great progress in solving that problem. Curious to know what FHIR is? Matt Hood will bring you a journey on what FHIR is, what it does, and the exciting possibilities it can deliver.\n  video_provider: \"youtube\"\n  video_id: \"YvOmkbeIe9o\"\n\n- id: \"thomas-himawan-ruby-australia-melbourne-meetup\"\n  title: \"Tips for New / Junior Developers\"\n  raw_title: \"Tips for new / junior developers - Thomas Himawan\"\n  speakers:\n    - Thomas Himawan\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month\n  date: \"2023-08-20\" # TODO: use real date\n  published_at: \"2023-08-20T04:58:44Z\"\n  description: |-\n    Thomas Himawan shares is his experiences and tips for struggling new / junior devs. A video you do not want to miss if you are seeking solid advice as a budding junior!\n  video_provider: \"youtube\"\n  video_id: \"HPtvqeVY0tY\"\n\n- id: \"ryan-bigg-ruby-australia-melbourne-meetup\"\n  title: \"A production bug - 26 years in the making\"\n  raw_title: \"A production bug - 26 years in the making - Ryan Bigg\"\n  speakers:\n    - Ryan Bigg\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month\n  date: \"2023-08-20\" # TODO: use real date\n  published_at: \"2023-08-20T04:51:22Z\"\n  description: |-\n    Ryan Bigg shares his encounter and solution for a production bug, that involves tracing the history of software development to fully understand the 'how it happened' and 'why it happened' for this bug.\n  video_provider: \"youtube\"\n  video_id: \"q_mCZABhJcc\"\n\n- id: \"michael-pope-ruby-australia-melbourne-meetup\"\n  title: 'Creating a Ruby Game: \"Metal Warrior: Search for Valhalla\"'\n  raw_title: \"Creating a ruby game: “Metal Warrior: Search for Valhalla” - Michael Pope, Daniel Curtis\"\n  speakers:\n    - Michael Pope\n    - Daniel Curtis\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month\n  date: \"2023-09-26\" # TODO: use real date\n  published_at: \"2023-09-26T07:11:03Z\"\n  description: |-\n    Michael and Daniel shares his experience on building a game using DragonRuby engine, which is a video you will want to watch if you are interesting in making your own game using ruby!\n  video_provider: \"youtube\"\n  video_id: \"z2qQUTFIEzo\"\n\n- id: \"rian-mcguire-ruby-australia-melbourne-meetup\"\n  title: \"But why does it work\"\n  raw_title: \"But why does it work - Rian McGuire\"\n  speakers:\n    - Rian McGuire\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month\n  date: \"2023-09-26\" # TODO: use real date\n  published_at: \"2023-09-26T07:13:18Z\"\n  description: |-\n    For such a magical framework like Rails, Rian will share his secrets and strategies on how to entangle the sorceries of Rails, and help us understand how and why it actually all works!\n  video_provider: \"youtube\"\n  video_id: \"eNgYVlkiRJs\"\n\n- id: \"selena-small-ruby-australia-melbourne-meetup\"\n  title: \"Unleashing the power of pair presenting\"\n  raw_title: \"Unleashing the power of pair presenting - Selena Small\"\n  speakers:\n    - Selena Small\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month\n  date: \"2023-09-01\" # TODO: use real date\n  published_at: \"2023-10-25T01:30:12Z\"\n  description: |-\n    Selena Small shares her experiences on the power of pair presenting, which will eventually elevate your conference impact. Why do it alone when you can share the fun and power of presenting with another!\n  video_provider: \"youtube\"\n  video_id: \"8dlbSd-Y_cw\"\n\n- id: \"tony-hansord-ruby-australia-melbourne-meetup-october-2023\"\n  title: \"Final Project Showcase with Academy Xi Bootcamp\"\n  raw_title: \"Final Project Showcase with Academy Xi Bootcamp - Tony Hansord\"\n  speakers:\n    - Tony Hansord\n  event_name: \"Ruby Australia Melbourne Meetup October 2023\"\n  date: \"2023-10-25\"\n  published_at: \"2023-11-06T04:29:07Z\"\n  description: |-\n    Tony showcases his very functional, practical, yet designed with finesse final project with Academy Xi bootcamp. A video you would not want to miss out if you are looking for inspirations!\n  video_provider: \"youtube\"\n  video_id: \"H2PILTYGuM8\"\n\n- id: \"michael-milewski-ruby-australia-melbourne-meetup-october-2023\"\n  title: \"Thoughts on Environment Variables\"\n  raw_title: \"Thoughts on Environment Variables - Michael Milewski\"\n  speakers:\n    - Michael Milewski\n  event_name: \"Ruby Australia Melbourne Meetup October 2023\"\n  date: \"2023-10-25\"\n  published_at: \"2023-11-06T04:27:53Z\"\n  description: |-\n    Michael Milewski shares his thoughts on environment variables, and the various strategies you can implement on managing secrets.\n  video_provider: \"youtube\"\n  video_id: \"Pf-IrWRm-UE\"\n\n- id: \"anton-panteleev-ruby-australia-melbourne-meetup\"\n  title: \"Big O Complexity on Job Search\"\n  raw_title: \"Big O Complexity on Job Search - Anton Panteleev\"\n  speakers:\n    - Anton Panteleev\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month\n  date: \"2023-11-06\" # TODO: use real date\n  published_at: \"2023-11-06T04:28:05Z\"\n  description: |-\n    If you are wondering how to ace on your job search, look no further because Anton will share his greatest tips and tricks on how to score a job even in this trying times!\n  video_provider: \"youtube\"\n  video_id: \"_mrF0pp8LIE\"\n\n- id: \"anton-katunin-ruby-australia-melbourne-meetup\"\n  title: \"Modular Monoliths with Rails Engines\"\n  raw_title: \"Modular Monoliths with Rails Engines - Anton Katunin\"\n  speakers:\n    - Anton Katunin\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month\n  date: \"2024-01-25\" # TODO: use real date\n  published_at: \"2024-01-25T00:08:45Z\"\n  description: |-\n    Want to know more about Rails Engines? This will be a video you would not want to miss, as Anton shares his knowledge on how to architect your system in a more efficient manner utilizing rails engines.\n  video_provider: \"youtube\"\n  video_id: \"weW4FFomi5Q\"\n\n- id: \"adam-rice-ruby-australia-melbourne-meetup-2\"\n  title: \"Processing DMARC reports via Action Mailbox\"\n  raw_title: \"Processing DMARC reports via Action Mailbox - Adam Rice\"\n  speakers:\n    - Adam Rice\n  event_name: \"Ruby Australia Melbourne Meetup\" # TODO: month\n  date: \"2024-02-21\" # TODO: use real date\n  published_at: \"2024-02-21T04:12:48Z\"\n  description: |-\n    Adam Rice on  how to process and handle DMARC (Domain-based Message Authentication, Reporting & Conformance) reports, via rails' Action Mailbox.\n  video_provider: \"youtube\"\n  video_id: \"FgrNHf_8kN8\"\n\n- id: \"kj-tsanaktsidis-ruby-australia-melbourne-meetup-january-2024\"\n  title: \"Fibers in Ruby\"\n  raw_title: \"Fibers in Ruby - KJ Tsanaktsidis\"\n  speakers:\n    - KJ Tsanaktsidis\n  event_name: \"Ruby Australia Melbourne Meetup January 2024\"\n  date: \"2024-01-25\"\n  published_at: \"2024-02-21T08:42:17Z\"\n  description: |-\n    Curious on what are Fibers in Ruby, what it does and why should you know about Fibers? KJ Tsanaktsidis gives a great cover on this interesting co-routine Ruby feature.\n  video_provider: \"youtube\"\n  video_id: \"dh46btPI3xg\"\n\n- id: \"michael-milewski-ruby-australia-meetup-8\"\n  title: \"Hosting Rails App from Home\"\n  raw_title: \"Hosting rails app from home - Michael Milewski\"\n  speakers:\n    - Michael Milewski\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2024-02-22\"\n  published_at: \"2024-03-24T08:17:58Z\"\n  description: |-\n    Can you host your rails application from home? Of course you can! Michael will show you the hows and whys of hosting your desired rails application from the convenience of your own home.\n  video_provider: \"youtube\"\n  video_id: \"BeG0CeyHRqQ\"\n\n- id: \"john-sherwood-ruby-australia-meetup-2\"\n  title: \"The Economics of Ruby\"\n  raw_title: \"The Economics of Ruby - John Sherwood\"\n  speakers:\n    - John Sherwood\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2024-04-19\" # TODO: use real date\n  published_at: \"2024-04-19T07:46:25Z\"\n  description: |-\n    John Sherwood presents his findings on the current economy of our favourite programming language, Ruby!\n  video_provider: \"youtube\"\n  video_id: \"ydU3WvLoXpY\"\n\n- id: \"rian-mcguire-ruby-australia-melbourne-meetup-march-2024\"\n  title: \"One Billion Rows in Ruby\"\n  raw_title: \"One billion rows in Ruby - Rian McGuire\"\n  speakers:\n    - Rian McGuire\n  event_name: \"Ruby Australia Melbourne Meetup March 2024\"\n  date: \"2024-03-28\"\n  published_at: \"2024-04-19T07:51:47Z\"\n  description: |-\n    Rian McGuire presents his journey on a challenge about processing a billion rows in Ruby, which is a video you wouldn't want to miss if you are interested in optimization!\n  video_provider: \"youtube\"\n  video_id: \"evvoWsP8o5Q\"\n\n- id: \"anton-panteleev-ruby-australia-meetup-2\"\n  title: \"Demystifying Rails\"\n  raw_title: \"Dissecting Rails - Anton Panteleev\"\n  speakers:\n    - Anton Panteleev\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2024-05-21\" # TODO: use real date\n  published_at: \"2024-05-21T09:58:39Z\"\n  description: |-\n    Anton tears and dissects apart Rails down to it's components, and showing you what are some of the wonderful parts that make today's Rails.\n  video_provider: \"youtube\"\n  video_id: \"LavkZM_CQME\"\n  slides_url: \"https://friendlyantz.me/demystifying-rails\"\n\n- id: \"simon-hildebrandt-ruby-australia-melbourne-meetup-may-2024\"\n  title: \"Pagination with Ruby\"\n  raw_title: \"Pagination with Ruby - Simon Hildebrandt\"\n  speakers:\n    - Simon Hildebrandt\n  event_name: \"Ruby Australia Melbourne Meetup May 2024\"\n  date: \"2024-05-23\"\n  published_at: \"2024-06-27T04:16:48Z\"\n  description: |-\n    Simon Hidebrandt on using Ruby to explain a popular new approach to accessing and displaying data, without the staleness issues of traditional pagination - cursors! Learn the basic concepts, and find out why this approach is popular in modern toolkits like GraphQL.\n  video_provider: \"youtube\"\n  video_id: \"J5RSqgl6GlY\"\n\n- id: \"adam-rice-ruby-australia-meetup-3\"\n  title: \"Laravel, meet my friend Turbo\"\n  raw_title: \"Laravel, meet my friend Turbo - Adam Rice\"\n  speakers:\n    - Adam Rice\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month\n  date: \"2024-06-27\"\n  published_at: \"2024-07-23T10:06:23Z\"\n  description: |-\n    Adam Rice on how you can integrate Turbo to your Laravel backend, and why they could make a good combo.\n  video_provider: \"youtube\"\n  video_id: \"QtJeilx1czI\"\n\n- id: \"dan-laush-ruby-australia-meetup\"\n  title: \"The Pinkest Pink\"\n  raw_title: \"The Pinkest Pink - Dan Laush\"\n  speakers:\n    - Dan Laush\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month # TODO city/month\n  date: \"2024-08-13\" # TODO: use real date\n  published_at: \"2024-08-13T11:23:35Z\"\n  description: |-\n    An expert in front-end development, Dan Laush gives a colorful, vibrant talk (no pun intended) on which set of colors you can utilize on your application to get the most spice out of it!\n  video_provider: \"youtube\"\n  video_id: \"hid13bPyeEk\"\n\n- id: \"nick-wolf-ruby-australia-meetup-7\"\n  title: \"Being a Good Male Ally\"\n  raw_title: \"Being a Good Male Ally - Nick Wolf\"\n  speakers:\n    - Nick Wolf\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month # TODO city/month\n  date: \"2024-08-13\" # TODO: use real date\n  published_at: \"2024-08-13T11:20:36Z\"\n  description: |-\n    The president of Ruby Australia, Nick Wolf, giving an important talk on some of the ways you can try to be an exceptional, yet compassionate male ally. One that will cultivate a positive culture for the team and the organization.\n  video_provider: \"youtube\"\n  video_id: \"qPeUwyZb-OI\"\n\n- id: \"helen-stonehouse-ruby-australia-melbourne-meetup-august-2024\"\n  title: \"My Career Change: Nothing is What it Seems\"\n  raw_title: \"My Career Change: Nothing is What it Seems - Helen Stonehouse\"\n  speakers:\n    - Helen Stonehouse\n  event_name: \"Ruby Australia Melbourne Meetup August 2024\"\n  date: \"2024-08-22\"\n  published_at: \"2024-09-25T11:13:39Z\"\n  description: |-\n    Helen Stonehouse on giving a very insightful talk on her career change journey, which provides some pearls of wisdom to inspire others to make the change!\n  video_provider: \"youtube\"\n  video_id: \"8F3oJlLq4Nw\"\n\n- id: \"chris-oliver-ruby-australia-melbourne-meetup-august-2024\"\n  title: \"Rails Engines in 20 minutes\"\n  raw_title: \"Rails Engines in 20 minutes - Chris Oliver\"\n  speakers:\n    - Chris Oliver\n  event_name: \"Ruby Australia Melbourne Meetup August 2024\"\n  date: \"2024-08-22\"\n  published_at: \"2024-09-25T11:06:45Z\"\n  description: |-\n    Welcome Chris Oliver, who will be walking through on a basic Rails plugin and talk about the different ways of extending Rails through Engines, a talk you definitely would not want to miss!\n  video_provider: \"youtube\"\n  video_id: \"hXNXLBvlWbI\"\n\n- id: \"julian-pinzon-eslava-ruby-australia-melbourne-meetup-september-2024\"\n  title: \"Oaken: A fresh take on Fixtures and Seeds\"\n  raw_title: \"Oaken: Fresh take on Fixtures and Seeds - Julián Pinzón Eslava\"\n  speakers:\n    - Julián Pinzón Eslava\n  event_name: \"Ruby Australia Melbourne Meetup September 2024\"\n  date: \"2024-09-26\"\n  published_at: \"2024-10-23T06:37:37Z\"\n  description: |-\n    Julián Pinzón Eslava delivering a talk on development and test data management for your Rails app, by utilizing Oaken gem and further talks about fixtures and seeds!\n  video_provider: \"youtube\"\n  video_id: \"bxOqXLL06Sg\"\n\n- id: \"abhijeet-anand-ruby-australia-melbourne-meetup-september-2024\"\n  title: \"How does `reload!` work?\"\n  raw_title: \"How does `reload!` work? - Abhijeet Anand\"\n  speakers:\n    - Abhijeet Anand\n  event_name: \"Ruby Australia Melbourne Meetup September 2024\"\n  date: \"2024-09-26\"\n  published_at: \"2024-10-23T06:40:18Z\"\n  description: |-\n    How does this magical `reload!` even works? Abhijeet Anand will go on a deep dive to show the intricacies of how `reload` works.\n  video_provider: \"youtube\"\n  video_id: \"Fb_sqlOotms\"\n\n- id: \"pat-allan-ruby-australia-melbourne-meetup-november-2024\"\n  title: \"Happy Ruby SAML Development\"\n  raw_title: \"Happy Ruby SAML Development - Pat Allan\"\n  speakers:\n    - Pat Allan\n  event_name: \"Ruby Australia Melbourne Meetup November 2024\"\n  date: \"2024-11-28\"\n  published_at: \"2024-11-27T07:13:32Z\"\n  description: |-\n    Pat Allan gives a introduction on how SAML requests and responses can be handled with Ruby.\n  video_provider: \"youtube\"\n  video_id: \"MeQXR8ojX5c\"\n\n- id: \"celia-king-ruby-australia-meetup-2\"\n  title: \"Cursor, A Cure for What Ails You\"\n  raw_title: \"Cursor, A Cure for What Ails You - Celia King\"\n  speakers:\n    - Celia King\n  event_name: \"Ruby Australia Meetup\" # TODO: city/month October 2024\n  date: \"2024-10-24\"\n  published_at: \"2024-11-27T07:10:42Z\"\n  description: |-\n    Celia King giving an evaluation talk of Cursor, how to configure it, which AI model to use, and a look at the pros and cons of Cursor compared to GitHub Copilot.\n  video_provider: \"youtube\"\n  video_id: \"AkDXMIFETyY\"\n\n- id: \"abhijeet-anand-ruby-australia-melbourne-meetup-november-2024\"\n  title: \"How do `CurrentAttributes` work?\"\n  raw_title: \"How do `CurrentAttributes` work? - Abhijeet Anand\"\n  speakers:\n    - Abhijeet Anand\n  event_name: \"Ruby Australia Melbourne Meetup November 2024\"\n  date: \"2024-11-28\"\n  published_at: \"2025-01-25T06:31:57Z\"\n  description: |-\n    Abhijeet Anand explains the magic behind this powerful rails feature that simplifies global state management in a rails application.\n  video_provider: \"youtube\"\n  video_id: \"doz32657dbM\"\n\n- id: \"jerome-paul-ruby-australia-melbourne-meetup-november-2024\"\n  title: \"Being happy with frontend development again with Turbo and Stimulus\"\n  raw_title: \"Being happy with frontend development again with Turbo (Hotwire) and StimulusJS - Jerome Paul\"\n  speakers:\n    - Jerome Paul\n  event_name: \"Ruby Australia Melbourne Meetup November 2024\"\n  date: \"2024-11-28\"\n  published_at: \"2025-01-25T06:33:40Z\"\n  description: |-\n    Jerome Paul on rediscovering his joy of front-end development with tools like Hotwire and StimulusJS, that make Rails a full stack dream.\n  video_provider: \"youtube\"\n  video_id: \"rhInecDwaKQ\"\n"
  },
  {
    "path": "data/ruby-australia/series.yml",
    "content": "---\nname: \"Ruby Australia\"\ndescription: |-\n  Videos from Ruby meetups around Australia\nwebsite: \"https://ruby.org.au\"\ntwitter: \"rubyaustralia\"\nyoutube_channel_name: \"RubyAustralia\"\nyoutube_channel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nkind: \"organisation\"\nfrequency: \"monthly\"\nlanguage: \"english\"\ndefault_country_code: \"AU\"\n"
  },
  {
    "path": "data/ruby-banitsa/ruby-banitsa-meetup/event.yml",
    "content": "---\nid: \"ruby-banitsa-meetup\"\ntitle: \"Ruby Banitsa Meetup\"\nlocation: \"Sofia, Bulgaria\"\ndescription: |-\n  Event filled with Ruby and Banitsa. We get together in Sofia, Bulgaria, nom some fresh pastry and talk about tech. All this in a casual setting.\nkind: \"meetup\"\npublished_at: \"\"\nyear: 2024\nbanner_background: \"#FDF2F3\"\nfeatured_background: \"#FDF2F3\"\nfeatured_color: \"#000000\"\nwebsite: \"https://rubybanitsa.com/events\"\ncoordinates:\n  latitude: 42.6977082\n  longitude: 23.3218675\n"
  },
  {
    "path": "data/ruby-banitsa/ruby-banitsa-meetup/videos.yml",
    "content": "---\n# Website: https://rubybanitsa.com/events\n# Videos: https://www.youtube.com/@gsamokovarov/videos\n\n# 2025\n\n- id: \"postgresql-tips-and-tricks-ruby-banitsa-september-2025\"\n  title: \"PostgreSQL tips & tricks\"\n  raw_title: \"PostgreSQL tips & tricks by Nikola Jichev\"\n  event_name: \"Ruby Banitsa September 2025\"\n  date: \"2025-09-09\"\n  speakers:\n    - \"Nikola Jichev\"\n  video_id: \"postgresql-tips-and-tricks-ruby-banitsa-september-2025\"\n  video_provider: \"not_published\"\n  description: |-\n    Those hidden gems that make your database life easier and your queries faster. Potential topics include advanced indexing strategies, window functions, and vector handling for AI applications.\n\n- id: \"radoslav-stankov-ruby-banitsa-july-2025\"\n  title: \"Angry Batch\"\n  raw_title: \"Ruby Banitsa – Angry Batch by Radoslav Stankov\"\n  event_name: \"Ruby Banitsa July 2025\"\n  date: \"2025-07-24\"\n  speakers:\n    - \"Radoslav Stankov\"\n  video_id: \"JM2hqxmwrRg\"\n  published_at: \"2025-08-28\"\n  video_provider: \"youtube\"\n  language: \"Bulgarian\"\n  description: |-\n    If you ever needed to orchestrate background jobs, you know the feelings associated with it. Welcome our regular code-therapist, Radoslav Stankov, who wrote Angry Batch, a tool that helps with job orchestration and cortisol level regulation.\n\n- id: \"modern-ux-classic-dx-ruby-banitsa-june-2025\"\n  title: \"Modern UX. Classic DX.\"\n  raw_title: \"Modern UX. Classic DX. by Hristo Vladev\"\n  event_name: \"Ruby Banitsa June 2025\"\n  date: \"2025-06-11\"\n  speakers:\n    - \"Hristo Vladev\"\n  video_id: \"modern-ux-classic-dx-ruby-banitsa-june-2025\"\n  video_provider: \"not_published\"\n  description: |-\n    A presentation exploring contemporary user experience design combined with traditional developer experience principles. Leveraging Inertia JS and Rails together.\n\n- id: \"darth-vs-vibe-coder-ruby-banitsa-april-2025\"\n  title: \"Darth vs Vibe Coder\"\n  raw_title: \"Darth (дърт) vs Vibe Coder\"\n  event_name: \"Ruby Banitsa April 2025\"\n  date: \"2025-04-15\"\n  speakers:\n    - \"Deyan Dobrinov\"\n    - \"Genadi Samokovarov\"\n  video_id: \"darth-vs-vibe-coder-ruby-banitsa-april-2025\"\n  video_provider: \"not_published\"\n  description: |-\n    This inaugural Ruby Banitsa Versus event features a debate between two contrasting coding philosophies. Darth coders develop independently without AI assistance, while Vibe coders leverage AI tools throughout their development process.\n\n- id: \"crafting-a-toy-programming-language-ruby-banitsa-february-2025\"\n  title: \"Crafting a toy programming language\"\n  raw_title: \"Crafting a toy programming language by Ivan Alexandrov\"\n  event_name: \"Ruby Banitsa February 2025\"\n  date: \"2025-02-17\"\n  speakers:\n    - \"Ivan Alexandrov\"\n  video_id: \"crafting-a-toy-programming-language-ruby-banitsa-february-2025\"\n  video_provider: \"not_published\"\n  description: |-\n    The presentation explores formal grammars and their role in modern programming languages. Attendees will learn about Formal Grammars, Lexers, Parsers, Interpreters, and discover popular parser-generator tools while beginning to build their own programming language.\n\n- id: \"administrating-balkan-ruby-ruby-banitsa-january-2025\"\n  title: \"Administrating Balkan Ruby\"\n  raw_title: \"Administrating Balkan Ruby by Genadi Samokovarov\"\n  event_name: \"Ruby Banitsa January 2025\"\n  date: \"2025-01-27\"\n  speakers:\n    - \"Genadi Samokovarov\"\n  video_id: \"administrating-balkan-ruby-ruby-banitsa-january-2025\"\n  video_provider: \"not_published\"\n  description: |-\n    Building a custom admin interface for the Balkan Ruby conference management system. The Balkan Ruby platform handles ticket sales, invoicing, lineup management, sponsorship, scheduling, and operates as a multi-tenant system serving multiple events.\n\n# 2024\n\n- id: \"custom-deployment-tooling-ruby-banitsa-november-2024\"\n  date: \"2024-11-22\"\n  title: \"Custom Deployment Tooling\"\n  raw_title: \"Custom Deployment Tooling\"\n  event_name: \"Ruby Banitsa November 2024\"\n  speakers:\n    - \"Evgeni Dzhelyov\"\n  video_id: \"custom-deployment-tooling-ruby-banitsa-november-2024\"\n  video_provider: \"not_recorded\"\n  description: |-\n    With Rails 8 out, Kamal is all the rage about deployment. But can we go even simpler? And by simpler, we mean roll it out all yourself because you know, you may know what you are doing, and competence is indeed bliss! Welcome Evgeni, who will present gobot, a custom deployment tool with automatic self-update, notification, and all the bells and whistles an organization needs.\n\n- id: \"authentication-scheming-ruby-banitsa-october-2024\"\n  date: \"2024-10-08\"\n  title: \"Authentication Scheming\"\n  raw_title: \"Authentication Scheming\"\n  event_name: \"Ruby Banitsa October 2024\"\n  speakers:\n    - \"Hristo Vladev\"\n  video_id: \"authentication-scheming-ruby-banitsa-october-2024\"\n  video_provider: \"not_recorded\"\n  description: |-\n    The circle of city life is spinning—the school year has started yet again, and so has the horrible Sofia traffic, Rails 8 was just announced, and Ruby Banitsa is back from its summer break!\n\n    Join us for a talk about the modern authentication primitives in Rails 8 with Hristo Vladev.\n\n- id: \"elixir-ai-show-and-tell-ruby-banitsa-july-2024\"\n  date: \"2024-07-10\"\n  title: \"Elixir AI Show and Tell\"\n  raw_title: \"Elixir AI Show and Tell\"\n  event_name: \"Ruby Banitsa July 2024\"\n  speakers:\n    - \"Nikola Jichev\"\n  video_id: \"elixir-ai-show-and-tell-ruby-banitsa-july-2024\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Modern AI opened the doors to tools, markets, and use cases hardly imagined just 3 years ago. Our long-time friend and seldom speaker, Nikola Jichev, is working on an AI-powered startup helping writers... well, write! He'll walk us through its cutting-edge Elixir-powered AI toolchain.\n\n    The talk won't be recorded, come in person.\n\n    A walk through a random Elxir AI toolchain (Nx, Scholar, Axon, Bumblebee) used to ~~DOMINATE~~ DEMOCRATIZE the book writing market.\n\n- id: \"balkan-ruby-code-and-tell-ruby-banitsa-may-2024\"\n  date: \"2024-05-22\"\n  title: \"Balkan Ruby Code-and-Tell\"\n  raw_title: \"Balkan Ruby Code-and-Tell\"\n  event_name: \"Ruby Banitsa May 2024\"\n  speakers:\n    - \"Genadi Samokovarov\"\n  video_id: \"balkan-ruby-code-and-tell-ruby-banitsa-may-2024\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Balkan Ruby was a great success! I had a blast and I hope you did as well. While running the event, I built a website, ticketing, and an invoicing system from scratch. Are those systems important for running the event? Absolutely not! However, I am a coder, and code I did.\n\n    It was worth it as those systems let us run a smooth registration at the event, do ticket discounts, one-off sales, issue refunds, and freed us from doing error-prone manual invoicing. Let me show you them codes!\n\n    Code is not essential for running events, even tech events but I'm a coder, and code I did. It helped!\n\n- id: \"short-but-sweet-tech-talk-ruby-banitsa-april-2024\"\n  date: \"2024-04-24\"\n  title: \"Short but Sweet Tech Talk\"\n  raw_title: \"Short but Sweet Tech Talk\"\n  event_name: \"Ruby Banitsa April 2024\"\n  speakers:\n    - \"Nick Sutterer\"\n  video_id: \"short-but-sweet-tech-talk-ruby-banitsa-april-2024\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Nick Sutterer is back in town for Balkan Ruby. Our time with him is always short but sweet, just like his tech talk for Ruby Banitsa.\n\n    We are super happy to have Nick back! Come for a bit of tech and a byte more of hanging out.\n\n    In preparation for Balkan Ruby, Nick will present a \"short but sweet tech talk\".\n\n- id: \"practical-observability-for-rails-developers-ruby-banitsa-march-2024\"\n  date: \"2024-03-20\"\n  title: \"Practical Observability for Rails Developers\"\n  raw_title: \"Practical Observability for Rails Developers\"\n  event_name: \"Ruby Banitsa March 2024\"\n  speakers:\n    - \"Evgeni Dzhelyov\"\n  video_id: \"practical-observability-for-rails-developers-ruby-banitsa-march-2024\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Join us for an evening full of carbs and observability insights! Evgeni Dhzelyov will discuss request logging, background jobs logging, and error tracking. How to wire up tracings, and what metrics in Rails applications we should pay attention to.\n\n- id: \"interactive-ux-with-stimulus-and-turbo-8-ruby-banitsa-february-2024\"\n  date: \"2024-02-22\"\n  title: \"Interactive UX with Stimulus and Turbo 8\"\n  raw_title: \"Interactive UX with Stimulus and Turbo 8\"\n  event_name: \"Ruby Banitsa February 2024\"\n  speakers:\n    - \"Ventsislav Nikolov\"\n  video_id: \"interactive-ux-with-stimulus-and-turbo-8-ruby-banitsa-february-2024\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Welcome to the very first Ruby Banitsa for 2024! We are starting the year by sharing the excitement around server-side rendering without React. Yes, you heard that right! Come for a talk about Interactive UX with Stimulus and Turbo 8 by Ventsislav Nikolov.\n\n## 2023\n\n- id: \"radoslav-stankov-ruby-banitsa-november-2023\"\n  title: \"Component-Driven UI with ViewComponent\"\n  raw_title: \"Component-Driven UI with ViewComponent\"\n  event_name: \"Ruby Banitsa November 2023\"\n  date: \"2023-11-02\"\n  speakers:\n    - \"Radoslav Stankov\"\n  video_id: \"V61ITjlJE1A\"\n  published_at: \"2023-11-07\"\n  video_provider: \"youtube\"\n  language: \"Bulgarian\"\n  description: |-\n    We are back after a-bit-too-long of a summer break with a lecture from Radoslav Stankov about Component-Driven UI with the help of the view_component gem.\n\n    A talk about Component-Driven UI with the help of the view_component Ruby gem.\n\n- id: \"hotwire-at-work-ruby-banitsa-june-2023\"\n  title: \"Hotwire at Work\"\n  raw_title: \"Hotwire at Work\"\n  event_name: \"Ruby Banitsa June 2023\"\n  date: \"2023-06-07\"\n  speakers:\n    - \"Hristo Vladev\"\n  video_id: \"hotwire-at-work-ruby-banitsa-june-2023\"\n  video_provider: \"not_recorded\"\n  description: |-\n    For this event we are hosted by Questers. We'll be in their terrace, or QTerrace, rain or shine.\n\n    Hristo Vladev is following up his May \"Intro to Hotwire\" talk with a practical \"Hotwire at Work\" session. This won't be a talk, but a live code-along.\n\n    Hotwire is an alternative approach to building modern web applications without using much JavaScript by sending HTML instead of JSON over the wire. It's an alternative to the single-page application frameworks like React.\n\n- id: \"hotwire-at-work-ruby-banitsa-may-2023\"\n  title: \"Intro to Hotwire\"\n  raw_title: \"Intro to Hotwire\"\n  event_name: \"Ruby Banitsa May 2023\"\n  date: \"2023-05-18\"\n  speakers:\n    - \"Hristo Vladev\"\n  video_id: \"hotwire-at-work-ruby-banitsa-may-2023\"\n  video_provider: \"not_recorded\"\n  description: |-\n    We are testing a new venue for our May event. Resonator, a place to collaborate, co-create, experiment & share knowledge & expertise. It's close to Pette Kyosheta.\n\n    Are you riding the the React Server Components (RSC) hype train? Did you know that you can avoid the whole hydration/de-hydration approach if you leverage plain old HTML? Hotwire is an alternative approach to building modern web applications without using much JavaScript by sending HTML instead of JSON over the wire.\n\n    Some people like it, some even use it, but we are just gonna talk about it. Welcome Hristo Vladev with his Intro to Hotwire to Ruby Banitsa!\n\n- id: \"genadi-samokovarov-ruby-banitsa-april-2023\"\n  title: \"RuboCop's Baddest Cop\"\n  raw_title: \"RuboCop's Baddest Cop\"\n  event_name: \"Ruby Banitsa April 2023\"\n  date: \"2023-04-20\"\n  speakers:\n    - \"Genadi Samokovarov\"\n  video_id: \"genadi-samokovarov-ruby-banitsa-april-2023\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Genadi Samokovarov is going to RubyKaigi in Matsumoto, Japan this year and he's going to talk about RuboCop's Baddest Cop; or, how hard it is (was) to enforce method calls without parentheses. But since you're \"my kind of people\" (наши хора), you'll get to see the very first edition of this talk, right here in Ruby Banitsa! This talk won't be recorded, come and see it live!\n\n- id: \"dimitar-dimitrov-ruby-banitsa-march-2023\"\n  title: \"Mysterious infrastructure\"\n  raw_title: \"Mysterious infrastructure\"\n  event_name: \"Ruby Banitsa March 2023\"\n  date: \"2023-03-06\"\n  speakers:\n    - \"Dimitar Dimitrov\"\n  video_id: \"dimitar-dimitrov-ruby-banitsa-march-2023\"\n  video_provider: \"not_recorded\"\n  description: |-\n    We had a Force majeure in February and we're giving it a second try. 🤞 Welcome, Dimitar Dimitrov a.k.a @mitio to Ruby Banitsa!\n\n    Schedule\n\n    18:30 – Snack, mostly banitsa for dinner 😋\n    18:45 – Mysterious infrastructure talk 🔮\n    20:00 – More snack, leftover banitsa 🤢\n\n    Dimitar Dimitrov is the Lead of Infrastructure at Dext, Rails Girls Sofia organiser and one of the local Ruby old-timers! Expect a mysterious infrastructure talk! 🔮\n\n# TODO: missing event: \"February 2023: Social Event\" - https://rubybanitsa.com/events/87\n\n- id: \"gabriela-luhova-ruby-banitsa-january-2023\"\n  title: \"Discussion: Process Organization\"\n  raw_title: \"Process organization discussion with Gabriela Luhova\"\n  event_name: \"Ruby Banitsa January 2023\"\n  date: \"2023-01-25\"\n  speakers:\n    - \"Gabriela Luhova\"\n  video_id: \"gabriela-luhova-ruby-banitsa-january-2023\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Happy new year! We are starting 2023 with something different. Our January 2023 event won't have a talk but will be a discussion, lead by Gabriela Luhova about \"Process organization\".\n\n    We, and I mean all of us, will talk about the processes we use to deliver our (non) Ruby projects because \"good code\", whatever your definition for good is, is not enough. How do we structure our workload? Do we use sprints? Do you work on a product or for a client? How do you communicate with clients? And all the evergreen questions!\n\n    Come and discourse with us in Barter Community Hub on the 25th of January from 18:30. We won't be streaming this one. While at it, make sure to convince me that chat channel and a Kanban board with a single \"Done\" column is not enough!\n"
  },
  {
    "path": "data/ruby-banitsa/series.yml",
    "content": "---\nname: \"Ruby Banitsa\"\nwebsite: \"https://rubybanitsa.com\"\ntwitter: \"rubybanitsa\"\nyoutube_channel_name: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\ndefault_country_code: \"BG\"\n"
  },
  {
    "path": "data/ruby-banitsa-conf/ruby-banitsa-conf-2024/event.yml",
    "content": "---\nid: \"ruby-banitsa-conf-2024\"\ntitle: \"Ruby Banitsa Conf 2024\"\nlocation: \"Sofia, Bulgaria\"\ndescription: |-\n  We have been running Sofia's Ruby Banitsa meetup for 7 years. Let's celebrate it with our very first conference! A single-day event full of carbs, fun, and laid-back Ruby.\nkind: \"conference\"\npublished_at: \"2024-12-07\"\nstart_date: \"2024-12-07\"\nend_date: \"2024-12-07\"\nyear: 2024\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://conf.rubybanitsa.com\"\ncoordinates:\n  latitude: 42.6615715\n  longitude: 23.3179759\n"
  },
  {
    "path": "data/ruby-banitsa-conf/ruby-banitsa-conf-2024/schedule.yml",
    "content": "# Schedule: https://conf.rubybanitsa.com\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-12-07\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"10:00\"\n        end_time: \"10:10\"\n        slots: 1\n        items:\n          - Introduction\n\n      - start_time: \"10:10\"\n        end_time: \"10:50\"\n        slots: 1\n\n      - start_time: \"10:50\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:40\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"12:00\"\n        end_time: \"12:40\"\n        slots: 1\n\n      - start_time: \"12:40\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:30\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"15:40\"\n        end_time: \"16:20\"\n        slots: 1\n\n      - start_time: \"16:20\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Give Thanks & Praises\n\ntracks: []\n"
  },
  {
    "path": "data/ruby-banitsa-conf/ruby-banitsa-conf-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Community partners\"\n      description: |-\n        Community partners of Ruby Banitsa 2024 conference as listed on the website.\n      level: 1\n      sponsors:\n        - name: \"Puzl\"\n          badge: \"\"\n          website: \"https://puzl.com\"\n          slug: \"puzl\"\n          logo_url:\n            \"https://conf.rubybanitsa.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MzAsInB1ciI6ImJsb2JfaWQifX0=--85ccde1d49ff66d1b3ec4baf261236cb1c4acb3\\\n            7/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOls1MDAsNTAwXX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--1af0099157b76e9cbcc497a0d35cdb95437cfe52/puzl.png\"\n\n        - name: \"Barter Community Hub\"\n          badge: \"\"\n          website: \"https://barter-hub.com\"\n          slug: \"barter-community-hub\"\n          logo_url:\n            \"https://conf.rubybanitsa.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MzEsInB1ciI6ImJsb2JfaWQifX0=--6f72fb852de67e1c2bf8ced9ec43eabbd9f2791\\\n            5/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOls1MDAsNTAwXX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--1af0099157b76e9cbcc497a0d35cdb95437cfe52/barter.png\"\n\n        - name: \"Geneva.rb\"\n          badge: \"\"\n          website: \"https://www.meetup.com/geneva-rb/\"\n          slug: \"geneva-rb\"\n          logo_url:\n            \"https://conf.rubybanitsa.com/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsiZGF0YSI6MzgsInB1ciI6ImJsb2JfaWQifX0=--e7605131c779518c08df4c6299cf8e4145f861c\\\n            2/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOls1MDAsNTAwXX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--1af0099157b76e9cbcc497a0d35cdb95437cfe52/geneva-rb.\\\n            avif\"\n"
  },
  {
    "path": "data/ruby-banitsa-conf/ruby-banitsa-conf-2024/venue.yml",
    "content": "---\nname: \"Barter Community Hub\"\n\naddress:\n  street: 'bulevard \"Cherni Vrah\" 47'\n  city: \"Sofia\"\n  region: \"\"\n  postal_code: \"\"\n  country: \"Bulgaria\"\n  country_code: \"BG\"\n  display: 'bul. Cherni Vrah 47, Rooftop, Промишлена зона Хладилника, Blvd. \"Cherni vrah\" 47, 1407 Sofia, Bulgaria'\n\ncoordinates:\n  latitude: 42.6615715\n  longitude: 23.3179759\n\nmaps:\n  google: \"https://maps.google.com/?q=Barter+Community+Hub,42.6615715,23.3179759\"\n  apple: \"https://maps.apple.com/?q=Barter+Community+Hub&ll=42.6615715,23.3179759\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=42.6615715&mlon=23.3179759\"\n"
  },
  {
    "path": "data/ruby-banitsa-conf/ruby-banitsa-conf-2024/videos.yml",
    "content": "---\n# Website: https://conf.rubybanitsa.com\n\n## Devember 7, 2024\n\n# Registration\n\n# Introduction\n\n- id: \"radoslav-stankov-ruby-banitsa-conf-2024\"\n  title: \"Rails: The Missing Parts\"\n  raw_title: \"Rails: The Missing Parts by Radoslav Stankov\"\n  event_name: \"Ruby Banitsa Conf 2024\"\n  speakers:\n    - \"Radoslav Stankov\"\n  video_id: \"c14M6QeFVgY\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GeLrKRZXMAAjxP6?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GeLrKRZXMAAjxP6?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GeLrKRZXMAAjxP6?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GeLrKRZXMAAjxP6?format=jpg\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GeLrKRZXMAAjxP6?format=jpg&name=large\"\n  date: \"2024-12-07\"\n  published_at: \"2024-12-15\"\n  description: |-\n    Radoslav Stankov was the CTO of Product Hunt. He is currently building Angry Building (https://angrybuilding.com/) as the single technical person on the team. This is his Rails stack.\n\n    Learn about the flavor of Rails that Rado likes and uses.\n\n# Break\n\n- id: \"nikola-jichev-the-erlang-vm-ruby-banitsa-2024\"\n  title: \"The Erlang VM\"\n  raw_title: \"The Erlang VM by Nikola Jichev\"\n  event_name: \"Ruby Banitsa Conf 2024\"\n  speakers:\n    - \"Nikola Jichev\"\n  video_id: \"nikola-jichev-the-erlang-vm-ruby-banitsa-2024\"\n  video_provider: \"scheduled\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GeL_CdcXAAA6Tsz?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GeL_CdcXAAA6Tsz?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GeL_CdcXAAA6Tsz?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GeL_CdcXAAA6Tsz?format=jpg\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GeL_CdcXAAA6Tsz?format=jpg&name=large\"\n  date: \"2024-12-07\"\n  description: |-\n    We’ll explore the Erlang Virtual Machine, a unique runtime designed for building highly concurrent and fault-tolerant systems. Built on the principles of the actor model, the Erlang VM handles processes and messaging in a way that has inspired scalable and resilient software for decades. Together, we’ll take a closer look at how it works and why its design continues to power some of the world's most demanding systems. Let’s dive in!\n\n# Break\n\n- title: \"Headless Components with Stimulus\"\n  raw_title: \"Headless Components with Stimulus by Ventsislav Nikolov\"\n  event_name: \"Ruby Banitsa Conf 2024\"\n  speakers:\n    - \"Ventsislav Nikolov\"\n  id: \"ventislav-nikolov-headless-components-with-stimulus-ruby-banitsa-2024\"\n  video_id: \"XM4SfSuzo6o\"\n  video_provider: \"youtube\"\n  published_at: \"2025-05-09\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GeMMeBzXgAAEWio?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GeMMeBzXgAAEWio?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GeMMeBzXgAAEWio?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GeMMeBzXgAAEWio?format=jpg\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GeMMeBzXgAAEWio?format=jpg&name=large\"\n  date: \"2024-12-07\"\n  description: |-\n    Ventsi will tell us what this means, it sure sound exciting. I can't wait to tail on those headless components.\n\n# Lunch Break\n\n- id: \"kasper-timm-hansen-ruby-banitsa-conf-2024\"\n  title: \"Express Your Ideas by Writing Your Own Gems\"\n  raw_title: \"Express Your Ideas by Writing Your Own Gems by Kasper Timm Hansen\"\n  event_name: \"Ruby Banitsa Conf 2024\"\n  speakers:\n    - \"Kasper Timm Hansen\"\n  video_id: \"_pI2muYwpM8\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GeMpS7LWsAAfR-6?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GeMpS7LWsAAfR-6?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GeMpS7LWsAAfR-6?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GeMpS7LWsAAfR-6?format=jpg\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GeMpS7LWsAAfR-6?format=jpg&name=large\"\n  date: \"2024-12-07\"\n  published_at: \"2025-01-20\"\n  description: |-\n    In this talk, we'll do a walkthrough of two gems of mine, ActiveRecord::AssociatedObject and Oaken.\n\n    I'll go over why I wrote them and we'll break down the code too.\n\n    The talk will you give you practical insight into what smaller gems look like, and hopefully inspire you to write your own!\n  alternative_recordings:\n    - title: \"Express Your Ideas by Writing Your Own Gems\"\n      event_name: \"Ruby Banitsa Conf 2024\"\n      date: \"2024-12-07\"\n      published_at: \"2024-12-20\"\n      video_id: \"Md90cwnmGc8\"\n      video_provider: \"youtube\"\n\n    - title: \"Express Your Ideas by Writing Your Own Gems\"\n      event_name: \"Ruby Banitsa Conf 2024\"\n      date: \"2024-12-07\"\n      published_at: \"2025-01-19\"\n      video_id: \"sNivVgVMM60\"\n      video_provider: \"youtube\"\n\n# Coffee Break\n\n- id: \"bozhidar-batsov-ruby-banitsa-conf-2024\"\n  title: \"Weird Ruby\"\n  raw_title: \"Weird Ruby by Bozhidar Batsov\"\n  event_name: \"Ruby Banitsa Conf 2024\"\n  speakers:\n    - \"Bozhidar Batsov\"\n  video_id: \"u-wBrjK7340\"\n  video_provider: \"youtube\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GeNAE2KX0AAF3GJ?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GeNAE2KX0AAF3GJ?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GeNAE2KX0AAF3GJ?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GeNAE2KX0AAF3GJ?format=jpg\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GeNAE2KX0AAF3GJ?format=jpg&name=large\"\n  date: \"2024-12-07\"\n  published_at: \"2024-12-16\"\n  description: |-\n    Bozhidar is the author of RuboCop and the editor of the community Ruby\n    style guide. He's involved in a myriad of open-source projects, mainly\n    related to Ruby, Clojure, and Emacs. Many would probably describe\n    him as an Emacs zealot (and they would be right).\n\n    This talk is very strange and unusual, unexpected, or not natural. It's a talk about Ruby!\n\n# Give Thanks & Praises\n"
  },
  {
    "path": "data/ruby-banitsa-conf/series.yml",
    "content": "---\nname: \"Ruby Banitsa Conf\"\nwebsite: \"https://conf.rubybanitsa.com\"\ntwitter: \"rubybanitsa\"\nkind: \"conference\"\nfrequency: \"irregular\"\nlanguage: \"english\"\ndefault_country_code: \"BG\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-summer-edition-2023/event.yml",
    "content": "---\nid: \"PLvMNoWK93wtmlQyKf59wu0IZk9N7ZpWpJ\"\ntitle: \"Ruby Community Conference Summer Edition 2023\"\nkind: \"conference\"\nlocation: \"Warsaw, Poland\"\ndescription: |-\n  The first edition of the Ruby Community Conference\nstart_date: \"2023-07-21\"\nend_date: \"2023-07-21\"\npublished_at: \"2023-08-30\"\nchannel_id: \"UCVlG6qQ1mGnJv185ayWjEzg\"\nyear: 2023\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubycommunityconference.com/summer2023.html\"\ncoordinates:\n  latitude: 52.19991\n  longitude: 21.0056214\naliases:\n  - Ruby Warsaw Community Conference 2023 Summer Edition\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-summer-edition-2023/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Mariusz Kozieł\n\n  organisations:\n    - Visuality\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-summer-edition-2023/venue.yml",
    "content": "# https://rubycommunityconference.com/summer2023.html\n---\nname: \"Centrum Łowicka\"\n\naddress:\n  street: \"21 Łowicka\"\n  city: \"Warszawa\"\n  region: \"Województwo mazowieckie\"\n  postal_code: \"02-502\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"Łowicka 21, 02-502 Warszawa, Poland\"\n\ncoordinates:\n  latitude: 52.19991\n  longitude: 21.0056214\n\nmaps:\n  google: \"https://maps.google.com/?q=CENTRUM+ŁOWICKA,52.19991,21.0056214\"\n  apple: \"https://maps.apple.com/?q=CENTRUM+ŁOWICKA&ll=52.19991,21.0056214\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=52.19991&mlon=21.0056214\"\n\nlocations:\n  - name: \"Visuality\"\n    kind: \"Workshops\"\n    address:\n      street: \"56 Odolańska\"\n      city: \"Warszawa\"\n      region: \"Województwo mazowieckie\"\n      postal_code: \"02-562\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Odolańska 56, 02-562 Warszawa, Poland\"\n    coordinates:\n      latitude: 52.2002536\n      longitude: 21.0128232\n    maps:\n      google: \"https://maps.google.com/?q=Visuality,52.2002536,21.0128232\"\n      apple: \"https://maps.apple.com/?q=Visuality&ll=52.2002536,21.0128232\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2002536&mlon=21.0128232\"\n\n  - name: \"Visuality\"\n    kind: \"After Party\"\n    address:\n      street: \"56 Odolańska\"\n      city: \"Warszawa\"\n      region: \"Województwo mazowieckie\"\n      postal_code: \"02-562\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Odolańska 56, 02-562 Warszawa, Poland\"\n    coordinates:\n      latitude: 52.2002536\n      longitude: 21.0128232\n    maps:\n      google: \"https://maps.google.com/?q=Visuality,52.2002536,21.0128232\"\n      apple: \"https://maps.apple.com/?q=Visuality&ll=52.2002536,21.0128232\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2002536&mlon=21.0128232\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-summer-edition-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"nick-sutterer-ruby-community-conference-summer-edition-2023\"\n  title: \"The Transformation of Trailblazer\"\n  raw_title: \"[EN] The Transformation of Trailblazer - Nick Sutterer\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"Ruby Community Conference Summer Edition 2023\"\n  date: \"2023-08-30\"\n  published_at: \"2023-09-01\"\n  description: |-\n    The Transformation of Trailblazer - A ride through the history of the Trailblazer project, through important milestones and releases that formed the functional concepts of the business logic framework over two decades.\n\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at:\n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development:\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here:\n\n    Instagram: https://www.instagram.com/visuality.pl/\n    Facebook: https://www.facebook.com/visualitypl\n    Linkedin: https://www.linkedin.com/company/visualitypl/\n    X: https://twitter.com/visualitypl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"B9ibwFBwrjE\"\n\n- id: \"chris-hasinski-ruby-community-conference-summer-edition-2023\"\n  title: \"Fantastic Databases And Where To Find Them\"\n  raw_title: \"[EN] Fantastic Databases And Where To Find Them - Krzysztof Hasiński\"\n  speakers:\n    - Chris Hasinski\n  event_name: \"Ruby Community Conference Summer Edition 2023\"\n  date: \"2023-08-30\"\n  published_at: \"2023-09-01\"\n  description: |-\n    Fantastic Databases And Where To Find Them\n\n    Ruby on Rails app tend to rely heavily on databases and yet we rarely talk about them during meetups. This talk explores some of the more unusual parts of working with databases in a context of a typical RoR app.\n\n    Authors: Chris Hasiński\n\n    Visuality talks: Y20W[...]\n\n    RESOURCES & LINKS:\n    ____________________________________________\n    SQLite appropriate uses: https://www.sqlite.org/whentouse.html\n    PostgreSQL manual: https://www.postgresql.org/docs/\n    PostgreSQL on using explain: https://www.postgresql.org/docs/current/using-explain.html\n    Citus columnar storage: https://docs.citusdata.com/en/v11.1/admin_guide/table_management.html#columnar-storage\n\n    Other databases mentioned:\n    MySQL, Clickhouse, Cockroach DB.\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at:\n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development:\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here:\n\n    Instagram: https://www.instagram.com/visuality.pl/\n    Facebook: https://www.facebook.com/visualitypl\n    Linkedin: https://www.linkedin.com/company/visualitypl/\n    X: https://twitter.com/visualitypl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"50umESFnRL0\"\n  additional_resources:\n    - name: \"SQLite appropriate uses\"\n      title: \"SQLite appropriate uses\"\n      type: \"link\"\n      url: \"https://www.sqlite.org/whentouse.html\"\n\n    - name: \"PostgreSQL manual\"\n      title: \"PostgreSQL manual\"\n      type: \"link\"\n      url: \"https://www.postgresql.org/docs/\"\n\n    - name: \"PostgreSQL on using explain\"\n      title: \"PostgreSQL on using explain\"\n      type: \"link\"\n      url: \"https://www.postgresql.org/docs/current/using-explain.html\"\n\n    - name: \"Citus columnar storage\"\n      title: \"Citus columnar storage\"\n      type: \"link\"\n      url: \"https://docs.citusdata.com/en/v11.1/admin_guide/table_management.html#columnar-storage\"\n\n- id: \"pawe-strzakowski-ruby-community-conference-summer-edition-2023\"\n  title: \"Rails Permanent Job - build a Ruby on Rails server using ServerEngine\"\n  raw_title: \"[EN] Rails Permanent Job - build a Ruby on Rails server using ServerEngine  - Paweł Strzałkowski\"\n  speakers:\n    - Paweł Strzałkowski\n  event_name: \"Ruby Community Conference Summer Edition 2023\"\n  date: \"2023-08-30\"\n  published_at: \"2023-09-01\"\n  description: |-\n    Video from the first edition of Ruby Community Conference with a presentation by Paweł Strzałkowski. The speaker introduces the concept of building multiple process servers using Ruby on Rails framework. The speech describes a helpful tool - Rails Permanent Job gem, which is a wrapper for ServerEngine gem.\n\n    Additional links:\n    - Rails Permanent Job gem - https://github.com/pstrzalk/rails_permanent_job\n    - ServerEngine gem - https://github.com/treasure-data/serverengine\n    - Sneakers gem (using ServerEngine) - https://github.com/jondot/sneakers\n\n    Presentation plan:\n    [0:23] Beginning of the presentation\n    [1:25] Games in Ruby on Rails\n    [5:45] Using Cron to perform scheduled actions\n    [9:10] Custom rake tasks for handling sub-minute intervals\n    [12:20] Continuous read for a data feed\n    [12:48] Do not use Sidekiq for scheduling next jobs\n    [15:45] Concurrent solutions\n    [18:10] Introduction to ServerEngine\n    [21:00] ServerEngine code examples\n    [23:55] Introduction to Rails Permanent Job\n    [25:17] Rails Permanent Job code examples\n    [30:16] Ruby on Rails game implementation presentation\n    [31:56] Summary\n    [33:34] Multiplayer Ruby on Rails game showcase\n    [35:08] Q&A\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at:\n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development:\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here:\n\n    Instagram: https://www.instagram.com/visuality.pl/\n    Facebook: https://www.facebook.com/visualitypl\n    Linkedin: https://www.linkedin.com/company/visualitypl/\n    X: https://twitter.com/visualitypl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"nRrxWJ4BExQ\"\n  additional_resources:\n    - name: \"pstrzalk/rails_permanent_job\"\n      type: \"repo\"\n      url: \"https://github.com/pstrzalk/rails_permanent_job\"\n\n    - name: \"treasure-data/serverengine\"\n      type: \"repo\"\n      url: \"https://github.com/treasure-data/serverengine\"\n\n    - name: \"jondot/sneakers\"\n      type: \"repo\"\n      url: \"https://github.com/jondot/sneakers\"\n\n- id: \"sergy-sergyenko-ruby-community-conference-summer-edition-2023\"\n  title: \"ChatGPT for Legacy Ruby Application Refactoring\"\n  raw_title: \"[EN] ChatGPT for Legacy Ruby Application Refactoring - Sergey Sergyenko\"\n  speakers:\n    - Sergy Sergyenko\n  event_name: \"Ruby Community Conference Summer Edition 2023\"\n  date: \"2023-08-30\"\n  published_at: \"2023-09-01\"\n  description: |-\n    ChatGPT for Legacy Ruby Application Refactoring\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at:\n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development:\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here:\n\n    Instagram: https://www.instagram.com/visuality.pl/\n    Facebook: https://www.facebook.com/visualitypl\n    Linkedin: https://www.linkedin.com/company/visualitypl/\n    X: https://twitter.com/visualitypl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"zXfQ2QiOLLs\"\n  slides_url: \"https://speakerdeck.com/sergyenko/legacy-rails-app-refactoring-with-chatgpt-4-dot-0\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-summer-edition-2024/event.yml",
    "content": "---\nid: \"PLvMNoWK93wtnWTpEaJBlEIf5JxrE7rPFY\"\ntitle: \"Ruby Community Conference Summer Edition 2024\"\nkind: \"conference\"\nlocation: \"Warsaw, Poland\"\ndescription: |-\n  The third edition of the Ruby Community Conference, which took place on July 19th, 2024 at the PKiN in Warsaw.\npublished_at: \"2024-07-31\"\nstart_date: \"2024-07-19\"\nend_date: \"2024-07-19\"\nchannel_id: \"UCVlG6qQ1mGnJv185ayWjEzg\"\nyear: 2024\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://www.rubycommunityconference.com/summer2024\"\ncoordinates:\n  latitude: 52.231838\n  longitude: 21.005995\naliases:\n  - Ruby Warsaw Community Conference 2024 Summer Edition\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-summer-edition-2024/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Mariusz Kozieł\n\n  organisations:\n    - Visuality\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-summer-edition-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Regular Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Appsignal\"\n          badge: \"\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/appsignal.d4b91333.svg\"\n\n        - name: \"2n\"\n          badge: \"\"\n          website: \"https://www.2n.pl/\"\n          slug: \"2n\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/2n-logo.c85f6e96.png\"\n\n        - name: \"Cybergizer\"\n          badge: \"\"\n          website: \"https://cybergizer.com/\"\n          slug: \"cybergizer\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/cybergizer.921a5f6f.svg\"\n\n        - name: \"Railsware\"\n          badge: \"\"\n          website: \"https://railsware.com/\"\n          slug: \"railsware\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/railsware_logo.7504cef7.svg\"\n\n        - name: \"Softswiss\"\n          badge: \"\"\n          website: \"https://www.softswiss.com/\"\n          slug: \"softswiss\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/Softswiss_logo.ffdbc61d.png\"\n\n        - name: \"Koleo\"\n          badge: \"\"\n          website: \"https://astarium.pl/kariera-w-koleo/\"\n          slug: \"koleo\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/koleo.fab642f9.svg\"\n\n        - name: \"Prowly\"\n          badge: \"\"\n          website: \"https://prowly.com/careers/\"\n          slug: \"prowly\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/prowly-logo.dd75fe42.png\"\n\n        - name: \"RORvsWild\"\n          badge: \"\"\n          website: \"https://www.rorvswild.com/\"\n          slug: \"rorvswild\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/sponsors_rorvswild_logo.9592cfe7.svg\"\n\n        - name: \"Honeybadger\"\n          badge: \"\"\n          website: \"https://www.honeybadger.io/\"\n          slug: \"honeybadger\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/sponsors_honeybadger_logo.ed493101.svg\"\n\n        - name: \"Visuality\"\n          badge: \"\"\n          website: \"https://www.visuality.pl/\"\n          slug: \"visuality\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/visuality.abac79f3.svg\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-summer-edition-2024/venue.yml",
    "content": "# https://www.rubycommunityconference.com/summer2024/\n---\nname: \"Kinoteka, Palace of Culture and Science\"\n\ndescription: |-\n  Pałac Kultury i Nauki, Sala Młoda Gwardia\n\naddress:\n  street: \"1 plac Defilad\"\n  city: \"Warszawa\"\n  region: \"Województwo mazowieckie\"\n  postal_code: \"00-901\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"pl. Defilad 1, 00-901 Warszawa, Poland\"\n\ncoordinates:\n  latitude: 52.231838\n  longitude: 21.005995\n\nmaps:\n  google: \"https://maps.google.com/?q=Kinoteka,+Palace+of+Culture+and+Science,52.2312884,21.0065014\"\n  apple: \"https://maps.apple.com/?q=Kinoteka,+Palace+of+Culture+and+Science&ll=52.2312884,21.0065014\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2312884&mlon=21.0065014\"\n\nlocations:\n  - name: \"Visuality\"\n    kind: \"Workshops\"\n    address:\n      street: \"56 Odolańska\"\n      city: \"Warszawa\"\n      region: \"Województwo mazowieckie\"\n      postal_code: \"02-562\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Odolańska 56, 02-562 Warszawa, Poland\"\n    coordinates:\n      latitude: 52.2002536\n      longitude: 21.0128232\n    maps:\n      google: \"https://maps.google.com/?q=Visuality,52.2002536,21.0128232\"\n      apple: \"https://maps.apple.com/?q=Visuality&ll=52.2002536,21.0128232\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2002536&mlon=21.0128232\"\n\n  - name: \"Koleo\"\n    kind: \"Workshops\"\n    address:\n      street: \"22 Katowicka\"\n      city: \"Warszawa\"\n      region: \"Województwo mazowieckie\"\n      postal_code: \"03-932\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Katowicka 22, 03-932 Warszawa, Poland\"\n    coordinates:\n      latitude: 52.234085\n      longitude: 21.051325\n    maps:\n      google: \"https://maps.google.com/?q=Koleo,52.234085,21.051325\"\n      apple: \"https://maps.apple.com/?q=Koleo&ll=52.234085,21.051325\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=52.234085&mlon=21.051325\"\n\n  - name: \"CodersLab\"\n    kind: \"Workshops\"\n    description: |-\n      Prosta Office Centre\n    address:\n      street: \"51 Prosta\"\n      city: \"Warszawa\"\n      region: \"Województwo mazowieckie\"\n      postal_code: \"00-838\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Prosta 51, 00-838 Warszawa, Poland\"\n    coordinates:\n      latitude: 52.2304938\n      longitude: 20.9874117\n    maps:\n      google: \"https://maps.google.com/?q=CodersLab,52.2304938,20.9874117\"\n      apple: \"https://maps.apple.com/?q=CodersLab&ll=52.2304938,20.9874117\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2304938&mlon=20.9874117\"\n\n  - name: \"Uwaga Piwo\"\n    kind: \"After Party\"\n    address:\n      street: \"51 Żelazna\"\n      city: \"Warszawa\"\n      region: \"Województwo mazowieckie\"\n      postal_code: \"00-841\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Żelazna 51/53, Fabryka Norblina, 00-841 Warszawa, Poland\"\n\n    coordinates:\n      latitude: 52.2322347\n      longitude: 20.9918847\n\n    maps:\n      google: \"https://maps.google.com/?q=Uwaga+Piwo,52.2322347,20.9918847\"\n      apple: \"https://maps.apple.com/?q=Uwaga+Piwo&ll=52.2322347,20.9918847\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2322347&mlon=20.9918847\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-summer-edition-2024/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"oskar-lakner-ruby-community-conference-summer-edition-2024\"\n  title: \"Workshop: From Junior to Mid-Level: Accelerate Your Rails Skills\"\n  raw_title: \"FROM JUNIOR TO MID-LEVEL: ACCELERATE YOUR ROR SKILLS\"\n  speakers:\n    - Oskar Lakner\n  event_name: \"Ruby Community Conference Summer Edition 2024\"\n  date: \"2024-07-29\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"oskar-lakner-ruby-community-conference-summer-edition-2024\"\n\n- id: \"chris-hasinski-patryk-ptasinski-ruby-community-conference-summer-edition-2024\"\n  title: \"Workshop: Fixing Performance Issues with Rails\"\n  raw_title: \"FIXING PERFORMANCE ISSUES WITH RAILS\"\n  speakers:\n    - Chris Hasinski\n    - Patryk Ptasiński\n  event_name: \"Ruby Community Conference Summer Edition 2024\"\n  date: \"2024-07-29\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"chris-hasinski-patryk-ptasinski-ruby-community-conference-summer-edition-2024\"\n\n- id: \"michal-lecicki-piotr-witek-ruby-community-conference-summer-edition-2024\"\n  title: \"Workshop: Building a Live Kanban Board Application with Hotwire and Rails\"\n  raw_title: \"BUILDING A LIVE KANBAN BOARD APPLICATION WITH HOTWIRE AND RAILS\"\n  speakers:\n    - Michał Łęcicki\n    - Piotr Witek\n  event_name: \"Ruby Community Conference Summer Edition 2024\"\n  date: \"2024-07-29\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"michal-lecicki-piotr-witek-ruby-community-conference-summer-edition-2024\"\n\n- id: \"cezary-klos-ruby-community-conference-summer-edition-2024\"\n  title: \"Workshop: Deploy with Kamal: A Hands-On Workshop\"\n  raw_title: \"DEPLOY WITH KAMAL: A HANDS-ON WORKSHOP\"\n  speakers:\n    - Cezary Kłos\n  event_name: \"Ruby Community Conference Summer Edition 2024\"\n  date: \"2024-07-29\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"cezary-klos-ruby-community-conference-summer-edition-2024\"\n\n- id: \"hana-harencarova-ruby-community-conference-summer-edition-2024\"\n  title: \"Production story and a brighter future with Rails 8\"\n  raw_title: \"[EN] Production story and a brighter future with Rails 8 - Hana Harencarova\"\n  speakers:\n    - Hana Harencarova\n  event_name: \"Ruby Community Conference Summer Edition 2024\"\n  date: \"2024-07-29\"\n  published_at: \"2024-07-31\"\n  description: |-\n    Hana Harencarová's presentation at the Ruby Community Conference, which took place on July 19, 2024, in Warsaw.\n\n\n    Building for web and mobile in 2024: Production story and a brighter future with Rails 8\n\n    Curious about how to build apps for web and mobile in 2024? Join me as we delve into a real-world production story of building one. Together, we'll uncover the benefits and challenges of creating a web application with native layers. We'll also discuss push notifications, and app architecture that promotes easy feature releases. Finally, we'll look at the promises of Rails 8 to simplify the development process in the future.\n\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at:\n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development:\n    http://bit.ly/SubscribeVisuality\n\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here:\n\n    Instagram:  https://www.instagram.com/visuality.pl/\n    Facebook:  https://www.facebook.com/visualitypl\n    Linkedin: https://pl.linkedin.com/company/visualitypl\n    X:  https://x.com/visuality.pl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"TDQ2wtmgeKw\"\n\n- id: \"cristian-planas-ruby-community-conference-summer-edition-2024\"\n  title: \"2,000 Engineers, 2 Million Lines of Code: The History of a Rails Monolith\"\n  raw_title: \"[EN] 2000 Engineers, 2 millions lines of code: The history of a Rails monolith - Cristian Planas\"\n  speakers:\n    - Cristian Planas\n  event_name: \"Ruby Community Conference Summer Edition 2024\"\n  date: \"2024-07-29\"\n  published_at: \"2024-07-31\"\n  description: |-\n    Cristian Planas's presentation at the Ruby Community Conference took place on July 19, 2024, in Warsaw.\n\n    2000 Engineers, 2 millions lines of code: The history of a Rails monolith\n\n    Rails is the best framework for building your startup. But what happens when the startup becomes a leading business? How do companies that have Rails at the heart of its stack manage growth? How do you maintain a growing application for 15 years in a constantly changing environment? In this presentation Cristian Planas, Senior Staff Engineers at Zendesk, will share with you his and his collegues' 10 years of experience in a company that has succeeded by keeping Rails in its core. He will guide you through the life of a Rails-centered organization, that scaled from zero to hundreds of millions of users.\n\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at:\n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development:\n    http://bit.ly/SubscribeVisuality\n\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here:\n\n    Instagram:  https://www.instagram.com/visuality.pl/\n    Facebook:  https://www.facebook.com/visualitypl\n    Linkedin: https://pl.linkedin.com/company/visualitypl\n    X:  https://x.com/visuality.pl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"CaJvhm1fRWg\"\n\n- id: \"viktor-schmidt-ruby-community-conference-summer-edition-2024\"\n  title: \"Avoiding Pitfalls in Active Record: Practical Usage and Best Practices\"\n  raw_title: \"[EN] Avoiding Pitfalls in Active Record: Practical Usage and Best Practices - Viktor Schmidt\"\n  speakers:\n    - Viktor Schmidt\n  event_name: \"Ruby Community Conference Summer Edition 2024\"\n  date: \"2024-07-29\"\n  published_at: \"2024-07-31\"\n  description: |-\n    Viktor Schmidt's presentation at the Ruby Community Conference took place on July 19, 2024, in Warsaw.\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at:\n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development:\n    http://bit.ly/SubscribeVisuality\n\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here:\n\n    Instagram:  https://www.instagram.com/visuality.pl/\n    Facebook:  https://www.facebook.com/visualitypl\n    Linkedin: https://pl.linkedin.com/company/visualitypl\n    X:  https://x.com/visuality.pl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"RuMJGm6tNKE\"\n\n- id: \"john-gallagher-ruby-community-conference-summer-edition-2024\"\n  title: \"Fix Production Bugs Quickly - The Power of Structured Logging in Rails\"\n  raw_title: \"[EN] Fix Production Bugs Quickly - The Power of Structured Logging in Rails - John Gallagher\"\n  speakers:\n    - John Gallagher\n  event_name: \"Ruby Community Conference Summer Edition 2024\"\n  date: \"2024-07-29\"\n  published_at: \"2024-07-31\"\n  description: |-\n    John Gallagher's presentation at the Ruby Community Conference took place on July 19, 2024, in Warsaw.\n\n\n    Fix Production Bugs Quickly - The Power of Structured Logging in Rails\n\n    Rails apps can be a black box. Have you ever tried to fix a bug where you just can’t understand what’s going on? This talk will give you practical steps to improve the observability of your Rails app, taking the time to understand and fix defects from hours or days to minutes. Rails 8 will bring an exciting new feature: built-in structured logging. This talk will delve into the transformative impact of structured logging on fixing bugs and saving engineers time. Structured logging, as a cornerstone of observability, offers a powerful way to handle logs compared to traditional text-based logs. This session will guide you through the nuances of structured logging in Rails, demonstrating how it can be used to gain better insights into your application’s behavior. This talk will be a practical, technical deep dive into how to make structured logging work with an existing Rails app.\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at:\n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development:\n    http://bit.ly/SubscribeVisuality\n\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here:\n\n    Instagram:  https://www.instagram.com/visuality.pl/\n    Facebook:  https://www.facebook.com/visualitypl\n    Linkedin: https://pl.linkedin.com/company/visualitypl\n    X:  https://x.com/visuality.pl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"0ldZ0TcTWt4\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2024/event.yml",
    "content": "---\nid: \"PLvMNoWK93wtnvS4NiaIkvAf_44u5L7T9n\"\ntitle: \"Ruby Community Conference Winter Edition 2024\"\nkind: \"conference\"\nlocation: \"Warsaw, Poland\"\ndescription: |-\n  The second edition of the Ruby Community Conference, which took place on February 2nd, 2024 at the PKiN in Warsaw.\npublished_at: \"2024-02-22\"\nstart_date: \"2024-02-02\"\nend_date: \"2024-02-02\"\nchannel_id: \"UCVlG6qQ1mGnJv185ayWjEzg\"\nyear: 2024\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubycommunityconference.com/winter2024/\"\ncoordinates:\n  latitude: 52.231838\n  longitude: 21.005995\naliases:\n  - Ruby Warsaw Community Conference 2024 Winter Edition\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2024/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Mariusz Kozieł\n\n  organisations:\n    - Visuality\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2024/venue.yml",
    "content": "---\nname: \"Kinoteka, Palace of Culture and Science\"\n\ndescription: |-\n  Pałac Kultury i Nauki\n\naddress:\n  street: \"1 plac Defilad\"\n  city: \"Warszawa\"\n  region: \"Województwo mazowieckie\"\n  postal_code: \"00-901\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"pl. Defilad 1, 00-901 Warszawa, Poland\"\n\ncoordinates:\n  latitude: 52.231838\n  longitude: 21.005995\n\nmaps:\n  google: \"https://maps.google.com/?q=Kinoteka,+Palace+of+Culture+and+Science,52.2312884,21.0065014\"\n  apple: \"https://maps.apple.com/?q=Kinoteka,+Palace+of+Culture+and+Science&ll=52.2312884,21.0065014\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2312884&mlon=21.0065014\"\n\nlocations:\n  - name: \"Visuality\"\n    kind: \"Workshops\"\n    address:\n      street: \"56 Odolańska\"\n      city: \"Warszawa\"\n      region: \"Województwo mazowieckie\"\n      postal_code: \"02-562\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Odolańska 56, 02-562 Warszawa, Poland\"\n    coordinates:\n      latitude: 52.2002536\n      longitude: 21.0128232\n    maps:\n      google: \"https://maps.google.com/?q=Visuality,52.2002536,21.0128232\"\n      apple: \"https://maps.apple.com/?q=Visuality&ll=52.2002536,21.0128232\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2002536&mlon=21.0128232\"\n\n  - name: \"SOFTSWISS\"\n    kind: \"Workshops\"\n    address:\n      street: \"28 Towarowa\"\n      city: \"Warszawa\"\n      region: \"Województwo mazowieckie\"\n      postal_code: \"00-847\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Towarowa 28, 10th floor, 00-847 Warszawa, Poland\"\n    coordinates:\n      latitude: 52.2313203\n      longitude: 20.9844122\n    maps:\n      google: \"https://maps.google.com/?q=SOFTSWISS,52.2313203,20.9844122\"\n      apple: \"https://maps.apple.com/?q=SOFTSWISS&ll=52.2313203,20.9844122\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2313203&mlon=20.9844122\"\n\n  - name: \"CodersLab\"\n    kind: \"Workshops\"\n    description: |-\n      Prosta Office Centre\n    address:\n      street: \"51 Prosta\"\n      city: \"Warszawa\"\n      region: \"Województwo mazowieckie\"\n      postal_code: \"00-838\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Prosta 51, 00-838 Warszawa, Poland\"\n    coordinates:\n      latitude: 52.2304938\n      longitude: 20.9874117\n    maps:\n      google: \"https://maps.google.com/?q=CodersLab,52.2304938,20.9874117\"\n      apple: \"https://maps.apple.com/?q=CodersLab&ll=52.2304938,20.9874117\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2304938&mlon=20.9874117\"\n\n  - name: \"Bowling Club Arco\"\n    kind: \"After Party\"\n    address:\n      street: \"19 Bitwy Warszawskiej 1920 Roku\"\n      city: \"Warszawa\"\n      region: \"Województwo mazowieckie\"\n      postal_code: \"02-366\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Bitwy Warszawskiej 1920 Roku 19, 02-366 Warszawa, Poland\"\n    coordinates:\n      latitude: 52.2150074\n      longitude: 20.9643141\n    maps:\n      google: \"https://maps.google.com/?q=Bowling+Club+Arco,52.2150074,20.9643141\"\n      apple: \"https://maps.apple.com/?q=Bowling+Club+Arco&ll=52.2150074,20.9643141\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=52.2150074&mlon=20.9643141\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2024/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"steven-baker-ruby-community-conference-winter-edition-2024\"\n  title: \"Renaissance of Ruby on Rails\"\n  raw_title: \"[EN] Renaissance of Ruby on Rails - Steven Baker\"\n  speakers:\n    - Steven Baker\n  event_name: \"Ruby Community Conference Winter Edition 2024\"\n  date: \"2024-02-22\"\n  published_at: \"2024-02-29\"\n  description: |-\n    Renaissance of Ruby on Rails - Ruby on Rails blazed trails in popular web application development with Convention Over Configuration, brought a version of MVC to the masses. All of this in the beautiful, expressive, and enjoyable Ruby programming language.\n\n    But web development moved away. Organisations wanted to split their development teams, and add complexity to the process using micro-services, bifurcating development teams, and complicating deployments with containerisation. Ruby on Rails fell behind the popular curve, and Ruby on Rails entered the Dark Ages.\n\n    In this talk, Steven will explore how the latest release of Ruby on Rails delivers us out of the Dark Ages, and back into the freedom offered by Full-Stack. You will see how, using just what’s built in to Rails, you can deliver highly interactive applications, and take advantage of the benefits of containerised deployments, without complicating your development and deployment workflows.\n\n    Let’s celebrate the Renaissance of Ruby on Rails together!\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at: \n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development: \n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here: \n\n    Instagram: https://www.instagram.com/visuality.pl/\n    Facebook: https://www.facebook.com/visualitypl\n    Linkedin: https://www.linkedin.com/company/visualitypl/\n    X: https://twitter.com/visualitypl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"nrgaeiDlQbI\"\n\n- id: \"xavier-noria-ruby-community-conference-winter-edition-2024\"\n  title: \"Zeitwerk Internals\"\n  raw_title: \"[EN] Zeitwerk Internals - Xavier Noria\"\n  speakers:\n    - Xavier Noria\n  event_name: \"Ruby Community Conference Winter Edition 2024\"\n  date: \"2024-02-22\"\n  published_at: \"2024-02-26\"\n  description: |-\n    Zeitwerk Internals - Zeitwerk is the Ruby gem responsible for autoloading code in modern Rails applications. It also works with other web frameworks and with Ruby gems.\n\n    After attending this talk you’ll have a good understanding of how Zeitwerk works. Going from a conceptual overview of the main ideas, down to implementation details.\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at: \n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development: \n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here: \n\n    Instagram: https://www.instagram.com/visuality.pl/\n    Facebook: https://www.facebook.com/visualitypl\n    Linkedin: https://www.linkedin.com/company/visualitypl/\n    X: https://twitter.com/visualitypl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"W8ZEOq9LTQU\"\n\n- id: \"maciej-mensfeld-ruby-community-conference-winter-edition-2024\"\n  title: \"Future- Proofing Ruby Gems: Strategies For Long-Term Maintenance\"\n  raw_title: \"[EN] Future- Proofing Ruby Gems: Strategies For Long-Term Maintenance - Maciej Mensfeld\"\n  speakers:\n    - Maciej Mensfeld\n  event_name: \"Ruby Community Conference Winter Edition 2024\"\n  date: \"2024-02-26\"\n  published_at: \"2024-03-07\"\n  description: |-\n    Future- Proofing Ruby Gems: Strategies For Long-Term Maintenance \n\n    Embark on an advanced journey with Maciej, where he offers a deep dive into the planning and foresight required when building Ruby OSS gems. This session transcends typical development discussions, focusing on the unique considerations necessary for creating open-source software that stands the test of time. Maciej will share insights from his experience, highlighting the importance of thoughtful decision-making in an environment where a simple fix is not always an option.\n\n    Attendees will learn how to avoid common pitfalls that lead to long-term issues, understand the nuances of building non-standard applications, and gain a new perspective on the delicate balance required to create robust, future-proof open-source software. This talk is an invitation to think differently about software development, encouraging a deep commitment to quality and sustainability in the OSS community.\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at: \n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development: \n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here: \n\n    Instagram: https://www.instagram.com/visuality.pl/\n    Facebook: https://www.facebook.com/visualitypl\n    Linkedin: https://www.linkedin.com/company/visualitypl/\n    X: https://twitter.com/visualitypl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"haJr093oVX0\"\n\n- id: \"micha-cicki-ruby-community-conference-winter-edition-2024\"\n  title: \"Implementing Business Archetypes in Rails\"\n  raw_title: \"[EN] Implementing Business Archetypes in Rails - Michał Łęcicki\"\n  speakers:\n    - Michał Łęcicki\n  event_name: \"Ruby Community Conference Winter Edition 2024\"\n  date: \"2024-02-26\"\n  published_at: \"2024-03-04\"\n  description: |-\n    Implementing Business Archetypes in Rails - An introduction into business archetypes patterns: a great pill of knowledge on how to implement universal concepts occurring in business and business software systems. A complex theory explained with various Rails examples and practical recipes.\n    ____________________________________________\n\n    ► Looking for a dedicated software development team? Contact us at: \n\n    https://visuality.page.link/page\n\n    ► SUBSCRIBE to learn more about software development: \n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n    http://bit.ly/SubscribeVisuality\n\n    ► Read what clients say about us on Clutch.co:\n\n    https://clutch.co/profile/visuality\n\n    ► Find us here: \n\n    Instagram: https://www.instagram.com/visuality.pl/\n    Facebook: https://www.facebook.com/visualitypl\n    Linkedin: https://www.linkedin.com/company/visualitypl/\n    X: https://twitter.com/visualitypl\n    Dribble: https://dribbble.com/VISUALITY\n    GitHub: https://github.com/visualitypl\n  video_provider: \"youtube\"\n  video_id: \"_PLp0JQIuM0\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2025/event.yml",
    "content": "---\nid: \"ruby-community-conference-winter-edition-2025\"\ntitle: \"Ruby Community Conference Winter Edition 2025\"\nkind: \"conference\"\nlocation: \"Kraków, Poland\"\ndescription: |-\n  The fourth edition of the Ruby Community Conference takes place in Cracow! Expect the same high-caliber discussions, practical workshops, and fantastic networking opportunities, all set against the charming backdrop of this historic city.\npublished_at: \"2025-03-17\"\nstart_date: \"2025-02-28\"\nend_date: \"2025-02-28\"\nchannel_id: \"UCVlG6qQ1mGnJv185ayWjEzg\"\nyear: 2025\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubycommunityconference.com\"\ncoordinates:\n  latitude: 50.0505654\n  longitude: 19.931556\naliases:\n  - Ruby Community Conference 2025 Winter Edition\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Mariusz Kozieł\n\n  organisations:\n    - Visuality\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2025/schedule.yml",
    "content": "# Schedule: https://www.rubycommunityconference.com/#agenda\n---\ndays:\n  - name: \"Day Before The Conference\"\n    date: \"2025-02-27\"\n    grid:\n      - start_time: \"Evening\"\n        end_time: \"Evening\"\n        slots: 1\n        items:\n          - title: \"Join Us For KRUG (Kraków Ruby User Group)\"\n            description: |-\n              With Some Fantastic Talks, Followed By A Fun Pre-Party To Kick Things Off!\n\n  - name: \"Conference Day\"\n    date: \"2025-02-28\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - title: \"Workshops\"\n            description: |-\n              The Main Event Starts With Morning Workshops\n\n      - start_time: \"15:00\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - title: \"Conference Hall Opens\"\n            description: |-\n              Registration and welcome\n\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 1\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"17:00\"\n        end_time: \"17:45\"\n        slots: 1\n\n      - start_time: \"17:45\"\n        end_time: \"18:15\"\n        slots: 1\n        items:\n          - Longer Coffee Break\n\n      - start_time: \"18:15\"\n        end_time: \"19:00\"\n        slots: 1\n\n      - start_time: \"19:00\"\n        end_time: \"19:15\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"19:15\"\n        end_time: \"20:00\"\n        slots: 1\n\n      - start_time: \"20:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Museum Tours\n\n      - start_time: \"21:00\"\n        end_time: \"02:30\"\n        slots: 1\n        items:\n          - title: \"After-Party\"\n            description: |-\n              Wraps Up With The After-Party!\n\n  - name: \"Day After The Conference\"\n    date: \"2025-03-01\"\n    grid:\n      - start_time: \"All-Day\"\n        end_time: \"All-Day\"\n        slots: 1\n        items:\n          - title: \"City Tour\"\n            description: |-\n              Stick Around To Explore The Beautiful City Of Kraków With The Ruby Friends.\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Strategic Sponsor\"\n      description: |-\n        Strategic sponsor tier\n      level: 1\n      sponsors:\n        - name: \"Zendesk\"\n          website: \"https://www.zendesk.com/careers/\"\n          slug: \"Zendesk\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/Zendesk_Logo.e170d936.svg\"\n\n    - name: \"Ruby Sponsors\"\n      description: |-\n        Ruby sponsors tier\n      level: 2\n      sponsors:\n        - name: \"Railsware\"\n          website: \"https://railsware.com/\"\n          slug: \"Railsware\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/railsware_logo.7504cef7.svg\"\n\n        - name: \"Cleo\"\n          website: \"https://web.meetcleo.com/careers/\"\n          slug: \"Cleo\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/cleo-logo.2de86fcd.png\"\n\n    - name: \"Regular Sponsors\"\n      description: |-\n        Regular sponsors tier\n      level: 3\n      sponsors:\n        - name: \"Koleo\"\n          website: \"https://koleo.pl/\"\n          slug: \"Koleo\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/koleo.fab642f9.svg\"\n\n        - name: \"2N\"\n          website: \"https://www.2n.pl/\"\n          slug: \"2N\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/2n-logo.c85f6e96.png\"\n\n        - name: \"Timescale\"\n          website: \"https://www.timescale.com/cloud\"\n          slug: \"Timescale\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/timescale_logo.e045d324.png\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2025/venue.yml",
    "content": "---\nname: \"Manggha Museum of Japanese Art and Technology\"\n\naddress:\n  street: \"ul. M. Konopnickiej 26\"\n  city: \"Cracow\"\n  region: \"\"\n  postal_code: \"\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"Marii Konopnickiej 26, 30-302 Kraków, Poland\"\n\ncoordinates:\n  latitude: 50.0505654\n  longitude: 19.931556\n\nmaps:\n  google: \"https://maps.google.com/?q=Manggha+Museum+of+Japanese+Art+and+Technology,50.0505654,19.931556\"\n  apple: \"https://maps.apple.com/?q=Manggha+Museum+of+Japanese+Art+and+Technology&ll=50.0505654,19.931556\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=50.0505654&mlon=19.931556\"\n\nlocations:\n  - name: \"Buma Square\"\n    kind: \"Workshops\"\n    address:\n      street: \"6 Wadowicka\"\n      city: \"Kraków\"\n      region: \"Województwo małopolskie\"\n      postal_code: \"30-415\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Wadowicka 6, 30-415 Kraków, Poland\"\n\n    coordinates:\n      latitude: 50.0326666\n      longitude: 19.9397487\n\n    maps:\n      google: \"https://maps.google.com/?q=Buma+Square,50.0326666,19.9397487\"\n      apple: \"https://maps.apple.com/?q=Buma+Square&ll=50.0326666,19.9397487\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=50.0326666&mlon=19.9397487\"\n\n  - name: \"Railsware\"\n    kind: \"Workshops\"\n    address:\n      street: \"50 Szlak\"\n      city: \"Kraków\"\n      region: \"Województwo małopolskie\"\n      postal_code: \"31-153\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Szlak 50/A4, 31-153 Kraków, Poland\"\n\n    coordinates:\n      latitude: 50.0709704\n      longitude: 19.9442172\n\n    maps:\n      google: \"https://maps.google.com/?q=Railsware,50.0709704,19.9442172\"\n      apple: \"https://maps.apple.com/?q=Railsware&ll=50.0709704,19.9442172\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=50.0709704&mlon=19.9442172\"\n\n  - name: \"Zendesk\"\n    kind: \"Workshops\"\n    address:\n      street: \"29 Marii Konopnickiej\"\n      city: \"Kraków\"\n      region: \"Województwo małopolskie\"\n      postal_code: \"30-302\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Marii Konopnickiej 29, 30-302 Kraków, Poland\"\n\n    coordinates:\n      latitude: 50.0460622\n      longitude: 19.9337023\n\n    maps:\n      google: \"https://maps.google.com/?q=Zendesk,50.0460622,19.9337023\"\n      apple: \"https://maps.apple.com/?q=Zendesk&ll=50.0460622,19.9337023\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=50.0460622&mlon=19.9337023\"\n\n  - name: \"Archeion\"\n    kind: \"Workshops\"\n    description: |-\n      Sala Parmenidesa\n    address:\n      street: \"23 Świętego Filipa\"\n      city: \"Kraków\"\n      region: \"Województwo małopolskie\"\n      postal_code: \"31-150\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Św. Filipa 23/4, 31-150 Kraków, Poland\"\n    coordinates:\n      latitude: 50.0677685\n      longitude: 19.9424013\n\n    maps:\n      google: \"https://maps.google.com/?q=Archeion,50.0677685,19.9424013\"\n      apple: \"https://maps.apple.com/?q=Archeion&ll=50.0677685,19.9424013\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=50.0677685&mlon=19.9424013\"\n\n  - name: \"Archeion\"\n    kind: \"Workshops\"\n    description: |-\n      Sala Platona\n    address:\n      street: \"23 Świętego Filipa\"\n      city: \"Kraków\"\n      region: \"Województwo małopolskie\"\n      postal_code: \"31-150\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Św. Filipa 23/6, 31-150 Kraków, Poland\"\n    coordinates:\n      latitude: 50.0677685\n      longitude: 19.9424013\n\n    maps:\n      google: \"https://maps.google.com/?q=Archeion,50.0677685,19.9424013\"\n      apple: \"https://maps.apple.com/?q=Archeion&ll=50.0677685,19.9424013\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=50.0677685&mlon=19.9424013\"\n\n  - name: \"Czyżówka 14\"\n    kind: \"Workshops\"\n    description: |-\n      Lokal 1.6\n    address:\n      street: \"14 Czyżówka\"\n      city: \"Kraków\"\n      region: \"Województwo małopolskie\"\n      postal_code: \"30-526\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Czyżówka 14, 30-526 Kraków, Poland\"\n    coordinates:\n      latitude: 50.0355164\n      longitude: 19.9449381\n\n    maps:\n      google: \"https://maps.google.com/?q=Czyżówka+14,50.0355164,19.9449381\"\n      apple: \"https://maps.apple.com/?q=Czyżówka+14&ll=50.0355164,19.9449381\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=50.0355164&mlon=19.9449381\"\n\n  - name: \"Manggha Museum of Japanese Art and Technology\"\n    kind: \"After Party\"\n    address:\n      street: \"26 Marii Konopnickiej\"\n      city: \"Kraków\"\n      region: \"Województwo małopolskie\"\n      postal_code: \"30-302\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Marii Konopnickiej 26, 30-302 Kraków, Poland\"\n\n    coordinates:\n      latitude: 50.0505654\n      longitude: 19.931556\n\n    maps:\n      google: \"https://maps.google.com/?q=Manggha+Museum,50.0505654,19.931556\"\n      apple: \"https://maps.apple.com/?q=Manggha+Museum&ll=50.0505654,19.931556\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=50.0505654&mlon=19.931556\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2025/videos.yml",
    "content": "---\n- title: \"Speeding Up Class#new\"\n  raw_title: \"[EN] Speeding Up Class#new - Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  published_at: \"2025-03-17\"\n  announced_at: \"2024-11-26\"\n  id: \"aaron-patterson-ruby-community–conference-winter–edition-2025\"\n  video_provider: \"youtube\"\n  video_id: \"H7jOJfA7MHk\"\n  description: |-\n    Many Ruby developers like to initialize new objects, so let's take a dive into Ruby object initialization! What makes initializing an object slow? Can we use Ruby to speed it up? In this talk, we will examine the internals of the `Class#new` method, explore the trade-offs between Ruby and C method calls, and experiment with a Ruby implementation of `Class#new`. Additionally, we will discuss strategies for speeding up Ruby method calls, such as inline caches, while also considering the drawbacks of moving from C to Ruby.\n\n- title: \"Solid Queue Internals, Externals and All the Things in Between\"\n  raw_title: \"[EN] Solid Queue Internals, Externals and All the Things in Between - Rosa Gutierrez\"\n  speakers:\n    - Rosa Gutiérrez\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  published_at: \"2025-03-17\"\n  announced_at: \"2024-11-20\"\n  description: |-\n    We’ve used Resque and Redis to run background jobs in multiple apps for many years at 37signals. However, performance, reliability, and our own apps’ idiosyncrasies led us to use a lot of different gems, some developed by us, some forked or patched to address our struggles. After multiple war stories with background jobs, looking at our increasingly complex setup, we wanted something we could use out-of-the-box without having to port our collection of hacks to every new app and with fewer moving pieces. After exploring existing alternatives, we decided to build our own and aim to make it the default for Rails 8.\n\n    In this talk, I’ll present Solid Queue, explain some of the problems we had over the years, how we designed Solid Queue to address them, and all the Fun™ we had doing that.\n  video_provider: \"youtube\"\n  video_id: \"AMoM0uIR3uU\"\n  id: \"rosa-gutierrez-ruby-community–conference-winter–edition-2025\"\n\n- title: \"The Joy of Creativity in the Age of AI\"\n  raw_title: \"[EN] The Joy of Creativity in the Age of AI - Paweł Strzałkowski\"\n  speakers:\n    - Paweł Strzałkowski\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  published_at: \"2025-03-17\"\n  announced_at: \"2024-12-23\"\n  description: |-\n    We'll explore how Ruby can unlock new avenues of creativity in the age of AI and cross-technology innovation. By leveraging Ruby's simplicity and adaptability, we can seamlessly integrate cutting-edge solutions like speech recognition and generation, or image analysis and creation. We can also incorporate advanced techniques like vector search into our projects with minimal effort. Let's rediscover the joy of building beyond traditional boundaries and position the Ruby community at the forefront of technological invention and creativity.\n  id: \"the-joy-of-creativity-in-the-age-of-ai-ruby-community–conference-winter–edition-2025\"\n  video_provider: \"youtube\"\n  video_id: \"SFLHBYLgJdI\"\n\n- title: \"From Legacy to Latest: How Zendesk Upgraded a Monolith to Rails 8.0 Overnight\"\n  raw_title: \"[EN] From Legacy to Latest: How Zendesk Upgraded a Monolith to Rails 8.0 Overnight - Thomas Countz\"\n  speakers:\n    - Thomas Countz\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  published_at: \"2025-03-17\"\n  announced_at: \"2025-01-28 10:59:00 UTC\"\n  description: |-\n    The Ruby Platform Core Team at Zendesk supports hundreds of Ruby services, internal gems, and a few massive monoliths. In this talk, the team will share how they upgraded one of their biggest monoliths to Rails 8.0 just 14 hours after it was released, covering the tools and processes that made it happen. Topics include dual booting in production, testing daily against Rails' main branch, tracking gem dependencies, and using production profiling to keep performance in check.\n\n    Thomas is part of Zendesk's Ruby Platform Core team, focusing on infrastructure support for Ruby and Rails across the organization. In his free time, he enjoys working on hardware projects, playing board games, and hiking in the forest with his husband. His career is guided by three core principles: to create, to learn, and to share.\n  id: \"from-legacy-to-latest-ruby-community–conference-winter–edition-2025\"\n  video_provider: \"youtube\"\n  video_id: \"kgVgcNtN5mc\"\n\n- id: \"workshop-building-live-kanban-board-ruby-community–conference-winter–edition-2025\"\n  title: \"Workshop: Building a Live Kanban Board Application With Hotwire and Rails\"\n  raw_title: \"Building a Live Kanban Board Application With Hotwire and Rails\"\n  speakers:\n    - Michał Łęcicki\n    - Piotr Witek\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  description: |-\n    We will build a fully functional Kanban board application with Rails and Hotwire. During the workshops, you will learn the basics of Hotwire, including Turbo Drive, Frames, Turbo Streams, and Stimulus controllers. We will also show how to design backend-frontend communication for dynamic, modern applications with Rails.\n\n    The workshop includes short theoretical introductions, practical examples, and tasks. We will progressively enhance the application with Hotwire.\n\n    This workshop is ideal for those familiar with Hotwire but haven't built a serious app yet. If you're new to Hotwire, don't worry; we'll explain the theory before each task and inspire you to use Hotwire's benefits whenever possible!\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-building-live-kanban-board-ruby-community–conference-winter–edition-2025\"\n\n- id: \"workshop-deploy-with-kamal-2-ruby-community–conference-winter–edition-2025\"\n  title: \"Workshop: Deploy with Kamal 2\"\n  raw_title: \"Deploy with Kamal 2: A Hands-On Workshop\"\n  speakers:\n    - Cezary Kłos\n    - Kaja Witek\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  description: |-\n    We will start the workshop by creating a new Rails 8 application using the “solid” stack and deploying it to a real cloud server. Next, we will explore the scenario of adding Kamal to an existing Rails 7.2 project. We will initialize and configure Kamal. Then, thanks to the new Kamal-proxy, we will deploy it alongside the first application. Following this, we will deploy a staging environment to mirror production settings.\n\n    To ensure you gain practical experience, we will intentionally break our deployment, providing you with hands-on experience in debugging and recovering from not-so-obvious scenarios.\n\n    Whether you’re new to containerized deployments or an experienced developer looking to streamline your workflow, this workshop will equip you with the essential skills to deploy and manage your web apps with confidence. On each step we will guide you trough the process and explain the Kamal’s inner-workings.\n\n    You’ll leave with a deeper understanding of Kamal and the ability to handle deployment challenges effectively! 💪\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-deploy-with-kamal-2-ruby-community–conference-winter–edition-2025\"\n\n- id: \"workshop-taming-the-beast-ruby-community–conference-winter–edition-2025\"\n  title: \"Workshop: Taming The Beast: TDD, Service Objects, and dry.rb for Complex Business Logic\"\n  raw_title: \"Taming The Beast: TDD, Service Objects, and dry.rb for Complex Business Logic\"\n  speakers:\n    - Oskar Lakner\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-taming-the-beast-ruby-community–conference-winter–edition-2025\"\n\n- id: \"workshop-fix-bugs-20x-faster-ruby-community–conference-winter–edition-2025\"\n  title: \"Workshop: Fix Bugs 20x Faster: From Zero To Incident Superhero\"\n  raw_title: \"Fix Bugs 20x Faster: From Zero To Incident Superhero\"\n  speakers:\n    - John Gallagher\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-fix-bugs-20x-faster-ruby-community–conference-winter–edition-2025\"\n\n- id: \"workshop-image-vector-search-ruby-community–conference-winter–edition-2025\"\n  title: \"Workshop: Image Vector Search\"\n  raw_title: \"Image Vector Search\"\n  speakers:\n    - Chris Hasiński\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-image-vector-search-ruby-community–conference-winter–edition-2025\"\n\n- id: \"workshop-updating-to-modern-gem-development-in-2025-ruby-community–conference-winter–edition-2025\"\n  title: \"Workshop: Updating to Modern Gem Development in 2025\"\n  raw_title: \"Updating to Modern Gem Development in 2025\"\n  speakers:\n    - Samuel Giddins\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  description: |-\n    Let's take the default bundle gem scaffold and transform it into the ideal development setup for 2025, including automated testing on CI, automated pushes to rubygems.org, and type checking right in your editor.\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-updating-to-modern-gem-development-in-2025-ruby-community–conference-winter–edition-2025\"\n\n- id: \"workshop-postgresql-performance-for-ruby-developers-ruby-community–conference-winter–edition-2025\"\n  title: \"Workshop: PostgreSQL Performance for Ruby Developers: Deep Dive into Database Performance & TimescaleDB\"\n  raw_title: \"PostgreSQL Performance for Ruby Developers: Deep Dive into Database Performance & TimescaleDB\"\n  speakers:\n    - Jônatas Paganini\n  event_name: \"Ruby Community Conference Winter Edition 2025\"\n  date: \"2025-02-28\"\n  announced_at: \"2025-01-30 10:58:00 UTC\"\n  description: |-\n    Join our hands-on workshop to explore PostgreSQL internals, query optimization, and time-series data with TimescaleDB. Learn how to debug queries with EXPLAIN ANALYZE, optimize transactions for high-concurrency apps, and fine-tune database performance. A must-attend for Ruby developers working with PostgreSQL!\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-postgresql-performance-for-ruby-developers-ruby-community–conference-winter–edition-2025\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2026/event.yml",
    "content": "---\nid: \"ruby-community-conference-winter-edition-2026\"\ntitle: \"Ruby Community Conference Winter Edition 2026\"\nkind: \"conference\"\nlocation: \"Kraków, Poland\"\ndescription: \"\"\nstart_date: \"2026-03-13\"\nend_date: \"2026-03-13\"\nchannel_id: \"UCVlG6qQ1mGnJv185ayWjEzg\"\nyear: 2026\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubycommunityconference.com\"\nluma: \"https://lu.ma/RubyCommunityConference2026\"\ntickets_url: \"https://lu.ma/RubyCommunityConference2026\"\ncoordinates:\n  latitude: 50.0505654\n  longitude: 19.931556\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2026/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Mariusz Kozieł\n\n  organisations:\n    - Visuality\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2026/schedule.yml",
    "content": "# docs/ADDING_SCHEDULES.md\n# TODO: After-party goes until 2:30am, but schedules only support until midnight\n# TODO: Order talks once schedule is fully revealed\n---\ndays:\n  - name: \"Day Before the Conference\"\n    date: \"2026-03-12\"\n    grid:\n      - start_time: \"18:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - title: \"Kraków Ruby User Group\"\n            description: |-\n              Join us for KRUG (Kraków Ruby User Group) Hosted at Zendesk, ul. Marii Konopnickiej 29, Kraków\n  - name: \"Conference Day\"\n    date: \"2026-03-13\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"14:00\"\n        slots: 7\n      - start_time: \"15:00\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - The conference hall opens\n      - start_time: \"16:00\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - The official start of the conference\n      - start_time: \"16:00\"\n        end_time: \"16:45\"\n        slots: 1\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Coffee break\n      - start_time: \"17:00\"\n        end_time: \"17:45\"\n        slots: 1\n      - start_time: \"17:45\"\n        end_time: \"18:15\"\n        slots: 1\n        items:\n          - Longer coffee break\n      - start_time: \"18:15\"\n        end_time: \"19:00\"\n        slots: 1\n      - start_time: \"19:00\"\n        end_time: \"19:15\"\n        slots: 1\n        items:\n          - Coffee break\n      - start_time: \"19:15\"\n        end_time: \"19:30\"\n        slots: 1\n      - start_time: \"19:30\"\n        end_time: \"19:45\"\n        slots: 1\n      - start_time: \"19:45\"\n        end_time: \"20:00\"\n        slots: 1\n      - start_time: \"20:00\"\n        end_time: \"20:15\"\n        slots: 1\n      - start_time: \"20:15\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Museum tours\n      - start_time: \"21:00\"\n        end_time: \"26:30\"\n        slots: 1\n        items:\n          - After-party!\n  - name: \"Day After the Conference\"\n    date: \"2026-03-14\"\n    grid:\n      - start_time: \"12:00\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - title: \"Trip to Wieliczka Salt Mine\"\n            description: |-\n              Trip to the UNESCO-listed World Heritage Site, including round-trip train transport from Kraków and a 2–3 hour English-guided tour. Separate ticket is required on Luma.\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2026/sponsors.yml",
    "content": "# docs/ADDING_SPONSORS.md\n---\n- tiers:\n    - name: \"Strategic Sponsor\"\n      level: 1\n      sponsors:\n        - name: \"Zendesk\"\n          website: \"https://www.zendesk.com/careers/\"\n          slug: \"zendesk\"\n    - name: \"Ruby Sponsor\"\n      level: 2\n      sponsors:\n        - name: \"typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"typesense\"\n    - name: \"Regular Sponsor\"\n      level: 3\n      sponsors:\n        - name: \"infakt\"\n          website: \"https://www.infakt.pl\"\n          slug: \"infakt\"\n        - name: \"sequra\"\n          website: \"https://www.sequra.com/\"\n          slug: \"sequra\"\n          logo_url: \"https://rubycommunityconference.com/_next/static/media/sequra-logo.1cebf986.png\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2026/venue.yml",
    "content": "---\nname: \"Manggha Museum of Japanese Art and Technology\"\n\ndescription: |-\n  Muzeum Sztuki i Techniki Japońskiej Manggha\n\naddress:\n  street: \"26 Marii Konopnickiej\"\n  city: \"Kraków\"\n  region: \"Województwo małopolskie\"\n  postal_code: \"30-302\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"Marii Konopnickiej 26, 30-302 Kraków, Poland\"\ncoordinates:\n  latitude: 50.0505654\n  longitude: 19.931556\nmaps:\n  google: \"https://maps.google.com/?q=Manggha+Museum,50.0505654,19.931556\"\n  apple: \"https://maps.apple.com/?q=Manggha+Museum&ll=50.0505654,19.931556\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=50.0505654&mlon=19.931556\"\n\nlocations:\n  - name: \"Manggha Museum of Japanese Art and Technology\"\n    kind: \"After Party\"\n    address:\n      street: \"26 Marii Konopnickiej\"\n      city: \"Kraków\"\n      region: \"Województwo małopolskie\"\n      postal_code: \"30-302\"\n      country: \"Poland\"\n      country_code: \"PL\"\n      display: \"Marii Konopnickiej 26, 30-302 Kraków, Poland\"\n    coordinates:\n      latitude: 50.0505654\n      longitude: 19.931556\n    maps:\n      google: \"https://maps.google.com/?q=Manggha+Museum,50.0505654,19.931556\"\n      apple: \"https://maps.apple.com/?q=Manggha+Museum&ll=50.0505654,19.931556\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=50.0505654&mlon=19.931556\"\n"
  },
  {
    "path": "data/ruby-community-conference/ruby-community-conference-winter-edition-2026/videos.yml",
    "content": "---\n- id: \"cezary-klos-kaja-witek-ruby-community-conference-winter-edition-2026\"\n  title: \"Workshop: Deploy with Kamal\"\n  speakers:\n    - Cezary Kłos\n    - Kaja Witek\n  event_name: \"Ruby Community Conference Winter Edition 2026\"\n  date: \"2026-03-13\"\n  announced_at: \"2025-12-16\"\n  video_provider: \"scheduled\"\n  video_id: \"cezary-klos-kaja-witek-ruby-community-conference-winter-edition-2026\"\n  kind: \"workshop\"\n  description: |-\n    Get hands-on experience deploying Rails applications with Kamal, the modern deployment tool from 37signals. Learn to deploy to your own servers with zero downtime.\n\n- id: \"michal-lecicki-ruby-community-conference-winter-edition-2026\"\n  title: \"Workshop: Building a Live Kanban Board with Hotwire and Rails\"\n  speakers:\n    - Michał Łęcicki\n    - Piotr Witek\n  event_name: \"Ruby Community Conference Winter Edition 2026\"\n  date: \"2026-03-13\"\n  announced_at: \"2025-12-16\"\n  kind: \"workshop\"\n  description: |-\n    Build a fully functional live Kanban board from scratch using Hotwire and Rails. Master Turbo Streams, Stimulus controllers, and real-time updates without writing JavaScript.\n  video_provider: \"scheduled\"\n  video_id: \"michal-lecicki-ruby-community-conference-winter-edition-2026\"\n\n- id: \"sebastian-tekieli-ruby-community-conference-winter-edition-2026\"\n  title: \"Workshop: Hotwire Native – Build Mobile Apps the Rails Way\"\n  speakers:\n    - Sebastian Tekieli\n    - Alexander Repnikov\n  event_name: \"Ruby Community Conference Winter Edition 2026\"\n  date: \"2026-03-13\"\n  announced_at: \"2025-12-16\"\n  kind: \"workshop\"\n  description: |-\n    Discover how to build native mobile apps for iOS and Android using Hotwire Native. Learn the Rails way of mobile development without leaving your comfort zone.\n  video_provider: \"scheduled\"\n  video_id: \"sebastian-tekieli-ruby-community-conference-winter-edition-2026\"\n\n- id: \"pawel-strzalkowski-ruby-community-conference-winter-edition-2026\"\n  title: \"Workshop: Model Context Protocol in Ruby on Rails\"\n  speakers:\n    - Paweł Strzałkowski\n  event_name: \"Ruby Community Conference Winter Edition 2026\"\n  date: \"2026-03-13\"\n  announced_at: \"2025-12-16\"\n  kind: \"workshop\"\n  description: |-\n    Explore Model Context Protocol (MCP) and learn how to integrate AI assistants with your Rails applications. Build custom MCP servers and connect them to Claude and other AI models.\n  video_provider: \"scheduled\"\n  video_id: \"pawel-strzalkowski-ruby-community-conference-winter-edition-2026\"\n\n- id: \"oskar-lakner-ruby-community-conference-winter-edition-2026\"\n  title: \"Workshop: From Code to Product: Build a Startup That Actually Works\"\n  description: |-\n    Learn how to turn an idea into a startup that doesn't fail in the first year. Most technical founders skip the fundamentals - they build before validating, split equity badly, and ship products nobody wants. In this hands-on workshop, we'll cover the complete journey: validating ideas before writing code, building teams without destroying friendships, avoiding the traps that kill 90% of startups, and scoping an MVP that actually ships.\n  date: \"2026-03-13\"\n  announced_at: \"2025-12-16\"\n  kind: \"workshop\"\n  speakers:\n    - Oskar Lakner\n  video_provider: \"scheduled\"\n  video_id: \"oskar-lakner-ruby-community-conference-winter-edition-2026\"\n\n- id: \"chris-hasinski-ruby-community-conference-winter-edition-2026\"\n  title: \"Workshop: Training an LLM from scratch with torch.rb\"\n  speakers:\n    - Chris Hasiński\n  event_name: \"Ruby Community Conference Winter Edition 2026\"\n  date: \"2026-03-13\"\n  announced_at: \"2025-12-16\"\n  kind: \"workshop\"\n  description: |-\n    Ever wondered how Large Language Models are actually built - from raw data to a talking model - but felt that most explanations stop at Python boilerplate?\n    Good news: we're doing it in Ruby.\n    In this hands-on workshop we'll build a real, working LLM from scratch, focusing on the pre-training phase. Using nanoGPT and torch.rb, we'll walk through the full pipeline: tokenization, model architecture, training loop, and finally running a model that mimics your own data.\n  video_provider: \"scheduled\"\n  video_id: \"chris-hasinski-ruby-community-conference-winter-edition-2026\"\n\n- id: \"carmine-paolino-ruby-community-conference-winter-edition-2026\"\n  title: \"Workshop: Building AI Apps in Ruby and Rails with RubyLLM\"\n  speakers:\n    - Carmine Paolino\n  event_name: \"Ruby Community Conference Winter Edition 2026\"\n  date: \"2026-03-13\"\n  announced_at: \"2026-01-08\"\n  kind: \"workshop\"\n  description: |-\n    Learn how to build modern AI-powered applications in Ruby and Rails using RubyLLM, the leading open-source framework for AI development in the Ruby ecosystem. In this hands-on workshop, we’ll build a real AI-powered Rails application together and explore how RubyLLM makes AI development simple, flexible, and production-ready.\n  video_provider: \"scheduled\"\n  video_id: \"carmine-paolino-ruby-community-conference-winter-edition-2026\"\n\n- id: \"obie-fernandez-ruby-community-conference-winter-edition-2026\"\n  title: \"Ruby & AI conversation\"\n  raw_title: \"Ruby & AI conversation - Obie Fernandez [EN]\"\n  description: |-\n    A conversation about the intersection of Ruby and AI technologies, exploring opportunities and challenges.\n  speakers:\n    - Obie Fernandez\n  date: \"2026-03-13\"\n  announced_at: \"2025-12-10\"\n  published_at: \"2026-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"BoXGn5-onb0\"\n\n- id: \"marco-roth-ruby-community-conference-winter-edition-2026\"\n  title: \"Herb to ReActionView: A New Foundation for the View Layer\"\n  raw_title: \"Herb and ReActionView - Marco Roth [EN]\"\n  description: |-\n    This talk is an overview of how Herb came to be, what Herb can do for you today, and what the future with ReActionView might look like and how Herb could enable it.\n  speakers:\n    - Marco Roth\n  date: \"2026-03-13\"\n  announced_at: \"2025-12-30\"\n  published_at: \"2026-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"NXYriXsz6Uo\"\n\n- id: \"carmine-paolino-talk-ruby-community-conference-winter-edition-2026\"\n  title: \"Ruby Is the Best Language for Building AI Web Apps\"\n  raw_title: \"Ruby Is the Best Language for Building AI Web Apps - Carmine Paolino [EN]\"\n  description: |-\n    Everyone says you need Python to build serious AI apps. That used to be true for training models, but most teams today are building products on top of APIs. This talk shows, with real code and production experience, why Ruby can be a better default for that work: less ceremony, cleaner agent abstractions, and faster iteration. The thesis is simple: when complexity drops, product quality goes up.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-03-13\"\n  published_at: \"2026-04-16\"\n  speakers:\n    - Carmine Paolino\n  video_provider: \"youtube\"\n  video_id: \"ucAwF9ZPZo4\"\n\n- id: \"chris-hasinski-lightning_talk-ruby-community-conference-winter-edition-2026\"\n  title: \"Doom\"\n  raw_title: \"Doom - Chris Hasiński [EN]\"\n  kind: \"lightning_talk\"\n  description: \"\"\n  date: \"2026-03-13\"\n  published_at: \"2026-04-16\"\n  speakers:\n    - Chris Hasiński\n  video_provider: \"youtube\"\n  video_id: \"tBNPfMqxUHQ\"\n\n- id: \"sergey-sergyenko-lightning_talk-ruby-community-conference-winter-edition-2026\"\n  title: \"The 00 Robot Arm: Low-Cost Open-Source Infrastructure for Embodied AI Inference\"\n  description: \"\"\n  kind: \"lightning_talk\"\n  date: \"2026-03-13\"\n  speakers:\n    - Sergey Sergyenko\n  video_provider: \"scheduled\"\n  video_id: \"sergey-sergyenko-lightning_talk-ruby-community-conference-winter-edition-2026\"\n\n- id: \"pawel-strzalkowski-lightning_talk-ruby-community-conference-winter-edition-2026\"\n  title: \"Make a game with Ruby and Model Context Protocol\"\n  raw_title: \"Make a game with Ruby and Model Context Protocol - Paweł Strzałkowski [EN]\"\n  description: \"\"\n  kind: \"lightning_talk\"\n  date: \"2026-03-13\"\n  published_at: \"2026-04-16\"\n  speakers:\n    - Paweł Strzałkowski\n  video_provider: \"youtube\"\n  video_id: \"ecRCx-8Vjgk\"\n\n- id: \"nick-sutterer-lightning_talk-ruby-community-conference-winter-edition-2026\"\n  title: \"The Story\"\n  raw_title: \"The Story - Nick Sutterer [EN]\"\n  description: \"\"\n  kind: \"lightning_talk\"\n  date: \"2026-03-13\"\n  published_at: \"2026-04-16\"\n  speakers:\n    - Nick Sutterer\n  video_provider: \"youtube\"\n  video_id: \"OmY7fVfL878\"\n"
  },
  {
    "path": "data/ruby-community-conference/series.yml",
    "content": "---\nname: \"Ruby Community Conference\"\nwebsite: \"https://www.rubycommunityconference.com\"\ntwitter: \"visualitypl\"\nkind: \"conference\"\nfrequency: \"biyearly\"\nplaylist_matcher: \"Ruby Community Conference\"\ndefault_country_code: \"PL\"\nyoutube_channel_name: \"Visualitypl\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCVlG6qQ1mGnJv185ayWjEzg\"\naliases:\n  - RCC\n  - RuCoCo\n"
  },
  {
    "path": "data/ruby-cwb/ruby-cwb-meetup/event.yml",
    "content": "---\nid: \"ruby-cwb-meetup\"\ntitle: \"Ruby CWB Meetup\"\ndescription: |-\n  RubyCWB - Curitiba Ruby Meetups\nlocation: \"Curitiba, Brazil\"\nplaylist: \"https://www.youtube.com/@rubycwb\"\nwebsite: \"https://rubycwb.com.br\"\nkind: \"meetup\"\nbanner_background: \"#FADCDC\"\nfeatured_background: \"#FADCDC\"\nfeatured_color: \"#E00101\"\ncoordinates:\n  latitude: -25.4268985\n  longitude: -49.2651984\n"
  },
  {
    "path": "data/ruby-cwb/ruby-cwb-meetup/videos.yml",
    "content": "---\n- title: \"RubyCWB 2nd Edition\"\n  raw_title: \"Ruby CWB - 2ª Edição\"\n  event_name: \"RubyCWB 2nd Edition\"\n  date: \"2025-07-11\"\n  published_at: \"2025-07-12\"\n  announced_at: \"2025-07-02 18:00:00 UTC\"\n  video_provider: \"children\"\n  video_id: \"ruby-cwb-2-edition\"\n  id: \"ruby-cwb-2-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby CWB - 2ª Edição\n\n    Date: Friday, July 11, 2025\n    Time: 7:00 PM - 9:00 PM BRT\n    Location: Pipefy, 3rd Floor\n    Address: Av. João Gualberto, 1740 - Juvevê, Curitiba - PR, 80030-001, Brasil\n\n    Sponsored by Pipefy, a Curitiba-based company using Ruby on Rails.\n\n    Schedule:\n    18:30 - 19:00: Registration + Welcome Coffee ☕️\n    19:00 - 19:15: Opening\n    19:15 - 19:45: Talk 1 - From React to Rails (Italo Aurelio)\n    19:45 - 20:15: Talk 2 - The House that Jack Built - OOD em Ruby (André Kupkovski)\n    20:15 - 20:45: Talk 3 - Ruby on Sinatra + Arquitetura Hexagonal (Eduardo Nakanishi)\n    20:45 - 21:00: Closing\n\n    The second edition of RubyCWB aimed to be \"the best Ruby event Curitiba has ever seen\" with three talks featuring practical experiences with Rails, object-oriented design, and alternative architectures in Ruby.\n\n    50 tickets were available for this event, building on the success of the previous event with 34 participants.\n\n    https://www.meetup.com/ruby-cwb/events/308396313/\n  talks:\n    - title: \"From React to Rails\"\n      raw_title: \"Italo Aurelio - From React to Rails | RubyCWB 2ª Edição\"\n      speakers:\n        - \"Italo Aurelio\"\n      event_name: \"RubyCWB 2nd Edition\"\n      date: \"2025-07-11\"\n      published_at: \"2025-07-12\"\n      announced_at: \"2025-07-02 18:00:00 UTC\"\n      video_provider: \"youtube\"\n      video_id: \"Phe1GUKZ3x8\"\n      id: \"italo-aurelio-ruby-cwb-2-edition\"\n      language: \"portuguese\"\n      description: |-\n        Minha jornada migrando do Next.js + React para o Ruby on Rails com Inertia.js\n\n    - title: \"The House that Jack Built - OOD em Ruby\"\n      raw_title: \"André Kupkovski - The House that Jack Built - OOD em ruby | RubyCWB 2ª Edição\"\n      speakers:\n        - \"André Kupkovski\"\n      event_name: \"RubyCWB 2nd Edition\"\n      date: \"2025-07-11\"\n      published_at: \"2025-07-12\"\n      announced_at: \"2025-07-02 18:00:00 UTC\"\n      video_provider: \"youtube\"\n      video_id: \"jnnakcjr2dw\"\n      id: \"andre-kupkovski-ruby-cwb-2-edition\"\n      language: \"portuguese\"\n      description: |-\n        Apresentando um trecho de uma talk da Sandi Metz, com uma abordagem bem prática da aplição de conceitos básicos de Design Orientado a Objetos\n\n    - title: \"Ruby on Sinatra + Arquitetura Hexagonal\"\n      raw_title: \"Eduardo Nakanishi - Ruby on Sinatra + Arquitetura Hexagonal | RubyCWB 2ª Edição\"\n      speakers:\n        - \"Eduardo Nakanishi\"\n      event_name: \"RubyCWB 2nd Edition\"\n      date: \"2025-07-11\"\n      published_at: \"2025-07-12\"\n      announced_at: \"2025-07-02 18:00:00 UTC\"\n      video_provider: \"youtube\"\n      video_id: \"G1AITT-MiW0\"\n      id: \"eduardo-nakanishi-ruby-cwb-2-edition\"\n      language: \"portuguese\"\n      description: |-\n        Uma alternativa para desenvolver aplicações em Ruby sem as convenções do Rails\n\n        Repo: https://github.com/eduardoyutaka/hexagonal-architecture\n      additional_resources:\n        - name: \"eduardoyutaka/hexagonal-architecture\"\n          type: \"repo\"\n          url: \"https://github.com/eduardoyutaka/hexagonal-architecture\"\n"
  },
  {
    "path": "data/ruby-cwb/series.yml",
    "content": "---\nname: \"Ruby CWB\"\nwebsite: \"https://rubycwb.com.br\"\ngithub: \"https://github.com/ruby-cwb\"\nmeetup: \"https://www.meetup.com/ruby-cwb\"\ntwitter: \"\"\nyoutube_channel_name: \"rubycwb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"BR\"\nlanguage: \"portuguese\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-dcamp/ruby-dcamp-2014/event.yml",
    "content": "---\nid: \"ruby-dcamp-2014\"\ntitle: \"Ruby DCamp 2014\"\ndescription: \"\"\nlocation: \"Prince William Forest Park, VA, United States\"\nkind: \"retreat\"\nstart_date: \"2014-10-10\"\nend_date: \"2014-10-12\"\nwebsite: \"http://rubydcamp.org/\"\ntwitter: \"ruby_dcamp\"\ncoordinates:\n  latitude: 38.5853701\n  longitude: -77.38417179999999\n"
  },
  {
    "path": "data/ruby-dcamp/ruby-dcamp-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubydcamp.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-dcamp/series.yml",
    "content": "---\nname: \"Ruby DCamp\"\nwebsite: \"http://rubydcamp.org/\"\ntwitter: \"ruby_dcamp\"\nyoutube_channel_name: \"\"\nkind: \"retreat\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-dev-summit/ruby-dev-summit-2017/event.yml",
    "content": "---\nid: \"ruby-dev-summit-2017\"\ntitle: \"Ruby Dev Summit 2017\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2017-10-16\"\nend_date: \"2017-10-21\"\ncoordinates: false\n"
  },
  {
    "path": "data/ruby-dev-summit/ruby-dev-summit-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-dev-summit/series.yml",
    "content": "---\nname: \"Ruby Dev Summit\"\nwebsite: \"\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-df/ruby-df-meetup/event.yml",
    "content": "---\nid: \"ruby-df-meetup\"\ntitle: \"Ruby DF Meetup\"\nkind: \"meetup\"\nlocation: \"Brasília, Brazil\"\ndescription: |-\n  Ruby DF is a Ruby community meetup in Brasília, Distrito Federal, Brazil.\n  The group gathers Ruby developers and enthusiasts to share knowledge,\n  experiences, and network.\nbanner_background: \"#D30000\"\nfeatured_background: \"#D30000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubydf.com\"\ngithub: \"https://github.com/Ruby-DF\"\nyoutube: \"https://www.youtube.com/@ruby-df\"\ncoordinates:\n  latitude: -15.7942287\n  longitude: -47.8821658\n"
  },
  {
    "path": "data/ruby-df/ruby-df-meetup/videos.yml",
    "content": "---\n- id: \"ruby-df-1-edition\"\n  title: \"Ruby DF 1st Edition - Pilot\"\n  event_name: \"Ruby DF 1st Edition\"\n  date: \"2023-10-07\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-1-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's pilot meetup, hosted at Universidade de Brasília - Faculdade do Gama.\n\n    Sponsors: thoughtbot, LAPPIS.\n\n    https://rubydf.com/events/piloto/\n  talks:\n    - title: \"Taming God Objects - Easy, incremental and safe\"\n      event_name: \"Ruby DF 1st Edition\"\n      date: \"2023-10-07\"\n      video_provider: \"not_recorded\"\n      video_id: \"matheus-richard-ruby-df-1-edition\"\n      id: \"matheus-richard-ruby-df-1-edition\"\n      language: \"portuguese\"\n      slides_url: \"https://docs.google.com/presentation/d/1YIDrzxoVWPtkbRbcv9_GkRvg5DmKU5JcmYKc0tK5qhE/edit?usp=sharing\"\n      speakers:\n        - \"Matheus Richard\"\n\n- id: \"ruby-df-2-edition\"\n  title: \"Ruby DF 2nd Edition - February 2024\"\n  event_name: \"Ruby DF 2nd Edition\"\n  date: \"2024-02-03\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-2-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's second edition, hosted at Universidade de Brasília - Faculdade de Tecnologia.\n\n    Sponsors: thoughtbot, Switch Dreams.\n\n    https://rubydf.com/events/segunda-edicao/\n  talks:\n    - title: \"Ruby on Rails: Putting Security on the Rails\"\n      raw_title: \"Ruby on Rails: Colocando a segurança nos trilhos\"\n      event_name: \"Ruby DF 2nd Edition\"\n      date: \"2024-02-03\"\n      video_provider: \"not_recorded\"\n      video_id: \"jose-augusto-dias-rosa-ruby-df-2-edition\"\n      id: \"jose-augusto-dias-rosa-ruby-df-2-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"José Augusto Dias Rosa\"\n\n    - title: \"Riding the Rails of Magic: The journey between request and response\"\n      event_name: \"Ruby DF 2nd Edition\"\n      date: \"2024-02-03\"\n      video_provider: \"not_recorded\"\n      video_id: \"alexandre-calaca-ruby-df-2-edition\"\n      id: \"alexandre-calaca-ruby-df-2-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Alexandre Calaça\"\n\n    - title: \"Security First: Building an Authorization Layer for your Rails Application\"\n      raw_title: \"Segurança em primeiro lugar: Como construir a Camada de autorização para sua aplicação Rails\"\n      event_name: \"Ruby DF 2nd Edition\"\n      date: \"2024-02-03\"\n      video_provider: \"not_recorded\"\n      video_id: \"pedro-augusto-ramalho-duarte-ruby-df-2-edition\"\n      id: \"pedro-augusto-ramalho-duarte-ruby-df-2-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Pedro Augusto Ramalho Duarte\"\n\n- id: \"ruby-df-3-edition\"\n  title: \"Ruby DF 3rd Edition - July 2024\"\n  event_name: \"Ruby DF 3rd Edition\"\n  date: \"2024-07-27\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-3-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's third edition, hosted at Blocks Coworking & Offices, Águas Claras.\n\n    Sponsors: thoughtbot, ludoteca.\n\n    https://rubydf.com/events/terceira-edicao/\n  talks:\n    - title: \"Rails is...\"\n      raw_title: \"Rails é...\"\n      event_name: \"Ruby DF 3rd Edition\"\n      date: \"2024-07-27\"\n      video_provider: \"not_recorded\"\n      video_id: \"lazaro-nixon-ruby-df-3-edition\"\n      id: \"lazaro-nixon-ruby-df-3-edition\"\n      language: \"portuguese\"\n      slides_url: \"https://drive.google.com/file/d/1T-dvjzYHKEg2k4rG7HIGJhhxpzoRAD3q/view?usp=sharing\"\n      speakers:\n        - \"Lázaro Nixon\"\n\n    - title: \"Practical Tips to Land Your First Ruby Job\"\n      raw_title: \"Dicas Práticas Para Conquistar Seu Primeiro Salário com Ruby\"\n      event_name: \"Ruby DF 3rd Edition\"\n      date: \"2024-07-27\"\n      video_provider: \"not_recorded\"\n      video_id: \"pedro-schmitt-ruby-df-3-edition\"\n      id: \"pedro-schmitt-ruby-df-3-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Pedro Schmitt\"\n\n    - title: \"The Fast Lane: Async Rails\"\n      event_name: \"Ruby DF 3rd Edition\"\n      date: \"2024-07-27\"\n      video_provider: \"not_recorded\"\n      video_id: \"matheus-richard-ruby-df-3-edition\"\n      id: \"matheus-richard-ruby-df-3-edition\"\n      language: \"portuguese\"\n      slides_url: \"https://docs.google.com/presentation/d/1zwy3RZhH4TOKBTEYPqtaK2Bl_d8bcIc9VhKr9t9lasw/edit?usp=sharing\"\n      speakers:\n        - \"Matheus Richard\"\n\n- id: \"ruby-df-4-edition\"\n  title: \"Ruby DF 4th Edition - January 2025\"\n  event_name: \"Ruby DF 4th Edition\"\n  date: \"2025-01-25\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-4-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's fourth edition, hosted at Blocks Coworking & Offices, Águas Claras.\n\n    Sponsors: thoughtbot, ludoteca.\n\n    https://rubydf.com/events/quarta-edicao/\n  talks:\n    - title: \"Build Your Own Gem\"\n      raw_title: \"Construa Sua Própria Gem\"\n      event_name: \"Ruby DF 4th Edition\"\n      date: \"2025-01-25\"\n      video_provider: \"not_recorded\"\n      video_id: \"jose-augusto-dias-rosa-ruby-df-4-edition\"\n      id: \"jose-augusto-dias-rosa-ruby-df-4-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"José Augusto Dias Rosa\"\n\n    - title: \"Rails and Blockchain Applications: Challenges and How to Solve Them\"\n      raw_title: \"Aplicação com Rails e Blockchain: quais os desafios e como resolvê-los\"\n      event_name: \"Ruby DF 4th Edition\"\n      date: \"2025-01-25\"\n      video_provider: \"not_recorded\"\n      video_id: \"thiago-ribeiro-ruby-df-4-edition\"\n      id: \"thiago-ribeiro-ruby-df-4-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Thiago Ribeiro\"\n\n    - title: \"How Rails is Shaping Democracy in Brazil\"\n      raw_title: \"Como Rails está moldando a democracia no Brasil\"\n      event_name: \"Ruby DF 4th Edition\"\n      date: \"2025-01-25\"\n      video_provider: \"not_recorded\"\n      video_id: \"maicon-mares-ruby-df-4-edition\"\n      id: \"maicon-mares-ruby-df-4-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Maicon Mares\"\n\n- id: \"ruby-df-5-edition\"\n  title: \"Ruby DF 5th Edition - Carnaval Refactoring\"\n  event_name: \"Ruby DF 5th Edition\"\n  date: \"2025-03-01\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-5-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's fifth edition: a Carnaval-themed group refactoring session.\n\n    Sponsor: thoughtbot.\n\n    https://rubydf.com/events/quinta-edicao/\n  talks:\n    - title: \"Group Refactoring Session\"\n      raw_title: \"Sessão de Refatoração em Grupo\"\n      event_name: \"Ruby DF 5th Edition\"\n      date: \"2025-03-01\"\n      video_provider: \"not_recorded\"\n      video_id: \"matheus-richard-ruby-df-5-edition\"\n      id: \"matheus-richard-ruby-df-5-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Matheus Richard\"\n\n- id: \"ruby-df-6-edition\"\n  title: \"Ruby DF 6th Edition - Behind the Scenes of Ruby\"\n  event_name: \"Ruby DF 6th Edition\"\n  date: \"2025-05-10\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-6-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's sixth edition: a deep dive into Ruby internals.\n\n    Sponsor: thoughtbot.\n\n    https://rubydf.com/events/sexta-edicao/\n  talks:\n    - title: \"Ruby Internals: A Guide for Rails Developers\"\n      event_name: \"Ruby DF 6th Edition\"\n      date: \"2025-05-10\"\n      video_provider: \"not_recorded\"\n      video_id: \"matheus-richard-ruby-df-6-edition\"\n      id: \"matheus-richard-ruby-df-6-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Matheus Richard\"\n\n- id: \"ruby-df-7-edition\"\n  title: \"Ruby DF 7th Edition - Group Refactoring\"\n  event_name: \"Ruby DF 7th Edition\"\n  date: \"2025-06-28\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-7-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's seventh edition: group pairing and refactoring session.\n\n    Sponsors: thoughtbot, ludoteca.\n\n    https://rubydf.com/events/setima-edicao/\n  talks:\n    - title: \"Refactoring: Group Pairing Session\"\n      raw_title: \"Refatorando: Sessão de pareamento em grupo\"\n      event_name: \"Ruby DF 7th Edition\"\n      date: \"2025-06-28\"\n      video_provider: \"not_recorded\"\n      video_id: \"matheus-richard-ruby-df-7-edition\"\n      id: \"matheus-richard-ruby-df-7-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Matheus Richard\"\n\n- id: \"ruby-df-8-edition\"\n  title: \"Ruby DF 8th Edition - Your First Job in Ruby\"\n  event_name: \"Ruby DF 8th Edition\"\n  date: \"2025-08-16\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-8-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's eighth edition: practical guidance on landing your first Ruby job.\n\n    Sponsors: ludoteca, Switch Dreams, thoughtbot.\n\n    https://rubydf.com/events/oitava-edicao/\n  talks:\n    - title: \"Practical Tips to Land Your First Ruby Job\"\n      raw_title: \"Dicas Práticas Para Conquistar Seu Primeiro Salário com Ruby\"\n      event_name: \"Ruby DF 8th Edition\"\n      date: \"2025-08-16\"\n      video_provider: \"not_recorded\"\n      video_id: \"pedro-schmitt-ruby-df-8-edition\"\n      id: \"pedro-schmitt-ruby-df-8-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Pedro Schmitt\"\n\n- id: \"ruby-df-9-edition\"\n  title: \"Ruby DF 9th Edition - Components in Rails without Complication\"\n  event_name: \"Ruby DF 9th Edition\"\n  date: \"2025-10-18\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-9-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's ninth edition: opinionated frontend for your no-build application.\n\n    Sponsors: GitHub, Ruby Central, thoughtbot.\n\n    https://rubydf.com/events/nona-edicao/\n  talks:\n    - title: \"CSS-Zero - Opinionated Frontend for your No-Build Application\"\n      raw_title: \"CSS-Zero - Frontend opinativo para seu aplicativo no-build\"\n      event_name: \"Ruby DF 9th Edition\"\n      date: \"2025-10-18\"\n      published_at: \"2025-10-20\"\n      video_provider: \"youtube\"\n      video_id: \"tun5XnQnSNE\"\n      id: \"lazaro-nixon-ruby-df-9-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Lázaro Nixon\"\n\n- id: \"ruby-df-10-edition\"\n  title: \"Ruby DF 10th Edition - Games with Ruby & Year-End Celebration\"\n  event_name: \"Ruby DF 10th Edition\"\n  date: \"2025-12-13\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-10-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's tenth edition: introduction to game development with Ruby, plus year-end celebration.\n\n    Sponsors: GitHub, Ruby Central, thoughtbot.\n\n    https://rubydf.com/events/decima-edicao/\n  talks:\n    - title: \"Introduction to Game Development with Ruby\"\n      raw_title: \"Introdução ao Desenvolvimento de Jogos com Ruby\"\n      event_name: \"Ruby DF 10th Edition\"\n      date: \"2025-12-13\"\n      published_at: \"2026-01-05\"\n      video_provider: \"youtube\"\n      video_id: \"rFahd2DzXxI\"\n      id: \"matheus-richard-ruby-df-10-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Matheus Richard\"\n\n- id: \"ruby-df-11-edition\"\n  title: \"Ruby DF 11th Edition - Hacking Kindles with Ruby\"\n  event_name: \"Ruby DF 11th Edition\"\n  date: \"2026-02-21\"\n  video_provider: \"children\"\n  video_id: \"ruby-df-11-edition\"\n  language: \"portuguese\"\n  description: |-\n    Ruby DF's eleventh edition: hacking Kindles with Ruby.\n\n    Sponsor: thoughtbot.\n\n    https://rubydf.com/events/decima-primeira-edicao/\n  talks:\n    - title: \"Hacking Kindles with Ruby\"\n      raw_title: \"Hackeando Kindles com Ruby\"\n      event_name: \"Ruby DF 11th Edition\"\n      date: \"2026-02-21\"\n      video_provider: \"not_recorded\"\n      video_id: \"joas-cabral-ruby-df-11-edition\"\n      id: \"joas-cabral-ruby-df-11-edition\"\n      language: \"portuguese\"\n      speakers:\n        - \"Joás Cabral\"\n"
  },
  {
    "path": "data/ruby-df/series.yml",
    "content": "---\nname: \"Ruby DF\"\nwebsite: \"https://rubydf.com\"\ngithub: \"https://github.com/Ruby-DF\"\nlinkedin: \"https://www.linkedin.com/company/103880803\"\nyoutube_channel_name: \"ruby-df\"\nkind: \"meetup\"\nfrequency: \"quarterly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"BR\"\nlanguage: \"portuguese\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-foo/ruby-foo-2009/event.yml",
    "content": "---\nid: \"ruby-foo-2009\"\ntitle: \"Ruby Foo 2009\"\ndescription: \"\"\nlocation: \"London, UK\"\nkind: \"conference\"\nstart_date: \"2009-10-02\"\nend_date: \"2009-10-03\"\noriginal_website: \"http://jaoo.dk/ruby-london-2009/\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/ruby-foo/ruby-foo-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/ruby-foo/series.yml",
    "content": "---\nname: \"Ruby Foo\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"GB\"\n"
  },
  {
    "path": "data/ruby-for-good/ruby-for-good-2016/event.yml",
    "content": "---\nid: \"ruby-for-good-2016\"\ntitle: \"Ruby for Good 2016\"\ndescription: \"\"\nlocation: \"Washington, DC\"\nkind: \"retreat\"\nstart_date: \"2016-06-16\"\nend_date: \"2016-06-19\"\nwebsite: \"http://www.rubyforgood.org/\"\ntwitter: \"rubyforgood\"\nbanner_background: \"#FFFFFF\"\nfeatured_color: \"#008080\"\nfeatured_background: \"#FFFFFF\"\ncoordinates:\n  latitude: 38.9071923\n  longitude: -77.0368707\n"
  },
  {
    "path": "data/ruby-for-good/ruby-for-good-2020/event.yml",
    "content": "---\nid: \"ruby-for-good-by-the-bay-2020\"\ntitle: \"Ruby for Good by the Bay 2020\"\ndescription: \"\"\nlocation: \"Sausalito, CA, United States\"\nkind: \"retreat\"\nstart_date: \"2020-04-03\"\nend_date: \"2020-04-05\"\nwebsite: \"https://rubybythebay.org/\"\ntwitter: \"rubyforgood\"\nbanner_background: \"#7BA1D3\"\nfeatured_color: \"#7FFF00\"\nfeatured_background: \"#7BA1D3\"\ncoordinates:\n  latitude: 37.8590937\n  longitude: -122.4852507\n"
  },
  {
    "path": "data/ruby-for-good/ruby-for-good-2023/event.yml",
    "content": "---\nid: \"ruby-for-good-2023\"\ntitle: \"Ruby for Good 2023\"\ndescription: \"\"\nlocation: \"Washington, DC\"\nkind: \"retreat\"\nstart_date: \"2023-07-27\"\nend_date: \"2023-07-30\"\nwebsite: \"https://rubyforgood.org/events\"\ntwitter: \"rubyforgood\"\nbanner_background: \"#FFFFFF\"\nfeatured_color: \"#008080\"\nfeatured_background: \"#FFFFFF\"\ncoordinates:\n  latitude: 38.9071923\n  longitude: -77.0368707\n"
  },
  {
    "path": "data/ruby-for-good/ruby-for-good-2024/event.yml",
    "content": "---\nid: \"ruby-for-good-2024\"\ntitle: \"Ruby for Good 2024\"\ndescription: \"\"\nlocation: \"Washington, DC\"\nkind: \"retreat\"\nstart_date: \"2024-05-30\"\nend_date: \"2024-06-02\"\nwebsite: \"https://rubyforgood.org/events\"\ntwitter: \"rubyforgood\"\nbanner_background: \"#FFFFFF\"\nfeatured_color: \"#008080\"\nfeatured_background: \"#FFFFFF\"\ncoordinates:\n  latitude: 39.5075257\n  longitude: -77.7904127\n"
  },
  {
    "path": "data/ruby-for-good/ruby-for-good-2024/venue.yml",
    "content": "# docs/ADDING_VENUES.md\n# Delete unnecessary keys\n---\nname: \"Shepherd's Spring Camp & Retreat Center\"\nurl: \"https://www.shepherdsspring.org/facilities\"\n\naddress:\n  street: \"16869 Taylors Landing Road\"\n  city: \"Woburn Estates\"\n  region: \"Maryland\"\n  postal_code: \"21782\"\n  country: \"United States\"\n  country_code: \"us\"\n  display: \"16869 Taylors Landing Road, Sharpsburg, MD 21782\"\n\ncoordinates:\n  latitude: 39.5075257\n  longitude: -77.7904127\n\nmaps:\n  google: \"https://maps.app.goo.gl/nwzNbZZgeVgo6Zww5\"\n"
  },
  {
    "path": "data/ruby-for-good/ruby-for-good-2025/event.yml",
    "content": "---\nid: \"ruby-for-good-2025\"\ntitle: \"Ruby for Good 2025\"\ndescription: \"\"\nlocation: \"Washington, DC\"\nkind: \"retreat\"\nstart_date: \"2025-09-11\"\nend_date: \"2025-09-14\"\nwebsite: \"https://rubyforgood.org/events\"\ntwitter: \"rubyforgood\"\nbanner_background: \"#FFFFFF\"\nfeatured_color: \"#008080\"\nfeatured_background: \"#FFFFFF\"\ncoordinates:\n  latitude: 38.9071923\n  longitude: -77.0368707\n"
  },
  {
    "path": "data/ruby-for-good/ruby-for-good-belgium-2025/event.yml",
    "content": "---\nid: \"ruby-for-good-belgium-2025\"\ntitle: \"Ruby for Good - Belgium 2025\"\ndescription: \"\"\nlocation: \"Ghent, Belgium\"\nkind: \"retreat\"\nstart_date: \"2025-02-03\"\nend_date: \"2025-02-05\"\nwebsite: \"https://RubyInGhent.org\"\ntwitter: \"rubyforgood\"\nbanner_background: \"#FFFFFF\"\nfeatured_color: \"#008080\"\nfeatured_background: \"#FFFFFF\"\ncoordinates:\n  latitude: 51.0499922\n  longitude: 3.7303853\naliases:\n  - Ruby for Good - Ghent 2025\n"
  },
  {
    "path": "data/ruby-for-good/ruby-for-good-belgium-2026/event.yml",
    "content": "---\nid: \"ruby-for-good-belgium-2026\"\ntitle: \"Ruby for Good - Belgium 2026\"\ndescription: |-\n  A code retreat where Ruby programmers (and others!) from all over the globe get together to build and contribute to projects that help our communities.\nlocation: \"Ghent, Belgium\"\naliases:\n  - Ruby in Ghent\nkind: \"retreat\"\nstart_date: \"2026-02-02\"\nend_date: \"2026-02-04\"\nwebsite: \"https://rubyinghent.org\"\ntickets_url: \"https://ti.to/codeforgood/rubyinghent\"\ntwitter: \"rubyforgood\"\nannounced_on: \"2025-10-01\"\nbanner_background: \"linear-gradient(135deg,teal 0%,#4ecdc4 100%)\"\nfeatured_color: \"#FFFFFF\"\nfeatured_background: \"#008080\"\ncoordinates:\n  latitude: 51.0418937834923\n  longitude: 3.722846025921733\n"
  },
  {
    "path": "data/ruby-for-good/ruby-for-good-belgium-2026/venue.yml",
    "content": "---\nname: \"Jam Ghent Hotel\"\naddress:\n  street: \"Gaspar de Craeyerstraat 2\"\n  city: \"Ghent\"\n  region: \"Flanders\"\n  postal_code: \"9000\"\n  country: \"Belgium\"\n  country_code: \"BE\"\n  display: \"Gaspar de Craeyerstraat 2, 9000 Gent, Belgium\"\ncoordinates:\n  latitude: 51.0418937834923\n  longitude: 3.722846025921733\nmaps:\n  google: \"https://maps.app.goo.gl/mD6wXQkyCZ88ejsg6\"\n"
  },
  {
    "path": "data/ruby-for-good/series.yml",
    "content": "---\nname: \"Ruby for Good\"\nwebsite: \"http://www.rubyforgood.org/\"\ntwitter: \"rubyforgood\"\nyoutube_channel_name: \"\"\nkind: \"retreat\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-frankfurt/ruby-frankfurt/event.yml",
    "content": "---\nid: \"ruby-frankfurt\"\ntitle: \"Ruby Frankfurt Meetup\"\nkind: \"meetup\"\nlocation: \"Frankfurt, Germany\"\ndescription: |-\n  Hier treffen sich alle Ruby und Ruby on Rails Entwickler und solche die es werden wollen. Ziel ist der Austausch zu aktuellen Themen in der Ruby-Welt. Du bist herzlich willkommen, ob Anfänger oder Profi.\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#C30D22\"\nwebsite: \"https://www.meetup.com/frankfurt-ruby-meetup\"\ncoordinates:\n  latitude: 50.1109221\n  longitude: 8.6821267\n"
  },
  {
    "path": "data/ruby-frankfurt/ruby-frankfurt/videos.yml",
    "content": "---\n- id: \"ruby-frankfurt-meetup-april-2024\"\n  title: \"Ruby Frankfurt Meetup - April 2024\"\n  raw_title: \"Ruby Frankfurt Meetup - April 2024\"\n  event_name: \"Ruby Frankfurt Meetup - April 2024\"\n  date: \"2024-04-16\"\n  thumbnail_xs: \"https://files.speakerdeck.com/presentations/acc18daa4a6f48f28c26e8b80ddc657e/preview_slide_0.jpg\"\n  thumbnail_sm: \"https://files.speakerdeck.com/presentations/acc18daa4a6f48f28c26e8b80ddc657e/slide_0.jpg\"\n  thumbnail_md: \"https://files.speakerdeck.com/presentations/acc18daa4a6f48f28c26e8b80ddc657e/slide_0.jpg\"\n  thumbnail_lg: \"https://files.speakerdeck.com/presentations/acc18daa4a6f48f28c26e8b80ddc657e/slide_0.jpg\"\n  thumbnail_xl: \"https://files.speakerdeck.com/presentations/acc18daa4a6f48f28c26e8b80ddc657e/slide_0.jpg\"\n  description: |-\n    Dear Frankfurt Rubyists,\n\n    let the spring feelings enlighten our Ruby feelings 🌸🌷🌼\n\n    We will be hosted by portagon again in their nice office:\n    https://www.openstreetmap.org/way/174789493\n\n    Nevertheless, there is a limit so please register your attendance here at meetup and unregister when you can't make it anymore.\n\n    The starting time from the last events worked well, so we hope to start gathering around 18:30 and start the talks around 19:00.\n\n    ***\n\n    ⭐️ Talks ⭐️\n\n    Going Native: We go step-by-step to turn our web-only Rails app native using Turbo Native & Strada\n    Pitfalls Working with URLs: You are manipulating URLs? You're probably doing it wrong. (more info)\n    If you have a quick one, there is always some space for lightning talks ⚡!\n\n    If you'd like to give a talk at the next meeting, head over to https://github.com/ruby-frankfurt/talks and look for requests or add your proposal. Or send us a message or an email. Or give the talk as a lightning talk!\n\n    ***\n\n    ✍💻 Connect on Slack ✍💻\n    We have a new Slack channel to connect in the time between meetups. The Rhein-Main Ruby! Just message one of the organizers of the meetup and we'll invite you.\n\n    https://www.meetup.com/frankfurt-ruby-meetup/events/299586276\n  video_provider: \"children\"\n  video_id: \"ruby-frankfurt-meetup-april-2024\"\n  talks:\n    - title: \"Turbo Native & Strada: Turning a Web-Only Rails App Native\"\n      date: \"2024-04-16\"\n      published_at: \"2024-04-22\"\n      id: \"kevin-liebholz-ruby-frankfurt-meetup-april-2024\"\n      video_id: \"BDBjgGSQA_4\"\n      video_provider: \"youtube\"\n      event_name: \"Ruby Frankfurt Meetup - April 2024\"\n      slides_url: \"https://speakerdeck.com/kevinliebholz/going-native-turning-a-web-only-rails-app-native\"\n      thumbnail_xs: \"https://files.speakerdeck.com/presentations/acc18daa4a6f48f28c26e8b80ddc657e/preview_slide_0.jpg\"\n      thumbnail_sm: \"https://files.speakerdeck.com/presentations/acc18daa4a6f48f28c26e8b80ddc657e/preview_slide_0.jpg\"\n      thumbnail_md: \"https://files.speakerdeck.com/presentations/acc18daa4a6f48f28c26e8b80ddc657e/slide_0.jpg\"\n      thumbnail_lg: \"https://files.speakerdeck.com/presentations/acc18daa4a6f48f28c26e8b80ddc657e/slide_0.jpg\"\n      thumbnail_xl: \"https://files.speakerdeck.com/presentations/acc18daa4a6f48f28c26e8b80ddc657e/slide_0.jpg\"\n      description: |-\n        Going Native: We go step-by-step to turn our web-only Rails app native using Turbo Native & Strada\n\n        As presented in the Ruby Meetup Frankfurt on April 16th, 2024.\n\n        Repo: https://github.com/kevkev300/personal_knowledge_base\n      speakers:\n        - Kevin Liebholz\n      additional_resources:\n        - name: \"kevkev300/personal_knowledge_base\"\n          type: \"repo\"\n          url: \"https://github.com/kevkev300/personal_knowledge_base\"\n\n# TODO: missing event: https://www.meetup.com/frankfurt-ruby-meetup/events/301216095\n# TODO: missing event: https://www.meetup.com/frankfurt-ruby-meetup/events/302960601\n\n- id: \"ruby-frankfurt-meetup-april-2025\"\n  title: \"Ruby Frankfurt Meetup - April 2025\"\n  raw_title: \"Ruby Frankfurt Meetup - April 2025 - Kamal 2\"\n  event_name: \"Ruby Frankfurt Meetup - April 2025\"\n  date: \"2025-04-23\"\n  description: |-\n    Dear Frankfurt Rubyists,\n\n    we're back for 2025!\n\n    After a longer break, we're back with one of our recurring speakers: Stefan Wienert, who will report from the trench lines of deployments with Kamal 2.\n\n    He worked with Kamal 2 on different apps with various scenarios. You can find his talk proposal here.\n\n    We will be hosted again by ioki in their nice office:\n\n    https://ioki.engineering/meetups\n    Google Maps\n    Apple Maps\n\n    The starting time from the last events worked well, so we hope to start gathering around 18:30 and start the talks around 19:00.\n\n    ***\n\n    ⭐️ Talks ⭐️\n\n    Kamal 2 - report from the trench lines\n    If you have a quick one, there is always some space for lightning talks ⚡!\n\n    If you'd like to give a talk at the next meeting, head over to https://github.com/ruby-frankfurt/talks and look for requests or add your proposal. Or send us a message or an email. Or give the talk as a lightning talk!\n\n    ***\n\n    ✍💻 Connect on Slack ✍💻\n    We have a new Slack channel to connect in the time between meetups. The Rhein-Main Ruby! Just message one of the organizers of the meetup and we'll invite you.\n\n    https://www.meetup.com/frankfurt-ruby-meetup/events/306805327\n  video_provider: \"children\"\n  video_id: \"ruby-frankfurt-meetup-april-2025\"\n  talks:\n    - title: \"Kamal 2 - report from the trench lines\"\n      date: \"2025-04-23\"\n      id: \"stefan-wienert-ruby-frankfurt-meetup-april-2025\"\n      video_id: \"stefan-wienert-ruby-frankfurt-meetup-april-2025\"\n      video_provider: \"not_recorded\"\n      event_name: \"Ruby Frankfurt Meetup - April 2025\"\n      slides_url: \"https://zealot128.github.io/presentations/kamal\"\n      description: |-\n        Writeup: https://www.stefanwienert.de/blog/2025/05/04/kamal-presentation-ruby-frankfurt\n      speakers:\n        - Stefan Wienert\n"
  },
  {
    "path": "data/ruby-frankfurt/series.yml",
    "content": "---\nname: \"Ruby Frankfurt\"\nwebsite: \"https://www.meetup.com/frankfurt-ruby-meetup\"\nmeetup: \"https://www.meetup.com/frankfurt-ruby-meetup\"\ngithub: \"https://github.com/ruby-frankfurt\"\ntwitter: \"ruby_frankfurt\"\nmastodon: \"https://ruby.social/@frankfurt\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"DE\"\nlanguage: \"english\"\n"
  },
  {
    "path": "data/ruby-fringe/futureruby-2009/event.yml",
    "content": "---\nid: \"futureruby-2009\"\ntitle: \"FutureRuby 2009\"\ndescription: |-\n  The successor to RubyFringe, FutureRuby continued the tradition of exploring forward-thinking topics in the Ruby community.\nlocation: \"Toronto, Canada\"\nkind: \"conference\"\nstart_date: \"2009-07-09\"\nend_date: \"2009-07-12\"\nwebsite: \"https://web.archive.org/web/20090802074642/http://futureruby.com/\"\noriginal_website: \"http://futureruby.com\"\ncoordinates:\n  latitude: 43.653226\n  longitude: -79.3831843\n"
  },
  {
    "path": "data/ruby-fringe/futureruby-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/ruby-fringe/rubyfringe-2008/event.yml",
    "content": "---\nid: \"rubyfringe-2008\"\ntitle: \"RubyFringe 2008\"\ndescription: |-\n  A unique Ruby conference emphasizing unconventional topics and community engagement, organized by Unspace.\nlocation: \"Toronto, Canada\"\nkind: \"conference\"\nstart_date: \"2008-07-18\"\nend_date: \"2008-07-20\"\nwebsite: \"https://web.archive.org/web/20080614170736/http://rubyfringe.com/\"\noriginal_website: \"http://rubyfringe.com/\"\ncoordinates:\n  latitude: 43.653226\n  longitude: -79.3831843\n"
  },
  {
    "path": "data/ruby-fringe/rubyfringe-2008/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/ruby-fringe/series.yml",
    "content": "---\nname: \"Ruby Fringe\"\nwebsite: \"https://rubyfringe.com\"\ntwitter: \"\"\nmastodon: \"\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v01/event.yml",
    "content": "---\nid: \"PLiTLfUaZn5sza7_soPUJuvQkHLTj1gJBf\"\ntitle: \"Ruby Galaxy v0.1\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  Launched on Jan 28th, 2021 - The first Ruby Galaxy\npublished_at: \"2021-02-01\"\nstart_date: \"2021-01-28\"\nend_date: \"2021-01-28\"\nchannel_id: \"UCLa57lJ1HFAKAkjxOjKEZSQ\"\nyear: 2021\nbanner_background: \"#0A101D\"\nfeatured_background: \"#0A101D\"\nfeatured_color: \"#FFFFFF\"\ncoordinates: false\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v01/videos.yml",
    "content": "---\n- id: \"casey-watts-ruby-galaxy-v01\"\n  title: \"Debugging Your Brain\"\n  raw_title: \"Ruby Galaxy v0.1 Casey Watts - Debugging Your Brain\"\n  speakers:\n    - Casey Watts\n  event_name: \"Ruby Galaxy v0.1\"\n  date: \"2021-02-02\"\n  published_at: \"2021-02-02\"\n  description: |-\n    Video synopsis:\n    The human brain is buggy. Sometimes your mind distorts reality, gets frustrated with shortcomings, and spirals out of control. With practice, you can debug your brain. Catch those distortions of reality, transform those frustrations into insight, and short-circuit those downward spirals.\n\n    In this workshop you will get a chance to practice each core idea from Casey’s book [Debugging Your Brain](https://www.debuggingyourbrain.com): Modeling The Brain, Cognitive Behavioral Therapy, Introspection, Identifying Inputs, Experience Processing, Experience Validation, and Cognitive Restructuring.\n\n    Debugging Your Brain is a clear applied psychology book and a concise self-help book, available in all three formats: printed book, eBook and audiobook: [debuggingyourbrain.com](https://www.debuggingyourbrain.com)\n  video_provider: \"youtube\"\n  video_id: \"4OWxVtfM1U4\"\n\n- id: \"yukihiro-matz-matsumoto-ruby-galaxy-v01\"\n  title: \"Beyond Ruby 3.0\"\n  raw_title: 'Ruby Galaxy v0.1 Yukihiro \"Matz\" Matsumoto - Beyond Ruby3'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"Ruby Galaxy v0.1\"\n  date: \"2021-02-02\"\n  published_at: \"2021-02-10\"\n  description: |-\n    Beyond Ruby3 is presented by the creator of Ruby,  Yukihiro Matsumoto. This was the keynote presentation at the first version of Ruby Galaxy. This talk demonstrates how Ruby3 makes progress without breaking the past. In Matz's words, Beyond Ruby3 ultimately explains Ruby's whole purpose - \"to create a better world.\"\n  video_provider: \"youtube\"\n  video_id: \"buhig8jr-Mo\"\n\n- id: \"okura-masafumi-ruby-galaxy-v01\"\n  title: \"Kaigi on Rails\"\n  raw_title: \"Ruby Galaxy v0.1 Okura Masafumi  - Kaigi on Rails\"\n  speakers:\n    - OKURA Masafumi\n  event_name: \"Ruby Galaxy v0.1\"\n  date: \"2021-02-03\"\n  published_at: \"2021-02-10\"\n  description: |-\n    Talk Synopsis:\n    Okura Masafumi is the chief organizer of Kaigi on Rails (https://kaigionrails.org), a new tech conference from Japan.\n    It launched last year and started its history as an online conference, apart from its original idea.\n    Okura is planning to improve it to be a better online conference this year to empower more people, from newbies to experienced devs.\n    Kaigi on Rails is currently a domestic conference, but will hopefully be an international from next year. In this talk, Okura talks briefly about Kaigi on Rails and some ideas around it, and propose the audience to be part of it.\n  video_provider: \"youtube\"\n  video_id: \"QpuaX8N19no\"\n\n- id: \"brooke-kuhlmann-ruby-galaxy-v01\"\n  title: \"Git Rebase\"\n  raw_title: \"Ruby Galaxy v0.1 Brooke Kuhlmann - Git Rebase\"\n  speakers:\n    - Brooke Kuhlmann\n  event_name: \"Ruby Galaxy v0.1\"\n  date: \"2021-02-04\"\n  published_at: \"2021-02-10\"\n  description: |-\n    Talk Synopsis:\n    Git is the dominant tool for version management. Misunderstanding and misusing Git can cost development teams time, energy, and money. Few better examples exist than Git's default merge workflow which creates repositories that are hard to read, debug, and maintain. In this talk, I'll\n    show how to use the Rebase Workflow instead, which puts Git to work for you to produce quality code that's easy to handle and kicks your team into high gear. We'll also get a chance to look at Git\n    Lint (https://www.alchemists.io/projects/git-lint) which is a linter for your Git commits written in Ruby!\n  video_provider: \"youtube\"\n  video_id: \"6NbtaML8GAg\"\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v02/event.yml",
    "content": "---\nid: \"PLiTLfUaZn5sy95eGhlL6IvOzo80pyfmkd\"\ntitle: \"Ruby Galaxy v0.2\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  Launched on Feb 25th, 2021 - Interviews with OSS Maintainers\npublished_at: \"2021-04-08\"\nstart_date: \"2021-02-25\"\nend_date: \"2021-02-25\"\nchannel_id: \"UCLa57lJ1HFAKAkjxOjKEZSQ\"\nyear: 2021\nbanner_background: \"#0A101D\"\nfeatured_background: \"#0A101D\"\nfeatured_color: \"#FFFFFF\"\ncoordinates: false\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v02/videos.yml",
    "content": "---\n- id: \"aaron-patterson-ruby-galaxy-v02\"\n  title: \"Open Source Maintainer Interviews: Open Source Contributing (Part 1)\"\n  raw_title: \"Ruby Galaxy v0.2 - Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n    - Jonan Scheffler\n    - Rachael Wright-Munn\n  event_name: \"Ruby Galaxy v0.2\"\n  date: \"2021-02-25\"\n  published_at: \"2021-04-08\"\n  description: |-\n    For version 0.2 of Ruby Galaxy, we interviewed Open Source Maintainers ✨  \n\n    Aaron Patterson (@tenderlove) is on the Ruby and Rails core team. He is currently working over at Shopify. He also makes a lot of cheese.\n\n    Hosted by Jonan Scheffler (@thejonanshow) and Rachael Wright-Munn(@ChaelCodes) 🛸\n\n    This was originally streamed on our Twitch channel where you can find our releases every last Thursday of the month (https://www.twitch.tv/therubygalaxy). \n\n    Interested in talking? Take a look at our CFP at rubygalaxy.io 🚀\n    We are always interested in talks of all sorts, whether you are an experienced presenter, or are looking for a great place to give your first talk ever.\n\n    Follow us on Twitter @therubygalaxy and visit our website at https://rubygalaxy.io/  👽\n\n    Soundtrack for the game DojoKratos done with Game Boy. Available as CC-BY. Found on the Free Music Archive under Boss Splash by sawsquarenoise.\n\n    Background Space Video by Space Space from Pexels\n  video_provider: \"youtube\"\n  video_id: \"58N38JgpivQ\"\n\n- id: \"aaron-patterson-ruby-galaxy-v02-open-source-maintainer-intervi\"\n  title: \"Open Source Maintainer Interviews: Sidekiq and Faktory (Part 2)\"\n  raw_title: \"Ruby Galaxy v0.2 Aaron Patterson and Mike Perham (Part 2 of 3)\"\n  speakers:\n    - Aaron Patterson\n    - Mike Perham\n    - Jonan Scheffler\n    - Rachael Wright-Munn\n  event_name: \"Ruby Galaxy v0.2\"\n  date: \"2021-02-25\"\n  published_at: \"2021-04-12\"\n  description: |-\n    For version 0.2 of Ruby Galaxy, we interviewed Open Source Maintainers ✨  \n\n    Aaron Patterson (@tenderlove) is on the Ruby and Rails core team. He is currently working over at Shopify. He also makes a lot of cheese.\n\n    Mike Perham (@getajobmike) is the author of Sidkiq and Faktory. He is also the founder of Contributed Systems and he is definitely not a cat.\n\n    Hosted by Jonan Scheffler (@thejonanshow) and Rachael Wright-Munn(@ChaelCodes) 🛸\n\n    This is part 2 of a 3 part video series that was originally streamed on our Twitch channel. You can find our releases every last Thursday of the month (https://www.twitch.tv/therubygalaxy). \n\n    Interested in talking? Take a look at our CFP at rubygalaxy.io 🚀\n    We are always interested in talks of all sorts, whether you are an experienced presenter, or are looking for a great place to give your first talk ever.\n\n    Follow us on Twitter @therubygalaxy and visit our website at https://rubygalaxy.io/  👽\n\n    Soundtrack for the game DojoKratos done with Game Boy. Available as CC-BY. Found on the Free Music Archive under Boss Splash by sawsquarenoise.\n\n    Background Space Video by Space Space from Pexels\n  video_provider: \"youtube\"\n  video_id: \"N5isXYght4Q\"\n\n- id: \"mike-perham-ruby-galaxy-v02\"\n  title: \"Open Source Maintainer Interviews: Being an Open Source Community Manager (Part 3)\"\n  raw_title: \"Ruby Galaxy v0.2 Mike Perham and Christina Gorton (Part 3 of 3)\"\n  speakers:\n    - Mike Perham\n    - Christina Gorton\n    - Jonan Scheffler\n    - Rachael Wright-Munn\n  event_name: \"Ruby Galaxy v0.2\"\n  date: \"2021-02-25\"\n  published_at: \"2021-04-12\"\n  description: |-\n    For version 0.2 of Ruby Galaxy, we interviewed Open Source Maintainers ✨  \n\n    Mike Perham (@getajobmike) is the author of Sidkiq and Faktory. He is also the founder of Contributed Systems and he is definitely not a cat.\n\n    Christina Gorton (@coffeecraftcode) is an open source community manager, instructor, technical writer and developer. At Forem she helps create an online space in which community members can learn, engage, and contribute. \n\n    Hosted by Jonan Scheffler (@thejonanshow) and Rachael Wright-Munn(@ChaelCodes) 🛸\n\n    This was originally streamed on our Twitch channel where you can find our releases every last Thursday of the month (https://www.twitch.tv/therubygalaxy). \n\n    Interested in talking? Take a look at our CFP at rubygalaxy.io 🚀\n    We are always interested in talks of all sorts, whether you are an experienced presenter, or are looking for a great place to give your first talk ever.\n\n    Follow us on Twitter @therubygalaxy and visit our website at https://rubygalaxy.io/  👽\n\n    Soundtrack for the game DojoKratos done with Game Boy. Available as CC-BY. Found on the Free Music Archive under Boss Splash by sawsquarenoise.\n\n    Background Space Video by Space Space from Pexels\n  video_provider: \"youtube\"\n  video_id: \"xtJsvR_Lk98\"\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v03/event.yml",
    "content": "---\nid: \"ruby-galaxy-v03\"\ntitle: \"Ruby Galaxy v0.3\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  Launched on March 25th, 2021 - Ruby off the Rails\npublished_at: \"2021-04-15\"\nstart_date: \"2021-03-25\"\nend_date: \"2021-03-25\"\nchannel_id: \"UCLa57lJ1HFAKAkjxOjKEZSQ\"\nyear: 2021\nbanner_background: \"#0A101D\"\nfeatured_background: \"#0A101D\"\nfeatured_color: \"#FFFFFF\"\ncoordinates: false\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v03/videos.yml",
    "content": "---\n- id: \"amir-rajan-ruby-galaxy-v03\"\n  title: \"DragonRuby Game Engine\"\n  raw_title: \"Ruby Galaxy v0.3 Amir Rajan\"\n  speakers:\n    - Amir Rajan\n    - Rachael Wright-Munn\n    - Danny Ramos\n  event_name: \"Ruby Galaxy v0.3\"\n  date: \"2021-03-25\"\n  published_at: \"2021-04-15\"\n  description: |-\n    For version 0.3 of Ruby Galaxy, it was all about Ruby off the Rails. We focused on all things Ruby that don't involve Rails 🛰  \n\n    Amir Rajan (@amirrajan) is an indie game developer. He created the #1 iOS game: A Dark Room and is CEO of DragonRuby.\n\n    Hosted by Rachael Wright-Munn(@ChaelCodes) and Danny Ramos (@muydanny) 🛸\n\n    This was originally streamed on our Twitch channel where you can find our releases every last Thursday of the month (https://www.twitch.tv/therubygalaxy​​). \n\n    Interested in talking? Take a look at our CFP at rubygalaxy.io 🚀\n    We are always interested in talks of all sorts, whether you are an experienced presenter, or are looking for a great place to give your first talk ever.\n\n    Follow us on Twitter @therubygalaxy and visit our website at https://rubygalaxy.io/​​  👽\n\n    Soundtrack for the game DojoKratos done with Game Boy. Available as CC-BY. Found on the Free Music Archive under Boss Splash by sawsquarenoise.\n\n    Background Space Video by Space Space from Pexels\n  video_provider: \"youtube\"\n  video_id: \"4_dqKoRUtDw\"\n\n- id: \"corey-haines-ruby-galaxy-v03\"\n  title: \"Automate with Ruby\"\n  raw_title: \"Ruby Galaxy V0.3 Corey Haines\"\n  speakers:\n    - Corey Haines\n    - Rachael Wright-Munn\n    - Danny Ramos\n  event_name: \"Ruby Galaxy v0.3\"\n  date: \"2021-03-25\"\n  published_at: \"2021-04-14\"\n  description: |-\n    For version 0.3 of Ruby Galaxy, it was all about Ruby off the Rails. We focused on all things Ruby that didn't involve Rails 🛰\n\n    Corey Haines (@coreyhaines) is the author of Understanding the 4 Rules of Simple Design bit.ly/4rulesbook. We talk about how Ruby can help automate your life.\n\n    Hosted by Rachael Wright-Munn(@ChaelCodes) and Danny Ramos (@muydanny) 🛸\n\n    This was originally streamed on our Twitch channel where you can find our releases every last Thursday of the month (https://www.twitch.tv/therubygalaxy​​). \n\n    Interested in talking? Take a look at our CFP at rubygalaxy.io 🚀\n    We are always interested in talks of all sorts, whether you are an experienced presenter, or are looking for a great place to give your first talk ever.\n\n    Follow us on Twitter @therubygalaxy and visit our website at https://rubygalaxy.io/​​  👽\n\n    Soundtrack for the game DojoKratos done with Game Boy. Available as CC-BY. Found on the Free Music Archive under Boss Splash by sawsquarenoise.\n\n    Background Space Video by Space Space from Pexels\n  video_provider: \"youtube\"\n  video_id: \"bj-Wtk40gE8\"\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v04/event.yml",
    "content": "---\nid: \"ruby-galaxy-v04\"\ntitle: \"Ruby Galaxy v0.4\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  Launched on April 29th, 2021 19:00 UTC - Ruby Galaxy April 🌌\nwebsite: \"https://x.com/therubygalaxy/status/1385645342046048257\"\npublished_at: \"2021-04-29\"\nstart_date: \"2021-04-29\"\nend_date: \"2021-04-29\"\nchannel_id: \"UCLa57lJ1HFAKAkjxOjKEZSQ\"\nyear: 2021\nbanner_background: \"#0A101D\"\ncoordinates: false\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v04/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n# TODO: missing talks: Joel Hawksley - ViewComponents in the Real World\n# TODO: missing talks: Brian Douglas - Setup Ruby for GitHub Actions and MySpace\n# TODO: missing talks: Dan Moore - JSON Web Tokens and Decentralized Identity - What Ruby Developers Need To Know\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v05/event.yml",
    "content": "---\nid: \"ruby-galaxy-v05\"\ntitle: \"Ruby Galaxy v0.5\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: \"\"\nwebsite: \"https://x.com/ChaelCodes/status/1393294356577140742\"\npublished_at: \"2021-05-27\"\nstart_date: \"2021-05-27\"\nend_date: \"2021-05-27\"\nchannel_id: \"UCLa57lJ1HFAKAkjxOjKEZSQ\"\nyear: 2021\nbanner_background: \"#0A101D\"\ncoordinates: false\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v05/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n# TODO: missing talks\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v06/event.yml",
    "content": "---\nid: \"ruby-galaxy-v06\"\ntitle: \"Ruby Galaxy v0.6\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: \"\"\nwebsite: \"https://x.com/therubygalaxy/status/1407357722958434314\"\npublished_at: \"2021-06-24\"\nstart_date: \"2021-06-24\"\nend_date: \"2021-06-24\"\nchannel_id: \"UCLa57lJ1HFAKAkjxOjKEZSQ\"\nyear: 2021\nbanner_background: \"#0A101D\"\ncoordinates: false\n"
  },
  {
    "path": "data/ruby-galaxy/ruby-galaxy-v06/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n# TODO: missing talks: Conversation between 2 RailsGirls Organizers - https://www.twitch.tv/videos/1066488918\n# TODO: missing talks: Interview with Max Tiu - https://www.twitch.tv/videos/1066488919\n# TODO: missing talks: Ramón Huidobro - New dev, old codebase: A series of mentorship stories - https://www.twitch.tv/videos/1066488920\n"
  },
  {
    "path": "data/ruby-galaxy/series.yml",
    "content": "---\nname: \"Ruby Galaxy\"\nwebsite: \"https://www.twitch.tv/therubygalaxy\"\ntwitter: \"therubygalaxy\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"Ruby Galaxy\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"therubygalaxy9941\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCLa57lJ1HFAKAkjxOjKEZSQ\"\n"
  },
  {
    "path": "data/ruby-hoedown/nuby-hoedown-2010/event.yml",
    "content": "---\nid: \"nuby-hoedown-2010\"\ntitle: \"Nuby Hoedown 2010\"\ndescription: |-\n  A beginner-focused Ruby workshop\nlocation: \"Nashville, TN, United States\"\nvenue: \"Downtown Hilton\"\nkind: \"workshop\"\nstart_date: \"2010-09-02\"\nend_date: \"2010-09-02\"\nwebsite: \"https://web.archive.org/web/20100826010429/http://rubyhoedown.com/nuby/\"\ncoordinates:\n  latitude: 36.1600155\n  longitude: -86.7772394\n"
  },
  {
    "path": "data/ruby-hoedown/nuby-hoedown-2010/venue.yml",
    "content": "---\nname: \"Downtown Hilton\"\naddress:\n  street: \"121 4th Ave S\"\n  city: \"Nashville\"\n  region: \"TN\"\n  postal_code: \"37201\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"121 4th Ave S, Nashville, TN 37201\"\ncoordinates:\n  latitude: 36.1600155\n  longitude: -86.7772394\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=36.1600155,-86.7772394\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=36.1600155&mlon=-86.7772394&zoom=17\"\n"
  },
  {
    "path": "data/ruby-hoedown/nuby-hoedown-2010/videos.yml",
    "content": "---\n- id: \"david-a-black-nuby-hoedown-2010\"\n  title: \"The Well-Grounded Nuby\"\n  speakers:\n    - David A. Black\n  event_name: \"Nuby Hoedown 2010\"\n  date: \"2010-09-02\"\n  description: |-\n    A tour of Ruby now and then\n  video_provider: \"not_recorded\"\n  video_id: \"david-a-black-nuby-hoedown-2010\"\n\n- id: \"kevin-gisi-nuby-hoedown-2010\"\n  title: \"Dynamic Ruby for Nubies\"\n  speakers:\n    - Kevin Gisi\n  event_name: \"Nuby Hoedown 2010\"\n  date: \"2010-09-02\"\n  description: |-\n    A discussion of metaprogramming\n  video_provider: \"not_recorded\"\n  video_id: \"kevin-gisi-nuby-hoedown-2010\"\n\n- id: \"scott-chacon-nuby-hoedown-2010\"\n  title: \"Improving Your Git Chops\"\n  speakers:\n    - Scott Chacon\n  event_name: \"Nuby Hoedown 2010\"\n  date: \"2010-09-02\"\n  description: |-\n    Getting git. Get it?\n  video_provider: \"not_recorded\"\n  video_id: \"scott-chacon-nuby-hoedown-2010\"\n\n- id: \"nick-gauthier-nuby-hoedown-2010\"\n  title: \"The How and Why of Testing\"\n  speakers:\n    - Nick Gauthier\n  event_name: \"Nuby Hoedown 2010\"\n  date: \"2010-09-02\"\n  description: |-\n    Learn testing from the ground up\n  video_provider: \"not_recorded\"\n  video_id: \"nick-gauthier-nuby-hoedown-2010\"\n\n- id: \"matt-yoho-nuby-hoedown-2010\"\n  title: \"Gem Authoring and Deployment\"\n  speakers:\n    - Matt Yoho\n  event_name: \"Nuby Hoedown 2010\"\n  date: \"2010-09-02\"\n  description: |-\n    A portrait of the young gem author\n  video_provider: \"not_recorded\"\n  video_id: \"matt-yoho-nuby-hoedown-2010\"\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2007/event.yml",
    "content": "---\nid: \"ruby-hoedown-2007\"\ntitle: \"Ruby Hoedown 2007\"\ndescription: \"\"\nlocation: \"Raleigh, NC, United States\"\nvenue: \"Red Hat Headquarters\"\nkind: \"conference\"\nstart_date: \"2007-08-10\"\nend_date: \"2007-08-11\"\nwebsite: \"https://web.archive.org/web/20070926044553/http://www.rubyhoedown.com/\"\ncoordinates:\n  latitude: 35.7736116\n  longitude: -78.6760637\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2007/schedule.yml",
    "content": "# Schedule from rubyhoedown.com\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2007-08-10\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Charity Workshop\n\n      - start_time: \"13:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Welcome\n\n      - start_time: \"13:30\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"16:15\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"19:00\"\n        end_time: \"20:30\"\n        slots: 1\n        items:\n          - Off-site social event (Dinner)\n\n  - name: \"Day 2\"\n    date: \"2007-08-11\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"08:30\"\n        slots: 1\n        items:\n          - Breakfast (provided by Microsoft)\n\n      - start_time: \"08:30\"\n        end_time: \"09:45\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"11:15\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch with short, self-organizing talks\n\n      - start_time: \"13:00\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"17:30\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - Wrap-up\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2007/venue.yml",
    "content": "---\nname: \"Red Hat Headquarters\"\naddress:\n  street: \"1801 Varsity Dr\"\n  city: \"Raleigh\"\n  region: \"NC\"\n  postal_code: \"27606\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"1801 Varsity Dr, Raleigh, NC 27606\"\ncoordinates:\n  latitude: 35.7736116\n  longitude: -78.6760637\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=35.7736116,-78.6760637\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=35.7736116&mlon=-78.6760637&zoom=17\"\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2007/videos.yml",
    "content": "# Friday, August 10, 2007\n---\n- id: \"chad-fowler-marcel-molina-ruby-hoedown-2007\"\n  title: \"Charity Workshop: Ruby and Rails Testing Techniques\"\n  raw_title: \"Ruby Hoedown 2007 - Charity Workshop: Ruby and Rails Testing Techniques\"\n  speakers:\n    - Chad Fowler\n    - Marcel Molina\n  event_name: \"Ruby Hoedown 2007\"\n  date: \"2007-08-10\"\n  published_at: \"2012-11-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3nH0y-yQcyA\"\n\n- id: \"ezra-zygmuntowicz-ruby-hoedown-2007\"\n  title: \"Exploring Merb\"\n  raw_title: \"Ruby Hoedown 2007 - Exploring Merb by Ezra Zygmuntowicz\"\n  speakers:\n    - Ezra Zygmuntowicz\n  event_name: \"Ruby Hoedown 2007\"\n  date: \"2007-08-10\"\n  published_at: \"2012-11-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"hnTJSBDles8\"\n\n- id: \"jay-phillips-ruby-hoedown-2007\"\n  title: \"Next-Gen VoIP Development with Ruby and Adhearsion\"\n  raw_title: \"Ruby Hoedown 2007 - Next-Gen VoIP Development with Ruby and Adhearsion by Jay Phillips\"\n  speakers:\n    - Jay Phillips\n  event_name: \"Ruby Hoedown 2007\"\n  date: \"2007-08-10\"\n  published_at: \"2012-11-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FV0oFm6BWxo\"\n\n- id: \"bruce-tate-ruby-hoedown-2007\"\n  title: \"Keynote: The Journey\"\n  raw_title: \"Ruby Hoedown 2007 - Keynote: The Journey by Bruce Tate\"\n  speakers:\n    - Bruce Tate\n  event_name: \"Ruby Hoedown 2007\"\n  date: \"2007-08-10\"\n  published_at: \"2012-11-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"pgLlM9cMpbQ\"\n\n# Saturday, August 11, 2007\n\n- id: \"andrea-ok-wright-ruby-hoedown-2007\"\n  title: \"Building Games with Ruby\"\n  raw_title: \"Ruby Hoedown 2007 - Building Games with Ruby by Andrea O.K. Wright\"\n  speakers:\n    - Andrea O. K. Wright\n  event_name: \"Ruby Hoedown 2007\"\n  date: \"2007-08-11\"\n  published_at: \"2012-11-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"1IZMRrEhf_c\"\n\n- id: \"lightning-talks-ruby-hoedown-2007\"\n  title: \"Lightning Talks\"\n  raw_title: \"Ruby Hoedown 2007 - Lightning Talks - Various Presenters\"\n  speakers:\n    - TODO\n  event_name: \"Ruby Hoedown 2007\"\n  date: \"2007-08-11\"\n  published_at: \"2012-11-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Mp_Y0qcw7l4\"\n\n- id: \"ken-auer-ruby-hoedown-2007\"\n  title: \"Does Ruby Have a Chasm to Cross?\"\n  raw_title: \"Ruby Hoedown 2007 - Does Ruby Have a Chasm to Cross? by Ken Auer\"\n  speakers:\n    - Ken Auer\n  event_name: \"Ruby Hoedown 2007\"\n  date: \"2007-08-11\"\n  published_at: \"2012-11-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jKJBosrpdXg\"\n\n- id: \"jared-richardson-ruby-hoedown-2007\"\n  title: \"Using C to Tune Your Ruby (or Rails) Application\"\n  raw_title: \"Ruby Hoedown 2007 - Using C to Tune Your Ruby (or Rails) Application by Jared Richardson\"\n  speakers:\n    - Jared Richardson\n  event_name: \"Ruby Hoedown 2007\"\n  date: \"2007-08-11\"\n  published_at: \"2012-11-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"16LNG6FYJmQ\"\n\n- id: \"marcel-molina-ruby-hoedown-2007\"\n  title: \"Keynote: What makes code beautiful?\"\n  raw_title: \"Ruby Hoedown 2007 - What makes code beautiful? by Marcel Molina\"\n  speakers:\n    - Marcel Molina\n  event_name: \"Ruby Hoedown 2007\"\n  date: \"2007-08-11\"\n  published_at: \"2012-11-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"uzONDRUKIMs\"\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2008/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"http://www.rubyhoedown.com/cfp.html\"\n  open_date: \"2008-05-06\"\n  close_date: \"2008-06-02\"\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2008/event.yml",
    "content": "# https://rubytalk.org/t/ruby-hoedown-2008-august-8-9-huntsville-al-keynotes-registration-and-cfp-open/46302\n---\nid: \"ruby-hoedown-2008\"\ntitle: \"Ruby Hoedown 2008\"\ndescription: \"\"\nlocation: \"Huntsville, AL, United States\"\nkind: \"conference\"\nstart_date: \"2008-08-08\"\nend_date: \"2008-08-09\"\nwebsite: \"https://web.archive.org/web/20080731234147/http://www.rubyhoedown.com/\"\noriginal_website: \"http://rubyhoedown.com\"\ncoordinates:\n  latitude: 34.7251606\n  longitude: -86.6404712\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2008/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jeremy McAnally\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2008/schedule.yml",
    "content": "# Schedule from rubyhoedown.com\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2008-08-08\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n\n      - start_time: \"14:15\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"15:35\"\n        slots: 1\n\n      - start_time: \"15:35\"\n        end_time: \"15:47\"\n        slots: 1\n\n      - start_time: \"15:47\"\n        end_time: \"15:53\"\n        slots: 1\n\n      - start_time: \"15:53\"\n        end_time: \"16:09\"\n        slots: 1\n\n      - start_time: \"16:09\"\n        end_time: \"16:14\"\n        slots: 1\n\n      - start_time: \"16:14\"\n        end_time: \"16:19\"\n        slots: 1\n\n      - start_time: \"16:19\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"19:30\"\n        end_time: \"20:30\"\n        slots: 1\n        items:\n          - Off-site Dinner Event\n\n  - name: \"Day 2\"\n    date: \"2008-08-09\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Breakfast and Lightning Talks\n\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:15\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:30\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - Wrap-up\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2008/venue.yml",
    "content": "---\nname: \"Shelby Center for Science and Technology, University of Alabama in Huntsville\"\naddress:\n  street: \"301 Sparkman Dr NW\"\n  city: \"Huntsville\"\n  region: \"AL\"\n  postal_code: \"35899\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"301 Sparkman Dr NW, Huntsville, AL 35899\"\ncoordinates:\n  latitude: 34.7251606\n  longitude: -86.6404712\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=34.7251606,-86.6404712\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=34.7251606&mlon=-86.6404712&zoom=17\"\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2008/videos.yml",
    "content": "---\n# Friday, August 8, 2008\n\n- id: \"joe-obrien-jim-weirich-ruby-hoedown-2008\"\n  title: \"Mock Dialogue\"\n  speakers:\n    - Joe O'Brien\n    - Jim Weirich\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"joe-obrien-jim-weirich-ruby-hoedown-2008\"\n\n- id: \"robert-dempsey-ruby-hoedown-2008\"\n  title: \"The Future is Now: Leveraging the Cloud with Ruby\"\n  raw_title: \"Ruby Hoedown 2008 - The Future is Now: Leveraging the Cloud with Ruby by: Robert Dempsey\"\n  speakers:\n    - Robert Dempsey\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"BPk15rfYRQI\"\n\n- id: \"jason-seifer-gregg-pollack-ruby-hoedown-2008\"\n  title: \"Ruby: A Year of Innovation\"\n  speakers:\n    - Jason Seifer\n    - Gregg Pollack\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"jason-seifer-gregg-pollack-ruby-hoedown-2008\"\n\n- id: \"rein-henrichs-ruby-hoedown-2008\"\n  title: \"Ruby Best Practice Patterns\"\n  raw_title: \"Ruby Hoedown 2008 - Ruby Best Practice Patterns by: Rein Henrichs\"\n  speakers:\n    - Rein Henrichs\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"a-KzxEVchlc\"\n\n- id: \"pj-davis-ruby-hoedown-2008\"\n  title: \"Lightning Talk: God Monitoring Tool\"\n  raw_title: \"Ruby Hoedown 2008 - Lightning Talk: God Monitoring Tool by: PJ Davis\"\n  speakers:\n    - PJ Davis\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"RhnnQmUncYE\"\n\n- id: \"bryan-liles-ruby-hoedown-2008\"\n  title: \"Lightning Talk: TATFT - Test All the F***in Time\"\n  raw_title: \"Ruby Hoedown 2008 - Lightning Talk: TATFT - Test All the F***in Time by: Bryan Liles\"\n  speakers:\n    - Bryan Liles\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"QMU6SjMZq1Q\"\n\n- id: \"yossef-mendelssohn-ruby-hoedown-2008\"\n  title: \"Lightning Talk: The Nature of Truth\"\n  raw_title: \"Ruby Hoedown 2008 - Lightning Talk: The Nature of Truth by: Yossef Mendelssohn\"\n  speakers:\n    - Yossef Mendelssohn\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"PDkrEoyva0E\"\n\n- id: \"obie-fernandez-ruby-hoedown-2008\"\n  title: \"Lightning Talk: Do the Hustle\"\n  raw_title: \"Ruby Hoedown 2008 - Do the Hustle by: Obie Fernandez\"\n  speakers:\n    - Obie Fernandez\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"fy5xKU7g-7c\"\n\n- id: \"coby-randquist-ruby-hoedown-2008\"\n  title: \"Lightning Talk: Kablame & YellowPages.com Overview\"\n  raw_title: \"Ruby Hoedown 2008 - Lightning Talk: Kablame & YellowPages.com Overview by: Coby Randquist\"\n  speakers:\n    - Coby Randquist\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ya8HwbgDP2U\"\n\n- id: \"shay-arnett-ruby-hoedown-2008\"\n  title: \"Lightning Talk: Archaeopteryx on the Cheap\"\n  raw_title: \"Ruby Hoedown 2008 - Lightning Talk: Archaeopteryx on the Cheap by: Shay Arnett\"\n  speakers:\n    - Shay Arnett\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"bLf5GlvbO-M\"\n\n- id: \"yehuda-katz-ruby-hoedown-2008\"\n  title: \"Lightning Talk: What Can We Learn from the Edge Projects?\"\n  raw_title: \"Ruby Hoedown 2008 - Lightning Talk: What Can We Learn from the Edge Projects? by: Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"b3xWshkBEX0\"\n\n- id: \"chris-wanstrath-ruby-hoedown-2008\"\n  title: \"Keynote\"\n  raw_title: \"Ruby Hoedown 2008 - Keynote by: Chris Wanstrath\"\n  speakers:\n    - Chris Wanstrath\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-08\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"e37ggWG_Cig\"\n\n# Saturday, August 9, 2008\n\n- id: \"troy-davis-ruby-hoedown-2008\"\n  title: \"Calling Your Code: Gluing Phone Calls to Ruby\"\n  raw_title: \"Ruby Hoedown 2008 - Calling Your Code Gluing Phone Calls to Ruby by: Troy Davis\"\n  speakers:\n    - Troy Davis\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-09\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"uFIT6I72KaM\"\n\n- id: \"joe-kutner-ruby-hoedown-2008\"\n  title: \"Ruleby: The Rules Engine for Ruby\"\n  raw_title: \"Ruby Hoedown 2008 - Ruleby: The Rules Engine for Ruby by: Joe Kutner\"\n  speakers:\n    - Joe Kutner\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-09\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"qMh2RDL6aBM\"\n\n- id: \"rick-bradley-ruby-hoedown-2008\"\n  title: \"flog << Test.new\"\n  raw_title: \"Ruby Hoedown 2008 - flog  Test.new by: Rick Bradley\"\n  speakers:\n    - Rick Bradley\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-09\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"i5CG-ncx2hM\"\n\n- id: \"giles-bowkett-ruby-hoedown-2008\"\n  title: \"Archaeopteryx: A Ruby MIDI Generator\"\n  raw_title: \"Ruby Hoedown 2008 - Archaeopteryx: A Ruby MIDI Generator by: Giles Bowkett\"\n  speakers:\n    - Giles Bowkett\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-09\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zr7rnf3EOz0\"\n\n- id: \"keynote-ghosts-of-ruby-ruby-hoedown-2008\"\n  title: \"Keynote: Ghosts of Ruby - A Neo-Dickensian Explication\"\n  raw_title: \"Ruby Hoedown 2008 - Keynote: Ghosts of Ruby - A Neo-Dickensian Explication\"\n  speakers:\n    - David A. Black\n  event_name: \"Ruby Hoedown 2008\"\n  date: \"2008-08-09\"\n  published_at: \"2015-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3UC3wXzrx2Y\"\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2009/event.yml",
    "content": "---\nid: \"ruby-hoedown-2009\"\ntitle: \"Ruby Hoedown 2009\"\ndescription: \"\"\nlocation: \"Nashville, TN, United States\"\nkind: \"conference\"\nstart_date: \"2009-08-28\"\nend_date: \"2009-08-29\"\noriginal_website: \"http://www.rubyhoedown.com/\"\ncoordinates:\n  latitude: 36.1626638\n  longitude: -86.7816016\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2010/event.yml",
    "content": "---\nid: \"ruby-hoedown-2010\"\ntitle: \"Ruby Hoedown 2010\"\naliases:\n  - Ruby Hoedown MMX\ndescription: \"\"\nlocation: \"Nashville, TN, United States\"\nkind: \"conference\"\nstart_date: \"2010-09-03\"\nend_date: \"2010-09-04\"\nwebsite: \"https://web.archive.org/web/20100908112142/http://rubyhoedown.com/\"\nfeatured_background: \"#BFA27B\"\nfeatured_color: \"#FFFFFF\"\nbanner_background: \"#BFA27B\"\ncoordinates:\n  latitude: 36.1600155\n  longitude: -86.7772394\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2010/venue.yml",
    "content": "---\nname: \"Hilton Downtown Nashville\"\naddress:\n  street: \"121 4th Ave S\"\n  city: \"Nashville\"\n  region: \"TN\"\n  postal_code: \"37201\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"121 4th Ave S, Nashville, TN 37201\"\ncoordinates:\n  latitude: 36.1600155\n  longitude: -86.7772394\nmaps:\n  google: \"https://www.google.com/maps/search/?api=1&query=36.1600155,-86.7772394\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=36.1600155&mlon=-86.7772394&zoom=17\"\n"
  },
  {
    "path": "data/ruby-hoedown/ruby-hoedown-2010/videos.yml",
    "content": "# https://web.archive.org/web/20100908112142/http://rubyhoedown.com/\n---\n- id: \"ben-scofield-ruby-hoedown-2010\"\n  title: \"Keynote\"\n  speakers:\n    - Ben Scofield\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-03\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"ben-scofield-ruby-hoedown-2010\"\n\n- id: \"brian-hogan-ruby-hoedown-2010\"\n  title: 'There''s A Wheel For That Already – Hidden \"gems\" in the Ruby Standard Library'\n  speakers:\n    - Brian Hogan\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-03\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"brian-hogan-ruby-hoedown-2010\"\n\n- id: \"justin-love-ruby-hoedown-2010\"\n  title: \"You already use Closure\"\n  speakers:\n    - Justin Love\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-03\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"justin-love-ruby-hoedown-2010\"\n\n- id: \"nick-gauthier-ruby-hoedown-2010\"\n  title: \"Grease Your Suite: Speeding up long running test suites\"\n  speakers:\n    - Nick Gauthier\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-03\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"nick-gauthier-ruby-hoedown-2010\"\n\n- id: \"yossef-mendelssohn-ruby-hoedown-2010\"\n  title: \"The Perpetual Novice\"\n  speakers:\n    - Yossef Mendelssohn\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-03\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"yossef-mendelssohn-ruby-hoedown-2010\"\n\n- id: \"john-m-willis-ruby-hoedown-2010\"\n  title: \"Configuration Management in the Cloud with Chef\"\n  speakers:\n    - John M. Willis\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-03\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"john-m-willis-ruby-hoedown-2010\"\n\n- id: \"matthew-bass-ruby-hoedown-2010\"\n  title: \"A/B Testing for Developers\"\n  speakers:\n    - Matthew Bass\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-04\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"matthew-bass-ruby-hoedown-2010\"\n\n- id: \"michael-jackson-ruby-hoedown-2010\"\n  title: \"Parsing Expressions in Ruby\"\n  speakers:\n    - Michael Jackson\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-04\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"michael-jackson-ruby-hoedown-2010\"\n\n- id: \"bryan-liles-ruby-hoedown-2010\"\n  title: \"Coding in anger, or is that desperation?\"\n  speakers:\n    - Bryan Liles\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-04\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"bryan-liles-ruby-hoedown-2010\"\n\n- id: \"alex-sharp-ruby-hoedown-2010\"\n  title: \"Refactoring in Practice\"\n  speakers:\n    - Alex Sharp\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-04\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"alex-sharp-ruby-hoedown-2010\"\n\n- id: \"glenn-vanderburg-ruby-hoedown-2010\"\n  title: \"Keynote\"\n  speakers:\n    - Glenn Vanderburg\n  event_name: \"Ruby Hoedown 2010\"\n  date: \"2010-09-04\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"glenn-vanderburg-ruby-hoedown-2010\"\n"
  },
  {
    "path": "data/ruby-hoedown/series.yml",
    "content": "---\nname: \"Ruby Hoedown\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"US\"\n"
  },
  {
    "path": "data/ruby-in-common/ruby-in-common-2024/event.yml",
    "content": "---\nid: \"ruby-in-common-2024\"\ntitle: \"Ruby in Common 2024\"\ndescription: \"\"\nlocation: \"Sydney, Australia\"\nkind: \"conference\"\nstart_date: \"2024-04-10\"\nend_date: \"2024-04-10\"\nwebsite: \"https://rubyincommon.org/\"\ncoordinates:\n  latitude: -33.8655116\n  longitude: 151.2053768\n"
  },
  {
    "path": "data/ruby-in-common/ruby-in-common-2024/venue.yml",
    "content": "---\nname: \"Microsoft Reactor Sydney\"\n\ndescription: |-\n  Level 10\n\naddress:\n  street: \"11 York Street\"\n  city: \"Sydney\"\n  region: \"New South Wales\"\n  postal_code: \"2000\"\n  country: \"Australia\"\n  country_code: \"AU\"\n  display: \"lvl 10/11 York St, Sydney NSW 2000, Australia\"\n\ncoordinates:\n  latitude: -33.8655116\n  longitude: 151.2053768\n\nmaps:\n  google: \"https://maps.google.com/?q=Microsoft+Reactor+Sydney,-33.8655116,151.2053768\"\n  apple: \"https://maps.apple.com/?q=Microsoft+Reactor+Sydney&ll=-33.8655116,151.2053768\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=-33.8655116&mlon=151.2053768\"\n"
  },
  {
    "path": "data/ruby-in-common/ruby-in-common-2024/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyincommon.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-in-common/series.yml",
    "content": "---\nname: \"Ruby in Common\"\nwebsite: \"https://rubyincommon.org/\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-in-london/ruby-in-london-meetup/event.yml",
    "content": "---\nid: \"ruby-in-london-meetup\"\ntitle: \"Ruby in London Meetup\"\nlocation: \"London, UK\"\ndescription: \"\"\nkind: \"meetup\"\npublished_at: \"2025-02-04\"\nchannel_id: \"1\"\nyear: 2025\nbanner_background: \"#2F3039\"\nfeatured_background: \"#2F3039\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://www.meetup.com/ruby-in-london\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/ruby-in-london/ruby-in-london-meetup/videos.yml",
    "content": "# https://www.meetup.com/ruby-in-london\n---\n- id: \"ruby-in-london-november-2023\"\n  title: \"Ruby in London November 2023\"\n  raw_title: \"Ruby in London with Currencycloud\"\n  event_name: \"Ruby in London November 2023\"\n  date: \"2023-11-08\"\n  video_id: \"ruby-in-london-november-2023\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/1/4/9/600_515009001.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/1/4/9/600_515009001.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/1/4/9/600_515009001.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/1/4/9/600_515009001.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/1/4/9/600_515009001.webp?w=750\"\n  description: |-\n    Hi All,\n\n    I hope you are well.\n\n    Our first in person event will be taking place at Currencycloud on the 8th of November starting at 5:30pm (pizzas and refreshments will be provided).\n\n    6:10pm Start: Introduction from Currencycloud\n\n    6:15pm Talk 1 - Francesco Papini will be giving the talk - 'Ruby-Java interoperability with Kafka using protobuf' - How to produce and consume Kafka messages between Ruby and Java microservices using protobuf encoding.\n\n    6:45pm Break\n\n    7:00 pm Talk 2 - David Somers will be giving the talk 'How to handle conversations about dependency technical debt with Libyear'\n\n    Get signed up early as spaces are limited and places will go!\n\n    Hope to see you there!\n\n    Liam\n\n    https://www.meetup.com/ruby-in-london/events/295338466\n\n  talks:\n    - title: \"Ruby-Java interoperability with Kafka using protobuf\"\n      date: \"2023-11-08\"\n      event_name: \"Ruby in London November 2023\"\n      description: |-\n        How to produce and consume Kafka messages between Ruby and Java microservices using protobuf encoding.\n      id: \"francesco-papini-ruby-in-london–november-2023\"\n      video_id: \"francesco-papini-ruby-in-london–november-2023\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Francesco Papini\n\n    - title: \"How to handle conversations about dependency technical debt with Libyear\"\n      date: \"2023-11-08\"\n      event_name: \"Ruby in London November 2023\"\n      description: \"\"\n      id: \"david-somers-ruby-in-london–november-2023\"\n      video_id: \"david-somers-ruby-in-london–november-2023\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - David Somers\n\n- id: \"ruby-in-london-february-2024\"\n  title: \"Ruby in London February 2024\"\n  raw_title: \"Ruby in London with Builder.ai\"\n  event_name: \"Ruby in London February 2024\"\n  date: \"2024-02-07\"\n  video_id: \"ruby-in-london-february-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/2/8/c/7/600_517570439.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/2/8/c/7/600_517570439.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/2/8/c/7/600_517570439.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/2/8/c/7/600_517570439.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/2/8/c/7/600_517570439.webp?w=750\"\n  description: |-\n    Hi All,\n\n    I hope you are well.\n\n    Our next event has been confirmed for the 7th of February with Builder.ai starting at 5:30pm, with food and drinks provided.\n\n    6:15 <> Talk 1 - Vikas Verma with \"Advanced Database Programming in Rails\"\n\n    7:00pm <> Talk 2 - Daniel Vartanov with \"Concurrency in Ruby and how it changed in 3.x\"\n\n    Look forward to seeing you all there!\n\n    Thanks,\n    Liam\n\n    https://www.meetup.com/ruby-in-london/events/297633001\n\n  talks:\n    - title: \"Advanced Database Programming in Rails\"\n      date: \"2024-02-07\"\n      event_name: \"Ruby in London February 2024\"\n      description: \"\"\n      id: \"vikas-verma-ruby-in-london–february-2024\"\n      video_id: \"vikas-verma-ruby-in-london–february-2024\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Vikas Verma\n\n    - title: \"Concurrency in Ruby and how it changed in 3.x\"\n      date: \"2024-02-07\"\n      event_name: \"Ruby in London February 2024\"\n      description: \"\"\n      id: \"daniel-vartanov-ruby-in-london–february-2024\"\n      video_id: \"daniel-vartanov-ruby-in-london–february-2024\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Daniel Vartanov\n\n- id: \"ruby-in-london-may-2024\"\n  title: \"Ruby in London May 2024\"\n  raw_title: \"Ruby in London with Mindful Chef\"\n  event_name: \"Ruby in London May 2024\"\n  date: \"2024-05-01\"\n  video_id: \"ruby-in-london-may-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/c/a/4/4/600_519711780.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/c/a/4/4/600_519711780.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/c/a/4/4/600_519711780.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/c/a/4/4/600_519711780.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/c/a/4/4/600_519711780.webp?w=750\"\n  description: |-\n    Hi All,\n\n    I hope you are well.\n\n    Our next event has been confirmed for the 1st of May with Mindful Chef starting at 5:30pm, with food and drinks provided.\n\n    Talk 1 - Miles Woodroffe with \"Getting Started with Solid Queue - The new default ActiveJob backend for Rails 8\"\n\n    Talk 2 - Serg Tyatin with \"Race Conditions RSpec How to\"\n\n    Look forward to seeing you all there!\n\n    Thanks,\n    Liam\n\n    https://www.meetup.com/ruby-in-london/events/299767863\n\n  talks:\n    - title: \"Getting Started with Solid Queue - The new default ActiveJob backend for Rails 8\"\n      date: \"2024-05-01\"\n      event_name: \"Ruby in London May 2024\"\n      description: \"\"\n      id: \"miles-woodroffe-ruby-in-london–may-2024\"\n      video_id: \"miles-woodroffe-ruby-in-london–may-2024\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Miles Woodroffe\n\n    - title: \"Race Conditions RSpec How to\"\n      date: \"2024-05-01\"\n      event_name: \"Ruby in London May 2024\"\n      description: \"\"\n      id: \"serg-tyatin-ruby-in-london–may-2024\"\n      video_id: \"serg-tyatin-ruby-in-london–may-2024\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Serg Tyatin\n\n- id: \"ruby-in-london-july-2024\"\n  title: \"Ruby in London July 2024\"\n  raw_title: \"Ruby in London with Beam\"\n  event_name: \"Ruby in London July 2024\"\n  date: \"2024-07-17\"\n  video_id: \"ruby-in-london-july-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/8/c/b/600_520802251.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/8/c/b/600_520802251.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/8/c/b/600_520802251.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/8/c/b/600_520802251.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/8/c/b/600_520802251.webp?w=750\"\n  description: |-\n    Hi All,\n\n    I hope you are well.\n\n    Our next event has been confirmed for the 17th of July with Beam starting at 6pm, with food and drinks provided.\n\n    Speakers/Talks\n    1st: Dan Hough (Beam) - The Human Touch: Ruby & AI for the Future of Welfare Services\n    2nd: Roman Samoilov - Modernising Ruby Systems with Rage\n\n    Look forward to seeing you all there!\n\n    Thanks,\n    Josh\n\n    https://www.meetup.com/ruby-in-london/events/300777187\n\n  talks:\n    - title: \"The Human Touch: Ruby & AI for the Future of Welfare Services\"\n      date: \"2024-07-17\"\n      event_name: \"Ruby in London July 2024\"\n      description: \"\"\n      id: \"dan-hough-ruby-in-london–july-2024\"\n      video_id: \"dan-hough-ruby-in-london–july-2024\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Dan Hough\n\n    - title: \"Modernising Ruby Systems with Rage\"\n      date: \"2024-07-17\"\n      event_name: \"Ruby in London July 2024\"\n      description: \"\"\n      id: \"roman-samoilov-ruby-in-london–july-2024\"\n      video_id: \"roman-samoilov-ruby-in-london–july-2024\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Roman Samoilov\n\n- id: \"ruby-in-london–january-2025\"\n  title: \"Ruby in London January 2025\"\n  raw_title: \"Ruby in London with Ophelos\"\n  event_name: \"Ruby in London January 2025\"\n  date: \"2025-01-22\"\n  video_id: \"ruby-in-london–january-2025\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/3/6/1/f/600_525733855.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/3/6/1/f/600_525733855.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/3/6/1/f/600_525733855.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/3/6/1/f/600_525733855.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/3/6/1/f/600_525733855.webp?w=750\"\n  description: |-\n    Hi All,\n\n    I hope you are well.\n\n    Our next event has been confirmed for Wednesday 22nd January with Ophelos starting at 5.30pm, with food and drinks provided.\n\n    Speakers/Talks\n    1st: Allan Wazacz, Senior Engineer at Ophelos - Engineered for Speed: A Custom A/B Testing Solution That Delivered Results Fast\n\n    2nd: Stephen Creedon, Engineering Director at Oyster - Serverless Gubbins in Ruby\n\n    Look forward to seeing you all there!\n\n    Thanks,\n    Josh\n\n    https://www.meetup.com/ruby-in-london/events/305376921\n\n  talks:\n    - title: \"Engineered for Speed: A Custom A/B Testing Solution That Delivered Results Fast\"\n      date: \"2025-01-22\"\n      event_name: \"Ruby in London January 2025\"\n      description: |-\n        Senior Engineer at Ophelos\n      id: \"allan-wazacz-ruby-in-london–january-2025\"\n      video_id: \"allan-wazacz-ruby-in-london–january-2025\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Allan Wazacz\n\n    - title: \"Serverless Gubbins in Ruby\"\n      date: \"2025-01-22\"\n      event_name: \"Ruby in London January 2025\"\n      description: |-\n        Engineering Director at Oyster\n      id: \"stephen-creedon-ruby-in-london–january-2025\"\n      video_id: \"stephen-creedon-ruby-in-london–january-2025\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Stephen Creedon\n"
  },
  {
    "path": "data/ruby-in-london/series.yml",
    "content": "---\nname: \"Ruby in London\"\nwebsite: \"https://www.meetup.com/ruby-in-london\"\ntwitter: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"UK\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-india/pune-ruby-meetup/event.yml",
    "content": "---\nid: \"pune-ruby-meetup\"\ntitle: \"Pune Ruby Meetup\"\nlocation: \"Pune, India\"\ndescription: \"\"\nkind: \"meetup\"\npublished_at: \"2025-02-01\"\nyear: 2025\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#DF1C5B\"\nwebsite: \"https://lu.ma/calendar/cal-KTu2DlicAMuYZT1\"\ncoordinates:\n  latitude: 18.5246091\n  longitude: 73.8786239\n"
  },
  {
    "path": "data/ruby-india/pune-ruby-meetup/videos.yml",
    "content": "---\n# Website: https://lu.ma/calendar/cal-KTu2DlicAMuYZT1\n\n# 2025\n\n- id: \"pune-ruby-meetup-february-2025\"\n  title: \"Pune Ruby Meetup February 2025\"\n  event_name: \"Pune Ruby Meetup February 2025\"\n  date: \"2025-02-01\"\n  video_provider: \"children\"\n  video_id: \"pune-ruby-meetup-february-2025\"\n  thumbnail_xs:\n    \"https://social-images.lu.ma/cdn-cgi/image/quality=75,width=320/api/event-one?c&calendar_name=Pune%20Ruby%20Meetup&color0=%232c2648&color1=%238b3c58&color2=%23d2907d\\\n    &color3=%23637ba2&host_avatar=https%3A%2F%2Fimages.lumacdn.com%2Favatars%2Fi9%2Fd39e07cd-004d-4e87-bd85-c5d6780cad1d&host_name=Ruby%20India&img=https%3A%2F%2Fimages.lumacdn.co\\\n    m%2Fgallery-images%2Fhb%2F7139411f-dcbf-49af-a919-df4e45f7754a&name=Pune%20Ruby%20Meetup%20February%202025\"\n  thumbnail_sm:\n    \"https://social-images.lu.ma/cdn-cgi/image/quality=75,width=480/api/event-one?c&calendar_name=Pune%20Ruby%20Meetup&color0=%232c2648&color1=%238b3c58&color2=%23d2907d\\\n    &color3=%23637ba2&host_avatar=https%3A%2F%2Fimages.lumacdn.com%2Favatars%2Fi9%2Fd39e07cd-004d-4e87-bd85-c5d6780cad1d&host_name=Ruby%20India&img=https%3A%2F%2Fimages.lumacdn.co\\\n    m%2Fgallery-images%2Fhb%2F7139411f-dcbf-49af-a919-df4e45f7754a&name=Pune%20Ruby%20Meetup%20February%202025\"\n  thumbnail_md:\n    \"https://social-images.lu.ma/cdn-cgi/image/quality=75,width=720/api/event-one?c&calendar_name=Pune%20Ruby%20Meetup&color0=%232c2648&color1=%238b3c58&color2=%23d2907d\\\n    &color3=%23637ba2&host_avatar=https%3A%2F%2Fimages.lumacdn.com%2Favatars%2Fi9%2Fd39e07cd-004d-4e87-bd85-c5d6780cad1d&host_name=Ruby%20India&img=https%3A%2F%2Fimages.lumacdn.co\\\n    m%2Fgallery-images%2Fhb%2F7139411f-dcbf-49af-a919-df4e45f7754a&name=Pune%20Ruby%20Meetup%20February%202025\"\n  thumbnail_lg:\n    \"https://social-images.lu.ma/cdn-cgi/image/quality=75,width=1024/api/event-one?c&calendar_name=Pune%20Ruby%20Meetup&color0=%232c2648&color1=%238b3c58&color2=%23d2907\\\n    d&color3=%23637ba2&host_avatar=https%3A%2F%2Fimages.lumacdn.com%2Favatars%2Fi9%2Fd39e07cd-004d-4e87-bd85-c5d6780cad1d&host_name=Ruby%20India&img=https%3A%2F%2Fimages.lumacdn.c\\\n    om%2Fgallery-images%2Fhb%2F7139411f-dcbf-49af-a919-df4e45f7754a&name=Pune%20Ruby%20Meetup%20February%202025\"\n  thumbnail_xl:\n    \"https://social-images.lu.ma/cdn-cgi/image/quality=75,width=2048/api/event-one?c&calendar_name=Pune%20Ruby%20Meetup&color0=%232c2648&color1=%238b3c58&color2=%23d2907\\\n    d&color3=%23637ba2&host_avatar=https%3A%2F%2Fimages.lumacdn.com%2Favatars%2Fi9%2Fd39e07cd-004d-4e87-bd85-c5d6780cad1d&host_name=Ruby%20India&img=https%3A%2F%2Fimages.lumacdn.c\\\n    om%2Fgallery-images%2Fhb%2F7139411f-dcbf-49af-a919-df4e45f7754a&name=Pune%20Ruby%20Meetup%20February%202025\"\n  description: |-\n    https://lu.ma/2yob77sl\n  talks:\n    - title: \"Serializers in Rails\"\n      event_name: \"Pune Ruby Meetup February 2025\"\n      date: \"2025-02-01\"\n      speakers:\n        - Apoorv Tiwari\n      id: \"apoorv-tiwari-pune-ruby-meetup-february-2025\"\n      video_id: \"apoorv-tiwari-pune-ruby-meetup-february-2025\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GirjUXlbYAUXZAd?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GirjUXlbYAUXZAd?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GirjUXlbYAUXZAd?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GirjUXlbYAUXZAd?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GirjUXlbYAUXZAd?format=jpg&name=large\"\n      description: \"\"\n\n    - title: \"Deploy Rails Application using Kamal 2\"\n      event_name: \"Pune Ruby Meetup February 2025\"\n      date: \"2025-02-01\"\n      speakers:\n        - Deepak Mahakale\n      id: \"deepak-mahakale-pune-ruby-meetup-february-2025\"\n      video_id: \"deepak-mahakale-pune-ruby-meetup-february-2025\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GirmHxDaIAAgdrO?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GirmHxDaIAAgdrO?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GirmHxDaIAAgdrO?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GirmHxDaIAAgdrO?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GirmHxDaIAAgdrO?format=jpg&name=large\"\n      description: \"\"\n\n    - title: \"Secret Talk\"\n      event_name: \"Pune Ruby Meetup February 2025\"\n      date: \"2025-02-01\"\n      speakers:\n        - Keshav Biswa\n      id: \"keshav-biswa-pune-ruby-meetup-february-2025\"\n      video_id: \"keshav-biswa-pune-ruby-meetup-february-2025\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GirysgCbkAACFp6?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GirysgCbkAACFp6?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GirysgCbkAACFp6?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GirysgCbkAACFp6?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GirysgCbkAACFp6?format=jpg&name=large\"\n      thumbnail_classes: \"object-bottom\"\n      description: \"\"\n\n    - title: \"Solid Trifecta\"\n      event_name: \"Pune Ruby Meetup February 2025\"\n      date: \"2025-02-01\"\n      speakers:\n        - Vipul A M\n      id: \"vipul-a-m-pune-ruby-meetup-february-2025\"\n      video_id: \"vipul-a-m-pune-ruby-meetup-february-2025\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GidYh2bW8AAFmjb?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GidYh2bW8AAFmjb?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GidYh2bW8AAFmjb?format=jpg&name=medium\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GidYh2bW8AAFmjb?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GidYh2bW8AAFmjb?format=jpg&name=large\"\n      description: \"\"\n"
  },
  {
    "path": "data/ruby-india/series.yml",
    "content": "---\nname: \"Ruby India\"\nwebsite: \"https://lu.ma/user/rubyindia\"\ntwitter: \"ruby_ind\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"IN\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-maizuru/ruby-maizuru-meetup/event.yml",
    "content": "---\nid: \"ruby-maizuru-meetup\"\ntitle: \"Ruby舞鶴 Meetup\"\nlocation: \"Maizuru, Japan\"\ndescription: |-\n  A study group for Rubyists in Maizuru, northern Kyoto, and nearby areas. It welcomes beginners and experienced developers for study sessions, presentations, and collaborative learning around Ruby and Rails.\nwebsite: \"https://ruby-maizuru.connpass.com\"\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 35.4747274\n  longitude: 135.3860338\n"
  },
  {
    "path": "data/ruby-maizuru/ruby-maizuru-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/ruby-maizuru/series.yml",
    "content": "---\nname: \"Ruby舞鶴\"\nwebsite: \"https://ruby-maizuru.connpass.com\"\nkind: \"meetup\"\nfrequency: \"irregular\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-1/event.yml",
    "content": "---\nid: \"ruby-manor-1\"\ntitle: \"Ruby Manor 1: Classic\"\nkind: \"conference\"\ndescription: |-\n  Everyone says the best part of a conference is hanging out the foyer (that's 'lobby' for the benefit of the colonials). But would you really pay £500 to do that? (That's $16,532,742, too).\nlocation: \"London, UK\"\nstart_date: \"2008-11-22\"\nend_date: \"2008-11-22\"\npublished_at: \"2008-11-22\"\nchannel_id: \"rubymanor\"\nyear: 2008\nwebsite: \"http://rubymanor.org/classic/\"\nbanner_background: \"#010101\"\nfeatured_background: \"#010101\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-1/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - James Adam\n    - Murray Steele\n\n- name: \"Camera Equipment\"\n  users:\n    - James Cox\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-1/videos.yml",
    "content": "---\n# Website: http://rubymanor.org/classic\n\n- id: \"http://video.rubymanor.org/classic/trailer/trailer.m4v\"\n  title: \"The Trailer\"\n  raw_title: \"The Trailer\"\n  speakers:\n    - Ruby Manor Organizers\n  event_name: \"Ruby Manor 1: Classic\"\n  date: \"2008-11-22\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/classic/trailer/trailer.m4v\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/videos/trailer/\"\n\n- id: \"http://video.rubymanor.org/classic/rack/rack.mp4\"\n  title: \"8 Minutes On Rack\"\n  raw_title: \"8 Minutes On Rack\"\n  speakers:\n    - Dan Webb\n  event_name: \"Ruby Manor 1: Classic\"\n  date: \"2008-11-22\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/classic/rack/rack.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/videos/rack/\"\n  slides_url: \"https://www.slideshare.net/danwrong/8-minutes-on-rack-presentation/\"\n\n- id: \"http://video.rubymanor.org/classic/iplayer/iplayer.mp4\"\n  title: \"I'm An Evil iPlayer Hacker\"\n  raw_title: \"I'm An Evil iPlayer Hacker\"\n  speakers:\n    - Paul Battley\n  event_name: \"Ruby Manor 1: Classic\"\n  date: \"2008-11-22\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/classic/iplayer/iplayer.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/videos/iplayer/\"\n  slides_url: \"https://po-ru.com/presentations/iplayer-hacker/\"\n\n- id: \"http://video.rubymanor.org/classic/unobtrusive_metaprogramming/unobtrusive_metaprogramming.mp4\"\n  title: \"Unobtrusive Metaprogramming\"\n  raw_title: \"Unobtrusive Metaprogramming\"\n  speakers:\n    - Sean O'Halpin\n  event_name: \"Ruby Manor 1: Classic\"\n  date: \"2008-11-22\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/classic/unobtrusive_metaprogramming/unobtrusive_metaprogramming.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/videos/unobtrusive_metaprogramming/\"\n  slides_url: \"https://seanohalpin.github.com/unobtrusive-metaprogramming/unobtrusive-metaprogramming.html\"\n\n- id: \"http://video.rubymanor.org/classic/gui_manor_born/gui_manor_born.mp4\"\n  title: \"GUI Manor Born\"\n  raw_title: \"GUI Manor Born\"\n  speakers:\n    - Martin Sadler\n    - Murray Steele\n  event_name: \"Ruby Manor 1: Classic\"\n  date: \"2008-11-22\"\n  published_at: \"\"\n  description: |-\n    https://www.slideshare.net/hlame/tying-your-shoes-presentation/\n    https://www.slideshare.net/martinbtt/monkeybars-in-the-manor-presentation\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/classic/gui_manor_born/gui_manor_born.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/videos/gui_manor_born/\"\n  slides_url: \"https://www.slideshare.net/hlame/tying-your-shoes-presentation/\"\n\n- id: \"http://video.rubymanor.org/classic/nanite/nanite.mp4\"\n  title: \"Nanite\"\n  raw_title: \"Nanite\"\n  speakers:\n    - George Palmer\n  event_name: \"Ruby Manor 1: Classic\"\n  date: \"2008-11-22\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/classic/nanite/nanite.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/videos/nanite/\"\n  slides_url: \"https://www.slideshare.net/Georgio_1999/rubymanor-presentation/\"\n\n- id: \"http://video.rubymanor.org/classic/rugalytics/rugalytics.mp4\"\n  title: \"Rugalytics\"\n  raw_title: \"Rugalytics\"\n  speakers:\n    - Rob McKinnon\n  event_name: \"Ruby Manor 1: Classic\"\n  date: \"2008-11-22\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/classic/rugalytics/rugalytics.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/videos/rugalytics/\"\n  slides_url: \"https://www.slideshare.net/delineator/rugalytics-ruby-manor-nov-2008-presentation\"\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-2/event.yml",
    "content": "---\nid: \"ruby-manor-2\"\ntitle: \"Ruby Manor 2: Manor Harder\"\nkind: \"conference\"\ndescription: \"\"\nlocation: \"London, UK\"\nstart_date: \"2009-12-12\"\nend_date: \"2009-12-12\"\npublished_at: \"2009-12-12\"\nchannel_id: \"rubymanor\"\nyear: 2009\nwebsite: \"http://rubymanor.org/harder/\"\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-2/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - James Adam\n    - Kalvir Sandhu\n    - Murray Steele\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-2/videos.yml",
    "content": "---\n# Website: http://rubymanor.org/harder\n\n- id: \"http://video.rubymanor.org/harder/browser_testing/martin_kleppmann_browser_testing.mp4\"\n  title: \"Browser-level testing\"\n  raw_title: \"Browser Testing\"\n  speakers:\n    - \"Martin Kleppmann\"\n  event_name: \"Ruby Manor 2: Manor Harder\"\n  date: \"2009-12-12\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/harder/browser_testing/martin_kleppmann_browser_testing.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/harder/videos/browser_testing/\"\n  slides_url: \"http://www.slideshare.net/martinkleppmann/browserlevel-testing\"\n\n- id: \"http://video.rubymanor.org/harder/short_order_ruby/ben_griffiths_short_order_ruby.mp4\"\n  title: \"Short Order Ruby\"\n  raw_title: \"Short Order Ruby\"\n  speakers:\n    - \"Ben Griffiths\"\n  event_name: \"Ruby Manor 2: Manor Harder\"\n  date: \"2009-12-12\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/harder/short_order_ruby/ben_griffiths_short_order_ruby.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/harder/videos/short_order_ruby/\"\n  slides_url: \"http://rubymanor.org/harder/videos/short_order_ruby/ben_griffiths_short_order_ruby.key\"\n\n- id: \"http://video.rubymanor.org/harder/tdd_with_webmock/bartosz_blimke_tdd_with_webmock.mp4\"\n  title: \"TDD With WebMock\"\n  raw_title: \"TDD With WebMock\"\n  speakers:\n    - \"Bartosz Blimke\"\n  event_name: \"Ruby Manor 2: Manor Harder\"\n  date: \"2009-12-12\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/harder/tdd_with_webmock/bartosz_blimke_tdd_with_webmock.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/harder/videos/tdd_with_webmock/\"\n  slides_url: \"http://www.slideshare.net/bartoszblimke/tdd-of-http-clients-with-webmock\"\n\n- id: \"http://video.rubymanor.org/harder/gem_that/james_adam_gem_that.mp4\"\n  title: \"Gem That\"\n  raw_title: \"Gem That\"\n  speakers:\n    - \"James Adam\"\n  event_name: \"Ruby Manor 2: Manor Harder\"\n  date: \"2009-12-12\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/harder/gem_that/james_adam_gem_that.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/harder/videos/gem_that/\"\n  slides_url: \"http://public.lazyatom.com/gem_that_with_notes.pdf\"\n\n- id: \"http://video.rubymanor.org/harder/secrets_of_the_stdlib/paul_battley_secrets_of_the_stdlib.mp4\"\n  title: \"Secrets Of The StdLib\"\n  raw_title: \"Secrets Of The StdLib\"\n  speakers:\n    - \"Paul Battley\"\n  event_name: \"Ruby Manor 2: Manor Harder\"\n  date: \"2009-12-12\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/harder/secrets_of_the_stdlib/paul_battley_secrets_of_the_stdlib.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/harder/videos/secrets_of_the_stdlib/\"\n  slides_url: \"http://rubymanor.org/harder/videos/secrets_of_the_stdlib/paul_battley_secrets_of_the_stdlib.pdf\"\n\n- id: \"http://video.rubymanor.org/harder/data_visualisation_with_ruby/chris_lowis_data_visualisation_with_ruby.mp4\"\n  title: \"Data Visualisation With Ruby\"\n  raw_title: \"Data Visualisation With Ruby\"\n  speakers:\n    - \"Chris Lowis\"\n  event_name: \"Ruby Manor 2: Manor Harder\"\n  date: \"2009-12-12\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/harder/data_visualisation_with_ruby/chris_lowis_data_visualisation_with_ruby.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/harder/videos/data_visualisation_with_ruby/\"\n  slides_url: \"http://github.com/chrislo/data_visualisation_ruby/raw/master/slides.pdf\"\n\n- id: \"http://video.rubymanor.org/harder/ruby_and_cocoa/james_mead_ruby_and_cocoa.mp4\"\n  title: \"Ruby And Cocoa\"\n  raw_title: \"Ruby And Cocoa\"\n  speakers:\n    - \"James Mead\"\n  event_name: \"Ruby Manor 2: Manor Harder\"\n  date: \"2009-12-12\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/harder/ruby_and_cocoa/james_mead_ruby_and_cocoa.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/harder/videos/ruby_and_cocoa/\"\n  slides_url: \"https://jamesmead.org/talks/2009-12-14-ruby-and-cocoa-at-ruby-manor/\"\n\n- id: \"http://video.rubymanor.org/harder/denormalizing_rails/daniel_lucraft_denormalizing_rails.mp4\"\n  title: \"Denormalizing Rails\"\n  raw_title: \"Denormalizing Rails\"\n  speakers:\n    - \"Daniel Lucraft\"\n  event_name: \"Ruby Manor 2: Manor Harder\"\n  date: \"2009-12-12\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/harder/denormalizing_rails/daniel_lucraft_denormalizing_rails.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/harder/videos/denormalizing_rails/\"\n  slides_url: \"http://github.com/danlucraft/presentations/raw/master/denormalizing.pdf\"\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-3/event.yml",
    "content": "---\nid: \"ruby-manor-3\"\ntitle: \"Ru3y Manor\"\nkind: \"conference\"\ndescription: |-\n  University of Westminster, New Cavendish Street, London\nlocation: \"London, UK\"\nstart_date: \"2011-10-29\"\nend_date: \"2011-10-29\"\npublished_at: \"2011-10-29\"\nchannel_id: \"rubymanor\"\nyear: 2011\nwebsite: \"http://rubymanor.org/3/\"\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\naliases:\n  - Ruby Manor 3\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-3/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - James Adam\n    - Murray Steele\n    - Tom Stuart\n\n- name: \"Camera Equipment & Operation\"\n  users:\n    - Andrew White\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-3/videos.yml",
    "content": "---\n# Website: http://rubymanor.org/3/\n\n- id: \"http://video.rubymanor.org/3/download/tom-stuart-object-oriented-rails-normal.mp4\"\n  title: \"Rails vs. Object Oriented Design\"\n  raw_title: \"Rails vs. Object Oriented Design\"\n  speakers:\n    - \"Tom Stuart @mortice\"\n  event_name: \"Ru3y Manor\"\n  date: \"2011-10-29\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/3/download/tom-stuart-object-oriented-rails-normal.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/3/videos/rails_vs_object-oriented_design/\"\n  slides_url: \"http://rails-vs-oo.heroku.com/\"\n\n- id: \"http://video.rubymanor.org/3/download/tim-cowlishaw-jruby-on-elephants-normal.mp4\"\n  title: \"JRuby on Elephants\"\n  raw_title: \"Jruby on Elephants\"\n  speakers:\n    - \"Tim Cowlishaw\"\n  event_name: \"Ru3y Manor\"\n  date: \"2011-10-29\"\n  published_at: \"\"\n  description: |-\n    Code: https://github.com/timcowlishaw/jruby-on-elephants\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/3/download/tim-cowlishaw-jruby-on-elephants-normal.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/3/videos/jruby_on_elephants/\"\n  slides_url: \"http://jruby-on-elephants.heroku.com/\"\n  additional_resources:\n    - name: \"timcowlishaw/jruby-on-elephants\"\n      type: \"repo\"\n      url: \"https://github.com/timcowlishaw/jruby-on-elephants\"\n\n- id: \"http://video.rubymanor.org/3/streaming/andrew-nesbit-eventmachine-and-node-js.mp4\"\n  title: \"Is Eventmachine a worthy alternative to Node.js?\"\n  raw_title: \"Is Eventmachine a worthy alternative to Node.js?\"\n  speakers:\n    - \"Andrew Nesbitt\"\n  event_name: \"Ru3y Manor\"\n  date: \"2011-10-29\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/3/streaming/andrew-nesbit-eventmachine-and-node-js.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/3/videos/is_eventmachine_a_worthy_alternative_to_node.js/\"\n  slides_url: \"http://speakerdeck.com/u/andrew/p/em-vs-node\"\n\n- id: \"http://video.rubymanor.org/3/download/tom-stuart-programming-with-nothing-normal.mp4\"\n  title: \"Programming with Nothing\"\n  raw_title: \"Programming with Nothing\"\n  speakers:\n    - \"Tom Stuart\"\n  event_name: \"Ru3y Manor\"\n  date: \"2011-10-29\"\n  published_at: \"\"\n  description: |-\n    Code: https://github.com/tomstuart/nothing\n    Transcript: http://codon.com/programming-with-nothing\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/3/download/tom-stuart-programming-with-nothing-normal.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/3/videos/programming_with_nothing/\"\n  slides_url: \"http://speakerdeck.com/u/tomstuart/p/programming-with-nothing\"\n  additional_resources:\n    - name: \"tomstuart/nothing\"\n      type: \"repo\"\n      url: \"https://github.com/tomstuart/nothing\"\n\n- id: \"http://video.rubymanor.org/3/download/jon-leighton-refactoring-rails-normal.mp4\"\n  title: \"Refactoring Rails\"\n  raw_title: \"Refactoring Rails\"\n  speakers:\n    - \"Jon Leighton\"\n  event_name: \"Ru3y Manor\"\n  date: \"2011-10-29\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/3/download/jon-leighton-refactoring-rails-normal.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/3/videos/how_hard_can_it_be_a_refactoring_battle_story/\"\n  slides_url: \"http://www.scribd.com/doc/73727221/How-Hard-Can-It-Be-A-refactoring-battle-story\"\n\n- id: \"http://video.rubymanor.org/3/download/sean-ohalpin-the-joy-of-text-normal.mp4\"\n  title: \"The Joy of Text\"\n  raw_title: \"The Joy of Text\"\n  speakers:\n    - \"Sean O'Halpin\"\n  event_name: \"Ru3y Manor\"\n  date: \"2011-10-29\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/3/download/sean-ohalpin-the-joy-of-text-normal.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/3/videos/the_joy_of_text/\"\n  slides_url: \"\"\n\n- id: \"http://video.rubymanor.org/3/download/paul-battley-dont-fear-the-lambda-normal.mp4\"\n  title: \"Don't fear the lambda\"\n  raw_title: \"Don't fear the lambda\"\n  speakers:\n    - \"Paul Battley\"\n  event_name: \"Ru3y Manor\"\n  date: \"2011-10-29\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/3/download/paul-battley-dont-fear-the-lambda-normal.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/3/videos/dont_fear_the_lambda/\"\n  slides_url: \"http://po-ru.com/presentations/dont-fear-the-lambda/\"\n\n- id: \"http://video.rubymanor.org/3/download/ben-griffiths-a-random-walk-normal.mp4\"\n  title: \"A Random Walk\"\n  raw_title: \"A Random Walk\"\n  speakers:\n    - \"Ben Griffiths\"\n  event_name: \"Ru3y Manor\"\n  date: \"2011-10-29\"\n  published_at: \"\"\n  description: \"\"\n  video_provider: \"mp4\"\n  video_id: \"http://video.rubymanor.org/3/download/ben-griffiths-a-random-walk-normal.mp4\"\n  external_player: false\n  external_player_url: \"http://rubymanor.org/3/videos/a_random_walk/\"\n  slides_url: \"http://rubymanor.org/3/videos/a_random_walk/ben_griffiths_a_random_walk.pdf\"\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-4/event.yml",
    "content": "---\nid: \"ruby-manor-4\"\ntitle: \"Ruby Manor 4.0\"\nkind: \"conference\"\ndescription: |-\n  Videos from the Ruby Manor 4.0 conference held in London in April 2013: http://rubymanor.org/4/\nlocation: \"London, UK\"\nstart_date: \"2013-04-06\"\nend_date: \"2013-04-06\"\npublished_at: \"2013-11-05\"\nchannel_id: \"rubymanor\"\nyear: 2013\nwebsite: \"http://rubymanor.org/4/\"\nplaylist: \"https://vimeo.com/showcase/2596602\"\nbanner_background: \"#E6E3D7\"\nfeatured_background: \"#E6E3D7\"\nfeatured_color: \"#373633\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-4/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - James Adam\n    - Murray Steele\n    - Tom Stuart\n\n- name: \"Camera Equipment\"\n  users:\n    - Andrew France\n"
  },
  {
    "path": "data/ruby-manor/ruby-manor-4/videos.yml",
    "content": "---\n# Website: http://rubymanor.org/4/\n# Schedule: https://web.archive.org/web/20130422025301/http://lanyrd.com/2013/ruby-manor/schedule/\n\n## Saturday 6th April 2013\n\n# Registration\n\n- id: \"james-adam-ruby-manor-40\"\n  title: \"Intro\"\n  raw_title: \"Ruby Manor 4.0: Intro\"\n  speakers:\n    - James Adam\n  event_name: \"Ruby Manor 4.0\"\n  date: \"2013-04-06\"\n  published_at: \"2013-04-04\"\n  description: |-\n    https://vimeo.com/showcase/2596602/video/63335661\n  video_provider: \"vimeo\"\n  video_id: \"63335661\"\n\n- id: \"george-brocklehurst-ruby-manor-40\"\n  title: \"Sleeping with the enemy\"\n  raw_title: \"Ruby Manor 4.0: George Brocklehurst - Sleeping with the enemy\"\n  speakers:\n    - George Brocklehurst\n  event_name: \"Ruby Manor 4.0\"\n  date: \"2013-04-06\"\n  published_at: \"2013-11-05\"\n  description: |-\n    This talk is a comparison of Rails and Django. All of the code examples come from a Django application which can be found here: github.com/georgebrock/swte-demo\n\n    https://vimeo.com/showcase/2596602/video/78618185\n    Original proposal: vestibule.rubymanor.org/proposals/12\n    Slides and more info: lanyrd.com/2013/ruby-manor/scfdzm/\n  video_provider: \"vimeo\"\n  video_id: \"78618185\"\n  slides_url: \"https://georgebrock.github.io/talks/sleeping-with-the-enemy/\"\n\n- id: \"tim-cowlishaw-ruby-manor-40\"\n  title: \"From Ruby to Scala and back again: Better living through type-checking\"\n  raw_title: \"Ruby Manor 4.0: Tim Cowlishaw - From Ruby to Scala and back again: Better living through type-checking\"\n  speakers:\n    - Tim Cowlishaw\n  event_name: \"Ruby Manor 4.0\"\n  date: \"2013-04-06\"\n  published_at: \"2013-11-05\"\n  description: |-\n    Original proposal: vestibule.rubymanor.org/proposals/53\n    Slides and more info: lanyrd.com/2013/ruby-manor/scfdzk/\n  video_provider: \"vimeo\"\n  video_id: \"79180652\"\n\n- id: \"tom-stuart-mortice-ruby-manor-40\"\n  title: \"Mistakes at the heart of Ruby\"\n  raw_title: \"Ruby Manor 4.0: Tom Stuart - Mistakes at the heart of Ruby\"\n  speakers:\n    - Tom Stuart @mortice\n    # - name: Tom Stuart\n    #   twitter: mortice\n  event_name: \"Ruby Manor 4.0\"\n  date: \"2013-04-06\"\n  published_at: \"2013-11-05\"\n  description: |-\n    Original proposal: vestibule.rubymanor.org/proposals/45\n    Slides and more info: lanyrd.com/2013/ruby-manor/scffpd/\n  video_provider: \"vimeo\"\n  video_id: \"79179145\"\n\n- id: \"aanand-prasad-ruby-manor-40\"\n  title: \"FRiPpery\"\n  raw_title: \"Ruby Manor 4.0: Aanand Prasad - FRiPpery\"\n  speakers:\n    - Aanand Prasad\n  event_name: \"Ruby Manor 4.0\"\n  date: \"2013-04-06\"\n  published_at: \"2013-11-05\"\n  description: |-\n    Original proposal: vestibule.rubymanor.org/proposals/56\n    Slides and more info: lanyrd.com/2013/ruby-manor/scfdzh/\n  video_provider: \"vimeo\"\n  video_id: \"78633680\"\n\n- id: \"sam-phippen-ruby-manor-40\"\n  title: \"A/B testing got you elected, Mr. President\"\n  raw_title: \"Ruby Manor 4.0: Sam Phippen - A/B testing got you elected, Mr. President\"\n  speakers:\n    - Sam Phippen\n  event_name: \"Ruby Manor 4.0\"\n  date: \"2013-04-06\"\n  published_at: \"2013-11-05\"\n  description: |-\n    Original proposal: vestibule.rubymanor.org/proposals/32\n    Slides and more info: lanyrd.com/2013/ruby-manor/scfdzp/\n  video_provider: \"vimeo\"\n  video_id: \"79179932\"\n\n- id: \"francis-fish-ruby-manor-40\"\n  title: \"On discovering Joy\"\n  raw_title: \"Ruby Manor 4.0: Francis Fish - On discovering Joy\"\n  speakers:\n    - Francis Fish\n  event_name: \"Ruby Manor 4.0\"\n  date: \"2013-04-06\"\n  published_at: \"2013-11-05\"\n  description: |-\n    Original proposal: vestibule.rubymanor.org/proposals/37\n    Slides and more info: lanyrd.com/2013/ruby-manor/scfdzr/\n\n    Note: Our projector capture device failed and so we have reconstructed the live-coding parts of this talk from Francis' own practice session video: vimeo.com/63419169\n  video_provider: \"vimeo\"\n  video_id: \"79763459\"\n\n- id: \"beln-albeza-ruby-manor-40\"\n  title: \"Rapid game development with Ruby and Gosu\"\n  raw_title: \"Ruby Manor 4.0: Belén Albeza - Rapid game development with Ruby and Gosu\"\n  speakers:\n    - Belén Albeza\n  event_name: \"Ruby Manor 4.0\"\n  date: \"2013-04-06\"\n  published_at: \"2013-11-05\"\n  description: |-\n    Original proposal: vestibule.rubymanor.org/proposals/26\n    Slides and more info: lanyrd.com/2013/ruby-manor/scfdzq/\n  video_provider: \"vimeo\"\n  video_id: \"78635461\"\n\n- id: \"paul-battley-ruby-manor-40\"\n  title: \"Ten years that never happened\"\n  raw_title: \"Ruby Manor 4.0: Paul Battley - Ten years that never happened\"\n  speakers:\n    - Paul Battley\n  event_name: \"Ruby Manor 4.0\"\n  date: \"2013-04-06\"\n  published_at: \"2013-11-05\"\n  description: |-\n    Original proposal: vestibule.rubymanor.org/proposals/21\n    Slides and more info: lanyrd.com/2013/ruby-manor/scfdzg/\n  video_provider: \"vimeo\"\n  video_id: \"80188702\"\n"
  },
  {
    "path": "data/ruby-manor/series.yml",
    "content": "---\nname: \"Ruby Manor\"\nwebsite: \"http://rubymanor.org\"\ntwitter: \"rubymanor\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\ndefault_country_code: \"UK\"\n"
  },
  {
    "path": "data/ruby-midwest/ruby-midwest-2011/event.yml",
    "content": "---\nid: \"PL708EC50565A7C4DE\"\ntitle: \"Ruby Midwest 2011\"\nkind: \"conference\"\nlocation: \"Kansas City, MO, United States\"\ndescription: |-\n  Ruby Midwest - Regional Ruby Conference\npublished_at: \"2012-01-18\"\nstart_date: \"2011-11-04\"\nend_date: \"2011-11-05\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2011\nbanner_background: \"#081625\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://web.archive.org/web/20110831095514/http://www.rubymidwest.com/\"\ncoordinates:\n  latitude: 39.0997265\n  longitude: -94.5785667\n"
  },
  {
    "path": "data/ruby-midwest/ruby-midwest-2011/videos.yml",
    "content": "---\n- id: \"marty-haught-ruby-midwest-2011\"\n  title: \"Ruby Community: Awesome; Could Be Awesomer\"\n  raw_title: \"Ruby Community: Awesome; Could Be Awesomer by Marty Haught\"\n  speakers:\n    - Marty Haught\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    We are known for our community. Does this mean our job is done? Are we starting to stagnate? Simply gathering Rubyists together isn't enough. How are you improving your community? Fear not as anyone of you can take action. Whether you live in a place with no organized Ruby meet-ups or you're contemplating a big regional event, we will go over why you should take action and give you practical steps to do so. We'll also bring light to not just increasing membership counts but actively making everyone better. Innovation is happening out there that we'll go over in detail. Join us, learn and get involved -- we're building something awesome!\n  video_provider: \"youtube\"\n  video_id: \"XUOhTIkj6YA\"\n  alternative_recordings:\n    - title: \"Ruby Community: Awesome; Could Be Awesomer\"\n      raw_title: \"Ruby Midwest 2011 -  Ruby Community: Awesome; Could Be Awesomer\"\n      speakers:\n        - Marty Haught\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Ruby Community: Awesome; Could Be Awesomer   by: Marty Haught\n\n        We are known for our community. Does this mean our job is done? Are we starting to stagnate? Simply gathering Rubyists together isn't enough. How are you improving your community? Fear not as anyone of you can take action. Whether you live in a place with no organized Ruby meet-ups or you're contemplating a big regional event, we will go over why you should take action and give you practical steps to do so. We'll also bring light to not just increasing membership counts but actively making everyone better. Innovation is happening out there that we'll go over in detail. Join us, learn and get involved -- we're building something awesome!\n      video_provider: \"youtube\"\n      video_id: \"2I3oawIsR-k\"\n\n- id: \"angela-harms-ruby-midwest-2011\"\n  title: \"Does Pair Programming have to suck?\"\n  raw_title: \"Does Pair Programming have to suck? by Angela Harms\"\n  speakers:\n    - Angela Harms\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    On some teams, pairing is the norm, and some developers really enjoy the collaboration, experiencing enhanced productivity.Others work on teams where pairing is shunned, avoided, or... faked. I have been on a quest to discover, on the one hand, why some who call themselves craftsmen love pairing, and others want nothing to do with it. I did a short survey about pairing attitudes, and comparing successful and unsuccessful pairing experiences. The survey produced some really clear results. Some factors most of us think are really important to a good pairing session turned out to be... meh. Other factors, though, stood out, hands down, as clearly separating good from bad pairing experiences. I'd like to talk about these survey results, and have an honest discussion about why pairing sucks or doesn't suck, and how we can bring the two sides together.\n  video_provider: \"youtube\"\n  video_id: \"OQXEzwXtzJ8\"\n  alternative_recordings:\n    - title: \"Does pair programming have to suck?\"\n      raw_title: \"Ruby Midwest 2011 -  Does pair programming have to suck?\"\n      speakers:\n        - Angela Harms\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Does pair programming have to suck? by:  Angela Harms\n\n        On some teams, pairing is the norm, and some developers really enjoy the collaboration, experiencing enhanced productivity.Others work on teams where pairing is shunned, avoided, or... faked.\n        I have been on a quest to discover, on the one hand, why some who call themselves craftsmen love pairing, and others want nothing to do with it. I did a short survey about pairing attitudes, and comparing successful and unsuccessful pairing experiences.\n        The survey produced some really clear results. Some factors most of us think are really important to a good pairing session turned out to be... meh. Other factors, though, stood out, hands down, as clearly separating good from bad pairing experiences.\n        I'd like to talk about these survey results, and have an honest discussion about why pairing sucks or doesn't suck, and how we can bring the two sides together.\n      video_provider: \"youtube\"\n      video_id: \"MvjGDnKVE3Q\"\n\n- id: \"ben-scofield-ruby-midwest-2011\"\n  title: \"Break It Down\"\n  raw_title: \"Break It Down by Ben Scofield\"\n  speakers:\n    - Ben Scofield\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    Rails has been around for seven years now, which means there's been more than enough time for us to build huge, monolithic apps that do way too much. It's no surprise, then, that we've started to see a surge of interest in the decomposing large apps into a set of smaller, interrelated services. In this talk, I'll show just how to go about decomposing one app into these sorts of services -- from identifying splittable functionality, to extracting it, and to integrating the service back into the main app.\n  video_provider: \"youtube\"\n  video_id: \"E0uXFxmmN-I\"\n  alternative_recordings:\n    - title: \"Break It Down\"\n      raw_title: \"Ruby Midwest 2011 - Break It Down\"\n      speakers:\n        - Ben Scofield\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Break It Down by: Ben Scofield\n\n        Rails has been around for seven years now, which means there's been more than enough time for us to build huge, monolithic apps that do way too much. It's no surprise, then, that we've started to see a surge of interest in the decomposing large apps into a set of smaller, interrelated services.\n        In this talk, I'll show just how to go about decomposing one app into these sorts of services -- from identifying splittable functionality, to extracting it, and to integrating the service back into the main app.\n      video_provider: \"youtube\"\n      video_id: \"MoJFreD7XKY\"\n\n- id: \"dave-rappin-ruby-midwest-2011\"\n  title: \"Test your legacy Rails code\"\n  raw_title: \"Test your legacy Rails code by Dave Rappin\"\n  speakers:\n    - Dave Rappin\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    Everybody wants to do test-driven development, but switching to TDD or BDD on an existing project that doesn't have tests presents special challenges. Often, the current code is a tangled mess of dependencies that defeats the very concept of unit testing. Worse, if somebody has attempted TDD in the past, you might have a test suite that needs to be fixed before any new tests can be written. Don't give up. Adding test-coverage and TDD to your application will make it easier. This session will describe techniques that you can use to bootstrap a test-driven process into your project. You'll see how to use \"black-box\" techniques that don't depend on the structure of the code and \"white-box\" techniques that interact with the code more directly. Topics covered will include: * Using Cucumber to perform black-box testing. * Using RSpec to perform white-box testing. * Using mocks to isolate legacy code. Safer refactoring by finding seams, or ways to update code without changing existing behavior Measuring test coverage and other useful metrics At the end of this session you will be ready to attack the most monstrous of code bases with TDD.\n  video_provider: \"youtube\"\n  video_id: \"q-xyk144AJk\"\n\n- id: \"zach-holman-ruby-midwest-2011\"\n  title: \"How GitHub Uses GitHub to Build GitHub\"\n  raw_title: \"How GitHub Uses GitHub to Build GitHub by Zach Holman\"\n  speakers:\n    - Zach Holman\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    Build features fast. Ship them. That's what we try to do at GitHub. Our process is the anti-process: what's the minimum overhead we can put up with to keep our code quality high, all while building features as quickly as possible? It's not just features, either: faster development means happier developers. This talk will dive into how GitHub uses GitHub: we'll look at some of our actual Pull Requests, the internal apps we build on our own API, how we plan new features, our Git branching strategies, and lots of tricks we use to get everyone — developers, designers, and everyone else — involved with new code. We think it's a great way to work, and we think it'll work in your company, too.\n  video_provider: \"youtube\"\n  video_id: \"qyz3jkOBbQY\"\n  alternative_recordings:\n    - title: \"How GitHub Uses GitHub to Build GitHub\"\n      raw_title: \"Ruby Midwest 2011 - How GitHub Uses GitHub to Build GitHub\"\n      speakers:\n        - Zach Holman\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        How GitHub Uses GitHub to Build GitHub  by: Zach Holman\n\n        Build features fast. Ship them. That's what we try to do at GitHub. Our process is the anti-process: what's the minimum overhead we can put up with to keep our code quality high, all while building features *as quickly as possible*? It's not just features, either: faster development means happier developers.\n        This talk will dive into how GitHub uses GitHub: we'll look at some of our actual Pull Requests, the internal apps we build on our own API, how we plan new features, our Git branching strategies, and lots of tricks we use to get everyone â€” developers, designers, and everyone else â€” involved with new code. We think it's a great way to work, and we think it'll work in your company, too.\n      video_provider: \"youtube\"\n      video_id: \"w95Udrj79Ok\"\n\n- id: \"ruby-rogues-ruby-midwest-2011\"\n  title: \"Beyond Web Development\"\n  raw_title: \"Beyond Web Development by Ruby Rogues\"\n  speakers:\n    - Ruby Rogues\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    Live Pod Cast\n  video_provider: \"youtube\"\n  video_id: \"7VKiZ7OjJTE\"\n\n- id: \"ethan-gunderson-ruby-midwest-2011\"\n  title: \"ActiveRecord Anti-Patterns for Fun and Profit\"\n  raw_title: \"ActiveRecord Anti-Patterns for Fun and Profit by Ethan Gunderson\"\n  speakers:\n    - Ethan Gunderson\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    If you're writing code that looks like User.all.reject(), you're doing it wrong. Don't worry though, we've all done it before. ActiveRecord makes it all too easy to introduce code that is far from performant, and after awhile, we tend to forget that underneath the pretty API, we're still producing SQL. In this talk, we'll peel back the API so that we can see some of the common mistakes I see when dealing with ActiveRecord statements, and more importantly, how you can fix them.\n  video_provider: \"youtube\"\n  video_id: \"kYuPxEzURvQ\"\n  alternative_recordings:\n    - title: \"ActiveRecord Anti-Patterns for Fun and Profit\"\n      raw_title: \"Ruby Midwest 2011 - ActiveRecord Anti-Patterns for Fun and Profit\"\n      speakers:\n        - Ethan Gunderson\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        ActiveRecord Anti-Patterns for Fun and Profit  by: Ethan Gunderson\n\n        If you're writing code that looks like User.all.reject(), you're doing it wrong. Don't worry though, we've all done it before. ActiveRecord makes it all too easy to introduce code that is far from performant, and after awhile, we tend to forget that underneath the pretty API, we are still producing SQL. In this talk, we'll peel back the API so that we can see some of the common mistakes I see when dealing with ActiveRecord statements, and more importantly, how you can fix them.\n      video_provider: \"youtube\"\n      video_id: \"TO2yfO6gDGU\"\n\n- id: \"michael-bleigh-ruby-midwest-2011\"\n  title: \"Rails is the New Rails\"\n  raw_title: \"Rails is the New Rails by Michael Bleigh\"\n  speakers:\n    - Michael Bleigh\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    The sweeping changes brought on by Rails 3 and 3.1 haven't just make our existing development patterns easier, they have opened up the ability for us to build new patterns that accomplish more in a more beautiful and efficient way. In this session you will see how thinking about new features in a different light can lead to real innovation for your development practices. Examples include baking routing constraints into your models, application composition with Rack, truly modular design with the asset pipeline, and more.\n  video_provider: \"youtube\"\n  video_id: \"7Dh1IWDK2-Q\"\n  alternative_recordings:\n    - title: \"Rails is the New Rails\"\n      raw_title: \"Ruby Midwest 2011 - Rails is the New Rails\"\n      speakers:\n        - Michael Bleigh\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Rails is the New Rails  by: Michael Bleigh\n\n        The sweeping changes brought on by Rails 3 and 3.1 havenâ€™t just make our existing development patterns easier, they have opened up the ability for us to build new patterns that accomplish more in a more beautiful and efficient way. In this session you will see how thinking about new features in a different light can lead to real innovation for your development practices. Examples include baking routing constraints into your models, application composition with Rack, truly modular design with the asset pipeline, and more.\n      video_provider: \"youtube\"\n      video_id: \"gFUx-DZUIVc\"\n\n- id: \"ola-bini-ruby-midwest-2011\"\n  title: \"Ruby Safari\"\n  raw_title: \"Ruby Safari by Ola Bini\"\n  speakers:\n    - Ola Bini\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    There are many strange beasts in the Ruby language. Some of them you might never have seen. Others you might have seen but not understood. Ruby is a big language, and this presentation will show you some of the corners of Ruby that you might not have known about, or even dared think would exist in a modern language. Some of these features are useful, some of them are useless and some of them are just downright puzzling. Come here to get a tasting of the weirder parts of Ruby.\n  video_provider: \"youtube\"\n  video_id: \"yu7E145_zB4\"\n  alternative_recordings:\n    - title: \"Ruby Safari\"\n      raw_title: \"Ruby Midwest 2011 - Ruby Safari\"\n      speakers:\n        - Ola Bini\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Ruby Safari by: Ola Bini\n\n        There are many strange beasts in the Ruby language. Some of them you might never have seen. Others you might have seen but not understood.\n        Ruby is a big language, and this presentation will show you some of the corners of Ruby that you might not have known about, or even dared think would exist in a modern language. Some of these features are useful, some of them are useless and some of them are just downright puzzling. Come here to get a tasting of the weirder parts of Ruby.\n      video_provider: \"youtube\"\n      video_id: \"_jkFXL-Q3o8\"\n\n- id: \"david-czarnecki-ruby-midwest-2011\"\n  title: \"Final Boss Ruby/Rails in the Video Game Industry\"\n  raw_title: \"Final Boss Ruby/Rails  in the Video Game Industry by David Czarnecki\"\n  speakers:\n    - David Czarnecki\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    Did you know there are video games, both console and handheld, that talk directly to a Rails stack to provide functionality, both in-game and on the web? Did you know that there are Ruby/Rails services running 24/7/365 to process game data for over 40 million players around the world? You will learn about the code, methodologies and tools used to make all of this happen (and gain 5000 Rails XP)!\n  video_provider: \"youtube\"\n  video_id: \"Q3ghtz4Bi-8\"\n  alternative_recordings:\n    - title: \"Final Boss: Ruby/Rails in the Video Game Industry\"\n      raw_title: \"Ruby Midwest 2011 - Final Boss: Ruby/Rails in the Video Game Industry\"\n      speakers:\n        - David Czarnecki\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Final Boss: Ruby/Rails in the Video Game Industry  by: David Czarnecki\n\n        Did you know there are video games, both console and handheld, that talk directly to a Rails stack to provide functionality, both in-game and on the web? Did you know that there are Ruby/Rails services running 24/7/365 to process game data for over 40 million players around the world? You will learn about the code, methodologies and tools used to make all of this happen (and gain 5000 Rails XP)!\n      video_provider: \"youtube\"\n      video_id: \"ywtUZfSTjmg\"\n\n- id: \"dr-nic-williams-ruby-midwest-2011\"\n  title: \"High Performance Ruby Threading Versus Evented\"\n  raw_title: \"Ruby Conf 2011 High Performance Ruby Threading  Versus Evented by Dr. Nic Williams\"\n  speakers:\n    - Dr. Nic Williams\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    I wanted to know, \"Do I need to learn about EventMachine or node.js? Can I use threads? What is so good or bad about threading in Ruby 1.8, Ruby 1.9, JRuby and Rubinius 2.0?\" What was important to me was the the choice was abstracted away. I wanted to write normal, step-by-step Ruby code. Yet I wanted it to be performant. I've asked a lot of people. I even hosted EM RubyConf (http://emrubyconf.com) during RailsConf 2011 in order to gather the brightest minds in the Ruby community. \"What choices do I need to make, how different does my code look, and how do I do testing?\" These are the questions I searched for answers. I'd like to now share the answers.\n  video_provider: \"youtube\"\n  video_id: \"8gxtt1BxYIU\"\n  alternative_recordings:\n    - title: \"High Performance Ruby:  Threading versus Evented\"\n      raw_title: \"Ruby Midwest 2011 - High Performance Ruby:  Threading versus Evented\"\n      speakers:\n        - Dr. Nic Williams\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        High Performance Ruby:  Threading versus Evented  by: Dr. Nic Williams\n\n        I wanted to know, \"Do I need to learn about EventMachine or node.js? Can I use threads? What is so good or bad about threading in Ruby 1.8, Ruby 1.9, JRuby and Rubinius 2.0?\"\n        What was important to me\n      video_provider: \"youtube\"\n      video_id: \"Nt3Zva6KBho\"\n\n- id: \"joe-obrien-ruby-midwest-2011\"\n  title: \"People Patterns\"\n  raw_title: \"People Patterns by Joe O'Brien\"\n  speakers:\n    - Joe O'Brien\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    We spend a large portion of our time thinking about code and technical project issues. What about the people side of things? The majority of project failures occur because of people, not technology. What we need are guides that help us navigate the waters between the people around us. People Patterns introduces my latest effort to capture the subtleties and nuances of interpersonal relations. I'm distilling a lot of experience, a bit of psychology and a substantial amount of research and have come up with a series of patterns that can help everyone be more successful in teams and at work. How do you have those critical conversations? How do you get your point across when you think the other person is incompetent? Come and help me reveal these and join a lively discussion.\n  video_provider: \"youtube\"\n  video_id: \"D2BMKWPpqx4\"\n  alternative_recordings:\n    - title: \"People Patterns\"\n      raw_title: \"Ruby Midwest 2011 - People Patterns\"\n      speakers:\n        - Joe O'Brien\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        People Patterns by: Joe O'Brien\n\n        We spend a large portion of our time thinking about code and technical project issues. What about the people side of things? The majority of project failures occur because of people, not technology. What we need are guides that help us navigate the waters between the people around us.\n        People Patterns introduces my latest effort to capture the subtleties and nuances of interpersonal relations. I'm distilling a lot of experience, a bit of psychology and a substantial amount of research and have come up with a series of patterns that can help everyone be more successful in teams and at work. How do you have those critical conversations? How do you get your point across when you think the other person is incompetent? Come and help me reveal these and join a lively discussion.\n      video_provider: \"youtube\"\n      video_id: \"JUqhl7Yd7v4\"\n\n- id: \"eric-redmond-ruby-midwest-2011\"\n  title: \"Modern Databases\"\n  raw_title: \"Modern Databases by Eric Redmond\"\n  speakers:\n    - Eric Redmond\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    Choosing a data storage engine is an important decision, but it doesn't have to be painful if you know the landscape. We'll look at several DBMSs (and a few you've never heard of), compare and contrast them based on use-cases, and how to plug each into Ruby. Authoring the book \"Seven Databases in Seven Weeks\" has opened up a whole world of database alternatives that I never before seriously considered. It's an important decision to be made by research, not buzzwords -- and we've sifted through them so you don't have to. At the very least we can settle the Mongo v. Couch debate (hint: they're both awesome). This is not the same RailsConf talk. This is split into two parts: The components of modern databases: A 30,000 foot view of the current database ecosystem Understanding why the CAP theorem is true Understanding map/reduce from the Ruby perspective 12 databases in 12 minutes: The similarities/differences of the most popular open source DBs today When to use them, when to avoid them Which Ruby drivers to use\n  video_provider: \"youtube\"\n  video_id: \"G7-OGEYCMxQ\"\n  alternative_recordings:\n    - title: \"Modern Databases\"\n      raw_title: \"Ruby Midwest 2011 - Modern Databases\"\n      speakers:\n        - Eric Redmond\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Modern Databases by: Eric Redmond\n\n        Choosing a data storage engine is an important decision, but it doesn't have to be painful if you know the landscape. We'll look at several DBMSs (and a few you've never heard of), compare and contrast them based on use-cases, and how to plug each into Ruby.\n        Authoring the book \"Seven Databases in Seven Weeks\" has opened up a whole world of database alternatives that I never before seriously considered. It's an important decision to be made by research, not buzzwords and we have sifted through them so you don't have to. At the very least we can settle the Mongo v. Couch debate (hint: they're both awesome).\n        This is not the same RailsConf talk. This is split into two parts:\n        The components of modern databases:\n        A 30,000 foot view of the current database ecosystem\n        Understanding why the CAP theorem is true\n        Understanding map/reduce from the Ruby perspective\n        12 databases in 12 minutes:\n        The similarities/differences of the most popular open source DBs today\n        When to use them, when to avoid them\n        Which Ruby drivers to use\n      video_provider: \"youtube\"\n      video_id: \"gTk7NaBMlN0\"\n\n- id: \"avdi-grimm-ruby-midwest-2011\"\n  title: \"Confident Code\"\n  raw_title: \"Ruby Midwest 2011 Confident Code by Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    Are your methods timid? Do they constantly second-guess themselves, checking for nil values, errors, and unexpected input? Even the cleanest Ruby codebases can become littered over time with nil checks, error handling, and other interruptions which steal attention away from the essential purpose of the code. This talk will discuss strategies for writing your Ruby classes and methods in a confident, straightforward style; without sacrificing functionality or robustness. In the process, we'll cover concepts and techniques points including: The narrative style of method construction The four parts of a method Three strategies for dealing with uncertain input Massaging input with coercion and the Decorator pattern Lightweight preconditions Exterminating nils from your code The chaining and iterative styles of method construction Eliminating conditionals with the Special Case and Null Object patterns Isolating errors with the Bouncer and Checked Method patterns\n  video_provider: \"youtube\"\n  video_id: \"T8J0j2xJFgQ\"\n  alternative_recordings:\n    - title: \"Confident Code\"\n      raw_title: \"Ruby Midwest 2011 - Confident Code\"\n      speakers:\n        - Avdi Grimm\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Confident Code by: Avdi Grimm\n\n        Are your methods timid? Do they constantly second-guess themselves, checking for nil values, errors, and unexpected input?\n        Even the cleanest Ruby codebases can become littered over time with nil checks, error handling, and other interruptions which steal attention away from the essential purpose of the code. This talk will discuss strategies for writing your Ruby classes and methods in a confident, straightforward style; without sacrificing functionality or robustness. In the process, we'll cover concepts and techniques points including:\n        The narrative style of method construction\n        The four parts of a method\n        Three strategies for dealing with uncertain input\n        Massaging input with coercion and the Decorator pattern\n        Lightweight preconditions\n        Exterminating nils from your code\n        The chaining and iterative styles of method construction\n        Eliminating conditionals with the Special Case and Null Object patterns\n        Isolating errors with the Bouncer and Checked Method patterns\n      video_provider: \"youtube\"\n      video_id: \"t8s2MqnDPD8\"\n\n- id: \"david-copeland-ruby-midwest-2011\"\n  title: \"Make Awesome Command-Line Apps with Ruby\"\n  raw_title: \"Make awesome command line apps with ruby by Dave Copeland\"\n  speakers:\n    - David Copeland\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    Tired of maintaining your one-off script that has now become someone's job to execute? Wishing you could create polished applications on the command line similar to git or cucumber? In my talk, I'll talk about what makes a command line application \"awesome\", and why you should care. I'll talk about what makes Ruby particularly suited to this task over mainstays like bash and Perl. We'll compare and contrast several Ruby libraries that can make even your lowliest automation script a polished, maintainable, and predictable application.\n  video_provider: \"youtube\"\n  video_id: \"1ILEw6Qca3U\"\n  alternative_recordings:\n    - title: \"Make Awesome Command-Line Apps with Ruby\"\n      raw_title: \"Ruby Midwest 2011 - Make Awesome Command-Line Apps with Ruby\"\n      speakers:\n        - David Copeland\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Make Awesome Command-Line Apps with Ruby  by: David Copeland\n\n        Tired of maintaining your one-off script that has now become someone's job to execute? Wishing you could create polished applications on the command line similar to git or cucumber? In my talk, I'll talk about what makes a command line application \"awesome\", and why you should care. I'll talk about what makes Ruby particularly suited to this task over mainstays like bash and Perl. We'll compare and contrast several Ruby libraries that can make even your lowliest automation script a polished, maintainable, and predictable application.\n      video_provider: \"youtube\"\n      video_id: \"eYk2Otz4X4I\"\n\n- id: \"matt-hicks-ruby-midwest-2011\"\n  title: \"Running Red Hat Openshift with a little help from Ruby Ruby\"\n  raw_title: \"Running Red Hat Openshift with a little help from Ruby Ruby by Matt Hicks\"\n  speakers:\n    - Matt Hicks\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    This talk will dive into the details of OpenShift Express and it's support for Ruby and Rack. It will also cover how we are using Ruby internally on our development of OpenShift. This session will not only walk you through how to use OpenShift to deploy a Rails 3 application, but will also dive into why we standardized on Ruby as our development language. I'll cover the following topics at a hands-on level: Deploying a Rails 3 application with the OpenShift Express Cover how we are using Selenium WebDriver and the Ruby bindings for automated testing on headless machines Cover how we are using Apache Qpid (AMQP), the Ruby bindings and MCollective as the basis of our scale-out architecture\n  video_provider: \"youtube\"\n  video_id: \"mcD0c9iBHDo\"\n  alternative_recordings:\n    - title: \"Running Red Hat OpenShift  with a little help from Ruby\"\n      raw_title: \"Ruby Midwest 2011 - Running Red Hat OpenShift  with a little help from Ruby\"\n      speakers:\n        - Matt Hicks\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Running Red Hat OpenShift  with a little help from Ruby  by: Matt Hicks\n\n        This talk will dive into the details of OpenShift Express and it's support for Ruby and Rack. It will also cover how we are using Ruby internally on our development of OpenShift. This session will not only walk you through how to use OpenShift to deploy a Rails 3 application, but will also dive into why we standardized on Ruby as our development language. I'll cover the following topics at a hands-on level:\n        Deploying a Rails 3 application with the OpenShift Express\n        Cover how we are using Selenium WebDriver and the Ruby bindings for automated testing on headless machines\n        Cover how we are using Apache Qpid (AMQP), the Ruby bindings and MCollective as the basis of our scale-out architecture\n      video_provider: \"youtube\"\n      video_id: \"umV2LAFbFpE\"\n\n- id: \"robert-martin-ruby-midwest-2011\"\n  title: \"Keynote: Architecture the Lost Years\"\n  raw_title: \"Ruby Midwest 2011 - Keynote: Architecture the Lost Years by Robert Martin\"\n  speakers:\n    - Robert Martin\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    Robert C. Martin (Uncle Bob) has been a software professional since 1970. In the last 40 years, he has worked in various capacities on literally hundreds of software projects. He has authored \"landmark\" books on Agile Programming, Extreme Programming, UML, Object-Oriented Programming, C++ Programming and Clean Code. He has published dozens of articles in various trade journals. Today, he is one of the software industry's leading authorities on Agile software development and is a regular speaker at international conferences and trade shows. He is a former editor of the C++ Report and writes regular blogs at http://cleancoder.posterous.com/.\n  video_provider: \"youtube\"\n  video_id: \"WpkDN78P884\"\n  alternative_recordings:\n    - title: \"Keynote: Architecture the Lost Years\"\n      raw_title: \"Ruby Midwest 2011 - Keynote: Architecture the Lost Years\"\n      speakers:\n        - Robert Martin\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Keynote: Architecture the Lost Years by: Robert Martin\n\n        Robert C. Martin (Uncle Bob) has been a software professional since 1970. In the last 40 years, he has worked in various capacities on literally hundreds of software projects. He has authored \"landmark\" books on Agile Programming, Extreme Programming, UML, Object-Oriented Programming, C++ Programming and Clean Code. He has published dozens of articles in various trade journals. Today, he is one of the software industry's leading authorities on Agile software development and is a regular speaker at international conferences and trade shows. He is a former editor of the C++ Report and writes regular blogs at http://cleancoder.posterous.com/.\n      video_provider: \"youtube\"\n      video_id: \"hALFGQNeEnU\"\n\n- id: \"jim-weirich-ruby-midwest-2011\"\n  title: \"Mastering the ruby debugger\"\n  raw_title: \"Mastering the ruby debugger by Jim Weirich\"\n  speakers:\n    - Jim Weirich\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2012-01-18\"\n  description: |-\n    You are happily writing new code for your system when all of a sudden the code is not behaving the way you thought it should. Perhaps you just created a failing test, and the code you wrote was expected to make the test pass ... but it doesn't. What's the first thing you do? Some Rubyists will drop some \"puts\" statements into the code. Some will add a raise statement. And still others will depend on logging to trace the internals of the code. But a surprisingly few Rubyists will reach for the Ruby debugger. Despite a general disdain for the debugger in the Ruby community, the Ruby debugger is a powerful tool that can quickly get to the heart of a coding problem. This talk will concentrate on getting Rubyists up to speed on the debugger, how to use it effectively and learning other general debugging tips.\n  video_provider: \"youtube\"\n  video_id: \"GwgF8GcynV0\"\n  alternative_recordings:\n    - title: \"Mastering the Ruby Debugger\"\n      raw_title: \"Ruby Midwest 2011 - Mastering the Ruby Debugger\"\n      speakers:\n        - Jim Weirich\n      date: \"2011-11-04\"\n      event_name: \"Ruby Midwest 2011\"\n      published_at: \"2015-07-30\"\n      description: |-\n        Mastering the Ruby Debugger by: Jim Weirich\n\n        You are happily writing new code for your system when all of a sudden the code is not behaving the way you thought it should. Perhaps you just created a failing test, and the code you wrote was expected to make the test pass ... but it doesn't. What's the first thing you do?\n        Some Rubyists will drop some \"puts\" statements into the code. Some will add a raise statement. And still others will depend on logging to trace the internals of the code. But a surprisingly few Rubyists will reach for the Ruby debugger.\n        Despite a general disdain for the debugger in the Ruby community, the Ruby debugger is a powerful tool that can quickly get to the heart of a coding problem. This talk will concentrate on getting Rubyists up to speed on the debugger, how to use it effectively and learning other general debugging tips.\n      video_provider: \"youtube\"\n      video_id: \"y0G_3GUfpu8\"\n\n- id: \"rogelio-j-samour-ruby-midwest-2011\"\n  title: \"No Sudo for You!\"\n  raw_title: \"Ruby Midwest 2011 - No Sudo for You!\"\n  speakers:\n    - Rogelio J. Samour\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2015-07-30\"\n  description: |-\n    No Sudo for You! by: Rogelio J. Samour\n\n    As developers, we want to minimize the time we spend fighting with our development environment. The less time we spend dealing with configuration issues, the more time we can spend doing what we do best... creating awesome apps! I show how you can easily set up a development environment that is both flexible and powerful. But best of all, it wonâ€™t need regular attention!\n  video_provider: \"youtube\"\n  video_id: \"w0ame6GLtrQ\"\n\n- id: \"beyond-web-development-ruby-midwest-2011\"\n  title: \"Beyond Web Development\"\n  raw_title: \"Ruby Midwest 2011 - Beyond Web Development\"\n  speakers:\n    - James Edward Gray II\n    - David Copeland\n    - Avdi Grimm\n    - Ruby Rogues\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2015-07-30\"\n  description: |-\n    Beyond Web Development  by: James Edward Gray II,  David Copeland,  Avdi Grimm,  Ruby Rogues\n\n    Live podcast recording for Ruby Rogues!\n  video_provider: \"youtube\"\n  video_id: \"WQqywsLhd-o\"\n\n- id: \"noel-rappin-ruby-midwest-2011\"\n  title: \"Test Your Legacy Rails Code\"\n  raw_title: \"Ruby Midwest 2011 - Test Your Legacy Rails Code\"\n  speakers:\n    - Noel Rappin\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2015-07-30\"\n  description: |-\n    Test Your Legacy Rails Code by: Noel Rappin\n\n    Everybody wants to do test-driven development, but switching to TDD or BDD on an existing project that doesn't have tests presents special challenges. Often, the current code is a tangled mess of dependencies that defeats the very concept of unit testing. Worse, if somebody has attempted TDD in the past, you might have a test suite that needs to be fixed before any new tests can be written.\n\n    Don't give up. Adding test-coverage and TDD to your application will make it easier.\n\n    This session will describe techniques that you can use to bootstrap a test-driven process into your project. You'll see how to use \"black-box\" techniques that don't depend on the structure of the code and \"white-box\" techniques that interact with the code more directly.\n\n    Topics covered will include:\n\n    * Using Cucumber to perform black-box testing.\n    * Using RSpec to perform white-box testing\n  video_provider: \"youtube\"\n  video_id: \"Xj5vO_-NXag\"\n\n- id: \"matt-kirk-ruby-midwest-2011\"\n  title: \"Recommendation Engines using  Machine Learning, and JRuby\"\n  raw_title: \"Ruby Midwest 2011 - Recommendation Engines using  Machine Learning, and JRuby\"\n  speakers:\n    - Matt Kirk\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2015-07-30\"\n  description: |-\n    Recommendation Engines using  Machine Learning, and JRuby by: Matt Kirk\n\n    Ever wonder how netflix can predict what rating you would give to a movie? How do recommendation engines get built?\n    Well, it's possible with JRuby and it's fairly straight forward. Many engines are built purely on support vector machine regressions which map arrays of data onto a classifier, like a star.\n    In this talk I'll explain how support vector machines are built, and how do make a simple movie prediction model all in JRuby.\n  video_provider: \"youtube\"\n  video_id: \"EgGKQEu0-Lk\"\n\n- id: \"james-edward-gray-ii-ruby-midwest-2011\"\n  title: \"Life on the Edge\"\n  raw_title: \"Ruby Midwest 2011 - Life on the Edge\"\n  speakers:\n    - James Edward Gray II\n  date: \"2011-11-04\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2015-07-30\"\n  description: |-\n    Life on the Edge by: James Edward Gray II\n\n    We are probably all familiar with the dreaded edge cases that creep up on our production code and sucker punch it with inputs we never expected. I bet most of us have scrambled to fix those at one time or another.\n    The good news is that you don't have to live in fear of edge cases. In fact, you can turn the tables and force them to work for you. That's a technique I have used quite successfully in my own programming for many years now. It can help you to have better conversations with your clients, design smarter code, choose better processing strategies, and even luck into the right algorithms.\n    In this talk, I'll explain how I use edge case thinking, explain what it can do for you, and show several examples of how it leads to better choices. You will learn how to stop \"slurping\" data (even with SQL), how to shed your fear of nil returns and how to avoid spreading that fear to others, how to think synchronously but still get an asynchronous advantage, and more.\n  video_provider: \"youtube\"\n  video_id: \"WFQjvndMaC8\"\n\n- id: \"andy-hunt-ruby-midwest-2011\"\n  title: \"Keynote\"\n  raw_title: \"Ruby Midwest 2011 - Keynote\"\n  speakers:\n    - Andy Hunt\n  date: \"2011-05-11\"\n  event_name: \"Ruby Midwest 2011\"\n  published_at: \"2015-07-30\"\n  description: |-\n    Keynote by: Andy Hunt\n  video_provider: \"youtube\"\n  video_id: \"0irNEvIW8sY\"\n"
  },
  {
    "path": "data/ruby-midwest/ruby-midwest-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZwIqysBb4BVWZ5hzWPPylr\"\ntitle: \"Ruby Midwest 2013\"\nkind: \"conference\"\nlocation: \"Kansas City, MO, United States\"\ndescription: \"\"\npublished_at: \"2013-04-28\"\nstart_date: \"2013-04-05\"\nend_date: \"2013-04-06\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2013\nbanner_background: \"#081625\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://web.archive.org/web/20140406224832/http://www.rubymidwest.com/\"\ncoordinates:\n  latitude: 39.0997265\n  longitude: -94.5785667\n"
  },
  {
    "path": "data/ruby-midwest/ruby-midwest-2013/videos.yml",
    "content": "---\n- id: \"james-edward-gray-ii-ruby-midwest-2013\"\n  title: \"Keynote by James Edward Gray II\"\n  raw_title: \"Ruby Midwest 2013 Keynote by James Edward Gray II\"\n  speakers:\n    - James Edward Gray II\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-27\"\n  announced_at: \"2012-12-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ZLFeqmh7Dec\"\n\n- id: \"ernie-miller-ruby-midwest-2013\"\n  title: \"The Most Important Optimization: Happiness\"\n  raw_title: \"Ruby Midwest 2013 The Most Important Optimization: Happiness by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-27\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Metaprogramming. It's awesome, right? Powerful? Maybe a little scary? Let's kick things up a notch. If writing code that writes code is powerful, what's hacking the life of the programmer writing the code? That's got to be an 11 on the meta-meter. At least. We'll talk about some of the bad assumptions we've made, lies we've bought into, and why we have the most awesome job ever.\n  video_provider: \"youtube\"\n  video_id: \"3OHNYIg6N5Y\"\n\n- id: \"corey-ehmke-ruby-midwest-2013\"\n  title: \"Lightweight Business Intelligence\"\n  raw_title: \"Ruby Midwest 2013 Lightweight Business Intelligence by Corey Ehmke\"\n  speakers:\n    - Corey Ehmke\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-27\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Long the provence of specialists in the hermetic world of enterprise software development, business intelligence (BI) is increasingly important to smaller, more agile companies and startups who need access to near-real-time information to make critical business decisions. With its support for aggregation and reduction of massive amounts of data and its flexible schemas, MongoDB is a great choice for creating lightweight, denormalized data stores optimized for BI, with the added bonus of peaceful co-existence with transactional data stores. In this talk I will explore how Trunk Club captures and analyzes customer information, monitors user behaviour, feeds machine-learning algorithms for decision support, and delivers value to business stakeholders through simple querying and reporting interfaces.\n  video_provider: \"youtube\"\n  video_id: \"c2TOY4lufIM\"\n\n- id: \"jessica-kerr-ruby-midwest-2013\"\n  title: \"Functional Principles for OO Development\"\n  raw_title: \"Ruby Midwest 2013 Functional Principles for OO Development by Jessica Kerr\"\n  speakers:\n    - Jessica Kerr\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-27\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    So you consider yourself an Object Oriented developer? Ruby isn't limited to an OO style! See what functional programming can do for us, without learning any new language. These six principles of functional style apply in OO code. Some of these principles you already use; some express patterns old and new; all give us different ways of thinking about problems. Developers without expertise in functional programming will find new techniques for thinking and coding in Ruby.\n  video_provider: \"youtube\"\n  video_id: \"tq5SQ4W3gRI\"\n\n- id: \"zachary-briggs-ruby-midwest-2013\"\n  title: \"Nobody Will Train You But You\"\n  raw_title: \"Ruby Midwest 2013 Nobody Will Train You But You by Zachary Briggs\"\n  speakers:\n    - Zachary Briggs\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-27\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Why do we all know a developer who has been pounding out unmaintainable code for a decade or more? Why do people \"\"believe in TDD but I don't have time to write tests during crunch?\"\" How is it that we have an entire industry based around rescuing teams from acutely awful Rails apps? It's because on the job experience is a poor teacher, plateauing as soon as the developer is able to ship code that meets requirements. Schools teach Computer Science which is only tangentially related to being a developer and most kata's are approached incorrectly, giving no value at best, and reinforcing poor practices at worst. On top of all this, our pairs (for the lucky ones who pair program) probably have not shown us anything new in months. This presentation will give specific, concrete steps on how to slowly and steadily improve our game through practice and hard work. I'll identify what skill Rails developers should be focusing on and walk the audience through how to target and eliminate these weaknesses so that nothing but white hot joy streams out of our fingers and into our apps. There's no magic here, no secrets, and no hacks; just you and me working our butts off until we suck a little less.\n  video_provider: \"youtube\"\n  video_id: \"N9NxRu21kiI\"\n\n- id: \"chris-mccord-ruby-midwest-2013\"\n  title: \"Lightning Talks\"\n  raw_title: \"Ruby Midwest 2013 Lightning Talks\"\n  speakers:\n    - Chris McCord\n    - Michael\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-27\"\n  announced_at: \"2012-12-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"bsm2DSUXZQs\"\n\n- id: \"matthias-gnther-ruby-midwest-2013\"\n  title: \"More time for Open Source work with the help of the Pomodoro Technique\"\n  raw_title: \"Ruby Midwest 2013 More time for Open Source work with the help of the Pomodoro Technique\"\n  speakers:\n    - Matthias Günther\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-27\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Title: More time for Open Source work with the help of the Pomodoro Technique\n    Presented by: Matthias Günther\n\n    You know the constraints: Day job, time for your family, urge to hack, visiting the local user group, and start a new project about the latest rocket science technology you need to learn. There is never enough time for all this stuff at once. This talk will present the time management method, called Pomodoro. Learn how to work time-boxed, get rid of distractions, focus on a single task for 25 minutes, and relax for couple of minutes to free your mind. We all love Open Source work and Pomodoro will help you to hack on your beloved babies in a time-boxed way to get more done in less time.\n  video_provider: \"youtube\"\n  video_id: \"249osnsUXtE\"\n\n- id: \"jaime-andrs-dvila-ruby-midwest-2013\"\n  title: \"DCI: semiotics applied to software\"\n  raw_title: \"Ruby Midwest 2013 DCI: semiotics applied to software by Jaime Andrés Dávila\"\n  speakers:\n    - Jaime Andrés Dávila\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-27\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Formally, semiotics is the study of signs: how do they relate?, how do they structure meaning?, what rules do they follow? All these questions are important to understand how humans communicate and how we interpret the world around us, so it's no wonder that semiotics are related to the process of building software. We, as developers, create software that communicates not only to the end user, but also to other systems and even to other developers. A clear separation of each part of the \"\"final message\"\" is important to keep the code maintainable and more important, to control the meaning of our app. DCI is an elegant way to keep that separation clear, we can manage the \"rules\" (context), the \"symbols\" (data) and the \"meaning\" (information) of the message. During this talk I'll explore some concepts of semiotics which are important for DCI and how DCI uses those concepts to communicate. Part of the talk includes an overview of an app I'm building using grape, which allowed me to build from scratch an architecture based on DCI an experiment ideas and concepts I'd like to share with you.\n  video_provider: \"youtube\"\n  video_id: \"g6glgB8QpSY\"\n\n- id: \"zee-spencer-ruby-midwest-2013\"\n  title: \"Computer, Program Theyself!\"\n  raw_title: \"Ruby Midwest 2013 Computer, Program Theyself! by Zee Spencer\"\n  speakers:\n    - Zee Spencer\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-26\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Robots. Unthinking. Unfeeling. Cold. Incapable of surprising us. Or are they? In this demonstration I'll be walking through how I use ruby to teach computers to surprise me with answers to problems I don't know how to solve. It draws heavily on testing to model behavior, stats, and rubies power to create domain specific languages; so hang on to your hats!\n  video_provider: \"youtube\"\n  video_id: \"Uw80R8TRW6U\"\n\n- id: \"michael-feathers-ruby-midwest-2013\"\n  title: \"Keynote by Michael Feathers\"\n  raw_title: \"Ruby Midwest 2013 Keynote by Michael Feathers\"\n  speakers:\n    - Michael Feathers\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-26\"\n  announced_at: \"2012-12-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"j3UJfOZdAV8\"\n\n- id: \"pj-hagerty-ruby-midwest-2013\"\n  title: \"Ruby Groups: Act Locally - Think Globally\"\n  raw_title: \"Ruby Midwest 2013 Ruby Groups: Act Locally - Think Globally by PJ Hagerty\"\n  speakers:\n    - PJ Hagerty\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-26\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    There are thousands of local Ruby groups worldwide. Sadly, many suffer along, become stagnant, some even die off. How can you make your local Ruby Group better and in so doing, improve the global Ruby Community? This talk focuses on the human side of getting a group together and making it successful so the members, as a group can contribute to the larger community. It is a universally useful guide to improving all parts of the ruby community, starting on a local level.\n  video_provider: \"youtube\"\n  video_id: \"O8IzXwNDtqA\"\n\n- id: \"david-kerber-ruby-midwest-2013\"\n  title: \"Ready To Code: Automate Your Development Environment\"\n  raw_title: \"Ruby Midwest 2013   Ready To Code: Automate Your Development Environment by David Kerber\"\n  speakers:\n    - David Kerber\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-26\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Remember when you first get started on an existing project, and you have to get your development environment setup?\n    \"You need Postgres and Ruby\", so you get that installed.\n    \"Oh wait, we can't run 1.9.3, you need 1.9.2\", so you change Ruby.\n    \"bundle is failing? Oh yeah, that gems needs some native packages, better google it\".\n    \"Why isn't that feature working? Oh yeah, I just remembered you need to install wkhtmltopdf for that to work\"; it's still not working, \"oh, you didn't install that with the package manager did you, that one never works, you have to download a binary and install it manually.\"\n    In an environment with more than one project it's even worse, since you could be moving between different projects each with their own unique requirements. Vagrant allows you to configure what you need installed on your development machine and isolate it into a headless VM to use for development. In our consulting shop, a new developer can usually be up and running in about 15 minutes with a complete development environment and ready to start coding. And if you really manage to mess something up badly, you can just destroy the whole thing and rebuild it with a couple commands.\n  video_provider: \"youtube\"\n  video_id: \"jJ6YKkBT2rY\"\n\n- id: \"bryan-helmkamp-ruby-midwest-2013\"\n  title: \"Rails Application Security in Practice\"\n  raw_title: \"Ruby Midwest 2013 Rails Application Security in Practice by Bryan Helmkamp\"\n  speakers:\n    - Bryan Helmkamp\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-26\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Out of the box, Rails does its best to help you secure your app. Unfortunately, without consistent application of secure development principles, practices and tools, it's just a matter of time before vulnerabilities creep in. The best time to start locking down your app now, not after your first close call (or worse). We'll walk through exactly what you need to reduce the risk of a security breach to your business, beyond the Rails defaults.\n  video_provider: \"youtube\"\n  video_id: \"TGbeIxf5RnI\"\n\n- id: \"ashe-dryden-ruby-midwest-2013\"\n  title: \"Must Have 10+ Years People Experience\"\n  raw_title: \"Ruby Midwest 2013 Must Have 10+ Years People Experience by Ashe Dryden\"\n  speakers:\n    - Ashe Dryden\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-26\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Solving a technical problem is relatively easy: there tends to be precedence, easily accessible data, black and white results, and a long list of knowledgeable developers to lean on. People problems are stickier; there are far more variables, no tests you can write, no debugger to use. In this talk, I'll focus on our biggest issues as developers and community members. We'll examine what's broken, what works, and some useful people katas.\n  video_provider: \"youtube\"\n  video_id: \"zgyi2Zrg2-U\"\n\n- id: \"evan-light-ruby-midwest-2013\"\n  title: \"Frustration Driven Development\"\n  raw_title: \"Ruby Midwest 2013 Frustration Driven Development by Evan Light\"\n  speakers:\n    - Evan Light\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-26\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Everyone draws inspiration and motivation from different sources. For most, it's often frustration. We make life decisions, define new features, or refactor code when we get too annoyed by current circumstances. This is where [the speaker] admits they has a low tolerance for frustration. Having been frustrated a great deal during his career, [the speaker] will discuss several anti-patterns that they have seen in code and how to use the Dark Side of the Force (frustration, anger, and rage) to escape from them.\n  video_provider: \"youtube\"\n  video_id: \"1BYZCC5khjE\"\n\n- id: \"matt-sears-ruby-midwest-2013\"\n  title: \"Make Testing Fun with Test Reporters\"\n  raw_title: \"Ruby Midwest 2013 Make Testing Fun with Test Reporters by Matt Sears\"\n  speakers:\n    - Matt Sears\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-26\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Slow tests got you down? As Ruby developers, we watch a lot of tests run in a given day. So why not make it more fun? In this talk, I'll take a light-hearted approach to introducing you to an array of test reporters including MiniTest's Pride, Fuubar, and my very own Nyan Cat Formatter. In addition, I will show how easy it is to make your very own test reporter for both Rspec or Minitest so you can have a more enjoyable testing experience.\n  video_provider: \"youtube\"\n  video_id: \"0UKasLJJ3o4\"\n\n- id: \"kerri-miller-ruby-midwest-2013\"\n  title: \"Failure for Fun and Profit!\"\n  raw_title: \"Ruby Midwest 2013 Failure for Fun and Profit! by Kerri Miller\"\n  speakers:\n    - Kerri Miller\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-26\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Do you actually know how deliberately acquire, sharpen, and retain a technical skill? In this talk, I'll discuss common strategies to enable you to be more focused, creative, and productive while learning, by using play, exploration, and ultimately failure. You'll leave knowing several \"Experiential Learning\" patterns and techniques that can help you turn failure into success. When was the last time you failed in a spectacular fashion? Was it really so bad? If you want to succeed, you first need to take a little time to fail.\n  video_provider: \"youtube\"\n  video_id: \"MVwdDtQFVro\"\n\n- id: \"steve-klabnik-ruby-midwest-2013\"\n  title: \"OOP and Philosophy\"\n  raw_title: \"Ruby Midwest 2013 OOP and Philosophy by Steve Klabnik\"\n  speakers:\n    - Steve Klabnik\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-26\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Actions are driven by ideas, and ideas are driven by philosophy. For a deep understanding of our actions, we have to go the whole way back to the philosophy that motivates them. So what's the philosophical basis for Object Oriented Programming? In this talk, [the speaker] will discuss Plato's theory of forms, its relationship to Object Oriented Programming, and its current relevance (or irrelevance) to modern philosophy.\n  video_provider: \"youtube\"\n  video_id: \"YfKAScYkGlk\"\n\n- id: \"bryan-thompson-ruby-midwest-2013\"\n  title: \"SOA Safari in the Amazon\"\n  raw_title: \"Ruby Midwest 2013 SOA Safari in the Amazon by Bryan Thompson\"\n  speakers:\n    - Bryan Thompson\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-25\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Amazon's toolbox of services can be pretty intimidating at first, and there are many possible solutions for scalability and redundancy. We've combined those tools with the power of Ruby to build a decoupled highly-testable platform that is a developers dream. We're going to share what we learned on this journey.\n  video_provider: \"youtube\"\n  video_id: \"n2o1vw0vzPI\"\n\n- id: \"david-kerber-ruby-midwest-2013-ready-to-code-automate-your-de\"\n  title: \"Ready To Code: Automate Your Development Environment\"\n  raw_title: \"Ruby Midwest 2013   Ready To Code: Automate Your Development Environment by David Kerber\"\n  speakers:\n    - David Kerber\n  date: \"2013-04-05\"\n  event_name: \"Ruby Midwest 2013\"\n  published_at: \"2013-04-25\"\n  announced_at: \"2012-12-17\"\n  description: |-\n    Remember when you first get started on an existing project, and you have to get your development environment setup?\n    \"You need Postgres and Ruby\", so you get that installed.\n    \"Oh wait, we can't run 1.9.3, you need 1.9.2\", so you change Ruby.\n    \"bundle is failing? Oh yeah, that gems needs some native packages, better google it\".\n    \"Why isn't that feature working? Oh yeah, I just remembered you need to install wkhtmltopdf for that to work\"; it's still not working, \"oh, you didn't install that with the package manager did you, that one never works, you have to download a binary and install it manually.\"\n    In an environment with more than one project it's even worse, since you could be moving between different projects each with their own unique requirements. Vagrant allows you to configure what you need installed on your development machine and isolate it into a headless VM to use for development. In our consulting shop, a new developer can usually be up and running in about 15 minutes with a complete development environment and ready to start coding. And if you really manage to mess something up badly, you can just destroy the whole thing and rebuild it with a couple commands.\n  video_provider: \"youtube\"\n  video_id: \"PxzYjFPt9KY\"\n"
  },
  {
    "path": "data/ruby-midwest/series.yml",
    "content": "---\nname: \"Ruby Midwest\"\nwebsite: \"\"\ntwitter: \"rubymidwest\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-montevideo/ruby-montevideo/event.yml",
    "content": "---\nid: \"PLtDsh6Hvvmkm6GWqpo9slt6gp__dbGJYa\"\ntitle: \"Ruby Montevideo Meetup\"\nkind: \"meetup\"\nlocation: \"Montevideo, Uruguay\"\ndescription: \"\"\nyear: 2024\nfeatured_background: \"#3967D1\"\nfeatured_color: \"#FFFFFF\"\nbanner_background: |-\n  linear-gradient(\n    to bottom,\n    #2E2E2E 1%,\n    #F6EEEC 1%, #F6EEEC 19%,\n    #2E2E2E 19%, #2E2E2E 20%,\n    #3967D1 20%\n  )\nwebsite: \"https://ruby.uy\"\ncoordinates:\n  latitude: -34.9055016\n  longitude: -56.1851147\n"
  },
  {
    "path": "data/ruby-montevideo/ruby-montevideo/videos.yml",
    "content": "---\n- id: \"ruby-montevideo-meetup-march-2024\"\n  title: \"Ruby Montevideo Meetup March 2024\"\n  event_name: \"Ruby Montevideo Meetup March 2024\"\n  date: \"2024-03-06\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-march-2024\"\n  description: \"\"\n  talks:\n    - title: \"Desmitificando Desafíos Más Allá de la Ingeniería\"\n      event_name: \"Ruby Montevideo Meetup March 2024\"\n      date: \"2024-03-06\"\n      published_at: \"2024-12-03\"\n      speakers:\n        - Darío Macchi\n      id: \"dario-macchi-ruby-montevideo-meetup-march-2024\"\n      video_id: \"xj1HsT2TCWU\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n    - title: \"Rails Microservices at PeerStreet: Show Me the Code\"\n      event_name: \"Ruby Montevideo Meetup March 2024\"\n      date: \"2024-03-06\"\n      published_at: \"2024-12-03\"\n      speakers:\n        - Leti Esperón\n      id: \"leti-esperon-ruby-montevideo-meetup-march-2024\"\n      video_id: \"bt_t_C_96UU\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n- id: \"ruby-montevideo-meetup-april-2024\"\n  title: \"Ruby Montevideo Meetup April 2024\"\n  event_name: \"Ruby Montevideo Meetup April 2024\"\n  date: \"2024-04-01\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-april-2024\"\n  description: \"\"\n  talks:\n    - title: \"Make Deploys Easy with Kamal\"\n      event_name: \"Ruby Montevideo Meetup April 2024\"\n      date: \"2024-04-01\"\n      published_at: \"2024-12-03\"\n      speakers:\n        - Santiago Rodriguez\n      id: \"santiago-rodriguez-ruby-montevideo-meetup-april-2024\"\n      video_id: \"TR68sEoOGdo\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n- id: \"ruby-montevideo-meetup-may-2024\"\n  title: \"Ruby Montevideo Meetup May 2024\"\n  event_name: \"Ruby Montevideo Meetup May 2024\"\n  date: \"2024-05-09\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-may-2024\"\n  description: \"\"\n  talks:\n    - title: \"View Components The Right Way: Creating Reusable Component Libraries\"\n      event_name: \"Ruby Montevideo Meetup May 2024\"\n      date: \"2024-05-09\"\n      published_at: \"2024-05-23\"\n      speakers:\n        - Jorge Leites\n      id: \"jorge-leites-ruby-montevideo-meetup-may-2024\"\n      video_id: \"P5qCe_lSlWk\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n    - title: \"Demystifying Auth\"\n      event_name: \"Ruby Montevideo Meetup May 2024\"\n      date: \"2024-05-09\"\n      published_at: \"2024-05-23\"\n      speakers:\n        - Maicol Bentancor\n      id: \"maicol-bentancor-ruby-montevideo-meetup-may-2024\"\n      video_id: \"xApchFT9R28\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n- id: \"ruby-montevideo-meetup-june-2024\"\n  title: \"Ruby Montevideo Meetup June 2024\"\n  event_name: \"Ruby Montevideo Meetup June 2024\"\n  date: \"2024-06-06\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-june-2024\"\n  description: \"\"\n  talks:\n    - title: \"Building real time features with Action Cable\"\n      event_name: \"Ruby Montevideo Meetup June 2024\"\n      date: \"2024-06-06\"\n      published_at: \"2024-06-11\"\n      speakers:\n        - Pablo Duran\n      id: \"pablo-duran-ruby-montevideo-meetup-june-2024\"\n      video_id: \"ewxw3KOsfFk\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n    - title: \"Clasificando residuos con el Garbage Collector de Ruby\"\n      event_name: \"Ruby Montevideo Meetup June 2024\"\n      date: \"2024-06-06\"\n      published_at: \"2024-06-11\"\n      speakers:\n        - Vicky Madrid\n      id: \"vicky-madrid-ruby-montevideo-meetup-june-2024\"\n      video_id: \"dTefRNHojVE\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n- id: \"ruby-montevideo-meetup-august-2024\"\n  title: \"Ruby Montevideo Meetup August 2024\"\n  event_name: \"Ruby Montevideo Meetup August 2024\"\n  date: \"2024-08-13\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-august-2024\"\n  description: \"\"\n  talks:\n    - title: \"Escribiendo tests rápidos de la mano de TestProf\"\n      event_name: \"Ruby Montevideo Meetup August 2024\"\n      date: \"2024-08-13\"\n      published_at: \"2024-12-03\"\n      speakers:\n        - Daniel Susviela\n      id: \"daniel-susviela-ruby-montevideo-meetup-august-2024\"\n      video_id: \"ylH4dMgiyyI\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n    - title: \"Lazuli: Un plugin de desarrollo interactivo con Ruby\"\n      event_name: \"Ruby Montevideo Meetup August 2024\"\n      date: \"2024-08-13\"\n      published_at: \"2024-12-03\"\n      speakers:\n        - Mauricio Zsabo\n      id: \"mauricio-zsabo-ruby-montevideo-meetup-august-2024\"\n      video_id: \"HzEbGvwIWLs\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n- id: \"ruby-montevideo-meetup-september-2024\"\n  title: \"Ruby Montevideo Meetup September 2024\"\n  event_name: \"Ruby Montevideo Meetup September 2024\"\n  date: \"2024-09-11\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-september-2024\"\n  description: \"\"\n  talks:\n    - title: \"Rescuing a Software Project: My Experience\"\n      event_name: \"Ruby Montevideo Meetup September 2024\"\n      date: \"2024-09-11\"\n      published_at: \"2024-11-29\"\n      speakers:\n        - Agus Fornio\n      id: \"agus-fornio-ruby-montevideo-meetup-september-2024\"\n      video_id: \"w4BYE1bPJi8\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n    - title: \"Speed up your CI for Rails applications\"\n      event_name: \"Ruby Montevideo Meetup September 2024\"\n      date: \"2024-09-11\"\n      published_at: \"2024-11-29\"\n      speakers:\n        - Laura Peralta\n        - Juan Pascual\n      id: \"laura-peralta-and-juan-pascual-ruby-montevideo-meetup-september-2024\"\n      video_id: \"_g3uBxpUz08\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n- id: \"ruby-montevideo-meetup-october-2024\"\n  title: \"Ruby Montevideo Meetup October 2024\"\n  event_name: \"Ruby Montevideo Meetup October 2024\"\n  date: \"2024-10-09\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-october-2024\"\n  description: \"\"\n  talks:\n    - title: \"Ran out of eggs? Fix it with Hotwire Native\"\n      event_name: \"Ruby Montevideo Meetup October 2024\"\n      date: \"2024-10-09\"\n      published_at: \"2024-11-29\"\n      speakers:\n        - Agustin Peluffo\n        - Facundo Busto\n      id: \"agustin-peluffo-and-facundo-busto-ruby-montevideo-meetup-october-2024\"\n      video_id: \"dwoOWi-XlVE\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n    - title: \"MultiMultiTenancy\"\n      event_name: \"Ruby Montevideo Meetup October 2024\"\n      date: \"2024-10-09\"\n      published_at: \"2024-11-29\"\n      speakers:\n        - Santiago Behak\n      id: \"santiago-behak-ruby-montevideo-meetup-october-2024\"\n      video_id: \"bota6HTyKoo\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n- id: \"ruby-montevideo-meetup-november-2024\"\n  title: \"Ruby Montevideo Meetup November 2024\"\n  event_name: \"Ruby Montevideo Meetup November 2024\"\n  date: \"2024-11-12\"\n  published_at: \"2024-11-29\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-november-2024\"\n  description: \"\"\n  talks:\n    - title: \"ActiveStorage + Cloudfront\"\n      event_name: \"Ruby Montevideo Meetup November 2024\"\n      date: \"2024-11-12\"\n      published_at: \"2024-11-29\"\n      speakers:\n        - Matías Lorenzo\n      id: \"matias-lorenzo-ruby-montevideo-meetup-november-2024\"\n      video_id: \"FrgVA9FwUP0\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n    - title: \"Navigating Polymorphism\"\n      event_name: \"Ruby Montevideo Meetup November 2024\"\n      date: \"2024-11-12\"\n      published_at: \"2024-11-29\"\n      speakers:\n        - Nicolas Erlichman\n      id: \"nicolas-erlichman-ruby-montevideo-meetup-november-2024\"\n      video_id: \"m6_4kxiSyaM\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n- id: \"ruby-montevideo-meetup-march-2025\"\n  title: \"Ruby Montevideo Meetup March 2025\"\n  event_name: \"Ruby Montevideo Meetup March 2025\"\n  date: \"2025-03-25\"\n  announced_at: \"2025-03-10T21:33:34.000Z\"\n  published_at: \"2025-05-09\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-march-2025\"\n  description: |-\n    https://ruby.uy/meetups/2025-03-25/howdy\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/3/7/8/7/highres_526694215.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/3/7/8/7/highres_526694215.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/3/7/8/7/highres_526694215.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/3/7/8/7/highres_526694215.webp\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/3/7/8/7/highres_526694215.webp\"\n  talks:\n    - title: \"Pursuing the Fix: A Rails Bug Story\"\n      event_name: \"Ruby Montevideo Meetup March 2025\"\n      date: \"2025-03-25\"\n      announced_at: \"2025-03-10T21:33:34.000Z\"\n      published_at: \"2025-05-09\"\n      speakers:\n        - Nicolás Buero\n      id: \"nicolas-buero-ruby-montevideo-meetup-march-2025\"\n      video_id: \"YbvruESauPI\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n    - title: \"Building Beautiful UIs with Ruby: A Rails-native Approach\"\n      event_name: \"Ruby Montevideo Meetup March 2025\"\n      date: \"2025-03-25\"\n      announced_at: \"2025-03-10T21:33:34.000Z\"\n      speakers:\n        - Seth Horsley\n      id: \"seth-horsley-ruby-montevideo-meetup-march-2025\"\n      video_id: \"seth-horsley-ruby-montevideo-meetup-march-2025\"\n      video_provider: \"scheduled\"\n      description: \"\"\n      language: \"english\"\n\n    - title: \"Scaling RubyVideo.dev: The mission to index all Ruby conferences\"\n      event_name: \"Ruby Montevideo Meetup March 2025\"\n      date: \"2025-03-25\"\n      announced_at: \"2025-03-10T21:33:34.000Z\"\n      published_at: \"2025-05-09\"\n      slides_url: \"https://speakerdeck.com/marcoroth/scaling-rubyvideo-dot-dev-the-mission-to-index-all-ruby-conferences-at-ruby-montevideo-march-2025\"\n      speakers:\n        - Marco Roth\n      id: \"marco-roth-ruby-montevideo-meetup-march-2025\"\n      video_id: \"ZD3oulz4-3g\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"english\"\n\n- id: \"ruby-montevideo-meetup-april-2025\"\n  title: \"Ruby Montevideo Meetup April 2025\"\n  event_name: \"Ruby Montevideo Meetup April 2025\"\n  date: \"2025-04-24\"\n  published_at: \"2025-05-09\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-april-2025\"\n  description: |-\n    https://ruby.uy/meetups/2025-04-24/qubika\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/8/0/7/6/highres_527372886.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/8/0/7/6/highres_527372886.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/8/0/7/6/highres_527372886.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/8/0/7/6/highres_527372886.webp\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/8/0/7/6/highres_527372886.webp\"\n  talks:\n    - title: \"xi-livecode - música en ruby\"\n      event_name: \"Ruby Montevideo Meetup April 2025\"\n      date: \"2025-04-24\"\n      published_at: \"2025-05-09\"\n      speakers:\n        - Juan Francisco Raposeiras\n      id: \"juan-francisco-raposeiras-ruby-montevideo-meetup-april-2025\"\n      video_id: \"lqkV4qzTTos\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n    - title: \"Modularizando Con Packwerk\"\n      event_name: \"Ruby Montevideo Meetup April 2025\"\n      date: \"2025-04-24\"\n      published_at: \"2025-05-09\"\n      speakers:\n        - Diego Algorta\n      id: \"diego-algorta-ruby-montevideo-meetup-april-2025\"\n      video_id: \"TAMMnmuXhE8\"\n      video_provider: \"youtube\"\n      description: \"\"\n      language: \"spanish\"\n\n- id: \"ruby-montevideo-meetup-may-2025\"\n  title: \"Ruby Montevideo Meetup May 2025\"\n  event_name: \"Ruby Montevideo Meetup May 2025\"\n  date: \"2025-05-21\"\n  video_provider: \"children\"\n  video_id: \"ruby-montevideo-meetup-may-2025\"\n  description: |-\n    🗓️ Miercoles 21 de Mayo - 19hs\n    📍 Joaquin de Salterain 1081 - Neocoast\n\n    En esta oportunidad vamos a contar con 2 charlas de ~30 minutos cada uno.\n    No importa si son expertos en Ruby o nunca escribieron una línea de código en Ruby, la idea es generar un ambiente descontracturado para pasar un buen rato y compartir experiencias trabajando con Ruby 💎💎.\n    Interesados en dar charlas: contamos con una spreadsheet pública donde cada uno puede ir y anotarse. La idea es que esto sea 100% transparente y todos puedan participar. Pueden ser charlas de todos los niveles, siempre y cuando sea de Ruby, Rails, o algo relacionado\n\n    https://www.meetup.com/ruby-montevideo/events/307735416\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/6/6/a/2/highres_527846274.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/6/6/a/2/highres_527846274.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/6/6/a/2/highres_527846274.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/6/6/a/2/highres_527846274.webp\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/6/6/a/2/highres_527846274.webp\"\n  talks:\n    - title: \"OpenAI Usage & Function Calling\"\n      event_name: \"Ruby Montevideo Meetup May 2025\"\n      date: \"2025-05-21\"\n      speakers:\n        - Franco Olivera\n      id: \"franco-olivera-ruby-montevideo-meetup-may-2025\"\n      video_id: \"franco-olivera-ruby-montevideo-meetup-may-2025\"\n      video_provider: \"scheduled\"\n      description: \"\"\n      language: \"spanish\"\n\n    - title: \"Building a chatbot the Rails Way with RubyLLM\"\n      event_name: \"Ruby Montevideo Meetup May 2025\"\n      date: \"2025-05-21\"\n      speakers:\n        - Agustin Peluffo\n      id: \"agustin-peluffo-ruby-montevideo-meetup-may-2025\"\n      video_id: \"agustin-peluffo-ruby-montevideo-meetup-may-2025\"\n      video_provider: \"scheduled\"\n      description: \"\"\n      language: \"spanish\"\n"
  },
  {
    "path": "data/ruby-montevideo/series.yml",
    "content": "---\nname: \"Ruby Montevideo\"\nwebsite: \"https://www.meetup.com/ruby-montevideo\"\ntwitter: \"rubymontevideo\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"UY\"\nyoutube_channel_name: \"ruby_uy\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCNTm-kFfkP_ArKDcXoQpxiQ\"\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2011/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyak7l7QRTq8GHUc6aDCyIVn\"\ntitle: \"Ruby on Ales 2011\"\nkind: \"conference\"\nlocation: \"Bend, OR, United States\"\ndescription: \"\"\npublished_at: \"2011-03-24\"\nstart_date: \"2011-03-24\"\nend_date: \"2011-03-25\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2011\ncoordinates:\n  latitude: 44.0581728\n  longitude: -121.3153096\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2011/videos.yml",
    "content": "---\n# https://web.archive.org/web/20110425113608/http://ruby.onales.com/schedule\n\n## Day 1 - 2011-03-24\n\n# Registration\n\n# Welcome and introductions\n\n- id: \"jim-weirich-ruby-on-ales-2011\"\n  title: \"Securing Your Rails App\"\n  raw_title: \"Ruby on Ales 2011 - Securing Your Rails App by: Jim Weirich, Matt Yoho\"\n  speakers:\n    - Jim Weirich\n    - Matt Yoho\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    \"Then it starts to scan the computer and transmit bits of information every time he clicks the mouse while he's surfing. After a while, [...] we've accumulated a complete mirror image of the content of his hard drive [...]. And then it's time for the hostile takeover.\" -- Lisbeth Salander in Stieg Larsson's \"The Girl with the Dragon Tattoo\"\n\n    Hacker dramas like the Stieg Larrson book make for good fiction, but we know that real life rarely matches drama. And with all the security features that Rails 3 has added, surely it is difficult to hack a typical Rails web site. Right? Wrong! Without deliberate attention to the details of security, it almost certain that your site has flaws that a knowledgeable hacker can exploit. This talk will cover the ins and outs of web security and help you build a site that is protected from the real Lisbeth Salanders of the world.\n\n  video_provider: \"youtube\"\n  video_id: \"Z-JZTAlDCh0\"\n\n- id: \"erik-michaels-ober-ruby-on-ales-2011\"\n  title: \"GUI Programming with Mac Ruby\"\n  raw_title: \"Ruby on Ales 2011 - Gui Programming with Mac Ruby by: Erik Michaels-Ober\"\n  speakers:\n    - Erik Michaels-Ober\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Ruby is a great language for building web applications and manipulating text but it's also the best language to interact with your favorite Mac apps or even build a new app to sell on the Mac App Store. I will demonstrate how to build a simple GUI app in MacRuby and discuss the benefits and drawbacks of doing so versus using RubyCocoa, Objective-C, Objective-J, or Java. I will also discuss the roadmap for MacRuby 1.0, scheduled to be released later this year.\n\n  video_provider: \"youtube\"\n  video_id: \"VSpZIkmywQM\"\n\n- id: \"richard-crowley-ruby-on-ales-2011\"\n  title: \"Why is Configuration Management Software Written in Ruby?\"\n  raw_title: \"Ruby on Ales 2011 -  Why is configuration management software written in Ruby?  by: Richard Crowley\"\n  speakers:\n    - Richard Crowley\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Puppet and Chef, both of the modern examples of configuration management and systems integration software are written in Ruby. Add Capistrano, Rake, and MCollective to the list and this starts to seem like much more than coincidence. We'll examine the history and implementation of each of these packages to find patterns that make Ruby an awesome tool for systems administration in 2011. We'll pay special attention to UNIX idioms as they're expressed in Ruby, API design and code organization, standard- and third-party libraries, and the language grammar itself. We'll learn lessons on idempotence, failure modes, and logging along the way that apply to any type of development and we'll discuss Ruby's future at the top of the operator's toolbox.\n\n  video_provider: \"youtube\"\n  video_id: \"QNc5dJ3AciA\"\n\n- id: \"kyle-neath-ruby-on-ales-2011\"\n  title: \"Design Hacks For The Pragmatic Minded\"\n  raw_title: \"Ruby on Ales 2011 - Design hacks for the pragmatic minded by: Kyle Neath\"\n  speakers:\n    - Kyle Neath\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    A lot of developers think they either can't or don't need to design. But that's just a myth â€” everyone can benefit from a few simple design concepts. Learn some simple design hacks you can apply to your documentation, presentations and products to make them just a little bit prettier.\n\n  video_provider: \"youtube\"\n  video_id: \"t785N2yWd-c\"\n\n# Lunch\n\n- id: \"avdi-grimm-ruby-on-ales-2011\"\n  title: \"Exceptional Ruby\"\n  raw_title: \"Ruby on Ales 2011 - Exceptional Ruby by: Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    You know how to raise and rescue exceptions. But do you know how they work, and how how to structure a robust error handling strategy for your app? Starting out with an in-depth walk-through of Ruby's Ruby's rich failure handling mechanisms -- including some features you may not have known about -- we'll move on to present strategies for implementing a cohesive error-handling policy for your application, based on real-world experience.\n\n  video_provider: \"youtube\"\n  video_id: \"pw76_eM0ZoI\"\n\n- id: \"rein-henrichs-ruby-on-ales-2011\"\n  title: \"You Got Ruby In My PHP! (You Got PHP In My Ruby!)\"\n  raw_title: \"Ruby on Ales 2011 - You Got Ruby In My PHP! (You Got PHP In My Ruby!)  by: Rein Henrichs\"\n  speakers:\n    - Rein Henrichs\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zI7T6BK2GQE\"\n\n- id: \"bradley-grzesiak-ruby-on-ales-2011\"\n  title: \"The Ruby Environment\"\n  raw_title: \"Ruby on Ales 2011 - The Ruby Environment by: Bradley Grzesiak\"\n  speakers:\n    - Bradley Grzesiak\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    You _could_ work in a business park. You _could_ lust after an office with a window. You _could_ have a monthly company \"meeting\" at that bar you have to drive to. Or you could change your environment. I helped create Bendyworks with a firm commitment to the importance of environment. We work downtown, above a bar, across the street from a microbrewery. We all pair program in one big room with a rotating music selection. We have book club and daily standups and weekly game nights (with beverages from aforementioned microbrewery). Learn from me - a beer connoisseur, former ski racer, and ruby business owner - about how to change your Ruby Environment.\n\n  video_provider: \"youtube\"\n  video_id: \"Lihsrw4oqUY\"\n\n# Break\n\n- id: \"john-britton-ruby-on-ales-2011\"\n  title: \"Quick and Dirty Apps with Sinatra, DataMapper, RestClient & Heroku\"\n  raw_title: \"Ruby on Ales 2011 - Quick and Dirty Apps with Sinatra, DataMapper, RestClient & Heroku\"\n  speakers:\n    - John Britton\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    by: John Britton\n\n  video_provider: \"youtube\"\n  video_id: \"MkMnUeUTkfk\"\n\n# TODO: missing talk: Lightning Talks\n\n## Day 2 - 2011-03-25\n\n# Registration\n\n# Announcements\n\n- id: \"ian-hunter-ruby-on-ales-2011\"\n  title: \"One Ruby App to Rule Them All\"\n  raw_title: \"Ruby on Ales 2011 - One Ruby App to Rule Them All by: Ian Hunter\"\n  speakers:\n    - Ian Hunter\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Single Project, Multi Purpose Enterprise Applications come in multiple flavors these days: Rails, Sinatra, Grape, ZMQ.\n\n    Let's explore a multi-site mulit-purpose single project architecture which serves all aspects of an enterprise design, heavily seated in RACK. Special attention to Rails, Sinatra, Grape, Rack and ZMQ/EventMachine/ZMQMachine/DripDrop.\n\n  video_provider: \"youtube\"\n  video_id: \"XjoB_xBoRxY\"\n\n- id: \"rick-olson-ruby-on-ales-2011\"\n  title: \"Stratocaster: Redis Event Timeline\"\n  raw_title: \"Ruby on Ales 2011 - Stratocaster: Redis Event Timeline by: Rick Olson\"\n  speakers:\n    - Rick Olson\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Stratocaster is an internal GitHub Ruby project written to replace the organically grown GitHub Event timeline. This is a tale of an overgrown MySQL table being replaced by a more specific Redis setup. We'll see what new possibilities that Redis is able to provide. Also, we'll go over how Mustache was able to replace Erb for event rendering.\n\n  video_provider: \"youtube\"\n  video_id: \"tgQu-cvqYvo\"\n\n- id: \"john-crepezzi-ruby-on-ales-2011\"\n  title: \"Splitting Your App\"\n  raw_title: \"Ruby on Ales 2011 - Splitting Your App by: John Crepezzi\"\n  speakers:\n    - John Crepezzi\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    This talk is about a technique for splitting your web applications in half, shifting the model layer into a very clean API running on Sinatra. Its much easier than you think - and with this architecture, you'll experience a great performance boost, and have a useful public facing API.\n\n  video_provider: \"youtube\"\n  video_id: \"IpqWXiT0Hwk\"\n\n# TODO: mising talk: Jesse Proudman - Demystifying Auto Scale: An API Mashup\n\n- id: \"chris-powers-ruby-on-ales-2011\"\n  title: \"Javascript TDD for Rubyists\"\n  raw_title: \"Ruby on Ales 2011 - Javascript TDD for Rubyists by: Chris Powers\"\n  speakers:\n    - Chris Powers\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    Most Rubyists are becoming comfortable with using TDD for their Ruby code using RSpec, yet have never written a single test for their JavaScript. This talk will introduce Jasmine as an easy to learn, easy to use JavaScript TDD framework to help you start writing tests now. Using RSpec as a point of comparison I present Jasmine's features and pitfalls, and demonstrate how it can revolutionize the way you think about JavaScript.\n\n  video_provider: \"youtube\"\n  video_id: \"d_YImOz9ndA\"\n\n# TODO: missing talk: BJ Clark - Agile Homebrewing\n\n# TODO: missing talk: Grant Goodale - Building Real-time systems with Ruby and MongoDB\n\n# Break\n\n# TODO: missing talk: Jim Remsik & Robert Pitts - The Uncanny Valley of Software Development\n\n# Outro\n\n## Not In Schedule\n\n- id: \"aaron-patterson-ruby-on-ales-2011\"\n  title: \"Ruby Hero Tenderlove!\"\n  raw_title: \"Ruby on Ales 2011 - Ruby Hero Tenderlove! by: Aaron Patterson, Jim Weirich, Ron Evans, Josh Susser\"\n  speakers:\n    - Aaron Patterson\n    - Jim Weirich\n    - Ron Evans\n    - Josh Susser\n  event_name: \"Ruby on Ales 2011\"\n  date: \"2011-04-07\"\n  published_at: \"2015-04-07\"\n  description: |-\n    ( to the tune of the Ultraman theme song:\n      http://www.televisiontunes.com/Ultraman.html )\n\n    Tenderlove, Tenderlove\n    Ruby programming guy\n    Tenderlove, Tenderlove\n    he's as awesome as _why\n\n    Seattle is his home\n    he's a Ruby brigadier\n    ...got a great porn 'stache\n    he'll write XML for cash\n\n    Tenderlove, Tenderlove\n    taught himself Japanese\n    hacks on Rails, makes it fast\n    Arel needs ASTs\n\n    he's a warrior dressed in pink\n    he's the nicest geek in town\n    he's the guy you're dreaming of\n    Ruby Hero Tenderlove!\n\n  video_provider: \"youtube\"\n  video_id: \"nXDKF_zxWkQ\"\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2012/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyb2zm3xjrG4_Ot98HIXObZv\"\ntitle: \"Ruby on Ales 2012\"\nkind: \"conference\"\nlocation: \"Bend, OR, United States\"\ndescription: \"\"\npublished_at: \"2012-03-01\"\nstart_date: \"2012-03-01\"\nend_date: \"2012-03-02\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2012\ncoordinates:\n  latitude: 44.0581728\n  longitude: -121.3153096\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2012/videos.yml",
    "content": "---\n# https://web.archive.org/web/20120531050211/http://ruby.onales.com/schedule\n\n## Day 1 - Thursday - 2012-10-03\n\n# Registration\n\n# Welcome and Introductions\n\n- id: \"mike-moore-ruby-on-ales-2012\"\n  title: \"Outgrowing the Cloud\"\n  raw_title: \"Outgrowing the Cloud by Mike Moore at Ruby on Ales 2012\"\n  speakers:\n    - Mike Moore\n  event_name: \"Ruby on Ales 2012\"\n  date: \"2012-03-01\"\n  published_at: \"2012-10-02\"\n  description: |-\n    The cloud is great. It has lowered the bar for deploying applications. The cloud has encouraged experimentation which has lead to innovation. But what happens when an application's needs grows beyond what simple cloud services can offer?\n\n    In this riveting presentation Mike will discuss systems architecture and strategies for growing apps. He'll share specifics about the challenges Bloomfire met by making key changes to their infrastructure, including how network topology was used to solve critical issues with no changes to the application code.\n\n  video_provider: \"youtube\"\n  video_id: \"z1umCUEc7_E\"\n\n- id: \"ryan-bigg-ruby-on-ales-2012\"\n  title: \"Start Your Engines\"\n  raw_title: \"Start Your Engines by Ryan Bigg at Ruby on Ales 2012\"\n  speakers:\n    - Ryan Bigg\n  event_name: \"Ruby on Ales 2012\"\n  date: \"2012-03-01\"\n  published_at: \"2012-10-02\"\n  description: |-\n    Engines are a new-to-Rails feature that really isn't all that new-to-Rails. The concept has been around for a very long time, it's just only now that they, the Rails Core Team, has Done It Right(tm). In this talk, I go through the lessons learned while developing not just one but two engines.\n\n    I also provide more documentation than Rails has at the moment on engines *in one talk*.\n\n  video_provider: \"youtube\"\n  video_id: \"bHKZfIeAbds\"\n\n- id: \"michael-harper-ruby-on-ales-2012\"\n  title: \"Learning Ruby Made Me A Better Objective C Programmer\"\n  raw_title: \"Learning Ruby Made me a better Objective C Programmer by Michael Harper at Ruby on Ales 2012\"\n  speakers:\n    - Michael Harper\n  event_name: \"Ruby on Ales 2012\"\n  date: \"2012-03-01\"\n  published_at: \"2012-10-02\"\n  description: |-\n    After working with C++ in the early 90s, I ended up on a project on NeXT for two years. The programming language on NeXT was Objective C which seemed like C++'s weird uncle. Java came along and kept me busy for the next several years while Apple simultaneously built Mac OS X atop NeXTStep. In 2006, I heard on the Java Posse podcast about Ruby on Rails. Compared to Java EE, Rails was a dream come true. After spending several years with Rails and simultaneously finding my way into Mac and iOS development, I started to understand why Objective C was much cooler than I had realized.\n\n  video_provider: \"youtube\"\n  video_id: \"0GNilQImFZ8\"\n\n# TODO: missing talk: Gary Bernhard - Deconstructing the Framework\n\n# Lunch\n\n- id: \"timmy-crawford-ruby-on-ales-2012\"\n  title: \"Dreaming of Freshies\"\n  raw_title: \"Dreaming of Freshies by Timmy Crawford at Ruby on Ales 2012\"\n  speakers:\n    - Timmy Crawford\n  event_name: \"Ruby on Ales 2012\"\n  date: \"2012-03-01\"\n  published_at: \"2012-10-02\"\n  description: |-\n    Timmy's personal sweet-spot of hacking is found where multiple passions of mine collide. He is going to cover his happy place of hacking and will include all aspects of the Ruby on Ales Lifestyle: Ruby, Beer, and the pursuit of Snow through them both.\n\n    He will discuss finding a niche where your passions combine, discovering a need for a business/service, and going for it. All the while finding a way to give back to OSS and your community.\n\n  video_provider: \"youtube\"\n  video_id: \"pLO0j9DjGsI\"\n\n- id: \"andr-arko-ruby-on-ales-2012\"\n  title: \"`bundle install` Y U SO SLOW\"\n  raw_title: \"Ruby on Ales 2012 - `bundle install` Y U SO SLOW\"\n  speakers:\n    - André Arko\n    - Terence Lee\n  event_name: \"Ruby on Ales 2012\"\n  date: \"2012-03-01\"\n  published_at: \"2015-07-30\"\n  description: |-\n    `bundle install` Y U SO SLOW by: Andre Arko, Terence Lee\n  video_provider: \"youtube\"\n  video_id: \"K_JzHHIddiw\"\n\n# Break\n\n# TODO: missing talk: Yehuda Katz - Keynote\n\n## Day 2 - Friday - 2012-10-02\n\n# Registration\n\n# Announcements\n\n# TODO: missing talk: Dave Hoover - Redis: Groupon's Swiss Army Datastore\n\n# TODO: missing talk: Evan Light - Frustration Driven Development\n\n# TODO: missing talk: Akira Matsuda - Made in Japan: How we use Rails in the land of Ruby\n\n# TODO: missing talk: Steven Baker - Developing Maintainable Software\n\n# Lunch\n\n# TODO: missing talk: Scott Burton - Client-Side Framework Shootout\n\n# TODO: missing talk: Rein Henrichs - How To Build A Distributed System And Why You Shouldn't\n\n# Lightning Talks\n\n# Break\n\n# TODO: missing talk: Jim Remsik & Robert Pitts - Love in the Time of Polyglots\n\n## Not in schedule\n\n- id: \"yehuda-katz-ruby-on-ales-2012\"\n  title: \"Random Panel\"\n  raw_title: \"Ruby on Ales 2012 - Random Panel\"\n  speakers:\n    - Yehuda Katz\n    - Ben Bleything\n    - Eric Hodel\n    - Coby Randquist\n    - Rein Henrichs\n    - Steven Baker\n    - Renée De Voursney\n  event_name: \"Ruby on Ales 2012\"\n  date: \"2012-03-01\"\n  published_at: \"2015-07-30\"\n  description: |-\n    Random Panel  by: Yehuda Katz, Ben Bleything, Eric Hodel, Coby Randquist, Rein Henrichs, Steven Baker,  Renée De Voursney\n  video_provider: \"youtube\"\n  video_id: \"DqGflocLJGA\"\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2013/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyY0jPJOeBOrF6Pmy0P5Bi81\"\ntitle: \"Ruby on Ales 2013\"\nkind: \"conference\"\nlocation: \"Bend, OR, United States\"\ndescription: \"\"\npublished_at: \"2013-03-07\"\nstart_date: \"2013-03-07\"\nend_date: \"2013-03-08\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2013\ncoordinates:\n  latitude: 44.0581728\n  longitude: -121.3153096\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2013/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: schedule website\n\n# Website: https://web.archive.org/web/20130531054439/http://ruby.onales.com/\n\n- id: \"ryan-bigg-ruby-on-ales-2013\"\n  title: \"Maintaining a large OSS project: war stories\"\n  raw_title: \"Ruby on Ales 2013 Maintaining a large OSS project: war stories by Ryan Bigg\"\n  speakers:\n    - Ryan Bigg\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-20\"\n  description: |-\n    At the end of 2011, I switched from being a Ruby consultant to being one of the lead maintainers of the biggest OSS Ruby projects. Best part is: I get paid to do it.\n\n    During that time, I've learned an awful lot about what it means to be responsible for something as massive as this project. Refactoring the code without causing tears for loyal users has been an extremely interesting problem to have.\n\n    I have some rather interesting stories to tell, like the time I renamed most of the files deliberately on purpose, or that time I ripped out a component that people depended on, and everyone was still happy. There's even been times where code has been moved out of the models and into new classes, which seems to be the cool thing to do.\n\n  video_provider: \"youtube\"\n  video_id: \"_t-Yt3fWF-4\"\n\n- id: \"jonan-scheffler-ruby-on-ales-2013\"\n  title: \"Hacking Cognition\"\n  raw_title: \"Ruby on Ales 2013 Hacking Cognition by Jonan Scheffler\"\n  speakers:\n    - Jonan Scheffler\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-20\"\n  description: |-\n    We are fortunate as software developers to spend our lives learning. Our careers require us to keep pace with an industry that innovates like few others and we adapt ourselves to constant change. Given the amount of time we dedicate to learning it is surprising that we don't make a greater effort to improve our cognitive ability itself. Cognitive function can be improved with some simple techniques that apply broadly in our profession, and it only makes sense that we should expend at least as much effort improving our ability to learn as we do actually learning.\n\n    This presentation will offer you some immediately actionable steps to improve your cognitive ability and be more efficient with your programming studies. You'll learn techniques mnemonists use to memorize random pages of binary digits, how your brain physically changes as you learn something new and how simple changes in your daily routine can have a deep impact on your work.\n\n    We spend hours refactoring our code and preparing for roflscale, why not spend some time optimizing our brains?\n\n    SKIP INTRO 0:20\n\n  video_provider: \"youtube\"\n  video_id: \"bS-f35m5_7Y\"\n\n- id: \"brian-morton-ruby-on-ales-2013\"\n  title: \"Services and Rails: The Shit They Don't Tell You\"\n  raw_title: \"Ruby on Ales Services and Rails: The Shit They Don't Tell You by Brian Morton\"\n  speakers:\n    - Brian Morton\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-21\"\n  description: |-\n    Building services and integrating them into Rails is hard. Often times we talk about how nice it would be if our Rails apps were smaller and we had nicely encapsulated services. And it would be, but services introduce complexity. If you build your application this way from the beginning, you're going to do extra work and probably get some of it wrong. If you wait too long, you've got a mess on your hands.\n\n    At Yammer, we work constantly to clean up the mess that worked well in the early days, but has become troublesome to maintain, scale, or handle lots of data. We're tasked with pulling things out of the core Rails app, standing them up on their own, and making sure they do what they do really well and really fast.\n\n    With over 20 services now running in production, we've learned some lessons along the way. Services that seem clean and simple in the beginning can turn into development environment nightmares. Temporary data double-dispatching solutions turn into duplication and developer confusion. Monitoring one app turns into monitoring a suite of apps and handling failure between them. This talk is a look into the tradeoffs, mistakes, and solutions that we deal with every day and how we're able to maintain velocity given the additional complexity.\n\n    At the end of the day, having services and a smaller Rails codebase makes for scalable development teams, happier engineers, and smoother and more predictable production environments. Getting there is full of tradeoffs and hard decisions -- sometimes we do it right, sometimes we fuck it up, but we usually have a story to tell.\n\n  video_provider: \"youtube\"\n  video_id: \"6OWHGGCj_yU\"\n\n- id: \"andrew-nordman-ruby-on-ales-2013\"\n  title: \"How Ruby makes Better Beer\"\n  raw_title: \"Ruby on Ales 2013 How Ruby makes Better Beer by Andrew Nordman\"\n  speakers:\n    - Andrew Nordman\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-21\"\n  description: |-\n    Craft beer is great. Ruby is great. When you can combine the two, you get a product that can only be described as Liquid Awesome. In this session, we will go over the brewing process and show how Ruby can help make better beer using automation, temperature control, and recipe analysis. We will look at a Ruby application created with recipe design and testing in mind, as well as a Ruby-based brewery control system run on a Raspberry Pi.\n\n  video_provider: \"youtube\"\n  video_id: \"sD_fN5Gyur4\"\n\n- id: \"davy-stevenson-ruby-on-ales-2013\"\n  title: \"The Fourth 'R'\"\n  raw_title: \"Ruby on Ales 2013 The Fourth 'R' by Davy Stevenson\"\n  speakers:\n    - Davy Stevenson\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-21\"\n  description: |-\n    As technology continues to grow at an increasing rate, why is our educational system stuck in a pre-technology age? Why is programming rarely taught even at a High School level? Why do stereotypes of the isolated, nerdy programmer continue to linger, driving away smart, creative people from computer science degrees?\n\n    'The Three Rs' of Reading, Writing and Arithmetic have come to stand as the cornerstones of education in this country. We need to step into the 21st century and add a fourth R -- Programming. As a community of programmers and Ruby lovers, we should work to advocate Ruby as the fourth R.\n\n    This is not just an education problem. This is also a diversity problem, and even a technological advancement problem. Negative programming stereotypes drive away women and minorities. Difficulty finding programming talent hampers technological innovation and growth. The technology community has stood by for decades waiting for education to catch up -- instead, we need to be the catalyst of change within the system.\n\n    I want the flying cars I was promised, and teaching today's children programming from an early age is the fastest path to a Jetsons future.\n\n  video_provider: \"youtube\"\n  video_id: \"PnzgakOqs9g\"\n\n- id: \"kerri-miller-ruby-on-ales-2013\"\n  title: \"You Can't Miss What You Can't Measure\"\n  raw_title: 'Ruby on Ales \"You Can''t Miss What You Can''t Measure\" by Kerri Miller'\n  speakers:\n    - Kerri Miller\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-21\"\n  description: |-\n    Adrift at sea, a GPS device will report your precise latitude and longitude, but if you don't know what those numbers mean, you're just as lost as before. Similarly, there are many tools that offer a wide variety of metrics about your code, but other than making you feel good, what are you supposed to do with this knowledge? Let's answer that question by exploring what the numbers mean, how static code analysis can add value to your development process, and how it can help us chart the unexplored seas of legacy code.\n\n  video_provider: \"youtube\"\n  video_id: \"jfNeXy5zUAQ\"\n\n- id: \"nic-benders-ruby-on-ales-2013\"\n  title: \"Get Your Ass to 1.9\"\n  raw_title: \"Ruby on Ales 2013 Get Your Ass to 1.9 by Nic Benders\"\n  speakers:\n    - Nic Benders\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-21\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"OcrpAT5LhFg\"\n\n- id: \"david-ryder-ruby-on-ales-2013\"\n  title: \"Dedication to David Ryder\"\n  raw_title: \"Ruby on Ales 2013 - Dedication to David Ryder\"\n  speakers:\n    - David Ryder\n    # - TODO: Speaker 1: https://cln.sh/dNWYfRMl\n    - Chris Stringer\n    - Chris Craybill\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-21\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"I46ARWDuPp4\"\n\n- id: \"lightning-talks-ruby-on-ales-2013\"\n  title: \"Lightning Talks\"\n  raw_title: \"Ruby on Ales 2013 Lightning Talks by Various Speakers\"\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-21\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"JIPyTpOztx4\"\n  talks:\n    - title: \"Lightning Talk: Jon Guymon\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jon-guymon-lighting-talk-ruby-on-ales-2013\"\n      video_id: \"jon-guymon-lighting-talk-ruby-on-ales-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Jon Guymon\n\n    - title: \"Lightning Talk: Rob Head\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"rob-head-lighting-talk-ruby-on-ales-2013\"\n      video_id: \"rob-head-lighting-talk-ruby-on-ales-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Rob Head\n\n    - title: \"Lightning Talk: Strand McCutchen\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"strand-mccutchen-lighting-talk-ruby-on-ales-2013\"\n      video_id: \"strand-mccutchen-lighting-talk-ruby-on-ales-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Strand McCutchen\n\n    - title: \"Lightning Talk: TODO\" # TODO: missing talk title\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-1-lighting-talk-ruby-on-ales-2013\"\n      video_id: \"todo-1-lighting-talk-ruby-on-ales-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name - https://cln.sh/ztmR2sMg\n\n    - title: \"Lightning Talk: Shane Becker\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"shane-becker-lighting-talk-ruby-on-ales-2013\"\n      video_id: \"shane-becker-lighting-talk-ruby-on-ales-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Shane Becker\n\n    - title: \"Lightning Talk: Aaron Kalin\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"aaron-kalin-lighting-talk-ruby-on-ales-2013\"\n      video_id: \"aaron-kalin-lighting-talk-ruby-on-ales-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Aaron Kalin\n\n    - title: \"Lightning Talk: Jason Clark\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jason-clark-lighting-talk-ruby-on-ales-2013\"\n      video_id: \"jason-clark-lighting-talk-ruby-on-ales-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Jason Clark\n\n    - title: \"Lightning Talk: TODO\" # TODO: missing talk title\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-2-lighting-talk-ruby-on-ales-2013\"\n      video_id: \"todo-2-lighting-talk-ruby-on-ales-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name - https://cln.sh/9DWYSwh4\n\n    - title: \"Lightning Talk: TODO\" # TODO: missing talk title\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-3-lighting-talk-ruby-on-ales-2013\"\n      video_id: \"todo-3-lighting-talk-ruby-on-ales-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name - https://cln.sh/281yQGqM\n\n    - title: \"Lightning Talk: Sethupathi Asokan\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"sethupathi-asokan-lighting-talk-ruby-on-ales-2013\"\n      video_id: \"sethupathi-asokan-lighting-talk-ruby-on-ales-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Sethupathi Asokan\n\n- id: \"shane-becker-ruby-on-ales-2013\"\n  title: \"Everything I Needed To Know About Open Source, I Learned From Punk Rock\"\n  raw_title: \"Ruby on Ales 2013 Everything I needed to know about open source, I learned from punk rock\"\n  speakers:\n    - Shane Becker\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-21\"\n  description: |-\n    By Shane Becker\n\n    It was the summer of 1993. I skipped out on the second game in a baseball double header to go to Lollapalooza with my cool older cousin. It was the first concert of my choosing (previously Hall & Oates, then The Grateful Dead). That day changed the course of my life.\n\n    I saw Rage Against the Machine which led to Inside Out which led to Revelation Records which led to Youth of Today, Bold and Gorilla Biscuits. Through those bands I'd learn about straightedge and veganism. I would discover a whole world of diy subcultures.\n\n    We made our own zines before there were blogs as a way to communicate across great time and distance. We formed our own bands to perform the soundtrack to our lives and ideals. We organized venues for our bands and friends' bands to play. We booked tours across timezones and oceans to see the world and meet new people.\n\n    We built our own networks and economies, in both gifts and exchanges. We created an aesthetic that was ours, a tribal identity. We created systems to record our story. We defined our lives on our terms.\n\n    Demo tapes were our Minimum Viable Product. Shows and tours were our meetups. Protests and convergences were our conferences. Cover songs were our permissive licenses. DIY was our flat organization. We didn't ask permission or forgiveness. We built, scammed or stole everything we could.\n\n    Punk rock is made of people. Open source is people. That we make music or software is just an artifact of the ideals we hold dear. All of these things I did when I was a kid in basements and tour vans, I'm doing again now on the internet and in office buildings.\n\n    What I didn't realize then, was that all of that was perfect training for the world of open source software.\n\n  video_provider: \"youtube\"\n  video_id: \"g1AbboNhnkk\"\n\n- id: \"evan-light-ruby-on-ales-2013\"\n  title: \"If It Bleeds, It Leads\"\n  raw_title: \"Ruby on Ales 2013 If it bleeds, it leads by Evan Light\"\n  speakers:\n    - Evan Light\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-20\"\n  description: |-\n    Many of us came to Ruby by way of Rails (including yours truly about six years ago). We came because our current solutions were clumsy and inconvenient. We came because we appreciated the relative simplicity that Rails offered. And we came because we believe that change is often a good thing. But not all changes are beneficial. Over several blog posts, books, and a couple of years, the Rails community has begun to choose complexity over simplicity.\n\n    Let's talk about why. And let's talk about how we can try to recapture that simplicity that we so once adored.\n\n  video_provider: \"youtube\"\n  video_id: \"HUgtPaiOL_8\"\n\n- id: \"terence-lee-ruby-on-ales-2013\"\n  title: \"`bundle install` Y U SO SLOW: Server Edition\"\n  raw_title: \"Ruby on Ales 2013 `bundle install` Y U SO SLOW: Server Edition by Terence Lee\"\n  speakers:\n    - Terence Lee\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-20\"\n  description: |-\n    If you've ever done anything in ruby, you've probably used rubygems and to search or install your favorite gem. On October 17, 2012, rubygems.org went down. A Dependency API was built to be used by Bundler 1.1+ to speed up bundle install. Unfortunately, it was a bit too popular and the service caused too much load on the current infrasture. In order to get rubygems.org back up the API had to be disabled. You can watch the post-mortem for details. http://youtu.be/z73uiWKdJhw\n\n  video_provider: \"youtube\"\n  video_id: \"bSUfsvvsk3E\"\n\n- id: \"jessica-suttles-ruby-on-ales-2013\"\n  title: \"The History of Women in Programming\"\n  raw_title: \"Ruby on Ales 2013 The History of Women in Programming\"\n  speakers:\n    - Jessica Suttles\n    - Elise Worthy\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-20\"\n  description: |-\n    By Jessica Suttles and Elise Worthy\n\n    Computer science was dominated by women until the 1970's. Women like Ada Lovelace and Grace Hopper paved the way for technical professions today. We'll cover the history of women in computing, possible causes of the gender shift, and ideas for how our community can shape the future.\n\n  video_provider: \"youtube\"\n  video_id: \"ZxwRRiGRaAY\"\n\n- id: \"andy-delcambre-ruby-on-ales-2013\"\n  title: \"Ruby Systems Programming\"\n  raw_title: \"Ruby on Ales 2013 Ruby Systems Programming by Andy Delcambre\"\n  speakers:\n    - Andy Delcambre\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-20\"\n  description: |-\n    We as rubyists tend to write software that runs on the web, without a deep understanding of what it would take to write the plumbing for that same software. I think it's useful to have a basic understanding of how some of the lower level components of a system work. I'll discuss the basics of systems programming, using Ruby. I'll talk about syscalls and kernel space vs user space. I'll cover a bit about file descriptors and what they're for. And hopefully I'll walk through a small example of a working webserver using those primitive syscalls.\n\n  video_provider: \"youtube\"\n  video_id: \"174m6GpYQfs\"\n\n- id: \"sarah-mei-ruby-on-ales-2013\"\n  title: \"The End of Fun\"\n  raw_title: \"Ruby on Ales 2013 The End of Fun by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"Ruby on Ales 2013\"\n  date: \"2013-03-07\"\n  published_at: \"2013-05-20\"\n  description: |-\n    I hate to break it to you, guys, but Ruby is almost old enough to drink. What started out as a small community full of fun, silliness, and connection has been growing. Our small codebases are now large. Our small *companies* are now large. And the large companies have finally figured out that they want in, too.\n\n    So maybe it's time to start tackling Real Problems and Real Solutions in the world of Real Innovation. Maybe it's time for the community to grow up, stop playing around, and get Serious™.\n\n    But...that's not who we are. Our community thrives on creativity, play, and luck. And those things aren't just a weird perk like not having to wear shoes in the office - creativity, play, and luck, when present, actually produce better software. As we grow our projects and our teams and invade the corporate cube farm, there are some things we can lay aside, and there are others we must hold on to as if our very identity depended on them.\n\n    Because it does.\n\n  video_provider: \"youtube\"\n  video_id: \"KgBqswPeJQU\"\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYYHU2QwS8gQzkQkaOn_lHr\"\ntitle: \"Ruby on Ales 2014\"\nkind: \"conference\"\nlocation: \"Bend, OR, United States\"\ndescription: \"\"\npublished_at: \"2014-03-09\"\nstart_date: \"2014-03-06\"\nend_date: \"2014-03-07\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2014\ncoordinates:\n  latitude: 44.0581728\n  longitude: -121.3153096\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2014/videos.yml",
    "content": "---\n# https://web.archive.org/web/20140228123824/https://ruby.onales.com/\n\n# TODO: talks running order\n# TODO: talk dates\n# TODO: schedule website\n\n- id: \"eric-hodel-ruby-on-ales-2014\"\n  title: \"Open Source Maintenance\"\n  raw_title: \"Ruby on Ales 2014 - Open Source Maintenance\"\n  speakers:\n    - Eric Hodel\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Eric Hodel\n    Maintaining RubyGems, RDoc and other Ruby libraries has grown from a hobby to my full time job over the past six years. Working on and maintaining open source projects has brought me lots of fun and enjoyment. I'll cover the joy and pain of being an open source developer, strategies for maintaining both your project and the interest and happiness you derive from it. I'll also talk about some of the things that keep me motivated to continue working on open source.\n  video_provider: \"youtube\"\n  video_id: \"WLoCnekSH3c\"\n\n- id: \"cameron-daigle-ruby-on-ales-2014\"\n  title: \"More Code, Fewer Pixels\"\n  raw_title: \"Ruby on Ales 2014 - More Code, Fewer Pixels\"\n  speakers:\n    - Cameron Daigle\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Cameron Daigle\n\n    Removing the \"Design Phase\". Eschewing Photoshop. Using frameworks. The malleable, flexible, agile nature of web apps these days\n    requires a drastically new approach to how UI concepts are transformed into working\n    code. Join me as I dive into the vagaries of Hashrocket's design-develop-revise-repeat\n    feedback loop -- and learn how we turn static markup into an essential communication\n    tool through rich UI prototyping, generated content, and general cleverness.\n  video_provider: \"youtube\"\n  video_id: \"FKYW9ZJ8lsI\"\n\n- id: \"mike-moore-ruby-on-ales-2014\"\n  title: \"Writing Games with Ruby\"\n  raw_title: \"Ruby on Ales 2014 - Writing Games with Ruby\"\n  speakers:\n    - Mike Moore\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Mike Moore\n    Creating games is crazy fun and dirt simple with Ruby.\n    You will leave this session with a working game; no previous game development\n    experience necessary. We will introduce basic concepts of game programming and\n    show how to implement them using the Gosu library. This includes the game loop,\n    sprites, animation, camera movement and hit detection. We will build a complete\n    game, so you might want to bring your notebook and follow along.\n\n  video_provider: \"youtube\"\n  video_id: \"VawT9BQr3Wk\"\n\n- id: \"ryan-bigg-ruby-on-ales-2014\"\n  title: \"Spree Adjustments\"\n  raw_title: \"Ruby on Ales 2014 - Spree Adjustments\"\n  speakers:\n    - Ryan Bigg\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Ryan Bigg\n    The brand new Spree 2.2 release contains a complete refactoring of how adjustments are handled. Whether you're interested in taxes, shipping or promotions you'll want to attend Ryan Bigg's comprehensive talk and learn more. The talk will include motivation for refactoring as well as how to get up and running with the new adjustment code.\n\n  video_provider: \"youtube\"\n  video_id: \"9D4-yKa4Kp4\"\n\n- id: \"jason-clark-ruby-on-ales-2014\"\n  title: \"Homebrewing, Simple as Ruby\"\n  raw_title: \"Ruby on Ales 2014 - Homebrewing, Simple as Ruby\"\n  speakers:\n    - Jason Clark\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Jason Clark\n\n    With a peculiar vocabulary, strict traditions, and heaps of arcane lore, brewing beer yourself can be overwhelming to the uninitiated... not unlike learning programming. But the basics of homebrewing are easily accessible with a bit of knowledge and some modest equipment. Like Ruby, brewing can be eased into, the complexity and variety of your tools growing alongside your skills. Step by step, we'll see how to make a delicious, quaffable beverage. Along the way we'll highlight how simplicity, experimentation, and an eye for quirkiness can make the act of creation--be it beer or code--awesome fun.\n\n  video_provider: \"youtube\"\n  video_id: \"Dn1y6xxo-y0\"\n\n- id: \"mark-menard-ruby-on-ales-2014\"\n  title: \"Small Code\"\n  raw_title: \"Ruby on Ales 2014 - Small Code\"\n  speakers:\n    - Mark Menard\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Mark Menard\n    To paraphrase Mark Twain, \"I didn't have time to write some small classes, so I wrote a BIG ONE instead.\" Now what do you do? Refactor! In this talk we'll refactor some large classes into a series of smaller classes. We'll learn techniques to identify buried abstractions, what to extract, what to leave behind, and why delegation, composition and dependency injection are key to writing small things that are easier to test.\n\n  video_provider: \"youtube\"\n  video_id: \"vBi6rtrTPx8\"\n\n- id: \"ben-bleything-ruby-on-ales-2014\"\n  title: \"Better Living Through ADHD\"\n  raw_title: \"Ruby on Ales 2014 - Better Living Through ADHD\"\n  speakers:\n    - Ben Bleything\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Ben Bleything\n    In late 2011, at age 30, I was diagnosed with ADHD. This is the story of how I noticed something was wrong and eventually got treatment. I'll talk about how ADHD is defined, what it looks like for me, how it has affected my life, and what I did to help myself.\n\n  video_provider: \"youtube\"\n  video_id: \"C4-yeaPHJmU\"\n\n- id: \"randall-thomas-ruby-on-ales-2014\"\n  title: \"Decade of Regression\"\n  raw_title: \"Ruby on Ales 2014 - TBA by Randall Thomas\"\n  speakers:\n    - Randall Thomas\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    TBA by Randall Thomas\n\n  video_provider: \"youtube\"\n  video_id: \"P4VoFApjDrE\"\n\n- id: \"sandi-metz-ruby-on-ales-2014\"\n  title: \"All The Little Things\"\n  raw_title: \"Ruby on Ales 2014 All The Little Things by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-11\"\n  description: |-\n    In theory, object-oriented applications consist of small, interchangeable objects which know almost nothing about one another. In reality, many Ruby apps contain big classes full of long methods built of many conditionals. Our classes act more like procedures than objects; they know too much, they contain code we can't reuse, they're hard to change and they get worse every time we do so. This talk uses the principles of object-oriented design to break ugly procedures into pleasing objects which have just the right balance of knowledge and ignorance. It bridges the gap between theory and practice and reveals a few simple secrets of OOD that you can use to convert confusing, unmaintainable faux-OO code into understandable, reusable, easily testable objects.\n\n  video_provider: \"youtube\"\n  video_id: \"x1wnI0AxpEU\"\n\n- id: \"jonan-scheffler-ruby-on-ales-2014\"\n  title: \"The Future of Computer Vision: How Two Rubyists Are Changing The World\"\n  raw_title: \"Ruby on Ales 2014 The Future of Computer Vision: How Two Rubyists Are Changing The World\"\n  speakers:\n    - Jonan Scheffler\n    - Aaron Patterson\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-11\"\n  description: |-\n    By Jonan Scheffler and Aaron Patterson\n    It all started with a dream. A dream of a world where people have learned to live in harmony with nature, where war is a distant memory, where humankind reaches unimaginable heights of technological innovation and Magic: The Gathering players no longer need to sort their cards by hand. This presentation will describe in detail the life-changing technological leaps that led us to this collectible card game utopia, examining the scanning, recognition and sorting of small bits of cardboard and all the Ruby that allows the magic to happen. If you've ever dreamed of being able to live your planeswalking dreams without the requisite hours of collating your cardboard collection, this is the presentation for you.\n\n  video_provider: \"youtube\"\n  video_id: \"ODTwPM_4pOI\"\n\n- id: \"bryce-kerley-ruby-on-ales-2014\"\n  title: \"Growing Distributed Systems\"\n  raw_title: \"Ruby on Ales 2014 - Growing Distributed Systems\"\n  speakers:\n    - Bryce Kerley\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Bryce Kerley\n    Distributed systems are big, in every sense of the word. From the biggest social networks and search engines to the simplest web or iOS application, distributed software causes problems, stemming from its greatest feature: the system should continue working even when parts break. Client applications without network connections still want to capture data, backends with a failed service or two shouldn't break the entire application, and the app should still mostly work even when the big datacenter (you know the one) goes down. How do you grow a simple monolithic Rails app into a distributed system? What does it take to make your UI save data for a network connection later? How do you even test all this stuff?\n\n  video_provider: \"youtube\"\n  video_id: \"BJ8TjmbN-dA\"\n\n- id: \"rein-henrichs-ruby-on-ales-2014\"\n  title: \"You Got Math In My Ruby! (You Got Ruby In My Math!)\"\n  raw_title: \"Ruby on Ales 2014 - You Got Math In My Ruby! (You Got Ruby In My Math!)\"\n  speakers:\n    - Rein Henrichs\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Rein Henrichs\n    Really? Math? With the boring formulas and definitions and proofs? Yes, math. But not that kind of math! The kind of math that challenges our creativity. The kind of math that explores the beautiful patterns that connect seemingly unrelated things in wonderful and surprising ways. The kind of math the helps us understand the problems we solve and the programs we write, makes complex things simpler, difficult things easier, and slow things faster. The kind of math that just might make you excited about learning math for the first time. The kind of math that you didn't even know was math. So come get some math in your Ruby. I think you'll like it.\n\n  video_provider: \"youtube\"\n  video_id: \"ZFzkmM4uEIQ\"\n\n- id: \"kerri-miller-ruby-on-ales-2014\"\n  title: \"Harry Potter and The Legacy Code Base\"\n  raw_title: \"Ruby on Ales 2014 - Harry Potter and The Legacy Code Base\"\n  speakers:\n    - Kerri Miller\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Kerri Miller\n    It's your first day at Hogwarts.com, and everything is wonderful and thrilling. You dig in to classes, and soon find a dusty book with a cryptic warning:\n\n    \"Do NOT on any circumstances make ANY change to this magic incantation without talking to Doug first!!!\"\n    Sound familiar? Approaching a legacy code base can feel like unraveling a mystery, not just about the code, but about the personalities who wrote it. What tools and techniques can help you solve the maze of twisty code? Let's explore how to get a handle on legacy code, how to negotiate joining an existing team of developers, and how we can get asumma cum laude at graduation.\n\n  video_provider: \"youtube\"\n  video_id: \"_sw9mhKtgCk\"\n\n- id: \"davy-stevenson-ruby-on-ales-2014\"\n  title: \"Ruby as Science, Art & Craft\"\n  raw_title: \"Ruby on Ales 2014 - Ruby as Science, Art & Craft\"\n  speakers:\n    - Davy Stevenson\n  event_name: \"Ruby on Ales 2014\"\n  date: \"2014-03-06\"\n  published_at: \"2014-05-12\"\n  description: |-\n    By Davy Stevenson\n    Developers are encouraged, and sometimes required,\n    to study Computer Science, however a large percentage of us are self-taught or\n    have entered programming through related fields. This sits in stark contrast to\n    most other engineering disciplines, and this diversity is possibly our greatest\n    strength.\n    Programming sits at the intersection of science, art, and craft.\n    I contend that, given introspection on each of these facets, we will all improve.\n    Learn how formal Computer Science techniques map to real-world problems. Contemplate\n    code as an art form. Think of code as your craft, and continue learning new techniques.\n    Take the time to look at problems through many lenses, and form diverse teams\n    that allow us to solve problems from many different angles.\n\n  video_provider: \"youtube\"\n  video_id: \"zkaeziqQs2I\"\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaUIjpEKMLTKc32kr4vseg9\"\ntitle: \"Ruby on Ales 2015\"\nkind: \"conference\"\nlocation: \"Bend, OR, United States\"\ndescription: |-\n  At the Tower Theatre in Bend, Oregon\npublished_at: \"2015-03-05\"\nstart_date: \"2015-03-05\"\nend_date: \"2015-03-06\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\ncoordinates:\n  latitude: 44.0581728\n  longitude: -121.3153096\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2015/videos.yml",
    "content": "---\n# https://web.archive.org/web/20150919113004/https://ruby.onales.com/schedules\n\n## Day 1 - 2015-03-05\n\n# Conference Registration\n\n# Welcome and Introduction\n\n- id: \"zachary-scott-ruby-on-ales-2015\"\n  title: \"Opening Keynote: TBA (Ruby everywhere - mruby)\"\n  raw_title: \"Ruby on Ales 2015 - TBA\"\n  speakers:\n    - Zachary Scott\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-05\"\n  published_at: \"2015-03-17\"\n  description: |-\n    By, Zachary Scott\n\n  video_provider: \"youtube\"\n  video_id: \"l1AGge1lcTw\"\n\n# Break\n\n- id: \"hsing-hui-hsu-ruby-on-ales-2015\"\n  title: \"Time Flies Like an Arrow, Fruit Flies Like a Banana: Parsing For Fun and Profit\"\n  raw_title: \"Ruby on Ales 2015 - Time flies like an arrow, fruit flies like a banana by Hsing-Hui Hsu\"\n  speakers:\n    - Hsing-Hui Hsu\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-05\"\n  published_at: \"2015-03-18\"\n  description: |-\n    How do we make sense of a regular sentence, especially when they take us down the \"garden path\"? For example, when we see a sentence that starts with \"The old man,\" most of us would expect the next word to be a verb. So when we read, \"The old man the boat,\" we have to backtrack to re-evaluate what the subject of the sentence really is. Humans are naturally attuned to parsing grammar in natural languages by analyzing the role and meaning of each word in context of its sentence. However, people may find the idea of parsing a computer language intimidating. In this talk, we'll explore the way we normally make sense out of an expression and relate that to the way parsers are used in computer science. By understanding the way we are inherently programmed to parse sentences, we can better understand common parsing strategies and how we can incorporate those tools into our code.\n\n  video_provider: \"youtube\"\n  video_id: \"KnTGGt-d7Gk\"\n\n# Break\n\n- id: \"terence-lee-ruby-on-ales-2015\"\n  title: \"Ruby Objects: A Walkabout\"\n  raw_title: \"Ruby on Ales 2015 - Ruby Objects: A Walkabout\"\n  speakers:\n    - Terence Lee\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-05\"\n  published_at: \"2015-03-24\"\n  description: |-\n    By, Terence Lee\n    In Ruby, it's easy to create classes, methods, and objects. For instance, did you know that a hello world sinatra app uses 43 classes, 155 methods, and dispatches 548 methods for a single request. In this talk, we're going use TracePoint API to look at how you can find out this information among other things. Additionally, now that we have all these objects from our Ruby app, the evolving ObjectSpace API we can glean information about rough object size in memory. Let's take a walk through objects in Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"G1ZpHUp9NeU\"\n\n# Break\n\n- id: \"amy-unger-ruby-on-ales-2015\"\n  title: \"Estimation Blackjack and Other Games: a Comedic Compendium\"\n  raw_title: \"Ruby on Ales 2015 - Estimation Blackjack and Other Games: a Comedic Compendium\"\n  speakers:\n    - Amy Unger\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-05\"\n  published_at: \"2015-03-23\"\n  description: |-\n    By, Amy Unger\n    Running a good estimation meeting is hard. It’s easy to get lost in the weeds of implementation, and let weird social interactions slip into our estimating process. You, too, may have played Estimation Blackjack without realizing it, being “out” if you give an estimate higher than everyone else’s. Calling out these bad habits is difficult: we sometimes stop seeing them, or stay silent to keep the peace. In doing so, we risk our stakeholders making critical business decisions based on bad estimates. How, then, can we improve how we estimate? Let’s start by cataloging the ways things go bad, and then considering different ways to talk about it. I will introduce a compendium of bad estimating games, anti-patterns that can emerge over time in the estimation process. You’ll walk away from this talk with new vocabulary for humorously discussing and improving your team’s estimation dynamic so you can help your business or your clients better plan for their future.\n\n  video_provider: \"youtube\"\n  video_id: \"mO0FM1_u3Rk\"\n\n# Break\n\n- id: \"akira-matsuda-ruby-on-ales-2015\"\n  title: \"The Recipe for the Worlds Largest Rails Monolith\"\n  raw_title: \"Ruby on Ales 2015 - The Recipe for the Worlds Largest Rails Monolith\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-05\"\n  published_at: \"2015-03-23\"\n  description: |-\n    By, Akira Matsuda\n\n  video_provider: \"youtube\"\n  video_id: \"naTRzjHaIhE\"\n\n# Break\n\n- id: \"jim-remsik-ruby-on-ales-2015\"\n  title: \"The Essential Elements of Networking (Fifteenth Edition)\"\n  raw_title: \"Ruby on Ales 2015 - The Essential Elements of Networking (Fifteenth Edition)\"\n  speakers:\n    - Jim Remsik\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-05\"\n  published_at: \"2015-03-23\"\n  description: |-\n    By, Jim Remsik\n    Thoroughly updated to reflect ComPIA’s Human+ H11-016 exam, The Essential Elements of Networking, Fifteenth Edition, is a practical, possibly out-of-date, and hands-on guide to the basics of networking. Written from the viewpoint of a \"working\" \"network\" \"administrator\", it requires absolutely no experience with either network concepts or day-to-day network management.\n\n  video_provider: \"youtube\"\n  video_id: \"a1jbJ2IIjj0\"\n\n# Break\n\n- id: \"chris-dillon-ruby-on-ales-2015\"\n  title: \"Dream: An Animation in Ruby\"\n  raw_title: \"Ruby on Ales 2015 - Dream: an animation in Ruby\"\n  speakers:\n    - Chris Dillon\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-05\"\n  published_at: \"2015-03-27\"\n  description: |-\n    By, Chris Dillon\n    A walkthrough about using the gamebox gem to create animation, in this case, a music video. You will see examples of sprites, pixel art, tweening, retro style parallax effects and pixellated cats.\n\n  video_provider: \"youtube\"\n  video_id: \"LFNoyi0nnsA\"\n\n# Break\n\n- id: \"ryan-davis-ruby-on-ales-2015\"\n  title: \"Standing on the Shoulders of Giants\"\n  raw_title: \"Ruby on Ales 2015 - Standing on the Shoulders of Giants\"\n  speakers:\n    - Ryan Davis\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-05\"\n  published_at: \"2015-03-23\"\n  description: |-\n    By, Ryan Davis\n    Ruby is a fantastic language, but it could be better. While it has done a terrific job of taking ideas from languages like smalltalk, lisp, and (to an extent) perl, it hasn't done nearly enough of it. Big thinkers have paved the way for us in so many programming languages, like Alan Kay & Dan Ingalls (smalltalk), David Ungar (self), Guy Steele & Gerald Sussman (scheme), and Matthias Felleisen (racket). You might not know their names, but you've certainly used their technology. We should plunder the treasures that they've thought up. I will survey a vast minority of these ideas and how they could help ruby. Ideas including: self-bootstrapping implementations and extensive collection / magnitude hierarchies from smalltalk, instance-based inheritance and JIT compilation from self, TCO and the overarching importance of lambdas from racket/scheme, and finally object level pattern matching and the combined object/lambda architecture from the View Points Research Institute. Ruby is at its best when borrowing great ideas from other languages, but lately it has fallen behind in this. It's time for ruby to step up and do more with these ideas, to keep pushing forward, to stand upon the shoulders of giants.\n\n  video_provider: \"youtube\"\n  video_id: \"w5JD3R6kmGI\"\n\n# Closing\n\n## Day 2 - 2015-03-06\n\n# Registration if you need it, or just coffee\n\n# Good Morning and Daily Business\n\n- id: \"ernie-miller-ruby-on-ales-2015\"\n  title: \"Humane Development\"\n  raw_title: \"Ruby on Ales 2015 - Humane Development\"\n  speakers:\n    - Ernie Miller\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-06\"\n  published_at: \"2015-03-24\"\n  description: |-\n    By, Ernie Miller\n    Agile. Scrum. Kanban. Waterfall. TDD. BDD. OOP. FP. AOP. WTH? As a software developer, I can adopt methodologies so that I feel there's a sense of order in the world. There's a problem with this story: We are humans, developing software with humans, to benefit humans. And humans are messy. We wrap ourselves in process, trying to trade people for personas, points, planning poker, and the promise of predictability. Only people aren't objects to be abstracted away. Let's take some time to think through the tradeoffs we're making together.\n\n  video_provider: \"youtube\"\n  video_id: \"SsReC-u--gg\"\n\n# Break\n\n- id: \"eric-hodel-ruby-on-ales-2015\"\n  title: \"Lessons in Mentorship\"\n  raw_title: \"Ruby on Ales 2015 - Lessons in Mentorship\"\n  speakers:\n    - Eric Hodel\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-06\"\n  published_at: \"2015-03-24\"\n  description: |-\n    By, Eric Hodel\n    Code schools are bringing new developers into the workforce, but regardless of the quality or length of the program there is only so much that can be absorbed by a student. It takes years of practice to move from a junior developer fresh out of school to a senior developer. Mentoring helps new developers improve faster, but years of experience as does not make you a good mentor by default. Successful mentoring can speed up this process. Being a successful mentor is more than pointing out mistakes in your junior's program. There are several basic strategies to successful mentorship including truly listening to your junior when they ask questions, giving just enough of a clue to allow self-discovery, managing frustration to keep on track, and focusing only on what you wish to teach right now while leaving other issues to handle later. By practicing these skills you can bring your junior developers skills forward faster to increase the productivity of your team.\n\n  video_provider: \"youtube\"\n  video_id: \"2uzvH2uR3-I\"\n\n# Break\n\n- id: \"nickolas-means-ruby-on-ales-2015\"\n  title: \"How To Code Like A Writer\"\n  raw_title: \"Ruby on Ales 2015 - How To Code Like A Writer\"\n  speakers:\n    - Nickolas Means\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-06\"\n  published_at: \"2015-03-25\"\n  description: |-\n    By, Nickolas Means\n    As developers, we spend more time writing code than thinking about the nuances of computer science. What would happen if we approached code like a writing exercise instead of a technical pursuit? What if we applied patterns from elegant prose instead of Gang of Four? Let's try it! We'll take some smelly Ruby and refactor it using only advice from Strunk and White's \"The Elements of Style\", the canonical text on writing beautiful, understandable English. You'll come away with a new approach to your craft and a new appreciation of the similarities between great writing and great code.\n\n  video_provider: \"youtube\"\n  video_id: \"XfvKpYgi7fI\"\n\n# Break\n\n- id: \"jason-clark-ruby-on-ales-2015\"\n  title: \"Testing the Multiverse\"\n  raw_title: \"Ruby on Ales 2015 - Testing the Multiverse\"\n  speakers:\n    - Jason Clark\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-06\"\n  published_at: \"2015-03-24\"\n  description: |-\n    By, Jason Clark\n    It’s a basic principle of testing that minimizing dependencies will make you happier, faster, and more productive. But what happens when you can’t? If your code plugs into or extends another gem, comfortable isolation might be out of the question. Stubbing and careful design can carry you a ways, but eventually you need to actually test your code against those gems you’re building on. Luckily, there are ways to reduce this pain. We’ll dig deep on creating a simple environment to check your work against multiple dependencies. We’ll see patterns that help avoid pulling your hair out when those dependencies change. We’ll even search around the raw edges, examining how to verify what your code does when it lands in an environment you haven’t tested. There’s a multitude of gems out there to build on. Let’s see how we can test with them!\n\n  video_provider: \"youtube\"\n  video_id: \"5a5zkpBIjzc\"\n\n# Break\n\n- id: \"will-leinweber-ruby-on-ales-2015\"\n  title: \"Better APIs with Pliny\"\n  raw_title: \"Ruby on Ales 2015 - Better APIs with Pliny\"\n  speakers:\n    - Will Leinweber\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-06\"\n  published_at: \"2015-03-24\"\n  description: |-\n    By, Will Leinweber\n    Heroku started out as single, large Rails app. Over the years it split into countless (really ... I have no idea how many) smaller services. Some of these splits were very successful, and others not so much. Pliny—an API framework built on Sinatra—distills everything we've learned the hard way about building production APIs in Ruby. Pliny takes care of mundane, mechanical decisions like logging and configuration, but also service problems including API versioning and json schemas. Most importantly, it comes with patterns to manage complexity as the service grows. It also shares its name with fantastic beer from Russian River. In this session, we'll explore what's important as you split into services, but also what can go terribly wrong. You'll learn everything you need to get started yourself with Pliny by looking at an open-source microservice built with it.\n\n  video_provider: \"youtube\"\n  video_id: \"lA8KhC9fFYY\"\n\n# Break\n\n- id: \"adrian-pike-ruby-on-ales-2015\"\n  title: \"Deployment Nirvana\"\n  raw_title: \"Ruby on Ales 2015 - Deployment Nirvana\"\n  speakers:\n    - Adrian Pike\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-06\"\n  published_at: \"2015-03-24\"\n  description: |-\n    By, Adrian Pike\n    Remember when Heroku showed up and how much it changed our world? Suddenly a simple `git push` and my app was online. Gosh, those were the good days, weren't they? Things have gotten a little more complicated for us these days. We've got inter-service dependencies. We should be doing some rolling deploys and user segmentation. Rollbacks should be instant and trivial. What about staging environments, why not be able to roll code safely? As an engineer, I should just be able to `git push`, and get back a running app instance. I should be able to route traffic to it whenever and however I want, whether it's production, staging, internal test, or just a running code spike on production servers to show a colleague. In this talk, I'm going to talk about the tools and infrastructure that I've built in the past to solve deployment woes for big, thorny, complicated apps, and give engineering teams tons of power. I'll also show off an open-source implementation that I'll be building specifically for RoA.\n\n  video_provider: \"youtube\"\n  video_id: \"P6SylUt7LNU\"\n\n# Break\n\n- id: \"mike-moore-ruby-on-ales-2015\"\n  title: \"Stupid Ruby Tricks\"\n  raw_title: \"Ruby on Ales 2015 - Stupid Ruby Tricks\"\n  speakers:\n    - Mike Moore\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-06\"\n  published_at: \"2015-03-25\"\n  description: |-\n    By, Mike Moore\n    Ruby is awesome. We all love Ruby. And Ruby loves us. We shouldn't abuse Ruby. Well, maybe a little.\n\n  video_provider: \"youtube\"\n  video_id: \"fSGWad5OkUc\"\n\n# Break\n\n- id: \"aja-hammerly-ruby-on-ales-2015\"\n  title: \"Storytime with Auntie Aja\"\n  raw_title: \"Ruby on Ales 2015 - Storytime with Auntie Aja\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-06\"\n  published_at: \"2015-03-23\"\n  description: |-\n    By, Aja Hammerly\n    I've been fortunate to receive some great advice during my career. Some of it is pithy, some of it is practical, and some is the little things you learn when working at semi-functional organizations. By the flickering light of a projector, I'll pass along the my favorite pieces of wisdom and tell stories about when I applied those lessons. New folks will learn some tried and true tricks for success in the software industry. Experienced developers can nod along and be comforted by the fact that everyone has had the same bad experiences at one point or another. So pull up a chair (and a beverage) and gather around for storytime.\n\n  video_provider: \"youtube\"\n  video_id: \"980WxugF3NI\"\n\n# Break\n\n- id: \"jonan-scheffler-ruby-on-ales-2015\"\n  title: \"Robolove\"\n  raw_title: \"Ruby on Ales 2015 - Robolove\"\n  speakers:\n    - Jonan Scheffler\n  event_name: \"Ruby on Ales 2015\"\n  date: \"2015-03-06\"\n  published_at: \"2015-04-06\"\n  description: |-\n    By, Jonan Scheffler\n    A story of hope and adventure as told by Robo and Bobo, two piles of legos and assorted robot parts powered by love and about 11 volts. Follow our tiny rolling lovers as they rekindle your passion for Ruby and reveal the triumph of the robot spirit. You’ll laugh, you’ll cry, you’ll compute.\n\n  video_provider: \"youtube\"\n  video_id: \"LnLm20OJibA\"\n# Closing\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2016/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyb0PFcp3rGqDb7xnM6c531Z\"\ntitle: \"Ruby on Ales 2016\"\nkind: \"conference\"\nlocation: \"Bend, OR, United States\"\ndescription: |-\n  At the Tower Theatre in Bend, Oregon. Ruby on Ales is a two day single track Ruby conference in Oregon. It has all of the requisite makings of a conference—presentations, opportunities to find a new job and network—but let's be honest: Ruby on Ales feels a lot like a reunion of friends and colleagues.\npublished_at: \"2016-03-31\"\nstart_date: \"2016-03-31\"\nend_date: \"2016-04-01\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2016\ncoordinates:\n  latitude: 44.0581728\n  longitude: -121.3153096\n"
  },
  {
    "path": "data/ruby-on-ales/ruby-on-ales-2016/videos.yml",
    "content": "---\n# https://web.archive.org/web/20160816134126/https://ruby.onales.com/\n\n# TODO: talks running order\n# TODO: talk dates\n# TODO: schedule website\n\n- id: \"rein-henrichs-ruby-on-ales-2016\"\n  title: \"Why Good Software Goes Bad\"\n  raw_title: \"Ruby on Ales 2016: Why Good Software Goes Bad by Rein Henrichs\"\n  speakers:\n    - Rein Henrichs\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    Software fails a lot. We spend a lot of time trying to fix failing software... and sometimes we fail at that too. How can we get better at it? Here are some questions that this talk will try -- and probably fail -- to answer:\n\n    Why do we so often do things wrong when we know how to do things right? How can we create a supportive environment that is tolerant of failure? Why do we keep repeating the same failures? What do other companies do that make them better at responding to failure? What does a company's culture have to do with their ability to respond to failure?\n\n    How do we observe and reason about failure? Why is it so hard to estimate things that can fail and what can we do to get better at it? Can we measure how efficiently we resolve failures? What sort of failure response strategies could we use and what are their tradeoffs? What can system complexity and human psychology teach us about failure?\n\n    From systems thinking to project management to the interaction between culture and process, if you've ever wondered why you keep experiencing the same problems writing and shipping software then this talk is for you.\n\n  video_provider: \"youtube\"\n  video_id: \"JXVHvqbfsNI\"\n\n- id: \"will-leinweber-ruby-on-ales-2016\"\n  title: \"Introducing the Crystal Programming Language\"\n  raw_title: \"Ruby on Ales 2016: Introducing the Crystal Programming Language by Will Leinweber\"\n  speakers:\n    - Will Leinweber\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    Developer happiness is what brought me to Ruby in the first place. And of all the new compiled languages, Crystal is the only one that shares this value. The syntax and idioms are entirely Ruby inspired. Although Crystal looks very similar to Ruby, there are big differences between the two. Crystal is statically typed and dispatched. While there are no runtime dynamic features, the compile-time macros solve many of the same problems. In this session, we’ll take a close look at these differences as well as the similarities, and what Ruby developers can learn from this exciting language.\n\n  video_provider: \"youtube\"\n  video_id: \"5QjvGuL4Opo\"\n\n- id: \"amy-wibowo-ruby-on-ales-2016\"\n  title: \"Fold, Paper, Scissors...\"\n  raw_title: \"Ruby on Ales 2016: Fold, Paper, Scissors... by Amy Wibowo\"\n  speakers:\n    - Amy Wibowo\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    This talk looks beyond origami as a childhood pastime and an art form and instead, explores origami as a source of many interesting mathematical problems, including one called the fold-and-cut problem. The fold and cut theorem states that it is possible, given a piece of paper and any polygonal shape, to find a series of folds of that paper such that the given shape can be generated with a single cut. This talk explores two proofs of the theorem and and a Ruby implementation of a solver that determines the correct series of folds given any input polygon. There will be a live demo of the program and paper cutting!\n\n  video_provider: \"youtube\"\n  video_id: \"SYkSCcRlmjk\"\n\n- id: \"julia-ferraioli-ruby-on-ales-2016\"\n  title: \"In the Name of Whiskey\"\n  raw_title: \"Ruby on Ales 2016: In the Name of Whiskey by Julia Ferraioli\"\n  speakers:\n    - Julia Ferraioli\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    One of the most common reasons for using machine learning is because you want to use data to make sense of more data: given lots of things with many characteristics, how do you use them to categorize, make recommendations, or evaluate something new? We can use machine learning for all sorts of lofty goals, so let’s tackle a critical problem in our lives: whiskey. I’m a novice to whiskey, and so far I’ve stuck to the lighter stuff. Finding new ones to add to my collection has been decidedly unscientific. Given the data we have available about whiskey, let’s try doing a bit of machine learning by feeding it into TensorFlow, an open source library, to see what cool insights we can get into a complex spirit.\n\n  video_provider: \"youtube\"\n  video_id: \"BzD7GJwY010\"\n\n- id: \"vaidehi-joshi-ruby-on-ales-2016\"\n  title: \"A Machine State of Mind\"\n  raw_title: \"Ruby on Ales 2016: A Machine State of Mind by Vaidehi Joshi\"\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    Software is a field littered with tough problems. One of the hardest and most hated problems arises when handling mutable state. This becomes especially complex when we try to mirror the real world objects, which are constantly changing, as objects within our code. Dealing with the state of an object can be a slippery slope, particularly if we don’t know what tools to reach for. This talk will delve into one of the most elegant (but often ignored!) solutions for tackling mutable state: state machines. We’ll break down the theory behind state machines and learn how they’re not nearly as complex as they seem to be.\n  video_provider: \"youtube\"\n  video_id: \"N1jnoPxBGGA\"\n\n- id: \"allison-mcmillan-ruby-on-ales-2016\"\n  title: \"BDD: Baby Driven Development\"\n  raw_title: \"Ruby on Ales 2016: BDD: Baby Driven Development by Allison McMillan\"\n  speakers:\n    - Allison McMillan\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    When I became a parent, I was amazed at how similar raising a newborn was to becoming a developer and the ways in which both experiences affect one another. Coding sets you on a challenging path of a lifetime of learning… and in the end you still aren’t an expert! We will compare tradeoffs and decisions that relate to both situations offering insights and lessons learned. Then, explore the similarities between these two journeys and common approaches we use when coding and raising a baby. Whether you’re a parent or not, come discover these interesting and often hilarious parallels. Also, there might be a baby on stage.\n  video_provider: \"youtube\"\n  video_id: \"nZHTg3Hza1U\"\n\n- id: \"aja-hammerly-ruby-on-ales-2016\"\n  title: \"Sharpening The Axe: Self-Teaching For Developers\"\n  raw_title: \"Ruby on Ales 2016: Sharpening The Axe: Self-Teaching For Developers by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  slides_url: \"https://thagomizer.com/files/RbOnAles_16.pdf\"\n  description: |-\n    Many of us get a few years into our career and get stuck in a rut. Maybe we stop reading about the latest and greatest in tech. Maybe we start managing and do less coding than we'd like. Maybe life gets in the way and coding becomes drudgery. One way to combat this feeling is to focus on learning. I'll share what I've learned about juggling self improvement with being a professional programmer. I'll talk about the courses, tools, books, and other resources I've found most useful. You’ll leave this talk with several ideas for breaking out of your own developer rut.\n  video_provider: \"youtube\"\n  video_id: \"7JD9ZQZMmjo\"\n\n- id: \"ryan-davis-ruby-on-ales-2016\"\n  title: \"Writing a Test Framework from Scratch\"\n  raw_title: \"Ruby on Ales 2016: Writing a Test Framework from Scratch by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    Assertions (or expectations) are the most important part of any test framework. How are they written? What happens when one fails? How does a test communicate its results? Past talks have shown how test frameworks work from the very top: how they find, load, select, and run tests. Instead of reading code from the top, we’ll write code from scratch starting with assertions and building up a full test framework. By the end, you'll know how every square inch of your testing framework works.\n  video_provider: \"youtube\"\n  video_id: \"9EsVZijRjxs\"\n\n- id: \"ernie-miller-ruby-on-ales-2016\"\n  title: \"Choices\"\n  raw_title: \"Ruby on Ales 2016: Choices by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    Our lives are filled with choices. And one thing's for sure: whether you're choosing what to eat for lunch, to add \"just one more gem\" to your Gemfile, or to start a new job, your choices *will* have consequences. If that's the case, let's step back for a moment to discuss how we tackle this thing we do so many times each day. Maybe we'll get better at making choices as a result? At the very least, we'll have some fun. Come equipped with your laptop or smartphone, as you'll be directly influencing the content of this talk as you make choices of your own! I hope you'll choose to join us.\n  video_provider: \"youtube\"\n  video_id: \"kJkJ_dRAAzQ\"\n\n- id: \"tobi-lehman-ruby-on-ales-2016\"\n  title: \"Object Oriented Orbits: A Primer on Newtonian Physics\"\n  raw_title: \"Ruby on Ales 2016: Object Oriented Orbits: a primer on newtonian physics by Tobi Lehman\"\n  speakers:\n    - Tobi Lehman\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    In this talk, we derive a simple 2D physics simulator, focusing on gravity and spherical objects. The speaker walks through a basic introduction to Newton's laws, and then derives a formula for a discrete approximation of the equations of motion. We convert the discrete approximation of the equations of motion into Ruby code, which accepts a state at a particular time, along with an interval of time, and then computes the new state at that following time interval. This updated state is then rendered using an HTML5 canvas element. The talk concludes with some demonstrations involving randomized initial conditions, highly symmetric initial conditions, and some awesome 3-body stable orbits.\n  video_provider: \"youtube\"\n  video_id: \"IaSPcs8Y6gc\"\n\n- id: \"andr-arko-ruby-on-ales-2016\"\n  title: \"Including People\"\n  raw_title: \"Ruby on Ales 2016: Including People by André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    This talk is about the twin open source project goals of, on the one hand, increasing participation and contribution to an open source project, and on the other hand including everyone while eliminating discrimination and harassment (whether deliberate or accidental). I'll talk about different approaches to reducing discrimination, including better documentation, better development tooling, explicit onboarding process, and codes of conduct. I'll also cover concrete steps that anyone can take to help increase inclusion and participation in the teams, communities, and open source projects that they are involved in.\n  video_provider: \"youtube\"\n  video_id: \"MrPtHogES6k\"\n\n- id: \"mike-moore-ruby-on-ales-2016\"\n  title: \"Open Source Survival Guide\"\n  raw_title: \"Ruby on Ales 2016: Open Source Survival Guide by Mike Moore\"\n  speakers:\n    - Mike Moore\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-21\"\n  description: |-\n    Collaboration is the key for successful software development. It works best when code can be understood and contributed to by many. Sometimes we think the unwritten rules for successful online collaboration are obvious, but experience has shown again and again that it is not. So let's discuss these rules and write them down so we have them. We will discuss how to make successful code contributions to the projects we all rely on, and offer some strategies for encouraging contributions on our own projects.\n  video_provider: \"youtube\"\n  video_id: \"NkwR9noUi6E\"\n\n- id: \"justin-searls-ruby-on-ales-2016\"\n  title: \"How to Stop Hating Your Test Suite\"\n  raw_title: \"Ruby on Ales 2016: How to Stop Hating Your Test Suite by Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"Ruby on Ales 2016\"\n  date: \"2016-03-31\"\n  published_at: \"2016-04-22\"\n  description: |-\n    How to Stop Hating Your Test Suite by Justin Searls\n\n    Your app is a unique snowflake. Your tests are too… but they shouldn't be! Years helping teams write better tests has taught me one thing: consistency is crucial. Inconsistent tests slow teams down, wasting time to understand how each test works. Deciding on conventions—even arbitrary ones—can prevent tremendous pain later. This talk will introduce a ready-to-fork Test Style Guide of carefully-considered rules and templates for Rubyists. You can customize it to fit your preferred tools, too. Soon, you'll be on your way to having more consistent tests that are much more fun to maintain!\n\n  video_provider: \"youtube\"\n  video_id: \"MIJ2Grv2Bts\"\n"
  },
  {
    "path": "data/ruby-on-ales/series.yml",
    "content": "---\nname: \"Ruby on Ales\"\nwebsite: \"http://ruby.onales.com\"\ntwitter: \"rbonales\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Ruby on Ales\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\n"
  },
  {
    "path": "data/ruby-on-ice/ruby-on-ice-2018/event.yml",
    "content": "---\nid: \"ruby-on-ice-2018\"\ntitle: \"Ruby on Ice 2018\"\nkind: \"conference\"\nlocation: \"Tegernsee, Germany\"\ndescription: |-\n  A conference about Ruby, Rails and related technologies. January 26th - 28th, 2018. Tegernsee, Germany\nstart_date: \"2018-02-26\"\nend_date: \"2018-02-28\"\nchannel_id: \"UCXNhwlbzt-6LoOzMt4wrF0A\"\nyear: 2018\nbanner_background: \"#6EB5CF\"\nfeatured_background: \"#6EB5CF\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2018.rubyonice.com/\"\ncoordinates:\n  latitude: 47.7130234\n  longitude: 11.7580899\n"
  },
  {
    "path": "data/ruby-on-ice/ruby-on-ice-2018/schedule.yml",
    "content": "# Schedule: https://2018.rubyonice.com/schedule\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2018-01-26\"\n    grid:\n      - start_time: \"16:30\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - title: \"Registration desk opens\"\n            description: |-\n              Register for badges and goodie bags.\n\n      - start_time: \"16:30\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - title: \"Reception\"\n            description: |-\n              Free snacks, coffee, tea and soft drinks\n\n      - start_time: \"17:30\"\n        end_time: \"17:55\"\n        slots: 1\n        items:\n          - title: \"How the conference works\"\n            description: |-\n              Monica explains travel, food, internet, activities, safety.\n\n      - start_time: \"17:55\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - Message from our sponsor xbAV\n\n      - start_time: \"18:00\"\n        end_time: \"18:45\"\n        slots: 1\n\n      - start_time: \"18:45\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - title: \"Break\"\n            description: |-\n              Free soft drinks\n\n      - start_time: \"19:00\"\n        end_time: \"19:45\"\n        slots: 1\n\n      - start_time: \"19:45\"\n        end_time: \"20:15\"\n        slots: 1\n        items:\n          - title: \"Info: Saturday activities\"\n            description: |-\n              Monica explains your Saturday afternoon options.\n\n      - start_time: \"20:15\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - title: \"Evening Buffet\"\n            description: |-\n              Free fingerfood buffet and soft drinks. Alcoholic drinks can be purchased.\n\n      - start_time: \"23:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Last public bus departs\n\n  - name: \"Day 2\"\n    date: \"2018-01-27\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - title: \"Seeforum venue opens\"\n            description: |-\n              Saturday arrivals can register for badges and goodie bags\n\n      - start_time: \"09:30\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Announcements\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - title: \"Coffee Break\"\n            description: |-\n              Free snacks, coffee, tea, soft drinks\n\n      - start_time: \"11:00\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"12:45\"\n        slots: 1\n        items:\n          - Announcements\n\n      - start_time: \"12:45\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - title: \"Lunch Break\"\n            description: |-\n              Free buffet and soft drinks\n\n      - start_time: \"13:30\"\n        end_time: \"16:30\"\n        slots: 2\n        description: |-\n          Choose one of four afternoon activities\n        items:\n          - title: \"Outdoor Activity: Sledding at mount Wallberg\"\n            description: |-\n              Subject to snowy weather\n              Winter gear required (no sneakers!)\n              Limited capacity\n\n          - title: \"Outdoor Activity: Walk around lake Tegernsee\"\n            description: |-\n              A light hike around the Southern shore\n              About 2 hours of walking\n              Afterwards we will visit a food market\n              Subject to good weather\n\n      - start_time: \"14:00\"\n        end_time: \"16:30\"\n        description: |-\n          Choose one of four afternoon activities\n        slots: 2\n\n      - start_time: \"16:30\"\n        end_time: \"17:15\"\n        slots: 1\n        description: |-\n          Meet back at seeforum\n        items:\n          - title: \"Coffee & Cakes\"\n            description: |-\n              Free apfelstrudel, coffee, tea, soft drinks\n\n      - start_time: \"17:15\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"18:15\"\n        slots: 1\n        items:\n          - title: \"Break\"\n            description: |-\n              Free soft drinks\n\n      - start_time: \"18:15\"\n        end_time: \"19:00\"\n        slots: 1\n\n      - start_time: \"19:00\"\n        end_time: \"19:30\"\n        slots: 1\n        items:\n          - title: \"Info: Evening event\"\n            description: |-\n              Monica explains dinner and how to get home\n\n      - start_time: \"19:30\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - title: \"Food and drinks at Bräustüberl\"\n            description: |-\n              Free appetizers. Rich Bavarian menu.\n\n      - start_time: \"23:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - title: \"Bus shuttles home\"\n            description: |-\n              Multiple conference shuttles depart to various regions of Tegernsee\n\n      - start_time: \"23:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Last public bus departs\n\n  - name: \"Day 3\"\n    date: \"2018-01-28\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - title: \"Seeforum venue opens\"\n            description: |-\n              Orga team will help you print out train or airplane tickets\n\n      - start_time: \"10:00\"\n        end_time: \"10:05\"\n        slots: 1\n        items:\n          - title: \"Lightning Talk Picks\"\n            description: |-\n              Monica announces Lightning talk schedule for Sunday noon\n\n      - start_time: \"10:05\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"10:45\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - title: \"Coffee Break\"\n            description: |-\n              Free snacks, coffee, tea, soft drinks\n\n      - start_time: \"11:00\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"12:00\"\n        slots: 1\n        items:\n          - title: \"Break\"\n            description: |-\n              Free soft drinks\n\n      - start_time: \"12:00\"\n        end_time: \"13:00\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - title: \"Lunch Break\"\n            description: |-\n              Free buffet and soft drinks\n\n      - start_time: \"14:00\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - title: \"Raffle Break\"\n            description: |-\n              Win a price from our sponsor xbAV\n              Free softdrinks\n\n      - start_time: \"15:00\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"15:45\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - title: \"Goodbye Ruby on Ice\"\n            description: |-\n              The orga team says farewell\n\n      - start_time: \"16:00\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - End of Scheduled Program\n\n      - start_time: \"17:00\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Seeforum venue closes\n"
  },
  {
    "path": "data/ruby-on-ice/ruby-on-ice-2018/videos.yml",
    "content": "---\n# Website: https://2018.rubyonice.com\n# Schedule: https://2018.rubyonice.com/schedule\n\n## Day 1 - Friday\n\n- title: \"Where do Rubyists go?\"\n  raw_title: \"Where do Rubyists go?\"\n  speakers:\n    - Tobias Pfeiffer\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-26\"\n  description: |-\n    Many Rubyists branch out and take a look at other languages. What are similarities between those languages and ruby? What are differences? How does Ruby influence these languages?\n  video_provider: \"not_recorded\"\n  video_id: \"tobias-pfeiffer-ruby-on-ice-2018\"\n  slug: \"where-do-rubyists-go-ruby-on-ice-2018\"\n  id: \"tobias-pfeiffer-ruby-on-ice-2018\"\n  slides_url: \"https://pragtob.wordpress.com/2018/01/27/slides-where-do-rubyists-go/\"\n\n- title: \"Don't aim for reusability\"\n  raw_title: \"Don't aim for reusability\"\n  speakers:\n    - Michael Sauter\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-26\"\n  description: |-\n    Reusable, flexible code is often seen as the holy grail of software development. However, when new requirements come up, the code that was supposed to be reusable turns out to be too complex, difficult to understand, and not quite what is needed now. If that is the case, why do we continue to strive for reusability in the first place? This talk questions our tendency to generalize and our conviction that we can foresee what we’ll need in the future - and it’ll propose a different guiding principle instead.\n  video_provider: \"not_recorded\"\n  video_id: \"michael-sauter-ruby-on-ice-2018\"\n  slug: \"dont-aim-for-reusability-ruby-on-ice-2018\"\n  id: \"michael-sauter-ruby-on-ice-2018\"\n  slides_url: \"https://speakerdeck.com/michaelsauter/dont-aim-for-reusability\"\n\n## Day 2 - Saturday\n\n- title: \"Ruby's Gems\"\n  raw_title: \"Ruby's Gems\"\n  speakers:\n    - Piotr Szotkowski\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-27\"\n  description: |-\n    The Ruby ecosystem is known for its plethora of gems (and – sadly only a few – of its standard libraries), but the base interpreter itself is a treasure trove with small, beautiful jewels of pleasant syntax and fairly unknown, but elegant solutions that spring to help in the most surprising circumstances.\n  video_provider: \"not_recorded\"\n  video_id: \"piotr-szotkowski-ruby-on-ice-2018\"\n  slug: \"rubys-gems-ruby-on-ice-2018\"\n  id: \"piotr-szotkowski-ruby-on-ice-2018\"\n  slides_url: \"https://talks.chastell.net/ruby-on-ice-2018\"\n\n- title: \"The Good Bad Bug: Fail Your Way to Better Code\"\n  raw_title: \"The Good Bad Bug: Fail Your Way to Better Code\"\n  speakers:\n    - Jessica Rudder\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-27\"\n  description: |-\n    Programming history is filled with bugs that turned out to be features and limitations that pushed developers to make even more interesting products. We’ll journey through code that was so ‘bad’ it was actually good. Along the way we'll look at the important role failure plays in learning. Then we’ll tame our inner perfectionists and tackle an approach to writing code that will help us fail spectacularly on our way to coding success.\n  video_provider: \"not_recorded\"\n  video_id: \"jessica-rudder-ruby-on-ice-2018\"\n  slug: \"the-good-bad-bug-ruby-on-ice-2018\"\n  id: \"jessica-rudder-ruby-on-ice-2018\"\n\n- title: \"My Ruby is a Paintbrush. My Ruby is a Synth\"\n  raw_title: \"My Ruby is a Paintbrush. My Ruby is a Synth\"\n  speakers:\n    - Jan Krutisch\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-27\"\n  description: |-\n    In 2017, Ruby is proven, almost boring technology. We use it mostly to build Backends for Hipster Technology™ JavaScript Frontends. But Ruby can do so much more - so let’s explore that. Ruby can paint pictures. Ruby can make music. As we will see: Ruby can be an engineer’s tool, or an artist’s tool.\n  video_provider: \"not_recorded\"\n  video_id: \"jan-krutisch-ruby-on-ice-2018\"\n  slug: \"my-ruby-is-a-paintbrush-my-ruby-is-a-synth-ruby-on-ice-2018\"\n  id: \"jan-krutisch-ruby-on-ice-2018\"\n  slides_url: \"http://slides.krutisch.de/roi2018_ruby_for_artists/slides.html#1\"\n\n- title: \"Workshop: Making music with Ruby\"\n  raw_title: \"Workshop: Making music with Ruby\"\n  speakers:\n    - Benjamin Reitzammer\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-27\"\n  video_provider: \"not_recorded\"\n  video_id: \"benjamin-reitzammer-ruby-on-ice-2018\"\n  slug: \"workshop-making-music-with-ruby-ruby-on-ice-2018\"\n  id: \"benjamin-reitzammer-ruby-on-ice-2018\"\n  description: |-\n    A practical introduction to SonicPI\n\n    Sonic Pi is a creative music programming tool that enables anyone, no matter their musicality, to create music. And Ruby has been the lucky choice of programming language for it.\n\n    In this entry-level workshop, you'll learn the basics of Sonic Pi, it's DSL and the tool itself. The majority of the time, however will be spent by you programming your own music. You'll learn some strategies, that enable you to get up to speed quickly and make you enjoy the ultra-fast feedback loop that is inherent in programming music with Sonic Pi.\n\n- title: \"Workshop: Tensorflow for Rubyists\"\n  raw_title: \"Workshop: Tensorflow for Rubyists\"\n  speakers:\n    - Arafat Khan\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-27\"\n  description: |-\n    Machine learning by example\n\n    Ruby has been mostly restricted to web development and scripting, until now. In this talk, I will introduce Tensorflow to the Ruby community to give them a glimpse of how they can do basic Machine Learning.\n\n    We will start with the basic concepts of machine learning with Tensorflow, visualize our program with TensorBoard, following along the Python API and will get to know the Ruby API tensorflow.rb. Prior knowledge of Machine Learning or Tensorflow is not necessary. We will go through the workshop in a shared development environment, so you don't need to install or prepare anything on your laptop.\n  video_provider: \"not_recorded\"\n  video_id: \"arafat-khan-ruby-on-ice-2018\"\n  slug: \"workshop-tensorflow-for-rubyists-ruby-on-ice-2018\"\n  id: \"arafat-khan-ruby-on-ice-2018\"\n\n- title: \"Spotting unsafe concurrent Ruby patterns\"\n  raw_title: \"Spotting unsafe concurrent Ruby patterns\"\n  speakers:\n    - Ivo Anjo\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-27\"\n  description: |-\n    Concurrency is an extremely powerful technique that should be part of every Rubyist's tool belt. But when a lot of people pick up tools such as puma, concurrent-ruby or even JRuby, they are at the same time thrilled by all the power that threads and concurrency gets them, and afraid for the day when a concurrency bug will come and chew their arm (or service) off.\n\n    But what do we normally mean when we talk about a concurrency bug? What do they look like? And how do you fix them, preferably without giving up performance or readability? In this talk, I will show examples of Ruby patterns and techniques that lead to unsafe behavior in the presence of multi-threading, be it in MRI or JRuby. I will then discuss how they can be spotted, why they are problematic, and propose safe alternatives.\n  video_provider: \"not_recorded\"\n  video_id: \"ivo-anjo-ruby-on-ice-2018\"\n  slug: \"spotting-unsafe-concurrent-ruby-patterns-ruby-on-ice-2018\"\n  id: \"ivo-anjo-ruby-on-ice-2018\"\n  slides_url: \"http://slides.com/ianjo/spotting-unsafe-concurrent-ruby-patterns\"\n\n- title: \"Better developer relations start with the interview\"\n  raw_title: \"Better developer relations start with the interview\"\n  speakers:\n    - Margo Urey\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-27\"\n  description: |-\n    First impressions are important and developer relations start with the interview. Here are a few ways companies got it right and got it wrong, and how you can take control to start things off on the right foot.\n  video_provider: \"not_recorded\"\n  video_id: \"margo-urey-ruby-on-ice-2018\"\n  slug: \"better-devrel-starts-with-interview-ruby-on-ice-2018\"\n  id: \"margo-urey-ruby-on-ice-2018\"\n  slides_url: \"https://2018.rubyonice.com/slides/margo_urey_better_developer_relations.pdf\"\n\n## Day 3 - Sunday\n\n- title: \"The Impermanence of Software\"\n  raw_title: \"The Impermanence of Software\"\n  speakers:\n    - Andy Croll\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-28\"\n  description: |-\n    A lot of the software we write is destined for deletion, yet one of the greatest drivers in humanity is the urge to be remembered. If we acknowledge the inevitability of this digital landfill what does this do to our definition of 'doing great work'?\n\n    Is great work inherent to the code? Is it our customer's results? Is it the teams we build? Is it anything to do with the output in the first place?\n  video_provider: \"not_recorded\"\n  video_id: \"andy-croll-ruby-on-ice-2018\"\n  slug: \"impermanence-of-software-ruby-on-ice-2018\"\n  id: \"andy-croll-ruby-on-ice-2018\"\n\n- title: \"Rails in the long run: Maintaining an app through the years\"\n  raw_title: \"Rails in the long run: Maintaining an app through the years\"\n  speakers:\n    - Mario Fernandez\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-28\"\n  description: |-\n    Everybody likes to work on the shiniest, newest stuff. But sometimes you have to maintain the existing legacy code that pays the bills.\n\n    I have spent four years working on an app that exists as a standalone rails project since 2009. It has gone through major rails and ruby updates and innumerable gem updates, while being actively developed. Achieving a healthy balance is crucial to avoid collapse through technical debt.\n  video_provider: \"not_recorded\"\n  video_id: \"mario-fernandez-ruby-on-ice-2018\"\n  slug: \"rails-in-the-long-run-ruby-on-ice-2018\"\n  id: \"mario-fernandez-ruby-on-ice-2018\"\n  slides_url: \"https://github.com/sirech/talks/blob/master/2018-01-rubyonice-maintainingrailsapps.pdf\"\n\n- title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  speakers:\n    - TODO\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-28\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-ruby-on-ice-2018\"\n  slug: \"lightning-talks-ruby-on-ice-2018\"\n  id: \"lightning-talks-ruby-on-ice-2018\"\n\n- title: \"Fortunately, maths!\"\n  raw_title: \"Fortunately, maths!\"\n  speakers:\n    - Tom Stuart @mortice\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-28\"\n  description: |-\n    A systematic approach to software engineering management\n\n    As engineers, we pride ourselves on building and continuously improving software systems that work. When it comes to organizing our teams and our working processes, though, we often leave this thinking at the door. In this talk, we'll look at the ways in which we can apply the mathematics of queues to design better ways to work together.\n  video_provider: \"not_recorded\"\n  video_id: \"tom-stuart-ruby-on-ice-2018\"\n  slug: \"fortunately-maths-ruby-on-ice-2018\"\n  id: \"tom-stuart-ruby-on-ice-2018\"\n  slides_url: \"https://docs.google.com/presentation/d/1vCZLtydVJzDUnJkVMU8u4QugIShzrvElm3duGmmEoB8/view\"\n\n- title: \"Compiling Ruby\"\n  raw_title: \"Compiling Ruby\"\n  speakers:\n    - Kevin Deisz\n  event_name: \"Ruby on Ice 2018\"\n  date: \"2018-01-28\"\n  description: |-\n    Since Ruby 2.3 and the introduction of RubyVM::InstructionSequence::load_iseq, we've been able to programmatically load ruby bytecode. By divorcing the process of running YARV byte code from the process of compiling ruby code, we can take advantage of the strengths of the ruby virtual machine while simultaneously reaping the benefits of a compiler such as macros, type checking, and instruction sequence optimizations. This can make our ruby faster and more readable! This talk demonstrates how to integrate this into your own workflows and the exciting possibilities this enables.\n  video_provider: \"not_recorded\"\n  video_id: \"kevin-deisz-ruby-on-ice-2018\"\n  slug: \"compiling-ruby-ruby-on-ice-2018\"\n  id: \"kevin-deisz-ruby-on-ice-2018\"\n  slides_url: \"https://speakerdeck.com/kddnewton/compiling-ruby\"\n"
  },
  {
    "path": "data/ruby-on-ice/ruby-on-ice-2019/event.yml",
    "content": "---\nid: \"PLClLcexm3Iukf--UcFDw_DgKhvKpQEOX-\"\ntitle: \"Ruby on Ice 2019\"\nkind: \"conference\"\nlocation: \"Tegernsee, Germany\"\ndescription: \"\"\npublished_at: \"2019-03-28\"\nstart_date: \"2019-02-22\"\nend_date: \"2019-02-24\"\nchannel_id: \"UCXNhwlbzt-6LoOzMt4wrF0A\"\nyear: 2019\nbanner_background: \"#6EB5CF\"\nfeatured_background: \"#6EB5CF\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2019.rubyonice.com/\"\ncoordinates:\n  latitude: 47.7130234\n  longitude: 11.7580899\n"
  },
  {
    "path": "data/ruby-on-ice/ruby-on-ice-2019/videos.yml",
    "content": "---\n# Website: https://rubyonice.com\n# Schedule: https://rubyonice.com/schedule\n\n## Day 1 - Friday\n\n- id: \"eileen-m-uchitelle-ruby-on-ice-2019\"\n  title: \"Keynote: The Past, Present, and Future of Rails at GitHub\"\n  raw_title: \"Ruby on Ice 2019 Keynote: The Past, Present, and Future of Rails at GitHub by Eileen Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-22\"\n  published_at: \"2019-04-02\"\n  slides_url: \"https://speakerdeck.com/eileencodes/ruby-on-ice-2019-the-past-present-and-future-of-rails-at-github\"\n  description: |-\n    On August 15, 2018 GitHub accomplished a great feat: upgrading our application from Rails 3.2 to 5.2. While this upgrade took a difficult year and a half your upgrade doesn't need to be this hard. In this talk we'll look at ways in which our upgrade was uniquely hard, how we accomplished this monumental task, and what we're doing to prevent hard upgrades in the future. We'll take a deep dive into why we upgraded Rails and our plans for upstreaming features from the GitHub application into the Rails framework.\n\n    Eileen M. Uchitelle is an Senior Systems Engineer on the Platform Systems Team at GitHub and a member of the Rails Core team. She's an avid contributor to open source focusing on the Ruby on Rails framework and its dependencies. Eileen is passionate about security, performance, and making open source communities more sustainable and welcoming.\n\n  video_provider: \"youtube\"\n  video_id: \"jxBAkhaRtNg\"\n\n- id: \"kinsey-ann-durham-ruby-on-ice-2019\"\n  title: \"Breaking the Chains of Oppressive Software\"\n  raw_title: \"Ruby on Ice 2019: Breaking the Chains of Oppressive Software by Kinsey Ann Durham\"\n  speakers:\n    - Kinsey Ann Durham\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-22\"\n  published_at: \"2019-04-02\"\n  description: |-\n    We have the power to stand up against oppression that exists in our software. Data discrimination, biases in algorithms, etc. are becoming an issue. You’ll learn about the biases we build, software that is bettering us and what you can do about it, as a developer, to truly make a difference.\n\n    Kinsey Ann Durham is an engineer at DigitalOcean working remotely in Denver, CO. She teaches students from around the globe how to write code through a program called Bloc. She co-founded a non-profit called Kubmo in 2013 that teaches and builds technology curriculum for women’s empowerment programs around the world. She, also, helps run the Scholar and Guide Program for Ruby Central conferences. In her free time, she enjoys fly fishing and adventuring in the Colorado outdoors with her dog, Harleigh.\n\n  video_provider: \"youtube\"\n  video_id: \"8atSI4k87X8\"\n\n## Day 2 - Saturday\n\n- id: \"carmen-huidobro-ruby-on-ice-2019\"\n  title: \"Hardware Hacking with Your Rails App\"\n  raw_title: \"Ruby on Ice 2019: Hardware Hacking with Your Rails App by Ramón Huidobro\"\n  speakers:\n    - Carmen Huidobro\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-23\"\n  published_at: \"2019-04-02\"\n  description: |-\n    When working on a Rails app with lots of users and a plethora of requests, you’ll likely soon be addressing how you can have dedicated custom hardware for them.\n    In this talk, I’ll go over my experiences and lessons learned from working on dedicated hardware for industrial catering services.\n\n    Carmen Huidobro is a chilean kids’ coding instructor and freelance software dev. She likes to introduce people to coding more than she enjoys coding itself. If you want pointless Nintendo trivia, look no further than Carmen! You’ll probably find her at a lot of conferences and has been told she has a distinctive laugh, so she’s easy to spot, especially when wearing a onesie.\n\n  video_provider: \"youtube\"\n  video_id: \"WoUL1pO99N8\"\n\n- id: \"betsy-haibel-ruby-on-ice-2019\"\n  title: \"Teach by Learning; Lead by Teaching\"\n  raw_title: \"Ruby on Ice 2019: Teach by Learning; Lead by Teaching by Betsy Haibel\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-23\"\n  published_at: \"2019-04-02\"\n  description: |-\n    Ever caught yourself dictating code to a junior dev, rather than pairing? Or resorted to saying “best practice”? Kill two birds with one stone: use “dialogic teaching,” an adult-education technique. Let’s turn “technical leadership” into a two-way process that surfaces tradeoffs and gets buy-in.\n\n    Betsy Haibel is the founding CTO of Cohere. She writes fiction and nonfiction in English, Ruby, and Javascript – among other languages – and co-organizes Learn Ruby in DC. Her lifelong ambitions? To meet a red panda, and to break down barriers between “developers” and “users.”\n\n  video_provider: \"youtube\"\n  video_id: \"hTXqhp084KE\"\n\n- id: \"joy-heron-ruby-on-ice-2019\"\n  title: \"Web Components: Designing Frontends for Reusability\"\n  raw_title: \"Ruby on Ice 2019: Web Components: Designing Frontends for Reusability by Joy Heron\"\n  speakers:\n    - Joy Heron\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-23\"\n  published_at: \"2019-04-02\"\n  description: |-\n    Have you ever tried to develop front end code that can be easily used in multiple projects? Reinventing the wheel is no fun. In this talk, I will use an example to share my design process for developing web components that are accessible, pretty, and most importantly easy to reuse.\n\n    Joy Heron is a consultant at INNOQ and develops software as a full-stack developer. She is passionate about developing responsive web applications using progressive enhancement and loves learning new things. Sketchnotes are a hobby.\n\n  video_provider: \"youtube\"\n  video_id: \"164EjUObiT4\"\n\n- id: \"anastasia-chicu-ruby-on-ice-2019\"\n  title: \"Improving Development Quality and Speed with Agile Testing\"\n  raw_title: \"Ruby on Ice 2019: Improving Development Quality and Speed with Agile Testing by Anastasia Chicu\"\n  speakers:\n    - Anastasia Chicu\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-23\"\n  published_at: \"2019-04-02\"\n  description: |-\n    Improving development quality and speed with agile testing\n    Releasing better software in ever shorter cycles demands an upgrade in testing. The talk shares techniques from an agile tester that will help you uncover risk early, improve product quality and build an approach to testing that includes your whole team. Ready? Let’s enhance your testing starting now!\n\n    Anna is an Senior Quality Assurance Engineer at Freeletics with over 5 years of digital experience. Since joining Freeletics she has coordinated testing activities, supported 4 development teams and worked closely with developers to build a quality culture. Her past experience as an Agile Tester at XING and before in an outsourcing company has helped her develop effective communication skills in her team and with other departments. Her obscure debate passion, on the other hand, determined her to trigger constructive discussions that add value to the product and process.-.\n\n  video_provider: \"youtube\"\n  video_id: \"RmJowZk5HVo\"\n\n- id: \"brittany-martin-ruby-on-ice-2019\"\n  title: \"Rails Against the Machine\"\n  raw_title: \"Ruby on Ice 2019: Rails Against the Machine by Brittany Martin\"\n  speakers:\n    - Brittany Martin\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-23\"\n  published_at: \"2019-04-02\"\n  description: |-\n    Rails Against the Machine\n    What should a development team do when a few bad users threaten their application? Online businesses are plagued with trolls and bots. Learn how your team can leverage features from RoR and AWS to monitor and (secretly) segment bad actors using automation and behavioral triggers.\n\n    Brittany Martin works for the Pittsburgh Cultural Trust as the nonprofit’s Lead Web Developer, where she is part of the team that develops, supports and maintains the Trust’s ticketing and festival web applications. Under her alter-ego, Norma Skates, Brittany plays and referees roller derby for the Little Steel Derby Girls. She tweets at @brittjmartin and is the host of the 5by5 Ruby on Rails podcast.\n\n  video_provider: \"youtube\"\n  video_id: \"bmIfkcAQEE8\"\n\n## Day 3 - Sunday\n\n- id: \"tobias-pfeiffer-ruby-on-ice-2019\"\n  title: \"Do You Need That Validation? Let Me Call You Back About It\"\n  raw_title: \"Ruby on Ice 2019: Do You Need That Validation? Let Me Call You Back About It by Tobias Pfeiffer\"\n  speakers:\n    - Tobias Pfeiffer\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-24\"\n  published_at: \"2019-04-02\"\n  description: |-\n    Rails apps start nice and cute. Fast forward a year and business logic and view logic are entangled in our validations and callbacks - getting in our way at every turn. Wasn’t this supposed to be easy?\n    Let’s explore different approaches to improve the situation and untangle the web.\n\n    Tobias Pfeiffer is a clean coder, Full Stack developer, Benchmarker by passion, Rubyist, Elixir fan, learner, teacher and agile crafter by passion. He organizes the Ruby User Group Berlin, maintains Shoes and benchee as well as contributing to a variety of projects while thinking about new ideas to put into code and push boundaries. He loves collaboratively creating just about anything people enjoy. Currently he’s creating wonderful web applications, most recently with Elixir and Phoenix refreshing his perspective on web applications.\n\n  video_provider: \"youtube\"\n  video_id: \"F05kXVqFWnc\"\n\n- id: \"benoit-daloze-ruby-on-ice-2019\"\n  title: \"Parallel and Thread-Safe Ruby at High-Speed with TruffleRuby\"\n  raw_title: \"Ruby on Ice 2019: Parallel and Thread-Safe Ruby at High-Speed with TruffleRuby by Benoit Daloze\"\n  speakers:\n    - Benoit Daloze\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-24\"\n  published_at: \"2019-04-02\"\n  description: |-\n    Array and Hash are used in every Ruby program, but current implementations either prevent to use them in parallel (MRI) or lack thread-safety guarantees (JRuby raises on concurrent Array#«). We show how to make Array and Hash thread-safe while allowing Ruby collections to scale up to tens of cores!\n\n    Benoit Daloze is a PhD student in Linz, Austria, researching concurrency in Ruby with TruffleRuby for the past several years. He has contributed to many Ruby implementations, including TruffleRuby, MRI and JRuby. He is the maintainer of ruby/spec, a test suite for the behavior of the Ruby programming language.\n\n  video_provider: \"youtube\"\n  video_id: \"DolpDFfPdh0\"\n\n- id: \"lightning-talks-ruby-on-ice-2019\"\n  title: \"Lightning Talks\"\n  raw_title: \"Ruby on Ice 2019: Lightning Talks\"\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-24\"\n  published_at: \"2019-07-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"7QgNDhtaQMQ\"\n  talks:\n    - title: \"Lightning Talk: Coming Out\"\n      start_cue: \"00:48\"\n      end_cue: \"05:44\"\n      id: \"ferdous-nasri-lighting-talk-ruby-on-ice-2019\"\n      video_id: \"ferdous-nasri-lighting-talk-ruby-on-ice-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Ferdous Nasri\n        - Kaja Santro\n\n    - title: \"Lightning Talk: How to Stream CSV Downloads\"\n      start_cue: \"06:15\"\n      end_cue: \"10:24\"\n      id: \"philipp-tessenow-lighting-talk-ruby-on-ice-2019\"\n      video_id: \"philipp-tessenow-lighting-talk-ruby-on-ice-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Philipp Tessenow\n\n    - title: \"Lightning Talk: Dance like nobody is watching\"\n      start_cue: \"10:36\"\n      end_cue: \"16:06\"\n      id: \"andy-schoenen-lighting-talk-ruby-on-ice-2019\"\n      video_id: \"andy-schoenen-lighting-talk-ruby-on-ice-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Andy Schoenen\n\n    - title: \"Lightning Talk: Know your Postgres data types\"\n      start_cue: \"16:08\"\n      end_cue: \"20:32\"\n      id: \"ben-fritsch-lighting-talk-ruby-on-ice-2019\"\n      video_id: \"ben-fritsch-lighting-talk-ruby-on-ice-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Ben Fritsch\n\n    - title: \"Lightning Talk: GDS, a new configuration and data definition language\"\n      start_cue: \"20:44\"\n      end_cue: \"26:44\"\n      id: \"uli-ramminger-lighting-talk-ruby-on-ice-2019\"\n      video_id: \"uli-ramminger-lighting-talk-ruby-on-ice-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Uli Ramminger\n\n    - title: \"Lightning Talk: Ruby without Rails\"\n      start_cue: \"26:55\"\n      end_cue: \"31:44\"\n      id: \"andrei-beliankou-lighting-talk-ruby-on-ice-2019\"\n      video_id: \"andrei-beliankou-lighting-talk-ruby-on-ice-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrei Beliankou\n\n    - title: \"Lightning Talk: HW & Machine Hacking with Ruby & Rails\"\n      start_cue: \"31:53\"\n      end_cue: \"37:29\"\n      id: \"jakub-malina-lighting-talk-ruby-on-ice-2019\"\n      video_id: \"jakub-malina-lighting-talk-ruby-on-ice-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Jakub Malina\n\n    - title: \"Lightning Talk: What's Wrong with Ruby?\"\n      start_cue: \"37:37\"\n      end_cue: \"42:55\"\n      id: \"amr-abdelwahab-lighting-talk-ruby-on-ice-2019\"\n      video_id: \"amr-abdelwahab-lighting-talk-ruby-on-ice-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Amr Abdelwahab\n\n- id: \"emily-stolfo-ruby-on-ice-2019\"\n  title: \"Beauty and the Beast: your application and distributed systems\"\n  raw_title: \"Ruby on Ice 2019: Beauty and the Beast: your application and distributed systems by Emily Stolfo\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-24\"\n  published_at: \"2019-04-02\"\n  description: |-\n    With more applications now using service-oriented architectures, developers must know how to talk to distributed technologies and to handle errors and failures. While you can usually depend on libraries to encapsulate such details, it's important to understand and to be able to predict the behavior of your distributed systems. This talk will arm you with algorithms and testing strategies so you can tame your services and build robust applications.\n\n    Emily Stolfo works at Elastic where she maintains the Ruby client and the Rails integrations project. She's also an adjunct faculty of Columbia University where she has taught courses on databases and web development. Although originally from New York, she's currently living in Berlin where she likes to run long distances and make sourdough bread.\n\n  video_provider: \"youtube\"\n  video_id: \"ex91n2XGes8\"\n\n- id: \"samuel-giddins-ruby-on-ice-2019\"\n  title: \"Making CocoaPods Fast with Modern Ruby Tooling\"\n  raw_title: \"Ruby on Ice 2019: Making CocoaPods Fast with Modern Ruby Tooling by Samuel Giddins\"\n  speakers:\n    - Samuel Giddins\n  event_name: \"Ruby on Ice 2019\"\n  date: \"2019-02-24\"\n  published_at: \"2019-04-02\"\n  description: |-\n    Writing performant code is hard. Writing performant ruby code that does lots of stuff is really hard. CocoaPods got to be pretty slow “at scale”, and this is the story of how we made our pod install times bearable again.\n\n    Samuel Giddins is a developer well-versed in the rituals of writing developer tools that occasionally work. By day, Samuel works on making the mobile developer experience at Square less arduous; by night he can be found breaking Bundler and CocoaPods. Before this whole “developer” thing, Samuel studied in the highly impractical Mathematics & Economics departments at UChicago, learning subjects such as “numbers”, “social theory”, and “memes”. When not coding, Samuel is often in the kitchen, marveling at the fact that dinner smells better than it looks.\n\n  video_provider: \"youtube\"\n  video_id: \"xMdUGh7x4so\"\n"
  },
  {
    "path": "data/ruby-on-ice/series.yml",
    "content": "---\nname: \"Ruby on Ice\"\nwebsite: \"https://rubyonice.com\"\ntwitter: \"rubyoniceconf\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"DE\"\nyoutube_channel_name: \"rubyonice7635\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCXNhwlbzt-6LoOzMt4wrF0A\"\n"
  },
  {
    "path": "data/ruby-on-rails-global-summit/ruby-on-rails-global-summit-2023/event.yml",
    "content": "---\nid: \"ruby-on-rails-global-summit-2023\"\ntitle: \"Ruby on Rails Global Summit 2023\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2023-01-24\"\nend_date: \"2023-01-25\"\nwebsite: \"https://events.geekle.us/ruby/\"\ntwitter: \"geekleofficial\"\ncoordinates: false\n"
  },
  {
    "path": "data/ruby-on-rails-global-summit/ruby-on-rails-global-summit-2023/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://events.geekle.us/ruby/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-on-rails-global-summit/series.yml",
    "content": "---\nname: \"Ruby on Rails Global Summit\"\nwebsite: \"https://events.geekle.us/ruby/\"\ntwitter: \"geekleofficial\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-on-rails-switzerland/railshock/event.yml",
    "content": "---\nid: \"railshöck\"\ntitle: \"Railshöck Meetup\"\nkind: \"meetup\"\nlocation: \"Zurich, Switzerland\"\ndescription: \"\"\npublished_at: \"2022-06-22\"\nyear: 2024\nbanner_background: \"#C90013\"\nfeatured_background: \"#C90013\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://www.meetup.com/rubyonrails-ch\"\ncoordinates:\n  latitude: 47.3768866\n  longitude: 8.541694\n"
  },
  {
    "path": "data/ruby-on-rails-switzerland/railshock/videos.yml",
    "content": "# 2010\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/14632894\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/14633038\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/14665391\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/14766731\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/15231980\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/15498298\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/15653069\n\n# 2011\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/15909990\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/15955701\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/16395638\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/16472299\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/16507244\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/16921114\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/17024837\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/17188468\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/16882769\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/17539326\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/14937058\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/17820471\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/20650631\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/22276051\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/23945591\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/24371231\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/26970671\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/29671311\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/29671321\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/29671351\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/35124912\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/36947632\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/39625282\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/41364612\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/42876402\n\n# 2012\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/45694662\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/46648982\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/49548042\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/51179682\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/54498232\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/57432762\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/57165652\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/60832542\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/61784192\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/64208592\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/66133362\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/68043662\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/71145932\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/72484412\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/72551662\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/78190882\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/80098992\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/81713512\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/84232532\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/86348722\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/86348762\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/86348752\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/86348772\n\n# 2013\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/94158272\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/94945372\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/94466542\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/94945552\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/94945612\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/99512912\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/94944872\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/108606452\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/108084932\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/111234032\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/112251582\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/118184392\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/118184092\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/118184662\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/119679872\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/124914332\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/134501672\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/137311992\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/138110932\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/138110992\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/138111042\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/144856852\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/147288632\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/151617722\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/151915582\n\n# 2014\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/155740132\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/155740172\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/94465462\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/155740192\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/161899872\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/162476152\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/162476442\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/164320172\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/165115262\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/165115342\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/165115382\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/165115442\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/165115482\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/184968102\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/184968772\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/190749122\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/190749222\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/190749152\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/190749232\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/185186732\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/190749322\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/206130982\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/206131002\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/206131012\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/206131022\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/206131032\n\n# 2015\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/206430572\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/206430602\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/219735348\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/220405320\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/220736583\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/220598303\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/220863006\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/220863013\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/220863022\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/220863024\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/222637099\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/222614500\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/223148049\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/220405317\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/223158476\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/223982577\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/224294108\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/226509995\n\n# 2016\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/227782171\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/228726508\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/229044868\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/228707432\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/230178460\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/231066966\n# TODO: missing event: https://www.meetup.com/rubyonrails-ch/events/233303155\n---\n- id: \"railshock-september-2016\"\n  title: \"Railshöck September 2016\"\n  raw_title: \"Railshöck @Simplificator\"\n  event_name: \"Railshöck September 2016\"\n  video_id: \"railshock-september-2016\"\n  video_provider: \"children\"\n  date: \"2016-09-14\"\n  description: |-\n    Dear all\n\n    We are looking forward to hearing a talk about Multitenancy with Rails.\n\n    Multitenancy is a way to architect software such that a single\n    application transparently serves multiple customers. Dimiter Petrov is going to present a case study of a project where multiple applications were consolidated into one and discuss:\n    * the advantages and disadvantages of multitenancy\n    * per-client data separation at the database level and file\n    * system level\n    * the configuration of mailers, background jobs, cache, etc.\n    * custom design and copy\n    * custom features\n\n    We hope to see you there! As usual there will be drinks and food as well.\n\n    https://www.meetup.com/rubyonrails-ch/events/233732199\n  talks:\n    - title: \"Multi-tenancy with Rails\"\n      raw_title: \"Railshöck @Simplificator\"\n      event_name: \"Railshöck September 2016\"\n      speakers:\n        - Dimiter Petrov\n      id: \"dimiter-petrov-railshock-september-2016\"\n      video_id: \"dimiter-petrov-railshock-september-2016\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://files.speakerdeck.com/presentations/654fc1a7e66f48b09910ef105eab254a/slide_0.jpg\"\n      thumbnail_sm: \"https://files.speakerdeck.com/presentations/654fc1a7e66f48b09910ef105eab254a/slide_0.jpg\"\n      thumbnail_md: \"https://files.speakerdeck.com/presentations/654fc1a7e66f48b09910ef105eab254a/slide_0.jpg\"\n      thumbnail_lg: \"https://files.speakerdeck.com/presentations/654fc1a7e66f48b09910ef105eab254a/slide_0.jpg\"\n      thumbnail_xl: \"https://files.speakerdeck.com/presentations/654fc1a7e66f48b09910ef105eab254a/slide_0.jpg\"\n      slides_url: \"https://speakerdeck.com/crackofdusk/multi-tenancy-with-rails\"\n      date: \"2016-09-14\"\n      description: |-\n        Dear all\n\n        We are looking forward to hearing a talk about Multitenancy with Rails.\n\n        Multitenancy is a way to architect software such that a single\n        application transparently serves multiple customers. Dimiter Petrov is going to present a case study of a project where multiple applications were consolidated into one and discuss:\n\n        * the advantages and disadvantages of multitenancy\n        * per-client data separation at the database level and file\n        * system level\n        * the configuration of mailers, background jobs, cache, etc.\n        * custom design and copy\n        * custom features\n\n        We hope to see you there! As usual there will be drinks and food as well.\n\n- id: \"railshock-november-2016\"\n  title: \"Railshöck November 2016\"\n  raw_title: \"Entering Elixir and Phoenix\"\n  event_name: \"Railshöck November 2016\"\n  date: \"2016-11-09\"\n  video_id: \"railshock-november-2016\"\n  video_provider: \"children\"\n  description: |-\n    At the next Railshöck on 09.11.2016 at Renuo AG we'll have a presentation about Elixir and Phoenix. Phoenix is a web development framework written in Elixir which implements the server-side MVC pattern. Many of its components and concepts will seem familiar to those of us with experience in other web frameworks like Ruby on Rails.\n\n    Phoenix provides the best of both worlds - high developer productivity and high application performance. It also has some interesting new twists like channels for implementing realtime features and pre-compiled templates for blazing speed.\n\n    https://www.meetup.com/rubyonrails-ch/events/235320092\n  talks:\n    - title: \"Entering Elixir and Phoenix\"\n      raw_title: 'Railshöck @Renuo \"Entering Elixir and Phoenix\"'\n      event_name: \"Railshöck November 2016\"\n      speakers:\n        - TODO\n      id: \"entering-elixir-and-phoenix-railshock-November-2016\"\n      video_id: \"entering-elixir-and-phoenix-railshock-November-2016\"\n      video_provider: \"not_recorded\"\n      date: \"2016-11-09\"\n      description: |-\n        At the next Railshöck on 09.11.2016 at Renuo AG we'll have a presentation about Elixir and Phoenix. Phoenix is a web development framework written in Elixir which implements the server-side MVC pattern. Many of its components and concepts will seem familiar to those of us with experience in other web frameworks like Ruby on Rails.\n\n        Phoenix provides the best of both worlds - high developer productivity and high application performance. It also has some interesting new twists like channels for implementing realtime features and pre-compiled templates for blazing speed.\n\n## 2017\n\n- id: \"railshock-february-2017\"\n  title: \"Railshöck February 2017\"\n  raw_title: \"Master21 - Switzerlands first coding bootcamp\"\n  event_name: \"Railshöck February 2017\"\n  date: \"2017-02-09\"\n  video_id: \"railshock-february-2017\"\n  video_provider: \"children\"\n  description: |-\n    In the US, coding bootcamps currently provide a viable and cheaper alternative to the traditional college- / university-education models. But bootcamps also raise a lot of questions. Do they work in a country like Switzerland where education usually does not come with a price-tag? Is it really possible to get a complete beginner \"job ready\" within 9 weeks? And what are Software companies expecting when they hire an intern or \"junior\" developer?\n\n    Should being able to join a company as a full-time dev really be the goal after graduation? Or are we inherently ignoring more favourable outcomes that coding bootcamps can bring?\n\n    During his presentation, Rodrigo will try to shed some light on these questions and talk about the philosophy, personal experiences and insights that went into designing the Master21 curriculum.\n\n    This Railshöck takes place at Impact Hub Zürich (location: Colab at Sihlquai 131, 8005 Zurich): The global community of entrepreneurial people prototyping the future of business. At Impact Hub, you can connect, collaborate, co-work and create great content in an inspiring environment.\n\n    https://www.meetup.com/rubyonrails-ch/events/237220479\n  talks:\n    - title: \"Master21 - Switzerlands first coding bootcamp\"\n      raw_title: \"Master21 - Switzerlands first coding bootcamp\"\n      event_name: \"Railshöck February 2017\"\n      speakers:\n        - Rodrigo Haenggi\n      id: \"rodrigo-haenggi-railshock-february-2017\"\n      video_id: \"rodrigo-haenggi-railshock-february-2017\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://files.speakerdeck.com/presentations/d3c47d62d8ec49ad875933290569e1ce/slide_0.jpg\"\n      thumbnail_sm: \"https://files.speakerdeck.com/presentations/d3c47d62d8ec49ad875933290569e1ce/slide_0.jpg\"\n      thumbnail_md: \"https://files.speakerdeck.com/presentations/d3c47d62d8ec49ad875933290569e1ce/slide_0.jpg\"\n      thumbnail_lg: \"https://files.speakerdeck.com/presentations/d3c47d62d8ec49ad875933290569e1ce/slide_0.jpg\"\n      thumbnail_xl: \"https://files.speakerdeck.com/presentations/d3c47d62d8ec49ad875933290569e1ce/slide_0.jpg\"\n      slides_url: \"https://speakerdeck.com/therod/master21-teaching-philosophy\"\n      date: \"2017-02-09\"\n      description: |-\n        In the US, coding bootcamps currently provide a viable and cheaper alternative to the traditional college- / university-education models. But bootcamps also raise a lot of questions. Do they work in a country like Switzerland where education usually does not come with a price-tag? Is it really possible to get a complete beginner \"job ready\" within 9 weeks? And what are Software companies expecting when they hire an intern or \"junior\" developer?\n\n        Should being able to join a company as a full-time dev really be the goal after graduation? Or are we inherently ignoring more favourable outcomes that coding bootcamps can bring?\n\n        During his presentation, Rodrigo will try to shed some light on these questions and talk about the philosophy, personal experiences and insights that went into designing the Master21 curriculum.\n\n        This Railshöck takes place at Impact Hub Zürich (location: Colab at Sihlquai 131, 8005 Zurich): The global community of entrepreneurial people prototyping the future of business. At Impact Hub, you can connect, collaborate, co-work and create great content in an inspiring environment.\n\n- id: \"railshock-march-2017\"\n  title: \"Railshöck March 2017\"\n  raw_title: \"Ruby on Rails 5.1\"\n  event_name: \"Railshöck March 2017\"\n  date: \"2017-03-29\"\n  video_id: \"railshock-march-2017\"\n  video_provider: \"children\"\n  description: |-\n    Yves Senn will talk about the upcoming Rails Release 5.1 and give an overview about news and changes.\n\n    https://www.meetup.com/rubyonrails-ch/events/238380173\n  talks:\n    - title: \"Ruby on Rails 5.1\"\n      raw_title: \"Ruby on Rails 5.1\"\n      event_name: \"Railshöck March 2017\"\n      speakers:\n        - Yves Senn\n      id: \"yves-senn-railshck-march-2017\"\n      video_id: \"_PPvjk3Fp7U\"\n      published_at: \"2017-04-03\"\n      video_provider: \"youtube\"\n      date: \"2017-03-29\"\n      description: |-\n        Yves Senn will talk about the upcoming Rails Release 5.1 and give an overview about news and changes.\n\n- id: \"railshock-may-2017\"\n  title: \"Railshöck May 2017\"\n  raw_title: \"Ruby on Rails - Request/Response Cycle\"\n  event_name: \"Railshöck May 2017\"\n  date: \"2017-05-24\"\n  video_id: \"railshock-may-2017\"\n  video_provider: \"children\"\n  description: |-\n    We are very happy to have Thomas Arni presenting his talk about Ruby on Rails - Request/Response Cycle.\n\n    https://www.meetup.com/rubyonrails-ch/events/239847831\n  talks:\n    - title: \"Ruby on Rails - Request/Response Cycle\"\n      raw_title: \"Ruby on Rails - Request/Response Cycle\"\n      event_name: \"Railshöck May 2017\"\n      speakers:\n        - Thomas Arni\n      id: \"thomas-arni-railshock-may-2017\"\n      video_id: \"thomas-arni-railshock-may-2017\"\n      video_provider: \"not_recorded\"\n      date: \"2017-05-24\"\n      description: |-\n        We are very happy to have Thomas Arni presenting his talk about Ruby on Rails - Request/Response Cycle.\n\n- id: \"railshock-june-2017\"\n  title: \"Railshöck June 2017\"\n  raw_title: \"Writing a Ruby Testing Framework from Scratch\"\n  event_name: \"Railshöck June 2017\"\n  date: \"2017-06-21\"\n  video_id: \"railshock-june-2017\"\n  video_provider: \"children\"\n  description: |-\n    In this live coding session, I implement assertions using fundamental concepts of the Ruby programming language, then create a test runner.\n\n    I spend some time on testing the framework using itself.\n\n    The final result is a small library which is used similarly to Ruby's minitest.\n\n    Blog post: https://dimiterpetrov.com/blog/self-testing-test-library\n    Source code: https://github.com/crackofdusk/raisin\n\n    https://www.meetup.com/rubyonrails-ch/events/240837783\n  talks:\n    - title: \"Writing a Ruby Testing Framework from Scratch\"\n      raw_title: \"Writing a Ruby Testing Framework from Scratch\"\n      event_name: \"Railshöck June 2017\"\n      speakers:\n        - Dimiter Petrov\n      id: \"dimiter-petrov-railshck-june-2017\"\n      video_id: \"IuYNTGA0C4g\"\n      published_at: \"2017-06-22\"\n      video_provider: \"youtube\"\n      date: \"2017-06-21\"\n      description: |-\n        In this live coding session, I implement assertions using fundamental concepts of the Ruby programming language, then create a test runner.\n\n        I spend some time on testing the framework using itself.\n\n        The final result is a small library which is used similarly to Ruby's minitest.\n\n        Blog post: https://dimiterpetrov.com/blog/self-testing-test-library\n        Source code: https://github.com/crackofdusk/raisin\n      additional_resources:\n        - name: \"crackofdusk/raisin\"\n          type: \"repo\"\n          url: \"https://github.com/crackofdusk/raisin\"\n\n        - name: \"Blog Post\"\n          title: \"A Self-Testing Test Library\"\n          type: \"repo\"\n          url: \"https://dimiterpetrov.com/blog/self-testing-test-library\"\n\n- id: \"railshock-august-2017\"\n  title: \"Railshöck August 2017\"\n  raw_title: \"Railshöck August 2017\"\n  event_name: \"Railshöck August 2017\"\n  date: \"2017-08-16\"\n  video_id: \"railshock-august-2017\"\n  video_provider: \"children\"\n  description: |-\n    Dear all\n\n    The next Railshöck will take place at Renuo AG in Wallisellen. The following talks will be held:\n\n    • Josua Schmid about \"Rails Routing Mapper\"\n\n    • Richi Bützer about \"Idiomatic RSpec\"\n\n    • Martin Cavoj about \"News in Rails 5.2: ActiveStorage\"\n\n    • Denis Müller about \"Session Replay Attacks\"\n\n    Drinks and snacks are on us :-)\n\n    https://www.meetup.com/rubyonrails-ch/events/242035630\n  talks:\n    - title: \"Rails Routing Mapper - Investigating a Bit\"\n      raw_title: \"Rails Routing Mapper by Josua Schmid\"\n      event_name: \"Railshöck August 2017\"\n      speakers:\n        - \"Josua Schmid\"\n      id: \"josua-schmid-railshock-august-2017\"\n      video_id: \"josua-schmid-railshock-august-2017\"\n      video_provider: \"not_recorded\"\n      date: \"2017-08-16\"\n      slides_url: \"https://docs.google.com/presentation/d/16oTEHnOOITv5_wwrkwH3tdJbZ9BLMRwdLoZuZEXFAgc/edit\"\n      description: |-\n        Josua Schmid looks into the Rails Routing Mapper, explaining its features and how to leverage it for effective routing in Rails.\n\n    - title: \"Idiomatic RSpec tests - How I keep my tests DRY and readable\"\n      raw_title: \"Idiomatic RSpec by Richard Bützer\"\n      event_name: \"Railshöck August 2017\"\n      speakers:\n        - Richard Bützer\n      id: \"richi-butzer-railshock-august-2017\"\n      video_id: \"richi-butzer-railshock-august-2017\"\n      video_provider: \"not_recorded\"\n      date: \"2017-08-16\"\n      slides_url: \"https://docs.google.com/presentation/d/1Ni5AFZyh6YgawJR8gZyBrW00_abdNCcVRNn5WlPQ5DI/edit\"\n      description: |-\n        Richard Bützer discusses best practices for writing idiomatic RSpec tests, focusing on clean, readable, and maintainable test suites.\n\n    - title: \"News in Rails 5.2 - ActiveStorage\"\n      raw_title: \"News in Rails 5.2: ActiveStorage by Martin Cavoj\"\n      event_name: \"Railshöck August 2017\"\n      speakers:\n        - \"Martin Cavoj\"\n      id: \"martin-cavoj-railshock-august-2017\"\n      video_id: \"martin-cavoj-railshock-august-2017\"\n      video_provider: \"not_recorded\"\n      date: \"2017-08-16\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/4/8/6/highres_478625254.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/4/8/6/highres_478625254.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/4/8/6/highres_478625254.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/4/8/6/highres_478625254.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/4/8/6/highres_478625254.webp\"\n      slides_url: \"https://docs.google.com/presentation/d/19J5BjUZiBSB611ieqIEJnQAwMUtHy7jqPoKfDrH2dIY/edit\"\n      description: |-\n        Martin Cavoj highlights the features of ActiveStorage introduced in Rails 5.2 and demonstrates.\n\n    - title: \"Session Replay Attacks\"\n      raw_title: \"Session Replay Attacks by Denis Müller\"\n      event_name: \"Railshöck August 2017\"\n      speakers:\n        - \"Denis Müller\"\n      id: \"denis-muller-railshock-august-2017\"\n      video_id: \"denis-muller-railshock-august-2017\"\n      video_provider: \"not_recorded\"\n      date: \"2017-08-16\"\n      description: |-\n        Denis Müller explains the risks of session replay attacks and provides strategies for protecting Rails applications against them.\n\n- id: \"railshock-september-2017\"\n  title: \"Railshöck September 2017\"\n  raw_title: \"Swift for Rubyists\"\n  event_name: \"Railshöck September 2017\"\n  date: \"2017-09-20\"\n  video_id: \"railshock-september-2017\"\n  video_provider: \"children\"\n  description: |-\n    Andy Park will talk about \"Swift for Rubyists\".\n\n    https://www.meetup.com/rubyonrails-ch/events/243296452\n  talks:\n    - title: \"Swift for Rubyists\"\n      raw_title: \"Swift for Rubyists\"\n      event_name: \"Railshöck September 2017\"\n      speakers:\n        - Andy Park\n      id: \"andy-park-railshock-september-2017\"\n      video_id: \"andy-park-railshock-september-2017\"\n      video_provider: \"not_recorded\"\n      date: \"2017-09-20\"\n      description: |-\n        Andy Park will talk about \"Swift for Rubyists\".\n\n## 2018\n\n- id: \"railshock-january-2018\"\n  title: \"Railshöck January 2018\"\n  raw_title: \"Railshöck January 2018\"\n  event_name: \"Railshöck January 2018\"\n  date: \"2018-01-31\"\n  video_id: \"railshock-january-2018\"\n  video_provider: \"children\"\n  description: |-\n    Welcome to the year 2018!\n\n    We'd like to get together at Renuo for a set of interesting presentations once more:\n\n    Goodbye Sprockets (Alessandro Rodi):\n    Alessandro is a software engineer and leads our education program. He will tell you why Sprockets are from the past and how we can move on with Webpacker.\n\n    Testing with Cucumber (Richard Bützer):\n    Richard is a software engineer at Renuo. He will tell you, why we have added yet another layer to our testing infrastructure.\n\n    Systematically speeding up your tests (Stéphane Bisinger):\n    Stéphane is a software engineer and is responsible for our smooth operations. He will show you how to look at your tests to easily spot speed improvement potential.\n\n    Simple & flexible Rails-API's with GraphQL (Denis Müller):\n    Denis is one of our three IMS interns. He will tell you something about GraphQL and how it can make your life easier.\n\n    As always, drinks and snacks are on us :-)\n\n    https://www.meetup.com/rubyonrails-ch/events/245854022\n  talks:\n    - title: \"Goodbye Sprockets - Welcome Webpacker\"\n      raw_title: \"Goodbye Sprockets by Alessandro Rodi\"\n      event_name: \"Railshöck January 2018\"\n      speakers:\n        - \"Alessandro Rodi\"\n      id: \"alessandro-rodi-railshck-january-2018\"\n      video_id: \"I_GGYIWbmg0\"\n      published_at: \"2018-02-01\"\n      video_provider: \"youtube\"\n      date: \"2018-01-31\"\n      slides_url: \"https://docs.google.com/presentation/d/1lnhiMF4JT9nPU3XGGSVfL_4jQKhoumd9YpYYNedFp04/edit\"\n      description: |-\n        Alessandro explains why Sprockets are outdated and how to transition to Webpacker for a modern asset pipeline.\n\n    - title: \"Testing with Cucumber\"\n      raw_title: \"Testing with Cucumber by Richard Bützer\"\n      event_name: \"Railshöck January 2018\"\n      speakers:\n        - \"Richard Bützer\"\n      id: \"richard-butzer-railshock-january-2018\"\n      video_id: \"richard-butzer-railshock-january-2018\"\n      video_provider: \"not_published\"\n      date: \"2018-01-31\"\n      slides_url: \"https://docs.google.com/presentation/d/1YdFoFd_hmat-nbEk5Sc-fmDO112sqtkQbfLDh5eQFGM/edit\"\n      description: |-\n        Richard discusses the benefits of adding Cucumber to the testing stack, highlighting its usefulness in bridging gaps between stakeholders.\n\n    - title: \"Getting Lightning Fast - Optimizing Your Test Suite for Speed\"\n      raw_title: \"Systematically Speeding Up Your Tests by Stéphane Bisinger\"\n      event_name: \"Railshöck January 2018\"\n      speakers:\n        - \"Stéphane Bisinger\"\n      id: \"stephane-bisinger-railshock-january-2018\"\n      video_id: \"stephane-bisinger-railshock-january-2018\"\n      video_provider: \"not_published\"\n      date: \"2018-01-31\"\n      slides_url: \"https://docs.google.com/presentation/d/1qIULhJDb63AsHl5qkVRlFLAwj0HZLgmjETRjP3Wgb5Y/edit\"\n      description: |-\n        Stéphane shows systematic ways to identify bottlenecks and improve the speed of your test suite for more efficient development.\n\n    - title: \"Simple & flexible Rails-APIs with GraphQL\"\n      raw_title: \"Simple & Flexible Rails APIs with GraphQL by Denis Müller\"\n      event_name: \"Railshöck January 2018\"\n      speakers:\n        - \"Denis Müller\"\n      id: \"denis-mller-railshck-january-2018\"\n      video_id: \"z1bavd3TAAg\"\n      published_at: \"2018-02-01\"\n      video_provider: \"youtube\"\n      date: \"2018-01-31\"\n      slides_url: \"https://docs.google.com/presentation/d/1y_qflnM9mVyyaV5SnJ-dJm7Jt1ZrNTBtmPfqksKcLCA/edit\"\n      description: |-\n        Denis introduces GraphQL and demonstrates how it simplifies building flexible and efficient APIs in Rails.\n\n- id: \"railshock-june-2018\"\n  title: \"Railshöck June 2018\"\n  raw_title: \"Railshöck June 2018\"\n  event_name: \"Railshöck June 2018\"\n  date: \"2018-06-20\"\n  video_id: \"railshock-june-2018\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/2/e/5/5/highres_471731861.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/2/e/5/5/highres_471731861.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/2/e/5/5/highres_471731861.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/2/e/5/5/highres_471731861.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/2/e/5/5/highres_471731861.webp?w=750\"\n  description: |-\n    Do you need a cool summer breeze because everything gets too hot?\n\n    We'd like to get together at Renuo for a set of fresh and handmade presentations once more:\n\n    Hot module reloading (Alessandro Rodi):\n    Alessandro is a software engineer and leads our education program. He fell in love with Webpacker and tells you how to ride the JS wave without being afraid of derailment.\n\n    CSP - Water wings for our users (Martin Cavoj):\n    Martin is a software engineer at Renuo. He will tell you, how we started using Content Security Policy in our Rails apps and how we reacted to an incoming hurricane.\n\n    Rails 6 Preview (Simon Huber)\n    Simon is a software engineer at Renuo. He will explain you some of the fresh features of Rails, for example about how to sail with multiple ships at the same time.\n\n    Percy.io (Lukas Bischof)\n    Lukas is an intern at Renuo. He explains you how we improved our code review process with screenshots. Visual cortex on deck!\n\n    As always, drinks and snacks are on us :-)\n\n    https://www.meetup.com/rubyonrails-ch/events/251398920\n  talks:\n    - title: \"Hot Module Reloading\"\n      raw_title: \"Hot Module Reloading by Alessandro Rodi\"\n      event_name: \"Railshöck June 2018\"\n      speakers:\n        - \"Alessandro Rodi\"\n      id: \"alessandro-rodi-railshck-june-2018\"\n      video_id: \"P5-SJnEf5TU\"\n      published_at: \"2018-06-21\"\n      video_provider: \"youtube\"\n      date: \"2018-06-20\"\n      description: |-\n        Alessandro is a software engineer and leads our education program. He fell in love with Webpacker and tells you how to ride the JS wave without being afraid of derailment.\n\n    - title: \"CSP - Water Wings for Our Users\"\n      raw_title: \"CSP - Water Wings for Our Users by Martin Cavoj\"\n      event_name: \"Railshöck June 2018\"\n      speakers:\n        - \"Martin Cavoj\"\n      id: \"martin-cavoj-railshock-june-2018\"\n      video_id: \"martin-cavoj-railshock-june-2018\"\n      video_provider: \"not_recorded\"\n      date: \"2018-06-20\"\n      description: |-\n        Martin is a software engineer at Renuo. He will tell you, how we started using Content Security Policy in our Rails apps and how we reacted to an incoming hurricane.\n\n    - title: \"Rails 6 Preview\"\n      raw_title: \"Rails 6 Preview by Simon Huber\"\n      event_name: \"Railshöck June 2018\"\n      speakers:\n        - \"Simon Huber\"\n      id: \"simon-huber-railshock-june-2018\"\n      video_id: \"simon-huber-railshock-june-2018\"\n      video_provider: \"not_recorded\"\n      date: \"2018-06-20\"\n      description: |-\n        Simon is a software engineer at Renuo. He will explain you some of the fresh features of Rails, for example about how to sail with multiple ships at the same time.\n\n    - title: \"Improving Code Review with Percy.io\"\n      raw_title: \"Improving Code Review with Percy.io by Lukas Bischof\"\n      event_name: \"Railshöck June 2018\"\n      speakers:\n        - \"Lukas Bischof\"\n      id: \"lukas-bischof-railshck-june-2018\"\n      video_id: \"nzeBhyru8u0\"\n      published_at: \"2018-06-21\"\n      video_provider: \"youtube\"\n      date: \"2018-06-20\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/4/2/a/highres_478625162.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/4/2/a/highres_478625162.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/4/2/a/highres_478625162.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/4/2/a/highres_478625162.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/4/2/a/highres_478625162.webp\"\n      description: |-\n        Lukas is an intern at Renuo. He explains you how we improved our code review process with screenshots. Visual cortex on deck!\n\n## 2019\n\n- id: \"railshock-january-2019\"\n  title: \"Railshöck January 2019\"\n  raw_title: \"Parallel and Thread-Safe Ruby at High-Speed with TruffleRuby\"\n  event_name: \"Railshöck January 2019\"\n  date: \"2019-01-29\"\n  video_id: \"railshock-january-2019\"\n  video_provider: \"children\"\n  description: |-\n    Array and Hash are used in every Ruby program. Yet, current implementations either prevent the use of them in parallel (the global interpreter lock in MRI) or lack thread-safety guarantees (JRuby raises an exception on concurrent Array#<<). Concurrent::Array from concurrent-ruby is thread-safe but prevents parallel access.\n\n    This talk starts with an introduction to show how TruffleRuby works and then shows a technique to make Array and Hash thread-safe while enabling parallel access, with no penalty on single-threaded performance. In short, we keep the most important thread-safety guarantees of the global lock while allowing Ruby to scale up to tens of cores!\n\n    https://www.meetup.com/rubyonrails-ch/events/258090195\n  talks:\n    - title: \"Parallel and Thread-Safe Ruby at High-Speed with TruffleRuby\"\n      raw_title: \"Parallel and Thread-Safe Ruby at High-Speed with TruffleRuby\"\n      event_name: \"Railshöck January 2019\"\n      speakers:\n        - Benoit Daloze\n      id: \"benoit-daloze-railshck-january-2019\"\n      video_id: \"Ll0uVIHkFdo\"\n      published_at: \"2019-01-30\"\n      video_provider: \"youtube\"\n      date: \"2019-01-29\"\n      description: |-\n        Array and Hash are used in every Ruby program. Yet, current implementations either prevent the use of them in parallel (the global interpreter lock in MRI) or lack thread-safety guarantees (JRuby raises an exception on concurrent Array#<<). Concurrent::Array from concurrent-ruby is thread-safe but prevents parallel access.\n\n        This talk starts with an introduction to show how TruffleRuby works and then shows a technique to make Array and Hash thread-safe while enabling parallel access, with no penalty on single-threaded performance. In short, we keep the most important thread-safety guarantees of the global lock while allowing Ruby to scale up to tens of cores!\n\n- id: \"railshock-april-2019\"\n  title: \"Railshöck April 2019\"\n  raw_title: \"Railshöck April 2019\"\n  event_name: \"Railshöck April 2019\"\n  date: \"2019-04-17\"\n  video_id: \"railshock-april-2019\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/highres_480484247.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/highres_480484247.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/highres_480484247.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/highres_480484247.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/highres_480484247.webp?w=750\"\n  description: |-\n    Multiple talks at this event:\n\n    https://www.meetup.com/rubyonrails-ch/events/259150790\n  talks:\n    - title: \"Can x3\"\n      raw_title: \"CanCanCan 3.0 Deep Dive by Alessandro Rodi\"\n      event_name: \"Railshöck April 2019\"\n      speakers:\n        - \"Alessandro Rodi\"\n      id: \"alessandro-rodi-railshock-april-2019\"\n      video_id: \"alessandro-rodi-railshock-april-2019\"\n      video_provider: \"not_recorded\"\n      date: \"2019-04-17\"\n      slides_url: \"https://docs.google.com/presentation/d/1info2uufN4rjujFjGiLfx8NwfYgBeBlXXGdvg16yTD4/edit\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      description: |-\n        CanCanCan 3.0 is out. Let's deep dive in the new features and how this version improves performance by removing associations preloading and by implementing a \"rules compressor\" which removes unnecessary rules automatically.\n\n    - title: \"Smart HTTP Clients\"\n      raw_title: \"Smart HTTP Clients by Sebastian Pape\"\n      event_name: \"Railshöck April 2019\"\n      speakers:\n        - \"Sebastian Pape\"\n      id: \"sebastian-pape-railshock-april-2019\"\n      video_id: \"sebastian-pape-railshock-april-2019\"\n      video_provider: \"not_recorded\"\n      date: \"2019-04-17\"\n      slides_url: \"https://drive.google.com/file/d/1uGXvDPiKeWfucxZ12_7rULETv_-23TaC/view\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      description: |-\n        What if you could use Rails ActiveRecord over the network? Actually you can, thanks to the ruby gem LHS. Get some big thoughts about how to easily navigate a heterogeneous enterprise api service landscape with smart HTTP clients.\n\n    - title: \"Input from Another World\"\n      raw_title: \"Input from Another World by Samuel Steiner\"\n      event_name: \"Railshöck April 2019\"\n      speakers:\n        - \"Samuel Steiner\"\n      id: \"samuel-steiner-railshock-april-2019\"\n      video_id: \"samuel-steiner-railshock-april-2019\"\n      video_provider: \"not_recorded\"\n      date: \"2019-04-17\"\n      slides_url: \"https://docs.google.com/presentation/d/1a3Iz8YdqW9YiVJ81DkQW_9Sp5A5hkyLTCNbGgZX1SuE/edit\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      description: |-\n        And now for something completely different: This is an introduction of how to overcome politeness façades towards more honest conversations. Get some tips on how to steer a conversation into a direction which benefits all participants the most – both in sales but also personal relationships.\n\n    - title: \"The RSpec includes Matcher in Depth\"\n      raw_title: \"The RSpec includes Matcher in Depth by Josua Schmid\"\n      event_name: \"Railshöck April 2019\"\n      speakers:\n        - \"Josua Schmid\"\n      id: \"josua-schmid-railshock-april-2019\"\n      video_id: \"josua-schmid-railshock-april-2019\"\n      video_provider: \"not_recorded\"\n      date: \"2019-04-17\"\n      slides_url: \"https://drive.google.com/file/d/1QI3k0isdLxf0tSX11GwmBbYfZTJ86wcT/view?usp=sharing\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/0/9/7/600_480484247.webp\"\n      description: |-\n        We'll examine together how one specific RSpec matcher came into existence and how it works in detail. Expect to see some software design patterns and application examples.\n\n        Source code: https://github.com/renuo/railshoeck-rspec-include-matcher\n      additional_resources:\n        - name: \"renuo/railshoeck-rspec-include-matcher\"\n          type: \"repo\"\n          url: \"https://github.com/renuo/railshoeck-rspec-include-matcher\"\n\n- id: \"railshock-december-2019\"\n  title: \"Railshöck December 2019\"\n  raw_title: \"Icecast Stream Parsing\"\n  event_name: \"Railshöck December 2019\"\n  date: \"2019-12-04\"\n  video_id: \"railshock-december-2019\"\n  video_provider: \"children\"\n  description: |-\n    Swiss artists registered on mx3.ch get notified when their songs are played on the radio. How does one get airplay information from arbitrary radio streams? How is it matched against a database of songs?\n\n    In this presentation, we are going to see the challenges encountered while building a production-ready airplay matching system, including:\n\n    * writing a Ruby parser for the Icecast protocol from scratch\n    * working around peculiarities in Net::HTTP\n    * threading, queues and ActiveRecord connection pools\n    * gracefully handling network errors\n    * fuzzy matching with PostgreSQL\n\n    https://www.meetup.com/rubyonrails-ch/events/266309675\n  talks:\n    - title: \"Icecast Stream Parsing\"\n      raw_title: \"Icecast Stream Parsing\"\n      event_name: \"Railshöck December 2019\"\n      speakers:\n        - Dimiter Petrov\n      id: \"dimiter-petrov-railshck-december-2019\"\n      video_id: \"V5X_J0hTkVY\"\n      published_at: \"2019-12-05\"\n      video_provider: \"youtube\"\n      date: \"2019-12-04\"\n      description: |-\n        Swiss artists registered on mx3.ch get notified when their songs are played on the radio. How does one get airplay information from arbitrary radio streams? How is it matched against a database of songs?\n\n        In this presentation, we are going to see the challenges encountered while building a production-ready airplay matching system, including:\n\n        * writing a Ruby parser for the Icecast protocol from scratch\n        * working around peculiarities in Net::HTTP\n        * threading, queues and ActiveRecord connection pools\n        * gracefully handling network errors\n        * fuzzy matching with PostgreSQL\n\n## 2020\n\n- id: \"railshock-october-2020\"\n  title: \"Railshöck October 2020\"\n  raw_title: \"Railshöck October 2020\"\n  event_name: \"Railshöck October 2020\"\n  date: \"2020-10-07\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/highres_492819460.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/highres_492819460.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/highres_492819460.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/highres_492819460.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/highres_492819460.webp?w=750\"\n  video_id: \"railshock-october-2020\"\n  video_provider: \"children\"\n  description: |-\n    We prepared four short presentations for you about intimate tech details of Renuo. We focus on detours and shortcuts this time.\n\n    100 ways to search (Simon & Simon)\n    The two Simons give us a rough overview about different ways how to implement a search in your rails project.\n\n    How to NOT search (Alessandro Rodi)\n    We optimized the performance of a search without relying on a search engine, saving costs and focusing on the business-side rather than the technical-side of the Web Application.\n\n    How NOT to find (Josua Schmid)\n    We built a usable search – we thought… Then suddenly there were five times more data to search through. This lead to a usability nightmare which made us reconsider.\n\n    Decorators & Co. (Gregor Wassmann)\n    Rails concerns? No, not this time. Gregor leads the IT at Hoelzle in Bubikon and has stories to tell about how he's modernizing the software of a parts trading company.\n\n    As always, drinks and snacks are on us :-)\n\n    https://www.meetup.com/rubyonrails-ch/events/269970094\n  talks:\n    - title: \"A hundred ways to search - An (opinionated) overview about search techniques\"\n      raw_title: \"100 Ways to Search by Simon & Simon\"\n      event_name: \"Railshöck October 2020\"\n      speakers:\n        - \"Simon Huber\"\n        - \"Simon Isler\"\n      id: \"simon-simon-railshock-october-2020\"\n      video_id: \"simon-simon-railshock-october-2020\"\n      video_provider: \"not_recorded\"\n      date: \"2020-10-07\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      slides_url: \"https://docs.google.com/presentation/d/16TdVhrDSKGeEZnhAf6Fz8t59oAuXPgtvFNI-Du6g0xk/edit\"\n      description: |-\n        The two Simons provide an overview of various methods for implementing search functionality in a Rails project.\n\n    - title: \"How to NOT Search\"\n      raw_title: \"How to NOT Search by Alessandro Rodi\"\n      event_name: \"Railshöck October 2020\"\n      speakers:\n        - \"Alessandro Rodi\"\n      id: \"alessandro-rodi-railshock-october-2020\"\n      video_id: \"alessandro-rodi-railshock-october-2020\"\n      video_provider: \"not_recorded\"\n      date: \"2020-10-07\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      slides_url: \"https://drive.google.com/file/d/1Ub-rsPrbvVtgLHnvJLSOP80my4mGaA0Q/view\"\n      description: |-\n        Alessandro shares insights on optimizing search performance without a search engine, focusing on business needs over technical solutions.\n\n    - title: \"How NOT to Find\"\n      raw_title: \"How NOT to Find by Josua Schmid\"\n      event_name: \"Railshöck October 2020\"\n      speakers:\n        - \"Josua Schmid\"\n      id: \"josua-schmid-railshock-october-2020\"\n      video_id: \"josua-schmid-railshock-october-2020\"\n      video_provider: \"not_recorded\"\n      date: \"2020-10-07\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      slides_url: \"https://docs.google.com/presentation/d/1r_Eu-N75Fgq2Gh1P-EcdhdVoyAxMuiNm9_bgqkY_ygo/edit\"\n      description: |-\n        Josua reflects on building a seemingly usable search that struggled under increased data load, leading to a usability overhaul.\n\n    - title: \"Decorators & Co\"\n      raw_title: \"Decorators & Co. Instead of Concerns by Gregor Wassmann\"\n      event_name: \"Railshöck October 2020\"\n      speakers:\n        - \"Gregor Wassmann\"\n      id: \"gregor-wassmann-railshock-october-2020\"\n      video_id: \"gregor-wassmann-railshock-october-2020\"\n      video_provider: \"not_recorded\"\n      date: \"2020-10-07\"\n      slides_url: \"https://drive.google.com/file/d/1lKhxRYVqT-qKcbCUD6zWWaCo3zr9VwZB/view\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/a/2/4/600_492819460.webp\"\n      description: |-\n        Gregor discusses moving away from Rails concerns in favor of modernizing software using decorators, drawing from his experience leading IT at Hoelzle.\n\n        Source code: https://github.com/hoelzle/rails-meetup-2020\n      additional_resources:\n        - name: \"hoelzle/rails-meetup-2020\"\n          type: \"repo\"\n          url: \"https://github.com/hoelzle/rails-meetup-2020\"\n\n## 2021\n\n- id: \"railshock-october-2021\"\n  title: \"Railshöck October 2021\"\n  raw_title: \"Railshöck October 2021\"\n  event_name: \"Railshöck October 2021\"\n  video_id: \"railshock-october-2021\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/highres_498348702.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/highres_498348702.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/highres_498348702.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/highres_498348702.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/highres_498348702.webp?w=750\"\n  date: \"2021-10-06\"\n  description: |-\n    It's time to harvest a year full of new insights! There will be talks about the following matters:\n\n    Rails 0.5\n    Josua Schmid: digging up some history\n\n    Modular Monolith Using Rails Engines\n    Gregor Wassmann: modular monolith vs. majestic monolith\n\n    Best of Both Worlds\n    Gregor Wassmann: SPA (Svelte) + Rails API + FactoryBot + RSpec + single CI/CD pipeline\n\n    Feeling Lucky with Crystal\n    Nick Flückiger: not about Ruby\n\n    As always: drinks and snacks are on us!\n\n    https://www.meetup.com/rubyonrails-ch/events/280293360\n  talks:\n    - title: \"Rails 0.5\"\n      raw_title: \"Rails 0.5 by Josua Schmid\"\n      event_name: \"Railshöck October 2021\"\n      speakers:\n        - \"Josua Schmid\"\n      id: \"josua-schmid-railshock-october-2021\"\n      video_id: \"josua-schmid-railshock-october-2021\"\n      video_provider: \"not_recorded\"\n      date: \"2021-10-06\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      slides_url: \"https://docs.google.com/presentation/d/1VjtOfm7gt0cWvy2DEqol8lUDM3PCdLRv6HavhNxnZiI/edit\"\n      description: |-\n        Josua Schmid digs into the history of Rails, exploring its early versions and evolution from Rails 0.5 onward.\n\n    - title: \"Modular Monolith Using Rails Engines\"\n      raw_title: \"Modular Monolith Using Rails Engines by Gregor Wassmann\"\n      event_name: \"Railshöck October 2021\"\n      speakers:\n        - \"Gregor Wassmann\"\n      id: \"gregor-wassmann-modular-monolith-railshock-october-2021\"\n      video_id: \"gregor-wassmann-modular-monolith-railshock-october-2021\"\n      video_provider: \"not_recorded\"\n      date: \"2021-10-06\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      slides_url: \"https://github.com/hoelzle/rails-meetup-2021/blob/master/doc/slides-enhanced.pdf\"\n      description: |-\n        Gregor Wassmann discusses the concept of modular monoliths with Rails Engines, contrasting it with majestic monolith architecture.\n\n        Source code: https://github.com/hoelzle/rails-meetup-2021\n      additional_resources:\n        - name: \"hoelzle/rails-meetup-2021\"\n          type: \"repo\"\n          url: \"https://github.com/hoelzle/rails-meetup-2021\"\n\n    - title: \"Best of Both Worlds\"\n      raw_title: \"Best of Both Worlds by Gregor Wassmann\"\n      event_name: \"Railshöck October 2021\"\n      speakers:\n        - \"Gregor Wassmann\"\n      id: \"gregor-wassmann-best-of-both-worlds-railshock-october-2021\"\n      video_id: \"gregor-wassmann-best-of-both-worlds-railshock-october-2021\"\n      video_provider: \"not_recorded\"\n      date: \"2021-10-06\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      slides_url: \"https://github.com/hoelzle/rails-meetup-2021/blob/master/doc/slides-enhanced.pdf\"\n      description: |-\n        Gregor Wassmann demonstrates how to combine a Svelte SPA, Rails API, FactoryBot, RSpec, and a single CI/CD pipeline for a seamless development experience.\n\n        Source code: https://github.com/hoelzle/rails-meetup-2021\n      additional_resources:\n        - name: \"hoelzle/rails-meetup-2021\"\n          type: \"repo\"\n          url: \"https://github.com/hoelzle/rails-meetup-2021\"\n\n    - title: \"Feeling Lucky with Crystal\"\n      raw_title: \"Feeling Lucky with Crystal by Nick Flückiger\"\n      event_name: \"Railshöck October 2021\"\n      speakers:\n        - \"Nick Flückiger\"\n      id: \"nick-fluckiger-railshock-october-2021\"\n      video_id: \"nick-fluckiger-railshock-october-2021\"\n      video_provider: \"not_recorded\"\n      date: \"2021-10-06\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/e/3/e/600_498348702.webp\"\n      slides_url: \"https://drive.google.com/file/d/1EiUjWy-aqgH3ZTjDu_i9DlGW0L53ceGM/view\"\n      description: |-\n        Nick Flückiger explores the Crystal programming language, showcasing its capabilities and use cases outside of Ruby.\n\n## 2022\n\n- id: \"railshock-august-2022\"\n  title: \"Railshöck August 2022\"\n  raw_title: \"Railshöck August 2022\"\n  event_name: \"Railshöck August 2022\"\n  video_id: \"railshock-august-2022\"\n  video_provider: \"children\"\n  date: \"2022-08-24\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/highres_506487707.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/highres_506487707.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/highres_506487707.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/highres_506487707.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/highres_506487707.webp?w=750\"\n  description: |-\n    It's already 2022! Time to gather and enjoy tech talks and the company of nice tech people.\n\n    * The Ruby Monstas team is going to unravel their teaching concept.\n    * Gregor Wassmann of Hoelzle talks about the discriminable gem.\n    * Alessandro Rodi of Renuo talks about a gem for the headless DatoCMS.\n    * Matthias Viehweger of Puzzle ITC will dive into the tech aspects of Hitobito.\n\n    As always: drinks and snacks are on us!\n\n    https://www.meetup.com/rubyonrails-ch/events/286090172\n  talks:\n    - title: \"Ruby Monstas: Teaching Ruby to beginners\"\n      raw_title: \"Unraveling the Ruby Monstas Teaching Concept by The Ruby Monstas Team\"\n      event_name: \"Railshöck August 2022\"\n      speakers:\n        - Ferdinand Niedermann\n        - Hana Harencarova\n        - Mario Schüttel\n        - Thomas Ritter\n      id: \"ruby-monstas-team-railshock-august-2022\"\n      video_id: \"ruby-monstas-team-railshock-august-2022\"\n      video_provider: \"not_recorded\"\n      date: \"2022-08-24\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/a/8/8/9/highres_506563145.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/a/8/8/9/highres_506563145.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/a/8/8/9/highres_506563145.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/a/8/8/9/highres_506563145.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/a/8/8/9/highres_506563145.webp\"\n      slides_url: \"https://drive.google.com/file/d/14JxMinq4d-xP0Wb-Nl6fNhWCqosJkSUX/view\"\n      description: |-\n        The Ruby Monstas team is going to unravel their unique teaching concept and approach to onboarding new developers into the Ruby community.\n\n        Website: https://rubymonstas.ch\n\n    - title: \"STI without type column: discriminable\"\n      raw_title: \"The Discriminable Gem by Gregor Wassmann\"\n      event_name: \"Railshöck August 2022\"\n      speakers:\n        - \"Gregor Wassmann\"\n      id: \"gregor-wassmann-railshock-august-2022\"\n      video_id: \"gregor-wassmann-railshock-august-2022\"\n      video_provider: \"not_recorded\"\n      date: \"2022-08-24\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      slides_url: \"https://github.com/gregorw/discriminable/blob/demo/docs/slides-enhanced.pdf\"\n      description: |-\n        Gregor Wassmann of Hölzle introduces the Discriminable gem and demonstrates its usage and applications in Rails projects.\n\n        GitHub: https://github.com/gregorw/discriminable\n      additional_resources:\n        - name: \"gregorw/discriminable\"\n          type: \"repo\"\n          url: \"https://github.com/gregorw/discriminable\"\n\n    - title: \"Dato::Rails - less Head, less Pain\"\n      raw_title: \"A Gem for Headless DatoCMS by Alessandro Rodi\"\n      event_name: \"Railshöck August 2022\"\n      speakers:\n        - \"Alessandro Rodi\"\n      id: \"alessandro-rodi-railshock-august-2022\"\n      video_id: \"alessandro-rodi-railshock-august-2022\"\n      video_provider: \"not_recorded\"\n      date: \"2022-08-24\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      description: |-\n        Alessandro Rodi of Renuo presents a gem tailored for integrating and managing content with the headless DatoCMS platform.\n\n        Blog post: https://dev.to/coorasse/datocms-with-ruby-on-rails-3ae5\n      additional_resources:\n        - name: \"Blog Post\"\n          type: \"blog\"\n          url: \"https://dev.to/coorasse/datocms-with-ruby-on-rails-3ae5\"\n\n    - title: \"Tech Dive into Hitobito\"\n      raw_title: \"Tech Aspects of Hitobito by Matthias Viehweger\"\n      event_name: \"Railshöck August 2022\"\n      speakers:\n        - \"Matthias Viehweger\"\n      id: \"matthias-viehweger-railshock-august-2022\"\n      video_id: \"matthias-viehweger-railshock-august-2022\"\n      video_provider: \"not_recorded\"\n      date: \"2022-08-24\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/6/c/3/b/600_506487707.webp\"\n      slides_url: \"https://github.com/kronn/rubykafis/blob/master/hitobito-techdive.md\"\n      description: |-\n        Matthias Viehweger of Puzzle ITC explores the technical challenges and solutions behind the Hitobito platform.\n\n## 2023\n\n- id: \"railshock-may-2023\"\n  title: \"Railshöck May 2023\"\n  raw_title: \"Railshöck May 2023\"\n  event_name: \"Railshöck May 2023\"\n  date: \"2023-05-11\"\n  video_id: \"railshock-may-2023\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/highres_511278878.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/highres_511278878.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/highres_511278878.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/highres_511278878.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/highres_511278878.webp?w=750\"\n  description: |-\n    This time we meet at Puzzle's.\n\n    There are three presentations organized:\n\n    * Ruby Performance Optimizations by Robin Steiner and Pascal Zumkehr\n    * From Spec to Spec with rswag by Simon Huber\n    * thoughtbot Defaults with suspenders by Dimiter Petrov\n\n    As always there's plenty of time for discussion after the presentations. You may bring questions like these and more:\n\n    * What performance problems do you have?\n    * How do you maintain your swagger files?\n    * Are best practices executable code in your company?\n\n    Snacks and drinks are on Puzzle!\n\n    https://www.meetup.com/rubyonrails-ch/events/291931256\n  talks:\n    - title: \"Ruby Performance Optimizations\"\n      raw_title: \"Ruby Performance Optimizations by Robin Steiner and Pascal Zumkehr\"\n      event_name: \"Railshöck May 2023\"\n      speakers:\n        - \"Robin Steiner\"\n        - \"Pascal Zumkehr\"\n      id: \"robin-steiner-pascal-zumkehr-railshock-may-2023\"\n      video_id: \"robin-steiner-pascal-zumkehr-railshock-may-2023\"\n      video_provider: \"not_recorded\"\n      date: \"2023-05-11\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      description: \"\"\n\n    - title: \"From Spec to Spec with rswag\"\n      raw_title: \"From Spec to Spec with rswag by Simon Huber\"\n      event_name: \"Railshöck May 2023\"\n      speakers:\n        - \"Simon Huber\"\n      id: \"simon-huber-railshock-may-2023\"\n      video_id: \"simon-huber-railshock-may-2023\"\n      video_provider: \"not_recorded\"\n      date: \"2023-05-11\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      description: |-\n        This talk demonstrates how to use rswag in Rails, including tweaks to avoid common pitfalls.\n\n        GitHub repo: https://github.com/sihu/rswag-getting-started\n      additional_resources:\n        - name: \"sihu/rswag-getting-started\"\n          type: \"repo\"\n          url: \"https://github.com/sihu/rswag-getting-started\"\n\n    - title: \"thoughtbot defaults with suspenders\"\n      raw_title: \"thoughtbot Defaults with suspenders by Dimiter Petrov\"\n      event_name: \"Railshöck May 2023\"\n      speakers:\n        - \"Dimiter Petrov\"\n      id: \"dimiter-petrov-railshock-may-2023\"\n      video_id: \"dimiter-petrov-railshock-may-2023\"\n      video_provider: \"not_recorded\"\n      date: \"2023-05-11\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/9/b/e/600_511278878.webp\"\n      slides_url: \"https://speakerdeck.com/crackofdusk/thoughtbot-defaults-with-suspenders\"\n      description: |-\n        A dive into the internals of the suspenders project. Suspenders uses Rails generators to quickly configure a Rails app in line with practices agreed and refined at thoughtbot.\n\n        GitHub Repo: https://github.com/thoughtbot/suspenders\n      additional_resources:\n        - name: \"thoughtbot/suspenders\"\n          type: \"repo\"\n          url: \"https://github.com/thoughtbot/suspenders\"\n\n## 2024\n\n- id: \"railshöck-march-2024\"\n  title: \"Railshöck March 2024\"\n  raw_title: \"Railshöck March 2024\"\n  event_name: \"Railshöck March 2024\"\n  date: \"2024-03-06\"\n  video_id: \"railshöck-march-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/highres_519460356.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/highres_519460356.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/highres_519460356.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/highres_519460356.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/highres_519460356.webp?w=750\"\n  description: |-\n    Multiple talks at this event:\n\n    https://www.meetup.com/rubyonrails-ch/events/298503697\n  talks:\n    - title: \"Travelling the Changelog of Ruby 3.3\"\n      raw_title: \"A Guide Through the Changelog of Ruby 3.3 by Matthias Viehweger (Puzzle)\"\n      event_name: \"Railshöck March 2024\"\n      speakers:\n        - \"Matthias Viehweger\"\n      id: \"matthias-viehweger-railshock-march-2024\"\n      video_id: \"matthias-viehweger-railshock-march-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-03-06\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      slides_url: \"https://github.com/kronn/rubykafis/blob/master/versions-2024-en.md#ruby-kafi-januar-2024\"\n      description: |-\n        Matthias Viehweger of Puzzle will be our guide through the changelog of Ruby 3.3.\n\n        https://www.meetup.com/rubyonrails-ch/events/298503697\n\n    - title: \"Offline Functionality with Rails\"\n      raw_title: \"Adding Offline Support to a Rails App Without Making It a PWA by Daniel Bengl (Renuo)\"\n      event_name: \"Railshöck March 2024\"\n      speakers:\n        - \"Daniel Bengl\"\n      id: \"daniel-bengl-railshock-march-2024\"\n      video_id: \"daniel-bengl-railshock-march-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-03-06\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      slides_url: \"https://github.com/renuo/rails-offline-talk/blob/main/slides.md\"\n      description: |-\n        Daniel Bengl of Renuo will talk about how he added offline support to a Rails app without making it a PWA.\n\n        GitHub repo: https://github.com/renuo/rails-offline-talk\n\n        https://www.meetup.com/rubyonrails-ch/events/298503697\n      additional_resources:\n        - name: \"renuo/rails-offline-talk\"\n          type: \"repo\"\n          url: \"https://github.com/renuo/rails-offline-talk\"\n\n    - title: \"Rails and Database Transactions\"\n      raw_title: \"Rails and Database Transactions by Emily Wangler (atpoint)\"\n      event_name: \"Railshöck March 2024\"\n      speakers:\n        - \"Emily Wangler\"\n      id: \"emily-wangler-railshock-march-2024\"\n      video_id: \"emily-wangler-railshock-march-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-03-06\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      slides_url: \"https://drive.google.com/file/d/1G481dIhU2MYNYOnSNMOOXsqjRjHX1auh/view\"\n      description: |-\n        Emily Wangler of atpoint will talk about Rails and database transactions.\n\n        https://www.meetup.com/rubyonrails-ch/events/298503697\n\n    - title: \"Componifying Rails: A Thought Experiment Turned Workhorse\"\n      raw_title: \"Componifying Rails: A Thought Experiment Turned Workhorse by Sandro Kalbermatter (Kalsan)\"\n      event_name: \"Railshöck March 2024\"\n      speakers:\n        - \"Sandro Kalbermatter\"\n      id: \"sandro-kalbermatter-railshock-march-2024\"\n      video_id: \"sandro-kalbermatter-railshock-march-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-03-06\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/d/a/4/600_519460356.webp\"\n      description: |-\n        Sandro Kalbermatter of Kalsan will talk about \"Componifying Rails – A thought experiment that has become my primary workhorse\".\n\n        GitHub repo: https://github.com/kalsan/compony\n\n        https://www.meetup.com/rubyonrails-ch/events/298503697\n      additional_resources:\n        - name: \"kalsan/compony\"\n          type: \"repo\"\n          url: \"https://github.com/kalsan/compony\"\n\n- id: \"railshock-july-2024\"\n  title: \"Railshöck July 2024\"\n  raw_title: \"Railshöck July 2024\"\n  event_name: \"Railshöck July 2024\"\n  date: \"2024-07-24\"\n  video_id: \"railshock-july-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/7/8/5/d/highres_521550813.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/7/8/5/d/highres_521550813.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/7/8/5/d/highres_521550813.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/7/8/5/d/highres_521550813.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/7/8/5/d/highres_521550813.webp?w=750\"\n  description: |-\n    Hello Rubyists\n\n    The Rails Foundation celebrated the 20 years anniversary of Rails last year using the inception date of the framework. As if you could just \"incept\" such a phenomenon – this is marketing BS. The relevant thing about Rails is that version 0.5 was published under the MIT license on July 24th 2004 (CET). Exactly 20 years ago. Let's celebrate this!\n\n    I reserved the Tonbandlounge in the 25hours hotel from which we'll have a good view over many rails.\n\n    18:00 Apéro (sponsored by Renuo)\n    18:30 Presentation by me about Rails 0.5\n    19:00 Open end\n\n    Cheers, Josua\n\n    PS: Other presentations about the Rails history are welcome. Please write me directly.\n\n    https://www.meetup.com/rubyonrails-ch/events/301480681\n  talks:\n    - title: \"20 Years of Rails - Rails 0.5\"\n      raw_title: \"20 Years of Rails - Rails 0.5\"\n      event_name: \"Railshöck July 2024\"\n      speakers:\n        - \"Josua Schmid\"\n      id: \"josua-schmid-railshock-august-2024\"\n      video_id: \"josua-schmid-railshock-august-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-07-24\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/9/7/a/highres_522527482.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/9/7/a/highres_522527482.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/9/7/a/highres_522527482.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/9/7/a/highres_522527482.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/9/7/a/highres_522527482.webp\"\n      slides_url: \"https://docs.google.com/presentation/d/e/2PACX-1vTTRiG_mEW_o8t6tKAZ-A_z4MjByU3cxzM88GhMFnae7WeY5nUHUXP7t-4H1XHXCp0V6PKETsDfJmjN/pub?start=false&loop=false&delayms=3000\"\n      description: |-\n        Rails version 0.5 was published under the MIT license on July 24th 2004 (CET). Exactly 20 years ago. Let's celebrate this!\n\n        https://www.meetup.com/rubyonrails-ch/events/301480681\n\n- id: \"railshock-august-2024\"\n  title: \"Railshöck August 2024\"\n  raw_title: \"Railshöck August 2024\"\n  event_name: \"Railshöck August 2024\"\n  date: \"2024-08-21\"\n  video_id: \"railshock-august-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/highres_522945446.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/highres_522945446.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/highres_522945446.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/highres_522945446.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/highres_522945446.webp?w=750\"\n  description: |-\n    Multiple talks at this event:\n\n    https://www.meetup.com/rubyonrails-ch/events/298503717\n  talks:\n    - title: \"Leveling Up Developer Tooling For The Modern Rails & Hotwire Era\"\n      raw_title: \"Developer Tooling for the Modern Rails & Hotwire Era by Marco Roth\"\n      event_name: \"Railshöck August 2024\"\n      speakers:\n        - \"Marco Roth\"\n      id: \"marco-roth-railshock-august-2024\"\n      video_id: \"marco-roth-railshock-august-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-08-21\"\n      slides_url: \"https://speakerdeck.com/marcoroth/developer-tooling-for-the-modern-rails-and-hotwire-era-at-railshock-switzerland-august-2024\"\n      thumbnail_xs: \"https://marcoroth.dev/images/resized/d2ca53ef4ba32a7a-75029166-512x.jpg\"\n      thumbnail_sm: \"https://marcoroth.dev/images/resized/d2ca53ef4ba32a7a-75029166-512x.jpg\"\n      thumbnail_md: \"https://marcoroth.dev/images/resized/d2ca53ef4ba32a7a-75029166-512x.jpg\"\n      thumbnail_lg: \"https://marcoroth.dev/images/talks/ruby-on-rails-switzerland-meetup-august-2024/saved/d2ca53ef4ba32a7a.jpg\"\n      thumbnail_xl: \"https://marcoroth.dev/images/talks/ruby-on-rails-switzerland-meetup-august-2024/saved/d2ca53ef4ba32a7a.jpg\"\n      description: |-\n        Drawing inspiration from the rapid advancements in JavaScript tooling, we explore the horizon of possibilities for Rails developers, including how advanced browser extensions and tools specifically designed for the Hotwire ecosystem can level up your developer experience.\n\n        https://www.meetup.com/rubyonrails-ch/events/298503717\n\n    - title: \"Pragmatic Rails – rails_api_logger\"\n      raw_title: \"Pragmatic Rails – rails_api_logger by Alessandro Rodi (Renuo)\"\n      event_name: \"Railshöck August 2024\"\n      speakers:\n        - \"Alessandro Rodi\"\n      id: \"alessandro-rodi-rails-api-logger-railshock-august-2024\"\n      video_id: \"alessandro-rodi-rails-api-logger-railshock-august-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-08-21\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      slides_url: \"https://drive.google.com/file/d/12A7f_U0f7TDKiY3M_jzvQX0a9oZlOVpj/view\"\n      description: |-\n        An Inbound and Outbound requests logger for your Rails application.\n\n        GitHub Repo: https://github.com/renuo/rails_api_logger\n\n        https://www.meetup.com/rubyonrails-ch/events/298503717\n      additional_resources:\n        - name: \"renuo/rails_api_logger\"\n          type: \"repo\"\n          url: \"https://github.com/renuo/rails_api_logger\"\n\n    - title: \"nochmal, the gem\"\n      raw_title: \"nochmal, the gem by Matthias Viehweger (Puzzle)\"\n      event_name: \"Railshöck August 2024\"\n      speakers:\n        - \"Matthias Viehweger\"\n      id: \"matthias-viehweger-nochmal-railshock-august-2024\"\n      video_id: \"matthias-viehweger-nochmal-railshock-august-2024\"\n      video_provider: \"not_recorded\"\n      slides_url: \"https://github.com/kronn/puzzle-presentations/blob/main/nochmal.pdf\"\n      date: \"2024-08-21\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      description: |-\n        Preserving user-data becomes challenging when the infrastructure evolves differently than you anticipated. How to migrate over 100GiB of user-uploads across 40 applications without downtime or data-loss.\n\n        GitHub Repo: https://github.com/puzzle/nochmal\n      additional_resources:\n        - name: \"puzzle/nochmal\"\n          type: \"repo\"\n          url: \"https://github.com/puzzle/nochmal\"\n\n    - title: \"Pragmatic Rails again - validation_errors\"\n      raw_title: \"Pragmatic Rails again - validation_errors by Alessandro Rodi (Renuo)\"\n      event_name: \"Railshöck August 2024\"\n      speakers:\n        - \"Alessandro Rodi\"\n      id: \"alessandro-rodi-validation-errors-railshock-august-2024\"\n      video_id: \"alessandro-rodi-validation-errors-railshock-august-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-08-21\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      slides_url: \"https://drive.google.com/file/d/1kfp8v4gbn7xSyw0X53dA9fpvYS8ujn-x/view\"\n      description: |-\n        Track ActiveRecord validation errors on your database.\n\n        GitHub Repo: https://github.com/coorasse/validation_errors\n      additional_resources:\n        - name: \"coorasse/validation_errors\"\n          type: \"repo\"\n          url: \"https://github.com/coorasse/validation_errors\"\n\n    - title: \"News Crawler via Langchain.rb and Gemini APIs\"\n      raw_title: \"News Crawler via Langchain.RB and Gemini APIs by Riccardo Carlesso (Google Cloud)\"\n      event_name: \"Railshöck August 2024\"\n      speakers:\n        - \"Riccardo Carlesso\"\n      id: \"riccardo-carlesso-railshock-august-2024\"\n      video_id: \"riccardo-carlesso-railshock-august-2024\"\n      video_provider: \"not_recorded\"\n      date: \"2024-08-21\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/1/8/6/600_522945446.webp\"\n      slides_url: \"https://drive.google.com/file/d/1dPK8qL8XzQ4p9CmmLnXjCYtlhW4lodlv/view\"\n      description: |-\n        How can we get an LLM to be updated to today's news? Gen AI is great at answering questions.. from the past.\n\n        After the LLM was trained, all you can do is RAG. How about crawling the web for latest news with Gemini for multimodal extraction and offering summarization by your favorite topic?\n\n        It all gets more exciting thanks to Andrei's langchainrb gem.\n\n- id: \"railshock-november-2024\"\n  title: \"Railshöck November 2024\"\n  raw_title: \"Railshöck November 2024\"\n  event_name: \"Railshöck November 2024\"\n  date: \"2024-11-27\"\n  video_id: \"railshock-november-2024\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/c/0/6/c/highres_524749260.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/c/0/6/c/highres_524749260.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/c/0/6/c/highres_524749260.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/c/0/6/c/highres_524749260.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/c/0/6/c/highres_524749260.webp?w=750\"\n  description: |-\n    Winter is coming. Hard to imagine now. But it's coming. Running.\n    Heralding the last Railshöck of the year. It takes place at On's.\n\n    As always there will be presentations around the wider matter of Ruby on Rails, each not more than 30min. The program is set like this:\n\n    * Don't call yourself a developer by Dimiter Petrov\n    * Postgres and Null Bytes by Simon Isler\n    * Server Sent Events by Patrik Sopran\n    * When Enums are not enough by Sandro Kalbermatter\n\n    Drinks and snacks are on On this time!\n\n    https://www.meetup.com/rubyonrails-ch/events/301751612\n  talks:\n    - title: \"Don't Call Yourself a Developer\"\n      raw_title: \"Railshöck November 2024 - Don't call yourself a developer\"\n      event_name: \"Railshöck November 2024\"\n      speakers:\n        - \"Dimiter Petrov\"\n      id: \"dimiter-petrov-railshock-november-2024\"\n      video_id: \"dimiter-petrov-railshock-november-2024\"\n      video_provider: \"not_published\"\n      date: \"2024-11-27\"\n      thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiejdeeggyoo6yjprbp5yqomze6p5f2orjs46fcxassbxe5sfx3qzy@jpeg\"\n      thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiejdeeggyoo6yjprbp5yqomze6p5f2orjs46fcxassbxe5sfx3qzy@jpeg\"\n      thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiejdeeggyoo6yjprbp5yqomze6p5f2orjs46fcxassbxe5sfx3qzy@jpeg\"\n      thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiejdeeggyoo6yjprbp5yqomze6p5f2orjs46fcxassbxe5sfx3qzy@jpeg\"\n      thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiejdeeggyoo6yjprbp5yqomze6p5f2orjs46fcxassbxe5sfx3qzy@jpeg\"\n      description: |-\n        https://www.meetup.com/rubyonrails-ch/events/301751612\n\n    - title: \"Postgres and Null Bytes - Strategies to Handle Null Bytes\"\n      raw_title: \"Railshöck November 2024 - Postgres and Null Bytes\"\n      event_name: \"Railshöck November 2024\"\n      speakers:\n        - \"Simon Isler\"\n      id: \"simon-isler-railshock-november-2024\"\n      video_id: \"simon-isler-railshock-november-2024\"\n      video_provider: \"not_published\"\n      slides_url: \"https://github.com/renuo/postgres-null-bytes-talk/blob/main/presentation.pdf\"\n      date: \"2024-11-27\"\n      thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreic3pqbtzcwohbrql5wdbb7zhycdgb2whnyrfp5onxsaml27mcmycq@jpeg\"\n      thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreic3pqbtzcwohbrql5wdbb7zhycdgb2whnyrfp5onxsaml27mcmycq@jpeg\"\n      thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreic3pqbtzcwohbrql5wdbb7zhycdgb2whnyrfp5onxsaml27mcmycq@jpeg\"\n      thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreic3pqbtzcwohbrql5wdbb7zhycdgb2whnyrfp5onxsaml27mcmycq@jpeg\"\n      thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreic3pqbtzcwohbrql5wdbb7zhycdgb2whnyrfp5onxsaml27mcmycq@jpeg\"\n      description: |-\n        https://github.com/renuo/postgres-null-bytes-talk\n\n        https://www.meetup.com/rubyonrails-ch/events/301751612\n      additional_resources:\n        - name: \"renuo/postgres-null-bytes-talk\"\n          type: \"repo\"\n          url: \"https://github.com/renuo/postgres-null-bytes-talk\"\n\n    - title: \"Server Sent Events - Making it work with Rack Hijacking and Postgres Notifications\"\n      raw_title: \"Railshöck November 2024 - Server Sent Events\"\n      event_name: \"Railshöck November 2024\"\n      speakers:\n        - \"Patrik Sopran\"\n      id: \"patrik-sopran-railshock-november-2024\"\n      video_id: \"patrik-sopran-railshock-november-2024\"\n      video_provider: \"not_published\"\n      date: \"2024-11-27\"\n      thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreigq7gruyi66dlirws6a5j6mp73k6utcdl7ygym3gxkmd373c4buiy@jpeg\"\n      thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreigq7gruyi66dlirws6a5j6mp73k6utcdl7ygym3gxkmd373c4buiy@jpeg\"\n      thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreigq7gruyi66dlirws6a5j6mp73k6utcdl7ygym3gxkmd373c4buiy@jpeg\"\n      thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreigq7gruyi66dlirws6a5j6mp73k6utcdl7ygym3gxkmd373c4buiy@jpeg\"\n      thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreigq7gruyi66dlirws6a5j6mp73k6utcdl7ygym3gxkmd373c4buiy@jpeg\"\n      slides_url: \"https://drive.google.com/file/d/1K2rJsOBbZtWQSW9X16unidQddlRqKfxr/view\"\n      description: |-\n        https://github.com/de-sopi/rails-sse-manager\n        https://github.com/de-sopi/sse-rails-react-demo\n\n        https://www.meetup.com/rubyonrails-ch/events/301751612\n      additional_resources:\n        - name: \"de-sopi/rails-sse-manager\"\n          type: \"repo\"\n          url: \"https://github.com/de-sopi/rails-sse-manager\"\n\n        - name: \"de-sopi/sse-rails-react-demo\"\n          type: \"repo\"\n          url: \"https://github.com/de-sopi/sse-rails-react-demo\"\n\n    - title: \"When Enums are not enough\"\n      raw_title: \"Railshöck November 2024 - When Enums are not enough\"\n      event_name: \"Railshöck November 2024\"\n      speakers:\n        - \"Sandro Kalbermatter\"\n      id: \"sandro-kalbermatter-railshock-november-2024\"\n      video_id: \"sandro-kalbermatter-railshock-november-2024\"\n      video_provider: \"not_published\"\n      date: \"2024-11-27\"\n      thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiawr2v5exzg7ehxqqbd4ihvmf2ss77cpsnaegxg6bowcnqwipdwfa@jpeg\"\n      thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiawr2v5exzg7ehxqqbd4ihvmf2ss77cpsnaegxg6bowcnqwipdwfa@jpeg\"\n      thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiawr2v5exzg7ehxqqbd4ihvmf2ss77cpsnaegxg6bowcnqwipdwfa@jpeg\"\n      thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiawr2v5exzg7ehxqqbd4ihvmf2ss77cpsnaegxg6bowcnqwipdwfa@jpeg\"\n      thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:fvamgbleudszao2uft3sysub/bafkreiawr2v5exzg7ehxqqbd4ihvmf2ss77cpsnaegxg6bowcnqwipdwfa@jpeg\"\n      description: |-\n        https://github.com/kalsan/anchormodel\n\n        https://www.meetup.com/rubyonrails-ch/events/301751612\n      additional_resources:\n        - name: \"kalsan/anchormodel\"\n          type: \"repo\"\n          url: \"https://github.com/kalsan/anchormodel\"\n\n## 2025\n\n- id: \"railshock-june-2025\"\n  title: \"Railshöck June 2025\"\n  raw_title: \"Railshöck June 2025\"\n  event_name: \"Railshöck June 2025\"\n  date: \"2025-06-18\"\n  video_id: \"railshock-june-2025\"\n  video_provider: \"children\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n  description: |-\n    Dear Rubyesses and Rubyists\n\n    Renuo invites for a meeting in June, soon.\n    Maybe you've got some leftovers to digest from Helvetic Ruby? Maybe you couldn't make it to Geneva? Anyways in Wallisellen, we've got the following presentations already secured:\n\n    * Zeno Davatz: Linux OpenSource Concept for Switzerland\n    * Marco Roth: HTML+ERB Parsing\n    * Masaomi Hatakeyama: Integrating Ruby and Blockchain for Genomic Data Analysis\n    * Ricardo Carlesso: Rails8 responsive chat done with RubyLLM\n\n    Snacks and drinks are on the host, as always, this time Renuo.\n\n    https://www.meetup.com/rubyonrails-ch/events/307626721\n  talks:\n    - title: \"Linux OpenSource Concept for Switzerland\"\n      raw_title: \"Railshöck June 2025 - Linux OpenSource Concept for Switzerland\"\n      event_name: \"Railshöck June 2025\"\n      speakers:\n        - \"Zeno Davatz\"\n      id: \"zeno-davatz-railshock-june-2025\"\n      video_id: \"zeno-davatz-railshock-june-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-06-18\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      description: |-\n        https://www.meetup.com/rubyonrails-ch/events/307626721\n\n    - title: \"Empowering Developers with HTML-Aware ERB Tooling\"\n      raw_title: \"Railshöck June 2025 - HTML+ERB Parsing\"\n      event_name: \"Railshöck June 2025\"\n      speakers:\n        - \"Marco Roth\"\n      id: \"marco-roth-railshock-june-2025\"\n      video_id: \"marco-roth-railshock-june-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-06-18\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      slides_url: \"https://speakerdeck.com/marcoroth/empowering-developers-with-html-aware-erb-tooling-at-ruby-on-rails-switzerland-meetup-june-2025-zurich\"\n      description: |-\n        https://www.meetup.com/rubyonrails-ch/events/307626721\n\n    - title: \"Integrating Ruby and Blockchain for Genomic Data Analysis\"\n      raw_title: \"Railshöck June 2025 - Integrating Ruby and Blockchain for Genomic Data Analysis\"\n      event_name: \"Railshöck June 2025\"\n      speakers:\n        - \"Masaomi Hatakeyama\"\n      id: \"masaomi-hatakeyama-railshock-june-2025\"\n      video_id: \"masaomi-hatakeyama-railshock-june-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-06-18\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      description: |-\n        https://www.meetup.com/rubyonrails-ch/events/307626721\n\n    - title: \"Rails8 responsive chat done with RubyLLM\"\n      raw_title: \"Railshöck June 2025 - Rails8 responsive chat done with RubyLLM\"\n      event_name: \"Railshöck June 2025\"\n      speakers:\n        - \"Riccardo Carlesso\"\n      id: \"ricardo-carlesso-railshock-june-2025\"\n      video_id: \"ricardo-carlesso-railshock-june-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-06-18\"\n      thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/c/e/a/highres_528348362.webp?w=750\"\n      slides_url: \"https://speakerdeck.com/palladius/print2-create-a-rails8-responsive-app-with-gemini-and-rubyllm\"\n      description: |-\n        Repo: https://github.com/palladius/rails8-turbo-chat\n\n        https://www.meetup.com/rubyonrails-ch/events/307626721\n      additional_resources:\n        - name: \"palladius/rails8-turbo-chat\"\n          type: \"repo\"\n          url: \"https://github.com/palladius/rails8-turbo-chat\"\n\n- title: \"Mini Höck September 2025\"\n  raw_title: \"Mini Höck at openscript\"\n  event_name: \"Mini Höck September 2025\"\n  date: \"2025-09-10\"\n  video_id: \"railshock-september-2025\"\n  id: \"railshock-september-2025\"\n  video_provider: \"children\"\n  description: |-\n    We've got a new host on the Railshöck parquet: openscript. Since they've got a cute little office, participation is limited to 12 people only.\n\n    The program\n\n    * Intro by Robin Bühler\n    * Rails + Inertia.js by Diego Steiner\n    * 5' Intermezzo \"Netzwerk SDS\" by Christian Sedlmair\n    * Rails + Svelte on Rails by Christian Sedlmair\n\n    Snacks and drinks are offered by openscript.\n\n    https://www.meetup.com/rubyonrails-ch/events/307191188\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/1/3/3/highres_530116691.webp\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/1/3/3/highres_530116691.webp\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/1/3/3/highres_530116691.webp\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/1/3/3/highres_530116691.webp\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/1/3/3/highres_530116691.webp\"\n  talks:\n    - id: \"robin-buehler-railshock-september-2025\"\n      title: \"Intro\"\n      event_name: \"Mini Höck September 2025\"\n      speakers:\n        - Robin Bühler\n      video_id: \"robin-buehler-railshock-september-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-09-10\"\n      description: \"\"\n\n    - id: \"diego-steiner-railshock-september-2025\"\n      title: \"Rails + Inertia.js\"\n      raw_title: \"Mini Höck September 2025 - Rails + Inertia.js\"\n      event_name: \"Mini Höck September 2025\"\n      speakers:\n        - Diego Steiner\n      video_id: \"diego-steiner-railshock-september-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-09-10\"\n      description: \"\"\n\n    - id: \"christian-sedlmair-netzwerk-railshock-september-2025\"\n      title: \"Netzwerk SDS\"\n      raw_title: \"Mini Höck September 2025 - Netzwerk SDS\"\n      event_name: \"Mini Höck September 2025\"\n      speakers:\n        - Christian Sedlmair\n      video_id: \"christian-sedlmair-netzwerk-sds-railshock-september-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-09-10\"\n      description: \"\"\n\n    - id: \"christian-sedlmair-svelte-railshock-september-2025\"\n      title: \"Rails + Svelte on Rails\"\n      raw_title: \"Mini Höck September 2025 - Rails + Svelte on Rails\"\n      event_name: \"Mini Höck September 2025\"\n      speakers:\n        - Christian Sedlmair\n      video_id: \"christian-sedlmair-svelte-railshock-september-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-09-10\"\n      description: \"\"\n\n- title: \"Railshöck November 2025\"\n  raw_title: \"Railshöck at Swisscom\"\n  event_name: \"Railshöck November 2025\"\n  date: \"2025-11-12\"\n  video_id: \"railshock-november-2025\"\n  id: \"railshock-november-2025\"\n  video_provider: \"children\"\n  description: |-\n    Hey everyone, this year's last Railshöck is hosted at Swisscom's. Three speakers committed to share their perspective on stage:\n\n    * Rage Against the Malicious by Alexis Bernard is\n    about how to protect Rails applications against bots and brute force attacks without annoying humans, and why he thinks captchas are not the best solution.\n\n    * Smart Queries for Dumb Models by Clemens Helm\n    about how complex data filtering in Rails often leads us down a rabbit hole of custom scopes, service objects, and Arel acrobatics. But what if we let the database do what it’s best at? In this talk, you’ll see how SQL views paired with plain ActiveRecord and Ransack can turn messy logic into elegant, powerful queries — without giving up the Rails way.\n\n    * Level Up Your Engineering Career with Mentorship, Pairing, and AI by Hana Harencarova\n    Feeling stuck in your technical growth? Don't learn alone. Discover how to tap into mentorship, pair programming, and AI to accelerate your skills. Whether you're early in career or going for senior roles, this session will equip you with strategies to get there faster and have fun in the process.\n\n    As always, snacks and drinks are sponsored by the host. So thanks to Swisscom!\n\n    https://www.meetup.com/rubyonrails-ch/events/307805999\n  talks:\n    - id: \"alexis-bernard-railshock-november-2025\"\n      title: \"Rage Against the Malicious\"\n      raw_title: \"Railshöck November 2025 - Rage Against the Malicious\"\n      event_name: \"Railshöck November 2025\"\n      speakers:\n        - Alexis Bernard\n      video_id: \"alexis-bernard-railshock-november-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-11-12\"\n      description: |-\n        How to protect Rails applications against bots and brute force attacks without annoying humans, and why he thinks captchas are not the best solution.\n      additional_resources:\n        - name: \"BaseSecrete/active_hashcash\"\n          type: \"repo\"\n          url: \"https://github.com/BaseSecrete/active_hashcash\"\n\n    - id: \"clemens-helm-railshock-november-2025\"\n      title: \"Smart Queries for Dumb Models\"\n      raw_title: \"Railshöck November 2025 - Smart Queries for Dumb Models\"\n      event_name: \"Railshöck November 2025\"\n      speakers:\n        - Clemens Helm\n      video_id: \"clemens-helm-railshock-november-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-11-12\"\n      description: |-\n        How complex data filtering in Rails often leads us down a rabbit hole of custom scopes, service objects, and Arel acrobatics. But what if we let the database do what it's best at? In this talk, you'll see how SQL views paired with plain ActiveRecord and Ransack can turn messy logic into elegant, powerful queries — without giving up the Rails way.\n      additional_resources:\n        - name: \"clemenshelm/rubyshop\"\n          type: \"repo\"\n          url: \"https://github.com/clemenshelm/rubyshop\"\n\n    - id: \"hana-harencarova-railshock-november-2025\"\n      title: \"Level Up Your Engineering Career with Mentorship, Pairing, and AI\"\n      raw_title: \"Railshöck November 2025 - Level Up Your Engineering Career with Mentorship, Pairing, and AI\"\n      event_name: \"Railshöck November 2025\"\n      speakers:\n        - Hana Harencarova\n      video_id: \"hana-harencarova-railshock-november-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-11-12\"\n      slides_url: \"https://docs.google.com/presentation/d/1cQJZFUUCekJ90yMNf3bvTbGWMGGi8pYutsJewtDFmP8/view\"\n      description: |-\n        Feeling stuck in your technical growth? Don't learn alone. Discover how to tap into mentorship, pair programming, and AI to accelerate your skills. Whether you're early in career or going for senior roles, this session will equip you with strategies to get there faster and have fun in the process.\n\n- title: \"Railshöck December 2025\"\n  raw_title: \"Railshöck at Renuo\"\n  event_name: \"Railshöck December 2025\"\n  date: \"2025-12-17\"\n  video_id: \"railshock-december-2025\"\n  id: \"railshock-december-2025\"\n  video_provider: \"children\"\n  description: |-\n    Hi everyone\n\n    On a short notice I'll revise what I said before: THIS Railshöck will be the last one of this year… probably! fxn is travelling around, so I couldn't say no ☺️. It will be quite a prominent round!\n\n    So brace yourselves and behold expecting the following presentations:\n\n    Anchor Model by Sandro Kalbermatter is about a yet undescribed software design pattern\n    onlylogs by Alessandro Rodi is about the challenges of building a logs viewer as a Rails Engine\n    How Zeitwerk Works by Xavier Noria\n    As always, snacks and drinks are sponsored by the host. So thanks to Renuo! I hope to see you all there!\n\n    Cheers, Josua\n\n    https://www.meetup.com/rubyonrails-ch/events/312295522\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/4/6/4/highres_531841124.webp\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/4/6/4/highres_531841124.webp\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/4/6/4/highres_531841124.webp\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/4/6/4/highres_531841124.webp\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/4/6/4/highres_531841124.webp\"\n  talks:\n    - id: \"sandro-kalbermatter-railshock-december-2025\"\n      title: \"Anchor Model\"\n      raw_title: \"Railshöck December 2025 - Anchor Model\"\n      event_name: \"Railshöck December 2025\"\n      speakers:\n        - Sandro Kalbermatter\n      video_id: \"sandro-kalbermatter-railshock-december-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-12-17\"\n      slides_url: \"https://drive.google.com/file/d/1ENiAY_MZkydYcdtJcnU6X-qqXT1NFVn8/view\"\n      description: |-\n        About a yet undescribed software design pattern.\n      additional_resources:\n        - name: \"kalsan/anchormodel\"\n          type: \"repo\"\n          url: \"https://github.com/kalsan/anchormodel\"\n\n    - id: \"alessandro-rodi-railshock-december-2025\"\n      title: \"onlylogs\"\n      raw_title: \"Railshöck December 2025 - onlylogs\"\n      event_name: \"Railshöck December 2025\"\n      speakers:\n        - Alessandro Rodi\n      video_id: \"alessandro-rodi-railshock-december-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-12-17\"\n      slides_url: \"https://drive.google.com/file/d/1XS3wr6MrwDMR7BGVm-FTWH32qTfvOTgv/view\"\n      description: |-\n        About the challenges of building a logs viewer as a Rails Engine.\n\n    - id: \"xavier-noria-railshock-december-2025\"\n      title: \"How Zeitwerk Works\"\n      raw_title: \"Railshöck December 2025 - How Zeitwerk Works\"\n      event_name: \"Railshöck December 2025\"\n      speakers:\n        - Xavier Noria\n      video_id: \"xavier-noria-railshock-december-2025\"\n      video_provider: \"not_recorded\"\n      date: \"2025-12-17\"\n      slides_url: \"https://drive.google.com/file/d/1IaOJK2HeK44Hm5BpYv_q6w_9NRDSQB3q/view\"\n      description: \"\"\n"
  },
  {
    "path": "data/ruby-on-rails-switzerland/series.yml",
    "content": "---\nname: \"Ruby on Rails Switzerland\"\nwebsite: \"https://www.meetup.com/rubyonrails-ch\"\ntwitter: \"\"\nyoutube_channel_name: \"\"\nkind: \"meetup\"\nfrequency: \"quarterly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-on-waves/ruby-on-waves-meetup/event.yml",
    "content": "---\nid: \"ruby-on-waves-meetup\"\ntitle: \"Ruby on Waves Meetup\"\nkind: \"meetup\"\nlocation: \"Ericeira, Portugal\"\ndescription: |-\n  Ruby on Waves is a Ruby and Rails meetup in Ericeira, Portugal.\n  It brings together Rubyists to cowork, share ideas, and talk Rails by the ocean.\nwebsite: \"https://rubyonwaves.com\"\nluma: \"https://luma.com/rubyonwaves\"\ncoordinates:\n  latitude: 38.968128\n  longitude: -9.4073\n"
  },
  {
    "path": "data/ruby-on-waves/ruby-on-waves-meetup/videos.yml",
    "content": "---\n- id: \"ruby-on-waves-0\"\n  title: \"Ruby on Waves #0\"\n  event_name: \"Ruby on Waves #0\"\n  date: \"2025-05-01\"\n  video_provider: \"not_recorded\"\n  video_id: \"ruby-on-waves-0\"\n  description: |-\n    Informal inaugural Ruby on Waves gathering in Ericeira, Portugal.\n\n    Coworking, coffee, and meeting other Rubyists by the beach.\n\n    https://luma.com/mar71t84\n  talks: []\n\n- id: \"ruby-on-waves-1\"\n  title: \"Ruby on Waves #1\"\n  event_name: \"Ruby on Waves #1\"\n  date: \"2026-04-15\"\n  video_provider: \"children\"\n  video_id: \"ruby-on-waves-1\"\n  description: |-\n    First Ruby on Waves meetup with talks.\n\n    A casual Ruby and Rails gathering in Ericeira near Lisbon.\n    Coffee, beer, laptops, and good Ruby conversations by the ocean.\n\n    https://luma.com/s1bzmkzf\n  talks:\n    - title: \"Opening Remarks\"\n      event_name: \"Ruby on Waves #1\"\n      date: \"2026-04-15\"\n      speakers:\n        - Javi (@rameerez)\n      id: \"javi-rameerez-ruby-on-waves-1-opening-remarks\"\n      video_id: \"javi-rameerez-ruby-on-waves-1-opening-remarks\"\n      video_provider: \"scheduled\"\n      description: |-\n        Opening remarks by Javi (@rameerez), organizer of Ruby on Waves.\n\n    - title: \"Startups on Rails\"\n      event_name: \"Ruby on Waves #1\"\n      date: \"2026-04-15\"\n      speakers:\n        - Anton Senkovskiy\n      id: \"anton-senkovskiy-ruby-on-waves-1\"\n      video_id: \"anton-senkovskiy-ruby-on-waves-1\"\n      video_provider: \"scheduled\"\n      description: |-\n        Talk by Anton Senkovskiy of Evil Martians.\n\n    - title: \"Keep Open Claw on Rails\"\n      event_name: \"Ruby on Waves #1\"\n      date: \"2026-04-15\"\n      speakers:\n        - Jankees van Woezik\n      id: \"jankees-van-woezik-ruby-on-waves-1\"\n      video_id: \"jankees-van-woezik-ruby-on-waves-1\"\n      video_provider: \"scheduled\"\n      description: |-\n        Talk by Jankees van Woezik of WBSO.ai.\n"
  },
  {
    "path": "data/ruby-on-waves/series.yml",
    "content": "---\nname: \"Ruby on Waves\"\nwebsite: \"https://rubyonwaves.com\"\nluma: \"https://luma.com/rubyonwaves\"\nkind: \"meetup\"\nfrequency: \"yearly\"\ndefault_country_code: \"PT\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\nyoutube_channel_name: \"\"\nplaylist_matcher: \"\"\n"
  },
  {
    "path": "data/ruby-phil/ruby-phil/event.yml",
    "content": "---\nid: \"ruby-phil\"\ntitle: \"Philippine Ruby Meetup\"\nkind: \"meetup\"\nlocation: \"Manila, Philippines\"\ndescription: \"\"\nbanner_background: \"#E72110\"\nfeatured_background: \"#E72110\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 14.5995133\n  longitude: 120.984234\n"
  },
  {
    "path": "data/ruby-phil/ruby-phil/videos.yml",
    "content": "---\n- id: \"ruby-phil-meetup-may-2025\"\n  title: \"Philippine Ruby Meetup May 2025\"\n  raw_title: \"PhRUG - Harvest Time!\"\n  event_name: \"Philippine Ruby Meetup May 2025\"\n  date: \"2025-05-28\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/0/3/d/highres_528124157.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/0/3/d/highres_528124157.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/0/3/d/highres_528124157.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/0/3/d/highres_528124157.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/0/3/d/highres_528124157.webp?w=750\"\n  description: |-\n    G'Day PhRUG Cutters!\n\n    This month we are at Narra!\n\n    Quezon City - Narra Labs - 15 Floor Sm North Tower 1 Quezon City\n    https://maps.app.goo.gl/4CiJTYFUw6GAbdng8\n\n    Al will demo some of hotwire-native's new functionality with his native podcast player app using compose multiplatform.\n\n    Ejay from Narra will show some tips and tricks for using materialized views to keep your database queries fresh and fast.\n\n    If you wanna give a talk feel free to reach out!\n\n    https://www.meetup.com/ruby-phil/events/308017459\n  video_provider: \"children\"\n  video_id: \"ruby-phil-meetup-may-2025\"\n  talks:\n    - title: \"Native Podcast Player app using Hotwire Native Android\" # TODO: exact title\n      date: \"2025-05-28\"\n      video_provider: \"scheduled\"\n      id: \"al-gray-ruby-phil-meetup-may-2025\"\n      video_id: \"al-gray-ruby-phil-meetup-may-2025\"\n      description: |-\n        Al will demo some of hotwire-native's new functionality with his native podcast player app using compose multiplatform.\n      speakers:\n        - Al Gray\n\n    - title: \"Materialized Views\" # TODO: exact title\n      date: \"2025-05-28\"\n      video_provider: \"scheduled\"\n      id: \"ejay-canaria-ruby-phil-meetup-may-2025\"\n      video_id: \"ejay-canaria-ruby-phil-meetup-may-2025\"\n      description: |-\n        Ejay from Narra will show some tips and tricks for using materialized views to keep your database queries fresh and fast.\n      speakers:\n        - Ejay Canaria\n- id: \"ruby-phil-armageddon-edition\"\n  title: \"Armageddon Edition\"\n  date: \"2026-03-26\"\n  video_id: \"ruby-phil-armageddon-edition\"\n  video_provider: \"scheduled\"\n  description: |-\n    As the war in the Middle East creates the largest supply disruption in the history of the global oil market, we'll be doing some more deep dives into databases. **Lightning Talks**  Al (sunEtrike) will be giving a mini update on his ongoing work towards an open-dataset for public transport for 2nd and 3rd tier Philippine cities such as Batangas City. Ray (Narra) Explain Analyze Active Record: How to Read Query Plans and Build Indexes That Actually Work\n\n    https://www.meetup.com/ruby-phil/events/313810115/\n  talks: []\n"
  },
  {
    "path": "data/ruby-phil/series.yml",
    "content": "---\nname: \"Philippine Ruby Users Group\"\nwebsite: \"https://web.archive.org/web/20180320054823/http://pinoyrb.org/\"\nmeetup: \"https://www.meetup.com/ruby-phil/\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"PH\"\nlanguage: \"english\"\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-1-2007/event.yml",
    "content": "---\nid: \"rails-camp-au-1-2007\"\ntitle: \"Rails Camp AU 1 (2007)\"\ndescription: \"\"\nlocation: \"Somersby, NSW, Australia\"\nkind: \"retreat\"\nstart_date: \"2007-06-15\"\nend_date: \"2007-06-18\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -33.3569025\n  longitude: 151.2904349\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-10-2012/event.yml",
    "content": "---\nid: \"rails-camp-au-10-2012\"\ntitle: \"Rails Camp AU 10 (2012)\"\ndescription: \"\"\nlocation: \"Piccadilly, SA, Australia\"\nkind: \"retreat\"\nstart_date: \"2012-01-13\"\nend_date: \"2012-01-16\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -34.9792014\n  longitude: 138.7301205\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-11-2012/event.yml",
    "content": "---\nid: \"rails-camp-au-11-2012\"\ntitle: \"Rails Camp AU 11 (2012)\"\ndescription: \"\"\nlocation: \"Springbrook, QLD, Australia\"\nkind: \"retreat\"\nstart_date: \"2012-06-15\"\nend_date: \"2012-06-18\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -28.1842993\n  longitude: 153.258621\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-12-2012/event.yml",
    "content": "---\nid: \"rails-camp-au-12-2012\"\ntitle: \"Rails Camp AU 12 (2012)\"\ndescription: \"\"\nlocation: \"Port Sorell, TAS, Australia\"\nkind: \"retreat\"\nstart_date: \"2012-11-16\"\nend_date: \"2012-11-19\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -41.1668112\n  longitude: 146.5530374\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-13-2013/event.yml",
    "content": "---\nid: \"rails-camp-au-13-2013\"\ntitle: \"Rails Camp AU 13 (2013)\"\ndescription: \"\"\nlocation: \"Somers, VIC, Australia\"\nkind: \"retreat\"\nstart_date: \"2013-06-21\"\nend_date: \"2013-06-24\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -38.3935632\n  longitude: 145.1635577\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-14-2013/event.yml",
    "content": "---\nid: \"rails-camp-au-14-2013\"\ntitle: \"Rails Camp AU 14 (2013)\"\ndescription: \"\"\nlocation: \"Yarramundi, NSW, Australia\"\nkind: \"retreat\"\nstart_date: \"2013-11-01\"\nend_date: \"2013-11-04\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -33.6362859\n  longitude: 150.6666707\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-15-2014/event.yml",
    "content": "---\nid: \"rails-camp-au-15-2014\"\ntitle: \"Rails Camp AU 15 (2014)\"\ndescription: \"\"\nlocation: \"Redland Bay, QLD, Australia\"\nkind: \"retreat\"\nstart_date: \"2014-05-09\"\nend_date: \"2014-05-12\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -27.6124586\n  longitude: 153.3030618\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-16-2014/event.yml",
    "content": "---\nid: \"rails-camp-au-16-2014\"\ntitle: \"Rails Camp AU 16 (2014)\"\ndescription: \"\"\nlocation: \"Perth, WA, Australia\"\nkind: \"retreat\"\nstart_date: \"2014-11-14\"\nend_date: \"2014-11-17\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -31.9513993\n  longitude: 115.8616783\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-17-2015/event.yml",
    "content": "---\nid: \"rails-camp-au-17-2015\"\ntitle: \"Rails Camp AU 17 (2015)\"\ndescription: \"\"\nlocation: \"Broken Bay, NSW, Australia\"\nkind: \"retreat\"\nstart_date: \"2015-06-12\"\nend_date: \"2015-06-15\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -33.5565739\n  longitude: 151.3326862\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-18-2015/event.yml",
    "content": "---\nid: \"rails-camp-au-18-2015\"\ntitle: \"Rails Camp AU 18 (2015)\"\ndescription: \"\"\nlocation: \"Cottermouth, ACT, Australia\"\nkind: \"retreat\"\nstart_date: \"2015-12-11\"\nend_date: \"2015-12-14\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -35.3312567\n  longitude: 148.961425\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-19-2016/event.yml",
    "content": "---\nid: \"rails-camp-au-19-2016\"\ntitle: \"Rails Camp AU 19 (2016)\"\ndescription: \"\"\nlocation: \"Mylor, SA, Australia\"\nkind: \"retreat\"\nstart_date: \"2016-07-08\"\nend_date: \"2016-07-11\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -35.0424797\n  longitude: 138.7602154\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-2-2007/event.yml",
    "content": "---\nid: \"rails-camp-au-2-2007\"\ntitle: \"Rails Camp AU 2 (2007)\"\ndescription: \"\"\nlocation: \"Bacchus Marsh, VIC, Australia\"\nkind: \"retreat\"\nstart_date: \"2007-11-23\"\nend_date: \"2007-11-26\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -37.6763789\n  longitude: 144.4463206\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-20-2016/event.yml",
    "content": "---\nid: \"rails-camp-au-20-2016\"\ntitle: \"Rails Camp AU 20 (2016)\"\ndescription: \"\"\nlocation: \"Springbrook, QLD, Australia\"\nkind: \"retreat\"\nstart_date: \"2016-12-09\"\nend_date: \"2016-12-12\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -28.1842993\n  longitude: 153.258621\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-21-2017/event.yml",
    "content": "---\nid: \"rails-camp-au-21-2017\"\ntitle: \"Rails Camp AU 21 (2017)\"\ndescription: \"\"\nlocation: \"Mount Bundy, NT, Australia\"\nkind: \"retreat\"\nstart_date: \"2017-05-05\"\nend_date: \"2017-05-08\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -12.9065206\n  longitude: 131.6733768\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-22-2017/event.yml",
    "content": "---\nid: \"rails-camp-au-22-2017\"\ntitle: \"Rails Camp AU 22 (2017)\"\ndescription: \"\"\nlocation: \"Toolangi, VIC, Australia\"\nkind: \"retreat\"\nstart_date: \"2017-11-10\"\nend_date: \"2017-11-13\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -37.5286609\n  longitude: 145.5191965\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-23-2018/event.yml",
    "content": "---\nid: \"rails-camp-au-23-2018\"\ntitle: \"Rails Camp AU 23 (2018)\"\ndescription: \"\"\nlocation: \"Whiteside, QLD, Australia\"\nkind: \"retreat\"\nstart_date: \"2018-05-18\"\nend_date: \"2018-05-21\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -27.2553008\n  longitude: 152.9297651\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-24-2018/event.yml",
    "content": "---\nid: \"rails-camp-au-24-2018\"\ntitle: \"Rails Camp AU 24 (2018)\"\ndescription: \"\"\nlocation: \"Dysart, TAS, Australia\"\nkind: \"retreat\"\nstart_date: \"2018-11-23\"\nend_date: \"2018-11-26\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -42.5553135\n  longitude: 147.1470503\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-25-2019/event.yml",
    "content": "---\nid: \"rails-camp-au-25-2019\"\ntitle: \"Rails Camp AU 25 (2019)\"\ndescription: \"\"\nlocation: \"Perth, WA, Australia\"\nkind: \"retreat\"\nstart_date: \"2019-05-10\"\nend_date: \"2019-05-13\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -31.9513993\n  longitude: 115.8616783\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-26-2019/event.yml",
    "content": "---\nid: \"rails-camp-au-26-2019\"\ntitle: \"Rails Camp AU 26 (2019)\"\ndescription: \"\"\nlocation: \"Campaspe Downs, VIC, Australia\"\nkind: \"retreat\"\nstart_date: \"2019-11-15\"\nend_date: \"2019-11-18\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -37.2970204\n  longitude: 144.4182182\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-27-2022/event.yml",
    "content": "---\nid: \"rails-camp-au-27-2022\"\ntitle: \"Rails Camp AU 27 (2022)\"\ndescription: \"\"\nlocation: \"Piccadilly, SA, Australia\"\nkind: \"retreat\"\nstart_date: \"2022-02-04\"\nend_date: \"2022-02-07\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -34.9792014\n  longitude: 138.7301205\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-3-2008/event.yml",
    "content": "---\nid: \"rails-camp-au-3-2008\"\ntitle: \"Rails Camp AU 3 (2008)\"\ndescription: \"\"\nlocation: \"Kariong, NSW, Australia\"\nkind: \"retreat\"\nstart_date: \"2008-06-20\"\nend_date: \"2008-06-23\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -33.434043\n  longitude: 151.2965146\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-4-2008/event.yml",
    "content": "---\nid: \"rails-camp-au-4-2008\"\ntitle: \"Rails Camp AU 4 (2008)\"\ndescription: \"\"\nlocation: \"Piccadilly, SA, Australia\"\nkind: \"retreat\"\nstart_date: \"2008-11-14\"\nend_date: \"2008-11-17\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -34.9792014\n  longitude: 138.7301205\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-5-2009/event.yml",
    "content": "---\nid: \"rails-camp-au-5-2009\"\ntitle: \"Rails Camp AU 5 (2009)\"\ndescription: \"\"\nlocation: \"Springbrook, QLD, Australia\"\nkind: \"retreat\"\nstart_date: \"2009-05-15\"\nend_date: \"2009-05-18\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -28.1842993\n  longitude: 153.258621\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-6-2009/event.yml",
    "content": "---\nid: \"rails-camp-au-6-2009\"\ntitle: \"Rails Camp AU 6 (2009)\"\ndescription: \"\"\nlocation: \"Somers, VIC, Australia\"\nkind: \"retreat\"\nstart_date: \"2009-11-20\"\nend_date: \"2009-11-23\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -38.3935632\n  longitude: 145.1635577\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-7-2010/event.yml",
    "content": "---\nid: \"rails-camp-au-7-2010\"\ntitle: \"Rails Camp AU 7 (2010)\"\ndescription: \"\"\nlocation: \"Canberra, ACT, Australia\"\nkind: \"retreat\"\nstart_date: \"2010-04-16\"\nend_date: \"2010-04-19\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -35.2801846\n  longitude: 149.1310324\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-8-2010/event.yml",
    "content": "---\nid: \"rails-camp-au-8-2010\"\ntitle: \"Rails Camp AU 8 (2010)\"\ndescription: \"\"\nlocation: \"Perth, WA, Australia\"\nkind: \"retreat\"\nstart_date: \"2010-11-12\"\nend_date: \"2010-11-15\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -31.9513993\n  longitude: 115.8616783\n"
  },
  {
    "path": "data/ruby-retreat-au/rails-camp-au-9-2011/event.yml",
    "content": "---\nid: \"rails-camp-au-9-2011\"\ntitle: \"Rails Camp AU 9 (2011)\"\ndescription: \"\"\nlocation: \"Lake Ainsworth, NSW, Australia\"\nkind: \"retreat\"\nstart_date: \"2011-06-10\"\nend_date: \"2011-06-13\"\nwebsite: \"https://rails.camp\"\ncoordinates:\n  latitude: -28.7838716\n  longitude: 153.5916768\n"
  },
  {
    "path": "data/ruby-retreat-au/ruby-retreat-au-2024/event.yml",
    "content": "---\nid: \"ruby-retreat-au-2024\"\ntitle: \"Ruby Retreat AU 28 (2024)\"\ndescription: \"\"\nlocation: \"Warrnambool, VIC, Australia\"\nkind: \"retreat\"\nstart_date: \"2024-10-18\"\nend_date: \"2024-10-21\"\nwebsite: \"https://retreat.ruby.org.au/\"\ncoordinates:\n  latitude: -38.396053\n  longitude: 142.470672\naliases:\n  - Ruby Retreat 2024\n"
  },
  {
    "path": "data/ruby-retreat-au/ruby-retreat-au-2024/venue.yml",
    "content": "---\nname: \"Warra Gnan Coastal Camp\"\ndescription: |-\n  Located minutes from the beach and the town itself, Warra Gnan Coastal Camp has capacity for about 80 people.\ninstructions: \"You will arrive at the venue by riding the train over from Melbourne, or by driving. We will provide more information on how to get there closer to the event.\"\naddress:\n  street: \"17 Stanley Street\"\n  city: \"Warrnambool\"\n  region: \"VIC\"\n  postal_code: \"3280\"\n  country: \"Australia\"\n  country_code: \"AU\"\n  display: \"17 Stanley Street, Warrnambool, VIC, 3280\"\ncoordinates:\n  latitude: -38.396053\n  longitude: 142.470672\nmaps:\n  google: \"https://maps.app.goo.gl/mDDXMTq3iZSzSuQq9\"\n"
  },
  {
    "path": "data/ruby-retreat-au/ruby-retreat-au-2024/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://retreat.ruby.org.au/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-retreat-au/ruby-retreat-au-2025/event.yml",
    "content": "---\nid: \"ruby-retreat-au-2025\"\ntitle: \"Ruby Retreat AU 29 (2025)\"\ndescription: |-\n  Ruby Retreat is a full weekend retreat for people interested in web development to gather and be awesome together. People attend for a variety of reasons: socializing, hacking, learning, teaching, gaming, and more. Though there is a focus on Ruby, we welcome anyone interested in programming or web technologies to join us.\nlocation: \"Warrnambool, VIC, Australia\"\nkind: \"retreat\"\nstart_date: \"2025-10-17\"\nend_date: \"2025-10-20\"\nwebsite: \"https://retreat.ruby.org.au/\"\nbanner_background: \"#E7F2E2\"\nfeatured_color: \"#064E3B\"\nfeatured_background: \"#E7F2E2\"\ncoordinates:\n  latitude: -38.396053\n  longitude: 142.470672\n"
  },
  {
    "path": "data/ruby-retreat-au/ruby-retreat-au-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - John Sherwood\n    - Jupiter Haehn\n    - Ryan Bigg\n"
  },
  {
    "path": "data/ruby-retreat-au/ruby-retreat-au-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: |-\n        Ruby Retreat couldn't exist without the support of our sponsors.\n      level: 1\n      sponsors:\n        - name: \"Assembly Four\"\n          website: \"https://assemblyfour.com/\"\n          slug: \"AssemblyFour\"\n          logo_url: \"https://retreat.ruby.org.au/images/sponsors/2025/assembly-four.png\"\n\n        - name: \"Bluethumb\"\n          website: \"https://tech.bluet.hm/\"\n          slug: \"Bluethumb\"\n          logo_url: \"https://retreat.ruby.org.au/images/sponsors/2025/bluethumb.png\"\n"
  },
  {
    "path": "data/ruby-retreat-au/ruby-retreat-au-2025/venue.yml",
    "content": "---\nname: \"Warra Gnan Coastal Camp\"\ndescription: |-\n  Located minutes from the beach and the town itself, Warra Gnan Coastal Camp has capacity for about 80 people.\ninstructions: \"You will arrive at the venue by riding the train over from Melbourne, or by driving. We will provide more information on how to get there closer to the event.\"\naddress:\n  street: \"17 Stanley Street\"\n  city: \"Warrnambool\"\n  region: \"VIC\"\n  postal_code: \"3280\"\n  country: \"Australia\"\n  country_code: \"AU\"\n  display: \"17 Stanley Street, Warrnambool, VIC, 3280\"\ncoordinates:\n  latitude: -38.396053\n  longitude: 142.470672\nmaps:\n  google: \"https://maps.app.goo.gl/mDDXMTq3iZSzSuQq9\"\n"
  },
  {
    "path": "data/ruby-retreat-au/ruby-retreat-au-2025/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://retreat.ruby.org.au/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-retreat-au/series.yml",
    "content": "---\nname: \"Ruby Retreat AU\"\nwebsite: \"https://retreat.ruby.org.au\"\nkind: \"retreat\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"AU\"\naliases:\n  - Ruby Retreat Australia\n"
  },
  {
    "path": "data/ruby-retreat-nz/ruby-retreat-nz-2020/event.yml",
    "content": "---\nid: \"ruby-retreat-nz-2020\"\ntitle: \"Ruby Retreat NZ 2020 (Cancelled)\"\ndescription: \"\"\nlocation: \"Mt Cheeseman, near Christchurch, New Zealand\"\nkind: \"event\"\nstart_date: \"2020-03-27\"\nend_date: \"2020-03-30\"\nwebsite: \"https://retreat.ruby.nz\"\nstatus: \"cancelled\"\ntwitter: \"RubyNewZealand\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: -43.5320301\n  longitude: 172.636648\naliases:\n  - Ruby Retreat NZ 2020\n"
  },
  {
    "path": "data/ruby-retreat-nz/ruby-retreat-nz-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://retreat.ruby.nz\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-retreat-nz/ruby-retreat-nz-2023/event.yml",
    "content": "---\nid: \"ruby-retreat-nz-2023\"\ntitle: \"Ruby Retreat NZ 2023\"\ndescription: \"\"\nlocation: \"Mount Cheeseman, Aotearoa, New Zealand\"\nkind: \"event\"\nstart_date: \"2023-10-27\"\nend_date: \"2023-10-30\"\nwebsite: \"https://retreat.ruby.nz\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: -43.1571159\n  longitude: 171.6690673\naliases:\n  - Ruby Retreat 2023\n"
  },
  {
    "path": "data/ruby-retreat-nz/ruby-retreat-nz-2023/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://retreat.ruby.nz\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-retreat-nz/ruby-retreat-nz-2025/event.yml",
    "content": "---\nid: \"ruby-retreat-nz-2025\"\ntitle: \"Ruby Retreat NZ 2025\"\ndescription: \"\"\nlocation: \"Whangaparāoa, Auckland, New Zealand\"\nkind: \"retreat\"\nstart_date: \"2025-05-09\"\nend_date: \"2025-05-12\"\nwebsite: \"https://retreat.ruby.nz\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: -36.61280051278539\n  longitude: 174.81887537984366\naliases:\n  - Ruby Retreat 2025\n"
  },
  {
    "path": "data/ruby-retreat-nz/ruby-retreat-nz-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: |-\n        Thanks to our generous sponsors who make Ruby Retreat possible.\n      level: 1\n      sponsors:\n        - name: \"Glory League\"\n          website: \"https://gloryleague.basketball/\"\n          slug: \"GloryLeague\"\n          logo_url: \"https://retreat.ruby.nz/img/friends/gloryleague.jpg\"\n\n        - name: \"DocSpring\"\n          website: \"https://docspring.com/\"\n          slug: \"DocSpring\"\n          logo_url: \"https://retreat.ruby.nz/img/friends/docspring.png\"\n\n        - name: \"Lil Regie\"\n          website: \"https://lilregie.com/\"\n          slug: \"LilRegie\"\n          logo_url: \"https://retreat.ruby.nz/img/friends/lilregie.svg\"\n\n        - name: \"Superlinear\"\n          website: \"https://www.superlinear.nz/\"\n          slug: \"Superlinear\"\n          logo_url: \"https://retreat.ruby.nz/img/friends/superlinear.svg\"\n"
  },
  {
    "path": "data/ruby-retreat-nz/ruby-retreat-nz-2025/venue.yml",
    "content": "---\nname: \"Y Shakespear Lodge\"\ndescription: |-\n  1 hour drive from Auckland CBD, the Y (formerly known as YMCA) Shakespear Lodge is located in the middle of a beautiful regional park.\ninstructions: \"Bus transport from and to Auckland Airport is included in the event ticket.\"\naddress:\n  street: \"1503 Whangaparaoa Road\"\n  city: \"Whangaparāoa\"\n  postal_code: \"930\"\n  country: \"New Zealand\"\n  country_code: \"NZ\"\n  display: \"1503 Whangaparaoa Road, Shakespear Regional Park, Whangaparaoa, Auckland, New Zealand\"\ncoordinates:\n  latitude: -36.61280051278539\n  longitude: 174.81887537984366\nmaps:\n  google: \"https://maps.app.goo.gl/u8o5H3yRdPxfhFM99\"\n"
  },
  {
    "path": "data/ruby-retreat-nz/ruby-retreat-nz-2025/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://retreat.ruby.nz\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-retreat-nz/series.yml",
    "content": "---\nname: \"Ruby Retreat NZ\"\nwebsite: \"https://ruby.nz\"\ntwitter: \"RubyNewZealand\"\nyoutube_channel_name: \"\"\nkind: \"retreat\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - Ruby Retreat New Zealand\n"
  },
  {
    "path": "data/ruby-romania/ruby-romania-meetup/event.yml",
    "content": "---\nid: \"ruby-romania\"\ntitle: \"Ruby Romania Meetup\"\nkind: \"meetup\"\nlocation: \"Romania\"\ndescription: \"\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#002B7F\"\nluma: \"https://lu.ma/ruby-romania\"\nmeetup: \"https://www.meetup.com/ruby-romania/\"\nyoutube: \"https://www.youtube.com/@RubyRomaniaCommunity\"\nwebsite: \"https://rubyromania.ro\"\ncoordinates:\n  latitude: 45.943161\n  longitude: 24.96676\n"
  },
  {
    "path": "data/ruby-romania/ruby-romania-meetup/videos.yml",
    "content": "---\n- title: \"Ruby Romania Meetup - November 2023 (Bucharest)\"\n  event_name: \"Ruby Romania meetup #01\"\n  date: \"2023-11-22\"\n  published_at: \"2023-11-21\"\n  announced_at: \"2023-10-21T09:11:39-04:00\"\n  video_provider: \"youtube\"\n  video_id: \"jKY8sjIoqNk\"\n  id: \"ruby-romania-meetup-november-2023\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/9/c/c/2/highres_516700130.webp\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/9/c/c/2/highres_516700130.webp\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/9/c/c/2/highres_516700130.webp\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/9/c/c/2/highres_516700130.webp\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/9/c/c/2/highres_516700130.webp\"\n  description: |-\n    Ruby Romania Meetup #01\n\n    Welcome to the Inaugural Ruby Romania Meetup!\n\n    Join us for our very first meetup where we'll have talks that delve into the practical application of Ruby in real-world scenarios and explore the latest developments in the language, presented by our two speakers, Jakob and Lucian.\n\n    **Agenda**\n\n    * \"Ticket Alert! Crafting a Cinema Watchdog with Ruby\" - [Jakob Cosoroabă](https://twitter.com/jcsrb)\n    * \"What's new in Ruby: A short history of language features from 2.7 to 3.2\" - [Lucian Ghinda](https://twitter.com/lucianghinda)\n\n    **Networking**\n\n    Connect with fellow Ruby enthusiasts, exchange ideas, and collaborate on exciting projects.\n\n    **Location**\n\n    Softia provided the space for our first edition, we'll be meeting at their office in **Soseaua Virtutii 19D, Bucuresti**, etaj 2.\n\n    Whether you're a seasoned Ruby developer or just starting your journey, this meetup is the perfect opportunity to learn, share, and grow within the Ruby community in Romania.\n    See you there!\n\n    https://www.meetup.com/ruby-romania/events/296874165\n  talks:\n    - title: \"Ticket Alert! Crafting a Cinema Watchdog with Ruby\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Ruby Romania Meetup - November 2023\"\n      date: \"2023-11-22\"\n      speakers:\n        - Jakob Cosoroabă\n      id: \"jakob-cosoroab-ruby-romania-meetup-november-2023\"\n      video_id: \"jakob-cosoroab-ruby-romania-meetup-november-2023\"\n      video_provider: \"parent\"\n\n    - title: \"What's new in Ruby: A short history of language features from 2.7 to 3.2\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Ruby Romania Meetup - November 2023\"\n      date: \"2023-11-22\"\n      speakers:\n        - Lucian Ghinda\n      id: \"lucian-ghinda-ruby-romania-meetup-november-2023\"\n      video_id: \"lucian-ghinda-ruby-romania-meetup-november-2023\"\n      video_provider: \"parent\"\n\n- title: \"Ruby Romania Meetup - February 2024 (Sibiu)\"\n  raw_title: \"Ruby Romania meetup #02 - in Sibiu\"\n  event_name: \"Ruby Romania Meetup - February 2024\"\n  date: \"2024-02-01\"\n  published_at: \"2024-02-04\"\n  location: \"Sibiu, Romania\"\n  announced_at: \"2024-01-11\"\n  video_provider: \"youtube\"\n  video_id: \"_zvR8y03N5s\"\n  id: \"ruby-romania-meetup-february-2024-sibiu\"\n  description: |-\n    Ruby Romania Meetup #02 - in Sibiu\n\n    Join us for an edition of Ruby Romania Meetup in Sibiu!\n\n    **Agenda**\n\n    * \"We're living the Ruby on Rails Renaissance\" - [Adrian Marin](https://twitter.com/adrianthedev)\n    * \"Ruby at scale: From Oscar awards to streaming services\" - [Alexandru Calinoiu](https://www.agilefreaks.com)\n\n    **Networking**\n\n    Connect with fellow Ruby enthusiasts, exchange ideas, and collaborate on exciting projects.\n\n    **Location**\n\n    We'll meet at Biblioteca Judeteana Astra, Corp B, Etaj V American Corner.\n\n    **Livestream**\n\n    Those who can't make it to Sibiu later this week but want to see the content can subscribe to the live stream: [https://youtube.com/live/UAFSyy3q6WU](https://youtube.com/live/UAFSyy3q6WU).\n\n    Whether you're a seasoned Ruby developer or just starting your journey, this meetup is the perfect opportunity to learn, share, and grow within the Ruby community in Romania.\n\n    https://www.meetup.com/ruby-romania/events/298491370\n  talks:\n    - title: \"We're living the Ruby on Rails Renaissance\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Ruby Romania Meetup - February 2024\"\n      date: \"2024-02-01\"\n      speakers:\n        - Adrian Marin\n      id: \"adrian-marin-ruby-romania-meetup-february-2024\"\n      video_id: \"adrian-marin-ruby-romania-meetup-february-2024\"\n      video_provider: \"parent\"\n\n    - title: \"Ruby at scale: From Oscar awards to streaming services\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Ruby Romania Meetup - February 2024\"\n      date: \"2024-02-01\"\n      speakers:\n        - Alexandru Calinoiu\n      id: \"alexandru-calinoiu-ruby-romania-meetup-february-2024\"\n      video_id: \"alexandru-calinoiu-ruby-romania-meetup-february-2024\"\n      video_provider: \"parent\"\n\n- id: \"ruby-romania-meetup-february-2024-bucharest\"\n  title: \"Ruby Romania Meetup - February 2024 (Bucharest)\"\n  raw_title: \"Ruby Romania meetup #03\"\n  event_name: \"Ruby Romania Meetup - February 2024\"\n  date: \"2024-02-08\"\n  announced_at: \"2024-01-22T06:01:14-05:00\"\n  video_provider: \"children\"\n  video_id: \"ruby-romania-meetup-february-2024-bucharest\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/3/a/6/d/highres_518954957.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/3/a/6/d/highres_518954957.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/3/a/6/d/highres_518954957.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/3/a/6/d/highres_518954957.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/3/a/6/d/highres_518954957.webp?w=750\"\n  description: |-\n    Ruby Romania Meetup #03\n\n    Join us for a laid-back evening of networking and fun at a local pub on February 8th at 18:30.\n\n    📍 Zeppelin Pub | Strada Marin Serghiescu 7, Bucuresti\n\n    🍻 Casual vibes, great conversations, and all things Ruby!\n\n    https://www.meetup.com/ruby-romania/events/298709446\n  talks: []\n\n- title: \"Ruby Romania Meetup - March 2024 (Bucharest)\"\n  event_name: \"Ruby Romania Meetup - March 2024\"\n  date: \"2024-03-14\"\n  published_at: \"2024-03-17\"\n  announced_at: \"2024-02-16\"\n  video_provider: \"youtube\"\n  video_id: \"Uu6kLEF-yQA\"\n  id: \"ruby-romania-meetup-march-2024\"\n  description: |-\n    Ruby Romania Meetup #04\n\n    Join us for the fourth edition of Ruby Romania Meetup!\n\n    **Agenda**\n\n    * \"Taming legacy databases with ActiveRecord\" - [Andrei Maxim](https://twitter.com/andreimaxim)\n    * \"HDA: O introducere practica cu Hotwire\" - [Gheorghiță Hurmuz](https://twitter.com/gheorghita)\n\n    **Networking**\n\n    Connect with fellow Ruby enthusiasts, exchange ideas, and collaborate on exciting projects.\n\n    **Location**\n\n    We'll meet at Hidden - The Social Space (Strada Doamna Chiajna 26, București)\n\n    **Livestream**\n\n    Those who can't make it but want to see the talks can subscribe to the live stream.\n\n    Whether you're a seasoned Ruby developer or just starting your journey, this meetup is the perfect opportunity to learn, share, and grow within the Ruby community in Romania.\n    See you there!\n\n    https://www.meetup.com/ruby-romania/events/299505611\n  talks:\n    - title: \"Taming legacy databases with ActiveRecord\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Ruby Romania Meetup - March 2024\"\n      date: \"2024-03-14\"\n      announced_at: \"2024-02-29\"\n      speakers:\n        - Andrei Maxim\n      id: \"andrei-maxim-ruby-romania-meetup-march-2024\"\n      video_id: \"andrei-maxim-ruby-romania-meetup-march-2024\"\n      video_provider: \"parent\"\n\n    - title: \"HDA: O introducere practica cu Hotwire\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Ruby Romania Meetup - March 2024\"\n      date: \"2024-03-14\"\n      announced_at: \"2024-02-29\"\n      speakers:\n        - Gheorghiță Hurmuz\n      id: \"gheorghita-hurmuz-ruby-romania-meetup-march-2024\"\n      video_id: \"gheorghita-hurmuz-ruby-romania-meetup-march-2024\"\n      video_provider: \"parent\"\n      language: \"romanian\"\n\n- id: \"ruby-romania-meetup-april-2024\"\n  title: \"Ruby Romania Meetup - April 2024 (Bucharest)\"\n  event_name: \"Ruby Romania Meetup - April 2024\"\n  date: \"2024-04-11\"\n  announced_at: \"2024-03-22\"\n  video_provider: \"children\"\n  video_id: \"ruby-romania-meetup-april-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/c/6/a/4/highres_520190852.webp\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/c/6/a/4/highres_520190852.webp\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/c/6/a/4/highres_520190852.webp\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/c/6/a/4/highres_520190852.webp\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/c/6/a/4/highres_520190852.webp\"\n  description: |-\n    Ruby Romania Meetup #05\n\n    Join us for a laid-back evening of networking and fun at a local pub on April 11th at 18:30.\n\n    **Location**\n\n    FIX ME A DRINK | Strada Ion Brezoianu 23-25, Universul, building B, floor 1, București\n\n    Casual vibes, great conversations, and all things Ruby!\n\n    https://www.meetup.com/ruby-romania/events/300231959\n  talks: []\n\n- title: \"Ruby Romania Meetup - April 2024 (Cluj)\"\n  raw_title: \"Ruby Romania meetup - in Cluj\"\n  event_name: \"Ruby Romania Meetup - April 2024\"\n  date: \"2024-04-16\"\n  published_at: \"2024-04-29\"\n  location: \"Cluj, Romania\"\n  announced_at: \"2024-02-29\"\n  video_provider: \"youtube\"\n  video_id: \"oSayjAko6-I\"\n  id: \"ruby-romania-meetup-april-2024-cluj\"\n  description: |-\n    Ruby Romania Meetup #06\n\n    Join us for an edition of Ruby Romania Meetup in Cluj!\n\n    **Agenda**\n\n    * \"Ruby ecosystem overview\" - [Victor Motogna](https://twitter.com/victormotogna)\n    * \"Building ActiveRecord features using vanilla Ruby & DSLs\" - [Cristian Chirtos](https://twitter.com/cristianchirtos)\n\n    **Networking**\n\n    Connect with fellow Ruby enthusiasts, exchange ideas, and collaborate on exciting projects.\n\n    **Location**\n\n    **Wolfpack Digital** will host us at their office in Emil Racovita 37 Street, Cluj-Napoca. They'll also provide the snacks and beverages 🙌\n\n    **Livestream**\n\n    Those who can't make it to Cluj but want to see the content can subscribe to the live stream.\n\n    Whether you're a seasoned Ruby developer or just starting your journey, this meetup is the perfect opportunity to learn, share, and grow within the Ruby community in Romania.\n    See you there!\n\n    https://www.meetup.com/ruby-romania/events/299505635\n  talks:\n    - title: \"Ruby ecosystem overview\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Ruby Romania Meetup - April 2024\"\n      date: \"2024-04-16\"\n      speakers:\n        - Victor Motogna\n      id: \"victor-motogna-ruby-romania-meetup-april-2024-cluj\"\n      video_id: \"victor-motogna-ruby-romania-meetup-april-2024-cluj\"\n      video_provider: \"parent\"\n\n    - title: \"Building ActiveRecord features using vanilla Ruby & DSLs\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      thumbnail_cue: \"TODO\"\n      event_name: \"Ruby Romania Meetup - April 2024\"\n      date: \"2024-04-16\"\n      speakers:\n        - Cristian Chirtos\n      id: \"cristian-chirtos-ruby-romania-meetup-april-2024-cluj\"\n      video_id: \"cristian-chirtos-ruby-romania-meetup-april-2024-cluj\"\n      video_provider: \"parent\"\n\n- id: \"ruby-romania-meetup-july-2024\"\n  title: \"Ruby Romania Meetup - July 2024 (Bucharest)\"\n  raw_title: \"Ruby Romania Meetup #05\"\n  event_name: \"Ruby Romania Meetup - July 2024\"\n  date: \"2024-07-11\"\n  location: \"Bucharest, Romania\"\n  announced_at: \"2024-07-03\"\n  video_provider: \"children\"\n  video_id: \"ruby-romania-meetup-july-2024\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/5/0/9/5/highres_522260629.webp\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/5/0/9/5/highres_522260629.webp\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/5/0/9/5/highres_522260629.webp\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/5/0/9/5/highres_522260629.webp\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/5/0/9/5/highres_522260629.webp\"\n  description: |-\n    Join us for the fifth edition of Ruby Romania Meetup!\n\n    **Agenda**\n\n    * \"Add a page builder to your next project\" - [Mihail Paleologu](https://twitter.com/mihailpaleologu)\n    * \"Teaching other programmers how to work with Ruby on Rails\" - [Andrei Maxim](https://twitter.com/andreimaxim)\n\n    **Networking**\n\n    Connect with fellow Ruby enthusiasts, exchange ideas, and collaborate on exciting projects.\n\n    **Location**\n\n    Softia will host us at their office in Soseaua Virtutii 19D, Bucharest.\n\n    **Livestream**\n\n    Whether you're a seasoned Ruby developer or just starting your journey, this meetup is the perfect opportunity to learn, share, and grow within the Ruby community in Romania.\n    See you there!\n\n    https://www.meetup.com/ruby-romania/events/302016838\n  talks:\n    - title: \"Add a page builder to your next project\"\n      event_name: \"Ruby Romania Meetup - July 2024\"\n      date: \"2024-07-11\"\n      announced_at: \"2024-07-03\"\n      speakers:\n        - Mihail Paleologu\n      id: \"mihail-paleologu-ruby-romania-meetup-july-2024\"\n      video_id: \"mihail-paleologu-ruby-romania-meetup-july-2024\"\n      video_provider: \"parent\"\n\n    - title: \"Teaching other programmers how to work with Ruby on Rails\"\n      event_name: \"Ruby Romania Meetup - July 2024\"\n      date: \"2024-07-11\"\n      announced_at: \"2024-07-03\"\n      speakers:\n        - Andrei Maxim\n      id: \"andrei-maxim-ruby-romania-meetup-july-2024\"\n      video_id: \"andrei-maxim-ruby-romania-meetup-july-2024\"\n      video_provider: \"parent\"\n\n- id: \"ruby-romania-meetup-february-2025\"\n  title: \"Ruby Romania Meetup - February 2025 (Bucharest)\"\n  raw_title: \"Ruby Romania Meetup | February 2025\"\n  event_name: \"Ruby Romania Meetup - February 2025\"\n  date: \"2025-02-27\"\n  location: \"Bucharest, Romania\"\n  announced_at: \"2025-02-12\"\n  video_provider: \"children\"\n  video_id: \"ruby-romania-meetup-february-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/6/a/6/c/highres_526347244.webp\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/6/a/6/c/highres_526347244.webp\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/6/a/6/c/highres_526347244.webp\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/6/a/6/c/highres_526347244.webp\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/6/a/6/c/highres_526347244.webp\"\n  description: |-\n    Join us for the February '25 edition of Ruby Romania Meetup!\n\n    **Agenda**\n\n    * \"Handling Traffic Spikes in Ruby: Lessons from the Trenches\" - [Andrei Maxim](https://twitter.com/andreimaxim)\n\n    **Networking**\n\n    Connect with fellow Ruby enthusiasts, exchange ideas, and collaborate on exciting projects.\n\n    **Location**\n\n    Stripe Romania will host us at their office in One Cotroceni Park, Building C, 11th Floor.\n\n    **Livestream**\n\n    Whether you're a seasoned Ruby developer or just starting your journey, this meetup is the perfect opportunity to learn, share, and grow within the Ruby community in Romania.\n    See you there!\n\n    https://www.meetup.com/ruby-romania/events/306133031\n  talks:\n    - title: \"Handling Traffic Spikes in Ruby: Lessons from the Trenches\"\n      event_name: \"Ruby Romania Meetup - February 2025\"\n      date: \"2025-02-27\"\n      announced_at: \"2025-02-12\"\n      speakers:\n        - Andrei Maxim\n      id: \"andrei-maxim-ruby-romania-meetup-february-2025\"\n      video_id: \"andrei-maxim-ruby-romania-meetup-february-2025\"\n      video_provider: \"parent\"\n"
  },
  {
    "path": "data/ruby-romania/series.yml",
    "content": "---\nname: \"Ruby Romania\"\nwebsite: \"https://rubyromania.ro\"\ntwitter: \"\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"RO\"\nyoutube_channel_name: \"RubyRomaniaCommunity\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-summit-china/ruby-summit-china-2018/event.yml",
    "content": "---\nid: \"ruby-summit-china-2018\"\ntitle: \"Ruby Summit China 2018\"\ndescription: \"\"\nlocation: \"ZhengZhou, Henan, China\"\nkind: \"conference\"\nstart_date: \"2018-10-13\"\nend_date: \"2018-10-14\"\nwebsite: \"http://rubysummit.cn/\"\ncoordinates:\n  latitude: 34.7472499\n  longitude: 113.62493\n"
  },
  {
    "path": "data/ruby-summit-china/ruby-summit-china-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubysummit.cn/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-summit-china/series.yml",
    "content": "---\nname: \"Ruby Summit China\"\nwebsite: \"http://rubysummit.cn/\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-tuesday/ruby-tuesday-meetup/event.yml",
    "content": "---\nid: \"ruby-tuesday-meetup\"\ntitle: \"Ruby Tuesday Meetup\"\nlocation: \"Osaka, Japan\"\ndescription: |-\n  A weekly Osaka gathering for focused hacking, lightning talks, and casual drinks around Ruby.\nwebsite: \"https://ruby-tuesday.doorkeeper.jp\"\nkind: \"meetup\"\nbanner_background: \"#0A0935\"\nfeatured_background: \"#0A0935\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 34.6937569\n  longitude: 135.5014539\n"
  },
  {
    "path": "data/ruby-tuesday/ruby-tuesday-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/ruby-tuesday/series.yml",
    "content": "---\nname: \"Ruby Tuesday\"\nwebsite: \"https://ruby-tuesday.doorkeeper.jp\"\nkind: \"meetup\"\nfrequency: \"weekly\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/ruby-turkiye/ruby-turkiye/event.yml",
    "content": "---\nid: \"PLEWqXxI7lAZLSsdkHtsfOQwS1M3fQAAU8\"\ntitle: \"Ruby Türkiye Meetup\"\nkind: \"meetup\"\nlocation: \"online\"\ndescription: |-\n  Türkiye'deki Ruby programcıları ve Ruby severler topluluğudur. Ruby ile program yazan ve ilgilenen herkese kapımız açıktır.\nchannel_id: \"UClXgXxIOKmdMY-EFOLvVgJQ\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#CC3822\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://kommunity.com/ruby-turkiye\"\ncoordinates: false\n"
  },
  {
    "path": "data/ruby-turkiye/ruby-turkiye/videos.yml",
    "content": "---\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/234939947\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/242193200\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/243270751\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/243854068\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/243977720\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/245631865\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/ruby-turkiye-bulusmasi-4\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/ruby-turkiye-bulusmasi-5\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/ruby-turkiye-bulusmasi-6\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/ruby-turkiye-bulusmasi-7\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/ruby-turkiye-bulusmasi-8-online-1-7166a878\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-3fe705b1\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-2-e96be617\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-2-e96be617\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-3-6eca96fa\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-4-0eda7b5b\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-5-05b09503\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-6-f6c14021\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-7-66fc320c\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-8-634fa5be\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-9-9a0cedf9\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-10-8fddb78b\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-11-91b58b5e\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-12-e20a493f\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/answers-to-common-ruby-on-rails-testing-questions-b2643150\n\n- id: \"murat-toygar-ruby-turkiye-meetup-june-2022\"\n  title: \"Optimizing Resource Utilization for Ruby processes\"\n  raw_title: \"Optimizing Resource Utilization for Ruby processes - Murat Toygar\"\n  speakers:\n    - Murat Toygar\n  event_name: \"Ruby Türkiye Meetup June 2022\"\n  date: \"2022-06-29\"\n  published_at: \"2022-07-02\"\n  language: \"turkish\"\n  description: |-\n    Ruby ile geliştirdiğiniz projeyi yayına aldınız ama RAM kullanımınız gittikçe artıyor mu? CPU yetmemeye mi başladı? Belki hata sizde değil, ondadır(configler). Bunun gibi bazı problemlerimizi ikinci makineyi açmadan, sunucuyu yeniden başlatmadan çözebiliriz. Nasıl mı, cevabı bu sunumda. :)\n\n  video_provider: \"youtube\"\n  video_id: \"PyBeX6pF45I\"\n\n- id: \"demirhan-aydin-ruby-turkiye-meetup-august-2022\"\n  title: \"Journey of building an analytics feature in a SaaS app\"\n  original_title: \"Bir SaaS uygulamasında veri analizi altyapısı oluşturma yolculuğu\"\n  raw_title: \"Bir SaaS uygulamasında veri analizi altyapısı oluşturma yolculuğu - Demirhan Aydin\"\n  speakers:\n    - Demirhan Aydin\n  event_name: \"Ruby Türkiye Meetup August 2022\"\n  date: \"2022-08-03\"\n  published_at: \"2024-01-21\"\n  language: \"turkish\"\n  description: |-\n    Çoğu B2B SaaS uygulaması müşterilerine analitik rapor özelliği sunar. Analitik rapor ihtiyacı kimi zaman basit, kimi zamansa oldukça karmaşık olabilir. Bu sunum, temel analitik raporlama özelliğinin nasıl büyüyebileceği, bir geliştirici olarak üzerinde çalışırken ne tür zorluklarla karşılaşabileceğiniz ve hangi araçları kullanabileceğiniz hakkında olacaktır.\n\n    Tamamen özgür bir ortamda Ruby ve bilgisayar bilimlerine dair konuları konuştuğumuz, yer yer gündemi değerlendirdiğimiz buluşmalarımıza sizi de bekleriz.\n  video_provider: \"youtube\"\n  video_id: \"jfqpEDW4uek\"\n\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/ruby-turkiye-istanbul-aksam-oturmasi-40105562\n\n- id: \"yaar-celep-ruby-turkiye-meetup-june-2023\"\n  title: \"Heroku'dan Kubernetes'e geçtik, ama nasıl?\"\n  raw_title: \"Heroku'dan Kubernetes'e geçtik, ama nasıl? - Yaşar Celep\"\n  speakers:\n    - Yaşar Celep\n  event_name: \"Ruby Türkiye Meetup June 2023\"\n  date: \"2023-06-21\"\n  published_at: \"2024-03-05\"\n  language: \"turkish\"\n  description: |-\n    2013'ten beri Türkiye'deki binlerce küçük ve orta işletmenin kullandığı, ön muhasebe programı Paraşüt'ün ana uygulaması dakikada yaklaşık 40 bin isteğe cevap veriyor.\n\n    Paraşüt'ün bu isteklere cevap verebilmesi ve takımların ihtiyaçlarını karşılamak için geliştirdiğimiz onlarca uygulamanın ihtiyaç duyduğu altyapının sağlanması ve ayakta kalması gibi bir çok sorumluluğu Heroku üstleniyordu. Bu yıla kadar. :)\n\n    Heroku'dan bu yıl tamamen çıktık, ama nasıl çıktık. Kubernetes'e taşıdık ve bitti gibi sihirli şeyler olmayan bu konuşmada; veritabanından takım çalışmasına birçok noktayı, karşılaştığımız sorunları, ve nasıl çözdüğümüzü konuşacağız.\n  video_provider: \"youtube\"\n  video_id: \"IqNXfB1jdlE\"\n\n- id: \"tayfun-zi-erikan-ruby-turkiye-meetup-january-2024\"\n  title: \"Akşam Oturması - 2024#01\"\n  raw_title: \"Akşam Oturması 31.01.2024\"\n  speakers:\n    - Tayfun Öziş Erikan #  Refactor from Turbo 7 to Turbo 8 in a Rails app with Hotwire: Hotwire ile geliştirilen Rails uygulamasında Turbo 7'den Turbo 8'e geçiş (veya yeniden düzenleme)\n    - Ender Ahmet Yurt # Feature Flags Development with Ruby on Rails: Bir Rails uygulamasında Feature Flag geliştirme yöntemi kullanımı\n  event_name: \"Ruby Türkiye Meetup January 2024\"\n  date: \"2024-01-31\"\n  published_at: \"2024-02-10\"\n  language: \"turkish\"\n  description: |-\n    Merhaba,\n\n    Bir Akşam Oturması online etkinliğinde daha bir araya geliyoruz. Arayı açtık biraz biliyoruz. Bu yüzden, iki sunum ile karşınızdayız.\n\n    Konuşmalar:\n\n    Tayfun Öziş Erikan - Refactor from Turbo 7 to Turbo 8 in a Rails app with Hotwire: Hotwire ile geliştirilen Rails uygulamasında Turbo 7'den Turbo 8'e geçiş (veya yeniden düzenleme)\n    Ender Ahmet Yurt - Feature Flags Development with Ruby on Rails: Bir Rails uygulamasında Feature Flag geliştirme yöntemi kullanımı\n    \\\n    Ruby yaz ya da yazma önemli değil. Sen de yeni insanalarla tanışmak, Ruby'nin sihirli dünyasında neler oluyormuş bi bakmak için bile bizlere katılabilirsin.\n\n    Sevgiler.\n  video_provider: \"youtube\"\n  video_id: \"4C-yJdvNi-U\"\n\n- id: \"berkan-nal-ruby-turkiye-meetup-february-2024\"\n  title: \"Akşam Oturması - 2024#02\"\n  raw_title: \"Akşam Oturması 29.02.2024\"\n  speakers:\n    - Berkan Ünal #  Null object pattern: Ruby’de null object pattern kullanımının örnek bir kod üzerinde refactoring yaparak gösterimi.\n    - Okan Davut # E2E Testing with Cypress: Bu sunum ile Frontend uygulamalarında End to end nedir? Neden gereklidir ve Cypress kullanarak End to End testlerinizi nasıl yazabilirsiniz bunlara değinilecektir.\n  event_name: \"Ruby Türkiye Meetup February 2024\"\n  date: \"2024-02-29\"\n  published_at: \"2024-03-01\"\n  language: \"turkish\"\n  description: |-\n    Merhaba,\n\n    Akşam Oturması etkinliklerimize ara vermeden devam ediyoruz. Bu buluşmamızda da, iki sunum ve sunumlar sonrasında tanışma, sohber etkinliklerimiz ile devam edeceğiz. Sizleri de aramızda görmek ve tanışmak istiyoruz.\n\n    Konuşmalar:\n\n    Berkan Ünal - Null object pattern: Ruby’de null object pattern kullanımının örnek bir kod üzerinde refactoring yaparak gösterimi.\n    Okan Davut - E2E Testing with Cypress: Bu sunum ile Frontend uygulamalarında End to end nedir? Neden gereklidir ve Cypress kullanarak End to End testlerinizi nasıl yazabilirsiniz bunlara değinilecektir.\n    \\\n    Ruby yaz ya da yazma önemli değil. Sen de yeni insanalarla tanışmak, Ruby'nin sihirli dünyasında neler oluyormuş bi bakmak için bile bizlere katılabilirsin.\n  video_provider: \"youtube\"\n  video_id: \"eaQ6GCYzxm8\"\n\n- id: \"ahmet-kaptan-ruby-turkiye-meetup-march-2024\"\n  title: \"RSpec ile Test Doubles: Mock ve Stub Kavramlarına Giriş\"\n  raw_title: \"Akşam Oturması 28.03.2024\"\n  speakers:\n    - Ahmet Kaptan\n  event_name: \"Ruby Türkiye Meetup March 2024\"\n  date: \"2024-03-28\"\n  published_at: \"2024-03-28\"\n  language: \"turkish\"\n  description: |-\n    Merhaba,\n\n     Akşam Oturmalarımıza devam ediyoruz. Bu sefer Ahmet Kaptan bizlerle RSpec ile Test Doubles: Mock ve Stub Kavramlarına Giriş başlıklı bir konuşma yapacak. Ahmet bizlere, Test Doubles (mock ve stub gibi) kavramsal tanıtımını yaparak, neden test süreçlerinde bu tür araçlara ihtiyaç duyulduğuna dair temel bir anlayış sunup, Test Doubles nasıl kullanılacağına dair temel kavramları kodlar ile açıklayacak. Kalan vakitte de sohbet edip, ne var yok konuşacağız.\n\n     Ruby dünyasındaki test kavramlarını merak ediyor, giriş yapmak istiyorsanız sizleri bekleriz. En önemlisi ise bizlerle tanışmak ve eğlenmek için sizleri bekliyoruz.\n\n     Sevgiler ❤️\n  video_provider: \"youtube\"\n  video_id: \"u4TIBlzJJ0s\"\n\n# TODO: missing meetup: https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-202404-eeae65c1\n\n- id: \"kasper-timm-hansen-ruby-turkiye-meetup-august-2024\"\n  title: \"Gem walkthrough: active_record-associated_object & Oaken\"\n  raw_title: \"Gem walk through: active_record-associated_object & Oaken - Kasper Timm Hansen\"\n  speakers:\n    - Kasper Timm Hansen\n  event_name: \"Ruby Türkiye Meetup August 2024\"\n  date: \"2024-08-20\"\n  published_at: \"2024-08-21\"\n  language: \"english\"\n  description: |-\n    Kasper Timm Hansen, is a seasoned Ruby developer and a core contributor to the Ruby on Rails framework between 2016-2022. He has made significant contributions to the Ruby community, particularly through his work on various gems that enhance the functionality of Rails.\n\n    \\\n\n    In this session, Kasper will walk us through some of his popular gems, active_record-associated_object and oaken. He will explore how these tools can help developers manage complex data relationships and simplify database interactions in their Ruby on Rails applications.\n  video_provider: \"youtube\"\n  video_id: \"DGatl7bH2yQ\"\n\n- id: \"ar-zkan-ruby-turkiye-meetup-october-2024\"\n  title: \"Don't Stop Representin' - Journey of Service Responses as Value Objects\"\n  raw_title: \"Akşam Oturması (23 Ekim 2024)\"\n  speakers:\n    - Çağrı Özkan\n  event_name: \"Ruby Türkiye Meetup October 2024\"\n  language: \"turkish\"\n  date: \"2024-10-23\"\n  published_at: \"2024-10-24\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"rvHyOIi9ZfA\"\n\n- id: \"marco-roth-ruby-turkiye-meetup-november-2024\"\n  title: \"Leveling Up Developer Tooling for the Modern Rails & Hotwire Era\"\n  raw_title: \"Leveling Up Developer Tooling for the Modern Rails & Hotwire Era - Marco Roth\"\n  speakers:\n    - Marco Roth\n  event_name: \"Ruby Türkiye Meetup November 2024\"\n  language: \"english\"\n  date: \"2024-11-20\"\n  published_at: \"2024-11-21\"\n  slides_url: \"https://speakerdeck.com/marcoroth/leveling-up-developer-tooling-for-the-modern-rails-and-hotwire-era-at-ruby-turkiye-november-2024\"\n  description: |-\n    The evolution of developer experience (DX) tooling has been a game-changer in how we build, debug, and enhance web applications.\n\n    This talk aims to illuminate the path toward enriching the Ruby on Rails ecosystem with advanced DX tools, focusing on the implementation of Language Server Protocols (LSP) for Stimulus and Turbo.\n\n    Drawing inspiration from the rapid advancements in JavaScript tooling, we explore the horizon of possibilities for Rails developers, including how advanced browser extensions and tools specifically designed for the Hotwire ecosystem can level up your developer experience.\n\n    https://kommunity.com/ruby-turkiye/events/leveling-up-developer-tooling-for-the-modern-rails-hotwire-era-671f5b80\n  video_provider: \"youtube\"\n  video_id: \"g2bVdaO8s7s\"\n\n- id: \"mehmet-etin-ruby-turkiye-meetup-december-2024\"\n  title: \"Going Fast with Ruby: Zero To Fintech in 42 Days\"\n  raw_title: \"Akşam Oturması 2024#08 (18/12/2024)\"\n  speakers:\n    - Mehmet Çetin\n  event_name: \"Ruby Türkiye Meetup December 2024\"\n  language: \"turkish\"\n  date: \"2024-12-18\"\n  published_at: \"2024-12-19\"\n  thumbnail_xs: \"https://media.kommunity.com/communities/ruby-turkiye/events/aksam-oturmasi-202408-be842d65/69368/mehmet.png\"\n  thumbnail_sm: \"https://media.kommunity.com/communities/ruby-turkiye/events/aksam-oturmasi-202408-be842d65/69368/mehmet.png\"\n  thumbnail_md: \"https://media.kommunity.com/communities/ruby-turkiye/events/aksam-oturmasi-202408-be842d65/69368/mehmet.png\"\n  thumbnail_lg: \"https://media.kommunity.com/communities/ruby-turkiye/events/aksam-oturmasi-202408-be842d65/69368/mehmet.png\"\n  thumbnail_xl: \"https://media.kommunity.com/communities/ruby-turkiye/events/aksam-oturmasi-202408-be842d65/69368/mehmet.png\"\n  description: |-\n    Merhabalar 👋\n\n    Aylık olarak yaptığımız Akşam Oturmalarımıza devam ediyoruz. Bu ay Mehmet Çetin konuşmacı konuğumuz olacak. Bizlere Going Fast with Ruby: Idea to Fintech in 42 Days başlık bir konuşma verecek. Bu konuşmada Mehmet, Ruby'nin geliştirici mutluluğuna ve sadeliğe odaklanan yapısının, küçük bir ekiple sadece 42 günde nasıl bir fintech platformu geliştirmelerini sağladığını paylaşıcak. Rails ve Ruby ekosisteminin gücüyle geliştirme ve test süreçlerini nasıl hızlandırdıklarını anlatacak. Ayrıca, çevik ekiplerin gücüne ve yapay zeka araçlarının geliştiricileri destekleyerek verimliliği artırma potansiyeline dikkat çekecek.\n\n    Sizleri de aramızda görmek, tanışmak ve sohbet etmek istiyoruz. Ruby ekosisteminin büyümesi ve gelişmesi adına meetup'da görüşmek üzere.\n\n    Sevgiler ❤️\n\n    https://kommunity.com/ruby-turkiye/events/aksam-oturmasi-202408-be842d65\n  video_provider: \"youtube\"\n  video_id: \"tZgNqrxd_E0\"\n\n- id: \"stephen-margheim-ruby-turkiye-meetup-january-2025\"\n  title: \"The present and future of SQLite on Rails\"\n  raw_title: \"The present and future of SQLite on Rails\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"Ruby Türkiye Meetup January 2025\"\n  language: \"english\"\n  date: \"2025-01-22\"\n  published_at: \"2025-01-23\"\n  thumbnail_xs: \"https://media.kommunity.com/communities/ruby-turkiye/events/the-present-and-future-of-sqlite-on-rails-79926ab2/70489/stephen.png\"\n  thumbnail_sm: \"https://media.kommunity.com/communities/ruby-turkiye/events/the-present-and-future-of-sqlite-on-rails-79926ab2/70489/stephen.png\"\n  thumbnail_md: \"https://media.kommunity.com/communities/ruby-turkiye/events/the-present-and-future-of-sqlite-on-rails-79926ab2/70489/stephen.png\"\n  thumbnail_lg: \"https://media.kommunity.com/communities/ruby-turkiye/events/the-present-and-future-of-sqlite-on-rails-79926ab2/70489/stephen.png\"\n  thumbnail_xl: \"https://media.kommunity.com/communities/ruby-turkiye/events/the-present-and-future-of-sqlite-on-rails-79926ab2/70489/stephen.png\"\n  description: |-\n    SQLite has gathered notable momentum this last year in the Rails ecosystem. Rails 8 marks the first release of Rails where SQLite is fully embraced and supported for production workloads across the core components that require persistent data. However, Rails isn’t slowing down, and more work is underway to continue making Rails the very best framework for building full-featured web applications. In this talk, I walk through the major changes that make SQLite on Rails the lovely experience it is today as well as the future innovations on the horizon.\n\n    https://kommunity.com/ruby-turkiye/events/the-present-and-future-of-sqlite-on-rails-79926ab2\n  video_provider: \"youtube\"\n  video_id: \"iGf9piw1lw0\"\n"
  },
  {
    "path": "data/ruby-turkiye/series.yml",
    "content": "---\nname: \"Ruby Türkiye\"\nwebsite: \"https://rubyturkiye.org\"\ntwitter: \"ruby_turkiye\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"TR\"\nyoutube_channel_name: \"rubyturkiyeorg\"\nlanguage: \"english\"\nyoutube_channel_id: \"UClXgXxIOKmdMY-EFOLvVgJQ\"\n"
  },
  {
    "path": "data/ruby-web-conference/ruby-web-conference-2010/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyafyFUlfIwxn9Gn2vclrrqH\"\ntitle: \"Ruby|Web Conference 2010\"\nkind: \"conference\"\ndescription: |-\n  September 9-10, 2010\nlocation: \"Snowbird, UT, United States\"\nstart_date: \"2010-09-09\"\nend_date: \"2010-09-10\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#911000\"\nbanner_background: \"#FFFFFF\"\nplaylist: \"https://www.youtube.com/playlist?list=PLE7tQUdRKcyafyFUlfIwxn9Gn2vclrrqH\"\nwebsite: \"https://web.archive.org/web/20110207142810/http://rubywebconf.org/\"\noriginal_website: \"http://rubywebconf.org\"\ncoordinates:\n  latitude: 40.5829259\n  longitude: -111.6556388\n"
  },
  {
    "path": "data/ruby-web-conference/ruby-web-conference-2010/videos.yml",
    "content": "# Website: https://web.archive.org/web/20100906085256/http://rubywebconf.org/\n# Schedule: https://web.archive.org/web/20100906085256/http://rubywebconf.org/schedule\n---\n# Thursday, September 9, 2010\n\n- id: \"david-richards-rubyweb-conference-2010\"\n  title: \"Integrating Web Apps\"\n  raw_title: \"Ruby|Web Conference 2010 - Integrating Web Apps By David Richards\"\n  speakers:\n    - David Richards\n  date: \"2010-09-09\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    Most useful applications today integrate with other services. Learning to build simple, focused applications that connect to more robust solutions can be as much of an art as it is a science. This presentation is a collection of ideas implemented by successful applications as well as the presenter's own experiences connecting his apps to other systems. Technologies covered include ActiveResource, DataMapper Adapters, as well as custom connection technologies.\n  video_provider: \"youtube\"\n  video_id: \"lXZQK_7soxg\"\n\n- id: \"nicholas-audo-rubyweb-conference-2010\"\n  title: \"Make Friends and Influence People with HTML5\"\n  raw_title: \"Ruby|Web Conference 2010 - Make Friends and Influence People with HTML5 by Nicholas Audo\"\n  speakers:\n    - Nicholas Audo\n  date: \"2010-09-09\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    In case you've been living under a rock for the past couple of years, chances are you've heard of HTML5 and even seen some demos. This talk will dive deeper than just the video tag and show how you can start leveraging HTML5 features in your webapps today. There will be plenty of code examples so come ready to get your hands dirty.\n  video_provider: \"youtube\"\n  video_id: \"mNjJ_X_AZUw\"\n\n- id: \"matthew-thorley-rubyweb-conference-2010\"\n  title: \"Dirt Simple Datamining\"\n  raw_title: \"Ruby|Web Conference 2010 - Dirt Simple Datamining By Matthew Thorley\"\n  speakers:\n    - Matthew Thorley\n  date: \"2010-09-09\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    Maybe you need a bot to track the price of vintage all-metal Optimus Prime figurines on Ebay or Craigslist. Or maybe you want to monitor blogs and Twitter for references to his Energon Axe. It could be that your ready for romance and need an automated way to find others, on nerdpassions.com, who share your affection for Halflings and Hawking. Or perhaps you just want to find out a little more about your clients, customers or competition.\n  video_provider: \"youtube\"\n  video_id: \"6b4O5iuFuNA\"\n\n- id: \"luigi-montanez-ruby-web-conference-2010\"\n  title: \"Search Friendly Web Development\"\n  raw_title: \"Ruby|Web Conference 2010 - Search Friendly Web Development By Luigi Montanez\"\n  speakers:\n    - Luigi Montanez\n  date: \"2010-09-09\"\n  event_name: \"Ruby|Web Conference 2010\"\n  description: |-\n    Search Engine Optimization, or SEO, has justifiably gotten a bad reputation over the years. SEO experts seem like nothing more than snake oil salesmen and spammers. But we as Rails web developers ignore search engines at our own peril. For the average site, over half of all traffic will come in through search engines: Google, Yahoo!, and Bing. While developing web apps, we need to keep searchability close to the top of our priorities. Implementing best practices when it comes to search is just as important as practicing TDD and keeping code DRY -- it should be a core competency for professional web developers. This talk will cover how search engines work, how to work with search engines, and how to develop your Ruby web apps with search engines in mind.\n  video_provider: \"not_published\"\n  video_id: \"luigi-montanez-ruby-web-conference-2010\"\n\n- id: \"bj-clark-rubyweb-conference-2010\"\n  title: \"Dr. Strangelove or: How I Learned to Stop Worrying and Love HTML, CSS...\"\n  raw_title: \"Ruby|Web Conference 2010 - Dr. Strangelove or: How I Learned to Stop Worrying and Love HTML, CSS...\"\n  speakers:\n    - BJ Clark\n  date: \"2010-09-09\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    In this session we'll take a hands on approach to building reusable and scaleable front end code in a Ruby application. We walk through building a modern web application UI using microformats, gracefully degrading CSS3 and Javascript closures and bunch of ruby tools that make it easy to do this. We'll finish up by seeing how the same code can be used throughout an application with little modification.\n  video_provider: \"youtube\"\n  video_id: \"ii6gGbDb69s\"\n\n- id: \"brad-midgley-ruby-web-conference-2010\"\n  title: \"Coming soon... 3D without plugins\"\n  raw_title: \"Ruby|Web Conference 2010 - Coming soon... 3D without plugins By Brad Midgley\"\n  speakers:\n    - Brad Midgley\n  date: \"2010-09-09\"\n  event_name: \"Ruby|Web Conference 2010\"\n  description: |-\n    WebGL is an emerging standard that (finally) brings native 3D to web browsers on devices large and small. Javascript libraries like GLGE, SpiderGL, and ProcessingJS help plug you in for using it. Use it for visualization or entertainment, but either way, build something that can't be done any other way. Grab a nightly build of your favorite browser and let's dive in.\n  video_provider: \"not_published\"\n  video_id: \"brad-midgley-ruby-web-conference-2010\"\n\n- id: \"matt-white-rubyweb-conference-2010\"\n  title: \"How TDD and CDD make your apps suck less\"\n  raw_title: \"Ruby|Web Conference 2010 - How TDD and CDD make your apps suck less By Matt White\"\n  speakers:\n    - Matt White\n  date: \"2010-09-09\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    Do you ever look back at code you've written in the past and think, \"Wow, this sucks\"? Following simple Test Driven Development and Comment Driven Development methods can make your code suck much less.\n  video_provider: \"youtube\"\n  video_id: \"-haFew1DuQQ\"\n\n- id: \"charles-max-wood-rubyweb-conference-2010\"\n  title: \"The Power of Middleware - Building Your Own Mini Web Framework on Rack\"\n  raw_title: \"Ruby|Web Conference 2010 - The Power of Middleware - Building Your Own Mini Web Framework on Rack\"\n  speakers:\n    - Charles Max Wood\n  date: \"2010-09-09\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    Rack has become the de-facto standard for developing web frameworks. It is also supported by nearly all of the popular web servers for Ruby applications. Part of its simplicity is what makes it so powerful. By stacking one application on top of another and delegating through the stack to the right application, one can build a relatively simple web framework.\n  video_provider: \"youtube\"\n  video_id: \"XjX_8ynFpBw\"\n\n# Friday, September 10, 2010\n\n- id: \"nick-howard-ruby-web-conference-2010\"\n  title: \"Extreme Performance with Mirah and Dubious\"\n  raw_title: \"Ruby|Web Conference 2010 - Extreme Performance with Mirah and Dubious By Nick Howard\"\n  speakers:\n    - Nick Howard\n  date: \"2010-09-10\"\n  event_name: \"Ruby|Web Conference 2010\"\n  description: |-\n    Developers are now deploying Rails and Sinatra applications to Google App Engine. These apps run in a servlet container, with access to all the Java APIs. Unlike a traditional Ruby hosting environment, new app instances spin-up on-demand, so you avoid paying for servers that sit idle. Unfortunately, new Rails instances can take sixteen seconds (or more) to spin-up.\n  video_provider: \"not_published\"\n  video_id: \"nick-howard-ruby-web-conference-2010\"\n\n- id: \"brian-sam-bodden-rubyweb-conference-2010\"\n  title: \"Trellis: A Component-Oriented Web Framework\"\n  raw_title: \"Ruby|Web Conference 2010 - Trellis: A Component-Oriented Web Framework\"\n  speakers:\n    - Brian Sam-Bodden\n  date: \"2010-09-10\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    Trellis is a component-based, event-driven Web micro-framework that provides a DSL to describe web applications in terms of pages, components and events. It combines the best features of desktop application development and modern MVC frameworks like Rails and Sinatra. Trellis pushes the complexity of building web applications onto components allowing you to build simple lightweight applications or complex, feature-rich applications.\n  video_provider: \"youtube\"\n  video_id: \"SpOrtpdKhNs\"\n\n- id: \"pat-maddox-rubyweb-conference-2010\"\n  title: \"Code Immersion: Building a Rails 3.0 app using Cucumber and Rspec\"\n  raw_title: \"Ruby|Web Conference 2010 - Code Immersion: Building a Rails 3.0 app using Cucumber and Rspec\"\n  speakers:\n    - Pat Maddox\n    - BJ Clark\n  date: \"2010-09-10\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"JrQ036q-iTs\"\n\n- id: \"evan-light-rubyweb-conference-2010\"\n  title: \"iOS Eye for the Rails Guy\"\n  raw_title: \"Ruby|Web Conference 2010 - iOS Eye for the Rails Guy By Evan Light\"\n  speakers:\n    - Evan Light\n  date: \"2010-09-10\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    Ruby developers tend to be technology-curious. We love to explore. We also, often, find ourselves writing back ends to iPhone/iOS front ends. However, Rails and iOS have more in common than you may know. I'll demonstrate how you can leverage your existing Rails skills to learn how to develop for iOS.\n  video_provider: \"youtube\"\n  video_id: \"D1G_dirTwb0\"\n\n- id: \"pat-maddox-ruby-web-conference-2010\"\n  title: \"Takin' the railway down to the seaside\"\n  raw_title: \"Ruby|Web Conference 2010 - Takin' the railway down to the seaside By Pat Maddox\"\n  speakers:\n    - Pat Maddox\n  date: \"2010-09-10\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    Rails became a wild success because it took so many problems that web developers had and wiped them away. After programming Rails for five years, I've definitely run into some of its limitations and have written some pretty interesting code to work around them. So when I came across Seaside and it appeared to wipe away some of the problems I had with Rails, I was intrigued. Seaside is a web framework unlike any other you've seen before. It's continuations-based, written in Smalltalk, and uses hideous URLs by default. What it lacks in approachability it makes up for with expressiveness, simplicity, and developer tools that will make you giddy. In this talk I will demonstrate how Seaside's unique approach to web application development can make your life easier and more fun. I will show off some of the areas that Seaside is particularly strong in, and show how easily Rails can integrate with Seaside so you can take advantage of the best that each of these amazing frameworks has to offer.\n  video_provider: \"youtube\"\n  video_id: \"j_DCvRIgaRY\"\n\n- id: \"rogelio-j-samour-rubyweb-conference-2010\"\n  title: \"No Sudo for You!\"\n  raw_title: \"Ruby|Web Conference 2010 - No Sudo for You! By Rogelio J. Samour\"\n  speakers:\n    - Rogelio J. Samour\n  date: \"2010-09-10\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    As developers, we want to minimize the time we spend fighting with our development environment. The less time we spend dealing with configuration issues, the more time we can spend doing what we do best... creating awesome apps! I show how you can easily set up a development environment that is both flexible and powerful. But best of all, it won't need regular attention!\n  video_provider: \"youtube\"\n  video_id: \"XyO5fnmoJXI\"\n\n- id: \"joe-obrien-rubyweb-conference-2010\"\n  title: \"Your Customers Aren't Stupid and Your Coworkers Are Not Incompetent\"\n  raw_title: \"Ruby|Web Conference 2010 - Your Customers Aren't Stupid and Your Coworkers Are Not Incompetent\"\n  speakers:\n    - Joe O'Brien\n  date: \"2010-09-10\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-14\"\n  description: |-\n    Communication is hard. No doubt about it. Many of us, being geeks at heart, have an inherently difficult time communicating with people. Why is it that if we look around, it seems that all we see is incompetence? Why is it that we struggle to get our point across? Why do customers and bosses always seem stupid?\n\n    In this talk we will focus on communication. How to more effectively listen and speak. We will discuss some patterns that we can look for in ourselves. We will talk about strategies on how can we take a step back and realize what it is we are trying to say and hopefully uncover what it is that our bosses and customers are really hearing.\n\n    I will also walk you through strategies on how to have those difficult conversations and steps that I've learned through my years in sales, consulting, project management and business ownership.\n  video_provider: \"youtube\"\n  video_id: \"yDdiAbgGJh0\"\n\n- id: \"alistair-cockburn-rubyweb-conference-2010\"\n  title: \"The 7 Habits of Highly Successful Samurai, and How That Helps Rubyists\"\n  raw_title: \"Ruby|Web Conference 2010 - The 7 Habits of Highly Successful Samurai, and How That Helps Rubyists\"\n  speakers:\n    - Alistair Cockburn\n  date: \"2010-09-10\"\n  event_name: \"Ruby|Web Conference 2010\"\n  published_at: \"2016-01-20\"\n  description: |-\n    The Crystal 3-step model consists of practices, principles, and personalization. The practices are what you know or learn how to do. The principles are the laws of design that inform you as to what works better, when. Personalization is adapting yourself to your situation, and your practices to your personality. In this closing keynote, Dr. Alistair Cockburn will incorporate the history of Agile development (which started at Snowbird) into the evolution of what we know about software development, leading to how to use the Crystal 3-step model to improve your and your team's performance.\n  video_provider: \"youtube\"\n  video_id: \"dSMFIsMSkbI\"\n"
  },
  {
    "path": "data/ruby-web-conference/series.yml",
    "content": "---\nname: \"Ruby|Web Conference\"\nwebsite: \"https://web.archive.org/web/20110207142810/http://rubywebconf.org/\"\ntwitter: \"\"\nmastodon: \"\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/ruby-wine/ruby-wine-2019/event.yml",
    "content": "---\nid: \"ruby-wine-2019\"\ntitle: \"Ruby Wine 2019\"\ndescription: \"\"\nlocation: \"Chișinău, Moldova\"\nkind: \"conference\"\nstart_date: \"2019-04-13\"\nend_date: \"2019-04-13\"\nwebsite: \"https://www.facebook.com/events/551051368675115/\"\nplaylist: \"https://www.youtube.com/playlist?list=PLRQ_gUZhiTmvN_KgcpEkREJF-tD43W7jZ\"\ncoordinates:\n  latitude: 47.0104529\n  longitude: 28.8638103\n"
  },
  {
    "path": "data/ruby-wine/ruby-wine-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://www.facebook.com/events/551051368675115/\n# Videos: https://www.youtube.com/playlist?list=PLRQ_gUZhiTmvN_KgcpEkREJF-tD43W7jZ\n---\n[]\n"
  },
  {
    "path": "data/ruby-wine/ruby-wine-2020/event.yml",
    "content": "---\nid: \"ruby-wine-2020\"\ntitle: \"Ruby Wine 2.0\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2020-04-04\"\nend_date: \"2020-04-04\"\nwebsite: \"https://www.rubywine.org\"\ntwitter: \"rubymeditation\"\ncoordinates: false\n"
  },
  {
    "path": "data/ruby-wine/ruby-wine-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://www.rubywine.org\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/ruby-wine/series.yml",
    "content": "---\nname: \"Ruby Wine\"\nwebsite: \"https://www.facebook.com/events/551051368675115/\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubybelgium/rubybelgium-meetup/event.yml",
    "content": "---\nid: \"rubybelgium-meetup\"\ntitle: \"Ruby Belgium Meetup\"\nlocation: \"Belgium\"\ndescription: |-\n  Ruby Belgium is a community of programming enthusiasts using ruby as a tool to connect, build and share knowledge.\nkind: \"meetup\"\nwebsite: \"https://rubybelgium.be\"\nbanner_background: \"#921213\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#901E1E\"\ncoordinates:\n  latitude: 50.503887\n  longitude: 4.469936\n"
  },
  {
    "path": "data/rubybelgium/rubybelgium-meetup/videos.yml",
    "content": "---\n- id: \"rubybelgium-july-2025\"\n  title: \"Ruby Belgium July 2025\"\n  raw_title: \"Ruby Belgium Meetup Summer 2025\"\n  event_name: \"Ruby Belgium July 2025\"\n  date: \"2025-07-01\"\n  video_provider: \"children\"\n  video_id: \"rubybelgium-july-2025\"\n  description: |-\n    Code Together events are back for Ruby Belgium this summer thanks to Leexi\n\n    Join us for the evening and listen to two amazing speakers, including... you?! Talks can be submit to louisramosdev@gmail.com, we'll make sure to get back to you very fast.\n\n    The location is in Leexi's office, Av. Herrmann-Debroux 2/floor 1, 1160 Auderghem\n\n    18.00 - Doors (Pizzas & Drinks!)\n\n    19.30 - Talk 1:\n\n    By: Kevin Vanzandberghe\n    Title: Mental Phlexibility\n    Desc:\n    Building on an already cutting-edge stack (Hotwire, Tailwind, Phlex) that made me challenge a lot of assumptions as a Rails developer, over the last 18 months, I decided to go all-in and challenge even more things we take for granted.\n    Can we let Devise go? Can we get away with SQLite in production? Can we finally ditch Redis? Can E2E specs actually be fast?\n    The answer might not be an enthusiastic yes for all, but there's a lot of value in asking and playing around.\n\n    20.00 - Break\n\n    20.30 - Talk 2:\n\n    By: Pablo Curell Mompo\n    Title: TDD: be effective (and efficient)\n    Desc:\n    In this talk, Pablo walk us to through an exercise of Advent of Code using TDD with minitest.\n\n    Outline:\n\n    * What is TDD\n    * A bit of theory\n    * Exercise.\n    * Lessons learned.\n\n    21.00 - Networking & Knowledge Sharing\n\n    Got any cool Ruby projects? Be sure to bring them along!\n\n    Sponsored by: Leexi\n\n    https://lu.ma/g8adodhj\n  talks:\n    - title: \"Mental Phlexibility\"\n      event_name: \"Ruby Belgium July 2025\"\n      date: \"2025-07-01\"\n      speakers:\n        - Kevin Vanzandberghe\n      video_id: \"kevin-vanzandberghe-ruby-belgium-july-2025\"\n      video_provider: \"parent\"\n      id: \"kevin-vanzandberghe-ruby-belgium-july-2025\"\n      description: |-\n        Building on an already cutting-edge stack (Hotwire, Tailwind, Phlex) that made me challenge a lot of assumptions as a Rails developer, over the last 18 months, I decided to go all-in and challenge even more things we take for granted.\n\n        Can we let Devise go? Can we get away with SQLite in production? Can we finally ditch Redis? Can E2E specs actually be fast?\n\n        The answer might not be an enthusiastic yes for all, but there's a lot of value in asking and playing around.\n\n    - title: \"TDD: be effective (and efficient)\"\n      event_name: \"Ruby Belgium July 2025\"\n      date: \"2025-07-01\"\n      speakers:\n        - Pablo Curell Mompo\n      video_id: \"pablo-curell-mompo-ruby-belgium-july-2025\"\n      video_provider: \"parent\"\n      id: \"pablo-curell-mompo-ruby-belgium-july-2025\"\n      description: |-\n        In this talk, Pablo walk us to through an exercise of Advent of Code using TDD with minitest.\n\n        Outline:\n\n        * What is TDD\n        * A bit of theory\n        * Exercise.\n        * Lessons learned.\n"
  },
  {
    "path": "data/rubybelgium/series.yml",
    "content": "---\nname: \"Ruby Belgium\"\nwebsite: \"https://rubybelgium.be\"\ntwitter: \"rubybelgium\"\nluma: \"https://lu.ma/rubybelgium\"\nlinkedin: \"https://www.linkedin.com/company/ruby-belgium\"\nkind: \"organisation\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"BE\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - rubybelgium\n"
  },
  {
    "path": "data/rubyc/rubyc-2014/event.yml",
    "content": "---\nid: \"rubyc-2014\"\ntitle: \"RubyC 2014\"\ndescription: \"\"\nlocation: \"Kiev, Ukraine\"\nkind: \"conference\"\nstart_date: \"2014-05-31\"\nend_date: \"2014-06-01\"\nwebsite: \"http://rubyc.eu/\"\ntwitter: \"rubyc_eu\"\nplaylist: \"https://rubyc.eu/archives/4\"\ncoordinates:\n  latitude: 50.4503596\n  longitude: 30.5245025\n"
  },
  {
    "path": "data/rubyc/rubyc-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyc.eu/\n# Videos: https://rubyc.eu/archives/4\n---\n[]\n"
  },
  {
    "path": "data/rubyc/rubyc-2015/event.yml",
    "content": "---\nid: \"rubyc-2015\"\ntitle: \"RubyC 2015\"\ndescription: \"\"\nlocation: \"Kiev, Ukraine\"\nkind: \"conference\"\nstart_date: \"2015-05-30\"\nend_date: \"2015-05-31\"\nwebsite: \"http://rubyc.eu/\"\ntwitter: \"rubyc_eu\"\nplaylist: \"https://rubyc.eu/archives/5\"\ncoordinates:\n  latitude: 50.4503596\n  longitude: 30.5245025\n"
  },
  {
    "path": "data/rubyc/rubyc-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyc.eu/\n# Videos: https://rubyc.eu/archives/5\n---\n[]\n"
  },
  {
    "path": "data/rubyc/rubyc-2016/event.yml",
    "content": "---\nid: \"rubyc-2016\"\ntitle: \"RubyC 2016\"\ndescription: \"\"\nlocation: \"Kiev, Ukraine\"\nkind: \"conference\"\nstart_date: \"2016-06-04\"\nend_date: \"2016-06-05\"\nwebsite: \"http://rubyc.eu/\"\ntwitter: \"rubyc_eu\"\nplaylist: \"https://rubyc.eu/posts/55\"\ncoordinates:\n  latitude: 50.4503596\n  longitude: 30.5245025\n"
  },
  {
    "path": "data/rubyc/rubyc-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyc.eu/\n# Videos: https://rubyc.eu/posts/55\n---\n[]\n"
  },
  {
    "path": "data/rubyc/rubyc-2017/event.yml",
    "content": "---\nid: \"rubyc-2017\"\ntitle: \"RubyC 2017\"\ndescription: \"\"\nlocation: \"Kyiv, Ukraine\"\nkind: \"conference\"\nstart_date: \"2017-06-03\"\nend_date: \"2017-06-04\"\nwebsite: \"http://rubyc.eu/\"\ntwitter: \"rubyc_eu\"\nplaylist: \"https://rubyc.eu/posts/75\"\ncoordinates:\n  latitude: 50.4503596\n  longitude: 30.5245025\n"
  },
  {
    "path": "data/rubyc/rubyc-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyc.eu/\n# Videos: https://rubyc.eu/posts/75\n---\n[]\n"
  },
  {
    "path": "data/rubyc/rubyc-2018/event.yml",
    "content": "---\nid: \"rubyc-2018\"\ntitle: \"RubyC 2018\"\ndescription: \"\"\nlocation: \"Kyiv, Ukraine\"\nkind: \"conference\"\nstart_date: \"2018-06-02\"\nend_date: \"2018-06-03\"\nwebsite: \"http://rubyc.eu/\"\ntwitter: \"rubyc_eu\"\nplaylist: \"https://rubyc.eu/posts/93\"\ncoordinates:\n  latitude: 50.4503596\n  longitude: 30.5245025\n"
  },
  {
    "path": "data/rubyc/rubyc-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyc.eu/\n# Videos: https://rubyc.eu/posts/93\n---\n[]\n"
  },
  {
    "path": "data/rubyc/rubyc-2019/event.yml",
    "content": "---\nid: \"rubyc-2019\"\ntitle: \"RubyC 2019\"\ndescription: \"\"\nlocation: \"Kyiv, Ukraine\"\nkind: \"conference\"\nstart_date: \"2019-09-14\"\nend_date: \"2019-09-15\"\nwebsite: \"https://rubyc.eu/\"\ntwitter: \"rubyc_eu\"\nplaylist: \"https://www.youtube.com/playlist?list=PLmEf5ppiRneTkaPA4fz6KBQKq-jAvTRkb\"\ncoordinates:\n  latitude: 50.4503596\n  longitude: 30.5245025\n"
  },
  {
    "path": "data/rubyc/rubyc-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyc.eu/\n# Videos: https://www.youtube.com/playlist?list=PLmEf5ppiRneTkaPA4fz6KBQKq-jAvTRkb\n---\n[]\n"
  },
  {
    "path": "data/rubyc/rubyc-2020/event.yml",
    "content": "---\nid: \"rubyc-2020\"\ntitle: \"RubyC 2020 (Cancelled)\"\ndescription: \"\"\nlocation: \"Kyiv, Ukraine\"\nkind: \"conference\"\nstart_date: \"2020-09-12\"\nend_date: \"2020-09-13\"\nwebsite: \"https://rubyc.eu/\"\nstatus: \"cancelled\"\ntwitter: \"rubyc_eu\"\ncoordinates:\n  latitude: 50.4503596\n  longitude: 30.5245025\n"
  },
  {
    "path": "data/rubyc/rubyc-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyc.eu/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyc/series.yml",
    "content": "---\nname: \"RubyC\"\nwebsite: \"http://rubyc.eu/\"\ntwitter: \"rubyc_eu\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubycon/rubycon-2026/cfp.yml",
    "content": "---\n- link: \"https://rubycon.it/cfp\"\n  open_date: \"2025-08-11\"\n  close_date: \"2026-01-15\"\n"
  },
  {
    "path": "data/rubycon/rubycon-2026/event.yml",
    "content": "---\nid: \"rubycon-2026\"\ntitle: \"Rubycon 2026\"\nkind: \"conference\"\nlocation: \"Rimini, Italy\"\ndescription: |-\n  Veni, Vidi, Codi. An unforgettable gathering of the Ruby clan. Alea iacta REST!\npublished_at: \"\"\nstart_date: \"2026-05-08\"\nend_date: \"2026-05-08\"\nwebsite: \"https://www.rubycon.it\"\ntickets_url: \"https://ti.to/rubycon/rubycon-2026\"\nbanner_background: \"#802125\"\nfeatured_background: \"#802125\"\nfeatured_color: \"#FDF7E9\"\ncoordinates:\n  latitude: 44.068849\n  longitude: 12.580334\n"
  },
  {
    "path": "data/rubycon/rubycon-2026/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Riccardo Carlesso\n    - Alessandro Rodi\n    - Emiliano Della Casa\n    - Elia Gamberi\n    - Alessia Ragni\n    - Federico Fois\n"
  },
  {
    "path": "data/rubycon/rubycon-2026/schedule.yml",
    "content": "---\ndays:\n  - name: \"Rubycon 2026\"\n    date: \"2026-05-08\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Check-in & Welcome Coffee\n\n      - start_time: \"09:30\"\n        end_time: \"09:45\"\n        slots: 1\n\n      - start_time: \"09:45\"\n        end_time: \"10:25\"\n        slots: 1\n\n      - start_time: \"10:25\"\n        end_time: \"11:05\"\n        slots: 1\n\n      - start_time: \"11:05\"\n        end_time: \"11:20\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"11:20\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:40\"\n        slots: 1\n\n      - start_time: \"12:40\"\n        end_time: \"13:45\"\n        slots: 1\n        items:\n          - Lunch Break & Networking\n\n      - start_time: \"13:45\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"15:25\"\n        slots: 1\n\n      - start_time: \"15:25\"\n        end_time: \"16:05\"\n        slots: 1\n\n      - start_time: \"16:05\"\n        end_time: \"16:20\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"16:20\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:40\"\n        slots: 1\n\n      - start_time: \"17:40\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - Drinks or Shower or Nap\n\n      - start_time: \"20:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - \"Dinner + Toga Party! @ Bagno 46\"\n"
  },
  {
    "path": "data/rubycon/rubycon-2026/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Imperator\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Wide Group\"\n          website: \"https://www.widegroup.eu/\"\n          slug: \"wide-group\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/imperator/wide_group.png\"\n\n    - name: \"Triumvir\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"typesense\"\n          description: |-\n            TypeSense is a fast, open-source, and distributed search engine that provides a fast and efficient way to search through large datasets.\n\n        - name: \"DatoCMS\"\n          website: \"https://datocms.com/\"\n          slug: \"datocms\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/triumvir/datocms.svg\"\n          description: |-\n            Simply put, the most complete, user-friendly and performant Headless CMS\n\n    - name: \"Praetor\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://appsignal.com/\"\n          slug: \"appsignal\"\n\n        - name: \"weLaika\"\n          website: \"https://welaika.com/\"\n          slug: \"welaika\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/praetor/weLaika.png\"\n\n        - name: \"Seesaw\"\n          website: \"https://seesaw.it/\"\n          slug: \"seesaw\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/praetor/seesaw.svg%20fill.png\"\n\n        - name: \"Fancy Pixel\"\n          website: \"https://www.fancypixel.it/\"\n          slug: \"fancy-pixel\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/praetor/fancy_pixel%201.png\"\n\n    - name: \"Quaestor\"\n      description: \"\"\n      level: 4\n      sponsors:\n        - name: \"Netframe\"\n          website: \"https://netframe.it/\"\n          slug: \"netframe\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/quaestor/netframe.png\"\n\n        - name: \"Engim\"\n          website: \"https://www.engim.eu/\"\n          slug: \"engim\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/quaestor/Engim.png\"\n\n        - name: \"Deploio\"\n          website: \"https://www.deplo.io/\"\n          slug: \"deploio\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/quaestor/Deploio.png\"\n\n    - name: \"Community\"\n      description: \"\"\n      level: 5\n      sponsors:\n        - name: \"Dev Fest Modena\"\n          website: \"https://devfest.modena.it/\"\n          slug: \"devfest-modena\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/community/devfest.webp\"\n          description: |-\n            An annual technology conference dedicated to developers, IT professionals, students, and tech enthusiasts, organized by the Google Developer Group (GDG) Cloud of Modena.\n\n        - name: \"GrUSP\"\n          website: \"https://www.grusp.org/\"\n          slug: \"grusp\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/community/grusp.png\"\n          description: |-\n            GrUSP è una associazione no-profit che ha come scopo il miglioramento dell'ecosistema del mondo dello sviluppo web in Italia\n\n        - name: \"Helvetic Ruby\"\n          website: \"https://helvetic-ruby.ch/\"\n          slug: \"helvetic-ruby\"\n          description: |-\n            A single-day, single-track event designed for Ruby programming language enthusiasts and professionals from Switzerland and internationally.\n\n        - name: \"Modena.rb\"\n          website: \"https://t.me/+0HSZ-Bv4-A1iODk0\"\n          slug: \"modenarb\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/community/modenarb.avif\"\n          description: |-\n            A Meetup group for individuals in the Modena area who are passionate about Ruby on Rails, aiming to improve members' skills through networking and education.\n\n        - name: \"RubyConf Austria\"\n          website: \"https://rubyconf.at/\"\n          slug: \"rubyconf-austria\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/community/rubyconfat.png\"\n          description: |-\n            A community-driven, single-track conference dedicated to the Ruby programming language, aiming to support and expand the Ruby community in Austria.\n\n        - name: \"SheTech\"\n          website: \"https://shetechitaly.org/\"\n          slug: \"shetech\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/community/shetech.png\"\n          description: |-\n            La community che unisce persone e aziende per portare la parità di genere nel tech e digital\n\n        - name: \"Tito\"\n          website: \"https://ti.to/home\"\n          slug: \"tito\"\n          description: |-\n            A robust, cloud-based event registration and ticketing software designed to simplify the planning, promotion, and management of events.\n\n        - name: \"Wroclove.rb\"\n          website: \"https://wrocloverb.com/\"\n          slug: \"wrocloverb\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/community/wroclove.png\"\n          description: |-\n            An annual, not-for-profit event held in Wrocław, Poland, organized by the local Ruby community since 2012.\n\n        - name: \"Avo\"\n          website: \"https://avohq.io/\"\n          slug: \"avo\"\n          description: |-\n            A powerful framework for building internal tools, admin panels, and content management systems for Ruby on Rails applications.\n\n        - name: \"Arkemis\"\n          website: \"https://arkemis.it/\"\n          slug: \"arkemis\"\n          logo_url: \"https://rubycon.it/assets/images/sponsors/community/arkemis.png\"\n"
  },
  {
    "path": "data/rubycon/rubycon-2026/venue.yml",
    "content": "---\nname: \"Hotel Ambasciatori\"\ndescription: |-\n  Located in the heart of Rimini, Hotel Ambasciatori offers modern facilities in an elegant seaside setting, just steps away from the beach and the city's main attractions.\n\naddress:\n  street: \"Viale Amerigo Vespucci, 22\"\n  city: \"Rimini\"\n  postal_code: \"47921\"\n  country: \"Italy\"\n  country_code: \"IT\"\n  display: \"Viale Amerigo Vespucci 22, 47921 Rimini, Italy\"\n\ncoordinates:\n  latitude: 44.068849\n  longitude: 12.580334\n\nmaps:\n  google: \"https://maps.app.goo.gl/3LxmsesECUedvtNj8\"\n  apple:\n    \"https://maps.apple.com/place?address=Viale%20Amerigo%20Vespucci%2022,%2047921%20Rimini,%20Italy&coordinate=44.068849,12.580334&name=Hotel%20Ambasciatori%20Rimini&place-id=\\\n    I988325D73C201608&map=transit\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=44.068849&mlon=12.580334&zoom=17\"\n"
  },
  {
    "path": "data/rubycon/rubycon-2026/videos.yml",
    "content": "# Website: https://rubycon.it\n# Schedule: https://rubycon.it/schedule/\n---\n- id: \"riccardo-carlesso-rubycon-2026\"\n  title: \"Welcome to Rubycon\"\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  announced_at: \"2025-12-18\"\n  speakers:\n    - Riccardo Carlesso\n  video_provider: \"scheduled\"\n  video_id: \"riccardo-carlesso-rubycon-2026\"\n\n- id: \"carmine-paolino-keynote-rubycon-2026\"\n  title: \"Ruby Is the Best Language for Building AI Web Apps\"\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  announced_at: \"2025-11-28 19:04 UTC\"\n  speakers:\n    - Carmine Paolino\n  video_provider: \"scheduled\"\n  video_id: \"carmine-paolino-keynote-rubycon-2026\"\n\n- id: \"julia-lopez-rubycon-2026\"\n  title: \"Shift-left on Accessibility in your Ruby webapps\"\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  announced_at: \"2025-12-18\"\n  speakers:\n    - Julia López\n  video_provider: \"scheduled\"\n  video_id: \"julia-lopez-rubycon-2026\"\n\n- id: \"silvano-stralla-rubycon-2026\"\n  title: \"Breaking the rules of software engineering: will it work?\"\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  speakers:\n    - Silvano Stralla\n  video_provider: \"scheduled\"\n  video_id: \"silvano-stralla-rubycon-2026\"\n\n- id: \"andre-arko-rubycon-2026\"\n  title: \"rv, a ruby manager for the future\"\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  speakers:\n    - André Arko\n  video_provider: \"scheduled\"\n  video_id: \"andre-arko-rubycon-2026\"\n\n- id: \"lightning-talks-rubycon-2026\"\n  title: \"Lightning Talks\"\n  description: |-\n    ⚡️ 5 minutes for everyone who has something to say\n  kind: \"lightning_talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  talks: []\n  video_provider: \"scheduled\"\n  video_id: \"lightning-talks-rubycon-2026\"\n\n- id: \"michele-franzin-rubycon-2026\"\n  title: \"Semantic Image Search in Ruby: Postgres, Redis, or LLM?\"\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  speakers:\n    - Michele Franzin\n  video_provider: \"scheduled\"\n  video_id: \"michele-franzin-rubycon-2026\"\n\n- id: \"akira-matsuda-rubycon-2026\"\n  title: \"My daily life on Ruby\"\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  speakers:\n    - Akira Matsuda\n  video_provider: \"scheduled\"\n  video_id: \"akira-matsuda-rubycon-2026\"\n\n- id: \"marco-roth-rubycon-2026\"\n  title: \"HTML-Aware ERB: The Path to Reactive Rendering\"\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  announced_at: \"2025-11-13 17:51 UTC\"\n  speakers:\n    - Marco Roth\n  video_provider: \"scheduled\"\n  video_id: \"marco-roth-rubycon-2026\"\n\n- id: \"yara-debian-rubycon-2026\"\n  title: \"From Plato to Production: A Philosophical History of Code\"\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  speakers:\n    - Yara Debian\n  video_provider: \"scheduled\"\n  video_id: \"yara-debian-rubycon-2026\"\n\n- id: \"piadina-its-a-wrap-rubycon-2026\"\n  title: \"Piadina - It's a wrap!\"\n  description: \"\"\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-05-08\"\n  speakers:\n    - Riccardo Carlesso\n  video_provider: \"scheduled\"\n  video_id: \"piadina-its-a-wrap-rubycon-2026\"\n"
  },
  {
    "path": "data/rubycon/series.yml",
    "content": "---\nname: \"Rubycon\"\nwebsite: \"https://www.rubycon.it/\"\ntwitter: \"https://x.com/rubycon2026\"\nbsky: \"https://bsky.app/profile/rubyconitaly.bsky.social\"\nmastodon: \"https://mastodon.social/@rubycon\"\nyoutube_channel_name: \"rubycon-italy\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCNqcu--Vp9H7JfGHW4TYzIw\"\ndefault_country_code: \"IT\"\naliases:\n  - RubyCon\n  - Rubycon IT\n  - Rubycon Italy\n  - rubyconitaly\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2001/event.yml",
    "content": "---\nid: \"rubyconf-2001\"\ntitle: \"RubyConf 2001\"\nkind: \"conference\"\nlocation: \"Tampa, FL, United States\"\ndescription: \"\"\nstart_date: \"2001-10-12\"\nend_date: \"2001-10-13\"\nyear: 2001\nwebsite: \"https://rubyconf.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F4554E\"\ncoordinates:\n  latitude: 27.9516896\n  longitude: -82.45875269999999\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2001/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2002/event.yml",
    "content": "---\nid: \"rubyconf-2002\"\ntitle: \"RubyConf 2002\"\nkind: \"conference\"\nlocation: \"Seattle, WA, United States\"\ndescription: \"\"\nstart_date: \"2002-11-01\"\nend_date: \"2002-11-03\"\nyear: 2002\nwebsite: \"https://rubyconf.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F4554E\"\ncoordinates:\n  latitude: 47.6061389\n  longitude: -122.3328481\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2002/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2003/event.yml",
    "content": "---\nid: \"rubyconf-2003\"\ntitle: \"RubyConf 2003\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: \"\"\nstart_date: \"2003-11-16\"\nend_date: \"2003-11-18\"\nyear: 2003\nwebsite: \"https://rubyconf.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F4554E\"\ncoordinates:\n  latitude: 30.267153\n  longitude: -97.7430608\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2003/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2004/event.yml",
    "content": "---\nid: \"rubyconf-2004\"\ntitle: \"RubyConf 2004\"\nkind: \"conference\"\nlocation: \"Washington, DC\"\ndescription: \"\"\nstart_date: \"2004-10-01\"\nend_date: \"2004-10-03\"\nyear: 2004\nwebsite: \"https://rubyconf.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F4554E\"\ncoordinates:\n  latitude: 38.9071923\n  longitude: -77.0368707\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2004/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2005/event.yml",
    "content": "---\nid: \"rubyconf-2005\"\ntitle: \"RubyConf 2005\"\nkind: \"conference\"\nlocation: \"San Diego, CA, United States\"\ndescription: \"\"\nstart_date: \"2005-10-14\"\nend_date: \"2005-10-16\"\nyear: 2005\nwebsite: \"https://rubyconf.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F4554E\"\ncoordinates:\n  latitude: 32.715738\n  longitude: -117.1610838\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2005/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2006/event.yml",
    "content": "---\nid: \"rubyconf-2006\"\ntitle: \"RubyConf 2006\"\nkind: \"conference\"\nlocation: \"Denver, CO, United States\"\ndescription: \"\"\nstart_date: \"2006-10-20\"\nend_date: \"2006-10-22\"\nyear: 2006\nwebsite: \"https://rubyconf.org\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#F4554E\"\ncoordinates:\n  latitude: 39.7392358\n  longitude: -104.990251\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2006/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2007/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyY_DtwggfJCsRyZPSs-rmUh\"\ntitle: \"RubyConf 2007\"\nkind: \"conference\"\nlocation: \"Charlotte, NC, United States\"\ndescription: |-\n  This was the first Ruby Conference recorded by Confreaks, in 2007.\n\n  November 2-4, 2007\n  Omni Charlotte Hotel\npublished_at: \"2013-04-14\"\nstart_date: \"2007-11-02\"\nend_date: \"2007-11-04\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2007\nbanner_background: \"#081625\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 35.2270768\n  longitude: -80.84089329999999\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2007/videos.yml",
    "content": "---\n- id: \"nathaniel-talbott-rubyconf-2007\"\n  title: \"Why Camping Matters\"\n  raw_title: \"Ruby Conference 2007 Why Camping Matters by Nathaniel Talbott\"\n  speakers:\n    - Nathaniel Talbott\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6rF2wJVRzio\"\n\n- id: \"aaron-bedra-rubyconf-2007\"\n  title: \"Sploitin' with Ruby (Point, Click, Root)\"\n  raw_title: \"Ruby Conference 2007 Sploitin' with Ruby (Point, Click, Root) by Aaron Bedra\"\n  speakers:\n    - Aaron Bedra\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"djtWGCaLFR0\"\n\n- id: \"andreas-erik-rubyconf-2007\"\n  title: \"Geocode/R\"\n  raw_title: \"Ruby Conference 2007 Geocode/R by Andreas Erik Johan Launila\"\n  speakers:\n    - Andreas Erik\n    - Johan Launila\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"VABC4Qvapw8\"\n\n- id: \"erik-hatcher-rubyconf-2007\"\n  title: \"solr-ruby: The Best Open Source Search Engine + Ruby\"\n  raw_title: \"Ruby Conference 2007 solr-ruby: The Best Open Source Search Engine + Ruby by Erik Hatcher\"\n  speakers:\n    - Erik Hatcher\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"S7ZikKkLYWE\"\n\n- id: \"kyle-maxwell-rubyconf-2007\"\n  title: \"JRuby in the Wild\"\n  raw_title: \"Ruby Conference 2007 JRuby in the Wild by Kyle Maxwell\"\n  speakers:\n    - Kyle Maxwell\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"xRp7ER4FdBw\"\n\n- id: \"justin-gehtland-rubyconf-2007\"\n  title: \"Security and Identity: Ruby, CAS, and OpenID\"\n  raw_title: \"Ruby Conference 2007 Security and Identity: Ruby, CAS, and OpenID by Justin Gehtland\"\n  speakers:\n    - Justin Gehtland\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DA3MIE4-u5M\"\n\n- id: \"william-bereza-rubyconf-2007\"\n  title: \"Enhancing Embedded Development with Ruby\"\n  raw_title: \"Ruby Conference 2007 Enhancing Embedded Development with Ruby by William Bereza\"\n  speakers:\n    - William Bereza\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"QRO65yzsFrs\"\n\n- id: \"jay-phillips-rubyconf-2007\"\n  title: \"Next-Gen VoIP Development with Adhearsion\"\n  raw_title: \"Ruby Conference 2007 Next-Gen VoIP Development with Adhearsion by Jay Phillips\"\n  speakers:\n    - Jay Phillips\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5ObIisW5bpU\"\n\n- id: \"dave-astels-rubyconf-2007\"\n  title: \"Behaviour Driven Development with RSpec\"\n  raw_title: \"Ruby Conference 2007 Behaviour Driven Development with RSpec by Dave Astels, David Chelimsky\"\n  speakers:\n    - Dave Astels\n    - David Chelimsky\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"yoon3u6PEIw\"\n\n- id: \"dr-nic-williams-rubyconf-2007\"\n  title: \"Use Ruby to Generate More Ruby - RubiGen\"\n  raw_title: \"Ruby Conference 2007 Use Ruby to Generate More Ruby - RubiGen by Dr. Nic Williams\"\n  speakers:\n    - Dr. Nic Williams\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"l0JQ_xlSDc8\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2007\"\n  title: \"Keynote: Does Language Matter?\"\n  raw_title: \"Ruby Conference 2007 Keynote Address: Does Language Matter? by Yukihiro 'Matz' Matsumoto\"\n  speakers:\n    - Yukihiro 'Matz' Matsumoto\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"h44PeXXBfhk\"\n\n- id: \"laurent-sansonetti-rubyconf-2007\"\n  title: \"Mac OS X Loves Ruby\"\n  raw_title: \"Ruby Conference 2007 Mac OS X Loves Ruby by Laurent Sansonetti\"\n  speakers:\n    - Laurent Sansonetti\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"uHTNAj6V8fs\"\n\n- id: \"francis-hwang-rubyconf-2007\"\n  title: \"Conversations vs. Laws\"\n  raw_title: \"Ruby Conference 2007 Conversations vs. Laws by Francis Hwang\"\n  speakers:\n    - Francis Hwang\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zuSesuycrQo\"\n\n- id: \"chris-nelson-rubyconf-2007\"\n  title: \"Efficient Ruby to Javascript Compilation and Applications\"\n  raw_title: \"Ruby Conference 2007 Efficient Ruby to Javascript Compilation and Applications by Chris Nelson\"\n  speakers:\n    - Chris Nelson\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"IXeBFUOJcSg\"\n\n- id: \"eric-hodel-rubyconf-2007\"\n  title: \"Maximizing Productivity\"\n  raw_title: \"Ruby Conference 2007 Maximizing Productivity by Eric Hodel\"\n  speakers:\n    - Eric Hodel\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"XNL4go72Eck\"\n\n- id: \"rich-kilmer-rubyconf-2007\"\n  title: \"Deployable Ruby Runtimes\"\n  raw_title: \"Ruby Conference 2007 Deployable Ruby Runtimes by Rich Kilmer, Bruce Williams\"\n  speakers:\n    - Rich Kilmer\n    - Bruce Williams\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jJ4d4UqX-Zc\"\n\n- id: \"phil-hagelberg-rubyconf-2007\"\n  title: \"Tightening the Feedback Loop\"\n  raw_title: \"Ruby Conference 2007 Tightening the Feedback Loop by Phil Hagelberg\"\n  speakers:\n    - Phil Hagelberg\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"V6tTt6PcX2U\"\n\n- id: \"luke-kanies-rubyconf-2007\"\n  title: \"Essential Incompleteness in Program Modeling\"\n  raw_title: \"Ruby Conference 2007 Essential Incompleteness in Program Modeling by Luke Kanies\"\n  speakers:\n    - Luke Kanies\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6UvwBfAwYWo\"\n\n- id: \"evan-phoenix-rubyconf-2007\"\n  title: \"Rubinius\"\n  raw_title: \"Ruby Conference 2007 Rubinius by Evan Phoenix\"\n  speakers:\n    - Evan Phoenix\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"aRM06lYsLyE\"\n\n- id: \"charles-nutter-rubyconf-2007\"\n  title: \"JRuby: Ruby for the JVM\"\n  raw_title: \"Ruby Conference 2007 JRuby: Ruby for the JVM by Charles Nutter, Thomas Enebo\"\n  speakers:\n    - Charles Nutter\n    - Thomas Enebo\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"js5PEe0fM2o\"\n\n- id: \"john-lam-rubyconf-2007\"\n  title: \"State of IronRuby\"\n  raw_title: \"Ruby Conference 2007 State of IronRuby by John Lam\"\n  speakers:\n    - John Lam\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"GyJvUi2LejA\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2007-town-meeting-with-ruby-creator\"\n  title: \"Town Meeting with Ruby Creator\"\n  raw_title: \"Ruby Conference 2007 Town Meeting with Ruby Creator by Yukihiro 'Matz' Matsumoto\"\n  speakers:\n    - Yukihiro 'Matz' Matsumoto\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Zz0zAWTFbTQ\"\n\n- id: \"eric-ivancich-rubyconf-2007\"\n  title: \"Ropes: An Alternative to Ruby's Strings\"\n  raw_title: \"Ruby Conference 2007 Ropes: An Alternative to Ruby's Strings by Eric Ivancich\"\n  speakers:\n    - Eric Ivancich\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5Xt6qN269Uo\"\n\n- id: \"paul-brannan-rubyconf-2007\"\n  title: \"Avoiding Pitfalls in C Extensions\"\n  raw_title: \"Ruby Conference 2007 Avoiding Pitfalls in C Extensions by Paul Brannan\"\n  speakers:\n    - Paul Brannan\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"qqSY4O9Dnn8\"\n\n- id: \"ryan-davis-rubyconf-2007\"\n  title: \"Hurting Code for Fun and Profit\"\n  raw_title: \"Ruby Conference 2007 Hurting Code for Fun and Profit by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"gYdqNNICyvI\"\n\n- id: \"nathan-sobo-rubyconf-2007\"\n  title: \"Treetop: Syntactic Analysis with Ruby\"\n  raw_title: \"Ruby Conference 2007 Treetop: Syntactic Analysis with Ruby by Nathan Sobo\"\n  speakers:\n    - Nathan Sobo\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"v5tTDZSIVrg\"\n\n- id: \"andrea-o-k-wright-rubyconf-2007\"\n  title: \"Building Games with Ruby\"\n  raw_title: \"Ruby Conference 2007 Building Games with Ruby by Andrea O. K. Wright\"\n  speakers:\n    - Andrea O. K. Wright\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"_KCnl5EhcdA\"\n\n- id: \"ben-bleything-rubyconf-2007\"\n  title: \"Controlling Electronics with Ruby\"\n  raw_title: \"Ruby Conference 2007 Controlling Electronics with Ruby by Ben Bleything\"\n  speakers:\n    - Ben Bleything\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"1UDwFvXlrXU\"\n\n- id: \"kiwamu-kato-rubyconf-2007\"\n  title: \"Introduction to AP4R\"\n  raw_title: \"Ruby Conference 2007 Introduction to AP4R by Kiwamu Kato, Shunichi Shinohara\"\n  speakers:\n    - Kiwamu Kato\n    - Shunichi Shinohara\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"v8eKVepQLic\"\n\n- id: \"marcel-molina-rubyconf-2007\"\n  title: \"What Makes Code Beautiful?\"\n  raw_title: \"Ruby Conference 2007 What Makes Code Beautiful? by Marcel Molina\"\n  speakers:\n    - Marcel Molina\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"eutF6GbJohY\"\n\n- id: \"jim-weirich-rubyconf-2007\"\n  title: \"Advanced Ruby Class Design\"\n  raw_title: \"Ruby Conference 2007 Advanced Ruby Class Design by Jim Weirich\"\n  speakers:\n    - Jim Weirich\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"vwBpTgdZBDk\"\n\n- id: \"ben-scofield-rubyconf-2007\"\n  title: \"Cleanliness Is Next to Domain Specificity\"\n  raw_title: \"Ruby Conference 2007 Cleanliness Is Next to Domain Specificity by Ben Scofield\"\n  speakers:\n    - Ben Scofield\n  event_name: \"RubyConf 2007\"\n  date: \"2007-11-02\" # TODO\n  published_at: \"2013-04-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"QAThcdbrbVg\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2008/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaIA3Do7AXp2ak7yBD_fLL8\"\ntitle: \"RubyConf 2008\"\nkind: \"conference\"\nlocation: \"Orlando, FL, United States\"\ndescription: \"\"\npublished_at: \"2015-02-12\"\nstart_date: \"2008-11-06\"\nend_date: \"2008-11-08\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2008\nbanner_background: \"#081625\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 28.5383832\n  longitude: -81.3789269\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2008/videos.yml",
    "content": "---\n- id: \"koichi-sasada-rubyconf-2008\"\n  title: \"Future of RubyVM\"\n  raw_title: \"Ruby Conference 2008 - Future of RubyVM\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Koichi Sasada\n  video_provider: \"youtube\"\n  video_id: \"9cN05h8z-OI\"\n\n- id: \"david-koontz-rubyconf-2008\"\n  title: \"Monkeybars: easy cross platform GUIs\"\n  raw_title: \"Ruby Conference 2008 - Monkeybars: easy cross platform GUIs\"\n  speakers:\n    - David Koontz\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: David Koontz\n  video_provider: \"youtube\"\n  video_id: \"hW6cFCeihLs\"\n\n- id: \"evan-phoenix-rubyconf-2008\"\n  title: \"Rubinius\"\n  raw_title: \"Ruby Conference 2008 - Rubinius\"\n  speakers:\n    - Evan Phoenix\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Evan Phoenix\n  video_provider: \"youtube\"\n  video_id: \"M0tFxdKLY3k\"\n\n- id: \"scott-chacon-rubyconf-2008\"\n  title: \"Using Git in Ruby Applications\"\n  raw_title: \"Ruby Conference 2008 - Using Git in Ruby Applications\"\n  speakers:\n    - Scott Chacon\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Scott Chacon\n  video_provider: \"youtube\"\n  video_id: \"YkcKHLerWBs\"\n\n- id: \"andy-maleh-rubyconf-2008\"\n  title: \"Desktop Development with Glimmer\"\n  raw_title: \"Ruby Conference 2008 - Desktop Development with Glimmer\"\n  speakers:\n    - Andy Maleh\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Andy Maleh\n  video_provider: \"youtube\"\n  video_id: \"viEnKGT3QJA\"\n\n- id: \"david-goodlad-rubyconf-2008\"\n  title: \"Ruby for Embedded Applications\"\n  raw_title: \"Ruby Conference 2008 - Ruby for Embedded Applications\"\n  speakers:\n    - David Goodlad\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: David Goodlad\n  video_provider: \"youtube\"\n  video_id: \"pRaHcEB35tk\"\n\n- id: \"thomas-enebo-rubyconf-2008\"\n  title: \"JRuby: What, Why, How...  Try It Now\"\n  raw_title: \"Ruby Conference 2008 - JRuby: What, Why, How...  Try It Now\"\n  speakers:\n    - Thomas Enebo\n    - Charles Nutter\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Thomas Enebo, Charles Nutter\n  video_provider: \"youtube\"\n  video_id: \"U6WuoHdjdoM\"\n\n- id: \"mark-bates-rubyconf-2008\"\n  title: \"Building Distributed Applications\"\n  raw_title: \"Ruby Conference 2008 - Building Distributed Applications\"\n  speakers:\n    - Mark Bates\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Mark Bates\n  video_provider: \"youtube\"\n  video_id: \"vMzg6ED6k3g\"\n\n- id: \"brian-ford-rubyconf-2008\"\n  title: \"What does my Ruby do?\"\n  raw_title: \"Ruby Conference 2008 - What does my Ruby do?\"\n  speakers:\n    - Brian Ford\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Brian Ford\n  video_provider: \"youtube\"\n  video_id: \"tCrFaqGEdtA\"\n\n- id: \"buck-jamis-rubyconf-2008\"\n  title: \"Recovering from Enterprise\"\n  raw_title: \"Ruby Conference 2008 - Recovering from Enterprise\"\n  speakers:\n    - Jamis Buck\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Buck Jamis\n  video_provider: \"youtube\"\n  video_id: \"ewIbYQ-QuC0\"\n\n- id: \"jim-menard-rubyconf-2008\"\n  title: \"Ruby in the Clouds\"\n  raw_title: \"Ruby Conference 2008 - Ruby in the Clouds\"\n  speakers:\n    - Jim Menard\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Jim Menard\n  video_provider: \"youtube\"\n  video_id: \"zShT3Yud_nM\"\n\n- id: \"nicholas-schlueter-rubyconf-2008\"\n  title: \"rush, a shell that will yeild to you\"\n  raw_title: \"Ruby Conference 2008 - rush, a shell that will yeild to you\"\n  speakers:\n    - Nicholas Schlueter\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Nicholas Schlueter\n  video_provider: \"youtube\"\n  video_id: \"WA_f-jJh3ZU\"\n\n- id: \"laurent-sansonetti-rubyconf-2008\"\n  title: \"MacRuby - Ruby for your Mac!\"\n  raw_title: \"Ruby Conference 2008 - Unfactoring From Patterns\"\n  speakers:\n    - Laurent Sansonetti\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Laurent Sansonetti\n  video_provider: \"youtube\"\n  video_id: \"Hr696IoDRZM\"\n\n- id: \"rein-henrichs-rubyconf-2008\"\n  title: \"The Future of Ruby\"\n  raw_title: \"Ruby Conference 2008 - Unfactoring From Patterns\"\n  speakers:\n    - Rein Henrichs\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Rein Henrichs\n  video_provider: \"youtube\"\n  video_id: \"UTlMZ0lpOcQ\"\n\n- id: \"preston-lee-rubyconf-2008\"\n  title: \"Peer-Aware Desktop Application Development\"\n  raw_title: \"Ruby Conference 2008 - Peer-Aware Desktop Application Development\"\n  speakers:\n    - Preston Lee\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Preston Lee\n  video_provider: \"youtube\"\n  video_id: \"w7QNI2kQM0E\"\n\n- id: \"joe-marinez-rubyconf-2008\"\n  title: \"Better Hacking With Training Wheels\"\n  raw_title: \"Ruby Conference 2008 - Better Hacking With Training Wheels\"\n  speakers:\n    - Joe Marinez\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-04-01\"\n  description: |-\n    By: Joe Marinez\n  video_provider: \"youtube\"\n  video_id: \"IdnYhqShMMI\"\n\n- id: \"francis-hwang-rubyconf-2008\"\n  title: \"Testing Heresies\"\n  raw_title: \"Ruby Conference 2008 - Testing Heresies\"\n  speakers:\n    - Francis Hwang\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Francis Hwang\n  video_provider: \"youtube\"\n  video_id: \"qNh6WjdVKh0\"\n\n- id: \"john-lam-rubyconf-2008\"\n  title: \"IronRuby\"\n  raw_title: \"Ruby Conference 2008 - IronRuby\"\n  speakers:\n    - John Lam\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: John Lam\n  video_provider: \"youtube\"\n  video_id: \"JW3PZURqLcI\"\n\n- id: \"w-idris-yasser-rubyconf-2008\"\n  title: \"NeverBlock, trivial non-blocking IO\"\n  raw_title: \"Ruby Conference 2008 - NeverBlock, trivial non-blocking IO\"\n  speakers:\n    - W. Idris Yasser\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: W. Idris Yasser\n  video_provider: \"youtube\"\n  video_id: \"X8jF3oDpoGM\"\n\n- id: \"bob-walker-rubyconf-2008\"\n  title: \"Ruby Persistence in MagLev\"\n  raw_title: \"Ruby Conference 2008 - Ruby Persistence in MagLev\"\n  speakers:\n    - Bob Walker\n    - Allan Ottis\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Bob Walker, Allan Ottis\n  video_provider: \"youtube\"\n  video_id: \"CqnEA14iMwo\"\n\n- id: \"dan-yoder-rubyconf-2008\"\n  title: \"Waves: a Resource-Oriented Framework\"\n  raw_title: \"Ruby Conference 2008 - Waves: a Resource-Oriented Framework\"\n  speakers:\n    - Dan Yoder\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Dan Yoder\n  video_provider: \"youtube\"\n  video_id: \"2Xn6Vg5Lk8Y\"\n\n- id: \"greg-borenstein-rubyconf-2008\"\n  title: \"Fear of Programming\"\n  raw_title: \"Ruby Conference 2008 - Fear of Programming\"\n  speakers:\n    - Greg Borenstein\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Greg Borenstein\n  video_provider: \"youtube\"\n  video_id: \"Fsuu-D5cF9Q\"\n\n- id: \"nathaniel-talbott-rubyconf-2008\"\n  title: \"Fear of Programming\"\n  raw_title: \"Ruby Conference 2008 - Fear of Programming by Nathaniel Talbott\"\n  speakers:\n    - Nathaniel Talbott\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Nathaniel Talbott\n  video_provider: \"youtube\"\n  video_id: \"g_ZyRVPY5Wc\"\n\n- id: \"dean-wampler-rubyconf-2008\"\n  title: \"Better Ruby through Functional Programming\"\n  raw_title: \"Ruby Conference 2008 - Better Ruby through Functional Programming\"\n  speakers:\n    - Dean Wampler\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Dean Wampler\n  video_provider: \"youtube\"\n  video_id: \"9zfSx46NlKY\"\n\n- id: \"tammer-saleh-rubyconf-2008\"\n  title: \"Coding for Failure\"\n  raw_title: \"Ruby Conference 2008 - Coding for Failure\"\n  speakers:\n    - Tammer Saleh\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Tammer Saleh\n  video_provider: \"youtube\"\n  video_id: \"nIB3qt5BRoI\"\n\n- id: \"blake-mizerany-rubyconf-2008\"\n  title: \"Lightweight Web Services\"\n  raw_title: \"Ruby Conference 2008 - Lightweight Web Services\"\n  speakers:\n    - Blake Mizerany\n    - Adam Wiggins\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Blake Mizerany, Adam Wiggins\n  video_provider: \"youtube\"\n  video_id: \"OR9U-6Bun7g\"\n\n- id: \"john-barnette-rubyconf-2008\"\n  title: \"How I Learned to Love JavaScript\"\n  raw_title: \"Ruby Conference 2008 - How I Learned to Love Javascript\"\n  speakers:\n    - John Barnette\n    - Aaron Patterson\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: John Barnette, Aaron Patterson\n  video_provider: \"youtube\"\n  video_id: \"1HXC0x23p5Q\"\n\n- id: \"jim-weirich-rubyconf-2008\"\n  title: \"What All Rubyists Should Know About Threads\"\n  raw_title: \"Ruby Conference 2008 - What All Rubyists Should Know About Threads\"\n  speakers:\n    - Jim Weirich\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Jim Weirich\n  video_provider: \"youtube\"\n  video_id: \"fK-N_VxdW7g\"\n\n- id: \"eric-ivancich-rubyconf-2008\"\n  title: \"Effective and Creative Coding\"\n  raw_title: \"Ruby Conference 2008 - Effective and Creative Coding\"\n  speakers:\n    - Eric Ivancich\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Eric Ivancich\n  video_provider: \"youtube\"\n  video_id: \"lMd7zNiyhRg\"\n\n- id: \"gregory-brown-rubyconf-2008\"\n  title: \"Ruby Mendicant Project\"\n  raw_title: \"Ruby Conference 2008 - Ruby Mendicant Project\"\n  speakers:\n    - Gregory Brown\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Gregory Brown\n  video_provider: \"youtube\"\n  video_id: \"u66wmChpu2M\"\n\n- id: \"eric-hodel-rubyconf-2008\"\n  title: \"Seattle.rb Rocks!\"\n  raw_title: \"Ruby Conference 2008 - Seattle.rb Rocks!\"\n  speakers:\n    - Eric Hodel\n    - Ryan Davis\n    - Aaron Patterson\n    - Phil Hagelberg\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2015-02-12\"\n  description: |-\n    By: Eric Hodel, Ryan Davis, Aaron Patterson, Phil Hagelberg\n\n    Seattle.rb Rocks would cover a number of side projects developed by Seattle.rb members in a lightning-talk-like format. Individual presentations would run for roughly ten minutes, and at least the following individual presentations would be given: Phil Hagelberg will talk about Bus Scheme, which is a Scheme implementation that is implemented (mostly) on the bus. Phil will explore what it's like to implement an interpreter in Ruby and what kinds of things Bus Scheme could be used for. Eric Hodel will talk about his work on a framework for controlling and implementing Universal Plug and Play devices (UPnP) including a media server that is usable by the PlayStation 3. Aaron Patterson swill talk about ZOMG, an IDL parser and ruby code generator. He will discuss parser, tokenizer and code generation in ruby using techniques found in ZOMG as examples. Aaron will talk about the tools he used, such as rex for tokenizer generation and racc for parser generation along with Ruby2Ruby for ruby code generation. Aaron will also talk about the pitfalls he encountered while using these tools and about practical applications for ZOMG such as DOM api generation. John Barnette will talk about project skeletons. There are a multitude of Ruby project skeleton generators. Everyone uses them, everyone tweaks them. There are no good tools for reusing and sharing customized project skeletons. John will demonstrate a tool for reusing and sharing customized skeletons for Gems, Rails, RubyCocoa, or anything else! Following all the talks, there would be a question and answer period at the end. Naturally, given the nature of this talk, members Seattle.rb would not expect to receive any discounts on conference tickets.\n  video_provider: \"youtube\"\n  video_id: \"LbKlEpB2G9I\"\n\n- id: \"luc-castera-rubyconf-2008\"\n  title: \"Ramaze: The underrated Web Framework\"\n  raw_title: \"Ruby Conference 2008 Ramaze: The underrated Web Framework by Luc Castera\"\n  speakers:\n    - Luc Castera\n  event_name: \"RubyConf 2008\"\n  date: \"2008-11-06\" # TODO\n  published_at: \"2013-04-16\"\n  description: |-\n    By: Luc Castera\n  video_provider: \"youtube\"\n  video_id: \"g-5b1yE33kw\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2009/event.yml",
    "content": "---\nid: \"rubyconf-2009\"\ntitle: \"RubyConf 2009\"\nkind: \"conference\"\nlocation: \"San Francisco, CA, United States\"\ndescription: \"\"\nstart_date: \"2009-11-19\"\nend_date: \"2009-11-21\"\nyear: 2009\nwebsite: \"https://rubyconf.org\"\ncoordinates:\n  latitude: 37.7749295\n  longitude: -122.4194155\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2010/event.yml",
    "content": "---\nid: \"rubyconf-2010\"\ntitle: \"RubyConf 2010\"\nkind: \"conference\"\nlocation: \"New Orleans, LA, United States\"\ndescription: \"\"\nstart_date: \"2010-11-11\"\nend_date: \"2010-11-13\"\nyear: 2010\nwebsite: \"https://rubyconf.org\"\ncoordinates:\n  latitude: 29.9508941\n  longitude: -90.07583559999999\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Playlist: https://www.youtube.com/playlist?list=PLE7tQUdRKcyYAOs4EJPp-a0M2vA20lvhm\n# Matz Slides: https://www.slideshare.net/slideshow/rubyconf-2010-keynote-by-matz/5777480\n\n# https://weekly-geekly.imtqy.com/articles/113635/index.html\n# https://vimeo.com/16774463\n---\n[]\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2011/event.yml",
    "content": "---\nid: \"PL12D99636F40AE59B\"\ntitle: \"RubyConf 2011\"\nkind: \"conference\"\nlocation: \"New Orleans, LA, United States\"\ndescription: \"\"\npublished_at: \"2011-10-21\"\nstart_date: \"2011-09-29\"\nend_date: \"2011-10-01\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2011\nbanner_background: \"#081625\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 29.9508941\n  longitude: -90.07583559999999\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2011/videos.yml",
    "content": "---\n- id: \"toshiaki-koshiba-rubyconf-2011\"\n  title: 'Lightning Talk: Let''s go to \"Shibuya Rubyist Lunch\" at Tokyo, Japan'\n  raw_title: |\n    Lightning Talk: Let's go to \"Shibuya Rubyist Lunch\" at Tokyo, Japan (Toshiaki Koshiba)\n  speakers:\n    - Toshiaki Koshiba\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-26\"\n  description: |-\n    Let's go to \"Shibuya Rubyist Lunch\" at Tokyo, Japan\n  video_provider: \"youtube\"\n  video_id: \"i5zBVyWsc_Q\"\n\n- id: \"konstantin-haase-rubyconf-2011\"\n  title: \"Message in a Bottle\"\n  raw_title: \"Message in a Bottle by Konstantin Haase\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-07\"\n  description: |-\n    What does really happen when we call a method? How do the different Ruby implementations actually figure out what code to execute? What plumbing is going on under the hood to get a speedy dispatch? In this talk we will have a look at the internals of the four major Ruby implementations - 1.8, 1.9, JRuby and Rubinius, focusing on their dispatch. From look-up tables and call site caches, to inlining and what on earth is invokedynamic? Expect C, C++, Java, and, of course, Ruby code. But fear not, all will be explained!\n  video_provider: \"youtube\"\n  video_id: \"kcvQ-DBvgFE\"\n\n- id: \"dave-mccrory-rubyconf-2011\"\n  title: \"Services Inception with Ruby\"\n  raw_title: \"Services Inception with  Ruby by Dave McCrory\"\n  speakers:\n    - Dave McCrory\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-07\"\n  description: |-\n    Ruby code creating services for it to then consume aka Service Metaprogramming A very large number of Ruby apps are deployed in hosted environments. Many of these hosted environments offer both internal and external services with APIs that your Ruby app can consume. The problem is that the use of these services often requires provisioning tasks for each service and the service must always be there or the app will fail. This session will show Metaprogramming Ruby code and a RubyGem for provisioning/de-provisioning, binding/unbinding, sharing configuration state, and more. This allows your application to create a Redis or MySQL instance only if needed (say on initial startup) or bind to a specific service, but only if/when it is present. This approach eliminates many of the forgotten steps during deployments and makes it easier to understand what your Ruby code really depends on because it is all encapsulated in the application's code itself!\n  video_provider: \"youtube\"\n  video_id: \"7VXJQUnPz68\"\n\n- id: \"sarah-mei-rubyconf-2011\"\n  title: \"MongoDB to MySQL the How and the Why\"\n  raw_title: \"MongoDB to MySQL the How and the Why by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-07\"\n  description: |-\n    Diaspora is the crowd-funded open-source decentralized social network built on Rails. Full buzzword compliance: on by default. We have many thousands of active users and they generate a lot of social data. But after nine months of full-time development with MongoDB as our primary storage engine, a few months ago we converted it all to MySQL. Wait...what? Most people are going the other way, dropping Mongo into a project in place of MySQL or PostgreSQL. Plus, conventional wisdom says that social data is ill-suited to a traditional data store. Come hear a story about a large-scale Rails project that tried it both ways. You'll see crisis and redemption, facts and figures, nerds, kittens, ponycorns, and, of course, the secret sauce. Hecklers will be piped to /dev/null.\n  video_provider: \"youtube\"\n  video_id: \"OqBAVC9GGeI\"\n\n- id: \"justin-martin-rubyconf-2011\"\n  title: \"A Mentor in the Limelight\"\n  raw_title: \"A Mentor in the Limelight by Justin Martin, Paul Pagel\"\n  speakers:\n    - Justin Martin\n    - Paul Pagel\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-07\"\n  description: |-\n    Learning how to be a well versed and competent developer is a life long process, but it must begin somewhere. One of the toughest parts about starting a career as a developer is the massive technology stack involved in pushing anything out to the real world. Similar to learning physics, chemistry, or biology for the first time, there is a whole language you need to learn before you can achieve any sort of mastery. With Limelight, you can teach the fundamental principles of becoming a Software Craftsman while only using Ruby! We will first explore Limelight as an educational tool, and then get our hands on our keyboards and work through an example Limelight Lesson. We will actually be writing some code! If you have JRuby on your machine, Limelight will do the rest of the setup.\n  video_provider: \"youtube\"\n  video_id: \"PG6TnX2Bq_E\"\n\n- id: \"brian-guthrie-rubyconf-2011\"\n  title: \"Ruby Software Continuously Delivered and Exhaustively Explained\"\n  raw_title: \"Ruby Software Continuously Delivered and Exhaustively Explained by Brian Guthrie, Srushti Ambekallu\"\n  speakers:\n    - Brian Guthrie\n    - Srushti Ambekallu\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-07\"\n  description: |-\n    The Ruby community has driven a lot of technical innovation in deployment and configuration management over the last few years, and so the idea of delivering high-quality software rapidly should be familiar to many of us. But although many of our tools are state-of-the-art, our practices could stand a bit of scrutiny. Your friendly neighborhood server admin probably isn't thrilled with running RVM or compiling gems in production, and your nervous project manager is asking why deploying constantly is such a great idea anyway. Won't you just stop coding for, like, five minutes and click around the app for a bit, just to make them feel better? In this talk, the maintainers of two competing continuous integration servers at two competing shops lead you on a Socratic tour of the past, present, and future of continuous delivery as seen through an Agile Ruby lens. We'll talk about the changing deployment toolchain, the difficulty of evolving code as it's deployed, and how to coach your developers, testers, and client to be \"production-ready, any time.\"\n  video_provider: \"youtube\"\n  video_id: \"DCA0e3fyWJk\"\n\n- id: \"jonas-nicklas-rubyconf-2011\"\n  title: \"Code Design and the Science of Pleasure\"\n  raw_title: \"Code Design and the Science of Pleasure\"\n  speakers:\n    - Jonas Nicklas\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-07\"\n  description: |-\n    As Rails programmers we talk a lot about the beauty, not only of the products we build, but the code we write. Why is this beauty important? Can we think systematically about the emotional effects of the code we are writing? Code is meant to be read and used, not just by machines, but perhaps even more importantly by people. How people are affected by the products they use has been studied extensively in the field of industrial design, can we apply these lessons to the code we write?\n  video_provider: \"youtube\"\n  video_id: \"eygh1LS6ZN0\"\n\n- id: \"jonathan-weiss-rubyconf-2011\"\n  title: \"Advanced Eventmachine\"\n  raw_title: \"Advanced Eventmachine by Jonathan Weiss\"\n  speakers:\n    - Jonathan Weiss\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-07\"\n  description: |-\n    We use EventMachine heavily in production. It is handling uploads to S3, managing thousands of messages a second or distributing agent workload. This taught us a load about EventMachine and some weired corner-cases. I want to about such advanced EventMachine topics and shared some use-cases and experiences from the trenches.\n  video_provider: \"youtube\"\n  video_id: \"mPDs-xQhPb0\"\n\n- id: \"hemant-kumar-rubyconf-2011\"\n  title: \"Debugging Ruby\"\n  raw_title: \"Debugging Ruby by Hemant Kumar\"\n  speakers:\n    - Hemant Kumar\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-06\"\n  description: |-\n    As Ruby programmers our server side programs throw us in all kind of troubles. Hung processes, memory leaks, process spending too much time in GC, profiling etceteras. As mostly live coding and hands on session, I intend to show - how to use modern tools to find and fix these problems. I will be demonstrating, how to use GDB with live process, using rbtrace, perftools and various ways to detect memory leaks & performance bottle necks in your process.\n  video_provider: \"youtube\"\n  video_id: \"F57J1vedlx0\"\n\n- id: \"david-copeland-rubyconf-2011\"\n  title: \"Test-drive the development of your command-line applications\"\n  raw_title: \"Test-drive the development of your command-line applications (David Copeland)\"\n  speakers:\n    - David Copeland\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-28\"\n  description: |-\n    Rubyists love testing, and test-driven-development is becoming THE way to write code. But, do we do this with our command-line tools? How DO you write a test that your awesome application cleans up its temp files? How does one make a failing test for a missing command-line option? What's the easiest way to check our app's exit codes? This talk will answer these questions with some real-world examples. We'll talk briefly about the challenges particular to testing command-line apps, and then dive into some code where we'll show off techniques for organizing code for testability, tools for interacting with the filesystem, and how to create full-blown acceptance tests for your command-line app. In no time, you'll be able to write your command-line apps the same way you write your other code: test-first.\n  video_provider: \"youtube\"\n  video_id: \"5zBK-rIje2c\"\n\n- id: \"brian-ford-rubyconf-2011\"\n  title: \"Nikita: The Ruby Secret Agent\"\n  raw_title: \"Nikita: The Ruby Secret Agent (Brian Ford)\"\n  speakers:\n    - Brian Ford\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-28\"\n  description: |-\n    Ruby, the beautiful, malleable language with a lovely object model and great reflection capabilities... and almost zero tools. If I had a coin for every time some Smalltalker gloated about the Smalltalk class browser or some bloke bragged about the Java refactoring tools, I could start my own bitcoin. Building great tools for Ruby requires great support for Ruby itself. The problem is, there is often a giant molten blob of C or Java code in the Ruby implementation with a thin veneer of \"Ruby\" method bindings. Rather than supporting great Ruby tools, that effectively prevents building them. How does one browse core library classes like Array when the code is not even Ruby? Rubinius addresses this situation on two levels. Firstly, the Rubinius core library is written primarily in Ruby. Curious what that Array#[] method does? Just pull up the Ruby code and take a look. Rubinius also creates first-class Ruby objects for Ruby infrastructure. When a method is defined, there is actually an object, CompiledMethod, that you can lay your hands on, inspect, and manipulate like any other Ruby object. Secondly, Rubinius builds essential tools into the virtual machine. There is a built-in debugger, profiler, and also stats for the garbage collector. Further, Rubinius has a facility, named Agent, for querying and controlling the virtual machine. Nikita is a top-secret project to create a set of simple, integrated applications that use the Rubinius facilities to build tools for Ruby. The interface is a Sproutcore application, which enables using the tools remotely, for example, to monitor servers. In this talk, we'll look at the Rubinius features that support writing tools for Ruby and examine how those features are used in Nikita. Then we'll set Nikita loose on some problem code. It might get bloody.\n  video_provider: \"youtube\"\n  video_id: \"4NCXjWPh-7o\"\n\n- id: \"christopher-bertels-rubyconf-2011\"\n  title: \"Getting Fancy on Rubinius\"\n  raw_title: \"Getting Fancy on Rubinius (Christopher Bertels)\"\n  speakers:\n    - Christopher Bertels\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-28\"\n  description: |-\n    Fancy is a self-hosted, dynamic, class based, pure object-oriented programming language heavily inspired by Smalltalk, Ruby and Erlang that runs on the Rubinius VM. It has first class integration with Ruby, support for asynchronous message sends, futures and actors, a simple syntax and consistent semantics, object oriented pattern matching that preserves encapsulation and much more. Fancy runs on Rubinius, a modern bytecode virtual machine designed for Ruby. It is the first fully self-hosted language running on Rubinius besides Ruby. This talk will show Fancy's semantics and language features, its integration with Ruby code, as well as how the new implementation for the Rubinius VM works and what Rubinius has to offer for programming language creators alike.\n  video_provider: \"youtube\"\n  video_id: \"Ob_xM5loQdQ\"\n\n- id: \"david-a-black-rubyconf-2011\"\n  title: \"The Well-Grounded Nuby\"\n  raw_title: \"Ruby Conf 2011 The Well-Grounded Nuby by David A. Black\"\n  speakers:\n    - David A. Black\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-28\"\n  description: |-\n    An examination of a large handful of features and characteristics of Ruby that, once understood, provide a solid foundation for continued learning and/or mentoring\n  video_provider: \"youtube\"\n  video_id: \"Xt6c6r4fbBs\"\n\n- id: \"dewayne-vanhoozer-rubyconf-2011\"\n  title: \"The Secret Life of Ruby: Warrior With A Cause\"\n  raw_title: \"RubyConf 2011 The Secret Life of Ruby: Warrior With A Cause (Dewayne VanHoozer)\"\n  speakers:\n    - Dewayne VanHoozer\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-28\"\n  description: |-\n    Ruby has demonstrated itself to be an extraordinary tool for the rapid development of prototype systems in an environment of unclear, undefined, ill-defined, missing requirements. As a dynamic language its ability to rapidly morph based upon the needs of the moment is remarkable. The way that it can be used to hide complexity via domain specific languages is unparalleled. This session reviews 5 years of success using Ruby within a research and development lab of a major USA defence contractor. Lessons learned, evolved patterns and suggestions for future improvements are on the agenda. There are movies. Bring your own popcorn.\n  video_provider: \"youtube\"\n  video_id: \"MafncIr9SSg\"\n\n- id: \"steve-klabnik-rubyconf-2011\"\n  title: \"The Return of Shoes\"\n  raw_title: \"The Return of Shoes by Steve Klabnik\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-07\"\n  description: |-\n    It's been two years since _why the lucky stiff has departed Ruby. His work, however, carries on. Shoes was one of _why's most ambitious projects, and a tiny but scrappy team has kept Shoes alive. If you haven't heard of Shoes, it's a GUI toolkit for Ruby. Most of these are simply bindings to toolkits written in other languages, like QT or Tk. Shoes is native to Ruby, so it uses Ruby-only features heavily, such as blocks. Shoes also includes packaging functionality that allows you to distribute your apps on Linux, OSX, and Windows. In this talk, Steve will cover the basics of building applications with Shoes, the challenges of maintaining a large polyglot project with an absent inventor, and what's in store for the future of Shoes.\n  video_provider: \"youtube\"\n  video_id: \"roZkVMcUHVM\"\n\n- id: \"todo-rubyconf-2011\"\n  title: \"Lightning Talks\"\n  raw_title: \"Ruby Conf 2011 Lightning Talks by Various Presenters\"\n  speakers:\n    - TODO\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-26\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Xnt7VBzpQyg\"\n\n- id: \"niranjan-paranjape-rubyconf-2011\"\n  title: \"Rails services in the walled garden\"\n  raw_title: \"Ruby Conf 2011 Rails services in the walled garden  (Niranjan Paranjape, Sidu Ponnappa)\"\n  speakers:\n    - Niranjan Paranjape\n    - Sidu Ponnappa\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-26\"\n  description: |-\n    In typical service oriented architectures, monolithic applications are sliced along domain verticals to create several independently evolving 'services' that can be used in combination to achieve various outcomes. Rails applications lend themselves to this architecture beautifully and are slowly making inroads in big organisations for this reason. One of the big problems with this approach is that analyzing and managing large quantities of data from multiple services to produce a result becomes very hard. What was originally a relatively simple task when all data sat in the same database as part of a monolithic application, becomes, when split into multiple services, a whole different beast. This talk will focus on our experiences building a system involving about a dozen rails based services integrated over HTTP and XML and the issues we had to deal with when working with large data sets. We will talk about: * Various problems we faced while building RESTful APIs which demanded asynchronous communication between two services * Places where this asynchronous communication was needed to be initiated by the server, essentially a push mechanism instead of pull * Different approaches to this solution ** Sharing a database using read-only 'remote models' ** Creating read only local caches at each consumer *** Propagating updates by having the producer explicitly update each consumer *** Propagating updates using a message queue and the pros and cons of integrating with them in Ruby\n  video_provider: \"youtube\"\n  video_id: \"NEYqYz-TbtM\"\n\n- id: \"jeremy-hinegardner-rubyconf-2011\"\n  title: \"JRuby and Big Data\"\n  raw_title: \"Ruby Conf 2011 JRuby and Big Data by Jeremy Hinegardner\"\n  speakers:\n    - Jeremy Hinegardner\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-26\"\n  description: |-\n    One of the amazing things that we as Ruby developers benefit from, when using JRuby, is the existing ecosystem of Java libraries and platforms for manipulating Big Data. The most famous, and probably of the most use to rubyists is Hadoop and the Hadoop ecosystem of projects. This talk will touch on how we, as developers who use Ruby, may be use JRuby within a variety of Hadoop and Hadoop related projects such as HDFS, MapReduce, HBase, Hive, Zookeeper, etc.\n  video_provider: \"youtube\"\n  video_id: \"MBXH0P5tB2g\"\n\n- id: \"robert-c-martin-rubyconf-2011\"\n  title: \"Pure Ruby GUI\"\n  raw_title: \"Ruby Conf 2011 Pure Ruby GUI by Robert C. Martin and Micah Martin\"\n  speakers:\n    - Robert C. Martin\n    - Micah Martin\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-26\"\n  description: |-\n    Father-son-team Bob and Micah Martin open the hood on a pure ruby GUI tool they built to monitor their website, cleancoders.com. During this whimsical tour Bob and Micah will reveal how they made use of Limelight, along with a simple web service layer, to build a desktop GUI that provides vivid realtime information on usage of their site.\n  video_provider: \"youtube\"\n  video_id: \"YkMnKWPIB_A\"\n\n- id: \"joshua-ballanco-rubyconf-2011\"\n  title: \"Keeping Ruby Reasonable\"\n  raw_title: \"Ruby Conf 2011 Keeping Ruby Reasonable by Joshua Ballanco\"\n  speakers:\n    - Joshua Ballanco\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-26\"\n  description: |-\n    Pop quiz, hot shot! What is the value of this Ruby expression: \"2 + 3\"? What if I told you that somewhere earlier I had done this: \"class Fixnum; alias :+ :*; end\"? Changes everything, right? We're all familiar with Ruby's open classes. For many of us, they're one of the facets of Ruby that make it so much fun to work with. However, Ruby treats bindings as first class objects, and they are, similarly, open. This can lead to problems. What sorts of problems? Well, effectively, the only way to know what a Ruby program will do is to run it. Stated another way: it is impossible to reason about Ruby. Now, this may not seem like such a big deal for the seasoned Rubyist. So long as we're responsible in how we write our code and make sure not to do anything too crazy, we can have a pretty good idea of what any piece of code will do ahead of time. Unfortunately, compilers and runtimes can't rely on \"responsible\" programmers and having a \"pretty good idea\" of what code will do just doesn't cut it for a VM. As a result, method caches get invalidated far too often and whole classes of common optimizations do not work with Ruby. So, what's a programming language to do? Luckily, Ruby is not alone in facing this dilema. The Scheme community has been confronting similar issues from the very beginning, and in the R5RS and R6RS reports, they outlined a solution. This talk will take a look at what makes first-class environments and \"eval\" so problematic, and what lessons Ruby might learn from Scheme in how to be more reasonable.\n  video_provider: \"youtube\"\n  video_id: \"vbX5BVCKiNs\"\n\n- id: \"bradley-grzesiak-rubyconf-2011\"\n  title: \"Better Than ROT13\"\n  raw_title: \"Ruby Conf 2011 Better Than ROT13 by Bradley Grzesiak\"\n  speakers:\n    - Bradley Grzesiak\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-26\"\n  description: |-\n    We use encryption every day, from SSL to SSH to passing notes to your crush during Social Studies class. But how does it actually work? I'll avoid most of the math but cover the concepts of both symmetric and asymmetric encryption, including hashing and signing. I'll also show how to use OpenSSL from inside ruby and show off the idkfa gem, a library to securely store sensitive information into your code repositories.\n  video_provider: \"youtube\"\n  video_id: \"yxXSQhMl6gI\"\n\n- id: \"prakash-murthy-rubyconf-2011\"\n  title: \"Local Community Building\"\n  raw_title: \"Ruby Conf 2011 Local Community Building by Prakash Murthy\"\n  speakers:\n    - Prakash Murthy\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-26\"\n  description: |-\n    The talk will focus on less than one day length events that any Rubyists can organize in their locality to nurture and grow a vibrant ruby community. Specifically, the talk will explore in detail two such events - Code Retreat & Rails Bugmash, and will be based on my experience in organizing Code Retreats in Boulder (Feb 2011) & Fort Collins (June 2011), and Rails Bugmashes in Boulder and Bangalore (both in May 2011).\n  video_provider: \"youtube\"\n  video_id: \"vGGTGaR3WDw\"\n\n- id: \"andy-delcambre-rubyconf-2011\"\n  title: \"Ruby Conf 2011 Release Early and Release Often: Reducing deployment friction\"\n  raw_title: \"Ruby Conf 2011 Release Early and Release Often: Reducing deployment friction by Andy Delcambre\"\n  speakers:\n    - Andy Delcambre\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-26\"\n  description: |-\n    At Engine Yard, we release the main AppCloud code base at least once a day, many times more often than that. Yet we still have a fairly rigorous testing and release process. We have simply automated and connected as much of the process as possible. In this talk I will discuss how we do our deployments and how it ties in with our continuous integration service, and how we automated and tied it all together.\n  video_provider: \"youtube\"\n  video_id: \"0ZMdesfHU9w\"\n\n- id: \"rob-sanheim-rubyconf-2011\"\n  title: \"How Getting Buff Can Make You a Better Rubyist\"\n  raw_title: \"Ruby Conf 2011 How Getting Buff Can Make You a Better Rubyist by Rob Sanheim\"\n  speakers:\n    - Rob Sanheim\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-25\"\n  description: |-\n    Two years ago, I was about to turn 30. I was working constantly. And I was in the worst shape of my life. I weighed almost 270 pounds. My back, hands, and wrists ached constantly from repetitive stress and poor posture after working long hours. A full eight hour day or programming left me exhausted and irritable. I got on a plan to get in shape and lose weight, and given enough time and good habits, it worked. I lost a ton of weight and feel great. Along the way, a funny thing happened: I became much more effective as a developer, getting more done in less time. Work is more fun, my repetitive stress injury is gone, and eight hours of pair programming doesn't destroy me like it used to. This talk will discuss pragmatic ways to improve your health, reduce stress, and improve focus, all without a gym membership or dreadful treadmill sessions. We'll touch on modern science that demonstrates the importance of the mind/body connection, and cover some hacker friendly diet and exercise plans.\n  video_provider: \"youtube\"\n  video_id: \"vx9bCy3qrz4\"\n\n- id: \"ben-klang-rubyconf-2011\"\n  title: \"Evented Telephony Application Design with Adhearsion\"\n  raw_title: \"Evented Telephony Application Design with Adhearsion  (Ben Klang)\"\n  speakers:\n    - Ben Klang\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-25\"\n  description: |-\n    Adhearsion is a new way to write voice-enabled applications. It's not just an API or library -- it's a fully-featured framework, the first of its kind, designed for maximal code reuse and intuitiveness. Building on ideas learned from existing Ruby web development frameworks, Adhearsion brings test-driven development, ActiveRecord models and the full power of the Ruby language to the world of telephone applications. This talk covers Adhearsion's powerful eventing interfaces for call control. Rather than handling each call session in a linear (and often blocking) sequence, we can react to events as they happen during the call, such as code reacting to the active speaker in a multi-channel conference, handling mid-call DTMF keypresses or manipulating state as calls are set up and torn down.\n  video_provider: \"youtube\"\n  video_id: \"G-ogFKpx_vw\"\n\n- id: \"jamis-buck-rubyconf-2011\"\n  title: '\"Algorithms\" is Not a Four-Letter Word'\n  raw_title: '\"Algorithms\" is Not a Four-Letter Word  (Jamis Buck)'\n  speakers:\n    - Jamis Buck\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-25\"\n  description: |-\n    Why does the word \"algorithms\" convey such a sense of musty dustiness? It doesn't have to! Implementing algorithms can be a fantastic way to grow your craft, practice programming idioms and patters, learn new programming languages, and just generally have a good time! Come learn how to generate, navigate, and solve MAZES in a variety of ways. Be prepared to drink from a firehose as I walk (run?) through eleven maze generation algorithms and several ways to solve mazes, in just 45 minutes! You'll never think of algorithms the same way again.\n  video_provider: \"youtube\"\n  video_id: \"4zjPm39kPDM\"\n\n- id: \"aja-hammerly-rubyconf-2011\"\n  title: \"Powerful (but Easy) Data Visualization with the Graph Gem\"\n  raw_title: \"Ruby Conf 11 - Powerful (but Easy) Data Visualization with the Graph Gem by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-20\"\n  description: |-\n    Many projects involve large datasets. While humans are master pattern matchers, trying to find patterns and issues by looking at reams of text is hard. Sometimes you just need the 30,000 foot view but creating diagrams by hand is time consuming and prone to error. The graph gem makes it quick and easy to create visualizations of your data. In this talk, we'll learn how to use nokogiri and graph to get data out of an XML file and into a format where you can see relationships and patterns. We'll also see how color coding and clustering can emphasize the patterns in your data. Many of the examples will come from my work with adaptive education apps.\n  video_provider: \"youtube\"\n  video_id: \"IxSSbUrgTBY\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2011\"\n  title: \"Keynote: Ruby Everywhere\"\n  raw_title: 'Ruby Conf 2011 - Keynote: Ruby Everywhere by Yukihiro \"Matz\" Matsumoto'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-21\"\n  description: |-\n    Keynote speech by the creator of the Ruby (Programming Language) Yukihiro \"Matz\" Matsumoto.\n  video_provider: \"youtube\"\n  video_id: \"OubzA8Q25jQ\"\n\n- id: \"tim-connor-rubyconf-2011\"\n  title: \"company_fit.should_not == monoculture\"\n  raw_title: \"Ruby Conf 2011 - company_fit.should_not == monoculture by Tim Connor\"\n  speakers:\n    - Tim Connor\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-21\"\n  description: |-\n    Lightning talk from the International Ruby Conference 2011\n  video_provider: \"youtube\"\n  video_id: \"XAJ-b0PoXNk\"\n\n- id: \"amit-kumar-rubyconf-2011\"\n  title: \"Big Data Enterprisy Analytics App and Ruby\"\n  raw_title: \"Big Data Enterprisy Analytics App and Ruby by Amit Kumar\"\n  speakers:\n    - Amit Kumar\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-25\"\n  description: |-\n    The enterprise is a closed ecosystem with its own rules. Internet is all about openness and freedom. Solving the `Big Data` problem for an Enterprise requires: 1) Maintain large amounts of structured and unstructured data 2) Complying with internal technical standards and enterprisy architectural guidelines 3) Local as well as global enterprise regulations etc. I would like to share how Ruby helped in building a scalable Analytic application. The application uses OLAP Cubes and deals with data slicing/dicing.\n  video_provider: \"youtube\"\n  video_id: \"DaSqQlEZdA0\"\n\n- id: \"jim-weirich-rubyconf-2011\"\n  title: \"Writing Solid Ruby Code\"\n  raw_title: \"RubyConf 2011 Writing Solid Ruby Code by Jim Weirich\"\n  speakers:\n    - Jim Weirich\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-25\"\n  description: |-\n    Do you always seem to be fixing bugs in your software project? Are you spending more time fixing defects that actually implementing new behavior? If so, this talk is for you. In the mid-90s, Steve Maquire wrote a book that strongly effected the way I developed software. Primarily writing in C and C++ in those years, the struggle to deliver bug free software was especially a challenge. In the book \"Writing Solid Code\", Steve gives sage advice on the problems of developing large software projects and the challenges that go with making sure your softare actual does what you think it should. Although as Ruby developers we are no longer using C to deliver our large projects, the challenge of writing solid, reliable code is still before us. Based on Maquire's advice and my own years of Ruby experience, this talk will show developers tools, techniques and practices that they can use to improve their software and begin writing solid code.\n  video_provider: \"youtube\"\n  video_id: \"FR95rp-9Oo4\"\n\n- id: \"piotr-szotkowski-rubyconf-2011\"\n  title: \"Persisting Relations Across Time and Space\"\n  raw_title: \"Persisting Relations Across Time and Space by Piotr Szotkowski\"\n  speakers:\n    - Piotr Szotkowski\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-25\"\n  description: |-\n    Entities and their relations are the backbone of many Ruby applications -- from trivial, one-off commandline utilities to full-blown social network websites. The good old relational databases, while showing extreme abilities in both adaptation and survival, are no longer the obvious choice for persistence -- and sometimes obviously not an ideal one. This talk discusses various entity/relation modelling approaches and different persistence techniques -- from rigid schemas in suits to collections of hippie free-form documents; from good old (transactional!) PStore through join-table-happy RDBMSes and muscle-flexing NoSQL hools to (social!) graph databases, waiting patiently for broader recognition and prime time. Quite a few interesting Ruby libraries for gluing all this together are also pondered upon -- from world-class champions like Active Record or ARel to less known gems like Candy and Ambition.\n  video_provider: \"youtube\"\n  video_id: \"LOAkX4J68AU\"\n\n- id: \"avdi-grimm-rubyconf-2011\"\n  title: \"Exceptional Ruby\"\n  raw_title: \"Exceptional Ruby by Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-25\"\n  description: |-\n    You know how to raise and rescue exceptions. But do you know how they work, and how how to structure a robust error handling strategy for your app? This talk starts with a technical deep dive into Ruby's exception facility, covering features, tricks, and gotchas you never knew about. You'll learn how to retry failed operations; how to override \"raise\" for fun and profit; and advanced techniques for matching exceptions in rescue clauses. From there, we'll move on to patterns and guidelines for structuring a robust, failure-resilient codebase. We'll look at strategies for avoiding failure cascades; how to characterize and verify the exception-safety of critical methods; and alternatives to raising exceptions for when \"fail fast\" isn't the right answer. Finally, you'll learn about the three exception classes every app needs.\n  video_provider: \"youtube\"\n  video_id: \"Y4mIRtEIG9k\"\n\n- id: \"gregory-moeck-rubyconf-2011\"\n  title: \"Why You Don't Get Mock Objects\"\n  raw_title: \"Why You Don't Get Mock Objects  by Gregory Moeck\"\n  speakers:\n    - Gregory Moeck\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-25\"\n  description: |-\n    Although the Ruby community has embraced TDD like no other community ever has, we have always looked at mock objects with disdain, and perhaps even a little hatred. I've heard conference speakers call them \"Wastes of time\", \"Scams\", and even \"Testing Heresies\". Why would anyone have ever developed these pieces of junk? In reality though many in the agile community have embraced mock objects within their testing cycles because they have found using these fake objects improves the design of their systems. But why not Rubyists? Most Rubyists don't get mock objects because they don't understand their history or their creators intent. They try to fit them into their current workflow without understanding them, and find them unhelpful and stupid. After all, almost all of the good literature on the subject is written in Java, and we know how frustrating it is to read Java when your used to Ruby. As such, this talk will attempt to demonstrate in Ruby the usefulness of mock objects, and how to use them to improve the design of your system. Specifically the following will be covered: * Why do we need mock objects (Following the 'Tell, Don't Ask Principle') * Why you should only mock objects you own * Why you shouldn't use mocks to test boundary objects like external API calls * Why you should mock roles, not Objects * Why you should only mock your immediate neighbors * Why listening to your unit tests will tell you about design problems in your code\n  video_provider: \"youtube\"\n  video_id: \"R9FOchgTtLM\"\n\n- id: \"richard-crowley-rubyconf-2011\"\n  title: \"Blueprint: configuration management for busy people\"\n  raw_title: \"Blueprint: configuration management for busy people  (Richard Crowley)\"\n  speakers:\n    - Richard Crowley\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-25\"\n  description: |-\n    Configuration management shouldn't be a luxury. It should be a right available to teams of every size and skill because it makes you confident when you deploy and calm when you scale up. Until now, however, the tools have been focused on the exotic possibilities seen at enormous scale in sprawling organizations. Blueprint is different. Blueprint reverse engineers servers to understand how they're configured and makes it painless to push the configuration to your coworkers and to production. It understands system packages, gems, config files, source installations, and more. In this talk we'll discuss the architecture of the Blueprint tools, their use and how they fit into most workflows, their limitations and how users address them, and some of the tools being built on top of Blueprint to manage many servers at once.\n  video_provider: \"youtube\"\n  video_id: \"CUARNcqDVoU\"\n\n- id: \"rein-henrichs-rubyconf-2011\"\n  title: \"So you think you can code - Code Panel moderated\"\n  raw_title: \"So you think you can code - Code Panel moderated by Rein Henrichs\"\n  speakers:\n    - Rein Henrichs\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-10-25\"\n  description: |-\n    The Fabulous Five are back! Last year we blew your mind. This year we will blow your heart. Join us as we put on our robes and wizard hats and enchant you with witty banter, amusing anecdotes and live Q&A. We'll cover topics ranging from \"best ruby interpreter\" to \"best ruby interpretive dance\". Featuring Aaron \"The Kissing Bandit\" Patterson, Ben \"It's Bleything, not Bleything!\" Bleything, Yosef \"Totally Great\" Mendelssohn, Jon \"The Bear Brogrammer\" Barnette, and Evan \"Totes Not Creepy\" Phoenix. Moderated by Rein Henrichs.\n  video_provider: \"youtube\"\n  video_id: \"pRuqwOyhORs\"\n\n- id: \"martin-bolet-rubyconf-2011\"\n  title: \"Ruby OpenSSL Present Future and Why It Matters\"\n  raw_title: \"Ruby OpenSSL Present Future and Why It Matters by Martin Boßlet\"\n  speakers:\n    - Martin Boßlet\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-12\"\n  description: |-\n    We will start with an overview of what exists today (Ruby 1.9.3) in Ruby's OpenSSL wrapper and how and where you can use it and why you should. After this brief introduction we will encounter new features that could find their way into future versions of Ruby OpenSSL. Among these is OpenSSL::ASN1::Template, a DSL that allows parsing/encoding ASN.1 structures with simple declarations that look similar to ASN.1 itself. We will find out why I finally decided to ditch a working implementation in pure Ruby just to replace its majority with C code - including the lessons learned about performance. Another feature would be XML signature support (OpenSSL meets Nokogiri) and a clean solution to finally stop people from using OpenSSL::SSL::VERIFY_NONE by making certificate validation less of a pain while still improving the security. Finally I'd like to revive a concept that never really found broad acceptance although it would largely increase the trustworthiness of our beloved gems - *digitally signed* gems.\n  video_provider: \"youtube\"\n  video_id: \"IDGzPoTjBDw\"\n\n- id: \"thomas-e-enebo-rubyconf-2011\"\n  title: \"JRuby Polyglot Heaven\"\n  raw_title: \"Jruby Polyglot Heaven by Thomas E Enebo and Charles Oliver Nutter\"\n  speakers:\n    - Thomas E Enebo\n    - Charles Oliver Nutter\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-12\"\n  description: |-\n    JRuby is a top-notch Ruby implementation. It's also your gateway to polyglot heaven. Ruby can do anything, but it's not always the best tool for the job. With JRuby, you can take advantage of other JVM languages. Build part of your application in Clojure, taking advantage of its immutability and transactional guarantees. Build another part in Scala, leveraging its flexible static type system and actor libraries like Akka. Use JavaScript via Rhino to test pages or run JS on the server alongside Rails. Use Mirah to build fast-as-Java algorithms in a Rubilicious syntax. The JVM is a haven for polyglots, and JRuby's your ticket to ride.\n  video_provider: \"youtube\"\n  video_id: \"ikhmBdQljVI\"\n\n- id: \"steven-harms-rubyconf-2011\"\n  title: \"Practical Meta Programming Modeling Thought\"\n  raw_title: \"Practical Meta Programming Modeling Thought by Steven Harms\"\n  speakers:\n    - Steven Harms\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-12\"\n  description: |-\n    I have completed a second major release of a library that fully conjugates Classical Latin verbs in each of their 133 froms * 5 standard paradigms. Owing to the irregularity of human communication, modeling the provision of unambiguous answers (return values) to ambiguously asked things (flexible / incomplete method calls) might have required hundreds, if not thousands, of method definitions or static values entered in a database. But what if heuristics could be given to a Ruby class such that it \"thought\" as language learners are taught to think? What if it could be taught to be flexible in respecting the ambiguous calls given and to still give precise, correct answers back - as human language learners are capable of doing? By adopting this design paradigm code could become leaner and more reflective of human cognitive process. Thankfully for Rubyists, this is not a dream, this is reality. Our programs can operate more intelligently, more heuristically, and more insightfully. We can save ourselves days of development time by integrating the next tier of metaprogramming patterns I seek to demonstrate. This is perhaps what makes Ruby so unique, so mysterious, so enticing and so special.\n  video_provider: \"youtube\"\n  video_id: \"s1MJh4VhrKM\"\n\n- id: \"kouji-takao-rubyconf-2011\"\n  title: \"Ruby Conf 2011 MacRuby on Rails\"\n  raw_title: \"Ruby Conf 2011 MacRuby on Rails by Kouji Takao\"\n  speakers:\n    - Kouji Takao\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-12\"\n  description: |-\n    MacRuby is an implementation of Ruby 1.9 that is directly on top of Mac OS X core technologies. Recently, MacRuby has become viable as a tool for developing useful desktop applications for Mac OS X. However, as of March 2011, MacRuby is still missing some functionality that is present in cRuby. Therefore, MacRuby is not able to run Ruby on Rails. In my presentation, I will explain how I modified MacRuby to make it a suitable foundation for running Rails. I would also like to explain some of technical intricacies that I discovered along the way.\n  video_provider: \"youtube\"\n  video_id: \"XRk1h6ekZGg\"\n\n- id: \"shota-rubyconf-2011\"\n  title: \"Parallel Testing World\"\n  raw_title: \"Ruby Conf 2011 Parallel Testing World by Shota, Fukumori\"\n  speakers:\n    - Shota\n    - Fukumori\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-12\"\n  description: |-\n    Ruby (MRI) has an unit-testing library, 'test/unit'. This is used for ruby's `make test-all`. In February 2011, I committed a patch (\"parallel_test\") that allows us to run multiple Test::Unit::TestCase-s at the same time. Because of this patch, ruby's `make test-all` can run tests faster. This patch also affects to existing tests using `test/unit`. In this talk, I take you into the parallel testing world. We'll talk about general parallel testing, benefits of parallel testing, multi-threaded or multi-process, etc. Then talk about the patch, the story of making the patch and describe how the patch works.\n  video_provider: \"youtube\"\n  video_id: \"ZWPZ9Fd4V0Q\"\n\n- id: \"koichi-sasada-rubyconf-2011\"\n  title: \"Implementation of Ruby 1.9.3 and Later\"\n  raw_title: \"Implementation of ruby 1.9.3 and Later by Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-12\"\n  description: |-\n    Maybe, Ruby 1.9.3 will have been released at the time of RubyConf2011. In this talk, I will introduce the news about this latest release. This is not a language features, but a implementation features. I will also introduce other developing features which can not implement on 1.9.3 in time. Moreover, I will introduce our research activities such as real-time profiler, pragmatic compilers and our approach to introduce parallel execution into Ruby - MVM.\n  video_provider: \"youtube\"\n  video_id: \"BsVSgG367lY\"\n\n- id: \"joshua-wehner-rubyconf-2011\"\n  title: \"Must it Always be about Sex\"\n  raw_title: \"Must it Always be about Sex by Joshua Wehner\"\n  speakers:\n    - Joshua Wehner\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-12\"\n  description: |-\n    Why do some people keep talking about diversity? Who cares if we're all the same? So long as we're not technically discriminating against anyone, that means we're good, right? If we only get applications from white dudes, that must mean that white dudes are the only ones out there. Right? Right? When we feel threatened, we find comfort among people who seem most like us. As specialization increases in the community, we glom on to people who look like us, talk like us, and think like us. There's safety in a crowd. But there are real dangers in becoming too much alike: monotony breeds more monotony. Real innovation happens when you think different than everyone else. What happens when we ruthlessly eliminate different thinkers, as we winnow the stack of resumés to those that seem most likely to \"fit in\"? Come to this talk to find out what you can do to diversify - yourself, your organization, and your peers - and how you can help grow a better, stronger, more diverse community.\n  video_provider: \"youtube\"\n  video_id: \"xZFJmSKisdA\"\n\n- id: \"sean-cribbs-rubyconf-2011\"\n  title: \"Resources, For Real This Time (with Webmachine)\"\n  raw_title: \"Resources, For Real This Time (with Webmachine) by Sean Cribbs\"\n  speakers:\n    - Sean Cribbs\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    Over the past 5-6 years we have seen a lot of changes in the way that Ruby apps speak HTTP -- from Rails' \"REST\" conventions, to the brilliantly simple Sinatra, to the modular Rack abstraction -- but we haven't yet unlocked the entire subtle power of HTTP. We know HTTP is so much more than verbs and URLs that correspond to CRUD, and yet it's still too hard to do conditional requests, content negotiation, and then return the right type of response. What if, instead of forcing HTTP into our MVC-shaped applications, we shaped our applications like HTTP? Instead of forcing a resource into seven controller actions or verb/URL-specific methods, what if the resource itself was the abstraction? A whole world of subtle and powerful programming patterns emerge. This is the world of Webmachine, a toolkit for building HTTP applications and a port of the Erlang toolkit of the same name. I will introduce Webmachine's unique programming model and demonstrate how to easily expose rich HTTP behavior in a few short lines of Ruby code.\n  video_provider: \"youtube\"\n  video_id: \"odRrLK87s_Y\"\n\n- id: \"eric-allam-rubyconf-2011\"\n  title: \"Sandboxing Ruby: The Good, the Bad, and the Fugly\"\n  raw_title: \"Sandboxing Ruby: The Good, the Bad, and the Fugly by Eric Allam\"\n  speakers:\n    - Eric Allam\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    You might never find the need to sandbox ruby, but trying to sandbox ruby is fun. We get to dive deep into the internals of Ruby and learn all the ways running ruby code securely can fail. We'll walk through some different approaches and how they can be broken: - REGEX to the Rescue - Threads and $SAFE - JRuby/MacRuby Sandbox - RubyCop -- A ruby static analyzer And after surveying the sandbox scene we'll draw some conclusions on how to mitigate potential sandbox failures and how Ruby itself can change to make really sandboxing Ruby a reality.\n  video_provider: \"youtube\"\n  video_id: \"6XxCOYco3Eg\"\n\n- id: \"matt-aimonetti-rubyconf-2011\"\n  title: \"Complex Ruby concepts dummified\"\n  raw_title: \"RubyConf 2011 - Complex Ruby concepts dummified by Matt Aimonetti\"\n  speakers:\n    - Matt Aimonetti\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    Programming languages, such as Ruby, are natural and elegant. But to achieve this elegance, things have to happen under the hood. Garbage Collection, concurrency, Global Interpreter Lock, metaprogramming, C extensions are just some of the things happening with or without our knowledge. Trying to understand these concepts, their implementations and their implications in daily coding might seem daunting. However, having a good understanding of these topics will make you a better developer. No CS degree or PhD required to attend this talk.\n  video_provider: \"youtube\"\n  video_id: \"Qxoc1wrjBuE\"\n\n- id: \"tom-preston-werner-rubyconf-2011\"\n  title: \"GitHub Flavored Ruby\"\n  raw_title: \"GitHub Flavored Ruby by Tom Preston-Werner\"\n  speakers:\n    - Tom Preston-Werner\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    Someone once told me that software development is a constant battle against complexity. Over the past three years we've built several large systems at GitHub and if anything, that saying is an understatement. Things like tight coupling, insufficient testing or documentation, lack of versioning discipline, and underspecified design documents can easily lead you down a path of ruin. In this talk I'll cover many of the techniques we use at GitHub to defend against complexity in our Ruby systems, including Readme Driven Development, Semantic Versioning, TomDoc, Git/GitHub workflow, modularization, metrics, and exception reporting.\n  video_provider: \"youtube\"\n  video_id: \"dCfmcPaYQXQ\"\n\n- id: \"michael-edgar-rubyconf-2011\"\n  title: \"Laser: Static Analysis for Ruby, in Ruby\"\n  raw_title: \"Laser: Static Analysis for Ruby, in Ruby by Michael Edgar\"\n  speakers:\n    - Michael Edgar\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    What truly makes Ruby special as a language is its focus on expressivity, flexibility, and dynamism. Yet these same properties - and their widespread use in the community - make even straightforward application code difficult to analyze statically in a meaningful way. Laser seeks to change that. As a general-purpose analyzer using traditional compiler techniques, it statically discovers properties of real-world Ruby programs that no existing tool can. This talk is a whirlwind tour of what Laser can do, how it does it, and what it means for a typical Ruby programmer (who doesn't want to litter his or her code with type annotations). Among the questions it attempts to answer: * What code never runs? * What variables are unused? * What code runs, but has no meaningful effect? * What exceptions might a method raise? * Are blocks required, optional, or ignored by a method? * What variables are constant? * What methods get generated (or removed) by loops at load-time? * What types are being used, and where? * What gets added to a class by calling a method like acts_as_list? Most importantly, Laser uses this information to find bugs and tell you about them, in addition to warning you about potential mistakes. It has a clear integration path with YARD and Redcar, as well as a possible future in optimization. On a broader scale, Laser exposes and builds upon the underlying strength and regularity of Ruby and modern Ruby techniques, without restricting Ruby's natural expressivity through static typing.\n  video_provider: \"youtube\"\n  video_id: \"Uadw9fmig_k\"\n\n- id: \"jonathan-dahl-rubyconf-2011\"\n  title: \"Advanced API design: how an awesome API can attract friends...\"\n  raw_title: \"Advanced API design: how an awesome API can attract friends... by Jonathan Dahl\"\n  speakers:\n    - Jonathan Dahl\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    Advanced API design: how an awesome API can attract friends, make you rich, and change the world by Jonathan Dahl.\n\n    APIs are becoming ubiquitous, but they are really hard to design well. In this talk, we'll discuss how to design and implement an API that isn't just functional, but makes people stand up and cheer. We'll also cover tips for integrating with other people's APIs. But an awesome API isn't just a feature. APIs are currently transforming the world, just like open source software has changed the world for the last decade. We'll talk about how this transformation impacts developers and changes the rules.\n  video_provider: \"youtube\"\n  video_id: \"OtxNUrTH0pA\"\n\n- id: \"dr-nic-williams-rubyconf-2011\"\n  title: \"Threading versus Evented\"\n  raw_title: \"Ruby Conf 2011 Threading versus Evented by Dr Nic Williams\"\n  speakers:\n    - Dr. Nic Williams\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    I wanted to know, \"Do I need to learn about EventMachine or node.js? Can I use threads? What is so good or bad about threading in Ruby 1.8, Ruby 1.9, JRuby and Rubinius 2.0?\" What was important to me was the the choice was abstracted away. I wanted to write normal, step-by-step Ruby code. Yet I wanted it to be performant. I've asked a lot of people. I even hosted EM RubyConf (http://emrubyconf.com) during RailsConf 2011 in order to gather the brightest minds in the Ruby community. \"What choices do I need to make, how different does my code look, and how do I do testing?\" These are the questions I searched for answers. I'd like to now share the answers.\n  video_provider: \"youtube\"\n  video_id: \"N0PZ7_x6ajw\"\n\n- id: \"marty-haught-rubyconf-2011\"\n  title: \"Ruby Community: Awesome; Could Be Awesomer\"\n  raw_title: \"Ruby Community: Awesome; Could Be Awesomer by Marty Haught\"\n  speakers:\n    - Marty Haught\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    We are known for our community. Does this mean our job is done? Are we starting to stagnate? Simply gathering Rubyists together isn't enough. How are you improving your community? Fear not as anyone of you can take action. Whether you live in a place with no organized Ruby meet-ups or you're contemplating a big regional event, we will go over why you should take action and give you practical steps to do so. We'll also bring light to not just increasing membership counts but actively making everyone better. Innovation is happening out there that we'll go over in detail. Join us, learn and get involved -- we're building something awesome!\n  video_provider: \"youtube\"\n  video_id: \"4SicPTXdArU\"\n\n- id: \"eleanor-mchugh-rubyconf-2011\"\n  title: \"Go and Ruby `by Eleanor McHugh\"\n  raw_title: \"Go and Ruby `by Eleanor McHugh\"\n  speakers:\n    - Eleanor McHugh\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    Go is a statically-compiled systems language geared to developing scalable and type-safe applications whilst leveraging type inference to approximate the light touch of a dynamic language. It could be characterised as the static-typing world's response to Ruby. In this session we're going to explore the Go language, its tool-chain and idioms such as CSP-based concurrency and dynamically inferred interfaces to see how they influence the design of Go applications. We'll compare these to equivalent Ruby idioms where they exist, model Go-style concurrency in pure MRI Ruby, and look at interoperability between the two languages. Along the way we'll meet gotest (Go's testing and benchmarking framework), CGO (for linking to C libraries), goinstall (the remote package installer) and Go's powerful reflection and type manipulation features. There'll be a good mix of Go and Ruby code so that by the end of the session you'll be comfortable reading Go source code, have a basic feel for developing with the language and the necessary background to start using Go components in your dev projects.\n  video_provider: \"youtube\"\n  video_id: \"XOjMmGzNILQ\"\n\n- id: \"zach-holman-rubyconf-2011\"\n  title: \"How GitHub Uses GitHub to Build GitHub\"\n  raw_title: \"How GitHub Uses GitHub to Build GitHub by Zach Holman\"\n  speakers:\n    - Zach Holman\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    Build features fast. Ship them. That's what we try to do at GitHub. Our process is the anti-process: what's the minimum overhead we can put up with to keep our code quality high, all while building features *as quickly as possible*? It's not just features, either: faster development means happier developers. This talk will dive into how GitHub uses GitHub: we'll look at some of our actual Pull Requests, the internal apps we build on our own API, how we plan new features, our Git branching strategies, and lots of tricks we use to get everyone — developers, designers, and everyone else — involved with new code. We think it's a great way to work, and we think it'll work in your company, too.\n  video_provider: \"youtube\"\n  video_id: \"MQZoy3VU3io\"\n\n- id: \"mitchell-hashimoto-rubyconf-2011\"\n  title: \"Next Level Virtual Machine Maneuver!\"\n  raw_title: \"Next Level Virtual Machine Maneuver! by Mitchell Hashimoto\"\n  speakers:\n    - Mitchell Hashimoto\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    Almost every developer has dreams of grandeur made up of machines bending to our every will. This is now not only possible, but its a good a practice! Harnessing some Ruby power and by scripting Vagrant, an application to build virtualized environments, virtual machines can be used in previously unthought ways. In this talk, learn how to script Vagrant and use it to build testing environments for your Ruby libraries and applications. The end result is that your applications and libraries are now known stable on systems which were previously difficult to test.\n  video_provider: \"youtube\"\n  video_id: \"IMGBiJ_haSM\"\n\n- id: \"ilya-grigorik-rubyconf-2011\"\n  title: \"Ruby in the browser with NativeClient (NaCl)\"\n  raw_title: \"Ruby in the browser with NativeClient (NaCl) by Ilya Grigorik\"\n  speakers:\n    - Ilya Grigorik\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    JavaScript is great, but let's face it, being stuck with just JavaScript in the browser is no fun. Why not write and run Ruby in the browser, on the client, and on the server as part of your next web application? Don't believe it, think its a crazy or an awesome idea, or think that it just plain won't work? Drop by to learn about Google Chrome's Native Client (NaCl) project which is aiming to allow web developers to seamlessly execute native code inside the browser. We'll take a look at the motivating use cases, dive under the hood to understand how it all works, and also work through a functional example of running Ruby code in the browser!\n  video_provider: \"youtube\"\n  video_id: \"Y3YGIMZ6Sw4\"\n\n- id: \"tyler-hunt-rubyconf-2011\"\n  title: \"Raising the Bar\"\n  raw_title: \"Raising the Bar by Tyler Hunt\"\n  speakers:\n    - Tyler Hunt\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    Now that there are now over 25,000 gems on RubyGems.org, it's time we took a step back to look at the quality of what we're producing and the best practices we can all follow that will benefit the community. Other languages expend a lot of effort maintaining a standard coding style and consistent APIs among their shared libraries, but the Ruby community doesn't. This has done a lot to lower the barrier to entry and allow the Ruby ecosystem to flourish, but it has also produced a lot of code of questionable quality that doesn't always mesh well in our applications. There are simple conventions we can follow, though, that will make a big difference in establishing a consistent baseline for our gems. These include things like writing gemspecs instead of Rake tasks that generate them, properly namespacing your libraries, and not polluting the load path. But there are also other practices that will benefit others, like producing good documentation, including binaries when needed, and establishing a sane versioning strategy. We'll cover the full lifecycle of a gem from beginning to end, from your first push to RubyGems.org to making and accepting community contributions, and consider the conventions that we can establish each step of the way to increase the value of the gems we're producing.\n  video_provider: \"youtube\"\n  video_id: \"mtC9ow6SGtA\"\n\n- id: \"mike-perham-rubyconf-2011\"\n  title: \"Scaling Ruby with Actors, or How I Learned to Stop Worrying and Love Threads\"\n  raw_title: \"Scaling Ruby with Actors, or How I Learned to Stop Worrying and Love Threads by Mike Perham\"\n  speakers:\n    - Mike Perham\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    The last two years have been a personal tour of EventMachine, Fibers and Threads for me as I've toured the ecosystem looking for a developer-friendly, efficient solution for scaling Ruby. Historically Threads have performed poorly in Ruby but guess what? - recent events may change your mind. Now would be a good time to give them a second chance.\n  video_provider: \"youtube\"\n  video_id: \"JpxT55j3IXo\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2011-qa-with-matz\"\n  title: \"Q&A with Matz\"\n  raw_title: 'Q&A with Yukihiro \"Matz\" Matsumoto'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    Question and Answer session with Yukihio \"Matz\" Matsumoto creator of the ruby programming language.\n  video_provider: \"youtube\"\n  video_id: \"2rfS72g1FSw\"\n\n- id: \"tim-connor-rubyconf-2011-mongomapper-mixins-and-migrati\"\n  title: \"MongoMapper, Mixins, and Migrations - a look at managing data-model complexity\"\n  raw_title: \"MongoMapper, Mixins, and Migrations - a look at managing data-model complexity by Tim Connor\"\n  speakers:\n    - Tim Connor\n  event_name: \"RubyConf 2011\"\n  date: \"2011-09-29\" # TODO\n  published_at: \"2011-12-13\"\n  description: |-\n    An exploration of how the DataMapper pattern used by MongoMapper works very well with key value stores, in general, and how exceptionally well it works in a Document store like Mongo exceptionally, versus it's less ideal match with a schema based document store like an RDBMS. Tim will be comparing benefits of how the ease of modeling your data in such a way, versus the iconic DB modeling of 3rd normal form, which brings up issues of composition over inheritance, which favors 3rd normal and how ruby's mixin system plays into that tension. This all leads up to having a data model that is trivial to make excessively dynamic, and challenging to keep sane and consistent, in such a system. Methods of migration and data massage are discussed with Tim suggesting what has worked best on some real Mongo projects, but such an approach would work well with any kv store.\n  video_provider: \"youtube\"\n  video_id: \"edft9TnOkOg\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2012/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyb2J9YQH65NIEcVpmK6Rgct\"\ntitle: \"RubyConf 2012\"\nkind: \"conference\"\nlocation: \"Denver, CO, United States\"\ndescription: \"\"\npublished_at: \"2012-11-16\"\nstart_date: \"2012-11-01\"\nend_date: \"2012-11-03\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2012\nbanner_background: \"#081625\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 39.7392358\n  longitude: -104.990251\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2012/videos.yml",
    "content": "---\n- id: \"yukihiro-matz-matsumoto-rubyconf-2012\"\n  title: \"Keynote: Reinventing Wheels of the Future\"\n  raw_title: \"Ruby Conf 12 Keynote: Reinventing Wheels of the Future by Yukihiro 'Matz' Matsumoto\"\n  speakers:\n    - Yukihiro 'Matz' Matsumoto\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-07\"\n  description: |-\n    In this Keynote 'Matz' talks about how diversity helps to create innovation.\n\n    12:36 - website Matz referes to http://www.malevole.com/mv/misc/killerquiz/\n  video_provider: \"youtube\"\n  video_id: \"hgs_fVfsduA\"\n\n- id: \"hiroshi-nakamura-rubyconf-2012\"\n  title: \"Ruby HTTP Clients Comparison\"\n  raw_title: \"Ruby Conf 12 - Ruby HTTP Clients Comparison by Hiroshi Nakamura\"\n  speakers:\n    - Hiroshi Nakamura\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-12-03\"\n  description: |-\n    The simplicity of the Ruby bundled library net/http has produced number of derivation / substitution HTTP clients for Ruby. I, who is an author of a HTTP client, performed surveys of those HTTP clients in last several years. One unsurprising thing I found from it is that users can pick one-gem-for-all generic HTTP client and also can pick the best one for the specified purpose.\n\n    In this talk, based on update to the advantages-and-disadvantages comparison of HTTP clients at http://bit.ly/RubyHTTPClients, I'll introduce characteristics of HTTP clients for different purposes.\n  video_provider: \"youtube\"\n  video_id: \"x6CeB75aMwc\"\n\n- id: \"josh-susser-fixed-rubyconf-2012\"\n  title: \"Thinking in Objects\"\n  raw_title: \"Ruby Conf 12 - Thinking in Objects by Josh Susser (Fixed)\"\n  speakers:\n    - Josh Susser (Fixed)\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-12-02\"\n  description: |-\n    Ruby is one of the best object-oriented languages around. Ubiquitous objects, duck-typing, mixins, expressive syntax with low ceremony, powerful reflection and metaprogramming. But Ruby has a mixed heritage that incorporates functional and procedural models along with OOP. This flexibility provides many options for how to solve problems, but it can also lead even experienced developers into a confusing mix of programming styles and hard-to-understand software designs. But what can we do to keep things simple and easy to understand? Alan Kay is often quoted as saying \"Perspective is worth 80 IQ points.\" So let's get the right perspective on Ruby and look at it from the direction of objects and OOP. This talk examines the fundamental concepts of object-orientation, and presents a simple model for how to think about objects and object-oriented programming. Why are objects so useful? What makes object-oriented programs easy to write and maintain? What are the pitfalls of not keeping to the OOP model? And how many slides can it take to explain two sentences? We'll answer all these questions and more!\n  video_provider: \"youtube\"\n  video_id: \"D52V2tbWdNQ\"\n\n- id: \"ben-orenstein-rubyconf-2012\"\n  title: \"Refactoring from Good to Great\"\n  raw_title: \"Ruby Conf 12 - Refactoring from Good to Great by Ben Orenstein\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-12-02\"\n  description: |-\n    See other deliveries of this presentation at:\n\n    http://www.youtube.com/watch?v=DC-pQPq0acs Aloha Ruby\n    http://www.youtube.com/watch?v=Lj-Pl3ttEWk Rocky Mountain Ruby\n\n    Most developers know enough about refactoring to write code that's pretty good. They create short methods, and classes with one responsibility. They're also familiar with a good handful of refactorings, and the code smells that motivate them.\n\n    This talk is about the next level of knowledge: the things advanced developers know that let them turn good code into great. Code that's easy to read and a breeze to change.\n\n    These topics will be covered solely by LIVE CODING; no slides. We'll boldly refactor right on stage, and pray the tests stay green. You might even learn some vim tricks as well as an expert user shows you his workflow.\n\n    Topics include:\n\n    The Open-Closed Principle The types of coupling, and their dangers Why composition is so damn great A powerful refactoring that Kent Beck refers to as \"deep deep magic\" How to destroy conditionals with a NullObject The beauty of the Decorator pattern Testing smells, including Mystery Guest and stubbing the system under test The stuff from the last halves of Refactoring and Clean Code that you never quite got to.\n  video_provider: \"youtube\"\n  video_id: \"L1G--mPscQM\"\n\n- id: \"pat-saughnessy-rubyconf-2012\"\n  title: \"Dissecting a Ruby Block\"\n  raw_title: \"Ruby Conf 12 - Dissecting a Ruby Block by Pat Saughnessy\"\n  speakers:\n    - Pat Saughnessy\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-12-01\"\n  description: |-\n    More than any other feature of the language, in my opinion blocks are what make using Ruby fun. But what is a block, exactly? What would I see if I could cut one open and look inside? During this talk we'll:\n\n    Explore Ruby's internal implementation of blocks, lambdas, procs and bindings. Learn how closures and metaprogramming are related in Ruby internals. Discover what metaclasses and singleton classes are and how Ruby uses them. Do you really need to know how Ruby works internally to be a good Ruby developer? Probably not. But taking a peek under the hood can help you better understand the language... and is a lot of fun!\n  video_provider: \"youtube\"\n  video_id: \"nQ1XYwzaqck\"\n\n- id: \"ryan-weald-rubyconf-2012\"\n  title: \"Building Data Driven Products with Ruby\"\n  raw_title: \"Ruby Conf 12 - Building Data Driven Products with Ruby by Ryan Weald\"\n  speakers:\n    - Ryan Weald\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-12-01\"\n  description: |-\n    Big data and data science have become hot topics in the developer community during the past year. This talk will show how ruby is used to build real data driven products at scale.\n\n    Data scientist Ryan Weald walks through the building of data driven products at Sharethrough, from exploratory analysis to production systems, with an emphasis on the role Ruby plays in each phase of the data driven product cycle.\n\n    He discusses how Ruby interacts with other data analysis tools -- such as Hadoop, Cascading, Python, and Javascript -- with a constructive look at Ruby's weaknesses, and presents suggestions on how Ruby can contribute more to data science in the areas of visualization and machine learning.\n  video_provider: \"youtube\"\n  video_id: \"XIqRdB5HCYM\"\n\n- id: \"chris-nelson-rubyconf-2012\"\n  title: \"Machine Learning for Fun and Profit\"\n  raw_title: \"Ruby Conf 12 - Machine Learning for Fun and Profit by Chris Nelson\"\n  speakers:\n    - Chris Nelson\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-28\"\n  description: |-\n    TDD is a great way to test code, but have you ever wondered if there are ways to leverage the awesome power of computers and help us write better tests? Research in the field of formal verification has shown promising results with tools that analyze programs for logic errors and can even figure out what input values caused those failures. However, until now, none of that research was ever used with Ruby. This talk discusses RubyCorrect, a research project that attempts to apply verification techniques like \"extended static checking\" and \"symbolic execution\" to the world of Ruby programs. We look at how these techniques work and how they could potentially improve the kinds of program faults we can detect. Machines that write our tests? So crazy that it just might work!\n  video_provider: \"youtube\"\n  video_id: \"snGGkCt4zQ0\"\n\n- id: \"loren-segal-rubyconf-2012\"\n  title: \"Could a Machine ever write tests for our code\"\n  raw_title: \"Ruby Conf 12 - Could a Machine ever write tests for our code by Loren Segal\"\n  speakers:\n    - Loren Segal\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-28\"\n  description: |-\n    TDD is a great way to test code, but have you ever wondered if there are ways to leverage the awesome power of computers and help us write better tests? Research in the field of formal verification has shown promising results with tools that analyze programs for logic errors and can even figure out what input values caused those failures. However, until now, none of that research was ever used with Ruby. This talk discusses RubyCorrect, a research project that attempts to apply verification techniques like \"extended static checking\" and \"symbolic execution\" to the world of Ruby programs. We look at how these techniques work and how they could potentially improve the kinds of program faults we can detect. Machines that write our tests? So crazy that it just might work!\n  video_provider: \"youtube\"\n  video_id: \"AHAONhPchKA\"\n\n- id: \"noel-rappin-rubyconf-2012\"\n  title: \"Testing Should Be Fun\"\n  raw_title: \"Ruby Conf 12 - Testing Should Be Fun by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-28\"\n  description: |-\n    Kent Beck's first articles about Test-Driven Development. I don't think I'm alone in being drawn to TDD at first because it was fun. The quick and consistent feedback and the ability to turn complicated problems into a series of smaller problems to be solved made TDD development seem more like a game than work.\n\n    Eventually TDD became less fun. Slow tests made running test suites a cruel joke. Test code gets bulky, and is hard to refactor because, of course, tests don't have their own tests.\n\n    Let's fix that. We'll show some notorious testing joy-killers, like slow tests, hard to read tests, tests that paper over bad designs rather than driving new ones. And we'll squash them, and regain testing delight.\n  video_provider: \"youtube\"\n  video_id: \"l07J_5luC3M\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2012-intimate-chat-with-matz\"\n  title: \"Intimate Chat with Matz\"\n  raw_title: \"Ruby Conf 12 - Intimate Chat with Matz featuring Yukihiro 'Matz' Matsumoto with Evan Phoenix\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n    - Evan Phoenix\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-28\"\n  description: |-\n    We're doing the Matz Q and A differently this year. Submit your questions throughout the conferences and come see Evan and Matz discuss them!\n  video_provider: \"youtube\"\n  video_id: \"B7vCuNaqT7k\"\n\n- id: \"joseph-wilk-rubyconf-2012\"\n  title: \"Somone is Wrong\"\n  raw_title: \"Ruby Conf 12 - Somone is Wrong by Joseph Wilk\"\n  speakers:\n    - Joseph Wilk\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-28\"\n  description: |-\n    Inspiration strikes you, you've done it. You have found the missing 7 letters from the MVC model. This changes everything. You start discussing it with your pair. 10 minutes later you somehow find yourself arguing if mocks are good or bad. Jettisoning your pair you gather all you're fellow colleagues for a quick discussion. Bracing yourself you unleash the full power of your words. 10 minutes later and somehow your idea has been lost and the discussion has devolved into discussing if mocks are good or bad. You're not quite sure what happend but you walk away realising you failed to convince your team or pair of this amazing concept. Maybe it was a bad idea, maybe it was the idea that would make everyones life better. Being able to convince and discuss your idea is the skill of Rhetoric. A tool no developer can live without.\n  video_provider: \"youtube\"\n  video_id: \"UUIBANm8s2s\"\n\n- id: \"chris-hunt-rubyconf-2012\"\n  title: \"Service Oriented Architecture at Square\"\n  raw_title: \"Ruby Conf 12 - Service Oriented Architecture at Square by Chris Hunt\"\n  speakers:\n    - Chris Hunt\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-28\"\n  description: |-\n    SOA is hard. Learn how Square is approaching this problem today with JRuby and where we hope to be in the future. We'll go from git init to cap deploy, covering Square's approach to testing and service isolation, dependency management, API documentation, code quality metrics, data seeding, schema versioning, logging, exception handling, security and password management, deployment and more.\n  video_provider: \"youtube\"\n  video_id: \"6mesJxUVZyI\"\n\n- id: \"nick-muerdter-rubyconf-2012\"\n  title: \"Abstracting Features Into Custom Reverse Proxies\"\n  raw_title: \"Ruby Conf 12 - Abstracting Features Into Custom Reverse Proxies by Nick Muerdter\"\n  speakers:\n    - Nick Muerdter\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-26\"\n  description: |-\n    or Making Better Lemonade From Chaos\n\n    Life isn't always simple. We often have to deal with a mishmash of applications, languages, and servers. How can we begin to standardize functionality across this chaos? Custom reverse proxies to the rescue! Using Ruby and EventMachine, learn how you can abstract high-level features and functionality into fast reverse proxies that can improve scalability, save time, and make the world happy.\n\n    See how we've applied this across a diverse set of web service APIs to standardize the implementation of authentication, request throttling, analytics, and more. See how this can save development time, eliminate code duplication, make your team happy, make the public happy, and make you a hero. See how this can be applied to any TCP-based application for a wide-variety of use cases. Still think your situation is complicated? Learn about the U.S. Government's plans to standardize API access across the entire federal government. With some reverse proxy magic, this isn't quite as difficult or as foolhardy as it may first sound. It also comes with some nice benefits for both the public audience and government developers.\n  video_provider: \"youtube\"\n  video_id: \"Vu2FOeAUZjw\"\n\n- id: \"tom-lee-rubyconf-2012\"\n  title: \"Rapid Programming Language Prototypes with Ruby RACC\"\n  raw_title: \"Ruby Conf 12 - Rapid Programming Language Prototypes with Ruby RACC by Tom Lee\"\n  speakers:\n    - Tom Lee\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-25\"\n  description: |-\n    Some people test in isolation, mocking everything except the class under test. We'll start with that idea, quickly examine the drawbacks, and ask how we might fix them without losing the benefits. This will send us on a trip through behavior vs. data, mutation vs. immutability, interface vs. data dependencies, how data shape affords parallelism, and what a system optimizing each of these for natural isolation might look like.\n  video_provider: \"youtube\"\n  video_id: \"goQZps9vt3o\"\n\n- id: \"gary-bernhardt-rubyconf-2012\"\n  title: \"Boundaries\"\n  raw_title: \"Ruby Conf 12 - Boundaries by Gary Bernhardt\"\n  speakers:\n    - Gary Bernhardt\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-25\"\n  description: |-\n    Some people test in isolation, mocking everything except the class under test. We'll start with that idea, quickly examine the drawbacks, and ask how we might fix them without losing the benefits. This will send us on a trip through behavior vs. data, mutation vs. immutability, interface vs. data dependencies, how data shape affords parallelism, and what a system optimizing each of these for natural isolation might look like.\n  video_provider: \"youtube\"\n  video_id: \"yTkzNHF6rMs\"\n\n- id: \"martin-bolet-rubyconf-2012\"\n  title: \"Krypt the next level of Ruby Cryptogaphy\"\n  raw_title: \"Ruby Conf 12 - Krypt the next level of Ruby Cryptogaphy by Martin Boßlet\"\n  speakers:\n    - Martin Boßlet\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-25\"\n  description: |-\n    Last year it was an idea, more of it in our heads than on github. This year, krypt is reality, it's growing quickly and its goal is to become the successor of the OpenSSL extension. Learn about why we need a successor at all, about the evils of OpenSSL certificate validation and how krypt will improve all this, running without restrictions on any Ruby platform. I'd like to contribute to putting an end to \"Ruby is slow\" by showing you how krypt's ASN.1/DER parser runs even faster than native OpenSSL C code or native Java crypto libraries. You'll learn about how you can use krypt today and how you can extend it to suit your needs by plugging in different \"providers\". Even if you are not particularly interested in cryptography, you might still be interested in how krypt takes testing to a new level, setting out to become one of the best-tested cryptography libraries out there. You probably know about RSpec, code coverage tools for Ruby, C and Java code, and Valgrind for sorting out memory issues. But krypt takes it one step further by making random testing an integral part of its test suite. Fuzzers are not for bad guys only - we all can benefit from random testing, with any application that accepts external input. Let me show you how krypt has spawned FuzzBert, a simple and extensible random testing framework that allows you to set up an effective random testing suite in no time. Finally, in the attempt to run as much of krypt as possible in plain Ruby, let me show you binyo, which allows dealing effectively with binary IO and low-level byte manipulation in particular, in all Rubies. If you implement protocols on the bit & byte level, need to do bit-level, exact-width operations on raw bytes, then binyo is what you have been looking for - speed up your code without having to deal with any of the implications that are inherent to Strings.\n  video_provider: \"youtube\"\n  video_id: \"U67JVwj9uT4\"\n\n- id: \"masayoshi-takahasi-rubyconf-2012\"\n  title: \"Ruby Conf 2012 mRuby meets iOS and RTOS\"\n  raw_title: \"Ruby Conf 2012 mRuby meets iOS and RTOS by Masayoshi Takahasi, Yichiro MASUI, and Yurie Yamane\"\n  speakers:\n    - Masayoshi Takahasi\n    - Yichiro MASUI\n    - and Yurie Yamane\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-24\"\n  description: |-\n    We have hacked mruby on non-PC OS. At the RubyConf 2012, we will talk and share our experiences.\n\n    Our talks have two parts (actually, we have two small talks)\n\n    Ruby + iOS = Super awesome!\n    mruby for embedded systems\n    First part (iOS):\n    Are you fed up with Objective-C? Now, you can build iOS apps with mruby.\n\n    MobiRuby aims to replace Objective-C/C/Java on mobile platforms with Ruby, just like you can use Lua or Mono to build apps on those platforms. In this presentation, I will talk about how to create iOS app using MobiRuby and MobiRuby internals.\n\n    Second part (RTOS):\n    The TOPPERS/ASP and TOPPERS/SSP (http://www.toppers.jp/en/) kernel is a famous RTOS in Japan, as extended and improved kernel for embedded systems, based on the standard profile of Micro ITRON4.0. We have used mruby on TOPPERS RTOS. We will show the issues about embedded systems and how to solve them.\n  video_provider: \"youtube\"\n  video_id: \"HuPOizo6pSE\"\n\n- id: \"josh-susser-rubyconf-2012\"\n  title: \"Thinking in Objects\"\n  raw_title: \"Ruby Conf 12 - Thinking in Objects by Josh Susser\"\n  speakers:\n    - Josh Susser\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-18\"\n  description: |-\n    Ruby is one of the best object-oriented languages around. Ubiquitous objects, duck-typing, mixins, expressive syntax with low ceremony, powerful reflection and metaprogramming. But Ruby has a mixed heritage that incorporates functional and procedural models along with OOP. This flexibility provides many options for how to solve problems, but it can also lead even experienced developers into a confusing mix of programming styles and hard-to-understand software designs. But what can we do to keep things simple and easy to understand?\n\n    Alan Kay is often quoted as saying \"Perspective is worth 80 IQ points.\" So let's get the right perspective on Ruby and look at it from the direction of objects and OOP. This talk examines the fundamental concepts of object-orientation, and presents a simple model for how to think about objects and object-oriented programming. Why are objects so useful? What makes object-oriented programs easy to write and maintain? What are the pitfalls of not keeping to the OOP model? And how many slides can it take to explain two sentences? We'll answer all these questions and more!\n  video_provider: \"youtube\"\n  video_id: \"A-Nk2j1i5p8\"\n\n- id: \"bryan-liles-rubyconf-2012\"\n  title: \"Simulating the World with Ruby\"\n  raw_title: \"Ruby Conf 12 - Simulating the World with Ruby by Bryan Liles\"\n  speakers:\n    - Bryan Liles\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-18\"\n  description: |-\n    You want to model a world. That world has millions of people, who also interact with each other. How would you even start tackling this model in Ruby? I'd like to demonstrate one solution. In this talk, we'll explore this problem from inception. See how the process can evolve from the simple first model to a much more complicated interactive tool. This talk will cover topics such as getting Ruby to do more than one thing at once, sampling discrete probability distributions in constant time, and the perils of garbage collection and a few other suprises.\n  video_provider: \"youtube\"\n  video_id: \"4vBrTEBlGnw\"\n\n- id: \"rodrigo-franco-rubyconf-2012\"\n  title: \"Interface Testing Creating a Diablo 3 bot using JRuby and Sikuli UI\"\n  raw_title: \"Ruby Conf 12 - Interface Testing Creating a Diablo 3 bot using JRuby and Sikuli UI by Rodrigo Franco\"\n  speakers:\n    - Rodrigo Franco\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-18\"\n  description: |-\n    Interface testing is boring. Making sure an image is always there when the page was loaded and also ensuring its positioned in the right place is really boring. A lot of bugs are not found because we don't have an easy way to find this little devils.\n\n    In this talk, Rodrigo Franco will guide you through the creation of a custom tailored tool, created to solve an specific interface problem that thwarts millons of people in the entire world - find out the most efficient way to fill your pockets with virtual gold in the online RPG Diablo 3.\n  video_provider: \"youtube\"\n  video_id: \"jLUwGNAHYIc\"\n\n- id: \"andrew-nordman-rubyconf-2012\"\n  title: \"Game Development and Ruby\"\n  raw_title: \"Ruby Conf 12 - Game Development and Ruby by Andrew Nordman\"\n  speakers:\n    - Andrew Nordman\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-18\"\n  description: |-\n    Game development is a topic within Ruby that is generally viewed as a novelty, only for toy projects or as a primitive tool to learn Ruby. There remains, however, a wide area of mostly untapped potential for Ruby to be used in the larger area of game development. As game engines get more complex, higher level scripting languages are being introduced and integrated with lower level programming languages to create the modern games you see today.\n  video_provider: \"youtube\"\n  video_id: \"H5_Kid3hpRs\"\n\n- id: \"tammer-saleh-rubyconf-2012\"\n  title: \"RubyMotion for Faster/Client Server Development\"\n  raw_title: \"Ruby Conf 12 - RubyMotion for Faster/Client Server Development by Tammer Saleh and Randall Thomas\"\n  speakers:\n    - Tammer Saleh\n    - Randall Thomas\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-18\"\n  description: |-\n    Tammer Saleh, cofounder of Thunderbolt Labs will take you through the process of writing a RubyMotion iOS application that interfaces seamlessly with a backend Rails API. He'll explore all of the modern iOS techniques through RubyMotion, while using Storyboards, Bundler, and pulling data from a JSON API. In the process, he'll discuss the merits and pitfalls of using RubyMotion, and when it is and isn't appropriate for your project.\n  video_provider: \"youtube\"\n  video_id: \"HSC-ZEw6Mhc\"\n\n- id: \"rich-kilmer-rubyconf-2012\"\n  title: \"Inside RubyMotion\"\n  raw_title: \"Ruby Conf 12 - Inside RubyMotion by Rich Kilmer\"\n  speakers:\n    - Rich Kilmer\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-18\"\n  description: |-\n    RubyMotion is a relatively new toolchain for iOS development using Ruby. With RubyMotion, developers can finally write full-fledged native iPhone or iPad apps in Ruby, the language you all know and love. In this session, we will cover how RubyMotion works, we will talk about its internals and what makes it unique, and we will show how easy it is to write an iOS app with it.\n  video_provider: \"youtube\"\n  video_id: \"r4F4ZW8Go5o\"\n\n- id: \"dr-nic-williams-rubyconf-2012\"\n  title: \"Change your tools, change your outcome\"\n  raw_title: \"Ruby Conf 12 - Change your tools, change your outcome by Dr. Nic Williams\"\n  speakers:\n    - Dr. Nic Williams\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-18\"\n  description: |-\n    When you type \"cap deploy\", \"ey deploy\", or \"git push heroku master\" your intent is to deploy your local application source to your running system on the Internet. That seems to be the point - you changed your code, and you want to Just Ship It. But what is your actual objective? Is it really to just \"deploy app code changes\"? Is this \"app-centric\" view and user experience satisfactory?\n\n    Code deployment is your intent on some occasions. On others you want to change your production environments for applications, or change scale attributes of your system, or change how applications and services within a system communicate with each other, or with remote services (such as facebook).\n\n    Is \"app-centric deployment\" the best mental model and toolchain for shipping changes to productions systems? Or is \"environment-centric\" or \"node-centric\", enabled with frameworks like Chef or Puppet, the most powerful & effective model of the system to allow you to deploy and manage change?\n\n    Or perhaps we should describe the entire system - all the apps, all the system dependencies, all the interconnections, all the scale attributes - and command it to come into existence? To command the system to go from nothing to v1 to v2 to v3, where each version includes changes in attributes of the system.\n\n    Where should configuration/manifests/attributes go? Source code files in the config folder? PaaS configuration or environment variables? Or should components of a system dynamically discover information about itself and configure itself?\n\n    Perhaps we need the benefits of a \"system-centric\" build toolchain, with an \"app-centric\" user/developer experience to trigger deploys, with a \"node-centric\" experience for sysadmins.\n\n    In this talk, we will reflect on the current state of deploying production systems, including build/deploy toolchains, and continuous deployment. We'll look at the attributes of a complete system, how we explicitly or implicitly describe them and their relationships, and how to orchestrate changes in the system - from app-centric, node-centric and system-centric views.\n\n    Let's discuss the difference between deployment in month 1 and living with your system for the next 59 months.\n  video_provider: \"youtube\"\n  video_id: \"BLDZrMetifM\"\n\n- id: \"jesse-storimer-rubyconf-2012\"\n  title: \"Grow Your Unix Beard Using Ruby\"\n  raw_title: \"Ruby Conf 12 - Grow Your Unix Beard Using Ruby by Jesse Storimer\"\n  speakers:\n    - Jesse Storimer\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-18\"\n  description: |-\n    Ruby, like Perl before it, has great support for systems programming and interfaces to common system calls. Unfortunately, this doesn't get talked about much in the Ruby community. In an age where alternative runtimes and threads are getting lots of attention many of the largest Rails deployments are running on single-threaded, blocking I/O, preforking web server called Unicorn.\n\n    This talk will be a safari tour through the unique features and internals of Unicorn. By strongly following the Unix philosophy of 'doing one thing well' Unicorn has carved out a reputation as a high-performance, dependable choice for Ruby apps.\n\n    The Unicorn codebase is the best, most comprehensive example of Unixsystems programming in Ruby that I've come across. You'll see real-worldexamples of fork(2), accept(2), execve(2), and others. I'll walk throughhow Unicorn distributes connections across a shared socket, how it implements deferred signal handling, how it can replace a running instance of itself without losing any connections. Trust me, by the time it's over you'll begin to feel mysteriously compelled to start growing your Unix beard.\n  video_provider: \"youtube\"\n  video_id: \"2rAoasxZKGU\"\n\n- id: \"jeese-cooke-rubyconf-2012\"\n  title: \"Allow me to reintroduce myself, my name is MagLev\"\n  raw_title: \"Ruby Conf 12 - Allow me to reintroduce myself, my name is MagLev by Jeese Cooke\"\n  speakers:\n    - Jeese Cooke\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-16\"\n  description: |-\n    Remember when Avi Bryant spoke at RailsConf '07 about Ruby's future, and how it'd be slick if we could get to where Smalltalk was 30 years ago? Well, we kinda have, in some respects, with the 1.0 release of MagLev, a Ruby implementation running on a Smalltalk VM.\n\n    What makes MagLev really special? How about a baked-in object database that sits on top of a VM almost 30 years in the making? There are a lot of cool things you can do with this type of persistence, but it's quite different from what we do in a typical Ruby app.\n\n    Let's explore what this great implementation has to offer, and learn how to help it along.\n  video_provider: \"youtube\"\n  video_id: \"Wh0BHJ7fUoc\"\n\n- id: \"rein-henrichs-rubyconf-2012\"\n  title: \"Making Security Priority Zero\"\n  raw_title: \"Ruby Conf 12 - Making Security Priority Zero by Rein Henrichs\"\n  speakers:\n    - Rein Henrichs\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-16\"\n  description: |-\n    Is security a priority for your team? The recent compromises of LinkedIn, eharmony, Last.fm, and Sony (twenty times) show that it's not enough to make it \"a priority\": it needs to be priority zero.\n\n    Learn how to build a security process that will help you detect and mitigate vulnerabilities at all levels and across all system boundaries.\n\n    Learn how to (more) accurately assess risk and make smart decisions about when and how to address security vulnerabilities.\n\n    Learn how to respond effectively to contain and minimize damage when you are compromised, and how to recover service as quickly as possible.\n\n    Learn how to disclose an incident to the public in an open, honest, responsible way that gives your users the information they need to protect themselves and opens the door to rebuilding lost trust and goodwill.\n\n    Learn how not to do the above from the tragicomic examples of others.\n  video_provider: \"youtube\"\n  video_id: \"dtG-7J1h7V8\"\n\n- id: \"davy-stevenson-rubyconf-2012\"\n  title: \"DRb vs. RabbitMQ Showdown\"\n  raw_title: \"Ruby Conf 12 - DRb vs. RabbitMQ Showdown by Davy Stevenson\"\n  speakers:\n    - Davy Stevenson\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-16\"\n  description: |-\n    Our enterprise product has used DRb as a communication layer for a number of years now. With the growth in popularity of EventMachine, it is time for us to evaluate whether a switch is right. This talk will discuss our current DRb setup, our process for comparing DRb and EventMachine and our comparison results, the decision on whether to switch, and either our reasoning to stay with DRb or how the resulting switch to EventMachine was handled.\n  video_provider: \"youtube\"\n  video_id: \"hhxEt5zAD3k\"\n\n- id: \"mike-perham-rubyconf-2012\"\n  title: \"Asynchronous Processing for Fun and Profity\"\n  raw_title: \"Ruby Conf 12 - Asynchronous Processing for Fun and Profity by Mike Perham\"\n  speakers:\n    - Mike Perham\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-16\"\n  description: |-\n    Learn the gotchas and secrets to successful message processing. The naive approach is to just throw a message on a queue but there many different trade-offs which can make your life miserable if not accounted for when designing your application. This session will show you those gotchas and secrets.\n  video_provider: \"youtube\"\n  video_id: \"RwUHcBg0i7Q\"\n\n- id: \"keavy-mcminn-rubyconf-2012\"\n  title: \"How to Build, Use, and Grow Internal Tools\"\n  raw_title: \"Ruby Conf 12 - How to Build, Use, and Grow Internal Tools by Keavy McMinn\"\n  speakers:\n    - Keavy McMinn\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-13\"\n  description: |-\n    Keavy is part of the internal tools team at Github. She will give an insight into some of the internal tools used at Github, and discuss the importance of building and using software that enables and supports your team, whether onsite or distributed, to be more productive, informed, motivated and happy.\n  video_provider: \"youtube\"\n  video_id: \"WpL9wE_KKD0\"\n\n- id: \"joseph-ruscio-rubyconf-2012\"\n  title: \"Ruby Monitoring State of the Union\"\n  raw_title: \"Ruby Conf 12 - Ruby Monitoring State of the Union by Joseph Ruscio\"\n  speakers:\n    - Joseph Ruscio\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-13\"\n  description: |-\n    A survey of the current state-of-the-art projects available for runtime monitoring of production Ruby code, encompassing everything from cron jobs to web-servers. Provides the audience with an overview of best practices as well as highlighting the remaining gaps. Covers both instrumentation and visualization/analysis.\n  video_provider: \"youtube\"\n  video_id: \"sp9OlDNAL9k\"\n\n- id: \"craig-muth-rubyconf-2012\"\n  title: \"- Xiki: the Rubyfied Next-Generation Shell\"\n  raw_title: \"Ruby Conf 12 - Xiki: the Rubyfied Next-Generation Shell by Craig Muth\"\n  speakers:\n    - Craig Muth\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-12\"\n  description: |-\n    The shell console hasn't changed in 40 years. Time for an update. Use Ruby to make commands that have menus, that you can navigate with the keyboard or your mouse. Type commands anywhere, not just at the bottom prompt. Control your rails apps, web browser, databases, and other tools. Type wiki elements like headings and bullet points. Xiki is implemented in ruby. Make new commands out of simple ruby classes.\n  video_provider: \"youtube\"\n  video_id: \"QqOrQN0bxNE\"\n\n- id: \"tony-arcieri-rubyconf-2012\"\n  title: \"The Celluloid Ecosystem\"\n  raw_title: \"Ruby Conf 12 - The Celluloid Ecosystem by Tony Arcieri\"\n  speakers:\n    - Tony Arcieri\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-12\"\n  description: |-\n    Celluloid is a concurrent object framework for Ruby that takes the headache out of building multithreaded programs. However, it's also an ecosystem of subprojects including the Reel web server for WebSockets, Celluloid::IO for evented sockets, Celluloid::ZMQ for ZeroMQ sockets, and DCell for building distributed Ruby programs. This talk will examine all of these components and help you decide which ones to use in your multithreaded Ruby programs.\n  video_provider: \"youtube\"\n  video_id: \"ZVU7yRoYb3o\"\n\n- id: \"makoto-inoue-rubyconf-2012\"\n  title: \"Rails is a Follower\"\n  raw_title: \"Ruby Conf 12 - Rails is a Follower by Makoto Inoue and Masatoshi Seki\"\n  speakers:\n    - Makoto Inoue\n    - Masatoshi SEKI\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-12\"\n  description: |-\n    \"dRuby came long before Rails. It uses metaprogramming features for distributed programming. Proxy objects \"automagically\" delegate method calls to remote objects. ... dRuby is a good example of a very flexible system implemented by Ruby. In this sense, Rails is a follower.\" - Matz\n\n    Masatoshi SEKI, the author of ERB and dRuby, and Makoto Inoue, the translator of \"The dRuby book\"　will show how dRuby's metaprogramming magic works, and inspire you to use the full power of ruby.\n\n    We will explain the history and design concepts behind dRuby, before diving into the details of the metaprogramming magic that makes it all work. dRuby will show you a side of Ruby you've never seen before. Let's explore together.\n  video_provider: \"youtube\"\n  video_id: \"kJsUgXsyfuQ\"\n\n- id: \"joshua-ballanco-rubyconf-2012\"\n  title: \"There and Back Again\"\n  raw_title: \"Ruby Conf 12 - There and Back Again by Joshua Ballanco\"\n  speakers:\n    - Joshua Ballanco\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-12\"\n  description: |-\n    Come hear a tale of how one programmer wanted to write a delegation library. Knowing that the wise elders have always stated \"it's not true until you measure it\", the programmer decided to benchmark the alternatives. But this was no ordinary benchmark. Down paths winding and mysterious, the programmer wielded his trusty \"gdb\" and became proficient with the weapon they call \"libgmalloc\". Finally, this sinister benchmark led the programmer straight into the dark heart of the Ruby Garbage Collector! But fear not...this tale has a happy ending.\n  video_provider: \"youtube\"\n  video_id: \"JlfyDp53_nY\"\n\n- id: \"matt-aimonetti-rubyconf-2012\"\n  title: \"Ruby Vs. The World\"\n  raw_title: \"Ruby Conf 12 - Ruby Vs. The World by Matt Aimonetti\"\n  speakers:\n    - Matt Aimonetti\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-11\"\n  description: |-\n    Ruby is an awesome programming language, it's so pleasing you probably haven't seriously looked at other languages since you switched. The programming world is evolving fast, new languages are created daily, new trends are emerging. Let's take a few minutes to look at a few languages from a Ruby developer perspective.\n  video_provider: \"youtube\"\n  video_id: \"V_k3q37Tieg\"\n\n- id: \"michael-bleigh-rubyconf-2012\"\n  title: \"Building modular, scalable web apps? of CORS!\"\n  raw_title: \"Ruby Conf 12 - Building modular, scalable web apps? of CORS! by Michael Bleigh\"\n  speakers:\n    - Michael Bleigh\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-11\"\n  description: |-\n    Cross Origin Resource Sharing (CORS) gives browsers the long-desired ability to make AJAX requests cross-domain. Even better, this functionality is dead simple to implement in Ruby. But while the implementation of CORS is simple, the implications are not. In this session learn about:\n\n    The many applications of CORS Using CORS to drive your application with a RESTful API Empowering 3rd party developers through registered CORS apps Implementing simple, secure user authentication for CORS apps Scale pieces of your app independently using CORS\n  video_provider: \"youtube\"\n  video_id: \"VQA2yrpI7Xk\"\n\n- id: \"josh-kalderimis-rubyconf-2012\"\n  title: \"Your App is not a Black Box\"\n  raw_title: \"Ruby Conf 12 - Your App is not a Black Box by Josh Kalderimis\"\n  speakers:\n    - Josh Kalderimis\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-11\"\n  description: |-\n    This talk is part story, part code, and part mustache.\n\n    Travis CI is a distributed continuous integration system running over 7,000 tests daily. For us to get a true insight into what is going on behind the scenes we have had to come a long way by integrating and building both tools and libraries so that Travis and its many parts are not just a black box of information.\n\n    Reading logs and using NewRelic is not new, but far from enough, especially when it comes to apps which are composed of many smaller apps, like Travis. How do you track and visualize requests being processed by multiple services? How do you silence verbose logs while not losing the core of the message? And how do you aggregate, visualize and share metrics?\n\n    A lot of how we track, manage, and visualize what is going on in Travis has been created as a set of internal tools and by using a range of awesome services, but core to a lot of this is ActiveSupport Notifications and Travis Instrumentation.\n\n    This session will give insight to how Travis is composed and connected, as well as shedding light on how simple it can be to gain more visibility into even a complex, distributed system like Travis, as well as your applications too.\n  video_provider: \"youtube\"\n  video_id: \"F9ZMMZqu3aI\"\n\n- id: \"jim-weirich-rubyconf-2012\"\n  title: \"Y Not- Adventures in Functional Programming\"\n  raw_title: \"Ruby Conf 12 - Y Not- Adventures in Functional Programming by Jim Weirich\"\n  speakers:\n    - Jim Weirich\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-11\"\n  description: |-\n    One of the deepest mysteries in the functional programming world is the Y-Combinator. Many have heard of it, but few have mastered its mysteries. Although fairly useless in real world software, understanding how the Y-Combinator works and why it is important gives the student an important insight into the nature of functional programming.\n\n    Join with us on this journey of understanding. Be prepared to curry your functions and bind your lambdas as we delve into the whys and wherefores of this paragon of functional programming. Although you will probably never have a need for the combinator, the effort put forth to understand it will improve your functional programming chops. This talk is not for the faint of heart, but the successful student will be richly rewarded.\n\n    Also, you will understand why \"Y-Combinator\" is the perfect name for Paul Graham's start-up funding company.\n\n    At the end of his talk Jim references Tom Stuart's talk \"Programming with Nothing\" which can be found here:\n\n    https://www.youtube.com/watch?v=VUhlNx_-wYk\n  video_provider: \"youtube\"\n  video_id: \"FITJMJjASUs\"\n\n- id: \"austin-vance-rubyconf-2012\"\n  title: \"Arduino the Ruby Way\"\n  raw_title: \"Ruby Conf 12 - Arduino the Ruby Way by Austin Vance\"\n  speakers:\n    - Austin Vance\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-09\"\n  description: |-\n    What's the deal\n    Writing software is great, websites, applications, and scripts are things we interact with every day. What about writing software that we can interact with in the physical world? From automated sprinkler systems that turn off when you pull into your drive way, to scoreboards at the company foosball table physical computing opens a door for the innovator inside every software engineer.\n\n    It's too hard\n    Not true, there are amazing libraries and compilers that let us write software for Arduinos in the best language, Ruby. Think about it no C, no headers, and no static types, just plain old ruby. That is a good deal.\n\n    In this talk I will go over a few of the most popular Ruby libraries for interacting with an Arduino, talk about some basics of each library and then spend time on how these libraries and Arduino can interact to create applications that respond in the physical world. There will be t-shirts shot from a robotic cannon.\n  video_provider: \"youtube\"\n  video_id: \"oUIor6GK-qA\"\n\n- id: \"aaron-patterson-rubyconf-2012\"\n  title: \"Real Time Salami\"\n  raw_title: \"Ruby Conf 12 - Real Time Salami by Aaron Patteson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-09\"\n  description: |-\n    Do you like building real time systems? Do you like salami? Then you will enjoy this talk! We're going to learn the process for curing meats at home, along with integrating the meat curing process with real time systems and Rails 4. Challenges of meat curing, and Rails internals will be discussed.\n\n    Salami is a delicious treat! Let's enjoy it together.\n  video_provider: \"youtube\"\n  video_id: \"axva-w-m9qg\"\n\n- id: \"matt-duncan-rubyconf-2012\"\n  title: \"Zero Downtime Deploys Made Easy\"\n  raw_title: \"Ruby Conf 12 - Zero Downtime Deploys Made Easy by Matt Duncan\"\n  speakers:\n    - Matt Duncan\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-09\"\n  description: |-\n    Every deploy introduces the risk of downtime because of changes which are not backwards compatible. At Yammer, we deploy our Rails codebase to hundreds of servers many times a week. In this talk, I'll discuss many of the strategies we use to mitigate downtime during deploys. This includes how we handle database changes as well as background workers and external services.\n  video_provider: \"youtube\"\n  video_id: \"LT_gFFcLj9Q\"\n\n- id: \"yehuda-katz-rubyconf-2012\"\n  title: \"Tokaido: Making Ruby Better on OS X\"\n  raw_title: \"Ruby Conf 12 - Tokaido: Making Ruby Better on OS X by Yehuda Katz\"\n  speakers:\n    - Yehuda Katz\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-09\"\n  description: |-\n    Last summer, I worked on a project that aimed to improve the experience of working with Ruby on OSX. Tokaido is a multifaceted project: it involved creating a portable binary build, a UI for working with Ruby-based web projects in development mode, and helping gem authors distribute their gems as precompiled binaries.\n\n    The ultimate goal: make it easy for Mac users to program with Ruby without needing to install and maintain a host of unrelated development tools.\n\n    In this talk, I will cover the basic architecture of Tokaido, and talk about what I learned about building and distributing Ruby during the process. This talk will cover some interesting low-level details of how Ruby loads and executes native code, and why I chose static linking for Tokaido. If you haven't given much thought to how \"native gems\" work in Ruby, you'll learn something from this talk.\n  video_provider: \"youtube\"\n  video_id: \"4iv3Gk95-v0\"\n\n- id: \"charles-nutter-rubyconf-2012\"\n  title: \"Why JRuby Works\"\n  raw_title: \"Ruby Conf 12 - Why JRuby Works by Charles Nutter and Tom Enebo\"\n  speakers:\n    - Charles Nutter\n    - Tom Enebo\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-09\"\n  description: |-\n    There's a lot to love about JRuby. It performs better than just about any other implementation. It has solid, reliable, parallel threading. Its extensions are managed code and won't segfault or interfere with threads or GC. And it gives Ruby access to anything that can run on a JVM, including code written in other languages.\n\n    But how does it work? More importantly, why does it work so well?\n\n    This talk will dig into the nitty-gritty details of how JRuby takes advantage of JVM optimization, threading, GC, and language integration. We'll show why Ruby works so well on top of the JVM and what it means for you. And we'll explore the future of the JVM and how it will make JRuby even better (and JRubyists even happier).\n  video_provider: \"youtube\"\n  video_id: \"wYFrGlSERto\"\n\n- id: \"brian-ford-rubyconf-2012\"\n  title: \"Toward a Design for Ruby\"\n  raw_title: \"Ruby Conf 12 - Toward a Design for Ruby by Brian Ford\"\n  speakers:\n    - Brian Ford\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-09\"\n  description: |-\n    Ruby is an industrial programming language. In the past eight years, tens of millions of dollars, if not more, have been invested in Ruby itself, and in frameworks and libraries for the language. Many times that have been invested in companies that have been built around Ruby.\n\n    The reason for this is that Ruby has been a remarkably good language for a wide domain of programming problems.\n\n    However, the world is changing rapidly and Ruby faces a number of significant challenges that have a very real possibility of destroying the rich ecosystem that that has been built around Ruby.\n\n    None of these significant challenges are particularly threatening to Ruby. In fact, many of them have been solved by other language ecosystems or are being actively researched.\n\n    The fundamental problem is that the Ruby design process is practically nonexistent. What does exist is opaque, ad hoc, immature, and unstructured. Stakeholders are not consulted. Rationales are not consistently explained. Technical expertise is not validated.\n\n    In this talk, I will explain key areas where I believe Ruby's existing design process threatens the viability of the language. I will detail a structure for making Ruby design decisions that provides technical rigor and balances the competing interests of existing and future Ruby stakeholders.\n  video_provider: \"youtube\"\n  video_id: \"BagNfTbXn3w\"\n\n- id: \"akira-matsuda-rubyconf-2012\"\n  title: \"Ruby 2.0 on Rails\"\n  raw_title: \"Ruby Conf 12 - Ruby 2.0 on Rails by Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-08\"\n  description: |-\n    Ruby 2.0 is coming very soon. The specification is fixed, and the first stable release will be in production in several months.\n\n    Now is the time to get prepared for 2.0\n\n    What new features are available in 2.0? How can our code, and lives be improved by these new features? Where are the examples?\n\n    This session will detail some of the great improvements in Ruby 2.0 such as:\n\n    refinements Module#prepend keyword arguments Enumerator::Lazy new literals and other lovely new features We'll cover these new features in depth with working code samples extracted from everyone's favorite and most widely read Ruby code - the Ruby on Rails framework, plugins, your Rails applications, and test codes.\n  video_provider: \"youtube\"\n  video_id: \"RHcXC9ROjlw\"\n\n- id: \"koichi-sasada-rubyconf-2012\"\n  title: \"Implementation Details of Ruby 2.0 VM\"\n  raw_title: \"Ruby Conf 12 - Implementation Details of Ruby 2.0 VM by Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-11-08\"\n  description: |-\n    As a member of Matz's team in Heroku, I'm working Ruby 2.0 to be released in next February. Ruby 2.0 doesn't have drastic changes in behavior except adding some new features. However, an internal of Ruby 2.0 VM is changing to improve performance! For example, we changed VM data structures and method invocation processes to achieve fast execution. In this presentation, I will introduce the internal changes and its performance.\n  video_provider: \"youtube\"\n  video_id: \"lWIP4nsKIMU\"\n\n- id: \"kerri-miller-rubyconf-2012\"\n  title: \"Failure for Fun and Profit!\"\n  raw_title: \"Ruby Conf 12 - Failure for Fun and Profit! by Kerri Miller (Better Slides)\"\n  speakers:\n    - Kerri Miller\n  event_name: \"RubyConf 2012\"\n  date: \"2012-11-01\" # TODO\n  published_at: \"2012-12-03\"\n  description: |-\n    Do you actually know how deliberately acquire, sharpen, and retain a technical skill? In this talk, I'll discuss common strategies to enable you to be more focused, creative, and productive while learning, by using play, exploration, and ultimately failure. You'll leave knowing several \"Experiential Learning\" patterns and techniques that can help you turn failure into success.\n\n    When was the last time you failed in a spectacular fashion? Was it really so bad? If you want to succeed, you first need to take a little time to fail.\n  video_provider: \"youtube\"\n  video_id: \"F8RnrbqKTgA\"\n  alternative_recordings:\n    - title: \"Failure for Fun and Profit\"\n      raw_title: \"Ruby Conf 12 - Failure for Fun and Profit by Kerri Miller\"\n      speakers:\n        - Kerri Miller\n      event_name: \"RubyConf 2012\"\n      date: \"2012-11-01\" # TODO\n      published_at: \"2013-03-19\"\n      description: |-\n        Repost of the video with clean slides.\n\n        http://www.youtube.com/watch?v=F8RnrbqKTgA\n\n        Do you actually know how deliberately acquire, sharpen, and retain a technical skill? In this talk, I'll discuss common strategies to enable you to be more focused, creative, and productive while learning, by using play, exploration, and ultimately failure. You'll leave knowing several \"Experiential Learning\" patterns and techniques that can help you turn failure into success.\n\n        When was the last time you failed in a spectacular fashion? Was it really so bad? If you want to succeed, you first need to take a little time to fail.\n      video_provider: \"youtube\"\n      video_id: \"OEk8tuJC1Rg\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2014/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYajZ5aZlJf1g2u5Boq-jic\"\ntitle: \"RubyConf 2014\"\nkind: \"conference\"\nlocation: \"San Diego, CA, United States\"\ndescription: \"\"\nstart_date: \"2014-11-17\"\nend_date: \"2014-11-19\"\npublished_at: \"2014-12-02\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2014\nbanner_background: \"#FAFAFA\"\nfeatured_background: \"#FAFAFA\"\nfeatured_color: \"#414866\"\ncoordinates:\n  latitude: 32.715738\n  longitude: -117.1610838\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2014/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"amy-wibowo-rubyconf-2014\"\n  title: \"Sweaters as a Servive\"\n  raw_title: \"RubyConf 2014 - Sweaters as a Servive by Amy Wibowo\"\n  speakers:\n    - Amy Wibowo\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-02\"\n  published_at: \"2014-12-02\"\n  description: |-\n    In the 1980's, Nintendo had plans for a knitting add-on to the NES, with an interface that resembled Mariopaint, but with patterned sweaters as output. Sadly, this product never saw the light of day. Devastated on hearing this, a group of Airbnb engineers (who knew nothing about machine knitting) set out to hack a knitting machine from the 1980's to be computer-controlled. Learn about how we wrote our own yarn printer API in ruby and printed our first doge meme in yarn. And watch us as we send knit requests to our yarn server, and behold as it knits ugly sweaters from those images!\n  video_provider: \"youtube\"\n  video_id: \"HKZ6nDEMpyc\"\n\n- id: \"justin-searls-rubyconf-2014\"\n  title: \"The Social Coding Contract\"\n  raw_title: \"RubyConf 2014 - The Social Coding Contract by Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-02\"\n  published_at: \"2014-12-02\"\n  description: |-\n    Social coding revolutionized how we share useful code with others. RubyGems, Bundler, and Github made publishing and consuming code so convenient that our dependencies have become smaller and more numerous. Nowadays, most projects quickly resemble a Jenga tower, with layer upon layer of poorly understood single points of failure.\n  video_provider: \"youtube\"\n  video_id: \"e_-qV8waPVM\"\n\n- id: \"richard-schneeman-rubyconf-2014\"\n  title: \"Going The Distance\"\n  raw_title: \"RubyConf 2014 - Going the Distance by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-02\"\n  published_at: \"2014-12-02\"\n  description: |-\n    If you've ever misspelled a word while searching on Google, you've benefitted from decades of distance algorithm development. In this talk we'll break down some popular distance measurements and see how they can be implemented in Ruby. We'll look at real world applications with some live demos. It won't matter if you get your kicks \"Hamming\" it up, if you drink your coffee in a \"Levenshtein\", or if you're new to Ruby: this talk is Rated R, for \"all Rubyists\". You'll be guaranteed to walk away with O(n^n) expectations met.\n  video_provider: \"youtube\"\n  video_id: \"PcINjHjIllk\"\n\n- id: \"christopher-sexton-rubyconf-2014\"\n  title: \"Epic Intro Music: BLE Beacons and Ruby\"\n  raw_title: \"RubyConf 2014 - Epic Intro Music: BLE Beacons and Ruby by Christopher Sexton\"\n  speakers:\n    - Christopher Sexton\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-02\"\n  published_at: \"2014-12-02\"\n  description: |-\n    Would you like to stroll into the office to your own dramatic theme music? We can arrive in style with an epic score. Learn how to use RubyMotion, a Raspberry Pi and iBeacon Technology to play the Imperial March when the CEO walks in.\n\n    The ability for mobile devices to detect their proximity to beacons is relatively new. We will learn how they work, the common gotchas, and how to integrate with a bigger system.\n\n    Let's build something fun with Ruby and Beacons. Plus, who doesn't want an awesome theme song?\n  video_provider: \"youtube\"\n  video_id: \"teTpPCwdh7g\"\n\n- id: \"brandon-hays-rubyconf-2014\"\n  title: \"My Little C Extension: Lego Robots are Magic\"\n  raw_title: \"RubyConf 2014 - My Little C Extension: Lego Robots are Magic by Brandon Hays\"\n  speakers:\n    - Brandon Hays\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-02\"\n  published_at: \"2014-12-02\"\n  description: |-\n    I didn't know squat about C or building extensions in Ruby. But I did want a Ruby-controlled Lego Mindstorms robot to get kids excited about Ruby. We'll dive into the basics of building C extensions, build a Ruby DSL to teach kids to drive cool Lego robots, and show off the amazing things you can do when you pull up Ruby's floorboards and look at the actually-not-too-scary C code underneath.\n  video_provider: \"youtube\"\n  video_id: \"uOsKIyD_RCo\"\n\n- id: \"jim-gay-rubyconf-2014\"\n  title: \"Eastward Ho! A Clear Path Through Ruby With OO\"\n  raw_title: \"RubyConf 2014 - Eastward Ho! A Clear Path Through Ruby With OO Jim Gay\"\n  speakers:\n    - Jim Gay\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-02\"\n  published_at: \"2014-12-02\"\n  description: |-\n    Messy code often begins with a simple \"if\". Continuing down that path is a road to ruin, but there's a simple way to avoid it. East-oriented Code is an approach that helps you follow Tell, Don't Ask. It guides you away from Feature Envy and toward better encapsulation. See before and after code and walk through easy to repeat steps that will make your Ruby programs better and easier to maintain.\n  video_provider: \"youtube\"\n  video_id: \"kXcrClJcfm8\"\n\n- id: \"tom-stuart-rubyconf-2014\"\n  title: \"A Lever for the Mind\"\n  raw_title: \"RubyConf 2014 - A Lever for the Mind by Tom Stuart\"\n  speakers:\n    - Tom Stuart\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-02\"\n  published_at: \"2014-12-02\"\n  description: |-\n    Our brains are great at social interaction and pattern matching, but terrible at reasoning about the complicated non-human systems which dominate our world. Abstraction is the adapter between the fearsome complexity of the universe and our simple primate minds; when the real world is too intricate for us to manipulate directly, abstraction gives us big friendly levers to pull instead.\n\n    I’ll explain how this single powerful idea underlies computers, mathematics, language and everything else we rely on in our daily work as computer programmers, and then show you how to use it effectively.\n  video_provider: \"youtube\"\n  video_id: \"tJkoHFjoMuk\"\n\n- id: \"mark-mcspadden-rubyconf-2014\"\n  title: \"The Quiet Programmer\"\n  raw_title: \"RubyConf 2014 - The Quiet Programmer by Mark McSpadden\"\n  speakers:\n    - Mark McSpadden\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-02\"\n  published_at: \"2014-12-02\"\n  description: |-\n    Hi, I'm [NAME] and I'm an introvert. But contrary to what you might think, it's not a problem and I am not working on it. In fact, I've embraced it.\n\n    In this session, we'll explore the strengths of introversion within the realm of programming and software development. We'll discuss how it plays a role in your interactions with other developers, your preferred work environment, and yes, even your code.\n  video_provider: \"youtube\"\n  video_id: \"iuZ-iAIw62E\"\n\n- id: \"jonan-scheffler-rubyconf-2014\"\n  title: \"Sauron: DIY Home Security with Ruby!\"\n  raw_title: \"RubyConf 2014 - Sauron: DIY Home Security with Ruby! by Jonan Scheffler\"\n  speakers:\n    - Jonan Scheffler\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-03\"\n  published_at: \"2014-12-03\"\n  description: |-\n    This is the story of how I built an all-seeing eye with Ruby, and how I use it to defend the sanctity of my suburban home.\n\n    Using a Raspberry Pi and some homemade motion detection software I've developed a home security system that can send me notifications on my phone and photograph intruders. It uses perceptual hashes to detect image changes and archives anything unusual. I can even set a custom alerting threshold and graph disturbances over time.\n\n    If you've ever had the desire to be an evil wizard with a glowing fireball of an eye this talk is perfect for you. Come play with Sauron.\n  video_provider: \"youtube\"\n  video_id: \"IIBM1Zxr66c\"\n\n- id: \"brock-wilcox-rubyconf-2014\"\n  title: \"A Partial-Multiverse Model of Time Travel for Debugging\"\n  raw_title: \"RubyConf 2014 - A Partial-Multiverse Model of Time Travel for Debugging by Brock Wilcox\"\n  speakers:\n    - Brock Wilcox\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-03\"\n  published_at: \"2014-12-03\"\n  description: |-\n    Ever type 'next' into your debugger and then realize you should have used 'step'? Or perhaps invoked a method that you wish you could take back? Regret no more! Just turn the clock back a few ticks and begin again! With only a few restrictions and side-effects we will learn how to construct and use a time machine.\n\n    WARNING: Time travel may cause zombies.\n  video_provider: \"youtube\"\n  video_id: \"EpYMRd1ZWDM\"\n\n- id: \"jeremy-evans-rubyconf-2014\"\n  title: \"Roda: The Routing Tree Web Framework\"\n  raw_title: \"RubyConf 2014 - Roda: The Routing Tree Web Framework by Jeremy Evans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-05\"\n  published_at: \"2014-12-05\"\n  description: |-\n    Roda is a new Ruby web framework designed around the concept of a routing tree. Roda gives you the simplicity of Sinatra for simple cases, while being able to scale well to handle larger, complex cases. It provides performance very close to a pure Rack application, with a flexible plugin system powerful enough to handle almost any needs. Come learn about routing trees, how they make web development better, and how Roda adds a twist on the routing tree concept to avoid the scope pollution problem inherent in many other Ruby web frameworks.\n  video_provider: \"youtube\"\n  video_id: \"W8zglFFFRMM\"\n\n- id: \"evan-phoenix-rubyconf-2014\"\n  title: \"Q&A with Matz\"\n  raw_title: \"RubyConf 2014 - Questions for Matz\"\n  speakers:\n    - Evan Phoenix\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-05\"\n  published_at: \"2014-12-05\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"_zoG2i7pMxg\"\n\n- id: \"loren-segal-rubyconf-2014\"\n  title: \"It's so quiet. Let's make music.\"\n  raw_title: \"RubyConf 2014 - It's so quiet. Let's make music. by Loren Segal\"\n  speakers:\n    - Loren Segal\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-05\"\n  published_at: \"2014-12-05\"\n  description: |-\n    Ruby is used for a lot of things, but for some reason, only a few people are using it for music. In a language that is meant to make programming fun, the lack of such creative code is scary. Let's fix the current landscape by learning how to use the tools available in Ruby (and some not) to let those creative juices flow. We will be focusing on how to build sounds from the ground up (the powerful amplitude, and the majestic waveform), so you don't need any prior audio wizardry. Just bring yourself and a Ruby console and we just might create some beautiful music in a beautiful language.\n  video_provider: \"youtube\"\n  video_id: \"oRt7rVlnPqk\"\n\n- id: \"jesse-toth-rubyconf-2014\"\n  title: \"Easy Rewrites With Ruby And Science!\"\n  raw_title: \"RubyConf 2014 - Easy rewrites with ruby and science! by Jesse Toth\"\n  speakers:\n    - Jesse Toth\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-05\"\n  published_at: \"2014-12-05\"\n  description: |-\n    Ruby makes it easy to prototype a new data model or codepath in your application and get it into production quickly to test it out. At GitHub, we've built on top of this concept with our open source dat-science gem, which helps measure and validate two codepaths at runtime. This talk will cover how we used this gem and its companion analysis gem to undertake (and complete!) a large-scale rewrite of a critical piece of our Rails app -- the permissions model -- live, side-by-side, and in production.\n  video_provider: \"youtube\"\n  video_id: \"kgDqUHWVw4A\"\n\n- id: \"kiyoto-tamura-rubyconf-2014\"\n  title: \"Build the Unified Logging Layer with Fluentd and Ruby\"\n  raw_title: \"RubyConf 2014 - Build the Unified Logging Layer with Fluentd and Ruby by Kiyoto Tamura\"\n  speakers:\n    - Kiyoto Tamura\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-05\"\n  published_at: \"2014-12-05\"\n  description: |-\n    As software becomes less monolithic and more service-oriented, log collection becomes a real problem. How can we stop hacking together brittle log parsing scripts and start building a unified logging layer?\n\n    Fluentd is a data collector written in Ruby to solve this problem. Unlike other log management tools that are designed for a single backend system, Fluentd aims to connect many input sources into several output systems.\n\n    This talk surveys Fluentd's architecture and shows real-world use cases of how different users extend it to do more with their logs with less code.\n  video_provider: \"youtube\"\n  video_id: \"sIVGsQgMHIo\"\n\n- id: \"ole-michaelis-rubyconf-2014\"\n  title: \"Chat Robots Next Level Tooling\"\n  raw_title: \"RubyConf 2014 - Chat Robots Next Level Tooling by Ole Michaelis\"\n  speakers:\n    - Ole Michaelis\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-05\"\n  published_at: \"2014-12-05\"\n  description: |-\n    Developers are lazy! So we are great in creating tooling for our daily work. But it has its weaknesses, we are creating a tons of scripts on our local maschine, sometimes we share them via git or other vcs systems. But all over all this tooling sucks when it comes to collaboration. We developers also love hanging out in chat rooms like campfire or jabber.\n  video_provider: \"youtube\"\n  video_id: \"_XagO-YkD1Q\"\n\n- id: \"liz-rush-rubyconf-2014\"\n  title: \"'Good Luck With That' : Tag Teaming Civic Data\"\n  raw_title: \"RubyConf 2014 - 'Good Luck With That' : Tag Teaming Civic Data by Liz Rush & Hsing-Hui Hsu\"\n  speakers:\n    - Liz Rush\n    - Hsing-Hui Hsu\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-16\"\n  published_at: \"2014-12-16\"\n  description: |-\n    In this end-to-end discussion about the challenges with civic data, from no-documentation & incomplete government code to figuring out how to scale data-driven SOA, we'll show you how two Ruby newbies managed to create an awesomely useful parking app in just four weeks. For those new to coding, or experienced devs looking to work with civic data, we'll show you our roadmap as well as what we learned pairing as two junior developers just starting out in the big bad world of programming.\n  video_provider: \"youtube\"\n  video_id: \"s-yjPnJwwiE\"\n\n- id: \"ernie-miller-rubyconf-2014\"\n  title: \"Ruby After Rails\"\n  raw_title: \"RubyConf 2014 - Ruby After Rails by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-16\"\n  published_at: \"2014-12-16\"\n  description: |-\n    What happens to Ruby when Rails dies?\n\n    Ruby rode the Rails rocketship to worldwide renown. While a handful of us were writing Ruby code before Rails came along, most of us owe Rails a debt of gratitude for taking Ruby mainstream, allowing us to make a living writing code in a language we love.\n\n    But opinions codified in Rails are falling out of favor. We're not writing apps that do heavy server-side rendering. Our apps have complex domain logic that grates against \"The Rails Way.\"\n\n    Is that it, then? Has Ruby entered its twilight years?\n  video_provider: \"youtube\"\n  video_id: \"EgjJYkuV0Sc\"\n\n- id: \"liz-abinante-rubyconf-2014\"\n  title: \"Programming, Education, and the American Dream\"\n  raw_title: \"RubyConf 2014 - Programming, Education, and the American Dream by Liz Abinante\"\n  speakers:\n    - Liz Abinante\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-16\"\n  published_at: \"2014-12-16\"\n  description: |-\n    The learn to code movement has popularized the idea that coding is a skill everyone can and should learn. It's the American dream: learn the desirable skill and you'll succeed financially. Those who master the skill and achieve the goals are held up as prime examples of just how easy it was. But if it was that easy, why are there so few victors encouraging hoards of hopefuls? I'll discuss the history of the American Dream, how new programming education endeavors have repackaged it, and how the lack of awareness and analysis of this privileged rhetoric is damaging our culture and workforce.\n  video_provider: \"youtube\"\n  video_id: \"_5zXjOEeRfE\"\n  slides_url: \"https://speakerdeck.com/feministy/programming-education-and-the-american-dream\"\n\n- id: \"olivier-lacan-rubyconf-2014\"\n  title: \"Polishing Ruby\"\n  raw_title: \"RubyConf 2014 - Polishing Ruby by Olivier Lacan\"\n  speakers:\n    - Olivier Lacan\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-16\"\n  published_at: \"2014-12-16\"\n  description: |-\n    There are gems out there solving very common problems that could easily be contributed back to Ruby itself. Suggesting a new Ruby feature isn't as daunting as it sounds. As long as you're diligent, you too can push ruby forward.\n  video_provider: \"youtube\"\n  video_id: \"lUDcC_HpRno\"\n\n- id: \"chris-hoffman-rubyconf-2014\"\n  title: \"2 + Cats = 4 * Cute: How Math Works in Ruby\"\n  raw_title: \"RubyConf 2014 - 2 + Cats = 4 * Cute: How Math Works in Ruby by Chris Hoffman\"\n  speakers:\n    - Chris Hoffman\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-16\"\n  published_at: \"2014-12-16\"\n  description: |-\n    Do you know how addition works in Ruby? It's simple right? You just add 2 and 2 and out pops 4. But what if you add 2 to cats? That makes no sense, but how does Ruby know it makes no sense? And what if you had a Really Good Business Reason for adding 2 and cats. To achieve the needed degree of cuteness, you're going to need to be positively cat-like yourself. In this talk you'll learn about the magic of the coerce method, and that can't be coerced into Fixnum isn't a warning, but a dare, and what you can do to make your coworkers, collaborators and future self regret it.\n  video_provider: \"youtube\"\n  video_id: \"_GIPsLpYmGE\"\n\n- id: \"mike-stowe-rubyconf-2014\"\n  title: \"Building Your API for Longevity\"\n  raw_title: \"RubyConf 2014 - Building Your API for Longevity by Mike Stowe\"\n  speakers:\n    - Mike Stowe\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-18\"\n  description: |-\n    One of the greatest challenges to developing an API is ensuring that your API lasts. After all, you don't want to have to release and manage multiple versions of your API just because you weren't expecting users to use it a certain way, or because you didn't anticipate far enough down the roadmap. In this session we'll talk about the challenge of API Longevity, as well as ways to increase your API lifecycle including having a proper mindset, careful design, agile user experience and prototyping, best design practices including hypermedia, and the challenge of maintaining persistence.\n  video_provider: \"youtube\"\n  video_id: \"8U7JoDfj3wM\"\n\n- id: \"jeffrey-matthias-rubyconf-2014\"\n  title: \"Future-Proofing Your 3rd Party Integrations\"\n  raw_title: \"RubyConf 2014 - Future-Proofing Your 3rd Party Integrations by Jeffrey Matthias\"\n  speakers:\n    - Jeffrey Matthias\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-18\"\n  description: |-\n    It's 2015... your stakeholders have decided that PayPal is out and Stripe is in. Fortunately, you're a planner. You have all of your PayPal interactions isolated in an adapter gem and your interface is clearly defined, easy to re-implement and enforce. Rewriting your adapter isn't small, but it is surmountable and can be estimated accurately so it won't lead to surprises. You win.\n\n    This talk will cover a collection of best practices for defining, enforcing and test-driving the adapter for your 3rd party service to provide easier flexibility in the future.\n  video_provider: \"youtube\"\n  video_id: \"LqZU2Q5nFRM\"\n\n- id: \"paul-gross-rubyconf-2014\"\n  title: \"Testing Isn't Enough: Fighting Bugs with Hacks\"\n  raw_title: \"RubyConf 2014 - Testing Isn't Enough: Fighting Bugs with Hacks by Paul Gross\"\n  speakers:\n    - Paul Gross\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-18\"\n  description: |-\n    Bugs and mess-ups are serious problems in software. Mistakes are inevitable - but the stakes can be high. If you're writing a hospital management system, they can cost lives. In a payments system, they can cost money. Since we can't eliminate bugs, this talk will cover strategies, hacks and monkey patches in Ruby to prevent bugs from leading to disaster. This isn't a traditional testing talk, but rather a thinking outside-of-the-box approach to busting bugs and building more robust software.\n  video_provider: \"youtube\"\n  video_id: \"qBt7v5PKHvQ\"\n\n- id: \"laura-frank-rubyconf-2014\"\n  title: \"Containerized Ruby Applications with Docker\"\n  raw_title: \"RubyConf 2014 - Containerized Ruby Applications with Docker by Laura Frank\"\n  speakers:\n    - Laura Frank\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-18\"\n  description: |-\n    Docker’s lightweight virtualization may supplant our hypervisor-backed VMs at some point in the future, and change the way that tomorrow's Ruby applications are architected, packaged and deployed. Using Docker, your Ruby applications will sit atop an excellent platform for packing, shipping and running low-overhead, isolated execution environments. You will get a brief intro to the Docker ecosystem, get to know the tools and processes needed to create containerized Ruby applications, and learn best practices for interacting with the Docker API from Ruby.\n  video_provider: \"youtube\"\n  video_id: \"SGyLjrY3LJo\"\n\n- id: \"cindy-backman-rubyconf-2014\"\n  title: \"On The Outside Looking In\"\n  raw_title: \"RubyConf 2014 - On The Outside Looking In by Cindy Backman\"\n  speakers:\n    - Cindy Backman\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-18\"\n  description: |-\n    The view of an outsider – What I have learned over the past 2 years from attending nearly 40 programming conferences on 3 different continents (with most of them being Ruby Conferences) and working on just under 1000 presentations.\n\n    Have you ever felt like you were on the outside...\n    What programming looks like to an outsider\n    Connections that are created\n    A better community experience\n    Superheroes are human too\n    Why an outsider loves the Ruby Community\n  video_provider: \"youtube\"\n  video_id: \"W3TpckhNzuM\"\n\n- id: \"randy-coulman-rubyconf-2014\"\n  title: \"Affordances in Programming Languages\"\n  raw_title: \"RubyConf 2014 - Affordances in Programming Languages by Randy Coulman\"\n  speakers:\n    - Randy Coulman\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-18\"\n  description: |-\n    A good design communicates the intended use of the object. In the physical world, this communication is accomplished by \"affordances\" as discussed by Donald Norman in \"The Psychology of Everyday Things\".\n\n    Programming languages also have affordances, and they influence the kinds of solutions we develop. The more languages we know, the more we \"expand our design space\" so that we can come up with better solutions to the problems we face every day.\n\n    We will look at a few example problems and show how they can be solved using the affordances provided by different languages.\n  video_provider: \"youtube\"\n  video_id: \"fjH1DCa56Co\"\n\n- id: \"kane-baccigalupi-rubyconf-2014\"\n  title: \"Going Evergreen\"\n  raw_title: \"RubyConf 2014 - Going Evergreen by Kane Baccigalupi\"\n  speakers:\n    - Kane Baccigalupi\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-18\"\n  description: |-\n    Consultants divide projects between greenfield and brownfield projects, and talk about this evolution from green to brown as inevitable. It's not true. Large evolving software projects can stay easy to change, easy to grow, easy to reimagine throughout their long lives. This talk explores the code and social practices that make this kind of project succeed.\n  video_provider: \"youtube\"\n  video_id: \"SziNSMP1xaM\"\n\n- id: \"adam-cuppy-rubyconf-2014\"\n  title: \"Rapidly Mapping JSON/XML API Schemas in Ruby\"\n  raw_title: \"RubyConf 2014 - Rapidly Mapping JSON/XML API Schemas in Ruby by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-18\"\n  published_at: \"2014-12-18\"\n  description: |-\n    Whether you are using a 3rd party or custom JSON API service, integration into an existing application can be time consuming: Where do you start? How can you build an object relational model that can adapt to changes in the schema?\n\n    In this talk we'll start with an existing JSON schema and build a Ruby adapter to provide a pure Ruby interface to: consume, modify and re-export that schema into JSON and XML.\n  video_provider: \"youtube\"\n  video_id: \"1K0Pt0o9F7w\"\n\n- id: \"koichi-sasada-rubyconf-2014\"\n  title: \"Incremental GC for Ruby interpreter\"\n  raw_title: \"RubyConf 2014 - Incremental GC for Ruby interpreter by Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-19\"\n  published_at: \"2014-12-19\"\n  description: |-\n    In this presentation, I will talk about incremental GC algorithm for Ruby interpreter.\n\n    Ruby 2.1 has Generational GC algorithm, which improves GC performance dramatically. However, long application pause time problem on major GC is not solved.\n\n    To overcome this problem, we Matz team at Heroku, Inc. implemented a well-known incremental GC algorithm into MRI/CRuby interpreter to reduce application pause time without any compatibility issues, with our \"write-barrier-unprotected\" objects technique. In this talk, I will explain the algorihtnm, implementation and evaluation results about new GC.\n  video_provider: \"youtube\"\n  video_id: \"4UO60ocw52w\"\n\n- id: \"forrest-chang-rubyconf-2014\"\n  title: \"6 Reasons Jubilee Could be a Rubyist's New Best Friend\"\n  raw_title: \"RubyConf 2014 - 6 Reasons Jubilee Could be a Rubyist's New Best Friend by Forrest Chang\"\n  speakers:\n    - Forrest Chang\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-19\"\n  published_at: \"2014-12-19\"\n  description: |-\n    Do you do web development in Ruby? Have you been forced to go to node or other technologies just for concurrency/websockets etc. Do miss your gems, and tire of functionality you have to implement from scratch? Do you hate javascript?\n\n    Well no need to switch languages/platforms, Jubilee could be your new best friend.\n\n    Jubilee, a rack server on top of Vert.x gives you\n\n    Concurrency\n    Speed\n    Easy Websockets support\n    Shared Memory\n    Access to the JVM ecosystem\n    Ability to reuse your existing Ruby knowledge and gems\n    \"Say Hello to your new friend\" - Al Pacino\n  video_provider: \"youtube\"\n  video_id: \"FFR0G89WXI8\"\n\n- id: \"sandi-metz-rubyconf-2014\"\n  title: \"Madame Sandi Tells Your Future\"\n  raw_title: \"RubyConf 2014 - Madam Sandi Tells Your Future by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-19\"\n  published_at: \"2014-12-19\"\n  slides_url: \"https://speakerdeck.com/skmetz/madame-sandi-tells-your-future\"\n  description: |-\n    Life's demands are such that it's easy to get lost in the day-to-day, trapped inside your own private world, expecting today to repeat endlessly and the future to remain a distant, untroubling land. The future is coming, however, whether you are ready or not, and when it does everything will change.\n\n    This talk is a history lesson that covers 3,000 years of technology. It uses the past to lend perspective to the present and give guidance for the future. It reminds us where we come from and suggests how technology can help us to choose where we’ll go next.\n  video_provider: \"youtube\"\n  video_id: \"JOM5_V5jLAs\"\n\n- id: \"yurie-yamane-rubyconf-2014\"\n  title: \"Writing mruby Debugger\"\n  raw_title: \"RubyConf 2014 - Writing mruby Debugger by Yurie Yamane & Masayoshi Takahashi\"\n  speakers:\n    - Yurie Yamane\n    - Masayoshi Takahashi\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-19\"\n  published_at: \"2014-12-19\"\n  description: |-\n    mruby forum released mruby 1.0.0 in Feb. 2014. It's been stable to use. However, because mruby is used on small boards or in application programs, it's hard to debug mruby applications. When we develop mruby application, we should write not only Ruby code, but also C code. So we need to debug both codes. To make debugging mruby application easier, we are writing prototype of mruby debugger. Current mruby distribution has no debugger, but there are some useful API sets to implement own debugger. In this talk, we introduce their API and how to use them to write a debugger.\n  video_provider: \"youtube\"\n  video_id: \"VXQYSa2jjLw\"\n\n- id: \"charles-nutter-rubyconf-2014\"\n  title: \"JRuby 9000\"\n  raw_title: \"RubyConf 2014 - JRuby 9000 by Charles Nutter & Thomas Enebo\"\n  speakers:\n    - Charles Nutter\n    - Thomas E Enebo\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-19\"\n  published_at: \"2014-12-19\"\n  description: |-\n    JRuby 9000 is the largest update to the JRuby platform during its lifetime. We will support Ruby 2.1 (or perhaps 2.2) features, replace our execution pipeline with a new optimizing compiler, support true native IO and Process logic, and finally bring character transcoding in line with MRI. At the same time, people are building more and more amazing things with JRuby. In this talk, we'll unveil JRuby 9000 and talk about the future of JRuby and Ruby.\n  video_provider: \"youtube\"\n  video_id: \"CJGVH1XTtSw\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2014\"\n  title: \"Opening Keynote: Feeding the Sharks\"\n  raw_title: \"RubyConf 2014 - Opening Keynote\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    By, Yukihiro \"Matz\" Matsumoto\n  video_provider: \"youtube\"\n  video_id: \"85ct6jOvVPI\"\n\n- id: \"satoshi-moris-tagomori-rubyconf-2014\"\n  title: \"Norikra: SQL Stream Processing in Ruby\"\n  raw_title: \"RubyConf 2014 - Norikra: SQL Stream Processing in Ruby by Tagomori Satoshi\"\n  speakers:\n    - Satoshi \"moris\" Tagomori\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    Data streams (ex: logs) are becoming larger, while analytics in (semi-) real time is also becoming more important today. Moreover, there are many non-programmers who wants to write queries in this big data era.\n\n    Norikra is an open source server software that provides \"Stream Processing\" with SQL, written in JRuby, runs on JVM. We can write and add queries for stream easily on Norikra, without any editors, compilers or deployments. I will talk about implementation of Norikra and its application in LINE corporation.\n  video_provider: \"youtube\"\n  video_id: \"5QsIMgGdw8w\"\n\n- id: \"akira-matsuda-rubyconf-2014\"\n  title: \"Template Engines in Ruby\"\n  raw_title: \"RubyConf 2014 - Template Engines in Ruby by Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    HTML template engine is one of the most important library to build a web application. But who actually knows how it works? Who can explain how the engine parses the given template and finally composes the HTML body?\n\n    In this session, I will dig into implementation details of several Ruby libraries such as ERB, Haml, Slim, Tilt, Temple, etc. and give you a quick tour into the world of template engines!\n  video_provider: \"youtube\"\n  video_id: \"ldDZggzePkk\"\n\n- id: \"zachary-scott-rubyconf-2014\"\n  title: \"Nobody Knows Nobu\"\n  raw_title: \"RubyConf 2014 - Nobody Knows Nobu by Zachary Scott\"\n  speakers:\n    - Zachary Scott\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    Nobuyoshi Nakada is the most prolific contributor to Ruby. He is the all time leader in commits to the CRuby source code. With over 10,000 commits, he leads second place by double the number of commits. Leading to his psuedonym \"Patch Monster\".\n\n    Allow me to introduce you to the man, the myth, and the legend that is nobu.\n\n    You will learn the true story of how nobu came to be, and witness exactly how he earned that psuedonym and why everyone loves nobu.\n\n    We will also show you what it takes to make it in ruby-core using nobu as an example.\n  video_provider: \"youtube\"\n  video_id: \"yqyIi0pwRO4\"\n\n- id: \"emily-stolfo-rubyconf-2014\"\n  title: \"Ruby-red onions: Peeling Back Ruby's Layers in C Extensions\"\n  raw_title: \"RubyConf 2014 - Ruby-red onions: Peeling Back Ruby's Layers in C Extensions by Emily Stolfo\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    The fact that Ruby has different implementations is both strange and powerful. Writing an extension for the language can be a daunting task but there's no better way to get to the heart of what exactly Ruby objects are and the reason for some of the language's quirks.\n\n    In this talk, we'll use an example of writing a C extension for Ruby to use a third-party C security library. We'll peel back the layers of Ruby objects to deepen our knowledge of MRI and to understand in a little more detail what it really means to write object-oriented code.\n  video_provider: \"youtube\"\n  video_id: \"8klc4R1TvoY\"\n\n- id: \"lightning-talks-rubyconf-2014\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf 2014 - Lightning Talks by Many People\"\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"GnUyjPGu5MQ\"\n  talks:\n    - title: \"Lightning Talk: Vektra\"\n      start_cue: \"00:00:00\"\n      end_cue: \"00:03:45\"\n      id: \"vektra-lighting-talk-rubyconf-2014\"\n      video_id: \"vektra-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Vektra # TODO: missing last name\n\n    - title: \"Lightning Talk: Claudio Baccigalupo\"\n      start_cue: \"00:03:45\"\n      end_cue: \"00:07:27\"\n      id: \"claudio-baccigalupo-lighting-talk-rubyconf-2014\"\n      video_id: \"claudio-baccigalupo-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Claudio Baccigalupo\n\n    - title: \"Lightning Talk: Richard Schneeman\"\n      start_cue: \"00:07:27\"\n      end_cue: \"00:11:58\"\n      id: \"richard-schneeman-lighting-talk-rubyconf-2014\"\n      video_id: \"richard-schneeman-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Richard Schneeman\n\n    - title: \"Lightning Talk: Shannon Skipper\"\n      start_cue: \"00:11:58\"\n      end_cue: \"00:15:34\"\n      id: \"shannon-skipper-lighting-talk-rubyconf-2014\"\n      video_id: \"shannon-skipper-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Shannon Skipper\n\n    - title: \"Lightning Talk: Sean Culver\"\n      start_cue: \"00:15:34\"\n      end_cue: \"00:20:36\"\n      id: \"sean-culver-lighting-talk-rubyconf-2014\"\n      video_id: \"sean-culver-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Sean Culver\n\n    - title: \"Lightning Talk: Steven Talcott Smith\"\n      start_cue: \"00:20:36\"\n      end_cue: \"00:25:28\"\n      id: \"steven-talcott-smith-lighting-talk-rubyconf-2014\"\n      video_id: \"steven-talcott-smith-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Steven Talcott Smith\n\n    - title: \"Lightning Talk: Brandon Rice\"\n      start_cue: \"00:25:28\"\n      end_cue: \"00:30:21\"\n      id: \"brandon-rice-lighting-talk-rubyconf-2014\"\n      video_id: \"brandon-rice-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Brandon Rice\n\n    - title: \"Lightning Talk: Alex Wood\"\n      start_cue: \"00:30:21\"\n      end_cue: \"00:34:32\"\n      id: \"alex-lighting-talk-rubyconf-2014\"\n      video_id: \"alex-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Alex Wood\n\n    - title: \"Lightning Talk: Phillip Ante\"\n      start_cue: \"00:34:32\"\n      end_cue: \"00:38:26\"\n      id: \"phillip-ante-lighting-talk-rubyconf-2014\"\n      video_id: \"phillip-ante-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Phillip Ante\n\n    - title: \"Lightning Talk: Jeramy Couts\"\n      start_cue: \"00:38:26\"\n      end_cue: \"00:42:32\"\n      id: \"jeramy-couts-lighting-talk-rubyconf-2014\"\n      video_id: \"jeramy-couts-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeramy Couts\n\n    - title: \"Lightning Talk: Ray Hightower\"\n      start_cue: \"00:42:32\"\n      end_cue: \"00:46:33\"\n      id: \"ray-hightower-lighting-talk-rubyconf-2014\"\n      video_id: \"ray-hightower-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Ray Hightower\n\n    - title: \"Lightning Talk: Tim Schmelmer\"\n      start_cue: \"00:46:33\"\n      end_cue: \"00:53:05\"\n      id: \"tim-schmelmer-lighting-talk-rubyconf-2014\"\n      video_id: \"tim-schmelmer-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Tim Schmelmer\n\n    - title: \"Lightning Talk: Aaron Patterson\"\n      start_cue: \"00:53:05\"\n      end_cue: \"00:58:32\"\n      id: \"aaron-patterson-lighting-talk-rubyconf-2014\"\n      video_id: \"aaron-patterson-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Aaron Patterson\n\n    - title: \"Lightning Talk: Bobby Matson\"\n      start_cue: \"00:58:32\"\n      end_cue: \"01:03:17\"\n      id: \"bobby-matson-lighting-talk-rubyconf-2014\"\n      video_id: \"bobby-matson-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Bobby Matson\n\n    - title: \"Lightning Talk: Jason Clark\"\n      start_cue: \"01:03:17\"\n      end_cue: \"01:08:25\"\n      id: \"jason-clark-lighting-talk-rubyconf-2014\"\n      video_id: \"jason-clark-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Jason Clark\n\n    - title: \"Lightning Talk: Chris Sexton\"\n      start_cue: \"01:08:25\"\n      end_cue: \"01:10:52\"\n      id: \"chris-sexton-lighting-talk-rubyconf-2014\"\n      video_id: \"chris-sexton-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Sexton\n\n    - title: \"Lightning Talk: Jonathan Slate\"\n      start_cue: \"01:10:52\"\n      end_cue: \"01:15:05\"\n      id: \"jonathan-slate-lighting-talk-rubyconf-2014\"\n      video_id: \"jonathan-slate-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Jonathan Slate\n\n    - title: \"Lightning Talk: Amanda Wagener\"\n      start_cue: \"01:15:05\"\n      end_cue: \"01:20:44\"\n      id: \"amanda-wagener-lighting-talk-rubyconf-2014\"\n      video_id: \"amanda-wagener-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Amanda Wagener\n\n    - title: \"Lightning Talk: Costi\"\n      start_cue: \"01:20:44\"\n      end_cue: \"01:27:03\"\n      id: \"costi-lighting-talk-rubyconf-2014\"\n      video_id: \"costi-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Costi # TODO: missing last name\n\n    - title: \"Lightning Talk: Colin Kelley\"\n      start_cue: \"01:27:03\"\n      end_cue: \"01:32:01\"\n      id: \"colin-kelley-lighting-talk-rubyconf-2014\"\n      video_id: \"colin-kelley-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Colin Kelley\n\n    - title: \"Lightning Talk: Michael Hartl\"\n      start_cue: \"01:32:01\"\n      end_cue: \"01:36:42\"\n      id: \"michael-hartl-lighting-talk-rubyconf-2014\"\n      video_id: \"michael-hartl-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Hartl\n\n    - title: \"Lightning Talk: Pamela Assogba\"\n      start_cue: \"01:36:42\"\n      end_cue: \"1:39:54\"\n      id: \"pamela-assogba-lighting-talk-rubyconf-2014\"\n      video_id: \"pamela-assogba-lighting-talk-rubyconf-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Pamela Assogba\n\n- id: \"ryan-stout-rubyconf-2014\"\n  title: \"Isomorphic App Development with Ruby and Volt\"\n  raw_title: \"RubyConf 2014 - Isomorphic App Development with Ruby and Volt by Ryan Stout\"\n  speakers:\n    - Ryan Stout\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    As single page apps become common, more and more of our logic becomes duplicated between the front and back-end. We also spend more time writing API glue code to move data between each side. With isometric development you can remove the boilerplate of web development and the cognitive load of switching between languages.\n\n    Existing isomorphic web frameworks run JavaScript on the server. Volt lets developers write their app code in ruby and have it run both in the browser and on the server. Data is automatically synchronized to remove the need for REST API development.\n  video_provider: \"youtube\"\n  video_id: \"7i6AL7Walc4\"\n\n- id: \"michael-hartl-rubyconf-2014\"\n  title: \"Enumerable for Fun & Profit\"\n  raw_title: \"RubyConf 2014 - Enumerable for Fun & Profit\"\n  speakers:\n    - Michael Hartl\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    By, Michael Hartl\n    Let's peek under the hood of the the Enumerable module, a goldmine of examples of the power and flexibility of Ruby. Although some of Enumerable's methods are familiar from workhorse Ruby data structures such as Array and Hash, there are tons of hidden gems, including cycle, lazy, partition, and grep. Mastering the ins & outs of Enumerable will save you time, avoid bugs, and help you write clearer and more concise code. Join the author of the Ruby on Rails Tutorial on a journey through one of the most captivating and illuminating modules in Ruby's Standard Library.\n  video_provider: \"youtube\"\n  video_id: \"y4V9qVTkj3c\"\n\n- id: \"david-copeland-rubyconf-2014\"\n  title: \"Overcoming Our Obsession with Stringly-Typed Ruby\"\n  raw_title: \"RubyConf 2014 - Overcoming Our Obsession with Stringly-Typed Ruby\"\n  speakers:\n    - David Copeland\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    By, David Copeland\n    We use Strings. A lot. We use them for pretty much everything that isn't a number (it's jokingly referred to as \"stringly-typed\").\n\n    It ends up creating unnecessary complexity in our applications, making the boundaries between classes and modules hard to understand.\n  video_provider: \"youtube\"\n  video_id: \"7Obobjq8g_U\"\n\n- id: \"sam-phippen-rubyconf-2014\"\n  title: \"An Introduction to Spies in RSpec\"\n  raw_title: \"RubyConf 2014 - An Introduction to Spies in RSpec\"\n  speakers:\n    - Sam Phippen\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    By, Sam Phippen\n    Spies are a relatively new feature in RSpec. In this tutorial-style talk: we'll look at what spies are, how spies work in RSpec and how one can write better tests with spies. We'll work through some of examples of writing new tests with spies, improving old tests with spies and the reasons why spying is a useful tool for your testing practice.\n\n    If you're new to RSpec and looking for ways to improve your testing practice, understand the library better or just ask some questions, this session will be great for you.\n  video_provider: \"youtube\"\n  video_id: \"kiHdUU73D14\"\n\n- id: \"abraham-sangha-rubyconf-2014\"\n  title: \"TDD For Your Soul: Virtue and Software Engineering\"\n  raw_title: \"RubyConf 2014 - TDD For Your Soul: Virtue and Software Engineering\"\n  speakers:\n    - Abraham Sangha\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    By, Abraham Sangha\n    Software engineering pushes us to our limits, not only of cognition, but, perhaps surprisingly, of character. Using the cardinal virtues as a framework, we can see that developers need courage to learn, temperance to prioritize goals, a sense of justice by which to discern, and wisdom to act. By being honest about where we lack virtue, and implementing steps to develop character, we can perform TDD on ourselves. This process can help us grow not only as coders, but as human beings.\n  video_provider: \"youtube\"\n  video_id: \"VxLkhCx2I1Q\"\n\n- id: \"eric-west-rubyconf-2014\"\n  title: \"Rsense Knows Your Code\"\n  raw_title: \"RubyConf 2014 - Rsense Knows Your Code by Eric West\"\n  speakers:\n    - Eric West\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-22\"\n  published_at: \"2014-12-22\"\n  description: |-\n    Rsense brings the kind of static analysis tooling to Ruby that programmers in other languages take for granted. The kind of tooling I kept hearing was impossible to implement for Ruby. Accurate type inference, code completion, definition finding, and eventually so much more. How about a real refactoring tool, or the ability to find whole classes of bugs without executing the code? This is where Rsense is headed.\n\n    Learn how Rsense does its magic, find out how you can use it to improve your daily coding experience, where it's going next and where you can pitch in to make rsense even better.\n  video_provider: \"youtube\"\n  video_id: \"HMcEEBR0yJY\"\n\n- id: \"aja-hammerly-rubyconf-2014\"\n  title: \"A World Without Assignment\"\n  raw_title: \"RubyConf 2014 - A World Without Assignment\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-23\"\n  published_at: \"2014-12-23\"\n  description: |-\n    By, Aja Hammerly\n    In Ruby, assignment is our primary tool. By contrast, functional programming makes much less use of assignment and mutation. Instead techniques like function composition, recursion, and anonymous functions are used.\n\n    Despite being OO, Ruby accommodates pure functional approaches. This talk will demonstrate how tasks can be accomplished without assignment. Ruby and Scheme will be used for examples. I'll also discuss some of the great resources available for those interested in digging deeper into functional programming.\n  video_provider: \"youtube\"\n  video_id: \"-7RR27bR0_E\"\n\n- id: \"dinshaw-gobhai-rubyconf-2014\"\n  title: \"Promises in Ruby\"\n  raw_title: \"RubyConf 2014 - Promises in Ruby\"\n  speakers:\n    - Dinshaw Gobhai\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-23\"\n  published_at: \"2014-12-23\"\n  description: |-\n    By, Dinshaw Gobhai\n    Sequential workflows are easy to write (top down), but hard to write well. State machine workflows start to feel hacky, when complex; presenter patterns can be very heavy. Promises are a beautiful way to define and execute progressive routines while allowing access to independent steps for things like logging, exception handling, and picking up where you left off.\n  video_provider: \"youtube\"\n  video_id: \"hDd6DCDoOs8\"\n\n- id: \"richard-bishop-rubyconf-2014\"\n  title: \"Letting Concurrency Help You Today\"\n  raw_title: \"RubyConf 2014 - Letting Concurrency Help You Today\"\n  speakers:\n    - Richard Bishop\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-23\"\n  published_at: \"2014-12-23\"\n  description: |-\n    By, Richard Bishop\n    Ruby has never been renowned for its performance. We choose to love Ruby for its more admirable traits, like simplicity and expressiveness. But it turns out that we can have the best of both worlds by kicking the single-threaded model to the curb and using tried and true concurrency abstractions.\n\n    We will take a look at the building blocks Ruby offers for concurrency and how Rubyists have used these to build scalable, performant libraries just dying to be used. You’ll walk away with an understanding of concurrency and how you can leverage it in your applications today.\n  video_provider: \"youtube\"\n  video_id: \"F7dC3vTpE6I\"\n\n- id: \"kouji-takao-rubyconf-2014\"\n  title: \"Kids, Ruby, Fun!:  Introduction of the Smalruby and the Ruby Programming Shounendan\"\n  raw_title: \"RubyConf 2014 - Kids, Ruby, Fun!:... by Kouji Takao\"\n  speakers:\n    - Kouji Takao\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-23\"\n  published_at: \"2014-12-23\"\n  description: |-\n    Kids, Ruby, Fun!:  Introduction of the Smalruby and the Ruby Programming Shounendan by Kouji Takao\n\n    We will explain the introduction of the Smalruby and the Ruby Programming Shounendan, For more information about the implementation of the smalruby-editor of the Ruby programming visual editor.\n  video_provider: \"youtube\"\n  video_id: \"c2P_8QURz1g\"\n\n- id: \"shota-fukumori-rubyconf-2014\"\n  title: \"Scalable Deployments - How we Deploy Rails app to 100+ Hosts in a Minute\"\n  raw_title: \"RubyConf 2014 - Scalable Deployments... by Shota Fukumori\"\n  speakers:\n    - Shota Fukumori\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-23\"\n  published_at: \"2014-12-23\"\n  description: |-\n    Scalable Deployments - How we Deploy Rails app to 100+ Hosts in a Minute by Shota Fukumori\n\n    If you're developing webapps, I guess you deploy sometime using tools like Capistrano. We think existing tools slow for huge apps and a lot of servers.\n\n    We serves cookpad.com, which is a huge Rails app, and the largest recipe site in Japan. It's backed 120+ app servers. We've used Capistrano + SSH + rsync, but it became a bottleneck, slower and slower, as well as server increases. Our developer have wanted to focus on development. Deployments should be done in short time.\n\n    In this talk I'll introduce about our new deploy tool Mamiya, and will talk about how we deploy webapp in a minute.\n  video_provider: \"youtube\"\n  video_id: \"Pta7Lr-eskc\"\n\n- id: \"brendon-mclean-rubyconf-2014\"\n  title: \"Harnessing Other Languages To Make Ruby Better\"\n  raw_title: \"RubyConf 2014 - Harnessing other languages to make Ruby better\"\n  speakers:\n    - Brendon McLean\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-23\"\n  published_at: \"2014-12-23\"\n  description: |-\n    By, Brendon McLean\n    What do you do when your Ruby startup takes off and you realise that Ruby might not be best suited for everything? This talk covers our initial attempts to use Ruby as a data analytics platform, and how we ultimately ended up solving the problem using ideas from LISP and ActiveRecord scopes to bring the power and performance of data science languages to Ruby. We will also cover how Ruby can learn from other languages, and why Ruby is still our language of choice.\n  video_provider: \"youtube\"\n  video_id: \"-wYAcuWQ0YQ\"\n\n- id: \"johnnyt-rubyconf-2014\"\n  title: \"Ruby Changed My Life\"\n  raw_title: \"RubyConf 2014 - Ruby Changed My Life\"\n  speakers:\n    - JohnnyT\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-23\"\n  published_at: \"2014-12-23\"\n  description: |-\n    By, JohnnyT\n    When I found Ruby several years ago, I had no idea how\n    strong an influence it would be in my life.\n\n    It made my life happier and I was eager to share this new found happiness with other developers.\n\n    Then by the way of MagLev - I found the magical world of Smalltalk - and my joy was complete.\n\n    Come hear about this journey, how Ruby.is_a? Smalltalk and appreciate the following quote on another level:\n\n    I always knew that one day Smalltalk would replace Java. I just didn't know it would be called Ruby. -- Kent Beck\n  video_provider: \"youtube\"\n  video_id: \"SQUJ3PiY4h8\"\n\n- id: \"benjamin-tan-wei-hao-rubyconf-2014\"\n  title: \"Rubyists, have a sip of Elixir!\"\n  raw_title: \"RubyConf 2014 - Rubyists, have a sip of Elixir!\"\n  speakers:\n    - Benjamin Tan Wei Hao\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-23\"\n  published_at: \"2014-12-23\"\n  description: |-\n    By, Benjamin Tan Wei Hao\n\n    This talk is about Elixir – a functional, meta-programming aware language built on top of the Erlang VM.\n\n    I introduce some of Elixir's more interesting language features. Then I will demonstrate some of the features that Erlang gives Elixir for free, such as the OTP framework, that let's you build fault tolerant and distributed systems.\n\n    So come along and join me to experience programming joy.\n  video_provider: \"youtube\"\n  video_id: \"0Ui-Vy2wYwo\"\n\n- id: \"jess-szmajda-rubyconf-2014\"\n  title: \"Learning from FP: Simulated Annealing in Haskell and Ruby\"\n  raw_title: \"RubyConf 2014 - Learning from FP: Simulated Annealing in Haskell and Ruby\"\n  speakers:\n    - Jess Szmajda\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-23\"\n  published_at: \"2014-12-23\"\n  description: |-\n    By, Jess Szmajda\n\n    Haskell is a functional programming language that cleanly separates pure algorithms from messy real-world concerns. To learn how it ticks, I've translated an algorithm for Simulated Annealing from Haskell to Ruby. It also gave me an excuse to play with ruby-processing, a toolkit for graphics processing ;). Come learn about Functional Programming and how it can make your Ruby better!\n  video_provider: \"youtube\"\n  video_id: \"GjyE3tKscSw\"\n\n- id: \"joo-moura-rubyconf-2014\"\n  title: \"Stress Testing as a Culture\"\n  raw_title: \"RubyConf 2014 - Stress Testing as a Culture\"\n  speakers:\n    - João Moura\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-23\"\n  published_at: \"2014-12-23\"\n  description: |-\n    By, João Moura\n\n    If you are working on a serious project, you want it to scale. The thing about scale is, you only focus on it once you really need it. I’m the CTO of an soccer social network based in Brazil. To put it mildly, soccer is big in my country. This summer, we focused our marketing on the World Cup, preparing our application to support as many users as possible. To do that, we had to benchmark and improve, but how could we load test? What tool should we use? Those are just some questions that I'll go through in this talk, that will show youhot to address this challenge so stress test you app.\n  video_provider: \"youtube\"\n  video_id: \"b7jqwVxdtcY\"\n\n- id: \"alexander-dymo-rubyconf-2014\"\n  title: \"Ruby Performance Secrets and How to Uncover Them\"\n  raw_title: \"RubyConf 2014 - Ruby Performance Secrets and How to Uncover Them\"\n  speakers:\n    - Alexander Dymo\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-24\"\n  published_at: \"2014-12-24\"\n  description: |-\n    By, Alexander Dymo\n\n    Did you know that inject  and especially all?  iterator nested in another loop can really slow you down? Or that bigdecimal and string comparison is unbelievably slow in Ruby  2.0? Or that parsed CSV is 13x larger in memory than on disk? Want to know these and other performance hints with in-depth explanations? Want to learn how to use profilers to find what's slow by yourself? Then this session is for you.\n  video_provider: \"youtube\"\n  video_id: \"lAI_uYQwh4s\"\n\n- id: \"davy-stevenson-rubyconf-2014\"\n  title: \"Benchmarking Ruby\"\n  raw_title: \"RubyConf 2014 - Benchmarking Ruby\"\n  speakers:\n    - Davy Stevenson\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-24\"\n  published_at: \"2014-12-24\"\n  description: |-\n    By, Davy Stevenson\n\n    Testing is firmly ingrained in our culture, and many of us rely on a network of services to test, evaluate and profile our code. But what about benchmarking?\n\n    Learn tips and tricks about how to approach benchmarking and the variety of gems that are available. Learn about tools to help determine algorithmic complexity of your code, as well as how this information can help you make development choices. Learn how to properly set up your benchmarking experiments to ensure that the results you receive are accurate. More importantly, discover that benchmarking can be both fun and easy.\n  video_provider: \"youtube\"\n  video_id: \"XlEZB3oilME\"\n\n- id: \"aaron-quint-rubyconf-2014\"\n  title: \"Real World Ruby Performance at Scale\"\n  raw_title: \"RubyConf 2014 - Real World Ruby Performance at Scale\"\n  speakers:\n    - Aaron Quint\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-24\"\n  published_at: \"2014-12-24\"\n  description: |-\n    By, Aaron Quint\n\n    Large scale and fast production Ruby applications are not a myth. As we've continued to scale out our infrastructure and our application, we've been able to keep things fast and reliable. We do this by building and using tools that take advantage the great improvements that have come in Ruby 2. I'd like to share some of the lessons we've learned in scaling our app as well as show off the latest and greatest in open source performance tooling.\n  video_provider: \"youtube\"\n  video_id: \"qlS3yr1oncQ\"\n\n- id: \"john-cinnamond-rubyconf-2014\"\n  title: \"Strong Duck Type Driven Development\"\n  raw_title: \"RubyConf 2014 - Strong Duck Type Driven Development\"\n  speakers:\n    - John Cinnamond\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-24\"\n  published_at: \"2014-12-24\"\n  description: |-\n    By, John Cinnamond\n\n    As a language, Ruby plays fast and loose with the type system. Developers rely on duck typing to check that the things they want to do with an object are permissible. Whilst this freedom makes writing code frictionless and often a whole lot of fun, it doesn't always scale up well to writing larger systems.\n\n    I can't promise that strong duck typing - adding automated checking to inter-object interfaces - will make writing complex systems easy but it will help you think about how to structure code in new ways and bring some of the lessons learned from other languages to the Ruby community.\n  video_provider: \"youtube\"\n  video_id: \"rMbx5FrqY4U\"\n\n- id: \"chris-seaton-rubyconf-2014\"\n  title: \"Deoptimizing Ruby\"\n  raw_title: \"RubyConf 2014 - Deoptimizing Ruby\"\n  speakers:\n    - Chris Seaton\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-26\"\n  published_at: \"2014-12-26\"\n  description: |-\n    By, Chris Seaton\n\n    Ruby is notoriously difficult to optimize, but there is a solution: deoptimization. This means jumping from compiled code back to an interpreter, and it allows Ruby implementations to take shortcuts, make guesses and pretend Ruby is simpler than it is, but at the same time still be ready to handle the full language if it’s needed.\n\n    You’ve seen talks about what makes Ruby slow: monkey patching, bindings, set_trace_func, object space & so on. We’ll show how with a Ruby implementation using deoptimization, such as JRuby+Truffle, you can use these features without any runtime overhead at all.\n  video_provider: \"youtube\"\n  video_id: \"z-YVygbDHLE\"\n\n- id: \"craig-buchek-rubyconf-2014\"\n  title: \"Ruby Idioms You're Not Using Yet\"\n  raw_title: \"RubyConf 2014 - Ruby Idioms You're Not Using Yet\"\n  speakers:\n    - Craig Buchek\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-26\"\n  published_at: \"2014-12-26\"\n  description: |-\n    By, Craig Buchek\n\n    Idioms are some of the smallest patterns that we use in our programming languages. Learning the idioms of a language helps you more quickly understand commonly used patterns. Over time, some idioms fall out of favor, and new idioms are developed and adopted.\n\n    In this talk, we'll explore a few idioms that are relatively new to the Ruby community. These include:\n\n    Module factory\n    Tag module\n    Circuit breaker\n    Fetch with default block\n  video_provider: \"youtube\"\n  video_id: \"hc_wtllfKtQ\"\n\n- id: \"betsy-haibel-rubyconf-2014\"\n  title: \"Your Bright Metaprogramming Future: Mistakes You'll Make (and How to Fix Them)\"\n  raw_title: \"RubyConf 2014 - Your Bright Metaprogramming Future: Mistakes You'll Make (and How to Fix Them)\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-26\"\n  published_at: \"2014-12-26\"\n  description: |-\n    By, Betsy Haibel\n\n    Ruby's full of nice little metaprogramming tricks. Learning a new one's always the same cycle: 1. scared & tentative; 2. drunk on power; 3. woefully repentant; 4. mature & reasonable. Using my own history (of poor choices), I'll take you through stages 1-4 for: mazes of twisty little send calls, all alike! replacing def with method_missing! hook method indirection \"magic!\" Ill-timed define_methods! Sure, you could skip to the end - stage 4 is mostly \"obey SRP; extract service objects\" and \"anonymous module inclusion's your BFF\" - but getting there is half the point and all the fun.\n  video_provider: \"youtube\"\n  video_id: \"7rN6ehNrtfc\"\n\n- id: \"kerri-miller-rubyconf-2014\"\n  title: \"5 Things I Wish Someone Had Told Me About Programming Before I Started\"\n  raw_title: \"RubyConf 2014 - 5 Things I Wish Someone Had Told Me About Programming Before I Started\"\n  speakers:\n    - Kerri Miller\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-29\"\n  published_at: \"2014-12-29\"\n  description: |-\n    By, Kerri Miller\n    There's more to being a successful developer than simply being great at programming. The gotchas that slow us down or trip us up are often outside of the code we write, manifesting instead in our process or how we work with our peers. Whether you're new to programming or a veteran of many projects, these 5 things can improve your code, your career, and your team, and is a refresher course on what goes into the day-to-day, reminding us to have some empathy for individuals new to our community.\n  video_provider: \"youtube\"\n  video_id: \"bZOnbBJW3a8\"\n\n- id: \"kinsey-ann-durham-rubyconf-2014\"\n  title: \"Switch Up: How to Switch Careers to Become a Ruby Engineer\"\n  raw_title: \"RubyConf 2014 - Switch Up: How to Switch Careers to Become a Ruby Engineer\"\n  speakers:\n    - Kinsey Ann Durham\n  event_name: \"RubyConf 2014\"\n  date: \"2014-12-30\"\n  published_at: \"2014-12-30\"\n  description: |-\n    By, Kinsey Ann Durham\n  video_provider: \"youtube\"\n  video_id: \"nRm-qlxq3Rw\"\n\n- id: \"oliver-lacan-rubyconf-2014\"\n  title: \"Polishing Ruby\"\n  raw_title: \"RubyConf 2014 - Polishing Ruby by Oliver Lacan\"\n  speakers:\n    - Oliver Lacan\n  event_name: \"RubyConf 2014\"\n  date: \"2015-03-23\"\n  published_at: \"2015-03-23\"\n  description: |-\n    There are gems out there solving very common problems that could easily be contributed back to Ruby itself. Suggesting a new Ruby feature isn't as daunting as it sounds. As long as you're diligent, you too can push ruby forward.\n  video_provider: \"youtube\"\n  video_id: \"iCRAalcAxQ0\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2015/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYqT3LHMg4iH270kfyENCpp\"\ntitle: \"RubyConf 2015\"\nkind: \"conference\"\nlocation: \"San Antonio, TX, United States\"\ndescription: \"\"\npublished_at: \"2015-11-20\"\nstart_date: \"2015-11-15\"\nend_date: \"2015-11-17\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2015\nbanner_background: \"#BE2428\"\nfeatured_background: \"#BE2428\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 29.4251905\n  longitude: -98.4945922\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2015/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n\n# Website: https://web.archive.org/web/20150924165354/http://rubyconf.org/\n# Schedule: https://web.archive.org/web/20151227062245/http://rubyconf.org/schedule\n\n- id: \"adam-cuppy-rubyconf-2015\"\n  title: \"Pluck It\"\n  raw_title: \"RubyConf 2015 - Pluck It by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    Pluck It by Adam Cuppy\n\n    How many times have you written the same bits of code, over and over, and thought, “You know, if only this was big enough to be a gem, I would pluck it out.\" Often, we think of a RubyGem as a larger library of code that we “bolt on” to an app. And, these smaller code blobs become a hassle to distribute to the multiple apps that use them.\n\n    A small micro-library, done the right way, at the right time, can greatly improve an app.\n\n    But, when can you benefit from extracting a micro-library? And, how do you build and publish that code into a RubyGem? I'll go through the process, from A to Z.\n  video_provider: \"youtube\"\n  video_id: \"r5l0CaxqSvA\"\n\n- id: \"jeff-norris-rubyconf-2015\"\n  title: \"Keynote: Leagues of Sea and Sky\"\n  raw_title: \"RubyConf 2015 - Keynote: Leagues of Sea and Sky by Jeff Norris\"\n  speakers:\n    - Jeff Norris\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    Keynote: Leagues of Sea and Sky by Jeff Norris\n\n    In this keynote, Jeff tells three stories of inventions for nautical and aeronautical exploration to reveal how partnership has shaped the greatest journeys in history and how it should shape your own. From the sextant to holographic mixed reality, Jeff shares meticulously researched history along with some of the projects he's led in space exploration via a unique medium that he created just for this presentation.\n  video_provider: \"youtube\"\n  video_id: \"BZg75PlmzXI\"\n\n- id: \"laura-eck-rubyconf-2015\"\n  title: \"The Not So Rational Programmer\"\n  raw_title: \"RubyConf 2015 - The Not So Rational Programmer by Laura Eck\"\n  speakers:\n    - Laura Eck\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    The Not So Rational Programmer by Laura Eck\n\n    Cognitive biases are heuristics that the brain uses to process information and quickly come up with decisions. They are generally pretty useful, but they aren’t perfect processes and can often lead to suboptimal decisions or behaviors.\n\n    This talk will help you to recognize their patterns in your thinking and behavior and (since we unfortunately can’t quite de-bug our own brains yet) to monkey-patch them - in order to become a more efficient, more cooperative and ultimately more successful developer.\n  video_provider: \"youtube\"\n  video_id: \"E-5VhMUYmVY\"\n\n- id: \"aaron-patterson-rubyconf-2015\"\n  title: \"Inside Ruby's VM: The TMI Edition.\"\n  raw_title: \"RubyConf 2015 - Inside Ruby's VM: The TMI Edition. by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    Inside Ruby's VM: The TMI Edition. by Aaron Patterson\n\n    This is about Ruby's Virtual Machine. Specifically MRI's Virtual Machine. We will take a dive in to how your Ruby code is compiled in to byte code and how that byte code is executed. Once we get a grip on how the VM works, we'll see how to make it perform tricks the likes of which you've never seen! Ok, maybe you have seen them, just not with MRI's virtual machine.\n  video_provider: \"youtube\"\n  video_id: \"CT8JSJkymZM\"\n\n- id: \"justin-searls-rubyconf-2015\"\n  title: \"How To Stop Hating Your Test Suite\"\n  raw_title: \"RubyConf 2015 - How to Stop Hating your Test Suite by Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    How to Stop Hating your Test Suite by Justin Searls\n\n    Your app is a unique snowflake. Your tests are too… but they shouldn't be!\n\n    Years helping teams write better tests has taught me one thing: consistency is crucial. Inconsistent tests slow teams down, wasting time to understand how each test works. Deciding on conventions—even arbitrary ones—can prevent tremendous pain later.\n\n    This talk will introduce a ready-to-fork Test Style Guide of carefully-considered rules and templates for Rubyists. You can customize it to fit your preferred tools, too. Soon, you'll be on your way to having more consistent tests that are much more fun to maintain!\n  video_provider: \"youtube\"\n  video_id: \"VD51AkG8EZw\"\n\n- id: \"nate-berkopec-rubyconf-2015\"\n  title: \"A Guided Read of Minitest\"\n  raw_title: \"RubyConf 2015 -  A Guided Read of Minitest by Nate Berkopec\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    A Guided Read of Minitest by Nate Berkopec\n\n    Minitest is a testing library of just 1,500 lines of Ruby code. By comparison, Rspec clocks in at nearly 15,000! Why is Minitest so small? I'd like to investigate by doing a guided read of Minitest's source code.\n  video_provider: \"youtube\"\n  video_id: \"ojd1G4gOMdk\"\n\n- id: \"andy-croll-rubyconf-2015\"\n  title: \"Your own 'Images as a Service'\"\n  raw_title: \"RubyConf 2015 - Your own 'Images as a Service' by Andy Croll\"\n  speakers:\n    - Andy Croll\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    Your own 'Images as a Service'\n\n    The average web page size is greater than 2MB, and increasing. And great swathes of that are images. Serving the right size of image can vastly improve the experience for your users. But while we're arguing about whether Rails is slow or not we're chucking vast images at peoples phones over EDGE connections.\n\n    Serving images should be a 'solved' problem, just like it is for 'hosting' or authentication. However lots of solutions make poor default suggestions. What can we do for our users with 100 lines of code, Sinatra, a single gem and a CDN?\n  video_provider: \"youtube\"\n  video_id: \"zhW1E6_YpC4\"\n\n- id: \"craig-buchek-rubyconf-2015\"\n  title: \"Ruby Preserves\"\n  raw_title: \"RubyConf 2015 - Ruby Preserves by Craig Buchek\"\n  speakers:\n    - Craig Buchek\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    Ruby Preserves by Craig Buchek\n\n    How simple can we make an Object-Relational Mapper (ORM) that's still useful? What if we just used SQL, instead of trying to hide it from developers?\n\n    I decided to find out.\n\n    In this presentation, we'll explore a simple ORM that uses the Repository and Data Mapper patterns. We'll also see how using these patterns enables us to write simpler model code.\n  video_provider: \"youtube\"\n  video_id: \"MZVSK4cjeF4\"\n\n- id: \"thomas-e-enebo-rubyconf-2015\"\n  title: \"JRuby 9000 Is Out; Now What?\"\n  raw_title: \"RubyConf 2015 -  JRuby 9000 Is Out; Now What? by Thomas Enebo and Charles Nutter\"\n  speakers:\n    - Thomas E Enebo\n    - Charles Nutter\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    JRuby 9000 Is Out; Now What? by  Thomas Enebo and Charles Nutter\n\n    JRuby 9000 is here! After years of work, JRuby now supports Ruby 2.2 and ships with a redesigned optimizing runtime. The first update release improved performance and compatibility, and we've only just begun. In this talk we'll show you where we stand today and cover upcoming work that will keep JRuby moving forward: profiling, inlining, unboxing...oh my!\n  video_provider: \"youtube\"\n  video_id: \"KifjmbSHHs0\"\n\n- id: \"nikki-murray-rubyconf-2015\"\n  title: \"Making it on your own and the pitfalls of gem dependencies\"\n  raw_title: \"RubyConf 2015 - Making it on your own... by Nikki Murray and Maggie Epps\"\n  speakers:\n    - Nikki Murray\n    - Maggie Epps\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    Making it on your own and the pitfalls of gem dependencies by Nikki Murray and Maggie Epps\n\n    Putting \"require '[gem name]'\" at the top of your Ruby file and running 'gem install' or 'bundle install' can be an easy way to solve a difficult problem. But you could be potentially adding hundreds of lines of code you didn't write or read, for only half a of a fix. Did the gem actually solve your problem or is it just an approximate solution? How much research did you do on that gem first? Are there hidden security risks in it? In this talk, you will learn how to evaluate gems for fit, figure out when it makes more sense to write your own, and how to go about writing your own.\n  video_provider: \"youtube\"\n  video_id: \"sjFqWUq6CjQ\"\n\n- id: \"sean-marcia-rubyconf-2015\"\n  title: \"Ruby in 79 AD (Open Sourcing my Role as Indiana Jones)\"\n  raw_title: \"RubyConf 2015 - Ruby in 79 AD (Open Sourcing my Role as Indiana Jones) by Sean Marcia\"\n  speakers:\n    - Sean Marcia\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    Ruby in 79 AD (Open Sourcing my Role as Indiana Jones) by sean Marcia\n\n    I'll demonstrate a practical guide on how you can get involved with neat projects by partnering with academics to build open source tools. We all have the ability to be Indiana Jones and I'll show you how through my experience. Come learn the unforeseen benefits of contributing to open source. My contributions to open source garnered the attention of an archaeological team doing research in Pompeii. Before I knew it I had been granted archaeologist credentials and was on my way to Italy as part of the research team collecting data in Pompeii.\n  video_provider: \"youtube\"\n  video_id: \"QaR3Wcms4HM\"\n\n- id: \"michel-martens-rubyconf-2015\"\n  title: \"Mind Over Error\"\n  raw_title: \"RubyConf 2015 - Mind Over Error by Michel Martens\"\n  speakers:\n    - Michel Martens\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    Mind Over Error by Michel Martens\n\n    Industries like aviation and power plants have improved their safety mechanisms using our growing understanding of the nature of human error, but have we kept up? How do we incorporate the ideas from Human Error, The Design of Everyday Things, and other great resources into what we build? I want to show you how to improve the safety of our systems by reducing their complexity and generating accurate mental models.\n  video_provider: \"youtube\"\n  video_id: \"_ztlV76b2Gg\"\n\n- id: \"nickolas-means-rubyconf-2015\"\n  title: \"How to Crash an Airplane\"\n  raw_title: \"RubyConf 2015 - How to Crash an Airplane by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    How to Crash an Airplane\n\n    On July 19, 1989, United Airlines Flight 232 was en route to Chicago when a mechanical failure caused the plane to become all but uncontrollable. In this unsurvivable situation, the flight crew saved more than half of those onboard. How did they do it?\n\n    Flight crews and software teams actually have a lot in common, and there's much we can learn from how the best crews do their jobs. What can we learn from the story of United 232? While this talk won't earn you your pilot's license, you'll definitely come away with some fresh ideas on how to make your team even more amazing.\n  video_provider: \"youtube\"\n  video_id: \"S2FUSr3WlPk\"\n\n- id: \"sonja-heinen-rubyconf-2015\"\n  title: \"RuntimeError: can't save WORLD\"\n  raw_title: \"RubyConf 2015 - RuntimeError: can't save WORLD by Sonja Heinen\"\n  speakers:\n    - Sonja Heinen\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    RuntimeError: can't save WORLD\n\n    Rumor has it that software engineers hold the power to build the things of our future. Now, the world is filling up with technologies and devices – who knows what all of them are for? With power comes responsibility, or in this case the chance to build and write better things.\n\n    Here is where strategies and concepts from the social design practice apply. They offer ideas for a holistic approach to programming, while yielding the prospect to establish a connection with your work that goes beyond the purely technical side of things.\n  video_provider: \"youtube\"\n  video_id: \"H2aKUfiFlFc\"\n\n- id: \"amar-shah-rubyconf-2015\"\n  title: \"Working Compassionately with Legacy Code\"\n  raw_title: \"RubyConf 2015 - Working Compassionately with Legacy Code by Amar Shah\"\n  speakers:\n    - Amar Shah\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-20\"\n  published_at: \"2015-11-20\"\n  description: |-\n    Working Compassionately with Legacy Code by Amar Shah\n\n    Your code is your partner. It struggles against you, but also alongside you. Your code comes to you as it is, not as you wish it were. Like a real-life partner, it has a history that you’ll never fully know; like a real-life child, it bears your imprint, but it is wild, unruly, and fiercely self-sovereign. You’ll never stop working with code that’s hard to figure out or difficult to change. But this code, this stubborn creature, is entrusted to you. Let go of your anger at the developer who wrote it. Let go of the terror of being blamed for its unforeseeable regressions. Let go--and find joy.\n  video_provider: \"youtube\"\n  video_id: \"JC4mS7sYQlU\"\n\n- id: \"andr-arko-rubyconf-2015\"\n  title: \"How does Bundler work, anyway?\"\n  raw_title: \"RubyConf 2015 - How does Bundler work, anyway? by Andre Arko\"\n  speakers:\n    - André Arko\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    How does Bundler work, anyway? by Andre Arko\n\n    We all use Bundler at some point, and most of us use it every day. But what does it do, exactly? Why do we have to use bundle exec? What's the point of checking in the Gemfile.lock? Why can't we just gem install the gems we need? Join me for a walk through the reasons that Bundler exists, and a guide to what actually happens when you use it. Finally, we'll cover some Bundler \"pro tips\" that can improve your workflow when developing on multiple applications at once.\n  video_provider: \"youtube\"\n  video_id: \"4DqzaqeeMgY\"\n\n- id: \"akira-matsuda-rubyconf-2015\"\n  title: \"Ruby 2 Methodology\"\n  raw_title: \"RubyConf 2015 - Ruby 2 Methodology by Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Ruby 2 Methodology by Akira Matsuda\n\n    This talk focuses on \"Method\" in Ruby.\n\n    Although Method is the key feature of an OOP language like Ruby, Ruby's Method is still drastically evolving. This session is a quick tour on new features and changes around Method in recent versions of the Ruby language. Not just introducing the APIs, we'll also show you lots of interesting stories behind these features, and real-world code examples. Through this session, you'll probably learn some modern methods of Ruby programming that you did never know.\n  video_provider: \"youtube\"\n  video_id: \"UhMnFy3vNAU\"\n\n- id: \"yurie-yamane-rubyconf-2015\"\n  title: \"Domo Arigato mruby Roboto\"\n  raw_title: \"RubyConf 2015 - Domo Arigato mruby Roboto by Yurie Yamane and Maysayoshi Takahashi\"\n  speakers:\n    - Yurie Yamane\n    - Maysayoshi Takahashi\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Domo Arigato mruby Roboto by Yurie Yamane and Maysayoshi Takahashi\n\n    Let's make a self-balancing robot with mruby!\n\n    We show inverted pendulum robots using mruby. Inverted pendulum robot is two-wheeled, self-balancing robot like Segway. A self-balancing robot usually uses C or C++ because of real time responsibility, but we try to use mruby. We show you two robots, LEGO Mindstorms EV3 version and Raspberry Pi DIY version, and describe how to make them.\n  video_provider: \"youtube\"\n  video_id: \"7qWZ5w5v7Eg\"\n\n- id: \"aja-hammerly-rubyconf-2015\"\n  title: \"Keynote: Stupid Ideas for Many Computers\"\n  raw_title: \"RubyConf 2015 - Keynote: Stupid Ideas for Many Computers by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  slides_url: \"https://thagomizer.com/files/rubyconf_15.pdf\"\n  description: |-\n    Keynote: Stupid Ideas for Many Computers by Aja Hammerly\n\n    There are plenty of useful things you can do with Ruby and a bunch of servers. This talk isn't about useful things. This talk will show off asinine, amusing, and useless things you can do with Ruby and access to cloud computing.\n\n    Sentiment analysis based on emoji? Why not? Hacky performance testing frameworks? Definitely! Multiplayer infinite battleship? Maybe? The world's most inefficient logic puzzle solver? Awesome!\n\n    If you are interested in having some fun and laughing at reasonable code for unreasonable problems this talk is for you.\n  video_provider: \"youtube\"\n  video_id: \"_O1MGHcsQCI\"\n\n- id: \"amanda-quaranto-rubyconf-2015\"\n  title: \"Nobody Expects an Inquisition! - A Programmer's Guide to Asking Questions\"\n  raw_title: \"RubyConf 2015 - Nobody Expects an Inquisition!... by Amanda Quaranto\"\n  speakers:\n    - Amanda Quaranto\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Nobody Expects an Inquisition! - A Programmer’s Guide to Asking Questions by Amanda Quaranto\n\n    What was the last question you asked someone? Did you actually care what the answer was? Did it improve the conversation? Did it start an interesting discussion? Did it start an argument?\n\n    Like many programmers, I’ve relied on deductive reasoning to avoid asking questions - fearing that someone would find out I didn't belong. At the start of this year, I made the decision to change all that. This talk will evaluate tools which improved my professional and personal life.\n\n    Let’s learn how to rely less on being intuitive and more on being inquisitive.\n  video_provider: \"youtube\"\n  video_id: \"2h1EocEyiSo\"\n\n- id: \"ian-duggan-rubyconf-2015\"\n  title: \"Stately State Machines with Ragel\"\n  raw_title: \"RubyConf 2015 - Stately State Machines with Ragel by Ian Duggan\"\n  speakers:\n    - Ian Duggan\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Stately State Machines with Ragel by Ian Duggan\n\n    State machines are an important tool in computer programming, and Ragel is a wonderful tool for creating them. Come learn how to use Ragel to compose simple state machines into much more complicated versions useful for parsing and processing all manner of input. We'll progress simple regex-like machines to full-blown context-sensitive scanners capable of ripping-fast processing of protocols and language grammars.\n  video_provider: \"youtube\"\n  video_id: \"Tr83XxNRg3k\"\n\n- id: \"josh-freeman-rubyconf-2015\"\n  title: \"Communicating Intent Through Git\"\n  raw_title: \"RubyConf 2015 - Communicating Intent Through Git by Josh Freeman\"\n  speakers:\n    - Josh Freeman\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Communicating Intent Through Git by Josh Freeman\n\n    Git is a distributed version control system for our source code. It provides the technical mechanism to answer the who, what, when, and where of every decision made. However, Git never requires us to answer why.\n\n    Software is the result of thousands of decisions. Add this feature; clarify this method; change this behavior. Every team should be able to know why a decision was made.\n\n    Creating software is a journey—let Git be your travel journal.\n  video_provider: \"youtube\"\n  video_id: \"vMOAcaA33Dk\"\n\n- id: \"petr-chalupa-rubyconf-2015\"\n  title: \"Writing concurrent libraries for all Ruby runtimes\"\n  raw_title: \"RubyConf 2015 - Writing concurrent libraries for all Ruby runtimes by Petr Chalupa\"\n  speakers:\n    - Petr Chalupa\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Writing concurrent libraries for all Ruby runtimes by Petr Chalupa\n\n    Have you ever wondered how to use all of your cores?\n\n    The talk will take you on a path of writing a simple concurrent class. We'll start with a basic implementation and gradually improve it based on presented problems and newly learned facts. Our final solution will behave well in the face of concurrency and execute consistently on all Ruby implementations.\n\n    We’ll investigate various Ruby runtime differences that we’ve abstracted away with the synchronization layer of the concurrent-ruby gem. We'll go down to JRuby extensions, even volatile fields and compare-and-swap operations.\n  video_provider: \"youtube\"\n  video_id: \"r5kwIm3Q6Y0\"\n\n- id: \"christopher-sexton-rubyconf-2015\"\n  title: \"Hardware Hacking: You Can Be A Maker\"\n  raw_title: \"RubyConf 2015 - Hardware Hacking: You can be a Maker by Christopher Sexton and Leah Sexton\"\n  speakers:\n    - Christopher Sexton\n    - Leah Sexton\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Hardware Hacking: You can be a Maker by Christopher Sexton and Leah Sexton\n\n    There is something fundamentally satisfying about building things that bridge the gap between your code and the physical world. This father/daughter duo will show you how they've bridge that gap.\n\n    I frequently find Rubyists that are interested in tinkering with hardware but are often intimidated by the idea. Turns out, it is so easy even a grown-up can do it. In fact it is easier than it has ever been. And the best part is, you can use little Ruby.\n  video_provider: \"youtube\"\n  video_id: \"8UrsjxJSPcY\"\n\n- id: \"darin-wilson-rubyconf-2015\"\n  title: \"Learn to Make Music. With Ruby.\"\n  raw_title: \"RubyConf 2015 - Learn to Make Music. With Ruby. by Darin Wilson\"\n  speakers:\n    - Darin Wilson\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Learn to Make Music. With Ruby. by Darin Wilson\n\n    If you can write code, you can make music. And in this talk, and you'll see exactly how.\n\n    We'll take a look at Sonic Pi, a powerful, multi-platform app that uses a Ruby DSL to create just about any kind of music you can think of.\n\n    And if you've never made a note of music in your life, fear not: you'll also get a crash course in music composition and learn how the elements of rhythm, melody, and harmony work together to make a cohesive whole.\n\n    Bring your laptop and headphones: this will be very hands-on, and you'll be making your first track before we even get to questions!\n  video_provider: \"youtube\"\n  video_id: \"exZTxhH06tw\"\n\n- id: \"federico-soria-rubyconf-2015\"\n  title: \"Mo Money Mo Problems (with Ruby)\"\n  raw_title: \"RubyConf 2015 - Mo Money Mo Problems (with Ruby) by Federico Soria\"\n  speakers:\n    - Federico Soria\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Mo Money Mo Problems (with Ruby) by Federico Soria\n\n    Are you thinking or starting to build an app that deals with money? Come to this talk to learn the best practices of handling money transactions. In my 2+ years working in a startup based on payments, I have been able to compile do's and don'ts of handling money.\n  video_provider: \"youtube\"\n  video_id: \"aQ0dz7eykvI\"\n\n- id: \"randy-coulman-rubyconf-2015\"\n  title: \"Shall We Play A Game?\"\n  raw_title: \"RubyConf 2015 - Shall We Play A Game? by Randy Coulman\"\n  speakers:\n    - Randy Coulman\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Shall We Play A Game? by Randy Coulman\n\n    Teaching computers to play games has been a pursuit and passion for many programmers. Game playing has led to many advances in computing over the years, and the best computerized game players have gained a lot of attention from the general public (think Deep Blue and Watson).\n\n    Using the Ricochet Robots board game as an example, let's talk about what's involved in teaching a computer to play games. Along the way, we'll touch on graph search techniques, data representation, algorithms, heuristics, pruning, and optimization.\n  video_provider: \"youtube\"\n  video_id: \"FXVj2kauFCM\"\n\n- id: \"jason-clark-rubyconf-2015\"\n  title: \"GDB: A Gentle Intro\"\n  raw_title: \"RubyConf 2015 - GDB: A Gentle Intro by Jason Clark\"\n  speakers:\n    - Jason Clark\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    GDB: A Gentle Intro by Jason Clark\n\n    We love Ruby’s elegance, simplicity, and flexibility. But our favorite language perches atop a world of native code. When that other world intrudes on your peaceful Ruby, GDB, the venerable GNU debugger, is the tool to turn to.\n\n    We’ll examine setting up Ruby to work with GDB. We’ll learn the fundamental commands, and soon you’ll be debugging with ease. We’ll even peer deep into Ruby object internals and face down crashes, deadlocks, and bugs.\n\n    Whether you’re writing a native gem, hacking the Ruby VM, or just want a glimpse of the layers below, this talk is for you!\n  video_provider: \"youtube\"\n  video_id: \"APNZmTEs9tc\"\n\n- id: \"micah-adams-rubyconf-2015\"\n  title: \"Not so Neo in the Matrix\"\n  raw_title: \"RubyConf 2015 - Not so Neo In the Matrix by Micah Adams\"\n  speakers:\n    - Micah Adams\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Not so Neo In the Matrix by Micah Adams\n\n    Matrices are powerful data structures that are used for all sorts of interesting problems- from 3d graphics, to image processing, and cryptography. However, the mighty matrix can be used to solve more mundane problems as well. This talk attempts to demystify the matrix and offer real life examples for using this powerful but understandable data structure.\n  video_provider: \"youtube\"\n  video_id: \"GCqd_BcOrsU\"\n\n- id: \"hsing-hui-hsu-rubyconf-2015\"\n  title: \"Time Flies Like An Arrow; Fruit Flies Like A Banana: Parsers for Great Good\"\n  raw_title: \"RubyConf 2015 - Time flies like an arrow; Fruit flies like a banana... by Hsing-Hui Hsu\"\n  speakers:\n    - Hsing-Hui Hsu\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Time flies like an arrow; Fruit flies like a banana: Parsers for Great Good by Hsing-Hui Hsu\n\n    When you type print \"Hello, world!\", how does your computer know what to do? Humans are able to naturally parse spoken language by analyzing the role and meaning of each word in context of its sentence, but we usually take for granted the way computers make sense of the code we write.\n\n    By exploring the way our brains construct grammars to parse sentences, we can better understand how parsers are used for computering -- whether it be in the way Ruby and other languages are implemented or in webserver routing -- and recognize when they may be the right tool to use in our own code.\n  video_provider: \"youtube\"\n  video_id: \"lCtzFWAPDP4\"\n\n- id: \"evan-phoenix-rubyconf-2015\"\n  title: \"Bikeshed! Live!\"\n  raw_title: \"RubyConf 2015 - Bikeshed! Live! by Evan Phoenix and Adam Keys\"\n  speakers:\n    - Evan Phoenix\n    - Adam Keys\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    Bikeshed! Live! by Evan Phoenix and Adam Keys\n\n    Everyone loves live coding! What's not to love about watching someone struggle through some trivial code while the audience corrects their every syntax error?\n\n    This session takes that to the next level by adding literal play-by-play commentary to a live coding session. Come and join us for what is sure to be a hilarious (and hopefully informational) trainwreck.\n  video_provider: \"youtube\"\n  video_id: \"sn7prRGGp4Q\"\n\n- id: \"eileen-m-uchitelle-rubyconf-2015\"\n  title: \"How to Performance\"\n  raw_title: \"RubyConf 2015 - How to Performance by Eileen Uchitelle\"\n  speakers:\n    - Eileen M Uchitelle\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-21\"\n  published_at: \"2015-11-21\"\n  description: |-\n    How to Performance by Eileen Uchitelle\n\n    Understanding performance output can feel like reading tea leaves. It makes sense to a few people, but many of us are left in the dark; overwhelmed and frustrated by the data. Additionally there are a ton of performance tools to choose from; StackProf, RubyProf, AllocationTracer. Where do you even start?\n\n    In this talk we will not only look at how to read performance output, but when and how to use the right profilers for the job. We'll discuss a variety of methods and techniques for benchmarking and profiling so you can get the most out of each performance tool.\n  video_provider: \"youtube\"\n  video_id: \"obyrJ_aJU6A\"\n\n- id: \"kinsey-ann-durham-rubyconf-2015\"\n  title: \"Code, Culture and the Pursuit of Happiness\"\n  raw_title: \"RubyConf 2015 - Code, Culture and the Pursuit of Happiness by Kinsey Ann Durham\"\n  speakers:\n    - Kinsey Ann Durham\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: |-\n    Code, Culture and the Pursuit of Happiness by Kinsey Ann Durham\n\n    Life’s good. People who never thought they could code are becoming developers. Outreach programs are getting people in, but we’re facing an even bigger problem. Getting them to stay there. 57% of women alone leave the tech industry. The root cause of people leaving, and not just people from underrepresented backgrounds, points to company culture. Let’s build company cultures the way we build products, applying scrum principles we use everyday. This talk dives into the reasons why people are leaving the industry in droves, and what unexpected, actionable steps we can take to solve this problem.\n  video_provider: \"youtube\"\n  video_id: \"O98rt9Z11LU\"\n\n- id: \"andrew-faraday-rubyconf-2015\"\n  title: \"Gameshow: Just a Ruby Minute\"\n  raw_title: \"RubyConf 2015 - Just a Ruby Minute by Andrew Faraday\"\n  speakers:\n    - Andrew Faraday\n    - Andy Croll\n    - Kinsey Ann Durham\n    - Aaron Patterson\n    - Sam Phippen\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: |-\n    We're bringing Just a Minute -- the popular British gameshow format -- to RubyConf! The rules of the game are simple, the results are hilarious, and who knows, you might even learn something new! Come join us to see some of your favorite Rubyists be utterly silly... for a minute at a time, at least.\n\n    Contestants: Aaron Patterson, Andy Croll, Kerri Miller, Sam Phippen\n  video_provider: \"youtube\"\n  video_id: \"V7N70mZ4NxI\"\n\n- id: \"john-cinnamond-rubyconf-2015\"\n  title: \"Softly, Softly Typing\"\n  raw_title: \"RubyConf 2015 - Softly, softly typing by John Cinnamond\"\n  speakers:\n    - John Cinnamond\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: |-\n    Softly, softly typing by John Cinnamond\n\n    The ruby community is large and varied but, for the most part, we haven't rushed to engage with type theory. Static typing - whatever that is - is for the slow moving world of Java developers. Type theory is for Haskell weirdos.\n\n    All that could be about to change.\n\n    In his keynote at Rubyconf 2014 Matz spoke about some ideas for Ruby 3, including the idea of adding static typing - or more specifically soft typing - to the language. So what is soft typing? How do we understand more about it? And what does it mean for us mere developers?\n  video_provider: \"youtube\"\n  video_id: \"XGLYHQ1BLfM\"\n\n- id: \"noel-rappin-rubyconf-2015\"\n  title: \"I Estimate this Talk will be 20 Minutes Long, Give or Take 10 Minutes\"\n  raw_title: \"RubyConf 2015 - I Estimate this Talk will be 20 Minutes Long, Give or Take 10 Minutes\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: |-\n    I Estimate this Talk will be 20 Minutes Long, Give or Take 10 Minutes by Noel Rappin\n\n    Estimates are like weather forecasts. Getting them right is hard, and everybody complains when you are wrong. Estimating projects is often critically important to the people who pay us to develop software.\n\n    We can do better. We can focus our estimates on the parts we do well, like estimating complexity. We can present estimates without falsely inflating them, and we can be transparent during the development process. The humble point estimate can help you, if you understand its limitations.\n\n    Better estimates and communication of estimates will make your projects run more smoothly.\n  video_provider: \"youtube\"\n  video_id: \"jBMwT53oGsM\"\n\n- id: \"adam-jonas-rubyconf-2015\"\n  title: \"Moneyball At The Keyboard: Lessons on How To Scout Talented Developers\"\n  raw_title: \"RubyConf 2015 - Moneyball at the keyboard: Lessons on how to Scout Talented Developers\"\n  speakers:\n    - Adam Jonas\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: |-\n    Moneyball at the keyboard: Lessons on how to Scout Talented Developers by Adam Jonas\n\n    The central premise of Moneyball is that the collected wisdom of baseball insiders is subjective and flawed. Like baseball, the tech industry has a poor history of evaluating talent by favoring biased perspectives over objective analysis. As a baseball scout turned web developer and team lead, I will explore how the lessons I learned in my former career can enable us all to make better decisions on how to grow our teams and surface undervalued skills.\n  video_provider: \"youtube\"\n  video_id: \"tw5wFOAmpTc\"\n\n- id: \"mat-brown-rubyconf-2015\"\n  title: \"Seven Habits of Highly Effective Gems\"\n  raw_title: \"RubyConf 2015 - Seven Habits of Highly Effective Gems by Mat Brown\"\n  speakers:\n    - Mat Brown\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: |-\n    Seven Habits of Highly Effective Gems by Mat Brown\n\n    These days, publishing a Ruby Gem is incredibly easy—but publishing a good one isn’t. By following a few best practices when you release your code to the open source community, you can make your library stand out from the crowd. We’ll lay out some basic principles, touching on both code design and build tooling, that will have other programmers clamoring to use and contribute to your project, guaranteeing that you will become a code celebrity practically overnight.\n  video_provider: \"youtube\"\n  video_id: \"tqLbgS0fw5c\"\n\n- id: \"chris-mar-rubyconf-2015\"\n  title: \"The Art of Ruby Technical Interviews\"\n  raw_title: \"RubyConf 2015 - The Art of Ruby Technical Interviews by Chris Mar\"\n  speakers:\n    - Chris Mar\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: |-\n    The Art of Ruby Technical Interviews by Chris Mar\n\n    So, you want to be a Ruby developer? You've attended a bootcamp, read the books, and completed online courses. You're ready to start building great things. But the technical interview process can be a challenge for new Ruby developers. I'll teach you how to prepare, practice and give you techniques to answer tough questions.\n  video_provider: \"youtube\"\n  video_id: \"nZNfSQKC-Yk\"\n\n- id: \"louisa-barrett-rubyconf-2015\"\n  title: \"Design Thinking for Rubyists\"\n  raw_title: \"RubyConf 2015 - Design Thinking for Rubyists by Louisa Barrett\"\n  speakers:\n    - Louisa Barrett\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: |-\n    Design Thinking for Rubyists by Louisa Barrett\n\n    Everyone has the power to be creative, and design thinking is about shifting your mindset to fully embrace your ability to generate new ideas. Let's explore how to flex those creative muscles -- because while technology needs change, the ability to generate great ideas that resonate with users will never lose value.\n  video_provider: \"youtube\"\n  video_id: \"ruETk-YbQpI\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2015\"\n  title: \"Keynote: Ruby 3 Challenges (and Q&A with Matz)\"\n  raw_title: \"RubyConf 2015 - Keynote and Q&A: Matz\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n    - Evan Phoenix\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: |-\n    Keynote and Q&A: Matz\n  video_provider: \"youtube\"\n  video_id: \"LE0g2TUsJ4U\"\n\n- id: \"heidi-waterhouse-rubyconf-2015\"\n  title: \"The Seven Righteous Fights\"\n  raw_title: \"RubyConf 2015 - The Seven Righteous Fights by Heidi Waterhouse\"\n  speakers:\n    - Heidi Waterhouse\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: |-\n    The Seven Righteous Fights by Heidi Waterhouse\n\n    There are seven fights that I have over and over again, whenever I start at a company. I'm here to convince you that it's valuable for everyone to have these things in mind from the inception of a project.\n\n    Having these fights early prevents you from doing the software equivalent of poking chocolate chips into an already-baked cookie\n  video_provider: \"youtube\"\n  video_id: \"7vuOth98ZzY\"\n\n- id: \"lightning-talks-rubyconf-2015\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf 2015 - Lightning Talks by Many People\"\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-22\"\n  published_at: \"2015-11-22\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"G4j_GrieCyk\"\n  talks:\n    - title: \"Lightning Talk: Learn Enough to be Dangerous\"\n      start_cue: \"00:00\"\n      end_cue: \"01:45\"\n      id: \"michael-hartl-lighting-talk-rubyconf-2015\"\n      video_id: \"michael-hartl-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Hartl\n\n    - title: \"Lightning Talk: Cooking Management to Give Back\"\n      start_cue: \"01:45\"\n      end_cue: \"03:23\"\n      id: \"david-bock-lighting-talk-rubyconf-2015\"\n      video_id: \"david-bock-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - David Bock\n\n    - title: \"Lightning Talk: Encoded TOSS String\"\n      start_cue: \"03:23\"\n      end_cue: \"04:57\"\n      id: \"benjamin-fleischer-lighting-talk-rubyconf-2015\"\n      video_id: \"benjamin-fleischer-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Benjamin Fleischer\n\n    - title: \"Lightning Talk: Universal Translator\"\n      start_cue: \"04:57\"\n      end_cue: \"10:34\"\n      id: \"steve-downie-lighting-talk-rubyconf-2015\"\n      video_id: \"steve-downie-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Steve Downie\n\n    - title: \"Lightning Talk: Rocket Job\"\n      start_cue: \"10:34\"\n      end_cue: \"15:43\"\n      id: \"reid-morrison-lighting-talk-rubyconf-2015\"\n      video_id: \"reid-morrison-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Reid Morrison\n\n    - title: \"Lightning Talk: Inconceivable\"\n      start_cue: \"15:43\"\n      end_cue: \"20:56\"\n      id: \"randy-coulman-lighting-talk-rubyconf-2015\"\n      video_id: \"randy-coulman-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Randy Coulman\n\n    - title: \"Lightning Talk: Plane Programming\"\n      start_cue: \"20:56\"\n      end_cue: \"26:00\"\n      id: \"billy-watson-lighting-talk-rubyconf-2015\"\n      video_id: \"billy-watson-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Billy Watson\n\n    - title: \"Lightning Talk: Parallella\"\n      start_cue: \"26:00\"\n      end_cue: \"30:57\"\n      id: \"ray-hightower-lighting-talk-rubyconf-2015\"\n      video_id: \"ray-hightower-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Ray Hightower\n\n    - title: \"Lightning Talk: ure\"\n      start_cue: \"30:57\"\n      end_cue: \"33:48\"\n      id: \"clayton-flesher-lighting-talk-rubyconf-2015\"\n      video_id: \"clayton-flesher-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Clayton Flesher\n\n    - title: \"Lightning Talk: 3D Printing is not like Cooking Rotisserie Chicken at Home.\"\n      start_cue: \"33:48\"\n      end_cue: \"38:52\"\n      id: \"devin-clark-lighting-talk-rubyconf-2015\"\n      video_id: \"devin-clark-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Devin Clark\n\n    - title: \"Lightning Talk: In Over My Head\"\n      start_cue: \"38:52\"\n      end_cue: \"42:32\"\n      id: \"scott-mascar-lighting-talk-rubyconf-2015\"\n      video_id: \"scott-mascar-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Scott Mascar\n\n    - title: \"Lightning Talk: UI Driven Development\"\n      start_cue: \"42:32\"\n      end_cue: \"46:33\"\n      id: \"paul-dawson-lighting-talk-rubyconf-2015\"\n      video_id: \"paul-dawson-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Paul Dawson\n\n    - title: \"Lightning Talk: Onboarding Junior Devs\"\n      start_cue: \"46:33\"\n      end_cue: \"51:27\"\n      id: \"miki-rezentes-lighting-talk-rubyconf-2015\"\n      video_id: \"miki-rezentes-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Miki Rezentes\n\n    - title: \"Lightning Talk: Improving SOA w/Pub-Sub\"\n      start_cue: \"51:27\"\n      end_cue: \"56:38\"\n      id: \"jordan-bach-lighting-talk-rubyconf-2015\"\n      video_id: \"jordan-bach-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Jordan Bach\n\n    - title: \"Lightning Talk: 2 Tiny Dev Tools\"\n      start_cue: \"56:38\"\n      end_cue: \"1:01:00\"\n      id: \"nat-budin-lighting-talk-rubyconf-2015\"\n      video_id: \"nat-budin-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Nat Budin\n\n    - title: \"Lightning Talk: Concepts for New Volt Devs\"\n      start_cue: \"1:01:00\"\n      end_cue: \"1:06:38\"\n      id: \"rick-carlino-lighting-talk-rubyconf-2015\"\n      video_id: \"rick-carlino-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Rick Carlino\n\n    - title: \"Lightning Talk: Ruby Vernac\"\n      start_cue: \"1:06:38\"\n      end_cue: \"1:12:12\"\n      id: \"ratnadeep-deshmane-lighting-talk-rubyconf-2015\"\n      video_id: \"ratnadeep-deshmane-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Ratnadeep Deshmane\n\n    - title: \"Lightning Talk: Too Late to Estimate\"\n      start_cue: \"1:12:12\"\n      end_cue: \"1:14:38\"\n      id: \"craig-buchek-lighting-talk-rubyconf-2015\"\n      video_id: \"craig-buchek-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Craig Buchek\n\n    - title: \"Lightning Talk: Book Duets\"\n      start_cue: \"1:14:38\"\n      end_cue: \"1:19:07\"\n      id: \"loraine-kanervisto-lighting-talk-rubyconf-2015\"\n      video_id: \"loraine-kanervisto-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Loraine Kanervisto\n\n    - title: \"Lightning Talk: Go Get a Damn Job\"\n      start_cue: \"1:19:07\"\n      end_cue: \"1:24:22\"\n      id: \"britni-alexander-lighting-talk-rubyconf-2015\"\n      video_id: \"britni-alexander-lighting-talk-rubyconf-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Britni Alexander\n\n- id: \"danny-guinther-rubyconf-2015\"\n  title: \"A Muggle's Guide to Tail Call Optimization in Ruby\"\n  raw_title: \"RubyConf 2015 - A Muggle's Guide to Tail Call Optimization in Ruby by Danny Guinther\"\n  speakers:\n    - Danny Guinther\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    A Muggle's Guide to Tail Call Optimization in Ruby by Danny Guinther\n\n    Submitted for your approval: a circle of torment unchronicled by the poets of old, a terror at the heart of many a horror story: SystemStackError: stack level too deep\n\n    Tremble no more! Conquer the well of eternity!\n\n    Behold the secrets of tail recursion and tail call optimization in Ruby! Witness the metamorphosis of a simple function as we explore the hidden power of tail call optimization buried deep within the Ruby VM! Follow the transformation to the revelation of tail call optimization's most ghastly secret: in many ways it's really just a special type of loop construct! The horror!\n  video_provider: \"youtube\"\n  video_id: \"6Tblgvvit4E\"\n\n- id: \"sam-phippen-rubyconf-2015\"\n  title: \"Extremely Defensive Coding\"\n  raw_title: \"RubyConf 2015 - Extremely Defensive Coding by Sam Phippen\"\n  speakers:\n    - Sam Phippen\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    Extremely Defensive Coding by Sam Phippen\n\n    Defensive programming is one of those abstract ideas that seems great but is often unclear in practice.\n\n    In this talk we'll look at some of the extremely defensive patterns that have been driven out in RSpec through the years. We'll look at building Ruby that works across a range of interpreters (including 1.8.7!). We'll investigate how you can write code that defends against objects that redefine methods like send, method and is_a?.\n\n    You should come to this talk if you want to learn about method resolution in Ruby, and cross interpreter design patterns.\n  video_provider: \"youtube\"\n  video_id: \"44VFrNs7JTU\"\n\n- id: \"jerry-dantonio-rubyconf-2015\"\n  title: \"Everything You Know About the GIL is Wrong\"\n  raw_title: \"RubyConf 2015 - Everything You Know About the GIL is Wrong by Jerry D'Antonio\"\n  speakers:\n    - Jerry D'Antonio\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    Everything You Know About the GIL is Wrong by Jerry D'Antonio\n\n    When a Rubyist hears \"concurrency\" they usually Google Elixir, Go, or even Node.js. Turns out, Ruby can be great for concurrency! The Global Interpreter Lock (GIL) does NOT prevent Ruby programs from performing concurrently. In this presentation we'll discuss the true meaning of concurrency, explore the inner-workings of the GIL, and gain a deeper understanding of how the GIL effects concurrent programs. Along the way we'll write a bunch of concurrent Ruby code, run it on multiple interpreters, and compare the results.\n  video_provider: \"youtube\"\n  video_id: \"dP4U1yI1WZ0\"\n\n- id: \"jack-danger-canty-rubyconf-2015\"\n  title: \"Ruby's Environment Variable API\"\n  raw_title: \"RubyConf 2015 - Ruby's Environment Variable API by Jack Danger Canty\"\n  speakers:\n    - Jack Danger Canty\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    Ruby's Environment Variable API by Jack DangerCanty\n\n    You use tools like Bundler, RVM, rbenv, or chruby every day. But what are these tools actually doing behind the scenes?\n\n    Let's take a closer look at how tools like these alter Ruby's behavior by tweaking the environment it runs in. We'll take the mystery out of load paths and gems sets. You'll come away with a better understanding of how tools like RVM work, and a better idea of where to look when they don't do what you expected.\n  video_provider: \"youtube\"\n  video_id: \"thZx3k6cmis\"\n\n- id: \"david-copeland-rubyconf-2015\"\n  title: \"Storytelling via the Psychology of Professional Wrestling\"\n  raw_title: \"RubyConf 2015 - Storytelling via the Psychology of Professional Wrestling by David Copeland\"\n  speakers:\n    - David Copeland\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    Storytelling via the Psychology of Professional Wrestling by David Copeland\n\n    Great storytelling feels almost impossible at times, yet week in and week out, for over 30 years, the jacked-up men & women of World Wrestling Entertainment have been doing it, five minutes at a time.\n\n    No back-story, little dialog, and a live crowd that knows it's all scripted. Yet, they get the audience invested in the outcomes almost every time.\n\n    Sound impossible? Pro-wrestlers know the essence of great storytelling—called “ring psychology”—and have used it for decades.\n  video_provider: \"youtube\"\n  video_id: \"FplG2HLe3y0\"\n\n- id: \"david-bock-rubyconf-2015\"\n  title: \"The Math Behind Mandelbrot\"\n  raw_title: \"RubyConf 2015 - The Math Behind Mandelbrot by David Bock\"\n  speakers:\n    - David Bock\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    The Math Behind Mandelbrot by David Bock\n\n    One day in my high school classroom I heard a student ask \"What is 'i' good for anyway? I mean, is it a concept that's useful in the real world?\" I jumped at the chance to explain the Mandelbrot set. Come with me on a journey to understand how infinite complexity can arise from a few simple rules. Infinity will fit inside your head, and you'll feel like you just learned one of the Great Secrets of the Universe. If you can multiply, you'll understand all the math in this talk.\n  video_provider: \"youtube\"\n  video_id: \"t2v32N56sSY\"\n\n- id: \"tobias-pfeiffer-rubyconf-2015\"\n  title: \"Beating Go Thanks To The Power Of Randomness\"\n  raw_title: \"RubyConf 2015 - Beating Go thanks to the power of randomness by Tobias Pfeiffer\"\n  speakers:\n    - Tobias Pfeiffer\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |+\n    Beating Go thanks to the power of randomness by Tobias Pfeiffer\n\n    Go is a board game that is more than 2,500 years old (yes, this is not about the programming language!) and it is fascinating from multiple viewpoints. For instance, go bots still can’t beat professional players, unlike in chess.\n\n    This talk will show you what is so special about Go that computers still can’t beat humans. We will take a look at the most popular underlying algorithm and show you how the Monte Carlo method, basically random simulation, plays a vital role in conquering Go's complexity and creating the strong Go bots of today.\n\n  video_provider: \"youtube\"\n  video_id: \"fFGB3VFuSFU\"\n\n- id: \"james-adam-rubyconf-2015\"\n  title: \"Why Is Nobody Using Refinements?\"\n  raw_title: \"RubyConf 2015 - Why is nobody using Refinements? by James Adam\"\n  speakers:\n    - James Adam\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    Why is nobody using Refinements? by James Adam\n\n    Refinements have been a feature in Ruby for several years now, added as a more structured alternative to the \"scourge\" of monkey patching, but it seems like almost nobody is using them. My question is this: why not? Are they a bad idea? Are they broken? Or do we just not understand them?\n\n    Let's figure out once and for all what refinements are good for, and what their limitations might be, so that future generations can either use them for glory, or rightfully ignore them forevermore.\n  video_provider: \"youtube\"\n  video_id: \"qXC9Gk4dCEw\"\n\n- id: \"betsy-haibel-rubyconf-2015\"\n  title: \"s/regex/DSLs/: What Regex Teaches Us About DSL Design\"\n  raw_title: \"RubyConf 2015 - s/regex/DSLs/: What Regex Teaches Us About DSL Design by Betsy Haibel\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    s/regex/DSLs/: What Regex Teaches Us About DSL Design by Betsy Haibel\n\n    Many Ruby domain-specific languages go for beauty over usability - and it shows, when you try to use them. But one of programming's oldest, most common DSLs - regular expressions - is both as ugly and as persistent as a cockroach. What makes regexes tick? By breaking down their design, we'll learn concrete principles that go deeper than \"Englishy:\" principles like \"composability\" and \"deep domain integration.\" We'll learn how to get precise about the API design and boundaries of our DSLs. We'll write a micro-DSL that is usable without monkeypatching.`\n  video_provider: \"youtube\"\n  video_id: \"wUWwDrP_6Zw\"\n\n- id: \"brad-urani-rubyconf-2015\"\n  title: \"Changing the Unchangeable: The Hows and Whys of Immutable Data Structures\"\n  raw_title: \"RubyConf 2015 - Changing the Unchangeable... by Brad Urani\"\n  speakers:\n    - Brad Urani\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    Changing the Unchangeable: The Hows and Whys of Immutable Data Structures by Brad Urani\n\n    Immutable data structures give us peace of mind, but using them is challenging. How do you build an immutable list? Why would you use one? Join us and learn what makes a data structure \"persistent\", the holy grail combination of immutability and performance. We'll see not just how to use them, but also why they're a good idea and how they work. Most importantly, we'll see how these data structures are useful in real-life programming scenarios. Master this cornerstone of functional programming and learn the answer to the ultimate riddle: how do you change a list while leaving it unchanged?  video_provider: youtube\n  video_provider: \"youtube\"\n  video_id: \"gTClDj9Zl1g\"\n\n- id: \"eric-weinstein-rubyconf-2015\"\n  title: \"The Hitchhiker's Guide to Ruby GC\"\n  raw_title: \"RubyConf 2015 - The Hitchhiker's Guide to Ruby GC by Eric Weinstein\"\n  speakers:\n    - Eric Weinstein\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |+\n    The Hitchhiker's Guide to Ruby GC by Eric Weinstein\n\n    When Ruby programs slow down, the usual culprits—database queries, superlinear time complexity—aren't always the real problem. Ruby's object space and garbage collection are a surprisingly rich and oft-misunderstood area of the language, and one where performance issues can easily hide. This talk is a brief but deep dive into the history and details of garbage collection in Ruby, including its evolution, parameter tuning, and a case study using the Unicorn web server.\n\n  video_provider: \"youtube\"\n  video_id: \"NnqId_OvUU4\"\n\n- id: \"lito-nicolai-rubyconf-2015\"\n  title: \"Botany with Bytes\"\n  raw_title: \"RubyConf 2015 - Botany with Bytes by Lito Nicolai\"\n  speakers:\n    - Lito Nicolai\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    Botany with Bytes by Lito Nicolai\n\n    Plants are tiny computers. As they grow, the sprouts are computing from first principles how to be a plant. We’ll see how they do it!\n\n    This talk uses Ruby and the ‘graphics’ gem to build models of all kinds of plants, from algae blooms to juniper branches. We’ll touch on rewriting systems, formal grammars, and Alan Turing’s contributions to botany. We’ll look at the shapes of euphorbia, artichoke, and oregon grape, and how these come from plants’ love of sunlight and greedy desire for growth. By the end, we'll have a series of great visual metaphors for fundamental computer science concepts!\n  video_provider: \"youtube\"\n  video_id: \"UM8rn2N0g4U\"\n\n- id: \"terence-lee-rubyconf-2015\"\n  title: \"Building CLI Apps for Everyone\"\n  raw_title: \"RubyConf 2015 - Building CLI Apps for Everyone by Terence Lee\"\n  speakers:\n    - Terence Lee\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    Building CLI Apps for Everyone by Terence Lee\n\n    Many projects rely on command-line tools to provide an efficient and powerful interface to work.\n\n    Building tools for everyone can be difficult, because of conflicting environment or OS.\n\n    How can we build command-line apps that work for everyone and still write Ruby?\n\n    This talk will discuss how to use mruby-cli to build cross-platform apps in Ruby.\n\n    Our goal will be to build a CLI app using mruby and produce a self-contained binary that can be shipped to end users.\n\n    Since mruby is designed to be embedded and statically compiled, it's also really good at packaging ruby code.\n  video_provider: \"youtube\"\n  video_id: \"zv_bCpOCXxo\"\n\n- id: \"sam-livingston-gray-rubyconf-2015\"\n  title: \"Cucumbers Have Layers: A Love Story\"\n  raw_title: \"RubyConf 2015 - Cucumbers Have Layers: A Love Story by Sam Livingston-Gray\"\n  speakers:\n    - Sam Livingston-Gray\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    Cucumbers Have Layers: A Love Story Sam Livingston-Gray\n\n    Cucumber sucks. Features are hard to write and constantly break when the UI changes. Step definitions are annoying to create and a freaking nightmare to maintain. And Cucumber suites take for-EVER to run, because you have to wait for a web browser.\n\n    Except... [almost] none of that is actually true.\n\n    After years of making awful messes with Cucumber, I finally found a way to use it that worked well, and a project I couldn't have done without it. I'd like to show you one way to use Cucumber that can be elegant, powerful, expressive, and—believe it or not—fast.\n  video_provider: \"youtube\"\n  video_id: \"v_3i_U7Nf80\"\n\n- id: \"adam-walker-rubyconf-2015\"\n  title: \"Tagging Your World With RFID\"\n  raw_title: \"RubyConf 2015 - Tagging your world with RFID by Adam Walker\"\n  speakers:\n    - Adam Walker\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-23\"\n  published_at: \"2015-11-23\"\n  description: |-\n    Tagging your world with RFID by Adam Walker\n\n    Come learn all the wonderful uses of UHF RFID tags and how Ruby makes it easy to read, write and deploy real time asset tracking systems. RFID tags can be read from 30 or more feet away and easily integrated with a variety of existing systems with a low barrier to entry. By the end of this session, you'll learn how to track your pets, clothes, keys, and even make a tool that assists with your grocery shopping.\n  video_provider: \"youtube\"\n  video_id: \"-C3WI5LxI-s\"\n\n- id: \"joe-mastey-rubyconf-2015\"\n  title: \"Manage Your Energy, Not Your Time\"\n  raw_title: \"RubyConf 2015 - Manage Your Energy, Not Your Time by Joe Mastey\"\n  speakers:\n    - Joe Mastey\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-24\"\n  published_at: \"2015-11-24\"\n  description: |-\n    Manage Your Energy, Not Your Time by Joe Mastey\n\n    High-tech culture is obsessed with managing time. In fact, if there’s one thing that we spend as much time on as actual work, it’s getting the most out of that work time. But here, like elsewhere, choosing the wrong optimization does more harm than good. Wringing every minute out of your day is more likely to burn you out than to turn you into a code-producing machine. Instead, we need to get better at managing our energy. Put down the kitchen timer, because in this talk you’ll learn about better research-driven approaches to get more out of work and life.\n  video_provider: \"youtube\"\n  video_id: \"505ybcH0f6s\"\n\n- id: \"jay-mcgavren-rubyconf-2015\"\n  title: \"Messenger: The (Complete) Story of Method Lookup\"\n  raw_title: \"RubyConf 2015 - Messenger: The (Complete) Story of Method Lookup by Jay McGavren\"\n  speakers:\n    - Jay McGavren\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-24\"\n  published_at: \"2015-11-24\"\n  description: |-\n    Messenger: The (Complete) Story of Method Lookup by Jay McGavren\n\n    You call a method on an object, and it invokes the instance method defined on the class. Simple. Except when the method isn't on the class itself, because it's inherited from a superclass. Or a singleton class, mixin, or refinement. Actually, this is kind of complicated!\n\n    In this talk, we'll take an inside look at Ruby method lookup. We'll start with the basics, like inherited methods, and work our way up to the cutting-edge stuff, like refinements and prepending mixins. You'll leave with a clear understanding of how it all works, and maybe with some better ideas for structuring your code!\n  video_provider: \"youtube\"\n  video_id: \"TZWQAvlMru8\"\n\n- id: \"rebecca-sliter-rubyconf-2015\"\n  title: \"A Tale of Two Feature Flags\"\n  raw_title: \"RubyConf 2015 - A Tale of Two Feature Flags by Rebecca Sliter\"\n  speakers:\n    - Rebecca Sliter\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-24\"\n  published_at: \"2015-11-24\"\n  description: |-\n    A Tale of Two Feature Flags by Rebecca Sliter\n\n    It was the best of times, it was the worst of times. Feature flags are a quick win for development teams seeking a way to more rapidly release software but can create unexpected technical complexity.\n\n    Join us for a comparison of the life-cycles of two seemingly similar feature flags. We'll discuss the challenges teams often face when implementing them, as well as strategies to avoid these issues and deliver software quickly and reliably.\n  video_provider: \"youtube\"\n  video_id: \"rBBLMmr9e-k\"\n\n- id: \"caleb-hearth-rubyconf-2015\"\n  title: \"The Joy of Miniature Painting\"\n  raw_title: \"RubyConf 2015 - The Joy of Miniature Painting by Caleb Thompson\"\n  speakers:\n    - Caleb Hearth\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-24\"\n  published_at: \"2015-11-24\"\n  description: |-\n    The Joy of Miniature Painting by Caleb Thompson\n\n    As developers, we often stare at a computer screen all day only to come home and stare at more glowing boxes all night. Having a productive, nontechnical hobby can really help to keep us sharp for our day jobs.\n\n    You'll watch me live-paint a small model for a game called Warmachine while I describe some of the techniques I use. You'll hear about how painting has helped me to clear my mind after work, keeping me away from burnout I might encounter if I wasn't exercising a different brain lobe.\n\n    Afterward, I'd love to chat about painting and playing games.\n  video_provider: \"youtube\"\n  video_id: \"xCBRqZpiB2M\"\n\n- id: \"tom-macklin-rubyconf-2015\"\n  title: \"Using Ruby In Security Critical Applications\"\n  raw_title: \"RubyConf 2015 - Using Ruby In Security Critical Applications by Tom Macklin\"\n  speakers:\n    - Tom Macklin\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-24\"\n  published_at: \"2015-11-24\"\n  description: |-\n    Using Ruby In Security Critical Applications by Tom Macklin\n\n    We’ve worked to improve security in MRI for a variety of security critical applications, and will describe some of our successes and failures in terms of real-world applications and their various runtime environments. We will describe some of the security principles that guide our work, and how they fit in with the ruby culture. We will also introduce some objectives we have moving forward to improve ruby’s security, and ways we’d like to engage the community to help.\n  video_provider: \"youtube\"\n  video_id: \"GenjU6iRb6o\"\n\n- id: \"brandon-hays-rubyconf-2015\"\n  title: \"Hacking Spacetime for a Successful Career\"\n  raw_title: \"RubyConf 2015 - Hacking Spacetime for a Successful Career by Brandon Hays\"\n  speakers:\n    - Brandon Hays\n  event_name: \"RubyConf 2015\"\n  date: \"2015-11-25\"\n  published_at: \"2015-11-25\"\n  description: |-\n    We talk a lot about building well-crafted software. But what about a well-crafted career in software? Who is making sure you’re on track for the life you want five, ten, thirty years from now?\n\n    We’ll build a time machine and follow a typical development career through various tracks, and see how a few basic principles can radically alter your career’s trajectory over time.\n\n    If you’ve ever felt the existential dread of “climbing the walls” at your job, you’re not alone. We’ll explore why and share some concrete steps you can take now to create a long, happy, rewarding career.\n  video_provider: \"youtube\"\n  video_id: \"TrLDU6u_-rY\"\n\n- id: \"carina-c-zona-rubyconf-2015\"\n  title: \"Keynote: Consequences of an Insightful Algorithm\"\n  raw_title: \"RubyConf 2015 - Keynote: Consequences of an Insightful Algorithm by Carina C. Zona\"\n  speakers:\n    - Carina C. Zona\n  event_name: \"RubyConf 2015\"\n  date: \"2015-12-07\"\n  published_at: \"2015-12-07\"\n  description: |-\n    Keynote: Consequences of an Insightful Algorithm by Carina C. Zona\n\n    Coders have ethical responsibilities. We can extract remarkably precise intuitions about people. Do we have a right to know what they didn't consent to share, even when they shared data leading us there? Balancing human needs and business specs can be tough. How do we mitigate against unintended outcomes? In this talk, we look at examples of uncritical programming, & painful results of using insightful data in ways that were benignly intended. You'll learn practices for examining how code might harm individuals. We’ll look at how to flip the paradigm, for consequences that are better for all.\n  video_provider: \"youtube\"\n  video_id: \"Vpr-xDmA2G4\"\n\n- id: \"colin-fulton-rubyconf-2015\"\n  title: \"String Theory and Time Travel: The Humble Text Editor\"\n  raw_title: \"RubyConf 2015 - String Theory and Time Travel: the humble text editor by Colin Fulton\"\n  speakers:\n    - Colin Fulton\n  event_name: \"RubyConf 2015\"\n  date: \"2015-12-07\"\n  published_at: \"2015-12-07\"\n  description: |-\n    String Theory and Time Travel: the humble text editor by Colin Fulton\n\n    Did you know that the time machine in your text editor is probably broken? Better yet, have you considered that your text editor has a time machine?\n\n    The majority of our day is spent in a text editor, but most never think about how they really work. There is a lot more to an editor than saving a few keystrokes or the rivalry between Vim and Emacs; they can teach us about data structures, IO, design, and the dangers of time travel.\n\n    Let's take a closer look at some of the most enduring applications, and see what we can learn by trying to build a better editor using Ruby.\n  video_provider: \"youtube\"\n  video_id: \"zaql_NwlO18\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2016/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaMUYwB6tTX5p2Z6fOCdGRE\"\ntitle: \"RubyConf 2016\"\nkind: \"conference\"\nlocation: \"Cincinnati, OH, United States\"\ndescription: \"\"\nstart_date: \"2016-11-10\"\nend_date: \"2016-11-12\"\npublished_at: \"2016-11-17\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2016\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 39.1031182\n  longitude: -84.5120196\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2016/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 1\"\n    date: \"2016-11-10\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:40\"\n        end_time: \"11:25\"\n        slots: 4\n\n      - start_time: \"11:35\"\n        end_time: \"12:20\"\n        slots: 4\n\n      - start_time: \"12:20\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 1\n\n      - start_time: \"14:10\"\n        end_time: \"14:55\"\n        slots: 4\n\n      - start_time: \"15:05\"\n        end_time: \"15:50\"\n        slots: 4\n\n      - start_time: \"15:50\"\n        end_time: \"16:20\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:20\"\n        end_time: \"17:05\"\n        slots: 4\n\n      - start_time: \"17:15\"\n        end_time: \"18:00\"\n        slots: 1\n\n  - name: \"Day 2\"\n    date: \"2016-11-11\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:25\"\n        end_time: \"11:10\"\n        slots: 4\n\n      - start_time: \"11:20\"\n        end_time: \"12:05\"\n        slots: 4\n\n      - start_time: \"12:05\"\n        end_time: \"13:15\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:15\"\n        end_time: \"14:00\"\n        slots: 4\n\n      - start_time: \"14:10\"\n        end_time: \"14:55\"\n        slots: 4\n\n      - start_time: \"15:05\"\n        end_time: \"15:50\"\n        slots: 4\n\n      - start_time: \"15:50\"\n        end_time: \"16:20\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:20\"\n        end_time: \"17:05\"\n        slots: 4\n\n      - start_time: \"17:15\"\n        end_time: \"18:45\"\n        slots: 1\n\n  - name: \"Day 3\"\n    date: \"2016-11-12\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:25\"\n        end_time: \"11:10\"\n        slots: 4\n\n      - start_time: \"11:20\"\n        end_time: \"12:05\"\n        slots: 4\n\n      - start_time: \"12:05\"\n        end_time: \"13:15\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:15\"\n        end_time: \"14:00\"\n        slots: 4\n\n      - start_time: \"14:10\"\n        end_time: \"14:55\"\n        slots: 4\n\n      - start_time: \"15:05\"\n        end_time: \"15:50\"\n        slots: 1\n\n      - start_time: \"15:50\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Closing Social\n\ntracks:\n  - name: \"Learning and Teaching\"\n    color: \"#FFD54F\"\n    text_color: \"#000000\"\n\n  - name: \"Comparative Ruby\"\n    color: \"#BA68C8\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Tools and Toys\"\n    color: \"#4DD0E1\"\n    text_color: \"#000000\"\n\n  - name: \"Ruby Deep Dive\"\n    color: \"#42A5F5\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Ruby and Hardware\"\n    color: \"#FF7043\"\n    text_color: \"#fff\"\n\n  - name: \"Testing\"\n    color: \"#66BB6A\"\n    text_color: \"#000000\"\n\n  - name: \"Lessons Learned\"\n    color: \"#FFCA28\"\n    text_color: \"#000000\"\n\n  - name: \"Performance\"\n    color: \"#EF5350\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"War Stories\"\n    color: \"#8D6E63\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Life Beyond Bootcamps\"\n    color: \"#26A69A\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Weird Ruby\"\n    color: \"#78909C\"\n    text_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2016/videos.yml",
    "content": "---\n# https://web.archive.org/web/20161115224654/http://rubyconf.org/schedule\n\n## Day 1 - 2016-11-10\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2016\"\n  title: \"Opening Keynote: RINSWAN\"\n  raw_title: \"RubyConf 2016 - Opening Keynote by Yukihiro 'Matz' Matsumoto\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Opening Keynote by Yukihiro 'Matz' Matsumoto\n  video_provider: \"youtube\"\n  video_id: \"1l3U1X3z0CE\"\n\n# ---\n\n# Track: General 1\n- id: \"ariel-caplan-rubyconf-2016\"\n  title: \"Building a Better OpenStruct\"\n  raw_title: \"RubyConf 2016 - Building a Better OpenStruct by Ariel Caplan\"\n  speakers:\n    - Ariel Caplan\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Building a Better OpenStruct by Ariel Caplan\n\n    OpenStruct, part of Ruby's standard library, is prized for its beautiful API. It provides dynamic data objects with automatically generated getters and setters. Unfortunately, OpenStruct also carries a hefty performance penalty.\n\n    Luckily, Rubyists have recently improved OpenStruct performance and provided some alternatives. We'll study their approaches, learning to take advantage of the tools in our ecosystem while advancing the state our community.\n\n    Sometimes, we can have our cake and eat it too. But it takes creativity, hard work, and willingness to question why things are the way they are.\n  video_provider: \"youtube\"\n  video_id: \"2IbJFCbBnQk\"\n\n# Track: Learning and Teaching\n- id: \"max-tiu-rubyconf-2016\"\n  title: \"Bootcamp Grads Have Feelings, Too\"\n  raw_title: \"RubyConf 2016 - Bootcamp Grads Have Feelings, Too by Max Tiu\"\n  speakers:\n    - Max Tiu\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Bootcamp Grads Have Feelings, Too by Max Tiu\n\n    You’re a bootcamp student. You’re so excited to become a developer! Amidst your excitement about this new industry, you hear everyone say that bootcamps are a blemish on the community, that they’re a waste of time and money. “Maybe I’ve made a huge mistake,” you think. “I don’t know how I’ll fit in here.\"\n\n    But you can make this community better! In this session, you’ll learn about the varied experiences of bootcamp students and grads, how exclusionary behavior can end up stunting our community as a whole, and what you can to do make a more inclusive environment for everyone of all skill levels.\n  video_provider: \"youtube\"\n  video_id: \"133HhIjmfRE\"\n  track: \"Learning and Teaching\"\n\n# Track: General 2\n- id: \"cory-chamblin-rubyconf-2016\"\n  title: \"Attention Rubyists: You Can Write Video Games\"\n  raw_title: \"RubyConf 2016 - Attention Rubyists: you can write video games by Cory Chamblin\"\n  speakers:\n    - Cory Chamblin\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Attention Rubyists: you can write video games by Cory Chamblin\n\n    Ruby may seem like a humdrum language best suited for writing web apps, but underneath that cool exterior lies plenty of power -- power we can harness for making our own games!\n\n    In this talk, we'll introduce Gosu, a sweet little game library. We'll talk about how games are structured in pretty much every language and framework ever, where to get ideas for things to make, and ways you can share your game with your friends and the world.\n  video_provider: \"youtube\"\n  video_id: \"bK9RX_CzCeI\"\n\n# Track: Comparative Ruby\n- id: \"eric-hodel-rubyconf-2016\"\n  title: \"Building Maintainable Command-Line Tools with MRuby\"\n  raw_title: \"RubyConf 2016 - Building maintainable command-line tools with MRuby by Eric Hodel\"\n  speakers:\n    - Eric Hodel\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Building maintainable command-line tools with MRuby by Eric Hodel\n\n    mruby and mruby-cli makes it possible to ship single binary command-line tools that can be used without setup effort, but how difficult is development in MRuby?\n\n    In this talk we'll explore how to work with MRuby and mruby-cli. We'll cover the differences in development patterns when using MRuby, the maturity of the MRuby ecosystem, and development patterns when using mruby-cli to build a command-line tool.\n  video_provider: \"youtube\"\n  video_id: \"96YgJSGaB3M\"\n  track: \"Comparative Ruby\"\n\n# ---\n\n# Track: Tools and Toys\n- id: \"loren-segal-rubyconf-2016\"\n  title: \"C Ruby? C Ruby Go! Go Ruby Go!\"\n  raw_title: \"RubyConf 2016 - C Ruby? C Ruby Go! Go Ruby Go! by Loren Segal\"\n  speakers:\n    - Loren Segal\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - C Ruby? C Ruby Go! Go Ruby Go! by Loren Segal\n\n    Ever wanted to rewrite performance sensitive code as a native Ruby extension, but got stuck trying to navigate the depths of Ruby’s C API before you could get anything done? Or maybe you’re just not comfortable with C and want an easier path.\n\n    Do you know any Go? Well, if you do, you’re in luck! Join us for this talk about a tool named gorb that will quickly and easily let you generate native Ruby extension wrappers for your Go programs. And if you don’t know Go, come anyway, it’s really easy to learn! We’ll have you writing blazing fast code that you can use right from Ruby, in no time at all.\n  video_provider: \"youtube\"\n  video_id: \"V1ZMQjm9I50\"\n  track: \"Tools and Toys\"\n\n# Track: Learning and Teaching\n- id: \"katherine-wu-rubyconf-2016\"\n  title: \"Continuing Education at Work\"\n  raw_title: \"RubyConf 2016 - Continuing Education at Work by Katherine Wu\"\n  speakers:\n    - Katherine Wu\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Continuing Education at Work by Katherine Wu\n\n    The list of things we want to learn is infinite. How many of us have marked items to read/watch, yet never go back to them? Despite the best of intentions, I often only learn what I directly need. It wasn’t until I started running a couple lightweight continuing education programs at work that I followed through on my goals. We’ll discuss strategies for making these programs low maintenance and long-lived, as well as flexible enough to help both more and less experienced folks. If you’ve been looking for a more effective approach to learning, but still outside classrooms, this talk is for you!\n  video_provider: \"youtube\"\n  video_id: \"9uRho69xSAI\"\n  track: \"Learning and Teaching\"\n\n# Track: General 2\n- id: \"chris-arcand-rubyconf-2016\"\n  title: \"Deletion Driven Development: Code to Delete Code!\"\n  raw_title: \"RubyConf 2016 - Deletion Driven Development: Code to delete code! by Chris Arcand\"\n  speakers:\n    - Chris Arcand\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Deletion Driven Development: Code to delete code! by Chris Arcand\n\n    Good news! Ruby is a successful and mature programming language with a wealth of libraries and legacy applications that have been contributed to for many years. The bad news: Those projects might contain a large amount of useless, unused code which adds needless complexity and confuses new developers. In this talk I'll explain how to build a static analysis tool to help you find unused code and remove it - because there's no code that's easier to maintain than no code at all!\n  video_provider: \"youtube\"\n  video_id: \"OfiIyNV00uI\"\n\n# Track: Comparative Ruby\n- id: \"james-dabbs-rubyconf-2016\"\n  title: \"Composition\"\n  raw_title: \"RubyConf 2016 - Composition by James Dabbs\"\n  speakers:\n    - James Dabbs\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Composition by James Dabbs\n\n    Our work as programmers consists largely of problem decomposition and solution recomposition. This talk is interested in how we cobble small units together into cohesive solutions. We'll examine and compare both object and functional composition, using a Haskell-inspired, functional style of Ruby. Along the way, we'll see how good functional principles can improve our object-oriented design, and vice versa.\n  video_provider: \"youtube\"\n  video_id: \"zwo7ZTHS8Wg\"\n  track: \"Comparative Ruby\"\n\n# Lunch\n\n- id: \"andrew-faraday-rubyconf-2016\"\n  title: \"Gameshow: Just a Ruby Minute\"\n  raw_title: \"RubyConf 2016 - Just a Ruby Minute by Andrew Faraday\"\n  speakers:\n    - Andrew Faraday\n    - Kinsey Ann Durham\n    - Aaron Patterson\n    - Tara Scherner de la Fuente\n    - Sam Phippen\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Just a Ruby Minute by Andrew Faraday\n\n    Just a Minute is a game show that's a part of the British national consciousness, delighting audiences across the country for almost half a century. In it, speakers are challenged to speak for one minute without hesitation, repetition or deviation, it's much harder than it sounds. It's fast paced, funny, insightful and you might even learn something.\n  video_provider: \"youtube\"\n  video_id: \"1hpoyjCB2WY\"\n\n# ---\n\n# Track: Tools and Toys\n- id: \"takashi-kokubun-rubyconf-2016\"\n  title: \"Evaluate Ruby Without Ruby\"\n  raw_title: \"RubyConf 2016 - Evaluate Ruby Without Ruby by Takashi Kokubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Evaluate Ruby Without Ruby by Takashi Kokubun\n\n    Have you ever wanted to implement a tool that can be configured by Ruby code? You may think such tools require MRI, JRuby or Rubinius to evaluate the configuration. But that's not true! Let's see how we can build a tool that evaluates Ruby without dependency on Ruby interpreter using mruby.\n  video_provider: \"youtube\"\n  video_id: \"jD0q8uHV5cA\"\n  track: \"Tools and Toys\"\n\n# Track: Learning and Teaching\n- id: \"katlyn-parvin-rubyconf-2016\"\n  title: '\"Am I Senior Yet?\" Grow Your Career by Teaching Your Peers'\n  raw_title: \"RubyConf 2016 - “Am I Senior Yet?” Grow Your Career by Teaching Your Peers Katlyn Parvin\"\n  speakers:\n    - Katlyn Parvin\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - “Am I Senior Yet?” Grow Your Career by Teaching Your Peers Katlyn Parvin\n\n    “How do I become a senior engineer?” It’s a question every bootcamp grad will ask. Most engineers look at advancement through a lens of increasing technical skill. More than ever, though, being “senior” means more than just parsing Ruby in your sleep. As our companies grow and as our industry grows, seniority means helping new teammates and colleagues advance their own skills. It means knowing how to teach.\n\n    You don’t need Matz-level knowledge to be a great teacher. With social awareness, a dash of psychology, and some proven approaches, by helping others learn, you’ll earn senior-level respect.\n  video_provider: \"youtube\"\n  video_id: \"jcTmoOHhG9A\"\n  track: \"Learning and Teaching\"\n\n# Track: Ruby Deep Dive\n- id: \"craig-buchek-rubyconf-2016\"\n  title: \"A Look at Hooks\"\n  raw_title: \"RubyConf 2016 - A Look at Hooks by Craig Buchek\"\n  speakers:\n    - Craig Buchek\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - A Look at Hooks by Craig Buchek\n\n    Ruby has several methods that are invoked implicitly under certain circumstances. These methods are called \"hooks\", and they provide points to extend behavior. While hooks might seem like \"spooky action at a distance\", they can be really powerful. In fact, hooks are one of the primary ways that Ruby provides for meta-programming.\n\n    Unfortunately, Ruby's hooks are not all documented very well. We'll take a look at what hooks are available and how to use them. We'll also talk about when to avoid using hooks and provide some tips on how to troubleshoot when hooks are involved.\n  video_provider: \"youtube\"\n  video_id: \"x7F4kkdKQbQ\"\n  track: \"Ruby Deep Dive\"\n\n# Track: Comparative Ruby\n- id: \"james-coglan-rubyconf-2016\"\n  title: \"Why Recursion Matters\"\n  raw_title: \"RubyConf 2016 - Why recursion matters by James Coglan\"\n  speakers:\n    - James Coglan\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Why recursion matters by James Coglan\n\n    In modern programming, recursion is so common that we take it for granted. We work with recursive processes and structures every day, and it's easy to forget that recursion was once a highly contentious issue in programming language design.\n\n    But there's more to recursion than meets the eye. In this talk I'll discuss how it is fundamental to computing; how it can prove programs are correct, make them run faster, and even let you run programs backwards! Along the way we'll meet maths, Haskell, Bash, JavaScript, and our old friend Ruby doing some very surprising things.\n  video_provider: \"youtube\"\n  video_id: \"qhwG2B77fQk\"\n  track: \"Comparative Ruby\"\n\n# ---\n\n# Track: Tools and Toys\n- id: \"ryan-davis-rubyconf-2016\"\n  title: \"Improving Coverage Analysis\"\n  raw_title: \"RubyConf 2016 - Improving Coverage Analysis by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Improving Coverage Analysis by Ryan Davis\n\n    If you follow modern practices, test coverage analysis is a lie, plain and simple. What it reports is a false positive and leaves you with a false sense of security, vulnerable to regression, and unaware that this is even the case. Come figure out how this happens, why it isn’t your fault, and how coverage analysis can be improved.\n  video_provider: \"youtube\"\n  video_id: \"ljTO3HDw1sI\"\n  track: \"Tools and Toys\"\n\n# Track: General 1\n- id: \"eric-weinstein-rubyconf-2016\"\n  title: \"Dōmo Arigatō, Mr. Roboto: Machine Learning with Ruby\"\n  raw_title: \"RubyConf 2016 - Dōmo arigatō, Mr. Roboto: Machine Learning with Ruby by Eric Weinstein\"\n  speakers:\n    - Eric Weinstein\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Dōmo arigatō, Mr. Roboto: Machine Learning with Ruby by Eric Weinstein\n\n    Machine learning is a popular and rapidly growing field\n    these days, but you don't usually hear it mentioned in the same breath as Ruby.\n    Many developers assume that if you want to do machine learning or computer vision,\n    you've got to do it in Python or Java. Not so! In this talk, we'll walk through\n    training a neural network written in Ruby on the MNIST dataset, then develop an\n    application to use that network to classify handwritten numbers.\n  video_provider: \"youtube\"\n  video_id: \"T1nFQ49TyeA\"\n\n# Track: Ruby Deep Dive\n- id: \"guyren-g-howe-rubyconf-2016\"\n  title: \"Keyword Args — The Killer Ruby Feature You Aren't Using\"\n  raw_title: \"RubyConf 2016 - Keyword Args — the killer Ruby feature you aren't using by  Guyren G. Howe\"\n  speakers:\n    - Guyren G. Howe\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Keyword Args — the killer Ruby feature you aren't using by  Guyren G. Howe\n\n    Write clearer code more easily. Write functions that are more composable and flexible.\n\n    Ruby 2.0's KWArgs feature isn't just an easier way to write functions that take keyword arguments; KWArgs turn Ruby into a lean, mean Hash processing machine.\n\n    In this talk, you'll learn the details of how to write the next generation of Ruby code. Code that is easier to read, easier to write, more flexible and easier to change, all based on this one simple Ruby feature.\n  video_provider: \"youtube\"\n  video_id: \"4e-_bbFjPRg\"\n  track: \"Ruby Deep Dive\"\n\n# Track: Comparative Ruby\n- id: \"phill-mv-rubyconf-2016\"\n  title: \"To Clojure and Back: Writing and Rewriting in Ruby\"\n  raw_title: \"RubyConf 2016 - To Clojure and back: writing and rewriting in Ruby by Phill MV\"\n  speakers:\n    - Phill MV\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - To Clojure and back: writing and rewriting in Ruby by Phill MV\n\n    Act 1 - State of Grace\n\n    After many years of Ruby, we built our app in Clojure, why not. Clojure is a breath of fresh air. Learn a lisp today!\n\n    Act 2 - The Fall\n\n    It's harder to succeed when you're in a new and different ecosystem. How Clojure contrasts with Ruby.\n\n    Act 3 - The Wilderness\n\n    Rewriting your app is a bad idea but we did it anyways. How we came to that decision.\n\n    Act 4 - Reconciliation\n\n    How I write Ruby has changed: a discussion.\n  video_provider: \"youtube\"\n  video_id: \"doZ0XAc9Wtc\"\n  track: \"Comparative Ruby\"\n\n# Break\n\n# Track: General 1\n- id: \"lito-nicolai-rubyconf-2016\"\n  title: \"Rainbows! Color Theory for Computers\"\n  raw_title: \"RubyConf 2016 - Rainbows! Color Theory for Computers by Lito Nicolai\"\n  speakers:\n    - Lito Nicolai\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Rainbows! Color Theory for Computers by Lito Nicolai\n\n    We often use color as a way to add information, whether in design, in UX, or for visualizations. When we visualize information, what's the best possible color scheme to use? How can we display the most possible information?\n\n    The only way to know is to explore the nature of color! We'll build up to the color-handling code that exists in 'graphics.rb', a Ruby-language visualizations library. For free, we'll end up with intuitive models of computer color spaces and tricks for how to think about common color concepts like gradients and paint mixing.\n  video_provider: \"youtube\"\n  video_id: \"pGGY5P9ZCUA\"\n\n# Track: General 2\n- id: \"gavin-mcgimpsey-rubyconf-2016\"\n  title: \"Problem Solved! Using Logic Programming to Find Answers\"\n  raw_title: \"RubyConf 2016 - Problem Solved! Using Logic Programming to Find Answers by Gavin McGimpsey\"\n  speakers:\n    - Gavin McGimpsey\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Problem Solved! Using Logic Programming to Find Answers by Gavin McGimpsey\n\n    We love Ruby's object orientation, and you might have heard functional programming is the new hotness. But don't leave home without one more paradigm! Logic programs express relations and constraints, allowing us to work with incomplete information, build knowledge systems, and find outputs of a system given whatever inputs are available.\n\n    You'll see examples of logic programs using Ruby, learn about an algorithm that searches for a solution in a finite problem space, and explore potential applications for logic programming approaches, both in practical areas and for your mental models.\n  video_provider: \"youtube\"\n  video_id: \"f5Bi6_GOIB8\"\n\n# Track: Ruby Deep Dive\n- id: \"haseeb-qureshi-rubyconf-2016\"\n  title: \"Lies, Damned Lies, and Substrings\"\n  raw_title: \"RubyConf 2016 - Lies, Damned Lies, and Substrings by Haseeb Qureshi\"\n  speakers:\n    - Haseeb Qureshi\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Lies, Damned Lies, and Substrings by Haseeb Qureshi\n\n    Generate all of the substrings of a string—a classic coding problem. But what's its time complexity? In many languages this is a pretty straightforward question, but in Ruby it turns out, it depends.\n\n    Follow me into the matrix as I explore copy-on-write optimization, how substrings are created in MRI, and eventually create a custom build of Ruby to try to speed up this classic coding problem. This talk will be a mix of computer science and a deep dive into how Ruby strings work in MRI.\n  video_provider: \"youtube\"\n  video_id: \"piLmdh3Am3o\"\n  track: \"Ruby Deep Dive\"\n\n# Track: General 3\n- id: \"colin-jones-rubyconf-2016\"\n  title: \"Diving into the Details with DTrace\"\n  raw_title: \"RubyConf 2016 - Diving into the Details with DTrace by Colin Jones\"\n  speakers:\n    - Colin Jones\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Diving into the Details with DTrace by Colin Jones\n    \"Argh, why is this so slow?!\" We've all asked questions like this without getting satisfying answers. And so we slog along, finding workarounds and architecting around the slow bits.\n\n    But what if we had a friend who could see things we can't? Someone who could say whether our guesses were right, and what to look at next?\n\n    DTrace is that friend, and it's here to help! In this talk, I'll show you how DTrace can answer incredibly general and specific questions about systems performance, and help us to generate new ones. Along the way, we'll see that it's easier to use than you might think!\n  video_provider: \"youtube\"\n  video_id: \"ZzYyl5vAWcA\"\n\n# ---\n\n- id: \"jeffrey-cohen-rubyconf-2016\"\n  title: \"Computer Science: The Good Parts\"\n  raw_title: \"RubyConf 2016 - Computer Science: The Good Parts by Jeffrey Cohen\"\n  speakers:\n    - Jeffrey Cohen\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-10\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Computer Science: The Good Parts by Jeffrey Cohen\n\n    You don't need a 4-year degree to learn the best parts of computer science. Maybe you've seen jargon like \"Big O Notation,\" \"binary trees\", \"graph theory\", \"map-reduce\", or the \"Turing test\", but have been afraid to ask. But did you know that that these concepts are responsible for Mars rovers, self-driving cars, mobile databases, our air traffic control system, and and even how we elect presidents? In this beginner-focused talk, I will present some simple and very practical ways apply the \"good parts\" of computer science to your next app.\n  video_provider: \"youtube\"\n  video_id: \"4V2kwMSDEsE\"\n\n## Day 2 - 2016-11-11\n\n- id: \"tara-scherner-de-la-fuente-rubyconf-2016\"\n  title: \"You Have the Empathy of a Goat: Documenting for the User\"\n  raw_title: \"RubyConf 2016 - You Have the Empathy of a Goat... by Tara Scherner De La Fuente\"\n  speakers:\n    - Tara Scherner de la Fuente\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - You Have the Empathy of a Goat: Documenting for the User by Tara Scherner de la Fuente\n    Are you the sort of developer who makes the user want to headbutt the computer or hop happily sideways? Documentation is often one of the least favorite activities of a developer, and it’s probably always going to suck for some people. But it doesn’t have to give you the bleat-down. We’ll cover: how to discover what the user wants, how to convey what the user needs, what we’re doing wrong, and then we’ll outline the winning formula. If things go really well with your empathetic documentation, you can reduce costs, justify a salary increase, and even become famous. No, really. I’m not KIDding.\n  video_provider: \"youtube\"\n  video_id: \"0Szd52CY9hE\"\n\n# ---\n\n# Track: Ruby and Hardware\n- id: \"shashank-dat-rubyconf-2016\"\n  title: \"(m)Ruby on Small Devices\"\n  raw_title: \"RubyConf 2016 - (m)Ruby on small devices by Shashank Daté\"\n  speakers:\n    - Shashank Daté\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - (m)Ruby on small devices by Shashank Daté\n\n    mruby is the lightweight implementation of the Ruby language for linking and embedding within your applications. This talk will show how it can be used on small resource constrained devices like Raspberry Pi Zero and exploring some techniques of memory and run-time optimizations.\n  video_provider: \"youtube\"\n  video_id: \"0q2HRwP7Vzo\"\n  track: \"Ruby and Hardware\"\n\n# Track: Testing\n- id: \"betsy-haibel-rubyconf-2016\"\n  title: \"Better Code Through Boring(er) Tests\"\n  raw_title: \"RubyConf 2016 - Better Code Through Boring(er) Tests by Betsy Haibel\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Better Code Through Boring(er) Tests by Betsy Haibel\n\n    Your tests are annoying. Whenever you update your application code, you need to change a lot of them. You've built yourself some test macros, and some nice FactoryGirl factories, and installed this really cool matcher gem... and your tests are still annoying. What if you changed your application code instead? In this talk, you'll learn what \"listening to your tests\" means in the real world: no mysticism, no arrogant TDD purism, just a few practical refactorings you can use tomorrow at work.\n  video_provider: \"youtube\"\n  video_id: \"tTQpD3o_FAw\"\n  track: \"Testing\"\n\n# Track: General 1\n- id: \"andr-arko-rubyconf-2016\"\n  title: \"From no OSS Experience to the Core Team in 15 Minutes a Day\"\n  raw_title: \"RubyConf 2016 - From no OSS experience to the core team in 15 minutes a day by André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - From no OSS experience to the core team in 15 minutes a day by André Arko\n\n    Using and contributing to open source has been a cornerstone of the Ruby community for many years. Despite this strong tradition, it’s hard to find anything collecting the likely advantages and costs of working on open source. This talk will introduce open source work, the benefits and costs of doing that work, and then provide a straightforward list of activities that can be done by anyone, no matter their level of experience with programming. Pick a project, schedule at least 15 minutes per day, join the core team. It’s your destiny!\n  video_provider: \"youtube\"\n  video_id: \"6jUe-9Y__KM\"\n\n# Track: Lessons Learned\n- id: \"paulette-luftig-rubyconf-2016\"\n  title: \"Finding Your Edge Through a Culture of Feedback\"\n  raw_title: \"RubyConf 2016 - Finding your edge through a culture of feedback by Paulette Luftig\"\n  speakers:\n    - Paulette Luftig\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Finding your edge through a culture of feedback by Paulette Luftig\n\n    Have you ever wished for more feedback from colleagues to help you get better at your job? When’s the last time you offered helpful feedback to someone else? Imagine an entire company fluent in the daily practice of giving and receiving constructive feedback. Would your experience improve? What does a team lose when feedback doesn’t flow?\n\n    Feedback conversations can be difficult. But giving and receiving feedback pushes us to the edge of our growth potential, where the biggest payoffs occur. Join this session to grow your career by learning how to get real.\n  video_provider: \"youtube\"\n  video_id: \"EkLdO-SphxA\"\n  track: \"Lessons Learned\"\n\n# ---\n\n# Track: Ruby and Hardware\n- id: \"jonan-scheffler-rubyconf-2016\"\n  title: \"Building HAL: Running Ruby with Your Voice\"\n  raw_title: \"RubyConf 2016 - Building HAL: Running Ruby with Your Voice by Jonan Scheffler\"\n  speakers:\n    - Jonan Scheffler\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Building HAL: Running Ruby with Your Voice by Jonan Scheffler\n\n    We’ve been living in the future for a full 15 years already and developers are still using antiquated technology like “keyboards” and “mice” to run their applications.\n\n    We’re going to learn to use voice recognition to run our Ruby code so we won’t need to depend on archaic plastic input methods to live our megalomaniacal dreams.\n\n    I think we can all agree that the world needs more robots listening to our every word, let’s build an army of them and arm them with Ruby!\n  video_provider: \"youtube\"\n  video_id: \"znvpPsLBZyg\"\n  track: \"Ruby and Hardware\"\n\n# Track: Testing\n- id: \"justin-searls-rubyconf-2016\"\n  title: \"Surgically Refactoring Ruby with Suture\"\n  raw_title: \"RubyConf 2016 - Surgically Refactoring Ruby with Suture by Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Surgically Refactoring Ruby with Suture by Justin Searls\n\n    The next feature means changing legacy code. The estimate just says \"PAIN\" in red ink. Your hands tremble as you claim the card from the wall.\n\n    For all of Ruby's breakthroughs, refactoring is as painful as 2004, when Feathers' book released. It's time we Make Refactors Great Again.\n\n    That's why I wrote Suture, a gem to help at every step:\n\n    In development, new code is verified against recorded calls\n    In staging, old & new code is ensured side-by-side\n    In production, unexpected errors fall back to the old code\n    With renewed confidence and without fear, you grab the card. You've got this.\n  video_provider: \"youtube\"\n  video_id: \"pBginuIW2WU\"\n  track: \"Testing\"\n\n# Track: General 1\n- id: \"eleanor-mchugh-rubyconf-2016\"\n  title: \"Implementing Virtual Machines in Ruby (and C)\"\n  raw_title: \"RubyConf 2016 - Implementing Virtual Machines in Ruby (and C) by Eleanor McHugh\"\n  speakers:\n    - Eleanor McHugh\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Implementing Virtual Machines in Ruby (and C) by Eleanor McHugh\n\n    Most of us who've played games or worked in any one of a number of popular programming languages will have used virtual machines but unless we've taken a course in programming language design we probably have only a loose idea of what these are and how they work.\n\n    In this talk I'll look at the various parts necessary to model a computer-like machine in code, borrowing ideas as I go from real-world hardware design. We'll use a mixture of C and Ruby as our modelling languages: C is the lingua franca of the VM world whilst Ruby is the language which brought us monkey-patching...\n  video_provider: \"youtube\"\n  video_id: \"wN-pNr2arxI\"\n\n# Track: Lessons Learned\n- id: \"john-dewyze-rubyconf-2016\"\n  title: \"My Meta Moments\"\n  raw_title: \"RubyConf 2016 - My Meta Moments by John Dewyze\"\n  speakers:\n    - John DeWyze\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - My Meta Moments by John Dewyze\n\n    Meta-programming is alluring. To write code that writes more code sounds like the peak of efficiency, but learning it is filled with infinite loops and confusing stack traces. It is a place with lots of hair pulling and endless puts debugging.\n\n    Meta-programming in ruby can be intimidating. Yet, even with all that, it is fun. It is learnable. It is quintessentially ruby. If you’re interested in getting your feet wet, come share my journey of learning things like method dispatch, BasicObject, class ancestry, and the joy of things you should think twice about before doing in production code.\n  video_provider: \"youtube\"\n  video_id: \"0OAgZBNIixU\"\n  track: \"Lessons Learned\"\n\n# Lunch\n\n# Track: Ruby and Hardware\n- id: \"greg-baugues-rubyconf-2016\"\n  title: \"How I Taught My Dog To Text Selfies\"\n  raw_title: \"RubyConf 2016 - How I Taught My Dog To Text Selfies by Greg Baugues\"\n  speakers:\n    - Greg Baugues\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - How I Taught My Dog To Text Selfies by Greg Baugues\n\n    This talk is for the Rubyist who wants to get into hardware hacking but feels intimidated or unsure of where to start. The Arduino Yun is wifi-enabled and runs a stripped-down version of Linux. That means that you can build hardware hacks that execute Ruby scripts and interact with web APIs. In this talk, we'll start from scratch and live code a hardware hack that my dog uses to text me selfies using a webcam, Twilio, and a big red button.\n  video_provider: \"youtube\"\n  video_id: \"7ysfTZT_-tY\"\n  track: \"Ruby and Hardware\"\n\n# Track: Testing\n- id: \"noel-rappin-rubyconf-2016\"\n  title: \"Test Doubles are Not To Be Mocked\"\n  raw_title: \"RubyConf 2016 - Test Doubles are Not To Be Mocked by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Test Doubles are Not To Be Mocked by Noel Rappin\n\n    Test doubles (which you may know under the alias “mock objects”) are the most misunderstood and misused testing tools we've got. Starting with the fact that nobody can agree on what to call them. Contrary to what you may have heard, test doubles do not inherently lead to fragile tests. What they do is hold up a harsh mirror to the assumptions in our code. They are the light saber of testing tools: a more elegant weapon for a more civilized age. But be careful not to cut your code in half, so to speak. Herein: a guide to using test doubles without losing your sanity.\n  video_provider: \"youtube\"\n  video_id: \"qgZu6vEuqBU\"\n  track: \"Testing\"\n\n# Track: Performance\n- id: \"koichi-sasada-rubyconf-2016\"\n  title: \"Ruby 3 Concurrency\"\n  raw_title: \"RubyConf 2016 - Ruby 3 Concurrency by Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Ruby 3 Concurrency by Koichi Sasada\n\n    Learn from Koichi about the work he's doing to bring a new concurrency model to Ruby 3!\n  video_provider: \"youtube\"\n  video_id: \"mjzmUUQWqco\"\n  track: \"Performance\"\n\n# Track: Lessons Learned\n- id: \"rashaun-stovall-rubyconf-2016\"\n  title: \"Why Is Open Source So Closed?\"\n  raw_title: \"RubyConf 2016 - Why Is Open Source So Closed? by Ra'Shaun Stovall\"\n  speakers:\n    - Ra'Shaun Stovall\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Why Is Open Source So Closed? by Ra'Shaun Stovall\n\n    Why is Open Source So Closed? With the rapidly increasing amount of students coming out of bootcamp schools we have now created a gap within our communities of the \"haves\", and the \"Looking for job\"s. Being the organizer of New York City's 4,500+ member Ruby community with NYC.rb I have discovered ways we can ensure the generations of rubyists after us have a path paved before them. \"Cyclical Mentorship\" is the answer. Best part is we will know individually how we can immediately begin the feedback loop of not computers, but people!\n  video_provider: \"youtube\"\n  video_id: \"A5ad52AogJ8\"\n  track: \"Lessons Learned\"\n\n# ---\n\n# Track: Ruby and Hardware\n- id: \"julian-cheal-rubyconf-2016\"\n  title: \"It's More Fun to Compute\"\n  raw_title: \"RubyConf 2016 - It's More Fun to Compute by Julian Cheal\"\n  speakers:\n    - Julian Cheal\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - It's More Fun to Compute by Julian Cheal\n\n    Come with us now on a journey through time and space. As we explore the world of analog/digital synthesis. From computer generated music to physical synthesisers and everything in between.\n\n    So you want to write music with code, but don’t know the difference between an LFO, ADSR, LMFAO, etc. Or a Sine wave, Saw wave, Google wave. We’ll explore what these mean, and how Ruby can be used to make awesome sounds. Ever wondered what Fizz Buzz sounds like, or which sounds better bubble sort or quick sort? So hey Ruby, let’s make music!\n  video_provider: \"youtube\"\n  video_id: \"v3wYX-HSkr0\"\n  track: \"Ruby and Hardware\"\n\n# Track: General 1\n- id: \"adam-forsyth-rubyconf-2016\"\n  title: \"Ruby for Home-Ec\"\n  raw_title: \"RubyConf 2016 - Ruby for Home-Ec by Adam  Forsyth\"\n  speakers:\n    - Adam Forsyth\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Ruby for Home-Ec by Adam  Forsyth\n\n    Come learn how to design your own algorithms and code to solve problems around the house. Trying to use your scrap wood efficiently? Want to sort your pantry to maximize variety? I’ll talk about the problem-solving process, walk through code, and touch on the computer science behind it all.\n  video_provider: \"youtube\"\n  video_id: \"iosgoDJl8VY\"\n\n# Track: Performance\n- id: \"chris-seaton-rubyconf-2016\"\n  title: \"Ruby’s C Extension Problem and How We're Solving It\"\n  raw_title: \"RubyConf 2016 - Ruby’s C Extension Problem and How We're Solving It by Chris Seaton\"\n  speakers:\n    - Chris Seaton\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Ruby’s C Extension Problem and How We're Solving It by Chris Seaton\n\n    Ruby’s C extensions have so far been the best way to improve the performance of Ruby code. Ironically, they are now holding performance back, because they expose the internals of Ruby and mean we aren’t free to make major changes to how Ruby works.\n\n    In JRuby+Truffle we have a radical solution to this problem – we’re going to interpret the source code of your C extensions, like how Ruby interprets Ruby code. Combined with a JIT this lets us optimise Ruby but keep support for C extensions.\n  video_provider: \"youtube\"\n  video_id: \"YLtjkP9bD_U\"\n  track: \"Performance\"\n\n# Track: General 2\n- id: \"sean-marcia-rubyconf-2016\"\n  title: \"Ruby, Red Pandas, and You\"\n  raw_title: \"RubyConf 2016 - Ruby, Red Pandas, and You by Sean Marcia\"\n  speakers:\n    - Sean Marcia\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Ruby, Red Pandas, and You by Sean Marcia\n\n    Red pandas are adorable, playful, curious, and super cute. Unfortunately, they are in serious trouble. Over 50% of red panda newborns born in captivity do not survive long enough to leave their den and no one knows why. Come find out why red pandas are so amazing, how I met a Smithsonian Zoo researcher studying this and how we’re solving this important problem using Ruby and machine learning. You will also leave this talk knowing how you can get involved (no matter your skill level) with great projects like this.\n  video_provider: \"youtube\"\n  video_id: \"jm9gEhXFUro\"\n\n# ---\n\n# Track: Ruby and Hardware\n- id: \"coraline-clark-rubyconf-2016\"\n  title: \"Programming in the Small: Kids, Chickens, and Ruby\"\n  raw_title: \"RubyConf 2016 - Programming in the Small: Kids, Chickens, and Ruby by Coraline Clark & Jason Clark\"\n  speakers:\n    - Coraline Clark\n    - Jason Clark\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Programming in the Small: Kids, Chickens, and Ruby by Coraline Clark & Jason Clark\n\n    After several years of programming in Ruby using Shoes, my daughter and I were hunting for a new project. Something more useful than a game. Something with a real-world connection. Then it struck us: Chickens!\n\n    Join us as we show you how we built our coop monitoring system. It’ll be a wild ride of hardware hacking, weather-proofing, and father-daughter bonding, with Ruby sprinkled throughout. You’ll learn how to modernize your surroundings, and about engaging the young people in your life in technology along the way.\n  video_provider: \"youtube\"\n  video_id: \"Iah2t1_iSYE\"\n  track: \"Ruby and Hardware\"\n\n# Track: General 1\n- id: \"thomas-e-enebo-rubyconf-2016\"\n  title: \"JRuby Everywhere! Server, Client, and Embedded\"\n  raw_title: \"RubyConf 2016 - JRuby Everywhere! Server, Client, and Embedded by Thomas Enebo\"\n  speakers:\n    - Thomas E Enebo\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - JRuby Everywhere! Server, Client, and Embedded by Thomas Enebo\n\n    Ruby has seen its heaviest on servers; Client-side Ruby has been limited to experiments and toys, and Ruby C extensions complicate embedded use. But there's a better way: JRuby. Using frameworks like JRubyFX and Shoes 4, among many GUI and graphics libraries, JRuby makes client-side development fast and powerful. With an embedded JVM, JRuby runs your app on mid-level embedded devices without compiling a line of code. And JRuby is still the best way to power up your Rails 5 app. Come learn how to use JRuby everwhere!\n  video_provider: \"youtube\"\n  video_id: \"Xl7LVkvSnoc\"\n\n# Track: Performance\n- id: \"richard-schneeman-rubyconf-2016\"\n  title: \"Slo Mo\"\n  raw_title: \"RubyConf 2016 - Slo Mo by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Slo Mo by Richard Schneeman\n\n    No one wants to be stuck in the slow lane, especially Rubyists. In this talk we'll look at the slow process of writing fast code. We'll look at several real world performance optimizations that may surprise you. We'll then rewind to see how these slow spots were found and fixed. Come to this talk and we will \"C\" how fast your Ruby can \"Go\".\n  video_provider: \"youtube\"\n  video_id: \"xii1oyad_kc\"\n  track: \"Performance\"\n\n# Track: General 2\n- id: \"stella-cotton-rubyconf-2016\"\n  title: \"The Little Server That Could\"\n  raw_title: \"RubyConf 2016 - The Little Server That Could by Stella Cotton\"\n  speakers:\n    - Stella Cotton\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - The Little Server That Could by Stella Cotton\n\n    Have you ever wondered what dark magic happens when you start up your Ruby server? Let’s explore the mysteries of the web universe by writing a tiny web server in Ruby! Writing a web server lets you dig deeper into the Ruby Standard Library and the Rack interface. You’ll get friendlier with I/O, signal trapping, file handles, and threading. You’ll also explore dangers first hand that can be lurking inside your production code- like blocking web requests and shared state with concurrency.\n  video_provider: \"youtube\"\n  video_id: \"AFgDPssfZ9k\"\n\n# Break\n\n# Track: Ruby and Hardware\n- id: \"lee-edwards-rubyconf-2016\"\n  title: \"Running Global Manufacturing on Ruby (among other things)\"\n  raw_title: \"RubyConf 2016 - Running Global Manufacturing on Ruby (among other things) by Lee Edwards\"\n  speakers:\n    - Lee Edwards\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Running Global Manufacturing on Ruby (among other things) by Lee Edwards\n\n    A few miles from this convention center, Teespring prints millions of short-run custom products every year from modern direct-to-garment printers and ships them all over the world. Like most companies, Teespring's architecture is polyglot, but the core business logic is in Ruby. We'll discuss how we use large at-scale manufacturing and production systems to help anyone, anywhere turn their ideas into reality.\n  video_provider: \"youtube\"\n  video_id: \"fbNfz_Npbic\"\n  track: \"Ruby and Hardware\"\n\n# Track: General 1\n- id: \"brandon-hays-rubyconf-2016\"\n  title: \"The Long Strange Trip of a Senior Developer\"\n  raw_title: \"RubyConf 2016 - The long strange trip of a senior developer by Brandon Hays\"\n  speakers:\n    - Brandon Hays\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - The long strange trip of a senior developer by Brandon Hays\n\n    Have you ever felt like you are in the passenger seat of your career? By simply looking around and seeing how few 20+ year veterans you work with, you're actually staring our industry's sustainability problem right in the face. But the software industry needs you still contributing 20 years from now! Fret not, we can start fixing these problems, right now, in your own job.\n\n    Using in-depth research across companies of all sizes, you'll come away with a plan to start designing a sustainable career track to help you grow in skill, influence, and income now and long into the future.\n  video_provider: \"youtube\"\n  video_id: \"egntf0nykzk\"\n\n# Track: Performance\n- id: \"nate-berkopec-rubyconf-2016\"\n  title: \"Halve Your Memory Usage With These 12 Weird Tricks\"\n  raw_title: \"RubyConf 2016 - Halve Your Memory Usage With These 12 Weird Tricks\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 -  Halve Your Memory Usage With These 12 Weird Tricks by Nate Berkopec\n\n    How does Ruby allocate memory? Ever wonder why that poor application of yours is using hundreds of megabytes of RAM? Ruby's garbage collector means that we don't have to worry about allocating memory in our programs, but an understanding of how C Ruby uses memory can help us avoid bloat and even write faster programs. We'll talk about what causes memory allocation, how the garbage collector works, and how to measure memory activity in our own Ruby programs.\n  video_provider: \"youtube\"\n  video_id: \"kZcqyuPeDao\"\n  track: \"Performance\"\n\n# Track: General 2\n- id: \"cheryl-gore-schaefer-rubyconf-2016\"\n  title: \"Grow Your Team In 90 Days\"\n  raw_title: \"RubyConf 2016 - Grow Your Team In 90 Days by Cheryl Gore Schaefer\"\n  speakers:\n    - Cheryl Gore Schaefer\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    RubyConf 2016 - Grow Your Team In 90 Days by Cheryl Gore Schaefer\n\n    So you want to work with an awesome ruby developer? Great! But finding one is hard. It’s much easier to hire that apprentice or bootcamp grad, but that person is not an awesome developer. How do you help them get there?\n\n    You will learn how to build a learning plan and become the best mentor to a budding software developer. You have the opportunity to mold your apprentice’s skill set into exactly what you need, while benefiting from their diverse skills and experiences. We will build an example learning plan of a developer learning Ruby, showing clear and specific choices and likely outcomes.\n  video_provider: \"youtube\"\n  video_id: \"pHABlefSVZk\"\n\n# ---\n\n- id: \"lightning-talks-rubyconf-2016\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf 2016 - Lightning Talks by Various Presenters\"\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-11\"\n  published_at: \"2016-11-21\"\n  description: |-\n    A lightning talk is a short presentation (up to 5 mins) on your chosen topic.\n  video_provider: \"youtube\"\n  video_id: \"SswGJpZVNFg\"\n  talks:\n    - title: \"Lightning Talk: André Arko\" # TODO: missing talk title\n      start_cue: \"00:00:00\"\n      end_cue: \"00:01:26\"\n      id: \"andre-arko-lighting-talk-rubyconf-2016\"\n      video_id: \"andre-arko-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - André Arko\n\n    - title: \"Lightning Talk: Francois Lapierre Messier\" # TODO: missing talk title\n      start_cue: \"00:01:26\"\n      end_cue: \"00:02:12\"\n      id: \"francois-lapierre-messier-lighting-talk-rubyconf-2016\"\n      video_id: \"francois-lapierre-messier-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Francois Lapierre Messier\n\n    - title: \"Lightning Talk: Sam Phippen\" # TODO: missing talk title\n      start_cue: \"00:02:12\"\n      end_cue: \"00:06:05\"\n      id: \"sam-phippen-lighting-talk-rubyconf-2016\"\n      video_id: \"sam-phippen-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Sam Phippen\n\n    - title: \"Lightning Talk: Caroline Jobe\" # TODO: missing talk title\n      start_cue: \"00:06:05\"\n      end_cue: \"00:10:07\"\n      id: \"caroline-jobe-lighting-talk-rubyconf-2016\"\n      video_id: \"caroline-jobe-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Caroline Jobe\n\n    - title: \"Lightning Talk: Jen Pengelly\" # TODO: missing talk title\n      start_cue: \"00:10:07\"\n      end_cue: \"00:13:31\"\n      id: \"jen-pengelly-lighting-talk-rubyconf-2016\"\n      video_id: \"jen-pengelly-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Jen Pengelly\n\n    - title: \"Lightning Talk: Starr Chen\" # TODO: missing talk title\n      start_cue: \"00:13:31\"\n      end_cue: \"00:18:22\"\n      id: \"starr-chen-lighting-talk-rubyconf-2016\"\n      video_id: \"starr-chen-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Starr Chen\n\n    - title: \"Lightning Talk: Olivia Brundage\" # TODO: missing talk title\n      start_cue: \"00:18:22\"\n      end_cue: \"00:20:46\"\n      id: \"olivia-brundage-lighting-talk-rubyconf-2016\"\n      video_id: \"olivia-brundage-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Olivia Brundage\n\n    - title: \"Lightning Talk: Kate Rezentes\" # TODO: missing talk title\n      start_cue: \"00:20:46\"\n      end_cue: \"00:23:20\"\n      id: \"kate-rezentes-lighting-talk-rubyconf-2016\"\n      video_id: \"kate-rezentes-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Kate Rezentes\n\n    - title: \"Lightning Talk: Amy Howes\" # TODO: missing talk title\n      start_cue: \"00:23:20\"\n      end_cue: \"00:28:26\"\n      id: \"amy-howes-lighting-talk-rubyconf-2016\"\n      video_id: \"amy-howes-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Amy Howes\n\n    - title: \"Lightning Talk: Assaf Hefetz\" # TODO: missing talk title\n      start_cue: \"00:28:26\"\n      end_cue: \"00:33:45\"\n      id: \"assaf-hefetz-lighting-talk-rubyconf-2016\"\n      video_id: \"assaf-hefetz-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Assaf Hefetz\n\n    - title: \"Lightning Talk: Miki Rezentes\" # TODO: missing talk title\n      start_cue: \"00:33:45\"\n      end_cue: \"00:38:52\"\n      id: \"miki-rezentes-lighting-talk-rubyconf-2016\"\n      video_id: \"miki-rezentes-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Miki Rezentes\n\n    - title: \"Lightning Talk: Michael Hartl\" # TODO: missing talk title\n      start_cue: \"00:38:52\"\n      end_cue: \"00:43:44\"\n      id: \"michael-hartl-lighting-talk-rubyconf-2016\"\n      video_id: \"michael-hartl-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Hartl\n\n    - title: \"Lightning Talk: James Thompson\" # TODO: missing talk title\n      start_cue: \"00:43:44\"\n      end_cue: \"00:48:00\"\n      id: \"james-thompson-lighting-talk-rubyconf-2016\"\n      video_id: \"james-thompson-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - James Thompson\n\n    - title: \"Lightning Talk: Victoria Gonda\" # TODO: missing talk title\n      start_cue: \"00:48:00\"\n      end_cue: \"00:52:17\"\n      id: \"victoria-gonda-lighting-talk-rubyconf-2016\"\n      video_id: \"victoria-gonda-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Victoria Gonda\n\n    - title: \"Lightning Talk: Jonathon Slate\" # TODO: missing talk title\n      start_cue: \"00:52:17\"\n      end_cue: \"00:56:22\"\n      id: \"jonathon-slate-lighting-talk-rubyconf-2016\"\n      video_id: \"jonathon-slate-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Jonathon Slate\n\n    - title: \"Lightning Talk: Michael Cain\" # TODO: missing talk title\n      start_cue: \"00:56:22\"\n      end_cue: \"00:58:54\"\n      id: \"michael-cain-lighting-talk-rubyconf-2016\"\n      video_id: \"michael-cain-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Cain\n\n    - title: \"Lightning Talk: Jamie Gaskins\" # TODO: missing talk title\n      start_cue: \"00:58:54\"\n      end_cue: \"01:03:57\"\n      id: \"jamie-gaskins-lighting-talk-rubyconf-2016\"\n      video_id: \"jamie-gaskins-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Jamie Gaskins\n\n    - title: \"Lightning Talk: Yurie Yamane\" # TODO: missing talk title\n      start_cue: \"01:03:57\"\n      end_cue: \"01:09:02\"\n      id: \"yurie-yamane-lighting-talk-rubyconf-2016\"\n      video_id: \"yurie-yamane-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Yurie Yamane\n\n    - title: \"Lightning Talk: Kei Nawanda\" # TODO: missing talk title\n      start_cue: \"01:09:02\"\n      end_cue: \"01:14:24\"\n      id: \"kei-nawanda-lighting-talk-rubyconf-2016\"\n      video_id: \"kei-nawanda-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Kei Nawanda\n\n    - title: \"Lightning Talk: Ryder Timberlake\" # TODO: missing talk title\n      start_cue: \"01:14:24\"\n      end_cue: \"01:19:18\"\n      id: \"ryder-timberlake-lighting-talk-rubyconf-2016\"\n      video_id: \"ryder-timberlake-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Ryder Timberlake\n\n    - title: \"Lightning Talk: Noah Gibbs\" # TODO: missing talk title\n      start_cue: \"01:19:18\"\n      end_cue: \"01:23:51\"\n      id: \"noah-gibbs-lighting-talk-rubyconf-2016\"\n      video_id: \"noah-gibbs-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Noah Gibbs\n\n    - title: \"Lightning Talk: Chris Vannoy\" # TODO: missing talk title\n      start_cue: \"01:23:51\"\n      end_cue: \"01:24:21\"\n      id: \"chris-vannoy-lighting-talk-rubyconf-2016\"\n      video_id: \"chris-vannoy-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Vannoy\n\n    - title: \"Lightning Talk: Andrew Faraday\" # TODO: missing talk title\n      start_cue: \"01:24:21\"\n      end_cue: \"01:24:37\"\n      id: \"andrew-faraday-lighting-talk-rubyconf-2016\"\n      video_id: \"andrew-faraday-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Faraday\n\n    - title: \"Lightning Talk: Mischa Lewis\" # TODO: missing talk title\n      start_cue: \"01:24:37\"\n      end_cue: \"01:29:10\"\n      id: \"mischa-lewis-lighting-talk-rubyconf-2016\"\n      video_id: \"mischa-lewis-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Mischa Lewis\n\n    - title: \"Lightning Talk: Jeff Foster\" # TODO: missing talk title\n      start_cue: \"01:29:10\"\n      end_cue: \"01:33:39\"\n      id: \"jeff-foster-lighting-talk-rubyconf-2016\"\n      video_id: \"jeff-foster-lighting-talk-rubyconf-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeff Foster\n\n# Day 3 - 2016-11-12\n\n- id: \"cassandra-cruz-rubyconf-2016\"\n  title: \"Ruby versus The Titans of FP\"\n  raw_title: \"RubyConf 2016 - Ruby versus the Titans of FP by Cassandra Cruz\"\n  speakers:\n    - Cassandra Cruz\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Ruby versus the Titans of FP by Cassandra Cruz\n\n    Clojure, Haskell and Javascript reign as the dominant functional languages of our era. But surely anything they can do, Ruby can do better? And what is it that they actually do? Come learn about three core concepts of functional programming, and see how Ruby stacks up against its peers when it comes to making them powerful.\n  video_provider: \"youtube\"\n  video_id: \"25u-pp-7PHE\"\n\n# ---\n\n# Track: War Stories\n- id: \"mike-calhoun-rubyconf-2016\"\n  title: \"How I Corrupted Survey Results and (Maybe) Ruined a Business\"\n  raw_title: \"RubyConf 2016 - How I Corrupted Survey Results and (Maybe) Ruined a Business by Mike Calhoun\"\n  speakers:\n    - Mike Calhoun\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - How I Corrupted Survey Results and (Maybe) Ruined a Business by Mike Calhoun\n\n    It was the perfect storm of events and circumstances: a first job, naïveté of inexperience, a fear of getting fired, and a loud boss prone to yelling. One morning, I realized that the first web “project” of my first job in my new career had gone horribly off track. What came to pass in the following weeks was the most involved and tense coverup I’ve undertaken in my life. This experience can tell us all about how we communicate with each other. How we can create environments where people can ask for help and how an atmosphere of pressure and tension can ruin a business.\n  video_provider: \"youtube\"\n  video_id: \"NFkym21cl4E\"\n  track: \"War Stories\"\n\n# Track: General 1\n- id: \"byron-woodfork-rubyconf-2016\"\n  title: \"The Truth About Mentoring Minorities\"\n  raw_title: \"RubyConf 2016 - The Truth About Mentoring Minorities by Byron Woodfork\"\n  speakers:\n    - Byron Woodfork\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-18\"\n  description: |-\n    RubyConf 2016 - The Truth About Mentoring Minorities by Byron Woodfork\n\n    In the tech industry, we currently lack the ability to produce mentors who are able to effectively teach and connect with their minority protégés. In this talk, we discuss what changes we can make in the way we mentor to give our minority protégés the best chance to succeed. We will take a look at some of the struggles that I faced throughout my software developer apprenticeship, and pinpoint the sources of my success. In conjunction, we will also look at various case studies of other minority professionals who were both successful and unsuccessful in their attempts to climb the corporate ladder.\n  video_provider: \"youtube\"\n  video_id: \"1Dttd0eJG94\"\n\n# Track: Ruby Deep Dive\n- id: \"aaron-patterson-rubyconf-2016\"\n  title: \"Methods of Memory Management in MRI\"\n  raw_title: \"RubyConf 2016 - Methods of Memory Management in MRI by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-18\"\n  slides_url: \"https://speakerdeck.com/tenderlove/methods-of-memory-management-in-mri\"\n  description: |-\n    RubyConf 2016 - Methods of Memory Management in MRI by Aaron Patterson\n\n    Let's talk about MRI's GC! In this talk we will cover memory management algorithms in MRI. We will cover how objects are allocated and how they are freed. We will start by looking at Ruby's memory layout, including page allocation and object allocations within those pages. Next we'll cover collection algorithms used by MRI starting with the mark and sweep algorithm, followed by generational collection, and the tri color abstraction. Finally we'll cover experimental developments for the GC like heap splitting. Expect to leave this talk with heaps of pointers to add to your remembered set!\n  video_provider: \"youtube\"\n  video_id: \"r0UjXixkBV8\"\n  track: \"Ruby Deep Dive\"\n\n# Track: General 2\n- id: \"elizabeth-barron-rubyconf-2016\"\n  title: \"The Neuroscience and Psychology of Open Source Communities\"\n  raw_title: \"RubyConf 2016 - The Neuroscience and Psychology of Open Source Communities by Elizabeth Barron\"\n  speakers:\n    - Elizabeth Barron\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - The Neuroscience and Psychology of Open Source Communities by Elizabeth Barron\n\n    ***Contains explicit language***\n\n    Because people are complex, diverse creatures, ensuring that your open source community is healthy, vibrant, and welcoming can be challenging. The good news is, science can help you understand human thoughts and behaviors, and the complexities of interacting in a collaborative way online. We'll discuss cognitive biases, the SCARF collaboration model, the online community life cycle, and how these things interact. You'll come away from this talk with a deeper understanding of yourself, your fellow humans, & the knowledge to improve personal interactions and the open source communities you belong to.\n  video_provider: \"youtube\"\n  video_id: \"VXE42FyFFX4\"\n\n# ---\n\n# Track: War Stories\n- id: \"aja-hammerly-rubyconf-2016\"\n  title: 'Datacenter Fires and Other \"Minor\" Disasters'\n  raw_title: 'RubyConf 2016 - Datacenter Fires and Other \"Minor\" Disasters by Aja Hammerly'\n  speakers:\n    - Aja Hammerly\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Datacenter Fires and Other \"Minor\" Disasters by Aja Hammerly\n\n    Most of us have a \"that day I broke the internet\" story. Some are amusing and some are disastrous but all of these stories change how we operate going forward. I'll share the amusing stories behind why I always take a database backup, why feature flags are important, the importance of automation, and how having a team with varied backgrounds can save the day. Along the way I'll talk about a data center fire, deleting a production database, and accidentally setting up a DDOS attack against our own site. I hope that by learning from my mistakes you won't have to make them yourself.\n  video_provider: \"youtube\"\n  video_id: \"ygu45C7bMHk\"\n  track: \"War Stories\"\n\n# Track: Life Beyond Bootcamps\n- id: \"kimberly-d-barnes-rubyconf-2016\"\n  title: \"Becoming a Mid: Two Perspectives on Leveling Up\"\n  raw_title: \"RubyConf 2016 - Becoming a Mid... by Kimberly D. Barnes & Kinsey Ann Durham\"\n  speakers:\n    - Kimberly D. Barnes\n    - Kinsey Ann Durham\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-18\"\n  description: |-\n    RubyConf 2016 - Becoming a Mid: Two Perspectives on Leveling Up by Kimberly D. Barnes & Kinsey Ann Durham\n\n    What does becoming a mid-level developer mean? How can a junior set goals and make steps to achieve this? It's difficult to shed the title of 'junior', not only in your own mind, but in the minds of others. It is important to keep progressing in your career as a developer to be able to level up and no longer be seen as the junior on the team. Kim and Kinsey will provide two perspectives to enable you to leave this talk with tangible action items. They will also dive into what employers can do to help build frameworks to allow for this transition.\n  video_provider: \"youtube\"\n  video_id: \"i_RisLTNZEY\"\n  track: \"Life Beyond Bootcamps\"\n\n# Track: Ruby Deep Dive\n- id: \"shyouhei-urabe-rubyconf-2016\"\n  title: \"Optimizing Ruby Core\"\n  raw_title: \"RubyConf 2016 - Optimizing ruby core by Shyouhei Urabe\"\n  speakers:\n    - Shyouhei Urabe\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-18\"\n  description: |-\n    RubyConf 2016 - Optimizing ruby core by Shyouhei Urabe\n\n    I made ruby interpreter 10 times faster. Let me show you how\n  video_provider: \"youtube\"\n  video_id: \"MqhapcDyP00\"\n  track: \"Ruby Deep Dive\"\n\n# Track: Weird Ruby\n- id: \"justin-weiss-rubyconf-2016\"\n  title: \"Metaprogramming? Not Good Enough!\"\n  raw_title: \"RubyConf 2016 - Metaprogramming? Not good enough! by Justin Weiss\"\n  speakers:\n    - Justin Weiss\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Metaprogramming? Not good enough! by Justin Weiss\n\n    If you know how to metaprogram in Ruby, you can create methods and objects on the fly, build Domain Specific Languages, or just save yourself a lot of typing. But can you change how methods are dispatched? Can you decide that the normal inheritance rules don't apply to some object?\n\n    In order to change those core parts of the language, there can't be much difference between how a language is implemented and how it's used. In this talk, you'll make that difference smaller, building a totally extensible object model on top of Ruby, using less than a dozen new classes and methods.\n  video_provider: \"youtube\"\n  video_id: \"JOvBmhukWI0\"\n  track: \"Weird Ruby\"\n\n# Lunch\n\n# Track: War Stories\n- id: \"nickolas-means-rubyconf-2016\"\n  title: \"The Building Built on Stilts\"\n  raw_title: \"RubyConf 2016 - The Building Built on Stilts by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - The Building Built on Stilts by Nickolas Means\n\n    In the summer of 1978, structural engineer William LeMessurier got a phone call that terrified him. An undergraduate student claimed that LeMessurier's acclaimed 59-story Citicorp Center in Manhattan, just completed the year prior, was dangerously unstable under certain wind conditions. The student was right, and it was almost hurricane season.\n\n    The key to building a culture of innovation in your team is learning how to respond when mistakes inevitably happen. Let's let Bill LeMessurier teach us how to respond when it all goes wrong so that our creations can thrive despite our mistakes.\n  video_provider: \"youtube\"\n  video_id: \"-ES1wlV-8lU\"\n  track: \"War Stories\"\n\n# Track: Life Beyond Bootcamps\n- id: \"sara-simon-rubyconf-2016\"\n  title: \"Learning Fluency\"\n  raw_title: \"RubyConf 2016 - Learning Fluency by Sara Simon\"\n  speakers:\n    - Sara Simon\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-18\"\n  description: |-\n    RubyConf 2016 - Learning Fluency by Sara Simon\n\n    All languages work in formulaic ways. Cracking these formulas takes discipline, time, creativity, trial and error. But is there an overarching formula to crack these formulas? Is there a designated set of steps we can take to guarantee fluency?\n\n    In this talk, you will learn about the methods people use to learn both foreign languages and programming languages. As developers, we often just jump in and start building. Why is this? Does full immersion work best always and for everyone? What is fluency, and is it ever something we can achieve in Ruby? Let’s explore.\n  video_provider: \"youtube\"\n  video_id: \"AZlOjCZlPLU\"\n  track: \"Life Beyond Bootcamps\"\n\n# Track: Ruby Deep Dive\n- id: \"lukas-nimmo-rubyconf-2016\"\n  title: \"Seeing Metaprogramming and Lambda Function Patterns in Ruby\"\n  raw_title: \"RubyConf 2016 - Seeing Metaprogramming and Lambda Function Patterns in Ruby by Lukas Nimmo\"\n  speakers:\n    - Lukas Nimmo\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-18\"\n  description: |-\n    RubyConf 2016 - Seeing Metaprogramming and Lambda Function Patterns in Ruby by Lukas Nimmo\n\n    Metaprogramming and lambda functions in Ruby should be explained within their rightful place: living examples. You may have read tutorials on what these concepts are, but still do not understand when or why to use them. I dredged through over 50 prominent Open Source Ruby projects to bring you ten successful patterns that are used time and time again to create some of the most expressive and popular Ruby DSLs. Join me as we cover these patterns so that you can immediately begin using them in your own code to implement powerful DSLs. No vacuum-living, esoteric concepts here.\n  video_provider: \"youtube\"\n  video_id: \"poAxCd7Z0Kg\"\n  track: \"Ruby Deep Dive\"\n\n# Track: Weird Ruby\n- id: \"celeen-rusk-rubyconf-2016\"\n  title: \"Rhythmic Recursion\"\n  raw_title: \"RubyConf 2016 - Rhythmic Recursion by Celeen Rusk\"\n  speakers:\n    - Celeen Rusk\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Rhythmic Recursion by Celeen Rusk\n\n    One of the best things about multi-disciplinary work is recognizing familiar ideas in a different setting. It’s like running into an old friend while you’re on vacation halfway around the world-- “I had no idea you’d be here! It’s so great to see you!”\n\n    In this talk we’ll run into our old friend recursion in the faraway land of minimalist music, by rewriting a piece of rhythmic music in Ruby.\n  video_provider: \"youtube\"\n  video_id: \"cSPhgRgjwZs\"\n  track: \"Weird Ruby\"\n\n# ---\n\n# Track: General 1\n- id: \"ernie-miller-rubyconf-2016\"\n  title: \"Lies\"\n  raw_title: \"RubyConf 2016 - Lies by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-18\"\n  description: |-\n    RubyConf 2016 - Lies by Ernie Miller\n\n    All abstractions are lies, if they are abstractions at all, and as developers, we live our lives surrounded by them. What makes a some abstractions better than others? This will be an opinionated and empowering look at the value and nature of abstractions, with a jaunt through quantum mechanics and the nature of reality.\n\n    You know, just your average, light discussion.\n  video_provider: \"youtube\"\n  video_id: \"Avf65oHa5vc\"\n\n# Track: Life Beyond Bootcamps\n- id: \"melanie-gilman-rubyconf-2016\"\n  title: \"You Graduated From Bootcamp, Now What?\"\n  raw_title: \"RubyConf 2016 - You graduated from bootcamp, now what? by Melanie Gilman\"\n  speakers:\n    - Melanie Gilman\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-18\"\n  description: |-\n    RubyConf 2016 - You graduated from bootcamp, now what? by Melanie Gilman\n\n    Throughout bootcamp, your biggest worry was finding a job. Now that you’ve found one and you’ve started your career as a developer, what comes next? In this talk, we’ll explore what the career of a bootcamp graduate looks like a few years after the program. We’ll talk about the good and not-so-good parts of being a newly-minted developer. We’ll come away with actionable steps we can take to continue to grow as developers post-bootcamp and be happy and successful, even when we don’t have the mythical perfect job.\n  video_provider: \"youtube\"\n  video_id: \"pCnvpB9tGws\"\n  track: \"Life Beyond Bootcamps\"\n\n# Track: General 2\n- id: \"allison-mcmillan-rubyconf-2016\"\n  title: \"Even the Justice League Works Remotely\"\n  raw_title: \"RubyConf 2016 -  Even the Justice League Works Remotely by Allison McMillan\"\n  speakers:\n    - Allison McMillan\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-18\"\n  description: |-\n    RubyConf 2016 -  Even the Justice League Works Remotely by Allison McMillan\n\n    \"Remote welcome for senior level\". This appears in countless job descriptions. Remote work is largely accepted in the developer community, but often only for very experienced developers. This fear is not without cause. Sometimes hiring remote developers at any level doesn’t turn out well but there’s generally a reason for that. Newer developers can also be very successful remote workers. In this talk, you’ll learn what to look for when hiring remote developers at any level and non-senior developers will learn what characteristics to keep in mind in order to have a successful remote experience.\n  video_provider: \"youtube\"\n  video_id: \"d7Z0uS2x_cY\"\n\n# Track: Weird Ruby\n- id: \"colin-fulton-rubyconf-2016\"\n  title: \"That Works?! Quines and Other Delightfully Useless Programs\"\n  raw_title: \"RubyConf 2016 - That Works?! Quines and Other Delightfully Useless Programs by Colin Fulton\"\n  speakers:\n    - Colin Fulton\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - That Works?! Quines and Other Delightfully Useless Programs by Colin Fulton\n\n    Performance, readability and correctness are fine and dandy, but what happens when we start optimizing for whimsy, illegibility and outright silliness? Self-rewriting programs that also function as ASCII art? Yup. Rewrite any JavaScript program only using six characters? Why not?\n\n    Let's take a break from the practical and laugh at some of the most unbelievable code you've ever seen. Then let's pull out the magnifying glass to figure out how it actually works.\n\n    Learn how to read the unreadable and how to write code that—to borrow a phrase from the Ig Nobel Awards—makes people laugh, then think.\n  video_provider: \"youtube\"\n  video_id: \"DC-bjR6WeaM\"\n  track: \"Weird Ruby\"\n\n# ---\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2016-qa-with-matz\"\n  title: \"Q&A with Matz\"\n  raw_title: \"RubyConf 2016 - Matz Q&A by Yukihiro 'Matz' Matsumoto\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2016\"\n  date: \"2016-11-12\"\n  published_at: \"2016-11-17\"\n  description: |-\n    RubyConf 2016 - Matz Q&A by Yukihiro 'Matz' Matsumoto\n\n    Part of our annual tradition, Matz answers questions from Evan as well as the audience\n  video_provider: \"youtube\"\n  video_id: \"Ohs2hZBzif8\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2017/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyayGHjjxZOmVEGsxX-rczZt\"\ntitle: \"RubyConf 2017\"\nkind: \"conference\"\nlocation: \"New Orleans, LA, United States\"\ndescription: \"\"\nstart_date: \"2017-11-15\"\nend_date: \"2017-11-17\"\npublished_at: \"2017-11-28\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2017\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 29.9508941\n  longitude: -90.07583559999999\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2017/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"lightning-talks-rubyconf-2017\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf 2017: Lightning Talks\"\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"YMoa5JpjEtM\"\n  talks:\n    - title: \"Lightning Talk: Michael Hartl\" # TODO: missing talk title\n      start_cue: \"0:40\"\n      end_cue: \"1:25\"\n      id: \"michael-hartl-lighting-talk-rubyconf-2017\"\n      video_id: \"michael-hartl-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Hartl\n\n    - title: \"Lightning Talk: Jonathan Slate\" # TODO: missing talk title\n      start_cue: \"1:25\"\n      end_cue: \"2:47\"\n      id: \"jonathan-slate-lighting-talk-rubyconf-2017\"\n      video_id: \"jonathan-slate-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jonathan Slate\n\n    - title: \"Lightning Talk: Kyle Heironimus\" # TODO: missing talk title\n      start_cue: \"2:47\"\n      end_cue: \"4:45\"\n      id: \"kyle-heironimus-lighting-talk-rubyconf-2017\"\n      video_id: \"kyle-heironimus-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Kyle Heironimus\n\n    - title: \"Lightning Talk: Yechiel Kalmenson\" # TODO: missing talk title\n      start_cue: \"4:45\"\n      end_cue: \"7:05\"\n      id: \"yechiel-kalmenson-lighting-talk-rubyconf-2017\"\n      video_id: \"yechiel-kalmenson-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Yechiel Kalmenson\n\n    - title: \"Lightning Talk: Heather Herrington\" # TODO: missing talk title\n      start_cue: \"7:05\"\n      end_cue: \"12:10\"\n      id: \"heather-herrington-lighting-talk-rubyconf-2017\"\n      video_id: \"heather-herrington-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Heather Herrington\n\n    - title: \"Lightning Talk: Jen Pengelly\" # TODO: missing talk title\n      start_cue: \"12:10\"\n      end_cue: \"16:09\"\n      id: \"jen-pengelly-lighting-talk-rubyconf-2017\"\n      video_id: \"jen-pengelly-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jen Pengelly\n\n    - title: \"Lightning Talk: Brian Underwood\" # TODO: missing talk title\n      start_cue: \"16:09\"\n      end_cue: \"21:15\"\n      id: \"brian-underwood-lighting-talk-rubyconf-2017\"\n      video_id: \"brian-underwood-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Brian Underwood\n\n    - title: \"Lightning Talk: Cameron Dutro\" # TODO: missing talk title\n      start_cue: \"21:15\"\n      end_cue: \"26:14\"\n      id: \"cameron-dutro-lighting-talk-rubyconf-2017\"\n      video_id: \"cameron-dutro-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Cameron Dutro\n\n    - title: \"Lightning Talk: Aaron Rosenberg\" # TODO: missing talk title\n      start_cue: \"26:14\"\n      end_cue: \"31:23\"\n      id: \"aaron-rosenberg-lighting-talk-rubyconf-2017\"\n      video_id: \"aaron-rosenberg-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Aaron Rosenberg\n\n    - title: \"Lightning Talk: Starr Chen\" # TODO: missing talk title\n      start_cue: \"31:23\"\n      end_cue: \"37:28\"\n      id: \"starr-chen-lighting-talk-rubyconf-2017\"\n      video_id: \"starr-chen-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Starr Chen\n\n    - title: \"Lightning Talk: Margo Urey\" # TODO: missing talk title\n      start_cue: \"37:28\"\n      end_cue: \"43:25\"\n      id: \"margo-urey-lighting-talk-rubyconf-2017\"\n      video_id: \"margo-urey-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Margo Urey\n\n    - title: \"Lightning Talk: Ryan Laughlin\" # TODO: missing talk title\n      start_cue: \"43:25\"\n      end_cue: \"49:19\"\n      id: \"ryan-laughlin-lighting-talk-rubyconf-2017\"\n      video_id: \"ryan-laughlin-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Ryan Laughlin\n\n    - title: \"Lightning Talk: Adam & Julia Cuppy\" # TODO: missing talk title\n      start_cue: \"49:19\"\n      end_cue: \"54:24\"\n      id: \"adam-julia-cuppy-lighting-talk-rubyconf-2017\"\n      video_id: \"adam-julia-cuppy-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Cuppy\n        - Julia Cuppy\n\n    - title: \"Lightning Talk: Jim Remsik\" # TODO: missing talk title\n      start_cue: \"54:24\"\n      end_cue: \"1:00:56\"\n      id: \"jim-remsik-lighting-talk-rubyconf-2017\"\n      video_id: \"jim-remsik-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jim Remsik\n\n    - title: \"Lightning Talk: Amir Rajan\" # TODO: missing talk title\n      start_cue: \"1:00:56\"\n      end_cue: \"1:07:06\"\n      id: \"amir-rajan-lighting-talk-rubyconf-2017\"\n      video_id: \"amir-rajan-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Amir Rajan\n\n    - title: \"Lightning Talk: Dave Aronson\" # TODO: missing talk title\n      start_cue: \"1:07:06\"\n      end_cue: \"1:12:24\"\n      id: \"dave-aronson-lighting-talk-rubyconf-2017\"\n      video_id: \"dave-aronson-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Dave Aronson\n\n    - title: \"Lightning Talk: Sam Livingston-Gray\" # TODO: missing talk title\n      start_cue: \"1:12:24\"\n      end_cue: \"1:17:10\"\n      id: \"sam-livingston-gray-lighting-talk-rubyconf-2017\"\n      video_id: \"sam-livingston-gray-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Sam Livingston-Gray\n\n    - title: \"Lightning Talk: Noah Gibbs\" # TODO: missing talk title\n      start_cue: \"1:17:10\"\n      end_cue: \"1:22:30\"\n      id: \"noah-gibbs-lighting-talk-rubyconf-2017\"\n      video_id: \"noah-gibbs-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Noah Gibbs\n\n    - title: \"Lightning Talk: Heidi Waterhouse\" # TODO: missing talk title\n      start_cue: \"1:22:30\"\n      end_cue: \"1:27:56\"\n      id: \"heidi-waterhouse-lighting-talk-rubyconf-2017\"\n      video_id: \"heidi-waterhouse-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Heidi Waterhouse\n\n    - title: \"Lightning Talk: Akira Matsuda\" # TODO: missing talk title\n      start_cue: \"1:27:56\"\n      end_cue: \"TODO\"\n      id: \"akira-matsuda-lighting-talk-rubyconf-2017\"\n      video_id: \"akira-matsuda-lighting-talk-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Akira Matsuda\n\n- id: \"andy-croll-rubyconf-2017\"\n  title: \"Keynote - The Impermanence of Software by Andy Croll\"\n  raw_title: \"RubyConf 2017: Keynote - The Impermanence of Software by Andy Croll\"\n  speakers:\n    - Andy Croll\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    The Impermanence of Software by Andy Croll\n  video_provider: \"youtube\"\n  video_id: \"l2WgVr1rv3c\"\n\n- id: \"anjuan-simmons-rubyconf-2017\"\n  title: \"Lending Privilege\"\n  raw_title: \"RubyConf 2017: Lending Privilege by Anjuan Simmons\"\n  speakers:\n    - Anjuan Simmons\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Lending Privilege by Anjuan Simmons\n\n    Diversity and inclusion have become hot topics in technology, but you may not know how you can make a difference. However, this talk will help you understand that, no matter your background, you have privilege and can lend it to marginalized groups in tech.\n  video_provider: \"youtube\"\n  video_id: \"zd4PsSk_0iQ\"\n\n- id: \"thursday-bram-rubyconf-2017\"\n  title: \"Writing Inclusively about Technology Topics\"\n  raw_title: \"RubyConf 2017: Writing Inclusively about Technology Topics by Thursday Bram\"\n  speakers:\n    - Thursday Bram\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Writing Inclusively about Technology Topics by Thursday Bram\n\n    Whether you're writing documentation, a talk for a technical conference, or a blog post on your work, identity can impact how your audience perceives and uses both written material and code repositories. If you want your work to be accessible to a wide audience, you need to write about it in an inclusive way. This talk will give you hands-on examples and resources to do just that!\n  video_provider: \"youtube\"\n  video_id: \"j1aLtqcTnk0\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2017\"\n  title: \"Opening Keynote: Good Change, Bad Change\"\n  raw_title: \"RubyConf 2017: Opening Keynote - Good Change, Bad Change by Yukihiro Matsumoto\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Opening Keynote - Good Change, Bad Change by Yukihiro Matsumoto\n  video_provider: \"youtube\"\n  video_id: \"1-A9eRzCBL0\"\n\n- id: \"eric-weinstein-rubyconf-2017\"\n  title: \"What If... ?: Ruby 3\"\n  raw_title: \"RubyConf 2017: What If... ?: Ruby 3 by Eric Weinstein\"\n  speakers:\n    - Eric Weinstein\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    What If... ?: Ruby 3 by Eric Weinstein\n\n    What if Professor X and Magneto formed the X-Men together? What if Jessica Jones had joined the Avengers? What if Tony Stark wrote Ruby? (Okay, I made that last one up, but we'd probably all read it.) This talk, in the mode of Marvel's What if... ? comics, explores what Ruby 3 might look like if key decisions in its history had been (or might be) made differently. We'll look at three \"what if\"s in particular: \"what if Ruby had a static type system?\", \"what if Ruby ran in the browser?\", and \"what if Ruby didn't have a global interpreter lock?\"\n  video_provider: \"youtube\"\n  video_id: \"0i2NgDhXH9Q\"\n\n- id: \"aja-hammerly-rubyconf-2017\"\n  title: \"4 Programming Paradigms in 45 Minutes\"\n  raw_title: \"RubyConf 2017: 4 Programming Paradigms in 45 Minutes by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  slides_url: \"https://thagomizer.com/files/ParadigmsRubyConf2017.pdf\"\n  description: |-\n    4 Programming Paradigms in 45 Minutes by Aja Hammerly\n\n    One of the most important lessons I've learned is that programming languages are tools and not all tools are good for all jobs. Some tasks are easier to solve functionally. Some are clearly suited for OO. Others get simpler when you use constraint solving or pattern matching.\n\n    Let's go on a whirlwind tour of 4 different programming languages emphasizing different programming techniques: OO, functional, logical, and procedural. You'll leave this talk with a better understanding of which languages are best suited to which types of jobs and a list of resources for learning more.\n  video_provider: \"youtube\"\n  video_id: \"3TBq__oKUzk\"\n\n- id: \"kevin-newton-rubyconf-2017\"\n  title: \"Compiling Ruby\"\n  raw_title: \"RubyConf 2017: Compiling Ruby by Kevin Newton\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Compiling Ruby by Kevin Newton\n\n    Since Ruby 2.3 and the introduction of RubyVM::InstructionSequence::load_iseq, we've been able to programmatically load ruby bytecode. By divorcing the process of running YARV byte code from the process of compiling ruby code, we can take advantage of the strengths of the ruby virtual machine while simultaneously reaping the benefits of a compiler such as macros, type checking, and instruction sequence optimizations. This can make our ruby faster and more readable! This talk demonstrates how to integrate this into your own workflows and the exciting possibilities this enables.\n  video_provider: \"youtube\"\n  video_id: \"iWDOXi7Kj2o\"\n\n- id: \"dorothy-jane-wingrove-rubyconf-2017\"\n  title: \"How to Build a World-Class Rock Paper Scissors Bot\"\n  raw_title: \"RubyConf 2017: How to Build a World-Class Rock Paper Scissors Bot by Dorothy Jane Wingrove\"\n  speakers:\n    - Dorothy Jane Wingrove\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    How to Build a World-Class Rock Paper Scissors Bot by Dorothy Jane Wingrove\n\n    This talk will teach you how to play rock-paper-scissors (no really, it’s more complicated than you might think) plus a little bit about AI history. It will also make you laugh — at least a little. You'll also learn some game theory, some mind games, and finally, how to build a world champion bot in the universe of Rock Paper Scissors.\n\n    This talk is aimed at all levels of Ruby programmers - beginner or advanced. All the examples in the talk and are explained step by step, and many of them relatively basic.\n  video_provider: \"youtube\"\n  video_id: \"Vo3qdIBOiko\"\n\n- id: \"ashley-ellis-pierce-rubyconf-2017\"\n  title: \"Git Driven Refactoring\"\n  raw_title: \"RubyConf 2017: Git Driven Refactoring by Ashley Ellis Pierce\"\n  speakers:\n    - Ashley Ellis Pierce\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Git Driven Refactoring by Ashley Ellis Pierce\n\n    Often we know that our code needs refactoring, but we have no idea where to start. Maybe we studied some common code smells and learned about the things that we should be avoiding, but memorizing the rules doesn’t automatically lead to fixing all problems. In this talk, we explore how you can use Git to recognize and address violations to each of the SOLID principles. Using diffs, commit history and pull requests you can learn to recognize patterns in code that point to problems. These same tools can help you correct those issues and write more maintainable code.\n  video_provider: \"youtube\"\n  video_id: \"3OgbQOsW61Y\"\n\n- id: \"minqi-pan-rubyconf-2017\"\n  title: \"Packing your Ruby application into a single executable\"\n  raw_title: \"RubyConf 2017: Packing your Ruby application into a single executable by  Minqi Pan\"\n  speakers:\n    - Minqi Pan\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Packing your Ruby application into a single executable by  Minqi Pan\n\n    Recent languages like Go compiles a project into a nice executable, why can't good ol' Ruby? We have built an packer for Ruby to do just that. It is 100% open-source, and can produce executables for Windows, macOS and Linux individually. By packing, distributing Ruby apps are made extremely easy, additionally with intellectual property protection. Auto-updating is also made easy, in that the executable only needs to download and replace itself. So, how we did it? How to use it? What goes under the hood? What future will this bring to Ruby? That's what will be unraveled in this talk!\n  video_provider: \"youtube\"\n  video_id: \"1mme7HiLqzA\"\n\n- id: \"andrew-faraday-rubyconf-2017\"\n  title: \"Gameshow: Just A Ruby Minute\"\n  raw_title: \"RubyConf 2017: Just A Ruby Minute by Andrew Faraday\"\n  speakers:\n    - Andrew Faraday\n    - Sam Phippen\n    - Andy Croll\n    - Tara Scherner de la Fuente\n    - Adam Cuppy\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Just A Ruby Minute by Andrew Faraday\n\n    Renowned game show Just a Minute has delighted audiences across the world for almost half a century, becoming part of the British national consciousness. Speakers are challenged to speak on an unseen (Rubyesque!) topic for one minute without hesitation, repetition, or deviation. It’s fast-paced, funny, insightful, and much harder than it sounds… and you might even learn something!\n  video_provider: \"youtube\"\n  video_id: \"DYc5X-in_oM\"\n\n- id: \"jessica-rudder-rubyconf-2017\"\n  title: \"The Good Bad Bug: Fail Your Way to Better Code\"\n  raw_title: \"RubyConf 2017: The Good Bad Bug: Fail Your Way to Better Code by Jessica Rudder\"\n  speakers:\n    - Jessica Rudder\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    The Good Bad Bug: Fail Your Way to Better Code by Jessica Rudder\n\n    Programming history is filled with bugs that turned out to be features and limitations that pushed developers to make even more interesting products. We’ll journey through code that was so ‘bad’ it was actually good. Along the way we'll look at the important role failure plays in learning. Then we’ll tame our inner perfectionists and tackle an approach to writing code that will help us fail spectacularly on our way to coding success.\n  video_provider: \"youtube\"\n  video_id: \"PW3Pj5o70JA\"\n\n- id: \"caroline-taymor-rubyconf-2017\"\n  title: \"Getting Unstuck: Using the Scientific Method for Debugging\"\n  raw_title: \"RubyConf 2017:  Getting Unstuck: Using the Scientific Method for Debugging by Caroline Taymor\"\n  speakers:\n    - Caroline Taymor\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Getting Unstuck: Using the Scientific Method for Debugging by Caroline Taymor\n\n    Have you ever gotten really stuck while trying to understand the cause of a bug? Thinking of your debugging session as a science experiment, and using the scientific method can help you make progress again. Come and learn how to adapt the scientific method (the process used for scientific research) to get past that stuck place and find the cause of bugs or production incidents. You’ll walk away with a great new tool to keep you calm and focused in the face of inevitable bugs.\n  video_provider: \"youtube\"\n  video_id: \"spwAyEn2VXs\"\n\n- id: \"tim-mertens-rubyconf-2017\"\n  title: \"Deterministic Solutions to Intermittent Failures\"\n  raw_title: \"RubyConf 2017: Deterministic Solutions to Intermittent Failures by Tim Mertens\"\n  speakers:\n    - Tim Mertens\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Deterministic Solutions to Intermittent Failures by Tim Mertens\n\n    Monday mornings are bad when the coffee runs out, but they’re even worse when all of your impossible to reproduce, “flaky” tests decide to detonate at the same time.\n\n    Join us to learn a systematic, proven workflow for expertly debugging any test failure including consistent, order-related, and non-deterministic failures. We’ll discuss the importance of fixing intermittent failures before they reach critical mass and why you should eradicate the term “flaky tests” from your vocabulary.\n\n    Don’t wait for an emergency to prioritize fixing the ticking time bomb of intermittent test failure.\n  video_provider: \"youtube\"\n  video_id: \"JH9vugpPNyw\"\n\n- id: \"heidi-helfand-rubyconf-2017\"\n  title: \"Leadership starts with Listening: Amplify your Impact\"\n  raw_title: \"RubyConf 2017: Leadership starts with Listening: Amplify your Impact by Heidi Helfand\"\n  speakers:\n    - Heidi Helfand\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Leadership starts with Listening: Amplify your Impact by Heidi Helfand\n\n    Listening is power. By “tuning in” and applying self management and directed curiosity you can help others thrive and solve their own problems. Doing this not only leads to greater ownership, but also more leaders in your organization instead of “order takers”. In this interactive talk I’ll teach you practical communication skills so you can become a more available and empowering coworker, friend and leader.\n  video_provider: \"youtube\"\n  video_id: \"VJxQZixy4b8\"\n\n- id: \"noel-rappin-rubyconf-2017\"\n  title: \"High Cost Tests and High Value Tests\"\n  raw_title: \"RubyConf 2017: High Cost Tests and High Value Tests by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    High Cost Tests and High Value Tests by Noel Rappin\n\n    There is a value in writing tests and there is also a cost. The currency is time. The trade-offs are difficult to evaluate because the cost and value are often seen by different people. The writer of the test bears much of the short term cost while long term benefits and cost are borne by the rest of the team. By planning around both the the cost and value of your tests, you’ll improve your tests and your code. How much do slow tests cost? When is it worth it to test an edge case? How can you tell if testing is helping? Here are some strategies to improve your tests and code.\n  video_provider: \"youtube\"\n  video_id: \"IS_9cRP9OZM\"\n\n- id: \"caleb-hearth-rubyconf-2017\"\n  title: \"Finding Responsibility\"\n  raw_title: \"RubyConf 2017: Finding Responsibility by Caleb Thompson\"\n  speakers:\n    - Caleb Hearth\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Finding Responsibility by Caleb Thompson\n\n    In 2011, with a team of interns at a Department of Defense contractor, I created a Wi-Fi geolocation app to locate hotspots. It could find the location in 3D space of every hotspot near you in seconds. We made formulas to model signal strength and probable distances. We used machine learning to optimize completion time and accuracy.\n\n    I was so caught up in the details that it took me months to see it would be used to kill people. What do we do when we discover that we're building something immoral or unethical? How can we think through the uses of our software to avoid this problem entirely?\n  video_provider: \"youtube\"\n  video_id: \"UBdBoWAtLNI\"\n\n- id: \"justin-searls-rubyconf-2017\"\n  title: \"There's Nothing . new under the sun\"\n  raw_title: \"RubyConf 2017: There's Nothing . new under the sun by Justin Searls and Josh Greenwood\"\n  speakers:\n    - Justin Searls\n    - Josh Greenwood\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    There's Nothing.new under the sun by Justin Searls and Josh Greenwood\n\n    Quick: say something about Ruby that hasn't already been said.\n\n    Not easy, right? This community is prolific. In thousands of talks, Ruby's story has been told and retold. We heralded programmer happiness, path of least surprise, and confident code. We unleashed metaprogramming (until we tamed our DSLs). We built apps, tested them to death, and then legacy-rescued them.\n\n    What's left to say? We could tell the same stories again, but that wouldn't be very DRY. What we need to hear was often said years ago, so this talk will help us rediscover timeless lessons from our community's greatest hits.\n  video_provider: \"youtube\"\n  video_id: \"tbzPeLaqp10\"\n\n- id: \"jason-charnes-rubyconf-2017\"\n  title: \"Saving Ruby from the Apocalypse\"\n  raw_title: \"RubyConf 2017: Saving Ruby from the Apocalypse by Jason Charnes\"\n  speakers:\n    - Jason Charnes\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Saving Ruby from the Apocalypse by Jason Charnes\n\n    You've just woken from a coma to find out that Ruby has fallen victim to the programming apocalypse. Walkers have taken over the programming world looking to infect any developers they can find. Posing even more of a threat are the other survivor camps such as Java and PHP all fighting to survive by any means necessary.\n\n    After reuniting with the Ruby Community, it's time to fight for survival. Ruby developers who remained safe in the post-apocalyptic Ruby community need a leader to keep the community together and keep the language thriving. Are you willing to step up to keep Ruby alive?\n  video_provider: \"youtube\"\n  video_id: \"PiT2XEWae1c\"\n\n- id: \"eileen-m-uchitelle-rubyconf-2017\"\n  title: \"The Unbearable Vulnerability of Open Source\"\n  raw_title: \"RubyConf 2017: The Unbearable Vulnerability of Open Source by Eileen M Uchitelle\"\n  speakers:\n    - Eileen M Uchitelle\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    The Unbearable Vulnerability of Open Source by Eileen M Uchitelle\n\n    If contributing to open source was only about writing code, it would be easy. In reality open source exposes our insecurities and makes us feel vulnerable. Vulnerability can inspire change, but can also paralyze us for fear of not being good enough. In this talk we'll look at how vulnerability affects open source contributors and explore how maintainers can foster a welcoming community. Contributors will learn how to identify projects with empathetic leaders who value GitHub’s community standards. Cultivating a better environment for contributing makes open source more sustainable for all.\n  video_provider: \"youtube\"\n  video_id: \"zOB4e-1cvsU\"\n\n- id: \"kelsey-pedersen-rubyconf-2017\"\n  title: \"Augmenting Human Decision Making with Data Science\"\n  raw_title: \"RubyConf 2017: Augmenting Human Decision Making with Data Science by Kelsey Pedersen\"\n  speakers:\n    - Kelsey Pedersen\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-28\"\n  published_at: \"2017-11-28\"\n  description: |-\n    Augmenting Human Decision Making with Data Science by Kelsey Pedersen\n\n    Humans and data science are flawed on their own. Humans lack the ability to process large volumes of information. Machines lack intuition, empathy and nuance. You’ll learn how to guide users of expert-use systems by applying data science to their user experience. Layering data science within our systems allows us to take advantage of the human-touch while leveraging our large data sets. In this talk, you’ll learn the process for sprinkling data science into your applications, the challenges we have faced along the way, and how to measure the business impact.\n  video_provider: \"youtube\"\n  video_id: \"mUcamCBDNcg\"\n\n- id: \"mark-simoneau-rubyconf-2017\"\n  title: \"Prototyping with Paper: How Board Games Become Reality\"\n  raw_title: \"RubyConf 2017: Prototyping with Paper: How Board Games Become Reality by Mark Simoneau\"\n  speakers:\n    - Mark Simoneau\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    Prototyping with Paper: How Board Games Become Reality by Mark Simoneau\n\n    Much like developing any feature in your app, the best developers start with an idea and then refine it through rapid testing, much of which requires very few technical skills--but does take focus, observation and patience. In this talk we'll discuss the process of developing and playtesting a board game and what we as software developers can learn from it to improve the features and apps we create. If you like board games or just want to create better experiences for your users, then this talk is for you!\n  video_provider: \"youtube\"\n  video_id: \"u68bi1kDwZ8\"\n\n- id: \"valerie-woolard-rubyconf-2017\"\n  title: \"How I Learned to Stop Worrying and Love Unit Testing\"\n  raw_title: \"RubyConf 2017: How I Learned to Stop Worrying and Love Unit Testing by Valerie Woolard Srinivasan\"\n  speakers:\n    - Valerie Woolard\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    How I Learned to Stop Worrying and Love Unit Testing by Valerie Woolard Srinivasan\n\n    We all know that testing is important. But it's also hard to get right. We'll talk about how to write effective tests that not only protect against defects in our code, but encourage us to write better quality code to begin with. You'll leave this talk with ideas on the philosophies that should inform your tests, and a good idea of what makes a good test suite.\n  video_provider: \"youtube\"\n  video_id: \"cWneFu2EnOY\"\n\n- id: \"sam-aaron-rubyconf-2017\"\n  title: \"Live Coding Music with Sonic Pi\"\n  raw_title: \"RubyConf 2017: Live Coding Music with Sonic Pi by Sam Aaron\"\n  speakers:\n    - Sam Aaron\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    Live Coding Music with Sonic Pi by Sam Aaron\n\n    Sonic Pi is a Ruby DSL & IDE for live coding music with a specific focus on education. In this demo-heavy talk, we’ll cover its history - why it was created, how it evolved and what it can do today. We’ll also take a quick technical nosedive into some of the more interesting linguistic innovations that were necessary to perform live with code. For example, we’ll see how we can rhythmically sync multiple threads, use lexical blocks to close over time, accurately sleep without drifting and deterministically manipulate global state concurrently. Expect noise!\n  video_provider: \"youtube\"\n  video_id: \"v9fKE0huqAE\"\n\n- id: \"jeff-sacks-rubyconf-2017\"\n  title: \"Voice Controlled Home Automation in Ruby\"\n  raw_title: \"RubyConf 2017: Voice Controlled Home Automation in Ruby by Jeff Sacks\"\n  speakers:\n    - Jeff Sacks\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    Voice Controlled Home Automation in Ruby by Jeff Sacks\n\n    Have you ever wanted to change the channel on your TV but the remote was missing? Wouldn't it be great to tell your TV to change the channel by speaking to it? In this talk, you will learn how to control your TV with nothing but your voice. Using Ruby you can connect your TV and cable box with the Amazon Echo, AWS Lambda, and a Raspberry Pi. Once you learn how easy this is to setup, you'll never look for that missing remote again.\n  video_provider: \"youtube\"\n  video_id: \"UaoL8x-brO8\"\n\n- id: \"stafford-brunk-rubyconf-2017\"\n  title: \"Rubyik's Cube\"\n  raw_title: \"RubyConf 2017: Rubyik's Cube by Stafford Brunk\"\n  speakers:\n    - Stafford Brunk\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    Rubyik's Cube by Stafford Brunk\n\n    The Rubik's Cube is one of the world's most recognizable puzzles. Knowing how to solve a scrambled cube can almost be called a badge of honor. While there are a multitude of books, articles, and apps on how to solve a cube as a human, what does it take to have a computer solve the problem? This talk will dive into exactly that question. We'll start with an overview of Rubik's Cube algorithms, move onto the logistics of implementing these algorithms, and finish up with some real examples of using Ruby to solve a Rubik's Cube!\n  video_provider: \"youtube\"\n  video_id: \"NTiGuvHkPOw\"\n\n- id: \"andrew-metcalf-rubyconf-2017\"\n  title: \"How to load 1m lines of Ruby in 5s\"\n  raw_title: \"RubyConf 2017: How to load 1m lines of Ruby in 5s by Andrew Metcalf\"\n  speakers:\n    - Andrew Metcalf\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    How to load 1m lines of Ruby in 5s by Andrew Metcalf\n\n    Applications written in Ruby, Python and several other popular dynamic languages become very slow to boot as they grow to millions of lines of code. Waiting to reload code in development becomes a major frustration and drain on productivity. This talk will discuss how we reduced the time to boot a service at Stripe from 35s to 5s and the static analysis tools we built along the way.\n  video_provider: \"youtube\"\n  video_id: \"vVFEROmdCkQ\"\n\n- id: \"takashi-kokubun-rubyconf-2017\"\n  title: \"LLVM-based JIT compiler for MRI\"\n  raw_title: \"RubyConf 2017: LLVM-based JIT compiler for MRI by Takashi Kokubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    LLVM-based JIT compiler for MRI by Takashi Kokubun\n\n    JIT compiler is considered a promising approach to achieve Ruby 3x3 goal these days. But the direction of its implementation is not fixed yet. What will be the ideal approach to achieve that goal?\n\n    In this talk, seeing my experiment to implement LLVM-based JIT compiler, you'll know how native code can be compiled from YARV ISeq, what makes it fast in LLVM, what are the difficulties underlying in it and how to solve them. I hope a discussion in this talk will help Ruby 3 to be great.\n  video_provider: \"youtube\"\n  video_id: \"Ti4a7SXGWig\"\n\n- id: \"tom-black-rubyconf-2017\"\n  title: \"Reimagining 2D graphics and game development with Ruby\"\n  raw_title: \"RubyConf 2017: Reimagining 2D graphics and game development with Ruby by Tom Black\"\n  speakers:\n    - Tom Black\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    Reimagining 2D graphics and game development with Ruby by Tom Black\n\n    Playing games and interacting with graphics, media, and devices is fun, but programming them rarely is. Even the simplest things can seem overwhelmingly complex and unnecessarily difficult, but it doesn't have to be that way! Let's explore how Ruby can help us design a more natural and expressive experience by leveraging MRI, mruby, and Opal, opening up possibilities natively and on the web. We'll poke under the hood of a cross-platform 2D engine designed to be scripted with Ruby. Many opportunities lie ahead in game development, education, and creative coding, so let's seize them — join us!\n  video_provider: \"youtube\"\n  video_id: \"-PPVypAS_Pc\"\n\n- id: \"catherine-meyers-rubyconf-2017\"\n  title: \"Mozart Could’ve Been an Engineer - Music + Code\"\n  raw_title: \"RubyConf 2017: Mozart Could’ve Been an Engineer - Music + Code by Catherine Meyers\"\n  speakers:\n    - Catherine Meyers\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    Mozart Could’ve Been an Engineer - Music + Code by Catherine Meyers\n\n    Would you hire a musician to build a web app? After this talk, you might not think it’s such a crazy idea. Transitioning from opera singer to software engineer, I was blown away by the parallels between music and code. During this talk, we’ll study these similarities: how we break down elements to learn, use patterns to build, problem solve with creativity, and succeed through persistence and flexibility. We’ll compare “Mary Had a Little Lamb” to a Ruby method and see how Puccini might have coded a Todo app. Warning: parts of this talk may be sung. Yes, you may bring your own instruments.\n  video_provider: \"youtube\"\n  video_id: \"n1U1rcThnzw\"\n\n- id: \"adam-cuppy-rubyconf-2017\"\n  title: \"Yes, and...\"\n  raw_title: \"RubyConf 2017: Yes, and... by Adam Cuppy & Julia Cuppy\"\n  speakers:\n    - Adam Cuppy\n    - Julia Cuppy\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    Yes, and... by Adam Cuppy & Julia Cuppy\n\n    What happens when we drop \"No, but...\" from our daily interactions or life choices in favor of the #1 rule of improv: Yes, and..?\n\n    This talk is not a technical deep dive into the Ruby VM or a walk through of a new gem. I won't touch on testing strategies or war stories as a developer. Instead, I'm going to teach you improv.\n\n    We'll call it a social strategy for an awesome life! This talk is for introverts and extroverts alike. You won't be brought onstage (unless you want to be).\n  video_provider: \"youtube\"\n  video_id: \"Tk8FTTfurmE\"\n\n- id: \"chad-fowler-rubyconf-2017\"\n  title: \"Keynote: Growing Old\"\n  raw_title: \"RubyConf 2017: Keynote: Growing Old by Chad Fowler\"\n  speakers:\n    - Chad Fowler\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    Keynote: Growing Old by Chad Fowler\n  video_provider: \"youtube\"\n  video_id: \"qH_y45he4-o\"\n\n- id: \"ignites-rubyconf-2017\"\n  title: \"Ignites\"\n  raw_title: \"RubyConf 2017: Ignites\"\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  video_provider: \"youtube\"\n  video_id: \"9VSo5u4ODWQ\"\n  description: \"\"\n  talks:\n    - title: \"Intro\"\n      start_cue: \"00:13\"\n      end_cue: \"01:53\"\n      id: \"evan-phoenix-ignites-intro-rubyconf-2017\"\n      video_id: \"evan-phoenix-ignites-intro-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Evan Phoenix\n\n    - title: \"Ignites: Foundations of the Ruby Community\"\n      start_cue: \"01:53\"\n      end_cue: \"07:13\"\n      id: \"rich-kilmer-ignites-rubyconf-2017\"\n      video_id: \"rich-kilmer-ignites-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Rich Kilmer\n\n    - title: \"Ignites: How to get involved in the Ruby community\"\n      start_cue: \"07:13\"\n      end_cue: \"12:50\"\n      id: \"nadia-odunayo-ignites-rubyconf-2017\"\n      video_id: \"nadia-odunayo-ignites-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Nadia Odunayo\n\n    - title: \"Ignites: Ruby Going Global\"\n      start_cue: \"13:10\"\n      end_cue: \"18:13\"\n      id: \"michael-hartl-ignites-rubyconf-2017\"\n      video_id: \"michael-hartl-ignites-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Hartl\n\n    - title: \"Ignites: Regional Conferences\"\n      start_cue: \"18:21\"\n      end_cue: \"23:49\"\n      id: \"jim-remsik-ignites-rubyconf-2017\"\n      video_id: \"jim-remsik-ignites-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jim Remsik\n\n    - title: \"Ignites: Ruby-Bears in the land of Ruby-a-lot\"\n      start_cue: \"23:55\"\n      end_cue: \"29:29\"\n      slides_url: \"https://speakerdeck.com/asheren/ruby-bears-in-the-land-of-ruby-a-lot\"\n      id: \"allison-mcmillan-ignites-rubyconf-2017\"\n      video_id: \"allison-mcmillan-ignites-rubyconf-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Allison McMillan\n\n- id: \"sandi-metz-rubyconf-2017\"\n  title: \"Keynote: You're Insufficiently Persuasive\"\n  raw_title: \"RubyConf 2017: Keynote - You're Insufficiently Persuasive by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  slides_url: \"https://speakerdeck.com/skmetz/you-are-insufficiently-persuasive-rubyconf\"\n  description: |-\n    Keynote - You're Insufficiently Persuasive by Sandi Metz\n  video_provider: \"youtube\"\n  video_id: \"VzWLGMtXflg\"\n\n- id: \"aaron-patterson-rubyconf-2017\"\n  title: \"Building a Compacting GC for MRI\"\n  raw_title: \"RubyConf 2017: Building a Compacting GC for MRI by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-29\"\n  published_at: \"2017-11-29\"\n  description: |-\n    Building a Compacting GC for MRI by Aaron Patterson\n\n    We will talk about implementing a compacting GC for MRI. This talk will cover compaction algorithms, along with implementation details, and challenges specific to MRI. Well cover low level and high level memory measurement tools, how to use them, and what they're telling us. We'll cover copy-on-write optimizations and how our GC impacts them. After this talk you should have a better understanding of how Ruby's memory management interacts with the system memory, how you can measure it, and how to adjust your application to work in concert with the system's memory.\n  video_provider: \"youtube\"\n  video_id: \"8Q7M513vewk\"\n\n- id: \"zachary-schroeder-rubyconf-2017\"\n  title: \"RubyCard: HyperCard, in Ruby\"\n  raw_title: \"RubyConf 2017: RubyCard: HyperCard, in Ruby by Zachary Schroeder\"\n  speakers:\n    - Zachary Schroeder\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    RubyCard: HyperCard, in Ruby by Zachary Schroeder\n\n    HyperCard was a visionary application that gave users the ability to create, share, and browse text content years before the Internet became commonplace. We will discuss its key features and explore recreating them in our own Ruby desktop app: RubyCard.\n  video_provider: \"youtube\"\n  video_id: \"WtUc4G2QDeQ\"\n\n- id: \"nate-berkopec-rubyconf-2017\"\n  title: \"Orbital Rocket Guidance with Ruby\"\n  raw_title: \"RubyConf 2017: Orbital Rocket Guidance with Ruby by Nate Berkopec\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Orbital Rocket Guidance with Ruby by Nate Berkopec\n\n    Using the popular space simulator Kerbal Space Program and some remote procedure calls, we're going to use Ruby to launch (simulated) rockets into space! We'll discuss the history of computing in the space program, real-life algorithms for getting rockets into orbit like the Space Shuttle's Powered Explicit Guidance Ascent System, and the software architecture of historic space computers like the Apollo Guidance Computer. Finally, we'll build our own orbital rocket, controlled by a Ruby program that emulates space computers of the past.\n  video_provider: \"youtube\"\n  video_id: \"VMxct9B5S1A\"\n\n- id: \"evan-phoenix-rubyconf-2017\"\n  title: \"Fireside Chat: Q&A with Matz\"\n  raw_title: \"RubyConf 2017: FIRESIDE CHAT - Q&A WITH MATZ by Evan Phoenix & Matz Evan\"\n  speakers:\n    - Evan Phoenix\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    FIRESIDE CHAT - Q&A WITH MATZ by Evan Phoenix & Matz Evan\n  video_provider: \"youtube\"\n  video_id: \"XhSpxGPa56Y\"\n\n- id: \"yusuke-endoh-rubyconf-2017\"\n  title: \"Esoteric, Obfuscated, Artistic Programming in Ruby\"\n  raw_title: \"RubyConf 2017: Esoteric, Obfuscated, Artistic Programming in Ruby by Yusuke Endoh\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Esoteric, Obfuscated, Artistic Programming in Ruby by Yusuke Endoh\n\n    Ruby has a rich and flexible syntax. It allows us to write not only an easy-to-read program, but also an \"hard-to-read\" one. This talk will show its unlimited power. We present and demonstrate some esoteric, obfuscated, and even artistic programs that we have ever created, including a program that contains a spinning globe, a robust program that can have any single character removed and still works, a program that consists only of alphabetical letters, and so on. We will also review the implementation techniques.\n  video_provider: \"youtube\"\n  video_id: \"6K7EmeptEHo\"\n\n- id: \"max-jacobson-rubyconf-2017\"\n  title: \"There are no rules in Ruby\"\n  raw_title: \"RubyConf 2017: There are no rules in Ruby by Max Jacobson\"\n  speakers:\n    - Max Jacobson\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    There are no rules in Ruby by Max Jacobson\n\n    Programming requires developing ideas about How Things Work that we internalize and rely on in our day-to-day programming life: when I write a class, I can use it like this; all strings have that method; I'm allowed to use private methods in these contexts. We start to rely on them. But which are rules, and which are more like norms? Turns out that with as dynamic a language as Ruby, a lot of rules are made to be broken. Let's take a look at what we can assume to be true in our Ruby programs and what we can't.\n  video_provider: \"youtube\"\n  video_id: \"hwFaScbQdIs\"\n\n- id: \"alex-wheeler-rubyconf-2017\"\n  title: \"Rewriting Rack: A Functional Approach\"\n  raw_title: \"RubyConf 2017: Rewriting Rack: A Functional Approach by Alex Wheeler\"\n  speakers:\n    - Alex Wheeler\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Rewriting Rack: A Functional Approach by Alex Wheeler\n\n    What if we traded in our classes for procs, our methods for functions, and took advantage of functional programming to rewrite Ruby's Rack? I kept hearing about the benefits of functional programming (simplicity, immutability, thread safety), but it wasn't until I reimplemented familiar Ruby concepts in a functional language that I really got it. In this talk, we'll steal some powerful FP ideas from Clojure and use them to rewrite Rack. You'll come out of it understanding how to write functional Ruby code that is simpler to reason about, less likely to break, and dead simple to debug.\n  video_provider: \"youtube\"\n  video_id: \"fVIVY7INWWQ\"\n\n- id: \"jason-r-clark-rubyconf-2017\"\n  title: \"A New Pair of Shoes!\"\n  raw_title: \"RubyConf 2017: A New Pair of Shoes! by Jason R. Clark\"\n  speakers:\n    - Jason R. Clark\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    A New Pair of Shoes! by Jason R. Clark\n\n    While web applications dominate much of the computing landscape, sometimes you just want to open a window on your desktop.\n\n    Enter Shoes! With a long history in the Ruby community, Shoes is an easy to learn, fun to use framework for writing and packaging GUI apps. It's ideal for kids, beginners, and anyone look for a simple way to build apps that run on Windows, Mac, and Linux.\n\n    After many years of development, a release candidate for the new version (4.0) of Shoes is ready! Come learn how to get Shoes, how it builds on the cross-platform power of JRuby, and how you can get involved in the project.\n  video_provider: \"youtube\"\n  video_id: \"EjN2ep1T6M8\"\n\n- id: \"soutaro-matsumoto-rubyconf-2017\"\n  title: \"Types and Ruby Programming Language\"\n  raw_title: \"RubyConf 2017: Types and Ruby Programming Language by Soutaro Matsumoto\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Types and Ruby Programming Language by Soutaro Matsumoto\n\n    Types have been a big interest for Rubyists for more than ten years. Even before Ruby3, some researchers have tried to type check Ruby programs. All of them had failed. No one in the world has successfully implemented practical type checker for Ruby programs yet.\n\n    Why is it difficult? How have we tried? What do we want exactly? Can we find any solution?\n  video_provider: \"youtube\"\n  video_id: \"Fjv9GxPXtck\"\n\n- id: \"olivier-lacan-rubyconf-2017\"\n  title: \"Human Errors\"\n  raw_title: \"RubyConf 2017: Human Errors by Olivier Lacan\"\n  speakers:\n    - Olivier Lacan\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Human Errors by Olivier Lacan\n\n    Runtime errors can sometimes turn into dark and unpleasant journeys which lead you to question the nature of reality. Thankfully, Ruby often provides friendly feedback for understanding the cause and remedy for exceptions. Yet, there are situations in which programmers don't receive clear enough context for what really caused an exception and how to address it. We'll look at Ruby's error feedback mechanisms and search for constructive ways in which they can be made more helpful to humans.\n  video_provider: \"youtube\"\n  video_id: \"eASsqQsaNOA\"\n\n- id: \"tara-scherner-de-la-fuente-rubyconf-2017\"\n  title: \"Rub[berDuck]yConf, I :mustache: you a question\"\n  raw_title: \"RubyConf 2017: Rub[berDuck]yConf, I :mustache: you a question by Tara Scherner de la Fuente\"\n  speakers:\n    - Tara Scherner de la Fuente\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Rub[berDuck]yConf, I :mustache: you a question by Tara Scherner de la Fuente\n\n    I :mustache: you a question.\n\n    That's what I send via Slack to folks I'm reaching out to when I'm stuck. Over these first few years of my career, the reach outs are fewer and the problems more specific and/or challenging. Now? I often get that inquiry in a DM. What I'm discovering more and more: That whole rubber duck thing is no joke—moreover, it's often the unofficial mentoring of our industry. What do our own questions teach us? What do they teach others? How can you be a great rubber duck? Beyond that moment, what can the rubber duck do for your career--the easy way?\n  video_provider: \"youtube\"\n  video_id: \"onaCI461Bww\"\n\n- id: \"max-tiu-rubyconf-2017\"\n  title: \"Finding Beauty in the Mundane\"\n  raw_title: \"RubyConf 2017: Finding Beauty in the Mundane by Max Tiu\"\n  speakers:\n    - Max Tiu\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Finding Beauty in the Mundane by Max Tiu\n\n    Amongst the exciting challenges of making software, there are some tasks we go out of our way to avoid: linting files, updating dependencies, writing documentation. But even the \"boring\" parts of the job are opportunities to make big changes for the better, little by little. In this talk, you'll learn how to make even the most mundane development tasks exciting in order to better your applications and become your team's hero in the process.\n  video_provider: \"youtube\"\n  video_id: \"ZRgiVRqPVL4\"\n\n- id: \"daniel-azuma-rubyconf-2017\"\n  title: \"Dispelling the dark magic: Inside a Ruby debugger\"\n  raw_title: \"RubyConf 2017: Dispelling the dark magic: Inside a Ruby debugger by Daniel Azuma\"\n  speakers:\n    - Daniel Azuma\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Dispelling the dark magic: Inside a Ruby debugger by Daniel Azuma\n\n    Debuggers can seem like dark magic—stopping a running program, tinkering with the program state, casting strange spells on VM internals. I spent much of my career diagnosing problems using “puts” because debuggers intimidated me. If you can relate, this is the talk for you! We’ll use Ruby's powerful TracePoint API to implement a simple but fully featured debugger for Ruby programs. We’ll also explore a few of the advanced techniques behind a \"live\" production debugger, and discuss some of the debugging features and limitations of the Ruby VM itself.\n  video_provider: \"youtube\"\n  video_id: \"UsrSu4x30Vo\"\n\n- id: \"prasun-anand-rubyconf-2017\"\n  title: \"High Performance GPU Computing with Ruby\"\n  raw_title: \"RubyConf 2017: High Performance GPU Computing with Ruby by Prasun Anand\"\n  speakers:\n    - Prasun Anand\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    High Performance GPU Computing with Ruby by Prasun Anand\n\n    ArrayFire gem a General Purpose GPU computing library can be used for high performance computing in Ruby be it statistical analysis of big data, image processing, linear algebra, machine learning.\n\n    ArrayFire has an outstanding performance considering other existing Ruby libraries that run on CPU. ArrayFire gem can also be run on clusters and handle real world problems by crunching huge datasets. The ease of using ArrayFire gem makes Ruby a viable choice for high performance scientific computing.\n  video_provider: \"youtube\"\n  video_id: \"eA3sgX0oLxU\"\n\n- id: \"shibata-hiroshi-rubyconf-2017\"\n  title: \"Gemification for Ruby 2.5/3.0\"\n  raw_title: \"RubyConf 2017: Gemification for Ruby 2.5/3.0 by Shibata Hiroshi\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Gemification for Ruby 2.5/3.0 by Shibata Hiroshi\n\n    Ruby have many libraries named standard library, extension and default-gems, bundled-gems. These are some differences under the bundler and rails application.\n\n    default-gems and bundled-gems are introduced to resolve dependency problem and development ecosystem around the ruby core. We have the plan to promote default/bundled gems from standard libraries. It says “Gemification” projects.\n\n    What Gemification changes in Ruby ecosystem? In this presentation, I will explain details of Gemification and future things of Ruby language.\n  video_provider: \"youtube\"\n  video_id: \"93nGROEgyEc\"\n\n- id: \"jacob-stoebel-rubyconf-2017\"\n  title: \"Code Reviews: Honesty, Kindness, Inspiration: Pick Three\"\n  raw_title: \"RubyConf 2017: Code Reviews: Honesty, Kindness, Inspiration: Pick Three by Jacob Stoebel\"\n  speakers:\n    - Jacob Stoebel\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Honesty, Kindness, Inspiration: Pick Three by Jacob Stoebel\n\n    The attitude among many developers seems to be that code reviews can be either honest or nice but not both. I see this as a false dichotomy; while code reviews should be both honest and kind, they should be focused on inspiring creators to go back to their work, excited to make it better.\n\n    This talk will introduce the Liz Lerman Critical Response process, a framework for giving feedback on anything creative. You'll leave this talk with tips on how to improve your code reviews by putting the creator in the driver's seat and inspiring everyone on the team to make the product even better.\n  video_provider: \"youtube\"\n  video_id: \"hP_2XKYia9I\"\n\n- id: \"yurie-yamane-rubyconf-2017\"\n  title: \"make mruby more portable: Why and How\"\n  raw_title: \"RubyConf 2017: make mruby more portable: Why and How by Yurie Yamane & Masayoshi Takahashi\"\n  speakers:\n    - Yurie Yamane\n    - Masayoshi Takahashi\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    make mruby more portable: Why and How by Yurie Yamane & Masayoshi Takahashi\n\n    Physical computing is very fascinating and fun, but there are also difficulties that were not found in normal Ruby programming. One of the issues is its low portability. Unlike PC, some computer boards that directly uses the devices use only small microcomputer whose memory is less than 1 MB. So most of the applications work only on specific boards. If we found an interesting project, we could not try it unless I had a target board. To solve it, I propose a plan of mruby platform, consisting of a group of mrbgems that absorb incompatibilities. I talk about the project and current progress.\n  video_provider: \"youtube\"\n  video_id: \"6JABFMn-bdI\"\n\n- id: \"betsy-haibel-rubyconf-2017\"\n  title: 'Set Design: Putting the \"Art\" in \"Architecture\"'\n  raw_title: 'RubyConf 2017: Set Design: Putting the \"Art\" in \"Architecture\" by Betsy Haibel'\n  speakers:\n    - Betsy Haibel\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Set Design: Putting the \"Art\" in \"Architecture\" by Betsy Haibel\n\n    I thought of software architects as petty waterfall dictators. Then I became one. My theater background saved me. In this talk, we’ll look at set design — an ongoing, collaborative process — as a model for a more agile kind of “architecture” than building metaphors allow us. You’ll learn about the most important part of any architecture (hint: people), about using architecture to foster team creativity, and about the agile-architecture superpowers that Ruby gives us. No matter your title, you too can architect!\n  video_provider: \"youtube\"\n  video_id: \"JWDPRWPtOeg\"\n\n- id: \"daniel-vartanov-rubyconf-2017\"\n  title: \"What does GIL really guarantee you?\"\n  raw_title: \"RubyConf 2017: What does GIL really guarantee you? by Daniel Vartanov\"\n  speakers:\n    - Daniel Vartanov\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    What does GIL really guarantee you? by Daniel Vartanov\n\n    You probably heard that Global Interpreter Lock (GIL) in Ruby \"allows only one thread to run at a time\", while technically it is correct it does not mean what you probably think it means. After this talk you will know why your code can be not thread safe even if GIL is enabled and how even a subtle change in your code can make GIL fail to protect you from race conditions. This talk is junior-friendly, but even experienced Ruby devs most probably will learn something new and important about GIL in Ruby.\n  video_provider: \"youtube\"\n  video_id: \"1nNfTWHF2YY\"\n\n- id: \"heidi-waterhouse-rubyconf-2017\"\n  title: \"Y2K and Other Disappointing Disasters: How To Create Fizzle\"\n  raw_title: \"RubyConf 2017: Y2K and Other Disappointing Disasters: How To Create Fizzle by Heidi Waterhouse\"\n  speakers:\n    - Heidi Waterhouse\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Y2K and Other Disappointing Disasters: How To Create Fizzle by Heidi Waterhouse\n\n    Risk Reduction is trying to make sure bad things happen as rarely as possible. It's anti-lock brakes and vaccinations and irons that turn off by themselves and all sorts of things that we think of as safety modifications in our life.\n\n    Harm Mitigation is what we do so that when bad things do happen, they are less catastrophic. Building fire sprinklers and seatbelts and needle exchanges are all about making the consequences of something bad less terrible.\n\n    This talk is focused on understanding where we can prevent problems and where we can just make them less bad.\n  video_provider: \"youtube\"\n  video_id: \"ddrFcg731tg\"\n\n- id: \"kevin-menard-rubyconf-2017\"\n  title: \"Improving TruffleRuby’s Startup Time with the SubstrateVM\"\n  raw_title: \"RubyConf 2017: Improving TruffleRuby’s Startup Time with the SubstrateVM by Kevin Menard\"\n  speakers:\n    - Kevin Menard\n  event_name: \"RubyConf 2017\"\n  date: \"2017-11-30\"\n  published_at: \"2017-11-30\"\n  description: |-\n    Improving TruffleRuby’s Startup Time with the SubstrateVM by Kevin Menard\n\n    Ruby applications can be broadly split into two categories: those that run for a short period and those that stick around for a while. Optimizing performance for one often comes at the expense of the other. Over the years, alternative Ruby implementations have demonstrated remarkable performance gains for long-lived applications -- so-called peak performance -- but often lose out to MRI for short-lived applications.\n\n    In this talk, I'll introduce the SubstrateVM and show how we use it to massively improve TruffleRuby's startup time with minimal impact on peak performance.\n  video_provider: \"youtube\"\n  video_id: \"hIMldcAzd5o\"\n\n- id: \"louisa-barrett-rubyconf-2017\"\n  title: \"Great Expectations: Power-Charging Apprenticeship Programs\"\n  raw_title: \"RubyConf 2017: Great Expectations: Power-Charging Apprenticeship Programs by Louisa Barrett\"\n  speakers:\n    - Louisa Barrett\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: Great Expectations: Power-Charging Apprenticeship Programs by Louisa Barrett\n\n    Apprenticeships are a great way to ramp up a newbie, but these programs are much tougher to successfully implement than many organizations expect. It is a surprisingly large investment to guide someone through the ups and downs of their first gig as a developer, and if you aren't prepared it can be a bad experience for everyone involved.\n\n    Let's dig into what makes a robust and empowering apprenticeship, from full team buy-in to setting clear learning goals to providing a clear path to the optimum final outcome: a new full time junior developer and a team dedicated to investing in education.\n  video_provider: \"youtube\"\n  video_id: \"o-J_OhgcvWU\"\n\n- id: \"thomas-e-enebo-rubyconf-2017\"\n  title: \"JRuby: What Why How ... Do it Now!\"\n  raw_title: \"RubyConf 2017: JRuby: What Why How ... Do it Now! by Thomas Enebo & Charles Nutter\"\n  speakers:\n    - Thomas E Enebo\n    - Charles Nutter\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: JRuby: What Why How ... Do it Now! by Thomas Enebo & Charles Nutter\n\n    Do you know JRuby? Built on the JVM platform, JRuby has been actively developed for over 17 years. But why would you choose JRuby? What benefits does it offer?\n\n    In this talk, we will introduce you to the wonderful world of JRuby. After basic setup, we'll show how JRuby's concurrency model and GC can help boost performance. We'll walk through deploying and scaling apps and services on JRuby. We'll demonstrate JRuby's powerful integration with other JVM languages. And we'll talk about how to start migrating to or building new apps on JRuby. Join us and learn what JRuby can do for you!\n  video_provider: \"youtube\"\n  video_id: \"Lja3HDcHNJA\"\n\n- id: \"tom-stuart-rubyconf-2017\"\n  title: \"Get Off the Tightrope\"\n  raw_title: \"RubyConf 2017: Get Off the Tightrope by Tom Stuart\"\n  speakers:\n    - Tom Stuart\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: Get Off the Tightrope by Tom Stuart\n\n    Do you feel stressed when you’re trying to hold a big problem in your head? Do you get frustrated when someone interrupts you and you have to start all over again? Those emotions are inevitable if you’re in the common habit of treating each programming task as a long, precarious, all-or-nothing tightrope walk. But it doesn’t have to be that way! In this talk I’ll explain why the tightrope walk is so harmful and show you some practical techniques for avoiding it.\n  video_provider: \"youtube\"\n  video_id: \"TdBELZG0UMY\"\n\n- id: \"haseeb-qureshi-rubyconf-2017\"\n  title: \"That time I used Ruby to crack my Reddit password\"\n  raw_title: \"RubyConf 2017: That time I used Ruby to crack my Reddit password by Haseeb Qureshi\"\n  speakers:\n    - Haseeb Qureshi\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: That time I used Ruby to crack my Reddit password by Haseeb Qureshi\n\n    I lost my password. So I used Ruby to crack it, kinda. I will re-enact the story live in front of a group of strangers.\n\n    I'm going to be honest, this is a weird and fairly embarrassing story. You probably shouldn't come see it.\n\n    You know what, forget I even said anything.\n  video_provider: \"youtube\"\n  video_id: \"ywiwq9IpDEU\"\n\n- id: \"andr-arko-rubyconf-2017\"\n  title: \"A History of Bundles: 2010 to 2017\"\n  raw_title: \"RubyConf 2017: A History of Bundles: 2010 to 2017 by André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: A History of Bundles: 2010 to 2017 by André Arko\n\n    When Bundler 1.0 came out in 2010, it did something really great: installed all of your gems and let you use them in your app. Today, Bundler does something really great: it installs all your gems and lets you use them. So, given that, why has Bundler needed thousands upon thousands of hours of development work? What exactly has changed since then? Prepare to find out. We’ll cover performance improvements, server response optimizations, adapting to new versions of Ruby, and adding features to support new usecases. Learn the tricks of Bundler power users, and find out how to optimize your gem workfl\n  video_provider: \"youtube\"\n  video_id: \"BXFYjO8qDxk\"\n\n- id: \"claudio-baccigalupo-rubyconf-2017\"\n  title: \"Just when you thought you couldn’t refactor any more…\"\n  raw_title: \"RubyConf 2017: Just when you thought you couldn’t refactor any more… by Claudio B.\"\n  speakers:\n    - Claudio Baccigalupo\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: Just when you thought you couldn’t refactor any more… by Claudio B.\n\n    In this talk, we will travel together on a refactoring journey. We will start from code that is easy to write but hard to read, and gradually advance to a level where the 4 C's of good code are satisfied: Correctness, Completeness, Clearness, and Compactness.\n\n    On the way, we will learn new Ruby 2.4 methods (String#match?, MatchData#named_captures) and review old methods (Enumerable#find, Regexp#===) that are more powerful than they seem at a first glance.\n  video_provider: \"youtube\"\n  video_id: \"nOa6FhMKsZ0\"\n\n- id: \"sam-phippen-rubyconf-2017\"\n  title: '\"RSpec no longer works with ActiveRecord\"'\n  raw_title: 'RubyConf 2017: \"RSpec no longer works with ActiveRecord\" by Sam Phippen'\n  speakers:\n    - Sam Phippen\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: \"RSpec no longer works with ActiveRecord\" by Sam Phippen\n\n    Sometimes an email appears in front of you in your inbox that immediately grabs your attention. For me, this was the case with a particularly scarily titled RSpec Mocks bug.\n\n    In this talk, you'll hear a story of investigation and fixing of what could have been a day ruining bug for all RSpec users. You'll come away with some deeper knowledge about RSpec's mocking library. You'll learn some protips on good practise when making an open source bug report. If you've ever used with RSpec's mocking library and would like to learn more about deep Ruby metaprogramming this talk is for you.\n  video_provider: \"youtube\"\n  video_id: \"VMcMqrpjAjU\"\n\n- id: \"sebastian-sogamoso-rubyconf-2017\"\n  title: \"The Overnight Failure\"\n  raw_title: \"RubyConf 2017: The overnight failure by Sebastian Sogamoso\"\n  speakers:\n    - Sebastian Sogamoso\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: The overnight failure by Sebastian Sogamoso\n\n    Close your eyes and imagine what is the worst thing that could happen to you at work. For me, that was charging users thousands of times the amount they should have been charged. In this talk we will find out what caused this particular bug and what we learnt from dealing with the whole situation.\n\n    Did someone get fired? Did the company survive the bug? Come to the talk and you will learn the answers, but more importantly a thing or two about how to go through tough times at work.\n  video_provider: \"youtube\"\n  video_id: \"3c_9WG_aImQ\"\n\n- id: \"jeremy-flores-rubyconf-2017\"\n  title: \"Hello Gmom!: Addressing loneliness in end-of-life care\"\n  raw_title: \"RubyConf 2017: Hello Gmom!: Addressing loneliness in end-of-life care by Jeremy Flores\"\n  speakers:\n    - Jeremy Flores\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: Hello Gmom!: Addressing loneliness in end-of-life care by Jeremy Flores\n\n    After suffering a debilitating stroke, Barbara, my significant other's grandmother, was left disabled, bed-bound, and mostly non-verbal. We visited often, and were with her when she passed earlier this year. For Christmas, I built her a web application to be a window into the life of her granddaughter.\n\n    Now that she’s passed, I’m hoping that the project can be a foundation or inspiration for others to build tools that bring them closer to the people they love. This small project--a $5 computer and some “off-the-shelf” technology--increased the quality of life for all of us.\n  video_provider: \"youtube\"\n  video_id: \"YLrRCmpVGw8\"\n\n- id: \"jan-lelis-rubyconf-2017\"\n  title: \"Ten Unicode Characters You Should Know About as a Programmer\"\n  raw_title: \"RubyConf 2017: Ten Unicode Characters You Should Know About as a Programmer by Jan Lelis\"\n  speakers:\n    - Jan Lelis\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: Ten Unicode Characters You Should Know About as a Programmer by Jan Lelis\n\n    There are a lot of things that can go wrong when working with Unicode data. Some examples of unmeant behavior:\n\n    You try to downcase \"I\" to \"i\", but your Turkish friends want it to be a dotless \"ı\"\n    Your UI is broken, because people use empty usernames, despite the String#blank? check\n    You think \"C\" is the same letter as \"С\", but your system does not think so and crashes\n    Using ten characters as representatives, I will highlight some Unicode characteristics which require a programmer's attention and demonstrate how Ruby's solid Unicode support can be of useful assistance!\n  video_provider: \"youtube\"\n  video_id: \"hlryzsdGtZo\"\n\n- id: \"colin-fulton-rubyconf-2017\"\n  title: \"Buuuuugs iiiiin Spaaaaace!\"\n  raw_title: \"RubyConf 2017: Buuuuugs iiiiin Spaaaaace! by Colin Fulton\"\n  speakers:\n    - Colin Fulton\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-01\"\n  published_at: \"2017-12-01\"\n  description: |-\n    RubyConf 2017: Buuuuugs iiiiin Spaaaaace! by Colin Fulton\n\n    Space is really cool. From precision electronics, to giant rockets, spacecraft can represent the best of engineering. But sometimes things go wrong. Terribly wrong.\n\n    What do exploding Soviet rockets have to do with Agile development?\n    How did LISP and Forth hacking save part of the Galileo probe?\n    What about that time astronauts added life-saving monkey patches... while orbiting the moon!\n    Exactly how much damage can a little dead code do? (Hint: a lot!)\n    This talk is for anyone whose love of a good space story is rivaled only by their passion for incredibly resilient software.\n  video_provider: \"youtube\"\n  video_id: \"_ZdF82h_GrM\"\n\n- id: \"john-feminella-rubyconf-2017\"\n  title: \"Steal This Talk: The Best Features Ruby Doesn't Have (Yet)\"\n  raw_title: \"RubyConf 2017: Steal This Talk: The Best Features Ruby Doesn't Have (Yet) by John Feminella\"\n  speakers:\n    - John Feminella\n  event_name: \"RubyConf 2017\"\n  date: \"2017-12-08\"\n  published_at: \"2017-12-08\"\n  description: |-\n    Steal This Talk: The Best Features Ruby Doesn't Have (Yet) by John Feminella\n\n    One of Ruby's greatest strengths is its burning desire to make writing software enjoyable for humans. Newer languages, perhaps taking some inspiration from Ruby, have recognized the practical value of doing this. What can Rubyists learn from these new ideas, and what can be adapted from them to improve Ruby?\n\n    In this talk, we'll discuss a few of the most interesting Ruby-like features that aren't really in Ruby yet. We'll also show how you can get these features (or an approximation to them) with Ruby today. By the end of the talk, you should feel empowered to try them out yourself!\n  video_provider: \"youtube\"\n  video_id: \"XrCU5r_NF2Q\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2018/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZEjH3kIyvIN0eZ4tuVEkBD\"\ntitle: \"RubyConf 2018\"\nkind: \"conference\"\nlocation: \"Los Angeles, CA, United States\"\ndescription: |-\n  RubyConf has been the main annual gathering of Rubyists from around the world since 2001.\npublished_at: \"2018-11-13\"\nstart_date: \"2018-11-13\"\nend_date: \"2018-11-15\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2018\nbanner_background: \"linear-gradient(-45deg, rgb(255,194,246) 0%, rgb(255,223,164) 100%)\"\nfeatured_background: \"linear-gradient(-45deg, rgb(255,194,246) 0%, rgb(255,223,164) 100%)\"\nfeatured_color: \"#2D2441\"\ncoordinates:\n  latitude: 34.0549076\n  longitude: -118.242643\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2018/videos.yml",
    "content": "---\n# https://web.archive.org/web/20181103192434/http://rubyconf.org/schedule\n\n## Day 1\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2018\"\n  title: \"Opening Keynote: The Power of The Community\"\n  raw_title: \"RubyConf 2018 - Opening Keynote by Yukihiro Matsumoto 'Matz'\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-28\"\n  description: |-\n    RubyConf 2018 - Opening Keynote by Yukihiro Matsumoto 'Matz'\n  video_provider: \"youtube\"\n  video_id: \"1XdTr84f-vA\"\n\n# Track: Ethical Decisions\n- id: \"caleb-hearth-rubyconf-2018\"\n  title: \"The Atonement of J. Robert Oppenheimer\"\n  raw_title: \"RubyConf 2018 - The Atonement of J. Robert Oppenheimer by Caleb Thompson\"\n  speakers:\n    - Caleb Hearth\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-29\"\n  description: |-\n    RubyConf 2018 - The Atonement of J. Robert Oppenheimer by Caleb Thompson\n\n    The Nazi party members at Nuremberg, J. Robert Oppenheimer at Los Alamos, and developers at exciting tech companies have something in common. The responsibility for what mark we leave on the world through our efforts or inventions rests on our own shoulders. We cannot push this burden to those who tell us what to do, and so we must be conscious about what it is that we're building and how it will be used. The repercussions of our actions come back to us if not legally, then weighing on our conscience.\n  video_provider: \"youtube\"\n  video_id: \"1PWjTLvTkos\"\n\n# Track: Scaling Teams\n- id: \"aaron-harpole-rubyconf-2018\"\n  title: \"Sweat the Small Stuff\"\n  raw_title: \"RubyConf 2018 - Sweat the Small Stuff by Aaron Harpole\"\n  speakers:\n    - Aaron Harpole\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-28\"\n  description: |-\n    RubyConf 2018 - Sweat the Small Stuff by Aaron Harpole\n\n    There is nothing quite like the excitement of leading a team of engineers while your company is in the middle of a growth spurt. Before you know it you start to notice that the work habits that used to work great just don’t seem to be that effective anymore.\n\n    In much the way that cooking for two is quite different from cooking for two hundred, building your systems for scale requires a different approach to your work.\n\n    In this talk we will explore antipatterns that start to show up during growth and some techniques that you can use to address them.\n  video_provider: \"youtube\"\n  video_id: \"Hx3LKRlJ774\"\n\n# Track: General 1\n- id: \"andy-croll-rubyconf-2018\"\n  title: \"The Games Developers Play\"\n  raw_title: \"RubyConf 2018 - The Games Developers Play by Andy Croll\"\n  speakers:\n    - Andy Croll\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - The Games Developers Play by Andy Croll\n\n    We all play games. Not video games, but the “games” of communication and power between humans.\n\n    Even the most rational of us may be unaware of the drivers of our behaviour and the impact it has on our ability to work well with others.\n\n    Find out how an awareness of our state of mind, our biases and the dynamics of human communication can help us to understand each other, ourselves, and build better software.\n  video_provider: \"youtube\"\n  video_id: \"IANnPHieT84\"\n\n# Track: General 2\n- id: \"pranav-garg-rubyconf-2018\"\n  title: \"RubyPlot - Creating a Plotting Library for Ruby\"\n  raw_title: \"RubyConf 2018 - RubyPlot - Creating a Plotting Library for Ruby by Pranav Garg\"\n  speakers:\n    - Pranav Garg\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-12-06\"\n  description: |-\n    RubyConf 2018 - RubyPlot - Creating a Plotting Library for Ruby by Pranav Garg\n\n    The talk introduces Rubyplot - the plotting library created for Ruby. It focuses on the general design of a plotting library, its influence from John Hunter's Matplotlib, the design decisions that were influenced by Ruby and provides a perspective of the language from the eyes of a newcomer.\n\n    The talk further argues why Ruby should be used for scientific computing and urges Rubyists to contribute to the development of scientific frameworks.\n  video_provider: \"youtube\"\n  video_id: \"7QBkckZ1aNQ\"\n\n# Track: Ethical Decisions\n- id: \"eric-weinstein-rubyconf-2018\"\n  title: \"Being Good: An Introduction to Robo- and Machine Ethics\"\n  raw_title: \"RubyConf 2018 - Being Good: An Introduction to Robo- and Machine Ethics by Eric Weinstein\"\n  speakers:\n    - Eric Weinstein\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-28\"\n  description: |-\n    RubyConf 2018 - Being Good: An Introduction to Robo- and Machine Ethics by Eric Weinstein\n\n    Machines are all around us: recommending our TV shows, planning our car trips, and running our day-to-day lives via AI assistants like Siri and Alexa. We know humans should act ethically, but what does that mean when building computer systems? Are machines themselves—autonomous vehicles, neural networks that diagnose cancer, algorithms that identify trends in police data—capable of ethical behavior? In this talk, we'll examine the implications of artificial moral agents and their relationships with the humans who build them through the lens of multiple case studies.\n  video_provider: \"youtube\"\n  video_id: \"-9V1TQ49vmI\"\n\n# Track: Scaling Teams\n- id: \"jack-danger-rubyconf-2018\"\n  title: \"Designing an engineering team: Making room for everyone\"\n  raw_title: \"RubyConf 2018 - Designing an engineering team: Making room for everyone by Jack Danger\"\n  speakers:\n    - Jack Danger\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-28\"\n  description: |-\n    RubyConf 2018 - Designing an engineering team: Making room for everyone by Jack Danger\n\n    How many different roles are there on engineering teams? Officially, there's probably just a manager and maybe a tech lead. Unofficially, you have technical specialists, company veterans, people focused on tools, and those who think deeply about the product.\n\n    In this talk we'll steal the best ideas from operating rooms, wartime deployments, and courtroom litigation. We'll see how it's possible to train, reward, and empower your teammates by respecting their uniqueness while also making room for very junior developers to join fast-moving teams.\n  video_provider: \"youtube\"\n  video_id: \"04bgdpAlAxU\"\n\n# Track: General 1\n- id: \"beth-haubert-rubyconf-2018\"\n  title: \"Cats, The Musical! Algorithmic Song Meow-ification\"\n  raw_title: \"RubyConf 2018 - Cats, The Musical! Algorithmic Song Meow-ification by Beth Haubert\"\n  speakers:\n    - Beth Haubert\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-29\"\n  description: |-\n    RubyConf 2018 - Cats, The Musical! Algorithmic Song Meow-ification by Beth Haubert\n\n    How are you supposed to sing along with your favorite TV theme song every week if it doesn’t have lyrics? At my house, we “meow” along (loudly). We also code, so I built ‘Meowifier’ to convert any song into a cat’s meows. Join me in this exploration of melody analysis APIs and gratuitous cat gifs.\n  video_provider: \"youtube\"\n  video_id: \"W0h5dzEFclY\"\n\n# Track: General 2\n- id: \"ryan-davis-rubyconf-2018\"\n  title: \"Graphics and Simulations (and Games), Oh My!\"\n  raw_title: \"RubyConf 2018 - Graphics and Simulations (and Games), Oh My! by Ryan Davis\"\n  speakers:\n    - Ryan Davis\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-29\"\n  description: |-\n    RubyConf 2018 - Graphics and Simulations (and Games), Oh My! by Ryan Davis\n\n    Quick and easy visualization is an important teaching tool and a wonderful way to see your ideas in action. Unfortunately, it is neither quick nor easy for rubyists to get from idea to visualization. You have to have a ton of extra stuff installed. You need to know game mechanics/math. You need to learn a whole other way of programming. It isn't something that is easy for a beginning programmer to pick up. This talk describes an alternative graphics and simulation library with a very clean API making it incredibly easy for newbs and experimenters to go from idea to visual simulation. Pew pew pew!\n  video_provider: \"youtube\"\n  video_id: \"5KVcsV_jseQ\"\n\n# Lunch\n\n- id: \"evan-phoenix-rubyconf-2018\"\n  title: \"Game Show: Ruby Family Fued\"\n  raw_title: \"RubyConf 2018 - Ruby Family Fued MC: Evan Phoenix\"\n  speakers:\n    - Evan Phoenix\n    - Eileen M. Uchitelle\n    - Aaron Patterson\n    - Justin Searls\n    - Nadia Odunayo\n    - Sam Phippen\n    - Valerie Woolard\n    - Kinsey Ann Durham\n    - Ernie Miller\n\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-29\"\n  description: |-\n    RubyConf 2018 - Ruby Family Fued MC: Evan Phoenix\n  video_provider: \"youtube\"\n  video_id: \"5DMw7MiBOGQ\"\n\n# Track: Ethical Decisions\n- id: \"audrey-eschright-rubyconf-2018\"\n  title: \"Unraveling the Masculinization of Technology\"\n  raw_title: \"RubyConf 2018 - Unraveling the Masculinization of Technology by Audrey Eschright\"\n  speakers:\n    - Audrey Eschright\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-28\"\n  description: |-\n    RubyConf 2018 - Unraveling the Masculinization of Technology by Audrey Eschright\n\n    Have you ever wondered where the perception that technology is a masculine pursuit comes from? Or why we have to explain that, \"no really, women are interested in computers too\"? At the beginning of the modern technological era, to be a computer was to be an actual literal woman—someone trained in math and computations. Decades later, women are underrepresented in most technical pursuits, with an increasingly “leaky” pipeline leaving fewer and fewer throughout our career progression. Learn about the gendered history of computing and explore how we can write a new narrative of participation.\n  video_provider: \"youtube\"\n  video_id: \"DPLrJtighWU\"\n\n# Track: Scaling Teams\n- id: \"annie-sexton-rubyconf-2018\"\n  title: \"The Dangers of Tribal Knowledge\"\n  raw_title: \"RubyConf 2018 - The Dangers of Tribal Knowledge by Annie Sexton\"\n  speakers:\n    - Annie Sexton\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-28\"\n  description: |-\n    RubyConf 2018 - The Dangers of Tribal Knowledge by Annie Sexton\n\n    Are you constantly tapped on the shoulder for answers? Tired of being the Google for your team? Or perhaps you’re the new kid, having to ask a dozen different people to find answers to all your questions? These are the consequences of tribal knowledge. In this talk we’ll discuss how to have a team that self-serves, finds answers on their own, without forcing them to wade through a colossal employee handbook.\n  video_provider: \"youtube\"\n  video_id: \"o-JL-so5Gm8\"\n\n# Track: Taming Services\n- id: \"daniel-azuma-rubyconf-2018\"\n  title: \"Yes, You Should Provide a Client Library For Your API\"\n  raw_title: \"RubyConf 2018 - Yes, You Should Provide a Client Library For Your API by Daniel Azuma\"\n  speakers:\n    - Daniel Azuma\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-29\"\n  description: |-\n    RubyConf 2018 - Yes, You Should Provide a Client Library For Your API by Daniel Azuma\n\n    Congratulations! You’ve launched a RESTful JSON-based API, and now anyone can call your service by making HTTP requests. But is that enough? While HTTP-REST by itself can enable access to your service, an API client library can provide significant benefits in safety, security, readability, and ease of use. In this session, you’ll learn API client design patterns and best practices honed from releasing hundreds of APIs at Google, and you’ll discover tools that can take the tedium out of building, testing, and documenting your API clients for Ruby, and across other languages.\n  video_provider: \"youtube\"\n  video_id: \"Q8l_3jMhjwY\"\n\n# Track: General\n- id: \"andy-glass-rubyconf-2018\"\n  title: \"Ruby for Makers: Designing Physical Products With Ruby\"\n  raw_title: \"RubyConf 2018 - Ruby for Makers: Designing Physical Products With Ruby by Andy Glass\"\n  speakers:\n    - Andy Glass\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-29\"\n  description: |-\n    RubyConf 2018 - Ruby for Makers: Designing Physical Products With Ruby by Andy Glass\n\n    Rubyists are creators. While we’re traditionally tasked with building digital products, our skills can cross into the physical medium too. This talk demonstrates a non-typical way to use code to create products: building a Ruby program that generates dynamic plans for laser-cut physical products (e.g. laptop stands, picture frames, notebooks, etc). With size, fonts and patterns as variables, our app programs a system that allows a user, or a computer, to design an infinite number of variants. Attendees will leave inspired to explore new avenues to use their skills to do what we do best: create.\n  video_provider: \"youtube\"\n  video_id: \"S3yLn9fuT9M\"\n\n# Track: Ethical Decisions\n- id: \"cecy-correa-rubyconf-2018\"\n  title: \"The Psychology of Fake News (And What Tech Can Do About It)\"\n  raw_title: \"RubyConf 2018 - The Psychology of Fake News (And What Tech Can Do About It) by Cecy Correa\"\n  speakers:\n    - Cecy Correa\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-28\"\n  description: |-\n    RubyConf 2018 - The Psychology of Fake News (And What Tech Can Do About It) by Cecy Correa\n\n    Fake news spread six times faster in social media than true stories. As technologists, our industry has built the tools that enable the spread of disinformation across social, the web, and beyond. But fake news is nothing new, it has been a part of each advancement in the technology that powers the spread of information, from the printing press to blogging. What makes fake news so appealing? Is it a tech problem or a human problem? In this talk, I will explain the psychology that makes fake news appealing to our brain, and what technology can learn about this psychology to build better tools.\n  video_provider: \"youtube\"\n  video_id: \"2cVfYMxqZmI\"\n\n# Track: Scaling Teams\n- id: \"mercedes-bernard-rubyconf-2018\"\n  title: \"Empowering Early-Career Developers\"\n  raw_title: \"RubyConf 2018 - Empowering Early-Career Developers by Mercedes Bernard\"\n  speakers:\n    - Mercedes Bernard\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-28\"\n  description: |-\n    RubyConf 2018 - Empowering Early-Career Developers by Mercedes Bernard\n\n    How can teams invest in and grow their less experienced developers into team-leading senior devs? I believe the first step is empowering them. On my team, we’ve created a process for each team member to lead and own one of our core features. Our early-career developers are learning client management and team leadership skills that they wouldn’t usually get to practice until they stepped into a senior role. In this talk, I’ll share our process and what we’ve learned so you can give your early-career developers valuable experience they need to become successful, senior team members.\n  video_provider: \"youtube\"\n  video_id: \"Qspf0SX_oPs\"\n\n# Track: Taming Services\n- id: \"jeremy-hanna-rubyconf-2018\"\n  title: \"Uncoupling Systems\"\n  raw_title: \"RubyConf 2018 - Uncoupling Systems by Jeremy Hanna\"\n  speakers:\n    - Jeremy Hanna\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-30\"\n  description: |-\n    RubyConf 2018 - Uncoupling Systems by Jeremy Hanna\n\n    We tackle unique business challenges but are solving similar problems, and all too rarely will we talk through our designs and mistakes. Integrations, external APIs, data-stores - these might not be pure code but we can learn a lot from good object design when scaling our systems.\n\n    In this talk we’ll discuss how parts of a distributed systems rely on each other, how data flow can couple and propagate failure, and how common emergent patterns can encapsulate services to be resilient.\n\n    This is a journey of close calls, errors, and design smells researched into how a service gets simplified.\n\n    Twitter: @almostjeremy\n  video_provider: \"youtube\"\n  video_id: \"33kf0AhZ794\"\n\n# Track: General\n- id: \"jonan-scheffler-rubyconf-2018\"\n  title: \"Wafflebot: Cloud Connected Artificially Intelligent Waffles\"\n  raw_title: \"RubyConf 2018 - Wafflebot: Cloud Connected Artificially Intelligent Waffles by Jonan Scheffler\"\n  speakers:\n    - Jonan Scheffler\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-29\"\n  description: |-\n    RubyConf 2018 - Wafflebot: Cloud Connected Artificially Intelligent Waffles by Jonan Scheffler\n\n    Come laugh and cry with me as I detail my audacious quest for the world's perfect waffle.\n\n    You'll learn valuable life skills like properly assembling a Geiger counter (yes, waffles are radioactive), when and how to use solenoid valves to prevent batterpocalypse, and why you should never, under any circumstances, attempt to modify a self-heating chunk of searing metal in such a way as to make it sentient.\n\n    Join me for a whirlwind tour of my most ambitious Ruby hardware project yet. Even if the talk is terrible, you might get a questionably food-grade waffle out of the deal.\n  video_provider: \"youtube\"\n  video_id: \"vXYklRYVjd4\"\n\n# Afternoon Break\n\n# Track: Ethical Decisions\n- id: \"colin-fleming-rubyconf-2018\"\n  title: \"Ethical Data Collection for Regular Developers\"\n  raw_title: \"RubyConf 2018 - Ethical Data Collection for Regular Developers by Colin Fleming\"\n  speakers:\n    - Colin Fleming\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-28\"\n  description: |-\n    RubyConf 2018 - Ethical Data Collection for Regular Developers by Colin Fleming\n\n    The DC Abortion Fund collects extremely sensitive data about people seeking abortions. That's terrifying for the engineering team, who are responsible for keeping client data safe! We've made a lot of carefully measured ethical decisions about data intake and usage. In this talk we'll examine how we have done data modeling, collection, and scrubbing, and the ethical reasoning and tradeoffs we've made along the way.\n  video_provider: \"youtube\"\n  video_id: \"EkHhBpO6Kzo\"\n\n# Track: General 1\n- id: \"katherine-wu-rubyconf-2018\"\n  title: \"Secrets of a Stealth Mentee\"\n  raw_title: \"RubyConf 2018 - Secrets of a Stealth Mentee by Katherine Wu\"\n  speakers:\n    - Katherine Wu\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-28\"\n  description: |-\n    RubyConf 2018 - Secrets of a Stealth Mentee by Katherine Wu\n\n    Your dream mentor is right around the corner, but they don't need to know that! In this talk, you’ll discover how to find and work with the great mentors you deserve. You’ll learn how to extract insights tailored to you and to keep the great advice coming. The best part? You can use these strategies even if you're not in a formal mentorship program. Maybe you don’t even know what you want right now, and that’s ok! You can still receive mentorship to help you identify and grow into the next stage of your career. We don’t have to wait to be chosen--let’s help others help us.\n  video_provider: \"youtube\"\n  video_id: \"aNnBowC-2ds\"\n\n# Track: Taming Services\n- id: \"james-thompson-rubyconf-2018\"\n  title: \"Building For Gracious Failure\"\n  raw_title: \"RubyConf 2018 - Building For Gracious Failure by James Thompson\"\n  speakers:\n    - James Thompson\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-29\"\n  description: |-\n    RubyConf 2018 - Building For Gracious Failure by James Thompson\n\n    Everything fails at some level, in some way, some of the time. How we deal with those failures can ruin our day, or help us learn and grow. Together we will explore some of the patterns for dealing with failure in service-based systems graciously. Whether you're integrating with an external system, building microservices, or designing serverless applications, you will gain insight on how to fail gracefully in both common, and uncommon circumstances.\n  video_provider: \"youtube\"\n  video_id: \"fAHwr9og4Ug\"\n\n# Track: General 2\n- id: \"alex-peattie-rubyconf-2018\"\n  title: \"Ruby-us Hagrid: Writing Harry Potter with Ruby\"\n  raw_title: \"RubyConf 2018 - Ruby-us Hagrid: Writing Harry Potter with Ruby by Alex Peattie\"\n  speakers:\n    - Alex Peattie\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-29\"\n  description: |-\n    RubyConf 2018 - Ruby-us Hagrid: Writing Harry Potter with Ruby by Alex Peattie\n\n    We all know that Ruby can give us super powers, but can we use it do something truly magical - write a brand new Harry Potter completely automatically?\n\n    It turns out that Ruby and the dark arts of Natural Language Programming are a match made in heaven! Using some basic NLP techniques, a dash of probability, and a few lines of simple Ruby code, we can create a virtual author capable of generating a very convincing Potter pastiche. And if the life of an author’s not for you, don’t worry. In the last part of the talk, we'll explore how we can apply what we've learnt to everyday coding problems.\n  video_provider: \"youtube\"\n  video_id: \"gTru3pXKPnI\"\n\n- id: \"bianca-escalante-rubyconf-2018\"\n  title: \"Keynote: Who and What We're Leaving Behind by Bianca Escalante\"\n  raw_title: \"RubyConf 2018 - Keynote: Who and What We're Leaving Behind by Bianca Escalante\"\n  speakers:\n    - Bianca Escalante\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-13\"\n  published_at: \"2018-11-29\"\n  description: |-\n    RubyConf 2018 - Who and What We're Leaving Behind by Bianca Escalante\n  video_provider: \"youtube\"\n  video_id: \"o2TdaLwTnKk\"\n\n## Day 2\n\n- id: \"saron-yitbarek-rubyconf-2018\"\n  title: \"Keynote: How to Build a Magical Living Room\"\n  raw_title: \"RubyConf 2018 - Keynote: How to Build a Magical Living Room by Saron Yitbarek\"\n  speakers:\n    - Saron Yitbarek\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-03\"\n  description: |-\n    RubyConf 2018 - Keynote: How to Build a Magical Living Room by Saron Yitbarek\n  video_provider: \"youtube\"\n  video_id: \"nOscsODuol4\"\n\n# Track: General 1\n- id: \"brad-urani-rubyconf-2018\"\n  title: \"The Ruby Developer's Command Line Toolkit\"\n  raw_title: \"RubyConf 2018 - The Ruby Developer's Command Line Toolkit by Brad Urani\"\n  speakers:\n    - Brad Urani\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-11-30\"\n  description: |-\n    RubyConf 2018 - The Ruby Developer's Command Line Toolkit by Brad Urani\n\n    As a Ruby developer, you use the command line, but do you take advantage of everything it can do? Join us for a demonstration of command line tools for Ruby developers. Increase productivity with search tools, shell functions, git aliases, tmux shortcuts and rbenv plugins. Want a better pry or irb? Supercharge it with shortcuts, macros and gems. Once you've perfected your setup, push it to GitHub so you can pull it and install it on any computer you want. Whether you're a reluctant minimalist or an experienced power user, you'll discover tools to make you a happier and more productive developer\n  video_provider: \"youtube\"\n  video_id: \"V0p7pWSxOXw\"\n\n# Track: Incident Response\n- id: \"courtney-eckhardt-rubyconf-2018\"\n  title: \"Retrospectives for Humans\"\n  raw_title: \"RubyConf 2018 - Retrospectives for Humans by Courtney Eckhardt\"\n  speakers:\n    - Courtney Eckhardt\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-03\"\n  description: |-\n    RubyConf 2018 - Retrospectives for Humans by Courtney Eckhardt\n\n    Seattle has two of the longest floating bridges in the world, and in 1990, one of them sank while it was being repurposed. This accident was a classic complex systems failure with a massive PR problem and great documentation. That combination is an excellent frame for talking about incident retrospectives- the good, the bad, the vaguely confusing and unsatisfying. Come for the interesting disaster story, stay to learn about the language of blame and how to ask warm, thoughtful engineering questions.\n  video_provider: \"youtube\"\n  video_id: \"s7R7V5wC0wA\"\n\n# Track: Inside Ruby\n- id: \"michael-herold-rubyconf-2018\"\n  title: \"Let's subclass Hash - what's the worst that could happen?\"\n  raw_title: \"RubyConf 2018 - Let's subclass Hash - what's the worst that could happen? by Michael Herold\"\n  speakers:\n    - Michael Herold\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Let's subclass Hash - what's the worst that could happen? by Michael Herold\n\n    Have you ever been tempted to subclass a core class like Hash or String? Or have you read blog posts about why you shouldn't do that, but been left confused as to the specifics? As a maintainer of Hashie, a gem that commits this exact sin, I'm here to tell you why you want to reach for other tools instead of the subclass.\n\n    In this talk, you'll hear stories from the trenches about what can go wrong when you subclass core classes. We'll dig into Ruby internals and you will leave with a few new tools for tracking down seemingly inexplicable performance issues and bugs in your applications.\n  video_provider: \"youtube\"\n  video_id: \"KzdSxgVPhXU\"\n\n# Track: General 2\n- id: \"jeremy-evans-rubyconf-2018\"\n  title: \"Running a Government Department on Ruby for over 13 Years\"\n  raw_title: \"RubyConf 2018 - Running a Government Department on Ruby for over 13 Years by Jeremy Evans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Running a Government Department on Ruby for over 13 Years by Jeremy Evans\n\n    In this presentation, I will be sharing my experiences running the programming unit for a government department for the over 15 years, using Ruby almost exclusively for the last 13. I will discuss our approach of having developers working directly with stakeholders to determine requirements, how we prioritize requests for new features, how we use Ruby for all types of applications, and our unique web application stack and how it uses defense-in-depth approaches to prevent and contain attacks.\n  video_provider: \"youtube\"\n  video_id: \"k7j4p4I1icY\"\n\n# Track: General 1\n- id: \"noel-rappin-rubyconf-2018\"\n  title: \"The Developer's Toolkit: Everything We Use But Ruby\"\n  raw_title: \"RubyConf 2018 - The Developer's Toolkit: Everything We Use But Ruby by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-11-30\"\n  description: |-\n    RubyConf 2018 - The Developer's Toolkit: Everything We Use But Ruby by Noel Rappin\n\n    As developers, our work is mediated through many tools besides languages. We use terminals, browsers, git, and the os. Not to mention editors. These are powerful tools that can be infinitely customized and extended. The tools can make common tasks easier or less error prone to perform. Or they can give you visibility into system behavior. But the options are bewildering and each customization has a cost. It’s time to make your environment work for you. This isn’t just a list of tips and tricks, but will also suggest how to evaluate whether a power tool or shortcut is worth your time.\n  video_provider: \"youtube\"\n  video_id: \"EeRyJtSTXv8\"\n\n# Track: Incident Response\n- id: \"cory-chamblin-rubyconf-2018\"\n  title: \"What Poker Can Teach Us About Post-Mortems\"\n  raw_title: \"RubyConf 2018 - What poker can teach us about post-mortems by Cory Chamblin\"\n  speakers:\n    - Cory Chamblin\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-03\"\n  description: |-\n    RubyConf 2018 - What poker can teach us about post-mortems by Cory Chamblin\n\n    Are your post-mortems reactive and unsatisfying?\n\n    The common post-mortem traces bad outcomes back to critical decisions so that we make different decisions in the future. But what if those decisions were sound? It tells us to stop making them!\n\n    In poker, as in software, variance is real and you can do everything correctly and still lose the hand.\n\n    In this talk, we'll talk about real post-mortems and problems with their conclusions. We'll rebalance our thinking to see when we might be learning the wrong lessons. We will learn about poker, taking risks, and a little about life.\n  video_provider: \"youtube\"\n  video_id: \"4ak_UBZnemY\"\n\n# Track: Inside Ruby\n- id: \"colin-fulton-rubyconf-2018\"\n  title: \"Trash Talk: A Garbage Collection Choose-Your-Own-Adventure\"\n  raw_title: \"RubyConf 2018 - Trash Talk: A Garbage Collection Choose-Your-Own-Adventure by Colin Fulton\"\n  speakers:\n    - Colin Fulton\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Trash Talk: A Garbage Collection Choose-Your-Own-Adventure by Colin Fulton\n\n    \"Walking into work one day, you see a raccoon in an embroidered vest carefully picking through some dumpsters. Startled, the raccoon shouts, 'Ack! No one is supposed to notice me!' before running away. Dumbfounded, you chase after them only to discover a magical world you never knew was right under your office...\"\n\n    This talk is a choose-your-own-adventure, where you decide what you want to learn about Ruby's garbage collector!\n\n    Get an easy introduction to how garbage collection works, the clever performance optimizations used by Ruby, and even what the future might look like.\n  video_provider: \"youtube\"\n  video_id: \"qXo3fqjY50o\"\n\n# Track: General 2\n- id: \"allison-mcmillan-rubyconf-2018\"\n  title: \"BDD: Baby Driven Development\"\n  raw_title: \"RubyConf 2018 - BDD: Baby Driven Development by Allison McMillan\"\n  speakers:\n    - Allison McMillan\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - BDD: Baby Driven Development by Allison McMillan\n\n    When I became a parent, I was completely unprepared for the challenges that awaited me. I reached out to hundreds of fellow parents in tech and learned there are common challenges that simply aren’t spoken about. These focus around one fact that no one wants to admit... parenting is not fun. Parenting is stressful, difficult, and oftentimes incredibly lonely. But being a parent also makes people more organized, focused, and empathetic. We’ll explore these survey results to expose common trends and issues and discuss solutions that show how supporting parents helps all team members thrive.\n  video_provider: \"youtube\"\n  video_id: \"epALpAVlbTc\"\n\n# Lunch\n\n- id: \"sam-phippen-rubyconf-2018\"\n  title: \"Live Mob Refactoring\"\n  raw_title: \"RubyConf 2018 - Live Mob Refactoring\"\n  speakers:\n    - Sam Phippen\n    - Betsy Haibel\n    # - Allie # TODO: last name\n    - Jennifer Tran\n    # - Habib # TODO: last name\n    - Trey Miller\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-03\"\n  description: |-\n    RubyConf 2018 - Mob Refactoring\n  video_provider: \"youtube\"\n  video_id: \"bxNUCtz2svo\"\n\n# Track: General 1\n- id: \"tony-drake-rubyconf-2018\"\n  title: \"The Anatomy of a Ruby Gem: Going From Zero to Sharing Code\"\n  raw_title: \"RubyConf 2018 - The Anatomy of a Ruby Gem: Going From Zero to Sharing Code by Tony Drake\"\n  speakers:\n    - Tony Drake\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-11-30\"\n  description: |-\n    RubyConf 2018 - The Anatomy of a Ruby Gem: Going From Zero to Sharing Code by Tony Drake\n\n    To many Rubyists just starting out, gems can appear very mysterious. You list them in a Gemfile and run 'bundle install' or install them directly with 'gem install'. Suddenly, your programs gain more functionality than they had before. But what are gems? What makes them work? How can you make your own to share with the world? Let's find out.\n  video_provider: \"youtube\"\n  video_id: \"XkGFMTyUr5A\"\n\n# Track: Incident Response\n- id: \"kelsey-pederson-rubyconf-2018\"\n  title: \"It's Down! Simulating Incidents in Production\"\n  raw_title: \"RubyConf 2018 - It's Down! Simulating Incidents in Production by Kelsey Pederson\"\n  speakers:\n    - Kelsey Pederson\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-03\"\n  description: |-\n    RubyConf 2018 - It's Down! Simulating Incidents in Production by Kelsey Pederson\n\n    Who loves getting paged at 3am? No one.\n\n    In responding to incidents -- either at 3am or the middle of the day -- we want to feel prepared and practiced in resolving production issues. In this talk, you'll learn how to practice incident response by simulating outages in production. We'll draw from learnings from our simulations at Stitch Fix, like technical implementation strategies, key metrics to watch, and writing runbooks. You'll walk away from this talk with the superhero ability help your team simulate incidents in production.\n\n    Be prepared for your next incident!\n  video_provider: \"youtube\"\n  video_id: \"l03zuqXuxVw\"\n\n# Track: Inside Ruby\n- id: \"aaron-patterson-rubyconf-2018\"\n  title: \"Pointers for Eliminating Heaps of Memory\"\n  raw_title: \"RubyConf 2018 - Pointers for Eliminating Heaps of Memory by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Pointers for Eliminating Heaps of Memory by Aaron Patterson\n\n    In this presentation, we'll cover techniques in Ruby 2.6 that reduce \"dead space\" memory overhead found in all Ruby programs today. First, we'll cover the compilation process of Ruby programs, instruction optimizations, as well as internal data structures used for running Ruby code. Next, we'll look at how to use this information to maintain liveness of Ruby objects in the code. Finally, we'll take all the information we covered so far to develop a technique for reducing dead space in the heap. Remember to mark your calendar because this presentation will be remembered for generations.\n  video_provider: \"youtube\"\n  video_id: \"ZfgxvNUfQdU\"\n\n# Track: General 2\n- id: \"mark-siemers-rubyconf-2018\"\n  title: \"Refactoring the Technical Interview\"\n  raw_title: \"RubyConf 2018 - Refactoring the Technical Interview by Mark Siemers\"\n  speakers:\n    - Mark Siemers\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Refactoring the Technical Interview by Mark Siemers\n\n    Is your technical interview optimized? Could it use a refactor?\n\n    Do you ask candidates questions that could actually influence your production codebase? Or, do you ask them about problems that are solved and standardized? Or worse, contrived and trivial?\n\n    Have you ever asked any of these questions:\n\n    Find min or max in a list\n    Implement a sorting algorithm\n    FizzBuzz (or any contrived algorithm)\n    “Now can you do it recursively?”\n    Leverage your production code and commit history to make your next interview more effective in identifying the right hire. All while having more fun.\n  video_provider: \"youtube\"\n  video_id: \"cMYTwP21dEU\"\n\n# Track: General 1\n- id: \"brandon-weaver-rubyconf-2018\"\n  title: \"Reducing Enumerable - An Illustrated Adventure\"\n  raw_title: \"RubyConf 2018 - Reducing Enumerable - An Illustrated Adventure by Brandon Weaver\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-11-30\"\n  description: |-\n    RubyConf 2018 - Reducing Enumerable - An Illustrated Adventure by Brandon Weaver\n\n    Meet Red. Red is a reducing lemur, and he loves to sum things using the reduce method. The problem is, with Ruby 2.4+ and the sum method he's starting to think reduce isn't that useful anymore. Distraught, Red asks his master for advice, and she sends him off on a grand journey to learn the true powers of the reduce method by reimplementing various methods from Enumerable.\n\n    Join Red on an illustrated adventure through the land of Enumerable as he learns to map, select, find, and more using his trusty reduce.\n\n    If you're new to Ruby and Functional Programming, this is the talk for you.\n  video_provider: \"youtube\"\n  video_id: \"x3b9KlzjJNM\"\n\n# Track: Make It Faster\n- id: \"jamie-gaskins-rubyconf-2018\"\n  title: \"Optimizations in Multiple Dimensions\"\n  raw_title: \"RubyConf 2018 - Optimizations in Multiple Dimensions by Jamie Gaskins\"\n  speakers:\n    - Jamie Gaskins\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-03\"\n  description: |-\n    RubyConf 2018 - Optimizations in Multiple Dimensions by Jamie Gaskins\n\n    Often when we think about performance, we see it as \"if it takes 20 milliseconds to do X, doing X 10 times will take 200ms\". It turns out, there's a lot more to it than that. In this talk, you'll learn about various aspects of performance, circumstances that could make scaling a particular code path non-linear, and even how optimizations can make your app slower.\n  video_provider: \"youtube\"\n  video_id: \"oze1Hu2sUdI\"\n\n# Track: General 2\n- id: \"koichi-sasada-rubyconf-2018\"\n  title: \"Parallel programming in Ruby3 with Guild\"\n  raw_title: \"RubyConf 2018 - Parallel programming in Ruby3 with Guild by Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Parallel programming in Ruby3 with Guild by Koichi Sasada\n\n    Do you want to write the parallel program with Ruby? Ruby 3 will offer new concurrent abstraction: Guild (code name) which enable to run Ruby programs in parallel without difficulties. This presentation will share our current design of Guild and discussions. You can see how to write a parallel program with Guild with prototype implementation.\n  video_provider: \"youtube\"\n  video_id: \"XiujvihOLq8\"\n\n# Track: General 3\n- id: \"sumana-harihareswara-rubyconf-2018\"\n  title: \"Code Review, Forwards and Back\"\n  raw_title: \"RubyConf 2018 - Code Review, Forwards and Back by Sumana Harihareswara & Jason Owen\"\n  speakers:\n    - Sumana Harihareswara\n    - Jason Owen\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Code Review, Forwards and Back by Sumana Harihareswara & Jason Owen\n\n    Your team’s code review practices cause ripple effects far into the future. In this play, see several ways a single code review can go, then fast-forward and rewind to see the effects – on codebase and culture – of different code review approaches.\n\n    The setting: an office conference room. The characters: a developer, who’s written a chunk of new Ruby code, and a team lead, who’s about to review it. The code is not great.\n\n    See a fast-paced montage of ways things can go. Recognize patterns from your past and present. Learn scripts for phrasing criticism constructively. And laugh.\n  video_provider: \"youtube\"\n  video_id: \"-6wX_QvtGdg\"\n\n# Afternoon Break\n\n# Track: General 1\n- id: \"cody-stringham-rubyconf-2018\"\n  title: \"Inheritance, Composition, Ruby and You\"\n  raw_title: \"RubyConf 2018 - Inheritance, Composition, Ruby and You by Cody Stringham\"\n  speakers:\n    - Cody Stringham\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-11-30\"\n  description: |-\n    RubyConf 2018 - Inheritance, Composition, Ruby and You by Cody Stringham\n\n    Prefer composition over inheritance is something you’ve probably heard. You may have even heard more strongly worded arguments against inheritance. This talk will give you the knowledge you need to know whether or not inheritance is a viable solution. While preferring composition is often the right answer, the Ruby language has deep ties into inheritance and we should know it well. If you’re new to Ruby, Object-Oriented programming, or just curious what all the hubbub is about - this talk is aimed at you.\n  video_provider: \"youtube\"\n  video_id: \"_f2LYPpueAY\"\n\n# Track: Make It Faster\n- id: \"molly-struve-rubyconf-2018\"\n  title: \"Cache is King: Get the Most Bang for Your Buck From Ruby\"\n  raw_title: \"RubyConf 2018 - Cache is King: Get the Most Bang for Your Buck From Ruby by Molly Struve\"\n  speakers:\n    - Molly Struve\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-05\"\n  description: |-\n    RubyConf 2018 - Cache is King: Get the Most Bang for Your Buck From Ruby by Molly Struve\n\n    Sometimes your fastest queries can cause the most problems. I will take you beyond the slow query optimization and instead zero in on the performance impacts surrounding the quantity of your datastore hits. Using real world examples dealing with datastores such as Elasticsearch, MySQL, and Redis, I will demonstrate how many fast queries can wreak just as much havoc as a few big slow ones. With each example I will make use of the simple tools available in Ruby to decrease and eliminate the need for these fast and seemingly innocuous datastore hits.\n  video_provider: \"youtube\"\n  video_id: \"vEi-vYcyTT8\"\n\n# Track: General 2\n- id: \"masayoshi-takahashi-rubyconf-2018\"\n  title: \"ROM: the final frontier of mruby\"\n  raw_title: \"RubyConf 2018 - ROM: the final frontier of mruby by Masayoshi Takahashi and Yurie Yamane\"\n  speakers:\n    - Masayoshi Takahashi\n    - Yurie Yamane\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - ROM: the final frontier of mruby by Masayoshi Takahashi and Yurie Yamane\n\n    Memory is limited resource of physical devices. Although mruby is smaller than MRI, it’s not small enough for cheap and easily avaiable devices. But there is another frontier: ROM. Many boards has larger Flash ROM than RAM. However, Ruby is too dynamic to put into ROM just as it is. How can we use ROM to implement classes of Ruby, and how small can we make mruby? It’s a thirty-minutes mission to explore strange new worlds.\n  video_provider: \"youtube\"\n  video_id: \"KVr5nBAaJb4\"\n\n# Track: General 3\n- id: \"greggory-rothmeier-rubyconf-2018\"\n  title: \"Documentation Tradeoffs and Why Good Commits Matter\"\n  raw_title: \"RubyConf 2018 - Documentation Tradeoffs and Why Good Commits Matter by Greggory Rothmeier\"\n  speakers:\n    - Greggory Rothmeier\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Documentation Tradeoffs and Why Good Commits Matter by Greggory Rothmeier\n\n    We've all thought \"what is this thing supposed to do?\" or \"why was this done that way\" moment when looking through codebases and unless there's documentation or you can find the author, the answer is often hard to find. There are many options to document code from comments to internal wikis, so I'll discuss a heuristic for evaluating the options based on the accessibility (how far away is the answer?) and accuracy (how likely is it that what I'm reading is out of date?) to build a case that the git commit message is likely where you should spend your energy documenting. I'll share my workflow and\n  video_provider: \"youtube\"\n  video_id: \"cdpaQ6R7100\"\n\n# Track: General 1\n- id: \"nadia-odunayo-rubyconf-2018\"\n  title: \"The Case of the Missing Method — A Ruby Mystery Story\"\n  raw_title: \"RubyConf 2018 - The Case of the Missing Method — A Ruby Mystery Story by Nadia Odunayo\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-11-30\"\n  description: |-\n    RubyConf 2018 - The Case of the Missing Method — A Ruby Mystery Story by Nadia Odunayo\n\n    Business is slow for Ruby Private Investigator, Deirdre Bug. She’s on the verge of switching industry when she gets a call from an anxious young man. \"Some class methods have gone missing,\" he tells her breathlessly. \"I need your help.\"\n\n    Deirdre takes the case and begins exploring Ruby objects behind the scenes. Though she thinks she's on familiar ground — Ruby's object model, method lookup — she's about to discover that she really has no clue.\n  video_provider: \"youtube\"\n  video_id: \"mn2D_k-X-es\"\n\n# Track: Make It Faster\n- id: \"anna-gluszak-rubyconf-2018\"\n  title: \"Practical Guide To Benchmarking Your Optimizations\"\n  raw_title: \"RubyConf 2018 - Practical guide to benchmarking your optimizations by Anna Gluszak\"\n  speakers:\n    - Anna Gluszak\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Practical guide to benchmarking your optimizations by Anna Gluszak\n\n    Many people believe that ruby applications are inherently slow, yet oftentimes it is the lack of optimization and not the language that is at fault. But how do you even get started with this daunting task of performance optimization? For those that do not have a computer science background, understanding all the different ways of algorithm optimization can sound scary and overwhelming. Some may have a good handle on the theory behind things like the big O notation, but struggle to put it in practice. This talk will focus on a tangible and data driven way to measure and optimize code performance.\n  video_provider: \"youtube\"\n  video_id: \"FapHqq5kU_Y\"\n\n# Track: General 2\n- id: \"takashi-kokubun-rubyconf-2018\"\n  title: \"The secret power of Ruby 2.6: JIT\"\n  raw_title: \"RubyConf 2018 - The secret power of Ruby 2.6: JIT by Takashi Kokubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - The secret power of Ruby 2.6: JIT by Takashi Kokubun\n\n    Have you tried the JIT compiler included in Ruby 2.6 preview releases? It's easy, just include \"--jit\" option to a ruby command or set RUBYOPT=\"--jit\" environment variable. You've just learned how to enable it.\n\n    But wait, are you sure you can use it? What the hell is going on behind it, why is there a GCC process under your Ruby process, and why can JIT even make your Ruby program even slower? In this talk, you'll be prepared to try the brand-new Ruby's secret power on production from the next Christmas.\n  video_provider: \"youtube\"\n  video_id: \"3fidwhVjuhs\"\n\n# Track: General 3\n# Missing Talk: Jeffrey Cohen - Modern Cryptography for the Absolute Beginner\n\n# Track: General 3\n- id: \"alex-stephen-rubyconf-2018\"\n  title: \"Make Ruby Write Your Code for You\"\n  raw_title: \"RubyConf 2018 - Make Ruby Write Your Code for You by Alex Stephen\"\n  speakers:\n    - Alex Stephen\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Make Ruby Write Your Code for You by Alex Stephen\n\n    Despite best intentions, sometimes you just have to write similar code over and over again. This leads to a massive maintenance burden down the road. But, there’s a better way: have the computer write the code for you.\n\n    Code generators are shrouded in mystery and can sound unapproachable, but they aren’t! I’ll show you how code generation is no different than web development and why Ruby has all of the tools to build one quickly. You’ll leave this talk knowing where you could apply code generation in your own code base and how to get started!\n  video_provider: \"youtube\"\n  video_id: \"Ly7lbd7myHU\"\n\n- id: \"lightning-talks-rubyconf-2018\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf 2018 - Lightning Talks\"\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-14\"\n  published_at: \"2018-12-03\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8s--ZyTmFxU\"\n  talks:\n    - title: \"Lightning Talk: Michael Hartl\"\n      start_cue: \"00:00:16\"\n      end_cue: \"00:01:17\"\n      id: \"michael-hartl-lighting-talk-rubyconf-2018\"\n      video_id: \"michael-hartl-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Hartl\n\n    - title: \"Lightning Talk: Christen Rittiger\"\n      start_cue: \"00:01:17\"\n      end_cue: \"00:02:30\"\n      id: \"christen-rittiger-lighting-talk-rubyconf-2018\"\n      video_id: \"christen-rittiger-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Christen Rittiger\n\n    - title: \"Lightning Talk: Tori Machen\"\n      start_cue: \"00:02:30\"\n      end_cue: \"00:06:42\"\n      id: \"tori-machen-lighting-talk-rubyconf-2018\"\n      video_id: \"tori-machen-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Tori Machen\n\n    - title: \"Lightning Talk: Jennifer Tran\"\n      start_cue: \"00:06:42\"\n      end_cue: \"00:11:33\"\n      id: \"jennifer-tran-lighting-talk-rubyconf-2018\"\n      video_id: \"jennifer-tran-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Jennifer Tran\n\n    - title: \"Lightning Talk: Jeremy Schuurmans\"\n      start_cue: \"00:11:33\"\n      end_cue: \"00:14:13\"\n      id: \"jeremy-schuurmans-lighting-talk-rubyconf-2018\"\n      video_id: \"jeremy-schuurmans-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeremy Schuurmans\n\n    - title: \"Lightning Talk: Kazumi Karbowski\"\n      start_cue: \"00:14:13\"\n      end_cue: \"00:18:33\"\n      id: \"kazumi-karbowski-lighting-talk-rubyconf-2018\"\n      video_id: \"kazumi-karbowski-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Kazumi Karbowski\n\n    - title: \"Lightning Talk: Justin Searls\"\n      start_cue: \"00:18:33\"\n      end_cue: \"00:23:27\"\n      id: \"justin-searls-lighting-talk-rubyconf-2018\"\n      video_id: \"justin-searls-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Justin Searls\n\n    - title: \"Lightning Talk: Jacob Crofts\"\n      start_cue: \"00:23:27\"\n      end_cue: \"00:29:20\"\n      id: \"jacob-crofts-lighting-talk-rubyconf-2018\"\n      video_id: \"jacob-crofts-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Jacob Crofts\n\n    - title: \"Lightning Talk: Roman Kofman\"\n      start_cue: \"00:29:20\"\n      end_cue: \"00:34:15\"\n      id: \"roman-kofman-lighting-talk-rubyconf-2018\"\n      video_id: \"roman-kofman-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Roman Kofman\n\n    - title: \"Lightning Talk: Ariel Caplan\"\n      start_cue: \"00:34:15\"\n      end_cue: \"00:38:03\"\n      id: \"ariel-caplan-lighting-talk-rubyconf-2018\"\n      video_id: \"ariel-caplan-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Ariel Caplan\n\n    - title: \"Lightning Talk: Jamie Gaskins\"\n      start_cue: \"00:38:03\"\n      end_cue: \"00:42:14\"\n      id: \"jamie-gaskins-lighting-talk-rubyconf-2018\"\n      video_id: \"jamie-gaskins-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Jamie Gaskins\n\n    - title: \"Lightning Talk: Aja Hammerly\"\n      start_cue: \"00:42:14\"\n      end_cue: \"00:45:47\"\n      id: \"aja-hammerly-lighting-talk-rubyconf-2018\"\n      video_id: \"aja-hammerly-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Aja Hammerly\n\n    - title: \"Lightning Talk: Isaac Sloan\"\n      start_cue: \"00:45:47\"\n      end_cue: \"00:50:45\"\n      id: \"isaac-sloan-lighting-talk-rubyconf-2018\"\n      video_id: \"isaac-sloan-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Isaac Sloan\n\n    - title: \"Lightning Talk: Zachary Schroeder\"\n      start_cue: \"00:50:45\"\n      end_cue: \"00:55:49\"\n      id: \"zachary-schroeder-lighting-talk-rubyconf-2018\"\n      video_id: \"zachary-schroeder-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Zachary Schroeder\n\n    - title: \"Lightning Talk: Junichi Ito\"\n      start_cue: \"00:55:49\"\n      end_cue: \"01:00:40\"\n      id: \"junichi-ito-lighting-talk-rubyconf-2018\"\n      video_id: \"junichi-ito-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Junichi Ito\n\n    - title: \"Lightning Talk: Tom Black\"\n      start_cue: \"01:00:40\"\n      end_cue: \"01:05:40\"\n      id: \"tom-black-lighting-talk-rubyconf-2018\"\n      video_id: \"tom-black-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Tom Black\n\n    - title: \"Lightning Talk: Quinn Stearns\"\n      start_cue: \"01:05:40\"\n      end_cue: \"01:09:44\"\n      id: \"quinn-stearns-lighting-talk-rubyconf-2018\"\n      video_id: \"quinn-stearns-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Quinn Stearns\n\n    - title: \"Lightning Talk: Antoine Lecl\"\n      start_cue: \"01:09:44\"\n      end_cue: \"01:13:27\"\n      id: \"antoine-lecl-lighting-talk-rubyconf-2018\"\n      video_id: \"antoine-lecl-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Antoine Lecl\n\n    - title: \"Lightning Talk: Scott Istvan\"\n      start_cue: \"01:13:27\"\n      end_cue: \"1:17:35\"\n      id: \"scott-istvan-lighting-talk-rubyconf-2018\"\n      video_id: \"scott-istvan-lighting-talk-rubyconf-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Scott Istvan\n\n## Day 3\n\n- id: \"jessie-shternshus-rubyconf-2018\"\n  title: \"Keynote: Unlearning - The Challenge of Change by Jessie Shternshus\"\n  raw_title: \"RubyConf 2018 - Keynote: Unlearning - The Challenge of Change by Jessie Shternshus\"\n  speakers:\n    - Jessie Shternshus\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-05\"\n  description: |-\n    RubyConf 2018 - Keynote: Unlearning - The Challenge of Change by Jessie Shternshus\n  video_provider: \"youtube\"\n  video_id: \"M0yO5sPxp-w\"\n\n# Track: General 1\n- id: \"thomas-e-enebo-rubyconf-2018\"\n  title: \"JRuby 2018: Real World Performance\"\n  raw_title: \"RubyConf 2018 - JRuby 2018: Real World Performance by Thomas Enebo & Charles Nutter\"\n  speakers:\n    - Thomas E Enebo\n    - Charles Nutter\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - JRuby 2018: Real World Performance by Thomas Enebo & Charles Nutter\n\n     This year has been big for JRuby! We're pushing the edges of performance on the JVM and now see large frameworks running much faster than CRuby. This talk will cover the optimizations we've done in 2018 and what impact they're having on performance. We'll go through several features that did not optimize well before the recent work. We'll talk about supporting new Rails versions and how we're working to make Rails apps more reliable, more concurrent, and more scalable. Finally we will discuss what the future holds and how you can get involved.\n  video_provider: \"youtube\"\n  video_id: \"_U-5TE9tBBA\"\n\n# Track: General 2\n- id: \"tekin-sleyman-rubyconf-2018\"\n  title: \"Branch In Time\"\n  raw_title: \"RubyConf 2018 - Branch in Time by Tekin Suleyman\"\n  speakers:\n    - Tekin Süleyman\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-06\"\n  description: |-\n    RubyConf 2018 - Branch in Time by Tekin Suleyman\n\n    In one timeline, a quick path to clarity. In the other, a long and painful journey trying to understand the obscure intent of a line of code. The only difference between the two realities? The revision history...\n\n    This is a story about writing maintainable software. But rather than the code itself, we’ll see how a well-crafted revision history is as important to maintainability as choosing the right abstraction. We'll explore the differences between a useful history and an unhelpful one. And you'll learn about the practices, tools and techniques that help make the difference.\n  video_provider: \"youtube\"\n  video_id: \"8OOTVxKDwe0\"\n\n# Track: Lead Rubyist\n- id: \"jim-liu-rubyconf-2018\"\n  title: \"No Title Required: How Leadership Can Come From Anywhere\"\n  raw_title: \"RubyConf 2018 - No Title Required: How Leadership Can Come From Anywhere by Jim Liu\"\n  speakers:\n    - Jim Liu\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-05\"\n  description: |-\n    RubyConf 2018 - No Title Required: How Leadership Can Come From Anywhere by Jim Liu\n\n    Think you can't take on a leadership role because you're too junior? Because you're in a remote office? Because you don't have \"manager\" in your title?\n\n    The truth is that all of these blockers (and more) are artificial. How do I know this? Because over the past 6 months, I could answer yes to all three of the questions above. At the same time, I was able to co-lead the engineering effort on one of the most complex parts of our company's product. We'll explore how to bridge the gap between that title you wish you had versus the impact you can actually have.\n  video_provider: \"youtube\"\n  video_id: \"yEork8Tq2NE\"\n\n# Track: General 3\n- id: \"kevin-kuchta-rubyconf-2018\"\n  title: \"Ruby is the Best JavaScript\"\n  raw_title: \"RubyConf 2018 - Ruby is the Best JavaScript by Kevin Kuchta\"\n  speakers:\n    - Kevin Kuchta\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-11\"\n  description: |-\n    RubyConf 2018 - Ruby is the Best JavaScript by Kevin Kuchta\n\n    Some people love Ruby and some people love JavaScript. Both will hate this talk. In a display of complete moral depravity, we'll abuse flexible syntax and metaprogramming to make valid Ruby code that's indistinguishable from JavaScript. We'll use a variety of tricks to accomplish it that you can take home and use in more respectable code.\n  video_provider: \"youtube\"\n  video_id: \"datDkio1AXM\"\n\n# Track: RubyKaigi\n- id: \"satoshi-moris-tagomori-rubyconf-2018\"\n  title: \"Hijacking Ruby Syntax in Ruby\"\n  raw_title: 'RubyConf 2018 - Hijacking Ruby Syntax in Ruby by Satoshi \"Moris\" Tagomori & Tomohiro Hashidate'\n  speakers:\n    - Satoshi Tagomori\n    - Tomohiro Hashidate\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - Hijacking Ruby Syntax in Ruby by Satoshi Tagomori & Tomohiro Hashidate\n\n    This talk shows how to introduce new syntax-ish stuffs using meta programming techniques and some more Ruby features not known well by many Rubyists. Have fun with magical code!\n\n    Show Ruby features to hack Ruby syntax (including Binding, TracePoint, Refinements, etc)\n    Describe stuffs introduced by these techniques\n    method modifiers (final, abstract, override)\n    Table-like syntax for testing DSL\n    Safe resource allocation/collection (with, defer)\n  video_provider: \"youtube\"\n  video_id: \"ZPaxvU7dMBU\"\n\n# Track: General 1\n- id: \"chris-salzberg-rubyconf-2018\"\n  title: \"Building Generic Software\"\n  raw_title: \"RubyConf 2018 - Building Generic Software by Chris Salzberg\"\n  speakers:\n    - Chris Salzberg\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-06\"\n  description: |-\n    RubyConf 2018 - Building Generic Software by Chris Salzberg\n\n    As engineers, most of the software we build is built for a specific purpose. Whether to serve web pages or solve math equations, that purpose makes our code meaningful and easy to comprehend.\n\n    But under the hood, it is generic software - software that solves whole classes of problems at once - that powers our applications. Ruby has one of the most vibrant ecosystems of such software, but good luck studying its design principles in any tutorial or coding school.\n\n    Instead, join me for a dive into this mysterious, hidden world, and learn to contribute where it counts: at the root of the problem\n  video_provider: \"youtube\"\n  video_id: \"RZkemV_-__A\"\n\n# Track: Lead Rubyist\n- id: \"jennifer-tu-rubyconf-2018\"\n  title: \"Humans Aren't APIs And Your Request Is 400 Denied\"\n  raw_title: \"RubyConf 2018 - Humans Aren't APIs And Your Request Is 400 Denied by Jennifer Tu\"\n  speakers:\n    - Jennifer Tu\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-05\"\n  description: |-\n    RubyConf 2018 - Humans Aren't APIs And Your Request Is 400 Denied by Jennifer Tu\n\n    Have you ever asked someone to do something, and they hear the exact opposite?\n\n    Why do miscommunications happen? Does knowing why matter? And more importantly, how do you achieve your original desired request?\n\n    If you want to learn more ways to influence those around you, this talk is for you! You’ll learn about different causes for failed communications, and different workarounds you can apply for different failure modes. Come to this talk to add another tool to your communications toolbox.\n  video_provider: \"youtube\"\n  video_id: \"jnC-JvbqnlA\"\n\n# Track: General 2\n- id: \"cameron-dutro-rubyconf-2018\"\n  title: \"Cheating with Ruby\"\n  raw_title: \"RubyConf 2018 - Cheating with Ruby by Cameron Dutro\"\n  speakers:\n    - Cameron Dutro\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-06\"\n  description: |-\n    RubyConf 2018 - Cheating with Ruby by Cameron Dutro\n\n    I used Ruby to cheat at a computer game, and it was so much fun. Come to this talk to hear about a game solver that analyzes a screenshot of the game and calculates the correct answer. We'll chat about dynamic image analysis, perceptual hashes, and the traveling salesman problem. I promise, it's going to be great.\n  video_provider: \"youtube\"\n  video_id: \"fmxTHBO2Yzc\"\n\n# Lunch\n\n- id: \"joseph-wilk-rubyconf-2018\"\n  title: \"d[-_-]b REPL-ELECTRIC\"\n  raw_title: \"RubyConf 2018 - d[-_-]b REPL-ELECTRIC by Joseph Wilk\"\n  speakers:\n    - Joseph Wilk\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-05\"\n  description: |-\n    RubyConf 2018 - d[-_-]b REPL-ELECTRIC by Joseph Wilk\n  video_provider: \"youtube\"\n  video_id: \"jVgGYFfifAs\"\n\n# Track: RubyKaigi\n- id: \"yoh-osaki-rubyconf-2018\"\n  title: \"Building web-based board games only with Ruby\"\n  raw_title: \"RubyConf 2018 - Building web-based board games only with Ruby by Yoh Osaki\"\n  speakers:\n    - Yoh Osaki\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-05\"\n  description: |-\n    RubyConf 2018 - Building web-based board games only with Ruby by Yoh Osaki\n\n    This talk explains how to build web-based board games without JavaScript but only with Ruby. Web programmers are forced to write front-end code using JavaScript. And interaction with the client-side and server-side grows increasingly complex. Board game which has rich UI and communicate in real-time is one of the applications which needs such requirements.\n\n    Opal is a compiler converts from Ruby to JavaScript. I created some gems for Opal as follow as.\n\n    Virtual DOM\n    Isomorphic web programming framework\n    dRuby implementation on browser\n    I show you a web- board game demonstration using these gems.\n  video_provider: \"youtube\"\n  video_id: \"RdcjZs8Ysng\"\n\n# Track: General 1\n- id: \"andrew-louis-rubyconf-2018\"\n  title: \"Building a Memex (with Ruby!)\"\n  raw_title: \"RubyConf 2018 - Building a Memex (with Ruby!) by Andrew Louis\"\n  speakers:\n    - Andrew Louis\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-06\"\n  description: |-\n    RubyConf 2018 - Building a Memex (with Ruby!) Andrew Louisa\n\n    In 1945, the Memex was supposed to be the ultimate personal library. In addition to storing information, users could navigate, organize, link, and share data. But tragically, it was never built.\n\n    73 years later, I’m building one in Ruby. I’ve created dozens of importers for different services I use, organized the 10M data points into a graph schema, and used Ruby to tie everything together. Almost all aspects of my life and personal history are now available through an API.\n\n    I’ll go over the history of the Memex, how I used Ruby to build my own, and do a demo of what I can do with it.\n  video_provider: \"youtube\"\n  video_id: \"DFWxvQn4cf8\"\n\n# Track: Lead Rubyist\n- id: \"brandon-hays-rubyconf-2018\"\n  title: \"The New Manager's Toolkit\"\n  raw_title: \"RubyConf 2018 - The New Manager's Toolkit by Brandon Hays\"\n  speakers:\n    - Brandon Hays\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-05\"\n  description: |-\n    RubyConf 2018 - The New Manager's Toolkit by Brandon Hays\n\n    Congratulations, you've been entrusted to lead a team! But wait... what does that mean? You didn't go to school for this. You may not have even been told what your job exactly is. Some call this new responsibility the \"Stone of Triumph\".\n\n    In this talk, we'll explain leading and managing (and how they're different), outline what success looks like, and show techniques to get there. You'll learn how to build the skills and tools to carry the \"Stone of Triumph\" with less pain, and set yourself up for a long and happy career leading creative and technical teams.\n  video_provider: \"youtube\"\n  video_id: \"67ky0Lxsq14\"\n\n# Track: General 2\n- id: \"damir-svrtan-rubyconf-2018\"\n  title: \"Building Serverless Ruby Bots\"\n  raw_title: \"RubyConf 2018 - Building Serverless Ruby Bots by Damir Svrtan\"\n  speakers:\n    - Damir Svrtan\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-05\"\n  description: |-\n    RubyConf 2018 - Building Serverless Ruby Bots by Damir Svrtan\n\n    Want to build a Bot without the hassle of provisioning and managing servers? Amazon’s got a service for that and it’s called AWS Lambda - it executes your code only when needed, scales automatically and you pay only for the compute time you consume.\n\n    There’s one problem with Lambda - it doesn’t support Ruby! Let’s checkout multiple options on how to build a Ruby Bot and package it into an executable which you can run on any machine without the need to actually have Ruby installed.\n  video_provider: \"youtube\"\n  video_id: \"USktC3PLE9s\"\n\n# Track: RubyKaigi\n- id: \"itoyanagi-sakura-rubyconf-2018\"\n  title: \"The New Design of Ruby's Documentation\"\n  raw_title: \"RubyConf 2018 - The New Design of Ruby's Documentation by ITOYANAGI Sakura\"\n  speakers:\n    - ITOYANAGI Sakura\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf 2018 - The New Design of Ruby's Documentation by ITOYANAGI Sakura\n\n    Unlike many other languages, Ruby doesn't have great design for documentation. Perl has \"perldoc\" feature and users easily access documents of modules by \"perldoc\" command. Python has \"docstring\" feature and users can access it on REPL. Those are each language's design of importance. The features are not just tool, it contains toolchains and eco-systems. Users of these languages benefit from good documentation design, so library authors write good documentation for them.\n\n    I'll talk about new Ruby 3's standard documentation design. It pretty improves your development experience.\n  video_provider: \"youtube\"\n  video_id: \"clahP0C0-Xg\"\n\n# Track: General 1\n- id: \"adam-forsyth-rubyconf-2018\"\n  title: \"Beating Mastermind: Winning with the help of Donald Knuth\"\n  raw_title: \"RubyConf 2018 - Beating Mastermind: Winning with the help of Donald Knuth by Adam Forsyth\"\n  speakers:\n    - Adam Forsyth\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-06\"\n  description: |-\n    RubyConf 2018 - Beating Mastermind: Winning with the help of Donald Knuth by Adam Forsyth\n\n    Come solve logic games with Ruby, learn about minimax algorithms, and turn a paper into code. There are lots of \"solved\" problems out there that don't have a good library available -- learn how to write one yourself. We'll take a paper written by Donald Knuth (the \"father of analysis of algorithms\" and author of \"The Art of Computer Science\") and use it to solve a game called Mastermind that many people (including me) played as children. We'll look at the game, walk through the paper, turn the prose and math into code, understand minimax algorithms, and never lose at Mastermind again!\n  video_provider: \"youtube\"\n  video_id: \"Okm_t5T1PiA\"\n\n# Track: Lead Rubyist\n- id: \"nickolas-means-rubyconf-2018\"\n  title: \"Eiffel's Tower\"\n  raw_title: \"RubyConf 2018 - Eiffel's Tower by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-05\"\n  description: |-\n    RubyConf 2018 - Eiffel's Tower by Nickolas Means\n\n    When Gustave Eiffel built his namesake tower, it was nearly twice as tall as the tallest structure on Earth. His crews built it in an astounding 22 months, pioneering new construction techniques to deliver it in time for the opening of the 1889 Exposition Universelle. It was amazing then, and it’s just as captivating today.\n\n    We all say we want to do groundbreaking work, but what does it actually take to push an organization forward? The answer starts long before the work itself. Let’s see what we can learn from how Gustave Eiffel went about building his record-shattering tower.\n  video_provider: \"youtube\"\n  video_id: \"RslVT-L2A40\"\n\n# Track: General 2\n- id: \"vladimir-dementyev-rubyconf-2018\"\n  title: \"High-Speed Cables for Ruby\"\n  raw_title: \"RubyConf 2018 - High-speed cables for Ruby by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-06\"\n  description: |-\n    RubyConf 2018 - High-speed cables for Ruby by Vladimir Dementyev\n\n    Modern web applications actively use real-time features. Unfortunately, nowadays Ruby is rarely considered as a technology to implement yet another chat – Ruby performance leaves much to be desired when dealing with concurrency and high-loads.\n\n    Does this mean that we should betray our favorite language, which brings us happiness, in favor of others?\n\n    My answer is NO, and I want to show you, how we can combine the elegance of Ruby with the power of other languages to improve the performance of real-time applications.\n  video_provider: \"youtube\"\n  video_id: \"8XRcOZXOzV4\"\n\n# Afternoon Break\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2018-qa-with-matz\"\n  title: \"Q&A with Matz\"\n  raw_title: \"RubyConf 2018 - Q&A with Matz by Yukihiro Matsumoto 'Matz'\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2018\"\n  date: \"2018-11-15\"\n  published_at: \"2018-12-05\"\n  description: |-\n    RubyConf 2018 - Q&A with Matz by Yukihiro Matsumoto 'Matz'\n  video_provider: \"youtube\"\n  video_id: \"gwZbR2oyjmQ\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2019/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZDE8nFrKaqkpd-XK4huygU\"\ntitle: \"RubyConf 2019\"\nkind: \"conference\"\nlocation: \"Nashville, TN, United States\"\ndescription: |-\n  Focused on fostering the Ruby programming language and the robust community that has sprung up around it, RubyConf brings together Rubyists both established and new to discuss emerging ideas, collaborate, and socialize in some of the best locations in the US. Come join us in Los Angeles for what will surely be the best RubyConf yet!\n\n  One of our key goals for RubyConf is to provide an inclusive and welcoming experience for all participants. To that end, we have an anti-harassment policy that we require ALL attendees, speakers, sponsors, volunteers, and staff to comply with — no exceptions.\nstart_date: \"2019-11-18\"\nend_date: \"2019-11-20\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2019\nbanner_background: \"#000000\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#F5C347\"\ncoordinates:\n  latitude: 36.1626638\n  longitude: -86.7816016\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2019/videos.yml",
    "content": "---\n# https://web.archive.org/web/20191024074737/http://rubyconf.org/schedule\n\n## Day 1\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2019\"\n  title: \"Opening Keynote: Ruby Progress Report\"\n  raw_title: \"RubyConf 2019 - Opening Keynote - Ruby Progress Report by Yukihiro Matsumoto (Matz)\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-11-27\"\n  description: |-\n    RubyConf 2019 - Opening Keynote - Ruby Progress Report by Yukihiro Matsumoto (Matz)\n\n    #confreaks #rubyconf2019 #rubyconf\n  video_provider: \"youtube\"\n  video_id: \"2g9R7PUCEXo\"\n\n- id: \"coraline-ada-ehmke-rubyconf-2019\"\n  title: \"Thomas Edison vs Three Teslas in a Trenchcoat\"\n  raw_title: \"RubyConf 2019 - Thomas Edison vs Three Teslas in a Trenchcoat by Coraline Ada Ehmke\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-11-27\"\n  description: |-\n    RubyConf 2019 - Thomas Edison vs Three Teslas in a Trenchcoat by Coraline Ada Ehmke\n\n    As a company grows, adopting new technologies becomes more complex, costly, and risky. But as developers we want to keep our skills up-to-date and are often drawn to the latest and hottest tools. So how can we effectively experiment with new technologies at work in a responsible way? This talk will recount the famously adversarial relationship between Thomas Edison and Nicola Tesla, and from their story we will learn ways to balance and exploit the tension between the boring and the new, the familiar and the shiny, the safe and the unknown.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"i5uBjcYARkU\"\n\n- id: \"noah-gibbs-rubyconf-2019\"\n  title: \"Conscious Coding Practice: The Three Concrete Steps\"\n  raw_title: \"RubyConf 2019 - Conscious Coding Practice: The Three Concrete Steps by Noah Gibbs\"\n  speakers:\n    - Noah Gibbs\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-03\"\n  description:\n    \"RubyConf 2019 - Conscious Coding Practice: The Three Concrete Steps by Noah Gibbs\n\n\n    You feel guilty about not knowing enough \\\"Computer Science.\\\" But that isn't what you're still missing in your coding. If you could just pick up any problem and solve it, you\n    wouldn't care if you used a formal-sounding algorithm to do it.\n\n\n    There's a way to get that \\\"fingertip feel\\\" for coding. And it comes from mindful, conscious practice.\\r\n\n\n    Sounds abstract, doesn't it? Instead, it's very simple, specific and concrete. We'll go over the basic steps, the pitfalls, and how to do it. It works whether you're a beginner\n    or an expert. You'll be able to create coding studies for yourself, not just find other people's exercises that are already worked out for you.\\r\n\n\n    This talk is in Ruby. But the technique works with any language, library or paradigm. It's also good for pairing.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"33fAzjOTaDE\"\n\n- id: \"avdi-grimm-rubyconf-2019\"\n  title: \"No Return: Beyond Transactions in Code and Life\"\n  raw_title: \"RubyConf 2019 - No Return: Beyond Transactions in Code and Life by Avdi Grimm\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-03\"\n  description: |-\n    RubyConf 2019 - No Return: Beyond Transactions in Code and Life by Avdi Grimm\n\n    At the root of catastrophes in both code and life lies a pervasive fallacy: the attempt to model processes as if they were transactions. Join me for an honest, sometimes raw retrospective on two decades of building a software development career. We’ll examine how personal philosophy impacts software design—and vice-versa. We’ll encounter the Transactional Fallacy, and how it can hinder our attempts to build resilient systems. And we’ll explore how a narrative-oriented mindset can lead to both better code and a more joyful life.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"qoriifl-z3Q\"\n\n- id: \"ivan-nemytchenko-rubyconf-2019\"\n  title: \"Less abstract! Surprising effects of expressing rules of OOP in pictures\"\n  raw_title: \"RubyConf 2019 -  Less abstract! Surprising effects of expressing rules of OOP... by Ivan Nemytchenko\"\n  speakers:\n    - Ivan Nemytchenko\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-04\"\n  description:\n    \"RubyConf 2019 -  Less abstract! Surprising effects of expressing rules of OOP in pictures by Ivan Nemytchenko\n\n\n    Abstractions are both our blessing and our curse. Because of them, we're so powerful. But also we so often fall into the trap of miscommunication :( Abstract rules, operating\n    with abstract terms, built on top of other abstract ideas. Ugh... In this talk, we're going to build a visual language to make things LESS ABSTRACT. We'll see how it helps\n    in:\\r\n\n\n\n    refactoring messy code\n\n    tracking codebase changes\n\n    teaching others\n\n    explaining non-obvious concepts\n\n\n    #rubyconf2019 #confreaks\"\n  video_provider: \"youtube\"\n  video_id: \"JH8KSPfFvxs\"\n\n- id: \"keavy-mcminn-rubyconf-2019\"\n  title: \"Principles of Awesome APIs and How to Build Them\"\n  raw_title: \"RubyConf 2019 - Principles of Awesome APIs and How to Build Them by Keavy McMinn\"\n  speakers:\n    - Keavy McMinn\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-11-27\"\n  description: |-\n    RubyConf 2019 - Principles of Awesome APIs and How to Build Them by Keavy McMinn\n\n    We know the theory of what makes for a good API: it should be consistent, stable, and well documented. However, when we struggle to put good principles into practice, the API becomes difficult for your teammates and frustrating for your users. So, how do we pragmatically implement APIs in line with good principles? In particular, how do we get a bundle of engineers to do this together?\n\n    This is a talk for those curious about designing, building, and maintaining modern APIs. We’ll look at specific tooling and strategies to help improve and maintain the quality, consistency, and stability of your API. You’ll learn how to proactively make improvements to these areas, and how to make it easier to shepherd API development in your company.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"NgFm7qAhv9g\"\n\n- id: \"kevin-kuchta-rubyconf-2019\"\n  title: \"Source-Diving for Fun and Profit\"\n  raw_title: \"RubyConf 2019 - Source-Diving for Fun and Profit by Kevin Kuchta\"\n  speakers:\n    - Kevin Kuchta\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-03\"\n  description: \"RubyConf 2019 - Source-Diving for Fun and Profit by Kevin Kuchta\n\n\n    Ever spent hours pouring over a gem's documentation trying to figure out how to make it work? Dug through dozens of blog posts trying to understand why a library's not working?\n    Well what if I promised you an end to all that?!\n\n    \\r\n\n\n    Well, ok, I'd be lying. But maybe I can save you some hair-pulling some of the time! Let me introduce you to the joys of Reading the Code. Maybe it seems obvious to you, but\n    one of the biggest leaps I made as a ruby dev was really getting comfortable jumping into a gem's source as a debugging technique.\\r\n\n\n    \\r\n\n\n    In an effort to get you over that hump earlier than I did, let's talk tips and tricks for getting in and out of a library's codebase as efficiently as possible. It won't solve\n    every problem, but sometimes 5 minutes on GitHub will save you hours on StackOverflow.\n\n\n    #rubyconf2019 #confreaks\"\n  video_provider: \"youtube\"\n  video_id: \"2YobJGkSSrU\"\n\n- id: \"betsy-haibel-rubyconf-2019\"\n  title: \"Investigative Metaprogramming\"\n  raw_title: \"RubyConf 2019 - Investigative Metaprogramming by Betsy Haibel\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-03\"\n  description: |-\n    RubyConf 2019 - Investigative Metaprogramming by Betsy Haibel\n\n    When was the last time you got an un-Googleable error? The kind that takes you and your lead three days to debug, with weird generic stacktraces deep in framework internals? What if you could approach that bug with something other than trial, error, and tears? Metaprogramming can come to the rescue -- just not the kind you do in production. In this talk, you'll learn strategies for investigative metaprogramming. You'll learn how to insert debugging hooks anywhere and instrument anything. You'll even learn how to turn that information into actionable bugfixes.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"bJMzWumXPmo\"\n\n- id: \"deedee-lavinder-rubyconf-2019\"\n  title: \"How to Become an Encoding Champion\"\n  raw_title: \"RubyConf 2019 - How to Become an Encoding Champion by Deedee Lavinder\"\n  speakers:\n    - DeeDee Lavinder\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-04\"\n  description: |-\n    RubyConf 2019 - How to Become an Encoding Champion by Deedee Lavinder\n\n    encoding&#39;s\n\n    Character encoding happens every time we interact with a computer or any digital device. There is no such thing as plain text. Understanding how encoding works, how Ruby handles encoding issues, and how to strategically debug encoding snafus, can be a great asset in your developer toolbox. We will cover a bit of history, dive deep into Ruby's encoding methods, and learn some tricks for managing encoding in your application.\n\n    #rubyconf2019 #confreaks\n  video_provider: \"youtube\"\n  video_id: \"3Uut6DEgW-4\"\n\n# Lunch\n\n- id: \"adam-cuppy-rubyconf-2019\"\n  title: \"Game Show: Syntax Error\"\n  raw_title: \"RubyConf 2019 - Syntax Error Game Show\"\n  speakers:\n    - Adam Cuppy\n    - Jonan Scheffler\n    - Filipe Costa\n    - Yvone Sanchez Reyes\n    - Carolyn Cole\n    - Penelope Phippen\n    - Lachlan Hardy\n    - Davy Stevenson\n    - Marla Zeschin\n    - Britni Alexander\n    - Sandi Metz\n    - Colin Pulton\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-04\"\n  description: |-\n    Syntax Error Game Show\n\n    Host - Adam Cuppy\n\n    Round 1 contestants - Jonan Scheffler and Filipe Costa\n\n    Round 2 contestants - Yvone Sanchez Reyes and Carolyn Cole\n\n    Panelists - Penelope Phippen, Lachlan Hardy, Davy Stevenson, Marla Zeschin, Britni Alexander, Sandi Metz, and Colin Pulton,\n\n\n    #confreaks #rubyconf2019 #rubyconf\n  video_provider: \"youtube\"\n  video_id: \"P4f83eqJN-c\"\n\n- id: \"kazuki-tsujimoto-rubyconf-2019\"\n  title: \"Pattern Matching - New feature in Ruby 2.7\"\n  raw_title: \"RubyConf 2019 - Pattern Matching - New feature in Ruby 2.7 by Kazuki Tsujimoto\"\n  speakers:\n    - Kazuki Tsujimoto\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-11-27\"\n  description: |-\n    RubyConf 2019 - Pattern Matching - New feature in Ruby 2.7 by Kazuki Tsujimoto\n\n    Ruby core team plans to introduce pattern matching as an experimental feature in Ruby 2.7. In this presentation, we will talk about the current proposed syntax and its design policy.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"wo4eZ2iVIyo\"\n\n- id: \"mina-slater-rubyconf-2019\"\n  title: \"Bridging the Knowledge Gap: Debugging\"\n  raw_title: \"RubyConf 2019 - Bridging the Knowledge Gap: Debugging by Mina Slater\"\n  speakers:\n    - Mina Slater\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-03\"\n  description:\n    \"RubyConf 2019 - Bridging the Knowledge Gap: Debugging by Mina Slater\n\n\n    We're usually never get an official lesson in debugging. No one tells us at bootcamp or in online tutorials what to do when our code doesn’t work. It’s one of those\n    learn-it-on-the-job sort of things and comes with experience. As early-career developers, we get a lot of syntax thrown at us when we’re first learning, but in actuality, the\n    majority of our time is spent trying to fix broken code.\n\n    \\r\n\n\n    But why should we slog through it alone? Let’s explore some Ruby/Rails debugging techniques and tools together!\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"DT5XeAnXifI\"\n\n- id: \"daniel-azuma-rubyconf-2019\"\n  title: \"Ruby ate my DSL!\"\n  raw_title: \"RubyConf 2019 - Ruby ate my DSL! by Daniel Azuma\"\n  speakers:\n    - Daniel Azuma\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-03\"\n  description: |-\n    RubyConf 2019 - Ruby ate my DSL! by Daniel Azuma\n\n    DSLs (Domain-Specific Languages) are fun to design, but it's easy to forget that they are still \"Just Ruby.\" If users of your DSL can mix in Ruby code... any Ruby code... you can bet they will, and it's all too easy for that to go awry. In this session, you'll encounter examples of how seemingly innocuous Ruby code can make a DSL go disastrously wrong, and you’ll learn techniques you can use to harden your DSL against the cleverness of your users. If you’re writing, or even thinking of writing a DSL, this talk is for you.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"Ov-tMtOkKS4\"\n\n- id: \"joe-leo-rubyconf-2019\"\n  title: \"The Functional Rubyist\"\n  raw_title: \"RubyConf 2019 - The Functional Rubyist by Joe Leo\"\n  speakers:\n    - Joe Leo\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-04\"\n  description: |-\n    RubyConf 2019 - The Functional Rubyist by Joe Leo\n\n    Functional programming’s popularity is on the rise and support for FP is growing in Ruby. But can you really write functional code in Ruby? More importantly, why should you? Learn how Ruby enables functional programming concepts while maintaining highly readable and fun-to-write code.\n\n    #rubyconf2019 #confreaks\n  video_provider: \"youtube\"\n  video_id: \"BV1-Z38ZWQU\"\n\n- id: \"hitoshi-hasumi-rubyconf-2019\"\n  title: \"mruby/c: Running on Less Than 64KB RAM Microcontroller\"\n  raw_title: \"RubyConf 2019 - mruby/c: Running on Less Than 64KB RAM Microcontroller by HASUMI Hitoshi\"\n  speakers:\n    - HASUMI Hitoshi\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-11-27\"\n  description: |-\n    RubyConf 2019 - mruby/c: Running on Less Than 64KB RAM Microcontroller by HASUMI Hitoshi\n\n    I will show you an actual IoT product which uses one-chip-microcontroller-based hardwares for a Japanese Sake Brewery. Brewing Sake requires workers to take temperature of the ingredients very frequently. mruby/c is a small implementation of Ruby and runs on microcontroller which has less than 64KB RAM. You will see a new Ruby World.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"1VFPSHs3WvI\"\n\n- id: \"michael-hartl-rubyconf-2019\"\n  title: \"Learn Enough Ruby\"\n  raw_title: \"RubyConf 2019 - Learn Enough Ruby by Michael Hartl\"\n  speakers:\n    - Michael Hartl\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-03\"\n  description: |-\n    RubyConf 2019 - Learn Enough Ruby by Michael Hartl\n\n    Ruby is a big language, used for lots of different things—so, where to start? This talk discusses the core subjects needed to learn enough Ruby to be productive, focusing both on features it has in common with other languages and the things that make it unique. For those interested in web development, we’ll also talk about the pros and cons of learning Ruby before Rails, as well as whether to learn Rails at all.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"NGXp6_-nc4s\"\n\n- id: \"vladimir-dementyev-rubyconf-2019\"\n  title: \"Ruby Next: Make old Ruby quack like a new one\"\n  raw_title: \"RubyConf 2019 - Ruby Next: make old Ruby quack like a new one by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-03\"\n  description:\n    \"RubyConf 2019 - Ruby Next: make old Ruby quack like a new one by Vladimir Dementyev\n\n\n    Ruby 2.7 is just around the corner. It will bring a lot of new features, including new syntax additions: pattern matching, numbered parameters.\n\n\n    That's good news. The bad news is that not many of us will be able to use these goodies right away: the upgrade cost blocks application developers; gem authors have to support\n    older versions.\\r\n\n\n    What if we were able to use Ruby Next features while running Ruby Current? Maybe, we can cast a metaprogramming spell for that? Yes, we can. And I'll show you how.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"T6epHXlUmG0\"\n\n- id: \"ben-greenberg-rubyconf-2019\"\n  title: \"What's Love Got To Do With It? Ruby and Sentiment Analysis\"\n  raw_title: \"RubyConf 2019 - What's Love Got To Do With It? Ruby and Sentiment Analysis by Ben Greenberg\"\n  speakers:\n    - Ben Greenberg\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-04\"\n  description:\n    \"RubyConf 2019 - What's Love Got To Do With It? Ruby and Sentiment Analysis by Ben Greenberg\n\n\n    The societies we live in, the companies we work for, the media we consume and much more are all shaped by words. Words can infuriate, enlighten, bring joy or cause great\n    despair. Natural Language Understanding gives us a window into analyzing the words that surround us for sentiment and tone.\n\n\n    How does Natural Language Understanding work? What insights can we glean from the data it provides?\\r\n\n\n    We will take a dive into understanding how this technology works, and apply it in a Ruby app that connects Natural Language Understanding analysis, the daily headlines and\n    social media all in one. Get ready to learn some Ruby, some human language insights and how they all intertwine!\n\n\n    #rubyconf2019 #confreaks\"\n  video_provider: \"youtube\"\n  video_id: \"VREjv9ZTxPg\"\n\n# Afternoon Break\n\n- id: \"colin-fulton-rubyconf-2019\"\n  title: \"Coding like it’s 1977: Ruby on the Apple ][\"\n  raw_title: \"RubyConf 2019 - Coding like it’s 1977: Ruby on the Apple ][ by Colin Fulton\"\n  speakers:\n    - Colin Fulton\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-03\"\n  description: |-\n    Coding like it’s 1977: Ruby on the Apple ][ by Colin Fulton\n\n    Many developers at some point in their programming career get curious about how HTTP servers work and how to build one from scratch without any external libraries.​Well, recently, I got curious about “How do HTTP servers work”? “How are HTTP servers built?” and “Can I build an HTTP server and client with Ruby without using any gems?“ And you know what, the answers are, yes, yes and yes!​We’ll explore how to build a simple http server using the Socket class available in the Ruby’s standard library. In the process, we will also get a crash course on how HTTP works.\n\n\n    #confreaks #rubyconf2019 #rubyconf\n  video_provider: \"youtube\"\n  video_id: \"M7LEf7-W12k\"\n\n- id: \"erica-sosa-rubyconf-2019\"\n  title: \"What happens when a linguist learns to code?\"\n  raw_title: \"RubyConf 2019 - What happens when a linguist learns to code?\\r by Erica Sosa\"\n  speakers:\n    - Erica Sosa\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-05\"\n  description: \"What happens when a linguist learns to code?\\r by Erica Sosa\n\n\n    When people find out about my former career as a linguist and language teacher, they often ask if my background helped me learn how to code. I started to wonder if there was\n    some overlap between learning a natural language and a programming language. What can we draw from the fields of first and second language acquisition that will help us become\n    better software engineers? How can we apply the principles of language learning and teaching when training new developers? Join me as I discuss my journey from Ruby as a first\n    language to JavaScript as a second, and stay for some code-learning tips from a former language acquisition professional.\n\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"98yjnksGB-0\"\n\n- id: \"daniel-ackerman-rubyconf-2019\"\n  title: \"Statistically Optimal API Timeouts\"\n  raw_title: \"RubyConf 2019 - Statistically Optimal API Timeouts by Daniel Ackerman\"\n  speakers:\n    - Daniel Ackerman\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-03\"\n  description:\n    \"RubyConf 2019 - Statistically Optimal API Timeouts by Daniel Ackerman\n\n\n    Have you ever written code that retries an API request? How did you pick the amount of time to wait before retrying? If you resorted to making an 'educated best guess' then\n    this talk is for you.\n\n\n    You will walk away from this talk with: 1. Knowledge of when a timeout is optimal & how important this optimality is! 2. An explanation of the algorithms necessary to calculate\n    optimal timeouts! 3. An overview of a new open source Ruby library to calculate optimal timeouts using an open source CAS!\\r\n\n\n    By the end: you will be equipped to optimize your timeouts, using your favorite language, Ruby.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"OxNL0vRsXi0\"\n\n- id: \"lori-olson-rubyconf-2019\"\n  title: \"Creating AR Apps with RubyMotion\"\n  raw_title: \"RubyConf 2019 - Creating AR Apps with RubyMotion by Lori Olson\"\n  speakers:\n    - Lori Olson\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-12-04\"\n  description: |-\n    RubyConf 2019 - Creating AR Apps with RubyMotion by Lori Olson\n\n    Augmented Reality (AR) is the new cool. But did you know you could write AR apps (and games!) using Ruby(Motion, that is)? Come and escape normal boring reality with us, as we create a native AR app using RubyMotion.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"9eqjppyV6iY\"\n\n- id: \"jessica-kerr-rubyconf-2019\"\n  title: \"Keynote: Collective Problem Solving in Music, Science, Art and Software\"\n  raw_title: \"RubyConf 2019 - Keynote - Collective Problem Solving in Music, Science, Art... by Jessica Kerr\"\n  speakers:\n    - Jessica Kerr\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-18\"\n  published_at: \"2019-11-27\"\n  description: |-\n    RubyConf 2019 - Keynote - Collective Problem Solving in Music, Science, Art and Software by Jessica Kerr\n\n    #confreaks #rubyconf2019 #rubyconf\n  video_provider: \"youtube\"\n  video_id: \"1oeigCANJVQ\"\n\n## Day 2\n\n- id: \"karen-g-lloyd-rubyconf-2019\"\n  title: \"Keynote: Slow, energy-efficient, and mysterious life deep within Earth's crust\"\n  raw_title: \"RubyConf 2019 - Keynote - Slow, energy-efficient, and mysterious life deep... by Karen G  Lloyd\"\n  speakers:\n    - Karen G Lloyd\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-11-28\"\n  description: |-\n    RubyConf 2019 - Keynote - Slow, energy-efficient, and mysterious life deep within Earth's crust by Karen G  Lloyd\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"6CfTrsz9148\"\n\n- id: \"brandon-weaver-rubyconf-2019\"\n  title: \"Tales of the Ruby Grimoire\"\n  raw_title: \"RubyConf 2019 - Tales of the Ruby Grimoire by Brandon Weaver\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-11-28\"\n  description: |-\n    RubyConf 2019 - Tales of the Ruby Grimoire by Brandon Weaver\n\n    There are arts best left unspoken, dark magics left forgotten and locked away in the deepest vaults of the Ruby language, lest they be seen by mortal eyes not ready for the horrors inside.\n\n    That is, until a particularly curious Lemur named Red happened to open it.\n\n    Journey with Red into the Tales of the Ruby Grimoire, through parts of the language not meant for the faint of heart. There is great power here, but that power comes at a cost. Are you willing to pay it?\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"TVwVLBor8WE\"\n\n- id: \"frederick-cheung-rubyconf-2019\"\n  title: \"Fixing Performance & Memory problems\"\n  raw_title: \"RubyConf 2019 - Fixing Performance & Memory problems by Frederick Cheung\"\n  speakers:\n    - Frederick Cheung\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  slides_url: \"https://speakerdeck.com/fcheung/fixing-performance-and-memory-problems\"\n  description:\n    \"RubyConf 2019 - Fixing Performance & Memory problems by Frederick Cheung\n\n\n    Performance problems got you down? Do memory leaks strike fear in your heart?\n\n    \\r\n\n\n    In this session I'll share two real world stories of how you can solve performance problems and plug memory leaks. You'll learn how to use tools such as ruby-prof and\n    stackprof, interpret their output and gain extra insight into how your code is performing.\\r\n\n\n    \\r\n\n\n    When dealing with memory leaks, the biggest challenge can be finding them. You'll learn how to use rbtrace and ObjectSpace to identify what objects are being leaked and by\n    which code, so that you can approach leaks with confidence.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"UCJsjr8ksDc\"\n\n- id: \"chris-hoffman-rubyconf-2019\"\n  title: \"Injecting Dependencies for Fun and Profit\"\n  raw_title: \"RubyConf 2019 - Injecting Dependencies for Fun and Profit by Chris Hoffman\"\n  speakers:\n    - Chris Hoffman\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description: |-\n    RubyConf 2019 - Injecting Dependencies for Fun and Profit by Chris Hoffman\n\n    Does your codebase not seem as flexible as it used to? Are you missing that bounce in its step? Is your test suite no longer full of vigor? Get Dependency Injection! Dependency Injection soothes testing pains, improves your domain model, and makes your code more maintainable. Pay no mind to the naysayers; Dependency Injection isn’t just for architecture astronauts--it’s truly a technique for the common developer. So step right up! Discover the potential dangers of Globals, learn how to use Dependency Injection to avoid them, and see if it could be a boon to your project!\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"b5vfNcjJsLU\"\n\n- id: \"udit-gulati-rubyconf-2019\"\n  title: \"Speeding up NMatrix by 100x\"\n  raw_title: \"RubyConf 2019 -  Speeding up NMatrix by 100x by Udit Gulati 1\"\n  speakers:\n    - Udit Gulati\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-04\"\n  description: \"RubyConf 2019 -  Speeding up NMatrix by 100x by Udit Gulati 1\n\n\n    With the growing need for fast numerical computing tools, there is a need for a library in Ruby which can perform at the level of NumPy in Python and can provide as much rich\n    API. In this talk, we'll explore how NMatrix is being re-implemented to match this need and how it ended up getting renamed as NumRuby. We'll further explore the progress so\n    far on NumRuby and potential future work.\n\n    \\r\n\n\n    We'll further explore how one can make the best use of Ruby C extensions for fast number crunching and not end up messing things up.\n\n\n    #rubyconf2019 #confreaks\"\n  video_provider: \"youtube\"\n  video_id: \"ogB_J3mgSa8\"\n\n- id: \"alberto-coln-viera-rubyconf-2019\"\n  title: \"How to use Your Superpowers to Transform People's Lives\"\n  raw_title: \"RubyConf 2019 - How to use Your Superpowers to Transform People's Lives by Alberto Colon Viera\"\n  speakers:\n    - Alberto Colón Viera\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-11-28\"\n  description: |-\n    RubyConf 2019 - How to use Your Superpowers to Transform People's Lives by Alberto Colon Viera\n\n    Have you ever thought about how government services should actually meet people's expectations? Have you ever considered using your skill sets to transform the way government operates?\n\n    Even if you haven't, you have to interact with government in your everyday life. Imagine being able to use your programming and technical superpowers to design a new government. You'll hear about how the U.S. Digital Service (USDS) team at the Small Business Administration redesigned the experience for small business owners. And we used ruby! You'll also learn about the civic tech ecosystem and other organizations from where you can contribute, as well as how USDS keeps transforming people's lives at other agencies.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"4U1Gt-eHEWg\"\n\n- id: \"david-copeland-rubyconf-2019\"\n  title: \"The Fewer the Concepts, the Better the Code\"\n  raw_title: \"RubyConf 2019 - The Fewer the Concepts, the Better the Code by David Copeland\"\n  speakers:\n    - David Copeland\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description: |-\n    RubyConf 2019 - The Fewer the Concepts, the Better the Code by David Copeland\n\n    How many people could change the code you wrote yesterday if they had to? I hope to convince you that the larger that number, the better your code, and the key is to manage conceptual overhead. The fewer things someone has to know to read and modify your code, the better for you, your team, your company, your app. We'll see real examples of code that we'll put on a conceptual diet. We'll then talk about what that reduction actually does to code quality.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"unpJ9qRjdMw\"\n  slides_url: \"https://speakerdeck.com/davetron5000/the-fewer-the-concepts-the-better-the-code\"\n\n- id: \"mercedes-bernard-rubyconf-2019\"\n  title: \"Fun, Friendly Computer Science\"\n  raw_title: \"RubyConf 2019 - Fun, Friendly Computer Science by Mercedes Bernard\"\n  speakers:\n    - Mercedes Bernard\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description:\n    \"RubyConf 2019 - Fun, Friendly Computer Science by Mercedes Bernard\n\n\n    Computer science concepts like Big O Notation, set theory, data structures, and principles of object-oriented programming sound intimidating, but they don’t have to be! This\n    talk will dive into some fundamental computer science topics and debunk the myth that only ‘real’ programmers know CS.\n\n    \\r\n\n\n    Whether you are a code school grad, self-taught career switcher, or someone who, like me, didn't pay attention in night class, join me as we explore some computer science\n    theory behind the code we write every day through fun illustrations and real-world examples.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"IhD-9Xvbnt0\"\n\n- id: \"mike-calhoun-rubyconf-2019\"\n  title: \"The Singleton Module and Its Pattern In Ruby\"\n  raw_title: \"RubyConf 2019 - The Singleton Module and Its Pattern In Ruby by Mike Calhoun\"\n  speakers:\n    - Mike Calhoun\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-04\"\n  description: |-\n    RubyConf 2019 - The Singleton Module and Its Pattern In Ruby by Mike Calhoun\n\n    The singleton design pattern allows for the creation of an object that is restricted to one single instance. No matter how big or complex your application is, there will only ever be one. This has caused some controversy about the quality and maintainability of code that leverages it. Yet, Ruby’s standard library contains a module that implements this pattern. Let’s take a closer look at this module and the “controversy” around its implemented pattern. Let’s also consider singletons in Ruby and the purpose they serve for the language in general.\n\n    #rubyconf2019 #confreaks\n  video_provider: \"youtube\"\n  video_id: \"r8LwiJVVtzo\"\n\n# Lunch\n\n- id: \"third-coast-comedy-club-rubyconf-2019\"\n  title: \"Improv\"\n  raw_title: \"RubyConf 2019 - Improv by the\\r Third Coast Comedy Club\"\n  speakers:\n    - Third Coast Comedy Club\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description: \"RubyConf 2019 - Improv by the\\r Third Coast Comedy Club\n\n\n    #confreaks #rubyconf2019 #rubyconf\"\n  video_provider: \"youtube\"\n  video_id: \"hhJ_UuN3Jas\"\n\n- id: \"jake-zimmerman-rubyconf-2019\"\n  title: \"Sorbet: A type checker for Ruby 3 you can use today!\"\n  raw_title: \"RubyConf 2019 - Sorbet: A type checker for Ruby 3...  by Jake Zimmerman & Dmitry Petrashko\"\n  speakers:\n    - Jake Zimmerman\n    - Dmitry Petrashko\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-11-28\"\n  description: |-\n    RubyConf 2019 - Sorbet: A type checker for Ruby 3 you can use today! by Jake Zimmerman & Dmitry Petrashko\n\n    In June we open-sourced Sorbet, a fast, powerful type checker designed for Ruby. In the 6 months since, tons of things have improved! We’ve built quality editor tools like jump-to-def and seen many contributions from a growing community. Within Stripe, we've used Sorbet to drive code quality via measurable, concrete indicators.\n\n    We’ll share these improvements and give an update on our collaboration with Matz and the Ruby 3 Types working group. Suitable for anyone using Ruby—no familiarity with Sorbet needed! Come follow in the footsteps of the many companies already using Sorbet.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"jielBIZ40mw\"\n\n- id: \"daniel-magliola-rubyconf-2019\"\n  title: \"Disk is fast, memory is slow. Forget all you think you know\"\n  raw_title: \"RubyConf 2019 - Disk is fast, memory is slow. Forget all you think you know by Daniel Magliola\"\n  speakers:\n    - Daniel Magliola\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description:\n    \"RubyConf 2019 - Disk is fast, memory is slow. Forget all you think you know by Daniel Magliola\n\n\n    Adding metrics to your code should effectively have no impact on performance.\n\n    \\r\n\n\n    When we were recently tasked with doing that in multi-process Ruby servers, we ran into an interesting challenge: could we aggregate our numbers across processes without\n    blowing our target of just one microsecond of overhead?\\r\n\n\n    \\r\n\n\n    The months of work that followed had us looking into C extensions, segfault dumps, memory maps, syscall timings, and pretty much everything we could think of to try and achieve\n    our objective.\\r\n\n\n    \\r\n\n\n    In the process, we found some very counter-intuitive performance results that I'd like to share with you.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"crbyeyPS7HE\"\n\n- id: \"colleen-schnettler-rubyconf-2019\"\n  title: \"Rekindling a love of creation with Ruby and Raspberry Pi\"\n  raw_title: \"RubyConf 2019 - Rekindling a love of creation with Ruby and Raspberry Pi by Colleen Schnettler\"\n  speakers:\n    - Colleen Schnettler\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description: |-\n    RubyConf 2019 - Rekindling a love of creation with Ruby and Raspberry Pi by Colleen Schnettler\n\n    Does your life and work as a software developer ever leave you feeling depleted? Have you lost your inspiration to create? Do you want to share your love of software and design with your children but don't know how? Well, fortunately if you already know Ruby it is a short leap to building physical devices with the Raspberry pi! This talk will give a detailed explanation on how to get started on the Pi with Ruby, and outline a few fun projects you can build with your children (or just yourself) to explore your love of software and hardware. This talk will also cover basic electronics (don't be scared of the breadboard), and show you how to build a whoopie cushion prank with some paper plates and your Pi. Leave feeling inspired to create something fun!\n\n    #rubyconf2019 #confreaks\n  video_provider: \"youtube\"\n  video_id: \"IH4r_mvVyhs\"\n\n- id: \"dave-aronson-rubyconf-2019\"\n  title: \"Kill All Mutants! (Intro to Mutation Testing)\"\n  raw_title: \"RubyConf2019 - Kill All Mutants! (Intro to Mutation Testing) by Dave Aronson\"\n  speakers:\n    - Dave Aronson\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-04\"\n  description:\n    \"RubyConf2019 - Kill All Mutants! (Intro to Mutation Testing) by Dave Aronson\n\n\n    How good are your tests? Would they still pass if the tested code was changed much? If so, you may have a problem!\n\n\n    Mutation testing helps reveal these cases. It runs your unit tests, using many slightly altered versions of each method, called \\\"mutants\\\". If a mutant passes (or\n    \\\"survives\\\") all of the method's tests, that implies certain flaws in your code, your tests, or both!\\r\n\n\n    Come find out how to use this advanced technique to discover problems lurking in your code and/or tests.\n\n\n    #rubyconf2019 #confreaks\"\n  video_provider: \"youtube\"\n  video_id: \"9GId6mFL0_c\"\n\n- id: \"ufuk-kayserilioglu-rubyconf-2019\"\n  title: \"Adopting Sorbet at Scale\"\n  raw_title: \"RubyConf 2019 - Adopting Sorbet at Scale by Ufuk Kayserilioglu\"\n  speakers:\n    - Ufuk Kayserilioglu\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-11-28\"\n  slides_url: \"https://speakerdeck.com/ufuk/adopting-sorbet-at-scale\"\n  description: |-\n    RubyConf 2019 - Adopting Sorbet at Scale by Ufuk Kayserilioglu\n\n    Shopify is a platform used by 800K merchants generating 12B$ revenue per year, serving 80K requests per second. Our core monolith is a 21K file Ruby on Rails application modified by 800 PRs per day. At this scale, we’re always looking out for tools that improve our confidence in the code that we write and maintain.\n\n    In this talk, we’ll explain how we adopted Sorbet to leverage static typing in our Ruby codebase. We’ll talk about our journey, the challenges we faced and how we overcame them. Based on this experience, you’ll get a better understanding of how you can benefit from Sorbet, too.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"v9oYeSZGkUw\"\n\n- id: \"ernesto-tagwerker-rubyconf-2019\"\n  title: \"Escaping The Tar Pit\"\n  raw_title: \"RubyConf 2019 - Escaping The Tar Pit by Ernesto Tagwerker\"\n  speakers:\n    - Ernesto Tagwerker\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description: \"RubyConf 2019 - Escaping The Tar Pit by Ernesto Tagwerker\n\n\n    Nobody wants to inherit a project that reeks but here we are: Stuck in the tar pit. How can we get out? Could we have avoided it in the first place?\n\n    \\r\n\n\n    In this talk you will learn how to use a few, great Ruby gems that will guide you out of that sticky tar you are in. On top of that, you will learn a repeatable way to\n    gradually pay off technical debt.\n\n\n    #rubyconf2019 #confreaks\"\n  video_provider: \"youtube\"\n  video_id: \"ZyU6K6eR-_A\"\n\n- id: \"julian-cheal-rubyconf-2019\"\n  title: \"Cocktail Masterclass with Ruby and Friends\"\n  raw_title: \"RubyConf 2019 - Cocktail Masterclass with Ruby and Friends by Julian Cheal\"\n  speakers:\n    - Julian Cheal\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description: \"Cocktail Masterclass with Ruby and Friends by Julian Cheal\n\n\n    Welcome to Nashville, Tennessee! Have you ever wanted to try making aTennessee Two Step Cocktail, an Old Fashioned, or a Citrus peach cooler for the non-drinkers? Well now you\n    can!\n\n    \\r\n\n\n    Introducing Ruby Mixologist the world's first (probably) Ruby cocktail maker. Ruby Mixologist is a cocktail robot tending to all your drink needs.\\r\n\n\n    \\r\n\n\n    In this talk we will discover how you too can build your very own Ruby powered drinks robot.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"YM-HoJ23wqQ\"\n\n- id: \"noah-matisoff-rubyconf-2019\"\n  title: \"Digging Up Code Graves in Ruby\"\n  raw_title: \"RubyConf2019 - Digging Up Code Graves in Ruby by Noah Matisoff\"\n  speakers:\n    - Noah Matisoff\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-04\"\n  description: \"RubyConf2019 - Digging Up Code Graves in Ruby by Noah Matisoff\n\n\n    As codebases grow, having dead code is a common issue that teams need to tackle. Especially for consumer-facing products that frequently run A/B tests using feature flags, dead\n    code paths can be a significant source of technical debt sneakily piling up. Luckily, the Ruby standard library exposes Coverage -- which is a simple, experimental code\n    coverage measurement tool.\n\n    \\r\n\n\n    Let's dive into how Coverage and other tools can be used and expanded to track down dead code paths in Ruby.\n\n\n    #rubyconf2019 #confreaks\"\n  video_provider: \"youtube\"\n  video_id: \"ffrv-JppavY\"\n\n# Afternoon Break\n\n- id: \"yusuke-endoh-rubyconf-2019\"\n  title: \"A Static Type Analyzer of Untyped Ruby Code for Ruby 3\"\n  raw_title: \"RubyConf 2019 - A Static Type Analyzer of Untyped Ruby Code for Ruby 3 by Yusuke Endoh\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-11-29\"\n  slides_url: \"https://speakerdeck.com/mame/a-static-type-analyzer-of-untyped-ruby-code-for-ruby-3\"\n  description: |-\n    RubyConf 2019 - A Static Type Analyzer of Untyped Ruby Code for Ruby 3 by Yusuke Endoh\n\n    Ruby 3 is planned to provide a toolchain for static analysis: (1) the standard type signature format for Ruby code, (2) a type analyzer to guess a signature of a non-signatured Ruby code, and (3) a type checker (such as Sorbet) to verify a code with its signature. In the talk, we present a candidate of (2), called Type Profiler, which aims to allow you not to write a signature manually. It abstractly runs a non-annotated Ruby code in \"type\" level, tries to find possible errors, and generates a type signature prototype for the code. We show some demos and development progress.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"l1B3NJc2eU8\"\n\n- id: \"penelope-phippen-rubyconf-2019\"\n  title: \"Introducing Rubyfmt\"\n  raw_title: \"RubyConf 2019 - Introducing Rubyfmt by Penelope Phippen\"\n  speakers:\n    - Penelope Phippen\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description: \"RubyConf 2019 - Introducing Rubyfmt by Penelope Phippen\n\n\n    Go has gofmt, Rust: rustfmt, elixir: mix format, so what about Ruby? One response is Rubocop! A sometimes beloved, sometimes maligned formatting and linting tool. A design\n    principle of Rubocop is configurability. So, what if we had a code formatter without configuration options?\n\n    \\r\n\n\n    In this talk, you’ll learn about my goals for Rubyfmt, my upcoming Ruby formatter. You’ll also get a guided tour through Ruby’s parser, and learn about why I’m rewriting the\n    parser in Rust! This talk will get technical, and you should come if you want to learn more about Ruby’s parser and internals.\n\n\n    #rubyconf2019 #confreaks\"\n  video_provider: \"youtube\"\n  video_id: \"ifUbj1xErlg\"\n\n- id: \"zachary-schroeder-rubyconf-2019\"\n  title: \"lo-fi hip hop ruby - beats to relax/study to\"\n  raw_title: \"RubyConf 2019 - lo-fi hip hop ruby - beats to relax/study to by Zachary Schroeder\"\n  speakers:\n    - Zachary Schroeder\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description: |-\n    RubyConf 2019 - lo-fi hip hop ruby - beats to relax/study to by Zachary Schroeder\n\n    Lo-fi hip hop, or chillhop, is both a successful meme (thanks to some very specifically worded youtube playlists) and a relaxing music genre. It is characterized by loops of quiet, calm music (often jazz), a hip-hop inspired beat, some airy effects, and perhaps some vocal samples. Now, would it amaze you to learn that our best friend Ruby can help us make our own tracks like these? In fact, by using a few gems for audio manipulation, beat making, and UI construction, we’ll construct our own chillhop studio! Thanks Ruby!\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"taYx6Dy6dwI\"\n\n- id: \"kevin-miller-rubyconf-2019\"\n  title: \"Parallel Ruby: Managing the Memory Monster\"\n  raw_title: \"RubyConf 2019 - Parallel Ruby: Managing the Memory Monster by Kevin Miller\"\n  speakers:\n    - Kevin Miller\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-04\"\n  description: |-\n    Parallel Ruby: Managing the Memory Monster by Kevin Miller\n\n    At Flexport, we process a lot of data. One sunny day, we decided to switch from a swarm of single-threaded Ruby processes to a wonderful new threadpool. Threads have way less overhead than processes, after all, so we could run far more. Fast forward a couple of hours and everything is on fire. Let’s talk about what went wrong, why it was the Ruby garbage collector's fault, and we did about it.\n\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"4_yxbh9Enoc\"\n\n- id: \"brittany-martin-rubyconf-2019\"\n  title: \"Hire Me: I'm Excellent at Quitting\"\n  raw_title: \"RubyConf 2019 - Hire Me: I'm Excellent at Quitting by Brittany Martin\"\n  speakers:\n    - Brittany Martin\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-11-29\"\n  description: |-\n    RubyConf 2019 - Hire Me: I'm Excellent at Quitting by Brittany Martin\n\n    You have the right to be happy at work — why would we want it to be any other way? As our careers as Ruby developers flourish, amazing new opportunities will require you to quit a job that you may love or loathe. It's OK to quit. If you want to learn how to gracefully leave your job with a solid game plan, an educated successor, and without burning bridges, this talk is for you.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"Jr0yGI7sKgI\"\n\n- id: \"roman-kofman-rubyconf-2019\"\n  title: \"How to write pleasant code\"\n  raw_title: \"RubyConf 2019 - How to write pleasant code by Roman Kofman\"\n  speakers:\n    - Roman Kofman\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description: \"RubyConf 2019 - How to write pleasant code by Roman Kofman\n\n\n    As we grow from beginner to intermediate developers, we tend to learn tools and Best Practices for writing good code. But. The more we learn, the more contradictions show up --\n    and the murkier it gets to find the right answers. Senior developers sometimes chime in with \\\"it depends!\\\". Which -- while being technically accurate, is also completely\n    unhelpful. What does it depend on? How do we reconcile Best Practices when they conflict with each other? Who is \\\"good\\\" code actually good for? Is perfectly clean code even\n    possible?\n\n    \\r\n\n\n    We'll learn to find the answers to all of these questions by exploring the discipline of Design (think fancy chairs in museum); and stealing from it shamelessly.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"S2s9FldrKug\"\n\n- id: \"elle-meredith-rubyconf-2019\"\n  title: \"Story Telling with Git rebase\"\n  raw_title: \"RubyConf 2019 - Story telling with Git rebase by Elle Meredith\"\n  speakers:\n    - Elle Meredith\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-03\"\n  description: \"RubyConf 2019 - Story telling with Git rebase by Elle Meredith\n\n\n    In a successful software development project, a key challenge is to manage complexity because projects get very complex very quickly even within small teams. Version control is\n    the tool for communicating intent in our codebase over the life time of the project. Rebasing allows us to revise our development history before sharing it with the team.\n\n    \\r\n\n\n    Learn to use Git commit messages to keep track of the intent of your code changes to make it easier to make future changes. Learn how to make using feature branches less\n    painful and more effective. Learn the mechanics of interactive rebasing, how to merge conflicts without losing precious code and how to auto-squash commits. Basically, stop\n    fearing interactive rebasing.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"-WsjKCledP4\"\n\n- id: \"brad-grzesiak-rubyconf-2019\"\n  title: \"Algorithms: CLRS in Ruby\"\n  raw_title: \"RubyConf 2019 - Algorithms: CLRS in Ruby\\r by Brad Grzesiak\"\n  speakers:\n    - Brad Grzesiak\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-12-04\"\n  description: \"Algorithms: CLRS in Ruby\\r by Brad Grzesiak\n\n\n    One of the most celebrated books in Computer Science academia is \\\"Introduction to Algorithms,\\\" also known as \\\"CLRS\\\" after its 4 authors. It's the go-to (pun!) textbook for\n    many intermediate college courses, and this talk will introduce some of its many wonderful algorithms in Ruby form, including: various sorting techniques, dynamic programming,\n    and some fun graph techniques. If you want a theory-heavy lecture, this talk is NOT for you!\n\n\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"eJL0M7H-p-I\"\n\n- id: \"lightning-talks-rubyconf-2019\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf 2019 - Lightning Talks\"\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-19\"\n  published_at: \"2019-11-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"7TrKS8ZiTyI\"\n  talks:\n    - title: \"Lightning Talk: Sean Marcia\" # TODO: missing talk title\n      start_cue: \"00:00:12\"\n      end_cue: \"00:00:59\"\n      id: \"sean-marcia-lighting-talk-rubyconf-2019\"\n      video_id: \"sean-marcia-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Sean Marcia\n\n    - title: \"Lightning Talk: Ivan Nemytchenko\" # TODO: missing talk title\n      start_cue: \"00:00:59\"\n      end_cue: \"00:02:20\"\n      id: \"ivan-nerytchenko-lighting-talk-rubyconf-2019\"\n      video_id: \"ivan-nerytchenko-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Ivan Nemytchenko\n\n    - title: \"Lightning Talk: Daniel Colson\" # TODO: missing talk title\n      start_cue: \"00:02:20\"\n      end_cue: \"00:02:55\"\n      id: \"daniel-colson-lighting-talk-rubyconf-2019\"\n      video_id: \"daniel-colson-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Daniel Colson\n\n    - title: \"Lightning Talk: Wendy Calderón\" # TODO: missing talk title\n      start_cue: \"00:02:55\"\n      end_cue: \"00:06:22\"\n      id: \"wendy-calderon-lighting-talk-rubyconf-2019\"\n      video_id: \"wendy-calderon-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Wendy Calderón\n\n    - title: \"Lightning Talk: Chyrelle Lewis\" # TODO: missing talk title\n      start_cue: \"00:06:22\"\n      end_cue: \"00:11:26\"\n      id: \"chyrelle-lewis-lighting-talk-rubyconf-2019\"\n      video_id: \"chyrelle-lewis-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Chyrelle Lewis\n\n    - title: \"Lightning Talk: LaNice Powell\" # TODO: missing talk title\n      start_cue: \"00:11:26\"\n      end_cue: \"00:12:59\"\n      id: \"lanice-powell-lighting-talk-rubyconf-2019\"\n      video_id: \"lanice-powell-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - LaNice Powell\n\n    - title: \"Lightning Talk: Jonan Scheffler\" # TODO: missing talk title\n      start_cue: \"00:12:59\"\n      end_cue: \"00:17:56\"\n      id: \"jonan-scheffler-lighting-talk-rubyconf-2019\"\n      video_id: \"jonan-scheffler-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Jonan Scheffler\n\n    - title: \"Lightning Talk: Rob Faldo\" # TODO: missing talk title\n      start_cue: \"00:17:56\"\n      end_cue: \"00:22:41\"\n      id: \"rob-faldo-lighting-talk-rubyconf-2019\"\n      video_id: \"rob-faldo-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Rob Faldo\n\n    - title: \"Lightning Talk: Carolyn Cole\" # TODO: missing talk title\n      start_cue: \"00:22:41\"\n      end_cue: \"00:26:39\"\n      id: \"carolyn-cole-lighting-talk-rubyconf-2019\"\n      video_id: \"carolyn-cole-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Carolyn Cole\n\n    - title: \"Lightning Talk: Daniel Azuma\" # TODO: missing talk title\n      start_cue: \"00:26:39\"\n      end_cue: \"00:31:34\"\n      id: \"daniel-azuma-lighting-talk-rubyconf-2019\"\n      video_id: \"daniel-azuma-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Daniel Azuma\n\n    - title: \"Lightning Talk: Justin Jones\" # TODO: missing talk title\n      start_cue: \"00:31:34\"\n      end_cue: \"00:35:55\"\n      id: \"justin-jones-lighting-talk-rubyconf-2019\"\n      video_id: \"justin-jones-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Justin Jones\n\n    - title: \"Lightning Talk: Braulio Martinez\" # TODO: missing talk title\n      start_cue: \"00:35:55\"\n      end_cue: \"00:41:00\"\n      id: \"braulio-martinez-lighting-talk-rubyconf-2019\"\n      video_id: \"braulio-martinez-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Braulio Martinez\n\n    - title: \"Lightning Talk: Bonzalo Rodriguez\" # TODO: missing talk title\n      start_cue: \"00:41:00\"\n      end_cue: \"00:45:56\"\n      id: \"bonzalo-rodriguez-lighting-talk-rubyconf-2019\"\n      video_id: \"bonzalo-rodriguez-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Bonzalo Rodriguez\n\n    - title: \"Lightning Talk: Rohaa Mendon\" # TODO: missing talk title\n      start_cue: \"00:45:56\"\n      end_cue: \"00:50:41\"\n      id: \"rohaa-mendon-lighting-talk-rubyconf-2019\"\n      video_id: \"rohaa-mendon-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Rohaa Mendon\n\n    - title: \"Lightning Talk: Emily Giurleo\" # TODO: missing talk title\n      start_cue: \"00:50:41\"\n      end_cue: \"00:56:10\"\n      id: \"emily-giurleo-lighting-talk-rubyconf-2019\"\n      video_id: \"emily-giurleo-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Emily Giurleo\n\n    - title: \"Lightning Talk: Chris O'Sullivan\" # TODO: missing talk title\n      start_cue: \"00:56:10\"\n      end_cue: \"01:00:38\"\n      id: \"chris-osullivan-lighting-talk-rubyconf-2019\"\n      video_id: \"chris-osullivan-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris O'Sullivan\n\n    - title: \"Lightning Talk: Ian Norris\" # TODO: missing talk title\n      start_cue: \"01:00:38\"\n      end_cue: \"01:04:20\"\n      id: \"ian-norris-lighting-talk-rubyconf-2019\"\n      video_id: \"ian-norris-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Ian Norris\n\n    - title: \"Lightning Talk: Noah Gibbs\" # TODO: missing talk title\n      start_cue: \"01:04:20\"\n      end_cue: \"01:10:04\"\n      id: \"noah-gibbs-lighting-talk-rubyconf-2019\"\n      video_id: \"noah-gibbs-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Noah Gibbs\n\n    - title: \"Lightning Talk: Dave Aronson\" # TODO: missing talk title\n      start_cue: \"01:10:04\"\n      end_cue: \"01:14:50\"\n      id: \"dave-aronson-lighting-talk-rubyconf-2019\"\n      video_id: \"dave-aronson-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Dave Aronson\n\n    - title: \"Lightning Talk: DeeDee Lavinder\" # TODO: missing talk title\n      start_cue: \"01:14:50\"\n      end_cue: \"TODO\"\n      id: \"deedee-lavinder-lighting-talk-rubyconf-2019\"\n      video_id: \"deedee-lavinder-lighting-talk-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - DeeDee Lavinder\n\n## Day 3\n\n- id: \"sandi-metz-rubyconf-2019\"\n  title: \"Keynote: Lucky You\"\n  raw_title: \"RubyConf 2019 - Keynote: Lucky You by Sandi Metz\"\n  speakers:\n    - Sandi Metz\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-11-30\"\n  slides_url: \"https://speakerdeck.com/skmetz/lucky-you\"\n  description: |-\n    Keynote: Lucky You by Sandi Metz\n\n\n    #confreaks #rubyconf2019 #rubyconf\n  video_provider: \"youtube\"\n  video_id: \"c5WWTvHB_sA\"\n\n- id: \"victor-shepelev-rubyconf-2019\"\n  title: \"Language as a Tool of Thought: Consistency versus Progress\"\n  raw_title: \"RubyConf 2019 - Language as a Tool of Thought: Consistency versus Progress by Victor Shepelev\"\n  speakers:\n    - Victor Shepelev\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-11-30\"\n  description: |-\n    Language as a Tool of Thought: Consistency versus Progress by Victor Shepelev\n\n    Our programming language is not a mere instrument: it shapes how we think about problems, what we feel right and wrong. But as the Ruby itself changes (and rather quickly, lately), what happens with our understanding and feeling of it? More powerful language is probably good, but how should it stay consistent and true to its spirit without losing the pace of the progress? Let's look closely at some new and upcoming Ruby features, and some missing and rejected ones, and discuss where are we standing currently in regards to consistency and \"developer's happiness\".\n\n\n    #confreaks #rubyconf2019 #rubyconf\n  video_provider: \"youtube\"\n  video_id: \"iMBqqjkbvl4\"\n\n- id: \"ryan-lopopolo-rubyconf-2019\"\n  title: \"Building a Ruby: Artichoke is a Ruby Made with Rust\"\n  raw_title: \"RubyConf 2019 - Building a Ruby: Artichoke is a Ruby Made with Rust by Ryan Lopopolo\"\n  speakers:\n    - Ryan Lopopolo\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-03\"\n  description: |-\n    RubyConf 2019 - Building a Ruby: Artichoke is a Ruby Made with Rust by Ryan Lopopolo\n\n    Artichoke is a new Ruby implementation. Artichoke is written in Rust and aspires to be compatible with MRI Ruby 2.6.3. Artichoke is a platform that allows experimenting with VM implementations while providing a VM-agnostic implementation of Ruby Core and Standard Library. This talk will discuss Artichoke’s history, architecture, goals, and implementation.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"QMni48MBqFw\"\n\n- id: \"jon-druse-rubyconf-2019\"\n  title: \"How to lose 50 Million Records in 5 minutes\"\n  raw_title: \"RubyConf 2019 - How to lose 50 Million Records in 5 minutes by Jon Druse\"\n  speakers:\n    - Jon Druse\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-04\"\n  description:\n    \"RubyConf 2019 - How to lose 50 Million Records in 5 minutes by Jon Druse\n\n\n    Join me in re-living the worst catastrophe of my more than a decade long career as a developer. Enough time has passed that I can laugh about it now and hopefully you will too\n    while being inspired to stop cutting corners.\n\n    \\r\n\n\n    It’s like a game of Clue and all the different parts of the system are characters. Which one was the killer? Spoiler alert, it was me, in the office with the keyboard.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"Qbxmf_TxA-s\"\n\n- id: \"david-mcdonald-rubyconf-2019\"\n  title: \"Bursting at the Seams\"\n  raw_title: \"RubyConf 2019 - Bursting at the Seams\\r by David McDonald\"\n  speakers:\n    - David McDonald\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-04\"\n  description: \"Bursting at the Seams\\r by David McDonald\n\n\n    Our industry remains in its infancy but we've had many important contributions to how we all think and talk about design. In order to tighten the existing gap between where\n    theory and practice meet, we need to continue to add to our shared vocabulary. With this aim, I want to underline one of the more accessible and oft-overlooked concepts from\n    software's past: seams. Seams are easy to identify, and point to crucial incisions in our code. Learning to see code in terms of seams will improve your existing codebases,\n    help you write better tests, and aid as you develop greenfield projects.\n\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"N6I34YEqZPc\"\n\n- id: \"esther-olatunde-rubyconf-2019\"\n  title: \"Let's build a simple HTTP server with Ruby\"\n  raw_title: \"RubyConf 2019 - Let's build a simple HTTP server with Ruby by Esther Olatunde\"\n  speakers:\n    - Esther Olatunde\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-11-30\"\n  description: |-\n    Let's build a simple HTTP server with Ruby by Esther Olatunde\n\n    Many developers at some point in their programming career get curious about how HTTP servers work and how to build one from scratch without any external libraries.​Well, recently, I got curious about “How do HTTP servers work”? “How are HTTP servers built?” and “Can I build an HTTP server and client with Ruby without using any gems?“ And you know what, the answers are, yes, yes and yes!​We’ll explore how to build a simple http server using the Socket class available in the Ruby’s standard library. In the process, we will also get a crash course on how HTTP works.\n\n\n    #confreaks #rubyconf2019 #rubyconf\n  video_provider: \"youtube\"\n  video_id: \"JFbBj2CN5Mo\"\n\n- id: \"yurie-yamane-rubyconf-2019\"\n  title: \"What's happening when initializing mruby?\"\n  raw_title: \"RubyConf 2019 - What's happening when initializing mruby? by Yurie Yamane and Masayoshi Takahashi\"\n  speakers:\n    - Yurie Yamane\n    - Masayoshi Takahashi\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-03\"\n  description: |-\n    RubyConf 2019 - What's happening when initializing mruby? by Yurie Yamane and Masayoshi Takahashi\n\n    Like MRI, mruby initializes all classes before execution. This has a negative impact on Ruby's initialization speed and memory. This increase in memory usage is particularly fatal for mruby. We have created a new mrbgem to solve this issue. The key idea is pre-execution; we actually run mruby and do initialization, generate the structures in the form of C source code, and recompile it. In this session, we will look at the initial behavior of the mruby through an introduction to our tools.\n\n    #rubyconf2019 #confreaks\n  video_provider: \"youtube\"\n  video_id: \"E05ACAZSXDI\"\n\n- id: \"amy-newell-rubyconf-2019\"\n  title: \"Late, Over Budget, & Happy: Our Service Extraction Story\"\n  raw_title: \"RubyConf 2019 - Late, Over Budget, & Happy: Our Service Extraction Story by Amy Newell & Nat Budin\"\n  speakers:\n    - Amy Newell\n    - Nat Budin\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-04\"\n  description:\n    \"RubyConf 2019 - Late, Over Budget, & Happy: Our Service Extraction Story by Amy Newell & Nat Budin\n\n\n    A 3-month project stretches out to 9 months. It's widely viewed as over-engineered and difficult to work with. But months after deployment, it's considered successful. What\n    happened?\n\n    \\r\n\n\n    In this talk, a principal engineer and a director of engineering recount the extraction of a social feeds GraphQL service from a decade-old Rails monolith. Along the way, we'll\n    cover topics including selling a big project, complexity in remote work, complexity in deployments, and complexity in emotions. We'll tell you about the scars we acquired and\n    the lessons we learned.\n\n\n    #rubyconf2019 #confreaks\"\n  video_provider: \"youtube\"\n  video_id: \"5qdWvw_oqPM\"\n\n- id: \"kevin-murphy-rubyconf-2019\"\n  title: \"Don't Hang Me Out To DRY\"\n  raw_title: \"RubyConf 2019 - Don’t Hang Me Out To DRY\\r by Kevin Murphy\"\n  speakers:\n    - Kevin Murphy\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-04\"\n  slides_url: \"https://speakerdeck.com/kevinmurphy/dont-hang-me-out-to-dry\"\n  description: \"Don’t Hang Me Out To DRY\\r by Kevin Murphy\n\n\n    Close your eyes and imagine the perfect codebase to work on. I bet you’ll say it has complete test coverage. It’s fully-optimized, both in terms of performance and\n    architectural design. And, of course, it contains only DRY code. Surely we can all agree that this is an aspirational situation. But...do we really want that?\\r\n\n\n    Don’t get me wrong; these qualities are all beneficial. However, if we also think we should value everything in moderation, when should we push back on these ideals? What\n    problems can they introduce? Let’s talk about the exceptions to some of the “rules” we all hold dear.\n\n\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"b960MApGA7A\"\n\n# Lunch\n\n- id: \"ignite-roulette-rubyconf-2019\"\n  title: \"Ignite Roulette\"\n  raw_title: \"RubyConf 2019 - Ignite Roulette\"\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-11-30\"\n  description: |-\n    Ignite Roulette\n\n    #confreaks #rubyconf2019 #rubyconf\n  video_provider: \"youtube\"\n  video_id: \"b5zH82inF_c\"\n  talks:\n    - title: \"Intro & Ignite Roulette Rules\"\n      start_cue: \"00:00\"\n      end_cue: \"02:37\"\n      id: \"adam-cuppy-ignite-roulette-intro-rubyconf-2019\"\n      video_id: \"adam-cuppy-ignite-roulette-intro-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Cuppy\n\n    - title: \"Ignite Roulette: Evan Phoenix\"\n      start_cue: \"02:37\"\n      end_cue: \"08:54\"\n      id: \"evan-phoenix-ignite-roulette-rubyconf-2019\"\n      video_id: \"evan-phoenix-ignite-roulette-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Evan Phoenix\n\n    - title: \"Ignite Roulette: Sara Jackson\"\n      start_cue: \"08:54\"\n      end_cue: \"13:20\"\n      id: \"sara-jackson-ignite-roulette-rubyconf-2019\"\n      video_id: \"sara-jackson-ignite-roulette-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Sara Jackson\n\n    - title: \"Ignite Roulette: Ernie Miller\"\n      start_cue: \"13:20\"\n      end_cue: \"18:16\"\n      id: \"ernie-miller-ignite-roulette-rubyconf-2019\"\n      video_id: \"ernie-miller-ignite-roulette-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Ernie Miller\n\n    - title: \"Ignite Roulette: Britni Alexander\"\n      start_cue: \"18:32\"\n      end_cue: \"23:00\"\n      id: \"britni-alexander-ignite-roulette-rubyconf-2019\"\n      video_id: \"britni-alexander-ignite-roulette-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Britni Alexander\n\n    - title: \"Ignite Roulette: Brandon Weaver\"\n      start_cue: \"23:00\"\n      end_cue: \"28:43\"\n      id: \"brandon-weaver-ignite-roulette-rubyconf-2019\"\n      video_id: \"brandon-weaver-ignite-roulette-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Brandon Weaver\n\n    - title: \"Ignite Roulette Winner\"\n      start_cue: \"28:43\"\n      end_cue: \"31:57\"\n      id: \"adam-cuppy-ignite-roulette-winner-rubyconf-2019\"\n      video_id: \"adam-cuppy-ignite-roulette-winner-rubyconf-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Cuppy\n\n- id: \"adam-mccrea-rubyconf-2019\"\n  title: 'In the beginning, there was \"require\"...'\n  raw_title: 'RubyConf 2019 - In the beginning, there was \"require\"... by Adam McCrea'\n  speakers:\n    - Adam McCrea\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-11-29\"\n  description: |-\n    RubyConf 2019 - In the beginning, there was \"require\"... by Adam McCrea\n\n    Almost every Ruby program begins with the \"require\" method, but many of us don't pause to think about what it's doing until it fails us.\n\n    What happens when we call \"require\"? How does Ruby find what we're looking for? Is Bundler somehow involved? What about \"requirerelative\" and \"requiredependency\", and what the heck is a \"binstub\"?\n\n    This talk will guide beginner and intermediate Rubyists through these foundational concepts that power our Ruby programs, from single-file script to a behemoth Rails 6 app.\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"I0a5zv7uBHw\"\n\n- id: \"christian-bruckmayer-rubyconf-2019\"\n  title: \"Digesting MRI by Studying Alternative Ruby Implementations\"\n  raw_title: \"RubyConf 2019 - Digesting MRI by Studying Alternative Ruby Implementations by Christian Bruckmayer\"\n  speakers:\n    - Christian Bruckmayer\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-03\"\n  description:\n    \"RubyConf 2019 - Digesting MRI by Studying Alternative Ruby Implementations by Christian Bruckmayer\n\n\n    Pointers, managing memory and static typing - writing C code is hard! However, most programming languages, including Matz's Ruby Interpreter (MRI), are implemented in a low\n    level programming language. So you think without knowing these concepts, you can not contribute to Ruby? Wrong! Although MRI is implemented in C, fortunately there are Ruby's\n    in Java, Go and even Ruby itself.\n\n    \\r\n\n\n    If you ever wanted to learn about Ruby internals without being a C expert, this talk is for you. Join me on my journey of re-implementing hash maps in JRuby, breaking bundler\n    and actually learn to write (some) C code.\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"-UVV8_560eE\"\n\n- id: \"molly-struve-rubyconf-2019\"\n  title: \"Elasticsearch 5 or and Bust\"\n  raw_title: \"RubyConf 2019 - Elasticsearch 5 or and Bust by Molly Struve\"\n  speakers:\n    - Molly Struve\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-04\"\n  description: |-\n    RubyConf 2019 - Elasticsearch 5 or and Bust by Molly Struve\n\n    Breaking stuff is part of being a developer, but that never makes it any easier when it happens to you. The Elasticsearch outage of 2017 was the biggest outage our company has ever experienced. We drifted between full-blown downtime and degraded service for almost a week. However, it taught us a lot about how we can better prepare and handle upgrades in the future. It also bonded our team together and highlighted the important role teamwork and leadership plays in high-stress situations. The lessons learned are ones that we will not soon forget. In this talk, I will share those lessons and our story in hopes that others can learn from our experiences and be better prepared when they execute their next big upgrade.\n\n    #rubyconf2019 #confreaks\n  video_provider: \"youtube\"\n  video_id: \"IiNPLJOZ0Kw\"\n\n- id: \"itoyanagi-sakura-rubyconf-2019\"\n  title: \"Technical Background of Interactive CLI of Ruby 2.7\"\n  raw_title: \"RubyConf 2019 - Technical Background of Interactive CLI of Ruby 2.7\\r by ITOYANAGI Sakura\"\n  speakers:\n    - ITOYANAGI Sakura\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-04\"\n  description:\n    \"Technical Background of Interactive CLI of Ruby 2.7\\r by ITOYANAGI Sakura\n\n\n    Ruby 2.7 will be released with new multiline IRB that uses a new input library Reline. I'll talk about the technical background of it.\\r\n\n\n    \\r\n\n\n    the history of terminal\n\n\n    the Morse code\\r\n\n\n    typewriter\\r\n\n\n    teletype\\r\n\n\n    escape sequence\\r\n\n\n    escape sequence on Unix like OS\\r\n\n\n    Windows support\\r\n\n\n    GNU Readline compatible features\\r\n\n\n    editing modes\\r\n\n\n    inputrc that is a setting file\\r\n\n\n    I8n support\\r\n\n\n    too many character encodings in the world\\r\n\n\n    Unicode's complex tweaked specifications\\r\n\n\n    ...it's very difficult to understand for non-CJK people so I'll try to explain it by emoji\n\n\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"SzgmcVN7qu4\"\n\n- id: \"aaron-patterson-rubyconf-2019\"\n  title: \"Compacting Heaps in Ruby 2.7\"\n  raw_title: \"RubyConf 2019 - Compacting Heaps in Ruby 2.7 by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-11-29\"\n  slides_url: \"https://speakerdeck.com/tenderlove/compacting-gc-for-mri\"\n  description: |-\n    RubyConf 2019 - Compacting Heaps in Ruby 2.7 by Aaron Patterson\n\n    Ruby 2.7 will feature a manual heap compactor integrated with the GC. In this presentation we'll cover how Ruby's memory is arranged, how compaction can be helpful to your application, as well as algorithms and implementation details of the heap compactor. As a bonus, we'll cover GC debugging techniques as well! This presentation is going to be heaps of fun. Don't turn the page because we're going to scan the stack for some great pointers!\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"1F3gXYhQsAY\"\n\n- id: \"charles-nutter-rubyconf-2019\"\n  title: \"JRuby: Zero to Scale! 🔥\"\n  raw_title: \"RubyConf 2019 - JRuby: Zero to Scale! 🔥 by Charles Oliver Nutter and Thomas E Enebo\"\n  speakers:\n    - Charles Nutter\n    - Thomas E Enebo\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-04\"\n  description:\n    \"JRuby: Zero to Scale! 🔥 by Charles Oliver Nutter and Thomas E Enebo\n\n\n    JRuby is deployed by hundreds of companies, running Rails and other services at higher speeds and with better scalability than any other runtime. With JRuby you get better\n    utilization of system resources, the performance and tooling of the JVM, and a massive collection of libraries to add to your toolbox.\n\n\n    In this talk, we'll cover:\\r\n\n\n    Getting started on JRuby\\r\n\n\n    Comparison to CRuby\\r\n\n\n    Building, migrating, and deploying apps\\r\n\n\n    Tuning, profiling, and monitoring\\r\n\n\n    Scaling considerations\n\n\n\n\n    #confreaks #rubyconf2019 #rubyconf\"\n  video_provider: \"youtube\"\n  video_id: \"yTGegFR3aGc\"\n\n- id: \"brian-mcelaney-rubyconf-2019\"\n  title: \"Seven Deadly Sins\"\n  raw_title: \"RubyConf 2019 - Seven Deadly Sins by Brian McElaney\"\n  speakers:\n    - Brian McElaney\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-04\"\n  description: \"RubyConf 2019 - Seven Deadly Sins by Brian McElaney\n\n\n    Software projects accumulate many kinds of debt. Each debt comes in the form of small qualitative shortcomings we (knowingly or unknowingly) choose to ignore in the name of\n    shipping. They cause friction -- and over time they can combine to easily grind momentum to a halt if left unchecked. While these kinds of debt can in fact be useful (if not\n    necessary) to creating software - teams need to understand the nature of their shortcomings to prevent \\\"velocity bankruptcy.\\\"\n\n    \\r\n\n\n    In this talk we'll discuss the nature of process debt by using classical ideas related to \\\"unproductive behavior\\\" as a guide: hitting on shortcomings in culture, empathy,\n    discipline, morale, organization, preparedness, and requirements. We'll discuss examples, tips on identifying the risks in your own projects, and how to decide when to avoid,\n    mitigate, or accept and track these risks.\n\n\n    #rubyconf2019 #confreaks\"\n  video_provider: \"youtube\"\n  video_id: \"w04t4D_DArE\"\n\n- id: \"tony-drake-rubyconf-2019\"\n  title: \"Containerizing Local Development... Is It Worth it?\"\n  raw_title: \"RubyConf 2019 - Containerizing Local Development... Is It Worth it?\\r by Tony Drake\"\n  speakers:\n    - Tony Drake\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-12-04\"\n  description:\n    \"Containerizing Local Development... Is It Worth it?\\r by Tony Drake\n\n\n    Containers are the current hotness for deployment. But, how about development? They can provide a good way to manage local dependencies even if you're just writing a gem\n    instead of an app. While writing and running code directly on your laptop has its own obstacles, using containers for development is not a silver bullet and brings along its\n    own set of headaches. Which cases do containers make sense and how would they be configured? Containers may not be for you, but we'll go through some example setups. It'll be\n    up to you whether or not you want to change your local setup after this talk.\n\n\n\n\n    #confreaks #rubyconf2019\"\n  video_provider: \"youtube\"\n  video_id: \"NZ02hy6QOOk\"\n\n# Afternoon Break\n\n- id: \"evan-phoenix-rubyconf-2019\"\n  title: \"Q&A with Matz\"\n  raw_title: \"RubyConf 2019 - Q&A with Yukihiro Matsumoto (Matz)\"\n  speakers:\n    - Evan Phoenix\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2019\"\n  date: \"2019-11-20\"\n  published_at: \"2019-11-30\"\n  description: |-\n    RubyConf 2019 - Q&A with Yukihiro Matsumoto (Matz)\n\n    #confreaks #rubyconf2019\n  video_provider: \"youtube\"\n  video_id: \"vqpNmaEDn-o\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2020/event.yml",
    "content": "---\nid: \"PLbHJudTY1K0cyDs1ZwFLzlfQqvkDKt17N\"\ntitle: \"RubyConf 2020\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: \"\"\npublished_at: \"2020-11-27\"\nstart_date: \"2020-11-17\"\nend_date: \"2020-11-19\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2020\nbanner_background: \"#FFFDF7\"\nfeatured_background: \"#FFFDF7\"\nfeatured_color: \"#37312B\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2020/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"allison-mcmillan-rubyconf-2020\"\n  title: \"Opening Announcements\"\n  raw_title: \"RubyConf 2020 - Opening Announcements\"\n  speakers:\n    - Allison McMillan\n    - Barrett Clark\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FTWKackp1Js\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2020\"\n  title: \"Keynote: Ruby 3 and Beyond\"\n  raw_title: \"Keynote by Matz\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Keynote by Yukihiro Matsumoto\n\n    The creator of Ruby, Matz works for the Ruby Association to improve everything Ruby.\n  video_provider: \"youtube\"\n  video_id: \"JojpqfaPhjI\"\n\n- id: \"aaron-patterson-rubyconf-2020\"\n  title: \"Automatic GC Compaction in MRI\"\n  raw_title: \"Automatic GC Compaction in MRI - Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Ruby 2.7 introduced GC compaction, a way to reduce memory memory usage in your application. Unfortunately the compaction process is completely manual, requiring developers to determine the best time to compact their heap. This talk is about making the compaction process automatic and the challenges in doing so. We'll discuss various implementation techniques including read barriers and running the GC concurrently with the main program. This talk will have read barriers, but it won't have watch barriers, so come watch the talk!\n\n    Aaron Patterson\n    Aaron is a full time Ruby developer working at Shopify, whose interests include: Keyboards, Cats, and Code. Aaron is known online as tenderlove, but he also answers by \"Aaron\".\n  video_provider: \"youtube\"\n  video_id: \"28BBjKfUpTc\"\n\n- id: \"brandon-weaver-rubyconf-2020\"\n  title: \"Tales of the Autistic Developer: The Expert\"\n  raw_title: \"Tales of the Autistic Developer: The Expert - Brandon Weaver\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Expertise is a strange concept, and very hard to quantify at that. It's a state in which you exceed in a given field and can stand as an authority, a wellspring of knowledge and an inspiration to others in that field.\n\n    For someone with autism and a particular obsessive streak expertise feels like a natural evolution of their interests into solidified knowledge and pragmatism.\n\n    Expertise is also perhaps the most dangerous part of an autists career.\n\n\n    Brandon Weaver\n    Brandon is a Ruby Architect at Square working on the Frameworks team, defining standards for Ruby across the company. He's an artist who turned programmer who had a crazy idea to teach programming with cartoon lemurs and whimsy. He's also autistic, and would love to talk to you about your own experiences.\n  video_provider: \"youtube\"\n  video_id: \"rEeCeJv_H28\"\n\n- id: \"ariel-caplan-rubyconf-2020\"\n  title: \"The Humble Hash\"\n  raw_title: \"The Humble Hash - Ariel Caplan\"\n  speakers:\n    - Ariel Caplan\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Hashes seem simple. Set a key to a corresponding value, retrieve the value by key. What else is there to know?\n\n    A whole lot, it turns out! Ruby makes several surprising choices about how hashes work, which turn hashes into dynamic powerhouses of functionality.\n\n    We'll dive into how hashes work, understand how they form the groundwork for some extremely useful standard library utilities, and learn patterns to leverage the unparalleled versatility of the humble hash to write concise, performant, beautiful code.\n\n\n    Ariel Caplan\n    Ariel Caplan is a developer, speaker, and open source contributor. In past stages of life, he has been a biologist, periodical editor, molecular animator, rabbinical student, stem cell donor, and award-winning amateur poet.\n\n    Ariel works at Cloudinary, developing new features on a Ruby app serving billions of image and video requests daily.\n\n    He also enjoys finding, sharing, and learning new ways to see the tools we work with every day, and hopes this talk will help you do just that!\n  video_provider: \"youtube\"\n  video_id: \"jAn3c6O2OZo\"\n\n- id: \"kevin-murphy-rubyconf-2020\"\n  title: \"Enough Coverage To Beat The Band\"\n  raw_title: \"Enough Coverage To Beat The Band - Kevin Murphy\"\n  speakers:\n    - Kevin Murphy\n  event_name: \"RubyConf 2020\"\n  slides_url: \"https://speakerdeck.com/kevinmurphy/enough-coverage-to-beat-the-band\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    The lights cut out. The crowd roars. It’s time. The band takes the stage. They’ve practiced the songs, particularly the covers. They’ve sound checked the coverage of the speakers. They know the lighting rig has the proper colored gels covering the lamps. They’re nervous, but they’ve got it all covered.\n\n    Similarly, code coverage can give you confidence before your app performs on production and also tell you how live code is used (or not used). We’ll cover how to leverage ruby’s different coverage measurement techniques in concert to assist your crew and delight your audience.\n\n\n    Kevin Murphy\n    Kevin lives near Boston, where he is a Software Developer at The Gnar Company. He’s doing the best he can to cope with a year of concerts that could have been.\n  video_provider: \"youtube\"\n  video_id: \"EyLO0EEm3BQ\"\n\n- id: \"olivier-lacan-rubyconf-2020\"\n  title: \"Tracking COVID 19 with Ruby\"\n  raw_title: \"Tracking COVID 19 with Ruby  - Olivier Lacan\"\n  speakers:\n    - Olivier Lacan\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Programmers are not epidemiologists, but epidemiologists have never needed programmers more. Not for our viral opinions but for our ability to retrieve large data sets and make them understandable through expressive code. As the pandemic was silently taking hold in the United States in early 2020, I used simple web and Ruby tools to gather invaluable data from often obscure state data sources in order to understand the extent of the pandemic in my area. I never expected this would lead me to become a contributor to the pirate CDC.\n\n    Olivier Lacan\n    Olivier likes to use computers to help people. He maintained Code School for many years and now builds tools to support exciting new learning modalities at Pluralsight. He created those Shields.io badges that plaster your open source READMEs and tried to make those same projects more accessible with Keep a Changelog. Recently, he contributed to the COVID Tracking Project at The Atlantic and focused on uncovering pandemic data for the state of Florida.\n  video_provider: \"youtube\"\n  video_id: \"lRUq3ZJHXKE\"\n\n- id: \"soutaro-matsumoto-rubyconf-2020\"\n  title: \"The State of Ruby 3 Typing\"\n  raw_title: \"The State of Ruby 3 Typing - Soutaro Matsumoto\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    This talk is about the new feature of Ruby 3 for static type checking. The Ruby committer team had a plan to provide an optional static type checker for Ruby 3, but it is changed. Ruby 3 won't ship with a static type checker, but it will provide a feature called RBS to support type checker developments. In this talk, I will explain what RBS is, how the gem helps type tools developments, and what to do to get your gems ready for RBS.\n\n\n    Soutaro Matsumoto\n    Soutaro is a lead Ruby engineer at Square working on Steep, RBS, and static typing. He is a core Ruby committer working with Matz and other core committers on the RBS specification that will ship with Ruby 3.\n  video_provider: \"youtube\"\n  video_id: \"xnwGPQghmo4\"\n\n- id: \"ryann-richardson-rubyconf-2020\"\n  title: \"Keynote\"\n  raw_title: \"Keynote - Ryann Richardson\"\n  speakers:\n    - Ryann Richardson\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    In 2018, Ryann Richardson made history, becoming the 50th Anniversary Miss Black America. Before that, the tech marketer-turned-founder and Diversity & Inclusion advocate spent 10 years building brands and culture for companies spanning early-stage start-ups (Victor) to billion-dollar \"unicorns\" (Uber) to the Fortune 500 (T-Mobile/Deutsche Telekom). Her work earned her a spot as the youngest honoree on Savoy Magazine’s list of Most Influential Black Executives in Corporate America and set her on the path to discovering her unique purpose as a champion for underrepresented voices. Now, in her second act as a founder, her company Ellington Lafayette Co. is building a new type of tech incubator, focusing exclusively on start-ups that drive social equity for women and communities of color. Ryann travels the US as a Keynote Speaker giving talks “Authenticity and Assimilation”, “Taking Up Space as Women and POC” and “The Politics of Race, Beauty, and Power.”\n  video_provider: \"youtube\"\n  video_id: \"db0Sw5iV5jM\"\n\n- id: \"kerri-miller-rubyconf-2020\"\n  title: \"Keynote: If you can move it, it isn't broken\"\n  raw_title: \"Keynote - Kerri Miller\"\n  speakers:\n    - Kerri Miller\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Kerri Miller is a Software Developer and Team Lead based in the Pacific Northwest. She has worked at enterprise companies, international ad agencies, boutique consultancies, start-ups, mentors and teaches students. She currently is a Senior Backend Engineer at Gitlab, and also works for Ruby Together on RubyGems.org and Bundler.\n\n    While that is all factually true, it doesn't actually describe an actual person. Kerri has an insatiable curiosity, having worked as a lighting designer, marionette puppeteer, sous chef, and farm hand. She attended college to study performance production, was once a semi-professional poker player, has strong opinions about keycaps, knows some sweet yoyo tricks, and enjoys melting hot glass with a blowtorch to create beads, cane, and murrini. Asked to describe herself in two words, she thought a bit and replied \"lackwit gadabout.\"\n  video_provider: \"youtube\"\n  video_id: \"TLRyAYSOWcc\"\n\n- id: \"emily-giurleo-rubyconf-2020\"\n  title: \"The Bug that Forced Me to Understand Memory Compaction\"\n  raw_title: \"The Bug that Forced Me to Understand Memory Compaction - Emily Giurleo\"\n  speakers:\n    - Emily Giurleo\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  slides_url: \"https://docs.google.com/presentation/d/1VmJyyM9dY5clrlCj8hkzkQY8DYZYM-HGYIBl5JAhUhU/edit#slide=id.p\"\n  description: |-\n    Did you know that Ruby 2.7 introduces a new method for manual memory compaction?\n\n    Neither did I.\n\n    Then a user reported a bug on a gem I maintain, and well...\n\n    In this talk, I’ll tell you a story about how one bug forced me to learn all about memory management in Ruby. By the end of this talk, you should understand how memory is allocated on the heap, how Ruby implements garbage collection, and what memory compaction is all about!\n\n    Emily Giurleo\n    Emily Giurleo is a software engineer and avid Rubyist. This December, she'll start working at Numero, where she'll help build the next generation of campaign finance tools. In her spare time, she enjoys creating tech for good causes, reading fantasy novels, and hanging out with her pets.\n  video_provider: \"youtube\"\n  video_id: \"GlpZPv1bp4g\"\n\n- id: \"koichi-sasada-rubyconf-2020\"\n  title: \"Ractor Demonstration\"\n  raw_title: \"Ractor Demonstration - Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Ruby 3 will have a new feature Ractor, an abstraction for thread-safe concurrent/parallel execution. Because most of objects are not shared with multiple Ractors, Ruby programmer can enjoy parallel programming without some kind of difficult thread-safety issues. However, to keep objects isolation, Ractor introduces some limitation for the languages. For example, you can not use global variables on a multi Ractor program. This presentation will introduce about Ractor briefly and show the powers of Ractor and its limitations with interactive demonstration.\n\n    Koichi Sasada\n    Koichi Sasada is a programmer, mainly developing Ruby interpreter (CRuby/MRI). He received Ph.D (Information Science and Technology) from the University of Tokyo, 2007. He became a faculty of University of Tokyo (Assistant associate 2006-2008, Assistant professor 2008-2012). After the 13 years life in university, he had joined a member of Matz's team in Heroku, Inc. Now he is a member of Cookpad Inc (engineer). He is also a director of Ruby Association.\n  video_provider: \"youtube\"\n  video_id: \"0kM7yFM6Dao\"\n\n- id: \"jesse-spevack-rubyconf-2020\"\n  title: \"The Minaswan::Interview\"\n  raw_title: \"The Minaswan::Interview - Jesse Spevack\"\n  speakers:\n    - Jesse Spevack\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    White-boarding is not nice. An unpaid take home project is not nice. We decided to apply the Ruby community motto \"Matz is nice and so we are nice,\" to our technical interview process. Come learn what changes we made, how we enlisted support of other rubyists and non-rubyists alike, and how you can too.\n\n\n    Jesse Spevack\n    I am a senior platform engineer at Ibotta, a cash back for shopping mobile app. Before getting into the tech world, I worked in public K-12 education for 11 years. I transitioned from education into technology by way of the Turing School of Software Design, a Denver based code school with a Ruby-centric curriculum.\n  video_provider: \"youtube\"\n  video_id: \"c4K-ORZmrGk\"\n\n- id: \"kevin-lesht-rubyconf-2020\"\n  title: \"Automation Engineering with Serverless Compute\"\n  raw_title: \"Automation Engineering with Serverless Compute - Kevin Lesht\"\n  speakers:\n    - Kevin Lesht\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Have you ever wanted to automate a tedious process? Like, relaying omelette photos straight from your phone to an omelette blog? This talk is for you! Learn how to leverage Ruby within serverless functions to handle everything from machine learning based object detection through event triggers, and static site generation!\n\n    As the system for automation is explored, so too are the challenges, or, brick walls, that were hit along the way. In this talk, you'll not only learn about technology, but also about mental models for solving problems and overcoming those inevitable brick walls.\n\n\n    Kevin Lesht\n    Kevin is a Senior Software Engineer working out of Chicago, Illinois, for Home Chef, a meal kit delivery company. He is the host of the Day as a Dev podcast, where he interviews developers from all walks of life, to offer students and those interested in tech, a practical look at life in the industry. Previously, he co-founded ZeroSleep Designs, a digital design agency, and worked with dozens of clients to bring their ideas online. He's passionate about getting others excited about tech!\n  video_provider: \"youtube\"\n  video_id: \"upf8Niku9MI\"\n\n- id: \"kent-beck-rubyconf-2020\"\n  title: \"Keynote\"\n  raw_title: \"Keynote - Kent Beck\"\n  speakers:\n    - Kent Beck\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Kent helps geeks feel safe in the world. In Kent's career he has constantly challenged software engineering dogma, promoting ideas like patterns, test-driven development, and Extreme Programming. Currently Fellow at Gusto, he is the author of a half dozen books.\n  video_provider: \"youtube\"\n  video_id: \"UIyMs7xV6eo\"\n\n- id: \"joshua-larson-rubyconf-2020\"\n  title: \"Screaming Zombies and Other Tales: Race Condition Woes\"\n  raw_title: \"Screaming Zombies and Other Tales: Race Condition Woes - Joshua Larson\"\n  speakers:\n    - Joshua Larson\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    What is the sound of a zombie screaming?\n\n    Race conditions are a problem that crop up everywhere. This talk will go over what a race condition is, and what it takes for a system to be vulnerable to them. Then we’ll walk through four stories of race conditions in production, including one that we named the “Screaming Zombies” bug.\n\n    You’ll leave this talk with a greater appreciation for how to build and analyze concurrent systems, and several fun stories for how things can go amusingly wrong.\n\n    And if you were wondering about the question at the top, the answer is: Silence\n\n\n    Josh Larson\n    Josh is a full-time programmer, part-time human, whose interests include weird programming, physics, math, and trying to make software reliably be better. When he’s not writing code or equations, he’s probably biking somewhere or watching something on HBO.\n  video_provider: \"youtube\"\n  video_id: \"p6Jz5cE4OkA\"\n\n- id: \"eileen-m-uchitelle-rubyconf-2020\"\n  title: \"Upgrading GitHub to Ruby 2.7\"\n  raw_title: \"Upgrading GitHub to Ruby 2.7 - Eileen Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    It's no secret that the upgrade to Ruby 2.7 is difficult — fixing the keyword argument, URI, and other deprecation warnings can feel overwhelming, tedious, and never ending. We experienced this first-hand at GitHub; we fixed over 11k+ warnings, sent patches to 15+ gems, upgraded 30+ gems, and replaced abandoned gems. In this talk we’ll look at our custom monkey patch for capturing warnings, how we divided work among teams, and the keys to a successful Ruby 2.7 upgrade. We’ll explore why upgrading is important and take a dive into Ruby 2.7’s notable performance improvements.\n\n\n    Eileen M. Uchitelle\n    Eileen Uchitelle is a Staff Software Engineer on the Ruby Architecture Team at GitHub and a member of the Rails Core team. She's an avid contributor to open source focusing on the Ruby on Rails framework and its dependencies. Eileen is passionate about scalability, performance, and making open source communities more sustainable and welcoming.\n  video_provider: \"youtube\"\n  video_id: \"OrPT7h2hsok\"\n\n- id: \"mercedes-bernard-rubyconf-2020\"\n  title: \"Coaching through Coding\"\n  raw_title: \"Coaching through Coding - Mercedes Bernard\"\n  speakers:\n    - Mercedes Bernard\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    When we use the words \"coaching\" or \"mentorship,\" we tend to picture one-on-one conversations with someone we respect where there are questions asked and advice given. But restricting our vision of mentorship to this type of interaction is extremely limiting!\n\n    Every activity during your workday is an opportunity to support your team members' career growth, including writing code, opening pull requests, and estimating tickets. In this talk, we'll identify strategies for coaching in our everyday technical activities and open our minds to look for opportunities in non-traditional places.\n\n\n    Mercedes Bernard\n    Mercedes Bernard is a Principal software engineer and engineering manager with Tandem, a digital consultancy in Chicago. She's also the founder of Dev Together, a mentorship community in Chi for those starting their dev careers. Outside of work, she likes to unplug and enjoys spinning yarn and crocheting.\n  video_provider: \"youtube\"\n  video_id: \"E0j-nXdnIp4\"\n\n- id: \"sun-li-beatteay-rubyconf-2020\"\n  title: \"How Prime Numbers Keep the Internet Secure\"\n  raw_title: \"How Prime Numbers Keep the Internet Secure - Sun-Li Beatteay\"\n  speakers:\n    - Sun-Li Beatteay\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    You may not know it, but you use prime numbers every day. They play a major role in internet security in the form of encryption.\n\n    In this talk, you will learn the inner workings of how the internet uses prime numbers to keep your data private as it travels over the wire. We will cover topics such as symmetric and asymmetric encryption, and why prime numbers are just so damn hard to crack. By the end, you will understand how to encrypt and decrypt data yourself with just the Ruby standard library.\n\n    So come join me as we demystify HTTPS using code, color theory, and only a pinch of math 🤓.\n\n\n    Sun-Li Beatteay\n    Sunny is a software engineer and Rubyist at DigitalOcean where he works on building managed storage products. He has been using Ruby since he started learning to program in 2016. Like Ruby, he's passionate about encapsulating complicated concepts in simple language. When he's not breaking production, he can be found trying to figure out how to pipe all his troubles into /dev/null.\n  video_provider: \"youtube\"\n  video_id: \"f_Qan-eNT-g\"\n\n- id: \"nickolas-means-rubyconf-2020\"\n  title: \"Mach 2.0 at Scale\"\n  raw_title: \"Mach 2.0 at Scale - Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    When Chuck Yeager broke the sound barrier for the first time, he set off a race around the world to do the same thing with a plane full of paying passengers. The US, Russia, UK, and France all wanted a piece of the inevitable fortune to be made building aircraft to cross oceans faster than sound itself.\n\n    In the end, though, only one design flew passengers in significant numbers, the Anglo-French Concorde. Why? Let’s figure out what allowed the British and French to succeed where others failed. Along the way, we’ll learn a little about compromise and constraints and a lot about success itself.\n\n\n    Nickolas Means\n    Nickolas Means loves nothing more than a story of engineering triumph (except maybe a story of engineering disaster). When he's not stuck in a Wikipedia loop reading about plane crashes, he spends his days as a Director of Engineering at GitHub. He works remotely from Austin, TX, and spends most of his spare time hanging out with his wife and kids, going for a run, or trying to brew the perfect cup of coffee.\n  video_provider: \"youtube\"\n  video_id: \"uFURynXi5bk\"\n\n- id: \"h-waterhouse-rubyconf-2020\"\n  title: \"The Future Should Be Uneven\"\n  raw_title: \"The Future Should Be Uneven - H. Waterhouse\"\n  speakers:\n    - H. Waterhouse\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    \"The future is here, it's just unevenly distributed\" is something we say about why people on instant connection devices walk past people sleeping on sidewalks.\n\n    Let's talk about how we can provide more power to users to customize, configure, streamline, and understand what they are getting from us. Let's explore some accessibility settings that turn out to be just good universal design.\n\n    You're going to leave this talk inspired to build an infrastructure that can support the glorious diversity of the future, instead of assuming that everyone is the same.\n\n\n    H. Waterhouse\n    Heidi is a developer advocate with LaunchDarkly. She delights in working at the intersection of usability, risk reduction, and cutting-edge technology. One of her favorite hobbies is talking to developers about things they already knew but had never thought of that way before. She sews all her conference dresses so that she's sure there is a pocket for the mic.\n  video_provider: \"youtube\"\n  video_id: \"E3alWkOAjV8\"\n\n- id: \"aniyia-williams-rubyconf-2020\"\n  title: \"Keynote: 5 Rules for Building the Future\"\n  raw_title: \"Keynote - Aniyia Williams\"\n  speakers:\n    - Aniyia Williams\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Aniyia Williams is a creator, inventor, and tech changemaker. She serves as Executive Director of Black & Brown Founders, which provides vital resources to Black and Latinx entrepreneurs building tech companies with limited capital. She is also co-founder of Zebras Unite, an entrepreneur-led movement focused on creating a more ethical and sustainable start-up ecosystem.\n  video_provider: \"youtube\"\n  video_id: \"Pa8L8fqq-Dg\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2020-qa-with-matz\"\n  title: \"Q&A With Matz\"\n  raw_title: \"Q&A With Matz - Yukihiro Matsumoto & Evan Phoenix\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n    - Evan Phoenix\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: |-\n    Matz and Evan discuss topics around his Keynote and other developments within the Ruby language and community.\n  video_provider: \"youtube\"\n  video_id: \"c3Uv0jbCjcs\"\n\n- id: \"allison-mcmillan-rubyconf-2020-conference-closing\"\n  title: \"Conference Closing\"\n  raw_title: \"RubyConf 2020 - Conference Closing\"\n  speakers:\n    - Allison McMillan\n    - Barrett Clark\n    - Adam Cuppy\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"EFR03PDZiIc\"\n\n- id: \"allison-mcmillan-rubyconf-2020-closing-day-2\"\n  title: \"Closing Day 2\"\n  raw_title: \"RubyConf 2020 - Closing Day 2\"\n  speakers:\n    - Allison McMillan\n    - Barrett Clark\n  event_name: \"RubyConf 2020\"\n  date: \"2020-12-18\"\n  published_at: \"2020-12-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5-r23sXhj1o\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2021/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYVnWhDQk4RCPVlMW40I6s5\"\ntitle: \"RubyConf 2021\"\nkind: \"conference\"\nlocation: \"Denver, CO, United States\"\ndescription: |-\n  Focused on fostering the Ruby programming language and the robust community that has sprung up around it, RubyConf brings together Rubyists both established and new to discuss emerging ideas, collaborate, and socialize in some of the best locations in the US.\npublished_at: \"2022-08-09\"\nstart_date: \"2021-11-08\"\nend_date: \"2021-11-11\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2021\nbanner_background: \"#FFFBEC\"\nfeatured_background: \"#FFFBEC\"\nfeatured_color: \"#171714\"\ncoordinates:\n  latitude: 39.7392358\n  longitude: -104.990251\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2021/videos.yml",
    "content": "---\n# TODO: running order\n# TODO: talk dates\n\n# Website: https://web.archive.org/web/20211204180005/https://rubyconf.org\n# Schedule: https://web.archive.org/web/20211204180005/https://rubyconf.org/schedule\n\n- id: \"riaz-virani-rubyconf-2021\"\n  title: \"Whimsy: Pry Irresponsibly\"\n  raw_title: \"RubyConf 2021 - Whimsy: Pry Irresponsibly by Riaz Virani\"\n  speakers:\n    - Riaz Virani\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"yj0dYow4B7E\"\n\n- id: \"aaron-patterson-rubyconf-2021\"\n  title: \"Some Assembly Required\"\n  raw_title: \"RubyConf 2021 - Some Assembly Required by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  slides_url: \"https://speakerdeck.com/tenderlove/some-assembly-required\"\n  description: |-\n    Some Assembly Required by Aaron Patterson\n\n    Let's write a JIT for Ruby, in Ruby! We're going to learn how a JIT works from the ground up by building TenderJIT, a pure Ruby JIT compiler. First, we'll learn how Ruby's virtual machine works, then we'll learn how to plug a JIT in to the virtual machine. Finally, we'll generate machine code from our Ruby programs. By the end of the presentation we'll have a working JIT that converts Ruby code in to machine code all written in pure Ruby! But don't forget: some assembly is required!\n  video_provider: \"youtube\"\n  video_id: \"4vDfegrjUtQ\"\n\n- id: \"andrea-guendelman-rubyconf-2021\"\n  title: \"Keynote: Finding Purpose and Cultivating Spirituality by Andrea Guendelman\"\n  raw_title: \"RubyConf 2021 - Keynote: Finding Purpose and Cultivating Spirituality by Andrea Guendelman\"\n  speakers:\n    - Andrea Guendelman\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Keynote: Finding Purpose and Cultivating Spirituality by Andrea Guendelman\n  video_provider: \"youtube\"\n  video_id: \"G5ZdlqqhYEM\"\n\n- id: \"betsy-haibel-rubyconf-2021\"\n  title: \"Your Team, as Saga\"\n  raw_title: \"RubyConf 2021 - Your Team, as Saga by Betsy Haibel\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Your Team, as Saga by Betsy Haibel\n\n    Software systems are made of code, and the people who work on them. But most of all, they're made of the stories those people tell. Heroic legends of shipping to deadline, spooky ghost stories of refactors gone bad... and a lot of sci-fi, projecting out into a utopian (or dystopian) future. How can you edit this story to make it go right? In this talk, we'll apply fiction-writing tricks to the art of engineering roadmapping. We'll learn how to build narratives, develop our characters, and world-build our way to healthier teams and healthier code.\n  video_provider: \"youtube\"\n  video_id: \"pdxWY5Ebm2k\"\n\n- id: \"brandon-weaver-rubyconf-2021\"\n  title: \"Delightfully Fashionable Lemurs in Decorating Ruby\"\n  raw_title: \"RubyConf 2021 - Delightfully Fashionable Lemurs in Decorating Ruby by Brandon Weaver\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Delightfully Fashionable Lemurs in Decorating Ruby by Brandon Weaver\n\n    What to wear what to wear! The lemurs have a love for new robes and clothes, but these clothes are magical, and do some very interesting things. As it turns out decorating in Ruby can do rather unusual things to methods, classes, and even the lemurs.\n\n    Join the lemurs on a fashion-filled journey through decoration patterns in Ruby including tricks with method, define_method, method_added, and Module#prepend.\n  video_provider: \"youtube\"\n  video_id: \"vLQEsG5MM8E\"\n\n- id: \"kevin-newton-rubyconf-2021\"\n  title: \"Parsing Ruby\"\n  raw_title: \"RubyConf 2021 - Parsing Ruby by Kevin Newton\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Since Ruby's inception, there have been many different projects that parse Ruby code. This includes everything from development tools to Ruby implementations themselves. This talk dives into the technical details and tradeoffs of how each of these tools parses and subsequently understands your applications. After, we'll discuss how you can do the same with your own projects using the Ripper standard library. You'll see just how far we can take this library toward building useful development tools.\n\n  video_provider: \"youtube\"\n  video_id: \"EXKsRKmkrns\"\n\n- id: \"nickolas-means-rubyconf-2021\"\n  title: \"Taking the 737 to the Max\"\n  raw_title: \"RubyConf 2021 - Taking the 737 to the Max by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Ten years ago, Boeing faced a difficult choice. The Airbus A320neo was racking up orders faster than any plane in history because of its fuel efficiency improvements, and Boeing needed to compete. Should they design a new plane from scratch or just update the tried-and-true 737 with new engines?\n\n    The 737 MAX entered service seven years later as the result of that and hundreds of other choices along the way. Let’s look at some of those choices in context to understand how the 737 MAX went so very wrong. We’ll learn a thing or two along the way about making better decisions ourselves and as teams.\n\n  video_provider: \"youtube\"\n  video_id: \"MfU8CrenyMo\"\n\n- id: \"ben-greenberg-rubyconf-2021\"\n  title: \"On Being an Early Career Dev in Your 30s\"\n  raw_title: \"RubyConf 2021 - On Being an Early Career Dev in Your 30s by Ben Greenberg\"\n  speakers:\n    - Ben Greenberg\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Being early in your career always presents unique challenges, while being early in your second career later in life has its own particular issues to grapple with. The typical pipeline for the software industry does not fit the paradigm of an older career changer, and their presence can often throw the system for a loop.\n\n    In this talk, we will cover practical steps for navigating specific challenges related to hiring and being hired as a second-career dev. If approached with intention and thoughtfulness, the benefits can be immense for all involved.\n\n  video_provider: \"youtube\"\n  video_id: \"BFopVe4xyyw\"\n\n- id: \"evan-phoenix-rubyconf-2021\"\n  title: \"Q&A with Matz\"\n  raw_title: \"RubyConf 2021 - Q&A with Matz by Evan Phoenix & Yukihiro Matsumoto (Matz)\"\n  speakers:\n    - Evan Phoenix\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"tAdb766lzX8\"\n\n- id: \"elisabeth-hendrickson-rubyconf-2021\"\n  title: \"Keynote: On the Care and Feeding of Feedback Cycles by Elisabeth Hendrickson\"\n  raw_title: \"RubyConf 2021 - Keynote: On the Care and Feeding of Feedback Cycles by Elisabeth Hendrickson\"\n  speakers:\n    - Elisabeth Hendrickson\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"qHPguCNzVbU\"\n\n- id: \"jenny-shih-rubyconf-2021\"\n  title: \"Fake Your Test Away: How To Abuse Your Test Doubles\"\n  raw_title: \"RubyConf 2021 - Fake Your Test Away: How To Abuse Your Test Doubles by Jenny Shih\"\n  speakers:\n    - Jenny Shih\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    You probably already know: In a unit test, use test doubles to sub real dependencies. You probably also know: In reality, things are not so easy. What do you do if the dependencies span multiple layers? What if the dependencies are implicit? If we can't find the best level of isolation, test doubles can be unwieldy very quickly and they will make the test, as well as the future you, miserable. In this talk, we will look at symptoms that produce unreliable and unmaintainable tests, and develop a strategy that will make your test suite more resilient and actually enjoyable.\n\n  video_provider: \"youtube\"\n  video_id: \"4oJX-AN0J5k\"\n\n- id: \"kyle-doliveira-rubyconf-2021\"\n  title: \"The Mindset of Debugging\"\n  raw_title: \"RubyConf 2021 - The Mindset of Debugging by Kyle d'Oliveira\"\n  speakers:\n    - Kyle d'Oliveira\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    We, as developers, spend a large portion of our time debugging software. Sometimes the problems are easy to understand, but many times they are not and we are thrown into unfamiliar code and are expected to quickly find the problem and craft a solution. However, honing the skill of debugging doesn’t come up as much as it should. In this talk, I’ll go through a generic approach to debugging that can be applied and built upon to help you excel as you move through your career solving problems for a living.\n\n  video_provider: \"youtube\"\n  video_id: \"LitTV2k_X34\"\n\n- id: \"rachael-wright-munn-rubyconf-2021\"\n  title: \"Your First Open-Source Contribution\"\n  raw_title: \"RubyConf 2021 - Your First Open-Source Contribution by Rachael Wright-Munn\"\n  speakers:\n    - Rachael Wright-Munn\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Is open-source intimidating? Are you nervous about your code being rejected by the maintainers? Or maybe you just don’t know where to start. I know those nerves well. Let’s talk about it. We'll go step-by-step through the process of finding an issue, creating a PR, and collaborating with maintainers. Let’s get you that first open-source PR!\n  video_provider: \"youtube\"\n  video_id: \"z3WLFQd9PXA\"\n\n- id: \"steve-lynch-rubyconf-2021\"\n  title: \"I Read It But Don’t Get It, or How to Tackle Technical Texts\"\n  raw_title: \"RubyConf 2021 - I Read It But Don’t Get It, or How to Tackle Technical Texts by Steve Lynch\"\n  speakers:\n    - Steve Lynch\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |+\n    Technical books can be a key and important source of learning for engineers and developers of all experience levels. However, it is not uncommon for some of us to pick up even a famously “approachable” text and struggle to hack our way through each page.\n\n    Help, however, is on the way -- there are concrete skills that engaged readers of all kinds of texts employ while reading. This talk will outline those techniques while also providing concrete questions that can be used during reading to help you stay\n\n  video_provider: \"youtube\"\n  video_id: \"NdjG55NiX8o\"\n\n- id: \"ariel-caplan-rubyconf-2021\"\n  title: \"The Audacious Array\"\n  raw_title: \"RubyConf 2021 - The Audacious Array by Ariel Caplan\"\n  speakers:\n    - Ariel Caplan\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    What could be simpler than the array? It's just a list of indexed values, right?\n\n    Well, not so fast. Ruby reimagines what an array can be, turning it into a randomizer, a 2D map, a stack, a queue, and a mathematical set. It also provides built-in utilities for unparalleled analysis and search of its contents.\n\n    Understanding arrays deeply is a powerful step forward in writing concise, beautiful, semantic Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"RKlbn3KuN5k\"\n\n- id: \"emily-giurleo-rubyconf-2021\"\n  title: \"To mock, or not to mock?\"\n  raw_title: \"RubyConf 2021 - To mock, or not to mock? by Emily Giurleo\"\n  speakers:\n    - Emily Giurleo\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  slides_url: \"https://docs.google.com/presentation/d/1il8WKCqY-rsoz-Dbr3hl7MabRFZ3jfc0-xikb4PRGBQ/edit?usp=drive_web&ouid=101939856070811570152\"\n  description: |-\n    Mocking: it’s one of the most controversial topics in the testing world. Using mocks, we can more easily test parts of our applications that might otherwise go untested, but mocks can also be misused, resulting in tests that are brittle or downright self-referential.\n\n    So… how do we know when to use mocks in our tests? In this talk, we’ll identify three important questions that can help us make that decision. By the end of the talk, you will have a framework in mind to help you answer the question: to mock, or not to mock?\n\n  video_provider: \"youtube\"\n  video_id: \"mD7zm3MFPuA\"\n\n- id: \"elayne-juten-rubyconf-2021\"\n  title: \"Blank Page Panic! Creating Confidence with TDD\"\n  raw_title: \"RubyConf 2021 - Blank Page Panic! Creating Confidence with TDD by Elayne Juten\"\n  speakers:\n    - Elayne Juten\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Have you ever stared at a blank feature spec file hoping for tests to magically appear? Well, you’re not alone! In this talk we’ll take a look at how the combination of Test-Driven Development, pseudocode and RSpec can help get you to your initial commit with confidence, one RSpec error at a time!\n\n  video_provider: \"youtube\"\n  video_id: \"OtfzxlddWDY\"\n\n- id: \"claudio-baccigalupo-rubyconf-2021\"\n  title: \"The art of deleting code\"\n  raw_title: \"RubyConf 2021 - The art of deleting code by Claudio Baccigalupo\"\n  speakers:\n    - Claudio Baccigalupo\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    As the size of your project grows, some blocks of code become irrelevant. How can you find and delete them? And how can you be sure code is actually dead?\n\n    This talk will review a few techniques I learned from removing 50,000 lines of Ruby code at work.\n\n    We will see how git can help, with commands like blame, log --follow, and bisect. We will talk about static analysis, and running code coverage in development. We will explain how Ruby meta-programming can conflict with the \"Find in Project\" approach. We will show how to be nice to reviewers when submitting Pull Requests that delete code.\n\n  video_provider: \"youtube\"\n  video_id: \"nBZn2nE3yDE\"\n\n- id: \"micah-gates-rubyconf-2021\"\n  title: \"Learning Ractor with Raft\"\n  raw_title: \"RubyConf 2021 - Learning Ractor with Raft by Micah Gates\"\n  speakers:\n    - Micah Gates\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Ractor is a new concurrency mechanism in Ruby that unlocks great performance improvement possibilities. Its well defined sharing and messaging system makes it easier to reason about than threaded models.\n\n    Raft is a distributed consensus algorithm that backs distributed data stores such as Etcd, Console, and soon, Kafka; it’s designed to be straightforward and easy to understand.\n\n    In this session we’ll build a simple Raft implementation from scratch using Ractor. Ractor is one of the most exciting new features of Ruby, and modeling a distributed system is a great way to see what it can offer.\n\n  video_provider: \"youtube\"\n  video_id: \"13QyqsFShc4\"\n\n- id: \"kevin-kuchta-rubyconf-2021\"\n  title: \"Vertical Assignment in Ruby\"\n  raw_title: \"RubyConf 2021 - Vertical Assignment in Ruby by Kevin Kuchta\"\n  speakers:\n    - Kevin Kuchta\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Ruby's long had leftward assignment (x = 3) and recently got rightward assignment (3 = or greater x). The problem here is obvious: we need a vertical assignment operator. In a complete abdication of good taste and common sense, this talk will walk through correcting this heinous oversight. We'll abuse otherwise-respectable metaprogramming tools like Ripper and TracePoint to add a fully functional vequals operator. While this talk is almost 100% bad-ideas-by-volume, you'll learn a few tricks that you can use in your day-to-day work (or at least to terrify your co-workers).\n\n  video_provider: \"youtube\"\n  video_id: \"B2nBB70uy6M\"\n\n- id: \"christian-bruckmayer-rubyconf-2021\"\n  title: \"Keeping Developers Happy with a Fast CI\"\n  raw_title: \"RubyConf 2021 - Keeping Developers Happy with a Fast CI by Christian Bruckmayer\"\n  speakers:\n    - Christian Bruckmayer\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    When talking about performance, most developers think application speed, faster algorithms or better data structures. But what about your test suite? CI time is developer waiting time!\n\n    At Shopify we have more than 170,000 Ruby tests and we add 30,000 more annually. The sheer amount of tests and their growth requires some aggressive methods. We will illustrate some of our techniques including monitoring, test selection, timeouts and the 80/20 rule. If you have experience in writing tests and want to learn tricks on how to speed up your test suite, this talk is for you!\n\n  video_provider: \"youtube\"\n  video_id: \"XgKfeD-20ts\"\n\n- id: \"sweta-sanghavi-rubyconf-2021\"\n  title: \"Schrödinger's Error: Living In the grey area of Exceptions\"\n  raw_title: \"RubyConf 2021 - Schrödinger's Error: Living In the grey area of Exceptions by Sweta Sanghavi\"\n  speakers:\n    - Sweta Sanghavi\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    ArgumentErrors, TimeOuts, TypeErrors… even scanning a monitoring dashboard can be overwhelming. Any complex system is likely swimming in exceptions. Some are high value signals. Some are red herrings. Resilient applications that live in the entropy of the web require developers to be experts at responding to exceptions. But which ones and how?\n\n    In this talk, we’ll discuss what makes exception management difficult, tools to triage and respond to exceptions, and processes for more collective and effective exception management. We'll also explore some related opinions from you, my dear colleagues.\n\n  video_provider: \"youtube\"\n  video_id: \"B1yIAhnkjDY\"\n\n- id: \"chris-cha-rubyconf-2021\"\n  title: \"Automating Legacy Desktop Applications with JRuby and Sikuli\"\n  raw_title: \"RubyConf 2021- Automating Legacy Desktop Applications with JRuby and Sikuli by Chris Cha\"\n  speakers:\n    - Chris Cha\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Desktop applications supporting line-of-business, enterprise functions live on as massive, complex beasts. Without an easy route into its internals and modernization falling by the wayside, it's up to you to make sure any small change doesn't break — well — everything. In this talk, we'll discuss the journey of bringing up a Windows VM to poke at an app using screenshots, image recognition, and Minitest to create our own Robotic Process Automation (RPA) framework.\n\n  video_provider: \"youtube\"\n  video_id: \"Oqh7ueTLlwo\"\n\n- id: \"nick-schwaderer-rubyconf-2021\"\n  title: \"Ruby Archaeology\"\n  raw_title: \"RubyConf 2021 - Ruby Archaeology by Nick Schwaderer\"\n  speakers:\n    - Nick Schwaderer\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    IN 2009 _WHY TWEETED: \"PROGRAMMING IS RATHER THANKLESS. YOU SEE YOUR WORKS BECOME REPLACED BY SUPERIOR WORKS IN A YEAR. UNABLE TO RUN AT ALL IN A FEW MORE.\"\n    I take this as a call to action to run old code. In this talk we dig, together, through historical Ruby. We will have fun excavating interesting gems from the past.\n\n    Further, I will answer the following questions:\n\n    What code greater than 12 years old still runs in Ruby 3.0?\n    What idioms have changed?\n    And for the brave: how can you set up an environment to run Ruby 1.8 code from ~2008 on a modern machine?\n\n  video_provider: \"youtube\"\n  video_id: \"9ai2nL93mt0\"\n\n- id: \"paul-sadauskas-rubyconf-2021\"\n  title: \"Service Objects With Dry.rb: Monads and Transactions\"\n  raw_title: \"RubyConf 2021 - Service Objects With Dry.rb: Monads and Transactions by Paul Sadauskas\"\n  speakers:\n    - Paul Sadauskas\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Service objects are an important tool in your toolbox, and Dry.rb's Transaction library is one of the most powerful, and one of the most magic. It's a \"business transaction\" DSL, and has error handling as a primary concern. We'll start by exploring Monads in Ruby (they're not scary!). Then we'll see how that simple concept unlocks another level of service objects that are far more robust and testable, and how to wire them all together with Dry::Transaction. Finally we'll touch on extending transactions with custom steps, and how to integrate them into an existing application.\n\n  video_provider: \"youtube\"\n  video_id: \"HOmCJq2LOZ4\"\n\n- id: \"vaidehi-joshi-rubyconf-2021\"\n  title: \"The Science and Magic of Debugging\"\n  raw_title: \"RubyConf 2021 - The Science and Magic of Debugging by Vaidehi Joshi\"\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    It was the best of times, it was the worst of times: it was debugging time. Debugging is an inevitable reality of writing software; every developer has had a piece of code behave unexpectedly at some point or another.\n\n    But debugging can feel like magic: Where do you start looking for the bug, and how do you know where to find it?\n\n    In this talk, we'll learn what makes debugging hard, and the cognitive process behind it. We'll also explore using the scientific method as a debugging process model in order to help us get better at finding the bugs in our own Ruby programs. Let's become better debuggers together!\n\n  video_provider: \"youtube\"\n  video_id: \"CidxJ_rJVBw\"\n\n- id: \"justin-searls-rubyconf-2021\"\n  title: \"How to Make a Gem of a Gem\"\n  raw_title: \"RubyConf 2021 - How to Make a Gem of a Gem by Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Want to know how to create and publish a Ruby gem? It only takes 15 minutes to learn, and this talk will show you how.\n\n    But when should you create a new gem? And how will the type of gem you make (e.g. an API wrapper, a testing DSL, or a CLI) impact its design, testing, and long-term maintenance?\n\n    Answering those questions is… harder. That's why the remaining 15 minutes of this talk will compress a decade of design missteps, dependency regrets, and versioning nightmares into actionable advice to help ensure that your next gem is a great one.\n\n  video_provider: \"youtube\"\n  video_id: \"tKzu-3m0ZZY\"\n\n- id: \"joel-hawksley-rubyconf-2021\"\n  title: \"How GitHub uses linters\"\n  raw_title: \"RubyConf 2021 - How GitHub uses linters by Joel Hawksley\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    The GitHub code base is growing at over 25% every year through contributions from over 1000 engineers, clocking in at 1.7+ million lines of Ruby. In this talk, we'll share how we use linters to keep our codebase healthy by ensuring best practices are applied consistently, feedback loops are as short as possible, and code reviews bring the most value, all without creating too much friction.\n\n  video_provider: \"youtube\"\n  video_id: \"cY2-KGOvBD0\"\n\n- id: \"mike-dalessio-rubyconf-2021\"\n  title: \"Building Native Extensions. This Could Take A While...\"\n  raw_title: \"RubyConf 2021 - Building Native Extensions. This Could Take A While... by Mike Dalessio\"\n  speakers:\n    - Mike Dalessio\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    \"Native gems\" contain pre-compiled libraries for a specific machine architecture, removing the need to compile the C extension or to install other system dependencies. This leads to a much faster and more reliable installation experience for programmers.\n\n    This talk will provide a deep look at the techniques and toolchain used to ship native versions of Nokogiri (a commonly-used rubygem), and will discuss why human trust is an important requirement. Gem maintainers will learn how to build native versions of their own gems, and developers will learn how to use and deploy pre-compiled packages\n\n  video_provider: \"youtube\"\n  video_id: \"jtpOci5o50g\"\n\n- id: \"jason-meller-rubyconf-2021\"\n  title: \"Dishonest Software: Fighting Back Against the Industry Norms\"\n  raw_title: \"RubyConf 2021 - Dishonest Software: Fighting Back Against the Industry Norms by Jason Meller\"\n  speakers:\n    - Jason Meller\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    From daemons that conceal themselves, to apps which lie to us, every day you're impacted by software with dishonest intentions.\n\n    No one starts their career building dishonest tools, but over time, the norms & incentives in specific industries (ex: infosec, advertising) can compromise the ethics of even the most principled developer.\n\n    In this talk we will...\n\n    Define dishonest software using examples & counter-examples\n    Arm you with compelling arguments to convince product leadership to build ethical software\n    Explore how engineers can advocate for the data privacy rights of others\n\n  video_provider: \"youtube\"\n  video_id: \"-svFoj2beT8\"\n\n- id: \"emily-harber-rubyconf-2021\"\n  title: \"Problem Solving Through Pair Programming\"\n  raw_title: \"RubyConf 2021 - Problem Solving Through Pair Programming by Emily Harber\"\n  speakers:\n    - Emily Harber\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Pair programming is your best tool for getting new team members up to speed and writing high quality code, so your team can move faster and build for the long term.\n\n    In this talk, I’ll give you the How and Why of pair programming with your mentee, as well as practical actionable advice to have more productive, educational, and even fun pairing sessions. You’ll come away from this talk excited for your next pairing session, where you’ll write better quality code with a longer shelf life, and give your mentee programming superpowers they couldn’t achieve on their own.\n\n  video_provider: \"youtube\"\n  video_id: \"YXsbz_9itFU\"\n\n- id: \"hilary-stohs-krause-rubyconf-2021\"\n  title: \"Why we worry about all the wrong things\"\n  raw_title: \"RubyConf 2021 - Why we worry about all the wrong things by Hilary Stohs Krause\"\n  speakers:\n    - Hilary Stohs-Krause\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Modern humans aren’t great at risk assessment.\n\n    We often blithely ignore that which could harm us, and are conversely intimidated by things that are quite safe. This inability to recognize threat has vast implications for many aspects of our lives, including our careers.\n\n    In this talk, we’ll explore root causes of fear and anxiety, and discover how we can start to deliberately rewrite our “instincts”. This will allow us to redirect our worry toward what actually matters, and channel it into productive outcomes that make us safer, happier and less stressed, both at work and in our personal lives.\n\n  video_provider: \"youtube\"\n  video_id: \"qTnSZVYCxok\"\n\n- id: \"jameson-hampton-rubyconf-2021\"\n  title: \"Reframing Shame & Embracing Mistakes\"\n  raw_title: \"RubyConf 2021 - Reframing Shame & Embracing Mistakes by Jameson Hampton\"\n  speakers:\n    - Jameson Hampton\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Imposter syndrome is rampant among tech workers and there are so many ways that we put ourselves down and minimize our own accomplishments without even realizing it - and shame is a powerful and dangerous emotion. But everyone makes mistakes and in fact, making mistakes and learning from them makes us smarter! The tenets of cognitive behavioral therapy suggest that these kinds of harmful thought patterns are automatic, ingrained in us from years of practice. This talk will help you identify some of those thought patterns so you can challenge them and reframe them in healthier ways!\n\n  video_provider: \"youtube\"\n  video_id: \"3_BFqbZVlpE\"\n\n- id: \"katya-dreyer-oren-rubyconf-2021\"\n  title: \"Contractualism + Software Engineering: We're All In This Together\"\n  raw_title: \"RubyConf 2021 - Contractualism + Software Engineering: We're All In This... by Katya Dreyer Oren\"\n  speakers:\n    - Katya Dreyer Oren\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Contractualism + Software Engineering: We're All In This Together by Katya Dreyer Oren\n\n    As engineers, we are constantly confronted with decisions, from the tiny – “how thick should this border box be?” – to the huge – “how will this algorithm affect the world?” How do we make those decisions? Come learn about contractualism, or how to treat your users as a part of a larger community. We’ll discuss the concept of the “user stack,” anyone who will use or be influenced by your work. Understanding the principles of contractualism and how to apply them makes it easier for you to make ethical decisions as a software engineer, and convince others at your organization to listen.\n\n  video_provider: \"youtube\"\n  video_id: \"2jkw-YW-SMs\"\n\n- id: \"yechiel-kalmenson-rubyconf-2021\"\n  title: \"The Algorithm Ate My Homework\"\n  raw_title: \"RubyConf 2021 - The Algorithm Ate My Homework by Yechiel Kalmenson\"\n  speakers:\n    - Yechiel Kalmenson\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Am I My Algorithm's Keeper?\n\n    If I write an AI that then goes on to make unethical decisions, who's responsibility is it?\n\n    In this Talmudic-styled discussion, we will delve into ancient case laws to try and find legal and ethical parallels to modern-day questions.\n\n    We may not leave with all the answers, but hopefully, we will spark a conversation about the questions we should be asking.\n\n  video_provider: \"youtube\"\n  video_id: \"I3ggfUMgjsI\"\n\n- id: \"omar-rubyconf-2021\"\n  title: \"Squashing Security Bugs with Rubocop\"\n  raw_title: \"RubyConf 2021 - Squashing Security Bugs with Rubocop by Omar\"\n  speakers:\n    - Omar\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    You spot a subtle security bug during a code review and flag it, making sure it's fixed before it gets deployed. Taking this one step further you want to make sure others don't make same mistake. Short of reviewing every piece of code, what can you do?\n\n    That's where Rubocop comes in. You can save time in code reviews by using it to enforce coding patterns and styles. As a security-minded engineer you might ask: could we use it to find security bugs? Turns out you can!\n\n    This talk will cover how Betterment uses Rubocop to detect vulnerabilities and the thought process that went into this work.\n\n  video_provider: \"youtube\"\n  video_id: \"75TtHyn5uLQ\"\n\n- id: \"ufuk-kayserilioglu-rubyconf-2021\"\n  title: \"Gradual Typing in Ruby - A Three Year Retrospective\"\n  raw_title: \"RubyConf 2021 - Gradual Typing in Ruby - A Three Year... by Ufuk Kayserilioglu, Alexandre Terrasa\"\n  speakers:\n    - Ufuk Kayserilioglu\n    - Alexandre Terrasa\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    We began adopting gradual typing on Shopify's giant monolith almost 3 years ago. Today, we are running the monolith with great type coverage and even see some internal teams commit to stricter typing in their components.\n\n    The road to get here was not easy, though. We had to work with our developers to solve the right problems at the right levels of abstraction to ensure the adoption was healthy. This talk will go over some of the challenges and some of our wins along the way. It will also help you decide if gradual typing might work for your codebase and your team, as well.\n\n  video_provider: \"youtube\"\n  video_id: \"ntXKTEaWjPM\"\n\n- id: \"stephen-margheim-rubyconf-2021\"\n  title: \"Acidic Jobs: A Layman's Guide to Job Bliss\"\n  raw_title: \"RubyConf 2021 - Acidic Jobs: A Layman's Guide to Job Bliss by Stephen Margheim\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  slides_url: \"https://speakerdeck.com/fractaledmind/acidic-jobs-a-laymans-guide-to-job-bliss-091517d6-eec0-419e-a80f-982b8e036392\"\n  description: |-\n    Background jobs have become an essential component of any Ruby infrastructure, and, as the Sidekiq Best Practices remind us, it is essential that jobs be \"idempotent and transactional.\" But how do we make our jobs idempotent and transactional? In this talk, we will explore various techniques to make our jobs robust and ACIDic.\n\n  video_provider: \"youtube\"\n  video_id: \"l7hIYegfOKk\"\n\n- id: \"nick-barone-rubyconf-2021\"\n  title: \"Joyful Polyglot: Beautiful insights from many languages\"\n  raw_title: \"RubyConf 2021 - Joyful Polyglot: Beautiful insights from many languages by Nick Barone\"\n  speakers:\n    - Nick Barone\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Every language teaches you something beautiful, leading new and experienced programmers alike to novel and joyful ways to think about code. Would you benefit from a broader bag of programming concepts, or are you just curious about what can be learned when venturing outside your current box? From C++'s template metaprogramming to Scala's companion objects and more, this talk will explore a multitude of different programming languages and how the ideas and principles exemplified by each can be used by any other - but specifically, Ruby.\n\n  video_provider: \"youtube\"\n  video_id: \"dXCvQCOZs78\"\n\n- id: \"shashank-dat-rubyconf-2021\"\n  title: \"Drones Galore: controlling multiple drones using mruby/ruby\"\n  raw_title: \"RubyConf 2021 - Drones Galore: controlling multiple drones using mruby/ruby by Shashank Daté\"\n  speakers:\n    - Shashank Daté\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    mruby is a lightweight implementation of the Ruby language. This talk focuses on how mruby differs from ruby, how its build system works, how to optimize its configuration for controlling a certain category (Tello) of programmable drones. It will include - flight control using UDP sockets in mruby - multiple drone control using Fibers in murby - multiple drone control using using Ruby Actors The talk will end with a demo of multi-drone acrobatics.\n\n  video_provider: \"youtube\"\n  video_id: \"BxXwoBp9gT8\"\n\n- id: \"kota-weaver-rubyconf-2021\"\n  title: \"Mixed Reality Robotics Simulation with Ruby\"\n  raw_title: \"RubyConf 2021 - Mixed Reality Robotics Simulation with Ruby by Kota Weaver\"\n  speakers:\n    - Kota Weaver\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Simulation for robots is useful. But how do robots translate to real life factory environments? Find out with a mixed-reality simulation featuring real robots, lots of projectors, and of course, Ruby!\n\n    We use the excellent DragonRuby Game Toolkit to develop-mixed reality robotics simulations to: - enhance robot development - provide unique testing methods using real world robots - showcase robot behavior in digital-twins of our customer sites in our testing lab - take a break and build fun interactive experiences\n\n    Join us in an exploration of this dynamic and interactive robot exploration lab!\n\n  video_provider: \"youtube\"\n  video_id: \"axQzs1moNUQ\"\n\n- id: \"jemma-issroff-rubyconf-2021\"\n  title: \"Achieving Fast Method Metaprogramming: Lessons from MemoWise\"\n  raw_title: \"RubyConf 2021 - Achieving Fast Method Metaprogramming: Lessons from.. by Jemma Issroff, Jacob Evelyn\"\n  speakers:\n    - Jemma Issroff\n    - Jacob Evelyn\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Are dynamically generated methods always slow? In this talk, we’ll recount our journey developing MemoWise, Ruby’s most performant memoization gem. It’s a tale of benchmark-driven development, unexpected object allocations, and learning to love eval. We’ll cover common performance problems in Ruby metaprogramming and the arcane techniques we used to overcome them.\n\n  video_provider: \"youtube\"\n  video_id: \"uV3LqxFBSII\"\n\n- id: \"maxime-chevalier-boisvert-rubyconf-2021\"\n  title: \"YJIT - Building a new JIT Compiler inside CRuby\"\n  raw_title: \"RubyConf 2021 - YJIT - Building a new JIT Compiler inside CRuby by Maxime Chevalier Boisvert\"\n  speakers:\n    - Maxime Chevalier-Boisvert\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    TruffleRuby together with Truffle Regex can now execute Ruby Regexps up to 40 times faster than CRuby! This is possible by just-in-time compiling Ruby Regexps to machine code by using Truffle Regex, a Truffle language for regular expressions. Truffle Regex uses finite-state machines, a much faster alternative to backtracking regexp engines. Because of the unique capability of GraalVM to inline across languages, the Ruby code and the Regexp are optimized and compiled together for ultimate performance.\n\n  video_provider: \"youtube\"\n  video_id: \"fqxkjb7wPy4\"\n\n- id: \"jake-zimmerman-rubyconf-2021\"\n  title: \"Compiling Ruby to Native Code with Sorbet & LLVM\"\n  raw_title: \"RubyConf 2021 - Compiling Ruby to Native Code with Sorbet & LLVM by Jake Zimmerman & Trevor Elliott\"\n  speakers:\n    - Jake Zimmerman\n    - Trevor Elliott\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    At Stripe, “make it faster!” is one of our most requested features, but we don’t want to have to pause work on other features to get speed. Instead, we’ve built an ahead-of-time compiler for Ruby, powered by Sorbet and LLVM, focusing on improving latency in Stripe’s multi-million line Ruby code base.\n\n    In this talk, we’ll cover why we built it, how it works, and share preliminary results from compiling Stripe’s production Ruby code. It’s not quite ready for prime time yet, but we’re interested in sharing our approach and getting early feedback on the design.\n\n  video_provider: \"youtube\"\n  video_id: \"mCVwbrsWOlE\"\n\n- id: \"eileen-m-uchitelle-rubyconf-2021\"\n  title: \"Improving CVAR performance in Ruby 3.1\"\n  raw_title: \"RubyConf 2021 - Improving CVAR performance in Ruby 3.1 by Eileen Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  slides_url: \"https://speakerdeck.com/eileencodes/improving-cvar-performance-in-ruby-3-dot-1\"\n  description: |-\n    Have you ever wondered how class variables (CVARs) in Ruby work? Would you be surprised to learn that their performance becomes increasingly worse as the inheritance chain grows? I’m excited to share that in Ruby 3.1 we fixed the performance of CVARs.\n\n    In this talk we'll look at the language design of class variables, learn about how they work, and, deep dive into how we improved their performance in Ruby 3.1 by adding a cache! We'll look at the cache design and real-world benchmarks showing how much faster they are regardless of the size of the inheritance chain.\n\n  video_provider: \"youtube\"\n  video_id: \"Y3tSf8FwHUw\"\n\n- id: \"jeremy-evans-rubyconf-2021\"\n  title: \"Optimizing Partial Backtraces in Ruby 3\"\n  raw_title: \"RubyConf 2021 - Optimizing Partial Backtraces in Ruby 3 by Jeremy Evans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Backtraces are very useful tools when debugging problems in Ruby programs. Unfortunately, backtrace generation is expensive for deep callstacks. In older versions of Ruby, this is true even if you only want a partial backtrace, such as a single backtrace frame. Thankfully, Ruby 3 has been optimized so that it no longer processes unnecessary backtrace frames, which can greatly speed up the generation of partial backtraces. Join me for an interesting look a Ruby backtraces, how they are generated, how we optimized partial backtraces in Ruby 3, and how we fixed bugs in the optimization in 3.0.1.\n\n  video_provider: \"youtube\"\n  video_id: \"GSlQEtEjmHM\"\n\n- id: \"rahul-subramaniam-ey-rubyconf-2021\"\n  title: \"A message from Engineyard\"\n  raw_title: \"RubyConf 2021 - A message from Engineyard by Rahul Subramaniam EY\"\n  speakers:\n    - Rahul Subramaniam EY\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"F2RoYrMLJ48\"\n\n- id: \"jose-rosello-rubyconf-2021\"\n  title: \"Sorbet at Grailed: Typing a Large Rails Codebase to Ship with Confidence\"\n  raw_title: \"RubyConf 2021 - Sorbet at Grailed: Typing a Large Rails Codebase to Ship with... by Jose Rosello\"\n  speakers:\n    - Jose Rosello\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Called “downcase” on nil? Forgot to return the right object in one of your logic branches? Called “first” on a String instead of an Array and spent half an hour trying to figure out why a single character was getting passed around everywhere?\n\n    At Grailed, these situations were not uncommon. We are the largest marketplace for luxury men's fashion, with over 7 million users, and a growing Rails codebase that spans hundreds of thousands of lines. Before typing, changes to core interfaces often required creative grepping, modification of type checking unit tests, and updating brittle type documentation.\n\n    Ever since we started gradually typing our codebase with Sorbet, we’ve been able to make intrusive changes faster and confidently. In this talk, we’ll walk you through our prior art, challenges, learnings, and big benefits of typing our codebase.\n\n  video_provider: \"youtube\"\n  video_id: \"jYqRV0Kt2ZI\"\n\n- id: \"zaid-zawaideh-rubyconf-2021\"\n  title: \"Scaling Happy Engineering Teams\"\n  raw_title: \"RubyConf 2021 - Scaling Happy Engineering Teams by Zaid Zawaideh\"\n  speakers:\n    - Zaid Zawaideh\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Scaling engineering organizations doesn't have to mean chaos, stress or losing the ability to have impact. In this talk I'll explain the principles we are applying at Wrapbook for scaling our Engineering teams to provide a healthy, happy and productive environment for people to do their best work.\n\n  video_provider: \"youtube\"\n  video_id: \"o04lx5kv_7Y\"\n\n- id: \"jake-anderson-rubyconf-2021\"\n  title: \"Cultivating Developer-Centric DSLs\"\n  raw_title: \"RubyConf 2021 - Cultivating Developer-Centric DSLs by Jake Anderson\"\n  speakers:\n    - Jake Anderson\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Writing boilerplate code can be draining. Breaking things out into classes and modules doesn't always make this process more enjoyable either. At Weedmaps, we've developed a suite of Domain Specific Languages (DSLs) for the vast majority of our workflows. This includes things like query objects all the way to crawlers. Done right, these tools allow team members to accomplish more with less. Done wrong, team members would have been better off writing everything from scratch. This talk is meant for those who want to build better tooling around repetitive workflows. It's also for those that want to better understand how some of these tools work under the hood. Embrace the magic!\n\n  video_provider: \"youtube\"\n  video_id: \"8VvgEQdp5YQ\"\n\n- id: \"sarah-reid-rubyconf-2021\"\n  title: \"Rswag: Automated API Documentation\"\n  raw_title: \"RubyConf 2021 - Rswag: Automated API Documentation by Sarah Reid\"\n  speakers:\n    - Sarah Reid\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Do you struggle to write documentation for your REST API? Do you often forget to update the docs after changing an endpoint? Does your API feel like a black box to other engineers? Do your docs say one thing, but your API does another? This talk is for you! We’ll explore all of these problems and discover how Rswag can solve them for you.\n  video_provider: \"youtube\"\n  video_id: \"47PwEkVs2uc\"\n\n- id: \"benoit-daloze-rubyconf-2021\"\n  title: \"Just-in-Time Compiling Ruby Regexps on TruffleRuby\"\n  raw_title: \"RubyConf 2021 - Just-in-Time Compiling Ruby Regexps on TruffleRuby by Benoit Daloze and Josef Haider\"\n  speakers:\n    - Benoit Daloze\n    - Josef Haider\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    TruffleRuby together with Truffle Regex can now execute Ruby Regexps up to 40 times faster than CRuby! This is possible by just-in-time compiling Ruby Regexps to machine code by using Truffle Regex, a Truffle language for regular expressions. Truffle Regex uses finite-state machines, a much faster alternative to backtracking regexp engines. Because of the unique capability of GraalVM to inline across languages, the Ruby code and the Regexp are optimized and compiled together for ultimate performance.\n  video_provider: \"youtube\"\n  video_id: \"JuVklIz1gts\"\n\n- id: \"anthony-navarre-rubyconf-2021\"\n  title: \"Dismantling Dystopian Futures with Humane Factories\"\n  raw_title: \"RubyConf 2021 - Dismantling Dystopian Futures with Humane Factories by Anthony Navarre\"\n  speakers:\n    - Anthony Navarre\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    The terminal glowed a sickly pale green, reflecting in her lenses. “What do you mean, RecordInvalid?” she scoffed, and set to the task of debugging the factory. Hairs stood up on her neck as she realized the implications of her findings — she could practically smell the corrosion, but it was nobody’s fault. It was everyone’s fault. Data was long ago divorced from the human lives they were intended to improve. Dmitry bolted upright in a sweat. She was safe at home — it was all a dream, at least for now. There was still time. She started her morning routine, but breakfast was the last thing on her mind. She didn’t know all the factors, but she knew where to begin. Join me in this whimsical exploration of some not-so-whimsical tactics to put your test factories to work in some unconventional ways.\n\n  video_provider: \"youtube\"\n  video_id: \"aEEexQ7dESQ\"\n\n- id: \"laura-maguire-rubyconf-2021\"\n  title: \"Workshop: Fundamentals of Joint Cognitive Systems\"\n  raw_title: \"RubyConf 2021 - Workshop: Fundamentals of Joint Cognitive Systems by Laura Maguire, John Allspaw\"\n  speakers:\n    - Laura Maguire\n    - John Allspaw\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    If we take the wayback machine to the time before there was Resilience Engineering, we find Cognitive Systems Engineering. Central to CSE is the concept of Joint Cognitive Systems - human/machine teaming based on principles of shared cognitive efforts, not simply dividing the work to be done across humans and machines. This thought-provoking and interactive workshop will give you a whole new lens to think about your work and the problems you face working on and with highly automated systems using a combination of lecture, discussion and hands on exercises.\n\n  video_provider: \"youtube\"\n  video_id: \"4uWjAMqmxQw\"\n\n- id: \"alex-robinson-rubyconf-2021\"\n  title: \"Workshop: Intentional Team Building\"\n  raw_title: \"RubyConf 2021 - Workshop: Intentional Team Building by Alex Robinson, Will Mitchell\"\n  speakers:\n    - Alex Robinson\n    - Will Mitchell\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    How do you build effective teams? What are the determining factors? In this collaborative workshop we will explore how to identify the values underpinning your team dynamics and explore techniques to cultivate effective teams built around intentional values.\n\n  video_provider: \"youtube\"\n  video_id: \"yATlt3hYvDk\"\n\n- id: \"amir-rajan-rubyconf-2021\"\n  title: \"Soup to Nuts: Build a video game using Ruby!\"\n  raw_title: \"RubyConf 2021 - Soup to Nuts: Build a video game using Ruby! by Amir Rajan\"\n  speakers:\n    - Amir Rajan\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Have you ever dreamed of building a video game? Well here’s your chance of making that dream come true. During this workshop, we’ll build a 2D platformer like Super Mario Brothers, and A top down RPG like Legend of Zelda: A Link to the Past.\n\n    No previous game dev experience is required.\n    If you’re new to Ruby, that’s okay too. Building games is a fantastic way to learn a language.\n    You’ll be given a free, unrestricted commercial license of DragonRuby Game Toolkit (this is the game engine we’ll be using during the workshop).\n\n  video_provider: \"youtube\"\n  video_id: \"jVen5yzrNeY\"\n\n- id: \"thai-wood-rubyconf-2021\"\n  title: \"Workshop: Run your first game day\"\n  raw_title: \"RubyConf 2021 - Workshop: Run your first game day by Thai Wood\"\n  speakers:\n    - Thai Wood\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Want to get better and incident response without waiting for actual incidents? Learn how to use table top exercises to practice your incident response framework, develop common ground, and improve communication during an incident.\n\n    You'll learn how to run table top game days, including how to set them up, how to design scenarios and how to encourage participation, all with techniques supported by real word experience and supported by research.\n\n  video_provider: \"youtube\"\n  video_id: \"xqye3wo68uc\"\n\n- id: \"chelsea-troy-rubyconf-2021\"\n  title: \"RubyCond 2021 - Workshop: Tackling Technical Debt: An Analytical Approach\"\n  raw_title: \"RubyCond 2021 - Workshop: Tackling Technical Debt: An Analytical Approach by Chelsea Troy\"\n  speakers:\n    - Chelsea Troy\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Getting out of tech debt can feel like a Sisyphean task. After weeks of work, the success case is for the app to work the same as it used to. Organizations often declare code bankruptcy and rewrite working systems from scratch. How do we end up here? And how do we alleviate, or even better, prevent such a situation?\n\n    In this workshop, you will learn how to measure tech debt and address the areas of highest need first. You’ll learn to identify high leverage code changes and separate those from renovations. You’ll also learn about the skills tech teams can use to prevent and reduce tech debt.\n\n  video_provider: \"youtube\"\n  video_id: \"DwW7zlNulbQ\"\n\n- id: \"scott-moore-rubyconf-2021\"\n  title: \"All comments must be haiku! Custom linting with RuboCop\"\n  raw_title: \"RubyConf 2021 - All comments must be haiku! Custom linting with RuboCop by Scott Moore, Kari Silva\"\n  speakers:\n    - Scott Moore\n    - Kari Silva\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    RuboCop is great for keeping code quality high by enforcing community-driven Ruby standards in our codebases. But RuboCop can also be easily customized to enforce standards that are unique to our codebase, automatically checking for the things that are most important to us.\n\n    In this workshop we'll customize RuboCop to enforce our most important style rule: all comments must be in the form of a haiku! Along the way we'll learn:\n\n    the basics of linting and RuboCop itself\n    a little about abstract syntax trees\n    how to build powerful custom tooling to enforce almost any standard we can think of!\n\n  video_provider: \"youtube\"\n  video_id: \"z9SwpkYa_Gc\"\n\n- id: \"jesse-spevack-rubyconf-2021\"\n  title: \"Clean RSpec: A Workshop on Ruby Testing Craftsmanship\"\n  raw_title: \"RubyConf 2021 - Clean RSpec: A Workshop on Ruby Testing Craftsmanship by Jesse Spevack\"\n  speakers:\n    - Jesse Spevack\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Testing has been a feature of the Ruby community for a long time. Why then are our spec files often so incomprehensible? In this workshop, I will share some ground rules for writing maintainable tests that will ensure that new teammates along with future-you can understand your test suite. We will use the RSpec testing framework to introduce several testing code-smells. For each smell, I will provide a demonstration on how to refactor the test along with time to practice for workshop participants. This workshop is geared towards anyone looking to hone their Ruby testing craft.\n\n  video_provider: \"youtube\"\n  video_id: \"e4HORZgt8-U\"\n\n- id: \"jade-dickinson-rubyconf-2021\"\n  title: \"Workshop: How to use flamegraphs to find performance problems\"\n  raw_title: \"RubyConf 2021 - Workshop: How to use flamegraphs to find performance problems by Jade Dickinson\"\n  speakers:\n    - Jade Dickinson\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Slow Ruby code can be a puzzle, but it doesn’t have to be that way. In this workshop you will see how fun it can be to use flamegraphs to find performance problems. You’ll get the most out of this session if you know you have slow areas in your Ruby application, and would like to learn how to find the code responsible.\n\n  video_provider: \"youtube\"\n  video_id: \"ALkoG4xNgD0\"\n\n- id: \"jason-swett-rubyconf-2021\"\n  title: \"Workshop: A Gentle Introduction to Docker for Rubyists\"\n  raw_title: \"RubyConf 2021 - Workshop: A Gentle Introduction to Docker for Rubyists by Jason Swett\"\n  speakers:\n    - Jason Swett\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Have you heard about how great Docker supposedly is, but you're not sure exactly what all the fuss is about, or even what Docker is or why people use it? Or maybe you understand what Docker is but you've never worked with it before. In this workshop, you'll learn exactly what Docker is and why you'd want to use it, and you'll come away with your own fully Dockerized Ruby application.\n\n  video_provider: \"youtube\"\n  video_id: \"9hVNjr_iHko\"\n\n- id: \"cory-watson-rubyconf-2021\"\n  title: \"Surprise! Inspiring Resilience\"\n  raw_title: \"RubyConf 2021 - Surprise! Inspiring Resilience by Cory Watson\"\n  speakers:\n    - Cory Watson\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Resilience is the ability to function in the face of damage or failure. This is a desirable trait in all of our work, but can be rather difficult to achieve. Let's look outside of our own practices to find inspiration for our own work!\n\n    In this talk we'll bring examples from outside tech. We’re talking aircraft carriers, race cars, priceless works of art, and hard-fought wisdom from across the accomplishments of humans and even nature itself. Join me in marveling at they ways things keep working, and we’ll get some cool ideas for how to create resilience in your organization or systems.\n  video_provider: \"youtube\"\n  video_id: \"0Fr8Kpe8Ro4\"\n\n- id: \"hitoshi-hasumi-rubyconf-2021\"\n  title: \"Picoruby and PRK Firmware\"\n  raw_title: \"RubyConf 2021 - Picoruby and PRK Firmware by Hitoshi Hasumi\"\n  speakers:\n    - Hitoshi Hasumi\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    PicoRuby is an alternative implementation of the mruby interpreter which runs on one-chip microcontrollers.\n\n    PRK Firmware is the world's first keyboard firmware framework in Ruby. You can write not only your own \"keymap\" in PicoRuby but also configure additional behavior with Ruby's features such as the open class system and the Proc object.\n\n    The ultimate goal is certainly not a small one --- let's make Ruby comparable to projects such as MicroPython, CircuitPython or Lua in terms of viability as a scripting language on Board!\n  video_provider: \"youtube\"\n  video_id: \"ZfIz34PK4zs\"\n\n- id: \"john-gallagher-rubyconf-2021\"\n  title: \"Using Monads for Elegant Error Handling\"\n  raw_title: \"RubyConf 2021 - Using Monads for Elegant Error Handling by John Gallagher\"\n  speakers:\n    - John Gallagher\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Your app blows up in production. It's an outage and you're under pressure. You read the code. \"How does this work? Why is this exception being caught here?\" And so begins a long, stressful journey to understand how to fix your code.\n\n    Rescuing exceptions is normalised in Ruby, but it's a clumsy way of reacting to error conditions and causes your code to be difficult to reason about.\n\n    You'll refactor an existing app to use a functional style and see first hand how easy monads are to use and how they can make your code incredibly clean and expressive.\n  video_provider: \"youtube\"\n  video_id: \"Nkg8tKOZccU\"\n\n- id: \"leon-hu-rubyconf-2021\"\n  title: \"Why Did We Rewrite Our Main Product Four Times?\"\n  raw_title: \"RubyConf 2021 - Why Did We Rewrite Our Main Product Four Times? by Leon Hu\"\n  speakers:\n    - Leon Hu\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    \"Hi, this is a friendly reminder you have an appt on 12/07, Thursday 2pm\". How hard can building and scaling an Appointment Reminder system be? An average developer can build such proof of concept in under a day. But to scale it to sending to millions of patients a week, nobody in our team thought it'd take us to rewrite it the 4th time. From dealing performance pain and ever increasing complexity, we poured in countless hours to come up with the perfect design. We have a thing or two to share about solving a seemingly trivial problem.\n  video_provider: \"youtube\"\n  video_id: \"w8q_Uymv-bM\"\n\n- id: \"lisa-karlin-curtis-rubyconf-2021\"\n  title: \"How to stop breaking other people's things\"\n  raw_title: \"RubyConf 2021 - How to stop breaking other people's things by Lisa Karlin Curtis\"\n  speakers:\n    - Lisa Karlin Curtis\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Breaking changes are sad. We’ve all been there; someone else changes their API in a way you weren’t expecting, and now you have a live-ops incident you need to fix urgently to get your software working again. Of course, many of us are on the other side too: we build APIs that other people’s software relies on.\n\n    This talk will cover how you can: (a) Get really good at identifying what changes might break someone’s integration (b) Help your API consumers to build integrations that are resilient to these kinds of changes (c) Release potentially breaking changes as safely as possible\n  video_provider: \"youtube\"\n  video_id: \"rmixCWytaJ8\"\n\n- id: \"marc-busqu-rubyconf-2021\"\n  title: \"Harness the power of functions to build composable rack applications\"\n  raw_title: \"RubyConf 2021 - Harness the power of functions to build composable rack applications by Marc Busqué\"\n  speakers:\n    - Marc Busqué\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    hat's a function? A function is a black box that takes an input and returns an output. Similarly, from the outside, HTTP requests take some request data to give it back as a response. Functions may compose if the output of one matches the input of the next one. web_pipe helps you build rack applications by plugging small process units that progressively create a response from a given request.\n  video_provider: \"youtube\"\n  video_id: \"Tv6_RAM4S6k\"\n\n- id: \"maria-moore-rubyconf-2021\"\n  title: \"Engineering at Root\"\n  raw_title: \"RubyConf 2021 - Engineering at Root by Maria Moore\"\n  speakers:\n    - Maria Moore\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Root is a car insurance company founded on the belief that good drivers should pay less for insurance since they’re less likely to get into accidents. Some drivers are paying significantly more than they should for car insurance because most carriers base rates primarily on demographics, not driving. We’re fixing that.\n\n    Root is reinventing the broken insurance industry by using technology in smartphones to measure driving behavior. The Root app measures things like smooth braking and turning to determine who is a safe driver and who isn’t. By only insuring good drivers, we can offer more affordable rates. And the software the engineering team built from scratch powers it all.\n\n    Maria will share more about how we built an insurance company from scratch and how our Engineering teams continue to unbreak the insurance industry every day.\n  video_provider: \"youtube\"\n  video_id: \"O15ifnV0UiI\"\n\n- id: \"okura-masafumi-rubyconf-2021\"\n  title: \"Control methods like a pro: A guide to Ruby's awesomeness, a.k.a metaprogramming\"\n  raw_title: \"RubyConf 2021 - Control methods like a pro: A guide to Ruby's awesomeness,... by Masafumi Okura\"\n  speakers:\n    - OKURA Masafumi\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Control methods like a pro: A guide to Ruby's awesomeness, a.k.a. metaprogramming by Masafumi Okura\n\n    Do you know that methods are objects in Ruby? We can manipulate method objects just like other object, meaning that we can store them in variables, get information from them and wrap them in other objects like Proc. In this talk, I'll show a real-world example of manipulating methods. I'll cover from the basic such as listing available methods and getting a method object to the difference between Method and UnboundMethod and redefining methods with original method object.\n  video_provider: \"youtube\"\n  video_id: \"fJsoWMFypxU\"\n\n- id: \"mercedes-bernard-rubyconf-2021\"\n  title: \"Minimize Your Circus Factor: Building resilient teams\"\n  raw_title: \"RubyConf 2021 - Minimize Your Circus Factor: Building resilient teams by Mercedes Bernard\"\n  speakers:\n    - Mercedes Bernard\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    If you or someone on your team ran away to join the circus, how stressful would it be for the rest of the team? How can we minimize that?\n\n    After a year+ in a pandemic, many are considering taking new roles or extended PTO. It's more important than ever to invest in minimizing our \"circus factor\" and building resilient teams so that everyone can unplug and do what's best for them with as little stress as possible. In this talk, we'll discuss low-friction changes you can make today so that if you join the circus tomorrow your team is empowered and enabled for continued success.\n  video_provider: \"youtube\"\n  video_id: \"jBMSWBND0WU\"\n\n- id: \"mina-slater-rubyconf-2021\"\n  title: \"Managing Out: Strategies for Leveling Up\"\n  raw_title: \"RubyConf 2021 - Managing Out: Strategies for Leveling Up by Mina Slater\"\n  speakers:\n    - Mina Slater\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    \"Mid-level Engineers\". Who are we? We have enough experience to understand the domain of a project and the technical know-how to provide guidance to earlier-career teammates. But how do we continue to grow and reach the next level of team leadership? Let's explore some of the initiatives we can take as mid-level engineers to level up our leadership skills, while contributing to the mentorship of newer engineers. You'll walk away with strategies to do so internal to the engineering team, across disciplines of Design and Product and externally with stakeholders and/or product owners.\n  video_provider: \"youtube\"\n  video_id: \"fKbO0RRdx6w\"\n\n- id: \"nat-budin-rubyconf-2021\"\n  title: \"Hello, computer. Writing Ruby with voice recognition\"\n  raw_title: \"RubyConf 2021 - Hello, computer. Writing Ruby with voice recognition by Nat Budin\"\n  speakers:\n    - Nat Budin\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Repetitive stress injuries are scary for tech workers. If I can’t type, is my career over?\n\n    When my finger was injured last year, I had a long recovery period, and during that time, I learned to code using voice recognition software. In this talk, I’ll tell the whole story and demo the tool I learned.\n  video_provider: \"youtube\"\n  video_id: \"g-xnh8mszQU\"\n\n- id: \"peter-zhu-rubyconf-2021\"\n  title: \"Optimizing Ruby's Memory Layout\"\n  raw_title: \"RubyConf 2021 - Optimizing Ruby's Memory Layout by Peter Zhu & Matt Valentine-House\"\n  speakers:\n    - Peter Zhu\n    - Matt Valentine-House\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Ruby’s current memory model assumes all objects live in fixed size slots. This means that object data is often stored outside of the Ruby heap, which has implications: an object's data can be scattered across many locations, increasing complexity and causing poor locality resulting in reduced efficiency of CPU caches.\n\n    Join us as we explore how our Variable Width Allocation project will move system heap memory into Ruby heap memory, reducing system heap allocations and giving us finer control of the memory layout to optimize for performance.\n  video_provider: \"youtube\"\n  video_id: \"3c7ijPD6Jlk\"\n\n- id: \"richard-schneeman-rubyconf-2021\"\n  title: \"Beware the Dreaded Dead End!!\"\n  raw_title: \"RubyConf 2021 - Beware the Dreaded Dead End!! by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Nothing stops a program from executing quite as fast as a syntax error. After years of “unexpected end” in my dev life, I decided to “do” something about it. In this talk we'll cover lexing, parsing, and indentation informed syntax tree search that power that dead_end Ruby library.\n  video_provider: \"youtube\"\n  video_id: \"7CTn2m1ME5A\"\n\n- id: \"rolen-le-rubyconf-2021\"\n  title: \"Dungeons and Collaboration\"\n  raw_title: \"RubyConf 2021 - Dungeons and Collaboration by Rolen Le\"\n  speakers:\n    - Rolen Le\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    What can fighting goblins teach us about working together? How can going on a perilous journey guide us through our careers? What if I told you I sit in a 4-hour meeting online every Friday night for fun?\n\n    Having played Dungeons and Dragons for almost a decade and playing remotely for half that time, I have learned lessons that have taught me how to interact as a developer on a distributed team. From general online etiquette to building great teams, I will discuss tips and tricks of roleplaying that can make someone a better coworker.\n  video_provider: \"youtube\"\n  video_id: \"9-7OCakUEIw\"\n\n- id: \"stefanni-brasil-rubyconf-2021\"\n  title: \"Perceptual Learning == More Ruby Experts?\"\n  raw_title: \"RubyConf 2021 - Perceptual Learning == More Ruby Experts? by Stefanni Brasil\"\n  speakers:\n    - Stefanni Brasil\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    ow do you become an expert? Why some Ruby developers can't explain what they know? Why some developers don't develop expert skills? What does it mean to be a Ruby expert?\n\n    To discuss these questions, we'll explore Perceptual Learning (PL) research. PL is a natural learning process that complements traditional Education. It accelerates expertise by speeding pattern recognition, intuition and fluency on a given subject.\n\n    In this talk, we'll learn how to create expertise based on PL's techniques, and how you can apply them to become an expert Ruby developer.\n  video_provider: \"youtube\"\n  video_id: \"5lJDjciN-us\"\n\n- id: \"stephanie-minn-rubyconf-2021\"\n  title: \"The Intro to Abstraction I Wish I'd Received\"\n  raw_title: \"RubyConf 2021 - The Intro to Abstraction I Wish I'd Received by Stephanie Minn\"\n  speakers:\n    - Stephanie Minn\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    So much talk about good software revolves around finding the “right abstraction”. Even programming itself is an act of abstracting the world into some form of bits and bytes. If, like me, you missed out on a proper introduction to such a fundamental concept, this talk will teach you what abstraction is and why it’s important to software development.\n\n    We’ll also dig into a real-world example of fighting a troublesome abstraction and learn strategies for identifying when one no longer works for you—the first step toward imagining new abstractions for your code to take shape.\n  video_provider: \"youtube\"\n  video_id: \"m0dC5RmxcFk\"\n\n- id: \"takashi-kokubun-rubyconf-2021\"\n  title: \"Optimizing Production Performance with MRI JIT\"\n  raw_title: \"RubyConf 2021 - Optimizing Production Performance with MRI JIT by Takashi Kokubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Since we introduced a JIT compiler to Ruby in 2.6, it had been known to slow down production applications like Rails. This year, we finally figured out why it was the case and found a way to fix it. Now we can even see the JIT compiler of Ruby 3.0 optimizes one of the most popular Rails applications.\n\n    In this talk, you'll learn some tricks to make sure it happens on your production application. Get the easy speedup of your application for free!\n  video_provider: \"youtube\"\n  video_id: \"MpHczwoVNSU\"\n\n- id: \"vinicius-stock-rubyconf-2021\"\n  title: \"Parallel testing with Ractors - Putting CPU's to work\"\n  raw_title: \"RubyConf 2021 - Parallel testing with Ractors - Putting CPU's to work by Vinicius Stock\"\n  speakers:\n    - Vinicius Stock\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Parallelizing tests is an opportune way of reducing the total runtime for a test suite. Rails achieves this by forking multiple separate workers that fetch tests from a queue. In Ruby 3, Ractors introduced new mechanisms for executing code in parallel. Can they be leveraged by a test framework? And how would that compare to current parallelization solutions?\n\n    Let’s find the answers to these questions by building a test framework built on Ractors, from scratch. We’ll compare the current solutions for parallelization and what advantages or limitations Ractors bring when used in this context.\n  video_provider: \"youtube\"\n  video_id: \"rdwvvDMmsAQ\"\n\n- id: \"amy-newell-rubyconf-2021\"\n  title: \"Debugging Product Teams\"\n  raw_title: \"RubyConf 2021 - Debugging Product Teams by Amy Newell\"\n  speakers:\n    - Amy Newell\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Everyone knows that to build great software you need great teams. Experts are quick to offer principles and processes that are “the key” to greatness.\n\n    But what if your team’s not “great”? It’s not “getting things done”. People don’t trust each other. There’s a lot of conflict. Low morale. Something is wrong.\n\n    Now what?\n\n    “Debugging” a team is a lot like caring for a complex distributed software system: it’s less about fixes, and more about observation, hypotheses, intervention, and more observation. Whatever your role, these are skills you can learn and apply right now, on your own teams.\n  video_provider: \"youtube\"\n  video_id: \"CoaYjkVRhiE\"\n\n- id: \"andromeda-yelton-rubyconf-2021\"\n  title: \"This is not a talk about airplane crashes\"\n  raw_title: \"RubyConf 2021 - This is not a talk about airplane crashes by Andromeda Yelton\"\n  speakers:\n    - Andromeda Yelton\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Are you:\n\n    an embodied, thinking, feeling human\n    who works together with other humans\n    in a context of technical systems\n    and wants that to go well?\n    If so, let's talk about aviation: a field that's become exceptionally safe by obsessively investigating accidents and sharing lessons learned. In addition to being fascinating engineering detective stories, these retrospectives yield recommendations that are useful for anyone who said \"yes\" to the above questions. I'll tell you stories of key accidents in aviation history and what we can learn from them.\n\n    (CW: injury, death.)\n  video_provider: \"youtube\"\n  video_id: \"9Z58SSn6ZXo\"\n\n- id: \"bruno-sutic-rubyconf-2021\"\n  title: \"Async Ruby\"\n  raw_title: \"RubyConf 2021 - Async Ruby by Bruno Sutic\"\n  speakers:\n    - Bruno Sutic\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Async Ruby is an exciting and innovating part of Ruby. It's a new approach to concurrency best described as \"threads with NONE of the downsides\". Async Ruby has mind-blowing capabilities, and is so good Matz invited the gem to the standard library. Despite the upsides, and strong support from the Ruby core team, Async gem has stayed relatively off of Ruby mainstream.\n\n    This talk is suitable for both beginners and experts, and is relevant for you if you're making web requests in ruby. It will introduce you to some the most impressive async features and explain its core concepts.\n  video_provider: \"youtube\"\n  video_id: \"LvfQTFNgYbI\"\n\n- id: \"chris-seaton-rubyconf-2021\"\n  title: \"A History of Compiling Ruby\"\n  raw_title: \"RubyConf 2021 - A History of Compiling Ruby by Chris Seaton\"\n  speakers:\n    - Chris Seaton\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Did you know that there have been at least sixteen attempts to build a compiler from Ruby to machine code? Why have there been so many? What were the ideas and context of each of these compilers? How are they similar and how are they different? What can we learn about compilers and Ruby from looking at them all? It turns out that we can trace the major advances in compiler research from the last couple of decades through Ruby!\n  video_provider: \"youtube\"\n  video_id: \"Idy9fryWGS8\"\n\n- id: \"ely-alvarado-rubyconf-2021\"\n  title: \"Golf Scripting with Ruby - Helping Santa Schedule Christmas\"\n  raw_title: \"RubyConf 2021 - Golf Scripting with Ruby - Helping Santa Schedule Christmas by Ely Alvarado\"\n  speakers:\n    - Ely Alvarado\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Code Golf is a fun form of programming competition where the aim is to produce the shortest source code that implements an algorithm. In this talk we will show how we tackle a complex problem: helping Santa schedule the work of his elves Army to deliver presents on Christmas Day. We will go step by step on how to find an algorithm to solve it and how to use Ruby’s language features to make it as short as possible. You’ll learn a few secret shortcuts built into Ruby that you probably don’t know about.\n  video_provider: \"youtube\"\n  video_id: \"d4QwyojCbX0\"\n\n- id: \"julia-ferraioli-rubyconf-2021\"\n  title: \"Black Swan Events in Open Source: That time we broke the internet\"\n  raw_title: \"RubyConf 2021 - Black Swan Events in Open Source: That time... by Julia Ferraioli and Amanda Casari\"\n  speakers:\n    - Julia Ferraioli\n    - Amanda Casari\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    A black swan event refers “to unexpected events of large magnitude and consequence which then play a dominant role in history\". With open source ecosystems increasing in complexity and growth as sociotechnical systems, we must examine how often these events are happening and if they are truly unexpected.\n\n    This talk will explore a series of events in open source history, some of which came as a surprise to users of the open source project and industry as a whole, had a wide and long-lasting impact on technology, or was inappropriately rationalized after the fact with the benefit of hindsight.\n  video_provider: \"youtube\"\n  video_id: \"bF4i7t7hpI4\"\n\n- id: \"koichi-sasada-rubyconf-2021\"\n  title: \"debug.gem: Ruby's new debug functionality\"\n  raw_title: \"RubyConf 2021 - debug.gem: Ruby's new debug functionality by Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    This talk introduces ruby/debug: Debugging functionality for Ruby, a completely rewritten debugger for Ruby and it will be shipped with Ruby 3.1 at next Christmas.\n\n    The new debugger has several advantages:\n\n    Fastest debugger: Using recent introduced TracePoint features and (almost) no penalty on normal execution.\n    Remote debugger\n    Native VSCode (DAP) integration\n    Easy integration with applications\n    Thread/Ractor support\n    And more useful features!\n    In this talk, I'll introduce useful features of this new debugger and tips for Ruby development.\n  video_provider: \"youtube\"\n  video_id: \"s74tfFk2txM\"\n\n- id: \"rein-henrichs-rubyconf-2021\"\n  title: \"Beyond Blameless\"\n  raw_title: \"RubyConf 2021- Beyond Blameless by Rein Henrichs\"\n  speakers:\n    - Rein Henrichs\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    In the aftermath of John Allspaw's hugely influential \"Blameless Post-Mortems\", blamelessness has become a shibboleth for modern production operations teams. But it seems that something has been lost in translation. Organizations that try to \"be blameless\" without understanding blame often make activities taboo that can lead to blame. But many of them (like attribution and event analysis) are not inherently harmful — and they are necessary for learning. When we throw the baby of learning out with the bathwater of blaming, we also lose opportunities to become more resilient.\n  video_provider: \"youtube\"\n  video_id: \"l2CdjZUAmb0\"\n\n- id: \"shailvi-wakhlu-rubyconf-2021\"\n  title: \"The Intentional Plan for Intersectionality\"\n  raw_title: \"RubyConf 2021 - The Intentional Plan for Intersectionality by Shailvi Wakhlu\"\n  speakers:\n    - Shailvi Wakhlu\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    When thinking about issues faced by the underrepresented groups, we cannot ignore intersectionality. For eg. Women face plenty of challenges in STEM fields, and also face additional challenges based on their race, sexual orientation, nationality, disability, education, etc. This talk highlights the fierce urgency of now, in planning for intersectionality.\n  video_provider: \"youtube\"\n  video_id: \"ua0TL4zRAIU\"\n\n- id: \"tom-stuart-rubyconf-2021\"\n  title: \"Programming with Something\"\n  raw_title: \"RubyConf 2021 - Programming with Something by Tom Stuart\"\n  speakers:\n    - Tom Stuart\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Programs which manipulate other programs are extremely fun and incredibly powerful. To write them, we need a way to represent code as a data structure which we can analyse, manipulate and eventually execute. In this talk we’ll learn how to store executable code as data in Ruby, and explore how to write different kinds of programs that process it.\n  video_provider: \"youtube\"\n  video_id: \"KwMuTJ_3Ljg\"\n\n- id: \"yusuke-endoh-rubyconf-2021\"\n  title: \"Enjoy Ruby Programming in IDE and TypeProf\"\n  raw_title: \"RubyConf 2021 - Enjoy Ruby Programming in IDE and TypeProf by Yusuke Endoh\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    The rich development experience in integrated development environments (IDEs), including on-the-fly error reporting, refactoring feature, completion, etc., has become increasingly important. To achieve this, many programing languages are incorporating annotations such as type hinting. However, is such IDE features infeasible without annotations? We are challenging ourselves to achieve modern development experience with non-type-annotated Ruby programs by using TypeProf, which is a type analysis tool bundled in Ruby 3.0. In this talk, we demonstrate our prototype, and present its roadmap.\n  video_provider: \"youtube\"\n  video_id: \"6lfAJeGHbfY\"\n\n- id: \"rachel-green-rubyconf-2021\"\n  title: \"Whimsy: Art, Beats & Code\"\n  raw_title: \"RubyConf 2021 - Whimsy: Art, Beats & Code by Rachel Green\"\n  speakers:\n    - Rachel Green\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"06xEs0py8qo\"\n\n- id: \"ali-ibrahim-rubyconf-2021\"\n  title: \"Whimsy: Babies just want to have fun\"\n  raw_title: \"RubyConf 2021 - Whimsy: Babies just want to have fun by Ali Ibrahim\"\n  speakers:\n    - Ali Ibrahim\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"hLl-uQFh3fA\"\n\n- id: \"mike-dalessio-whimsy-rubyconf-2021\"\n  title: \"Whimsy: Put That Test Down! You don't know where it's been\"\n  raw_title: \"RubyConf 2021 - Whimsy: Put That Test Down! You don't know where it's been by Michael Dalessio\"\n  speakers:\n    - Mike Dalessio\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"cWzsmOw-AFw\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2021\"\n  title: \"Keynote: Beyond Ruby3.0\"\n  raw_title: \"RubyConf 2021 - Keynote: Beyond Ruby3.0 by Yukihiro (Matz) Matsumoto\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2021\"\n  date: \"2021-11-08\"\n  published_at: \"2022-08-09\"\n  description: |-\n    Keynote: Beyond Ruby3.0 by Yukihiro (Matz) Matsumoto\n  video_provider: \"youtube\"\n  video_id: \"sAu8UUnVc_Y\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2022/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZYz0O3d9ZDdo0-BkOWhrSk\"\ntitle: \"RubyConf 2022\"\nkind: \"conference\"\nlocation: \"Houston, TX, United States\"\ndescription: |-\n  RubyConf Houston 2022\nstart_date: \"2022-11-29\"\nend_date: \"2022-12-01\"\npublished_at: \"2023-02-28\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2022\nbanner_background: \"#2C2626\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 29.7600771\n  longitude: -95.37011079999999\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2022/videos.yml",
    "content": "---\n# TODO: talks running order\n#\n# Website:  https://web.archive.org/web/20221130083932/https://rubyconf.org/\n# Schedule: https://web.archive.org/web/20221130083932/https://rubyconf.org/schedule\n\n- id: \"michael-toppa-rubyconf-2022\"\n  title: \"From beginner to expert, and back again\"\n  raw_title: \"RubyConf 2022: From beginner to expert, and back again by Michael Toppa\"\n  speakers:\n    - Michael Toppa\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    \"In the beginner's mind there are many possibilities, in the expert's mind there are few.\" - Shunryu Suzuki, from \"Zen Mind, Beginner's Mind\" The Japanese Zen term shoshin translates as “beginner’s mind” and refers to a paradox: the more you know about a subject, the more likely you are to close your mind to further learning. In contrast, the beginner’s state of mind is judgment free. It’s open, curious, available, and present. We’ll draw on examples of these mindsets from fields as varied as aviation and geology, and discover lessons we can apply to the world of software development.\n  video_provider: \"youtube\"\n  video_id: \"UcFBtBOo0dk\"\n\n- id: \"ben-greenberg-rubyconf-2022\"\n  title: \"Change the Climate Before Changing the Weather\"\n  raw_title: \"RubyConf 2022: Change the Climate Before Changing the Weather by Ben Greenberg\"\n  speakers:\n    - Ben Greenberg\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Unless you're self-employed you work for a system. That system is comprised of its own culture in decision making, inclusivity, and a lot more. As one person in a system how can you make an impact on it? Sometimes you can’t change the weather, but you can change the climate in your own room. You may even find that if you change the temperature in enough rooms, surprisingly, you end up changing the weather. In this talk, we’ll discuss a process of systems change that is ground up, going from the micro to the macro. You’ll leave more empowered to start changing the climate in your own workplace.\n  video_provider: \"youtube\"\n  video_id: \"OidmT2LhOdA\"\n\n- id: \"chris-bloom-rubyconf-2022\"\n  title: \"Simulated Annealing: The Most Metal Algorithm Ever 🤘\"\n  raw_title: \"RubyConf 2022: Simulated Annealing: The Most Metal Algorithm Ever 🤘 by Chris Bloom\"\n  speakers:\n    - Chris Bloom\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Simulated annealing is a fascinating algorithm that's designed to help find a particular type of solution (near-optimal, aka \"good enough\") to a particular type of problem (constrained optimization). It's inspired by the science of metallurgy, and because it's grounded in a real-world process I find it incredibly approachable. In this talk I'll explain in plain terms about what simulated annealing is, what a constrained optimization problem is, why you might want a \"good enough\" solution, and how we can use the Annealing gem to add simulated annealing to our Ruby apps.\n  video_provider: \"youtube\"\n  video_id: \"REMwU_dZ0ow\"\n\n- id: \"keith-bennett-rubyconf-2022\"\n  title: \"Ruby Lambdas\"\n  raw_title: \"RubyConf 2022: Ruby Lambdas by Keith Bennett\"\n  speakers:\n    - Keith Bennett\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  slides_url: \"https://speakerdeck.com/keithrbennett/2022-rubyconf-ruby-lambdas\"\n  description: |-\n    Object Oriented Design is powerful for organizing software behavior, but without the benefit of lambdas' code-as-data flexibility, it often fails to reduce solutions to their simplest form. Although Ruby's Enumerable functionality is widely appreciated, its lambdas generally are not. This presentation introduces the developer to lambdas, and shows how they can be used to write software that is cleaner, simpler, and more flexible. We'll go through lots of code fragments, exploring diverse ways of exploiting their power and identifying reusable functional design patterns along the way.\n  video_provider: \"youtube\"\n  video_id: \"lxSoqjJSd38\"\n\n- id: \"andy-maleh-rubyconf-2022\"\n  title: \"Building Native GUI Apps in Ruby\"\n  raw_title: \"RubyConf 2022: Building Native GUI Apps in Ruby by Andy Maleh\"\n  speakers:\n    - Andy Maleh\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Ruby is an excellent choice for building desktop apps with a native GUI (Graphical User Interface) that looks familiar on Mac, Windows, and Linux. In fact, Ruby pushes the boundaries of developing such apps in brand new ways not seen in web development by supporting very lightweight and declarative GUI syntax including bidirectional data-binding, thanks to Glimmer DSL for LibUI, a gem that won a Fukuoka Ruby 2022 Special Award. In this talk, I will cover concepts like the GUI DSL, data-binding, custom controls, area graphics, drag & drop, MVC/MVP pattern, and scaffolding, with sample demos.\n  video_provider: \"youtube\"\n  video_id: \"w3tOrHDbbFA\"\n\n- id: \"noel-rappin-rubyconf-2022\"\n  title: \"In Defense of Ruby Metaprogramming\"\n  raw_title: \"RubyConf 2022: In Defense of Ruby Metaprogramming By Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    If you’ve learned Ruby recently, you’ve likely been told to avoid using Ruby’s metaprogramming features because they are “dangerous”. Here at RubyConf, we laugh at danger. Or at least chuckle nervously at it. Ruby’s flexibility is one of the features that makes Ruby powerful, and ignoring it limits what you can do with the language. Plus, metaprogramming is fun. Let’s talk about when it makes sense to metaprogram, what parts of Ruby to use, and how to do it safely. You’ll leave with the tools to effectively metaprogram in your code.\n  video_provider: \"youtube\"\n  video_id: \"o1XvgJoH_tE\"\n\n- id: \"dylan-blakemore-rubyconf-2022\"\n  title: \"Pushing to master - adopting trunk based development\"\n  raw_title: \"RubyConf 2022: Pushing to master - adopting trunk based development by Dylan Blakemore\"\n  speakers:\n    - Dylan Blakemore\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Trunk based development is a scary practice to adopt for engineers used to git flow or github flow. But there is ample evidence to show that it leads to higher quality code and faster delivery. So why are so many resistant to pushing to master? In this talk, we'll go over why TBD can be scary, what challenges are involved in pushing for team and company adoption, and how to overcome those challenges\n  video_provider: \"youtube\"\n  video_id: \"1sKFkV19XAc\"\n\n- id: \"vinicius-stock-rubyconf-2022\"\n  title: \"Improving the development experience with language servers\"\n  raw_title: \"RubyConf 2022: Improving the development experience with language servers by Vinicius Stock\"\n  speakers:\n    - Vinicius Stock\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Providing a state of the art development experience greatly contributes to Ruby’s goal of making developers happy. A complete set of editor features can make a big difference in helping navigate and understand our Ruby code. Let’s explore a modern way of enhancing editor functionality: the language server protocol (LSP). What it is, how to implement it and how an LSP server like the Ruby LSP can make writing Ruby even better.\n  video_provider: \"youtube\"\n  video_id: \"zxdb-xCcHdE\"\n\n- id: \"ryan-perry-rubyconf-2022\"\n  title: \"A Tale of Two Flamegraphs: Continuous Profiling in Ruby\"\n  raw_title: \"RubyConf 2022: A Tale of Two Flamegraphs: Continuous Profiling in Ruby by Ryan Perry\"\n  speakers:\n    - Ryan Perry\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    This talk will dive deep into the internals of one of the fastest growing profiling gems: Pyroscope. Pyroscope is unique because it is actually a ruby gem of another ruby gem written in rust; Pyroscope extends the popular rbspy project as a foundation to not only collect profiling data, but also to tag and analyze that data as well. You can think of Pyroscope as what you would get if rbspy and speedscope had a baby. We’ll start with the internals and end with an example of how two flamegraphs can be used to tell a story about your applications performance.\n  video_provider: \"youtube\"\n  video_id: \"8niNCkiF2Xo\"\n\n- id: \"kevin-kuchta-rubyconf-2022\"\n  title: \"Everything a Microservice: The Worst Possible Intro to dRuby\"\n  raw_title: \"RubyConf 2022: Everything a Microservice: The Worst Possible Intro to dRuby by Kevin Kuchta\"\n  speakers:\n    - Kevin Kuchta\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Microservices are great, but I think we can all agree: we need more of them and they should be micro-er. What's the logical limit here? What if every object was remote in a language where everything's an object? Let's take a look at dRuby, the distributed programming module you've never heard of, and use it to achieve that deranged goal! You'll learn about a nifty little corner of the standard library while we attempt to reach the illogical conclusion of today's hottest architecture trend. Be warned: those sitting in the first few rows may get poorly-marshaled data on them.\n  video_provider: \"youtube\"\n  video_id: \"nrJP9Qr2AXQ\"\n\n- id: \"peter-zhu-rubyconf-2022\"\n  title: \"1.5 is the Midpoint Between 0 and Infinity\"\n  raw_title: \"RubyConf 2022: 1.5 is the Midpoint Between 0 and Infinity by Peter Zhu\"\n  speakers:\n    - Peter Zhu\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    What’s the midpoint between 0 and infinity? Well, the answer differs depending on whether you are asking a mathematician, philosopher, or a Ruby developer. I’m not a mathematician or a philosopher, but I am a Ruby developer, so I can tell you that 1.5 is the midpoint between 0 and infinity. In this talk, we'll discuss the binary search algorithm, IEEE 754 floating-point numbers, and a clever trick Ruby uses to perform binary search on floating-point ranges.\n  video_provider: \"youtube\"\n  video_id: \"RQsH54GK85M\"\n\n- id: \"charles-nutter-rubyconf-2022\"\n  title: \"Using JRuby: What, When, How, and Why\"\n  raw_title: \"RubyConf 2022: Using JRuby: What, When, How, and Why by Charles Nutter\"\n  speakers:\n    - Charles Nutter\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    JRuby has just been updated for Ruby 3.1 support, bringing compatibility up to date for the most widely-deployed alternative Ruby implementation! This talk will teach you all about JRuby: what is it, when should you use it, how to get started and why it matters. Learn why Ruby shops around the world choose JRuby for world-class concurrency, GC, JIT, and cross-platform support.\n  video_provider: \"youtube\"\n  video_id: \"zLX9o_cEen4\"\n\n- id: \"amir-rajan-rubyconf-2022\"\n  title: \"Building a Commercial Game Engine using mRuby and SDL\"\n  raw_title: \"RubyConf 2022: Building a Commercial Game Engine using mRuby and SDL by Amir Rajan\"\n  speakers:\n    - Amir Rajan\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    What does it take to build a cross platform game engine in Ruby? How do you render to the screen? How is the simulation and rendering pipeline orchestrated? Why is Ruby a viable option is to begin with? These questions and more will be answered by Amir. Be a part of this renaissance and see how Ruby can be used for so much more than server side web development.\n  video_provider: \"youtube\"\n  video_id: \"YVcl1Oy6QFM\"\n\n- id: \"ratnadeep-deshmane-rubyconf-2022\"\n  title: \"Writing Ruby, just not in English!\"\n  raw_title: \"RubyConf 2022: Writing Ruby, just not in English! by Ratnadeep Deshmane (rtdp)\"\n  speakers:\n    - Ratnadeep Deshmane\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    My talk shows how to write Ruby in a non-English language and the benefits of doing so. This will certainly be a great help for people who don’t speak English. It also helps get a better programming perspective for seasoned developers who don’t have English as their first language. I will also demo the tooling that I have developed, using which one can quickly create a new spoken language variant of Ruby and start programming in Spanish, Portuguese etc.\n  video_provider: \"youtube\"\n  video_id: \"g8PgM5WGyhQ\"\n\n- id: \"lori-m-olson-rubyconf-2022\"\n  title: \"This Old App\"\n  raw_title: \"RubyConf 2022: This Old App by Lori M Olson\"\n  speakers:\n    - Lori M Olson\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    What could renovating an old house have in common with upgrading an old app? *Everything!* Let me show you how this old house renovation project proceeds, from planning to scheduling, demolition to finishing, and how every stage directly relates the lessons learned from app upgrades over the course of my career.\n  video_provider: \"youtube\"\n  video_id: \"-q9b5wlXr0c\"\n\n- id: \"espartaco-palma-rubyconf-2022\"\n  title: \"Never again without a contract: dry-validation\"\n  raw_title: \"RubyConf 2022: Never again without a contract: dry-validation by Espartaco Palma\"\n  speakers:\n    - Espartaco Palma\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    The same as you shouldn't work without a contract, our systems should accept external inputs without one, a written, clear and enforceable one. Define the structure & expected payload being aware of their schema, structure & types. Using dry-schema or dry-validation this part is a matter of a few lines of codes covering most of the cases you may find with the cherry-on-top: error handling out-of-the-box and if this not enough with optional pattern matching for results.\n  video_provider: \"youtube\"\n  video_id: \"_lMw7guragc\"\n\n- id: \"cj-avilla-rubyconf-2022\"\n  title: \"Boutique machine generated gems\"\n  raw_title: \"RubyConf 2022: Boutique machine generated gems by CJ Avilla\"\n  speakers:\n    - CJ Avilla\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    What if writing boilerplate for Ruby gems were automated using familiar UI building blocks? Many Rubyists are familiar with components for generating clean HTML with higher-level frameworks. Unfortunately, many developers are unaware they can generate clean Ruby code that is as beautiful as their UIs. This talk will explore how we automatically created a generator to produce high-quality ruby and docs for a popular gem. I'll show how to use this approach to keep gems up-to-date with fast-moving APIs, release new versions frequently, and provide an excellent developer experience.\n  video_provider: \"youtube\"\n  video_id: \"aV1obsuDmjU\"\n\n- id: \"glenn-harmon-rubyconf-2022\"\n  title: \"The Power of 'No'\"\n  raw_title: \"RubyConf 2022: The Power of 'No' by Glenn Harmon\"\n  speakers:\n    - Glenn Harmon\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Have you ever attended a meeting that you wish you hadn’t? Have you ever been happy that plans were canceled because you never really wanted to go in the first place? Saying no is hard and can be truly challenging when faced with the prospect of feeling like maybe you’ll let someone down. Another reason saying no is hard is the feeling or FOMO, or the Fear Of Missing Out. All of these are even harder if you're a person of color. But is that 'Yes' worth your peace of mind? This talk is about how knowing when to say no and how to do so.\n  video_provider: \"youtube\"\n  video_id: \"q9Eoo5i6hmk\"\n\n- id: \"lightning-talks-rubyconf-2022\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf 2022: Lightning Talks\"\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"-FM__GyT57Y\"\n  talks:\n    - title: \"Lightning Talk: Olya Boiaryntseva\"\n      start_cue: \"00:16\"\n      end_cue: \"05:21\"\n      id: \"olya-boiaryntseva-lighting-talk-rubyconf-2022\"\n      video_id: \"olya-boiaryntseva-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Olya Boiaryntseva\n\n    - title: \"Lightning Talk: Baking is Like Programming\"\n      start_cue: \"05:24\"\n      end_cue: \"11:27\"\n      id: \"jose-miguel-tomita-rodriguez-lighting-talk-rubyconf-2022\"\n      video_id: \"jose-miguel-tomita-rodriguez-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Jose Miguel Tomita Rodriguez\n\n    - title: \"Lightning Talk: Tom Brown\"\n      start_cue: \"11:29\"\n      end_cue: \"12:48\"\n      id: \"tom-brown-lighting-talk-rubyconf-2022\"\n      video_id: \"tom-brown-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Tom Brown\n\n    - title: \"Lightning Talk: Adam Cuppy\"\n      start_cue: \"12:51\"\n      end_cue: \"15:01\"\n      id: \"adam-cuppy-lighting-talk-rubyconf-2022\"\n      video_id: \"adam-cuppy-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Cuppy\n\n    - title: \"Lightning Talk: How to Open Source\"\n      start_cue: \"15:02\"\n      end_cue: \"20:10\"\n      id: \"richard-schneeman-lighting-talk-rubyconf-2022\"\n      video_id: \"richard-schneeman-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Richard Schneeman\n\n    - title: \"Lightning Talk: Bryce Simons\"\n      start_cue: \"20:12\"\n      end_cue: \"24:20\"\n      id: \"bryce-simons-lighting-talk-rubyconf-2022\"\n      video_id: \"bryce-simons-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Bryce Simons\n\n    - title: \"Lightning Talk: Models and Multi-tenancy\"\n      start_cue: \"24:22\"\n      end_cue: \"29:27\"\n      id: \"jacob-daddario-lighting-talk-rubyconf-2022\"\n      video_id: \"jacob-daddario-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Jacob Daddario\n\n    - title: \"Lightning Talk: Mike Eduard\"\n      start_cue: \"29:29\"\n      end_cue: \"31:41\"\n      id: \"mike-eduard-lighting-talk-rubyconf-2022\"\n      video_id: \"mike-eduard-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Mike Eduard\n\n    - title: \"Lightning Talk: Why Contributing to Open Source is Easy\"\n      start_cue: \"31:50\"\n      end_cue: \"36:49\"\n      id: \"landon-gray-lighting-talk-rubyconf-2022\"\n      video_id: \"landon-gray-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Landon Gray\n\n    - title: \"Lightning Talk: A Smarter Way to Build Circuits\"\n      start_cue: \"36:51\"\n      end_cue: \"41:13\"\n      id: \"jenner-la-fave-lighting-talk-rubyconf-2022\"\n      video_id: \"jenner-la-fave-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Jenner La Fave\n\n    - title: \"Lightning Talk: Don't abuse #reduce\"\n      raw_title: \"Don't abuse #reduce, A love letter to Enumerable\"\n      start_cue: \"41:16\"\n      end_cue: \"46:43\"\n      thumbnail_cue: \"41:22\"\n      id: \"alexander-momchilov-lighting-talk-rubyconf-2022\"\n      video_id: \"alexander-momchilov-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Alexander Momchilov\n\n    - title: \"Lightning Talk: Stack Overflow Embedded\"\n      start_cue: \"46:45\"\n      end_cue: \"49:10\"\n      id: \"andrew-gauger-lighting-talk-rubyconf-2022\"\n      video_id: \"andrew-gauger-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew Gauger\n\n    - title: \"Lightning Talk: Tech Injury\"\n      start_cue: \"49:12\"\n      end_cue: \"54:29\"\n      id: \"casey-watts-lighting-talk-rubyconf-2022\"\n      video_id: \"casey-watts-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Casey Watts\n\n    - title: \"Lightning Talk: Keith Bennett\"\n      start_cue: \"54:30\"\n      end_cue: \"58:00\"\n      id: \"keith-bennett-lighting-talk-rubyconf-2022\"\n      video_id: \"keith-bennett-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Keith Bennett\n\n    - title: \"Lightning Talk: Craig Buchek\"\n      start_cue: \"58:02\"\n      end_cue: \"1:02:30\"\n      id: \"craig-buchek-lighting-talk-rubyconf-2022\"\n      video_id: \"craig-buchek-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Craig Buchek\n\n    - title: \"Lightning Talk: Failing Fast with Sorbet\"\n      start_cue: \"1:02:31\"\n      end_cue: \"1:07:15\"\n      id: \"james-reid-smith-lighting-talk-rubyconf-2022\"\n      video_id: \"james-reid-smith-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - James Reid-Smith\n\n    - title: \"Lightning Talk: Asynchronous Messaging in Ruby\"\n      start_cue: \"1:07:18\"\n      end_cue: \"1:12:25\"\n      id: \"adam-e-hampton-lighting-talk-rubyconf-2022\"\n      video_id: \"adam-e-hampton-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam E. Hampton\n\n    - title: \"Lightning Talk: I defer too much to the internet\"\n      start_cue: \"1:12:28\"\n      end_cue: \"1:16:35\"\n      id: \"yasu-flores-lighting-talk-rubyconf-2022\"\n      video_id: \"yasu-flores-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Yasu Flores\n\n    - title: \"Lightning Talk: Weekly Cool Down\"\n      start_cue: \"1:16:37\"\n      end_cue: \"1:21:15\"\n      id: \"anas-alkhatib-lighting-talk-rubyconf-2022\"\n      video_id: \"anas-alkhatib-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Anas Alkhatib\n\n    - title: \"Lightning Talk: Captioners: How Do You Do That???\"\n      start_cue: \"1:21:18\"\n      end_cue: \"1:25:15\"\n      id: \"amanda-lundberg-lighting-talk-rubyconf-2022\"\n      video_id: \"amanda-lundberg-lighting-talk-rubyconf-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Amanda Lundberg\n\n- id: \"allison-mcmillan-rubyconf-2022\"\n  title: \"Ruby Central Panel\"\n  raw_title: \"RubyConf 2022: Ruby Central Panel\"\n  speakers:\n    - Allison McMillan\n    - Chelsea Kaufman\n    - Neil McGovern\n    - Marty Haught\n    - Valerie Woolard\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"0ItWcBK7pTk\"\n\n- id: \"eileen-m-uchitelle-rubyconf-2022\"\n  title: \"Exit(ing) Through the YJIT\"\n  raw_title: \"RubyConf 2022: Exit(ing) Through the YJIT by Eileen M Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    When optimizing code for the YJIT compiler it can be difficult to figure out what code is exiting and why. While working on tracing exits in a Ruby codebase, I found myself wishing we had a tool to reveal the exact line that was causing exits to occur. We set to work on building that functionality into Ruby and now we are able to see every side-exit and why. In this talk we’ll learn about side-exits and how we built a tracer for them. We’ll explore the original implementation, how we rewrote it in Rust, and lastly why it’s so important to always ask \"can I make what I built even better?\"\n  video_provider: \"youtube\"\n  video_id: \"EZEEl61bWSw\"\n\n- id: \"tori-machen-rubyconf-2022\"\n  title: \"Crocheting & Coding: they're more similar than you think!\"\n  raw_title: \"RubyConf 2022: Crocheting & Coding: they're more similar than you think! by Tori Machen\"\n  speakers:\n    - Tori Machen\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Many of us have hobbies that we enjoy outside of our careers in tech. For me, that is amigurumi, the art of crocheting stuffed creatures. What if I told you that amigurumi is extremely similar to software development? Join me in exploring the intersection between crocheting amigurumi and developing software. We’ll look at the key similarities between these two crafts, and I’ll share how crocheting has helped me become a better software developer. You’ll walk away inspired to connect your own hobbies to your role in tech or find a new creative hobby (like crochet)!\n  video_provider: \"youtube\"\n  video_id: \"GOnW_586TiU\"\n\n- id: \"nadia-odunayo-rubyconf-2022\"\n  title: \"Keynote: The Case Of The Vanished Variable - A Ruby Mystery Story\"\n  raw_title: \"RubyConf 2022: Keynote: The Case Of The Vanished Variable - A Ruby Mystery Story by Nadia Odunayo\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    After a stressful couple of days at work, Deirdre Bug is looking forward to a quiet evening in. But her plans are thwarted when the phone rings. “I know I’m the last person you want to hear from…but...I need your help!” Follow Deirdre as she embarks on an adventure that features a looming Demo Day with serious prize money up for grabs, a trip inside the walls of one of the Ruby community’s most revered institutions, and some broken code that appears to be much more simple than meets the eye.\n  video_provider: \"youtube\"\n  video_id: \"HSgY9o4gIPE\"\n\n- id: \"sijia-wu-rubyconf-2022\"\n  title: \"Eclectics Unite: Leverage Your Diverse Background\"\n  raw_title: \"RubyConf 2022: Eclectics Unite: Leverage Your Diverse Background by Sijia Wu\"\n  speakers:\n    - Sijia Wu\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    In addition to writing Ruby for work, I am also an academic translator, a snowboard instructor, and a drummer in a rock band. I am consistently amazed and inspired by the similarities and connections between software development and my seemingly unrelated experiences. What does translating science articles teach me about effectively using coding resources? How is playing drums in a rehearsal similar to test-driven development? How do I apply snowboard teaching principles to pair programming? Join me as I share my own story and explore ways you can leverage your diverse background.\n  video_provider: \"youtube\"\n  video_id: \"NGQzBjDWo-A\"\n\n- id: \"suzan-bond-rubyconf-2022\"\n  title: \"Keynote: Lost in the Wilderness\"\n  raw_title: \"RubyConf 2022: Keynote by Suzan Bond\"\n  speakers:\n    - Suzan Bond\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Suzan Bond is a former COO of Travis CI, leadership consultant and executive coach. Her specialty is leaders at scaling startups. She's spent more than 15 years in technology. Her education background includes psychology, organization development, leadership and community organizing. Suzan facilitates workshops and is host of LeadDev's Bookmarked series. She's spoken at numerous events, is a contributor to Fast Company's Work Life section and writes the Suzan's Fieldnotes newsletter.\n  video_provider: \"youtube\"\n  video_id: \"OqpBxSp-4FI\"\n\n- id: \"thijs-cadier-rubyconf-2022\"\n  title: \"How music works, using Ruby\"\n  raw_title: \"RubyConf 2022: How music works, using Ruby Thijs Cadier\"\n  speakers:\n    - Thijs Cadier\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    That strange phenomenon where air molecules bounce against each other in a way that somehow comforts you, makes you cry, or makes you dance all night: music. Since the advent of recorded audio, a musician doesn't even need to be present anymore for this to happen (which makes putting \"I will always love you\" on repeat a little less awkward). Musicians and sound engineers have found many ways of creating music, and making it sound good. Some of their methods have become industry staples used on every recording released today. Let's look at what they do and reproduce some of their methods in Ruby!\n  video_provider: \"youtube\"\n  video_id: \"RAtDPFsk3hc\"\n\n- id: \"nickolas-means-rubyconf-2022\"\n  title: \"The Magnitude 9.1 Meltdown at Fukushima\"\n  raw_title: \"RubyConf 2022: The Magnitude 9.1 Meltdown at Fukushima by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    It was mid-afternoon on Friday, March 11, 2011 when the ground in Tōhoku began to shake. At Fukushima Daiichi nuclear power plant, it seemed like the shaking would never stop. Once it did, the reactors had automatically shut down, backup power had come online, and the operators were well on their way to having everything under control. And then the tsunami struck. They found themselves facing something beyond any worse-case scenario they imagined, and their response is a study in contrasts. We can learn a lot from the extremes they experienced about finding happiness and satisfaction at work.\n  video_provider: \"youtube\"\n  video_id: \"RGS0jBMniag\"\n\n- id: \"aaron-patterson-rubyconf-2022\"\n  title: \"Don't @ me! Faster Instance Variables with Object Shapes\"\n  raw_title: \"RubyConf 2022: Don't @ me! Faster Instance Variables with Object Shapes by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  slides_url: \"https://speakerdeck.com/tenderlove/dont-at-me-faster-instance-variables-with-object-shapes\"\n  description: |-\n    Instance variables are a popular feature of the Ruby programming language, and many people enjoy using them. They are so popular that the Ruby core team has done lots of work to speed them up. But we can do even better to speed them up by using a technique called \"Object Shapes\". In this presentation we'll learn about what object shapes are, how they are implemented, how how they can be used to speed up getting and setting instance variables. We'll make sure to square up Ruby instance variable implementation details so that you can become a more well rounded developer!\n  video_provider: \"youtube\"\n  video_id: \"ZaHd5MDJRBw\"\n\n- id: \"varun-gandhi-rubyconf-2022\"\n  title: \"scip-ruby - A Ruby indexer built with Sorbet\"\n  raw_title: \"RubyConf 2022: scip-ruby - A Ruby indexer built with Sorbet by Varun Gandhi\"\n  speakers:\n    - Varun Gandhi\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    scip-ruby is an open source indexer that lets you browse Ruby code online, with IDE functionality like “Go to definition” and “Find usages”. We originally built scip-ruby to improve Ruby support in Sourcegraph, a code intelligence platform. In this talk, you will learn how we built scip-ruby on top of Sorbet, a Ruby typechecker, and how scip-ruby compares to IDEs and other online code navigation tools. Along the way, we will discuss how quintessential ideas like layering code into a functional core and an imperative shell apply to developer tools, and enable easier testing.\n  video_provider: \"youtube\"\n  video_id: \"cfceVH_1H3Q\"\n\n- id: \"tyler-ackerman-rubyconf-2022\"\n  title: \"Building an education savings platform, with Ruby!\"\n  raw_title: \"RubyConf 2022: Building an education savings platform, with Ruby! by Tyler Ackerman\"\n  speakers:\n    - Tyler Ackerman\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Wealthsimple Foundation is a Canadian charity working to enable a brighter future for everyone in Canada through access to post-secondary education. The Foundation is supported by Wealthsimple, which builds a variety of digital financial tools trusted by over 2.5 million Canadians. In this talk we'll go over: - How an organization supporting for-profit and non-profit activities is structured (and the ethical considerations that can arise from that) - Responsibilities of engineers working in a non-profit space - Opportunities and challenges of digital products addressing systematic inequalities\n  video_provider: \"youtube\"\n  video_id: \"cmZKu-kyyio\"\n\n- id: \"gaurav-kumar-singh-rubyconf-2022\"\n  title: \"Static typing with RBS in Ruby\"\n  raw_title: \"RubyConf 2022: Static typing with RBS in Ruby by Gaurav Kumar Singh\"\n  speakers:\n    - Gaurav Kumar Singh\n  event_name: \"RubyConf 2022\"\n  date: \"2022-12-01\"\n  published_at: \"2023-03-07\"\n  description: |-\n    In this talk, we'll generally explore the static type eco system in Ruby. Ruby has two main type checkers Sorbet and RBS. Sorbet was created by the Stripe and RBS is supported by ruby. Sorbet is an annotation base type checking system while RBS is a definition file-based type system. We'll add type annotation for a popular gem using sorbet and RBS and then compare the differences between the two systems. There is lot of interoperability announced between Sorbet and RBS and we'll explore if it's practically possible to convert a sorbet annotated project to RBS.\n  video_provider: \"youtube\"\n  video_id: \"iKJeKxf3Nck\"\n\n- id: \"jeremy-evans-rubyconf-2022\"\n  title: \"Helping Redistrict California with Ruby\"\n  raw_title: \"RubyConf 2022: Helping Redistrict California with Ruby by Jeremy Evans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Every 10 years, after the federal census, California and most other states redraw the lines of various electoral districts to attempt to ensure the districts are fair and have roughly equal population. California uses a system written in Ruby for citizens to apply to become redistricting commissioners, and for review of the submitted applications. Come learn about redistricting and the unique design of the California redistricting commissioner application system, with 12 separate web server process types, isolated networks, 3-factor authentication, and other security features.\n  video_provider: \"youtube\"\n  video_id: \"q5nke59IuAs\"\n\n- id: \"mae-beale-rubyconf-2022\"\n  title: \"Solidarity not Charity and Collective Liberation\"\n  raw_title: \"RubyConf 2022: Solidarity not Charity and Collective Liberation by Mae Beale\"\n  speakers:\n    - Mae Beale\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Wondering how to get involved in supporting your communities? Hear from someone who has spun up (and down) multiple volunteer and service projects. May it spark your imagination -- and your heart -- to join or start helping out both this wild world and yourself. New mutual aid groups formed around the world in 2020. The tools were not ideal and the volume overwhelmed volunteers. A handful of of tech folx built a fit-to-suit app to manage immediate needs and maximize impact of partner mutual aid groups. Wins were achieved. Lessons were learned. And the interconnectedness of all things was felt.\n  video_provider: \"youtube\"\n  video_id: \"saPZ0Jh3UU0\"\n\n- id: \"daniel-magliola-rubyconf-2022\"\n  title: 'What does \"high priority\" mean? The secret to happy queues'\n  raw_title: 'RubyConf 2022: What does \"high priority\" mean? The secret to happy queues by Daniel Magliola'\n  speakers:\n    - Daniel Magliola\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Like most web applications, you run important jobs in the background. And today, some of your urgent jobs are running late. Again. No matter how many changes you make to how you enqueue and run your jobs, the problem keeps happening. The good news is you're not alone. Most teams struggle with this problem, try more or less the same solutions, and have roughly the same result. In the end, it all boils down to one thing: keeping latency low. In this talk I will present a latency-focused approach to managing your queues reliably, keeping your jobs flowing and your users happy.\n  video_provider: \"youtube\"\n  video_id: \"w0Bl-5TDCC4\"\n\n- id: \"caleb-hearth-rubyconf-2022\"\n  title: \"RSpec: The Bad Parts\"\n  raw_title: \"RubyConf 2022: RSpec: The Bad Parts by Caleb Hearth\"\n  speakers:\n    - Caleb Hearth\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    RSpec is good, but it’s even better with less of it. Looking at a realistic example spec, we’ll learn why parts of RSpec like let, subject, shared_examples, behaves like, and before can make your tests hard to read, difficult to navigate, and more complex. We'll discuss when DRY is not worth the price and how we can avoid repetition without using RSpec's built-in DSL methods. In the end, we'll look at what's left. RSpec: The Good Parts.\n  video_provider: \"youtube\"\n  video_id: \"_UFE0t2Sgaw\"\n\n- id: \"benji-lewis-rubyconf-2022\"\n  title: \"Data indexing with RGB (Ruby, Graphs and Bitmaps)\"\n  raw_title: \"RubyConf 2022: Data indexing with RGB (Ruby, Graphs and Bitmaps) by Benji Lewis\"\n  speakers:\n    - Benji Lewis\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    In this talk, we will go on a journey through Zappi’s data history and how we are using Ruby, a graph database, and a bitmap store to build a unique data engine. A journey that starts with the problem of a disconnected data set and serialised data frames, and ends with the solution of an in-memory index. We will explore how we used RedisGraph to model the relationships in our data, connecting semantically equal nodes. Then delve into how a query layer was used to index a bitmap store and, in turn, led to us being able to interrogate our entire dataset orders of magnitude faster than before.\n  video_provider: \"youtube\"\n  video_id: \"FwBRoxrHaBU\"\n\n- id: \"paul-hoffer-rubyconf-2022\"\n  title: \"Bending Time with Crystal: 6 hours to 15 minutes\"\n  raw_title: \"RubyConf 2022: Bending Time with Crystal: 6 hours to 15 minutes by Paul Hoffer\"\n  speakers:\n    - Paul Hoffer\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    In software, we often encounter problems that we accept as \"just how things are.\" But sometimes, that creates opportunities to identify creative, out of the box solutions. One idea can be combining the power of Crystal with our existing Ruby knowledge, to create effective tools with minimal learning curve and cognitive overhead. I'll demonstrate how easily Ruby code can be ported to Crystal, how it can benefit us, and how to identify these opportunities.\n  video_provider: \"youtube\"\n  video_id: \"6MpXSrgBVww\"\n\n- id: \"benoit-daloze-rubyconf-2022\"\n  title: \"Splitting: the Crucial Optimization for Ruby Blocks\"\n  raw_title: \"RubyConf 2022: Splitting: the Crucial Optimization for Ruby Blocks by Benoit Daloze\"\n  speakers:\n    - Benoit Daloze\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Blocks are one of the most expressive parts of the Ruby syntax. Many Ruby methods take a block. When a method is given different blocks, there is a crucial optimization necessary to unlock the best performance. This optimization dates back to the early days of research on dynamic languages, yet it seems only a single Ruby implementation currently uses it. This optimization is called splitting and what it does is using different copies of a method and specialize them to the block given at different call sites. This enables compiling the method and the block together for the best performance.\n  video_provider: \"youtube\"\n  video_id: \"PjUpcR5UPHI\"\n\n- id: \"ali-hamidi-rubyconf-2022\"\n  title: \"Building Stream Processing Applications with Ruby & Meroxa\"\n  raw_title: \"RubyConf 2022: Building Stream Processing Applications with Ruby & Meroxa by Ali Hamidi\"\n  speakers:\n    - Ali Hamidi\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    As the world moves towards real-time there’s a growing demand for building sophisticated stream processing applications. Traditionally building these apps has involved spinning up separate task-specific tooling, learning new and unfamiliar paradigms, as well as deploying and operating a constellation of complex services. In this talk, we’ll take a look at how to use the Turbine framework (turbine.rb) to build and deploy real-time stream processing applications using Ruby.\n  video_provider: \"youtube\"\n  video_id: \"6bHZQy0Ti_c\"\n\n- id: \"stacey-mcknight-rubyconf-2022\"\n  title: \"Boot the backlog: Optimizing your workflow for dev happiness\"\n  raw_title: \"RubyConf 2022: Boot the backlog: Optimizing your workflow for dev happiness by Stacey McKnight\"\n  speakers:\n    - Stacey McKnight\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    What would happen if your team dropped that standing Monday morning refinement meeting? Chaos? We often follow work processes because they’re “the way things are done”, but clunky, unexamined processes slow down even talented teams. Never ending backlogs make it hard to feel like you’re making progress. Frequent meetings break up focus. If something about the way we work doesn’t help us move more quickly or effectively, it’s time to rethink it. Seeking a better way to coordinate work across 3 continents, the Workforce.com dev team adopted the Shape Up approach to project management. This talk explores the core elements of that approach and ways to optimize developer happiness while delivering more value for users.\n  video_provider: \"youtube\"\n  video_id: \"BB_GjUIA06c\"\n\n- id: \"kevin-whinnery-rubyconf-2022\"\n  title: \"Business in the Front, Party in the Back (Office)\"\n  raw_title: \"RubyConf 2022: Business in the Front, Party in the Back (Office) by Kevin Whinnery\"\n  speakers:\n    - Kevin Whinnery\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    If you have ever built a web application, chances are that you have also had to deal with \"the back office\" - the chores and one-off tasks required to operate your software in production. Workflows that aren't user-facing, like creating promo codes, moderating content, or running reports, are often a janky combination of admin scripts and spreadsheets. Retool helps developers quickly and easily solve these problems with software instead. In this session, we'll show how to build a back office interface for a Ruby on Rails application using Postgres and several common API services, so you can keep your focus on the business in the front, and let Retool help throw the party in the back (office).\n  video_provider: \"youtube\"\n  video_id: \"GSBhVVWycvU\"\n\n- id: \"kyle-doliveira-rubyconf-2022\"\n  title: \"Analyzing an analyzer - A dive into how RuboCop works\"\n  raw_title: \"RubyConf 2022: Analyzing an analyzer - A dive into how RuboCop works by Kyle d'Oliveira\"\n  speakers:\n    - Kyle d'Oliveira\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    To help us with aspects like linting, security or style, many of us have Rubocop analyzing our code. It's a very useful tool that is widely used, easy to set up and configure. Rubocop can even automatically auto-correct your source code as needed. How is this even possible? It turns out that Ruby is really good at taking Ruby code as input and doing various things based on that input. In this talk, I will go through some of the internals of Rubocop to show how it analyzes and makes changes to your source code.\n  video_provider: \"youtube\"\n  video_id: \"pSCMgcttW4c\"\n\n- id: \"nick-schwaderer-rubyconf-2022\"\n  title: \"Ruby Archaeology: Forgotten web frameworks\"\n  raw_title: \"RubyConf 2022: Ruby Archaeology: Forgotten web frameworks by Nick Schwaderer\"\n  speakers:\n    - Nick Schwaderer\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    In the 2000's everyone was writing a Ruby web framework **Today, it seems, we are all too content to focus our energy on a small number of large Ruby web projects**. What happened to our creative spirit? In this talk we focus on Ruby web frameworks that have long gone by the wayside. I won't spoil them here, but I can tell you what we won't be covering: \n    * Sinatra \n    * Hanami \n    * roda \n    * merb \n\n    We will answer questions like: \n    * Why are fewer people experimenting with their own frameworks today? \n    * What features, idioms and ideas are worth exploring? \n    * Are any of these frameworks worth reviving or copying?\n  video_provider: \"youtube\"\n  video_id: \"oXHgNh6DcSI\"\n\n- id: \"chris-seaton-rubyconf-2022\"\n  title: \"Ruby's Core Gem\"\n  raw_title: \"RubyConf 2022: Ruby’s Core Gem by Chris Seaton\"\n  speakers:\n    - Chris Seaton\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Ruby has a core library that is part of the interpreter and always available. It’s classes like String and Time. But what would it be like if we re-implemented the core library, writing it in Ruby itself, and made it available as a gem? Would it be faster or slower? Would it be easier to understand and debug? What other benefits could there be? It was originally Rubinius that implemented Ruby’s core in Ruby, and it has been taken up and maintained by the TruffleRuby team.\n  video_provider: \"youtube\"\n  video_id: \"8mqDIHer1G4\"\n\n- id: \"carolyn-cole-rubyconf-2022\"\n  title: \"I'm in love with Mermaid\"\n  raw_title: \"RubyConf 2022: I'm in love with Mermaid by Carolyn Cole\"\n  speakers:\n    - Carolyn Cole\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Everyone says that a picture is worth a thousand words... The issue in the past is that those pictures have been hard to create let alone maintain. Welcome Mermaid (https://mermaid-js.github.io/mermaid/#/)! Mermaid is a mark down compatible graphing tool that allows you to add diagrams directly to your markdown in github. I have been using it for a a year and just love it. I believe that you will love it too once you join my session.\n  video_provider: \"youtube\"\n  video_id: \"iFXomx3QLM4\"\n\n- id: \"justin-bowen-rubyconf-2022\"\n  title: \"Discover Machine Learning in Ruby\"\n  raw_title: \"RubyConf 2022: Discover Machine Learning in Ruby by Justin Bowen\"\n  speakers:\n    - Justin Bowen\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-03-07\"\n  description: |-\n    We can use Ruby to do anything we as a community want. Today we’ll explore the work of a hidden gem of a contributor in our community, Andrew Kane, and their Ruby gems for Machine Learning. We will see how contemporary computer vision neural networks can run with Ruby. Ruby is all about developer happiness. Computer Vision is something that brings me great joy as it delivers satisfying visual feedback and connects our code with the real world through images and videos in a way that wasn’t accessible until the last decade or so.\n  video_provider: \"youtube\"\n  video_id: \"HPbizNgcyFk\"\n\n- id: \"alexandre-terrasa-rubyconf-2022\"\n  title: \"Staff Engineer: “Here be dragons”\"\n  raw_title: \"RubyConf 2022: Staff Engineer: “Here be dragons” by Alexandre Terrasa\"\n  speakers:\n    - Alexandre Terrasa\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    “Here be dragons”: this is how uncharted areas of maps were marked in medieval times. Today, while the journey to become a Senior Engineer is known territory, being a Staff Engineer appears full of dragons. Together, let’s demystify what leading beyond the management track really means.\n  video_provider: \"youtube\"\n  video_id: \"_7DOSoXICMo\"\n\n- id: \"kelly-ryan-rubyconf-2022\"\n  title: \"Working Together: Pairing as Senior and Junior Developers\"\n  raw_title: \"RubyConf 2022: Working Together: Pairing as Senior and Junior Developers by Kelly Ryan\"\n  speakers:\n    - Kelly Ryan\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-30\"\n  published_at: \"2023-03-07\"\n  description: |-\n    Pairing with a senior developer is a daily necessity for a programmer just starting out. But how should you as a junior developer approach pairing to get the most out of the interaction? How can you not only find a solution to a current problem, but also build relationships and learn skills for future problems? In this talk, you will learn best practices for getting the most out of time with a mentor. I will recommend practical tips and positive habits, as well as ways of thinking that can improve your experience pairing and help you become a better developer.\n  video_provider: \"youtube\"\n  video_id: \"pvl1HPFqRdk\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2022\"\n  title: \"Performance does (not) Matter by Yukihiro Matsumoto (Matz)\"\n  raw_title: \"RubyConf 2022: Performance does (not) Matter by Yukihiro Matsumoto (Matz)\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2022\"\n  date: \"2022-11-29\"\n  published_at: \"2023-02-06\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"knutsgHTrfQ\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2022-mini/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZYz0O3d9ZDdo0-BkOWhrSk\"\ntitle: \"RubyConf 2022 Mini\"\nkind: \"conference\"\nlocation: \"Providence, RI, United States\"\ndescription: |-\n  RubyConf Mini held in Providence, RI\nstart_date: \"2022-11-15\"\nend_date: \"2022-11-17\"\npublished_at: \"2023-02-28\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2022\nbanner_background: \"#FFFDF8\"\nfeatured_background: \"#FFFDF8\"\nfeatured_color: \"#372E6A\"\nwebsite: \"https://web.archive.org/web/20221128050008/https://www.rubyconfmini.com/\"\noriginal_website: \"https://www.rubyconfmini.com\"\ntwitter: \"rubyconfmini\"\ncoordinates:\n  latitude: 41.8244836\n  longitude: -71.4127462\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2022-mini/videos.yml",
    "content": "# Website: https://web.archive.org/web/20221128050008/https://www.rubyconfmini.com/\n# Schedule: https://web.archive.org/web/20221128043326/http://www.rubyconfmini.com/schedule\n# Program: https://web.archive.org/web/20221128050459/http://www.rubyconfmini.com/program\n\n# TODO: talks running order\n---\n- id: \"vladimir-dementyev-rubyconf-2022-mini\"\n  title: \"Weaving and seaming mocks\"\n  raw_title: \"RubyConf Mini 2022: Weaving and seaming mocks by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-16\"\n  published_at: \"2023-03-01\"\n  description: |-\n    To mock or not mock is an important question, but let's leave it apart and admit that we, Rubyists, use mocks in our tests.\n\n    Mocking is a powerful technique, but even when used responsibly, it could lead to false positives in our tests (thus, bugs leaking to production): fake objects could diverge from their real counterparts.\n\n    In this talk, I'd like to discuss various approaches to keeping mocks in line with the actual implementation and present a brand new idea based on mock fixtures and contracts.\n  video_provider: \"youtube\"\n  video_id: \"-ExPO-FCKQA\"\n\n- id: \"ernesto-tagwerker-rubyconf-2022-mini\"\n  title: \"Here Be Dragons: The Hidden Gems of Tech Debt\"\n  raw_title: \"RubyConf Mini 2022: Here Be Dragons: The Hidden Gems of Tech Debt by Ernesto Tagwerker\"\n  speakers:\n    - Ernesto Tagwerker\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-16\"\n  published_at: \"2023-03-01\"\n  slides_url: \"https://speakerdeck.com/etagwerker/here-be-dragons-the-hidden-gems-of-technical-debt\"\n  description: |-\n    How do you find the most unmaintainable code in your codebase? What will you prioritize in your next technical debt spike, and why?\n\n    In this talk you will learn how you can use RubyCritic, SimpleCov, Flog, Reek, and Skunk to slay dragons in your next refactoring adventure! Find out how the relationship between churn, complexity, and code coverage can give you a common language to talk about code quality and increase trust in your code.\n  video_provider: \"youtube\"\n  video_id: \"fl-gbog_wtc\"\n\n- id: \"maple-ong-rubyconf-2022-mini\"\n  title: \"Looking Into Peephole Optimizations\"\n  raw_title: \"RubyConf Mini 2022: Looking Into Peephole Optimizations by Maple Ong\"\n  speakers:\n    - Maple Ong\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Did you know Ruby optimizes your code before executing it? If so, ever wonder how that works? The Ruby VM performs various optimizations on bytecode before executing them, one of them called peephole optimizations. Let’s learn about how some peephole optimizations work and how these small changes impact the execution of Ruby’s bytecode. Do these small changes make any impact on the final runtime? Let's find out - experience reading bytecode is not needed!\n  video_provider: \"youtube\"\n  video_id: \"l0YeRKkUU6c\"\n\n- id: \"hilary-stohs-krause-rubyconf-2022-mini\"\n  title: \"How We Implemented Salary Transparency (And Why It Matters)\"\n  raw_title: \"RubyConf Mini: How We Implemented Salary Transparency (And Why It Matters) by Hilary Stohs Krause\"\n  speakers:\n    - Hilary Stohs-Krause\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-15\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Depending on where you live, money can be a prickly topic in the workplace; however, survey after survey shows it’s also a conversation many employees actively want started. Data also shows that transparency around wages increases trust and job satisfaction and improves gender and racial salary equity.\n\n    However, just because folks want something doesn’t mean getting there will be smooth sailing (as we discovered when we instituted wage transparency three years ago). In this talk, we’ll discuss why salary transparency matters, ways it can manifest, and how to pitch it to the rest of your company.\n  video_provider: \"youtube\"\n  video_id: \"lTiVlylJxSY\"\n\n- id: \"chelsea-kaufman-rubyconf-2022-mini\"\n  title: \"Start a Ruby Internship\"\n  raw_title: \"RubyConf Mini 2022: Start a Ruby Internship by Chelsea Kaufman and Adam Cuppy\"\n  speakers:\n    - Chelsea Kaufman\n    - Adam Cuppy\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Starting an internship doesn’t have to reduce your team's progress. On the contrary, a quality internship can benefit interns and senior folks. And, it doesn't take much to set up and start. We've done over 100!\n\n    You’ll use our established blueprint to draft a successful internship program throughout this workshop. We'll walk through all the planning phases and help you set up the templates so you're ready to make it a win for all involved and \"sell it\" to management. By the end, your internship program will be prepared to hit the ground running, so your interns will be productive on day one.\n  video_provider: \"youtube\"\n  video_id: \"m0VLrlcmyks\"\n\n- id: \"lindsay-kelly-rubyconf-2022-mini\"\n  title: \"Knowing When To Walk Away\"\n  raw_title: \"RubyConf Mini 2022: Knowing When To Walk Away by Lindsay Kelly\"\n  speakers:\n    - Lindsay Kelly\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-15\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Picture this: the job you've always wanted. Doing exactly the kind of work you want. Having great coworkers and management. But then something shifts, and the dream becomes closer to a nightmare. How do you identify these things happening? How do you raise concerns in an appropriate way? And as a last resort, how do you know when it's the right choice to walk away?\n  video_provider: \"youtube\"\n  video_id: \"qk30MqtCIMc\"\n\n- id: \"jenny-shih-rubyconf-2022-mini\"\n  title: \"Functional programming for fun and profit!!\"\n  raw_title: \"RubyConf Mini 2022: Functional programming for fun and profit!! by Jenny Shih\"\n  speakers:\n    - Jenny Shih\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Functional programming brings you not just fun, but also profit!\n\n    Have you ever felt curious towards functional programming (FP)? Were you, soon afterwards, intimidated by the mystic terms like monads and functors? Do you think FP is not related to your Ruby work and thus, useless? Guess what–you can actually apply FP to your Ruby projects and reap benefits from it before fully understanding what a monad is!\n\n    This talk will walk you through the powerful mental models and tools that FP gives us, and how we can readily use them to improve our apps in a language that we all love and understand.\n  video_provider: \"youtube\"\n  video_id: \"tQPmFQSI0lo\"\n\n- id: \"jol-quenneville-rubyconf-2022-mini\"\n  title: \"Teaching Ruby to Count\"\n  raw_title: \"RubyConf Mini 2022: Teaching Ruby to Count by Joël Quenneville\"\n  speakers:\n    - Joël Quenneville\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  slides_url: \"https://speakerdeck.com/joelq/teaching-ruby-to-count\"\n  description: |-\n    Ruby has some of the best tooling in the business for working with iteration and data series. By leveraging its full power, you can build delightful interfaces for your objects.\n\n    In this case-study based presentation, we’ll explore a variety of problems such as composing Enumerable methods, generating a series of custom objects, and how to provide a clean interface for a collection with multiple valid traversal orders. Beyond just the beloved Enumerable module, this talk will take you into the world of Enumerators and Ranges and equip you to write objects that bring joy to your teammates.\n  video_provider: \"youtube\"\n  video_id: \"yCiGMYzhlew\"\n\n- id: \"alan-ridlehoover-rubyconf-2022-mini\"\n  title: \"A Brewer’s Guide to Filtering out Complexity and Churn\"\n  raw_title: \"RubyConf Mini 2022: A Brewer’s Guide to Filtering out Complexity and Churn by Fito von Zastrow\"\n  speakers:\n    - Alan Ridlehoover\n    - Fito von Zastrow\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Mechanical coffee machines are amazing! You drop in a coin, listen for the clink, make a selection, and the machine springs to life, hissing, clicking, and whirring. Then the complex mechanical ballet ends, splashing that glorious, aromatic liquid into the cup. Ah! C’est magnifique!\n\n    There’s just one problem. Our customers also want soup! And, our machine is not extensible. So, we have a choice: we can add to the complexity of our machine by jamming in a new dispenser with each new request; or, we can pause to make our machine more extensible before development slows to a halt.\n  video_provider: \"youtube\"\n  video_id: \"zHK1lYh4n-s\"\n\n- id: \"brittany-martin-rubyconf-2022-mini\"\n  title: \"We Need Someone Technical on the Call\"\n  raw_title: \"RubyConf Mini 2022: We Need Someone Technical on the Call by Brittany Martin\"\n  speakers:\n    - Brittany Martin\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: |-\n    A DM. The dreaded message. “They want someone technical on the call.”\n\n    If that statement is terrifying, never fear. Being effective at these interactions can be a big opportunity for your career. Learn tactics on when to commit to calls and how to execute them while empowering your team, conserving your time and acing the follow through.\n  video_provider: \"youtube\"\n  video_id: \"zONREhN9wQg\"\n\n- id: \"john-hawthorn-rubyconf-2022-mini\"\n  title: \"Making .is_a? Fast\"\n  raw_title: \"RubyConf Mini 2022: Making .is_a? Fast by John Hawthorn\"\n  speakers:\n    - John Hawthorn\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-15\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Until Ruby 3.2 the `is_a?` method can be a surprising performance bottleneck. It be called directly or through its various synonyms like case statements, rescue statements, protected methods, `Module#===` and more! Recently `is_a?` and its various flavours have been optimized and it's now faster and runs in constant time. Join me in the journey of identifying it as a bottleneck in production, implementing the optimization, squashing bugs, and finally turning it into assembly language in YJIT.\n  video_provider: \"youtube\"\n  video_id: \"zcKbWXzopCU\"\n\n- id: \"cameron-gose-rubyconf-2022-mini\"\n  title: \"From Start to Published, Create a game with Ruby!\"\n  raw_title: \"RubyConf Mini 2022: From Start to Published, Create a game with Ruby! by Cameron Gose\"\n  speakers:\n    - Cameron Gose\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-16\"\n  published_at: \"2023-03-01\"\n  description: |-\n    We'll be building a game in Ruby from start to finish using the DragonRuby GameToolkit. Finally we'll publish it so that your new creation can be shared.\n  video_provider: \"youtube\"\n  video_id: \"-dz9KGYMT24\"\n\n- id: \"kevin-murphy-rubyconf-2022-mini\"\n  title: \"Anyone Can Play Guitar (With Ruby)\"\n  raw_title: \"RubyConf Mini 2022: Anyone Can Play Guitar (With Ruby) by Kevin Murphy\"\n  speakers:\n    - Kevin Murphy\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-15\"\n  published_at: \"2023-03-01\"\n  slides_url: \"https://speakerdeck.com/kevinmurphy/anyone-can-play-guitar\"\n  description: |-\n    I've got the blues. I've been looking for the perfect guitar tone, but haven't found it. To amp up my mood, let's teach a computer to play the guitar through an amplifier.\n\n    Let's string together object-oriented principles to orchestrate a blues shuffle. We'll model our domain with the help of inheritance, composition, and dependency injection. This talk will strike a chord with you, whether you've strummed a guitar before or not.\n  video_provider: \"youtube\"\n  video_id: \"1fIPv-vOSj0\"\n\n- id: \"rose-wiegley-rubyconf-2022-mini\"\n  title: \"Ruby Office Hours with Shopify Engineering\"\n  raw_title: \"RubyConf Mini 2022: Ruby Office Hours with Shopify Engineering by Rose Wiegley, Ufuk Kayserilioglu\"\n  speakers:\n    - Rose Wiegley\n    - Ufuk Kayserilioglu\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-16\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Curious about Shopify’s relationship with Ruby? Got questions on projects Shopify Ruby on Rails Engineers are currently working on? Join Rose Wiegley (Sr Staff Developer), Ufuk Kayserilioglu (Production Engineering Manager), and other Shopify Engineers for a 30-minute office hours session dedicated to answering your questions on Ruby, Shopify’s relationship with Ruby, and life at Shopify!\n  video_provider: \"youtube\"\n  video_id: \"37DkMimLG4A\"\n\n- id: \"julia-evans-rubyconf-2022-mini\"\n  title: \"Keynote: Learning DNS\"\n  raw_title: \"RubyConf Mini 2022: Keynote: Learning DNS by Julia Evans\"\n  speakers:\n    - Julia Evans\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-16\"\n  published_at: \"2023-03-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"HoG2T0aJvfY\"\n\n- id: \"christopher-aji-slater-rubyconf-2022-mini\"\n  title: \"Zen and the Art of Incremental Automation\"\n  raw_title: \"RubyConf Mini 2022: Zen and the Art of Incremental Automation by Aji Slater\"\n  speakers:\n    - Christopher \"Aji\" Slater\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-16\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Automation doesn’t have to be all or nothing. Automating manual processes is a practice that one can employ via simple principles. Broad enough to be applied to a range of workflows, flexible enough to be tailored to an individual’s personal development routines; these principles are not in themselves complex, and can be performed regularly in the day to day of working in a codebase.\n    Learn how to cultivate habits and a culture of incremental automation so even if the goal is not a full self-service suite of automated tools, your team can begin a journey away from friction and manual tasks.\n  video_provider: \"youtube\"\n  video_id: \"I2b1h1gVOfQ\"\n\n- id: \"kevin-newton-rubyconf-2022-mini\"\n  title: \"Syntax Tree\"\n  raw_title: \"RubyConf Mini 2022: Syntax Tree by Kevin Newton\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-16\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Syntax Tree is a new toolkit for interacting with the Ruby parse tree. It can be used to analyze, inspect, debug, and format your Ruby code. In this talk we'll walk through how it works, how to use it in your own applications, and the exciting future possibilities enabled by Syntax Tree.\n  video_provider: \"youtube\"\n  video_id: \"Ieq6SKtYJD4\"\n\n- id: \"lightning-talks-rubyconf-2022-mini\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf Mini 2022: Lightning Talks\"\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"IfzO_yyiYmw\"\n  talks:\n    - title: \"Lightning Talk: Dissecting Rails - A Different Approach to Learning Rails\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"ratnadeep-deshmane-lighting-talk-rubyconf-2022-mini\"\n      video_id: \"ratnadeep-deshmane-lighting-talk-rubyconf-2022-mini\"\n      video_provider: \"parent\"\n      speakers:\n        - Ratnadeep Deshmane\n\n    - title: \"Lightning Talk: Presenting The 'Who You Gonna Call' Paper by Sophie Kaleba et al.\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"chris-seaton-lighting-talk-rubyconf-2022-mini\"\n      video_id: \"chris-seaton-lighting-talk-rubyconf-2022-mini\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Seaton\n\n    - title: \"Lightning Talk: What open source software can learn from co-operatives\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"nick-quaranto-lighting-talk-rubyconf-2022-mini\"\n      video_id: \"nick-quaranto-lighting-talk-rubyconf-2022-mini\"\n      video_provider: \"parent\"\n      speakers:\n        - Nick Quaranto\n\n    - title: \"Lightning Talk: Coding with Ruby\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"keith-bennett-lighting-talk-rubyconf-2022-mini\"\n      video_id: \"keith-bennett-lighting-talk-rubyconf-2022-mini\"\n      video_provider: \"parent\"\n      speakers:\n        - Keith Bennett\n\n    - title: \"Lightning Talk: Church Numerals\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jo-ha-lighting-talk-rubyconf-2022-mini\"\n      video_id: \"jo-ha-lighting-talk-rubyconf-2022-mini\"\n      video_provider: \"parent\"\n      speakers:\n        - Jo Ha # TODO: double-check name\n\n    - title: \"Lightning Talk: Whimsical Features & Junior Developers\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"max-wofford-lighting-talk-rubyconf-2022-mini\"\n      video_id: \"max-wofford-lighting-talk-rubyconf-2022-mini\"\n      video_provider: \"parent\"\n      speakers:\n        - Max Wofford\n\n- id: \"barbara-tannenbaum-rubyconf-2022-mini\"\n  title: \"Keynote: Persuasive Communication\"\n  raw_title: \"RubyConf Mini 2022: Keynote by Barbara Tannenbaum\"\n  speakers:\n    - Barbara Tannenbaum\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-15\"\n  published_at: \"2023-03-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"JpimJspmess\"\n\n- id: \"jeremy-smith-rubyconf-2022-mini\"\n  title: \"Solo: Building Successful Web Apps By Your Lonesome\"\n  raw_title: \"RubyConf Mini 2022: Solo: Building Successful Web Apps By Your Lonesome by Jeremy Smith\"\n  speakers:\n    - Jeremy Smith\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-15\"\n  published_at: \"2023-03-01\"\n  slides_url: \"https://speakerdeck.com/jeremysmithco/solo-building-successful-web-apps-by-your-lonesome\"\n  description: |-\n    Whether by choice or by circumstance, you may find yourself developing a web application alone. Congratulations! You've got the house to yourself and no one telling you what to do. But at the same time, there's no one to share the burden or make up for your shortcomings. How do you build well and ensure project success? We'll look at the pros and cons of working alone, what kinds of projects are well-suited to solo development, strategies for professional growth, and development and operational processes that will save you time and help you sleep better at night.\n  video_provider: \"youtube\"\n  video_id: \"Rr871vmV4YM\"\n\n- id: \"stephanie-minn-rubyconf-2022-mini\"\n  title: \"Empathetic Pair Programming with Nonviolent Communication\"\n  raw_title: \"RubyConf Mini 2022: Empathetic Pair Programming with Nonviolent Communication by Stephanie Minn\"\n  speakers:\n    - Stephanie Minn\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-15\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Pair programming is intimate. It’s the closest collaboration we do as software developers. When it goes well, it feels great! But when it doesn’t, you might be left feeling frustrated, discouraged, or withdrawn.\n\n    To navigate the vulnerability of sharing our keyboard and code, let’s learn about nonviolent communication (NVC), an established practice of deep listening to ourselves and others. We’ll cover real-life examples and how to apply the four tenets of NVC– observations, feelings, needs, and requests– to bring more joy and fulfillment the next time you pair.\n  video_provider: \"youtube\"\n  video_id: \"Tzlyrra00Z0\"\n\n- id: \"emily-samp-rubyconf-2022-mini\"\n  title: \"Sponsor Panel\"\n  raw_title: \"RubyConf Mini 2022: Sponsor Panel\"\n  speakers:\n    - Emily Samp\n    - Geoffrey Lessel\n    - Ryan Laughlin\n    - Ufuk Kayserilioglu\n    - Someone at Shopify\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"exxUz9k03s4\"\n\n- id: \"brittany-martin-rubyconf-2022-mini-panel-podcast\"\n  title: \"Panel: Podcast\"\n  raw_title: \"RubyConf Mini 2022: Podcast Panel\"\n  speakers:\n    - Brittany Martin\n    - Julie J\n    - Drew Bragg\n    - Joël Quenneville\n    - Andy Croll\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"gOq7PJ-0ngA\"\n\n- id: \"drew-bragg-rubyconf-2022-mini\"\n  title: \"Who Wants to be a Ruby Engineer?\"\n  raw_title: \"RubyConf Mini 2022: Who Wants to be a Ruby Engineer? by Drew Bragg\"\n  speakers:\n    - Drew Bragg\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Welcome to the Ruby game show where one lucky contestant tries to guess the output of a small bit of Ruby code. Sound easy? Here's the challenge: the snippets come from some of the weirdest parts of the Ruby language.  The questions aren't easy. Get enough right to be crowned a (some sort of something) Ruby Engineer and win a fabulous, mysterious prize.\n  video_provider: \"youtube\"\n  video_id: \"JoZo9uGuXQw\"\n\n- id: \"jared-norman-rubyconf-2022-mini\"\n  title: \"TDD on the Shoulders of Giants\"\n  raw_title: \"RubyConf Mini 2022: TDD on the Shoulders of Giants by Jared Norman\"\n  speakers:\n    - Jared Norman\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Getting started with TDD is hard enough without having to also navigate a programming language barrier. Many of the best books on testing focus on very different languages like Java, making it tricky to apply their advice in Ruby, especially if you're new to testing. I'll go through the most important practices and techniques that we can pull from the testing literature and show how they can be applied in your day-to-day Ruby development. You'll learn how to make the most of testing in Ruby using the patterns, practices, and techniques that popularized TDD in the first place.\n  video_provider: \"youtube\"\n  video_id: \"V8Sx8h7KZZQ\"\n\n- id: \"kirk-haines-rubyconf-2022-mini\"\n  title: \"Crystal for Rubyists\"\n  raw_title: \"RubyConf Mini 2022: Crystal for Rubyists by Kirk Haines\"\n  speakers:\n    - Kirk Haines\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-15\"\n  published_at: \"2023-03-01\"\n  description: |-\n    Crystal is a Ruby-like compiled language that was originally built using Ruby. Its syntax is remarkably similar to Ruby's, which generally makes it straightforward for a Ruby programmer to start using Crystal. There are some notable, and interesting differences between the languages, however. In this workshop, let's learn some Crystal while we learn a little about the similarities and the differences between the two languages.\n  video_provider: \"youtube\"\n  video_id: \"YmsSmp4yjOc\"\n\n- id: \"jenny-shen-rubyconf-2022-mini\"\n  title: \"RubyGems.org MFA: The Past, Present and Future\"\n  raw_title: \"RubyConf Mini 2022: RubyGems.org MFA: The Past, Present and Future by Jenny Shen\"\n  speakers:\n    - Jenny Shen\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-16\"\n  published_at: \"2023-03-01\"\n  description: |-\n    What do Ruby’s rest-client, Python’s ctx, and npm’s ua-parser-js have in common?\n\n    They all suffered account takeovers that were preventable. Attackers aim to take control of a legitimate RubyGems.org user account and then use it to upload malicious code. It might dial home. It might steal your keys. Perhaps it will encrypt your disk. Or all of the above! Don’t you wish it couldn’t happen?\n\n    MFA prevents 99.9% of account takeover attacks. Come learn about MFA, the history of RubyGems.org MFA support, the new MFA policy for top gems, and what’s on the horizon.\n  video_provider: \"youtube\"\n  video_id: \"YxVGMvwJsHQ\"\n\n- id: \"nadia-odunayo-rubyconf-2022-mini\"\n  title: \"The Case Of The Vanished Variable - A Ruby Mystery Story\"\n  raw_title: \"RubyConf Mini 2022: The Case Of The Vanished Variable - A Ruby Mystery Story by Nadia Odunayo\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-16\"\n  published_at: \"2023-03-01\"\n  description: |-\n    After a stressful couple of days at work, Deirdre Bug is looking forward to a quiet evening in. But her plans are thwarted when the phone rings. “I know I’m the last person you want to hear from…but...I need your help!” Follow Deirdre as she embarks on an adventure that features a looming Demo Day with serious prize money up for grabs, a trip inside the walls of one of the Ruby community’s most revered institutions, and some broken code that appears to be much more simple than meets the eye.\n  video_provider: \"youtube\"\n  video_id: \"a63aSvHu18c\"\n\n- id: \"jess-hottenstein-rubyconf-2022-mini\"\n  title: \"Declare Victory with Class Macros\"\n  raw_title: \"RubyConf Mini 2022: Splitwise Sponsor Session: Declare Victory with Class Macros by Jess Hottenstein\"\n  speakers:\n    - Jess Hottenstein\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: |-\n    How can we write classes that are easy to understand? How can we write Ruby in a declarative way? How can we use metaprogramming without introducing chaos?\n\n    Come learn the magic behind the first bit of metaprogramming we all encounter with Ruby - attr_reader. From there, we can learn how different gems use class macros to simplify our code. Finally, we’ll explore multiple ways we can make our own class macros to make our codebase easier to read and extend.\n  video_provider: \"youtube\"\n  video_id: \"aMfHqajixeM\"\n\n- id: \"rose-wiegley-rubyconf-2022-mini-keynote-leading-from-where-you\"\n  title: \"Keynote: Leading From Where You Are\"\n  raw_title: \"RubyConf Mini 2022: Keynote by Rose Wiegley\"\n  speakers:\n    - Rose Wiegley\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-17\"\n  published_at: \"2023-03-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"c_HhfehMBHE\"\n\n- id: \"kevin-menard-rubyconf-2022-mini\"\n  title: \"The Three-Encoding Problem\"\n  raw_title: \"RubyConfMini 2022: The Three-Encoding Problem by Kevin Menard\"\n  speakers:\n    - Kevin Menard\n  event_name: \"RubyConf 2022 Mini\"\n  date: \"2022-11-16\"\n  published_at: \"2023-03-01\"\n  description: |-\n    You’ve probably heard of UTF-8 and know about strings, but did you know that Ruby supports more than 100 other encodings? In fact, your application probably uses three encodings without you realizing it. Moreover, encodings apply to more than just strings. In this talk, we’ll take a look at Ruby’s fairly unique approach to encodings and better understand the impact they have on the correctness and performance of our applications. We’ll take a look at the rich encoding APIs Ruby provides and by the end of the talk, you won’t just reach for force_encoding when you see an encoding exception.\n  video_provider: \"youtube\"\n  video_id: \"eoD0MsBpDXk\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2023/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZ13yKsi3ID6a4MWDxSw-LE\"\ntitle: \"RubyConf 2023\"\nkind: \"conference\"\nlocation: \"San Diego, CA, United States\"\ndescription: |-\n  RubyConf is the annual fall conference for Ruby enthusiasts to gather and enjoy talks about new projects, meet and network with other Ruby developers, and hear from the community's leading minds.\npublished_at: \"2023-12-19\"\nstart_date: \"2023-11-13\"\nend_date: \"2023-11-15\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2023\nbanner_background: \"#FFF2FA\"\nfeatured_background: \"#FFF2FA\"\nfeatured_color: \"#5F6FBF\"\ncoordinates:\n  latitude: 32.7629019\n  longitude: -117.1677861\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2023/venue.yml",
    "content": "---\nname: \"Town and Country Resort\"\n\naddress:\n  street: \"500 Hotel Circle North\"\n  city: \"San Diego\"\n  region: \"California\"\n  postal_code: \"92108\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"500 Hotel Cir N, San Diego, CA 92108, USA\"\n\ncoordinates:\n  latitude: 32.7629019\n  longitude: -117.1677861\n\nmaps:\n  google: \"https://maps.google.com/?q=Town+and+Country+Resort,32.7629019,-117.1677861\"\n  apple: \"https://maps.apple.com/?q=Town+and+Country+Resort&ll=32.7629019,-117.1677861\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=32.7629019&mlon=-117.1677861\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2023\"\n  title: \"Keynote: Lessons from the Past\"\n  raw_title: 'RubyConf 2023 - Keynote by Yukihiro \"Matz\" Matsumoto'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  description: |-\n    In this pre-recorded presentation, Matz shares insights into Ruby and answers questions submitted by the Ruby community.\n  video_provider: \"youtube\"\n  video_id: \"Dxy9UBoZjTQ\"\n\n- id: \"jol-quenneville-rubyconf-2023\"\n  title: \"Which Time Is It?\"\n  raw_title: \"RubyConf 2023 - Which Time Is It? by Joël Quenneville\"\n  speakers:\n    - Joël Quenneville\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  slides_url: \"https://speakerdeck.com/joelq/which-time-is-it\"\n  description: |-\n    Can you add two time values together? Yes. No. Not so fast!\n\n    Reset your clocks and join me on a graphical tour of time itself. You'll discover how \"time\" is more than a single thing, build intuition around what different operations mean, and get a sense of when some operations are nonsensical. You'll leave with a better mental model for thinking about time and avoiding subtle time-related bugs in your own code.\n  video_provider: \"youtube\"\n  video_id: \"54Hs2E7zsQg\"\n\n- id: \"puneet-khushwani-rubyconf-2023\"\n  title: \"Finding a needle in the haystack - Debugging performance issues\"\n  raw_title: \"RubyConf 2023 - Finding a needle in the haystack - Debugging performance issues by Puneet Khushwani\"\n  speakers:\n    - Puneet Khushwani\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  description: |-\n    What should a developer do if suddenly one day they get assigned to debug a Sev1 performance issue?\n\n    From our experience, sometimes finding the problem itself is very difficult and thus takes a lot of time. In this talk we will talk about some profilers which one can use to get visibility into what’s happening while executing code. These profilers may not always give us the exact root-cause but will always be able to give us directions to debug further.\n\n    To also make things more relatable, as a case-study, we would be using a real problem which our team dealt with recently while upgrading the Ruby version of one of the largest monolith Rails application.\n  video_provider: \"youtube\"\n  video_id: \"EMiuLfBWx1I\"\n\n- id: \"jemma-issroff-rubyconf-2023\"\n  title: \"Popping Into CRuby\"\n  raw_title: \"RubyConf 2023 - Popping Into CRuby by Jemma Issroff\"\n  speakers:\n    - Jemma Issroff\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  description: |-\n    Ever wondered why a line of Ruby code with no side effects has no performance impact? This talk will explain the concept of \"popped\" instruction sequences, demystifying how CRuby works behind the scenes to avoid running unnecessary code. We'll delve into parsing, compiling, abstract syntax trees, and instruction sequence. You’ll leave this talk with a deeper understanding of Ruby's inner workings and why they matter.\n  video_provider: \"youtube\"\n  video_id: \"8R78YHyQ9ko\"\n\n- id: \"paul-reece-rubyconf-2023\"\n  title: \"Get your Data prod ready, Fast, with Ruby Polars!\"\n  raw_title: \"RubyConf 2023 - Get your Data prod ready, Fast, with Ruby Polars! by Paul Reece\"\n  speakers:\n    - Paul Reece\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  description: |-\n    Imagine you receive a CSV of data that has over 500,000 rows and 100 columns. Data is randomly missing in some places, some of the column names are wrong, and you have mixed Data types in some of the columns.  Correcting and cleaning that data by hand could take hours. Fear not! There is a better and faster way.  We will look into using Ruby Polars, a gem written in Rust with a Ruby API, to wrangle and clean tabular data to get it prod ready. By learning some basic operations used in Polars you can greatly expedite the import process of CSV files and API Data. Whether your goal is to use the Data in an existing application or use it in a Ruby AI/Machine learning project(since cleaning Data is a vital first step in this process), this talk will get you well on your way!\n  video_provider: \"youtube\"\n  video_id: \"QjTLx7po1jY\"\n\n- id: \"samuel-giddins-rubyconf-2023\"\n  title: \"State of the RubyGems\"\n  raw_title: \"RubyConf 2023 - State of the RubyGems by Samuel Giddins\"\n  speakers:\n    - Samuel Giddins\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  description: |-\n    Part history, part state of the union, and part roadmap for community feedback, this talk will cover how Ruby Central came to have an open source team, what we have been doing for the last 8.5 years, highlights from our work in 2023, and a deep dive into the ideas that we would like to get onto our road map. If you want to know more about Ruby Central, RubyGems, or project planning in long-running open source projects, this is the talk for you.\n  video_provider: \"youtube\"\n  video_id: \"wV9JpikPM9g\"\n\n- id: \"collin-donnell-rubyconf-2023\"\n  title: \"Rooftop Ruby podcast\"\n  raw_title: \"RubyConf 2023 - Rooftop Ruby podcast by Collin Donnell\"\n  speakers:\n    - Collin Donnell\n    - Joel Drapper\n    - Roman Turner\n    - Catherine Ricafort McCreary\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  description: |-\n    Live - Rooftop Ruby podcast\n  video_provider: \"youtube\"\n  video_id: \"_RSLyjYeNTU\"\n\n- id: \"murray-steele-rubyconf-2023\"\n  title: \"Re-interpreting Data\"\n  raw_title: \"RubyConf 2023 - Re-interpreting Data by Murray Steele\"\n  speakers:\n    - Murray Steele\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  description: |-\n    A talk about turning data into other data. Not particularly useful data, but imagine if you could listen to a jpeg, or see what an executable file looked like, or turn a zip file into an orchestral score?\n\n    Some time ago I stumbled across the header description for WAV files and wondered: what if I took a file and calculated the appropriate WAV file header for it, could I hear my data? Turns out, yes, you can. You probably don’t want to, but you can! In this talk we’ll explore how it works for WAV files, BMP files and MIDI files. Along the way we’ll learn a lot about using ruby to manipulate raw bytes and bits of data, but also we’ll hear a README file, view an executable, and listen to the ruby interpreter itself!\n  video_provider: \"youtube\"\n  video_id: \"0MrgQ7TzRUc\"\n\n- id: \"kevin-newton-rubyconf-2023\"\n  title: \"The Future of Understanding Ruby Code\"\n  raw_title: \"RubyConf 2023 - The Future of Understanding Ruby Code by Kevin Newton\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  description: |-\n    For decades, the Ruby community has been fractured in the way that it parses and understands Ruby code. After countless tools have been developed and person-hours have been invested, we still don't have a common language for understanding Ruby code. No longer! Starting in Ruby 3.3, we will have a single API for parsing and understanding Ruby code. This talk will cover the history of how we got here, what is getting built today, and what you can expect from this exciting future.\n  video_provider: \"youtube\"\n  video_id: \"F9X5uJO9PV8\"\n\n- id: \"jenny-shen-rubyconf-2023\"\n  title: \"Demystifying the Ruby package ecosystem\"\n  raw_title: \"RubyConf 2023 - Demystifying the Ruby package ecosystem by Jenny Shen\"\n  speakers:\n    - Jenny Shen\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  description: |-\n    A Ruby application is built on a foundation of its gems. But how does a gem get from the package repository to running in your project? RubyGems and Bundler does an excellent job in removing the complexities of gem resolution and installation so developers can focus on building great software. Let’s do a deep dive on how these tools seamlessly manage the dependencies you need to get your project off the ground!\n\n    In this talk, we’ll be taking a look at the inner workings of the Ruby package ecosystem. This includes:\n    - The processes involved in installing gems from a Gemfile\n    - Insights into debugging gems within a Rails application\n    - Ensuring you're selecting the right gems to avoid security risks\n  video_provider: \"youtube\"\n  video_id: \"fkfCXFxJW08\"\n\n- id: \"christopher-aji-slater-rubyconf-2023\"\n  title: \"The Unbreakable Code Whose Breaking Won WWII\"\n  raw_title: \"RubyConf 2023 - The Unbreakable Code Whose Breaking Won WWII by Aji Slater\"\n  speakers:\n    - Christopher \"Aji\" Slater\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-19\"\n  published_at: \"2024-01-01\"\n  description: |-\n    After the last carrier pigeon but before digital encryption algorithms, there was the Enigma machine. An ingenious piece of pre-atomic age technology encoded German military secrets during World War II, baffling code-breakers with mere physical rotors, and switches, without elliptic curves or private keys.\n\n    Delve into object-oriented programming and bring the Enigma machine back to life with an emulator built in Ruby. Unravel the secrets of this nigh-unbreakable cipher device, witness OO principles unlock its mysteries, discover the power and versatility of the patterns we use as developers and how they mirror the Enigma's inner workings.\n  video_provider: \"youtube\"\n  video_id: \"soB5h2t2HO4\"\n\n- id: \"tim-riley-rubyconf-2023\"\n  title: \"Livin’ La Vida Hanami\"\n  raw_title: \"RubyConf 2023 - Livin’ La Vida Hanami by Tim Riley\"\n  speakers:\n    - Tim Riley\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-20\"\n  published_at: \"2024-01-01\"\n  description: |-\n    Upside, inside out, Hanami 2.0 is out!\n\n    This release brings new levels of polish and power to a framework that you can use for Ruby apps of all shapes and sizes.\n\n    Together we’ll take a first look at Hanami, then build our very own app, and discover how Hanami apps can remain a joy to develop even as they grow.\n\n    Once you’ve had a taste of it you’ll never be the same!\n  video_provider: \"youtube\"\n  video_id: \"L35MPfmtJZM\"\n\n- id: \"sharon-steed-rubyconf-2023\"\n  title: \"Keynote: Making Empathy Actionable\"\n  raw_title: \"RubyConf 2023 - Keynote by Sharon Steed\"\n  speakers:\n    - Sharon Steed\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-20\"\n  published_at: \"2024-01-01\"\n  description: |-\n    Sharon Steed is the founder of Communilogue, an empathy consultancy that teaches audiences how to make empathy actionable so individuals can better connect with their coworkers; companies can better understand their consumers; and everyone can bring more humanity into the office.\n  video_provider: \"youtube\"\n  video_id: \"wkOh5yCLX60\"\n\n- id: \"saron-yitbarek-rubyconf-2023\"\n  title: \"Keynote: Our superpower\"\n  raw_title: \"RubyConf 2023 - Keynote by Saron Yitbarek\"\n  speakers:\n    - Saron Yitbarek\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-20\"\n  published_at: \"2024-01-01\"\n  description: |-\n    Saron Yitbarek shares stories and lessons she's learned from years of helping new developers transition into tech careers and building developer communities.\n  video_provider: \"youtube\"\n  video_id: \"07gTTE4NPZk\"\n\n- id: \"meagan-waller-rubyconf-2023\"\n  title: \"Ruby on Rack: The Magic Between Request and Response\"\n  raw_title: \"RubyConf 2023 - Ruby on Rack: The Magic Between Request and Response by Meagan Waller\"\n  speakers:\n    - Meagan Waller\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-20\"\n  published_at: \"2024-01-01\"\n  description: |-\n    Are you ready to embark on an expedition into the core of Ruby web applications? Well, get ready, because it's time to delve into  web development with Rack—the powerhouse that fuels popular Ruby web frameworks like Rails and Sinatra. In this captivating talk, we'll plunge deep into the inner workings of Rack, the unsung hero of web development. We'll uncover its secrets, bask in its versatility, and summon the magic of custom Rack middleware—where session management, authentication, and caching reside. For developers at all levels, this talk offers practical insights and fresh perspectives. Equip yourself with the prowess to wield Rack's middleware magic, making your development journey more efficient and enjoyable.\n  video_provider: \"youtube\"\n  video_id: \"cJ7V9Mg1vzc\"\n\n- id: \"jeremy-evans-rubyconf-2023\"\n  title: \"The Second Oldest Bug\"\n  raw_title: \"RubyConf 2023 - The Second Oldest Bug by Jeremy Evans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-20\"\n  published_at: \"2024-01-01\"\n  description: |-\n    Historically, calling a method with a very large number of arguments resulted in a core dump. In Ruby 1.9, this was improved to instead raise SystemStackError.  In Ruby 2.2, the issue was fixed for methods defined in Ruby.  However, in Ruby 3.2, this is still an issue for methods defined in C.  This issue was reported as a bug over 12 years ago, and was the second oldest open bug in Ruby's bug tracker.  Come learn about stacks, heaps, argument handling during method dispatch, and how we fixed this bug in Ruby 3.3.\n  video_provider: \"youtube\"\n  video_id: \"cIKYxSLCyX0\"\n\n- id: \"garen-torikian-rubyconf-2023\"\n  title: \"Wrapping Rust in Ruby\"\n  raw_title: \"RubyConf 2023 - Wrapping Rust in Ruby by Garen Torikian\"\n  speakers:\n    - Garen Torikian\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-20\"\n  published_at: \"2024-01-01\"\n  description: |-\n    Ruby is slow. Despite improvements over the years, the language will never be as fast as a compiled language. To compensate for this, whenever Ruby developers need to run performance critical code, it's not uncommon for them to interoperate with a library written in C. Dozens of well known gems, such as Nokogiri and Bcrypt, already do this. But with C comes other problems: how can we ensure that our low-level code is safe from memory leaks and other security vulnerabilities? In this talk, I'll introduce the oxidize-rb project, which is a suite of open source tools which makes it possible to call Rust libraries from within Ruby. I'll also demonstrate how simple it is to incorporate Rust code (including Cargo dependencies) into a Ruby gem.\n  video_provider: \"youtube\"\n  video_id: \"l7TPj7dRHso\"\n\n- id: \"alan-ridlehoover-rubyconf-2023\"\n  title: \"The Secret Ingredient: How To Understand and Resolve Just About Any Flaky Test\"\n  raw_title: \"RubyConf 2023 - The Secret Ingredient: How To Understand and Resolve Just... by Alan Ridlehoover\"\n  speakers:\n    - Alan Ridlehoover\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-20\"\n  published_at: \"2024-01-01\"\n  description: |-\n    The Secret Ingredient: How To Understand and Resolve Just About Any Flaky Test by Alan Ridlehoover\n\n    Flaky tests are an inscrutable bane. Hard to understand. Annoying. And, so frustrating! My personal nemesis is Daylight Saving Time. I can’t tell you how many times I’ve tripped over it. Let’s just say I was well into the “shame on me” part of that relationship, until I discovered the secret ingredient that nearly all flaky tests have in common. Turns out they only seem inscrutable. It really is possible to understand and resolve just about any flaky test.\n  video_provider: \"youtube\"\n  video_id: \"De3-v54jrQo\"\n\n- id: \"phil-crissman-rubyconf-2023\"\n  title: \"How Programs Learn, and What Happens After They're Built\"\n  raw_title: \"RubyConf 2023 - How Programs Learn, and What Happens After They're Built by Phil Crissman\"\n  speakers:\n    - Phil Crissman\n  event_name: \"RubyConf 2023\"\n  date: \"2023-12-20\"\n  published_at: \"2024-01-01\"\n  description: |-\n    In 1994, Stewart Brand published a book called \"How Buildings Learn, and What Happens After They're Built\". As well as a fascinating account of architecture and the history of various buildings and building styles, some ideas from this book were inspirational to the famous \"Big Ball of Mud\" paper, by Brian Foote and Joseph Yoder.\n\n    Can we learn anything about building software systems from the observations in Brand's book and the Big Ball of Mud paper? Spoiler alert: yes, I think so! Let's talk about them.\n  video_provider: \"youtube\"\n  video_id: \"F_RvmYZAMJw\"\n\n- id: \"lightning-talks-rubyconf-2023\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf 2023 - Lightning Talks\"\n  description: |-\n    Lightning talks are short presentation (up to 5 mins) delivered by different people in a single session. Conference attendees are welcome to sign up near Check In during the conference.\n  date: \"2023-12-20\"\n  published_at: \"2024-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"JreuXFz8MpE\"\n  talks:\n    - title: \"Lightning Talks Intro\"\n      start_cue: \"00:17\"\n      end_cue: \"01:06\"\n      thumbnail_cue: \"00:39\"\n      id: \"lighting-talk-intro-rubyconf-2023\"\n      video_id: \"lighting-talk-intro-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Erik Guzman\n\n    - title: \"Lightning Talk: Metaprogramming in Ruby - or how to reduce boilerplate code using RM\"\n      start_cue: \"01:06\"\n      end_cue: \"06:08\"\n      id: \"anna-lopukhina-lighting-talk-rubyconf-2023\"\n      video_id: \"anna-lopukhina-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Anna Lopukhina\n\n    - title: \"Lightning Talk: Contributing to a gem I love & The power of Community\"\n      start_cue: \"06:08\"\n      end_cue: \"08:47\"\n      id: \"salomon-charabati-lighting-talk-rubyconf-2023\"\n      video_id: \"salomon-charabati-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Salomón Charabati\n\n    - title: \"Lightning Talk: Briding the gap between technology and creativity\"\n      start_cue: \"08:47\"\n      end_cue: \"13:18\"\n      id: \"jade-stewart-lighting-talk-rubyconf-2023\"\n      video_id: \"jade-stewart-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Jade Stewart\n\n    - title: \"Lightning Talk: How to Debug Your Body: A Rubyists Guide to Wellness & Self-Care\"\n      start_cue: \"13:18\"\n      end_cue: \"17:25\"\n      id: \"amanda-vikdal-lighting-talk-rubyconf-2023\"\n      video_id: \"amanda-vikdal-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Amanda Vikdal\n\n    - title: \"Lightning Talk: Simple Scripts with Ruby - Automate boring tasks to sparkjoy\"\n      start_cue: \"17:25\"\n      end_cue: \"21:45\"\n      id: \"jarrod-reyes-lighting-talk-rubyconf-2023\"\n      video_id: \"jarrod-reyes-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Jarrod Reyes\n\n    - title: \"Lightning Talk: Fear is the Way\"\n      start_cue: \"21:45\"\n      end_cue: \"25:41\"\n      id: \"eli-barreto-lighting-talk-rubyconf-2023\"\n      video_id: \"eli-barreto-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Eli Barreto\n\n    - title: \"Lightning Talk: Imagining a Fully Ruby Frontend with RERB\"\n      start_cue: \"25:41\"\n      end_cue: \"30:47\"\n      id: \"seong-heon-jung-lighting-talk-rubyconf-2023\"\n      video_id: \"seong-heon-jung-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Seong-Heon Jung\n\n    - title: \"Lightning Talk: Resilience Under Fire - Sticking With The Job Search Especially When It's Hard\"\n      start_cue: \"30:47\"\n      end_cue: \"35:21\"\n      id: \"joshua-maurer-lighting-talk-rubyconf-2023\"\n      video_id: \"joshua-maurer-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Joshua Maurer\n\n    - title: \"Lightning Talk: Intro to PEDAC - A Problem Solving Approach Using Ruby\"\n      start_cue: \"35:21\"\n      end_cue: \"40:20\"\n      id: \"eric-halverson-lighting-talk-rubyconf-2023\"\n      video_id: \"eric-halverson-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Eric Halverson\n\n    - title: \"Lightning Talk: Module Mixins - A Kautionary Tale\"\n      start_cue: \"40:20\"\n      end_cue: \"45:10\"\n      id: \"fito-von-zastrow-lighting-talk-rubyconf-2023\"\n      video_id: \"fito-von-zastrow-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Fito von Zastrow\n\n    - title: \"Lightning Talk: What is noira? & why we're designing for junior devs\"\n      start_cue: \"45:10\"\n      end_cue: \"50:10\"\n      thumbnail_cue: \"45:11\"\n      id: \"paul-lemus-lighting-talk-rubyconf-2023\"\n      video_id: \"paul-lemus-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Paul Lemus\n\n    - title: \"Lightning Talk: Experimenting in Production\"\n      start_cue: \"50:10\"\n      end_cue: \"53:56\"\n      id: \"gary-tou-lighting-talk-rubyconf-2023\"\n      video_id: \"gary-tou-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      description: |-\n        Gems: `scientist` + `lab_tech`\n      speakers:\n        - Gary Tou\n\n    - title: \"Lightning Talk: Ruby Conferences + Baltic Ruby\"\n      start_cue: \"53:56\"\n      end_cue: \"58:25\"\n      id: \"sergey-sergyenko-lighting-talk-rubyconf-2023\"\n      video_id: \"sergey-sergyenko-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Sergy Sergyenko\n\n    - title: \"Lightning Talk: Making online identity verification less awful\"\n      start_cue: \"58:25\"\n      end_cue: \"01:03:29\"\n      id: \"mike-toppa-lighting-talk-rubyconf-2023\"\n      video_id: \"mike-toppa-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Mike Toppa\n\n    - title: \"Lightning Talk: The Opportunity of Failure\"\n      start_cue: \"01:03:29\"\n      end_cue: \"01:07:06\"\n      id: \"heather-roulston-lighting-talk-rubyconf-2023\"\n      video_id: \"heather-roulston-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Heather Roulston\n\n    - title: \"Lightning Talk: Grind Your Engineering Org to a Halt With This One Simple Trick - or: A Cautionary Tale on Depdency Management\"\n      start_cue: \"01:07:06\"\n      end_cue: \"01:11:05\"\n      id: \"ryan-erickson-lighting-talk-rubyconf-2023\"\n      video_id: \"ryan-erickson-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Ryan Erickson\n\n    - title: \"Lightning Talk: Good Bad Quick Code - or: When You're In A Rush, How to Not Hate Yourself Later\"\n      start_cue: \"01:11:05\"\n      end_cue: \"01:16:05\"\n      id: \"nicholas-barone-lighting-talk-rubyconf-2023\"\n      video_id: \"nicholas-barone-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Nicholas Barone\n\n    - title: \"Lightning Talk: Getting good - At being bad a things\"\n      start_cue: \"01:16:05\"\n      end_cue: \"01:20:17\"\n      thumbnail_cue: \"01:16:06\"\n      id: \"victoria-guido-lighting-talk-rubyconf-2023\"\n      video_id: \"victoria-guido-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Victoria Guido\n\n    - title: \"Lightning Talk: My Campervan\"\n      start_cue: \"01:20:17\"\n      end_cue: \"01:25:13\"\n      thumbnail_cue: \"01:20:37\"\n      id: \"daniel-azuma-lighting-talk-rubyconf-2023\"\n      video_id: \"daniel-azuma-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Daniel Azuma\n\n    - title: \"Lightning Talk: Let's Talk About Numbers\"\n      start_cue: \"01:25:13\"\n      end_cue: \"01:28:55\"\n      id: \"xiujiao-gao-lighting-talk-rubyconf-2023\"\n      video_id: \"xiujiao-gao-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Xiujiao Gao\n\n    - title: \"Lightning Talk: Reflections & Ruminations\"\n      start_cue: \"01:28:55\"\n      end_cue: \"01:35:18\"\n      id: \"wayne-e-seguin-lighting-talk-rubyconf-2023\"\n      video_id: \"wayne-e-seguin-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Wayne E. Seguin\n\n    - title: \"Lightning Talk: You Should Livestream\"\n      start_cue: \"01:35:18\"\n      end_cue: \"01:40:22\"\n      thumbnail_cue: \"01:35:20\"\n      id: \"rachael-wright-munn-lighting-talk-rubyconf-2023\"\n      video_id: \"rachael-wright-munn-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Rachael Wright-Munn\n\n    - title: \"Lightning Talk: Frest - APIs should be actually good.\"\n      start_cue: \"01:40:22\"\n      end_cue: \"01:45:38\"\n      id: \"guyren-howe-lighting-talk-rubyconf-2023\"\n      video_id: \"guyren-howe-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Guyren Howe\n\n    - title: \"Lightning Talk: The Night Before Code Freeze\"\n      start_cue: \"01:45:38\"\n      end_cue: \"01:48:09\"\n      id: \"brandon-weaver-lighting-talk-rubyconf-2023\"\n      video_id: \"brandon-weaver-lighting-talk-rubyconf-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Brandon Weaver\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2024/cfp.yml",
    "content": "---\n- link: \"https://sessionize.com/rubyconf-2024/\"\n  open_date: \"2024-06-06\"\n  close_date: \"2024-07-22\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2024/event.yml",
    "content": "---\nid: \"rubyconf-2024\"\ntitle: \"RubyConf 2024\"\nkind: \"conference\"\nlocation: \"Chicago, IL, United States\"\ndescription: \"\"\npublished_at: \"2024-12-13\"\nstart_date: \"2024-11-13\"\nend_date: \"2024-11-15\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2024\nbanner_background: \"#05061C\"\nfeatured_background: \"#05061C\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 41.87225919999999\n  longitude: -87.624696\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2024/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users: []\n  organisations:\n    - Ruby Central\n\n- name: \"Program Chair\"\n  users:\n    - Jim Remsik\n    - Kinsey Durham Grace\n\n- name: \"Program Committee Member\"\n  users:\n    - Tess Griffin\n    - Kerri Miller\n    - Mina Slater\n    - Jenny Shih\n    - Sarah Mei\n    - Ben Sheldon\n    - Joel Hawksley\n    - Mike Perham\n\n- name: \"Ruby Central Executive Director\"\n  users:\n    - Adarsh Pandit\n\n- name: \"Ruby Central Operations Manager\"\n  users:\n    - Ally Vogel\n\n- name: \"Ruby Central Marketing Manager\"\n  users:\n    - Rhiannon Payne\n\n- name: \"Ruby Central Sponsorship Manager\"\n  users:\n    - Tom Chambers\n\n- name: \"Scholar\"\n  users:\n    - Ahmad Hassan\n    - Alexander Mitchell\n    - Elshadai Tegegn\n    - Jorja Fleming\n    - Ken Maeshima\n    - Manu Vasconcelos\n    - Muhammad USAMA Yousaf\n    - Neil Hendren\n    - Noah Durbin\n    - Sunjay Armstead\n\n- name: \"Guide\"\n  users:\n    - Chris Oliver\n    - Collin Jilbert\n    - Erin Pintozzi\n    - Frederick Cheung\n    - Jacklyn Ma\n    - Kazumi Karbowski\n    - Michael Lee\n    - Michelle Yuen\n    - Nony Dutton\n    - Rae Stanton\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2024/schedule.yml",
    "content": "# Schedule: https://rubyconf.org/schedule/\n# Embed: https://sessionize.com/api/v2/3nqsadrc/view/GridSmart?under=True\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-11-13\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Registration & Breakfast\n\n      - start_time: \"09:15\"\n        end_time: \"09:25\"\n        slots: 1\n\n      - start_time: \"09:25\"\n        end_time: \"09:27\"\n        slots: 1\n\n      - start_time: \"09:27\"\n        end_time: \"09:30\"\n        slots: 1\n\n      - start_time: \"09:30\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 4\n\n      - start_time: \"11:15\"\n        end_time: \"11:20\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 4\n\n      - start_time: \"12:00\"\n        end_time: \"12:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"12:15\"\n        end_time: \"12:45\"\n        slots: 4\n\n      - start_time: \"12:45\"\n        end_time: \"14:15\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 5\n\n      - start_time: \"15:00\"\n        end_time: \"15:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 5\n\n      - start_time: \"15:45\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 3\n\n      - start_time: \"16:30\"\n        end_time: \"16:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:45\"\n        end_time: \"17:45\"\n        slots: 1\n\n      - start_time: \"17:45\"\n        end_time: \"17:45\"\n        slots: 1\n        items:\n          - Closing\n\n  - name: \"Day 2 (Hack Day)\"\n    date: \"2024-11-14\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"13:45\"\n        slots: 3\n\n      - start_time: \"13:30\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Working Lunch\n\n      - start_time: \"15:45\"\n        end_time: \"17:45\"\n        slots: 2\n\n      - start_time: \"18:15\"\n        end_time: \"19:45\"\n        slots: 1\n\n      - start_time: \"12:20\"\n        end_time: \"14:20\"\n        slots: 1\n        items:\n          - title: \"Happy Hour & Kick it with Sidekiq at Game Night!\"\n            description: |-\n              Game night is ON! This is a B.Y.O.G. (Bring Your Own Game) special event space where you can get together, drink, snack, and play with #RubyFriends for the night. **Please NO games that include throwing or kicking objects!** Located in the Expo Spaces in Salon A Sponsored by Mike Perham (Sidekiq)\n\n  - name: \"Day 3\"\n    date: \"2024-11-15\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"08:45\"\n        slots: 1\n        items:\n          - Breakfast\n\n      - start_time: \"08:45\"\n        end_time: \"09:45\"\n        slots: 1\n\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 3\n\n      - start_time: \"10:30\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 3\n\n      - start_time: \"11:15\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 2\n\n      - start_time: \"12:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - title: \"Closing Social\"\n            description: |-\n              End the evening with your Ruby Friends with a wonderful closing reception social. We would love to have you join us for a final send-off~\n\ntracks:\n  - name: \"Supporter Talk\"\n    color: \"#E1CD00\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby\"\n      description: |-\n        Top level Ruby sponsors supporting RubyConf 2024.\n      level: 1\n      sponsors:\n        - name: \"Paypal\"\n          website: \"https://www.paypal.com/\"\n          slug: \"paypal\"\n          logo_url: \"https://rubyconf.org/images/uploads/paypal-logo-cmyk-black.png\"\n\n        - name: \"Cisco Meraki\"\n          website: \"https://meraki.cisco.com/\"\n          slug: \"ciscomeraki\"\n          logo_url: \"https://rubyconf.org/images/uploads/cisco-meraki-logo-full-color-digital.png\"\n\n    - name: \"Platinum\"\n      description: |-\n        Platinum level sponsors for RubyConf 2024.\n      level: 2\n      sponsors:\n        - name: \"Chime\"\n          website: \"https://www.chime.com/\"\n          slug: \"chime\"\n          logo_url: \"https://rubyconf.org/images/uploads/chime-logo-2-.png\"\n\n    - name: \"Gold\"\n      description: |-\n        Gold level sponsors for RubyConf 2024.\n      level: 3\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com/\"\n          slug: \"shopify\"\n          logo_url: \"https://rubyconf.org/images/uploads/copy-of-shopify_logo_black.png\"\n\n        - name: \"Beyond Finance\"\n          website: \"https://www.beyondfinance.com/\"\n          slug: \"beyondfinance\"\n          logo_url: \"https://rubyconf.org/images/uploads/600x300_beyond_logo-1-.png\"\n\n    - name: \"Silver\"\n      description: |-\n        Silver level sponsors for RubyConf 2024.\n      level: 4\n      sponsors:\n        - name: \"Wellsheet\"\n          website: \"https://www.wellsheet.com/\"\n          slug: \"wellsheet\"\n          logo_url: \"https://rubyconf.org/images/uploads/wellsheet-logo-no-slogan-blue-extra-large.png\"\n\n        - name: \"Ubicloud\"\n          website: \"https://www.ubicloud.com/?utm_source=sponsorship&utm_medium=web&utm_id=rubyconf\"\n          slug: \"ubicloud\"\n          logo_url: \"https://rubyconf.org/images/uploads/ubicloud.png\"\n\n        - name: \"Reinteractive\"\n          website: \"https://reinteractive.com/\"\n          slug: \"reinteractive\"\n          logo_url: \"https://rubyconf.org/images/uploads/reinteractive-logo-red-black-confident-3x.png\"\n\n        - name: \"Honeybadger\"\n          website: \"https://www.honeybadger.io/\"\n          slug: \"honeybadger\"\n          logo_url: \"https://rubyconf.org/images/uploads/honeybadger_logo2024.png\"\n\n        - name: \"GitHub\"\n          website: \"https://www.github.com\"\n          slug: \"github\"\n          logo_url: \"https://rubyconf.org/images/uploads/github-mark.png\"\n\n        - name: \"Flagrant\"\n          website: \"https://www.beflagrant.com/\"\n          slug: \"flagrant\"\n          logo_url: \"https://rubyconf.org/images/uploads/flagrant-1-.png\"\n\n        - name: \"Cedarcode\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"cedarcode\"\n          logo_url: \"https://rubyconf.org/images/uploads/cedarcodelogo-horizontal.png\"\n\n    - name: \"Other\"\n      description: |-\n        Other sponsors supporting RubyConf 2024.\n      level: 5\n      sponsors:\n        - name: \"Workforce\"\n          website: \"https://workforce.com/\"\n          slug: \"workforce\"\n          logo_url: \"https://rubyconf.org/images/uploads/workforce.png\"\n\n        - name: \"Sidekiq\"\n          website: \"https://sidekiq.org/\"\n          slug: \"sidekiq\"\n          logo_url: \"https://rubyconf.org/images/uploads/sidekiq.png\"\n\n        - name: \"Sea Foam Media\"\n          website: \"https://www.seafoam.media/\"\n          slug: \"seafoammedia\"\n          logo_url: \"https://rubyconf.org/images/uploads/sea-foam-media-logo.png\"\n\n        - name: \"Scout Monitoring\"\n          website: \"https://www.scoutapm.com/\"\n          slug: \"scoutapm\"\n          logo_url: \"https://rubyconf.org/images/uploads/scout-logo.png\"\n\n        - name: \"GitLab\"\n          website: \"https://about.gitlab.com/\"\n          slug: \"gitlab\"\n          logo_url: \"https://rubyconf.org/images/uploads/gitlab-logo-100.png\"\n\n        - name: \"Couchbase\"\n          website: \"https://www.couchbase.com/\"\n          slug: \"couchbase\"\n          logo_url: \"https://rubyconf.org/images/uploads/couchbase.png\"\n\n    - name: \"Travel Sponsors\"\n      description: |-\n        Ruby Central wants to recognize and give our appreciation to these incredibly supportive individuals who sponsored our event programming.\n      level: 6\n      sponsors:\n        - name: \"Codeminer42\"\n          website: \"https://www.codeminer42.com\"\n          slug: \"codeminer42\"\n          logo_url: \"\"\n\n        - name: \"Headius Enterprises\"\n          website: \"https://www.headius.com\"\n          slug: \"headius\"\n          logo_url: \"\"\n\n        - name: \"Jeremy Evans\"\n          website: \"https://code.jeremyevans.net\"\n          slug: \"jeremy-evans\"\n          logo_url: \"\"\n\n        - name: \"Lexop\"\n          website: \"https://www.lexop.com\"\n          slug: \"lexop\"\n          logo_url: \"\"\n\n        - name: \"MongoDB\"\n          website: \"https://www.mongodb.com\"\n          slug: \"mongodb\"\n          logo_url: \"\"\n\n        - name: \"Sublayer\"\n          website: \"https://www.sublayer.com\"\n          slug: \"sublayer\"\n          logo_url: \"\"\n      # PARTICIPATING COMPANY SPONSORS\n      # Let’s give a special thanks to our participating company sponsors at RubyConf who played a significant part in financially supporting this event.\n      #\n      # Above Lending, Affinipay, Algolia, AnyCable, ART19, Arux Software, Autodesk, Bamboo Health, Bendyworks, Beyond Finance, Brotherhood Mutual Insurance Company, CKH Consulting, Cloud City, Codeminer42, Collective Idea, ConvertKit, CreditNinja, daisyBill, DRW Holdings, Edge, Evil Martians, FBS, Flexcar, G2, GitHub, Judoscale, Kajabi, Kin Insurance, Launch Scout, LiaisonEdu, Medidata Solutions, Merchants Bonding Company, Nasdaq, NinjaCard, Ontra AI, PagerDuty, Planning Center, Privia Health, Public Health Agency of Canada, Pubmark, Purdue Federal Credit Union, Root Insurance, S3 Matching Technologies, Simply Business, SolarWinds Inc, Sublayer, Super Good Software Inc., Test Double, TravelJoy Inc, UAB, Unabridged Software LLC, Unite Us, Vinted,\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2024/venue.yml",
    "content": "---\nname: \"Hilton Chicago\"\n\naddress:\n  street: \"720 South Michigan Avenue\"\n  city: \"Chicago\"\n  region: \"Illinois\"\n  postal_code: \"60605\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"720 S Michigan Ave, Chicago, IL 60605, USA\"\n\ncoordinates:\n  latitude: 41.87225919999999\n  longitude: -87.624696\n\nmaps:\n  google: \"https://maps.google.com/?q=Hilton+Chicago,41.87225919999999,-87.624696\"\n  apple: \"https://maps.apple.com/?q=Hilton+Chicago&ll=41.87225919999999,-87.624696\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=41.87225919999999&mlon=-87.624696\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2024/videos.yml",
    "content": "---\n# Wesbite: https://rubyconf.org\n# Schedule: https://rubyconf.org/schedule\n\n## Day 1 - 2024-11-13\n\n- id: \"kinsey-durham-grace-rubyconf-2024\"\n  title: \"Welcome\"\n  raw_title: \"RubyConf 2024 Welcome with Kinsey Durham Grace & Jim Remsik\"\n  speakers:\n    - Kinsey Durham Grace\n    - Jim Remsik\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Welcome & Intros\n    Program Chairs Kinsey & Jim\n  video_provider: \"youtube\"\n  video_id: \"pJsFj-0a9Bw\"\n\n- id: \"alan-ridlehoover-rubyconf-2024\"\n  title: \"Sponsor Moment Cisco Meraki: Ruby Love\"\n  raw_title: \"RubyConf 2024 Sponsor Moment Cisco Meraki: Ruby Love with Alan Ridlehoover\"\n  speakers:\n    - Alan Ridlehoover\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"rbGe9oWcV0k\"\n\n- id: \"sharon-decaro-rubyconf-2024\"\n  title: \"Sponsor Moment Paypal: Ruby Love\"\n  raw_title: \"RubyConf 2024 Sponsor Moment Paypal: Ruby Love with Sharon DeCaro\"\n  speakers:\n    - Sharon DeCaro\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"aE3Kg5VpsLE\"\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-2024\"\n  title: \"Keynote: Infinity and Beyond\"\n  raw_title: 'RubyConf 2024 Keynote: Yukihiro \"Matz\" Matsumoto'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"a4BJ9VUPWI8\"\n\n- id: \"vincius-stock-rubyconf-2024\"\n  title: \"The State of Ruby Dev Tooling\"\n  raw_title: \"RubyConf 2024 The state of Ruby dev tooling by Vinícius Stock\"\n  speakers:\n    - Vinícius Stock\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    During the last few years, the Ruby community invested significant effort into improving developer tooling. A lot of this effort has been divergent; trying out many solutions to find out what works best and fits Rubyists expectations.\n\n    So where are we at this point? How do we compare to other ecosystems? Is it time to converge, unite efforts and reduce fragmentation? And where are we going next? Let’s analyze the full picture of Ruby tooling and try to answer these questions together.\n  video_provider: \"youtube\"\n  video_id: \"WvyZypFIRYw\"\n\n- id: \"ivo-anjo-rubyconf-2024\"\n  title: \"How the Ruby Global VM Lock impacts app performance\"\n  raw_title: \"RubyConf 2024 How the Ruby Global VM Lock impacts app performance by Ivo Anjo\"\n  speakers:\n    - Ivo Anjo\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Have you ever heard of Ruby's Global VM Lock? Maybe you've heard of the GIL instead?\n\n    Spoiler: It's an implementation detail of Ruby that can have a big impact on latency and performance of applications.\n    At a high-level, it prevents Ruby code across multiple threads from running in parallel, while still safely allowing concurrency.\n\n    Join me as we explore what the GVL is; what it is not; and how we can use the `gvl-tracing` gem to show it in action. We’ll also look into how Ractors, M:N scheduling and fibers fit into this story. By the end of the talk you’ll have the tools to evaluate if your own applications are being impacted, as well as learn a number of do’s and don’ts of Ruby performance.\n  video_provider: \"youtube\"\n  video_id: \"reJyuCXODZY\"\n\n- id: \"murray-steele-rubyconf-2024\"\n  title: \"Names from a hat\"\n  raw_title: \"RubyConf 2024 Names from a hat by Murray Steele\"\n  speakers:\n    - Murray Steele\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    As an organiser of a local ruby meetup group I occasionally need to pluck names from a hat to announce winners of raffles or randomise the order of speakers for a particularly packed agenda. We can do that with actual bits of paper from a hat, but being a rubyist I'm much more interested in writing little ruby scripts to do it for me.\n\n    We'll start with the obvious technique of using `Array#sample` but as it's not very interesting or satisfying to write we'll go a bit further. We'll look at interactivity using `Fiber`, and several attempts at animation using _why's Shoes framework. Finally, we'll explore my magnum opus of a terminal-based dungeon crawler (like nethack and rogue) written in ruby that introduces a human element of randomisation alongside the computer element.\n  video_provider: \"youtube\"\n  video_id: \"LsqgWIB5dDU\"\n\n- id: \"liz-heym-rubyconf-2024\"\n  title: \"Supporter Talk by Cisco: Catching Waves with Time-Series Data\"\n  raw_title: \"RubyConf 2024 Supporter Talk by Cisco: Catching Waves with Time-Series Data by Liz Heym\"\n  speakers:\n    - Liz Heym\n  event_name: \"RubyConf 2024\"\n  track: \"Supporter Talk\"\n  date: \"2024-11-13\"\n  published_at: \"2024-12-13\"\n  description: |-\n    Time-series data is remarkably common, with applications ranging from IoT to finance. Effectively storing, reading, and presenting this time-series data can be as finicky as catching the perfect wave.\n\n    In order to understand the best-practices of time-series data, we’ll follow a surfer’s journey as she attempts to record every wave she’s ever caught. We’ll discover how to structure the time-series data, query for performant access, aggregate data over timespans, and present the data via an API endpoint. Surf’s up!\n  video_provider: \"youtube\"\n  video_id: \"AlHSnxJS7O0\"\n\n- id: \"ahmed-omran-rubyconf-2024\"\n  title: \"Compose Software Like Nature Would\"\n  raw_title: \"RubyConf 2024 Compose Software Like Nature Would by Ahmed Omran\"\n  speakers:\n    - Ahmed Omran\n  event_name: \"RubyConf 2024\"\n  date: \"2024-11-13\"\n  published_at: \"2024-12-13\"\n  slides_url: \"https://speakerdeck.com/this_ahmed/compose-software-like-nature-would-rubyconf-2024\"\n  description: |-\n    The only constant in software development is change. When our software cannot adapt, it turns into a big ball of mud. It becomes hard to reason about and hard to change. On the other hand, living organisms have the incredible ability to adapt to their environment. Over eons, they evolved innumerable adaptations. Let’s explore together how we can create adaptable, maintainable, and resilient software with some inspiration from nature.\n  video_provider: \"youtube\"\n  video_id: \"bVBAvCm2mCs\"\n\n- id: \"koichi-sasada-rubyconf-2024\"\n  title: \"Ractor on Ruby 3.4\"\n  raw_title: \"RubyConf 2024 Ractor on Ruby 3.4 by Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Ractor enables parallel programming on Ruby and has been introduced since Ruby 3.0. However, Ractor has many issues regarding performance and compatibility with the existing code base. In order to solve the current situation, Ruby 3.4 will introduce a number of features and performance improvements.\n\n    This presentation will show the advantages and limitations of\n    of current Ractor programming, and the future perspective of Ractor in Ruby 3.4 and beyond.\n  video_provider: \"youtube\"\n  video_id: \"8fdTpQdGU70\"\n\n- id: \"herve-aniglo-rubyconf-2024\"\n  title: \"Sounds, Synths, and Sonic Pi! Oh My!\"\n  raw_title: \"RubyConf 2024 Sounds, Synths, and Sonic Pi! Oh My! by Herve Aniglo\"\n  speakers:\n    - Herve Aniglo\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Have you ever thought about making some really awesome beats by coding? You can do that with Sonic Pi! Sonic Pi is based off of Ruby and you can create all types of beats and melodies with this technology and I can show you how to do it through a demo.\n\n    In this talk attendees will learn about Sonic Pi, a live coding environment based on the Ruby programming language, and will learn how to create different genres of music by coding.\n\n    Attendees will leave this talk with an understanding of Sonic Pi and learn how to:\n\n    make music\n    make beats\n    make songs\n    music transcription and playback\n    audio looping, computer-aided music composition\n    development of computer-based musical instruments (including hybrid instruments)\n    live performance\n    Live demo where I will turn my computer into a myriad of musical instruments to play music and songs of different genres\n  video_provider: \"youtube\"\n  video_id: \"tTrMtMe56kE\"\n\n- id: \"youssef-chaker-rubyconf-2024\"\n  title: \"Supporter Talk by Paypal: Building Scalable & Resilient Background Jobs for FinTech\"\n  raw_title: \"RubyConf 2025 Supporter Talk by Paypal: Building Scalable & Resilient ... by Youssef Chaker\"\n  speakers:\n    - Youssef Chaker\n  event_name: \"RubyConf 2024\"\n  track: \"Supporter Talk\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Supporter Talk by Paypal: Building Scalable & Resilient Background Jobs for FinTech\n\n    Join the Funding team at Braintree/PayPal on a journey through the intricacies of constructing robust, resilient, and repeatable pipelines using Ruby. Our system, composed of a series of sophisticated background jobs with complex dependencies, is finely tuned to meet the demanding scale of the fintech industry. In this talk, I will share the strategies and techniques we employed to achieve our goals, providing valuable insights for anyone looking to build or optimize similar systems.\n  video_provider: \"youtube\"\n  video_id: \"ssqt6V3RICk\"\n\n- id: \"craig-buchek-rubyconf-2024\"\n  title: \"Fifty Years of Ruby\"\n  raw_title: \"RubyConf 2024 Fifty Years of Ruby by Craig Buchek\"\n  speakers:\n    - Craig Buchek\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Our modern-day concepts of GUIs, WYSIWYG, and IDEs were developed at Xerox PARC in the early 1970s. Alan Kay was one of the first employees, working on programming languages, among other things. He first released Smalltalk in 1972.\n\n    While Ruby was not directly derived from Smalltalk, the two are surprisingly similar. We'll explore the history of Smalltalk, and the context in which it was formed. We'll see how Ruby rediscovered and reapplied Smalltalk's concepts, with an eye towards understanding Ruby's future.\n  video_provider: \"youtube\"\n  video_id: \"I8hfKCXpqPc\"\n\n- id: \"keith-gable-rubyconf-2024\"\n  title: \"Lessons Learned Running Sidekiq at Scale\"\n  raw_title: 'RubyConf 2024 Lessons Learned Running Sidekiq at Scale by Keith \"Ziggy the Hamster\" Gable'\n  speakers:\n    - Keith Gable\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    I've been using Sidekiq for more than a decade and have made a ton of mistakes along my journey from being the second engineer at a tiny startup to becoming acquired by a huge company over the past 10 years.\n\n    I aim to share my operational experience, architectural advice, and how I got out of sticky situations when I made poor choices.\n  video_provider: \"youtube\"\n  video_id: \"Wjppe-diJUU\"\n\n- id: \"thomas-e-enebo-rubyconf-2024\"\n  title: \"Let's write an esoteric language in Ruby!\"\n  raw_title: \"RubyConf 2024 Let's write an esoteric language in Ruby! by Thomas Enebo\"\n  speakers:\n    - Thomas E Enebo\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Ever wondered if some programming languages are weird by design? Welcome to the wild and wacky world of esoteric programming languages! The main focus of this talk will be to create a Ruby implementation of the image-based (gif/png/jpeg) language Piet. Can you imagine your source code as a picture of a cow?\n\n    Rpiet starts as a naive port of one of the other language implementations of Piet. From there, we consider what is special about this language versus traditional programming languages. We then distill our initial implementation into a lean and mean version which verges on ROFLScale. It even includes a working graphical debugger!\n  video_provider: \"youtube\"\n  video_id: \"N607ypZnFNw\"\n\n- id: \"noel-rappin-rubyconf-2024\"\n  title: \"Supporter Talk by Chime: Coordinate Ruby Teams With Chime\"\n  raw_title: \"RubyConf 2024 Supporter Talk by Chime: Coordinate Ruby Teams With Chime by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RubyConf 2024\"\n  track: \"Supporter Talk\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Coordinating hundreds of Ruby developers on dozens of projects can be challenging. Join members of Chimes \"I Heart Ruby\" team as we discuss some of the ways that we help our teams coordinate their Ruby tooling.\n  video_provider: \"youtube\"\n  video_id: \"M_MgprNAiHw\"\n\n# Lunch\n\n- id: \"enrique-mogolln-rubyconf-2024\"\n  title: \"Breaking nil to fix bugs: experimental approach\"\n  raw_title: \"RubyConf 2024 Breaking nil to fix bugs: experimental approach by Enrique Mogollan\"\n  speakers:\n    - Enrique Mogollán\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    In Ruby, encountering `nil` is inevitable and often leads to frustrating bugs and NoMethodError exceptions. While `nil` is a crucial part of Ruby's design, it can be the source of elusive and hard-to-diagnose issues in your codebase. This talk explores an unconventional and experimental approach to debugging by \"breaking\" the nil object.\n    How will we debug bugs?\n    - extending the NilClass\n    - customizing method_missing\n    - creating methods dynamically with the previous options\n\n    This is probably the wrong solution. Don't try this in production. However, we'll find bugs and it will be fun!\n\n    Notes, code and more: https://github.com/mogox/talk_breaking_nil\n  video_provider: \"youtube\"\n  video_id: \"NVf-YCCIgJo\"\n  additional_resources:\n    - name: \"mogox/talk_breaking_nil\"\n      type: \"repo\"\n      url: \"https://github.com/mogox/talk_breaking_nil\"\n\n- id: \"charles-nutter-rubyconf-2024\"\n  title: \"Building JRuby: How We Implement Ruby on the JVM\"\n  raw_title: \"RubyConf 2024 Building JRuby: How We Implement Ruby on the JVM by Charles Nutter & Thomas Enebo\"\n  speakers:\n    - Charles Nutter\n    - Thomas E Enebo\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  slides_url: \"https://speakerdeck.com/headius/building-jruby-how-we-implement-ruby-on-the-jvm\"\n  description: |-\n    What does it take to build a language runtime on the JVM? This talk will show how we implement JRuby, from Java versions of core classes and native extensions to our parser, compiler, and JIT subsystems. You'll learn how to find and fix bugs, profile Ruby code, and integrate with the many libraries and features of the JVM.\n  video_provider: \"youtube\"\n  video_id: \"RXOmW82rb3g\"\n\n- id: \"jade-dickinson-rubyconf-2024\"\n  title: \"Plan to Scale or Plan to Fail: An Evidence-Based Approach for Improving Systems Performance\"\n  raw_title: \"RubyConf 2024 Plan to scale or plan to fail: an evidence-based approach for... by Jade Dickinson\"\n  speakers:\n    - Jade Dickinson\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Plan to scale or plan to fail: an evidence-based approach for improving systems performance by Jade Dickinson\n\n    In this talk, I will present a methodology for replicating most standard Rails systems, for the purpose of load testing.\n\n    You can use this to find out how your system performs with more traffic than you currently encounter. This will be useful if you are on a Rails team that is starting to see scaling challenges.\n\n    At Theta Lake we operate at scale and are applying this methodology to proactively find ways to bring down our server costs. You don’t want to leave it until either your server costs soar out of control, or your entire system is about to fail. By seeing into the future just a little bit, you can find bottlenecks in your system and so find where you can improve its scalability.\n  video_provider: \"youtube\"\n  video_id: \"cBiXF4S5ePU\"\n\n- id: \"samuel-giddins-rubyconf-2024\"\n  title: \"The State of RubyGems\"\n  raw_title: \"RubyConf 2024 The State of RubyGems with Samuel Giddins, Martin Emde & Marty Haught\"\n  speakers:\n    - Samuel Giddins\n    - Martin Emde\n    - Marty Haught\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    2024 marked Ruby Central’s most productive year with work across RubyGems, Bundler, and RubyGems.org. Join us as we explore our major projects over the past year, with a special emphasis on what we’re doing to keep the Ruby ecosystem safe, secure, and delightful to participate in. We’ll finish up by sharing our ambitious plans for the next year, some details about how our open source team works, and give you all the information you need to support us.\n  video_provider: \"youtube\"\n  video_id: \"yNylJiBI_H0\"\n\n- id: \"errol-schmidt-rubyconf-2024\"\n  title: \"Supporter Talk by reinteractive: Future Proofing your Ruby Stack\"\n  raw_title: \"RubyConf 2024 Supporter Talk by reinteractive: Future Proofing your Ruby Stack by Errol Schmidt\"\n  speakers:\n    - Errol Schmidt\n  event_name: \"RubyConf 2024\"\n  track: \"Supporter Talk\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Discussing how current industry trends and product owner expectations effect how we build and maintain our Ruby apps (without compromising).\n  video_provider: \"youtube\"\n  video_id: \"u7i_FRWiAf8\"\n\n- id: \"jamis-buck-rubyconf-2024\"\n  title: \"Flattening Recursion with Fibers\"\n  raw_title: \"RubyConf 2024 Flattening Recursion with Fibers by Jamis Buck & Adviti Mishra\"\n  speakers:\n    - Jamis Buck\n    - Adviti Mishra\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    We used Ruby's fibers at MongoDB to unwind a recursive algorithm and execute it horizontally, without the stack overhead of recursion.\n\n    \"Hang on,\" you might be thinking. \"I thought fibers were a concurrency primitive?\"\n\n    You're not wrong!\n\n    In this presentation, we'll summarize the problem we encountered while working with recursive callbacks, and give an overview of fibers in Ruby. Then, we'll put the two together and show you exactly how we ended up using fibers to solve an issue that was completely unrelated to concurrency.\n  video_provider: \"youtube\"\n  video_id: \"mWEjGXLYcaE\"\n\n- id: \"sara-jackson-rubyconf-2024\"\n  title: \"Chaos Engineering on the Death Star\"\n  raw_title: \"RubyConf 2024 Chaos Engineering on the Death Star by Sara Jackson\"\n  speakers:\n    - Sara Jackson\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    An exhaust vent wasn't the only flaw on the Death Star! We'll follow along with a flustered Death Star engineer, Maia, and learn how ideas from the world of chaos engineering could have saved her app from exploitation by the rebels.\n  video_provider: \"youtube\"\n  video_id: \"__ndB5cGoCo\"\n\n- id: \"stephen-margheim-rubyconf-2024\"\n  title: \"ACIDic Jobs: Scaling a resilient jobs layer\"\n  raw_title: \"RubyConf 2024 ACIDic Jobs: Scaling a resilient jobs layer by Stephen Margheim\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Background jobs have become an essential component of any Rails app. As your /jobs directory grows, however, how do you both ensure that your jobs are resilient and that complex operations are maintainable and cohesive? In this talk, we will explore how we can build maintainable, resilient, cohesive jobs, all by making our jobs ACIDic.\n  video_provider: \"youtube\"\n  video_id: \"JrLRFc5D6hI\"\n\n- id: \"mariusz-kozie-rubyconf-2024\"\n  title: \"Building the Future of Ruby Through Community\"\n  raw_title: \"RubyConf 2024 Building the future of Ruby through community by Mariusz Kozieł\"\n  speakers:\n    - Mariusz Kozieł\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Discover how Ruby Europe is creating a stronger Ruby ecosystem by prioritizing community development. Explore real-life examples of how community initiatives have transformed careers, inspired projects, and sparked innovations. See how each of us can play a vital role in shaping the future of Ruby.\n  video_provider: \"youtube\"\n  video_id: \"EQLl9kV95-M\"\n\n- id: \"daniel-farina-rubyconf-2024\"\n  title: \"Supporter Talk by Ubicloud: Build a Cloud in Thirteen Years\"\n  raw_title: \"RubyConf 2024 Supporter Talk by Ubicloud: Build a Cloud in Thirteen Years by Daniel Farina\"\n  speakers:\n    - Daniel Farina\n  event_name: \"RubyConf 2024\"\n  track: \"Supporter Talk\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    In 2011, I joined a tiny team at Heroku, managing servers with a custom Ruby program. By 2023, I co-founded Ubicloud, developing the fourth generation of such a program...again, in Ruby. Unlike 2011, the choice of Ruby in 2024 raises questions, even from Ruby programmers.\n\n    The Ubicloud team's engineering approach is unusual: most of the team has used Ruby for infrastructure cloud programs, none of them depending upon Rails. I'll share our unconventional practices and assessment of Ruby's strengths, aiming to broaden perspectives on Ruby's capabilities and applications.\n  video_provider: \"youtube\"\n  video_id: \"5QqltsU4tEs\"\n\n- id: \"aaron-patterson-rubyconf-2024\"\n  title: \"Fast Forward: Speeding up Delegate Methods\"\n  raw_title: \"Ruby Conf 2024 Fast Forward: Speeding up Delegate Methods by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Delegate methods are methods that take any parameters, and pass those parameters on to other methods. It may not seem like it, but this is an extremely common pattern in Ruby code. In this session, we’re going to learn how Ruby method calls work, how inline caches work, and how we can use the combination of this knowledge to optimize delegate methods.\n  video_provider: \"youtube\"\n  video_id: \"jexSQUfKnlI\"\n\n- id: \"tyler-lemburg-rubyconf-2024\"\n  title: \"The Mutation Game: Cracking the Enigma of Mutation Testing\"\n  raw_title: \"RubyConf 2024 The Mutation Game: Cracking the Enigma of Mutation Testing by Tyler Lemburg\"\n  speakers:\n    - Tyler Lemburg\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    Can your application's code achieve complete perfection? If you join Professor X's School for Gifted Mutation Testers, it can get pretty dang close. Discover the Mystique of transforming your code in silly (and not-so-silly) ways, and seeing if this makes your tests fail. If your tests do fail, they are solid as a Colossus! If your tests passed, then you have discovered a Rogue mutant! But do not worry: I will teach you the ins and outs of squashing that mutant like a Blob and making your code stronger than Wolverine.\n\n    Storm into this session and learn what mutation testing is all about, see if it may be right for your Ruby codebase, and explore the tools that make it possible. We will use the `mutant` gem and delve into an example Ruby app, bringing it to full mutation testing coverage through simplifying code and improving tests. Even if this technique is not right for your project, you will come away from this session with a deeper understanding of Ruby, code parsing, test-driven development, and writing clean, beautiful code.\n  video_provider: \"youtube\"\n  video_id: \"ifrmqWoaee0\"\n\n- id: \"jp-camara-rubyconf-2024\"\n  title: \"In-Depth Ruby Concurrency: Navigating the Ruby Concurrency Landscape\"\n  raw_title: \"RubyConf 2024 In-Depth Ruby Concurrency: Navigating the Ruby concurrency landscape by JP Camara\"\n  speakers:\n    - JP Camara\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: |-\n    When do I use a Process, or a Thread, or a Fiber? And Why? Can I use Ractors yet? What is the FiberScheduler? The M:N Thread scheduler? What's a Reactor? Do I fork, prefork, or refork? Should I care?\n\n    Do I scale up my Threads? My Fibers? My Processes? Do I use lots of lower powered, low-process horizontal scaling or high-powered, high-process vertical scaling? All of the above?\n\n    In this talk, we'll build an understanding of the Ruby concurrency landscape, and map that understanding onto concurrent gems like Sidekiq, Puma, Falcon, Pitchfork, SolidQueue and Mooro. My goal is for you to better understand how they work, what concurrency options they offer, and how you can best utilize them for scaling your applications.\n  video_provider: \"youtube\"\n  video_id: \"rewiLd2w0kE\"\n\n# TBA\n\n- id: \"nickolas-means-rubyconf-2024\"\n  title: \"Keynote: Ice, Confusion, and the 38,000ft Crash\"\n  raw_title: \"Keynote: Ice, Confusion, and the 38,000ft Crash by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"m_Eanh1Okk0\"\n\n## Day 2 - 2024-11-14\n\n- id: \"drew-bragg-rubyconf-2024\"\n  title: \"Keynote: Who Wants to be a Ruby Engineer?\"\n  raw_title: \"RubyConf 2024 Who Wants to be a Ruby Engineer? by Drew Bragg\"\n  speakers:\n    - Drew Bragg\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-14\"\n  description: |-\n    'Welcome to the Ruby game show where contestants try to guess the output\n    of a small bit of Ruby code. Sound easy? Here''s the challenge: the snippets come\n    from some of the weirdest parts of the Ruby language. The questions aren''t easy,\n    but et enough right to be crowned a \"Strange\" Ruby Engineer and win a fabulous\n    prize.'\n  video_provider: \"youtube\"\n  video_id: \"iMCqYjWKv5w\"\n\n- id: \"christopher-aji-slater-rubyconf-2024\"\n  title: \"Workshop: Breaking the Unbreakable Code Whose Breaking Won World War II\"\n  raw_title: \"RubyConf 2024 Workshop: Building the Unbreakable Code Whose Breaking Won WWII by Aji Slater\"\n  speakers:\n    - Christopher \"Aji\" Slater\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-14\"\n  slides_url: \"https://speakerdeck.com/doodlingdev/breaking-the-unbreakable-code-whose-breaking-won-world-war-ii\"\n  description: |-\n    After the last carrier pigeon but before digital encryption algorithms, there was the Enigma machine. An ingenious piece of pre-atomic age technology encoded German military secrets during World War II, baffling code-breakers with mere physical rotors, and switches, without elliptic curves or private keys.\n\n    Delve into object-oriented programming and bring the Enigma machine back to life with an emulator built in Ruby. Use Test Driven Development to unravel the secrets of this nigh-unbreakable cipher device, witness OO principles unlock its mysteries, discover the power and versatility of the patterns we use as developers and how they mirror the Enigma's inner workings.\n  video_provider: \"youtube\"\n  video_id: \"u8xbVk8aWjA\"\n\n- id: \"andy-maleh-rubyconf-2024\"\n  title: \"Workshop: How To Build Basic Desktop Applications in Ruby\"\n  raw_title: \"RubyConf 2024 Workshop: How To Build Basic Desktop Applications in Ruby by Andy Maleh\"\n  speakers:\n    - Andy Maleh\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-14\"\n  description: |-\n    Learn how to build basic desktop applications in Ruby with hands-on code exercises!\n\n    Workshop outline (every step will involve a hands-on exercise or more):\n    1. GUI Basics (Controls, Properties, and Listeners):\n    2. Observer Pattern and MVC (Model-View-Controller) Software Architecture\n    3. Data-Binding and MVP (Model-View-Presenter) Software Architecture\n    4. Advanced Data-Binding\n\n    This workshop will be conducted using Glimmer DSL for LibUI, the prerequisite-free ruby desktop development cross-platform native GUI gem that won a Fukuoka Ruby 2022 Special Award after getting judged by Matz, the creator of Ruby.\n\n    Please install the latest version of the Ruby gem (run `gem install glimmer-dsl-libui`) and confirm it is working (run `glimmer examples`) in advance to hit the ground running when the workshop begins.\n  video_provider: \"youtube\"\n  video_id: \"TTSqRdTVtDY\"\n\n- id: \"koichi-sasada-rubyconf-2024-ruby-hack-challenge\"\n  title: \"Ruby Hack Challenge\"\n  raw_title: \"RubyConf 2024 Ruby Hack Challenge by Koichi Sasada and Core team\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-14\"\n  description: |-\n    Come try your own internal hacking on the Ruby MRI!\n\n    This workshop introduces how to hack the Ruby interpreter with the text\n    https://github.com/ko1/rubyhackchallenge/tree/master and Ruby core committers.\n\n    We welcome you If you have\n    * interest how to work the Ruby interpreter\n    * questions about Ruby interpreter\n    * ideas to improve Ruby interpreter\n    * tickets you issued on our Redmine\n\n    Also we held \"Ask Ruby core developers\" session (12:00-13:30) so you can ask anything you want to ask.\n  video_provider: \"youtube\"\n  video_id: \"jB3S03xoljc\"\n  talks:\n    - title: \"Ruby Hack Challenge Intro\"\n      start_cue: \"00:15\"\n      end_cue: \"14:27\"\n      date: \"2024-11-14\"\n      video_provider: \"parent\"\n      id: \"ruby-hack-challenge-intro-rubyconf-2024\"\n      video_id: \"ruby-hack-challenge-intro-rubyconf-2024\"\n      speakers:\n        - Koichi Sasada\n\n    - title: \"Ruby Core Developers Q&A\"\n      start_cue: \"14:27\"\n      end_cue: \"01:35:17\"\n      thumbnail_cue: \"17:14\"\n      date: \"2024-11-14\"\n      video_provider: \"parent\"\n      id: \"ruby-core-developers-q-and-a-rubyconf-2024\"\n      video_id: \"ruby-core-developers-q-and-a-rubyconf-2024\"\n      speakers:\n        - Koichi Sasada\n        - Aaron Patterson\n        - Yukihiro \"Matz\" Matsumoto\n        - John Hawthorn\n        - Eileen M. Uchitelle\n        - Peter Zhu\n        - Alan Wu\n        - Yusuke Endoh\n        - Akira Matsuda\n  additional_resources:\n    - name: \"ko1/rubyhackchallenge\"\n      type: \"repo\"\n      url: \"https://github.com/ko1/rubyhackchallenge/tree/master\"\n\n- id: \"sean-collins-workshop-rubyconf-2024\"\n  title: \"Workshop: Hands on Hanami\"\n  raw_title: \"Workshop: Hands on Hanami by Sean Collins\"\n  speakers:\n    - Sean Collins\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-11\"\n  date: \"2024-11-14\"\n  description: |-\n    Have you had a chance to walk through every layer of a Hanami 2 web application? Here’s your chance. With the release of 2.2 this summer, all the basic building blocks are in place: with a zero-config database layer (built on ROM), and an optional but first-class operations layer that provides a flexible and consistent API for your domain operations.\n\n    We’ll write a simple blog application across the entire suite of Hanami libraries. You’ll route a request to an action, which is responsible for parameters and delegating to the rest of your app. They are the gateway from the web into your app. From there we’ll create a record in the database and surface it back up to the action. The action’s final job is to render a view. That view is a ruby class that is responsible for preparing data to render in its simple logicless ERB template.\n\n    We’ll end the workshop by dividing into small groups based on interest: extracting core business operations into their own classes, refactoring the view into different parts, or diving into the database by building more complicated queries.\n  video_provider: \"not_recorded\"\n  video_id: \"sean-collins-workshop-rubyconf-2024\"\n\n- id: \"noel-rappin-rubyconf-2024-workshop-no-static-types-no-pr\"\n  title: \"Workshop: No Static Types? No Problem!\"\n  raw_title: \"RubyConf 2024 Workshop: No Static Types? No Problem! by Noel Rappin\"\n  speakers:\n    - Noel Rappin\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-14\"\n  description: |-\n    New Ruby developers often wonder how to write safe code in Ruby without\n    static typing. In this workshop, we’re going to refactor working code to get the\n    data validation and safety of static typing, but using Ruby’s existing features.\n    We’ll show how to use coercions, data objects, the null object pattern, among\n    others, and we’ll use Ruby’s debugger and console to show the power of Ruby’s\n    flexibility. We’ll even see how improve your editor tooling. Then, we’ll discuss\n    how static typing can work together with dynamic typing to make the most maintainable\n    code. You’ll leave with a great set of tools for improving the code you work on\n    daily.\n\n    Code Samples: https://github.com/noelrappin/cookie_cutter\n  video_provider: \"youtube\"\n  video_id: \"l0vMpP-5QBY\"\n  slides_url: \"https://sharing.ia.net/presenter/efad9c8e05bf4db699a874433186fadf/view\"\n  additional_resources:\n    - name: \"noelrappin/cookie_cutter\"\n      type: \"repo\"\n      url: \"https://github.com/noelrappin/cookie_cutter\"\n\n- id: \"lightning-talks-rubyconf-2024\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf 2024 Lightning Talks\"\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"4WC3d3SGIUk\"\n  talks:\n    - title: \"Lightning Talks Intro\"\n      start_cue: \"00:13\"\n      end_cue: \"01:10\"\n      date: \"2024-11-14\"\n      id: \"sara-mei-lightning-talks-intro-rubyconf-2024\"\n      video_id: \"sara-mei-lightning-talks-intro-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Sarah Mei\n\n    - title: \"Lightning Talk: An intro to Langchain.rb\"\n      start_cue: \"01:10\"\n      end_cue: \"06:23\"\n      date: \"2024-11-14\"\n      id: \"noah-durbin-lightning-talk-rubyconf-2024\"\n      video_id: \"noah-durbin-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Noah Durbin\n\n    - title: \"Lightning Talk: Advance - How to Propel the Next Generation of Technologists\"\n      start_cue: \"06:23\"\n      end_cue: \"11:30\"\n      date: \"2024-11-14\"\n      id: \"sunjay-armstead-lightning-talk-rubyconf-2024\"\n      video_id: \"sunjay-armstead-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      slides_url: \"https://speakerdeck.com/sarmstead/advance-how-to-propel-the-next-generation-of-technologists\"\n      speakers:\n        - Sunjay Armstead\n      description: |-\n        Today’s marketplace for software jobs is increasingly less favorable to junior and mid-level technologists. Overlooked, disregarded, and far underestimated, these technologists know grit better than any of us. They’ve searched for jobs to no avail, wrestled with technical problems with little help, and spent long nights fretting over their dreams. By signing the Advance Manifesto, regardless of skill-level or classification, you can commit to advancing the next generation of technologists. Read more about the movement and make your pledge at advancemanifesto.com.\n\n        Website: https://advancemanifesto.com\n\n    - title: \"Lightning Talk: Software Engineering Gaphic Design\"\n      start_cue: \"11:30\"\n      end_cue: \"15:51\"\n      date: \"2024-11-14\"\n      id: \"manu-vanconcelos-lightning-talk-rubyconf-2024\"\n      video_id: \"manu-vanconcelos-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Manu Vanconcelos\n\n    - title: \"Lightning Talk: How to be a Ruby scholar, do a prject, and (accidentally) break your laptop\"\n      start_cue: \"15:51\"\n      end_cue: \"18:53\"\n      date: \"2024-11-14\"\n      id: \"alexander-mitchell-lightning-talk-rubyconf-2024\"\n      video_id: \"alexander-mitchell-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Alexander Mitchell\n\n    - title: \"Lightning Talk: Interactive Data Visualization with JavaScript and the HTMLS5 Canvas\"\n      start_cue: \"18:53\"\n      end_cue: \"24:00\"\n      date: \"2024-11-14\"\n      id: \"neil-hendren-lightning-talk-rubyconf-2024\"\n      video_id: \"neil-hendren-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Neil Hendren\n\n    - title: \"Lightning Talk: We do not need a static site generator\"\n      start_cue: \"24:00\"\n      end_cue: \"28:52\"\n      date: \"2024-11-14\"\n      id: \"adam-mccrea-lightning-talk-rubyconf-2024\"\n      video_id: \"adam-mccrea-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam McCrea\n\n    - title: \"Lightning Talk: Interpretable and Explainable AI\"\n      start_cue: \"28:52\"\n      end_cue: \"33:55\"\n      date: \"2024-11-14\"\n      id: \"elshadai-tegegn-lightning-talk-rubyconf-2024\"\n      video_id: \"elshadai-tegegn-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Elshadai Tegegn\n\n    - title: \"Lightning Talk: Sombrero Code - From blog post to jargon\"\n      start_cue: \"33:55\"\n      end_cue: \"38:53\"\n      date: \"2024-11-14\"\n      id: \"benjamin-fleischer-lightning-talk-rubyconf-2024\"\n      video_id: \"benjamin-fleischer-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Benjamin Fleischer\n\n    - title: \"Lightning Talk: Ruby for Good\"\n      start_cue: \"38:53\"\n      end_cue: \"43:56\"\n      date: \"2024-11-14\"\n      id: \"ken-maeshima-lightning-talk-rubyconf-2024\"\n      video_id: \"ken-maeshima-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Ken Maeshima\n\n    - title: \"Lightning Talk: My Top 5 Favorite Ruby Gems\"\n      start_cue: \"43:56\"\n      end_cue: \"48:40\"\n      date: \"2024-11-14\"\n      id: \"gary-tou-lightning-talk-rubyconf-2024\"\n      video_id: \"gary-tou-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Gary Tou\n\n    - title: \"Lightning Talk: Tooling Over Documentation\"\n      start_cue: \"48:40\"\n      end_cue: \"53:51\"\n      date: \"2024-11-14\"\n      id: \"ronan-potage-lightning-talk-rubyconf-2024\"\n      video_id: \"ronan-potage-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Ronan Potage\n\n    - title: \"Lightning Talk: Ruby Community\"\n      start_cue: \"53:51\"\n      end_cue: \"59:35\"\n      date: \"2024-11-14\"\n      id: \"jeff-casimir-lightning-talk-rubyconf-2024\"\n      video_id: \"jeff-casimir-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeff Casimir\n\n    - title: \"Lightning Talk: Owning Telemetry Data in Ruby\"\n      start_cue: \"59:35\"\n      end_cue: \"01:04:59\"\n      date: \"2024-11-14\"\n      id: \"michal-kazmierczak-lightning-talk-rubyconf-2024\"\n      video_id: \"michal-kazmierczak-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Michal Kazmierczak\n\n    - title: \"Lightning Talk: Active Agents\"\n      start_cue: \"01:04:59\"\n      end_cue: \"01:09:35\"\n      date: \"2024-11-14\"\n      id: \"justin-bowen-lightning-talk-rubyconf-2024\"\n      video_id: \"justin-bowen-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Justin Bowen\n      description: |-\n        Website: https://www.activeagents.ai\n\n    - title: \"Lightning Talk: Why It's important to attend and organize Ruby Meetups\"\n      start_cue: \"01:09:35\"\n      end_cue: \"01:15:09\"\n      date: \"2024-11-14\"\n      id: \"mariusz-koziel-lightning-talk-rubyconf-2024\"\n      video_id: \"mariusz-koziel-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Mariusz Kozieł\n\n    - title: \"Lightning Talk: Ode to RailsConf Podcast\"\n      start_cue: \"01:15:09\"\n      end_cue: \"01:16:22\"\n      date: \"2024-11-14\"\n      id: \"david-hill-lightning-talk-rubyconf-2024\"\n      video_id: \"david-hill-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - David Hill\n\n    - title: \"Lightning Talk: How to Open Source (Book)\"\n      start_cue: \"01:16:22\"\n      end_cue: \"01:17:30\"\n      date: \"2024-11-14\"\n      id: \"richard-schneeman-lightning-talk-rubyconf-2024\"\n      video_id: \"richard-schneeman-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Richard Schneeman\n      description: |-\n        Website: https://howtoopensource.dev\n\n    - title: \"Lightning Talk: Introduction - Marketing for Ruby Central\"\n      start_cue: \"01:17:30\"\n      end_cue: \"01:18:43\"\n      date: \"2024-11-14\"\n      id: \"rhiannon-payne-lightning-talk-rubyconf-2024\"\n      video_id: \"rhiannon-payne-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Rhiannon Payne\n\n    - title: \"Lightning Talk: Confreaks\"\n      start_cue: \"01:18:43\"\n      end_cue: \"01:20:11\"\n      date: \"2024-11-14\"\n      id: \"cindy-backman-lightning-talk-rubyconf-2024\"\n      video_id: \"cindy-backman-lightning-talk-rubyconf-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Cindy Backman\n\n## Day 3 - 2024-11-15\n\n- id: \"brandon-weaver-rubyconf-2024\"\n  title: \"Keynote: Red in Fantasyland\"\n  raw_title: \"RubyConf 2024 Keynote by Brandon Weaver\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-16\"\n  date: \"2024-11-15\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"BDepeodE0i4\"\n\n- id: \"mari-imaizumi-rubyconf-2024\"\n  title: \"Exploring Reline: Enhancing Command Line Usability\"\n  raw_title: \"RubyConf 2024 Exploring Reline: Enhancing Command Line Usability by Mari Imaizumi\"\n  speakers:\n    - Mari Imaizumi\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-15\"\n  description: |-\n    Reline is a pure Ruby implementation of GNU Readline and IRB uses it.\n    GNU Readline allows you to write configuration in .inputrc, and Reline reads this\n    configuration file and sets key bindings. However, there are many things that\n    GNU Readline can do that Reline cannot. This session will introduce those features\n    and talk about their implementation in Reline.\n  video_provider: \"youtube\"\n  video_id: \"_6S1K3G4jgo\"\n\n- id: \"shunsuke-kokuyou-mori-rubyconf-2024\"\n  title: \"Do LLMs dream of Type Inference?\"\n  raw_title: 'RubyConf 2024 Do LLMs dream of Type Inference? by Shunsuke \"Kokuyou\"  Mori'\n  speakers:\n    - Shunsuke \"Kokuyou\" Mori\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-15\"\n  description: |-\n    Large Language Models (LLMs) have been rapidly evolving in recent years. They offer a completely different approach to challenges that were difficult to solve with classical algorithms.\n\n    In this session, I will describe how RBS Goose, an LLM-based type inference tool I am currently developing, works and its current evaluation.\n    For future improvement of RBS Goose, a more detailed evaluation mechanism is needed. In this regard, we will share ideas about TypeEvalRb, a type inference benchmark, by referring to examples from previous studies.\n  video_provider: \"youtube\"\n  video_id: \"GO_DSchtTJo\"\n\n- id: \"karl-weber-rubyconf-2024\"\n  title: \"MVC Ruby in Less Than 5K. The Wonder of Camping\"\n  raw_title: \"RubyConf 2024 MVC Ruby in less than 5k. The wonder of Camping by Karl Weber\"\n  speakers:\n    - Karl Weber\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-15\"\n  description: |-\n    Learn about the journey to resurrect an almost 20 year old ruby library, And all the amazing Ruby tricks it uses to be a fully featured MVC Web Framework.\n\n    Ruby's semantics allow remarkable flexibility, and robustness. Let's walk through how Camping uses Ruby's best & hidden features to make a fully featured MVC Micro Web Framework, in a ridiculously small amount of code.\n\n    Ruby's maturity promotes innovation and stability. Camping is almost 20 years old, and sat derelict unchanged for almost 8 years. To get it running with the latest versions of Ruby and its dependencies took only a couple of code changes.\n\n    Camping isn't just another small micro framework written by a mad genius. It's the BEST ONE. Its small size and compact architecture makes it ideal for beginners, side projects, and small apps.\n\n    # Key Takeaways.\n    * Ruby is OP (Over Powered) and makes everything possible.\n    * Framework Plugins in Ruby in a couple of lines of code.\n    * Full Featured web server in like 100 bytes.\n    * Put your whole app in one file.\n    * Dynamic file lookups for views in a single line of Ruby.\n    * Templating in 4 lines of Ruby? Yes!\n    * HTML, CSS, Javascript... In your RUBY!\n    * Rack conventions make ruby incredibly reliable, extensible, and extremely badass.\n    * And more\n\n    * Steps to ressurect Camping.\n    * It doesn't run.\n    * It Runs.\n    * What does it do? Times ten. (Lots of small examples of interesting Ruby code that does interesting things in Camping)\n    * Writing more tests.\n    * Ok so it's actually broken and I didn't know and now it's fixed again.\n    * Am I a Ruby Expert now?\n    * No.\n\n    # Session Highlights\n    Ruby is great\n    You can do so much with so little in Ruby\n    How to make a Blog in 3 minutes\n    Yes it's less than 5k\n    Stickers\n\n    Bonus I have physical boxed copies of Ruby Camping that you can win or buy.\n  video_provider: \"youtube\"\n  video_id: \"SPThZyrCMs0\"\n\n- id: \"yusuke-endoh-rubyconf-2024\"\n  title: \"An Invitation to TRICK: How to write weird Ruby programs\"\n  raw_title: \"RubyConf 2024 An Invitation to TRICK: How to write weird Ruby programs by Yusuke Endoh\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-15\"\n  slides_url: \"https://speakerdeck.com/mame/an-invitation-to-trick-how-to-write-weird-ruby-programs\"\n  description: |-\n    You don't know truly weird Ruby yet, do you?\n\n    TRICK is an irregularly held Ruby programming contest that celebrates the most creative and weird Ruby programs. Among the many submissions, about a dozen particularly exceptional entries are awarded.\n\n    Curious about what kind of programs win? It is a code like this, this whole text itself.\n\n    ';BEGIN{eval$q=%q(def don(e)=e;def You(g)=at_exit{puts\"You don'#{g}';BEGIN{eval$q=%q(#$q)};$s=%!#$s!\"})};$s=%!\n    puts %(Nb, lbh unir gb pbcl gur jubyr grkg, sebz \"Ybh qba'g xabj\" gb gur raq\").tr(\"a-z\",\"n-za-m\")\n\n    In this talk, we will showcase the winning entries from past TRICK contest and our own weird Ruby code.\n    We will explore various techniques for writing such programs.\n    By the end of this talk, you'll be ready to submit your original Ruby creations to TRICK 2025!\n  video_provider: \"youtube\"\n  video_id: \"Xdvalg_q_Jc\"\n\n- id: \"scott-werner-rubyconf-2024\"\n  title: \"Going Postel\"\n  raw_title: \"RubyConf 2024 Going Postel by Scott Werner\"\n  speakers:\n    - Scott Werner\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-15\"\n  description: |-\n    Postel’s Law states that we should be liberal in what we accept and\n    conservative in what we send. When working with code generated from LLMs, embracing\n    this principle is even more important. This talk explores and demonstrates live\n    the ways that Ruby’s flexibility makes this possible, why I think Ruby is a sleeping\n    giant in the future of LLM-generated code, and the key to unlocking generative\n    AI’s true power for software development.\n  video_provider: \"youtube\"\n  video_id: \"pCTse_sZwn0\"\n\n- id: \"jeremy-evans-rubyconf-2024\"\n  title: \"10 Years of Roda\"\n  raw_title: \"RubyConf 2024 10 Years of Roda by Jeremy Evans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-15\"\n  description: |-\n    Roda is a Ruby web toolkit that uses a routing tree. It integrates routing with request handling, which significantly simplifies the development of web applications. Roda has a small core and an extensive plugin system, which has allowed it to add many features while significantly increasing performance.\n\n    The first conference presentation on Roda was given 10 years ago at RubyConf 2014. Come learn about Roda, the progress Roda has made since then, how Roda powers open source frameworks and applications, and why you may want to use Roda for your next web application.\n  video_provider: \"youtube\"\n  video_id: \"GrYlZjbXeP8\"\n\n- id: \"fabio-leandro-janiszevski-rubyconf-2024\"\n  title: \"Detecting and classifying object images using ruby\"\n  raw_title: \"RubyConf 2024 Detecting and classifying object images using ruby by Fabio Leandro Janiszevski\"\n  speakers:\n    - Fabio Leandro Janiszevski\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-15\"\n  slides_url: \"https://docs.google.com/presentation/d/10uMgsRnllndUjkbcRL1O-qNEcy49UW3MlE2SZdqUGAo/edit\"\n  description: |-\n    When we discuss Digital Image Processing, we always encounter other\n    programming languages but Ruby. Today, Ruby will rise in this topic! I'll discuss\n    the Ruby implementations that helped me write code to detect objects in a tiled\n    image and then classify them using deep learning techniques. AI is right there!\n\n    Repo: https://github.com/fabiosammy/rubyconf2024\n  video_provider: \"youtube\"\n  video_id: \"03wMU_yWZ7Y\"\n  additional_resources:\n    - name: \"fabiosammy/rubyconf2024\"\n      type: \"repo\"\n      url: \"https://github.com/fabiosammy/rubyconf2024\"\n\n- id: \"shannon-skipper-rubyconf-2024\"\n  title: \"Streaming over the web with modern Ruby\"\n  raw_title: \"RubyConf 2024 Streaming over the web with modern Ruby by Shannon Skipper\"\n  speakers:\n    - Shannon Skipper\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-15\"\n  description: |-\n    This session will explore streaming data over the web with modern Ruby. We’ll take a look at the new Rack 3 streaming interface and the state of Ruby HTTP client support for Server-Sent Events (SSE) and WebSockets over HTTP/2, and soon, HTTP/3. Then we’ll dive into practical code examples and demonstrate how to use Rack 3 streaming directly and how to leverage WebSockets and SSE with Roda to stream hypertext to the browser with HTMX representing the application state.\n\n    This session will provide foundational definitions along with practical insights and examples, showcasing how Ruby library advancements can be applied in real-world applications.\n  video_provider: \"youtube\"\n  video_id: \"WqYExpMWIUU\"\n\n- id: \"nadia-odunayo-rubyconf-2024\"\n  title: \"Keynote: The Case of the Peculiar Pattern - A Ruby Mystery Story\"\n  raw_title: \"RubyConf 2024 Keynote by Nadia Odunayo\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-15\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"pOW4vepSX8g\"\n\n- id: \"kinsey-durham-grace-rubyconf-2024-closing-remarks\"\n  title: \"Closing Remarks\"\n  raw_title: \"RubyConf 2024 Closing Remarks with Kinsey Durham Grace & Jim Remsik\"\n  speakers:\n    - Kinsey Durham Grace\n    - Jim Remsik\n  event_name: \"RubyConf 2024\"\n  published_at: \"2024-12-13\"\n  date: \"2024-11-15\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"D6ZVUze-VUk\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://sessionize.com/rubyconf-2026/\"\n  open_date: \"2026-02-10\"\n  close_date: \"2026-03-15\"\n- name: \"Ruby Runway: Pitch Competition\"\n  link: \"https://rubycentral.teamtailor.com/jobs/6963879-rubyconf-pitch-competition-the-ruby-runway\"\n  open_date: \"2025-12-30\"\n  close_date: \"2026-02-28\"\n- name: \"Community Day Application\"\n  link: \"https://docs.google.com/forms/d/e/1FAIpQLSeFyvgo05RYHsI-UPylYYq3KTgfgPPAE1pVZKhbVGXZKrIKFw/viewform\"\n  open_date: \"2026-03-17\"\n  close_date: \"2026-05-01\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2026/event.yml",
    "content": "---\nid: \"rubyconf-2026\"\ntitle: \"RubyConf 2026\"\nkind: \"conference\"\nlocation: \"Las Vegas, NV, United States\"\ndescription: \"\"\nstart_date: \"2026-07-14\"\nend_date: \"2026-07-16\"\ntickets_url: \"https://ti.to/rubyconf/rubyconf-2026\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\nyear: 2026\nbanner_background: \"#303A32\"\nfeatured_background: \"#303A32\"\nfeatured_color: \"#E3ECDB\"\ncoordinates:\n  latitude: 36.15717656477005\n  longitude: -115.3335261034805\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2026/sponsors.yml",
    "content": "# docs/ADDING_SPONSORS.md\n---\n- tiers:\n    - name: \"gold\"\n      level: 1\n      sponsors:\n        - name: \"Flagrant\"\n          website: \"https://www.beflagrant.com/\"\n          slug: \"flagrant\"\n          logo_url: \"https://rubyconf.org/images/sponsors/flagrant.svg\"\n    - name: \"silver\"\n      level: 2\n      sponsors:\n        - name: \"GitButler\"\n          website: \"https://gitbutler.com/\"\n          slug: \"gitbutler\"\n          logo_url: \"https://rubyconf.org/images/sponsors/gitbutler.png\"\n        - name: \"beyond\"\n          website: \"https://www.beyondfinance.com/\"\n          slug: \"beyond\"\n          logo_url: \"https://rubyconf.org/images/sponsors/beyond.png\"\n        - name: \"Judoscale\"\n          website: \"https://judoscale.com/\"\n          slug: \"judoscale\"\n          logo_url: \"https://rubyconf.org/images/sponsors/judoscale-logo-horizontal-color.png\"\n        - name: \"cedarcode\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"cedarcode\"\n          logo_url: \"https://rubyconf.org/images/sponsors/cedarcode-white.svg\"\n    - name: \"other\"\n      level: 3\n      sponsors:\n        - name: \"GitLab\"\n          website: \"https://gitlab.com/gitlab-com\"\n          slug: \"gitlab\"\n          logo_url: \"https://rubyconf.org/images/sponsors/gitlab-logo.svg\"\n          badge: \"Lanyards and Coffee\"\n        - name: \"typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"typesense\"\n          logo_url: \"https://rubyconf.org/images/sponsors/typesense.svg\"\n          badge: \"WiFi\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2026/venue.yml",
    "content": "---\nname: \"Red Rock Casino Resort and Spa\"\naddress:\n  street: \"11011 W Charleston Blvd\"\n  city: \"Las Vegas\"\n  region: \"NV\"\n  postal_code: \"89135\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"11011 W Charleston Blvd, Las Vegas, NV 89135\"\ncoordinates:\n  latitude: 36.15717656477005\n  longitude: -115.3335261034805\nmaps:\n  google: \"https://maps.app.goo.gl/Goj9wWUsVjLW1UGh9\"\n"
  },
  {
    "path": "data/rubyconf/rubyconf-2026/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rubyconf/series.yml",
    "content": "---\nname: \"RubyConf\"\nwebsite: \"https://rubyconf.org/\"\ntwitter: \"rubyconf\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"rubyconf\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"Confreaks\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\naliases:\n  - Ruby Conf\n  - Ruby Conference\n"
  },
  {
    "path": "data/rubyconf-africa/rubyconf-africa-2024/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://www.papercall.io/rubyconfafrica2024\"\n  open_date: \"2024-03-20\"\n  close_date: \"2024-07-20\"\n"
  },
  {
    "path": "data/rubyconf-africa/rubyconf-africa-2024/event.yml",
    "content": "---\nid: \"rubyconf-africa-2024\"\ntitle: \"RubyConf Africa 2024\"\ndescription: \"\"\nlocation: \"Nairobi, Kenya\"\nkind: \"conference\"\nstart_date: \"2024-07-26\"\nend_date: \"2024-07-27\"\nwebsite: \"https://rubyconf.africa/\"\ntwitter: \"ruby_african\"\ncoordinates:\n  latitude: -1.2920659\n  longitude: 36.8219462\n"
  },
  {
    "path": "data/rubyconf-africa/rubyconf-africa-2024/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyconf.africa/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-africa/rubyconf-africa-2025/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://www.papercall.io/rubyconfafrica2025\"\n  open_date: \"2025-01-31\"\n  close_date: \"2025-04-30\"\n"
  },
  {
    "path": "data/rubyconf-africa/rubyconf-africa-2025/event.yml",
    "content": "---\nid: \"rubyconf-africa-2025\"\ntitle: \"RubyConf Africa 2025\"\ndescription: \"\"\nlocation: \"Nairobi, Kenya\"\nkind: \"conference\"\nstart_date: \"2025-07-18\"\nend_date: \"2025-07-19\"\nwebsite: \"https://rubyconf.africa/\"\ntwitter: \"ruby_african\"\nbanner_background: \"#E2CEB5\"\nfeatured_background: \"#E2CEB5\"\nfeatured_color: \"#571217\"\ncoordinates:\n  latitude: -1.2920659\n  longitude: 36.8219462\n"
  },
  {
    "path": "data/rubyconf-africa/rubyconf-africa-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum Sponsors\"\n      description: |-\n        Our Platinum Sponsors are the foundational force behind this event!\n      level: 1\n      sponsors:\n        - name: \"Typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"Typesense\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1cd9EfIOFhF20DO6e6gp1y3Ma2qwNkn_1=w1000?authuser=1/view\"\n\n    - name: \"Gold Sponsors\"\n      description: |-\n        Our Gold Sponsors provide essential support, truly elevating our\n      level: 2\n      sponsors:\n        - name: \"KopoKopo\"\n          website: \"https://kopokopo.co.ke/\"\n          slug: \"KopoKopo\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1rbPtUhbySsMvTxITANOrj7qjXh_lvZMD=w1000?authuser=1/view\"\n\n    - name: \"Silver Sponsors\"\n      description: |-\n        Thank you to our Silver Sponsors for their strong and valued contributions!\n      level: 3\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"AppSignal\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1q24RR_XiJq0q8YMGVtUoOOjxtMJjkx0G=w1000?authuser=1/view\"\n\n    - name: \"Speaker Supporters\"\n      description: |-\n        Our Speaker Supporters help us bring inspiring voices to the stage!\n      level: 4\n      sponsors:\n        - name: \"Gurzu\"\n          website: \"https://gurzu.com/\"\n          slug: \"Gurzu\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1dOfsgA_Ly2JhJG3TnSVdgBt68nyNLKiG=w1000?authuser=1/view\"\n\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com/\"\n          slug: \"Shopify\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1COvHCKDTFpYhxrflB3ZmDzuFxbuZ7ahn=w1000?authuser=1/view\"\n\n        - name: \"Must Company\"\n          website: \"https://must.company/\"\n          slug: \"MustCompany\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1BZVa52wteUfgB3fstorMTaOCIc3HQ-mz=w1000?authuser=1/view\"\n\n    - name: \"Partner Sponsors\"\n      description: |-\n        These Partner Sponsors are key collaborators, making our event stronger!\n      level: 5\n      sponsors:\n        - name: \"Finplus Group\"\n          website: \"https://finplusgroup.com/\"\n          slug: \"FinplusGroup\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1CuboKibwV1OlHiVVNHGAPNJoiES9Ti-n=w1000?authuser=1/view\"\n\n        - name: \"Solutech\"\n          website: \"https://www.solutech.co.ke\"\n          slug: \"Solutech\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1-iON65nBrSTLiHE32SnKi2eQXqPGgv5v=w1000?authuser=1/view\"\n\n        - name: \"Daystar\"\n          website: \"https://www.daystar.ac.ke/\"\n          slug: \"Daystar\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1FSvAx1B_xPtkxZRKYFLaTgg8nd5FblH2=w1000?authuser=1/view\"\n\n        - name: \"Quikk Api\"\n          website: \"https://quickapi.io/\"\n          slug: \"QuikkApi\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1slL1cayhUKiieB_PoNUZtQ3pcZVCM7j_=w1000?authuser=1/view\"\n\n        - name: \"Prosper Hedge\"\n          website: \"https://www.prosperhedge.com/\"\n          slug: \"ProsperHedge\"\n          logo_url: \"https://lh3.googleusercontent.com/d/1nJJp_B1Vx_Tl8RpfGS_2hy2d0LPz1oum=w1000?authuser=1/view\"\n"
  },
  {
    "path": "data/rubyconf-africa/rubyconf-africa-2025/videos.yml",
    "content": "---\n# TODO: talk video IDs\n# TODO: talk descriptions\n# Website: https://rubyconf.africa/\n# Schedule: https://rubyconf.africa/schedule.html\n# Date: 2025-07-18 to 2025-07-19\n# Venue: Daystar University, Nairobi, Kenya\n\n# Day 1 - Friday, July 18, 2025\n\n- id: \"tom-rossi-rubyconf-africa-2025\"\n  title: \"Keynote: Are you my mother\"\n  raw_title: \"Are you my mother(Keynote)\"\n  speakers:\n    - Tom Rossi\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-18\"\n  video_provider: \"scheduled\"\n  video_id: \"tom-rossi-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"patrick-wendo-rubyconf-africa-2025\"\n  title: \"Read the tests, best way to get up to speed with a new codebase.\"\n  raw_title: \"Read the tests, best way to get up to speed with a new codebase\"\n  speakers:\n    - Patrick Wendo\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-18\"\n  video_provider: \"scheduled\"\n  video_id: \"patrick-wendo-rubyconf-africa-2025\"\n  description: |-\n    This is a talk advocating that developers write tests to make it easier to onboard other developers. Further that tests are important documentation for the code base as they will change with the codebase.\n  language: \"english\"\n  slides_url: \"https://speakerdeck.com/w3ndo/read-the-tests-best-way-to-get-up-to-speed-with-a-new-codebase\"\n\n- id: \"purity-maina-rubyconf-africa-2025\"\n  title: \"Automate Your Mundane: Small Scripts, Big Impact for Everyday Tasks\"\n  raw_title: \"Automate Your Mundane: Small Scripts, Big Impact for Everyday Tasks\"\n  speakers:\n    - Purity Maina\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-18\"\n  video_provider: \"scheduled\"\n  video_id: \"purity-maina-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"dmitry-pogrebnoy-rubyconf-africa-2025\"\n  title: \"Demystifying Ruby Debuggers: A Deep Dive into Internals\"\n  raw_title: \"Demystifying Ruby Debuggers: A Deep Dive into Internals\"\n  speakers:\n    - Dmitry Pogrebnoy\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-18\"\n  video_provider: \"scheduled\"\n  video_id: \"dmitry-pogrebnoy-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"panel-rubyconf-africa-2025\"\n  title: \"Panel\"\n  raw_title: \"Panel\"\n  speakers:\n    - Tom Rossi\n    - Amani Kanu\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-18\"\n  video_provider: \"scheduled\"\n  video_id: \"panel-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"kariuki-gathitu-rubyconf-africa-2025\"\n  title: \"Building Scalable APIs with Roda: Lessons from Quikk's Journey\"\n  raw_title: \"Building Scalable APIs with Roda: Lessons from Quikk's Journey\"\n  speakers:\n    - Kariuki Gathitu\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-18\"\n  video_provider: \"scheduled\"\n  video_id: \"kariuki-gathitu-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"ganesh-kunwar-rubyconf-africa-2025\"\n  title: \"Optimizing for Efficiency: How Rails Helps Eliminate Development Waste\"\n  raw_title: \"Optimizing for Efficiency: How Rails Helps Eliminate Development Waste\"\n  speakers:\n    - Ganesh Kunwar\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-18\"\n  video_provider: \"scheduled\"\n  video_id: \"ganesh-kunwar-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n# Day 2 - Saturday, July 19, 2025\n\n- id: \"marek-piasecki-rubyconf-africa-2025\"\n  title: \"How to make yet another framework\"\n  raw_title: \"How to make yet another framework\"\n  speakers:\n    - Marek Piasecki\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"marek-piasecki-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"tresor-bireke-rubyconf-africa-2025\"\n  title: \"Move fast but don’t break things: How to balance delivery speed and reliability\"\n  raw_title: \"Move fast but don't break things: How to balance delivery speed and reliability\"\n  speakers:\n    - Tresor Bireke\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"tresor-bireke-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"caleb-muoki-rubyconf-africa-2025\"\n  title: \"DevOps is Dead, Long Live Platform Engineering\"\n  raw_title: \"DevOps is Dead, Long Live Platform Engineering\"\n  speakers:\n    - Caleb Muoki\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"caleb-muoki-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"amani-kanu-rubyconf-africa-2025\"\n  title: \"Mentorship - Tool for the Future\"\n  raw_title: \"Mentorship - Tool for the Future\"\n  speakers:\n    - Amani Kanu\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"amani-kanu-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"njonge-fred-rubyconf-africa-2025\"\n  title: \"Beyond Code: The Future of Ruby in a Changing Tech Landscape\"\n  raw_title: \"Beyond Code: The Future of Ruby in a Changing Tech Landscape\"\n  speakers:\n    - Njonge Fred\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"njonge-fred-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"obie-fernandez-rubyconf-africa-2025\"\n  title: \"Patterns of Application Development Using AI Revisited\"\n  raw_title: \"Patterns of Application Development Using AI Revisited\"\n  speakers:\n    - Obie Fernandez\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"obie-fernandez-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"victor-turuthi-rubyconf-africa-2025\"\n  title: \"Performance Without Compromise: Supercharging Ruby Applications with Foreign Function Interface\"\n  raw_title: \"Performance Without Compromise: Supercharging Ruby Applications with Foreign Function Interface\"\n  speakers:\n    - Victor Turuthi\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"victor-turuthi-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n\n- id: \"matz-rubyconf-africa-2025\"\n  title: \"Keynote\"\n  raw_title: \"Keynote\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf Africa 2025\"\n  date: \"2025-07-19\"\n  video_provider: \"scheduled\"\n  video_id: \"matz-rubyconf-africa-2025\"\n  description: \"\"\n  language: \"english\"\n"
  },
  {
    "path": "data/rubyconf-africa/rubyconf-africa-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://www.papercall.io/ruby-conf-africa-2026\"\n  open_date: \"2025-11-20\"\n  close_date: \"2026-03-11\"\n"
  },
  {
    "path": "data/rubyconf-africa/rubyconf-africa-2026/event.yml",
    "content": "---\nid: \"rubyconf-africa-2026\"\ntitle: \"RubyConf Africa 2026\"\nkind: \"conference\"\nlocation: \"Nairobi, Kenya\"\ndescription: \"\"\nstart_date: \"2026-08-21\"\nend_date: \"2026-08-22\"\nwebsite: \"https://rubyconf.africa/\"\ntwitter: \"ruby_african\"\nbanner_background: \"#E2CEB5\"\nfeatured_background: \"#E2CEB5\"\nfeatured_color: \"#571217\"\ncoordinates:\n  latitude: -1.2920659\n  longitude: 36.8219462\n"
  },
  {
    "path": "data/rubyconf-africa/rubyconf-africa-2026/videos.yml",
    "content": "---\n# Website: https://rubyconf.africa/\n[]\n"
  },
  {
    "path": "data/rubyconf-africa/series.yml",
    "content": "---\nname: \"RubyConf Africa\"\nwebsite: \"https://rubyconf.africa/\"\ntwitter: \"ruby_african\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\n"
  },
  {
    "path": "data/rubyconf-argentina/rubyconf-argentina-2011/event.yml",
    "content": "---\nid: \"rubyconf-argentina-2011\"\ntitle: \"RubyConf Argentina 2011\"\ndescription: \"\"\nlocation: \"Buenos Aires, Argentina\"\nkind: \"conference\"\nstart_date: \"2011-11-08\"\nend_date: \"2011-11-09\"\nwebsite: \"https://web.archive.org/web/20111028103035/http://rubyconfargentina.org/en\"\ntwitter: \"rubyconfar\"\nplaylist: \"\"\ncoordinates:\n  latitude: -34.6036739\n  longitude: -58.3821215\n"
  },
  {
    "path": "data/rubyconf-argentina/rubyconf-argentina-2011/videos.yml",
    "content": "---\n- id: \"matt-aimonetti-rubyconf-argentina-2011\"\n  title: \"Inside Ruby: concurrency & garbage collection explained\"\n  raw_title: \"Matt Aimonetti - Inside Ruby: concurrency & garbage collection explained\"\n  speakers:\n    - \"Matt Aimonetti\"\n  date: \"2011-11-08\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"AYUYVSUSXGU\"\n\n- id: \"koichiro-eto-rubyconf-argentina-2011\"\n  title: \"The Timeless Way of Software Development\"\n  raw_title: \"Koichiro Eto - The Timeless Way of Software Development\"\n  speakers:\n    - Koichiro Eto\n  date: \"2011-11-08\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"ua3TqCeFVgU\"\n\n- id: \"luis-lavena-rubyconf-argentina-2011\"\n  title: \"Tirando Ruby por la Ventana\"\n  raw_title: \"Luis Lavena - Tirando Ruby por la Ventana\"\n  speakers:\n    - Luis Lavena\n  date: \"2011-11-08\"\n  event_name: \"RubyConf Argentina 2011\"\n  language: \"spanish\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"Ja97xUzaakM\"\n\n- id: \"alex-coles-rubyconf-argentina-2011\"\n  title: \"The quiet and versatile Rubyist\"\n  raw_title: \"Alex Coles - The quiet and versatile Rubyist\"\n  speakers:\n    - Alex Coles\n  date: \"2011-11-08\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"yvslkx7XHeU\"\n\n- id: \"pedro-belo-rubyconf-argentina-2011\"\n  title: \"On distributed systems lessons learned at Heroku\"\n  raw_title: \"Pedro Belo - On distributed systems lessons learned at Heroku\"\n  speakers:\n    - Pedro Belo\n  date: \"2011-11-08\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"YkqT6wceUmg\"\n\n- id: \"federico-brubacher-rubyconf-argentina-2011\"\n  title: \"Cómo ser un data scientist con Ruby\"\n  raw_title: \"Federico Brubacher y Bruno Aguirre - Cómo ser un data scientist con Ruby\"\n  speakers:\n    - Federico Brubacher\n    - Bruno Aguirre\n  date: \"2011-11-08\"\n  event_name: \"RubyConf Argentina 2011\"\n  language: \"spanish\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"FQ9ztj_w3I8\"\n\n- id: \"patrick-huesler-rubyconf-argentina-2011\"\n  title: \"Monitoring with Syslog and EventMachine\"\n  raw_title: \"Patrick Huesler - Monitoring with Syslog and EventMachine\"\n  speakers:\n    - Patrick Huesler\n  date: \"2011-11-08\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"w26fYiv5JiA\"\n\n- id: \"yutaka-hara-rubyconf-argentina-2011\"\n  title: \"Ruby's past, present, and future\"\n  raw_title: \"Yutaka Hara - Ruby's past, present, and future\"\n  speakers:\n    - Yutaka HARA\n  date: \"2011-11-08\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-15\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"Kby1YWZW7v4\"\n\n- id: \"sean-cribbs-rubyconf-argentina-2011\"\n  title: \"Embrace NoSQL and Eventual Consistency with Ripple\"\n  raw_title: \"Sean Cribbs - Embrace NoSQL and Eventual Consistency with Ripple\"\n  speakers:\n    - Sean Cribbs\n  date: \"2011-11-09\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"tc-ujKld4Nw\"\n\n- id: \"konstantin-haase-rubyconf-argentina-2011\"\n  title: \"Beyond Ruby\"\n  raw_title: \"Konstantin Haase - Beyond Ruby\"\n  speakers:\n    - Konstantin Haase\n  date: \"2011-11-09\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"t62enAAy61Q\"\n\n- id: \"norman-clarke-rubyconf-argentina-2011\"\n  title: \"Back to the future  with SQL and stored procedures\"\n  raw_title: \"Norman Clarke - Back to the future  with SQL and stored procedures\"\n  speakers:\n    - Norman Clarke\n  date: \"2011-11-09\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"LZbKF6s9-A0\"\n\n- id: \"aaron-patterson-rubyconf-argentina-2011\"\n  title: \"Who makes the best asado\"\n  raw_title: \"Aaron Patterson - Who makes the best asado\"\n  speakers:\n    - Aaron Patterson\n  date: \"2011-11-09\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"WvJ3TphJ9DE\"\n\n- id: \"nicolas-sanguinetti-rubyconf-argentina-2011\"\n  title: \"Testing it's a horrible idea!\"\n  raw_title: \"Nicolás Sanguinetti - Testing it's a horrible idea!\"\n  speakers:\n    - Nicolás Sanguinetti\n  date: \"2011-11-09\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-16\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"m0KoH-8Np0I\"\n\n- id: \"scott-chacon-rubyconf-argentina-2011\"\n  title: \"Un cuento de tres árboles\"\n  raw_title: \"Scott Chacon - Un cuento de tres árboles\"\n  speakers:\n    - Scott Chacon\n  date: \"2011-11-09\"\n  event_name: \"RubyConf Argentina 2011\"\n  language: \"spanish\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"_6iVjOfRi88\"\n\n- id: \"blake-mizerany-rubyconf-argentina-2011\"\n  title: \"On distributed failures\"\n  raw_title: \"Blake Mizerany - On distributed failures\"\n  speakers:\n    - Blake Mizerany\n  date: \"2011-11-09\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"kAm9ZAe66nI\"\n\n- id: \"narihiro-nakamura-rubyconf-argentina-2011\"\n  title: \"Parallel worlds of CRuby's GC\"\n  raw_title: \"Narihiro Nakamura - Parallel worlds of CRuby's GC\"\n  speakers:\n    - Narihiro Nakamura\n  date: \"2011-11-09\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"hLt9fFUhEIM\"\n\n- id: \"tom-preston-werner-rubyconf-argentina-2011\"\n  title: \"Optimizing for Happiness\"\n  raw_title: \"Tom Preston Werner - Optimizing for Happiness\"\n  speakers:\n    - Tom Preston Werner\n  date: \"2011-11-09\"\n  event_name: \"RubyConf Argentina 2011\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2011\n  video_provider: \"youtube\"\n  video_id: \"ZFPRYRukeOU\"\n"
  },
  {
    "path": "data/rubyconf-argentina/rubyconf-argentina-2012/event.yml",
    "content": "---\nid: \"rubyconf-argentina-2012\"\ntitle: \"RubyConf Argentina 2012\"\ndescription: \"\"\nlocation: \"Buenos Aires, Argentina\"\nkind: \"conference\"\nstart_date: \"2012-10-15\"\nend_date: \"2012-10-16\"\nwebsite: \"https://web.archive.org/web/20130617134243/http://rubyconfargentina.org/en\"\ntwitter: \"rubyconfar\"\nplaylist: \"\"\ncoordinates:\n  latitude: -34.6036739\n  longitude: -58.3821215\n"
  },
  {
    "path": "data/rubyconf-argentina/rubyconf-argentina-2012/videos.yml",
    "content": "---\n- id: \"jano-gonzalez-rubyconf-argentina-2012\"\n  title: \"¿Dónde están mis interfaces?\"\n  raw_title: \"Jano González - ¿Dónde están mis interfaces?\"\n  speakers:\n    - Jano González\n  date: \"2012-10-15\"\n  event_name: \"RubyConf Argentina 2012\"\n  language: \"spanish\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"-CpSwKVunmk\"\n\n- id: \"andy-atkinson-rubyconf-argentina-2012\"\n  title: \"Ship it: Staying Lean at LivingSocial\"\n  raw_title: \"Andy Atkinson - Ship it: Staying Lean at LivingSocial\"\n  speakers:\n    - \"Andy Atkinson\"\n  date: \"2012-10-15\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"EvSWKzApUiU\"\n\n- id: \"michel-martens-rubyconf-argentina-2012\"\n  title: \"The Power of Small Tools\"\n  raw_title: \"Michel Martens - The Power of Small Tools\"\n  speakers:\n    - Michel Martens\n  date: \"2012-10-15\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"Lk9jkSMaBWc\"\n\n- id: \"bruno-aguirre-rubyconf-argentina-2012\"\n  title: \"The web of tomorrow\"\n  raw_title: \"Bruno Aguirre - The web of tomorrow\"\n  speakers:\n    - Bruno Aguirre\n  date: \"2012-10-15\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"U_Z03ZCrpr0\"\n\n- id: \"florian-gilcher-rubyconf-argentina-2012\"\n  title: \"Self improvement for pros\"\n  raw_title: \"Florian Gilcher - Self improvement for pros\"\n  speakers:\n    - Florian Gilcher\n  date: \"2012-10-15\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"-tGithm-pPU\"\n\n- id: \"wynn-netherland-rubyconf-argentina-2012\"\n  title: \"API logetics\"\n  raw_title: \"Wynn Netherland - API logetics\"\n  speakers:\n    - Wynn Netherland\n  date: \"2012-10-15\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"FzOcZODhVVY\"\n\n- id: \"santiago-pastorino-rubyconf-argentina-2012\"\n  title: \"Rails 4 en 30 minutos\"\n  raw_title: \"Santiago Pastorino - Rails 4 en 30 minutos\"\n  speakers:\n    - Santiago Pastorino\n  date: \"2012-10-15\"\n  event_name: \"RubyConf Argentina 2012\"\n  language: \"spanish\"\n  published_at: \"2018-01-18\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"D7HqJ_Cdl0w\"\n\n- id: \"nicolas-sztabzyb-rubyconf-argentina-2012\"\n  title: \"Dealing with designers\"\n  raw_title: \"Nicolás Sztabzyb y Lucas Florio - Dealing with designers\"\n  speakers:\n    - Nicolás Sztabzyb\n    - Lucas Florio\n  date: \"2012-10-15\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-19\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"Q8goAc2qdRo\"\n\n- id: \"nick-sutterer-rubyconf-argentina-2012\"\n  title: \"Off the Tracks: Challenging the Rails Mindset\"\n  raw_title: \"Nick Sutterer - Off the Tracks: Challenging the Rails Mindset\"\n  speakers:\n    - \"Nick Sutterer\"\n  date: \"2012-10-15\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-19\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"FpypqLkJANQ\"\n\n- id: \"martin-salias-rubyconf-argentina-2012\"\n  title: \"REST in peace\"\n  raw_title: \"Martín Salías - REST in peace\"\n  speakers:\n    - Martín Salías\n  date: \"2012-10-16\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-19\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"8qu1LJAfptA\"\n\n- id: \"jeff-casimir-rubyconf-argentina-2012\"\n  title: \"Internationalization Isn't a Bad Word\"\n  raw_title: \"Jeff Casimir - Internationalization Isn't a Bad Word\"\n  speakers:\n    - Jeff Casimir\n  date: \"2012-10-16\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-19\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"UqHTkVpNu-c\"\n\n- id: \"bermon-painter-rubyconf-argentina-2012\"\n  title: \"Rapid Prototyping with Sass, Compass and Nanoc\"\n  raw_title: \"Bermon Painter - Rapid Prototyping with Sass, Compass and Nanoc\"\n  speakers:\n    - Bermon Painter\n  date: \"2012-10-16\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-19\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"diVKCgXa2v4\"\n\n- id: \"david-calavera-rubyconf-argentina-2012\"\n  title: \"Escalabilidad en lo desconocido: GitHub Enterprise\"\n  raw_title: \"David Calavera - Escalabilidad en lo desconocido: GitHub Enterprise\"\n  speakers:\n    - \"David Calavera\"\n  date: \"2012-10-16\"\n  event_name: \"RubyConf Argentina 2012\"\n  language: \"spanish\"\n  published_at: \"2018-01-19\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"ygMfvK1fwNY\"\n\n- id: \"ernesto-tagwerker-rubyconf-argentina-2012\"\n  title: \"The Lean Startup Hacker\"\n  raw_title: \"Ernesto Tagwerker - The Lean Startup Hacker\"\n  speakers:\n    - Ernesto Tagwerker\n  date: \"2012-10-16\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-19\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"83CCnk7TVl4\"\n\n- id: \"krzysztof-kowalik-rubyconf-argentina-2012\"\n  title: \"Ruby sometimes sucks\"\n  raw_title: \"Krzysztof Kowalik y Pablo Astigarraga - Ruby sometimes sucks\"\n  speakers:\n    - Krzysztof Kowalik\n    - Pablo Astigarraga\n  date: \"2012-10-16\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-19\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"rv36RVKyYX0\"\n\n- id: \"augusto-becciu-rubyconf-argentina-2012\"\n  title: \"Infrastructure as Ruby code\"\n  raw_title: \"Augusto Becciu - Infrastructure as Ruby code\"\n  speakers:\n    - Augusto Becciu\n  date: \"2012-10-16\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-19\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"-_mS5x6raWw\"\n\n- id: \"steve-klabnik-rubyconf-argentina-2012\"\n  title: \"Development and Philosophy\"\n  raw_title: \"Steve Klabnik - Development and Philosophy\"\n  speakers:\n    - Steve Klabnik\n  date: \"2012-10-16\"\n  event_name: \"RubyConf Argentina 2012\"\n  published_at: \"2018-01-19\"\n  description: |-\n    RubyConf Argentina 2012\n  video_provider: \"youtube\"\n  video_id: \"vJX3nBB9AwA\"\n"
  },
  {
    "path": "data/rubyconf-argentina/rubyconf-argentina-2013/event.yml",
    "content": "---\nid: \"rubyconf-argentina-2013\"\ntitle: \"RubyConf Argentina 2013\"\ndescription: \"\"\nlocation: \"Buenos Aires, Argentina\"\nkind: \"conference\"\nstart_date: \"2013-11-27\"\nend_date: \"2013-11-28\"\nwebsite: \"https://2013.rubyconfargentina.org/en\"\ntwitter: \"rubyconfar\"\nplaylist: \"\"\ncoordinates:\n  latitude: -34.6036739\n  longitude: -58.3821215\n"
  },
  {
    "path": "data/rubyconf-argentina/rubyconf-argentina-2013/videos.yml",
    "content": "---\n- id: \"thomas-edward-figg-rubyconf-argentina-2013\"\n  title: \"Programming is terrible: Lessons learned from a life wasted\"\n  raw_title: \"Thomas Edward Figg - Programming is terrible: Lessons learned from a life wasted\"\n  speakers:\n    - \"Thomas Edward Figg\"\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  published_at: \"2018-01-23\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"_eVcYAIzJfA\"\n\n- id: \"pablo-astigarraga-rubyconf-argentina-2013\"\n  title: \"Las 50 sombras de MVC\"\n  raw_title: \"Pablo Astigarraga - Las 50 sombras de MVC\"\n  speakers:\n    - Pablo Astigarraga\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  language: \"spanish\"\n  published_at: \"2018-01-23\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"ChJg7kOQi_E\"\n\n- id: \"cecilia-rivero-rubyconf-argentina-2013\"\n  title: \"Aplicación open source para búsquedas laborales\"\n  raw_title: \"Cecilia Rivero y Mayn E Kjæ - Primer proyecto: Aplicación open source para búsquedas laborales\"\n  speakers:\n    - Cecilia Rivero\n    - Mayn E Kjæ\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  language: \"spanish\"\n  published_at: \"2018-01-25\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"2k9iTUlr_ec\"\n\n- id: \"thiago-pradi-rubyconf-argentina-2013\"\n  title: \"Go for Rubyists\"\n  raw_title: \"Thiago Pradi - Go for Rubyists\"\n  speakers:\n    - Thiago Pradi\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  published_at: \"2018-01-29\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"t-D8dYAEA54\"\n\n- id: \"ostap-cherkashin-rubyconf-argentina-2013\"\n  title: \"Gluing Data Together\"\n  raw_title: \"Ostap Cherkashin - Gluing Data Together\"\n  speakers:\n    - Ostap Cherkashin\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  published_at: \"2018-01-29\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"f0JHSMEH3PA\"\n\n- id: \"justine-arreche-rubyconf-argentina-2013\"\n  title: \"Escondamos los cuchillos: Podemos trabajar juntos!\"\n  raw_title: \"Justine Arreche - Escondamos los cuchillos: Podemos trabajar juntos!\"\n  speakers:\n    - \"Justine Arreche\"\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  language: \"spanish\"\n  published_at: \"2018-01-29\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"djeWBum-jSc\"\n\n- id: \"santiago-pastorino-rubyconf-argentina-2013\"\n  title: \"Del trabajo a la pasión\"\n  raw_title: \"Santiago Pastorino - Del trabajo a la pasión\"\n  speakers:\n    - Santiago Pastorino\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  language: \"spanish\"\n  published_at: \"2018-01-29\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"gxcZhvymnrE\"\n\n- id: \"augusto-becciu-rubyconf-argentina-2013\"\n  title: \"Construyendo una plataforma de datos con Ruby glue\"\n  raw_title: \"Augusto Becciu - Construyendo una plataforma de datos con Ruby glue\"\n  speakers:\n    - Augusto Becciu\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  language: \"spanish\"\n  published_at: \"2018-01-29\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"MT3l182ZO_A\"\n\n- id: \"hanneli-tavante-rubyconf-argentina-2013\"\n  title: \"Server side Ruby tips for mobile apps\"\n  raw_title: \"Hanneli Tavante - Server side Ruby tips for mobile apps\"\n  speakers:\n    - Hanneli Tavante\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  published_at: \"2018-01-29\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"bHzlHPpQo8I\"\n\n- id: \"cristian-rasch-rubyconf-argentina-2013\"\n  title: \"Rack and roll\"\n  raw_title: \"Cristian Rasch - Rack and roll\"\n  speakers:\n    - Cristian Rasch\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  published_at: \"2018-01-29\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"WGNy2mv9ABU\"\n\n- id: \"jano-gonzalez-rubyconf-argentina-2013\"\n  title: \"El programador bipolar\"\n  raw_title: \"Jano González - El programador bipolar\"\n  speakers:\n    - Jano González\n  date: \"2013-11-27\"\n  event_name: \"RubyConf Argentina 2013\"\n  language: \"spanish\"\n  published_at: \"2018-01-29\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"I3HrNj-Trcw\"\n\n- id: \"martin-sarsale-rubyconf-argentina-2013\"\n  title: \"IPython Notebook con Ruby!\"\n  raw_title: \"Martín Sarsale - IPython Notebook con Ruby!\"\n  speakers:\n    - Martín Sarsale\n  date: \"2013-11-28\"\n  event_name: \"RubyConf Argentina 2013\"\n  language: \"spanish\"\n  published_at: \"2018-01-31\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"e6l-_3gMaaI\"\n\n- id: \"vitor-pellegrino-rubyconf-argentina-2013\"\n  title: \"Separando un Monoriel Micro servicios y más allá\"\n  raw_title: \"Vitor Pellegrino y Sergio Gil - Separando un Monoriel  Micro servicios y más allá\"\n  speakers:\n    - Vitor Pellegrino\n    - Sergio Gil\n  date: \"2013-11-28\"\n  event_name: \"RubyConf Argentina 2013\"\n  language: \"spanish\"\n  published_at: \"2018-01-31\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"MKczHdtrkmY\"\n\n- id: \"linda-sandvik-rubyconf-argentina-2013\"\n  title: \"Code Club: Hacking the future\"\n  raw_title: \"Linda Sandvik - Code Club: Hacking the future\"\n  speakers:\n    - \"Linda Sandvik\"\n  date: \"2013-11-28\"\n  event_name: \"RubyConf Argentina 2013\"\n  published_at: \"2018-02-03\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"kfVRyk7vfmA\"\n\n- id: \"alexandre-de-oliveira-rubyconf-argentina-2013\"\n  title: \"Forget about classes, welcome objects\"\n  raw_title: \"Alexandre de Oliveira - Forget about classes, welcome objects\"\n  speakers:\n    - Alexandre de Oliveira\n  date: \"2013-11-28\"\n  event_name: \"RubyConf Argentina 2013\"\n  published_at: \"2018-02-04\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"LAm00Ni4mvM\"\n\n- id: \"brock-whitten-rubyconf-argentina-2013\"\n  title: \"Lessons learned building the Harp Platform\"\n  raw_title: \"Brock Whitten - Lessons learned building the Harp Platform\"\n  speakers:\n    - Brock Whitten\n  date: \"2013-11-28\"\n  event_name: \"RubyConf Argentina 2013\"\n  published_at: \"2018-02-05\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"TTiG0SZoe9w\"\n\n- id: \"adrian-mugnolo-rubyconf-argentina-2013\"\n  title: \"Lo suficiente de Unix como para ser peligroso\"\n  raw_title: \"Adrián Mugnolo - Lo suficiente de Unix como para ser peligroso\"\n  speakers:\n    - Adrián Mugnolo\n  date: \"2013-11-28\"\n  event_name: \"RubyConf Argentina 2013\"\n  language: \"spanish\"\n  published_at: \"2018-02-06\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"DzXLDorgGxo\"\n\n- id: \"andrs-robalino-rubyconf-argentina-2013\"\n  title: \"Ruby Kryptography\"\n  raw_title: \"Andrés Robalino - Ruby Kryptography\"\n  speakers:\n    - Andrés Robalino\n  date: \"2013-11-28\"\n  event_name: \"RubyConf Argentina 2013\"\n  published_at: \"2018-02-06\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"lcw97Bm9KOQ\"\n\n- id: \"bruno-aguirre-rubyconf-argentina-2013\"\n  title: \"Break the Rules\"\n  raw_title: \"Bruno Aguirre - Break the Rules\"\n  speakers:\n    - Bruno Aguirre\n  date: \"2013-11-28\"\n  event_name: \"RubyConf Argentina 2013\"\n  published_at: \"2018-02-06\"\n  description: |-\n    RubyConf Argentina 2013\n  video_provider: \"youtube\"\n  video_id: \"hOaF1ZgFNZo\"\n"
  },
  {
    "path": "data/rubyconf-argentina/rubyconf-argentina-2014/event.yml",
    "content": "---\nid: \"rubyconf-argentina-2014\"\ntitle: \"RubyConf Argentina 2014\"\ndescription: \"\"\nlocation: \"Buenos Aires, Argentina\"\nkind: \"conference\"\nstart_date: \"2014-10-24\"\nend_date: \"2014-10-25\"\nwebsite: \"https://rubyconfargentina.org/index_es.html\"\ntwitter: \"rubyconfar\"\nplaylist: \"\"\ncoordinates:\n  latitude: -34.6036739\n  longitude: -58.3821215\n"
  },
  {
    "path": "data/rubyconf-argentina/rubyconf-argentina-2014/videos.yml",
    "content": "---\n- id: \"jano-gonzalez-rubyconf-argentina-2014\"\n  title: \"Microservicios en la práctica\"\n  raw_title: \"Jano González - Microservicios en la práctica\"\n  speakers:\n    - Jano González\n  date: \"2014-10-24\"\n  event_name: \"RubyConf Argentina 2014\"\n  language: \"spanish\"\n  published_at: \"2018-02-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"YRXu4Golk9I\"\n\n- id: \"lucas-videla-rubyconf-argentina-2014\"\n  title: \"You already git started. Now what?\"\n  raw_title: \"Lucas Videla - You already git started. Now what?\"\n  speakers:\n    - Lucas Videla\n  date: \"2014-10-24\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"LACyH2itUGA\"\n\n- id: \"hanneli-tavante-rubyconf-argentina-2014\"\n  title: \"Our daily graphs written in Ruby and Neo4j\"\n  raw_title: \"Hanneli Tavante - Our daily graphs written in Ruby and Neo4j\"\n  speakers:\n    - Hanneli Tavante\n  date: \"2014-10-24\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"B_yOITpjYSQ\"\n\n- id: \"paul-smith-rubyconf-argentina-2014\"\n  title: \"Derailing irrationality\"\n  raw_title: \"Paul smith - Derailing irrationality\"\n  speakers:\n    - Paul smith\n  date: \"2014-10-24\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"CJNKroPvSJA\"\n\n- id: \"federico-carrone-rubyconf-argentina-2014\"\n  title: \"Concurrency for Rubyists\"\n  raw_title: \"Federico Carrone - Concurrency for Rubyists\"\n  speakers:\n    - Federico Carrone\n  date: \"2014-10-24\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-08\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"aoN1NBxlf-0\"\n\n- id: \"lucia-escanellas-rubyconf-argentina-2014\"\n  title: \"Look ma', I know my algorithms\"\n  raw_title: \"Lucía Escanellas - Look ma', I know my algorithms!\"\n  speakers:\n    - Lucía Escanellas\n  date: \"2014-10-24\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"xfDVvUMrWK8\"\n\n- id: \"ignacio-piantanida-rubyconf-argentina-2014\"\n  title: \"Ruby on your pocket with RubyMotion\"\n  raw_title: \"Ignacio Piantanida - Ruby on your pocket with RubyMotion\"\n  speakers:\n    - Ignacio Piantanida\n  date: \"2014-10-24\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8LmhdAOmIQ8\"\n\n- id: \"damian-janowsky-rubyconf-argentina-2014\"\n  title: \"Redis: más allá del caché y las colas\"\n  raw_title: \"Damian Janowsky - Redis: más allá del caché y las colas\"\n  speakers:\n    - \"Damian Janowsky\"\n  date: \"2014-10-24\"\n  event_name: \"RubyConf Argentina 2014\"\n  language: \"spanish\"\n  published_at: \"2018-02-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5XUQZR9NDIU\"\n\n- id: \"emilio-gutter-rubyconf-argentina-2014\"\n  title: \"Los Diez Mandamientos del Programador en Ruby\"\n  raw_title: \"Emilio Gutter - Los Diez Mandamientos del Programador en Ruby\"\n  speakers:\n    - Emilio Gutter\n  date: \"2014-10-24\"\n  event_name: \"RubyConf Argentina 2014\"\n  language: \"spanish\"\n  published_at: \"2018-02-09\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"oc6l-ubzWRs\"\n\n- id: \"patricio-bruna-rubyconf-argentina-2014\"\n  title: \"De desarrollo a producción con Docker\"\n  raw_title: \"Patricio Bruna - De desarrollo a producción con Docker\"\n  speakers:\n    - Patricio Bruna\n  date: \"2014-10-25\"\n  event_name: \"RubyConf Argentina 2014\"\n  language: \"spanish\"\n  published_at: \"2018-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ZLLedMuDcpM\"\n\n- id: \"juan-barreneche-rubyconf-argentina-2014\"\n  title: \"Data analysis for startups\"\n  raw_title: \"Juan Barreneche - Data analysis for startups\"\n  speakers:\n    - Juan Barreneche\n  date: \"2014-10-25\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"KgwkuyljzJo\"\n\n- id: \"marta-paciorkowska-rubyconf-argentina-2014\"\n  title: \"Programming, languages, literature\"\n  raw_title: \"Marta Paciorkowska - Programming, languages, literature\"\n  speakers:\n    - Marta Paciorkowska\n  date: \"2014-10-25\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"9sUvT0faNMc\"\n\n- id: \"federico-builes-rubyconf-argentina-2014\"\n  title: \"Practical EventMachine\"\n  raw_title: \"Federico Builes - Practical EventMachine\"\n  speakers:\n    - Federico Builes\n  date: \"2014-10-25\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"seqATiP6Pps\"\n\n- id: \"todo-rubyconf-argentina-2014\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  speakers:\n    - TODO\n  date: \"2014-10-25\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-12\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"w90f1FLk9jc\"\n\n- id: \"chris-hunt-rubyconf-argentina-2014\"\n  title: \"Resolviendo el Cubo Rubik con los ojos vendados\"\n  raw_title: \"Chris Hunt - Resolviendo el Cubo Rubik con los ojos vendados\"\n  speakers:\n    - Chris Hunt\n  date: \"2014-10-25\"\n  event_name: \"RubyConf Argentina 2014\"\n  language: \"spanish\"\n  published_at: \"2018-02-12\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"oJm5gmnTvks\"\n\n- id: \"lucas-dohmen-rubyconf-argentina-2014\"\n  title: \"ArangoDB, A different approach to NoSQL\"\n  raw_title: \"Lucas Dohmen - ArangoDB, A different approach to NoSQL\"\n  speakers:\n    - Lucas Dohmen\n  date: \"2014-10-25\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-12\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"BQ1hbpnd4i0\"\n\n- id: \"augusto-becciu-rubyconf-argentina-2014\"\n  title: \"Construyendo tu propio motor de búsqueda con JRuby y Lucene\"\n  raw_title: \"Augusto Becciu - Construyendo tu propio motor de búsqueda con JRuby y Lucene\"\n  speakers:\n    - Augusto Becciu\n  date: \"2014-10-25\"\n  event_name: \"RubyConf Argentina 2014\"\n  language: \"spanish\"\n  published_at: \"2018-02-12\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ELKjfOp6HoQ\"\n\n- id: \"pote-rubyconf-argentina-2014\"\n  title: \"The Dilemma of Simplicity\"\n  raw_title: \"Pote - The Dilemma of Simplicity\"\n  speakers:\n    - Pote\n  date: \"2014-10-25\"\n  event_name: \"RubyConf Argentina 2014\"\n  published_at: \"2018-02-12\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"fOMGzRHhPmI\"\n"
  },
  {
    "path": "data/rubyconf-argentina/series.yml",
    "content": "---\nname: \"RubyConf Argentina\"\nwebsite: \"http://rubyconfargentina.org/\"\ntwitter: \"rubyconfar\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2013/event.yml",
    "content": "---\nid: \"PL9_jjLrTYxc27yAJT75euaS_Xg-vVmuMF\"\ntitle: \"RubyConf AU 2013\"\nkind: \"conference\"\nlocation: \"Melbourne, Australia\"\ndescription: |-\n  It’s time to bring the leading developers from around the region and beyond together for the first ever Ruby conference to be held in Australia!\npublished_at: \"2017-05-22\"\nstart_date: \"2013-02-20\"\nend_date: \"2013-02-22\"\nchannel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nyear: 2013\ncoordinates:\n  latitude: -37.8136276\n  longitude: 144.9630576\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2013/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Keith Pitty\n    - Martin Stannard\n    - Mike Koukoulis\n\n  organisations:\n    - Ruby Australia\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2013/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 1\"\n    date: \"2013-02-20\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:00\"\n        end_time: \"17:00\"\n        slots: 5\n\n  - name: \"Day 2\"\n    date: \"2013-02-21\"\n    grid:\n      - start_time: \"07:30\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Welcome\n\n      - start_time: \"09:15\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Morning tea\n\n      - start_time: \"10:30\"\n        end_time: \"11:15\"\n        slots: 2\n\n      - start_time: \"11:20\"\n        end_time: \"12:05\"\n        slots: 2\n\n      - start_time: \"12:05\"\n        end_time: \"12:55\"\n        slots: 2\n\n      - start_time: \"12:55\"\n        end_time: \"13:40\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:40\"\n        end_time: \"14:25\"\n        slots: 2\n\n      - start_time: \"14:30\"\n        end_time: \"15:15\"\n        slots: 2\n\n      - start_time: \"15:15\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Afternoon tea\n\n      - start_time: \"15:30\"\n        end_time: \"16:15\"\n        slots: 2\n\n      - start_time: \"16:20\"\n        end_time: \"16:40\"\n        slots: 1\n        items:\n          - \"Special Documentary\"\n\n      - start_time: \"16:45\"\n        end_time: \"17:45\"\n        slots: 1\n\n      - start_time: \"17:45\"\n        end_time: \"19:45\"\n        slots: 1\n        items:\n          - Drinks\n\n  - name: \"Day 3\"\n    date: \"2013-02-22\"\n    grid:\n      - start_time: \"9:00\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:15\"\n        slots: 1\n        items:\n          - Morning tea\n\n      - start_time: \"10:15\"\n        end_time: \"11:00\"\n        slots: 2\n\n      - start_time: \"11:05\"\n        end_time: \"11:50\"\n        slots: 2\n\n      - start_time: \"11:55\"\n        end_time: \"12:40\"\n        slots: 2\n\n      - start_time: \"12:40\"\n        end_time: \"13:25\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:25\"\n        end_time: \"14:10\"\n        slots: 2\n\n      - start_time: \"14:15\"\n        end_time: \"15:00\"\n        slots: 2\n\n      - start_time: \"15:00\"\n        end_time: \"15:15\"\n        slots: 1\n        items:\n          - Afternoon tea\n\n      - start_time: \"15:15\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:05\"\n        slots: 1\n        items:\n          - Closing Remarks\n\n      - start_time: \"17:15\"\n        end_time: \"23:59\"\n        slots: 1\n        items:\n          - Closing Party\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2013/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby\"\n      level: 1\n      sponsors:\n        - name: \"Envato\"\n          website: \"https://envato.com/\"\n          slug: \"Envato\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/envato.svg\"\n\n    - name: \"Emerald\"\n      level: 2\n      sponsors:\n        - name: \"ThoughtWorks\"\n          website: \"https://www.thoughtworks.com/\"\n          slug: \"ThoughtWorks\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/thoughtworks.svg\"\n\n        - name: \"RealEstate.com.au\"\n          website: \"https://realestate.com.au/\"\n          slug: \"RealEstateComAu\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/rea.svg\"\n\n    - name: \"Sapphire\"\n      level: 3\n      sponsors:\n        - name: \"Fairfax Media\"\n          website: \"https://www.fairfax.com.au/\"\n          slug: \"FairfaxMedia\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/fairfax.svg\"\n\n        - name: \"Icelab\"\n          website: \"https://icelab.com.au/\"\n          slug: \"Icelab\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/icelab.svg\"\n\n        - name: \"Flippa\"\n          website: \"https://flippa.com/\"\n          slug: \"Flippa\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/flippa.svg\"\n\n        - name: \"Everyday Hero\"\n          website: \"https://www.everydayhero.com.au/\"\n          slug: \"EverydayHero\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/edh.svg\"\n\n        - name: \"Ninefold\"\n          website: \"https://ninefold.com/\"\n          slug: \"Ninefold\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/ninefold.svg\"\n\n        - name: \"New Relic\"\n          website: \"https://newrelic.com/\"\n          slug: \"NewRelic\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/newrelic.svg\"\n\n    - name: \"Other\"\n      level: 4\n      sponsors:\n        - name: \"Campaign Monitor\"\n          website: \"https://www.campaignmonitor.com/\"\n          slug: \"CampaignMonitor\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/campaignmonitor.svg\"\n\n        - name: \"Lookahead Search\"\n          website: \"https://www.lookahead.com.au/\"\n          slug: \"LookaheadSearch\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/lookahead.png\"\n\n        - name: \"StillAlive\"\n          website: \"https://stillalive.com/\"\n          slug: \"StillAlive\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/stillalive.svg\"\n\n        - name: \"DiUS\"\n          website: \"https://dius.com.au/\"\n          slug: \"DiUS\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/dius.svg\"\n\n        - name: \"GitHub\"\n          website: \"https://github.com/\"\n          slug: \"GitHub\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/github.svg\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2013/videos.yml",
    "content": "---\n# Website: https://rubyconf.org.au/2013\n\n- id: \"dave-thomas-rubyconf-au-2013-workshop-1\"\n  title: \"Advanced Ruby\"\n  raw_title: \"Advanced Ruby by Dave Thomas\"\n  speakers:\n    - Dave Thomas\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-20\"\n  published_at: \"N/A\"\n  description: |-\n    At the start of the day, we list out all the topics and prioritize them\n    based on the class's wishes. From there, we start at the top and see how far\n    we get. There's a mixture of talk, demonstrations, and exercises, and I\n    generally let the class lead me down rabbit holes as long as enough people\n    are interested. In general, the more experienced the audience, the faster we\n    go. In general, people will need at least 6 months Ruby to keep up. A year\n    or two is the sweet spot\n  video_provider: \"not_recorded\"\n  video_id: \"dave-thomas-rubyconf-au-2013-workshop-1\"\n\n- id: \"corey-haines-rubyconf-au-2013-workshop-2\"\n  title: \"Code Retreat\"\n  raw_title: \"Code Retreat by Corey Haines\"\n  speakers:\n    - Corey Haines\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-20\"\n  published_at: \"N/A\"\n  description: |-\n    Coderetreat is a day-long, intensive practice event, focusing on the\n    fundamentals of software development and design. By providing developers the\n    opportunity to take part in focused practice, away from the pressures of\n    'getting things done', the coderetreat format has proven itself to be a\n    highly effective means of skill improvement. Practicing the basic principles\n    of modular and object-oriented design, developers can improve their ability\n    to write code that minimizes the cost of change over time.\n  video_provider: \"not_recorded\"\n  video_id: \"corey-haines-rubyconf-au-2013-workshop-2\"\n\n- id: \"jruby-rubyconf-au-2013-workshop-3\"\n  title: \"JRuby\"\n  raw_title: \"JRuby by Hiro Asari, Charles Nutter\"\n  speakers:\n    - Hiro Asari\n    - Charles Nutter\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-20\"\n  published_at: \"N/A\"\n  description: |-\n    The JRuby core team members Charles Oliver Nutter and Hiro Asari lead the first JRuby workshop in the Southern Hemisphere.\n  video_provider: \"not_recorded\"\n  video_id: \"jruby-rubyconf-au-2013-workshop-3\"\n\n- id: \"rails4ios-rubyconf-au-2013-workshop-4\"\n  title: \"Rails4iOS\"\n  raw_title: \"Rails4iOS by Lori M Olson, Tim Breitkreutz\"\n  speakers:\n    - Lori M Olson\n    - Tim Breitkreutz\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-20\"\n  published_at: \"N/A\"\n  description: |-\n    You've got your iPhone app almost ready to go, but now you need a website.\n    You're an iOS developer, not a web developer, and every day that goes by is\n    another day that your app ISN'T in the App Store. You can outsource your\n    server-side development, but that costs both time & money. What if you could\n    build your own website? Our Rails for iOS Developers Workshop will help you\n    get your responsive website up and running, using the powerful Ruby on Rails\n    framework, from creation to deployment, in straight-forward, easy to follow\n    steps.\n  video_provider: \"not_recorded\"\n  video_id: \"rails4ios-rubyconf-au-2013-workshop-4\"\n\n- id: \"rails-girls-rubyconf-au-2013-workshop-5\"\n  title: \"Rails Girls\"\n  raw_title: \"Rails Girls\"\n  speakers:\n    - Robert Postill\n    - Kai Lemmetty\n    - Susan Jones\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-20\"\n  published_at: \"N/A\"\n  description: |-\n    Rails Girls kicks off with an installation party on the evening of Tuesday,\n    February 19 before attendees are guided in the use of Ruby on Rails to build\n    a web application.\n  video_provider: \"not_recorded\"\n  video_id: \"rails-girls-rubyconf-au-2013-workshop-5\"\n\n- id: \"corey-haines-rubyconf-au-2013\"\n  title: \"Opening Keynote: Stading on the shoulders of giants\"\n  raw_title: \"RubyConf AU 2013: Opening Keynote by Corey Haines\"\n  speakers:\n    - Corey Haines\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Corey Haines helps developers improve their fundamental software design skills through the use of focused-practice events, such as coderetreat. He trains teams on development technical practices, and builds projects and products when not on the road.\n  video_provider: \"youtube\"\n  video_id: \"UJ_6NZ6UX18\"\n\n- id: \"ben-orenstein-rubyconf-au-2013\"\n  title: \"Refactoring from Good to Great - A Live-Coding Odyssey\"\n  raw_title: \"RubyConf AU 2013: Refactoring from Good to Great - A Live-Coding Odyssey by Ben Orenstein\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Most developers know enough about refactoring to write code that's pretty good. They create short methods, and classes with one responsibility. They're also familiar with a good handful of refactorings, and the code smells that motivate them.\n    This talk is about the next level of knowledge: the things advanced developers know that let them turn good code into great. Code that's easy to read and a breeze to change.\n    These topics will be covered solely by LIVE CODING; no slides. We'll boldly refactor right on stage, and pray the tests stay green. You might even learn some vim tricks as well as an expert user shows you his workflow.\n    Topics include:\n    * The Open-Closed Principle\n    * The types of coupling, and their dangers\n    * Why composition is so damn great\n    * A powerful refactoring that Kent Beck refers to as \"deep deep magic\"\n    * How to destroy conditionals with a NullObject\n    * The beauty of the Decorator pattern\n    * Testing smells, including Mystery Guest and stubbing the system under test\n    * The stuff from the last halves of Refactoring and Clean Code that you never quite got to :)\n  video_provider: \"youtube\"\n  video_id: \"AfK_Iyr07Ho\"\n\n- id: \"chris-kelly-rubyconf-au-2013\"\n  title: \"Down the rb_newobj() Rabbit Hole: Garbage Collection in Ruby\"\n  raw_title: \"RubyConf AU 2013: Down the rb_newobj() Rabbit Hole: Garbage Collection in Ruby by Chris Kelly\"\n  speakers:\n    - Chris Kelly\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    (apologies for the poor audio)\n    New Relic recently made the big move to Ruby 1.9.3 which showed meaningful improvements over 1.8, particularly in garbage collection. So this talk is taking a look at what changed in Ruby's garbage collection that caused much of the improvements. We will start with the fundamentals of garbage collection but work down to the nitty gritty C code to get to the details of what's going on, starting with rb_newobj(). You should walk away with an understanding of how garbage collection works in MRI and a nice appreciation for the overall lifecycle of Ruby objects.\n  video_provider: \"youtube\"\n  video_id: \"o9El1zJ0Gmk\"\n\n- id: \"konstantin-haase-rubyconf-au-2013\"\n  title: \"Sinatra in SIX lines - How to do crazy stuff with Ruby\"\n  raw_title: \"RubyConf AU 2013: Sinatra in SIX lines - How to do crazy stuff with Ruby by Konstantin Haase\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    A fun code analysis.\n\n    Slides: speakerdeck.com/rkh/rubyconf-au-sinatra-in-six-lines\n  video_provider: \"youtube\"\n  video_id: \"2CUijbZH2bs\"\n\n- id: \"toby-hede-rubyconf-au-2013\"\n  title: \"Realtime Rails and Ruby\"\n  raw_title: \"Realtime Rails and Ruby by Toby Hede\"\n  speakers:\n    - Toby Hede\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  description: |-\n    A whirlwind and in-the-deep-end introduction to using Ruby and Rails for\n    \"realtime\" applications so you never have to write javascript on the server.\n    Includes Rails 4 Live Streams, Evented Asynchronous Rails and vert.x.\n  video_provider: \"not_recorded\"\n  video_id: \"toby-hede-rubyconf-au-2013\"\n\n- id: \"rene-de-voursney-rubyconf-au-2013\"\n  title: \"Teaching Ruby for fun and profit\"\n  raw_title: \"RubyConf AU 2013: Teaching Ruby for fun and profit by Renée De Voursney\"\n  speakers:\n    - Renée De Voursney\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    How many companies are hiring Ruby developers right now? How many are finding qualified candidates? Why aren't workers swarming into our industry to fill up all these empty developer positions? Is learning Ruby really that hard? Why is learning Ruby so hard? Isn't it a language built by people for people? Shouldn't that be easy for anyone to pickup and use? Why isn't everyone building Ruby apps? I'm going to tell you. The good, the bad, and the goofy of trying to teach Ruby, Rails, and everything else we take for granted as RoR developers. There may even be a guest appearance from a real life Ruby Newbie to demonstrate!\n  video_provider: \"youtube\"\n  video_id: \"wD-8mIpyBb8\"\n\n- id: \"richard-schneeman-rubyconf-au-2013\"\n  title: \"Millions of Apps: What we’ve Learned\"\n  raw_title: \"RubyConf AU 2013: Millions of Apps: What we’ve Learned by Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Heroku has deployed millions of web apps. When you've run that many applications, it's hard not to notice when frameworks and developers do things wrong, and when they do them right. We've taken a look at the most common patterns and boiled down the best of our advice in to 12 simple factors that can help you build your next app to be stable, successful, and scaleable. After this talk you'll walk away with in depth knowledge of web framework design patterns and practical examples of how to improve your application code.\n  video_provider: \"youtube\"\n  video_id: \"fFOl-oiugZk\"\n\n- id: \"pat-allan-rubyconf-au-2013\"\n  title: \"The C Word\"\n  raw_title: \"RubyConf AU 2013: The C Word by Pat Allan\"\n  speakers:\n    - Pat Allan\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    One of the most notable things about Ruby is its community - the passion towards writing good code, the opinions on how code should behave, the tools it produces, the people it draws to it, and yes, occasionally the arguments and drama.\n    Is this something we should take for granted? Should we be actively guiding the community to behave in a particular way? What makes up a healthy community? Are there ideas and wisdom can we take from other communities? So many questions – let's see if we can find some answers!\n  video_provider: \"youtube\"\n  video_id: \"qX0e4kf_G7s\"\n\n- id: \"terence-lee-rubyconf-au-2013\"\n  title: \"`bundle install` Y U SO SLOW: Server Edition\"\n  raw_title: \"RubyConf AU 2013: bundle install Y U SO SLOW: Server Edition by Terence Lee\"\n  speakers:\n    - Terence Lee\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    If you've ever done anything in ruby, you've probably used rubygems and to search or install your favorite gem. On October 17, 2012, rubygems.org went down. A Dependency API was built to be used by Bundler 1.1+ to speed up bundle install. Unfortunately, it was a bit too popular and the service caused too much load on the current infrasture. In order to get rubygems.org back up the API had to be disabled. You can watch the post-mortem for details.\n    Members in the community stepped up and built a compatible Dependency API service called the Bundler API. Working with the rubygems.org team, we were able to bring the API up for everyone within a week. In this talk, I will cover the process we went through of extracting the API out into a separate Sinatra app that now runs on Heroku. I'll go over how the API works and how Bundler itself uses it. Since we don't have direct access to their database, we needed to build a syncing service to keep our local cache up to date. We'll discuss the original sequential implementation of the sync code and how we improved performance through the use of a consumer thread pool. The sync time down was cut from 16 mins to 2-3 mins. Next, we'll talk about the productization steps we took for visibility to make sure the app is performing well.\n    We're prototyping a replay service, to replay production traffic to different Heroku apps. With this we can compare the performance between the current MRI app in production and the same app running on JRuby. This will also allow us to test any changes/features against real production load. We'll go over how to set this up.\n  video_provider: \"youtube\"\n  video_id: \"AZYsvDTqmvA\"\n\n- id: \"will-farrington-rubyconf-au-2013\"\n  title: \"The Setup: Managing an Army of Laptops with Puppet\"\n  raw_title: \"RubyConf AU 2013: The Setup: Managing an Army of Laptops with Puppet by Will Farrington\"\n  speakers:\n    - Will Farrington\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    As a rapidly growing company, GitHub's faced some challenges in how to make sure that everyone can get up and running on projects or continue to work on one of the dozens of existing projects if they've never set it up before. What a nightmare! That's what prompted @jbarnette and @wfarr to develop The Setup. The Setup aims to solve all the problems that used to plague on-boarding GitHubbers onto projects with a lot of automation and a case of the \"It Just Works\". This presentation talks about the history of The Setup, how it works, and some of the lessons learned along the way.\n  video_provider: \"youtube\"\n  video_id: \"3d0Uez2N4Hc\"\n\n- id: \"carina-c-zona-rubyconf-au-2013\"\n  title: \"Schemas for the Real World\"\n  raw_title: \"RubyConf AU 2013: Schemas for the Real World by Carina C. Zona\"\n  speakers:\n    - Carina C. Zona\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Social app development challenges us how to code for users' personal world. Users are giving push-back to ill-fitted assumptions about their identity — including name, gender, sexual orientation, important relationships, and other attributes they value.\n    How can we balance users' realities with an app's business requirements?\n    Facebook, Google+, and others are grappling with these questions. Resilient approaches arise from an app's own foundation. Discover schemas' influence over codebase, UX, and development itself. Learn how we can use schemes to both inspire users and generate data we need as developers.\n\n\n    Slides for my RubyConfAU talk, \"Schemas for the Real World\" are at slideshare.net/cczona/schemas-for-the-real-world-rubyconf-au-201302\n    It includes a Resources page with links to source material for this talk, and additional reading if you'd like to explore more on this topic. Enjoy!\n\n\n    Links to the most recent videos & slides for \"Schemas for the Real World\" are maintained at cczona.com/blog/talks/ This talk is constantly in evolution; so each iteration expands topics and adds new visuals/examples.\n    However, the version recorded here at RubyConfAU has the best Q&A session (starts at time mark 31:55). Australians are great at raising terrifically challenging questions.\n  video_provider: \"youtube\"\n  video_id: \"NxAyZ8Z3vsI\"\n\n- id: \"geoffrey-grosenbach-rubyconf-au-2013\"\n  title: \"Lessons from the Masters\"\n  raw_title: \"RubyConf AU 2013: Lessons from the Masters by Geoffrey Grosenbach\"\n  speakers:\n    - Geoffrey Grosenbach\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Over the last two years, I've traveled the world to pair with expert designers and developers on short projects to learn their day to day secrets and understand their philosophies. I've condensed this to 45 minutes of tricks, insights, opinions, and old-fashioned rants from Ryan Singer (37signals), Kyle Neath (GitHub), Neven Mrgan (Panic), Zed Shaw, Gary Bernhardt (Destroy All Software), and others.\n  video_provider: \"youtube\"\n  video_id: \"vzjARuXpFZY\"\n\n- id: \"michael-fairley-rubyconf-au-2013\"\n  title: \"Immutable Ruby\"\n  raw_title: \"RubyConf AU 2013: Immutable Ruby by Michael Fairley\"\n  speakers:\n    - Michael Fairley\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Most Ruby code makes heavy use of mutable state, which often contributes to long term maintenance problems. Mutability can lead to code that's difficult to understand, libraries and applications that aren't thread-safe, and tests that are slow and brittle. Immutability, on the other hand, can make code easy to reason about, safe to use in multi-threaded environments, and simple to test. Doesn't that sound nice?\n    This talk answers the question \"why immutability?\", covers the building blocks of immutable code, such as value objects and persistent data structures, as well as higher order concepts that make heavy use of immutability, such as event sourcing and pure functions, and finally discusses the tradeoffs involved in going immutable.\n  video_provider: \"youtube\"\n  video_id: \"a1XZ1fhPiV0\"\n\n- id: \"aaron-patterson-rubyconf-au-2013\"\n  title: \"Keynote\"\n  raw_title: \"Keynote by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-21\"\n  description: |-\n    Aaron Patterson is one of Ruby’s most respected and loved programmers. A\n    committer to both Ruby and Ruby on Rails and a member of Seattle's Ruby\n    community, he also has a sense of humour that has endeared him to many\n    audiences.\n  video_provider: \"not_recorded\"\n  video_id: \"aaron-patterson-rubyconf-au-2013\"\n\n- id: \"mikel-lindsaar-rubyconf-au-2013\"\n  title: \"Keynote\"\n  raw_title: \"RubyConf AU 2013: Keynote by Mikel Lindsaar\"\n  speakers:\n    - Mikel Lindsaar\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Mikel Lindsaar needs no introduction to the Australian Ruby community. He is the author of the Ruby E-Mail handling library, mail, and has worked extensively on the Rails ActionMailer component. Mikel is the only Australian member of the Ruby on Rails commit team.\n  video_provider: \"youtube\"\n  video_id: \"Wr_Aqwhvqc8\"\n\n- id: \"charles-nutter-rubyconf-au-2013\"\n  title: \"High Performance Ruby\"\n  raw_title: \"RubyConf AU 2013: High Performance Ruby by Charles Nutter\"\n  speakers:\n    - Charles Nutter\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Ruby has become a global phenomenon, and more people use it every day. But too often, Ruby is maligned for poor performance, poor scalability, and inability to efficiently parallelize. It's time we changed those impressions.\n    This talk will cover strategies for optimizing Ruby code, from using different Ruby implementations with better performance characteristics to generating code and avoiding excessive object churn. We'll see how one implementation, JRuby, optimizes different Ruby language constructs and how knowing a bit about your Ruby impl of choice will help you write better code. And we'll explore the future of Ruby for high performance computing and solutions to get us there.\n    If you don't know how to write faster, better Ruby code by the end of this talk, I'll let you buy me a beer and we'll keep talking.\n  video_provider: \"youtube\"\n  video_id: \"3Fm-n_Vr7e4\"\n\n- id: \"amit-kumar-rubyconf-au-2013\"\n  title: \"Using Ruby for iOS development (RubyMotion)\"\n  raw_title: \"RubyConf AU 2013: Using Ruby for iOS development (RubyMotion) by Amit Kumar\"\n  speakers:\n    - Amit Kumar\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    RubyMotion has revolutionized native apps development platform for iOS devices. I would like to share some best practices/lessons learnt building apps using RubyMotion. This includes but not limited to:\n    What is RubyMotion\n    REPL\n    Using Obj-C, native C, gems in your RubyMotion application\n    Using storyboard\n    DSL for views\n    ActiveRecord-like ORM for iOS\n    Testing storyboard interface (Rspec and TestUnit)\n    CocoaPods\n    Dependency Management\n    Creating Gems\n    XCode integration\n    Continuous Integration\n    Releasing to AppStore\n    and others\n  video_provider: \"youtube\"\n  video_id: \"-xgh0p4DpDw\"\n\n- id: \"ben-hoskings-rubyconf-au-2013\"\n  title: \"State of the Ruby\"\n  raw_title: \"RubyConf AU 2013: State of the Ruby by Ben Hoskings\"\n  speakers:\n    - Ben Hoskings\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Every year is an eventful one in ruby. Many rubies have been polished this year, and many new ones have been cut.\n    I'll take us through the state of things in MRI, jruby, rubinius and friends, and what we can expect from them next year, particularly in regards to ruby 2.0, which is scheduled for release just a couple of days after RubyConfAU.\n  video_provider: \"youtube\"\n  video_id: \"a3aOltpjAGw\"\n\n- id: \"keith-pitt-rubyconf-au-2013\"\n  title: \"Keith and Mario’s Guide to Fast Websites\"\n  raw_title: \"RubyConf AU 2013: Keith and Mario’s Guide to Fast Websites by Keith Pitt & Mario Visic\"\n  speakers:\n    - Keith Pitt\n    - Mario Visic\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    When you talk to most people about Rails performance the conversation usually turns to concurrency. How can my Rails app handle 60 simultanious requests per second? How do I webscale?\n    Although the topic of concurrency is important, we won't be focusing on that during this talk. We want to focus on end user speed.\n    For every extra second your application takes to load your conversion rates will drop by an average of 7%. While most people start tweaking their backends to squeeze every extra ms in response time, more often than not (80-90%) of the actual time spent loading your application is on the front end and the network stack. This is where you should start.\n    We will cover a range of techniques and provide benchmarks along the way to show how much performance you can expect from each step along the way. We'll also cover some backend performance tuning as well.\n    Here's some of the topics we'll cover:\n    How to accurately benchmark performance\n    Asyncronously loading assets\n    Reducing requests per page\n    Rails http streaming (chunked responses)\n    Basic caching\n    What is SPDY - and how to use it\n    What CDN is right for your app?\n    Server location and why it matters\n  video_provider: \"youtube\"\n  video_id: \"d3e5zaiBR-c\"\n\n- id: \"paul-gross-rubyconf-au-2013\"\n  title: \"Uptime == Money: High Availability at Braintree\"\n  raw_title: \"RubyConf AU 2013: Uptime == Money: High Availability at Braintree by Paul Gross\"\n  speakers:\n    - Paul Gross\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Braintree is a payment gateway, so downtime directly costs both us and our merchants money. Therefore, high availability is extremely important at Braintree. This talk will cover how we do HA at Braintree on our Ruby on Rails application.\n    Specific topics will include:\n\n    Working around planned downtime and deploys:\n    - How we pause traffic for short periods of time without failing requests\n    - How we fit our maintenance into these short pauses\n    - How we do rolling deploys and schema changes without downtime\n\n    Working around unplanned failures:\n    - How we load balance across redundant services\n    - How the app is structured to retry requests\n  video_provider: \"youtube\"\n  video_id: \"mBmAlqaapcc\"\n\n- id: \"nick-sutterer-rubyconf-au-2013\"\n  title: \"Off the Tracks - Challenging the Rails Mindset\"\n  raw_title: \"RubyConf AU 2013: Off the Tracks - Challenging the Rails Mindset by Nick Sutterer\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Rails - a word that stirs programmer's blood. It brought us testing, easy web app building, database abstraction and hundreds of extension gems. Why not take it to another level and discover how Rails turns into a real OOP framework? By exploring chosen gems let's discuss what MVC really is and how it boosts your AJAX user interface, how to apply patterns like DCI, dependency injection and POROs to your database layer and how to expose your Rails system through a real RESTful API. Also, have you ever tried using Rails helpers outside of Rails, maybe in Sinatra? Let's do it and learn about some refreshing aspects of this framework.\n  video_provider: \"youtube\"\n  video_id: \"Xj24IuwjW-0\"\n\n- id: \"adam-hawkins-rubyconf-au-2013\"\n  title: \"Dear God What Am I Doing? Concurrency and Parallel Processing\"\n  raw_title: \"RubyConf AU 2013: Dear God What Am I Doing? Concurrency and Parallel Processing by Adam Hawkins\"\n  speakers:\n    - Adam Hawkins\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Here's a situation we've all be in at one point. We have a program. We want to make that program faster. We know about threads, processes, fibers. Then you start programming and you have no clue what to do. I was there. It sucks. This talk guides you down the rabbit hole and brings out the other side.\n    Points covered:\n    Threads, Fibers\n    Processes, Forking, Detaching\n    Parellelism vs Concurrency\n    The many many different ways I crashed my computer learning these things\n    Gotchas of each\n    Common ways you shoot yourself in the foot\n    Celluoid\n    This is a learning and informative talk. It's target at intermediate developers who have ruby experience but never written any multi threaded code.\n  video_provider: \"youtube\"\n  video_id: \"C4dB2rrZdFM\"\n\n- id: \"geoffrey-giesemann-rubyconf-au-2013\"\n  title: \"From Stubbies to Longnecks\"\n  raw_title: \"RubyConf AU 2013: From Stubbies to Longnecks by Geoffrey Giesemann\"\n  speakers:\n    - Geoffrey Giesemann\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    From Stubbies to Longnecks - Finding and curing scaling bottlenecks\n\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Every application is different. Every application performs and scales in a different manner. What stays the same are the tools we use to monitor and diagnose our applications when they get sick or have a big night out.\n    In this talk I'll cover how realestate.com.au monitors and troubleshoots the performance and scalability of our Ruby and non-Ruby apps. I'll look at the tools we use to infer when/where things go wrong and several cases where things have gone wrong and how we've dug our way out of the whole.\n    Examples of areas covered include:\n    - Vertical scaling our way out of I/O pain\n    - Horizontal scaling our apps for throughput and availability\n    - Using HTTP and CDNs to avoid the reddit-effect\n    - Tools we use for establishing performance 'baselines'\n  video_provider: \"youtube\"\n  video_id: \"fQRd-0ukAEM\"\n\n- id: \"benjamin-smith-rubyconf-au-2013\"\n  title: \"Hacking With Gems\"\n  raw_title: \"RubyConf AU 2013: Hacking With Gems by Benjamin Smith\"\n  speakers:\n    - Benjamin Smith\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    What's the worst that could happen if your app has a dependency on a malicious gem? How easy would it be to write a gem that could compromise a box?\n    Much of the Ruby community blindly trusts our gems. This talk will make you second guess that trust. It will also show you how to vet gems that you do choose to use.\n    There are four malicious gems I will be presenting:\n    - Harvesting passwords from requests going through a Rails app\n    - Exposing the contents of a Rails app's database\n    - Compromising the source code of a Rails app\n    - Providing SSH access to a box a 'gem install' time and stealing gem cutter credentials (and going viral)\n    My talk will increase awareness that these sort of gems can exist in the wild, show how easy it is for anyone to build malicious gems, and give easy techniques for identifying these gems.\n  video_provider: \"youtube\"\n  video_id: \"DKKyGAeNEPw\"\n\n- id: \"john-barton-rubyconf-au-2013\"\n  title: \"Web scale for the rest of us\"\n  raw_title: \"RubyConf AU 2013: Web scale for the rest of us by John Barton\"\n  speakers:\n    - John Barton\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    On the internet, there seems to be two kinds of information available to do with \"scaling rails\", or on \"scaling\" in general.\n    Blog posts about how the really big boys are doing things\n    Blog posts full of non-production benchmarks explaining why you need a particular data store, templating framework, or anything else to be \"web-scale\"\n    This talk will hopefully be a third kind, practical advice to help you grow your application at the right pace alongside your business' growth, based on real world experience.\n    Topics covered will (probably) include:\n    Why you should probably choose Postgres or Mysql as your data store\n    Why going from one developer to two developers is the hardest\n    Why going from one server to two servers is the hardest\n    Why those two things are actually the same problem\n    How YAGNI and SRP apply to your hosting just as much as your code\n    How you balance your cost-speed-quality stool for developing your app up against the same cost-speed-quality tripod for your infrastructure\n    Why other people's advice on the topic can only ever provide a starting point, not a final answer\n\n    The slides for the talk are available at slideshare.net/johnb/webscale-for-the-rest-of-us-ruby-conf-2013\n  video_provider: \"youtube\"\n  video_id: \"7y2JeLtRCRs\"\n\n- id: \"lightning-talks-rubyconf-au-2013\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf AU 2013: Lightning Talks\"\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n  video_provider: \"youtube\"\n  video_id: \"PVUErJVkM2k\"\n  talks:\n    - title: \"Lightning Talk: Dr Smalltak - or: How I Learned to Stop Worrying and Love Objective-C\"\n      start_cue: \"01:03\"\n      end_cue: \"03:47\"\n      video_provider: \"parent\"\n      id: \"darcy-laycock-lighting-talk-rubyconf-au-2013\"\n      video_id: \"darcy-laycock-lighting-talk-rubyconf-au-2013\"\n      speakers:\n        - Darcy Laycock\n      slides_url: \"https://speakerdeck.com/sutto/dr-smalltalk\"\n\n    - title: \"Lightning Talk: Black/White\"\n      start_cue: \"03:47\"\n      end_cue: \"08:37\"\n      video_provider: \"parent\"\n      id: \"john-rowe-lighting-talk-rubyconf-au-2013\"\n      video_id: \"john-rowe-lighting-talk-rubyconf-au-2013\"\n      speakers:\n        - John Rowe\n\n    - title: \"Lightning Talk: An Ode to 17 Databases in 5 minutes\"\n      start_cue: \"08:37\"\n      end_cue: \"13:04\"\n      video_provider: \"parent\"\n      id: \"toby-hede-lighting-talk-rubyconf-au-2013\"\n      video_id: \"toby-hede-lighting-talk-rubyconf-au-2013\"\n      speakers:\n        - Toby Hede\n\n    - title: \"Lightning Talk: RailsGirls - It's more fun than falling into favorite foodstuff\"\n      start_cue: \"13:04\"\n      end_cue: \"18:18\"\n      video_provider: \"parent\"\n      id: \"robert-postill-lighting-talk-rubyconf-au-2013\"\n      video_id: \"robert-postill-lighting-talk-rubyconf-au-2013\"\n      speakers:\n        - Robert Postill\n\n    - title: \"Lightning Talk: Desing your API\"\n      start_cue: \"18:18\"\n      end_cue: \"23:48\"\n      video_provider: \"parent\"\n      id: \"cameron-barrie-lighting-talk-rubyconf-au-2013\"\n      video_id: \"cameron-barrie-lighting-talk-rubyconf-au-2013\"\n      speakers:\n        - Cameron Barrie\n\n    - title: \"Lightning Talk: freshshell.com - Keep your dot files fresh\"\n      start_cue: \"23:48\"\n      end_cue: \"27:34\"\n      video_provider: \"parent\"\n      id: \"jason-odin-lighting-talk-rubyconf-au-2013\"\n      video_id: \"jason-odin-lighting-talk-rubyconf-au-2013\"\n      speakers:\n        - Jason Weathered\n        - Odin Dutton\n\n    - title: \"Lightning Talks Winners - Result\"\n      start_cue: \"27:34\"\n      end_cue: \"32:21\"\n      video_provider: \"parent\"\n      id: \"lighting-talks-winner-rubyconf-au-2013\"\n      video_id: \"lighting-talks-winner-rubyconf-au-2013\"\n      speakers:\n        - Ben Schwarz\n        - Lincoln Stoll\n        - Konstantin Haase\n        - Josh Kalderimis\n\n- id: \"dave-thomas-rubyconf-au-2013\"\n  title: \"Closing Keynote\"\n  raw_title: \"RubyConf AU 2013: Closing Keynote by Dave Thomas\"\n  speakers:\n    - Dave Thomas\n  event_name: \"RubyConf AU 2013\"\n  date: \"2013-02-22\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2013: http://www.rubyconf.org.au\n\n    Dave Thomas needs no introduction to Ruby programmers. As co-author of \"Programming Ruby: The Pragmatic Programmers' Guide\" - fondly known as the \"Pickaxe\", Dave was instrumental in spreading Ruby beyond its birthplace in Japan.\n  video_provider: \"youtube\"\n  video_id: \"ca_UEQlf6LM\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2014/event.yml",
    "content": "---\nid: \"PL9_jjLrTYxc1jTSURVicc5xrt6am7UxR1\"\ntitle: \"RubyConf AU 2014\"\nkind: \"conference\"\nlocation: \"Sydney, Australia\"\ndescription: |-\n  RubyConf Australia 2014\npublished_at: \"2017-05-22\"\nstart_date: \"2014-02-19\"\nend_date: \"2014-02-21\"\nchannel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nyear: 2014\ncoordinates:\n  latitude: -33.8727409\n  longitude: 151.2057136\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2014/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Elle Meredith\n    - Georgina Robilliard\n    - Jason Crane\n    - Josh Price\n    - Steve Gilles\n\n  organisations:\n    - Ruby Australia\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2014/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 1\"\n    date: \"2014-02-19\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"17:00\"\n        slots: 3\n\n  - name: \"Day 2\"\n    date: \"2014-02-20\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:15\"\n        end_time: \"11:00\"\n        slots: 2\n\n      - start_time: \"11:00\"\n        end_time: \"11:45\"\n        slots: 2\n\n      - start_time: \"11:45\"\n        end_time: \"12:30\"\n        slots: 2\n\n      - start_time: \"12:30\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:40\"\n        slots: 2\n\n      - start_time: \"14:40\"\n        end_time: \"15:20\"\n        slots: 2\n\n      - start_time: \"15:20\"\n        end_time: \"16:00\"\n        slots: 2\n\n      - start_time: \"16:00\"\n        end_time: \"16:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:15\"\n        end_time: \"15:15\"\n        slots: 1\n\n  - name: \"Day 3\"\n    date: \"2014-02-21\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:15\"\n        end_time: \"11:00\"\n        slots: 2\n\n      - start_time: \"11:00\"\n        end_time: \"11:45\"\n        slots: 2\n\n      - start_time: \"11:45\"\n        end_time: \"12:30\"\n        slots: 2\n\n      - start_time: \"12:30\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:40\"\n        slots: 2\n\n      - start_time: \"14:40\"\n        end_time: \"15:20\"\n        slots: 2\n\n      - start_time: \"15:20\"\n        end_time: \"16:00\"\n        slots: 2\n\n      - start_time: \"16:00\"\n        end_time: \"16:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:15\"\n        end_time: \"15:15\"\n        slots: 1\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2014/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby\"\n      level: 1\n      sponsors:\n        - name: \"Envato\"\n          website: \"https://envato.com/\"\n          slug: \"Envato\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/envato.svg\"\n\n    - name: \"Emerald\"\n      level: 2\n      sponsors:\n        - name: \"JobReady\"\n          website: \"https://jobready.com.au/\"\n          slug: \"JobReady\"\n          logo_url: \"https://rubyconf.org.au/images/sponsors/jobready.svg\"\n\n        - name: \"RedAnt\"\n          website: \"https://redant.com.au/\"\n          slug: \"RedAnt\"\n          logo_url: \"https://rubyconf.org.au/images/sponsors/redant.jpg\"\n\n        - name: \"DiUS\"\n          website: \"https://dius.com.au/\"\n          slug: \"DiUS\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/dius.svg\"\n\n    - name: \"Opal\"\n      level: 3\n      sponsors:\n        - name: \"ThoughtWorks\"\n          website: \"https://www.thoughtworks.com/\"\n          slug: \"ThoughtWorks\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/thoughtworks.svg\"\n\n        - name: \"Fairfax Media\"\n          website: \"https://www.fairfax.com.au/\"\n          slug: \"FairfaxMedia\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/fairfax.svg\"\n\n        - name: \"Ninefold\"\n          website: \"https://ninefold.com/\"\n          slug: \"Ninefold\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/ninefold.svg\"\n\n    - name: \"Other\"\n      level: 4\n      sponsors:\n        - name: \"Braintree\"\n          website: \"https://www.braintreepayments.com/\"\n          slug: \"Braintree\"\n          logo_url: \"https://rubyconf.org.au/images/sponsors/braintree.png\"\n\n        - name: \"Lookahead Search\"\n          website: \"https://www.lookahead.com.au/\"\n          slug: \"LookaheadSearch\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/lookahead.png\"\n\n        - name: \"SauceLabs\"\n          website: \"https://saucelabs.com/\"\n          slug: \"SauceLabs\"\n          logo_url: \"https://rubyconf.org.au/images/sponsors/saucelabs.svg\"\n\n        - name: \"Travis CI\"\n          website: \"https://travis-ci.org/\"\n          slug: \"TravisCI\"\n          logo_url: \"https://rubyconf.org.au/images/sponsors/travisci.svg\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2014/videos.yml",
    "content": "---\n# Website: https://rubyconf.org.au/2014\n\n- id: \"jon-rowe-rubyconf-au-2014-workshop-1\"\n  title: \"Testing Zero to Hero\"\n  raw_title: \"Testing Zero to Hero by Jon Rowe\"\n  speakers:\n    - Jon Rowe\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-19\"\n  published_at: \"N/A\"\n  description: |-\n    So testing… How does it work?\n\n    What is a unit test? Why is that an integration test, should I even bother\n    with acceptance tests?\n\n    Let's work through the differences between the various types of testing,\n    look at differing strategies for tackling problems and how they can be\n    solved. Try doing things with TDD, try doing things building tests after.\n\n    Let's use RSpec, TestUnit and MiniSpec to test different techniques and\n    perfect our tests. And we will look at how we can apply these to our real\n    world problems to make our lives easier and our software better!\n  video_provider: \"not_recorded\"\n  video_id: \"jon-rowe-rubyconf-au-2014-workshop-1\"\n\n- id: \"andre-medeiros-rubyconf-au-2014-workshop-2\"\n  title: \"Building C Extensions in Ruby\"\n  raw_title: \"Building C Extensions in Ruby by André Medeiros\"\n  speakers:\n    - André Medeiros\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-19\"\n  published_at: \"N/A\"\n  description: |-\n    You will learn how amazingly simple it is to build high-performance\n    extensions that leverage existing C libraries.\n\n    You’ll receive a basic notion of the C language, and then you will dive into\n    the various Ruby APIs that allow you to bridge C code to our favourite\n    language.\n\n    We will also go through a heavy testing component that will help you ensure\n    that your extension works as intended, and remains as bulletproof as\n    possible.\n  video_provider: \"not_recorded\"\n  video_id: \"andre-medeiros-rubyconf-au-2014-workshop-2\"\n\n- id: \"rails-girls-next-rubyconf-au-2014-workshop-3\"\n  title: \"Rails Girls Next\"\n  raw_title: \"Rails Girls Next\"\n  speakers:\n    - TODO\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-19\"\n  published_at: \"N/A\"\n  description: |-\n    Take the next step in your coding journey!\n\n    Join us and continue the learning you started at Rails Girls. Since you have\n    Ruby installed already, we can jump right in!\n\n    We've organised three mentor-led tutorials that will help you dive deeper\n    into the world of professional development with Ruby. Tutorials include a\n    look at some of Ruby's more advanced features and syntax, building a Sinatra\n    app and deploying it, test-driven development and more.\n\n    Lastly, you will gain a greater appreciation of development work procedures\n    by pairing up to solve coding challenges and using Git for version control.\n  video_provider: \"not_recorded\"\n  video_id: \"rails-girls-next-rubyconf-au-2014-workshop-3\"\n\n- id: \"cameron-barrie-rubyconf-au-2014\"\n  title: \"What it is you really do?\"\n  raw_title: \"RubyConf AU 2014: What it is you really do? by Cameron Barrie\"\n  speakers:\n    - Cameron Barrie\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Programming is hard, correct? Code, tests, design patterns, abstractions, deployments, are the things we do everyday and coding can be a craft; it takes skill, patience, perseverance and sometimes downright stubbornness, but what is the result of all that hard work? What are we striving to achieve?\n    As programmers we often talk at length about how to build things. Questions like, what is the right level of abstraction? what database should I use? where should I deploy? etc etc. Indeed there is complexity in the craft of programming and in answering those questions. By why do we ask them in the first place?\n    You build software, you've put in all that hard work, and now you've launched. Time to learn about what you really do for a living!\n  video_provider: \"youtube\"\n  video_id: \"Yh3pLUu-cx0\"\n\n- id: \"mark-bates-rubyconf-au-2014\"\n  title: \"A Big Look at MiniTest\"\n  raw_title: \"RubyConf AU 2014: A Big Look at MiniTest by Mark Bates\"\n  speakers:\n    - Mark Bates\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    In Ruby 1.9 the MiniTest testing framework was introduced. This lightweight testing framework is fast, powerful, and easy to understand, yet so many people over look it.\n    In this talk we'll look at using MiniTest in a simple, non-Rails, project and then work up to using it in a Rails application. We'll look at both the TestUnit and RSpec style syntaxes that MiniTest offers. We'll also learn to write custom matchers, run specific files, and much more.\n    Testing is important to all Ruby developers, and with such a powerful testing library already bundled with Ruby, shouldn't we learn how to use it?\n  video_provider: \"youtube\"\n  video_id: \"nbUYbzS7Vlg\"\n\n- id: \"andr-arko-rubyconf-au-2014\"\n  title: \"Extreme Makeover - Rubygems Edition\"\n  raw_title: \"RubyConf AU 2014: Extreme Makeover - Rubygems Edition by André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Rubygems.org provides every Rubyist with an amazing service: all the libraries in the Ruby world. As amazing as that is, installing gems can be a time-consuming and even error-prone process. (Just ask the Travis guys.) In this talk, you'll learn about the recent dramatic changes in Rubygems and Bundler to improve speed and reliability by rewriting the Rubygems client/server architecture. I'll show how the new system caches more information, makes fewer requests, and takes less time to install gems. Finally, I'll cover how the changes allow worldwide mirrors of rubygems.org, improving things for Rubyists around the globe.\n    Why this talk?\n    This talk exists primarily as a \"State of the Gem Ecosystem Address\", to tell everyone how things are going, what we've been working on, and why they should care. It also tries to point out the benefits that every Rubyist gets from the Ruby ecosystem, while gently letting them know that those things don't happen for free. Hopefully, by providing that information, we can ask people to contribute time and effort to improving things for everyone and sound like we are leading by example, rather than demanding that someone step up to solve the problems for us, already.\n  video_provider: \"youtube\"\n  video_id: \"_2y7fP69qO8\"\n\n- id: \"nishant-modak-rubyconf-au-2014\"\n  title: \"Rack - A Framework to Roll Your Own\"\n  raw_title: \"Rack - A Framework to Roll Your Own by Nishant Modak\"\n  speakers:\n    - Nishant Modak\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  description: |-\n    What is common between Rails, Sinatra and numerous other Ruby frameworks?\n\n    They are built on top of Rack or have Rack interfaces for allowing\n    application servers to connect to them.\n\n    A deep-dive of sorts on Rack and see what it takes to build a framework,\n    helping us understand these better and ultimately rolling our own.\n\n    Almost anyone doing a Ruby app ends up using Rack in one way or the other\n    without ever realising the magic and simplicity that it provides. This\n    session should help decoding that and provide ways on writing your own\n    frameworks.\n  video_provider: \"not_recorded\"\n  video_id: \"nishant-modak-rubyconf-au-2014\"\n\n- id: \"felix-clack-rubyconf-au-2014\"\n  title: \"Teach Your Way To Better Code\"\n  raw_title: \"RubyConf AU 2014: Teach Your Way To Better Code by Felix Clack\"\n  speakers:\n    - Felix Clack\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    You may have this vague sense that you don't know Ruby as well as you think you do. And you worry that you're not learning and growing as a developer in your day job as much as you did when you first picked up Ruby. Perhaps you've lost that spark of excitement you experienced when you discovered new ways to solve problems with Ruby.\n    There is a way to re-invigorate your code and coding practices. Teach everything you know.\n    This talk will focus on some of the principals of teaching and why it can be an effective tool, not only for others to learn, but for you as the teacher to really deepen your knowledge of the subject. It will be specifically centred around using Ruby, and some of the ways I have discovered work well for teaching it as a first programming language.\n  video_provider: \"youtube\"\n  video_id: \"oRGpWUPYiwk\"\n\n- id: \"hailey-somerville-rubyconf-au-2014\"\n  title: \"MRI Magic Tricks\"\n  raw_title: \"RubyConf AU 2014: MRI Magic Tricks by Hailey Somerville\"\n  speakers:\n    - Hailey Somerville\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Join me as we dive under the hood and take a rip-roaring tour of the internals of Ruby's canonical implementation.\n    This talk will have you hanging on the edge of your seat as we push the very limits of the Ruby language and take advantage of a few interesting bugs to do things you never thought were possible.\n    You'll laugh, you'll cry, and hopefully you'll come away from this talk with some fresh knowledge on just what makes Ruby tick.\n  video_provider: \"youtube\"\n  video_id: \"3ROuTjbdkPk\"\n\n- id: \"amanda-wagener-rubyconf-au-2014\"\n  title: \"The Parental Programmer\"\n  raw_title: \"RubyConf AU 2014: The Parental Programmer by Amanda Wagener\"\n  speakers:\n    - Amanda Wagener\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Programming can be an all consuming job. So can parenting.\n    How do you keep up with new technology, contribute to open source, earn some money, and be there for your children? What do you focus on and what do you discard? Is it even possible to do it all?\n    As the mother of a 3 month old, I certainly don't have all the answers. This talk will collate suggestions from programming parents all around the world, so we can make new mistakes going forward, instead of repeating those of the past.\n  video_provider: \"youtube\"\n  video_id: \"yxWTCKsVymg\"\n\n- id: \"toby-hede-rubyconf-au-2014\"\n  title: \"An Ode to 17 Databases in 39 minutes\"\n  raw_title: \"RubyConf AU 2014: An Ode to 17 Databases in 39 minutes by Toby Hede\"\n  speakers:\n    - Toby Hede\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    A detailed, deep-diving, in-the-deep-end and occasionally humorous whirlwind introduction and analysis of a suite of modern (and sometimes delightfully archaic) database technologies. How they work, why they work, and when you might want them to work in your Ruby and Rails application.\n    At no extra charge I will also attempt to explain the oft-misunderstood CAP theorem, using databases as a device for understanding the trade offs and compromises inherent in building complex distributed systems.\n    Including but not limited to:\n    PostgreSQL\n    Redis\n    Cassandra\n    Hyperdex\n    MongoDb\n    Riak\n    Animated Gifs\n    The goal of the talk is to shed light on the wide range of options outside of the \"traditional\" PostgreSQL or MySQL. Ruby on Rails has a rather myopic focus on particular patterns of database interaction and technology on which lead developers to overlook other tools that may be really well suited for particular use-cases.\n\n    Toby put the slides from his talk here: slid.es/tobyhede/an-ode-to-17-database-in-39-minutes-rubyconf-2014/\n  video_provider: \"youtube\"\n  video_id: \"j1unEPBMjRM\"\n\n- id: \"samuel-cochran-rubyconf-au-2014\"\n  title: \"Rails Asset Pipeline: Defunct or Da Funk\"\n  raw_title: \"RubyConf AU 2014: Rails Asset Pipeline: Defunct or Da Funk by Samuel Cochran\"\n  speakers:\n    - Samuel Cochran\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    The Rails asset pipeline has been a useful tool for rapidly crafting beautiful front ends but with ever growing JavaScript toolchains like Grunt and Gulp it seems defunct, or is it?\n    Traditionally elegant front end interfaces can be a pleasure to craft by following The Rails Way(tm) with simple JavaScript behaviours.\n    When a round-trip delay just doesn't cut it, more complex approaches can be crafted with libraries like Backbone to create a truly client-side application. The asset pipeline remains a perfect complement, allowing all sorts of optimisations.\n    But going beyond these simpler approaches is all the rage with Angular leading the charge. We'll look at building Angular apps leveraging the pipeline for templates, compilation, and more.\n    Quickly touching on some more esoteric applications, we can also export rails routes for use in client side templates, automatically create sprite sheets, and even generate icon fonts, optimising assets along the way. The Rails asset pipeline is still Da Funk; a fantastic tool for front end developers.\n  video_provider: \"youtube\"\n  video_id: \"J1WrRyrDk34\"\n\n- id: \"kinsey-ann-durham-rubyconf-au-2014\"\n  title: \"Becoming a Software Engineer\"\n  raw_title: \"RubyConf AU 2014: Becoming a Software Engineer by Kinsey Ann Durham\"\n  speakers:\n    - Kinsey Ann Durham\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    Becoming a Software Engineer: Insipring a New Generation of Developers\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n\n    In my wildest dreams, I never thought that I would become a software developer. I thought that I wasn't smart enough, that I needed a computer science degree and to have been writing code since I was young. But, the traditional path to becoming a developer is changing. This talk will focus on alternative and untraditional paths to becoming a developer such as programs like Railsbridge, mentorship and apprentice programs. These alternative paths ultimately foster a more diverse and inclusive community, which drives economic growth and produces more innovative solutions.\n    The objectives of the talk are:\n    to bring awareness to the educational alternatives to computer science degrees to encourage empathy when mentoring a beginner to get the audience to see a different perspective and embrace differences in the industry\n  video_provider: \"youtube\"\n  video_id: \"mbBJWRZD5pQ\"\n\n- id: \"arnab-deka-rubyconf-au-2014\"\n  title: \"Modern Concurrency Practices in Ruby\"\n  raw_title: \"RubyConf AU 2014: Modern Concurrency Practices in Ruby by Arnab Deka\"\n  speakers:\n    - Arnab Deka\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    He posted the slides from his talk here: slid.es/arnab_deka/modern-concurrency-practises-in-ruby\n\n    He posted the slides from his talk here: slid.es/arnab_deka/modern-concurrency-practises-in-ruby\n  video_provider: \"youtube\"\n  video_id: \"Foq_F94E1Ho\"\n\n- id: \"benjamin-smith-rubyconf-au-2014\"\n  title: \"How I Architected My Big Rails App For Success\"\n  raw_title: \"RubyConf AU 2014: How I Architected My Big Rails App For Success by Benjamin Smith\"\n  speakers:\n    - Benjamin Smith\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Rails is a great framework for creating web apps… for awhile. What do you do when your codebase grows large? How do you handle large teams of developers? When performance becomes an issue, how do you scale? Most importantly, how do you write code which can easily be refactored later?\n    This is a story of a real life project built from day 1 with all these questions in mind. Learn about the problems we solved and lessons we learned: how to partition your Rails app into distinct modular engines, how to speed up your test suite by only running code effected by your changes, how to add a layer on top of ActiveRecord to enforce loose coupling, and many other patterns that can be applied to your own Rails apps!\n\n    slides here: speakerdeck.com/benjaminleesmith/how-i-architected-my-big-rails-app-for-success-rubyconfau-2014\n  video_provider: \"youtube\"\n  video_id: \"1gXmh528o84\"\n\n- id: \"sam-saffron-rubyconf-au-2014\"\n  title: \"Why I am excited about Ruby 2.1?\"\n  raw_title: \"RubyConf AU 2014: Why I am excited about Ruby 2.1? by Sam Saffron\"\n  speakers:\n    - Sam Saffron\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Ruby 2.1 is about to be released, it will include a generational GC, performance improvements and a much improved platform for diagnostics and profiling.\n    In this talk I will cover many of the new profiling and instrumentation APIs introduced in Ruby 2.1, introduce you to the new GC and show you some cool tools you can build on top of this. I will cover memory profiling, GC instrumentation, the much improved stack sampling, memory profilers, flame graphs and more.\n\n    Sam posted the slides from his talk here: speakerdeck.com/samsaffron/why-ruby-2-dot-1-excites-me\n  video_provider: \"youtube\"\n  video_id: \"kici_QRQbOM\"\n\n- id: \"pat-allan-rubyconf-au-2014\"\n  title: \"The Golden Age of the Internet\"\n  raw_title: \"RubyConf AU 2014: The Golden Age of the Internet by Pat Allan\"\n  speakers:\n    - Pat Allan\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-20\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Congratulations. The Internet is now the centre of civilisation as we know it, and we are the ones who shape the Internet. Our skills are in high demand, we are paid well, we find our work challenging, interesting, and even sometimes fulfilling. These are the glory days of our industry, and we should soak up every minute of it!\n    But with such great power comes a great deal of responsibility. Will we be looking back in the near future, wondering if we squandered our opportunities to shape the digital world accordingly?\n    There's no doubt that we value humanity, intelligence, and compassion. Let's take a look at the ways our industry can ensure these values are reflected not just in the people we are, but the way we work.\n  video_provider: \"youtube\"\n  video_id: \"UAVtX0yKFSo\"\n\n- id: \"greg-brockman-rubyconf-au-2014\"\n  title: \"Rescuing Ruby\"\n  raw_title: \"RubyConf AU 2014: Rescuing Ruby by Greg Brockman\"\n  speakers:\n    - Greg Brockman\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n  video_provider: \"youtube\"\n  video_id: \"VeoYIE370XY\"\n\n- id: \"ben-turner-rubyconf-au-2014\"\n  title: \"Ansible - Your First Step Into Server Provisioning\"\n  raw_title: \"RubyConf AU 2014: Ansible - Your First Step Into Server Provisioning by Ben Turner\"\n  speakers:\n    - Ben Turner\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    The ability to repeatably and automatically build your servers in code is essential for managing a modern Ruby application's server infrastructure.\n    Solutions such as Chef and Puppet are often used to solve this issue, but for some teams, this might be too costly to learn and implement effectively. Bridging the gap between these larger solutions and shell scripting is Ansible, a light footprint provisioning tool using SSH and YAML files to quickly define repeatable server creation and configuration steps.\n    This talk will cover:\n    introduce server provisioning at a high level explain how Ansible fits into that pattern describe simple Ansible commands and modules run through a basic playbook example, bringing these elements together summarise other functionality offered by Ansible\n  video_provider: \"youtube\"\n  video_id: \"KFn8isYw97g\"\n\n- id: \"zachary-scott-rubyconf-au-2014\"\n  title: \"Standing on the Shoulders of Giants\"\n  raw_title: \"RubyConf AU 2014: Standing on the Shoulders of Giants by Zachary Scott\"\n  speakers:\n    - Zachary Scott\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    We take for granted the wealth of knowledge and wisdom that goes into each library we use within our programs. Many of the them we use today are built on top of libraries that have existed much longer than most of us have been programming in Ruby.\n    Allow me to guide you through some of these unusual and mysterious libraries that are made available in every Ruby installation. I'm talking about the standard library, which has largely been apart of the Ruby ecosystem since before gems were available.\n    There's around ~70MB of code in every installation, and it's just waiting for those eager to explore and discover what the pioneers of Ruby have provided for us.\n  video_provider: \"youtube\"\n  video_id: \"gNUy2ZULQcQ\"\n\n- id: \"andr-medeiros-rubyconf-au-2014\"\n  title: \"Building C Extensions in Ruby\"\n  raw_title: \"RubyConf AU 2014: Building C Extensions in Ruby by André Medeiros\"\n  speakers:\n    - André Medeiros\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    From time to time, when building Ruby apps, you realise there are no libraries available for what you need. Even worse, Ruby doesn't quite perform as quickly as we would expect in certain areas. There are, however, a lot of high performance, mature technologies built in C that can easily be ported to be used with Ruby. By doing this, we get to keep using our favourite language, opening it to a plethora of applications that were not possible before, and still keep things snappy.\n    In this talk, I will walk you through the ins and outs of building Spyglass, an OpenCV binding for Ruby. I will also talk in detail about some gotchas (memory management, lack of threading), good practices (C objects as first class citizens, how to properly test extensions), why mkmf needs to be retired and some great examples of extensions you probably already use and should be looking at.\n  video_provider: \"youtube\"\n  video_id: \"KZgovmyB8d8\"\n\n- id: \"zach-holman-rubyconf-au-2014\"\n  title: \"RubyConf AU 2014: How Github (No Longer) Works\"\n  raw_title: \"RubyConf AU 2014: How Github (No Longer) Works by Zach Holman\"\n  speakers:\n    - Zach Holman\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Too many startups do this thing where they build their reputation with all these great technical blog posts and fascinating public talks, and then they become a Real Company and suddenly decide they're too cool to be open and transparent. Maybe the lawyers get to them, or maybe all the cool ninja rockstars become managers.\n    In any case, I think that's stupid. I don't want GitHub to be one of those companies. I think the scaling problems we face — both technical and human — as we near five million users and 250 employees are super interesting to talk about and learn from.\n    A lot of my talks like How GitHub Uses GitHub to Build GitHub and posts like How GitHub Works are nifty, but they represent a snapshot of the company when we were 30-75 employees. We're 217 today, and things inevitably changed to grow the company to that scale.\n    This talk is a retrospective: it takes a closer look at specific things that we've said over the last few years, and then details the adjustments that were made as we've grown.\n  video_provider: \"youtube\"\n  video_id: \"Jy__R9RFe7c\"\n\n- id: \"darcy-laycock-rubyconf-au-2014\"\n  title: \"Hacking Sidekiq for Fun and Profit\"\n  raw_title: \"RubyConf AU 2014: Hacking Sidekiq for Fun and Profit by Darcy Laycock\"\n  speakers:\n    - Darcy Laycock\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    It's almost inevitable in any Ruby Project - you hit that stage where your logic starts getting more complex, you start doing more stuff that needs to happen but doesn't have to happen in the foreground - or you just want things to be faster.\n    You move your logic out into workers and do the work in the background.\n    This talk is going to be all about Sidekiq - a threaded background job implementation written in Ruby - and, in two parts: How you can use it and how you can bend it to your will.\n    Part 1: Intro to Sidekiq\n    The boring: a brief introduction to sidekiq, how it works - what it's advantages are. The stuff you need to know about it, why it's useful to consider - even if you're using CRuby / MRI.\n    Part 2: Hacking Sidekiq\n    The cooler part - once you know what Sidekiq is, I'm going to show how you can use Sidekiq in your product, how you can extend it and bend it to your will. I'll go into how it implements itself in ruby land and how it interacts with the Redis.\n    I'll show how you can use the existing middleware (and write your own) to add behaviour to your code, patterns we've found useful for implementing and testing workers as well as the even more interesting side - using Lua support in Redis to implement stuff in Sidekiq.\n    I want to encourage developers to look at extending their tool set to work better with not just ruby - to become comfortable with how they work internally (e.g. you should really learn how to love redis) and what you really need to be careful of (e.g. bugs that manifest when the site is under less load than usual - a real world example of going too far).\n    Finally, I'll end with an important question: Why not just use a proper message queue?\n  video_provider: \"youtube\"\n  video_id: \"MimELPl9J9c\"\n\n- id: \"sebastian-von-conrad-rubyconf-au-2014\"\n  title: \"Real Developers Ship (a.k.a Tenets for Software Delivery)\"\n  raw_title: \"RubyConf AU 2014: Real Developers Ship (a.k.a Tenets for Software Delivery) by Sebastian von Conrad\"\n  speakers:\n    - Sebastian von Conrad\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Not too long ago, a small group of developers inside Envato embarked on a mission: take an idea, and turn it into something real. To accomplish this goal, they didn't just have to build the product, but change the way they were writing and shipping code as well. In the end, the way they were delivering was radically different to anything they'd ever done before. The result? Mission accomplished.\n    This talk explores the core tenets of the team's delivery process, and explores the reasons behind the decisions that were made. It mixes anecdotes with practical examples, showing how changing the way you think can really help get things done.\n    Some of the tenets in the talk include:\n    Level up your CI to continuous deployment Time is valued above all Staying lean with YAGNI Pay the refactor cost upfront Testing is best done in production Do things that don't scale Living on the bleeding edge The only way to move is forward After listening to this talk, you will know how easy it is to introduce these principles into your Rails app. You'll be armed with ideas of what you can take home to your team, in order to deliver better and faster than before.\n  video_provider: \"youtube\"\n  video_id: \"z7TbxlCTv3Y\"\n\n- id: \"todo-rubyconf-au-2014\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyConf AU 2014: Lightning Talks\"\n  speakers:\n    - TODO\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    A whirlwind of great talks: 5 minutes each.\n  video_provider: \"youtube\"\n  video_id: \"YGe3Vn7lHyo\"\n\n- id: \"hiro-asari-rubyconf-au-2014\"\n  title: \"State of JRuby 2014\"\n  raw_title: \"RubyConf AU 2014: State of JRuby 2014 by Hiro Asari\"\n  speakers:\n    - Hiro Asari\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    JRuby is a fast implementation of the Ruby language on the Java Virtual Machine.\n    You may wonder if it can be faster. You may have heard of the slow startup time. Can it load faster? You may have heard that your favorite C extension does not work on JRuby. What about cross-platform C extension API?\n    This talk will discuss these questions.\n    This year (2014), the project will release a major milestone: JRuby 9000 (仮). Main new features of this release include:\n    Ruby 2.1 compatibility New compiler Better InvokeDynamic experience\n  video_provider: \"youtube\"\n  video_id: \"QEuUQLl5I-Y\"\n\n- id: \"keith-pitt-rubyconf-au-2014\"\n  title: \"Continuous Deployment with Rails\"\n  raw_title: \"RubyConf AU 2014: Continuous Deployment with Rails by Keith Pitt & Mario Visic\"\n  speakers:\n    - Keith Pitt\n    - Mario Visic\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Recently it has become common practise for development teams to deploy their code several times a day, as well as encouraging new developers to deploy on their first day at work.\n    In our talk, we will discuss how we use continuous deployment to push these practises to the extreme. Automatically deploying the master branch on new changes is an awesome way to improve your development process.\n    Automatically deploying master will fundamentally change how you work. Gone are the days of the epic pull request. You'll quickly find yourself writing smaller more manageable chunks of code, that overall have a great impact on the quality of the software you produce.\n    By the end of the talk you'll know how to change the GitHub merge pull request button into a deploy button - and have the confidence to do so.\n    Some things we'll go over in the talk:\n    How to setup your CI environment for deployments Why having fast tests are important How to use your Staging environment for testing deployments How to use feature flags to hide deployed features from some users Zero downtime deploys, even when there are database migrations Your new deploy button, AKA The GitHub merge pull request button What to do when deployment goes wrong\n  video_provider: \"youtube\"\n  video_id: \"lcyp3MKYRhY\"\n\n- id: \"jon-rowe-rubyconf-au-2014\"\n  title: \"Tales of Interest\"\n  raw_title: \"RubyConf AU 2014: Tales of Interest by Jon Rowe\"\n  speakers:\n    - Jon Rowe\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-19\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    So you want to be an open source contributor? Think you can handle supporting multiple rubies, tracking down weird bugs, stomaching all that the wider developer eco system can throw at you? Well good reader, I can tell you stories that will turn your stomach, and blind your eyes.\n    Let me take you on a journey deep into the depths of open source triage and follow the kind of madness that comes from tracking down bugs across differing versions of Ruby and VMs.\n    Finally let me entertain you with stories of the perils of dogfooding your testing framework, and throw in some stories about the kind of hackery you can commit with a bit of mischievousness.\n  video_provider: \"youtube\"\n  video_id: \"EC1dY-nKTYY\"\n\n- id: \"sasha-gerrand-rubyconf-au-2014\"\n  title: \"Learning from Smalltalk\"\n  raw_title: \"RubyConf AU 2014: Learning from Smalltalk by Sasha Gerrand\"\n  speakers:\n    - Sasha Gerrand\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    Smalltalk is an object-oriented, dynamically typed, reflective programming language. Smalltalk is a \"pure\" object-oriented programming language, meaning that, unlike Java and C++, there is no difference between values which are objects and values which are primitive types. In Smalltalk, primitive values such as integers, booleans and characters are also objects, in the sense that they are instances of corresponding classes, and operations on them are invoked by sending messages.\n    Sound familiar?\n    Smalltalk leaves a long shadow on the programming landscape and can be considered both as an ancestor and influence on the design of Ruby. This talk introduces Smalltalk to Rubyists and covers software principles which can be applied to Ruby applications, both large and small.\n    Topics include:\n    Brief overview\n    Design\n    Expressions\n    Literals\n    Messages\n    Patterns\n    Reflection\n  video_provider: \"youtube\"\n  video_id: \"cBe-VnHMaUo\"\n\n- id: \"seth-vargo-rubyconf-au-2014\"\n  title: \"Using Ruby to Automate Your Life\"\n  raw_title: \"RubyConf AU 2014: Using Ruby to Automate Your Life by Seth Vargo\"\n  speakers:\n    - Seth Vargo\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n\n    You probably use Ruby everyday, so why not use Ruby to automate some common tasks? What if you could spin up an EC2 instance and have it automatically configure your web server, database, users, and more? What if you could effectively capture and replicate your production environments reliably and consistently? What if you could then give developers production-like environments as Virtual Machines, with no additional work? What if you could set up your new laptop with multiple Ruby versions, your favourite software, and even change the desktop background - from a single command? The good news is - you can!\n    Chef is a configuration management and automation tool that solves these problems and many more. In this talk, you'll learn common just how easy it is to capture your infrastructure in Chef. Save time and money by using Chef's Ruby DSL to \"define\" your laptop.\n    How many times have you bought a new laptop and realise just how much stuff you installed over the years? If you're using Chef, run a single command\n  video_provider: \"youtube\"\n  video_id: \"R_qFzviMkGY\"\n\n- id: \"eleanor-saitta-rubyconf-au-2014\"\n  title: \"Outcome Oriented Security\"\n  raw_title: \"RubyConf AU 2014: Outcome Oriented Security by Eleanor Saitta\"\n  speakers:\n    - Eleanor Saitta\n  event_name: \"RubyConf AU 2014\"\n  date: \"2014-02-21\"\n  published_at: \"2017-05-22\"\n  description: |-\n    RubyConf AU 2014: http://www.rubyconf.org.au\n  video_provider: \"youtube\"\n  video_id: \"f4sVHdb4ik4\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2015/event.yml",
    "content": "---\nid: \"PL9_jjLrTYxc2uUcqG2wjZ1ppt-TkFG-gm\"\ntitle: \"RubyConf AU 2015\"\nkind: \"conference\"\nlocation: \"Melbourne, Australia\"\ndescription: \"\"\npublished_at: \"2017-05-20\"\nstart_date: \"2015-02-04\"\nend_date: \"2015-02-07\"\nchannel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nyear: 2015\ncoordinates:\n  latitude: -37.8136276\n  longitude: 144.9630576\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2015/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Pat Allan\n    - Mel Kaulfuss\n    - Sebastian von Conrad\n    - Matt Allen\n\n  organisations:\n    - Ruby Australia\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2015/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 1\"\n    date: \"2015-02-04\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"16:00\"\n        slots: 3\n\n      - start_time: \"19:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Opening Party\n\n  - name: \"Day 2\"\n    date: \"2015-02-05\"\n    grid:\n      - start_time: \"9:50\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:25\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"11:50\"\n        slots: 1\n\n      - start_time: \"11:50\"\n        end_time: \"12:15\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"13:55\"\n        slots: 1\n\n      - start_time: \"13:55\"\n        end_time: \"14:20\"\n        slots: 1\n\n      - start_time: \"14:20\"\n        end_time: \"14:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:50\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"15:40\"\n        slots: 1\n\n      - start_time: \"15:40\"\n        end_time: \"16:10\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:10\"\n        end_time: \"16:35\"\n        slots: 1\n\n      - start_time: \"16:35\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"20:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Melbourne by Night - Rooftop Cinema\n\n  - name: \"Day 3\"\n    date: \"2015-02-06\"\n    grid:\n      - start_time: \"9:40\"\n        end_time: \"10:05\"\n        slots: 1\n\n      - start_time: \"10:05\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:25\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"11:50\"\n        slots: 1\n\n      - start_time: \"11:50\"\n        end_time: \"12:15\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"13:55\"\n        slots: 1\n\n      - start_time: \"13:55\"\n        end_time: \"14:20\"\n        slots: 1\n\n      - start_time: \"14:20\"\n        end_time: \"14:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:50\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"15:40\"\n        slots: 1\n\n      - start_time: \"15:40\"\n        end_time: \"16:10\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:10\"\n        end_time: \"16:35\"\n        slots: 1\n\n      - start_time: \"16:35\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"19:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Friday Night Dinners\n\n  - name: \"Day 4\"\n    date: \"2015-02-07\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"16:00\"\n        slots: 4\n        items:\n          - Healesville Sanctuary 🐨\n          - Riverside Bike Ride 🚴\n          - City Walking Tour 📸\n          - Hack Day 💻\n\n      - start_time: \"16:30\"\n        end_time: \"20:00\"\n        slots: 1\n        items:\n          - Closing Picnic\n\n      - start_time: \"20:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - After Party\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2015/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby\"\n      level: 1\n      sponsors:\n        - name: \"Envato\"\n          website: \"https://envato.com/\"\n          slug: \"Envato\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/envato.png\"\n\n    - name: \"Emerald\"\n      level: 2\n      sponsors:\n        - name: \"RedBubble\"\n          website: \"https://redbubble.com/\"\n          slug: \"RedBubble\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/redbubble.png\"\n\n        - name: \"RealEstate.com.au\"\n          website: \"https://realestate.com.au/\"\n          slug: \"RealEstateComAu\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/rea.png\"\n\n        - name: \"reInteractive\"\n          website: \"https://reinteractive.net/\"\n          slug: \"reInteractive\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/reinteractive.png\"\n\n    - name: \"Sapphire\"\n      level: 3\n      sponsors:\n        - name: \"Digital Ocean\"\n          website: \"https://www.digitalocean.com/\"\n          slug: \"DigitalOcean\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/digitalocean.png\"\n\n        - name: \"JobReady\"\n          website: \"http://jobready.com.au/\"\n          slug: \"JobReady\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/jobready.png\"\n\n        - name: \"Torii\"\n          website: \"http://toriirecruitment.com.au/\"\n          slug: \"Torii\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/torii.png\"\n\n        - name: \"GitHub\"\n          website: \"https://github.com/\"\n          slug: \"GitHub\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/github.png\"\n\n        - name: \"PluralSight\"\n          website: \"http://www.pluralsight.com/\"\n          slug: \"PluralSight\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/pluralsight.png\"\n\n        - name: \"Buildkite\"\n          website: \"https://buildkite.com/\"\n          slug: \"Buildkite\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/buildkite.png\"\n\n        - name: \"Lookahead Search\"\n          website: \"http://www.lookahead.com.au/\"\n          slug: \"LookaheadSearch\"\n          logo_url: \"https://www.rubyconf.org.au/images/2015/sponsors/lookahead.png\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2015/videos.yml",
    "content": "---\n# Website: https://rubyconf.org.au/2015\n\n- id: \"paolo-perrotta-rubyconf-au-2015-workshop-1\"\n  title: \"Crash Into Ruby - From the basics to metaprogramming\"\n  raw_title: \"Crash Into Ruby - From the basics to metaprogramming presented by Paolo Perrotta\"\n  speakers:\n    - Paolo Perrotta\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-04\"\n  published_at: \"N/A\"\n  description: |-\n    This is a one-day crash-course for Ruby beginners and intermediates. It will\n    take you all the way through from basic Ruby coding, to the secrets of the\n    object model, and up to advanced metaprogramming techniques. Whether you're\n    a Java developer, a Python guru, or a JavaScript wizard, this workshop will\n    show you what's the big deal about Ruby, why people love it so much, and why\n    idiomatic Ruby code looks... different.\n  video_provider: \"not_recorded\"\n  video_id: \"paolo-perrotta-rubyconf-au-2015-workshop-1\"\n\n- id: \"jon-rowe-rubyconf-au-2015-workshop-2\"\n  title: \"RSpec++\"\n  raw_title: \"RSpec++ presented by Jon Rowe\"\n  speakers:\n    - Jon Rowe\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-04\"\n  published_at: \"N/A\"\n  description: |-\n    You've been using RSpec for a while, you know how to write tests, but you're\n    not sure you're getting the most from it. Let's spend some time working with\n    the more advanced features, take a look at the new stuff from RSpec 3 and\n    talk about making tests faster. If you use Rails, learn how to use RSpec\n    without rspec-rails and experience the power that brings.\n  video_provider: \"not_recorded\"\n  video_id: \"jon-rowe-rubyconf-au-2015-workshop-2\"\n\n- id: \"christophe-philemotte-rubyconf-au-2015-workshop-3\"\n  title: \"Static Analysis Driven Refactoring\"\n  raw_title: \"Static Analysis Driven Refactoring presented by Christophe Philemotte\"\n  speakers:\n    - Christophe Philemotte\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-04\"\n  published_at: \"N/A\"\n  description: |-\n    We'll illustrate how we can use static analysis tools to drive the\n    refactoring of a Rails app. First, we'll quickly introduce static analysis,\n    its benefits and complimentarity with other practices. We'll present each\n    tools, how to understand them, and how they can drive the refactoring on a\n    real big open source project. We'll show how to automate their run and\n    integrate it in your workflow. Finally, if we get the time, we'll do the\n    same on projects of the audience.\n  video_provider: \"not_recorded\"\n  video_id: \"christophe-philemotte-rubyconf-au-2015-workshop-3\"\n\n- id: \"collis-taeed-rubyconf-au-2015\"\n  title: \"Sideprojects and Startups\"\n  raw_title: \"RubyConf AU 2015: Sideprojects and Startups by Collis Ta'eed\"\n  speakers:\n    - Collis Ta'eed\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-05\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n  video_provider: \"youtube\"\n  video_id: \"lwWEc4PhmJI\"\n\n- id: \"linda-liukas-rubyconf-au-2015\"\n  title: \"Principles of Play\"\n  raw_title: \"RubyConf AU 2015: Principles of Play by Linda Liukas\"\n  speakers:\n    - Linda Liukas\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-05\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n  video_provider: \"youtube\"\n  video_id: \"KMBiP6VIlig\"\n\n- id: \"keith-pitty-rubyconf-au-2015\"\n  title: \"Loving Legacy Code\"\n  raw_title: \"RubyConf AU 2015: Loving Legacy Code by Keith Pitty\"\n  speakers:\n    - Keith Pitty\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-05\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    February 2015 marks the tenth anniversary of DHH sharing commit rights to Rails. Doubtless there is now much legacy Rails code. Why do developers typically hate legacy code? What characteristics of a Rails application earn it the right to be classified as \"legacy\"? Whilst these should not be difficult to answer, perhaps there are more important and challenging questions that we ought to consider. How can we learn to love legacy code so that it, in turn, becomes more loveable? What practical steps can we take to tame a legacy codebase so that it becomes more of a pleasure to work with?\n  video_provider: \"youtube\"\n  video_id: \"-PdHrg43sCc\"\n\n- id: \"lauren-voswinkel-rubyconf-au-2015\"\n  title: \"Nitty Gritty Service Building\"\n  raw_title: \"RubyConf AU 2015: Nitty Gritty Service Building by Lauren Voswinkel\"\n  speakers:\n    - Lauren Voswinkel\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-05\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    You've learned about Service Oriented Architecture. You want to use it. You know the benefits to testing speeds, to team velocity, and page load (why do in sequence what can be done in parallel?). Problem is, you're tearing your hair out trying to figure out how to actually pull those services out of your monorail.\n\n    This isn't about the metrics to determine what should be pulled out into a service. This talk isn't even about optimizing the service you pull out. This talk is a step-by-step approach about how to successfully pull a service out of an existing app and optimizing its performance.\n  video_provider: \"youtube\"\n  video_id: \"1lmMlIQuE6Q\"\n\n- id: \"tom-stuart-rubyconf-au-2015\"\n  title: \"Consider Static Typing\"\n  raw_title: \"RubyConf AU 2015: Consider Static Typing by Tom Stuart\"\n  speakers:\n    - Tom Stuart\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-05\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    Matz announced in his RubyConf 2014 keynote that Ruby 3.0 might have a static type system. What does that really mean? How should we feel about it? Will Ruby 3.0 still be Ruby? In this talk I’ll unpack what Matz said and make some educated guesses about what it means for the future of Ruby.\n  video_provider: \"youtube\"\n  video_id: \"efzHrOxzrNE\"\n  slides_url: \"https://speakerdeck.com/tomstuart/consider-static-typing\"\n  thumbnail_xs: \"https://img.youtube.com/vi/efzHrOxzrNE/default.jpg\"\n  thumbnail_sm: \"https://img.youtube.com/vi/efzHrOxzrNE/mqdefault.jpg\"\n  thumbnail_md: \"https://img.youtube.com/vi/efzHrOxzrNE/mqdefault.jpg\"\n  thumbnail_lg: \"https://img.youtube.com/vi/efzHrOxzrNE/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/efzHrOxzrNE/hqdefault.jpg\"\n\n- id: \"sean-marcia-rubyconf-au-2015\"\n  title: \"Saving the World (Literally) with Ruby\"\n  raw_title: \"RubyConf AU 2015: Saving the World (Literally) with Ruby by Sean Marcia\"\n  speakers:\n    - Sean Marcia\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-05\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    Two thirds of honeybee hives have died out in Virginia. Is it possible for us to devise a way of monitoring beehives in remote locations to find the cause? Enter a raspberry pi + rails. Using a combination of this robust hardware and software solution, we were able to successfully track, monitor and provide real time reporting on the well-being of hives from across the county. Find out how we used ruby, rails, solar panels and other libraries to provide insight into this problem.\n  video_provider: \"youtube\"\n  video_id: \"nDYh7cdGqFc\"\n\n- id: \"konstantin-gredeskoul-rubyconf-au-2015\"\n  title: 'DevOps Without The \"Ops\" – A Fallacy? A Dream? Or Both?'\n  raw_title: 'RubyConf AU 2015: DevOps Without The \"Ops\" – A Fallacy? A Dream? Or Both? by Konstantin Gredeskoul'\n  speakers:\n    - Konstantin Gredeskoul\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-05\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    Do you need Ops in your new startup? If not now, then when? And...what is Ops?\n\n    Learn how to scale ruby-based distributed software infrastructure in the cloud to serve 4,000 requests per second, handle 400 updates per second, and achieve 99.97% uptime – all while building the product at the speed of light.\n\n    Unimpressed? Now try doing the above altogether without the Ops team, while growing your traffic 100x in 6 months and deploying 5-6 times a day!\n\n    It could be a dream, but luckily it's a reality that could be yours.\n  video_provider: \"youtube\"\n  video_id: \"fd9i0GAzZI8\"\n\n- id: \"amy-wibowo-rubyconf-au-2015\"\n  title: \"Sweaters as a Service\"\n  raw_title: \"RubyConf AU 2015: Sweaters as a Service by Amy Wibowo\"\n  speakers:\n    - Amy Wibowo\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-05\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    In the 1980's, Nintendo had plans for making a knitting add-on to the NES, with an interface that resembled Mariopaint, but with patterned mittens, sweaters, and scarves as output. Sadly, this product never saw the light of day. Devastated upon hearing this and dreaming about what could have been, a group of engineers (who knew nothing about machine knitting) set out to hack a knitting machine from the 1980's to be computer-controlled, using a tutorial from adafruit as a starting point.\n  video_provider: \"youtube\"\n  video_id: \"5Er--usI5gw\"\n\n- id: \"coraline-ada-ehmke-rubyconf-au-2015\"\n  title: \"Pre-factoring: Getting it (Closer to) Right the First Time\"\n  raw_title: \"RubyConf AU 2015: Pre-factoring: Getting it (Closer to) Right the First Time by Coraline Ada Ehmke\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-05\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    Mention the word architecture and you're sure to hear criticism about the difference between waterfall and agile processes. Spending time on extensibility? You ain't gonna need it, they say. Worried about speed? Cries of premature optimization ensue. But that MVP you're building is going to form the core of a business solution that will presumably last for years. Short-sightedly painting yourself into a corner is not a good way to start it off. But it doesn't have to be a choice between cowboy coding and analysis paralysis. We can take a step back and explore ways to budget for basic architecture, plan for the future, lay the foundations for growth, and avoid becoming riddled with technical debt.\n  video_provider: \"youtube\"\n  video_id: \"U6ejBh80gxg\"\n\n- id: \"john-barton-rubyconf-au-2015\"\n  title: \"On Second Acts\"\n  raw_title: \"RubyConf AU 2015: On Second Acts by John Barton\"\n  speakers:\n    - John Barton\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-05\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    Australia's had a vibrant nation wide Ruby community for a good 7 years now. We're definitely well into the second act of our story arc, but what does that mean? Where do we want the community to go from here? Is there something special about the Ruby & Rails platform and community that can give us a unique third act?\n  video_provider: \"youtube\"\n  video_id: \"lVG1SV8wWxs\"\n\n- id: \"steve-klabnik-rubyconf-au-2015\"\n  title: \"What is a Rubyist?\"\n  raw_title: \"RubyConf AU 2015: What is a Rubyist? by Steve Klabnik\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n  video_provider: \"youtube\"\n  video_id: \"ImfGkWQ9zBQ\"\n\n- id: \"joss-paling-rubyconf-au-2015\"\n  title: \"Feeling like a better developer (AKA overcoming impostor syndrome)\"\n  raw_title: \"RubyConf AU 2015: Feeling like a better developer (AKA overcoming impostor syndrome) by Joss Paling\"\n  speakers:\n    - Joss Paling\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    This isn't a talk about becoming a better developer - you may be less in need of that than you think! This is a talk about feeling like a better developer. It's a talk about overcoming doubts that will hold you back both personally and professionally. It's a talk about feeling confident with your own ability, while working in one of the most complex, fast-paced, and ever-changing industries in the world.\n  video_provider: \"youtube\"\n  video_id: \"cWZM_KgOFD4\"\n\n- id: \"sabrina-leandro-rubyconf-au-2015\"\n  title: \"Rewriting Code and Culture\"\n  raw_title: \"RubyConf AU 2015: Rewriting Code and Culture by Sabrina Leandro\"\n  speakers:\n    - Sabrina Leandro\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    This is the story of a company that survived a much needed transformation of its product and codebase, but most importantly, of its culture. There's no real prescription for being agile. It's about the journey a team takes to discover how to best work together and deliver great products.\n\n    In this presentation, I'll share a candid view of a team trying to overcome a slow product development process. How we refactored our way out of badly coupled code, moved to continuous deployment, and greatly improved our approach to product and software development.\n  video_provider: \"youtube\"\n  video_id: \"787v6BcloJg\"\n\n- id: \"scott-feinberg-rubyconf-au-2015\"\n  title: \"Securing your App and the History of Guerilla Warfare\"\n  raw_title: \"RubyConf AU 2015: Securing your App and the History of Guerilla Warfare by Scott Feinberg\"\n  speakers:\n    - Scott Feinberg\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    It's a battle in the trenches everyday working in financial services keeping our users protected, making sure that hackers aren't breaking in and diverting funds or using our system as a laundering machine.\n\n    We'll journey through some lesser known attack vectors hackers can use to break into systems and best practices to both detect and prevent attacks. What are some easy ways to fight these in your app? How do you know if you're safe?\n  video_provider: \"youtube\"\n  video_id: \"8ikjuuL8Qrg\"\n\n- id: \"rachel-myers-rubyconf-au-2015\"\n  title: \"Service Oriented Disasters\"\n  raw_title: \"RubyConf AU 2015: Service Oriented Disasters by Rachel Myers\"\n  speakers:\n    - Rachel Myers\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    Starting with the assumptions that, first, we’re all building and maintaining complex applications, because Rails has made that relatively easy, and, second, that application complexity isn’t limited to Rails, this talk walks through a few practical case studies of identifying (or misidentifying) modern application complexity. We’ll delve into my personal anti-pattern goldmine for examples of yesterday’s architecture trend becoming today’s legacy headache, and also look at examples of creative, workable solutions to application complexity!\n  video_provider: \"youtube\"\n  video_id: \"e02h_cTeuVM\"\n\n- id: \"joseph-wilk-rubyconf-au-2015\"\n  title: \"Programming as Performance\"\n  raw_title: \"RubyConf AU 2015: Programming as Performance by Joseph Wilk\"\n  speakers:\n    - Joseph Wilk\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n  video_provider: \"youtube\"\n  video_id: \"_z8FQdIbpJo\"\n\n- id: \"shevaun-coker-rubyconf-au-2015\"\n  title: \"A Case for Use Cases\"\n  raw_title: \"RubyConf AU 2015: A Case for Use Cases by Shevaun Coker\"\n  speakers:\n    - Shevaun Coker\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    Wikipedia, the Webster's Dictionary of our generation, defines a Use Case as \"a list of steps, defining interactions between a role and a system, to achieve a goal.\"\n\n    If you cut your teeth on RoR, at some point you've probably shuffled domain logic from views to controllers to models to POROs in pursuit of Separation of Concerns.\n\n    Now it's time to introduce Use Cases as a contextual, well-defined interface between your Rails controllers and your domain entities. Walk through real examples and learn how these nifty little classes reveal your user stories while hiding implementation detail.\n  video_provider: \"youtube\"\n  video_id: \"atFN0rReJfA\"\n\n- id: \"sarah-mei-rubyconf-au-2015\"\n  title: \"Fields & Fences\"\n  raw_title: \"RubyConf AU 2015: Fields & Fences by Sarah Mei\"\n  speakers:\n    - Sarah Mei\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n  video_provider: \"youtube\"\n  video_id: \"HFk1vnJMXpc\"\n\n- id: \"john-dalton-rubyconf-au-2015\"\n  title: \"Understanding Despair\"\n  raw_title: \"RubyConf AU 2015: Understanding Despair by John Dalton\"\n  speakers:\n    - John Dalton\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    Depression is a topic that many people avoid talking about, but one that touches everyone's lives. In the developer community in particular many people are affected by depression and mental illness, yet it can be difficult to understand what people are going through or how to help. I want to show you how I came to understand what it means to have clinical depression, and the single most important thing we can do about it.\n  video_provider: \"youtube\"\n  video_id: \"nvl9muoYPaY\"\n\n- id: \"philip-arndt-rubyconf-au-2015\"\n  title: \"Succeeding with Open Source\"\n  raw_title: \"RubyConf AU 2015: Succeeding with Open Source by Philip Arndt\"\n  speakers:\n    - Philip Arndt\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    Open source is at the heart of the Ruby community and there's great value in contributing. I found this out after becoming a maintainer of one of the most popular Ruby gems. Open source helped me dramatically raise my coding abilities, reputation, and salary - all while meeting people from around the globe.\n\n    You'll learn how to get started and maintain a high velocity open source codebase + tips for effective communication with collaborators. Whether you're new to Ruby or sitting on a quarter of a million rubygems downloads, you'll walk away with a clear path to open source success.\n  video_provider: \"youtube\"\n  video_id: \"8i5c3RXa3g8\"\n\n- id: \"erik-michaels-ober-rubyconf-au-2015\"\n  title: \"Towards a Higher-Level Language\"\n  raw_title: \"RubyConf AU 2015: Towards a Higher-Level Language by Erik Michaels-Ober\"\n  speakers:\n    - Erik Michaels-Ober\n  event_name: \"RubyConf AU 2015\"\n  date: \"2015-02-06\"\n  published_at: \"2017-05-20\"\n  description: |-\n    RubyConf AU 2015: http://www.rubyconf.org.au\n\n    Over time, programming languages have allowed programmers to work at higher and higher levels of abstraction. Very little code is written in machine language or assembly language anymore.\n\n    Despite this long-term trend, most programming languages that have emerged over the past 5 years (e.g. Go, Rust, Swift) are lower-level than Ruby. Arguably, Ruby is the highest-level language in wide use today, despite being over 20 years old.\n\n    This talk will explore the possibilities of a new language that would operate at an even higher level of abstraction, making programming even simpler.\n  video_provider: \"youtube\"\n  video_id: \"cjPybeAeKDQ\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2016/event.yml",
    "content": "---\nid: \"PL9_jjLrTYxc3ILv2Lxlt422NjIFWnXl0U\"\ntitle: \"RubyConf AU 2016\"\nkind: \"conference\"\nlocation: \"Gold Coast, Australia\"\ndescription: |-\n  Leading Rubyists from around the world came together on the Gold Coast to share, inspire and learn.\n\n  February 10th-13th 2016, Sea World Resort, Gold Coast\npublished_at: \"2017-01-31\"\nstart_date: \"2016-02-10\"\nend_date: \"2016-02-13\"\nchannel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nyear: 2016\ncoordinates:\n  latitude: -27.9769248\n  longitude: 153.380936\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2016/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Rob Jacoby\n    - Jo Montanari\n    - Rachelle LeQuesne\n\n  organisations:\n    - Ruby Australia\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2016/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 1\"\n    date: \"2016-02-10\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"9:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:00\"\n        end_time: \"17:00\"\n        slots: 5\n\n      - start_time: \"19:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Opening Party\n\n  - name: \"Day 2\"\n    date: \"2016-02-11\"\n    grid:\n      - start_time: \"09:15\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:05\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"10:45\"\n        end_time: \"11:05\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:05\"\n        end_time: \"11:40\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:05\"\n        slots: 1\n\n      - start_time: \"12:05\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:35\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:35\"\n        end_time: \"14:00\"\n        slots: 1\n\n      - start_time: \"14:00\"\n        end_time: \"14:25\"\n        slots: 1\n\n      - start_time: \"14:25\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:35\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:35\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:25\"\n        slots: 1\n\n      - start_time: \"16:25\"\n        end_time: \"16:50\"\n        slots: 1\n\n      - start_time: \"16:50\"\n        end_time: \"17:30\"\n        slots: 1\n\n  - name: \"Day 3\"\n    date: \"2016-02-12\"\n    grid:\n      - start_time: \"09:15\"\n        end_time: \"09:40\"\n        slots: 1\n\n      - start_time: \"09:40\"\n        end_time: \"10:05\"\n        slots: 1\n\n      - start_time: \"10:05\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"10:45\"\n        end_time: \"11:05\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:05\"\n        end_time: \"11:40\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:05\"\n        slots: 1\n\n      - start_time: \"12:05\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:35\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:35\"\n        end_time: \"14:00\"\n        slots: 1\n\n      - start_time: \"14:00\"\n        end_time: \"14:25\"\n        slots: 1\n\n      - start_time: \"14:25\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:35\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:35\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:25\"\n        slots: 1\n\n      - start_time: \"16:25\"\n        end_time: \"16:50\"\n        slots: 1\n\n      - start_time: \"19:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - \"Movie World Party\"\n\n  - name: \"Day 4\"\n    date: \"2016-02-13\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"13:00\"\n        slots: 5\n        items:\n          - \"Paddle Boarding\"\n          - \"Currumbin Wildlife Sanctuary\"\n          - \"Bush Walk\"\n          - \"Sea World\"\n          - \"Hack Day\"\n\n      - start_time: \"14:00\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - Beach BBQ\n\n      - start_time: \"18:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Evening Drinks\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2016/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby\"\n      level: 1\n      sponsors:\n        - name: \"Envato\"\n          website: \"https://envato.com/\"\n          slug: \"Envato\"\n          logo_url: \"https://www.rubyconf.org.au/images/2016/sponsors/envato.png\"\n\n    - name: \"Emerald\"\n      level: 2\n      sponsors:\n        - name: \"Culture Amp\"\n          website: \"https://www.cultureamp.com\"\n          slug: \"CultureAmp\"\n          logo_url: \"https://www.rubyconf.org.au/images/2016/sponsors/culture-amp.png\"\n\n        - name: \"PayPal Developer\"\n          website: \"https://www.paypal.com/au/home\"\n          slug: \"PayPal\"\n          logo_url: \"https://www.rubyconf.org.au/images/2016/sponsors/braintree.png\"\n\n    - name: \"Sapphire\"\n      level: 3\n      sponsors:\n        - name: \"Lookahead Search\"\n          website: \"https://www.lookahead.com.au/\"\n          slug: \"LookaheadSearch\"\n          logo_url: \"https://www.rubyconf.org.au/images/2016/sponsors/lookahead.jpg\"\n\n        - name: \"Zendesk\"\n          website: \"https://www.zendesk.com\"\n          slug: \"Zendesk\"\n          logo_url: \"https://www.rubyconf.org.au/images/2016/sponsors/zendesk.png\"\n\n        - name: \"Sitepoint\"\n          website: \"https://www.sitepoint.com\"\n          slug: \"Sitepoint\"\n          logo_url: \"https://www.rubyconf.org.au/images/2016/sponsors/sitepoint.png\"\n\n    - name: \"Opal\"\n      level: 4\n      sponsors:\n        - name: \"LocalSearch\"\n          website: \"https://www.localsearch.com.au\"\n          slug: \"LocalSearch\"\n          logo_url: \"https://www.rubyconf.org.au/images/2016/sponsors/local-search.png\"\n\n        - name: \"GitHub\"\n          website: \"https://github.com/\"\n          slug: \"GitHub\"\n          logo_url: \"https://www.rubyconf.org.au/images/2016/sponsors/github.png\"\n\n    - name: \"RubyConf Assist\"\n      level: 5\n      sponsors:\n        - name: \"Cogent\"\n          website: \"https://www.cogent.co\"\n          slug: \"Cogent\"\n          logo_url: \"https://www.rubyconf.org.au/images/2016/sponsors/cogent.png\"\n\n        - name: \"ThoughtWorks\"\n          website: \"https://www.thoughtworks.com/\"\n          slug: \"ThoughtWorks\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/thoughtworks.svg\"\n\n    - name: \"Speakers\"\n      level: 6\n      sponsors:\n        - name: \"Facebook\"\n          website: \"https://www.facebook.com\"\n          slug: \"Facebook\"\n          logo_url: \"https://www.rubyconf.org.au/images/2016/sponsors/facebook.png\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2016/videos.yml",
    "content": "---\n# Website: https://rubyconf.org.au/2016\n\n- id: \"trailblazer-rubyconf-au-2016-workshop-1\"\n  title: \"Architecture Matters: An Appetizing Introduction to Trailblazer\"\n  raw_title: \"Architecture Matters: An Appetizing Introduction to Trailblazer by Nick Kirkwood and Nick Sutterer\"\n  speakers:\n    - Nick Kirkwood\n    - Nick Sutterer\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-10\"\n  published_at: \"N/A\"\n  description: |-\n    Trailblazer is an extension framework on top of Rails. It provides\n    desperately needed, new abstraction layers, decent encapsulation and a\n    better maintainable architecture.\n\n    In this workshop we're gonna learn the basics about designing your domain,\n    encapsulating business logic in operations, form objects and view models,\n    and a different take on the persistence layer. After a compact introducing\n    presentation by Nick Kirkwood and Nick Sutterer, we'll dive into the code,\n    write a small Trailblazer/Rails app and learn all the nice things about this\n    alternative architecture over a cold bottle of beer.\n  video_provider: \"not_recorded\"\n  video_id: \"trailblazer-rubyconf-au-2016-workshop-1\"\n\n- id: \"developer-flow-rubyconf-au-2016-workshop-2\"\n  title: \"Finding Developer Flow\"\n  raw_title: \"Finding Developer Flow by Richie Khoo and Dan Draper\"\n  speakers:\n    - Richie Khoo\n    - Dan Draper\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-10\"\n  published_at: \"N/A\"\n  description: |-\n    Sometimes everything just clicks, solutions just come to you and as you\n    quietly tap away you feel almost at one with the computer, you're in the\n    zone. At other times, nothing seems to make sense, you've been struggling\n    with this one issue for hours and not even StackOverflow seems to know what\n    the problem is. You feel like your brain is about to explode. Why even do\n    this?! You're in the chasm.\n\n    Join Richie & Dan as we explore what is \"Developer Flow\" and how it affects\n    your productivity as a programmer.\n\n    This workshop is designed for the post-beginner/intermediate developer who\n    maybe has a few coding books, favorite gems and editor shortcuts under their\n    belt but is still hunting for a more peaceful and focussed way to code.\n\n    In an interactive full day workshop we'll discuss, pair, debate, compare and\n    dig deep to help you find your own path to greater developer flow and\n    finding your way more often into the zone. Richie Khoo is a serial polyglot\n    and extreme learner. Richie Khoo has been working as a ruby gun-for-hire for\n    over 6 years, has mentored devs as a Ruby Mentor at Thinkful and helped\n    co-found Ruby Australia. Dan Draper has been a Rubyist since 2007 after\n    throwing in the towel on Java. He was Chief Course Instructor at Coder\n    Factory and has been a CTO and CEO of several companies.\n  video_provider: \"not_recorded\"\n  video_id: \"developer-flow-rubyconf-au-2016-workshop-2\"\n\n- id: \"tasteful-go-rubyconf-au-2016-workshop-3\"\n  title: \"Tasteful Go\"\n  raw_title: \"Tasteful Go by Katrina Owen\"\n  speakers:\n    - Katrina Owen\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-10\"\n  published_at: \"N/A\"\n  description: |-\n    Go is a beautiful, minimalistic, and consistent language. It is simple, yet\n    learning it can feel quite intimidating for many developers who come to the\n    language without a background in Computer Science.\n\n    Join Katrina Owen for this hands-on, one-day workshop, focused on developing\n    fluency and ease with the fundamental features of the language. It provides\n    a practical introduction to writing Go the way Gophers expect to see it\n    written.\n\n    Participants switch between writing code to solve small exercises, and\n    reviewing pre-selected solutions that exemplify common gotchas and style\n    violations. We look at the official recommendations relevant to each\n    example. Finally we look at several idiomatic solutions that make good use\n    of the language features.\n\n    By the end of the day, participants should be comfortable reading Go code,\n    and able to solve basic problems idiomatically.\n\n    The ideal participant is currently programming professionally in a language\n    other than Go.\n  video_provider: \"not_recorded\"\n  video_id: \"tasteful-go-rubyconf-au-2016-workshop-3\"\n\n- id: \"rails-girls-rubyconf-au-2016-workshop-4\"\n  title: \"Rails Girls\"\n  raw_title: \"Rails Girls\"\n  speakers:\n    - TODO\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-10\"\n  published_at: \"N/A\"\n  description: |-\n    Our aim is to give tools and a community for women to understand technology\n    and to build their ideas. We do this by providing a great experience on\n    building things and by making technology more approachable.\n\n    Learn sketching, prototyping, basic programming and get introduced to the\n    world of technology. Rails Girls was born in Finland, but is nowadays a\n    global, non-profit volunteer community.\n  video_provider: \"not_recorded\"\n  video_id: \"rails-girls-rubyconf-au-2016-workshop-4\"\n\n- id: \"rails-girls-next-rubyconf-au-2016-workshop-5\"\n  title: \"Rails Girls Next\"\n  raw_title: \"Rails Girls Next\"\n  speakers:\n    - TODO\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-10\"\n  published_at: \"N/A\"\n  description: |-\n    During this free one-day workshop, we'll dive into the magical world of\n    Ruby.\n\n    This particular workshop requires that you've either done the original Rails\n    Girls day, or have some prior programming experience. If not, you may like\n    to join the original Rails Girls event instead.\n  video_provider: \"not_recorded\"\n  video_id: \"rails-girls-next-rubyconf-au-2016-workshop-5\"\n\n- id: \"jeff-casimir-rubyconf-au-2016\"\n  title: \"10 years 10 mistakes\"\n  raw_title: \"10 years 10 mistakes by Jeff Casimir\"\n  speakers:\n    - Jeff Casimir\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-01-31\"\n  description: |-\n    Over the past 10 years I've started or run six different businesses. Along that way I made a lot of painful, painful mistakes. In this session we'll go through some great stories, figure out what went wrong, and the lessons learned to avoid making the same mistakes again. You can take these lessons I learned the hard way and apply them to your creative work as a consultant, startup, or even within a larger organisation. Worst case scenario, we get to laugh together about things that seemed like good ideas -- at the time.\n  video_provider: \"youtube\"\n  video_id: \"DhqzMc_LXgQ\"\n\n- id: \"saron-yitbarek-rubyconf-au-2016\"\n  title: \"Learning Code Good\"\n  raw_title: \"RubyConf AU 2016: Learning Code Good by Saron Yitbarek\"\n  speakers:\n    - Saron Yitbarek\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016:\n  video_provider: \"youtube\"\n  video_id: \"q4mPIctwZ-Q\"\n\n- id: \"enrico-teotti-rubyconf-au-2016\"\n  title: \"Build and maintain large Ruby applications\"\n  raw_title: \"RubyConf AU 2016: Build and maintain large Ruby applications by Enrico Teotti\"\n  speakers:\n    - Enrico Teotti\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-05-18\"\n  description: |-\n    RubyConf AU 2016: This presentation will be about the challenges of building large Ruby web applications and how to maintain existing ones.\n\n    I will use examples adapted from real applications that I worked on during my 10 years of experience with Ruby outlining: technical limitations of the language, how to use a modular dependency structure to enforce boundaries in complex domains.\n  video_provider: \"youtube\"\n  video_id: \"b1glMxMPscA\"\n\n- id: \"thong-kuah-rubyconf-au-2016\"\n  title: \"Code Review: Pitfalls and Good Practices\"\n  raw_title: \"RubyConf AU 2016: Code Review: Pitfalls and Good Practices by Thong Kuah\"\n  speakers:\n    - Thong Kuah\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Some of us have practiced code review as part of our software development process. But it is more than just a peer review of code written by another. I will attempt to summarise some of the good practices that worked for us to review code effectively and some of the common mistakes not to make when setting out a code review programme for your team.\n  video_provider: \"youtube\"\n  video_id: \"akf0Mx72wgI\"\n\n- id: \"katie-miller-rubyconf-au-2016\"\n  title: \"Pursuing the Strong, Not So Silent Type: A Haskell Story\"\n  raw_title: \"RubyConf AU 2016: Pursuing the Strong, Not So Silent Type: A Haskell Story by Katie Miller\"\n  speakers:\n    - Katie Miller\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: In recent months Katie's Facebook team has completely replaced an in-house interpreted language, moving to a strong and statically typed Haskell DSL called Haxl. Dozens of Facebook developers have become functional programmers, using the open-source Haxl framework to battle spam at scale. This talk will explain how Haskell shines in this context, bust a few myths about the language, and highlight lessons Rubyists and Haskellers could learn from each other.\n  video_provider: \"youtube\"\n  video_id: \"mLlVsX3p-oc\"\n\n- id: \"dan-draper-rubyconf-au-2016\"\n  title: \"Debugging Diversity\"\n  raw_title: \"RubyConf AU 2016: Debugging Diversity by Dan Draper & Catherine Jones\"\n  speakers:\n    - Dan Draper\n    - Catherine Jones\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Most of us who work in the tech space know that it is painfully lacking in diversity. But why is it the case? After all, the early pioneers of computer science were largely women and yet now only 6% of tech leaders are female. In Australia, the number of Aboriginal developers barely blips past 0%.\n\n    Debugging Diversity performs a root cause analysis on diversity in tech and explains how it can be fixed. How each and everyone of us plays a role. Come and hear how over 2 years of research has culminated in a provocative, yet inspiring presentation.\n  video_provider: \"youtube\"\n  video_id: \"ZAC2mU24bH8\"\n\n- id: \"sebastian-von-conrad-rubyconf-au-2016\"\n  title: \"Event Sourcing, or Why ActiveRecord Must Die\"\n  raw_title: \"RubyConf AU 2016: Event Sourcing, or Why ActiveRecord Must Die by Sebastian von Conrad\"\n  speakers:\n    - Sebastian von Conrad\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Much has been said about the dangers with ActiveRecord, but the advice is usually limited to avoiding callbacks or not building God models. We still use it because there hasn't been a viable alternative. It is not actually a trait unique to ActiveRecord that makes it dangerous, however--it's because it's an ORM, and all ORMs must die.\n\n    With Event Sourcing, we can build Ruby applications that are simple, scalable, extensible, and elegant without ActiveRecord or any other ORM anywhere in sight. We get a free time machine, and find out that Event Sourcing is a lot older than we might think.\n  video_provider: \"youtube\"\n  video_id: \"hiFqu1BTgsA\"\n\n- id: \"jon-rowe-rubyconf-au-2016\"\n  title: \"In-spec-tion\"\n  raw_title: \"RubyConf AU 2016: In-spec-tion by Jon Rowe\"\n  speakers:\n    - Jon Rowe\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Ever wondered what goes on inside RSpec? How the constituent parts of core mocks and expectations fit together? Or maybe you want to extend it to add a cool new feature.\n\n    Follow me on a whirlwind tour of the insides of RSpec, It’s syntax can often look magical on the outside but underneath it all it’s just Ruby.\n\n    We’ll cover how the constituent parts fit together, how RSpec uses itself to extend itself and how some of the core protocols work.\n  video_provider: \"youtube\"\n  video_id: \"-93B0tAVVbM\"\n\n- id: \"john-feminella-rubyconf-au-2016\"\n  title: \"Taking Apart Ruby's Object Model\"\n  raw_title: \"Taking Apart Ruby's Object Model\"\n  speakers:\n    - John Feminella\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"john-feminella-rubyconf-au-2016\"\n\n- id: \"elle-meredith-rubyconf-au-2016\"\n  title: \"Feedback Matters\"\n  raw_title: \"RubyConf AU 2016: Feedback Matters by Elle Meredith\"\n  speakers:\n    - Elle Meredith\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Feedback matters, whether positive or corrective. It's essential to creating a productive work environment. It shows attentiveness and signals appreciation for a job well done. It redirects undesirable behaviour to other productive alternatives.\n\n    So why are many of us so stingy with feedback? Do we try to avoid difficult conversations? Do we know how to give feedback effectively? Whatever the reasons are, we can learn when and how to comfortably offer feedback to others.\n\n    This talk will cover why feedback matters, what makes feedback effective, when and to give feedback, and much more.\n  video_provider: \"youtube\"\n  video_id: \"vpSv1wS49yA\"\n\n- id: \"arne-brasseur-rubyconf-au-2016\"\n  title: \"Burn Your Idiomatic Ruby\"\n  raw_title: \"RubyConf AU 2016: Burn Your Idiomatic Ruby by Arne Brasseur\"\n  speakers:\n    - Arne Brasseur\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Ruby makes programmers happy because of its elegant style and readable code. Rubyists like code that looks \"right\". Clever hacks and obscure use of syntax are frowned upon, and code linters and metrics are used to enforce a clean and idiomatic style.\n\n    But there's a danger in this attitude. Innovations may look foreign at first, and by discarding them offhand we may be throwing the baby out with the bathwater. On the flip side, libraries providing good looking interfaces may be smuggling complexity into your project that is hidden underneath the surface.\n  video_provider: \"youtube\"\n  video_id: \"7gcbaNlqdLE\"\n\n- id: \"dr-nic-williams-rubyconf-au-2016\"\n  title: \"Winning in Production\"\n  raw_title: \"RubyConf AU 2016: Winning in Production by Dr. Nic Williams\"\n  speakers:\n    - Dr. Nic Williams\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-11\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016:\n  video_provider: \"youtube\"\n  video_id: \"1S4NV6F3d3Q\"\n\n- id: \"katrina-owen-rubyconf-au-2016\"\n  title: \"One Undo\"\n  raw_title: \"RubyConf AU 2016: One Undo by Katrina Owen\"\n  speakers:\n    - Katrina Owen\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Refactoring sometimes devolves into an appalling mess. You're chasing a broken test suite, and every change just makes it worse. An even more insidious antipattern is the slow, perfectly controlled process culminating in dreadful design.\n\n    This talk presents an end-to-end refactoring that demonstrates simple strategies to avoid such misadventures.\n  video_provider: \"youtube\"\n  video_id: \"Uk-DMWVR1zc\"\n\n- id: \"allison-mcmillan-rubyconf-au-2016\"\n  title: \"Out of sight, out of mind? Helping teams thrive\"\n  raw_title: \"RubyConf AU 2016: Out of sight, out of mind? Helping teams thrive by Allison McMillan\"\n  speakers:\n    - Allison McMillan\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Out of sight, out of mind? Helping teams thrive when they’re permanently Out-Of-Office\n\n    “Besides not being as productive, what are the challenges of working remotely?” This and other questions are asked to distributed teams all the time. Presented by a remote manager and an employee with varying remote experiences in different companies, both successful and not, we’ll focus on real failures and teams that achieved success. Some remote teams don’t quite have it down, others wish their company understood them better. Even more folks want to work remotely but don’t know how to do it effectively. We’ll dive into each of these areas demonstrating failures and strategies that work.\n  video_provider: \"youtube\"\n  video_id: \"bGGj7JFzPns\"\n\n- id: \"paolo-nusco-perrotta-rubyconf-au-2016\"\n  title: \"Refinements - the Worst Feature You Ever Loved\"\n  raw_title: \"RubyConf AU 2016: Refinements - the Worst Feature You Ever Loved by Paolo Perrotta\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Refinements are cool. They are the biggest new language feature in Ruby 2. They help you avoid some of Ruby's most dangerous pitfalls. They make your code cleaner and safer.\n\n    Oh, and some people really hate them.\n\n    Are Refinements the best idea since blocks and modules, or a terrible mistake? Decide for yourself. I'll tell you the good, the bad and the ugly about refinements. At the end of this speech, you'll understand the trade-offs of this controversial feature, and know what all the fuss is about.\n  video_provider: \"youtube\"\n  video_id: \"XvlGOokgSi4\"\n\n- id: \"stella-cotton-rubyconf-au-2016\"\n  title: \"Site Availability is for Everybody\"\n  raw_title: \"RubyConf AU 2016: Site Availability is for Everybody by Stella Cotton\"\n  speakers:\n    - Stella Cotton\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Your phone rings in the middle of the night and the site is down- do you know what to do? Don’t let a crisis catch you off guard! Practice your skills with load testing.\n\n    This talk will cover common pitfalls when simulating load on your application, and key metrics you should look for when your availability is compromised. We’ll also look at how tools like ruby-prof and bullet can help unearth problem code in Ruby apps.\n  video_provider: \"youtube\"\n  video_id: \"TPD3qiWsEV8\"\n\n- id: \"tom-ridge-rubyconf-au-2016\"\n  title: \"Explicit Tests Tell a Better Tale\"\n  raw_title: \"RubyConf AU 2016: Explicit Tests Tell a Better Tale by Tom Ridge\"\n  speakers:\n    - Tom Ridge\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Red, Green, Refactor is a persistent mantra that is drilled into us from day one. As a developer new to Ruby, how do we know how to write the right kind of test? When should we refactor? What tricks and techniques can we use to improve our tests and recognise the feedback they give us to build well designed applications?\n\n    We’re going to take a look at how our tests give us feedback on our application. We’ll identify some testing smells, and how to determine when to make that refactoring and when not to.\n  video_provider: \"youtube\"\n  video_id: \"z5EctI4jATY\"\n\n- id: \"jess-rudder-rubyconf-au-2016\"\n  title: \"Diversity in Tech - It's About More than Just the Hiring Process\"\n  raw_title: \"RubyConf AU 2016: Diversity in Tech - It's About More than Just the Hiring Process by Jess Rudder\"\n  speakers:\n    - Jess Rudder\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Increasing diversity in tech seems as simple as hiring diverse programmers. However, statistics show that women and minorities leave tech at higher rates than the standard programmer. Learn what you can do to not only make your dev team an attractive option for diverse technical talent, but what you can do to make it a place that talent will stay for years to come.\n  video_provider: \"youtube\"\n  video_id: \"CgDLI0Ounhg\"\n\n- id: \"ernie-miller-rubyconf-au-2016\"\n  title: \"Humane Development - Empathy\"\n  raw_title: \"RubyConf AU 2016: Humane Development - Empathy by Ernie Miller\"\n  speakers:\n    - Ernie Miller\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016:\n  video_provider: \"youtube\"\n  video_id: \"yeBpknHjyGo\"\n\n- id: \"bianca-gibson-rubyconf-au-2016\"\n  title: \"Functional programming for rubyists\"\n  raw_title: \"RubyConf AU 2016: Functional programming for rubyists by Bianca Gibson\"\n  speakers:\n    - Bianca Gibson\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Rampant side effects. The shifting sands of mutable state beneath your feet. Mocks as far as the eye can see. Enter Functional Programming. Functional Programming helps you write clear, maintainable and testable code. This talk will cover the core principles of functional programming, how to apply them in ruby, the benefits they can offer, and how to introduce them to other developers.\n  video_provider: \"youtube\"\n  video_id: \"wOgeMk8PCfE\"\n\n- id: \"richard-huang-rubyconf-au-2016\"\n  title: \"Rails Performance Tips\"\n  raw_title: \"RubyConf AU 2016: Rails Performance Tips by Richard Huang\"\n  speakers:\n    - Richard Huang\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Many developers are complaining that rails is slow, but most teams are not tuning performance at all or not properly, in this talk, you will learn how to monitor performance, how to find out performance issue and how to fix, I will also show you some tips that can dramatically improve your rails apps' performance.\n  video_provider: \"youtube\"\n  video_id: \"2xu8MDNj0Dk\"\n\n- id: \"andr-arko-rubyconf-au-2016\"\n  title: \"Security is hard, but we can't go shopping\"\n  raw_title: \"RubyConf AU 2016: Security is hard, but we can't go shopping by Andre Arko\"\n  speakers:\n    - André Arko\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-01-31\"\n  description: |-\n    RubyConf AU 2016: Security is really important, and a lot of rubyists are unfamiliar with how it works, why it's important, how to explain it to bosses and managers, and most importantly, how to handle security vulnerabilities in code they use (or code they wrote). This talk is about why security is important, even though Matz is nice. It's also about what to do when vulnerabilities show up, since they always will.\n  video_provider: \"youtube\"\n  video_id: \"w_Lwd3sGSbc\"\n\n- id: \"adam-cuppy-rubyconf-au-2016\"\n  title: \"What If Shakespeare Wrote Ruby?\"\n  raw_title: \"RubyConf AU 2016: What If Shakespeare Wrote Ruby? by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016: Did you know that Shakespeare wrote almost no direction into his plays? No fight direction. No staging. No notes to the songs. Of the 1700 words he created, there was no official dictionary. That’s right the author of some of the greatest literary works in history, which were filled with situational complexity, fight sequences and music, include NO documentation! How did he do it?\n\n    In this talk, we're going \"thee and thou.\" I'm going to give you a crash course in how: Shakespeare writes software.\n  video_provider: \"youtube\"\n  video_id: \"nEHLhiOLB0A\"\n\n- id: \"senator-scott-ludlam-rubyconf-au-2016\"\n  title: \"Ruby off the Rails: How the government broke the internet\"\n  raw_title: \"RubyConf AU 2016: Ruby off the Rails: How the government broke the internet by Senator Scott Ludlam\"\n  speakers:\n    - Senator Scott Ludlam\n  event_name: \"RubyConf AU 2016\"\n  date: \"2016-02-12\"\n  published_at: \"2017-05-19\"\n  description: |-\n    RubyConf AU 2016:\n  video_provider: \"youtube\"\n  video_id: \"XwQyQTT_i0Q\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2017/event.yml",
    "content": "---\nid: \"PL9_jjLrTYxc3hxsmj3AnPFf3RD4f3zfUl\"\ntitle: \"RubyConf AU 2017\"\nkind: \"conference\"\nlocation: \"Melbourne, Australia\"\ndescription: |-\n  February 9-10, Melbourne, Australia\npublished_at: \"2017-02-22\"\nstart_date: \"2017-02-09\"\nend_date: \"2017-02-10\"\nchannel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nyear: 2017\ncoordinates:\n  latitude: -37.8136276\n  longitude: 144.9630576\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2017/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 1\"\n    date: \"2017-02-08\"\n    grid:\n      - start_time: \"19:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Opening Party\n\n  - name: \"Day 2\"\n    date: \"2017-02-09\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:20\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:20\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:40\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:40\"\n        end_time: \"12:25\"\n        slots: 1\n\n      - start_time: \"12:25\"\n        end_time: \"13:00\"\n        slots: 1\n\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:25\"\n        slots: 1\n\n      - start_time: \"16:25\"\n        end_time: \"17:10\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Happy Hour\n\n  - name: \"Day 3\"\n    date: \"2017-02-10\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:20\"\n        slots: 1\n\n      - start_time: \"10:20\"\n        end_time: \"11:10\"\n        slots: 2\n\n      - start_time: \"11:10\"\n        end_time: \"11:40\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:40\"\n        end_time: \"12:05\"\n        slots: 2\n\n      - start_time: \"12:05\"\n        end_time: \"12:40\"\n        slots: 2\n\n      - start_time: \"12:40\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:45\"\n        slots: 2\n\n      - start_time: \"14:45\"\n        end_time: \"15:10\"\n        slots: 2\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 2\n\n      - start_time: \"15:40\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:35\"\n        slots: 2\n\n      - start_time: \"16:35\"\n        end_time: \"17:15\"\n        slots: 1\n\n      - start_time: \"19:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Closing Party\n\n  - name: \"Day Four\"\n    date: \"2017-02-11\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"15:00\"\n        slots: 5\n        items:\n          - Walking Tour\n          - Healesville Wildlife Sanctuary\n          - Craft Beer Tour\n          - Hack Day\n          - Beach Bike Ride\n\ntracks:\n  - name: \"Deep Dive\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2017/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby\"\n      level: 1\n      sponsors:\n        - name: \"REA Group\"\n          website: \"https://www.rea-group.com/\"\n          slug: \"REAGroup\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/rea-new.svg\"\n\n        - name: \"Envato\"\n          website: \"https://envato.com/\"\n          slug: \"Envato\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/2013-envato.svg\"\n\n    - name: \"Emerald\"\n      level: 2\n      sponsors:\n        - name: \"Culture Amp\"\n          website: \"https://www.cultureamp.com\"\n          slug: \"CultureAmp\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/culture-amp.png\"\n\n        - name: \"Lookahead Search\"\n          website: \"https://www.lookahead.com.au/\"\n          slug: \"LookaheadSearch\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/lookahead.svg\"\n\n    - name: \"Sapphire\"\n      level: 3\n      sponsors:\n        - name: \"Hired\"\n          website: \"https://hired.com.au/\"\n          slug: \"Hired\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/hired.png\"\n\n    - name: \"Opal\"\n      level: 4\n      sponsors:\n        - name: \"OneFlare\"\n          website: \"https://www.oneflare.com.au/\"\n          slug: \"OneFlare\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/oneflare.svg\"\n\n        - name: \"AirTasker\"\n          website: \"https://www.airtasker.com/\"\n          slug: \"AirTasker\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/airtasker.svg\"\n\n        - name: \"Cogent\"\n          website: \"https://www.cogent.co\"\n          slug: \"Cogent\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/cogent.png\"\n\n    - name: \"RubyConf Assist\"\n      level: 5\n      sponsors:\n        - name: \"GitHub\"\n          website: \"https://github.com/\"\n          slug: \"GitHub\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/github-2.svg\"\n\n        - name: \"reInteractive\"\n          website: \"https://reinteractive.net/\"\n          slug: \"reInteractive\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/reinteractive.svg\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2017/videos.yml",
    "content": "---\n# Website: https://rubyconf.org.au/2017\n# Schedule: https://rubyconf.org.au/2017/schedule\n\n- id: \"tim-riley-rubyconf-au-2017\"\n  title: \"Reinvesting in Ruby\"\n  raw_title: \"RubyConf AU 2017 -  Reinvesting in Ruby, by Tim Riley\"\n  speakers:\n    - Tim Riley\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    As our community matures, and technology evolves around us, how can we ensure Ruby remains vital?\n\n    Speaker: Tim Riley\n  video_provider: \"youtube\"\n  video_id: \"V8Sdg25eKlM\"\n\n- id: \"shana-moore-rubyconf-au-2017\"\n  title: \"So You Want To Become a Software Engineer?\"\n  raw_title: \"RubyConf AU 2017 -  So you want to become a software engineer?, by Shana Moore\"\n  speakers:\n    - Shana Moore\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    This talk will be geared towards career changers, juniors, and those interested in becoming software engineers. It's a personal testimony of how I was able to change careers and become a software engineer without a technical degree.\n  video_provider: \"youtube\"\n  video_id: \"v8kAD9XTFwU\"\n\n- id: \"hiro-asari-rubyconf-au-2017\"\n  title: \"Ruby, HTTP/2 and You\"\n  raw_title: \"RubyConf AU 2017 - Ruby, HTTP/2 and You, by Hiro Asari\"\n  speakers:\n    - Hiro Asari\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    HTTP/2 is here.\n\n    The first major revision since 1997 to Hypertext Transfer Protocol on which so much of the modern information transfer relies, HTTP/2 could have an enormous impact on the way we write applications.\n  video_provider: \"youtube\"\n  video_id: \"_KFxWyJrzso\"\n\n- id: \"colby-swandale-rubyconf-au-2017\"\n  title: \"Writing a Gameboy Emulator in Ruby\"\n  raw_title: \"RubyConf AU 2017 - Writing a Gameboy emulator in Ruby, by Colby Swandale\"\n  speakers:\n    - Colby Swandale\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    Released in 1989 the Gameboy was the first handheld console of the Gameboy series to be released by Nintendo. It featured games such as Pokemon Red & Blue, Tetris, Super Mario Land and went on to sell 64 million units worldwide.\n\n    My talk will be discussing what components make up a Gameboy, such as the CPU, RAM, Graphics and Game Cartridge. How each component works individually and how they work together to let trainers catch em all. Then how to replicate the behavior of the Gameboy in code to eventually make an emulator.\n  video_provider: \"youtube\"\n  video_id: \"WbO2FEpNPvQ\"\n\n- id: \"pat-allan-rubyconf-au-2017\"\n  title: \"Open Source: Power and the Passion\"\n  raw_title: \"RubyConf AU 2017 - Open Source: Power and the Passion, by Pat Allan\"\n  speakers:\n    - Pat Allan\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    Especially as Rubyists, Open Source is one of the foundation pillars of our industry. You probably use the power of open source software every day: in the code you write, the tools you build with, the servers you deploy to.\n\n    But perhaps it’s not quite the stable foundation we were hoping for? This talk will cover the various strengths and weaknesses of both open source and our reliance upon it, so we can trade in our assumptions for a greater awareness of the issues. Then together, we can find a path towards a more sustainable open source ecosystem.\n  video_provider: \"youtube\"\n  video_id: \"uIqcGzQO01k\"\n\n- id: \"julian-doherty-rubyconf-au-2017\"\n  title: \"Functional Programming For The Anxious Developer\"\n  raw_title: \"RubyConf AU 2017 - Functional Programming For The Anxious Developer, by Julian Doherty\"\n  speakers:\n    - Julian Doherty\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    Programming involves dealing with an overwhelming amount of complexity. The human brain can only deal with so much information to process before anxiety kicks in and your ability to proceed suffers. Functional programming provides tools to manage the combinatorial explosion of state and logic. Here we'll cover some practical uses of functional programming techniques in Ruby that can be directly applied to your everyday work.\n  video_provider: \"youtube\"\n  video_id: \"3b1YhdP2fis\"\n\n- id: \"marcos-matos-rubyconf-au-2017\"\n  title: \"Actors in Ruby! Why Let Elixir Have All The Fun?\"\n  raw_title: \"RubyConf AU 2017 - Actors in Ruby! Why let Elixir have all the fun?, by Marcos Matos\"\n  speakers:\n    - Marcos Matos\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    We all want to have performant concurrent code, but threads are such a pain. Who wants to deal with race conditions in their code?! In this talk we show a better way of doing concurrency, the Actor model. No, that’s not just for Erlang or Elixir, we can have it in Ruby too.\n  video_provider: \"youtube\"\n  video_id: \"wveC2bbFYgA\"\n\n- id: \"katie-mclaughlin-rubyconf-au-2017\"\n  title: \"The Power ⚡ and Responsibility 😓 of Unicode Adoption ✨\"\n  raw_title: \"RubyConf AU 2017 - The Power ⚡️ and Responsibility 😓 of Unicode Adoption ✨, by Katie McLaughlin\"\n  speakers:\n    - Katie McLaughlin\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n  video_provider: \"youtube\"\n  video_id: \"Acf14xTjnFA\"\n\n- id: \"piotr-solnica-rubyconf-au-2017\"\n  title: \"Persistence Pays Off: A New Look At rom-rb\"\n  raw_title: \"RubyConf AU 2017 - Persistence pays off: a new look at rom-rb, by Piotr Solnica\"\n  speakers:\n    - Piotr Solnica\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n  video_provider: \"youtube\"\n  video_id: \"9TBvWRgll64\"\n\n- id: \"aaron-patterson-rubyconf-au-2017\"\n  title: \"Defragging Ruby\"\n  raw_title: \"RubyConf AU 2017 - Defragging Ruby by Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"nAEt36XNtAE\"\n\n- id: \"barrett-clark-rubyconf-au-2017\"\n  title: \"Simple and Awesome Database Tricks\"\n  raw_title: \"RubyConf AU 2017 - Simple and Awesome Database Tricks, By Barrett Clark\"\n  speakers:\n    - Barrett Clark\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    This talk discusses a collection of things that have been helpful through the years. Some are supported by ActiveRecord, and some fall outside the scope of what ActiveRecord provides. You'll learn things like awesome datatypes, proactive and reactive performance testing, time-series data, backup and restore strategies, PostGIS, scripting with Postgres, and more!\n  video_provider: \"youtube\"\n  video_id: \"N08NHsyaoKM\"\n\n- id: \"philip-arndt-rubyconf-au-2017\"\n  title: \"Taking Refinery off the Rails\"\n  raw_title: \"RubyConf AU 2017 - Taking Refinery off the Rails, by Philip Arndt & Samuel Seay\"\n  speakers:\n    - Philip Arndt\n    - Samuel Seay\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    We're seeing more evidence that the future of Ruby may not be tied to Rails as newer micro-frameworks and purpose built libraries are released to mass appeal.\n\n    In this talk we'll explore what happens when we take the most popular CMS for Rails, \"Refinery CMS\", and rebuild it with Hanami and dry-rb, plus reliable Frontend frameworks and libraries rather than a mess of Rails, jQuery, and organic CSS.\n\n    We'll provide you with both gems and solid advice to allow you to refactor your own applications to take advantage of the solid and agile foundation provided by Hanami and dry-rb.\n  video_provider: \"youtube\"\n  video_id: \"aVxJ0GyD3vw\"\n  track: \"Deep Dive\"\n\n- id: \"ram-ramakrishnan-rubyconf-au-2017\"\n  title: \"VR Backend Rails vs. Serverless: Froth or Future?\"\n  raw_title: \"RubyConf AU 2017 - VR backend rails vs serverless: froth or future? Ram Ramakrishnan & Janet Brown\"\n  speakers:\n    - Ram Ramakrishnan\n    - Janet Brown\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    Serverless (via AWS Lambda), the new hotness, was definitely something we wanted to explore when developing the backend for our new Virtual Reality app. TLDR - despite expectations to the contrary we came back to Rails, specifically Rails 5 API mode. We'll walk you through our journey, what the different considerations were, what the different strengths of each platform are and how we reached our decision. We think it's essential that as Rails developers we have an understanding of Serverless, both as a replacement and as an augmentation to our skill-set and development environment.\n  video_provider: \"youtube\"\n  video_id: \"E0wPImDxSt8\"\n\n- id: \"andr-arko-rubyconf-au-2017\"\n  title: \"How Does Bundler Work, Anyway?\"\n  raw_title: \"RubyConf AU 2017 - How does Bundler work anyway?, by Andre Arko\"\n  speakers:\n    - André Arko\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    We all use Bundler at some point, and most of us use it every day. But what does it do, exactly? Why do we have to use bundle exec? What's the point of checking in the Gemfile.lock? Why can't we just gem install the gems we need? Join me for a walk through the reasons that Bundler exists, and a guide to what actually happens when you use it. Finally, we'll cover some Bundler \"pro tips\" that can improve your workflow when developing on multiple applications at once.\n  video_provider: \"youtube\"\n  video_id: \"j2V-A8vvLP0\"\n  track: \"Deep Dive\"\n\n- id: \"kinsey-ann-durham-rubyconf-au-2017\"\n  title: \"Impactful Refactors: Refactoring for Readability\"\n  raw_title: \"RubyConf AU 2017 - Impactful Refactors: Refactoring for Readability, by Kinsey Ann Durham\"\n  speakers:\n    - Kinsey Ann Durham\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    We have no problems justifying a refactoring effort when it improves performance or eliminates a code smell. What if I told you there's a way your refactoring could be even more impactful? One of the most costly and time-consuming things we do is on boarding. It takes an incredible amount of effort to bring a developer up to speed on a new codebase. In this talk, we’ll see real-world readability refactors, discuss how you can apply these techniques for the benefit of your current (and future) team members, and how we can continue to program with empathy and diversity in mind.\n  video_provider: \"youtube\"\n  video_id: \"CHaKY8tTY6E\"\n\n- id: \"valerie-woolard-rubyconf-au-2017\"\n  title: \"Finding Translations, Localisation and Internationalisation\"\n  raw_title: \"RubyConf AU 2017 - Finding translations, localisation and internationalisation, by Valerie Woolard\"\n  speakers:\n    - Valerie Woolard\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    This talk will discuss localization and internationalization for Rails applications. We’ll discuss available tools as well as best practices for building apps for localization. We’ll also talk about the more human and subjective struggles of translating ideas and concepts for new audiences.\n  video_provider: \"youtube\"\n  video_id: \"mN6lynGNzxs\"\n  track: \"Deep Dive\"\n\n- id: \"stella-cotton-rubyconf-au-2017\"\n  title: \"The Little Server That Could\"\n  raw_title: \"RubyConf AU 2017 - The little server that could, by Stella Cotton\"\n  speakers:\n    - Stella Cotton\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    Have you ever wondered what dark magic happens when you start up your Ruby server? Let’s explore the mysteries of the web universe by writing a tiny web server in Ruby! Writing a web server lets you dig deeper into the Ruby Standard Library and the Rack interface. You’ll get friendlier with I/O, signal trapping, file handles, and threading. You’ll also explore dangers first hand that can be lurking inside your production code- like blocking web requests and shared state with concurrency.\n  video_provider: \"youtube\"\n  video_id: \"Wh88DZyTiK8\"\n\n- id: \"louis-simoneau-rubyconf-au-2017\"\n  title: \"Functional in the Front, Rails in the Back: Give Your App An Elm Mullet\"\n  raw_title: \"RubyConf AU 2017 - Functional in the front: rails in the back... by Louis Simoneau & Rahul Trikha\"\n  speakers:\n    - Louis Simoneau\n    - Rahul Trikha\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    You want to keep up with new and exciting technologies, but rewriting your monolith in the language du jour is too daunting a task, and you're not sure a microservice split is right for you. Why not experiment with a purely functional, powerfully typed language in your existing Rails app? Elm is a new language that compiles to JavaScript and has lots of great mind-bending features. In this talk we'll look at the basics of Elm and how you can integrate it into an existing Rails app, even alongside your existing JavaScript code.\n  video_provider: \"youtube\"\n  video_id: \"Bd6DTg1uNe0\"\n  track: \"Deep Dive\"\n\n- id: \"elle-meredith-rubyconf-au-2017\"\n  title: \"Self Learning is a Marathon not a Sprint\"\n  raw_title: \"RubyConf AU 2017 - Self learning is a marathon not a sprint, by Elle Meredith\"\n  speakers:\n    - Elle Meredith\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    The web industry never stops evolving and changing. We have to keep on our toes and learn the new hot thing. Whether you have limited time because of family, or just started on your way, self-learning is challenging, difficult, and sometimes even overwhelming. This talk is my list of tips, techniques, and strategies I use when I self-learn. Hopefully, you can find one or two things here to keep you motivated, and on your way.\n  video_provider: \"youtube\"\n  video_id: \"bU9QprllR3s\"\n\n- id: \"andy-nicholson-rubyconf-au-2017\"\n  title: \"You And Your Type[s] Aren't Welcome Here\"\n  raw_title: \"RubyConf AU 2017 - You and your type[s] aren't welcome here, by Andy Nicholson\"\n  speakers:\n    - Andy Nicholson\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    Whenever the stereotypical Ruby developer hears the words \"statically-typed\", they have one of two responses:\n\n    they have flash-backs to their C++/Java days they prepare their memorized Alan Kay / Kent Beck quotes for battle. Now that stronger typing is coming to Ruby, maybe we need to calm down a little.\n\n    This talk is not designed to persuade anyone to drop our beloved Ruby, but maybe we can learn some lessons from our stronger-typed friends to bring even greater happiness than before.\n  video_provider: \"youtube\"\n  video_id: \"gzXjqfPydFo\"\n  track: \"Deep Dive\"\n\n- id: \"alex-coles-rubyconf-au-2017\"\n  title: \"Ruby: How a Language Affects its People\"\n  raw_title: \"RubyConf AU 2017 - Ruby: how a language affects its people, by Alex Coles\"\n  speakers:\n    - Alex Coles\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    In human-to-human languages the same core ideas get shaped differently depending on the language in which they are spoken. What if every computational language engenders a set (or a subset) of culture and values, and as a consequence attracts and shapes a corresponding community? What are the values that entered into the language by way of its core committers and what are the values we identify with as a community. How can making these values explicit help us foster a better community?\n  video_provider: \"youtube\"\n  video_id: \"ybrsMpLA6u8\"\n\n- id: \"prathmesh-ranaut-rubyconf-au-2017\"\n  title: \"Performance Optimization in Ruby\"\n  raw_title: \"RubyConf AU 2017 - Performance Optimization in Ruby, by Prathmesh Ranaut\"\n  speakers:\n    - Prathmesh Ranaut\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    The talk will focus on techniques I used to increase the performance of a popular concurrency framework, Celluloid, by upto 3 times. I'll discuss the areas where the Ruby application takes a performance hit and provide solutions for them.\n  video_provider: \"youtube\"\n  video_id: \"HHRTSpFGCGg\"\n  track: \"Deep Dive\"\n\n- id: \"kylie-stradley-rubyconf-au-2017\"\n  title: \"A Common Taxonomy of Bugs and How to Catch Them\"\n  raw_title: \"RubyConf AU 2017 - A Common Taxonomy of Bugs and How to Catch Them, by Kylie Stradley\"\n  speakers:\n    - Kylie Stradley\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    Catching software bugs is a mysterious magic, unknowable by science, and untouchable by process. Debugging skills are instinctual and come only from years of experience.\n\n    False! Programming bugs, like real bugs, can be organized into a deterministic taxonomy. At its base, consistent and successful debugging is pattern matching. Classifying bugs by their attributes and behaviors makes the seemingly impossible possible—codifying the elusive “programmer’s instincts” into a logical debugging process.\n  video_provider: \"youtube\"\n  video_id: \"0J5OWi65rTI\"\n\n- id: \"kate-deutscher-rubyconf-au-2017\"\n  title: \"Automation Run Rampant\"\n  raw_title: \"RubyConf AU 2017 - Automation Run Rampant, by Kate Deutscher\"\n  speakers:\n    - Kate Deutscher\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-07-06\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    With the rise of micro services and DevOps culture, engineers are finding themselves responsible for the all facets of a rapidly growing number of systems. Luckily for you, many of the processes managing these systems can be automated! But where do you begin? How do you know when something is ripe for automation? Is there such as thing as bad automation? And how do you take the first step?\n  video_provider: \"youtube\"\n  video_id: \"vK6qbMnl1xQ\"\n  track: \"Deep Dive\"\n\n- id: \"aja-hammerly-rubyconf-au-2017\"\n  title: \"Datacenter Fires and Other 'Minor' Disasters\"\n  raw_title: \"RubyConf AU 2017 - Datacenter Fires and Other 'Minor' Disasters, by Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RubyConf AU 2017\"\n  date: \"2017-02-09\"\n  published_at: \"2017-03-03\"\n  description: |-\n    http://www.rubyconf.org.au\n\n    Most of us have a “that day I broke the internet” story. Some are amusing and some are disastrous but all of these stories change how we operate going forward. I’ll share the amusing stories behind why I always take a database backup, why feature flags are important, the importance of automation, and how having a team with varied backgrounds can save the day. Along the way I’ll talk about a data center fire, deleting a production database, and accidentally setting up a DDOS attack against our own site. I hope that by learning from my mistakes you won’t have to make them yourself.\n  video_provider: \"youtube\"\n  video_id: \"WoTemqfZiHE\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2018/event.yml",
    "content": "---\nid: \"PL9_jjLrTYxc2Xi0rotTPuPRQAoJnDU-my\"\ntitle: \"RubyConf AU 2018\"\nkind: \"conference\"\nlocation: \"Sydney, Australia\"\ndescription: \"\"\npublished_at: \"2018-07-10\"\nstart_date: \"2018-03-08\"\nend_date: \"2018-03-09\"\nchannel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nyear: 2018\ncoordinates:\n  latitude: -33.8727409\n  longitude: 151.2057136\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2018/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 1\"\n    date: \"2018-03-07\"\n    grid:\n      - start_time: \"19:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Opening Party\n\n  - name: \"Day 2\"\n    date: \"2018-03-08\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:30\"\n        end_time: \"09:50\"\n        slots: 1\n        items:\n          - Welcome to Country\n\n      - start_time: \"09:50\"\n        end_time: \"10:35\"\n        slots: 1\n\n      - start_time: \"10:35\"\n        end_time: \"11:05\"\n        slots: 1\n        items:\n          - Morning tea\n\n      - start_time: \"11:05\"\n        end_time: \"11:40\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:15\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"13:05\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:05\"\n        end_time: \"13:40\"\n        slots: 1\n\n      - start_time: \"13:40\"\n        end_time: \"14:20\"\n        slots: 1\n\n      - start_time: \"14:20\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Afternoon tea\n\n      - start_time: \"15:30\"\n        end_time: \"16:15\"\n        slots: 1\n\n      - start_time: \"16:15\"\n        end_time: \"17:00\"\n        slots: 1\n\n  - name: \"Day 3\"\n    date: \"2018-03-09\"\n    grid:\n      - start_time: \"07:00\"\n        end_time: \"08:30\"\n        slots: 1\n        items:\n          - Breakfast\n\n      - start_time: \"08:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:30\"\n        end_time: \"10:05\"\n        slots: 1\n\n      - start_time: \"10:05\"\n        end_time: \"10:35\"\n        slots: 1\n\n      - start_time: \"10:35\"\n        end_time: \"11:05\"\n        slots: 1\n        items:\n          - Morning tea\n\n      - start_time: \"11:05\"\n        end_time: \"11:40\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:15\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"13:05\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:05\"\n        end_time: \"13:40\"\n        slots: 1\n\n      - start_time: \"13:40\"\n        end_time: \"14:20\"\n        slots: 1\n\n      - start_time: \"14:20\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Afternoon tea\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"18:30\"\n        end_time: \"22:30\"\n        slots: 1\n        items:\n          - Closing Party\n\n  - name: \"Day Four\"\n    date: \"2018-03-10\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"16:00\"\n        slots: 2\n        items:\n          - Taronga Zoo\n          - Hack Day\n\ntracks:\n  - name: \"Deep Dive\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2018/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby\"\n      level: 1\n      sponsors:\n        - name: \"Envato\"\n          website: \"https://envato.com/\"\n          slug: \"Envato\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/envato.png\"\n\n    - name: \"Emerald\"\n      level: 2\n      sponsors:\n        - name: \"Culture Amp\"\n          website: \"https://www.cultureamp.com\"\n          slug: \"CultureAmp\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/culture-amp.png\"\n\n        - name: \"Lookahead Search\"\n          website: \"https://www.lookahead.com.au/\"\n          slug: \"LookaheadSearch\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/lookahead.png\"\n\n    - name: \"Community\"\n      level: 3\n      sponsors:\n        - name: \"reInteractive\"\n          website: \"https://reinteractive.com/\"\n          slug: \"reInteractive\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/reinteractive.png\"\n\n    - name: \"Opal\"\n      level: 4\n      sponsors:\n        - name: \"OneFlare\"\n          website: \"https://www.oneflare.com.au/\"\n          slug: \"OneFlare\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/oneflare.png\"\n\n    - name: \"Amber\"\n      level: 5\n      sponsors:\n        - name: \"Shippit\"\n          website: \"https://www.shippit.com/\"\n          slug: \"Shippit\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/shippit.png\"\n\n    - name: \"Conference\"\n      level: 6\n      sponsors:\n        - name: \"Twilio\"\n          website: \"https://www.twilio.com/\"\n          slug: \"Twilio\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/twilio.png\"\n\n    - name: \"Speakers\"\n      level: 7\n      sponsors:\n        - name: \"The Conversation\"\n          website: \"https://theconversation.com/\"\n          slug: \"TheConversation\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/the-conversation.png\"\n\n        - name: \"Netflix\"\n          website: \"https://www.netflix.com/\"\n          slug: \"Netflix\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/netflix.png\"\n\n        - name: \"Disco\"\n          website: \"https://discolabs.com/\"\n          slug: \"Disco\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/discolabs.png\"\n\n        - name: \"Heroku\"\n          website: \"https://heroku.com/\"\n          slug: \"Heroku\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/heroku.png\"\n\n        - name: \"REA Group\"\n          website: \"https://www.rea-group.com/\"\n          slug: \"REAGroup\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/rea-group.png\"\n\n        - name: \"Up\"\n          website: \"https://up.com.au/\"\n          slug: \"Up\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/up.png\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2018/videos.yml",
    "content": "---\n# Website: https://rubyconf.org.au/2018\n# Schedule: https://rubyconf.org.au/2018/schedule\n\n- id: \"sandi-metz-rubyconf-au-2018\"\n  title: \"You Are Insufficiently Persuasive\"\n  raw_title: \"Sandi Metz - You Are Insufficiently Persuasive\"\n  speakers:\n    - Sandi Metz\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-07-20\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"Y3k7tHll3RY\"\n\n- id: \"paolo-nusco-perrotta-part-1-rubyconf-au-2018\"\n  title: \"Machine Learning Explained to Humans (Part 1)\"\n  raw_title: \"Paolo Perotta - Machine Learning Explained to Humans (Part 1)\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-09-03\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"zbxtlQaJZ7M\"\n\n- id: \"katie-mclaughlin-rubyconf-au-2018\"\n  title: \"JavaScript is Awe-ful\"\n  raw_title: \"JavaScript is Awe-ful by Katie McLaughlin\"\n  speakers:\n    - Katie McLaughlin\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"6FS1Hy8jhfQ\"\n  published_at: \"2018-09-16\"\n\n- id: \"andy-nicholson-rubyconf-au-2018\"\n  title: \"Consider Crystal\"\n  raw_title: \"Andy Nicholson - Consider Crystal\"\n  speakers:\n    - Andy Nicholson\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-09-17\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"XakoiU2mw3c\"\n\n- id: \"michael-morris-rubyconf-au-2018\"\n  title: \"High Performance Mario Kart On Ruby\"\n  raw_title: \"Michael Morris - High Performance Mario Kart On Ruby\"\n  speakers:\n    - Michael Morris\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-09-17\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"LVRcHzOgsRY\"\n\n- id: \"eleanor-kiefel-haggerty-rubyconf-au-2018\"\n  title: \"Here's to history: programming through archaeology\"\n  raw_title: \"Eleanor Kiefel Haggerty - Here's to history: programming through archaeology\"\n  speakers:\n    - Eleanor Kiefel Haggerty\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-09-03\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"MEG3HyVDgjU\"\n\n- id: \"ken-scrambler-rubyconf-au-2018\"\n  title: \"A Human Approach to Functional Programming\"\n  raw_title: \"A Human Approach to Functional Programming by Ken Scrambler\"\n  speakers:\n    - Ken Scrambler\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-09-17\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"JWM4J2TLGNQ\"\n\n- id: \"ryan-bigg-rubyconf-au-2018\"\n  title: \"Hiring Juniors\"\n  raw_title: \"Ryan Bigg - Hiring Juniors\"\n  speakers:\n    - Ryan Bigg\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-07-20\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"aD6dci9rLXM\"\n\n- id: \"lauren-tan-rubyconf-au-2018\"\n  title: \"Building the World's Largest Studio at Netflix\"\n  raw_title: \"Lauren Tan - Building the World's Largest Studio at Netflix\"\n  speakers:\n    - Lauren Tan\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-12-20\"\n  description: |-\n    Download slides from: https://github.com/thetron/ruby-conf-au-slides/raw/master/lauren-tan-netflix-rubyconf-2018.pdf\n\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"5_Xj7okmauc\"\n  slides_url: \"https://github.com/thetron/ruby-conf-au-slides/raw/master/lauren-tan-netflix-rubyconf-2018.pdf\"\n\n- id: \"amy-unger-rubyconf-au-2018\"\n  title: \"Knobs, Levers and Buttons: tools for operating your application at scale\"\n  raw_title: \"Amy Unger - Knobs, Levers and Buttons: tools for operating your application at scale\"\n  speakers:\n    - Amy Unger\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-12-20\"\n  description: |-\n    Download slides from: https://github.com/thetron/ruby-conf-au-slides/raw/master/amy-unger-heroku-rubyconf-2018.pdf\n\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"Bdck0TpHdGc\"\n  slides_url: \"https://github.com/thetron/ruby-conf-au-slides/raw/master/amy-unger-heroku-rubyconf-2018.pdf\"\n\n- id: \"danielle-adams-rubyconf-au-2018\"\n  title: \"Outside of the Web Box: Using Ruby for Other Protocols\"\n  raw_title: \"Danielle Adams - Outside of the Web Box: Using Ruby for Other Protocols\"\n  speakers:\n    - Danielle Adams\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-09-17\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"ZvyaC3SK-nA\"\n\n- id: \"tom-gamon-rubyconf-au-2018\"\n  title: \"Dyslexia and Developers\"\n  raw_title: \"Tom Gamon - Dyslexia and Developers\"\n  speakers:\n    - Tom Gamon\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-11-20\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"JZ03E0FUj1M\"\n\n- id: \"paolo-nusco-perrotta-part-2-rubyconf-au-2018\"\n  title: \"Machine Learning Explained to Humans Part 2\"\n  raw_title: \"Paolo Perotta - Machine Learning Explained to Humans Part 2\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-11-20\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"cn8bfOxR21E\"\n\n- id: \"zach-holman-rubyconf-au-2018\"\n  title: \"UTC is Enough for Everyone, Right?\"\n  raw_title: \"Zach Holman - UTC is Enough for Everyone, Right?\"\n  speakers:\n    - Zach Holman\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-12-04\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"ibJE_T4w3Bo\"\n\n- id: \"alaina-kafkes-rubyconf-au-2018\"\n  title: \"Tackling Technical Writing\"\n  raw_title: \"Alaina Kafkes - Tackling Technical Writing\"\n  speakers:\n    - Alaina Kafkes\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-12-03\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"brewx-lO3ak\"\n\n- id: \"jessica-rudder-rubyconf-au-2018\"\n  title: \"The Good Bad Bug: Fail Your Way to Better Code\"\n  raw_title: \"Jessica Rudder - The Good Bad Bug: Fail Your Way to Better Code\"\n  speakers:\n    - Jessica Rudder\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-11-21\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"4JEZU8-IHs8\"\n\n- id: \"stella-cotton-rubyconf-au-2018\"\n  title: \"Debugging Your Services with Distributed Tracing\"\n  raw_title: \"Stella Cotton - Debugging Your Services with Distributed Tracing\"\n  speakers:\n    - Stella Cotton\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-11-21\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"MYej9nMux-E\"\n\n- id: \"merrin-macleod-rubyconf-au-2018\"\n  title: \"Politics? In My Technology?\"\n  raw_title: \"Merrin Macleod - Politics? In My Technology?\"\n  speakers:\n    - Merrin Macleod\n  event_name: \"RubyConf AU 2018\"\n  date: \"2018-03-08\"\n  published_at: \"2018-11-20\"\n  description: |-\n    RubyConf AU 2018 | Sydney | Australia\n    March 8th & 9th, 2018\n\n    Organisers: Melissa Kaulfuss (@melissakaulfuss), Nicholas Bruning (@thetron), Sharon Vaughan (@Sharon_AV) & Nadia Vu (@nadiavu_)\n    MCs: Melissa Kaulfuss & Nicholas Bruning\n\n    Sponsored by: Envato, Culture Amp, Lookahead, Reinteractive, Oneflare, Shippit, Twilio, The Conversation, Netflix, Disco, Heroku, REA Group\n  video_provider: \"youtube\"\n  video_id: \"7NxkCRd4Z1M\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2019/event.yml",
    "content": "---\nid: \"PL9_jjLrTYxc3dTbvb8fIuzDFGTCaEdO3a\"\ntitle: \"RubyConf AU 2019\"\nkind: \"conference\"\nlocation: \"Melbourne, Australia\"\ndescription: |-\n  Our yearly gathering where we share knowledge about the Ruby programming language, and celebrate the Australian and broader Ruby community. 7th-9th February 2019, The Forum, Melbourne\npublished_at: \"2019-02-06\"\nstart_date: \"2019-02-07\"\nend_date: \"2019-02-09\"\nchannel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nyear: 2019\ncoordinates:\n  latitude: -37.8136276\n  longitude: 144.9630576\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2019/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Pat Allan\n    - Toby Nieboer\n    - Caitlin Donaldson\n    - Sharon Vaughan\n    - Samuel Cochran\n    - Phil Nash\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2019/schedule.yml",
    "content": "---\ndays:\n  - name: \"Day 1\"\n    date: \"2019-02-06\"\n    grid:\n      - start_time: \"19:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Opening Party\n\n  - name: \"Day 2\"\n    date: \"2019-02-07\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:30\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Welcome and Opening Remarks\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Morning Tea\n\n      - start_time: \"11:00\"\n        end_time: \"11:25\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"11:50\"\n        slots: 1\n\n      - start_time: \"11:50\"\n        end_time: \"12:15\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"13:55\"\n        slots: 1\n\n      - start_time: \"13:55\"\n        end_time: \"14:20\"\n        slots: 1\n\n      - start_time: \"14:20\"\n        end_time: \"14:50\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"14:40\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Afternoon Tea\n\n      - start_time: \"16:00\"\n        end_time: \"16:25\"\n        slots: 1\n\n      - start_time: \"16:25\"\n        end_time: \"16:50\"\n        slots: 1\n\n      - start_time: \"16:50\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Closing Remarks\n\n  - name: \"Day 3\"\n    date: \"2019-02-08\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:30\"\n        end_time: \"09:40\"\n        slots: 1\n        items:\n          - Opening Remarks\n\n      - start_time: \"09:40\"\n        end_time: \"10:05\"\n        slots: 1\n\n      - start_time: \"10:05\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Morning Tea\n\n      - start_time: \"11:00\"\n        end_time: \"11:25\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"11:50\"\n        slots: 1\n\n      - start_time: \"11:50\"\n        end_time: \"12:15\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"13:55\"\n        slots: 1\n\n      - start_time: \"13:55\"\n        end_time: \"14:20\"\n        slots: 1\n\n      - start_time: \"14:20\"\n        end_time: \"14:50\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"14:40\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Afternoon Tea\n\n      - start_time: \"16:00\"\n        end_time: \"16:25\"\n        slots: 1\n\n      - start_time: \"16:25\"\n        end_time: \"16:50\"\n        slots: 1\n\n      - start_time: \"16:50\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Closing Remarks\n\n      - start_time: \"17:15\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Closing Party\n\n  - name: \"Day 4\"\n    date: \"2019-02-09\"\n    grid:\n      - start_time: \"12:00\"\n        end_time: \"16:00\"\n        slots: 4\n        items:\n          - Hands-on Pizza Cooking Class 🍕\n          - Aboriginal History & City Walking Tour 📸\n          - Indoor Bouldering 🧗‍♀️\n          - Hack Day 💻\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2019/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Emerald\"\n      level: 1\n      sponsors:\n        - name: \"Lookahead Search\"\n          website: \"https://www.lookahead.com.au/\"\n          slug: \"LookaheadSearch\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/lookahead.svg\"\n\n        - name: \"Envato\"\n          website: \"https://envato.com/\"\n          slug: \"Envato\"\n          logo_url: \"https://www.rubyconf.org.au/2018/images/sponsors/envato.png\"\n\n        - name: \"Culture Amp\"\n          website: \"https://www.cultureamp.com\"\n          slug: \"CultureAmp\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/culture-amp.png\"\n\n    - name: \"Opal\"\n      level: 3\n      sponsors:\n        - name: \"Buildkite\"\n          website: \"https://buildkite.com/\"\n          slug: \"Buildkite\"\n          logo_url: \"https://www.rubyconf.org.au/images/sponsors/buildkite.svg\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2019/videos.yml",
    "content": "---\n# Website: https://rubyconf.org.au/2019\n# Schedule: https://rubyconf.org.au/2019/schedule\n\n## Day 0 - Wednesday, 2019-02-06\n\n# Opening Party\n\n## Day 1 - Thursday, 2019-02-07\n\n# Registration\n\n# Welcome and Opening Remarks\n\n- id: \"nadia-odunayo-rubyconf-au-2019\"\n  title: \"The Case Of The Missing Method - A Ruby Mystery Story\"\n  raw_title: \"The Case Of The Missing Method - A Ruby Mystery Story\"\n  speakers:\n    - Nadia Odunayo\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-07\"\n  published_at: \"2019-02-07\"\n  description: \"Nadia Odunayo\n\n\n    Business is slow for Ruby Private Investigator, Deirdre Bug. She’s on the verge of switching industry when she gets a call from an anxious young man. \\\"Some class methods have\n    gone missing,\\\" he tells her breathlessly. \\\"I need your help.\\\"\\r\n\n    \\r\n\n    Deirdre takes the case and begins exploring Ruby objects behind the scenes. Though she thinks she's on familiar ground — Ruby's object model, method lookup — she's about to\n    discover that she really has no clue.\\r\n\n    \\r\n\n    [Nadia](http://www.nadiaodunayo.com/) is CEO at [The StoryGraph](https://thestorygraph.com). Before that, she co-directed Ignition Works, a company that did a mix of in-house\n    product development and software consultancy, helping large firms to manage their cloud platforms. She previously worked at Pivotal and originally learnt to code at Makers\n    Academy in London. She maintains [speakerline.io](https://speakerline.io/) in her spare time.\\\"\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"aRkHqYDi_wQ\"\n\n# Morning Tea\n\n- id: \"heidi-waterhouse-rubyconf-au-2019\"\n  title: \"I Have ADD and So Can - Ooh, Shiny!\"\n  raw_title: \"I Have ADD and So Can - Ooh, Shiny!\"\n  speakers:\n    - Heidi Waterhouse\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-07\"\n  published_at: \"2019-02-12\"\n  description: |-\n    Heidi Waterhouse\n    (Fixed video)\n\n    Come listen to me talk about my own invisible neurodiversity, and what it has taught me about being a good employee and becoming more effective because of who I am, not in spite of it.\n\n    Heidi is a developer advocate with LaunchDarkly. She delights in working at the intersection of usability, risk reduction, and cutting-edge technology. One of her favorite hobbies is talking to developers about things they already knew but had never thought of that way before. She sews all her conference dresses so that she’s sure there is a pocket for the mic.\n\n    #ruby #rubyconf #rubyconfau #programming\n  video_provider: \"youtube\"\n  video_id: \"xX6qLuarYVs\"\n\n- id: \"dvid-halsz-rubyconf-au-2019\"\n  title: \"How to hijack, proxy and smuggle sockets with Rack/Ruby\"\n  raw_title: \"How to hijack, proxy and smuggle sockets with Rack/Ruby\"\n  speakers:\n    - Dávid Halász\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-07\"\n  published_at: \"2019-02-07\"\n  description: \"Dávid Halász\n\n\n    Does your network only let through HTTP connections? No problem! Let’s hijack some sockets from incoming HTTP connections and use it to smuggle any kind of traffic through an\n    HTTP session! Concurrently! In Ruby!\\r\n\n    \\r\n\n    Warning: your infosec team already does not like me, but I have some cute stickers.\\r\n\n    \\r\n\n    David is a Software Engineer working for Red Hat. His first language is C, but fell in love with Ruby in 2012 and now codes in it for a living.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"dU7192V1mLI\"\n\n- id: \"tom-stuart-rubyconf-au-2019\"\n  title: \"Representations Count\"\n  raw_title: \"Representations Count\"\n  speakers:\n    - Tom Stuart\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-07\"\n  published_at: \"2019-02-07\"\n  description: \"Tom Stuart\n\n\n    In your grandparents’ attic you discover a mysterious old computer. You boot it up and discover it runs Ruby, but doesn’t support negative numbers! How can you implement\n    negative numbers in an elegant way? We’ll explore two solutions and discover how important it is to pick the right representation.\\r\n\n    \\r\n\n    [Tom](https://twitter.com/tomstuart) is a [computer scientist](http://computationbook.com/) and programmer. He has lectured on optimising compilers at the University of\n    Cambridge, co-organises the Ruby Manor conference, and is a member of the London Ruby User Group. He is currently the CTO of [FutureLearn](https://www.futurelearn.com/), an\n    online learning platform.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"ej-W956YQN0\"\n\n# Lunch\n\n- id: \"daniel-fone-rubyconf-au-2019\"\n  title: \"What Could Go Wrong? The Subtle Science Of Coding for Failure\"\n  raw_title: \"What Could Go Wrong? The Subtle Science Of Coding for Failure\"\n  speakers:\n    - Daniel Fone\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-07\"\n  published_at: \"2019-02-07\"\n  description: \"Daniel Fone\n\n\n    Software development is the anticipation of a thousand dangers: regressions, edge-cases, exceptions, attacks, downtime, the list is endless. Drawing from a wide range of\n    disciplines, we’ll build a simple model for quantifying danger, explore why the human brain is so bad at it, and examine some practical applications for our development\n    processes. There will be at least one science.\\r\n\n    \\r\n\n    [Daniel](http://daniel.fone.net.nz/) has been writing Ruby/Rails for about 10 years. In recent years he has been helping to organise the Christchurch Ruby meetups and serving\n    as secretary on the Ruby New Zealand committee. He lives in 🇳🇿 with 👨‍👩‍👧‍👦👶, and enjoys 🏃, 🍺, and 🔎 📖 ἡ κοινὴ. Much like Ruby, he tries to be optimised for\n    happiness — both his own and other people's.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"R7BSwkvGoH0\"\n\n- id: \"laura-mosher-rubyconf-au-2019\"\n  title: \"Harry the Hedgehog Learns You A Communication\"\n  raw_title: \"Harry the Hedgehog Learns You A Communication\"\n  speakers:\n    - Laura Mosher\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-07\"\n  published_at: \"2019-02-07\"\n  description: \"Laura Mosher\n\n\n    Communication is one of the most difficult skills to master in software development. There are many shortfalls in communication — both written and spoken — that have an impact\n    on how you are perceived. Harry the Hedgehog will uncover some of those shortfalls and how he overcame them.\\r\n\n    \\r\n\n    Laura is a software engineer with a passion for clean code and oxford commas. She’s passionate about creating a better world through code, kindness, and understanding. When she\n    isn’t coding, she enjoys rescuing hedgehogs, making things, and playing games.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"1R_2MZC81Aw\"\n\n# Coffee Break\n\n- id: \"kelly-sutton-rubyconf-au-2019\"\n  title: \"Taming Monoliths Without Microservices\"\n  raw_title: \"Taming Monoliths Without Microservices\"\n  speakers:\n    - Kelly Sutton\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-07\"\n  published_at: \"2019-02-07\"\n  description: \"Kelly Sutton\n\n\n    In the recent years, microservices have been an investment among many engineering teams as they scale. They are often the default of many new companies.\\r\n\n    \\r\n\n    But how has that gone wrong? This talk will dive into how one company of ~100 engineers refined their thinking and their Rails app for the better.\\r\n\n    \\r\n\n    Kelly Sutton is an engineering manager at Gusto. In the past, he helped create LayerVault, Designer News, and a blog for college students. He is currently based in San\n    Francisco, CA. He regularly writes blog posts about software engineering at https://kellysutton.com\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"-ovkkvvTiRM\"\n\n- id: \"betsy-haibel-rubyconf-au-2019\"\n  title: \"Pairing with People Who Don't Look Like You\"\n  raw_title: \"Pairing with People Who Don't Look Like You\"\n  speakers:\n    - Betsy Haibel\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-07\"\n  published_at: \"2019-02-07\"\n  description: \"Betsy Haibel\n\n\n    Pair programming can be hazardous if you’re from an underrepresented group. Bad pairs will keyboard-hog, ignore your ideas, and talk down to you. In this talk, you’ll learn how\n    to rescue pairing sessions from bad power dynamics – whether you’re a well-intentioned jerk or their long-suffering pair.\\r\n\n    \\r\n\n    Betsy Haibel is the founding CTO of Cohere. She writes fiction and nonfiction in English, Ruby, and Javascript – among other languages – and co-organizes Learn Ruby in DC. Her\n    lifelong ambitions? To meet a red panda, and to break down barriers between “developers” and “users.”\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"A_9v5L01fcs\"\n\n# Afternoon Tea\n\n- id: \"tekin-sleyman-rubyconf-au-2019\"\n  title: \"A Branch in Time (a story about revision histories)\"\n  raw_title: \"A Branch in Time (a story about revision histories)\"\n  speakers:\n    - Tekin Süleyman\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-07\"\n  published_at: \"2019-02-07\"\n  description: \"Tekin Süleyman\n\n\n    In one timeline a quick path to clarity. In the other a painful journey trying to uncover the obscure intent of a line of code. The only difference between these two realities?\n    The revision history…\\r\n\n    \\r\n\n    This is a story about revision histories and their impact on software maintainability. Think Sliding Doors, but with more Git!\\r\n\n    \\r\n\n    Tekin is a senior freelance consultant who’s been shipping Ruby code for over a decade. He’s worked with teams, large and small: from Government agencies (GDS) to listed\n    startups (FreeAgent), and the world’s oldest and largest Co-operative (Co-op Digital). He also runs the North West Ruby User Group in Manchester, UK.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"1NoNTqank_U\"\n\n- id: \"merrin-macleod-rubyconf-au-2019\"\n  title: \"Environment Variables\"\n  raw_title: \"Environment Variables\"\n  speakers:\n    - Merrin Macleod\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-07\"\n  published_at: \"2019-02-07\"\n  description: \"Merrin Macleod\n\n\n    How can we minimise our software’s contribution to climate change? How do we make software that can withstand climate change-related disasters? How do we deal with the\n    knowledge that we’re careening towards catastrophe?\\r\n\n    \\r\n\n    \\ I don’t have all the answers, but let’s do some maths about it.\\r\n\n    \\r\n\n    Merrin is a Ruby developer with a background in design, social enterprise, and the electricity industry.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"N4hiqGwTRBU\"\n\n# Closing Remarks\n\n## Day 2 - Friday - 2019-02-08\n\n# Registration ️and Coffee\n\n# Opening Remarks\n\n- id: \"eliza-sorensen-rubyconf-au-2019\"\n  title: \"Internet Legislation is Eating the World\"\n  raw_title: \"Internet Legislation is Eating the World\"\n  speakers:\n    - Eliza Sorensen\n    - Jack Chen\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"Eliza Sorensen, Jack Chen\n\n\n    [Eliza](https://twitter.com/Zemmiph0bia) is an Infrastructure & Security engineer, cyber witch and co-founder of social enterprise [Assembly Four](https://assemblyfour.com/)\n    who created sex worker friendly social network Switter and inclusive modern advertising platform Tryst.\\r\n\n    \\r\n\n    Mostly known as “chendo”, Jack is a software-oriented problem-solver who occasionally enjoys making computers do his bidding. He is one of the co-founders of a social\n    enterprise called [Assembly Four](https://assemblyfour.com/), which aims to build modern products and services for sex workers around the world. When he’s not yelling at\n    computers, you can find him bouldering, playing video games, or go karting.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"MDBm6_udqLg\"\n\n- id: \"keith-pitty-rubyconf-au-2019\"\n  title: '\"What were they thinking?\"'\n  raw_title: '\"What were they thinking?\"'\n  speakers:\n    - Keith Pitty\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"Keith Pitty\n\n\n    This is a sentiment many Rails developers have experienced whilst reading a legacy codebase, trying to glean the motivations behind the code or simply understand what it is\n    meant to do. This talk turns that perspective on its head and asks, “what can I do to prevent this scenario?\\\"\\r\n\n    \\r\n\n    Keith Pitty has been developing software professionally for more than three decades. Since 2000 he has maintained a keen interest in Agile approaches and for the last ten years\n    has made many contributions to the Australian Ruby community. He has been fascinated by how developers consider other people when developing software since his early days of\n    programming on mainframes. Away from computers he enjoys golf, is a cricket tragic and a passionate Collingwood supporter.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"KiGbAbjYAjI\"\n\n# Morning Tea\n\n- id: \"tim-riley-rubyconf-au-2019\"\n  title: \"Views, From The Top\"\n  raw_title: \"Views, from the top\"\n  speakers:\n    - Tim Riley\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"Tim Riley\n\n\n    /Veni, vidi, view-ci/ – I came, I saw, I left the views in a mess.\\r\n\n    \\r\n\n    With server-rendered HTML still delivering most of the web, our views deserve more than a grab bag of helpers.\\r\n\n    \\r\n\n    Come along and learn the tools and techniques to conquer the design challenges that a complex view layer presents.\\r\n\n    \\r\n\n    Tim Riley is a partner at Australian design agency Icelab, and a core developer of dry-rb and rom-rb. He’s excited by small libraries, first-class functions, and pushing\n    forward web app development with Ruby.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"VGWt1OLFzdU\"\n\n- id: \"mila-dymnikova-rubyconf-au-2019\"\n  title: \"Learn to make the point: data visualisation strategy\"\n  raw_title: \"Learn to make the point: data visualisation strategy\"\n  speakers:\n    - Mila Dymnikova\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"Mila Dymnikova\n\n\n    Let me guess, your code is awesome but no one else gets it? You need a data visualisation! Complex concepts can easily be explained through visual information. There are four\n    types to choose from storytelling, status, analytical and exploratory. I’ll help you find the perfect one.\\r\n\n    \\r\n\n    Mila is a data geek that loves data visualisations. Especially if the data visualisation is related to cats. Ruby is still her favourite language because of the community and\n    how expressive it is. When she's not coding, you’ll find Mila cruising on an electric skateboard.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"4OkoJxR3jdM\"\n\n- id: \"john-sawers-rubyconf-au-2019\"\n  title: \"Hacking Your Emotional API\"\n  raw_title: \"Hacking Your Emotional API\"\n  speakers:\n    - John Sawers\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"John Sawers\n\n\n    Being a good developer isn’t just about slinging code; we’re part of a community. Interacting with others in a community means feelings are involved.\\r\n\n    \\r\n\n    In this talk you’ll learn how emotions are affecting you by modeling them as an API and looking at the code.\\r\n\n    \\r\n\n    John the co-founder and CTO of Data Simply and a Senior Developer at Privia Health. He’s been programming professionally for two decades, in Perl, Java, PHP and Ruby. In recent\n    years he has also been supervising workshops called “Purpose, Passion, Peace” which helps people get deeply in touch with themselves and liberated from past traumas. He has\n    fused his expertise from these disparate areas into a new way of thinking about them both.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"OGDRUI8biTc\"\n\n# Lunch\n\n- id: \"elle-meredith-rubyconf-au-2019\"\n  title: \"Algorithms to live by and why should we care\"\n  raw_title: \"Algorithms to live by and why should we care\"\n  speakers:\n    - Elle Meredith\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"Elle Meredith\n\n\n    In this talk we will discuss algorithmic thinking in everyday life in language we can all understand. We will explore widely applicable algorithms, and how they reveal\n    themselves in our everyday lives, so that we better understand what when and how we can use them in our programs.\\r\n\n    \\r\n\n    Elle is a full stack web developer with more than ten years experience writing Ruby and Rails. Currently at Blackmill, previously she was Development Director at thoughtbot New\n    York. Elle believes in writing clean code, driven by automatic tests, with agile practices, an even work/life balance, and a respectful and inclusive team culture. Recently,\n    she developed and ran the apprenticeship program for Hooroo, up-skilling less experienced developers. When she is not immersed in the Ruby community, she is probably immersed\n    in water, or lately, in bread flour.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"kxYL0EyYOKw\"\n\n- id: \"tom-ridge-rubyconf-au-2019\"\n  title: \"Building APIs You Want To Hug With GraphQL\"\n  raw_title: \"Building APIs you want to hug with GraphQL\"\n  speakers:\n    - Tom Ridge\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"Tom Ridge\n\n\n    REST-ful, more like stress-ful am I right? What if I told you you could build amazing APIs your cat would be proud of with GraphQL instead.\\r\n\n    \\r\n\n    Let’s take a look at how to go about implementing a GraphQL API that’s evolvable and empowers your team.\\r\n\n    \\r\n\n    Tom Ridge is a developer currently residing in Brisbane, Australia. A father of twins, he’s recently organised a Rails Camp, was Vice President of Ruby Australia and has\n    co-organised his local meetup. Somehow, he’s still not sure why he has so little free time.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"lyJebJuG_sk\"\n\n# Coffee Break\n\n- id: \"tom-gamon-rubyconf-au-2019\"\n  title: \"What The Hell is a JRuby?\"\n  raw_title: \"What the hell is a JRuby?\"\n  speakers:\n    - Tom Gamon\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"Tom Gamon\n\n\n    If you are like me and you don’t know your MRI from your RBX, you think a Truffle Ruby sounds delicious and panic when someone mentions JRuby, then this talk is for you. We\n    will delve into JRuby and figure out what it is, why it is and how it is different from 'normal' ruby and other alternative Ruby implementations.\\r\n\n    \\r\n\n    I am a Ruby developer working out of Melbourne. I am awful at writing bios, I like tinkering with electronics and I know my chiffonade from my chicory.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"qJqC6xm-2PI\"\n\n- id: \"kelsey-pedersen-rubyconf-au-2019\"\n  title: \"It's Down! Simulating Incidents in Production\"\n  raw_title: \"It's Down! Simulating Incidents in Production\"\n  speakers:\n    - Kelsey Pedersen\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"Kelsey Pedersen\n\n\n    Who loves getting paged at 3am? No one.\\r\n\n    \\r\n\n    In responding to incidents – either at 3am or the middle of the day – we want to feel prepared and practiced in resolving production issues. In this talk, you’ll learn how to\n    practice incident response by simulating outages in your application.\\r\n\n    \\r\n\n    Kelsey Pedersen is a software engineer at Stitch Fix on the styling engineering team. She builds internal software their stylists use to curate clothes for their clients. She\n    works cross-functionally with their styling community and data science team to build new features to better assist their stylists. She had a former career in sales and as a\n    Division I rower at UC Berkeley.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"NYZdambrG_I\"\n\n# Afternoon Tea\n\n- id: \"adam-cuppy-rubyconf-au-2019\"\n  title: \"Mechanically Confident\"\n  raw_title: \"Mechanically Confident\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"Adam Cuppy\n\n\n    There’s a thread amongst all skilled practitioners: specific habits, routines, and processes that wrap uncertainty and create confidence. Oscar-winning actors rehearse,\n    pro-drivers do laps, chefs prep. This talk will help you recognize and design habits and routines that embed confidence in the body.\\\"\\r\n\n    \\r\n\n    Adam is _not_ a Fortune 500 CEO, award-winning book author, or Nobel Prize recipient. But, he’s an actor turned software engineer who co-founded [ZEAL](https://codingzeal.com),\n    a people-centric process-focused consulting company located around the United States.\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"Btsx9YzhJVM\"\n\n- id: \"beth-haubert-rubyconf-au-2019\"\n  title: \"Cats, The Musical! Algorithmic Song Meow-ification\"\n  raw_title: \"Cats, The Musical! Algorithmic Song Meow-ification\"\n  speakers:\n    - Beth Haubert\n  event_name: \"RubyConf AU 2019\"\n  date: \"2019-02-08\"\n  published_at: \"2019-02-08\"\n  description: \"Beth Haubert\n\n\n    How are you supposed to sing along with your favorite TV theme song every week if it doesn't have lyrics? At my house, we \\\"meow\\\" along (loudly). We also code, so I built\n    'Meowifier' to convert any song into a cat's meows. Join me in this exploration of melody analysis APIs and gratuitous cat gifs.\\r\n\n    \\r\n\n    I built an application that takes a song's audio and outputs a new audio file with that song's melody **sung by cats**. It's a technical feat. It's hilarious. It's beautiful.\n    It's a new way to waste time on the internet.\\r\n\n    \\r\n\n    [Beth](https://www.bethanyhaubert.com/) is a software engineer who loves Ruby, little-known APIs, handcrafting SQL queries, and as many monitors on her desk as possible. She’s\n    also a former airborne cryptologic linguist for the US Air Force, fluent in Mandarin. Things you can ask her about include cats, board games, karaoke, and building applications\n    that convert songs into auto-tuned cat meows. Things she'll have to kill you if you ask her about: the airborne linguist part. Also, she likes to make emojis look like they're\n    farting. 🐈💨\\\"\n\n\n    #ruby #rubyconf #rubyconfau #programming\"\n  video_provider: \"youtube\"\n  video_id: \"JTNPLwqJIDg\"\n# Closing Remarks\n\n## Day 3 - Saturday, 2019-02-09\n\n# Hands-on Pizza Cooking Class\n\n# Hack Day\n\n# Indoor Bouldering\n\n# Aboriginal History and Melbourne Walking Tour\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2020/event.yml",
    "content": "---\nid: \"PL9_jjLrTYxc1G0L8h-rMtO3fBSi4PJK26\"\ntitle: \"RubyConf AU 2020\"\nkind: \"conference\"\nlocation: \"Melbourne, Australia\"\ndescription: |-\n  A conference to share Ruby knowledge amongst like-minded Rubyists, 20th-21st February 2020, Melbourne Town Hall, 90-130 Swanston St\npublished_at: \"2020-02-19\"\nstart_date: \"2020-02-20\"\nend_date: \"2020-02-21\"\nchannel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nyear: 2020\ncoordinates:\n  latitude: -37.8136276\n  longitude: 144.9630576\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2020/videos.yml",
    "content": "---\n# Website: https://rubyconf.org.au/2020\n# Schedule: https://rubyconf.org.au/2020/schedule\n\n## Day 0 - Wednesday, 2020-02-19\n\n# Welcome Cocktail Party\n\n## Day 1 - Thursday, 2020-02-20\n\n# Registration and Coffee\n\n- id: \"caitlin-palmer-bright-rubyconf-au-2020\"\n  title: \"Welcome and Opening Remarks\"\n  raw_title: '\"Welcome (Thursday)\" - Caitlin Palmer-Bright, Melissa Kaulfuss (RubyConf AU 2020)'\n  speakers:\n    - Caitlin Palmer-Bright\n    - Melissa Kaulfuss\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-20\"\n  published_at: \"2020-02-20\"\n  description: |-\n    Caitlin Palmer-Bright, Melissa Kaulfuss\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n    #ruby #rubyconf #rubyconfau #programming\n\n    Thu Feb 20 09:00:00 2020 at Plenary Room\n  video_provider: \"youtube\"\n  video_id: \"1zqoH6LxnIE\"\n\n- id: \"vaidehi-joshi-rubyconf-au-2020\"\n  title: \"The Cost of Data\"\n  raw_title: '\"The Cost of Data\" - Vaidehi Joshi (RubyConf AU 2020)'\n  speakers:\n    - Vaidehi Joshi\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-20\"\n  published_at: \"2020-02-20\"\n  description: \"Vaidehi Joshi\n\n\n    The internet grows every day. Every second, one of us is making calls to an API, uploading images, and streaming the latest content. But what is the cost of this—is it free?\n    This talk explores the reality of data, and what responsibilities we have as creators and consumers of tech.\\r\n\n    \\r\n\n    Vaidehi is a senior engineer at DEV, where she builds community and helps improve the software careers of millions. She enjoys building and breaking code, but loves creating\n    empathetic engineering teams a whole lot more. She is the creator of basecs and baseds, two writing series exploring the fundamentals of computer science and distributed\n    systems. She also co-hosts the Base.cs Podcast, and is a producer of the BaseCS and Byte Sized video series.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #programming\n\n\n    Thu Feb 20 09:30:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"iEUPwHyIOBQ\"\n\n- id: \"liam-mcnally-rubyconf-au-2020\"\n  title: \"Working Remotely And How To Scale A Remote First Environment\"\n  raw_title: '\"Working remotely and how to scale a remote first environment\" - Liam McNally (RubyConf AU 2020)'\n  speakers:\n    - Liam McNally\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-20\"\n  published_at: \"2020-02-20\"\n  description: \"Liam McNally\n\n\n    Ever thought about being a remote worker, or what it is really like to work remote, the no nonsense version. This talk will explore why being a remote worker is amazing, why\n    sometimes it isn’t and why for some people it’s not for them.\\r\n\n    \\r\n\n    How do you identify who will be strong remote workers at recruitment? How to build a culture centred around remote working and how to get it to scale from 100 people to 1000\n    people and beyond.\\r\n\n    \\r\n\n    Close to 10 years experience working in HR and Talent Acquisition and the last 3 years working and scaling remote businesses. I have worked in tech environments for the last 5\n    years and have become a huge advocate for remote working as a way of building and teams/businesses.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Thu Feb 20 10:05:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"Ljjy9IHNUWo\"\n\n# Morning Tea\n\n- id: \"rob-howard-rubyconf-au-2020\"\n  title: \"A Message to the Stars\"\n  raw_title: '\"A Message to the Stars\" - Rob Howard (RubyConf AU 2020)'\n  speakers:\n    - Rob Howard\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-20\"\n  published_at: \"2020-02-20\"\n  description: \"Rob Howard\n\n\n    NASA sent out two probes, each with a gold-plated audio disc (the ‘Golden Record’) attached to them. The audio disc has, among more usual things like music and greetings, a\n    bunch of images that have been turned into sound. The disc has a cover with a bunch of pictorial instructions explaining how to read it. This talk is about pretending to be\n    aliens finding this disc, and following those instructions to recreate the images from that audio, because… well, because it’s cool goshdarnit. \\r\n\n    \\r\n\n    Rob Howard is a web developer and figurative magpie. Having spent his career so far learning and mixing the nice parts from different programming languages, he'd like nothing\n    better than to help technical communities learn more from each other, build better stuff, and have fun in the process.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Thu Feb 20 11:10:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"W5A7_TWd4QM\"\n\n- id: \"nancy-cai-rubyconf-au-2020\"\n  title: \"How Much Pressure Can Your App Handle - Performance Testing With Ruby\"\n  raw_title: \"How much pressure can your app handle - Performance testing with Ruby\"\n  speakers:\n    - Nancy Cai\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-20\"\n  published_at: \"2020-02-20\"\n  description: \"Nancy Cai\n\n\n    Nowadays more and more companies started to realise the importance of performance testing as new features and products, marketing campaigns, and annual events such as the\n    festival could all cause spikes in traffic to any site. To find your application’s bottleneck, come and enjoy a talk of how to build a performance testing framework with Ruby .\n    Through this talk Nancy will take you through what are the correct questions to ask before designing your testing strategy. Then you will learn how Airtasker selected the\n    testing tools and what our testing strategies are. This is a topic for anyone interested in doing performance testing for both web and API\\r\n\n    \\r\n\n    I learnt Economics and Interpreting and Translation in Uni. But after I graduated I ended up being a dental nurse for 2.5 years. Then I realised I need a career that has bright\n    future so I started to learn software testing. I taught myself the necessary coding skills to became a QA engineer. Later under the mentorship of the other software engineers\n    at Airtasker I became one of them as well. I love Lord of the Rings to death! For me it's the best movie ever! I also love to make fondant cakes and according to my co-workers\n    they are amazing :)\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Thu Feb 20 11:50:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"Q09wJm4P8Xw\"\n\n# Lunch\n\n- id: \"ernesto-tagwerker-rubyconf-au-2020\"\n  title: \"Escaping The Tar Pit\"\n  raw_title: '\"Escaping The Tar Pit\" - Ernesto Tagwerker (RubyConf AU 2020)'\n  speakers:\n    - Ernesto Tagwerker\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-20\"\n  published_at: \"2020-02-20\"\n  description: \"Ernesto Tagwerker\n\n\n    This talk will look at different definitions of code quality and then focus on one which will be composed of three sections:Code Coverage: How well covered is my application?\n    Complexity: How complex are the methods in my application? Code Smells: Are there any known code smells in my application? Code CoverageI will talk about SimpleCov and how we\n    would use it to calculate test coverage for our applications.ComplexityI will talk about flog and how we would use it to calculate a complexity score for our application.\n    Combined with the previous section, we will be able to calculate the relative complexity (super complex methods are so much worse with 0% testcoverage). Ernesto will briefly\n    explain Flog’s ABC metric (Assignments, Branches, Calls) Code Smells. He will also talk about reek and how we would use it to find code smells in a sample Roda application.\n    After going over these three sections, he will talk about a new tool that he's built to take all these things into account and calculate a maintainability score. Let’s call it\n    the StinkScore\\r\n\n    \\r\n\n    Ernesto is the Founder of Ombu Labs, a small software development company dedicated to building lean code. When he is not playing table tennis, he likes to maintain a few Ruby\n    gems including database_cleaner and email-spec. He is passionate about writing less code, contributing to open source, and eating empanadas.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Thu Feb 20 13:30:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"ORb2UQ0_8zg\"\n\n- id: \"jameson-hampton-rubyconf-au-2020\"\n  title: \"Walking A Mile In Your Users' Shoes\"\n  raw_title: '\"Walking A Mile In Your Users'' Shoes\" - Jameson Hampton (RubyConf AU 2020)'\n  speakers:\n    - Jameson Hampton\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-20\"\n  published_at: \"2020-02-20\"\n  description: \"Jameson Hampton\n\n\n    One of the reasons that tech is a cool industry to work in is because “working in tech” doesn’t confine you to working in the tech industry. Everyone needs applications! Even\n    within tech, different people have different accessibility needs. But when you’re working in other industries, it’s often much less true that what “works” for you as a\n    programmer will also work for your users. Sometimes, while we get stuck on highly techinical problems for our users the barriers are suprisingly low tech. This talk will\n    cultivating empathy for your users while helping you solve the right problems.\\r\n\n    \\r\n\n    Jamey is a non-binary adventurer from Buffalo, NY who wishes they were immortal so they’d have time to visit every coffee shop in the world. They're a Rails engineer who has\n    recently been taking the plunge into DevRel and a panelist on the Greater than Code podcast. In their spare time, they do advocacy in the transgender community, write comics\n    and spend as much time as possible in the forest.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Thu Feb 20 14:10:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"w-zYKo8f7nM\"\n\n- id: \"brandon-weaver-rubyconf-au-2020\"\n  title: \"Tales From The Ruby Grimoire\"\n  raw_title: '\"Tales from the Ruby Grimoire\" - Brandon Weaver (RubyConf AU 2020)'\n  speakers:\n    - Brandon Weaver\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-20\"\n  published_at: \"2020-02-20\"\n  description: \"Brandon Weaver\n\n\n    There are arts best left unspoken, black magicks left forgotten and locked away in the deepest vaults of the Ruby language, lest they be seen by mortal eyes not ready for the\n    horrors inside.\\r\n\n    That is, until a particularly curious Lemur named Red happened to open it. Journey with Red into the Tales of the Ruby Grimoire, through parts of the language not meant for the\n    faint of heart.\\r\n\n    There is great power here, but that power comes at a cost. Are you willing to pay it? \\r\n\n    \\r\n\n    Brandon is a Ruby Architect at Square working on the Frameworks team, defining standards for Ruby across the company. He's an artist who turned programmer who had a crazy idea\n    to teach programming with cartoon lemurs and whimsy.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Thu Feb 20 14:50:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"xRj5DWvdx6k\"\n\n# Afternoon Tea\n\n- id: \"selena-small-rubyconf-au-2020\"\n  title: \"10x Your Teamwork Through Pair Programming\"\n  raw_title: '\"10X your teamwork through pair programming\" - Selena Small, Michael Milewski (RubyConf AU 2020)'\n  speakers:\n    - Selena Small\n    - Michael Milewski\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-20\"\n  published_at: \"2020-02-20\"\n  description: \"Selena Small, Michael Milewski\n\n\n    These two presenters will take you on a roller coaster journey of how to get started and get the most out of pair-programming. Live on stage they will switch from\n    conversational overview straight into acting out various highs, lows, do’s and don’ts of pair-programming collaboration. Laughs and tears are guaranteed as the audience connect\n    on the difficulties and ultimately the rewards that can be reaped from teamwork through effective pairing.Pair-programming, 2 developers writing code collaboratively with 2\n    keyboards and 1 computer, might feel weird, foreign, or impossible.\\r\n\n    \\r\n\n    Selena and Michael met through work at Fresho! but soon realised they are the kind of friends who would rather talk tech at a party. So they turned their party times into\n    numerous hackathons, coding camps, and duo talks and workshops on topics around test driving software and pair programming.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Thu Feb 20 16:00:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"wujR20wFhNM\"\n\n- id: \"yuji-yokoo-rubyconf-au-2020\"\n  title: \"Developing your Dreamcast Games with mruby\"\n  raw_title: '\"Developing your Dreamcast games with mruby\" - Yuji Yokoo (RubyConf AU 2020)'\n  speakers:\n    - Yuji Yokoo\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-20\"\n  published_at: \"2020-02-20\"\n  description: \"Yuji Yokoo\n\n\n    What is mruby, and why use it? This session will cover questions such as; What is Dreamcast, and why use it? Getting started on Dreamcast programming, Getting mruby to build\n    for Dreamcast, Getting the built binary over to the console unit, plus a quick overview of the game code Short Demo. Yuji believes developing software for video game consoles\n    is exciting for many people. It is especally exciting when you can run your code on a retro-console, off-the-shelf, unmodified. This presentation will involve some technical\n    contents but it will not go too deep. This session will cover mruby and running it on a non-mainstream architecture and is suitable for all levels.\\r\n\n    \\r\n\n    Yuji is a software developer based in Adelaide, South Australia. He was born and raised in Tokyo, Japan. He used to be a Windows desktop application developer until he\n    discovered Ruby. He also enjoys console video games, Judo and Brazilian Jiu Jitsu.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Thu Feb 20 16:40:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"ni-1x5Esa_o\"\n\n# Close\n\n## Day 2 - Friday, 2020-02-21\n\n# Registration and Coffee\n\n- id: \"adel-smee-rubyconf-au-2020\"\n  title: \"Inclusiveness - It's In Your Hands\"\n  raw_title: '\"Inclusiveness - It''s In Your Hands\" - Adel Smee (RubyConf AU 2020)'\n  speakers:\n    - Adel Smee\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-21\"\n  published_at: \"2020-02-21\"\n  description: \"Adel Smee\n\n\n    Resilient, effective teams are diverse teams, teams that feel safe throwing around ideas, teams that look out for each other, teams where the needs of the individuals in the\n    team are (mostly) met, teams that can learn and grow with your company. Nurturing environments in which such teams can form and flourish is an endlessly challenging and\n    rewarding task that belongs to everyone in the company. And yet, a lot of the work to identify issues, champion change and improve a company’s culture and the diversity of its\n    workforce is done by the same few people, or left entirely to HR. These folks could do with a hand. A hand from you! This talk will lay out (some) of the work that’s already\n    being done, provides a handy how-to guide to getting started in diversity and inclusion and extends an invitation to anyone who cares about the issue to lend a hand.\\r\n\n    \\r\n\n    Adel Smee is an Engineering Manager at Zendesk where, for the last four years, she has led innovation projects across a variety of technologies and grown a number of high\n    performing teams. Her career in tech started with teaching people to code, before she decided to break out and get paid to do it commercially at a startup, then at Lonely\n    Planet, and then at Zendesk. Along the way she realised that her main implicit motivator is delight in the success of others, which turns out to be a really useful quality in a\n    manager. She is obsessed with what makes people (and herself) tick and loves to hear how she is getting it wrong so she can do better. Adel is an incurable optimist who\n    believes that one day we’ll live in a world where everybody likes their job as much as she does, but isn’t naive enough to think that day is coming any time soon.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Fri Feb 21 09:15:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"6QKA7LtYiG0\"\n\n- id: \"matthew-borden-rubyconf-au-2020\"\n  title: \"Murdering our Mongo Database (or how we migrated to a relational database)\"\n  raw_title: \"Murdering our Mongo Database (or how we migrated to a relational database)\"\n  speakers:\n    - Matthew Borden\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-21\"\n  published_at: \"2020-02-21\"\n  description: \"Matthew Borden\n\n\n    This is the story of migrating large parts of an application’s data layer from MongoDB to MySQL with zero downtime using Ruby.\\r\n\n    \\r\n\n    We’ll cover designing schemas to represent untyped data, dual writing to both databases, migrating old data and staging the cutover to the new database. \\r\n\n    \\r\n\n    Matthew is a Site Reliability Engineer at Seer Medical maintaining a cloud based epilepsy diagnostics system. Previously, he was at Stile Education developing a science\n    education platform for high school students. He enjoys the detective work of debugging issues in production, the delightful nature of writing Ruby and finding new ways to break\n    systems early before they break in production.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Fri Feb 21 10:00:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"Knd3m2qh0o8\"\n\n# Morning Tea\n\n- id: \"lena-plaksina-rubyconf-au-2020\"\n  title: \"Just my type: things I learned from writing my own programming language\"\n  raw_title: \"Just my type: things I learned from writing my own programming language\"\n  speakers:\n    - Lena Plaksina\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-21\"\n  published_at: \"2020-02-21\"\n  description: \"Lena Plaksina\n\n\n    If programming languages are about technology, why did Matz optimise Ruby for “developer happiness”?  Computers pay little regard to how an instruction is expressed — whatever\n    we write in Ruby can just as well be expressed in Java, C#, or Smalltalk. So, why do people gravitate to one language over another? How do programming communities form? What\n    drives their ethos and manifestos?\\r\n\n    \\r\n\n    Hi, I’m Lena. I’m an avid cat rescuer, learning enthusiast, and Rails Bridge Wellington organising committee member. I started out in design, but fell for web and software\n    development during my first industry internship. I've been writing Ruby since 2015, and I'm currently learning other languages to expand my toolkit. I’m all about finding\n    patterns, building and communicating software in a way that helps everyone understands it, and failing better – mistakes make me a better developer, and I believe that failing\n    is just an opportunity to learn. When I’m not coding, I’m watching movies with my 3-legged rescue cat Warlock, collecting enamel pins, and helping out and/or presenting at tech\n    community events around town.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Fri Feb 21 11:15:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"3wSLmQWlixc\"\n\n- id: \"julian-doherty-rubyconf-au-2020\"\n  title: \"Escape Your Framework\"\n  raw_title: '\"Escape Your Framework\" - Julian Doherty (RubyConf AU 2020)'\n  speakers:\n    - Julian Doherty\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-21\"\n  published_at: \"2020-02-21\"\n  description: \"Julian Doherty\n\n\n    Rails and other frameworks let you quickly throw together ideas to get up and running quickly. But as your app grows, this can limit what you can do. How can we set ourselves\n    up to get the benefits that come from using a framework, while staying flexible and not beholden to it?\\r\n\n    \\r\n\n    Julian is a lead developer with 20 years experience, and has been hacking on Ruby for the last 13. Originally from Wellington, New Zealand, he now calls Melbourne home.\n    Currently working at Envato, he has spent time at some of the biggest Rails shops in Australia. Julian also runs the Elixir Melbourne meetup group, and tries to spend as much\n    time as possible inflicting functional programming paradigms on codebases he works in.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Fri Feb 21 11:50:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"IsRCJA-SXBU\"\n\n# Lunch\n\n- id: \"carmen-chung-rubyconf-au-2020\"\n  title: \"How To Write Tech Documentation That Will Save Your Career\"\n  raw_title: '\"How To Write Tech Documentation That Will Save Your Career\" - Carmen Chung (RubyConf AU 2020)'\n  speakers:\n    - Carmen Chung\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-21\"\n  published_at: \"2020-02-21\"\n  description: \"Carmen Chung\n\n\n    Ever heard of “cscareerthrowaway567”, the software engineer who lost his job on the first day of work? This happened because of terrible internal documentation - something that\n    is surprisingly common in the tech industry.Follow along with Carmen on the journey of three employees of Big Tech Co (a company that uses Ruby on Rails): junior software\n    developer, Kira; senior software engineer Felicity; and product manager Franco, as they struggle to navigate the day’s hurdles because of poor technical documentation at their\n    company.\\r\n\n    \\r\n\n    Carmen is a software engineer, writer, and conference speaker, with a reputation for breaking people's code. Prior to her move into tech, she worked internationally as a\n    corporate lawyer for almost seven years. \\r\n\n    \\r\n\n    During the day, she is a software engineer at Valiant Finance, and at night, she's the host and producer of a YouTube channel called CodeFights, which teaches people how to\n    solve coding questions in 15 minutes. In her spare time, she teaches flexibility classes, creates (often absurd) side projects, and fosters rescue dogs.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Fri Feb 21 13:30:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"ocqjOFrrios\"\n\n- id: \"paul-joe-george-rubyconf-au-2020\"\n  title: \"Build a voice based smart home using Sinatra & mruby/c\"\n  raw_title: \"Build a voice based smart home using Sinatra & mruby/c\"\n  speakers:\n    - Paul Joe George\n    - Do Xuan Thanh\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-21\"\n  published_at: \"2020-02-21\"\n  description: \"Paul Joe George, Do Xuan Thanh\n\n\n    As of 2019 smart assistants support more than 30 languages and is still learning many more. In the future, it is expected to have a good role in humans life.The usage of smart\n    assistants is rapidly increasing day by day. It can reduce unnecessary effort and time consumption. Nowadays it is not necessary to own a smart device like Alexa Echo or Google\n    Home. A cheaper option is available for free on our phones; it has improved the portability factor as well. And most importantly, training a smart assistant is less complicated\n    so that anyone with basic knowledge in programming can create custom skills and make life much more beautiful. This is an experiment to convert home appliances into smart\n    appliances and normal kids safety door lock to a smart lock by using voice commands. Smart assistants can make the life of everyone better regardless of skill or age. What if\n    old people can control lights, TV, curtain etc using voice commands? It is set to make life more beautiful.\\r\n\n    \\r\n\n    Paul and Thanh are software developers at Monstar Lab Inc.  Living in Matz's hometown, where Ruby is more than a programming language. They use Ruby purely for fun as Ruby is\n    fun. Using Ruby only for traditional Ruby on Rails projects never satisfied them. For that reason they decided to experiment using mruby/c - a mini version of Ruby for one-chip\n    microcontroller programming. Currently they are building more and more practical applications  to inspire other Ruby lovers to start using Ruby for IoT.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Fri Feb 21 14:10:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"0V-MJgklza4\"\n\n- id: \"elle-meredith-rubyconf-au-2020\"\n  title: \"Start your own engineering apprenticeship program\"\n  raw_title: '\"Start your own engineering apprenticeship program\" - Elle Meredith (RubyConf AU 2020)'\n  speakers:\n    - Elle Meredith\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-21\"\n  published_at: \"2020-02-21\"\n  description: \"Elle Meredith\n\n\n    With a surge of over 1.3 million technology sector jobs by 2020, companies will continue to struggle filling these roles because of a widening skills gap. Technology companies\n    survive by their ability to hire and retain fantastic employees. With software engineers that means delivering an environment that offers autonomy, opportunities for learning,\n    and values craft. Technology companies employ people who can learn, who love it, and those inspired to keep doing it. But, how do you foster that in emerging developers? Such\n    that they have sufficient foundational knowledge to build a meaningful career, and that they are provided the tools to continue to bridge knowledge gaps in our changing\n    industry.\\r\n\n    \\r\n\n    Elle has been writing Ruby for over a decade. Currently at Blackmill, previously Development Director at thoughtbot New York. Elle believes in writing clean code, driven by\n    automatic tests, with agile practices, an even work/life balance, and a respectful and inclusive team culture. Recently, she developed and ran an apprenticeship program for\n    Qantas Hotels. When not immersed in the Ruby community, she is probably immersed in water, or lately in flour\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Fri Feb 21 14:50:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"HVREurpIvsg\"\n\n# Afternoon Tea\n\n- id: \"dana-sherson-rubyconf-au-2020\"\n  title: \"300x Faster Ruby\"\n  raw_title: '\"300x faster ruby\" - Dana Sherson (RubyConf AU 2020)'\n  speakers:\n    - Dana Sherson\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-21\"\n  published_at: \"2020-02-21\"\n  description: \"Dana Sherson\n\n\n    Ruby sometimes has a reputation for being slow, but it doesn't have to be. There are likely ways to optimise fragments of your application and not even have to rewrite it in\n    rust. Improve your intuition about bottlenecks and optimisations and how to use and read the output of tools like ruby-prof, rb-spy, benchmark, and others (including Dana's\n    favourite: time), how to know what needs attention, and some surprising quirks when writing fast ruby. The title may seem like an exaggeration, but Dana did make a\n    spell-checking ruby gem at least 300 times faster with the liberal application of benchmarking and profiling, and you can too.\\r\n\n    \\r\n\n    Dana has been programming in ruby for at least 10 years, and her ruby tattoo may prove she might like it a little too much. When not programming in ruby, Dana can be found\n    failing at being a photographer, singing Avril Lavigne songs at karaoke, or adding unnecessary emoji to slack :yoda:. Dana has killed every plant that was ever in her care.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Fri Feb 21 16:00:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"hnGVFzZ0DuI\"\n\n- id: \"xavier-shay-rubyconf-au-2020\"\n  title: \"My Experience With Experience\"\n  raw_title: '\"My Experience With Experience\" - Xavier Shay (RubyConf AU 2020)'\n  speakers:\n    - Xavier Shay\n  event_name: \"RubyConf AU 2020\"\n  date: \"2020-02-21\"\n  published_at: \"2020-02-21\"\n  description: \"Xavier Shay\n\n\n    Becoming a senior contributor to your organization takes years. It's a process that is stubbornly hard to accelerate - it takes much more than drilling code katas!\\r\n\n    \\r\n\n    In this talk Xavier reflect on situations he's encountered over the last decade, and apply some academic models he's found useful to explain and learn from them. By doing so we\n    can better understand the limits to learning and prepare ourselves to make the most out of our experience.\\r\n\n    \\r\n\n    Xavier recently moved back home to Melbourne after spending eight years in San Francisco, mostly as an engineering leader at Square. Currently working at Ferocia building Up, a\n    fancy new digital bank. He's scheming to introduce the RubyConf 5K tradition to Australia.\n\n\n    Produced by NDV: https://youtube.com/channel/UCQ7dFBzZGlBvtU2hCecsBBg?sub_confirmation=1\n\n\n    #ruby #rubyconf #rubyconfau #rubyconf_au #rails #programming\n\n\n    Fri Feb 21 16:35:00 2020 at Plenary Room\"\n  video_provider: \"youtube\"\n  video_id: \"0na_1A_-Ebo\"\n# Closing Remarks\n\n# Closing Games Night\n\n## Day 3 - Saturday, 2020-02-22\n\n# Saturday Afternoon Drinks\n\n# Hack Day\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2023/event.yml",
    "content": "---\nid: \"PL9_jjLrTYxc0s-zA-RxRyb62tIcugZyG3\"\ntitle: \"RubyConf AU 2023\"\nkind: \"conference\"\nlocation: \"Melbourne, Australia\"\ndescription: |-\n  A conference to share Ruby knowledge amongst like-minded Rubyists, 16th-17th February 2023, Melbourne Convention Centre, South Wharf\npublished_at: \"2023-02-17\"\nstart_date: \"2023-02-16\"\nend_date: \"2023-02-17\"\nyear: 2023\nbanner_background: \"#B22918\"\nfeatured_background: \"#B22918\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: -37.8136276\n  longitude: 144.9630576\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2023/videos.yml",
    "content": "---\n# Website: https://rubyconf.org.au/2023\n# Schedule: https://rubyconf.org.au/2023/schedule\n\n## Day 0 - Wednesday, 2023-02-15\n\n# Welcome Games Night - Sponsored by Assembly Four\n\n## Day 1 - Thursday, 2023-02-16\n\n# Registration and Coffee\n\n# Welcome and Opening Remarks\n\n- id: \"samuel-williams-rubyconf-au-2023\"\n  title: \"Asynchronous Rails\"\n  raw_title: \"Asynchronous Rails\"\n  speakers:\n    - Samuel Williams\n  description: |-\n    The fiber scheduler presents new opportunities for building scalable and concurrent Ruby programs. However, Rails has traditionally been a request-per-process or request-per-thread framework. We will give a brief introduction to the fiber scheduler, and look at how we are evolving Rails and Ruby in general to take advantage of request-per-fiber using Falcon.\n  date: \"2023-02-16\"\n  published_at: \"2023-02-28\"\n  video_id: \"9tOMD491mFY\"\n  video_provider: \"youtube\"\n\n- id: \"yuji-yokoo-rubyconf-au-2023\"\n  title: \"Megaruby - mruby/c on Sega Mega Drive\"\n  raw_title: \"Megaruby - mruby/c on Sega Mega Drive\"\n  speakers:\n    - Yuji Yokoo\n  description: |\n    With mruby/c, it's now possible to run Ruby code on Sega Mega Drive!\n\n    I will show you how to get started, what makes Sega Mega Drive a great platform for mruby/c, and some of the challenges I faced.\n\n    This presentation will be delivered on a Mega Drive unit.\n  date: \"2023-02-16\"\n  published_at: \"2023-02-16\"\n  video_id: \"sz8tmrQtAUE\"\n  video_provider: \"youtube\"\n\n# Morning Tea\n\n- id: \"shaila-man-rubyconf-au-2023\"\n  title: \"Neurodiversity - Shifting the Paradigm from Silent Disability to Super Power\"\n  raw_title: \"Neurodiversity - Shifting the Paradigm from Silent Disability to Super Power\"\n  speakers:\n    - Shaila Man\n  description: |\n    Is thinking different such a bad thing? ...Let's look at the evolutionary theory behind neurodiversity. Would the human race even exist today if Neurodiversity wasn't engineered into the population? the answer is - Probably not! Why is that?\n\n    How and why do modern teams benefit by actively including neurodiversity? More and more workplaces, such as the Australian Defence Force, are actively seeking out and including neurodiversity? They're offering supportive working environments to unlock their super powers!\n\n    Are you unknowingly suppressing the super powers of your neurodiverse colleagues by forcing them to conform to neurotypical expectations? Are you aware of their daily struggles due to workplaces and processes being built for neurotypicals? eg. do you offer pairing opportunities to help with task paralysis? or quiet working spaces? or attention to office lighting? or recorded Zoom meetings, etc? The chances are, if they are female - they might not be aware of their own needs! Did you know that the average age for ADHD diagnosis for anyone born male is single digits, and goes up to 45 for anyone born female?!\n\n    Let's encourage more open conversations, and educate ourselves and our peers. Neurodiversity is not a disability - it's a super power from being wired differently. The benefits can be incredible when we become inclusive!\n  date: \"2023-02-16\"\n  published_at: \"2023-02-16\"\n  video_id: \"CsoB-kP3-J0\"\n  video_provider: \"youtube\"\n\n- id: \"pat-allan-rubyconf-au-2023\"\n  title: \"Upgrading the Ruby Community\"\n  raw_title: \"Upgrading the Ruby Community\"\n  speakers:\n    - Pat Allan\n  description: |\n    The Ruby community has a reputation across the wider tech industry for being a bit special - opinionated, yes, but also warm and welcoming. Our conferences, our events, even our code is so often a bit more thoughtful and a bit more fun, and the legacy of this has spread beyond Ruby to other language communities such as Elixir and Rust. We have every reason to be proud… yet, we should be wary of resting of our laurels.\n\n    And when we look at the broader world - with pandemics, wars, and the devastation of the climate emergency - well, it's easy to become despondent, or to shut that out and focus on the code. But instead, we should tap into that special community vibe that has nurtured us, and take a step forward in having a broader impact. So what could that look like?\n\n    To understand what we can (and perhaps should) do, we must understand what has been done already: this session will cast a critical eye on our industry, pointing out missteps and missed perspectives, as well as looking at what has been done elsewhere to make lasting, positive changes. With that foundation set, we will then talk through several recommendations on what meaningful action for software developers can be, as well as possible guidelines to help each other critique, share and refactor our actions to have even greater impact.\n  date: \"2023-02-16\"\n  published_at: \"2023-02-16\"\n  video_id: \"ml9wma3WL8c\"\n  video_provider: \"youtube\"\n\n# Lunch\n\n- id: \"rhiana-heppenstall-rubyconf-au-2023\"\n  title: \"But, You Don't Look Autistic\"\n  raw_title: \"But, you don't look Autistic\"\n  speakers:\n    - Rhiana Heppenstall\n  description: |\n    Put yourself into the eyes of someone with autism… wait that's not how that goes, metaphors are hard. As someone who grew up in an autistic house, I knew we were different, but not why and what to do about it. After stumbling through life, here's what I'd like to share about autism. Wait, shoes!\n\n    An in depth look into autism and how people with autism function in the workplace.\n\n    This talk goes through:\n\n    Personal history and experiences\n\n    * I've been diagnosed for 15 years and majored psychology at university to learn more\n\n    How autism is diagnosed including criteria and levels of autism\n\n    * Including the history of autism\n    * Debunking some common myths and stereotypes\n\n    Strengths and weaknesses\n\n    * Real life min/maxing\n\n    Workplace consideration and accommodations\n\n    * Asking people what they need and believing them helps everyone\n\n    I'm hoping by sharing my experiences you'll be able to gain some insight on how to help others, or yourself if you identify with what I've been saying a little too much.\n  date: \"2023-02-16\"\n  published_at: \"2023-02-16\"\n  video_id: \"i85MQxE9TR0\"\n  video_provider: \"youtube\"\n\n- id: \"julian-pinzon-eslava-rubyconf-au-2023\"\n  title: \"All You Need is Rails (Engines) - Compartmentalising Your Monolith\"\n  raw_title: \"All you need is Rails (Engines) - Compartmentalising your Monolith\"\n  speakers:\n    - Julián Pinzón Eslava\n  description: |\n    As much as Rails is all in on Convention over Configuration, there comes a point where there is just so much code, such intricate relationships between classes and such complex business requirements that conventions don't seem to fit anymore. It seems like the only solution is to abandon the Majestic Monolith and use micro services.\n\n    However, there is an answer to this. An answer that's been there for a very long time, right under our noses. One that allows Ruby on Rails developers to keep growing a beautiful, sustainable and scalable Monoliths and ride with them to the sunset.\n\n    The answer is Rails Engines.\n\n    Like… Devise or Spree?\n\n    Not quite. In this talk you'll learn a whole new perspctive on Rails Engines; a much lighter and leaner way to use them that allow teams to break up their app into meaningful modules without losing the beauty of Rails' conventions. Sprinkle in the Packwerk Gem by Shopify for the perfect combo to scale your domain and your team.\n  date: \"2023-02-16\"\n  published_at: \"2023-02-16\"\n  video_id: \"StDoHXO8H6E\"\n  video_provider: \"youtube\"\n\n- id: \"prakriti-mateti-rubyconf-au-2023\"\n  title: \"REACT to Imposter Syndrome\"\n  raw_title: \"REACT to Imposter Syndrome\"\n  speakers:\n    - Prakriti Mateti\n  description: |\n    70% of people worldwide have felt like an imposter at some point in their career. 46% respondents to a women-in-tech survey agreed that help overcoming imposter syndrome would make them happier and more successful. Do you worry sometimes that you're not as smart as the other people in your organisation? Or that you won't be able to keep up and they'll find out that you don't really belong there? Do you stress out about living up to the expectations of the people you manage?\n\n    People working in tech, including those in leadership positions, often struggle to overcome prejudice and lack of privilege but still end up feeling like they don't belong, like they are a fraud, even when they're achieving success and making an impact. Imposter syndrome can affect people at any stage in their career - whether they're an intern or in a senior leadership or executive role.\n\n    In this talk I'll go over personal experiences with imposter syndrome and practical strategies I've developed that anyone can apply to banish imposter thoughts and prevent them from getting in the way of your success, career progression, mental health, and happiness at work. An easy to remember acronym (REACT) with 5 realistic steps you can take away and practice can help you create a more accurate representation of your performance. You can take these steps away for yourself, or if you are a people leader, use them to help coach your people through the confusing world of imposter syndrome.\n  date: \"2023-02-16\"\n  published_at: \"2023-02-16\"\n  video_id: \"Ee0QCyRuwCU\"\n  video_provider: \"youtube\"\n\n# Afternoon Tea\n\n- id: \"hilary-stohs-krause-rubyconf-au-2023\"\n  title: \"How to Make Your Website Not Ugly - Basic UX for Programmers\"\n  raw_title: \"How to Make Your Website Not Ugly - Basic UX for Programmers\"\n  speakers:\n    - Hilary Stohs-Krause\n  description: |\n    If you're a programmer who has ever found themselves inadvertently (perhaps unwillingly!) straddling the line between design and code, this is the talk for you.\n\n    Even with zero design training or background, there are numerous small, simple and practical ways you can vastly improve the look and usability of a website.\n\n    In this talk, we'll explore 10 of them together, using research and proven solutions to see how the impact as a whole for both clients and users is greater than the sum of its parts.\n  date: \"2023-02-16\"\n  published_at: \"2023-02-19\"\n  video_id: \"zkrRd5itj8w\"\n  video_provider: \"youtube\"\n\n- id: \"nate-berkopec-rubyconf-au-2023\"\n  title: \"How Puma Works\"\n  raw_title: \"How Puma Works\"\n  speakers:\n    - Nate Berkopec\n  description: |-\n    Have you ever wondered how Puma (or other webservers) work? Let's explore the internals of how a pre-forking webserver like Puma buffers and processes requests, what Rack is and how Puma uses it to interact with Rails, and how Puma's multi-threaded and parallel design works in practice.\n  date: \"2023-02-16\"\n  published_at: \"2023-02-16\"\n  video_id: \"SquGNt4FhY0\"\n  video_provider: \"youtube\"\n\n# Close\n\n## Day 2 - Friday, 2023-02-17\n\n# Registration and Coffee\n\n- id: \"coraline-ada-ehmke-rubyconf-au-2023\"\n  title: \"The World Set Free\"\n  raw_title: \"The World Set Free\"\n  speakers:\n    - Coraline Ada Ehmke\n  description: |-\n    In an age of algorithmic manipulation, surveillance capitalism, privacy erosion, rising fascism, and impending climate disaster, it's easy to fall prey to despair, to grimly accept our slide into an inevitable dystopian future. But there is another way. The philosophy of techno-optimism challenges us to imagine alternate futures in which technology helps promote broad social good. This talk applies a literary lens, by way of an early 20th century \"future history\" by H. G. Wells, to explore our evolving relationship with world-changing technologies, and help us imagine &mdash; and build toward &mdash; a future we can all not just survive in, but truly thrive in.\n  date: \"2023-02-17\"\n  published_at: \"2023-02-17\"\n  video_id: \"SG759w1qfpI\"\n  video_provider: \"youtube\"\n\n- id: \"jemma-issroff-rubyconf-au-2023\"\n  title: \"Implementing Object Shapes for CRuby\"\n  raw_title: \"Implementing Object Shapes for CRuby\"\n  speakers:\n    - Jemma Issroff\n  description: |\n    The Ruby 3.2 release includes a new technique for for representing objects' properties that can increase cache hits in instance variable lookups, decrease runtime checks, and improve JIT performance. This technique is called \"Object Shapes.\" In this talk, we'll learn how object shapes work, why we implemented them for Ruby 3.2, and interesting implementation details.\n\n    If you're curious to learn more about Ruby internals, or how instance variables work, this talk is for you!\n  date: \"2023-02-17\"\n  published_at: \"2023-02-18\"\n  video_id: \"0lg9Y8gj3FI\"\n  video_provider: \"youtube\"\n\n# Morning Tea\n\n- id: \"fiona-mccawley-rubyconf-au-2023\"\n  title: \"Encrypted Search Party\"\n  raw_title: \"Encrypted Search Party\"\n  speakers:\n    - Fiona McCawley\n  description: |\n    Recently I've been working in Rails applications where protecting sensitive data is a priority. But keeping data secure sometimes comes at the cost of utility. The types of queries you can execute can be limited.\n\n    In this talk, I'll share what I've been learning about application level encryption, and an encryption scheme called Order Revealing Encryption (ORE).\n\n    ORE enables querying capabilities while still keeping data encrypted when in use. I'll be demonstrating ORE's capabilities using a toy ORE library that I have built in Ruby.\n  date: \"2023-02-17\"\n  published_at: \"2023-02-18\"\n  video_id: \"lp0k94sUwI8\"\n  video_provider: \"youtube\"\n\n- id: \"tim-riley-rubyconf-au-2023\"\n  title: \"Hanami 2 - New Framework, New You\"\n  raw_title: \"Hanami 2 - New Framework, New You\"\n  speakers:\n    - Tim Riley\n  description: |\n    Years in the making, Hanami 2.0 is out! This release brings new levels of polish and power to a framework you can use for Ruby apps of all shapes and sizes.\n\n    Come along to discover what goes into building a new Hanami app, the principles that underpin the framework, and how they just might change the way you work with Ruby altogether.\n  date: \"2023-02-17\"\n  published_at: \"2023-02-18\"\n  video_id: \"-B9AbFsQOKo\"\n  video_provider: \"youtube\"\n\n- id: \"colleen-lavin-rubyconf-au-2023\"\n  title: \"A People Pleaser's Guide to Salary Negotiation\"\n  raw_title: \"A People Pleaser's Guide to Salary Negotiation\"\n  speakers:\n    - Colleen Lavin\n  description: |\n    Negotiating salaries is hard. It's harder if you always want people to like you. If you fall behind your peers and don't reach your full earning potential.\n\n    This talk demystifies negotiation and empowers the attendees to earn as much as their peers while staying true to their personality.\n  date: \"2023-02-17\"\n  published_at: \"2023-02-18\"\n  video_id: \"4EoMYQ6fmss\"\n  video_provider: \"youtube\"\n\n# Lunch\n\n- id: \"geoffrey-donaldson-rubyconf-au-2023\"\n  title: \"Aussie Internet - How We Learned To Stop Fearing The NBN and Love the SPA\"\n  raw_title: \"Aussie Internet - How we learned to stop fearing the NBN and love the SPA\"\n  speakers:\n    - Geoffrey Donaldson\n  description: |-\n    Having performant queries means nothing if your customers can't load them. Slow internet is a reality for many Aussies, especially in rural areas. This is even more challenging when building interactive data-visualisation tools. Learn how we adopted modern web tech to deliver, even when NBN doesn't.\n  date: \"2023-02-17\"\n  published_at: \"2023-02-18\"\n  video_id: \"EvT_hsTjgfg\"\n  video_provider: \"youtube\"\n\n- id: \"igor-kapkov-rubyconf-au-2023\"\n  title: \"Testing in Production: There is a Better Way\"\n  raw_title: \"Testing in Production: there is a better way\"\n  speakers:\n    - Igor Kapkov\n  description: |-\n    Testing in Production is a common CI/CD practice nowadays. However, feature flags and canary deployments can only get you so far. This talk will walk you through the [Branch By Abstraction](https://martinfowler.com/bliki/BranchByAbstraction.html) pattern and the tools to give you confidence when shipping your code to production because we should be able to move fast and break nothing.\n  date: \"2023-02-17\"\n  published_at: \"2023-02-18\"\n  video_id: \"OWICpZ_8KJk\"\n  video_provider: \"youtube\"\n\n- id: \"sameera-gayan-rubyconf-au-2023\"\n  title: \"Mentoring - For me or not for me, that is the question\"\n  raw_title: \"Mentoring - For me or not for me, that is the question\"\n  speakers:\n    - Sameera Gayan\n  description: |\n    Mentoring - For me or not for me, that is the question!\n\n    \"Tell me and I forget,\n    teach me and I remember,\n    involve me and I learn.\"\n    &ndash; Xunzi (Xun Kuang)\n\n    From the day you start as a Developer, to the point you achieve your highest career goal your journey is about transformation and that like anything else relies on HELP. Being a good mentor/community contributor will change the lives of others in ways you never even think of.\n\n    Let me share a thing or two I learnt about being a mentor and helping the community over the years.\n  date: \"2023-02-17\"\n  published_at: \"2023-02-18\"\n  video_id: \"uuLl8W1sz60\"\n  video_provider: \"youtube\"\n\n# Afternoon Tea\n\n- id: \"wiktoria-dalach-rubyconf-au-2023\"\n  title: \"Security Doesn't Have To Be a Nightmare\"\n  raw_title: \"Security Doesn't Have To Be a Nightmare\"\n  speakers:\n    - Wiktoria Dalach\n  description: |\n    How to build secure products? After 9 years of coding, I moved to the security team where I discovered a better, more manageable approach to security.\n\n    From my talk, you will learn how to design with security in mind so that security isn't a blocker but an enabler for innovation.\n  date: \"2023-02-17\"\n  published_at: \"2023-02-18\"\n  video_id: \"-VuM4FMIgT4\"\n  video_provider: \"youtube\"\n\n- id: \"bianca-power-rubyconf-au-2023\"\n  title: \"Ruby Makes My Brain Happy\"\n  raw_title: \"Ruby Makes My Brain Happy\"\n  speakers:\n    - Bianca Power\n  description: |\n    Why is Ruby more fun than JS or Python? Why might a JS dev disagree? Different people have different ways of processing the world - does that mean there's a language that `best fits` your brain? Let's explore this idea, touching on learning theories and implications for getting people into coding.\n\n    Having learnt and taught Ruby, Python, JavaScript, and a bit of C to hundreds of career changers - and teaching alongside dozens of experienced developers over the years - I have seen over and over the passion that someone can feel for one particular programming language over another. I've also felt it myself - when I'm coding in Ruby, I can feel it fitting in my brain, and I can feel it actually making me happier in a way that no other language quite does.\n\n    Drawing on my background in education and experience teaching and managing coding bootcamps, this talk will explore the relationship between how we as individuals see and process the world around us, and the languages and paradigms we work in as developers.\n\n    Implications for how we understand and work with our colleagues will be discussed - both those new to the industry and seasoned professionals, as well as how this can help us to understand ourselves as developers and lifelong learners.\n  date: \"2023-02-17\"\n  published_at: \"2023-02-18\"\n  video_id: \"VOJS_Jq_Eg4\"\n  video_provider: \"youtube\"\n# Closing Remarks\n\n# Closing Cocktail Party - Sponsored By HotDoc\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2024/cfp.yml",
    "content": "---\n- link: \"https://sessionize.com/rubyconf-au-2024\"\n  open_date: \"2023-11-14\"\n  close_date: \"2024-01-12\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2024/event.yml",
    "content": "---\nid: \"PL9_jjLrTYxc26AtvP5jUHGHqWe5EoVLYf\"\ntitle: \"RubyConf AU 2024\"\nkind: \"conference\"\nlocation: \"Sydney, Australia\"\ndescription: |-\n  11th-12th April 2024, Swissôtel Sydney\npublished_at: \"2024-04-19\"\nstart_date: \"2024-04-11\"\nend_date: \"2024-04-12\"\nchannel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nyear: 2024\nbanner_background: \"#FCFAED\"\nfeatured_background: \"#FCFAED\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: -33.8702647\n  longitude: 151.2074559\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2024/venue.yml",
    "content": "---\nname: \"Swissôtel Sydney\"\n\naddress:\n  street: \"68 Market Street\"\n  city: \"Sydney\"\n  region: \"New South Wales\"\n  postal_code: \"2000\"\n  country: \"Australia\"\n  country_code: \"AU\"\n  display: \"68 Market St, Sydney NSW 2000, Australia\"\n\ncoordinates:\n  latitude: -33.8702647\n  longitude: 151.2074559\n\nmaps:\n  google: \"https://maps.google.com/?q=Swissôtel+Sydney,-33.8702647,151.2074559\"\n  apple: \"https://maps.apple.com/?q=Swissôtel+Sydney&ll=-33.8702647,151.2074559\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=-33.8702647&mlon=151.2074559\"\n"
  },
  {
    "path": "data/rubyconf-au/rubyconf-au-2024/videos.yml",
    "content": "---\n# Website: https://2024.rubyconf.au\n# Schedule: https://2024.rubyconf.au/schedule/#Schedule\n\n## Day 0 - Wednesday - 2024-04-10\n\n# Ruby In Common Unconference @ Microsoft Reactor\n\n# Welcome and Pre-Registration @ Squire's Landing\n\n# WNB.rb Meetup @ Artsicle\n\n## Day 1 - Thursday - 2024-04-11\n\n# Registration & Coffee Open\n\n# Conference Welcome\n\n- id: \"hiroshi-shibata-rubyconf-au-2024\"\n  title: \"Long Journey of Ruby Standard Library\"\n  raw_title: \"Hiroshi Shibata - Long journey of Ruby standard library\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-11\"\n  published_at: \"2024-04-19\"\n  description: |-\n    Ruby has many standard libraries since Ruby 1.8. We are developing them with GitHub today using default and bundled gems mechanism. I plan to continue this process for Ruby 3.4 and future versions.\n\n    However, some versions may encounter `LoadError` at `require` when running `bundle exec` or `bin/rails`, for example with `matrix` or `net-smtp`. We need to understand how they differ from standard libraries.\n\n    In this presentation, I will explain how Ruby's `require` and `bundle exec` work with default/bundled gems. I will also suggest what users can do to load them successfully.\n  video_provider: \"youtube\"\n  video_id: \"HB_Qa1sE2kM\"\n\n- id: \"ryan-bigg-rubyconf-au-2024\"\n  title: \"Magic is Ruby, Ruby is Magic!\"\n  raw_title: \"Ryan Bigg - Magic is Ruby, Ruby is Magic!\"\n  speakers:\n    - Ryan Bigg\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-11\"\n  published_at: \"2024-04-19\"\n  description: |-\n    Magic: The Gathering is a popular card game with over 20,000 unique cards where the cards themselves define the rules of the game.\n\n    Can we write a Ruby app to simulate games of Magic: The Gathering? This is the story of one man's attempt to do just that.\n  video_provider: \"youtube\"\n  video_id: \"btIbue1JkA0\"\n\n# Morning Tea\n\n- id: \"dmitry-sadovnikov-rubyconf-au-2024\"\n  title: \"Scaling Ruby Applications: Challenges, Solutions and Best Practices\"\n  raw_title: \"Dmitry Sadovnikov - Scaling Ruby Applications: Challenges, Solutions and Best Practices\"\n  speakers:\n    - Dmitry Sadovnikov\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-11\"\n  published_at: \"2024-04-19\"\n  description: |-\n    This presentation covers scaling Ruby applications using lessons learned over eight years. First, it touches on the importance of managing on-call duties, such as addressing incidents, fixing errors, and performing updates. The talk then moves to the topic of team structure, detailing roles such as domain lead and architect, and ways to split larger groups into smaller, agile teams.\n\n    The presentation also covers application updates, discussing methods like soft updates, force updates, and feature toggles. A focus on secure data management includes best practices for data encryption and protecting customer's data.\n\n    The importance of clear, understandable documentation will also be discussed, along with strategies for fostering a testing culture in development teams and applying UML schemas before starting development.\n\n    Optimising the developer experience is essential for productivity - so the presentation explores ways to collect and implement developers' ideas. Finally, it explains how to use modern technologies to speed up releases, track success metrics, perform regular stress testing, and ensure ongoing security.\n\n    This presentation aims to help you navigate the complexities of scaling Ruby applications, saving both time and resources in your operations.\n  video_provider: \"youtube\"\n  video_id: \"iBhCEvFR6zk\"\n\n- id: \"georgina-robilliard-rubyconf-au-2024\"\n  title: \"What I Learned From A Clown About Engineering Culture\"\n  raw_title: \"Georgina Robilliard & Stefan Bramble - What I learned from a clown about engineering culture\"\n  speakers:\n    - Georgina Robilliard\n    - Stefan Bramble\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-11\"\n  published_at: \"2024-04-19\"\n  description: |-\n    Culture is complex. Startups grow. So how do we build an effective organisation that gets shit done, and the people doing the work love what they do and where they work. We know a secret! It came from a clown, and is backed up by the science. It’s a word we have lost the true meaning of.. it’s play. Come and listen to how a head of people and a clown helped co-create a company culture grounded in play that navigated the waters of remote working, global expansion and high growth… while the world was going through some things. This talk is going to be weird, fun and above all super useful.\n  video_provider: \"youtube\"\n  video_id: \"YRhFZG6mX5g\"\n\n# Lunch\n\n- id: \"mandy-michael-rubyconf-au-2024\"\n  title: \"Advanced HTML for Performance & Accessibility\"\n  raw_title: \"Mandy Michael - Advanced HTML for Performance & Accessibility\"\n  speakers:\n    - Mandy Michael\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-11\"\n  published_at: \"2024-04-19\"\n  description: |-\n    HTML is not just the foundation we build on, it's vital in making our websites accessible, usable and performant.\n\n    We'll explore how we can make the most of our HTML elements and attributes to improve the performance and accessibility of our website and applications as well as boosting the efficiency of our development process.\n\n    All by using a technology we are already use day to day, but just using it better than we were before. At the end of the talk you'll be able to make things more useful and usable, not just for performance and accessibility but for our users and different technologies as well.\n  video_provider: \"youtube\"\n  video_id: \"Qv8hjid6WDI\"\n\n- id: \"mu-fan-teng-rubyconf-au-2024\"\n  title: \"Reconstructing Taiwan’s Internet-Based Party Politics\"\n  raw_title: \"Mu Fan Teng - Reconstructing Taiwan’s Internet-Based Party Politics\"\n  speakers:\n    - Mu-Fan Teng\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-11\"\n  published_at: \"2024-04-19\"\n  description: |-\n    In an era where most activities in life can be executed online, the majority of countries still lack the ability to interact politically via the internet, such as online voting, party membership registration, and petition signing.\n\n    In Taiwan, a political party named “New Power Party” has, since its establishment in 2015, relied on volunteers to develop a complete system enabling online party membership, donations, and voting. After several years of developing and operating in a dynamic and evolving manner, the system accumulated substantial technical debt. This led to issues with proper and complete system functionality and maintenance, impacting the party’s operations. Eventually, we decided to re-evaluate the specifications and rebuild the entire system using the latest versions of Ruby and Rails.\n\n    In this session, I will explore the process of revamping an outdated Rails application, lacking in testing and specification documentation, with the new Ruby 3 and Rails 7. This will include code refactoring, selecting the Runtime Stack, and integrating automated deployment processes using Ruby-based tools. I will also share practical experiences and reflections on integrating data from old and new versions and relaunching the system.\n  video_provider: \"youtube\"\n  video_id: \"rGBgTCILW3k\"\n\n- id: \"elle-meredith-rubyconf-au-2024\"\n  title: \"Exploring Rails anti-patterns\"\n  raw_title: \"Elle Meredith - Exploring Rails anti-patterns\"\n  speakers:\n    - Elle Meredith\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-11\"\n  published_at: \"2024-04-19\"\n  description: |-\n    Is your Rails app sluggish? Does its performance suffer? Even with the best intentions, Rails applications can become littered with anti-patterns that negatively affect developer velocity, code clarity, and maintenance. Following a few simple patterns and strategies, you can transform your Rails application code to become more robust and functional. One that will be easier to extend and maintain. This talk will explore anti-patterns in practice and suggest fixes to ensure your Rails project is a success.\n  video_provider: \"youtube\"\n  video_id: \"Ndn49iqnzn8\"\n\n- id: \"prakriti-mateti-rubyconf-au-2024\"\n  title: \"One does not simply... rebuild a product\"\n  raw_title: \"Prakriti Mateti - One does not simply... rebuild a product\"\n  speakers:\n    - Prakriti Mateti\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-11\"\n  published_at: \"2024-04-19\"\n  description: |-\n    \"A rebuild is never finished, only started\"\n    \"Technical rebuilds are doomed to fail\"\n    \"One does not simply walk into Mordor\"\n\n    We're rebuilding Culture Amp's second largest product - Performance. It's 9 years old, came in as a Series A acquisition 5 years ago, has over 2700 customers with the largest one at 77k users. Against conventional wisdom, we're rebuilding it from the ground up with an aggressive timeline. The underlying model is outdated, slow to iterate on, and not extensible. The monoliths are riddled with tech debt, tightly coupled, patched and band-aided over many times, and won't scale to the $3b global Performance market we're targeting.\n\n    That wasn't challenging enough already I'm also using this opportunity to rebuild our engineering culture. Setting a high bar for engineering standards, ways of working, and hoping to improve engagement as we go.\n  video_provider: \"youtube\"\n  video_id: \"NHIeIQtel7E\"\n\n# Afternoon Tea\n\n- id: \"vishwajeetsingh-desurkar-rubyconf-au-2024\"\n  title: \"Concurrency Showdown: Threads vs. Fibers\"\n  raw_title: \"Vishwajeetsingh Desurkar & Ishani Trivedi - Concurrency Showdown: Threads vs. Fibers\"\n  speakers:\n    - Vishwajeetsingh Desurkar\n    - Ishani Trivedi\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-11\"\n  published_at: \"2024-04-19\"\n  description: |-\n    Our conference talk explores the subtle yet impactful enhancements in concurrency in Ruby 3.0. Through optimized Global VM Lock handling, upgraded fiber scheduling, and language improvements, we will demonstrate how these enhancements profoundly influence parallel tasks and boost efficiency in concurrent Ruby applications. Attendees will gain insights into the interplay between Ruby's language upgrades and concurrency optimizations, empowering them with effective strategies to maximize performance. Join us for a comprehensive understanding of concurrency in Ruby 3.0's models and their real-world impact.\n  video_provider: \"youtube\"\n  video_id: \"kU22NJq1sS0\"\n\n- id: \"charles-nutter-rubyconf-au-2024\"\n  title: \"Ruby on the Modern JVM with JRuby\"\n  raw_title: \"Charles Nutter - Ruby on the Modern JVM with JRuby\"\n  speakers:\n    - Charles Nutter\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-11\"\n  published_at: \"2024-04-19\"\n  description: |-\n    JRuby has been the go-to option for high performance, scalable Ruby applications for over a decade, bringing world-class garbage collection, jit compilation, and concurrency to Ruby and Rails developers. With the release of Java 22, we now have true native fibers, fast native function and memory support, and fast startup and warm up are on the horizon. This talk will show you how to get started with JRuby and why it's so exciting for the Ruby community.\n  video_provider: \"youtube\"\n  video_id: \"rVUzQGv-icc\"\n\n# Close\n\n# Manly Adventure @ Manly Wharf Bar\n\n## Day 2 - Friday - 2024-04-12\n\n# Registration & Coffee Open\n\n# Welcome\n\n- id: \"bronwen-zande-rubyconf-au-2024\"\n  title: \"Data Unleashed: A Developer's Perspective on Navigating the Architecture Maze\"\n  raw_title: \"Bronwen Zande - Data Unleashed: A Developer's Perspective on Navigating the Architecture Maze\"\n  speakers:\n    - Bronwen Zande\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-04-19\"\n  description: |-\n    In today's data-driven world, organisations recognise the immense value of data as a strategic asset. With the potential to revolutionize decision-making, enhance operational efficiency, and provide a competitive edge, effective data management has become paramount. However, the ever-expanding range of data architectures and philosophies presents a challenge when determining the most suitable approach.\n    In this talk, we will look at the landscape of data architectures and philosophies from the perspective of a developer. We delve into the key players: databases, data warehouses, data factories, data lakes, and data meshes. We aim to illuminate the strengths and weaknesses of each architecture, enabling you to make informed choices for your organisation's data strategy.\n    Join us as we compare and contrast these architectures, unveiling the unique capabilities they offer. Choosing the right data architecture and philosophy is no easy feat. That's why we'll equip you with the necessary insights and learnings to navigate this complex decision-making process. Learn how to align your organisation's unique needs as we discuss the factors to consider, such as scalability, practicality, data retention, integration requirements, and latency.\n  video_provider: \"youtube\"\n  video_id: \"ZEqsdfa5Z78\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/ZEqsdfa5Z78/mqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/ZEqsdfa5Z78/mqdefault.jpg\"\n\n- id: \"chris-oliver-rubyconf-au-2024\"\n  title: \"Mapping Concepts Into Code\"\n  raw_title: \"Chris Oliver - Mapping Concepts Into Code\"\n  speakers:\n    - Chris Oliver\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-04-19\"\n  description: |-\n    Implementing a feature like \"notifications\" in an app sounds simple, right? As you dig in to problems like this, you'll realize the complexity that lies below the surface.\n\n    In this talk, we'll walk through designing a feature like Notifications and how naming, DSLs, metaprogramming, and a bunch of other small decisions can make code feel delightful to use. Plus, we'll take a look at some of the decisions along the way that didn't turn out so well, analyze why they didn't work, and how we can improve them.\n  video_provider: \"youtube\"\n  video_id: \"DF6hZVHQTjo\"\n  thumbnail_lg: \"https://i3.ytimg.com/vi/DF6hZVHQTjo/mqdefault.jpg\"\n  thumbnail_xl: \"https://i3.ytimg.com/vi/DF6hZVHQTjo/mqdefault.jpg\"\n\n# Morning Tea\n\n- id: \"kieran-andrews-rubyconf-au-2024\"\n  title: \"Junior Gems: Hiring, Valuing, and Empowering the Next Wave of Ruby Developers\"\n  raw_title: \"Kieran Andrews - Junior Gems: Hiring, Valuing, and Empowering the Next Wave of Ruby Developers\"\n  speakers:\n    - Kieran Andrews\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-04-19\"\n  description: |-\n    Remember Ryan's inspiring talk in 2018 about the magic of hiring junior developers? It definitely struck a chord with me, leading me to bring numerous juniors on board since then. Their fresh perspectives have been game-changers, sparking innovation and enriching our team's dynamics and skillset.\n\n    In my talk, I’ll dive into the ‘how-tos’ of finding and integrating these rising stars into your team, especially in a remote setting. We'll explore effective mentoring strategies, and I’ll share my playbook on crafting an onboarding process that truly resonates. You’ll learn the art of teaching vital skills that transform juniors into invaluable team players.\n\n    We'll talk about creating a nurturing space where regular feedback and one-on-one sessions are the norm. I'll guide you through the balancing act of challenging your juniors - hitting that sweet spot where it's neither overwhelming nor underwhelming. It's about finding the right rhythm that fosters growth.\n\n    And here’s a twist: this journey isn’t just about the juniors. It’s a fantastic opportunity for your senior members to level up as well, evolving into mentors and leaders. My talk isn’t just a guide; it's a story of growth, learning, and collective success. Let’s explore how junior developers can be your team’s next great asset.\n  video_provider: \"youtube\"\n  video_id: \"YAMEgkLKafA\"\n\n- id: \"tash-postolovski-rubyconf-au-2024\"\n  title: \"A Software Developer's Guide to Launching Your Own Product\"\n  raw_title: \"Tash Postolovski - A Software Developer's Guide to Launching Your Own Product\"\n  speakers:\n    - Tash Postolovski\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-04-19\"\n  description: |-\n    This talk focuses on practical, step-by-step instructions to help full-time software developers start their own product business on the side. Whether you have a product idea or are still looking, this talk will take you through the process of coming up with an idea, testing it, building it, and finding your first paying customers.\n  video_provider: \"youtube\"\n  video_id: \"abifIOByKuU\"\n\n- id: \"andrey-novikov-rubyconf-au-2024\"\n  title: \"Threads, callbacks, and execution context in Ruby\"\n  raw_title: \"Andrew Novikov - Threads, callbacks, and execution context in Ruby\"\n  speakers:\n    - Andrey Novikov\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-04-19\"\n  description: |-\n    When you provide a block to a function in Ruby, do you know when and where that block will be executed? What is safe to do inside a block, and what is dangerous? What is a block, after all? Blocks in Ruby are everywhere, and we’re so used to them that we may even be ignorant of all their power and complexity. Let’s take a look at various code examples and understand what dragons are hidden in Ruby dungeons.\n\n    Ruby programmers usually don't need to think much about blocks… until they have to. As a contributor to Ruby gems that have callback-based API for developers, I've found that internal implementation details of these gems affects how these callbacks are executed and resulting behavior can be quite surprising sometimes, and I think that good Ruby developer should know inner workings of blocks to better understand execution flow of complex Ruby programs.\n  video_provider: \"youtube\"\n  video_id: \"y4e_sXubhyI\"\n\n# Lunch\n\n- id: \"bianca-power-rubyconf-au-2024\"\n  title: \"Retinas on Rails! - Eye spy with my little eye Macuject\"\n  raw_title: \"Bianca Power & Bradley Beddoes - Retinas on Rails! - Eye spy with my little eye Macuject\"\n  speakers:\n    - Bianca Power\n    - Bradley Beddoes\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-04-19\"\n  description: |-\n    Macuject is an Australian digital health startup helping prevent blindness by supporting eye care professionals in achieving the best possible outcomes for their patients with diseases such as age-related macular degeneration (AMD).\n    Our presentation will give an overview of the eye's structure, straightforward steps to ensure the health of your eyes, AMD, its treatment, and how our software helps make individualised decisions. It is sure to be a real eye-opener!\n\n    After that, we’ll switch lenses to discuss our technology stack, primarily focusing on our Majestic Monolith powered by Rails 7! As a MedTech startup, the experience doctors have when interacting with our app can have a considerable impact. Over the past year, we've improved that experience dramatically through using Hotwire. We’ll share how our small team is gradually replacing our React frontend with Hotwire while rapidly building eye-popping new features.\n\n    With Turbo Frames, Turbo Streams, and Stimulus, Hotwire lets us rethink when to use JavaScript and allows us to use just the amount we need, where we need it. It allows us the flexibility we want, with all the functionality we need, in a Rails-friendly paradigm that's a delight to work with.\n\n    What do you call a Deer with no eyes? We have no Eye-Deer, but we look forward to seeing you at our talk!\n  video_provider: \"youtube\"\n  video_id: \"lrc1D6hiQRw\"\n\n- id: \"kj-tsanaktsidis-rubyconf-au-2024\"\n  title: \"Scaling Redis writes with cluster mode\"\n  raw_title: \"KJ Tsanaktsidis - Scaling Redis writes with cluster mode\"\n  speakers:\n    - KJ Tsanaktsidis\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-04-19\"\n  description: |-\n    When a single Redis instance is not enough, Redis offers a number of different options for scaling out to multiple nodes, with different tradeoffs for read/write throughput and availability. At Zendesk, we have migrated to Redis cluster mode for one of our write-heavy workloads.\n\n    We found, however, that simply flipping the switch to turn on cluster mode did not quite work as we'd hoped! This talk will cover our journey of getting Redis Cluster to work properly with our Ruby monolith; in particular:\n\n    * How Redis cluster mode works, and what it requires of language-specific client libraries, and\n    * How we added support for missing features we needed into the redis-cluster-client gem\n\n    Redis Cluster should now be a solid choice for your Ruby applications as well!\n  video_provider: \"youtube\"\n  video_id: \"CBl2zzW-ELQ\"\n\n# Special Announcements & Surprise Session\n\n# Afternoon Tea\n\n- id: \"maple-ong-rubyconf-au-2024\"\n  title: \"Lessons From A Rails Infrastructure Team\"\n  raw_title: \"Maple Ong - Lessons From A Rails Infrastructure Team\"\n  speakers:\n    - Maple Ong\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-04-19\"\n  description: |-\n    Ruby on Rails is growing! As a Rails company grows, the application too becomes larger as more engineers work on it at the same time. There is an increasing need for companies to build out a \"Rails Infrastructure\" team. The team’s primary goal is to ensure the long-term success of the application and its engineers. But how?\n\n    Let’s talk about the responsibilities and philosophy behind such a team. These learnings are from working on a team that supports 400+ engineers at one of the largest Rails applications. You’ll get some insight on what our team does in order to ensure a Rails application scales with its growth. Spoiler: There’s more to just enforcing Rubocop rules!\n  video_provider: \"youtube\"\n  video_id: \"DWwm9d1NG58\"\n\n- id: \"kane-hooper-rubyconf-au-2024\"\n  title: \"Giving My Wife a Voice with Ruby and AI Cloning (+ Discussion on The AI and Ruby Landscape)\"\n  raw_title: \"Kane Hooper - Giving my wife a voice with Ruby and AI cloning (+ discussion)\"\n  speakers:\n    - Kane Hooper\n  event_name: \"RubyConf AU 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-04-19\"\n  description: |-\n    Last year my wife was diagnosed with a neurological condition causing her to lose 80% of her speech capacity. Through the use of AI voice cloning technology and Ruby in the backend I was able to build an application that has given her back her voice. In this talk I will walk through the AI voice cloning technology and the key Ruby code to build an application that utilises her own voice.\n\n    We will also look at the overall AI landscape, what tools and technologies (particularly open-source) can be integrated into Ruby applications.\n  video_provider: \"youtube\"\n  video_id: \"bkOpAXrzEls\"\n## Day 3 - Saturday - 2024-04-13\n\n# Rails Girls Sydney\n\n# Casual Coffee\n"
  },
  {
    "path": "data/rubyconf-au/series.yml",
    "content": "---\nname: \"RubyConf AU\"\nwebsite: \"https://www.rubyconf.org.au/\"\ntwitter: \"rubyconf_au\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"RubyConf AU\"\nyoutube_channel_name: \"RubyAustralia\"\nyoutube_channel_id: \"UCr38SHAvOKMDyX3-8lhvJHA\"\nlanguage: \"english\"\naliases:\n  - Ruby Conf AU\n  - RubyConf Australia\n  - Ruby Conf Australia\n"
  },
  {
    "path": "data/rubyconf-austria/rubyconf-austria-2026/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/rubyconfaustria2026\"\n  open_date: \"2025-07-13\"\n  close_date: \"2025-12-01\"\n"
  },
  {
    "path": "data/rubyconf-austria/rubyconf-austria-2026/event.yml",
    "content": "---\nid: \"rubyconf-austria-2026\"\ntitle: \"RubyConf Austria 2026\"\ndescription: |-\n  The first edition of RubyConf Austria will be held at Das MuTh theater in Vienna.\nlocation: \"Vienna, Austria\"\nkind: \"conference\"\nstart_date: \"2026-05-29\"\nend_date: \"2026-05-31\"\nwebsite: \"https://rubyconf.at\"\nbanner_background: \"#E20818\"\nfeatured_background: \"#E20818\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 48.2200194\n  longitude: 16.3800359\n"
  },
  {
    "path": "data/rubyconf-austria/rubyconf-austria-2026/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Muhamed Isabegović\n\n- name: \"Programm Comittee Member\"\n  users:\n    - Hans Schnedlitz\n    - Christoph Lipautz\n    - Rosa Gutiérrez\n    - Carmen Huidobro\n    - Zuzanna Kusznir\n    - Adrian Marin\n    - Stephen Margheim\n    - Paul Campbell\n    - Yudai Takada\n    - Lucian Ghindă\n    - Johannes Daxböck\n    - Abdelkader Seuros Boudih\n"
  },
  {
    "path": "data/rubyconf-austria/rubyconf-austria-2026/venue.yml",
    "content": "---\nname: \"Das MuTh\"\n\naddress:\n  street: \"1 Am Augartenspitz\"\n  city: \"Wien\"\n  region: \"Wien\"\n  postal_code: \"1020\"\n  country: \"Austria\"\n  country_code: \"AT\"\n  display: \"Am Augartenspitz 1, 1020 Wien, Austria\"\n\ncoordinates:\n  latitude: 48.2200194\n  longitude: 16.3800359\n\nmaps:\n  google: \"https://maps.google.com/?q=Das+MuTh,48.2200194,16.3800359\"\n  apple: \"https://maps.apple.com/?q=Das+MuTh&ll=48.2200194,16.3800359\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=48.2200194&mlon=16.3800359\"\n"
  },
  {
    "path": "data/rubyconf-austria/rubyconf-austria-2026/videos.yml",
    "content": "# Website: https://rubyconf.at\n# Videos: -\n---\n# Day 1 - May 29th (Haus Der Musik)\n\n- id: \"marco-roth-rubyconf-austria-2026\"\n  title: \"Herb & ReActionView: Mid-2026 Progress Update\"\n  speakers:\n    - Marco Roth\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-29\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"marco-roth-rubyconf-austria-2026\"\n\n- id: \"maedi-prichard-rubyconf-austria-2026\"\n  title: \"Introducing Raindeer\"\n  speakers:\n    - Maedi Prichard\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-29\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"maedi-prichard-rubyconf-austria-2026\"\n\n- id: \"bozhidar-batsov-rubyconf-austria-2026\"\n  title: \"RuboCop 2.0: Where do we go now?\"\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-29\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"bozhidar-batsov-rubyconf-austria-2026\"\n\n- id: \"panel-discussion-rubyconf-austria-2026\"\n  title: \"Panel Discussion\"\n  speakers:\n    - Chad Fowler\n    - José Valim\n    - Obie Fernandez\n    - Armin Ronacher\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-29\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"panel-discussion-rubyconf-austria-2026\"\n\n# Day 2 - May 30th (Das MuTh)\n\n- id: \"chad-fowler-rubyconf-austria-2026\"\n  title: \"Opening Keynote\"\n  speakers:\n    - Chad Fowler\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-07-14 13:39:00 UTC\"\n  description: \"\"\n  kind: \"keynote\"\n  video_provider: \"scheduled\"\n  video_id: \"chad-fowler-rubyconf-austria-2026\"\n\n- id: \"kinsey-durham-grace-rubyconf-austria-2026\"\n  title: \"Composing Agentic Systems in Ruby: Turning AI Chaos into Harmony\"\n  speakers:\n    - Kinsey Durham Grace\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"kinsey-durham-grace-rubyconf-austria-2026\"\n\n- id: \"vladimir-dementyev-rubyconf-austria-2026\"\n  title: \"Pattern matching on the loose\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"vladimir-dementyev-rubyconf-austria-2026\"\n\n- id: \"andy-maleh-rubyconf-austria-2026\"\n  title: \"Frontend Ruby on Rails with Glimmer DSL for Web\"\n  speakers:\n    - Andy Maleh\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"andy-maleh-rubyconf-austria-2026\"\n\n- id: \"john-gallagher-rubyconf-austria-2026\"\n  title: \"Workshop: Understand Your Rails App, Practical Observability for Engineers\"\n  speakers:\n    - John Gallagher\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  kind: \"workshop\"\n  video_provider: \"scheduled\"\n  video_id: \"john-gallagher-rubyconf-austria-2026\"\n\n- id: \"ljubomir-markovic-rubyconf-austria-2026\"\n  title: \"The Humble Event Bus: Building Safe Concurrency in Ruby\"\n  speakers:\n    - Ljubomir Marković\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"ljubomir-markovic-rubyconf-austria-2026\"\n\n- id: \"vlad-dyachenko-rubyconf-austria-2026\"\n  title: \"jemalloc is dead, long live mimalloc!\"\n  speakers:\n    - Vlad Dyachenko\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"vlad-dyachenko-rubyconf-austria-2026\"\n\n- id: \"andrzej-krzywda-rubyconf-austria-2026\"\n  title: \"15 years of Rails with Domain Driven Design - lessons learnt\"\n  speakers:\n    - Andrzej Krzywda\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"andrzej-krzywda-rubyconf-austria-2026\"\n\n- id: \"charles-oliver-nutter-rubyconf-austria-2026\"\n  title: \"Workshop: Do More With JRuby\"\n  speakers:\n    - Charles Oliver Nutter\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  kind: \"workshop\"\n  video_provider: \"scheduled\"\n  video_id: \"charles-oliver-nutter-rubyconf-austria-2026\"\n\n- id: \"bernard-banta-rubyconf-austria-2026\"\n  title: \"Sanarei: Offline Web Browsing with Ruby\"\n  speakers:\n    - Bernard Banta\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"bernard-banta-rubyconf-austria-2026\"\n\n- id: \"dalma-jess-rubyconf-austria-2026\"\n  title: \"Why You Should Go Surfing with Strangers: Creating Connection in the Ruby Community\"\n  speakers:\n    - Dalma Boros\n    - Jess Sullivan\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-12-27 12:05:00 UTC\"\n  description: \"\"\n  video_provider: \"scheduled\"\n  video_id: \"dalma-jess-rubyconf-austria-2026\"\n\n- id: \"dave-thomas-rubyconf-austria-2026\"\n  title: \"Closing Keynote\"\n  speakers:\n    - Dave Thomas\n  event_name: \"RubyConf Austria 2026\"\n  date: \"2026-05-30\"\n  announced_at: \"2025-07-14 15:19:00 UTC\"\n  description: \"\"\n  kind: \"keynote\"\n  video_provider: \"scheduled\"\n  video_id: \"dave-thomas-rubyconf-austria-2026\"\n"
  },
  {
    "path": "data/rubyconf-austria/series.yml",
    "content": "---\nname: \"RubyConf Austria\"\nwebsite: \"https://rubyconf.at\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - rubyconfat\n  - RubyConf AT\n  - Ruby Conf AT\n  - Ruby Conf Austria\n  - RubyConf Österreich\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2014/event.yml",
    "content": "---\nid: \"rubyconf-brazil-2014\"\ntitle: \"RubyConf Brazil 2014\"\ndescription: \"\"\nlocation: \"São Paulo, Brazil\"\nkind: \"conference\"\nstart_date: \"2014-08-28\"\nend_date: \"2014-08-29\"\nwebsite: \"\"\ntwitter: \"rubyconfbr\"\ncoordinates:\n  latitude: -23.5557714\n  longitude: -46.6395571\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2015/event.yml",
    "content": "---\nid: \"rubyconf-brazil-2015\"\ntitle: \"RubyConf Brazil 2015\"\ndescription: \"\"\nlocation: \"São Paulo, Brazil\"\nkind: \"conference\"\nstart_date: \"2015-09-18\"\nend_date: \"2015-09-19\"\nwebsite: \"\"\ntwitter: \"rubyconfbr\"\ncoordinates:\n  latitude: -23.5557714\n  longitude: -46.6395571\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2016/event.yml",
    "content": "---\nid: \"rubyconf-brazil-2016\"\ntitle: \"RubyConf Brazil 2016\"\ndescription: \"\"\nlocation: \"São Paulo, Brazil\"\nkind: \"conference\"\nstart_date: \"2016-09-23\"\nend_date: \"2016-09-24\"\nwebsite: \"\"\ntwitter: \"rubyconfbr\"\ncoordinates:\n  latitude: -23.5557714\n  longitude: -46.6395571\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2017/event.yml",
    "content": "---\nid: \"rubyconf-brazil-2017\"\ntitle: \"RubyConf Brazil 2017\"\ndescription: \"\"\nlocation: \"São Paulo, Brazil\"\nkind: \"conference\"\nstart_date: \"2017-11-17\"\nend_date: \"2017-11-18\"\nwebsite: \"\"\ntwitter: \"rubyconfbr\"\ncoordinates:\n  latitude: -23.5557714\n  longitude: -46.6395571\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2019/event.yml",
    "content": "---\nid: \"rubyconf-brazil-2019\"\ntitle: \"RubyConf Brazil 2019\"\ndescription: \"\"\nlocation: \"São Paulo, Brazil\"\nkind: \"conference\"\nstart_date: \"2019-11-28\"\nend_date: \"2019-11-29\"\nwebsite: \"https://callforpapers.locaweb.com.br/events/rubyconf-2019\"\ntwitter: \"rubyconfbr\"\ncoordinates:\n  latitude: -23.5557714\n  longitude: -46.6395571\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://callforpapers.locaweb.com.br/events/rubyconf-2019\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2021/event.yml",
    "content": "---\nid: \"rubyconf-brazil-2021\"\ntitle: \"RubyConf Brazil 2021\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2021-07-29\"\nend_date: \"2021-07-30\"\nwebsite: \"https://online.rubyconf.com.br/\"\ntwitter: \"rubyconfbr\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyconf-brazil/rubyconf-brazil-2021/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://online.rubyconf.com.br/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-brazil/series.yml",
    "content": "---\nname: \"RubyConf Brazil\"\nwebsite: \"\"\ntwitter: \"rubyconfbr\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyconf-by/rubyconfby-2016/event.yml",
    "content": "---\nid: \"rubyconfby-2016\"\ntitle: \"RubyConfBY 2016\"\ndescription: \"\"\nlocation: \"Minsk, Belarus\"\nkind: \"conference\"\nstart_date: \"2016-04-24\"\nend_date: \"2016-04-24\"\nwebsite: \"https://2016.rubyconference.by/en/\"\ntwitter: \"rubyconfby\"\nplaylist: \"https://www.youtube.com/playlist?list=PLpVeA1tdgfCC82YnUz8sAsjmNyPWxIr9l\"\ncoordinates:\n  latitude: 53.9006011\n  longitude: 27.558972\n"
  },
  {
    "path": "data/rubyconf-by/rubyconfby-2016/videos.yml",
    "content": "---\n- id: \"aleksander-kirillov-rubyconfby-2016\"\n  title: \"Continuous Integration под микроскопом\"\n  raw_title: \"Aleksander Kirillov - Continuous Integration под микроскопом\"\n  speakers:\n    - Aleksander Kirillov\n  event_name: \"RubyConfBY 2016\"\n  date: \"2016-04-24\"\n  published_at: \"2016-06-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"sZ4_c6TooX0\"\n\n- id: \"steve-klabnik-rubyconfby-2016\"\n  title: \"Rust for Rubyists\"\n  raw_title: \"Steve Klabnik - Rust for Rubyists\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"RubyConfBY 2016\"\n  date: \"2016-04-24\"\n  published_at: \"2016-06-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"OM4dynVjxUw\"\n\n- id: \"laurent-sansonetti-rubyconfby-2016\"\n  title: \"Write Cross-Platform Mobile Apps in Ruby\"\n  raw_title: \"Laurent Sansonetti - Write Cross-Platform Mobile Apps in Ruby\"\n  speakers:\n    - Laurent Sansonetti\n  event_name: \"RubyConfBY 2016\"\n  date: \"2016-04-24\"\n  published_at: \"2016-06-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"QSb1d7IRZZU\"\n\n- id: \"piotr-szotkowski-rubyconfby-2016\"\n  title: \"Ruby OOP Code Smells\"\n  raw_title: \"Piotr Szotkowski - Ruby OOP Code Smells\"\n  speakers:\n    - Piotr Szotkowski\n  event_name: \"RubyConfBY 2016\"\n  date: \"2016-04-24\"\n  published_at: \"2016-06-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"pazYe7WRWRU\"\n\n- id: \"koichi-sasada-rubyconfby-2016\"\n  title: \"MRI Internals\"\n  raw_title: \"Koichi Sasada - MRI Internals\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyConfBY 2016\"\n  date: \"2016-04-24\"\n  published_at: \"2016-06-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"CQNlP78j1SQ\"\n\n- id: \"alexander-yarotsky-rubyconfby-2016\"\n  title: \"Unit-Testing Yourself\"\n  raw_title: \"Alexander Yarotsky - Unit-Testing Yourself\"\n  speakers:\n    - Alexander Yarotsky\n  event_name: \"RubyConfBY 2016\"\n  date: \"2016-04-24\"\n  published_at: \"2016-06-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"TVBzCopEiAA\"\n\n- id: \"anton-davydov-rubyconfby-2016\"\n  title: \"Viewing Ruby Blossom\"\n  raw_title: \"Anton Davydov - Viewing Ruby Blossom\"\n  speakers:\n    - Anton Davydov\n  event_name: \"RubyConfBY 2016\"\n  date: \"2016-04-24\"\n  published_at: \"2016-06-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6ANpq13FUDE\"\n\n- id: \"jeremy-evans-rubyconfby-2016\"\n  title: \"Rodauth: Website Security Through Database Security\"\n  raw_title: \"Jeremy Evans - Rodauth: Website Security Through Database Security\"\n  speakers:\n    - \"Jeremy Evans\"\n  event_name: \"RubyConfBY 2016\"\n  date: \"2016-04-24\"\n  published_at: \"2016-06-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"z3HZZHXXo3I\"\n\n- id: \"alexander-shestakov-rubyconfby-2016\"\n  title: \"Keep Calm and Kill Mutants!\"\n  raw_title: \"Alexander Shestakov - Keep Calm and Kill Mutants!\"\n  speakers:\n    - Alexander Shestakov\n  event_name: \"RubyConfBY 2016\"\n  date: \"2016-04-24\"\n  published_at: \"2016-06-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"KrEJzk6zAT4\"\n\n- id: \"thijs-cadier-rubyconfby-2016\"\n  title: \"Concurrency in Ruby\"\n  raw_title: \"Thijs Cadier - Concurrency in Ruby\"\n  speakers:\n    - Thijs Cadier\n  event_name: \"RubyConfBY 2016\"\n  date: \"2016-04-24\"\n  published_at: \"2016-06-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"kZyog5N78Jw\"\n"
  },
  {
    "path": "data/rubyconf-by/rubyconfby-2017/event.yml",
    "content": "---\nid: \"rubyconfby-2017\"\ntitle: \"RubyConfBY 2017\"\ndescription: \"\"\nlocation: \"Minsk, Belarus\"\nkind: \"conference\"\nstart_date: \"2017-04-02\"\nend_date: \"2017-04-02\"\nwebsite: \"https://2017.rubyconference.by/en/\"\ntwitter: \"rubyconfby\"\nplaylist: \"https://www.youtube.com/playlist?list=PLpVeA1tdgfCBpR87Q5nw_3caqbVo71EP7\"\ncoordinates:\n  latitude: 53.9006011\n  longitude: 27.558972\n"
  },
  {
    "path": "data/rubyconf-by/rubyconfby-2017/videos.yml",
    "content": "---\n- id: \"aaron-patterson-rubyconfby-2017\"\n  title: \"Defragging Ruby\"\n  raw_title: \"Aaron Patterson - Defragging Ruby, RubyConfBY 2017\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConfBY 2017\"\n  date: \"2017-04-02\"\n  published_at: \"2017-05-02\"\n  description: |-\n    It's been said that programmers like garbage collectors, so lets take a look at Ruby's GC! In this talk we'll walk through how Ruby allocates objects, then talk about how we can optimize object layout and memory usage via compaction. Finally we'll take a look at how to actually build a compacting GC for Ruby as well as the interesting challenges that can be found within.\n  video_provider: \"youtube\"\n  video_id: \"6U5QIxNOVoM\"\n\n- id: \"miha-rekar-rubyconfby-2017\"\n  title: \"What Are Flame Graphs and How to Read Them\"\n  raw_title: \"Miha Rekar - What Are Flame Graphs and How to Read Them, RubyConfBY 2017\"\n  speakers:\n    - Miha Rekar\n  event_name: \"RubyConfBY 2017\"\n  date: \"2017-04-02\"\n  published_at: \"2017-05-02\"\n  description: |-\n    Do you struggle with a slow application? Is New Relic not giving you any valuable insight? Maybe it's always the same controller or maybe it's (what seems) completely random. How do you tackle that? [Flame Graphs](http://www.brendangregg.com/flamegraphs.html) are the answer. Let me teach you how to read flame graphs so you'll be able to find the slow spots of your app and fix them.\n  video_provider: \"youtube\"\n  video_id: \"6uKZXIwd6M0\"\n\n- id: \"maxim-gordienok-rubyconfby-2017\"\n  title: \"Cook Data with CQRS and Event Sourcing and Don't Get Burned\"\n  raw_title: \"Maxim Gordienok - Cook Data with CQRS and Event Sourcing and Don't Get Burned, RubyConfBY 2017\"\n  speakers:\n    - Maxim Gordienok\n  event_name: \"RubyConfBY 2017\"\n  date: \"2017-04-02\"\n  published_at: \"2017-05-02\"\n  description: |-\n    - Why you should know about CQRS and Event Sourcing \n    - No more pain when working with various data sources \n    - Data analysis and reports building with pleasure \n    - Reliable data with Event Sourcing or how to rollback to fix errors\n  video_provider: \"youtube\"\n  video_id: \"V-ZusRKtshQ\"\n\n- id: \"jan-krutisch-rubyconfby-2017\"\n  title: \"Let Humans Human and Computers Computer\"\n  raw_title: \"Jan Krutisch - Let Humans Human and Computers Computer, RubyConfBY 2017\"\n  speakers:\n    - Jan Krutisch\n  event_name: \"RubyConfBY 2017\"\n  date: \"2017-04-02\"\n  published_at: \"2017-05-02\"\n  description: |-\n    Boring, repetitive tasks, are, if we like it or not, part of our daily routine as developers. We can try to automate them away as much as possible, but what exactly makes a good automation? By looking in detail at the grunt work of updating dependencies and how we’re automating it, we’ll see how we can make computers do what they do best and at the same time keep us humans in control.\n  video_provider: \"youtube\"\n  video_id: \"ElwCE-6RfT8\"\n\n- id: \"ivan-shamatov-rubyconfby-2017\"\n  title: \"View Layer in Ruby Frameworks\"\n  raw_title: \"Ivan Shamatov - View Layer in Ruby Frameworks, RubyConfBY 2017\"\n  speakers:\n    - Ivan Shamatov\n  event_name: \"RubyConfBY 2017\"\n  date: \"2017-04-02\"\n  published_at: \"2017-05-02\"\n  description: |-\n    Ok, we've got M-models: ApplicationRecord.new \n    We've got C-controllers: ApplictionController.new \n    And of course V-view: SWOOSH \n    Ok, we have some magic here inside Rails, but what can we use to have real view layer. ERB? That's just templates.\n    I would like to make an overview of some solutions we already have.\n    * Arbre / RABL as DSL to render \n    * Presenters / Serializers / Grape-entities for logicless view-templates\n    * Cells as View Component / Hanami-view / Dry-view with really similar approach of separation view-model from template.\n  video_provider: \"youtube\"\n  video_id: \"LlJ4fgOeB30\"\n\n- id: \"charles-nutter-rubyconfby-2017\"\n  title: \"JRuby in 2017: Fast, Compatible, and Concurrent\"\n  raw_title: \"Charles Nutter - JRuby in 2017: Fast, Compatible, and Concurrent, RubyConfBY 2017\"\n  speakers:\n    - \"Charles Nutter\"\n  event_name: \"RubyConfBY 2017\"\n  date: \"2017-04-02\"\n  published_at: \"2017-05-02\"\n  description: |-\n    The JRuby project began over 15 years ago, and in 2016 for the first time we caught up on compatibility. Now it's 2017 and we're pushing forward with aggressive optimizations and better support for concurrent programming. I'll show you how and why JRuby works so well and how you can start building or migrating apps to JRuby today. Is 2017 the year of JRuby? Let's find out!\n  video_provider: \"youtube\"\n  video_id: \"Qeqdmicuc1U\"\n\n- id: \"bozhidar-batsov-rubyconfby-2017\"\n  title: \"Ruby 4.0: To Infinity and Beyond\"\n  raw_title: \"Bozhidar Batsov - Ruby 4.0: To Infinity and Beyond, RubyConfBY 2017\"\n  speakers:\n    - \"Bozhidar Batsov\"\n  event_name: \"RubyConfBY 2017\"\n  date: \"2017-04-02\"\n  published_at: \"2017-05-02\"\n  description: |-\n    An exploration of the challenges that Ruby faces today, combined with ideas regarding how we can change things for the better. We'll talk about the language, its ecosystem and its community. While on this bold adventure we'll plot a course towards Ruby 4.0 - a mystical and magical Ruby release that would ensure Ruby's dominance to infinity and beyond! Oh, and did I mention we'll have a ton fun while doing so? We'll most certainly do!\n  video_provider: \"youtube\"\n  video_id: \"Dg3iSZxhIwM\"\n\n- id: \"anna-shcherbinina-rubyconfby-2017\"\n  title: \"Scaling Issues with Monoliths, Microservices and Hybrids\"\n  raw_title: \"Anna Shcherbinina - Scaling Issues with Monoliths, Microservices and Hybrids, RubyConfBY 2017\"\n  speakers:\n    - Anna Shcherbinina\n  event_name: \"RubyConfBY 2017\"\n  date: \"2017-04-02\"\n  published_at: \"2017-05-02\"\n  description: |-\n    It's cool when your application is able to cope with stress. Not good when it's costly to scale. It's really bad when application fails under capacity. We'll talk about microservices, monoliths and hybrids in perspective of scaling abilities. How to design scale into the solutions? Use horizontal scale, scale though services and partitioning. Want your app to support the load of success? - welcome!\n  video_provider: \"youtube\"\n  video_id: \"iOSLPcRe8tk\"\n\n- id: \"andrei-savchenko-rubyconfby-2017\"\n  title: \"Alice & Bob Goes Wild\"\n  raw_title: \"Andrei Savchenko - Alice & Bob Goes Wild, RubyConfBY 2017\"\n  speakers:\n    - Andrei Savchenko\n  event_name: \"RubyConfBY 2017\"\n  date: \"2017-04-02\"\n  published_at: \"2017-05-02\"\n  description: |-\n    Security tales for non-security people: how you can harden your apps for little to no cost and why you should care.\n  video_provider: \"youtube\"\n  video_id: \"kzsJdVL5P-k\"\n\n- id: \"vladimir-dementyev-rubyconfby-2017\"\n  title: \"Run Test Run\"\n  raw_title: \"Vladimir Dementyev - Run Test Run, RubyConfBY 2017\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RubyConfBY 2017\"\n  date: \"2017-04-02\"\n  published_at: \"2017-05-02\"\n  description: |-\n    Writing tests is a significant part of the development process, especially in Ruby and Rails community. But usually, we do not care too much about tests' code organization, optimization, conventions, etc. – all these lovely things we always do with our application code. Until we realize that our whole test suite or its parts take too much time to run (or even launch in case of Rails). I want to share some tips & tricks on how to make your tests run faster, look prettier and be maintainable.\n  video_provider: \"youtube\"\n  video_id: \"q52n4p0wkIs\"\n"
  },
  {
    "path": "data/rubyconf-by/rubyconfby-2018/event.yml",
    "content": "---\nid: \"rubyconfby-2018\"\ntitle: \"RubyConfBY 2018\"\ndescription: \"\"\nlocation: \"Minsk, Belarus\"\nkind: \"conference\"\nstart_date: \"2018-04-21\"\nend_date: \"2018-04-21\"\nwebsite: \"https://rubyconference.by/2018\"\ntwitter: \"rubyconfby\"\nplaylist: \"https://www.youtube.com/playlist?list=PLpVeA1tdgfCD5vCJvBlbUGTNd5KHO4AWL\"\ncoordinates:\n  latitude: 53.9006011\n  longitude: 27.558972\n"
  },
  {
    "path": "data/rubyconf-by/rubyconfby-2018/videos.yml",
    "content": "---\n- id: \"stefan-wintermeyer-rubyconfby-2018\"\n  title: \"Better WebPerformance with Rails 5.2\"\n  raw_title: 'RubyConfBY 2018: Stefan Wintermeyer \"Better WebPerformance with Rails 5.2\"'\n  speakers:\n    - Stefan Wintermeyer\n  event_name: \"RubyConfBY 2018\"\n  date: \"2018-04-21\"\n  published_at: \"2018-05-08\"\n  description: |-\n    Speed is paramount for the success of a website (key for a good conversion rate and SEO). Unfortunately Webperformance is not a strong suite of a vanilla Rails application.\n\n    Let's optimize an example Ruby on Rails 5.2 web shop application and analyze before/after times. I'll show the audience where it makes sense to spend time to optimize and where not. Use the new 5.2 goodies!\n\n    Side effect: By making your Rails app faster you'll save server costs.\n  video_provider: \"youtube\"\n  video_id: \"R-0QXFqoQzM\"\n\n- id: \"bozhidar-batsov-rubyconfby-2018\"\n  title: \"All about RuboCop\"\n  raw_title: 'RubyConfBY 2018: Bozhidar Batsov \"All about RuboCop\"'\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"RubyConfBY 2018\"\n  date: \"2018-04-21\"\n  published_at: \"2018-05-08\"\n  description: |-\n    In this talk we'll go over everything you need to know about RuboCop - a powerful Ruby static code analyzer that makes it easy for you to enforce a consistent code style throughout your Ruby projects.\n\n    We'll begin by examining the events that lead to the creation of RuboCop, its early days and its evolution, effective RuboCop usage and some of its cool but little-known features. Then we'll continue with a brief look into RuboCop's internals and show you how easy it is to extend its functionality.\n\n    We'll wrap the talk with a glimpse inside RuboCop's future and discuss some of the challenges the project faces and some of the work that remains to be done, before RuboCop finally reaches the coveted 1.0 version.\n  video_provider: \"youtube\"\n  video_id: \"7u8nL9ABv2E\"\n\n- id: \"anna-shcherbinina-rubyconfby-2018\"\n  title: \"Docker + GPU. Not about mining\"\n  raw_title: 'RubyConfBY 2018: Anna Shcherbinina \"Docker + GPU. Not about mining\"'\n  speakers:\n    - Anna Shcherbinina\n  event_name: \"RubyConfBY 2018\"\n  date: \"2018-04-21\"\n  published_at: \"2018-05-08\"\n  description: |-\n    Just before Christmas we launched a new body-measurement feature for our shapify.me project. A person goes into the 3D booth, gets scanned, and the body-measurements are calculated with the 3D scan data. We couldn't avoid using a GPU with these calculations.\n\n    How to install this branch of processing into our elegant scaling pipeline? When you're dealing with 3D scans you should remember two things: it's expensive and time-consuming. By the way, its workload fluctuates throughout the days. The easiest solution for us was to use Docker.\n\n    This speech is not about mining, but the most helpful articles for us were ones such as \"Building your own mining farm\". That's because we use quite a similar infrastructure.\n    GPU, Docker, scaling. What we achieved, where we failed, and what it became of it in the end is all included in my speech.\n  video_provider: \"youtube\"\n  video_id: \"MuZr_R0p3AE\"\n\n- id: \"benjamin-roth-rubyconfby-2018\"\n  title: \"ACID's extasy\"\n  raw_title: 'RubyConfBY 2018: Benjamin Roth \"ACID''s extasy\"'\n  speakers:\n    - Benjamin Roth\n  event_name: \"RubyConfBY 2018\"\n  date: \"2018-04-21\"\n  published_at: \"2018-05-08\"\n  description: |-\n    Whenever things can get wrong and you need a way to go back to a consistent state, ACID (and service objects) gets your back. We will explore some patterns to go back on your feet even if you have to orchestrate many database writes and even third party: queues, api calls.\n  video_provider: \"youtube\"\n  video_id: \"t9NJdHM8dsQ\"\n\n- id: \"margo-urey-rubyconfby-2018\"\n  title: \"Better Developer Relations Start with the Interview\"\n  raw_title: 'RubyConfBY 2018: Margo Urey \"Better Developer Relations Start with the Interview\"'\n  speakers:\n    - Margo Urey\n  event_name: \"RubyConfBY 2018\"\n  date: \"2018-04-21\"\n  published_at: \"2018-05-08\"\n  description: |-\n    The importance of soft skills for successful developer teams cannot be overestimated.\n\n    First impressions set the tone for developer relations and the interview is where you make that first impression.\n\n    Here are a few ways companies got it right and got it wrong; and how you can take control to start things off on the right foot.\n  video_provider: \"youtube\"\n  video_id: \"7AbPvP--PDY\"\n\n- id: \"maxim-gordienok-rubyconfby-2018\"\n  title: 'Is there life on \"Ruby on Machine Learning\" planet?'\n  raw_title: 'RubyConfBY 2018: Maxim Gordienok \"Is there life on \"Ruby on Machine Learning\" planet?\"'\n  speakers:\n    - Maxim Gordienok\n  event_name: \"RubyConfBY 2018\"\n  date: \"2018-04-21\"\n  published_at: \"2018-05-08\"\n  description: |-\n    Making tired on developing \"new-Snapchat-with\" or \"app-like-Airbnb-but\" or doing something like \"ok, I will copy that from that project, add design and go to production\" sounds familiar to you? Was ruby worth it to learn and use it for all these years? Let's see what more can ruby do for you!\n\n    We will start with top level overview about options you have today (they will make your life is a developer challenging), then will go down to real world case(-s) and, hopefully, will make something working together. I want to present my experience and will guide you on what can ruby do with machine learning, so often called AI today.\n  video_provider: \"youtube\"\n  video_id: \"VN0M5hVGKX0\"\n\n- id: \"mikhail-bortnyk-rubyconfby-2018\"\n  title: \"Ruby JIT Compilation\"\n  raw_title: 'RubyConfBY 2018: Mikhail Bortnyk \"Ruby JIT Compilation\"'\n  speakers:\n    - Mikhail Bortnyk\n  event_name: \"RubyConfBY 2018\"\n  date: \"2018-04-21\"\n  published_at: \"2018-05-08\"\n  description: |-\n    Reviewing just-in-time compilation as a possible future way to speed up Ruby 3.0, comparisons of implementations and different benchmarking ways.\n\n    I will tell a little about JIT theory and a lot about existing implementations (starting from JRuby+Truffle, ending up with MJIT and LLRB).\n\n    Warning: a lot of graphs, benchmarks, LLVM, JVM and Ruby source code.\n  video_provider: \"youtube\"\n  video_id: \"OYsJ7lElSKI\"\n\n- id: \"sergey-dolganov-rubyconfby-2018\"\n  title: \"Make External API Dependency Great Again (API Contract Testing)\"\n  raw_title: 'RubyConfBY 2018: Sergey Dolganov \"Make External API Dependency Great Again (API Contract Testing)\"'\n  speakers:\n    - Sergey Dolganov\n  event_name: \"RubyConfBY 2018\"\n  date: \"2018-04-21\"\n  published_at: \"2018-05-08\"\n  description: |-\n    Nowadays, unit tests are an essential part of our development process. While we are proud we have 100% test coverage; it does not mean that our code behaves as expected, notably when we deal with external APIs.\n\n    I'm working on the eBaymag project which mostly built around various API interactions: eBay API, Google Translate API, DHL API and so on.\n    I solve different sophisticated problems based on unexpected API behavior on my daily basis.\n\n    So I want to introduce a contract-based testing framework that aims to get rid of unexpected behavior of your app. I'll share the tools and approaches that will minimize the risks of being dependent on some external system API.\n  video_provider: \"youtube\"\n  video_id: \"uLCcm3B09ZM\"\n\n- id: \"nick-sutterer-rubyconfby-2018\"\n  title: \"Super Ain't Super - How my Programming Style Changed\"\n  raw_title: 'RubyConfBY 2018: Nick Sutterer \"Super Ain''t Super – How my Programming Style Changed\"'\n  speakers:\n    - Nick Sutterer\n  event_name: \"RubyConfBY 2018\"\n  date: \"2018-04-21\"\n  published_at: \"2018-06-13\"\n  description: |-\n    A blazing fast voyage through the jungle of object-oriented programming, onwards to functional discipline, up to my rediscovery of an ancient, long-lost art: Enterprise software!\n  video_provider: \"youtube\"\n  video_id: \"T_3t3nBwC7M\"\n"
  },
  {
    "path": "data/rubyconf-by/rubyconfby-2019/event.yml",
    "content": "---\nid: \"rubyconfby-2019\"\ntitle: \"RubyConfBY 2019\"\ndescription: \"\"\nlocation: \"Minsk, Belarus\"\nkind: \"conference\"\nstart_date: \"2019-04-06\"\nend_date: \"2019-04-06\"\nwebsite: \"https://rubyconference.by/\"\ntwitter: \"rubyconfby\"\nplaylist: \"https://www.youtube.com/playlist?list=PLpVeA1tdgfCCvTdTREN1pbu8ivniZEdlS\"\ncoordinates:\n  latitude: 53.9006011\n  longitude: 27.558972\n"
  },
  {
    "path": "data/rubyconf-by/rubyconfby-2019/videos.yml",
    "content": "---\n- id: \"david-halasz-rubyconfby-2019\"\n  title: \"How to Hijack, Proxy and Smuggle Sockets with Rack/Ruby\"\n  raw_title: '#RubyConfBY2019 – \"How to Hijack, Proxy and Smuggle Sockets with Rack/Ruby\", David Halasz'\n  speakers:\n    - David Halasz\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 – https://rubyconference.by\n\n    Does your network only let through HTTP connections? No problem! Let's hijack some sockets from incoming HTTP connections and use it to smuggle any kind of traffic through an HTTP session! Concurrently! In #Ruby! \n\n    Rack is a super simple, yet a very versatile tool to implement web servers in Ruby. It beats under the hood of #Rails, but it can do much more. The socket hijacking has been implemented into Rack to support WebSockets by bypassing the middleware and so not blocking the worker threads. Together with the HTTP Upgrade requests, this can be used to send regular TCP traffic through an open HTTP connection. This talk is about leveraging socket hijacking to smuggle an SSH connection through an HTTP session using Rack. All this by using Ruby, a language that's not ideal for doing concurrency and IO.\n\n    Warning: your infosec team already does not like me, but I have some cute stickers.\n\n\n    Video Partner – iTechArt https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"dAFXekd6k68\"\n\n- id: \"ivan-nemytchenko-rubyconfby-2019\"\n  title: \"What's Missing?\"\n  raw_title: '#RubyConfBY2019 – \"What''s Missing?\", Ivan Nemytchenko (Lightning Talk)'\n  speakers:\n    - Ivan Nemytchenko\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 - https://rubyconference.by\n    We are experienced developers. Yet, when we deal with big codebases, we often feel that we don't fully control the situation. The question is what's missing? What is this mysterious thing? \n\n    We continuously learn new things, try new frameworks and approaches, but it doesn't really help. Let's talk why is it happening and how to reclaim the sense of control back.\n\n    Video Partner – iTechArt https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"OyQ61ch7pnE\"\n\n- id: \"nick-grysimov-rubyconfby-2019\"\n  title: \"Kafka's Metamorphosis\"\n  raw_title: '#RubyConfBY2019 – \"Kafka''s Metamorphosis\", Nick Grysimov'\n  speakers:\n    - Nick Grysimov\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 – https://rubyconference.by\n    On our way to scalability in SoftSwiss we discovered that our beloved RabbitMQ does not want to play by new rules. So we turn our heads towards #ApacheKafka, stream-processing platform developed to withhold hundreds of thousands messages per second. \n\n    In this talk I'll briefly discuss Kafka's architecture, show how we spin it up in production (and which problems we encountered) and talk about future challenges our product have to solve to fully encorporate high-availability mindset.\n\n    Video Partner – iTechArt https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"2y1hFXGHqR0\"\n\n- id: \"tung-nguyen-rubyconfby-2019\"\n  title: \"Ruby Serverless Framework\"\n  raw_title: '#RubyConfBY2019 – \"Ruby Serverless Framework\", Tung Nguyen'\n  speakers:\n    - Tung Nguyen\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 – https://rubyconference.by\n    AWS released official #Ruby Support for Lambda at re:Invent 2018. This announcement makes Ruby a first-class citizen in the Serverless world. The framework that will be discussed was already been running Ruby at Native speed prior to the announcement. The framework switched over to the official AWS version of Ruby less than 2 weeks after the announcement!\n\n    We will do a quick introduction to the Serverless world and AWS Lambda to establish a baseline for everyone. Then we'll jump into a Ruby Framework that makes Serverless easy to work with.\n\n    Ruby is the not only one of most beautiful languages in the world but also extremely powerful. The power lies in Ruby's Metaprogramming abilities. This serverless framework leverages these Ruby powers to create a DSL that essentially translates Ruby code to AWS Lambda functions. We'll introduce these Framework concepts:\n\n        Controllers\n        Routes\n        Jobs\n\n    We will create a few demos and deploy it to AWS Lambda live. We will also cover some architecture pattern examples that can be built with the framework:\n\n        Web API Application\n        Event Driven Security: Auto-Remediation\n        Continuous Compliance: AWS Config Rules\n        Event Driven IoT Architectures\n\n    Serverless Ruby opens a world of possibilities for Ruby programmers.\n\n    Video Partner – iTechArt https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"PfbIT-_mugk\"\n\n- id: \"andrzej-krzywda-rubyconfby-2019\"\n  title: \"Business Logic in Ruby\"\n  raw_title: '#RubyConfBY2019 – \"Business Logic in Ruby\", Andrzej Krzywda'\n  speakers:\n    - Andrzej Krzywda\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 – https://rubyconference.by\n    This talk is a story of my journey in the programming world - a journey which started in the Smalltalk world, switched to Java, but then was dominated by #Ruby/Rails. \n\n    My focus on implementing the business logic was always crucial in my apps. During the talk, I will show how my thinking has been changing, how it was challenged and where I ended for now. I will show many code examples and discuss their pros and cons, including the ways of testing them. Object-oriented and Function-driven techniques will be shown. \n\n    I strongly believe that the ability of implementing business logic, separated from the framework, separated from the persistence mechanism, separated from any library - is crucial to the success of many business projects. \n\n    During the talk I want to take you for this journey with me and leave you with new knowledge that you can apply in your codebase immediately.\n\n    Video Partner – iTechArt https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"d1tPdmPRVU4\"\n\n- id: \"yulia-oletskaya-rubyconfby-2019\"\n  title: \"RPC Frameworks Overview\"\n  raw_title: '#RubyConfBY2019 – \"RPC Frameworks Overview\", Yulia Oletskaya (Lightning Talk)'\n  speakers:\n    - Yulia Oletskaya\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 - https://rubyconference.by/2019\n    Overview of #gRPC, #ApacheThrift, #Twirp, #Finagle frameworks, their main features, and #Ruby specific implementation details.\n\n    Lately, a lot of web developers tend to find out that REST isn't always the ultimate solution for services communication problems. Some people thrift to search for new architectural styles (e.g. GraphQL) and others give a new breath to old-fashioned RPCs. This talk is a brief overview of existing RPC frameworks (e.g. gRPC, Apache Thrift, Twirp) including Ruby specific details.\n\n    Video Partner – iTechArt  https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"R_W48bwWD24\"\n\n- id: \"sergey-dolganov-rubyconfby-2019\"\n  title: \"Railways, States & Sagas: Pure Ruby for Wizards\"\n  raw_title: '#RubyConfBY2019 – \"Railways, States & Sagas: Pure Ruby for Wizards\", Sergey Dolganov, Lightning talk'\n  speakers:\n    - Sergey Dolganov\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 – https://rubyconference.by\n    Have you ever heard about data consistency problems within the multi-service architecture? That problem could be solved using Sagas design pattern. In fact, it's quite hard to implement. \n\n    Want to know how? Welcome on board, young magicians!\n\n    Video Partner – iTechArt https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"Ku-IqG4X3q4\"\n\n- id: \"piotr-murach-rubyconfby-2019\"\n  title: \"It is correct, but is it fast?\"\n  raw_title: '#RubyConfBY2019 – \"It is correct, but is it fast?\", Piotr Murach'\n  speakers:\n    - Piotr Murach\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 - https://rubyconference.by\n    #Ruby is optimised for happiness, we tell ourselves when we write beautiful code. We've written our acceptance and unit tests. What else is there to do? Nah, we don't need to worry about performance. \n\n    Sometimes, though, things turn sour when your beautiful code meets reality and the data processing consumes all of the server's resources. There are no magic bullets that can instantly detect performance and scaling issues in our code, but there are techniques that can help. \n\n    In this talk, you'll learn all about the benefits of writing performance assertions in a test suite. You'll see how a seemingly reasonable algorithm in fact exhibits abysmal performance and doesn't scale. We'll explore two different types of performance assertions that can be used to establish the performance characteristics of our example. Once we've done that, from then on, only hard cold measurements will guide us in refactoring the code to be more performant. \n\n    You will leave equipped with the techniques to help you learn how fast your code really is. Let's put a stop to slow code and remove all of those pesky performance bugs!\n\n    Video Partner – iTechArt  https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"8_HrI5kOwMY\"\n\n- id: \"dmitry-salahutdinov-rubyconfby-2019\"\n  title: \"Optimistic UI with Logux & Ruby\"\n  raw_title: '#RubyConfBY2019 – \"Optimistic UI with Logux & Ruby\", Dmitry Salahutdinov'\n  speakers:\n    - Dmitry Salahutdinov\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 - https://rubyconference.by\n    The modern web becomes more distributed: both front-end and back-end turns out to be the complicated part of the bipolar web-application. And communication between them is going to be a new challenge. \n\n    The classic AJAX problems: - the unstable network makes AJAX based UI works annoying - does not work offline - there is no way to merge conflits, last processed update is accepted as the last truth - UI becomes pessimistic with a huge amount of loaders and other request-time lockers - the increasing complexity of the JavaScript code for processing AJAX requests - AJAX work only in one way and does not allow live updates \n\n    #Logux is the new way of synchronization between client and server, which provides many features for modern web out of the box: Live Updates, Optimistic UI, Offline-first. \n\n    What does Logux bring to level up client-server communication? - uses event-sourcing and CRDT concepts to work automatic resolving conflicts - communicates over web-socket in both directions to support Live Updates - synchronizes event log between clients automatically - support the protocol upgrade - is fully integrated with the current front-end ecosystem (Redux) \n\n    I will talk about how basic Logux concepts and how all of the work together to support the modern web features.\n\n    Video Partner – iTechArt  https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"i_E-CeUb6ek\"\n\n- id: \"aaron-patterson-rubyconfby-2019\"\n  title: \"The View Is Clear from Here\"\n  raw_title: '#RubyConfBY2019 – \"The View Is Clear from Here\", Aaron Patterson'\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 – https://rubyconference.by\n    Web applications typically have bottlenecks at the database layer. This is one reason Active Record gets so much attention by application developers, Rails core developers, and conference speakers. \n\n    In this talk we will be focusing on something a little bit different. Instead of the database layer, we will be looking at the view layer of the application. We will be looking at how view \n    rendering is handled in #Rails. This will include the process by which views are compiled, cached, and rendered. We'll learn how much memory they are found, how much memory they use, and more importantly how we can speed them up.\n\n    Audience members should expect to leave with more information about Rails internals along with development techniques that they can use in their applications today!\n\n    Video Partner – iTechArt https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"MiW1NA1FR8U\"\n\n- id: \"denis-defreyne-rubyconfby-2019\"\n  title: \"Code as Data\"\n  raw_title: '#RubyConfBY2019 – \"Code as Data\", Denis Defreyne'\n  speakers:\n    - Denis Defreyne\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 - https://rubyconference.by\n    Algorithms are typically encoded in code. Sometimes, however, letting non-developers modify algorithms can be beneficial — but for that, we'll have to move the implementation of the algorithm from code into data. Doing so yields a bunch of interesting advantages.\n\n    Imagine that you're implementing a complex algorithm that encapsulates some business process at your company. The business stakeholders are pleased, but sometimes come to you with questions, such as\n\n        Why is this calculation result so high?\n        Can you please tweak some factors in the algorithm?\n\n    One-off requests like these are probably fine, but occasionally they can be so numerous that you end up spending a significant amount of your time dealing with incoming requests. (You have more interesting stuff to do!) Ideally, business stakeholders themselves would be able to figure out why that calculation result is so high, and would be able to change the factors themselves.\n\n    The implementation of the algorithm is in code – and it is typically not feasible to let business stakeholders handle code. (They have more interesting stuff to do!) We can move the algorithm's implementation out of code and into data… and that yields us a bunch of interesting advantages. \n\n    Video Partner – iTechArt https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"InnlXmswdyk\"\n\n- id: \"ana-mara-martnez-gmez-rubyconfby-2019\"\n  title: \"The Biggest Mobprogramming Session Ever\"\n  raw_title: '#RubyConfBY2019 – \"The Biggest Mobprogramming Session Ever\", Ana María Martínez Gómez'\n  speakers:\n    - Ana María Martínez Gómez\n  event_name: \"RubyConfBY 2019\"\n  date: \"2019-04-06\"\n  published_at: \"2019-04-26\"\n  description: |-\n    #RubyConfBY 2019 – https://rubyconference.by\n    Do you like hacking? For the first time, you will be able to do this during a talk! \n\n    In this talk, Ana will drive the biggest mobprogramming session ever. We all will write code live together to send a PR to an open source #Ruby or #Rails project. The project we choose, what we implement and the code we write is up to you! More than 200 developers and 45 minutes to select a task, implement it and send a working code upstream may sound impossible. Even if we don't manage, we will learn from each other a ton about open source, git, Ruby and RoR.\n\n    Video Partner – iTechArt https://www.itechart.by\n  video_provider: \"youtube\"\n  video_id: \"lFWi_JzVFpw\"\n"
  },
  {
    "path": "data/rubyconf-by/rubyconfby-2020/event.yml",
    "content": "---\nid: \"rubyconfby-2020\"\ntitle: \"RubyConfBY 2020\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2020-07-18\"\nend_date: \"2020-07-19\"\nwebsite: \"https://rubyconference.by/\"\ntwitter: \"RubyConfBY\"\nplaylist: \"https://www.youtube.com/playlist?list=PLpVeA1tdgfCCle4AS77lvMYxg2Eqkd5dT\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyconf-by/rubyconfby-2020/videos.yml",
    "content": "---\n- id: \"matias-korhonen-rubyconfby-2020\"\n  title: \"A Benjamin Button History of Ruby\"\n  raw_title: \"RubyConfBY 2020: Matias Korhonen - A Benjamin Button History of Ruby\"\n  speakers:\n    - Matias Korhonen\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    Let's take a Ruby script designed to run using the latest bells and whistles of Ruby 2.7 and port it to earlier versions of Ruby version by version. How far can we take this? Find out together with Matias Korhonen.\n  video_provider: \"youtube\"\n  video_id: \"Cc7Ny_Y5ccU\"\n\n- id: \"frederick-cheung-rubyconfby-2020\"\n  title: \"How to A/B test with confidence\"\n  raw_title: \"RubyConfBY 2020: Frederick Cheung - How to A/B test with confidence\"\n  speakers:\n    - Frederick Cheung\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    A/B tests should be a surefire way to make confident, data-driven decisions about all areas of your app - but it's really easy to make mistakes in their setup, implementation or analysis that can seriously skew results!\n\n    After a quick recap of the fundamentals, you'll learn the procedural, technical and human factors that can affect the trustworthiness of a test.\n\n    In his talk Fredrick shows how to mitigate these issues with easy, actionable tips that will have you A/B testing accurately in no time!\n  video_provider: \"youtube\"\n  video_id: \"xI48AV27YU8\"\n\n- id: \"piotr-solnica-rubyconfby-2020\"\n  title: \"Growing a library ecosystem\"\n  raw_title: \"RubyConfBY 2020: Piotr Solnica - Growing a library ecosystem\"\n  speakers:\n    - Piotr Solnica\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    In this talk Piotr shares his experiences when building, maintaining, and growing an entire ecosystem of open source libraries.\n\n    From small building blocks, through high-level abstractions, ending with feature-rich frameworks. How this type of work can be organized? How do you manage contributions? What about documentation? Versioning? Release process? And the most important question: is it worth the extra effort?\n  video_provider: \"youtube\"\n  video_id: \"_0qSyPPUdNw\"\n\n- id: \"anton-davydov-rubyconfby-2020\"\n  title: \"How to visualize a ruby project\"\n  raw_title: \"RubyConfBY 2020: Anton Davydov - How to visualize a ruby project\"\n  speakers:\n    - Anton Davydov\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    Code visualization is an important part of coding. Usually, we use our imagination but what will happen if we ask ruby to do this work?\n\n    In his talk, Anton will show a tool that we build in dry-rb and which exists only in the ruby ecosystem. This tool will help us to see all project component associations on the one page. You'll find out why other tools work terribly and how to visualize important things.\n\n    Also, Anton explains how this visualization can help with onboarding new developers, find \"god\" objects in the system and use a heatmap of dependency usage for finding unused parts of the project.\n  video_provider: \"youtube\"\n  video_id: \"zBb6hOOo1Dw\"\n\n- id: \"vladimir-dementyev-rubyconfby-2020\"\n  title: \"Crash course in transpiling Ruby\"\n  raw_title: \"RubyConfBY 2020: Vladimir Dementyev - Crash course in transpiling Ruby\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    What is a transpiler? Isn't it something we use to make JavaScript less painful to work with? Sure, but not only that. Transpilers could be useful for other languages, too\n\n    Find out how we can build a transpiler for Ruby, what \"magic\" is required to make edge Ruby syntax work in all Rubies, and why on Mars you might need it.\n  video_provider: \"youtube\"\n  video_id: \"Nxm4-wpttck\"\n\n- id: \"noah-gibbs-rubyconfby-2020\"\n  title: \"A Better Kind of Conscious Coding Practice\"\n  raw_title: \"RubyConfBY 2020: Noah Gibbs - A Better Kind of Conscious Coding Practice\"\n  speakers:\n    - Noah Gibbs\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    From the talk by Noah Gibbs you will learn how to create coding studies for yourself, not just find other people's pre-worked exercises. The technique is good for a beginner or an expert & works with any language, library or paradigm.\n  video_provider: \"youtube\"\n  video_id: \"NF4rHCUElVI\"\n\n- id: \"jan-krutisch-rubyconfby-2020\"\n  title: \"Ruby patterns for contemporary dance music\"\n  raw_title: \"RubyConfBY 2020: Jan Krutisch - Ruby patterns for contemporary dance music\"\n  speakers:\n    - Jan Krutisch\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    Thanks to SonicPi, you can make some impressive music by writing ruby code. But what if we really want to understand how the sausage is made?\n\n    In a quick tour through the basics of digital audio processing, subtractive synthesis and more, you'll learn how pure ruby can produce a complete song.\n  video_provider: \"youtube\"\n  video_id: \"oJBNEYo_eN8\"\n\n- id: \"tetiana-chupryna-rubyconfby-2020\"\n  title: \"Joy of painting with Ruby and OpenGL\"\n  raw_title: \"RubyConfBY 2020: Tetiana Chupryna - Joy of painting with Ruby and OpenGL\"\n  speakers:\n    - Tetiana Chupryna\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    Tetiana will try to open hidden potentials of Ruby language and apply it to graphics programming. She'll draw a picture using OpenGL, and step by step you'll find out how to control the scene and draw different types of objects.\n\n    The repo with code samples https://gitlab.com/brytannia/rubyconf_by_2020\n  video_provider: \"youtube\"\n  video_id: \"vfcfw1hycJ4\"\n\n- id: \"valerie-woolard-rubyconfby-2020\"\n  title: \"Code and Fear: Talent, Art, and Software Development\"\n  raw_title: \"RubyConfBY 2020: Valerie Woolard - Code and Fear: Talent, Art, and Software Development\"\n  speakers:\n    - Valerie Woolard\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    Writing code is a creative pursuit in many ways. In her inspiring talk Valerie addresses the ways in which code is similar to making art and discusses lessons from the book \"Art & Fear\" and how they can be applied to software.\n  video_provider: \"youtube\"\n  video_id: \"VUuXa_c3fG4\"\n\n- id: \"daniel-magliola-rubyconfby-2020\"\n  title: \"Disk is fast, memory is slow. Forget all you think you know\"\n  raw_title: \"RubyConfBY 2020: Daniel Magliola - Disk is fast, memory is slow. Forget all you think you know\"\n  speakers:\n    - Daniel Magliola\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    When trying to add metrics to their application, Daniel Magliola with the team hit an interesting challenge: could the numbers be aggregated across processes without blowing the target of one microsecond per call?\n  video_provider: \"youtube\"\n  video_id: \"Wh-dWt5CYMg\"\n\n- id: \"vitaly-pushkar-rubyconfby-2020\"\n  title: \"Error handling with Monads in Ruby\"\n  raw_title: \"RubyConfBY 2020: Vitaly Pushkar - Error handling with Monads in Ruby\"\n  speakers:\n    - Vitaly Pushkar\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    Ever wondered how exceptions became the default error handling technique in many programming languages, and if there are better alternatives?\n\n    Wonder no more! Watch this talk to learn about the pros and cons of error handling with Monads in Ruby, code examples included.\n  video_provider: \"youtube\"\n  video_id: \"bKqw5eQIkDw\"\n\n- id: \"luca-guidi-rubyconfby-2020\"\n  title: \"Hanami::API\"\n  raw_title: \"RubyConfBY 2020: Luca Guidi - Hanami::API\"\n  speakers:\n    - Luca Guidi\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"tfvoNBU9-Zo\"\n\n- id: \"stefan-wintermeyer-rubyconfby-2020\"\n  title: \"The Greener Grass\"\n  raw_title: \"RubyConfBY 2020: Stefan Wintermeyer - The Greener Grass\"\n  speakers:\n    - Stefan Wintermeyer\n  event_name: \"RubyConfBY 2020\"\n  date: \"2020-07-18\"\n  published_at: \"2020-12-29\"\n  description: |-\n    All is good in Ruby and Rails land. Or is it? What about Elixir? Why do so many Ruby developers migrate into that functional programming space? The Elixir community tells how green the grass in functional programming land is. Is Elixir really so fast and stable? In his talk Stefan Wintermeyer dwells on the current state of both technologies and communities.\n  video_provider: \"youtube\"\n  video_id: \"BGonmvUbt08\"\n"
  },
  {
    "path": "data/rubyconf-by/series.yml",
    "content": "---\nname: \"RubyConfBY\"\nwebsite: \"https://2016.rubyconference.by/en/\"\ntwitter: \"rubyconfby\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - rubyconfby\n  - Ruby Conf BY\n  - Ruby Conference BY\n  - RubyConf BY\n  - Ruby Conf Belarus\n  - RubyConf Belarus\n"
  },
  {
    "path": "data/rubyconf-china/rubyconf-china-2017/event.yml",
    "content": "---\nid: \"rubyconf-china-2017\"\ntitle: \"RubyConf China 2017\"\ndescription: \"\"\nlocation: \"Hangzhou, China\"\nkind: \"conference\"\nstart_date: \"2017-09-16\"\nend_date: \"2017-09-17\"\nwebsite: \"http://rubyconfchina.org\"\ncoordinates:\n  latitude: 30.2741499\n  longitude: 120.15515\n"
  },
  {
    "path": "data/rubyconf-china/rubyconf-china-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconfchina.org\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-china/rubyconf-china-2023/event.yml",
    "content": "---\nid: \"rubyconf-china-2023\"\ntitle: \"RubyConf China 2023\"\ndescription: \"\"\nlocation: \"Shanghai, China\"\nkind: \"conference\"\nstart_date: \"2023-08-19\"\nend_date: \"2023-08-20\"\nwebsite: \"https://www.rubyconfchina.org\"\ncoordinates:\n  latitude: 31.230416\n  longitude: 121.473701\n"
  },
  {
    "path": "data/rubyconf-china/rubyconf-china-2023/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://www.rubyconfchina.org\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-china/rubyconf-china-2024/event.yml",
    "content": "---\nid: \"rubyconf-china-2024\"\ntitle: \"RubyConf China 2024\"\ndescription: \"\"\nlocation: \"Guangzhou, China\"\nkind: \"conference\"\nstart_date: \"2024-11-30\"\nend_date: \"2024-12-01\"\nwebsite: \"https://www.rubyconfchina.org\"\ncoordinates:\n  latitude: 23.1290799\n  longitude: 113.26436\n"
  },
  {
    "path": "data/rubyconf-china/rubyconf-china-2024/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://www.rubyconfchina.org\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-china/series.yml",
    "content": "---\nname: \"RubyConf China\"\nwebsite: \"http://rubyconfchina.org\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyconf-colombia/rubyconf-colombia-2015/event.yml",
    "content": "---\nid: \"rubyconf-colombia-2015\"\ntitle: \"RubyConf Colombia 2015\"\ndescription: \"\"\nlocation: \"Medellin, Colombia\"\nkind: \"conference\"\nstart_date: \"2015-10-15\"\nend_date: \"2015-10-16\"\nwebsite: \"http://2015.rubyconf.co/\"\ntwitter: \"rubyconfco\"\nplaylist: \"https://www.youtube.com/playlist?list=PLq_08z5fuQgFP64HqrRWd3RWUKmPFMdo6\"\ncoordinates:\n  latitude: 6.2476376\n  longitude: -75.56581530000001\n"
  },
  {
    "path": "data/rubyconf-colombia/rubyconf-colombia-2015/videos.yml",
    "content": "---\n- id: \"steve-klabnik-rubyconf-colombia-2015\"\n  title: \"What Rust can teach us about Ruby\"\n  raw_title: \"What Rust can teach us about Ruby\"\n  event_name: \"RubyConf Colombia 2015\"\n  date: \"2015-09-04\"\n  published_at: \"2016-01-21\"\n  description: |-\n    A presentation about what rust can teach us about ruby at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"1VDjHBRK9Eo\"\n  speakers:\n    - Steve Klabnik\n\n- id: \"ann-harter-rubyconf-colombia-2015\"\n  title: \"There is no Magic: Write your own HTTP server, and then stop\"\n  raw_title: \"There is no Magic: Write your own HTTP server, and then stop\"\n  event_name: \"RubyConf Colombia 2015\"\n  date: \"2015-09-04\"\n  published_at: \"2016-01-21\"\n  description: |-\n    A presentation about there is no magic: write your own http server, and then stop at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"uZGPZua6xgA\"\n  speakers:\n    - Ann Harter\n\n- id: \"nicols-hock-rubyconf-colombia-2015\"\n  title: \"Queue Based Architectures with AMQP\"\n  raw_title: \"Queue Based Architectures with AMQP\"\n  event_name: \"RubyConf Colombia 2015\"\n  date: \"2015-09-04\"\n  published_at: \"2016-01-21\"\n  description: |-\n    A presentation about queue based architectures with amqp at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"naZg0PZQJyw\"\n  speakers:\n    - Nicolás Hock\n\n- id: \"jean-pierre-rubyconf-colombia-2015\"\n  title: \"Ruby + Voice Control\"\n  raw_title: \"Ruby + Voice Control\"\n  event_name: \"RubyConf Colombia 2015\"\n  date: \"2015-09-04\"\n  published_at: \"2016-01-21\"\n  description: |-\n    A presentation about ruby + voice control at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"i53UHCa3d88\"\n  speakers:\n    - Jean Pierre\n\n- id: \"sharon-steed-rubyconf-colombia-2015\"\n  title: \"How to Talk to Humans: what stuttering can teach you about connecting with people\"\n  raw_title: \"How to Talk to Humans: what stuttering can teach you about connecting with people\"\n  event_name: \"RubyConf Colombia 2015\"\n  published_at: \"2016-01-21\"\n  date: \"2015-09-04\"\n  description: |-\n    A presentation about how to talk to humans: what stuttering can teach you about connecting with people at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"phos1sdtWuc\"\n  speakers:\n    - Sharon Steed\n\n- id: \"sarah-mei-rubyconf-colombia-2015\"\n  title: \"Is Your Code Too SOLID?\"\n  raw_title: \"Is Your Code Too SOLID?\"\n  event_name: \"RubyConf Colombia 2015\"\n  date: \"2015-09-04\"\n  published_at: \"2016-01-21\"\n  description: |-\n    A presentation about is your code too solid? at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"WtpQD1cR3mA\"\n  speakers:\n    - Sarah Mei\n\n- id: \"michel-martens-rubyconf-colombia-2015\"\n  title: \"Human Error, Mental Models and Simplicity\"\n  raw_title: \"Human Error, Mental Models and Simplicity\"\n  event_name: \"RubyConf Colombia 2015\"\n  date: \"2015-09-04\"\n  published_at: \"2016-01-21\"\n  description: |-\n    A presentation about human error, mental models and simplicity at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"pfiv_lSQp3Y\"\n  speakers:\n    - Michel Martens\n\n- id: \"david-padilla-rubyconf-colombia-2015\"\n  title: \"Escribiendo Música con Ruby\"\n  raw_title: \"Escribiendo Música con Ruby\"\n  event_name: \"RubyConf Colombia 2015\"\n  date: \"2015-09-04\"\n  published_at: \"2016-01-21\"\n  description: |-\n    A presentation about escribiendo música con ruby at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"OzeWiz467MM\"\n  speakers:\n    - David Padilla\n\n- id: \"matt-aimonetti-rubyconf-colombia-2015\"\n  title: \"10 Years of Ruby\"\n  raw_title: \"10 Years of Ruby\"\n  event_name: \"RubyConf Colombia 2015\"\n  date: \"2015-09-04\"\n  published_at: \"2016-01-21\"\n  description: |-\n    A presentation about 10 years of ruby at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"IWIPLzjIhTI\"\n  speakers:\n    - Matt Aimonetti\n\n- id: \"sandi-metz-rubyconf-colombia-2015\"\n  title: \"Nothing is Something\"\n  raw_title: \"Nothing is Something\"\n  event_name: \"RubyConf Colombia 2015\"\n  published_at: \"2016-02-01\"\n  date: \"2015-09-04\"\n  description: |-\n    A presentation about nothing is something at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"zc9OvLzS9mU\"\n  speakers:\n    - Sandi Metz\n\n- id: \"ray-hightower-rubyconf-colombia-2015\"\n  title: \"Supercomputing for Everyone featuring Ruby\"\n  raw_title: \"Supercomputing for Everyone featuring Ruby\"\n  event_name: \"RubyConf Colombia 2015\"\n  date: \"2015-09-04\"\n  published_at: \"2016-02-01\"\n  description: |-\n    A presentation about supercomputing for everyone featuring ruby at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"7ZinXb6qQ1U\"\n  speakers:\n    - Ray Hightower\n"
  },
  {
    "path": "data/rubyconf-colombia/rubyconf-colombia-2016/event.yml",
    "content": "---\nid: \"rubyconf-colombia-2016\"\ntitle: \"RubyConf Colombia 2016\"\ndescription: \"\"\nlocation: \"Medellin, Colombia\"\nkind: \"conference\"\nstart_date: \"2016-09-02\"\nend_date: \"2016-09-03\"\nwebsite: \"http://www.rubyconf.co/\"\ntwitter: \"rubyconfco\"\nplaylist: \"https://www.youtube.com/playlist?list=PLq_08z5fuQgGLwr7cJtU27IBgtz3Q4PII\"\ncoordinates:\n  latitude: 6.2476376\n  longitude: -75.56581530000001\n"
  },
  {
    "path": "data/rubyconf-colombia/rubyconf-colombia-2016/videos.yml",
    "content": "---\n- id: \"robert-mosolgo-rubyconf-colombia-2016\"\n  title: \"Data fetching with GraphQL and ActionCable\"\n  raw_title: \"Data fetching with GraphQL and ActionCable\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about data fetching with graphql and actioncable at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"9UG_xqc_Dvw\"\n  speakers:\n    - Robert Mosolgo\n\n- id: \"oscar-rendn-rubyconf-colombia-2016\"\n  title: \"Expert systems based on rules\"\n  raw_title: \"Expert systems based on rules\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about expert systems based on rules at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"EsOI1u2h-nU\"\n  speakers:\n    - Oscar Rendón\n\n- id: \"stella-cotton-rubyconf-colombia-2016\"\n  title: \"Site availability is for everybody\"\n  raw_title: \"Site availability is for everybody\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about site availability is for everybody at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"4rfvmbGcRdM\"\n  speakers:\n    - Stella Cotton\n\n- id: \"ann-harter-rubyconf-colombia-2016\"\n  title: \"The Rubyists guide to Existentialism\"\n  raw_title: \"The Rubyists guide to Existentialism\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about the rubyists guide to existentialism at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"hP-mmN0gA70\"\n  speakers:\n    - Ann Harter\n\n- id: \"katherine-wu-rubyconf-colombia-2016\"\n  title: \"Wow code, such read!\"\n  raw_title: \"Wow code, such read!\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about wow code, such read! at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"u2VrYZDh-4g\"\n  speakers:\n    - Katherine Wu\n\n- id: \"rafael-mendona-frana-rubyconf-colombia-2016\"\n  title: \"Riding Rails for decades\"\n  raw_title: \"Riding Rails for decades\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about riding rails for decades at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"ePKlEUEa7EY\"\n  speakers:\n    - Rafael Mendonça França\n\n- id: \"federico-builes-rubyconf-colombia-2016\"\n  title: \"Computer science, engineering and craft\"\n  raw_title: \"Computer science, engineering and craft\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about computer science, engineering and craft at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"E_o9W48mun0\"\n  speakers:\n    - Federico Builes\n    - Sebastián Arcila\n\n- id: \"nicols-hock-rubyconf-colombia-2016\"\n  title: \"The process of building APIs\"\n  raw_title: \"The process of building APIs\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about the process of building apis at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"gX-EIC3izAg\"\n  speakers:\n    - Nicolás Hock\n\n- id: \"cate-huston-rubyconf-colombia-2016\"\n  title: \"Applied humaning for technical interviews\"\n  raw_title: \"Applied humaning for technical interviews\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about applied humaning for technical interviews at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"yeV62jgu1l0\"\n  speakers:\n    - Cate Huston\n\n- id: \"camille-fournier-rubyconf-colombia-2016\"\n  title: \"The elements of scaling\"\n  raw_title: \"The elements of scaling\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about the elements of scaling at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"z8V8LO6tTRA\"\n  speakers:\n    - Camille Fournier\n\n- id: \"nick-sutterer-rubyconf-colombia-2016\"\n  title: \"The illusion of stable APIs\"\n  raw_title: \"The illusion of stable APIs\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about the illusion of stable apis at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"xjmo9rSB1N4\"\n  speakers:\n    - Nick Sutterer\n\n- id: \"jessica-rudder-rubyconf-colombia-2016\"\n  title: \"Will it inject? A look at SQL injection and ActiveRecord\"\n  raw_title: \"Will it inject? A look at SQL injection and ActiveRecord\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about will it inject? a look at sql injection and activerecord at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"gV7laXXBpBY\"\n  speakers:\n    - Jessica Rudder\n\n- id: \"david-pelez-rubyconf-colombia-2016\"\n  title: \"Functional Ruby and the (big) dependency diet\"\n  raw_title: \"Functional Ruby and the (big) dependency diet\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    A presentation about functional ruby and the (big) dependency diet at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"ZUleJSBjMRI\"\n  speakers:\n    - David Peláez\n\n- id: \"miles-woodroffe-rubyconf-colombia-2016\"\n  title: \"Going global on Rails\"\n  raw_title: \"Going global on Rails\"\n  event_name: \"RubyConf Colombia 2016\"\n  date: \"2016-09-02\"\n  published_at: \"2017-01-26\"\n  description: |-\n    Going global on Rails: Lessons learned internationalising Japan’s biggest recipe service\n  video_provider: \"youtube\"\n  video_id: \"O8ACjy2Kq5I\"\n  speakers:\n    - Miles Woodroffe\n"
  },
  {
    "path": "data/rubyconf-colombia/rubyconf-colombia-2017/event.yml",
    "content": "---\nid: \"rubyconf-colombia-2017\"\ntitle: \"RubyConf Colombia 2017\"\ndescription: \"\"\nlocation: \"Medellin, Colombia\"\nkind: \"conference\"\nstart_date: \"2017-09-08\"\nend_date: \"2017-09-09\"\nwebsite: \"http://2017.rubyconf.co/\"\ntwitter: \"rubyconfco\"\nplaylist: \"https://www.youtube.com/playlist?list=PLq_08z5fuQgFnASevZeUy1l4lbaqoidcL\"\ncoordinates:\n  latitude: 6.2476376\n  longitude: -75.56581530000001\n"
  },
  {
    "path": "data/rubyconf-colombia/rubyconf-colombia-2017/videos.yml",
    "content": "---\n- id: \"sebastin-arcila-rubyconf-colombia-2017\"\n  title: \"Smashing dense graphs\"\n  raw_title: \"Smashing dense graphs\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-01-31\"\n  description: |-\n    Have you ever hit your face against a “giant distributed event consistent graph”? and still was not sure what it was and how to handle it. I was there and this is my history.\n  video_provider: \"youtube\"\n  video_id: \"jzsEfZHyGLo\"\n  speakers:\n    - Sebastián Arcila\n\n- id: \"nicole-lopez-rubyconf-colombia-2017\"\n  title: \"A Tale of Two Codepaths: Notes on a Refactor\"\n  raw_title: \"A Tale of Two Codepaths: Notes on a Refactor\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-01-31\"\n  description: |-\n    Refactoring is a daunting task. It’s hard to resist the urge to change all the things at once, and it’s easy to find yourself in an endless pit of data issues, bugs, and unhappy business owners. We’ll cover how to make changes safely and manage the inevitable complexities of phasing out legacy code.\n  video_provider: \"youtube\"\n  video_id: \"3rVcIrycg7Y\"\n  speakers:\n    - Nicole Lopez\n\n- id: \"eileen-m-uchitelle-rubyconf-colombia-2017\"\n  title: \"Building the Rails ActionDispatch::SystemTestCase framework\"\n  raw_title: \"Building the Rails ActionDispatch::SystemTestCase framework\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-01-31\"\n  description: |-\n    t the 2014 RailsConf DHH declared system testing would be added to Rails. Three years later, Rails 5.1 makes good on that promise by introducing a new testing framework: ActionDispatch::SystemTestCase. The feature brings system testing to Rails with zero application configuration by adding Capybara integration. After a demonstration of the new framework, we'll walk through what's uniquely involved with building OSS features & how the architecture follows the Rails Doctrine. We'll take a rare look at what it takes to build a major feature for Rails, including goals, design decisions, & roadblocks.\n  video_provider: \"youtube\"\n  video_id: \"wY9RulVUcDk\"\n  speakers:\n    - Eileen M. Uchitelle\n\n- id: \"gabi-stefanini-rubyconf-colombia-2017\"\n  title: \"Keeping Code Style Sanity in a 13-year-old Codebase\"\n  raw_title: \"Keeping Code Style Sanity in a 13-year-old Codebase\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-02-01\"\n  description: |-\n    We’ll explore the good, bad, and the ugly of code style consistency as illustrated by the history of Shopify’s codebase. You will hear about our techniques, tools and guides to enrich developer experience without compromising productivity and highlight strategies to push for better code consistency.\n  video_provider: \"youtube\"\n  video_id: \"QO06lMh6OiA\"\n  speakers:\n    - Gabi Stefanini\n\n- id: \"jason-charnes-rubyconf-colombia-2017\"\n  title: \"Discovering anxiety\"\n  raw_title: \"Discovering anxiety\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-02-01\"\n  description: |-\n    A presentation about discovering anxiety at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"jrh78wn5aQA\"\n  speakers:\n    - Jason Charnes\n\n- id: \"aaron-patterson-rubyconf-colombia-2017\"\n  title: \"Compacting GC in MRI\"\n  raw_title: \"Compacting GC in MRI\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-02-01\"\n  description: |-\n    We will talk about implementing a compacting GC for MRI. This talk will cover compaction algorithms, along with implementation details, and challenges specific to MRI. Well cover low level and high level memory measurement tools, how to use them, and what they're telling us. We'll cover copy-on-write optimizations and how our GC impacts them. After this talk you should have a better understanding of how Ruby's memory management interacts with the system memory, how you can measure it, and how to adjust your application to work in concert with the system's memory.\n  video_provider: \"youtube\"\n  video_id: \"ptG5HtmvQx8\"\n  speakers:\n    - Aaron Patterson\n\n- id: \"dana-scheider-rubyconf-colombia-2017\"\n  title: \"A beginner's guide to Open Source\"\n  raw_title: \"A beginner's guide to Open Source\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-02-02\"\n  description: |-\n    Making your first open source contributions can be daunting. This talk demystifies how open-source projects work and how you can get involved with the projects you love.\n  video_provider: \"youtube\"\n  video_id: \"EKpCU67yvY8\"\n  speakers:\n    - Dana Scheider\n\n- id: \"zachary-scott-rubyconf-colombia-2017\"\n  title: \"10 years of Sinatra\"\n  raw_title: \"10 years of Sinatra\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-02-06\"\n  description: |-\n    A presentation about 10 years of sinatra at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"3grWCELiJ9A\"\n  speakers:\n    - Zachary Scott\n\n- id: \"mauricio-a-chvez-rubyconf-colombia-2017\"\n  title: \"Ruby internals\"\n  raw_title: \"Ruby internals\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-02-09\"\n  description: |-\n    Ruby Internals is a talk to discover what happens when you ask Ruby to execute your code. We will explore how code is executed, starting with Ruby’s tokenizer, parser, compilation, and finally, code execution.\n  video_provider: \"youtube\"\n  video_id: \"PT5UO23zOHc\"\n  speakers:\n    - Mauricio A Chávez\n\n- id: \"phil-sturgeon-rubyconf-colombia-2017\"\n  title: \"A no nonsense GraphQL and REST comparison\"\n  raw_title: \"A no nonsense GraphQL and REST comparison\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-02-09\"\n  description: |-\n    A presentation about a no nonsense graphql and rest comparison at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"vgm_uGmspMI\"\n  speakers:\n    - Phil Sturgeon\n\n- id: \"eileen-m-uchitelle-rubyconf-colombia-2017-panel-rails-core-team\"\n  title: \"Panel: Rails Core Team\"\n  raw_title: \"Rails core team panel\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-03-21\"\n  description: |-\n    A presentation about rails core team panel at RubyConf Colombia.\n  video_provider: \"youtube\"\n  video_id: \"v_11VoDDbpU\"\n  speakers:\n    - Eileen M. Uchitelle\n    - Aaron Patterson\n    - Rafael Mendonça França\n    - Guillermo Iguaran\n\n- id: \"germn-escobar-rubyconf-colombia-2017\"\n  title: \"Minitest with Capybara: Tips, Tricks and Lessons Learned\"\n  raw_title: \"Minitest with Capybara: Tips, Tricks and Lessons Learned\"\n  event_name: \"RubyConf Colombia 2017\"\n  date: \"2017-09-08\"\n  published_at: \"2018-03-21\"\n  description: |-\n    Testing can be hard. But testing can also be a lot of fun and a rewarding experience! In this talk I’ll show you how I test, what I test, and what I have learned after writing hundreds of tests with Minitest, Fixtures and Capybara, after switching from RSpec and Factory Girl.\n  video_provider: \"youtube\"\n  video_id: \"GYbf48APy1I\"\n  speakers:\n    - Germán Escobar\n"
  },
  {
    "path": "data/rubyconf-colombia/rubyconf-colombia-2019/event.yml",
    "content": "---\nid: \"rubyconf-colombia-2019\"\ntitle: \"RubyConf Colombia 2019\"\ndescription: \"\"\nlocation: \"Medellín, Colombia\"\nkind: \"conference\"\nstart_date: \"2019-09-20\"\nend_date: \"2019-09-21\"\nwebsite: \"https://rubyconf.co\"\ntwitter: \"rubyconfco\"\ncoordinates:\n  latitude: 6.2476376\n  longitude: -75.56581530000001\n"
  },
  {
    "path": "data/rubyconf-colombia/rubyconf-colombia-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyconf.co\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-colombia/series.yml",
    "content": "---\nname: \"RubyConf Colombia\"\nwebsite: \"https://www.rubyconf.co/\"\ntwitter: \"rubyconfco\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"CO\"\nyoutube_channel_name: \"RubyConfCo\"\nlanguage: \"spanish\"\nyoutube_channel_id: \"UCLvVrdSpILOIW8PN1d2fJmg\"\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2010/event.yml",
    "content": "---\nid: \"rubyconf-india-2010\"\ntitle: \"RubyConf India 2010\"\ndescription: |-\n  Inaugural Ruby conference held in India.\nlocation: \"Bangalore, India\"\nvenue: \"The Royal Orchid Hotel\"\nkind: \"conference\"\nstart_date: \"2010-03-20\"\nend_date: \"2010-03-21\"\nwebsite: \"https://2010.rubyconfindia.org\"\ntwitter: \"rubyconfindia\"\ncoordinates:\n  latitude: 12.9716\n  longitude: 77.5946\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2010.rubyconfindia.org/\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2011/event.yml",
    "content": "---\nid: \"rubyconf-india-2011\"\ntitle: \"RubyConf India 2011\"\ndescription: |-\n  Second annual Ruby conference held in India.\nlocation: \"Bangalore, India\"\nvenue: \"The Royal Orchid Hotel\"\nkind: \"conference\"\nstart_date: \"2011-05-28\"\nend_date: \"2011-05-29\"\nwebsite: \"https://2011.rubyconfindia.org\"\ntwitter: \"rubyconfindia\"\ncoordinates:\n  latitude: 12.9716\n  longitude: 77.5946\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2011.rubyconfindia.org/\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2012/event.yml",
    "content": "---\nid: \"rubyconf-india-2012\"\ntitle: \"RubyConf India 2012\"\ndescription: |-\n  Third annual Ruby conference held in India.\nlocation: \"Pune, India\"\nvenue: \"Hyatt Regency Pune\"\nkind: \"conference\"\nstart_date: \"2012-03-24\"\nend_date: \"2012-03-25\"\nwebsite: \"https://2012.rubyconfindia.org\"\ntwitter: \"rubyconfindia\"\nbanner_background: \"#9F0000\"\nfeatured_background: \"#9F0000\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 18.5679\n  longitude: 73.9142\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2012.rubyconfindia.org/\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2013/event.yml",
    "content": "---\nid: \"rubyconf-india-2013\"\ntitle: \"RubyConf India 2013\"\ndescription: |-\n  Premier Ruby conference focusing on community growth, technical talks, and networking for Ruby developers in India.\nlocation: \"Pune, India\"\nvenue: \"Hyatt Regency Pune\"\nkind: \"conference\"\nstart_date: \"2013-06-22\"\nend_date: \"2013-06-23\"\nwebsite: \"https://2013.rubyconfindia.org\"\ntwitter: \"rubyconfindia\"\ncoordinates:\n  latitude: 18.5679\n  longitude: 73.9142\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2013.rubyconfindia.org/\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2014/event.yml",
    "content": "---\nid: \"PLNyYRB_d4fk2Hz8_HuHIAPv5dJGrnxh14\"\ntitle: \"RubyConf India 2014\"\ndescription: \"\"\nlocation: \"Goa, India\"\nkind: \"conference\"\nstart_date: \"2014-03-22\"\nend_date: \"2014-03-23\"\nwebsite: \"https://2014.rubyconfindia.org/\"\ntwitter: \"rubyconfindia\"\nplaylist: \"https://www.youtube.com/playlist?list=PLNyYRB_d4fk2Hz8_HuHIAPv5dJGrnxh14\"\nbanner_background: \"#FEF1C3\"\nfeatured_background: \"#FEF1C3\"\nfeatured_color: \"#AA0300\"\ncoordinates:\n  latitude: 15.2993265\n  longitude: 74.12399599999999\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2014.rubyconfindia.org/\n# Videos: https://www.youtube.com/playlist?list=PLNyYRB_d4fk2Hz8_HuHIAPv5dJGrnxh14\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2015/event.yml",
    "content": "---\nid: \"UCRNZy_ouJ1ai_uYwDBR2J5Q\"\ntitle: \"RubyConf India 2015\"\ndescription: \"\"\nlocation: \"Goa, India\"\nkind: \"conference\"\nstart_date: \"2015-04-03\"\nend_date: \"2015-04-05\"\nwebsite: \"https://2015.rubyconfindia.org/\"\ntwitter: \"rubyconfindia\"\nplaylist: \"https://www.youtube.com/channel/UCRNZy_ouJ1ai_uYwDBR2J5Q\"\nbanner_background: \"#AA0300\"\nfeatured_background: \"#AA0300\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 15.2993265\n  longitude: 74.12399599999999\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2015.rubyconfindia.org/\n# Videos: https://www.youtube.com/channel/UCRNZy_ouJ1ai_uYwDBR2J5Q/videos\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2016/event.yml",
    "content": "---\nid: \"PLNyYRB_d4fk2LfGLjyv8Oa-ruc4EgkfAQ\"\ntitle: \"RubyConf India 2016\"\ndescription: \"\"\nlocation: \"Kochi, India\"\nkind: \"conference\"\nstart_date: \"2016-03-19\"\nend_date: \"2016-03-20\"\nwebsite: \"https://2016.rubyconfindia.org/\"\ntwitter: \"rubyconfindia\"\nplaylist: \"https://www.youtube.com/playlist?list=PLNyYRB_d4fk2LfGLjyv8Oa-ruc4EgkfAQ\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#636363\"\ncoordinates:\n  latitude: 9.9312328\n  longitude: 76.26730409999999\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2016.rubyconfindia.org/\n# Videos: https://www.youtube.com/playlist?list=PLNyYRB_d4fk2LfGLjyv8Oa-ruc4EgkfAQ\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2017/event.yml",
    "content": "---\nid: \"PLe872Yf6CJWHc6XDdHo_22hktStG866-6\"\ntitle: \"RubyConf India 2017\"\ndescription: |-\n  On the 28th & 29th of January 2017, the Eighth edition of RubyConfIndia was held at Le Meridien in the scenic & historic coastal town of Kochi.\nlocation: \"Kochi, India\"\nkind: \"conference\"\nstart_date: \"2017-01-28\"\nend_date: \"2017-01-29\"\nwebsite: \"http://2017.rubyconfindia.org/\"\ntwitter: \"rubyconfindia\"\nplaylist: \"https://www.youtube.com/playlist?list=PLe872Yf6CJWHc6XDdHo_22hktStG866-6\"\nbanner_background: \"#7D200F\"\nfeatured_background: \"#7D200F\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 9.9312328\n  longitude: 76.26730409999999\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2017/videos.yml",
    "content": "---\n- title: \"Opening Keynote\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"2. Matz - Opening Keynote\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"GShlkGXQTWE\"\n  speakers:\n    - 'Yukihiro \"Matz\" Matsumoto'\n  id: \"matz-rubyconf-india-2017\"\n  date: \"2017-01-28\"\n\n- title: \"mRuby on small devices\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"3. Shashank Date - mRuby on small devices\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"Y0jQDguUDdw\"\n  speakers:\n    - Shashank Date\n  id: \"shashank-date-rubyconf-india-2017\"\n  date: \"2017-01-28\"\n\n- title: \"Lazy, lazy, lazy all the things!\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"4. Shaunak Pagnis on Lazy, lazy, lazy all the things!\"\n  published_at: \"2017-03-09\"\n  video_provider: \"youtube\"\n  video_id: \"SNQSwKIN5oo\"\n  speakers:\n    - Shaunak Pagnis\n  id: \"shaunak-pagnis-rubyconf-india-2017\"\n  date: \"2017-01-28\"\n\n- title: \"10 things not to do before going to production with rails+mongo+sidekiq\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"5. Kiran Narasareddy - 10 things not to do before going to production with rails+mongo+sidekiq\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"LInTGF8aTkU\"\n  speakers:\n    - Kiran Narasareddy\n  id: \"kiran-narasareddy-rubyconf-india-2017\"\n  date: \"2017-01-28\"\n\n- title: \"Introducing Rubex\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"6. Sameer Deshmukh - Introducing Rubex\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"5gGhW4vUTfc\"\n  speakers:\n    - Sameer Deshmukh\n  id: \"sameer-deshmukh-rubyconf-india-2017\"\n  date: \"2017-01-28\"\n\n- title: \"Concurrent ruby modern tools explained\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"9. Anil Wadghule - Concurrent ruby modern tools explained\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"K8c-gfUcnZA\"\n  speakers:\n    - Anil Wadghule\n  id: \"anil-wadghule-rubyconf-india-2017\"\n  date: \"2017-01-28\"\n\n- title: \"Lightning Talks\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"10. Lightning Talks\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"E2-UPRMYrcs\"\n  id: \"lightning-talks-rubyconf-india-2017\"\n  date: \"2017-01-28\"\n  speakers:\n    - TODO\n\n- title: \"Production Ready Ruby\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"D21. Adam Hawkins - Production Ready Ruby\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"6bpq1PoAzOQ\"\n  speakers:\n    - Adam Hawkins\n  id: \"adam-hawkins-rubyconf-india-2017\"\n  date: \"2017-01-29\"\n\n- title: \"Scientific Computing on JRuby\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"D22. Prasun Anand - Scientific Computing on JRuby\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"mZEZ13nr-LQ\"\n  speakers:\n    - Prasun Anand\n  id: \"prasun-anand-rubyconf-india-2017\"\n  date: \"2017-01-29\"\n\n- title: \"Getting started with Rails\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"D23. Anagha R - Getting started with Rails\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"CZQjoXRuhoY\"\n  speakers:\n    - Anagha R\n  id: \"anagha-r-rubyconf-india-2017\"\n  date: \"2017-01-29\"\n\n- title: \"It's 2017, and I _still_ want to sell you a graph database!\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"D24. Swanand Pagnis - It's 2017, and I _still_ want to sell you a graph database!\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"a-3sm1rUbPg\"\n  speakers:\n    - Swanand Pagnis\n  id: \"swanand-pagnis-rubyconf-india-2017\"\n  date: \"2017-01-29\"\n\n- title: \"This Bot Will Pump You Up\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"D26. Aaron Cruz - This Bot Will Pump You Up\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"_II771f7p4g\"\n  speakers:\n    - Aaron Cruz\n  id: \"aaron-cruz-rubyconf-india-2017\"\n  date: \"2017-01-29\"\n\n- title: \"Slow Mo\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"D27. Richard Schneeman - Slow Mo (Laptop Audio Required)\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"BwAFcMrisLw\"\n  speakers:\n    - Richard Schneeman\n  id: \"richard-schneeman-rubyconf-india-2017\"\n  date: \"2017-01-29\"\n- title: \"Panel Discussion: Topic - Scientific Computing in Ruby\"\n  event_name: \"RubyConf India 2017\"\n  description: \"\"\n  raw_title: \"D28. Panel Discussion: Topic - Scientific Computing in Ruby\"\n  published_at: \"2017-03-08\"\n  video_provider: \"youtube\"\n  video_id: \"tmyEXwUPNLM\"\n  id: \"panel-discussion-topic-scientific-computing-in-ruby-rubyconf-india-2017\"\n  date: \"2017-01-29\"\n  speakers:\n    - TODO\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2018/event.yml",
    "content": "---\nid: \"PLe872Yf6CJWGYKLny9jFs9mLv0Z94m8k4\"\ntitle: \"RubyConf India 2018\"\ndescription: \"\"\nlocation: \"Bengaluru, India\"\nkind: \"conference\"\nstart_date: \"2018-02-09\"\nend_date: \"2018-02-10\"\nwebsite: \"https://2018.rubyconfindia.org/\"\ntwitter: \"RubyConfIndia\"\nplaylist: \"https://www.youtube.com/playlist?list=PLe872Yf6CJWGYKLny9jFs9mLv0Z94m8k4\"\ncoordinates:\n  latitude: 12.9628669\n  longitude: 77.57750899999999\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2018/videos.yml",
    "content": "---\n- title: \"Opening keynote #NOCODE\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    For beginning programmers, coding is a superpower. But for experienced developers, code-centric thinking can also be a trap. Prepare to have your conception of what it means to be a programmer challenged, as we explore how to increase your leverage by choosing NOT to write code.\n  raw_title: \"Day 1 - Avdi Grimm Opening keynote #NOCODE\"\n  date: \"2018-02-09\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"Vp9zb9CO1n8\"\n  speakers:\n    - Avdi Grimm\n  id: \"day-1-avdi-grimm-opening-keynote-nocode-rubyconf-india-2018\"\n\n- title: \"Reflection in Ruby: Understanding the Implications of Loading Gems and Files\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    Have you wondered what is provided by a gem? What about monkey patches? Can you be sure that new changes do not conflict with old ones? We will demonstrate how to use Ruby’s built-in reflection methods to address all of these topics, building up from foundations available to every Ruby developer.\n  raw_title: \"Day 1 - Paul Stefan Ort Reflection in Ruby: Understanding the Implications of Loading Gems and Files\"\n  date: \"2018-02-09\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"YzNtTIkga9g\"\n  speakers:\n    - Paul Stefan Ort\n  id: \"day-1-paul-stefan-ort-reflection-in-ruby-understanding-the-implications-of-loading-gems-and-files-rubyconf-india-2018\"\n\n- title: \"Towards a de-centralized world with Ruby\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    The centralized system based service invites privacy concerns and questions how the data is handled/censored by the system. Discuss how having a decentralised software would really help us, Implementation of a simple decentralised app, Using Diaspora and Mastadon as examples.\n  raw_title: \"Day 1 - Aboobacker's talk on Towards a de-centralized world with Ruby\"\n  date: \"2018-02-09\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"MZ1pZM_DFlY\"\n  speakers:\n    - Aboobacker MK\n  id: \"day-1-aboobacker-s-talk-on-towards-a-de-centralized-world-with-ruby-rubyconf-india-2018\"\n\n- title: \"A Rack and Morty adventure in serving requests\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    In this talk you’ll go through Rack from request to response. Starting with a basic “Hello C137” request and moving to something more complex. We’ll find what Rack enables us to do, write tests for our code, learn how to create reusable middleware, and how it fits in Ruby frameworks like Rails.\n  raw_title: \"Day 1 - Shobhit Bakliwal's Talk on A Rack and Morty adventure in serving requests\"\n  date: \"2018-02-09\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"vPX9MfwZ6_Y\"\n  speakers:\n    - Shobhit Bakliwal\n  id: \"day-1-shobhit-bakliwal-s-talk-on-a-rack-and-morty-adventure-in-serving-requests-rubyconf-india-2018\"\n\n- title: \"Reusing the Wheel\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    This talk demonstrates with examples how to write better Ruby code using some lesser known, underused ruby/rails methods & abstractions. Don’t miss this talk if you want to learn about some simple yet powerful methods like ‘enum#flat_map’ & ‘object#tap’ that can help you code like a pro using Ruby.\n  raw_title: \"Day 1 - Tony Vincent's Talk on Reusing the Wheel\"\n  date: \"2018-02-09\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"4tdhIrV8TBQ\"\n  speakers:\n    - Tony Vincent\n  id: \"day-1-tony-vincent-s-talk-on-reusing-the-wheel-rubyconf-india-2018\"\n\n- title: \"Faster green builds: The key to developer happiness ..!!\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    Wouldn’t it be great if your the test cases were blazingly fast? In this experience talk, I will share how I reduced the test suite run time by 75%. I will share how using certain expectations, selectors, what to test and team work can lead to faster test cases.\n  raw_title: 'Day 1 - Rishi Jain''s Talk on \"Faster green builds: The key to developer happiness ..!!\"'\n  date: \"2018-02-09\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"Kvvb6JAgPiw\"\n  speakers:\n    - Rishi Jain\n  id: \"day-1-rishi-jain-s-talk-on-faster-green-builds-the-key-to-developer-happiness-rubyconf-india-2018\"\n\n- title: \"Scaling up: Myths Busted!!\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    Scaling a legacy system is something we all face at one point or the other. In this talk, I will share about scaling a Write heavy system along with some of the myths busted in process. These learning and myths will leave you with a thirst of doing your own research as per your use-cases for sure.\n  raw_title: 'Day 1 - Tushar Maroo''s Talk on \"Scaling up: Myths Busted!!\"'\n  date: \"2018-02-09\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"ukPazaSfTAo\"\n  speakers:\n    - Tushar Maroo\n  id: \"day-1-tushar-maroo-s-talk-on-scaling-up-myths-busted-rubyconf-india-2018\"\n\n- title: \"Panel discussion\"\n  event_name: \"RubyConf India 2018\"\n  description: \"\"\n  raw_title: \"Day 1 -  Panel discussion\"\n  date: \"2018-02-09\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"oTVaFWkRgeE\"\n  id: \"day-1-panel-discussion-rubyconf-india-2018\"\n  speakers:\n    - Sidu Ponnappa\n    - Sachin Shintre\n    - Avdi Grimm\n    - Keith Bennett\n\n- title: \"Closing Keynote: Algorithms to live by and why should we care\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    In this talk we will discuss algorithmic thinking in everyday life in language we can all understand. We will explore widely applicable algorithms, and how they reveal themselves in our everyday lives, so that we better understand what when and how we can use them in our programs.\n  raw_title: \"Day 1 - Elle Meredith's Closing Keynote on Algorithms to live by and why should we care\"\n  date: \"2018-02-09\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"YMk13BAxznY\"\n  speakers:\n    - Elle Meredith\n  id: \"day-1-elle-meredith-s-closing-keynote-on-algorithms-to-live-by-and-why-should-we-care-rubyconf-india-2018\"\n\n- title: \"Opening Keynote: Programming Carbon Based Wetwares\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    At some point in your programming life, it might fall upon you to be responsible for the output of other humans. Humans run a weird carbon-based wetware that is infamous for its highly inconsistent API, fuzzy logic and extreme fragmentation. I’ll help you understand, work with and scale this wetware.\n  raw_title: 'Day 2 - Opening Keynote by Siddharth Sharma on \"Programming Carbon Based Wetwares\"'\n  date: \"2018-02-10\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"t6Mz_jzZLwk\"\n  speakers:\n    - Siddharth Sharma\n  id: \"day-2-opening-keynote-by-siddharth-sharma-on-programming-carbon-based-wetwares-rubyconf-india-2018\"\n\n- title: \"When The Whole World Is Your Database\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    How to model all real world concepts in Ruby and don’t lose your mind in the process? How to fetch data uniformly from Wikidata, WorldBank, OpenStreetMap, and TheMoviesDB and mash them up?… And why would anybody try to lift up such a task? Answers are coming.\n  raw_title: 'Day 2 - Talk by Victor Shepelev on \"When The Whole World Is Your Database\"'\n  date: \"2018-02-10\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"x9GePP3B0oE\"\n  speakers:\n    - Victor Shepelev\n  id: \"day-2-talk-by-victor-shepelev-on-when-the-whole-world-is-your-database-rubyconf-india-2018\"\n\n- title: \"GPU-accelerated Libraries for Ruby\"\n  event_name: \"RubyConf India 2018\"\n  description: \"\"\n  raw_title: 'Day 2 - Talk by Prasun Anand on \"GPU-accelerated Libraries for Ruby\"'\n  date: \"2018-02-10\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"Um8DhAk7DOo\"\n  speakers:\n    - Prasun Anand\n  id: \"day-2-talk-by-prasun-anand-on-gpu-accelerated-libraries-for-ruby-rubyconf-india-2018\"\n\n- title: \"Multi-tenant applications and challenges I faced\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    Multi-tenant applications are some of the most interesting applications. How do you make such applications using Postgresql and Elasticsearch which work very seamlessly together? What are the challenges I faced when creating a multi-tenant application used by many banks and airline loyalty programs?\n  raw_title: 'Day 2 - Talk by Aram Bhusal on \"Multi-tenant applications and challenges I faced\"'\n  date: \"2018-02-10\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"cadhbLZ5HRQ\"\n  speakers:\n    - Aram Bhusal\n  id: \"day-2-talk-by-aram-bhusal-on-multi-tenant-applications-and-challenges-i-faced-rubyconf-india-2018\"\n\n- title: \"Prototyping Kubernetes CRI With Ruby and gRPC\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    Are you interested in wondering what Ruby can do to make this containerized world better? Want to know what is happening under the hood when Kubernetes is running? Then this talk is for you! In this talk, we will explore how we can make the best use of Ruby, gRPC, and k8s to orchestrate containers.\n  raw_title: 'Day 2 - Talk by Kei Sawada on \"Prototyping Kubernetes CRI With Ruby and gRPC\"'\n  date: \"2018-02-10\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"1h-vzx9Ia6Q\"\n  speakers:\n    - Kei Sawada\n  id: \"day-2-talk-by-kei-sawada-on-prototyping-kubernetes-cri-with-ruby-and-grpc-rubyconf-india-2018\"\n\n- title: \"Closing Keynote: UTC is Enough for Everybody, Right?\"\n  event_name: \"RubyConf India 2018\"\n  description: |-\n    \"Just use UTC\" is the common sentiment we give programmers when it comes to dates and times. But that's not... entirely... accurate... particularly when we're building applications meant to be seen and used by multiple humans in multiple timezones. There's a lot of very valuable things we can learn to help us improve our software when it comes to times and dates.\n  raw_title: 'Day 2 - Closing Keynote by Zach Holman on \"UTC is Enough for Everybody, Right?\"'\n  date: \"2018-02-10\"\n  published_at: \"2018-03-11\"\n  video_provider: \"youtube\"\n  video_id: \"aEvB98CstOk\"\n  speakers:\n    - Zach Holman\n  id: \"day-2-closing-keynote-by-zach-holman-on-utc-is-enough-for-everybody-right-rubyconf-india-2018\"\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2019/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/rci19\"\n  close_date: \"2018-11-30\"\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2019/event.yml",
    "content": "---\nid: \"PLbgP71NCXCqEFr8nuY2mhAobKv_ldqL2f\"\ntitle: \"RubyConf India 2019\"\ndescription: \"\"\nlocation: \"Goa, India\"\nkind: \"conference\"\nstart_date: \"2019-01-20\"\nend_date: \"2019-01-21\"\nwebsite: \"http://2019.rubyconfindia.org/\"\ntwitter: \"rubyconfindia\"\nplaylist: \"https://www.youtube.com/playlist?list=PLbgP71NCXCqEFr8nuY2mhAobKv_ldqL2f\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#FF2600\"\ncoordinates:\n  latitude: 15.2993265\n  longitude: 74.12399599999999\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2019/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum\"\n      level: 1\n      sponsors:\n        - name: \"GO-JEK\"\n          website: \"https://www.gojek.com\"\n          slug: \"gojek\"\n          description: |-\n            Super App. Indonesia's first unicorn. One app for food, commuting, payments, shopping, delivery and more. GO-JEK Tech runs one of the largest JRuby, Java and Go clusters in Asia.\n\n    - name: \"Gold\"\n      level: 2\n      sponsors:\n        - name: \"Coupa\"\n          website: \"https://www.coupa.com\"\n          slug: \"coupa\"\n          description: |-\n            Business Spend Management (BSM) platform. Uses RoR, React, Go, AWS, Azure. Machine Learning and AI for data classification.\n\n        - name: \"Josh Software\"\n          website: \"https://joshsoftware.com\"\n          slug: \"joshsoftware\"\n          description: |-\n            Ruby on Rails development shop since 2007. Focus on high performance, scalability and code quality. Team of 65, active in open source.\n\n    - name: \"Silver\"\n      level: 3\n      sponsors:\n        - name: \"Maropost\"\n          website: \"https://www.maropost.com\"\n          slug: \"maropost\"\n          description: |-\n            B2C cloud-based sales and marketing suite. Headquartered in Toronto. Trusted by DigitalMarketer, New York Post, Mercedes-Benz, SHOP.com, Yext.\n\n    - name: \"Digital Sponsor\"\n      level: 4\n      sponsors:\n        - name: \"BigBinary\"\n          website: \"https://www.bigbinary.com\"\n          slug: \"bigbinary\"\n          description: |-\n            Ruby on Rails consulting company based in San Francisco, Miami and Pune. Top contributors to Ruby on Rails. Web and mobile with Rails, React, React Native.\n\n    - name: \"Hoodies and Mugs Sponsor\"\n      level: 5\n      sponsors:\n        - name: \"Pepipost\"\n          website: \"https://www.pepipost.com\"\n          slug: \"pepipost\"\n          description: |-\n            Cloud-based email delivery platform for transactional emails. Focus on clean email ecosystem and good sender practices.\n\n    - name: \"Media Sponsor\"\n      level: 6\n      sponsors:\n        - name: \"Ruby Garage\"\n          website: \"https://rubygarage.org\"\n          slug: \"ruby-garage\"\n          description: |-\n            Web development company. Ruby and Ruby on Rails expertise. Blog on software development and technology trends.\n\n    - name: \"Bags Sponsor\"\n      level: 7\n      sponsors:\n        - name: \"Mavenhive\"\n          website: \"https://mavenhive.com\"\n          slug: \"mavenhive\"\n          description: |-\n            Bangalore-based boutique consulting firm. End-to-end product development and training. Long-time supporter of the Ruby community in India.\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2019/videos.yml",
    "content": "---\n- id: \"yukihiro-matsumoto-opening-keynote-rubyconf-india-2019\"\n  title: \"Opening Keynote: The Power of the Community\"\n  event_name: \"RubyConf India 2019\"\n  description: \"\"\n  raw_title: \"Opening Keynote\"\n  date: \"2019-01-20\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"DsmTTQhwP9I\"\n  speakers:\n    - Yukihiro Matsumoto\n  kind: \"keynote\"\n\n- id: \"swanand-pagnis-deep-work-mentality-rubyconf-india-2019\"\n  title: \"The Deep Work Mentality\"\n  event_name: \"RubyConf India 2019\"\n  description: |-\n    Mastering hard things fast is the ultimate x-factor\n  raw_title: \"The Deep Work Mentality\"\n  date: \"2019-01-20\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"korBf8lOU30\"\n  speakers:\n    - Swanand Pagnis\n\n- id: \"bala-kuma-semian-marginalia-freshdesk-rubyconf-india-2019\"\n  title: \"Semian, Marginalia, i18nema and more on scaling the Freshdesk monolith Rails app\"\n  event_name: \"RubyConf India 2019\"\n  description: |-\n    Bala KumaR - Semian, Marginalia, i18nema and more on scaling the Freshdesk monolith Rails app\n  raw_title: \"Semian, Marginalia, i18nema and more on scaling the Freshdesk monolith Rails app\"\n  date: \"2019-01-20\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"OjWz88qIEwo\"\n  speakers:\n    - Bala Kuma\n\n- id: \"brad-urani-command-line-toolkit-rubyconf-india-2019\"\n  title: \"The Ultimate Ruby Developer's Command Line Toolkit\"\n  event_name: \"RubyConf India 2019\"\n  description: \"\"\n  raw_title: \"The Ultimate Ruby Developer's Command Line Toolkit\"\n  date: \"2019-01-20\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"r5M8dyBCUhY\"\n  speakers:\n    - Brad Urani\n\n- id: \"ratnadeep-deshmane-story-of-rails-rubyconf-india-2019\"\n  title: \"The story of Rails!\"\n  event_name: \"RubyConf India 2019\"\n  description: \"\"\n  raw_title: \"The story of Rails!\"\n  date: \"2019-01-20\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"wEg5_8pYLnw\"\n  speakers:\n    - Ratnadeep Deshmane\n\n- id: \"gautam-rege-keynote-rubyconf-india-2019\"\n  title: \"Keynote: Confessions of a Ruby-preneur\"\n  event_name: \"RubyConf India 2019\"\n  description: \"\"\n  raw_title: \"Keynote\"\n  date: \"2019-01-20\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"NKdEx5ZPsFU\"\n  speakers:\n    - Gautam Rege\n  kind: \"keynote\"\n\n- id: \"charles-nutter-keynote-rubyconf-india-2019\"\n  title: \"Keynote: JRuby: Ready for Action\"\n  event_name: \"RubyConf India 2019\"\n  description: \"\"\n  raw_title: \"Keynote\"\n  date: \"2019-01-21\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"rrwETXh36xE\"\n  speakers:\n    - Charles Nutter\n  kind: \"keynote\"\n\n- id: \"jason-swett-tests-wrangle-legacy-rubyconf-india-2019\"\n  title: \"Using Tests as a Tool to Wrangle Legacy Projects\"\n  event_name: \"RubyConf India 2019\"\n  description: \"\"\n  raw_title: \"Using Tests as a Tool to Wrangle Legacy Projects\"\n  date: \"2019-01-21\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"WG-Dt2FMSIg\"\n  speakers:\n    - Jason Swett\n\n- id: \"mudit-maheshwari-monitor-gojek-rubyconf-india-2019\"\n  title: \"How we monitor applications at Go-Jek\"\n  event_name: \"RubyConf India 2019\"\n  description: \"\"\n  raw_title: \"How we monitor applications at Go-Jek\"\n  date: \"2019-01-21\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"6ymN6fmHUY0\"\n  speakers:\n    - Mudit Maheshwari\n\n- id: \"bragadeesh-jegannathan-serverless-rubyconf-india-2019\"\n  title: \"Serverless concept, not Serverless framework.\"\n  event_name: \"RubyConf India 2019\"\n  description: |-\n    Serverless concept, not Serverless framework. Insane scaling using stock Rails application\n  raw_title: \"Serverless concept, not Serverless framework.\"\n  date: \"2019-01-21\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"9UfaVYHIQ98\"\n  speakers:\n    - Bragadeesh Jegannathan\n\n- id: \"torsten-ruger-rubyx-rubyconf-india-2019\"\n  title: \"RubyX, compiling ruby to binary\"\n  event_name: \"RubyConf India 2019\"\n  description: \"\"\n  raw_title: \"RubyX, compiling ruby to binary\"\n  date: \"2019-01-21\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"d00yetsnqyk\"\n  speakers:\n    - Torsten Rüger\n\n- id: \"sidu-ponnappa-keynote-rubyconf-india-2019\"\n  title: \"Keynote: 13 Years of Ruby\"\n  event_name: \"RubyConf India 2019\"\n  description: \"\"\n  raw_title: \"Keynote\"\n  date: \"2019-01-21\"\n  published_at: \"2019-03-02\"\n  video_provider: \"youtube\"\n  video_id: \"EdYCBE4Zj4U\"\n  speakers:\n    - Sidu Ponnappa\n  kind: \"keynote\"\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2020/event.yml",
    "content": "---\nid: \"rubyconf-india-2020\"\ntitle: \"RubyConf India 2020 (Cancelled)\"\ndescription: \"\"\nlocation: \"Goa, India\"\nkind: \"conference\"\nstart_date: \"2020-04-25\"\nend_date: \"2020-04-26\"\nwebsite: \"https://rubyconfindia.org\"\nstatus: \"cancelled\"\ntwitter: \"rubyconfindia\"\ncoordinates:\n  latitude: 15.2993265\n  longitude: 74.12399599999999\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyconfindia.org\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2022/event.yml",
    "content": "---\nid: \"rubyconf-india-2022\"\ntitle: \"RubyConf India 2022\"\ndescription: \"\"\nlocation: \"Pune, India\"\nkind: \"conference\"\nstart_date: \"2022-08-27\"\nend_date: \"2022-08-27\"\nwebsite: \"https://web.archive.org/web/20221022113315/https://rubyconf.in/\"\ntwitter: \"rubyconfindia\"\nbanner_background: \"#161D28\"\nfeatured_background: \"#161D28\"\nfeatured_color: \"#FFFFFF\"\noriginal_website: \"https://rubyconf.in\"\nplaylist: \"https://www.youtube.com/playlist?list=PLbgP71NCXCqEGWPlVAYuur1u3ke4WutAw\"\nchannel_id: \"emergingtechnologytrust\"\ncoordinates:\n  latitude: 18.5246091\n  longitude: 73.8786239\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2022/videos.yml",
    "content": "# TODO: Speakers and title for Flash Talks\n---\n- title: \"Platinum sponsor talk\"\n  event_name: \"RubyConf India 2022\"\n  description: \"\"\n  raw_title: \"RUBYCONF INDIA | 2022 | Platinum sponsor talk by Dinesh\"\n  speakers:\n    - Dinesh Kumar\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"5okrqdC9YCY\"\n  id: \"platinum-sponsor-talk-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n\n- title: \"Being RESTful over GraphQL\"\n  event_name: \"RubyConf India 2022\"\n  description: |-\n    GraphQL and REST aren’t the bitter rivals that you might think they are! REST is a way of life, a way to make your APIs easy to explore, use and document. Learn how we can get the benefits of rest in GraphQL. Covers Caching, Error Handling, Discoverability and Documentation.\n  raw_title: \"RUBYCONF INDIA | 2022 | Being RESTful over GraphQL  by Tejas Dinkar\"\n  speakers:\n    - Tejas Dinkar\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"DhMQV83bhHY\"\n  id: \"being-restful-over-graphql-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n\n- title: \"Static Typing in Ruby3 using RBS\"\n  event_name: \"RubyConf India 2022\"\n  description: |-\n    Ruby is shipped with a type checking tool called RBS. In this talk I’d present on the main features of the RBS and working example of RBS. Since Ruby already have a powerful type checking tool developed by Stripe named Sorbet then why do we need RBS? What are the main differences between these two.\n  raw_title: \"RUBYCONF INDIA | 2022 | Static Typing in Ruby3 using RBS  by Gaurav Singh\"\n  speakers:\n    - Gaurav Singh\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"qT_c_CWoHF8\"\n  id: \"static-typing-in-ruby3-using-rbs-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n\n- title: \"The Achilles heel of a Rails developer: Upgrading Rails app\"\n  event_name: \"RubyConf India 2022\"\n  description: |-\n    Did you know upgrading Rails is as strategic decision as building an app from start? With Rails apps getting more complex every day, so is upgrading them, and not all apps are ready to be upgraded. In this talk, you will get answers to some of the common questions and best practices for upgrading.\n  raw_title: \"RUBYCONF INDIA | 2022 | The Achilles heel of a Rails developer: Upgrading Rails app by Rishi Jain\"\n  speakers:\n    - Rishi Jain\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"gIbXlIDjeC8\"\n  id: \"the-achilles-heel-of-a-rails-developer-upgrading-rails-app-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n\n- title: \"Exceptional Ruby\"\n  event_name: \"RubyConf India 2022\"\n  description: |-\n    It all starts with a raise (or a fail). You know how to raise and rescue exceptions. But do you know how they work, and how to structure a robust error handling strategy for your app? The spotlight will be on error and exception handling and brings your exception handling techniques up to speed.\n  raw_title: \"RUBYCONF INDIA | 2022 | Exceptional Ruby  by Amulya Tanksale\"\n  speakers:\n    - Amulya Tanksale\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"ALQdQfiY9r0\"\n  id: \"exceptional-ruby-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n\n- title: \"0 - 300km/hour with Bullet Train\"\n  event_name: \"RubyConf India 2022\"\n  description: |-\n    The release of Ruby on Rails and its opinionated nature increased the velocity of development for web applications. In order to go even faster there were some constraints to which we all agreed. Take the next leap in building SaaS apps by adopting a few more constraints and a thriving community.\n  raw_title: \"RUBYCONF INDIA | 2022 | 0 - 300km/hour with Bullet Train by Jim Remsik\"\n  speakers:\n    - Jim Remsik\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"yqJmxhiBZeo\"\n  id: \"0-300km-hour-with-bullet-train-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n\n- title: \"DevOps practices at GitHub\"\n  event_name: \"RubyConf India 2022\"\n  description: |-\n    GitHub supports 83+ million devs and 200+ million repos on its platform, backed by RoR. Hundreds of developers working at GitHub ship code multiple times a day. In this talk, get an insight into some of our practices at GitHub, including - deployment strategies, CI/CD, and the codebase itself.\n  raw_title: \"RUBYCONF INDIA | 2022 | DevOps practices at GitHub  by MV Karan\"\n  speakers:\n    - MV Karan\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"t7TwaZUZARY\"\n  id: \"devops-practices-at-github-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n\n- title: \"Data Analytics in Ruby/Rails way\"\n  event_name: \"RubyConf India 2022\"\n  description: |-\n    For Data Analytics, the defacto developers choice is Python, R etc., Even Spark & Scala are choices for distributed computing. This talk is to showcase how we manipulated data distributed over a cluster using functional concepts with vanilla ruby/rails stack.\n  raw_title: \"RUBYCONF INDIA | 2022 | Data Analytics in Ruby/Rails way  by Navarasu Muthu\"\n  speakers:\n    - Navarasu Muthu\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"3or_2bw8bOQ\"\n  id: \"data-analytics-in-ruby-rails-way-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n\n- title: \"Flash Talks\"\n  event_name: \"RubyConf India 2022\"\n  description: \"\"\n  raw_title: \"RUBYCONF INDIA | 2022 | Flash Talks\"\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"AfqiNdvlqBQ\"\n  id: \"flash-talks-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n  talks: []\n\n- title: \"How music works, using Ruby\"\n  event_name: \"RubyConf India 2022\"\n  description: |-\n    That strange phenomenon where air molecules bounce against each other in a way that somehow comforts you, makes you cry, or makes you dance all night: music. Musicians and engineers have found many ways of making music sound good. Let’s reproduce some of their methods in Ruby!\n  raw_title: \"RUBYCONF INDIA | 2022 | How music works, using Ruby  by Thijs Cadier\"\n  speakers:\n    - Thijs Cadier\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"Io8wW74kfCg\"\n  id: \"how-music-works-using-ruby-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n\n- title: \"Engineering Excellence\"\n  event_name: \"RubyConf India 2022\"\n  description: |-\n    A good engineering team writes code that lives through time, people & scale. At most companies engineering excellence takes a back seat because of various reasons. This talk will show how to maintain engineering standards at all phases of the project to build great software.\n  raw_title: \"RUBYCONF INDIA | 2022 | Engineering Excellence  by Narendran\"\n  speakers:\n    - Narendran\n  published_at: \"2022-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"oqa2SPwXQ_Q\"\n  id: \"engineering-excellence-rubyconf-india-2022\"\n  date: \"2022-08-27\"\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2023/event.yml",
    "content": "---\nid: \"PLbgP71NCXCqGwy6QzXbGmX43qtGYkhntL\"\ntitle: \"RubyConf India 2023\"\nkind: \"conference\"\nlocation: \"Pune, India\"\ndescription: |-\n  Hyatt Regency Pune & Residences Nagar Road, Sakore Nagar, Viman Nagar, Pune, Pune, India 411014\npublished_at: \"2023-09-15\"\nstart_date: \"2023-08-26\"\nend_date: \"2023-08-27\"\nchannel_id: \"emergingtechnologytrust\"\nyear: 2023\nbanner_background: \"#15162B\"\nfeatured_background: \"#15162B\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://web.archive.org/web/20240507005032/https://rubyconf.in/\"\ncoordinates:\n  latitude: 18.5246091\n  longitude: 73.8786239\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2023/videos.yml",
    "content": "# Website: https://rubyconf.in/#schedule\n# Schedule: https://rubyconf.in/#schedule\n\n## Day 1 - August 26, 2023\n\n# Kickoff\n---\n- id: \"karan-mv-rubyconf-india-2023\"\n  title: \"Building a Rails app live with AI\"\n  raw_title: \"Building a Rails app live with AI - Karan MV\"\n  event_name: \"RubyConf India 2023\"\n  date: \"2023-08-26\"\n  published_at: \"2023-09-15\"\n  speakers:\n    - \"Karan MV\"\n  video_id: \"fj_1tk_Rb34\"\n  video_provider: \"youtube\"\n  description: |-\n    Everyone loves live music. Developers love live coding! In this live session, we’ll build a complete Rails app from scratch using GitHub Copilot. GitHub Copilot is an AI pair programmer that helps developers boost their productivity by writing entire functions by providing natural language prompts right within the IDE.\n\n- id: \"magesh-s-rubyconf-india-2023\"\n  title: \"Concurrency in Ruby: Threads, Fibers and Ractors Demystified\"\n  raw_title: \"Concurrency in Ruby: Threads, Fibers and Ractors Demystified - Magesh\"\n  event_name: \"RubyConf India 2023\"\n  date: \"2023-08-26\"\n  published_at: \"2023-09-15\"\n  speakers:\n    - \"Magesh S\"\n  video_id: \"0p31ofu9RGk\"\n  video_provider: \"youtube\"\n  description: |-\n    Speed up your Ruby applications with the power of concurrency! Join us as we demystify threads, fibers, and Ractors, understanding their unique strengths, use cases, and impact on Ruby performance. Learn to tackle I/O bottlenecks and enable parallel execution, boosting your code’s speed.\n\n# Tea Break\n\n- id: \"rishi-jain-rubyconf-india-2023\"\n  title: \"Rails Performance monitoring: A primer for developers\"\n  raw_title: \"Rails Performance monitoring: A primer for developers - Rishi Jain\"\n  event_name: \"RubyConf India 2023\"\n  date: \"2023-08-26\"\n  published_at: \"2023-09-15\"\n  speakers:\n    - \"Rishi Jain\"\n  video_id: \"P9ThX14ZSzk\"\n  video_provider: \"youtube\"\n  description: |-\n    Congratulations! You have just joined a startup that went viral. Your first task is to figure out why their Rails application is slow. Now what? This talk will give you the tools you need to quickly find what’s wrong and learn a top-down approach for triaging performance issues and scaling the app\n\n- id: \"maheshwari-ramu-rubyconf-india-2023\"\n  title: \"Common Mistakes that make test cases flaky and how to avoid them\"\n  raw_title: \"Common Mistakes that make test cases flaky and how to avoid them - Maheshwari Ramu\"\n  event_name: \"RubyConf India 2023\"\n  date: \"2023-08-26\"\n  published_at: \"2023-09-15\"\n  speakers:\n    - \"Maheshwari Ramu\"\n  video_id: \"sEKb4ne7dVc\"\n  video_provider: \"youtube\"\n  description: |-\n    Tired of flaky test cases causing frustration and delays? Imagine reliable, consistent tests with accurate results every time. Learn about test automation pitfalls and get practical strategies for a smoother software development process. Stop the frustration, embrace efficiency!\n\n- id: \"harman-sohanpal-rubyconf-india-2023\"\n  title: \"Payment workflow with Ruby and Clickhouse\"\n  raw_title: \"Payment workflow with Ruby and Clickhouse - Harman Sohanpal\"\n  event_name: \"RubyConf India 2023\"\n  date: \"2023-08-26\"\n  published_at: \"2023-09-15\"\n  speakers:\n    - \"Harman Sohanpal\"\n  video_id: \"TpWoqSiTB3c\"\n  video_provider: \"youtube\"\n  description: |-\n    Simple tech solution on payments workflow with huge business impact. Equally divided work among idempotent Sidekiq workers, Clickhouse data ingestion from CSV files using s3 connectors and ruby ODBC to show aggregated reports to users via API simplified our payments workflow and reporting.\n\n# Lunch\n# Energizer\n\n- id: \"arihant-hirawat-rubyconf-india-2023\"\n  title: \"Diving into Dynamic: Demystefying Metaprogrammaing with Ruby\"\n  raw_title: \"Diving into Dynamic: Demystefying Metaprogrammaing with Ruby - Arihant Hirawat\"\n  event_name: \"RubyConf India 2023\"\n  date: \"2023-08-26\"\n  published_at: \"2023-09-15\"\n  speakers:\n    - \"Arihant Hirawat\"\n  video_id: \"5sM7UHwKxAA\"\n  video_provider: \"youtube\"\n  description: |-\n    Dive deeper into the underlying dynamics of Ruby Metaprogramming to deepen the understanding of the language and its inner workings. We explore its real-world applications and unearth how Ruby gems harness this power to solve real-world coding challenges.\n\n- id: \"shloka-shah-rubyconf-india-2023\"\n  title: \"Embracing Code Quality with Rubocop\"\n  raw_title: \"Embracing Code Quality with Rubocop - Shloka Shah\"\n  event_name: \"RubyConf India 2023\"\n  date: \"2023-08-26\"\n  published_at: \"2023-09-15\"\n  speakers:\n    - \"Shloka Shah\"\n  video_id: \"vhzaC3iHlDE\"\n  video_provider: \"youtube\"\n  description: |-\n    Supercharge code quality with Rubocop: the go-to Code-Style Linter for Ruby. Learn practical usage, configuration tips, and maintaining code quality. Tackle legacy code using Rubocop TODO Approach. Understand real-life application. Elevate your code quality by harmonizing a standard among developers.\n\n# Flash Talks\n# Tea Break\n\n- id: \"rahul-mahale-rubyconf-india-2023\"\n  title: \"Rails Orbiting the cloud: Mastering the scalability with Kubernetes\"\n  raw_title: \"Rails Orbiting the cloud: Mastering the scalability with Kubernetes - Rahul Mahale\"\n  event_name: \"RubyConf India 2023\"\n  date: \"2023-08-26\"\n  published_at: \"2023-09-15\"\n  speakers:\n    - \"Rahul Mahale\"\n  video_id: \"TVO9QjTxBBQ\"\n  video_provider: \"youtube\"\n  description: |-\n    Kubernetes is a container orchestration system that can help you scale your Rails application with ease. In this talk, I will discuss the benefits of using Kubernetes for Rails applications, and I will show you how to solve the scaling challenges of Rails apps on Kubernetes.\n\n- id: \"chinmay-naik-rubyconf-india-2023\"\n  title: \"Avoid overengineering & big ball of mud- 7 lessons for maintaining the balance\"\n  raw_title: \"Avoid overengineering & big ball of mud- 7 lessons for maintaining the balance - Chinmay Naik\"\n  event_name: \"RubyConf India 2023\"\n  date: \"2023-08-26\"\n  published_at: \"2023-09-15\"\n  speakers:\n    - \"Chinmay Naik\"\n  video_id: \"HbCZpDKYNOA\"\n  video_provider: \"youtube\"\n  description: |-\n    Teams in technology companies are often in a “tug of war” with themselves. They have to balance between “over-engineering” on one side and a “big ball of mud” on the other. They must maintain this balance to build software for today that can also scale for tomorrow. This talk covers how to do that.\n\n# Networking\n\n# Party\n\n## Day 2 - August 27, 2023\n\n- id: \"vipul-a-m-rubyconf-india-2023\"\n  title: \"From Sprockets to js-bundling: Evolution of JavaScript tooling in Rails!\"\n  raw_title: \"From Sprockets to js-bundling: Evolution of JavaScript tooling in Rails! - Vipul A M\"\n  event_name: \"RubyConf India 2023\"\n  speakers:\n    - \"Vipul A M\"\n  video_id: \"a91xj5SinDk\"\n  video_provider: \"youtube\"\n  date: \"2023-08-27\"\n  published_at: \"2023-09-15\"\n  description: |-\n    From sprockets to Webpacker and js-bundling, Rails tooling for JavaScript has evolved with time. Lets travel through the history of this evolution and how you should build modern Rails Apps in today’s rich JavaScript Ecosystem. An SPA, Monolith or API-only App, we’ll see different Rails solutions!\n\n- id: \"aniket-rao-rubyconf-india-2023\"\n  title: \"Monitoring Rails apps using Open Source\"\n  raw_title: \"Monitoring Rails apps using Open Source - Aniket Rao\"\n  event_name: \"RubyConf India 2023\"\n  speakers:\n    - \"Aniket Rao\"\n  video_id: \"8OX5a_TMS8A\"\n  video_provider: \"youtube\"\n  date: \"2023-08-27\"\n  published_at: \"2023-09-15\"\n  description: |-\n    Exhausted by APM inefficiencies? Harness open-source tools like Grafana, PromQL, OpenMetrics, Jaeger for optimal data handling. Achieve superior monitoring at a lower cost, cutting through data clutter, and rise above the ‘Shannon Limit’.\n\n# Tea Break\n\n- id: \"hieu-nguyen-rubyconf-india-2023\"\n  title: \"Building a Resilient MFA Framework: Strategies and Best Practices\"\n  raw_title: \"Building a Resilient MFA Framework: Strategies and Best Practices - Hieu Nguyen\"\n  event_name: \"RubyConf India 2023\"\n  speakers:\n    - \"Hieu Nguyen\"\n  video_provider: \"youtube\"\n  video_id: \"-7BNm3tlF94\"\n  date: \"2023-08-27\"\n  published_at: \"2023-09-15\"\n  description: |-\n    In an era of heightened security threats, constructing a resilient Multiple Factors Authentication (MFA) framework is vital. In this talk, we’ll explore the strategies and best practices for building a reliable MFA framework. The talk will also discuss how to strike the right balance between security and usability while safeguarding sensitive data. Hopefully, this session will equip you with the knowledge and tools to improve your organization authentication security system.\n\n- id: \"manu-janardhanan-rubyconf-india-2023\"\n  title: \"Look Ma, No Sidekiq: A peek into async future\"\n  raw_title: \"Look Ma, No Sidekiq: A peek into async future - Manu Janardhanan\"\n  event_name: \"RubyConf India 2023\"\n  speakers:\n    - \"Manu Janardhanan\"\n  video_id: \"x8qOIY252sw\"\n  video_provider: \"youtube\"\n  date: \"2023-08-27\"\n  published_at: \"2023-09-15\"\n  description: |-\n    We usually turn to Sidekiq for tackling long-running tasks. However, using the async gem with Falcon lets us execute IO-bound tasks directly with clean, simple, performant and scalable code . Plus, this approach dovetails perfectly with Turbo Frames for embedding task results.\n\n- id: \"puneet-khushwani-rubyconf-india-2023\"\n  title: \"From Startup to Scale Up: How to Scale Engineering teams\"\n  raw_title: \"From Startup to Scale Up: How to Scale Engineering teams - Puneet Khushwani\"\n  event_name: \"RubyConf India 2023\"\n  speakers:\n    - \"Puneet Khushwani\"\n  video_id: \"0WlkzRjpTSI\"\n  video_provider: \"youtube\"\n  date: \"2023-08-27\"\n  published_at: \"2023-09-15\"\n  description: |-\n    When teams are small, design decisions can be made over a coffee, code reviews can be done by sitting next to each other. When we have hundreds of developers, what are the areas for which we should implement checks and balances to ensure quality & efficiency isn’t compromised?\n\n# Lunch\n\n- id: \"vishwajeetsingh-desurkar-rubyconf-india-2023\"\n  title: \"Connecting the Dots: Unleash the magic of AI in IOT\"\n  raw_title: \"Connecting the Dots: Unleash the magic of AI in IOT - Vishwajeetsingh Desurkar\"\n  event_name: \"RubyConf India 2023\"\n  speakers:\n    - \"Vishwajeetsingh Desurkar\"\n  video_id: \"YhkEQ9pP-W0\"\n  video_provider: \"youtube\"\n  date: \"2023-08-27\"\n  published_at: \"2023-09-15\"\n  description: |-\n    This talk dives deep into how to Revolutionize IoT: Preventive Maintenance & Anomaly Detection with Ruby! Witness language-driven magic as we showcase live demos of Ruby-powered IoT devices detecting anomalies and ensuring optimal performance. Join us to discover how Language and AI empower IoT with preventive maintenance.\n\n- id: \"ratnadeep-deshmane-rubyconf-india-2023\"\n  title: \"Dissecting Rails\"\n  raw_title: \"Dissecting Rails - Ratnadeep Deshmane\"\n  event_name: \"RubyConf India 2023\"\n  speakers:\n    - \"Ratnadeep Deshmane\"\n  video_id: \"Pt820oSj2Qw\"\n  video_provider: \"youtube\"\n  date: \"2023-08-27\"\n  published_at: \"2023-09-15\"\n  description: |-\n    After evolving for 15 years, Ratnadeep feels Rails is at a stage where it is a bit overwhelming for new developers to get started, because of the surface area of its features. This talk proposes a different approach to teaching Rails that is much more easier, comprehensive and less confusing.\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2024/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/rubyconf-india-2024\"\n  open_date: \"2024-07-23\"\n  close_date: \"2024-09-25\"\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2024/event.yml",
    "content": "---\nid: \"PLbgP71NCXCqE1fhfOAOpmKjRbvHojsZX5\"\ntitle: \"RubyConf India 2024\"\nkind: \"conference\"\nlocation: \"Jaipur, India\"\ndescription: |-\n  Clarks Amer Hotel Jawahar Lal Nehru Marg, Opposite Fortis Escorts Hospital, Jaipur, Rajasthan 302018\npublished_at: \"2024-12-20\"\nstart_date: \"2024-11-29\"\nend_date: \"2024-11-30\"\nchannel_id: \"emergingtechnologytrust\"\nyear: 2024\nbanner_background: \"#15162B\"\nfeatured_background: \"#15162B\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://web.archive.org/web/20241208133005/https://rubyconf.in/\"\ncoordinates:\n  latitude: 26.9124336\n  longitude: 75.7872709\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2024/videos.yml",
    "content": "# Website: https://rubyconf.in/#schedule\n# Schedule: https://rubyconf.in/#schedule\n\n## Day 1 - November 29, 2024\n\n# Kickoff\n---\n- id: \"manu-janardhanan-rubyconf-india-2024\"\n  title: \"Puma, Falcon, Pitchfork: Navigating the Ruby Web Server Landscape\"\n  raw_title: \"Puma, Falcon, Pitchfork: Navigating the Ruby Web Server Landscape by Manu Janardhanan\"\n  event_name: \"RubyConf India 2024\"\n  date: \"2024-11-29\"\n  published_at: \"2024-12-20\"\n  speakers:\n    - \"Manu Janardhanan\"\n  video_id: \"A3KXW2h3dcM\"\n  video_provider: \"youtube\"\n  description: |-\n    Puma's Ruby server dominance is being challenged by Falcon's fiber-based concurrency and Pitchfork's memory efficiency. This talk aims to explore these choices and guide you to select the most suitable server for your unique application needs.\n\n- id: \"sriram-v-rubyconf-india-2024\"\n  title: \"Taming Flaky Specs: Diagnosing Test Failures in Ruby\"\n  raw_title: \"Taming Flaky Specs: Diagnosing Test Failures in Ruby by Sriram V\"\n  event_name: \"RubyConf India 2024\"\n  date: \"2024-11-29\"\n  published_at: \"2024-12-20\"\n  speakers:\n    - \"Sriram V\"\n  video_id: \"Adsv4l8Z-OY\"\n  video_provider: \"youtube\"\n  description: |-\n    Flaky specs can cause random test failures, disrupting CI pipelines and eroding confidence in your test suite. In this talk, we'll explore common root causes of flaky specs and dive into strategies for diagnosing rare, hard-to-reproduce issues to help stabilize your test suite.\n\n# Tea Break\n\n- id: \"puneet-khushwani-rubyconf-india-2024\"\n  title: \"Understanding Garbage Collection in Ruby\"\n  raw_title: \"Understanding Garbage Collection in Ruby by Puneet Khushwani\"\n  event_name: \"RubyConf India 2024\"\n  date: \"2024-11-29\"\n  published_at: \"2024-12-20\"\n  speakers:\n    - \"Puneet Khushwani\"\n  video_id: \"KdfmUBPuu5k\"\n  video_provider: \"youtube\"\n  description: |-\n    Unlike languages like C, Ruby's automatic garbage collection frees us from manual memory management worries. Discover how it works behind the scenes. Also discover how misconfigured GC can harm performance.\n\n- id: \"rohit-mukherjee-rubyconf-india-2024\"\n  title: \"Ruby Mediator\"\n  raw_title: \"Ruby Mediator by Rohit Mukherjee\"\n  event_name: \"RubyConf India 2024\"\n  date: \"2024-11-29\"\n  published_at: \"2024-12-20\"\n  speakers:\n    - \"Rohit Mukherjee\"\n  video_id: \"AhtCIZghDsA\"\n  video_provider: \"youtube\"\n  description: |-\n    The mediator design pattern in Ruby is a behavioral pattern that reduces coupling between program components. It does this by allowing components to communicate indirectly through a mediator object instead of directly.\n\n# Lunch\n\n# Sponsor Showcase\n\n- id: \"chaitali-khangar-rubyconf-india-2024\"\n  title: \"Metaprogramming: Unraveling the Magic\"\n  raw_title: \"Metaprogramming: Unraveling the Magic by Chaitali Khangar\"\n  event_name: \"RubyConf India 2024\"\n  date: \"2024-11-29\"\n  published_at: \"2024-12-20\"\n  speakers:\n    - \"Chaitali Khangar\"\n  video_id: \"v71swsc8qk4\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover Ruby metaprogramming! Learn powerful techniques to make your code dynamic and adaptable while avoiding added complexity. Join us to master the art of clean, flexible Ruby!\n\n- id: \"anush-kumar-rubyconf-india-2024\"\n  title: \"Solid Queue - Default Active Job Adaptor in Rails 8\"\n  raw_title: \"Solid Queue - Default Active Job Adaptor in Rails 8 by Anush Kumar\"\n  event_name: \"RubyConf India 2024\"\n  date: \"2024-11-29\"\n  published_at: \"2024-12-20\"\n  speakers:\n    - \"Anush Kumar\"\n  video_id: \"HEkxZRdzyZU\"\n  video_provider: \"youtube\"\n  description: |-\n    Struggling with Sidekiq config or performance issues with delayed_jobs? Join our talk on \"Solid Queue,\" a new Active Job adapter that boosts background job performance and simplifies setup. It will soon be the default in Rails 8!\n\n# Tea Break\n\n- id: \"keshav-biswa-rubyconf-india-2024\"\n  title: \"From Curiosity to Confusion: My Journey of Creating Confuscript in Ruby\"\n  raw_title: \"From Curiosity to Confusion: My Journey of Creating Confuscript in Ruby by Keshav Biswa\"\n  event_name: \"RubyConf India 2024\"\n  date: \"2024-11-29\"\n  published_at: \"2024-12-20\"\n  speakers:\n    - \"Keshav Biswa\"\n  video_id: \"rOQ-L9a_l9c\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover this unique language designed to challenge conventional coding logic, exploring its syntax, quirks, and the playful philosophy behind it. Perfect for those curious about unconventional programming perspectives—join us to unravel the confusion!\n\n- id: \"vishwajeetsingh-desurkar-rubyconf-india-2024\"\n  title: \"The Harvey Dent Dilemma: Ruby's White Knight Rises (or Falls)\"\n  raw_title: \"The Harvey Dent Dilemma: Ruby's White Knight Rises (or Falls) by Vishwajeetsingh Desurkar\"\n  event_name: \"RubyConf India 2024\"\n  date: \"2024-11-29\"\n  published_at: \"2024-12-20\"\n  speakers:\n    - \"Vishwajeetsingh Desurkar\"\n  video_id: \"8LYHEzQL_-4\"\n  video_provider: \"youtube\"\n  description: |-\n    Frozen strings, memoization, and Ruby's other quirky features can be your performance secret weapon, but misuse can lead to a performance nightmare. Let's dive into the rabbit hole of Ruby optimization and learn how to avoid the traps while writing code that's both fast and fun.\n\n- id: \"todo-rubyconf-india-2024\"\n  title: \"Flash Talks (Day 1)\"\n  raw_title: \"Flash Talks\"\n  event_name: \"RubyConf India 2024\"\n  date: \"2024-11-29\"\n  published_at: \"2024-12-23\"\n  speakers:\n    - TODO\n    - Subin Siby # activerecord-ruby.wasm - Play with a SQLite DB on browser with ActiveRecord https://x.com/SubinSiby/status/1862177919671705882 - https://github.com/subins2000/activerecord-ruby-wasm\n  video_id: \"tIbyOA59Hxo\"\n  video_provider: \"youtube\"\n  description: |-\n    Explore the brilliance of the Ruby community with our exciting 5-minute flash talks from Day 1 of RubyConf India 2024! These lightning-fast sessions pack a punch with thought-provoking ideas, practical tips, and inspiring stories from passionate Rubyists across the globe.\n\n    Whether you're a seasoned developer or just getting started, these flash talks are guaranteed to leave you inspired and full of fresh insights. Don't miss this whirlwind of knowledge, innovation, and community spirit!\n\n# Networking\n\n# Party\n\n## Day 2 - November 30, 2024\n\n- id: \"ratnadeep-deshmane-rubyconf-india-2024\"\n  title: \"Reading Ruby - A Visual Walkthrough of the Source Code\"\n  raw_title: \"Reading Ruby - A Visual Walkthrough of the Source Code by Ratnadeep Deshmane\"\n  event_name: \"RubyConf India 2024\"\n  speakers:\n    - \"Ratnadeep Deshmane\"\n  video_id: \"jS2IlXQzxQ8\"\n  video_provider: \"youtube\"\n  date: \"2024-11-30\"\n  published_at: \"2024-12-20\"\n  description: |-\n    Curious about Ruby's internals but want to avoid diving deep into C? Interested in contributing to Ruby and need a primer before tackling the code? This talk covers both, simplifying the complexity with visuals, diagrams, and a touch of C.\n\n- id: \"sumit-dey-rubyconf-india-2024\"\n  title: \"Rails Upgrade Mastery: Best Practices for Large-Scale Enterprise Applications\"\n  raw_title: \"Rails Upgrade Mastery: Best Practices for Large-Scale Enterprise Applications by Sumit Dey\"\n  event_name: \"RubyConf India 2024\"\n  speakers:\n    - \"Sumit Dey\"\n  video_id: \"5O2qX08D2MI\"\n  video_provider: \"youtube\"\n  date: \"2024-11-30\"\n  published_at: \"2024-12-20\"\n  description: |-\n    Upgrading Rails in an enterprise software? Learn from Coupa's journey! This talk will share our challenges, strategies, and best practices based on our experience of upgrading from Rails 6 to 7. Take away valuable insights and practical tips for a seamless Rails upgrade at scale.\n\n# Tea Break\n\n- id: \"ashish-tendulkar-rubyconf-india-2024\"\n  title: \"Power of Gemini and How Developers Can Harness It\"\n  raw_title: \"Power of Gemini and How Developers Can Harness It by Ashish Tendulkar\"\n  event_name: \"RubyConf India 2024\"\n  speakers:\n    - \"Ashish Tendulkar\"\n  video_id: \"ashish-tendulkar-rubyconf-india-2024\"\n  video_provider: \"not_published\"\n  date: \"2024-11-30\"\n  published_at: \"2024-12-20\"\n  description: |-\n    Discover the capabilities of Gemini and learn how developers can leverage its power in their applications. This session will delve into practical use cases and integration strategies.\n\n- id: \"sonal-sachdev-rubyconf-india-2024\"\n  title: \"If You Can Whisk, You Can Code\"\n  raw_title: \"If You Can Whisk, You Can Code by Sonal Sachdev\"\n  event_name: \"RubyConf India 2024\"\n  speakers:\n    - \"Sonal Sachdev\"\n  video_id: \"37HJZxiGIpQ\"\n  video_provider: \"youtube\"\n  date: \"2024-11-30\"\n  published_at: \"2024-12-20\"\n  description: |-\n    This talk will debunk common coding myths and showcase the essential tools for success, proving that, like Remy the rat, creativity and confidence are all you need. Get ready to whisk your way into coding!\n\n# Lunch\n\n- id: \"gautam-rege-rubyconf-india-2024\"\n  title: \"Panel Discussion\"\n  raw_title: \"Panel Discussion\"\n  event_name: \"RubyConf India 2024\"\n  speakers:\n    - Gautam Rege\n    - Dutta Deshmukh\n    - Surbhi Gupta\n    - Swanand Pagnis\n    - Siddharth Sharma\n  video_id: \"VIS42lVAwfw\"\n  video_provider: \"youtube\"\n  date: \"2024-11-30\"\n  published_at: \"2024-12-20\"\n  description: |-\n    Join Dutta Deshmukh, Surbhi Gupta, Swanand Pagnis and Siddharth Sharma in an engaging panel discussion on performance and scale in modern applications and engineering teams. Dive into their personal experiences, from handling SQL database migrations to the trade-offs between microservices and monoliths. This session covers theoretical insights, practical failure stories, and performance optimization strategies, aiming to provide a comprehensive understanding of scaling both applications and engineering teams. Tune in for expert advice, industry anecdotes, and thought-provoking questions about the future of performance engineering.\n\n    Moderator: Gautam Rege\n\n    00:00 Introduction to the Panel Discussion\n    00:30 Meet the Panelists\n    04:17 Diving into Performance and Scale\n    04:55 Failure Stories and Lessons Learned\n    08:54 Monolith vs. Microservices Debate\n    15:28 Parallel Workloads and Scalability\n    20:43 Engineer Performance and Productivity Tools\n\n- id: \"todo-rubyconf-india-2024-flash-talks-day-2\"\n  title: \"Flash Talks (Day 2)\"\n  raw_title: \"Flash Talks\"\n  event_name: \"RubyConf India 2024\"\n  speakers:\n    - TODO\n  video_id: \"eGnhXyYQRos\"\n  video_provider: \"youtube\"\n  date: \"2024-11-30\"\n  published_at: \"2024-12-23\"\n  description: |-\n    Day 2 of RubyConf India 2024 brought another round of exciting 5-minute flash talks, where Rubyists showcased their innovative ideas, quick tips, and inspiring journeys.\n\n    From solving real-world challenges to sharing unique perspectives on Ruby and beyond, these lightning sessions are the perfect way to ignite your curiosity and fuel your passion for development.\n\n    Catch these quick bursts of brilliance and be inspired by the amazing Ruby community!\n\n# Vote of Thanks\n\n# Tea Break\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2025/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/rubyconf-india-2025\"\n  open_date: \"2025-05-22\"\n  close_date: \"2025-07-15\"\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2025/event.yml",
    "content": "---\nid: \"PLbgP71NCXCqFeiIq8ITx36QRuaJxdZwdP\"\ntitle: \"RubyConf India 2025\"\ndescription: |-\n  Clarks Amer Hotel, Jawahar Lal Nehru Marg, Opposite Fortis Escorts Hospital, Jaipur, Rajasthan 302018\nlocation: \"Jaipur, India\"\nkind: \"conference\"\nstart_date: \"2025-09-12\"\nend_date: \"2025-09-13\"\nwebsite: \"https://rubyconf.in\"\nbanner_background: \"#15162B\"\nfeatured_background: \"#15162B\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 26.9124336\n  longitude: 75.7872709\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum\"\n      description: |-\n        Top level sponsors with highest sponsorship tier.\n      level: 1\n      sponsors:\n        - name: \"Josh Software Pvt Ltd\"\n          website: \"https://joshsoftware.com/\"\n          slug: \"joshsoftware\"\n          logo_url: \"https://rubyconf.in/images/company-logos/JOSH.png\"\n\n    - name: \"Gold\"\n      description: |-\n        Second level sponsors with gold tier sponsorship.\n      level: 2\n      sponsors:\n        - name: \"Pattern\"\n          website: \"https://www.pattern.com/\"\n          slug: \"pattern\"\n          logo_url: \"https://rubyconf.in/images/company-logos/pattern-black.png\"\n\n        - name: \"Coupa\"\n          website: \"https://www.coupa.com/\"\n          slug: \"coupa\"\n          logo_url: \"https://rubyconf.in/images/company-logos/CoupaSoftware.png\"\n\n    - name: \"Silver\"\n      description: |-\n        Third level sponsors with silver tier sponsorship.\n      level: 3\n      sponsors:\n        - name: \"Saleoun\"\n          website: \"https://www.saeloun.com/\"\n          slug: \"saleoun\"\n          logo_url: \"https://rubyconf.in/images/company-logos/saeloun.png\"\n\n        - name: \"Railsfactory\"\n          website: \"https://railsfactory.com/\"\n          slug: \"railsfactory\"\n          logo_url: \"https://rubyconf.in/images/company-logos/railsfactory-1.png\"\n\n    - name: \"Flash Talk Sponsors\"\n      description: |-\n        Fourth level sponsors with flash talk sponsorship.\n      level: 4\n      sponsors:\n        - name: \"Typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"typesense\"\n          logo_url: \"https://rubyconf.in/images/company-logos/typsense_logo.png\"\n\n    - name: \"Community Sponsors\"\n      description: |-\n        Other sponsors not fitting in main tiers.\n      level: 5\n      sponsors:\n        - name: \"Lanes & Planes\"\n          website: \"https://www.lanes-planes.com/\"\n          slug: \"lanes_planes\"\n          logo_url: \"http://rubyconf.in/images/company-logos/Lanes-Planes_primary_postive.png\"\n"
  },
  {
    "path": "data/rubyconf-india/rubyconf-india-2025/videos.yml",
    "content": "# Website: https://rubyconf.in/\n# Schedule: https://rubyconf.in/#schedule\n\n## Day 1 - September 12, 2025\n\n# Kickoff\n---\n- id: \"andrzej-krzywda-rubyconf-india-2025\"\n  title: \"15 years of Rails with DDD — battle-tested patterns\"\n  raw_title: \"15 years of Rails with DDD — battle-tested patterns by Andrzej Krzywda\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-12\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Andrzej Krzywda\n  video_id: \"DSXnpsal-vU\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover how Domain-Driven Design, CQRS, and Event Sourcing can bring structure, clarity, and scalability — without over-engineering. Real-world lessons, battle-tested patterns, and tools like RailsEventStore.\n\n- id: \"puneet-khushwani-rubyconf-india-2025\"\n  title: \"From Characters to Meaning: Ruby's Lexer & Parser\"\n  raw_title: \"From Characters to Meaning: Ruby's Lexer & Parser by Puneet Khushwani\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-12\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Puneet Khushwani\n  video_id: \"Hu6EZHGv3Vw\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover how Ruby reads your code! From lexing raw characters into tokens to parsing them into an Abstract Syntax Tree, explore Ruby’s flexible syntax with practical examples and Ripper.\n\n# Tea Break\n\n- id: \"udbhav-gambhir-rubyconf-india-2025\"\n  title: \"Inside Rails Boot: Puma's Role in Initialization\"\n  raw_title: \"Inside Rails Boot: Puma's Role in Initialization by Udbhav Gambhir\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-12\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Udbhav Gambhir\n  video_id: \"RcpVqigDYPE\"\n  video_provider: \"youtube\"\n  description: |-\n    Trace what happens when you run `rails server`! From Rails boot to Puma launch, uncover how components load, signals fire, plugins initialize, and requests are handled.\n\n- id: \"vishwajeetsingh-desurkar-rubyconf-india-2025\"\n  title: \"What If… Ruby Led the AI Revolution?\"\n  raw_title: \"What If… Ruby Led the AI Revolution? by Vishwajeetsingh Desurkar\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-12\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Vishwajeetsingh Desurkar\n  video_id: \"1h5RZWSL4Oc\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover Ruby’s hidden AI powers! See how to build intelligent, semantic features right in Rails — no language switch, no lost joy, just powerful simplicity.\n\n# Lunch Break\n\n- id: \"nandini-singhal-rubyconf-india-2025\"\n  title: \"Ruby, Meet the Metaverse\"\n  raw_title: \"Ruby, Meet the Metaverse by Nandini Singhal\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-12\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Nandini Singhal\n  video_id: \"5pbw1iLiRwA\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover Ruby beyond web apps! See a real-time multiplayer world built with Ractors for state and Fiber-powered WebSockets for users — live demo with 50+ players, code on GitHub.\n\n- id: \"prateek-choudhary-rubyconf-india-2025\"\n  title: \"The Solid Shift: Redis → Rails 8 Solid Stack\"\n  raw_title: \"The Solid Shift: Redis → Rails 8 Solid Stack by Prateek Choudhary\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-12\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Prateek Choudhary\n  video_id: \"HPa9M19V8TA\"\n  video_provider: \"youtube\"\n  description: |-\n    Learn a zero-downtime, service-by-service migration from Redis to Rails 8’s Solid Queue, Solid Cache, and Solid Cable. Real-world strategies with parallel runs, dual writes, canary deployments, rollback, and monitoring.\n\n- id: \"rakesh-jha-rubyconf-india-2025\"\n  title: \"JRuby: A Love Affair of Java & Ruby\"\n  raw_title: \"JRuby: A Love Affair of Java & Ruby by Rakesh Jha\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-12\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Rakesh Jha\n  video_id: \"Zimv_11s5lg\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover how JRuby blends Java’s power with Ruby’s elegance! Explore its evolution, real-world use cases, and practical tips to harness scalability and expressiveness in one platform.\n\n# Tea Break\n\n- id: \"sameer-kumar-rubyconf-india-2025\"\n  title: \"Ruby DSLs: Write Code That Looks Like English\"\n  raw_title: \"Ruby DSLs: Write Code That Looks Like English by Sameer Kumar\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-12\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Sameer Kumar\n  video_id: \"Xr8wsj3FTdQ\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover the art of Ruby DSLs — balancing elegant abstraction with readable syntax. Avoid the perils of `method_missing`, explore live demos, and create code that reads like English.\n\n- id: \"vlad-dyachenko-rubyconf-india-2025\"\n  title: \"MCP Security: Real-world Risks & Defenses\"\n  raw_title: \"MCP Security: Real-world Risks & Defenses by Vlad Dyachenko\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-12\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Vlad Dyachenko\n  video_id: \"Rfjm8w0hwaY\"\n  video_provider: \"youtube\"\n  description: |-\n    Learn how Model Context Protocol works, its real-world attack vectors, and defense strategies — from poisoning and code injection to audits and safe remote MCPs.\n\n# Networking\n\n# Party\n\n## Day 2 - September 13, 2025\n\n# Kickoff\n- id: \"ratnadeep-deshmane-rubyconf-india-2025\"\n  title: \"Reading Rails: A Visual Walkthrough of the Source Code\"\n  raw_title: \"Reading Rails: A Visual Walkthrough of the Source Code by Ratnadeep Deshmane\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-13\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Ratnadeep Deshmane\n  video_id: \"1lPRRLn8ehc\"\n  video_provider: \"youtube\"\n  description: |-\n    Get a visual roadmap to navigate Rails core components, demystify the magic, and use AI tools to explore, understand, and confidently contribute.\n\n- id: \"charles-nutter-rubyconf-india-2025\"\n  title: \"JRuby: Do More With Ruby\"\n  raw_title: \"Charles Nutter\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-13\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Charles Nutter\n  video_id: \"10nArtB3LvA\"\n  video_provider: \"youtube\"\n  description: |-\n    For over 13 years, Charles Nutter has been at the forefront of the JRuby project. He will share lessons from JVM internals, programming language design, and the unpredictable adventures of JRuby.\n\n- id: \"prathamesh-sonpatki-rubyconf-india-2025\"\n  title: \"Teaching AI to Debug Your Rails Apps (MCP + observability)\"\n  raw_title: \"Teaching AI to Debug Your Rails Apps (MCP + observability) by Prathamesh Sonpatki\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-13\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Prathamesh Sonpatki\n  video_id: \"MD3-_TRBOoQ\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover AI-powered Rails debugging! Use MCP servers to link observability stack with AI for instant insights — query logs, trace slow queries, and spot performance issues.\n\n# Lunch Break\n\n- id: \"chikahiro-tokoro-rubyconf-india-2025\"\n  title: \"Is the monolith a problem?\"\n  raw_title: \"Is the monolith a problem? by Chikahiro Tokoro\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-13\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Chikahiro Tokoro\n  video_id: \"irq7sjXLevQ\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover the truth about monoliths vs microservices! Debunk myths, uncover real architectural differences, and learn strategies to fix real problems — not just follow trends.\n\n- id: \"deepan-kumar-rubyconf-india-2025\"\n  title: \"AI at Runtime: Self-Healing Ruby Apps\"\n  raw_title: \"AI at Runtime: Self-Healing Ruby Apps by Deepan Kumar\"\n  event_name: \"RubyConf India 2025\"\n  date: \"2025-09-13\"\n  published_at: \"2025-09-29\"\n  speakers:\n    - Deepan Kumar\n  video_id: \"kuOdCfLvhUs\"\n  video_provider: \"youtube\"\n  description: |-\n    Discover how to capture crashes, use AI to generate fixes, write tests, and patch code at runtime — creating an app that evolves like an engineer who never sleeps!\n\n# Flash talks\n\n# Vote of Thanks\n"
  },
  {
    "path": "data/rubyconf-india/series.yml",
    "content": "---\nname: \"RubyConf India\"\nwebsite: \"https://rubyconf.in\"\ntwitter: \"rubyconfindia\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyconf-indonesia/rubyconf-indonesia-2019/event.yml",
    "content": "---\nid: \"rubyconf-indonesia-2019\"\ntitle: \"RubyConf Indonesia 2019\"\ndescription: \"\"\nlocation: \"Jakarta, Indonesia\"\nkind: \"conference\"\nstart_date: \"2019-09-29\"\nend_date: \"2019-09-29\"\nwebsite: \"https://ruby.id/conf/2019/\"\ntwitter: \"rubyconfid\"\ncoordinates:\n  latitude: -6.1944491\n  longitude: 106.8229198\n"
  },
  {
    "path": "data/rubyconf-indonesia/rubyconf-indonesia-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://ruby.id/conf/2019/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-indonesia/series.yml",
    "content": "---\nname: \"RubyConf Indonesia\"\nwebsite: \"https://ruby.id\"\ntwitter: \"rubyconfid\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyconf-jakarta/rubyconf-jakarta-2017/event.yml",
    "content": "---\nid: \"rubyconf-jakarta-2017\"\ntitle: \"RubyConf Jakarta 2017\"\ndescription: \"\"\nlocation: \"Jakarta, Indonesia\"\nkind: \"conference\"\nstart_date: \"2017-10-06\"\nend_date: \"2017-10-07\"\nwebsite: \"http://ruby.id/conf/2017/\"\ntwitter: \"id_ruby\"\ncoordinates:\n  latitude: -6.1944491\n  longitude: 106.8229198\n"
  },
  {
    "path": "data/rubyconf-jakarta/rubyconf-jakarta-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://ruby.id/conf/2017/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-jakarta/series.yml",
    "content": "---\nname: \"RubyConf Jakarta\"\nwebsite: \"http://ruby.id/conf/2017/\"\ntwitter: \"id_ruby\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyconf-lt/rubyconf-lt-2015/event.yml",
    "content": "---\nid: \"rubyconf-lt-2015\"\ntitle: \"RubyConfLT 2015\"\ndescription: \"\"\nlocation: \"Vilnius, Lithuania\"\nkind: \"conference\"\nstart_date: \"2015-03-21\"\nend_date: \"2015-03-21\"\nwebsite: \"https://2015.rubyconf.lt/\"\nplaylist: \"https://www.youtube.com/user/rubyconflt\"\ncoordinates:\n  latitude: 54.6871555\n  longitude: 25.2796514\n"
  },
  {
    "path": "data/rubyconf-lt/rubyconf-lt-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2015.rubyconf.lt/\n# Videos: https://www.youtube.com/user/rubyconflt\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-lt/rubyconf-lt-2016/event.yml",
    "content": "---\nid: \"rubyconf-lt-2016\"\ntitle: \"RubyConfLT 2016\"\ndescription: \"\"\nlocation: \"Vilnius, Lithuania\"\nkind: \"conference\"\nstart_date: \"2016-04-23\"\nend_date: \"2016-04-23\"\nwebsite: \"https://2016.rubyconf.lt/\"\nplaylist: \"https://www.youtube.com/user/rubyconflt\"\ncoordinates:\n  latitude: 54.6871555\n  longitude: 25.2796514\n"
  },
  {
    "path": "data/rubyconf-lt/rubyconf-lt-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2016.rubyconf.lt/\n# Videos: https://www.youtube.com/user/rubyconflt\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-lt/rubyconf-lt-2017/event.yml",
    "content": "---\nid: \"rubyconf-lt-2017\"\ntitle: \"RubyConfLT 2017\"\ndescription: \"\"\nlocation: \"Vilnius, Lithuania\"\nkind: \"conference\"\nstart_date: \"2017-04-01\"\nend_date: \"2017-04-01\"\nwebsite: \"https://rubyconf.lt/\"\ncoordinates:\n  latitude: 54.6871555\n  longitude: 25.2796514\n"
  },
  {
    "path": "data/rubyconf-lt/rubyconf-lt-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyconf.lt/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-lt/series.yml",
    "content": "---\nname: \"RubyConfLT\"\nwebsite: \"https://2015.rubyconf.lt/\"\ntwitter: \"rubyconflt\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - RubyConf LT\n  - Ruby Conf LT\n  - RubyConf Lithuania\n  - Ruby Conf Lithuania\n"
  },
  {
    "path": "data/rubyconf-my/rubyconf-kl-2016/event.yml",
    "content": "---\nid: \"rubyconf-kl-2016\"\ntitle: \"RubyConf KL 2016\"\ndescription: \"\"\nlocation: \"Kuala Lumpur, Malaysia\"\nkind: \"conference\"\nstart_date: \"2016-08-13\"\nend_date: \"2016-08-13\"\nwebsite: \"http://rubyconf.my/2016\"\ntwitter: \"rubyconfmy\"\ncoordinates:\n  latitude: 3.1319197\n  longitude: 101.6840589\n"
  },
  {
    "path": "data/rubyconf-my/rubyconf-kl-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.my/2016\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-my/rubyconf-my-2017/event.yml",
    "content": "---\nid: \"PLrD6VJeUSN28nfWhU5PwlD-9vgPNV3WsU\"\ntitle: \"RubyConf MY 2017\"\nkind: \"conference\"\nlocation: \"Selangor, Malaysia\"\ndescription: |-\n  Auditorium, Magic @ Cyberjaya, Selangor, Malaysia\npublished_at: \"2017-10-13\"\nstart_date: \"2017-10-12\"\nend_date: \"2017-10-13\"\nchannel_id: \"UCtayOVyGOpjYCcNzVCgR0Xg\"\nyear: 2017\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#1E2235\"\nwebsite: \"https://rubyconf.my/2017/\"\ncoordinates:\n  latitude: 3.509247\n  longitude: 101.5248055\n"
  },
  {
    "path": "data/rubyconf-my/rubyconf-my-2017/videos.yml",
    "content": "---\n# Website: https://rubyconf.my/2017/\n# Schedule: https://rubyconf.my/2017/#schedule\n\n## Day 1 - October 12, 2017\n\n# Registration\n\n# Welcome Message\n\n- id: \"akira-matsuda-rubyconf-my-2017\"\n  title: \"Keynote: Ruby, Community and You\"\n  raw_title: \"Keynote: Ruby, Community and You - RubyConfMY 2017\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Akira Matsuda (@amatsuda)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"LVk4af9iuzA\"\n\n- id: \"alex-topalov-rubyconf-my-2017\"\n  title: \"Sustainable Architecture\"\n  raw_title: \"Sustainable Architecture - RubyConfMY 2017\"\n  speakers:\n    - Alex Topalov\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Alex Topalov\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"1nytCQoEl9I\"\n\n# Tea Break\n\n- id: \"aja-hammerly-rubyconf-my-2017\"\n  title: \"Syntax Isn't Everything: NLP For Rubyists\"\n  raw_title: \"Syntax Isn't Everything: NLP For Rubyists - RubyConfMY 2017\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Aja Hammerly (@the_thagomizer)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"-zoN4bBYhyg\"\n\n- id: \"ilake-chang-rubyconf-my-2017\"\n  title: \" 500X Memory Reduction In Rails With Postgres Schemas And Apartment\"\n  raw_title: \"500X Memory Reduction In Rails With Postgres Schemas And Apartment - RubyConfMY 2017\"\n  speakers:\n    - Ilake Chang\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Ilake Chang\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"8-k39-8pit0\"\n\n# CATERED LUNCH\n\n- id: \"vladimir-dementyev-rubyconf-my-2017\"\n  title: \"AnyCable - Universal Action Cable\"\n  raw_title: \"Anycable - Universal Action Cable - RubyConfMY 2017\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Vladimir Dementyev (@palkan_tula)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"j5oFx525zNw\"\n\n- id: \"tim-riley-rubyconf-my-2017\"\n  title: \"Real-World Functional Ruby\"\n  raw_title: \"Real-World Functional Ruby - RubyConfMY 2017\"\n  speakers:\n    - Tim Riley\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Tim Riley (@timriley)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"V-6Rv5I9iPM\"\n\n# Tea Break\n\n- id: \"kevin-litchfield-rubyconf-my-2017\"\n  title: \"Anatomy of an Active Record Migration\"\n  raw_title: \"ANATOMY OF AN ACTIVE RECORD MIGRATION - RubyConfMY 2017\"\n  speakers:\n    - Kevin Litchfield\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-12\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"kevin-litchfield-rubyconf-my-2017\"\n\n- id: \"elisha-tan-rubyconf-my-2017\"\n  title: \"How We Built TechLadies\"\n  raw_title: \"How We Built TechLadies - RubyConfMY 2017\"\n  speakers:\n    - Elisha Tan\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Elisha Tan (@elishatan)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"GxSb7LLEgNY\"\n\n# Tea Break\n\n- id: \"nick-marden-rubyconf-my-2017\"\n  title: \"Unix For Rubyists\"\n  raw_title: \"Unix For Rubyists - RubyConfMY 2017\"\n  speakers:\n    - Nick Marden\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Nick Marden\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"YnQ1AIDAd7k\"\n\n- id: \"dilum-navanjana-rubyconf-my-2017\"\n  title: \"Parallel Processing With Ruby\"\n  raw_title: \"Parallel Processing With Ruby - RubyConfMY 2017\"\n  speakers:\n    - Dilum Navanjana\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-12\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Dilum Navanjana (@dilumn_)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"v23VlKykU2M\"\n\n# Closing\n\n## Day 2 - October 13, 2017\n\n# Registration\n\n# Welcome Message\n\n- id: \"saron-yitbarek-rubyconf-my-2017\"\n  title: \"Lucky\"\n  raw_title: \"Lucky - RubyConfMY 2017\"\n  speakers:\n    - Saron Yitbarek\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Saron Yitbarek (@saronyitbarek)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"ER-4QFgJsaM\"\n\n- id: \"gooi-liang-zheng-rubyconf-my-2017\"\n  title: \"BDD With Cucumber\"\n  raw_title: \"BDD With Cucumber - RubyConfMY 2017\"\n  speakers:\n    - Gooi Liang Zheng\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Gooi Liang Zheng\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"fxgBJOlZIqE\"\n\n# Tea Break\n\n- id: \"tan-jun-qi-rubyconf-my-2017\"\n  title: \"All I'd Wanted To Know About Ruby's Object Model Starting Out...And Mooar!!!\"\n  raw_title: \"All I'd Wanted To Know About Ruby's Object Model Starting Out...And Mooar!!! - RubyConfMY 2017\"\n  speakers:\n    - Jun Qi Tan\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Tan Jun Qi\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"IbyPipTH1r0\"\n\n- id: \"akira-matsuda-rubyconf-my-2017-panel-ruby-core-team\"\n  title: \"Panel: Ruby Core Team\"\n  raw_title: \"Panel Session with Ruby Core Team - RubyConfMY 2017\"\n  speakers:\n    - Akira Matsuda\n    - Aaron Patterson\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Panelists:\n\n    - Akira Matsuda (@amatsuda)\n    - Aaron Patterson (@tenderlove)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"YpN6NLAcr4k\"\n\n# Catered Lunch\n\n- id: \"sylvia-choong-rubyconf-my-2017\"\n  title: \"Lightning Talk: Best Practices Of SVG On Ruby On Rails\"\n  raw_title: \"Best Practices Of SVG On Ruby On Rails - RubyConfMY 2017\"\n  speakers:\n    - Sylvia Choong\n    - Jany Mai\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Sylvia Choong & Jany Mai\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"56nmrNACyqw\"\n\n- id: \"kyle-dolezal-rubyconf-my-2017\"\n  title: \"Lightning Talk: Civic Coding In Ruby\"\n  raw_title: \"Civic Coding In Ruby - RubyConfMY 2017\"\n  speakers:\n    - Kyle Dolezal\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Kyle Dolezal\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"j88kBP8CsJo\"\n\n- id: \"anton-lvov-rubyconf-my-2017\"\n  title: \"Lightning Talk: Multiple Backend DBs In A Rails Application\"\n  raw_title: \"Multiple Backend DBs In A Rails Application - RubyConfMY 2017\"\n  speakers:\n    - Anton Lvov\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Anton Lvov\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"rJO9rPTkL38\"\n\n- id: \"jinny-wong-rubyconf-my-2017\"\n  title: \"Lightning Talk: One Blind Weekend\"\n  raw_title: \"One Blind Weekend - RubyConfMY 2017\"\n  speakers:\n    - Jinny Wong\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Jinny Wong (@shujinh)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"4x9qPgMsBfo\"\n\n- id: \"michael-cheng-rubyconf-my-2017\"\n  title: \"Lightning Talk: What About Ruby on Rails? ... From A PHP Guy\"\n  raw_title: \"What About Ruby On Rails? ... From A PHP Guy - RubyConfMY 2017\"\n  speakers:\n    - Michael Cheng\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Michael Cheng (@coderkungfu)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"WdSEVwy9-eo\"\n\n- id: \"gabrielle-ong-hui-min-rubyconf-my-2017\"\n  title: \"Lightning Talk: Programming Like An Athlete\"\n  raw_title: \"Programming Like An Athlete - RubyConfMY 2017\"\n  speakers:\n    - Gabrielle Ong Hui Min\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Gabrielle Ong Hui Min (@hellogabbo)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"15VckGvwSOY\"\n\n# Tea Break\n\n- id: \"daniel-baark-rubyconf-my-2017\"\n  title: \"Chasing Pandas\"\n  raw_title: \"Chasing Pandas - RubyConfMY 2017\"\n  speakers:\n    - Daniel Baark\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-26\"\n  description: |-\n    Speaker: Daniel Baark\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"-voFRSPT1F0\"\n\n- id: \"aaron-patterson-rubyconf-my-2017\"\n  title: \"Keynote: Exploring Memory in Ruby - Building a Compacting GC\"\n  raw_title: \"Keynote: Exploring Memory in Ruby - Building a Compacting GC - RubyConfMY 2017\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyConf MY 2017\"\n  date: \"2017-10-13\"\n  published_at: \"2017-11-07\"\n  description: |-\n    Speaker: Aaron Patterson (@tenderlove)\n\n    Website: http://rubyconf.my\n\n    Produced by Engineers.SG\n  video_provider: \"youtube\"\n  video_id: \"Kgi0MwWQgDE\"\n# After Party by GitHub\n\n# Pubcrawl by Umai\n"
  },
  {
    "path": "data/rubyconf-my/rubyconf-my-2018/event.yml",
    "content": "---\nid: \"rubyconf-my-2018\"\ntitle: \"RubyConf MY 2018\"\nkind: \"conference\"\nlocation: \"Kuala Lumpur, Malaysia\"\ndescription: \"\"\nstart_date: \"2018-10-25\"\nend_date: \"2018-10-26\"\nchannel_id: \"UCtayOVyGOpjYCcNzVCgR0Xg\"\nyear: 2018\nbanner_background: \"#081625\"\nfeatured_background: \"#000000\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubyconf.my\"\ncoordinates:\n  latitude: 4.210484\n  longitude: 101.975766\n"
  },
  {
    "path": "data/rubyconf-my/rubyconf-my-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.my/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-my/series.yml",
    "content": "---\nname: \"RubyConf MY\"\nwebsite: \"http://rubyconf.my\"\ntwitter: \"rubyconfmy\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_name: \"\"\nyoutube_channel_id: \"\"\ndefault_country_code: \"MY\"\naliases:\n  - RubyConf Malaysia\n"
  },
  {
    "path": "data/rubyconf-philippines/rubyconf-philippines-2014/event.yml",
    "content": "---\nid: \"rubyconf-philippines-2014\"\ntitle: \"RubyConf Philippines 2014\"\ndescription: \"\"\nlocation: \"Manila, Philippines\"\nkind: \"conference\"\nstart_date: \"2014-03-28\"\nend_date: \"2014-03-29\"\nwebsite: \"http://rubyconf.ph/\"\ntwitter: \"rubyconfph\"\ncoordinates:\n  latitude: 14.5995133\n  longitude: 120.984234\n"
  },
  {
    "path": "data/rubyconf-philippines/rubyconf-philippines-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.ph/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-philippines/rubyconf-philippines-2015/event.yml",
    "content": "---\nid: \"rubyconf-philippines-2015\"\ntitle: \"RubyConf Philippines 2015\"\ndescription: \"\"\nlocation: \"Boracay Island, Philippines\"\nkind: \"conference\"\nstart_date: \"2015-03-27\"\nend_date: \"2015-03-28\"\nwebsite: \"http://rubyconf.ph/2015/\"\ntwitter: \"rubyconfph\"\nplaylist: \"https://www.youtube.com/playlist?list=PL0mVjsUoElSGlKtZOeqZKUMOB2w8qlUC_\"\ncoordinates:\n  latitude: 11.9673753\n  longitude: 121.924815\n"
  },
  {
    "path": "data/rubyconf-philippines/rubyconf-philippines-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.ph/2015/\n# Videos: https://www.youtube.com/playlist?list=PL0mVjsUoElSGlKtZOeqZKUMOB2w8qlUC_\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-philippines/rubyconf-philippines-2016/event.yml",
    "content": "---\nid: \"rubyconf-philippines-2016\"\ntitle: \"RubyConf Philippines 2016\"\ndescription: \"\"\nlocation: \"Manila, Philippines\"\nkind: \"conference\"\nstart_date: \"2016-04-07\"\nend_date: \"2016-04-09\"\nwebsite: \"http://rubyconf.ph/2016/\"\ntwitter: \"rubyconfph\"\nplaylist: \"https://www.youtube.com/playlist?list=PL0mVjsUoElSH173SE64f28eQeTmXnufQj\"\ncoordinates:\n  latitude: 14.5995133\n  longitude: 120.984234\n"
  },
  {
    "path": "data/rubyconf-philippines/rubyconf-philippines-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.ph/2016/\n# Videos: https://www.youtube.com/playlist?list=PL0mVjsUoElSH173SE64f28eQeTmXnufQj\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-philippines/rubyconf-philippines-2017/event.yml",
    "content": "---\nid: \"rubyconf-philippines-2017\"\ntitle: \"RubyConf Philippines 2017\"\ndescription: \"\"\nlocation: \"Bohol, Philippines\"\nkind: \"conference\"\nstart_date: \"2017-03-16\"\nend_date: \"2017-03-18\"\nwebsite: \"http://rubyconf.ph/2017/\"\ntwitter: \"rubyconfph\"\nplaylist: \"https://www.youtube.com/playlist?list=PL0mVjsUoElSHKtxq2efDQc6EXTDqabxdV\"\ncoordinates:\n  latitude: 9.849991099999999\n  longitude: 124.1435427\n"
  },
  {
    "path": "data/rubyconf-philippines/rubyconf-philippines-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.ph/2017/\n# Videos: https://www.youtube.com/playlist?list=PL0mVjsUoElSHKtxq2efDQc6EXTDqabxdV\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-philippines/rubyconf-philippines-2018/event.yml",
    "content": "---\nid: \"rubyconf-philippines-2018\"\ntitle: \"RubyConf Philippines 2018\"\ndescription: \"\"\nlocation: \"Manila, Philippines\"\nkind: \"conference\"\nstart_date: \"2018-03-15\"\nend_date: \"2018-03-17\"\nwebsite: \"http://rubyconf.ph/\"\ntwitter: \"rubyconfph\"\nplaylist: \"https://www.youtube.com/playlist?list=PL0mVjsUoElSENtu25MLim42HJszfsXDt2\"\ncoordinates:\n  latitude: 14.5995133\n  longitude: 120.984234\n"
  },
  {
    "path": "data/rubyconf-philippines/rubyconf-philippines-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.ph/\n# Videos: https://www.youtube.com/playlist?list=PL0mVjsUoElSENtu25MLim42HJszfsXDt2\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-philippines/series.yml",
    "content": "---\nname: \"RubyConf Philippines\"\nwebsite: \"http://rubyconf.ph/\"\ntwitter: \"rubyconfph\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyconf-portugal/rubyconf-portugal-2014/event.yml",
    "content": "---\nid: \"rubyconf-portugal-2014\"\ntitle: \"RubyConf Portugal 2014\"\ndescription: \"\"\nlocation: \"Braga, Portugal\"\nkind: \"conference\"\nstart_date: \"2014-10-13\"\nend_date: \"2014-10-14\"\nwebsite: \"http://2014.rubyconf.pt/\"\nplaylist: \"https://www.youtube.com/playlist?list=PLgGhdJEbwzoLCuTL4BD--TOKdHomGsRDm\"\ncoordinates:\n  latitude: 41.5454486\n  longitude: -8.426506999999999\n"
  },
  {
    "path": "data/rubyconf-portugal/rubyconf-portugal-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2014.rubyconf.pt/\n# Videos: https://www.youtube.com/playlist?list=PLgGhdJEbwzoLCuTL4BD--TOKdHomGsRDm\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-portugal/rubyconf-portugal-2015/event.yml",
    "content": "---\nid: \"rubyconf-portugal-2015\"\ntitle: \"RubyConf Portugal 2015\"\ndescription: \"\"\nlocation: \"Braga, Portugal\"\nkind: \"conference\"\nstart_date: \"2015-09-14\"\nend_date: \"2015-09-15\"\nwebsite: \"http://2015.rubyconf.pt/\"\nplaylist: \"https://www.youtube.com/playlist?list=PLgGhdJEbwzoJSREjEZhKnDxyezC47Cgh5\"\ncoordinates:\n  latitude: 41.5454486\n  longitude: -8.426506999999999\n"
  },
  {
    "path": "data/rubyconf-portugal/rubyconf-portugal-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2015.rubyconf.pt/\n# Videos: https://www.youtube.com/playlist?list=PLgGhdJEbwzoJSREjEZhKnDxyezC47Cgh5\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-portugal/rubyconf-portugal-2016/event.yml",
    "content": "---\nid: \"rubyconf-portugal-2016\"\ntitle: \"RubyConf Portugal 2016\"\ndescription: \"\"\nlocation: \"Braga, Portugal\"\nkind: \"conference\"\nstart_date: \"2016-10-27\"\nend_date: \"2016-10-28\"\nwebsite: \"http://rubyconf.pt/\"\nplaylist: \"https://www.youtube.com/playlist?list=PLgGhdJEbwzoI6sUw_2wTlFHCGPRVoatln\"\ncoordinates:\n  latitude: 41.5454486\n  longitude: -8.426506999999999\n"
  },
  {
    "path": "data/rubyconf-portugal/rubyconf-portugal-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubyconf.pt/\n# Videos: https://www.youtube.com/playlist?list=PLgGhdJEbwzoI6sUw_2wTlFHCGPRVoatln\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-portugal/series.yml",
    "content": "---\nname: \"RubyConf Portugal\"\nwebsite: \"http://2014.rubyconf.pt/\"\ntwitter: \"rubyconfpt\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2014/event.yml",
    "content": "---\nid: \"PLhKZ4RWngmpCUi7IcCDEVSRc1OsaJSguB\"\ntitle: \"RubyConf Taiwan 2014\"\ndescription: \"\"\nlocation: \"Taipei, Taiwan\"\nkind: \"conference\"\nstart_date: \"2014-04-25\"\nend_date: \"2014-04-26\"\nwebsite: \"https://rubyconf.tw/2014/\"\nplaylist: \"https://www.youtube.com/playlist?list=PLhKZ4RWngmpCUi7IcCDEVSRc1OsaJSguB\"\ncoordinates:\n  latitude: 25.0329636\n  longitude: 121.5654268\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyconf.tw/2014/\n# Videos: https://www.youtube.com/playlist?list=PLhKZ4RWngmpCUi7IcCDEVSRc1OsaJSguB\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2015/event.yml",
    "content": "---\nid: \"PLhKZ4RWngmpDVKgAH_p_X7gtLSGsvmMJj\"\ntitle: \"RubyConf Taiwan 2015\"\ndescription: \"\"\nlocation: \"Taipei, Taiwan\"\nkind: \"conference\"\nstart_date: \"2015-09-11\"\nend_date: \"2015-09-12\"\nwebsite: \"https://2015.rubyconf.tw/\"\nplaylist: \"https://www.youtube.com/playlist?list=PLhKZ4RWngmpDVKgAH_p_X7gtLSGsvmMJj\"\ncoordinates:\n  latitude: 25.0329636\n  longitude: 121.5654268\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2015.rubyconf.tw/\n# Videos: https://www.youtube.com/playlist?list=PLhKZ4RWngmpDVKgAH_p_X7gtLSGsvmMJj\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2016/event.yml",
    "content": "---\nid: \"PLhKZ4RWngmpB7wxvDs02oGA9IRKw3dVYO\"\ntitle: \"RubyConf Taiwan 2016\"\ndescription: \"\"\nlocation: \"Taipei, Taiwan\"\nkind: \"conference\"\nstart_date: \"2016-12-02\"\nend_date: \"2016-12-03\"\nwebsite: \"https://2016.rubyconf.tw/\"\nplaylist: \"https://www.youtube.com/playlist?list=PLhKZ4RWngmpB7wxvDs02oGA9IRKw3dVYO\"\ncoordinates:\n  latitude: 25.0329636\n  longitude: 121.5654268\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2016.rubyconf.tw/\n# Videos: https://www.youtube.com/playlist?list=PLhKZ4RWngmpB7wxvDs02oGA9IRKw3dVYO\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2018/event.yml",
    "content": "---\nid: \"PLhKZ4RWngmpAdmjfDBiqiOKpk1PiCIb2A\"\ntitle: \"RubyConf Taiwan 2018\"\ndescription: \"\"\nlocation: \"Taipei, Taiwan\"\nkind: \"conference\"\nstart_date: \"2018-04-27\"\nend_date: \"2018-04-28\"\nwebsite: \"https://2018.rubyconf.tw/\"\nplaylist: \"https://www.youtube.com/playlist?list=PLhKZ4RWngmpAdmjfDBiqiOKpk1PiCIb2A\"\ncoordinates:\n  latitude: 25.0329636\n  longitude: 121.5654268\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2018.rubyconf.tw/\n# Videos: https://www.youtube.com/playlist?list=PLhKZ4RWngmpAdmjfDBiqiOKpk1PiCIb2A\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2019/event.yml",
    "content": "---\nid: \"PLhKZ4RWngmpBgD6t068O_EZ4grSlUtl3Y\"\ntitle: \"RubyConf Taiwan 2019\"\ndescription: \"\"\nlocation: \"Taipei, Taiwan\"\nkind: \"conference\"\nstart_date: \"2019-07-26\"\nend_date: \"2019-07-27\"\nwebsite: \"https://2019.rubyconf.tw\"\nplaylist: \"https://www.youtube.com/playlist?list=PLhKZ4RWngmpBgD6t068O_EZ4grSlUtl3Y\"\ncoordinates:\n  latitude: 25.0329636\n  longitude: 121.5654268\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2019.rubyconf.tw\n# Videos: https://www.youtube.com/playlist?list=PLhKZ4RWngmpBgD6t068O_EZ4grSlUtl3Y\n---\n[]\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2021/event.yml",
    "content": "---\nid: \"rubyconf-taiwan-2021\"\ntitle: \"RubyConf Taiwan 2021\"\ndescription: |-\n  Entirely virtual on Gathertown & Youtube\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2021-07-31\"\nend_date: \"2021-08-01\"\nwebsite: \"https://2021.rubyconf.tw\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2021/videos.yml",
    "content": "# Website: https://2021.rubyconf.tw\n# Videos: -\n---\n- id: \"yukihiro-matsumoto-rubyconf-taiwan-2021\"\n  title: \"How to Design the Future\"\n  raw_title: \"RubyConf Taiwan 2021-Keynote-How to Design the Future by Yukihiro Matsumoto (Matz)\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-07-31\"\n  language: \"english\"\n  description: |-\n    Matz will explain how to design the future from lessons he learned from the history of Ruby development. By following his steps you will also be able to create the future!\n  video_provider: \"not_published\"\n  video_id: \"yukihiro-matsumoto-rubyconf-taiwan-2021\"\n\n- id: \"cindy-liu-rubyconf-taiwan-2021\"\n  title: \"Dockerize Rails Best Practice / Rails 容器化最佳實踐\"\n  raw_title: \"RubyConf Taiwan 2021-Dockerize Rails Best Practice by Cindy Liu\"\n  speakers:\n    - Cindy Liu\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-07-31\"\n  language: \"Chinese\"\n  description: |-\n    In recent years, Container technology has gradually became the mainstream choice of development and deployment. In the DevOps plan of 5xRuby software development, we have designed the best practice for packaging images with GitLab CI. In this speech, I will share how we containerize a Rails application and make a container image with the size of 100MB for Production Ready.\n  video_provider: \"not_published\"\n  video_id: \"cindy-liu-rubyconf-taiwan-2021\"\n\n- id: \"samuel-williams-rubyconf-taiwan-2021\"\n  title: \"Event Driven Concurrency using the Ruby Fiber Scheduler\"\n  raw_title: \"RubyConf Taiwan 2021-Event Driven Concurrency using the Ruby Fiber Scheduler by Samuel Williams\"\n  speakers:\n    - Samuel Williams\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-07-31\"\n  language: \"english\"\n  description: |-\n    Event driven concurrency is a feature of many modern programming languages, but until recently was difficult to use with Rub y. Ru by 3 includes a new fiber scheduler interface which allows us to hook into non-blocking operations and execute them concurrently, however robust implementations of this interface are not yet widely available. We will discuss the implementation of the Async fiber scheduler, how it works and how it can be used to build highly scalable applications.\n  video_provider: \"not_published\"\n  video_id: \"samuel-williams-rubyconf-taiwan-2021\"\n\n- id: \"大兜-rubyconf-taiwan-2021\"\n  title: \"Sanbao GO, A Free Traffic Violation Reporting System that Concerns Privacy\"\n  raw_title: \"RubyConf Taiwan 2021-Sanbao GO by 大兜\"\n  speakers:\n    - Da Dou (大兜)\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-07-31\"\n  language: \"zh\"\n  description: |-\n    Sanbao GO is a PWA powered by Ruby on Rails and React. We create it since 2019 because of the disappointment to the system made by the government and non-government. This session would cover a brief introduction of the problem and current situation of the government’s reporting system, and the implementation details of Sanbao GO including email processing using Action Mailbox. https://www.sanbao.icu/\n  video_provider: \"not_published\"\n  video_id: \"大兜-rubyconf-taiwan-2021\"\n\n- id: \"albert-song-tim-wei-rubyconf-taiwan-2021\"\n  title: \"Rina: Chatbot Game Engine for Real-life Adventure Games & Case Study\"\n  raw_title: \"RubyConf Taiwan 2021-Rina by Albert Song & Tim Wei\"\n  speakers:\n    - Albert Song\n    - Tim Wei\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-07-31\"\n  language: \"english\"\n  description: |-\n    Rina is a chatbot game engine developed for CYBERSEC 2021 playground booth adventure game \"1337 Operation\".\n\n    Related report:\n    https://www.ithome.com.tw/news/144252\n\n    We will release the source code for this project under MIT license alongside this talk.\n\n    In the game \"1337 Operation\", the player is an FBI agent investigating a major ransomware attack. Though intelligence gathering & analysis, the player will identify the related hacking group, and the location of the suspect.\n\n    At the finale, the player and other FBI agents will storm the residence of the suspect, using a micro bomb to break open the door and arrest the suspect.\n\n    The whole process is captured by cameras, a fictional news clip would be automatically sent to the player as a souvenir.\n\n    We've included various easter egg in the game. The player could check his/her process at the progress monitor on our booth, and compete with other players.\n\n    In this talk, we will introduce various feature of Rina, e.g., context-aware dialogue, achievements, rankings, message speed adjustments and async external service integration.\n\n    We will discuss our design and implementation. Using \"1337 Operation\" as our modal case, we will introduce how each feature could be utilized.\n\n    Besides Rina, we will also share our experience on composing the story of the game, making interactive props, and how we connect physical devices with the game.\n\n    We hope after our talk, you can also make your own real-life adventure game driven by chatbot, with ease.\"\n  video_provider: \"not_published\"\n  video_id: \"albert-song-tim-wei-rubyconf-taiwan-2021\"\n\n- id: \"jimmy-wu-rubyconf-taiwan-2021\"\n  title: \"From Ruby To Python, From Game Designer To Software Developer\"\n  raw_title: \"RubyConf Taiwan 2021-From Ruby To Python by Jimmy Wu\"\n  speakers:\n    - Jimmy Wu\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-07-31\"\n  language: \"Chinese\"\n  description: |-\n    Review: Learning Ruby and Ruby On Rails for a career change from a game designer to becoming a software developer. Using Python In order to fulfill the needs of the client and develop b2b EDI System. The talk is for the beginners of learning to code or just start to code recently as a job\n  video_provider: \"not_published\"\n  video_id: \"jimmy-wu-rubyconf-taiwan-2021\"\n\n- id: \"meng-ying-tsai-rubyconf-taiwan-2021\"\n  title: \"Intro of Ruby CGI programming, Rack and Puma\"\n  raw_title: \"RubyConf Taiwan 2021-Intro of Ruby CGI programming by Meng-Ying Tsai\"\n  speakers:\n    - Meng-Ying Tsai\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-08-01\"\n  language: \"zh\"\n  description: |-\n    The Rails beginners might curious: \"What is rack in ruby? What is puma in ruby?\" In this talk, I would like to clear up the confusion. In addition I am going to show how to run Ruby CGI script with python, to explain how are the hostname, path passed into the CGI program.\n  video_provider: \"not_published\"\n  video_id: \"meng-ying-tsai-rubyconf-taiwan-2021\"\n\n- id: \"soumya-ray-rubyconf-taiwan-2021\"\n  title: \"Ruby in the Classroom: Going off the Rails with Roda and Sequel\"\n  raw_title: \"RubyConf Taiwan 2021-Ruby in the Classroom by Soumya Ray\"\n  speakers:\n    - Soumya Ray\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-08-01\"\n  language: \"english\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"soumya-ray-rubyconf-taiwan-2021\"\n\n- id: \"panel-rubyconf-taiwan-2021\"\n  title: \"Panel: The Developer Community vs. the Short Supply of Senior Developers\"\n  raw_title: \"RubyConf Taiwan 2021-Panel Discussion by 鄧慕凡, 范聖佑, Caesar Chi, 蘇芃翰\"\n  speakers:\n    - Mu-Fan Teng\n    - Fan Sheng You (范聖佑)\n    - Caesar Chi\n    - Su Peng Han (蘇芃翰)\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-08-01\"\n  language: \"zh\"\n  description: |-\n    In recent years, Taiwan has attracted a lot of global companies due to political and economical reasons. We have also seen a surge of oversea entrepreneurs setting base here since the pandemic. This trend has put senior developers in high demand but short supply. Ruby Taiwan invites leaders of the PHP, Javascript and Java communities, who are also business owners themselves, to talk about how we as the developer community should face these challenges.\n  video_provider: \"not_published\"\n  video_id: \"panel-rubyconf-taiwan-2021\"\n\n- id: \"john-lin-rubyconf-taiwan-2021\"\n  title: \"Making Multi-platform Tool With mruby\"\n  raw_title: \"RubyConf Taiwan 2021-Making Multi-platform Tool With mruby by John Lin\"\n  speakers:\n    - John Lin\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-08-01\"\n  language: \"zh\"\n  description: |-\n    Deployment is one of the biggest issue when developing tools with Ruby. Due to the interpreter nature of Ruby, we need to bundle interpreter and all dependencies with our code when deploying. It's troublesome to deploy tons of stuffs. Is there a better way to deploy? This talk will introduce mruby, a Ruby that's designed to be embedded into other programs. And show how to write multi-platform single binary tool with mruby. difficulty: easy expected audience: people who interested in mruby. people who want to write multi-platform tools.\"\n  video_provider: \"not_published\"\n  video_id: \"john-lin-rubyconf-taiwan-2021\"\n\n- id: \"delton-ding-rubyconf-taiwan-2021\"\n  title: \"Ruby High Concurrent Programming in 2021\"\n  raw_title: \"RubyConf Taiwan 2021-Ruby High Concurrent Programming in 2021 by Delton Ding\"\n  speakers:\n    - Delton Ding\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-08-01\"\n  language: \"zh\"\n  description: |-\n    - The Sufficient and Necessary Conditions in High Concurrency Program\n    - The History of Ruby Async Programming\n    - Ruby 3 Fiber Scheduler\n    - Ruby 3 Ractors\n    - When Could We Benefit from Async Programs\n    - How to Upgrade Your Ruby Program\n  video_provider: \"not_published\"\n  video_id: \"delton-ding-rubyconf-taiwan-2021\"\n\n- id: \"cang-shi-xian-ye-rubyconf-taiwan-2021\"\n  title: 'Talk the \"tricks\" of programming skill with the LINE Bot and the crawl'\n  raw_title: \"RubyConf Taiwan 2021-Talk the tricks of programming with LINE Bot by 蒼時弦也\"\n  speakers:\n    - Cang Shi Xian Ye (蒼時弦也)\n  event_name: \"RubyConf Taiwan 2021\"\n  date: \"2021-08-01\"\n  language: \"zh\"\n  description: |-\n    When I write some code, I usually think about \"can I do it better?\" since my over 10 years of programming life. I use Ruby to write a simple LINE Bot with many Ruby language features to help me to find new movies as I need. Therefore I think about how can we use the \"tricks\" to let others feel the programming is very \"simple\" after we learned the programming skills. Let me show the programming tricks to you, it is not easy for everyone and needs a lot of practice and programming language knowledge, but it is not the reason to stop us.\n  video_provider: \"not_published\"\n  video_id: \"cang-shi-xian-ye-rubyconf-taiwan-2021\"\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2023/event.yml",
    "content": "---\nid: \"PLhKZ4RWngmpARULXh_Sv5X5AYQ8hLlGih\"\ntitle: \"RubyConf Taiwan 2023\"\nkind: \"conference\"\nlocation: \"Taipai, Taiwan\"\ndescription: |-\n  Dec 15-16 2023, National Taipei University of Education, https://2023.rubyconf.tw\npublished_at: \"2023-12-15\"\nstart_date: \"2023-12-15\"\nend_date: \"2023-12-16\"\nchannel_id: \"UCqw_z59yI24SivuD573FECA\"\nyear: 2023\nbanner_background: \"#0A0323\"\nfeatured_background: \"#0A0323\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2023.rubyconf.tw/\"\ncoordinates:\n  latitude: 25.0329636\n  longitude: 121.5654268\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2023/videos.yml",
    "content": "---\n# TODO: conference website\n\n# Day 1\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-taiwan-2023\"\n  title: \"Keynote: 30 Years of Ruby\"\n  raw_title: \"RubyConf Taiwan 2023-Keynote-30 Years of Ruby by MATSUMOTO Yukihiro (Matz)\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-25\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Lessons Matz has learned from the history of Ruby development\n  video_provider: \"youtube\"\n  video_id: \"YpRXqcULyVI\"\n\n# Track 1\n- id: \"cristian-planas-rubyconf-taiwan-2023\"\n  title: \"A Rails Performance Guidebook: from 0 to 1B requests/day\"\n  raw_title: \"RubyConf Taiwan 2023-A Rails performance guidebook: from 0 to 1B requests/day by Cristian Planas\"\n  speakers:\n    - Cristian Planas\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-21\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    A Rails performance guidebook: from 0 to 1B requests/day\n\n    Building a feature is not good enough anymore: all your work won't be of use if it's not performant enough. So how to improve performance? After all, performance is not an easy discipline to master: all slow applications are slow in their own way, meaning that there is no silver bullet for these kinds of problems.\n\n    In this presentation, we will guide you across patterns, strategies, and little tricks to improve performance. We will do that by sharing real stories of our daily experience facing and solving real performance issues in an application that daily serves billions of requests per day.\n  video_provider: \"youtube\"\n  video_id: \"6fE94oa5xjo\"\n\n# Track 2\n- id: \"ryo-kajiwara-rubyconf-taiwan-2023\"\n  title: \"L406-D1S1-Adventures in the Dungeons of OpenSSL\"\n  raw_title: \"RubyConf Taiwan 2023-L406-D1S1-Adventures in the Dungeons of OpenSSL by Ryo KAJIWARA\"\n  speakers:\n    - Ryo Kajiwara\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-21\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Adventures in the Dungeons of OpenSSL by Ryo KAJIWARA\n\n    As part of implementing Hybrid Public Key Encryption (HPKE; RFC 9180) in Ruby, I had a chance to send a patch into Ruby's OpenSSL gem. Missing functionalities? Major version upgrade of the OpenSSL backend? There is a deep dungeon behind one of Ruby's default gem, and I will talk about one adventure through this dungeon.\n  video_provider: \"youtube\"\n  video_id: \"kFBe9hVMgR8\"\n\n# Track 1\n- id: \"yuji-yokoo-rubyconf-taiwan-2023\"\n  title: \"Developing cross-platform mruby software for Dreamcast and Wii\"\n  raw_title: \"RubyConf Taiwan 2023-Developing cross-platform mruby software for Dreamcast and Wii by Yuji YOKOO\"\n  speakers:\n    - Yuji Yokoo\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-21\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Developing cross-platform mruby software for Dreamcast and Wii\n\n    With mruby, we can write Ruby for many environments including old video game consoles. I am working on a cross-platform library for mruby so software written for mruby on Dreamcast can be run on Wii with little change to the source. I have ported the block puzzle I showed at RubyConfTW 2019 to Wii, and am now working on the presentation tool.\n\n    I will tell you about what is involved in making a cross-platform mruby library for Dreamcast and Wii, as well as challenges and lessons learned.\n\n    This presentation will (hopefully) be delivered on either of those consoles and will include some live demos.\n  video_provider: \"youtube\"\n  video_id: \"8bts8Ko6jkA\"\n\n# Track 2\n- id: \"tetsuya-hirota-rubyconf-taiwan-2023\"\n  title: \"High Speed Parsing Massive XML Data in Ruby\"\n  raw_title: \"RubyConf Taiwan 2023-High Speed Parsing Massive XML Data in Ruby by HIROTA Tetsuya\"\n  speakers:\n    - Tetsuya Hirota\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-26\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    High Speed Parsing Massive XML Data in Ruby\n\n    A massive XML called BioProject has been published. However, when I parsed the XML as it was, rexml got freeze somewhere, and nokogiri ended up consuming a large amount of memory and being slow. Looking at the sample implementation in Python, it uses iterparse() to parse each element in the first layer. Therefore, we created a similar mechanism in Ruby and also used ractor to speed it up.\n  video_provider: \"youtube\"\n  video_id: \"0W7P29jxUmI\"\n\n# Track 1\n- id: \"jian-wei-hang-rubyconf-taiwan-2023\"\n  title: \"Refining Fork Management: From Workarounds to `Process#_fork`\"\n  raw_title: \"RubyConf Taiwan 2023-Refining Fork Management: From Workarounds to `Process#_fork` by Jian Wei-Hang\"\n  speakers:\n    - Jian Wei-Hang\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-21\"\n  language: \"Chinese\"\n  description: |-\n    #rubyconftw 2023\n\n    Refining Fork Management: From Workarounds to `Process#_fork`\n\n    With the release of Ruby 3.1 in 2021, an enhancement arrived as Process#_fork, allowing us to override the fork method. This addition simplifies creating callbacks when forking. While there was no official method to track fork events prior to Ruby 3.1, this limitation didn't deter the community from exploring various approaches to achieve the same goal.\n\n    In the past, Rails encouraged the use of before_fork and after_fork for connection management, redis-rb ensured fork safety by storing the Process#pid in a variable, and some even used threads to track fork events.\n\n    During this session, I will delve into the backstory of _fork and explore the diverse methods the community employed for creating callbacks during forking prior to Ruby 3.1.\n  video_provider: \"youtube\"\n  video_id: \"nOTLdEpj8oo\"\n\n# Track 2\n- id: \"mark-chao-rubyconf-taiwan-2023\"\n  title: \"Translating XML and EPUB using ChatGPT\"\n  raw_title: \"RubyConf Taiwan 2023-Translating XML and EPUB using ChatGPT by Mark CHAO\"\n  speakers:\n    - Mark Chao\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-26\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Translating XML and Epub using ChatGPT\n\n    Natsukantou and epub-translator gems offer XML translation by allowing users to mix & match filters and translation services (DeepL/ChatGPT). The gem's architecture will be presented, showcasing its middleware pattern, the use cases and wizard configuration inference.\n  video_provider: \"youtube\"\n  video_id: \"P4jCrhoCKmQ\"\n\n# Track 1\n- id: \"hiroshi-shibata-rubyconf-taiwan-2023\"\n  title: \"Deep dive into Ruby require\"\n  raw_title: \"RubyConf Taiwan 2023-Deep dive into Ruby require by SHIBATA Hiroshi\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-21\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Deep dive into Ruby require\n\n    Since Ruby's bundled and default gems change every year with each release, some versions may suddenly happen LoadError at require when running bundle exec or bin/rails, for example matrix or net-smtp.\n\n    In this presentation, I will introduce the details of the functionality that extends Ruby's require to provide guidance to users on what they can do to load them. And I will also show how $LOAD_PATH is build behind Ruby and Rails by Bundler.\n  video_provider: \"youtube\"\n  video_id: \"qK3FTOSSD3A\"\n\n# Track 2\n- id: \"helio-cola-rubyconf-taiwan-2023\"\n  title: \"Let's pop into Passkeys\"\n  raw_title: \"RubyConf Taiwan 2023-Let's pop into Passkeys by Helio Cola\"\n  speakers:\n    - Helio Cola\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-26\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Let's pop into Passkeys\n\n    Can you recall a world without having to remember passwords? If Passkeys becomes widely available, that world is a few steps away in our future. Instead of remembering passwords, we will use our biometrics, already available in our phones, laptops, and desktops, and public key encryption! To a future with no passwords!\n  video_provider: \"youtube\"\n  video_id: \"VpJrEVmVTRM\"\n\n# Track 1\n- id: \"ho-tse-ching-rubyconf-taiwan-2023\"\n  title: \"Use View Components with Rails Projects from the Design Stage\"\n  raw_title: \"RubyConf Taiwan 2023-Use View Components with Rails Projects from the Design Stage by Ho Tse-Ching\"\n  speakers:\n    - Ho Tse-Ching\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-21\"\n  language: \"Chinese\"\n  description: |-\n    #rubyconftw 2023\n\n    從設計階段就開始元件化 Rails 專案 / Use View Components with Rails Projects from the Design Stage\n\n    介紹如何從 Figma 設計稿，就開始規劃、製作與預覽元件（View Component + Lookbook）。 說明目前偏好的元件組成方式，協助製作元件的工具和注意事項，以及安置元件到頁面中的方式（partial + helper）。 展示利用 settings 搭配 builder 活用元件的嘗試。\n\n    Let’s start to plan, create, and preview view components from the design stage with Figma, ViewComponent and Lookbook. I will introduce my preferred way to compose view components, the tools and tips which can help build, and how to use partial and helper to render it. I will also show you a pattern to rendering view components with settings and builder.\n  video_provider: \"youtube\"\n  video_id: \"Mx4ir49-hQs\"\n\n# Track 2\n- id: \"junichi-kobayashi-rubyconf-taiwan-2023\"\n  title: \"Understanding Parser Generators surronding Ruby with Contributing Lrama\"\n  raw_title: \"RubyConf Taiwan 2023-Understanding Parser Generators surronding Ruby with Contributing Lrama\"\n  speakers:\n    - Junichi Kobayashi\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-26\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Understanding Parser Generators surronding Ruby with Contributing Lrama\n\n    At RubyKaigi 2023, yui-knk introduced Lrama, for which I submitted a PR to implement the 'Named References' feature, a functionality found in GNU Bison. In this presentation, I will delve into the internal workings of Lrama gained through this implementation. Alongside, I will touch upon the foundational knowledge of parsers and parser generators, as well as the current state of parsers surrounding Ruby.\n  video_provider: \"youtube\"\n  video_id: \"QvU7uvPN5XM\"\n\n# Track 1\n- id: \"hitoshi-hasumi-rubyconf-taiwan-2023\"\n  title: \"The Rise of Microcontroller Ruby\"\n  raw_title: \"RubyConf Taiwan 2023-The Rise of Microcontroller Ruby by HASUMI Hitoshi\"\n  speakers:\n    - Hitoshi Hasumi\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-22\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    The Rise of Microcontroller Ruby\n\n    In this presentation, we will embark on a journey of live coding to bring microcontrollers to life. All you need is (at least) two \"Raspberry Pi Pico W\" boards, the same number of USB cables, and a laptop. Witness the realization of PicoRuby, a production-ready Ruby implementation for microcontrollers, as we delve into the world of innovation.\n  video_provider: \"youtube\"\n  video_id: \"WxZNE5zTAjg\"\n\n# Track 2\n- id: \"radoslav-stankov-rubyconf-taiwan-2023\"\n  title: \"Component Driven UI with ViewComponent gem\"\n  raw_title: \"RubyConf Taiwan 2023-Component Driven UI with ViewComponent gem by Radoslav Stankov\"\n  speakers:\n    - Radoslav Stankov\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-15\"\n  published_at: \"2024-03-26\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Component Driven UI with ViewComponent gem\n\n    The View layer is the messiest part of a Ruby on Rails application. Developers are confused about where to put logic. Should it be in the model, presenter, decorator, helper, or partial?\n\n    ViewComponents, developed by GitHub simplifies the View layer and makes it much easier to manage.\n  video_provider: \"youtube\"\n  video_id: \"JlksEZMXt8Y\"\n\n# Day 2\n\n# Track 1\n- id: \"aotoki-tsuruya-rubyconf-taiwan-2023\"\n  title: \"Rethink Rails Architecture\"\n  raw_title: \"RubyConf Taiwan 2023-Rethink Rails Architecture by Aotoki Tsuruya\"\n  speakers:\n    - Aotoki Tsuruya\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-22\"\n  language: \"Chinese\"\n  description: |-\n    #rubyconftw 2023\n\n    Rethink Rails Architecture\n\n    Rails 讓開發 Web Application 變得相當容易，然而因為簡化了許多問題，當我們面臨更複雜的系統時感到極大的挑戰。複雜的 Rails 專案之所以難以維護是 Rails 在架構上的設計造成的限制，讓我們重新思考 Rails 來尋找更容易維護的架構。\n  video_provider: \"youtube\"\n  video_id: \"g0iumjmIwnk\"\n\n# Track 2\n- id: \"andrei-bondarev-rubyconf-taiwan-2023\"\n  title: \"Catching the AI Train\"\n  raw_title: \"RubyConf Taiwan 2023-Catching the AI Train by Andrei Bondarev\"\n  speakers:\n    - Andrei Bondarev\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-25\"\n  slides_url: \"https://speakerdeck.com/andreibondarev/rubyconf-taiwan-2023-catching-the-ai-train\"\n  language: \"English\"\n  description: |-\n    Official Website：http://2023.rubyconf.tw\n\n    The Large-Language Models have taken application development by storm. Ruby has libraries that help build LLM applications, e.g.: Langchain.rb. We need to understand what kind of LLM applications can be built, how to build them, and what are common pitfalls when building them. We're going to look at building vector (semantic) search, chat bots and business process automation solutions. We're going to learn AI/LLM-related concepts, terms and ideas, learn what AI agents are, and look at some of the latest cutting edge AI research.\n  video_provider: \"youtube\"\n  video_id: \"DdEamGfNg6o\"\n\n# Track 1\n- id: \"samuel-giddins-rubyconf-taiwan-2023\"\n  title: \"Handling 225k requests per second to RubyGems.org\"\n  raw_title: \"RubyConf Taiwan 2023-Handling 225k requests per second to RubyGems.org by Samuel Giddins\"\n  speakers:\n    - Samuel Giddins\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-22\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Handling 225k requests per second to RubyGems.org\n\n    Chances are you’ve run bundle install or gem install at some point, seeing as we’re at RubyConf. Turns out, you’re not alone. At peak times, RubyGems.org has received as many as 225 thousand requests per second. How does a small, mostly-volunteer team handle serving all that traffic with their rails app? Let’s dive into how using CDNs, scaling with static files, and wrangling expensive endpoints has kept your favorite gem index up and running over the past decade.\n  video_provider: \"youtube\"\n  video_id: \"53VESJCfnz4\"\n\n# Track 2\n- id: \"warren-wong-rubyconf-taiwan-2023\"\n  title: \"How Rails 7 Helped Us Achieve GDPR Compliance\"\n  raw_title: \"RubyConf Taiwan 2023-How Rails 7 Helped Us Achieve GDPR Compliance by  Warren Wong\"\n  speakers:\n    - Warren Wong\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-26\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    How Rails 7 Helped Us Achieve GDPR Compliance\n\n    Rails 7 introduced a new feature called Active Record Encryption. I will go over what it is, how it works, and how Viewabo used it to help us achieve GDPR compliance. I will include example usage and an overview of the preparatory work that went into implementing Active Record Encryption.\n  video_provider: \"youtube\"\n  video_id: \"ZhfQwvE_zBU\"\n\n# Track 1\n- id: \"delton-ding-rubyconf-taiwan-2023\"\n  title: \"Yet Another Ruby DSL for LLM\"\n  raw_title: \"RubyConf Taiwan 2023-Yet Another Ruby DSL for LLM by Delton Ding\"\n  speakers:\n    - Delton Ding\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-25\"\n  language: \"Chinese\"\n  description: |-\n    #rubyconftw 2023\n\n    在過去一年裏我們經歷了 LLM 的巨大衝擊，但是對於使用 LLM 實作應用依然困難重重。如何利用 Ruby 的 meta-programming 更好地對 LLM 進行處理和約束從而實作下一世代的 AI 應用是本 Topic 試圖討論的關鍵問題。\n  video_provider: \"youtube\"\n  video_id: \"IAMMhoA9bmg\"\n\n# Track 2\n- id: \"du-gia-huy-rubyconf-taiwan-2023\"\n  title: \"Monadic Approach to Ruby Error Handling\"\n  raw_title: \"RubyConf Taiwan 2023-Monadic Approach to Ruby Error Handling by Du Gia Huy\"\n  speakers:\n    - Du Gia Huy\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-26\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Monadic Approach to Ruby Error Handling\n\n    Error handling is an essential part of software development. No matter how well-written your code is, there will always be errors. The key is to handle them in a way that minimizes their impact.\n\n    In this talk, we will build a foundation of error handling concepts, categorizing errors and exceptions in Ruby. We'll look at practical code examples that demonstrate common issues when propagating errors through layers of code. Explore how Monadic Handling abstract away error handling details by combine Monads Result and Service Object in Ruby programming.\n\n    This talk will empower you understand how to use Monadic Handling Ruby code. You'll leave with a deeper appreciation of monads and concrete strategies for encapsulating errors elegantly in your Ruby applications. Join me to discover how monads enable you to minimize disruption and maximize control over error handling in Ruby.\n  video_provider: \"youtube\"\n  video_id: \"6_bqotkr3dk\"\n\n# Track 1\n- id: \"john-lin-rubyconf-taiwan-2023\"\n  title: \"Unearth Ruby builtin Gems\"\n  raw_title: \"RubyConf Taiwan 2023-Unearth Ruby builtin Gems by John Lin (CHT)\"\n  speakers:\n    - John Lin\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-26\"\n  language: \"Chinese\"\n  description: |-\n    #rubyconftw 2023\n\n    發掘 Ruby 的內建 Gems / Unearth Ruby builtin Gems\n\n    你曾經在不用外部 Gems 的情況下使用 Ruby 嗎？\n\n    Ruby 其實內建了很多非常實用的 Gems。不需要做任何的額外安裝就可以直接使用。 這些Gems 包括方便的資料結構與演算法，跨平台的檔案處理，實用的簡易伺服器等等。讓我們一起來發掘各種鮮為人知的內建 Gems。\n\n    How many times did you run ruby without external Gems?\n\n    Ruby includes many Gems by default. We can use them without extra installation steps. These Gems includes convenient data structure and algorithms, cross platform file handling and practical simple server, etc. Let's unearth the less known builtin Gems.\n  video_provider: \"youtube\"\n  video_id: \"WVS_cxn2HuY\"\n\n# Track 2\n- id: \"okura-masafumi-rubyconf-taiwan-2023\"\n  title: \"Writing Minitest clone in 30 minutes\"\n  raw_title: \"RubyConf Taiwan 2023-Writing Minitest clone in 30 minutes by OKURA Masafumi\"\n  speakers:\n    - OKURA Masafumi\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-26\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Writing Minitest clone in 30 minutes\n\n    Minitest is a testing library for Ruby that's bundled with CRuby. Unlike RSpec, it takes more straightforward approach. Class, method and assertion are all we need to write tests in Minitest. However, there are still some magical things going on here. What do assertions actually do? How does autorun feature work? In this talk, we'll write code together. More specifically, we'll write simpler clone of Minitest and make it work.\n  video_provider: \"youtube\"\n  video_id: \"4pF5SP1dDq4\"\n\n# Track 1\n- id: \"cindy-liu-rubyconf-taiwan-2023\"\n  title: \"Ever Been Punched by a Colleague?\"\n  raw_title: \"RubyConf Taiwan 2023-Ever Been Punched by a Colleague? by Cindy Liu\"\n  speakers:\n    - Cindy Liu\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-22\"\n  language: \"Chinese\"\n  description: |-\n    #rubyconftw 2023\n\n    你有被同事打過嗎？ / Ever Been Punched by a Colleague?\n\n    Race condition 是在 Ruby on Rails 應用程式中可能出現的問題之一，尤其涉及多執行緒的情況。這次演講提供了 race condition 的基本概念，以及如何在 Rails 中測試和解決這些問題的方法。測試 race condition 的方法至關重要，可以通過模擬並發情境來確保穩定性。\n\n    \"Race condition\" is a potential issue in Ruby on Rails applications, especially in situations involving multiple threads. This presentation provides a basic understanding of race conditions and how to test and resolve them in Rails. Testing for race conditions is crucial and can be achieved by simulating concurrent scenarios to ensure stability.\n  video_provider: \"youtube\"\n  video_id: \"Vgud5hkMmJ4\"\n\n# Track 2\n- id: \"ted-johansson-rubyconf-taiwan-2023\"\n  title: \"The Forgotten Web\"\n  raw_title: \"RubyConf Taiwan 2023-The Forgotten Web by Ted Johansson\"\n  speakers:\n    - Ted Johansson\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-26\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    The Forgotten Web\n\n    Is Rails still a good choice in 2023? For a new project at work? For a side hustle? How about for someone just looking to get into web development? How does it stack up against \"modern\" frameworks?\n\n    In this presentation we explore the ancient history of web development, discuss the perils of \"the modern web application\", highlight a brewing generational conflict, and examine how Rails' connection to the past puts it in a unique position to project itself into the future.\n  video_provider: \"youtube\"\n  video_id: \"CF1DcKV-U0o\"\n\n# Track 1\n- id: \"wen-tien-chang-rubyconf-taiwan-2023\"\n  title: \"A Brief Introduction to Generative AI Engineer: A Guide for Rubyists\"\n  raw_title: \"RubyConf Taiwan 2023-A Brief Introduction to Generative AI Engineer: A Guide for Rubyists by ihower\"\n  speakers:\n    - Wen-Tien Chang\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-22\"\n  language: \"Chinese\"\n  description: |-\n    #rubyconftw 2023\n\n    淺談 Generative AI Engineer: 給 Rubyist 的上手指南 / A Brief Introduction to Generative AI Engineer: A Guide for Rubyists\n\n    在這場分享中，我們將新定義 Generative AI Engineer (生成式 AI 工程師) 這一新興職位。除了 LLM 模型本身之外，要真正開發 AI 應用，我們還需要面對許多的挑戰和工作。隨著開發 AI 應用的門檻逐漸降低，許多原先沒有 AI 背景的應用軟體工程師，現在也能透過呼叫 LLM API 轉型成為 AI 工程師，不再需要從零開始學習訓練機器學習模型，而是專注在 Prompt Engineering (提示工程) 和開發各種 AI 應用，如 Chatbot、Retrieval Augmented Generation(RAG)、Vector Search、Agents 和 OpenAI Function Calling 等。歡迎一起探索這個新時代的 AI 工程師角色。\n\n    In this talk, we redefine the emerging role of Generative AI Engineer. Beyond just the LLM itself, developing AI applications presents many challenges and tasks. Now software developers can build AI apps by using LLM APIs and don’t have to start learning machine learning from the beginning. We can focus on Prompt Engineering, Retrieval Augmented Generation(RAG), Vector Search, Agents, and OpenAI Function Calling. Join us in exploring the role of AI engineers in this new era.\n  video_provider: \"youtube\"\n  video_id: \"a2-h2nJqWHA\"\n\n# Track 2\n- id: \"hiu-nguyn-rubyconf-taiwan-2023\"\n  title: \"Solving Real-World Challenges with Ruby Ractor\"\n  raw_title: \"RubyConf Taiwan 2023-Solving Real-World Challenges with Ruby Ractor by Hiếu Nguyễn\"\n  speakers:\n    - Hiếu Nguyễn\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-26\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    Solving Real-World Challenges with Ruby Ractor\n\n    In this talk, we explore on how we can take advantage of Ractor to improve parallel processing in some real world scenarios, such as data encryption and transaction processing. We delve into some features of Ractor, with their strength and limitation, and how to migrate thread-based or process-based functionalities using them. This talk hopefully will give the audience more insights on how they can improve their application performance.\n  video_provider: \"youtube\"\n  video_id: \"Zrck3-lx_Mo\"\n\n# Track 1\n# Missing Talk: Ruby on the Modern JVM with JRuby - Charles Oliver Nutter\n\n# Track 2\n- id: \"stephen-margheim-rubyconf-taiwan-2023\"\n  title: \"How (and why) to run SQLite in production\"\n  raw_title: \"RubyConf Taiwan 2023-How (and why) to run SQLite in production by Stephen Margheim\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-22\"\n  slides_url: \"https://speakerdeck.com/fractaledmind/how-and-why-to-run-sqlite-in-production\"\n  language: \"English\"\n  description: |-\n    #rubyconftw 2023\n\n    How (and why) to run SQLite in production\n\n    You've heard the whispers, sensed the hype, but you're still not sure what all the fuss is about with SQLite these days. Join me as we explore the use-cases and benefits of running SQLite in a production environment. Along the way, we will learn why SQLite makes sense as your next production database and how to ensure that your setup is optimized for end-user performance and developer happiness. We will setup and deploy a full Rails application—with caching, background jobs, websockets, and full-text search all backed by SQLite—in these 40 minutes. Come along for the ride!\n  video_provider: \"youtube\"\n  video_id: \"uT6TUfopY6E\"\n\n# Track 1\n- id: \"tim-riley-rubyconf-taiwan-2023\"\n  title: \"Keynote: Quest of the Rubyist by Tim Riley\"\n  raw_title: \"RubyConf Taiwan 2023-Keynote-Quest of the Rubyist by  Tim Riley\"\n  speakers:\n    - Tim Riley\n  event_name: \"RubyConf Taiwan 2023\"\n  date: \"2023-12-16\"\n  published_at: \"2024-03-22\"\n  language: \"English\"\n  description: |-\n    Official Website：http://2023.rubyconf.tw\n\n    Quest of the Rubyist\n\n    What do curiosity, cooperation and cognisance mean for the budding Rubyist? And can these virtues help us follow the path of programmer happiness?\n\n    As we enter a land where both peril and opportunity abound, how can we plot a course towards towards the Ruby of our future? Let’s find out together, as we embark on the adventure of our time!\n  video_provider: \"youtube\"\n  video_id: \"nMmwFzP8brI\"\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2025/cfp.yml",
    "content": "---\n- link: \"https://pretalx.coscup.org/coscup-2025/cfp\"\n  open_date: \"2025-04-07\"\n  close_date: \"2025-05-10\"\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2025/event.yml",
    "content": "---\nid: \"rubyconf-taiwan-x-coscup-2025\"\ntitle: \"RubyConf Taiwan x COSCUP 2025\"\ndescription: \"\"\nlocation: \"Taipei, Taiwan\"\nkind: \"conference\"\nstart_date: \"2025-08-09\"\nend_date: \"2025-08-10\"\nwebsite: \"https://2025.rubyconf.tw\"\ntwitter: \"rubyconftw\"\nbanner_background: \"#E5EAEE\"\nfeatured_background: \"#E5EAEE\"\nfeatured_color: \"#00A991\"\ncoordinates:\n  latitude: 25.0329636\n  longitude: 121.5654268\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Speaker Supporters\"\n      description: |-\n        Sponsors who support the speakers at the event.\n      level: 1\n      sponsors:\n        - name: \"Sparkle\"\n          badge: \"\"\n          website: \"https://www.sparkle.health/\"\n          slug: \"sparkle\"\n          logo_url: \"https://2025.rubyconf.tw/assets/images/logo-sparkle.svg\"\n\n        - name: \"Evil Martians\"\n          badge: \"\"\n          website: \"https://evilmartians.com\"\n          slug: \"evil-martians\"\n          logo_url: \"https://2025.rubyconf.tw/assets/images/evilmartians.svg\"\n\n        - name: \"Ruby Central\"\n          badge: \"\"\n          website: \"https://rubycentral.org/\"\n          slug: \"ruby-central\"\n          logo_url: \"https://2025.rubyconf.tw/assets/images/RubyCentral-logo.png\"\n\n    - name: \"Special Thanks\"\n      description: |-\n        Special thanks sponsors contributing to the event.\n      level: 2\n      sponsors:\n        - name: \"Ruby City MATSUE\"\n          badge: \"\"\n          website: \"https://www.city.matsue.lg.jp/sangyo_business/sangyoshinko/RubyCityMATSUE/index.html\"\n          slug: \"rubycitymatsue\"\n          logo_url: \"https://2025.rubyconf.tw/assets/images/matsue.png\"\n\n        - name: \"Piccollage\"\n          badge: \"\"\n          website: \"https://piccollage.com\"\n          slug: \"piccollage\"\n          logo_url: \"https://2025.rubyconf.tw/assets/images/piccollage.png\"\n"
  },
  {
    "path": "data/rubyconf-taiwan/rubyconf-taiwan-2025/videos.yml",
    "content": "# Website: https://2025.rubyconf.tw\n# Videos: TBD (conference is August 9-10, 2025)\n---\n# Day 1 - August 9, 2025\n\n# Opening Ceremony\n- id: \"akihito-uesada-rubyconf-taiwan-2025\"\n  title: \"Opening Ceremony: Shaping Dreams with Digital Power— MATSUE City\"\n  raw_title: \"RubyConf Taiwan 2025 - Shaping Dreams with Digital Power— MATSUE City by Akihito Uesada\"\n  speakers:\n    - Akihito Uesada\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    Opening ceremony presentation introducing the opensource history & culture of RubyCity MATSUE.\n  video_provider: \"scheduled\"\n  video_id: \"akihito-uesada-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx4C13CbsAIehIp?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx4C13CbsAIehIp?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx4C13CbsAIehIp?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx4C13CbsAIehIp?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx4C13CbsAIehIp?format=jpg&name=large\"\n\n# Keynote\n- id: \"yukihiro-matsumoto-rubyconf-taiwan-2025\"\n  title: \"Keynote: Programming Language for AI age\"\n  raw_title: \"RubyConf Taiwan 2025 - Programming Language for AI age by MATSUMOTO Yukihiro (Matz)\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    What is the best language for AI age? (You can guess from the name of the presenter). What is characteristics of programming language for AI age?\n  video_provider: \"scheduled\"\n  video_id: \"yukihiro-matsumoto-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx4DUReagAA-Ioa?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx4DUReagAA-Ioa?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx4DUReagAA-Ioa?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx4DUReagAA-Ioa?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx4DUReagAA-Ioa?format=jpg&name=large\"\n\n# Track Sessions\n- title: \"Funding Ruby Infrastructure as a Non-Profit\"\n  raw_title: \"RubyConf Taiwan 2025 - Funding Ruby Infrastructure as a Non-Profit by Samuel Giddins\"\n  speakers:\n    - Samuel Giddins\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  published_at: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    Over the past half decade, software supply chains have become an increasing focus for governments and large companies. This has created an interesting dynamic, as Ruby infrastructure (our package manager, package repository, etc.) used to be developed by volunteers. This is the story of how Ruby Central has adapted to the changing times, and has managed to fund work (including a full-time employee!) on our infrastructure. Along with the story of Ruby Central’s evolution, we’ll cover the current landscape surrounding funding and governance of infrastructural open source projects, and hopefully come away feeling hopeful about the future of critical open source.\n  video_provider: \"youtube\"\n  video_id: \"V8O1CbGpDfI\"\n  id: \"samuel-giddins-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx4Ky3VaIAAFD1f?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx4Ky3VaIAAFD1f?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx4Ky3VaIAAFD1f?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx4Ky3VaIAAFD1f?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx4Ky3VaIAAFD1f?format=jpg&name=large\"\n  slides_url: \"https://speakerdeck.com/segiddins/funding-ruby-infrastructure-as-a-non-profit\"\n\n- id: \"sampo-kuokkanen-rubyconf-taiwan-2025\"\n  title: \"What is happening with strings in Ruby and why is it feeling chilly? 🥶\"\n  raw_title: \"RubyConf Taiwan 2025 - What is happening with strings in Ruby and why is it feeling chilly? by Sampo Kuokkanen\"\n  speakers:\n    - Sampo Kuokkanen\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    Deep dive into Ruby strings, exploring changes in string handling, frozen strings, and Ruby's string implementation.\n  video_provider: \"scheduled\"\n  video_id: \"sampo-kuokkanen-rubyconf-taiwan-2025\"\n\n- id: \"hitoshi-hasumi-rubyconf-taiwan-2025\"\n  title: \"Well, PicoRuby Can Do That\"\n  raw_title: \"RubyConf Taiwan 2025 - Well, PicoRuby Can Do That by Hitoshi HASUMI\"\n  speakers:\n    - HASUMI Hitoshi\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    Exploring PicoRuby as a new way to experience Ruby, focusing on creativity and IoT platforms.\n  video_provider: \"scheduled\"\n  video_id: \"hitoshi-hasumi-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx4RJoFbsAMmxh0?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx4RJoFbsAMmxh0?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx4RJoFbsAMmxh0?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx4RJoFbsAMmxh0?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx4RJoFbsAMmxh0?format=jpg&name=large\"\n\n- id: \"cristian-planas-rubyconf-taiwan-2025\"\n  title: \"Rails Scales! - Why startups fail and how you can succeed\"\n  raw_title: \"RubyConf Taiwan 2025 - Rails Scales! - Why startups fail and how you can succeed by Cristian Planas\"\n  speakers:\n    - Cristian Planas\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    Discussing Rails scalability, performance challenges, and solutions from companies like Shopify and Zendesk.\n  video_provider: \"scheduled\"\n  video_id: \"cristian-planas-rubyconf-taiwan-2025\"\n\n- id: \"ryo-kajiwara-rubyconf-taiwan-2025\"\n  title: \"End-to-End Encryption Saves Lives. You Can Start Saving Lives In Ruby, Too\"\n  raw_title: \"RubyConf Taiwan 2025 - End-to-End Encryption Saves Lives. You Can Start Saving Lives In Ruby, Too by Ryo Kajiwara\"\n  speakers:\n    - Ryo Kajiwara\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    Covers Ruby implementation of Messaging Layer Security Protocol (RFC 9420), focusing on end-to-end encryption in group messaging systems.\n  video_provider: \"scheduled\"\n  video_id: \"ryo-kajiwara-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx4xWq0bsAEGRH5?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx4xWq0bsAEGRH5?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx4xWq0bsAEGRH5?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx4xWq0bsAEGRH5?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx4xWq0bsAEGRH5?format=jpg&name=large\"\n  slides_url: \"https://speakerdeck.com/sylph01/end-to-end-encryption-saves-lives-you-can-start-saving-lives-with-ruby-too-rubyconf-taiwan-2025-ver-dot\"\n\n- id: \"kazuaki-tanaka-rubyconf-taiwan-2025\"\n  title: \"From Scripts to Circuits: IoT Applications with mruby/c\"\n  raw_title: \"RubyConf Taiwan 2025 - From Scripts to Circuits: IoT Applications with mruby/c by Kazuaki TANAKA\"\n  speakers:\n    - Kazuaki Tanaka\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    Explores mruby/c, a lightweight Ruby implementation for IoT devices with minimal memory consumption and concurrent execution capabilities.\n  video_provider: \"scheduled\"\n  video_id: \"kazuaki-tanaka-rubyconf-taiwan-2025\"\n\n- id: \"hayao-kimura-rubyconf-taiwan-2025\"\n  title: \"RISC-V CPU emulator made with Ruby\"\n  raw_title: \"RubyConf Taiwan 2025 - RISC-V CPU emulator made with Ruby by Hayao Kimura\"\n  speakers:\n    - Hayao Kimura\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    Building a RISC-V CPU emulator in Ruby, explaining CPU core cycle and binary analysis.\n  video_provider: \"scheduled\"\n  video_id: \"hayao-kimura-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx5DplWboAA7Vrt?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx5DplWboAA7Vrt?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx5DplWboAA7Vrt?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx5DplWboAA7Vrt?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx5DplWboAA7Vrt?format=jpg&name=large\"\n  slides_url: \"https://speakerdeck.com/hayaokimura/risc-v-cpu-emulator-made-with-ruby-fcc3d4d1-b418-491c-b0c2-123302ea0f53\"\n\n- id: \"yuichiro-kaneko-rubyconf-taiwan-2025\"\n  title: \"Understanding Ruby Grammar Through Conflicts\"\n  raw_title: \"RubyConf Taiwan 2025 - Understanding Ruby Grammar Through Conflicts by Yuichiro Kaneko\"\n  speakers:\n    - Yuichiro Kaneko\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    Exploring Ruby's grammar structure by introducing syntax changes and analyzing parser conflicts.\n  video_provider: \"scheduled\"\n  video_id: \"yuichiro-kaneko-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx5IJtsbsAMLMNS?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx5IJtsbsAMLMNS?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx5IJtsbsAMLMNS?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx5IJtsbsAMLMNS?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx5IJtsbsAMLMNS?format=jpg&name=large\"\n  slides_url: \"https://speakerdeck.com/yui_knk/understanding-ruby-grammar-through-conflicts\"\n\n- id: \"masafumi-okura-rubyconf-taiwan-2025\"\n  title: \"Why doesn't Ruby have Boolean class?\"\n  raw_title: \"RubyConf Taiwan 2025 - Why doesn't Ruby have Boolean class? by OKURA Masafumi\"\n  speakers:\n    - OKURA Masafumi\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-09\"\n  language: \"en\"\n  description: |-\n    Explores Ruby's object-oriented design, questioning why Ruby lacks a Boolean class and delving into language design principles.\n  video_provider: \"scheduled\"\n  video_id: \"masafumi-okura-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx5QvjDboAAvYBY?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx5QvjDboAAvYBY?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx5QvjDboAAvYBY?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx5QvjDboAAvYBY?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx5QvjDboAAvYBY?format=jpg&name=large\"\n  slides_url: \"https://speakerdeck.com/okuramasafumi/why-doesnt-ruby-have-boolean-class-9854c791-e4f4-4ae0-80c8-59d43e72a003\"\n\n# Day 2 - August 10, 2025\n\n- id: \"etrex-kuo-rubyconf-taiwan-2025\"\n  title: \"用 Ruby 寫一個 MCP Server\"\n  raw_title: \"RubyConf Taiwan 2025 - 用 Ruby 寫一個 MCP Server by Etrex Kuo\"\n  speakers:\n    - Etrex Kuo\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-10\"\n  language: \"zh\"\n  description: |-\n    Creating an MCP Server with Ruby. Shares experience implementing an MCP (Model Context Protocol) Server from scratch, covering protocol structure, implementation, testing, and security.\n\n    Repo: https://github.com/etrex/mcp_server_demo\n  video_provider: \"scheduled\"\n  video_id: \"etrex-kuo-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx9LA7zbsAASbo7?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx9LA7zbsAASbo7?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx9LA7zbsAASbo7?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx9LA7zbsAASbo7?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx9LA7zbsAASbo7?format=jpg&name=large\"\n  additional_resources:\n    - name: \"etrex/mcp_server_demo\"\n      type: \"repo\"\n      url: \"https://github.com/etrex/mcp_server_demo\"\n\n- id: \"samuel-williams-rubyconf-taiwan-2025\"\n  title: \"Building, Deploying, and Monitoring Ruby Web Applications with Falcon\"\n  raw_title: \"RubyConf Taiwan 2025 - Building, Deploying, and Monitoring Ruby Web Applications with Falcon by Samuel Williams\"\n  speakers:\n    - Samuel Williams\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-10\"\n  language: \"en\"\n  description: |-\n    Demonstrates building concurrent Ruby web applications using Falcon and Async, covering development, deployment, and monitoring strategies.\n  video_provider: \"scheduled\"\n  video_id: \"samuel-williams-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx9WFJfaoAAb941?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx9WFJfaoAAb941?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx9WFJfaoAAb941?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx9WFJfaoAAb941?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx9WFJfaoAAb941?format=jpg&name=large\"\n\n- id: \"aleksandr-kunin-rubyconf-taiwan-2025\"\n  title: \"Loosing Seat in Concurrency: A tale of Transactions and Locks\"\n  raw_title: \"RubyConf Taiwan 2025 - Loosing Seat in Concurrency: A tale of Transactions and Locks by Aleksandr Kunin\"\n  speakers:\n    - Aleksandr Kunin\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-10\"\n  language: \"en\"\n  description: |-\n    Explores database concurrency problems, transaction isolation, and locking patterns using a seat booking scenario.\n  video_provider: \"scheduled\"\n  video_id: \"aleksandr-kunin-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx9gz2yboAA8GSv?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx9gz2yboAA8GSv?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx9gz2yboAA8GSv?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx9gz2yboAA8GSv?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx9gz2yboAA8GSv?format=jpg&name=large\"\n\n- id: \"yudai-takada-rubyconf-taiwan-2025\"\n  title: \"Joy with 3D Graphics Using Ruby\"\n  raw_title: \"RubyConf Taiwan 2025 - Joy with 3D Graphics Using Ruby by Yudai Takada\"\n  speakers:\n    - Yudai Takada\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-10\"\n  language: \"en\"\n  description: |-\n    Introduction to 3D graphics creation using Ruby, covering basics of 3D rendering, practical examples, and step-by-step implementation for creating spinning 3D objects.\n\n    Repo: https://github.com/ydah/rubyconftw_opengl_demo\n  video_provider: \"scheduled\"\n  video_id: \"yudai-takada-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx97I4pacAA5ACt?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx97I4pacAA5ACt?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx97I4pacAA5ACt?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx97I4pacAA5ACt?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx97I4pacAA5ACt?format=jpg&name=large\"\n  slides_url: \"https://speakerdeck.com/ydah/joy-with-3d-graphics-using-ruby\"\n  additional_resources:\n    - name: \"ydah/rubyconftw_opengl_demo\"\n      type: \"repo\"\n      url: \"https://github.com/ydah/rubyconftw_opengl_demo\"\n\n- id: \"cindy-liu-rubyconf-taiwan-2025\"\n  title: \"Rails Active Storage 如何避免被同事攻擊 — 你，懂 BAC 嗎？\"\n  raw_title: \"RubyConf Taiwan 2025 - Rails Active Storage 如何避免被同事攻擊 — 你，懂 BAC 嗎？ by Cindy Liu\"\n  speakers:\n    - Cindy Liu\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-10\"\n  language: \"zh\"\n  description: |-\n    Rails Active Storage security considerations and best practices for avoiding common vulnerabilities.\n  video_provider: \"scheduled\"\n  video_id: \"cindy-liu-rubyconf-taiwan-2025\"\n\n- id: \"andrey-novikov-rubyconf-taiwan-2025\"\n  title: \"Nuances of running Ruby on Kubernetes\"\n  raw_title: \"RubyConf Taiwan 2025 - Nuances of running Ruby on Kubernetes by Andrey Novikov\"\n  speakers:\n    - Andrey Novikov\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-10\"\n  language: \"en\"\n  description: |-\n    Exploring the challenges and solutions for deploying and running Ruby applications on Kubernetes infrastructure.\n  video_provider: \"scheduled\"\n  video_id: \"andrey-novikov-rubyconf-taiwan-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/Gx-LxVSbcAADFev?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/Gx-LxVSbcAADFev?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/Gx-LxVSbcAADFev?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/Gx-LxVSbcAADFev?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/Gx-LxVSbcAADFev?format=jpg&name=large\"\n  slides_url: \"https://speakerdeck.com/envek/nuances-on-kubernetes-rubyconf-taiwan-2025\"\n\n- id: \"aotoki-tsuruya-rubyconf-taiwan-2025\"\n  title: \"Crafting AI-Friendly Application in Ruby\"\n  raw_title: \"RubyConf Taiwan 2025 - Crafting AI-Friendly Application in Ruby by 蒼時弦也 / Aotoki Tsuruya\"\n  speakers:\n    - Aotoki Tsuruya\n  event_name: \"RubyConf Taiwan 2025\"\n  date: \"2025-08-10\"\n  language: \"zh\"\n  description: |-\n    Building Ruby applications that integrate seamlessly with AI systems and machine learning workflows.\n  video_provider: \"scheduled\"\n  video_id: \"aotoki-tsuruya-rubyconf-taiwan-2025\"\n  slides_url: \"https://talks.aotoki.me/2025-08-10-coscup\"\n"
  },
  {
    "path": "data/rubyconf-taiwan/series.yml",
    "content": "---\nname: \"RubyConf Taiwan\"\nwebsite: \"https://rubyconf.tw\"\ntwitter: \"rubyconftw\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"RubyConf\"\ndefault_country_code: \"TW\"\nyoutube_channel_name: \"RubyConfTW\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCqw_z59yI24SivuD573FECA\"\naliases:\n  - rubyconftw\n  - RubyConf TW\n  - Ruby Conf TW\n  - Ruby Conf Taiwan\n"
  },
  {
    "path": "data/rubyconf-uruguay/rubyconf-uruguay-2013/event.yml",
    "content": "---\nid: \"PLxx5qlTQCf0z2oFGlTDvLJTNMEKpgyopE\"\ntitle: \"RubyConf Uruguay 2013\"\nkind: \"conference\"\nlocation: \"Montevideo, Uruguay\"\ndescription: \"www.rubyconfuruguay.org\\r\n\n  Regional conference about Ruby, Rails and AgileMarch 22--23, 2013. Montevideo, Uruguay\"\npublished_at: \"2013-04-16\"\nstart_date: \"2013-03-22\"\nend_date: \"2013-03-23\"\nchannel_id: \"UCfUYtVgYsL-6C5_mGydDuvA\"\nyear: 2013\nbanner_background: \"#222222\"\nfeatured_background: \"#222222\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://web.archive.org/web/20130402191403/http://rubyconfuruguay.org/\"\ncoordinates:\n  latitude: -34.9055016\n  longitude: -56.1851147\n"
  },
  {
    "path": "data/rubyconf-uruguay/rubyconf-uruguay-2013/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20130402191403/http://rubyconfuruguay.org/\n# Schedule: https://web.archive.org/web/20130402191403/http://rubyconfuruguay.org/#agenda\n\n## Day 1 - 2013-03-22\n\n- id: \"jim-weirich-rubyconf-uruguay-2013\"\n  title: \"Keynote: Why aren't you using Ruby?\"\n  raw_title: \"Keynote: Jim Weirich - Why aren't you using Ruby? (RubyConf Uruguay 2013)\"\n  speakers:\n    - Jim Weirich\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-22\"\n  published_at: \"2013-05-24\"\n  description: |-\n    RubyConf Uruguay 2013 initial keynote by Jim Weirich.\n    http://rubyconfuruguay.org\n\n    Traducción al español:\n    http://www.youtube.com/watch?v=7C3CFo13tU8\n  video_provider: \"youtube\"\n  video_id: \"0D3KfnbTdWw\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"Keynote: Jim Weirich - Why aren't you using Ruby?\"\n      video_provider: \"youtube\"\n      video_id: \"7C3CFo13tU8\"\n      language: \"spanish\"\n      date: \"2013-03-22\"\n\n- id: \"thiago-pradi-rubyconf-uruguay-2013\"\n  title: \"PostgreSQL on Rails\"\n  raw_title: \"Thiago Pradi - PostgreSQL on Rails (RubyConf Uruguay 2013)\"\n  speakers:\n    - Thiago Pradi\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-22\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Thiago Pradi's talk at RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    Traducción al español:\n    http://www.youtube.com/watch?v=pMt3_ioOOY0\n  video_provider: \"youtube\"\n  video_id: \"P0sMBmw1Gfs\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"PostgreSQL on Rails\"\n      video_provider: \"youtube\"\n      video_id: \"pMt3_ioOOY0\"\n      language: \"spanish\"\n      date: \"2013-03-22\"\n\n- id: \"don-mullen-rubyconf-uruguay-2013\"\n  title: \"An Introduction to Datomic\"\n  raw_title: \"Don Mullen - An Introduction to Datomic (RubyConf Uruguay 2013)\"\n  speakers:\n    - Don Mullen\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-22\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Don Mullen's talk at RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    Traducción al español:\n    http://www.youtube.com/watch?v=oFNRpP0oYW8\n  video_provider: \"youtube\"\n  video_id: \"YSriFOsoP7g\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"An Introduction to Datomic\"\n      video_provider: \"youtube\"\n      video_id: \"oFNRpP0oYW8\"\n      language: \"spanish\"\n      date: \"2013-03-22\"\n\n- id: \"marcos-matos-rubyconf-uruguay-2013\"\n  title: \"Ruby Theater - Using the actor model to achieve concurrency\"\n  raw_title: \"Marcos Matos - Ruby Theater - Using the actor model to achieve concurrency (RubyConf Uruguay 2013)\"\n  speakers:\n    - Marcos Matos\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-22\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Marcos Mato's talk at RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    Traducción al español:\n    http://www.youtube.com/watch?v=aip6Ge6YVLw\n  video_provider: \"youtube\"\n  video_id: \"6tWqttfxjjY\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"Ruby Theater - Using the actor model to achieve concurrency\"\n      video_provider: \"youtube\"\n      video_id: \"aip6Ge6YVLw\"\n      language: \"spanish\"\n      date: \"2013-03-22\"\n\n- id: \"vernica-rebagliatte-rubyconf-uruguay-2013\"\n  title: \"An Intro to Backbone.js\"\n  raw_title: \"Verónica Rebagliatte - An intro to backbone.js (RubyConf Uruguay 2013)\"\n  speakers:\n    - Verónica Rebagliatte\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-22\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Charla de Verónica Rebagliatte en RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    English translation:\n    http://www.youtube.com/watch?v=YiWMP9S3uxQ\n  video_provider: \"youtube\"\n  video_id: \"YI9lTBUsyZI\"\n  language: \"spanish\"\n  alternative_recordings:\n    - title: \"An Intro to Backbone.js\"\n      video_provider: \"youtube\"\n      video_id: \"YI9lTBUsyZI\"\n      language: \"english\"\n      date: \"2013-03-22\"\n\n# Lunch\n\n- id: \"justine-arreche-rubyconf-uruguay-2013\"\n  title: \"I Am Designer and So Can You!\"\n  raw_title: \"Justine Arreche - I Am Designer and So Can You! (RubyConf Uruguay 2013)\"\n  speakers:\n    - Justine Arreche\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-22\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Justine Arreche's talk at RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    Traducción al español:\n    http://www.youtube.com/watch?v=yVwuxVsJt1g\n  video_provider: \"youtube\"\n  video_id: \"kk3o92RZbw0\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"I Am Designer and So Can You!\"\n      video_provider: \"youtube\"\n      video_id: \"yVwuxVsJt1g\"\n      language: \"spanish\"\n      date: \"2013-03-22\"\n\n- id: \"andreas-fast-rubyconf-uruguay-2013\"\n  title: \"Performance matters\"\n  raw_title: \"Andreas Fast - Performance matters (RubyConf Uruguay 2013)\"\n  speakers:\n    - Andreas Fast\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-22\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Charla de Andreas Fast en RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    English translation:\n    http://www.youtube.com/watch?v=CmvG_YXalFE\n  video_provider: \"youtube\"\n  video_id: \"2Birrga-bE8\"\n  language: \"spanish\"\n  alternative_recordings:\n    - title: \"Keynote: Andreas Fast - Why aren't you using Ruby?\"\n      video_provider: \"youtube\"\n      video_id: \"CmvG_YXalFE\"\n      language: \"english\"\n      date: \"2013-03-22\"\n\n# Break\n\n- id: \"luismi-cavalle-rubyconf-uruguay-2013\"\n  title: \"Sustainable productivity: Rails vs OOP\"\n  raw_title: \"Luismi Cavalle - Sustainable productivity: Rails vs OOP (RubyConf Uruguay 2013)\"\n  speakers:\n    - Luismi Cavalle\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-22\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Luismi Cavalle's talk at RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    Traducción al español:\n    http://www.youtube.com/watch?v=0yRkEluRtbY\n  video_provider: \"youtube\"\n  video_id: \"KWcuGUh5RmE\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"Sustainable productivity: Rails vs OOP\"\n      video_provider: \"youtube\"\n      video_id: \"0yRkEluRtbY\"\n      language: \"spanish\"\n      date: \"2013-03-22\"\n\n- id: \"bryan-helmkamp-rubyconf-uruguay-2013\"\n  title: \"Rails Application Security in Practice\"\n  raw_title: \"Bryan Helmkamp - Rails Application Security in Practice (RubyConf Uruguay 2013)\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-22\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Bryan Helmkamp's talk at RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    Traducción al español:\n    http://www.youtube.com/watch?v=vi1DL9cIKWQ\n  video_provider: \"youtube\"\n  video_id: \"Uuw9_k30c4M\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"Rails Application Security in Practice\"\n      video_provider: \"youtube\"\n      video_id: \"vi1DL9cIKWQ\"\n      language: \"spanish\"\n      date: \"2013-03-22\"\n\n- id: \"vicent-marti-rubyconf-uruguay-2013\"\n  title: \"Unicorns die with bullets made of glitter\"\n  raw_title: \"Vicent Marti - Unicorns die with bullets made of glitter (RubyConf Uruguay 2013)\"\n  speakers:\n    - Vicent Marti\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-22\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Charla de Vicent Marti en RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    English translation:\n    http://www.youtube.com/watch?v=VJ4wqh5sUac\n  video_provider: \"youtube\"\n  video_id: \"9E9qfD4_Rx0\"\n  language: \"spanish\"\n  alternative_recordings:\n    - title: \"Unicorns die with bullets made of glitter\"\n      video_provider: \"youtube\"\n      video_id: \"VJ4wqh5sUac\"\n      language: \"english\"\n      date: \"2013-03-22\"\n\n# End of day 1\n\n# Drink Up by Neo @ Osadia (Luis Alberto de Herrera 1172)\n\n## Day 2 - 2013-03-23\n\n# Registration\n\n- id: \"cristian-rasch-rubyconf-uruguay-2013\"\n  title: \"Despliegue de aplicaciones Rack sobre la JVM\"\n  raw_title: \"Cristian Rasch - Despliegue de aplicaciones Rack sobre la JVM (RubyConf Uruguay 2013)\"\n  speakers:\n    - Cristian Rasch\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Charla de Cristian Rasch en RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    English translation:\n    http://www.youtube.com/watch?v=mR78n1dLIO0\n  video_provider: \"youtube\"\n  video_id: \"IsSOD9YE6p8\"\n  language: \"spanish\"\n  alternative_recordings:\n    - title: \"Despliegue de aplicaciones Rack sobre la JVM\"\n      video_provider: \"youtube\"\n      video_id: \"mR78n1dLIO0\"\n      language: \"english\"\n      date: \"2013-03-23\"\n\n- id: \"mximo-mussini-rubyconf-uruguay-2013\"\n  title: \"The Mobile's Developer Dilemma\"\n  raw_title: \"Máximo Mussini / Martín Barreto - The Mobile's Developer Dilemma (RubyConf Uruguay 2013)\"\n  speakers:\n    - Máximo Mussini\n    - Martín Barreto\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Charla de Máximo Mussino y Martín Barreto en RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    English translation:\n    http://www.youtube.com/watch?v=CGB6XMLm6wk\n  video_provider: \"youtube\"\n  video_id: \"5vAEAPOc6L8\"\n  language: \"spanish\"\n  alternative_recordings:\n    - title: \"The Mobile's Developer Dilemma\"\n      video_provider: \"youtube\"\n      video_id: \"CGB6XMLm6wk\"\n      language: \"english\"\n      date: \"2013-03-23\"\n\n- id: \"schalk-neethling-rubyconf-uruguay-2013\"\n  title: \"Writing, Debugging And Testing Apps for FirefoxOS\"\n  raw_title: \"Schalk Neethling - Writing, Debugging And Testing Apps for FirefoxOS (RubyConf Uruguay 2013)\"\n  speakers:\n    - Schalk Neethling\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Schalk Neethling's talk at RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    Traducción al español:\n    http://www.youtube.com/watch?v=71jPgIEyM7A\n  video_provider: \"youtube\"\n  video_id: \"nkyf9Ow1SdE\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"Writing, Debugging And Testing Apps for FirefoxOS\"\n      video_provider: \"youtube\"\n      video_id: \"71jPgIEyM7A\"\n      language: \"spanish\"\n      date: \"2013-03-23\"\n\n# Break\n\n- id: \"patricio-mac-adden-rubyconf-uruguay-2013\"\n  title: \"New York, New York\"\n  raw_title: \"Patricio Mac Adden - New York, New York (RubyConf Uruguay 2013)\"\n  speakers:\n    - Patricio Mac Adden\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Charla de Patricio Mac Adden en RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    English translation:\n    http://www.youtube.com/watch?v=519QXlNgO88\n  video_provider: \"youtube\"\n  video_id: \"0yaGP5FHCDc\"\n  language: \"spanish\"\n  alternative_recordings:\n    - title: \"New York, New York\"\n      video_provider: \"youtube\"\n      video_id: \"519QXlNgO88\"\n      language: \"english\"\n      date: \"2013-03-23\"\n\n- id: \"rodolfo-pilas-rubyconf-uruguay-2013\"\n  title: \"Puppet para hacer el trabajo por ti en el Datacenter\"\n  raw_title: \"Rodolfo Pilas - Puppet para hacer el trabajo por ti en el Datacenter (RubyConf Uruguay 2013)\"\n  speakers:\n    - Rodolfo Pilas\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Charla de Rodolfo Pilas en RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    English translation:\n    http://www.youtube.com/watch?v=xF7fDDZZNq0\n  video_provider: \"youtube\"\n  video_id: \"0-M-2mOrIKU\"\n  language: \"spanish\"\n  alternative_recordings:\n    - title: \"Puppet para hacer el trabajo por ti en el Datacenter\"\n      video_provider: \"youtube\"\n      video_id: \"xF7fDDZZNq0\"\n      language: \"english\"\n      date: \"2013-03-23\"\n\n- id: \"michel-martens-rubyconf-uruguay-2013\"\n  title: \"A Ruby Toolbox\"\n  raw_title: \"Michel Martens - A Ruby Toolbox (RubyConf Uruguay 2013)\"\n  speakers:\n    - Michel Martens\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Charla de Michel Martens en RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    English translation:\n    http://www.youtube.com/watch?v=giwGKg8lHr8\n  video_provider: \"youtube\"\n  video_id: \"h_4nazdj9ok\"\n  language: \"spanish\"\n  alternative_recordings:\n    - title: \"A Ruby Toolbox\"\n      video_provider: \"youtube\"\n      video_id: \"giwGKg8lHr8\"\n      language: \"english\"\n      date: \"2013-03-23\"\n\n- id: \"todo-rubyconf-uruguay-2013\"\n  title: \"Lightning Talks (English)\"\n  raw_title: \"Lightning Talks - English (RubyConf Uruguay 2013) HD\"\n  speakers:\n    - TODO\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    RubyConf Uruguay 2013 Lightning talks in English.\n\n    Spanish videos:\n    http://www.youtube.com/watch?v=8QZuUKJYmCI\n  video_provider: \"youtube\"\n  video_id: \"bn5eft7ggmU\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"Lightning Talks (Spanish)\"\n      video_provider: \"youtube\"\n      video_id: \"8QZuUKJYmCI\"\n      language: \"spanish\"\n      date: \"2013-03-23\"\n\n- id: \"julie-ann-horvath-rubyconf-uruguay-2013\"\n  title: \"The Rubyist's Guide to Design\"\n  raw_title: \"Julie Ann Horvath - The Rubyist's Guide to Design (RubyConf Uruguay 2013)\"\n  speakers:\n    - Julie Ann Horvath\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Julie Ann Horvath's talk at RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    Traducción al español:\n    http://www.youtube.com/watch?v=kDN6hEEiHkk\n  video_provider: \"youtube\"\n  video_id: \"iRfoKdRgZdU\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"The Rubyist's Guide to Design\"\n      video_provider: \"youtube\"\n      video_id: \"kDN6hEEiHkk\"\n      language: \"spanish\"\n      date: \"2013-03-23\"\n\n- id: \"richard-schneeman-rubyconf-uruguay-2013\"\n  title: \"Dissecting Ruby with Ruby\"\n  raw_title: \"Richard Schneeman - Dissecting Ruby with Ruby (RubyConf Uruguay 2013)\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Richard Schneeman's talk at RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n\n    Traducción Español:\n    http://www.youtube.com/watch?v=d6IT92VCPLA\n  video_provider: \"youtube\"\n  video_id: \"iNZ9dneuhCQ\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"Dissecting Ruby with Ruby\"\n      video_provider: \"youtube\"\n      video_id: \"d6IT92VCPLA\"\n      language: \"spanish\"\n      date: \"2013-03-23\"\n\n# Break\n\n- id: \"cyril-david-rubyconf-uruguay-2013\"\n  title: \"Lean software development\"\n  raw_title: \"Cyril David - Lean software development (RubyConf Uruguay 2013)\"\n  speakers:\n    - Cyril David\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Cyril David's talk at RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    Traducción español:\n    http://www.youtube.com/watch?v=I6dwNefN07o\n  video_provider: \"youtube\"\n  video_id: \"uHgkhLF_mP4\"\n  language: \"english\"\n  alternative_recordings:\n    - title: \"Lean software development\"\n      video_provider: \"youtube\"\n      video_id: \"I6dwNefN07o\"\n      language: \"spanish\"\n      date: \"2013-03-23\"\n\n- title: \"Lean Leadership aka Don't be an Asshole\"\n  raw_title: \"Lean Leadership aka Don't be an Asshole\"\n  speakers:\n    - Peter Shanley\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-08\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"peter-shanley-rubyconf-uruguay-2013\"\n  id: \"peter-shanley-rubyconf-uruguay-2013\"\n\n- id: \"jano-gonzalez-rubyconf-uruguay-2013\"\n  title: \"Keynote: Jano Gonzalez - Cómo Ruby me programó a mí\"\n  raw_title: \"Keynote: Jano Gonzalez - Cómo Ruby me programó a mí (RubyConf Uruguay 2013)\"\n  speakers:\n    - Jano Gonzalez\n  event_name: \"RubyConf Uruguay 2013\"\n  date: \"2013-03-23\"\n  published_at: \"2013-05-24\"\n  description: |-\n    Keynote de Jano Gonzalez en RubyConf Uruguay 2013.\n    http://rubyconfuruguay.org\n\n    English translation:\n    http://youtu.be/yJwEt7v4bp8\n  video_provider: \"youtube\"\n  video_id: \"LNtmg-btc5E\"\n  language: \"spanish\"\n  alternative_recordings:\n    - title: \"Keynote: Jano Gonzalez - Cómo Ruby me programó a mí\"\n      video_provider: \"youtube\"\n      video_id: \"yJwEt7v4bp8\"\n      language: \"english\"\n      date: \"2013-03-23\"\n      published_at: \"2013-04-26\"\n# Goodbyes\n\n# Drink Up by GitHub @ Gallagher's Irish Pub\n"
  },
  {
    "path": "data/rubyconf-uruguay/rubyconf-uruguay-2014/event.yml",
    "content": "---\nid: \"PLxx5qlTQCf0zx-DIFVHlftznHExI7ONEV\"\ntitle: \"RubyConf Uruguay 2014\"\nkind: \"conference\"\nlocation: \"Montevideo, Uruguay\"\ndescription: |-\n  May 23-24, 2014, Montevideo, Uruguay\npublished_at: \"2014-11-15\"\nstart_date: \"2014-05-23\"\nend_date: \"2014-05-24\"\nchannel_id: \"UCfUYtVgYsL-6C5_mGydDuvA\"\nyear: 2014\nbanner_background: \"#D9D6CF\"\nfeatured_background: \"#D9D6CF\"\nfeatured_color: \"#303336\"\nwebsite: \"https://web.archive.org/web/20150105045157/http://www.rubyconfuruguay.org/en\"\ncoordinates:\n  latitude: -34.9055016\n  longitude: -56.1851147\n"
  },
  {
    "path": "data/rubyconf-uruguay/rubyconf-uruguay-2014/videos.yml",
    "content": "---\n# Website: https://web.archive.org/web/20150105045157/http://www.rubyconfuruguay.org/en\n# Schedule: https://web.archive.org/web/20150105045157/http://www.rubyconfuruguay.org/en\n\n## Day 1 - 2014-05-23\n\n# Registration & Breakfast\n\n- id: \"nicols-sanguinetti-rubyconf-uruguay-2014\"\n  title: \"Sé responsable\"\n  raw_title: \"Sé responsable - Foca\"\n  speakers:\n    - Nicolás Sanguinetti\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    Como desarrolladores tenemos la oportunidad de construir productos de la nada, lo que es increíble. La gente usa las cosas que construimos, y todo el mundo queda encantado.\n\n    Pero la mayor parte de nuestro trabajo está oculto a la vista. Tenemos una tendencia a sacar adelante los problemas con cosas que no se deberían hacer. Nos refugiamos bajo la bandera del \"bueno, ¡funciona!\" y seguimos adelante.\n\n    Eso está mal.\n\n    Como desarrolladores, somos responsables de nuestro trabajo. Somos responsables ante nuestros usuarios, nuestros jefes, nuestros compañeros, y sobre todo nosotros mismos.\n  video_provider: \"youtube\"\n  video_id: \"ppuNhkN1wUg\"\n  language: \"spanish\"\n\n- id: \"mike-abiezzi-rubyconf-uruguay-2014\"\n  title: \"Confidently building complex domains in Rails\"\n  raw_title: \"Confidently building complex domains in Rails - Mike AbiEzzi\"\n  speakers:\n    - Mike AbiEzzi\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    Rails models are simple. But your domain’s models might not be as simple as Rails would like them to be.\n\n    Modeling large, complex domains \"the Rails way” can cause some serious pain. Ruby and Rails are supposed to make developers happy. Let's not allow “the Rails way” and complex domains to take that away from us.\n\n    Join me as I’ll walk through a set of easy to implement Domain Driven Design (DDD) pointers. The goal is to make sure your model’s business logic stay under control no matter how complex your domain is or gets. Your application will be able to sustain steady growth and dramatically reduce business rule related defects, all the while, staying easy to grok.\n\n    I'll walk you through:\n\n    How communicating the domain properly will make an imprint on your codebase and product.\n    How creating boundaries around clusters of models will make your code easier to understand, manage, and interact with.\n    How immutable objects simplify domain gymnastics.\n    How data store access expresses the domain's intentions.\n    How to represent natural business transactions between models.\n  video_provider: \"youtube\"\n  video_id: \"taKijvrMQ6U\"\n  language: \"english\"\n\n- id: \"mariano-iglesias-rubyconf-uruguay-2014\"\n  title: \"Procesando pagos: lo estás haciendo mal\"\n  raw_title: \"Procesando pagos: lo estás haciendo mal - Mariano Iglesias\"\n  speakers:\n    - Mariano Iglesias\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    Esta charla no está atada a un lenguaje de programación, y no es solamente sobre la tecnología detrás del procesamiento de pagos, sino más especificamente sobre lo que hay que hacer y lo que no hay que hacer, experiencia obtenida luego de procesar millones de dólares en tu webapp.\n\n    Vamos a recorrer los diferentes procesadores de pagos (para pagos internacionales, y pagos en América Latina) y luego nos concentraremos en una serie de tips, como:\n\n    Técnicas para la subscripción automática de pagos (aka pagos periódicos.)\n    Debo / puedo guardar información de CC? Cómo?\n    Utilizando más de un gateway (y porqué deberías.)\n    Técnicas para resolver errores de usuario comunes.\n    Fraude: en el momento que empiezas a procesar pagos, miles de malos muchachos van a tratar de lastimarte. Creeme.\n    Prevención de fraude: técnicas, herramientas, y cómo prevenir (y lidiar) con el fraude.\n    Manteniendo una experiencia de pago amigable para tus clientes.\n  video_provider: \"youtube\"\n  video_id: \"v-R-BYb4Dpg\"\n  language: \"spanish\"\n\n# Lunch\n\n- id: \"chris-hunt-rubyconf-uruguay-2014\"\n  title: \"Secrets of a world memory champion\"\n  raw_title: \"Secrets of a world memory champion - Chris Hunt\"\n  speakers:\n    - Chris Hunt\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    You don't have a bad memory, you were just never taught how to use it. We are going to practice several powerful memory techniques that have been perfected by memory contest champions over the last hundred years. By the end of this talk, you will know how to quickly memorize a foreign language, driving directions, phone conversations, the entire Chuck Norris filmography, your friend's credit card number, a shuffled deck of playing cards, and the name of every person you meet at RubyConf Uruguay.\n  video_provider: \"youtube\"\n  video_id: \"YZJMz4Q6_Ks\"\n  language: \"english\"\n\n- id: \"noelia-cabane-rubyconf-uruguay-2014\"\n  title: \"Un día dije (╯°□°）╯︵ ┻━┻ y empecé a escribir sass como un programador\"\n  raw_title: \"Un día dije (╯°□°）╯︵ ┻━┻ y empecé a escribir sass como un programador - Noelia Cabane\"\n  speakers:\n    - Noelia Cabane\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    La intención de la charla es compartir la experiencia de cómo el uso y la experimentación con SASS nos enseñó a crear, escalar y mantener mejor nuestros CSSs. Exploraremos con ejemplos prácticos la tensión existente entre SASS orientado a objetos, performance del sitio y la velocidad de desarrollo y diseño esperada en una start-up. No se resume a hablar de qué se trata SASS, de lo que son los mixins y variables, si es mejor que LESS o qué framework es mejor, sino a mostrar como el uso de ciertas practicas nos ayudo a mejorar.\n  video_provider: \"youtube\"\n  video_id: \"i0P2v0PrZQ4\"\n  language: \"spanish\"\n\n- id: \"nicolas-barrera-rubyconf-uruguay-2014\"\n  title: \"Modularizando tu front-end\"\n  raw_title: \"Modularizando tu front-end - Nicolas Barrera\"\n  speakers:\n    - Nicolas Barrera\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    ¿Alguna vez te tuviste que enfrentar a una guerra de selectores? ¿Agregando una clase tras otra para modificar el comportamiento de un componente? Teniendo miedo de cambiar la estructura de un elemento, porque ni siquiera sabías de lo que podía llegar a pasar en otro lugar? Tal vez el front-end de tu aplicación se pueda mejorar!\n\n    Tratando a tu aplicación como un sistema de bloques intercambiables, definiendo un alcance inicial para los módulos básicos, y teniendo un entendimiento claro de la herencia y el contexto, se puede crear un sistema que es resistente, fácilmente modificable y adaptable a diferentes contextos.\n\n    En esta charla vamos a analizar el front-end independientemente de plataformas y/o lenguaje y vamos a ver cuáles son las técnicas y formas de pensar acerca de nuestro front-end pueden ayudarnos a construir un sistema de módulos en lugar de un conjunto de páginas sueltas.\n  video_provider: \"youtube\"\n  video_id: \"9k0VJ9GuCks\"\n  language: \"spanish\"\n\n# Break\n\n- id: \"sebastian-sogamoso-rubyconf-uruguay-2014\"\n  title: \"Programando sockets TCP con Ruby\"\n  raw_title: \"Programando sockets TCP con Ruby - Sebastian Sogamoso\"\n  speakers:\n    - Sebastian Sogamoso\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    Como desarrolladores Ruby, una gran parte de nuestro tiempo estamos construyendo aplicaciones que dependen de algún tipo de conexión de red. Debido a las grandes abstracciones de Ruby damos la mayoría de las cosas relacionadas con la red por sentado. Creemos que sabemos cómo todo funciona, pero lo hacemos? Vamos a repasar los fundamentos juntos, aprender sobre los modelos de Ruby, los sockets TCP y cómo podemos hacer un buen uso de ellos.\n\n    Incluso si no estás haciendo network programming, el ser capaz de bucear a través de múltiples niveles para comprender lo que está pasando te dará una gran ventaja. El tipo de conceptos vamos a repasar en esta charla no se aplican sólo a Ruby. Todos los idiomas modernos soportan el API de sockets de Berkeley y por tanto este conocimiento es portátil y te servirá durante muchos años.\n\n    La primera parte de la charla se trata de ir a través de los fundamentos de la programación con sockets. Esto incluye la creación de sockets, el cliente y el ciclo de vida del servidor, la lectura y la escritura de datos, el manejo de los sockets en Ruby y SSL. La última parte de la charla tiene que ver con la aplicación de estos conceptos a un problema del mundo real escribiendo un servidor web.\n  video_provider: \"youtube\"\n  video_id: \"ZugtotypRgw\"\n  language: \"spanish\"\n\n- id: \"adrin-mugnolo-rubyconf-uruguay-2014\"\n  title: \"Suficente Unix para ser peligroso\"\n  raw_title: \"Suficente Unix para ser peligroso - Adrián Mugnolo\"\n  speakers:\n    - Adrián Mugnolo\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    Aun cuando la mayor parte del desarrollo de Ruby y despliegue ocurre en sistemas tipo Unix, como OS X o Linux, la mayoría de Rubyistas nunca llegan a escribir código que se aprovecha de los conceptos que hicieron a Unix legendario. En esta charla, vamos a cubrir los procesos, señales, pipes y otras \"exóticas\" características de Unix disponibles desde Ruby, usando un enfoque de problema / solución. Para cada tema, vamos a presentar ejemplos de código de gemas populares junto con los casos de uso concreto. Con muchos desarrolladores de venir a Ruby desde PHP, Java o. Net, el entorno de programación Unix puede no ser el más familiar para ellos.\n\n    Desde un cita muy conocida en Unix, \"el poder de un sistema viene más de las relaciones entre los programas que de los propios programas.\" Desafortunadamente, las características de Ruby que proporcionan acceso a estas características de Unix, reciben sólo unas pocas páginas en las secciones de referencia. Estas son características de gran alcance, que merecen más atención!\n  video_provider: \"youtube\"\n  video_id: \"6bbnRRRk0f0\"\n  language: \"spanish\"\n\n- id: \"ernesto-tagwerker-rubyconf-uruguay-2014\"\n  title: \"No alimentes a los zombies!\"\n  raw_title: \"No alimentes a los zombies! - Ernesto Tagwerker\"\n  speakers:\n    - Ernesto Tagwerker\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    Los zombis están por todas partes! (Zombis = proyectos que están muertos por dentro, pero todavía funcionan.)\n\n    El mantenimiento no es cool. No es una palabra de moda como nodo, Lean, o Big Data, pero es más importante que todos ellos juntos, porque la deuda técnica pudre un proyecto desde el interior y lo mata.\n\n    Seguimos manteniendo proyectos de un parche a la vez, pero todos los odiamos. ¿Qué podemos hacer para matarlos una vez por todas? ¿Podemos salvarlos? Quizás. ¿Podemos dejar de construirlos? ¡Por supuesto!\n\n    Esta charla es sobre:\n\n    Cómo escribir los tests de una forma que nos permita mejorar la calidad del código.\n    Cómo desarrollar proyectos que sean fáciles de mantener en Rails, Sinatra y Cuba\n    Simplicidad\n    Buenas prácticas\n    Finalmente, habrá una introducción al \"Atomic Design\", como una manera de dejar de escribir espaguettis y CSS desordenado.\n\n    La mantenibilidad está infravalorada, pero representa más del 80% de la vida un proyecto promedio. La próxima vez que inicies un proyecto, utilizá esta guía para construir software más fácil de mantener.\n  video_provider: \"youtube\"\n  video_id: \"dpP8-EdRXew\"\n  language: \"spanish\"\n\n# Break\n\n- id: \"nicols-cerrini-rubyconf-uruguay-2014\"\n  title: \"¿Pastilla azul o pastilla roja? El camino de una mente sin jefes\"\n  raw_title: \"¿Pastilla azul o pastilla roja? El camino de una mente sin jefes - Nicolás Cerrini\"\n  speakers:\n    - Nicolás Cerrini\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    ¿No te sentías cómodo trabajando en una empresa? ¿Te molesta el horario fijo de 9 a 18?\n    ¿Querés tomar vos mismo todas las decisiones técnicas? ¿Te imaginás renunciando a todo y pasar a trabajar en pantuflas? ¡Podés dejar de ser empleado y trabajar por tu cuenta!... Pero ¡cuidado! Con que te guste programar, diseñar, escribir, o a lo que sea que te dediques... no alcanza. En el mundo del freelance a veces hace falta ponerse el sombrero de secretaria, ejecutivo de cuentas, cadete, y no sé cuántos más. No hay soluciones mágicas, pero vengo a contarte mi experiencia, y una serie de temas para que tengas en cuenta si te interesa seguir por este camino... Esta charla está dirigida a programadores, diseñadores, y otros profesionales, que estén interesados en probar suerte con su propio emprendimiento, brindando servicios a clientes en forma directa.\n  video_provider: \"youtube\"\n  video_id: \"9P5S9cko0Vs\"\n  language: \"spanish\"\n\n- id: \"santiago-pastorino-rubyconf-uruguay-2014\"\n  title: \"Del trabajo a la pasión\"\n  raw_title: \"Del trabajo a la pasión - Santiago Pastorino\"\n  speakers:\n    - Santiago Pastorino\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-23\"\n  published_at: \"2014-11-15\"\n  description: |-\n    La charla trata de como logré convertir mis pasiones profesionales en mi trabajo diario. La misma no pretende ser una receta de lo que hay que hacer, simplemente porque no hay receta :), es un humilde punto de vista para motivar a la gente que se sienta identificada de que es posible vivir de lo que a uno le gusta o de lo que a uno le apasiona. En la misma cuento cómo logre vivir de lo que me apasiona construyendo lentamente mi empresa de desarrollo de software WyeWorks y contribuyendo a Ruby on Rails. Enumero mis pasiones en la charla: alta calidad, alto impacto, desafíos y aprender. Y Defino el éxito en función de vivir de tus pasiones, explicando que se suele relacionar el éxito con los negocios y/o directamente con el dinero. Para mi eso es completamente secundario, que en la sociedad que vivimos es un vehículo para otras cosas pero no un fin. Las personas nos podemos sentir exitosas si logramos ser lo más felices posible. Les dejo los slides y un artículo que se escribió sobre la charla. https://speakerdeck.com/spastorino/del-trabajo-a-la-pasion http://rails.mx/blog/2013/06/10/magmaconf-2013-keynote-dia-2-santiago-pastorino\n  video_provider: \"youtube\"\n  video_id: \"dNjZnD8UexQ\"\n  language: \"spanish\"\n  slides_url: \"https://speakerdeck.com/spastorino/del-trabajo-a-la-pasion\"\n\n# After party sponsored by Citrusbyte\n\n## Day 2 - 2014-05-24\n\n# Registration & Breakfast\n\n- id: \"fernando-briano-rubyconf-uruguay-2014\"\n  title: \"Superhéroes y Programación\"\n  raw_title: \"Superhéroes y Programación - Fernando Briano\"\n  speakers:\n    - Fernando Briano\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-24\"\n  published_at: \"2014-11-15\"\n  description: |-\n    Super héroes: ¿Personajes de ficción? ¿Los seres mitológicos de nuestra era? ¿Qué los hace especiales? Los super héroes existen, y todos podemos ser un super programador.\n\n    Tenemos la habilidad de crear cosas y definir varios aspectos en los que las personas interactúan con su entorno. Las decisiones que tomamos pueden determinar ElMundoDelMañana™. Es nuestra responsabilidad dejar las cosas mejor que como las encontramos, y no se necesitan super poderes para lograrlo (¿o sí pero ya los tenemos?).\n\n    La charla es una serie limitada en pocos números que hace un paralelismo entre super héroes y desarrolladores, infectada por años de daño cerebral leyendo cómics, mirando películas y jugando videojuegos.\n  video_provider: \"youtube\"\n  video_id: \"QJ8vhi8DAV8\"\n  language: \"spanish\"\n\n- id: \"michele-guido-rubyconf-uruguay-2014\"\n  title: \"It takes a village to make a programmer\"\n  raw_title: \"It takes a village to make a programmer - Michele Guido\"\n  speakers:\n    - Michele Guido\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-24\"\n  published_at: \"2014-11-15\"\n  description: |-\n    I owe my successful one year transformation into a hirable web-developer to a whole network of people who may or may not have known how hugely they were impacting my life. I'll share with you the distinct ways people supported me on my journey of learning to program. You will come away inspired with ways to give back to other beginners or late-comers to the field. As Tal Ben-Shahar said, \"There's so much benefit to the person who contributes to others that I often think that there is no more selfish act than a generous act,\" so, why not come to this talk for your own good?\n  video_provider: \"youtube\"\n  video_id: \"eFGm-51hhwI\"\n  language: \"english\"\n\n- id: \"david-muto-rubyconf-uruguay-2014\"\n  title: \"What's best for our users? Let them decide!\"\n  raw_title: \"What's best for our users? Let them decide! - David Muto\"\n  speakers:\n    - David Muto\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-24\"\n  published_at: \"2014-11-15\"\n  description: |-\n    Making the right decision can be difficult and time consuming. Every feature comes with a cost so we need to be selective about what we deliver.\n\n    In this talk I'll discuss methods of A/B testing in Rails. I'll look at defining experiments and leveraging data to make better decisions. I’ll cover running several versions of a feature in production to see which one your users prefer. Finally, I'll discuss rolling out a risky schema change to measure the effects before releasing to everyone.\n  video_provider: \"youtube\"\n  video_id: \"HvMHZa6J__g\"\n  language: \"english\"\n\n# Lunch\n\n- id: \"evan-henshaw-plath-rubyconf-uruguay-2014\"\n  title: \"Neo's Sponsor Talk\"\n  raw_title: \"Neo's Sponsor Talk - Evan Henshaw-Plath\"\n  speakers:\n    - Evan Henshaw-Plath\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-24\"\n  published_at: \"2014-11-15\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jQUtthPbFbQ\"\n  language: \"english\"\n\n- id: \"ben-orenstein-rubyconf-uruguay-2014\"\n  title: \"You really should know a little bit of Clojure\"\n  raw_title: \"You really should know a little bit of Clojure - Ben Orenstein\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-24\"\n  published_at: \"2014-11-15\"\n  description: |-\n    For the past 15 years or so, I've been solving problems with object-oriented code, usually in Ruby. My projects have been mostly successful, but there have always been things that bothered me about object-oriented programming--a feeling that there had to be a better way to construct software.\n\n    Recently, I've been experimenting with a language that seems to have discovered that better way: Clojure.\n\n    Functional programming in general, and Clojure in particular seem to offer some tremendous benefits over the way I've always written code. Not only am I thrilled with the solutions I've been able to create, but the things I've learned have even improved my Ruby.\n\n    I've started to believe that all Rubyists should be exposed to at least a little bit of Clojure. This talk can be your first step.\n\n    Also, I'll show how some of these ideas can help you write better Ruby, even if you never touch a single line of Clojure.\n\n    Topics to cover include:\n\n    The power of immutable data (and how you can accomplish anything if your data never changes).\n    Why writing code that deals with time is always so painful.\n    What life is like when everything doesn't have to be a class.\n    Generative testing: a higher-level approach that's faster and more thorough than traditional unit tests.\n    A way out of JavaScript's \"callback hell\" (and I don't just mean futures or promises).\n    Homoiconicity: scary name, simple concept, immensely powerful results.\n  video_provider: \"youtube\"\n  video_id: \"c9TSQJPKs6A\"\n  language: \"english\"\n\n- id: \"netto-farah-rubyconf-uruguay-2014\"\n  title: \"Redis :heart: at 8tracks.com\"\n  raw_title: \"Redis :heart: at 8tracks.com - Netto Farah\"\n  speakers:\n    - Netto Farah\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-24\"\n  published_at: \"2014-11-15\"\n  description: |-\n    At 8tracks.com we believe on finding the best tool for the job.\n\n    In the quest of finding a great persistence solution to power our \"Explore\" system one of our engineers stumbled upon redis.io.\n\n    A few years later, we run 25 different Redis instances powering several features for our 10 million users.\n\n    From Tag Browsing, to Autocomplete Search, persisting Player sessions and our News Feed. Our 4 engineers team eats the redis documentation for breakfast.\n\n    Come join me in some redis love while I tell you why we're such big fans of zsets, set intersections and some other nice features that help us power 12.5 million hours of streaming per month.\n  video_provider: \"youtube\"\n  video_id: \"8BXPIwfSKgE\"\n  language: \"english\"\n\n- id: \"florian-gilcher-rubyconf-uruguay-2014\"\n  title: \"Ruby through the crystal ball\"\n  raw_title: \"Ruby through the crystal ball - Florian Gilcher\"\n  speakers:\n    - Florian Gilcher\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-24\"\n  published_at: \"2014-11-15\"\n  description: |-\n    Go, Scala, Node and whatnot - everyone wants a share of Rubys lunch. Are we seeing Rubys decline or just a new phase?\n\n    On RubyConf Argentina 2012, I postulated that in 5 years, no one will program Ruby like we did back then. I'd like to revisit that statement on the continent where I made it.\n  video_provider: \"youtube\"\n  video_id: \"T-jPWlzgQ_Y\"\n  language: \"english\"\n\n# Break\n\n# Lightning Talks\n\n- id: \"cristian-rasch-rubyconf-uruguay-2014\"\n  title: \"Rubystas: No teman a la concurrencia, adóptenla!\"\n  raw_title: \"Rubystas: No teman a la concurrencia, adóptenla! - Cristian Rasch\"\n  speakers:\n    - Cristian Rasch\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-24\"\n  published_at: \"2014-11-15\"\n  description: |-\n    No tiene sentido andarse por las ramas: la necesidad de aplicaciones concurrentes, muti-hilo esta en aumento y ha sido durante mucho tiempo. Si bien es cierto que un enfoque multi-proceso funciona 'bastante bien' para aplicaciones pequeñas, la realidad nos demostró una y otra vez que eso, es más bien un enfoque híbrido de la única manera de construir verdaderamente aplicaciones totalmente concurrentes y escalables , a medida que crecen se vuelve más complejo .\n\n    Por todo lo que nos ha dado Matz a los Rubyistas, ciertamente también instaló un temor fundamental en nosotros. El de la creación de aplicaciones de subprocesos múltiples , y que tenía sentido hasta cierto punto, en ese entonces. La verdad es que, no hace mucho tiempo, nos han faltado las estructuras de datos adecuadas y las primitivas de concurrencia que nos permiten hoy en día escribir aplicaciones de subprocesos múltiples escalables y de alto rendimiento.\n\n    Así, después de golpearme la cabeza contra la pared desde hace bastante tiempo, he llegado a aprovechar y disfrutar con algunas de las herramientas que quiero compartir con todos ustedes en esta charla. Esperemos que, al final de esta presentación , se le han metido manera más allá de su conocimiento básico de Mutex#synchronize como el único martillo con el que clavar todos sus problemas de concurrencia.\n  video_provider: \"youtube\"\n  video_id: \"c6KKRN5r5Og\"\n  language: \"spanish\"\n\n- id: \"najaf-ali-rubyconf-uruguay-2014\"\n  title: \"Better security for your Rails applications\"\n  raw_title: \"Better security for your Rails applications - Najaf Ali\"\n  speakers:\n    - Najaf Ali\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-24\"\n  published_at: \"2014-11-15\"\n  description: |-\n    Security is hard, and as developers we have very little time to focus on it. Short of hiring a professional security firm, what's a development team supposed to do to stay one step ahead of attackers? Or at the very least remove themselves from the lowest hanging fruit?\n\n    We'll be covering why you should care about security at all, common ways in which security mechanisms fail and good habits for you development team that will strengthen your software against attacks. The talk will be packed with war stories from real exploits and examples of non-trivial vulnerabilities of the sort that turn up in web application code.\n  video_provider: \"youtube\"\n  video_id: \"P0wFQxVr6Eg\"\n  language: \"english\"\n\n# Break\n\n- id: \"michel-martens-rubyconf-uruguay-2014\"\n  title: \"La contracultura minimalista\"\n  raw_title: \"La contracultura minimalista - Michel Martens\"\n  speakers:\n    - Michel Martens\n  event_name: \"RubyConf Uruguay 2014\"\n  date: \"2014-05-24\"\n  published_at: \"2014-11-15\"\n  description: |-\n    ¿Y si pudieras resolver un problema con una pequeña fracción del código que utilizás hoy? ¿Y si pudieras leer cada línea de código en todo el stack de tu aplicación en menos de un día? Se está formando una contracultura minimalista en la comunidad de Ruby, y sos bienvenido si querés formar parte de ella.\n\n    En esta presentación, voy a mostrar librerías y herramientas diseñadas con alta calidad y simplicidad en mente, y voy a tirar abajo algunos mitos que por lo general mantienen los desarrolladores encerrados en el mainstream.\n  video_provider: \"youtube\"\n  video_id: \"eim_5mt8boo\"\n  language: \"spanish\"\n# After party sponsored by Neo at Bulevar España 2529\n"
  },
  {
    "path": "data/rubyconf-uruguay/series.yml",
    "content": "---\nname: \"RubyConf Uruguay\"\nwebsite: \"http://web.archive.org/web/20150105045157/http://www.rubyconfuruguay.org:80/en\"\ntwitter: \"rubyconfuruguay\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconf-th-2020/event.yml",
    "content": "---\nid: \"rubyconf-th-2020\"\ntitle: \"RubyConf TH 2020 (Cancelled)\"\ndescription: \"\"\nlocation: \"Bangkok, Thailand\"\nkind: \"conference\"\nstart_date: \"2020-10-16\"\nend_date: \"2020-10-17\"\nwebsite: \"https://rubyconfth.com/\"\nstatus: \"cancelled\"\ntwitter: \"rubyconfth\"\ncoordinates:\n  latitude: 13.7563309\n  longitude: 100.5017651\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2019/event.yml",
    "content": "---\nid: \"PLM_LdV8tMIazzAKhtGxJvYCPCgP8HiB5k\"\ntitle: \"RubyConf TH 2019\"\nkind: \"conference\"\nlocation: \"Bangkok, Thailand\"\ndescription: |-\n  Enjoy all the talks from the very first Ruby conference in Bangkok held on Sept. 6-7 2019.\n\n  Speakers and talks details can be found on the website 👉https://rubyconfth.com/past/2019/\npublished_at: \"2019-09-06\"\nstart_date: \"2019-09-06\"\nend_date: \"2019-09-07\"\nchannel_id: \"UCwIhYV_sPTzvjk6B6EUnf1g\"\nyear: 2019\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://rubyconfth.com/past/2019\"\ncoordinates:\n  latitude: 13.7588878\n  longitude: 100.5373605\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2019/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n\n  users:\n    - Matt Mayer\n    - Dan Itsara\n    - Georgi Ker\n    - Michael Kohl\n    - Cody Fox\n    - Olivier Robert\n    - Alex Timofeev\n    - Keith Bennett\n\n  organisations:\n    - Bangkok.rb\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2019/schedule.yml",
    "content": "# Schedule: RubyConf TH 2019\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2019-09-06\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration & Conference Door Opens\n\n      - start_time: \"09:00\"\n        end_time: \"09:10\"\n        slots: 1\n        items:\n          - Welcome Address\n\n      - start_time: \"09:10\"\n        end_time: \"09:50\"\n        slots: 1\n\n      - start_time: \"09:50\"\n        end_time: \"10:20\"\n        slots: 1\n\n      - start_time: \"10:20\"\n        end_time: \"10:40\"\n        slots: 1\n        items:\n          - Tea Break\n\n      - start_time: \"10:40\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Buffet Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Sponsor Lightning Talk - Official Partner\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"15:50\"\n        slots: 1\n        items:\n          - Tea Break\n\n      - start_time: \"15:50\"\n        end_time: \"16:20\"\n        slots: 1\n\n      - start_time: \"16:20\"\n        end_time: \"16:50\"\n        slots: 1\n\n      - start_time: \"16:50\"\n        end_time: \"17:30\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"17:40\"\n        slots: 1\n        items:\n          - Closing Remarks/Announcements\n\n      - start_time: \"18:30\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - title: \"Official Party @ Bangkok Heritage\"\n            description: |-\n              Hosted at Bangkok Heritage, a short walk away from the venue.\n\n  - name: \"Day 2\"\n    date: \"2019-09-07\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration & Conference Door Opens\n\n      - start_time: \"09:00\"\n        end_time: \"09:10\"\n        slots: 1\n        items:\n          - Welcome Address\n\n      - start_time: \"09:10\"\n        end_time: \"09:50\"\n        slots: 1\n\n      - start_time: \"09:50\"\n        end_time: \"10:20\"\n        slots: 1\n\n      - start_time: \"10:20\"\n        end_time: \"10:40\"\n        slots: 1\n        items:\n          - Tea Break\n\n      - start_time: \"10:40\"\n        end_time: \"11:10\"\n        slots: 1\n\n      - start_time: \"11:10\"\n        end_time: \"11:40\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Buffet Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 1\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"15:50\"\n        slots: 1\n        items:\n          - Tea Break\n\n      - start_time: \"15:50\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"16:40\"\n        slots: 1\n        items:\n          - Closing Remarks/Announcements\n\ntracks:\n  - name: \"Main Track\"\n    color: \"#DC2626\"\n    text_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2019/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsor\"\n      level: 1\n      sponsors:\n        - name: \"Go-jek\"\n          website: \"https://www.gojek.io\"\n          slug: \"gojek\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-gojek.svg\"\n\n    - name: \"Platinum Sponsors\"\n      level: 2\n      sponsors:\n        - name: \"Nimble\"\n          website: \"https://nimblehq.co\"\n          slug: \"nimble\"\n          badge: \"Official Partner\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-nimble.svg\"\n        - name: \"Omise\"\n          website: \"https://www.omise.co\"\n          slug: \"omise\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-omise.svg\"\n\n    - name: \"Gold Sponsors\"\n      level: 3\n      sponsors:\n        - name: \"Gitlab\"\n          website: \"https://about.gitlab.com\"\n          slug: \"gitlab\"\n          badge: \"Swag Sponsor\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-gitlab.svg\"\n        - name: \"Matestack\"\n          website: \"https://www.matestack.org\"\n          slug: \"matestack\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-matestack.svg\"\n        - name: \"Nexmo\"\n          website: \"https://developer.nexmo.com\"\n          slug: \"nexmo\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-nexmo.svg\"\n        - name: \"Rapid River Software\"\n          website: \"https://rrsoft.co\"\n          slug: \"rapid-river-software\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-rapid-river.svg\"\n        - name: \"Jetbrains\"\n          website: \"https://www.jetbrains.com\"\n          slug: \"jetbrains\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-jetbrains.svg\"\n\n    - name: \"Speakers Sponsors & Individuals\"\n      level: 5\n      sponsors:\n        - name: \"Ascenda Loyalty\"\n          website: \"https://www.ascenda.com/\"\n          slug: \"ascenda-loyalty\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-ascenda.jpg\"\n        - name: \"Blackmill\"\n          website: \"https://blackmill.co\"\n          slug: \"blackmill\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-blackmill.jpg\"\n        - name: \"Brightwire\"\n          website: \"https://www.brightwire.com\"\n          slug: \"brightwire\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-brightwire.jpg\"\n        - name: \"IEX\"\n          website: \"https://iextrading.com\"\n          slug: \"iex\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-iex.jpg\"\n        - name: \"Josh\"\n          website: \"https://www.joshsoftware.com\"\n          slug: \"josh\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-josh.jpg\"\n        - name: \"Saeloun\"\n          website: \"https://www.saeloun.com\"\n          slug: \"saeloun\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-saeloun.jpg\"\n        - name: \"Speee\"\n          website: \"https://speee.jp\"\n          slug: \"speee\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-speee.jpg\"\n        - name: \"TTY Toolkit\"\n          website: \"https://ttytoolkit.org\"\n          slug: \"tty-toolkit\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-tty-toolkit.jpg\"\n        - name: \"Twilio\"\n          website: \"https://www.twilio.com\"\n          slug: \"twilio\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-twilio.jpg\"\n        - name: \"Zero One\"\n          website: \"https://www.zero-one.io\"\n          slug: \"zero-one\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-zero-one.jpg\"\n\n    - name: \"Partners\"\n      level: 6\n      sponsors:\n        - name: \"Eventpop\"\n          website: \"https://www.eventpop.me\"\n          slug: \"eventpop\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-eventpop.jpg\"\n        - name: \"Gummy Bear Recruitment\"\n          website: \"https://www.gummybear.tech\"\n          slug: \"gummy-bear-recruitment\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-gummy-bear.jpg\"\n        - name: \"Lemi\"\n          website: \"https://app.lemi.travel\"\n          slug: \"lemi\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-lemi.jpg\"\n        - name: \"Notion\"\n          website: \"https://www.notion.so\"\n          slug: \"notion\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-notion.jpg\"\n        - name: \"Pigeonhole\"\n          website: \"https://pigeonholelive.com\"\n          slug: \"pigeonhole\"\n          badge: \"Live Audience Engagement\"\n          logo_url: \"https://rubyconfth.com/past/2019/assets/images/pages/home/sponsors/logo-pigeonhole.jpg\"\n\n    - name: \"Organizer\"\n      level: 7\n      sponsors:\n        - name: \"Bangkok.rb\"\n          website: \"https://bangkokrb.org\"\n          slug: \"bangkokrb\"\n          logo_url: \"https://bangkokrb.org/images/ruby-tuesday.svg\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2019/venue.yml",
    "content": "# https://rubyconfth.com/past/2019/#venue\n---\nname: \"Pullman Bangkok King Power\"\n\naddress:\n  street: \"8-2 Rang Nam Alley, Khwaeng Thanon Phaya Thai, Khet Ratchathewi\"\n  city: \"Bangkok\"\n  region: \"\"\n  postal_code: \"10400\"\n  country: \"Thailand\"\n  country_code: \"TH\"\n  display: \"8, 2 Thanon Rang Nam, Khwaeng Thanon Phaya Thai, Khet Ratchathewi, Krung Thep Maha Nakhon 10400, Thailand\"\n\ncoordinates:\n  latitude: 13.7588878\n  longitude: 100.5373605\n\nmaps:\n  google: \"https://maps.google.com/?q=Pullman+Bangkok+King+Power,13.7588878,100.5373605\"\n  apple: \"https://maps.apple.com/?q=Pullman+Bangkok+King+Power&ll=13.7588878,100.5373605\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=13.7588878&mlon=100.5373605\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2019/videos.yml",
    "content": "# Day 1\n---\n- id: \"tim-riley-rubyconf-th-2019\"\n  title: \"Opening Keynote: Quest of the Rubyist\"\n  raw_title: \"RubyConf TH 2019 - Opening Keynote by Tim Riley\"\n  speakers:\n    - Tim Riley\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-14\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"B26rbJfRoZo\"\n  kind: \"keynote\"\n\n- id: \"vipul-a-m-rubyconf-th-2019\"\n  title: \"Beyond REST in Rails\"\n  raw_title: \"RubyConf TH 2019 - Beyond REST in Rails by Vipul Am\"\n  speakers:\n    - Vipul A M\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-14\"\n  description: |-\n    GraphQL is changing how data is being served in Ruby and Rails products from GitHub to KickStarter.\n\n    This talk is based on experiences from moving away from Rails REST routing to GraphQL Ruby in production Applications.\n\n    Lets explore features like Introspection and others in GraphQL Ruby/Rails.\n  video_provider: \"youtube\"\n  video_id: \"bES0zXqYfMQ\"\n\n- id: \"tae-noppakun-wongsrinoppakun-rubyconf-th-2019\"\n  title: \"Pattern Matching In Ruby 2.7\"\n  raw_title: \"RubyConf TH 2019 - Pattern Matching In Ruby 2.7 by Tae Noppakun Wongsrinoppakun\"\n  speakers:\n    - Tae Noppakun Wongsrinoppakun\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-14\"\n  description: |-\n    Pattern Matching is an upcoming Ruby 2.7 feature. As an elixir enthusiast and a professional Rubyist, I installed Ruby 2.7 and tried out the feature. I would like to show to pattern matching is implemented in Ruby, it’s potential and what could be improved.\n  video_provider: \"youtube\"\n  video_id: \"4etn_CAldy4\"\n\n- id: \"kazuma-furuhashi-rubyconf-th-2019\"\n  title: \"Charty - Visualize Real-world Data with Ruby\"\n  raw_title: \"RubyConf TH 2019 - Charty - Visualize Real-world Data with Ruby by Kazuma Furuhashi\"\n  speakers:\n    - Kazuma Furuhashi\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-15\"\n  description: |-\n    Kazuma is a Programmer and the Creator of a visualization library named Charty. A member of Asakusa.rb and Red Data Tools. Working at Speee Inc. His talk is about his visualization library called \"Charty\".\n  video_provider: \"youtube\"\n  video_id: \"GcxlNOewz18\"\n\n- id: \"jarka-kosanova-rubyconf-th-2019\"\n  title: \"How to Collaborate and Keep Healthy Culture in a Full-Remote Company\"\n  speakers:\n    - Jarka Košanová\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-15\"\n  description: |-\n    How do we make remote work possible? How do we communicate and what challenges do we face? Is it easy to keep a healthy work-life balance? How do we socialize and meet?\n\n    Jarka has been working for Gitlab for 2 and 1/2 years and has seen the company grow from 200 to 700 employees. She'll show you that it's possible!\n  video_provider: \"youtube\"\n  video_id: \"4kmFsHcaLfE\"\n\n- id: \"rodrigo-urubatan-rubyconf-th-2019\"\n  title: \"Data Science in Ruby? Is it possible? Is it Fast? Should we use it?\"\n  raw_title: \"RubyConf TH 2019 - Data Science in Ruby? Is it possible? Is it Fast? ... by Rodrigo Urubatan\"\n  speakers:\n    - Rodrigo Urubatan\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-14\"\n  description: |-\n    In this talk we’ll review the state of the tools for data science in Ruby!\n\n    Python is the “crown jewel” of the data science languages today, but many of us work mostly with Ruby for the business applications, and it is important to use the best tool for each job.\n  video_provider: \"youtube\"\n  video_id: \"nxubUjsqJYM\"\n\n- id: \"piotr-murach-rubyconf-th-2019\"\n  title: \"It Is Correct but Is It Fast?\"\n  speakers:\n    - Piotr Murach\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  description: |-\n    This talk from RubyConf TH 2019 did not have a published recording, but is included here so the schedule matches the full program.\n  video_provider: \"not_recorded\"\n  video_id: \"piotr-murach-rubyconf-th-2019\"\n\n- id: \"enrique-mogolln-rubyconf-th-2019\"\n  title: \"The Developer Who Wanted To Refactor The Moon\"\n  raw_title: \"RubyConf TH 2019 - The developer who wanted to refactor the moon by Enrique Mogollan\"\n  speakers:\n    - Enrique Mogollán\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-15\"\n  description: |-\n    Once upon a time, in a country far away, there was a developer that wanted to refactor the moon. The moon of course is written in Ruby.\n    At first, this developer was unable to find a way to do it but it was helped by the 3 wise Developers of the country:\n\n    the MetaProgramming Minister, who helped create the most magic Ruby code in the country.\n    the Object Oriented General, who works on the largest and fastest growing Ruby on Rails Application in the country.\n    the Functional Mathematician, who has written the most elegant and beautiful poems that are functions that solve real life problems.\n    This is a refactoring talk that showcases the flexibility of Ruby as a Programming Language.\n  video_provider: \"youtube\"\n  video_id: \"nJRGf1_JEUA\"\n\n- id: \"radoslav-stankov-rubyconf-th-2019\"\n  title: \"How to Get to Zero Unhandled Exceptions in Production\"\n  raw_title: \"RubyConf TH 2019 - How to get to zero unhandled exceptions in production by Radoslav Stankov\"\n  speakers:\n    - Radoslav Stankov\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-14\"\n  description: |-\n    In the talk, I’m going to explain how to categorize exceptions and their level of impact. Present use cases and code samples of common problems in a Rails application. How to make sure your background workers run without issues and how to debug exceptions.\n  video_provider: \"youtube\"\n  video_id: \"btUnSR-NGV0\"\n\n- id: \"giovanni-sakti-rubyconf-th-2019\"\n  title: \"Guide to Discourage your Boss from Migrating into Kubernetes\"\n  raw_title: \"RubyConf TH 2019 - Guide to Discourage your Boss from Migrating into Kubernetes by Giovanni Sakti\"\n  speakers:\n    - Giovanni Sakti\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-15\"\n  description: |-\n    Practical Guide to Discourage your Boss from Migrating into Kubernetes by Giovanni Sakti.\n\n    Kubernetes and all the ‘cloud-native’ baggage that it brings are some of the most-talked about stuff recently. More and more companies are adopting Kubernetes to deploy and manage their services. There are also lots of other companies that are starting to provide Kubernetes-as-a-service, not to mention dozens of open source projects that are published almost every week related to it.\n\n    For those who are still using more ‘traditional’ approach, such as VM-based deployment, Kubernetes can be very daunting because there are tons of new concepts being introduced. And because of the buzz around it, sometimes we feel the urge to use it even though it might not be appropriate for our use case.\n\n    Therefore in this talk, I want to convince you that it is not necessary to use Kubernetes, unless proven otherwise :)\n  video_provider: \"youtube\"\n  video_id: \"ZrF4mb5Hgt0\"\n\n- id: \"gabriel-fortuna-rubyconf-th-2019\"\n  title: \"How We Use Service Objects to Make Our Apps Clean, Composable, Maintainable, and Testable\"\n  speakers:\n    - Gabriel Fortuna\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-15\"\n  description: |-\n    How we use service objects to make our apps clean, composable, maintainable, and testable by Gabriel Fortuna.\n\n    Wouldn't it be great if you could keep the maintainability of your app high even as it grew in complexity? Wouldn't it feel wonderful to know that all your app functionality is fully tested, and that those tests are fast? How amazing would it be to start finally treating your app like a set of lego bricks?\n\n    Using service objects can get you a very long way there. They're not a silver bullet by any stretch of the imagination, but in my experience, they have been the number one thing alongside TDD that has really elevated my skill level.\n\n    Not all service object toolchains are created equal, and there are downsides, trade-offs, benefits, and useful shortcuts to be gained depending on the kind you reach for. I've battle tested a bunch of them, and this talk will include pointers for helping you decide what's right for you, for when you start using these tools in your own software projects.\n\n    Join me as I walk through the learnings to be had from using this software development technique, and how I've matured my thinking on this topic to make me an extremely effective developer that ships robust working code.\n  video_provider: \"youtube\"\n  video_id: \"omCsnwAzDy4\"\n\n- id: \"charles-nutter-rubyconf-th-2019\"\n  title: \"Closing Keynote: Scalable Applications with JRuby\"\n  raw_title: \"RubyConf TH 2019 - Keynote talk by Charles Nutter - Scalable Applications with JRuby\"\n  speakers:\n    - Charles Nutter\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-06\"\n  published_at: \"2019-10-15\"\n  description: |-\n    Scalable Applications with JRuby by Charles Nutter.mp4\n\n    I work on JRuby, the fastest and most scalable way to run Ruby web applications. This past year we’ve continued work on better database support, more Ruby optimizations, and tighter integration with recent JDK releases. This talk will show how to get started with JRuby.\n\n\n    JRuby is the fastest and most scalable way to run web applications built with Ruby or Rails. This past year we’ve continued work on better database support, more Ruby optimizations, and tighter integration with recent JDK releases. In this talk, I’ll cover:\n\n    Getting started with JRuby, building new applications or migrating existing ones.\n    Things to know about scaling JRuby, including tuning flags and deployment patterns.\n    Future plans for maintaining Ruby and Rails compatibility.\n    A call-to-action for anyone who’d like to help keep JRuby moving forward.\n  video_provider: \"youtube\"\n  video_id: \"V_I-A6LRxGw\"\n  kind: \"keynote\"\n\n# Day 2\n\n- id: \"richard-schneeman-rubyconf-th-2019\"\n  title: \"Opening Keynote: The Life-Changing Magic of Tidying Up ActiveRecord Allocations\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  description: |-\n    Opening keynote from RubyConf TH 2019 without an available recording, included here for schedule completeness.\n  video_provider: \"not_recorded\"\n  video_id: \"richard-schneeman-rubyconf-th-2019\"\n  kind: \"keynote\"\n\n- id: \"anton-davydov-rubyconf-th-2019\"\n  title: \"Events. Events. Events!\"\n  raw_title: \"RubyConf TH 2019 - Events. Events. Events! by Anton Davydov.mp4\"\n  speakers:\n    - Anton Davydov\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  published_at: \"2019-10-14\"\n  description: |-\n    We build different systems and usually think about the current state of our application. Usually, it’s data from our DBs. But what will happen if we start thing about the list of events which can help us calculate a state of the application for any time?\n  video_provider: \"youtube\"\n  video_id: \"jTNDhogZKQA\"\n\n- id: \"vishal-chandnani-rubyconf-th-2019\"\n  title: \"Debug Hard: Ruby String Library Methods and Underlying C Implementations\"\n  raw_title: \"RubyConf TH 2019 - Debug Hard: Ruby String Library Methods and Underlying C ... by Vishal Chandnani\"\n  speakers:\n    - Vishal Chandnani\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  published_at: \"2019-10-15\"\n  description: |-\n    Debug Hard: Ruby String Library Methods and Underlying C Implementations by Vishal Chandnani\n\n    What if the Ruby String library ‘reverse’ method or its underlying C implementation had a bug? What if it produced unexpected results with certain types of inputs? e.g. strings with unicode characters. How would you catch and fix such a bug? How would you explain the unexpected results?\n\n    1. Relevance\n    The Ruby String library ‘reverse’ method is implemented in C. The debugging tools in this talk apply to Ruby programs, and help provide useful insights into the underlying C implementation.\n\n    2. Novelty and Originality\n    The ‘use unicode_normalize to address certain string reversal issues’ appears to be known to certain developers. The novel idea in this talk is the analysis of Ruby and C implementation to explain the problem and possible solutions.\n\n    3. Knowledge\n    I started my software development career at Lucent Technologies (originally Bell Labs Innovations, currently Nokia Bell Labs) and used C/C++ to develop CDMA wireless communication system software for 12 years. At The Boeing Company, I used Ruby/Rails to develop U.S. government intelligence community software for 7 years. I am fascinated that Ruby is implemented in C and am excited to share my recent debugging experiences with our community.\n\n    4. Coverage\n    This talk presents a step-by-step approach to debugging Ruby programs by diving into their underlying C implementation. It uses a string with unicode characters to demonstrate the problem and provides insights into the reversal process by understanding their byte-level representation.\n\n    5. Organization\n    This talk starts with a high-level view of the Ruby String library ‘reverse’ method implementation. It introduces the idea of using a Virtual Machine (VM) to build Ruby from source. We learn about the Unicode standard and encoding fundamental principles. We explore the ‘unicode_normalize’ implementation and how it addresses ‘reverse’ method problems. Along the way, we use commands/tools like grep, chars, code_points, each_byte, printf and gdb to provide insight into Ruby library methods.\n\n    6. Bottom Line\n    This talk aims to improve confidence in understanding bugs and/or unexpected results in the current application language (e.g. Ruby) as well as the underlying (e.g. C) implementations. I hope to inspire the Ruby community to explore the internals of Ruby strings and provide recommendations for further exploration.\n  video_provider: \"youtube\"\n  video_id: \"C_LHpELWK4g\"\n\n- id: \"harley-davidson-karel-rubyconf-th-2019\"\n  title: \"Security Issues on Your Ruby Code\"\n  speakers:\n    - Harley Davidson Karel\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  description: |-\n    This talk from RubyConf TH 2019 did not have a published recording, but is included here so the schedule matches the full program.\n  video_provider: \"not_recorded\"\n  video_id: \"harley-davidson-karel-rubyconf-th-2019\"\n\n- id: \"melvrick-goh-rubyconf-th-2019\"\n  title: \"Metaprogramming DSLs for managing complexity at scale\"\n  raw_title: \"RubyConf TH 2019 - Metaprogramming DSLs for managing complexity at scale by Melvrick Goh\"\n  speakers:\n    - Melvrick Goh\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  published_at: \"2019-10-15\"\n  description: |-\n    Our product TransferConnect facilitates loyalty transfers (points) between over 100+ banks & airlines’ systems. Our major challenge here was how to quickly & flexibly cater to varied systems, both legacy and new.\n\n    Here’s our story of how we designed a DSL which enabled our engineers (including new joiners & interns) to jump in and easily develop & maintain our integrations. This is also about our teething pains & learning journey towards the mature version of the DSL we had.\n\n    This session is best useful to you haven’t employed metaprogramming extensively. If you’re well versed in it, you may be keen to see how we’ve designed to enable easy maintainability. Fret not, this has been made easy to digest for the everyday engineer.\n  video_provider: \"youtube\"\n  video_id: \"VNt5eVOlyFo\"\n\n- id: \"shweta-kale-rubyconf-th-2019\"\n  title: \"Go-ing a Long Way with Rails\"\n  speakers:\n    - Shweta Kale\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  description: |-\n    This talk from RubyConf TH 2019 did not have a published recording, but is included here so the schedule matches the full program.\n  video_provider: \"not_recorded\"\n  video_id: \"shweta-kale-rubyconf-th-2019\"\n\n- id: \"janko-marohnic-rubyconf-th-2019\"\n  title: \"Handling File Uploads for a Modern Developer\"\n  speakers:\n    - Janko Marohnić\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  description: |-\n    This talk will introduce the Shrine gem and go over some of the modern best practices for handling file attachments. We will cover topics such as image processing (“Is ImageMagick always the best option?”), asynchronous file uploads (“Which JavaScript solution should I choose?”), and handling large uploads (“How do I help users that have a flaky internet connection?”).\n  video_provider: \"youtube\"\n  video_id: \"XbCAOFr4oNM\"\n  published_at: \"2019-10-16\"\n\n- id: \"elle-meredith-rubyconf-th-2019\"\n  title: \"Start your own engineering apprenticeship program\"\n  raw_title: \"RubyConf TH 2019 - Start your own engineering apprenticeship program by  Elle Meredith\"\n  speakers:\n    - Elle Meredith\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  published_at: \"2019-10-16\"\n  description: |-\n    With a surge of over 1.3 million technology sector jobs by 2020, companies will continue to struggle filling these roles because of a widening skills gap. Technology companies survive by their ability to hire and retain fantastic employees. With software engineers that means delivering an environment that offers autonomy, opportunities for learning, and values craft. Technology companies employ people who can learn, who love it, and those inspired to keep doing it – “life-long learners”. But, how do you foster that in emerging developers? Such that they have sufficient foundational knowledge to build a meaningful career, and that they are provided the tools to continue to bridge knowledge gaps in our ever-changing industry.\n\n    An apprenticeship program helps all your engineers understand your technology platform, culture, and shared vocabulary, so they can meaningfully contribute earlier and better. Learn how to develop and implement a robust apprenticeship program that creates a solid and continuous pipeline of talent that will grow your business. This talk is about learning, how to get started, keep motivated, self-assess, and other useful patterns.\n  video_provider: \"youtube\"\n  video_id: \"pwoWEpEWAvo\"\n\n- id: \"phil-nash-rubyconf-th-2019\"\n  title: \"Smaller Is Always Better\"\n  speakers:\n    - Phil Nash\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  description: |-\n    This talk from RubyConf TH 2019 did not have a published recording, but is included here so the schedule matches the full program.\n  video_provider: \"not_recorded\"\n  video_id: \"phil-nash-rubyconf-th-2019\"\n\n- id: \"sergey-dolganov-rubyconf-th-2019\"\n  title: \"Dirty Magic for Resilient API Dependencies\"\n  raw_title: \"RubyConf TH 2019 - Dirty Magic for Resilient API Dependencies by Sergey Dolganov\"\n  speakers:\n    - Sergey Dolganov\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  published_at: \"2019-10-15\"\n  description: |-\n    Imagine that you want to build a system which depends on external service, e.g., logistics, payments or notifications service. These systems have its life-cycle which you have to be in sync with. Sergey will share how to treat issues you could face, using the examples of DHL, UPS, Zoho, eBay integrations. \n\n    Sergey is an experienced Software Developer interested in building a strong and sustainable community around OSS and likes to discuss different ways to profile, debug and optimize applications. He also loves dogs and is a drummer and musician.\n  video_provider: \"youtube\"\n  video_id: \"k0U1ZLSzMrk\"\n\n- id: \"saron-yitbarek-rubyconf-th-2019\"\n  title: \"Closing Keynote: The Magical Living Room: how to build authentic and engaged communities\"\n  speakers:\n    - Saron Yitbarek\n  event_name: \"RubyConf TH 2019\"\n  date: \"2019-09-07\"\n  published_at: \"2019-10-15\"\n  description: |-\n    Saron is the CEO and founder of CodeNewbie, the most supportive community of programmers and people learning to code. She's also a developer, speaker, and podcaster.\n\n    In the closing keynote for RubyConf TH 2019 in Bangkok, Saron talked about \"The Magical Living Room: how to build authentic and engaged communities\".\n  video_provider: \"youtube\"\n  video_id: \"0zwyIfE0R9A\"\n  kind: \"keynote\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2022/cfp.yml",
    "content": "---\n- link: \"https://papercall.io/rubyconfth2022\"\n  open_date: \"2022-08-16\"\n  close_date: \"2022-09-30\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2022/event.yml",
    "content": "---\nid: \"PLM_LdV8tMIaxpMTv9dnWk3cq61xJcE2Pv\"\ntitle: \"RubyConf TH 2022\"\nkind: \"conference\"\nlocation: \"Bangkok, Thailand\"\ndescription: |-\n  A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n  Find out more and register for updates for our 2023 conference at https://rubyconfth.com/ \n\n  RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\npublished_at: \"2022-12-09\"\nstart_date: \"2022-12-09\"\nend_date: \"2022-12-10\"\nchannel_id: \"UCwIhYV_sPTzvjk6B6EUnf1g\"\nyear: 2022\nbanner_background: \"#F92849\"\nfeatured_background: \"#F92849\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubyconfth.com/past/2022/\"\ncoordinates:\n  latitude: 13.7588878\n  longitude: 100.5373605\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2022/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n\n  users:\n    - Matt Mayer\n    - Dan Itsara\n    - Georgi Ker\n    - Michael Kohl\n    - Keith Bennett\n    - Olivier Robert\n    - Alex Timofeev\n    - Ted Thetnaungsoe\n\n  organisations:\n    - Bangkok.rb\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2022/schedule.yml",
    "content": "# Schedule: RubyConf TH 2022\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2022-12-09\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration & Conference Door Opens\n\n      - start_time: \"09:00\"\n        end_time: \"09:10\"\n        slots: 1\n        items:\n          - Welcome Address\n\n      - start_time: \"09:10\"\n        end_time: \"09:55\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"10:50\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"10:50\"\n        end_time: \"11:20\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"11:55\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:50\"\n        slots: 1\n        items:\n          - Buffet Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:35\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:35\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"15:35\"\n        end_time: \"16:05\"\n        slots: 1\n\n      - start_time: \"16:10\"\n        end_time: \"16:55\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:10\"\n        slots: 1\n        items:\n          - Closing remarks & announcements\n\n      - start_time: \"18:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - title: \"Official Party @ Bangkok Heritage\"\n            description: |-\n              Official RubyConf TH 2022 party at Bangkok Heritage, 2 Phaya Thai Rd, Thung Phaya Thai, Ratchathewi, Bangkok 10400.\n\n  - name: \"Day 2\"\n    date: \"2022-12-10\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Conference Door Opens\n\n      - start_time: \"09:00\"\n        end_time: \"09:10\"\n        slots: 1\n        items:\n          - Welcome Address\n\n      - start_time: \"09:10\"\n        end_time: \"09:55\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"10:50\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"10:50\"\n        end_time: \"11:20\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"11:55\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:50\"\n        slots: 1\n        items:\n          - Buffet Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:35\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:35\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"15:35\"\n        end_time: \"16:05\"\n        slots: 1\n\n      - start_time: \"16:10\"\n        end_time: \"16:55\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:10\"\n        slots: 1\n        items:\n          - Closing remarks & announcements\n\ntracks:\n  - name: \"Main Track\"\n    color: \"#DC2626\"\n    text_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2022/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold Sponsors\"\n      level: 3\n      sponsors:\n        - name: \"Eventpop\"\n          website: \"https://www.eventpop.me\"\n          slug: \"eventpop\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/eventpop.png\"\n        - name: \"Honeybadger\"\n          website: \"https://www.honeybadger.io\"\n          slug: \"honeybadger\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/honeybadger.svg\"\n        - name: \"Oivan\"\n          website: \"https://oivan.com\"\n          slug: \"oivan\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/oivan.svg\"\n\n    - name: \"Silver Sponsors\"\n      level: 4\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com\"\n          slug: \"appsignal\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/appsignal.svg\"\n        - name: \"Bee SCM\"\n          website: \"https://beescm.com\"\n          slug: \"bee-scm\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/beeees.png\"\n        - name: \"Cloud 66\"\n          website: \"https://www.cloud66.com\"\n          slug: \"cloud-66\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/cloud-66.svg\"\n        - name: \"GetLinks\"\n          website: \"https://www.getlinks.com\"\n          slug: \"getlinks\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/getlinks.svg\"\n        - name: \"MyCloudFulfillment\"\n          website: \"https://www.mycloudfulfillment.com\"\n          slug: \"mycloudfulfillment\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/mycloudfulfillment.svg\"\n        - name: \"PRODIGY9\"\n          website: \"https://prodigy9.com\"\n          slug: \"prodigy9\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/prodigy9.svg\"\n        - name: \"ProudCloud\"\n          website: \"https://www.proudcloud.io\"\n          slug: \"proudcloud\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/proudcloud.svg\"\n        - name: \"Talented\"\n          website: \"https://talented.co\"\n          slug: \"talented\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/talented.svg\"\n\n    - name: \"Speaker Sponsors\"\n      level: 5\n      sponsors:\n        - name: \"Bluethumb\"\n          website: \"https://bluethumb.com.au\"\n          slug: \"bluethumb\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/bluethumb.svg\"\n        - name: \"BuildKite\"\n          website: \"https://buildkite.com\"\n          slug: \"buildkite\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/buildkite.svg\"\n        - name: \"Fresho\"\n          website: \"https://www.fresho.com\"\n          slug: \"fresho\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/fresho.svg\"\n        - name: \"Jobandtalent\"\n          website: \"https://www.jobandtalent.com\"\n          slug: \"jobandtalent\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/jobandtalent.svg\"\n\n    - name: \"Community Partners\"\n      level: 6\n      sponsors:\n        - name: \"STYAVA\"\n          website: \"https://styava.com\"\n          slug: \"styava\"\n          logo_url: \"https://rubyconfth.com/past/2022/images/sponsors/styava.png\"\n\n    - name: \"Organizer\"\n      level: 7\n      sponsors:\n        - name: \"Bangkok.rb\"\n          website: \"https://bangkokrb.org\"\n          slug: \"bangkokrb\"\n          logo_url: \"https://bangkokrb.org/images/ruby-tuesday.svg\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2022/venue.yml",
    "content": "# https://rubyconfth.com/past/2022/venue/\n---\nname: \"Pullman Bangkok King Power\"\n\ndescription: |\n  Infinity Ballroom\n\naddress:\n  street: \"8-2 Rang Nam Alley, Khwaeng Thanon Phaya Thai, Khet Ratchathewi\"\n  city: \"Bangkok\"\n  region: \"\"\n  postal_code: \"10400\"\n  country: \"Thailand\"\n  country_code: \"TH\"\n  display: \"8, 2 Thanon Rang Nam, Khwaeng Thanon Phaya Thai, Khet Ratchathewi, Krung Thep Maha Nakhon 10400, Thailand\"\n\ncoordinates:\n  latitude: 13.7588878\n  longitude: 100.5373605\n\nmaps:\n  google: \"https://maps.google.com/?q=Pullman+Bangkok+King+Power,13.7588878,100.5373605\"\n  apple: \"https://maps.apple.com/?q=Pullman+Bangkok+King+Power&ll=13.7588878,100.5373605\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=13.7588878&mlon=100.5373605\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2022/videos.yml",
    "content": "---\n# TODO: conference website\n# TODO: schedule website\n\n# Day 1\n\n- id: \"nate-berkopec-rubyconf-th-2022\"\n  title: \"Keynote: A Beginner's Guide to Puma Internals\"\n  raw_title: \"RubyConfTH 2022 - Keynote: A Beginner's Guide to Puma Internals by Nate Berkopec\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-09\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"w4X_oBuPmTM\"\n\n- id: \"cristian-planas-rubyconf-th-2022\"\n  title: \"A Rails Performance Guidebook: from 0 to 1B requests/day\"\n  raw_title: \"RubyConfTH 2022 - A Rails performance guidebook: from 0 to 1B requests/day by Cristian Planas\"\n  speakers:\n    - Cristian Planas\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-09\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"QOGY1GHVQu0\"\n\n- id: \"tim-riley-rubyconf-th-2022\"\n  title: \"Hanami 2: New Framework, New You\"\n  raw_title: \"RubyConfTH 2022 - Hanami 2: New Framework, New You by Tim Riley\"\n  speakers:\n    - Tim Riley\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-09\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"jxJ4-iadvIk\"\n\n- id: \"yuji-yokoo-rubyconf-th-2022\"\n  title: \"Megaruby - mruby/c on Sega Mega Drive\"\n  raw_title: \"RubyConfTH 2022 - Megaruby - mruby/c on Sega Mega Drive by Yuji Yokoo\"\n  speakers:\n    - Yuji Yokoo\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-09\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"s65qlUFRWtI\"\n\n- id: \"paolo-nusco-perrotta-rubyconf-th-2022\"\n  title: \"Roasting the Duck - A Talk About Ruby and Types\"\n  raw_title: \"RubyConfTH 2022 - Roasting the Duck - A talk about Ruby and types by Paolo Perrotta\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-09\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"tQU8PEY55rg\"\n\n- id: \"charles-nutter-rubyconf-th-2022\"\n  title: \"Scaling Ruby with JRuby\"\n  raw_title: \"RubyConfTH 2022 - Scaling Ruby with JRuby by Charles Oliver Nutter\"\n  speakers:\n    - Charles Nutter\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-09\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"OwEDqtlBg04\"\n\n- id: \"michael-milewski-rubyconf-th-2022\"\n  title: \"10x Your Teamwork Through Pair Programming\"\n  raw_title: \"RubyConfTH 2022 - 10x your teamwork through pair programming by Michael Milewski and Selena Small\"\n  speakers:\n    - Michael Milewski\n    - Selena Small\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-09\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"6E_2azg8r40\"\n\n- id: \"aaron-cruz-rubyconf-th-2022\"\n  title: \"Why I choose Phoenix\"\n  raw_title: \"RubyConfTH 2022 - Why I choose Phoenix by Aaron Cruz\"\n  speakers:\n    - Aaron Cruz\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-09\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"PIrLtOvDwGA\"\n\n- id: \"siddharth-sharma-rubyconf-th-2022\"\n  title: \"Keynote: The Ecstatic Organisation by Siddharth Sharma\"\n  raw_title: \"RubyConfTH 2022 - Keynote: The Ecstatic Organisation by Siddharth Sharma\"\n  speakers:\n    - Siddharth Sharma\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-09\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"M_vHUl3riKQ\"\n\n# Day 2\n\n- id: \"yarden-laifenfeld-rubyconf-th-2022\"\n  title: \"Keynote: Ruby & JVM: A (JRuby) Love Story\"\n  raw_title: \"RubyConfTH 2022 - Keynote: Ruby & JVM: A (JRuby) Love Story by Yarden Laifenfeld\"\n  speakers:\n    - Yarden Laifenfeld\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-10\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"QdXX7OjhZJY\"\n\n- id: \"stephan-eberle-rubyconf-th-2022\"\n  title: \"On Making Your Rails App More Transparent\"\n  raw_title: \"RubyConfTH 2022 - On making your Rails App more transparent by Stephan Eberle\"\n  speakers:\n    - Stephan Eberle\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-10\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"uLjaTFAOnIs\"\n\n- id: \"thatthep-vorrasing-rubyconf-th-2022\"\n  title: \"GitOps: The Single Source of Truth\"\n  raw_title: \"RubyConfTH 2022 - GitOps: The Single source of truth by Thatthep Vorrasing\"\n  speakers:\n    - Thatthep Vorrasing\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-10\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"wxHcV1qhiiU\"\n\n- id: \"anita-jaszewska-rubyconf-th-2022\"\n  title: \"Dealing With A Project's Complexity In A Changing Environment\"\n  raw_title: \"RubyConfTH 2022 - Dealing With A Project's Complexity In A Changing Environment by Anita Jaszewska\"\n  speakers:\n    - Anita Jaszewska\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-10\"\n  published_at: \"2023-01-07\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"gDzlsoBdxtM\"\n\n- id: \"ratnadeep-deshmane-rubyconf-th-2022\"\n  title: \"Dissecting Rails - A Different Approach to Learning Rails\"\n  raw_title: \"RubyConfTH 2022 - Dissecting Rails - a different approach to learning Rails by Ratnadeep Deshmane\"\n  speakers:\n    - Ratnadeep Deshmane\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-10\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"gXwRs-FwcmE\"\n\n- id: \"jeremy-evans-rubyconf-th-2022\"\n  title: \"Roda: Simplicity, Reliability, Extensibility, Performance\"\n  raw_title: \"RubyConfTH 2022 - Roda: Simplicity, Reliability, Extensibility, Performance by Jeremy Evans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-10\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"9fukis_VHl4\"\n\n- id: \"jnatas-paganini-rubyconf-th-2022\"\n  title: \"Processing data: Ruby or SQL?\"\n  raw_title: \"RubyConfTH 2022 - Processing data: Ruby or SQL? by Jônatas Paganini\"\n  speakers:\n    - Jônatas Paganini\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-10\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"MXAtSZ5Szgk\"\n\n- id: \"rodrigo-urubatan-rubyconf-th-2022\"\n  title: \"Refactoring for Rails - Using Deodorant to Prevent Code Smells\"\n  raw_title: \"RubyConfTH 2022 - Refactoring for Rails - using deodorant to prevent code smells by Rodrigo Urubatan\"\n  speakers:\n    - Rodrigo Urubatan\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-10\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"5THDThGPOVQ\"\n\n- id: \"noah-gibbs-rubyconf-th-2022\"\n  title: \"Keynote: YJIT's Three Languages: The Fun of Code That Writes Code\"\n  raw_title: \"RubyConfTH 2022 - Keynote: YJIT's Three Languages: the Fun of Code that Writes Code by Noah Gibbs\"\n  speakers:\n    - Noah Gibbs\n  event_name: \"RubyConf TH 2022\"\n  date: \"2022-12-10\"\n  published_at: \"2023-01-04\"\n  description: |-\n    A talk from RubyConfTH, held in Bangkok, Thailand on December 9-10, 2022.\n\n    Find out more and register for updates for our 2023 conference at https://rubyconfth.com/\n\n    RubyConfTH 2022 videos are presented by Cloud 66. https://cloud66.com\n  video_provider: \"youtube\"\n  video_id: \"yZSe1BhiTvI\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2023/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/rubyconfth2023\"\n  open_date: \"2023-04-03\"\n  close_date: \"2023-06-04\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2023/event.yml",
    "content": "---\nid: \"PLM_LdV8tMIay0GaJcCHegGyk0MGyQIVA6\"\ntitle: \"RubyConf TH 2023\"\nkind: \"conference\"\nlocation: \"Bangkok, Thailand\"\ndescription: |-\n  A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n  Find out more and register for updates for our next conference at https://rubyconfth.com/\npublished_at: \"2023-10-06\"\nstart_date: \"2023-10-06\"\nend_date: \"2023-10-07\"\nchannel_id: \"UCwIhYV_sPTzvjk6B6EUnf1g\"\nyear: 2023\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://rubyconfth.com/past/2023/\"\ncoordinates:\n  latitude: 13.7315121\n  longitude: 100.5641589\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2023/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n\n  users:\n    - Matt Mayer\n    - Dan Itsara\n    - Michael Kohl\n    - Keith Bennett\n    - Olivier Robert\n    - Ted Thetnaungsoe\n    - Alex Timofeev\n    - Thar Htet\n\n  organisations:\n    - Bangkok.rb\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2023/schedule.yml",
    "content": "# Schedule: RubyConf TH 2023\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2023-10-06\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration & Conference Door Opens\n\n      - start_time: \"09:00\"\n        end_time: \"09:10\"\n        slots: 1\n        items:\n          - Welcome Address\n\n      - start_time: \"09:10\"\n        end_time: \"09:55\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"10:50\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"10:50\"\n        end_time: \"11:20\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"11:55\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:50\"\n        slots: 1\n        items:\n          - Buffet Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:35\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:35\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"15:35\"\n        end_time: \"16:05\"\n        slots: 1\n\n      - start_time: \"16:10\"\n        end_time: \"16:55\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:10\"\n        slots: 1\n        items:\n          - Closing remarks & announcements\n\n      - start_time: \"18:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - title: \"Official Party @ The Deck\"\n            description: |-\n              Official RubyConf TH 2023 party at The Deck.\n\n  - name: \"Day 2\"\n    date: \"2023-10-07\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Conference Door Opens\n\n      - start_time: \"09:00\"\n        end_time: \"09:10\"\n        slots: 1\n        items:\n          - Welcome Address\n\n      - start_time: \"09:10\"\n        end_time: \"09:55\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"10:50\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"10:50\"\n        end_time: \"11:20\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"11:55\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:50\"\n        slots: 1\n        items:\n          - Buffet Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:35\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:35\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"15:35\"\n        end_time: \"16:05\"\n        slots: 1\n\n      - start_time: \"16:10\"\n        end_time: \"16:55\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:10\"\n        slots: 1\n        items:\n          - Closing remarks & announcements\n\ntracks:\n  - name: \"Main Track\"\n    color: \"#DC2626\"\n    text_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2023/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold Sponsors\"\n      level: 3\n      sponsors:\n        - name: \"Eventpop\"\n          website: \"https://www.eventpop.me\"\n          slug: \"eventpop\"\n          logo_url: \"https://rubyconfth.com/past/2023/images/sponsors/eventpop.png\"\n        - name: \"Oivan\"\n          website: \"https://oivan.com\"\n          slug: \"oivan\"\n          logo_url: \"https://rubyconfth.com/past/2023/images/sponsors/oivan.svg\"\n        - name: \"The Urban Office\"\n          website: \"https://www.theurbanoffice.co.th\"\n          slug: \"the-urban-office\"\n          logo_url: \"https://rubyconfth.com/past/2023/images/sponsors/urbanoffice.svg\"\n\n    - name: \"Silver Sponsors\"\n      level: 4\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com\"\n          slug: \"appsignal\"\n          logo_url: \"https://rubyconfth.com/past/2023/images/sponsors/appsignal.svg\"\n        - name: \"Bluethumb\"\n          website: \"https://bluethumb.com.au\"\n          slug: \"bluethumb\"\n          logo_url: \"https://rubyconfth.com/past/2023/images/sponsors/bluethumb.svg\"\n        - name: \"Data Wow\"\n          website: \"https://datawow.io\"\n          slug: \"data-wow\"\n          logo_url: \"https://rubyconfth.com/past/2023/images/sponsors/datawow.svg\"\n        - name: \"devoteam\"\n          website: \"https://www.devoteam.com\"\n          slug: \"devoteam\"\n          logo_url: \"https://rubyconfth.com/past/2023/images/sponsors/devoteam.svg\"\n        - name: \"Jetbrains\"\n          website: \"https://www.jetbrains.com\"\n          slug: \"jetbrains\"\n          logo_url: \"https://rubyconfth.com/past/2023/images/sponsors/jetbrains.svg\"\n\n    - name: \"Speaker Sponsors\"\n      level: 5\n      sponsors:\n        - name: \"Rakuten Viki\"\n          website: \"https://www.viki.com\"\n          slug: \"rakuten-viki\"\n          logo_url: \"https://rubyconfth.com/past/2023/images/sponsors/viki.png\"\n        - name: \"WNB.rb\"\n          website: \"https://www.wnb-rb.dev\"\n          slug: \"wnb-rb\"\n          logo_url: \"https://rubyconfth.com/past/2023/images/sponsors/wnb-rb.png\"\n\n    - name: \"Organizer\"\n      level: 6\n      sponsors:\n        - name: \"Bangkok.rb\"\n          website: \"https://bangkokrb.org\"\n          slug: \"bangkokrb\"\n          logo_url: \"https://bangkokrb.org/images/ruby-tuesday.svg\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2023/venue.yml",
    "content": "# https://rubyconfth.com/past/2023/venue\n---\nname: \"Novotel Bangkok Sukhumvit 20\"\n\naddress:\n  street: \"19/9 Sukhumvit 20 Alley, Khwaeng Khlong Toei, Khlong Toei, Bangkok\"\n  city: \"Bangkok\"\n  region: \"Bangkok\"\n  postal_code: \"10110\"\n  country: \"Thailand\"\n  country_code: \"TH\"\n  display: \"19/9 Soi Sukhumvit 20, Khwaeng Khlong Toei, Khet Khlong Toei, Krung Thep Maha Nakhon 10110, Thailand\"\n\ncoordinates:\n  latitude: 13.7315121\n  longitude: 100.5641589\n\nmaps:\n  google: \"https://maps.google.com/?q=Novotel+Bangkok+Sukhumvit+20,13.7315121,100.5641589\"\n  apple: \"https://maps.apple.com/?q=Novotel+Bangkok+Sukhumvit+20&ll=13.7315121,100.5641589\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=13.7315121&mlon=100.5641589\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2023/videos.yml",
    "content": "---\n# TODO: conference website\n# TODO: schedule website\n\n# Day 1\n\n- id: \"yukihiro-matz-matsumoto-rubyconf-th-2023\"\n  title: \"Keynote: 30 Years of Ruby\"\n  raw_title: 'RubyConfTH 2023 - Keynote: 30 Years of Ruby by Yukihiro \"Matz\" Matsumoto'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"v9htIvpqaug\"\n\n- id: \"radoslav-stankov-rubyconf-th-2023\"\n  title: \"Component Driven UI with ViewComponent gem\"\n  raw_title: \"RubyConfTH 2023 - Component Driven UI with ViewComponent gem by Radoslav Stankov\"\n  speakers:\n    - Radoslav Stankov\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"ar8RMbDPoSY\"\n\n- id: \"elle-meredith-rubyconf-th-2023\"\n  title: \"Learn to Delegate; Like a Boss\"\n  raw_title: \"RubyConfTH 2023 - Learn to delegate; like a boss by Elle Meredith & Lachlan Hardy\"\n  speakers:\n    - Elle Meredith\n    - Lachlan Hardy\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"RWVe2EXCE9M\"\n\n- id: \"matthew-lindfield-seager-rubyconf-th-2023\"\n  title: \"Error 418 - I'm a Teapot\"\n  raw_title: \"RubyConfTH 2023 - Error 418 - I'm a teapot Slides by Matthew Lindfield Seager\"\n  speakers:\n    - Matthew Lindfield Seager\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"gzww742hcuE\"\n\n- id: \"chakrit-wichian-rubyconf-th-2023\"\n  title: \"Big Corps, Big Worries Some Points on Selling Ruby to Big Corps\"\n  raw_title: \"RubyConfTH 2023 - Big Corps, Big Worries Some points on selling Ruby to Big Corps by Chakrit Wichian\"\n  speakers:\n    - Chakrit Wichian\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"nynzHHNQbDA\"\n\n- id: \"syed-faraaz-ahmad-rubyconf-th-2023\"\n  title: \"BYOJ: Build your own JIT with Ruby\"\n  raw_title: \"RubyConfTH 2023 - BYOJ: Build your own JIT with Ruby by Syed Faraaz Ahmad\"\n  speakers:\n    - Syed Faraaz Ahmad\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"PGElh63JnUA\"\n\n- id: \"katrina-owen-rubyconf-th-2023\"\n  title: \"Cultivating Instinct\"\n  raw_title: \"RubyConfTH 2023 - Cultivating Instinct by Katrina Owen\"\n  speakers:\n    - Katrina Owen\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"htGjAZROOUo\"\n\n- id: \"benji-lewis-rubyconf-th-2023\"\n  title: \"Data Indexing with RGB (Ruby, Graphs and Bitmaps)\"\n  raw_title: \"RubyConfTH 2023 - Data indexing with RGB (Ruby, Graphs and Bitmaps) by Benji Lewis\"\n  speakers:\n    - Benji Lewis\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"xz9FMFGV2Eo\"\n\n- id: \"bernard-banta-rubyconf-th-2023\"\n  title: \"Keynote: Breaking Barriers — Empowering the Unbanked with Innovative Tech\"\n  raw_title: \"RubyConfTH 2023 - Keynote: Breaking Barriers — Empowering the Unbanked with Inno .. by Bernard Banta\"\n  speakers:\n    - Bernard Banta\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-06\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"oRtgSlJeiuw\"\n\n# Day 2\n\n- id: \"jemma-issroff-rubyconf-th-2023\"\n  title: \"Keynote: Popping into Ruby\"\n  raw_title: \"RubyConfTH 2023 - Keynote: Popping into Ruby by Jemma Issroff\"\n  speakers:\n    - Jemma Issroff\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-07\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"vsiFjuBt-v8\"\n\n- id: \"hitoshi-hasumi-rubyconf-th-2023\"\n  title: \"A Beginner's Complete Guide to Microcontroller Programming with Ruby\"\n  raw_title: \"RubyConfTH 2023 - A Beginner's Complete Guide to Microcontroller Programming w.. by Hitoshi Hasumi\"\n  speakers:\n    - Hitoshi Hasumi\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-07\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"GkIRr1Xm8GU\"\n\n- id: \"huy-du-rubyconf-th-2023\"\n  title: \"Avoiding Disaster: Practical Strategies for Error Handling\"\n  raw_title: \"RubyConfTH 2023 - Avoiding Disaster: Practical Strategies for Error Handling Slides by Huy Du\"\n  speakers:\n    - Huy Du\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-07\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"Ci1f9NKuOyY\"\n\n- id: \"brad-urani-rubyconf-th-2023\"\n  title: \"Event Streaming Patterns for Ruby Services\"\n  raw_title: \"RubyConfTH 2023 - Event Streaming Patterns for Ruby Services by Brad Urani\"\n  speakers:\n    - Brad Urani\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-07\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"RBj4S9S-fJI\"\n\n- id: \"dan-itsara-rubyconf-th-2023\"\n  title: \"Panel Discussion\"\n  raw_title: \"RubyConfTH 2023 - Panel Discussion\"\n  speakers:\n    - Dan Itsara\n    - Jemma Issroff\n    - Selena Small\n    - Brad Urani\n    - Elle Meredith\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-07\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"lYO7w-sSLgs\"\n\n- id: \"michael-milewski-rubyconf-th-2023\"\n  title: \"Kickboxer vs. Ruby - The State of MRuby, JRuby and CRuby\"\n  raw_title: \"RubyConfTH 2023 - Kickboxer vs Ruby - the state of MRuby, JRuby.. by Michael Milewski & Selena Small\"\n  speakers:\n    - Michael Milewski\n    - Selena Small\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-07\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"JQRT6-Yjumo\"\n\n- id: \"helio-cola-rubyconf-th-2023\"\n  title: \"The World of Passkeys 🤝🏽 Ruby\"\n  raw_title: \"RubyConfTH 2023 - The world of Passkeys 🤝🏽 Ruby Slides by Helio Cola\"\n  speakers:\n    - Helio Cola\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-07\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"3UiVL6TnDr8\"\n\n- id: \"rishi-jain-rubyconf-th-2023\"\n  title: \"Rails Performance Monitoring 101: A Primer for Developers\"\n  raw_title: \"RubyConfTH 2023 - Rails Performance Monitoring 101: A Primer for Developers by Rishi Jain\"\n  speakers:\n    - Rishi Jain\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-07\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"41HtDXJj-fw\"\n\n- id: \"ben-halpern-rubyconf-th-2023\"\n  title: \"Keynote: Thriving in Uncertainty\"\n  raw_title: \"RubyConfTH 2023 - Keynote: Thriving in Uncertainty by Ben Halpern\"\n  speakers:\n    - Ben Halpern\n  event_name: \"RubyConf TH 2023\"\n  date: \"2023-10-07\"\n  published_at: \"2023-11-07\"\n  description: |-\n    A talk from RubyConfTH 2023, held in Bangkok, Thailand on October 6-7, 2023.\n    Find out more and register for updates for our next conference at https://rubyconfth.com/\n  video_provider: \"youtube\"\n  video_id: \"L01VKh78cnQ\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2026/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/rubyconfth2026\"\n  open_date: \"2025-05-26\"\n  close_date: \"2025-06-30\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2026/event.yml",
    "content": "---\nid: \"rubyconfth-2026\"\ntitle: \"RubyConf TH 2026\"\nkind: \"conference\"\nlocation: \"Bangkok, Thailand\"\ndescription: |-\n  Jan 31-Feb 1, 2026. RubyConf TH is back. Novotel Sukhumvit 20 Bangkok, Thailand\nstart_date: \"2026-01-31\"\nend_date: \"2026-02-01\"\npublished_at: \"2026-02-20\"\nchannel_id: \"UCwIhYV_sPTzvjk6B6EUnf1g\"\nyear: 2026\nbanner_background: \"#0F172B\"\nfeatured_background: \"#0F172B\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubyconfth.com\"\ntickets_url: \"https://www.eventpop.me/e/80284/rubyconf-th-2026\"\ncoordinates:\n  latitude: 13.731772641321976\n  longitude: 100.56438420036864\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2026/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Bill Sendewicz\n    - Roland Lopez\n    - Matt Mayer\n    - Dan Itsara\n    - Michael Kohl\n    - Keith Bennett\n\n  organisations:\n    - Bangkok.rb\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2026/schedule.yml",
    "content": "# Schedule: RubyConf TH 2026\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2026-01-31\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:00\"\n        end_time: \"09:10\"\n        slots: 1\n\n      - start_time: \"09:10\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"10:50\"\n        slots: 1\n        items:\n          - Coffee break\n\n      - start_time: \"10:50\"\n        end_time: \"11:25\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Buffet lunch\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Typesense Workshop\n\n      - start_time: \"14:00\"\n        end_time: \"14:35\"\n        slots: 1\n\n      - start_time: \"14:35\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:35\"\n        slots: 1\n        items:\n          - Coffee break\n\n      - start_time: \"15:35\"\n        end_time: \"16:10\"\n        slots: 1\n\n      - start_time: \"16:10\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"23:59\"\n        slots: 1\n        items:\n          - title: \"Official Party @ The Deck\"\n            description: |-\n              Join us for the official party at the end of day 1! All ticketholders are welcome to a relaxed evening of food, drinks, and conversation at The Deck, just a five minute walk from the conference venue.\n\n  - name: \"Day 2\"\n    date: \"2026-02-01\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:10\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:10\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"10:50\"\n        slots: 1\n        items:\n          - Coffee break\n\n      - start_time: \"10:50\"\n        end_time: \"11:25\"\n        slots: 1\n\n      - start_time: \"11:25\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Buffet lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:35\"\n        slots: 1\n\n      - start_time: \"14:35\"\n        end_time: \"15:05\"\n        slots: 1\n\n      - start_time: \"15:05\"\n        end_time: \"15:35\"\n        slots: 1\n        items:\n          - Coffee break\n\n      - start_time: \"15:35\"\n        end_time: \"16:10\"\n        slots: 1\n\n      - start_time: \"16:10\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:15\"\n        slots: 1\n        items:\n          - Closing remarks\n\ntracks:\n  - name: \"Main Track\"\n    color: \"#DC2626\"\n    text_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2026/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      level: 1\n      sponsors:\n        - name: \"ODDS\"\n          website: \"https://odds.team\"\n          slug: \"odds\"\n          logo_url: \"https://rubyconfth.com/images/sponsors/vector/odds.svg\"\n        - name: \"Typesense\"\n          website: \"https://typesense.org\"\n          slug: \"typesense\"\n          logo_url: \"https://rubyconfth.com/images/sponsors/vector/typesense.svg\"\n        - name: \"Sidekiq\"\n          website: \"https://sidekiq.org\"\n          slug: \"sidekiq\"\n          logo_url: \"https://rubyconfth.com/images/sponsors/vector/sidekiq.svg\"\n        - name: \"Omise\"\n          website: \"https://omise.co\"\n          slug: \"omise\"\n          logo_url: \"https://rubyconfth.com/images/sponsors/vector/omise.svg\"\n        - name: \"Thamtech\"\n          website: \"https://youtube.com/@tinothamtech\"\n          slug: \"thamtech\"\n          logo_url: \"https://rubyconfth.com/images/sponsors/vector/thamtech.svg\"\n        - name: \"Eventpop\"\n          website: \"https://www.eventpop.me\"\n          slug: \"eventpop\"\n          logo_url: \"https://rubyconfth.com/images/sponsors/vector/eventpop.svg\"\n        - name: \"Avo\"\n          website: \"https://avohq.io\"\n          slug: \"avo\"\n          logo_url: \"https://rubyconfth.com/images/sponsors/vector/avo.svg\"\n    - name: \"Organizer\"\n      level: 2\n      sponsors:\n        - name: \"Bangkok.rb\"\n          website: \"https://bangkokrb.org\"\n          slug: \"bangkokrb\"\n          logo_url: \"https://bangkokrb.org/images/ruby-tuesday.svg\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2026/venue.yml",
    "content": "---\nname: \"Novotel Bangkok Sukhumvit 20\"\ndescription: |-\n  Novotel Bangkok: you can't make more central in Bangkok\naddress:\n  street: \"19/9 Sukhumvit 20 Alley\"\n  city: \"Bangkok\"\n  region: \"Bangkok\"\n  postal_code: \"10110\"\n  country: \"Thailand\"\n  country_code: \"TH\"\n  display: \"Novotel Bangkok Sukhumvit 20, Benjasari Ballroom\"\ncoordinates:\n  latitude: 13.731772641321976\n  longitude: 100.56438420036864\nmaps:\n  google: \"https://maps.app.goo.gl/fwP3gCHcCZRVJ8nz7\"\n\nlocations:\n  - name: \"The Deck Bangkok\"\n    kind: \"Party Location\"\n    address:\n      street: \"15 Sukhumvit 20 Alley\"\n      city: \"Bangkok\"\n      region: \"Khlong Toei\"\n      postal_code: \"10110\"\n      country: \"Thailand\"\n      country_code: \"TH\"\n      display: \"15 Sukhumvit 20 Alley, Khlong Toei, Bangkok 10110, Thailand\"\n    coordinates:\n      latitude: 13.7321766\n      longitude: 100.5639919\n    maps:\n      google: \"https://maps.app.goo.gl/n453PcTQ4wRvD3Bu7\"\n      apple:\n        \"https://maps.apple.com/place?address=Sukhumvit%20Soi%2020%0AKhlong%20Toei,%20Khlong%20Toei%0ABangkok%2010110%0AThailand&coordinate=13.732168,100.564105&name=The%20Deck%20B\\\n        angkok&place-id=I6A20E26BB030AE68&map=h\"\n"
  },
  {
    "path": "data/rubyconfth/rubyconfth-2026/videos.yml",
    "content": "---\n- id: \"opening-address-bangkok-rb\"\n  title: \"Opening Address - Bangkok.rb\"\n  raw_title: \"RubyConfTH 2026 - Opening Address - Bangkok.rb\"\n  date: \"2026-01-31\"\n  description: \"\"\n  event_name: \"RubyConf TH 2026\"\n  speakers:\n    - Bill Sendewicz\n  slug: \"opening-address-bangkok-rb-rubyconf-th-2026\"\n  video_id: \"opening-address-bangkok-rb\"\n  video_provider: \"not_recorded\"\n\n- id: \"irina-nazarova-rubyconfth-2026\"\n  title: \"Opening Keynote: Startups on Rails in 2026\"\n  raw_title: \"RubyConfTH 2026 - Opening Keynote: Startups on Rails in 2026\"\n  speakers:\n    - Irina Nazarova\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-01-31\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"irina-nazarova-rubyconfth-2026\"\n  video_provider: \"youtube\"\n  video_id: \"8Ak3NbvtS7w\"\n  slides_url: \"https://sfruby.com/rubyconfth/\"\n\n- id: \"15-years-of-rails-with-domain-driven-design-lessons-learnt\"\n  title: \"15 Years of Rails With Domain Driven Design - Lessons Learnt\"\n  raw_title: \"RubyConfTH 2026 - 15 Years of Rails With Domain Driven Design - Lessons Learnt\"\n  speakers:\n    - Andrzej Krzywda\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-01-31\"\n  published_at: \"2026-02-20\"\n  description: |-\n    This talk presents what is the current problem with Rails apps from AI agents perspective. The lack of modularity in Rails apps make agents confused - the context is too big for them. The solution is making a big number of small modules with well defined interfaces.\n\n    Domain Driven Design (DDD) is a technique which, together with event-driven and CQRS results in smaller modules.\n\n    The app I am presenting has 50 small modules, composed via commands and events.\n\n    I am also presenting an algorithm which helps reducing the size of ActiveRecord models - by gradually moving their responsibilities to read models and aggregates.\n\n    Look at this repo to see the modularity mentioned - https://github.com/RailsEventStore/ecommerce\n  slug: \"15-years-of-rails-with-domain-driven-design-lessons-learnt-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"g5hcMxAs4cU\"\n  slides_url: \"https://speakerdeck.com/andrzejkrzywda/15-years-with-rails-and-ddd-ai-edition\"\n  additional_resources:\n    - name: \"RailsEventStore/ecommerce\"\n      type: \"repo\"\n      url: \"https://github.com/RailsEventStore/ecommerce\"\n\n- id: \"dont-rewrite-your-framework\"\n  title: \"Don't Rewrite Your Framework\"\n  raw_title: \"RubyConfTH 2026 - Don't Rewrite Your Framework\"\n  speakers:\n    - Vinícius Alonso\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-01-31\"\n  published_at: \"2026-02-20\"\n  description: |-\n    Have you ever seen someone rewriting the framework during a code review? After some time studying the Ruby on Rails documentation and doing some research on Reddit, I found some interesting features that are often not known by developers.\n  slug: \"dont-rewrite-your-framework-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"jVnGiOhNdOA\"\n  slides_url: \"https://speakerdeck.com/viniciusalonso/dont-rewrite-your-framework-rubyconfth\"\n\n- id: \"solid-golden-hammer\"\n  title: \"SOLID Golden Hammer\"\n  raw_title: \"RubyConfTH 2026 - SOLID Golden Hammer\"\n  speakers:\n    - Arkadiy Zabazhanov\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-01-31\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"solid-golden-hammer-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"HF6MWLwdSnk\"\n  slides_url: \"https://docs.google.com/presentation/d/147vcrJoi9Osthg7NpodmQ0hjDo_6MCn3BCZJ7Iq8IdM/edit?usp=sharing\"\n\n- id: \"breaking-rules-to-ship-products-a-beginners-rails-journey\"\n  title: \"Breaking Rules to Ship Products: A Beginner's Rails Journey\"\n  raw_title: \"RubyConfTH 2026 - Breaking Rules to Ship Products: A Beginner's Rails Journey\"\n  speakers:\n    - Onur Ozer\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-01-31\"\n  published_at: \"2026-02-20\"\n  description: |-\n    After a long career in marketing, this is my personal story of learning Ruby and Rails with the goal of building SaaS businesses, and the lessons I had to learn along the way.\n  slug: \"breaking-rules-to-ship-products-a-beginners-rails-journey-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"WFVokjTblC0\"\n  slides_url: \"https://speakerdeck.com/onurozer/breaking-rules-to-ship-products-a-beginners-rails-journey\"\n\n- id: \"operating-rails-what-about-after-you-deploy\"\n  title: \"Operating Rails: What About After You Deploy?\"\n  raw_title: \"RubyConfTH 2026 - Operating Rails: What About After You Deploy?\"\n  speakers:\n    - André Arko\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-01-31\"\n  published_at: \"2026-02-20\"\n  description: |-\n    There are a million tutorials out there showing you how to build a blog in Rails (in just 15 minutes!) and how to deploy that Rails app to some cloud provider (in just 5 minutes!), but what about after that first half-hour? When the guide says \"this tutorial of course isn't production ready\", what actually is production-ready? Let's talk about operating Rails apps in production.\n  slug: \"operating-rails-what-about-after-you-deploy-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"Zo7xVGZCSEA\"\n  slides_url: \"https://speakerdeck.com/indirect/operating-rails-what-about-after-you-deploy-df2100d4-10b0-4ac5-a15b-97c53da10832\"\n\n- id: \"if-you-didnt-record-it-it-didnt-happen-practical-observability-for-rails\"\n  title: \"If You Didn't Record It It Didn't Happen: Practical Observability for Rails\"\n  raw_title: \"RubyConfTH 2026 - If You Didn't Record It It Didn't Happen: Practical Observability for Rails\"\n  speakers:\n    - Aaron Cruz\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-01-31\"\n  published_at: \"2026-02-20\"\n  description: |-\n    Your Rails app is in production. A user says it's slow. Another says a feature just broke. You need answers fast. This talk shows how to make your app observable: capturing metrics, logs, and traces, then feeding them into open source monitoring tools. You'll see what's worth recording, how to avoid drowning in noise, and how to set alerts that lead straight to the cause. Walk away ready to see inside your app when it matters most and fix problems before everything is on fire.\n  slug: \"if-you-didnt-record-it-it-didnt-happen-practical-observability-for-rails-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"u-cIr4MKWtQ\"\n  slides_url: \"https://speakerdeck.com/pferdefleisch/if-you-didnt-record-it-it-didnt-happen-practical-observability-for-rails\"\n\n- id: \"ruby-in-the-8-bit-world-a-small-mruby-vm-for-the-zilog-z80\"\n  title: \"Ruby in the 8 Bit World - A Small mruby VM for the Zilog Z80\"\n  raw_title: \"RubyConfTH 2026 - Ruby in the 8 Bit World - A Small mruby VM for the Zilog Z80\"\n  speakers:\n    - Yuji Yokoo\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-01-31\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"ruby-in-the-8-bit-world-a-small-mruby-vm-for-the-zilog-z80-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"T3b86TLK9zk\"\n  additional_resources:\n    - name: \"yujiyokoo/mrubyz\"\n      type: \"repo\"\n      url: \"https://codeberg.org/yujiyokoo/mrubyz\"\n\n- id: \"marco-roth-rubyconfth-2026\"\n  title: \"Closing Keynote: Herb to ReActionView: A New Foundation for the View Layer\"\n  raw_title: \"RubyConfTH 2026 - Closing Keynote: Herb to ReActionView: A New Foundation for the View Layer\"\n  speakers:\n    - Marco Roth\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-01-31\"\n  published_at: \"2026-02-20\"\n  description: |-\n    This keynote is an overview of how Herb came to be, what Herb can do for you today, and what the future with ReActionView might look like and how Herb could enable it.\n  slug: \"marco-roth-rubyconfth-2026\"\n  video_provider: \"youtube\"\n  video_id: \"rZT9ex3w9bI\"\n  slides_url: \"https://speakerdeck.com/marcoroth/herb-to-reactionview-a-new-foundation-for-the-view-layer-at-rubyconf-th-2026-bangkok-thailand\"\n\n- id: \"ridhwana-khan-rubyconfth-2026\"\n  title: \"Opening Keynote: The Architecture of Understanding: Building Clarity in Complex Ruby Systems\"\n  raw_title: \"RubyConfTH 2026 - Opening Keynote: The Architecture of Understanding: Building Clarity in Complex Ruby Systems\"\n  speakers:\n    - Ridhwana Khan\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-02-01\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"ridhwana-khan-rubyconfth-2026\"\n  video_provider: \"youtube\"\n  video_id: \"Op5GunxvRKU\"\n  slides_url: \"https://www.slideshare.net/slideshow/the-architecture-of-understanding-how-to-build-clarity-in-complex-ruby-systems/286094300\"\n\n- id: \"building-a-rails-engine-from-scratch-lessons-from-active-storage-dashboard\"\n  title: \"Building a Rails Engine From Scratch: Lessons From Active Storage Dashboard\"\n  raw_title: \"RubyConfTH 2026 - Building a Rails Engine From Scratch: Lessons From Active Storage Dashboard\"\n  speakers:\n    - Giovanni Panasiti\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-02-01\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"building-a-rails-engine-from-scratch-lessons-from-active-storage-dashboard-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"BM5jbduE52Y\"\n  slides_url: \"https://drive.google.com/file/d/1rfbrNXawFuwtzri7ZN4xwXj-FbxteDZ-/view?usp=sharing\"\n\n- id: \"making-canvas-prints-from-artwork-photos-pipeline-constraints-upscaling-models\"\n  title: \"Making Canvas Prints From Artwork Photos: Pipeline Constraints & Upscaling Models\"\n  raw_title: \"RubyConfTH 2026 - Making Canvas Prints From Artwork Photos: Pipeline Constraints & Upscaling Models\"\n  speakers:\n    - Alex Timofeev\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-02-01\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"making-canvas-prints-from-artwork-photos-pipeline-constraints-upscaling-models-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"dAhSOlcgIaU\"\n  slides_url: \"https://speakerdeck.com/querystring/making-canvas-prints-from-artwork-photos-pipeline-constraints-and-upscaling-models\"\n\n- id: \"cell-based-architecture-with-ruby-on-rails\"\n  title: \"Cell-Based Architecture With Ruby on Rails\"\n  raw_title: \"RubyConfTH 2026 - Cell-Based Architecture With Ruby on Rails\"\n  speakers:\n    - Roonglit Chareonsupkul\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-02-01\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"cell-based-architecture-with-ruby-on-rails-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"vySzceQGhiw\"\n  slides_url: \"https://drive.google.com/file/d/1wHZbt0jXLVBLRgm_t28lAk05RiEcRqIe/view\"\n\n- id: \"metaprogramming-isnt-real-it-cant-hurt-you\"\n  title: \"Metaprogramming Isn't Real, It Can't Hurt You\"\n  raw_title: \"RubyConfTH 2026 - Metaprogramming Isn't Real, It Can't Hurt You\"\n  speakers:\n    - Masafumi Okura\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-02-01\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"metaprogramming-isnt-real-it-cant-hurt-you-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"-n9Rj8nO74o\"\n  slides_url: \"https://speakerdeck.com/okuramasafumi/metaprogramming-isnt-real-it-cant-hurt-you\"\n\n- id: \"from-9-to-5-to-pull-requests-sustainable-open-source-contribution\"\n  title: \"From 9-to-5 to Pull Requests: Sustainable Open Source Contribution\"\n  raw_title: \"RubyConfTH 2026 - From 9-to-5 to Pull Requests: Sustainable Open Source Contribution\"\n  speakers:\n    - Joshua Young\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-02-01\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"from-9-to-5-to-pull-requests-sustainable-open-source-contribution-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"KUrnmarNkVQ\"\n  slides_url: \"https://drive.google.com/file/d/1oG2DvCz35YAhojwaFgSBFQYkJLdeIXG4/view?usp=sharing\"\n\n- id: \"simulation-testing-for-background-jobs\"\n  title: \"Simulation Testing for Background Jobs\"\n  raw_title: \"RubyConfTH 2026 - Simulation Testing for Background Jobs\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-02-01\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"simulation-testing-for-background-jobs-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"CacDguC_l0s\"\n\n- id: \"what-software-engineers-can-learn-from-the-chernobyl-disaster\"\n  title: \"What Software Engineers Can Learn From the Chernobyl Disaster\"\n  raw_title: \"RubyConfTH 2026 - What Software Engineers Can Learn From the Chernobyl Disaster\"\n  speakers:\n    - Frederick Cheung\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-02-01\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"what-software-engineers-can-learn-from-the-chernobyl-disaster-rubyconf-th-2026\"\n  video_provider: \"youtube\"\n  video_id: \"BHc8kWh8_AY\"\n  slides_url: \"https://drive.google.com/file/d/1_nzOoetrErKKxTPD-i1yUa6kTSeXpfwv/view\"\n\n- id: \"carmine-paolino-rubyconfth-2026\"\n  title: \"Closing Keynote: Ruby Is the Best Language for Building AI Web Apps\"\n  raw_title: \"RubyConfTH 2026 - Closing Keynote: Ruby Is the Best Language for Building AI Web Apps\"\n  speakers:\n    - Carmine Paolino\n  event_name: \"RubyConf TH 2026\"\n  date: \"2026-02-01\"\n  published_at: \"2026-02-20\"\n  description: \"\"\n  slug: \"carmine-paolino-rubyconfth-2026\"\n  video_provider: \"youtube\"\n  video_id: \"fAHif8MNCfw\"\n  slides_url: \"https://talks.paolino.me/rubyconfth-2026\"\n"
  },
  {
    "path": "data/rubyconfth/series.yml",
    "content": "---\nname: \"RubyConf TH\"\nwebsite: \"https://rubyconfth.com\"\ntwitter: \"rubyconfth\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"TH\"\nyoutube_channel_name: \"rubyconfth\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCwIhYV_sPTzvjk6B6EUnf1g\"\naliases:\n  - RubyConf Thailand\n  - Ruby Conf TH\n  - Ruby Conf Thailand\n"
  },
  {
    "path": "data/rubyday/rubyday-2011/event.yml",
    "content": "---\nid: \"rubyday-2011\"\ntitle: \"rubyday 2011\"\nkind: \"conference\"\nlocation: \"Assago, Italy\"\ndescription: |-\n  Vogliamo diffondere la conoscenza sull'ecosistema di Ruby in Italia. Rubyday si terrà il 10 giugno 2011 al Centro Congressi Milanofiori.\nstart_date: \"2011-06-10\"\nend_date: \"2011-06-10\"\nyear: 2011\nbanner_background: \"#3A3A3A\"\nfeatured_background: \"#EAEAEA\"\nfeatured_color: \"#3A3A3A\"\nwebsite: \"https://web.archive.org/web/20161025231207/http://2011.rubyday.it/\"\ncoordinates:\n  latitude: 45.4090982\n  longitude: 9.12712\n"
  },
  {
    "path": "data/rubyday/rubyday-2011/schedule.yml",
    "content": "---\n# rubyday 2011 - Conference Schedule\n# Source: https://web.archive.org/web/20200809103350/http://2011.rubyday.it/agenda.html\n# Conference date: 2011-06-11\n\ndays:\n  - name: \"Day 1\"\n    date: \"2011-06-11\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registrazione\n\n      - start_time: \"09:00\"\n        end_time: \"09:40\"\n        slots: 1\n\n      - start_time: \"09:40\"\n        end_time: \"10:10\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"10:10\"\n        end_time: \"11:10\"\n        slots: 2\n\n      - start_time: \"11:10\"\n        end_time: \"12:10\"\n        slots: 2\n\n      - start_time: \"12:10\"\n        end_time: \"13:10\"\n        slots: 2\n\n      - start_time: \"13:10\"\n        end_time: \"14:10\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:10\"\n        end_time: \"15:10\"\n        slots: 2\n\n      - start_time: \"15:10\"\n        end_time: \"16:10\"\n        slots: 2\n\n      - start_time: \"16:10\"\n        end_time: \"17:10\"\n        slots: 2\n\n      - start_time: \"17:10\"\n        end_time: \"18:10\"\n        slots: 2\n\n      - start_time: \"18:10\"\n        end_time: \"18:30\"\n        slots: 1\n        items:\n          - Saluti finali e distribuzione premi\n\ntracks:\n  - name: \"Track 1 (Ruby Mine)\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n\n  - name: \"Track 2 (Ruby Space)\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2011/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Gold\"\n      description: |-\n        Gold sponsors (€1,000 contribution). Companies receive visibility on the website, public acknowledgments at the start and end of the event, ability to collect participant CVs, and ability to distribute promotional materials during the event.\n      level: 1\n      sponsors:\n        - name: \"Mikamai\"\n          website: \"https://mikamai.com/\"\n          slug: \"mikamai\"\n          logo_url: \"\"\n\n        - name: \"XPeppers\"\n          website: \"https://www.xpeppers.com/\"\n          slug: \"xpeppers\"\n          logo_url: \"\"\n\n    - name: \"Silver\"\n      description: |-\n        Silver sponsors (€500 contribution). Companies receive visibility on the website, public acknowledgments at the start and end of the event, and ability to collect participant CVs.\n      level: 2\n      sponsors:\n        - name: \"Unbit\"\n          website: \"https://unbit.it/\"\n          slug: \"unbit\"\n          logo_url: \"\"\n\n        - name: \"The Fool\"\n          website: \"https://www.thefool.it/\"\n          slug: \"the-fool\"\n          logo_url: \"\"\n\n    - name: \"Bronze\"\n      description: |-\n        Bronze sponsors (€200 contribution). Companies receive visibility on the website and public acknowledgments at the start and end of the event.\n      level: 3\n      sponsors:\n        - name: \"The Pragmatic Bookshelf\"\n          website: \"https://pragprog.com/\"\n          slug: \"pragmatic-bookshelf\"\n          logo_url: \"\"\n\n        - name: \"JetBrains\"\n          website: \"https://www.jetbrains.com/\"\n          slug: \"jetbrains\"\n          logo_url: \"\"\n\n    - name: \"Media\"\n      description: |-\n        Media sponsors.\n      level: 4\n      sponsors:\n        - name: \"O'Reilly\"\n          website: \"https://oreilly.com/\"\n          slug: \"oreilly\"\n          logo_url: \"\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2011/videos.yml",
    "content": "---\n# rubyday 2011 - Conference videos\n# Source: https://web.archive.org/web/20200809103350/http://2011.rubyday.it/agenda.html\n# Conference date: 2011-06-11\n\n- id: \"rubyday-2011-giovanni-intini\"\n  title: \"Presentazione RubyDay.it, la storia della comunità Ruby in Italia\"\n  raw_title: \"RubyDay 2011 - Giovanni Intini - Presentazione RubyDay.it, la storia della comunità Ruby in Italia\"\n  speakers:\n    - Giovanni Intini\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  published_at: \"2011-06-11\"\n  description: |-\n    Opening presentation about rubyday.it and the history of the Ruby community in Italy.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-giovanni-intini\"\n  kind: \"keynote\"\n\n- id: \"rubyday-2011-francesco-vollero\"\n  title: \"The Aeolus Project\"\n  raw_title: \"RubyDay 2011 - Francesco Vollero - The Aeolus Project\"\n  speakers:\n    - Francesco Vollero\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 1 (Ruby Mine)\"\n  published_at: \"2011-06-11\"\n  description: |\n    Il mondo dei cloud provider è veramente vario e cresce ogni giorno di più il numero di provider che offrono questi servizi. La scelta è infinitamente varia, per rispondere alla necessità più disparate per l'utente medio. Aeolus Project nasce per offrire un sistema di gestione centralizzato dei diversi provider cloud per grandi società. Infatti questo progetto si propone come un sistema completo di gestione delle immagini di macchine virtuali, eseguirle nella loro infrastruttura interna (es. VMware vSphere, RHEV) e nello stesso tempo copiare/eseguire/gestire queste immagini virtuali in diversi cloud hosters (es. Amazon EC2, Rackspace, IBM Smart Business Cloud, Microsoft Azure, etc). Potrebbe apparire un'idiozia al primo sguardo ma è una opzione nel caso in cui, supponiamo, amazon ec2 va giù e possiamo avere la stessa istanza della macchina virtuale (diciamo) su Rackspace e continuare a lavorare da lì. Aeolus si occupa di tutto ciò che riguarda la conversione/trasferimento/etc automaticamente. Vi starete chiedendo, che ci azzecca questo con il Ruby day? Beh, ci azzecca molto, poiché molte parti di questo progetto sono in Ruby. Tipo? Uno dei componenti più importanti, deltacloud è scritto in Sinatra, parti della gestione delle code è scritto in Ruby e la nostra interfaccia UI è scritta in Rails.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-francesco-vollero\"\n  language: \"Italian\"\n\n- id: \"rubyday-2011-gian-carlo-pace\"\n  title: \"Ruby on Rails survival guide of an aged Java developer\"\n  raw_title: \"RubyDay 2011 - Gian Carlo Pace - Ruby on Rails survival guide of an aged Java developer\"\n  speakers:\n    - Gian Carlo Pace\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 2 (Ruby Space)\"\n  published_at: \"2011-06-11\"\n  description: |\n    Switching to ruby language and to the rails framework can be puzzling if you come from a deep java background knowledge. \"How can I...? How do I...?\" are the most common question during the ramp up period of the learning curve and there is a good chance to get lost in the big \"cave of the gems\". In this talk I'll try to explain the tips and tricks a java developer should know to avoid some common pitfalls and deliver his first rails project on time.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-gian-carlo-pace\"\n\n- id: \"rubyday-2011-antonio-carpentieri\"\n  title: \"Varnish e caching di applicazioni Rails\"\n  raw_title: \"RubyDay 2011 - Antonio Carpentieri - Varnish e caching di applicazioni Rails\"\n  speakers:\n    - Antonio Carpentieri\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 1 (Ruby Mine)\"\n  published_at: \"2011-06-11\"\n  description: |\n    \"Varnish Cache is an open-source web application accelerator. You install it in front of any server that speaks HTTP and you can configure it to cache the contents.\" Come utilizzare e configurare Varnish davanti a Rails 2.3.x e Rails 3.0.x per far lavorare le tue macchine solo quando è necessario. Vedremo come evitare i più comuni pitfall ed ottenere un caching efficace, a partire dall' esperienza fatta nell'integrazione di Varnish su una applicazione web in Rails attualmente in produzione. Vedremo anche quali sono i risultati in termini di performance e carico sulle nostre macchine.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-antonio-carpentieri\"\n\n- id: \"rubyday-2011-simone-damico\"\n  title: \"MacRuby\"\n  raw_title: \"RubyDay 2011 - Simone D'Amico - MacRuby\"\n  speakers:\n    - Simone D'Amico\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 2 (Ruby Space)\"\n  published_at: \"2011-06-11\"\n  description: |\n    Introduzione e presentazione di MacRuby, implementazione di ruby 1.9 per Mac Os X. Si vedrà come, e con quali tecnologie, MacRuby s'integra in Cocoa, il framework di riferimento per lo sviluppo su piattaforma Apple. Si vedranno anche i requisiti e le procedure necessarie per pubblicare, ed eventualmente vendere, la propria applicazione ruby sull'App Store.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-simone-damico\"\n  language: \"Italian\"\n\n- id: \"rubyday-2011-marco-borromeo\"\n  title: \"Analisi statica per un linguaggio dinamico\"\n  raw_title: \"RubyDay 2011 - Marco Borromeo - Analisi statica per un linguaggio dinamico\"\n  speakers:\n    - Marco Borromeo\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 1 (Ruby Mine)\"\n  published_at: \"2011-06-11\"\n  description: |\n    Tutti sappiamo che Ruby è definito un linguaggio \"dinamico\", e accostarlo alla parola \"statico\" fa un pò impressione. Ma ci sono casi dove analizzare staticamente il nostro codice può far solo bene: l'analisi statica ci permette di identificare velocemente blocchi di codice ripetuti o molto simili tra loro, verificare la copertura dei tests, eventuali problemi sul design del codice, trovare files che cambiano spesso e misurare la complessità media del codice. Tenere costantemente monitorati questi dati durante lo sviluppo ci permette di prevenire situazioni dove diventa difficile mantenere il codice, fare bugfixing o introdurre nuove funzionalità. Durante il talk verranno esaminati i principali tool a disposizione per gestire l'analisi statica di codice Ruby, con esempi di refactoring di codice reale a partire dai dati emersi dalle analisi.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-marco-borromeo\"\n  language: \"Italian\"\n\n- id: \"rubyday-2011-alessandro-cinelli-sandro-paganotti-alberto-barilla\"\n  title: \"Symfony2 and RoR3 friends for an hour\"\n  raw_title: \"RubyDay 2011 - Alessandro Cinelli, Sandro Paganotti, Alberto Barillà - Symfony2 and RoR3 friends for an hour\"\n  speakers:\n    - Alessandro Cinelli\n    - Sandro Paganotti\n    - Alberto Barillà\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 2 (Ruby Space)\"\n  published_at: \"2011-06-11\"\n  description: |\n    Il talk è focalizzato sulla spiegazione delle princiapli differenze/similitudini fra questi due web framework mainstream. Adotteremo un approccio Top-Down parallelo nel quale gli aspetti di maggior importanza di entrambi i framework verranno descritti uno per uno a partire da quelli più infrastrutturali fino ad arrivare a quelli prevalentemente implementativi. Nella parte conclusiva dello speech ci focalizzeremo nel mostrare le filosofie dietro questi framework esponendo le feature più interessanti di entrambi i mondi. Tre speaker parteciperanno a questo speech. ognuno avrà un particolare ruolo: Alessandro, essendo PHP developer, si occuperà di approfondire glia spetti implementativi di syMfony2; Sandro è un hacker Ruby di vecchia data, che conosce e governa le technicalities del framework Rails; Alberto è il cialtrone (o più comunemente moderatore, nei circoli più mondani) che cercherà di fare da collante fra i due lati della forza.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-alessandro-cinelli-sandro-paganotti-alberto-barilla\"\n  language: \"Italian\"\n\n- id: \"rubyday-2011-paolo-perrotta\"\n  title: \"A Metaprogramming Spell Book for Ruby and Rails\"\n  raw_title: \"RubyDay 2011 - Paolo Perrotta - A Metaprogramming Spell Book for Ruby and Rails\"\n  speakers:\n    - Paolo Perrotta\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 1 (Ruby Mine)\"\n  published_at: \"2011-06-11\"\n  description: |\n    When I started to learn Ruby, I was awed by the code of experienced rubyists. That code was full of amazing magic tricks that I could barely understand. People called those tricks metaprogramming. With time, I found that metaprogramming sits right at the core of Ruby. To really understand Ruby, I had to understand all those scary tricks! Feeling like a sorcerer's apprentice, I set out to write a Spell Book of metaprogramming techniques. Once I'd finished the Spell Book, metaprogramming didn't seem like black magic anymore. Instead, it just felt like any other set of techniques. In this talk, I'll show you the content of my Spell Book, so that you don't have to go through the trouble of writing one yourself.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-paolo-perrotta\"\n\n- id: \"rubyday-2011-andrea-schiavini\"\n  title: \"Webby: ASCII alchemy for quick website authoring\"\n  raw_title: \"RubyDay 2011 - Andrea Schiavini - Webby: ASCII alchemy for quick website authoring\"\n  speakers:\n    - Andrea Schiavini\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 2 (Ruby Space)\"\n  published_at: \"2011-06-11\"\n  description: |\n    Webby allows to quickly manage a small website by combining the contents of a page with a layout to produce HTML. It supports different templating engines (ERB, Textile, Markdown, HAML, SASS), rake tasks to build the site and deploy it to a server, templates to quickly build resources like blog posts and much more. Introduzione a webby, installazione e dimostrazione del suo funzionamento per la creazione di un sito personale utilizzando haml e sass. Mostreremo anche come sia possibile usare i siti generati da Webby con Amazon S3. Opzionale: qualche accenno alla web typography con 960 GS.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-andrea-schiavini\"\n\n- id: \"rubyday-2011-matteo-collina-daniele-bottillo\"\n  title: \"Progettare e sviluppare mobile web applications utilizzando Mockup, Sencha Touch e Sinatra\"\n  raw_title: \"RubyDay 2011 - Matteo Collina, Daniele Bottillo - Progettare e sviluppare mobile web applications utilizzando Mockup, Sencha Touch e Sinatra\"\n  speakers:\n    - Matteo Collina\n    - Daniele Bottillo\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 1 (Ruby Mine)\"\n  published_at: \"2011-06-11\"\n  description: |\n    Mavigex è un'azienda giovane e dinamica che propone soluzioni mobili e interattive all' avanguardia. La presenza di molteplici piattaforme nel mercato degli smartphone ha portato a scegliere di sviluppare mobile applications con un approccio web-based: HTML5, CSS3 e il framework JavaScript Sencha Touch. Tra i vari linguaggi server-side, verrà mostrato come Ruby e il framework Sinatra siano la scelta che si integra meglio con questo approccio. Partendo da semplici mockup, durante la presentazione verrà illustrato il processo di sviluppo di queste mobile web applications mostrando la soluzione di un problema specifico, quale la fruizione di recensioni geolocalizzate. Verrà presentato il progetto dell'interazione tra l' applicazione e il suo backend, poi verranno illustrati brevemente i framework Sencha Touch e Sinatra. L'applicazione sviluppata verrà poi distribuita su un'infrastruttura di cloud computing.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-matteo-collina-daniele-bottillo\"\n  language: \"Italian\"\n\n- id: \"rubyday-2011-luca-guidi\"\n  title: \"Minegems: Hosting privato di gemme\"\n  raw_title: \"RubyDay 2011 - Luca Guidi - Minegems: Hosting privato di gemme\"\n  speakers:\n    - Luca Guidi\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 2 (Ruby Space)\"\n  published_at: \"2011-06-11\"\n  description: |\n    L'ecosistema Ruby si è notevolmente evoluto: RVM, Bundler ed un nuovo RubyGems.org hanno reso più agevole lavorare con le gemme. Sfortunatamente siamo ancora lontani dalla soluzione ideale: i deploy sono ancora troppo lenti, le gemme private sono distribuite tramite sistemi non standardizzati, i plugin Rails non possono essere facilmente distribuiti. In questo talk verrà spiegato come è stato sviluppato un servizio di hosting privato di gemme.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-luca-guidi\"\n  language: \"Italian\"\n\n- id: \"rubyday-2011-simone-carletti\"\n  title: \"RSpec best practices\"\n  raw_title: \"RubyDay 2011 - Simone Carletti - RSpec best practices\"\n  speakers:\n    - Simone Carletti\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 1 (Ruby Mine)\"\n  published_at: \"2011-06-11\"\n  description: |\n    Il testing è da sempre uno dei pilastri dello sviluppo in Ruby. Ruby è stato uno dei primi linguaggi ad avere un framework completo per lo unit testing direttamente all'interno della standard library. Tuttavia, questo non ha impedito la nascita di nuovi strumenti e librerie per il testing e continuous integration. Questo talk prende in esame RSpec, una delle alternative più mature e diffuse a Test::Unit, la libreria di testing distribuita nella Ruby Standard Library. RSpec è una libreria elegante e completa, in grado di combinare l'importanza di scrivere test \"leggibili\" con l'obiettivo fondamentale di riprodurre e validare al meglio l'efficacia del nostro programma. Vedremo come usare al meglio RSpec, quali sono i vantaggi rispetto a Test::Unit e come scrivere test in modo efficace ed efficiente. Non mancheranno accenni al testing in generale, altre librerie come Cucumber, Shoulda, Mocha, RR e all'uso di RSpec con Rails ed altri framework Ruby.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-simone-carletti\"\n  slides_url: \"https://speakerdeck.com/simonecarletti/rubyday-2011-rspec-best-practices\"\n  language: \"Italian\"\n\n- id: \"rubyday-2011-luca-mearelli\"\n  title: \"To batch or not to batch\"\n  raw_title: \"RubyDay 2011 - Luca Mearelli - To batch or not to batch\"\n  speakers:\n    - Luca Mearelli\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 2 (Ruby Space)\"\n  published_at: \"2011-06-11\"\n  description: |\n    Sviluppare un'applicazione web sembra essere diventato molto semplice da quando abbiamo framework come rails o sinatra, ma la realtà è un po' più complessa di quello che sembra :) Qualunque applicazione dovrà fare una o più di queste operazioni, o operazioni simili: mandare email, generare documenti o esportazioni dei dati, ridimensionare o trasformare foto, interrogare web service remoti. Tutte queste sono troppo lente e pesanti per essere eseguite nel normale ciclo di richiesta/risposta. Non potendo eseguire certe attività in poche frazioni di secondo, l'unica possibilità che abbiamo è farle al di fuori dell'applicazione, utilizzando un meccanismo di esecuzione asincrono. Quando l'applicazione si trova a dover eseguire un'attività \"lenta\", ne potrà lanciare l'esecuzione e potrà proseguire a rispondere all'utente senza doverne aspettare la conclusione. Nei casi in cui sia necessario utilizzare il risultato dell'operazione asincrona, si farà in modo che questi possano essere recuperati con facilità. Questo permette all'applicazione di rimanere rapida e reattiva alle richieste degli utenti e rende più facile farla scalare. Oltre alle operazioni \"lente\" richieste dagli utente, è spesso necessario eseguire attività di manutenzione programmata (ad esempio: la pulizia delle sessioni), vedremo dunque come alcuni strumenti permettono di programmare nel tempo le attività asincrone, indipendentemente dalle richieste degli utenti. Esistono varie possibilità e librerie che permettono di implementare un sistema del genere e durante il talk utilizzando vari esempi, parleremo soprattutto di code, workers, & co: Resque, Delayed_job. Ma anche di crontab: Craken, Whenever. Accennando infine ad altri approcci (attuali & storici): Beanstalkd and Stalker, BackgroundRb, SQS, Nanite.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-luca-mearelli\"\n  language: \"Italian\"\n\n- id: \"rubyday-2011-sam-reghenzi\"\n  title: \"Continuous integration/deployment\"\n  raw_title: \"RubyDay 2011 - Sam Reghenzi - Continuous integration/deployment\"\n  speakers:\n    - Sam Reghenzi\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 1 (Ruby Mine)\"\n  published_at: \"2011-06-11\"\n  description: |-\n    Continuous integration/deployment cos'è, perché è importante e come implementarlo per un progetto ruby/rails ottenendo molto con poco sforzo.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-sam-reghenzi\"\n  language: \"Italian\"\n\n- id: \"rubyday-2011-matteo-vaccari\"\n  title: \"Solid design for Rails applications\"\n  raw_title: \"RubyDay 2011 - Matteo Vaccari - Solid design for Rails applications\"\n  speakers:\n    - Matteo Vaccari\n  event_name: \"rubyday 2011\"\n  date: \"2011-06-11\"\n  track: \"Track 2 (Ruby Space)\"\n  published_at: \"2011-06-11\"\n  description: |\n    Le applicazioni Rails sono progettate secondo uno schema preciso: model, view, controller. Quando l'applicazione è giovane, i modelli le view e i controller sono di una chiarezza cristallina. Ma con l'andare del tempo, si aggiungono gli IF e le modifiche e l'originale chiarezza viene offuscata. Che fare quando la view, il modello o il controller diventano foreste impenetrabili? In questa presentazione vorrei mostrare alcune tecniche per riportare la semplicità in un'applicazione Rails, ritornando ad alcuni ben noti principi di programmazione a oggetti.\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2011-matteo-vaccari\"\n  language: \"Italian\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2014/event.yml",
    "content": "---\nid: \"PL5ImBN21eKvbQ6kH6WCAqj1QqgusGsiO0\"\ntitle: \"rubyday 2014\"\nkind: \"conference\"\nlocation: \"Verona, Italy\"\ndescription: \"\"\npublished_at: \"2014-10-23\"\nstart_date: \"2014-09-26\"\nend_date: \"2014-09-26\"\nchannel_id: \"UCkxizXigZY3iewM6dswcYzQ\"\nyear: 2014\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#333333\"\nwebsite: \"https://2014.rubyday.it\"\ncoordinates:\n  latitude: 45.4383659\n  longitude: 10.9917136\n"
  },
  {
    "path": "data/rubyday/rubyday-2014/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"paolo-montrasio-rubyday-2014\"\n  title: \"Ruby's influence over the Elixir language\"\n  raw_title: \"Ruby's influence over the Elixir language by Paolo Montrasio\"\n  speakers:\n    - Paolo Montrasio\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Elixir is a functional language that runs over the Erlang virtual machine. Despite being Erlang inside, Elixir has a Ruby-like syntax, with do...end blocks and many intentional name collisions with Ruby's keywords and library methods. This makes it easier for Rubysts to pick it up than most other functional languages with arcane syntaxes. The talk will present elements of the Elixir language. We'll also look at the Phoenix web framework and how it was influenced by Ruby on Rails.\n  video_provider: \"youtube\"\n  video_id: \"NzyqGrYyPjw\"\n\n- id: \"giacomo-bagnoli-rubyday-2014\"\n  title: \"Streamline your development environment with Docker\"\n  raw_title: \"Streamline your development environment with Docker by Giacomo Bagnoli\"\n  speakers:\n    - Giacomo Bagnoli\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    These days applications are getting more and more complex. It's becoming quite difficult to keep track of all the different components an application needs in order to function (a database, a message queueing system, a web server, a document store, a search engine, you name it.). How many times we heard 'it worked on my machine'?. In this talk we are going to explore Docker, what it is, how it works and how much it can benefit in keeping the development environment consistent. We are going to talk about Dockerfiles, best practices, tools like fig and vagrant, and finally show an example of how it applies to a ruby on rails application.\n  video_provider: \"youtube\"\n  video_id: \"mY4iErRL4zc\"\n\n- id: \"ju-liu-rubyday-2014\"\n  title: \"The Design of Everyday Ruby\"\n  raw_title: \"The Design of Everyday Ruby by Ju Liu\"\n  speakers:\n    - Ju Liu\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Everyday we read about DRY, YAGNI, TDD, SOLID, REST, SOA.. We are not only discussing about these concepts, but also we use them as canons to design, build and maintain our applications. In this talk, I want to explore the possible dangers in treating these concepts as sacred principles: in our everyday life, it pays off to treat these concepts as general guidelines, which can and should be challenged on a daily basis. In doing so, we can improve our understanding of these concepts and become better programmers.\n  video_provider: \"youtube\"\n  video_id: \"PpBaJNIkoGA\"\n\n- id: \"fabrizio-monti-rubyday-2014\"\n  title: \"Miele per le nostre API\"\n  raw_title: \"Miele per le nostre API by Fabrizio Monti, Matteo Piotto, and Federico Parodi\"\n  speakers:\n    - Fabrizio Monti\n    - Matteo Piotto\n    - Federico Parodi\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    La proliferazione delle applicazioni mobile e di quelle web basate su javascript ci porta sempre più spesso a dover realizzare interfacce API. Ci sono tanti modi per farlo, e c'è il modo giusto. Illustreremo le best practice per la costruzione di un server API RESTful in RoR che lo rendano adatto ai nostri progetti, performante e manutenibile, vedendo insieme un esempio di loro implementazione.\n  video_provider: \"youtube\"\n  video_id: \"qtJyc28ZcXE\"\n\n- id: \"giuseppe-modarelli-rubyday-2014\"\n  title: \"Ruby over Rails\"\n  raw_title: \"Ruby over Rails by Giuseppe Modarelli\"\n  speakers:\n    - Giuseppe Modarelli\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Ruby has a powerful set of libs and tools that we don't use in our day to day jobs as ruby developers. The main reason for this is because we force logic where it should not be: the template. By refactoring a simple application I'll show you how to unlock the power of Ruby and how to write code that you will love to work with in the future.\n  video_provider: \"youtube\"\n  video_id: \"LiyShndVLPo\"\n\n- id: \"matteo-papadopoulos-rubyday-2014\"\n  title: \"Frontend: riorganizzare (di nuovo) il caos\"\n  raw_title: \"Frontend: riorganizzare (di nuovo) il caos by Matteo Papadopoulos and Stefano Verna\"\n  speakers:\n    - Matteo Papadopoulos\n    - Stefano Verna\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Una delle maggiori difficoltà da affrontare per lo sviluppo di un buon front-end, in un progetto web, è l'organizzazione dello stile, tanto apparentemente banale quanto complesso da tenere pulito, riusabile e comprensibile nel tempo.\" Questo era l'incipit del talk sui css modulari che realizzai a BetterSoftware nel 2012. Il tema è sempre maledettamente attuale e, con un po' più di esperienza, con una nuova organizzazione degli assets rails e la nascita di gemme e convenzioni tipo Sass, Slim, Guard, Grunt ecc, si sono aperte nuove interessanti possibilità che permettono agli sviluppatori di organizzare bene i layout, il markup, codice per unit test, moduli css, utilizzo di mixin e stili comprensibili e mantenibili nel tempo.\n  video_provider: \"youtube\"\n  video_id: \"fUJOJY_yVXg\"\n\n- id: \"stefano-verna-rubyday-2014\"\n  title: \"More fun, less pain: a strategy for writing maintainable Rails admin backends\"\n  raw_title: \"More fun, less pain: a strategy for writing maintainable Rails admin backends by Stefano Verna\"\n  speakers:\n    - Stefano Verna\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    The Rails ecosystem features many full-fledged solutions to generate administrative interfaces (ActiveAdmin, RailsAdmin, you name it...). Although these tools come very handy to bootstrap a project quickly, they all obey the 80%-20% rule and tend to be very invasive (and incredibly painful to test). A time always comes when they start getting in the way, and all the cumulated saved time will be wasted to solve a single, trivial problem with ugly workarounds and EPIC FACEPALMS. This talk will walk through an alternative strategy for building administrative backends: we'll make use of well-known gems like Inherited Resources and Simple Form, the Rails 3.1+ template-inheritance feature and a mix of some good ol' OOP patterns to build an (arguably) more maintainable, testable and modular codebase, without sacrificing the super-DRY, declarative style ActiveAdmin and similar gems offer.\n  video_provider: \"youtube\"\n  video_id: \"e9iabDiBHZU\"\n\n- id: \"web-server-challenge-rubyday-2014\"\n  title: \"Web server challenge\"\n  raw_title: \"Web server challenge by Filippo Gangi Dino and Alessandro Fazzi\"\n  speakers:\n    - Filippo Gangi Dino\n    - Alessandro Fazzi\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Il dilemma della scelta del miglior web server per le nostre applicazioni è ricorrente nell'esperienza di uno sviluppatore Ruby/RoR. Approfondiremo meglio le caratteristiche uniche, i punti di contatto, ma soprattutto le divergenze tra i principali software utilizzati. Cercheremo di fornire una bussola con cui orientarsi e poter davvero comprendere come soddisfare l'esigenza specifica di ogni progetto.\n  video_provider: \"youtube\"\n  video_id: \"GEumX6mC4T4\"\n\n- id: \"ole-michaelis-12-tricks-rubyday-2014\"\n  title: \"Build the perfect web application with these 12 weird tricks\"\n  raw_title: \"Build the perfect web application with these 12 weird tricks by Ole Michaelis\"\n  speakers:\n    - Ole Michaelis\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Thats the dream we all share. *Building the one perfect software.* But you know the answer already, you just have to admit it: **There is no perfect software.** But I've a few tips and tricks to do better: ‘The 12 Factor App’ is a manifesto written by Adam Wiggins (co-founder of heroku) describing the perfect (cloud ready) web app. But it’s way more than that. It should be the standard way of writing apps. Because it contains some tips and tricks how to build your webapp. For example only logging to stdout or that all configuration should be done via environment variables. It’s about building robust and scalable systems. If everyone followed these 12 simple principles, we could have shared tooling across programming languages borders. Image that one pre-build logging and metrics solution. The one and only way of configuring your project. The one way to run it, successfully.\n  video_provider: \"youtube\"\n  video_id: \"kTrSHOJxeLw\"\n\n- id: \"christophe-philemotte-rubyday-2014\"\n  title: \"Safety Nets: Learn to code with confidence\"\n  raw_title: \"Safety Nets: Learn to code with confidence by Christophe Philemotte\"\n  speakers:\n    - Christophe Philemotte\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Ruby gives you a great power. As the saying goes, \"With great power there must also comes great responsibility!\" It comes at a price. We cannot afford to blow off everything when shipping. That's why it's important to put in place different strategies to help us to catch errors asap, but also to avoid the cruft long term. Like a safety net, they allow you to go forward with more confidence.\n  video_provider: \"youtube\"\n  video_id: \"cVTrY2qL-Hs\"\n\n- id: \"ole-michaelis-soa-rubyday-2014\"\n  title: \"Service Oriented Architecture for robust and scalable systems\"\n  raw_title: \"Service Oriented Architecture for robust and scalable systems by Ole Michaelis\"\n  speakers:\n    - Ole Michaelis\n  event_name: \"rubyday 2014\"\n  date: \"2014-09-26\"\n  published_at: \"2014-10-23\"\n  description: |-\n    Software Architecture is hard. And when your business grows, its getting even harder because scaling doesn’t come out the box and it’s not only the software which grows it’s also the team. So you have to find a way how to scale your software in a way that it stays easy maintainable for growing teams and scalable. I’d like to talk about Service Oriented Architecture in general and also share some experience and give some examples where SOA would save your ass and maybe places where SOA isn’t the best idea to implement.\n  video_provider: \"youtube\"\n  video_id: \"SYr-XgybLG0\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2015/event.yml",
    "content": "---\nid: \"PL5ImBN21eKvaTC30b0rwaIWe3DRLr062d\"\ntitle: \"rubyday 2015\"\nkind: \"conference\"\nlocation: \"Turin, Italy\"\ndescription: \"\"\npublished_at: \"2016-01-08\"\nstart_date: \"2015-11-13\"\nend_date: \"2015-11-13\"\nchannel_id: \"UCkxizXigZY3iewM6dswcYzQ\"\nyear: 2015\nbanner_background: \"#79CBB1\"\nfeatured_background: \"#79CBB1\"\nfeatured_color: \"#5F47A6\"\nwebsite: \"https://web.archive.org/web/20161025230547/http://2015.rubyday.it/\"\ncoordinates:\n  latitude: 45.0703155\n  longitude: 7.6868552\n"
  },
  {
    "path": "data/rubyday/rubyday-2015/schedule.yml",
    "content": "---\n# rubyday 2015 - Conference Schedule\n# Source: https://web.archive.org/web/20161025230627/http://2015.rubyday.it/schedule/\n# Conference date: 2015-11-13\n\ndays:\n  - name: \"Day 1\"\n    date: \"2015-11-13\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:40\"\n        slots: 1\n        items:\n          - Opening & Registration\n\n      - start_time: \"09:40\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Welcome Speech\n\n      - start_time: \"09:45\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:15\"\n        slots: 2\n\n      - start_time: \"11:15\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"11:30\"\n        end_time: \"12:15\"\n        slots: 2\n\n      - start_time: \"12:15\"\n        end_time: \"13:00\"\n        slots: 2\n\n      - start_time: \"13:00\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:30\"\n        end_time: \"15:15\"\n        slots: 2\n\n      - start_time: \"15:15\"\n        end_time: \"16:00\"\n        slots: 2\n\n      - start_time: \"16:00\"\n        end_time: \"16:15\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"16:15\"\n        end_time: \"17:00\"\n        slots: 2\n\n      - start_time: \"17:00\"\n        end_time: \"17:45\"\n        slots: 2\n\n      - start_time: \"17:45\"\n        end_time: \"18:30\"\n        slots: 1\n\n      - start_time: \"18:30\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - Cheers\n\ntracks:\n  - name: \"Room 1\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n\n  - name: \"Room 2\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n\n  - name: \"Workshop\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2015/sponsors.yml",
    "content": "---\n# Source: https://web.archive.org/web/20161025230627/http://2015.rubyday.it/schedule/\n\n- tiers:\n    - name: \"Platinum\"\n      description: |-\n        Platinum sponsors.\n      level: 1\n      sponsors:\n        - name: \"Mikamai\"\n          website: \"https://mikamai.com/\"\n          slug: \"mikamai\"\n          logo_url: \"\"\n\n    - name: \"Gold\"\n      description: |-\n        Gold sponsors.\n      level: 2\n      sponsors:\n        - name: \"Cayenne\"\n          website: \"https://cayenne.it/\"\n          slug: \"cayenne\"\n          logo_url: \"\"\n\n    - name: \"Silver\"\n      description: |-\n        Silver sponsors.\n      level: 3\n      sponsors:\n        - name: \"Seeweb\"\n          website: \"https://www.seeweb.it/\"\n          slug: \"seeweb\"\n          logo_url: \"\"\n\n    - name: \"Bronze\"\n      description: |-\n        Bronze sponsors.\n      level: 4\n      sponsors:\n        - name: \"Commit Software\"\n          website: \"https://www.commitsoftware.it/\"\n          slug: \"commitsoftware\"\n          logo_url: \"\"\n\n        - name: \"AlphaSights\"\n          website: \"http://engineering.alphasights.com/\"\n          slug: \"alphasights\"\n          logo_url: \"\"\n\n        - name: \"coders51\"\n          website: \"http://coders51.com/\"\n          slug: \"coders51\"\n          logo_url: \"\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"DNSimple\"\n          logo_url: \"\"\n\n        - name: \"Moze\"\n          website: \"http://mozestudio.com/\"\n          slug: \"mozestudio\"\n          logo_url: \"\"\n\n        - name: \"Pull Review\"\n          website: \"http://pullreview.com/\"\n          slug: \"pullreview\"\n          logo_url: \"\"\n\n        - name: \"Simplabs\"\n          website: \"https://simplabs.com/\"\n          slug: \"simplabs\"\n          logo_url: \"\"\n\n        - name: \"Seesaw\"\n          website: \"https://seesaw.it/\"\n          slug: \"seesaw\"\n          logo_url: \"\"\n\n        - name: \"Big Nerd Ranch\"\n          website: \"http://bignerdranch.com/\"\n          slug: \"bignerdranch\"\n          logo_url: \"\"\n\n        - name: \"Coupa\"\n          website: \"http://www.coupa.com/\"\n          slug: \"coupa\"\n          logo_url: \"\"\n\n    - name: \"Organizer\"\n      description: |-\n        Event organizers.\n      level: 5\n      sponsors:\n        - name: \"Cantiere Creativo\"\n          website: \"https://www.cantierecreativo.net/\"\n          slug: \"cantiere-creativo\"\n          logo_url: \"\"\n\n        - name: \"Nebulab\"\n          website: \"https://nebulab.it/\"\n          slug: \"nebulab\"\n          logo_url: \"\"\n\n        - name: \"weLaika\"\n          website: \"https://welaika.com/\"\n          slug: \"welaika\"\n          logo_url: \"\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2015/videos.yml",
    "content": "---\n- id: \"simone-carletti-rubyday-2015\"\n  title: \"Beyond the language. An introduction to algorithms\"\n  raw_title: \"RubyDay 2015 - S. Carletti - Beyond the language. An introduction to algorithms.\"\n  speakers:\n    - Simone Carletti\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  published_at: \"2016-01-08\"\n  kind: \"keynote\"\n  language: \"english\"\n  description: |-\n    Mastering a programming language is not enough to write efficient code. Programmers often try to squeeze a programming language as much as they can in order to achieve the best performance, without realizing that the solution could be found in a more efficient algorithm or data structure.\n\n    The talk is meant to inspire you to learn more about algorithm design by demonstrating how a properly designed algorithm may drastically increase the efficiency of your code, regardless of the Ruby version you are using.\n  video_provider: \"youtube\"\n  video_id: \"Iv1z5KjDBSA\"\n\n- id: \"ju-liu-rubyday-2015\"\n  title: \"Sonic PI: live music, live coding\"\n  raw_title: \"RubyDay 2015 - Ju Liu - Sonic PI: live music, live coding\"\n  speakers:\n    - Ju Liu\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 1\"\n  published_at: \"2016-01-11\"\n  language: \"english\"\n  description: |-\n    Sonic PI is a free live coding synth where you can write code to compose and perform music. In this talk, I will go through the main features of the application and show how easy it is to start composing your own pieces writing plain old Ruby. Then, we will move on to the more advanced synth features, using multiple threads and sample manipulation to start producing more complex tracks. After all that, we get the party started with some live coding!\n  video_provider: \"youtube\"\n  video_id: \"r2xMo3J8-CA\"\n  slides_url: \"https://speakerdeck.com/weppos/beyond-the-language-rubyday-2015\"\n\n- id: \"gregorio-setti-rubyday-2015\"\n  title: \"Flux on Rails: ripensare la assets pipeline e l'architettura del frontend\"\n  raw_title: \"RubyDay 2015 - G. Setti - Flux on Rails: ripensare la assets pipeline e l'architettura del frontend\"\n  speakers:\n    - Gregorio Setti\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 2\"\n  published_at: \"2016-01-11\"\n  language: \"italian\"\n  description: |-\n    Il paradigma MVC è ormai radicato e presente in ogni parte dello sviluppo web. Esistono però altri pattern, talvolta più flessibili ed efficienti, che iniziano a mettere in discussione l'egemonia dell'MVC soprattutto nello sviluppo frontend. La necessità di creare interfacce reattive e dinamiche trova un'ottima soluzione in Flux. In questo talk vedremo come si può implementare questa architettura all'interno dell'ecosistema Rails, e come i componenti React possono aiutarci a mantenere un frontend elegante e ben organizzato.\n  video_provider: \"youtube\"\n  video_id: \"haLI8IxJO2A\"\n\n- id: \"hal-fulton-rubyday-2015\"\n  title: \"Elixir for the rubyist\"\n  raw_title: \"RubyDay 2015 - H. Fulton - Elixir for the rubyist\"\n  speakers:\n    - Hal Fulton\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 1\"\n  published_at: \"2016-02-08\"\n  language: \"english\"\n  description: |-\n    Elixir is based on Erlang, but it borrows heavily from Ruby. If you understand functional programming (or if you want to), this is an excellent new language to learn. If you appreciate the beauty and elegance of Ruby, you might love Elixir, too.\n  video_provider: \"youtube\"\n  video_id: \"UNWPp5YSDXQ\"\n\n- id: \"christophe-philemotte-rubyday-2015\"\n  title: \"Deep diving: how to explore a new code base\"\n  raw_title: \"RubyDay 2015 - C. Philemotte - Deep diving: how to explore a new code base\"\n  speakers:\n    - Christophe Philemotte\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 2\"\n  published_at: \"2016-01-12\"\n  language: \"english\"\n  description: |-\n    As a developer, diving in a new code base is not uncommon: you've just been hired, you change of project, you want to help an open source project, the open source library your project depends on is buggy, etc. It's like entering in a underwater cave, you don't know the treasures or the monsters you'll find there, neither if the path is treacherous or if it's a true labyrinth where you'll get lost. You can prepare yourself, you can plan your visit, you can equip yourself, you can survive and find the gem you're looking for...\n  video_provider: \"youtube\"\n  video_id: \"eI3e7E2PDQg\"\n\n- id: \"jonathan-martin-rubyday-2015\"\n  title: \"require() bombed my multi-threaded app!\"\n  raw_title: \"RubyDay 2015 - J. Martin - require() bombed my multi-threaded app!\"\n  speakers:\n    - Jonathan Martin\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 1\"\n  published_at: \"2016-01-20\"\n  language: \"english\"\n  description: |-\n    Would you like Circular Dependencies with that? In Rails we take autoloading for granted, but slow test suites and evasive multi-thread bombs too often drive us to upbraid ActiveSupport's autoloading magic.\n\n    To dispel the magic, we will cover nothing less than the entirety of require's modest origins, the enlightening truth of Ruby execution, a selection of minimal autoload examples, the most interesting ways to break integration specs, and utopian isolation practices. All while speeding up your test suite.\n  video_provider: \"youtube\"\n  video_id: \"rV8un2Py6Kk\"\n\n- id: \"enrico-carlesso-rubyday-2015\"\n  title: \"The joy of Ruby debugging - Pry universe\"\n  raw_title: \"RubyDay 2015 - E. Carlesso - The joy of Ruby debugging - Pry universe\"\n  speakers:\n    - Enrico Carlesso\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 2\"\n  published_at: \"2016-01-12\"\n  language: \"english\"\n  description: |-\n    Let's be honest, in typical programming world debugging is a pain in the ass. `printf` everywhere, rerun the code every time... Such a waste of time.\n\n    But Ruby... Ruby is different, is such a great language for introspection and live code analysis. Here's where Pry shines. During this talk we will meet Pry alongside some other tool in his universe, like `pry-rescue`, `pry-stack_explorer` and we will see how debugging a simple Ruby script or a large RubyOnRails application is easy, and fun!\n  video_provider: \"youtube\"\n  video_id: \"4f4e5WNAeE8\"\n\n- id: \"carmen-huidobro-rubyday-2015\"\n  title: \"How teaching kids to code made me a better developer\"\n  raw_title: \"RubyDay 2015 - R. Huidobro - How teaching kids to code made me a better developer\"\n  speakers:\n    - Carmen Huidobro\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 1\"\n  published_at: \"2016-01-21\"\n  language: \"english\"\n  description: |-\n    Kids have this magical ability to take something you think you understand well and turn it upside down within an instant. They challenge norms and ask questions that you never thought existed or could be asked.\n\n    In this talk, I'll go over some of the challenges I faced introducing kids to the world of programming, and how their inquisitiveness changed the way I look at software development, how I learn to get better at it and what I want to do with it in the coming years. It has also made me a more confident and active community member, which I will outline.\n  video_provider: \"youtube\"\n  video_id: \"CPXb0W_VdSk\"\n\n- id: \"alessandro-lepore-rubyday-2015\"\n  title: \"E-Commerce is hard\"\n  raw_title: \"RubyDay 2015 - A. Lepore - E-Commerce is hard\"\n  speakers:\n    - Alessandro Lepore\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 2\"\n  published_at: \"2016-02-08\"\n  language: \"italian\"\n  description: |-\n    Gli e-commerce sono delle \"brutte bestie\" in fatto di complessità. Nel mondo Ruby e Rails abbiamo la fortuna di avere il progetto Spree Commerce che ci offre una buona base di codice su cui costruire i nostri progetti. Vediamo insieme cosa è, come funziona, che problemi risolve e come può migliorare grazie al nostro aiuto.\n  video_provider: \"youtube\"\n  video_id: \"xoaffxR67B4\"\n\n- id: \"david-muto-rubyday-2015\"\n  title: \"Making hybrid apps that don't suck\"\n  raw_title: \"RubyDay 2015 - D. Muto - Making hybrid apps that don't suck\"\n  speakers:\n    - David Muto\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 1\"\n  published_at: \"2016-01-27\"\n  language: \"english\"\n  description: |-\n    Want to make hybrid apps that don't suck? I'll go over tips and tricks, the ups and downs, and the pros and cons as well as the overall process that Shopify took to develop a world class hybrid app for iOS and Android using Rails, CoffeeScript, Objective-C and Java.\n  video_provider: \"youtube\"\n  video_id: \"LObvMbX8Cko\"\n\n- id: \"pierluigi-riti-rubyday-2015\"\n  title: \"CI/CD and devops with Ruby and Rails\"\n  raw_title: \"RubyDay 2015 - P. Riti - CI/CD and devops with Ruby and Rails\"\n  speakers:\n    - Pierluigi Riti\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 2\"\n  published_at: \"2016-01-27\"\n  language: \"english\"\n  description: |-\n    Creating a secure and strong web application can be a real challenge. There are many elements that must be taken into account including the HTTPS setup, host server and the input sanitization/authorization/authentication mechanisms.\n\n    In this lecture we will walk through the setup of a simple, yet secure ToDO application. We will focus on the most common threats and the best practices for maintaining proper security.\n  video_provider: \"youtube\"\n  video_id: \"K2lg2HxEZE8\"\n\n- id: \"james-kiesel-rubyday-2015\"\n  title: \"Is it me you're searching for?\"\n  raw_title: \"RubyDay 2015 - J. Kiesel - Is it me you're searching for?\"\n  speakers:\n    - James Kiesel\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 1\"\n  published_at: \"2016-01-28\"\n  language: \"english\"\n  description: |-\n    Search is a ubiquitous, yet often-overlooked part of many applications; your site's search can make (or break!) your user experience pretty easily. Here we'll talk through some of the options for doing full text searching in your Rails applications.\n  video_provider: \"youtube\"\n  video_id: \"p8qrRSp72I0\"\n\n- id: \"rubyday-2015-lightning-talks\"\n  title: \"Lightning Talks\"\n  raw_title: \"RubyDay 2015 - Lightning Talks\"\n  speakers:\n    - Unknown\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 2\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"rubyday-2015-lightning-talks\"\n\n- id: \"marco-otte-witte-rubyday-2015\"\n  title: \"JSON API\"\n  raw_title: \"RubyDay 2015 - M. Otte-Witte - JSON API\"\n  speakers:\n    - Marco Otte-Witte\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 1\"\n  published_at: \"2016-01-28\"\n  language: \"english\"\n  description: |-\n    This talk explains what [JSON API](https://jsonapi.org/) is, why it's so important and how it can be implemented in Ruby servers (Rails or others). I will use a sample project to illustrate client/server communication and show how both sides benefit from using the standard.\n  video_provider: \"youtube\"\n  video_id: \"fixLcFPXo0I\"\n\n- id: \"sante-rotondi-rubyday-2015\"\n  title: \"Presentazione progetto Italy On Rails\"\n  raw_title: \"RubyDay 2015 - Sante Rotondi - Presentazione progetto Italy On Rails\"\n  speakers:\n    - Sante Rotondi\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  track: \"Room 2\"\n  language: \"italian\"\n  description: |-\n    Durante questo talk verrà presentato il progetto Italy On Rails, organizzato dall'Associazione Ruby Italia per promuovere Ruby come strumento di lavoro e divertimento. Non possiamo svelarti di più su questo progetto adesso, ma se verrai ad ascoltare il talk ti sarà richiesto di aiutare a dar forma alla prima operazione di questo tipo al mondo.\n  video_provider: \"not_recorded\"\n  video_id: \"sante-rotondi-rubyday-2015\"\n\n- id: \"luca-guidi-rubyday-2015\"\n  title: \"Lotus and the future of Ruby\"\n  raw_title: \"RubyDay 2015 - L. Guidi - Lotus and the future of Ruby\"\n  speakers:\n    - Luca Guidi\n  event_name: \"rubyday 2015\"\n  date: \"2015-11-13\"\n  published_at: \"2016-01-08\"\n  kind: \"keynote\"\n  language: \"english\"\n  description: |-\n    Lotus is an emerging web framework for Ruby. It's fast, lightweight but yet powerful. Luca will show the main ideas, how to get started and the technical problems that it aims to solve. We'll discuss together why a project like this it's important for the future of Ruby and the Community.\n  video_provider: \"youtube\"\n  video_id: \"XCgsXUKLsOc\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2016/event.yml",
    "content": "---\nid: \"PL5ImBN21eKvbFLhByXvzczzqtx9ApeKAY\"\ntitle: \"rubyday 2016\"\nkind: \"conference\"\nlocation: \"Florence, Italy\"\ndescription: \"\"\npublished_at: \"2016-12-20\"\nstart_date: \"2016-11-25\"\nend_date: \"2016-11-26\"\nchannel_id: \"UCkxizXigZY3iewM6dswcYzQ\"\nyear: 2016\nbanner_background: \"#75CEA0\"\nfeatured_background: \"#75CEA0\"\nfeatured_color: \"#492996\"\nwebsite: \"https://web.archive.org/web/20161029010336/http://www.rubyday.it/\"\ncoordinates:\n  latitude: 43.7699685\n  longitude: 11.2576706\n"
  },
  {
    "path": "data/rubyday/rubyday-2016/schedule.yml",
    "content": "---\n# rubyday 2016 - Conference Schedule\n# Source: https://web.archive.org/web/20161028060141/http://www.rubyday.it/schedule/\n# Conference date: 2016-11-25\n\ndays:\n  - name: \"Day 1\"\n    date: \"2016-11-25\"\n    grid:\n      - start_time: \"08:45\"\n        end_time: \"09:40\"\n        slots: 1\n        items:\n          - Opening & Registration\n\n      - start_time: \"09:30\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Welcome Speech\n\n      - start_time: \"09:45\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"11:15\"\n        end_time: \"12:10\"\n        slots: 2\n\n      - start_time: \"12:10\"\n        end_time: \"13:00\"\n        slots: 2\n\n      - start_time: \"13:00\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:30\"\n        end_time: \"15:20\"\n        slots: 2\n\n      - start_time: \"15:20\"\n        end_time: \"16:20\"\n        slots: 2\n\n      - start_time: \"16:20\"\n        end_time: \"16:40\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"16:40\"\n        end_time: \"17:30\"\n        slots: 2\n\n      - start_time: \"17:30\"\n        end_time: \"17:40\"\n        slots: 1\n        items:\n          - Mini Break\n\n      - start_time: \"17:40\"\n        end_time: \"18:40\"\n        slots: 1\n\n      - start_time: \"18:40\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - End\n\n  - name: \"Day 2\"\n    date: \"2016-11-26\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening & Registration\n\n      - start_time: \"10:00\"\n        end_time: \"13:00\"\n        slots: 3\n\n      - start_time: \"13:00\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:30\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"16:00\"\n        end_time: \"19:00\"\n        slots: 3\n\n      - start_time: \"19:00\"\n        end_time: \"19:15\"\n        slots: 1\n        items:\n          - Closing and Greetings\n\ntracks:\n  - name: \"Room 1\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n\n  - name: \"Room 2\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n\n  - name: \"Workshop 1\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n\n  - name: \"Workshop 2\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n\n  - name: \"Workshop 3\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2016/sponsors.yml",
    "content": "---\n# Source: https://web.archive.org/web/20161029010336/http://www.rubyday.it/\n\n- tiers:\n    - name: \"Platinum\"\n      description: |-\n        Platinum sponsors.\n      level: 1\n      sponsors:\n        - name: \"Mikamai\"\n          website: \"https://mikamai.com/\"\n          slug: \"mikamai\"\n          logo_url: \"\"\n\n    - name: \"Gold\"\n      description: |-\n        Gold sponsors.\n      level: 2\n      sponsors:\n        - name: \"Deliveroo\"\n          website: \"https://deliveroo.it/\"\n          slug: \"deliveroo\"\n          logo_url: \"\"\n\n    - name: \"Silver\"\n      description: |-\n        Silver sponsors.\n      level: 3\n      sponsors:\n        - name: \"Seeweb\"\n          website: \"https://www.seeweb.it/\"\n          slug: \"seeweb\"\n          logo_url: \"\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"DNSimple\"\n          logo_url: \"\"\n\n        - name: \"Commit Software\"\n          website: \"http://www.commitsoftware.it/\"\n          slug: \"commitsoftware\"\n          logo_url: \"\"\n\n    - name: \"Bronze\"\n      description: |-\n        Bronze sponsors.\n      level: 4\n      sponsors:\n        - name: \"The Pragmatic Bookshelf\"\n          website: \"https://pragprog.com\"\n          slug: \"pragmatic-bookshelf\"\n          logo_url: \"\"\n\n        - name: \"JetBrains\"\n          website: \"https://www.jetbrains.com/ruby/\"\n          slug: \"JetBrains\"\n          logo_url: \"\"\n\n        - name: \"UnixStickers\"\n          website: \"https://www.unixstickers.com/\"\n          slug: \"unixstickers\"\n          logo_url: \"\"\n\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"AppSignal\"\n          logo_url: \"\"\n\n        - name: \"Shopify\"\n          website: \"https://shopify.com\"\n          slug: \"shopify\"\n          logo_url: \"\"\n\n        - name: \"Simplificator\"\n          website: \"https://www.simplificator.com/\"\n          slug: \"simplificator\"\n          logo_url: \"\"\n\n        - name: \"Rebased\"\n          website: \"https://rebased.pl/\"\n          slug: \"rebased\"\n          logo_url: \"\"\n\n        - name: \"Dato CMS\"\n          website: \"https://www.datocms.com/\"\n          slug: \"datocms\"\n          logo_url: \"\"\n\n        - name: \"Worders\"\n          website: \"https://worders.net/\"\n          slug: \"worders\"\n          logo_url: \"\"\n\n        - name: \"Blue Apron\"\n          website: \"https://www.blueapron.com/\"\n          slug: \"blueapron\"\n          logo_url: \"\"\n\n        - name: \"Erlang Solutions\"\n          website: \"https://www.erlang-solutions.com/\"\n          slug: \"erlang-solutions\"\n          logo_url: \"\"\n\n    - name: \"Organizer\"\n      description: |-\n        Event organizers.\n      level: 5\n      sponsors:\n        - name: \"Cantiere Creativo\"\n          website: \"https://www.cantierecreativo.net/\"\n          slug: \"cantiere-creativo\"\n          logo_url: \"\"\n\n        - name: \"Nebulab\"\n          website: \"https://nebulab.it/\"\n          slug: \"nebulab\"\n          logo_url: \"\"\n\n        - name: \"weLaika\"\n          website: \"https://welaika.com/\"\n          slug: \"welaika\"\n          logo_url: \"\"\n\n        - name: \"Associazione Ruby Italia\"\n          website: \"https://www.facebook.com/AssociazioneRubyItalia\"\n          slug: \"ruby-italia\"\n          logo_url: \"\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2016/videos.yml",
    "content": "---\n- id: \"xavier-noria-rubyday-2016\"\n  title: \"Little Snippets\"\n  raw_title: \"RubyDay2016 - Xavier Noria - Little Snippets\"\n  speakers:\n    - Xavier Noria\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  published_at: \"2016-12-14\"\n  kind: \"keynote\"\n  video_provider: \"youtube\"\n  video_id: \"U39Ou_eBkr4\"\n  description: |-\n    In this talk we are going to make a trip through idiomatic Ruby, concise code, readable code, exact code. Using selected real small snippets I have often found doing open source or consultancy, we are going to reflect about these concepts, how do they apply, and how subjective and social they are. A talk, indeed, with maybe more questions than answers.\n\n- id: \"kylie-stradley-rubyday-2016\"\n  title: \"A Common Taxonomy Of Bugs And How To Squash Them\"\n  raw_title: \"RubyDay2016 - Kylie Stradley - A Common Taxonomy Of Bugs And How To Squash Them\"\n  speakers:\n    - Kylie Stradley\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  track: \"Room 1\"\n  published_at: \"2016-12-14\"\n  video_provider: \"youtube\"\n  video_id: \"S70Zo5bFZwU\"\n  description: |-\n    Did you really think you could make changes to the database by editing the schema file? Who are you, Amelia Bedelia?\n\n    The silly mistakes we all made when first learning Rails may be funny to us now, but we should remember how we felt at the time. New developers don't always realize senior developers were once beginners too and may assume they are the first and last developer to mix up when to use the rails and rake commands.\n\n    This talk, presented in a storybook style, will be a lighthearted examination of some of the common mistakes (and causes of those mistakes) made by beginner Rails developers.\n\n- id: \"piotr-szotkowski-rubyday-2016\"\n  title: \"Integration Tests Are Bogus\"\n  raw_title: \"RubyDay2016 - Piotr Szotkowski - Integration Tests Are Bogus\"\n  speakers:\n    - Piotr Szotkowski\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  track: \"Room 2\"\n  published_at: \"2016-12-14\"\n  video_provider: \"youtube\"\n  video_id: \"EfX511HjwuM\"\n  slides_url: \"https://talks.chastell.net/rubyday-2016\"\n  description: |-\n    Heavy mocking and stubbing comes with a cost: you can't say anything about collaboration features of well-unit-tested objects without integration and end-to-end tests. This talk covers stubbing, mocking and spying that verifies whether the faked methods exist on the actual object, take the right number of arguments and whether tests for a given class verify the behaviour that the class's doubles pretend to have; with these facilities writing a system from outside in is demonstrably enjoyable.\n\n    Whether you like to write well-isolated (and fast!) unit tests or need to implement the outside of a system without having the inside nits-and-bolts in place beforehand there's a plethora of stubbing and mocking libraries to choose from. Unfortunately, heavy mocking and stubbing comes with a cost: even with the most well-tested-in-isolation objects you can't really say anything about their proper wirings without some integration and end-to-end tests – and writing the former is often not a very enjoyable experience.\n\n    This talk covers stubbing, mocking and spying that goes the extra mile and verifies whether your fakes have any connection with reality – whether the faked methods exist on the actual object, whether they take the right number of arguments and even whether tests for a given class verify the behaviour that the class's fakes pretend to have. Both RSpec verified doubles and Bogus's contract tests are covered; a change to a method's name or its signature will make all of the related fakes complain, all the missing pieces of a system written from outside in will present themselves ready to be implemented, and a subset of mocks and stubs of your choice will verify that their production counterparts work as assumed.\n\n    This talk presents integration tests and different types of test doubles (and which use when if you follow CQRS). It also shows how to use RSpec's verified doubles (with their pros and cons) and Bogus's fakes, including faking roles and verifying contract tests based on the fakes' configuration.\n\n- id: \"devon-estes-rubyday-2016\"\n  title: \"Make Ruby Functional Again!\"\n  raw_title: \"RubyDay2016 - Devon Estes - Make Ruby Functional Again!\"\n  speakers:\n    - Devon Estes\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  track: \"Room 1\"\n  published_at: \"2016-12-14\"\n  video_provider: \"youtube\"\n  video_id: \"a7opGxpGw3k\"\n  description: |-\n    Functional programming is all the rage these days, and many Rubyists feel left out of all the fun. But don't despair - many of the great ideas that are coming out of the functional revolution are applicable to our Ruby code, too! In this talk we'll explore some of the ways we can make our Ruby code more functional (pun intended) without giving up any of the joys of object orientation. In this talk you'll see how using some functional programming concepts can make your Ruby code easier to test, easier to maintain, and easier to change!\n\n- id: \"marion-schleifer-rubyday-2016\"\n  title: \"Learning To Program Using Ruby\"\n  raw_title: \"RubyDay2016 - Marion Schleifer - Learning To Program Using Ruby\"\n  speakers:\n    - Marion Schleifer\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  track: \"Room 2\"\n  published_at: \"2016-12-14\"\n  video_provider: \"youtube\"\n  video_id: \"buuqM92Cw80\"\n  description: |-\n    One and a half years ago, I decided to learn programming with zero knowledge about computers and programming languages, as my work experience and education were in an entirely different field. I then started learning Ruby in self-study and then in an internship. Now, I have my first full-time programming job in a company that works with Ruby. Also, I co-founded a free programming course for women, because I think the industry needs more female programmers. I want to talk to you about the up and downs with Ruby as the first programming language, as well as the strong need for more female developers. I absolutely love my new career as a Ruby programmer and I want to share my experience with you.\n\n- id: \"rafael-mendona-frana-rubyday-2016\"\n  title: \"How Sprockets Works\"\n  raw_title: \"RubyDay2016 - Rafael Franca - How Sprockets Works\"\n  speakers:\n    - Rafael Mendonça França\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  track: \"Room 1\"\n  published_at: \"2016-12-14\"\n  video_provider: \"youtube\"\n  video_id: \"ANRfQrGeZRM\"\n  description: |-\n    Almost all applications have assets like CSS, JavaScript and others. That means the asset pipeline is an integral part of the Ruby on Rails framework. In this talk we'll show you how the asset pipeline works, and how you can take full advantage of the asset pipeline's features. Ever wondered how to convert an SVG to PNG automatically? Wanted to know what exactly happens to your CoffeeScript files? We'll explore that, and more.\n\n- id: \"paolo-nusco-perrotta-rubyday-2016\"\n  title: \"Refinements - The Worst Feature You Ever Loved\"\n  raw_title: \"RubyDay2016 - Paolo Perrotta - Refinements - The Worst Feature You Ever Loved\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  track: \"Room 2\"\n  published_at: \"2016-12-14\"\n  video_provider: \"youtube\"\n  video_id: \"bChCKrqrtqk\"\n  description: |-\n    Refinements are cool. They are the biggest new language feature in Ruby 2. They help you avoid some of Ruby's most dangerous pitfalls.\n\n    They make your code cleaner and safer.\n\n    Oh, and some people really hate them.\n\n    Are Refinements the best idea since blocks and modules, or a terrible mistake? Decide for yourself. I'll tell you the good, the bad and the ugly about refinements. At the end of this speech, you'll understand the trade-offs of this controversial feature, and know what all the fuss is about.\n\n- id: \"simone-carletti-rubyday-2016\"\n  title: \"How Programming In Other Languages Made My Ruby Code Better\"\n  raw_title: \"RubyDay2016 - Simone Carletti - How Programming In Other Languages Made My Ruby Code Better\"\n  speakers:\n    - Simone Carletti\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  track: \"Room 1\"\n  published_at: \"2016-12-14\"\n  video_provider: \"youtube\"\n  video_id: \"p0DPNbnjkCw\"\n  slides_url: \"https://slidr.io/weppos/how-programming-in-other-languages-made-my-ruby-code-better-rubyday-2016\"\n  description: |-\n    Learning new programming languages it's like approaching new cultures: it will largely enrich your knowledge and leverage your skills. New programming languages will not only made you a better software developer in general, but they will also help you to write better Ruby code. This talk will provide you real world examples of Ruby code evolution, using lessons learned from other languages.\n\n- id: \"danielle-adams-rubyday-2016\"\n  title: \"Ruby Racing: Challenging Ruby Methods\"\n  raw_title: \"RubyDay2016 - Danielle Adams - Ruby Racing: Challenging Ruby Methods\"\n  speakers:\n    - Danielle Adams\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  track: \"Room 2\"\n  published_at: \"2016-12-14\"\n  video_provider: \"youtube\"\n  video_id: \"u9iQK4kBt-M\"\n  description: |-\n    Ruby is widely-used and prides itself on \"simplicity and productivity\". But what is happening under the hood of our favorite programming language? Are there better, faster, or stronger ways to implement these methods? I'm going to take a deep dive into testing and optimizing some of Ruby's most popularly convenient methods.\n\n- id: \"luca-guidi-rubyday-2016\"\n  title: \"Lessons Learned While Building Hanami\"\n  raw_title: \"RubyDay2016 - Luca Guidi - Lessons Learned While Building Hanami\"\n  speakers:\n    - Luca Guidi\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  track: \"Room 1\"\n  published_at: \"2016-12-14\"\n  video_provider: \"youtube\"\n  video_id: \"0RyitUKfUFE\"\n  description: |-\n    Building an Open Source project is great.. except when it isn't. It's rewarding and frustrating, challenging and boring. It's an emotional rollercoaster, where you have to deal with people and expectations, innovation, copyrights, companies, communication and communities, fear, anger, mistakes, features and bugs, a day job, get almost broke, time management, and finally.. writing the code. This is the story of Hanami in the last four years: from a hack experiment to established software.\n\n- id: \"benjamin-roth-rubyday-2016\"\n  title: \"Structure and Chain your Poros\"\n  raw_title: \"RubyDay2016 - Benjamin Roth - Structure and Chain your Poros\"\n  speakers:\n    - Benjamin Roth\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  track: \"Room 2\"\n  published_at: \"2016-12-14\"\n  video_provider: \"youtube\"\n  video_id: \"sSQOBK9goLg\"\n  description: |-\n    Design patterns vary. We learnt code was cool in controller then removed it from here in favor of fat models. Yet it was not the best approach either.\n\n    The Service Object pattern arised articulated around so called Poor Old Ruby Objects. While it encapsulate logic and make it easy to test fundamental questions remain: how do I know everything went well when I called the object? How to retrieve errors? How to rollback? What if I have object ls calling other objects?\n\n    I try to address these questions with examples and existing libraries.\n\n- id: \"piotr-solnica-rubyday-2016\"\n  title: \"Can We Still Innovate?\"\n  raw_title: \"RubyDay2016 - Piotr Solnica - Can We Still Innovate?\"\n  speakers:\n    - Piotr Solnica\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-25\"\n  published_at: \"2016-12-14\"\n  kind: \"keynote\"\n  video_provider: \"youtube\"\n  video_id: \"KMdvWzjLjlY\"\n  description: |-\n    Rails revolutionized the way we build web apps - but that was 10 years ago. These days, it's not uncommon to hear dramatic statements like, “Rails is dead” or even, “Ruby is dead”. Even though such conclusions are far-fetched, it's a sign that some people have become tired of struggling with various problems that Rails doesn't address.\n\n    We're starting to see people leave Ruby - should you do the same? Or is there a place in the Ruby world where we can still innovate and prove that Ruby is a viable technological choice?\n\n    In this talk, I'll introduce you to the growing ecosystem of modern Ruby libraries and frameworks. Let's go beyond Rails and see that Ruby is doing just fine.\n\n- id: \"martin-meyerhoff-rubyday-2016-setting-up-solidus\"\n  title: \"Setting up Solidus\"\n  raw_title: \"RubyDay2016 - Martin Meyerhoff - Setting up Solidus\"\n  speakers:\n    - Martin Meyerhoff\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-26\"\n  track: \"Workshop 1\"\n  published_at: \"2016-11-26\"\n  kind: \"workshop\"\n  video_provider: \"not_recorded\"\n  video_id: \"martin-meyerhoff-rubyday-2016-setting-up-solidus\"\n  description: |-\n    How do you go from Rails new to a deployable store? What steps are necessary to configure an ecommerce project such that taxes, shipping and payment work? This will be a hands-on workshop, at the end of which you should have a basic shop running.\n\n- id: \"ivan-nemytchenko-rubyday-2016-how-to-stop-being-rails-developer\"\n  title: \"How to stop being Rails developer\"\n  raw_title: \"RubyDay2016 - Ivan Nemytchenko - How to stop being Rails developer\"\n  speakers:\n    - Ivan Nemytchenko\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-26\"\n  track: \"Workshop 2\"\n  published_at: \"2016-11-26\"\n  kind: \"workshop\"\n  video_provider: \"not_recorded\"\n  video_id: \"ivan-nemytchenko-rubyday-2016-how-to-stop-being-rails-developer\"\n  description: |-\n    There is ongoing discussion in Ruby Community whether we should be ok with Rails-way of development, or should we move to more modular Lotus/ROM-like ways?\n    While we keep thinking about it, we're still need to teach newcomers somehow. Rails is still dominating framework, therefore it is important to help newbies avoid our self-learners generation mistakes, like:\n\n    - bloated controllers/models\n    - OOP/SOLID principles ignorance\n    - doing testing wrong\n    - messing with layers of abstractions\n\n    I personally think that the best way to get motivation to learn how to do something properly is to feel the pain of doing it improperly. A year ago I was organising remote internship for junior ruby developers. The program was designed to give interns that feeling of pain :)\n    In this workshop I will share my recipes & principles, so you could apply them for your specifics & technologies stack.\n\n- id: \"luca-guidi-rubyday-2016-hanami\"\n  title: \"Hanami\"\n  raw_title: \"RubyDay2016 - Luca Guidi - Hanami\"\n  speakers:\n    - Luca Guidi\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-26\"\n  track: \"Workshop 3\"\n  published_at: \"2016-11-26\"\n  kind: \"workshop\"\n  video_provider: \"not_recorded\"\n  video_id: \"luca-guidi-rubyday-2016-hanami\"\n  description: |-\n    Learn how to build a project with Hanami.\n\n- id: \"ju-liu-rubyday-2016-running-ruby-on-raspberry-pi\"\n  title: \"Running Ruby on a Raspberry PI\"\n  raw_title: \"RubyDay2016 - Ju Liu - Running Ruby on a Raspberry PI\"\n  speakers:\n    - Ju Liu\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-26\"\n  published_at: \"2016-11-26\"\n  kind: \"workshop\"\n  video_provider: \"not_recorded\"\n  video_id: \"ju-liu-rubyday-2016-running-ruby-on-raspberry-pi\"\n  description: |-\n    Do you have a Raspberry PI laying around that you feel a little bit ashamed about? In this talk, we will overcome that shame and find out what we can build with it with the help of some amazing little sensors. We will create a mysterious application together from scratch, writing the code in Ruby. We will also be building the hardware circuit live on stage, so keep your fingers crossed!\n\n- id: \"alexander-coles-rubyday-2016-taking-rails-beyond-asset-pipeline\"\n  title: \"Taking Rails beyond the asset pipeline\"\n  raw_title: \"RubyDay2016 - Alexander Coles - Taking Rails beyond the asset pipeline\"\n  speakers:\n    - Alexander Coles\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-26\"\n  track: \"Workshop 1\"\n  published_at: \"2016-11-26\"\n  kind: \"workshop\"\n  video_provider: \"not_recorded\"\n  video_id: \"alexander-coles-rubyday-2016-taking-rails-beyond-asset-pipeline\"\n  description: |-\n    The way we're building our front-ends has changed irrevocably. Clean architecture is now a prerequisite and no longer simply nice-to-have. Thanks to frameworks like Ember.js and Angular, We have entered into the era of front-end MVC.\n\n    When Rails came into being over ten years ago, it was ground-breaking. Rails developers shouldn't have to forgo innovation and use of upcoming technologies like ES6 and isomorphism. So how can Rails keep up?\n\n- id: \"michele-franzin-andrea-reginato-rubyday-2016-fullstack-pm-survivor-guide\"\n  title: \"Fullstack|PM survivor guide\"\n  raw_title: \"RubyDay2016 - Michele Franzin e Andrea Reginato - Fullstack|PM survivor guide\"\n  speakers:\n    - Michele Franzin\n    - Andrea Reginato\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-26\"\n  track: \"Workshop 2\"\n  published_at: \"2016-11-26\"\n  kind: \"workshop\"\n  video_provider: \"not_recorded\"\n  video_id: \"michele-franzin-andrea-reginato-rubyday-2016-fullstack-pm-survivor-guide\"\n  description: |-\n    That every morning you wake Dev or PM does not matter: whatever you make web-apps | digital products | Mobile-apps | Web services | *AAS you have as many possibilities as when you are in a technology store.\n\n    Taking the right decisions is essential in order not to lose your sight and avoid unpleasant encounters.\n\n    Backend, Frontend, UI, Ops, UX, Data Storage: is this all you need to be a fullstack developer?\n\n    Starting from a collective refactor we want to discuss and act out together what it means to have a \"FullStack Approach\" and how this affects the choices we make (technologies, communication, architecture, costs, human aspects, projects, ...).\n\n    There's a chance to be contaminated through sharing experiences (ours & yours), sharing ideas, and maybe earning another point of view. If you already know everything or you feel too noob to participate, it is a good opportunity to make use of your skills in a more pragmatic way and take home a wider vision.\n\n- id: \"nick-sutterer-rubyday-2016-architecture-matters-trailblazer-workshop\"\n  title: \"Architecture Matters! A Trailblazer Workshop\"\n  raw_title: \"RubyDay2016 - Nick Sutterer - Architecture Matters! A Trailblazer Workshop\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"rubyday 2016\"\n  date: \"2016-11-26\"\n  track: \"Workshop 3\"\n  published_at: \"2016-11-26\"\n  kind: \"workshop\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"nick-sutterer-rubyday-2016-architecture-matters-trailblazer-workshop\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2019/event.yml",
    "content": "---\nid: \"PLWK9j6ps_unmgzGOw3cbjS8ID-b-cF1d9\"\ntitle: \"rubyday 2019\"\nkind: \"conference\"\nlocation: \"Verona, Italy\"\ndescription: \"\"\npublished_at: \"2019-07-12\"\nstart_date: \"2019-04-11\"\nend_date: \"2019-04-11\"\nchannel_id: \"UCdWnwC8nz_CCFQrmLBrLCVw\"\nyear: 2019\nbanner_background: \"#EBEEF5\"\nfeatured_background: \"#EBEEF5\"\nfeatured_color: \"#5F4E9B\"\nwebsite: \"https://2019.rubyday.it\"\ncoordinates:\n  latitude: 45.43999609999999\n  longitude: 10.9719328\n"
  },
  {
    "path": "data/rubyday/rubyday-2019/venue.yml",
    "content": "---\nname: \"Hotel San Marco Verona\"\n\naddress:\n  street: \"Via Baldassarre Longhena, 42\"\n  city: \"Verona\"\n  region: \"Veneto\"\n  postal_code: \"37138\"\n  country: \"Italy\"\n  country_code: \"IT\"\n  display: \"Via Baldassarre Longhena, 42, 37138 Verona VR, Italy\"\n\ncoordinates:\n  latitude: 45.43999609999999\n  longitude: 10.9719328\n\nmaps:\n  google: \"https://maps.google.com/?q=Hotel+San+Marco+Verona,45.43999609999999,10.9719328\"\n  apple: \"https://maps.apple.com/?q=Hotel+San+Marco+Verona&ll=45.43999609999999,10.9719328\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=45.43999609999999&mlon=10.9719328\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2019/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"bozhidar-batsov-rubyday-2019\"\n  title: \"Ruby 3.0 Redux\"\n  raw_title: \"Bozhidar Batsov - Ruby 3.0 Redux - rubyday 2019\"\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"rubyday 2019\"\n  date: \"2019-04-11\"\n  published_at: \"2019-07-13\"\n  description: |-\n    For several years now Rubyists around the world have been fascinated by the plans for the next big Ruby release - namely Ruby 3.0. While a lot has been said about 3.0, there’s also a lot of confusion about it - the scope, the timeline, backwards compatibility, etc. This talk is an attempt to summarize everything that’s currently known about Ruby 3.0 and present it into an easily digestible format. We’ll go over all the main features targeting Ruby 3.0 and many of the open questions surrounding them.\n\n    rubyday Verona 2019 - April 11th https://2019.rubyday.it/\n\n    Next edition: April 2nd 2020, Verona - https://rubyday-2020.eventbrite.it\n    Keep in touch! Subscribe to our newsletter http://eepurl.com/rCZZT\n  video_provider: \"youtube\"\n  video_id: \"ypdDL3BJm_Q\"\n\n- id: \"emily-stolfo-rubyday-2019\"\n  title: \"Beauty and the Beast: your application and distributed systems\"\n  raw_title: \"Emily Stolfo - Beauty and the Beast: your application and distributed systems - rubyday 2019\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"rubyday 2019\"\n  date: \"2019-04-11\"\n  published_at: \"2019-07-13\"\n  description: |-\n    With more applications now using service-oriented architectures, developers must know how to talk to distributed technologies and to handle errors and failures. While you can usually depend on libraries to encapsulate such details, it's important to understand and to be able to predict the behavior of your distributed systems. This talk will arm you with algorithms and testing strategies so you can tame your services and build robust applications.\n\n    rubyday Verona 2019 - April 11th https://2019.rubyday.it/\n\n    Next edition: April 2nd 2020, Verona - https://rubyday-2020.eventbrite.it\n    Keep in touch! Subscribe to our newsletter http://eepurl.com/rCZZT\n  video_provider: \"youtube\"\n  video_id: \"V72vASzx0A4\"\n\n- id: \"xavier-noria-rubyday-2019\"\n  title: \"Zeitwerk: A new code loader for Ruby\"\n  raw_title: \"Xavier Noria - Zeitwerk: A new code loader for Ruby - rubyday 2019\"\n  speakers:\n    - Xavier Noria\n  event_name: \"rubyday 2019\"\n  date: \"2019-04-11\"\n  published_at: \"2019-07-13\"\n  description: |-\n    Zeitwerk is a new code loader for Ruby, and it is going to replace the classic autoloader in Rails 6. In this talk we'll cover what motivated Zeitwerk, how to use it, and interesting aspects of its implementation.\n\n    rubyday Verona 2019 - April 11th https://2019.rubyday.it/\n\n    Next edition: April 2nd 2020, Verona - https://rubyday-2020.eventbrite.it\n    Keep in touch! Subscribe to our newsletter http://eepurl.com/rCZZT\n  video_provider: \"youtube\"\n  video_id: \"3-PuF2HIg0A\"\n\n- id: \"elia-schito-rubyday-2019\"\n  title: \"Live code a game on the browser with Opal and Vue.js\"\n  raw_title: \"Elia Schito - Live code a game on the browser with Opal and Vue.js - rubyday 2019\"\n  speakers:\n    - Elia Schito\n  event_name: \"rubyday 2019\"\n  date: \"2019-04-11\"\n  published_at: \"2019-07-13\"\n  description: |-\n    JS is often a struggle for the Ruby developer used to live in the backend. We'll have a fresh look at the language implementing interfaces for a Tetris-like game for the terminal (using MRI) and for the browser (using Opal) using different techniques (vanilla JS, jQuery, Vue.js). The whole thing will be preceded by an introduction to Opal.\n\n    rubyday Verona 2019 - April 11th https://2019.rubyday.it/\n\n    Next edition: April 2nd 2020, Verona - https://rubyday-2020.eventbrite.it\n    Keep in touch! Subscribe to our newsletter http://eepurl.com/rCZZT\n  video_provider: \"youtube\"\n  video_id: \"Mm0_Y9IpN18\"\n\n- id: \"luca-guidi-rubyday-2019\"\n  title: \"Hanami 2.0\"\n  raw_title: \"Luca Guidi - Hanami 2.0 - rubyday 2019\"\n  speakers:\n    - Luca Guidi\n  event_name: \"rubyday 2019\"\n  date: \"2019-04-11\"\n  published_at: \"2019-07-13\"\n  description: |-\n    Hanami is being reinvented. We learned from experience, and community feedback, how to build a much more simplified, fast, and productive framework. This is a preview of how Hanami 2.0 will work.\n  video_provider: \"youtube\"\n  video_id: \"LqGBhTSOmTI\"\n\n- id: \"marion-schleifer-rubyday-2019\"\n  title: \"Building modern web-applications with GraphQL & serverless Ruby\"\n  raw_title: \"Marion Schleifer - Building modern web-applications with GraphQL & serverless Ruby - rubyday 2019\"\n  speakers:\n    - Marion Schleifer\n  event_name: \"rubyday 2019\"\n  date: \"2019-04-11\"\n  published_at: \"2019-07-13\"\n  description: |-\n    Many Ruby programmers are looking for new opportunities now that serverless is becoming more popular. Hasura offers instant realtime GraphQL on Postgres as a serverless backend option. And the best part: you can still use Ruby to write the business logic for the backend! Using a sample application, I will show you how to build fast web applications with a Vue frontend and a backend running on Hasura’s GraphQL engine. We will explore how the different components work together and how you can take full advantage of the combination of these technologies.\n\n    rubyday Verona 2019 - April 11th https://2019.rubyday.it/\n\n    Next edition: April 2nd 2020, Verona - https://rubyday-2020.eventbrite.it\n    Keep in touch! Subscribe to our newsletter http://eepurl.com/rCZZT\n  video_provider: \"youtube\"\n  video_id: \"p4Fou2ZKwvM\"\n\n- id: \"nick-sutterer-rubyday-2019\"\n  title: \"Enterprise Ruby 2.1\"\n  raw_title: \"Nick Sutterer - Enterprise Ruby 2.1 - rubyday 2019\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"rubyday 2019\"\n  date: \"2019-04-11\"\n  published_at: \"2019-07-13\"\n  description: |-\n    In the past three years, the Trailblazer project has evolved from a simple service object implementation to an advanced business logic framework that can define, orchestrate and implement entire application workflows. Let's discover all those new concepts such as workflows, BPMN and state machines.\n\n    rubyday Verona 2019 - April 11th https://2019.rubyday.it/\n\n    Next edition: April 2nd 2020, Verona - https://rubyday-2020.eventbrite.it\n    Keep in touch! Subscribe to our newsletter http://eepurl.com/rCZZT\n  video_provider: \"youtube\"\n  video_id: \"YMo_2fMPQUU\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2020/event.yml",
    "content": "---\nid: \"PLWK9j6ps_unl0S5Xmi6FVfDLFUkntQTfK\"\ntitle: \"rubyday 2020\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  rubyday 2020 - Virtual edition, September 16th 2020. https://2020.rubyday.it/​\n\n  Next edition: https://2021.rubyday.it/\npublished_at: \"2021-04-01\"\nstart_date: \"2020-09-16\"\nend_date: \"2020-09-16\"\nchannel_id: \"UCdWnwC8nz_CCFQrmLBrLCVw\"\nyear: 2020\nbanner_background: \"#EEEEEE\"\nfeatured_background: \"#EEEEEE\"\nfeatured_color: \"#6956A9\"\nwebsite: \"https://2020.rubyday.it\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyday/rubyday-2020/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"john-crepezzi-rubyday-2020\"\n  title: \"Cool, But... Why?\"\n  raw_title: \"Cool, But... Why? - John Crepezzi - Rubyday 2020\"\n  speakers:\n    - John Crepezzi\n  event_name: \"rubyday 2020\"\n  date: \"2020-09-16\"\n  published_at: \"2021-04-02\"\n  description: |-\n    If you work around Ruby long enough, you’ll learn that certain ideas are just taken as gospel. Don’t use for loops, avoid global state, use symbols pretty much wherever possible. This talk will go deep into the ‘why’ behind some commonly accepted advice on Ruby, dig into the internals, and what we find might just surprise you.\n\n    rubyday 2020 - Virtual edition, September 16th 2020. https://2020.rubyday.it/\n\n    Next edition: https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"mQVZy132Y0Q\"\n\n- id: \"ivan-nemytchenko-rubyday-2020\"\n  title: \"Less abstract! Expressing Ruby OOP in pictures\"\n  raw_title: \"Less abstract! Expressing Ruby OOP in pictures - Ivan Nemytchenko - rubyday 2020\"\n  speakers:\n    - Ivan Nemytchenko\n  event_name: \"rubyday 2020\"\n  date: \"2020-09-16\"\n  published_at: \"2021-04-01\"\n  description: |-\n    Abstractions are both our blessing and our curse. Because of them, we're so powerful. But also we so often fall into the trap of miscommunication :( Abstract rules, operating with abstract terms, built on top of other abstract ideas. Ugh... In this talk, we're going to build a visual language to make things LESS ABSTRACT.\n    I'll show you how it helps in:\n    1. teaching others\n    2. explaining non-obvious concepts\n    3. refactoring messy code 4. tracking codebase changes\n\n    rubyday 2020 - Virtual edition, September 16th 2020. https://2020.rubyday.it/\n\n    Next edition: https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"BVH3Mk5eJUY\"\n\n- id: \"janko-marohnic-rubyday-2020\"\n  title: \"Sequel: When ActiveRecord is not enough\"\n  raw_title: \"Sequel: When ActiveRecord is not enough - Janko Marohnić - Rubyday 2020\"\n  speakers:\n    - Janko Marohnić\n  event_name: \"rubyday 2020\"\n  date: \"2020-09-16\"\n  published_at: \"2021-04-01\"\n  description: |-\n    As Rails developers, using ActiveRecord as our database library is a given. As our application grows, we start noticing that some of our new requirements aren't exactly supported by the ActiveRecord API. So, we pull up our sleeves and write that raw SQL snippet, re-create some queries without models to get that extra performance gain, or work around that bug in the library, and move on. But gaining this technical debt isn't necessary if you're using a library that supports your advanced use cases. Enter Sequel, an alternative ORM for Ruby. In this talk we will show some advantages that Sequel has over Active Record, covering topics like the query API, building SQL expressions (Arel), connection pools, immutability and more.\n\n    rubyday 2020 - Virtual edition, September 16th 2020. https://2020.rubyday.it/\n\n    Next edition: https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"77Xmji1-urg\"\n\n- id: \"floor-drees-rubyday-2020\"\n  title: \"OSS - to be defined\"\n  raw_title: \"OSS - to be defined - Floor Drees - Rubyday 2020\"\n  speakers:\n    - Floor Drees\n  event_name: \"rubyday 2020\"\n  date: \"2020-09-16\"\n  published_at: \"2021-04-01\"\n  description: |-\n    Enterprises have embraced Open Source software - but their grip is suffocating. Business critical software is plagued by vulnerabilities because of maintainer burnout. We're looking for more sustainable models, and regaining control over what our code can be used for - enter the Hippocratic License. GitHub taking down software that was vital infrastructure for opposition groups in Spain shows us that no one party (let alone company) should own access to open source software. The world runs on open source, how do we make sure it can do so sustainably and reliably?\n\n    rubyday 2020 - Virtual edition, September 16th 2020. https://2020.rubyday.it/\n\n    Next edition: https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"WLull6UJOC0\"\n\n- id: \"dmitry-salahutdinov-rubyday-2020\"\n  title: \"Product metrics for developers\"\n  raw_title: \"Product metrics for developers - Dmitry Salahutdinov - Rubyday 2020\"\n  speakers:\n    - Dmitry Salahutdinov\n  event_name: \"rubyday 2020\"\n  date: \"2020-09-16\"\n  published_at: \"2021-04-01\"\n  description: |-\n    Product metrics could be handy to analyze feature performance and get in-depth into business essence. But they are mostly out of the developer's scope. I am going to tell you why developers should use product analytics and how easy set it up in your project.\n\n    rubyday 2020 - Virtual edition, September 16th 2020. https://2020.rubyday.it/\n\n    Next edition: https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"4E1tEH4NTZU\"\n\n- id: \"greg-kaczorek-rubyday-2020\"\n  title: \"Moving to GraphQL - the fuzzy parts\"\n  raw_title: \"Moving to GraphQL - the fuzzy parts - Greg Kaczorek - Rubyday 2020\"\n  speakers:\n    - Greg Kaczorek\n  event_name: \"rubyday 2020\"\n  date: \"2020-09-16\"\n  published_at: \"2021-04-02\"\n  description: |-\n    We all know the good feeling that comes from starting a green field project and being able to use all the great new technology. But what if you have a 460k LOC monolith but you really feel that a new GraqhQL API is the way to go. Well, if you have good design, you can totally do it, and here's how. GraphQL is all the rage for good reason. It's geared towards solving the problems REST API's have when used by modern front-end apps. However, new technology often has a way of breaking apart when subjected to legacy projects. How easy is it to create a GraphQL API for a commercial project with 7 years of active development and 400k users? What difficulties might you encounter that blurbs and blog posts won't tell you about? I'll cover all that and more in this riveting tale of fun, sweat and tears (of joy).\n\n    rubyday 2020 - Virtual edition, September 16th 2020. https://2020.rubyday.it/\n\n    Next edition: https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"gdM0IKfwKyM\"\n\n- id: \"eileen-m-uchitelle-rubyday-2020\"\n  title: \"Technically, a Talk\"\n  raw_title: \"Technically, a Talk - Eileen Uchitelle - Rubyday 2020\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"rubyday 2020\"\n  date: \"2020-09-16\"\n  published_at: \"2021-04-02\"\n  slides_url: \"https://speakerdeck.com/eileencodes/technically-a-talk-ruby-day-2020\"\n  description: |-\n    Peer deep into Rails' database handling and you may find the code overly complex, hard to follow, and full of technical debt. On the surface you're right - it is complex, but that complexity represents the strong foundation that keeps your applications simple and focused on your product code. In this talk we'll look at how to use multiple databases, the beauty (and horror) of Rails connection management, and why we built this feature for you.\n\n    rubyday 2020 - Virtual edition, September 16th 2020. https://2020.rubyday.it/\n\n    Next edition: https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"nRJ6iQGpeuI\"\n\n- id: \"aaron-patterson-rubyday-2020\"\n  title: \"Reduce Memory by Using More\"\n  raw_title: \"Reduce Memory by Using More - Aaron Patterson - Rubyday 2020\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"rubyday 2020\"\n  date: \"2020-09-16\"\n  published_at: \"2021-04-01\"\n  description: |-\n    Most programmers don't need to think about allocating or deallocating memory, and they have the garbage collector to thank for that! In this presentation we'll discuss the latest developments in GC compaction as well as how the GC allocates and arranges memory internally. Once we understand this we'll explore a strange way Ruby is decreasing memory usage by allocating more memory. The GC manages memory so that you don't have to, but we're going to see how it's actually done!\n\n    rubyday 2020 - Virtual edition, September 16th 2020. https://2020.rubyday.it/\n\n    Next edition: https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"tqkwM9kiro8\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2021/event.yml",
    "content": "---\nid: \"PLWK9j6ps_unmW3N5wPFG6WKVEVqCz0uAt\"\ntitle: \"rubyday 2021\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: \"\"\npublished_at: \"2023-02-15\"\nstart_date: \"2021-04-07\"\nend_date: \"2021-04-07\"\nchannel_id: \"UCdWnwC8nz_CCFQrmLBrLCVw\"\nyear: 2021\nbanner_background: \"#6A58A5\"\nfeatured_background: \"#6A58A5\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2021.rubyday.it\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyday/rubyday-2021/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"brandon-weaver-rubyday-2021\"\n  title: \"Playing a Hand with Ruby Pattern Matching\"\n  raw_title: \"Playing a Hand with Ruby Pattern Matching - Brandon Weaver - rubyday 2021\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"rubyday 2021\"\n  date: \"2021-04-07\"\n  published_at: \"2023-02-10\"\n  description: |-\n    Playing a Hand with Ruby Pattern Matching - Brandon Weaver - rubyday 2021\n\n    Ruby 2.7 introduced Pattern Matching, but what can you use it for? How about we play a few hands of poker to find out. This talk explores Pattern Matching patterns through scoring poker hands using named captures, pins, hash destructuring, array destructuring, and more. If you've been waiting for some practical examples of Pattern Matching this is your talk.\n\n\n    The ninth edition of the Italian Ruby conference, for the third time organised by GrUSP, took place online on April 7th 2021.\n\n    Speaker and details on https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"-5RHj9OcCeM\"\n\n- id: \"joel-hawksley-rubyday-2021\"\n  title: \"ViewComponents in the Real World\"\n  raw_title: \"ViewComponents in the Real World - Joel Hawksley - rubyday 2021\"\n  speakers:\n    - Joel Hawksley\n  event_name: \"rubyday 2021\"\n  date: \"2021-04-07\"\n  published_at: \"2023-02-10\"\n  description: |-\n    ViewComponents in the Real World - Joel Hawksley - rubyday 2021\n\n    With the release of 6.1, Rails added support for rendering objects that respond to 'render_in', a feature extracted from the GitHub application. This change enabled the development of ViewComponent, a framework for building reusable, testable & encapsulated view components. In this talk, we’ll share what we’ve learned scaling to hundreds of ViewComponents in our application, open sourcing a library of ViewComponents, and nurturing a thriving community around the project, both internally and externally.\n\n    The ninth edition of the Italian Ruby conference, for the third time organised by GrUSP, took place online on April 7th 2021.\n\n    Speaker and details on https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"CyN1pdmBCtc\"\n\n- id: \"maciek-rzasa-rubyday-2021\"\n  title: \"API Optimization Tale: Monitor, Fix and Deploy (on Friday)\"\n  raw_title: \"API Optimization Tale: Monitor, Fix and Deploy (on Friday) - Maciek Rząsa - rubyday 2021\"\n  speakers:\n    - Maciek Rząsa\n  event_name: \"rubyday 2021\"\n  date: \"2021-04-07\"\n  published_at: \"2023-02-10\"\n  description: |-\n    API Optimization Tale: Monitor, Fix and Deploy (on Friday) - Maciek Rząsa - rubyday 2021\n\n    I saw a green build on a Friday afternoon. I knew I need to push it to production before the weekend. My gut told me it was a trap. I had already stayed late to revert a broken deploy. I knew the risk. In the middle of a service extraction project, we decided to migrate from REST to GraphQL and optimize API usage. My deploy was a part of this radical change. Why was I deploying so late? How did we measure the migration effects? And why was I testing on production? I'll tell you a tale of small steps, monitoring, and old tricks in a new setting. Hope, despair, and broken production included.\n\n    The ninth edition of the Italian Ruby conference, for the third time organised by GrUSP, took place online on April 7th 2021.\n\n    Speaker and details on https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"JPFvPCgWn0M\"\n\n- id: \"sabrina-gannon-rubyday-2021\"\n  title: \"Checking Your Types: An Overview of Ruby's Type System\"\n  raw_title: \"Checking Your Types: An Overview of Ruby's Type System - Sabrina Gannon - rubyday 2021\"\n  speakers:\n    - Sabrina Gannon\n  event_name: \"rubyday 2021\"\n  date: \"2021-04-07\"\n  published_at: \"2023-02-10\"\n  description: |-\n    Checking Your Types: An Overview of Ruby's Type System - Sabrina Gannon - rubyday 2021\n\n    Typechecking is an exciting feature that distinguishes Ruby 3 and beyond! In this talk we'll explore how types work in Ruby with the future of type checking in mind to deepen our understanding of the value of the new type checking tools and to delve deeper into Ruby types overall. Here's to getting to the root of understanding NoMethodError!\n\n    The ninth edition of the Italian Ruby conference, for the third time organised by GrUSP, took place online on April 7th 2021.\n\n    Speaker and details on https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"OevCwq5I9fM\"\n\n- id: \"yukihiro-matz-matsumoto-rubyday-2021\"\n  title: \"Ruby 3.0 and Beyond\"\n  raw_title: 'Ruby3.0 and Beyond - Yukihiro \"Matz\" Matsumoto - rubyday 2021'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"rubyday 2021\"\n  date: \"2021-04-07\"\n  published_at: \"2023-02-10\"\n  description: |-\n    Ruby3.0 and Beyond - Yukihiro \"Matz\" Matsumoto - rubyday 2021\n\n\n    The ninth edition of the Italian Ruby conference, for the third time organised by GrUSP, took place online on April 7th 2021.\n\n    Speaker and details on https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"g4f2cq2sSg4\"\n\n- id: \"coraline-ada-ehmke-rubyday-2021\"\n  title: \"The Rising Ethical Storm in Open Source\"\n  raw_title: \"The Rising Ethical Storm in Open Source - Coraline Ada Ehmke - rubyday 2021\"\n  speakers:\n    - Coraline Ada Ehmke\n  event_name: \"rubyday 2021\"\n  date: \"2021-04-07\"\n  published_at: \"2023-02-10\"\n  description: |-\n    The Rising Ethical Storm in Open Source - Coraline Ada Ehmke - rubyday 2021\n\n    The increased debate around ethical source threatens to divide the OSS community. In his book 'The Structure of Scientific Revolutions', philosopher Thomas Kuhn posits that there are three possible solutions to a crisis like the one we're facing: procrastination, assimilation, or revolution. Which will we choose as we prepare for the hard work of reconciling ethics and open source?\n\n    The ninth edition of the Italian Ruby conference, for the third time organised by GrUSP, took place online on April 7th 2021.\n\n    Speaker and details on https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"gO5LEiUovBM\"\n\n- id: \"casey-watts-rubyday-2021\"\n  title: \"Debugging Your Brain\"\n  raw_title: \"Debugging Your Brain - Casey Watts - rubyday 2021\"\n  speakers:\n    - Casey Watts\n  event_name: \"rubyday 2021\"\n  date: \"2021-04-07\"\n  published_at: \"2023-02-10\"\n  description: |-\n    Debugging Your Brain - Casey Watts - rubyday 2021\n\n    Sometimes your mind distorts reality, gets frustrated with shortcomings, or spirals out of control. Learn how to debug these by using research-backed psychology techniques.\n\n    The ninth edition of the Italian Ruby conference, for the third time organised by GrUSP, took place online on April 7th 2021.\n\n    Speaker and details on https://2021.rubyday.it/\n  video_provider: \"youtube\"\n  video_id: \"tqUexv0S4kg\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2023/event.yml",
    "content": "---\nid: \"PLWK9j6ps_unm-KNKVWSOHiGa4vrA_zCJO\"\ntitle: \"rubyday 2023\"\nkind: \"conference\"\nlocation: \"Verona, Italy\"\ndescription: |-\n  rubyday 2023 is the 10th edition of the Italian Ruby conference, organized by GrUSP.\n\n  👾 Main topics: Ruby, ChatGPT, LLM, AI, Rubocop, team management, End to end typing, Ruby Kata, Caching strategies, Haskell \n\n  🗓️ 16 June | 📍Verona and online \n  🔗 www.2023.rubyday.it\npublished_at: \"2024-01-15\"\nstart_date: \"2023-06-16\"\nend_date: \"2023-06-16\"\nchannel_id: \"UCdWnwC8nz_CCFQrmLBrLCVw\"\nyear: 2023\nbanner_background: \"#5F4E9B\"\nfeatured_background: \"#5F4E9B\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://2023.rubyday.it\"\ncoordinates:\n  latitude: 45.43999609999999\n  longitude: 10.9719328\n"
  },
  {
    "path": "data/rubyday/rubyday-2023/venue.yml",
    "content": "---\nname: \"Hotel San Marco Verona\"\n\naddress:\n  street: \"Via Baldassarre Longhena, 42\"\n  city: \"Verona\"\n  region: \"Veneto\"\n  postal_code: \"37138\"\n  country: \"Italy\"\n  country_code: \"IT\"\n  display: \"Via Baldassarre Longhena, 42, 37138 Verona VR, Italy\"\n\ncoordinates:\n  latitude: 45.43999609999999\n  longitude: 10.9719328\n\nmaps:\n  google: \"https://maps.google.com/?q=Hotel+San+Marco+Verona,45.43999609999999,10.9719328\"\n  apple: \"https://maps.apple.com/?q=Hotel+San+Marco+Verona&ll=45.43999609999999,10.9719328\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=45.43999609999999&mlon=10.9719328\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"hana-harencarova-rubyday-2023\"\n  title: \"Investing in the Future: Unlocking the Potential of Junior Developers\"\n  raw_title: \"Investing in the Future: Unlocking the Potential of Junior Developers | Hana Harencarova | rubyday 2023\"\n  speakers:\n    - Hana Harencarova\n  event_name: \"rubyday 2023\"\n  date: \"2023-06-16\"\n  published_at: \"2024-01-13\"\n  description: |-\n    Junior developers are often undervalued in the workplace, yet they are the future of our industry.\n    Companies struggle to find enough senior developers but often miss out on the opportunity to educate their own.\n    In this talk, we will explore best practices for empowering and elevating junior developers.\n    How you, as a senior developer can contribute most effectively to their growth and use hands on learning to not only transfer knowledge but also motivate them. We will also look at how you, as a junior developer can best guide your early career and leverage the team to progress in your career and gain expertise.\n\n    Join us to learn how to invest in the future of your company by building a strong and diverse team.\n\n\n    rubyday 2023 happened in Verona on 16th June 2023\n\n    Info and details of this edition:\n    2023.rubyday.it/\n\n  video_provider: \"youtube\"\n  video_id: \"s-_9naKwAJ0\"\n\n- id: \"paolo-nusco-perrotta-rubyday-2023\"\n  title: \"How ChatGPT Works\"\n  raw_title: \"How ChatGPT Works | Paolo Perrotta | rubyday 2023\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"rubyday 2023\"\n  date: \"2023-06-16\"\n  published_at: \"2024-01-12\"\n  description: |-\n    ChatGPT astonishes everyone, including maybe his own designers.\n    As software developers, we're always looking for the gears behind the magic.\n    How can this thing possibly work?\n    Give me some time, and I'll give you an intuitive, high-level understanding of AI language models\n\n\n    rubyday 2023 happened in Verona on 16th June 2023\n\n    Info and details of this edition:\n    2023.rubyday.it/\n\n  video_provider: \"youtube\"\n  video_id: \"F8fOOjvZXJw\"\n\n- id: \"frederick-cheung-rubyday-2023\"\n  title: \"End to end typing for web applications\"\n  raw_title: \"End to end typing for web applications | Frederick Cheung | rubyday 2023\"\n  speakers:\n    - Frederick Cheung\n  event_name: \"rubyday 2023\"\n  date: \"2023-06-16\"\n  published_at: \"2024-01-12\"\n  description: |-\n    Ever had a bug because the frontend made incorrect assumptions about the shape of response data from the backend?\n    Or maybe you trod nervously during a refactor? Or perhaps you broke an app by changing the backend data in a way you didn’t think would matter?\n\n    This talk will show you how avoid these mistakes, enabling you to keep moving fast, by having a single source of truth for your data types, checked both on the frontend and the backend.\n\n    rubyday 2023 happened in Verona on 16th June 2023\n\n    Info and details of this edition:\n    2023.rubyday.it/\n\n  video_provider: \"youtube\"\n  video_id: \"KM5NwJemRWQ\"\n\n- id: \"alessandro-rizzo-rubyday-2023\"\n  title: \"RuboCop sent you a friend request\"\n  raw_title: \"RuboCop sent you a friend request | Alessandro Rizzo | rubyday 2023\"\n  speakers:\n    - Alessandro Rizzo\n  event_name: \"rubyday 2023\"\n  date: \"2023-06-16\"\n  published_at: \"2024-01-12\"\n  description: |-\n    Most of us are using RuboCop as a code style checker with the large amount of Cops that the community provides, but is that enough for you? By understanding the powerful internals of RuboCop, we’ll create a custom Cop and a custom style guide to push forward the quality of the code we write daily.\n\n\n    rubyday 2023 happened in Verona on 16th June 2023\n\n    Info and details of this edition:\n    2023.rubyday.it/\n\n  video_provider: \"youtube\"\n  video_id: \"S-4dGvLisDE\"\n\n- id: \"ju-liu-rubyday-2023\"\n  title: \"The Functional Alternative\"\n  raw_title: \"The Functional Alternative | Ju Liu | rubyday 2023\"\n  speakers:\n    - Ju Liu\n  event_name: \"rubyday 2023\"\n  date: \"2023-06-16\"\n  published_at: \"2024-01-13\"\n  description: |-\n    We'll start with a simple Ruby Kata and solve it together, live, with imperative programming.\n    We'll then fix the many, many, many things we got wrong. Then we'll solve the problem again using patterns from functional programming. You'll leave this talk with a clear and concrete example of why functional programming matters, why immutable code matters, and why it can help you writing bug-free code.\n\n    The next time you find yourself writing imperative code, you'll think about... the functional alternative.\n\n\n    rubyday 2023 happened in Verona on 16th June 2023\n\n    Info and details of this edition:\n    2023.rubyday.it/\n\n  video_provider: \"youtube\"\n  video_id: \"WloeM166UG0\"\n\n- id: \"bozhidar-batsov-rubyday-2023\"\n  title: \"Ruby's Creed\"\n  raw_title: \"Ruby's Creed | Bozhidar Batsov | rubyday 2023\"\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"rubyday 2023\"\n  date: \"2023-06-16\"\n  published_at: \"2024-01-13\"\n  description: |-\n    Every programming language has some fundamental idea(s) that drives its design and evolution.\n    For Haskell that’s functional purity and state-of-the-art static typing, for Erlang that’s distributed programming and fault tolerance, for Clojure that’s simplicity and stability.\n\n    What all these examples have in common is that they are relatively easy to understand and map to design decisions in the languages. This, in turn, makes it possible to determine down the road whether a language sticks to its core values or deviates from them.\n\n    Ruby, however, is very different. It’s world famous for its unique creed - “optimizing for programming happiness”. But what does this really mean? How does one optimize for happiness?\n    Unfortunately I’ve never heard Matz speak about this, so in this talk I’ll offer you my perspective instead. I'll also discuss some of the recent changes to Ruby and whether they adhere to its creed or not. Controversy & fun ahead!\n\n\n    rubyday 2023 happened in Verona on 16th June 2023\n\n    Info and details of this edition:\n    2023.rubyday.it/\n\n  video_provider: \"youtube\"\n  video_id: \"Zpl7yBkz92Q\"\n\n- id: \"ridhwana-khan-rubyday-2023\"\n  title: \"Caching strategies on dev.to\"\n  raw_title: \"Caching strategies on https://dev.to | Ridhwana Khan | rubyday 2023\"\n  speakers:\n    - Ridhwana Khan\n  event_name: \"rubyday 2023\"\n  date: \"2023-06-16\"\n  published_at: \"2024-01-13\"\n  description: |-\n    We’ve always put a lot of effort into performance at DEV (https://dev.to/).\n    We want our users to be able to see their content almost instantaneously when interacting with our site.\n    In order to do so we’ve placed emphasis on caching. We’ve had to ask ourselves questions like what are the right things to cache?\n    Which layer in the stack would be best to cache it? And how will this affect the overall performance?\n\n    During this presentation, I’d like to show you some of the caching strategies we have in place and discuss how they’ve sped up the interactions within our site.\n\n\n    rubyday 2023 happened in Verona on 16th June 2023\n\n    Info and details of this edition:\n    2023.rubyday.it/\n\n  video_provider: \"youtube\"\n  video_id: \"fCy_76bS-m4\"\n\n- id: \"giulia-mialich-rubyday-2023\"\n  title: \"One-on-One: the benefit you should look for\"\n  raw_title: \"One-on-One: the benefit you should look for | Giulia Mialich | rubyday 2023\"\n  speakers:\n    - Giulia Mialich\n  event_name: \"rubyday 2023\"\n  date: \"2023-06-16\"\n  published_at: \"2024-01-12\"\n  description: |-\n    One-on-one meetings are crucial for promoting a healthy company culture, but do the participants truly recognize their value?\n    The theory says these meetings provide an excellent opportunity for managers and employees to improve communication, reduce conflicts, and increase job satisfaction and motivation. The reality shows that one-on-one effectiveness relies heavily on human interactions, making success unpredictable.\n\n    During the session, we'll explore effective practices to help answer questions such as:\n    What makes one-on-one meetings effective for managers and what for engineers?\n    How can we effectively communicate with silent individuals during these meetings?\n    Should we establish an agenda for the meeting or not?\n    Should personal matters be discussed during those sections?\n\n    This talk is a must-attend if you want to improve your team management skills or gain insight into how one-on-one meetings can contribute to your professional development.\n\n\n    ---\n    rubyday 2023 happened in Verona on 16th June 2023\n\n    Info and details of this edition:\n    2023.rubyday.it/\n\n  video_provider: \"youtube\"\n  video_id: \"7930cQNxM3g\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2024/cfp.yml",
    "content": "---\n- link: \"https://2024.rubyday.it/welcome/cfp.html\"\n  open_date: \"2023-11-03\"\n  close_date: \"2024-01-31\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2024/event.yml",
    "content": "---\nid: \"PLWK9j6ps_unkUWzaxZrYpkOU5pOg8BZBE\"\ntitle: \"rubyday 2024\"\nkind: \"conference\"\nlocation: \"Verona, Italy\"\ndescription: |-\n  rubyday 2024 is the 11th edition of the Italian Ruby conference. The event is international and allows all Rubyists to meet and share experience while having fun and networking in an enjoyable context.\npublished_at: \"2024-12-16\"\nstart_date: \"2024-05-31\"\nend_date: \"2024-05-31\"\nchannel_id: \"UCkxizXigZY3iewM6dswcYzQ\"\nyear: 2024\nwebsite: \"https://2024.rubyday.it\"\nbanner_background: \"linear-gradient(to right, #1F133B 50%, #07040D 50%)\"\nfeatured_background: \"#5F4E9B\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 45.43999609999999\n  longitude: 10.9719328\n"
  },
  {
    "path": "data/rubyday/rubyday-2024/schedule.yml",
    "content": "# Schedule: https://2024.rubyday.it/schedule/\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-05-31\"\n    grid:\n      - start_time: \"08:45\"\n        end_time: \"09:25\"\n        slots: 1\n        items:\n          - Check-in and welcome coffee\n\n      - start_time: \"09:25\"\n        end_time: \"09:40\"\n        slots: 1\n        items:\n          - Opening by GrUSP\n\n      - start_time: \"09:40\"\n        end_time: \"10:20\"\n        slots: 1\n\n      - start_time: \"10:20\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n        items:\n          - Coffee break\n\n      - start_time: \"11:30\"\n        end_time: \"12:10\"\n        slots: 1\n\n      - start_time: \"12:10\"\n        end_time: \"12:50\"\n        slots: 1\n\n      - start_time: \"12:50\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch break\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"14:30\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"15:10\"\n        end_time: \"15:50\"\n        slots: 1\n\n      - start_time: \"15:50\"\n        end_time: \"16:20\"\n        slots: 1\n        items:\n          - Coffee break\n\n      - start_time: \"16:20\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:00\"\n        end_time: \"17:40\"\n        slots: 1\n\n      - start_time: \"17:40\"\n        end_time: \"17:50\"\n        slots: 1\n        items:\n          - Closing by GrUSP - See you next time!\n"
  },
  {
    "path": "data/rubyday/rubyday-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Main\"\n      description: |-\n        1 dedicated session (30 mins max, no commercial talks accepted), Access to attendees list (attendees who agreed to share their contact with sponsors), Large Stand (in-person event), Large Virtual booth, Your logo on conference rollup banners (in-person event), Your own rollup banner (80x200cm) in the conference room (in-person event), Your logo displayed on rotation in the lower third throughout the event, Bring your gadgets to the in-person event, Your own digital flyer and/or gadget in digital swag bag, Your logo in pre-event communications, Your logo on conference website, Your company mentioned and the logo shown during the opening remarks, 10 free tickets for the online event, 5 free tickets for the in-person event\n      level: 1\n      sponsors: []\n\n    - name: \"Diamond\"\n      description: |-\n        Access to attendees list (attendees who agreed to share their contact with sponsors), Large Stand (in-person event), Medium Virtual booth, Your logo on conference rollup banners (in-person event), Your own rollup banner (80x200cm) in the conference room (in-person event), Your logo displayed on rotation in the lower third throughout the event, Bring your gadgets to the in-person event, Your own digital flyer and/or gadget in digital swag bag, Your logo in pre-event communications, Your logo on conference website, Your company mentioned and the logo shown during the opening remarks, 8 free tickets for the online event, 4 free tickets for the in-person event\n      level: 2\n      sponsors: []\n\n    - name: \"Platinum\"\n      description: |-\n        Small Stand (in-person event), Small Virtual booth, Your logo on conference rollup banners (in-person event), Your own rollup banner (80x200cm) in the conference room (in-person event), Your logo displayed on rotation in the lower third throughout the event, Bring your gadgets to the in-person event, Your own digital flyer and/or gadget in digital swag bag, Your logo in pre-event communications, Your logo on conference website, Your company mentioned and the logo shown during the opening remarks, 6 free tickets for the online event, 3 free tickets for the in-person event\n      level: 3\n      sponsors: []\n\n    - name: \"Gold\"\n      description: |-\n        Your logo on conference rollup banners (in-person event), Your own rollup banner (80x200cm) in the conference room (in-person event), Your logo displayed on rotation in the lower third throughout the event, Bring your gadgets to the in-person event, Your own digital flyer and/or gadget in digital swag bag, Your logo in pre-event communications, Your logo on conference website, Your company mentioned and the logo shown during the opening remarks, 5 free tickets for the online event, 2 free tickets for the in-person event\n      level: 4\n      sponsors:\n        - name: \"Condense\"\n          badge: \"\"\n          website: \"https://condense.tech\"\n          slug: \"condense\"\n          logo_url: \"https://2024.rubyday.it/img/logos/condense.svg\"\n\n        - name: \"Seesaw\"\n          badge: \"\"\n          website: \"https://seesaw.it/\"\n          slug: \"seesaw\"\n          logo_url: \"https://2024.rubyday.it/img/logos/seesaw.png\"\n\n        - name: \"weLaika\"\n          badge: \"\"\n          website: \"https://welaika.com/\"\n          slug: \"welaika\"\n          logo_url: \"https://2024.rubyday.it/img/logos/welaika.svg\"\n\n        - name: \"Workwave\"\n          badge: \"\"\n          website: \"https://www.workwave.com/\"\n          slug: \"workwave\"\n          logo_url: \"https://2024.rubyday.it/img/logos/workwave.svg\"\n\n    - name: \"Silver\"\n      description: |-\n        Your logo on conference rollup banners (in-person event), Your logo displayed on rotation in the lower third throughout the event, Bring your gadgets to the in-person event, Your own digital flyer and/or gadget in digital swag bag, Your logo in pre-event communications, Your logo on conference website, Your company mentioned and the logo shown during the opening remarks, 4 free tickets for the online event, 1 free tickets for the in-person event\n      level: 5\n      sponsors:\n        - name: \"AppSignal\"\n          badge: \"\"\n          website: \"https://www.appsignal.com/ruby\"\n          slug: \"appsignal\"\n          logo_url: \"https://2024.rubyday.it/img/logos/appsignal.svg\"\n\n        - name: \"Archeido\"\n          badge: \"\"\n          website: \"https://archeido.com/\"\n          slug: \"archeido\"\n          logo_url: \"https://2024.rubyday.it/img/logos/archeido.svg\"\n\n        - name: \"Daruma\"\n          badge: \"\"\n          website: \"http://www.darumahq.com/\"\n          slug: \"daruma\"\n          logo_url: \"https://2024.rubyday.it/img/logos/daruma.svg\"\n\n        - name: \"Google Cloud\"\n          badge: \"\"\n          website: \"https://cloud.google.com/\"\n          slug: \"google-cloud\"\n          logo_url: \"https://2024.rubyday.it/img/logos/google-cloud.svg\"\n\n    - name: \"Bronze\"\n      description: |-\n        Your logo in pre-event communications, Your logo on conference website, Your company mentioned and the logo shown during the opening remarks, 2 free tickets for the online event\n      level: 6\n      sponsors:\n        - name: \"Stickermule\"\n          badge: \"\"\n          website: \"https://www.stickermule.com/it/adesivi-personalizzati\"\n          slug: \"stickermule\"\n          logo_url: \"https://2024.rubyday.it/img/logos/stickermule.svg\"\n\n    - name: \"Diversity\"\n      description: |-\n        Your logo in pre-event communications, Your logo on conference website, Your company mentioned and the logo shown during the opening remarks, 2 free tickets for the online event\n      level: 7\n      sponsors: []\n"
  },
  {
    "path": "data/rubyday/rubyday-2024/venue.yml",
    "content": "---\nname: \"Hotel San Marco Verona\"\n\naddress:\n  street: \"Via Baldassarre Longhena, 42\"\n  city: \"Verona\"\n  region: \"Veneto\"\n  postal_code: \"37138\"\n  country: \"Italy\"\n  country_code: \"IT\"\n  display: \"Via Baldassarre Longhena, 42, 37138 Verona VR, Italy\"\n\ncoordinates:\n  latitude: 45.43999609999999\n  longitude: 10.9719328\n\nmaps:\n  google: \"https://maps.google.com/?q=Hotel+San+Marco+Verona,45.43999609999999,10.9719328\"\n  apple: \"https://maps.apple.com/?q=Hotel+San+Marco+Verona&ll=45.43999609999999,10.9719328\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=45.43999609999999&mlon=10.9719328\"\n"
  },
  {
    "path": "data/rubyday/rubyday-2024/videos.yml",
    "content": "---\n# Website: https://2024.rubyday.it\n# Schedule: https://2024.rubyday.it/schedule\n\n- id: \"bozhidar-batsov-rubyday-2024\"\n  title: \"Weird Ruby\"\n  raw_title: \"Weird Ruby | Bozhidar Batsov | rubyday 2024\"\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"rubyday 2024\"\n  published_at: \"2024-12-16\"\n  date: \"2024-05-31\"\n  description: |-\n    Over its long history (31 years and counting) Ruby has accumulated dozens of little known, obscure and somewhat weird features. Some of them are annoying, some of them are fun and a few are actually quite useful. In this session we'll go over some of my favorite weird Ruby features and we'll discuss how to make the best use of them (provided they are any useful, that is). It will be weird and fun, I promise!\n\n\n\n    Bozhidar Batsov is Senior Director of Engineering @ Toptal.\n\n    ---\n\n    rubyday 2024 is the 11th edition of the Italian Ruby conference, organized by GrUSP,\n    The event is international, and all sessions will be in English.\n    📍 Verona | 📅 May 21, 2024\n\n    Join the next edition\n    🔗 www.rubyday.it\n\n    ---\n\n    rubyday is organized by GrUSP.\n    We organize events, conferences and informal meetings involving Italian and international professionals.\n    We aim to make the ecosystem of the Italian world of web development better both in terms of skills and opportunities by creating greater awareness through comparison and sharing.\n\n    Subscribe to our newsletter:\n    ✉️ [www.grusp.org/en/newsletter](http://www.grusp.org/en/newsletter)\n\n     Follow us\n     Website https://www.grusp.org/en/\n     LinkedIn https://www.linkedin.com/company/grusp\n     Twitter https://twitter.com/grusp\n     Instagram https://www.instagram.com/grusp_\n     Facebook https://www.facebook.com/GrUSP\n  video_provider: \"youtube\"\n  video_id: \"3R6-tUy0mJo\"\n\n- id: \"riccardo-carlesso-rubyday-2024\"\n  title: \"News Crawler via Langchain.rb and Gemini APIs\"\n  raw_title: \"News Crawler via Langchain.RB and Gemini APIs |  Riccardo Carlesso | rubyday 2024\"\n  speakers:\n    - Riccardo Carlesso\n  event_name: \"rubyday 2024\"\n  published_at: \"2024-12-16\"\n  date: \"2024-05-31\"\n  description: |-\n    How can we get an LLM to be updated to today's news? Gen AI is great at answering questions...from the past. After the LLM was trained, all you can do is RAG. How about crawling the web for latest news with Gemini for multimodal extraction and offering summarization by your favorite topic? It all gets more exciting thanks to Andrei's langchainrb gem.\n\n\n    Riccardo Carlesso è Developer Advocate @ Google Cloud.\n\n\n    ---\n\n    rubyday 2024 is the 11th edition of the Italian Ruby conference, organized by GrUSP,\n    The event is international, and all sessions will be in English.\n    📍 Verona | 📅 May 21, 2024\n\n    Join the next edition\n    🔗 www.rubyday.it\n\n    ---\n\n    rubyday is organized by GrUSP.\n    We organize events, conferences and informal meetings involving Italian and international professionals.\n    We aim to make the ecosystem of the Italian world of web development better both in terms of skills and opportunities by creating greater awareness through comparison and sharing.\n\n    Subscribe to our newsletter:\n    ✉️ [www.grusp.org/en/newsletter](http://www.grusp.org/en/newsletter)\n\n     Follow us\n     Website https://www.grusp.org/en/\n     LinkedIn https://www.linkedin.com/company/grusp\n     Twitter https://twitter.com/grusp\n     Instagram https://www.instagram.com/grusp_\n     Facebook https://www.facebook.com/GrUSP\n  video_provider: \"youtube\"\n  video_id: \"JhjM6Qi9I5U\"\n\n- id: \"emiliano-della-casa-rubyday-2024\"\n  title: \"Using Ruby on AWS's Lambda\"\n  raw_title: \"Using Ruby on AWS's Lambda | Emiliano Della Casa | rubyday 2024\"\n  speakers:\n    - Emiliano Della Casa\n  event_name: \"rubyday 2024\"\n  published_at: \"2024-12-16\"\n  date: \"2024-05-31\"\n  description: |-\n    A Hitchhiker's Guide to Ruby on AWS's Lambda. Starting from a real world example, I will show how to develop and deploy ruby code on AWS's Lambda. I will show why we chose ruby for the project and why we decided to move part of the monolith code to microservices keeping ruby as main language. I will also show how to test and deploy the code using rspec, cucumber and serverless for a complete CI/CD cycle.\n\n\n    Emiliano Della Casa is Software Architect Independent Consultant.\n\n    ---\n\n    rubyday 2024 is the 11th edition of the Italian Ruby conference, organized by GrUSP,\n    The event is international, and all sessions will be in English.\n    📍 Verona | 📅 May 21, 2024\n\n    Join the next edition\n    🔗 www.rubyday.it\n\n    ---\n\n    rubyday is organized by GrUSP.\n    We organize events, conferences and informal meetings involving Italian and international professionals.\n    We aim to make the ecosystem of the Italian world of web development better both in terms of skills and opportunities by creating greater awareness through comparison and sharing.\n\n    Subscribe to our newsletter:\n    ✉️ [www.grusp.org/en/newsletter](http://www.grusp.org/en/newsletter)\n\n     Follow us\n     Website https://www.grusp.org/en/\n     LinkedIn https://www.linkedin.com/company/grusp\n     Twitter https://twitter.com/grusp\n     Instagram https://www.instagram.com/grusp_\n     Facebook https://www.facebook.com/GrUSP\n  video_provider: \"youtube\"\n  video_id: \"3lhr-L5yft4\"\n\n- id: \"lucian-ghinda-rubyday-2024\"\n  title: \"Discover Modern Ruby Features\"\n  raw_title: \"Discover Modern Ruby features | Lucian Ghinda | rubyday 2024\"\n  speakers:\n    - Lucian Ghinda\n  event_name: \"rubyday 2024\"\n  published_at: \"2024-12-16\"\n  date: \"2024-05-31\"\n  description: |-\n    Exploring Ruby's evolution as a language: Dive into new features like pattern matching, hash literal value omission, object shapes, and a wide range of new abilities. Learn their real-world applications & impact on code readability in my talk. Let's unlock Ruby's full potential!\n\n    Lucian Ghinda is Senior Ruby Developer | Curator of Short Ruby Newsletter.\n\n    ---\n\n    rubyday 2024 is the 11th edition of the Italian Ruby conference, organized by GrUSP,\n    The event is international, and all sessions will be in English.\n    📍 Verona | 📅 May 21, 2024\n\n    Join the next edition\n    🔗 www.rubyday.it\n\n    ---\n\n    rubyday is organized by GrUSP.\n    We organize events, conferences and informal meetings involving Italian and international professionals.\n    We aim to make the ecosystem of the Italian world of web development better both in terms of skills and opportunities by creating greater awareness through comparison and sharing.\n\n    Subscribe to our newsletter:\n    ✉️ [www.grusp.org/en/newsletter](http://www.grusp.org/en/newsletter)\n\n     Follow us\n     Website https://www.grusp.org/en/\n     LinkedIn https://www.linkedin.com/company/grusp\n     Twitter https://twitter.com/grusp\n     Instagram https://www.instagram.com/grusp_\n     Facebook https://www.facebook.com/GrUSP\n  video_provider: \"youtube\"\n  video_id: \"IsjrIX7-lms\"\n\n# Lunch\n\n# Lightning Talks\n\n- id: \"abiodun-olowode-rubyday-2024\"\n  title: \"Monads: Exploring Railway Oriented Programming in Ruby\"\n  raw_title: \"Monads: Exploring Railway Oriented Programming in Ruby | Abiodun Olowode | rubyday 2024\"\n  speakers:\n    - Abiodun Olowode\n  event_name: \"rubyday 2024\"\n  published_at: \"2024-12-16\"\n  date: \"2024-05-31\"\n  description: |-\n    Can we apply the fundamental concept of monads in building maintainable and robust applications in Ruby? In this talk, we'll explore what railway-oriented programming is and how it enhances error handling, simplifies complex workflows, and improves code readability via the use of monads. Throughout the session, we'll write code together and actively test it, uncovering the unique failure and success contexts of monads.\n\n    Abiodun Olowode is Senior Engineering Manager @ Factorial.\n\n    ---\n\n    rubyday 2024 is the 11th edition of the Italian Ruby conference, organized by GrUSP,\n    The event is international, and all sessions will be in English.\n    📍 Verona | 📅 May 21, 2024\n\n    Join the next edition\n    🔗 www.rubyday.it\n\n    ---\n\n    rubyday is organized by GrUSP.\n    We organize events, conferences and informal meetings involving Italian and international professionals.\n    We aim to make the ecosystem of the Italian world of web development better both in terms of skills and opportunities by creating greater awareness through comparison and sharing.\n\n    Subscribe to our newsletter:\n    ✉️ [www.grusp.org/en/newsletter](http://www.grusp.org/en/newsletter)\n\n     Follow us\n     Website https://www.grusp.org/en/\n     LinkedIn https://www.linkedin.com/company/grusp\n     Twitter https://twitter.com/grusp\n     Instagram https://www.instagram.com/grusp_\n     Facebook https://www.facebook.com/GrUSP\n  video_provider: \"youtube\"\n  video_id: \"Tb7mQ2d7HPA\"\n\n- id: \"rashmi-nagpal-rubyday-2024\"\n  title: \"From Data to Recommendations: Building an Intelligent System with Ruby on Rails\"\n  raw_title: \"From Data to Recommendations: Building an Intelligent System with ROR | Rashmi Nagpal | rubyday 2024\"\n  speakers:\n    - Rashmi Nagpal\n  event_name: \"rubyday 2024\"\n  published_at: \"2024-12-16\"\n  date: \"2024-05-31\"\n  description: |-\n    From Data to Recommendations: Building an Intelligent System with Ruby on Rails.\n\n    Did you know that 75% of users are more likely to engage with a platform offering personalized recommendations? Well, with 1.2 million websites worldwide built on Ruby on Rails, let’s harness the power of this popular framework to implement intelligent recommendations effortlessly! This talk will explore the exciting realm of recommendation systems and how to build an intelligent system using Ruby on Rails. We will start by unraveling the fundamentals of recommendation systems, including collaborative filtering. With this foundation, we will integrate machine learning techniques into the Ruby on Rails framework. Throughout the talk, we will discuss various strategies for capturing and utilizing user preferences, improving recommendation accuracy, and continuously refining the system based on user feedback. By the end of this talk, you will have gained valuable insights into building an intelligent system that can transform raw data into valuable recommendations within a Ruby on Rails application!\n\n\n    Rashmi Nagpal is Machine Learning Engineer @ Patchstack.\n\n\n    ---\n\n    rubyday 2024 is the 11th edition of the Italian Ruby conference, organized by GrUSP,\n    The event is international, and all sessions will be in English.\n    📍 Verona | 📅 May 21, 2024\n\n    Join the next edition\n    🔗 www.rubyday.it\n\n    ---\n\n    rubyday is organized by GrUSP.\n    We organize events, conferences and informal meetings involving Italian and international professionals.\n    We aim to make the ecosystem of the Italian world of web development better both in terms of skills and opportunities by creating greater awareness through comparison and sharing.\n\n    Subscribe to our newsletter:\n    ✉️ [www.grusp.org/en/newsletter](http://www.grusp.org/en/newsletter)\n\n     Follow us\n     Website https://www.grusp.org/en/\n     LinkedIn https://www.linkedin.com/company/grusp\n     Twitter https://twitter.com/grusp\n     Instagram https://www.instagram.com/grusp_\n     Facebook https://www.facebook.com/GrUSP\n  video_provider: \"youtube\"\n  video_id: \"rYAIezv0Sgw\"\n\n- id: \"cristian-planas-rubyday-2024\"\n  title: \"2,000 Engineers, 2 Million Lines of Code: The History of a Rails Monolith\"\n  raw_title: \"The history of a Rails monolith | C.Planas & A. Mikhaylov | rubyday 2024\"\n  speakers:\n    - Cristian Planas\n    - Anatoly Mikhaylov\n  event_name: \"rubyday 2024\"\n  published_at: \"2024-12-16\"\n  date: \"2024-05-31\"\n  description: |-\n    2000 engineers, 2 millions lines of code: the history of a Rails monolith\n\n    Rails is the best framework for building your startup. But what happens when the startup becomes a leading business? How do companies that have Rails at the heart of its stack manage growth? How do you maintain a growing application for 15 years in a constantly changing environment? In this Cristian Planas, Senior Staff Engineer at Zendesk, will share with you his 10 years of experience in a company that has succeeded by keeping Rails in its core. He will guide you through the life of a Rails-centered organization, that scaled from zero to hundreds of millions of users.\n\n    ---\n\n    rubyday 2024 is the 11th edition of the Italian Ruby conference, organized by GrUSP,\n    The event is international, and all sessions will be in English.\n    📍 Verona | 📅 May 21, 2024\n\n    Join the next edition\n    🔗 www.rubyday.it\n\n    ---\n\n    rubyday is organized by GrUSP.\n    We organize events, conferences and informal meetings involving Italian and international professionals.\n    We aim to make the ecosystem of the Italian world of web development better both in terms of skills and opportunities by creating greater awareness through comparison and sharing.\n\n    Subscribe to our newsletter:\n    ✉️ [www.grusp.org/en/newsletter](http://www.grusp.org/en/newsletter)\n\n     Follow us\n     Website https://www.grusp.org/en/\n     LinkedIn https://www.linkedin.com/company/grusp\n     Twitter https://twitter.com/grusp\n     Instagram https://www.instagram.com/grusp_\n     Facebook https://www.facebook.com/GrUSP\n  video_provider: \"youtube\"\n  video_id: \"pA3JtUfQ8Lc\"\n\n- id: \"monica-giambitto-rubyday-2024\"\n  title: \"Panel: Navigating A Career: Tech, People, and LLMs\"\n  raw_title: \"Panel - Navigating a career: tech, people, and LLMs | Panel | rubyday 2024\"\n  speakers:\n    - Monica Giambitto\n    - Bozhidar Batsov\n    - Rashmi Nagpal\n    - Lucian Ghinda\n  event_name: \"rubyday 2024\"\n  published_at: \"2024-12-16\"\n  date: \"2024-05-31\"\n  description: |-\n    Join our distinguished panelists as they explore the future of careers in the tech industry amidst rapid technological advancements and economic uncertainty. This discussion will cover key topics such as transitioning into leadership roles, upskilling, navigating career pivots, and insights for early-career developers. Learn strategies for staying relevant in a fast-evolving field and gain practical advice on building a strong professional network. Don’t miss this engaging conversation that promises to provide valuable perspectives and actionable insights for tech professionals at all stages of their careers.\n\n\n    Monica Giambitto is Engineering Leader - MASTER OF CEREMONIES\n    Bozhidar Batsov is Senior Director of Engineering @ Toptal\n    Rashmi Nagpal is Machine Learning Engineer @ Patchstack\n    Lucian Ghinda is Senior Ruby Developer\n\n    ---\n\n    rubyday 2024 is the 11th edition of the Italian Ruby conference, organized by GrUSP,\n    The event is international, and all sessions will be in English.\n    📍 Verona | 📅 May 21, 2024\n\n    Join the next edition\n    🔗 www.rubyday.it\n\n    ---\n\n    rubyday is organized by GrUSP.\n    We organize events, conferences and informal meetings involving Italian and international professionals.\n    We aim to make the ecosystem of the Italian world of web development better both in terms of skills and opportunities by creating greater awareness through comparison and sharing.\n\n    Subscribe to our newsletter:\n    ✉️ [www.grusp.org/en/newsletter](http://www.grusp.org/en/newsletter)\n\n     Follow us\n     Website https://www.grusp.org/en/\n     LinkedIn https://www.linkedin.com/company/grusp\n     Twitter https://twitter.com/grusp\n     Instagram https://www.instagram.com/grusp_\n     Facebook https://www.facebook.com/GrUSP\n  video_provider: \"youtube\"\n  video_id: \"nNIFbG49Tj4\"\n"
  },
  {
    "path": "data/rubyday/series.yml",
    "content": "---\nname: \"rubyday\"\nwebsite: \"https://rubyday.it\"\ntwitter: \"rubydayit\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"rubyday\"\ndefault_country_code: \"IT\"\nyoutube_channel_name: \"GrUSP\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCdWnwC8nz_CCFQrmLBrLCVw\"\n"
  },
  {
    "path": "data/rubyenrails/rubyandrails-2010/event.yml",
    "content": "---\nid: \"rubyandrails-2010\"\ntitle: \"RubyAndRails Europe 2010\"\nkind: \"conference\"\nlocation: \"Amsterdam, Netherlands\"\ndescription: |-\n  Formerly known as RubyEnRails, this years edition of the RubyAndRails Conf will again be a two day conference.\nstart_date: \"2010-10-21\"\nend_date: \"2010-10-22\"\nyear: 2010\nwebsite: \"https://web.archive.org/web/20130114155815/http://rubyandrails.eu/\"\noriginal_website: \"http://rubyandrails.eu/\"\ncoordinates:\n  latitude: 52.3768\n  longitude: 4.9221\n"
  },
  {
    "path": "data/rubyenrails/rubyandrails-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubyenrails/rubyenrails-2006/event.yml",
    "content": "---\nid: \"rubyenrails-2006\"\ntitle: \"RubyEnRails 2006\"\nkind: \"conference\"\nlocation: \"Amsterdam, Netherlands\"\ndescription: |-\n  Ruby en Rails 2006\nstart_date: \"2006-05-18\"\nend_date: \"2006-05-18\"\nyear: 2006\nwebsite: \"https://web.archive.org/web/20060618220328/http://www.profict.nl/ruby/\"\noriginal_website: \"http://rubyenrails.nl/\"\ncoordinates:\n  latitude: 52.3675734\n  longitude: 4.9041389\n"
  },
  {
    "path": "data/rubyenrails/rubyenrails-2006/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://web.archive.org/web/20060618220328/http://www.profict.nl/ruby/\n# https://web.archive.org/web/20060411005928/http://www.rubyenrails.nl/\n---\n[]\n"
  },
  {
    "path": "data/rubyenrails/rubyenrails-2007/event.yml",
    "content": "---\nid: \"rubyenrails-2007\"\ntitle: \"RubyEnRails 2007\"\nkind: \"conference\"\nlocation: \"Amsterdam, Netherlands\"\ndescription: |-\n  Ruby en Rails 2007\nstart_date: \"2007-06-07\"\nend_date: \"2007-06-07\"\nyear: 2007\nwebsite: \"https://web.archive.org/web/20070820192609/http://2007.rubyenrails.nl/\"\noriginal_website: \"http://2007.rubyenrails.nl/\"\ncoordinates:\n  latitude: 52.3675734\n  longitude: 4.9041389\n"
  },
  {
    "path": "data/rubyenrails/rubyenrails-2007/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://web.archive.org/web/20070820192609/http://2007.rubyenrails.nl/\n# https://web.archive.org/web/20090308083909/http://rubyenrails.nl:80/articles/2007/03/20/rubyenrails-2007\n---\n[]\n"
  },
  {
    "path": "data/rubyenrails/rubyenrails-2008/event.yml",
    "content": "---\nid: \"rubyenrails-2008\"\ntitle: \"RubyEnRails 2008\"\nkind: \"conference\"\nlocation: \"Amsterdam, Netherlands\"\ndescription: |-\n  Ruby en Rails 2008\nstart_date: \"2008-06-10\"\nend_date: \"2008-06-10\"\nyear: 2008\nwebsite: \"https://web.archive.org/web/20080915055623/http://2008.rubyenrails.nl/\"\ncoordinates:\n  latitude: 52.3675734\n  longitude: 4.9041389\n"
  },
  {
    "path": "data/rubyenrails/rubyenrails-2008/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://web.archive.org/web/20080915055623/http://2008.rubyenrails.nl/\n# https://web.archive.org/web/20240720211123/https://rubyenrails.nl/articles/2008/06/11/rubyenrails-2008-een-groot-succes.html\n# https://web.archive.org/web/20090421235744/http://2008.rubyenrails.nl/speakers\n# https://web.archive.org/web/20240720220549/https://rubyenrails.nl/articles/2008/05/06/inschrijving-ruby-en-rails-2008-geopend.html\n# http://rer2008.holder.nl/\n# https://web.archive.org/web/20080507151743/http://rer2008.holder.nl/\n# Schedule: https://web.archive.org/web/20090119082242/http://2008.rubyenrails.nl/tracks\n---\n[]\n"
  },
  {
    "path": "data/rubyenrails/rubyenrails-2009/event.yml",
    "content": "---\nid: \"rubyenrails-2009\"\ntitle: \"RubyEnRails 2009\"\nkind: \"conference\"\nlocation: \"Amsterdam, Netherlands\"\ndescription: |-\n  Ruby en Rails 2009\nstart_date: \"2009-10-30\"\nend_date: \"2009-10-30\"\nyear: 2009\nwebsite: \"https://web.archive.org/web/20091231043249/http://2009.rubyenrails.nl/\"\noriginal_website: \"http://2009.rubyenrails.nl/\"\ncoordinates:\n  latitude: 52.3675734\n  longitude: 4.9041389\n"
  },
  {
    "path": "data/rubyenrails/rubyenrails-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://web.archive.org/web/20091231043249/http://2009.rubyenrails.nl/\n# https://www.vimeo.com/7643075\n# https://vimeo.com/user2623183\n---\n[]\n"
  },
  {
    "path": "data/rubyenrails/series.yml",
    "content": "---\nname: \"RubyEnRails\"\nwebsite: \"https://web.archive.org/web/20080915055623/http://2008.rubyenrails.nl/\"\ntwitter: \"\"\nmastodon: \"\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyeurope/rubyeurope-meetup/event.yml",
    "content": "---\nid: \"rubyeurope-meetup\"\ntitle: \"Ruby Europe Meetup\"\nlocation: \"Europe\"\ndescription: |-\n  Ruby Europe organizes Ruby + AI meetups across European cities\npublished_at: \"2025-07-17\"\nchannel_id: \"UCPkGcnK-vKiYVmefSp22enA\"\nwebsite: \"https://rubyeurope.com\"\nkind: \"meetup\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#B72425\"\nbanner_background: |-\n  linear-gradient(to bottom, #501F1B 67%, #501F1B 67%) left top / 50% 100% no-repeat, /* Left side */\n  linear-gradient(to bottom, #4A1D1A 67%, #4A1D1A 67%) right top / 50% 100% no-repeat /* Right side */\ncoordinates:\n  latitude: 54.5259614\n  longitude: 15.2551187\n"
  },
  {
    "path": "data/rubyeurope/rubyeurope-meetup/videos.yml",
    "content": "---\n# 2025\n\n- title: \"London Ruby + AI Meetup June 2025\"\n  raw_title: \"London Ruby + AI meetup, June 17th, 2025\"\n  event_name: \"London Ruby + AI Meetup June 2025\"\n  date: \"2025-06-17\"\n  published_at: \"2025-07-17\"\n  video_provider: \"children\"\n  video_id: \"london-ruby-ai-meetup-june-2025\"\n  id: \"london-ruby-ai-meetup-june-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GtPvD_JW4AA4Hiz?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GtPvD_JW4AA4Hiz?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GtPvD_JW4AA4Hiz?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GtPvD_JW4AA4Hiz?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GtPvD_JW4AA4Hiz?format=jpg&name=4096x4096\"\n  description: |-\n    Ruby + AI meetup that took place in London on June 17th, 2025, organized by Ruby Europe.\n\n    The meetup focused on connecting AI models to Ruby applications and modern test-driven development practices enhanced by AI.\n  talks:\n    - title: \"FastMCP How to connect AI models to your Ruby application\"\n      raw_title: \"FastMCP How to connect AI models to your Ruby application - Yorick Jacquin\"\n      speakers:\n        - Yorick Jacquin\n      event_name: \"London Ruby + AI Meetup June 2025\"\n      date: \"2025-06-17\"\n      published_at: \"2025-07-17\"\n      video_provider: \"youtube\"\n      video_id: \"6hY1IoOgO6Y\"\n      id: \"yorick-jacquin-london-ruby-ai-meetup-june-2025\"\n      description: |-\n        Yorick Jackquin presentation at the London Ruby + AI meetup, which took place on June 17th, 2025.\n\n        The topic was FastMCP, which is a Ruby implementation of a Model Context Protocol (MCP), allowing you to build an MCP Server in minutes.\n      language: \"english\"\n\n    - title: \"TDD 2.0: AI Brings Test-Driven Development Back on Track\"\n      raw_title: \"TDD 2.0: AI Brings Test-Driven Development Back on Track - Sergey Sergyenko\"\n      speakers:\n        - Sergy Sergyenko\n      event_name: \"London Ruby + AI Meetup June 2025\"\n      date: \"2025-06-17\"\n      published_at: \"2025-07-17\"\n      video_provider: \"youtube\"\n      video_id: \"XyrvCVKlbPM\"\n      id: \"sergy-sergyenko-london-ruby-ai-meetup-june-2025\"\n      description: |-\n        Sergy Sergyenko presentation at the London Ruby + AI meetup, which took place on June 17th, 2025.\n\n        The topic was - TDD 2.0: AI Brings Test-Driven Development Back on Track.\n      language: \"english\"\n\n- title: \"Berlin Ruby + AI Meetup June 2025\"\n  raw_title: \"Berlin Ruby + AI meetup, June 24th, 2025\"\n  event_name: \"Berlin Ruby + AI Meetup June 2025\"\n  date: \"2025-06-24\"\n  published_at: \"2025-07-17\"\n  video_provider: \"children\"\n  video_id: \"berlin-ruby-ai-meetup-june-2025\"\n  id: \"berlin-ruby-ai-meetup-june-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GuNXUYjWQAAYbE7?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GuNXUYjWQAAYbE7?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GuNXUYjWQAAYbE7?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GuNXUYjWQAAYbE7?format=jpg&name=4096x4096\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GuNXUYjWQAAYbE7?format=jpg&name=4096x4096\"\n  description: |-\n    Ruby + AI meetup that took place in Berlin on June 24th, 2025, organized by Ruby Europe.\n\n    The meetup focused on creativity in the age of AI, featuring advanced Ruby on Rails AI integration techniques.\n  talks:\n    - title: \"Ruby Europe introduction for Ruby+AI Meetup in Berlin\"\n      raw_title: \"Ruby Europe introduction for Ruby+AI Meetup in Berlin - Mariusz Kozieł\"\n      speakers:\n        - Mariusz Kozieł\n      event_name: \"Berlin Ruby + AI Meetup June 2025\"\n      date: \"2025-06-24\"\n      published_at: \"2025-07-17\"\n      video_provider: \"youtube\"\n      video_id: \"gk6jkW19D18\"\n      id: \"mariusz-koziel-berlin-ruby-ai-meetup-june-2025\"\n      description: |-\n        Mariusz Kozieł presentation at the Berlin Ruby + AI meetup, which took place on June 24th, 2025.\n      language: \"english\"\n\n    - title: \"Joy of creativity in the age of AI\"\n      raw_title: \"Joy of creativity in the age of AI - Paweł Strzałkowski\"\n      speakers:\n        - Paweł Strzałkowski\n      event_name: \"Berlin Ruby + AI Meetup June 2025\"\n      date: \"2025-06-24\"\n      published_at: \"2025-07-17\"\n      video_provider: \"youtube\"\n      video_id: \"iz0sx7xPU60\"\n      id: \"pawel-strzalkowski-berlin-ruby-ai-meetup-june-2025\"\n      description: |-\n        Paweł Strzałkowski presentation at the Berlin Ruby + AI meetup, which took place on June 24th, 2025.\n\n        The topic was - The joy of creativity in the age of AI.\n\n        The presentation included the description of features and techniques such as:\n        - in-browser audio recording\n        - LLM-driven audio transcription in Ruby on Rails\n        - Tool usage in Ruby on Rails\n        - Broadcasting voice commands\n        - Image capture using Javascript\n        - Image recognition with GPT-4\n        - Embeddings\n        - Vector Search\n        All within a Ruby on Rails application\n      language: \"english\"\n\n    - title: \"AI, offline\"\n      raw_title: \"AI, offline - Chris Hasiński\"\n      speakers:\n        - Chris Hasiński\n      event_name: \"Berlin Ruby + AI Meetup June 2025\"\n      date: \"2025-06-24\"\n      published_at: \"2025-07-17\"\n      video_provider: \"youtube\"\n      video_id: \"R2DizRmuDGQ\"\n      id: \"chris-hasinski-berlin-ruby-ai-meetup-june-2025\"\n      description: |-\n        Chris Hasiński presentation at the Berlin Ruby + AI meetup, which took place on June 24th, 2025.\n\n        The topic was - AI, offline\n      language: \"english\"\n"
  },
  {
    "path": "data/rubyeurope/series.yml",
    "content": "---\nname: \"Ruby Europe\"\nwebsite: \"https://rubyeurope.com\"\ntwitter: \"RubyEurope\"\nyoutube_channel_name: \"Ruby Europe\"\nkind: \"meetup\"\nfrequency: \"irregular\"\nplaylist_matcher: \"Ruby\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCPkGcnK-vKiYVmefSp22enA\"\n"
  },
  {
    "path": "data/rubyevents/rubyevents/event.yml",
    "content": "---\nid: \"rubyevents\"\ntitle: \"RubyEvents\"\ndescription: |-\n  A collection of Ruby talks at Non-Ruby events\nkind: \"meetup\"\nwebsite: \"https://rubyevents.org\"\ntwitter: \"rubyevents_org\"\nlocation: \"Unknown\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyevents/rubyevents/videos.yml",
    "content": "# Ruby talks at Non-Ruby events\n---\n- id: \"nick-schwaderer-future-sync-2019\"\n  title: \"Preparing for a Natural Disaster Using Bots\"\n  raw_title: \"Preparing for a Natural Disaster Using Bots\"\n  event_name: \"Future Sync 2019\"\n  date: \"2019-06-15\"\n  description: |-\n    Nick discusses the use of Bots when prepping for a natural disaster.\n  video_provider: \"youtube\"\n  video_id: \"hSwtA-WmAcQ\"\n  published_at: \"2019-06-15\"\n  speakers:\n    - Nick Schwaderer\n\n- id: \"nick-schwaderer-software-cornwall-2019\"\n  title: \"Preparing for a Natural Disaster Using Bots\"\n  raw_title: \"Preparing for a Natural Disaster Using Bots\"\n  event_name: \"Software Cornwall 2019\"\n  date: \"2019-03-28\"\n  description: |-\n    Nick discusses the use of Bots when prepping for a natural disaster.\n  video_provider: \"youtube\"\n  video_id: \"WCRfOcYf6tI\"\n  published_at: \"2019-03-28\"\n  speakers:\n    - Nick Schwaderer\n\n- id: \"andrew-atkinson-posette-2024\"\n  title: \"SaaS on Rails on PostgreSQL\"\n  raw_title: \"SaaS on Rails on PostgreSQL\"\n  event_name: \"Posette 2024\"\n  location: \"online\"\n  date: \"2024-06-11\"\n  description: |-\n    Video of a conference talk about Saas on Rails on PostgreSQL presented by Andrew Atkinson at POSETTE: An Event for Postgres 2024. In this talk attendees will learn how Ruby on Rails and PostgreSQL can be used to create scalable SaaS applications, focusing on schema and query design, and leveraging database capabilities. We’ll define SaaS concepts, B2B, B2C, and multi-tenancy. Although Rails doesn't natively support SaaS or multi-tenancy, solutions like Bullet Train and Jumpstart Rails can be used for common SaaS needs. Next we'll cover database designs from the Apartment and actsastenant gems which support multi-tenancy concepts, and connect their designs to Citus's row and schema sharding capabilities from version 12.0. We’ll also cover PostgreSQL's LIST partitioning and how to use it for efficient detachment of unneeded customer data. We'll cover the basics of leveraging Rails 6.1's Horizontal Sharding for database-per-tenant designs. Besides the benefits for each tool, limitations will be described so that attendees can make informed choices. Attendees will leave with a broad survey of building multi-tenant SaaS applications, having reviewed application level designs, database designs, to help them put these into action in their own applications.\n\n    Andrew is a Staff Software Engineer who specializes in building high performance web applications using PostgreSQL and Ruby on Rails.\n\n    Andrew wrote a book \"High Performance PostgreSQL for Rails,\" published by Pragmatic Programmers in 2024. Andrew has spoken previously at RailsConf, Sin City Ruby, PGDay Chicago, PGConf NYC, and RubyConf Argentina.\n\n    Chapters:\n    00:00 - Intro\n    00:39 - Overview of the presentation\n    01:10 - Definition of terms\n    05:36 - Adding multi-tenancy to Rideshare application\n    12:55 - Scaling beyond a single PostgreSQL instance\n    14:27 - Multi-Tenancy and Sharding with Active Record\n    17:02 - Citus and Sharding\n    22:52 - Wrap Up and Advice\n  video_provider: \"youtube\"\n  video_id: \"RwXJ4s2pw1A\"\n  published_at: \"2024-06-13\"\n  speakers:\n    - Andrew Atkinson\n\n- id: \"vladimir-dementyev-wasmcon-2024\"\n  title: \"Lightning Talk: From Server to Client: Ruby on Rails on WebAssembly\"\n  raw_title: \"Lightning Talk: From Server to Client: Ruby on Rails on WebAssembly - Vladimir Dementyev\"\n  event_name: \"WasmCon 2024\"\n  location: \"Salt Lake City, UT\"\n  date: \"2024-09-10\"\n  description: |-\n    Ruby on Rails is a famous “batteries included” framework for the rapid development of web applications. Its full-stack promise comes in a server-oriented, or HTML-over-the-Wire flavor: a server oversees everything from database interactions to your application UI/UX. And whenever there is a server involved, the network and its unpredictability come into play. No matter how much you enjoy developing with Rails, it would be hard to achieve the same level of user experience as with client-side and especially local-first frameworks. And here comes Wasm. With the help of WebAssembly, we can do a radical shift—bring the Rails application right into your browser, and make it local-first! In my talk, I want to discuss the challenges of making a classic web framework Wasm compatible, the techniques we can use to run server-first applications in the browsers and what are the use cases.\n  video_provider: \"youtube\"\n  video_id: \"z_iWZrC3rtQ\"\n  published_at: \"2024-11-18\"\n  speakers:\n    - Vladimir Dementyev\n\n- id: \"irina-nazarova-viteconf-2024\"\n  title: \"Using Vite Ruby\"\n  raw_title: \"Irina Nazarova | Using Vite Ruby | ViteConf 2024\"\n  event_name: \"ViteConf 2024\"\n  location: \"online\"\n  date: \"2024-10-03\"\n  description: |-\n    Let's talk about the depth of the asset pipeline problem for the Ruby on Rails community and the role of Vite and Vite Ruby. I'm also sharing feedback and quotes from the teams using Vite Ruby: why they chose it and what's missing.\n\n    https://ViteConf.org hosted by https://StackBlitz.com\n  video_provider: \"youtube\"\n  video_id: \"vIxQ6u9pHaw\"\n  published_at: \"2024-11-05\"\n  slides_url: \"https://speakerdeck.com/irinanazarova/using-vite-ruby-vite-conf-2024\"\n  speakers:\n    - Irina Nazarova\n\n- id: \"okura-masafumi-burikaigi-2024\"\n  title: \"Writing documentation can be fun with plugin system\"\n  raw_title: \"Writing documentation can be fun with plugin system\"\n  event_name: \"BuriKaigi 2024\"\n  location: \"Toyama, Japan\"\n  date: \"2024-07-27\"\n  description: |-\n    https://burikaigi.dev/2024/speakers/004/\n    https://fortee.jp/burikaigi-2025/proposal/03ac7594-fce1-4dad-9dd0-c37649127f90\n  video_provider: \"not_recorded\"\n  video_id: \"okura-masafumi-burikaigi-2024\"\n  published_at: \"2024-07-27\"\n  slides_url: \"https://speakerdeck.com/okuramasafumi/writing-documentation-can-be-fun-with-plugin-system\"\n  speakers:\n    - OKURA Masafumi\n\n- id: \"charles-nutter-carolina-code-conference-2023\"\n  title: \"Bringing Ruby to the JVM: Making the Impossible Possible\"\n  raw_title: \"Charles Nutter - Bringing Ruby to the JVM: Making the Impossible Possible // Carolina Code Conf 2023\"\n  event_name: \"Carolina Code Conference 2023\"\n  location: \"Greenville, SC\"\n  date: \"2023-08-19\"\n  description: |-\n    Over the past 18 years, the JRuby team has worked to bring Ruby to the JVM, defying impossible challenges and building the most successful alternative Ruby implementation in the world. Today, JRuby is actively developed and deployed at thousands of Ruby and Java shops around the world... but how did we get here? This talk provides a retrospective of the JRuby project, with examples of modern JRuby usage along the way.\n\n    Presented on August 19, 2023 at the Carolina Code Conference in Greenville, SC\n\n    https://carolina.codes\n  video_provider: \"youtube\"\n  video_id: \"pzm6I4liJlg\"\n  published_at: \"2023-09-04\"\n  speakers:\n    - Charles Nutter\n\n- id: \"https://push.cx/talks/kcdc2016/Rails-Database-Corruption-Peter-Bhat-Harkins-KCDC-2016.mp4\"\n  title: \"Rails Database Corruption\"\n  raw_title: \"Rails Database Corruption\"\n  event_name: \"Kansas City Developer Conference 2016\"\n  date: \"2016-06-22\"\n  description: |-\n    Almost every Rails database contains records that won't pass their model validations, leading to \"can't happen\" bugs months or years later. This talk introduces a gem that detects unsafe practices and lurking corrupt data. Learn to recognize and prevent five six ways data becomes corrupt, and maybe replace ActiveRecord validations entirely.\n\n    https://push.cx/talks/kcdc2016\n  video_provider: \"mp4\"\n  video_id: \"https://push.cx/talks/kcdc2016/Rails-Database-Corruption-Peter-Bhat-Harkins-KCDC-2016.mp4\"\n  published_at: \"2016-06-22\"\n  slides_url: \"https://push.cx/talks/kcdc2016/Rails%20Database%20Corruption%20-%20Peter%20Bhat%20Harkins.pdf\"\n  speakers:\n    - Peter Bhat Harkins\n\n- id: \"henning-koch-full-stack-hour-by-makandra\"\n  title: \"Fixing Flaky E2E Tests\"\n  raw_title: \"Fixing Flaky E2E Tests\"\n  event_name: \"Full Stack Hour by makandra\"\n  location: \"online\"\n  date: \"2023-12-07\"\n  description: |-\n    Flaky tests can lead to unreliability in software development and negatively impact the quality of test results. In this video, we'll show you how to prevent flaky tests.\n  video_provider: \"youtube\"\n  video_id: \"LaCwiFDm2Vs\"\n  published_at: \"2023-12-07\"\n  speakers:\n    - Henning Koch\n\n- id: \"jim-weirich-cincycocoadev-meetup-april-2013\"\n  title: \"RubyMotion\"\n  raw_title: \"April CincyCocoaDev - RubyMotion with Jim Weirich\"\n  event_name: \"CincyCocoaDev Meetup - April 2013\"\n  location: \"Cincinnati, OH\"\n  date: \"2013-04-18\"\n  published_at: \"2013-04-19\"\n  description: |-\n    RubyMotion is a revolutionary toolchain for iOS. It lets you quickly develop and test native iOS applications for iPhone or iPad, all using the awesome Ruby language you know and love.\n\n    Bio: Jim Weirich first learned about computers when his college adviser suggested he take a computer science course: \"It will be useful, and you might enjoy it.\" With those prophetic words, Jim has been developing now for over 25 years, working with everything from crunching rocket launch data on supercomputers to wiring up servos and LEDs on micro-controllers. Currently he loves working in Ruby and Rails as the Chief Scientist at New Context, but you can also find him strumming on his ukulele as time permits.\n\n    Repo: https://github.com/captproton/jim-weirich-rubymotion-intro\n\n    https://www.meetup.com/cincycocoadev/events/112048512/\n  video_provider: \"youtube\"\n  video_id: \"z7E1zx9j31M\"\n  speakers:\n    - Jim Weirich\n  additional_resources:\n    - name: \"captproton/jim-weirich-rubymotion-intro\"\n      type: \"repo\"\n      url: \"https://github.com/captproton/jim-weirich-rubymotion-intro\"\n\n- id: \"ezra-zygmuntowicz-google-tech-talks\"\n  title: \"Merb, Rubinius and the Engine Yard Stack\"\n  raw_title: \"Merb, Rubinius and the Engine Yard Stack\"\n  event_name: \"Google Tech Talks\"\n  date: \"2008-10-20\"\n  published_at: \"2008-10-21\"\n  description: |-\n    In this talk we will explore a few of the open source projects we work on here at Engine Yard. I will give a detailed overview of the Merb web framework and what it brings to the table. We will also discuss Rubinius, an alternate ruby VM based on SmallTalk 80 blue book that also uses LLVM for low level optimizations. We will also explore the 'stack' we are working on at EY which includes our own variant of Gentoo linux as well as a full stack of software dedicated to running ruby applications as efficiently as possible.\n\n    Merb, like Ruby on Rails is an MVC framework. Unlike Rails, Merb is ORM-agnostic, JavaScript library agnostic, and template language agnostic, preferring plugins that add in support for a particular feature rather than trying to produce a monolithic library with everything in the core. While trying to keep the core as minimal and clean as possible, this hasnt meant a sacrifice of features. Merb has a very comprehensive set of features, which are continually improving.\n\n    Rubinius is a project to develop the next generation virtual machine for the Ruby programming language, drawing on the best virtual machine research and technology of the last 30 years. It implements the core libraries in Ruby, making a system easily accessible for development and extension. Rubinius is also an excellent platform for experimenting with cutting-edge technology like software transactional memory.\n  video_provider: \"youtube\"\n  video_id: \"TcMklv40YMY\"\n  speakers:\n    - Ezra Zygmuntowicz\n\n- id: \"irina-nazarova-open-core-summit-2023\"\n  title: \"Wildest Dreams of Making Profit on Open Source\"\n  raw_title: \"Irina Nazarova at the Open Core Summit 2023: Wildest Dreams of Making Profit on Open Source\"\n  event_name: \"Open Core Summit 2023\"\n  location: \"San Francisco, CA\"\n  date: \"2023-12-07\"\n  published_at: \"2024-01-03\"\n  description: |-\n    Irina Nazarova, CEO at Evil Martians, gave a talk at the Open Core Summit in San Francisco on December 7, 2023. The topic is how to recognize and overcome the fundamental problem in the business of open source: the conflict between the open and the commercial mindsets.\n  video_provider: \"youtube\"\n  video_id: \"tfQghAdUUtY\"\n  speakers:\n    - Irina Nazarova\n"
  },
  {
    "path": "data/rubyevents/series.yml",
    "content": "---\nname: \"RubyEvents.org\"\nwebsite: \"https://rubyevents.org/\"\ntwitter: \"rubyevents_org\"\nyoutube_channel_name: \"\"\nfrequency: \"yearly\"\nkind: \"organisation\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2014/event.yml",
    "content": "---\nid: \"rubyfuza-2014\"\ntitle: \"Rubyfuza 2014\"\ndescription: \"\"\nlocation: \"Cape Town, South Africa\"\nkind: \"conference\"\nstart_date: \"2014-02-06\"\nend_date: \"2014-02-08\"\nwebsite: \"http://www.rubyfuza.org/2014/\"\ntwitter: \"rubyfuza\"\nplaylist: \"http://www.confreaks.com/events/rubyfuza2014\"\ncoordinates:\n  latitude: -33.922087\n  longitude: 18.4231418\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubyfuza.org/2014/\n# Videos: http://www.confreaks.com/events/rubyfuza2014\n---\n[]\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2015/event.yml",
    "content": "---\nid: \"rubyfuza-2015\"\ntitle: \"Rubyfuza 2015\"\ndescription: \"\"\nlocation: \"Cape Town, South Africa\"\nkind: \"conference\"\nstart_date: \"2015-02-05\"\nend_date: \"2015-02-06\"\nwebsite: \"http://www.rubyfuza.org/2015/\"\ntwitter: \"rubyfuza\"\nplaylist: \"https://www.youtube.com/playlist?list=PLI113oIao_x63Ne1S8ObKYQwbPRcpb8kN\"\ncoordinates:\n  latitude: -33.922087\n  longitude: 18.4231418\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubyfuza.org/2015/\n# Videos: https://www.youtube.com/playlist?list=PLI113oIao_x63Ne1S8ObKYQwbPRcpb8kN\n---\n[]\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2016/event.yml",
    "content": "---\nid: \"rubyfuza-2016\"\ntitle: \"Rubyfuza 2016\"\ndescription: \"\"\nlocation: \"Cape Town, South Africa\"\nkind: \"conference\"\nstart_date: \"2016-02-04\"\nend_date: \"2016-02-05\"\nwebsite: \"http://www.rubyfuza.org/2016/\"\ntwitter: \"rubyfuza\"\ncoordinates:\n  latitude: -33.922087\n  longitude: 18.4231418\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubyfuza.org/2016/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2017/event.yml",
    "content": "---\nid: \"rubyfuza-2017\"\ntitle: \"Rubyfuza 2017\"\ndescription: \"\"\nlocation: \"Cape Town, South Africa\"\nkind: \"conference\"\nstart_date: \"2017-02-02\"\nend_date: \"2017-02-04\"\nwebsite: \"http://www.rubyfuza.org/2017/\"\ntwitter: \"rubyfuza\"\nplaylist: \"https://www.youtube.com/playlist?list=PLI113oIao_x5PHCdz0VLSKW4-Qp58pWOs\"\ncoordinates:\n  latitude: -33.922087\n  longitude: 18.4231418\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubyfuza.org/2017/\n# Videos: https://www.youtube.com/playlist?list=PLI113oIao_x5PHCdz0VLSKW4-Qp58pWOs\n---\n[]\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2018/event.yml",
    "content": "---\nid: \"rubyfuza-2018\"\ntitle: \"Rubyfuza 2018\"\ndescription: \"\"\nlocation: \"Cape Town, South Africa\"\nkind: \"conference\"\nstart_date: \"2018-02-01\"\nend_date: \"2018-02-03\"\nwebsite: \"http://www.rubyfuza.org\"\ntwitter: \"rubyfuza\"\nplaylist: \"https://www.youtube.com/playlist?list=PLI113oIao_x4i51ynrHhhNz3UpEDs0qxy\"\ncoordinates:\n  latitude: -33.922087\n  longitude: 18.4231418\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubyfuza.org\n# Videos: https://www.youtube.com/playlist?list=PLI113oIao_x4i51ynrHhhNz3UpEDs0qxy\n---\n[]\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2019/event.yml",
    "content": "---\nid: \"rubyfuza-2019\"\ntitle: \"Rubyfuza 2019\"\ndescription: \"\"\nlocation: \"Cape Town, South Africa\"\nkind: \"conference\"\nstart_date: \"2019-02-07\"\nend_date: \"2019-02-09\"\nwebsite: \"http://www.rubyfuza.org\"\ntwitter: \"rubyfuza\"\nplaylist: \"https://www.youtube.com/playlist?list=PLI113oIao_x55gOvfDER9ocuEQD94kjjx\"\ncoordinates:\n  latitude: -33.922087\n  longitude: 18.4231418\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubyfuza.org\n# Videos: https://www.youtube.com/playlist?list=PLI113oIao_x55gOvfDER9ocuEQD94kjjx\n---\n[]\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2020/event.yml",
    "content": "---\nid: \"rubyfuza-2020\"\ntitle: \"Rubyfuza 2020\"\ndescription: \"\"\nlocation: \"Cape Town, South Africa\"\nkind: \"conference\"\nstart_date: \"2020-02-06\"\nend_date: \"2020-02-08\"\nwebsite: \"https://www.rubyfuza.org\"\ntwitter: \"rubyfuza\"\ncoordinates:\n  latitude: -33.922087\n  longitude: 18.4231418\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://www.rubyfuza.org\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2024/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/rubyfuza-2024\"\n  open_date: \"2023-12-05\"\n  close_date: \"2024-08-10\"\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2024/event.yml",
    "content": "---\nid: \"rubyfuza-2024\"\ntitle: \"Rubyfuza 2024 (Cancelled)\"\ndescription: \"\"\nlocation: \"Cape Town, South Africa\"\nkind: \"conference\"\nstart_date: \"2024-10-17\"\nend_date: \"2024-10-18\"\nwebsite: \"https://www.rubyfuza.org\"\nstatus: \"cancelled\"\ntwitter: \"rubyfuza\"\ncoordinates:\n  latitude: -33.922087\n  longitude: 18.4231418\n"
  },
  {
    "path": "data/rubyfuza/rubyfuza-2024/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://www.rubyfuza.org\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyfuza/series.yml",
    "content": "---\nname: \"Rubyfuza\"\nwebsite: \"http://www.rubyfuza.org/2014/\"\ntwitter: \"rubyfuza\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyhack/rubyhack-2017/event.yml",
    "content": "---\nid: \"rubyhack-2017\"\ntitle: \"RubyHACK 2017\"\ndescription: \"\"\nlocation: \"Salt Lake City, UT, United States\"\nkind: \"conference\"\nstart_date: \"2017-04-20\"\nend_date: \"2017-04-21\"\nwebsite: \"https://rubyhack.com/archives/2017\"\nplaylist: \"https://confreaks.tv/events/rubyhack2017\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/rubyhack/rubyhack-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyhack.com/archives/2017\n# Videos: https://confreaks.tv/events/rubyhack2017\n---\n[]\n"
  },
  {
    "path": "data/rubyhack/rubyhack-2018/event.yml",
    "content": "---\nid: \"rubyhack-2018\"\ntitle: \"RubyHACK 2018\"\ndescription: \"\"\nlocation: \"Salt Lake City, UT, United States\"\nkind: \"conference\"\nstart_date: \"2018-05-03\"\nend_date: \"2018-05-04\"\nwebsite: \"https://rubyhack.com/archives/2018\"\nplaylist: \"https://confreaks.tv/events/rubyhack2018\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/rubyhack/rubyhack-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyhack.com/archives/2018\n# Videos: https://confreaks.tv/events/rubyhack2018\n---\n[]\n"
  },
  {
    "path": "data/rubyhack/rubyhack-2019/event.yml",
    "content": "---\nid: \"rubyhack-2019\"\ntitle: \"RubyHACK 2019\"\ndescription: \"\"\nlocation: \"Salt Lake City, UT, United States\"\nkind: \"conference\"\nstart_date: \"2019-04-03\"\nend_date: \"2019-04-04\"\nwebsite: \"https://rubyhack.com\"\nplaylist: \"https://www.youtube.com/playlist?list=PLE7tQUdRKcyYoLJFe8Y6TMgZgUkqlSQzN\"\ncoordinates:\n  latitude: 40.7605601\n  longitude: -111.8881397\n"
  },
  {
    "path": "data/rubyhack/rubyhack-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyhack.com\n# Videos: https://www.youtube.com/playlist?list=PLE7tQUdRKcyYoLJFe8Y6TMgZgUkqlSQzN\n---\n[]\n"
  },
  {
    "path": "data/rubyhack/series.yml",
    "content": "---\nname: \"RubyHACK\"\nwebsite: \"https://rubyhack.com\"\ntwitter: \"utrubyhack\"\nyoutube_channel_name: \"\"\nkind: \"retreat\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyhiroba/rubyhiroba-2013/event.yml",
    "content": "---\nid: \"rubyhiroba-2013\"\ntitle: \"RubyHiroba 2013\"\nkind: \"conference\"\nlocation: \"Minato City, Tokyo, Japan\"\ndescription: |-\n  Microsoft Japan Co., Ltd headquarters building 31st floor\nstart_date: \"2013-06-02\"\nend_date: \"2013-06-02\"\nyear: 2013\nwebsite: \"http://rubyhiroba.org/2013/\"\nbanner_background: \"#E3E0C9\"\nfeatured_background: \"#E3E0C9\"\nfeatured_color: \"#1D2E51\"\ncoordinates:\n  latitude: 35.65808130000001\n  longitude: 139.7515077\n"
  },
  {
    "path": "data/rubyhiroba/rubyhiroba-2013/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rubyhiroba/rubyhiroba-2014/event.yml",
    "content": "---\nid: \"rubyhiroba-2014\"\ntitle: \"RubyHiroba 2014\"\nkind: \"conference\"\nlocation: \"Shibuya, Tokyo, Japan\"\ndescription: \"\"\nstart_date: \"2014-09-21\"\nend_date: \"2014-09-21\"\nyear: 2014\nwebsite: \"http://rubyhiroba.org/2014/\"\nbanner_background: \"#A7C3B4\"\nfeatured_background: \"#A7C3B4\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 35.6619707\n  longitude: 139.703795\n"
  },
  {
    "path": "data/rubyhiroba/rubyhiroba-2014/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rubyhiroba/series.yml",
    "content": "---\nname: \"RubyHiroba\"\nwebsite: \"http://rubyhiroba.org\"\nyoutube_channel_name: \"\"\nfrequency: \"yearly\"\nkind: \"event\"\nlanguage: \"japanese\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2006/event.yml",
    "content": "---\nid: \"rubykaigi-2006\"\ntitle: \"RubyKaigi 2006\"\nkind: \"conference\"\nlocation: \"Odaiba, Tokyo, Japan\"\ndescription: \"\"\nstart_date: \"2006-09-22\"\nend_date: \"2006-09-23\"\nyear: 2006\nwebsite: \"https://rubykaigi.org/2006/\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 35.62058340000001\n  longitude: 139.7805445\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2006/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2007/event.yml",
    "content": "---\nid: \"rubykaigi-2007\"\ntitle: \"RubyKaigi 2007\"\nkind: \"conference\"\nlocation: \"Chiyoda, Tokyo, Japan\"\ndescription: \"\"\nstart_date: \"2007-06-09\"\nend_date: \"2007-06-10\"\nyear: 2007\nwebsite: \"https://rubykaigi.org/2007/\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 35.6764225\n  longitude: 139.650027\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2007/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2008/event.yml",
    "content": "---\nid: \"rubykaigi-2008\"\ntitle: \"RubyKaigi 2008\"\nkind: \"conference\"\nlocation: \"Tsukuba City, Ibaraki, Japan\"\ndescription: \"\"\nstart_date: \"2008-06-20\"\nend_date: \"2008-06-22\"\nyear: 2008\nwebsite: \"https://rubykaigi.org/2008/\"\nbanner_background: \"#FF2000\"\nfeatured_background: \"#FF2000\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 36.0835255\n  longitude: 140.0764454\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2008/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2009/event.yml",
    "content": "---\nid: \"rubykaigi-2009\"\ntitle: \"RubyKaigi 2009\"\nkind: \"conference\"\nlocation: \"Chiyoda, Tokyo, Japan\"\ndescription: \"\"\nstart_date: \"2009-07-17\"\nend_date: \"2009-07-19\"\nyear: 2009\nwebsite: \"https://rubykaigi.org/2009/\"\nbanner_background: \"#191919\"\nfeatured_background: \"#E9E9E9\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 35.6764225\n  longitude: 139.650027\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2010/event.yml",
    "content": "---\nid: \"rubykaigi-2010\"\ntitle: \"RubyKaigi 2010\"\nkind: \"conference\"\nlocation: \"Tsukuba, Ibaraki, Japan\"\ndescription: \"\"\nstart_date: \"2010-08-27\"\nend_date: \"2010-08-29\"\nyear: 2010\nwebsite: \"https://rubykaigi.org/2010/\"\nbanner_background: \"#010101\"\nfeatured_background: \"#010101\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 36.0835255\n  longitude: 140.0764454\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2011/event.yml",
    "content": "---\nid: \"rubykaigi-2011\"\ntitle: \"RubyKaigi 2011\"\nkind: \"conference\"\nlocation: \"Nerima, Tokyo, Japan\"\ndescription: \"\"\nstart_date: \"2011-06-16\"\nend_date: \"2011-06-18\"\nyear: 2011\nwebsite: \"https://rubykaigi.org/2011/\"\nbanner_background: \"#E6E5E0\"\nfeatured_background: \"#E6E5E0\"\nfeatured_color: \"#050000\"\ncoordinates:\n  latitude: 35.6764225\n  longitude: 139.650027\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2013/event.yml",
    "content": "---\nid: \"rubykaigi-2013\"\ntitle: \"RubyKaigi 2013\"\nkind: \"conference\"\nlocation: \"Koto-ku, Tokyo, Japan\"\ndescription: \"\"\npublished_at: \"2013-07-15\"\nstart_date: \"2013-05-30\"\nend_date: \"2013-06-01\"\nchannel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\nyear: 2013\nbanner_background: \"#E9F7BE\"\nfeatured_background: \"#E9F7BE\"\nfeatured_color: \"#BD6AB4\"\nwebsite: \"https://rubykaigi.org/2013/\"\ncoordinates:\n  latitude: 35.6727748\n  longitude: 139.8174521\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2013/videos.yml",
    "content": "## Day 1\n---\n- id: \"shintaro-kakutani-rubykaigi-2013\"\n  title: \"Opening\"\n  raw_title: \"[JA] Opening / Shintaro Kakutani\"\n  speakers:\n    - Shintaro Kakutani\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-06-17\"\n  video_provider: \"not_recorded\"\n  video_id: \"shintaro-kakutani-rubykaigi-2013\"\n  language: \"japanese\"\n  description: \"\"\n\n- id: \"masayoshi-takahashi-rubykaigi-2013\"\n  title: \"The History of Ruby; 20th Anniversary Ed.\"\n  raw_title: \"[JA] The History of Ruby; 20th Anniversary Ed. / Masayoshi Takahashi\"\n  speakers:\n    - Masayoshi Takahashi\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"67731254\"\n  language: \"japanese\"\n  slides_url: \"https://www.slideshare.net/takahashim/the-history-of-ruby-20th-anniversary-ed\"\n  description: |-\n    The first session in RubyKaigi 2006, the first RubyKaigi, is \"The History of Ruby.\" As re-booting of RubyKaigi, we'd like to take a look back over the history of Ruby and us again.\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2013\"\n  title: \"Keynote: How to create Ruby\"\n  raw_title: \"[JA][Keynote] How to create Ruby / Yukihiro 'Matz' Matsumoto\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"67807958\"\n  language: \"japanese\"\n  description: |-\n    Keynote given by Matz.\n\n- id: \"christopher-rigor-rubykaigi-2013\"\n  title: \"Identical Production, Staging and Development Environments Using Chef, AWS and Vagrant\"\n  raw_title: \"[EN] Identical Production, Staging and Development Environments Using Chef, AWS and Vagrant / Christopher Rigor\"\n  speakers:\n    - Christopher Rigor\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"67731302\"\n  language: \"english\"\n  description: |-\n    Learn how Engine Yard uses Amazon Web Services and Chef to bring up any number of servers ranging from a solo instance to a cluster of instances with multiple app instances, database instances and utility instances for memcached, resque, sphinx, and everything your app needs.\n\n    Snapshots are used to create a clone of your production environment where you can test all the changes before making them in production.\n\n    Vagrant and VirtualBox are used to provide a development environment with the same OS you use in production. Chef is used to install the same packages. In fact you use the same chef recipes everywhere.\n\n- id: \"laurent-sansonetti-rubykaigi-2013\"\n  title: \"Inside RubyMotion\"\n  raw_title: \"[EN][JA] Inside RubyMotion / Laurent Sansonetti, Shizuo Fujita\"\n  speakers:\n    - Laurent Sansonetti\n    - Shizuo Fujita\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"67731482\"\n  language: \"japanese\"\n  description: |-\n    This talk will describe the internals of RubyMotion, a Ruby toolchain for iOS development. RubyMotion is different from CRuby in many ways and this session will focus on the technical differences and explain what makes RubyMotion unique.\n\n- id: \"keiju-ishitsuka-rubykaigi-2013\"\n  title: \"Ruby Archaeology\"\n  raw_title: \"[JA] Ruby Archaeology / Keiju Ishitsuka\"\n  speakers:\n    - Keiju Ishitsuka\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-06-14\"\n  video_provider: \"vimeo\"\n  video_id: \"69688041\"\n  language: \"japanese\"\n  description: |-\n    I will unearth the early history of Ruby, from the night before it was born to day it was released to the world.\n\n- id: \"okkez-rubykaigi-2013\"\n  title: \"Ruby2.0 Reference Manual for japanese\"\n  raw_title: \"[JA] Ruby2.0 Reference Manual for japanese / okkez\"\n  speakers:\n    - okkez\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-07-04\"\n  video_provider: \"vimeo\"\n  video_id: \"69688043\"\n  language: \"japanese\"\n  description: |-\n    The work updating the Ruby Reference Manual (RuReMa) for Ruby 2.0 is done, so I'll report on that in my talk. In addition, there are a lot of people outside the project using the manual to do a variety of things, and I'd like to take this opportunity to thank them. I'll also talk about where we'd like to go in the future with the project.\n\n- id: \"thomas-e-enebo-rubykaigi-2013\"\n  title: \"The Future of JRuby?\"\n  raw_title: \"[EN] The Future of JRuby? / Thomas E. Enebo, Charles O. Nutter\"\n  speakers:\n    - Thomas E. Enebo\n    - Charles O. Nutter\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-07-13\"\n  video_provider: \"vimeo\"\n  video_id: \"68301517\"\n  language: \"english\"\n  description: |-\n    JRuby is a fast, compliant Ruby implementation which can make use of many features of the Java platform. What more is there to do? Can it be made faster? Will it ever load faster? Any plans on making cross-implementation native C extension API?\n\n    This presentation will answer questions like this and give some examples of exciting future projects involving JRuby. If you want a good insight into where JRuby is going then this talk is for you.\n\n- id: \"shibata-hiroshi-rubykaigi-2013\"\n  title: \"Ruby 'root'\"\n  raw_title: \"[JA] Ruby 'root' / SHIBATA Hiroshi\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-06-06\"\n  video_provider: \"vimeo\"\n  video_id: \"67807964\"\n  language: \"japanese\"\n  description: |-\n    Ruby 'root' has all of permission in ruby development resources such as ruby-lang.org. I'll describe and introduce my work between Feb and Jun. and I'll announce some big news in RubyKaigi.\n\n- id: \"kazuyoshi-fukuda-rubykaigi-2013\"\n  title: \"Two Legal Bodies about Ruby and its Projects\"\n  raw_title: \"[JA] Two Legal Bodies about Ruby and its Projects / Ruby Association & Ruby-no-Kai\"\n  speakers:\n    - Kazuyoshi Fukuda\n    - Kenji Sugihara\n    - Masayoshi Takahashi\n    - Shintaro Kakutani\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-07-12\"\n  video_provider: \"vimeo\"\n  video_id: \"70184263\"\n  language: \"japanese\"\n  description: |-\n    - Part 1: Ruby Association\n    Speaker: Kazuyoshi Fukuda, Kenji Sugihara\n\n    - Part 2: Ruby-no-Kai\n    Speaker: Masayoshi Takahashi, Shintaro Kakutani\n\n    There are two legal bodies who support Rubyists in Japan; Ruby Association and Ruby-no-Kai. What are their activities? What is the difference between them? It's time to unveil them.\n\n    https://rubykaigi.org/2013/talk/S52\n\n- id: \"the-why-documentary-rubykaigi-2013\"\n  title: \"TWO CARTOON FOXES: the _why documentary\"\n  raw_title: \"[EN][JA] TWO CARTOON FOXES: the _why documentary (japanese Subtitled) / Kevin Triplett, Shintaro Kakutani\"\n  speakers:\n    - Kevin Triplett\n    - Shintaro Kakutani\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  video_provider: \"not_published\"\n  video_id: \"the-why-documentary-rubykaigi-2013\"\n  language: \"english\"\n  description: |-\n    In this short documentary film, we explore Ruby's beloved and mysterious character Why the Lucky Stiff (_why). Matz created Ruby and _why created his (poignant) Guide to Ruby, with musical soundtrack, to spread the Ruby love to people outside the Land of the Rising Sun. This documentary celebrates _why's art and features interviews with TenderLove, MeNTaLguY, Steve Klabnik, Flip, Geoffrey Grosenbach, and Matz. And rabbits and cartoon foxes.\n\n    For Japanese: This film will play with Japanese subtitle <3\n\n    https://rubykaigi.org/2013/talk/S51/\n\n- id: \"koichi-sasada-rubykaigi-2013\"\n  title: \"Toward efficient Ruby 2.1\"\n  raw_title: \"[JA] Toward efficient Ruby 2.1 / Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-06-06\"\n  video_provider: \"vimeo\"\n  video_id: \"67807718\"\n  language: \"japanese\"\n  description: |-\n    In this presentation, I will show the ways to achieve more efficient Ruby 2.1 interpreter, the next release of CRuby/MRI. My talk will include VM/compilier optimizations, memory/object management and runtime libraries modification. Most of techniques and implementations may be work in progress.\n\n    https://rubykaigi.org/2013/talk/S73\n\n- id: \"ron-evans-rubykaigi-2013\"\n  title: \"Ruby On Robots Using Artoo: A New Platform For Robotics, Physical Computing, and the Real World Web\"\n  raw_title: \"[EN] Ruby On Robots Using Artoo: A New Platform For Robotics, Physical Computing, and the Real World Web / Ron Evans, Adrian Zankich\"\n  speakers:\n    - Ron Evans\n    - Adrian Zankich\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-07-04\"\n  video_provider: \"vimeo\"\n  video_id: \"69688042\"\n  language: \"english\"\n  description: |-\n    The robotics revolution has already begun. You can buy drones and robotic devices at local retail stores. Unfortunately, it’s hard to develop code for robots, and nearly impossible to create solutions that integrate multiple different kind of devices.\n\n    Introducing Artoo, a new robotics framework written in Ruby. Artoo can communicate with many different kinds of hardware devices, and integrate them together. With surprisingly few lines of code, you can write interesting applications that tie together Arduinos, ARDrones, Spheros, and more.\n\n    Artoo is based on Celluloid, giving it the ability to support the levels of concurrency that are required for industrial-strength robotic applications. Artoo has a built in API-server. This allows your robots to be controlled by external applications, or integrated into larger, more complex solutions.\n\n    The time has come for Ruby-based robotics, and Artoo can help lead the way!\n\n- id: \"danish-khan-rubykaigi-2013\"\n  title: \"We Are Family\"\n  raw_title: \"[EN] We Are Family / Danish Khan\"\n  speakers:\n    - Danish Khan\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-07-04\"\n  video_provider: \"vimeo\"\n  video_id: \"69688044\"\n  language: \"english\"\n  description: |-\n    The traditional way of running a company has been documented by people from Harvard Business School and many other reputable institutions. If you do it differently you are considered to be in uncharted territory. I've started to notice that the new approaches companies like GitHub are taking to running a business are influenced a lot from the way families and family businesses are run.\n\n    Becoming close with your coworkers and treating them like family helps foster innovation and creates an amazing culture where a variety of people can feel comfortable and enjoy themselves. Family members are honest with each other. Sometimes when someone critics you it can hurt, but when you know that it is backed with great respect and love you use it to help you become better.\n\n    Having a great idea, creating useful products, and writing stellar code can be done by smart people. The difficult part is figuring out how to get tons of smart people to work well together. The social aspect is hard, but when you build a culture based off of values that are important to a family you'll see the amazing things that can be done.\n\n- id: \"terence-lee-rubykaigi-2013\"\n  title: \"`bundle install` Y U SO SLOW: Server Edition\"\n  raw_title: \"[EN] `bundle install` Y U SO SLOW: Server Edition / Terence Lee\"\n  speakers:\n    - Terence Lee\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-06-06\"\n  video_provider: \"vimeo\"\n  video_id: \"67807956\"\n  language: \"english\"\n  description: |-\n    If you've ever done anything in ruby, you've probably used rubygems.org to search or install your favorite gem. On October 17, 2012, rubygems.org went down. A Dependency API was built to be used by Bundler 1.1+ to speed up bundle install. Unfortunately, it was a bit too popular and the service caused too much load on the current infrastructure. In order to get rubygems.org back up the API had to be disabled.\n\n    This talk will cover how we built a compatible API running on Heroku working with the rubygems.org team. We'll cover both how the API works and how Bundler uses it. Since this is a separate service, we had to start work towards a federated rubygems.org by building out a syncing service initially using just the rubygems indexes to keep our local cache up to date. We'll go over the sync code and how we've minimized the time between when you push a gem and it's available via the API.\n\n    In order to keep the service up, we've taken productization steps like setting up on call rotations and instrumentation. We'll go over the tools and how we run the a volunteer OSS project.\n\n    We've prototyped a replay service, to replay production traffic to different Heroku apps. With this and our instrumentation we were able to compare performance impact of different changes. We've used this data to guide our decision to change web servers from thin to unicorn. We're also keeping tabs on various setups including MRI 2 and JRuby under real production code and load. We'll go over how we've set this up and how it works on Heroku.\n\n- id: \"shugo-maeda-rubykaigi-2013\"\n  title: \"Refining refinements\"\n  raw_title: \"[JA] Refining refinements / Shugo Maeda\"\n  speakers:\n    - Shugo Maeda\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-06-14\"\n  video_provider: \"vimeo\"\n  video_id: \"71052100\"\n  language: \"japanese\"\n  description: |-\n    Refinements have been introduced in Ruby 2.0. However, they are experimental, and some of the features have been removed from Ruby 2.0.0. This talk explains the current features of Refinements, their limits, and how to refine Refinements themselves in Ruby 2.1.\n\n- id: \"prem-sichanugrist-rubykaigi-2013\"\n  title: \"You have to test multiple versions of your gem's dependencies. You used Appraisal. It's super affective!\"\n  raw_title: \"[EN] You have to test multiple versions of your gem's dependencies. You used Appraisal. It's super affective! / Prem Sichanugrist\"\n  speakers:\n    - Prem Sichanugrist\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-07-05\"\n  video_provider: \"vimeo\"\n  video_id: \"69748748\"\n  language: \"english\"\n  description: |-\n    So, it seems like you've finished writing your awesome gem. However, are you sure that your gem is working perfectly against multiple versions of its dependency? Are you sure that you didn't break any backward compatibility? In this talk, I'm going to show you the approach we have been taken to test our gems against multiple versions of dependencies, such as testing against Rails 3.2 and Rails 3.1. I'm also going to introduce you to our gem called \"Appraisal\" which helps you generating\n\n    Gemfiles to be used with Bundler, and also guide it to running your test suite against those multiple Gemfiles. Lastly, I'm going to show you how you can config Travis CI to test your gem against those multiple versions of dependencies.\n\n- id: \"sebastian-burkhard-rubykaigi-2013\"\n  title: \"RubyJS\"\n  raw_title: \"[EN] RubyJS / Sebastian Burkhard\"\n  speakers:\n    - Sebastian Burkhard\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-07-05\"\n  video_provider: \"vimeo\"\n  video_id: \"69748750\"\n  language: \"english\"\n  description: |-\n    RubyJS is a JavaScript implementation of all methods from Ruby classes like Array, String, Numbers, Time and more.\n\n    This talk will tell you how you can use RubyJS to stay sane when writing JavaScript. I'll show best practices, tips & tricks for daily use and how you can extend RubyJS with more methods and classes.\n\n    https://rubykaigi.org/2013/talk/S27\n\n- id: \"takeshi-yabe-rubykaigi-2013\"\n  title: \"Ruby Kaja 2013 / Community Appeal\"\n  raw_title: \"[JA] Ruby Kaja 2013 / Community Appeal / Takeshi Yabe, Toshiaki Koshiba\"\n  speakers:\n    - Takeshi Yabe\n    - Toshiaki Koshiba\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-30\"\n  published_at: \"2013-07-25\"\n  video_provider: \"vimeo\"\n  video_id: \"71052214\"\n  language: \"japanese\"\n  description: |-\n    Kaja(冠者) is Japanese traditional word. Kaja means hopeful youngster. We use the word as newcomer hopeful rubyist.\n\n    RubyKaja is Award of Rubyist for \"shy\" Japanese Rubyist. For the purpose of making a chance to praise each other, We have regional Rubyist communities elect active but \"not famous\" Rubyist, and We all honor them. In this talk, We announce and honor the Rubyists as RubyKaja 2013 and, introduce Rubyist communities which nominated for election RubyKaja.\n\n    The Communities will appeals are:\n\n    - Asakusa.rb\n    - Hiroshima.rb\n    - Kanazawa.rb\n    - Okinawa.rb\n    - Rails Girls Tokyo\n    - Rails勉強会@東京\n    - Ruby札幌\n    - Shibuya.rb\n    - Shinjuku.rb\n    - Yokohama.rb\n    - guRuby\n    - toRuby\n    - るびま編集コミュニティ\n    - 西脇.rb & 東灘.rb\n\n## Day 2\n\n- id: \"issei-naruta-rubykaigi-2013\"\n  title: \"High Performance Rails\"\n  raw_title: \"[JA] High Performance Rails / Issei Naruta\"\n  speakers:\n    - Issei Naruta\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-14\"\n  video_provider: \"vimeo\"\n  video_id: \"68301518\"\n  language: \"japanese\"\n  description: |-\n    Why do websites tend to slow down day by day? Why do people say \"Ruby on Rails is slow\"? This presentation is the story that we Cookpad are fighting against the problems.\n\n    We rewrote whole codes of Cookpad.com by Ruby on Rails in 2008. Since then we've been had an aim that we keep the average response time be under 200 ms.\n\n    In this presentation, I'll introduce ways to make websites fast using Rails based on our experiences. And I'll talk about how engineers who are responsible for site's performance should work in their company.\n\n- id: \"kensuke-nagae-rubykaigi-2013\"\n  title: \"Continuous gem dependency updating with Jenkins and Pull Request\"\n  raw_title: \"[JA] Continuous gem dependency updating with Jenkins and Pull Request / Kensuke Nagae\"\n  speakers:\n    - Kensuke Nagae\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-14\"\n  video_provider: \"vimeo\"\n  video_id: \"68300423\"\n  language: \"japanese\"\n  description: |-\n    In this talk, I will talk about the technique of saving labor of gem dependency updating by Jenkins CI and GitHub's pull request.\n\n    Bundler will be used to manage the library in the web application development with Ruby these days. Bundler is a useful tool to intelligently manage the version and dependencies of the library. However, developers are so busy that they often forget or postpone the updating work. Moreover, sometimes developers might be not permitted to spend their time for these work by their boss.\n\n    Presenter also fall into this situation, and experienced some troubles in the updating work for the first time in a long time.\n\n    Analysis of the cause of the update work disruptions,\n\n    Good habit which rely on the motivation of developers is easy to be damaged\n\n    Work that has not been incorporated into the daily workflow would be forgotten\n\n    Since the notification from email or IRC has not enough pressure, it is difficult to feel a sense of duty\n\n    I've found that there is a problem.\n\n    Therefore, to solve the problem I made a mechanism to make the updating work smoothly by Jenkins CI and GitHub's pull request. In this talk, I will talk about how I solved this problem, and compare this method to the similar ways.\n\n- id: \"martin-bosslet-rubykaigi-2013\"\n  title: \"krypt. semper pi.\"\n  raw_title: \"[EN] krypt. semper pi. / Martin Bosslet\"\n  speakers:\n    - Martin Bosslet\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-14\"\n  video_provider: \"vimeo\"\n  video_id: \"68300345\"\n  language: \"english\"\n  description: |-\n    Many people don't like Cryptography. Whenever he falls out of a bar, he carries this strong odor of ivory-towering, bikeshedding and plain, outright arrogance. He seems to be a loner and a smartass, rude, and it's hard to follow his boring, lengthy explanations. But once you get to know him better, it actually turns out that he's really a nice guy. Sure, a little bit paranoid, but his intentions are pure and just. He'll probably never be your buddy on Facebook ('cause he likely won't set up an account in the first place), but over time you will realize that it can be quite pleasant having him around.\n\n    krypt is the tool that tames him, and krypt is the tool that translates his sentences into plain, understandable Ruby. Gone are the times when you just couldn't figure out what parameters to use in order to please him, gone are the times when he would take your passwords and not stow them away safely because yet again he didn't fully understand what you were asking him to do.\n\n    OK, this metaphor thing is getting a little old now. krypt makes using crypto fun and easy, and it works on all Rubies on all platforms (yep, Windows, too) - out of the box, no restrictions. It is about diversity - it allows you to choose from different providers that are best-suited for the particular task at hand. You'll get a whirlwind tour of how krypt is different than other crypto libraries and why. You'll find out about the finer pieces of its inner workings and you might take home a few tricks that evolved while developing the native extensions that sit at the very heart of krypt.\n\n    With its recent integration into JRuby, you might already be using krypt with JRuby right now without even knowing. Learn about the details and how krypt is used to simulate OpenSSL features that were not available in JRuby before. Find out more about how it can help making Ruby a safer place. How it can help solving nasty problems such as signing our beloved gems for example.\n\n    krypt tries to ultimately replace the OpenSSL extension in the Ruby standard library, and with our combined effort we could actually steer the story of Ruby cryptography towards a happy ending.\n\n    Find out how!\n\n- id: \"eddie-kao-rubykaigi-2013\"\n  title: \"Code Reading - Learning More about Ruby by Reading Ruby Source Code\"\n  raw_title: \"[EN] Code Reading - Learning More about Ruby by Reading Ruby Source Code / Eddie Kao\"\n  speakers:\n    - Eddie Kao\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-07-05\"\n  video_provider: \"vimeo\"\n  video_id: \"69748751\"\n  language: \"english\"\n  description: \"\"\n\n- id: \"andr-arko-rubykaigi-2013\"\n  title: \"Security is hard, but we can’t go shopping\"\n  raw_title: \"[EN] Security is hard, but we can’t go shopping / André Arko\"\n  speakers:\n    - André Arko\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-17\"\n  slides_url: \"https://speakerdeck.com/indirect/security-is-hard-but-we-cant-go-shopping-rubykaigi-2013\"\n  video_provider: \"vimeo\"\n  video_id: \"68464116\"\n  language: \"english\"\n  description: |-\n    The last few months have been pretty brutal for anyone who depends on Ruby libraries in production. Ruby is really popular now, and that’s exciting! But it also means that we are now square in the crosshairs of security researchers, whether whitehat, blackhat, or some other hat. Only the Ruby and Rails core teams have meaningful experience with vulnerabilites so far. It won’t last. Vulnerabilities are everywhere, and handling security issues responsibly is critical if we want Ruby (and Rubyists) to stay in high demand. Using Bundler’s first CVE as a case study, I’ll explain responsible disclosure for bugs you find, and repsonsible ownership of your own code. Don’t let your site get hacked, or worse yet, let your project allow someone else’s site to get hacked! Learn from the hard-won wisdom of the security community so that we won’t repeat the mistakes of others.\n\n- id: \"akira-matsuda-rubykaigi-2013\"\n  title: \"Ruby on Your Rails\"\n  raw_title: \"[EN] Ruby on Your Rails / Akira Matsuda\"\n  speakers:\n    - Akira Matsuda\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-17\"\n  slides_url: \"https://speakerdeck.com/a_matsuda/ruby-on-your-rails\"\n  video_provider: \"vimeo\"\n  video_id: \"68464117\"\n  language: \"english\"\n  description: |-\n    My Rails are not like yours. I'm gonna tell you why and how.\n\n- id: \"daniel-bovensiepen-rubykaigi-2013\"\n  title: \"Shrink to Grow\"\n  raw_title: \"[EN] Shrink to Grow / Daniel Bovensiepen\"\n  speakers:\n    - Daniel Bovensiepen\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-07-05\"\n  video_provider: \"vimeo\"\n  video_id: \"69748752\"\n  language: \"english\"\n  description: |-\n    Ruby has grown in the last 20 years. The feature-set and field of usage has increased. But also the code-size has reached an exceptional size. For many systems Ruby is nowadays to large.\n\n    To reach new systems we have to re-think the way we implement Ruby. We have to shrink Ruby to be able to grow into a new field with an army of small devices.\n\n    This talk will cover the development of mruby. The current state of the implementation and the reason why you should contribute to it.\n\n- id: \"xuejie-rafael-xiao-rubykaigi-2013\"\n  title: \"Webruby: Now you can write your favorite Ruby code for the browser!\"\n  raw_title: '[EN] Webruby: Now you can write your favorite Ruby code for the browser! / Xuejie \"Rafael\" Xiao'\n  speakers:\n    - Xuejie \"Rafael\" Xiao\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-07-20\"\n  video_provider: \"vimeo\"\n  video_id: \"70673036\"\n  language: \"english\"\n  description: |-\n    Webruby uses emscripten to compile mruby, the lightweight Ruby implementation into pure JavaScript. This allows programmers to write Ruby code and run it in the browser. What's more, we also built a JavaScript calling interface from Webruby, and an OpenGL ES 2.0 binding. While naturally suited for building Web-based games, Webruby also provides an alternative for modern single-page applications without using JavaScript.\n\n- id: \"jos-valim-rubykaigi-2013\"\n  title: \"Keynote: Concurrency in Ruby: In search of inspiration\"\n  raw_title: \"[EN][Keynote] Concurrency in Ruby: In search of inspiration / José Valim\"\n  speakers:\n    - José Valim\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"68259585\"\n  language: \"english\"\n  description: |-\n    Concurrency has been a popular topic in the programming community in the last decade and has received special attention in the Ruby community in recent years. José Valim will start his talk by explaining why concurrency has become so important and why it is particularly hard to write safe concurrent software in Ruby, based on his experience from working on Ruby on Rails. The goal of this talk is to highlight the current limitations and start the search for possible solutions, looking at how other languages are tackling this issue today.\n\n- id: \"kyosuke-morohashi-rubykaigi-2013\"\n  title: \"Concerning `Applications`\"\n  raw_title: \"[JA] Concerning `Applications` / moro, Kyosuke MOROHASHI\"\n  speakers:\n    - Kyosuke MOROHASHI\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-18\"\n  video_provider: \"vimeo\"\n  video_id: \"68611166\"\n  language: \"japanese\"\n  description: |-\n    In recent years, as Rails has been used in more and more contexts and applied to increasingly complex real-life problems, Rails applications themselves have become more complex. As a result, the so-called Rails \"model\" has become bloated and complex. The question of how to deal with this bloat currently occupies the mind of many Rails users.\n\n    A variety of approaches have been proposed as solutions to this problem. One of these is a technique by which model behavior is divided into small units called \"Concerns\", such that the size of individual classes (whose source code we have to maintain) can be minimized. (In Rails 4, the framework conventions make this easier to do.)\n\n    Starting with Rails 3, I have applied this technique to a number of practical applications. In the process, I have struggled and learned many lessons about how to extract code into concerns, how to test such concerns, and what level of metaprogramming to use. In this talk I'd like to share some of these lessons with you.\n\n- id: \"bryan-helmkamp-rubykaigi-2013\"\n  title: \"Refactoring Fat Models with Patterns\"\n  raw_title: \"[EN] Refactoring Fat Models with Patterns / Bryan Helmkamp\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"68611168\"\n  language: \"english\"\n  description: |-\n    \"Fat models\" cause maintenance issues in large apps. Only incrementally better than cluttering controllers with domain logic, they usually represent a failure to apply the Single Responsibility Principle (SRP). “Anything related to what a user does” is not a single responsibility.\n\n    Early on, SRP is easier to apply. ActiveRecord classes handle persistence, associations and not much else. But bit-by-bit, they grow. Objects that are inherently responsible for persistence become the de facto owner of all business logic as well. And a year or two later you have a User class with over 500 lines of code, and hundreds of methods in it’s public interface. Callback hell ensues.\n\n    This talk will explore patterns to smoothly deal with increasing intrinsic complexity (read: features!) of your application. Transform fat models into a coordinated set of small, encapsulated objects working together in a veritable symphony.\n\n- id: \"usaku-nakamura-rubykaigi-2013\"\n  title: \"Ruby on Windows -- the past, the present, and the future\"\n  raw_title: \"[JA] Ruby on Windows -- the past, the present, and the future / Usaku NAKAMURA\"\n  speakers:\n    - Usaku NAKAMURA\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-07-20\"\n  video_provider: \"vimeo\"\n  video_id: \"70673037\"\n  language: \"japanese\"\n  description: |-\n    Introducing the efforts to the present and future directivity about Windows support of Ruby, and also introducing the truth of how Ruby can actually be used on Windows now.\n\n- id: \"daisuke-inoue-rubykaigi-2013\"\n  title: \"How NougakuDo connect Windows Azure and Rails Application\"\n  raw_title: \"[JA] How NougakuDo connect Windows Azure and Rails Application / Daisuke Inoue\"\n  speakers:\n    - Daisuke Inoue\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"70673038\"\n  language: \"japanese\"\n  description: |-\n    Windows Azure is a Microsoft cloud platform not only for developers with .NET/C#, but also for developers with Ruby on Rails. Ruby on Rails Application can be hosted on Windows Azure Cloud Services (PaaS) with Nougakudo. In this talk, We'll introduce\n\n    - What is Windows Azure Cloud Service\n    - How NougakuDo connect Windows Azure and Rails Application\n    - Case Study\n\n- id: \"nari-rubykaigi-2013\"\n  title: \"Ruby's GC 2.0\"\n  raw_title: \"[JA] Ruby's GC 2.0 / nari\"\n  speakers:\n    - nari\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-18\"\n  video_provider: \"vimeo\"\n  video_id: \"68611167\"\n  language: \"japanese\"\n  description: |-\n    I will talk about some improvements of GC in Ruby 2.0.0. For instance, I will introduce about implementations of Bitmap Marking GC and so on, and show results of benchmarks after these are implemented.\n\n- id: \"tomoyuki-chikanaga-rubykaigi-2013\"\n  title: \"CRuby Committers Who's Who in 2013\"\n  raw_title: \"[JA] CRuby Committers Who's Who in 2013 / Tomoyuki Chikanaga\"\n  speakers:\n    - Tomoyuki Chikanaga\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"68611165\"\n  language: \"japanese\"\n  description: |-\n    Everyday, the CRuby committers work hard to develop CRuby. And there are various services support the development of CRuby(MRI). In this talk, I will introduce the backyard of CRuby development.\n\n- id: \"richard-schneeman-rubykaigi-2013\"\n  title: \"Millions of Apps Deployed: What We've Learned\"\n  raw_title: \"[EN] Millions of Apps Deployed: What We've Learned / Richard Schneeman\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"70673039\"\n  language: \"english\"\n  description: |-\n    Heroku has deployed over a million web apps. When you've run that many applications, it's hard not to notice when frameworks and developers do things wrong, and when they do them right. We've taken a look at the most common patterns and boiled down the best of our advice in to 12 simple factors that can help you build your next app to be stable, successful, and scalable. After this talk you'll walk away with in depth knowledge of web framework design patterns and practical examples of how to improve your application code.\n\n- id: \"matthew-conway-rubykaigi-2013\"\n  title: \"Heroku Add-ons For Fun and Profit\"\n  raw_title: \"[EN] Heroku Add-ons For Fun and Profit / Matthew Conway\"\n  speakers:\n    - Matthew Conway\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"70673040\"\n  language: \"english\"\n  description: |-\n    For building today's web applications, our job is less about doing it all ourself, and often more about integrating the right services. This is how engineers build on Heroku, using any of the broad range of add-ons available to them. It's easy to build add-ons for this marketplace and provide the components for applications of the future. I'll show you how!\n\n- id: \"lightning-talks-rubykaigi-2013\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-21\"\n  video_provider: \"vimeo\"\n  video_id: \"68850145\"\n  language: \"english\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Challenges building a call center with 3rd party APIs\"\n      raw_title: \"Challenges building a call center with 3rd party APIs\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"00:55\"\n      end_cue: \"06:10\"\n      thumbnail_cue: \"01:04\"\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      video_provider: \"parent\"\n      id: \"christian-sousa-lightning-talk-rubykaigi-2013\"\n      video_id: \"christian-sousa-lightning-talk-rubykaigi-2013\"\n      language: \"english\"\n      speakers:\n        - Christian Sousa\n      description: |-\n        Even with the help of third party APIs (Twilio, Tropo, Adhersion, etc.) that provide telephony functionality, there are mayor design challenges involved when building a call center.\n\n        But thanks to the ruby community and the availability of incredible gems and libraries this task is now simple enough that just a few developers can build and replicate full feature telephony systems.\n\n    - title: \"Lightning Talk: A case study on exporting local culture with Rails application\"\n      raw_title: \"A case study on exporting local culture with Rails application\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"07:15\"\n      end_cue: \"12:12\"\n      thumbnail_cue: \"07:20\"\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      video_provider: \"parent\"\n      id: \"yuki-torii-lightning-talk-rubykaigi-2013\"\n      video_id: \"yuki-torii-lightning-talk-rubykaigi-2013\"\n      language: \"english\"\n      speakers:\n        - Yuki Torii\n      description: |-\n        Rails helps people understand new idea, we know.\n\n        There are many interesting local cultures in the world, but it is difficult to introduce such cultures to other people. Rails application can reduce such difficulty using some tips.\n\n        Our experience is introduction of Japanese 'Kukai' to French students. Kukai is a game to enjoy Haiku, short Japanese poetry. In Kukai, attendees score each Haikus and comments by each other. We developed a Kukai Rails application and this system used by a lecture at a French school. The lecture was well-received. To develop our Kukai system, Internationalisation (i18n) is easy to support using Rails framework.\n\n        In this talk, we show our experience and key points of transferring one local culture to other cultures using Rails web application.\n\n    - title: \"Lightning Talk: The Pragmatic Glitch\"\n      raw_title: \"The Pragmatic Glitch\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"12:28\"\n      end_cue: \"16:25\"\n      thumbnail_cue: \"12:28\"\n      language: \"english\"\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      video_provider: \"parent\"\n      id: \"shimpei-makimoto-lightning-talk-rubykaigi-2013\"\n      video_id: \"shimpei-makimoto-lightning-talk-rubykaigi-2013\"\n      speakers:\n        - Shimpei Makimoto\n      description: |-\n        The meaning of glitch is originally unexpected results by malfunctions. By extension, it stands for phenomena (or arts using them) that are caused by errors in various media. In this presentation, I'll show some image glitch ways that beginners can try easily using Ruby.\n\n    - title: \"Lightning Talk: Using flash cards to improve your Ruby\"\n      raw_title: \"Using flash cards to improve your Ruby\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"16:38\"\n      end_cue: \"21:45\"\n      thumbnail_cue: \"16:40\"\n      language: \"english\"\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      video_provider: \"parent\"\n      id: \"peter-evjan-lightning-talk-rubykaigi-2013\"\n      video_id: \"peter-evjan-lightning-talk-rubykaigi-2013\"\n      speakers:\n        - Peter Evjan\n      description: |-\n        When it comes to memorizing the innards of a programming language in order to understand it better, nothing beats flash cards with spaced repetition in my experience. This presentation will show you how you can apply the same technique to make sure you remember everything you want to remember about Ruby (or anything else for that matter).\n\n    - title: \"Lightning Talk: Log Strategy at DeNA with Haikanko - a management tool of fluentd cluster\"\n      raw_title: \"Log Strategy at DeNA with Haikanko - a management tool of fluentd cluster\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"22:17\"\n      thumbnail_cue: \"22:18\"\n      end_cue: \"26:45\"\n      language: \"english\"\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      video_provider: \"parent\"\n      id: \"naotoshi-seo-lightning-talk-rubykaigi-2013\"\n      video_id: \"naotoshi-seo-lightning-talk-rubykaigi-2013\"\n      speakers:\n        - Naotoshi Seo\n      description: |-\n        In this session, I present the log utilization strategy at DeNA, and introduce a tool named Haikanko.\n\n        Haikanko is an application to manage fluentd cluster easily. It enables to generate fluentd configuration files automatically, and deploy them onto lots of fluentd nodes by one click.\n\n        Haikanko is written with ruby / sinatra / erb / mina (yet another capistrano).\n\n    - title: \"Lightning Talk: a test code generator for RSpec users\"\n      raw_title: \"a test code generator for RSpec users\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"27:18\"\n      end_cue: \"31:10\"\n      thumbnail_cue: \"27:20\"\n      language: \"english\"\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      video_provider: \"parent\"\n      id: \"kazuhiro-sera-lightning-talk-rubykaigi-2013\"\n      video_id: \"kazuhiro-sera-lightning-talk-rubykaigi-2013\"\n      speakers:\n        - Kazuhiro Sera\n      description: |-\n        rspec-kickstarter is a test code generator for RSpec users.\n\n        https://github.com/seratch/rspec-kickstarter\n\n        TDD is a very useful approach but actually many projects are not fully TDD-based and we sometimes need to face apps that don't have enough coverage. In such a situation, I believe that this tool is especially useful.\n\n        It's easy to say \"You should write tests for the legacy code before modifying it\" but it's not always easy to keep the motivation to do the right thing because developers have many things to do before they start writing essential parts of test. It's messy to create a new file or figure out the existing spec file, find out what the lacking test cases are and write routine stuff which starts with 'describe'.\n\n        rspec-kickstarteer enables developers writing test immediately. If the spec is absent, it generates a new spec template file. Furthermore, it appends lacking test cases (with TODO comments) to existing the spec file if they're found.\n\n        I know that testing for methods is not perfect but it's pretty important to reduce the psychological barrier.\n\n        I'll show some examples about rspec-kickstarter in this talk.\n      additional_resources:\n        - name: \"seratch/rspec-kickstarter\"\n          type: \"repo\"\n          url: \"https://github.com/seratch/rspec-kickstarter\"\n\n    - title: \"Lightning Talk: Introduction of '3dcg-arts.net'\"\n      raw_title: \"Introduction of '3dcg-arts.net'\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"31:48\"\n      end_cue: \"36:36\"\n      thumbnail_cue: \"31:52\"\n      language: \"english\"\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      video_provider: \"parent\"\n      id: \"hiroyuki-inoue-lightning-talk-rubykaigi-2013\"\n      video_id: \"hiroyuki-inoue-lightning-talk-rubykaigi-2013\"\n      speakers:\n        - Hiroyuki Inoue\n      description: |-\n        I would like to talk about the use of rspec and CI (Jenkins) to improve reliability of 3D computer graphics models conversion software. I'll introduce '3dcg-arts.net', which provides sharing (publish, browse, evaluate, etc) 3D computer graphics works on web browsers. In this service, we developed a software to convert 3D models to a common format for convenient view on web browsers and use rspec and CI for reliability check.\n\n    - title: \"Lightning Talk: FlawDetector - finding ruby code's flaw by static analysis\"\n      raw_title: \"FlawDetector - finding ruby code's flaw by static analysis\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"37:15\"\n      end_cue: \"41:30\"\n      thumbnail_cue: \"37:16\"\n      language: \"english\"\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      video_provider: \"parent\"\n      id: \"rikiya-ayukawa-lightning-talk-rubykaigi-2013\"\n      video_id: \"rikiya-ayukawa-lightning-talk-rubykaigi-2013\"\n      speakers:\n        - Rikiya Ayukawa\n      description: |-\n        I will introduce my static analysis tool called FlawDetector. It analyzes RubyVM bytecode and detects some \"flaws\" in ruby code. \"flaws\" means some bugs and redundant code, which is similar to bug pattern of FindBugs - a static analysis tool of java bytecode. I wish you use FlawDetector and improve it with me.\n\n    - title: \"Lightning Talk: Show Your Opensource Activities w/ ScreenX TV\"\n      raw_title: \"Show Your Opensource Activities w/ ScreenX TV\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"41:42\"\n      end_cue: \"46:50\"\n      thumbnail_cue: \"41:44\"\n      language: \"english\"\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      video_provider: \"parent\"\n      id: \"yasukawa-yohai-lightning-talk-rubykaigi-2013\"\n      video_id: \"yasukawa-yohai-lightning-talk-rubykaigi-2013\"\n      speakers:\n        - Yohei Yasukawa\n      description: |-\n        Knowing WHAT you code is easy; just check your GitHub account, but knowing HOW you code is still difficult. So, we made ScreenX TV, an opensource terminal broadcasting tool, which lets you easily broadcast your terminal to the world.\n\n        In this lightning talk, you'll learn how to broadcast, how it works, and how it's used by terminal broadcasters. ScreenX TV http://screenx.tv/\n\n    - title: \"Lightning Talk: Ruby Taiwan Community: We share, we promote, we celebrate.\"\n      raw_title: \"Ruby Taiwan Community: We share, we promote, we celebrate.\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"47:00\"\n      end_cue: \"52:10\"\n      thumbnail_cue: \"47:01\"\n      language: \"english\"\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      video_provider: \"parent\"\n      id: \"mu-fan-teng-lightning-talk-rubykaigi-2013\"\n      video_id: \"mu-fan-teng-lightning-talk-rubykaigi-2013\"\n      speakers:\n        - Mu-Fan Teng\n      description: |-\n        Introduce the history, activities and achievements of Ruby Taiwan Community and talk about what I have learned from the community.\n\n    - title: \"Lightning Talk: Image resizing and cache Engine by Sinatra\"\n      raw_title: \"Image resizing and cache Engine by Sinatra\"\n      event_name: \"RubyKaigi 2013\"\n      start_cue: \"52:18\"\n      end_cue: \"55:22\"\n      thumbnail_cue: \"52:24\"\n      language: \"english\"\n      speakers:\n        - Chikahiro Tokoro\n      date: \"2013-05-31\"\n      published_at: \"2013-06-21\"\n      slides_url: \"https://speakerdeck.com/kibitan/rubykaigi-2013-lightning-talk-kibitan\"\n      video_provider: \"parent\"\n      id: \"chikahiro-tokoro-lightning-talk-rubykaigi-2013\"\n      video_id: \"chikahiro-tokoro-lightning-talk-rubykaigi-2013\"\n      description: |-\n        Realtime resizing and caching images engine with GET Parameters made by Sinatra.\n\n        It's useful to use as The Image Server with big web service using many images.\n\n        And also useful to fit the image size to smartphone or mobile views without time and effort.\n\n        https://rubykaigi.org/2013/lightning_talks/#kibitan\n      alternative_recordings:\n        - title: \"Lightning Talk: Image resizing and cache Engine by Sinatra\"\n          raw_title: \"Rubykaigi2013 Lightning Talk - Chikahiro Tokoro\"\n          video_id: \"uN8F2wpnBnE\"\n          video_provider: \"youtube\"\n          published_at: \"2013-06-08\"\n          speakers:\n            - Chikahiro Tokoro\n\n- id: \"ruby-committers-vs-the-world-rubykaigi-2023\"\n  title: \"Ruby Committers vs. the World\"\n  raw_title: \"[JA] Ruby Committers vs. the World\"\n  speakers:\n    - Ruby Committers\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-05-31\"\n  published_at: \"2013-06-17\"\n  video_provider: \"not_recorded\"\n  video_id: \"ruby-committers-vs-the-world-rubykaigi-2023\"\n  language: \"japanese\"\n  description: \"\"\n\n## Day 3\n\n- id: \"masatoshi-seki-rubykaigi-2013\"\n  title: \"Async programming is all about programming synchronously\"\n  raw_title: \"[JA] Async programming is all about programming synchronously / Masatoshi SEKI\"\n  speakers:\n    - Masatoshi SEKI\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-06-01\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"68850149\"\n  language: \"japanese\"\n  description: |-\n    \"dRuby is a failure.\"\n\n    I resolved to give this talk after hearing these words from the authors of other libraries.\n\n    In the talk I'll introduce some common asynchronous programming patterns and show how common themes in asynchronous programming are actually all about programming synchronously.\n\n    I will also touch on asynchronous function calls in Ruby, the design philosophy of dRuby, and what Drip was aimed to solve.\n\n    Target audiences:\n    people with intermediate to advanced-level programming experience with high-level multiplexing languages that use select and TCP, such as Node.js, X11 and dRuby\n    enthusiasts of Linda languages and actor-based models\n\n- id: \"jim-gay-rubykaigi-2013\"\n  title: \"If you do not enter the tiger's cave, you will not catch its cub: Objects, DCI, and Programming\"\n  raw_title: \"[EN] If you do not enter the tiger's cave, you will not catch its cub: Objects, DCI, and Programming / Jim Gay\"\n  speakers:\n    - Jim Gay\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-06-01\"\n  published_at: \"2013-06-21\"\n  video_provider: \"vimeo\"\n  video_id: \"68850148\"\n  language: \"english\"\n  description: |-\n    As the responsibility of our applications grows, so too does our code. We'll walk through techniques of object-oriented programming that help clarify our intent and put responsibilities right where we need them.\n\n- id: \"david-padilla-rubykaigi-2013\"\n  title: \"From Rails to the web server to the browser\"\n  raw_title: \"[EN] From Rails to the web server to the browser / David Padilla\"\n  speakers:\n    - David Padilla\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-06-01\"\n  published_at: \"2013-06-12\"\n  video_provider: \"vimeo\"\n  video_id: \"70184258\"\n  language: \"english\"\n  description: |-\n    Most of us know how to build beautiful web applications with Rails. With the help of templating tools like ERB and HAML our web apps create HTML documents, but, do you know exactly how those HTML documents end up in a browser?\n\n    During this talk I will show you the bits that make it all happen. We will dissect the relevant code within Rails, Rack and the thin web server to discover exactly how the web server starts and listens to a TCP port, communicates with Rails and returns the HTML document that your browser parses.\n\n    Why? Because we're curious about it, that's why.\n\n- id: \"ryan-smith-rubykaigi-2013\"\n  title: \"Fewer Constraints, More Concurrency.\"\n  raw_title: \"[EN] Fewer Constraints, More Concurrency. / Ryan Smith\"\n  speakers:\n    - Ryan Smith\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-06-01\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"68850147\"\n  language: \"english\"\n  description: |-\n    Traditional data structures like stacks and queues are strict - perhaps too strict. In this talk I will showcase some classical data structures and then provide alternative constraints that will allow our algorithms to achieve a greater level of concurrency. Examples will include a mix of Ruby and Postgres.\n\n- id: \"max-gorin-rubykaigi-2013\"\n  title: \"Rapid development of enterprise web apps with Netzke\"\n  raw_title: \"[EN] Rapid development of enterprise web apps with Netzke / Max Gorin\"\n  speakers:\n    - Max Gorin\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-06-01\"\n  published_at: \"2013-06-26\"\n  video_provider: \"vimeo\"\n  video_id: \"69128205\"\n  language: \"english\"\n  description: |-\n    Netzke is a library that allows creating full-featured client-server GUI components - such as data grids, forms, windows, trees, etc - which then can be easily used as building blocks for complex enterprise applications. It uses Ruby on Rails at the server-side, and Sencha Ext JS in the browser. The choice of Ext JS provides for consistent look and feel, as well as for painless reusability of third-party Netzke components. Most importantly, Netzke allows for writing clean and highly maintainable code, which almost doesn't grow with the number of data models being used. After a brief introduction to the basics of Netzke design, some cool code will be shown from a fairly complex real-life web application, which will demonstrate a few highly practical aspects of Netzke.\n\n- id: \"toru-kawamura-rubykaigi-2013\"\n  title: \"Rails Gems realize RESTful modeling patterns\"\n  raw_title: \"[JA] Rails Gems realize RESTful modeling patterns / Toru Kawamura\"\n  speakers:\n    - Toru Kawamura\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-06-01\"\n  published_at: \"2013-07-12\"\n  video_provider: \"vimeo\"\n  video_id: \"70184260\"\n  language: \"japanese\"\n  description: |-\n    Although it is not widely known, classic Rails gems such as Devise and Kaminari hide within them the RESTful resource modeling pattern. Using these gems encourages good resource design.\n\n    Since 2.0, Rails has moved toward incorporating RESTful resource design. The RESTful architecture has become a part of Rails. One of the best examples of this are the resources in routes.rb, which provide the basic resource pattern for Rails applications. However, the world of practical applications is not ready for this RESTful side of Rails, and so when people actually develop applications, they hesitate about this aspect of RESTful resource design. It is here that these gems fill an essential gap.\n\n    In this talk I will look at useful practical patterns adopted in such gems, and also introduce a gem currently under development which has the potential to play the role of a key missing piece.\n\n- id: \"matthew-mongeau-rubykaigi-2013\"\n  title: \"The Origamist's Ruby: Folding better code\"\n  raw_title: \"[EN] The Origamist's Ruby: Folding better code / Matthew Mongeau\"\n  speakers:\n    - Matthew Mongeau\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-06-01\"\n  published_at: \"2013-07-12\"\n  video_provider: \"vimeo\"\n  video_id: \"70184420\"\n  language: \"english\"\n  description: |-\n    Origami and the Ruby programming language have a lot more in common than having Japanese roots. This talk will make parallels between the two with the goal of presenting various techniques at becoming a better artist of code.\n\n- id: \"kouhei-sutou-rubykaigi-2013\"\n  title: \"Be a library developer!\"\n  raw_title: \"[JA] Be a library developer! / Kouhei Sutou\"\n  speakers:\n    - Kouhei Sutou\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-06-01\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"69128203\"\n  language: \"japanese\"\n  description: |-\n    Is there a gem author around you? Did you meet any author of the gems used? Did you contact with any author of the gems used on the Internet?\n\n    Do you think that \"the author is cool!\", \"the author is awesome!\" or \"I respect the author!\"? Do you want to be a gem author?\n\n    This talk doesn't describe about how to create a gem because it is easy. \"gem\" is a package of Ruby library (, tool and so on) for easy to install. This talk describes about developing a library that is gem content.\n\n    This talk is based on my experience as a library developer. This talk describes about how to write codes, how to write documents, release, support and mental set for a better \"library developer\". I hope that this talk is a trigger for increasing the number of better \"library developers\".\n\n- id: \"konstantin-haase-rubykaigi-2013\"\n  title: \"Beyond Ruby\"\n  raw_title: \"[EN] Beyond Ruby / Konstantin Haase\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"RubyKaigi 2013\"\n  date: \"2013-06-01\"\n  published_at: \"2013-06-17\"\n  video_provider: \"vimeo\"\n  video_id: \"69128201\"\n  language: \"english\"\n  description: |-\n    Ruby is the most flexible language out there, imposing no limitations on the developers, giving all the expressiveness possible. Or so we think. But there are languages pushing dynamic features and expressiveness far beyond what is possible in Ruby. Some are old, like Lisp and Smalltalk, some are just emerging, purely experimental languages, like Ioke or Newspeak. In this talk, we will take a look at some of these languages and what they can do that Ruby can't. What does it mean, to be homoiconic? How does a language without keywords work? Can I dispatch in more than one direction? And what is partial evaluation?\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2014/event.yml",
    "content": "---\nid: \"rubykaigi-2014\"\ntitle: \"RubyKaigi 2014\"\nkind: \"conference\"\nlocation: \"Edogawa, Tokyo, Japan\"\ndescription: |-\n  Tower Hall Funabori\nstart_date: \"2014-09-18\"\nend_date: \"2014-09-20\"\nyear: 2014\nwebsite: \"https://rubykaigi.org/2014/\"\nbanner_background: \"#EDDCC2\"\nfeatured_background: \"#EDDCC2\"\nfeatured_color: \"#5A4A40o\"\ncoordinates:\n  latitude: 35.6764225\n  longitude: 139.650027\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2015/event.yml",
    "content": "---\nid: \"PLbFmgWm555yalhrTtBXJdPBq6bQWIiza1\"\ntitle: \"RubyKaigi 2015\"\nkind: \"conference\"\nlocation: \"Chuo-ku, Tokyo, Japan\"\ndescription: \"\"\npublished_at: \"2017-09-18\"\nstart_date: \"2015-12-11\"\nend_date: \"2015-12-13\"\nchannel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\nyear: 2015\nbanner_background: \"#FFAB0C\"\nfeatured_background: \"#FFAB0C\"\nfeatured_color: \"#444444\"\nwebsite: \"https://rubykaigi.org/2015/\"\ncoordinates:\n  latitude: 35.6706392\n  longitude: 139.7719892\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2015/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"evan-phoenix-rubykaigi-2015\"\n  title: \"Keynote: Ruby 2020\"\n  raw_title: \"Ruby: 2020 - RubyKaigi 2015 Keynote\"\n  speakers:\n    - Evan Phoenix\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-20\"\n  video_provider: \"youtube\"\n  video_id: \"QaLvtNpoc5o\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/evanphx\n\n- id: \"lein-weber-rubykaigi-2015\"\n  title: \"Introducing the Crystal Programming Language\"\n  raw_title: \"Introducing the Crystal Programming Language - RubyKaigi 2015\"\n  speakers:\n    - Lein Weber\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"7dwDzlVI7OU\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/leinweber\n\n    Developer happiness is what brought me to Ruby in the first place. And of all the new compiled languages, Crystal is the only one that shares this value. The syntax and idioms are entirely Ruby inspired.\n\n    Although Crystal looks very similar to Ruby, there are big differences between the two. Crystal is statically typed and dispatched. While there are no runtime dynamic features, the compile-time macros solve many of the same problems.\n\n    In this session, we’ll take a close look at these differences as well as the similarities, and what Ruby developers can learn from this exciting language.\n\n- id: \"takashi-kokubun-rubykaigi-2015\"\n  title: \"High Performance Template Engine: Guide to optimize your Ruby code\"\n  raw_title: \"High Performance Template Engine: Guide to optimize your Ruby code - RubyKaigi 2015\"\n  speakers:\n    - Takashi Kokubun\n    - Kohei Suzuki\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-24\"\n  video_provider: \"youtube\"\n  video_id: \"vM9XfqlqyNw\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/eagletmt_k0kubun\n\n    Have you ever thought about performance of your Ruby code? If not, you might write ineffective code and slow down your application. Poor performance disappoints the users of your app causing you to lose their confidence.\n\n    In this talk, we show the process of creating faster Haml implementations: Faml and Hamlit. You will see how to improve the performance of your code.\n    We will show you the typical structure of template engines first, so experience with them is not required. After this talk, you'll be able to optimize your application using the techniques we will show you.\n\n- id: \"kosaki-motohiro-rubykaigi-2015\"\n  title: \"Linux loves Ruby, Ruby loves Linux - Keynote\"\n  raw_title: \"Linux loves Ruby, Ruby loves Linux - RubyKaigi 2015 Keynote\"\n  speakers:\n    - KOSAKI Motohiro\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-20\"\n  video_provider: \"youtube\"\n  video_id: \"idmfWkP5lOw\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/kosaki\n\n- id: \"kevin-menard-rubykaigi-2015\"\n  title: \"Fast Metaprogramming with Truffle\"\n  raw_title: \"Fast Metaprogramming with Truffle - RubyKaigi 2015\"\n  speakers:\n    - Kevin Menard\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-24\"\n  video_provider: \"youtube\"\n  video_id: \"lRMWwjqbXUo\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/nirvdrum\n\n    \"Metaprogramming is a powerful technique that sets Ruby apart from other contemporary languages. It allows compact and elegant solutions to seemingly intractable problems. Serving as the foundation of some of the mostly widely used frameworks and DSLs in the Ruby ecosystem, it’s arguably the single most defining feature of Ruby. Unfortunately, that expressive power has traditionally come at the expense of performance.\n\n    We’ll show you how JRuby+Truffle has eliminated the cost of metaprogramming so Rubyists can write idiomatic Ruby without having to worry about hidden performance trade-offs.\"\n\n- id: \"koichi-sasada-rubykaigi-2015\"\n  title: \"Compiling Ruby scripts\"\n  raw_title: \"Compiling Ruby scripts - RubyKaigi 2015\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-24\"\n  video_provider: \"youtube\"\n  video_id: \"sFfwQ1-PFt0\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/ko1\n\n    Ruby (MRI) 2.2 compiles Ruby scripts into bytecode (instruction sequences) at run time. This approach is simple, but has several problems such as overhead of compile time. We are working on making an Ahead of Time compiler which compiles Ruby script before executing the script. This compiler will help to reduce boot time and to reduce memory consumption on multiple Ruby processes. In this presentation, we will introduce the compiler and that mechanism.\n\n- id: \"yehuda-katz-rubykaigi-2015\"\n  title: \"Turbo Rails with Rust\"\n  raw_title: \"Turbo Rails with Rust - RubyKaigi 2015\"\n  speakers:\n    - Yehuda Katz\n    - Godfrey Chan\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-25\"\n  video_provider: \"youtube\"\n  video_id: \"uiNpoDB4dA0\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/wycats_chancancode\n\n    Ruby is not the fastest language in the world, there is no doubt about it. This doesn't turn out to matter all that much – Ruby and its ecosystem has so much more to offer, making it a worthwhile tradeoff a lot of the times.\n\n    However, you might occasionally encounter workloads that are simply not suitable for Ruby. In this talk, we will explore building a native extension with Rust to speed up parts of Rails. (No prior experience with Rust required!) What does Rust has to offer in this scenario over plain-old C? Let's find out!\n\n- id: \"hsing-hui-hsu-rubykaigi-2015\"\n  title: \"Time flies like an arrow; Fruit flies like a banana: Parsers for Great Good\"\n  raw_title: \"Time flies like an arrow; Fruit flies like a banana: Parsers for Great Good - RubyKaigi 2015\"\n  speakers:\n    - Hsing-Hui Hsu\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"a_mJIR0Rk9U\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/SoManyHs\n\n    When you type print \"Hello, world!\", how does your computer\n    know what to do? Humans are able to naturally parse spoken language by\n    analyzing the role and meaning of each word in context of its\n    sentence, but we usually take for granted the way computers make sense\n    of the code we write.\n\n    By exploring the way our brains construct grammars to parse sentences,\n    we can better understand how parsers are used for computering --\n    whether it be in the way Ruby and other languages are implemented or\n    in webserver routing -- and recognize when they may be the right tool\n    to use in our own code.\n\n- id: \"kouhei-sutou-rubykaigi-2015\"\n  title: \"The history of testing framework in Ruby\"\n  raw_title: \"The history of testing framework in Ruby - RubyKaigi 2015\"\n  speakers:\n    - Kouhei Sutou\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-25\"\n  video_provider: \"youtube\"\n  video_id: \"g33d9SSbvd8\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/kou\n\n    This talk describes about the history of testing framework in Ruby.\n\n    Ruby 2.2 bundles two testing frameworks. They are minitest and test-unit. Do you know why two testing frameworks are bundled? Do you know that test-unit was bundled and then removed from Ruby distribution? If you can't answer these questions and you're interested in testing framework, this talk will help you.\n\n    This talk describes about the history of bundled testing framework in Ruby and some major testing frameworks for Ruby in chronological order.\n\n- id: \"fernando-hamasaki-de-amorim-rubykaigi-2015\"\n  title: \"The worst Ruby codes I've seen in my life\"\n  raw_title: \"The worst Ruby codes I've seen in my life - RubyKaigi 2015\"\n  speakers:\n    - Fernando Hamasaki de Amorim\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"jLAFXQ1Av50\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/prodis\n\n    Most applications written in Ruby are great, but also exists evil code applying WOP techniques. There are many workarounds in several programming languages, but in Ruby, when it happens, the proportion is bigger. It's very easy to write Ruby code with collateral damage.\n\n    You will see a collection of bad Ruby codes, with a description of how these codes affected negatively their applications and the solutions to fix and avoid them. Long classes, coupling, misapplication of OO, illegible code, tangled flows, naming issues and other things you can ever imagine are examples what you'll get.\n\n- id: \"laurent-sansonetti-rubykaigi-2015\"\n  title: \"The future of Ruby is in motion!\"\n  raw_title: \"The future of Ruby is in motion! - RubyKaigi 2015\"\n  speakers:\n    - Laurent Sansonetti\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-25\"\n  video_provider: \"youtube\"\n  video_id: \"uzUmUmEX-Ls\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/lrz\n\n    In this presentation we will give a quick and gentle introduction to RubyMotion, a Ruby toolchain to write cross-platform apps for iOS and Android. Then, we will cover 3 of its latest features: Apple Watch, Apple TV and a cross-platform game engine. We will do live demos and coding.\n\n- id: \"youchan-rubykaigi-2015\"\n  title: \"Writing web application in Ruby\"\n  raw_title: \"Writing web application in Ruby - RubyKaigi 2015\"\n  speakers:\n    - youchan\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-02\"\n  video_provider: \"youtube\"\n  video_id: \"xEK1hg8noSc\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/youchan\n\n    Does this happen to you?\n    You were developing web application with Ruby on Rails, but somehow you ended up writing front-end in JavaScript.\n    Ruby on Rails seemed very cool to me! And Rubyists are always happy to build applications with it!\n    However, front-end development is becoming important today.\n    Then I found Opal, and my dream of writing Ruby on the front-end is possible!\n    Recently, React.js, a kind of Virtual DOM, has become very popular in the front-end community.\n    It's not only intended for front-end web, there is also ReactNative for other platforms too.\n    I think many Rubyists are still lost, so I created a Virtual DOM implementation in Ruby called Hyalite.\n    All right, Opal, Hyalite ... tools have been gathered. Let's build web applications on server-side and front-end with Ruby!\n\n- id: \"sadayuki-furuhashi-rubykaigi-2015\"\n  title: \"Plugin-based software design with Ruby and RubyGems\"\n  raw_title: \"Plugin-based software design with Ruby and RubyGems - RubyKaigi 2015\"\n  speakers:\n    - Sadayuki Furuhashi\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"C6SP3CzCb5k\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/frsyuki\n\n    Plugin architecture is known as a technique that brings extensibility to a program. Ruby has good language features for plugins. RubyGems.org is an excellent platform for plugin distribution. However, creating plugin architecture is not as easy as writing code without it: plugin loader, packaging, loosely-coupled API, and performance. Loading two versions of a gem is a unsolved challenge that is solved in Java on the other hand.\n    I have designed some open-source software such as Fluentd and Embulk. They provide most of functions by plugins. I will talk about their plugin-based architecture.\n\n- id: \"matthew-gaudet-rubykaigi-2015\"\n  title: \"Experiments in sharing Java VM technology with CRuby\"\n  raw_title: \"Experiments in sharing Java VM technology with CRuby - RubyKaigi 2015\"\n  speakers:\n    - Matthew Gaudet\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-24\"\n  video_provider: \"youtube\"\n  video_id: \"EDxoaEdR-_M\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/MattStudies\n\n    What happens you have a virtual machine full of powerful technology and you start pulling out the language independent parts, with plans to open source these technologies?\n\n    You get the ability to experiment! This talk covers a set of experiments where IBM has tested out language-agnostic runtime technologies inside of CRuby, including a GC, JIT and more-- all while still running real Ruby applications, including Rails.\n\n    We want to share results from these experiments, talk about how we connected to CRuby, and discuss how this may one day become a part of everyone's CRuby.\n\n- id: \"lightning-talks-rubykaigi-2015\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks - RubyKaigi 2015\"\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-25\"\n  video_provider: \"youtube\"\n  video_id: \"Yf7l4Yp461I\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/lt\n  talks:\n    - title: \"Lightning Talk: Update Early, Update Often\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"juanito-fatas-lighting-talk-rubykaigi-2015\"\n      video_id: \"juanito-fatas-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Juanito Fatas\n\n    - title: \"Lightning Talk: Automating View Internationalization in Ruby on Rails\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"kouta-kariyado-lighting-talk-rubykaigi-2015\"\n      video_id: \"kouta-kariyado-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Kouta Kariyado\n\n    - title: \"Lightning Talk: A new testing framework Rgot\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"yuki-kurihara-lighting-talk-rubykaigi-2015\"\n      video_id: \"yuki-kurihara-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Yuki Kurihara\n\n    - title: \"Lightning Talk: Building an Unbreakable MRI-based Embedded Computer Appliance\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"arkadiusz-turlewicz-lighting-talk-rubykaigi-2015\"\n      video_id: \"arkadiusz-turlewicz-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Arkadiusz Turlewicz\n\n    - title: \"Lightning Talk: Do you trust that certificate?\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"zunda-lighting-talk-rubykaigi-2015\"\n      video_id: \"zunda-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - zunda\n\n    - title: \"Lightning Talk: How I debugged debugger\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"takashi-kokubun-lighting-talk-rubykaigi-2015\"\n      video_id: \"takashi-kokubun-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Takashi Kokubun\n\n    - title: \"Lightning Talk: Padrino Travel Guide\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"namusyaka-lighting-talk-rubykaigi-2015\"\n      video_id: \"namusyaka-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - namusyaka\n\n    - title: \"Lightning Talk: What I learned by implementing a Ruby VM in Erlang\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"lin-yu-hsiang-lighting-talk-rubykaigi-2015\"\n      video_id: \"lin-yu-hsiang-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Lin Yu Hsiang\n\n    - title: \"Lightning Talk: Rubygemsで作るお手軽データ分析基盤 〜あるいは 私はどうやって他人の褌で相撲を取ったか〜\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tomohiro-hashidate-lighting-talk-rubykaigi-2015\"\n      video_id: \"tomohiro-hashidate-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomohiro Hashidate\n\n    - title: \"Lightning Talk: Rationalを最適化してみた\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tadashi-saito-lighting-talk-rubykaigi-2015\"\n      video_id: \"tadashi-saito-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Tadashi Saito\n\n    - title: \"Lightning Talk: The Mythical Creatures of Summer of Code\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pilar-andrea-huidobro-peltier-lighting-talk-rubykaigi-2015\"\n      video_id: \"pilar-andrea-huidobro-peltier-lighting-talk-rubykaigi-2015\"\n      video_provider: \"parent\"\n      speakers:\n        - Pilar Andrea Huidobro Peltier\n\n- id: \"yusuke-endoh-rubykaigi-2015\"\n  title: \"TRICK 2015: The second Transcendental Ruby Imbroglio Contest for RubyKaigi\"\n  raw_title: \"TRICK 2015: The second Transcendental Ruby Imbroglio Contest for RubyKaigi - RubyKaigi 2015\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-24\"\n  video_provider: \"youtube\"\n  video_id: \"dmHqtr_GNtg\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/trick\n\n    The result presentation of TRICK 2015, an esoteric Ruby programming contest, will take place. You can (perhaps) enjoy some winning entries of unearthly Ruby code selected by esoteric judges.\n\n- id: \"masaki-matsushita-rubykaigi-2015\"\n  title: \"Ruby meets Go\"\n  raw_title: \"Ruby meets Go - RubyKaigi 2015\"\n  speakers:\n    - Masaki Matsushita\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-25\"\n  video_provider: \"youtube\"\n  video_id: \"xIVrUWmmass\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/mmasaki\n\n    In this talk, I will present how to extend your Ruby code with Golang.\n    Since Go 1.5, you can build C compatible binaries by using buildmode c-shared/c-archive. This is a very exciting feature for rubyists.\n    First, I'd like to show you how to use Go code from Ruby with FFI and fiddle.\n    Then, I will talk about how to build gems with Golang.\n\n- id: \"franck-verrot-rubykaigi-2015\"\n  title: \"Ruby and PostgreSQL, a love story\"\n  raw_title: \"Ruby and PostgreSQL, a love story - RubyKaigi 2015\"\n  speakers:\n    - Franck Verrot\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"bchlcxAZ9tU\"\n  description: |-\n    PostgreSQL 9.1 introduced Foreign Data Wrappers, as an implementation of SQL/MED foreign tables, to provide transparent access to external data. Restricted to being written in C, writing FDWs can be a hard task.\n\n    In this talk we will learn just enough of mruby's (the ISO-compliant version of Ruby) internals to understand how one can embed mruby in an external program (like PostgreSQL), and start writing Foreign Data Wrappers in Ruby.\n\n- id: \"yuki-nishijima-rubykaigi-2015\"\n  title: \"Saving people from typos\"\n  raw_title: \"Saving people from typos - RubyKaigi 2015\"\n  speakers:\n    - Yuki Nishijima\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"b9621w7_vxc\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/yuki24\n\n    Whenever you make a typo on Google or a git … cmd, they’ll automagically correct it for you. It’s great, but have you ever wondered why programming languages don’t have such a cool feature? The next major version of Ruby will! The did_you_mean gem was built to add on a “Did you mean?” experience and Ruby 2.3 will ship with it.\n\n    So what does the whole story look like? How can you use it in your app or gem? How does it correct typos? What even is a typo?\n\n    Let's learn how to take advantage of this new feature in Ruby 2.3 and save ourselves from typos forever!\n\n- id: \"aaron-patterson-rubykaigi-2015\"\n  title: \"Request and Response\"\n  raw_title: \"Request and Response - RubyKaigi 2015\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"0cmXVXMdbs8\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/tenderlove\n\n    What goes in to a request and response in a Rails application? Where does the\n    application get its data, and how does that data get to the client when you are\n    done? In this talk we'll look at the request and response lifecycle in Rails.\n    We'll start with how a request and response are serviced today, then move on\n    to more exciting topics like adding HTTP2 support and what that means for\n    developing Rails applications.\n\n- id: \"yutaka-hara-rubykaigi-2015\"\n  title: \"Let's make a functional language!\"\n  raw_title: \"Let's make a functional language! - RubyKaigi 2015\"\n  speakers:\n    - Yutaka HARA\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-02\"\n  video_provider: \"youtube\"\n  video_id: \"NNsX92hKirM\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/yhara\n\n    Recently, functional programming with type inference has become popular, let's try to make it! But what if you don't know where to start...? For such a Rubyist, this talk will explain from basics of language implementation to the Hindley-Milner type inference. We can make a functional language!\n\n- id: \"shota-nakano-rubykaigi-2015\"\n  title: \"mruby on the minimal embedded resource\"\n  raw_title: \"mruby on the minimal embedded resource - RubyKaigi 2015\"\n  speakers:\n    - Shota Nakano\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-24\"\n  video_provider: \"youtube\"\n  video_id: \"EXvDKb2LTYM\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/shotantan\n\n    Introducing how mruby comes to term with the embedded board's poor resource.\n    I suggest a solution that they can mount an external NOR Flash chip as RAM cache.\n    Although mruby is a minimal implementation of Ruby, it requires huge RAM as is Embed field. A lot of embedded board has poor RAM less than 128KB, except for rich embedded board, like Raspberry Pi.\n    An external NOR Flash as mruby RAM cache is cheap solution. Typically, NOR Flash's writing frequency is limited, 100 thousand times. I also introduce performance measurement to reduce mruby RAM writting.\n\n- id: \"terence-lee-rubykaigi-2015\"\n  title: \"Building CLI Apps for Everyone\"\n  raw_title: \"Building CLI Apps for Everyone - RubyKaigi 2015\"\n  speakers:\n    - Terence Lee\n    - Zachary Scott\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-25\"\n  video_provider: \"youtube\"\n  video_id: \"EhEWn5Uudow\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/hone02_zzak\n\n    Many projects rely on command-line tools to provide an efficient and powerful interface to work.\n\n    Building tools for everyone can be difficult, because of conflicting environment or OS.\n\n    How can we build command-line apps that work for everyone and still write Ruby?\n\n    This talk will discuss how to use mruby-cli to build cross-platform apps in Ruby.\n\n    Our goal will be to build a CLI app using mruby and produce a self-contained binary that can be shipped to end users.\n\n    Since mruby is designed to be embedded and statically compiled, it's also really good at packaging ruby code.\n\n- id: \"ruby-committers-rubykaigi-2015\"\n  title: \"Ruby Committers vs the World\"\n  raw_title: \"Ruby Committers vs the World - RubyKaigi 2015\"\n  speakers:\n    - Ruby Committers # TODO: list each person\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"LcXKSHsniTY\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/committers\n\n- id: \"paolo-nusco-perrotta-rubykaigi-2015\"\n  title: \"Refinements - the Worst Feature You Ever Loved\"\n  raw_title: \"Refinements - the Worst Feature You Ever Loved - RubyKaigi 2015\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"_gLgE3c5jTU\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/nusco\n\n    Refinements are cool. They are the biggest new language feature in Ruby 2. They help you avoid some of Ruby's most dangerous pitfalls. They make your code cleaner and safer.\n\n    Oh, and some people really hate them.\n\n    Are Refinements the best idea since blocks and modules, or a terrible mistake? Decide for yourself. I'll tell you the good, the bad and the ugly about refinements. At the end of this speech, you'll understand the trade-offs of this controversial feature, and know what all the fuss is about.\n\n- id: \"robert-young-rubykaigi-2015\"\n  title: \"It's dangerous to GC alone. Take this!\"\n  raw_title: \"It's dangerous to GC alone. Take this! - RubyKaigi 2015\"\n  speakers:\n    - Robert Young\n    - Craig Lehmann\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"nhqNaZxHbHY\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/youngrw_CraigLehmann\n\n    Every language community implements the same core components. Things like garbage collection, just-in-time compilation and threading. Wouldn't it be great if these were shared between languages? An improvement to one language would mean an improvement to all.\n\n    We’re actually doing it: open sourcing the core components of IBM’s Java Virtual Machine into an open language toolkit. Our first proof of concept language is Ruby. This talk will discuss the process and results of integrating a new garbage collector into Ruby.\n\n- id: \"josh-kalderimis-rubykaigi-2015\"\n  title: \"Beyond Saas: Building for Enterprise\"\n  raw_title: \"Beyond Saas: Building for Enterprise - RubyKaigi 2015\"\n  speakers:\n    - Josh Kalderimis\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"gVm7dd2G7CQ\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/joshk\n\n    Travis CI found itself growing a great SaaS product, when Enterprise users began unexpectedly asking to use our product on-premise. Our small team had to quickly understand:\n\n    The maintenance implications for different ways to package our app.\n    How to provide enterprise customers great support, despite the new constraints.\n    How to prioritize Enterprise-specific features.\n\n    This talk is the story of how we added an Enterprise offering to our existing hosted Continuous Integration service, the bumps we hit along the way, and what we would do differently now.\n\n- id: \"yurie-yamane-rubykaigi-2015\"\n  title: \"making robots with mruby\"\n  raw_title: \"making robots with mruby - RubyKaigi 2015\"\n  speakers:\n    - Yurie Yamane\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-25\"\n  video_provider: \"youtube\"\n  video_id: \"u7WCIN5HMDI\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/yurie\n\n    Linuxの入っているハードウェアをあえてLinuxを使わないでTOPPERS EV3RT というRTOS を入れたり、bare metal の状態にしてmrubyを動かします。\n    今回の対象はLEGO Mindstorms EV3とraspberry pi。\n    Cに比べて遅いのでハードウェア制御には向かないのでは？と言われがちなmrubyを使って倒立振子の制御をします。\n\n- id: \"masahiro-nagano-rubykaigi-2015\"\n  title: \"Rhebok, High Performance Rack Handler\"\n  raw_title: \"Rhebok, High Performance Rack Handler - RubyKaigi 2015\"\n  speakers:\n    - Masahiro Nagano\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"EPxWD_2Yekg\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/kazeburo\n\n    Rhebok is High Performance Rack Handler/Web Server. 2x performance when compared against Unicorn.\n\n    In this presentation, I'll introduce the Rack interface spec, the architecture of widely used rack servers, and technology that supports performance of Rhebok includes prefork_engine, picohttpparser, system calls.\n\n- id: \"ippei-obayashi-rubykaigi-2015\"\n  title: \"Ruby for one day game programming camp for beginners\"\n  raw_title: \"Ruby for one day game programming camp for beginners - RubyKaigi 2015\"\n  speakers:\n    - Ippei Obayashi\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"bvXYCpcOQ3E\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/ohai\n\n    KMC, Kyoto university Microcomputer Club, a computer circle in Kyoto University, holds one day game programming camp for newcomers (undergraduate students interested in KMC and programming) in April and May to invite an enjoyable programming world.\n\n    As you know, Ruby is one of the best languages to learn programming itself and used in the camp to build a simple game within one day. This talk provides experiences and messages coming from the events, and explains the history of frameworks used in the event. This talk give you a hint to educate beginners.\n\n- id: \"emily-stolfo-rubykaigi-2015\"\n  title: \"DIY (Do-it-Yourself) Testing\"\n  raw_title: \"DIY (Do-it-Yourself) Testing - RubyKaigi 2015\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"MrfdHpz0-AQ\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/estolfo\n\n    There are so many testing frameworks available to us that we sometimes overlook a completely valid, and sometimes preferable option: writing our own.\n\n    The drivers team at MongoDB focused over the last year on conforming to common APIs and algorithms but we needed a way to validate our consistency. We therefore ended up building our own testing DSL, REST service, and individual test frameworks.\n\n    Using these common tests and the Ruby driver's test suite as examples, this talk will demonstrate when existing test frameworks aren't the best choice and show how you can build your own.\n\n- id: \"naohisa-goto-rubykaigi-2015\"\n  title: \"Running Ruby on Solaris\"\n  raw_title: \"Running Ruby on Solaris - RubyKaigi 2015\"\n  speakers:\n    - Naohisa Goto\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"LlcEduexIcU\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/ngoto\n\n    I'm using Fujitsu SPARC Enterprise server whose OS is Oracle (former Sun) Solaris 10. In Solaris, there is a number of minor differences from other major OS like Linux and Mac OS X, and a number of changes have been made to run Ruby (CRuby) without failure. I'd like to talk about these changes as a user of the Solaris OS.\n\n    The following topics will be included in this presentation.\n\n    Tips to build Ruby and other free software on Solaris\n    Recent changes to Ruby (CRuby) needed for Solaris\n    Bugs potentially affected to all platforms but revealed by running on Solaris\n\n- id: \"shibata-hiroshi-rubykaigi-2015\"\n  title: \"Pragmatic Testing of Ruby Core\"\n  raw_title: \"Pragmatic Testing of Ruby Core - RubyKaigi 2015\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"Tgtprqw8_IQ\"\n  description: |-\n    When you need to understand a new library or framework, you might try to invoke the test suite with \"rake test\" or \"rake spec\". CRuby also has a test suite like many libraries and frameworks, written in Ruby. But, It's different from typical ruby libraries. Therefore many Rubyists don't know how to run the CRuby test suite.\n    This is because CRuby's test suite has historical and complex structures. In this talk, I explain the details of the CRuby test suite and protips for CRuby's testing technology.\n\n- id: \"julian-cheal-rubykaigi-2015\"\n  title: \"Charming Robots\"\n  raw_title: \"Charming Robots - RubyKaigi 2015\"\n  speakers:\n    - Julian Cheal\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"t2NoXELaF0E\"\n  description: |-\n    [Due to copyright reasons, mute audio in some parts of the movie]\n\n\n    http://rubykaigi.org/2015/presentations/juliancheal\n\n    Web apps are great and everything, but imagine using Ruby to fly drones and make them dance to the sounds of dubstep! Or to control disco lights and other robots! Sounds fun, right? In this talk, we will not only explore how we can write code to make this possible, but it will also be full of exciting, interactive (and possibly dangerous ;) ) demos!\n\n- id: \"christophe-philemotte-rubykaigi-2015\"\n  title: \"Prepare yourself against Zombie epidemic\"\n  raw_title: \"Prepare yourself against Zombie epidemic - RubyKaigi 2015\"\n  speakers:\n    - Christophe Philemotte\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"erx00WTzvcY\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/toch\n\n    The news is everywhere: some weird disease makes the dead walking. We do not know yet if it is highly contagious. What should we do? What we do everyday: writing code.\n\n    This couldn't be a better moment to use an agent based model — a technique that simulates interactions between agents in a environment to understand their effects as a whole. For such, we'll visit its minimal Ruby implementation, address some common design, simulate the Zombie epidemic, visualize it, and test different survival strategies to hopefully find the best one.\n\n    We can code, we'll be prepared ... or not.\n\n- id: \"mayumi-emori-rubykaigi-2015\"\n  title: \"Discussion on Thread between version 1.8.6 and 2.2.3\"\n  raw_title: \"Discussion on Thread between version 1.8.6 and 2.2.3 - RubyKaigi 2015\"\n  speakers:\n    - Mayumi EMORI\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-01-01\"\n  video_provider: \"youtube\"\n  video_id: \"9C98Eyr9jOY\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/emorima\n\n    Thread in Ruby 1.8.6 often got stuck and I had to implement my own Thread monitoring framework. How is it improved in the latest release, Ruby 2.2.3? Now can we use an implementation that I couldn't use with 1.8.6 because of the broken Thread?\n\n    Ruby1.8.6 のThreadはよく刺さり、自前でのThread監視機能を作成を余儀なくされた。では、最新のRuby2.2.3ではどうだろうか？\n    またRuby1.8.6では、Threadが高確率で刺さるために回避せざるを得なかった、あの実装方法は、Ruby2.2.3では使えるのだろうか？\n\n- id: \"satoshi-moris-tagomori-rubykaigi-2015\"\n  title: \"Data Analytics Service Company and Its Ruby Usage\"\n  raw_title: \"Data Analytics Service Company and Its Ruby Usage - RubyKaigi 2015\"\n  speakers:\n    - Satoshi \"moris\" Tagomori\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-25\"\n  video_provider: \"youtube\"\n  video_id: \"6qrdqLlgTo8\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/tagomoris\n\n    This talk describes the architecture of data analytics platform service of Treasure Data, what we use Ruby/JRuby for and what we don't use Ruby for. We will discuss the many reasons, not only for productivity and performance.\n\n    Data analytics platform architecture is very far from well-known web service architecture. There are huge scale queues, workers, schedulers and distributed processing clusters, besides well-known parts like web application servers written in RoR and RDBMSs.\n\n- id: \"masatoshi-seki-rubykaigi-2015\"\n  title: \"Actor, Thread and me\"\n  raw_title: \"Actor, Thread and me - RubyKaigi 2015\"\n  speakers:\n    - Masatoshi SEKI\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"EdB-s2GX-68\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/seki\n\n    Everybody says. Actor helps to solve the multithreading problem. Actor is awesome. Threads are 💩\n\n    Really?\n\n    An actor model is \"just a model\", just like MVC.\n\n    Today, Recap what Actor Model is.\n\n- id: \"charles-nutter-rubykaigi-2015\"\n  title: \"Upcoming Improvements to JRuby 9000\"\n  raw_title: \"Upcoming Improvements to JRuby 9000 - RubyKaigi 2015\"\n  speakers:\n    - Charles Nutter\n    - Thomas E Enebo\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"QAqjtdExtJw\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/headius_enebo\n\n    JRuby 9000 is here! After years of work, JRuby now supports Ruby 2.2 and ships with a redesigned optimizing runtime. The first update release improved performance and compatibility, and we've only just begun. In this talk we'll show you where we stand today and cover upcoming work that will keep JRuby moving forward: profiling, inlining, unboxing...oh my!\n\n- id: \"keiju-ishitsuka-rubykaigi-2015\"\n  title: \"Usage and implementation of Reish which is an Unix shell for Rubyist\"\n  raw_title: \"Usage and implementation of Reish which is an Unix shell for Rubyist - RubyKaigi 2015\"\n  speakers:\n    - Keiju Ishitsuka\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2016-08-30\"\n  video_provider: \"youtube\"\n  video_id: \"xiAyp97ElA8\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/keiju\n\n    Reish is an Unix shell for Rubyist. It was a language that was realized Ruby in the syntax of the shell. I will introduce usage and implementation of Reish.\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2015\"\n  title: \"Keynote: Ruby 3 challenges\"\n  raw_title: \"Ruby3 challenges - RubyKaigi 2015 Keynote\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2015\"\n  date: \"2015-12-11\"\n  published_at: \"2015-12-20\"\n  video_provider: \"youtube\"\n  video_id: \"E9bO1uqs4Oc\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2015/presentations/matz\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2016/event.yml",
    "content": "---\nid: \"PLbFmgWm555yYfT493G8C2fLvvhPDs-lIQ\"\ntitle: \"RubyKaigi 2016\"\nkind: \"conference\"\nlocation: \"Kyoto, Japan\"\ndescription: \"\"\npublished_at: \"2016-09-14\"\nstart_date: \"2016-09-08\"\nend_date: \"2016-09-10\"\nchannel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\nyear: 2016\nbanner_background: \"#C22700\"\nfeatured_background: \"#C22700\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubykaigi.org/2016/\"\ncoordinates:\n  latitude: 35.011564\n  longitude: 135.7681489\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2016/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"petr-chalupa-rubykaigi-2016\"\n  title: \"Who reordered my code?!\"\n  raw_title: \"[EN] Who reordered my code?! / Petr Chalupa\"\n  speakers:\n    - Petr Chalupa\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"3FS1xnCEMq0\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/pitr_ch.html\n\n    There is a hidden problem waiting as Ruby becomes 3x faster and starts to support parallel computation - reordering by JIT compilers and CPUs.\n    In this talk, we’ll start by trying to optimize a few simple Ruby snippets. We’ll play the role of a JIT and a CPU and order operations as the rules of the system allow. Then we add a second thread to the snippets and watch it as it breaks horribly.\n    In the second part, we’ll fix the unwanted reorderings by introducing a memory model to Ruby. We’ll discuss in detail how it fixes the snippets and how it can be used to write faster code for parallel execution.\n\n    Petr Chalupa / @pitr_ch\n    He is a core maintainer of concurrent-ruby, where he has contributed concurrent abstractions and a synchronisation layer, providing volatile and atomic instance variables. He is part of the team working on JRuby+Truffle Ruby implementation at Oracle Labs. He is a happy Ruby user for 10 years.\n\n- id: \"kevin-menard-rubykaigi-2016\"\n  title: \"A Tale of Two String Representations\"\n  raw_title: \"[EN] A Tale of Two String Representations / Kevin Menard\"\n  speakers:\n    - Kevin Menard\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"UQnxukip368\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/nirvdrum.html\n\n    Strings are used pervasively in Ruby. If we can make them faster, we can make many apps faster.\n    In this talk, I will be introducing ropes: an immutable tree-based data structure for implementing strings. While an old idea, ropes provide a new way of looking at string performance and mutability in Ruby. I will describe how we replaced a byte array-oriented string representation with a rope-based one in JRuby+Truffle. Then we’ll look at how moving to ropes affects common string operations, its immediate performance impact, and how ropes can have cascading performance implications for apps.\n\n    Kevin Menard @nirvdrum\n    Kevin is a researcher at Oracle Labs where he works as part of a team developing a high performance Ruby implementation in conjunction with the JRuby team. He’s been involved with the Ruby community since 2008 and has been doing open source in some capacity since 1999. In his spare time he’s a father of two and enjoys playing drums.\n\n- id: \"martin-j-drst-rubykaigi-2016\"\n  title: \"Ups and Downs of Ruby Internationalization\"\n  raw_title: \"[EN] Ups and Downs of Ruby Internationalization / Martin J. Dürst\"\n  speakers:\n    - Martin J. Dürst\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"vfJp4mkf0EQ\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/duerst.html\n\n    Currently many of Ruby's String methods, such as upcase and downcase, are limited to ASCII and ignore the rest of the world. This is finally going to change in Ruby 2.4, where this functionality will be extended to cover full Unicode. You will get to know what will change, how your programs may be affected, and how these changes are implemented behind the scenes. We will also look at the overall state of internationalization functionality in Ruby, and potential future directions.\n\n    Martin J. Dürst @duerst\n    Martin is a Professor of Computer Science at Aoyama Gakuin University in Japan. He has been one of the main drivers of Internationalization (I18N) and the use of Unicode on the Web and the Internet. He published the first proposals for DNS I18N and NFC character normalization, and is the main author of the W3C Character Model and the IRI specification (RFC 3987). Since 2007, he and his students have contributed to the implementation of Ruby, mostly in the area of I18N.\n\n- id: \"masatoshi-seki-rubykaigi-2016\"\n  title: \"dRuby in the last century.\"\n  raw_title: \"[JA] dRuby in the last century. / Masatoshi SEKI\"\n  speakers:\n    - Masatoshi SEKI\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"Z7wTY3xZ7G0\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/m_seki.html\n\n    My first dRuby talk was in 2000, here in Kyoto. After the talk, I got many opportunities to write books and to talk on various topics including OSS, XP, and software testing. So, I'm glad to talk again here this year.\n\n    Nowadays, concurrent processing has become more familiar with many people as one of their solutions. It's time for us to begin understanding dRuby.\n\n    In this talk, I will introduce dRuby, sometimes called an OOPArt, to all generations of Rubyists.\n    私の最初のdRubyの講演は、2000年、この会場でした。\n\n    この講演以降、本の出版や絶版、Rubyだけでなく様々なテーマ（OSSやXP、software testingなど）で講演する機会を得ました。\n\n    2016年、再び同じ場所で話せることに喜んでいます。\n    並行処理は多くの人たちの解決策として身近に考えられるようになってきました。\n\n    いまこそdRubyを理解する環境が整ってきたと思います。\n\n    本講演では、再びdRubyを紹介します。\n    全ての世代のRubyistのみなさんに、20世紀のオーパーツと呼ばれている dRubyをお届けします。\n    \\\n    Masatoshi SEKI @m_seki\n    Masatoshi Seki is a Ruby committer and the author of several Ruby standard libraries including dRuby, ERB, and Rinda. He’s an expert in object-oriented programming, distributed systems, and eXtreme programming. He has been speaking at RubyKaigi every year since 2006 when the Kaigi first started.\n\n- id: \"koichi-sasada-rubykaigi-2016\"\n  title: \"A proposal of new concurrency model for Ruby 3\"\n  raw_title: \"[EN] A proposal of new concurrency model for Ruby 3 / Koichi Sasada\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"WIrYh14H9kA\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/ko1.html\n\n    A proposal of new concurrency model for Ruby 3\n    This presentation proposes a new concurrency model to support parallel execution for Ruby 3.\n\n    Now, Ruby has \"Thread\" to support concurrency.\n\n    However, making thread-safe programs is very hard because we need to manage all of the concurrent object mutations.\n\n    To overcome such difficulty, we propose a new concurrency model that enables parallel execution.\n\n    This presentation shows the following topics.\n    (1) Why is thread programming difficult?\n\n    (2) New concurrent model proposal and why is this model easy?\n\n    (3) Current design and implementation of this idea.\n\n    Koichi Sasada/ @ko1\n    Koichi Sasada is a programmer, mainly developing Ruby interpreter (CRuby/MRI). He received Ph.D (Information Science and Technology) from the University of Tokyo, 2007. He became a faculty of University of Tokyo (Assistant associate 2006-2008, Assistant professor 2008-2012). After the 13 years life in university, now, he is a member of Matz's team in Heroku, Inc. He is also a director of Ruby Association.\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2016\"\n  title: \"Keynote: Ruby 3 Typing\"\n  raw_title: '[JA][Keynote] Ruby3 Typing / Yukihiro \"Matz\" Matsumoto'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"2Ag8l-wq5qk\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/yukihiro_matz.html\n\n    Static typing is very popular among recent languages, e.g. TypeScript, Flow, Go, Swift, etc. Even Python has introduced type annotation. How about Ruby?\n\n    Can Ruby statically typed? Has dynamic typing become obsolete?\n    I will show you the answer. You will see the future of the type system in Ruby3.\n\n    Yukihiro \"Matz\" Matsumoto @yukihiro_matz\n    The Creator of Ruby\n\n- id: \"tanaka-akira-rubykaigi-2016\"\n  title: \"Unifying Fixnum and Bignum into Integer\"\n  raw_title: \"[JA] Unifying Fixnum and Bignum into Integer / Tanaka Akira\"\n  speakers:\n    - Tanaka Akira\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"-k_ZhC5Lkgg\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/tanaka_akr.html\n\n    Ruby has three classes to represent integers: Fixnum, Bignum and Integer. \n    Integer is the abstract super class of Fixnum and Bignum. \n    Fixnum represents small integers that fit in a word. \n    Bignum can represent any integers until the memory is full. \n    The exact range of Fixnum varies depending on the machine architecture and Ruby implementation. \n    Since Fixnum and Bignum are implementation details, \n    applications which depend on the Fixnum range is not portable at least, and just wrong in most cases. \n    We'll unify Fixnum and Bignum into Integer for Ruby 2.4. \n    This makes Ruby programs a bit more portable. \n    Also, hiding the implementation detail makes Ruby easier for beginners to learn.\n\n    Tanaka Akira @tanaka_akr\n    Ruby committer, Researcher of National Institute of Advanced Industrial Science and Technology (AIST)\n\n- id: \"kouhei-sutou-rubykaigi-2016\"\n  title: \"How to create bindings 2016\"\n  raw_title: \"[JA] How to create bindings 2016 / Kouhei Sutou\"\n  speakers:\n    - Kouhei Sutou\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"Iw0ha41Ty6I\"\n  language: \"Japanese\"\n  description: |-\n    How to create bindings 2016\n    This talk describes how to create Ruby bindings of a C library. I want to increase Ruby bindings developers. If you're interested in using C libraries from Ruby and/or using Ruby more cases, this talk will help you.\n    This talk includes the following topics:\n    * List of methods to create Ruby bindings of a C library.\n    * Small example of each method.\n    * Pros and cons of each method.\n\n    Kouhei Sutou @ktou\n    He is a free software programmer and the president of ClearCode Inc. He is also the namer of ClearCode Inc. The origin of the company name is \"clear code\". We will be programmers that code clear code as our company name suggests. He is interested in how to tell other programmers about how he codes clear code.\n\n- id: \"kirk-haines-rubykaigi-2016\"\n  title: \"Web Server Concurrency Architecture\"\n  raw_title: \"[EN] Web Server Concurrency Architecture / Kirk Haines\"\n  speakers:\n    - Kirk Haines\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"4FsZfcv28ig\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/wyhaines.html\n\n    Ruby has many different web server options, covering a gamut of possible concurrency architectures. We will look at what those concurrency options are, and at what their respective theoretical costs and benefits are.\n    We will then look at a reference ruby web server implementation that can have each of these different concurrency architectures plugged into it, and examine how its performance under load varies with each of those architectures.\n    We'll wrap it all up with a summary of the results, and a look at which Ruby web servers fall into which categories of concurrency architecture.\n\n    Kirk Haines, @wyhaines\n    I started using Ruby back in the Ruby 1.6 days, and I have used it in my daily professional life ever since. I'm fascinated by issues of application design, distributed architecture, and making hard things easy. I was also the last Ruby 1.8.6 maintainer. For entertainment, I read studies on exercise and nutrition physiology, and I like to run and bicycle long distances. This year will include my first 50k and 50m running races, and at least one 75 mile gravel bike race.\n\n- id: \"justin-searls-rubykaigi-2016\"\n  title: \"Fearlessly Refactoring Legacy Ruby\"\n  raw_title: \"[EN] Fearlessly Refactoring Legacy Ruby / Justin Searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"lQvDd9GPSB4\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/searls.html\n\n    Until recently, we didn't talk much about \"legacy Ruby\". But today, so many companies rely on Ruby that legacy code is inevitable.\n    When code is hard-to-understand, we fear our changes may silently break something. This fear erodes the courage to improve code's design, making future change even harder.\n    If we combine proven refactoring techniques with Ruby's flexibility, we can safely add features while gradually improving our design. This talk will draw on code analysis, testing, and object-oriented design to equip attendees with a process for refactoring legacy code without fear.\n\n    Justin Searls @searls\n    Nobody knows bad code like Justin Searls—he writes bad code effortlessly. And it's given him the chance to study why the industry has gotten so good at making bad software. He co-founded Test Double, an agency focused on fixing what's broken in software.\n\n- id: \"sameer-deshmukh-rubykaigi-2016\"\n  title: \"Data Analysis in RUby with daru\"\n  raw_title: \"[EN] Data Analysis in RUby with daru / Sameer Deshmukh\"\n  speakers:\n    - Sameer Deshmukh\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"ZLBGyACJJS4\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/v0dro.html\n\n    Easy and fast analysis of data is an uphill task for any Rubyist today. Ruby has been mostly restricted to web development and scripting, until now. In this talk we will have a look at daru, a gem from the Ruby Science Foundation specifically developed for simplifying data analysis tasks for Rubyists.\n    You will learn how you can use daru for analyzing large data sets and get a tour of daru being coupled with other Ruby tools like pry, iruby and nyaplot for interactive and standalone data analysis and plotting for gaining quick insights into your data — all with a few lines of Ruby code.\n\n    Sameer Deshmukh, @v0dro\n    Sameer is a student and a contributor to the Ruby Science Foundation, where he helps build scientific computation tools in Ruby. He is currently maintaining daru, a library for data analysis and manipulation in Ruby. He enjoys spending spare time with friends, books and his bass guitar.\n\n- id: \"masahiro-tanaka-rubykaigi-2016\"\n  title: \"Pwrake: Distributed Workflow Engine based on Rake\"\n  raw_title: \"[JA] Pwrake: Distributed Workflow Engine based on Rake / Masahiro TANAKA\"\n  speakers:\n    - Masahiro TANAKA\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"a4kMUrETrLk\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/masa16tanaka.html\n\n    Pwrake: Distributed Workflow Engine based on Rake\n    Pwrake aims at the high-performance parallel execution of data-intensive scientific workflows using multi-node clusters with 10,000 cores. In the design of Pwrake, I made use of existing powerful tools. First, Pwrake is implemented as an extension to Rake. In this talk, I show that Rake is so powerful that it enables portable definition of workflow DAGs comprised of many tasks. Second, Pwrake has an option to make use of Gfarm distributed file system for high-performance parallel file I/O. Also, I will talk about other studies on Pwrake such as locality-aware task scheduling.\n\n    Masahiro TANAKA, @masa16tanaka\n    Research Fellow at CCS, University of Tsukuba. The author of NArray, a numerical library for Ruby.\n\n- id: \"aja-hammerly-rubykaigi-2016\"\n  title: \"Exploring Big Data with rubygems.org Download Data\"\n  raw_title: \"[EN] Exploring Big Data with rubygems.org Download Data / Aja Hammerly\"\n  speakers:\n    - Aja Hammerly\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  slides_url: \"https://thagomizer.com/files/ruby_kaigi_2016.pdf\"\n  video_provider: \"youtube\"\n  video_id: \"kLzkkL_V2Ts\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/the_thagomizer.html\n\n    Many people strive to be armchair data scientists. Google BigQuery provides an easy way for anyone with basic SQL knowledge to dig into large data sets and just explore. Using the rubygems.org download data we'll see how the Ruby and SQL you already know can help you parse, upload, and analyze multiple gigabytes of data quickly and easily without any previous Big Data experience.\n\n    Aja Hammerly, @the_thagomizer\n    Aja lives in Seattle where she is a developer advocate at Google and a member of the Seattle Ruby Brigade. Her favorite languages are Ruby and Prolog. She also loves working with large piles of data. In her free time she enjoys skiing, cooking, knitting, and long coding sessions on the beach.\n\n- id: \"kenta-murata-rubykaigi-2016\"\n  title: \"SciRuby Machine Learning Current Status and Future\"\n  raw_title: \"[JA] SciRuby Machine Learning Current Status and Future / Kenta Murata\"\n  speakers:\n    - Kenta Murata\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"gfQ8XEy7vO4\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/mrkn.html\n\n    How do we do machine-learning things by using Ruby?\n    In this talk, I will show you the current status of SciRuby by comparing it with other language stacks such as the SciPy stack on Python.\n\n    Kenta Murata, @mrkn\n    A Ruby committer. A BigDecimal maintainer.\n\n- id: \"matthew-gaudet-rubykaigi-2016\"\n  title: \"Ruby3x3: How are we going to measure 3x?\"\n  raw_title: \"[EN] Ruby3x3: How are we going to measure 3x? / Matthew Gaudet\"\n  speakers:\n    - Matthew Gaudet\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"kJDOpucaUR4\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/MattStudies.html\n\n    To hit Ruby3x3, we must first figure out **what** we're going to measure, **how** we're going to measure it, in order to get what we actually want. I'll cover some standard definitions of benchmarking in dynamic languages, as well as the tradeoffs that must be made when benchmarking. I'll look at some of the possible benchmarks that could be considered for Ruby 3x3, and evaluate them for what they're good for measuring, and what they're less good for measuring, in order to help the Ruby community decide what the 3x goal is going to be measured against.\n\n    Matthew Gaudet, @MattStudies\n    A developer at IBM Toronto on the OMR project, Matthew Gaudet is focused on helping to Open Source IBM's JIT technology, with the goal of making it usable by many language implementations.\n\n- id: \"yurie-yamane-rubykaigi-2016\"\n  title: \"High Tech Seat in mruby\"\n  raw_title: \"[JA] High Tech Seat in mruby / Yurie Yamane\"\n  speakers:\n    - Yurie Yamane\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"z93299YHVYI\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/yuri_at_earth.html\n\n    How do you write software for controlling home appliance such as High Tech Seat (a.k.a. Washlet) ?\n\n    When you write bad code, water may flood or may not be flushed...\n\n    Even after you write correct code, you might want to add some nice features like open and close the cover working with flusher. How do you verify the behavior of it?\n    State machine diagram is usually used to verify the behavior, especially for embedded systems.\n\n    In UML 2.x, nested states and orthogonal regions are supported to describe complex behaviors.\n\n    Through the diagrams, you can learn what is \"good\" design for controlling devices.\n\n    In addition, Ruby lets us convert the diagrams into executable code easily.\n\n    Let's try to implement High Tech Seat from state machine with mruby.\n\n    Yurie Yamane, @yuri_at_earth\n    \"nora\" mrubyist. A member of Team Yamanekko. A member of TOPPERS Project. A staff of ET robocon TOKYO.\n\n- id: \"franck-verrot-rubykaigi-2016\"\n  title: \"Hijacking syscalls with (m)ruby\"\n  raw_title: \"[EN] Hijacking syscalls with (m)ruby / Franck Verrot\"\n  speakers:\n    - Franck Verrot\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"zRoiX0BES0s\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/franckverrot.html\n\n    mruby's unique packaging strategy gives developers the possibility to inject Ruby code in any program, written in any language.\n    In this talk we'll discover how a mruby application can be distributed, how one could replace OS system calls with custom Ruby apps, and real-world usages of this technique.\n\n    Franck Verrot, @franckverrot\n    Franck is a software engineer. He specializes in Ruby and JavaScript, with a focus on performance.\n\n- id: \"urabe-shyouhei-rubykaigi-2016\"\n  title: \"Optimizing Ruby\"\n  raw_title: \"[JA] Optimizing Ruby / Urabe, Shyouhei\"\n  speakers:\n    - Shyouhei Urabe\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"spxcAHidm5o\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/shyouhei.html\n\n    I made ruby 10x faster. Let me show you how.\n\n    Urabe, Shyouhei, @shyouhei\n    Money Forward, Inc. hire Shyouhei, a long-time ruby-core committer, to contribute to the whole ruby ecosystem. Being a full-time ruby-core developer, his current interest is to speed up ruby execution by modifying its internals. Doing so is not straight-forward because of ruby's highly dynamic nature. To tackle this problem he is implementing a deoptimization engine onto ruby, which enables lots of optimization techniques that are yet to be applied to it.\n\n- id: \"julian-cheal-rubykaigi-2016\"\n  title: \"It's More Fun to Compute\"\n  raw_title: \"[EN] It's More Fun to Compute / Julian Cheal\"\n  speakers:\n    - Julian Cheal\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"z7So-iCJSUY\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/juliancheal.html\n\n    Come with us now on a journey through time and space. As we explore the world of analog/digital synthesis. From computer generated music to physical synthesisers and everything in between.\n    So you want to write music with code, but don’t know the difference between an LFO, ADSR, LMFAO, etc. Or a Sine wave, Saw wave, Google wave. We’ll explore what these mean, and how Ruby can be used to make awesome sounds. Ever wondered what Fizz Buzz sounds like, or which sounds better bubble sort or quick sort? So hey Ruby, let’s make music!\n\n    Julian Cheal, @juliancheal\n    A British Ruby/Rails developer, with a penchant for tweed, fine coffee, and homebrewing. When not deploying enterprise clouds, I help organise fun events around the world that teach people to program flying robots. I also occasionally speak at international conferences on the intersection of programming and robotics.\n\n- id: \"naruse-yui-rubykaigi-2016\"\n  title: \"[JA Keynote] Dive into CRuby\"\n  raw_title: \"[JA Keynote] Dive into CRuby / NARUSE, Yui\"\n  speakers:\n    - NARUSE Yui\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"iMtpCes8VqU\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/nalsh.html\n\n    People sometimes want to involve CRuby development, but won't. I guess it's because they couldn't embody the motivation and don't know how to work about it.\n\n    I explain how to find an entry point, write code, make matz merge it.\n\n    NARUSE, Yui / @nalsh\n    Ruby committer, nkf maintainer, working at Treasure Data Inc.\n\n- id: \"takashi-kokubun-rubykaigi-2016\"\n  title: \"Scalable job queue system built with Docker\"\n  raw_title: \"[JA] Scalable job queue system built with Docker / Takashi Kokubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"MO2Zs0q6T9Y\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/k0kubun.html\n\n    While job queue system has been indispensable to execute a task asynchronously for a long time, we have some problems in typical job queue systems built with Ruby. Have you ever suffered from job queue system's availability, scalability or operation cost? Don't you want to implement a job with another language which is suitable for the job?\n    We built a new job queue system using Docker this year. In this talk, you'll know how these problems can be solved with the system constructed with Ruby.\n\n    Takashi Kokubun, @k0kubun\n    A software engineer working to improve developer's productivity at Cookpad Inc.\n\n- id: \"toru-kawamura-rubykaigi-2016\"\n  title: \"Web Clients for Ruby and What they should be in the future\"\n  raw_title: \"[JA] Web Clients for Ruby and What they should be in the future / Toru Kawamura\"\n  speakers:\n    - Toru Kawamura\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"DeK6EDzEMI0\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/tkawa.html\n\n    REST and Hypermedia Web APIs such as Amazon Web Services are getting more common every day. Of course it is also common to integrate those APIs into Ruby app. There are so many HTTP clients we use for integration written in Ruby but all of them lack the feature \"state management\" for taking advantage of Web APIs.\n    I implemented the feature on Faraday, a typical HTTP client in Ruby. I'll show you the key point and the usefulness of the implementation.\n\n    Toru Kawamura, @tkawa\n    RESTafarian, freelance programmer, technology assistance partner at SonicGarden Inc., co-organizer of Sendagaya.rb (regional rubyist meetup), and facilitator of RESTful-towa (“What is RESTful”) Workshop\n\n- id: \"lin-yu-hsiang-rubykaigi-2016\"\n  title: \"ErRuby: Ruby on Erlang/OTP\"\n  raw_title: \"[EN] ErRuby: Ruby on Erlang/OTP / Lin Yu Hsiang\"\n  speakers:\n    - Lin Yu Hsiang\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"Yl7F3wyEMlQ\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/johnlinvc.html\n\n    Concurrency will be an important feature for future Ruby, and Erlang programming language is famous for its concurrency features such as Actor model, Lightweight process and ability to build fault tolerant distributed systems such as the telecom.\n\n    ErRuby, an Ruby interpreter on Erlang/OTP, tries to bring Ruby to the concurrent world. ErRuby use Actor and process to create an Object-Oriented realm in immutable Erlang universe. I'll talk about how to implement key Ruby features in a functional way and demonstrate experimental concurrency features of ErRuby.\n\n    ErRuby is at github.com/johnlinvc/erruby\n\n- id: \"thomas-e-enebo-rubykaigi-2016\"\n  title: \"JRuby 9000 Last Year, Today, and Tomorrow\"\n  raw_title: \"[EN] JRuby 9000 Last Year, Today, and Tomorrow / Thomas E Enebo\"\n  speakers:\n    - Thomas E Enebo\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"vAEFVQQwo1c\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/tom_enebo.html\n\n    JRuby 9000 was released over a year ago after a lengthy set of pre-releases. Our most significant major release in nearly 10 years. New runtime. Native IO subsystem. Complete port of C Ruby's transcoding facilities. How did things go? Is the new runtime faster? Did it enable more aggressive optimizations? Does it help aid debugging in development? This talk will discuss lessons learned and where we are focused for upcoming improvements.\n\n    Thomas E Enebo, @tom_enebo\n    Thomas Enebo co-leads the JRuby project. He has been passionately working on JRuby for many years. When not working on JRuby, he is writing Ruby applications, playing with Java, and enjoying a decent beer.\n\n- id: \"ruby-committers-rubykaigi-2016\"\n  title: \"Ruby Committers vs the World\"\n  raw_title: \"Ruby Committers vs the World\"\n  speakers:\n    - Ruby Committers # TODO: list each person\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"gcqbvLHNPTM\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/cruby_committers.html\n\n- id: \"ritta-narita-rubykaigi-2016\"\n  title: \"How to create multiprocess server on Windows with Ruby\"\n  raw_title: \"[EN] How to create multiprocess server on Windows with Ruby / Ritta Narita\"\n  speakers:\n    - Ritta Narita\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"h3Vg6B-mg6o\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/narittan.html\n\n    Unicorn is the most used multiprocess server framework implemented in ruby. But it doesn't work on Windows unfortunately.\n\n    Serverengine is a robust multiprocess server implemented in ruby and it works on windows now. This is the first multiprocess server with ruby which can work on windows.\n    I'll talk about what only ruby can do and my original effort for realizing a robust multiprocess server for restricted environment.\n\n    And in the end, I'll introduce real demos on windows.\n\n    Ritta Narita, @narittan\n    Ritta graduated from university last September and now is working at Treasure Data.Inc. And he is maintainer of serverengine.\n\n- id: \"uchio-kondo-rubykaigi-2016\"\n  title: \"Welcome to haconiwa - the (m)Ruby on Container\"\n  raw_title: \"[EN] Welcome to haconiwa - the (m)Ruby on Container / Uchio KONDO\"\n  speakers:\n    - Uchio KONDO\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"ZKMC5uFlo9s\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/udzura.html\n\n    In the current tech scene, many developers use so-called Container-based virtualization such as Docker or LXC.\n\n    Uchio KONDO, @udzura\n    An 8 y.o. Rubyist, Hashicorp freak, DevOps enthusiast, system programming novice. One of the writers of books \"Perfect Ruby\" / \"Perfect Ruby on Rails\" (both in Japanese). He lives in Fukuoka - the \"coast\" city of \"west\" Japan, works at GMO Pepabo, Inc. as SRE/R&D/Dev Productivity Engineer, and holds Fukuoka.rb local meetup. He also is a organizer of RailsGirls Fukuoka #1.\n\n- id: \"mitsutaka-mimura-rubykaigi-2016\"\n  title: \"Learn Programming Essence from Ruby patches\"\n  raw_title: \"[JA] Learn Programming Essence from Ruby patches / Mitsutaka Mimura\"\n  speakers:\n    - Mitsutaka Mimura\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"ktuMYe-Q9SY\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/takkanm.html\n\n    Various patches are sent to Ruby. Those patches contain various ideas on programming.\n\n    In this session, I would like to discuss the knowledge underlying programming, such as the original algorithm and data structure patches of Ruby and some libraries.\n\n    Mitsutaka Mimura, @takkanm\n    member of Asakusa.rb, eiwa-system-management.\n\n- id: \"yoh-osaki-rubykaigi-2016\"\n  title: \"Isomorphic web programming in Ruby\"\n  raw_title: \"[JA] Isomorphic web programming in Ruby / Yoh Osaki\"\n  speakers:\n    - Yoh Osaki\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-20\"\n  video_provider: \"youtube\"\n  video_id: \"gKDs4V5D_k0\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/youchan.html\n\n    Last year at RubyKaigi, I introduced Hyalite, a virtual DOM implemented in Ruby. \n    Hyalite allows Rubyists to write front and back-end code in Ruby, an approach that has proven to provide many benefits. Using a single language across an application stack is sometimes referred to as isomorphic programming. \n    This talk introduces a new framework for isomorphic programming with the Opal: Menilite. \n    Menilite shares model code between the server side and the client side by marshalling objects and storing them in the database automatically. \n    As a result, code duplication is reduced and APIs are no longer a necessity. \n    Isomorphic programming can significantly accelerate your progress on a project; I sincerely hope you find it helpful in developing web applications. \n    Menilite aims to expand the playing field for the Ruby language, a language optimized for developer happiness. I'm sure you will agree that we will find even more happiness by bringing Ruby to the front-end as well.\n\n    Yoh Osaki, @youchan\n    Software engineer at Ubiregi inc. Author of Hyalite which is react like virtual DOM library. Member of Asakusa.rb, Chidoriashi.rb\n\n- id: \"kazuho-oku-rubykaigi-2016\"\n  title: \"Recent Advances in HTTP and Controlling them using ruby\"\n  raw_title: \"[JA] Recent Advances in HTTP and Controlling them using ruby / Kazuho Oku\"\n  speakers:\n    - Kazuho Oku\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"_YroMCap4y8\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/kazuho.html\n\n    Configuration of a web server is becoming more and more complex, as technologies such as OAuth, Client Hints, HTTP/2 push become standardized.\n    This talk introduces the recent advances in HTTP and related technology, as well as explaining how they can be configured and maintained by writing ruby code based on the Rack interface.\n\n    Kazuho Oku, @kazuho\n\n- id: \"satoshi-moris-tagomori-rubykaigi-2016\"\n  title: \"Modern Black Mages Fighting in the Real World\"\n  raw_title: '[JA] Modern Black Mages Fighting in the Real World / Satoshi \"moris\" Tagomori'\n  speakers:\n    - Satoshi \"moris\" Tagomori\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"fXbVT_Afzsw\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/tagomoris.html\n\n    Fluentd v0.14, which has drastically updated Plugin APIs, also has a layer to provide compatibility for old-fashioned plugins to support them and huge amount of existing configuration files in user environments.\n\n    It was far from easy, and developers had to do everything possible, including any kind of black magics.\n    This talk will show some stories with code and commits of a software used in real world:\n    * How to provide compatibility between different APIs\n    * How to provide required methods on existing objects\n    * How to make sure to call super for existing methods without super\n\n    Satoshi \"moris\" Tagomori, @tagomoris\n    OSS developer/maintainer: Fluentd, Norikra, MessagePack-Ruby, Woothee and many others mainly about Web services, data collecting and distributed/streaming data processing. Living in Tokyo, and day job is for Treasure Data.\n\n- id: \"elct9620-rubykaigi-2016\"\n  title: \"Play with GLSL on OpenFrameworks\"\n  raw_title: \"[EN] Play with GLSL on OpenFrameworks\"\n  speakers:\n    - elct9620\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"C2t05Y3dOFQ\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/elct9620.html\n\n    Learning GLSL (OpenGL Shader Language) is a little harder to me, but if I can create shader like Unreal Engine 4's material design tool? Let's play with Shader on OpenFrameworks.\n    I using mruby and OpenFrameworks to create a scriptable GLSL generator to create shader. By the power of Ruby DSL, the shader generate becomes very fun and simplely.\n\n    蒼時弦也, @elct9620\n    A Web Developer focus on Interaction Design, and love Game, Animation and Comic. Current working on develop game and website.\n\n- id: \"shibata-hiroshi-rubykaigi-2016\"\n  title: \"How DSL works on Ruby\"\n  raw_title: \"[JA] How DSL works on Ruby / SHIBATA Hiroshi\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"JwjwnPTt_k8\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/hsbt.html\n\n    Domain-Specific Language(DSL) is a useful tool for communication between programmers and businesses. One of the greatest present from Ruby to programmers is to allow them to develop DSL easily. Ruby has a variety of functionalities for DSL making.\n    I started to maintain Rake last year. I found interesting techniques in Rake and felt different things on other popular DSLs like rspec examples, rails routes, and thor tasks etc. And I found patterns of code for DSL with Ruby.\n    I’m going to try to improve Rake 12 using these patterns. So I will describe these patterns of code for DSL with Ruby and talk on the future of Rake 12.\n\n    SHIBATA Hiroshi, @hsbt\n    Ruby Committer, Chief Engineer at GMO Pepabo, Inc.\n\n- id: \"colby-swandale-rubykaigi-2016\"\n  title: \"Writing A Gameboy Emulator in Ruby\"\n  raw_title: \"[EN] Writing A Gameboy Emulator in Ruby / Colby Swandale\"\n  speakers:\n    - Colby Swandale\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"_mHdUhVQOb8\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/0xColby.html\n\n    Released in 1989 the Gameboy was the first handheld console of the Gameboy series to be released by Nintendo. It featured games such as Pokemon Red & Blue, Tetris, Super Mario Land and went on to sell 64 million units worldwide.\n    My talk will be discussing what components make up a Gameboy, such as the CPU, RAM, Graphics and Game Cartridge. How each component works individually and how they work together to let trainers catch em all. Then how to replicate the behavior of the Gameboy in code to eventually make an emulator.\n\n    Colby Swandale, @0xColby\n    Working in Melbourne at Marketplacer. I enjoy working on Ruby on Rails projects, low level computing and encryption.\n\n- id: \"eric-hodel-rubykaigi-2016\"\n  title: \"Building maintainable command-line tools with mruby\"\n  raw_title: \"[EN] Building maintainable command-line tools with mruby / Eric Hodel\"\n  speakers:\n    - Eric Hodel\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"u6SB-Alat9E\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/drbrain.html\n\n    mruby and mruby-cli makes it possible to ship single binary command-line tools that can be used without setup effort. How can we make these easy to write too?\n    Existing libraries for making command-line tools are built for experienced rubyists. This makes them a poor choice for porting to mruby.\n    In this talk we'll explore how to build a command-line tool with mruby-cli along with a design and philosophy that makes it easy to create new commands and maintain existing commands even for unfamiliar developers.\n\n    Eric Hodel, @drbrain\n    Eric Hodel is a ruby committer and maintainer of many gems. He works at Fastly on the API features team maintaining and building ruby services that customers use to configure their CDN services.\n\n- id: \"anil-wadghule-rubykaigi-2016\"\n  title: \"Ruby Concurrency compared\"\n  raw_title: \"[EN] Ruby Concurrency compared / Anil Wadghule\"\n  speakers:\n    - Anil Wadghule\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"lbX-9mDUOIw\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/anildigital.html\n\n    Ruby is used everywhere now. In this talk we will compare Ruby concurrency with Node.js, JVM, Erlang and others.\n    Ruby supports concurrency but with GIL, it can't run threads parallely. We will explore options available that makes this problem irrelevant.\n    Node.js doesn’t support concurrency or parallelism. Node.js is single threaded. It runs an event loop which makes non blocking IO possible. We will explore why Node.js fits well to only certain types of problems only\n    JVM supports native threads and can do parallelism. But in JVM memory is still shared among different objects. We will explore JVM architecture in regards with memory. Where JVM gets it wrong.\n    Erlang/Elixir achieves concurrency and parallelism with shared nothing, immutable data, first class processes, actor model. We will explore whether this approach is better for solving every kind of problem.\n    Talk will have deep comparison with all of these platforms in regards with what most real world project need,\n\n    Anil Wadghule, @anildigital\n    I am a geek but a senior software developer by profession, currently working for Equal Experts, India. When not programming, I spent time in exploring music around the world. Emacs is my text editor of choice. I love watching Japanese animes.\n\n- id: \"amir-rajan-rubykaigi-2016\"\n  title: \"Game Development + Ruby = Happiness\"\n  raw_title: \"[EN] Game Development + Ruby = Happiness / Amir Rajan\"\n  speakers:\n    - Amir Rajan\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"jfTM_0ezZuI\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/amirrajan.html\n\n    Amir Rajan (creator of the #1 iOS Game: A Dark Room), will speak about his journey to becoming a game developer using Ruby. He'll explore the source code for his games, showing how elegance in code becomes elegance on screen.\n\n    Amir Rajan, @amirrajan\n    Amir Rajan is a pretty decent dev and is constantly trying to improve in his craft. He’s a jack of all trades, being comfortable with a number of platforms and languages. Last but certainly not least, Amir is the creator of A Dark Room iOS. This RPG conquered the world and took the #1 spot in the App Store and placed in the top #10 paid apps across 70 countries. It has been downloaded over 2.5 millions times and is a staple game in the App Store with over 25,000 five star reviews.\n\n- id: \"chris-arcand-rubykaigi-2016\"\n  title: \"Deletion Driven Development: Code to delete code!\"\n  raw_title: \"[EN] Deletion Driven Development: Code to delete code!\"\n  speakers:\n    - Chris Arcand\n  event_name: \"RubyKaigi 2016\"\n  date: \"2016-09-08\"\n  published_at: \"2016-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"UlfyX8zRVc8\"\n  language: \"English\"\n  description: |-\n    http://rubykaigi.org/2016/presentations/chrisarcand.html\n\n    Good news! Ruby is a successful and mature programming language with a wealth of libraries and legacy applications that have been contributed to for many years. The bad news: Those projects might contain a large amount of useless, unused code which adds needless complexity and confuses new developers. In this talk I'll explain how to build a static analysis tool to help you clear out the cruft - because there's no code that's easier to maintain than no code at all!\n\n    Chris Arcand, @chrisarcand\n    Chris is a Ruby developer at Red Hat on the ManageIQ core team. He enjoys working full time on open source software to manage The Cloud™ and has contributed to various projects in the Ruby ecosystem. Chris hails from Minnesota in the United States and also enjoys hockey, hiking, and tasty beers.\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2017/event.yml",
    "content": "---\nid: \"PLbFmgWm555yaJalSEHY17E96ChjY-kF2D\"\ntitle: \"RubyKaigi 2017\"\nkind: \"conference\"\nlocation: \"Hiroshima, Japan\"\ndescription: |-\n  http://rubykaigi.org/2017/\n  Sep.18th-20th\n  International Conference Center Hiroshima, Hiroshima, Japan\npublished_at: \"2017-09-21\"\nstart_date: \"2017-09-18\"\nend_date: \"2017-09-20\"\nchannel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\nyear: 2017\nbanner_background: \"#FFF6EF\"\nfeatured_background: \"#FFF6EF\"\nfeatured_color: \"#5E5E5E\"\nwebsite: \"https://rubykaigi.org/2017/\"\ncoordinates:\n  latitude: 34.3852894\n  longitude: 132.4553055\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2017/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"shugo-maeda-rubykaigi-2017\"\n  title: \"Handling mails on a text editor\"\n  raw_title: \"[JA] Handling mails on a text editor / Shugo Maeda @shugomaeda\"\n  speakers:\n    - Shugo Maeda\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"pvSOWiVB-KA\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/shugomaeda.html\n\n    A text editor is perfect for mail handling because mails consist of text. Ruby is perfect for text editing because it's so powerful.\n\n    In this talk, I introduce Textbringer, a text editor written in Ruby, and Mournmail, a message user agent implemented as a plugin of Textbringer, and I tells the fun of text editing and mail handling.\n\n    I also talk about Law, Chaos, and the Cosmic Balance through the design and implementation of Textbringer and Mournmail.\n\n- id: \"nobuyoshi-nakada-rubykaigi-2017\"\n  title: \"Keynote: Making Ruby? ゆるふわRuby生活\"\n  raw_title: \"[JA][Keynote] Making Ruby? ゆるふわRuby生活 / Nobuyoshi Nakada @n0kada\"\n  speakers:\n    - Nobuyoshi Nakada\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"Bt-PvFLbMbU\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/n0kada.html\n\n- id: \"shibata-hiroshi-rubykaigi-2017\"\n  title: \"Gemification for Ruby 2.5/3.0\"\n  raw_title: \"[JA] Gemification for Ruby 2.5/3.0 /  SHIBATA Hiroshi @hsbt\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"VKm93Mwe__k\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/hsbt.html\n\n    Ruby have many libraries named standard library, extension and default gems, bundled gems. These are some differences under the bundler and rails application.\n\n    default gems and bundled gems are introduced to resolve dependency problem and development ecosystem around the ruby core. We have the plan to promote default/bundled gems from standard libraries. It says “Gemification” projects.\n\n    What Gemification changes in Ruby ecosystem? In this presentation, from the standpoint of the maintainer of the Ruby programming language, I will explain details of Gemification and its blocker things. Finally, I will also introduce the new features of Ruby 2.5 and 3.0.\n\n- id: \"shizuo-fujita-rubykaigi-2017\"\n  title: \"How to optimize Ruby internal.\"\n  raw_title: \"[JA] How to optimize Ruby internal. / Shizuo Fujita @watson1978\"\n  speakers:\n    - Shizuo Fujita\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"4VOEdd-BYHE\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/watson1978.html\n\n    \"Ruby 3\" has aimed to optimize performance which is one of goals to release. I have made some patches to optimize Ruby internal to realize it.\n\n    This talk describes how optimized Ruby internal at Ruby 2.5.\n\n- id: \"takafumi-onaka-rubykaigi-2017\"\n  title: \"API Development in 2017\"\n  raw_title: \"[JA] API Development in 2017 / Takafumi ONAKA @onk\"\n  speakers:\n    - Takafumi ONAKA\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"a28jJ62ZfZM\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/onk.html\n\n    Summarize \"How to develop API server efficiently.\"\n\n    This talk will talk while looking back on the history like\n\n    Why REST (RESTful API) was born?\n    The world has became to need Native client / Web front-end\n    API documentation tool are widely used\n    API Blueprint, Swagger, RAML, JSON Hyper-Schema\n    Schema driven development\n    API Query Language (GraphQL)'s birth\n    And I talk about the library concept and code that we implemented as necessary. There were many challenges such as how to communicate at the interface boundary, how to implement without any mistakes, etc.\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2017\"\n  title: \"Keynote: The Many Faces of Module\"\n  raw_title: '[JA][Keynote] The Many Faces of Module / Yukihiro \"Matz\" Matsumoto @yukihiro_matz'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-21\"\n  video_provider: \"youtube\"\n  video_id: \"OnDSm-GZCko\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/yukihiro_matz.html\n\n- id: \"vladimir-makarov-rubykaigi-2017\"\n  title: \"Keynote: Towards Ruby 3x3 performance\"\n  raw_title: \"[EN][Keynote] Towards Ruby 3x3 performance / Vladimir Makarov @vnmakarov\"\n  speakers:\n    - Vladimir Makarov\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-22\"\n  video_provider: \"youtube\"\n  video_id: \"qpZDw-p9yag\"\n  language: \"English\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/vnmakarov.html\n\n    Ruby 3x3 project has a very ambitious goal to improve MRI performance in 3 times in comparison with MRI version 2.0.\n\n    This talk is about my attempt to achieve this goal in a project to implement RTL VM instructions and JIT in MRI VM. The project can be found on https://github.com/vnmakarov/ruby.\n\n    We will talk about the project motivation, goals, and approaches, and the current state of the project. Performance comparison with JRuby, Graal/Truffle Ruby, and OMR Ruby and future directions of the project will be given too.\n  additional_resources:\n    - name: \"vnmakarov/ruby\"\n      type: \"repo\"\n      url: \"https://github.com/vnmakarov/ruby\"\n\n- id: \"martin-j-drst-rubykaigi-2017\"\n  title: \"Regular Expressions Inside Out\"\n  raw_title: \"[JA] Regular Expressions Inside Out / Martin J. Dürst @duerst\"\n  speakers:\n    - Martin J. Dürst\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"sUdZ8s4GbnE\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/duerst.html\n\n    Regular expressions are a very important part of the toolkit of every Ruby programmer. This talk will help improve your understanding of regular expressions, including how to use them from Ruby, and how they are implemented. Examples will include things Ruby can do but other programming languages can't, huge regular expressions, substitutions that change as we go, and performance improvements for future Ruby versions.\n\n- id: \"takuya-nishimoto-rubykaigi-2017\"\n  title: \"What visually impaired programmers are thinking about Ruby?\"\n  raw_title: \"[JA] What visually impaired programmers are thinking about Ruby? / Takuya Nishimoto @nishimotz\"\n  speakers:\n    - Takuya Nishimoto\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"O1coxtDTkwY\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/nishimotz.html\n\n    Computer programming is an important job opportunity for visually impaired people. Several colleges are educating Ruby programming to such students in Japan and overseas. This talk reveals the current situations of visually impaired Ruby programmers, especially in Japan, i.e. what they are developing, which tools or environments they are using, and whether they are satisfied or not regarding the Ruby language. Accessibility of documents, which are generated from Ruby sources via rdoc or yard, is one of the issue I found so far.\n\n- id: \"yasushi-itoh-rubykaigi-2017\"\n  title: \"Introducing the Jet Programming Language\"\n  raw_title: \"[JA] Introducing the Jet Programming Language / Yasushi Itoh @i2y_\"\n  speakers:\n    - Yasushi Itoh\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"SfF9va8NGhM\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/i2y_.html\n\n    Jet is similar to Ruby and run on Erlang VM. In this talk, I will mainly explain the specification and implementation.\n\n- id: \"kevin-newton-rubykaigi-2017\"\n  title: \"Compiling Ruby\"\n  raw_title: \"[EN] Compiling Ruby / Kevin Deisz @kddeisz\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"B3Uf-aHZwmw\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/kddeisz.html\n\n    Since Ruby 2.3 and the introduction of RubyVM::InstructionSequence::load_iseq, we've been able to programmatically load ruby bytecode. By divorcing the process of running YARV byte code from the process of compiling ruby code, we can take advantage of the strengths of the ruby virtual machine while simultaneously reaping the benefits of a compiler such as macros, type checking, and instruction sequence optimizations. This can make our ruby faster and more readable! This talk demonstrates how to integrate this into your own workflows and the exciting possibilities this enables.\n\n- id: \"mat-schaffer-rubykaigi-2017\"\n  title: \"Mapping your world with Ruby\"\n  raw_title: \"[EN] Mapping your world with Ruby / Mat Schaffer @matschaffer\"\n  speakers:\n    - Mat Schaffer\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"Qk3VSCDZITs\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/matschaffer.html\n\n    In the wake of the March 2011 earthquake, many noticed a lack of good environmental data regarding radiation. The Safecast project was born from that need and our Ruby-based infrastructure how is home to nearly 70 million data points.\n\n    In this talk we'll go over the basics of the project, what we've learned over the last 6 years of running a volunteer-based Ruby project, and our plans for future expansion into tracking both radiation and air quality data.\n\n- id: \"stan-lo-rubykaigi-2017\"\n  title: \"I quit my job to write my own language: Goby\"\n  raw_title: \"[EN] I quit my job to write my own language: Goby / Stan Lo @_st0012\"\n  speakers:\n    - Stan Lo\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"GRNlTWzoC74\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/_st0012.html\n\n    That day, for no particular reason, I decided to write my own language. So I followed a book and wrote the monkey. And when I wrote monkey, I thought maybe I'd create my own language. And when I created it, I thought maybe I'd just make it more like Ruby. And I figured, since I've spent so many time, maybe I'd just make it a VM-based language. And that's what I did. I wrote VM and compiler just like Ruby did in version 1.9. For no particular reason I just kept on going. I created file and http library. And when I made them, I figured, since I'd gone this far, I might as well add a web server. When I created the web server, I figured, since I'd gone this far, I might just quit my job and make it my own programming language: Goby\n\n    For leanring more about Goby, please also checkout our Gitbook (constantly updated!)\n\n- id: \"yutaka-hara-rubykaigi-2017\"\n  title: \"Ruby, Opal and WebAssembly\"\n  raw_title: \"[JA] Ruby, Opal and WebAssembly / Yutaka HARA @yhara\"\n  speakers:\n    - Yutaka HARA\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"bNTajEO_ndA\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/yhara.html\n\n    WebAssembly is a state-of-the-art technology to run CPU intensive calculation on the browser. So how does it relate to Ruby? Well, for instance, you would like to use it while writing browser games, with Ruby.\n\n    In this talk, I will introduce DXOpal, a game programming framework for Opal (Ruby-to-JavaScript compiler). DXOpal takes advantage of WebAssembly for complex calculations like collision detection.\n\n- id: \"satoshi-moris-tagomori-rubykaigi-2017\"\n  title: \"Ruby for Distributed Storage System\"\n  raw_title: '[JA] Ruby for Distributed Storage System / Satoshi \"moris\" Tagomori @tagomoris'\n  speakers:\n    - Satoshi \"moris\" Tagomori\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"KrWhhgWHTwE\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/tagomoris.html\n\n    Storage systems is a big topic in distributed systems, which requires high stability, reliability and performance. There are many OSS distributed storage systems, but most of these are implemented in Java and other JVM languages (just some others are in C++, Riak, etc). An OSS distributed storage, bigdam-pool, is implemented both in Java and Ruby and I'm getting a benchmark score for both implementations. This talk will show the details of benchmark result, and what I learnt from this trial.\n\n    - Providing HTTP API in a daemon\n    - Serializing/Deserializing Data\n    - Performance\n\n- id: \"kouji-takao-rubykaigi-2017\"\n  title: \"Smalruby : The neat thing to connect Rubyists and Scratchers\"\n  raw_title: \"[JA] Smalruby : The neat thing to connect Rubyists and Scratchers\"\n  speakers:\n    - Kouji Takao\n    - Nobuyuki Honda\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"U3pre3Bv9rk\"\n  language: \"Japanese\"\n  description: |-\n    Kouji Takao @takaokouji, Nobuyuki Honda @nobyuki\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/takaokouji.html\n\n    The Smalruby is a 2D game development library that aims to be compatible with Scratch (Scratch is most famous visual programming language: https://scratch.mit.edu/).\n\n    Reacently, programming education for kids is expanding rapidly and Scratch is ususally a first-contact programming language for them. Some kids, good Scratchers, try to learn a text-based programming languege.\n\n    Smalruby helps to make Scratcher Rubyist!\n\n    This talk includes the following topics:\n    - The recent situation of programming education for kids.\n    - Smalruby's features.\n    - Smalruby inside.\n\n- id: \"masahiro-tanaka-rubykaigi-2017\"\n  title: \"Progress of Ruby/Numo: Numerical Computing for Ruby\"\n  raw_title: \"[JA] Progress of Ruby/Numo: Numerical Computing for Ruby / Masahiro TANAKA @masa16tanaka\"\n  speakers:\n    - Masahiro TANAKA\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"qJ6YIfbTLGM\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/masa16tanaka.html\n\n    In my view, the primary reason why Python has become popular in scientific computing is that Python has Numpy, a powerful tool for data processing and it serves as the basis of various libraries. As an equivalent to Numpy in Ruby, I have been developing NArray as I reported in RubyKaigi 2010. Now I am developing the new version of NArray as a library in Ruby/Numo (NUmerical MOdule). Currently Ruby/Numo contains interfaces to BLAS/LAPACK, GSL, FFTE, and Gnuplot. However, the development is far from complete and needs further effort. In this talk, I will report the progress of the Ruby/Numo project and discuss issues in scientific computing with Ruby.\n\n- id: \"mayumi-emori-rubykaigi-2017\"\n  title: \"Serial Protocol Analyzer on Ruby\"\n  raw_title: \"[JA] Serial Protocol Analyzer on Ruby / Mayumi EMORI @emorima\"\n  speakers:\n    - Mayumi EMORI\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"E6LpGzrYWRc\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/emorima.html\n\n    It is easy to program serial communication on Ruby. (Thanks to greate useful gems.)\n    However it is difficult to judge whether there is a problem in either the sending program or the receiving program if data received cannot be successfully. To solve the difficulty, let's analyze the data the sending program has written to the device.\n\n    Rubyでシリアル通信プログラムを書くのは簡単だ。 しかしながら、正しくデータが受信できない場合に、送信側に問題があるのか、受信側に問題があるのかを判断するのが困難である。 その困難さを解決するために、送信プログラムがデバイスに書き込みしたデータをRubyで解析してみよう。\n\n- id: \"ritta-narita-rubykaigi-2017\"\n  title: \"mruby gateway for huge amount of realtime data processing\"\n  raw_title: \"[JA] mruby gateway for huge amount of realtime data processing / Ritta Narita @narittan\"\n  speakers:\n    - Ritta Narita\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"7DuwISRyqGE\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/narittan.html\n\n    TreasureData deals with huge amount of streaming data import request and saves them into our database in realtime without any lost. New scalable system is required to process requests increasing day by day, and I decided to replace old system with rails and fluentd to new system with h2o and mruby for gateway server.\n\n    I'll introduce why h2o and mruby is good and how I optimized mruby server handler for the system. In addition, I'll talk about my patches for h2o to make it possible for mruby parallel processing/asynchronous processing. And also, I'll show benchmarks of actual product.\n\n- id: \"anton-davydov-rubykaigi-2017\"\n  title: \"Hanami - New Ruby Web Framework\"\n  raw_title: \"[EN] Hanami - New Ruby Web Framework / Anton Davydov @anton_davydov\"\n  speakers:\n    - Anton Davydov\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"aYboQzyIoPc\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/anton_davydov.html\n\n    The hanami is quite new and interesting framework which you are unlikely to write complex applications. But this does not mean that this framework is not worth your attention. Besides old approaches, you can also find new interesting solutions.\n\n- id: \"sameer-deshmukh-rubykaigi-2017\"\n  title: \"C how to supercharge Ruby with Rubex\"\n  raw_title: \"[EN] C how to supercharge Ruby with Rubex / Sameer Deshmukh @v0dro\"\n  speakers:\n    - Sameer Deshmukh\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"pZSuuyiQNZk\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/v0dro.html\n\n    CRuby is still one of the most popular Ruby interpreters in use today, but it lacks speed. In this talk you will be introduced to Rubex - a new programming language that compiles to C, looks almost exactly like Ruby and is specifically designed for supercharging your Ruby code with minimal effort.\n\n- id: \"masataka-kuwabara-rubykaigi-2017\"\n  title: \"Writing Lint for Ruby\"\n  raw_title: \"[JA] Writing Lint for Ruby / Masataka Kuwabara @p_ck_\"\n  speakers:\n    - Masataka Kuwabara\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"xr3uDzQIuBA\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/p_ck_.html\n\n    This talk describes how to write Lint for Ruby program.\n\n    Lint finds bugs from code automatically. So, if you can write Lint, you can reduce bugs from your code automatically. This talk includes the following topics.\n\n    - Implementation of existing Lint such as RuboCop and Reek.\n    - How to create new Lint or add a new rule to existing Lint yourself.\n\n- id: \"itoyanagi-sakura-rubykaigi-2017\"\n  title: \"Ruby Parser In IRB 20th Anniversary...Now Let Time Resume\"\n  raw_title: \"[EN] Ruby Parser In IRB 20th Anniversary...Now Let Time Resume / ITOYANAGI Sakura @aycabta\"\n  speakers:\n    - ITOYANAGI Sakura\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"fZGyXwiFNAo\"\n  language: \"English\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/aycabta.html\n\n    IRB has an internal Ruby code parser by pure Ruby. It's contributing greatly to some Ruby tools. A part of them is RDoc. RDoc uses forked Ruby parser of IRB. It is great works, but so legacy. The maintenance cost for new Ruby syntax continues to increase. For example, Ruby 2.1 supports new feature visibility def method definition, but RDoc supports it after Ruby 2.4.\n\n    I provide a solution for it. After Ruby 1.9, Ripper is adopted as standard library. Ripper is a parser for Ruby code, it uses parse.y of CRuby in common. It's perfect for supporting latest Ruby syntax.\n\n- id: \"kentaro-goto-rubykaigi-2017\"\n  title: \"Ruby in office time reboot\"\n  raw_title: \"[JA] Ruby in office time reboot / Kentaro Goto, ごとけん @gotoken\"\n  speakers:\n    - Kentaro Goto\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-24\"\n  video_provider: \"youtube\"\n  video_id: \"PAQwlSfRjko\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/gotoken.html\n\n    I'll introduce some uses of Ruby in my everyday office hours. Various kind of tasks are helped by Ruby: data processing, scraping, excel sheet generation, Installation ruby, etc. This is a continuation of old my talk series: Shigoto de tsukau Ruby.\n\n- id: \"joe-kutner-rubykaigi-2017\"\n  title: \"Asynchronous and Non-Blocking IO with JRuby\"\n  raw_title: \"[EN] Asynchronous and Non-Blocking IO with JRuby / Joe Kutner @codefinger\"\n  speakers:\n    - Joe Kutner\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-25\"\n  video_provider: \"youtube\"\n  video_id: \"BB5z8cg2Hlc\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/codefinger.html\n\n    Asynchronous and non-blocking IO yields higher throughput, lower resource usage, and more predictable behaviour under load. This programming model has become increasingly popular in recent years, but you don't need to use Node.js to see these benefits in your program. You can build asynchronous applications with JRuby. In this talk, we’ll look at libraries and patterns for doing high performance IO in Ruby.\n\n- id: \"mai-nguyen-rubykaigi-2017\"\n  title: \"Food, Wine and Machine Learning: Teaching a Bot to Taste\"\n  raw_title: \"[EN] Food, Wine and Machine Learning: Teaching a Bot to Taste / Mai Nguyen @happywinebot\"\n  speakers:\n    - Mai Nguyen\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-25\"\n  video_provider: \"youtube\"\n  video_id: \"FP5Zxd5o_4M\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/happywinebot.html\n\n    To use machine learning effectively, you have to understand its strengths, limitations and look for creative ways to apply it. Even if you are already familiar with machine learning, we can all learn more! Let me show you how I have used machine learning to build a bot that can suggest a wine to accompany your next meal.\n\n- id: \"chris-salzberg-rubykaigi-2017\"\n  title: \"The Ruby Module Builder Pattern\"\n  raw_title: \"[EN] The Ruby Module Builder Pattern / Chris Salzberg / @shioyama\"\n  speakers:\n    - Chris Salzberg\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-25\"\n  video_provider: \"youtube\"\n  video_id: \"_E1yKPC-r1E\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/shioyama.html\n\n    Did you know that Ruby has configurable modules? One of the most interesting features of Ruby, the Module Builder Pattern is also probably its least well-known. Simply subclass the Module class, dynamically define some methods in an initializer, and boom, you can create named, customizable modules to include in other classes. In this talk, I'll explain how I've leveraged this unique feature of Ruby to build a translation gem called Mobility that can handle a wide range of different storage strategies through a single, uniform interface.\n\n- id: \"victor-shepelev-rubykaigi-2017\"\n  title: \"The Curious Case of Wikipedia Parsing\"\n  raw_title: \"[EN] The Curious Case of Wikipedia Parsing / Victor Shepelev @zverok\"\n  speakers:\n    - Victor Shepelev\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-25\"\n  video_provider: \"youtube\"\n  video_id: \"oqsX8kNq94I\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/zverok.html\n\n    A case study of developing Wikipedia client/parser for structured information extraction, or How we are making entire world common knowledge information machine accessible (from Ruby). Includes investigation of parser development for semi-structured markup and semantic API design.\n\n- id: \"john-mettraux-rubykaigi-2017\"\n  title: \"Flor - hubristic interpreter\"\n  raw_title: \"[EN] Flor - hubristic interpreter / John Mettraux @jmettraux\"\n  speakers:\n    - John Mettraux\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-25\"\n  video_provider: \"youtube\"\n  video_id: \"gXep-LwPvw8\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/jmettraux.html\n\n    Originally, the talk was named \"I wanted to write less code\". We all do. But I fell into a rabbit hole of languages and interpreters. This will be an exposé of my hubristic quest.\n\n    Flor is a workflow engine, a remake of ruote, yet another celebration of the joy of programming in Ruby.\n\n- id: \"yuki-nishijima-rubykaigi-2017\"\n  title: \"Static Typo Checker in Ruby\"\n  raw_title: \"[EN] Static Typo Checker in Ruby / Yuki Nishijima @yuki24\"\n  speakers:\n    - Yuki Nishijima\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-25\"\n  video_provider: \"youtube\"\n  video_id: \"k9WEDRMvanM\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/yuki24.html\n\n    Since 2.3.0, Ruby comes with a dynamic typo checker called the did_you_mean gem, which helps find a bug caused by a typo. However, there's one argument against its design: it runs a naming check at runtime.\n\n    So what makes it difficult to implement a static typo checker? What are the technical challenges to build it? Is Type really necessary? In this talk, we'll discuss techniques for how to write a static typo checker by looking at examples that find an undefined method without running Ruby code. Join us to learn about the future of Ruby's typo checker.\n\n- id: \"keiju-ishitsuka-rubykaigi-2017\"\n  title: \"Irb 20th anniversary memorial session: Reish and Irb2\"\n  raw_title: \"[JA] Irb 20th anniversary memorial session: Reish and Irb2 / Keiju Ishitsuka @keiju\"\n  speakers:\n    - Keiju Ishitsuka\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"mS7fBsBF_gg\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/keiju.html\n\n    Irb has been born 20 years now.. To commemorate it I will talk about Reish and the next generation of Irb. Reish is an an unix shell for rubyist. It is a shell language that realize Ruby's feature. Also, it is an language which is metamorphosed from Ruby for more natural shell operation. Reish is under development. Reish is similar to Irb in usage, and various knowledge was gained in its development. I will introduce the vision of Irb next generation based on that.\n\n    Irbは今年で生まれて20年になります. それを記念してReishとIrbの次世代の話をします. ReishはRubyistのためのshellで, Rubyの機能を実現しています. また, Ruby操作から自然にshell操作に変換可能な言語です. Reishは現在開発中です. ReishはIrbと使い方が似ていて, その開発からいろいろな知見を得ることができます。それを基にIrbの次世代の構想をお話しします.\n\n- id: \"yuki-torii-rubykaigi-2017\"\n  title: \"Pattern Matching in Ruby\"\n  raw_title: \"[EN] Pattern Matching in Ruby / YUKI TORII @yotii23\"\n  speakers:\n    - Yuki Torii\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"1m4IPJH0k0E\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/yotii23.html\n\n    Do you want pattern matching in Ruby? I want. It will make Ruby more elegant, more useful, and more comfortable. So in this talk, I'll propose a specification about pattern matching in Ruby and will show my implementation in parse.y (a part of them).\n\n- id: \"noah-gibbs-rubykaigi-2017\"\n  title: \"How Close is Ruby 3x3 For Production Web Apps?\"\n  raw_title: \"[EN] How Close is Ruby 3x3 For Production Web Apps? / Noah Gibbs @codefolio\"\n  speakers:\n    - Noah Gibbs\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"xZ5mw3x2pdo\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/codefolio.html\n\n    How much faster is current Ruby than Ruby 2.0 for a production web application? Let's look at a mixed workload in the real commercial Discourse forum software. We'll see how the speed has changed overall. We'll also examine slow requests, garbage collection, warmup iterations and more. You'll see how to use this benchmark to test your own Ruby optimizations.\n\n- id: \"yoh-osaki-rubykaigi-2017\"\n  title: \"dRuby on Browser\"\n  raw_title: \"[JA] dRuby on Browser / Yoh Osaki @youchan\"\n  speakers:\n    - Yoh Osaki\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"Tgq5GhagmcU\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/youchan.html\n\n    I implemented dRuby on Browser with Opal(a JavaScript to Ruby source code compiler). Browser communicate with WebSocket to the server. The clients transparently access the server-side objects through the distributed objects. Also, by sharing the server-side objects among multiple clients, it can be applied to collaborative applications like Google Apps. This talk will explain the implementation of dRuby on Opal and demonstrate the collaborative application.\n\n- id: \"aaron-patterson-rubykaigi-2017\"\n  title: \"Compacting GC in MRI\"\n  raw_title: \"[JA] Compacting GC in MRI / Aaron Patterson @tenderlove\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  slides_url: \"https://speakerdeck.com/tenderlove/building-a-compacting-gc\"\n  video_provider: \"youtube\"\n  video_id: \"AuuYQaoqr24\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/tenderlove.html\n\n    We will talk about implementing a compacting GC for MRI. This talk will cover compaction algorithms, along with implementation details, and challenges specific to MRI.\n\n- id: \"akira-matsuda-rubykaigi-2017\"\n  title: \"Lightning Talks (Day 1)\"\n  raw_title: \"[EN][JA] Lightning Talks\"\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"5vcv3s7cEeE\"\n  language: \"Japanese\"\n  description: |-\n    http://rubykaigi.org/2017/presentations/lt/\n  speakers:\n    - Akira Matsuda\n  talks:\n    - title: \"Lightning Talk: Implementation of Web Standards in Mastodon\"\n      start_cue: \"00:42\"\n      end_cue: \"06:03\"\n      id: \"hiroshi-kawada-lighting-talk-rubykaigi-2017\"\n      video_id: \"hiroshi-kawada-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Hiroshi Kawada\n\n    - title: \"Lightning Talk: How to develop CRuby easily with Vim\"\n      start_cue: \"06:03\"\n      end_cue: \"11:29\"\n      id: \"tatsuhiro-ujihisa-lighting-talk-rubykaigi-2017\"\n      video_id: \"tatsuhiro-ujihisa-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Tatsuhiro Ujihisa\n\n    - title: \"Lightning Talk: How to specify `frozen_string_literal: true`.\"\n      start_cue: \"11:29\"\n      end_cue: \"16:30\"\n      id: \"kazuhiro-nishiyama-lighting-talk-rubykaigi-2017\"\n      video_id: \"kazuhiro-nishiyama-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Kazuhiro NISHIYAMA\n\n    - title: \"Lightning Talk: Use case of Refinements with black magic\"\n      start_cue: \"16:30\"\n      end_cue: \"21:47\"\n      id: \"tomohiro-hashidate-lighting-talk-rubykaigi-2017\"\n      video_id: \"tomohiro-hashidate-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomohiro Hashidate\n\n    - title: \"Lightning Talk: A WebSocket proxy server of Niconico comment server by Ruby\"\n      start_cue: \"21:47\"\n      end_cue: \"26:13\"\n      id: \"kinoppyd-lighting-talk-rubykaigi-2017\"\n      video_id: \"kinoppyd-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - kinoppyd\n\n    - title: \"Lightning Talk: Auto Completion in Rails::WebConsole\"\n      start_cue: \"26:13\"\n      end_cue: \"30:58\"\n      id: \"hiroyuki-sano-lighting-talk-rubykaigi-2017\"\n      video_id: \"hiroyuki-sano-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Hiroyuki Sano\n\n    - title: \"Lightning Talk: My Challenge of embedding mruby into a bare-metal hypervisor\"\n      start_cue: \"30:58\"\n      end_cue: \"36:17\"\n      id: \"yuki-nakata-lighting-talk-rubykaigi-2017\"\n      video_id: \"yuki-nakata-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Yuki Nakata\n\n    - title: \"Lightning Talk: Glitching ruby script\"\n      start_cue: \"36:17\"\n      end_cue: \"41:17\"\n      id: \"urabe-shyouhei-lighting-talk-rubykaigi-2017\"\n      video_id: \"urabe-shyouhei-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Shyouhei Urabe\n\n    - title: \"Lightning Talk: DNN/GPU with Ruby\"\n      start_cue: \"41:17\"\n      end_cue: \"46:33\"\n      id: \"satoshi-namai-lighting-talk-rubykaigi-2017\"\n      video_id: \"satoshi-namai-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Satoshi Namai\n\n    - title: \"Lightning Talk: Migration from hiki to markdown in Rubima\"\n      start_cue: \"46:33\"\n      end_cue: \"51:53\"\n      id: \"miyohide-lighting-talk-rubykaigi-2017\"\n      video_id: \"miyohide-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - miyohide\n\n    - title: \"Lightning Talk: Independence of mruby.\"\n      start_cue: \"51:53\"\n      end_cue: \"57:16\"\n      id: \"takeshi-watanabe-lighting-talk-rubykaigi-2017\"\n      video_id: \"takeshi-watanabe-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Takeshi Watanabe\n\n    - title: \"Lightning Talk: LLVM-based JIT compiler for CRuby\"\n      start_cue: \"57:16\"\n      end_cue: \"01:03:04\"\n      id: \"takashi-kokubun-lighting-talk-rubykaigi-2017\"\n      video_id: \"takashi-kokubun-lighting-talk-rubykaigi-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Takashi Kokubun\n\n- id: \"soutaro-matsumoto-rubykaigi-2017\"\n  title: \"Type Checking Ruby Programs with Annotations\"\n  raw_title: \"[EN] Type Checking Ruby Programs with Annotations / Soutaro Matsumoto @soutaro\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"JExXdUux024\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/soutaro.html\n\n    Type inference for Ruby programs is really difficult, and no one on earth has implemented successfully yet.\n\n    Q: What if we write type annotations?\n    A: Much easier, but it is still not trivial.\n\n    I will explain why they are difficult, how we can have a practical type checker for Ruby, and how the programming experience will be with types.\n\n- id: \"koichi-sasada-rubykaigi-2017\"\n  title: \"Fiber in the 10th year\"\n  raw_title: \"[JA] Fiber in the 10th year / Koichi Sasada @ko1\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"pgFx8DFjN8M\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/ko1.html\n\n\n    10 years ago I introduced new class Fiber into Ruby 1.9 as (semi-)coroutine.\n\n    Fiber is a powerful tool to make generators and self managing context switching scheduler. Recently we receive a new proposal \"auto-Fiber\" to use Fiber aggressively in asynchronous operations.\n\n    In this talk, I will introduce a Fiber itself and a brief histroy of Fiber implementations. What is coroutine and semi-coroutine? Why we need to require 'fiber' library to use Fiber#transfer? How to implement fibers and how to speed up them? Also I introduce new proposal \"auto-Fiber\" and this discussion.\n\n- id: \"ruby-committers-rubykaigi-2017\"\n  title: \"Ruby Committers vs the World\"\n  raw_title: \"[JA] Ruby Committers vs the World\"\n  speakers:\n    - Ruby Committers # TODO: list each person\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"Vw36kmRmH5I\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/rubylangorg.html\n\n    Live discussions and Q&A from the Ruby Core team\n\n- id: \"valentin-fondaratov-rubykaigi-2017\"\n  title: \"Automated Type Contracts Generation for Ruby\"\n  raw_title: \"[EN] Automated Type Contracts Generation for Ruby / Valentin Fondaratov @rubymine\"\n  speakers:\n    - Valentin Fondaratov\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"JS6m2gke0Ic\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/rubymine.html\n\n    Beauty and power of Ruby and Rails pays us back when it comes to finding bugs in large codebases. Static analysis is hindered by magic DSLs and patches. We may annotate the code with YARD which also enables improved tooling such as code completion. Sadly, the benefits of this process rarely compensate for the effort.\n\n    In this session we’ll see a new approach to type annotations generation. We'll learn how to obtain this data from runtime, to cope with DSLs and monkey patching, propose some tooling beyond YARD and create contracts like (String, T) - T\n\n    YARV hacking and minimized DFAs included.\n\n- id: \"charles-nutter-rubykaigi-2017\"\n  title: \"JRuby at 15 Years: Meeting the Challenges\"\n  raw_title: \"[EN] JRuby at 15 Years: Meeting the Challenges / Charles Nutter @headius, Thomas E Enebo @tom_enebo\"\n  speakers:\n    - Charles Nutter\n    - Thomas E Enebo\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"rkvrikvoYPQ\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/headius.html\n\n    JRuby has evolved a lot over 15 years. We've met challenges of performance, native integration, and compatibility. What will we face in the future? In this talk we'll discuss today's JRuby challenges: startup time, code size, type specialization, and tooling. JRuby is the most-used alternative Ruby, and with your help we'll continue to make it the best way to run your Ruby apps.\n\n- id: \"yusuke-endoh-rubykaigi-2017\"\n  title: \"An introduction and future of Ruby coverage library\"\n  raw_title: \"[JA] An introduction and future of Ruby coverage library / Yusuke Endoh @mametter\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"zkP8pXOpiH0\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/mametter.html\n\n    Are you using code coverage? As Ruby is a dynamic language and there is no standard static code checker yet, a good test suite is crucial to write a production-level Ruby code. Code coverage is a measure of test goodness. Therefore, it is also important to (properly) use code coverage to take a hint about whether your test suite is good enough or not yet (and if any, which modules are not tested well). We talk an introduction to code coverage, types and usage of code coverage, the current status of Ruby coverage library, and some planned improvements towards Ruby 2.5.\n\n- id: \"julian-cheal-rubykaigi-2017\"\n  title: \"Do Androids Dream of Electronic Dance Music?\"\n  raw_title: \"[EN] Do Androids Dream of Electronic Dance Music? / Julian Cheal, Eric Weinstein\"\n  speakers:\n    - Julian Cheal\n    - Eric Weinstein\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"OfDBRfmVFHk\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/juliancheal.html\n\n    AI is everywhere in our lives these days: recommending our TV shows, planning our car trips, and running our day-to-day lives through artificially intelligent assistants like Siri and Alexa. But are machines capable of creativity? Can they write poems, paint pictures, or compose music that moves human audiences? We believe they can! In this talk, we’ll use Ruby and cutting-edge machine learning tools to train a neural network on human-generated Electronic Dance Music (EDM), then see what sorts of music the machine dreams up.\n\n- id: \"kouhei-sutou-rubykaigi-2017\"\n  title: \"Improve extension API: C++ as better language for extension\"\n  raw_title: \"[JA] Improve extension API: C++ as better language for extension / Kouhei Sutou @ktou\"\n  speakers:\n    - Kouhei Sutou\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"gfoizFzJ-oI\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/ktou.html\n\n    This talk proposes better extension API.\n\n    The current extension API is C API. In the past, some languages such as Rust (RubyKaigi 2015), Go (Oedo RubyKaigi 05), rubex (RubyKaigi 2016) were proposed as languages to write extension.\n\n    This talks proposes C++ as a better language for writing extension. Reasons:\n\n    - C++ API can provide simpler API than C API.\n    - C++ API doesn't need C bindings because C++ can use C API including macro natively. Other languages such as Rust and Go need C bindings.\n    - Less API maintenance cost. Other approaches need more works for Ruby evolution such as introduces new syntax and new API.\n\n- id: \"godfrey-chan-rubykaigi-2017\"\n  title: \"Bending The Curve: Putting Rust in Ruby with Helix\"\n  raw_title: \"[EN] Bending The Curve: Putting Rust in Ruby with Helix / Godfrey Chan, Terence Lee\"\n  speakers:\n    - Godfrey Chan\n    - Terence Lee\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"M2erAV1CpRk\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/chancancode.html\n\n    Two years ago at RubyKaigi, we demonstrated our initial work on Helix, an FFI toolkit that makes it easy for anyone to write Ruby native extensions in Rust. In this talk, we will focus on the challenges and lessons we learned while developing Helix. What did it take to fuse the two languages and still be able to take advantage of their unique features and benefits? How do we distribute the extensions to our end-users? Let's find out!\n\n- id: \"tanaka-akira-rubykaigi-2017\"\n  title: \"Ruby Extension Library Verified using Coq Proof-assistant\"\n  raw_title: \"[JA] Ruby Extension Library Verified using Coq Proof-assistant / Tanaka Akira @tanaka_akr\"\n  speakers:\n    - Tanaka Akira\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"berjYyI5Bys\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/tanaka_akr.html\n\n    Ruby extension library is written in C. C is great because it is fast and easy to access low-level features of OS and CPU. However it is dangerous and error-prone: it is difficult to avoid failures such as integer overflow and buffer overrun. We explain a method to generate C functions verified using Coq proof-assistant with Coq plugins we developed. We can verify safety (absence of failures) and correctness (functions works as expected) in Coq. The generated functions can be used in Ruby extension library. This provides a way to develop trustful Ruby extension library. Supplement material: https://github.com/akr/coq-html-escape\n  additional_resources:\n    - name: \"akr/coq-html-escape\"\n      type: \"repo\"\n      url: \"https://github.com/akr/coq-html-escape\"\n\n- id: \"masatoshi-seki-rubykaigi-2017\"\n  title: \"How to write synchronization mechanisms for Fiber\"\n  raw_title: \"[JA] How to write synchronization mechanisms for Fiber / Masatoshi SEKI @m_seki\"\n  speakers:\n    - Masatoshi SEKI\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"0mDnZ0V9OSA\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/m_seki.html\n\n    Ruby threads are amazing, but for some reason they don't seem to be very popular. So I decided I'd try experimenting with programming multiple independent execution flows in a single thread using Fibers.\n\n    In this talk, I'll first explain an idiom for easily writing synchronization mechanisms between Fibers. Then I will explain in detail an example which combines a framework abstracting 'select' with the Fiber idiom to achieve blocking-like non-blocking IO. I'll explain this using actual code from examples of timer-based periodic processing and simple TCP/IP server programming, to an over-the-top example running WEBrick on a single thread (using Fiber to handle multiple clients synchronously). I'll also explain ways to combine this with threads.\n\n    In the talk I'd like to present the following: * an example of select abstraction * some essential features for Fibers\n\n- id: \"yurie-yamane-rubykaigi-2017\"\n  title: \"Write once, run on every boards: portable mruby\"\n  raw_title: \"[JA] Write once, run on every boards: portable mruby / Yurie Yamane @yuri_at_earth\"\n  speakers:\n    - Yurie Yamane\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"DF4oLrc7KaE\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/yuri_at_earth.html\n\n    In embedded programming, the development environment and libraries we use to program are different depending on hardware. So, we have to make different programs for each hardware. Would not it be nice if CRuby works on Mac and Windows, even if the hardware is different, would the same mruby program run? I have a plan off platform to make one same Ruby code run on various microcontrollers. In this session, I will introduce an example of running Ruby code on several microcomputers.\n\n- id: \"colby-swandale-rubykaigi-2017\"\n  title: \"Bundler 2\"\n  raw_title: \"[EN] Bundler 2 / Colby Swandale @0xColby\"\n  speakers:\n    - Colby Swandale\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-27\"\n  video_provider: \"youtube\"\n  video_id: \"sZX7SK3hxk4\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/0xColby.html\n\n    The Bundler core team has been working hard on the next major release of Bundler. We'll talk about what improvements we've been making, new features & what we've removed.\n\n- id: \"fumiaki-matsushima-rubykaigi-2017\"\n  title: \"Ruby Language Server\"\n  raw_title: \"[JA] Ruby Language Server / Fumiaki MATSUSHIMA @mtsmfm\"\n  speakers:\n    - Fumiaki MATSUSHIMA\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"spPAdvskyLI\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2017\n    http://rubykaigi.org/2017/presentations/mtsmfm.html\n\n    This talk describes a ruby language server implementation I created. I want to increase developers interested in Ruby language server because I hope it will improve Ruby development experience.\n\n    In last year, Microsoft published Language Server Protocol. This protocol is created to communicate between editors and language servers which provide useful information for development (ex. linting, completion, method definition).\n\n    In this talk, I'll show you why it is important to create language server for Ruby community and how it's implemented.\n\n- id: \"nate-berkopec-rubykaigi-2017\"\n  title: \"Memory Fragmentation and Bloat in Ruby\"\n  raw_title: \"[EN] Memory Fragmentation and Bloat in Ruby / Nate Berkopec @nateberkopec\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-27\"\n  video_provider: \"youtube\"\n  video_id: \"eBmM-yWPeMw\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/nateberkopec.html\n\n    Memory is not a simple abstraction. The layers of indirection between \"Object.new\" and flipping a bit in RAM are numerous: the Ruby heap, the memory allocator, the kernel, the memory management unit and more. Unfortunately, all of these layers can contribute to \"bad behavior\", resulting in memory fragmentation and bloat. This talk examines each of the different layers of memory abstraction, and how tuning and controlling them can result in reduced memory usage in Ruby applications.\n\n- id: \"kevin-menard-rubykaigi-2017\"\n  title: \"Improving TruffleRuby’s Startup Time with the SubstrateVM\"\n  raw_title: \"[EN] Improving TruffleRuby’s Startup Time with the SubstrateVM / Kevin Menard @nirvdrum\"\n  speakers:\n    - Kevin Menard\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-27\"\n  video_provider: \"youtube\"\n  video_id: \"5Ik2qCTmeN0\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/nirvdrum.html\n\n    We’ve solved the startup time problem in TruffleRuby! In this talk, I’ll introduce the SubstrateVM and how we make use of it to compile the Java-based TruffleRuby to a static binary and massively improve our startup time.\n\n- id: \"julian-nadeau-rubykaigi-2017\"\n  title: \"Busting Performance Bottlenecks: Improving Boot Time by 60%\"\n  raw_title: \"[EN] Busting Performance Bottlenecks: Improving Boot Time by 60% / Julian Nadeau @jules2689\"\n  speakers:\n    - Julian Nadeau\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-27\"\n  video_provider: \"youtube\"\n  video_id: \"8BJKrx6rsM0\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/jules2689.html\n\n    Lengthy application boot times cause developers to quickly lose context and view applications in a negative light, which in turn costs organizations a lot of money and productivity. We found that there were a few areas that impacted boot time: compiling Ruby bytecode, serializing configurations, looking up files and constants, autoloading files, and booting Bundler. This talk focuses on our strategies and solutions which improved our boot time by 60%. Attendees will leave with knowledge of ways to find and mitigate their own startup performance bottlenecks.\n\n- id: \"delton-ding-rubykaigi-2017\"\n  title: \"High Concurrent Ruby Web Development Without Fear\"\n  raw_title: \"[EN] High Concurrent Ruby Web Development Without Fear / Delton Ding @DeltonDing\"\n  speakers:\n    - Delton Ding\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-27\"\n  video_provider: \"youtube\"\n  video_id: \"L_DRmV3LMYA\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/DeltonDing.html\n\n    High Concurrent Ruby Web Development Without Fear\n    We've been debating on the concurrency solution of Ruby for several years. Numerous custom \"evented\" drivers have been built, but for most of these projects, developers are required to think in the \"evented\" way to get things work properly, which not only breaks the elegance of Ruby programming, but also greatly increases the complexity of the refactoring process.\n\n    We will then think in Ruby, looking for the solution to make your whole web application \"evented\" with great meta-programming features of Ruby language itself. So that, you could still concentrate on your business models while programming as usual, but the performance may boost to 5 times faster or more without any hesitation.\n\n- id: \"henry-tseng-rubykaigi-2017\"\n  title: \"Tamashii - Create Rails IoT applications more easily\"\n  raw_title: \"[EN] Tamashii - Create Rails IoT applications more easily / Henry Tseng @lctseng\"\n  speakers:\n    - Henry Tseng\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-27\"\n  video_provider: \"youtube\"\n  video_id: \"g7WM6ITZYp0\"\n  language: \"English\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/lctseng.html\n\n\n    There is also a short demo video to help you know more about Tamashii: https://youtu.be/hH6u4sJx_L4\n\n    Tamashii Official Website: https://tamashii.io\n\n- id: \"kenta-murata-rubykaigi-2017\"\n  title: \"Development of Data Science Ecosystem for Ruby\"\n  raw_title: \"[JA] Development of Data Science Ecosystem for Ruby / Kenta Murata @mrkn\"\n  speakers:\n    - Kenta Murata\n  event_name: \"RubyKaigi 2017\"\n  date: \"2017-09-18\"\n  published_at: \"2017-09-26\"\n  video_provider: \"youtube\"\n  video_id: \"U9GdgZowmGY\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi2017\n    http://rubykaigi.org/2017/presentations/mrkn.html\n\n    The importance of data analysis in business is increasing day by day. Considering the future of Ruby which is often adopted as the development of business systems, it is an urgent task to make this programming language available in datascience.\n\n    By the appearance of PyCall, Ruby has became able to use mainstreem tools used in datascience such as pandas and matplotlib. However, in order to establish Ruby as a programming language that can be used in datascience, and to keep it in the future as well, there are many problems now, but only a very few developers are working on solving this problem.\n\n    In this presentation, we will introduce what we'll need in the future to establish Ruby as a programming language that can be used in data science. And we'll aim to stimulate Rubyists who are interested in this field, and to activate the development of the datascience ecosystem for Ruby by encouraging development of missing tools, documentation, and reporting on feeling of use and bugs.\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2018/event.yml",
    "content": "---\nid: \"PLbFmgWm555yZ8IJuzGOn3rj2dOvRLDdxL\"\ntitle: \"RubyKaigi 2018\"\nkind: \"conference\"\nlocation: \"Sendai, Miyagi, Japan\"\ndescription: |-\n  RubyKaigi 2018\n  May 31st - Jun 2nd\n  Sendai International Center, Sendai, Miyagi, Japan\n\n  https://rubykaigi.org/2018/\npublished_at: \"2018-06-15\"\nstart_date: \"2018-05-31\"\nend_date: \"2018-06-02\"\nchannel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\nyear: 2018\nbanner_background: \"#F3F1D7\"\nfeatured_background: \"#F3F1D7\"\nfeatured_color: \"#424133\"\nwebsite: \"https://rubykaigi.org/2018/\"\ncoordinates:\n  latitude: 38.268195\n  longitude: 140.869418\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2018/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"kouhei-sutou-rubykaigi-2018\"\n  title: \"Keynote: My way with Ruby\"\n  raw_title: \"[JA][Keynote] My way with Ruby / Kouhei Sutou @ktou\"\n  speakers:\n    - Kouhei Sutou\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-15\"\n  video_provider: \"youtube\"\n  video_id: \"d7lDhsE1jXg\"\n  language: \"Japanese\"\n  description: |-\n    Here are my activities as a Rubyist:\n\n      * Increase what Ruby can do with free software\n      * Maintain libraries\n\n    In this talk, I introduce my activities.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/ktou\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2018\"\n  title: \"Keynote: Keynote\"\n  raw_title: '[JA][Keynote] Keynote / Yukihiro \"Matz\" Matsumoto @yukihiro_matz'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-15\"\n  video_provider: \"youtube\"\n  video_id: \"zb8dXWYUX10\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/yukihiro_matz\n\n- id: \"benoit-daloze-rubykaigi-2018\"\n  title: \"Keynote: Parallel and Thread-Safe Ruby at High-Speed with TruffleRuby\"\n  raw_title: \"[EN][Keynote] Parallel and Thread-Safe Ruby at High-Speed with TruffleRuby / Benoit Daloze @eregontp\"\n  speakers:\n    - Benoit Daloze\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-15\"\n  video_provider: \"youtube\"\n  video_id: \"mRKjWrNJ8DI\"\n  language: \"English\"\n  description: |-\n    Array and Hash are used in every Ruby program. Yet, current implementations either prevent the use of them in parallel (the global interpreter lock in MRI) or lack thread-safety guarantees (JRuby raises an exception on concurrent Array#). Concurrent::Array from concurrent-ruby is thread-safe but prevents parallel access.\n\n    This talk shows a technique to make Array and Hash thread-safe while enabling parallel access, with no penalty on single-threaded performance. In short, we keep the most important thread-safety guarantees of the global lock while allowing Ruby to scale up to tens of cores!\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/eregontp\n\n- id: \"marc-andr-lafortune-rubykaigi-2018\"\n  title: \"Deep into Ruby Code Coverage\"\n  raw_title: \"[EN] Deep into Ruby Code Coverage / Marc-André Lafortune @malafortune\"\n  speakers:\n    - Marc-André Lafortune\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-17\"\n  video_provider: \"youtube\"\n  video_id: \"HWj3nrvAmRM\"\n  language: \"English\"\n  description: |-\n    Code coverage is an easy way to measure if we have enough tests, yet many of us have yet to use it.\n    This talk delves into the benefits of meaningful code coverage and how to avoid some of its pitfalls with a new tool called DeepCover.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/malafortune\n\n- id: \"eric-hodel-rubykaigi-2018\"\n  title: \"Devly, a multi-service development environment\"\n  raw_title: \"[EN] Devly, a multi-service development environment / Eric Hodel @drbrain, Ezekiel Templin @ezkl\"\n  speakers:\n    - Eric Hodel\n    - Ezekiel Templin\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-17\"\n  video_provider: \"youtube\"\n  video_id: \"rlZR9jXmvL4\"\n  language: \"English\"\n  description: |-\n    Writing a system alone is hard. Building many systems with many people is harder.\n    As our company has grown, we tried many approaches to user-friendly, shared development environments and learned what works and what doesn't. We incorporated what we learned into a tool called devly. Devly is used to develop products at Fastly that span many services written in different languages.\n\n    We learned that the design of our tools must be guided by how teams work and communicate. To respond to these needs, Devly allows self\n    -service, control, and safety so that developers can focus on their work.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/drbrain\n\n- id: \"itoyanagi-sakura-rubykaigi-2018\"\n  title: \"IRB Reboot: Modernize Implementation and Features\"\n  raw_title: \"[EN] IRB Reboot: Modernize Implementation and Features / ITOYANAGI Sakura @aycabta\"\n  speakers:\n    - ITOYANAGI Sakura\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-17\"\n  video_provider: \"youtube\"\n  video_id: \"zUBxip-bhJA\"\n  language: \"English\"\n  description: |-\n    IRB was written at 20 years ago and contains Ruby code parser by pure Ruby. The parser is contributing greatly to some Ruby tools over\n     many years but the maintenance cost for new Ruby syntax continues to increase. IRB must parse Ruby code certainly for when should evaluate the code. I provide a solution for it. Ruby 1.9 or later has two big new features for this problem, `Ripper` and `RubyVM::InstructionSequence.compile`. The two features provide whether code piece continues by tokens information and syntax check.\n\n    After IRB implementation was modernized, I added some new features to IRB. IRB imports RDoc features as a library, such as show documentation with auto-complete, auto-complete for meta-programmed namespaces.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/aycabta\n\n- id: \"takeshi-watanabe-rubykaigi-2018\"\n  title: \"LuaJIT as a Ruby backend.\"\n  raw_title: \"[JA] LuaJIT as a Ruby backend. / Takeshi Watanabe @take-cheeze\"\n  speakers:\n    - Takeshi Watanabe\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-17\"\n  video_provider: \"youtube\"\n  video_id: \"F-lZtxewCcs\"\n  language: \"Japanese\"\n  description: |-\n    LuaJIT is an excellent implementation of Lua with JIT.\n    It also provides JIT modules that can be reused in other language.\n    In this session I will talk experience using LuaJIT as mruby backend.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/take-cheeze\n\n- id: \"i110-rubykaigi-2018\"\n  title: \"How happy they became with H2O/mruby, and the future of HTTP\"\n  raw_title: \"[JA] How happy they became with H2O/mruby, and the future of HTTP / @i110, Kazuho Oku @kazuho\"\n  speakers:\n    - \"i110\"\n    - Kazuho Oku\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-17\"\n  video_provider: \"youtube\"\n  video_id: \"r9zNEY6KtkI\"\n  language: \"Japanese\"\n  description: |-\n    Are you suffering from your messy web server config files? Do you have a craving for maintainability and flexibility, but worry about performance? This talk introduces a real migration story from nginx to H2O in a large-scale photo sharing service, illustrating how mruby scripting makes it easier to write and maintain configurations. We'll see real configuration examples, some issues we faced and the final result with some benchmarks. In addition, I'll show a lot of shiny new features and mrbgems added recently. You'd be surprised how advanced things can be done with H2O and mruby!\n    In the talk, Kazuho Oku will also discuss the standardization of H2 extensions, QUIC, and how they are likely to affect web application development and deployment.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/i110\n\n- id: \"matsumoto-ryosuke-rubykaigi-2018\"\n  title: \"Design pattern for embedding mruby into middleware\"\n  raw_title: \"[JA] Design pattern for embedding mruby into middleware / MATSUMOTO, Ryosuke @matsumotory\"\n  speakers:\n    - MATSUMOTO Ryosuke\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-17\"\n  video_provider: \"youtube\"\n  video_id: \"xXvaY-xpfpc\"\n  language: \"Japanese\"\n  description: |-\n    mruby released in 2012 and 6 years have passed.\n    I have embedded mruby into a lot of middleware like ngx_mruby, and have designed and implemented both extensibility and performance compatibility in middleware.\n    I want to share not only the specifications and background but also design and implementation that only I know for embedding mruby into middleware since I have been sending patches of specifications and features to mruby.\n    In this presentation, I generalize the design and implementation to connect middleware supporting Internet service with mruby and introduce it as a design pattern.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/matsumotory\n\n- id: \"keiju-ishitsuka-rubykaigi-2018\"\n  title: \"Reirb: Reborn Irb\"\n  raw_title: \"[JA] Reirb: Reborn Irb / Keiju Ishitsuka @keiju\"\n  speakers:\n    - Keiju Ishitsuka\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-17\"\n  video_provider: \"youtube\"\n  video_id: \"zGbmD7LQP2s\"\n  language: \"Japanese\"\n  description: |-\n    Reirb is a reborn irb, which interactive ruby language.\n    It is a high-functional shell language with ruby's syntax.\n    Its feature are job control, multiline-editor, smart-completion, language-navigation functionalities, etc.\n    Everyone will be able to live more enjoyable Ruby-life by using Reirb.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/keiju\n\n- id: \"thomas-e-enebo-rubykaigi-2018\"\n  title: \"JRuby 9.2 and Rails 5.x\"\n  raw_title: \"[EN] JRuby 9.2 and Rails 5.x / Thomas E Enebo @tom_enebo\"\n  speakers:\n    - Thomas E Enebo\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-17\"\n  video_provider: \"youtube\"\n  video_id: \"ue5XVN0SJEw\"\n  language: \"English\"\n  description: |-\n    JRuby 9.2 has been released. 9.2 supports Ruby 2.5 compatibility and it also runs Rails 5.x well. This talk will discuss some of the more interesting apects of JRuby 9.2:\n\n      - Performance updates\n        - Graal integration\n        - IR instr refactoring\n        - Object shaping\n      - Full encoding support ( @@かいぎ ||= $🐻🌻.send :┬─┬ノº_ºノ' )\n      - Improved Windows support\n\n    It will also give an update on the state of running Rails 5.x on JRuby. This talk will go over updates we have made to ActiveRecord-JDBC and show a real world use-case of getting Discourse running. Get up to date on the state of JRuby!\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/tom_enebo\n\n- id: \"prasun-anand-rubykaigi-2018\"\n  title: \"High Performance GPU computing with Ruby\"\n  raw_title: \"[EN] High Performance GPU computing with Ruby / Prasun Anand @prasun_anand\"\n  speakers:\n    - Prasun Anand\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-17\"\n  video_provider: \"youtube\"\n  video_id: \"LP9lIqCAbFE\"\n  language: \"English\"\n  description: |-\n    Ruby being so old and a mature programming is still not preferred for Scientific Computing, mostly because it can’t handle large datasets.\n    RbCUDA and ArrayFire gem, that I created have an outstanding performance and can handle real world problems by crunching huge datasets.\n    In this talk I would like to show how RbCUDA and ArrayFire help you easily accelerate your code.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/prasun_anand\n\n- id: \"yoh-osaki-rubykaigi-2018\"\n  title: \"How to get the dark power from ISeq\"\n  raw_title: \"[JA] How to get the dark power from ISeq / Yoh Osaki @youchan\"\n  speakers:\n    - Yoh Osaki\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-19\"\n  video_provider: \"youtube\"\n  video_id: \"zTO2t24IhgI\"\n  language: \"Japanese\"\n  description: |-\n    ISeq is a cross-section of the Ruby interpreter.\n    If there is a parser that generates ISeq, it can run languages other than Ruby. If there is a processing system that interprets iSeq,\n    it may be possible to run Ruby on other than MRI's supporting platform.\n    Java is actively carrying out such things by disclosing the Virtual Machine specification. For example, Scala is the language running\n    on JavaVM, and there are many versions of JavaVM for various platforms.\n    Specifying Ruby's iSeq may be a good thing or a bad thing. Either way, it will be useful to explore its possibilities.\n    In this talk, I will talk to three stances of people. The first are the most of the audiences who purely interest about hacking of ISeq.  The second are potential users of ISeq, I show hints what we should do. At last I will raise a plobrem whether ISeq should be documented to the Ruby core team.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/youchan\n\n- id: \"vladimir-makarov-rubykaigi-2018\"\n  title: \"Three Ruby performance projects\"\n  raw_title: \"[EN] Three Ruby performance projects / Vladimir Makarov @vnmakarov\"\n  speakers:\n    - Vladimir Makarov\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-19\"\n  video_provider: \"youtube\"\n  video_id: \"emhYoI_RiOA\"\n  language: \"English\"\n  description: |-\n    There are many ways to improve performance of a serious program like CRuby.  This presentation is an illustration of this on three different size projects.\n\n      One project is pretty small. It is to introduce a **new CRuby internal representation of IEEE 754 double precision numbers** to improve CRuby floating point performance. The second one is a medium-size **project to generate RTL from YARV instructions** and to use RTL for the interpretation and JIT compilation.  And the third one is a very ambitious project to create a **light-weight JIT** which can be used together with MJIT as a tier 1 JIT compiler or as a single JIT for mruby.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/vnmakarov\n\n- id: \"takashi-kokubun-rubykaigi-2018\"\n  title: \"The Method JIT Compiler for Ruby 2.6\"\n  raw_title: \"[JA] The Method JIT Compiler for Ruby 2.6 / Takashi Kokubun @k0kubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-20\"\n  video_provider: \"youtube\"\n  video_id: \"svtRUkD0ACg\"\n  language: \"Japanese\"\n  description: |-\n    Did you know Ruby 2.6 will be shipped with JIT compiler? Do you know why JIT compiler makes Ruby fast?\n\n    In this talk, you'll see how Ruby can be made faster by surprisingly short ERB code,\n    and the future of Ruby's performance by method inlining.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/k0kubun\n\n- id: \"keita-sugiyama-rubykaigi-2018\"\n  title: \"Grow and Shrink - Dynamically Extending the Ruby VM Stack\"\n  raw_title: \"[JA] Grow and Shrink - Dynamically Extending the Ruby VM Stack / @sugiyama-k, @duerst\"\n  speakers:\n    - Keita Sugiyama\n    - Martin J. Dürst\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-20\"\n  video_provider: \"youtube\"\n  video_id: \"hjTw0T220zs\"\n  language: \"Japanese\"\n  description: |-\n    Currently, MRI (the reference implementation of Ruby) allocates 1MB of stack space for each thread. This is clearly sub-optimal, in particular for highly multi-threaded applications.\n\n    We have successfully implemented dynamical stack extension for MRI, starting with a very small stack size and growing each stack only when needed.\n     We will present two different implementations, one very close to the current stack structure, and one with a different stack structure. We will also explain how we made sure that our implementation is stable. On Linux, we achieve a memory reduction per thread of up to 30%, at the cost of an average speed increase (measured across all Ruby benchmarks) of 6%.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/sugiyama-k\n\n- id: \"shugo-maeda-rubykaigi-2018\"\n  title: \"Build your own tools\"\n  raw_title: \"[JA] Build your own tools / Shugo Maeda @shugomaeda\"\n  speakers:\n    - Shugo Maeda\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-20\"\n  video_provider: \"youtube\"\n  video_id: \"H0mn5u28tPo\"\n  language: \"Japanese\"\n  description: |-\n    Now FLOSS is so common that even Microsoft use it and develop it.  But do you have control over your tools for daily use?\n\n    Building your own tools is the best way to develop software, and Ruby is the best language for such use.  In this talk, I introduce my own tools and my development style.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/shugomaeda\n\n- id: \"aaron-patterson-rubykaigi-2018\"\n  title: \"Analyzing and Reducing Ruby Memory Usage\"\n  raw_title: \"[JA] Analyzing and Reducing Ruby Memory Usage / Aaron Patterson @tenderlove\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-22\"\n  video_provider: \"youtube\"\n  video_id: \"ILzQYMDp18o\"\n  language: \"Japanese\"\n  description: |-\n    Memory usage can be difficult to analyze.  In this presentation we will cover\n    different techniques for analyzing memory usage of a Ruby process including\n    in-process analysis tools as well as system level tools.  After doing memory\n    analysis, we'll look at some ways to reduce overall memory used by the system.\n    Attendees will leave with practical tips and tricks for memory analysis in\n    their Ruby systems, as well as a better understanding of Ruby internals.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/tenderlove\n\n- id: \"kenichi-kanai-rubykaigi-2018\"\n  title: \"Ruby code from the stratosphere - SIAF, Sonic Pi, Petal\"\n  raw_title: \"[JA] Ruby code from the stratosphere - SIAF, Sonic Pi, Petal / Kenichi Kanai @kn1kn1\"\n  speakers:\n    - Kenichi Kanai\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-22\"\n  video_provider: \"youtube\"\n  video_id: \"amn6gHJOjIQ\"\n  language: \"Japanese\"\n  description: |-\n    Last year I participated in a project called [space-moere](http://space-moere.org/) of [SIAF2017](http://siaf.jp/en/) (Sapporo International Art F\n    estival 2017). In the project we received [Sonic Pi](http://sonic-pi.net/) code generated in the stratosphere and had live performance using it. F\n    or the live performance, I made a small language called [Petal](https://github.com/siaflab/petal).\n\n    In this session, I will talk about the topics as follows:\n\n    * space-moere project\n    * Petal\n    * some projects based on it (Sonic Pi and TidalCycles)\n\n    Session Notes: https://gist.github.com/kn1kn1/c28f8029ba5ee069d83b8b6a6c4c8543\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/kn1kn1\n  additional_resources:\n    - name: \"siaflab/petal\"\n      type: \"repo\"\n      url: \"https://github.com/siaflab/petal\"\n\n    - name: \"Session Notes\"\n      type: \"repo\"\n      url: \"https://gist.github.com/kn1kn1/c28f8029ba5ee069d83b8b6a6c4c8543\"\n\n- id: \"kenta-murata-rubykaigi-2018\"\n  title: \"Deep Learning Programming on Ruby\"\n  raw_title: \"[JA] Deep Learning Programming on Ruby / Kenta Murata @mrkn, Yusaku Hatanaka @hatappi\"\n  speakers:\n    - Kenta Murata\n    - Yusaku Hatanaka\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-22\"\n  video_provider: \"youtube\"\n  video_id: \"J-d_Lk4SFtQ\"\n  language: \"Japanese\"\n  description: |-\n    We will present you how to program deep learning models with a practical performance by Ruby language.\n    We will use Apache MXNet and Red Chainer from Ruby.  While Apache MXNet is available through pycall.rb, they will be used directly from Ruby without such bridge system in this talk.\n    Our demonstrations will show you that Ruby is ready to do such tasks.\n\n    Additionally, we will show you the latest progress and the future forecasts of the projects that aim to make Ruby available in data science field.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/mrkn\n\n- id: \"bozhidar-batsov-rubykaigi-2018\"\n  title: \"All About RuboCop\"\n  raw_title: \"[EN] All About RuboCop / Bozhidar Batsov @bbatsov\"\n  speakers:\n    - Bozhidar Batsov\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-23\"\n  video_provider: \"youtube\"\n  video_id: \"nrHjVCuVsGA\"\n  language: \"English\"\n  description: |-\n    In this talk we'll go over everything you need to know about RuboCop - a powerful Ruby static code analyzer that makes it easy for you to enforce a consistent code style throughout your Ruby projects.\n\n    We'll begin by examining the events that lead to the creation of RuboCop, its early days and its evolution, effective RuboCop usage\n    and some of its cool but little-known features. Then we'll continue with a brief look into RuboCop's internals and show you how easy it is\n    to extend its functionality.\n\n    We'll wrap the talk with a glimpse inside RuboCop's future and discuss some of the challenges the project faces and some of the work that remains\n    to be done, before RuboCop finally reaches the coveted 1.0 version.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/bbatsov\n\n- id: \"tomohiro-hashidate-rubykaigi-2018\"\n  title: \"Hijacking Ruby Syntax in Ruby\"\n  raw_title: '[JA] Hijacking Ruby Syntax in Ruby / @joker1007, Satoshi \"moris\" Tagomori @tagomoris'\n  speakers:\n    - Tomohiro Hashidate\n    - Satoshi \"moris\" Tagomori\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-23\"\n  video_provider: \"youtube\"\n  video_id: \"04HGQEw3A6Y\"\n  language: \"Japanese\"\n  description: |-\n    This talk shows how to introduce new syntax-ish stuffs using meta programming techniques and some more Ruby features not known well by many Rubyists. Have fun with magical code!\n\n    - Show Ruby features to hack Ruby syntax (including Binding, TracePoint, Refinements, etc)\n    - Describe stuffs introduced by these techniques\n      - method modifiers (final, abstract, override)\n      - Table-like syntax for testing DSL\n      - Safe resource allocation/collection (with, defer)\n    - Propose new traceable events, hooks, etc\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/joker1007\n\n- id: \"piotr-murach-rubykaigi-2018\"\n  title: \"TTY - Ruby alchemist’s secret potion\"\n  raw_title: \"[EN] TTY - Ruby alchemist’s secret potion / Piotr Murach @piotr_murach\"\n  speakers:\n    - Piotr Murach\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-23\"\n  video_provider: \"youtube\"\n  video_id: \"AeUls-THfpQ\"\n  language: \"English\"\n  description: |-\n    What if you were told that there is a set of simple and potent gems developed to exponentially increase productivity when building modern terminal\n     applications such as Bundler, in next to no time? Curious about how you can harness this power and become a command line applications alchemist?\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/piotr_murach\n\n- id: \"lightning-talks-day-1-rubykaigi-2018\"\n  title: \"Lightning Talks (Day 1)\"\n  raw_title: \"[EN][JA] Lightning Talks\"\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-25\"\n  video_provider: \"youtube\"\n  video_id: \"hCZWrvO_27k\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/lt/\n  talks:\n    - title: \"Lightning Talk: From String#undump to String#unescape\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tadashi-saito-lighting-talk-rubykaigi-2018\"\n      video_id: \"tadashi-saito-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Tadashi Saito\n\n    - title: \"Lightning Talk: Rib - Yet another interactive Ruby shell\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"lulalala-lighting-talk-rubykaigi-2018\"\n      video_id: \"lulalala-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - lulalala\n\n    - title: \"Lightning Talk: Create libcsv based ruby/csv compatible CSV library\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"kazuma-furuhashi-lighting-talk-rubykaigi-2018\"\n      video_id: \"kazuma-furuhashi-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Kazuma Furuhashi\n\n    - title: \"Lightning Talk: Improve JSON performance\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"shizuo-fujita-lighting-talk-rubykaigi-2018\"\n      video_id: \"shizuo-fujita-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Shizuo Fujita\n\n    - title: \"Lightning Talk: Improve Red Chainer and Numo::NArray performance\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"naitoh-jun-lighting-talk-rubykaigi-2018\"\n      video_id: \"naitoh-jun-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - NAITOH Jun\n\n    - title: \"Lightning Talk: Using Tamashii Connect Real World with Chatbot\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"elct9620-lighting-talk-rubykaigi-2018\"\n      video_id: \"elct9620-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - elct9620\n\n    - title: \"Lightning Talk: Find out potential dead codes from diff\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"sangyong-sim-lighting-talk-rubykaigi-2018\"\n      video_id: \"sangyong-sim-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Sangyong Sim\n\n    - title: \"Lightning Talk: Test asynchronous functions with RSpec\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"shigeru-nakajima-lighting-talk-rubykaigi-2018\"\n      video_id: \"shigeru-nakajima-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Shigeru Nakajima\n\n    - title: \"Lightning Talk: To refine or not to refine\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"vladimir-dementyev-lighting-talk-rubykaigi-2018\"\n      video_id: \"vladimir-dementyev-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Vladimir Dementyev\n\n    - title: \"Lightning Talk: 5-Minute Recipe of Todo-app\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"yoh-osaki-lighting-talk-rubykaigi-2018\"\n      video_id: \"yoh-osaki-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Yoh Osaki\n\n    - title: \"Lightning Talk: Symbolic Execution of Ruby Programs\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"lin-yu-hsiang-lighting-talk-rubykaigi-2018\"\n      video_id: \"lin-yu-hsiang-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Lin Yu Hsiang\n\n    - title: \"Lightning Talk: Schrödinger's branch\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"unak-lighting-talk-rubykaigi-2018\"\n      video_id: \"unak-lighting-talk-rubykaigi-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - unak\n\n- id: \"yuta-kurotaki-rubykaigi-2018\"\n  title: \"bancor: Token economy made with Ruby\"\n  raw_title: \"[JA] bancor: Token economy made with Ruby / Yuta Kurotaki @kurotaky\"\n  speakers:\n    - Yuta Kurotaki\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"gqBWoyMdn4c\"\n  language: \"Japanese\"\n  description: |-\n    There is a protocol called \"Bancor Protocol\" which is said to bring about automation of token liquidity and transaction price finding in Smart Contract.\n    To verify the usefulness of this protocol in your project, it is costly to write a smart contract program and implement the application.\n    When implementing applications with Ruby, I am making gem \"bancor\" to easily introduce and verify the Bancor Protocol.\n\n    In this presentation, we will talk about how developers build \"token economy\" on Ruby application using \"bancor\" and how to quickly verify effect.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/kurotaky\n\n- id: \"emma-haruka-iwao-rubykaigi-2018\"\n  title: \"Exploring Internal Ruby Through C Extensions\"\n  raw_title: \"[JA] Exploring Internal Ruby Through C Extensions / Emma Haruka Iwao @Yuryu\"\n  speakers:\n    - Emma Haruka Iwao\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"Om_cm120t1E\"\n  language: \"Japanese\"\n  description: |-\n    You may have wondered how Ruby objects are represented in the CRuby code. Not really? I would say writing a C extension is a great way to explore and learn how CRuby handles different object types. This session will re-implement our own Hash class, explain basic types in the CRuby, compare performance between native Hash, pure C++ implementation, and the C extension version, and discuss memory layouts and consumption in Ruby. The audience will also become more comfortable with the CRuby code through this session. Experience with C is not required.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/Yuryu\n\n- id: \"naotoshi-seo-rubykaigi-2018\"\n  title: \"Fast Numerical Computing and Deep Learning in Ruby with Cumo\"\n  raw_title: \"[JA] Fast Numerical Computing and Deep Learning in Ruby with Cumo / Naotoshi Seo @sonots\"\n  speakers:\n    - Naotoshi Seo\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-26\"\n  video_provider: \"youtube\"\n  video_id: \"osUvCcwMFnc\"\n  language: \"Japanese\"\n  description: |-\n    Ruby is far behind than other languages such as Python in scientific computing. One reason is because there is no fast numerical library in Ruby.\n\n    I have made a high speed numerical library for Ruby using CUDA named \"Cumo\". In this talk, I describe:\n\n    * Overview of Scientific Computing in Ruby\n    * Basic knowledge of GPU programming\n    * Cumo inside, such as\n      * Writing fast CUDA kernel\n      * Implementing GPU memory pool\n      * JIT compiling user-defined kernel\n    * Performance comparison with Numo in an emerging DNN framework written in Ruby, red-chainer\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/sonots\n\n- id: \"maciej-mensfeld-rubykaigi-2018\"\n  title: \"Karafka - Ruby Framework for Event Driven Architecture\"\n  raw_title: \"[EN] Karafka - Ruby Framework for Event Driven Architecture / Maciej Mensfeld  @maciejmensfeld\"\n  speakers:\n    - Maciej Mensfeld\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-28\"\n  video_provider: \"youtube\"\n  video_id: \"bzvb1u_kSro\"\n  language: \"English\"\n  description: |-\n    Karafka allows you to capture everything that happens in your systems in large scale, providing you with a seamless and stable core for consuming and processing this data, without having to focus on things that are not your business domain. Have you ever tried to pipe data from one application to another, transform it and send it back? Have you ever wanted to decouple for existing code base and make it much more resilient and flexible? Come and learn about Karafka, where it fits in your existing projects and how to use it as a messages backbone for a modern, distributed and scalable ecosystem.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/maciejmensfeld\n\n- id: \"hiroshi-shibata-rubykaigi-2018\"\n  title: \"RubyGems 3 & 4\"\n  raw_title: \"[JA] RubyGems 3 & 4 / Hiroshi SHIBATA @hsbt\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-28\"\n  video_provider: \"youtube\"\n  video_id: \"wuyhit3-_xA\"\n  language: \"Japanese\"\n  description: |-\n    The RubyGems is a mechanism to install libraries via the Internet without standard libraries. As maintenance manager of RubyGems and core member of Ruby core team, I'm working to merge the latest version of RubyGems with a latest stable version of ruby every year.\n\n    In this presentation, I will introduce the new feature of RubyGems 2.7 and describe the mechanism of integration with Bundler. Finally, I introduce a roadmap for RubyGems 3 and 4, which is developing for Ruby 2.6 and 3 release.\n\n    Through this talk, you will be able to enjoy the ruby world more by understanding RubyGems at the center of ruby's ecosystem.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/hsbt\n\n- id: \"masataka-kuwabara-rubykaigi-2018\"\n  title: \"A parser based syntax highlighter\"\n  raw_title: \"[JA] A parser based syntax highlighter / Masataka Kuwabara @p_ck_\"\n  speakers:\n    - Masataka Kuwabara\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-28\"\n  video_provider: \"youtube\"\n  video_id: \"8tarr2k0kMI\"\n  language: \"Japanese\"\n  description: |-\n    | It has an elegant syntax that is natural to read and easy to write.\n    | https://www.ruby-lang.org/en/\n\n    Definitely. The syntax is elegant. But it is too complex sometimes. So, syntax highlighters for Ruby are difficult and easy to break.\n    For example, probably your editor cannot correctly highlight `????::?:`, `% %s%% %%%%` or `def end(def:def def;end)end` (They are **valid** Ruby programs!).\n    Yeah, it is edge cases. In real cases, some syntax highlighter cannot correctly highlight a here document.\n\n    I'll talk a robust syntax highlighter for Ruby, it is Iro gem and Iro.vim.  The highlighter never break since it uses Ripper to highlight code.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/p_ck_\n\n- id: \"stan-lo-rubykaigi-2018\"\n  title: \"What would your own version of Ruby look like?\"\n  raw_title: \"[EN] What would your own version of Ruby look like? / Stan Lo @_st0012\"\n  speakers:\n    - Stan Lo\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-06-28\"\n  video_provider: \"youtube\"\n  video_id: \"ldqb5u4pQb0\"\n  language: \"English\"\n  description: |-\n    I believe most of us love Ruby, but I also believe most of us don't think Ruby is perfect. So what'd your own version of Ruby look like if you can create one?\n\n    As some of you may know, I created a language called Goby about a year ago. It's largely inspired by Ruby, and looks very similar to it. But it also have some design choices different than Ruby or have some unique features that Ruby doesn't have.\n\n    In this talk I'm going to discuss some important things we should focus on when designing a language. And I will al\n    so share the design choices made when developing Goby, as well as the philosophy behind these choices.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/_st0012\n\n- id: \"noah-gibbs-rubykaigi-2018\"\n  title: \"Faster Apps, No Memory Thrash: Get Your Memory Config Right\"\n  raw_title: \"[EN] Faster Apps, No Memory Thrash: Get Your Memory Config Right / Noah Gibbs @codefolio\"\n  speakers:\n    - Noah Gibbs\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-03\"\n  video_provider: \"youtube\"\n  video_id: \"Z4nBjXL-ymI\"\n  language: \"English\"\n  description: |-\n    The Ruby memory system can be tricky. Configuring it isn't easy. I'll show you a new simple tool to optimize your Ruby binary's memory settings.\n    You'll learn about the CRuby memory resources and how you check them. Let's optimize your memory usage to keep memory small and keep garbage collection fast.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/codefolio\n\n- id: \"koichi-sasada-rubykaigi-2018\"\n  title: \"Guild Prototype\"\n  raw_title: \"[EN] Guild Prototype / Koichi Sasada @ko1\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-03\"\n  video_provider: \"youtube\"\n  video_id: \"BO8ThL2H3tc\"\n  language: \"English\"\n  description: |-\n    RubyKaigi 2016, I proposed a new concurrency abstraction named Guild for Ruby 3.\n    Guild will achieve safe concurrency programming and parallel computation.\n    We are making prototype of Guild. This talk will introduce Guild concepts and evaluation with prototype of Guild.\n    Also we are discussing about the name of \"Guild\" to find out the another appropriate name. I will introduce the discussion of this \"naming battle\".\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/ko1\n\n- id: \"anton-davydov-rubykaigi-2018\"\n  title: \"Architecture of hanami applications\"\n  raw_title: \"[EN] Architecture of hanami applications / Anton Davydov @anton_davydov\"\n  speakers:\n    - Anton Davydov\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-03\"\n  video_provider: \"youtube\"\n  video_id: \"Rcbqa0QFXJQ\"\n  language: \"English\"\n  description: |-\n    The general part of any web application is business logic. Unforchanotly, it's really hard to find a framework with specific rules and explanations how to work with it. In hanami, we care about long-term maintenance that's why it's really important to us how to work with business logic.\n\n    In my talk, I'll share my ideas how to store and work with business logic in hanami apps. We will talk about hanami, dry and some architecture ideas, like event sourcing. This talk will be interesting for any developers. If you work with other frameworks you can take these ideas and my it to your project.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/anton_davydov\n\n- id: \"terence-lee-rubykaigi-2018\"\n  title: \"Controlling Droids™ with mruby & Go\"\n  raw_title: \"[EN] Controlling Droids™ with mruby & Go / Terence Lee  @hone02, Chase McCarthy @code0100fun\"\n  speakers:\n    - Terence Lee\n    - Chase McCarthy\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-03\"\n  video_provider: \"youtube\"\n  video_id: \"NhQovmLaHfY\"\n  language: \"English\"\n  description: |-\n    Ruby has never been at the forefront of dealing with robots, IoT, or other low level systems. What Ruby is great at is scripting and building DSLs. Using mruby we can leverage existing ecosystems while still using the language we love.\n\n    In this talk, we'll deep dive into how we can execute mruby handlers inside a Go event reactor to control a Sphero R2-D2. With surprisingly few lines of code, you can coordinate motors, lights, and sound concurrently. Come learn about mruby & robotics and see the Droids™ you're looking for in action.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/hone02\n\n- id: \"koichi-ito-rubykaigi-2018\"\n  title: \"Improve Ruby coding style rules and Lint\"\n  raw_title: \"[JA] Improve Ruby coding style rules and Lint / Koichi ITO @koic\"\n  speakers:\n    - Koichi ITO\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-03\"\n  video_provider: \"youtube\"\n  video_id: \"W4ZvpNpKWXo\"\n  language: \"Japanese\"\n  description: |-\n    This talk describes improving a Ruby coding style rules and Lint when using RuboCop.\n\n    Opportunities for using static analysis tools to unify coding style within a repository are not uncommon. However, the real world is not unified by the sole coding rule\n    . Even so, we can approach the coding rule that we think is better. I'd like to talk about that in this topic.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/koic\n\n- id: \"kirk-haines-rubykaigi-2018\"\n  title: \"It's Rubies All The Way Down\"\n  raw_title: \"[EN] It's Rubies All The Way Down / Kirk Haines @wyhaines\"\n  speakers:\n    - Kirk Haines\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-03\"\n  video_provider: \"youtube\"\n  video_id: \"_rwfsse7OYk\"\n  language: \"English\"\n  description: |-\n    Ruby is a language with expansive capabilities. One of it's main niches is with web application work. Typically, Ruby is used exclusively in the application container/application layer, with other technologies providing the rest of the stack. Ruby can fill other roles in the application stack, though, so for fun, let's explore a stack that is composed of Ruby software from top to bottom. What would that look like? How would it perform? Why would you do this?\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/wyhaines\n\n- id: \"edouard-chin-rubykaigi-2018\"\n  title: \"Journey of a complex gem upgrade\"\n  raw_title: \"[EN] Journey of a complex gem upgrade / Edouard Chin @Edouard-chin\"\n  speakers:\n    - Edouard Chin\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-03\"\n  video_provider: \"youtube\"\n  video_id: \"Lu5aHMxldmg\"\n  language: \"English\"\n  description: |-\n    Although every gem bump should be done carefully and with attention, most of the time it’s just a matter of running the `bundle update` command, look at the CHANGELOG, and maybe fix couple tests failing due to the upgrade.\n    But what about upgrading a gem whom introduced a lot of breaking changes in the new version?\n    The upgrade could cause hundreds if not thousands of your existing tests to fail.\n    In this talk I’d like to share the different techniques and strategies that will allow you to upgrade any dependency smoothy and safely.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/Edouard-chin\n\n- id: \"julian-nadeau-rubykaigi-2018\"\n  title: \"Scaling Teams using Tests for Productivity and Education\"\n  raw_title: \"[EN] Scaling Teams using Tests for Productivity and Education / Julian Nadeau @jules2689\"\n  speakers:\n    - Julian Nadeau\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-04\"\n  video_provider: \"youtube\"\n  video_id: \"InFnu8bYi6s\"\n  language: \"English\"\n  description: |-\n    As Ruby organizations scale, more developers join the team. More developers makes it increasingly difficult to enforce code styles, follow best practices, and document\n    mistakes that were made without relying on word of mouth. While we have tools, such as Rubocop, to check some stylistic components, we lack tooling to document issues and best practices. This talk focuses on strategies and solutions, particularly around best practices, that we employ to help educate and accelerate nearly a thousand developers, without getting in their way, by providing them information “just in time”.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/jules2689\n\n- id: \"yurie-yamane-rubykaigi-2018\"\n  title: \"mruby can be more lightweight\"\n  raw_title: \"[JA] mruby can be more lightweight / Yurie Yamane @yuri_at_earth\"\n  speakers:\n    - Yurie Yamane\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-04\"\n  video_provider: \"youtube\"\n  video_id: \"sFz5-xGTEbI\"\n  language: \"Japanese\"\n  description: |-\n    mruby is called “lightweight Ruby”, but in fact it consumes rather much RAM memory.\n    In this talk, I will explain a proposal of implementation to use ROM instead of RAM.  In addition, I will talk about some configurations for reducing RAM usage.\n    I also demonstrate using an evaluation board (RAM:96 KB) which became available as a result of reducing RAM usage.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/yuri_at_earth\n\n- id: \"hitoshi-hasumi-rubykaigi-2018\"\n  title: \"Firmware programming with mruby/c\"\n  raw_title: \"[JA] Firmware programming with mruby/c / Hitoshi HASUMI @hasumon\"\n  speakers:\n    - HASUMI Hitoshi\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-04\"\n  video_provider: \"youtube\"\n  video_id: \"ng0N0761N3c\"\n  language: \"Japanese\"\n  description: |-\n    We have a new choice to write firmware for microcomputers(microcontrollers). It's mruby/c.\n    This talk shows how to introduce mruby/c firmware programming. And besides, my actual IoT project for Japanese Sake brewery will be described.\n    Since mruby/c is still a young growing tool, you will know there are several(many?) things you can help it to become better.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/hasumon\n\n- id: \"masatoshi-seki-rubykaigi-2018\"\n  title: \"extend your own programming language\"\n  raw_title: \"[JA] extend your own  programming language / Masatoshi SEKI @m_seki\"\n  speakers:\n    - Masatoshi SEKI\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-04\"\n  video_provider: \"youtube\"\n  video_id: \"FXELyEXajD4\"\n  language: \"Japanese\"\n  description: |-\n    書籍「RubyでつくるRuby」はRubyの（極小の）サブセットMinRubyをRubyで実装しながら、Rubyとプログラミング言語とインタプリタを学ぶ本です。入門者にとって、フルセットのRubyを\n    改造するのはちょっと難しいですが、MinRubyのサイズならちょうどよい教材です。MinRubyを拡張し自分の言語を作ることで得られる万能感は格別です。\n    本講演では、MinRubyを拡張してRuby自体に新しい機能を追加する例を紹介します。末尾呼び出し最適化、実行コンテキストの別プロセスへ移送、変数操作のフックなど、ライブラリだけ\n    で実装するのは難しいRubyの変種を示します。\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/m_seki\n\n- id: \"soutaro-matsumoto-rubykaigi-2018\"\n  title: \"Ruby Programming with Type Checking\"\n  raw_title: \"[EN] Ruby Programming with Type Checking / Soutaro Matsumoto @soutaro\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-04\"\n  video_provider: \"youtube\"\n  video_id: \"QK_v0XN8kXc\"\n  language: \"English\"\n  description: |-\n    Last year, I had a presentation to introduce Steep, a type checker for Ruby. However, the implementation is so experimental that it cannot be used for production at all.\n    In this talk, I will report the nine months progress of the project and share the experience how the tool helps Ruby programming.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/soutaro\n\n- id: \"sameer-deshmukh-rubykaigi-2018\"\n  title: \"Ferrari Driven Development: superfast Ruby with Rubex\"\n  raw_title: \"[EN] Ferrari Driven Development: superfast Ruby with Rubex / Sameer Deshmukh @v0dro\"\n  speakers:\n    - Sameer Deshmukh\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-04\"\n  video_provider: \"youtube\"\n  video_id: \"7edbdHZvr8k\"\n  language: \"English\"\n  description: |-\n    Did you ever really really want to speed up your Ruby code with C extensions but got baffled by mountains of documentation and scary C programming and chose to move to another language instead? Did you wish that you could just release that GIL and extract all the juice that your processor has to offer without losing your hair? If yes, then come see this talk!\n\n    This talk will introduce you to Rubex, the fastest and happiest way of writing Ruby C extensions. Rubex is a whole new language designed from the ground up keeping in mind Ruby's core philosophy - make programmers happy.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/v0dro\n\n- id: \"vladimir-dementyev-rubykaigi-2018\"\n  title: \"One cable to rule them all\"\n  raw_title: \"[EN] One cable to rule them all / Vladimir Dementyev @palkan_tula\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-06\"\n  video_provider: \"youtube\"\n  video_id: \"jXCPuNICT8s\"\n  language: \"English\"\n  slides_url: \"https://speakerdeck.com/palkan/rubykaigi-2018-anycable-one-cable-to-rule-them-all\"\n  description: |-\n    Modern web applications actively use real-time features. Unfortunately, nowadays Ruby is rarely considered as a technology to implement yet another chat – Ruby performance leaves much to be desired when dealing with concurrency and high-loads.\n\n    Does this mean that we should betray our favorite language, which brings us happiness, in favor of others?\n\n    My answer is NO, and I want to show you, how we can combine the elegance of Ruby with the power of other languages to improve the performance of real-time applications.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/palkan_tula\n\n- id: \"yuichiro-kaneko-rubykaigi-2018\"\n  title: \"RNode with code positions\"\n  raw_title: \"[JA] RNode with code positions / Yuichiro Kaneko @spikeolaf\"\n  speakers:\n    - Yuichiro Kaneko\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-06\"\n  video_provider: \"youtube\"\n  video_id: \"YjmBJg52aws\"\n  language: \"Japanese\"\n  description: |-\n    This talk describes about code positions on Ruby.\n\n    Code positions are new location information of AST Nodes, introduced from Ruby 2.5.\n    Code positions enable us to improve warning messages, exception messages, `Proc#source_location` and so on.\n\n    This talk includes the following topics.\n\n    * What code positions are.\n    * Why they are needed.\n    * How they are implemented.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/spikeolaf\n\n- id: \"yusuke-endoh-rubykaigi-2018\"\n  title: \"TRICK 2018 (FINAL)\"\n  raw_title: \"[JA] TRICK 2018 (FINAL) / mame & the judges\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-06\"\n  video_provider: \"youtube\"\n  video_id: \"TB-nmGG6uu0\"\n  language: \"Japanese\"\n  description: |-\n    The 3rd (FINAL) Transcendental Ruby Imbroglio Contest for RubyKaigi\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/tric\n\n- id: \"thiago-scalone-rubykaigi-2018\"\n  title: \"20k MRuby devices in production\"\n  raw_title: \"[EN] 20k MRuby devices in production / Thiago Scalone @scalone\"\n  speakers:\n    - Thiago Scalone\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-06\"\n  video_provider: \"youtube\"\n  video_id: \"vMjT2DqV_vw\"\n  language: \"English\"\n  description: |-\n    I've changed an entire solid runtime for mRuby, and for 3 years, even if is not recommend, we've been runnin\n    g mRuby in production reaching 20k machines and billons of dollars in payment transactions. We faced a lot o\n    f problems, but even more benefits adopting mRuby. This talk is about those topics, like:\n\n    - Runtime and application Update/Upgrade\n    - Communication configuration and intelligence\n    - Payment transaction security and cryptography\n    - Concurrency\n    - Code sharing between CRuby and mRuby\n    - Memory management and leaks\n    - Open Source\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/scalone\n\n- id: \"uchio-kondo-rubykaigi-2018\"\n  title: \"How Ruby Survives in the Cloud Native World\"\n  raw_title: \"[EN] How Ruby Survives in the Cloud Native World / Uchio KONDO @udzura\"\n  speakers:\n    - Uchio KONDO\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-06\"\n  video_provider: \"youtube\"\n  video_id: \"7Anlio4nnng\"\n  language: \"English\"\n  description: |-\n    The container orchestration technology is attracting the Ops/SRE's attention along with the gaining importance of microservices and server-less architecture. But in my opinion, around these \"cloud-native\" development\n    s, the Ruby language shows smaller activities than other younger languages(especially Go and Rust).\n    By the way, in 2016, I created a container runtime Haconiwa with mruby. In 2017, I also scratched up the containers platform for my company's web hosting service using Ruby and mruby in many components. Here in 2018,\n     I'm going to create the brand-new container orchestration tool fully implemented in Ruby and mruby.\n    I will talk about how I used Ruby and mruby in these container and orchestration implementations.  In addition, I will show my opinion about what kind of Ruby's features are good for these implementations, and what kind of features are required for cloud-native Ruby.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/udzura\n\n- id: \"genadi-samokovarov-rubykaigi-2018\"\n  title: \"Implementing Web Console\"\n  raw_title: \"[EN] Implementing Web Console / Genadi Samokovarov @gsamokovarov\"\n  speakers:\n    - Genadi Samokovarov\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-06\"\n  video_provider: \"youtube\"\n  video_id: \"OCjc0RH5epY\"\n  language: \"English\"\n  description: |-\n    Web Console is a debugging tool bundled with Rails. The most popular feature is a console that is shown in every development error, however, it is a general purpose debugging tool that let you execute Ruby code in any binding as it runs, through its web UI.\n\n    In this talk, we'll take a look at how the web-console gem is implemented. This includes a deep dive into how exceptions in Ruby work; how to build Ruby bindings for every part of an exception backtrace, so we can execute code in them; how we interact with the DebugInspector and TracePoint C APIs to make this possible and how we supported alternative Ruby implementations like JRuby.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/gsamokovarov\n\n- id: \"yusuke-endoh-rubykaigi-2018-type-profiler-an-analysis-to-g\"\n  title: \"Type Profiler: An analysis to guess type signatures\"\n  raw_title: \"[JA] Type Profiler: An analysis to guess type signatures / Yusuke Endoh @mametter\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-06\"\n  video_provider: \"youtube\"\n  video_id: \"U6mKwwO7QCg\"\n  language: \"Japanese\"\n  description: |-\n    After matz set Ruby 3 goals including static analysis, its requirements (and compromises) have been revealed gradually.  We review the current status as far as we know, briefly survey some existing proposals and implementations related to type checking for Ruby, and clarify what is good and what is missing.\n\n    Based on this survey, we prototype a type profiler, one of the missing parts for Ruby type checking system.\n     A type profiler analyzes existing Ruby programs statically and dynamically, and creates a stub of type definitions.  We discuss its design and show some experiment results.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/mametter\n\n- id: \"dmitry-petrashko-rubykaigi-2018\"\n  title: \"A practical type system for Ruby at Stripe\"\n  raw_title: \"[EN] A practical type system for Ruby at Stripe. @DarkDimius @ptarjan @nelhage\"\n  speakers:\n    - Dmitry Petrashko\n    - Paul Tarjan\n    - Nelson Elhage\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-11\"\n  video_provider: \"youtube\"\n  video_id: \"eCnnBS2LXcI\"\n  language: \"English\"\n  description: |-\n    Slides: https://sorbet.run/talks/RubyKaigi2018/\n\n    At Stripe, we believe that a typesystem provides substantial benefits for a big codebase. They :\n\n    - are documentation that is always kept up-to-date;\n    - speed up the development loop via faster feedback from tooling;\n    - help discover corner cases that are not handled by the happy path;\n    - allow building tools that expose knowledge obtained through type-checking, such as \"jump to definition\".\n\n    We have built a type system that is currently being adopted by our Ruby code at Stripe. This typesystem can be adopted gradually with different teams and projects adopting it at a different pace. We support And and OrTypes as well as basic generics. Our type syntax that is backwards compatible with untyped ruby.\n\n    In this talk we describe our experience in developing and adopting a type system for our multi-million line ruby codebase. We will also discuss what future tools are made possible by having knowledge about types in the code base.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/DarkDimius\n\n- id: \"thibaut-barrre-rubykaigi-2018\"\n  title: \"Kiba 2 - Past, present & future of data processing with Ruby\"\n  raw_title: \"[EN]Kiba 2 - Past, present & future of data processing with Ruby Thibaut Barrère @thibaut_barrere\"\n  speakers:\n    - Thibaut Barrère\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2018-07-11\"\n  video_provider: \"youtube\"\n  video_id: \"fxVtbog7pIQ\"\n  language: \"English\"\n  description: |-\n    Kiba ETL (http://www.kiba-etl.org) is a lightweight, generic data processing framework for Ruby, initially released in 2015 & now in v2.\n\n    In this talk, I'll highlight why Kiba was created, how it is used for low-maintenance data preparation and processing in the enterprise (illustrated by many different use cases), why and how the version 2 (leveraging Ruby's Enumerator) brings a massive improvement in authoring reusable & composable data processing components, and why I'm optimistic about the future of data processing with Ruby.\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/thibaut_barrere\n\n- id: \"ruby-committers-rubykaigi-2018\"\n  title: \"Ruby Committers vs the World\"\n  raw_title: \"[JA] Ruby Committers vs the World / CRuby Committers\"\n  speakers:\n    - Ruby Committers # TODO: list each person\n  event_name: \"RubyKaigi 2018\"\n  date: \"2018-05-31\"\n  published_at: \"2019-02-11\"\n  video_provider: \"youtube\"\n  video_id: \"dhHAaybjCfE\"\n  language: \"Japanese\"\n  description: |-\n    Ruby core committers on stage!\n\n    RubyKaigi 2018 https://rubykaigi.org/2018/presentations/rubylangorg\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2019/event.yml",
    "content": "---\nid: \"PLbFmgWm555yYc9_jx9HkS_1WkOLKWnRw3\"\ntitle: \"RubyKaigi 2019\"\nkind: \"conference\"\nlocation: \"Fukuoka, Japan\"\ndescription: \"\"\npublished_at: \"2019-05-13\"\nstart_date: \"2019-04-18\"\nend_date: \"2019-04-20\"\nchannel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\nyear: 2019\nbanner_background: \"#1F1548\"\nfeatured_background: \"#1F1548\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubykaigi.org/2019/\"\ncoordinates:\n  latitude: 33.6047206\n  longitude: 130.4036164\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2019/venue.yml",
    "content": "# https://rubykaigi.org/2019/venue\n---\nname: \"Fukuoka International Congress Center\"\n\naddress:\n  street: \"\"\n  city: \"Fukuoka\"\n  region: \"Fukuoka\"\n  postal_code: \"812-0032\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"2-1 Sekijōmachi, Hakata Ward, Fukuoka, 812-0032, Japan\"\n\ncoordinates:\n  latitude: 33.6047206\n  longitude: 130.4036164\n\nmaps:\n  google: \"https://maps.google.com/?q=Fukuoka+International+Congress+Center,33.6047206,130.4036164\"\n  apple: \"https://maps.apple.com/?q=Fukuoka+International+Congress+Center&ll=33.6047206,130.4036164\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=33.6047206&mlon=130.4036164\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2019/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"urabe-shyouhei-rubykaigi-2019\"\n  title: \"The send-pop optimisation\"\n  raw_title: \"[JA] The send-pop optimisation / Urabe, Shyouhei @shyouhei\"\n  speakers:\n    - Shyouhei Urabe\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-14\"\n  video_provider: \"youtube\"\n  video_id: \"rH81nlm1lcE\"\n  language: \"Japanese\"\n  description: |-\n    \"Sending a method to an object, then discarding its return value immediately\" is one of the most frequent operations that ruby does. By eliminating such wastes of time and memory, ruby execution could be much more efficient. I will share you some stories and outcomes of my journey trying to optimise that part.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/shyouhei.html#apr20\n\n- id: \"jake-zimmerman-rubykaigi-2019\"\n  title: \"State of Sorbet: A Type Checker for Ruby\"\n  raw_title: \"[EN] State of Sorbet: A Type Checker for Ruby / Jake Zimmerman @jez, Paul Tarjan @ptarjan\"\n  speakers:\n    - Jake Zimmerman\n    - Paul Tarjan\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-12\"\n  video_provider: \"youtube\"\n  video_id: \"odmlf_ezsBo\"\n  language: \"English\"\n  description: |-\n    We have developed a typesystem for Ruby at Stripe with a goal of helping developers understand code better, write code with more confidence, and detect+prevent significant classes of bugs.\n\n    This talk shares experience of Stripe successfully adopting Sorbet in our codebase which had millions lines of code that were written before the typechecker had been conceived. The talk will describe: - the process used to add typing to existing code; - many tools developed to support this process; - impact of this type system on safety and productivity at Stripe.\n\n    We also have some exciting announcements!\n    The talk does not require any previous knowledge of types and should be accessible to a broad audience.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/jez.html#apr19\n\n- id: \"ruby-committers-rubykaigi-2019\"\n  title: \"Ruby Committers vs the World\"\n  raw_title: \"[JA|EN] Ruby Committers vs the World\"\n  speakers:\n    - Ruby Committers # TODO: list each person\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-14\"\n  video_provider: \"youtube\"\n  video_id: \"5eAXAUTtNYU\"\n  language: \"Japanese\"\n  description: |-\n    Ruby core committers on stage!\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/rubylangorg.html#apr20\n\n- id: \"kazuki-tsujimoto-rubykaigi-2019\"\n  title: \"Pattern matching - New feature in Ruby 2.7\"\n  raw_title: \"[JA] Pattern matching - New feature in Ruby 2.7 / Kazuki Tsujimoto @k_tsj\"\n  speakers:\n    - Kazuki Tsujimoto\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-12\"\n  video_provider: \"youtube\"\n  video_id: \"paBlgsqoKk8\"\n  language: \"Japanese\"\n  description: |-\n    Ruby core team plans to introduce pattern matching as an experimental feature in Ruby 2.7. In this presentation, we will talk about the current proposed syntax and its design policy.\n\n    https://rubykaigi.org/2019/presentations/k_tsj.html#apr18\n\n- id: \"soutaro-matsumoto-rubykaigi-2019\"\n  title: \"The challenges behind Ruby type checking\"\n  raw_title: \"[JA] The challenges behind Ruby type checking / Soutaro Matsumoto @soutaro\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-14\"\n  video_provider: \"youtube\"\n  video_id: \"7N-QOx6cVI4\"\n  language: \"Japanese\"\n  description: |-\n    Static type checking for Ruby is challenging because the language is dynamically typed. What exactly is the source of the difficulty? You might think of duck typing or defime_method? Totally! But not only them are the reason. In fact, only a few lines of typical and innocent looking Ruby code can make type checking much more complicated than you assume.\n\n    This talk is about the difficulties and type system extensions to make the type checking possible. Static type checking is not easy and requires unfamiliar type system features, but we can do that.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/soutaro.html#apr20\n\n- id: \"samuel-williams-rubykaigi-2019\"\n  title: \"Fibers Are the Right Solution\"\n  raw_title: \"[EN] Fibers Are the Right Solution / Samuel Williams @ioquatix\"\n  speakers:\n    - Samuel Williams\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-12\"\n  video_provider: \"youtube\"\n  video_id: \"qKQcUDEo-ZI\"\n  language: \"English\"\n  description: |-\n    The majority of performance improvements in modern processors are due to increased core count rather than increased instruction execution frequency. To maximise hardware utilization, applications need to use multiple processes and threads. Servers that process discrete requests are a good candidate for both parallelization and concurrency improvements. We discuss different ways in which servers can improve processor utilization and how these different approaches affect application code. We show that fibers require minimal changes to existing application code and are thus a good approach for retrofitting existing systems.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/ioquatix.html#apr18\n\n- id: \"sam-phippen-rubykaigi-2019\"\n  title: \"How RSpec works\"\n  raw_title: \"[EN] How RSpec works / Sam Phippen @samphippen\"\n  speakers:\n    - Sam Phippen\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-12\"\n  video_provider: \"youtube\"\n  video_id: \"B8yKlTNlY5E\"\n  language: \"English\"\n  description: |-\n    RSpec is a much beloved series of libraries, currently holding spots 1, 2, 4, 5, and 6 in terms of most downloaded gems. Many of us use it every day, but the question is, how does it work?\n\n    In this talk, you will learn about how RSpec executes your tests, the anatomy of an expect(...).to ... expression, and how stubs and mocks work. You'll learn deeply about the behind the scenes architecture of RSpec. This talk is quite technical, and a fair amount of Ruby knowledge is assumed.\n\n- id: \"nagachika-rubykaigi-2019\"\n  title: \"Keynote: All bugfixes are incompatibilities\"\n  raw_title: \"[JA][Keynote] All bugfixes are incompatibilities / @nagachika\"\n  speakers:\n    - Tomoyuki Chikanaga\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-07\"\n  video_provider: \"youtube\"\n  video_id: \"g_wPQzNlu9Q\"\n  language: \"Japanese\"\n  description: |-\n    https://rubykaigi.org/2019/presentations/nagachika.html#apr19\n\n- id: \"takashi-kokubun-rubykaigi-2019\"\n  title: \"Performance Improvement of Ruby 2.7 JIT in Real World\"\n  raw_title: \"[JA] Performance Improvement of Ruby 2.7 JIT in Real World / Takashi Kokubun @k0kubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-12\"\n  video_provider: \"youtube\"\n  video_id: \"bz-sy5b2EXY\"\n  language: \"Japanese\"\n  description: |-\n    Ruby 2.6's JIT was known to make a Rails application slower, while it achieved a good progress on some other benchmarks.\n    Will that be beneficial for your application in Ruby 2.7? How many times will it make Rails faster? How much additional memory will it consume? Come to the talk and figure it out.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/k0kubun.html#apr18\n\n- id: \"hiromasa-ishii-rubykaigi-2019\"\n  title: \"intimate Chat with Matz and mruby developers about mruby\"\n  raw_title: \"[JA] intimate Chat with Matz and mruby developers about mruby / Hiromasa Ishii @Hir0_IC\"\n  speakers:\n    - Hiromasa Ishii\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-12\"\n  video_provider: \"youtube\"\n  video_id: \"Mf4v3u6tgOk\"\n  language: \"Japanese\"\n  description: |-\n    Talk about mruby's development confidential stories, current situation, and future of mruby with Yukihio \"Matz\" Matsumoto creator of the mruby programming language.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/Hir0_IC.html#apr19\n\n- id: \"yurie-yamane-rubykaigi-2019\"\n  title: \"(partially) Non-volatile mruby\"\n  raw_title: \"[JA] (partially) Non-volatile mruby / Yurie Yamane @yuri_at_earth, Masayoshi Takahashi @takahashim\"\n  speakers:\n    - Yurie Yamane\n    - Masayoshi Takahashi\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-14\"\n  video_provider: \"youtube\"\n  video_id: \"N-TGgiNp5u0\"\n  language: \"Japanese\"\n  description: |-\n    In RubyKaigi 2018, I talked about basic idea of putting mruby on ROM. But there’s still some objects consuming RAM, such as IREP structure and libraries defined in Ruby. In this session, I will give another solution for the problem to put more structures into ROM. Moreover, I will explain about the change of implementation of instance variables and Hash class in mruby 2.0, and the effect of memory consumption.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/yuri_at_earth.html#apr20\n\n- id: \"koichi-sasada-rubykaigi-2019\"\n  title: \"Write a Ruby interpreter in Ruby for Ruby 3\"\n  raw_title: \"[EN] Write a Ruby interpreter in Ruby for Ruby 3 / Koichi Sasada @ko1\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-12\"\n  video_provider: \"youtube\"\n  video_id: \"PZDhXPgt98U\"\n  language: \"English\"\n  description: |-\n    Ruby interpreter called MRI (Matz Ruby Interpreter) or CRuby is written in C language. Writing an interpreter in C has several advantages, such as performance at early development, extensibility in C language and so on. However, now we have several issues because of writing MRI in C. To overcome this issue, I propose to rewrite some part of MRI in Ruby language with C functions. It will be a base of Ruby 3 (or Ruby 2.7). In this talk, I'll show the issues and how to solve them with writing Ruby, how to write MRI internal in Ruby and how to build an interpreter with Ruby code.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/ko1.html#apr18\n\n- id: \"lightning-talks-rubykaigi-2019\"\n  title: \"Lightning Talks\"\n  raw_title: \"[JA|EN] Lightning Talks\"\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-12\"\n  video_provider: \"youtube\"\n  video_id: \"B2NTL_J62JE\"\n  description: |-\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/lt/\n  talks:\n    - title: \"Lightning Talk: How does TruffleRuby work\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"naoki-kishida-lighting-talk-rubykaigi-2019\"\n      video_id: \"naoki-kishida-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Naoki Kishida\n      # language: TODO\n\n    - title: \"Lightning Talk: Invitation to Dark Side of Ruby\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"satoshi-moris-tagomori-lighting-talk-rubykaigi-2019\"\n      video_id: \"satoshi-moris-tagomori-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Satoshi \"moris\" Tagomori\n      # language: TODO\n\n    - title: \"Lightning Talk: Automatic Differentiation for Ruby\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"lin-yu-hsiang-lighting-talk-rubykaigi-2019\"\n      video_id: \"lin-yu-hsiang-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Lin Yu Hsiang\n      # language: TODO\n\n    - title: \"Lightning Talk: From Emperors to Zombies: Ruby from Unicode 10 to 12.1\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"martin-j-durst-lighting-talk-rubykaigi-2019\"\n      video_id: \"martin-j-durst-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Martin J. Dürst\n      # language: TODO\n\n    - title: \"Lightning Talk: From ㍻ to U+32FF\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"mitsubosh-lighting-talk-rubykaigi-2019\"\n      video_id: \"mitsubosh-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - MITSUBOSH\n      # language: TODO\n\n    - title: \"Lightning Talk: Dive into middleware with mruby\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"yuichiro-kaneko-lighting-talk-rubykaigi-2019\"\n      video_id: \"yuichiro-kaneko-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Yuichiro Kaneko\n      # language: TODO\n\n    - title: \"Lightning Talk: VXLAN VTEPs with Ruby\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"sorah-fukumori-lighting-talk-rubykaigi-2019\"\n      video_id: \"sorah-fukumori-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Sorah Fukumori\n      # language: TODO\n\n    - title: \"Lightning Talk: Write ETL or ELT data processing jobs with bricolage.\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"hiroyuki-inoue-lighting-talk-rubykaigi-2019\"\n      video_id: \"hiroyuki-inoue-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Hiroyuki Inoue\n      # language: TODO\n\n    - title: \"Lightning Talk: Applying mruby to World-first Small SAR Satellite\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"shunsuke-onishi-lighting-talk-rubykaigi-2019\"\n      video_id: \"shunsuke-onishi-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Shunsuke Onishi\n      # language: TODO\n\n    - title: \"Lightning Talk: How to Make Bad Source\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"oda-hirohito-lighting-talk-rubykaigi-2019\"\n      video_id: \"oda-hirohito-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - ODA Hirohito\n      # language: TODO\n\n    - title: \"Lightning Talk: The TracePoint Bomb!\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"koichi-ito-lighting-talk-rubykaigi-2019\"\n      video_id: \"koichi-ito-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Koichi ITO\n      # language: TODO\n\n    - title: \"Lightning Talk: Make Ruby Differentiable\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"nagachika-lighting-talk-rubykaigi-2019\"\n      video_id: \"nagachika-lighting-talk-rubykaigi-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomoyuki Chikanaga\n      # language: TODO\n\n- id: \"vladimir-makarov-rubykaigi-2019\"\n  title: \"A light weight JIT compiler project for CRuby\"\n  raw_title: \"[EN] A light weight JIT compiler project for CRuby / Vladimir Makarov @vnmakarov\"\n  speakers:\n    - Vladimir Makarov\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-12\"\n  video_provider: \"youtube\"\n  video_id: \"FdWLXKvZ6Gc\"\n  language: \"English\"\n  description: |-\n    JITs based on GCC/LLVM as recently introduced CRuby MJIT might be heavy and slow for some environments and applications. CRuby MJIT needs two tier compilation with a light weight compiler used as a tier 1 JIT compiler.\n\n    This talk will be about the light weight JIT compiler project for CRuby MJIT. The talk will cover the project motivations, current and future state of the project.\n\n- id: \"giovanni-sakti-rubykaigi-2019\"\n  title: \"Pathfinder - Building a Container Platform in Ruby Ecosystem\"\n  raw_title: \"[EN] Pathfinder - Building a Container Platform in Ruby Ecosystem / Giovanni Sakti @giosakti\"\n  speakers:\n    - Giovanni Sakti\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-14\"\n  video_provider: \"youtube\"\n  video_id: \"AhBds1xGT94\"\n  language: \"English\"\n  description: |-\n    This session will discuss about an attempt to build container platform in ruby/mruby ecosystem, the current situation and lesson-learned that we can discern to improve it further.\n\n    Further on, for those whom are unfamiliar, this session will also touch a bit about container platform/orchestrator and the generic architecture behind it. So that as a developer, we understand the abstraction that it provides.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/giosakti.html#apr18\n\n- id: \"jeremy-evans-rubykaigi-2019\"\n  title: \"Keynote: Optimization Techniques Used by the Benchmark Winners\"\n  raw_title: \"[EN][Keynote] Optimization Techniques Used by the Benchmark Winners / Jeremy Evans @jeremyevans0\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-07\"\n  video_provider: \"youtube\"\n  video_id: \"RuGZCcEL2F8\"\n  language: \"English\"\n  description: |-\n    Sequel and Roda have dominated TechEmpower's independent benchmarks for Ruby web frameworks for years. This presentation will discuss optimizations that Sequel and Roda use, and how to use similar approaches to improve the performance of your own code.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/jeremyevans0.html#apr20\n\n- id: \"yusuke-endoh-rubykaigi-2019\"\n  title: \"A Type-level Ruby Interpreter for Testing and Understanding\"\n  raw_title: \"[JA] A Type-level Ruby Interpreter for Testing and Understanding / Yusuke Endoh @mametter\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-12\"\n  video_provider: \"youtube\"\n  video_id: \"2oDBKrPYEu8\"\n  language: \"Japanese\"\n  description: |-\n    We propose a type-level abstract interpreter for Ruby 3's static analysis. This interpreter runs normal (i.e., non-type-annotated) Ruby programs in \"type\" level: each variable has only a type instead of a value. It reports a possible type-error bug, e.g., attempting to call a unknown method or to pass an invalid type argument during the interpretation. By recording all method definitions and calls, it also creates a summary of the program structure in type signature format. This is useful to understand the code, and can be also used as a prototype of type definition for external type checkers.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/mametter.html#apr18\n\n- id: \"tanaka-akira-rubykaigi-2019\"\n  title: \"What is Domain Specific Language?\"\n  raw_title: \"[JA] What is Domain Specific Language? / Tanaka Akira @tanaka_akr\"\n  speakers:\n    - Tanaka Akira\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"9S6RK0AGzng\"\n  language: \"Japanese\"\n  description: |-\n    Ruby is known as a good language for DSL (Domain Specific Language). However, it is unclear what differentiate internal DSL and normal library. This presentation tries to explain the difference. Both DSL and normal library solves part of programmers task. They tries to make programming easier. However, DSL tends to use some kind of black magic unlike normal library. The black magic is used to realize succinct and easy-to-read program for many applications in the domain. I hope this presentation makes programmers aware to design good library.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/tanaka_akr.html#apr19\n\n- id: \"shizuo-fujita-rubykaigi-2019\"\n  title: \"RMagick, migrate to ImageMagick 7\"\n  raw_title: \"[JA] RMagick, migrate to ImageMagick 7 / Shizuo Fujita @watson1978\"\n  speakers:\n    - Shizuo Fujita\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"Wt9eR8sj9s8\"\n  language: \"Japanese\"\n  description: |-\n    The currently RMagick has some problems about installing on macOS/Windows platform. I will talk about RMagick that it will be migrated from ImageMagick 6 to 7 and it will be solved the problems.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/watson1978.html#apr18\n\n- id: \"shugo-maeda-rubykaigi-2019\"\n  title: \"Terminal curses\"\n  raw_title: \"[JA] Terminal curses / Shugo Maeda @shugomaeda\"\n  speakers:\n    - Shugo Maeda\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"67M6Deo2aTw\"\n  language: \"Japanese\"\n  description: |-\n    Terminal programming with curses is useful and fun, but it sometimes brings terminal curses.\n\n    This talk shows basics of terminals (e.g., real text terminals, terminal emulators, the controlling terminal, /dev/tty and con, pty, control characters, escape sequences, termcap/terminfo, terminal mode), pros and cons of text-based user interfaces, an introduction to curses.gem, its applications, and issues you'll face when programming with curses.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/shugomaeda.html#apr19\n\n- id: \"naotoshi-seo-rubykaigi-2019\"\n  title: \"Red Chainer and Cumo: Practical Deep Learning in Ruby\"\n  raw_title: \"[JA] Red Chainer and Cumo: Practical Deep Learning in Ruby / @sonots, @hatappi\"\n  speakers:\n    - Naotoshi Seo\n    - Yusaku Hatanaka\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-28\"\n  video_provider: \"youtube\"\n  video_id: \"PdHcIn51B7Y\"\n  language: \"Japanese\"\n  description: |-\n    Naotoshi Seo @sonots, Yusaku Hatanaka @hatappi\n\n    We will introduce Red Chainer which is a deep learning framework purely written in Ruby and Cumo which is GPU aware fast numerical library for Ruby, and talk about their evolutions.\n\n    In this talk, we describe:\n\n    Current status about Deep Learning and Scientific Computing in Ruby.\n    Introduction about Red Chainer project.\n    Introduction of the ONNX data format, and automatic generation of Ruby codes by supporting ONNX with Red Chainer.\n    Introduction about Cumo project, and its support in Red Chainer.\n    Recent updates about supporting Fast Convolutional Neural Networks in Red Chainer.\n    Also, @sonots talks about ChainerX and a plan to make a further faster deep learning with its ruby bindings.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/sonots.html#apr20\n\n- id: \"sadayuki-furuhashi-rubykaigi-2019\"\n  title: \"Performance Optimization Techniques of MessagePack-Ruby\"\n  raw_title: \"[JA] Performance Optimization Techniques of MessagePack-Ruby / Sadayuki Furuhashi @frsyuki\"\n  speakers:\n    - Sadayuki Furuhashi\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-28\"\n  video_provider: \"youtube\"\n  video_id: \"yn5mEH8dUIY\"\n  language: \"Japanese\"\n  description: |-\n    Performance Optimization Techniques of MessagePack-Ruby\n    MessagePack is known as one of the world's fastest object serialization formats available with compatibility to JSON. MessagePack is fast not just because of its binary format but also because of VERY optimized implementations crafted by enthusiasts for each programming languages. To be the fastest serialization library for Ruby, MessagePack-Ruby implements various performance optimization techniques. This session explains the techniques with numbers and discusses further possible optimizations.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/frsyuki.html#apr20\n\n- id: \"nobuyoshi-nakada-rubykaigi-2019\"\n  title: \"Timezone API\"\n  raw_title: \"[JA] Timezone API / nobu @n0kada\"\n  speakers:\n    - Nobuyoshi Nakada\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-28\"\n  video_provider: \"youtube\"\n  video_id: \"AjQUCWeh9sQ\"\n  language: \"Japanese\"\n  description: |-\n    The Time, a core class, supports timezone since Ruby 2.6. This talk will give what the API is, and how it is determined to cooperate with existing external libraries.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/n0kada.html#apr20\n\n- id: \"itoyanagi-sakura-rubykaigi-2019\"\n  title: \"Terminal Editors For Ruby Core Toolchain\"\n  raw_title: \"[EN] Terminal Editors For Ruby Core Toolchain / ITOYANAGI Sakura @aycabta\"\n  speakers:\n    - ITOYANAGI Sakura\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-14\"\n  video_provider: \"youtube\"\n  video_id: \"8l1ep4nN_KQ\"\n  language: \"English\"\n  description: |-\n    I implemented \"Reline\" that is a compatibility library with \"readline\" stdlib by pure Ruby and works correctly without GNU Readline and works on Windows too.\n\n    \"Reidline\" is authored for new IRB by keiju-san who is Ruby's grandfather, it behaves as a multiline editor like JavaScript console on browsers. It had many technical problems but I've already solved that when I implemented Reline. So I helped to complete Reidline.\n\n    These are highlights of Ruby 2.7. I'll talk about the technical problems of these and show a demo on Ruby 2.7.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/aycabta.html#apr18\n\n- id: \"justin-searls-rubykaigi-2019\"\n  title: \"The Selfish Programmer\"\n  raw_title: \"[EN] The Selfish Programmer / Justin Searls @searls\"\n  speakers:\n    - Justin Searls\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"LVe0g91yZ84\"\n  language: \"English\"\n  description: |-\n    Using Ruby at work is great… but sometimes it feels like a job!\n\n    This year, I rediscovered the joy of writing Ruby apps for nobody but myself—and you can, too! Solo development is a great way to learn skills, to find inspiration, and to distill what matters most about programming.\n\n    Building an entire app by yourself can be overwhelming, but this talk will make it easier. We'll start with a minimal toolset that one person can maintain. You'll learn how many \"bad\" coding practices can actually reduce complexity. You may be surprised how selfish coding can make you a better team member, too!\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/searls.html#apr20\n\n- id: \"xavier-noria-rubykaigi-2019\"\n  title: \"Zeitwerk: A new code loader\"\n  raw_title: \"[EN] Zeitwerk: A new code loader / Xavier Noria @fxn\"\n  speakers:\n    - Xavier Noria\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"YSc_GNQP6ts\"\n  language: \"English\"\n  description: |-\n    The talk presents Zeitwerk, a new code loader for gems and applications.\n\n    Zeitwerk is able to preload, lazy load, unload, and eager load the code of gems and applications with a compatible file structure without the need to write require calls.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/fxn.html#apr19\n\n- id: \"kenta-murata-rubykaigi-2019\"\n  title: \"RubyData Workshop\"\n  raw_title: \"[JA] RubyData Workshop / @mrkn, @284km, @kozo2, @ktou, @znz, and Red Data Tools project members\"\n  speakers:\n    - Kenta Murata\n    - Kazuma Furuhashi\n    - Kozo Nishida\n    - Kouhei Sutou\n    - Kazuhiro NISHIYAMA\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"PFcpmbRgB5A\"\n  language: \"Japanese\"\n  description: |-\n    In this session, we'd like to introduce the current state of our data science ecosystems for Ruby.\n\n    This session consists of the following four parts.\n\n    1. In the first part, mrkn will talk about the whole summary.\n    2. In the second part, kou and people from Red Data Tools project will introduce this project and its current status.\n    3. In the third part, kozo2 will explain his achievements of RubyGrant 2018.\n    4. In the last part, Kazuma Furuhashi will explain his achievements of RubyGrant 2018.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/mrkn_workshop.html#apr19\n\n- id: \"uchio-kondo-rubykaigi-2019\"\n  title: \"The fastest way to bootstrap Ruby on Rails\"\n  raw_title: \"[EN] The fastest way to bootstrap Ruby on Rails / Uchio KONDO @udzura\"\n  speakers:\n    - Uchio KONDO\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"pmlUq5fNkzA\"\n  language: \"English\"\n  description: |-\n    Ruby on Rails applications sometimes take too long time in bootstrapping, especially when the application is complicated, monolithic or \"legacy\" one. This inhibits Kubernetes or other orchestrators to do smooth autoscaling. There are technologies such as bootsnap to solve this problem. In addition to them, I propose new strategy - \"checkpoint and restore\". I used CRIU(Checkpoint and Restore In Userspace) in Linux environment to make \"ahead of time\" process dump, and boot the application from image to reduce the bootstrap time. In my case, observed bootstrap time is reduced from about 2,500ms to 1,200ms. I will describe what the CRIU is in the first place, use cases where CRIU is effective and some problems using CRIU.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/udzura.html#apr19\n\n- id: \"kouhei-sutou-rubykaigi-2019\"\n  title: \"Better CSV processing with Ruby 2.6\"\n  raw_title: \"[JA] Better CSV processing with Ruby 2.6 / Kouhei Sutou @ktou, Kazuma Furuhashi @284km\"\n  speakers:\n    - Kouhei Sutou\n    - Kazuma Furuhashi\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"z8yV3yEqxJY\"\n  language: \"Japanese\"\n  description: |-\n    csv, one of the standard libraries, in Ruby 2.6 has many improvements:\n\n    - Default gemified\n    - Faster CSV parsing\n    - Faster CSV writing\n    - Clean new CSV parser implementation for further improvements\n    - Reconstructed test suites for further improvements\n    - Benchmark suites for further performance improvements\n\n    These improvements are done without breaking backward compatibility.\n\n    This talk describes details of these improvements by a new csv maintainer.\n\n- id: \"hitoshi-hasumi-rubykaigi-2019\"\n  title: \"Practical mruby/c firmware development with CRuby\"\n  raw_title: \"[EN] Practical mruby/c firmware development with CRuby / Hitoshi HASUMI @hasumikin\"\n  speakers:\n    - HASUMI Hitoshi\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"rl0Nfiqs4e0\"\n  language: \"English\"\n  description: |-\n    Writing mruby/c firmware applications is like writing mrbgems. You need to make some C functions and mruby wrapper of them in order to handle peripherals like sensor, flash memory or BLE. Easy to imagine it's hard to develop for a team in a situation of TIGHT COUPLING, right? I will talk about some tools, mrubyc-test and mrubyc-debugger, which I made with CRuby for testing and debugging to keep our team slack coupling.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/hasumikin.html#apr19\n\n- id: \"alexander-ivanov-rubykaigi-2019\"\n  title: \"Compiling Ruby to idiomatic code in static languages\"\n  raw_title: \"[EN] Compiling Ruby to idiomatic code in static languages / @alehander42, @zah\"\n  speakers:\n    - Alexander Ivanov\n    - Zahary Karadjov\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-18\"\n  video_provider: \"youtube\"\n  video_id: \"hlWCp210IIY\"\n  language: \"English\"\n  description: |-\n    Alexander Ivanov @alehander42, Zahary Karadjov @zah\n\n    Generating code and compiling code are very useful, but usually the target is the machine: so the generated code is very unfriendly for programmers. We will show two approaches with which we are able to compile Ruby to code in statically typed languages and make it idiomatic and nice\n\n    pseudocode-like(where we support small programs in a subset of Ruby, but we can generate correct statically typed code in C++, C#, Go, Java) and\n\n    realcode-like, where we infer ruby types on runtime and autotranslate more complicated codebase to Nim(rb2nim): the result requires some manual work, but automates most of it.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/alehander42.html#apr18\n\n- id: \"petr-chalupa-rubykaigi-2019\"\n  title: \"TruffleRuby: Wrapping up compatibility for C extensions\"\n  raw_title: \"[EN] TruffleRuby: Wrapping up compatibility for C extensions / Petr Chalupa @pitr_ch\"\n  speakers:\n    - Petr Chalupa\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"R-vInXwpPPg\"\n  language: \"English\"\n  description: |-\n    We think it is crucial that any alternative Ruby implementation aiming to be fully compatible with MRI runs the C extensions. TruffleRuby's compatibility was recently significantly improved, with much better support that almost completely removes the need to patch C extensions.\n\n    In this talk you will hear and see: how the old approach to C extensions worked and where and why it was failing short; how does the new approach work and how much closer it brings TruffleRuby to its goal to be a drop-in replacement for MRI.\n\n    We have been interpreting the C extensions (and JITing together with Ruby code) for a while, however we have been passing the Ruby objects directly into the C code which had lead to problems. We now have a new innovative technique which no longer requires patches in almost all cases. The objects are wrapped for greater compatibility and there is a virtual GC marking phase to avoid memory leaks.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/pitr_ch.html#apr20\n\n- id: \"yoh-osaki-rubykaigi-2019\"\n  title: \"Ruby for NLP\"\n  raw_title: \"[JA] Ruby for NLP / Yoh Osaki @youchan\"\n  speakers:\n    - Yoh Osaki\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"nzPwSDRsv_0\"\n  language: \"Japanese\"\n  description: |-\n    There is no doubt that Deep Learning was the spark of the recent AI boom. Deep Learning has been improving the field of image recognition and natural language processing. In this presentation, I will explain how to deal with natural language processing in Ruby In the first half I will explain the basic methodology of natural language processing and in the second half I will explain how to deal with Ruby.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/youchan.html#apr18\n\n- id: \"colby-swandale-rubykaigi-2019\"\n  title: \"Working towards Bundler 3\"\n  raw_title: \"[EN] Working towards Bundler 3 / Colby Swandale @oceanicpanda\"\n  speakers:\n    - Colby Swandale\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"m_KTuPuEmQ0\"\n  language: \"English\"\n  description: |-\n    Bundler hit a big milestone this year with the release of Bundler 2 🎉, but not without its bumps and hurdles. We'll look into the problems that some of our users have been experiencing after the Bundler 2 release, what the core team has been doing to fix these issues and what we've since learned. Afterwards, We'll look at the upcoming Bundler 2.1 and Bundler 3 releases.\n\n- id: \"tomohiro-hashidate-rubykaigi-2019\"\n  title: \"Pragmatic Monadic Programing in Ruby\"\n  raw_title: \"[JA] Pragmatic Monadic Programing in Ruby / @joker1007\"\n  speakers:\n    - Tomohiro Hashidate\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"xUV2DvZ5L1A\"\n  language: \"Japanese\"\n  description: |-\n    Ruby is not only for Objective Oriented Programming style, but also for Functional Programming style. I talk how ruby expresses important essences of Functional Programming. For example, Functor, Applicative, Monad.\n\n    And Monadic syntax suger is very important to take advantage of Monad. I also talk about Implementation of Monadic syntax suger that is inspired by Scala language. I will show popular monad implementations like belows. - Maybe - Either - State - Future (like async syntax in JavaScript) - Parser Combinator\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/joker1007.html#apr18\n\n- id: \"genadi-samokovarov-rubykaigi-2019\"\n  title: \"Writing Debuggers in Plain Ruby! Fact or fiction?\"\n  raw_title: \"[EN] Writing Debuggers in Plain Ruby! Fact or fiction? / Genadi Samokovarov @gsamokovarov\"\n  speakers:\n    - Genadi Samokovarov\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-24\"\n  video_provider: \"youtube\"\n  video_id: \"vV_tZX7jooo\"\n  language: \"English\"\n  description: |-\n    In this talk, we'll build a simple byebug-like debugger in plain Ruby. We'll try to go all the way, but also explain what we cannot do without some C or Java code.\n\n    Let's imagine a Ruby future, where a debugger written in Ruby can be used in CRuby, JRuby and even TruffleRuby!\n\n- id: \"kevin-menard-rubykaigi-2019\"\n  title: \"Beyond `puts`: TruffleRuby’s Modern Debugger Using Chrome\"\n  raw_title: \"[EN] Beyond `puts`: TruffleRuby’s Modern Debugger Using Chrome / Kevin Menard @nirvdrum\"\n  speakers:\n    - Kevin Menard\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"pe28r1VSBdU\"\n  language: \"English\"\n  description: |-\n    We all write bugs. How quickly we can identify & understand them depends on the quality of our tools.\n\n    In this talk you'll be introduced to TruffleRuby's modern debugger, based on the Chrome browser's DevTools Protocol. TruffleRuby's uniquely powerful set of tools let you debug, profile, and inspect the memory usage of Ruby code, native extensions, and other embedded languages all at the same time. Support for those tools is zero-overhead so you can have them always enabled. I'll show you how it all works and how it lets you step through Ruby code, inspect local variables, evaluate expressions, and more.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/nirvdrum.html#apr19\n\n- id: \"emily-stolfo-rubykaigi-2019\"\n  title: \"Benchmarking your code, inside and out\"\n  raw_title: \"[EN] Benchmarking your code, inside and out / Emily Stolfo @estolfo\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"WOnxe6qWtzY\"\n  language: \"English\"\n  description: |-\n    Benchmarking is an important component of writing applications, gems, Ruby implementations, and everything in between. There is never a perfect formula for how to measure the performance of your code, as the requirements vary from codebase to codebase. Elastic has an entire team dedicated to measuring the performance of Elasticsearch and the clients team has worked with them to build a common benchmarking framework for itself. This talk will explore how the Elasticsearch Ruby Client is benchmarked and highlight key elements that are important for any benchmarking framework\n\n- id: \"hiroshi-shibata-rubykaigi-2019\"\n  title: \"The future of the Bundled Bundler with RubyGems\"\n  raw_title: \"[JA] The future of the Bundled Bundler with RubyGems / Hiroshi SHIBATA @hsbt\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-14\"\n  video_provider: \"youtube\"\n  video_id: \"H4rsTfJw9A4\"\n  language: \"Japanese\"\n  description: |-\n    I did merge Bundler into Ruby core repository and shipped bundler as standard library on Ruby 2.6. It helps to preparation of the fresh Ruby install and easy to use gem and bundle commands.\n\n    In background, we have a lot of issues until done to merge bundler into ruby core. This presentation show the some of issues of it works that are test suite, rubygems integration and library ecosystem like Heroku. You can understand the internal of library management by rubygems and bundler.\n\n    Finally, I'm going to show the integration plan of RubyGems and Bundler and the part of its implements. Also I will show the issues of the current status. You can resolve them after my talk.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/hsbt.html#apr20\n\n- id: \"kenta-murata-rubykaigi-2019-reducing-activerecord-memory-c\"\n  title: \"Reducing ActiveRecord memory consumption using Apache Arrow\"\n  raw_title: \"[JA] Reducing ActiveRecord memory consumption using Apache Arrow / Kenta Murata @mrkn\"\n  speakers:\n    - Kenta Murata\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"c1Y5o4tgblQ\"\n  language: \"Japanese\"\n  description: |-\n    The pluck method provided in ActiveRecord is a platform to obtain one or few field values as an array or arrays from a database. The pluck method, compared with finder methods, can considerably reduce memory consumption because it does not generate model instances.\n\n    In this talk, I would like to introduce my new approach to reduce the memory consumption of ActiveRecord. This approach employs Apache Arrow as the internal data representation of an ActiveRecord::Result object. This approach can achieve a remarkable reduction of the memory consumption of the pluck method; it is 2-12x efficient than the original implementation.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/mrkn.html#apr20\n\n- id: \"masatoshi-seki-rubykaigi-2019\"\n  title: \"dRuby 20th anniversary hands-on workshop\"\n  raw_title: \"[JA] dRuby 20th anniversary hands-on workshop / Masatoshi SEKI @m_seki\"\n  speakers:\n    - Masatoshi SEKI\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"6BJLGr_M30g\"\n  language: \"Japanese\"\n  description: |-\n    dRuby (distributed ruby) is a cool library bone in the 20th century.\n    In this session, we will learn the basics of dRuby. Experience distributed objects on your PC.\n    Please download (or print) the document. (V0.7) → http://www.druby.org/fukuoka2019.pdf\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/m_seki.html#apr20\n\n- id: \"kevin-newton-rubykaigi-2019\"\n  title: \"Pre-evaluation in Ruby\"\n  raw_title: \"[EN] Pre-evaluation in Ruby / Kevin Deisz @kddeisz\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"q3i5pYpxP-s\"\n  language: \"English\"\n  description: |-\n    Ruby is historically difficult to optimize due to features that improve flexibility and productivity at the cost of performance. Techniques like Ruby's new JIT compiler and deoptimization code help, but still are limited by techniques like monkey-patching and binding inspection.\n\n    Pre-evaluation is another optimization technique that works based on user-defined contracts and assumptions. Users can opt in to optimizations by limiting their use of Ruby's features and thereby allowing further compiler work.\n\n    In this talk we'll look at how pre-evaluation works, and what benefits it enables.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/kddeisz.html#apr20\n\n- id: \"tung-nguyen-rubykaigi-2019\"\n  title: \"Ruby Serverless Framework\"\n  raw_title: \"[EN] Ruby Serverless Framework / Tung Nguyen @tongueroo\"\n  speakers:\n    - Tung Nguyen\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"a0VKbrgzKso\"\n  language: \"English\"\n  description: |-\n    Learn how to run Ruby applications on AWS Lambda with a Serverless Framework specifically designed with Ruby. Demo is provided. We deploy it to AWS Lambda with a single command.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/tongueroo.html#apr20\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2019\"\n  title: \"Keynote: The Year of Concurrency\"\n  raw_title: '[JA][Keynote] The Year of Concurrency  / Yukihiro \"Matz\" Matsumoto @yukihiro_matz'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-24\"\n  video_provider: \"youtube\"\n  video_id: \"WZu-WVzbEOA\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/yukihiro_matz.html#apr18\n\n- id: \"alex-wood-rubykaigi-2019\"\n  title: \"Building Serverless Applications in Ruby with AWS Lambda\"\n  raw_title: \"[EN] Building Serverless Applications in Ruby with AWS Lambda / Alex Wood @alexwwood\"\n  speakers:\n    - Alex Wood\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-18\"\n  video_provider: \"youtube\"\n  video_id: \"OA7jwECjvRY\"\n  language: \"English\"\n  description: |-\n    Come join us and learn about how you can build serverless applications using Ruby on AWS Lambda! We will demonstrate how to create Ruby serverless functions for web APIs as well as for event-driven applications, then build, test and deploy them to production. We'll also discuss general best practices for developing serverless applications.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/alexwwood.html#apr18\n\n- id: \"michael-grosser-rubykaigi-2019\"\n  title: \"Actionable Code Coverage\"\n  raw_title: \"[EN] Actionable Code Coverage / Michael Grosser @grosser\"\n  speakers:\n    - Michael Grosser\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"01LYb28rMUQ\"\n  language: \"English\"\n  description: |-\n    No more external tools / unclear percentage scores / slow PR feedback.\n\n    Code coverage at your fingertips while developing, by having tests fail when newly added code is missing coverage, with minimal overhead and great visibility.\n\n    how code coverage works in ruby (regular vs branch vs oneshot)\n    how single_cov keeps things fast and simple\n    onboarding for small and large codebases (automated onboarding + divide & conquer)\n    how to hack forked code coverage with forking-test-runner\n    wishlist for coverage.so\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/grosser.html#apr19\n\n- id: \"maciej-mensfeld-rubykaigi-2019\"\n  title: \"How to take over a Ruby gem\"\n  raw_title: \"[EN] How to take over a Ruby gem / Maciej Mensfeld @maciejmensfeld\"\n  speakers:\n    - Maciej Mensfeld\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-18\"\n  video_provider: \"youtube\"\n  video_id: \"wePVhZeZTNM\"\n  language: \"English\"\n  description: |-\n    Using Ruby gems is safe, right? We're a nice community of friendly beings that act towards the same goal: making Ruby better. But is that true? Can we just blindly use libraries, without making sure, that they are what they are supposed to be?\n\n    Come and learn how you can take over a gem, what you can do with it once you have it and what you can do to protect yourself against several types of attacks you're exposed to on a daily basis. Let's exploit the Ruby gems world, and its data together.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/maciejmensfeld.html#apr18\n\n- id: \"shawnee-gao-rubykaigi-2019\"\n  title: \"GraphQL Migration: A Proper Use Case for Metaprogramming?\"\n  raw_title: \"[EN] GraphQL Migration: A Proper Use Case for Metaprogramming? / Shawnee Gao @gao_shawnee\"\n  speakers:\n    - Shawnee Gao\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-14\"\n  video_provider: \"youtube\"\n  video_id: \"GKj4dipBEts\"\n  language: \"English\"\n  description: |-\n    When my team took the plunge to migrate Square’s largest Ruby app to GraphQL, no way were we going to manually redefine over 200 objects. Implementing a GraphQL layer includes repetitive and straightforward processes that can be expedited with metaprogramming. I will start with some GraphQL basics, then dig into process of metaprogramming a GraphQL layer from a demo ruby server. I will explain the benefits of using this design pattern and how it improves developer experience. At the end, I will demo the server handling a set diverse and complex client calls!\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/gao_shawnee.html#apr18\n\n- id: \"charles-nutter-rubykaigi-2019\"\n  title: \"JRuby: The Road to Ruby 2.6 and Rails 6\"\n  raw_title: \"[EN] JRuby: The Road to Ruby 2.6 and Rails 6 / Charles Nutter @headius, Thomas E Enebo @tom_enebo\"\n  speakers:\n    - Charles Nutter\n    - Thomas E Enebo\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"vPy5KO4uHuA\"\n  language: \"English\"\n  description: |-\n    Over the past six months, the JRuby team has been working on filling in edges: getting refinements working well, porting C extensions, and getting well-known applications running. At the same time, we always try to push forward on performance and general compatibility. In this talk, we'll cover recent work to support Rails 6 and Ruby 2.6. We'll show off a major Rails application running on JRuby. And we'll show you how you can help us keep JRuby moving forward.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/headius.html#apr20\n\n- id: \"nate-berkopec-rubykaigi-2019\"\n  title: \"Determining Ruby Process Counts: Theory and Practice\"\n  raw_title: \"[EN] Determining Ruby Process Counts: Theory and Practice / Nate Berkopec @nateberkopec\"\n  speakers:\n    - Nate Berkopec\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-18\"\n  video_provider: \"youtube\"\n  video_id: \"BE5C2ydN0y0\"\n  language: \"English\"\n  description: |-\n    You have a Ruby web application or service that takes a certain number of requests per minute. How do you know how many Ruby processes you will need to serve that load? The answer is actually very complex, and getting it wrong can cost you a lot of money! In this talk, we'll go through the mathematics and theory of queues, and then apply them to the configuration and provisioning of Ruby services (web, background job, and otherwise). Finally, we'll discuss the application of this theory in the real world, including multi-threading and the GVL, \"autoscaling\", containers and deployment processes, and how Guilds may impact this process in the future.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/nateberkopec.html#apr18\n\n- id: \"ota42y-rubykaigi-2019\"\n  title: \"How to use OpenAPI3 for API developer\"\n  raw_title: \"[JA] How to use OpenAPI3 for API developer / @ota42y\"\n  speakers:\n    - ota42y\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"om1dgTbmXrw\"\n  language: \"Japanese\"\n  description: |-\n    I'll talk about how to use OpenAPI 3 and another tools in production.\n\n    JSON is widely used in the current Web. But the request / response format is not in the JSON specification, so we can't guarantee.\n\n    In the case of developing API servers for backend server and multiple servers like micro services, guaranteeing the request / response format is improve for stability and development efficiency. So the definition of schema is important.\n\n    OpenAPI 3 (formerly Swagger) is a specification for describing the interface of RESTful API. We can define request / response parameters schema for the endpoint using it.\n\n    The committee is gem which validates request / response in rack layer. I'm developing the function to perform validation using OpenAPI 3 in this gem. And I shifted my application specification to OpenAPI3 from another schema specification called JSON Hyper-Schema.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/ota42y.html#apr18\n\n- id: \"colin-fulton-rubykaigi-2019\"\n  title: \"Running Ruby On The Apple II\"\n  raw_title: \"[EN] Running Ruby On The Apple II / Colin Fulton @PeterQuines\"\n  speakers:\n    - Colin Fulton\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"qiwpWHfyXpM\"\n  language: \"English\"\n  description: |-\n    An 8-bit CPU running at 1 megahertz. Kilobytes of RAM. The Apple II was released in the 1970's and many people first learned to program on it using the built in BASIC. Surely it is impossible to fit a language as complicated as Ruby on such a limited machine… right?\n\n    Come see Ruby running where it has never run before, and learn how such a rich language can be squeezed down to fit on the humble Apple II.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/PeterQuines.html#apr20\n\n- id: \"noah-gibbs-rubykaigi-2019\"\n  title: \"Six Years of Ruby Performance: A History\"\n  raw_title: \"[EN] Six Years of Ruby Performance: A History / Noah Gibbs @codefolio\"\n  speakers:\n    - Noah Gibbs\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"iy4N7AtzZYc\"\n  language: \"English\"\n  description: |-\n    Ruby keeps getting faster. And people keep asking, \"but how fast is it for Rails?\" Rails makes a great way to measure Ruby's speed, and how Ruby has changed version-by-version. Let's look at six years of performance graphs for apps big and small. How fast is 2.6.0? With JIT? How close is Ruby 3x3?\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/codefolio.html#apr19\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2019-ruby-3-progress-report\"\n  title: \"Ruby 3 Progress Report\"\n  raw_title: \"[JA] Ruby 3 Progress Report / Matz & the Ruby Core Team @matzbot\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-24\"\n  video_provider: \"youtube\"\n  video_id: \"1qEhEad5uPI\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/matzbot.html#apr18\n\n- id: \"paolo-nusco-perrotta-rubykaigi-2019\"\n  title: \"A Deep Learning Adventure\"\n  raw_title: \"[EN] A Deep Learning Adventure / Paolo Perrotta @nusco\"\n  speakers:\n    - Paolo \"Nusco\" Perrotta\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"Uj-7X-9lkIg\"\n  language: \"English\"\n  description: |-\n    Deep learning is the most exciting recent idea in software–but it's also intimidating. If you have no previous machine learning and deep learning experience, this talk is your entry ticket to the field.\n\n    We'll start from scratch, with a look at supervised learning. Then we'll see Ruby code that trains a neural network. Finally, we'll talk about deep neural networks, and explore a wonderful new concept that's changing the field of computer graphics: Generation Adversarial Networks. See how a deep learning program can invent imaginary animals!\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/nusco.html#apr18\n\n- id: \"sangyong-sim-rubykaigi-2019\"\n  title: \"Cleaning up a huge ruby application\"\n  raw_title: \"[JA] Cleaning up a huge ruby application / Sangyong Sim @riseshia\"\n  speakers:\n    - Sangyong Sim\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-29\"\n  video_provider: \"youtube\"\n  video_id: \"4akNWMKVZQU\"\n  language: \"Japanese\"\n  description: |-\n    (JA) プロジェクトに顕在している未使用のコードを消すのは難しいです。 その理由としては特定コードを消していいのか確信を持ちづらいこと、そして実際削除可能なコードを探す作業は作業効率が悪いということなどが上げられます。 クックパッドでも未使用コードを削除しているのですが、上記のような問題がありこれらを解決するためにコードの修正履歴を利用したコード監視や、本番環境の実行履歴からの未使用コード探すなど仕組みを導入しています。\n\n    この発表ではコード削除業の意義や面倒さを説明し、そして1年で現行のサービスのクローズなしで5万行以上のコードを消せた経験を共有します。\n\n    (EN) Deleting unused code from a huge project is hard. Because it's difficult to:\n\n    get confidence whether we could delete it or not.\n    find potential unused codes is cost-inefficient task.\n    We has cleaned up unused codes, and introduced the stuffs such as logging code execution on the production environment, monitoring the code changes for solving these problems.\n\n    In this talk, I will explain why cleaning up codes is needed, why it's troublesome, and describe our experience how we deleting more than 50,000 lines codes without closing any services.\n\n    RubyKaigi 2018 https://rubykaigi.org/2019/presentations/riseshia.html#apr20\n\n- id: \"alex-rodionov-rubykaigi-2019\"\n  title: \"Crystalball: predicting test failures\"\n  raw_title: \"[EN] Crystalball: predicting test failures / Alex Rodionov @p0deje\"\n  speakers:\n    - Alex Rodionov\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"q2q-9Td71kE\"\n  language: \"English\"\n  description: |-\n    Tests are often slow and are a bottleneck in development. We build complex CI systems with heavy parallelization to reduce the amount of time it takes to run all the tests, but we still tend to run all of them even for the slightest change in code. What if instead, we could run only the tests that might fail as a result of our changes? In a world of static languages, it's not hard, but Ruby is very flexible and dynamic language so implementing this idea is tricky.\n\n    Meet Crystalball (https://toptal.github.io/crystalball/) - a regression test selection library we built in Toptal. I'll demonstrate how to use it with RSpec, how it predicts what tests to run and how it can be extended.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/p0deje.html#apr19\n\n- id: \"go-sueyoshi-rubykaigi-2019\"\n  title: \"Best practices in web API client development\"\n  raw_title: \"[JA] Best practices in web API client development / Go Sueyoshi @sue445\"\n  speakers:\n    - Go Sueyoshi\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-28\"\n  video_provider: \"youtube\"\n  video_id: \"Ry0uQeTCHHs\"\n  language: \"Japanese\"\n  description: |-\n    How many did you make web API clients?\n\n    I have made web API clients as OSS, but I have made more private web API clients (not OSS) than that. (total 10+ gems)\n\n    Everyone should have used an external web service web API to create something.\n\n    Sometimes, you may need to create a client to use private web APIs that are not publicly exposed.\n\n    I would like to introduce the best practices of making web API clients.\n\n    I think that designing a good API client will lead to a good gem design, so I believe that my talk is beneficial not only for API client developers but also gem developers.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/sue445.html#apr20\n\n- id: \"mike-mcquaid-rubykaigi-2019\"\n  title: \"Building Homebrew in Ruby: The Good, Bad and Ugly\"\n  raw_title: \"[EN] Building Homebrew in Ruby: The Good, Bad and Ugly / Mike McQuaid @MikeMcQuaid\"\n  speakers:\n    - Mike McQuaid\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"m1P_06bjjCs\"\n  language: \"English\"\n  description: |-\n    Homebrew is a popular macOS package manager in the Ruby community and is also written in Ruby. As Homebrew isn't a web application and doesn't provide a Ruby library, the Ruby ecosystem works great for us in some ways and less great in others. Learn about things we love, hate and struggle with because Homebrew is built in Ruby.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/MikeMcQuaid.html#apr19\n\n- id: \"matthew-draper-rubykaigi-2019\"\n  title: \"A Bundle of Joy: Rewriting for Performance\"\n  raw_title: \"[EN] A Bundle of Joy: Rewriting for Performance / Matthew Draper @_matthewd\"\n  speakers:\n    - Matthew Draper\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-18\"\n  video_provider: \"youtube\"\n  video_id: \"fQBrWrJKPVU\"\n  language: \"English\"\n  description: |-\n    Local gem management is a key part of our modern workflow, but our tools are layered on historical approaches and requirements. In this talk we explore a ground-up rewrite of local gem management, and ask whether careful implementation (and some feature-cutting) can produce a tool that meets most people's needs while outperforming the current options. In the process, we'll look at specific design choices that make common operations faster, and which might apply to your projects too.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/_matthewd.html#apr18\n\n- id: \"tatsuhiro-ujihisa-rubykaigi-2019\"\n  title: \"Play with local vars\"\n  raw_title: \"[EN] Play with local vars / Tatsuhiro Ujihisa @ujm\"\n  speakers:\n    - Tatsuhiro Ujihisa\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-21\"\n  video_provider: \"youtube\"\n  video_id: \"oNJyBZ5OAMw\"\n  language: \"English\"\n  description: |-\n    This 40min talk is only about Ruby's local variables. I'm not going to talk about anything else.\n\n    I'll demonstrate, or more precisely, play with Ruby local variables, including a discussion about the following common pitfall:\n\n    eval 'a = 1'\n    eval 'p a' # NameError!\n\n    Ruby has multiple different types of variables: global vars, instance vars, class vars, constants, local vars, and pseudo vars such as self. Identifiers without sigils such as @ are considered either local vars, methods, method arguments, block parameters, pseudo variables, or other reserved words. Particularly important aspect I believe is that Ruby intentionally tries to make local vars and methods indistinguishable for human. This talk focuses only on local vars among other variables or methods.\n\n    Keywords: parse.y, binding, yarv iseq, continuation, flip-flop operator, regular expression, and gdb\n    Oh by the way, the whole presentation is likely going to be done inside my Vim.\n\n- id: \"aaron-patterson-rubykaigi-2019\"\n  title: \"Compacting GC for MRI v2\"\n  raw_title: \"[JA] Compacting GC for MRI v2 / Aaron Patterson @tenderlove\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-16\"\n  video_provider: \"youtube\"\n  video_id: \"HgAZsg7D_Jo\"\n  language: \"Japanese\"\n  description: |-\n    In this talk we will cover an implementation for a compacting GC in MRI. MRI's implementation presents unique challenges for implementing a compacting GC. In this talk, we will cover compactor implementation and algorithms, challenges presented by MRI's implementation, compaction reference verification, and results of compactor benchmarks.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/tenderlove.html#apr18\n\n- id: \"andrey-novikov-rubykaigi-2019\"\n  title: \"Yabeda: Monitoring monogatari\"\n  raw_title: \"[EN] Yabeda: Monitoring monogatari / Andrey Novikov @Envek\"\n  speakers:\n    - Andrey Novikov\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"CvjefIat8yE\"\n  language: \"English\"\n  description: |-\n    Developing large and high load application without monitoring is a hard and dangerous task, just like piloting an aircraft without gauges. Why it is so important to keep an eye on how application's “flight“ goes, what things you should care more, and how graphs may help to resolve occurring performance problems quickly. On an example of Sidekiq, Prometheus, and Grafana, we will learn how to take metrics from the Ruby application, what can we see from their visualization, and I will tell a couple of sad tales about how it helps in everyday life (with happy-end!)\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/Envek.html#apr19\n\n- id: \"yutaka-hara-rubykaigi-2019\"\n  title: \"Ovto: Frontend web framework for Rubyists\"\n  raw_title: \"[JA] Ovto: Frontend web framework for Rubyists / Yutaka HARA @yhara\"\n  speakers:\n    - Yutaka HARA\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-05-24\"\n  video_provider: \"youtube\"\n  video_id: \"Vu2z8krSAYs\"\n  language: \"Japanese\"\n  description: |-\n    What framework do you use for creating single-page webapps? React, Vue, Angular, etc... If you're tired of wirting JavaScript, Ovto may be a good choice. In this talk, I will in introduce Ovto, a frontend framework which allows you to write single-page webapps all in Ruby. https://github.com/yhara/ovto\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/yhara.html#apr19\n  additional_resources:\n    - name: \"yhara/ovto\"\n      type: \"repo\"\n      url: \"https://github.com/yhara/ovto\"\n\n- id: \"amir-rajan-rubykaigi-2019\"\n  title: \"Building a game for the Nintendo Switch using Ruby - First Half\"\n  raw_title: \"[EN] Building a game for the Nintendo Switch using Ruby - First Half /Amir Rajan @amirrajan\"\n  speakers:\n    - Amir Rajan\n  event_name: \"RubyKaigi 2019\"\n  date: \"2019-04-18\"\n  published_at: \"2019-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"o0d4sjcUfCg\"\n  language: \"English\"\n  description: |-\n    The second half will be \"coming soon\"\n\n    Amir Rajan has done something insane. He released a Nintendo Switch game written entirely in mRuby and C. Amir will share his journey with you from the inception of A Dark Room Switch, it's integration with libSDL, all the way to the submission to his publisher. Hopefully, Amir will inspire others to pursue game development projects of their own using Ruby.\n\n    RubyKaigi 2019 https://rubykaigi.org/2019/presentations/amirrajan.html#apr19\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2020/event.yml",
    "content": "---\nid: \"PLbFmgWm555yZeLpdOLhYwORIF9UjBAFHw\"\ntitle: \"RubyKaigi Takeout 2020\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: |-\n  https://rubykaigi.org/2020-takeout/\npublished_at: \"2020-09-03\"\nstart_date: \"2020-09-04\"\nend_date: \"2020-09-05\"\nchannel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\nyear: 2020\nbanner_background: \"#7E0303\"\nfeatured_background: \"#7E0303\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubykaigi.org/2020-takeout/\"\ncoordinates: false\naliases:\n  - RubyKaigi 2020 Takeout\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2020/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"soutaro-matsumoto-rubykaigi-2020-takeout\"\n  title: \"The State of Ruby 3 Typing\"\n  raw_title: \"[EN] The State of Ruby 3 Typing / Soutaro Matsumoto @soutaro\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"PvkpW1OEaP8\"\n  language: \"English\"\n  description: |-\n    Ruby 3 will ship with a new feature for type checking, RBS. It provides a language to describe types of Ruby programs, the type declarations for standard library classes, and a set of features to support using and developing type checkers. In this talk, I will introduce the feature and how the Ruby programming will be with RBS.\n\n- id: \"vladimir-dementyev-rubykaigi-2020-takeout\"\n  title: \"The whys and hows of transpiling Ruby\"\n  raw_title: \"[EN] The whys and hows of transpiling Ruby / Vladimir Dementyev @palkan_tula\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"zLInIisYlDo\"\n  language: \"English\"\n  slides_url: \"https://speakerdeck.com/palkan/rubykaigi-2020-the-whys-and-hows-of-transpiling-ruby\"\n  description: |-\n    Transpiling is a source-to-source compiling. Why might we need it in Ruby? Compatibility and experiments.\n\n    Ruby is evolving fast nowadays. The latest MRI release introduced, for example, the pattern matching syntax. Unfortunately, not everyone is ready to use it yet: gems authors have to support older versions, Ruby implementations are lagging. And it's still experimental, which raises the question: how to evaluate proposals? By backporting them to older Rubies!\n\n    I want to discuss these problems and share the story of the Ruby transpiler — Ruby Next. A decent amount of Ruby hackery is guaranteed.\n\n- id: \"ufuk-kayserilioglu-rubykaigi-2020-takeout\"\n  title: \"Reflecting on Ruby Reflection for Rendering RBIs\"\n  raw_title: \"[EN] Reflecting on Ruby Reflection for Rendering RBIs / Ufuk Kayserilioglu @paracycle\"\n  speakers:\n    - Ufuk Kayserilioglu\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"OJRQAn6BfpE\"\n  language: \"English\"\n  description: |-\n    As part of our adoption process of Sorbet at Shopify, we needed an automated way to teach Sorbet about our ~400 gem dependencies. We decided to tackle this problem by generating interface files (RBI) for each gem via runtime reflection.\n\n    However, this turns out to not be as simple as it sounds; the flexible nature of Ruby allows gem authors to do many wild things that make this Hard. Come and hear about all the lessons that we learnt about runtime reflection in Ruby while building \"tapioca\".\n\n- id: \"elct9620-rubykaigi-2020-takeout\"\n  title: \"Is it time run Ruby on Web via WebAssembly?\"\n  raw_title: \"[EN] Is it time run Ruby on Web via WebAssembly? / 蒼時弦也 @elct9620\"\n  speakers:\n    - elct9620\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"PJLWoz6K7w4\"\n  language: \"English\"\n  description: |-\n    The W3C is starting to recommend to use WebAssembly, and we can compile mruby to WebAssembly very easy in now day. But we have Opal and it works well, we really need to use WebAssembly? Let me share my experience about trying to add mruby to HTML5 game, and discuss the pros and cons when we use Ruby in WebAssembly way in Web.\n\n- id: \"hitoshi-hasumi-rubykaigi-2020-takeout\"\n  title: \"mruby machine: An Operating System for Microcontoller\"\n  raw_title: \"[EN] mruby machine: An Operating System for Microcontoller / Hitoshi HASUMI @hasumikin\"\n  speakers:\n    - HASUMI Hitoshi\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"kDOf_tZKlLU\"\n  language: \"English\"\n  description: |-\n    There are different approaches to make an operating system.\n    I take an approach which takes advantage of mruby/c's VM then makes my own mruby compiler and shell program.\n    Though my purpose is making an useful and effective development platform for microcontroller with Ruby, I will also share some universal knowledge on how to make an OS with you.\n\n- id: \"jeremy-evans-rubykaigi-2020-takeout\"\n  title: \"Keyword Arguments: Past, Present, and Future\"\n  raw_title: \"[EN] Keyword Arguments: Past, Present, and Future / Jeremy Evans @jeremyevans0\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"rxJRrccXRfg\"\n  language: \"English\"\n  description: |-\n    Ruby 3 will separate keyword arguments from positional arguments, which causes the biggest backwards compatibility issues in Ruby since Ruby 1.9. This presentation will discuss the history of keyword arguments, how keyword arguments are handled internally, how keyword arguments were separated from positional arguments internally, and possible future improvements in the handling of keyword arguments.\n\n- id: \"jnatas-davi-paganini-rubykaigi-2020-takeout\"\n  title: \"Live coding: Grepping Ruby code like a boss\"\n  raw_title: \"[EN] Live coding: Grepping Ruby code like a boss / Jônatas Davi Paganini @jonatas\"\n  speakers:\n    - Jônatas Davi Paganini\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"YczrZQC9aP8\"\n  language: \"English\"\n  description: |-\n    Our favorite language allows us to implement the same code in a few different ways. Because of that, it becomes tough to search and find the target code only with regular expressions.\n    I'd like to present fast, a searching DSL that can help you build complex searches directly in the AST nodes as regexes does for plain strings.\n    The presentation will be a live coding tour of how to use the tool and create your searching patterns.\n    I'll also show how to manipulate the code in the target AST nodes, allowing us to refactor the source code in an automated way. I'll share a few funny stories about how I refactored thousands of files in a week.\n\n- id: \"katsuhiko-kageyama-rubykaigi-2020-takeout\"\n  title: \"Now is the time to create your own (m)Ruby computer\"\n  raw_title: \"[EN] Now is the time to create your own (m)Ruby computer / Katsuhiko Kageyama @kishima\"\n  speakers:\n    - Katsuhiko Kageyama\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"N24gfQJMXfs\"\n  language: \"English\"\n  description: |-\n    Now is the time to create your own (m)Ruby computer\n    mruby has been known as a good tool for supporting server applications and embedded softwares like an IoT application on a small CPU whose resource is limited. Now times are changing. mruby gets more power from recent micro processors. I believe now Ruby engineers can create their own computer as per their wish. Basic process and essential technique how to create an original (m)Ruby computer will be shown in the talk with a live demonstration of the computer.\n\n- id: \"yoh-osaki-rubykaigi-2020-takeout\"\n  title: \"Asynchronous Opal\"\n  raw_title: \"[JA] Asynchronous Opal / Yoh Osaki @youchan\"\n  speakers:\n    - Yoh Osaki\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"yDUmMuPdSUA\"\n  language: \"Japanese\"\n  description: |-\n    Opal is a compiler convert from Ruby to JavaScript. JavaScript has async/await syntax for asynchronous processing. But Opal hasn't implemented it yet. The Opal community had been discussed mapping Fiber semantics to JavaScript async/await. The conclusion was it is impossible to map coroutine such as Fiber because async/await is just a syntax sugar that expresses nested callbacks into flat statements. I'm going to talk about the idea I'm trying to incorporate easy-to-use asynchronous processing into Opal.\n\n- id: \"masatoshi-seki-rubykaigi-2020-takeout\"\n  title: \"Rinda in the real-world embedded systems\"\n  raw_title: \"[JA] Rinda in the real-world embedded systems / Masatoshi SEKI @m_seki\"\n  speakers:\n    - Masatoshi SEKI\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"qwe6qmtxHbk\"\n  language: \"Japanese\"\n  description: |-\n    Okayama Astrophysical Observatory Wide-Field Camera (OAOWFC), is an autonomous wide-field near-infrared camera and has been in operation since 2015. A distributed control system is operated via control software using Rinda. I report the implementation of the robot telescope 🤖🔭.\n\n- id: \"lin-yu-hsiang-rubykaigi-2020-takeout\"\n  title: \"mruby-rr: Time Traveling Debugger For mruby Using rr\"\n  raw_title: \"[EN] mruby-rr: Time Traveling Debugger For mruby Using rr / Lin Yu Hsiang @johnlinvc\"\n  speakers:\n    - Lin Yu Hsiang\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"E5ifh9yZCKk\"\n  language: \"English\"\n  description: |-\n    Debugging bugs that don't happen every time is painful. It needs both technique and luck. When dealing with these, a mistyped continue command is irreversible and will take us a whole afternoon just to reproduce the issue again.\n\n    mruby-rr comes to rescue! It's a Time Traveling Debugger for mruby that based on Mozilla's rr. mruby-rr supports record and replay of mruby program execution. We can record the tough bug using mruby-rr for just once. Afterwards we can playback the execution as many times as we want. mruby-rr can also do time traveling operations like reverse-next and evaluating expressions.\n\n- id: \"yuji-yokoo-rubykaigi-2020-takeout\"\n  title: \"Developing your Dreamcast apps and games with mruby\"\n  raw_title: \"[EN] Developing your Dreamcast apps and games with mruby / Yuji Yokoo @yuji_yokoo\"\n  speakers:\n    - Yuji Yokoo\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"oqBTlYUkGXk\"\n  language: \"English\"\n  description: |-\n    What would you make, if you can run your Ruby code on Dreamcast?\n\n    Well, now you can! I have been working on my development setup for running mruby code on Dreamcast. I would like to show you what I have developed so far and how you can get started. I would also like to tell you why development on Dreamcast is a great idea and share a few things I learned along the way.\n\n- id: \"aaron-patterson-rubykaigi-2020-takeout\"\n  title: \"Don't @ me! Instance Variable Performance in Ruby\"\n  raw_title: \"[EN] Don't @ me! Instance Variable Performance in Ruby / Aaron Patterson @tenderlove\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"4ysxA8DDplQ\"\n  language: \"English\"\n  description: |-\n    Japanese version: https://youtu.be/iDW93fAp2I8\n\n\n    How do instance variables work? We've all used instance variables in our programs, but how do they actually work? In this presentation we'll look at how instance variables are implemented in Ruby. We'll start with a very strange benchmark, then dive in to Ruby internals to understand why the code behaves the way it does. Once we've figured out this strange behavior, we'll follow up with a patch to increase instance variable performance. Be prepared for a deep dive in to a weird area of Ruby, and remember: don't @ me!\n\n- id: \"aaron-patterson-rubykaigi-2020-takeout-dont-me-instance-variable-perf\"\n  title: \"Don't @ me! Instance Variable Performance in Ruby\"\n  raw_title: \"[JA] Don't @ me! Instance Variable Performance in Ruby / Aaron Patterson @tenderlove\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"iDW93fAp2I8\"\n  language: \"Japanese\"\n  description: |-\n    English version: https://youtu.be/4ysxA8DDplQ\n\n\n    How do instance variables work? We've all used instance variables in our programs, but how do they actually work? In this presentation we'll look at how instance variables are implemented in Ruby. We'll start with a very strange benchmark, then dive in to Ruby internals to understand why the code behaves the way it does. Once we've figured out this strange behavior, we'll follow up with a patch to increase instance variable performance. Be prepared for a deep dive in to a weird area of Ruby, and remember: don't @ me!\n\n- id: \"hideki-miura-rubykaigi-2020-takeout\"\n  title: \"Ruby to C Translator by AI\"\n  raw_title: \"[JA] Ruby to C Translator by AI / Hideki Miura @miura1729\"\n  speakers:\n    - Hideki Miura\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"kr2RXLoiLNA\"\n  language: \"Japanese\"\n  description: |-\n    I am developing Ruby to C Translator \"MMC\". This uses AI (i.e. Abstract Interpretation) for Type Profiling and Escape Analysis. MMC generates very efficient C code by AI. For example , MMC gains about 50 times faster than CRuby for ao-bench (faster than C version). I will presentation the technical detail of MMC especially escape analysis.\n\n- id: \"itoyanagi-sakura-rubykaigi-2020-takeout\"\n  title: \"The Complex Nightmare of the Asian Cultural Area\"\n  raw_title: \"[EN] The Complex Nightmare of the Asian Cultural Area / ITOYANAGI Sakura @aycabta\"\n  speakers:\n    - ITOYANAGI Sakura\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"s7Zc7VJMBv8\"\n  language: \"English\"\n  description: |-\n    There are many different cultures in Asia that seem odd to the rest of the world. This session introduces the complexities of the current situation and the various technologies that have been created to achieve their goals.\n\n- id: \"hiroshi-shibata-rubykaigi-2020-takeout\"\n  title: \"Dependency Resolution with Standard Libraries\"\n  raw_title: \"[JA] Dependency Resolution with Standard Libraries\"\n  speakers:\n    - Hiroshi Shibata\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"wvayhyTEL_k\"\n  language: \"Japanese\"\n  description: |-\n    I maintain the RubyGems, Bundler and the standard libraries of the Ruby language. So, I have a plan to make all of the standard libraries to default gems at Ruby 3. In the past, I described the detail of default gems and bundled gems at RubyKaigi and the Ruby conferences in the world. But the users still confused the differences standard libraries and default/bundled gems.\n\n    After releasing Ruby 3, We need to learn about the dependency is not only \"Versioning\" with default gems. It caused by the between library and library over the versioning. For that reason, I need to describe the motivation of \"Promoting/Demoting the Default Gems or Bundle Gems\" continuously. You will learn the resolution mechanism on RubyGems/Bundler and the standard libraries of the Ruby language with my talk.\n\n- id: \"oda-hirohito-rubykaigi-2020-takeout\"\n  title: \"msgraph: Microsoft Graph API Client with Ruby\"\n  raw_title: \"[JA] msgraph: Microsoft Graph API Client with Ruby / ODA Hirohito @jimlock\"\n  speakers:\n    - ODA Hirohito\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"TrVhnrTPtoI\"\n  language: \"Japanese\"\n  description: |-\n    msgraph is the unofficial Microsoft Graph API Client with Ruby. The official Microsoft Graph Client Library for Ruby is microsoft_graph. However, since its release on August 1, 2016, the preview version has been continued and has not been maintained. So, I created an API client that I can maintain on my own.\n\n    In this talk, I will talk about why I created the unofficial API Client.\n\n- id: \"shugo-maeda-rubykaigi-2020-takeout\"\n  title: \"Magic is organizing chaos\"\n  raw_title: \"[JA] Magic is organizing chaos / Shugo Maeda @shugomaeda\"\n  speakers:\n    - Shugo Maeda\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"QKiQiK7gSHQ\"\n  language: \"Japanese\"\n  description: |-\n    The power of Law (e.g., type signatures, type checkers, type profilers) is growing toward Ruby 3. We need the power of Chaos for the Cosmic Balance.\n\n    In this talk, I propose Proc#using to extend area where Refinements can be used.\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2020-takeout\"\n  title: \"Keynote: Ruby 3 and Beyond\"\n  raw_title: '[JA Keynote] Ruby3 and Beyond / Yukihiro \"Matz\" Matsumoto @yukihiro_matz'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"wVrJZReHlM8\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"koichi-ito-rubykaigi-2020-takeout\"\n  title: \"Road to RuboCop 1.0\"\n  raw_title: \"[JA] Road to RuboCop 1.0 / Koichi ITO @koic\"\n  speakers:\n    - Koichi ITO\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"jkY7J9k6mHs\"\n  language: \"Japanese\"\n  description: |-\n    RuboCop 1.0 is coming soon.\n\n    RuboCop 1.0 introduces several new features and breaking changes to go to the stable major version 1.0! In this presentation, I will talk about how the milestones for RuboCop 1.0 has been implemented. For examples, gemified departments, safe annotate, new cop status, and others.\n\n    RuboCop 1.0 will provide the safest static analysis in the all‐time previous releases. The pragmatic meaning of them has emerged during the implementation process. This talk will help you ride on RuboCop 1.0.\n\n- id: \"sutou-kouhei-rubykaigi-2020-takeout\"\n  title: \"Goodbye fat gem\"\n  raw_title: \"[JA] Goodbye fat gem / Sutou Kouhei @ktou\"\n  speakers:\n    - Sutou Kouhei\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"tGZiCqyMU_g\"\n  language: \"Japanese\"\n  description: |-\n    Fat gem mechanism is useful to install extension library without any compiler. Fat gem mechanism is especially helpful for Windows rubyists because Windows rubyists don't have compiler. But there are some downsides. For example, fat gem users can't use Ruby 2.7 (the latest Ruby) until fat gem developers release a new gem for Ruby 2.7. As of 2020, pros of fat gem mechanism is decreasing and cons of it is increasing. This talk describes the details of pros and cons of it then says thanks and goodbye to fat gem.\n\n- id: \"urabe-shyouhei-rubykaigi-2020-takeout\"\n  title: \"On sending methods\"\n  raw_title: \"[JA] On sending methods / Urabe, Shyouhei @shyouhei\"\n  speakers:\n    - Shyouhei Urabe\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"IAkrGf9XJi0\"\n  language: \"Japanese\"\n  description: |-\n    As you have noticed 2.7 is faster than older ruby versions. One of the main reason for this is my optimisation around method invocations. Let me share what was suboptimal, and how was that fixed.\n\n- id: \"yusuke-endoh-rubykaigi-2020-takeout\"\n  title: \"Type Profiler: a Progress Report of a Ruby 3 Type Analyzer\"\n  raw_title: \"[JA] Type Profiler: a Progress Report of a Ruby 3 Type Analyzer / Yusuke Endoh @mametter\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"6KcFdQWp8W0\"\n  language: \"Japanese\"\n  description: |-\n    Type Profiler is a type inference tool for plain Ruby code. It analyzes Ruby code that has no type information and guesses a type of the modules and methods in the code. The output will serve as a signature for external type checkers like Sorbet and Steep. Since 2019, we have been developing the tool as one of the key features for Ruby 3 static analysis, and now it works with some practical applications. In this talk, we briefly explain what and how Type Profiler works, present a roadmap and progress of the development, and discuss how useful it is for practical applications with some demos.\n\n- id: \"koichi-sasada-rubykaigi-2020-takeout\"\n  title: \"Ractor report\"\n  raw_title: \"[JA] Ractor report / Koichi Sasada @ko1\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"40t8EPpnujg\"\n  language: \"Japanese\"\n  description: |-\n    This talk will introduce Ractor, the concurrency system for Ruby 3 based on actual implementation.\n\n    At RubyKaigi 2016, I proposed Guild (A proposal of new concurrency model for Ruby 3, http://rubykaigi.org/2016/presentations/ko1.html) and at RubyKaigi 2018, I introduced prototype of it (Guild Prototype - RubyKaigi 2018, https://rubykaigi.org/2018/presentations/ko1.html). For Ruby 3, we renamed Guild to Ractor and finished the first implementation. This talk will introduce Ractor API with current implementation.\n\n- id: \"benoit-daloze-rubykaigi-2020-takeout\"\n  title: \"Running Rack and Rails Faster with TruffleRuby\"\n  raw_title: \"[EN] Running Rack and Rails Faster with TruffleRuby / Benoit Daloze @eregontp\"\n  speakers:\n    - Benoit Daloze\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"281YdMYRAsk\"\n  language: \"English\"\n  description: |-\n    Optimizing Rack and Rails applications with a just-in-time (JIT) compiler is a challenge. For example, MJIT does not speed up Rails currently. TruffleRuby tackles this challenge. We have been running the Rails Simpler Benchmarks with TruffleRuby and now achieve higher performance than any other Ruby implementation.\n\n    In this talk we’ll show how we got there and what TruffleRuby optimizations are useful for Rack and Rails applications. TruffleRuby is getting ready to speed up your applications, will you try it?\n\n- id: \"ernesto-tagwerker-rubykaigi-2020-takeout\"\n  title: \"RubyMem: The Leaky Gems Database for Bundler\"\n  raw_title: \"[EN] RubyMem: The Leaky Gems Database for Bundler / Ernesto Tagwerker @etagwerker\"\n  speakers:\n    - Ernesto Tagwerker\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  slides_url: \"https://speakerdeck.com/etagwerker/rubymem-the-leaky-gems-database-for-bundler-at-ruby-kaigi-takeout-2020\"\n  video_provider: \"youtube\"\n  video_id: \"ghaA6LD5OEo\"\n  language: \"English\"\n  description: |-\n    Out of memory errors are quite tricky. Our first reaction is always the same: \"It can't be my code, it must be one of my dependencies!\" What if you could quickly check that with bundler?\n\n    In this talk you will learn about memory leaks, out of memory errors, and leaky dependencies. You will learn how to use bundler-leak, a community-driven, open source tool that will make your life easier when debugging memory leaks.\n\n- id: \"kevin-newton-rubykaigi-2020-takeout\"\n  title: \"Prettier Ruby\"\n  raw_title: \"[EN] Prettier Ruby / Kevin Deisz @kddeisz\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"3945FmGGHhw\"\n  language: \"English\"\n  description: |-\n    Prettier was created in 2017 and has since seen a meteoric rise within the JavaScript community. It differentiated itself from other code formatters and linters by supporting minimal configuration, eliminating the need for long discussions and arguments by enforcing an opinionated style on its users. That enforcement ended up resonating well, as it allowed developers to get back to work on the more important aspects of their job.\n\n    Since then, it has expanded to support other languages and markup, including Ruby. The Ruby plugin is now in use in dozens of applications around the world, and better formatting is being worked on daily. This talk will give you a high-level overview of prettier and how to wield it in your project. It will also dive into the nitty gritty, showing how the plugin was made and how you can help contribute to its growth. You’ll come away with a better understanding of Ruby syntax, knowledge of a new tool and how it can be used to help your team.\n\n- id: \"samuel-williams-rubykaigi-2020-takeout\"\n  title: \"Don't Wait For Me! Scalable Concurrency for Ruby 3!\"\n  raw_title: \"[EN] Don't Wait For Me! Scalable Concurrency for Ruby 3! / Samuel Williams @ioquatix\"\n  speakers:\n    - Samuel Williams\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-09\"\n  video_provider: \"youtube\"\n  video_id: \"Y29SSOS4UOc\"\n  language: \"English\"\n  description: |-\n    We have proven that fibers are useful for building scalable systems. In order to develop this further, we need to add hooks into the various Ruby VMs so that we can improve the concurrency of existing code without changes. There is an outstanding PR for this work, but additional effort is required to bring this to completion and show its effectiveness in real world situations. We will discuss the implementation of this PR, the implementation of the corresponding Async Scheduler, and how they work together to improve the scalability of Ruby applications.\n\n- id: \"ruby-committers-rubykaigi-2020-takeout\"\n  title: \"Ruby Committers vs the World - Day 1\"\n  raw_title: \"Ruby committers vs the World - Day 1 (extended)\"\n  speakers:\n    - Ruby Committers # TODO: list each person\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-09-15\"\n  video_provider: \"youtube\"\n  video_id: \"D-AK1x4vuRU\"\n  description: |-\n    https://rubykaigi.org/2020-takeout/presentations/rubylangorg.html#sep04\n\n- id: \"ruby-committers-rubykaigi-2020-takeout-ruby-committers-vs-the-world-d\"\n  title: \"Ruby Committers vs the World - Day 2\"\n  raw_title: \"Ruby committers vs the World - Day 2\"\n  speakers:\n    - Ruby Committers # TODO: list each person\n  event_name: \"RubyKaigi Takeout 2020\"\n  date: \"2020-09-04\"\n  published_at: \"2020-10-10\"\n  video_provider: \"youtube\"\n  video_id: \"20VDvtpjGn0\"\n  description: |-\n    https://rubykaigi.org/2020-takeout/presentations/rubylangorg.html#sep05\n\n    Ruby core all stars on stage!\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2021/event.yml",
    "content": "---\nid: \"PLbFmgWm555yYgc4sx2Dkb7WWcfflbt6AP\"\ntitle: \"RubyKaigi Takeout 2021\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: \"\"\npublished_at: \"2021-09-11\"\nstart_date: \"2021-09-09\"\nend_date: \"2021-09-11\"\nchannel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\nyear: 2021\nbanner_background: \"#EBE0CE\"\nfeatured_background: \"#EBE0CE\"\nfeatured_color: \"#0B374D\"\nwebsite: \"https://rubykaigi.org/2021-takeout/\"\ncoordinates: false\naliases:\n  - RubyKaigi 2021 Takeout\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2021/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"hiroshi-shibata-rubykaigi-2021-takeout\"\n  title: \"How to develop the Standard Libraries of Ruby?\"\n  raw_title: \"[JA] How to develop the Standard Libraries of Ruby? / Hiroshi SHIBATA @hsbt\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"0yZ2fle1zTo\"\n  language: \"Japanese\"\n  description: |-\n    I maintain the RubyGems, Bundler and the standard libraries of the Ruby language. So, I've been extract many of the standard libraries to default gems and GitHub at Ruby 3.0. But the some of libraries still remains in only Ruby repository. I will describe these situation.\n\n    So, Rubyists can submit a pull-request for the default gems like net-http, irb or etc after Ruby 3.0. We need to learn about the mechanism of the default gems. and also learn the bundled gems. I will describe a technic for developing the standard libraries with GitHub..\n\n    RubyKaigi Takeout: https://rubykaigi.org/2021-takeout/presentations/hsbt.html\n\n- id: \"misaki-shioi-rubykaigi-2021-takeout\"\n  title: \"Toycol: Define your own application protocol\"\n  raw_title: \"[JA] Toycol: Define your own application protocol / Misaki Shioi @shioimm\"\n  speakers:\n    - Misaki Shioi\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"zfuYguzvlbg\"\n  language: \"Japanese\"\n  description: |-\n    TCP/IP is the protocol stack where each layer is independent.\n\n    So what is a protocol? - It is a set of rules for communication between network nodes. What if you could change these rules at will? For example, why not change our familiar HTTP/1.x to a different communication style?\n\n    I’ve created a minimal framework that translates the custom toy application protocol for the Web into HTTP/1.x, with which you can define the protocol that clients and servers understand. In this talk, I'd like to show the flexibility of this framework with some examples of both nodes that speak in given protocols.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/coe401_.html\n\n- id: \"daniel-magliola-rubykaigi-2021-takeout\"\n  title: \"Do regex dream of Turing Completeness?\"\n  raw_title: \"[EN] Do regex dream of Turing Completeness? / Daniel Magliola @dmagliola\"\n  speakers:\n    - Daniel Magliola\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"hkDZCFBlD5Q\"\n  language: \"English\"\n  description: |-\n    We're used to using Regular Expressions every day for pattern matching and text replacement, but... What can Regexes actually do? How far can we push them? Can we implement actual logic with them?\n\n    What if I told you... You can actually implement Conway's Game of Life with just a Regex? What if I told you... You can actually implement ANYTHING with just a Regex?\n\n    Join me on a wild ride exploring amazing Game of Life patterns, unusual Regex techniques, Turing Completeness, programatically generating complex Regexes with Ruby, and what all this means for our understanding of what a Regex can do.\n\n    RubyKaigi 2021: https://rubykaigi.org/2021-takeout/presentations/dmagliola.html\n\n- id: \"jeremy-evans-rubykaigi-2021-takeout\"\n  title: \"Optimizing Partial Backtraces in Ruby 3\"\n  raw_title: \"[EN] Optimizing Partial Backtraces in Ruby 3 / Jeremy Evans @jeremyevans\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"QDbj4Y0E5xo\"\n  language: \"English\"\n  description: |-\n    Backtraces are very useful tools when debugging problems in Ruby programs. Unfortunately, backtrace generation is expensive for deep callstacks. In older versions of Ruby, this is true even if you only want a partial backtrace, such as a single backtrace frame. Thankfully, Ruby 3 has been optimized so that it no longer processes unnecessary backtrace frames, which can greatly speed up the generation of partial backtraces. Join me for an interesting look a Ruby backtraces, how they are generated, how we optimized partial backtraces in Ruby 3, and how we fixed bugs in the optimization in 3.0.1.\n\n    RubyKaigi Takeout: https://rubykaigi.org/2021-takeout/presentations/jeremyevans0.html\n\n- id: \"masatoshi-seki-rubykaigi-2021-takeout\"\n  title: \"dRuby in the real-world embedded systems.\"\n  raw_title: \"[JA] dRuby in the real-world embedded systems. / @seki and @t-sono1809\"\n  speakers:\n    - Masatoshi SEKI\n    - Tatsuya Sonokawa\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"kkXKHPRxeyM\"\n  language: \"Japanese\"\n  description: |-\n    Masatoshi SEKI @seki\n    Tatsuya Sonokawa @t-sono1809\n\n    We will report an example of using dRuby and CRuby (not mruby) in embedded software for small medical devices. In this talk, we will discuss the architecture of our products.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/m_seki.html\n\n- id: \"elct9620-rubykaigi-2021-takeout\"\n  title: \"It is time to build your mruby VM on the microcontroller?\"\n  raw_title: \"[EN] It is time to build your mruby VM on the microcontroller? / 蒼時弦也 @elct9620\"\n  speakers:\n    - elct9620\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"IqZW3i7HbmY\"\n  language: \"English\"\n  description: |-\n    In 2020, I find a mini-arcade maker product that uses ESP8622 and MicroPython. Since I know the mruby/c can run on the ESP32 but it doesn't support running on the ESP8622. Is it possible to implement our own mruby VM and execute Ruby on any microcontroller we want to use it? This talk will show my progress to run a simple mruby script on the ESP8622 by implementing my own small mruby VM.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/elct9620.html\n\n- id: \"martin-j-drst-rubykaigi-2021-takeout\"\n  title: \"Regular Expressions: Amazing and Dangerous\"\n  raw_title: \"[EN] Regular Expressions: Amazing and Dangerous / Martin J. Dürst @duerst\"\n  speakers:\n    - Martin J. Dürst\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"bLzUiOm97Ps\"\n  language: \"English\"\n  description: |-\n    Many Ruby programmers use regular expressions frequently. They are an amazingly powerful tool for many different kinds of text processing. However, if not used carefully, they can also be dangerous: They may not exactly match what their writer thinks they match, and they may execute very slowly on certain inputs. This talk will help you understand regular expressions better, so that you can make good use of their amazing power while avoiding their dangerous sides. It will also discuss recent changes to Ruby in the area of regular expressions.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/duerst.html\n\n- id: \"peter-zhu-rubykaigi-2021-takeout\"\n  title: \"Variable Width Allocation: Optimizing Ruby's Memory Layout\"\n  raw_title: \"[EN] Variable Width Allocation: Optimizing Ruby's Memory Layout / @peterzhu2118 and @eightbitraptor\"\n  speakers:\n    - Peter Zhu\n    - Matt Valentine-House\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"7C3bdT6Ri2Q\"\n  language: \"English\"\n  description: |-\n    Peter Zhu @peterzhu2118\n    Matt Valentine-House @eightbitraptor\n\n    Ruby’s current memory model assumes all objects live in fixed size slots. This means that object data is often stored outside of the Ruby heap, which has implications: an object's data can be scattered across many locations, increasing complexity and causing poor locality resulting in reduced efficiency of CPU caches.\n\n    Join us as we explore how our Variable Width Allocation project will move system heap memory into Ruby heap memory, reducing system heap allocations and giving us finer control of the memory layout to optimize for performance.\n\n- id: \"mat-schaffer-rubykaigi-2021-takeout\"\n  title: \"10 years of Ruby-powered citizen science\"\n  raw_title: \"[EN] 10 years of Ruby-powered citizen science / Mat Schaffer @matschaffer\"\n  speakers:\n    - Mat Schaffer\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"Jg8PY00HDnA\"\n  language: \"English\"\n  description: |-\n    In the wake of the 2011 Tohoku earthquake and tsunami, people were worried for their safety. Safecast answered that call and went on to the largest open radiation database in the world.\n\n    10 years later our science project continues, with Ruby at its heart. Our radiation measurements span the globe and are freely available for anyone to use. And now with projects like Airnote we’re using that expertise to tackle new environmental challenges such as the California wildfires.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/matschaffer.html\n\n- id: \"maxime-chevalier-boisvert-rubykaigi-2021-takeout\"\n  title: \"YJIT - Building a new JIT Compiler inside CRuby\"\n  raw_title: \"[EN] YJIT - Building a new JIT Compiler inside CRuby / Maxime Chevalier-Boisvert @maximecb\"\n  speakers:\n    - Maxime Chevalier-Boisvert\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"PBVLf3yfMs8\"\n  language: \"English\"\n  description: |-\n    YJIT, an open source project led by a small team of developers at Shopify to incrementally build a new JIT compiler inside CRuby. Key advantages are that our compiler delivers very fast warm up, and we have complete, fine-grained control over the entire code generation pipeline. In this talk, I present the approach we are taking to implement YJIT and discuss early performance results. The talk will conclude with a discussion of what steps can be taken to unlock higher levels of performance for all JIT compilers built inside CRuby, be it YJIT, MJIT or any future JIT compiler efforts.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/maximecb.html\n\n- id: \"itoyanagi-sakura-rubykaigi-2021-takeout\"\n  title: \"Graphical Terminal User Interface of Ruby 3.1\"\n  raw_title: \"[EN] Graphical Terminal User Interface of Ruby 3.1 / ITOYANAGI Sakura @aycabta\"\n  speakers:\n    - ITOYANAGI Sakura\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"xLeLW-p43bc\"\n  language: \"English\"\n  description: |-\n    The IRB shipped with Ruby 3.1 provides a dialog window feature on the terminal to achieve autocomplete. This is implemented as a new feature in Reline, which displays a dialog in an interactive user input interface at any time you want.\n\n    In this article, I will show you how to utilize this dialog display feature of Reline, with IRB and the Ruby debugger which is a new feature in Ruby 3.1.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/aycabta.html\n\n- id: \"takashi-kokubun-rubykaigi-2021-takeout\"\n  title: \"Why Ruby's JIT was slow\"\n  raw_title: \"[EN] Why Ruby's JIT was slow / Takashi Kokubun @k0kubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"db3GHHllRyQ\"\n  language: \"English\"\n  description: |-\n    Japanese: https://youtu.be/rE5OucBHm18\n\n    In Ruby 2.6, we started to use a JIT compiler architecture called \"MJIT\", which uses a C compiler to generate native code. While it achieved Ruby 3x3 in one benchmark, we had struggled to optimize web application workloads like Rails with MJIT. The good news is we recently figured out why.\n\n    In this talk, you will hear how JIT architectures impact various benchmarks differently, and why it matters for you. You may or may not benefit from Ruby's JIT, depending on what JIT architecture we'll choose beyond the current MJIT. Let's discuss which direction we'd like to go.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/k0kubun.html\n\n- id: \"takashi-kokubun-rubykaigi-2021-takeout-why-rubys-jit-was-slow\"\n  title: \"Why Ruby's JIT was slow\"\n  raw_title: \"[JA] Why Ruby's JIT was slow / Takashi Kokubun @k0kubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"rE5OucBHm18\"\n  language: \"Japanese\"\n  description: |-\n    English: https://youtu.be/db3GHHllRyQ\n\n    In Ruby 2.6, we started to use a JIT compiler architecture called \"MJIT\", which uses a C compiler to generate native code. While it achieved Ruby 3x3 in one benchmark, we had struggled to optimize web application workloads like Rails with MJIT. The good news is we recently figured out why.\n\n    In this talk, you will hear how JIT architectures impact various benchmarks differently, and why it matters for you. You may or may not benefit from Ruby's JIT, depending on what JIT architecture we'll choose beyond the current MJIT. Let's discuss which direction we'd like to go.\n\n    https://rubykaigi.org/2021-takeout/presentations/k0kubun.html\n\n- id: \"koichi-sasada-rubykaigi-2021-takeout\"\n  title: \"The Art of Execution Control for Ruby's Debugger\"\n  raw_title: \"[JA] The Art of Execution Control for Ruby's Debugger / Koichi Sasada @ko1\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"tfXiL5wDA6Q\"\n  language: \"Japanese\"\n  description: |-\n    We introduce debug.gem (ruby/debug: Debugging functionality for Ruby), the fastest debugger for Ruby and how to make it.\n\n    Existing debuggers have performance penalty to control execution. debug.gem uses recently introduced TracePoint features to mange execution and there is (almost) no penalties.\n\n    debug.gem has more interesting features:\n\n    Remote debugging\n    IDE (VSCode) Integration\n    Thread/Ractor support\n    and more\n    In this presentation, we introduce newly created debug.gem and show the tricks to make the fastest debugger.\n\n    RubyKaigi Takeout: https://rubykaigi.org/2021-takeout/presentations/ko1.html\n\n- id: \"yusuke-endoh-rubykaigi-2021-takeout\"\n  title: \"Keynote: TypeProf for IDE: Enrich Dev-Experience without Annotations\"\n  raw_title: \"[JA][Keynote] TypeProf for IDE: Enrich Dev-Experience without Annotations / Yusuke Endoh @mame\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"uNttp63ELoE\"\n  language: \"Japanese\"\n  description: |-\n    Ruby 3.0 comes bundled with TypeProf, a code analysis tool that doesn't require so many type annotations. Its primary goal is to create type signatures for existing Ruby programs and help users to apply some external type checkers like Steep. Since the release, we have made an effort to adapt TypeProf to an integrated development environment (IDE), which allows users to enjoy many features supported in an IDE, such as browsing method type signatures inferred on the fly, find definition, find references, error checking, etc. We demonstrate TypeProf for IDE, and present its roadmap.\n\n    RubyKaigi Takeout: https://rubykaigi.org/2021-takeout/presentations/mametter.html\n\n- id: \"mike-dalessio-rubykaigi-2021-takeout\"\n  title: \"Building Native Extensions. This Could Take A While...\"\n  raw_title: \"[EN] Building Native Extensions. This Could Take A While... / Mike Dalessio @flavorjones\"\n  speakers:\n    - Mike Dalessio\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"oktN_CbOJKc\"\n  language: \"English\"\n  description: |-\n    \"Native gems\" contain pre-compiled libraries for a specific machine architecture, removing the need to compile the C extension or to install other system dependencies. This leads to a much faster and more reliable installation experience for programmers.\n\n    This talk will provide a deep look at the techniques and toolchain used to ship native versions of Nokogiri and other rubygems with C extensions. Gem maintainers will learn how to build native versions of their own gems, and developers will learn how to use and deploy pre-compiled packages.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/flavorjones.html\n\n- id: \"kevin-newton-rubykaigi-2021-takeout\"\n  title: \"Parsing Ruby\"\n  raw_title: \"[EN] Parsing Ruby / Kevin Newton @kddnewton\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"ijPE7k7iW8I\"\n  language: \"English\"\n  description: |-\n    Since Ruby's inception, there have been many different projects that parse Ruby code. This includes everything from development tools to Ruby implementations themselves. This talk dives into the technical details and tradeoffs of how each of these tools parses and subsequently understands your applications. After, we'll discuss how you can do the same with your own projects using the Ripper standard library. You'll see just how far we can take this library toward building useful development tools.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/kddnewton.html\n\n- id: \"nick-schwaderer-rubykaigi-2021-takeout\"\n  title: \"Ruby Archaeology\"\n  raw_title: \"[EN] Ruby Archaeology / Nick Schwaderer @schwad\"\n  speakers:\n    - Nick Schwaderer\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"qv4XniFPapQ\"\n  language: \"English\"\n  description: |-\n    In 2009 _why tweeted: \"programming is rather thankless. you see your works become replaced by superior works in a year. unable to run at all in a few more.\"\n\n    I take this as a call to action to run old code. In this talk we dig, together, through historical Ruby. We will have fun excavating interesting gems from the past.\n\n    Further, I will answer the following questions:\n\n    - What code greater than 12 years old still runs in Ruby 3.0?\n    - What idioms have changed?\n    -  And for the brave: how can you set up an environment to run Ruby 1.8 code from ~2008 on a modern machine?\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/schwad4hd14.html\n\n- id: \"chris-seaton-rubykaigi-2021-takeout\"\n  title: \"Keynote: The Future Shape of Ruby Objects\"\n  raw_title: \"[EN][Keynote] The Future Shape of Ruby Objects / Chris Seaton @chrisseaton\"\n  speakers:\n    - Chris Seaton\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"RqwVEw-Rd5c\"\n  language: \"English\"\n  description: |-\n    TruffleRuby uses an optimisation called object shapes to optimise Ruby. It automatically learns and understands the layout and types, or the shape, of your objects as your code is running and optimises code to work better with those shapes. As the community tries to make MRI faster, it could be time to adopt object shapes there as well. We’ll talk about what TruffleRuby does, how it does it, and the benefits it achieves in practice.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/chrisgseaton.html\n\n- id: \"ufuk-kayserilioglu-rubykaigi-2021-takeout\"\n  title: \"Demystifying DSLs for better analysis and understanding\"\n  raw_title: \"[EN] Demystifying DSLs for better analysis and understanding / Ufuk Kayserilioglu @paracycle\"\n  speakers:\n    - Ufuk Kayserilioglu\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"Ms7_PrryvMM\"\n  language: \"English\"\n  description: |-\n    The ability to create DSLs is one of the biggest strengths of Ruby. They allow us to write easy to use interfaces and reduce the need for boilerplate code. On the flip side, DSLs encapsulate complex logic which makes it hard for developers to understand what's happening under the covers.\n\n    Surfacing DSLs as static artifacts makes working with them much easier. Generating RBI/RBS files that declare the methods which are dynamically created at runtime, allows static analyzers like Sorbet or Steep to work with DSLs. This also allows for better developers tooling and as some kind of \"DSL linter\".\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/paracycle.html\n\n- id: \"vinicius-stock-rubykaigi-2021-takeout\"\n  title: \"Parallel testing with Ractors: putting CPUs to work\"\n  raw_title: \"[EN] Parallel testing with Ractors: putting CPUs to work / Vinicius Stock @vinistock\"\n  speakers:\n    - Vinicius Stock\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"bvFj6_dulSo\"\n  language: \"English\"\n  description: |-\n    Parallelizing tests is an opportune way of reducing the total runtime for a test suite. Rails achieves this by forking multiple separate workers that fetch tests from a queue. In Ruby 3, Ractors introduced new mechanisms for executing code in parallel. Can they be leveraged by a test framework? And how would that compare to current parallelization solutions?\n\n    Let’s find the answers to these questions by building a test framework built on Ractors, from scratch. We’ll compare the current solutions for parallelization and what advantages or limitations Ractors bring when used in this context.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/vinistock.html\n\n- id: \"masataka-kuwabara-rubykaigi-2021-takeout\"\n  title: \"The newsletter of RBS updates\"\n  raw_title: \"[JA] The newsletter of RBS updates / Masataka Kuwabara @pocke\"\n  speakers:\n    - Masataka Kuwabara\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"AwuSHC6j-48\"\n  language: \"Japanese\"\n  description: |-\n    I talk about the RBS updates between Ruby 3.0 and 3.1 in this talk.\n\n    RBS for Ruby 3.1 will be released with many changes. I'll pick up and describe some features for this talk.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/p_ck_.html\n\n- id: \"satoshi-moris-tagomori-rubykaigi-2021-takeout\"\n  title: \"Ractor's speed is not light-speed\"\n  raw_title: '[EN] Ractor''s speed is not light-speed / Satoshi \"moris\" Tagomori @tagomoris'\n  speakers:\n    - Satoshi \"moris\" Tagomori\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"TR_3xFPCGO8\"\n  language: \"English\"\n  description: |-\n    Ractor is the new feature, introduced in Ruby 3.0, to run Ruby code on multiple CPU cores. But unfortunately, Ruby 3.0 is not fully ready for actual workloads. This session will show how we can improve web-app performance by Ractor, and what we have to do to run our web apps on Ractor.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/tagomoris.html\n\n- id: \"benoit-daloze-rubykaigi-2021-takeout\"\n  title: \"Just-in-Time Compiling Ruby Regexps on TruffleRuby\"\n  raw_title: \"[EN] Just-in-Time Compiling Ruby Regexps on TruffleRuby / @eregon and @djoooooe\"\n  speakers:\n    - Benoit Daloze\n    - Josef Haider\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"DYPCkR7Ngx8\"\n  language: \"English\"\n  description: |-\n    Benoit Daloze @eregon\n    Josef Haider @djoooooe\n\n    TruffleRuby together with Truffle Regex can now execute Ruby Regexps up to 40 times faster than CRuby! This is possible by just-in-time compiling Ruby Regexps to machine code by using Truffle Regex, a Truffle language for regular expressions. Truffle Regex uses finite-state machines, a much faster alternative to backtracking regexp engines. Because of the unique capability of GraalVM to inline across languages, the Ruby code and the Regexp are optimized and compiled together for ultimate performance.\n\n    RubyKaigi Takeout: https://rubykaigi.org/2021-takeout/presentations/eregontp.html\n\n- id: \"sutou-kouhei-rubykaigi-2021-takeout\"\n  title: \"Red Arrow - Ruby and Apache Arrow\"\n  raw_title: \"[JA] Red Arrow - Ruby and Apache Arrow / Sutou Kouhei @kou\"\n  speakers:\n    - Sutou Kouhei\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"okXiuYiP2C4\"\n  language: \"Japanese\"\n  description: |-\n    To use Ruby for data processing widely, Apache Arrow support is important.\n\n    We can do the followings with Apache Arrow:\n\n    - Super fast large data interchange and processing\n    - Reading/writing data in several famous formats such as CSV and Apache Parquet\n    - Reading/writing partitioned large data on cloud storage such as Amazon S3\n\n    This talk describes the followings:\n\n    - What is Apache Arrow\n    - How to use Apache Arrow with Ruby\n    - How to integrate with Ruby 3.0 features such as MemoryView and Ractor\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/ktou.html\n\n- id: \"kenta-murata-rubykaigi-2021-takeout\"\n  title: \"Charty: Statistical data visualization in Ruby\"\n  raw_title: \"[JA] Charty: Statistical data visualization in Ruby / Kenta Murata @mrkn\"\n  speakers:\n    - Kenta Murata\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"iHOWyQt4y-Q\"\n  language: \"Japanese\"\n  description: |-\n    Have you ever thought it would be better to make stylish charts by Ruby for daily data visualization tasks that sometimes occur? I will make that wish come true! Using Charty, you can do it by Ruby.\n\n    Charty makes statistical data visualization easier. If you want to put error bars in a bar plot, you must calculate the mean and the 95% confidence interval before plotting. Charty performs these calculations instead of you. Moreover, Charty can recognize many data types as table data and supports files, Jupyter Notebook, JupyerLab, VSCode, and a terminal emulator as the output destination.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/mrkn.html\n\n- id: \"koichi-ito-rubykaigi-2021-takeout\"\n  title: \"RuboCop in 2021: Stable and Beyond\"\n  raw_title: \"[JA] RuboCop in 2021: Stable and Beyond / Koichi ITO @koic\"\n  speakers:\n    - Koichi ITO\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"yJF5EKM_zPw\"\n  language: \"Japanese\"\n  description: |-\n    RuboCop 1.0 stable version was released last year.\n\n    Well, ​RuboCop v1 provided a background to stable upgrade. On the other hand, RuboCop supports various coding styles and the development is a struggle against false positives and false negatives. So, the improvement must go on. This presentation shows behind the scenes of development to make RuboCop and environment surrounding it better. Finally, I will show several ideas for future RuboCop.\n\n    Through this talk, you will know about benefits and considerations for upgrading RuboCop.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/koic.html\n\n- id: \"richard-schneeman-rubykaigi-2021-takeout\"\n  title: \"Beware the Dead End!!\"\n  raw_title: \"[EN] Beware the Dead End!! / Richard Schneeman @schneems\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-11\"\n  video_provider: \"youtube\"\n  video_id: \"oL_yxJN8534\"\n  language: \"English\"\n  description: |-\n    Nothing stops a program from executing quite as fast as a syntax error. After years of “unexpected end” in my dev life, I decided to “do” something about it. In this talk we'll cover lexing, parsing, and indentation informed syntax tree search that power that dead_end Ruby library.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/schneems.html\n\n- id: \"yamori813-rubykaigi-2021-takeout\"\n  title: \"Falling down from FreeBSD\"\n  raw_title: \"[JA] Falling down from FreeBSD / やもり @yamori813\"\n  speakers:\n    - yamori813\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-12\"\n  video_provider: \"youtube\"\n  video_id: \"JvFCljZeF1w\"\n  language: \"Japanese\"\n  description: |-\n    Why I started mruby on YABM(Yet Another Bare Metal). I describe inside of mruby and how to use it. Also I talked about IoT use case.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/yamori813.html\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2021-takeout\"\n  title: \"Keynote: Beyond Ruby 3.0\"\n  raw_title: '[JA] Matz Keynote / Yukihiro \"Matz\" Matsumoto @matz'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-12\"\n  video_provider: \"youtube\"\n  video_id: \"QQASprf5EGw\"\n  language: \"Japanese\"\n  description: |-\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/yukihiro_matz.html\n\n- id: \"hitoshi-hasumi-rubykaigi-2021-takeout\"\n  title: \"PRK Firmware: Keyboard is Essentially Ruby\"\n  raw_title: \"[JA] PRK Firmware: Keyboard is Essentially Ruby / Hitoshi HASUMI @hasumikin\"\n  speakers:\n    - HASUMI Hitoshi\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-12\"\n  video_provider: \"youtube\"\n  video_id: \"5unMW_BAd4A\"\n  language: \"Japanese\"\n  description: |-\n    PRK Firmware is the world's first keyboard firmware framework in Ruby. You can write not only your own \"keymap\" in Ruby but also additional behavior by features of Ruby like open class system and Proc object.\n\n    Plus, your keyboard itself interprets a Ruby script on the fly. Essentially, your keyboard can become Ruby.\n\n    The ultimate goal is certainly not a small one --- let's make Ruby comparable to projects such as MicroPython, CircuitPython or Lua in terms of viability as a scripting language for microcontrollers.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/hasumikin.html\n\n- id: \"ruby-committers-rubykaigi-2021-takeout\"\n  title: \"Ruby Committers vs the World\"\n  raw_title: \"Ruby Committers vs the World / CRuby Committers @rubylangorg\"\n  speakers:\n    - Ruby Committers # TODO: list each person\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-12\"\n  video_provider: \"youtube\"\n  video_id: \"zQnN1pqK4FQ\"\n  language: \"Japanese\"\n  description: |-\n    Ruby core committers on stage!\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/rubylangorg.html\n\n- id: \"yusuke-nakamura-rubykaigi-2021-takeout\"\n  title: \"Ruby, Ractor, QUIC\"\n  raw_title: \"[JA] Ruby, Ractor, QUIC / Yusuke Nakamura @unasuke\"\n  speakers:\n    - Yusuke Nakamura\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-12\"\n  video_provider: \"youtube\"\n  video_id: \"9da7QccHXV4\"\n  language: \"Japanese\"\n  description: |-\n    From Ruby 3, a parallel processing mechanism called Ractor has been introduced. This has made it easy to implement safe parallel processing in Ruby. In addition, QUIC, which was announced by Google in 2013, standardized in May 2021, and will be used more and more in the future. In this presentation, I will explain what QUIC is, whether it is possible to implement a QUIC server and client with Ractor introduced in Ruby 3, and if so, why it is difficult or impossible.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/yu_suke1994.html\n\n- id: \"mari-imaizumi-rubykaigi-2021-takeout\"\n  title: \"Dive into Encoding\"\n  raw_title: \"[JA] Dive into Encoding / Mari Imaizumi @ima1zumi\"\n  speakers:\n    - Mari Imaizumi\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-12\"\n  video_provider: \"youtube\"\n  video_id: \"9PA6twS9Oq4\"\n  language: \"Japanese\"\n  description: |-\n    Each Ruby String object has an encoding internally. Therefore, it can use a different encoding in the same application. It's very convenient. So, how does Ruby encode a String? What does it mean to have an encoding for each String? As they say, practice makes perfect, so I figured I could understand it by adding self-made encoding. This talk would like to try to add self-made encoding in Ruby and see how Ruby handles encodings.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/ima1zumi.html\n\n- id: \"mauro-eldritch-rubykaigi-2021-takeout\"\n  title: \"Crafting exploits, tools and havoc with Ruby\"\n  raw_title: \"[EN] Crafting exploits, tools and havoc with Ruby / Mauro Eldritch @MauroEldritch\"\n  speakers:\n    - Mauro Eldritch\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-12\"\n  video_provider: \"youtube\"\n  video_id: \"LIECErdtTDc\"\n  language: \"English\"\n  description: |-\n    Can I use ruby to ...? Create Websites? Yes Create Applications? Yes Wreak havoc, write exploits, and hack stuff? Of course!\n\n    During this session we will analyze different exploits and tools written in Ruby by the author: from scanners and bruteforcers to C2 servers and complex exploits.\n\n    Each exploit will be explained in a simple and friendly way for newcomers, and different samples and libraries will be shared so that anyone interested can start building its ruby-powered hacking toolbox.\n\n    There will also be a short lab demo of these tools. Take a seat, grab an exploit, hack stuff.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/MauroEldritch.html\n\n- id: \"uchio-kondo-rubykaigi-2021-takeout\"\n  title: \"Story of Rucy - How to compile a BPF binary from Ruby\"\n  raw_title: '[EN] Story of Rucy - How to \"compile\" a BPF binary from Ruby / Uchio KONDO @udzura'\n  speakers:\n    - Uchio KONDO\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-12\"\n  video_provider: \"youtube\"\n  video_id: \"qvaXv8exFFQ\"\n  language: \"English\"\n  description: |-\n    BPF is a technology used in Linux for packet filtering, tracing or access auditing. BPF has its own VM and set of opcodes.\n\n    If you want to write a program that loads and uses BPF binary, you can write it in any language including Ruby.\n\n    However, to prepare a \"BPF binary\" itself, you generally need to write a bit weird C, and pass it to clang compiler using bpf target.\n\n    Wouldn't it be great if we could make these BPF binaries entirely in Ruby?\n\n    Rucy is intended to allow programmers to write their whole BPF programs in Ruby. I'll discuss how to \"compile\" BPF binaries from Ruby in this talk.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/udzura.html\n\n- id: \"osyo-rubykaigi-2021-takeout\"\n  title: \"Use Macro all the time ~ マクロを使いまくろ ~\"\n  raw_title: \"[JA] Use Macro all the time ~ マクロを使いまくろ ~ / osyo @osyo-manga\"\n  speakers:\n    - osyo-manga\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-12\"\n  video_provider: \"youtube\"\n  video_id: \"w2B99qYrkX8\"\n  language: \"Japanese\"\n  description: |-\n    Ruby can get AST with RubyVM::AbstractSyntaxTree. I have implemented to convert AST into Ruby code. This will allow you to modify and execute Ruby code at AST level.\n\n    Ruby code → Convert to AST → Convert to another AST → Convert AST to Ruby code → Run Ruby code\n\n    In this session, I will discuss \"Implementations for converting AST to Ruby code\" and \"Implementations for converting AST to another AST\". This feature of \"converting to another AST\" is similar to what is called a \"Macro\" in other languages. Let's think together about what happens when we implement \"Macro\" in Ruby.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/pink_bangbi.html\n\n- id: \"shugo-maeda-rubykaigi-2021-takeout\"\n  title: \"include/prepend in refinements should be prohibited\"\n  raw_title: \"[JA] include/prepend in refinements should be prohibited / Shugo Maeda @shugo\"\n  speakers:\n    - Shugo Maeda\n  event_name: \"RubyKaigi Takeout 2021\"\n  date: \"2021-09-09\"\n  published_at: \"2021-09-12\"\n  video_provider: \"youtube\"\n  video_id: \"b4ls7Y_vZMg\"\n  language: \"Japanese\"\n  description: |-\n    include/prepend in refinements are often used to define the same set of methods in multiple refinements. However it should be prohibited because it has implementation difficulties such as https://bugs.ruby-lang.org/issues/17007 and https://bugs.ruby-lang.org/issues/17379, and tends to be misleading like https://bugs.ruby-lang.org/issues/17374.\n\n    In this talk, I propose a new feature instead of include/prepend in refinements.\n\n    RubyKaigi Takeout 2021: https://rubykaigi.org/2021-takeout/presentations/shugomaeda.html\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2022/event.yml",
    "content": "---\nid: \"PLbFmgWm555yYwwmwMvpC-RaqnmUTKB2EO\"\ntitle: \"RubyKaigi 2022\"\nkind: \"conference\"\nlocation: \"Mie, Japan\"\ndescription: \"\"\npublished_at: \"2022-10-05\"\nstart_date: \"2022-09-08\"\nend_date: \"2022-09-10\"\nchannel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\nyear: 2022\nbanner_background: \"#FCF7EE\"\nfeatured_background: \"#FCF7EE\"\nfeatured_color: \"#2F2F34\"\nwebsite: \"https://rubykaigi.org/2022/\"\ncoordinates:\n  latitude: 34.7441867\n  longitude: 136.5017198\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2022/venue.yml",
    "content": "# https://rubykaigi.org/2022/venue/\n---\nname: \"Mie Center for the Arts\"\n\naddress:\n  street: \"Mie Center for the Arts\"\n  city: \"Mie\"\n  region: \"Mie\"\n  postal_code: \"514-0061\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"1234 Isshindenkōzubeta, Tsu, Mie 514-0061, Japan\"\n\ncoordinates:\n  latitude: 34.7441867\n  longitude: 136.5017198\n\nmaps:\n  google: \"https://maps.google.com/?q=Mie+Center+for+the+Arts,34.7441867,136.5017198\"\n  apple: \"https://maps.apple.com/?q=Mie+Center+for+the+Arts&ll=34.7441867,136.5017198\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=34.7441867&mlon=136.5017198\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2022/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"osyo-rubykaigi-2022\"\n  title: \"Let's collect type info during Ruby running and automaticall\"\n  raw_title: \"[JA]Let's collect type info during Ruby running and automaticall / osyo @pink_bangbi\"\n  speakers:\n    - osyo-manga\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"BP7UACeJpJk\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"samuel-williams-rubykaigi-2022\"\n  title: \"Real World Applications with the Ruby Fiber Scheduler\"\n  raw_title: \"[EN]Real World Applications with the Ruby Fiber Scheduler / Samuel Williams @ioquatix\"\n  speakers:\n    - Samuel Williams\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"yXyj9wlkJKM\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"chris-salzberg-rubykaigi-2022\"\n  title: \"Caching With MessagePack\"\n  raw_title: \"[EN]Caching With MessagePack / Chris Salzberg @shioyama\"\n  speakers:\n    - Chris Salzberg\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"pYSEurptls0\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"yuta-saito-rubykaigi-2022\"\n  title: \"Keynote: Ruby meets WebAssembly\"\n  raw_title: \"[JA][Keynote]Ruby meets WebAssembly / Yuta Saito @kateinoigakukun\"\n  speakers:\n    - Yuta Saito\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-10-25\"\n  video_provider: \"youtube\"\n  video_id: \"-x8pU6mGtPI\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"alan-wu-rubykaigi-2022\"\n  title: \"Keynote: Stories from developing YJIT\"\n  raw_title: \"[EN][Keynote]Stories from developing YJIT / Alan Wu @alanwusx\"\n  speakers:\n    - Alan Wu\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"EMchdR9C8XM\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"takashi-kokubun-rubykaigi-2022\"\n  title: \"Towards Ruby 4 JIT\"\n  raw_title: \"[EN]Towards Ruby 4 JIT / Takashi Kokubun @k0kubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-10-25\"\n  video_provider: \"youtube\"\n  video_id: \"Cbidkl6ApMM\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2022\"\n  title: \"Keynote: Contribute to Ruby\"\n  raw_title: '[JA][Keynote]Matz Keynote / Yukihiro \"Matz\" Matsumoto @yukihiro_matz'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"m_LW5WIYJ9Q\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"soutaro-matsumoto-rubykaigi-2022\"\n  title: \"Ruby programming with types in action\"\n  raw_title: \"[EN]Ruby programming with types in action / Soutaro Matsumoto @soutaro\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"4E4TRgMDYqo\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"fujimoto-seiji-rubykaigi-2022\"\n  title: \"How fast really is Ruby 3.x?\"\n  raw_title: \"[JA]How fast really is Ruby 3.x? / Fujimoto Seiji @fujimotos\"\n  speakers:\n    - Fujimoto Seiji\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"x9x169j6xco\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"koichi-sasada-rubykaigi-2022\"\n  title: \"Making *MaNy* threads on Ruby\"\n  raw_title: \"[JA]Making *MaNy* threads on Ruby / Koichi Sasada @ko1\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-10-25\"\n  video_provider: \"youtube\"\n  video_id: \"G0LX53QJdBE\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"ruby-committers-rubykaigi-2022\"\n  title: \"Ruby Committers vs The World\"\n  raw_title: \"[JA]Ruby Committers vs The World\"\n  speakers:\n    - Ruby Committers # TODO: list each person\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"ajm3lr6Y9yE\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"stan-lo-rubykaigi-2022\"\n  title: \"ruby/debug - The best investment for your productivity\"\n  raw_title: \"[EN]ruby/debug - The best investment for your productivity / Stan Lo @_st0012\"\n  speakers:\n    - Stan Lo\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"gseo4vdmSjE\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"jemma-issroff-rubykaigi-2022\"\n  title: \"Implementing Object Shapes in CRuby\"\n  raw_title: \"[EN]Implementing Object Shapes in CRuby / Jemma Issroff @jemmaissroff\"\n  speakers:\n    - Jemma Issroff\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"So-KvN3p-eE\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"yusuke-endoh-rubykaigi-2022\"\n  title: \"Trick 2022\"\n  raw_title: \"[JA]TRICK 2022 (Returns)\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-10-25\"\n  video_provider: \"youtube\"\n  video_id: \"tvxdccqFzmQ\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yuji-yokoo-rubykaigi-2022\"\n  title: \"Megaruby - Running mruby/c programs on Sega Mega Drive\"\n  raw_title: \"[EN]Megaruby - Running mruby/c programs on Sega Mega Drive / Yuji Yokoo @yujiyokoo\"\n  speakers:\n    - Yuji Yokoo\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"JuKYJ-G8heU\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"yuta-kurotaki-rubykaigi-2022\"\n  title: \"Ethereum for Ruby\"\n  raw_title: \"[EN]Ethereum for Ruby / Yuta Kurotaki @kurotaky\"\n  speakers:\n    - Yuta Kurotaki\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"2wut6zg22bA\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"vladimir-makarov-rubykaigi-2022\"\n  title: \"A Faster CRuby interpreter with dynamically specialized IR\"\n  raw_title: \"[EN]A Faster CRuby interpreter with dynamically specialized IR / Vladimir Makarov @vnmakarov\"\n  speakers:\n    - Vladimir Makarov\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"TGc8rccEXno\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"ivo-anjo-rubykaigi-2022\"\n  title: \"Hunting Production Memory Leaks with Heap Sampling\"\n  raw_title: \"[EN]Hunting Production Memory Leaks with Heap Sampling / @KnuX and @KJTsanaktsidis\"\n  speakers:\n    - Ivo Anjo\n    - KJ Tsanaktsidis\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"xoGJPtNp074\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"peter-zhu-rubykaigi-2022\"\n  title: \"Automatically Find Memory Leaks in Native Gems\"\n  raw_title: \"[EN]Automatically Find Memory Leaks in Native Gems / Peter Zhu @peterzhu2118\"\n  speakers:\n    - Peter Zhu\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"SchKPrZefXY\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"sutou-kouhei-rubykaigi-2022\"\n  title: \"Fast data processing with Ruby and Apache Arrow\"\n  raw_title: \"[JA]Fast data processing with Ruby and Apache Arrow / Sutou Kouhei @ktou\"\n  speakers:\n    - Sutou Kouhei\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"C_-r8IQLAVY\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"kevin-newton-rubykaigi-2022\"\n  title: \"Syntax Tree\"\n  raw_title: \"[EN]Syntax Tree / Kevin Newton @kddnewton\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"VN72YBy8KsY\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"mari-imaizumi-rubykaigi-2022\"\n  title: \"String Meets Encoding\"\n  raw_title: \"[JA]String Meets Encoding / Mari Imaizumi @ima1zumi\"\n  speakers:\n    - Mari Imaizumi\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"cRMP9-7LiLg\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"fu-ga-rubykaigi-2022\"\n  title: \"Types teaches success, what will we do?\"\n  raw_title: \"[JA]Types teaches success, what will we do? / Fu-ga @fugakkbn\"\n  speakers:\n    - Fu-ga\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-10-25\"\n  video_provider: \"youtube\"\n  video_id: \"QK2XsIHAc9U\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"masatoshi-seki-rubykaigi-2022\"\n  title: \"Create my own search engine.\"\n  raw_title: \"[JA]Create my own search engine. / Masatoshi SEKI @m_seki\"\n  speakers:\n    - Masatoshi SEKI\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"ol4MsygRnIE\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"hiroshi-shibata-rubykaigi-2022\"\n  title: \"Why is building the Ruby environment hard?\"\n  raw_title: \"[JA]Why is building the Ruby environment hard? / Hiroshi SHIBATA @hsbt\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"J5c-3HY7uH0\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"colby-swandale-rubykaigi-2022\"\n  title: \"Adding Type Signatures into Ruby Docs\"\n  raw_title: \"[EN]Adding Type Signatures into Ruby Docs / Colby Swandale @oceanicpanda\"\n  speakers:\n    - Colby Swandale\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-10-25\"\n  video_provider: \"youtube\"\n  video_id: \"ZI0Cttpsy1g\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"naoto-ono-rubykaigi-2022\"\n  title: \"Tools for Providing rich user experience in debugger\"\n  raw_title: \"[JA]Tools for Providing rich user experience in debugger / Naoto Ono @ono-max\"\n  speakers:\n    - Naoto Ono\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-10-25\"\n  video_provider: \"youtube\"\n  video_id: \"6b5TJwKKJ5U\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"nick-schwaderer-rubykaigi-2022\"\n  title: \"Ruby Archaeology: Forgotten web frameworks\"\n  raw_title: \"[EN]Ruby Archaeology: Forgotten web frameworks / Nick Schwaderer @schwad_rb\"\n  speakers:\n    - Nick Schwaderer\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-10-25\"\n  video_provider: \"youtube\"\n  video_id: \"0h9lISoqEn4\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"kazuhiro-nishiyama-rubykaigi-2022\"\n  title: \"History of Japanese Ruby reference manual, and future\"\n  raw_title: \"[JA]History of Japanese Ruby reference manual, and future / Kazuhiro NISHIYAMA @znz\"\n  speakers:\n    - Kazuhiro NISHIYAMA\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"3N93YQGOj6Q\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"koichi-ito-rubykaigi-2022\"\n  title: \"Make RuboCop super fast\"\n  raw_title: \"[JA]Make RuboCop super fast / Koichi ITO @koic\"\n  speakers:\n    - Koichi ITO\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"bMLy09UV6TY\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yamori813-rubykaigi-2022\"\n  title: \"ZRouter.org with mruby\"\n  raw_title: \"[JA]ZRouter.org with mruby / やもり @yamori813\"\n  speakers:\n    - yamori813\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-10-25\"\n  video_provider: \"youtube\"\n  video_id: \"uiwIaCS34aw\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"misaki-shioi-rubykaigi-2022\"\n  title: \"Packet analysis with mruby on Wireshark - dRuby as example\"\n  raw_title: \"[JA]Packet analysis with mruby on Wireshark - dRuby as example / Misaki Shioi @coe401_\"\n  speakers:\n    - Misaki Shioi\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"dqFogicnyLQ\"\n  language: \"Japanese\"\n  description: |-\n    Uncut version: https://youtu.be/71oVELdmR8U\n\n- id: \"misaki-shioi-rubykaigi-2022-uncut\"\n  title: \"Packet analysis with mruby on Wireshark - dRuby as example (Uncut version)\"\n  raw_title: \"[JA][uncut]Packet analysis with mruby on Wireshark - dRuby as example - Misaki Shioi @coe401_\"\n  speakers:\n    - Misaki Shioi\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"71oVELdmR8U\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yasuko-ohba-rubykaigi-2022\"\n  title: \"The Better RuboCop World to enjoy Ruby\"\n  raw_title: \"[JA]The Better RuboCop World to enjoy Ruby / Yasuko Ohba @nay3\"\n  speakers:\n    - Yasuko Ohba\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"_QY5GMVhG1c\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yusuke-endoh-rubykaigi-2022-errorhighlight-user-friendly-e\"\n  title: \"error_highlight: user-friendly error diagnostics\"\n  raw_title: \"[JA]error_highlight: user-friendly error diagnostics / Yusuke Endoh @mametter\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"SfFmhunJTEQ\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"uchio-kondo-rubykaigi-2022\"\n  title: \"Ruby x BPF in Action: How important observability is\"\n  raw_title: \"[EN]Ruby x BPF in Action: How important observability is / Uchio KONDO @udzura\"\n  speakers:\n    - Uchio KONDO\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"9OvoOVc8690\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"matt-valentine-house-rubykaigi-2022\"\n  title: \"Heaping on the complexity! An adventure in GC Compaction\"\n  raw_title: \"[EN]Heaping on the complexity! An adventure in GC Compaction / Matt Valentine-House @eightbitraptor\"\n  speakers:\n    - Matt Valentine-House\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"bHDHeFXm9kg\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"jeremy-evans-rubykaigi-2022\"\n  title: \"Fixing Assignment Evaluation Order\"\n  raw_title: \"[EN]Fixing Assignment Evaluation Order / Jeremy Evans @jeremyevans0\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"oqvFi7crbd4\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"yusuke-nakamura-rubykaigi-2022\"\n  title: \"Do Pure Ruby Dream of Encrypted Binary Protocol?\"\n  raw_title: \"[JA]Do Pure Ruby Dream of Encrypted Binary Protocol? / Yusuke Nakamura @yu_suke1994\"\n  speakers:\n    - Yusuke Nakamura\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"hCos6p_S-qc\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"kenta-murata-rubykaigi-2022\"\n  title: \"Method-based JIT compilation by transpiling to Julia\"\n  raw_title: \"[JA]Method-based JIT compilation by transpiling to Julia / Kenta Murata @Kenta Murata\"\n  speakers:\n    - Kenta Murata\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-04\"\n  video_provider: \"youtube\"\n  video_id: \"BAB26lpklj8\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yuki-kurihara-rubykaigi-2022\"\n  title: \"RBS generation framework using Rack architecture\"\n  raw_title: \"[JA]RBS generation framework using Rack architecture / Yuki Kurihara @_ksss_\"\n  speakers:\n    - Yuki Kurihara\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-11-11\"\n  video_provider: \"youtube\"\n  video_id: \"CBW_GutxCFc\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"maxime-chevalier-boisvert-rubykaigi-2022\"\n  title: \"Building a Lightweight IR and Backend for YJIT\"\n  raw_title: \"[EN]Building a Lightweight IR and Backend for YJIT / Maxime Chevalier-Boisvert @maximecb\"\n  speakers:\n    - Maxime Chevalier-Boisvert\n  event_name: \"RubyKaigi 2022\"\n  date: \"2022-11-08\"\n  published_at: \"2022-10-25\"\n  video_provider: \"youtube\"\n  video_id: \"BbLGqTxTRp0\"\n  language: \"English\"\n  description: \"\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2023/event.yml",
    "content": "---\nid: \"PLbFmgWm555yYvWS7VGTFipF7ckduvSeT-\"\ntitle: \"RubyKaigi 2023\"\nkind: \"conference\"\nlocation: \"Nagano, Japan\"\ndescription: |-\n  https://rubykaigi.org/2023/\npublished_at: \"2023-06-09\"\nstart_date: \"2023-05-11\"\nend_date: \"2023-05-13\"\nchannel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\nyear: 2023\nbanner_background: \"#F8F8F8\"\nfeatured_background: \"#F8F8F8\"\nfeatured_color: \"#333333\"\nwebsite: \"https://rubykaigi.org/2023/\"\ncoordinates:\n  latitude: 36.2299659\n  longitude: 137.9746548\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2023/venue.yml",
    "content": "---\nname: \"Matsumoto Performing Arts Centre (まつもと市民芸術館)\"\n\naddress:\n  street: \"\"\n  city: \"Matsumoto\"\n  region: \"Nagano\"\n  postal_code: \"390-0815\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"3-chōme-10-1 Fukashi, Matsumoto, Nagano 390-0815, Japan\"\n\ncoordinates:\n  latitude: 36.2299659\n  longitude: 137.9746548\n\nmaps:\n  google: \"https://maps.google.com/?q=Matsumoto+Performing+Arts+Centre+(まつもと市民芸術館),36.2299659,137.9746548\"\n  apple: \"https://maps.apple.com/?q=Matsumoto+Performing+Arts+Centre+(まつもと市民芸術館)&ll=36.2299659,137.9746548\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=36.2299659&mlon=137.9746548\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"kohei-yamada-rubykaigi-2023\"\n  title: \"DIY Your Touchpad Experience: Building Your Own Gestures\"\n  raw_title: \"[JA] DIY Your Touchpad Experience: Building Your Own Gestures / Kohei Yamada @nukumaro22\"\n  speakers:\n    - Kohei Yamada\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"gnwe8DqPDrk\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yuichiro-kaneko-rubykaigi-2023\"\n  title: \"The future vision of Ruby Parser\"\n  raw_title: \"[JA] The future vision of Ruby Parser / Yuichiro Kaneko @spikeolaf\"\n  speakers:\n    - Yuichiro Kaneko\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"IhfDsLx784g\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"genadi-samokovarov-rubykaigi-2023\"\n  title: \"RuboCop's baddest cop\"\n  raw_title: \"[EN] RuboCop's baddest cop / Genadi Samokovarov @gsamokovarov\"\n  speakers:\n    - Genadi Samokovarov\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"n-D9uPOo_kc\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"emily-samp-rubykaigi-2023\"\n  title: \"Generating RBIs for dynamic mixins with Sorbet and Tapioca\"\n  raw_title: \"[EN] Generating RBIs for dynamic mixins with Sorbet and Tapioca / Emily Samp @egiurleo\"\n  speakers:\n    - Emily Samp\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  slides_url: \"https://drive.google.com/drive/folders/1PzSj_wTHVIrZNC80IyZzuma85sVIiWTz?usp=sharing\"\n  video_provider: \"youtube\"\n  video_id: \"UpbVZ4Gqk3c\"\n  language: \"English\"\n  description: |-\n    Last year, Tapioca became the official tool for generating RBI files for Sorbet. Using Tapioca, developers can quickly generate accurate RBIs for external Ruby gems, allowing them to use Sorbet in their projects even if most gems have not yet added type signatures.\n\n    In this talk, I’ll explain how I implemented new functionality in Tapioca to help it generate RBIs for dynamic mixins in Ruby gems. Along the way, we’ll learn about how Tapioca uses information about the Ruby object model to generate RBIs, and how this work has impacted the Ruby language as a whole.\n\n- id: \"hiroya-fujinami-rubykaigi-2023\"\n  title: \"Make Regexp#match much faster\"\n  raw_title: \"[JA] Make Regexp#match much faster / Hiroya FUJINAMI @makenowjust\"\n  speakers:\n    - Hiroya Fujinami\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"IbMFHxeqpN4\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"ivo-anjo-rubykaigi-2023\"\n  title: \"Understanding the Ruby Global VM Lock by observing it\"\n  raw_title: \"[EN] Understanding the Ruby Global VM Lock by observing it / Ivo Anjo @KnuX\"\n  speakers:\n    - Ivo Anjo\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"rI4XlFvMNEw\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"yuma-sawai-rubykaigi-2023\"\n  title: \"develop chrome extension with ruby.wasm\"\n  raw_title: \"[JA] develop chrome extension with ruby.wasm / Yuma Sawai @aaaa777\"\n  speakers:\n    - Yuma Sawai\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"A2ziP8V9muE\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"koichi-sasada-rubykaigi-2023\"\n  title: \"Ractor reconsidered\"\n  raw_title: \"[EN] Ractor reconsidered / Koichi Sasada @ko1\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"Id706gYi3wk\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"frederico-linhares-rubykaigi-2023\"\n  title: \"High-performance real-time 3D graphics with Vulkan\"\n  raw_title: \"[EN] High-performance real-time 3D graphics with Vulkan / Frederico Linhares @fredolinhares\"\n  speakers:\n    - Frederico Linhares\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"Tuhk4iS3F_I\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"mari-imaizumi-rubykaigi-2023\"\n  title: \"UTF-8 is coming to mruby/c\"\n  raw_title: \"[JA] UTF-8 is coming to mruby/c / Mari Imaizumi @ima1zumi\"\n  speakers:\n    - Mari Imaizumi\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"y5rGatij0DE\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"tomoya-ishida-rubykaigi-2023\"\n  title: \"Power up your REPL life with types\"\n  raw_title: \"[JA] Power up your REPL life with types / Tomoya Ishida @tompng\"\n  speakers:\n    - Tomoya Ishida\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"VweV7ngcDEk\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"matt-valentine-house-rubykaigi-2023\"\n  title: \"Plug & Play Garbage Collection with MMTk\"\n  raw_title: \"[EN] Plug & Play Garbage Collection with MMTk / Matt Valentine-House @eightbitraptor\"\n  speakers:\n    - Matt Valentine-House\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"chhNDhyPbyc\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2023\"\n  title: \"Keynote: 30 Years of Ruby\"\n  raw_title: '[JA][Keynote] Matz Keynote / Yukihiro \"Matz\" Matsumoto @yukihiro_matz'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"184Sc0hsnek\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"akira-matsuda-rubykaigi-2023\"\n  title: \"Lightning Talks\"\n  raw_title: \"[EN][JA] Lightning Talks\"\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"c58mN6NtwsQ\"\n  language: \"Japanese\"\n  description: \"\"\n  thumbnail_lg: \"https://img.youtube.com/vi/c58mN6NtwsQ/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/c58mN6NtwsQ/hqdefault.jpg\"\n  speakers:\n    - Akira Matsuda\n  talks:\n    - title: \"Lightning Talk: Building Ruby Native Extension using Ruby\"\n      start_cue: \"00:55\"\n      end_cue: \"TODO\"\n      id: \"katsyoshi-lighting-talk-rubykaigi-2023\"\n      video_id: \"katsyoshi-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"Japanese\" # and English\n      speakers:\n        - katsyoshi\n\n    - title: \"Lightning Talk: RBS meets LLMs\"\n      start_cue: \"06:14\"\n      end_cue: \"TODO\"\n      id: \"kokuyou-lighting-talk-rubykaigi-2023\"\n      video_id: \"kokuyou-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - kokuyou\n\n    - title: \"Lightning Talk: I love VIM\"\n      start_cue: \"11:30\"\n      end_cue: \"TODO\"\n      id: \"okura-masafumi-lighting-talk-rubykaigi-2023\"\n      video_id: \"okura-masafumi-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"English\"\n      speakers:\n        - OKURA Masafumi\n\n    - title: \"Lightning Talk: mruby VM\"\n      start_cue: \"16:40\"\n      end_cue: \"TODO\"\n      id: \"yukihiro-matz-matsumoto-lighting-talk-rubykaigi-2023\"\n      video_id: \"yukihiro-matz-matsumoto-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Yukihiro \"Matz\" Matsumoto\n\n    - title: \"Lightning Talk: Natsukantou - an XML translator\"\n      start_cue: \"22:03\"\n      end_cue: \"TODO\"\n      id: \"lulalala-lighting-talk-rubykaigi-2023\"\n      video_id: \"lulalala-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"English\"\n      speakers:\n        - lulalala\n\n    - title: \"Lightning Talk: Bingo in the browser using ruby.wasm\"\n      start_cue: \"26:29\"\n      end_cue: \"TODO\"\n      id: \"shugo-maeda-lighting-talk-rubykaigi-2023\"\n      video_id: \"shugo-maeda-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Shugo Maeda\n\n    - title: \"Lightning Talk: Adding custom rule for RuboCop in the 2 month of employment\"\n      start_cue: \"31:36\"\n      end_cue: \"TODO\"\n      id: \"yla-aioi-lighting-talk-rubykaigi-2023\"\n      video_id: \"yla-aioi-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Yla Aioi\n\n    - title: \"Lightning Talk: Unexplored Region - parse.y\"\n      start_cue: \"35:53\"\n      end_cue: \"TODO\"\n      id: \"yuichiro-kaneko-lighting-talk-rubykaigi-2023\"\n      video_id: \"yuichiro-kaneko-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Yuichiro Kaneko\n\n    - title: \"Lightning Talk: Ultra-fast Test Driven Development\"\n      start_cue: \"41:07\"\n      end_cue: \"TODO\"\n      id: \"yuya-fujiwara-lighting-talk-rubykaigi-2023\"\n      video_id: \"yuya-fujiwara-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Yuya Fujiwara\n\n    - title: \"Lightning Talk: Optimizing Ruby's Memory Layout - Variable Width Allocation\"\n      start_cue: \"46:20\"\n      end_cue: \"TODO\"\n      id: \"peter-zhu-lighting-talk-rubykaigi-2023\"\n      video_id: \"peter-zhu-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"English\"\n      speakers:\n        - Peter Zhu\n\n    - title: \"Lightning Talk: Dividing and Managing - The Cops Squad of RuboCop Rspec Dept.\"\n      start_cue: \"50:09\"\n      end_cue: \"TODO\"\n      id: \"yudai-takada-lighting-talk-rubykaigi-2023\"\n      video_id: \"yudai-takada-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Yudai Takada\n\n    - title: \"Lightning Talk: Serverless IdP for Small Team\"\n      start_cue: \"54:31\"\n      end_cue: \"59:35\"\n      id: \"sorah-fukumori-lighting-talk-rubykaigi-2023\"\n      video_id: \"sorah-fukumori-lighting-talk-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"English\"\n      speakers:\n        - Sorah Fukumori\n\n    - title: \"Day Closing\"\n      start_cue: \"59:35\"\n      end_cue: \"01:01:46\"\n      id: \"sorah-fukumori-lightning-talks-closing-rubykaigi-2023\"\n      video_id: \"sorah-fukumori-lightning-talks-closing-rubykaigi-2023\"\n      video_provider: \"parent\"\n      language: \"English\" # and Japanese\n      speakers:\n        - Sorah Fukumori\n\n- id: \"martin-j-drst-rubykaigi-2023\"\n  title: \"On Ruby and ꝩduЯ, or How Scary are Trojan Source Attacks\"\n  raw_title: \"[EN] On Ruby and ꝩduЯ, or How Scary are Trojan Source Attacks / Martin J. Dürst @duerst\"\n  speakers:\n    - Martin J. Dürst\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"F3feRCr6S64\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"masatoshi-seki-rubykaigi-2023\"\n  title: \"Learn Ractor\"\n  raw_title: \"[JA] Learn Ractor / Masatoshi SEKI @m_seki\"\n  speakers:\n    - Masatoshi SEKI\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"_pMKdqCxE8w\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"charles-nutter-rubykaigi-2023\"\n  title: \"JRuby: Looking Forward\"\n  raw_title: \"[EN] JRuby: Looking Forward / Charles Nutter @headius\"\n  speakers:\n    - Charles Nutter\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"yxdbbOMWE0g\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"stan-lo-rubykaigi-2023\"\n  title: \"Build a mini Ruby debugger in under 300 lines\"\n  raw_title: \"[EN] Build a mini Ruby debugger in under 300 lines / Stan Lo @_st0012\"\n  speakers:\n    - Stan Lo\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"7uLFVL2KNXo\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"misaki-shioi-rubykaigi-2023\"\n  title: \"Implementing ++ operator, stepping into parse.y\"\n  raw_title: '[JA] Implementing \"++\" operator, stepping into parse.y / Misaki Shioi @coe401_'\n  speakers:\n    - Misaki Shioi\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"x_p5r8p0i1o\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"kevin-newton-rubykaigi-2023\"\n  title: \"Yet Another Ruby Parser\"\n  raw_title: \"[EN] Yet Another Ruby Parser / Kevin Newton @kddnewton\"\n  speakers:\n    - Kevin Newton\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"3vzpv9GZdLo\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"maciej-mensfeld-rubykaigi-2023\"\n  title: \"RubyGems on the watch\"\n  raw_title: \"[EN] RubyGems on the watch / Maciej Mensfeld @maciejmensfeld\"\n  speakers:\n    - Maciej Mensfeld\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-12\"\n  video_provider: \"youtube\"\n  video_id: \"H4qbhzifBz8\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"go-sueyoshi-rubykaigi-2023\"\n  title: \"Fix SQL N+1 queries with RuboCop\"\n  raw_title: \"[JA] Fix SQL N+1 queries with RuboCop / Go Sueyoshi @sue445\"\n  speakers:\n    - Go Sueyoshi\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"mDDAbZsDPMk\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yusuke-endoh-rubykaigi-2023\"\n  title: \"Revisiting TypeProf - IDE support as a primary feature\"\n  raw_title: \"[JA] Revisiting TypeProf - IDE support as a primary feature / Yusuke Endoh @mametter\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"UitqAvgmX0Y\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"benoit-daloze-rubykaigi-2023\"\n  title: \"Splitting: the Crucial Optimization for Ruby Blocks\"\n  raw_title: \"[EN] Splitting: the Crucial Optimization for Ruby Blocks / Benoit Daloze @eregontp\"\n  speakers:\n    - Benoit Daloze\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"KdyV6geWZAk\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"koichi-ito-rubykaigi-2023\"\n  title: \"The Resurrection of the Fast Parallel Test Runner\"\n  raw_title: \"[JA] The Resurrection of the Fast Parallel Test Runner / Koichi ITO @koic\"\n  speakers:\n    - Koichi ITO\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"Bg45cDBcQzo\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"chris-salzberg-rubykaigi-2023\"\n  title: \"Multiverse Ruby\"\n  raw_title: \"[JA] Multiverse Ruby / Chris Salzberg @shioyama\"\n  speakers:\n    - Chris Salzberg\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"xGpz0ZXrhco\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"yusuke-nakamura-rubykaigi-2023\"\n  title: \"Ruby Implementation of QUIC: Progress and Challenges\"\n  raw_title: \"[EN] Ruby Implementation of QUIC: Progress and Challenges / Yusuke Nakamura @yu_suke1994\"\n  speakers:\n    - Yusuke Nakamura\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"jcm8hsRuFYs\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"yuki-torii-rubykaigi-2023\"\n  title: \"Reading and improving Pattern Matching in Ruby\"\n  raw_title: \"[EN] Reading and improving Pattern Matching in Ruby / Yuki Torii @yotii23\"\n  speakers:\n    - Yuki Torii\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"KDvVfbWQyMA\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"alan-wu-rubykaigi-2023\"\n  title: \"Fitting Rust YJIT into CRuby\"\n  raw_title: \"[EN] Fitting Rust YJIT into CRuby / Alan Wu @alanwusx\"\n  speakers:\n    - Alan Wu\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"GI7vvAgP_Qs\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"daisuke-aritomo-rubykaigi-2023\"\n  title: \"Hacking and profiling Ruby for performance\"\n  raw_title: \"[EN] Hacking and profiling Ruby for performance / Daisuke Aritomo @osyoyu\"\n  speakers:\n    - Daisuke Aritomo\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"WPgor5jmcuE\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"naoto-ono-rubykaigi-2023\"\n  title: \"Introduction of new features for VS Code debugging\"\n  raw_title: \"[JA] Introduction of new features for VS Code debugging / Naoto Ono @ono-max\"\n  speakers:\n    - Naoto Ono\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"kuXD9p--Te0\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"jemma-issroff-rubykaigi-2023\"\n  title: \"Tips and Tricks for working in the MRI Codebase\"\n  raw_title: \"[EN] Tips and Tricks for working in the MRI Codebase / Jemma Issroff @jemmaissroff\"\n  speakers:\n    - Jemma Issroff\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"7y6DhXQU4wU\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"jeremy-evans-rubykaigi-2023\"\n  title: \"The Second Oldest Bug\"\n  raw_title: \"[EN] The Second Oldest Bug / Jeremy Evans @jeremyevans0\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"y_1iqQOkv1E\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"takashi-yoneuchi-rubykaigi-2023\"\n  title: \"Eliminating ReDoS with Ruby 3.2\"\n  raw_title: \"[JA] Eliminating ReDoS with Ruby 3.2 / Takashi Yoneuchi @lmt_swallow\"\n  speakers:\n    - Takashi Yoneuchi\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"CEvSx1D3dFQ\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"maxime-chevalier-boisvert-rubykaigi-2023\"\n  title: \"Keynote: Optimizing YJIT’s Performance, from Inception to Production\"\n  raw_title: \"[EN][Keynote] Optimizing YJIT’s Performance, from Inception to Production / @maximecb\"\n  speakers:\n    - Maxime Chevalier-Boisvert\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"X0JRhh8w_4I\"\n  language: \"English\"\n  description: \"\"\n  thumbnail_lg: \"https://img.youtube.com/vi/X0JRhh8w_4I/hqdefault.jpg\"\n  thumbnail_xl: \"https://img.youtube.com/vi/X0JRhh8w_4I/hqdefault.jpg\"\n\n- id: \"soutaro-matsumoto-rubykaigi-2023\"\n  title: \"Keynote: Parsing RBS\"\n  raw_title: \"[EN][Keynote] Parsing RBS / Soutaro Matsumoto @soutaro\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"3qPUy4t7QHE\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"ruby-committers-rubykaigi-2023\"\n  title: \"Ruby Committers and The World\"\n  raw_title: \"[EN] Ruby Committers and The World / CRuby Committers @rubylangorg\"\n  speakers:\n    - Ruby Committers # TODO: list each person\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"APa9R0v9GY0\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"alexandre-terrasa-rubykaigi-2023\"\n  title: \"Gradual typing for Ruby: comparing RBS and RBI/Sorbet\"\n  raw_title: \"[EN] Gradual typing for Ruby: comparing RBS and RBI/Sorbet / Alexandre Terrasa @Morriar\"\n  speakers:\n    - Alexandre Terrasa\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"GOC4BRJ-OPY\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"hirokazu-suzuki-rubykaigi-2023\"\n  title: \"The Adventure of RedAmber - A data frame library in Ruby\"\n  raw_title: \"[JA] The Adventure of RedAmber - A data frame library in Ruby / Hirokazu SUZUKI @heronshoes\"\n  speakers:\n    - Hirokazu SUZUKI\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"MZxDBDRUu6I\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"sutou-kouhei-rubykaigi-2023\"\n  title: \"Ruby + ADBC - A single API between Ruby and DBs\"\n  raw_title: \"[JA] Ruby + ADBC - A single API between Ruby and DBs / Sutou Kouhei @ktou\"\n  speakers:\n    - Sutou Kouhei\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"vwEiRTK32Ik\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"selena-small-rubykaigi-2023\"\n  title: \"Ruby vs Kickboxer - the state of MRuby, JRuby and CRuby\"\n  raw_title: \"[EN] Ruby vs Kickboxer - the state of MRuby, JRuby and CRuby / @saramic @selenasmall88\"\n  speakers:\n    - Selena Small\n    - Michael Milewski\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"tBuceJGDtmE\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"vinicius-stock-rubykaigi-2023\"\n  title: \"Code indexing: How language servers understand our code\"\n  raw_title: \"[EN] Code indexing: How language servers understand our code / Vinicius Stock @vinistock\"\n  speakers:\n    - Vinicius Stock\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"ks3tQojSJLU\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"richard-huang-rubykaigi-2023\"\n  title: \"Find and Replace Code based on AST\"\n  raw_title: \"[EN] Find and Replace Code based on AST / Richard Huang @flyerhzm\"\n  speakers:\n    - Richard Huang\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"zqA0vfKXYsk\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"shigeru-nakajima-rubykaigi-2023\"\n  title: \"Load gem from browser\"\n  raw_title: \"[JA] Load gem from browser / SHIGERU NAKAJIMA @ledsun\"\n  speakers:\n    - Shigeru Nakajima\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"bol8RnNVREg\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"takashi-kokubun-rubykaigi-2023\"\n  title: \"Ruby JIT Hacking Guide\"\n  raw_title: \"[EN] Ruby JIT Hacking Guide / Takashi Kokubun @k0kubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"mlcQ8DErvVs\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"samuel-williams-rubykaigi-2023\"\n  title: \"Unleashing the Power of Asynchronous HTTP with Ruby\"\n  raw_title: \"[EN] Unleashing the Power of Asynchronous HTTP with Ruby / Samuel Williams @ioquatix\"\n  speakers:\n    - Samuel Williams\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"SKNhyqHmqUo\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"kevin-menard-rubykaigi-2023\"\n  title: \"Rethinking Strings\"\n  raw_title: \"[EN] Rethinking Strings / Kevin Menard @nirvdrum\"\n  speakers:\n    - Kevin Menard\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"a1xvhB8jndQ\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"masataka-kuwabara-rubykaigi-2023\"\n  title: \"Let's write RBS!\"\n  raw_title: \"[EN] Let's write RBS! / Masataka Kuwabara @p_ck_\"\n  speakers:\n    - Masataka Kuwabara\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"ngoXe-6BCXU\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"hitoshi-hasumi-rubykaigi-2023\"\n  title: \"Build Your Own SQLite3\"\n  raw_title: \"[JA] Build Your Own SQLite3 / Hitoshi HASUMI @hasumikin\"\n  speakers:\n    - HASUMI Hitoshi\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-06-09\"\n  video_provider: \"youtube\"\n  video_id: \"Nypt-HP4NAI\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"hiroshi-shibata-rubykaigi-2023\"\n  title: \"How resolve Gem dependencies in your code?\"\n  raw_title: \"[JA] How resolve Gem dependencies in your code? / Hiroshi SHIBATA @hsbt\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyKaigi 2023\"\n  date: \"2023-05-11\"\n  published_at: \"2023-11-24\"\n  video_provider: \"youtube\"\n  video_id: \"NydwplWLuH0\"\n  language: \"Japanese\"\n  description: \"\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2024/cfp.yml",
    "content": "---\n- link: \"https://cfp.rubykaigi.org/events/2024\"\n  open_date: \"2023-12-25\"\n  close_date: \"2024-01-31\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2024/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKXsRzSBhaGbd7jF270RnaWI\"\ntitle: \"RubyKaigi 2024\"\nkind: \"conference\"\nlocation: \"Naha, Okinawa, Japan\"\ndescription: |-\n  RubyKaigi 2024, May 15-17, Naha, Okinawa\npublished_at: \"2024-05-15\"\nstart_date: \"2024-05-15\"\nend_date: \"2024-05-17\"\nchannel_id: \"UCnl2p1jpQo4ITeFq4yqmVuA\"\nyear: 2024\nbanner_background: \"#FEEC00\"\nfeatured_background: \"#FEEC00\"\nfeatured_color: \"#000000\"\nwebsite: \"https://rubykaigi.org/2024/\"\ncoordinates:\n  latitude: 26.2163385\n  longitude: 127.6828071\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2024/venue.yml",
    "content": "---\nname: \"Naha Cultural Arts Theater NAHArt\"\n\naddress:\n  street: \"3 Chome-26-27 Kumoji\"\n  city: \"Naha\"\n  region: \"Okinawa\"\n  postal_code: \"900-0015\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"3 Chome-26-27 Kumoji, Naha, Okinawa 900-0015, Japan\"\n\ncoordinates:\n  latitude: 26.2163385\n  longitude: 127.6828071\n\nmaps:\n  google: \"https://www.google.com/maps/place/Naha+Culture+Arts+Theater+NAHArt/@26.2163385,127.6802322,17z\"\n  apple: \"https://maps.apple.com/?q=Naha+Cultural+Arts+Theater+NAHArt\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=26.2172&mlon=127.6850\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2024/videos.yml",
    "content": "---\n# TODO: conference website\n\n# Day 1\n\n- id: \"tomoya-ishida-rubykaigi-2024\"\n  title: \"Keynote: Writing Weird Code\"\n  raw_title: \"[JA][Keynote] Writing Weird Code / Tomoya Ishida @tompng\"\n  speakers:\n    - Tomoya Ishida\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"k6QGq5uGhgU\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://drive.google.com/file/d/1Dkx15u_5UAGoFqJHCeAuj2FXS-z_U7EE/view\"\n\n- id: \"yuichiro-kaneko-rubykaigi-2024\"\n  title: \"The Grand Strategy of Ruby Parser\"\n  raw_title: \"[JA] The grand strategy of Ruby Parser / Yuichiro Kaneko @spikeolaf\"\n  speakers:\n    - Yuichiro Kaneko\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"CjYLcnlXO2Y\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/yui_knk/the-grand-strategy-of-ruby-parser\"\n\n- id: \"masato-ohba-rubykaigi-2024\"\n  title: \"Unlocking Potential of Property Based Testing with Ractor\"\n  raw_title: \"[JA] Unlocking Potential of Property Based Testing with Ractor / Masato Ohba @ohbarye\"\n  speakers:\n    - Masato Ohba\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"UljjMq86OUI\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/ohbarye/unlocking-potential-of-property-based-testing-with-ractor\"\n\n- id: \"samuel-giddins-rubykaigi-2024\"\n  title: \"Remembering (ok, not really Sarah) Marshal\"\n  raw_title: \"[EN] Remembering (ok, not really Sarah) Marshal / Samuel Giddins @segiddins\"\n  speakers:\n    - Samuel Giddins\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"mi6XhlDPmsA\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"matt-valentine-house-rubykaigi-2024\"\n  title: \"Strings! Interpolation, Optimisation & Bugs\"\n  raw_title: \"[EN] Strings! Interpolation, Optimisation & Bugs / Matt Valentine-House @eightbitraptor\"\n  speakers:\n    - Matt Valentine-House\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"CLIqUDqVTC8\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://www.eightbitraptor.com/presentations/RubyKaigi2024-MVH.pdf\"\n\n- id: \"hiroshi-shibata-rubykaigi-2024\"\n  title: \"Long journey of Ruby standard library\"\n  raw_title: \"[JA] Long journey of Ruby standard library / Hiroshi SHIBATA @hsbt\"\n  speakers:\n    - Hiroshi SHIBATA\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"uRYuFyNR9PU\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://www.slideshare.net/slideshow/long-journey-of-ruby-standard-library-at-rubykaigi-2024/268585781\"\n\n- id: \"yuji-yokoo-rubykaigi-2024\"\n  title: \"Cross-platform mruby on Sega Dreamcast and Nintendo Wii\"\n  raw_title: \"[EN] Cross-platform mruby on Sega Dreamcast and Nintendo Wii / Yuji Yokoo @yujiyokoo\"\n  speakers:\n    - Yuji Yokoo\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"n4cIKfXytEI\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://github.com/yujiyokoo/dreampresent-wii/releases/tag/RubyKaigi-2024\"\n\n- id: \"satoshi-moris-tagomori-rubykaigi-2024\"\n  title: \"Namespace, What and Why\"\n  raw_title: \"[JA] Namespace, What and Why / Satoshi Tagomori @tagomoris\"\n  speakers:\n    - Satoshi \"moris\" Tagomori\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"M4MDbxuFZyc\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/tagomoris/namespace-what-and-why\"\n\n- id: \"shunsuke-mori-rubykaigi-2024\"\n  title: \"Let's use LLMs from Ruby 〜 Refine RBS types using LLM 〜\"\n  raw_title: \"[JA] Let's use LLMs from Ruby 〜 Refine RBS types using LLM 〜 / Shunsuke Mori (kokuyou) @kokuyouwind\"\n  speakers:\n    - Shunsuke Mori\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"M2zvcq5VBwo\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://slides.com/kokuyouwind/lets-use-llms-from-ruby\"\n\n- id: \"daisuke-aritomo-rubykaigi-2024\"\n  title: \"The Depths of Profiling Ruby\"\n  raw_title: \"[EN] The depths of profiling Ruby / Daisuke Aritomo @osyoyu\"\n  speakers:\n    - Daisuke Aritomo\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"NkNlg8YdZHU\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/osyoyu/the-depthes-of-profiling-ruby-rubykaigi-2024\"\n\n- id: \"john-hawthorn-rubykaigi-2024\"\n  title: \"Vernier: A next generation profiler for CRuby\"\n  raw_title: \"[EN] Vernier: A next generation profiler for CRuby / John Hawthorn @jhawthorn\"\n  speakers:\n    - John Hawthorn\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"QSjN-H4hGsM\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/jhawthorn/vernier-a-next-generation-cruby-profiler-rubykaigi-2024\"\n\n- id: \"mari-imaizumi-rubykaigi-2024\"\n  title: \"Exploring Reline: Enhancing Command Line Usability\"\n  raw_title: \"[JA] Exploring Reline: Enhancing Command Line Usability / Mari Imaizumi @ima1zumi\"\n  speakers:\n    - Mari Imaizumi\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"U0lo4mYHttc\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/ima1zumi/exploring-reline-enhancing-command-line-usability\"\n\n- id: \"matt-muller-rubykaigi-2024\"\n  title: \"Generating a custom SDK for your web service or Rails API\"\n  raw_title: \"[EN] Generating a custom SDK for your web service or Rails API / Matt Muller @mullermp\"\n  speakers:\n    - Matt Muller\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"wTOrDRrahuM\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://www.slideshare.net/slideshow/generating-a-custom-ruby-sdk-for-your-web-service-or-rails-api-using-smithy/269389846\"\n\n- id: \"koichi-sasada-rubykaigi-2024\"\n  title: \"Ractor Enhancements, 2024\"\n  raw_title: \"[EN] Ractor Enhancements, 2024 / Koichi Sasada @ko1\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"hzuNr0VnuKM\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://www.atdot.net/~ko1/activities/2024_rubykaigi.pdf\"\n\n- id: \"misaki-shioi-rubykaigi-2024\"\n  title: \"An Adventure of Happy Eyeballs\"\n  raw_title: \"[JA] An adventure of Happy Eyeballs / Misaki Shioi @coe401_\"\n  speakers:\n    - Misaki Shioi\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"HU-kfUxM2lc\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/coe401_/an-adventure-of-happy-eyeballs\"\n\n- id: \"brandon-weaver-rubykaigi-2024\"\n  title: \"Refactoring with ASTs and Pattern Matching\"\n  raw_title: \"[EN] Refactoring with ASTs and Pattern Matching / Brandon Weaver @keystonelemur\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-15\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"rq2cJfM49N4\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://drive.google.com/file/d/1EKknpjvafzM0uQKtgEVxywlP3WdcLS8g/view?usp=sharing\"\n\n# Day 2\n\n- id: \"samuel-williams-rubykaigi-2024\"\n  title: \"Keynote: Leveraging Falcon and Rails for Real-Time Interactivity\"\n  raw_title: \"[EN][Keynote] Leveraging Falcon and Rails for Real-Time Interactivity / Samuel Williams @ioquatix\"\n  speakers:\n    - Samuel Williams\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"YacN_phi_ME\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"peter-zhu-rubykaigi-2024\"\n  title: \"Finding Memory Leaks in the Ruby Ecosystem\"\n  raw_title: \"[EN] Finding Memory Leaks in the Ruby Ecosystem / Peter Zhu Adam Hess @peterzhu2118 @HParker\"\n  speakers:\n    - Peter Zhu\n    - Adam Hess\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"pQ1XCrwq1qc\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://blog.peterzhu.ca/assets/rubykaigi_2024_slides.pdf\"\n\n- id: \"yudai-takada-rubykaigi-2024\"\n  title: \"Does Ruby Parser Dream of Highly Expressive Grammar?\"\n  raw_title: \"[JA] Does Ruby Parser dream of highly expressive grammar? / Yudai Takada @ydah_\"\n  speakers:\n    - Yudai Takada\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"Zs_Or0xUD1Q\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/ydah/does-ruby-parser-dream-of-highly-expressive-grammar\"\n\n- id: \"masataka-kuwabara-rubykaigi-2024\"\n  title: \"Community-driven RBS Repository\"\n  raw_title: \"[EN] Community-driven RBS repository / Masataka Kuwabara @p_ck_\"\n  speakers:\n    - Masataka Kuwabara\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"r31gVDlIJhc\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/pocke/community-driven-rbs-repository\"\n\n- id: \"soutaro-matsumoto-rubykaigi-2024\"\n  title: \"Embedding it into Ruby Code\"\n  raw_title: \"[EN] Embedding it into Ruby code / Soutaro Matsumoto @soutaro\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"vfnspVtoN3U\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/soutaro/embedding-it-into-ruby-code\"\n\n- id: \"yuta-saito-rubykaigi-2024\"\n  title: \"RubyGems on ruby.wasm\"\n  raw_title: \"[EN] RubyGems on ruby.wasm / Yuta Saito @kateinoigakukun\"\n  speakers:\n    - Yuta Saito\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"_4d20A6xIsM\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/kateinoigakukun/rubygems-on-ruby-dot-wasm\"\n\n- id: \"ivo-anjo-rubykaigi-2024\"\n  title: \"Optimizing Ruby: Building an Always-On Production Profiler\"\n  raw_title: \"[EN] Optimizing Ruby: Building an Always-On Production Profiler / Ivo Anjo @KnuX\"\n  speakers:\n    - Ivo Anjo\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"7wWlbvUctoE\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://dtdg.co/rubykaigi2024\"\n\n- id: \"jeremy-evans-rubykaigi-2024\"\n  title: \"Reducing Implicit Allocations During Method Calling\"\n  raw_title: \"[EN] Reducing Implicit Allocations During Method Calling / Jeremy Evans @jeremyevans0\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"K7WK9NvNRzg\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://code.jeremyevans.net/presentations/rubykaigi2024/index.html\"\n\n- id: \"hitoshi-hasumi-rubykaigi-2024\"\n  title: \"Unlock The Universal Parsers: A New PicoRuby Compiler\"\n  raw_title: \"[JA] Unlock The Universal Parsers: A New PicoRuby Compiler / Hitoshi HASUMI @hasumikin\"\n  speakers:\n    - HASUMI Hitoshi\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"z7VcMewHXJg\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://slide.rabbit-shocker.org/authors/hasumikin/RubyKaigi2024/\"\n\n- id: \"masaki-hara-rubykaigi-2024\"\n  title: \"Getting Along with YAML Comments with Psych\"\n  raw_title: \"[EN] Getting along with YAML comments with Psych / Masaki Hara @qnighy\"\n  speakers:\n    - Masaki Hara\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"SFpqBT8kTbk\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/qnighy/getting-along-with-yaml-comments-with-psych\"\n\n- id: \"maxime-chevalier-boisvert-rubykaigi-2024\"\n  title: \"Breaking the Ruby Performance Barrier\"\n  raw_title: \"[EN] Breaking the Ruby Performance Barrier / Maxime Chevalier-Boisvert @maximecb\"\n  speakers:\n    - Maxime Chevalier-Boisvert\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"qf5V02QNMnA\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://www.slideshare.net/slideshow/breaking-the-ruby-performance-barrier-with-yjit/269367259\"\n\n- id: \"koichi-ito-rubykaigi-2024\"\n  title: \"RuboCop: LSP and Prism\"\n  raw_title: \"[JA] RuboCop: LSP and Prism / Koichi ITO @koic\"\n  speakers:\n    - Koichi ITO\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"HK_LfWd9NRY\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/koic/rubocop-lsp-and-prism\"\n\n- id: \"uchio-kondo-rubykaigi-2024\"\n  title: \"An mruby for WebAssembly\"\n  raw_title: \"[EN] An mruby for WebAssembly / Uchio KONDO @udzura\"\n  speakers:\n    - Uchio KONDO\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"FyomdDn9eGo\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://udzura.jp/slides/2024/rubykaigi/\"\n\n- id: \"yusuke-endoh-rubykaigi-2024\"\n  title: \"Good First Issues of TypeProf\"\n  raw_title: \"[JA] Good first issues of TypeProf / Yusuke Endoh @mametter\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"PMNwv1fzujU\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/mame/good-first-issues-of-typeprof\"\n\n- id: \"ahogappa-rubykaigi-2024\"\n  title: \"It's About Time To Pack Ruby and Ruby Scripts In One Binary\"\n  raw_title: \"[JA] It's about time to pack Ruby and Ruby scripts in one binary / ahogappa @ahogappa0613\"\n  speakers:\n    - ahogappa\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"DMNDw4fYu60\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/ahogappa0613/its-about-time-to-pack-ruby-and-ruby-scripts-in-one-binary\"\n\n- id: \"benoit-daloze-rubykaigi-2024\"\n  title: \"From Interpreting C Extensions to Compiling Them\"\n  raw_title: \"[EN] From Interpreting C Extensions to Compiling Them / Benoit Daloze @eregontp\"\n  speakers:\n    - Benoit Daloze\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"DkSvI43k1Ag\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://eregon.me/blog/assets/research/from-interpreting-c-extensions-to-compiling-them.pdf\"\n\n- id: \"martin-j-drst-rubykaigi-2024\"\n  title: \"Squeezing Unicode Names into Ruby Regular Expressions\"\n  raw_title: \"[EN] Squeezing Unicode Names into Ruby Regular Expressions / Martin J. Dürst @duerst\"\n  speakers:\n    - Martin J. Dürst\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"gKOGPVLgSak\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"monochrome-rubykaigi-2024\"\n  title: \"Running Optcarrot (faster) on my own Ruby.\"\n  raw_title: \"[JA] Running Optcarrot (faster) on my own Ruby. / monochrome @s_isshiki1969\"\n  speakers:\n    - monochrome\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"OfeUyQDFy_Y\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/sisshiki1969/running-optcarrot-faster-on-my-own-ruby\"\n\n- id: \"ryo-kajiwara-rubykaigi-2024\"\n  title: \"Adding Security to Microcontroller Ruby\"\n  raw_title: \"[EN] Adding Security to Microcontroller Ruby / Ryo Kajiwara @sylph01\"\n  speakers:\n    - Ryo Kajiwara\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"V8tf34Iw2YY\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/sylph01/adding-security-to-microcontroller-ruby\"\n\n- id: \"akira-matsuda-rubykaigi-2024\"\n  title: \"Lightning Talks\"\n  raw_title: \"[EN][JA] Lightning Talks\"\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-16\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"w1AodsHYT_o\"\n  language: \"Japanese\"\n  description: \"\"\n  speakers:\n    - Akira Matsuda\n  talks:\n    - title: \"Lightning Talk: Visualize the internal state of ruby processes in Real-Time\"\n      start_cue: \"00:51\"\n      end_cue: \"06:05\"\n      id: \"sunao-hogelog-komuro-lighting-talk-rubykaigi-2024\"\n      video_id: \"sunao-hogelog-komuro-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Sunao Hogelog Komuro\n\n    - title: \"Lightning Talk: The Frontend Rubyist\"\n      start_cue: \"06:05\"\n      end_cue: \"11:10\"\n      id: \"andi-idogawa-lighting-talk-rubykaigi-2024\"\n      video_id: \"andi-idogawa-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"English\"\n      speakers:\n        - Andi Idogawa\n\n    - title: \"Lightning Talk: Enjoy Creative Coding with Ruby\"\n      start_cue: \"11:10\"\n      end_cue: \"16:28\"\n      id: \"miyuki-koshiba-lighting-talk-rubykaigi-2024\"\n      video_id: \"miyuki-koshiba-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Miyuki Koshiba\n\n    - title: \"Lightning Talk: Rearchitect Ripper\"\n      start_cue: \"16:28\"\n      end_cue: \"21:37\"\n      id: \"yuichiro-kaneko-lighting-talk-rubykaigi-2024\"\n      video_id: \"yuichiro-kaneko-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Yuichiro Kaneko\n\n    - title: \"Lightning Talk: The Journey of rubocop-daemon into RuboCop\"\n      start_cue: \"21:37\"\n      end_cue: \"26:33\"\n      id: \"hayato-kawai-lighting-talk-rubykaigi-2024\"\n      video_id: \"hayato-kawai-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Hayato Kawai\n\n    - title: \"Lightning Talk: The test code generator using static analysis and LLM\"\n      start_cue: \"26:33\"\n      end_cue: \"31:40\"\n      id: \"hashino-mikiko-lighting-talk-rubykaigi-2024\"\n      video_id: \"hashino-mikiko-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Hashino Mikiko\n\n    - title: \"Lightning Talk: Contributing to the Ruby Parser\"\n      start_cue: \"31:40\"\n      end_cue: \"36:48\"\n      id: \"s-h-gamelinks-lighting-talk-rubykaigi-2024\"\n      video_id: \"s-h-gamelinks-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - S-H-GAMELINKS\n\n    - title: \"Lightning Talk: Improved REXML XML parsing performance using StringScanner\"\n      start_cue: \"36:48\"\n      end_cue: \"41:40\"\n      id: \"naitoh-jun-lighting-talk-rubykaigi-2024\"\n      video_id: \"naitoh-jun-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - NAITOH Jun\n\n    - title: \"Lightning Talk: Hotspot on Coverage\"\n      start_cue: \"41:40\"\n      end_cue: \"46:50\"\n      id: \"sangyong-sim-lighting-talk-rubykaigi-2024\"\n      video_id: \"sangyong-sim-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Sangyong Sim\n\n    - title: \"Lightning Talk: Drive Your Code: Building an RC Car by Writing Only Ruby\"\n      start_cue: \"46:50\"\n      end_cue: \"51:50\"\n      id: \"hayao-kimura-lighting-talk-rubykaigi-2024\"\n      video_id: \"hayao-kimura-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"Japanese\"\n      speakers:\n        - Hayao Kimura\n\n    - title: \"Lightning Talk: An anthropological view of the Ruby community\"\n      start_cue: \"51:50\"\n      end_cue: \"56:36\"\n      id: \"gui-heurich-lighting-talk-rubykaigi-2024\"\n      video_id: \"gui-heurich-lighting-talk-rubykaigi-2024\"\n      video_provider: \"parent\"\n      language: \"English\"\n      speakers:\n        - Guilherme Orlandini Heurich\n\n# Day 3\n\n- id: \"ruby-committers-rubykaigi-2024\"\n  title: \"Ruby Committers and the World\"\n  raw_title: \"[JA][EN] Ruby Committers and the World / CRuby Committers @rubylangorg\"\n  speakers:\n    - Ruby Committers\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"26sbpaGbU-0\"\n  language: \"Japanese\"\n  description: \"\"\n\n- id: \"takashi-kokubun-rubykaigi-2024\"\n  title: \"YJIT Makes Rails 1.7x Faster\"\n  raw_title: \"[EN] YJIT Makes Rails 1.7x Faster / Takashi Kokubun @k0kubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"osK8F__0FVI\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/k0kubun/rubykaigi-2024\"\n\n- id: \"kei-inoue-rubykaigi-2024\"\n  title: \"How to implement a RubyVM with PHP?\"\n  raw_title: \"[JA] How to implement a RubyVM with PHP? / memory @m3m0r7\"\n  speakers:\n    - Kei Inoue\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"6SLUW2PEoZY\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/memory1994/how-to-implement-a-rubyvm-with-php-rubykaigi2024\"\n\n- id: \"kay-sawada-rubykaigi-2024\"\n  title: \"Turning CDN edge into a Rack web server with ruby.wasm\"\n  raw_title: \"[EN] Turning CDN edge into a Rack web server with ruby.wasm / Kay Sawada @remore\"\n  speakers:\n    - Kay Sawada\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"LciYstdyuhc\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/remore/turning-cdn-edge-into-a-rack-web-server-with-ruby-dot-wasm\"\n\n- id: \"aaron-patterson-rubykaigi-2024\"\n  title: \"Speeding up Instance Variables with Red-Black Trees\"\n  raw_title: \"[JA] Speeding up Instance Variables with Red-Black Trees / Aaron Patterson @tenderlove\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"dDvyYVjS5b0\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/tenderlove/speeding-up-instance-variables-in-ruby-3-dot-3\"\n\n- id: \"mike-mcquaid-rubykaigi-2024\"\n  title: 'Using \"modern\" Ruby to Build a Better, Faster Homebrew'\n  raw_title: '[EN] Using \"modern\" Ruby to build a better, faster Homebrew / Mike McQuaid @MikeMcQuaid'\n  speakers:\n    - Mike McQuaid\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"QDnaY0quYp0\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/mikemcquaid/using-modern-ruby-to-build-a-better-faster-homebrew\"\n\n- id: \"charles-nutter-rubykaigi-2024\"\n  title: \"JRuby 10: Ruby 3.3 on the Modern JVM\"\n  raw_title: \"[EN] JRuby 10: Ruby 3.3 on the Modern JVM / Charles Nutter @headius\"\n  speakers:\n    - Charles Nutter\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"NXFRKetpF68\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/headius/jruby-10-ruby-3-dot-3-on-the-modern-jvm\"\n\n- id: \"masatoshi-seki-rubykaigi-2024\"\n  title: \"ERB, Ancient and Future\"\n  raw_title: \"[JA] ERB, ancient and future / Masatoshi SEKI @m_seki\"\n  speakers:\n    - Masatoshi SEKI\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"4NYBtwLqits\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/m_seki/erb-ancient-and-future\"\n\n- id: \"junichi-kobayashi-rubykaigi-2024\"\n  title: \"From LALR to IELR: A Lrama's Next Step\"\n  raw_title: \"[JA] From LALR to IELR: A Lrama's Next Step / Junichi Kobayashi @junk0612\"\n  speakers:\n    - Junichi Kobayashi\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"8c7w7ecwGDc\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/junk0612/from-lalr-to-ielr-a-lramas-next-step\"\n\n- id: \"emma-haruka-iwao-rubykaigi-2024\"\n  title: \"Ruby and the World Record Pi Calculation\"\n  raw_title: \"[EN] Ruby and the World Record Pi Calculation / Emma Haruka Iwao @Yuryu\"\n  speakers:\n    - Emma Haruka Iwao\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"LvaX-3vvNMA\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/yuryu/ruby-and-the-world-record-pi-calculation\"\n\n- id: \"kj-tsanaktsidis-rubykaigi-2024\"\n  title: \"Finding and fixing memory safety bugs in C with ASAN\"\n  raw_title: \"[EN] Finding and fixing memory safety bugs in C with ASAN / KJ Tsanaktsidis @KJTsanaktsidis\"\n  speakers:\n    - KJ Tsanaktsidis\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"yM1us32z-9I\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://docs.google.com/presentation/d/1pxadIOluKjlpuscaq4B3RBnD0mwy02v6Fp-2bt29QRU/edit#slide=id.g2d0dab1d345_0_3\"\n\n- id: \"ryota-egusa-rubykaigi-2024\"\n  title: \"Porting mruby/c for the SNES (Super Famicom)\"\n  raw_title: \"[JA] Porting mruby/c for the SNES (Super Famicom) / Ryota Egusa @gedorinku\"\n  speakers:\n    - Ryota Egusa\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"iiauZuJnqlA\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/gedorinku/c-for-the-snes-super-famicom-rubykaigi-2024\"\n\n- id: \"vladimir-dementyev-rubykaigi-2024\"\n  title: \"Ruby Mixology 101: adding shots of PHP, Elixir, and more\"\n  raw_title: \"[EN] Ruby Mixology 101: adding shots of PHP, Elixir, and more / Vladimir Dementyev @palkan_tula.\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"tfzAZiGGHvM\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/palkan/rubykaigi-2024-ruby-mixology-101-adding-shots-of-php-elixir-and-more\"\n\n- id: \"hiroya-fujinami-rubykaigi-2024\"\n  title: \"Make Your Own Regex Engine!\"\n  raw_title: \"[JA] Make Your Own Regex Engine! / Hiroya FUJINAMI @makenowjust\"\n  speakers:\n    - Hiroya Fujinami\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"kaN1NqhL7VI\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/makenowjust/rubykaigi-2024-make-your-own-regex-engine\"\n\n- id: \"shigeru-nakajima-rubykaigi-2024\"\n  title: \"Using Ruby in The Browser is Wonderful.\"\n  raw_title: \"[JA] Using Ruby in the browser is wonderful. / Shigeru Nakajima @ledsun\"\n  speakers:\n    - Shigeru Nakajima\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"PDTz9QOHBFo\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/ledsun/using-ruby-in-the-browser-is-wonderful\"\n\n- id: \"vinicius-stock-rubykaigi-2024\"\n  title: \"The State of Ruby Dev Tooling\"\n  raw_title: \"[EN] The state of Ruby dev tooling / Vinicius Stock @vinistock\"\n  speakers:\n    - Vinicius Stock\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"qhp04EwmIjo\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/vinistock/the-state-of-ruby-tooling\"\n\n- id: \"yukihiro-matz-matsumoto-rubykaigi-2024\"\n  title: \"Keynote: Better Ruby\"\n  raw_title: '[JA][Keynote] Matz Keynote / Yukihiro \"Matz\" Matsumoto @yukihiro_matz'\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2024\"\n  date: \"2024-05-17\"\n  published_at: \"2024-08-23\"\n  video_provider: \"youtube\"\n  video_id: \"ixVjrn-b1K0\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"https://rubykaigi.org/2024/data/BetterRuby.pdf\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2025/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://cfp.rubykaigi.org/events/2025\"\n  open_date: \"2024-12-14\"\n  close_date: \"2025-01-19\"\n\n- name: \"Lightning Talks CFP\"\n  link: \"https://cfp.rubykaigi.org/events/2025LT\"\n  open_date: \"2025-03-07\"\n  close_date: \"2025-03-30\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2025/event.yml",
    "content": "---\nid: \"rubykaigi-2025\"\ntitle: \"RubyKaigi 2025\"\nkind: \"conference\"\nlocation: \"Matsuyama, Ehime, Japan\"\ndescription: |-\n  RubyKaigi 2025, April 16-18, Matsuyama, Ehime\npublished_at: \"2025-05-27\"\nstart_date: \"2025-04-16\"\nend_date: \"2025-04-18\"\nchannel_id: \"UCnl2p1jpQo4ITeFq4yqmVuA\"\nyear: 2025\nbanner_background: \"#EB4102\"\nfeatured_background: \"#EB4102\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://rubykaigi.org/2025/\"\ncoordinates:\n  latitude: 33.852\n  longitude: 132.787\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2025/schedule.yml",
    "content": "---\n# https://rubykaigi.org/2025/schedule/\ndays:\n  - name: \"Day 1\"\n    date: \"2025-04-16\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Door Open\n\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:10\"\n        end_time: \"11:40\"\n        slots: 3\n\n      - start_time: \"11:50\"\n        end_time: \"12:20\"\n        slots: 3\n\n      - start_time: \"12:20\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 3\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 3\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 1\n        items:\n          - Afternoon Break\n\n      - start_time: \"15:40\"\n        end_time: \"16:10\"\n        slots: 3\n\n      - start_time: \"16:20\"\n        end_time: \"16:50\"\n        slots: 3\n\n      - start_time: \"17:00\"\n        end_time: \"18:00\"\n        slots: 1\n\n  - name: \"Day 2\"\n    date: \"2025-04-17\"\n    grid:\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:10\"\n        end_time: \"11:40\"\n        slots: 3\n\n      - start_time: \"11:50\"\n        end_time: \"12:20\"\n        slots: 3\n\n      - start_time: \"12:20\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 3\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 3\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 1\n        items:\n          - Afternoon Break\n\n      - start_time: \"15:40\"\n        end_time: \"16:10\"\n        slots: 3\n\n      - start_time: \"16:20\"\n        end_time: \"16:50\"\n        slots: 3\n\n      - start_time: \"17:00\"\n        end_time: \"18:00\"\n        slots: 1\n\n  - name: \"Day 3\"\n    date: \"2025-04-18\"\n    grid:\n      - start_time: \"09:50\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:10\"\n        end_time: \"11:40\"\n        slots: 3\n\n      - start_time: \"11:50\"\n        end_time: \"12:20\"\n        slots: 3\n\n      - start_time: \"12:20\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 3\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 3\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 1\n        items:\n          - Afternoon Break\n\n      - start_time: \"15:40\"\n        end_time: \"16:10\"\n        slots: 3\n\n      - start_time: \"16:20\"\n        end_time: \"17:20\"\n        slots: 1\n\ntracks:\n  - name: \"Main Hall #rubykaigiA\"\n    color: \"#FF5719\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Sub Hall #rubykaigiB\"\n    color: \"#000000\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Pearls Room #rubykaigiC\"\n    color: \"#FFF5EC\"\n    text_color: \"#000000\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsors\"\n      description: |-\n        Sponsors under the Ruby Sponsors tier\n      level: 1\n      sponsors:\n        - name: \"TwoGate Inc.\"\n          website: \"https://twogate.com\"\n          slug: \"TwoGateInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/796-1f684a11.png\"\n\n        - name: \"ITANDI, Inc.\"\n          website: \"https://www.itandi.co.jp/\"\n          slug: \"ITANDIInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/834-8efcb790.png\"\n\n        - name: \"DIGGLE Inc.\"\n          website: \"https://diggle.jp/\"\n          slug: \"DIGGLEInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/837-1f4e21ee.png\"\n\n        - name: \"codeTakt Inc.\"\n          website: \"https://codetakt.com/\"\n          slug: \"codeTaktInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/840-6787a733.png\"\n\n        - name: \"dely inc.\"\n          website: \"https://dely.jp/\"\n          slug: \"delyinc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/846-404c0139.png\"\n\n        - name: \"TenshokuDRAFT\"\n          website: \"https://job-draft.jp\"\n          slug: \"TenshokuDRAFT\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/858-c0b6bb9c.png\"\n\n        - name: \"Shopify\"\n          website: \"https://shopify.com\"\n          slug: \"Shopify\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/793-ef8d3949.png\"\n          badge: \"Ruby Committers' Sponsor\"\n\n        - name: \"mov inc.\"\n          website: \"https://mov.am/\"\n          slug: \"movinc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/823-2c68b001.png\"\n          badge: \"Drinkup Sponsor\"\n\n        - name: \"hacomono Inc.\"\n          website: \"https://www.hacomono.co.jp/recruit/engineer/\"\n          slug: \"hacomonoInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/838-ca1565c4.png\"\n          badge: \"Wellness and Drinkup Sponsor\"\n\n        - name: \"IVRy Inc.\"\n          website: \"https://ivry.jp/\"\n          slug: \"IVRyInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/851-870a5289.png\"\n          badge: \"Climbing Sponsor\"\n\n    - name: \"Platinum Sponsors\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"SmartBank, Inc.\"\n          website: \"https://smartbank.co.jp/\"\n          slug: \"SmartBankInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/787-a4eda431.png\"\n          badge: \"Hack Space Sponsor\"\n\n        - name: \"ANDPAD Inc.\"\n          website: \"https://engineer.andpad.co.jp/\"\n          slug: \"andpad\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/789-3adf94c9.png\"\n          badge: \"Drinks Sponsor\"\n\n        - name: \"STORES, Inc.\"\n          website: \"https://jobs.st.inc/\"\n          slug: \"stores\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/790-761291a9.png\"\n          badge: \"Nursery Sponsor\"\n\n        - name: \"SmartHR, Inc.\"\n          website: \"https://smarthr.co.jp/\"\n          slug: \"SmartHRInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/794-23a76df6.png\"\n          badge: \"Scheduler and Drinkup Sponsor\"\n\n        - name: \"pixiv Inc\"\n          website: \"https://www.pixiv.co.jp/\"\n          slug: \"pixivInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/802-86207023.png\"\n          badge: \"Music Event and Scholarship Sponsor\"\n\n        - name: \"note inc.\"\n          website: \"https://note.jp/\"\n          slug: \"noteinc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/813-2fbe450b.png\"\n          badge: \"Design Sponsor\"\n\n        - name: \"GMO INTERNET GROUP\"\n          website: \"https://www.gmo.jp/\"\n          slug: \"GMOINTERNETGROUP\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/821-0feb6fa3.png\"\n          badge: \"Ferry Sponsor\"\n\n        - name: \"ESM, Inc.\"\n          website: \"https://agile.esm.co.jp/\"\n          slug: \"ESMInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/767-3578e060.png\"\n          badge: \"Drinkup Sponsor\"\n\n        - name: \"Leaner Technologies Inc.\"\n          website: \"https://leaner.co.jp/\"\n          slug: \"LeanerTechnologiesInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/775-8f4f1c68.png\"\n          badge: \"Drinkup Sponsor\"\n\n        - name: \"Agileware Inc.\"\n          website: \"https://agileware.jp/\"\n          slug: \"AgilewareInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/780-a0922aac.png\"\n          badge: \"Drinkup Sponsor\"\n\n        - name: \"Qiita Inc.\"\n          website: \"https://qiita.com/\"\n          slug: \"QiitaInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/841-b95da5da.png\"\n          badge: \"Drinkup Sponsor\"\n\n        - name: \"mybest, Inc.\"\n          website: \"https://my-best.com/company\"\n          slug: \"mybestInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/770-d5f2d001.png\"\n\n        - name: \"ZOZO, Inc.\"\n          website: \"https://corp.zozo.com/\"\n          slug: \"ZOZOInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/771-d43dd7ed.png\"\n\n        - name: \"Vonage\"\n          website: \"https://vonage.dev/rubykaigi\"\n          slug: \"Vonage\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/776-0844a951.png\"\n\n        - name: \"Findy Inc.\"\n          website: \"https://findy.co.jp/\"\n          slug: \"FindyInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/777-c983f1cb.png\"\n\n        - name: \"Money Forward, Inc.\"\n          website: \"https://corp.moneyforward.com/en/\"\n          slug: \"MoneyForwardInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/779-afbe2ef3.png\"\n\n        - name: \"Net Protections, Inc.\"\n          website: \"https://corp.netprotections.com/\"\n          slug: \"NetProtectionsInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/782-893f8377.png\"\n\n        - name: \"Timee, Inc.\"\n          website: \"https://corp.timee.co.jp/\"\n          slug: \"TimeeInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/788-981908f4.png\"\n\n        - name: \"primeNumber Inc.\"\n          website: \"https://primenumber.com/\"\n          slug: \"primeNumberInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/791-e4f6df9a.png\"\n\n        - name: \"Linc'well Inc.\"\n          website: \"https://linc-well.com\"\n          slug: \"LincwellInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/795-ead423ed.png\"\n\n        - name: \"Unifa Inc.\"\n          website: \"https://unifa-e.com/\"\n          slug: \"UnifaInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/799-52665dfe.png\"\n\n        - name: \"OPTiM Corporation\"\n          website: \"https://www.optim.co.jp/\"\n          slug: \"OPTiMCorporation\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/801-e3ac625c.png\"\n\n        - name: \"stmn, inc.\"\n          website: \"https://stmn.co.jp/\"\n          slug: \"stmninc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/806-c4fb26e3.png\"\n\n        - name: \"MIXI, Inc.\"\n          website: \"https://mixi.co.jp/\"\n          slug: \"MIXIInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/807-e390651b.png\"\n\n        - name: \"JetBrains\"\n          website: \"https://www.jetbrains.com/ruby/\"\n          slug: \"JetBrains\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/808-42097c3b.png\"\n\n        - name: \"GMO Flatt Security Inc.\"\n          website: \"https://flatt.tech/en\"\n          slug: \"GMOFlattSecurityInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/811-153a7353.png\"\n\n        - name: \"Tabelog\"\n          website: \"https://tabelog.com/\"\n          slug: \"Tabelog\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/812-a6e7afa9.png\"\n\n        - name: \"Ruby Development Inc.\"\n          website: \"https://www.ruby-dev.jp/\"\n          slug: \"rubydevelopment\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/814-908be200.png\"\n\n        - name: \"WED, Inc.\"\n          website: \"https://wed.company/\"\n          slug: \"WEDInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/825-139839c6.png\"\n\n        - name: \"KOMOJU by Degica\"\n          website: \"https://komoju.com/\"\n          slug: \"KOMOJUbyDegica\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/826-9c55c79b.png\"\n\n        - name: \"with.inc\"\n          website: \"https://enito.co.jp/who-we-are/\"\n          slug: \"withinc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/828-6775e496.png\"\n\n        - name: \"Cookpad\"\n          website: \"https://cookpad.careers/\"\n          slug: \"cookpad\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/833-9a5ae15b.png\"\n\n        - name: \"TOKIUM Inc.\"\n          website: \"https://corp.tokium.jp/\"\n          slug: \"TOKIUMInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/836-d859f080.png\"\n\n        - name: \"Sentry\"\n          website: \"https://sentry.ichizoku.io/\"\n          slug: \"Sentry\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/839-1836ff6c.png\"\n\n        - name: \"FASTLY K.K.\"\n          website: \"https://www.fastly.com/jp\"\n          slug: \"FASTLYKK\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/843-2f796a72.png\"\n\n        - name: \"PKSHA Technology Inc.\"\n          website: \"https://www.pkshatech.com/recruitment/\"\n          slug: \"PKSHATechnologyInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/844-c8deb48d.png\"\n\n        - name: \"RECEPTIONIST\"\n          website: \"https://receptionist.co.jp/\"\n          slug: \"RECEPTIONIST\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/847-18b18b54.png\"\n\n        - name: \"Medley, Inc.\"\n          website: \"https://www.medley.jp/\"\n          slug: \"MedleyInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/848-b67d1977.png\"\n\n        - name: \"Offers\"\n          website: \"https://offers.jp/\"\n          slug: \"Offers\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/849-31549593.png\"\n\n        - name: \"DeNA Co., Ltd.\"\n          website: \"https://dena.com\"\n          slug: \"DeNACoLtd\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/850-7d776fd0.png\"\n\n        - name: \"SMS Co., Ltd.\"\n          website: \"https://careers.bm-sms.co.jp/engineer\"\n          slug: \"SMSCoLtd\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/855-ead7e6ee.png\"\n\n        - name: \"Hubble Inc.\"\n          website: \"https://hubble-docs.com/about\"\n          slug: \"HubbleInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/856-fbeeffd0.png\"\n\n        - name: \"mruby/c\"\n          website: \"https://www.s-itoc.jp/mrubyc\"\n          slug: \"mrubyc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/859-9fc6d8b4.png\"\n\n    - name: \"Gold Sponsors\"\n      description: |-\n        Gold tier sponsors supporting RubyKaigi 2025\n      level: 3\n      sponsors:\n        - name: \"giftee Inc.\"\n          website: \"https://en.giftee.co.jp/\"\n          slug: \"gifteeInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/785-096d2a19.png\"\n          badge: \"Drinkup Sponsor\"\n\n        - name: \"freee K.K.\"\n          website: \"https://www.freee.co.jp/\"\n          slug: \"freeeKK\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/854-65d80cc7.png\"\n          badge: \"Drinkup Sponsor\"\n\n        - name: \"Treasure Data\"\n          website: \"https://www.treasuredata.com\"\n          slug: \"TreasureData\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/871-2a1e5cd0.png\"\n          badge: \"Drinkup Sponsor\"\n\n        - name: \"GMO Pepabo, Inc.\"\n          website: \"https://pepabo.com/\"\n          slug: \"GMOPepaboInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/878-e43e811e.png\"\n          badge: \"Video Sponsor\"\n\n        - name: \"Studist Corporation\"\n          website: \"https://studist.jp/\"\n          slug: \"StudistCorporation\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/769-9538d434.png\"\n\n        - name: \"Network Applied Communication Laboratory Ltd.\"\n          website: \"https://www.netlab.jp/\"\n          slug: \"NetworkAppliedCommunicationLaboratoryLtd\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/772-cc737f16.png\"\n\n        - name: \"RAKSUL Inc.\"\n          website: \"https://corp.raksul.com/\"\n          slug: \"RAKSULInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/774-5a1758c1.png\"\n\n        - name: \"Studyplus, Inc.\"\n          website: \"https://tech.studyplus.co.jp/recruit\"\n          slug: \"StudyplusInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/781-2d9e7303.png\"\n\n        - name: \"Coincheck, Inc.\"\n          website: \"https://corporate.coincheck.com/\"\n          slug: \"CoincheckInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/783-05b1ee51.png\"\n\n        - name: \"Karrot\"\n          website: \"https://karrotmarket.com\"\n          slug: \"Karrot\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/786-d23add7d.png\"\n\n        - name: \"Hamee Corp.\"\n          website: \"https://hamee.co.jp/\"\n          slug: \"HameeCorp\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/798-24fba905.png\"\n\n        - name: \"MNTSQ, Ltd.\"\n          website: \"https://www.mntsq.co.jp/\"\n          slug: \"MNTSQLtd\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/803-207dfc37.png\"\n\n        - name: \"ENECHANGE Ltd.\"\n          website: \"https://enechange.co.jp/\"\n          slug: \"ENECHANGELtd\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/805-b39afaaf.png\"\n\n        - name: \"ASHITA-TEAM Co., Ltd.\"\n          website: \"https://www.ashita-team.com/\"\n          slug: \"ASHITATEAMCoLtd\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/809-858834f1.png\"\n\n        - name: \"TimeTree, Inc.\"\n          website: \"https://timetreeapp.com/intl\"\n          slug: \"TimeTreeInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/817-2d1a9c67.png\"\n\n        - name: \"Linkers Corporation\"\n          website: \"https://corp.linkers.net/\"\n          slug: \"LinkersCorporation\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/827-5b1ab083.png\"\n\n        - name: \"IBJ, inc\"\n          website: \"https://www.ibjapan.jp/\"\n          slug: \"IBJinc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/853-a24f0d82.png\"\n\n        - name: \"Social PLUS Inc.\"\n          website: \"https://www.socialplus.jp/\"\n          slug: \"SocialPLUSInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/857-33a1fede.png\"\n\n        - name: \"AppBrew, Inc.\"\n          website: \"https://appbrew.io/\"\n          slug: \"AppBrewInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/862-a041f686.png\"\n\n        - name: \"Fusic Co., Ltd.\"\n          website: \"https://fusic.co.jp/\"\n          slug: \"FusicCoLtd\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/872-76e15893.png\"\n\n        - name: \"SAKURA internet Inc.\"\n          website: \"https://www.sakura.ad.jp/\"\n          slug: \"SAKURAinternetInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/874-87c79346.png\"\n\n        - name: \"vivid garden Inc.\"\n          website: \"https://vivid-garden.co.jp/\"\n          slug: \"vividgardenInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/875-5e20a03e.png\"\n\n        - name: \"CrowdWorks, Inc.\"\n          website: \"https://crowdworks.co.jp/\"\n          slug: \"CrowdWorksInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/876-9a3762ea.png\"\n\n    - name: \"Silver Sponsors\"\n      description: |-\n        Silver tier sponsors supporting RubyKaigi 2025\n      level: 4\n      sponsors:\n        - name: \"FjordBootCamp\"\n          website: \"https://bootcamp.fjord.jp\"\n          slug: \"FjordBootCamp\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/766-76f55318.png\"\n\n        - name: \"ClearCode Inc.\"\n          website: \"https://www.clear-code.com/\"\n          slug: \"ClearCodeInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/768-a95ac705.png\"\n\n        - name: \"Geekneer, Inc.\"\n          website: \"https://geekneer.com/\"\n          slug: \"GeekneerInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/773-7c7373c5.png\"\n\n        - name: \"I'LL inc.\"\n          website: \"https://www.ill.co.jp\"\n          slug: \"ILLinc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/778-d0b1ccf6.png\"\n\n        - name: \"xalpha Inc.\"\n          website: \"https://xalpha.jp/\"\n          slug: \"xalphaInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/797-5db65c11.png\"\n\n        - name: \"TakeyuWeb Inc.\"\n          website: \"https://takeyuweb.co.jp\"\n          slug: \"TakeyuWebInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/800-25512760.png\"\n\n        - name: \"PIXTA Inc.\"\n          website: \"https://pixta.co.jp/business\"\n          slug: \"PIXTAInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/810-ce7b9067.png\"\n\n        - name: \"kickflow, Inc.\"\n          website: \"https://kickflow.com/\"\n          slug: \"kickflowInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/816-1ba151f0.png\"\n\n        - name: \"Being\"\n          website: \"https://www.beingcorp.co.jp/\"\n          slug: \"Being\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/818-5afcfd6d.png\"\n\n        - name: \"i-plug Co., Ltd.\"\n          website: \"https://i-plug.co.jp/\"\n          slug: \"iplugCoLtd\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/819-34a9c5b4.png\"\n\n        - name: \"Rentio Inc.\"\n          website: \"https://www.rentio.jp/\"\n          slug: \"RentioInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/822-f2266a38.png\"\n\n        - name: \"Everyleaf Corporation\"\n          website: \"https://everyleaf.com/\"\n          slug: \"EveryleafCorporation\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/824-3edffdc0.png\"\n\n        - name: \"Wantedly, Inc.\"\n          website: \"https://wantedlyinc.com/ja\"\n          slug: \"WantedlyInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/829-a225bee1.png\"\n\n        - name: \"B4A, Inc.\"\n          website: \"https://jobs.b4a.co.jp/\"\n          slug: \"B4AInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/835-c6f7a2d9.png\"\n\n        - name: \"Ezowin Inc.\"\n          website: \"https://ezowin.com/\"\n          slug: \"EzowinInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/842-74f4d63e.png\"\n\n        - name: \"esa LLC\"\n          website: \"https://esa.io\"\n          slug: \"esaLLC\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/845-896282ea.png\"\n\n        - name: \"Tsukulink Inc.\"\n          website: \"https://tsukulink.co.jp/\"\n          slug: \"TsukulinkInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/860-d28c6fbe.png\"\n\n        - name: \"Bloomo Securities Inc.\"\n          website: \"https://bloomo.co.jp/\"\n          slug: \"BloomoSecuritiesInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/861-02aa9b23.png\"\n\n        - name: \"Doctorbook Inc.\"\n          website: \"https://doctorbook.co.jp/\"\n          slug: \"DoctorbookInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/863-0e443661.png\"\n\n        - name: \"A's Child Inc.\"\n          website: \"https://www.as-child.com/\"\n          slug: \"AsChildInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/864-cf9e3dd3.png\"\n\n        - name: \"i Cubed Systems, Inc.\"\n          website: \"https://www.i3-systems.com/\"\n          slug: \"iCubedSystemsInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/865-165b3483.png\"\n\n        - name: \"FUNDINNO Inc.\"\n          website: \"https://corp.fundinno.com/\"\n          slug: \"FUNDINNOInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/866-387d3463.png\"\n\n        - name: \"Luxiar Co., Ltd.\"\n          website: \"https://www.luxiar.com/\"\n          slug: \"LuxiarCoLtd\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/869-33384f0a.png\"\n\n        - name: \"Synchro Food\"\n          website: \"https://www.synchro-food.co.jp/\"\n          slug: \"SynchroFood\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/870-352b86c8.png\"\n\n        - name: \"HireRoo, Inc.\"\n          website: \"https://hireroo.io/\"\n          slug: \"HireRooInc\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/873-9a3246be.png\"\n\n        - name: \"Research and Innovation Co.,Ltd.\"\n          website: \"https://r-n-i.jp/\"\n          slug: \"ResearchandInnovationCoLtd\"\n          logo_url: \"https://rubykaigi.org/2025/images/sponsors/877-eaad636f.png\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2025/venue.yml",
    "content": "---\nname: \"Ehime Prefectural Culture Hall\"\n\naddress:\n  street: \"1-11-1 Dogo-Imamachi\"\n  city: \"Matsuyama\"\n  region: \"Ehime\"\n  postal_code: \"790-0843\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"1-11-1 Dogo-Imamachi, Matsuyama, Ehime 790-0843, Japan\"\n\ncoordinates:\n  latitude: 33.8520\n  longitude: 132.7870\n\nmaps:\n  google: \"https://maps.google.com/?q=Ehime+Prefectural+Culture+Hall,+Matsuyama\"\n  apple: \"https://maps.apple.com/?q=Ehime+Prefectural+Culture+Hall,+Matsuyama\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=33.8520&mlon=132.7870\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2025/videos.yml",
    "content": "---\n## Day 1\n\n- title: \"Keynote: Ruby Taught Me About Encoding Under the Hood\"\n  raw_title: \"[JA][Keynote] Ruby Taught Me About Encoding Under the Hood / Mari Imaizumi @ima1zumi\"\n  speakers:\n    - Mari Imaizumi\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"hNSkCqMUMQA\"\n  id: \"mari-imaizumi-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    In modern computing, Unicode has become the go-to solution for most scenarios. However, challenges related to character encoding still exist and continue to evolve as we adapt to Unicode. By examining how Ruby handles updates to Unicode, this discussion explores the current issues surrounding character encoding.\n\n    https://rubykaigi.org/2025/presentations/ima1zumi.html\n  slides_url: \"https://speakerdeck.com/ima1zumi/ruby-taught-me-about-under-the-hood\"\n\n- title: \"Make Parsers Compatible Using Automata Learning\"\n  raw_title: \"[JA] Make Parsers Compatible Using Automata Learning / Hiroya Fujinami @makenowjust\"\n  speakers:\n    - Hiroya Fujinami\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"GnQ03guf0fo\"\n  id: \"hiroya-fujinami-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    CRuby currently has two parsers, Prism and parse.y, and starting with Ruby 3.4, Prism has become the default parser. Prism is a new Ruby parser that claims to be highly compatible with the traditional parser, parse.y. But, how can we guarantee this compatibility? One formal (academic) solution to this problem is automata learning, an algorithm to infer an automata from a black-box system. Automata has some benefits, e.g., we can verify two automata are the same. Therefore, we can ensure that Prism and parse.y are the same if their automata obtained by automata learning are the same. In this talk, we provide an overview the automata theory and introduce an algorithm of automata learning called L*. We will also introduce the case study of how a compatibility issue in Prism was found using automata learning (ruby/prism#3035). We believe it will be an interesting talk as an application of the latest academic topics.\n\n    https://rubykaigi.org/2025/presentations/makenowjust.html\n  slides_url: \"https://speakerdeck.com/makenowjust/make-parsers-compatible-using-automata-learning\"\n\n- title: \"Bringing Linux pidfd to Ruby\"\n  raw_title: \"[EN] Bringing Linux pidfd to Ruby / Maciej Mensfeld @maciejmensfeld\"\n  speakers:\n    - Maciej Mensfeld\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"c0IOtaaMzow\"\n  id: \"maciej-mensfeld-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: |-\n    Processes and fork management in Ruby have traditionally relied on PIDs, leading to race conditions and potential security issues in high-throughput systems. While Linux 5.3 introduced pidfd as a solution, Ruby lacks native support for this feature. I'll demonstrate how I bridged this gap using FFI, exploring syscall mappings, zombie process prevention, and practical process management patterns. Through live demonstrations, you'll learn how Linux pidfd APIs can help you eliminate race conditions and make your Ruby applications more reliable in modern environments.\n\n    https://rubykaigi.org/2025/presentations/maciejmensfeld.html\n  slides_url: \"https://mensfeld.github.io/bringing_linux_pidfd_to_ruby/\"\n\n- title: \"Introducing Type Guard to Steep\"\n  raw_title: \"[JA] Introducing Type Guard to Steep / Takeshi KOMIYA @tk0miya\"\n  speakers:\n    - Takeshi KOMIYA\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"kp_jeGkUmhY\"\n  id: \"takeshi-komiya-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: |-\n    Type checking in Ruby often requires narrowing the types of objects, especially within complex conditionals or method chains. While Steep already supports type narrowing through built-in methods like #is_a? and #nil?, real-world Ruby applications frequently rely on user-defined logic for type narrowing.\n\n    In this talk, I will propose \"Type Guard,\" an enhancement to Steep that enables developers to define custom type narrowing logic. This feature aims to bridge the gap between Steep's capabilities and the diverse needs of real-world Ruby projects, providing a more seamless type-checking experience.\n\n    Attendees will learn how Type Guard works, and how it can be integrated into their projects.\n\n    https://rubykaigi.org/2025/presentations/tk0miya.html\n  slides_url: \"https://docs.google.com/presentation/d/1VpFDEG0ZOghhvAYlTrthzD9QdlXbCbSn9MUd2FCGGC4/view\"\n\n- title: \"The Evolution of the CRuby Build System\"\n  raw_title: \"[EN] The Evolution of the CRuby Build System / Yuta Saito @kateinoigakukun\"\n  speakers:\n    - Yuta Saito\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"SeaGU6OXnIw\"\n  id: \"yuta-saito-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    The CRuby build system based on GNU Autotools has been evolving over the years, and it has been a critical part of the Ruby development process. However, the current build system has two major challenges: it's showing its age and is getting harder to edit and maintain without help from the expert, and `./configure && make` takes a long time even on a modern machine with many cores.\n\n    In this talk, I will discuss the evolution of the CRuby build system, the challenges we face today, and the potential future directions. I will also introduce the new build system that I have been working on, which is inspired by the Shake build system.\n\n    https://rubykaigi.org/2025/presentations/kateinoigakukun.html\n  slides_url: \"https://speakerdeck.com/kateinoigakukun/the-evolution-of-the-cruby-build-system\"\n\n- title: \"A side gig for RuboCop, the Bookworm code crawler\"\n  raw_title: \"[EN] A side gig for RuboCop, the Bookworm code crawler / David T. Crosby @dafyddcrosby\"\n  speakers:\n    - David T. Crosby\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"w-nLv5qn3XI\"\n  id: \"david-t-crosby-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: |-\n    RuboCop is typically thought of as 'just' a linting or refactoring tool. However, one of RuboCop's foundational features, the NodePattern API, is so useful for crawling Ruby AST that an open-source tool called Bookworm has been written that uses the NodePattern API to understand the large Chef Ruby codebase used at Meta.\n\n    https://rubykaigi.org/2025/presentations/dafyddcrosby.html\n  slides_url: \"https://dafyddcrosby.com/bookworm_kaigi_talk.pdf\"\n\n- title: \"Continuation is to be continued\"\n  raw_title: \"[JA] Continuation is to be continued / Masayuki Mizuno @fetburner\"\n  speakers:\n    - Masayuki Mizuno\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"3F0aNCWjZT0\"\n  id: \"masayuki-mizuno-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: |-\n    Despite the subtle relationship with interpreter implementations, first-class continuations still have unique functionality. In this talk, I will describe how \"callcc\"—a control flow operator which is provided in library \"continuation\"—plays an important role in the context of domain specific language through the \"do syntax\" of list monads. In addition, I also claim how \"callcc\" has some inconveniences—cutting unnecessarily wide program pieces, and resulting in degraded executing performances—and introduce its advanced form, delimited continuation operators can resolve many issues.\n\n    https://rubykaigi.org/2025/presentations/fetburner.html\n  slides_url: \"\"\n\n- title: \"Deoptimization: How YJIT Speeds Up Ruby by Slowing Down\"\n  raw_title: \"[EN] Deoptimization: How YJIT Speeds Up Ruby by Slowing Down / Takashi Kokubun @k0kubun\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"bvK86pmU-Oc\"\n  id: \"takashi-kokubun-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    Have you wondered why Ruby keeps getting faster at every release despite challenges like handling metaprogramming and dynamic typing? In this talk, you'll discover how YJIT \"hides\" Ruby's sources of slowness by sometimes \"slowing down\" Ruby, and why this counterintuitive strategy is key to its performance gains.\n\n    https://rubykaigi.org/2025/presentations/k0kubun.html\n  slides_url: \"https://speakerdeck.com/k0kubun/rubykaigi-2025\"\n\n- title: \"Empowering Developers with HTML-Aware ERB Tooling\"\n  raw_title: \"[EN] Empowering Developers with HTML-Aware ERB Tooling / Marco Roth @marcoroth\"\n  speakers:\n    - Marco Roth\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"EIoGfMGsiZI\"\n  id: \"marco-roth-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: |-\n    ERB tooling has lagged behind modern web development needs, especially with the rise of Hotwire and HTML-over-the-wire. Discover a new HTML-aware ERB parser that unlocks advanced developer tools like formatters, linters, and LSP integrations, enhancing how we build and ship HTML in our Ruby applications.\n\n    https://rubykaigi.org/2025/presentations/marcoroth.html\n  slides_url: \"https://speakerdeck.com/marcoroth/empowering-developers-with-html-aware-erb-tooling-at-rubykaigi-2025-matsuyama-ehime\"\n\n- title: \"Goodbye fat gem 2025\"\n  raw_title: \"[JA] Goodbye fat gem 2025 / Sutou Kouhei @ktou\"\n  speakers:\n    - Sutou Kouhei\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"ZAONpE2JYw0\"\n  id: \"sutou-kouhei-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: |-\n    This talk proposes that moving away from fat gems—gems that include pre-built binaries—would benefit the Ruby ecosystem. While fat gems offer fast installation, they also bring high maintenance costs, slow updates for new Ruby versions, and delayed vulnerability fixes. The session discusses whether the Python wheel approach is suitable for Ruby, considering both user and developer perspectives.\n\n    https://rubykaigi.org/2025/presentations/ktou.html\n  slides_url: \"https://slide.rabbit-shocker.org/authors/kou/rubykaigi-2025/\"\n\n- title: \"Ruby's Line Breaks\"\n  raw_title: \"[JA] Ruby's Line Breaks / Yuichiro Kaneko @spikeolaf\"\n  speakers:\n    - Yuichiro Kaneko\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"_JvNjN49wfI\"\n  id: \"yuichiro-kaneko-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    Line break is one of the interesting characters in Ruby grammar. For example, line break on the first line is ignored but on the fourth line works as separator of statements.\n\n    This talk will reveal principles and exceptions of line break in Ruby Grammar by analysis of grammar file and introduce new Lrama parser generator feature to reduce implementation complexity of lex state.\n\n    https://rubykaigi.org/2025/presentations/spikeolaf.html\n  slides_url: \"https://speakerdeck.com/yui_knk/rubys-line-breaks\"\n\n- title: \"SDB: Efficient Ruby Stack Scanning Without the GVL\"\n  raw_title: \"[EN] SDB: Efficient Ruby Stack Scanning Without the GVL / Mike Yang @yfractal\"\n  speakers:\n    - Mike Yang\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"vJHqrRQoJsU\"\n  id: \"mike-yang-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: |-\n    Most existing Ruby stack profilers rely on the GVL, which blocks application execution and leads to high CPU usage.\n\n    SDB, on the other hand, releases the GVL when scanning Ruby thread stacks. This design minimizes its impact on Ruby applications, allowing us to increase the sampling rate from 100/s to 1000/s while still consuming very low CPU. This makes SDB a truly always-online stack profiler.\n\n    In this talk, I will explain how to implement a stack profiler without relying on the GVL, along with its benefits and challenges.\n\n    https://rubykaigi.org/2025/presentations/yfractal.html\n  slides_url: \"https://speakerdeck.com/yfractal/sdb-efficient-ruby-stack-scanning-without-the-gvl\"\n\n- title: \"Automatically generating types by running tests\"\n  raw_title: \"[JA] Automatically generating types by running tests / Takumi Shotoku @sinsoku_listy\"\n  speakers:\n    - Takumi Shotoku\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"JUmQ01Y1F_E\"\n  id: \"takumi-shotoku-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: |-\n    Introducing RBS into an existing application is difficult. It is impractical to manually write types for all methods in an application with many lines of code.\n\n    To solve this issue, I am developing a gem that collects type information at test runtime and automatically inserts it as an embedded RBS type declaration (for rbs-inline). This talk will introduce the development status of the gem, implementation details, and usage.\n\n    https://rubykaigi.org/2025/presentations/sinsoku_listy.html\n  slides_url: \"https://speakerdeck.com/sinsoku/automatically-generating-types-by-running-tests\"\n\n- title: \"State of Namespace\"\n  raw_title: \"[JA] State of Namespace / Satoshi Tagomori @tagomoris\"\n  speakers:\n    - Satoshi \"moris\" Tagomori\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"lV9JoFtR1To\"\n  id: \"satoshi-tagomori-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    This presentation will explain what Namespace is, the current state of Namespace, and the things to be done in the future.\n\n    https://rubykaigi.org/2025/presentations/tagomoris.html\n  slides_url: \"https://speakerdeck.com/tagomoris/state-of-namespace\"\n\n- title: \"Embracing Ruby magic: Statically analyzing DSLs\"\n  raw_title: \"[EN] Embracing Ruby magic: Statically analyzing DSLs / Vinicius Stock @vinistock\"\n  speakers:\n    - Vinicius Stock\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"O0ZYNhHvPXQ\"\n  id: \"vinicius-stock-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: |-\n    One of Ruby's most powerful features is the ability to extend the language itself through meta-programming. We can create rich and elegant DSLs that allow developers to solve problems with flexible and concise code.\n\n    The drawback of DSLs is that they are difficult to analyze statically, reducing the usefulness of developer tooling like editor integrations. Since each gem can define their own DSL, we cannot account for all possible DSLs that may exist in a given application. So what can we do?\n\n    Let's do a deep dive into the Ruby LSP's add-on API, which allows any other gem to enhance the static analysis understanding of the language server for a more accurate editor experience. We'll explore the techniques behind it and which class of problems it can solve.\n\n    https://rubykaigi.org/2025/presentations/vinistock.html\n  slides_url: \"https://speakerdeck.com/vinistock/embracing-ruby-magic\"\n\n- title: \"50.000 processed records per second: a CRuby & JRuby story\"\n  raw_title: \"[EN] 50.000 processed records per second: a CRuby & JRuby story / Cristian Planas @cristian_planas\"\n  speakers:\n    - Cristian Planas\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"cFiXnzF-_p0\"\n  id: \"cristian-planas-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: |-\n    In this talk, we will share the fascinating journey of the Zendesk Indexer, a microservice responsible for indexing tens of thousands of records per second from a relational database into ElasticSearch. Originally born from a need to speed up record updates, the Indexer evolved from a series of scripts written in C-Ruby into a full application built in JRuby. Over the years, it incorporated diverse technologies like Riak and S3 and tackled significant challenges, particularly with concurrency, as Zendesk scaled. Now, we are preparing to reintegrate it into the Rails monolith. Attendees will learn valuable lessons about concurrency, safety mechanisms and scaling.\n\n    https://rubykaigi.org/2025/presentations/cristian_planas.html\n  slides_url: \"https://www.slideshare.net/slideshow/50-000-processed-records-per-second-a-cruby-jruby-story/278760878\"\n\n- title: \"mruby/c and data-flow programming for small devices\"\n  raw_title: \"[EN] mruby/c and data-flow programming for small devices / Kazuaki Tanaka @kaz0505\"\n  speakers:\n    - Kazuaki Tanaka\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"DLCzPvAgayo\"\n  id: \"kazuaki-tanaka-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    In my presentation, I will show how data-flow programming can be used for software development of small devices. The effectiveness of the proposed method is demonstrated with a microcontroller implementation in mruby/c.\n\n    In IoT programming, we want to focus on the flow of data generation and processing. This is data flow programming, also known as the Node-RED development environment.\n\n    Data flow is processed asynchronously. I will explain how to implement this asynchronous processing in a reasonable manner using mruby/c and demonstrate its operation on a real microcontroller.\n\n    https://rubykaigi.org/2025/presentations/kaz0505.html\n  slides_url: \"https://www.slideshare.net/slideshow/mruby-c-and-data-flow-programming-for-small-devices/278614229\"\n\n- title: \"Parsing and generating SQLite's SQL dialect with Ruby\"\n  raw_title: \"[EN] Parsing and generating SQLite's SQL dialect with Ruby / Stephen Margheim @fractaledmind\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"VaSpF9JmbZo\"\n  id: \"stephen-margheim-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: |-\n    SQLite's popularity is on the rise, and likewise the ecosystem of tools around it is growing. Unfortunately, SQLite does not expose its parser for 3rd parties to use independently. This greatly limits the ability of developers to build tools that must interact with SQLite's SQL dialect. And so, I have hand-written a 100% Ruby, 100% compatible parser for SQLite's SQL dialect. In addition, having a complete AST permits us to also generate SQL queries from terse, structured Ruby code. In this talk, I will demonstrate how we ensure that the parser is 100% compatible with SQLite's SQL dialect. We will also explore how the parser is implemented and what kind of AST it produces. Then, we will dive into how to use the parser to build tools that can analyze and manipulate SQL queries. Finally, we will look at how to use the generator to build tools that can generate SQL queries programmatically. As Ruby's only full SQLite SQL parser, this library opens up a world of possibilities for developers.\n\n    https://rubykaigi.org/2025/presentations/fractaledmind.html\n  slides_url: \"https://speakerdeck.com/fractaledmind/ruby-kaigi-2025-parsing-and-generating-sqlites-sql-dialect-with-ruby\"\n\n- title: \"dRuby on Browser Again!\"\n  raw_title: \"[JA] dRuby on Browser Again! / Yoh Osaki @youchan Shigeru Nakajima @ledsun\"\n  speakers:\n    - Yoh Osaki\n    - Shigeru Nakajima\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"A6IhjHHqYFU\"\n  id: \"yoh-osaki-shigeru-nakajima-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: |-\n    I talked about dRuby on Browser at RubyKaigi2017. This talk is about two of my gems: an implementation of dRuby websocket protocol and a dRuby implementation that runs on browser using opal. Recently, ruby.wasm is one more Ruby option that runs on browsers. I implement a dRuby again! Let's get to experience seamless programming on browser by dRuby.\n\n    https://rubykaigi.org/2025/presentations/youchan.html\n  slides_url: \"https://slide.youchan-apps.net\"\n\n- title: \"TRICK 2025: Episode I\"\n  raw_title: \"[JA] TRICK 2025: Episode I / mame & the judges @tric\"\n  speakers:\n    - Yusuke Endoh\n    - Koichiro Eto\n    - Shinichiro Hamaji\n    - Yutuka Hara\n    - Yukihiro \"Matz\" Matsumoto\n    - Sun Park\n    - Darren Smith\n    - Tomoya Ishida\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-16\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"z0V0L1nTVMg\"\n  id: \"mame-the-judges-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    \"Feel, don't think.\"\n\n    https://github.com/tric/trick2025\n  slides_url: \"https://speakerdeck.com/mame/trick-2025-results\"\n  additional_resources:\n    - name: \"tric/trick2025\"\n      type: \"repo\"\n      url: \"https://github.com/tric/trick2025\"\n\n## Day 2\n\n- title: \"Keynote: Performance Bugs and Low-level Ruby Observability APIs\"\n  raw_title: \"[EN][Keynote] Performance Bugs and Low-level Ruby Observability APIs / Ivo Anjo @KnuX\"\n  speakers:\n    - Ivo Anjo\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"nSdkM-PEL6c\"\n  id: \"ivo-anjo-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Main Hall #rubykaigiA\"\n  description: \"\"\n  slides_url: \"https://docs.google.com/presentation/d/1lDnxFkc4URsi0LP4w1M5IXv5A02AG_HUy3gW_SpEWOA/view\"\n\n- title: \"Dissecting and Reconstructing Ruby Syntactic Structures\"\n  raw_title: \"[JA] Dissecting and Reconstructing Ruby Syntactic Structures / Yudai Takada @ydah_\"\n  speakers:\n    - Yudai Takada\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"17xQKhpCmGs\"\n  id: \"yudai-takada-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: \"\"\n  slides_url: \"\"\n\n- title: \"Benchmark and profile every single change\"\n  raw_title: \"[EN] Benchmark and profile every single change / Daisuke Aritomo @osyoyu\"\n  speakers:\n    - Daisuke Aritomo\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"PI_ODvQsj2g\"\n  id: \"daisuke-arimoto-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: \"\"\n  slides_url: \"\"\n\n- title: \"Running JavaScript within Ruby\"\n  raw_title: \"[EN] Running JavaScript within Ruby / Kengo Hamasaki @hmsk\"\n  speakers:\n    - Kengo Hamasaki\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"vkq4Cv-g8nk\"\n  id: \"kengo-hamasaki-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: \"\"\n  slides_url: \"\"\n\n- title: \"ZJIT: Building a Next Generation Ruby JIT\"\n  raw_title: \"[EN] ZJIT: Building a Next Generation Ruby JIT / Maxime Chevalier-Boisvert @maximecb\"\n  speakers:\n    - Maxime Chevalier-Boisvert\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"1CCDuRW0OLk\"\n  id: \"maxime-chevalier-boisvert-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Main Hall #rubykaigiA\"\n  description: \"\"\n  slides_url: \"https://www.slideshare.net/slideshow/zjit-building-a-next-generation-ruby-jit/278807093\"\n\n- title: \"Keeping Secrets: Lessons Learned From Securing GitHub\"\n  raw_title: \"[EN] Keeping Secrets: Lessons Learned From Securing GitHub / Dennis Pacewicz @lyninx Wei Lin Ngo @Creastery\"\n  speakers:\n    - Dennis Pacewicz\n    - Wei Lin Ngo\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"oY0OcLpdCXs\"\n  id: \"dennis-pacewicz-wei-lin-ngo-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: \"\"\n  slides_url: \"\"\n\n- title: \"Improvement of REXML and speed up using StringScanner\"\n  raw_title: \"[JA] Improvement of REXML and speed up using StringScanner / NAITOH Jun @naitoh\"\n  speakers:\n    - NAITOH Jun\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"-R5w5vVbw-8\"\n  id: \"naitoh-jun-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: \"\"\n  slides_url: \"\"\n\n- title: \"Writing Ruby Scripts with TypeProf\"\n  raw_title: \"[JA] Writing Ruby Scripts with TypeProf / Yusuke Endoh @mametter\"\n  speakers:\n    - Yusuke Endoh\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"EEWnXE8kbgg\"\n  id: \"yusuke-endoh-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: \"\"\n  slides_url: \"\"\n\n- title: \"Demystifying Ruby Debuggers: A Deep Dive into Internals\"\n  raw_title: \"[EN] Demystifying Ruby Debuggers: A Deep Dive into Internals / Dmitry Pogrebnoy @DmitryPogrebnoy\"\n  speakers:\n    - Dmitry Pogrebnoy\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"ynrXsbuApXM\"\n  id: \"dmitry-pogrebnoy-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: \"\"\n  slides_url: \"\"\n\n- title: \"How to make the Groovebox\"\n  raw_title: \"[JA] How to make the Groovebox / Yuya Fujiwara @asonas\"\n  speakers:\n    - Yuya Fujiwara\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"4DgmD9TS5xY\"\n  id: \"yuya-fujiwara-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: |-\n    Ruby isn't just for the Web. Did you know you can create music with it too?\n\n    In this talk, I will demonstrate how groovebox-ruby was built from scratch as a functional groovebox using Ruby. What is a groovebox? It's a machine for sketching musical ideas, equipped with tools like synthesizers, step sequencers, filters, samplers, and interactive controls such as buttons, knobs, and displays.\n\n    With groovebox-ruby, I began by implementing synthesizer basics like VCOs (Voltage Controlled Oscillators) and VCFs (Voltage Controlled Filters) to understand how these components shape sound. I then added a step sequencer, allowing users to program patterns and interact dynamically with MIDI inputs.\n\n    Reimplementing these features in Ruby deepened my understanding of synthesizers, particularly the roles of oscillators and filters. Ruby's extensibility also enabled modular design, such as chaining filters, using MIDI controllers, and building a distributed step sequencer with dRuby.\n\n    https://rubykaigi.org/2025/presentations/asonas.html\n  slides_url: \"https://speakerdeck.com/asonas/how-to-make-the-groovebox\"\n\n- title: \"MicroRuby: True Microcontroller Ruby\"\n  raw_title: \"[JA] MicroRuby: True Microcontroller Ruby / Hitoshi HASUMI @hasumikin\"\n  speakers:\n    - HASUMI Hitoshi\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"5lHtsJJ3jXI\"\n  id: \"hitoshi-hasumi-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    PicoRuby's VM is mruby/c. While it has the advantage of being memory-saving, it also has disadvantages such as a lack of Ruby language specifications and the inability to call Ruby methods from C.\n\n    By integrating the mruby VM into PicoRuby's features of memory-saving runtime compilation and a practical development ecosystem, MicroRuby brings ISO/IEC 30170-compliant Ruby to microcontroller programming and expands the scope of application development. In this session, I will provide a detailed explanation of the technical barriers that this project has overcome.\n\n    https://rubykaigi.org/2025/presentations/hasumikin.html\n  slides_url: \"https://slide.rabbit-shocker.org/authors/hasumikin/RubyKaigi2025/\"\n\n- title: \"Bazel for Ruby\"\n  raw_title: \"[EN] Bazel for Ruby / Alex Rodionov @p0deje\"\n  speakers:\n    - Alex Rodionov\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"6C4NKE_f5Kk\"\n  id: \"alex-rodionov-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: |-\n    From Google and Nvidia to Airbnb and Stripe, top companies use Bazel to power their builds. Nowadays, with canonical support for the Ruby language, Bazel isn't just for Java and C++ anymore!\n\n    Learn how Bazel can transform the development experience in your Ruby projects! We'll talk about leveraging Bazel's speed, scalability, and reliability to streamline your workflows, improve code quality, make tests blazing fast, and boost developer productivity:\n\n    * Seamlessly integrate Bazel with popular tools and frameworks like Rails, RSpec, and RuboCop.\n    * Optimize test execution from minutes to seconds.\n    * Integrate remote caching and execution to supercharge your development and CI pipelines.\n    * Manage dependencies with ease and precision, ensuring consistent and reproducible builds.\n    * Unlock advanced build features like hermeticity and fine-grained invalidation.\n\n    Leave this session with the knowledge and resources to start using Bazel in your Ruby projects today!\n\n    https://rubykaigi.org/2025/presentations/p0deje.html\n  slides_url: \"https://speakerdeck.com/p0deje/bazel-for-ruby-rubykaigi-2025\"\n\n- title: \"RuboCop: Modularity and AST Insights\"\n  raw_title: \"[JA] RuboCop: Modularity and AST Insights / Koichi ITO @koic\"\n  speakers:\n    - Koichi ITO\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"g5B-DMqzjIA\"\n  id: \"koichi-ito-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: |-\n    RuboCop has long faced issues with a lack of modularity and is now encountering new challenges due to changes in the parser engine.\n\n    There has been extensive development of custom cop extension gems, but these extension methods have relied on RuboCop's implementation for a long time. RuboCop is widely used behind the scenes in the Ruby ecosystem. For example, the backends of Ruby LSP and Standard Ruby utilize RuboCop's engine. However, the division of responsibilities with these tools has been insufficient. The introduction of the plugin system using lint_roller and the Ruby LSP add-on aim to resolve these issues. I will discuss the adoption and availability of integrating these into RuboCop.\n\n    Another major issue is the maintenance status of the Parser gem, which has long been RuboCop's backend parser. I will talk about RuboCop's future backend strategy based on Prism.\n\n    You will gain insights into new methods of extending RuboCop and the upcoming changes in the near future.\n\n    https://rubykaigi.org/2025/presentations/koic.html\n  slides_url: \"https://speakerdeck.com/koic/rubocop-modularity-and-ast-insights\"\n\n- title: \"Speeding up Class#new\"\n  raw_title: \"[JA] Speeding up Class#new / Aaron Patterson @tenderlove\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"vu89GT2q6ZI\"\n  id: \"aaron-patterson-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    Many Ruby developers like to initialize new objects, so let's take a dive into Ruby object initialization! What makes creating an object slow? Can we use Ruby to speed it up? In this talk, we will examine the internals of the `Class#new` method, explore the trade-offs between Ruby and C method calls, and experiment with a Ruby implementation of `Class#new`. Additionally, we will discuss strategies for speeding up Ruby method calls, such as inline caches, while also considering the drawbacks of moving from C to Ruby.\n\n    https://rubykaigi.org/2025/presentations/tenderlove.html\n  slides_url: \"https://speakerdeck.com/tenderlove/rubykaigi-2025-class-new-a-new-approach\"\n\n- title: \"You Can Save Lives With End-to-end Encryption in Ruby\"\n  raw_title: \"[EN] You Can Save Lives With End-to-end Encryption in Ruby / Ryo Kajiwara @s01\"\n  speakers:\n    - Ryo Kajiwara\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"JWQsJxdvMQg\"\n  id: \"ryo-kajiwara-rubykaigi-2025\"\n  language: \"english\"\n  track: \"Sub Hall #rubykaigiB\"\n  description: |-\n    \"Why do you need End-to-end Encryption in Ruby?\"\n\n    This talk will cover the Ruby implementation of the Messaging Layer Security protocol (RFC 9420), which enables authenticated key exchange in group messaging systems. By learning how end-to-end encryption in group messaging works, you could be more confident about the security of your daily messages that are sent through your messaging apps. And yes, it does save actual lives.\n\n    This talk covers how the protocol works, details of the Ruby implementation, why it is important for Ruby, and the ongoing work on the future of modern cryptography in Ruby.\n\n    https://rubykaigi.org/2025/presentations/s01.html\n  slides_url: \"https://speakerdeck.com/sylph01/end-to-end-encryption-saves-lives-you-can-start-saving-lives-with-ruby-too\"\n\n- title: \"Write you a Barrier - Automatic Insertion of Write Barriers\"\n  raw_title: \"[JA] Write you a Barrier - Automatic Insertion of Write Barriers / Martin J. Dürst @duerst Joichiro Okoshi @joetake\"\n  speakers:\n    - Martin J. Dürst\n    - Joichiro Okoshi\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"w1l_QoAeTlY\"\n  id: \"martin-j-durst-joichiro-okoshi-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: |-\n    Currently, inserting write barriers into C extension code for Ruby is difficult and error-prone. We present a new tool that we created to add or check for write barriers automatically. We explain the benefits of using the tool for C extension creation, give implementation details, and show the tool's limitations.\n\n    https://rubykaigi.org/2025/presentations/duerst.html\n  slides_url: \"\"\n\n- title: \"Making TCPSocket.new 'Happy'!\"\n  raw_title: \"[JA] Making TCPSocket.new 'Happy'! / Misaki Shioi @coe401_\"\n  speakers:\n    - Misaki Shioi\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"b0BXNOLJ124\"\n  id: \"misaki-shioi-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: |-\n    I introduced Happy Eyeballs Version 2 (RFC8305) (hereafter HEv2) into the socket library's `Socket.tcp` and `TCPSocket.new`. This algorithm addresses the issue of delays that occur when DNS resolution for one address family takes too long, or when one of the candidate IP addresses is unavailable, preventing fallback to other options.\n\n    At RubyKaigi 2024, I presented how HEv2 was implemented in `Socket.tcp` (written in Ruby). And I initially planned to apply the same approach to `TCPSocket.new` (written in C). However, things did not go as expected, and the work began with reimplementing `Socket.tcp` itself.\n\n    This was a deeply rewarding project—so much so that it turned me, a Rubyist with an interest in networking, into a Ruby committer.\n\n    In this presentation, I will revisit HEv2, particularly focusing on `TCPSocket.new`, and share the journey of how it was implemented, merged, and eventually released as part of Ruby 3.4.\n\n    https://rubykaigi.org/2025/presentations/coe401_.html\n  slides_url: \"https://speakerdeck.com/coe401_/making-tcpsocket-dot-new-happy\"\n\n- title: \"From C extension to pure C: Migrating RBS\"\n  raw_title: \"[EN] From C extension to pure C: Migrating RBS / Alexander Momchilov @amomchilov\"\n  speakers:\n    - Alexander Momchilov\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"AgY9tm4sBbc\"\n  id: \"alexander-momchilov-rubykaigi-2025\"\n  track: \"Sub Hall #rubykaigiB\"\n  language: \"english\"\n  description: |-\n    Learn how we migrated RBS to remove its dependency on the Ruby VM and expose a new C API. In addition to being faster and more memory-efficient, it's now more portable: tools like Prism, Sorbet, JRuby and TruffleRuby will be able to use RBS directly. Type checkers like Steep and Sorbet will now be able to parse multiple RBS files in parallel, unconstrained by the GVL.\n\n    The Ruby VM offers many luxuries that can help ease C extension development, such as garbage collection, exceptions, and the many built-in data structures like `Array` and `Hash`. Unfortunately, to be maximally portable and multi-threaded, some C extensions like RBS and Prism will need to forego these conveniences. We'll show techniques for replicating them in pure C.\n\n    Join us to explore advanced techniques in writing C extensions and see how this universal RBS parser paves the way for improved tooling and collaboration in the Ruby ecosystem.\n\n    https://rubykaigi.org/2025/presentations/amomchilov.html\n  slides_url: \"https://momchilov.ca/resources/RubyKaigi2025/RBS-talk-slides.pdf\"\n\n- title: \"The Implementations of Advanced LR Parser Algorithm\"\n  raw_title: \"[JA] The Implementations of Advanced LR Parser Algorithm / Junichi Kobayashi @junk0612\"\n  speakers:\n    - Junichi Kobayashi\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"nxBUG0F8_oc\"\n  id: \"junichi-kobayashi-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Pearls Room #rubykaigiC\"\n  description: |-\n    I have been working on a better implementation of the LR algorithm to improve parse.y using Lrama. In Lrama 0.7, which is designed for CRuby 3.5, the parser can now be generated using IELR, an algorithm that is one step further from LALR, with a wider range of languages that can be parsed than LALR. In this presentation, I will discuss the detailed theory of IELR and its implementation in Lrama.\n\n    https://rubykaigi.org/2025/presentations/junk0612.html\n  slides_url: \"https://speakerdeck.com/junk0612/the-implementations-of-advanced-lr-parser-algorithm\"\n\n- title: \"Lightning Talks\"\n  raw_title: \"[EN/JA] Lightning Talks\"\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-17\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"9vPTXGzBjKI\"\n  id: \"lightning-talks-rubykaigi-2025\"\n  language: \"japanese\"\n  track: \"Main Hall #rubykaigiA\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talks Intro\"\n      start_cue: \"00:00\"\n      end_cue: \"03:05\"\n      thumbnail_cue: \"00:02\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"lightning-talks-intro-rubykaigi-2025\"\n      id: \"lightning-talks-intro-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - TODO\n      description: \"\"\n\n    - title: \"Lightning Talk: PicoRabbit: a Tiny Presentation Device Powered by Ruby\"\n      start_cue: \"03:13\"\n      end_cue: \"08:20\"\n      thumbnail_cue: \"03:44\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"shunsuke-michii-rubykaigi-2025\"\n      id: \"shunsuke-michii-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - Shunsuke Michii\n      description: |\n        This talk introduces PicoRabbit, a presentation system built from scratch on a Raspberry Pi Pico 2. This talk itself is running on PicoRabbit.\n\n        PicoRabbit is inspired by Rabbit, a slide tool for Rubyists. It aims to deliver real-time video output, USB-rewriteable content, and a slide engine implemented in mruby, all on a tiny $5 board.\n\n        Through the implementation of PicoRabbit, I will show that developing with mruby on Raspberry Pi Pico has potential beyond just keyboards. By using Ruby to control real-time video output, I hope to show how it can expand our creativity with Ruby.\n\n    - title: \"Lightning Talk: Road to RubyKaigi: Making Tinny Chiptunes with Ruby\"\n      start_cue: \"08:26\"\n      end_cue: \"13:35\"\n      thumbnail_cue: \"08:31\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"makicamel-rubykaigi-2025\"\n      id: \"makicamel-rubykaigi-2025\"\n      language: \"japanese\"\n      slides_url: \"https://speakerdeck.com/makicamel/road-to-rubykaigi-making-tinny-chiptunes-with-ruby\"\n      speakers:\n        - makicamel\n      description: |\n        \"Road to RubyKaigi\" is an action game made in Ruby that you can play right in your terminal. We defeat bugs, dodge deadlines, and race toward the RubyKaigi venue. All the graphics are rendered with text, and the background music is performed on the fly using Ruby. In this talk, I will talk how to implement the BGM performance and present a live demo of the game in action.\n\n    - title: \"Lightning Talk: Ruby as a Frontend for Programming Language Implementations\"\n      start_cue: \"13:39\"\n      end_cue: \"18:43\"\n      thumbnail_cue: \"13:44\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"white-green-rubykaigi-2025\"\n      id: \"white-green-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - White-Green\n      description: |\n        When developing a new programming language, it is typically necessary to implement both a frontend (such as a parser) and a backend (such as a virtual machine). However, especially during the prototyping stage, if the primary novelty of the language lies in its backend, it is desirable to simplify frontend implementation as much as possible. This presentation introduces an approach that leverages Ruby's powerful metaprogramming capabilities to construct language frontends with minimal effort. Specifically, we discuss an intuitive method of generating intermediate representations (such as SSA forms) directly from Ruby scripts written in a natural syntax.\n\n    - title: \"Lightning Talk: Ruby on Railroad: The Power of Visualizing CFG\"\n      start_cue: \"18:50\"\n      end_cue: \"24:00\"\n      thumbnail_cue: \"18:52\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"yudai-takada-lightning-talk-rubykaigi-2025\"\n      id: \"yudai-takada-lightning-talk-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - Yudai Takada\n      description: |\n        A world has arrived where Ruby's grammar can be visualized graphically, allowing you to grasp the overall picture of its complex syntax rules at a glance. This has been made possible through the collaboration of railroad_diagrams and Lrama. So, Ruby on Railroad is here.\n\n    - title: \"Lightning Talk: Ruby on a PlayStation\"\n      start_cue: \"24:01\"\n      end_cue: \"27:59\"\n      thumbnail_cue: \"24:13\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"chris-hasinski-rubykaigi-2025\"\n      id: \"chris-hasinski-rubykaigi-2025\"\n      language: \"english\"\n      speakers:\n        - Chris Hasiński\n      description: |\n        My very incomplete yet working port of mruby/c for PlayStation 1!\n\n        A short story about setting up a development environment for a 30 year old video game console and getting it to run some .mrb files.\n\n    - title: \"Lightning Talk: Debugging DDR for Encrypted DNS with Ruby\"\n      start_cue: \"28:04\"\n      end_cue: \"33:10\"\n      thumbnail_cue: \"28:07\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"taketo-takashima-rubykaigi-2025\"\n      id: \"taketo-takashima-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - Taketo Takashima\n      description: |\n        As concerns about privacy and security in DNS resolution grow, encrypted protocols such as DoH (DNS over HTTPS) have emerged. In this talk, I will introduce a Ruby implementation of a DDR (Discovery of Designated Resolvers) client, which enables the distribution of information about secure and encrypted DNS resolvers like DoH. While DDR allows multiple DNS resolvers to be advertised, verifying whether each resolver is functioning correctly can be challenging. To address this, I developed a debugging tool as a Ruby gem to confirm whether DDR is operating as expected.\n\n        Additionally, this talk will cover how this gem was used to troubleshoot issues encountered when deploying DDR in the DNS service provided for exhibitors and visitors at Interop Tokyo 2024's ShowNet.\n\n    - title: \"Lightning Talk: riscv64.rubyci.org internal\"\n      start_cue: \"33:15\"\n      end_cue: \"38:23\"\n      thumbnail_cue: \"33:18\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"kazuhiro-nishiyama-rubykaigi-2025\"\n      id: \"kazuhiro-nishiyama-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - Kazuhiro NISHIYAMA\n      description: |\n        I set up the current riscv64.rubyci.org. It runs chkbuild on a RISC-V virtual machine using qemu. It's difficult to find maintenance windows between CI runs in a slow environment, so I'll talk about the way I solved that problem.\n\n    - title: \"Lightning Talk: Fiber Scheduler vs. General-Purpose Parallel Client\"\n      start_cue: \"38:30\"\n      end_cue: \"43:33\"\n      thumbnail_cue: \"38:35\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"hayao-kimura-rubykaigi-2025\"\n      id: \"hayao-kimura-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - Hayao Kimura\n      description: |\n        In an effort to build a general-purpose parallel request client in Ruby—something anyone in our team could easily use—I ran into an unexpected roadblock: the limitations of the Fiber Scheduler. This talk walks through the journey from parallelizing Faraday requests, to exploring Fiber Scheduler as a lightweight alternative to threads, and ultimately hitting a wall when trying to support gRPC and AWS SDK. I'll explain why Fiber Scheduler couldn't handle gRPC due to its C-level implementation, and how that led to a shift toward using threads instead. If you're curious about the real-world limitations of Ruby's Fiber Scheduler and what it takes to design a truly flexible parallel request client, this talk is for you.\n\n    - title: \"Lightning Talk: Displaying 'アパート' correctly on Textbringer\"\n      start_cue: \"43:37\"\n      end_cue: \"48:45\"\n      thumbnail_cue: \"43:42\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"shugo-maeda-rubykaigi-2025\"\n      id: \"shugo-maeda-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - Shugo Maeda\n      description: |\n        Displaying \"アパート\" on a text editor seems simple, right? But is it really? This presentation will explain how to handle combining diacritical marks, variation selectors, hangul jamo etc. on a text editor.\n\n    - title: \"Lightning Talk: Making a MIDI controller device with PicoRuby/R2P2\"\n      start_cue: \"48:52\"\n      end_cue: \"54:00\"\n      thumbnail_cue: \"48:57\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"ryo-ishigaki-rubykaigi-2025\"\n      id: \"ryo-ishigaki-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - Ryo Ishigaki\n      description: |\n        There are many wonderful synthesizers and electronic instruments in the world. And instruments and devices that support MIDI (Musical Instrument Digital Interface) can easily be played together.\n\n        I am making a simple MIDI controller device PRMC-1 for use in electronic music performances using PicoRuby/R2P2 (Ruby Rapid Portable Platform). I can adjust the synthesizer parameters by turning the knobs, or play chords as arpeggios with the sequencer function. The hardware is made with Raspberry Pi Pico, M5Stack Unit 8Angle and Unit MIDI, and no soldering.\n\n        All code is written in Ruby! Would you like to create your own musical device using Ruby?\n\n    - title: \"Lightning Talk: Securing Credentials for Package Manager and Bundler\"\n      start_cue: \"54:02\"\n      end_cue: \"58:40\"\n      thumbnail_cue: \"54:07\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"taiga-asano-rubykaigi-2025\"\n      id: \"taiga-asano-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - Taiga ASANO\n      description: |\n        When using private gems, tokens are passed to Bundler via environment variables or config.\n\n        Bundler would benefit from adopting credential helpers to reduce friction in automated environments and address security challenges, particularly when managing short-lived tokens. In this lightning talk, we'll explore how other package managers solved these challenges and present a practical proposal for bringing credential helpers to Bundler.\n\n    - title: \"Lightning Talks Outro\"\n      start_cue: \"58:41\"\n      end_cue: \"59:39\"\n      thumbnail_cue: \"58:46\"\n      date: \"2025-04-17\"\n      published_at: \"2025-05-27\"\n      video_provider: \"parent\"\n      video_id: \"lightning-talks-outro-rubykaigi-2025\"\n      id: \"lightning-talks-outro-rubykaigi-2025\"\n      language: \"japanese\"\n      speakers:\n        - TODO\n      description: \"\"\n\n## Day 3\n\n- title: \"Ruby Committers and the World\"\n  raw_title: \"[EN/JA] Ruby Committers and the World / CRuby Committers @rubylangorg\"\n  speakers:\n    - Ruby Committers\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"oluYFmZSTwk\"\n  id: \"ruby-committers-and-the-world-rubykaigi-2025\"\n  track: \"Main Hall #rubykaigiA\"\n  language: \"english\"\n  description: \"\"\n  slides_url: \"\"\n\n- title: \"API for docs\"\n  raw_title: \"[EN] API for docs / Soutaro Matsumoto @soutaro\"\n  speakers:\n    - Soutaro Matsumoto\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"UPqyIDscX7k\"\n  id: \"soutaro-matsumoto-rubykaigi-2025\"\n  track: \"Main Hall #rubykaigiA\"\n  language: \"english\"\n  description: |-\n    Steep provides documentation features integrated with editors. You can read Ruby code with documentations of classes and methods, which hovers near the cursor. You can write Ruby code with completion suggestions with documentation, helping you select the best option from the list.\n\n    The feature can be seen as a variant of traditional documentation tools, like RDoc and YARD. However, it is essentially different from other tools: instead of generating human-readable files, it provides an API. The API provides a data structure that allows retrieving the documentation associated with each component of Ruby programs.\n\n    In this talk, I will outline the implementation, discuss the requirements, and share design considerations behind the feature.\n\n    https://rubykaigi.org/2025/presentations/soutaro.html\n  slides_url: \"https://speakerdeck.com/soutaro/api-for-doc\"\n\n- title: \"Improving my own Ruby\"\n  raw_title: \"[EN] Improving my own Ruby / monochrome @s_isshiki1969\"\n  speakers:\n    - monochrome\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"RG82gY2bXMs\"\n  id: \"monochrome-rubykaigi-2025\"\n  track: \"Sub Hall #rubykaigiB\"\n  language: \"english\"\n  description: |-\n    monoruby is a new Ruby implementation I am working on, written in Rust, built from scratch, and consisting of a parser, interpreter, garbage collector, and just-in-time (JIT) compiler. Since the last RubyKaigi, I have made progress in Rubygems support and other performance improvements. This time I want to present the details of the optimizations and the various features for performance tuning. Meaningful optimization requires measurement and evaluation, so I have implemented features to record where and why various events such as JIT compilation, JIT code invalidation, and deoptimization (back to the interpreter) occurred, and to display the generated assembly for each virtual machine instruction. The actual optimizations implemented in monoruby include machine code inlining, method inlining, polymorphic method call optimization, faster instance variable access, faster array access, etc. Making the Ruby compiler is fun.\n\n    https://rubykaigi.org/2025/presentations/s_isshiki1969.html\n  slides_url: \"https://speakerdeck.com/sisshiki1969/improve-my-own-ruby\"\n\n- title: \"Running ruby.wasm on Pure Ruby Wasm Runtime\"\n  raw_title: \"[EN] Running ruby.wasm on Pure Ruby Wasm Runtime / Uchio KONDO @udzura\"\n  speakers:\n    - Uchio KONDO\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"OuFm7F4ocNw\"\n  id: \"uchio-kondo-rubykaigi-2025\"\n  track: \"Pearls Room #rubykaigiC\"\n  language: \"english\"\n  description: |-\n    The speaker has developed a WebAssembly(wasm) runtime named Wardite, which is implemented entirely in pure Ruby. Wardite implements core wasm specifications and instructions, enabling the successful execution of ruby.wasm with basic Ruby functionalities. This talk will explore the technical challenges of implementing a wasm runtime in pure Ruby and problems encountered during development. Key topics include the implementation of WASI preview 1 support, performance enhancements using ruby-prof and perf, and core wasm specification compliance testing. The talk will provide a comprehensive overview of the progress made so far and the future directions for Wardite, highlighting its potential impact on the Ruby and WebAssembly ecosystems. Attendees will gain insights into the current status of Wardite, its architecture, and the approaches taken to efficiently implement WebAssembly runtime in Ruby.\n\n    https://rubykaigi.org/2025/presentations/udzura.html\n  slides_url: \"https://udzura.jp/slides/2025/rubykaigi/\"\n\n- title: \"Eliminating Unnecessary Implicit Allocations\"\n  raw_title: \"[EN] Eliminating Unnecessary Implicit Allocations / Jeremy Evans @jeremyevans0\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"7Gmk8bH6UPE\"\n  id: \"jeremy-evans-rubykaigi-2025\"\n  track: \"Main Hall #rubykaigiA\"\n  language: \"english\"\n  description: |-\n    This is a followup to my RubyKaigi 2024 presentation, \"Reducing Implicit Allocations During Method Calling\", discussing an entirely new set of allocation reduction optimizations included in Ruby 3.4. This presentation will describe allocation regressions that occurred while developing these optimizations, and the allocation test suite added to prevent future regressions. It will also discuss other bugs that were found as a result of this optimization work, and how they were fixed. Finally, it will discuss the implicit allocations that remain, and why they would be challenging to address.\n\n    https://rubykaigi.org/2025/presentations/jeremyevans0.html\n  slides_url: \"https://code.jeremyevans.net/presentations/rubykaigi2025/index.html\"\n\n- title: \"A taxonomy of Ruby calls\"\n  raw_title: \"[EN] A taxonomy of Ruby calls / Alan Wu @alanwusx\"\n  speakers:\n    - Alan Wu\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"8hvByM48kMs\"\n  id: \"alan-wu-rubykaigi-2025\"\n  track: \"Sub Hall #rubykaigiB\"\n  language: \"english\"\n  description: |-\n    Calls are an essential feature of Ruby and there are an eye dazzling number of options available for declaring and calling methods and blocks. In this talk, I will explore interesting interactions between call related features and put forward a classification of them based on my experience with their implementation in the CRuby interpreter and YJIT.\n\n    https://rubykaigi.org/2025/presentations/alanwusx.html\n  slides_url: \"https://github.com/XrXr/slides/blob/main/RubyKaigi2025/A%20taxonomy%20of%20ruby%20calls.key.pdf\"\n\n- title: \"The Ruby One-Binary Tool, Enhanced with Kompo\"\n  raw_title: \"[JA] The Ruby One-Binary Tool, Enhanced with Kompo / ahogappa @ahogappa\"\n  speakers:\n    - ahogappa\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"O5IpYW_yISE\"\n  id: \"ahogappa-rubykaigi-2025\"\n  track: \"Pearls Room #rubykaigiC\"\n  language: \"japanese\"\n  description: |-\n    I want to introduce a Ruby one-binary conversion tool. I am developing a gem called Kompo. Kompo was developed to make one-binary Ruby game engines, which I can develop in Ruby as a hobby. Kompo is based on the concept of \"easy to run anywhere reasonably fast.\" Now, a simple program with Sinatra + SQLite can be made one binary. However, Kompo cannot include anything besides Ruby scripts in the binary because it achieves one binary by overriding `require,` which is sufficient. If you want to make a Ruby on Rails app one-binary, you need to include YAML, etc., in the binary and also be able to read it via `IO.read`, etc. So, I have provided Kompo with a means for users to access binary data freely. This allows you to read the YAML files in the binary using `IO.read`, etc. In this session, I will describe the details of this implementation and demonstrate how Ruby can be run as one binary.\n\n    https://rubykaigi.org/2025/presentations/ahogappa.html\n  slides_url: \"https://speakerdeck.com/ahogappa/the-ruby-one-binary-tool-enhanced-with-kompo\"\n\n- title: \"Toward Ractor local GC\"\n  raw_title: \"[EN] Toward Ractor local GC / Koichi Sasada @ko1\"\n  speakers:\n    - Koichi Sasada\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"3KR1udGT7co\"\n  id: \"koichi-sasada-rubykaigi-2025\"\n  track: \"Main Hall #rubykaigiA\"\n  language: \"english\"\n  description: |-\n    Garbage collection (GC) is a big challenge in multi-Ractor systems. In the current implementation, all Ractors share a global heap, and GC requires stopping all Ractors to perform GC. This approach negatively impacts object allocation and GC performance.\n\n    Ideally, GC should be executed in parallel for each Ractor's local heap. However, shareable objects make it difficult to track references and implement fully parallel GC.\n\n    To address this, we propose Ractor-local GC, which focuses on collecting non-shareable, Ractor-local objects in parallel, while continuing to perform global GC for shareable objects by pausing all Ractors, as in the current system. This hybrid approach allows most GC operations to run in parallel, improving overall performance. Furthermore, since shareable objects are expected to be relatively few compared to non-shareable objects, the frequency of global GC should remain low.\n\n    This talk will present the design of Ractor-local GC and the progress of its implementation.\n\n    https://rubykaigi.org/2025/presentations/ko1.html\n  slides_url: \"https://atdot.net/~ko1/activities/2025_rubykaigi2025.pdf\"\n\n- title: \"Inline RBS comments for seamless type checking with Sorbet\"\n  raw_title: \"[EN] Inline RBS comments for seamless type checking with Sorbet / Alexandre Terrasa @Morriar\"\n  speakers:\n    - Alexandre Terrasa\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"l4YjoEgpmXs\"\n  id: \"alexandre-terrasa-rubykaigi-2025\"\n  track: \"Sub Hall #rubykaigiB\"\n  language: \"english\"\n  description: |-\n    In this talk, we'll explore how integrating the RBS parser into Sorbet allows us to include type information as comments directly into our Ruby code. This integration enables fast type checking with an appealing syntax while enhancing type safety and code navigation for large-scale projects.\n\n    We'll discuss the improvements we made to the `ruby/rbs` parser, which can now function without the need for the RubyVM. This enhancement not only makes it compatible with Sorbet but also opens the door for use from other C/C++/Rust tools.\n\n    We'll also showcase our tool to automatically convert Sorbet RBI signatures into RBS comments, addressing some of the differences and challenges between the two syntaxes.\n\n    Join us to discover how Sorbet and RBS can work together to elevate your Ruby development experience.\n\n    https://rubykaigi.org/2025/presentations/Morriar.html\n  slides_url: \"https://drive.google.com/file/d/1PWCyZycvgCWlZd57daUm5FAFYb_117hV/view\"\n\n- title: \"Road to Go gem\"\n  raw_title: \"[JA] Road to Go gem / Go Sueyoshi @sue445\"\n  speakers:\n    - Go Sueyoshi\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"BefVCoM35XY\"\n  id: \"go-sueyoshi-rubykaigi-2025\"\n  track: \"Pearls Room #rubykaigiC\"\n  language: \"japanese\"\n  description: |-\n    Go talks about Ruby native extension gem with Go (a.k.a. Go gem).\n\n    I created https://github.com/ruby-go-gem/go-gem-wrapper for Go gem. This is a library to make it easier to create Go gem (contains both Go module and Ruby gem).\n\n    I will talk the following regarding go-gem-wrapper and Go gem:\n    * Auto-generate (almost) all of Go's bindings from `ruby.h` (about 1,100 functions)\n    * Parse CRuby's `ruby.h` with Ruby\n    * C lang's pointer difficulties from `ruby.h` parser's point of view\n    * Run `go test` with CRuby\n    * Pros/Cons of Go gem\n    * My bundler's patch for Go gem\n\n    https://rubykaigi.org/2025/presentations/sue445.html\n  slides_url: \"https://speakerdeck.com/sue445/road-to-go-gem-number-rubykaigi\"\n  additional_resources:\n    - name: \"ruby-go-gem/go-gem-wrapper\"\n      type: \"repo\"\n      url: \"https://github.com/ruby-go-gem/go-gem-wrapper\"\n\n- title: \"Analyzing Ruby Code in IRB\"\n  raw_title: \"[JA] Analyzing Ruby Code in IRB / Tomoya Ishida @tompng\"\n  speakers:\n    - Tomoya Ishida\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"Ql15TZ3_538\"\n  id: \"tomoya-ishida-rubykaigi-2025\"\n  track: \"Main Hall #rubykaigiA\"\n  language: \"japanese\"\n  description: |-\n    IRB analyzes the input code for many purposes: syntax highlighting, detecting termination of multiline input, auto-indent and completion. Some of them uses token-base, some uses syntax-tree based analysis. Let's explore why, how and what's interesting especially when IRB receives weird input code. In this talk, I will also show the strategy of making IRB more weird-code tolerant by migrating these analysis to use Prism.\n\n    https://rubykaigi.org/2025/presentations/tompng.html\n  slides_url: \"https://drive.google.com/file/d/1BMGGH-V-8Wj2m9VoJVcAAXbg3jn9azG4/view\"\n\n- title: \"Optimizing JRuby 10\"\n  raw_title: \"[EN] Optimizing JRuby 10 / Charles Nutter @headius\"\n  speakers:\n    - Charles Nutter\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"83RqLa6858Y\"\n  id: \"charles-nutter-rubykaigi-2025\"\n  track: \"Sub Hall #rubykaigiB\"\n  language: \"english\"\n  description: |-\n    JRuby 10 is out now with Ruby 3.4 and Rails 8 compatibility! After years of catching up on features, we've finally been able to spend time on long-delayed optimizations. This talk will show some of the best examples, including real-world application performance, and teach you how to find and fix performance problems in your JRuby applications.\n\n    https://rubykaigi.org/2025/presentations/headius\n  slides_url: \"https://speakerdeck.com/headius/optimizing-jruby-10\"\n\n- title: \"Porting PicoRuby to Another Microcontroller: ESP32\"\n  raw_title: \"[JA] Porting PicoRuby to Another Microcontroller: ESP32 / Yuhei Okazaki @Y_uuu\"\n  speakers:\n    - Yuhei Okazaki\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"USGYCDzh0Rc\"\n  id: \"yuhei-okazaki-rubykaigi-2025\"\n  track: \"Pearls Room #rubykaigiC\"\n  language: \"japanese\"\n  description: |-\n    PicoRuby is a very small implementation of Ruby designed to run on microcontrollers. It is an outstanding open-source project that has already been proven to work on well-known microcontroller boards such as the Raspberry Pi Pico. Moreover, it is thoughtfully designed to facilitate operation on other microcontrollers.\n\n    In my project, I worked on porting PicoRuby to the ESP32, a low-cost and low-power microcontroller module developed by Espressif Systems. The ESP32 supports wireless communication such as Wi-Fi and Bluetooth, making it an excellent match for developing IoT (Internet of Things) systems.\n\n    The process of adapting PicoRuby to different microcontrollers involved continuous hypothesis testing. It required writing build configurations tailored to the specific microcontroller and developing dedicated C source code for it.\n\n    In this presentation, I will introduce the approaches I took and invite you into the deep and fascinating world of embedded systems.\n\n    https://rubykaigi.org/2025/presentations/Y_uuu.html\n  slides_url: \"https://speakerdeck.com/yuuu/porting-picoruby-to-another-microcontroller-esp32\"\n\n- title: \"Modular Garbage Collectors in Ruby\"\n  raw_title: \"[EN] Modular Garbage Collectors in Ruby / Peter Zhu @peterzhu2118\"\n  speakers:\n    - Peter Zhu\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"04axm4JcaT4\"\n  id: \"peter-zhu-rubykaigi-2025\"\n  track: \"Main Hall #rubykaigiA\"\n  language: \"english\"\n  description: |-\n    Introduced in Feature #20470, Ruby 3.4 ships with an experimental API for implementing garbage collectors.\n\n    In addition to the built-in garbage collector, Ruby 3.4 also ships with an experimental garbage collector implemented using the Memory Management Toolkit (MMTk) framework. MMTk provides a wide variety of advanced garbage collector implementations such as Immix and LXR.\n\n    In this talk, we will introduce the Modular GC API, look at how MMTk is implemented using this API, discuss our current progress and future roadmap, and how you can implement your own garbage collector using this API.\n\n    https://rubykaigi.org/2025/presentations/peterzhu2118.html\n  slides_url: \"https://blog.peterzhu.ca/assets/rubykaigi_2025_slides.pdf\"\n\n- title: \"The Challenges of Building sigstore-ruby\"\n  raw_title: \"[EN] The Challenges of Building sigstore-ruby / Samuel Giddins @segiddins\"\n  speakers:\n    - Samuel Giddins\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"VLbTL_UdCFw\"\n  id: \"samuel-giddins-rubykaigi-2025\"\n  track: \"Sub Hall #rubykaigiB\"\n  language: \"english\"\n  description: |-\n    Sigstore Ruby now exists. So exciting! But bringing it to life was a challenge, particularly due to the goal of being able to ship it as a part of Ruby itself. Building a sigstore implementation atop only the standard library required writing a TUF client, implementing custom x509 handling, and abstracting over all the supported key types, among other challenges. This talk will explore those challenges, and dive into _why_ a sigstore implementation proves to be such an undertaking, hopefully inspiring some simplification for the next poor soul who attempts to build one from scratch.\n\n    https://rubykaigi.org/2025/presentations/segiddins.html\n  slides_url: \"\"\n\n- title: \"On-the-fly Suggestions of Rewriting Method Deprecations\"\n  raw_title: \"[JA] On-the-fly Suggestions of Rewriting Method Deprecations / Masato Ohba @ohbarye\"\n  speakers:\n    - Masato Ohba\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"OTVOObCRlZg\"\n  id: \"masato-ohba-rubykaigi-2025\"\n  track: \"Pearls Room #rubykaigiC\"\n  language: \"japanese\"\n  description: |-\n    This talk is for both library authors and their users - showing how to make method deprecations more manageable through automated code analysis and transformation suggestions. While Ruby's ecosystem has various ways to handle method deprecations, the process of updating deprecated code often remains manual and time-consuming.\n\n    What if the world were like this? Library authors would only need to define conversion rules for deprecated methods. Client developers would get patches that they could apply immediately to resolve deprecations by simply running their existing programs. In this talk, I will show how my own tool, Deprewriter, makes this possible. I'll introduce how to analyze deprecated method calls at runtime and suggest code transformations with Ruby's metaprogramming capabilities.\n\n    Through this presentation, I'll explore how Ruby's flexibility can be leveraged to create tools that make deprecation handling more systematic and developer-friendly.\n\n    https://rubykaigi.org/2025/presentations/ohbarye.html\n  slides_url: \"https://speakerdeck.com/ohbarye/on-the-fly-suggestions-of-rewriting-method-deprecations\"\n\n- title: \"Keynote: Programming Language for AI age\"\n  raw_title: \"[JA][Keynote] Matz Keynote / Yukihiro 'Matz' Matsumoto @yukihiro_matz\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  event_name: \"RubyKaigi 2025\"\n  date: \"2025-04-18\"\n  published_at: \"2025-05-27\"\n  video_provider: \"youtube\"\n  video_id: \"oeuYishyqo8\"\n  id: \"yukihiro-matz-rubykaigi-2025\"\n  track: \"Main Hall #rubykaigiA\"\n  language: \"japanese\"\n  description: |-\n    Keynote by Yukihiro \"Matz\" Matsumoto, the creator of Ruby, at RubyKaigi 2025.\n\n    https://rubykaigi.org/2025/presentations/yukihiro_matz.html\n  slides_url: \"\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://cfp.rubykaigi.org/events/2026/\"\n  open_date: \"2025-12-15\"\n  close_date: \"2026-01-11\"\n- name: \"Call for Proposals Extension\"\n  link: \"https://cfp.rubykaigi.org/events/2026\"\n  open_date: \"2026-01-11\"\n  close_date: \"2026-01-18\"\n- name: \"Lightning Talks\"\n  link: \"https://cfp.rubykaigi.org/events/2026LT\"\n  open_date: \"2026-03-21\"\n  close_date: \"2026-04-05\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2026/event.yml",
    "content": "---\nid: \"rubykaigi-2026\"\ntitle: \"RubyKaigi 2026\"\ndescription: \"\"\nlocation: \"Hakodate, Hokkaido, Japan\"\nkind: \"conference\"\nstart_date: \"2026-04-22\"\nend_date: \"2026-04-24\"\nwebsite: \"https://rubykaigi.org/2026/\"\ntwitter: \"rubykaigi\"\nmastodon: \"https://ruby.social/@rubykaigi\"\ntickets_url: \"https://ti.to/rubykaigi/2026\"\nbanner_background: |-\n  linear-gradient(to bottom, #471712, #471712 50%, #471712 50%) left top / 50% 100% no-repeat, /* Left side */\n  linear-gradient(to bottom, #883D25, #883D25 50%, #883D25 50%) right top / 50% 100% no-repeat /* Right side */\nfeatured_background: \"#883D25\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 41.78201480210688\n  longitude: 140.7835670190506\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2026/involvements.yml",
    "content": "---\n- name: \"Chief Organizer\"\n  users:\n    - Akira Matsuda\n\n- name: \"Señor Organizer\"\n  users:\n    - Shintaro Kakutani\n\n- name: \"Organizer\"\n  users:\n    - Masayoshi Takahashi\n    - Sorah Fukumori\n    - Ippei Ogiwara\n    - Yusuke Matsumoto\n    - Chie Kobayashi\n    - Yuka Atsumi\n    - Natsuko Nadoyama\n    - Kodai Kinjo\n    - Shyouhei Urabe\n\n- name: \"NOC Lead\"\n  users:\n    - Sorah Fukumori\n\n- name: \"Local Organizer\"\n  users:\n    - Chris Salzberg\n    - Atsushi Katsuura\n    - Takuya Jumbo Nakamura\n    - Satoshi Azuma\n    - Shintaro Suzuki\n    - Takumi Iwasaki\n\n- name: \"Designer\"\n  users:\n    - Naoki Matsuda\n    - Emi Imanishi\n    - Atsuhiro Tsuji\n    - Naotaka Harada\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2026/schedule.yml",
    "content": "---\n# https://rubykaigi.org/2026/schedule/\ndays:\n  - name: \"Day 1\"\n    date: \"2026-04-22\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:30\"\n        slots: 1\n        items:\n          - Door Open\n\n      - start_time: \"09:30\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:50\"\n        end_time: \"11:20\"\n        slots: 3\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 3\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 3\n\n      - start_time: \"14:10\"\n        end_time: \"14:40\"\n        slots: 3\n\n      - start_time: \"14:50\"\n        end_time: \"15:20\"\n        slots: 3\n\n      - start_time: \"15:20\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Afternoon Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 3\n\n      - start_time: \"16:40\"\n        end_time: \"17:10\"\n        slots: 3\n\n      - start_time: \"17:20\"\n        end_time: \"18:20\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n  - name: \"Day 2\"\n    date: \"2026-04-23\"\n    grid:\n      - start_time: \"09:30\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:50\"\n        end_time: \"11:20\"\n        slots: 3\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 3\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 3\n\n      - start_time: \"14:10\"\n        end_time: \"14:40\"\n        slots: 3\n\n      - start_time: \"14:50\"\n        end_time: \"15:20\"\n        slots: 3\n\n      - start_time: \"15:20\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Afternoon Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 3\n\n      - start_time: \"16:40\"\n        end_time: \"17:10\"\n        slots: 3\n\n      - start_time: \"17:20\"\n        end_time: \"17:50\"\n        slots: 3\n\n  - name: \"Day 3\"\n    date: \"2026-04-24\"\n    grid:\n      - start_time: \"09:20\"\n        end_time: \"10:30\"\n        slots: 1\n\n      - start_time: \"10:50\"\n        end_time: \"11:20\"\n        slots: 3\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 3\n\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch Break\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 3\n\n      - start_time: \"14:10\"\n        end_time: \"14:40\"\n        slots: 3\n\n      - start_time: \"14:50\"\n        end_time: \"15:20\"\n        slots: 3\n\n      - start_time: \"15:20\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Afternoon Break\n\n      - start_time: \"16:00\"\n        end_time: \"16:30\"\n        slots: 3\n\n      - start_time: \"16:40\"\n        end_time: \"17:40\"\n        slots: 1\n\ntracks:\n  - name: \"Large Hall #rubykaigiA\"\n    color: \"#883D25\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Sub Arena #rubykaigiB\"\n    color: \"#471712\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"Small Hall #rubykaigiC\"\n    color: \"#E33030\"\n    text_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2026/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsors\"\n      level: 1\n      sponsors:\n        - name: \"Medley, Inc.\"\n          slug: \"medley-inc\"\n          website: \"https://www.medley.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/898-57936efc.png\"\n        - name: \"ITANDI, Inc.\"\n          slug: \"itandi-inc\"\n          website: \"https://corp.itandi.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/907-2ee14b11.png\"\n        - name: \"KOMOJU Co., Ltd.\"\n          slug: \"komoju-co-ltd\"\n          website: \"https://komoju.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/923-7a1454f9.png\"\n        - name: \"Gaji-Labo Inc.\"\n          slug: \"gaji-labo-inc\"\n          badge: \"Design Sponsor\"\n          website: \"https://www.gaji.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/899-36144df9.png\"\n        - name: \"hacomono Inc.\"\n          slug: \"hacomono-inc\"\n          badge: \"Wellness Sponsor\"\n          website: \"https://www.hacomono.co.jp/recruit/engineer/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/905-54eb13b2.png\"\n        - name: \"IVRy Inc.\"\n          slug: \"ivry-inc\"\n          badge: \"Climbing and Wi-Fi Sponsor\"\n          website: \"https://ivry.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/915-04203bac.png\"\n        - name: \"mov inc.\"\n          slug: \"mov-inc\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://mov.am/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/922-64f6c7d9.png\"\n        - name: \"GMO Internet Group\"\n          slug: \"gmo-internet-group\"\n          badge: \"Ferry Sponsor\"\n          website: \"https://group.gmo/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/925-d95bd001.png\"\n        - name: \"ANDPAD Inc.\"\n          slug: \"andpad-inc\"\n          badge: \"Drinks and Local Meals Sponsor\"\n          website: \"https://engineer.andpad.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/929-37b271f6.png\"\n        - name: \"Shopify Engineering\"\n          slug: \"shopify\"\n          badge: \"Ruby Committers' Sponsor\"\n          website: \"https://www.shopify.com\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/943-2a628fe3.png\"\n\n    - name: \"Platinum Sponsors\"\n      level: 2\n      sponsors:\n        - name: \"SmartHR, Inc.\"\n          slug: \"smarthr-inc\"\n          badge: \"Hangout Sponsor\"\n          website: \"https://smarthr.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/900-20e74a3f.png\"\n        - name: \"STORES, Inc.\"\n          slug: \"stores-inc\"\n          badge: \"Nursery and Scholarship Sponsor\"\n          website: \"https://jobs.st.inc/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/902-3300a470.png\"\n        - name: \"Leaner Technologies Inc.\"\n          slug: \"leaner-technologies-inc\"\n          badge: \"Board Game Night Sponsor\"\n          website: \"https://leaner.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/908-603bdfd8.png\"\n        - name: \"SmartBank, Inc.\"\n          slug: \"smartbank-inc\"\n          badge: \"Hack Space Sponsor\"\n          website: \"https://smartbank.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/909-3e224e2c.png\"\n        - name: \"pixiv Inc.\"\n          slug: \"pixiv-inc\"\n          badge: \"Music Event and Scholarship Sponsor\"\n          website: \"https://www.pixiv.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/913-eea91e62.png\"\n        - name: \"ESM, Inc.\"\n          slug: \"esm-inc\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://agile.esm.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/888-07371bdd.png\"\n        - name: \"Findy Inc.\"\n          slug: \"findy-inc\"\n          website: \"https://findy.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/903-0e18ae1f.png\"\n        - name: \"Studist\"\n          slug: \"studist\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://studist.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/924-7ca27e22.png\"\n        - name: \"Net Protections, Inc.\"\n          slug: \"net-protections-inc\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://corp.netprotections.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/928-567161fd.png\"\n        - name: \"OPTiM Corporation\"\n          slug: \"optim-corporation\"\n          website: \"https://www.optim.co.jp\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/944-97be4877.png\"\n        - name: \"Link and Motivation Inc.\"\n          slug: \"link-and-motivation-inc\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://www.lmi.ne.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/946-dffecc87.png\"\n        - name: \"giftee Inc.\"\n          slug: \"giftee-inc\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://en.giftee.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/949-d6292988.png\"\n        - name: \"mybest,Inc.\"\n          slug: \"mybestinc\"\n          website: \"https://my-best.com/company/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/892-194b71cb.png\"\n        - name: \"Sentry\"\n          slug: \"sentry\"\n          website: \"https://sentry.io\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/893-7abc488a.png\"\n        - name: \"DELTA Co., Ltd.\"\n          slug: \"delta-co-ltd\"\n          website: \"https://teamdelta.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/894-9ab8be83.png\"\n        - name: \"kickflow, Inc.\"\n          slug: \"kickflow-inc\"\n          website: \"https://careers.kickflow.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/897-8b28381f.png\"\n        - name: \"Linc'well Inc.\"\n          slug: \"lincwell-inc\"\n          website: \"https://linc-well.com\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/904-4dd3bb0f.png\"\n        - name: \"with.inc\"\n          slug: \"withinc\"\n          website: \"https://enito.co.jp/who-we-are/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/906-4b8d3297.png\"\n        - name: \"ZOZO, Inc.\"\n          slug: \"zozo-inc\"\n          website: \"https://corp.zozo.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/912-9be87472.png\"\n        - name: \"Cookpad Inc.\"\n          slug: \"cookpad-inc\"\n          website: \"https://cookpad.careers/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/919-291372f2.png\"\n        - name: \"Leafea, Inc.\"\n          slug: \"leafea-inc\"\n          website: \"https://leafea.co.jp\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/918-a48706bc.png\"\n        - name: \"GA technologies Co., Ltd.\"\n          slug: \"ga-technologies-co-ltd\"\n          website: \"https://www.ga-tech.co.jp/en/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/921-22594853.png\"\n        - name: \"Timee, Inc.\"\n          slug: \"timee-inc\"\n          website: \"https://corp.timee.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/927-cda21104.png\"\n        - name: \"TOKIUM Inc.\"\n          slug: \"tokium-inc\"\n          website: \"https://corp.tokium.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/931-d21c61f3.png\"\n        - name: \"Hubble Inc.\"\n          slug: \"hubble-inc\"\n          website: \"https://hubble-docs.com/about\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/932-3dc36aee.png\"\n        - name: \"note inc.\"\n          slug: \"note-inc\"\n          website: \"https://note.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/937-7c6a35dc.png\"\n        - name: \"WED, Inc.\"\n          slug: \"wed-inc\"\n          website: \"https://wed.company/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/938-21fcbff7.png\"\n        - name: \"JetBrains s.r.o.\"\n          slug: \"jetbrains-sro\"\n          website: \"https://www.jetbrains.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/940-3d5c9da6.png\"\n        - name: \"CrowdWorks, Inc.\"\n          slug: \"crowdworks-inc\"\n          website: \"https://crowdworks.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/942-7b55bc80.png\"\n        - name: \"PKSHA Technology Inc.\"\n          slug: \"pksha-technology-inc\"\n          website: \"https://www.pkshatech.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/947-385be674.png\"\n        - name: \"stmn,inc.\"\n          slug: \"stmninc\"\n          website: \"https://stmn.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/948-f3925f71.png\"\n\n    - name: \"Gold Sponsors\"\n      level: 3\n      sponsors:\n        - name: \"Coincheck, Inc.\"\n          slug: \"coincheck-inc\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://corporate.coincheck.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/891-1cc3f5de.png\"\n        - name: \"TenshokuDRAFT\"\n          slug: \"tenshokudraft\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://job-draft.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/952-4a7e6938.png\"\n        - name: \"Hello, Inc.\"\n          slug: \"hello-inc\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://www.hello.ai/en\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/956-b2ae4813.png\"\n        - name: \"Treasure Data\"\n          slug: \"treasure-data\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://www.treasuredata.com\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/963-8d0e9f9d.png\"\n        - name: \"freee K.K.\"\n          slug: \"freee-kk\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://www.freee.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/967-ee1bbc72.png\"\n        - name: \"GMO Pepabo, Inc.\"\n          slug: \"gmo-pepabo-inc\"\n          badge: \"Video Sponsor\"\n          website: \"https://pepabo.com\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/985-1fad2cb1.png\"\n        - name: \"Network Applied Communication Laboratory Ltd.\"\n          slug: \"network-applied-communication-laboratory-ltd\"\n          website: \"https://www.netlab.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/886-1e42e402.png\"\n        - name: \"TimeTree, Inc.\"\n          slug: \"timetree-inc\"\n          website: \"https://timetreeapp.com/intl\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/896-d29e7ee4.png\"\n        - name: \"ENECHANGE Ltd.\"\n          slug: \"enechange-ltd\"\n          website: \"https://enechange.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/911-88485c80.png\"\n        - name: \"DeNA Co., Ltd.\"\n          slug: \"dena-co-ltd\"\n          website: \"https://dena.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/916-4ac4d224.png\"\n        - name: \"Linkers Corporation\"\n          slug: \"linkers-corporation\"\n          website: \"https://corp.linkers.net/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/917-e927c3ae.png\"\n        - name: \"Studyplus, Inc.\"\n          slug: \"studyplus-inc\"\n          website: \"https://tech.studyplus.co.jp/recruit\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/926-95e2d983.png\"\n        - name: \"Karrot\"\n          slug: \"karrot\"\n          website: \"https://www.karrotmarket.com/jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/933-22f42cf4.png\"\n        - name: \"MNTSQ, Ltd.\"\n          slug: \"mntsq-ltd\"\n          website: \"https://www.mntsq.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/935-b5cf8655.png\"\n        - name: \"MedPeer, Inc.\"\n          slug: \"medpeer-inc\"\n          website: \"https://medpeer.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/945-99c1e1de.png\"\n        - name: \"SMS Co., Ltd.\"\n          slug: \"sms-co-ltd\"\n          website: \"https://careers.bm-sms.co.jp/engineer\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/950-107856fe.png\"\n        - name: \"AppBrew, Inc.\"\n          slug: \"appbrew-inc\"\n          website: \"https://appbrew.io/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/951-08d89095.png\"\n        - name: \"CodeCast inc.\"\n          slug: \"codecast-inc\"\n          website: \"https://codecast.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/955-891d5ba0.png\"\n        - name: \"Repro Inc.\"\n          slug: \"repro-inc\"\n          website: \"https://company.repro.io/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/959-9ac24230.png\"\n        - name: \"Money Forward, Inc.\"\n          slug: \"money-forward-inc\"\n          website: \"https://corp.moneyforward.com/en/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/960-e02ad55e.png\"\n        - name: \"foodnia.inc\"\n          slug: \"foodniainc\"\n          website: \"http://foodnia.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/962-f0c9d885.png\"\n        - name: \"Kurashiru, Inc.\"\n          slug: \"kurashiru-inc\"\n          website: \"https://kurashiru.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/968-1fa7e94d.png\"\n        - name: \"i Cubed Systems, Inc.\"\n          slug: \"i-cubed-systems-inc\"\n          website: \"https://www.icubedsystems.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/969-6fbe5bda.png\"\n        - name: \"MIXI, Inc.\"\n          slug: \"mixi-inc\"\n          website: \"https://mixi.co.jp/en/company/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/971-bbb183ef.png\"\n        - name: \"SocialPLUS Inc.\"\n          slug: \"socialplus-inc\"\n          website: \"https://www.socialplus.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/972-78f2826e.png\"\n        - name: \"SerpApi, LLC\"\n          slug: \"serpapi-llc\"\n          website: \"https://serpapi.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/976-3214f34d.png\"\n        - name: \"codeTakt Inc.\"\n          slug: \"codetakt-inc\"\n          website: \"https://codetakt.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/978-1257ac23.png\"\n        - name: \"PoppinsSitter Co., Ltd.\"\n          slug: \"poppinssitter-co-ltd\"\n          website: \"https://smartsitter.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/979-56b68ebd.png\"\n        - name: \"Headius Enterprises\"\n          slug: \"headius-enterprises\"\n          website: \"https://headius.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/981-10db2b68.png\"\n        - name: \"Photosynth Inc.\"\n          slug: \"photosynth-inc\"\n          website: \"https://photosynth.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/982-5560ff9a.png\"\n\n    - name: \"Silver Sponsors\"\n      level: 4\n      sponsors:\n        - name: \"TwoGate Inc.\"\n          slug: \"twogate-inc\"\n          badge: \"Drinkup Sponsor\"\n          website: \"https://twogate.com\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/961-48f73dd7.png\"\n        - name: \"TakeyuWeb Inc.\"\n          slug: \"takeyuweb-inc\"\n          website: \"https://takeyuweb.co.jp\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/885-f4dad51d.png\"\n        - name: \"FjordBootCamp\"\n          slug: \"fjordbootcamp\"\n          website: \"https://bootcamp.fjord.jp\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/887-ce5883d0.png\"\n        - name: \"ClearCode Inc.\"\n          slug: \"clearcode-inc\"\n          website: \"https://www.clear-code.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/889-5c30468b.png\"\n        - name: \"A's Child Inc.\"\n          slug: \"as-child-inc\"\n          website: \"https://www.as-child.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/890-6e85d4c3.png\"\n        - name: \"Hamee Corp.\"\n          slug: \"hamee-corp\"\n          website: \"https://hamee.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/910-7e69224c.png\"\n        - name: \"fejo.dk ApS\"\n          slug: \"fejodk-aps\"\n          website: \"https://www.fejo.dk\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/914-ac07715c.png\"\n        - name: \"iCARE Co.,Ltd.\"\n          slug: \"icare-coltd\"\n          website: \"https://www.icare-carely.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/920-4ecd8298.png\"\n        - name: \"Shunju LLC\"\n          slug: \"shunju-llc\"\n          website: \"https://www.shunju.io\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/934-8af4dc60.png\"\n        - name: \"Everyleaf Corporation\"\n          slug: \"everyleaf-corporation\"\n          website: \"https://everyleaf.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/936-706e3f6e.png\"\n        - name: \"FUNDINNO Inc.\"\n          slug: \"fundinno-inc\"\n          website: \"https://corp.fundinno.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/939-cfbec643.png\"\n        - name: \"PIXTA Inc.\"\n          slug: \"pixta-inc\"\n          website: \"https://pixta.co.jp/business\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/941-67303456.png\"\n        - name: \"Tsukulink Inc.\"\n          slug: \"tsukulink-inc\"\n          website: \"https://tsukulink.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/953-3d75848a.png\"\n        - name: \"Agileware Inc.\"\n          slug: \"agileware-inc\"\n          website: \"https://agileware.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/954-463c77a3.png\"\n        - name: \"stadium, inc.\"\n          slug: \"stadium-inc\"\n          website: \"https://stadium.fan/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/958-af981fdc.png\"\n        - name: \"B4A, Inc.\"\n          slug: \"b4a-inc\"\n          website: \"https://jobs.b4a.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/964-8af73fa0.png\"\n        - name: \"Ezowin Inc.\"\n          slug: \"ezowin-inc\"\n          website: \"https://ezowin.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/965-178ac7e0.png\"\n        - name: \"esa LLC\"\n          slug: \"esa-llc\"\n          website: \"https://esa.io\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/966-f250289b.png\"\n        - name: \"Ruby Development Inc.\"\n          slug: \"ruby-development-inc\"\n          website: \"https://www.ruby-dev.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/973-de4d549f.png\"\n        - name: \"Fusic Co., Ltd.\"\n          slug: \"fusic-co-ltd\"\n          website: \"https://fusic.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/975-01d462b6.png\"\n        - name: \"Nexway Co.,Ltd.\"\n          slug: \"nexway-coltd\"\n          website: \"https://www.nexway.co.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/977-7735734e.png\"\n        - name: \"LUXIAR CO.,LTD.\"\n          slug: \"luxiar-coltd\"\n          website: \"https://www.luxiar.com/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/980-830f998b.png\"\n        - name: \"Rentio Inc.\"\n          slug: \"rentio-inc\"\n          website: \"https://www.rentio.jp/\"\n          logo_url: \"https://rubykaigi.org/2026/images/sponsors/983-71132f02.png\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2026/venue.yml",
    "content": "---\nname: \"Hakodate Arena\"\naddress:\n  street: \"1 Chome-32-2 Yunokawacho\"\n  city: \"Hakodate\"\n  region: \"Hokkaido\"\n  postal_code: \"042-0932\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"1 Chome-32-2 Yunokawacho, Hakodate, Hokkaido 042-0932, Japan\"\ncoordinates:\n  latitude: 41.78201480210688\n  longitude: 140.7835670190506\nmaps:\n  google: \"https://maps.app.goo.gl/PT4zEkEriLAudB2NA\"\n\nlocations:\n  - name: \"Hakodate Citizen Hall\"\n    kind: \"Second Venue\"\n    address:\n      street: \"1-chōme-32-1 Yunokawachō\"\n      city: \"Hakodate\"\n      region: \"Hokkaido\"\n      postal_code: \"042-0932\"\n      country: \"Japan\"\n      country_code: \"JP\"\n      display: \"1 Chome-32-1 Yunokawacho, Hakodate, Hokkaido 042-0932, Japan\"\n    coordinates:\n      latitude: 41.783077602222484\n      longitude: 140.78414429762648\n    maps:\n      google: \"https://maps.app.goo.gl/NvmJrkHWt5XVrpa69\"\n"
  },
  {
    "path": "data/rubykaigi/rubykaigi-2026/videos.yml",
    "content": "# Website: https://rubykaigi.org/2026/schedule/\n# Videos: -\n---\n- id: \"satoshi-tagomori-keynote-rubykaigi-2026\"\n  title: \"Keynote: The Journey of Box Building\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    \"Ruby Box\" is a new experimental feature, introduced at Ruby 4.0.\n    I'll introduce the very basic of Ruby Box, and then will explain the problems, hard things, and technically interesting points around finding/determining boxes while running Ruby programs.\n  kind: \"keynote\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - Satoshi Tagomori\n  video_provider: \"scheduled\"\n  video_id: \"satoshi-tagomori-keynote-rubykaigi-2026\"\n\n- id: \"hitoshi-hasumi-rubykaigi-2026\"\n  title: \"Funicular: A Browser App Framework Powered by PicoRuby.WASM\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    PicoRuby's compact design and built-in multitasking capabilities unlock the potential for developing entirely Ruby-based applications that run directly in the browser.\n    In this talk, we'll discuss the technical details of Funicular, a new web frontend framework, providing a lightweight and Ruby-centric alternative to existing solutions.\n    Discover how Full-Stack Ruby can make your Ruby life fun!\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - HASUMI Hitoshi\n  video_provider: \"scheduled\"\n  video_id: \"hitoshi-hasumi-rubykaigi-2026\"\n\n- id: \"andrey-marchenko-rubykaigi-2026\"\n  title: \"When Can You Skip a Test? Tracking Test Impact\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    Running a full test suite for a Ruby app on every change works at a small scale, but eventually becomes slow and expensive. Many existing tools that try to run only the tests affected by a change either skip too much and then miss test failures or add so much overhead that they are unusable in CI. To solve this I built a test impact analysis engine for the open-source Datadog test optimization gem. This tool now runs in production and saves engineering teams 150 000+ hours of CI time per year.\n\n    In this talk I’ll show how that work became a deep dive into the Ruby internals with some surprising findings about what coverage means in Ruby: turns out it is far from being only about the lines of code. In this talk I will tell you about a journey of building a high-performance library that tracks what is really covered by your tests and share the tricks I learned along the way.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-22\"\n  speakers:\n    - Andrey Marchenko\n  video_provider: \"scheduled\"\n  video_id: \"andrey-marchenko-rubykaigi-2026\"\n\n- id: \"oda-hirohito-rubykaigi-2026\"\n  title: \"Back to the roots of date\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    The date library was originally implemented in Ruby, but during the transition from version 1.8.7 to the 1.9 series, it was rewritten in C to improve performance. Currently, the date library lacks a dedicated maintainer, which has become a burden for Ruby committers. Therefore, I am taking on the challenge of replacing the date library with a pure Ruby implementation.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - ODA Hirohito\n  video_provider: \"scheduled\"\n  video_id: \"oda-hirohito-rubykaigi-2026\"\n\n- id: \"yudai-takada-rubykaigi-2026\"\n  title: \"Liberating Ruby's Parser from Lexer Hacks\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    In traditional LR parsing, the lexer must decide what token to return before the parser sees it. But for context-sensitive syntax, the correct tokenization depends on context that only the parser knows. The lexer can't see it—so Ruby's lexer resorts to manual lex state management, guessing context through hand-written code. This scatters language rules across implementation details, makes bugs hard to reproduce, and complicates every syntax change. PSLR(1): Pseudo-Scannerless Minimal LR(1), which I've implemented in Lrama, inverts this relationship: the parser tells the lexer which tokens are valid at each point. In this talk, I'll show how PSLR(1) bridges the information gap between parser and lexer, and explore how it could liberate Ruby's parser from the Lexer Hack curse.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-22\"\n  speakers:\n    - Yudai Takada\n  video_provider: \"scheduled\"\n  video_id: \"yudai-takada-rubykaigi-2026\"\n\n- id: \"justin-bowen-rubykaigi-2026\"\n  title: \"Million-Agent Ruby: Ractor-Local GC in the Age of AI\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    Ractors promised true parallelism, but \"Stop-the-World\" Garbage Collection remained the final bottleneck—until now. Ruby 4.x introduces Ractor-Local GC, a monumental shift in memory management that decouples object heaps and allows for disjoint collection.\n    This talk explores the technical breakthroughs of the MaNy Project (M:N threading) and how they enable \"Hyper-Generational\" on device workloads in Ruby. Using ragents—a Ractor-native AI agent framework—we demonstrate how to bridge the conceptual gap between Memory Management and LLM Context Management. We will visualize the synergy between heap compaction and token window summarization, proving how Ruby 4.x enables near-linear scaling for autonomous agent swarms. Attendees will leave with a deep understanding of Ruby 4.x internals and a blueprint for high-concurrency AI orchestration.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-22\"\n  speakers:\n    - Justin Bowen\n  video_provider: \"scheduled\"\n  video_id: \"justin-bowen-rubykaigi-2026\"\n\n- id: \"tsutomu-katsube-rubykaigi-2026\"\n  title: \"Portable and Fast - How to implement a parallel test runner\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    When a library grows, its test suites become slow. This makes programmers unhappy. Parallel testing based on the multiprocess is a common practice to solve this. However, most testing frameworks and tools are not \"portable\" enough to support various environments. Because they depend on Unix specific features like fork or external libraries including other bundled gems like drb.\n\n    To address this, test-unit (as a bundled gem) now natively supports portable and fast parallel test running based on the multiprocess. It is designed to work in various environments (e.g. Windows) out of the box.\n\n    This talk describes the journey of implementing parallel running to a historical testing framework without breaking backward compatibility. If you are interested in speeding up your test suites, implementing portable parallel libraries or maintaining historical codebases, this talk will help you.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - Tsutomu Katsube\n  video_provider: \"scheduled\"\n  video_id: \"tsutomu-katsube-rubykaigi-2026\"\n\n- id: \"koichi-ito-rubykaigi-2026\"\n  title: \"Exploring RuboCop with MCP\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    This talk explores the potential of tools in the Ruby ecosystem in the AI era, with a particular focus on linters and formatters.\n\n    Traditionally, RuboCop has been triggered by humans or by other programs. In the AI era, AI agents have emerged as a new kind of trigger. This talk discusses practical ways to combine generative AI with linters and formatters, such as running these tools alongside AI agents, by integrating an MCP (Model Context Protocol) server implemented in Ruby.\n\n    While the AI landscape is evolving rapidly and technologies are changing at a fast pace, this talk aims to provide an opportunity for Ruby ecosystem developers to consider how existing Ruby tools like RuboCop can evolve in the AI era through MCP.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - Koichi ITO\n  video_provider: \"scheduled\"\n  video_id: \"koichi-ito-rubykaigi-2026\"\n\n- id: \"daisuke-aritomo-rubykaigi-2026\"\n  title: \"ext/profile, or How to Make Profilers Tell the Truth\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    When our code runs in slow motion, we reach for profilers. They promise to tell us what’s making it slow.\n\n    Or do they? Profilers do not always “tell the truth”. Their non-deterministic nature comes with pitfalls: sampling bias, hidden methods optimized away, misattributed work between threads. Existing profilers rely on a surprising number of tricks to observe Ruby execution internals.\n\n    As Ruby evolves with features such as Ractors, M:N threading and JIT, the limits of this external approach are becoming increasingly apparent. The more complex the runtime becomes, the harder it is for profilers outside of the VM.\n\n    Let us explore the capabilities and limits of today's Ruby profilers, and show how embedding a profiler, say 'ext/profile', directly into CRuby lets us break fundamental limits of external profiling. What should be called \"true\"? We will find out by the end.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-22\"\n  speakers:\n    - Daisuke Aritomo\n  video_provider: \"scheduled\"\n  video_id: \"daisuke-aritomo-rubykaigi-2026\"\n\n- id: \"hadashia-rubykaigi-2026\"\n  title: \"mruby on C#: From VM Implementation to Game Scripting\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    What if mruby could run anywhere—without any C compilation?\n    I built MRubyCS, a complete mruby VM implementation in pure C#. This makes embedding mruby in cross-platform applications far easier.  Cross-platform distribution means juggling build targets, static/dynamic linking, and diverse host machines—a constant hassle (iOS, Web, Win, Mac, consoles, etc.). And on closed platforms like game consoles (Ps, Switch, Xbox..), it's often impractical without SDK access—now it just works. Unity and .NET already handle platform abstraction for you.\n    This also opens new doors for the Ruby community. Game development has long been a space where Ruby has limited presence. With mruby running in Unity, Ruby developers can bring their language into one of the world's most popular game engines—for scripting game logic, building tools, and more.\n    Beyond the VM implementation story, I'll show practical game scripting with VitalRouter.MRuby and Fiber-based coroutines!\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - hadashiA\n  video_provider: \"scheduled\"\n  video_id: \"hadashia-rubykaigi-2026\"\n\n- id: \"luke-gruber-rubykaigi-2026\"\n  title: \"Ruby's Scheduler: Improving I/O\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Ruby’s thread scheduler is a round-robin scheduler, which makes it simple and completely fair. However, this hurts the responsiveness of I/O-bound threads for mixed I/O and CPU workloads because I/O-bound threads have to wait for CPU-bound threads to finish their timeslice. Many Ruby applications have this type of workload, so would benefit from a priority scheduler. In this talk, we will examine how a priority scheduler works and the benefits it can give to a Ruby application.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-22\"\n  speakers:\n    - Luke Gruber\n  video_provider: \"scheduled\"\n  video_id: \"luke-gruber-rubykaigi-2026\"\n\n- id: \"yuji-yokoo-rubykaigi-2026\"\n  title: \"mruby in the 8-bit world: mruby VM for Zilog Z80\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    Zilog Z80 was a popular 8-bit processor back in its day, and still remains popular in many use cases today. It was widely used for personal computers and game consoles including Sega Master System and Game Gear. However, there is currently no Ruby implementation that runs on Z80.\n\n    I am working on mrubyz, which is an mruby VM implementation that aims to run the mruby bytecode on the Z80 processor, with caveats and limitations.\n\n    It is very limited in terms of supported features and instructions. Also, Z80 is a rather old, and slow processor with many limitations. However, I am making it usable for some purposes.\n\n    This presentation will share with you what it takes to run (a subset of) Ruby on an old 8-bit processor, and some insights gained from developing one.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-22\"\n  speakers:\n    - Yuji Yokoo\n  video_provider: \"scheduled\"\n  video_id: \"yuji-yokoo-rubykaigi-2026\"\n\n- id: \"kazuho-oku-rubykaigi-2026\"\n  title: \"Rapid Start: Faster Internet Connections, with Ruby's Help\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    Making communication faster has long meant removing bottlenecks, one by one. In the past, bandwidth was the primary bottleneck. As bandwidth became more abundant, latency emerged as the next major constraint. Early efforts to reduce it included HTTP/2 multiplexing, TLS 1.3, and QUIC's shorter handshakes.\n\n    Now that QUIC has been standardized and is gaining adoption, attention is shifting to the next bottleneck: the startup phase—the time it takes to discover and fully utilize available bandwidth after a connection is established.\n\n    This session introduces \"Rapid Start,\" a new approach currently being evaluated by Fastly. It reviews Slow Start, the conventional method for bandwidth probing, explaining why startup can be slow, what assumptions it relies on, and where its limitations appear. It then shows how Rapid Start changes the initial behavior of bandwidth estimation to shorten startup time, highlighting its design points, trade-offs, and how Ruby was used to analyze its behavior.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - Kazuho Oku\n  video_provider: \"scheduled\"\n  video_id: \"kazuho-oku-rubykaigi-2026\"\n\n- id: \"yuichiro-kaneko-rubykaigi-2026\"\n  title: \"Kingdom of the Machine: The Tale of Operators and Commands\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Leaving aside the trivialities of specific implementation details[^1], what are the fundamental problems a parser must confront and solve[^2]?\n\n    Let’s consider the input: 1 + 2 * 3. Suppose a grammar dictates that this input should be structured as 1 + (2 * 3). As a parser reads the input from left to right, it reaches 1 + 2 and recognizes that the next token is *. At this point, it must decide whether to group the preceding part into a single unit or continue. This challenge is independent of how the parser is implemented; it's a universal problem inherent to parsing itself.\n\n    In this session, I will highlight several such problems within the parsing domain and explore how different parser implementations try to solve them.\n\n    [^1]: In truth, the \"how\" is where the real struggle lies…\n    [^2]: I will limit my scope to one-way, non-backtracking parsers that read input from left to right.\n    [^3]: Of course, the discussion won't end with simply observing how those problems are addressed…\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - Yuichiro Kaneko\n  video_provider: \"scheduled\"\n  video_id: \"yuichiro-kaneko-rubykaigi-2026\"\n\n- id: \"yuya-fujiwara-rubykaigi-2026\"\n  title: \"From Live Code to Sound: Building a Ruby Live Coding Engine\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    What if we could create sounds incrementally, shaping music as we type Ruby in a live coding session?\n\n    I built strudel-rb, a Ruby implementation inspired by Strudel (a browser-based live coding environment for algorithmic music at https://strudel.cc ),  so we can live-code in Ruby while generating rhythmic patterns and melodies from Ruby syntax.\n\n    In this presentation, I will talk about parsing a sequence of sounds defined in Mini-Notation, how to calculate the timing of sound playback, syntax that Ruby cannot handle when adapting Strudel-style syntax, and techniques for preventing sound from stopping when a syntax error occurs during live-coding.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-22\"\n  speakers:\n    - Yuya Fujiwara\n  video_provider: \"scheduled\"\n  video_id: \"yuya-fujiwara-rubykaigi-2026\"\n\n- id: \"katsuhiko-kageyama-rubykaigi-2026\"\n  title: \"PicoRuby as a Multi-VM Operating System\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    With the emergence of PicoRuby, mruby-centered technologies have increasingly been used as lightweight operating environments for microcontrollers.\n\n    In this talk, I present a more self-contained approach: an operating system for microcontrollers built around PicoRuby, where the mruby VM serves as the system core. I call this framework Family mruby OS.\n\n    The system enables developers to write and run Ruby applications directly on a microcontroller with a GUI, using a USB keyboard, mouse, and display—without relying on a PC.\n\n    By leveraging FreeRTOS, multiple PicoRuby VMs, as well as VMs of other languages, can run concurrently at the machine-code level, enabling true multi-VM execution while keeping Ruby responsible for application lifecycle management.\n\n    I will explain the design and implementation of this framework, discuss the key technical challenges involved, and demonstrate the system running on real hardware.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - Katsuhiko Kageyama\n  video_provider: \"scheduled\"\n  video_id: \"katsuhiko-kageyama-rubykaigi-2026\"\n\n- id: \"max-bernstein-rubykaigi-2026\"\n  title: \"The design and implementation of ZJIT & the next five years\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    The ZJIT team talked about ZJIT briefly last year right before it was merged. Now I will talk about what has changed, where the optimization ideas come from, and what the future holds, including constant-folding, value numbering, escape analysis, scalar replacement, register allocation, and more. I will walk through the rich history of dynamic language compiler research and how it can be applied to a language as dynamic as Ruby. Last, we will see if Ruby 4 holds up to the performance expectations from RubyKaigi 2022.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-22\"\n  speakers:\n    - Max Bernstein\n  video_provider: \"scheduled\"\n  video_id: \"max-bernstein-rubykaigi-2026\"\n\n- id: \"albert-pazderin-rubykaigi-2026\"\n  title: \"TutorialKit.rb: interactive Ruby gem docs powered by Wasm\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    What if trying a Ruby gem was as easy as opening a web page – no local setup, no \"bundle install,\" no version headaches? TutorialKit.rb enables interactive, runnable tutorials for Ruby gems directly in the browser by combining Ruby on WebAssembly with an in-browser development runtime.\n\n    This talk presents the grant-funded evolution of the project: TutorialKit.rb was awarded a Ruby Association Grant in 2025, and the work from that grant is the core of what I'll share at RubyKaigi 2026.\n\n    First of all I'll showcase building an example tutorial using the framework.\n    . RubyKaigi is a technical conference, so then we'll go beyond the demo and focus on the engineering: the architecture that wires Browser → WebContainer → Ruby WASM, the Ruby ⇄ WebContainer bridge, and the build/distribution pipeline that makes a full-featured development workflow possible inside the browser.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-22\"\n  speakers:\n    - Albert Pazderin\n  video_provider: \"scheduled\"\n  video_id: \"albert-pazderin-rubykaigi-2026\"\n\n- id: \"yoh-osaki-rubykaigi-2026\"\n  title: \"Guide to getting started walking source codes of CRuby\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    Have you ever wanted to read CRuby's source code?\n    Do you want to understand how Ruby works?\n    I wrote a self-published book called “CRuby Adventures Log (CRubyのぼうけんのしょ)”. In this book, you'll read CRuby's source code alongside the author, exploring its inner workings as if on an adventure.\n    In this talk, I'll share the essence of the book and techniques for deciphering source code that I gained through writing it.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - Yoh Osaki\n  video_provider: \"scheduled\"\n  video_id: \"yoh-osaki-rubykaigi-2026\"\n\n- id: \"tomoya-ishida-rubykaigi-2026\"\n  title: \"Digits, Digits, and Digits\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Do you know BigDecimal's BigMath module?\n    It can calculate mathematical functions in arbitrary precision.\n    But it takes few seconds calculating sin(1) for just 10000 digits in bigdecimal-3.1.9. It's not \"Big\" at all. We need more and more digits.\n    In this talk, I'll show how BigMath calculation is maintained, improved, and the fun part of designing digit calculation.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - Tomoya Ishida\n  video_provider: \"scheduled\"\n  video_id: \"tomoya-ishida-rubykaigi-2026\"\n\n- id: \"edouard-chin-rubykaigi-2026\"\n  title: \"Faster Bundler, Happier Developers\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    Bundler has reliably helped the Ruby community install and manage dependencies for close to two decades, but with the announcement of Python's uv we found ourselves asking \"Could Bundler be faster?\".\n    We took this opportunity to investigate and fix a multitude of performance issues now released in Bundler 4.\n\n    In this talk, we’ll dive into why Bundler is slow, what we are doing about it, and how the Ruby community can help.\n    Our goals are to evolve Rubygems and Bundler in order to offer Ruby developers an exceptionally fast experience when running bundle install.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-22\"\n  speakers:\n    - Edouard Chin\n  video_provider: \"scheduled\"\n  video_id: \"edouard-chin-rubykaigi-2026\"\n\n- id: \"shunsuke-michii-rubykaigi-2026\"\n  title: \"Building a Standalone Ruby Programming Environment\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    Modern computing is too complex for young learners to get a feel for programming. Even to write Ruby, beginners must first learn, such as managing an OS, setting up an editor, and installing Ruby runtimes. This noise makes it hard to reach the essence of programming.\n\n    In this talk, I will demonstrate how a standalone Ruby computer was built with mruby. This $20 handmade single board computer provides a complete programming environment with display output and keyboard input, all without a host PC.\n\n    I will dive into the implementation of its graphics engine featuring real-time 640x480 output and text/shape rendering, as well as a Ruby shell with USB keyboard input and serial communication with external R2P2 devices. By showing how every component runs on the mruby VM, I will demonstrate that it is powerful enough to build a complete computing experience from scratch on a tiny microcontroller.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-22\"\n  speakers:\n    - Shunsuke Michii\n  video_provider: \"scheduled\"\n  video_id: \"shunsuke-michii-rubykaigi-2026\"\n\n- id: \"charles-nutter-keynote-rubykaigi-2026\"\n  title: \"Keynote: Twenty Years of JRuby\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    For the past twenty years, I have poured my heart and soul into JRuby to bring new opportunities to the Ruby world. We built the first JIT compiler for Ruby, helped the community embrace parallel threads, and became the only alternative Ruby deployed at scale.\n\n    Today, JRuby continues to expand Ruby's horizons, offering unique features.\n\n    And with JRuby 10.1, we're adding new and amazing features and optimizations every day. You've never seen Ruby like this!\n\n    This talk will explore the history of JRuby and show how you can take Ruby to new places and open up a whole new world of Ruby applications.\n  kind: \"keynote\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Charles Oliver Nutter\n  video_provider: \"scheduled\"\n  video_id: \"charles-nutter-keynote-rubykaigi-2026\"\n\n- id: \"koichi-sasada-rubykaigi-2026\"\n  title: \"The AST Galaxy to the Virtual Machine Blues\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Ruby has long relied on virtual machines for performance, but their growing complexity can sometimes feel like the \"virtual machine blues.\" In this talk, I introduce ASTro, an AST-based reusable optimization framework, and share an experiment in reimplementing Ruby using this new approach.\n\n    Before Ruby 1.9, Ruby programs were executed by directly traversing their AST. While modern Ruby implementations have moved to bytecode VMs and JIT compilers, this talk revisits AST-based execution with today’s techniques by rebuilding parts of Ruby on top of ASTro.\n\n    Using ASTro, Ruby programs are optimized and compiled at the AST level, generating C source code and producing efficient native code. This is a research-stage experiment rather than a production proposal, and the talk focuses on what worked, what did not, and what we learned from the attempt.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Koichi Sasada\n  video_provider: \"scheduled\"\n  video_id: \"koichi-sasada-rubykaigi-2026\"\n\n- id: \"daichi-kamiyama-rubykaigi-2026\"\n  title: \"No Types Needed, Just Callable Method Check\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    In recent years, Ruby's type ecosystem has been growing steadily. More and more production applications are benefiting from type checking. However, as AI-generated Ruby code continues to improve in quality, I find myself questioning more often: do we really need types?\n\n    In this session, I'll share my realization that most of the benefits of typing really boil down to preventing NoMethodError. Based on this, I'll introduce Method-Ray, a gem I'm developing that provides this benefit without requiring any type annotations. I will cover its usage, development background, current architecture (implemented in Rust), and how it differs from existing type checkers.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Daichi Kamiyama\n  video_provider: \"scheduled\"\n  video_id: \"daichi-kamiyama-rubykaigi-2026\"\n\n- id: \"daisuke-fujimura-rubykaigi-2026\"\n  title: \"Keeping Ruby Running on Cygwin\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    Ruby runs on a wide variety of platforms, but behind that portability lies continuous and often invisible package maintenance for each environment.\n\n    This talk presents a case study of maintaining Ruby binary packages on the Cygwin environment, from the perspective of a downstream package maintainer rather than a Ruby core committer.\n    It focuses on how Ruby packages on Cygwin, which had fallen far behind upstream releases due to a lack of active maintenance, were restored and kept up to date, and on the technical challenges encountered along the way.\n    These include platform-specific build and test issues, packaging decisions, and the effects of Cygwin’s POSIX compatibility layer, toolchain, and library differences on Ruby.\n    Some of these issues resulted in feedback and patches to Ruby upstream.\n\n    Through this experience, I will share practical lessons on keeping Ruby running on a non-mainstream platform, and the role of downstream maintenance in supporting Ruby’s multi-platform support.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-23\"\n  speakers:\n    - Daisuke Fujimura\n  video_provider: \"scheduled\"\n  video_id: \"daisuke-fujimura-rubykaigi-2026\"\n\n- id: \"peter-zhu-rubykaigi-2026\"\n  title: \"Building the Next-Generation Garbage Collector in Ruby\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Last year at RubyKaigi 2025, the Modular Garbage Collector feature in Ruby was introduced. With this feature, we shipped an alternative garbage collector using the Memory Management Toolkit (MMTk) framework. At the time, however, MMTk was significantly slower than the default garbage collector in Ruby.\n\n    Over the past year, the MMTk Ruby integration has been significantly improved and the performance is now on par with the default garbage collector. It now supports the Moving Immix garbage collection strategy, improved parallelism, and numerous optimizations.\n\n    In this talk, we will go over the Modular Garbage Collector feature and its differences with the default garbage collector, examine the techniques used to speed up the Ruby MMTk integration, and discuss how it can be improved further in the future.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Peter Zhu\n  video_provider: \"scheduled\"\n  video_id: \"peter-zhu-rubykaigi-2026\"\n\n- id: \"uchio-kondo-rubykaigi-2026\"\n  title: \"Uzumibi: Reinventing mruby for the Edges\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    Can Ruby be practically deployed in edge computing environments like Cloudflare Workers, Fastly Compute, or Spin? In this talk, I will introduce \"mruby/edge\" and \"Uzumibi,\" a framework built upon it to bring the power of Ruby to the edge.\n\n    mruby/edge is an mruby-compatible VM built from scratch in Pure Rust. It generates highly portable Wasm binaries, enabling minimal builds under 400KiB.\n\n    Since RubyKaigi 2024, mruby/edge has evolved significantly. It now supports basic OOP features, exception handling, closures, control structures, keyword args, and feature flags.\n\n    Uzumibi is a lightweight web framework leveraging mruby/edge. Uzumibi can run the same Ruby code across multiple edge platforms, providing a simple web API.\n\n    mruby/edge and Uzumibi are opening new possibilities for Ruby in edge computing, where Ruby has traditionally been difficult to utilize.\n    I'll discuss why I built a VM from scratch for Wasm and edges, share the challenges and solutions, and present the future roadmap.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Kondo Uchio\n  video_provider: \"scheduled\"\n  video_id: \"uchio-kondo-rubykaigi-2026\"\n\n- id: \"masatoshi-seki-rubykaigi-2026\"\n  title: \"Programming with a DJ Controller - not vibe coding\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    The current DJ scene is dominated by PCDJ controllers, which communicate with a PC via MIDI for performance. This eliminates the need to carry around equipment or vinyl records, making it easy to get started. However, many people who start easily quickly lose interest or realize the limits of their own talent. I am certainly one of them.\n\n    DJ controllers are equipped with multiple switches such as jog wheels, volume controls, and buttons, and can be purchased for just a few tens of thousands of yen. It's difficult to assemble a similar device yourself by gathering the necessary parts. This presentation will introduce examples of effectively utilizing DJ controllers as Human Interface Devices (HIDs).\n\n    I want to share the know-how of implementing each area in Ruby, from communication with the DJ controller to control of desktop applications and editors, and programming support.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-23\"\n  speakers:\n    - Masatoshi SEKI\n  video_provider: \"scheduled\"\n  video_id: \"masatoshi-seki-rubykaigi-2026\"\n\n- id: \"vladimir-dementyev-rubykaigi-2026\"\n  title: \"Require Hooks: Filling the Gap in Ruby's Extensibility\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Ruby is famously extensible: open classes, included, inherited and such, TracePoint, and more. Yet when it comes to intercepting the process of loading (or requiring) source code, we're left without a standard mechanism to do so.\n\n    Transpilers, load flow analyzers, runtime type checkers—all of these could benefit from having a standard API for hijacking require calls. What if we had one? Actually, we do.\n\n    Let me introduce the require-hooks gem, which brings a universal interface for intercepting require (and load) calls in Ruby, allowing you to perform source transformations and more.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Vladimir Dementyev\n  video_provider: \"scheduled\"\n  video_id: \"vladimir-dementyev-rubykaigi-2026\"\n\n- id: \"samuel-williams-rubykaigi-2026\"\n  title: \"Surviving Black Friday: 100 billion requests with Falcon!\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    On Black Friday 2025, Shopify's Storefront served billions of requests on Falcon—23 million RPM at peak, zero dropped requests. One year earlier, we ran three different web servers and had no idea which parts of our 15-year-old Rails codebase were thread-safe.\n\n    This talk brings together three perspectives on migrating a massive Rails application to async Ruby in production:\n\n    Samuel Williams discusses production reliability: worker health monitoring, proactive memory management, and fiber profiling to detect code blocking the event loop.\n\n    Marc-André Cournoyer dives into \"long tasks\": an approach that lets CPU-bound Rails apps handle concurrent I/O without performance degradation. GraphQL @defer went from blocking workers for 30+ seconds to nearly free.\n\n    Josh Teeter shares the infrastructure wins: the Outbox system (hundreds of Kafka connections → one per pod), debugging issues that only surfaced at BFCM scale, and orchestrating a zero-downtime rollout.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Samuel Williams\n    - Marc-André Cournoyer\n    - Josh Teeter\n  video_provider: \"scheduled\"\n  video_id: \"samuel-williams-rubykaigi-2026\"\n\n- id: \"nagachika-rubykaigi-2026\"\n  title: \"Pure Intonation on Browser: Building a Sequencer with Ruby\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    Ruby/WASM empowers Rubyists to build flexible applications directly on the browser. I developed \"purified-synth,\" a browser-based synthesizer and sequencer combining Ruby/WASM with the Web Audio API.\n    The core distinction of this project is its focus on \"Pure Intonation\" rather than the standard 12-tone equal temperament. While microtonal music often relies on approximations like 53-TET, this sequencer uses Ruby to calculate precise frequency ratios, enabling chords in their purest mathematical form.\n    In this session, I will demonstrate the implementation of this musical theory in Ruby and share practical techniques for building functional applications using Ruby/WASM. I will discuss the nuances of JavaScript interoperability (JS interop) and the architectural patterns required to bridge the gap between Ruby and Web APIs, providing insights for those looking to move beyond \"Hello World\" examples in Ruby/WASM.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-23\"\n  speakers:\n    - Tomoyuki Chikanaga\n  video_provider: \"scheduled\"\n  video_id: \"nagachika-rubykaigi-2026\"\n\n- id: \"aaron-patterson-rubykaigi-2026\"\n  title: \"A Faster FFI\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    We all love programming in Ruby, but sometimes it is necessary to call native code.  Unfortunately, C extensions usually have better performance than using FFI.  In this presentation, I want to show how we can have an FFI implementation that matches, or even beats, the performance of using a C extension.  We’ll look at what makes FFI slow and how we can address performance.  Lets make FFI fast so that we can stop using C extensions!\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-23\"\n  speakers:\n    - Aaron Patterson\n  video_provider: \"scheduled\"\n  video_id: \"aaron-patterson-rubykaigi-2026\"\n\n- id: \"soutaro-matsumoto-rubykaigi-2026\"\n  title: \"Making the RBS Parser Faster\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    At the last RubyKaigi, a talk introduced a major overhaul of the RBS parser, making it more portable so that it could be reused by other tools such as Sorbet. After the new parser was merged into the main branch, an issue was reported indicating roughly a 10% performance regression compared to the RBS 3.9 parser.\n\n    However, this was not the worst case. We soon noticed that, for smaller files, the new parser could be up to five times slower than the previous implementation.\n\n    In this talk, I will walk you through a short journey of making the RBS parser faster by profiling the implementation, clarifying undocumented assumptions, and improving the parser implementation in C.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Soutaro Matsumoto\n  video_provider: \"scheduled\"\n  video_id: \"soutaro-matsumoto-rubykaigi-2026\"\n\n- id: \"ryosuke-uchida-rubykaigi-2026\"\n  title: \"Extreme MQTT on PicoRuby\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    PicoRuby aims to bring Ruby into the world of microcontrollers, where severe memory and execution constraints make practical networking difficult. In this talk, I present a real-world implementation of a practical MQTT client on PicoRuby with mruby/c, built on top of picoruby-net.\n\n    Unlike CRuby, mruby/c provides no threads and very restricted memory. Implementing MQTT in this environment required careful design of polling-based progress, buffer management, connection lifecycle handling, and the boundary between Ruby and native code, while preserving a Ruby-like programming model.\n\n    This session explores what it actually takes to implement a non-trivial network protocol in Ruby under extreme constraints. It shows how far Ruby can realistically be pushed toward bare-metal environments and where it must adapt.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-23\"\n  speakers:\n    - Ryosuke Uchida\n  video_provider: \"scheduled\"\n  video_id: \"ryosuke-uchida-rubykaigi-2026\"\n\n- id: \"jeremy-evans-rubykaigi-2026\"\n  title: \"Implementing Core Set\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Historically, Ruby's Set class was in the standard library.  Starting in Ruby 3.2, the Set standard library was autoloaded by default.  In Ruby 4.0, Set is now implemented as one of the core classes.  In this presentation, I'll go over the history of Set, why and how it was implemented as a core class, interesting implementation issues, and how it led to a decrease in memory usage for some embedded RTypedData objects (and what RTypedData objects are).\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Jeremy Evans\n  video_provider: \"scheduled\"\n  video_id: \"jeremy-evans-rubykaigi-2026\"\n\n- id: \"chris-hasinski-rubykaigi-2026\"\n  title: \"From C to Ruby: Porting Doom\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    optcarrot has become a de-facto benchmark for Ruby performance experiments, but it represents a relatively simple rendering workload. To explore a different performance profile, I ported the core of the 1993 game Doom to Ruby, including its BSP-based renderer translated directly from Chocolate Doom.\n\n    Despite its reputation, Doom is not a raycaster but a constrained 3D engine operating on 2D maps, with dynamic lighting, sprites, stairs, and variable floor heights. This makes it a surprisingly rich real-time, CPU-bound workload for Ruby.\n\n    In this talk, I will describe strategies for porting a large C codebase to Ruby, validating correctness via frame-by-frame comparison with the original engine, and measuring performance. I will also show how modern Ruby features such as YJIT affect a real-time renderer, where the engine reaches playable frame rates at 320×240 but quickly exposes bottlenecks at higher resolutions.\n\n    Includes a demo (gem install doom && doom).\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Chris Hasiński\n  video_provider: \"scheduled\"\n  video_id: \"chris-hasinski-rubykaigi-2026\"\n\n- id: \"shigeru-nakajima-rubykaigi-2026\"\n  title: \"ruby.wasm also enables JavaScript to call Ruby libraries.\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    In 2022, ruby.wasm emerged and has advanced in the realm of Ruby in browser. Examples include loading Ruby scripts from files, automatic conversion of JavaScript native types, and Promise operations. On the other hand, there has been no progress in executing Ruby scripts from JavaScript. Currently, only minimal eval functionality is available. By implementing features equivalent to Ruby in browser—such as loading scripts from files, automatic conversion of native types, and method calls—we can expand Ruby's use cases. For example, it could enable executing Ruby libraries from JavaScript running in browsers or Node.js servers.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-23\"\n  speakers:\n    - Shigeru Nakajima\n  video_provider: \"scheduled\"\n  video_id: \"shigeru-nakajima-rubykaigi-2026\"\n\n- id: \"maciej-mensfeld-rubykaigi-2026\"\n  title: \"Thread-Coordinated Ractors: The Pattern That Delivers\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Ractors have been \"experimental\" since Ruby 3.0. Four years later, most developers still haven't found a practical use for them.\n\n    I did. By moving message deserialization into a Ractor pool, Karafka achieves up to 70% throughput improvement on certain workloads - without requiring users to change a single line of code.\n\n    This talk covers the architecture, the patterns that actually perform, and what I learned about making Ractors useful in production.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Maciej Mensfeld\n  video_provider: \"scheduled\"\n  video_id: \"maciej-mensfeld-rubykaigi-2026\"\n\n- id: \"charlie-savage-rubykaigi-2026\"\n  title: \"Building a Modern Ruby <-> C++ Toolchain\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    It started with pybind11 envy. Back in 2020, I used pybind11 to create a Python extension for my company's C++ pattern discovery engine. It took only a few days but enabled our data scientists to make breakthrough discoveries in cancer research. There is something magical when compiled code comes alive in a REPL like IRB.\n\n    I wanted that experience in Ruby, but the tooling was not there. Thus began a 5-year journey to build a modern Ruby ↔ C++ toolchain. The result now powers Ruby bindings for libraries such as PyTorch, faiss and OpenCV.\n\n    This talk will walk through the toolchain:\n\n\n    ffi-clang: parse C++ headers using libclang\n    ruby-bindgen: generate bindings from the clang AST\n    Rice: Ruby <-> C++ interoperability\n    CMake: cross-platform native builds\n\n\n    We will cover challenges like ownership, garbage collection, templates and method overloading. Attendees will leave knowing how to bridge Ruby and modern C++ for both small utilities and large, complex libraries.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Charlie Savage\n  video_provider: \"scheduled\"\n  video_id: \"charlie-savage-rubykaigi-2026\"\n\n- id: \"shintaro-otsuka-rubykaigi-2026\"\n  title: \"Chasing Real-Time Observability for CRuby\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    Understanding how a program behaves is hard. You need to understand what happens inside the methods being executed and in Ruby, which method is actually called is often not obvious from reading the source code. On top of that, CRuby performs runtime work that never appears in your program, such as GVL-driven thread scheduling and garbage collection.\n\n    CRuby does provide observability APIs, including TracePoint. In this talk, I will present rrtrace, an attempt at chasing real-time observability for CRuby: a system that captures instrumentation events in a CRuby C-extension, streams them to a dedicated external process, reconstructs thread/stack state, and visualizes execution in near real time as a 3D space: time × thread × call stack. With this view, you can literally see GVL thread switches and GC runs as they happen.\n\n    I will also cover the engineering required to make this feasible while disturbing the observed Ruby process as little as possible.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-23\"\n  speakers:\n    - Shintaro Otsuka\n  video_provider: \"scheduled\"\n  video_id: \"shintaro-otsuka-rubykaigi-2026\"\n\n- id: \"yusuke-endoh-rubykaigi-2026\"\n  title: \"Practical TypeProf: Lessons from Analyzing Optcarrot\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    TypeProf is a static type analyzer designed to analyze Ruby code with minimal type annotations. While TypeProf has steadily evolved, its verification has been largely limited to self-hosting: analyzing its own source code with TypeProf itself.\n\n    To prove its utility for the wider ecosystem beyond the tool's own codebase, I conducted an experiment on a \"real-world\" application. Specifically, I used Optcarrot, an 8-bit machine simulator written in pure Ruby that I developed.\n\n    Optcarrot has historically served as a benchmark to drive Ruby interpreter development. Its optimized, complex logic is an ideal, challenging subject for static analysis. I will report on the specific issues encountered during this experiment and the improvements made to TypeProf to resolve them.\n\n    Finally, I will share practical lessons learned and workflows derived from this experience. Attendees will gain a realistic understanding of TypeProf’s current capabilities and how to leverage it in their own projects.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-23\"\n  speakers:\n    - Yusuke Endoh\n  video_provider: \"scheduled\"\n  video_id: \"yusuke-endoh-rubykaigi-2026\"\n\n- id: \"jacob-rubykaigi-2026\"\n  title: \"Whose Memory is it Anyway\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    Ruby’s dynamic nature makes for a great developer experience but causes challenges during compilation. More information gives the compiler more opportunities to generate better code.\n\n    In this talk, I’ll show how statements can be optimized, re-ordered, and removed in ZJIT. We will discuss a new side effect analysis system, show the improvements in code generation due to this design, and discuss the future performance increases that the effect system may lead to.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Jacob\n  video_provider: \"scheduled\"\n  video_id: \"jacob-rubykaigi-2026\"\n\n- id: \"masato-ohba-rubykaigi-2026\"\n  title: \"From Formal Specification to Property Based Test\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    Formal methods may not be common in everyday software development, but they are time-tested tools for detecting ambiguities and contradictions in specifications. What if we could identify properties from formal specifications and automatically generate property based tests? This would be valuable from a quality assurance perspective.\n\n    I'm exploring this idea by building a Ruby tool that parses formal specifications, detects property patterns, and generates executable property based test code.\n\n    In this talk, I'll demonstrate the concept, discuss the challenges, and share insights from bridging formal methods and Ruby testing.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-23\"\n  speakers:\n    - Masato Ohba\n  video_provider: \"scheduled\"\n  video_id: \"masato-ohba-rubykaigi-2026\"\n\n- id: \"stan-lo-rubykaigi-2026\"\n  title: \"The future of Ruby documentation\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Ruby documentation is getting its biggest update in years. As an RDoc maintainer, I've spent the past year modernizing how we read Ruby docs. But improving the reading experience is just the beginning.\n\n    This year, I'm focusing on three major developments: migrating from RDoc markup to GitHub Flavored Markdown, integrating RBS type signatures directly into documentation, and preparing Ruby docs for the AI era with LLM-ready output formats and agent tooling.\n\n    This talk covers where Ruby documentation has been, where it's going, and the concrete roadmap for RDoc's evolution. Writing and consuming Ruby documentation is about to get a lot better.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Stan Lo\n  video_provider: \"scheduled\"\n  video_id: \"stan-lo-rubykaigi-2026\"\n\n- id: \"soichiro-isshiki-rubykaigi-2026\"\n  title: \"Invariants in my own Ruby: some things must never change\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    We all love Ruby for its flexibility, but it’s a total nightmare for a JIT compiler. Redefining Integer#+ or using eval and Binding creates chaos. To go fast, JIT compilers make \"optimistic bets\" called invariants—assuming things won't change to skip redundant checks. But when these bets fail, we need an emergency exit to the great Mother interpreter : deoptimization.\n\n    I’ll share my journey building monoruby (a Ruby implementation written from scratch in Rust) and how I keep it fast and correct. We'll explore:\n\n\n    Why JIT-generated code is faster than the interpreter.\n    The specific invariants used to handle Ruby's dynamic nature.\n    Implementation details in monoruby.\n\n\n    Let's dive into the black box of JIT internals!\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-23\"\n  speakers:\n    - Soichiro Isshiki\n  video_provider: \"scheduled\"\n  video_id: \"soichiro-isshiki-rubykaigi-2026\"\n\n- id: \"hayao-kimura-rubykaigi-2026\"\n  title: \"Integration of PRK Firmware and R2P2\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    PicoRuby currently has two major implementations: PRK Firmware and R2P2. PRK Firmware serves as a keyboard firmware, while R2P2 can be used as a general-purpose electronics platform.\n    Can these two be integrated? In other words, if R2P2 is a general-purpose electronics platform, wouldn't it be possible to write keyboard firmware using R2P2?\n    In practice, there are several hurdles to achieving this integration. In this session, I will discuss the work I have been doing toward this integration.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-23\"\n  speakers:\n    - Hayao Kimura\n  video_provider: \"scheduled\"\n  video_id: \"hayao-kimura-rubykaigi-2026\"\n\n- id: \"ruby-committers-rubykaigi-2026\"\n  title: \"Ruby Committers and the World\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    CRuby committers on stage!\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-24\"\n  speakers:\n    - CRuby Committers\n  video_provider: \"scheduled\"\n  video_id: \"ruby-committers-rubykaigi-2026\"\n\n- id: \"misaki-shioi-rubykaigi-2026\"\n  title: \"The Less-Told Story of Socket Timeouts\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    TCPSocket.new and Socket.tcp are methods that return a socket connected to a remote host over TCP, and starting with Ruby 4.0, they introduce a new timeout feature called open_timeout.\n    Even before Ruby 3.4, these methods already provided two kinds of timeout features: resolv_timeout, which sets a timeout for hostname resolution, and connect_timeout, which sets a timeout for establishing the connection.\n\n    Why, then, is a third timeout necessary now? The answer lies in a less-told story of these methods.\n\n    In this talk, I would like to discuss the history of how these methods came to have the timeout features, the impact of the HEv2 algorithm introduced in Ruby 3.4, the bug that had actually existed for a long time, and the new feature that comprehensively improves these methods for the future, along with concrete implementation details.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-24\"\n  speakers:\n    - Misaki Shioi\n  video_provider: \"scheduled\"\n  video_id: \"misaki-shioi-rubykaigi-2026\"\n\n- id: \"nate-berkopec-rubykaigi-2026\"\n  title: \"Autoresearching Ruby Performance with LLMs\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    AI agents (LLMs) are very good at automating the less-fun parts of programming. They're also very good at working in a loop: try something, verify if it worked, learn and try again. We'll talk about how to harness LLM agents to use \"autoresearch\" to fix performance problems, even in Ruby itself.\n\n    We'll show how to use a combination of LLMs, simple scripts, skills and MCPs to create reproducible benchmarks. These tools will combine to create an \"agent-native\" Ruby performance improving workbench. We'll also explore and discuss the limitations of these tools, including what kinds of problems they tend to be bad at solving.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-24\"\n  speakers:\n    - Nate Berkopec\n  video_provider: \"scheduled\"\n  video_id: \"nate-berkopec-rubykaigi-2026\"\n\n- id: \"kazuaki-tanaka-rubykaigi-2026\"\n  title: \"Native Multi-Core Support in mruby/c: Enhancing Performance\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    mruby/c is a lightweight Ruby implementation that is optimised for use in embedded systems and environments with limited resources.\n    mruby/c now supports native multi-core, enabling it to leverage the capabilities of modern processors.\n\n    This presentation will highlight how mruby/c enables concurrent processing through its native multi-core functionality, particularly within the mruby/c VM, which is designed to efficiently manage multiple threads.\n\n    The presentation covers the following topics:\n\n\n    Challenges in multi-core support\n    Mutex\n    task switching among cores\n    Performance evaluation\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-24\"\n  speakers:\n    - Kazuaki Tanaka\n  video_provider: \"scheduled\"\n  video_id: \"kazuaki-tanaka-rubykaigi-2026\"\n\n- id: \"john-hawthorn-rubykaigi-2026\"\n  title: \"A Write Barrier Validating GC for Ruby\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Missing or incorrect write barriers are a common source of bugs both in C extensions and CRuby itself. They can cause memory corruption that only manifests under specific GC timing, making them difficult to reproduce and to be confident in a fix.\n\n    This talk introduces a new garbage collector specifically for dynamic analysis of write barrier correctness. I'll explain how it works, how to use it, the bugs it has fixed, and the hard rules for when write barriers are required.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-24\"\n  speakers:\n    - John Hawthorn\n  video_provider: \"scheduled\"\n  video_id: \"john-hawthorn-rubykaigi-2026\"\n\n- id: \"andrey-novikov-rubykaigi-2026\"\n  title: \"Writing DSL for DSL: Catch Code as It's Born with TracePoint\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    Let’s dive into an unconventional use of Ruby’s TracePoint API, not for performance profiling, but for runtime introspection in metaprogramming-heavy Ruby code.\n\n    We’ll focus on real-world use case of writing DSLs for use with existing DSLs, exploring how TracePoint enables us to untangle messy results of metaprogramming techniques and do things like dynamic linking logic to DSL-generated methods.\n\n    Expect a blend of advanced Ruby techniques, practical insights, and a fresh perspective on a lesser-known Ruby API.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-24\"\n  speakers:\n    - Andrey Novikov\n  video_provider: \"scheduled\"\n  video_id: \"andrey-novikov-rubykaigi-2026\"\n\n- id: \"sutou-kouhei-rubykaigi-2026\"\n  title: \"Pure Ruby Apache Arrow reader/writer\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    Apache Arrow is the de fact standard data format in modern data processing systems. We can use the official Red Arrow gem to process Apache Arrow data. It's suitable for fast large data processing but it's  over-performance for only low cost data exchange needs. Red Arrow is larger and a bit difficult to install than pure Ruby gems because Red Arrow is implemented as bindings.\n\n    I'm implementing the official pure Ruby Apache Arrow reader/writer for only low cost data exchange needs. I expect that more Ruby libraries and applications add support for Apache Arrow inputs/outputs by the pure Ruby Apache Arrow reader/writer. Ruby can be used more for data processing by it.\n\n    This talk describes how to implement fast pure Ruby binary data reader/writer and the future of data processing in Ruby.\n\n    This is a 2025 Ruby Association Grant project: https://www.ruby.or.jp/en/news/20251030\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-24\"\n  speakers:\n    - Kouhei Sutou\n  video_provider: \"scheduled\"\n  video_id: \"sutou-kouhei-rubykaigi-2026\"\n\n- id: \"hiroya-fujinami-rubykaigi-2026\"\n  title: \"(Re)make Regexp in Ruby: Democratizing internals for the JIT\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    With the rise of JIT implementations like YJIT and ZJIT, rewriting Ruby primitives in Ruby has become a realistic way for optimization. This brings a dream of a pure-Ruby Regexp engine that works with JIT and integrates naturally with Ruby features (e.g., timeouts).\n\n    However, turning this dream into a production-ready reality faces a massive hurdle: compatibility. To replace Onigmo, we must replicate its exact behaviors, which is notoriously difficult. From my experience, the hardest barriers to a compatible reimplementation are the parsing and character class semantics.\n\n    I propose a pragmatic solution: exposing Onigmo's parser and character class logic as Ruby APIs. This democratizes the engine, offloading the complexity of compatibility to C while allowing us to focus on rewriting the matching logic in Ruby. I will demonstrate a PoC and discuss the future of a hackable, JIT-friendly Regexp engine.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-24\"\n  speakers:\n    - Hiroya Fujinami\n  video_provider: \"scheduled\"\n  video_id: \"hiroya-fujinami-rubykaigi-2026\"\n\n- id: \"ivo-anjo-rubykaigi-2026\"\n  title: \"From Ruby 2 to 4: Updating a C extension for a Modern VM\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    The Ruby VM has evolved a lot from Ruby 2 to Ruby 4. While this evolution was reflected in Ruby's C APIs, great care was taken to provide backwards compatibility. Old gems work with little change on Ruby 4, ensuring apps don't get stuck on old versions just because some dependency has not been updated.\n\n    However, C extensions shouldn't remain stuck on \"old ways\". If not updated, they can silently get in the way of modern VM features such as GC compaction, or force the garbage collector to do extra unnecessary work, on top of missing out on performance and correctness improvements.\n\n    In this talk, I present our ongoing work to modernize the datadog gem for a Ruby 4-era VM, identifying key modern Ruby C APIs, the VM assumptions they encode, and when and why native gems should adopt them.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-24\"\n  speakers:\n    - Ivo Anjo\n  video_provider: \"scheduled\"\n  video_id: \"ivo-anjo-rubykaigi-2026\"\n\n- id: \"kouji-takao-rubykaigi-2026\"\n  title: \"Smalruby: Visualizing Ruby with Bidirectional Transpiration\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    Smalruby 3 (https://smalruby.app) is a visual programming environment that seamlessly bridges the gap between Scratch blocks and Ruby code. While Scratch is the de facto standard for K-12 education, transitioning to text-based languages remains a high barrier. Smalruby 3 solves this by providing real-time, bidirectional conversion between blocks and Ruby.\n\n    In this talk, I will explore the technical challenges and implementation details of Smalruby 3. How do we map Scratch's event-driven, actor model to Ruby's object-oriented syntax? How is the AST manipulated to ensure that a move(10) block becomes a method call, and conversely, how arbitrary Ruby code is parsed back into visual blocks?\n\n    I will demonstrate how puts \"Hello\" is visualized not as console output but as a speech bubble from a sprite, and how class and def definitions intuitively map to actor properties and behaviors. This session reveals how we can \"visualize\" Ruby's semantics to foster the next generation of Rubyists.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-24\"\n  speakers:\n    - Kouji Takao\n  video_provider: \"scheduled\"\n  video_id: \"kouji-takao-rubykaigi-2026\"\n\n- id: \"hiroshi-shibata-rubykaigi-2026\"\n  title: \"Ruby Releases Ruby\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    The process of delivering Ruby involves more than just shipping code; it is a defense against supply chain attacks. To build a robust fortress around our ecosystem, we had to eliminate the most significant security vulnerability: the human element.\n\n    Gone are the days of manual checklists and opaque procedures. Today, they have been replaced by secure, automated pipelines where code verifies code. In essence, Ruby is releasing Ruby.\n\n    In this session, I will take you behind the scenes of this evolution from the perspective of a Ruby Core Release Manager. We will dive deep into how release-gem and Sigstore build attestations create a tamper-proof chain of custody. The highlight of this session is the \"self-hosting\" challenge: releasing Ruby and RubyGems—the root of our dependency tree—autonomously. I will demonstrate our recursive engineering approach, utilizing sigstore-ruby to cryptographically verify the release of RubyGems itself. Join us to see how we ensure that the tools you rely.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-24\"\n  speakers:\n    - Hiroshi SHIBATA\n  video_provider: \"scheduled\"\n  video_id: \"hiroshi-shibata-rubykaigi-2026\"\n\n- id: \"marco-roth-rubykaigi-2026\"\n  title: \"HTML-Aware ERB: The Path to Reactive Rendering\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    ERB templates in Ruby are traditionally rendered by engines that treat templates as string generators, which makes it difficult to reason about HTML structure, state changes, or incremental updates. These limitations become especially visible in modern HTML-over-the-wire workflows.\n\n    In this talk, we explore what it would take to build a reactive ERB rendering engine. We begin by revisiting how existing ERB engines compile templates into Ruby code and look at how recent advances in HTML-aware parsing and tooling make new approaches possible.\n\n    Using Herb::Engine as a concrete example, we examine how structural understanding enables state-aware rendering, diff-based updates, and a more responsive development experience, including instant updates without full page reloads, rich in-browser developer tools. Such as template outlines, partial and ERB structure views, jump-to-source navigation, and many other innovations.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-24\"\n  speakers:\n    - Marco Roth\n  video_provider: \"scheduled\"\n  video_id: \"marco-roth-rubykaigi-2026\"\n\n- id: \"yutaka-hara-rubykaigi-2026\"\n  title: \"Ruby on NES - how to make the smallest ruby ever\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    If this is not your first RubyKaigi, you may know that Ruby has been ported to many game consoles. But how about to NES?\n    In this session, I will explain how I built nesruby — a tiny Ruby interpreter that runs on the NES, inspired by mruby/c. I'll cover the strategy of reusing mruby's bytecode format, the VM implementation in C using cc65, and some interesting internals such as the Symbol class implementation.\n    Note: this talk focuses on the Ruby interpreter side. NES-specific topics (graphics hardware quirks, PPU, etc.) are out of scope, so no prior NES knowledge is required.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-24\"\n  speakers:\n    - Yutaka HARA\n  video_provider: \"scheduled\"\n  video_id: \"yutaka-hara-rubykaigi-2026\"\n\n- id: \"benoit-daloze-rubykaigi-2026\"\n  title: \"Making Hash Parallel, Thread-Safe and Fast!\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Can we make Hash support parallel reads and writes, be thread-safe, and still be as fast on a single thread as before? Yes!\n    With extensive state-of-the-art research, including an all-new lock to allow parallel reads and writes, we found a way to achieve all of these goals. Embark on a journey to reimplement Hash so it’s fast and safe no matter if used by one or many threads at once. It's even safer than under the GVL!\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-24\"\n  speakers:\n    - Benoit Daloze\n  video_provider: \"scheduled\"\n  video_id: \"benoit-daloze-rubykaigi-2026\"\n\n- id: \"alexandre-terrasa-rubykaigi-2026\"\n  title: \"Blazing-fast Code Indexing for Smarter Ruby Tools\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    Building smart, code-aware developer tools for Ruby should be easier. Today, tools like language servers, documentation generators, and type checkers each implement its own mechanism for understanding Ruby code.\n\n    With Rubydex, we introduce a unified code indexer that simplifies static analysis across the entire Ruby ecosystem. Rubydex delivers fast, memory-efficient access to code insights like constant resolution, inheritance linearization, reference tracking, and is accessible from both Ruby and non-Ruby tools via native bindings. After integrating Rubydex in RubyLSP, Tapioca, and Spoom, we observed up to 10x speed improvements and 2x lower memory usage.\n\n    In this talk, we'll dive into Rubydex’s architecture, implementation, optimizations, and show how you can leverage it to create the next generation of Ruby developer tools.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-24\"\n  speakers:\n    - Alexandre Terrasa\n  video_provider: \"scheduled\"\n  video_id: \"alexandre-terrasa-rubykaigi-2026\"\n\n- id: \"yuhei-okazaki-rubykaigi-2026\"\n  title: \"PicoRuby for IoT: Connecting to the Cloud with MQTT\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    PicoRuby is an extremely small implementation of Ruby that can run even on microcontrollers such as the ESP32, developed by Espressif Systems. At RubyKaigi 2025, I talked about porting PicoRuby to the ESP32.\n\n    This talk is a sequel to that session. I will introduce the process of enabling PicoRuby on the ESP32 to connect to the cloud over the internet.\n\n    The ESP32 supports Wi-Fi and TCP/IP networking, making it well suited for IoT applications. For PicoRuby running on the ESP32, I implemented and refined classes such as WiFi, Socket, and an MQTT client. This work also includes secure communication using TLS and device authentication with X.509 client certificates. These implementations are portable and can be adapted to POSIX environments as well as other microcontrollers.\n\n    As a result, PicoRuby can now communicate with cloud services such as AWS IoT Core using the publish/subscribe model, making it ready for real-world IoT systems.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-24\"\n  speakers:\n    - Yuhei Okazaki\n  video_provider: \"scheduled\"\n  video_id: \"yuhei-okazaki-rubykaigi-2026\"\n\n- id: \"takashi-kokubun-rubykaigi-2026\"\n  title: \"Lightning-Fast Method Calls with Ruby 4.1 ZJIT\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    One of the largest sources of slowness in Ruby is the overhead associated with method calls. While recent versions of Ruby have seen YJIT enhance method call performance by optimizing machine code for various method call types, a significant bottleneck remains: the process of pushing a Ruby method frame.\n\n    In this talk, we will explore the various elements Ruby needs to handle within method frames and unveil our approach to making this process nearly zero-cost with ZJIT's Lightweight Frames and method inlining. Additionally, we will discuss the compelling reasons to transition from YJIT to ZJIT in Ruby 4.1, highlighting the performance benefits you can expect.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-24\"\n  speakers:\n    - Takashi Kokubun\n  video_provider: \"scheduled\"\n  video_id: \"takashi-kokubun-rubykaigi-2026\"\n\n- id: \"samuel-giddins-rubykaigi-2026\"\n  title: \"Ruby the Hard Way: Writing Bytecode to Optimize Plain Ruby\"\n  track: \"Sub Arena #rubykaigiB\"\n  description: |-\n    Ruby is famously dynamic, expressive, and productive—but those same qualities can make performance tuning feel opaque when you hit a true hotspot. When profiling stops pointing to anti-patterns code and starts pointing at our beautiful idiomatic Ruby, what options do you have?\n\n    In this talk, we’ll explore an unconventional but powerful approach: writing Ruby bytecode (or generating it) to optimize critical paths in otherwise ordinary Ruby applications. We’ll look at how Ruby code is compiled into bytecode, what that bytecode actually looks like, and how controlling it can eliminate overhead that’s difficult or impossible to remove at the source level.\n\n    Through concrete examples, we’ll demonstrate replacing hot Ruby methods with bytecode-generated equivalents, discuss the tradeoffs and risks involved, and show when this technique is worth considering. The goal is not to replace Ruby—but to understand it deeply enough to bend it, safely, when performance truly matters.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-24\"\n  speakers:\n    - Samuel Giddins\n  video_provider: \"scheduled\"\n  video_id: \"samuel-giddins-rubykaigi-2026\"\n\n- id: \"sangyong-sim-rubykaigi-2026\"\n  title: \"Good Enough Types: Heuristic Type Inference for Ruby\"\n  track: \"Small Hall #rubykaigiC\"\n  description: |-\n    What if you could get type information without writing type annotations?\n\n    type-guessr is a Ruby LSP addon with duck typing heuristic.\n    Instead of \"if it responds to these methods, it's OK,\" we reason:\n    \"if these methods were called, it must be this class.\"\n\n    For example, if ingredients and steps are called on a variable, and only the Recipe class has both methods, we infer the type as Recipe.\n\n    In this talk, I'll share how it works in practice, its algorithm design, and the limits of this approach.\n  kind: \"talk\"\n  language: \"ja\"\n  date: \"2026-04-24\"\n  speakers:\n    - Sangyong \"Shia\" Sim\n  video_provider: \"scheduled\"\n  video_id: \"sangyong-sim-rubykaigi-2026\"\n\n- id: \"yukihiro-matsumoto-keynote-rubykaigi-2026\"\n  title: \"Keynote\"\n  track: \"Large Hall #rubykaigiA\"\n  description: |-\n    Keynote by Yukihiro \"Matz\" Matsumoto\n  kind: \"keynote\"\n  language: \"ja\"\n  date: \"2026-04-24\"\n  speakers:\n    - Yukihiro \"Matz\" Matsumoto\n  video_provider: \"scheduled\"\n  video_id: \"yukihiro-matsumoto-keynote-rubykaigi-2026\"\n"
  },
  {
    "path": "data/rubykaigi/series.yml",
    "content": "---\nname: \"RubyKaigi\"\nwebsite: \"https://rubykaigi.org\"\ntwitter: \"RubyKaigi\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"RubyKaigi\"\ndefault_country_code: \"JA\"\nyoutube_channel_name: \"rubykaigi4884\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCBSg5zH-VFJ42BGQFk4VH2A\"\naliases:\n  - Ruby Kaigi\n"
  },
  {
    "path": "data/rubykansai/rubykansai-meetup/event.yml",
    "content": "---\nid: \"rubykansai-meetup\"\ntitle: \"Ruby関西 Meetup\"\nlocation: \"Osaka, Japan\"\ndescription: |-\n  A long-running community that organizes Ruby-related events across the Kansai region, including study sessions, KansaiRubyKaigi, and Rails meetups in Kansai.\nwebsite: \"https://rubykansai.doorkeeper.jp\"\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 34.6937569\n  longitude: 135.5014539\n"
  },
  {
    "path": "data/rubykansai/rubykansai-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rubykansai/series.yml",
    "content": "---\nname: \"Ruby関西\"\nwebsite: \"https://github.com/rubykansai/workshops/wiki\"\nmeetup: \"https://rubykansai.doorkeeper.jp\"\nkind: \"organisation\"\nfrequency: \"irregular\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/rubymotion-inspect/rubymotion-inspect-2013/event.yml",
    "content": "---\nid: \"rubymotion-inspect-2013\"\ntitle: \"RubyMotion #inspect 2013\"\ndescription: \"\"\nlocation: \"Brussels, Belgium\"\nkind: \"conference\"\nstart_date: \"2013-03-28\"\nend_date: \"2013-03-29\"\nwebsite: \"http://www.rubymotion.com/events/conference\"\ncoordinates:\n  latitude: 50.8260453\n  longitude: 4.3802052\n"
  },
  {
    "path": "data/rubymotion-inspect/rubymotion-inspect-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubymotion.com/events/conference\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubymotion-inspect/rubymotion-inspect-2014/event.yml",
    "content": "---\nid: \"rubymotion-inspect-2014\"\ntitle: \"RubyMotion #inspect 2014\"\ndescription: \"\"\nlocation: \"San Francisco, CA, United States\"\nkind: \"conference\"\nstart_date: \"2014-05-28\"\nend_date: \"2014-05-29\"\nwebsite: \"http://www.rubymotion.com/conference/2014/\"\nplaylist: \"http://confreaks.tv/events/inspect2014\"\ncoordinates:\n  latitude: 37.7749295\n  longitude: -122.4194155\n"
  },
  {
    "path": "data/rubymotion-inspect/rubymotion-inspect-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubymotion.com/conference/2014/\n# Videos: http://confreaks.tv/events/inspect2014\n---\n[]\n"
  },
  {
    "path": "data/rubymotion-inspect/series.yml",
    "content": "---\nname: \"RubyMotion #inspect\"\nwebsite: \"http://www.rubymotion.com/events/conference\"\ntwitter: \"rubymotion\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - rubymotion\n  - Ruby Motion\n  - Ruby Motion inspect\n  - RubyMotion inspect\n"
  },
  {
    "path": "data/rubymx/rubymx-meetup/event.yml",
    "content": "---\nid: \"rubymx\"\ntitle: \"RubyMX Meetup\"\nlocation: \"Mexico\"\ndescription: |-\n  RubyMX is a monthly meetup in Mexico. Join us to learn more about Ruby and meet other Ruby enthusiasts.\nwebsite: \"https://comunidadruby.mx/\"\nkind: \"meetup\"\npublished_at: \"2022-03-16\"\nchannel_id: \"UCiqr32yu2joQdUyT9QIzDxQ\"\nyear: 2022\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#38053C\"\ncoordinates:\n  latitude: 23.634501\n  longitude: -102.552784\n"
  },
  {
    "path": "data/rubymx/rubymx-meetup/videos.yml",
    "content": "---\n- id: \"rubymx-meetup-2022-03\"\n  title: \"RubyMX Meetup March 2022\"\n  raw_title: \"RubyMX | Novedades de Rails 7 Antes y después\"\n  date: \"2022-03-16\"\n  event_name: \"RubyMX Meetup March 2022\"\n  published_at: \"2022-03-24\"\n  video_provider: \"youtube\"\n  video_id: \"usDo0nTor4c\"\n  description: |-\n    En esta charla, hablaré sobre algunas nuevas funcionalidades que fueron agregadas a Rails y que no es tan fácil conocerlas porque se pierden un poco en la lista de cambios.\n  talks:\n    - title: \"Novedades de Rails 7 Antes y después\"\n      event_name: \"RubyMX Meetup March 2022\"\n      language: \"spanish\"\n      start_cue: \"00:00\"\n      end_cue: \"45:00\"\n      video_provider: \"parent\"\n      id: \"cesar-eduardo-rubymx-2022-03\"\n      video_id: \"cesar-eduardo-rubymx-2022-03\"\n      speakers:\n        - César Eduardo\n\n- id: \"rubymx-meetup-2022-04\"\n  title: \"RubyMX Meetup April 2022\"\n  raw_title: \"Ruby | Introducción a Turbo Rails\"\n  date: \"2022-04-20\"\n  event_name: \"RubyMX Meetup April 2022\"\n  published_at: \"2022-04-21\"\n  video_provider: \"youtube\"\n  video_id: \"fv3W6EZ_1ho\"\n  description: |-\n    Full Stack developer con más de 15 años de experiencia. Importada desde Eldorado, Sinaloa. Mamá de un plebito de 8 años.\n  talks:\n    - title: \"Introducción a Turbo Rails\"\n      event_name: \"RubyMX Meetup April 2022\"\n      language: \"spanish\"\n      start_cue: \"04:53\"\n      end_cue: \"36:50\"\n      video_provider: \"parent\"\n      id: \"erendira-garcia-rubymx-2022-04\"\n      video_id: \"erendira-garcia-rubymx-2022-04\"\n      speakers:\n        - Eréndira García\n\n    - title: \"Atomic Web Design\"\n      event_name: \"RubyMX Meetup April 2022\"\n      start_cue: \"38:58\"\n      end_cue: \"01:09:50\"\n      video_provider: \"parent\"\n      id: \"yannik-gonzalez-rubymx-2022-04\"\n      video_id: \"yannik-gonzalez-rubymx-2022-04\"\n      speakers:\n        - Yannik González Alarcón\n\n- id: \"rubymx-meetup-2022-06\"\n  title: \"RubyMX Meetup June 2022\"\n  raw_title: \"RUBY MEXICO | De Python a Ruby\"\n  date: \"2022-06-23\"\n  event_name: \"RubyMX Meetup June 2022\"\n  published_at: \"2022-06-24\"\n  video_provider: \"youtube\"\n  video_id: \"Ve_7Wc_RCpA\"\n  description: |-\n    Bryan Guerrero nos contará sobre las cosas que ha aprendido y las curiosidades que ha encontrado al moverse de Python a Ruby como su lenguaje principal. Jueves 23 de junio en WeWork Américas en Guadalajara\n  talks:\n    - title: \"De Python a Ruby\"\n      event_name: \"RubyMX Meetup June 2022\"\n      language: \"spanish\"\n      start_cue: \"09:12\"\n      end_cue: \"27:50\"\n      video_provider: \"parent\"\n      id: \"bryan-guerrero-rubymx-2022-06\"\n      video_id: \"bryan-guerrero-rubymx-2022-06\"\n      speakers:\n        - Bryan Guerrero\n\n    - title: \"Analytics en tiempo real con Rails\"\n      event_name: \"RubyMX Meetup June 2022\"\n      language: \"spanish\"\n      start_cue: \"55:30\"\n      end_cue: \"01:28:36\"\n      video_provider: \"parent\"\n      id: \"eduardo-hernandez-rubymx-2022-06\"\n      video_id: \"eduardo-hernandez-rubymx-2022-06\"\n      speakers:\n        - Eduardo Hernández\n\n- id: \"rubymx-meetup-2022-07\"\n  title: \"RubyMX Meetup July 2022\"\n  raw_title: \"Ruby MX 07.22 | Ru[by|st] El vínculo entre Ruby y Rust\"\n  date: \"2022-07-20\"\n  event_name: \"RubyMX Meetup July 2022\"\n  published_at: \"2022-09-30\"\n  video_provider: \"youtube\"\n  video_id: \"9bChwKA2ieY\"\n  description: |-\n    La quinta edición será en colaboración con Nuvocargo, la empresa anfitriona del mes. El evento comienza a las 6 pm en BBVA Open Spaces: dentro de The Landmark.\n  talks:\n    - title: \"Ru[by|st] El vínculo entre Ruby y Rust\"\n      event_name: \"RubyMX Meetup July 2022\"\n      language: \"spanish\"\n      start_cue: \"09:05\"\n      end_cue: \"36:54\"\n      video_provider: \"parent\"\n      id: \"yuliana-reyna-rubymx-2022-07\"\n      video_id: \"yuliana-reyna-rubymx-2022-07\"\n      speakers:\n        - Yuliana Reyna\n\n    - title: \"Low Code Tools & Lowest Effort Api para Superar una Migración Inminente\"\n      event_name: \"RubyMX Meetup July 2022\"\n      language: \"spanish\"\n      start_cue: \"37:15\"\n      end_cue: \"01:12:12\"\n      video_provider: \"parent\"\n      id: \"angel-malavar-rubymx-2022-07\"\n      video_id: \"angel-malavar-rubymx-2022-07\"\n      speakers:\n        - Angel Malavar\n\n- id: \"rubymx-meetup-2022-08\"\n  title: \"RubyMX Meetup August 2022\"\n  raw_title: \"Ruby MX meetup | Actualizando Rails y No Morir en el Intento\"\n  date: \"2022-08-24\"\n  event_name: \"RubyMX Meetup August 2022\"\n  published_at: \"2022-08-25\"\n  video_provider: \"youtube\"\n  video_id: \"aYVLQ2CcbuQ\"\n  description: |-\n    Inicia agosto y ya tenemos algunos detalles de nuestra sexta edición en colaboración con Brightcove. 24 de agosto a las 7 pm en las oficinas de Brightcove: Blvrd Puerta de Hierro 5153 - piso 19 y 20.\n  talks:\n    - title: \"Actualizando Rails y No Morir en el Intento\"\n      event_name: \"RubyMX Meetup August 2022\"\n      language: \"spanish\"\n      start_cue: \"16:50\"\n      end_cue: \"54:16\"\n      video_provider: \"parent\"\n      id: \"guillermo-moreno-rubymx-2022-08\"\n      video_id: \"guillermo-moreno-rubymx-2022-08\"\n      speakers:\n        - Guillermo Moreno\n\n    - title: \"Metaprogramming, el superpoder que no deberías usar\"\n      event_name: \"RubyMX Meetup August 2022\"\n      language: \"spanish\"\n      start_cue: \"01:09:49\"\n      end_cue: \"01:36:42\"\n      video_provider: \"parent\"\n      id: \"brian-martinez-rubymx-2022-08\"\n      video_id: \"brian-martinez-rubymx-2022-08\"\n      speakers:\n        - Brian Martinez\n\n- id: \"rubymx-meetup-2022-10\"\n  title: \"RubyMX Meetup October 2022\"\n  raw_title: \"Comunidad Ruby MX | El Pasado, Presente y Futuro de Ruby\"\n  date: \"2022-10-26\"\n  event_name: \"RubyMX Meetup October 2022\"\n  published_at: \"2022-10-27\"\n  video_provider: \"youtube\"\n  video_id: \"Xul2P15nSdQ\"\n  description: |-\n    La octava edición será en colaboración con Luxoft, la empresa anfitriona del mes. El evento comienza a las 7 pm en Luxoft Guadalajara.\n  talks:\n    - title: \"El Pasado, Presente y Futuro de Ruby\"\n      event_name: \"RubyMX Meetup October 2022\"\n      language: \"spanish\"\n      start_cue: \"04:44\"\n      end_cue: \"33:50\"\n      video_provider: \"parent\"\n      id: \"fernando-perales-rubymx-2022-10\"\n      video_id: \"fernando-perales-rubymx-2022-10\"\n      speakers:\n        - Fernando Perales\n\n    - title: \"Design Strategies of Technological Product\"\n      event_name: \"RubyMX Meetup October 2022\"\n      start_cue: \"40:30\"\n      end_cue: \"01:07:22\"\n      video_provider: \"parent\"\n      id: \"norma-medrano-rubymx-2022-10\"\n      video_id: \"norma-medrano-rubymx-2022-10\"\n      speakers:\n        - Norma Medrano\n\n- id: \"rubymx-meetup-2023-03\"\n  title: \"RubyMX Meetup March 2023\"\n  raw_title: \"Comunidad Ruby MX | Sobreviviendo a Integraciones de Terceros\"\n  date: \"2023-03-29\"\n  event_name: \"RubyMX Meetup March 2023\"\n  published_at: \"2023-03-30\"\n  video_provider: \"youtube\"\n  video_id: \"DWw9yXHpfOA\"\n  description: |-\n    RubyMX Marzo 2023\n  talks:\n    - title: \"Sobreviviendo a Integraciones de Terceros\"\n      event_name: \"RubyMX Meetup March 2023\"\n      language: \"spanish\"\n      start_cue: \"05:36\"\n      end_cue: \"26:36\"\n      video_provider: \"parent\"\n      id: \"juan-c-ruiz-rubymx-2023-03\"\n      video_id: \"juan-c-ruiz-rubymx-2023-03\"\n      speakers:\n        - Juan C. Ruiz\n\n    - title: \"Principio de Inversion de Dependencia\"\n      event_name: \"RubyMX Meetup March 2023\"\n      language: \"spanish\"\n      start_cue: \"34:48\"\n      end_cue: \"01:14:11\"\n      video_provider: \"parent\"\n      id: \"javier-trevino-rubymx-2023-03\"\n      video_id: \"javier-trevino-rubymx-2023-03\"\n      speakers:\n        - Javier Treviño\n"
  },
  {
    "path": "data/rubymx/series.yml",
    "content": "---\nname: \"RubyMX Meetup\"\nwebsite: \"https://comunidadruby.mx/\"\ngithub: \"https://github.com/comunidadrubymx\"\ntwitter: \"comunidadrubymx\"\nyoutube_channel_name: \"comunidadrubymx\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"MX\"\nlanguage: \"spanish\"\nyoutube_channel_id: \"UCiqr32yu2joQdUyT9QIzDxQ\"\naliases:\n  - comunidadrubymx\n  - comunidadruby MX\n  - Ruby Mexico\n  - Ruby MX\n"
  },
  {
    "path": "data/rubynation/rubynation-2014/event.yml",
    "content": "---\nid: \"rubynation-2014\"\ntitle: \"RubyNation 2014\"\ndescription: \"\"\nlocation: \"Washington, DC\"\nkind: \"conference\"\nstart_date: \"2014-06-06\"\nend_date: \"2014-06-07\"\nwebsite: \"http://www.rubynation.org/\"\ntwitter: \"rubynation\"\ncoordinates:\n  latitude: 38.9071923\n  longitude: -77.0368707\n"
  },
  {
    "path": "data/rubynation/rubynation-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubynation.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubynation/rubynation-2015/event.yml",
    "content": "---\nid: \"rubynation-2015\"\ntitle: \"RubyNation 2015\"\ndescription: \"\"\nlocation: \"Washington, DC\"\nkind: \"conference\"\nstart_date: \"2015-06-12\"\nend_date: \"2015-06-13\"\nwebsite: \"http://www.rubynation.org/\"\ntwitter: \"rubynation\"\ncoordinates:\n  latitude: 38.9071923\n  longitude: -77.0368707\n"
  },
  {
    "path": "data/rubynation/rubynation-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubynation.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubynation/rubynation-2016/event.yml",
    "content": "---\nid: \"rubynation-2016\"\ntitle: \"RubyNation 2016\"\ndescription: \"\"\nlocation: \"Washington, DC\"\nkind: \"conference\"\nstart_date: \"2016-06-03\"\nend_date: \"2016-06-04\"\nwebsite: \"http://www.rubynation.org/\"\ntwitter: \"rubynation\"\ncoordinates:\n  latitude: 38.9071923\n  longitude: -77.0368707\n"
  },
  {
    "path": "data/rubynation/rubynation-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.rubynation.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubynation/rubynation-2017/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKX7QRIXzHyVOxq55dFfW3vf\"\ntitle: \"RubyNation 2017\"\ndescription: |-\n  June 16, 2017 - Arlington, Virginia\nlocation: \"Arlington, VA, United States\"\nkind: \"conference\"\nstart_date: \"2017-06-16\"\nend_date: \"2017-06-16\"\nyear: 2017\nchannel_id: \"UCgRpkkcigKZk52JyAOYNs6w\"\nwebsite: \"http://www.rubynation.org/\"\ntwitter: \"rubynation\"\nplaylist: \"https://www.youtube.com/playlist?list=PLvpu5WTDxTKX7QRIXzHyVOxq55dFfW3vf\"\ncoordinates:\n  latitude: 38.8816208\n  longitude: -77.09098089999999\n"
  },
  {
    "path": "data/rubynation/rubynation-2017/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: schedule website\n\n- id: \"polly-schandorf-rubynation-2017\"\n  title: \"Let's Get Creative with Arguments\"\n  raw_title: \"RubyNation 2017: Polly Schandorf - Let's Get Creative with Arguments\"\n  speakers:\n    - Polly Schandorf\n  event_name: \"RubyNation 2017\"\n  date: \"2017-06-16\"\n  published_at: \"2017-06-30\"\n  description: |-\n    Let's Get Creative with Arguments by Polly Schandorf\\n\\nWould you\n    like better error messages? Or methods that are clearer to the caller. How about\n    more flexibility ? Most of us have a preference for parameters, but sometimes\n    there are better options in certain circumstances. We’ll look at keyword arguments,\n    option hashes, splats and destructuring. \\n\\nIn her previous life, Polly was a\n    teacher of elementary through high school students. After being introduced to\n    coding using a Rasberry Pi in a teacher workshop - she was hooked, and never looked\n    back. She is totally fascinated with fermented foods and makes her own Kombucha,\n    Kefir and Red Wine Vinegar.\n  video_provider: \"youtube\"\n  video_id: \"bj6ocNQATdo\"\n\n- id: \"adam-cuppy-rubynation-2017\"\n  title: \"What if Shakespeare Wrote Ruby?\"\n  raw_title: \"RubyNation 2017: What if Shakespeare Wrote Ruby? by Adam Cuppy\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"RubyNation 2017\"\n  date: \"2017-06-16\"\n  published_at: \"2017-07-02\"\n  description: |-\n    What if Shakespeare Wrote Ruby?\n\n    Did you know that Shakespeare wrote almost no direction into his plays? No fight direction. No staging. No notes to the songs. Of the 1700 words he created, there was no official dictionary. That’s right the author of some of the greatest literary works in history, which were filled with situational complexity, fight sequences and music, include NO documentation! How did he do it?\n\n    In this talk, we’re going “thee and thou.” I’m going to give you a crash course in how: Shakespeare writes software.\n\n    Adam Cuppy is: Master of Smile Generation. Ambassador of Company Culture. Tech Entreprenur. Speaker/Educator. One-time Professional Actor @osfashland. Husband. Chief Zealous Officer @CodingZeal.\n  video_provider: \"youtube\"\n  video_id: \"lBzC14efRcY\"\n\n- id: \"david-bock-rubynation-2017\"\n  title: \"A Rubyist Takes a Look at Crystal\"\n  raw_title: \"RubyNation 2017: A Rubyist Takes a Look at Crystal by David Bock\"\n  speakers:\n    - David Bock\n  event_name: \"RubyNation 2017\"\n  date: \"2017-06-16\"\n  published_at: \"2017-07-01\"\n  description: |-\n    A Rubyist Takes a Look at Crystal by David Bock\n\n    Ruby syntax? Compiled? With strong typing? 2x4 times the performance? As an educator, I teach a lot of cool algorithmic stuff. As a rubyist, I want the syntax I know and love. As a computer scientist, this creates a tension over algorithmic performance. So I took a look at crystal and liked what I saw. Will you?\n\n    David Bock turned to programming Ruby full time in 2006, after an upstanding career using Java in the Federal Contracting space, and he has never looked back. He is now corrupting the minds of our youth by posing at a \"Teacher’s Assistant\" for a java-based high school curriculum, only to expose teenagers to Ruby and tempt them with the Dark Side of the Force. Dave is also the director of the Loudoun Computer Science Initiative.\n  video_provider: \"youtube\"\n  video_id: \"VgNN8iokc54\"\n\n- id: \"kerri-miller-rubynation-2017\"\n  title: \"Crescent Wrenches and Debuggers\"\n  raw_title: \"RubyNation 2017: Crescent Wrenches and Debuggers by Kerri Miller\"\n  speakers:\n    - Kerri Miller\n  event_name: \"RubyNation 2017\"\n  date: \"2017-06-16\"\n  published_at: \"2017-07-01\"\n  description: |-\n    Crescent Wrenches and Debuggers: Building Your Own Toolkit For Rational Inquiry by Kerri Miller\n\n    Software exists in a constant state of failure, facing pressure on many fronts - malicious intruders, hapless users, accidental features, and our own limits of imagination all conspire to bring our system to a screeching halt. Untangle even the most tangled of Gordian Knots by building your own toolkit for inquiry, by relying on the simplest technique of all: asking “why?”\n\n    This presentation will discuss the challenges and potential solutions for refreshing multiple application environments (Development/Staging/UAT/etc.) with data from a Production database, while keeping some amount of table data intact from the prior database after the Production restore.\n  video_provider: \"youtube\"\n  video_id: \"QqpIaKXDyBM\"\n\n- id: \"robert-mosolgo-rubynation-2017\"\n  title: \"Solving GraphQL's Challenges\"\n  raw_title: \"RubyNation 2017: Solving GraphQL’s Challenges by Robert Mosolgo\"\n  speakers:\n    - Robert Mosolgo\n  event_name: \"RubyNation 2017\"\n  date: \"2017-06-16\"\n  published_at: \"2017-07-01\"\n  description: |-\n    Solving GraphQL’s Challenges by Robert Mosolgo\n\n    GraphQL empowers your API clients by serving type-safe, predictable and flexible data from your application. JavaScript developers rejoice! But what about the server? Let’s explore GraphQL for Ruby servers. First, we’ll learn some GraphQL basics and see what it looks like to serve GraphQL from a Ruby app. Then, we’ll look at how we solve some web service challenges at GitHub: authentication, authorization and load management. We’ll see how these solutions compare to their REST equivalents and you’ll be ready to take GraphQL for a spin in your app!\n\n    Robert Mosolgo, works on GraphQL at GitHub. In open-source, you’ll find him poking around with APIs, compilers, and runtimes. Besides coding, he enjoys eating, growing plants, and spending time with his family.\n  video_provider: \"youtube\"\n  video_id: \"hCvczSqpdYs\"\n\n- id: \"katherine-mcclintic-rubynation-2017\"\n  title: \"SEO is Not a Four-Letter Word\"\n  raw_title: \"RubyNation 2017: SEO is Not a Four-Letter Word by Katherine McClintic\"\n  speakers:\n    - Katherine McClintic\n  event_name: \"RubyNation 2017\"\n  date: \"2017-06-16\"\n  published_at: \"2017-07-01\"\n  description: |-\n    SEO is Not a Four-Letter Word\n\n    How can your startup get more users to see your app in the first pages of Google results without spending money on advertising? Together we’ll walk through a way to create your own data structures for Google to consume using JSON-LD and the data you already have–no gems or cursing necessary.\n\n    About Katherine: I'm a history teacher turned developer currently working as a Software Engineer. I'm a proud native of Washington, DC, where I teach to learn as the Director of Education for Women Who Code DC. When I’m not bug hunting you’ll find me making awful puns, practicing the bodhran, and vociferously defending the Oxford comma.\n  video_provider: \"youtube\"\n  video_id: \"0eizbJQAzkA\"\n\n- id: \"sam-phippen-rubynation-2017\"\n  title: \"Type. Context.\"\n  raw_title: \"RubyNation 2017: Type. Context. by Sam Phippen\"\n  speakers:\n    - Sam Phippen\n  event_name: \"RubyNation 2017\"\n  date: \"2017-06-16\"\n  published_at: \"2017-07-01\"\n  description: |-\n    Type. Context. by Sam Phippen\n\n    Every language has at least one big idea behind it. In Ruby we cherish the powers of abstraction in the language and the conventions of Rails. Experienced Ruby programmers lean on these ideas without a thought. Imagine my surprise when I changed jobs, stopped programming Ruby full time, and those ideas were nowhere around.\n\n    This talk is the antidote to the “x language is cool talk”. It’s a talk where you’ll learn about the ideas behind a couple of current ‘hot’ languages. You’ll learn how new languages change the way you program. We’ll find some gaps in Ruby and bring some neat stuff back.\n\n    Sam Phippen is an Engineer at DigitalOcean, RSpec core team member, and all round Ruby aficionado. You may know him for being English, but he lives in New York City now. He’s sad that he can’t hug every cat.\n  video_provider: \"youtube\"\n  video_id: \"yY4TicWfczM\"\n\n- id: \"steve-hackley-rubynation-2017\"\n  title: \"Keeping Data and Integrations in Sync\"\n  raw_title: \"RubyNation 2017: Steve Hackley - Keeping Data and Integrations in Sync\"\n  speakers:\n    - Steve Hackley\n  event_name: \"RubyNation 2017\"\n  date: \"2017-06-16\"\n  published_at: \"2017-06-30\"\n  description: |-\n    Keeping Data and Integrations in Sync by Steve Hackley\n\n    This presentation will discuss the challenges and potential solutions for refreshing multiple application\n    environments (Development/Staging/UAT/etc.) with data from a Production database,\n    while keeping some amount of table data intact from the prior database after the\n    Production restore.\n    When not white boarding out solutions with his team, Steve Hackley can be found with the hiking boots on traversing the switchbacks of the Appalachian Trail, or cooking out on the deck at home. With almost 20 years of web development and management experience in all areas including pre-sales, strategy, consulting, operations, and development, Steve has been responsible for assembling and leading several development teams implementing various technologies ( .Net Stack, BI technologies, Ruby on Rails) for clients believing in the notion 'work smarter, not harder'.\n  video_provider: \"youtube\"\n  video_id: \"fpsY3RdGvBc\"\n\n- id: \"eileen-m-uchitelle-rubynation-2017\"\n  title: \"Building the Rails ActionDispatch::SystemTestCase Framework\"\n  raw_title: \"RubyNation 2017: Building the Rails ActionDispatch::SystemTestCase Framework by Eileen Uchitelle\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"RubyNation 2017\"\n  date: \"2017-06-16\"\n  published_at: \"2017-07-02\"\n  description: |-\n    Building the Rails ActionDispatch::SystemTestCase Framework\n\n    At the 2014 RailsConf DHH declared system testing would be added to Rails. Three years later, Rails 5.1 makes good on that promise by introducing a new testing framework: ActionDispatch::SystemTestCase. The feature brings system testing to Rails with zero application configuration by adding Capybara integration. After a demonstration of the new framework, we'll walk through what's uniquely involved with building OSS features & how the architecture follows the Rails Doctrine. We'll take a rare look at what it takes to build a major feature for Rails, including goals, design decisions, & roadblocks.\n\n    Eileen Uchitelle is a Senior Systems Engineer at GitHub where she works on improving the GitHub application, related systems, and the Ruby on Rails framework. Eileen is an avid contributor to open source and is a member of the Rails Core Team. She's passionate about performance, security, and getting new programmers contributing to OSS.\n  video_provider: \"youtube\"\n  video_id: \"gOoSKAiD-a8\"\n"
  },
  {
    "path": "data/rubynation/rubynation-2018/event.yml",
    "content": "---\nid: \"rubynation-2018\"\ntitle: \"RubyNation 2018\"\ndescription: \"\"\nlocation: \"Arlington, VA, United States\"\nkind: \"conference\"\nstart_date: \"2018-06-22\"\nend_date: \"2018-06-22\"\nwebsite: \"http://rubynation.org/\"\ntwitter: \"rubynation\"\ncoordinates:\n  latitude: 38.8816208\n  longitude: -77.09098089999999\n"
  },
  {
    "path": "data/rubynation/rubynation-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://rubynation.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubynation/series.yml",
    "content": "---\nname: \"RubyNation\"\nwebsite: \"http://www.rubynation.org/\"\ntwitter: \"rubynation\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyness/rubyness-2020/event.yml",
    "content": "---\nid: \"rubyness-2020\"\ntitle: \"RubyNess 2020 (Cancelled)\"\ndescription: \"\"\nlocation: \"Inverness, Scotland, UK\"\nkind: \"conference\"\nstart_date: \"2020-07-16\"\nend_date: \"2020-07-17\"\nwebsite: \"https://rubyness.org/\"\nstatus: \"cancelled\"\ntwitter: \"rubynessconf\"\ncoordinates:\n  latitude: 57.477773\n  longitude: -4.224721\n"
  },
  {
    "path": "data/rubyness/rubyness-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyness.org/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyness/series.yml",
    "content": "---\nname: \"RubyNess\"\nwebsite: \"https://rubyness.org/\"\ntwitter: \"rubynessconf\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2018/event.yml",
    "content": "---\nid: \"rubyrussia-2018\"\ntitle: \"RubyRussia 2018\"\ndescription: \"\"\nlocation: \"Moscow, Russia\"\nkind: \"conference\"\nstart_date: \"2018-10-06\"\nend_date: \"2018-10-06\"\nwebsite: \"https://rubyrussia.club/en\"\ntwitter: \"railsclub_ru\"\nplaylist: \"https://www.youtube.com/playlist?list=PLiWUIs1hSNeNz4UCJk9r-5nFklqvzL7vy\"\ncoordinates:\n  latitude: 55.7568721\n  longitude: 37.6150527\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyrussia.club/en\n# Videos: https://www.youtube.com/playlist?list=PLiWUIs1hSNeNz4UCJk9r-5nFklqvzL7vy\n---\n[]\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2019/event.yml",
    "content": "---\nid: \"rubyrussia-2019\"\ntitle: \"RubyRussia 2019\"\ndescription: \"\"\nlocation: \"Moscow, Russia\"\nkind: \"conference\"\nstart_date: \"2019-09-28\"\nend_date: \"2019-09-28\"\nwebsite: \"https://rubyrussia.club/en\"\ntwitter: \"railsclub_ru\"\nplaylist: \"https://www.youtube.com/playlist?list=PLiWUIs1hSNeP3xDhqfTVCXZd8_L07QZ2c\"\ncoordinates:\n  latitude: 55.7568721\n  longitude: 37.6150527\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyrussia.club/en\n# Videos: https://www.youtube.com/playlist?list=PLiWUIs1hSNeP3xDhqfTVCXZd8_L07QZ2c\n---\n[]\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2020/event.yml",
    "content": "---\nid: \"rubyrussia-2020\"\ntitle: \"RubyRussia 2020\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2020-11-13\"\nend_date: \"2020-11-15\"\nwebsite: \"https://rubyrussia.club\"\ntwitter: \"railsclub_ru\"\nplaylist: \"https://www.youtube.com/playlist?list=PLiWUIs1hSNeO_YkVRot6JOLgTVSH9uUEB\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyrussia.club\n# Videos: https://www.youtube.com/playlist?list=PLiWUIs1hSNeO_YkVRot6JOLgTVSH9uUEB\n---\n[]\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2021/event.yml",
    "content": "---\nid: \"rubyrussia-2021\"\ntitle: \"RubyRussia 2021\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2021-09-24\"\nend_date: \"2021-09-25\"\nwebsite: \"https://rubyrussia.club/\"\ntwitter: \"railsclub_ru\"\nplaylist: \"https://www.youtube.com/playlist?list=PLiWUIs1hSNeMfiEGak_zwF_ULP8Rc6HcL\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2021/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyrussia.club/\n# Videos: https://www.youtube.com/playlist?list=PLiWUIs1hSNeMfiEGak_zwF_ULP8Rc6HcL\n---\n[]\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2023/event.yml",
    "content": "---\nid: \"rubyrussia-2023\"\ntitle: \"RubyRussia 2023\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2023-09-30\"\nend_date: \"2023-09-30\"\nwebsite: \"https://rubyrussia.club/\"\ntwitter: \"railsclub_ru\"\nplaylist: \"https://www.youtube.com/watch?v=1bN2uBDylQU\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2023/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyrussia.club/\n# Videos: https://www.youtube.com/watch?v=1bN2uBDylQU\n---\n[]\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2024/event.yml",
    "content": "---\nid: \"rubyrussia-2024\"\ntitle: \"RubyRussia 2024\"\ndescription: \"\"\nlocation: \"Moscow, Russia\"\nkind: \"conference\"\nstart_date: \"2024-10-02\"\nend_date: \"2024-10-02\"\nwebsite: \"https://rubyrussia.club/\"\ntwitter: \"railsclub_ru\"\ncoordinates:\n  latitude: 55.7568721\n  longitude: 37.6150527\n"
  },
  {
    "path": "data/rubyrussia/rubyrussia-2024/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://rubyrussia.club/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyrussia/series.yml",
    "content": "---\nname: \"RubyRussia\"\nwebsite: \"https://rubyrussia.club/en\"\ntwitter: \"railsclub_ru\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyrx/rubyrx-2009-philadelphia/event.yml",
    "content": "---\nid: \"rubyrx-2009-philadelphia\"\ntitle: \"RubyRx 2009 (Philadelphia)\"\ndescription: \"\"\nlocation: \"Philadelphia, PA, United States\"\nkind: \"conference\"\nstart_date: \"2009-07-30\"\nend_date: \"2009-08-01\"\noriginal_website: \"http://www.nfjsone.com/conference/philadelphia/2009/07/home\"\ncoordinates:\n  latitude: 39.9525839\n  longitude: -75.1652215\n"
  },
  {
    "path": "data/rubyrx/rubyrx-2009-philadelphia/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rubyrx/rubyrx-2009-washington-dc/event.yml",
    "content": "---\nid: \"rubyrx-2009-washington-dc\"\ntitle: \"RubyRx 2009 (Washington DC)\"\ndescription: \"\"\nlocation: \"Washington, DC\"\nkind: \"conference\"\nstart_date: \"2009-09-10\"\nend_date: \"2009-09-11\"\noriginal_website: \"http://www.nfjsone.com/conference/washington_dc/2009/09/home\"\ncoordinates:\n  latitude: 38.9071923\n  longitude: -77.0368707\n"
  },
  {
    "path": "data/rubyrx/rubyrx-2009-washington-dc/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rubyrx/series.yml",
    "content": "---\nname: \"RubyRx\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"US\"\naliases:\n  - Ruby Rx\n"
  },
  {
    "path": "data/rubysauna/rubysauna-2014/event.yml",
    "content": "---\nid: \"rubysauna-2014\"\ntitle: \"RubySauna 2014\"\ndescription: \"\"\nlocation: \"Oulu, Finland\"\nkind: \"conference\"\nstart_date: \"2014-02-27\"\nend_date: \"2014-02-27\"\nwebsite: \"http://web.archive.org/web/20140213081334/http://www.rubysauna.org:80/\"\ncoordinates:\n  latitude: 65.0120888\n  longitude: 25.4650773\n"
  },
  {
    "path": "data/rubysauna/rubysauna-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://web.archive.org/web/20140213081334/http://www.rubysauna.org:80/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubysauna/series.yml",
    "content": "---\nname: \"RubySauna\"\nwebsite: \"http://web.archive.org/web/20140213081334/http://www.rubysauna.org:80/\"\ntwitter: \"rubysauna\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2018/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKWA9z0jSc0gAvQ-wH00Rs5T\"\ntitle: \"Ruby Unconf 2018\"\nkind: \"conference\"\nlocation: \"Hamburg, Germany\"\ndescription: |-\n  Ruby Unconf 2018 in Hamburg, Germany. May 5th and May 6th 2018\npublished_at: \"2018-05-05\"\nstart_date: \"2018-05-05\"\nend_date: \"2018-05-06\"\nchannel_id: \"UCnl2p1jpQo4ITeFq4yqmVuA\"\nyear: 2018\nbanner_background: \"#DBD4C4\"\nfeatured_background: \"#DBD4C4\"\nfeatured_color: \"#5C4594\"\nwebsite: \"https://2018.rubyunconf.eu/\"\ncoordinates:\n  latitude: 53.5488282\n  longitude: 9.987170299999999\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2018/videos.yml",
    "content": "---\n# TODO: conference website\n\n# Schedule: https://docs.google.com/spreadsheets/d/1SH3ujYbBMPPICPZTqR6A2vVUGvAnBAv5ZqdzWBKSOn4\n\n# Day 1\n\n# emacs track\n- id: \"aaron-patterson-ruby-unconf-2018\"\n  title: \"Keynote: Reducing Memory Usage\"\n  raw_title: \"Keynote Speech: Aaron Patterson\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-06-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8kdfKInkENI\"\n\n# emacs track\n- id: \"kerstin-puschke-ruby-unconf-2018\"\n  title: \"Background Jobs at Scale\"\n  raw_title: \"Background Jobs at Scale talk by Kerstin Puschke\"\n  speakers:\n    - Kerstin Puschke\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"PFviclwil20\"\n\n# vim track\n- id: \"tobias-meyer-ruby-unconf-2018\"\n  title: \"Building Confidence on a Docker Devbox\"\n  raw_title: \"Talk by Tobias Meyer - Building Confidence on a Docker Devbox\"\n  speakers:\n    - Tobias Meyer\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"HH4Sy_oNa9U\"\n\n# emacs track\n- id: \"tobias-schwab-ruby-unconf-2018\"\n  title: \"The (even longer) Road from Capistrano to Kubernetes\"\n  raw_title: \"The (even longer) Road from Capistrano to Kubernetes: Talk By Tobias Schwab\"\n  speakers:\n    - Tobias Schwab\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"NrFTEd8RVOE\"\n\n# vim track\n- id: \"julia-hurrelmann-ruby-unconf-2018\"\n  title: \"The Importance of Cross Cultural Competency\"\n  raw_title: \"Talk by Julia Hurrelmann - The Importance of Cross Cultural Competency\"\n  speakers:\n    - Julia Hurrelmann\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"s73M1sWRaMI\"\n\n# emacs track\n- id: \"jan-lelis-ruby-unconf-2018\"\n  title: \"Ruby is Full of Surprises\"\n  raw_title: \"Ruby is Full of Surprises: Talk by Jan Lelis\"\n  speakers:\n    - Jan Lelis\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"tPpvxN-Kqj4\"\n\n# vim track\n- id: \"sergio-gil-perez-de-la-manga-ruby-unconf-2018\"\n  title: \"Understanding Unix Pipes with Ruby\"\n  raw_title: \"Talk by Sergio Gil Pérez de la Manga - Understanding Unix Pipes with Ruby\"\n  speakers:\n    - Sergio Gil Pérez de la Manga\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-06-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"NLheas7jQ-U\"\n\n# emacs track\n- id: \"andreas-finger-ruby-unconf-2018\"\n  title: \"RabbitMQ to the Rescue\"\n  raw_title: \"RabbitMQ to the Rescue: Talk By Andreas Finger\"\n  speakers:\n    - Andreas Finger\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-05-30\"\n  description: |-\n    Please visit https://github.com/mediafinger/rabbitmq_presentation/ for the slides' text and some example apps.\n  video_provider: \"youtube\"\n  video_id: \"eJhxlVkGXdQ\"\n  additional_resources:\n    - name: \"mediafinger/rabbitmq_presentation\"\n      type: \"repo\"\n      url: \"https://github.com/mediafinger/rabbitmq_presentation/\"\n\n# vim track\n# missing talk: Cultural Bias in UX Design - Gerrit Bruno Blöss\n\n# emacs track\n- id: \"ana-mara-martnez-gmez-ruby-unconf-2018\"\n  title: \"Property Testing\"\n  raw_title: \"Property Testing:Talk by Ana Maria Martinez Gomez\"\n  speakers:\n    - Ana María Martínez Gómez\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-06-01\"\n  description: \"\"\n  slides_url: \"https://2018.rubyunconf.eu/uploads/PropertyTests-Ana-UNCONF-HAMBURG.odp\"\n  video_provider: \"youtube\"\n  video_id: \"FSrNXI1SyCg\"\n\n# vim track\n- id: \"florian-munz-ruby-unconf-2018\"\n  title: \"Updating Depencencies Sucks, So Let's Do That More Often\"\n  raw_title: \"Talk by Florian: Updating depencencies sucks, so let's do that more often\"\n  speakers:\n    - Florian Munz\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-06-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"g_SIUxa39WI\"\n\n# 1st floor track\n# missing workshop: \"Workshop: Getting Your Feet Wet With Elm - Andy\n\n# emacs track\n- id: \"robin-drexler-ruby-unconf-2018\"\n  title: \"How to Speed Up Websites with Resource Hints\"\n  raw_title: \"Robin Drexler: How to speed up websites with Resource hints\"\n  speakers:\n    - Robin Drexler\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-06-01\"\n  description: |-\n    preconnect, prefetch, preload, pre-what? How to speed up websites with Resource hints\n  video_provider: \"youtube\"\n  video_id: \"V3mQatuVZLY\"\n\n# vim track\n- id: \"filipe-abreu-ruby-unconf-2018\"\n  title: \"Cached Rest Models\"\n  raw_title: \"Talk by Filipe: Cached Rest Models\"\n  speakers:\n    - Filipe Abreu\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-05\"\n  published_at: \"2018-06-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"y0fRAMk1cHQ\"\n\n# Day 2\n\n# emacs track:\n# missing talk: A MP3 player for very small, small and big kids - Christoph Eicke\n# slides_url: https://2018.rubyunconf.eu/uploads/Norbert.pdf\n\n# vim track\n- id: \"stefan-exner-ruby-unconf-2018\"\n  title: 'Petra \"Yeah I''ll Commit That Later\"'\n  raw_title: 'Talk by  Stefan Exner: petra \"Yeah I''ll commit that later\"'\n  speakers:\n    - Stefan Exner\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-06-01\"\n  description: |-\n    Slides:\n\n    https://gitpitch.com/stex/petra-rails_demo/master\n\n    The mentioned examples and demo application can be found at\n\n    https://github.com/stex/petra-rails_demo\n  video_provider: \"youtube\"\n  video_id: \"UGo1dL8i4Jo\"\n  additional_resources:\n    - name: \"stex/petra-rails_demo\"\n      type: \"repo\"\n      url: \"https://github.com/stex/petra-rails_demo\"\n\n# emacs track\n- id: \"ole-michaelis-ruby-unconf-2018\"\n  title: \"It Looks Like Ruby, But It Doesn't Quack\"\n  raw_title: \"Talk by Ole Michaelis: It looks like Ruby, but it doesn''t quack\"\n  speakers:\n    - Ole Michaelis\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-06-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"InIFQ9m17Xo\"\n\n# vim track\n- id: \"darius-murawski-ruby-unconf-2018\"\n  title: \"Seeding in a Microservice Architecture'\"\n  raw_title: \"Talk by Darius Murawski: Seeding in a Microservice Architecture\"\n  speakers:\n    - Darius Murawski\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-06-01\"\n  description: \"\"\n  slides_url: \"https://2018.rubyunconf.eu/uploads/Seeding_in_a_microservice_architecture.pdf\"\n  video_provider: \"youtube\"\n  video_id: \"TYQsniXUbZE\"\n\n# emacs track\n# missing talk: The basic income experience - Ariane\n\n# vim track\n- id: \"fabian-afknapping-ruby-unconf-2018\"\n  title: \"Talk/Workshop: UX Sketching 101\"\n  raw_title: \"Talk/Workshop by Fabian: UX Sketching 101\"\n  speakers:\n    - Fabian (afknapping)\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-06-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8JGrDZUA498\"\n\n# emacs track\n- id: \"sergio-gil-ruby-unconf-2018\"\n  title: \"The Crystal Language from ~Scratch~\"\n  raw_title: \"Talk by Sérgio Gil: The Crystal Language from ~scratch~\"\n  speakers:\n    - Sérgio Gil\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-06-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"NjkuYfGV9jU\"\n\n# vim track\n- id: \"patryk-pastewski-ruby-unconf-2018\"\n  title: \"Find a bAr with the Power of PostGIS\"\n  raw_title: \"Talk by  Patryk Pastewski: Find a bar with the power of PostGIS\"\n  speakers:\n    - Patryk Pastewski\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-06-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FnzgLnaCxXU\"\n\n# emacs track\n# missing talk: Lightning Talk 1\n\n# emacs track\n- id: \"janusz-mordarski-ruby-unconf-2018\"\n  title: \"Lightning Talk: Profiling Ruby with Flamegraphs\"\n  raw_title: \"Lightning Talk 2: Janusz Mordarski - Profiling Ruby with Flamegraphs\"\n  speakers:\n    - Janusz Mordarski\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ZLt7Ir4UzFs\"\n\n# emacs track\n- id: \"amr-abdelwahab-ruby-unconf-2018\"\n  title: \"Lightning Talk: An Empathy Exercise\"\n  raw_title: \"Lightning Talk 3: Amr Abdelwahab - An Empathy Exercise\"\n  speakers:\n    - Amr Abdelwahab\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  slides_url: \"https://prezi.com/view/QB1AL4r0uwEZ1tuqsf5v/\"\n  video_provider: \"youtube\"\n  video_id: \"j4ro5uJ8yzE\"\n\n# emacs track\n- id: \"julia-hurrelmann-ruby-unconf-2018-lightning-talk-how-to-increase\"\n  title: \"Lightning Talk: How To Increase Diversity in Your Engineering Teams\"\n  raw_title: \"Lightning Talk 4: Julia Hurrelmann - How to increase diversity in your engineering teams\"\n  speakers:\n    - Julia Hurrelmann\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"cPXNIVMfLZg\"\n\n# emacs track\n# missing talk: Lightning Talk 5\n\n# emacs track\n- id: \"ana-mara-martnez-gmez-ruby-unconf-2018-lightning-talk-open-source\"\n  title: \"Lightning Talk: Open Source\"\n  raw_title: \"Lightning Talk 6: Ana Maria Martinez Gomez - Open Source\"\n  speakers:\n    - Ana María Martínez Gómez\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  slides_url: \"https://2018.rubyunconf.eu/uploads/OpenSource-Ana-UNCONF-HAMBURG.odp\"\n  video_provider: \"youtube\"\n  video_id: \"B-eIchAJBa0\"\n\n# emacs track\n- id: \"fabian-afknapping-ruby-unconf-2018-lightning-talk-a-thing-i-hacke\"\n  title: \"Lightning Talk: A Thing I Hacked For Contriboot Yesterday\"\n  raw_title: \"Lightning Talk 7: Fabian - A thing I hacked for Contriboot yesterday\"\n  speakers:\n    - Fabian (afknapping)\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"E2a-W57dRAU\"\n\n# emacs track\n- id: \"daniel-carral-ruby-unconf-2018\"\n  title: \"Lightning Talk: Random Experiment by a Random Potential Speaker\"\n  raw_title: \"Lightning Talk 8: Daniel Carral - Random Experiment by a Random Potential Speaker\"\n  speakers:\n    - Daniel Carral\n  event_name: \"Ruby Unconf 2018\"\n  date: \"2018-05-06\"\n  published_at: \"2018-05-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"8G_e-pPHURU\"\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2019/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKVC08sqymaBAEDKoVkJG3pr\"\ntitle: \"Ruby Unconf 2019\"\nkind: \"conference\"\nlocation: \"Hamburg, Germany\"\ndescription: |-\n  Ruby Unconf 2019 in Hamburg, Germany. May 25th and May 26th 2019\npublished_at: \"2019-05-25\"\nstart_date: \"2019-05-25\"\nend_date: \"2019-05-26\"\nchannel_id: \"UCnl2p1jpQo4ITeFq4yqmVuA\"\nyear: 2019\nbanner_background: \"#DBD4C4\"\nfeatured_background: \"#DBD4C4\"\nfeatured_color: \"#5C4594\"\nwebsite: \"https://2019.rubyunconf.eu/\"\ncoordinates:\n  latitude: 53.5688823\n  longitude: 10.0330191\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2019/venue.yml",
    "content": "# https://2019.rubyunconf.eu/#venue\n---\nname: \"HAW Hamburg, Campus Finkenau\"\n\ndescription: |-\n  Hamburg University of Applied Sciences, Faculty of Design, Media and Information.\n\naddress:\n  street: \"Finkenau 35\"\n  city: \"Hamburg\"\n  region: \"Hamburg\"\n  postal_code: \"22081\"\n  country: \"Germany\"\n  country_code: \"DE\"\n  display: \"Finkenau 35, 22081 Hamburg, Germany\"\n\ncoordinates:\n  latitude: 53.5688823\n  longitude: 10.0330191\n\nmaps:\n  google: \"https://maps.google.com/?q=HAW+Hamburg+Finkenau,53.5688823,10.0330191\"\n  apple: \"https://maps.apple.com/?q=HAW+Hamburg+Finkenau&ll=53.5688823,10.0330191\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=53.5688823&mlon=10.0330191\"\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2019/videos.yml",
    "content": "---\n# TODO: conference website\n\n# Schedule: https://docs.google.com/spreadsheets/d/1YLiU9QU6HH_MaRT-zh_yJf6pQfUdYk59plJUwaOWciE\n\n# Day 1\n\n# emacs Track\n- id: \"terence-lee-ruby-unconf-2019\"\n  title: \"Keynote: Progress\"\n  raw_title: \"Ruby Unconf 2019 Keynote Speech by Terence Lee\"\n  speakers:\n    - Terence Lee\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"I9aip9qoXew\"\n\n# emacs Track\n- id: \"amina-adewusi-ruby-unconf-2019\"\n  title: \"Death Laughter & Extreme Programming\"\n  raw_title: \"Amina Adewusi @ Ruby Unconf 2019: Death Laughter & Extreme Programming\"\n  speakers:\n    - Amina Adewusi\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-06-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"bNg6zMiOOR8\"\n\n# vim Track\n- id: \"bente-pieck-ruby-unconf-2019\"\n  title: \"A brief Introduction of Kubernetes\"\n  raw_title: \"Bente Pieck @ Ruby Unconf 2019: A brief Introduction of Kubernetes\"\n  speakers:\n    - Bente Pieck\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"cQPTF7zERvk\"\n\n# emacs Track\n- id: \"torsten-rger-ruby-unconf-2019\"\n  title: \"Compiling Ruby to Binary\"\n  raw_title: \"Torsten Rüger @ Ruby Unconf 2019: Compiling Ruby to binary\"\n  speakers:\n    - Torsten Rüger\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ojW-q_wiSn8\"\n\n# vim Track\n- id: \"andreas-finger-ruby-unconf-2019\"\n  title: \"Settings - A clean way to handle custom configuration values\"\n  raw_title: \"Andreas Finger @ Ruby Unconf 2019: Settings\"\n  speakers:\n    - Andreas Finger\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-06-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"jRByM1rZLXM\"\n\n# emacs Track\n- id: \"jonas-jabari-ruby-unconf-2019\"\n  title: \"Easily Create Interactive UIs in Pure Ruby\"\n  raw_title: \"Jonas Jabari @ Ruby Unconf 2019: Easily create interactive UIs in pure ruby\"\n  speakers:\n    - Jonas Jabari\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"OY5AeGhgK7I\"\n\n# vim Track\n- id: \"sven-dittmer-ruby-unconf-2019\"\n  title: '\"👨‍👩‍👧‍👧\".length == 7'\n  raw_title: 'Sven Dittmer @ Ruby Unconf 2019: \"👨‍👩‍👧‍👧\".length == 7'\n  speakers:\n    - Sven Dittmer\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-06-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"mJkzMoEd_Wo\"\n\n# emacs Track\n- id: \"sergey-dolganov-ruby-unconf-2019\"\n  title: \"Building Resilient API Dependency\"\n  raw_title: \"Sergey Dolganov @ Ruby Unconf 2019:  Building Resilient API Dependency\"\n  speakers:\n    - Sergey Dolganov\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-07-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6gOV6WbvksQ\"\n\n# vim Track\n# Missing discussion: Fishbowl Discussion: Estimates? No Estimates? - by Tina\n\n# emacs Track\n- id: \"iulia-costea-ruby-unconf-2019\"\n  title: \"Why Soft Skills Matter in Software Development\"\n  raw_title: \"Iulia Costea @ Ruby Unconf 2019: Why Soft Skills Matter in Software Development\"\n  speakers:\n    - Iulia Costea\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"YAZC8NEJQ_w\"\n\n# vim Track\n- id: \"patrick-franken-ruby-unconf-2019\"\n  title: \"Open Source Nightmare\"\n  raw_title: \"Patrick Franken @ Ruby Unconf 2019: Open Source Nightmare\"\n  speakers:\n    - Patrick Franken\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"XSrYfXDoXNc\"\n\n# emacs Track\n- id: \"matheus-mina-ruby-unconf-2019\"\n  title: \"Functional Programming in Ruby\"\n  raw_title: \"Functional Programming in Ruby - by Matheus\"\n  speakers:\n    - Matheus Mina\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-25\"\n  published_at: \"2019-09-17\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Rg5nPwgIo90\"\n\n# vim Track\n# Missing discussion: Fishbowl Discussion: Freelance Tools/Setup - by Ramon\n\n# Day 2\n\n# emacs Track\n- id: \"denys-yahofarov-ruby-unconf-2019\"\n  title: \"How Do I Review The Code\"\n  raw_title: \"Denys Yahofarov @ Ruby Unconf 2019: How do I review the code\"\n  speakers:\n    - Denys Yahofarov\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5FUrNaoEImI\"\n\n# vim Track\n- id: \"paul-martensen-ruby-unconf-2019\"\n  title: \"Rust for Rubyists (and Rubyists for Rust)!\"\n  raw_title: \"Paul Martensen @ Ruby Unconf 2019: Rust for Rubyists (and Rubyists for Rust)!\"\n  speakers:\n    - Paul Martensen\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"m3HpNs-_MVI\"\n\n# emacs Track\n- id: \"stefan-exner-ruby-unconf-2019\"\n  title: \"I can't believe it's not an attribute!\"\n  raw_title: 'Stefan Exner @ Ruby Unconf 2019: \"I can''t believe it''s not an attribute!\"'\n  speakers:\n    - Stefan Exner\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"AFw9__q0Weg\"\n\n# vim Track\n- id: \"benjamin-vetter-ruby-unconf-2019\"\n  title: \"search_flip - Full featured ElasticSearch Ruby Client\"\n  raw_title: \"Benjamin Vetter @ Ruby Unconf 2019: search_flip - Full featured ElasticSearch Ruby Client\"\n  speakers:\n    - Benjamin Vetter\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"-fVabmi8C-I\"\n\n# emacs Track\n- id: \"daniel-neagaru-ruby-unconf-2019\"\n  title: \"Attacking own APIs to find security bugs\"\n  raw_title: \"Daniel Neagaru @ Ruby Unconf 2019:  Attacking own APIs to find security bugs\"\n  speakers:\n    - Daniel Neagaru\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"lGDETbe0b6w\"\n\n# vim Track\n- id: \"elizabeth-orwig-ruby-unconf-2019\"\n  title: \"Rails Slim, An Introduction\"\n  raw_title: \"Elizabeth Orwig @ Ruby Unconf 2019: Rails Slim, An Introduction\"\n  speakers:\n    - Elizabeth Orwig\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"HqzSLVOwdnY\"\n\n# emacs Track\n- id: \"dvid-halsz-ruby-unconf-2019\"\n  title: \"How to Hijack, Proxy and Smuggle Sockets with Rack/Ruby\"\n  raw_title: \"Dávid Halász: How to hijack, proxy and smuggle sockets with Rack/Ruby @ RubyUnconf 2019 in Hamburg\"\n  speakers:\n    - Dávid Halász\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-28\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ghs6uoPAuMQ\"\n\n# vim Track\n- id: \"gharbi-mohammed-ruby-unconf-2019\"\n  title: \"Component-Based Rails Applications\"\n  raw_title: \"Gharbi Mohammed @ Ruby Unconf 2019: Component-Based Rails Applications\"\n  speakers:\n    - Gharbi Mohammed\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-29\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"mQignvxjVXY\"\n\n# emacs Track\n- id: \"tobias-schulz-hess-ruby-unconf-2019\"\n  title: \"Lightning Talk: Tracking Your Professional Life\"\n  raw_title: \"Lightning Talk 1 @ Ruby Unconf 2019: Tracking Your Professional Life\"\n  speakers:\n    - Tobias Schulz-Hess\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"JHY3EstvTkM\"\n\n# emacs Track\n- id: \"yuri-veremeyenko-ruby-unconf-2019\"\n  title: \"Lightning Talk: Price Explorer - Bringing Transparency\"\n  raw_title: \"Lightning Talk 2 @ Ruby Unconf 2019. Price Explorer: Bringing Transparency to Real Estate Prices\"\n  speakers:\n    - Yuri Veremeyenko\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"L7NGTA00nVA\"\n\n# emacs Track\n- id: \"yevhenii-yevtushenko-ruby-unconf-2019\"\n  title: \"Lightning Talk: Keep Calm and Stay in VOIP Context\"\n  raw_title: \"Lightning Talk 3 @ Ruby Unconf 2019: Keep Calm and Stay in VOIP Context\"\n  speakers:\n    - Yevhenii Yevtushenko\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"w-D4J9RYDKA\"\n\n# emacs Track\n- id: \"pratvrirash-ruby-unconf-2019\"\n  title: \"Lightning Talk: Get the most out of your postgres instance with pghero\"\n  raw_title: \"Lightning Talk 4 @ Ruby Unconf 2019: Get the most out of your postgres instance with pghero\"\n  speakers:\n    - Pratvrirash\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"YA_Svfd436I\"\n\n# emacs Track\n- id: \"yonatan-miller-ruby-unconf-2019\"\n  title: \"Lightning Talk: Organizing Ourselves\"\n  raw_title: \"Lightning Talk 5 @ Ruby Unconf 2019: Organizing Ourselves\"\n  speakers:\n    - Yonatan Miller\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"i0BYyKSFkG8\"\n\n# emacs Track\n- id: \"ole-michaelis-ruby-unconf-2019\"\n  title: \"Lightning Talk: Creating the Perfect Slide Deck in 5 Minutes\"\n  raw_title: \"Lightning Talk 6 @ Ruby Unconf 2019: Creating the Perfect Slide Deck in 5 Minutes\"\n  speakers:\n    - Ole Michaelis\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"7rSfgAn8auA\"\n\n# emacs Track\n- id: \"todo-ruby-unconf-2019\"\n  title: \"Lightning Talk: Go, The Programming Language, Not the Game\"\n  raw_title: \"Lightning Talk 7 @ Ruby Unconf 2019: Go, The Programming Language, Not the Game\"\n  speakers:\n    - TODO\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"a_M7WsUdquk\"\n\n# emacs Track\n- id: \"josef-lika-ruby-unconf-2019\"\n  title: 'Lightning Talk: Implementation of the language \"Josef\" in Ruby'\n  raw_title: 'Lightning Talk 8 @ Ruby Unconf 2019: Implementation of the language \"Josef\" in Ruby'\n  speakers:\n    - Josef Liška\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FF7Il5T3MKQ\"\n\n# emacs Track\n- id: \"janusz-mordarski-ruby-unconf-2019\"\n  title: \"Lightning Talk: Turning Web Servers into Workers\"\n  raw_title: \"Lightning Talk 9 @ Ruby Unconf 2019: Turning Web Servers into Workers\"\n  speakers:\n    - Janusz Mordarski\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-06-30\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"mmdLC_K8JyE\"\n\n# emacs Track\n- id: \"dolganov-sergey-ruby-unconf-2019\"\n  title: \"Lightning Talk: Working Remotely Martians Style\"\n  raw_title: \"Lightning Talk 10 @ Ruby Unconf 2019: Working Remotely Martians Style\"\n  speakers:\n    - Dolganov Sergey\n  event_name: \"Ruby Unconf 2019\"\n  date: \"2019-05-26\"\n  published_at: \"2019-07-01\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"TPy7LqZrLHQ\"\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2020/event.yml",
    "content": "---\nid: \"rubyunconf-2020\"\ntitle: \"Ruby Unconf 2020 (Cancelled)\"\ndescription: \"\"\nlocation: \"Hamburg, Germany\"\nkind: \"conference\"\nstart_date: \"2020-06-06\"\nend_date: \"2020-06-07\"\nwebsite: \"https://2020.rubyunconf.eu/\"\nstatus: \"cancelled\"\ncoordinates:\n  latitude: 53.5488282\n  longitude: 9.987170299999999\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2020.rubyunconf.eu/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2023/event.yml",
    "content": "---\nid: \"rubyunconf-2023\"\ntitle: \"Ruby Unconf 2023\"\ndescription: \"\"\nlocation: \"Hamburg, Germany\"\nkind: \"conference\"\nstart_date: \"2023-06-10\"\nend_date: \"2023-06-11\"\nwebsite: \"https://2023.rubyunconf.eu\"\ncoordinates:\n  latitude: 53.5688823\n  longitude: 10.0330191\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2023/venue.yml",
    "content": "# https://2023.rubyunconf.eu/#location\n---\nname: \"HAW Hamburg, Campus Finkenau\"\n\ndescription: |-\n  Hamburg University of Applied Sciences, Faculty of Design, Media and Information.\n\naddress:\n  street: \"Finkenau 35\"\n  city: \"Hamburg\"\n  region: \"Hamburg\"\n  postal_code: \"22081\"\n  country: \"Germany\"\n  country_code: \"DE\"\n  display: \"Finkenau 35, 22081 Hamburg, Germany\"\n\ncoordinates:\n  latitude: 53.5688823\n  longitude: 10.0330191\n\nmaps:\n  google: \"https://maps.google.com/?q=HAW+Hamburg+Finkenau,53.5688823,10.0330191\"\n  apple: \"https://maps.apple.com/?q=HAW+Hamburg+Finkenau&ll=53.5688823,10.0330191\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=53.5688823&mlon=10.0330191\"\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2023/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2023.rubyunconf.eu\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2024/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKVWSm0O7wsAyxRDF_gBsBrP\"\ntitle: \"Ruby Unconf 2024\"\nkind: \"conference\"\nlocation: \"Hamburg, Germany\"\ndescription: |-\n  Ruby Unconf 2024 in Hamburg, Germany. June 8th & June 9th 2024\npublished_at: \"2024-06-08\"\nstart_date: \"2024-06-08\"\nend_date: \"2024-06-09\"\nchannel_id: \"UCnl2p1jpQo4ITeFq4yqmVuA\"\nyear: 2024\nbanner_background: \"#FCE9E9\"\nfeatured_background: \"#FCE9E9\"\nfeatured_color: \"#5C4594\"\ncoordinates:\n  latitude: 53.5688823\n  longitude: 10.0330191\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2024/venue.yml",
    "content": "---\nname: \"HAW Hamburg, Campus Finkenau\"\n\ndescription: |-\n  Hamburg University of Applied Sciences, Faculty of Design, Media and Information.\n\naddress:\n  street: \"Finkenau 35\"\n  city: \"Hamburg\"\n  region: \"Hamburg\"\n  postal_code: \"22081\"\n  country: \"Germany\"\n  country_code: \"DE\"\n  display: \"Finkenau 35, 22081 Hamburg, Germany\"\n\ncoordinates:\n  latitude: 53.5688823\n  longitude: 10.0330191\n\nmaps:\n  google: \"https://maps.google.com/?q=HAW+Hamburg+Finkenau,53.5688823,10.0330191\"\n  apple: \"https://maps.apple.com/?q=HAW+Hamburg+Finkenau&ll=53.5688823,10.0330191\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=53.5688823&mlon=10.0330191\"\n"
  },
  {
    "path": "data/rubyunconf/rubyunconf-2024/videos.yml",
    "content": "---\n# https://docs.google.com/spreadsheets/d/1oecmEFCue9jNs4PuLBrs99WMLrifxzTHrT_wVJTJ3mE/edit?gid=0#gid=0\n\n## Day 1 - 2024-06-08\n\n# Registration & Breakfast\n\n# Welcome\n\n# Proposals & Voting\n\n- title: \"Keynote: The Magic of Rails\"\n  raw_title: \"Keynote\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-08\"\n  published_at: \"2025-01-27\"\n  description: |-\n    Keynote by Eileen Uchitelle at the Ruby Unconf 2024 in Hamburg, Germany\n  video_provider: \"youtube\"\n  video_id: \"r9Q5yyeH_zo\"\n  id: \"keynote-the-magic-of-rails-ruby-unconf-2024\"\n  slug: \"keynote-the-magic-of-rails-ruby-unconf-2024\"\n\n- id: \"alexander-sulim-ruby-unconf-2024\"\n  title: \"Laziness Driven Development\"\n  raw_title: \"Laziness driven development by Alexander Sulim\"\n  speakers:\n    - Alexander Sulim\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-08\"\n  published_at: \"2024-10-18\"\n  description: |-\n    Alexander Sulim: \"Laziness-driven development is a set of rules that might help anyone to harness great power of laziness to create better software. Some of these rules are obvious, some might be controversial, but they all are based on personal experience and serve me well for many years already.\"\n  video_provider: \"youtube\"\n  video_id: \"LfYeO5hW3fA\"\n\n- id: \"ole-michaelis-ruby-unconf-2024\"\n  title: \"Fish Bowl: Ruby is Dying\"\n  raw_title: \"Fish Bowl Discussion: Ruby is dying by Ole Michaelis\"\n  speakers:\n    - Ole Michaelis\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-08\"\n  published_at: \"2024-10-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"15oe92S4hkw\"\n\n# Lunch Break\n\n- id: \"jochen-lillich-ruby-unconf-2024\"\n  title: \"Infrastructure as Ruby Code\"\n  raw_title: \"Infrastructure as Ruby Code by Jochen Lillich\"\n  speakers:\n    - Jochen Lillich\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-08\"\n  published_at: \"2024-10-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"KuocghIxvFE\"\n\n- id: \"nina-siessegger-ruby-unconf-2024\"\n  title: \"When Software Development Teams Grow Too Big - Learnings From Slicing Teams\"\n  raw_title: \"Nina Siessegger - When software development teams grow too big - learnings from slicing teams\"\n  speakers:\n    - Nina Siessegger\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-08\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"nina-siessegger-ruby-unconf-2024\"\n\n# Family Photo\n\n# Coffee & Cake\n\n- id: \"joschka-schulz-ruby-unconf-2024\"\n  title: \"From Pico Ruby to Twitch\"\n  raw_title: \"Joschka Schulz - From Pico Ruby to Twitch\"\n  speakers:\n    - Joschka Schulz\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-08\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"joschka-schulz-ruby-unconf-2024\"\n\n- id: \"iratxe-garrido-ruby-unconf-2024\"\n  title: \"Panel: How To Find a Job as a Ruby Developer\"\n  raw_title: \"Panel   How to find a job as a ruby developer by Iratxe and Nina\"\n  speakers:\n    - Iratxe Garrido\n    # - Tobias # TODO: missing last name\n    - Eileen M. Uchitelle\n    - Kaja Santro\n    # - Nina # TODO: missing last name\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-08\"\n  published_at: \"2024-10-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"sCfVTYgSKVg\"\n\n# Party at haekken\n\n## Day 2 - 2024-06-09\n\n# Breakfast\n\n# Votings\n\n- id: \"simon-kaleschke-ruby-unconf-2024\"\n  title: \"Refactoring Code I Hate\"\n  raw_title: \"Refactoring code I hate by Simon Kaleschke\"\n  speakers:\n    - Simon Kaleschke\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-09\"\n  published_at: \"2024-10-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"IKlKOhN9NQE\"\n\n- title: \"Going back to the BASICs\"\n  raw_title: \"Jan Krutisch - Back to the BASICs\"\n  speakers:\n    - Jan Krutisch\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-09\"\n  published_at: \"2025-01-27\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"oaaLBmOrDh0\"\n  id: \"going-back-to-the-basics-ruby-unconf-2024\"\n  slug: \"going-back-to-the-basics-ruby-unconf-2024\"\n\n# Lunch\n\n- id: \"micha-cicki-ruby-unconf-2024\"\n  title: \"Showing Progress of Background Jobs with Hotwire Turbo\"\n  raw_title: \"Showing progress of background jobs with Hotwire Turbo by Michał Łęcicki\"\n  speakers:\n    - Michał Łęcicki\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-09\"\n  published_at: \"2024-10-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DYr_HAgJtlo\"\n\n- id: \"chikahiro-tokoro-ruby-unconf-2024\"\n  title: \"Generate Anonymised Databases with MasKING\"\n  raw_title: \"Generate anonymised database with MasKING by Chikahiro Tokoro\"\n  speakers:\n    - Chikahiro Tokoro\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-09\"\n  published_at: \"2024-10-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"qgHm6EFm-Eg\"\n\n# Coffeebreak\n\n- id: \"lightning-talks-ruby-unconf-2024\"\n  title: \"Lightning Talks\"\n  raw_title: \"Lightning Talks\"\n  speakers:\n    - TODO\n  event_name: \"Ruby Unconf 2024\"\n  date: \"2024-06-09\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"lightning-talks-ruby-unconf-2024\"\n# Closing\n"
  },
  {
    "path": "data/rubyunconf/series.yml",
    "content": "---\nname: \"Ruby Unconf\"\nwebsite: \"https://rubyunconf.eu\"\ntwitter: \"rubyunconfeu\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"DE\"\nyoutube_channel_name: \"rubyunconf5227\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCpdY3gEqGW10EVrUbd1itug\"\naliases:\n  - RubyUnconf\n  - rubyunconfeu\n  - RubyUnconf EU\n  - Ruby Unconf EU\n  - Ruby Unconf Hamburg\n  - Ruby Unconference\n  - Ruby Unconference EU\n  - Ruby Unconference Hamburg\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2009/event.yml",
    "content": "---\nid: \"rubyworld-2009\"\ntitle: \"RubyWorld Conference 2009\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2009-09-07\"\nend_date: \"2009-09-08\"\noriginal_website: \"http://www.rubyworld-conf.org/en/\"\ncoordinates:\n  latitude: 35.4681908\n  longitude: 133.0484055\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2014/event.yml",
    "content": "---\nid: \"rubyworld-2014\"\ntitle: \"RubyWorld Conference 2014\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2014-11-13\"\nend_date: \"2014-11-14\"\nwebsite: \"http://2014.rubyworld-conf.org/en/\"\ncoordinates:\n  latitude: 35.4681908\n  longitude: 133.0484055\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2014.rubyworld-conf.org/en/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2015/event.yml",
    "content": "---\nid: \"rubyworld-2015\"\ntitle: \"RubyWorld Conference 2015\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2015-11-11\"\nend_date: \"2015-11-12\"\nwebsite: \"http://2015.rubyworld-conf.org/en/\"\nplaylist: \"http://2015.rubyworld-conf.org/en/program/\"\ncoordinates:\n  latitude: 35.4681908\n  longitude: 133.0484055\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2015.rubyworld-conf.org/en/\n# Videos: http://2015.rubyworld-conf.org/en/program/\n---\n[]\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2016/event.yml",
    "content": "---\nid: \"rubyworld-2016\"\ntitle: \"RubyWorld Conference 2016\"\ndescription: \"\"\nlocation: \"Matsue, Shimane, Japan\"\nkind: \"conference\"\nstart_date: \"2016-11-03\"\nend_date: \"2016-11-04\"\nwebsite: \"http://2017.rubyworld-conf.org/en/\"\nplaylist: \"http://2016.rubyworld-conf.org/en/program/\"\ncoordinates:\n  latitude: 35.4681908\n  longitude: 133.0484055\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2017.rubyworld-conf.org/en/\n# Videos: http://2016.rubyworld-conf.org/en/program/\n---\n[]\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2017/event.yml",
    "content": "---\nid: \"rubyworld-2017\"\ntitle: \"RubyWorld Conference 2017\"\ndescription: \"\"\nlocation: \"Matsue, Shimane, Japan\"\nkind: \"conference\"\nstart_date: \"2017-11-01\"\nend_date: \"2017-11-02\"\nwebsite: \"http://2017.rubyworld-conf.org/en/\"\nplaylist: \"http://2017.rubyworld-conf.org/en/program/\"\ncoordinates:\n  latitude: 35.4681908\n  longitude: 133.0484055\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2017.rubyworld-conf.org/en/\n# Videos: http://2017.rubyworld-conf.org/en/program/\n---\n[]\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2018/event.yml",
    "content": "---\nid: \"rubyworld-2018\"\ntitle: \"RubyWorld Conference 2018\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2018-11-01\"\nend_date: \"2018-11-02\"\nwebsite: \"http://2018.rubyworld-conf.org/\"\nplaylist: \"https://2018.rubyworld-conf.org/program/\"\ncoordinates:\n  latitude: 35.4681908\n  longitude: 133.0484055\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2018.rubyworld-conf.org/\n# Videos: https://2018.rubyworld-conf.org/program/\n---\n[]\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2019/event.yml",
    "content": "---\nid: \"rubyworld-2019\"\ntitle: \"RubyWorld Conference 2019\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2019-11-07\"\nend_date: \"2019-11-08\"\nwebsite: \"https://2019.rubyworld-conf.org/en/\"\ncoordinates:\n  latitude: 35.4700991\n  longitude: 133.0673056\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2019/venue.yml",
    "content": "# https://2019.rubyworld-conf.org/en/venue/\n---\nname: 'Shimane Prefectural Convention Center \"Kunibiki Messe\"'\n\ndescription: |-\n  International Conference Hall (3F) and Small Hall (1F) within the convention center.\n\naddress:\n  street: \"2-1-1 Chome Gakuen Minami\"\n  city: \"Matsue City\"\n  region: \"Shimane Prefecture\"\n  postal_code: \"690-0826\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"1-chōme-2-10 Gakuenminami, Matsue, Shimane 690-0826, Japan\"\n\ncoordinates:\n  latitude: 35.4700991\n  longitude: 133.0673056\n\nmaps:\n  google: 'https://maps.google.com/?q=Shimane+Prefectural+Convention+Center+\"Kunibiki+Messe\",35.4700991,133.0673056'\n  apple: 'https://maps.apple.com/?q=Shimane+Prefectural+Convention+Center+\"Kunibiki+Messe\"&ll=35.4700991,133.0673056'\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=35.4700991&mlon=133.0673056\"\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2019.rubyworld-conf.org/en/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2020/event.yml",
    "content": "---\nid: \"rubyworld-2020\"\ntitle: \"RubyWorld Conference 2020\"\ndescription: \"\"\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2020-12-17\"\nend_date: \"2020-12-17\"\nwebsite: \"https://2020.rubyworld-conf.org/en/\"\nplaylist: \"https://www.youtube.com/watch?v=2fldr2HcuVw\"\ncoordinates: false\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2020.rubyworld-conf.org/en/\n# Videos: https://www.youtube.com/watch?v=2fldr2HcuVw\n---\n[]\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2023/event.yml",
    "content": "---\nid: \"rubyworld-2023\"\ntitle: \"RubyWorld Conference 2023\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2023-11-09\"\nend_date: \"2023-11-10\"\nwebsite: \"http://2023.rubyworld-conf.org/en/\"\ncoordinates:\n  latitude: 35.4700991\n  longitude: 133.0673056\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2023/venue.yml",
    "content": "# https://2023.rubyworld-conf.org/en/venue/\n---\nname: 'Shimane Prefectural Convention Center \"Kunibiki Messe\"'\n\ndescription: |-\n  International Conference Hall (3F) and Small Hall (1F) within the convention center.\n\naddress:\n  street: \"2-1-1 Chome Gakuen Minami\"\n  city: \"Matsue City\"\n  region: \"Shimane Prefecture\"\n  postal_code: \"690-0826\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"1-chōme-2-10 Gakuenminami, Matsue, Shimane 690-0826, Japan\"\n\ncoordinates:\n  latitude: 35.4700991\n  longitude: 133.0673056\n\nmaps:\n  google: 'https://maps.google.com/?q=Shimane+Prefectural+Convention+Center+\"Kunibiki+Messe\",35.4700991,133.0673056'\n  apple: 'https://maps.apple.com/?q=Shimane+Prefectural+Convention+Center+\"Kunibiki+Messe\"&ll=35.4700991,133.0673056'\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=35.4700991&mlon=133.0673056\"\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2023/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://2023.rubyworld-conf.org/en/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2024/event.yml",
    "content": "---\nid: \"rubyworld-2024\"\ntitle: \"RubyWorld Conference 2024\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2024-12-05\"\nend_date: \"2024-12-06\"\nwebsite: \"https://2024.rubyworld-conf.org/en/\"\ncoordinates:\n  latitude: 35.4700991\n  longitude: 133.0673056\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2024/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsors\"\n      description: |-\n        Top tier sponsors labeled as Ruby Sponsors.\n      level: 1\n      sponsors:\n        - name: \"Network Applied Communication Laboratory Ltd.\"\n          website: \"https://www.netlab.jp\"\n          slug: \"NetworkAppliedCommunicationLaboratoryLtd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/netlab_jp.png\"\n\n        - name: \"ANDPAD Inc.\"\n          website: \"https://engineer.andpad.co.jp/\"\n          slug: \"andpad\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/andpad_co_jp.png\"\n\n        - name: \"TOKIUM Inc.\"\n          website: \"https://corp.tokium.jp/\"\n          slug: \"TOKIUMInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/corp_tokium_jp.png\"\n\n    - name: \"Platinum Sponsors\"\n      description: |-\n        Second tier sponsors labeled as Platinum Sponsors.\n      level: 2\n      sponsors:\n        - name: \"ESM, Inc.\"\n          website: \"https://agile.esm.co.jp/en/\"\n          slug: \"ESM,Inc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/esm_co_jp.png\"\n\n        - name: \"Agileware\"\n          website: \"https://agileware.jp/\"\n          slug: \"agileware\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/agileware_jp.png\"\n\n        - name: \"Far End Technologies Corporation\"\n          website: \"https://www.redminecloud.net/\"\n          slug: \"FarEndTechnologiesCorporation\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/farend_co_jp.png\"\n\n        - name: \"VITAL LEAD Co., Ltd.\"\n          website: \"https://www.vitallead.co.jp/\"\n          slug: \"VITALLEADCo.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/vitallead_co_jp.png\"\n\n        - name: \"LIBERTYFISH Co., Ltd.\"\n          website: \"https://www.libertyfish.co.jp/\"\n          slug: \"LIBERTYFISHCo.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/libertyfish_co_jp.png\"\n\n        - name: \"Sky Co., LTD.\"\n          website: \"https://www.skyseaclientview.net/\"\n          slug: \"SkyCo.,LTD.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/skyseaclientview_net.png\"\n\n        - name: \"KOMATSU ELECTRIC INDUSTRY CO., LTD.\"\n          website: \"https://www.komatsuelec.co.jp/eng/index.html\"\n          slug: \"KOMATSUELECTRICINDUSTRYCO.,LTD.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/komatsuelec_co_jp.png\"\n\n        - name: \"Ruby Business Council\"\n          website: \"https://www.ruby-b.com/\"\n          slug: \"RubyBusinessCouncil\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/ruby-b_com.png\"\n\n        - name: \"e-Grid Inc.\"\n          website: \"https://www.e-grid.co.jp/\"\n          slug: \"e-GridInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/e-grid_co_jp.png\"\n\n        - name: \"RIZAP GROUP, Inc.\"\n          website: \"https://ir-english.rizapgroup.com/\"\n          slug: \"RIZAPGROUP,Inc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/rizapgroup_com.png\"\n\n        - name: \"Fenrir Inc.\"\n          website: \"https://www.fenrir-inc.com/jp/\"\n          slug: \"FenrirInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/fenrir-inc_com.png\"\n\n        - name: \"ASHITA-TEAM Co., Ltd.\"\n          website: \"https://www.ashita-team.com\"\n          slug: \"ASHITA-TEAMCo.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/ashita-team_com.png\"\n\n        - name: \"Open Source Software Society Shimane\"\n          website: \"https://www.shimane-oss.org/\"\n          slug: \"OpenSourceSoftwareSocietyShimane\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/shimane-oss_org.png\"\n\n        - name: \"freee K.K.\"\n          website: \"https://corp.freee.co.jp/en/\"\n          slug: \"freeeK.K.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/freee_co_jp.png\"\n\n        - name: \"Unifa Inc.\"\n          website: \"https://unifa-e.com/\"\n          slug: \"UnifaInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/unifa-e_com.png\"\n\n    - name: \"Gold Sponsors\"\n      description: |-\n        Third tier sponsors labeled as Gold Sponsors.\n      level: 3\n      sponsors:\n        - name: \"Japan Business Press Co., Ltd.\"\n          website: \"https://mediaweaver.jp/\"\n          slug: \"JapanBusinessPressCo.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/mediaweaver_jp.png\"\n\n        - name: \"Splout Ltd.\"\n          website: \"https://splout.co.jp/\"\n          slug: \"SploutLtd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/splout_co_jp.png\"\n\n        - name: \"Shimane Johoshori Center Inc.\"\n          website: \"https://www.sjc-inc.co.jp/\"\n          slug: \"ShimaneJohoshoriCenterInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/sjc-inc_co_jp.png\"\n\n        - name: \"Matsukei Co.,Ltd.\"\n          website: \"https://www.matsukei.co.jp/\"\n          slug: \"MatsukeiCo.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/matsukei_co_jp.png\"\n\n        - name: \"Techno Project Japan Co.\"\n          website: \"https://www.tpj.co.jp/\"\n          slug: \"TechnoProjectJapanCo.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/tpj_co_jp.png\"\n\n        - name: \"MEDLEY, Inc.\"\n          website: \"https://www.medley.jp/\"\n          slug: \"MEDLEY,Inc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/medley_jp.png\"\n\n        - name: \"PENTAS-NET Co.,Ltd.\"\n          website: \"https://www.pentas-net.co.jp/en.html\"\n          slug: \"PENTAS-NETCo.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/pentas-net_co_jp.png\"\n\n        - name: \"WYRD Corporation\"\n          website: \"https://wyrd.co.jp/\"\n          slug: \"WYRDCorporation\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/wyrd_co_jp.png\"\n\n        - name: \"Internet Initiative Japan Inc.\"\n          website: \"https://www.iij.ad.jp/en/\"\n          slug: \"InternetInitiativeJapanInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/iij_ad_jp.png\"\n\n        - name: \"TSK Information System Co.Ltd.\"\n          website: \"https://tskis.jp/\"\n          slug: \"TSKInformationSystemCo.Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/tskis_jp.png\"\n\n        - name: \"PDC Co., LTD.\"\n          website: \"https://www.pdc-ds.com/\"\n          slug: \"PDCCo.,LTD.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/pdc-ds_com.png\"\n\n        - name: \"Coincheck, Inc.\"\n          website: \"https://corporate.coincheck.com/\"\n          slug: \"Coincheck,Inc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/corporate_coincheck_com.png\"\n\n        - name: \"CMC Solutions INC.\"\n          website: \"https://www.cmc-solutions.co.jp/\"\n          slug: \"CMCSolutionsINC.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/cmc-solutions_co_jp.png\"\n\n        - name: \"mov inc.\"\n          website: \"https://mov.am/\"\n          slug: \"movinc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/mov_am.png\"\n\n    - name: \"Silver Sponsors\"\n      description: |-\n        Fourth tier sponsors labeled as Silver Sponsors.\n      level: 4\n      sponsors:\n        - name: \"Lokka, Inc\"\n          website: \"https://bootcamp.fjord.jp/welcome\"\n          slug: \"Lokka,Inc\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/fjord_jp.png\"\n\n        - name: \"esa LLC\"\n          website: \"https://esa.io\"\n          slug: \"esaLLC\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/esa_io.png\"\n\n        - name: \"BUNBU COMPANY LIMITED\"\n          website: \"https://www.bunbusoft.com/\"\n          slug: \"BUNBUCOMPANYLIMITED\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/bunbusoft_com.png\"\n\n        - name: \"TakeyuWeb Inc.\"\n          website: \"https://takeyuweb.co.jp/\"\n          slug: \"TakeyuWebInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/takeyuweb_co_jp.png\"\n\n        - name: \"xalpha Inc.\"\n          website: \"https://xalpha.jp/\"\n          slug: \"xalphaInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/xalpha_jp.png\"\n\n        - name: \"F&.NEXT\"\n          website: \"https://fandnext.jp/\"\n          slug: \"F&.NEXT\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/fandnext_jp.png\"\n\n        - name: \"PROBIZMO CO.,LTD\"\n          website: \"https://www.probizmo.co.jp/\"\n          slug: \"PROBIZMOCO.,LTD\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/probizmo_co_jp.png\"\n\n        - name: \"specified non-profit corporation mruby Forum\"\n          website: \"http://forum.mruby.org/\"\n          slug: \"specifiednon-profitcorporationmrubyForum\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/forum_mruby_org.png\"\n\n        - name: \"Ichibata Electric Railway Co.,Ltd\"\n          website: \"https://www.ichibata.co.jp/\"\n          slug: \"IchibataElectricRailwayCo.,Ltd\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/ichibata_co_jp.png\"\n\n        - name: \"AcuteSysCom Ltd.\"\n          website: \"https://www.acute-sc.co.jp/\"\n          slug: \"AcuteSysComLtd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/acute-sc_co_jp.png\"\n\n        - name: \"Trust Software Co.\"\n          website: \"https://trust-software.co.jp/\"\n          slug: \"TrustSoftwareCo.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/trust-software_co_jp.png\"\n\n        - name: \"Japan High Soft Co., Ltd.\"\n          website: \"https://www.jhsc.co.jp\"\n          slug: \"JapanHighSoftCo.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/jhsc_co_jp.png\"\n\n        - name: \"PAY, Inc\"\n          website: \"https://pay.jp/\"\n          slug: \"PAY,Inc\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/pay_jp.png\"\n\n        - name: \"SmartStyle Co.,Ltd.\"\n          website: \"https://www.s-style.co.jp/english\"\n          slug: \"SmartStyleCo.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/s-style_co_jp.png\"\n\n        - name: \"Pasona Inc.\"\n          website: \"https://www.pasona.co.jp/clients/service/xtech/\"\n          slug: \"PasonaInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/pasona_co_jp.png\"\n\n        - name: \"Fujitsu Japan Limited\"\n          website: \"https://www.fujitsu.com/jp/group/fjj/\"\n          slug: \"FujitsuJapanLimited\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/fujitsu_com.png\"\n\n        - name: \"OSS-Vision Co., Ltd.\"\n          website: \"https://www.oss-vision.com\"\n          slug: \"OSS-VisionCo.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/oss-vision_com.png\"\n\n        - name: \"Everyleaf Corporation\"\n          website: \"https://everyleaf.com/english\"\n          slug: \"EveryleafCorporation\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/everyleaf_com.png\"\n\n        - name: \"Dogrun Inc.\"\n          website: \"https://dogrun.jp/en/\"\n          slug: \"DogrunInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/dogrun_jp.png\"\n\n        - name: \"Monstarlab, Inc.\"\n          website: \"https://monstar-lab.com/global\"\n          slug: \"Monstarlab,Inc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/monstar-lab_com.png\"\n\n        - name: \"ZAUEL LLC.\"\n          website: \"https://zauel.co.jp/\"\n          slug: \"ZAUELLLC.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/zauel_co_jp.png\"\n\n        - name: \"SmartHR, Inc.\"\n          website: \"https://hello-world.smarthr.co.jp/\"\n          slug: \"smarthr\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/smarthr_co_jp.png\"\n\n        - name: \"Willport Co., Ltd.\"\n          website: \"https://www.willport.co.jp/\"\n          slug: \"WillportCo.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/willport_co_jp.png\"\n\n        - name: \"Rentio Inc.\"\n          website: \"https://www.rentio.jp/\"\n          slug: \"RentioInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/rentio_jp.png\"\n\n        - name: \"Donatello.Co.,Ltd.\"\n          website: \"https://donatello.jp/\"\n          slug: \"Donatello.Co.,Ltd.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/donatello_jp.png\"\n\n        - name: \"ROUTE06, Inc.\"\n          website: \"https://route06.com/\"\n          slug: \"ROUTE06,Inc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/route06_co_jp.png\"\n\n        - name: \"Cuon.Inc\"\n          website: \"https://cuon.co.jp/\"\n          slug: \"Cuon.Inc\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/cuon_co_jp.png\"\n\n        - name: \"Ruby Development Inc.\"\n          website: \"https://www.ruby-dev.jp/\"\n          slug: \"rubydevelopment\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/ruby-dev_jp.png\"\n\n        - name: \"Enecom,Inc.\"\n          website: \"https://www.enecom.co.jp/\"\n          slug: \"Enecom,Inc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/enecom_co_jp.png\"\n\n        - name: \"codeTakt Inc.\"\n          website: \"https://codetakt.com/\"\n          slug: \"codeTaktInc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/codetakt_com.png\"\n\n        - name: \"Ichizoku inc.\"\n          website: \"https://sentry.io/welcome\"\n          slug: \"Ichizokuinc.\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/sentry_ichizoku_io.png\"\n\n        - name: \"REGISTACT.inc\"\n          website: \"https://www.registact.jp/\"\n          slug: \"REGISTACT.inc\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/registact_jp.png\"\n\n        - name: \"EnHearth.team\"\n          website: \"https://www.enhearth.team/\"\n          slug: \"EnHearth.team\"\n          logo_url: \"https://2024.rubyworld-conf.org/images/sponsors/enhearth_team.png\"\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2024/venue.yml",
    "content": "# https://2024.rubyworld-conf.org/en/venue/\n---\nname: 'Shimane Prefectural Convention Center \"Kunibiki Messe\"'\n\ndescription: |-\n  International Conference Hall (3F) and Small Hall (1F) within the convention center.\n\naddress:\n  street: \"2-1-1 Chome Gakuen Minami\"\n  city: \"Matsue City\"\n  region: \"Shimane Prefecture\"\n  postal_code: \"690-0826\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"1-chōme-2-10 Gakuenminami, Matsue, Shimane 690-0826, Japan\"\n\ncoordinates:\n  latitude: 35.4700991\n  longitude: 133.0673056\n\nmaps:\n  google: 'https://maps.google.com/?q=Shimane+Prefectural+Convention+Center+\"Kunibiki+Messe\",35.4700991,133.0673056'\n  apple: 'https://maps.apple.com/?q=Shimane+Prefectural+Convention+Center+\"Kunibiki+Messe\"&ll=35.4700991,133.0673056'\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=35.4700991&mlon=133.0673056\"\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2024/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2024.rubyworld-conf.org/en/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2025/cfp.yml",
    "content": "---\n- link: \"https://2025.rubyworld-conf.org/en/news/2025/06/call-for-proposals/\"\n  open_date: \"2025-06-23\"\n  close_date: \"2025-08-01\"\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2025/event.yml",
    "content": "---\nid: \"rubyworld-2025\"\ntitle: \"RubyWorld Conference 2025\"\ndescription: \"\"\nlocation: \"Matsue, Japan\"\nkind: \"conference\"\nstart_date: \"2025-11-06\"\nend_date: \"2025-11-07\"\nwebsite: \"https://2025.rubyworld-conf.org/en/\"\nfeatured_background: \"#1E2230\"\nfeatured_color: \"#FFFFFF\"\nbanner_background: \"#1E2230\"\ncoordinates:\n  latitude: 35.4700991\n  longitude: 133.0673056\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2025/venue.yml",
    "content": "# https://2025.rubyworld-conf.org/en/venue/\n---\nname: 'Shimane Prefectural Convention Center \"Kunibiki Messe\"'\n\ndescription: |-\n  International Conference Hall (3F) and Small Hall (1F) within the convention center.\n\naddress:\n  street: \"2-1-1 Chome Gakuen Minami\"\n  city: \"Matsue City\"\n  region: \"Shimane Prefecture\"\n  postal_code: \"690-0826\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"1-chōme-2-10 Gakuenminami, Matsue, Shimane 690-0826, Japan\"\n\ncoordinates:\n  latitude: 35.4700991\n  longitude: 133.0673056\n\nmaps:\n  google: 'https://maps.google.com/?q=Shimane+Prefectural+Convention+Center+\"Kunibiki+Messe\",35.4700991,133.0673056'\n  apple: 'https://maps.apple.com/?q=Shimane+Prefectural+Convention+Center+\"Kunibiki+Messe\"&ll=35.4700991,133.0673056'\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=35.4700991&mlon=133.0673056\"\n"
  },
  {
    "path": "data/rubyworld/rubyworld-2025/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://2024.rubyworld-conf.org/ja/news/2025/01/rwc2025/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/rubyworld/series.yml",
    "content": "---\nname: \"RubyWorld Conference\"\nwebsite: \"https://2024.rubyworld-conf.org/en/\"\ntwitter: \"rubyworldconf\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - RubyWorld\n  - Ruby World\n  - rubyworldconf\n  - RubyWorld Conf\n"
  },
  {
    "path": "data/rulu/rulu-2011/event.yml",
    "content": "---\nid: \"rulu-2011\"\ntitle: \"Ruby Lugdunum Conference 2011\"\nkind: \"conference\"\nlocation: \"Lyon, France\"\ndescription: |-\n  25-26 June 2011. Lyon, France\nstart_date: \"2011-06-25\"\nend_date: \"2011-06-26\"\nyear: 2011\nwebsite: \"http://2011.rulu.fr\"\ncoordinates:\n  latitude: 45.764043\n  longitude: 4.835659\n"
  },
  {
    "path": "data/rulu/rulu-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# http://2011.rulu.fr\n# https://github.com/lyonrb/2011.rulu.eu/\n# https://github.com/lyonrb/ruby-lugdunum\n---\n[]\n"
  },
  {
    "path": "data/rulu/rulu-2012/event.yml",
    "content": "---\nid: \"PLE581136FC9265730\"\ntitle: \"Ruby Lugdunum Conference 2012\"\nkind: \"conference\"\nlocation: \"Lyon, France\"\ndescription: \"\"\npublished_at: \"2012-08-24\"\nstart_date: \"2012-06-22\"\nend_date: \"2012-06-23\"\nchannel_id: \"UCFqRbkEEaM4w1iEK1ovBXxg\"\nyear: 2012\nwebsite: \"https://2012.rulu.fr\"\ncoordinates:\n  latitude: 45.764043\n  longitude: 4.835659\n"
  },
  {
    "path": "data/rulu/rulu-2012/videos.yml",
    "content": "# Website: https://2012.rulu.fr\n# Schedule: https://2012.rulu.fr/schedule\n---\n## Day 1 - 2013-06-22\n\n- id: \"dave-neary-ruby-lugdunum-conference-2012\"\n  title: \"Keynote: The Shy Developer Syndrome\"\n  raw_title: \"The Shy Developer Syndrome - Dave Neary - RuLu 2012\"\n  speakers:\n    - Dave Neary\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-22\"\n  published_at: \"2012-07-12\"\n  description: |-\n    The hardest part of joining an open source project for a professional developer is being completely transparent on a mailing list, and submitting your work to public peer review. When you are used to talking about technical details with your manager and colleagues, writing an email to a mailing list can be very daunting: Am I exposing some confidential information here? Have I made a mistake which someone will criticise? Is this message important enough to make an announcement on a public mailing list?\n\n    I call this \"Shy Developer Syndrome\". Developers used to working in a commercial software development environment can clam up when asked to work in public.\n\n    There are some straightforward ways to help experienced developers gain confidence in working in public forums, and gain the respect of their peers in open source projects. This presentation will outline some of the strategies which have worked in the past for me.\n\n    Dave is a frequent speaker on GNOME, including accessibility, mobile, community processes and other aspects of the project, Dave used to be a freelance consultant specialising in the relationship between companies and free software communities. He is the former maemo.org docmaster, and product & community manager for the OpenWengo project. Dave recently joined Red Hat to work in the \"Open Source and Standards\" team.\n  video_provider: \"youtube\"\n  video_id: \"AqDEgNlyjvo\"\n\n- id: \"brandon-keepers-ruby-lugdunum-conference-2012\"\n  title: \"Why Our Code Smells\"\n  raw_title: \"Why Our Code Smells - Brandon Keepers - RuLu 2012\"\n  speakers:\n    - Brandon Keepers\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-22\"\n  published_at: \"2012-07-11\"\n  description: |-\n    Odors are communication devices. They exist for a reason and are usually trying to tell us something.\n\n    Our code smells and it is trying to tell us what is wrong. Does a test case require a lot of setup? Maybe the code being tested is doing too much, or it is not isolated enough for the test? Does an object have an abundance of instance variables? Maybe it should be split into multiple objects? Is a view brittle? Maybe it is too tightly coupled to a model, or maybe the logic needs abstracted into an object that can be tested?\n\n    In this talk, I will walk through code from projects that I work on every day, looking for smells that indicate problems, understanding why it smells, what the smell is trying to tell us, and how to refactor it.\n\n    Brandon is a developer at GitHub. He spends most of his time crafting beautiful code for Gaug.es and SpeakerDeck.com. Brandon has created and maintains many open-source projects, and shares about his endeavors at opensoul.org.\n  video_provider: \"youtube\"\n  video_id: \"JxPKljUkFQw\"\n\n- id: \"xavier-noria-ruby-lugdunum-conference-2012\"\n  title: \"Constants In Ruby\"\n  raw_title: \"Constants In Ruby - Xavier Noria - RuLu 2012\"\n  speakers:\n    - Xavier Noria\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-22\"\n  published_at: \"2012-07-14\"\n  description: |-\n    Constants are a rich and under-documented topic in Ruby. We are going to cover them in detail, their relationship with classes and modules, nesting, resolution algorithms, dynamic API, etc. At the end of the talk we will connect the dots to explain at a high level how constant autoloading works in Ruby on Rails.\n\n    Everlasting student, Rails core team, Ruby Hero, with a wonderful daughter, Kinesis keyboard user, Segway glider, Gold Winger, I also breathe.\n  video_provider: \"youtube\"\n  video_id: \"wCyTRdtKm98\"\n\n- id: \"thibaut-barrre-ruby-lugdunum-conference-2012\"\n  title: \"Transforming your Data with Ruby and ActiveWarehouse-ETL\"\n  raw_title: \"Transforming your Data with Ruby and ActiveWarehouse-ETL - Thibaut Barrère - RuLu 2012\"\n  speakers:\n    - Thibaut Barrère\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-22\"\n  published_at: \"2012-07-16\"\n  description: |-\n    This talk will show how to use ActiveWarehouse-ETL to extract, transform and move your data around in Ruby, and what other people do in real life with this toolkit.\n\n    Thibaut Barrère is a Ruby freelancer since 2005, doing data processing on a regular basis since then too. He is also bootstrapping a Rails-based SaaS product WiseCashHQ.\n  video_provider: \"youtube\"\n  video_id: \"LW863DOXqZQ\"\n\n# Lunch\n\n- id: \"alex-koppel-ruby-lugdunum-conference-2012\"\n  title: \"Sleep!\"\n  raw_title: \"Sleep! - Alex Koppel - RuLu 2012\"\n  speakers:\n    - Alex Koppel\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-22\"\n  published_at: \"2012-07-17\"\n  description: |-\n    Sleep: we all do it, and yet somehow it's hard (as most of us can attest every morning). It's also really relevant: as thinkers, creators, and problem solvers, anything that makes our brains less effective matters. Missed sleep makes a difference -- even two fewer hours a night quickly produce measurable cognitive impairment. Things get more interesting when we look at why it's so hard: our sleep cycles are determined by our internal clocks, which often put us in conflict with society's timetables, leaving many of us in a state of \"social jet lag\", as if we'd been traveling a timezone or more every day. That's not how any of us want to code (or live), I think, and by understanding how and why so many of us are constantly tired, we can start to make things better.\n\n    Alex Koppel is Just Another Rails Developer at 6Wunderkinder and the author of the Koala Facebook gem. Before joining the 6W team in Berlin, he helped build a leading social marketing platform, led part of a massive healthcare IT installation in California, and moonlighted as an online bookseller. An amateur cook, eager language learner, and inveterate book reader, Alex dual majored in computer science and scavenger hunts at the University of Chicago.\n  video_provider: \"youtube\"\n  video_id: \"-jQRuSjVeu0\"\n\n- id: \"roy-tomeij-ruby-lugdunum-conference-2012\"\n  title: \"Modular & Reusable Front-end Code With HTML5, SASS and CoffeeScript\"\n  raw_title: \"Modular & Reusable Front-end Code With HTML5, SASS and CoffeeScript - Roy Tomeij - RuLu 2012\"\n  speakers:\n    - Roy Tomeij\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-22\"\n  published_at: \"2012-07-19\"\n  description: |-\n    Keeping your front-end code clean is hard. Before you know it you're suffering from CSS specificity issues and not-really-generic partials. Find out how to keep things tidy using the HTML5 document outline and modular Sass & CoffeeScript, for truly reusable code.\n\n    Roy has been a front-end specialist for almost a decade. As one of the co-founders of consultancy 80beans in Amsterdam, he weaves HTML5 and CSS3 magic on an hourly basis. As well as being in love with front-end meta languages like haml, sass and coffeescript, he is all about a sweet mixture of function and form.\n  video_provider: \"youtube\"\n  video_id: \"TqPzxrCIJTs\"\n\n- id: \"piotr-solnica-ruby-lugdunum-conference-2012\"\n  title: \"Beyond The ORM\"\n  raw_title: \"Beyond The ORM - Piotr Solnica - RuLu 2012\"\n  speakers:\n    - Piotr Solnica\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-22\"\n  published_at: \"2012-07-12\"\n  description: |-\n    Ruby developers are living in the world of Active Record. No matter what ORM you're using, it's an implementation of the Active Record pattern. There's been a recent discussion in our community about separating business logic from the persistence concerns. People are experimenting with different approaches but they still use an ActiveRecord ORM under the hood.\n    In this presentation I will give you an introduction to the development of DataMapper 2 - the first true implementation of the Data Mapper pattern in Ruby language. I will talk a little bit about ORM patterns and show you core parts of DM2 that already exist and the ones we're going to build soon.\n\n    Husband & Fresh Father. Ruby & JavaScript Developer. OpenSource Contributor. DataMapper Core Team Member. Mac user waiting for the year of Linux on desktop.\n  video_provider: \"youtube\"\n  video_id: \"kOnbcPlVFdU\"\n\n- id: \"thorben-schrder-ruby-lugdunum-conference-2012\"\n  title: \"Improving Inter Service Communication\"\n  raw_title: \"Improving Inter Service Communication - Thorben Schröder - RuLu 2012\"\n  speakers:\n    - Thorben Schröder\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-22\"\n  published_at: \"2012-07-20\"\n  description: |-\n    In times when applications get more and more split up into small pieces that have to communicate with each other it's critical to have systems in place that make this communication as trouble-free as possible. This talk covers what we did at Engine Yard to improve our inter service communication and how you can apply that to your own infrastructure.\n\n    Thorben is the former founder of \"kopfmaschine\", a German Rails shop located in Bremen and now working to make the cloud a better place for developers at Engine Yard in San Francisco. He is living and breathing Ruby since his days at University where he graduated with his thesis on how to scale large Rails applications.\n  video_provider: \"youtube\"\n  video_id: \"BBml-8p-O8E\"\n\n## Day 2 - 2013-06-23\n\n- id: \"joan-wolkerstorfer-ruby-lugdunum-conference-2012\"\n  title: \"I am Rails (and So Can You!)\"\n  raw_title: \"I am Rails (and So Can You!) - Joan Wolkerstorfer - RuLu 2012\"\n  speakers:\n    - Joan Wolkerstorfer\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-21\"\n  description: |-\n    I taught myself to code and went from zero to a full-time programming gig in under a year. I will discuss my story, tools for new developers, and what I've learned from coaching with RailsGirls, particularly what we can do to teach new programmers, with a focus on women.\n\n    After graduating from the University of Chicago in 2006 with a degree in humanities/social sciences fields, Joan spent a couple of years in San Francisco working in theater as a stage manager and wishing her hours worked out better with all her friends at tech companies. After moving to Germany in 2009 and spending a year learning German, she set her sights on learning to program. She picked Ruby on Rails, and things took off. She quickly found herself in an internship for a respected Berlin Rails development shop, and soon after that landed a job with mediapeers.\n  video_provider: \"youtube\"\n  video_id: \"I2KeHOtgUUk\"\n\n- id: \"laurent-sansonetti-ruby-lugdunum-conference-2012\"\n  title: \"RubyMotion: Ruby In Your Pocket\"\n  raw_title: \"RubyMotion: Ruby In Your Pocket - Laurent Sansonetti - RuLu 2012\"\n  speakers:\n    - Laurent Sansonetti\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-23\"\n  description: |-\n    RubyMotion is a revolutionary toolchain for iOS development using Ruby. With RubyMotion, developers can finally write full-fledged native iOS apps in Ruby, the language you all know and love. In this session, we will cover what RubyMotion is and how easy it is to write an app with it.\n\n    Laurent is the founder of HipByte, a new company that crafts revolutionary software tools. He worked at Apple for 7 years as a senior software engineer, on both iLife and OS X. A long time rubyist, he created and still maintains the MacRuby project. In a previous life, he worked on IDA Pro and was an active contributor to RubyCocoa and GNOME.\n  video_provider: \"youtube\"\n  video_id: \"aw95qqbe4_Y\"\n\n- id: \"konstantin-haase-ruby-lugdunum-conference-2012\"\n  title: \"Message in a Bottle\"\n  raw_title: \"Message in a Bottle - Konstantin Haase - RuLu2012\"\n  speakers:\n    - Konstantin Haase\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-23\"\n  description: |-\n    What does really happen when we call a method? How do the different Ruby implementations actually figure out what code to execute? What plumbing is going on under the hood to get a speedy dispatch? In this talk we will have a look at the internals of the the major Ruby implementations, focusing on their dispatch. From look-up tables and call site caches, to inlining and what on earth is invokedynamic? Fear not, all will be explained!\n\n    As current maintainer of Sinatra, Konstantin is an Open Source developer by heart. Ruby has become his language of choice since 2005. He regularly contributes to different widespread projects, like Rubinius, Rack, Travis, Rails and MRI.\n\n    He currently holds the position of \"Berry Sparkling Lord\" at Travis CI.\n  video_provider: \"youtube\"\n  video_id: \"NG8goJpbKk0\"\n\n- id: \"rogelio-samour-ruby-lugdunum-conference-2012\"\n  title: \"I Know Kung Fu (or Using Neo4j on Rails Without JRuby)!\"\n  raw_title: \"I Know Kung Fu (or Using Neo4j on Rails Without JRuby)! - Rogelio Samour - RuLu 2012\"\n  speakers:\n    - Rogelio Samour\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-30\"\n  description: |-\n    Sure graph databases are really cool and have a timestamp dated next week, but do you know when you should actually use one? Sometimes living on the bleeding edge pays off and in this talk, I'll show you how you can simplify your application and model your data more naturally with a graph database. They are suited towards a specific problem that is actually quite common in today's applications and they may even apply to that thing you'll be working on during this talk!\n\n    Born in El Salvador, Rogelio started tinkering with computers when his dad gave him a Tandy in the early 80's. He is passionate about using Computer Science to solve complex problems. He also thinks these things are rad: Vim, Ruby, Rails, Linux, Open Source Software, Marsupials, short walks on the beach (with his wife), and playing the guitar and singing made-up songs to his son. He loves Middle Eastern cuisine and dislikes talking about himself in the third person.\n  video_provider: \"youtube\"\n  video_id: \"MkaLSL09eQM\"\n\n- id: \"damian-le-nouaille-ruby-lugdunum-conference-2012\"\n  title: \"Lightning Talk: Capucine\"\n  raw_title: \"Capucine - Damian Le Nouaille - RuLu 2012\"\n  speakers:\n    - Damian Le Nouaille\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-31\"\n  description: |-\n    Capucine is a command line tool for using Compass, CoffeeScript and Incloudr in any project. It is completely agnostic and there are few configuration (just a simple and understandable YAML file).\n\n    @damln - http://dln.name\n  video_provider: \"youtube\"\n  video_id: \"40VjpfczUeE\"\n\n- id: \"thomas-darde-ruby-lugdunum-conference-2012\"\n  title: \"Lightning Talk: Gog\"\n  raw_title: \"Gog - Thomas Darde - RuLu 2012\"\n  speakers:\n    - Thomas Darde\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-31\"\n  description: |-\n    Gog aims to help developers to insert changelog data inside git commits. Gog allows to create changelogs based on commit data and tagged commits.\n\n    @thomasdarde\n  video_provider: \"youtube\"\n  video_id: \"dD3Ga8b9xTw\"\n\n- id: \"jevin-maltais-ruby-lugdunum-conference-2012\"\n  title: \"Lightning Talk: Ruby saved me from depression\"\n  raw_title: \"Ruby saved me from depression - Jevin Maltais - RuLu 2012\"\n  speakers:\n    - Jevin Maltais\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-31\"\n  description: |-\n    Ruby saved me from depression.\n\n    @jevy\n  video_provider: \"youtube\"\n  video_id: \"fDIEq92Mh6c\"\n\n- id: \"cyril-rohr-ruby-lugdunum-conference-2012\"\n  title: \"Lightning Talk: pkgr\"\n  raw_title: \"pkgr - Cyril Rohr - RuLu 2012\"\n  speakers:\n    - Cyril Rohr\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-31\"\n  description: |-\n    Package your Rails app into deb packages\n\n    @crohr - http://crohr.me\n  video_provider: \"youtube\"\n  video_id: \"KbljOCtolAc\"\n\n- id: \"nicolas-mrouze-ruby-lugdunum-conference-2012\"\n  title: \"Lightning Talk: Mastering Tea\"\n  raw_title: \"Mastering Tea - Nicolas Mérouze - RuLu 2012\"\n  speakers:\n    - Nicolas Mérouze\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-31\"\n  description: |-\n    @nmerouze\n  video_provider: \"youtube\"\n  video_id: \"zptldtJ4ZW8\"\n\n- id: \"thomas-riboulet-ruby-lugdunum-conference-2012\"\n  title: \"Lightning Talk: Devs, Devs, Devs\"\n  raw_title: \"Devs, Devs, Devs - Thomas Riboulet - RuLu 2012\"\n  speakers:\n    - Thomas Riboulet\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-31\"\n  description: |-\n    @mcansky\n  video_provider: \"youtube\"\n  video_id: \"0fSuAOVTh_4\"\n\n- id: \"ori-pekelman-ruby-lugdunum-conference-2012\"\n  title: \"Lightning Talk: Tony Arcieri ...\"\n  raw_title: \"Tony Arcieri ... - Ori Pekelman - RuLu 2012\"\n  speakers:\n    - Ori Pekelman\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-31\"\n  description: |-\n    @OriPekelman\n  video_provider: \"youtube\"\n  video_id: \"-XvLnZhiiSk\"\n\n- id: \"marcin-olichwirowicz-ruby-lugdunum-conference-2012\"\n  title: \"DCI, Diet For Your Models\"\n  raw_title: \"DCI Diet For Your Models - Marcin Olichwirowicz - RuLu 2012\"\n  speakers:\n    - Marcin Olichwirowicz\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-31\"\n  description: |-\n    Everyone knows the rule \"fat models, thin controllers\". It's really efficient when it comes to simple applications, but when we have an enterprise application, suddenly our models seem to look a bit overweight. Actually they are fat and ugly. I want to show a few examples of using DCI architectural pattern (which is complementary to MVC pattern) with Rails as a potential solution for these problems. My personal goal is to encourage people to experiment with the code and thinking outside the box (Rails box). Start thinking through domain model, not database design, to look at Datamapper pattern and DDD concepts. However, DCI is a good start to enter this enterprise world.\n\n    Marcin is from Poland where he is working as a Senior Ruby Developer at Applicake. Before joining a ruby community Marcin spent years struggling with developing huge applications in PHP in several companies. He has an MSc in Applied Computer Science.\n  video_provider: \"youtube\"\n  video_id: \"GeGAtGhgPeU\"\n\n- id: \"anthony-eden-ruby-lugdunum-conference-2012\"\n  title: \"RATFT (Refactor All The F***ing Time)\"\n  raw_title: \"RATFT (Refactor All The F***ing Time) - Anthony Eden - RuLu 2012\"\n  speakers:\n    - Anthony Eden\n  event_name: \"Ruby Lugdunum Conference 2012\"\n  date: \"2012-08-23\"\n  published_at: \"2012-07-31\"\n  description: |-\n    You know you should be testing all the time, but do you know why you are testing all the time? One of the main benefits of testing all the time is that it lets you refactor with impunity. Unfortunately too many times we leave the \"refactor\" out of the red-green-refactor. In this talk I will convince you that you should be refactoring all the time and I'll show you some of the techniques on how you can do it. With good refactoring techniques and regular refactoring even the hairiest of codebases can be tamed.\n\n    Anthony Eden is the founder of DNSimple and the perpetrator of numerous open source projects such as ActiveWarehouse and Rails SQL Views. Anthony has also contributed to a wide variety of open source projects over the past 17 years as a software developer across a variety of languages including Java, Python and Ruby. Anthony currently lives near Montpellier, France.\n  video_provider: \"youtube\"\n  video_id: \"y5k8JyaFBZk\"\n"
  },
  {
    "path": "data/rulu/rulu-2013/event.yml",
    "content": "---\nid: \"PLWO0_50XhBj8rzshoKAzT-x_seGSX2PnR\"\ntitle: \"Ruby Lugdunum Conference 2013\"\nkind: \"conference\"\nlocation: \"Lyon, France\"\ndescription: |-\n  Talks recorded at RuLu 2013\npublished_at: \"2013-10-08\"\nstart_date: \"2013-06-20\"\nend_date: \"2013-06-21\"\nchannel_id: \"UCFqRbkEEaM4w1iEK1ovBXxg\"\nyear: 2013\nwebsite: \"https://2013.rulu.fr\"\ncoordinates:\n  latitude: 45.764043\n  longitude: 4.835659\n"
  },
  {
    "path": "data/rulu/rulu-2013/videos.yml",
    "content": "# Website: https://2013.rulu.fr\n# Schedule: https://2013.rulu.fr/schedule/\n---\n## Day 1 - 2013-06-20\n\n- id: \"benjamin-smith-ruby-lugdunum-conference-2013\"\n  title: \"Hacking With Gems\"\n  raw_title: \"Hacking With Gems - Benjamin Smith\"\n  speakers:\n    - Benjamin Smith\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-20\"\n  published_at: \"2013-10-19\"\n  description: |-\n    Recorded at RuLu 2013. http://rulu.eu/\n\n    \"What's the worst that could happen if your app has a dependency on a malicious gem? How easy would it be to write a gem that could compromise a box? Much of the Ruby community blindly trusts our gems. This talk will make you second guess that trust. It will also show you how to vet gems that you do choose to use. There are four malicious gems I will be presenting: Harvesting passwords from requests going through a Rails app, exposing the contents of a Rails app's database, compromising the source code of a Rails app, providing SSH access to a box a 'gem install' time and stealing gem cutter credentials (and going viral).\n\n    My talk will increase awareness that these sort of gems can exist in the wild, show how easy it is for anyone to build malicious gems, and give easy techniques for identifying these gems.\"\n  video_provider: \"youtube\"\n  video_id: \"zEBReauO-vg\"\n\n- id: \"jrmy-lecour-ruby-lugdunum-conference-2013\"\n  title: \"From no code to a profitable business\"\n  raw_title: \"From no code to a profitable business - Jérémy Lecour\"\n  speakers:\n    - Jérémy Lecour\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-20\"\n  published_at: \"2013-10-19\"\n  description: |-\n    Recorded at RuLu 2013. http://rulu.eu/\n\n    \"It took us four years to grow from an ambitious idea to a profitable business, with a small team and not a lot of resources. I'll tell you how making \"just enough\" and \"good enough\", with a fine mix of various best practices, a lot motivation and some Ruby, we've managed to build a fast-growing product and a happy company.\"\n  video_provider: \"youtube\"\n  video_id: \"F8hH_5LKrQY\"\n\n- id: \"greg-karkinian-ruby-lugdunum-conference-2013\"\n  title: \"Dependencies, a boring, solved problem?\"\n  raw_title: \"Dependencies, a boring, solved problem? - Greg Karékinian\"\n  speakers:\n    - Greg Karékinian\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-20\"\n  published_at: \"2013-10-18\"\n  description: |-\n    Recorded at RuLu 2013. http://rulu.eu/\n\n    As Ruby developers, we all love RubyGems and Bundler. These tools are pretty amazing when it comes to installing the dependencies of your web app. Do they solve everything for command-line applications too?\n    In theory, you install the right version of Ruby and then run gem install. In practice, it's a bit more complicated than that.\n    I will show you examples of the different ways things can and will break, based on real issues I encountered as a developer and sysadmin. That includes dependencies that \"work today!\" (but probably won't tomorrow) and the mess created by the API instability in gems like json. We will also look at how other programming languages deal with library and their dependencies. Finally, I will tell you why vendoring everything in a system package is a good approach.\n  video_provider: \"youtube\"\n  video_id: \"ueEwcHXyNRA\"\n\n- id: \"joshua-ballanco-ruby-lugdunum-conference-2013\"\n  title: \"A Tale of Two Rubies\"\n  raw_title: \"A Tale of Two Rubies - Joshua Ballanco\"\n  speakers:\n    - Joshua Ballanco\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-20\"\n  published_at: \"2013-10-18\"\n  description: |-\n    Recorded at RuLu 2013. http://rulu.eu/\n\n    We are often told that looking at a programming problem from more than one angle can be the key to finding a solution...but what about programming languages themselves? Does having multiple implementations of Ruby just mean that we can run Ruby code in more places? Or can alternate implementations improve the Ruby language itself? In this talk, I will tell the story of how a bug in JRuby led me to an area of poorly specified behavior in MRI, and how both implementations, and the Ruby language itself, came out better in the end.\n  video_provider: \"youtube\"\n  video_id: \"U-yxcvAxC6s\"\n\n- id: \"arne-brasseur-ruby-lugdunum-conference-2013\"\n  title: \"Web Linguistics: Towards Higher Fluency\"\n  raw_title: \"Web Linguistics: Towards Higher Fluency - Arne Brasseur\"\n  speakers:\n    - Arne Brasseur\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-20\"\n  published_at: \"2013-10-18\"\n  description: |-\n    Recorded at RuLu 2013. http://rulu.eu/\n\n    Do you know what XSS stands for? If not, you'll find out, and you'll learn how to make these vulnerabilities a thing of the past. We'll need to talk about languages first though, and the steps involved in concisely representing meaning.\n    Language is both about expressing and understanding, and in either case there's a lot of machinery involved that we tend to take for granted. By prying these processes apart we might gain some insights to smarten up our code. Does your app generate output as if it learned HTML from a phrase book? Stop being a web tourist and finally become fluent!\n  video_provider: \"youtube\"\n  video_id: \"1B4wWQAiDFA\"\n\n- id: \"vincent-tourraine-ruby-lugdunum-conference-2013\"\n  title: \"Web + native = love\"\n  raw_title: \"Web + native = love - Vincent Tourraine\"\n  speakers:\n    - Vincent Tourraine\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-20\"\n  published_at: \"2013-10-19\"\n  description: |-\n    Recorded at RuLu 2013. http://rulu.eu/\n\n    The fight is over. It's not web apps versus native apps, it's a mobile world, and we need both. Let me tell you a bit about my experience with connected native apps, and why they are essentials. More importantly, how they can work with web apps and web services in order to build truly awesome experiences.\n  video_provider: \"youtube\"\n  video_id: \"PF0deee65Tk\"\n\n- id: \"michael-wawra-ruby-lugdunum-conference-2013\"\n  title: \"From .NET to Ruby\"\n  raw_title: \"From .NET to Ruby - Michael Wawra\"\n  speakers:\n    - Michael Wawra\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-20\"\n  published_at: \"2013-10-20\"\n  description: |-\n    Recorded at RuLu 2013. http://rulu.eu/\n\n    Think of the satisfaction you felt the first time you wrote a chain of Ruby method calls, as a C# developer, this was a scary moment. In this talk Michael will describe unlearning the C# way as he learned the Ruby way. How the languages compare, how the toolbox differ, and the pure joy of the brevity built into Ruby.\n  video_provider: \"youtube\"\n  video_id: \"b5re7NnYDik\"\n\n- id: \"pj-hagerty-ruby-lugdunum-conference-2013\"\n  title: \"Ruby Groups: Act Locally - Think Globally\"\n  raw_title: \"Ruby Groups: Act Locally - Think Globally - PJ Hagerty\"\n  speakers:\n    - PJ Hagerty\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-20\"\n  published_at: \"2013-10-20\"\n  description: |-\n    Recorded at RuLu 2013. http://rulu.eu/\n\n    There are thousands of local Ruby groups worldwide. Sadly, many suffer along, become stagnant, some even die off. How can you make your local Ruby Group better and in so doing, improve the global Ruby Community? This talk focuses on the human side of getting a group together and making it successful so the members, as a group can contribute to the larger community. It is a universally useful guide to improving all parts of the ruby community, starting on a local level.\n  video_provider: \"youtube\"\n  video_id: \"r8PVS5GKIpk\"\n\n- id: \"thomas-riboulet-ruby-lugdunum-conference-2013\"\n  title: \"Let's take a walk\"\n  raw_title: \"Let's take a walk - Thomas Riboulet\"\n  speakers:\n    - Thomas Riboulet\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-20\"\n  published_at: \"2013-10-20\"\n  description: |-\n    Recorded at RuLu 2013. http://rulu.eu/\n\n    We are no factory: we are delicate organic systems that can work nicely if they are respected and used properly. We do not crash because we don't do enough, we crash because we do too much. We continually push ourselves to work, deliver and build : we expect and are expected to produce a lot. We forget we are not factories producing tons of product every day. We are machines, biological ones, tailored by millennia of genetic history. Ignoring this, leads to crashes.\n\n    What is a proper schedule for our brain to learn and process information? Why can't we stay focused for 8 hours? What is the impact of sleep and naps? What is the impact of physical activity in our daily lives? In this talk we will see how much modern workplaces and schedules are disconnected from our biology, how we can change little things to avoid big crashes, work better and be happier.\n  video_provider: \"youtube\"\n  video_id: \"0I6SazTh1D0\"\n\n## Day 2 - 2013-06-21\n\n- id: \"laurent-sansonetti-rulu-2013\"\n  title: \"Workshop: RubyMotion\"\n  raw_title: \"RubyMotion - Laurent Sansonetti\"\n  speakers:\n    - Laurent Sansonetti\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-21\"\n  description: |-\n    RubyMotion is a revolutionary toolchain that lets you quickly develop and test native iOS and OS X applications for iPhone, iPad and Mac, all using the awesome Ruby language you know and love.\n\n    We will introduce the iOS system, RubyMotion, then write our very first iOS app: a timezone converter! This workshop is derived from RubyMotion official training.\n  video_provider: \"not_recorded\"\n  video_id: \"laurent-sansonetti-rulu-2013\"\n\n- id: \"haikel-guemar-rulu-2013\"\n  title: \"Workshop: Coding Dojo\"\n  raw_title: \"Coding Dojo - Haikel Guémar\"\n  speakers:\n    - Haikel Guémar\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-21\"\n  description: |-\n    A Coding Dojo id merely a gathering of programmers practicing their craft without worrying about deadlines or pointy-haired bosses, a safe place to practice, experiment and learn new skills. More importantly, it's a place to have fun together!\n\n    After a short introduction to Coding Dojo, we will practice two katas. The katas will also focus on SOLID principles and using test doubles. You'll practice pair programming, Test-Driven Development, emergent design, etc.\n  video_provider: \"not_recorded\"\n  video_id: \"haikel-guemar-rulu-2013\"\n\n- id: \"damien-matthieu-rulu-2013\"\n  title: \"Workshop: Rails 4\"\n  raw_title: \"Rails 4 - Damien Matthieu\"\n  speakers:\n    - Damien Matthieu\n  event_name: \"Ruby Lugdunum Conference 2013\"\n  date: \"2013-06-21\"\n  description: |-\n    Ready to upgrade to Rails 4? Even if you're familiar with previous versions of Rails, there may be some tricks and tweaks you don't know!\n\n    The workshop will be split in 3 sessions. We first install Rails 4 and Ruby 2, and set things up for testing. Then, we create a Rails app with basic CRUD scaffolding. Finally, we move on to a more advanced Rails app with JSON APIs.\n  video_provider: \"not_recorded\"\n  video_id: \"damien-matthieu-rulu-2013\"\n"
  },
  {
    "path": "data/rulu/rulu-2014/event.yml",
    "content": "---\nid: \"PLWO0_50XhBj8i99jLQMMW30Dq2SURyYxx\"\ntitle: \"Ruby Lugdunum Conference 2014\"\nkind: \"conference\"\nlocation: \"Lyon, France\"\ndescription: |-\n  Talks recorded at RuLu 2014\npublished_at: \"2014-11-20\"\nstart_date: \"2014-06-19\"\nend_date: \"2014-06-20\"\nchannel_id: \"UCFqRbkEEaM4w1iEK1ovBXxg\"\nyear: 2014\nwebsite: \"https://2014.rulu.fr\"\ncoordinates:\n  latitude: 45.764043\n  longitude: 4.835659\naliases:\n  - Ruby Lugdunum 2014\n"
  },
  {
    "path": "data/rulu/rulu-2014/videos.yml",
    "content": "# Website: https://2014.rulu.fr\n# Schedule: https://2014.rulu.fr/schedule/\n# Repo: https://github.com/lyonrb/rulu2014\n---\n## Day 1\n\n- id: \"chris-kelly-ruby-lugdunum-conference-2014\"\n  title: \"String Theory\"\n  raw_title: \"String Theory\"\n  speakers:\n    - Chris Kelly\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-19\"\n  published_at: \"2015-02-01\"\n  video_provider: \"youtube\"\n  video_id: \"zWQFhC-hmoY\"\n  description: |-\n    Peer into the dark and mysterious world of Ruby internals, delve to the point that the basic String becomes a complex web of optimizations, flags and peculiarities. The starting point for String Theory is the observation that immutable strings are more performant than mutable ones, and 23 character strings are more performant than longer ones. The how and why of these idiosyncrasies is where our journey begins. We'll chip away at the Ruby VM to explore how String is implemented in C, to fully understand String Theory we'll need to journey into Ruby memory structures and ultimately to the garbage collector. Get your spelunking gear ready as we discover how the GC has evolved, once we emerge from the darkness you'll see Ruby in a whole new light.\n\n- id: \"emily-stolfo-ruby-lugdunum-conference-2014\"\n  title: \"Wrapper's Delight\"\n  raw_title: \"Wrapper's Delight\"\n  speakers:\n    - Emily Stolfo\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-19\"\n  published_at: \"2015-04-28\"\n  video_provider: \"youtube\"\n  video_id: \"4GOCfpmSdeQ\"\n  description: |-\n    Many of us have found ourselves writing a Ruby API to wrap another API but caught up in the tension between feature over-exposure and idiomatic consistency. It isn't always obvious whether it's better to favor flexibility by exposing the underlying API itself or to commit to a concrete level of abstraction. In using the Ruby driver to MongoDB as an example, we'll explore some of the choices us wrappers have to make in building the best API.\n\n    There are two main points to keep in mind while building an API and making design choices: Ruby gem API design is a form of user experience design and a good API should be easy to maintain. We'll take a look at a number of UX principles and see how they apply to API design and discuss how to optimize for unanticipated changes in what we are wrapping.\n\n- id: \"yannick-schutz-ruby-lugdunum-conference-2014\"\n  title: \"PostgreSQL for the Ruby/Rails Developer\"\n  raw_title: \"Postgresql for the ruby/rails developer\"\n  speakers:\n    - Yannick Schutz\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-19\"\n  published_at: \"2015-02-01\"\n  video_provider: \"youtube\"\n  video_id: \"DrjmtS59j6k\"\n  description: |-\n    Frameworks tend to abstract more and more the database to provide users a similar experience using MySQL, SQLite, PostgreSQL and some even try to abstract over MongoDB. It is important to bring back the power of the database to the web developer.\n\n    The database is where all your data lives and is the most important piece of your architecture. Tame your database and learn its inner power to bring a better experience to your users. My favorite animal is PostgreSQL. What you will learn here:\n\n    - How multi columns indexes, partial indexes and functional indexes will turn your old Lada to a Lamborghini.\n    - JSON and Hstore columns. Bring the NoSQL to your SQL with grace. See how your tables says thanks when you stop adding columns to them every 5 minutes when a store column give you power for the next ten features.\n    - Arel: How to level up your ActiveRecord to do what basic it cannot do alone. I'm looking at you OR queries.\n    - Plain text queries in your Ruby and how it is not always SQL injection-ish. SQL can do magical stuff for you too.\n    - psql, EXPLAIN ANALYZE, testing indexes, using pg_stat_statements, and some queries that will tell you what is wrong with that database.\n\n    It might also interest you, GO/PHP/Python dev!\n\n- id: \"sam-phippen-ruby-lugdunum-conference-2014\"\n  title: \"Anatomy of a Mocked Call\"\n  raw_title: \"Anatomy of a mocked call\"\n  speakers:\n    - Sam Phippen\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-19\"\n  published_at: \"2015-02-02\"\n  video_provider: \"youtube\"\n  video_id: \"5xJaM6B6JRs\"\n  description: |-\n    RSpec is often accused of being \"full of magic\". For the most part: I disagree. However: mocking a method on an object, calling it, recording that call and then working out if expectations have been violated after the fact is a complex set of operations.\n\n    This talk will give a guided tour, with code, through RSpec's mocks. We'll look at one of the most simple cases possible. We'll also look at the most complicated case I can conceive of. Hopefully everyone will learn a little something about testing whilst watching this talk.\n\n- id: \"eloy-durn-ruby-lugdunum-conference-2014\"\n  title: \"RubyMotion Under the Bonnet\"\n  raw_title: \"RubyMotion under the bonnet\"\n  speakers:\n    - Eloy Durán\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-19\"\n  published_at: \"2014-11-25\"\n  video_provider: \"youtube\"\n  video_id: \"3h0W-zorIL8\"\n  description: |-\n    RubyMotion is a toolchain that lets you develop native applications using the Ruby language. This talk will focus on what makes RubyMotion tick and take a look at Ruby from a static point of view, covering topics such as AOT vs JIT compilation, memory management, and interfacing with different languages and runtimes.\n\n- id: \"konstantin-tennhard-ruby-lugdunum-conference-2014\"\n  title: \"Large-scale Rails Applications\"\n  raw_title: \"Large-scale Rails Applications\"\n  speakers:\n    - Konstantin Tennhard\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-19\"\n  published_at: \"2014-11-25\"\n  video_provider: \"youtube\"\n  video_id: \"80S6vYwz4DI\"\n  description: |-\n    Building large-scale applications is a demanding process – no matter which framework you use. The true challenge, however, lies in maintaining these applications. To guarantee maintainability, we need to focus on the following three aspects: comprehensibility, modularity, and robustness. And easy to maintain applications make developers happy!\n\n    This talk is about building large scale applications on top of Ruby on Rails. The framework is known for getting you started quickly, but is it still a good choice when your application grows past 100,000 lines of code?\n\n## Day 2\n\n- id: \"tom-stuart-ruby-lugdunum-conference-2014\"\n  title: \"Compilers for Free\"\n  raw_title: \"Compilers for Free\"\n  speakers:\n    - Tom Stuart\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-20\"\n  published_at: \"2015-04-28\"\n  video_provider: \"youtube\"\n  video_id: \"9oHdvKkuWno\"\n  description: |-\n    Partial evaluation is a powerful tool for timeshifting some aspects of a program's execution from the future into the present. Among other things, it gives us an automatic way to turn a general, abstract program into a faster, more specialised one.\n\n    This maths-free talk uses Ruby to explain how partial evaluation works, how it can be used to make programs go faster, and how it compares to ideas like currying and partial application from the world of functional programming. It then investigates what happens when you run a partial evaluator on itself, and reveals some surprising results about how these techniques can be used to automatically generate compilers instead of writing them from scratch.\n\n- id: \"paolo-perrotta-ruby-lugdunum-conference-2014\"\n  title: \"A Problem with Frogs\"\n  raw_title: \"A Problem with Frogs\"\n  speakers:\n    - Paolo Perrotta\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-20\"\n  published_at: \"2014-12-15\"\n  video_provider: \"youtube\"\n  video_id: \"z5v53qXqo9E\"\n  description: |-\n    When you tell people that you’re a programmer, they think that you work with complicated stuff. But you know better: not everything that you do is complicated. Most things that you do are much worse than that.\n\n    This is a speech about the theory of complexity—but don’t worry, it’s more fun than it sounds. I’ll try to answer a question that applies to most things you do as a developer, from writing code to talking to customers: how do you solve a problem, when you don’t even know what the problem is?\n\n- id: \"arnab-deka-ruby-lugdunum-conference-2014\"\n  title: \"Modern Concurrency Practices in Ruby\"\n  raw_title: \"Modern Concurrency Practices in Ruby\"\n  speakers:\n    - Arnab Deka\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-20\"\n  published_at: \"2015-04-29\"\n  video_provider: \"youtube\"\n  video_id: \"aqqoD9r4cWw\"\n  description: |-\n    So you think that concurrency is a subject lost in the Ruby world? That it's not practical because of the GIL? That the concurrency paradigm that's bundled with Ruby (a.k.a threading) is not the best way to do concurrency?\n\n    Think again. The Ruby concurrency story has advanced a lot in the last couple of years. Have you heard of people talking about actor-based concurrency, using futures, Software Transactional Memory, channels etc. and want to know more about those?\n\n    This talk is a primer on these different paradigms of concurrency, briefly touching on the traditional threads-based model, but focusing more on modern paradigms like actors/futures/STM/channels, with examples and demos.\n\n- id: \"cameron-daigle-ruby-lugdunum-conference-2014\"\n  title: \"More Code, Fewer Pixels\"\n  raw_title: \"More Code, Fewer Pixels\"\n  speakers:\n    - Cameron Daigle\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-20\"\n  published_at: \"2015-04-29\"\n  video_provider: \"youtube\"\n  video_id: \"jNdsClEOC3I\"\n  description: |-\n    Removing the \"Design Phase\". Eschewing Photoshop. Using frameworks. The malleable, flexible, agile nature of web apps these days requires a drastically new approach to how UI concepts are transformed into working code.\n\n    Join me as I dive into the vagaries of Hashrocket's design-develop-revise-repeat feedback loop – and learn how we turn static markup into an essential communication tool through rich UI prototyping, generated content, and general cleverness.\n\n- id: \"terence-lee-ruby-lugdunum-conference-2014\"\n  title: \"Ruby & You\"\n  raw_title: \"Ruby & You\"\n  speakers:\n    - Terence Lee\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-20\"\n  published_at: \"2015-02-14\"\n  video_provider: \"youtube\"\n  video_id: \"QydSpDCoskk\"\n  description: |-\n    On November 22, 2013, a devastating security exploit was publicized to the Ruby community: Heap Overflow in Floating Point Parsing (CVE-2013-4164). There were no fixes provided for Ruby 1.9.2.\n\n    At Heroku, we realized this impacted our ability to provide reliable runtime support. Not wanting to leave our customers high and dry, Heroku released Ruby 1.8.7 and 1.9.2 security patches on our runtimes and pushed to get them upstream.\n\n    This talk goes through the steps and mistakes I learned on how to interact with members of ruby-core, tell war stories from core, and explain how you can get contributions upstream and improve Ruby for everyone.\n\n- id: \"discussion-ruby-future-rulu-2014\"\n  title: \"Panel: Discussion of Ruby's Future\"\n  raw_title: \"Discussion of Ruby's Future\"\n  speakers:\n    - TODO\n  event_name: \"Ruby Lugdunum Conference 2014\"\n  date: \"2014-06-20\"\n  video_provider: \"not_published\"\n  video_id: \"discussion-ruby-future-rulu-2014\"\n  description: |-\n    Join us at a café close to the conference to talk about Ruby's future with our panelists.\n"
  },
  {
    "path": "data/rulu/series.yml",
    "content": "---\nname: \"Ruby Lugdunum Conference\"\nwebsite: \"http://2014.rulu.fr\"\ntwitter: \"lyonrb\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"FR\"\nyoutube_channel_name: \"Lyonrb\"\nlanguage: \"french\"\nyoutube_channel_id: \"UCFqRbkEEaM4w1iEK1ovBXxg\"\naliases:\n  - RuLu Conference\n  - RuLu Conf\n  - RuLu Ruby Conference\n"
  },
  {
    "path": "data/rupy/rupy-2009/event.yml",
    "content": "---\nid: \"rupy-2009\"\ntitle: \"RuPy 2009\"\ndescription: \"\"\nlocation: \"Poznań, Poland\"\nkind: \"conference\"\nstart_date: \"2009-11-07\"\nend_date: \"2009-11-08\"\noriginal_website: \"http://rupy.eu\"\ncoordinates:\n  latitude: 52.40567859999999\n  longitude: 16.9312766\n"
  },
  {
    "path": "data/rupy/rupy-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/rupy/series.yml",
    "content": "---\nname: \"RuPy\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"PL\"\naliases:\n  - Rupy\n"
  },
  {
    "path": "data/saint-p-rubyconf/saint-p-rubyconf-2018/event.yml",
    "content": "---\nid: \"saint-p-rubyconf-2018\"\ntitle: \"Saint P Rubyconf 2018\"\ndescription: \"\"\nlocation: \"Saint Petersburg, Russia\"\nkind: \"conference\"\nstart_date: \"2018-06-10\"\nend_date: \"2018-06-10\"\nwebsite: \"https://spbrubyconf.ru/\"\ncoordinates:\n  latitude: 59.9310584\n  longitude: 30.3609097\n"
  },
  {
    "path": "data/saint-p-rubyconf/saint-p-rubyconf-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: -\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/saint-p-rubyconf/saint-p-rubyconf-2019/event.yml",
    "content": "---\nid: \"saint-p-rubyconf-2019\"\ntitle: \"Saint P Rubyconf 2019\"\ndescription: \"\"\nlocation: \"Saint Petersburg, Russia\"\nkind: \"conference\"\nstart_date: \"2019-06-01\"\nend_date: \"2019-06-02\"\nwebsite: \"https://spbrubyconf.ru/\"\nplaylist: \"https://www.youtube.com/watch?v=CjOwKbf8L3I\"\ncoordinates:\n  latitude: 59.9310584\n  longitude: 30.3609097\n"
  },
  {
    "path": "data/saint-p-rubyconf/saint-p-rubyconf-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://spbrubyconf.ru/\n# Videos: https://www.youtube.com/watch?v=CjOwKbf8L3I\n---\n[]\n"
  },
  {
    "path": "data/saint-p-rubyconf/saint-p-rubyconf-2020/event.yml",
    "content": "---\nid: \"saint-p-rubyconf-2020\"\ntitle: \"Saint P Rubyconf 2020 (Cancelled)\"\ndescription: \"\"\nlocation: \"Saint Petersburg, Russia\"\nkind: \"conference\"\nstart_date: \"2020-06-06\"\nend_date: \"2020-06-07\"\nwebsite: \"https://spbrubyconf.ru/\"\nstatus: \"cancelled\"\ncoordinates:\n  latitude: 59.9310584\n  longitude: 30.3609097\n"
  },
  {
    "path": "data/saint-p-rubyconf/saint-p-rubyconf-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://spbrubyconf.ru/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/saint-p-rubyconf/saint-p-rubyconf-2021/event.yml",
    "content": "---\nid: \"saint-p-rubyconf-2021\"\ntitle: \"Saint P Rubyconf 2021\"\ndescription: \"\"\nlocation: \"Saint Petersburg, Russia\"\nkind: \"conference\"\nstart_date: \"2021-06-05\"\nend_date: \"2021-06-05\"\nwebsite: \"https://spbrubyconf.ru/\"\nplaylist: \"https://www.youtube.com/watch?v=MIX8S3n9Nwc\"\ncoordinates:\n  latitude: 59.9310584\n  longitude: 30.3609097\n"
  },
  {
    "path": "data/saint-p-rubyconf/saint-p-rubyconf-2021/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://spbrubyconf.ru/\n# Videos: https://www.youtube.com/watch?v=MIX8S3n9Nwc\n---\n[]\n"
  },
  {
    "path": "data/saint-p-rubyconf/series.yml",
    "content": "---\nname: \"Saint P Rubyconf\"\nwebsite: \"\"\ntwitter: \"saintprug\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/scotlandonrails/scotlandonrails-2008/event.yml",
    "content": "---\nid: \"scotlandonrails-2008\"\ntitle: \"Scotland on Rails 2008\"\nkind: \"conference\"\nlocation: \"Edinburgh, Scotland, UK\"\ndescription: |-\n  Scotland on Rails 2008\nstart_date: \"2008-04-04\"\nend_date: \"2008-04-05\"\nyear: 2008\nwebsite: \"https://web.archive.org/web/20080316084102/http://scotlandonrails.com\"\noriginal_website: \"http://scotlandonrails.com/\"\ncoordinates:\n  latitude: 55.953252\n  longitude: -3.188267\n"
  },
  {
    "path": "data/scotlandonrails/scotlandonrails-2008/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://web.archive.org/web/20080302034424/http://www.scotlandonrails.com/talks\n# https://rubyonrails.org/2008/2/29/registration-is-open-for-scotland-on-rails\n---\n[]\n"
  },
  {
    "path": "data/scotlandonrails/scotlandonrails-2009/event.yml",
    "content": "---\nid: \"scotlandonrails-2009\"\ntitle: \"Scotland on Rails 2009\"\nkind: \"conference\"\nlocation: \"Edinburgh, Scotland, UK\"\ndescription: |-\n  Scotland on Rails 2009\nstart_date: \"2009-03-26\"\nend_date: \"2009-03-28\"\nyear: 2009\nwebsite: \"https://web.archive.org/web/20090605000000/http://scotlandonrails.com/\"\noriginal_website: \"http://scotlandonrails.com/\"\ncoordinates:\n  latitude: 55.953252\n  longitude: -3.188267\n"
  },
  {
    "path": "data/scotlandonrails/scotlandonrails-2009/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://web.archive.org/web/20090918185130/http://scotlandonrails.com/\n# https://urgetopunt.com/2009/04/01/scotland-on-rails.html\n# https://johntopley.com/2009/04/08/scotland-on-rails-2009/index.html\n---\n[]\n"
  },
  {
    "path": "data/scotlandonrails/series.yml",
    "content": "---\nname: \"Scotland on Rails\"\nwebsite: \"http://scotlandonrails.com\"\ntwitter: \"scotlandonrails\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/scottish-ruby-conf/scottish-ruby-conf-2010/event.yml",
    "content": "---\nid: \"scottish-ruby-conf-2010\"\ntitle: \"Scottish Ruby Conf 2010\"\ndescription: \"\"\nlocation: \"Edinburgh, Scotland, UK\"\nkind: \"conference\"\nstart_date: \"2010-03-26\"\nend_date: \"2010-03-27\"\nwebsite: \"https://web.archive.org/web/20100629050148/http://video2010.scottishrubyconference.com/\"\noriginal_website: \"http://scottishrubyconference.com\"\ncoordinates:\n  latitude: 55.953252\n  longitude: -3.188267\n"
  },
  {
    "path": "data/scottish-ruby-conf/scottish-ruby-conf-2010/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Photos: https://www.flickr.com/groups/scotruby2010/pool/\n# https://web.archive.org/web/20100912010027/http://speakerrate.com/events/344-scottish-ruby-conference\n# https://web.archive.org/web/20100629050148/http://video2010.scottishrubyconference.com/\n---\n[]\n"
  },
  {
    "path": "data/scottish-ruby-conf/scottish-ruby-conf-2011/event.yml",
    "content": "---\nid: \"scottish-ruby-conf-2011\"\ntitle: \"Scottish Ruby Conf 2011\"\ndescription: \"\"\nlocation: \"Edinburgh, Scotland, UK\"\nkind: \"conference\"\nstart_date: \"2011-04-07\"\nend_date: \"2011-04-09\"\nwebsite: \"https://web.archive.org/web/20110702212114/http://scottishrubyconference.com/posts\"\noriginal_website: \"http://scottishrubyconference.com\"\ncoordinates:\n  latitude: 55.953252\n  longitude: -3.188267\n"
  },
  {
    "path": "data/scottish-ruby-conf/scottish-ruby-conf-2011/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://web.archive.org/web/20110702212114/http://scottishrubyconference.com/posts\n# https://www.flickr.com/groups/scotruby2011/pool/\n---\n[]\n"
  },
  {
    "path": "data/scottish-ruby-conf/scottish-ruby-conf-2012/event.yml",
    "content": "---\nid: \"scottish-ruby-conf-2012\"\ntitle: \"Scottish Ruby Conf 2012\"\ndescription: \"\"\nlocation: \"Edinburgh, Scotland, UK\"\nkind: \"conference\"\nstart_date: \"2012-06-29\"\nend_date: \"2012-06-30\"\nwebsite: \"https://web.archive.org/web/20120521184005/http://scottishrubyconference.com/\"\noriginal_website: \"http://scottishrubyconference.com\"\ncoordinates:\n  latitude: 55.953252\n  longitude: -3.188267\n"
  },
  {
    "path": "data/scottish-ruby-conf/scottish-ruby-conf-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# https://web.archive.org/web/20120521184005/http://scottishrubyconference.com/\n---\n[]\n"
  },
  {
    "path": "data/scottish-ruby-conf/scottish-ruby-conf-2013/event.yml",
    "content": "---\nid: \"scottish-ruby-conf-2013\"\ntitle: \"Scottish Ruby Conf 2013\"\ndescription: \"\"\nlocation: \"Perthshire, Scotland, UK\"\nkind: \"conference\"\nstart_date: \"2013-05-12\"\nend_date: \"2013-05-13\"\nwebsite: \"https://web.archive.org/web/20240104093801/http://2013.scottishrubyconference.com/\"\noriginal_website: \"http://2013.scottishrubyconference.com/\"\ncoordinates:\n  latitude: 57.7470127655324\n  longitude: -4.687305781018138\n"
  },
  {
    "path": "data/scottish-ruby-conf/scottish-ruby-conf-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/scottish-ruby-conf/scottish-ruby-conf-2014/event.yml",
    "content": "---\nid: \"scottish-ruby-conf-2014\"\ntitle: \"Scottish Ruby Conf 2014\"\ndescription: \"\"\nlocation: \"Perthshire, Scotland, UK\"\nkind: \"conference\"\nstart_date: \"2014-05-12\"\nend_date: \"2014-05-13\"\nwebsite: \"https://web.archive.org/web/20230503184426/http://2014.scottishrubyconference.com/\"\noriginal_website: \"http://2014.scottishrubyconference.com\"\nplaylist: \"https://confreaks.tv/events/scottishrubyconf2014\"\nfeatured_color: \"#FFFFFF\"\nfeatured_background: \"#000000\"\nbanner_background: \"#000000\"\nlast_edition: true\ncoordinates:\n  latitude: 57.7470127655324\n  longitude: -4.687305781018138\n"
  },
  {
    "path": "data/scottish-ruby-conf/scottish-ruby-conf-2014/videos.yml",
    "content": "# TODO: Add lightning talks\n\n# Website: http://scottishrubyconference.com\n# Schedule: https://web.archive.org/web/20140702200220/http://programme2014.scottishrubyconference.com/schedule\n# Videos: https://vimeo.com/edgecaseuk\n---\n- id: \"evan-phoenix-scottish-ruby-conference-2014\"\n  title: \"Keynote: Reading Code\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"96882200\"\n  speakers:\n    - Evan Phoenix\n  date: \"2014-05-12\"\n\n- id: \"tom-stuart-scottish-ruby-conference-2014\"\n  title: \"I Have No Idea What I’m Doing\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: |-\n    One day I found a note on my desk at home. I had no memory of writing it, but the handwriting was unmistakably mine. “I HAVE NO IDEA WHAT I’M DOING”, it said. In this talk I’ll confirm that I have no idea what I’m doing, and explain why that’s not necessarily a bad thing.\n  video_provider: \"vimeo\"\n  video_id: \"96882197\"\n  speakers:\n    - Tom Stuart\n  date: \"2014-05-12\"\n\n- id: \"klaas-jan-wierenga-scottish-ruby-conference-2014\"\n  title: \"State machines are everywhere! Let's face it.\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: |-\n    State machines are everywhere. In fact the theoretical basis of our universe, quantum physics, consists of microscopic quantum state machines. These particles find themselves in discrete quantum states and can change state only in certain ways via uninterruptible transitions known as quantum leaps. Voila a perfect state machine.\n\n    State machines control the phone call between you and your mother to ensure that you get connected when both of you pick up the phone at exactly the same time.\n\n    State machines are paramount in the development of robust hypermedia API’s. The messages drive the application state (machine).\n\n    In general the state machine helps to simplify the logic to ensure your program responds appropriately in whatever order you throw events at it.\n\n    In this talk we will explore the powerful features of hierarchical state machines and look at how you can use them to accomplish simplexity in your programs.\n\n    Simplexity: complexity wrapped in something simple.\n  video_provider: \"vimeo\"\n  video_id: \"97522204\"\n  speakers:\n    - Klaas Jan Wierenga\n  date: \"2014-05-12\"\n\n- id: \"todo-klaas-jan-wierenga-scottish-ruby-conference-2014\"\n  title: \"Non-violent Communication\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: |-\n    96882198\n  video_provider: \"not_recorded\"\n  video_id: \"todo-klaas-jan-wierenga-scottish-ruby-conference-2014\"\n  speakers:\n    - Matt Wynne\n  date: \"2014-05-12\"\n\n- id: \"caleb-hearth-scottish-ruby-conference-2014\"\n  title: \"Not Invented Here: Things Rails Didn't Innovate\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"96882201\"\n  speakers:\n    - Caleb Hearth\n  date: \"2014-05-12\"\n\n- id: \"kerri-miller-scottish-ruby-conference-2014\"\n  title: \"Concurrency for !Dummies (Who Don't Get It (...Yet))\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"97522205\"\n  speakers:\n    - Kerri Miller\n  date: \"2014-05-12\"\n\n- id: \"nat-buckley-scottish-ruby-conference-2014\"\n  title: \"ntlk's engineering delights\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"96882330\"\n  speakers:\n    - Nat Buckley\n  date: \"2014-05-12\"\n\n- id: \"emily-stolfo-scottish-ruby-conference-2014\"\n  title: \"Thread Safety First\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"97522862\"\n  speakers:\n    - Emily Stolfo\n  date: \"2014-05-12\"\n\n- id: \"justin-searls-scottish-ruby-conference-2014\"\n  title: \"Office politics for the thin-skinned developer\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"96882203\"\n  speakers:\n    - Justin Searls\n  date: \"2014-05-12\"\n\n- id: \"workshop-getting-started-osc-scottish-ruby-conference-2014\"\n  title: \"Workshop: Getting started with Open Source Contributions\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-getting-started-osc-scottish-ruby-conference-2014\"\n  speakers:\n    - Matt Wynne\n    - André Arko\n  date: \"2014-05-12\"\n\n- id: \"maria-gutierrez-scottish-ruby-conference-2014\"\n  title: \"Choosing Management: a Programmer at the crossroads\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"98250947\"\n  speakers:\n    - Maria Gutierrez\n  date: \"2014-05-12\"\n\n- id: \"andy-pliszka-scottish-ruby-conference-2014\"\n  title: \"Introduction to CRuby source code\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"96882332\"\n  speakers:\n    - Andy Pliszka\n  date: \"2014-05-12\"\n\n- id: \"workshop-tom-stuart-scottish-ruby-conference-2014\"\n  title: \"Workshop: Web applications from scratch\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"workshop-tom-stuart-scottish-ruby-conference-2014\"\n  speakers:\n    - Tom Stuart\n  date: \"2014-05-12\"\n\n- id: \"steven-r-baker-scottish-ruby-conference-2014\"\n  title: \"Managing and Working with Remote Teams\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"98434413\"\n  speakers:\n    - Steven R. Baker\n  date: \"2014-05-12\"\n\n- id: \"martin-evans-scottish-ruby-conference-2014\"\n  title: \"Coding a new generation\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"96882204\"\n  speakers:\n    - Martin Evans\n    - Luke Evans\n  date: \"2014-05-12\"\n\n- id: \"johnny-winn-scottish-ruby-conference-2014\"\n  title: \"Elixir = Ruby, A Pattern Matching\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"98250948\"\n  speakers:\n    - Johnny Winn\n  date: \"2014-05-13\"\n\n- id: \"jess-eldredge-scottish-ruby-conference-2014\"\n  title: \"Sketchnoting: Creative Notes for Technical Content\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"98251170\"\n  speakers:\n    - Jess Eldredge\n  date: \"2014-05-13\"\n\n- id: \"lori-m-olson-scottish-ruby-conference-2014\"\n  title: \"Do the Work\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"98250946\"\n  speakers:\n    - Lori M Olson\n  date: \"2014-05-13\"\n\n- id: \"todo-scottish-ruby-conference-2014\"\n  title: \"Lightning talks\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"96825209\"\n  speakers:\n    - TODO\n  date: \"2014-05-13\"\n\n- id: \"chrissy-welsh-scottish-ruby-conference-2014\"\n  title: \"The hitchhikers guide to UXing without a UXer\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"98251819\"\n  speakers:\n    - Chrissy Welsh\n  date: \"2014-05-13\"\n\n- id: \"fernand-galiana-scottish-ruby-conference-2014\"\n  title: \"In the land of graphs...\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"97522206\"\n  speakers:\n    - Fernand Galiana\n  date: \"2014-05-13\"\n\n- id: \"gautam-rege-scottish-ruby-conference-2014\"\n  title: \"The Dark Side of Ruby\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"96882392\"\n  speakers:\n    - Gautam Rege\n  date: \"2014-05-13\"\n\n- id: \"graham-lee-scottish-ruby-conference-2014\"\n  title: \"Architectural Patterns for Wetware Systems\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: |-\n    TODO\n  video_provider: \"vimeo\"\n  video_id: \"97522207\"\n  speakers:\n    - Graham Lee\n  date: \"2014-05-13\"\n\n- id: \"todo-mike-moore-scottish-ruby-conference-2014\"\n  title: \"Writing a game in Ruby\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"todo-mike-moore-scottish-ruby-conference-2014\"\n  speakers:\n    - Mike Moore\n  date: \"2014-05-13\"\n\n- id: \"andr-arko-scottish-ruby-conference-2014\"\n  title: \"The Tip of the Iceberg: Development Was the Easy Part\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"96882390\"\n  speakers:\n    - André Arko\n  date: \"2014-05-13\"\n\n- id: \"todo-amy-lynch-scottish-ruby-conference-2014\"\n  title: \"It's up to us!\"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"not_recorded\"\n  video_id: \"todo-amy-lynch-scottish-ruby-conference-2014\"\n  speakers:\n    - Amy Lynch\n  date: \"2014-05-13\"\n\n- id: \"ron-evans-scottish-ruby-conference-2014\"\n  title: \"Keynote: \"\n  event_name: \"Scottish Ruby Conference 2014\"\n  description: \"\"\n  video_provider: \"vimeo\"\n  video_id: \"98844313\"\n  speakers:\n    - Ron Evans\n  date: \"2014-05-13\"\n"
  },
  {
    "path": "data/scottish-ruby-conf/series.yml",
    "content": "---\nname: \"Scottish Ruby Conf\"\nwebsite: \"http://scottishrubyconference.com\"\ntwitter: \"scotrubyconf\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/sekigahara-rubykaigi/sekigahara-rubykaigi-01/event.yml",
    "content": "---\nid: \"sekigahara-rubykaigi-01\"\ntitle: \"Sekigahara RubyKaigi 01\"\naliases:\n  - 関ケ原Ruby会議01\nkind: \"conference\"\nwebsite: \"https://regional.rubykaigi.org/sekigahara01/\"\nlocation: \"Sekigahara, Gifu, JP\"\ndescription: |-\n  関ケ原Ruby会議01は、天下分け目の地「関ケ原」で開催される地域Ruby会議です。 歴史ある古戦場で、新たなRubyの歴史を刻みましょう。\nyear: 2026\nstart_date: \"2026-05-30\"\nend_date: \"2026-05-30\"\ncoordinates:\n  latitude: 35.36684987274667\n  longitude: 136.46685696928364\nbanner_background: \"#DDBD58\"\nfeatured_background: \"#DDBD58\"\nfeatured_color: \"#332F2E\"\n"
  },
  {
    "path": "data/sekigahara-rubykaigi/sekigahara-rubykaigi-01/involvements.yml",
    "content": "---\n- name: \"Organizers\"\n  users:\n    - Yudai Takada\n    - Daisuke Aritomo\n    - Takahiro Tsuchiya\n    - soul\n    - Natsuko Nadoyama\n    - Pasta-K\n\n- name: \"Designer\"\n  users:\n    - Yuka Atsumi\n\n- name: \"Support\"\n  organisations:\n    - Nihon Ruby no Kai\n"
  },
  {
    "path": "data/sekigahara-rubykaigi/sekigahara-rubykaigi-01/venue.yml",
    "content": "---\nname: \"関ケ原ふれあいセンター\"\nurl: \"https://www.town.sekigahara.gifu.jp/2568.htm\"\naddress:\n  street: \"894-29 Sekigahara, Fuwa District, Gifu 503-1501, Japan\"\n  city: \"Sekigahara\"\n  region: \"Gifu\"\n  postal_code: \"503-1521\"\n  country: \"Japan\"\n  country_code: \"JP\"\n  display: \"503-1521岐阜県不破郡関ケ原町大字関ケ原894-29\"\ncoordinates:\n  latitude: 35.36684987274667\n  longitude: 136.46685696928364\nmaps:\n  google: \"https://maps.app.goo.gl/BBTRC5Dm2ya3Ujm76\"\n"
  },
  {
    "path": "data/sekigahara-rubykaigi/series.yml",
    "content": "---\nname: \"Sekigahara RubyKaigi\"\ntwitter: \"https://x.com/sekigahara01\"\nkind: \"conference\"\nfrequency: \"irregular\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\nyoutube_channel_name: \"\"\nyoutube_channel_id: \"\"\nplaylist_matcher: \"\"\naliases:\n  - \"関ケ原Ruby会議\"\n"
  },
  {
    "path": "data/sf-bay-area-ruby/series.yml",
    "content": "---\nname: \"SF Bay Area Ruby\"\nwebsite: \"https://lu.ma/sfruby\"\ntwitter: \"sfruby\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - SF Bay Area Ruby Meetup\n  - San Francisco Ruby Meetup\n  - San Francisco Bay Area Ruby Meetup\n  - Bay Area Ruby Meetup\n  - Bay Area Ruby\n  - SF Ruby Meetup\n  - SFRuby Meetup\n  - SFRuby\n  - SF Ruby\n"
  },
  {
    "path": "data/sf-bay-area-ruby/sf-bay-area-ruby-meetup/cfp.yml",
    "content": "---\n- link: \"https://forms.gle/C9HQzaT5jvwA5xwc7\"\n"
  },
  {
    "path": "data/sf-bay-area-ruby/sf-bay-area-ruby-meetup/event.yml",
    "content": "---\nid: \"sf-bay-area-ruby-meetup\"\ntitle: \"SF Bay Area Ruby Meetup\"\nlocation: \"San Francisco, CA, United States\"\ndescription: \"\"\npublished_at: \"2024-11-30\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nbanner_background: \"#0038FF\"\nfeatured_background: \"#0038FF\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://lu.ma/sfruby\"\ncoordinates:\n  latitude: 37.7749295\n  longitude: -122.4194155\n"
  },
  {
    "path": "data/sf-bay-area-ruby/sf-bay-area-ruby-meetup/videos.yml",
    "content": "---\n- id: \"sf-bay-area-ruby-meetup-march-2024\"\n  title: \"SF Bay Area Ruby Meetup - March 2024\"\n  raw_title: \"SF Bay Area Ruby Meetup\"\n  event_name: \"SF Bay Area Ruby Meetup - March 2024\"\n  date: \"2024-03-28\"\n  description: |-\n    Hey, Bay Area builders and tinkerers!\n\n    Whether you're weaving magic with Ruby or Rails in your day job, crafting the next big thing in your garage, or simply intrigued by the promise of productivity and sheer joy Ruby and Rails could sprinkle on your 2024 projects, this is where you want to be.\n\n    Learn from the talks, share opinions and make new friends!\n\n    https://lu.ma/r6d0lghm\n  video_provider: \"youtube\"\n  video_id: \"9-PWz9nbrT8\"\n  published_at: \"2024-04-01\"\n  talks:\n    - title: \"Intro: SF Ruby Meetups are back\"\n      date: \"2024-03-28\"\n      start_cue: \"00:04\"\n      end_cue: \"03:29\"\n      id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-march-2024\"\n      video_id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-march-2024\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2024\"\n      thumbnail_xs: \"https://marcoroth.dev/images/resized/GJzK2F1a8AAr2GH-20e0497b-512x.jpg\"\n      thumbnail_sm: \"https://marcoroth.dev/images/resized/GJzK2F1a8AAr2GH-20e0497b-512x.jpg\"\n      thumbnail_md: \"https://marcoroth.dev/images/resized/GJzK2F1a8AAr2GH-20e0497b-512x.jpg\"\n      thumbnail_lg: \"https://marcoroth.dev/images/resized/GJzK2F1a8AAr2GH-20e0497b-512x.jpg\"\n      thumbnail_xl: \"https://marcoroth.dev/images/talks/san-francisco-ruby-meetup-march-2024/saved/GJzK2F1a8AAr2GH.jpg\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Intro: TEKsystems\"\n      date: \"2024-03-28\"\n      start_cue: \"03:29\"\n      end_cue: \"04:35\"\n      id: \"meredith-barry-intro-sf-bay-area-ruby-meetup-march-2024\"\n      video_id: \"meredith-barry-intro-sf-bay-area-ruby-meetup-march-2024\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2024\"\n      speakers:\n        - Meredith Barry\n\n    - title: \"An ok compromise: Faster development by designing for the Rails Autoloader\"\n      date: \"2024-03-28\"\n      start_cue: \"04:35\"\n      end_cue: \"26:46\"\n      id: \"ben-sheldon-autoloading-rails-goodjob-sf-bay-area-ruby-meetup-march-2024\"\n      video_id: \"ben-sheldon-autoloading-rails-goodjob-sf-bay-area-ruby-meetup-march-2024\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2024\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GJ3I7P4bAAAfDS-?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GJ3I7P4bAAAfDS-?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GJ3I7P4bAAAfDS-?format=jpg&name=large\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GJ3I7P4bAAAfDS-?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GJ3I7P4bAAAfDS-?format=jpg&name=4096x4096\"\n      slides_url: \"https://speakerdeck.com/bensheldon/an-ok-compromise-faster-development-by-designing-for-the-rails-autoloader\"\n      speakers:\n        - Ben Sheldon\n\n    - title: \"Announcements: AnyCable\"\n      date: \"2024-03-28\"\n      start_cue: \"26:46\"\n      end_cue: \"28:48\"\n      id: \"irina-nazarova-announcements-sf-bay-area-ruby-meetup-march-2024\"\n      video_id: \"irina-nazarova-announcements-sf-bay-area-ruby-meetup-march-2024\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2024\"\n      thumbnail_xs: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/357/646/134/395/small/cc23b519348ce265.jpg\"\n      thumbnail_sm: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/357/646/134/395/small/cc23b519348ce265.jpg\"\n      thumbnail_md: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/357/646/134/395/small/cc23b519348ce265.jpg\"\n      thumbnail_lg: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/357/646/134/395/small/cc23b519348ce265.jpg\"\n      thumbnail_xl: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/357/646/134/395/original/cc23b519348ce265.jpg\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Announcements: Ruby Central\"\n      date: \"2024-03-28\"\n      start_cue: \"28:48\"\n      end_cue: \"34:17\"\n      id: \"adarsh-pandit-announcements-sf-bay-area-ruby-meetup-march-2024\"\n      video_id: \"adarsh-pandit-announcements-sf-bay-area-ruby-meetup-march-2024\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2024\"\n      thumbnail_xs: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/368/337/309/296/small/bc05ad4fa29c7471.jpg\"\n      thumbnail_sm: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/368/337/309/296/small/bc05ad4fa29c7471.jpg\"\n      thumbnail_md: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/368/337/309/296/small/bc05ad4fa29c7471.jpg\"\n      thumbnail_lg: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/368/337/309/296/small/bc05ad4fa29c7471.jpg\"\n      thumbnail_xl: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/368/337/309/296/original/bc05ad4fa29c7471.jpg\"\n      speakers:\n        - Adarsh Pandit\n\n    - title: \"Announcements: Presenting Hotwire.io\"\n      date: \"2024-03-28\"\n      start_cue: \"34:17\"\n      end_cue: \"39:42\"\n      id: \"marco-roth-announcements-sf-bay-area-ruby-meetup-march-2024\"\n      video_id: \"marco-roth-announcements-sf-bay-area-ruby-meetup-march-2024\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2024\"\n      thumbnail_xs: \"https://marcoroth.dev/images/talks/san-francisco-ruby-meetup-march-2024/saved/a01f2d0ddf0317a8.jpeg\"\n      thumbnail_sm: \"https://marcoroth.dev/images/talks/san-francisco-ruby-meetup-march-2024/saved/a01f2d0ddf0317a8.jpeg\"\n      thumbnail_md: \"https://marcoroth.dev/images/talks/san-francisco-ruby-meetup-march-2024/saved/a01f2d0ddf0317a8.jpeg\"\n      thumbnail_lg: \"https://marcoroth.dev/images/talks/san-francisco-ruby-meetup-march-2024/saved/a01f2d0ddf0317a8.jpeg\"\n      thumbnail_xl: \"https://marcoroth.dev/images/talks/san-francisco-ruby-meetup-march-2024/saved/a01f2d0ddf0317a8.jpeg\"\n      slides_url: \"https://speakerdeck.com/marcoroth/hotwire-dot-io-at-san-francisco-ruby-meetup-march-2024-at-github-hq\"\n      speakers:\n        - Marco Roth\n\n    - title: \"Building a Cloud in Thirteen Years using Ruby and Roda\"\n      date: \"2024-03-28\"\n      start_cue: \"39:42\"\n      end_cue: \"1:11:30\"\n      id: \"daniel-farina-building-cloud-ruby-roda-sf-bay-area-ruby-meetup-march-2024\"\n      video_id: \"daniel-farina-building-cloud-ruby-roda-sf-bay-area-ruby-meetup-march-2024\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2024\"\n      thumbnail_xs: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/465/163/819/543/small/44d09ee327bd409d.jpg\"\n      thumbnail_sm: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/465/163/819/543/small/44d09ee327bd409d.jpg\"\n      thumbnail_md: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/465/163/819/543/small/44d09ee327bd409d.jpg\"\n      thumbnail_lg: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/465/163/819/543/small/44d09ee327bd409d.jpg\"\n      thumbnail_xl: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/465/163/819/543/original/44d09ee327bd409d.jpg\"\n      slides_url: \"https://slides.com/fdrfdr/build-a-cloud-in-thirteen-years\"\n      speakers:\n        - Daniel Farina\n\n    - title: \"Rails on WASM - Welcome to the future?\"\n      date: \"2024-03-28\"\n      start_cue: \"1:11:30\"\n      end_cue: \"2:28:47\"\n      id: \"vladimir-dementyev-rails-wasm-browser-sf-bay-area-ruby-meetup-march-2024\"\n      video_id: \"vladimir-dementyev-rails-wasm-browser-sf-bay-area-ruby-meetup-march-2024\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2024\"\n      thumbnail_xs: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/555/355/135/239/small/f9bee13b0082b0c0.jpg\"\n      thumbnail_sm: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/555/355/135/239/small/f9bee13b0082b0c0.jpg\"\n      thumbnail_md: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/555/355/135/239/small/f9bee13b0082b0c0.jpg\"\n      thumbnail_lg: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/555/355/135/239/small/f9bee13b0082b0c0.jpg\"\n      thumbnail_xl: \"https://cdn.masto.host/rubysocial/media_attachments/files/112/176/555/355/135/239/original/f9bee13b0082b0c0.jpg\"\n      slides_url: \"https://speakerdeck.com/palkan/sf-ruby-march-2024-rails-on-wasm\"\n      speakers:\n        - Vladimir Dementyev\n\n- id: \"sf-bay-area-ruby-meetup-july-2024\"\n  title: \"SF Bay Area Ruby Meetup - July 2024\"\n  raw_title: \"SF Bay Area Ruby Meetup in July @ Cisco Meraki\"\n  event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n  date: \"2024-07-18\"\n  published_at: \"2024-07-23\"\n  description: |-\n    Hey, Bay Area builders and tinkerers!\n\n    We continue our exploration of the nicest Ruby HQs of SF, this time visting Cisco Meraki at the Mission Bay. Join us to discuss everything new in the world of Ruby, while make new friends!\n\n    Agenda:\n    – Liz Heym from Meraki with \"Catching Waves with Time-Series Data\"\n    – Lukas Fittl from pganalyze.com \"How to optimize Postgres queries for Rails developers\"\n    – Yang Chung \"Dokku your way to Heroku\"\n    – Cameron Dutro from GitHub \"Let's Write a C Extension!\"\n    – James Kerr \"Borrowing Concepts from React to Build Dynamic Forms in Rails\"\n\n    And an open mic 🎤 for your announcements and questions!\n\n    Submit talk proposals for this and future events here: https://forms.gle/C9HQzaT5jvwA5xwc7\n\n    And catch you on the flip side! Massive shoutout to Cisco Meraki for being our gracious host this time.\n\n    Address: 500 Terry A Francois Blvd, San Francisco, CA 94158\n\n    Brought to you by evilmartians.com–check our open source, blog and come for consulting help any time!\n\n    https://lu.ma/bxzdp6mz\n  video_provider: \"youtube\"\n  video_id: \"A31jZ_7KC5Y\"\n  talks:\n    - title: \"Intro SF Bay Area Ruby Meetup - July 2024\"\n      start_cue: \"00:00\"\n      end_cue: \"07:20\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n      date: \"2024-07-18\"\n      id: \"irina-nazarova-sf-bay-area-meetup-july-2024-intro\"\n      video_id: \"irina-nazarova-sf-bay-area-meetup-july-2024-intro\"\n      video_provider: \"parent\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Welcome to Cisco Merarki\"\n      start_cue: \"07:20\"\n      end_cue: \"16:05\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n      date: \"2024-07-18\"\n      id: \"welcome-to-cisco-meraki-sf-bay-area-meetup-july-2024\"\n      video_id: \"welcome-to-cisco-meraki-sf-bay-area-meetup-july-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Ronan Potage\n\n    - title: \"Catching Waves with Time-Series Data\"\n      start_cue: \"16:05\"\n      end_cue: \"36:55\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n      date: \"2024-07-18\"\n      id: \"liz-heym-catching-waves-time-series-data\"\n      video_id: \"liz-heym-catching-waves-time-series-data\"\n      video_provider: \"parent\"\n      speakers:\n        - Liz Heym\n\n    - title: \"How to Optimize Postgres Queries for Ruby/Rails Developers\"\n      start_cue: \"36:55\"\n      end_cue: \"\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n      date: \"2024-07-18\"\n      id: \"lukas-fittl-optimize-postgres-queries\"\n      video_id: \"lukas-fittl-optimize-postgres-queries\"\n      video_provider: \"parent\"\n      speakers:\n        - Lukas Fittl\n\n    - title: \"Open Mic: Jeremiah Laravel\"\n      start_cue: \"1:06:15\"\n      end_cue: \"1:08:19\"\n      thumbnail_cue: \"1:07:26\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n      date: \"2024-07-18\"\n      id: \"jeremiah-laravel-sf-bay-area-meetup-july-2024\"\n      video_id: \"jeremiah-laravel-sf-bay-area-meetup-july-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Jeremiah Laravel\n\n    - title: \"Open Mic: Why Should I Learn Rails?\"\n      start_cue: \"1:08:26\"\n      end_cue: \"1:12:11\"\n      thumbnail_cue: \"1:09:38\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n      date: \"2024-07-18\"\n      id: \"why-should-i-learn-rails-sf-bay-area-meetup-july-2024\"\n      video_id: \"why-should-i-learn-rails-sf-bay-area-meetup-july-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO\n        - Irina Nazarova\n\n    - title: \"Open Mic: Binti (Fostercare with Technology) is Hiring\"\n      start_cue: \"1:12:11\"\n      end_cue: \"1:13:08\"\n      thumbnail_cue: \"1:12:25\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n      date: \"2024-07-18\"\n      id: \"binti-sf-bay-area-meetup-july-2024\"\n      video_id: \"binti-sf-bay-area-meetup-july-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Chris Fung\n\n    - title: \"Dokku Your Way to Heroku - How I learned to use Dokku and found my peace\"\n      start_cue: \"1:14:05\"\n      end_cue: \"1:33:33\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n      date: \"2024-07-18\"\n      id: \"yang-chung-dokku-your-way-heroku\"\n      video_id: \"yang-chung-dokku-your-way-heroku\"\n      video_provider: \"parent\"\n      speakers:\n        - Yang Chung\n\n    - title: \"Let's Write a C Extension!\"\n      start_cue: \"1:33:33\"\n      end_cue: \"1:50:00\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n      date: \"2024-07-18\"\n      id: \"cameron-dutro-write-c-extension\"\n      video_id: \"cameron-dutro-write-c-extension\"\n      video_provider: \"parent\"\n      speakers:\n        - Cameron Dutro\n\n    - title: \"Borrowing Concepts from React to Build Dynamic Forms in Rails\"\n      start_cue: \"1:50:00\"\n      end_cue: \"2:10:00\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2024\"\n      date: \"2024-07-18\"\n      id: \"james-kerr-react-dynamic-forms-rails\"\n      video_id: \"james-kerr-react-dynamic-forms-rails\"\n      video_provider: \"parent\"\n      speakers:\n        - James Kerr\n\n- id: \"sf-bay-area-ruby-meetup-august-2024\"\n  title: \"SF Bay Area Ruby Meetup - August 2024\"\n  raw_title: \"YC Ruby Meetup\"\n  event_name: \"SF Bay Area Ruby Meetup - August 2024\"\n  date: \"2024-08-13\"\n  description: |-\n    YC is co-hosting a Ruby Meetup with Evil Martians to bring together fellow rubyists at YC’s new San Francisco HQ!\n\n    We’ll have tech talks from YC founders sharing their novel uses of Ruby in the wild — and how it’s not the Ruby you tried 10+ years ago. Speakers so far:\n\n    * Jared Friedman (YC Group Partner & Scribd, S06) will give an opening talk about the history of software at YC: how we chose Rails, who wrote the first MR to our codebase , why Bookface is a YC founder’s secret weapon, and how Rails powers everything from apps to Work at a Startup.\n    * Daniel Farina (Ubicloud, W24) has been building infrastructure control planes in Ruby for 13 years - first at Heroku and now at Ubicloud. Daniel will detail his long and unusual journey with Ruby, and share his five favorite “features” that make Ruby particularly powerful for building infrastructure code.\n    * Kelsey Pedersen (Capsule, S22) built Capsule on a V1 vector database with Rails, Postgres and Active Record with the PGVector plugin. She’s happy to share learnings at pitfalls, as well as how she uses webhooks and rakes to automate workflows and help keep the team small.\n    * Keith Schacht (Mystery.org, S17) started coding Ruby in ‘05, and is still at it — building ChatGPT in Rails (vs Python) and keeping up with stimulus, new morphing, and Turbo Native. He’ll do some live coding of these new features, and wants to hear what you think!\n\n    Also note: many of the companies presenting are hiring — including Y Combinator’s Software Team looking to hire a few Rails-guru too!\n\n    If you’re interested, please apply to attend us for talks, dinner and refreshments — we have limited capacity, and we’ll try to get as many people in the doors as we can.\n\n    https://events.ycombinator.com/yc-ruby-meetup\n  video_provider: \"children\"\n  video_id: \"sf-bay-area-ruby-meetup-august-2024\"\n  talks:\n    - title: \"Intro\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2024\"\n      date: \"2024-08-13\"\n      id: \"ryan-choi-sf-bay-area-ruby-meetup-august-2024\"\n      video_id: \"ryan-choi-sf-bay-area-ruby-meetup-august-2024\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Ryan Choi\n\n    - title: \"The History of Software at YC: How we chose Rails\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2024\"\n      date: \"2024-08-13\"\n      id: \"jared-friedman-sf-bay-area-ruby-meetup-august-2024\"\n      video_id: \"jared-friedman-sf-bay-area-ruby-meetup-august-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GU53OtTa4AIXWjJ?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GU53OtTa4AIXWjJ?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GU53OtTa4AIXWjJ?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GU53OtTa4AIXWjJ?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GU53OtTa4AIXWjJ?format=jpg&name=large\"\n      speakers:\n        - Jared Friedman\n\n    - title: \"Ruby for Infrastructure: 13 Years of Lessons and Favorite Features\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2024\"\n      date: \"2024-08-13\"\n      id: \"daniel-farina-sf-bay-area-ruby-meetup-august-2024\"\n      video_id: \"daniel-farina-sf-bay-area-ruby-meetup-august-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GU6Din5aQAAVj45?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GU6Din5aQAAVj45?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GU6Din5aQAAVj45?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GU6Din5aQAAVj45?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GU6Din5aQAAVj45?format=jpg&name=large\"\n      speakers:\n        - Daniel Farina\n\n    - title: \"Building Capsule: Lessons from a V1 Vector Database with Rails & PGVector\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2024\"\n      date: \"2024-08-13\"\n      id: \"kelsey-pedersen-sf-bay-area-ruby-meetup-august-2024\"\n      video_id: \"kelsey-pedersen-sf-bay-area-ruby-meetup-august-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GU6EbRKa4AA4oK7?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GU6EbRKa4AA4oK7?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GU6EbRKa4AA4oK7?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GU6EbRKa4AA4oK7?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GU6EbRKa4AA4oK7?format=jpg&name=large\"\n      speakers:\n        - Kelsey Pedersen\n\n    - title: \"Building ChatGPT in Rails: Live Coding with Stimulus, Morphing, and Turbo Native\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2024\"\n      date: \"2024-08-13\"\n      id: \"keith-schacht-sf-bay-area-ruby-meetup-august-2024\"\n      video_id: \"keith-schacht-sf-bay-area-ruby-meetup-august-2024\"\n      video_provider: \"not_recorded\"\n      speakers:\n        - Keith Schacht\n\n- id: \"sf-bay-area-ruby-meetup-september-2024\"\n  title: \"SF Bay Area Ruby Meetup - September 2024\"\n  raw_title: \"SF Bay Area Ruby Meetup #6 at GitHub on September 3\"\n  event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n  date: \"2024-09-03\"\n  published_at: \"2024-09-04\"\n  description: |-\n    Hey, Bay Area builders and tinkerers!\n\n    For our September edition, we are back to where it started, the GitHub HQ 🎉. Join us to learn what's new and exciting in the world of Ruby, while making new and reconnecting with old friends!\n\n    ​Agenda:\n\n    ​​5 PM: Doors open, food, socializing\n    ​5.30: Intro and talks\n    – Cameron Dutro (GitHub) will speak about Web Components at GitHub\n    – Takashi Kokubun (Shopify) will tell us about YJIT and why we should start using it!\n    ​6.20: Break\n    ​6.40: Open mic 🎤 (prepare your announcements!)\n    ​7: Talks continue\n    – Brad Gessler announcing Terminalwire: Ship a CLI for your web app. No API required.\n    – Kamil Nicieja (Plane, a YC startup) with \"Exploring the Flavors of Ruby on Rails Architectures in the Wild\"\n    – Konstantin Gredeskoul (Academia.edu) \"Concurrency paradigms in Ruby 3.3: Fibers and Ractors\"\n    ​8: Community socializing\n    ​8.50: Doors close\n    ​Speak at one of the future meetups! Submit a talk proposal here:\n\n    ​https://forms.gle/C9HQzaT5jvwA5xwc7\n    Catch you on the flip side! Massive shoutout to GitHub for being our gracious host this time.\n\n    Address: 88 Colin P Kelly Jr. St., San Francisco, CA 94107\n    Guest Entrance: 275 Brannan St., San Francisco, CA 94107\n\n    We will also have a live stream and a recording of the event later! https://youtube.com/live/aqvGdPF5Qro?feature=share\n\n    Brought to you by Evil Martians. Check out:\n    – Rails Startup Stack\n    – Martian Chronicles\n\n    https://lu.ma/qfyzbfkk\n  video_provider: \"youtube\"\n  video_id: \"aqvGdPF5Qro\"\n  talks:\n    - title: \"Intro SF Bay Area Ruby Meetup - September 2024\"\n      start_cue: \"01:25\"\n      end_cue: \"11:37\"\n      thumbnail_cue: \"02:00\"\n      event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n      date: \"2024-09-03\"\n      id: \"irina-nazarova-sf-bay-area-meetup-september-2024-intro\"\n      video_id: \"irina-nazarova-sf-bay-area-meetup-september-2024-intro\"\n      video_provider: \"parent\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"How GitHub Uses Web Components\"\n      start_cue: \"13:12\"\n      end_cue: \"34:09\"\n      thumbnail_cue: \"13:13\"\n      date: \"2024-09-03\"\n      event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n      id: \"cameron-dutro-sf-bay-area-meetup-september-2024\"\n      video_id: \"cameron-dutro-sf-bay-area-meetup-september-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Cameron Dutro\n\n    - title: \"YJIT: The Future of Ruby Optimization\"\n      start_cue: \"35:25\"\n      end_cue: \"57:00\"\n      thumbnail_cue: \"35:37\"\n      date: \"2024-09-03\"\n      event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n      id: \"takashi-kokubun-sf-bay-area-meetup-september-2024\"\n      video_id: \"takashi-kokubun-sf-bay-area-meetup-september-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Takashi Kokubun\n\n    - title: \"Open Mic: GoCodeo\"\n      start_cue: \"01:25:14\"\n      end_cue: \"01:06:52\"\n      date: \"2024-09-03\"\n      event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n      id: \"meghana-jagadeesh-sf-bay-area-meetup-september-2024\"\n      video_id: \"meghana-jagadeesh-sf-bay-area-meetup-september-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Meghana Jagadeesh\n\n    - title: \"Open Mic: Rocky Mountain Ruby 2024\"\n      start_cue: \"01:27:17\"\n      end_cue: \"01:27:52\"\n      date: \"2024-09-03\"\n      event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n      id: \"zack-mariscal-sf-bay-area-meetup-september-2024\"\n      video_id: \"zack-mariscal-sf-bay-area-meetup-september-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Zack Mariscal\n\n    - title: \"Open Mic: BabyList\"\n      start_cue: \"01:27:58\"\n      end_cue: \"01:28:25\"\n      date: \"2024-09-03\"\n      event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n      id: \"jamie-alessio-sf-bay-area-meetup-september-2024\"\n      video_id: \"jamie-alessio-sf-bay-area-meetup-september-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Jamie Alessio\n\n    - title: \"Open Mic: Ruby Central\"\n      start_cue: \"01:28:29\"\n      end_cue: \"01:32:15\"\n      thumbnail_cue: \"01:28:30\"\n      date: \"2024-09-03\"\n      event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n      id: \"adarsh-pundit-sf-bay-area-meetup-september-2024\"\n      video_id: \"adarsh-pundit-sf-bay-area-meetup-september-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Adarsh Pandit\n\n    - title: \"Terminalwire: A Better CLI for Web Apps\"\n      start_cue: \"01:32:36\"\n      end_cue: \"01:44:35\"\n      thumbnail_cue: \"01:32:45\"\n      date: \"2024-09-03\"\n      event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n      id: \"brad-gessler-sf-bay-area-meetup-september-2024\"\n      video_id: \"brad-gessler-sf-bay-area-meetup-september-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Brad Gessler\n\n    - title: \"Exploring the Flavors of Ruby on Rails Architectures in the Wild\"\n      start_cue: \"01:45:30\"\n      end_cue: \"02:10:54\"\n      thumbnail_cue: \"01:45:34\"\n      date: \"2024-09-03\"\n      event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n      id: \"kamil-nicieja-sf-bay-area-meetup-september-2024\"\n      video_id: \"kamil-nicieja-sf-bay-area-meetup-september-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Kamil Nicieja\n\n    - title: \"Concurrency Paradigms in Ruby 3.3: Fibers and Ractors\"\n      start_cue: \"02:12:26\"\n      end_cue: \"02:38:00\"\n      thumbnail_cue: \"02:12:45\"\n      date: \"2024-09-03\"\n      event_name: \"SF Bay Area Ruby Meetup - September 2024\"\n      id: \"konstantin-gredeskoul-sf-bay-area-meetup-september-2024\"\n      video_id: \"konstantin-gredeskoul-sf-bay-area-meetup-september-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Konstantin Gredeskoul\n\n- id: \"sf-bay-area-ruby-meetup-october-2024\"\n  title: \"SF Bay Area Ruby Meetup - October 2024\"\n  raw_title: \"SF Bay Area Ruby Meetup #7\"\n  event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n  date: \"2024-10-10\"\n  description: |-\n    This is SF Bay Area Ruby Meetup #7 held at Chime's San Francisco Headquarters.\n\n    Join us for insightful talks and networking with fellow Ruby enthusiasts.\n\n    https://lu.ma/sf-ruby-oct-2024\n  video_provider: \"youtube\"\n  video_id: \"JFD8MJiUk6g\"\n  published_at: \"2024-10-25\"\n  talks:\n    - title: \"Intro SF Bay Area Ruby Meetup - October 2024\"\n      date: \"2024-10-10\"\n      start_cue: \"00:00\"\n      end_cue: \"05:40\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GZkoeHwWYAgYnKN?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GZkoeHwWYAgYnKN?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GZkoeHwWYAgYnKN?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GZkoeHwWYAgYnKN?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GZkoeHwWYAgYnKN?format=jpg&name=4096x4096\"\n      id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-october-2024\"\n      video_id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-october-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Ruby's Legacy and Ruby's Future\"\n      date: \"2024-10-10\"\n      start_cue: \"05:40\"\n      end_cue: \"36:07\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GZkvCj7XYAkeoFR?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GZkvCj7XYAkeoFR?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GZkvCj7XYAkeoFR?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GZkvCj7XYAkeoFR?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GZkvCj7XYAkeoFR?format=jpg&name=4096x4096\"\n      id: \"noel-rappin-ruby-legacy-ecosystem-sf-bay-area-ruby-meetup-october-2024\"\n      video_id: \"noel-rappin-ruby-legacy-ecosystem-sf-bay-area-ruby-meetup-october-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Noel Rappin\n\n    - title: \"Forms on Rails\"\n      date: \"2024-10-10\"\n      start_cue: \"36:07\"\n      end_cue: \"1:00:00\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GZkvWD4WcAg-9F5?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GZkvWD4WcAg-9F5?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GZkvWD4WcAg-9F5?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GZkvWD4WcAg-9F5?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GZkvWD4WcAg-9F5?format=jpg&name=4096x4096\"\n      id: \"vladimir-dementyev-forms-on-rails-sf-bay-area-ruby-meetup-october-2024\"\n      video_id: \"vladimir-dementyev-forms-on-rails-sf-bay-area-ruby-meetup-october-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Vladimir Dementyev\n\n    - title: \"Open Mic: Ruby Central\"\n      date: \"2024-10-10\"\n      start_cue: \"01:00:00\"\n      end_cue: \"01:07:00\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GZk9OcrX0AkqDCd?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GZk9OcrX0AkqDCd?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GZk9OcrX0AkqDCd?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GZk9OcrX0AkqDCd?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GZk9OcrX0AkqDCd?format=jpg&name=4096x4096\"\n      id: \"open-mic-presentations-sf-bay-area-ruby-meetup-october-2024\"\n      video_id: \"open-mic-presentations-sf-bay-area-ruby-meetup-october-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Adarsh Pandit\n\n    - title: \"Open Mic: rspec-llama\"\n      date: \"2024-10-10\"\n      start_cue: \"01:07:25\"\n      end_cue: \"01:16:07\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GZk-bfWXAAUZ4-t?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GZk-bfWXAAUZ4-t?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GZk-bfWXAAUZ4-t?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GZk-bfWXAAUZ4-t?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GZk-bfWXAAUZ4-t?format=jpg&name=4096x4096\"\n      id: \"rspec-llama-open-mic-sf-bay-area-ruby-meetup-october-2024\"\n      video_id: \"rspec-llama-open-mic-sf-bay-area-ruby-meetup-october-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Sergy Sergyenko\n\n    - title: \"Open Mic: I'm Speaking at RubyConf & Why You Should Hire Me\"\n      date: \"2024-10-10\"\n      start_cue: \"01:16:14\"\n      end_cue: \"01:17:15\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GZlBsrWW8AAB88C?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GZlBsrWW8AAB88C?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GZlBsrWW8AAB88C?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GZlBsrWW8AAB88C?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GZlBsrWW8AAB88C?format=jpg&name=4096x4096\"\n      id: \"im-speaking-at-rubyconf-and-why-you-should-hire-me-1-open-mic-sf-bay-area-ruby-meetup-october-2024\"\n      video_id: \"im-speaking-at-rubyconf-and-why-you-should-hire-me-1-open-mic-sf-bay-area-ruby-meetup-october-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Keith Gable\n\n    - title: \"Open Mic: Why You Should Hire Me\"\n      date: \"2024-10-10\"\n      start_cue: \"01:17:29\"\n      end_cue: \"01:18:22\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GZlBsrWWgAkOZCr?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GZlBsrWWgAkOZCr?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GZlBsrWWgAkOZCr?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GZlBsrWWgAkOZCr?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GZlBsrWWgAkOZCr?format=jpg&name=4096x4096\"\n      id: \"why-you-should-hire-me-open-mic-sf-bay-area-ruby-meetup-october-2024\"\n      video_id: \"why-you-should-hire-me-open-mic-sf-bay-area-ruby-meetup-october-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Meredith White\n\n    - title: \"Open Mic: oyencov - Usage-Weighted Test Coverage for Rails applications\"\n      date: \"2024-10-10\"\n      start_cue: \"01:18:32\"\n      end_cue: \"01:19:22\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GZlDNblXgAk8oht?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GZlDNblXgAk8oht?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GZlDNblXgAk8oht?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GZlDNblXgAk8oht?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GZlDNblXgAk8oht?format=jpg&name=4096x4096\"\n      id: \"usage-weighted-test-coverage-rails-open-mic-sf-bay-area-ruby-meetup-october-2024\"\n      video_id: \"usage-weighted-test-coverage-rails-open-mic-sf-bay-area-ruby-meetup-october-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Anonoz Chong\n\n    - title: \"Open Mic: ActiveAgents.ai\"\n      date: \"2024-10-10\"\n      start_cue: \"01:19:30\"\n      end_cue: \"01:21:02\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n      description: |-\n        https://www.activeagents.ai\n      thumbnail_xs: \"https://pbs.twimg.com/media/GZlD4L3XsAApLfx?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GZlD4L3XsAApLfx?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GZlD4L3XsAApLfx?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GZlD4L3XsAApLfx?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GZlD4L3XsAApLfx?format=jpg&name=4096x4096\"\n      id: \"activeagents-ai-open-mic-sf-bay-area-ruby-meetup-october-2024\"\n      video_id: \"activeagents-ai-open-mic-sf-bay-area-ruby-meetup-october-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Justin Bowen\n\n    - title: \"Red Fantasy Land\"\n      date: \"2024-10-10\"\n      start_cue: \"01:22:30\"\n      end_cue: \"01:52:18\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2024\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GZlE-6dWcAgJ1Lf?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GZlE-6dWcAgJ1Lf?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GZlE-6dWcAgJ1Lf?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GZlE-6dWcAgJ1Lf?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GZlE-6dWcAgJ1Lf?format=jpg&name=4096x4096\"\n      id: \"brandon-weaver-red-fantasy-land-sf-bay-area-ruby-meetup-october-2024\"\n      video_id: \"brandon-weaver-red-fantasy-land-sf-bay-area-ruby-meetup-october-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Brandon Weaver\n\n- id: \"sf-bay-area-ruby-meetup-november-2024\"\n  title: \"SF Bay Area Ruby Meetup - November 2024\"\n  raw_title: \"SF Bay Area Ruby Meetup in November @ Academia.edu\"\n  event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n  date: \"2024-11-19\"\n  description: |-\n    ​​Hey, Bay Area builders and tinkerers!\n\n    While Ruby may not dominate the headlines, it's the silent force behind the Bay Area's most successful startups. From GitHub and Stripe to Chime and Stackblitz, Ruby powers teams that go HUGE with less.\n\n    ​Join us as we re-kindle the SF Ruby community's flame! It is a unique place to meet authors of your favorite open-source tools (or members of the Ruby core team), incredibly experienced engineers and new converts, as well as new startup founders building and experimenting with the power of Ruby and Rails. It's a chance to meet every month and make new Ruby friends.\n\n    Our meetups explore Rails at scale, practical Hotwire implementations, methods for building AI-native apps and so much more—all through Ruby's uniquely productive lens.\n\n    For our November gathering, Academia.edu is our gracious host! This time, the speaker lineup is unmatched: Jeremy Evans, author of \"Polished Ruby,\" Sequel, and Roda, is joined by Konstantin Gredeskoul (Academia), Chris Fung (Binti), and Brad Gessler (Rocketship, Fly).\n\n    Address: 580 California St. Suite 400 San Francisco, CA 94104\n\n    https://lu.ma/f4pfsigc\n  video_provider: \"youtube\"\n  video_id: \"emg8KhSKXzI\"\n  published_at: \"2024-12-05\"\n  talks:\n    - title: \"Intro SF Bay Area Ruby Meetup - November 2024\"\n      date: \"2024-11-19\"\n      start_cue: \"00:00\"\n      end_cue: \"05:20\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Design for Loose Coupling in Ruby\"\n      date: \"2024-11-19\"\n      raw_title: \"Designing for Loose Coupling in Ruby\"\n      start_cue: \"05:20\"\n      end_cue: \"29:20\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"konstantin-gredeskoul-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"konstantin-gredeskoul-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Konstantin Gredeskoul (Academia.edu)\n      speakers:\n        - Konstantin Gredeskoul\n\n    - title: \"How to translate your Rails app into over 20 languages - and why you should!\"\n      date: \"2024-11-19\"\n      start_cue: \"29:20\"\n      end_cue: \"56:06\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"chris-fung-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"chris-fung-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      slides_url: \"https://speakerdeck.com/aergonaut/how-to-translate-your-rails-app-into-over-20-languages-and-why-you-should\"\n      description: |-\n        Chris Fung (Binti)  \"How to translate your Rails app into over 20 languages\"\n      speakers:\n        - Chris Fung\n\n    - title: \"Open Mic: filterameter\"\n      date: \"2024-11-19\"\n      start_cue: \"56:06\"\n      end_cue: \"57:47\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"todd-kummer-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"todd-kummer-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Simplify and speed development of Rails controllers by making filter parameters declarative.\n\n        Repo: https://github.com/RockSolt/filterameter\n      speakers:\n        - Todd Kummer\n      additional_resources:\n        - name: \"RockSolt/filterameter\"\n          type: \"repo\"\n          url: \"https://github.com/RockSolt/filterameter\"\n\n    - title: \"Open Mic: Looking For A PM Role\"\n      date: \"2024-11-19\"\n      start_cue: \"57:47\"\n      end_cue: \"58:26\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"ken-decanio-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"ken-decanio-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      description: \"\"\n      speakers:\n        - Ken Decanio\n\n    - title: \"Open Mic: rubyvideo.dev\"\n      date: \"2024-11-19\"\n      start_cue: \"58:26\"\n      end_cue: \"59:50\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"cameron-dutro-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"cameron-dutro-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Website: https://rubyvideo.dev\n      speakers:\n        - Cameron Dutro\n\n    - title: \"Open Mic: Veteran Ruby Meetups\"\n      date: \"2024-11-19\"\n      start_cue: \"59:50\"\n      end_cue: \"1:00:38\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"dave-doolin-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"dave-doolin-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      description: \"\"\n      speakers:\n        - Dave Doolin\n\n    - title: \"Open Mic: us_geo\"\n      date: \"2024-11-19\"\n      start_cue: \"1:00:38\"\n      end_cue: \"1:03:00\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"brian-durand-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"brian-durand-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Collection of geographic data for the United States for use with ActiveRecord\n\n        Repo: https://github.com/bdurand/us_geo\n      speakers:\n        - Brian Durand\n      additional_resources:\n        - name: \"bdurand/us_geo\"\n          type: \"repo\"\n          url: \"https://github.com/bdurand/us_geo\"\n\n    - title: \"Open Mic: Espartaco Palma\"\n      date: \"2024-11-19\"\n      start_cue: \"1:01:37\"\n      end_cue: \"1:03:00\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"esparta-palma-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"esparta-palma-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      description: \"\"\n      speakers:\n        - Espartaco Palma\n\n    - title: \"Open Mic: macchiato.dev\"\n      date: \"2024-11-19\"\n      start_cue: \"1:03:00\"\n      end_cue: \"1:06:00\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"benjamin-atkin-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"benjamin-atkin-open-mic-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      description: |-\n        A notebook container and a collection of notebooks for interacting with data.\n\n        Repo: https://github.com/macchiato-dev\n      speakers:\n        - Benjamin Atkin\n\n    - title: \"Build ambitious content websites in Rails\"\n      raw_title: \"Manage Content with Sitepress in Rails Apps or Static Websites\"\n      date: \"2024-11-19\"\n      start_cue: \"1:06:00\"\n      end_cue: \"1:26:16\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"brad-gessler-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"brad-gessler-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Brad Gessler (Rocketship, Fly) \"Content management in Rails with Sitepress.cc\"\n\n        This talk dives into https://sitepress.cc, a tool for integrating content management directly into Rails applications. Originally conceived to combine the power of static site generators like Middleman with Rails’ flexibility, Sitepress simplifies building and managing content-heavy websites. It’s designed to work as a standalone static site generator, a Rails engine, or a dynamic server.\n\n        During the talk, we explore how the developer documentation at https://terminalwire.com use Sitepress’s advanced features, such as using markdown for pages, frontmatter for metadata, and traversing content with powerful tools like globbing and page models. A live demo showcased how these features come together to create polished documentation sites for developers.\n\n        Links:\n        Longer extended version of the talk: https://youtube.com/watch?v=K2N8fp2P7Ms\n        Website with Sitepress documentation and examples: https://sitepress.cc\n        Example used in presentation that uses Sitepress: https://terminalwire.com\n      speakers:\n        - Brad Gessler\n      alternative_recordings:\n        - title: \"Manage Content with Sitepress in Rails Apps or Static Websites\"\n          video_id: \"K2N8fp2P7Ms\"\n          video_provider: \"youtube\"\n          speakers:\n            - Brad Gessler\n\n    - title: \"The First 10 Years of Roda\"\n      start_cue: \"1:26:16\"\n      end_cue: \"2:13:56\"\n      event_name: \"SF Bay Area Ruby Meetup - November 2024\"\n      id: \"jeremy-evans-sf-bay-area-ruby-meetup-november-2024\"\n      video_id: \"jeremy-evans-sf-bay-area-ruby-meetup-november-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Jeremy Evans \"The first 10 years of Roda\"\n      speakers:\n        - Jeremy Evans\n\n- id: \"sf-bay-area-ruby-meetup-december-2024\"\n  title: \"SF Bay Area Ruby Meetup - December 2024\"\n  raw_title: \"SF Ruby presents: Ruby&AI, December 🎅 edition @ Sentry\"\n  event_name: \"SF Bay Area Ruby Meetup - December 2024\"\n  date: \"2024-12-03\"\n  description: |-\n    Registration closes at noon on Dec 2.\n    Address: 45 Fremont St, we'll be meeting you in the lobby. If you are running late, please send a message.\n\n    Before the event, you will receive a message from Sentry (no-reply@envoy.com). Please fill out your details and sign a visitor's agreement. They ask for a photo too =) After that, you'll receive a QR code to enter.\n\n    Hey, Bay Area builders and tinkerers!\n\n    From GitHub and Stripe to Chime and Stackblitz, Ruby powers teams that go HUGE with less.\n\n    Join us as we re-kindle the SF Ruby community's flame! It is a place to meet authors of your favorite open-source and Ruby/Rails core, experienced Rubyists and new converts, entrepreneurs, and, well, people who hire. We meet every month and gradually make new Ruby friends.\n\n    For our December edition, Sentry is our gracious host! This time, we dedicate the event to all aspects of building AI-native apps and leveraging the power of AI in our Ruby applications.\n\n    It is also our special HOLIDAY edition, so let's do something about it! Choose your fighter:\n    - bake and bring your cookies 🍪 (two people are doing it already, join us!)\n    - wear something 🎅-esque\n    - steal the Xmas 😈\n\n    https://lu.ma/q7fwrtj2\n  video_provider: \"youtube\"\n  video_id: \"NU7ld8ERUFY\"\n  published_at: \"2024-12-05\"\n  talks:\n    - title: \"Intro SF Bay Area Ruby Meetup - December 2024\"\n      date: \"2024-12-03\"\n      start_cue: \"00:00\"\n      end_cue: \"07:30\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2024\"\n      id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-december-2024\"\n      video_id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-december-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"AI Grouping for Ruby SDK at Sentry\"\n      date: \"2024-12-03\"\n      start_cue: \"07:30\"\n      end_cue: \"35:32\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2024\"\n      id: \"tillman-elser-sf-bay-area-ruby-meetup-december-2024\"\n      video_id: \"tillman-elser-sf-bay-area-ruby-meetup-december-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Tillman Elser\n\n    - title: \"ActiveAgents\"\n      date: \"2024-12-03\"\n      start_cue: \"35:32\"\n      end_cue: \"59:38\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2024\"\n      id: \"justin-bowen-sf-bay-area-ruby-meetup-december-2024\"\n      video_id: \"justin-bowen-sf-bay-area-ruby-meetup-december-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Website: https://www.activeagents.ai\n        Repo: https://github.com/activeagents/activeagent\n      speakers:\n        - Justin Bowen\n      additional_resources:\n        - name: \"activeagents/activeagent\"\n          type: \"repo\"\n          url: \"https://github.com/activeagents/activeagent\"\n\n    - title: \"Ruby & GenAI @ Stepful\"\n      date: \"2024-12-03\"\n      start_cue: \"59:38\"\n      end_cue: \"1:16:45\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2024\"\n      id: \"edoardo-serra-sf-bay-area-ruby-meetup-december-2024\"\n      video_id: \"edoardo-serra-sf-bay-area-ruby-meetup-december-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Website: https://stepful.com\n      speakers:\n        - Edoardo Serra\n\n    - title: \"Open Mic: Learning Rails\"\n      date: \"2024-12-03\"\n      start_cue: \"1:16:45\"\n      end_cue: \"1:18:32\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2024\"\n      id: \"ken-decanio-open-mic-sf-bay-area-ruby-meetup-december-2024\"\n      video_id: \"ken-decanio-open-mic-sf-bay-area-ruby-meetup-december-2024\"\n      video_provider: \"parent\"\n      speakers:\n        - Ken Decanio\n\n    - title: \"Open Mic: epicstrips.tv\"\n      date: \"2024-12-03\"\n      start_cue: \"1:18:32\"\n      end_cue: \"1:20:05\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2024\"\n      id: \"chris-hobbs-open-mic-sf-bay-area-ruby-meetup-december-2024\"\n      video_id: \"chris-hobbs-open-mic-sf-bay-area-ruby-meetup-december-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Website: https://epicstrips.tv\n      speakers:\n        - Chris Hobbs\n\n    - title: \"Open Mic: Ruby Central\"\n      date: \"2024-12-03\"\n      start_cue: \"1:20:05\"\n      end_cue: \"1:22:57\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2024\"\n      id: \"rhiannon-payne-open-mic-sf-bay-area-ruby-meetup-december-2024\"\n      video_id: \"rhiannon-payne-open-mic-sf-bay-area-ruby-meetup-december-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Website: https://rubycentral.org\n        Marketing Agency: https://seafoam.media\n      speakers:\n        - Rhiannon Payne\n\n    - title: \"Introducing Lammy\"\n      date: \"2024-12-03\"\n      start_cue: \"1:22:57\"\n      end_cue: \"1:38:35\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2024\"\n      id: \"kamil-nicieja-sf-bay-area-ruby-meetup-december-2024\"\n      video_id: \"kamil-nicieja-sf-bay-area-ruby-meetup-december-2024\"\n      video_provider: \"parent\"\n      description: |-\n        Lammy is a simple LLM library for Ruby. It doesn't treat prompts as just strings. They represent the entire code that generates the strings sent to a LLM. The abstraction also makes it easy to attach these methods directly to models, avoiding the need for boilerplate service code.\n\n        Repo: https://github.com/nicieja/lammy\n      speakers:\n        - Kamil Nicieja\n      additional_resources:\n        - name: \"nicieja/lammy\"\n          type: \"repo\"\n          url: \"https://github.com/nicieja/lammy\"\n\n    - title: \"Building Voice AI Apps with Ruby\"\n      date: \"2024-12-03\"\n      start_cue: \"1:38:35\"\n      end_cue: \"2:01:21\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2024\"\n      id: \"irina-nazarova-sf-bay-area-ruby-meetup-december-2024\"\n      video_id: \"irina-nazarova-sf-bay-area-ruby-meetup-december-2024\"\n      video_provider: \"parent\"\n      description: |-\n        This talk is based on https://evilmartians.com/chronicles/anycable-speaking-needing-help-with-a-twilio-openai-connection\n        The code is here https://github.com/anycable/twilio-ai-demo/blob/demo/rbs-tools/app/channels/twilio/media_stream_channel.rb\n        And the \"tool\" is defined here https://github.com/anycable/twilio-ai-demo/blob/demo/rbs-tools/app/channels/concerns/openai_tools.rb\n      speakers:\n        - Irina Nazarova\n      additional_resources:\n        - name: \"anycable/twilio-ai-demo\"\n          type: \"repo\"\n          url: \"https://github.com/anycable/twilio-ai-demo/blob/demo/rbs-tools/app/channels/twilio/media_stream_channel.rb\"\n\n        - name: \"anycable/twilio-ai-demo\"\n          type: \"repo\"\n          url: \"https://github.com/anycable/twilio-ai-demo/blob/demo/rbs-tools/app/channels/concerns/openai_tools.rb\"\n\n- title: \"SF Bay Area Ruby Meetup - January 2025\"\n  raw_title: \"SF Ruby January Meetup @ Productboard\"\n  event_name: \"SF Bay Area Ruby Meetup - January 2025\"\n  date: \"2025-01-16\"\n  published_at: \"2025-01-24\"\n  description: |-\n    ​Hey, Bay Area builders and tinkerers!\n\n    While Ruby may not dominate the headlines, it's the silent force behind the Bay Area's most successful startups. From GitHub and Stripe to Chime and Stackblitz, Ruby powers teams that go HUGE with less.\n\n    ​Join us as we re-kindle the SF Ruby community's flame! It is a unique place to meet authors of your favorite open-source tools (or members of the Ruby core team), incredibly experienced engineers and new converts, as well as new startup founders building and experimenting with the power of Ruby and Rails. It's a chance to meet every month and make new Ruby friends.\n\n    Our meetups explore practical and explorational stories about Rails at scale, performance and maintainability, deployments, frontend, AI-powered features, and so much more—all through Ruby's uniquely productive lens.\n\n    For the first event of the year, Productboard is our gracious host!\n\n    Our special 🌟 speaker is Jason Swett, coming from Michigan!\n\n    Agenda:\n    5 pm Doors open, pizza\n    5.30 pm intro words, Irina and Productboard\n    5.40 Jason Swett (codewithjason.com) on How to make your tests easier to understand\n    6.20 Bart Agapinan (ID.me) on How to add passkeys to a Rails app (and why)\n    6.40 break\n    7.00 open mic\n    7.10 Cameron Dutro (GitHub) on WASM in Ruby\n    7.30 Alex Rodionov (Toptal) on using Bazel in Ruby projects\n    9 pm doors close\n\n    Submit a talk proposal here:\n\n    ​​https://forms.gle/C9HQzaT5jvwA5xwc7\n\n    ​\n    Catch you on the flip side! A massive shoutout to Productboard for hosting and sponsoring the event!\n\n    Brought to you by Evil Martians.\n\n    https://lu.ma/goujxu3a\n  video_provider: \"youtube\"\n  video_id: \"cnhBfOCI0JA\"\n  id: \"sf-bay-area-ruby-meetup-january-2025\"\n  talks:\n    - title: \"Intro SF Bay Area Ruby Meetup - January 2025\"\n      start_cue: \"00:04\"\n      end_cue: \"05:55\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2025\"\n      id: \"intro-sf-bay-area-ruby-meetup-january-2025\"\n      video_id: \"intro-sf-bay-area-ruby-meetup-january-2025\"\n      video_provider: \"parent\"\n      date: \"2025-01-16\"\n      published_at: \"2025-01-24\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Productboard\"\n      start_cue: \"05:55\"\n      end_cue: \"07:50\"\n      thumbnail_cue: \"06:45\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2025\"\n      id: \"productboard-sf-bay-area-ruby-meetup-january-2025\"\n      video_id: \"productboard-sf-bay-area-ruby-meetup-january-2025\"\n      video_provider: \"parent\"\n      date: \"2025-01-16\"\n      published_at: \"2025-01-24\"\n      speakers:\n        - Claudio Andrei\n\n    - title: \"How to make your tests easier to understand\"\n      start_cue: \"13:16\"\n      end_cue: \"40:55\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2025\"\n      id: \"jason-swett-how-to-make-your-tests-easier-to-understand\"\n      video_id: \"jason-swett-how-to-make-your-tests-easier-to-understand\"\n      video_provider: \"parent\"\n      date: \"2025-01-16\"\n      published_at: \"2025-01-24\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GhipDm9bwAAW_Xp?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GhipDm9bwAAW_Xp?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GhipDm9bwAAW_Xp?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GhipDm9bwAAW_Xp?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GhipDm9bwAAW_Xp?format=jpg&name=large\"\n      speakers:\n        - Jason Swett\n\n    - title: \"How to add passkeys to a Rails app (and why)\"\n      start_cue: \"40:55\"\n      end_cue: \"01:06:39\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2025\"\n      id: \"bart-agapinan-how-to-add-passkeys-to-a-rails-app-and-why\"\n      video_id: \"bart-agapinan-how-to-add-passkeys-to-a-rails-app-and-why\"\n      video_provider: \"parent\"\n      date: \"2025-01-16\"\n      published_at: \"2025-01-24\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GhipDm8bQAEJNa_?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GhipDm8bQAEJNa_?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GhipDm8bQAEJNa_?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GhipDm8bQAEJNa_?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GhipDm8bQAEJNa_?format=jpg&name=large\"\n      slides_url: \"https://docs.google.com/presentation/d/1cWArcQ7o2RD6OjugWjVepo9tS1skAo1eYvboHjIBIqI/edit?usp=sharing\"\n      description: |-\n        Repo: https://github.com/viamin/passkeys-demo\n      speakers:\n        - Bart Agapinan\n      additional_resources:\n        - name: \"viamin/passkeys-demo\"\n          type: \"repo\"\n          url: \"https://github.com/viamin/passkeys-demo\"\n\n    - title: \"WASM in Ruby\"\n      start_cue: \"01:06:40\"\n      end_cue: \"01:35:17\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2025\"\n      id: \"cameron-dutro-wasm-in-ruby\"\n      video_id: \"cameron-dutro-wasm-in-ruby\"\n      video_provider: \"parent\"\n      date: \"2025-01-16\"\n      published_at: \"2025-01-24\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GhipDm-aUAE2JsU?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GhipDm-aUAE2JsU?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GhipDm-aUAE2JsU?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GhipDm-aUAE2JsU?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GhipDm-aUAE2JsU?format=jpg&name=large\"\n      description: |-\n        Repos:\n        https://github.com/camertron/onigmo-wasm\n        https://github.com/camertron/onigmo-ruby\n      speakers:\n        - Cameron Dutro\n      additional_resources:\n        - name: \"camertron/onigmo-wasm\"\n          type: \"repo\"\n          url: \"https://github.com/camertron/onigmo-wasm\"\n\n        - name: \"camertron/onigmo-ruby\"\n          type: \"repo\"\n          url: \"https://github.com/camertron/onigmo-ruby\"\n\n    - title: \"Using Bazel in Ruby Projects\"\n      start_cue: \"01:35:17\"\n      end_cue: \"02:07:36\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2025\"\n      id: \"alex-rodionov-using-bazel-in-ruby-projects\"\n      video_id: \"alex-rodionov-using-bazel-in-ruby-projects\"\n      video_provider: \"parent\"\n      date: \"2025-01-16\"\n      published_at: \"2025-01-24\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GhipDm9aEAE7LV7?format=jpg&name=small\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GhipDm9aEAE7LV7?format=jpg&name=small\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GhipDm9aEAE7LV7?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GhipDm9aEAE7LV7?format=jpg&name=large\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GhipDm9aEAE7LV7?format=jpg&name=large\"\n      description: |-\n        Bazel: https://bazel.build\n        Rules Ruby: https://github.com/bazel-contrib/rules_ruby\n        Slack Channel: https://bazelbuild.slack.com/channels/ruby\n      speakers:\n        - Alex Rodionov\n      additional_resources:\n        - name: \"bazel-contrib/rules_ruby\"\n          type: \"repo\"\n          url: \"https://github.com/bazel-contrib/rules_ruby\"\n\n- title: \"SF Bay Area Ruby Meetup - February 2025\"\n  raw_title: \"SF Ruby February Meetup @ GitHub\"\n  event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n  date: \"2025-02-11\"\n  published_at: \"2025-02-12\"\n  description: |-\n    ​​Hey, Bay Area builders and tinkerers!\n\n    This time we are hosted by GitHub, and our keynote speaker is Joel Hawksley with \"Lessons from 5 years of UI architecture at GitHub\" 🔥\n\n    Address: 88 Colin P Kelly Jr, GitHub HQ\n\n    We'll have a livestream: https://www.youtube.com/live/M25fETp83jQ\n\n    We begin the programming at 5.30 PM PST and we have an amazing agenda:\n\n    5.40 PM Joel Hawksley (GitHub) Lessons from 5 years of UI architecture at GitHub\n\n    6.40 PM Sam Poder (Hack Club) How we built a bank w/ Ruby on Rails\n\n    7 PM Break\n\n    7.30 PM Open mic! Prepare your announcements!\n\n    7.45 PM Vladimir Dementyev (Evil Martians) with a secret topic\n\n    8.20 PM Talks conclude, social time\n\n    8.50 PM Doors close\n\n    🎙️ Submit a talk proposal here: ​https://forms.gle/C9HQzaT5jvwA5xwc7\n\n    ​Ruby is the quiet force behind the Bay Area's most successful tech organizations and startups from GitHub, Shopify and Stripe to Chime, Lago, and bolt.new.\n\n    ​We are gathering every month to learn, share, inspire each other, and it feels great because of MINASWAN 💗.\n\n    ​Our meetups explore building and scaling Ruby and Rails applications. We go deep into technical topics and don't shy away from new ideas and weird experiments! We always have an open mic for everyone's announcements or questions🎙️! Join us in discovering the nicest Ruby HQs 🏙️❤️\n\n    Catch you on the flip side! A massive shoutout to GitHub for hosting and sponsoring the event!\n\n    Brought to you by Evil Martians.\n\n    https://lu.ma/hoou421h\n  video_provider: \"youtube\"\n  video_id: \"M25fETp83jQ\"\n  id: \"sf-bay-area-ruby-meetup-february-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n  talks:\n    - title: \"Lessons from 5 years of UI architecture at GitHub\"\n      start_cue: \"40:25\"\n      end_cue: \"01:25:10\"\n      thumbnail_cue: \"40:30\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-01-30 02:48:00 UTC\"\n      published_at: \"2025-02-11\"\n      event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n      id: \"joel-hawksley-sf-bay-area-ruby-meetup-february-2025\"\n      video_id: \"joel-hawksley-sf-bay-area-ruby-meetup-february-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Joel Hawksley\n\n    - title: \"How we built a bank w/ Ruby on Rails\"\n      start_cue: \"01:26:49\"\n      end_cue: \"02:00:35\"\n      thumbnail_cue: \"01:26:53\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-01-30 02:48:00 UTC\"\n      published_at: \"2025-02-11\"\n      event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n      id: \"sam-poder-sf-bay-area-ruby-meetup-february-2025\"\n      video_id: \"sam-poder-sf-bay-area-ruby-meetup-february-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Sam Poder\n\n    - title: \"Open Mic: ActiveAgents.ai\"\n      start_cue: \"02:20:58\"\n      end_cue: \"02:21:43\"\n      thumbnail_cue: \"02:21:31\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-02-04 06:25:00 UTC\"\n      published_at: \"2025-02-11\"\n      event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n      id: \"open-mic-justin-bowen-sf-bay-area-ruby-meetup-february-2025\"\n      video_id: \"open-mic-justin-bowen-sf-bay-area-ruby-meetup-february-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Website: https://www.activeagents.ai\n      speakers:\n        - Justin Bowen\n\n    - title: \"Open Mic: ZETIC.ai\"\n      start_cue: \"02:21:50\"\n      end_cue: \"02:24:25\"\n      thumbnail_cue: \"02:22:59\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-02-04 06:25:00 UTC\"\n      published_at: \"2025-02-11\"\n      event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n      id: \"open-mic-yeonseok-kim-sf-bay-area-ruby-meetup-february-2025\"\n      video_id: \"open-mic-yeonseok-kim-sf-bay-area-ruby-meetup-february-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Website: https://zetic.ai\n      speakers:\n        - Yeonseok Kim\n\n    - title: \"Open Mic: AI job and software engineer screening platform\" # TODO: add company title\n      start_cue: \"02:24:30\"\n      end_cue: \"02:25:44\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-02-04 06:25:00 UTC\"\n      published_at: \"2025-02-11\"\n      event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n      id: \"open-mic-federico-ramoso-sf-bay-area-ruby-meetup-february-2025\"\n      video_id: \"open-mic-federico-ramoso-sf-bay-area-ruby-meetup-february-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Federico Ramoso # TODO: check name\n\n    - title: \"Open Mic: Quantoflow\"\n      start_cue: \"02:25:45\"\n      end_cue: \"02:26:23\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-02-04 06:25:00 UTC\"\n      published_at: \"2025-02-11\"\n      event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n      id: \"open-mic-michael-yu-sf-bay-area-ruby-meetup-february-2025\"\n      video_id: \"open-mic-michael-yu-sf-bay-area-ruby-meetup-february-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Michael Yu\n\n    - title: \"Open Mic: Visit your local Library\"\n      start_cue: \"02:26:30\"\n      end_cue: \"02:28:07\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-02-04 06:25:00 UTC\"\n      published_at: \"2025-02-11\"\n      event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n      id: \"open-mic-TODO-sf-bay-area-ruby-meetup-february-2025\"\n      video_id: \"open-mic-TODO-sf-bay-area-ruby-meetup-february-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO\n\n    - title: \"Open Mic: San Francisco Slack\"\n      start_cue: \"02:28:10\"\n      end_cue: \"02:29:08\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-02-04 06:25:00 UTC\"\n      published_at: \"2025-02-11\"\n      event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n      id: \"open-mic-brandon-weaver-sf-bay-area-ruby-meetup-february-2025\"\n      video_id: \"open-mic-brandon-weaver-sf-bay-area-ruby-meetup-february-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Brandon Weaver\n\n    - title: \"Presence Ain't Perfect\"\n      start_cue: \"02:31:55\"\n      end_cue: \"03:08:25\"\n      thumbnail_cue: \"02:32:03\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-02-04 06:25:00 UTC\"\n      published_at: \"2025-02-11\"\n      event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n      id: \"vladimir-dementyev-sf-bay-area-ruby-meetup-february-2025\"\n      video_id: \"vladimir-dementyev-sf-bay-area-ruby-meetup-february-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Vladimir Dementyev\n\n    - title: \"Hexagonal Architecture and Rails\"\n      start_cue: \"03:10:18\"\n      end_cue: \"03:37:28\"\n      thumbnail_cue: \"03:11:04\"\n      date: \"2025-02-11\"\n      announced_at: \"2025-02-04 06:25:00 UTC\"\n      published_at: \"2025-02-11\"\n      event_name: \"SF Bay Area Ruby Meetup - February 2025\"\n      id: \"alan-ridlehoover-sf-bay-area-ruby-meetup-february-2025\"\n      video_id: \"alan-ridlehoover-sf-bay-area-ruby-meetup-february-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Alan Ridlehoover\n\n- title: \"SF Bay Area Ruby Meetup - March 2025\"\n  raw_title: \"SF Ruby February Meetup in March @ New Relic\"\n  event_name: \"SF Bay Area Ruby Meetup - March 2025\"\n  date: \"2025-03-20\"\n  published_at: \"\"\n  description: |-\n    ​​Hey, Bay Area builders and tinkerers!\n\n    This time we are hosted by New Relic and also sponsored by Ruby Central! We are quickly crafting the agenda now, and it's going to be amazing thanks to all of you.\n\n    Address: 188 Spear St Floor 10, New Relic\n\n    We begin the programming at 5.30 PM PST and we have an amazing agenda:\n\n    Agenda:\n\n    ​5.30 PM Intro: Cameron Dutro\n\n    5.40 PM Kayla Reopelle: Talk from New Relic\n\n    6.30 PM Adrian Marin: Avo\n\n    7:00 PM Break\n\n    7.20 PM Open mic! Prepare your announcements!\n\n    7.30 PM Fito von Zastrow & Alan Ridlehoover: A Brewer's Guide to Filtering out Complexity and Churn\n\n    8.00 PM Federico Ramallo: Why I Chose Stimulus Over React for Building with Rails 7\n\n    8.30 PM Social time\n\n    8.50 PM Doors close\n\n    Brought to you by Evil Martians.\n\n    https://lu.ma/npghoigs\n  video_provider: \"not_recorded\"\n  id: \"sf-bay-area-ruby-meetup-march-2025\"\n  video_id: \"sf-bay-area-ruby-meetup-march-2025\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n  talks:\n    - title: \"New Relic\"\n      date: \"2025-03-20\"\n      announced_at: \"2025-03-03 12:00:00 UTC\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2025\"\n      id: \"kayla-reopelle-sf-bay-area-ruby-meetup-march-2025\"\n      video_id: \"kayla-reopelle-sf-bay-area-ruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n      speakers:\n        - Kayla Reopelle\n\n    - title: \"Avo\"\n      date: \"2025-03-20\"\n      announced_at: \"2025-03-03 12:00:00 UTC\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2025\"\n      id: \"adrian-marin-sf-bay-area-ruby-meetup-march-2025\"\n      video_id: \"adrian-marin-sf-bay-area-ruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n      speakers:\n        - Adrian Marin\n\n    - title: \"Open Mic\"\n      date: \"2025-03-20\"\n      announced_at: \"2025-03-03 12:00:00 UTC\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2025\"\n      id: \"open-mic-sf-bay-area-ruby-meetup-march-2025\"\n      video_id: \"open-mic-sf-bay-area-ruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n      speakers:\n        - TBA\n\n    - title: \"A Brewer's Guide to Filtering out Complexity and Churn\"\n      date: \"2025-03-20\"\n      announced_at: \"2025-03-03 12:00:00 UTC\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2025\"\n      id: \"fito-alan-sf-bay-area-ruby-meetup-march-2025\"\n      video_id: \"fito-alan-sf-bay-area-ruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n      speakers:\n        - Fito von Zastrow\n        - Alan Ridlehoover\n\n    - title: \"Why I Chose Stimulus Over React for Building with Rails 7\"\n      date: \"2025-03-20\"\n      announced_at: \"2025-03-03 12:00:00 UTC\"\n      event_name: \"SF Bay Area Ruby Meetup - March 2025\"\n      id: \"federico-ramallo-sf-bay-area-ruby-meetup-march-2025\"\n      video_id: \"federico-ramallo-sf-bay-area-ruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      thumbnail_xs: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_sm: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_md: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg\"\n      thumbnail_lg: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n      thumbnail_xl: \"https://pbs.twimg.com/media/GigjZUSawAAlce8?format=jpg&name=4096x4096\"\n      speakers:\n        - Federico Ramallo\n\n- title: \"SF Bay Area Ruby Meetup - April 2025\"\n  raw_title: \"SF Ruby February Meetup in April @ Sentry\"\n  event_name: \"SF Bay Area Ruby Meetup - April 2025\"\n  date: \"2025-04-23\"\n  announced_at: \"2025-04-08 12:00:00 UTC\"\n  published_at: \"2025-04-28\"\n  description: |-\n    ​​Hey, Bay Area builders and tinkerers!\n\n    This time we are hosted by our friends from Sentry.\n\n    Address: 45 Fremont St, San Francisco\n\n    ​Agenda:\n\n    ​5:30 PM Intro\n\n    5:40 PM Neil Manvar (Sentry): Solving Ruby issues in Record-time\n\n    ​6:00 PM Rich Steinmetz (Clickfunnels): Grow Your API Integration Suite While Keeping Your Devs Focused on the Product Core\n\n    ​6:30 PM Break\n\n    ​6:50 PM Open mic! Prepare your announcements!\n\n    ​7:10 PM Jake Zimmerman (Stripe): Sorbet syntax: a retrospective\n\n    ​7:40 PM Todd Sedano (Gusto): Starting a Rails project with Packwerk\n\n    ​8:10 PM Irina Nazarova (Evil Martians): Start-ups on Rails\n\n    8.30 PM Social time\n\n    9:00 PM Doors close\n\n    Brought to you by Evil Martians, Irina Nazarova, Cameron Dutro.\n\n    https://lu.ma/9uabe94u\n  video_provider: \"youtube\"\n  video_id: \"eqLbYCCCRO0\"\n  id: \"sf-bay-area-ruby-meetup-april-2025\"\n  talks:\n    - title: \"Intro SF Bay Area Ruby Meetup - April 2025\"\n      start_cue: \"00:00:00\"\n      end_cue: \"00:02:57\"\n      date: \"2025-04-23\"\n      announced_at: \"2025-04-08 12:00:00 UTC\"\n      published_at: \"2025-04-28\"\n      event_name: \"SF Bay Area Ruby Meetup - April 2025\"\n      id: \"intro-sf-bay-area-ruby-meetup-april-2025\"\n      video_id: \"intro-sf-bay-area-ruby-meetup-april-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Cameron Dutro\n\n    - title: \"Solving Ruby 'issues' in record-time (using Sentry's Autofix)\"\n      start_cue: \"00:03:34\"\n      end_cue: \"00:21:51\"\n      thumbnail_cue: \"03:33\"\n      date: \"2025-04-23\"\n      announced_at: \"2025-04-08 12:00:00 UTC\"\n      published_at: \"2025-04-28\"\n      event_name: \"SF Bay Area Ruby Meetup - April 2025\"\n      id: \"neil-manvar-sf-bay-area-ruby-meetup-april-2025\"\n      video_id: \"neil-manvar-sf-bay-area-ruby-meetup-april-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Neil Manvar\n\n    - title: \"Grow Your API Integration Suite While Keeping Your Devs Focused on the Product Core\"\n      start_cue: \"00:21:51\"\n      end_cue: \"00:54:43\"\n      date: \"2025-04-23\"\n      announced_at: \"2025-04-08 12:00:00 UTC\"\n      published_at: \"2025-04-28\"\n      event_name: \"SF Bay Area Ruby Meetup - April 2025\"\n      id: \"rich-steinmetz-sf-bay-area-ruby-meetup-april-2025\"\n      video_id: \"rich-steinmetz-sf-bay-area-ruby-meetup-april-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Rich Steinmetz\n\n    - title: \"Open Mic: New edition of the Eloquent Ruby Book\"\n      start_cue: \"00:55:11\"\n      end_cue: \"00:55:56\"\n      thumbnail_cue: \"00:55:34\"\n      date: \"2025-04-23\"\n      announced_at: \"2025-04-08 12:00:00 UTC\"\n      published_at: \"2025-04-28\"\n      event_name: \"SF Bay Area Ruby Meetup - April 2025\"\n      id: \"open-mic-brandon-weaver-sf-bay-area-ruby-meetup-april-2025\"\n      video_id: \"open-mic-brandon-weaver-sf-bay-area-ruby-meetup-april-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Brandon Weaver is working on the new edition of the Eloquent Ruby book that is coming out soon!\n      speakers:\n        - Brandon Weaver\n\n    - title: \"Open Mic: Gusto is hiring\"\n      start_cue: \"00:56:20\"\n      end_cue: \"00:57:20\"\n      date: \"2025-04-23\"\n      announced_at: \"2025-04-08 12:00:00 UTC\"\n      published_at: \"2025-04-28\"\n      event_name: \"SF Bay Area Ruby Meetup - April 2025\"\n      id: \"open-mic-todd-sedano-sf-bay-area-ruby-meetup-april-2025\"\n      video_id: \"open-mic-todd-sedano-sf-bay-area-ruby-meetup-april-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Todd Sedano says Gusto is hiring! Join them in Dogpatch.\n      speakers:\n        - Todd Sedano\n\n    - title: \"Open Mic: Luthor.ai is hiring\"\n      start_cue: \"00:57:58\"\n      end_cue: \"00:58:24\"\n      date: \"2025-04-23\"\n      announced_at: \"2025-04-08 12:00:00 UTC\"\n      published_at: \"2025-04-28\"\n      event_name: \"SF Bay Area Ruby Meetup - April 2025\"\n      id: \"open-mic-glen-espinosa-sf-bay-area-ruby-meetup-april-2025\"\n      video_id: \"open-mic-glen-espinosa-sf-bay-area-ruby-meetup-april-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Glenn Espinosa says Luthor.ai is hiring! Build the bleeding-age AI in Ruby at the YC-backed startup.\n      speakers:\n        - Glenn Espinosa\n\n    - title: \"Past, Present, and Future of Sorbet Type Syntax\"\n      start_cue: \"00:58:25\"\n      end_cue: \"01:34:38\"\n      date: \"2025-04-23\"\n      announced_at: \"2025-04-08 12:00:00 UTC\"\n      published_at: \"2025-04-28\"\n      event_name: \"SF Bay Area Ruby Meetup - April 2025\"\n      id: \"jake-zimmerman-sf-bay-area-ruby-meetup-april-2025\"\n      video_id: \"jake-zimmerman-sf-bay-area-ruby-meetup-april-2025\"\n      slides_url: \"https://sorbet.run/talks/SFRubyApril2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Jake Zimmerman\n\n    - title: \"Starting a Rails project with Packwerk\"\n      start_cue: \"01:34:39\"\n      end_cue: \"0​1:59:27\"\n      date: \"2025-04-23\"\n      announced_at: \"2025-04-08 12:00:00 UTC\"\n      published_at: \"2025-04-28\"\n      event_name: \"SF Bay Area Ruby Meetup - April 2025\"\n      id: \"todd-sedano-sf-bay-area-ruby-meetup-april-2025\"\n      video_id: \"todd-sedano-sf-bay-area-ruby-meetup-april-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Todd Sedano\n\n    - title: \"Startups on Rails in 2025\"\n      start_cue: \"01:59:28\"\n      end_cue: \"02:29:35\"\n      date: \"2025-04-23\"\n      announced_at: \"2025-04-08 12:00:00 UTC\"\n      published_at: \"2025-04-28\"\n      event_name: \"SF Bay Area Ruby Meetup - April 2025\"\n      id: \"irina-nazarova-sf-bay-area-ruby-meetup-april-2025\"\n      video_id: \"irina-nazarova-sf-bay-area-ruby-meetup-april-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Irina Nazarova\n\n- title: \"SF Bay Area Ruby Meetup - May 2025\"\n  raw_title: \"SF Ruby February Meetup in May @ Cisco Meraki\"\n  event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n  date: \"2025-05-21\"\n  published_at: \"2025-06-01\"\n  video_provider: \"youtube\"\n  video_id: \"-9MZVvnqw-0\"\n  id: \"sf-bay-area-ruby-meetup-may-2025\"\n  description: |-\n    Hey, Bay Area builders and tinkerers!\n\n    This time we are hosted by Cisco Meraki and sponsored by Gusto! We are quickly crafting the agenda now, and it's going to be amazing thanks to all of you.\n\n    🎙️ Submit a talk proposal here: https://forms.gle/C9HQzaT5jvwA5xwc7\n\n    Ruby is the quiet force behind the Bay Area's most successful tech organizations and startups from GitHub, Shopify and Stripe to Figma, Chime, and bolt.new.\n\n    We are gathering every month to learn, share, inspire each other, and it feels great because of MINASWAN 💗.\n\n    Our meetups explore building and scaling Ruby and Rails applications. We go deep into technical topics and don't shy away from new ideas and weird experiments! We always have an open mic for everyone's announcements or questions🎙️! Join us in discovering the nicest Ruby HQs 🏙️❤️\n\n    Catch you on the flip side! A massive shoutout to Cisco Meraki for hosting!\n\n    Agenda:\n\n    Fito von Zastrow & Alan Ridlehoover (Cisco Meraki): Derailing Our Application: How and Why We Are Decoupling Ourselves from Rails\n    Obie Fernandez (Shopify): Structured AI Workflows at Scale with Roast\n    Todd Kummer (Rockridge Solutions): Deploying a hobby project on Rails 8 and Kamal\n    Victoria Melnikova (Evil Martians): Ruby events not to miss in 2025\n    Brandon Weaver (One Medical): Red in Fantasyland\n\n    Brought to you by Evil Martians.\n\n    P.S. The video from the last meetup is up on our RubyEvents page, as usual:\n    https://www.rubyevents.org/talks/sf-bay-area-ruby-meetup-april-2025\n\n    https://lu.ma/9f6l9pn2\n  talks:\n    - title: \"Intro SF Bay Area Ruby Meetup - May 2025\"\n      start_cue: \"00:00\"\n      end_cue: \"03:44\"\n      thumbnail_cue: \"00:05\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"intro-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"intro-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Cameron Dutro\n\n    - title: \"Intro from Meraki\"\n      start_cue: \"03:44\"\n      end_cue: \"08:20\"\n      thumbnail_cue: \"03:49\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"ronan-potage-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"ronan-potage-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Ronan Potage\n\n    - title: \"Derailing Our Application: How and Why We Are Decoupling Ourselves from Rails\"\n      start_cue: \"08:20\"\n      end_cue: \"39:24\"\n      thumbnail_cue: \"08:25\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"fito-von-zastrow-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"fito-von-zastrow-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Fito von Zastrow\n        - Alan Ridlehoover\n\n    - title: \"Structured AI Workflows at Scale with Roast\"\n      start_cue: \"39:24\"\n      end_cue: \"01:18:30\"\n      thumbnail_cue: \"39:33\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"obie-fernandez-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"obie-fernandez-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Obie Fernandez\n\n    - title: \"Deploying a hobby project on Rails 8 and Kamal\"\n      start_cue: \"01:18:41\"\n      end_cue: \"01:34:31\"\n      thumbnail_cue: \"01:19:03\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"todd-kummer-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"todd-kummer-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Todd Kummer\n\n    - title: \"Open Mic: SF Ruby AI Hackathon\"\n      start_cue: \"01:34:31\"\n      end_cue: \"01:38:08\"\n      thumbnail_cue: \"01:35:37\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"kamil-nicieja-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"kamil-nicieja-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      description: |-\n        sign up at https://lu.ma/sfruby\n      speakers:\n        - Kamil Nicieja\n\n    - title: \"Open Mic: HelloCSV\"\n      start_cue: \"01:38:11\"\n      end_cue: \"01:41:42\"\n      thumbnail_cue: \"01:38:44\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"chris-zhu-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"chris-zhu-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Founder of Primary.health\n\n        https://github.com/HelloCSV/HelloCSV\n      speakers:\n        - Chris Zhu\n      additional_resources:\n        - name: \"HelloCSV/HelloCSV\"\n          type: \"repo\"\n          url: \"https://github.com/HelloCSV/HelloCSV\"\n\n    - title: \"Open Mic: Substack\"\n      start_cue: \"01:41:42\"\n      end_cue: \"01:42:21\"\n      thumbnail_cue: \"01:41:47\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"sarah-mei-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"sarah-mei-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      description: |-\n        https://substack.com/@sarahmei\n      speakers:\n        - Sarah Mei\n\n    - title: \"Open Mic: Upcoming Edition of Eloquent Ruby Version 2\"\n      start_cue: \"01:42:21\"\n      end_cue: \"01:43:05\"\n      thumbnail_cue: \"01:42:26\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"brandon-weaver-open-mic-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"brandon-weaver-open-mic-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Brandon Weaver\n\n    - title: \"Ruby events not to miss in 2025\"\n      start_cue: \"01:43:05\"\n      end_cue: \"0​1:45:55\"\n      thumbnail_cue: \"01:43:10\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"victoria-melnikova-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"victoria-melnikova-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Victoria Melnikova\n\n    - title: \"Red in Fantasyland\"\n      start_cue: \"01:45:55\"\n      end_cue: \"02:43:25\"\n      thumbnail_cue: \"01:46:00\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"brandon-weaver-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"brandon-weaver-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Brandon Weaver\n\n    - title: \"Outro + sfruby.com announcement\"\n      start_cue: \"02:43:25\"\n      end_cue: \"02:44:49\"\n      thumbnail_cue: \"02:44:01\"\n      date: \"2025-05-21\"\n      published_at: \"2025-05-31\"\n      event_name: \"SF Bay Area Ruby Meetup - May 2025\"\n      id: \"outro-sf-bay-area-ruby-meetup-may-2025\"\n      video_id: \"outro-sf-bay-area-ruby-meetup-may-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Cameron Dutro\n        - Irina Nazarova\n\n- title: \"SF Bay Area Ruby Meetup - June 2025\"\n  raw_title: \"SF Ruby February Meetup in June @ Chime\"\n  event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n  date: \"2025-06-04\"\n  published_at: \"2025-06-07\"\n  video_provider: \"youtube\"\n  video_id: \"F_mznVxIfYM\"\n  id: \"sf-bay-area-ruby-meetup-june-2025\"\n  description: |-\n    ​Hey, Bay Area builders and tinkerers!\n\n    Here's our agenda:\n\n    5.30 Connecting with Chicago Ruby!\n    5.40 Intro, news and a message from Chime\n    6 Charles Oliver Nutter (JRuby): Optimize your Ruby World with JRuby!\n    6.40 Melvyn Peignon (Clickhouse): Ruby gems analytics using Clickhouse\n    7 break\n    7.20 open mic\n    7.30 Kieran Klaassen (Cora): Systematic LLM Evaluation for Rails Developers\n    7.50 Justin Bowen (Active Agent): Agents Are Controllers — Agent-oriented programming conventions for Rails with Active Agent\n    8.10 wrap up\n\n    Two of our speakers – Charles Oliver Nutter and Kieran Klaassen – travel to SF to speak at the meetup, thanks to the sponsorship from Gusto!\n\n    Gusto is hiring Ruby engineers and more! Check out https://gusto.com/about/careers to join the team!\n\n    🎙️ Submit a talk proposal here:​https://forms.gle/C9HQzaT5jvwA5xwc7\n\n    ​Ruby is the quiet force behind the Bay Area's most successful tech organizations and startups from GitHub, Shopify and Stripe to Figma, Chime, and bolt.new.\n\n    ​We are gathering every month to learn, share, inspire each other, and it feels great because of MINASWAN 💗.\n\n    ​Our meetups explore building and scaling Ruby and Rails applications. We go deep into technical topics and don't shy away from new ideas and weird experiments! We always have an open mic for everyone's announcements or questions🎙️! Join us in discovering the nicest Ruby HQs 🏙️❤️\n\n    Catch you on the flip side! A massive shoutout to Chime for hosting and sponsoring the event! We are also sponsored by Gusto!\n\n    Brought to you by Evil Martians.\n\n    https://lu.ma/doa9bu64\n  talks:\n    - title: \"Welcome and Introduction from Chime\"\n      start_cue: \"00:00\"\n      end_cue: \"01:35\"\n      thumbnail_cue: \"00:05\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"welcome-intro-chime-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"welcome-intro-chime-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Brandt Sheets\n\n    - title: \"San Francisco Ruby Conference Announcement and CFP\"\n      start_cue: \"01:35\"\n      end_cue: \"08:56\"\n      thumbnail_cue: \"01:40\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"sf-ruby-conference-announcement-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"sf-ruby-conference-announcement-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Website: https://sfruby.com\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Optimize your Ruby World with JRuby\"\n      start_cue: \"08:56\"\n      end_cue: \"1:00:10\"\n      thumbnail_cue: \"09:00\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"charles-oliver-nutter-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"charles-oliver-nutter-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Charles Oliver Nutter\n\n    - title: \"Ruby gems analytics using Clickhouse\"\n      start_cue: \"1:00:10\"\n      end_cue: \"1:19:54\"\n      thumbnail_cue: \"1:00:15\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"melvyn-peignon-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"melvyn-peignon-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Melvyn Peignon\n\n    - title: \"Open Mic: prettytodo\"\n      start_cue: \"1:19:54\"\n      end_cue: \"1:21:53\"\n      thumbnail_cue: \"1:20:00\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"marisa-lopez-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"marisa-lopez-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Gem: https://rubygems.org/gems/prettytodo\n        Repo: https://github.com/celina-lopez/prettytodo\n      speakers:\n        - Marisa Lopez\n      additional_resources:\n        - name: \"Gem\"\n          type: \"gem\"\n          url: \"https://rubygems.org/gems/prettytodo\"\n\n        - name: \"Repository\"\n          type: \"repo\"\n          url: \"https://github.com/celina-lopez/prettytodo\"\n\n    - title: \"Open Mic: SF Ruby AI Hackathon\"\n      start_cue: \"1:22:38\"\n      end_cue: \"1:25:09\"\n      thumbnail_cue: \"1:22:38\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"kamil-nicieja-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"kamil-nicieja-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Luma: https://lu.ma/znhcct7v\n      speakers:\n        - Kamil Nicieja\n\n    - title: \"Open Mic: SF Ruby AI Hackathon\"\n      start_cue: \"1:25:25\"\n      end_cue: \"1:28:10\"\n      thumbnail_cue: \"1:25:25\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"brian-douglas-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"brian-douglas-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Continue.dev: https://continue.dev\n        Amplified.dev: https://amplified.dev\n        Amplified's Repo: https://github.com/continuedev/amplified.dev\n      speakers:\n        - Brian Douglas\n      additional_resources:\n        - name: \"continuedev/amplified.dev\"\n          type: \"repo\"\n          url: \"https://github.com/continuedev/amplified.dev\"\n\n    - title: \"Open Mic: Miles Georgi, Foobara\"\n      start_cue: \"1:28:15\"\n      end_cue: \"1:30:45\"\n      thumbnail_cue: \"1:28:15\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"miles-georgi-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"miles-georgi-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Foobara Repo: https://github.com/foobara/foobara\n        Website: https://foobara.com\n      speakers:\n        - Miles Georgi\n      additional_resources:\n        - name: \"foobara/foobara\"\n          type: \"repo\"\n          url: \"https://github.com/foobara/foobara\"\n\n    - title: \"Open Mic: Sarah Mei's Newsletter\"\n      start_cue: \"1:30:45\"\n      end_cue: \"1:31:40\"\n      thumbnail_cue: \"1:30:45\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"sarah-mei-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"sarah-mei-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      description: |-\n        Sarah Mei's Newsletter: https://sarahmei.substack.com/\n      speakers:\n        - Sarah Mei\n\n    - title: \"Learnings and roadmap for Langchain.rb\"\n      start_cue: \"1:32:00\"\n      end_cue: \"1:38:47\"\n      thumbnail_cue: \"1:32:05\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"andrei-bondarev-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"andrei-bondarev-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrei Bondarev\n\n    - title: \"Systematic LLM Evaluation for Rails Developers\"\n      start_cue: \"1:38:47\"\n      end_cue: \"1:54:42\"\n      thumbnail_cue: \"1:38:50\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"kieran-klaassen-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"kieran-klaassen-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Kieran Klaassen\n\n    - title: \"Agents Are Controllers — Agent-oriented programming conventions for Rails with Active Agent\"\n      start_cue: \"1:54:42\"\n      end_cue: \"2:10:17\"\n      thumbnail_cue: \"1:54:57\"\n      date: \"2025-06-04\"\n      published_at: \"2025-06-04\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025\"\n      id: \"justin-bowen-sf-bay-area-ruby-meetup-june-2025\"\n      video_id: \"justin-bowen-sf-bay-area-ruby-meetup-june-2025\"\n      video_provider: \"parent\"\n      speakers:\n        - Justin Bowen\n\n- title: \"SF Ruby & Elixir - June 2025 Special\"\n  raw_title: \"SF Ruby & Elixir Meetup @ Planet Scale, June 18, 2025\"\n  event_name: \"SF Bay Area Ruby Meetup - June 2025 Special\"\n  date: \"2025-06-18\"\n  published_at: \"2025-07-25\"\n  description: |-\n    ​Address: 123 S Park St\n\n    ​Hey, Bay Area builders and tinkerers,\n\n    This is a special edition of the SF Ruby x Elixir that we host while José Valim is in town. José is the author of Elixir, a member of core Ruby and Rails teams in the past, a brilliant and inspiring speaker, and now the founder of Tidewave.ai!\n\n    The main item on the agenda is the talk from José, but we will certainly have our classic open mic, and perhaps something else. Join us, it's going to be cool!\n\n    A massive shoutout to PlanetScale for hosting.\n    Brought to you by Evil Martians.\n\n    https://lu.ma/rzyjxo93\n  video_provider: \"children\"\n  video_id: \"sf-ruby-elixir-meetup-june-2025\"\n  id: \"sf-ruby-elixir-meetup-june-2025\"\n  thumbnail_xs: \"https://i.ytimg.com/vi/sv0GsuAAWe8/default.jpg\"\n  thumbnail_sm: \"https://i.ytimg.com/vi/sv0GsuAAWe8/mqdefault.jpg\"\n  thumbnail_md: \"https://i.ytimg.com/vi/sv0GsuAAWe8/hqdefault.jpg\"\n  thumbnail_lg: \"https://i.ytimg.com/vi/sv0GsuAAWe8/sddefault.jpg\"\n  thumbnail_xl: \"https://i.ytimg.com/vi/sv0GsuAAWe8/maxresdefault.jpg\"\n  talks:\n    - title: \"Tidewave.ai\"\n      start_cue: \"00:00\"\n      end_cue: \"05:40\"\n      date: \"2025-06-18\"\n      published_at: \"2025-07-25\"\n      video_provider: \"youtube\"\n      id: \"jose-valim-sf-ruby-elixir-meetup-june-2025\"\n      video_id: \"sv0GsuAAWe8\"\n      event_name: \"SF Bay Area Ruby Meetup - June 2025 Special\"\n      description: |-\n        José Valim, author of Elixir programming language, happened to be in San Francisco in June, and we organized a quick meetup, bringing together Elixir and Ruby meetups. Huge shoutout to PlanetScale for hosting.\n\n        José talked about his new product, Tidewave.ai, an AI-powered coding assistant built for server-centric frameworks–Elixir, Rails, and Django (coming soon!), and his vision for the space and the work of a software engineer.\n\n        https://tidewave.ai/\n      speakers:\n        - José Valim\n\n- id: \"sf-ruby-ai-hackathon-2025\"\n  title: \"SF Ruby AI Hackathon 2025\"\n  raw_title: \"SF Ruby AI Hackathon\"\n  event_name: \"SF Ruby AI Hackathon\"\n  date: \"2025-07-19\"\n  description: |-\n    We are thrilled to announce a community-driven Ruby AI Hackathon on Saturday, July 19, 2025 at the Sentry office in San Francisco! 🎉 Hosted by the SF Bay Area Ruby Meetup, this one-day hackathon is open to Ruby engineers of all kinds from the SF area. Details:\n\n    * ​When: Saturday, July 19, 2025, 10:00 am to 5:30 pm\n    * ​Where: Sentry HQ – 45 Fremont St, San Francisco, CA\n    * ​Host: SF Bay Area Ruby Meetup\n    * ​Who: Open to all Rubyists & friends in the Bay Area at any experience level\n    * ​Teams: Solo or teams up to 3 people – your choice\n    * ​Entry fee: None!\n    * ​Food: lunch brought to you by Sentry\n    * ​Prizes: $1,500 for the best team; $1,000 for the 2nd best team; $500 for the third best team\n\n\n    # Rails as the one-person framework\n\n    ​AI-assisted coding has exploded onto the scene, promising to amplify what solo devs can do. Ruby on Rails is the perfect partner for this approach. Rails has long been known as the one-person framework, a powerful toolkit designed to give lone developers and small teams superpowers, compressing the time and knowledge needed to ship big features\n\n    ​This Ruby AI hackathon is about exploring that vision: how AI can make building a Rails app even more of a one-person show! Some participants might even experiment with voice coding setups – it’s all about exploring new ways to build with Ruby.\n\n\n    # ​Current plans\n\n    ​You can work solo as part of a small team. Bring your own application idea to life or choose from several project prompts we’ll provide if you need inspiration. Throughout the day, mentors will be on hand to help with technical issues, brainstorm AI solutions, or just cheer you on. We’re working on bringing special guests from the Ruby AI community joining as mentors and judges.\n\n    ​As an all-day event, we’ll have breaks for lunch and snacks. At the end of the day, each individual or team will get to demo their app and briefly show off their code. A panel of judges will evaluate each project and provide encouraging feedback. They’ll be looking at creativity, use of the theme, and technical achievement given the time constraints.\n\n    ​# Ready to hack? RSVP now!\n\n    ​Sounds exciting? We sure hope so! RSVP on our Meetup page here so we can get a headcount. If you have any questions, feel free to drop by our Ruby SF Slack channel. Otherwise, just bring your laptop on July 19 and get ready to code with vibes.\n\n\n    # ​Brought to you by\n\n    ​The $3,000 prize pool is sponsored by Continue, Evil Martians, and Fly.io. Big thanks to our sponsors for making this event possible.\n\n    ​Continue is the open-source AI code assistant that puts you in control. Customize everything, run anywhere, and build infrastructure that gets better over time.\n\n    ​Evil Martians is the go-to agency for devtools. They design and develop high performance developer tools that scale.\n\n    ​Fly.io is a public cloud built for developers who ship: Easy to deploy on, powerful to grow on.\n\n    ​We’d also like to thank Sentry for hosting the event and keeping us well-fed while we code. Sentry is application monitoring software considered “not bad” by 4 million developers. When your app breaks, it lets you fix it faster.\n\n    https://lu.ma/znhcct7v\n  thumbnail_xs: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,quality=75,width=1920/editor-images/ds/3da48e8b-57af-4a71-8727-0abb38a7baf0.jpg\"\n  thumbnail_sm: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,quality=75,width=1920/editor-images/ds/3da48e8b-57af-4a71-8727-0abb38a7baf0.jpg\"\n  thumbnail_md: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,quality=75,width=1920/editor-images/ds/3da48e8b-57af-4a71-8727-0abb38a7baf0.jpg\"\n  thumbnail_lg: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,quality=75,width=1920/editor-images/ds/3da48e8b-57af-4a71-8727-0abb38a7baf0.jpg\"\n  thumbnail_xl: \"https://images.lumacdn.com/cdn-cgi/image/format=auto,fit=cover,dpr=2,quality=75,width=1920/editor-images/ds/3da48e8b-57af-4a71-8727-0abb38a7baf0.jpg\"\n  # https://pbs.twimg.com/media/Gs3qtgmbQAANYiv?format=jpg&name=medium\n  video_provider: \"scheduled\"\n  video_id: \"sf-ruby-ai-hackathon-2025\"\n  talks: []\n  speakers: []\n\n- id: \"sf-bay-area-ruby-meetup-july-2025\"\n  title: \"SF Bay Area Ruby Meetup - July 2025\"\n  raw_title: \"SF Ruby Meetup, July 22, 2025 @Figma\"\n  event_name: \"SF Bay Area Ruby Meetup - July 2025\"\n  date: \"2025-07-22\"\n  published_at: \"2025-07-26\"\n  description: |-\n    Hey, Bay Area builders and tinkerers,\n\n    In July we are hosted by Figma! Huge shoutout to Gusto for sponsoring travel for Marco Roth.\n\n    Here're our speakers:\n\n    5.30 pm Irina Nazarova (Evil Martians, SF Ruby) intro and the SF Ruby conference ticket sale\n    5.40 Mike Chlipala and Kim Ahlström (Figma): Ruby at Figma\n    5.50 Harrison Touw (Figma): Ruby framework for building internal tools at Figma\n    6.00 Marco Roth with The Modern View Layer Rails Deserves: A Vision for 2025 and Beyond\n    6.40 break\n    7.10 open mic\n    7.30 Jeremy Evans(Ubicloud): Eliminating Unnecessary Implicit Allocations\n    8.10 Social time\n    9 pm Doors close\n\n    🎙️ Submit a talk proposal here:​https://forms.gle/C9HQzaT5jvwA5xwc7\n\n    ​Ruby is the quiet force behind the Bay Area's most successful tech organizations and startups from GitHub, Shopify and Stripe to Figma, Chime, and bolt.new.\n\n    ​We are gathering every month to learn, share, inspire each other, and it feels great because of MINASWAN 💗.\n\n    ​Our meetups explore building and scaling Ruby and Rails applications. We go deep into technical topics and don't shy away from new ideas and weird experiments! We always have an open mic for everyone's announcements or questions🎙️! Join us in discovering the nicest Ruby HQs 🏙️❤️\n\n    Catch you on the flip side! A massive shoutout to Figma for hosting and sponsoring the event! We are also sponsored by Gusto!\n\n    Brought to you by Evil Martians.\n\n    https://lu.ma/8jcbnfls\n  video_provider: \"youtube\"\n  video_id: \"b8lhXJUo_cI\"\n  talks:\n    - title: \"Intro and SF Ruby conference ticket sale\"\n      start_cue: \"00:00\"\n      end_cue: \"05:40\"\n      thumbnail_cue: \"00:06\"\n      date: \"2025-07-22\"\n      id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-july-2025\"\n      video_id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-july-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2025\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Ruby at Figma\"\n      start_cue: \"05:40\"\n      end_cue: \"11:20\"\n      thumbnail_cue: \"05:56\"\n      date: \"2025-07-22\"\n      id: \"mike-chlipala-kim-ahlstrom-sf-bay-area-ruby-meetup-july-2025\"\n      video_id: \"mike-chlipala-kim-ahlstrom-sf-bay-area-ruby-meetup-july-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2025\"\n      speakers:\n        - Mike Chlipala\n        - Kim Ahlström\n\n    - title: \"How Figma builds admin tools\"\n      start_cue: \"11:20\"\n      end_cue: \"30:20\"\n      date: \"2025-07-22\"\n      id: \"harrison-touw-sf-bay-area-ruby-meetup-july-2025\"\n      video_id: \"harrison-touw-sf-bay-area-ruby-meetup-july-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2025\"\n      speakers:\n        - Harrison Touw\n\n    - title: \"The Modern View Layer Rails Deserves: A Vision for 2025 and Beyond\"\n      start_cue: \"30:20\"\n      end_cue: \"1:13:42\"\n      thumbnail_cue: \"30:26\"\n      date: \"2025-07-22\"\n      id: \"marco-roth-sf-bay-area-ruby-meetup-july-2025\"\n      video_id: \"marco-roth-sf-bay-area-ruby-meetup-july-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2025\"\n      slides_url: \"https://speakerdeck.com/marcoroth/the-modern-view-layer-rails-deserves-a-vision-for-2025-and-beyond-at-sf-bay-area-ruby-meetup-july-2025\"\n      speakers:\n        - Marco Roth\n\n    - title: \"Open Mic\"\n      start_cue: \"1:13:42\"\n      end_cue: \"1:42:07\"\n      date: \"2025-07-22\"\n      id: \"open-mic-sf-bay-area-ruby-meetup-july-2025\"\n      video_id: \"open-mic-sf-bay-area-ruby-meetup-july-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2025\"\n      speakers:\n        - TODO\n\n    - title: \"Eliminating Unnecessary Implicit Allocations\"\n      start_cue: \"1:42:07\"\n      end_cue: \"2:36:26\"\n      thumbnail_cue: \"01:42:06\"\n      date: \"2025-07-22\"\n      id: \"jeremy-evans-sf-bay-area-ruby-meetup-july-2025\"\n      video_id: \"jeremy-evans-sf-bay-area-ruby-meetup-july-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - July 2025\"\n      slides_url: \"https://code.jeremyevans.net/presentations/sf-ruby-meetup-2025-07/index.html\"\n      speakers:\n        - Jeremy Evans\n\n- title: \"SF Bay Area Ruby Meetup - August 2025\"\n  id: \"sf-bay-area-ruby-meetup-august-2025\"\n  raw_title: \"SF Ruby Meetup, August @ GitHub\"\n  event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n  date: \"2025-08-26\"\n  published_at: \"2025-08-27\"\n  description: |-\n    Hey, Bay Area builders and tinkerers,\n\n    In August we are hosted by Github!\n\n    🎙️ Submit a talk proposal here: ​https://forms.gle/C9HQzaT5jvwA5xwc7\n\n    ​Ruby is the quiet force behind the Bay Area's most successful tech organizations and startups from GitHub, Shopify and Stripe to Figma, Chime, and bolt.new.\n\n    ​We are gathering every month to learn, share, inspire each other, and it feels great because of MINASWAN 💗.\n\n    ​Our meetups explore building and scaling Ruby and Rails applications. We go deep into technical topics and don't shy away from new ideas and weird experiments! We always have an open mic for everyone's announcements or questions🎙️! Join us in discovering the nicest Ruby HQs 🏙️❤️\n\n    Catch you on the flip side! A massive shoutout to Chime for hosting and sponsoring the event! We are also sponsored by Gusto!\n\n    ​Agenda:\n\n    ​5.30 Intro\n    5.40 GitHub speaker (TBD)\n    6.10 Drew Hoskins (Temporal): Temporal Ruby\n    6.40 break\n    7.00 open mic\n    7.10 Miles Georgi: Tackling Domain Complexity with Foobara\n    7.30 Enrique Mogollán (Handshake): What I've Learned Building an MCP Inspector in Ruby\n    7.50 Irina Nazarova (Evil Martians): Cutting CI Build Time in Half for Whop\n    8.10 wrap up\n\n    Brought to you by Evil Martians.\n\n    https://lu.ma/k2l9089u\n\n  video_provider: \"youtube\"\n  video_id: \"IMAABWxnbUM\"\n  talks:\n    - title: \"Intro & San Francisco Ruby Conference 2025\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"0:00:00\"\n      end_cue: \"0:07:45\"\n      thumbnail_cue: \"0:01:24\"\n      speakers:\n        - Irina Nazarova\n        - Cameron Dutro\n\n    - title: \"Temporal Ruby\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"drew-hoskins-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"drew-hoskins-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"0:07:47\"\n      end_cue: \"0:45:59\"\n      thumbnail_cue: \"0:08:03\"\n      speakers:\n        - Drew Hoskins\n\n    - title: \"What I've Learned Building an MCP Inspector in Ruby\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"enrique-mogollan-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"enrique-mogollan-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      start_cue: \"47:42\"\n      end_cue: \"1:06:18\"\n      thumbnail_cue: \"47:50\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      speakers:\n        - Enrique Mogollán\n\n    - title: \"Open Mic: LlamaPress\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"open-mic-kody-kendall-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"open-mic-kody-kendall-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"1:29:10\"\n      end_cue: \"1:33:00\"\n      thumbnail_cue: \"1:29:46\"\n      speakers:\n        - Kody C. Kendall\n\n    - title: \"Open Mic: tokenruby.com\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"open-mic-yatish-mehta-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"open-mic-yatish-mehta-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"1:33:21\"\n      end_cue: \"1:34:16\"\n      thumbnail_cue: \"1:33:51\"\n      speakers:\n        - Yatish Mehta\n\n    - title: \"Open Mic: dScribe AI\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"open-mic-cole-robertson-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"open-mic-cole-robertson-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"1:34:20\"\n      end_cue: \"1:37:00\"\n      thumbnail_cue: \"1:36:08\"\n      speakers:\n        - Cole Robertson\n\n    - title: \"Open Mic: Cactus\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"open-mic-avinash-joshi-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"open-mic-avinash-joshi-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"1:37:04\"\n      end_cue: \"1:38:22\"\n      thumbnail_cue: \"1:37:09\"\n      speakers:\n        - Avinash Joshi\n\n    - title: \"Open Mic: rv\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"open-mic-andre-arko-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"open-mic-andre-arko-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"1:38:30\"\n      end_cue: \"1:40:36\"\n      thumbnail_cue: \"1:39:42\"\n      speakers:\n        - André Arko\n\n    - title: \"Open Mic: Active Agent v0.6.1\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"open-mic-justin-bowen-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"open-mic-justin-bowen-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"1:40:40\"\n      end_cue: \"1:42:27\"\n      thumbnail_cue: \"1:40:45\"\n      speakers:\n        - Justin Bowen\n\n    - title: \"Open Mic: The Human History of Ruby Book\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"open-mic-rhiannon-payne-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"open-mic-rhiannon-payne-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"1:42:27\"\n      end_cue: \"1:45:11\"\n      thumbnail_cue: \"1:44:22\"\n      speakers:\n        - Rhiannon Payne\n\n    - title: \"Open Mic: Superform\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"open-mic-brad-gessler-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"open-mic-brad-gessler-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"1:45:15\"\n      end_cue: \"1:47:36\"\n      thumbnail_cue: \"1:45:37\"\n      speakers:\n        - Brad Gessler\n\n    - title: \"Tackling Domain Complexity with Foobara\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"miles-georgi-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"miles-georgi-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      start_cue: \"1:49:43\"\n      end_cue: \"2:12:26\"\n      thumbnail_cue: \"1:49:54\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      speakers:\n        - Miles Georgi\n\n    - title: \"The Whop & Chop - Cutting CI Time in half\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"irina-nazarova-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"irina-nazarova-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      start_cue: \"2:14:44\"\n      end_cue: \"2:29:55\"\n      thumbnail_cue: \"2:15:25\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Getting the Most out of AI Coding Agents for Your Rails App\"\n      date: \"2025-08-26\"\n      published_at: \"2025-08-27\"\n      id: \"sergey-karayev-sf-bay-area-ruby-meetup-august-2025\"\n      video_id: \"sergey-karayev-sf-bay-area-ruby-meetup-august-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - August 2025\"\n      start_cue: \"2:30:46\"\n      end_cue: \"2:47:59\"\n      thumbnail_cue: \"2:30:59\"\n      speakers:\n        - Sergey Karayev\n\n- id: \"sf-bay-area-ruby-meetup-october-2025\"\n  title: \"SF Bay Area Ruby Meetup - October 2025\"\n  raw_title: \"SF Ruby Meetup. October 30, 2025 @ AngelList's Founders Cafe\"\n  event_name: \"SF Bay Area Ruby Meetup - October 2025\"\n  date: \"2025-10-30\"\n  published_at: \"2025-12-19\"\n  description: |-\n    Hey, Bay Area builders and tinkerers,\n\n    In October we are hosted by the Ruby team at AngelList's @Founders_Cafe!\n\n    ​Agenda:\n    5.30 Intro\n    5.40 Chamod Gamage (AngelList): How AngelList Writes Spreadsheets... in Ruby!\n    6.10 Chris Fung (Binti): Writing Ruby Bindings to the Fjall Embedded Key/Value Store in Rust\n    6.30 break\n    6.50 open mic\n    7.00 Scott Motte (Dotenvx): Secure App Configuration with Dotenvx\n    7.20 Cameron Dutro (Cisco Meraki): LiveComponent: Client-side Rendering and State Management for ViewComponent\n    7.40: Miles Georgi: Demoing AI-backed Domain Logic in Foobara\n    8.00 wrap up\n\n    🎙️ Submit a talk proposal for future events here:​https://forms.gle/C9HQzaT5jvwA5xwc7\n\n    ​Ruby is the quiet force behind the Bay Area's most successful tech organizations and startups from GitHub, Shopify and Stripe to Figma, Chime, and bolt.new.\n\n    ​We are gathering every month to learn, share, inspire each other, and it feels great because of MINASWAN 💗.\n\n    ​Our meetups explore building and scaling Ruby and Rails applications. We go deep into technical topics and don't shy away from new ideas and weird experiments! We always have an open mic for everyone's announcements or questions🎙️! Join us in discovering the nicest Ruby HQs 🏙️❤️\n\n    Catch you on the flip side! A massive shoutout to AngelList for hosting and sponsoring the event.\n\n    Brought to you by Evil Martians.\n\n    https://lu.ma/xh2h2jd3\n\n  video_provider: \"youtube\"\n  video_id: \"BCKGvKTk3cU\"\n  talks:\n    - title: \"Intro\"\n      date: \"2025-10-30\"\n      published_at: \"2025-12-19\"\n      id: \"intro-sf-bay-area-ruby-meetup-october-2025\"\n      video_id: \"intro-sf-bay-area-ruby-meetup-october-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2025\"\n      start_cue: \"00:00\"\n      end_cue: \"00:25\"\n      thumbnail_cue: \"00:15\"\n      speakers:\n        - Cameron Dutro\n\n    - title: \"Improving Excel reporting workflow productivity by 10× with a graph-based Ruby DSL\"\n      date: \"2025-10-30\"\n      published_at: \"2025-12-19\"\n      id: \"chamod-gamage-sf-bay-area-ruby-meetup-october-2025\"\n      video_id: \"chamod-gamage-sf-bay-area-ruby-meetup-october-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2025\"\n      start_cue: \"00:26\"\n      end_cue: \"28:10\"\n      thumbnail_cue: \"06:15\"\n      speakers:\n        - Chamod Gamage\n\n    - title: \"Building Ruby–Rust native extensions by binding Ruby to the Fjall embedded key-value store\"\n      date: \"2025-10-30\"\n      published_at: \"2025-12-19\"\n      id: \"chris-fung-sf-bay-area-ruby-meetup-october-2025\"\n      video_id: \"chris-fung-sf-bay-area-ruby-meetup-october-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2025\"\n      start_cue: \"28:24\"\n      end_cue: \"52:42\"\n      thumbnail_cue: \"28:46\"\n      speakers:\n        - Chris Fung\n\n    - title: \"The evolution of .env files and a new approach to encrypted, commit-safe secrets with MVX\"\n      date: \"2025-10-30\"\n      published_at: \"2025-12-19\"\n      id: \"scott-motte-sf-bay-area-ruby-meetup-october-2025\"\n      video_id: \"scott-motte-sf-bay-area-ruby-meetup-october-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2025\"\n      start_cue: \"52:53\"\n      end_cue: \"1:18:16\"\n      thumbnail_cue: \"53:15\"\n      speakers:\n        - Scott Motte\n\n    - title: \"Introducing LiveComponent, a Rails framework for live, stateful ViewComponent built on Hotwire and Stimulus\"\n      date: \"2025-10-30\"\n      published_at: \"2025-12-19\"\n      id: \"cameron-dutro-sf-bay-area-ruby-meetup-october-2025\"\n      video_id: \"cameron-dutro-sf-bay-area-ruby-meetup-october-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2025\"\n      start_cue: \"1:21:44\"\n      end_cue: \"1:39:11\"\n      thumbnail_cue: \"1:21:49\"\n      speakers:\n        - Cameron Dutro\n\n    - title: \"Using AI-backed domain logic in Foobara to model and execute business rules\"\n      date: \"2025-10-30\"\n      published_at: \"2025-12-19\"\n      id: \"miles-georgi-sf-bay-area-ruby-meetup-october-2025\"\n      video_id: \"miles-georgi-sf-bay-area-ruby-meetup-october-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - October 2025\"\n      start_cue: \"1:40:03\"\n      end_cue: \"2:04:14\"\n      thumbnail_cue: \"1:40:08\"\n      speakers:\n        - Miles Georgi\n\n- id: \"sf-ruby-hack-day-november-2025\"\n  title: \"SF Ruby Hack Day - November 2025\"\n  raw_title: \"SF Ruby Hack Day @ AngelList\"\n  event_name: \"SF Ruby Hack Day - November 2025\"\n  date: \"2025-11-21\"\n  description: |-\n    ​Community Day of the SF Ruby Conference and AngelList present: Hack Day at AngelList HQ! See you there!\n\n    https://lu.ma/sfrubyconf25hackday\n\n  video_provider: \"not_recorded\"\n  video_id: \"sf-ruby-hack-day-november-2025\"\n  talks: []\n\n- id: \"sf-bay-area-ruby-meetup-december-2025\"\n  title: \"SF Bay Area Ruby Meetup - December 2025\"\n  raw_title: \"SF Ruby Meetup. December 2025 @ Intercom\"\n  event_name: \"SF Bay Area Ruby Meetup - December 2025\"\n  date: \"2025-12-18\"\n  published_at: \"2026-02-23\"\n  description: |-\n    Hey, Bay Area builders and tinkerers,\n\n    In December we are hosted by friends from Intercom🥳\n\n    5.30 Hiten Parmar: Intro and welcome from Intercom\n    5.40 Noel Rappin (Chime) remotely: Ruby 4.0\n    6.00 Irina Nazarova (Evil Martians): One Yummy JS Runtime for Rails\n    6.20 break\n    6.50 Open mic (bring your announcements!)\n    7.10 Justin Bowen: live demo of ActiveAgent-powered Fizzy and Writebook\n    7.30-8.30 Social time!\n\n    ​Please send your talk proposals here:\n    https://forms.gle/C9HQzaT5jvwA5xwc7\n\n    ​Ruby is the quiet force behind the Bay Area's most successful tech organizations and startups from GitHub, Shopify and Stripe to Figma, Chime, and bolt.new.\n\n    ​We are gathering every month to learn, share, inspire each other, and it feels great because of MINASWAN 💗.\n\n    ​Our meetups explore building and scaling Ruby and Rails applications. We go deep into technical topics and don't shy away from new ideas and weird experiments! We always have an open mic for everyone's announcements or questions🎙️! Join us in discovering the nicest Ruby HQs 🏙️❤️\n\n    Catch you on the flip side! A massive shoutout to Intercom for hosting and sponsoring the event.\n\n    Brought to you by Evil Martians.\n\n    https://lu.ma/ot3v0fzb\n\n  video_provider: \"youtube\"\n  video_id: \"V3b9hfN230w\"\n  talks:\n    - title: \"Introduction\"\n      date: \"2025-12-18\"\n      published_at: \"2026-02-23\"\n      id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-december-2025\"\n      video_id: \"irina-nazarova-intro-sf-bay-area-ruby-meetup-december-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2025\"\n      start_cue: \"00:00\"\n      end_cue: \"02:15\"\n      thumbnail_cue: \"00:05\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Introduction and welcome from Intercom\"\n      date: \"2025-12-18\"\n      published_at: \"2026-02-23\"\n      id: \"hiten-parmar-sf-bay-area-ruby-meetup-december-2025\"\n      video_id: \"hiten-parmar-sf-bay-area-ruby-meetup-december-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2025\"\n      start_cue: \"02:15\"\n      end_cue: \"05:00\"\n      thumbnail_cue: \"02:50\"\n      speakers:\n        - Hiten Parmar\n\n    - title: \"Ruby 4.0\"\n      date: \"2025-12-18\"\n      published_at: \"2026-02-23\"\n      id: \"noel-rappin-sf-bay-area-ruby-meetup-december-2025\"\n      video_id: \"noel-rappin-sf-bay-area-ruby-meetup-december-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2025\"\n      start_cue: \"05:00\"\n      end_cue: \"47:45\"\n      thumbnail_cue: \"07:49\"\n      speakers:\n        - Noel Rappin\n\n    - title: \"One Yummy JS Runtime for Rails\"\n      date: \"2025-12-18\"\n      published_at: \"2026-02-23\"\n      id: \"irina-nazarova-sf-bay-area-ruby-meetup-december-2025\"\n      video_id: \"irina-nazarova-sf-bay-area-ruby-meetup-december-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2025\"\n      start_cue: \"47:45\"\n      end_cue: \"57:05\"\n      thumbnail_cue: \"47:50\"\n      speakers:\n        - Irina Nazarova\n\n    - title: \"Open mic\"\n      date: \"2025-12-18\"\n      published_at: \"2026-02-23\"\n      id: \"open-mic-sf-bay-area-ruby-meetup-december-2025\"\n      video_id: \"open-mic-sf-bay-area-ruby-meetup-december-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2025\"\n      start_cue: \"57:05\"\n      end_cue: \"1:07:57\"\n      thumbnail_cue: \"57:10\"\n      speakers: []\n\n    - title: \"Live demonstration of ActiveAgent-powered Fizzy and Writebook\"\n      date: \"2025-12-18\"\n      published_at: \"2026-02-23\"\n      id: \"justin-bowen-sf-bay-area-ruby-meetup-december-2025\"\n      video_id: \"justin-bowen-sf-bay-area-ruby-meetup-december-2025\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - December 2025\"\n      start_cue: \"1:07:57\"\n      end_cue: \"1:21:25\"\n      thumbnail_cue: \"1:08:02\"\n      speakers:\n        - Justin Bowen\n\n- id: \"sf-bay-area-ruby-meetup-january-2026\"\n  title: \"SF Bay Area Ruby Meetup - January 2026\"\n  raw_title: \"SF Ruby Meetup. January 2026 @ Persona\"\n  event_name: \"SF Bay Area Ruby Meetup - January 2026\"\n  date: \"2026-01-22\"\n  published_at: \"2026-02-26\"\n  description: |-\n    ​Hey, Bay Area builders and tinkerers,\n\n    In January Persona is hosting the first SF Ruby in 2026🥳\n\n    ​Take the stage for 10-30 minutes. Here's what we are looking for:\n    - demos of new and ambitious Ruby startups (just tell us what you're building with Ruby!)\n    - new open source in Ruby/Rails ecosystem (including your wild experiments and new ideas in established open source projects)\n    - real stories from Ruby/Rails apps and teams, solving complex, tricky, or fun problems\n\n    Send your talk details here: https://forms.gle/C9HQzaT5jvwA5xwc7\n\n    Agenda (preliminary):\n\n    5.30 Intro\n    5.40 Samuel Giddins (Persona): The 3Rs of Ruby Performance: Reduce, Reuse, Recycle (Objects)\n    6.10 Enrique Mogollán (Handshake): Breaking Nil to fix Bugs\n    6.40 break\n    7.00 open mic\n    7.10 Vitor Oliveira (Strides): What to Expect from Ruby 4.0\n    7.40 Todd Kummer (Rockridge Solutions): Customizing form helpers and tag helpers\n    8.10 wrap up\n\n    ---\n\n    ​Ruby is the quiet force behind the Bay Area's most successful tech organizations and startups from GitHub, Shopify and Stripe to Figma, Chime, and bolt.new.\n\n    ​We are gathering every month to learn, share, inspire each other, and it feels great because of MINASWAN 💗.\n\n    ​Our meetups explore building and scaling Ruby and Rails applications. We go deep into technical topics and don't shy away from new ideas and weird experiments! We always have an open mic for everyone's announcements or questions🎙️! Join us in discovering the nicest Ruby HQs 🏙️❤️\n\n    Catch you on the flip side! A massive shoutout to Persona for hosting and sponsoring the event.\n\n    Brought to you by Evil Martians.\n  video_provider: \"youtube\"\n  video_id: \"DykqANnJfBc\"\n  talks:\n    - title: \"Introduction\"\n      date: \"2026-01-22\"\n      published_at: \"2026-02-26\"\n      id: \"intro-sf-bay-area-ruby-meetup-january-2026\"\n      video_id: \"intro-sf-bay-area-ruby-meetup-january-2026\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2026\"\n      start_cue: \"00:00\"\n      end_cue: \"02:15\"\n      thumbnail_cue: \"00:05\"\n      speakers:\n        - Irina Nazarova\n        - Charles Yeh\n\n    - title: \"The 3Rs of Ruby Performance: Reduce, Reuse, Recycle (Objects)\"\n      date: \"2026-01-22\"\n      published_at: \"2026-02-26\"\n      id: \"samuel-giddins-sf-bay-area-ruby-meetup-january-2026\"\n      video_id: \"samuel-giddins-sf-bay-area-ruby-meetup-january-2026\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2026\"\n      start_cue: \"02:15\"\n      end_cue: \"40:13\"\n      thumbnail_cue: \"02:20\"\n      speakers:\n        - Samuel Giddins\n\n    - title: \"Breaking Nil to fix Bugs\"\n      date: \"2026-01-22\"\n      published_at: \"2026-02-26\"\n      id: \"enrique-mogollan-sf-bay-area-ruby-meetup-january-2026\"\n      video_id: \"enrique-mogollan-sf-bay-area-ruby-meetup-january-2026\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2026\"\n      start_cue: \"40:13\"\n      end_cue: \"1:05:49\"\n      thumbnail_cue: \"40:18\"\n      speakers:\n        - Enrique Mogollán\n\n    - title: \"Open mic\"\n      date: \"2026-01-22\"\n      published_at: \"2026-02-26\"\n      id: \"open-mic-sf-bay-area-ruby-meetup-january-2026\"\n      video_id: \"open-mic-sf-bay-area-ruby-meetup-january-2026\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2026\"\n      start_cue: \"1:05:49\"\n      end_cue: \"1:11:24\"\n      thumbnail_cue: \"1:05:54\"\n      speakers: []\n\n    - title: \"What to Expect from Ruby 4.0\"\n      date: \"2026-01-22\"\n      published_at: \"2026-02-26\"\n      id: \"vitor-oliveira-sf-bay-area-ruby-meetup-january-2026\"\n      video_id: \"vitor-oliveira-sf-bay-area-ruby-meetup-january-2026\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2026\"\n      start_cue: \"1:11:24\"\n      end_cue: \"1:40:24\"\n      thumbnail_cue: \"1:11:29\"\n      speakers:\n        - Vitor Oliveira\n\n    - title: \"Customizing form helpers and tag helpers\"\n      date: \"2026-01-22\"\n      published_at: \"2026-02-26\"\n      id: \"todd-kummer-sf-bay-area-ruby-meetup-january-2026\"\n      video_id: \"todd-kummer-sf-bay-area-ruby-meetup-january-2026\"\n      video_provider: \"parent\"\n      event_name: \"SF Bay Area Ruby Meetup - January 2026\"\n      start_cue: \"1:40:24\"\n      end_cue: \"2:09:59\"\n      thumbnail_cue: \"1:40:29\"\n      speakers:\n        - Todd Kummer\n\n- id: \"sf-bay-area-ruby-meetup-february-2026\"\n  title: \"SF Bay Area Ruby Meetup - February 2026\"\n  event_name: \"SF Bay Area Ruby Meetup - February 2026\"\n  date: \"2026-02-25\"\n  description: |-\n    Hey, Bay Area builders and tinkerers!\n\n    In February Sentry is hosting the SF Ruby meetup.\n\n    Whether you're weaving magic with Ruby or Rails in your day job, crafting the next big thing in your garage, or simply intrigued by the promise of productivity and sheer joy Ruby and Rails could sprinkle on your 2026 projects, this is where you want to be.\n\n    Learn from the talks, share opinions and make new friends!\n\n    Agenda: TBC\n\n    Brought to you by Evil Martians.\n\n    https://lu.ma/3mf4bhdl\n\n  video_provider: \"scheduled\"\n  video_id: \"sf-bay-area-ruby-meetup-february-2026\"\n  talks: []\n\n- id: \"sf-bay-area-ruby-meetup-april-2026\"\n  title: \"SF Bay Area Ruby Meetup - April 2026\"\n  event_name: \"SF Bay Area Ruby Meetup - April 2026\"\n  date: \"2026-04-16\"\n  description: |-\n    Hey, Bay Area builders and tinkerers!\n\n    In April New Relic is hosting the SF Ruby meetup.\n\n    Whether you're weaving magic with Ruby or Rails in your day job, crafting the next big thing in your garage, or simply intrigued by the promise of productivity and sheer joy Ruby and Rails could sprinkle on your 2026 projects, this is where you want to be.\n\n    Learn from the talks, share opinions and make new friends!\n\n    Agenda: TBC\n\n    Brought to you by Evil Martians.\n\n    https://lu.ma/ij3343mc\n\n  video_provider: \"scheduled\"\n  video_id: \"sf-bay-area-ruby-meetup-april-2026\"\n  talks: []\n"
  },
  {
    "path": "data/sfruby/series.yml",
    "content": "---\nname: \"San Francisco Ruby Conference\"\nwebsite: \"https://lu.ma/sfruby\"\ntwitter: \"sfruby\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"San Francisco Ruby Conference\"\ndefault_country_code: \"US\"\nyoutube_channel_name: \"evil.martians\"\nyoutube_channel_id: \"UCQFMqO1jX_2O4CckfQgRHjg\"\nlanguage: \"english\"\naliases:\n  - SF Ruby Conf\n  - SF Ruby Conference\n  - SF RubyConf\n  - SFRuby\n"
  },
  {
    "path": "data/sfruby/sfruby-2025/cfp.yml",
    "content": "---\n- link: \"https://cfp.sfruby.com/\"\n  close_date: \"2025-07-13\"\n"
  },
  {
    "path": "data/sfruby/sfruby-2025/event.yml",
    "content": "---\nid: \"sfruby-2025\"\n# id: PLAgBW0XUpyOUOs3E0QnDrJRIqCJCueq5F # Main Stage Playlist ID\n# id: PLAgBW0XUpyOUg-uWfRM71wHVCp4J8UNYV # Black Box Theater Playlist ID\n# id: PLAgBW0XUpyOXnC3Y37y-MMTUHLIwudnhd # Workshops Playlist ID\ntitle: \"San Francisco Ruby Conference 2025\"\nlocation: \"San Francisco, CA, United States\"\ndescription: \"\"\nstart_date: \"2025-11-19\"\nend_date: \"2025-11-20\"\nchannel_id: \"UCQFMqO1jX_2O4CckfQgRHjg\"\nplaylist: \"https://www.youtube.com/watch?list=PLAgBW0XUpyOUOs3E0QnDrJRIqCJCueq5F\"\npublished_at: \"2025-12-26\"\nkind: \"conference\"\nfrequency: \"yearly\"\nyear: 2025\nbanner_background: \"linear-gradient(oklch(0.65 0.17 250), oklch(0.45 0.17 250), oklch(0.45 0.17 250));\"\nfeatured_background: \"#0054AE\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://sfruby.com\"\ncoordinates:\n  latitude: 37.80826\n  longitude: -122.43136\n"
  },
  {
    "path": "data/sfruby/sfruby-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Irina Nazarova\n\n  organisations:\n    - Evil Martians\n\n- name: \"Program Committee Member\"\n  users:\n    - Maple Ong\n    - Cameron Dutro\n    - Noel Rappin\n    - Vladimir Dementyev\n\n- name: \"Speaker Support Coordinator\"\n  users:\n    - Aurelie Verrot\n\n- name: \"Speaker Preparation & Vendor Coordinator\"\n  users:\n    - Amanda Kinney\n\n- name: \"AV & Vendor Coordinator\"\n  users:\n    - Aleksandr Berdyugin\n    - Anton Senkovskiy\n\n- name: \"Logo and Identity Designer\"\n  users:\n    - Yaroslav Lozhkin\n\n- name: \"Designer\"\n  users:\n    - Anton Lovchikov\n\n- name: \"Student Program Coordinator\"\n  users:\n    - Gary Tou\n\n- name: \"Marketing Coordinator\"\n  users:\n    - Rhiannon Payne\n    - Victoria Melnikova\n\n- name: \"Volunteer Coordinator\"\n  users:\n    - Steven Ancheta\n\n- name: \"Volunteer\"\n  users:\n    - Daniel Azuma\n    - Todd Kummer\n    - Ken Decanio\n    - Dave Doolin\n    - Varun Sanjay Shembekar\n    - Madeline Hou\n    - Joshue Osuna\n    - Dominic Lizarraga\n    - Alan Fung-Schwarz\n    - Yang Chung\n    - Andrew Ford\n    - Jon Kaplan\n    - Mark Valdez\n    - Mark de Dios\n    - Megan Wong\n    - Hector Miramontes\n    - Kenneth Ng\n    - Miles Georgi\n    - Zack Mariscal\n    - Nathan Straub\n    - Alexander Baygeldin\n    - Albert Pazderin\n    - Gennady Shenker\n    - Emmanuel Delgado\n\n- name: \"Conference Software Developer\"\n  users:\n    - Vladimir Dementyev\n\n- name: \"MC\"\n  users:\n    - Brittany Springer\n    - Cameron Dutro\n"
  },
  {
    "path": "data/sfruby/sfruby-2025/schedule.yml",
    "content": "# Schedule: https://sfruby.com/schedule\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2025-11-19\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"08:50\"\n        slots: 1\n        items:\n          - Doors Open & Registration\n\n      - start_time: \"08:50\"\n        end_time: \"09:00\"\n        slots: 1\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n\n      - start_time: \"09:40\"\n        end_time: \"10:10\"\n        slots: 2\n\n      - start_time: \"9:40\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"10:20\"\n        end_time: \"10:50\"\n        slots: 2\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 2\n\n      - start_time: \"11:40\"\n        end_time: \"1:10\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"1:20\"\n        end_time: \"1:50\"\n        slots: 2\n\n      - start_time: \"1:20\"\n        end_time: \"3:10\"\n        slots: 1\n\n      - start_time: \"2:00\"\n        end_time: \"2:30\"\n        slots: 2\n\n      - start_time: \"2:40\"\n        end_time: \"3:10\"\n        slots: 2\n\n      - start_time: \"3:20\"\n        end_time: \"3:50\"\n        slots: 2\n\n      - start_time: \"4:00\"\n        end_time: \"4:50\"\n        slots: 1\n\n      - start_time: \"5:00\"\n        end_time: \"5:30\"\n        slots: 1\n\n      - start_time: \"5:30\"\n        end_time: \"8:30\"\n        slots: 1\n        items:\n          - title: \"🎉 GitButler Afterparty 🍻\"\n            description: |-\n              Join us at San Francisco Brewing Co. (3150 Polk St, San Francisco, CA 94109) for an evening of food, drinks, and great conversations with fellow Rubyists! Sponsored by our Ruby friends from GitButler!\n\n  - name: \"Day 2\"\n    date: \"2025-11-20\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"08:50\"\n        slots: 1\n        items:\n          - Doors Open & Coffee\n\n      - start_time: \"09:00\"\n        end_time: \"09:30\"\n        slots: 1\n\n      - start_time: \"09:40\"\n        end_time: \"10:10\"\n        slots: 2\n\n      - start_time: \"9:40\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"10:20\"\n        end_time: \"10:50\"\n        slots: 2\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 2\n\n      - start_time: \"11:40\"\n        end_time: \"1:10\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"1:20\"\n        end_time: \"1:50\"\n        slots: 2\n\n      - start_time: \"1:20\"\n        end_time: \"3:10\"\n        slots: 1\n\n      - start_time: \"1:30\"\n        end_time: \"1:50\"\n        slots: 1\n        items:\n          - title: \"Open Mic\"\n            description: |-\n              Our tradition at SF Ruby is a session where anyone can grab a mic for a couple minutes to share their announcements, news, or ask a question.\n\n      - start_time: \"2:00\"\n        end_time: \"2:30\"\n        slots: 1\n\n      - start_time: \"2:00\"\n        end_time: \"2:30\"\n        slots: 1\n        items:\n          - title: \"Open Mic 2\"\n            description: |-\n              Our tradition at SF Ruby is a session where anyone can grab a mic for a couple minutes to share their announcements, news, or ask a question.\n\n      - start_time: \"2:40\"\n        end_time: \"3:30\"\n        slots: 2\n\n      - start_time: \"3:40\"\n        end_time: \"4:30\"\n        slots: 2\n\n      - start_time: \"4:40\"\n        end_time: \"5:30\"\n        slots: 1\n\n      - start_time: \"5:30\"\n        end_time: \"5:40\"\n        slots: 1\n\ntracks:\n  - name: \"Main Stage\"\n    color: \"#ffe3df\"\n    text_color: \"#a9000a\"\n\n  - name: \"Blackbox Theater\"\n    color: \"#d8f2ff\"\n    text_color: \"#0055ab\"\n\n  - name: \"Workshop Studio\"\n    color: \"#d1fae5\"\n    text_color: \"#065f46\"\n"
  },
  {
    "path": "data/sfruby/sfruby-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Pickaxe Sponsors\"\n      description: |-\n        Premier sponsorship with maximum visibility and branding.\n      level: 1\n      sponsors:\n        - name: \"Chime\"\n          website: \"https://www.chime.com\"\n          slug: \"chime\"\n          logo_url: \"https://sfruby.com/sponsor_chime.png\"\n\n        - name: \"Bolt.new\"\n          website: \"https://www.bolt.new\"\n          slug: \"bolt-new\"\n          logo_url: \"https://sfruby.com/sponsor_boltnew.png\"\n\n        - name: \"Cisco\"\n          website: \"https://www.cisco.com\"\n          slug: \"cisco\"\n          logo_url: \"https://sfruby.com/sponsor_cisco.png\"\n\n    - name: \"Ruby Sponsors\"\n      description: |-\n        High-visibility sponsorship with excellent branding opportunities.\n      level: 2\n      sponsors:\n        - name: \"Gusto\"\n          website: \"https://www.gusto.com\"\n          slug: \"gusto\"\n          logo_url: \"https://sfruby.com/sponsor_gusto.png\"\n\n        - name: \"Temporal\"\n          website: \"https://temporal.io/\"\n          slug: \"temporal\"\n          logo_url: \"https://sfruby.com/sponsor_temporal.png\"\n\n        - name: \"Intercom\"\n          website: \"https://intercom.com/\"\n          slug: \"intercom\"\n          logo_url: \"https://sfruby.com/sponsor_intercom.png\"\n\n        - name: \"Omada Health\"\n          website: \"https://omadahealth.com/\"\n          slug: \"omada-health\"\n          logo_url: \"https://sfruby.com/sponsor_omada.png\"\n\n        - name: \"Avo\"\n          website: \"https://avohq.io/\"\n          slug: \"avo\"\n          logo_url: \"https://sfruby.com/sponsor_avo.png\"\n\n        - name: \"Thatch\"\n          website: \"https://thatch.com/\"\n          slug: \"thatch\"\n          logo_url: \"https://sfruby.com/sponsor_thatch.png\"\n\n        - name: \"Finta\"\n          website: \"https://finta.com/\"\n          slug: \"finta\"\n          logo_url: \"https://sfruby.com/sponsor_finta.png\"\n\n        - name: \"AngelList\"\n          website: \"https://angellist.com\"\n          slug: \"angellist\"\n          logo_url: \"https://sfruby.com/sponsor_angellist.png\"\n\n        - name: \"PlanetScale\"\n          website: \"https://planetscale.com/\"\n          slug: \"planetscale\"\n          logo_url: \"https://sfruby.com/sponsor_planetscale.png\"\n\n    - name: \"Emerald Sponsors\"\n      description: |-\n        Strong presence with quality branding and networking.\n      level: 3\n      sponsors:\n        - name: \"Scout Monitoring\"\n          website: \"https://scoutapm.com/\"\n          slug: \"scoutmonitoring\"\n          logo_url: \"https://sfruby.com/sponsor_scout.png\"\n\n        - name: \"Typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"typesense\"\n          logo_url: \"https://sfruby.com/sponsor_typesense.png\"\n\n        - name: \"Cedarcode\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"cedarcode\"\n          logo_url: \"https://sfruby.com/sponsor_cedarcode.png\"\n\n        - name: \"Planet Argon\"\n          website: \"https://www.planetargon.com/\"\n          slug: \"planetargon\"\n          logo_url: \"https://sfruby.com/sponsor_planetargon.png\"\n\n        - name: \"Cactus\"\n          website: \"https://oncactus.com\"\n          slug: \"cactus\"\n          logo_url: \"https://sfruby.com/sponsor_cactus.png\"\n\n        - name: \"visuality\"\n          website: \"https://visuality.pl\"\n          slug: \"visuality\"\n          logo_url: \"https://sfruby.com/sponsor_visuality.png\"\n\n        - name: \"ubicloud\"\n          website: \"https://ubicloud.com\"\n          slug: \"ubicloud\"\n          logo_url: \"https://sfruby.com/sponsor_ubicloud.png\"\n\n        - name: \"Uscreen\"\n          website: \"https://www.uscreen.tv\"\n          slug: \"uscreen\"\n          logo_url: \"https://sfruby.com/sponsor_uscreen.png\"\n\n    - name: \"Reception Sponsor\"\n      description: |-\n        Exclusive sponsorship of the evening reception.\n      level: 5\n      sponsors:\n        - name: \"GitButler\"\n          website: \"https://gitbutler.com\"\n          slug: \"gitbutler\"\n          logo_url: \"https://sfruby.com/sponsor_gitbutler.png\"\n\n    - name: \"Post Production Sponsor\"\n      description: |-\n        Sponsoring the editing and post-production of conference videos.\n      level: 5\n      sponsors:\n        - name: \"Mux\"\n          website: \"https://mux.com\"\n          slug: \"mux\"\n\n    - name: \"Travel Sponsors\"\n      description: |-\n        Supporting speakers' travel to the conference.\n      level: 6\n      sponsors:\n        - name: \"tidewave.ai\"\n          website: \"https://tidewave.ai\"\n          slug: \"tidewave\"\n          logo_url: \"https://sfruby.com/sponsor_tidewave.png\"\n\n        - name: \"Hack Club\"\n          website: \"https://hackclub.com/\"\n          slug: \"hackclub\"\n          logo_url: \"https://sfruby.com/sponsor_hackclub.png\"\n\n        - name: \"ezCater\"\n          website: \"https://www.ezcater.com\"\n          slug: \"ezcater\"\n          logo_url: \"https://sfruby.com/sponsor_ezcater.png\"\n"
  },
  {
    "path": "data/sfruby/sfruby-2025/venue.yml",
    "content": "---\nname: \"Fort Mason Center - Gateway Pavilion - Pier 2\"\n\naddress:\n  street: \"2 Marina Blvd\"\n  city: \"San Francisco\"\n  region: \"CA\"\n  postal_code: \"94123\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"2 Marina Blvd, San Francisco, CA 94123, United States\"\n\ncoordinates:\n  latitude: 37.80826\n  longitude: -122.43136\n\nmaps:\n  apple: \"https://maps.apple.com/place?address=2%20Marina%20Blvd,%20San%20Francisco,%20CA%2094123,%20United%20States&coordinate=37.80826,-122.43136&name=Fort%20Mason%20Center\"\n  google: \"https://maps.app.goo.gl/To5gKLyG6eoV4FsX8\"\n\nlocations:\n  - name: \"San Francisco Brewing Co.\"\n    kind: \"Afterparty Location\"\n    description: |-\n      The official San Francisco Ruby Conference Afterparty is hosted by our Ruby friends at GitButler!\n      Please note that the party is only for SF Ruby Conference ticket holders. Badges will be required for entrance.\n      Food and drinks are provided!\n\n      https://luma.com/881j9e2l\n    address:\n      street: \"3150 Polk Street\"\n      city: \"San Francisco\"\n      region: \"California\"\n      postal_code: \"94109\"\n      country: \"United States\"\n      country_code: \"US\"\n      display: \"3150 Polk St, San Francisco, CA 94109, United States\"\n    coordinates:\n      latitude: 37.8055723\n      longitude: -122.4235068\n    maps:\n      google: \"https://maps.app.goo.gl/af96GyBBAbBKvoR89\"\n      apple:\n        \"https://maps.apple.com/place?address=3150%20Polk%20St,%20San%20Francisco,%20CA%20%2094109,%20United%20States&coordinate=37.805478,-122.423519&name=San%20Francisco%20Brewin\\\n        g%20Co.&place-id=I75944C8C0365D0FC&map=transit\"\n"
  },
  {
    "path": "data/sfruby/sfruby-2025/videos.yml",
    "content": "---\n## Day 1\n\n- id: \"opening-words-sfruby-2025\"\n  title: \"Opening Words\"\n  raw_title: \"Opening words: Irina Nazarova, Brittany Martin Springer. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Irina Nazarova\n    - Brittany Springer\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Irina opens the conference by sharing the idea behind it and recognizing those involved in organizing it. She then introduces the main stage MC, Brittany Martin Springer, a beloved member of the community known for her years of hosting the Ruby on Rails podcast.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"Nhe8FXbN0p0\"\n\n- id: \"marco-roth-sfruby-2025\"\n  title: \"Keynote: Herb to ReActionView: A New Foundation for the View Layer\"\n  raw_title: \"Opening Keynote: Marco Roth, Herb to ReActionView. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Marco Roth\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2025-12-26\"\n  description: |-\n    At RubyKaigi, Marco introduced Herb, a new HTML-aware ERB parser and tooling ecosystem. At RailsConf, he released developer tools built on Herb, which included a formatter, linter, and language server. There, he also shared a vision for modernizing the Rails view layer. This talk concludes his 2025 journey on the topic.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"L7WpwtqHn_g\"\n  slides_url: \"https://speakerdeck.com/marcoroth/herb-to-reactionview-a-new-foundation-for-the-view-layer\"\n\n- id: \"rachael-wright-munn-sfruby-2025\"\n  title: \"Play with your code\"\n  raw_title: \"Rachael Wright Munn, Play with your code. San Francisco Ruby Conference 2025\"\n  speakers:\n    - Rachael Wright-Munn\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Why are programming games more fun than our day jobs? Rachael digs into this exact question and shares the lessons we can learn from those games, and how to bring them back into the developer experience. Spoiler: This talk mentions some rad programming games you should play!\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"ltYep_SOjNg\"\n  slides_url: \"https://docs.google.com/presentation/d/1MDyBkQ_Ifa2CJ8DxY_e56TpHqPcwUhKOgM_sInFXIG8\"\n\n- id: \"fito-von-zastrow-alan-ridlehoover-sfruby-2025\"\n  title: \"Derailing Our Application: How and Why We Are Decoupling Our Code from Rails\"\n  raw_title: \"Derailing Our Application: How and Why We Are Decoupling Our Code from Rails\"\n  speakers:\n    - Fito von Zastrow\n    - Alan Ridlehoover\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2026-01-09\"\n  description: |-\n    Successful Rails apps tend to become massive monoliths over time. Our's is no exception. Our team is over 1000 engineers. Our codebase is over 4 million lines of Ruby.\n\n    But, Rails doesn't tell you how to manage that many developers working on that large a codebase. So, we're encouraging modularization and boundaries within our codebase. Our approach is lightweight and actually producing results.\n\n    We're the right ones to talk about this because we're the one's issuing the guidance internally.\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"-H1GZjECTsU\"\n\n- id: \"justin-bowen-sfruby-2025\"\n  title: \"Building Agents with Rails\"\n  raw_title: \"Justin Bowen: Building agents with Rails - Workshop. San Francisco Ruby Conference 2025\"\n  speakers:\n    - Justin Bowen\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2026-01-21\"\n  description: |-\n    Hands-on workshop for building AI agents using Rails framework and modern AI tools.\n  track: \"Workshop Studio\"\n  video_provider: \"youtube\"\n  video_id: \"f20j7Cmq7JI\"\n\n- id: \"jp-camara-sfruby-2025\"\n  title: \"Real-time collaboration with Rails, AnyCable and Yjs\"\n  raw_title: \"JP Camara, Real-time collaboration with Rails, AnyCable and Yjs. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - JP Camara\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Real-time collaboration is a powerful tool for web apps, but difficult to implement. Most Ruby developers lack CRDT exposure and collaborative software challenges like conflict resolution and distributed consistency. In this talk, JP shows how to leverage Rails while adding sophisticated collaborative features using AnyCable to boost ActionCable performance and Yjs to simplify collaborative editing.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"J68QOBLEItY\"\n\n- id: \"brandon-weaver-sfruby-2025\"\n  title: \"Rails Expertise, Distilled: AI Agents That Get Your Monolith\"\n  raw_title: \"Rails Expertise, Distilled: AI Agents That Get Your Monolith\"\n  speakers:\n    - Brandon Weaver\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2026-01-09\"\n  description: |-\n    New developers face months of unproductive confusion when dropped into massive codebases they can't navigate or understand. What if they could get instant answers about how systems work, identify what code needs changing, and understand complex business logic without waiting for help? This talk demonstrates how Rails' built-in introspection transforms into expert AI tools that understand your specific codebase, making institutional knowledge accessible 24/7. Instead of 3-month ramp-ups, developers contribute meaningfully in days while the entire team stays productive.\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"-x9Ir3FakDY\"\n\n- id: \"adrian-marin-sfruby-2025\"\n  title: \"Master the Rails Asset Pipeline: Best Practices for Apps & Gems\"\n  raw_title: \"Adrian Marin, Master the Rails asset pipeline. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Adrian Marin\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Adrian shares his learnings and a plugin system for asset handling. This talk is based on his experience shipping his gem, Avo, which is used by hundreds of applications with varying asset pipeline configurations, as well as over four years of building applications, from the pre-Webpacker era all the way to importmaps, esbuild, and Vite.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"AFpbFXPBs3w\"\n\n- id: \"ben-sheldon-sfruby-2025\"\n  title: \"Performance starts at boot\"\n  raw_title: \"Performance starts at boot\"\n  speakers:\n    - Ben Sheldon\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2026-01-09\"\n  description: |-\n    Everyone can better understand how their Ruby code performs, regardless of whether they're using Rails or Hanami or just scripting with Ruby. As applications grow, I frequently see inside-out application performance work ignored or unacceptably tolerated (\"that's just the way it is [sigh]\").\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"FIipSavS5qo\"\n  slides_url: \"https://speakerdeck.com/bensheldon/performance-starts-at-boot\"\n\n- id: \"takashi-kokubun-sfruby-2025\"\n  title: \"ZJIT: The Future of Ruby Performance\"\n  raw_title: \"Takashi Kokubun, ZJIT: The future of Ruby performance. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Takashi Kokubun\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Since Rails 7.2 enabled YJIT by default, it has been widely adopted by the Ruby community, delivering a 10-20% speedup in various production workloads. To enhance Ruby's speed further, the Ruby and Rails Infrastructure (R&RI) team at Shopify is developing ZJIT, the next generation of YJIT for Ruby 3.5. In this talk, Takashi dives into ZJIT and how it'll improve Ruby performance.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"XSdBCKepWHM\"\n  slides_url: \"https://speakerdeck.com/k0kubun/san-francisco-ruby-conference-2025\"\n\n- id: \"tia-anderson-sfruby-2025\"\n  title: \"Peace, Love, and CRUD: Finding Calm in the Chaos—With Ruby, AI, and a Little Garden Magic\"\n  raw_title: \"Peace, Love, and CRUD: Finding Calm in the Chaos—With Ruby, AI, and a Little Garden Magic\"\n  speakers:\n    - Tia Anderson\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2026-01-09\"\n  description: |-\n    This talk matters because we are enduring death by a thousand quiet cuts. The world asks us to go faster while our spirits beg us to slow down. Emotional exhaustion has become the norm, but it doesn't have to be. I built Peace of Mind not just with Rails, but with urgency and heart. As a newer dev and RailsConf Scholar, I've lived the tension between burnout and beauty. Choosing peace...in our work, our lives, and our code creates ripples. It starts with one. One you. One me.\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"Cq4sWAf-d5U\"\n\n- id: \"inertia-rails-workshop-sfruby-2025\"\n  title: \"Inertia Rails Workshop\"\n  raw_title: \"Brandon Shar, Svyatoslav Kryukov, and Brian Knoles: Inertia Rails workshop. SF Ruby Conference 2025\"\n  speakers:\n    - Brandon Shar\n    - Brian Knoles\n    - Svyatoslav Kryukov\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2026-01-21\"\n  description: |-\n    Inertia.js solves a huge pain point for server side MVC frameworks: clean integration with rich client-side libraries like React, Vue, and Svelte. Inertia Rails allows both sides of this equation to shine. The Rails code looks almost exactly like vanilla Rails code (without the view layer), which keeps existing Rails teams productive. On the client, Inertia Rails takes away a lot of the headaches in gluing React and Rails together: session based auth, server side global state management, and Inertia form submissions make life much easier on teams.\n  track: \"Workshop Studio\"\n  video_provider: \"youtube\"\n  video_id: \"XBZcLD5xcPY\"\n\n- id: \"jose-valim-sfruby-2025\"\n  title: \"Programming language evolution in the AI era\"\n  raw_title: \"José Valim, Programming language evolution in the AI era. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - José Valim\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2025-12-26\"\n  description: |-\n    José Valim, author of the Elixir language, former core Rails team member, and now founder of Tidewave.ai, shares his pragmatic take on the role of AI in software development. In this talk, he explains how web frameworks and developer tools need to evolve to meet the expectations and demands of tomorrow.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"ydkP8yB9ozg\"\n\n- id: \"pawel-strzalkowski-sfruby-2025\"\n  title: \"AI Interface in 5 Minutes - Model Context Protocol on Rails\"\n  raw_title: \"AI Interface in 5 Minutes - Model Context Protocol on Rails\"\n  speakers:\n    - Paweł Strzałkowski\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2026-01-09\"\n  description: |-\n    This talk delivers a low-risk, high-value AI strategy that applies to any Rails app, new or old. It proves the ecosystem's power to modernize existing assets in the AI era without the need for expensive rewrites. It teaches one of the key aspects of the modern AI tech stack, giving a competitive advantage.\n\n    I'm a CTO, a veteran Rails developer and a vetted conference speaker. My expertise on a similar topic is validated by my upcoming talks at Rails World and EuRuKo this year. I'm excited to bring this timely material to the US community\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"9Ij63xgLHE4\"\n\n- id: \"dave-thomas-sfruby-2025\"\n  title: \"Start Writing Ruby (Stop Using Classes)\"\n  raw_title: \"Dave Thomas, Start writing Ruby (stop using classes). San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Dave Thomas\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2025-12-26\"\n  description: |-\n    David Thomas is a legend of the Ruby community and the Agile software development movement, an author of numerous books on Ruby and Rails, and the founder of the Pragmatic Bookshelf. In this talk, he argues that we are writing Ruby code the wrong way. We use classes as the unit of design when we don't need them and shouldn't rely on them. We also treat design patterns as recipes, which makes them largely irrelevant. Finally, we create arcane project structures and convoluted deployment systems that we simply do not need.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"sjuCiIdMe_4\"\n\n- id: \"enrique-carlos-mogollan-sfruby-2025\"\n  title: \"The MCP Fog Made Me Do It: A Ruby Inspector's Unexpected Journey\"\n  raw_title: \"The MCP Fog Made Me Do It: A Ruby Inspector's Unexpected Journey\"\n  speakers:\n    - Enrique Mogollán\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2026-01-09\"\n  description: |-\n    MCP is still pretty foggy for most developers, and Ruby shouldn't be left out of the AI tooling party. This story shows how a simple \"let me figure this out\" project can accidentally become something fun and interesting to share. I've been learning about MCP, from the official ruby SDK, and stumbled onto this idea of self-generating UI interfaces. If you've ever stared a new project and wondered \"how do I even start?\", this talk is one example from foggy confusion to sunshine moment of \"holy smokes, I didn't know that was possible.\" Besides, Ruby deserves a seat at the AI table.\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"3u72MBYDRFA\"\n\n- id: \"stephan-hagemann-sf-ruby-2025\"\n  title: \"Pack It Up: Why Packwerk Can't Save Your Messy Rails App (But You Can)\"\n  raw_title: \"Stephan Hagemann, Pack it up. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Stephan Hagemann\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Packwerk promised modularity in a gem install, but good architecture does not come from 'bundle add.' Stephan from Gusto shares Packwerk's story and the deeper truths it reveals about software design, organizational habits, and how we sometimes ask our tools to do our growing for us. This is a call to arms, and a reminder of our love of the craft, for teams that want to scale Rails applications by scaling their understanding first.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"py_vjWTmAwg\"\n\n- id: \"evgeny-li-sfruby-2025\"\n  title: \"Building Cloud Data Infrastructure with Ruby\"\n  raw_title: \"Building Cloud Data Infrastructure with Ruby\"\n  speakers:\n    - Evgeny Li\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2026-01-09\"\n  description: |-\n    Ruby isn't just for web development. Discover why Ruby is a great choice for building and automating modern cloud data infrastructure. Learn real-world lessons from BemiDB, a data analytics platform. You'll gain practical skills and be inspired to leverage Ruby for your next infrastructure project!\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"tE_gTgnoLw8\"\n  slides_url: \"https://speakerdeck.com/exaspark/building-cloud-data-infrastructure-with-ruby-at-sf-ruby-2025-3d33b52c-d041-4225-b271-e719a0ddc12e\"\n\n- id: \"startup-demos-sfruby-2025-session-1\"\n  title: \"Startup Demos (Session 1)\"\n  raw_title: \"Startup Demos (Session 1)\"\n  event_name: \"SF Ruby 2025\"\n  description: |-\n    Live demonstrations from innovative startups building with Ruby and Rails.\n  date: \"2025-11-19\"\n  track: \"Main Stage\"\n  kind: \"demo\"\n  video_provider: \"children\"\n  video_id: \"startup-demos-sfruby-2025-session-1\"\n  talks:\n    - id: \"recognize-demo-sf-ruby-2025\"\n      title: \"Startup Demo: Recognize\"\n      raw_title: \"Ruby startup demo: Peter Philips, Recognize. San Francisco Ruby Conference 2025.\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://recognizeapp.com/\n        High-impact, affordable, and easy to launch employee recognition and rewards program. Even for frontline teams across multiple locations.\n      video_provider: \"youtube\"\n      video_id: \"Ou7CGuQUy6Q\"\n      speakers:\n        - \"Peter Philips\"\n\n    - id: \"stepful-demo-sf-ruby-2025\"\n      title: \"Startup Demo: Stepful\"\n      raw_title: \"Ruby startup demo: Wyatt Ades, Stepful. San Francisco Ruby Conference 2025.\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://www.stepful.com/\n        A four-month, tech-driven online healthcare training program for entry-level roles, accessible to candidates with a high school diploma.\n      video_provider: \"youtube\"\n      video_id: \"GoFbMl3TBmw\"\n      speakers:\n        - \"Wyatt Ades\"\n\n    - id: \"thatch-demo-sf-ruby-2025\"\n      title: \"Startup Demo: Thatch\"\n      raw_title: \"Ruby startup demo: Bart de Water, Thatch. San Francisco Ruby Conference 2025.\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://thatch.com/\n        Thatch makes it easy to give your team great healthcare. You set a budget, and your employees spend it the way that works best for them.\n      video_provider: \"youtube\"\n      video_id: \"7M4dzK9wY7I\"\n      speakers:\n        - \"Bart de Water\"\n\n    - id: \"angellist-demo-sf-ruby-2025\"\n      title: \"Startup Demo: AngelList\"\n      raw_title: \"Ruby startup demo: Chamod Gamage, AngelList. San Francisco Ruby Conference 2025.\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://www.angellist.com/\n        AngelList builds software investors use to fund world-changing startups.\n      video_provider: \"youtube\"\n      video_id: \"931PpANN8bs\"\n      speakers:\n        - \"Chamod Gamage\"\n\n    - id: \"planetscale-demo-sf-ruby-2025\"\n      title: \"Startup Demo: PlanetScale\"\n      raw_title: \"Ruby startup demo: Sam Lambert, PlanetScale. San Francisco Ruby Conference 2025.\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://planetscale.com/\n        PlanetScale is the database platform for developers. It provides MySQL-compatible serverless database with built-in scaling, branching, and non-blocking schema changes.\n      video_provider: \"youtube\"\n      video_id: \"WxdB4sg2eIM\"\n      speakers:\n        - \"Sam Lambert\"\n\n- id: \"carmine-paolino-sfruby-2025\"\n  title: \"Keynote: RubyLLM\"\n  raw_title: \"Keynote: Carmine Paolino, RubyLLM. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Carmine Paolino\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-19\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Carmine believes the merchants of complexity have sold the AI world a lie. They claim you need their frameworks, SDKs, and enterprise architectures. He argues that today's AI is mostly API calls, and when the challenge shifts from training models to building products, complexity becomes a liability and simplicity becomes everything. Rails proved that lesson before.\n\n    Meet Carmine Paolino and learn about the design decisions behind one of the most popular new Ruby open-source projects: RubyLLM.\n\n    \"One API for every model, every vendor. One developer on one machine serving thousands. While Python developers debug their 14-line 'Hello World,' we're shipping. Ruby's time in AI isn't coming. It's here.\"\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"y535u1EWqAg\"\n\n## Day 2\n\n- id: \"obie-fernandez-sfruby-2025\"\n  title: \"Keynote: Ruby & AI conversation\"\n  raw_title: \"Ruby & AI conversation\"\n  speakers:\n    - Obie Fernandez\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  description: |-\n    A conversation about the intersection of Ruby and AI technologies, exploring opportunities and challenges.\n  track: \"Main Stage\"\n  video_provider: \"not_recorded\"\n  video_id: \"obie-fernandez-sfruby-2025\"\n  thumbnail_xs: \"https://miro.medium.com/v2/resize:fit:320/format:webp/0*MudvRlo9a_KAGA1c\"\n  thumbnail_sm: \"https://miro.medium.com/v2/resize:fit:512/format:webp/0*MudvRlo9a_KAGA1c\"\n  thumbnail_md: \"https://miro.medium.com/v2/resize:fit:1024/format:webp/0*MudvRlo9a_KAGA1c\"\n  thumbnail_lg: \"https://miro.medium.com/v2/resize:fit:2048/format:webp/0*MudvRlo9a_KAGA1c\"\n  thumbnail_xl: \"https://miro.medium.com/v2/resize:fit:4096/format:webp/0*MudvRlo9a_KAGA1c\"\n  additional_resources:\n    - name: \"Ruby Was Ready From The Start\"\n      url: \"https://obie.medium.com/ruby-was-ready-from-the-start-4b089b17babb\"\n      type: \"blog\"\n\n- id: \"colleen-schnettler-sfruby-2025\"\n  title: \"From code to customers: technical marketing for people who'd rather be building\"\n  raw_title: \"Colleen Schnettler, From code to customers. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Colleen Schnettler\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Too many brilliant Rails developers build great products and then quit when customers don't appear. They're missing one skill: marketing.\n\n    Colleen wants to change that.\n\n    \"The Rails renaissance is here, and I believe helping Rails builders become successful entrepreneurs is crucial for our community's future,\" she adds.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"xP86mvtqEh0\"\n\n- id: \"andre-arko-sfruby-2025\"\n  title: \"Operating rails: what about after you deploy?\"\n  raw_title: \"Operating rails: what about after you deploy?\"\n  speakers:\n    - André Arko\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2026-01-09\"\n  description: |-\n    Running a web service requires you to do so many things that aren't included in any programming books or tutorials. We need more developers able to ship services that work, rather than expecting each developer to figure out the entire list by trial and error, one at a time, by themselves. Blog posts with individual tips about isolated problems don't cut it either, because no one is creating a field survey or a checklist of the overall process and making sure developers are aware of and ready for what they'll face in production.\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"2h2XEyOM6lg\"\n  slides_url: \"https://speakerdeck.com/indirect/operating-rails-what-about-after-you-deploy-1c7b6a98-c411-46e7-87fb-1b74a6398f9d\"\n\n- id: \"kasper-timm-hansen-sfruby-2025\"\n  title: \"Upskill Your Team by Diving into Rails itself & other Gems\"\n  raw_title: \"Kasper Timm Hansen: Workshop - Upskill your team by diving into Rails. SF Ruby Conference 2025\"\n  speakers:\n    - Kasper Timm Hansen\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2026-01-21\"\n  description: |-\n    There's a ton of untapped potential in Rails and other gem source for upskilling that teams aren't leveraging because they don't know how. And there's almost no content showing how.\n\n    This problem hurts Ruby open source, because teams don't know how to contribute or make gems (exposure to real open source code is the first step IMO).\n\n    I've given several Rails source deep-dive workshops over Zoom that 70+ people have attended. I've shown a live-demo of this on stage at RailsConf that attendees raved about.\n  track: \"Workshop Studio\"\n  video_provider: \"youtube\"\n  video_id: \"N5VpMNgbrsg\"\n\n- id: \"jeremy-evans-sfruby-2025\"\n  title: \"The Thin CLIent Approach\"\n  raw_title: \"Jeremy Evans, The thin CLIent approach. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Jeremy Evans\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2025-12-26\"\n  description: |-\n    In this presentation, Jeremy Evans, author of Roda and Sequel, the book Polished Ruby Programming, and Principal Engineer at Ubicloud, shares a new approach to CLI development. Instead of parsing command-line arguments in the client, arguments are sent to an endpoint. He discusses the pros and cons of this approach, the development of a new argument-parsing library, cross-compiling CLI programs, and how this design enables using a CLI without installation by integrating it into a web application.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"JmmtO8vChyA\"\n  slides_url: \"https://code.jeremyevans.net/presentations/sfruby2025/index.html\"\n\n- id: \"albert-pai-sf-ruby-2025\"\n  title: \"Fireside chat with the co-founder and CTO of bolt.new Albert Pai\"\n  raw_title: \"Fireside chat with the co-founder and CTO of bolt.new Albert Pai\"\n  event_name: \"SF Ruby 2025\"\n  speakers:\n    - Albert Pai\n    - Irina Nazarova\n  date: \"2025-11-20\"\n  published_at: \"2026-01-09\"\n  description: |-\n    Irina Nazarova sits down with Albert Pai, Co-founder and CTO of Bolt.new, to talk about building one of the fastest-growing startups in code generation—what worked, what didn't, and how Ruby and Rails shaped the path.\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"pzA1Q8sBwcA\"\n\n- id: \"sarah-mei-sfruby-2025\"\n  title: \"The Role of Software Design in an AI World\"\n  raw_title: \"Sarah Mei, The role of software design in an AI world. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Sarah Mei\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Ruby developers, like all developers, are nervous about their worth in an AI-first world. This talk offers reason for optimism by sharing a perspective on using AI to enhance roles rather than replace them.\n\n    For over ten years, Sarah has spoken, written, and thought deeply about software design. Over the last six months, she has worked with code assistants to explore what they can do in real Rails codebases, not new projects or toy apps.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"gTHmwQviVI8\"\n\n- id: \"sam-poder-sfruby-2025\"\n  title: \"How to open-source your Rails startup\"\n  raw_title: \"How to open-source your Rails startup\"\n  speakers:\n    - Sam Poder\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2026-01-09\"\n  description: |-\n    As Rails developers, we develop on the shoulders of giants. We can do what we can do because of the work of thousands of open source contributors; I want to encourage more developers to give back through open sourcing their work.\n\n    This also isn't a subject talked about often and having just taken a codebase from open to closed source, I can offer a unique perspective. I remember struggling with a lack of resources of the subject when we started the project. Hopefully this talk can make it easier for the next person who open sources their codebase.\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"Y_J84x5ePUs\"\n\n- id: \"mike-perham-sfruby-2025\"\n  title: \"Sidekiq: Open Source, Business and the Future\"\n  raw_title: \"Mike Perham, Sidekiq: Open source, business and the future. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Mike Perham\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Learn how to build a successful open source business model from the creator of the most popular background job infrastructure for Rails applications, and one of the most successful one-person businesses: Sidekiq Pro.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"4H5V6gnG9Oo\"\n\n- id: \"tom-wheeler-sfruby-2025\"\n  title: \"Temporal Demo\"\n  raw_title: \"Temporal Demo\"\n  speakers:\n    - Tom Wheeler\n  kind: \"talk\"\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2026-01-09\"\n  description: |-\n    Alternating between software engineering and technical education roles, Tom Wheeler's career spans nearly 30 years in the financial, healthcare, defense, and tech industries. Prior to joining Temporal in 2022, he created training courses at Cloudera, developed aerospace engineering software at Object Computing, helped design and implement a distributed system for high-volume data processing at WebMD, and wrote some of the earliest web applications at brokerage firm A.G. Edwards.\n  track: \"Blackbox Theater\"\n  video_provider: \"youtube\"\n  video_id: \"JvCQgUcQNps\"\n\n- id: \"noel-rappin-sfruby-2025\"\n  title: \"The Dynamic Ruby Toolkit\"\n  raw_title: \"Noel Rappin: The dynamic Ruby toolkit - Workshop. San Francisco Ruby Conference 2025\"\n  speakers:\n    - Noel Rappin\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2026-01-21\"\n  description: |-\n    Ruby rewards thinking about types with a dynamic mindset instead of a static one. In this workshop, we'll show how use Ruby's dynamism to your advantage. From the humble comment to runtime type checking, from tests to debugging techniques, from data management to true object-oriented design, this workshop will give you the tools you need to bring out Ruby's full power.\n  track: \"Workshop Studio\"\n  video_provider: \"youtube\"\n  video_id: \"c0v3qj06nfc\"\n\n- id: \"eugene-kenny-sfruby-2025\"\n  title: \"Scaling Rails to two million MySQL requests per second\"\n  raw_title: \"Eugene Kenny, Scaling Rails to 2M MySQL requests per second. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Eugene Kenny\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Eugene shares the patterns and techniques Intercom's monolith used to go from 'rails new intercom' to comfortably scaling to over two million MySQL requests per second. From this talk, expect practical takeaways on replication, sharding, caching, connection routing, and upgrade strategy, along with the bumps and trade-offs encountered along the way.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"Xc8OYnIci3E\"\n\n- id: \"startup-demos-sfruby-2025-session-2\"\n  title: \"Startup Demos (Session 2)\"\n  raw_title: \"Startup Demos (Session 2)\"\n  kind: \"demo\"\n  description: |-\n    Live demonstrations from innovative startups building with Ruby and Rails.\n  date: \"2025-11-20\"\n  event_name: \"SF Ruby 2025\"\n  track: \"Main Stage\"\n  video_provider: \"children\"\n  video_id: \"startup-demos-sfruby-2025-session-2\"\n  talks:\n    - id: \"bolt-new-demo-sf-ruby-2025\"\n      title: \"Startup Demo: Bolt\"\n      raw_title: \"Ruby startup demo: Alex Kalderimis, Bolt. San Francisco Ruby Conference 2025\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://bolt.new/\n        Bolt is an AI-native browser tool for building and deploying full-stack web apps with zero code. Since its launch in 2024, it has reached $40M in ARR in just five months.\n      video_provider: \"youtube\"\n      video_id: \"zXbAWkUueUM\"\n      speakers:\n        - \"Alex Kalderimis\"\n\n    - id: \"fin-by-intercom-demo-sf-ruby-2025\"\n      title: \"Startup Demo: Fin by Intercom\"\n      raw_title: \"Ruby startup demo: Ryan Sherlock, Fin by Intercom. San Francisco Ruby Conference 2025\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://fin.ai/\n        Fin is Intercom's AI support agent. It learns from your docs and policies while keeping your tone. Then, Fin can resolve customer questions with human-quality answers across chat, email, voice, and social.\n\n        Here, Ryan shows Fin's AI Engine, including: intent clarification, knowledge retrieval, and response validation to reduce hallucinations.\n      video_provider: \"youtube\"\n      video_id: \"5MepvHfFXgk\"\n      speakers:\n        - \"Ryan Sherlock\"\n\n    - id: \"nexhealth-demo-sf-ruby-2025\"\n      title: \"Startup Demo: NexHealth\"\n      raw_title: \"Ruby startup demo: Matt Duszynski, NexHealth. San Francisco Ruby Conference 2025\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://www.nexhealth.com/\n        NexHealth is a healthcare unicorn accelerating innovation with a universal API powered by the Synchronizer. It is used by tens of thousands of practices across North America and by hundreds of startups.\n      video_provider: \"youtube\"\n      video_id: \"21hf1Ue1o6I\"\n      speakers:\n        - \"Matt Duszynski\"\n\n    - id: \"simple-ai-demo-sf-ruby-2025\"\n      title: \"Startup Demo: SimpleAI\"\n      raw_title: \"Ruby startup demo: Zach Kamran, SimpleAI. San Francisco Ruby Conference 2025\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://www.usesimple.ai/\n        Simple AI is YC-backed and makes it easy to build and deploy enterprise-grade phone agents in days, not weeks. Iconic businesses use this tool for sales calls, customer support, leads qualification, and more.\n      video_provider: \"youtube\"\n      video_id: \"Bl7Dq6aYidE\"\n      speakers:\n        - \"Zach Kamran\"\n\n    - id: \"sixfold-demo-sf-ruby-2025\"\n      title: \"Startup Demo: Sixfold\"\n      raw_title: \"Ruby startup demo: Brian Moseley, Sixfold. San Francisco Ruby Conference 2025\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://www.sixfold.ai/\n        This is an insurtech startup that uses generative AI to optimize insurance underwriting processes.\n      video_provider: \"youtube\"\n      video_id: \"L91KPH6f_q8\"\n      speakers:\n        - \"Brian Moseley\"\n\n- id: \"startup-demos-sfruby-2025-session-3\"\n  title: \"Startup Demos (Session 3)\"\n  raw_title: \"Startup Demos (Session 3)\"\n  event_name: \"SF Ruby 2025\"\n  description: |-\n    Live demonstrations from innovative startups building with Ruby and Rails.\n  date: \"2025-11-20\"\n  kind: \"demo\"\n  track: \"Blackbox Theater\"\n  video_provider: \"children\"\n  video_id: \"startup-demos-sfruby-2025-session-3\"\n  talks:\n    - id: \"accessgrid-demo-sf-ruby-2025\"\n      title: \"AccessGrid Demo\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2026-01-09\"\n      video_id: \"LK0CmY72U9w\"\n      video_provider: \"youtube\"\n      speakers:\n        - \"Auston Bunsen\"\n\n    - id: \"suppli-demo-sf-ruby-2025\"\n      title: \"Suppli Demo\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2026-01-09\"\n      video_id: \"nfeEQBmeirg\"\n      video_provider: \"youtube\"\n      speakers:\n        - \"David Paluy\"\n\n    - id: \"tend-cash-demo-sf-ruby-2025\"\n      title: \"Tend Cash Demo\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2026-01-09\"\n      video_id: \"WItgAAtvJhc\"\n      video_provider: \"youtube\"\n      speakers:\n        - \"James Kerr\"\n\n    - id: \"spinel-demo-sf-ruby-2025\"\n      title: \"Spinel Demo\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2026-01-09\"\n      video_id: \"F6dwuKszqWs\"\n      video_provider: \"youtube\"\n      speakers:\n        - \"André Arko\"\n\n    - id: \"cleary-demo-sf-ruby-2025\"\n      title: \"Cleary Demo\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2026-01-09\"\n      video_id: \"nJ6oxetPDMY\"\n      video_provider: \"youtube\"\n      speakers:\n        - \"Ryan O'Donnell\"\n\n- id: \"startup-demos-sfruby-2025-session-4\"\n  title: \"Startup Demos (Session 4)\"\n  raw_title: \"Startup Demos (Session 4)\"\n  event_name: \"SF Ruby 2025\"\n  kind: \"demo\"\n  description: |-\n    Live demonstrations from innovative startups building with Ruby and Rails.\n  date: \"2025-11-20\"\n  track: \"Main Stage\"\n  video_provider: \"children\"\n  video_id: \"startup-demos-sfruby-2025-session-4\"\n  talks:\n    - id: \"cactus-demo-sf-ruby-2025\"\n      title: \"Startup Demo: Cactus\"\n      raw_title: \"Ruby startup demo: Avinash Joshi, Cactus. San Francisco Ruby Conference 2025\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://oncactus.com/\n        Cactus is an AI-powered business assistant that answers, qualifies, and follows up with every lead around the clock. This way, you never miss a customer, call, or opportunity.\n      video_provider: \"youtube\"\n      video_id: \"kdVAm_yzqpE\"\n      speakers:\n        - \"Avinash Joshi\"\n\n    - id: \"superconductor-demo-sf-ruby-2025\"\n      title: \"Startup Demo: Superconductor\"\n      raw_title: \"Ruby startup demo: Arjun Singh, Superconductor. San Francisco Ruby Conference 2025\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://www.superconductor.dev/\n        Superconductor lets you run multiple coding agents in parallel, each with a live browser preview on desktop or mobile. You can also launch multiple agents per ticket to boost your productivity.\n      video_provider: \"youtube\"\n      video_id: \"P8myd01GxAA\"\n      speakers:\n        - \"Arjun Singh\"\n\n    - id: \"ai-squared-demo-sf-ruby-2025\"\n      title: \"Startup Demo: AI Squared / Multiwoven\"\n      raw_title: \"Ruby startup demo: Nagendra Dhanakeerthi, AI Squared/Multwoven. San Francisco Ruby Conference 2025\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://github.com/Multiwoven/multiwoven\n        Multiwoven by AI Squared is an open-source reverse ETL platform that activates warehouse data into SaaS apps. It offers one-click self-hosting, customizable connectors, and is built for modern data teams.\n      video_provider: \"youtube\"\n      video_id: \"A3smrePJj4M\"\n      speakers:\n        - \"Nagendra Hassan Dhanakeerthi\"\n\n    - id: \"ubicloud-demo-sf-ruby-2025\"\n      title: \"Startup Demo: Ubicloud\"\n      raw_title: \"Ruby startup demo: Dan Farina, Ubicloud. San Francisco Ruby Conference 2025\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://www.ubicloud.com/\n        Ubicloud is an open source alternative to AWS that provides cloud services on bare metal providers, such as Hetzner, Leaseweb, or AWS Bare Metal.\n      video_provider: \"youtube\"\n      video_id: \"rhmINL-nK5o\"\n      speakers:\n        - \"Daniel Farina\"\n\n    - id: \"finta-demo-sf-ruby-2025\"\n      title: \"Startup Demo: Finta\"\n      raw_title: \"Ruby startup demo: Andy Wang, Finta. San Francisco Ruby Conference 2025\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2025-12-26\"\n      description: |-\n        Ruby Startup Demo: https://www.finta.com/\n        Finta is the new default for startups to handle accounting and taxes. Within 10 minutes, you get automated bookkeeping, effortless tax filing, and real-time insights.\n      video_provider: \"youtube\"\n      video_id: \"FDHtRONY4kk\"\n      speakers:\n        - \"Andy Wang\"\n\n- id: \"startup-demos-sfruby-2025-session-5\"\n  title: \"Startup Demos (Session 5)\"\n  raw_title: \"Startup Demos\"\n  event_name: \"SF Ruby 2025\"\n  description: |-\n    Live demonstrations from innovative startups building with Ruby and Rails.\n  date: \"2025-11-20\"\n  track: \"Blackbox Theater\"\n  kind: \"demo\"\n  video_provider: \"children\"\n  video_id: \"startup-demos-sfruby-2025-session-5\"\n  talks:\n    - id: \"cora-computer-demo-sf-ruby-2025\"\n      title: \"Cora Computer Demo\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2026-01-09\"\n      video_id: \"FNWAKyTX4Uo\"\n      video_provider: \"youtube\"\n      speakers:\n        - \"Kieran Klaassen\"\n\n    - id: \"terminalwire-demo-sf-ruby-2025\"\n      title: \"Terminalwire Demo\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2026-01-09\"\n      video_id: \"ExICQ7RDT0E\"\n      video_provider: \"youtube\"\n      speakers:\n        - \"Brad Gessler\"\n\n    - id: \"llamapress-demo-sf-ruby-2025\"\n      title: \"llamapress Demo\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2026-01-09\"\n      video_id: \"Po-k0sddd0Y\"\n      video_provider: \"youtube\"\n      speakers:\n        - \"Kody Kendall\"\n\n    - id: \"chatwithwork-demo-sf-ruby-2025\"\n      title: \"Chatwithwork Demo\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2026-01-09\"\n      video_id: \"H0XwqkQfiIM\"\n      video_provider: \"youtube\"\n      speakers:\n        - \"Carmine Paolino\"\n\n    - id: \"bemi-ai-demo-sf-ruby-2025\"\n      title: \"Bemi AI Demo\"\n      event_name: \"SF Ruby 2025\"\n      published_at: \"2026-01-09\"\n      video_id: \"3s6Je3wTXqE\"\n      video_provider: \"youtube\"\n      speakers:\n        - \"Evgeny Li\"\n\n- id: \"vladimir-dementyev-sfruby-2025\"\n  title: \"Keynote: Rails X\"\n  raw_title: \"Closing Keynote: Vladimir Dementyev, Rails X. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Vladimir shares a vision for the future of Rails, informed by surveys of Ruby developers and his work with Ruby startups. He inspires us to take part in building it!\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"hP4SkKH4IsA\"\n  slides_url: \"https://speakerdeck.com/palkan/sf-ruby-conf-2025-rails-x\"\n\n- id: \"closing-words-sfruby-2025\"\n  title: \"Closing Words\"\n  raw_title: \"Closing words: Irina Nazarova. San Francisco Ruby Conference 2025.\"\n  speakers:\n    - Irina Nazarova\n    - Vladimir Dementyev\n  event_name: \"SF Ruby 2025\"\n  date: \"2025-11-20\"\n  published_at: \"2025-12-26\"\n  description: |-\n    Irina closes the official Day 2 of the conference and invites everyone to share the Rails X cake and join Day 3 of community events, from an open-water swim to Alcatraz, to a bike ride, a 10K run, and a Hack Day at AngelList.\n\n    She thanks everyone who participated: attendees, sponsors, speakers, volunteers, organizers, students, and many Martians. She hopes that the connections made at the event will turn into friendships and collaborations, inspiration will turn into open source and products, and that, together with everything learned, they will help support new and upcoming Ruby startups and grow them into the big success stories of the years to come.\n  track: \"Main Stage\"\n  video_provider: \"youtube\"\n  video_id: \"Fx-AgNTMIRU\"\n"
  },
  {
    "path": "data/shinosakarb/series.yml",
    "content": "---\nname: \"Shinosaka.rb\"\nwebsite: \"https://shinosakarb.doorkeeper.jp\"\nkind: \"meetup\"\nfrequency: \"irregular\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/shinosakarb/shinosakarb-meetup/event.yml",
    "content": "---\nid: \"shinosakarb-meetup\"\ntitle: \"Shinosaka.rb Meetup\"\nlocation: \"Osaka, Japan\"\ndescription: |-\n  A Ruby community around Shin-Osaka with a history of workshops and meetups spanning Ruby, Rails, and related technologies.\nwebsite: \"https://shinosakarb.doorkeeper.jp\"\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 34.7340782\n  longitude: 135.5018726\n"
  },
  {
    "path": "data/shinosakarb/shinosakarb-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/shrug/series.yml",
    "content": "---\nname: \"Sheffield Ruby\"\nwebsite: \"https://shrug.org/\"\ntwitter: \"https://x.com/sheffieldruby\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"GB\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCoyqucxoFXDFnh3khD0rjUg\"\naliases:\n  - shrug\n  - sheffieldruby\n"
  },
  {
    "path": "data/shrug/shrug-meetup/event.yml",
    "content": "---\nid: \"shrug-meetup\"\ntitle: \"Sheffield Ruby\"\nlocation: \"Sheffield, UK\"\ndescription: \"\"\nchannel_id: \"UCoyqucxoFXDFnh3khD0rjUg\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nwebsite: \"https://shrug.org/\"\ncoordinates:\n  latitude: 53.38112899999999\n  longitude: -1.470085\n"
  },
  {
    "path": "data/shrug/shrug-meetup/videos.yml",
    "content": "---\n- id: \"nick-schwaderer-sheffield-ruby-meetup-june-2018\"\n  title: \"Measuring Chronic Pain Outcomes with Ruby and Twilio\"\n  raw_title: \"Measuring Chronic Pain Outcomes with Ruby and Twilio - Sheffield Ruby - June 2018\"\n  event_name: \"Sheffield Ruby Meetup - June 2018\"\n  date: \"2018-06-28\"\n  description: |-\n    We can use our skills to improve the lives of those around us, not just our employers and customers. In 2017 Nick's fiancée's surgeon told her that she would require a hip replacement. The surgeon remarked that barometric pressure very much affected day to day chronic pain. He decided to test this.\n\n    Using a Twilio SMS 'front end', Ruby on Rails 'back end', and WeatherUnderground integration Nick promptly built an application to randomly request her pain levels against local barometric pressure for four months and processed the results. The processing involved his first foray into machine learning concepts with Ruby. This talk will tell their story, walk through the exact code as it was executed, and elaborate on our responsibility to 'give back' to those around us with our Ruby 'superpower'.\n  video_provider: \"youtube\"\n  video_id: \"ZtBckwQaEBA\"\n  published_at: \"2018-06-28\"\n  speakers:\n    - Nick Schwaderer\n"
  },
  {
    "path": "data/sin-city-ruby/series.yml",
    "content": "---\nname: \"Sin City Ruby\"\nwebsite: \"https://sincityruby.com\"\ntwitter: \"jasonswett\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"Sin City Ruby\"\ndefault_country_code: \"US\"\nlanguage: \"english\"\nyoutube_channel_name: \"\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2022/event.yml",
    "content": "---\nid: \"sin-city-ruby-2022\"\ntitle: \"Sin City Ruby 2022\"\nkind: \"conference\"\nlocation: \"Las Vegas, NV, United States\"\ndescription: |-\n  March 24-25, Las Vegas, Tropicana Las Vegas\nstart_date: \"2022-03-24\"\nend_date: \"2022-03-25\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2022\nwebsite: \"https://web.archive.org/web/20220330020102/https://www.sincityruby.com/\"\nbanner_background: \"#000\"\nfeatured_background: \"#000\"\nfeatured_color: \"#FF0\"\ncoordinates:\n  latitude: 36.0988118\n  longitude: -115.1703887\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2022/venue.yml",
    "content": "# https://web.archive.org/web/20220330020102/https://www.sincityruby.com/\n---\nname: \"Tropicana Las Vegas\"\n\naddress:\n  street: \"3801 S Las Vegas Blvd\"\n  city: \"Las Vegas\"\n  region: \"NV\"\n  postal_code: \"89109\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"3801 Las Vegas Blvd S, Las Vegas, NV 89109, USA\"\n\ncoordinates:\n  latitude: 36.0988118\n  longitude: -115.1703887\n\nmaps:\n  google: \"https://maps.google.com/?q=Tropicana+Las+Vegas,36.0988118,-115.1703887\"\n  apple: \"https://maps.apple.com/?q=Tropicana+Las+Vegas&ll=36.0988118,-115.1703887\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=36.0988118&mlon=-115.1703887\"\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2022/videos.yml",
    "content": "---\n# TODO: talk titles\n\n# Website: https://web.archive.org/web/20220401040813/https://www.sincityruby.com\n# Schedule: https://web.archive.org/web/20220401040813/https://www.sincityruby.com/schedule.html\n# Schedule: https://github.com/jasonswett/sincityruby/blob/25a6b6222757af636738e55d4051d5945025998f/schedule.html\n\n## Day 1 - 2022-03-24\n\n- id: \"sin-city-ruby-2022-kelly-sutton\"\n  title: \"Talk by Kelly Sutton\"\n  raw_title: \"Talk by Kelly Sutton\"\n  date: \"2022-03-24\"\n  speakers:\n    - Kelly Sutton\n  video_id: \"sin-city-ruby-2022-kelly-sutton\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Opening talk by Kelly Sutton.\n\n- id: \"sin-city-ruby-2022-matthias-lee\"\n  title: \"Talk by Matthias Lee\"\n  raw_title: \"Talk by Matthias Lee\"\n  date: \"2022-03-24\"\n  speakers:\n    - Matthias Lee\n  video_id: \"sin-city-ruby-2022-matthias-lee\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Presentation by Matthias Lee.\n\n- id: \"sin-city-ruby-2022-thai-wood\"\n  title: \"Talk by Thai Wood\"\n  raw_title: \"Talk by Thai Wood\"\n  date: \"2022-03-24\"\n  speakers:\n    - Thai Wood\n  video_id: \"sin-city-ruby-2022-thai-wood\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Session by Thai Wood.\n\n- id: \"sin-city-ruby-2022-andrea-fomera\"\n  title: \"Upgrading Rails doesn't have to be scary\"\n  raw_title: \"Talk by Andrea Fomera\"\n  date: \"2022-03-24\"\n  slides_url: \"https://docs.google.com/presentation/d/15SHgg1uFONuqPHFQ5LdtdEoRqOFYRspAW0tnQShfFK4/edit?usp=sharing\"\n  speakers:\n    - Andrea Fomera\n  video_id: \"sin-city-ruby-2022-andrea-fomera\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Ever felt overwhelmed when figuring out how to upgrade a Rails app? Unsure where you should begin? We’ll talk about how upgrading should be treated as a feature, and how you can get buy-in from management for upgrading Rails.\n\n- id: \"sin-city-ruby-2022-drew-bragg\"\n  title: \"Talk by Drew Bragg\"\n  raw_title: \"Talk by Drew Bragg\"\n  date: \"2022-03-24\"\n  speakers:\n    - Drew Bragg\n  video_id: \"sin-city-ruby-2022-drew-bragg\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Presentation by Drew Bragg.\n\n- id: \"sin-city-ruby-2022-brittany-martin\"\n  title: \"We Need Someone Technical on the Call\"\n  raw_title: \"Talk by Brittany Martin\"\n  date: \"2022-03-24\"\n  speakers:\n    - Brittany Martin\n  video_id: \"sin-city-ruby-2022-brittany-martin\"\n  video_provider: \"not_recorded\"\n  description: |-\n    A DM. The dreaded message. “They want someone technical on the call.”\n\n    If that statement is terrifying, never fear. Being effective at these interactions can be a big opportunity for your career. Learn tactics on when to commit to calls and how to execute them while empowering your team, conserving your time and acing the follow through.\n\n## Day 2 - 2022-03-25\n\n- id: \"sin-city-ruby-2022-ivy-evans\"\n  title: \"Talk by Ivy Evans\"\n  raw_title: \"Talk by Ivy Evans\"\n  date: \"2022-03-25\"\n  speakers:\n    - Ivy Evans\n  video_id: \"sin-city-ruby-2022-ivy-evans\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Morning session with Ivy Evans.\n\n- id: \"sin-city-ruby-2022-nikita-vasilevsky\"\n  title: \"Talk by Nikita Vasilevsky\"\n  raw_title: \"Talk by Nikita Vasilevsky\"\n  date: \"2022-03-25\"\n  speakers:\n    - Nikita Vasilevsky\n  video_id: \"sin-city-ruby-2022-nikita-vasilevsky\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Presentation by Nikita Vasilevsky.\n\n- id: \"sin-city-ruby-2022-andrew-culver\"\n  title: \"Talk by Andrew Culver\"\n  raw_title: \"Talk by Andrew Culver\"\n  date: \"2022-03-25\"\n  speakers:\n    - Andrew Culver\n  video_id: \"sin-city-ruby-2022-andrew-culver\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Session by Andrew Culver.\n\n- id: \"sin-city-ruby-colleen-schnettler\"\n  title: \"Talk by Colleen Schnettler\"\n  raw_title: \"Talk by Colleen Schnettler\"\n  date: \"2022-03-25\"\n  speakers:\n    - Colleen Schnettler\n  video_id: \"sin-city-ruby-colleen-schnettler\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Afternoon session with Colleen Schnettler.\n\n- id: \"sin-city-ruby-2022-nick-schwaderer\"\n  title: \"Talk by Nick Schwaderer\"\n  raw_title: \"Talk by Nick Schwaderer\"\n  date: \"2022-03-25\"\n  speakers:\n    - Nick Schwaderer\n  video_id: \"sin-city-ruby-2022-nick-schwaderer\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Presentation by Nick Schwaderer.\n\n- id: \"sin-city-ruby-2022-jason-charnes\"\n  title: \"Talk by Jason Charnes\"\n  raw_title: \"Talk by Jason Charnes\"\n  date: \"2022-03-25\"\n  speakers:\n    - Jason Charnes\n  video_id: \"sin-city-ruby-2022-jason-charnes\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Session by Jason Charnes.\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2024/event.yml",
    "content": "---\nid: \"sin-city-ruby-2024\"\ntitle: \"Sin City Ruby 2024\"\nkind: \"conference\"\nlocation: \"Las Vegas, NV, United States\"\ndescription: |-\n  March 21-22, Las Vegas, Tropicana Las Vegas\nstart_date: \"2024-03-21\"\nend_date: \"2024-03-22\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2024\nwebsite: \"https://web.archive.org/web/20240329122802/https://www.sincityruby.com/\"\nbanner_background: \"#000\"\nfeatured_background: \"#000\"\nfeatured_color: \"#FF0\"\ncoordinates:\n  latitude: 36.0988118\n  longitude: -115.1703887\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2024/venue.yml",
    "content": "# https://web.archive.org/web/20240329122802/https://www.sincityruby.com/\n---\nname: \"Tropicana Las Vegas\"\n\naddress:\n  street: \"3801 S Las Vegas Blvd\"\n  city: \"Las Vegas\"\n  region: \"NV\"\n  postal_code: \"89109\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"3801 Las Vegas Blvd S, Las Vegas, NV 89109, USA\"\n\ncoordinates:\n  latitude: 36.0988118\n  longitude: -115.1703887\n\nmaps:\n  google: \"https://maps.google.com/?q=Tropicana+Las+Vegas,36.0988118,-115.1703887\"\n  apple: \"https://maps.apple.com/?q=Tropicana+Las+Vegas&ll=36.0988118,-115.1703887\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=36.0988118&mlon=-115.1703887\"\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2024/videos.yml",
    "content": "---\n# TODO: talk titles\n\n# Website: https://web.archive.org/web/20240329122802/https://www.sincityruby.com/\n# Schedule: https://github.com/jasonswett/sincityruby/blob/5d0788fbfc36a3d281d4b14241ad57df409b6ba2/schedule.html\n\n## Day 1 - Thursday, March 21st\n\n# Opening remarks and introductions\n\n- id: \"sin-city-ruby-2024-adrian-marin\"\n  title: \"How To Build A Business on Rails and Open-Source\"\n  raw_title: \"Sin City Ruby 2024 - How to build a business on Rails and Open-Source\"\n  date: \"2024-03-21\"\n  speakers:\n    - Adrian Marin\n  video_id: \"sin-city-ruby-2024-adrian-marin\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Talk by Adrian Marin at Sin City Ruby 2024.\n\n- id: \"sin-city-ruby-2024-chris-hobbs\"\n  title: \"Talk by Chris Hobbs\"\n  raw_title: \"Sin City Ruby 2024 - Talk by Chris Hobbs\"\n  date: \"2024-03-21\"\n  speakers:\n    - Chris Hobbs\n  video_id: \"sin-city-ruby-2024-chris-hobbs\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Talk by Chris Hobbs at Sin City Ruby 2024.\n\n- id: \"sin-city-ruby-2024-Drew Bragg\"\n  title: \"Who Wants to be a Ruby Engineer?\"\n  raw_title: \"Sin City Ruby 2024 - Talk by Drew Bragg\"\n  date: \"2024-03-21\"\n  speakers:\n    - Drew Bragg\n  video_id: \"sin-city-ruby-2024-Drew Bragg\"\n  video_provider: \"not_recorded\"\n  kind: \"gameshow\"\n  description: |-\n    Games and prizes with Drew Bragg.\n\n# Lunch\n\n- id: \"sin-city-ruby-2024-stefanni-brasil\"\n  title: \"From RSpec to Jest: JavaScript testing for Rails devs\"\n  raw_title: \"Sin City Ruby 2024 - Talk by Stefanni Brasil\"\n  date: \"2024-03-21\"\n  speakers:\n    - Stefanni Brasil\n  video_id: \"sin-city-ruby-2024-stefanni-brasil\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Do you want to write JavaScript tests but feel stuck transferring your testing skills to the JavaScript world? Do you wish that one day you could write JS tests as confidently as you write Ruby tests? If so, this talk is for you.\n\n    Let’s face it: JavaScript isn’t going anywhere. One way to become more productive is to be confident with writing JavaScript automated tests.\n\n    Learn how to use Jest, a popular JavaScript testing framework. Let's go through the basics of JavaScript Unit testing with Jest, gotchas, and helpful tips to make your JS testing experience more joyful.\n\n    By the end of this talk, you’ll have added new skills to your JS tests toolbox. How to set up test data, mock HTTP requests, assert elements in the DOM, and more helpful bites to cover your JavaScript code confidently.\n\n- id: \"sin-city-ruby-2024-andrew-atkinson\"\n  title: \"Mastering Query Performance With Active Record\"\n  raw_title: \"Sin City Ruby 2024 - Talk by Andrew Atkinson\"\n  date: \"2024-03-21\"\n  speakers:\n    - Andrew Atkinson\n  video_id: \"sin-city-ruby-2024-andrew-atkinson\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://andyatkinson.com/assets/images/posts/2024/scr-1.jpg\"\n  thumbnail_sm: \"https://andyatkinson.com/assets/images/posts/2024/scr-1.jpg\"\n  thumbnail_md: \"https://andyatkinson.com/assets/images/posts/2024/scr-1.jpg\"\n  thumbnail_lg: \"https://andyatkinson.com/assets/images/posts/2024/scr-1.jpg\"\n  thumbnail_xl: \"https://andyatkinson.com/assets/images/posts/2024/scr-1.jpg\"\n  description: |-\n    https://andyatkinson.com/blog/2024/03/25/sin-city-ruby-2024\n\n- id: \"sin-city-ruby-2024-jeremy-smith\"\n  title: \"Talk by Jeremy Smith\"\n  raw_title: \"Sin City Ruby 2024 - Talk by Jeremy Smith\"\n  date: \"2024-03-21\"\n  speakers:\n    - Jeremy Smith\n  video_id: \"sin-city-ruby-2024-jeremy-smith\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Talk by Jeremy Smith at Sin City Ruby 2024.\n\n# Break\n\n# Opening Reception\n\n## Day 2 - Friday, March 22nd\n\n- id: \"sin-city-ruby-2024-ernesto-tagwerker\"\n  title: \"Stuck in the Tar Pit\"\n  raw_title: \"Sin City Ruby 2024 - Talk by Ernesto Tagwerker\"\n  date: \"2024-03-22\"\n  slides_url: \"https://speakerdeck.com/etagwerker/stuck-in-the-tar-pit-at-sin-city-ruby-24\"\n  speakers:\n    - Ernesto Tagwerker\n  video_id: \"sin-city-ruby-2024-ernesto-tagwerker\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Nobody wants to inherit a project that reeks but here we are: Stuck in the tar pit. How did we get here? In this talk you will learn how to use a few, great Ruby gems that will guide you out of that sticky tar you are in.\n\n- id: \"sin-city-ruby-2024-tom-rossi\"\n  title: \"Are you my mother?\"\n  raw_title: \"Sin City Ruby 2024 - Talk by Tom Rossi\"\n  date: \"2024-03-22\"\n  speakers:\n    - Tom Rossi\n  video_id: \"sin-city-ruby-2024-tom-rossi\"\n  video_provider: \"not_recorded\"\n  description: |-\n    This session explores the \"Rails family trees,\" examining how classes in Rails share behaviors and attributes through inheritance, modules, single table inheritance, and delegated types. It provides practical guidance on determining the best approach for your application while highlighting common pitfalls to avoid.\n\n- id: \"sin-city-ruby-2024-vladimir-dementyev\"\n  title: \"Seven deadly Rails anti-patterns\"\n  raw_title: \"Sin City Ruby 2024 - Talk by Vladimir Dementyev\"\n  date: \"2024-03-22\"\n  slides_url: \"https://speakerdeck.com/palkan/sin-city-ruby-2024-seven-deadly-rails-anti-patterns\"\n  speakers:\n    - Vladimir Dementyev\n  video_id: \"sin-city-ruby-2024-vladimir-dementyev\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Developing web applications with Ruby on Rails is known to be hellishly productive. What’s the price of this deal? Let’s talk about design patterns leveraged by the framework responsible for increased productivity and at the same time often acclaimed for being anti-patterns.\n\n# Arm wrestling\n\n# Lunch\n\n- id: \"sin-city-ruby-2024-jason-charnes\"\n  title: \"Talk by Jason Charnes\"\n  raw_title: \"Sin City Ruby 2024 - Talk by Jason Charnes\"\n  date: \"2024-03-22\"\n  speakers:\n    - Jason Charnes\n  video_id: \"sin-city-ruby-2024-jason-charnes\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GJTzd8wbUAAPqnB?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GJTzd8wbUAAPqnB?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GJTzd8wbUAAPqnB?format=jpg&name=large\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GJTzd8wbUAAPqnB?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GJTzd8wbUAAPqnB?format=jpg&name=large\"\n  description: |-\n    Talk by Jason Charnes at Sin City Ruby 2024.\n\n- id: \"sin-city-ruby-2024-irina-nazarova\"\n  title: \"How To Do Well In Consulting\"\n  raw_title: \"Sin City Ruby 2024 - Talk by Irina Nazarova\"\n  date: \"2024-03-22\"\n  slides_url: \"https://speakerdeck.com/irinanazarova/how-to-do-well-in-consulting\"\n  speakers:\n    - Irina Nazarova\n  video_id: \"sin-city-ruby-2024-irina-nazarova\"\n  video_provider: \"not_recorded\"\n  thumbnail_xs: \"https://pbs.twimg.com/media/GJUJ73jbQAAS2iM?format=jpg\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/GJUJ73jbQAAS2iM?format=jpg\"\n  thumbnail_md: \"https://pbs.twimg.com/media/GJUJ73jbQAAS2iM?format=jpg&name=large\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/GJUJ73jbQAAS2iM?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/GJUJ73jbQAAS2iM?format=jpg&name=large\"\n  description: |-\n    Talk by Irina Nazarova at Sin City Ruby 2024.\n\n- id: \"sin-city-ruby-2024-obie-fernandez\"\n  title: \"Keynote by Obie Fernandez\"\n  raw_title: \"Sin City Ruby 2024 - Keynote: Obie Fernandez\"\n  date: \"2024-03-22\"\n  speakers:\n    - Obie Fernandez\n  video_id: \"sin-city-ruby-2024-obie-fernandez\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Keynote by Obie Fernandez at Sin City Ruby 2024.\n\n# End of Conference\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2025/event.yml",
    "content": "---\nid: \"sin-city-ruby-2025\"\ntitle: \"Sin City Ruby 2025\"\nkind: \"conference\"\nlocation: \"Las Vegas, NV, United States\"\ndescription: |-\n  April 10-11, 2025, Las Vegas, NV, MGM Grand\nstart_date: \"2025-04-10\"\nend_date: \"2025-04-11\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2025\nwebsite: \"https://www.sincityruby.com\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#8C020E\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 36.1028922\n  longitude: -115.1700325\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2025/schedule.yml",
    "content": "# Schedule: Conference April 10-11, 2025\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2025-04-10\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"08:30\"\n        slots: 1\n        items:\n          - Doors open\n\n      - start_time: \"08:30\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - '\"Forced Socialization\"'\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"09:15\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:30\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Sponsor Message\n\n      - start_time: \"10:45\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n        items:\n          - Arm wrestling\n\n      - start_time: \"12:30\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:30\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:45\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"17:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - Opening reception\n\n  - name: \"Day 2\"\n    date: \"2025-04-11\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"08:30\"\n        slots: 1\n        items:\n          - Doors open\n\n      - start_time: \"08:30\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - '\"Forced Socialization\"'\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"09:15\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Break\n      - start_time: \"10:30\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n        items:\n          - Break\n      - start_time: \"11:45\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"14:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:30\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:45\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Closing remarks\n\n      - start_time: \"17:00\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Conclusion of conference\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Cisco Meraki\"\n          badge: \"\"\n          website: \"https://meraki.cisco.com\"\n          slug: \"cisco-meraki\"\n          logo_url: \"https://images.squarespace-cdn.com/content/v1/66ce1b88d0c8cb12f495dc48/566e6210-b8d2-43c5-b8e8-f54cd86d0264/Cisco_Meraki_Logo_Color.png\"\n\n        - name: \"Cedarcode\"\n          badge: \"\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"cedarcode\"\n          logo_url: \"https://images.squarespace-cdn.com/content/v1/66ce1b88d0c8cb12f495dc48/a4f39b63-303c-45b1-a26e-103b3655664f/logo-horizontal-dark-540x82.png\"\n\n        - name: \"Evil Martians\"\n          badge: \"\"\n          website: \"https://evilmartians.com/\"\n          slug: \"evil-martians\"\n          logo_url: \"https://images.squarespace-cdn.com/content/v1/66ce1b88d0c8cb12f495dc48/ee9cb4d1-e01c-4e83-bb94-6e47f1d57168/evil+martians.png\"\n\n        - name: \"Judoscale\"\n          badge: \"\"\n          website: \"https://judoscale.com/\"\n          slug: \"judoscale\"\n          logo_url: \"https://images.squarespace-cdn.com/content/v1/66ce1b88d0c8cb12f495dc48/04dc5eb8-357b-47ca-acb7-5514eeb0ac62/judoscale-logo-horizontal-color_500.png\"\n\n        - name: \"Offsite\"\n          badge: \"\"\n          website: \"https://www.offsite.com/\"\n          slug: \"offsite\"\n          logo_url: \"https://images.squarespace-cdn.com/content/v1/66ce1b88d0c8cb12f495dc48/cebdb46d-bae2-4420-a45f-eb612a7bd1df/offsite+logo+1.png\"\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2025/venue.yml",
    "content": "---\nname: \"MGM Grand\"\n\naddress:\n  street: \"3799 South Las Vegas Boulevard\"\n  city: \"Las Vegas\"\n  region: \"Nevada\"\n  postal_code: \"89109\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"3799 S Las Vegas Blvd, Las Vegas, NV 89109, USA\"\n\ncoordinates:\n  latitude: 36.1028922\n  longitude: -115.1700325\n\nmaps:\n  google: \"https://maps.google.com/?q=MGM+Grand,36.1036224,-115.1675744\"\n  apple: \"https://maps.apple.com/?q=MGM+Grand&ll=36.1036224,-115.1675744\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=36.1036224&mlon=-115.1675744\"\n"
  },
  {
    "path": "data/sin-city-ruby/sin-city-ruby-2025/videos.yml",
    "content": "---\n# TODO: talk titles\n\n# Website: https://www.sincityruby.com\n# Schedule: https://www.sincityruby.com/schedule\n\n## Day 1\n\n- title: \"Talk by Jason Swett\"\n  raw_title: \"Sin City Ruby 2025 - Talk by Jason “Sin City Ruby” Swett\"\n  speakers:\n    - Jason Swett\n  id: \"sin-city-ruby-2025-jason-swett\"\n  video_id: \"sin-city-ruby-2025-jason-swett\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Talk by Jason “Sin City Ruby” Swett at Sin City Ruby 2025.\n  date: \"2025-04-10\"\n\n- title: \"Talk by Freedom Dumlao\"\n  raw_title: \"Sin City Ruby 2025 - Talk by Freedom Dumlao\"\n  speakers:\n    - Freedom Dumlao\n  id: \"sin-city-ruby-2025-freedom-dumlao\"\n  video_id: \"sin-city-ruby-2025-freedom-dumlao\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Talk by Freedom Dumlao at Sin City Ruby 2025.\n  date: \"2025-04-10\"\n\n- title: \"Talk by Fito von Zastrow and Alan Ridlehoover\"\n  raw_title: \"Sin City Ruby 2025 - Talk by Fito von Zastrow and Alan Ridlehoover\"\n  speakers:\n    - Fito von Zastrow\n    - Alan Ridlehoover\n  id: \"sin-city-ruby-2025-fito-von-zastrow-alan-ridlehoover\"\n  video_id: \"sin-city-ruby-2025-fito-von-zastrow-alan-ridlehoover\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Talk by Fito von Zastrow and Alan Ridlehoover at Sin City Ruby 2025.\n  date: \"2025-04-10\"\n\n- title: \"Game Show by Drew Bragg\"\n  raw_title: \"Sin City Ruby 2025 - Game Show by Drew Bragg\"\n  speakers:\n    - Drew Bragg\n  id: \"drew-bragg-sin-city-ruby-2025\"\n  video_id: \"drew-bragg-sin-city-ruby-2025\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Game Show by Drew Bragg at Sin City Ruby 2025.\n  date: \"2025-04-10\"\n  announced_at: \"2025-03-14T15:18:00Z\"\n\n## Day 2\n\n- title: \"Talk by Prarthana Shiva\"\n  raw_title: \"Sin City Ruby 2025 - Talk by Prarthana Shiva\"\n  speakers:\n    - Prarthana Shiva\n  id: \"sin-city-ruby-2025-prarthana-shiva\"\n  video_id: \"sin-city-ruby-2025-prarthana-shiva\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Talk by Prarthana Shiva at Sin City Ruby 2025.\n  date: \"2025-04-11\"\n\n- title: \"Startups on Rails 2025\"\n  raw_title: \"Sin City Ruby 2025 - Talk by Irina Nazarova\"\n  speakers:\n    - Irina Nazarova\n  id: \"sin-city-ruby-2025-irina-nazarova\"\n  video_id: \"sin-city-ruby-2025-irina-nazarova\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Talk by Irina Nazarova at Sin City Ruby 2025.\n  date: \"2025-04-11\"\n\n- title: \"Talk by Jason Charnes\"\n  raw_title: \"Sin City Ruby 2025 - Talk by Jason Charnes\"\n  speakers:\n    - Jason Charnes\n  id: \"sin-city-ruby-2025-jason-charnes\"\n  video_id: \"sin-city-ruby-2025-jason-charnes\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Talk by Jason Charnes at Sin City Ruby 2025.\n  date: \"2025-04-11\"\n\n- title: \"Hotwire Demystified\"\n  raw_title: \"Sin City Ruby 2025 - Talk by Chris Oliver\"\n  speakers:\n    - Chris Oliver\n  id: \"sin-city-ruby-2025-chris-oliver\"\n  video_id: \"sin-city-ruby-2025-chris-oliver\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Talk by Chris Oliver at Sin City Ruby 2025.\n  date: \"2025-04-11\"\n\n- title: \"Keynote by Dave Thomas\"\n  raw_title: \"Sin City Ruby 2025 - Keynote by Dave Thomas\"\n  speakers:\n    - Dave Thomas\n  id: \"dave-thomas-sin-city-ruby-2025\"\n  video_id: \"dave-thomas-sin-city-ruby-2025\"\n  video_provider: \"not_recorded\"\n  description: |-\n    Keynote by Dave Thomas at Sin City Ruby 2025.\n  date: \"2025-04-11\"\n  announced_at: \"2024-03-26T17:11:00Z\"\n"
  },
  {
    "path": "data/solidusconf/series.yml",
    "content": "---\nname: \"SolidusConf\"\nwebsite: \"http://conf.solidus.io\"\ntwitter: \"solidusIO\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2016/event.yml",
    "content": "---\nid: \"solidusconf-2016\"\ntitle: \"SolidusConf 2016\"\ndescription: \"\"\nlocation: \"Toronto, Canada\"\nkind: \"conference\"\nstart_date: \"2016-05-11\"\nend_date: \"2016-05-12\"\nwebsite: \"https://conf2016.solidus.io\"\ncoordinates:\n  latitude: 43.653226\n  longitude: -79.3831843\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2017/event.yml",
    "content": "---\nid: \"solidusconf-2017\"\ntitle: \"Solidus Conf 2017\"\ndescription: |-\n  The third annual conference for Solidus experts, people new to Solidus ecommerce, and stores considering the platform.\nlocation: \"London, UK\"\nkind: \"conference\"\nstart_date: \"2017-05-22\"\nend_date: \"2017-05-25\"\nwebsite: \"https://conf2017.solidus.io\"\ncoordinates:\n  latitude: 51.5072178\n  longitude: -0.1275862\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2017/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2018/event.yml",
    "content": "---\nid: \"solidusconf-2018\"\ntitle: \"Southeast Solidus - Solidus By The Lake 2018\"\ndescription: \"\"\nlocation: \"Cordova, TN, United States\"\nkind: \"conference\"\nstart_date: \"2018-08-06\"\nend_date: \"2018-08-08\"\nwebsite: \"https://conf2018.solidus.io\"\ncoordinates:\n  latitude: 35.1598391\n  longitude: -89.761545\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2018/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2019/event.yml",
    "content": "---\nid: \"solidusconf-2019\"\ntitle: \"Solidus Conf 2019\"\ndescription: |-\n  21-24 Oct 2019 Salt Lake City, Utah\nlocation: \"Salt Lake City, UT, United States\"\nkind: \"conference\"\nstart_date: \"2019-10-21\"\nend_date: \"2019-10-24\"\nwebsite: \"https://conf2019.solidus.io\"\nplaylist: \"https://www.youtube.com/playlist?list=PLE7tQUdRKcyaJKKOulAmyi-z323OPY5mW\"\ncoordinates:\n  latitude: 40.7600376\n  longitude: -111.8846127\naliases:\n  - SolidusConf 2019\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2019/venue.yml",
    "content": "---\nname: \"Salt Lake City Public Library\"\n\naddress:\n  street: \"210 East 400 South\"\n  city: \"Salt Lake City\"\n  region: \"Utah\"\n  postal_code: \"84111\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"210 E 400 S, Salt Lake City, UT 84111, USA\"\n\ncoordinates:\n  latitude: 40.7600376\n  longitude: -111.8846127\n\nmaps:\n  google: \"https://maps.google.com/?q=Salt+Lake+City+Public+Library,40.7600376,-111.8846127\"\n  apple: \"https://maps.apple.com/?q=Salt+Lake+City+Public+Library&ll=40.7600376,-111.8846127\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=40.7600376&mlon=-111.8846127\"\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://conf.solidus.io\n# Videos: https://www.youtube.com/playlist?list=PLE7tQUdRKcyaJKKOulAmyi-z323OPY5mW\n---\n[]\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2020/event.yml",
    "content": "---\nid: \"solidusconf-2020\"\ntitle: \"Solidus Conf 2020\"\ndescription: |-\n  100% digital conference\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2020-09-23\"\nend_date: \"2020-09-25\"\nwebsite: \"https://conf2020.solidus.io/solidus-conf-2020-100-percent-digital-conference/\"\ncoordinates: false\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2020/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2022/event.yml",
    "content": "---\nid: \"solidusconf-2022\"\ntitle: \"Solidus Conf 7\"\ndescription: |-\n  Solid us: Support Open Source\nlocation: \"online\"\nkind: \"conference\"\nstart_date: \"2022-01-27\"\nend_date: \"2022-01-28\"\nwebsite: \"https://conf2020.solidus.io/solidus-conf-7-solid-us-support-open-source/\"\ncoordinates: false\n"
  },
  {
    "path": "data/solidusconf/solidusconf-2022/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/southeast-ruby/series.yml",
    "content": "---\nname: \"Southeast Ruby\"\nwebsite: \"https://southeastruby.com\"\ntwitter: \"southeastruby\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/southeast-ruby/southeast-ruby-2017/event.yml",
    "content": "# https://jasoncharnes.com/organizing-southeast-ruby\n---\nid: \"southeast-ruby-2017\"\ntitle: \"Southeast Ruby 2017\"\ndescription: \"\"\nlocation: \"Nashville, TN, United States\"\nkind: \"conference\"\nstart_date: \"2017-10-05\"\nend_date: \"2017-10-06\"\nwebsite: \"https://2017.southeastruby.com\"\ntwitter: \"southeastruby\"\nplaylist: \"https://www.youtube.com/watch?v=5wI0ss02leo&list=PLRO4gNnSWQ4LSAVV7_7BliuoFCRHIqVk0\"\nfeatured_background: \"#EDE2CF\"\nfeatured_color: \"#3F3F3F\"\nbanner_background: \"#EDE2CF\"\ncoordinates:\n  latitude: 36.137789\n  longitude: -86.806249\n"
  },
  {
    "path": "data/southeast-ruby/southeast-ruby-2017/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jason Charnes\n"
  },
  {
    "path": "data/southeast-ruby/southeast-ruby-2017/schedule.yml",
    "content": "# Schedule: https://web.archive.org/web/20171007124452/https://southeastruby.com/\n---\ndays:\n  - name: \"Thursday, October 5th\"\n    date: \"2017-10-05\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n\n      - start_time: \"09:15\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:30\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n\n      - start_time: \"14:00\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"17:00\"\n        slots: 1\n\n  - name: \"Friday, October 6th\"\n    date: \"2017-10-06\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"12:00\"\n        slots: 1\n\n      - start_time: \"12:00\"\n        end_time: \"12:30\"\n        slots: 1\n\n      - start_time: \"12:30\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:30\"\n        end_time: \"16:30\"\n        slots: 1\n\n      - start_time: \"16:30\"\n        end_time: \"17:30\"\n        slots: 1\n\ntracks: []\n"
  },
  {
    "path": "data/southeast-ruby/southeast-ruby-2017/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      level: 1\n      sponsors:\n        - name: \"Honeybadger\"\n          website: \"https://honeybadger.io/\"\n          slug: \"Honeybadger\"\n          logo_url: \"https://2017.southeastruby.com/images/sponsors/honeybadger.svg\"\n\n        - name: \"Ramsey Solutions\"\n          website: \"https://www.daveramsey.com/\"\n          slug: \"RamseySolutions\"\n          logo_url: \"https://2017.southeastruby.com/images/sponsors/ramsey.png\"\n\n        - name: \"Clear Function\"\n          website: \"https://clearfunction.com/\"\n          slug: \"ClearFunction\"\n          logo_url: \"https://2017.southeastruby.com/images/sponsors/clearfunction.png\"\n\n        - name: \"Icelab\"\n          website: \"https://www.icelab.com.au/\"\n          slug: \"Icelab\"\n          logo_url: \"https://2017.southeastruby.com/images/sponsors/icelab.svg\"\n\n        - name: \"Prompt\"\n          website: \"https://mhprompt.org/\"\n          slug: \"Prompt\"\n          logo_url: \"https://2017.southeastruby.com/images/sponsors/prompt.png\"\n\n        - name: \"OmbuLabs\"\n          website: \"https://www.ombulabs.com/\"\n          slug: \"OmbuLabs\"\n          logo_url: \"https://2017.southeastruby.com/images/sponsors/ombulabs.png\"\n"
  },
  {
    "path": "data/southeast-ruby/southeast-ruby-2017/venue.yml",
    "content": "---\nname: \"Ruby\"\naddress:\n  street: \"2411 Blakemore Ave\"\n  city: \"Nashville\"\n  region: \"TN\"\n  postal_code: \"37212\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"2411 Blakemore Ave, Nashville, TN 37212\"\ncoordinates:\n  latitude: 36.137789\n  longitude: -86.806249\nmaps:\n  google: \"https://maps.app.goo.gl/be8F53XXPV7xag7HA\"\n  apple:\n    \"https://maps.apple.com/place?address=2411%20Blakemore%20Ave,%20Nashville,%20TN%20%2037212,%20United%20States&coordinate=36.137789,-86.806249&name=Ruby&place-id=I38ADCBD0F3\\\n    D11F9A&map=transit\"\n"
  },
  {
    "path": "data/southeast-ruby/southeast-ruby-2017/videos.yml",
    "content": "---\n## Day 1 - Thursday, October 5\n\n- id: \"jason-charnes-southeast-ruby-2017\"\n  title: \"Opening Remarks\"\n  speakers:\n    - Jason Charnes\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-05\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"jason-charnes-southeast-ruby-2017\"\n\n- id: \"ernie-miller-southeast-ruby-2017\"\n  title: \"Keynote\"\n  speakers:\n    - Ernie Miller\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-05\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"ernie-miller-southeast-ruby-2017\"\n\n- id: \"harisankar-p-s-southeast-ruby-2017\"\n  title: \"Using Databases to Pull Your Application Weight\"\n  raw_title: \"Harisankar P S - Using Databases to Pull Your Application Weight - Southeast Ruby 2017\"\n  speakers:\n    - Harisankar P S\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-05\"\n  description: |-\n    Harisankar P S - Using Databases to Pull Your Application Weight - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"cYzgXir0zg4\"\n  published_at: \"2018-07-31\"\n\n- id: \"adam-cuppy-southeast-ruby-2017\"\n  title: \"Pluck It\"\n  raw_title: \"Adam Cuppy - Pluck It - Southeast Ruby 2017\"\n  speakers:\n    - Adam Cuppy\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-05\"\n  description: |-\n    Adam Cuppy - Pluck It - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"-uFQAvpNn9E\"\n  published_at: \"2018-07-31\"\n\n- id: \"ernesto-tagwerker-southeast-ruby-2017\"\n  title: \"Open Source: When Nights & Weekends Are Not Enough\"\n  raw_title: \"Ernesto Tagwerker - Open Source: When Nights & Weekends Are Not Enough - Southeast Ruby 2017\"\n  speakers:\n    - Ernesto Tagwerker\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-05\"\n  description: |-\n    Ernesto Tagwerker - Open Source: When Nights & Weekends Are Not Enough - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"MOJoF7sPVdM\"\n  published_at: \"2018-07-31\"\n\n- id: \"daniel-pritchett-southeast-ruby-2017\"\n  title: \"Building Chatbot Skills and (Easily) Publishing Them as Gems\"\n  raw_title: \"Daniel Pritchett - Publishing Them as Gems - Southeast Ruby 2017\"\n  speakers:\n    - Daniel Pritchett\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-05\"\n  description: |-\n    Daniel Pritchett - Publishing Them as Gems - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"HVc-FgRIJU8\"\n  published_at: \"2018-07-31\"\n  slides_url: \"https://github.com/dpritchett/slides/tree/master/building-chatbot-skills\"\n\n- id: \"caleb-matthiesen-southeast-ruby-2017\"\n  title: \"Motorcycles and the Art of Software Maintenance\"\n  raw_title: \"Caleb Matthiesen - Motorcycles and the Art of Software Maintenance - Southeast Ruby 2017\"\n  speakers:\n    - Caleb Matthiesen\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-05\"\n  description: |-\n    Caleb Matthiesen - Motorcycles and the Art of Software Maintenance - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"FGKgxdCBejU\"\n  published_at: \"2018-07-31\"\n\n- id: \"kinsey-ann-durham-southeast-ruby-2017\"\n  title: \"Keynote\"\n  raw_title: \"Kinsey Ann Durham - Keynote - Southeast Ruby 2017\"\n  speakers:\n    - Kinsey Ann Durham\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-05\"\n  description: |-\n    Kinsey Ann Durham - Keynote - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"lN_0ZhpxJXg\"\n  published_at: \"2018-07-31\"\n\n## Day 2 - Friday, October 6\n\n- id: \"ben-orenstein-southeast-ruby-2017\"\n  title: \"Keynote: Trust, but Verify\"\n  raw_title: \"Ben Orenstein - Trust, but Verify - Southeast Ruby 2017\"\n  speakers:\n    - Ben Orenstein\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-06\"\n  description: |-\n    Ben Orenstein - Trust, but Verify - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"xSJMhfy5BBQ\"\n  published_at: \"2018-07-30\"\n\n- id: \"adam-niedzielski-southeast-ruby-2017\"\n  title: \"Boring Ruby Code\"\n  raw_title: \"Adam Niedzielski - Boring Ruby Code - Southeast Ruby 2017\"\n  speakers:\n    - Adam Niedzielski\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-06\"\n  description: |-\n    Adam Niedzielski - Boring Ruby Code - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"t9x3-6ZQ7xY\"\n  published_at: \"2018-07-30\"\n\n- id: \"tim-riley-southeast-ruby-2017\"\n  title: \"Real-world Functional Ruby\"\n  raw_title: \"Tim Riley - Real-world Functional Ruby - Southeast Ruby 2017\"\n  speakers:\n    - Tim Riley\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-06\"\n  description: |-\n    Tim Riley - Real-world Functional Ruby - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"4p4LE9J5bWA\"\n  published_at: \"2018-07-30\"\n\n- id: \"damir-svrtan-southeast-ruby-2017\"\n  title: \"Stateless Auth with JSON Web Tokens\"\n  raw_title: \"Damir Svrtan - Stateless Auth w/ JSON Web Tokens - Southeast Ruby 2017\"\n  speakers:\n    - Damir Svrtan\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-06\"\n  description: |-\n    Damir Svrtan - Stateless Auth w/ JSON Web Tokens - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"-PGDnX5PYYM\"\n  published_at: \"2018-07-30\"\n\n- id: \"mary-thengvall-southeast-ruby-2017\"\n  title: \"The Care and Monitoring of You\"\n  raw_title: \"Mary Thengvall - Monitoring the Health of Self - Southeast Ruby 2017\"\n  speakers:\n    - Mary Thengvall\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-06\"\n  description: |-\n    Mary Thengvall - Monitoring the Health of Self - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"DTxGfWTLkbs\"\n  published_at: \"2018-07-30\"\n\n- id: \"brad-urani-southeast-ruby-2017\"\n  title: \"Building HUGE Web Apps: Rails at 1,000,000 Lines of Code\"\n  raw_title: \"Brad Urani - Building HUGE Web Apps: Rails at 1,000,000 Lines of Code - Southeast Ruby 2017\"\n  speakers:\n    - Brad Urani\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-06\"\n  description: |-\n    Brad Urani - Building HUGE Web Apps: Rails at 1,000,000 Lines of Code - Southeast Ruby 2017\n  video_provider: \"youtube\"\n  video_id: \"Yz4wFqnKYBY\"\n  published_at: \"2018-07-30\"\n\n- id: \"josh-lewis-southeast-ruby-2017\"\n  title: \"Skinny Models, Skinny Controllers\"\n  speakers:\n    - Josh Lewis\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-06\"\n  description: \"\"\n  video_provider: \"not_published\"\n  video_id: \"josh-lewis-southeast-ruby-2017\"\n\n- id: \"avdi-grimm-southeast-ruby-2017\"\n  title: \"Keynote: No Code\"\n  raw_title: \"Avdi Grimm - No Code - Southeast Ruby 2017\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"Southeast Ruby 2017\"\n  date: \"2017-10-06\"\n  description: |-\n    Avdi Grimm - No Code - Southeast Ruby 2017 in Nashville, TN\n  video_provider: \"youtube\"\n  video_id: \"5wI0ss02leo\"\n  published_at: \"2018-07-05\"\n"
  },
  {
    "path": "data/southeast-ruby/southeast-ruby-2018/event.yml",
    "content": "---\nid: \"southeast-ruby-2018\"\ntitle: \"Southeast Ruby 2018\"\ndescription: \"\"\nlocation: \"Nashville, TN, United States\"\nkind: \"conference\"\nstart_date: \"2018-08-02\"\nend_date: \"2018-08-03\"\nwebsite: \"https://2018.southeastruby.com/\"\ntwitter: \"southeastruby\"\nplaylist: \"https://www.youtube.com/watch?v=-JpAUN6Ovok&list=PLRO4gNnSWQ4JNwiS-MyfIIejk2R_Y6UKR\"\ncoordinates:\n  latitude: 36.1626638\n  longitude: -86.7816016\n"
  },
  {
    "path": "data/southeast-ruby/southeast-ruby-2018/videos.yml",
    "content": "# Website: https://southeastruby.com/\n# Videos: https://www.youtube.com/watch?v=-JpAUN6Ovok&list=PLRO4gNnSWQ4JNwiS-MyfIIejk2R_Y6UKR\n---\n# Day 1 - Thursday, August 2, 2018\n\n- id: \"erin-page-southeast-ruby-2018\"\n  title: \"Keynote: Ruby is Dead, Long Live Ruby\"\n  description: \"\"\n  raw_title: \"Erin Page - Keynote - Ruby is Dead, Long Live Ruby - Southeast Ruby 2018\"\n  speakers:\n    - \"Erin Page\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-02\"\n  published_at: \"2018-12-21\"\n  video_provider: \"youtube\"\n  video_id: \"MWHgyeIXFWM\"\n\n- id: \"vladimir-dementyev-southeast-ruby-2018\"\n  title: \"The Gem Check: writing better Ruby gems\"\n  description: \"\"\n  speakers:\n    - \"Vladimir Dementyev\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-02\"\n  video_provider: \"not_recorded\"\n  video_id: \"vladimir-dementyev-southeast-ruby-2018\"\n\n- id: \"noah-gibbs-southeast-ruby-2018\"\n  title: \"Make Ruby 2.6 Faster with JIT!\"\n  description: \"\"\n  speakers:\n    - \"Noah Gibbs\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-02\"\n  video_provider: \"not_recorded\"\n  video_id: \"noah-gibbs-southeast-ruby-2018\"\n\n- id: \"beth-haubert-southeast-ruby-2018\"\n  title: \"Cats, The Musical! Algorithmic Song Meow-ification\"\n  description: \"\"\n  speakers:\n    - \"Beth Haubert\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-02\"\n  video_provider: \"not_recorded\"\n  video_id: \"beth-haubert-southeast-ruby-2018\"\n\n- id: \"joe-ferguson-southeast-ruby-2018\"\n  title: \"The open source talk that changed my life wasn't technical\"\n  description: \"\"\n  speakers:\n    - \"Joe Ferguson\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-02\"\n  video_provider: \"not_recorded\"\n  video_id: \"joe-ferguson-southeast-ruby-2018\"\n\n- id: \"seema-ullal-southeast-ruby-2018\"\n  title: \"Writing Lovable Code\"\n  description: \"\"\n  speakers:\n    - \"Seema Ullal\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-02\"\n  video_provider: \"not_recorded\"\n  video_id: \"seema-ullal-southeast-ruby-2018\"\n\n- id: \"nickolas-means-southeast-ruby-2018\"\n  title: \"Keynote: Eiffel's Tower\"\n  description: \"\"\n  raw_title: \"Nickolas Means - Keynote - Eiffel's Tower - Southeast Ruby 2018\"\n  speakers:\n    - \"Nickolas Means\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-02\"\n  published_at: \"2018-09-18\"\n  video_provider: \"youtube\"\n  video_id: \"F0sSicux-FM\"\n\n# Day 2 - Friday, August 3, 2018\n\n- id: \"brittany-martin-southeast-ruby-2018\"\n  title: \"Rails Against the Machine\"\n  description: \"\"\n  speakers:\n    - \"Brittany Martin\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-03\"\n  video_provider: \"not_recorded\"\n  video_id: \"brittany-martin-southeast-ruby-2018\"\n\n- id: \"paul-stefan-ort-southeast-ruby-2018\"\n  title: \"Reflection in Ruby: Understanding the Implications of Loading Gems and Files\"\n  description: \"\"\n  speakers:\n    - \"Paul Stefan Ort\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-03\"\n  video_provider: \"not_recorded\"\n  video_id: \"paul-stefan-ort-southeast-ruby-2018\"\n\n- id: \"christopher-coleman-southeast-ruby-2018\"\n  title: \"Repositories in Rails\"\n  description: \"\"\n  speakers:\n    - \"Christopher Coleman\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-03\"\n  video_provider: \"not_recorded\"\n  video_id: \"christopher-coleman-southeast-ruby-2018\"\n\n- id: \"brandon-weaver-southeast-ruby-2018\"\n  title: \"Reducing Enumerable - An Illustrated Adventure\"\n  description: \"\"\n  speakers:\n    - \"Brandon Weaver\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-03\"\n  video_provider: \"not_recorded\"\n  video_id: \"brandon-weaver-southeast-ruby-2018\"\n\n- id: \"craig-kerstiens-southeast-ruby-2018\"\n  title: \"Postgres at any scale\"\n  description: \"\"\n  speakers:\n    - \"Craig Kerstiens\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-03\"\n  video_provider: \"not_recorded\"\n  video_id: \"craig-kerstiens-southeast-ruby-2018\"\n\n- id: \"tom-ridge-southeast-ruby-2018\"\n  title: \"Your story matters.\"\n  description: \"\"\n  speakers:\n    - \"Tom Ridge\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-03\"\n  video_provider: \"not_recorded\"\n  video_id: \"tom-ridge-southeast-ruby-2018\"\n\n- id: \"avdi-grimm-southeast-ruby-2018\"\n  title: \"Keynote: OOPS\"\n  description: \"\"\n  raw_title: \"Avdi Grimm - Keynote - OOPS - Southeast Ruby 2018\"\n  speakers:\n    - \"Avdi Grimm\"\n  event_name: \"Southeast Ruby 2018\"\n  date: \"2018-08-03\"\n  published_at: \"2018-08-16\"\n  video_provider: \"youtube\"\n  video_id: \"-JpAUN6Ovok\"\n"
  },
  {
    "path": "data/southeast-ruby/southeast-ruby-2019/event.yml",
    "content": "---\nid: \"southeast-ruby-2019\"\ntitle: \"Southeast Ruby 2019\"\ndescription: \"\"\nlocation: \"Nashville, TN, United States\"\nkind: \"conference\"\nstart_date: \"2019-08-01\"\nend_date: \"2019-08-02\"\nwebsite: \"https://2019.southeastruby.com/\"\ntwitter: \"southeastruby\"\ncoordinates:\n  latitude: 36.1626638\n  longitude: -86.7816016\n"
  },
  {
    "path": "data/southeast-ruby/southeast-ruby-2019/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://southeastruby.com/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/speakers.yml",
    "content": "---\n- name: \"Aanand Prasad\"\n  github: \"aanand\"\n  slug: \"aanand-prasad\"\n- name: \"Aaron Batalion\"\n  github: \"aaronbatalion\"\n  website: \"http://aaronbatalion.com\"\n  slug: \"aaron-batalion\"\n- name: \"Aaron Bedra\"\n  twitter: \"abedra\"\n  github: \"abedra\"\n  website: \"http://aaronbedra.com\"\n  slug: \"aaron-bedra\"\n- name: \"Aaron Cruz\"\n  twitter: \"mraaroncruz\"\n  github: \"mraaroncruz\"\n  website: \"https://aaroncruz.com\"\n  slug: \"aaron-cruz\"\n- name: \"Aaron Grey\"\n  github: \"aarongrey\"\n  slug: \"aaron-grey\"\n- name: \"Aaron Harpole\"\n  github: \"aharpole\"\n  website: \"http://icanthascheezburger.com\"\n  slug: \"aaron-harpole\"\n- name: \"Aaron Kalin\"\n  github: \"martinisoft\"\n  slug: \"aaron-kalin\"\n- name: \"Aaron Lasseigne\"\n  github: \"AaronLasseigne\"\n  slug: \"aaron-lasseigne\"\n- name: \"Aaron Patterson\"\n  twitter: \"tenderlove\"\n  github: \"tenderlove\"\n  website: \"https://tenderlovemaking.com/\"\n  slug: \"aaron-patterson\"\n- name: \"Aaron Pfeifer\"\n  github: \"obrie\"\n  website: \"http://www.aaronpfeifer.com\"\n  slug: \"aaron-pfeifer\"\n- name: \"Aaron Quint\"\n  github: \"quirkey\"\n  website: \"http://www.quirkey.com/blog\"\n  slug: \"aaron-quint\"\n- name: \"Aaron Rosenberg\"\n  github: \"agrberg\"\n  slug: \"aaron-rosenberg\"\n- name: \"Aaron Suggs\"\n  twitter: \"ktheory\"\n  github: \"ktheory\"\n  website: \"https://ktheory.com/\"\n  slug: \"aaron-suggs\"\n- name: \"Aarti Parikh\"\n  github: \"\"\n  slug: \"aarti-parikh\"\n- name: \"Abel Martin\"\n  github: \"abelmartin\"\n  slug: \"abel-martin\"\n- name: \"Abhijeet Anand\"\n  github: \"\"\n  slug: \"abhijeet-anand\"\n- name: \"Abhishek Pillai\"\n  twitter: \"abhiondemand\"\n  github: \"abhishekpillai\"\n  slug: \"abhishek-pillai\"\n- name: \"Abiodun Olowode\"\n  twitter: \"abiodunajibade3\"\n  github: \"tripple-a\"\n  website: \"https://abiodun.tech\"\n  slug: \"abiodun-olowode\"\n- name: \"Aboobacker MK\"\n  twitter: \"_tachyons\"\n  github: \"tachyons\"\n  slug: \"aboobacker-mk\"\n- name: \"Abraham Sangha\"\n  github: \"abrahamsangha\"\n  website: \"http://abrahamsangha.github.io/\"\n  slug: \"abraham-sangha\"\n- name: \"Adam Blum\"\n  github: \"adamblum\"\n  slug: \"adam-blum\"\n- name: \"Adam Butler\"\n  github: \"adambutler\"\n  slug: \"adam-butler\"\n- name: \"Adam Cuppy\"\n  twitter: \"adamcuppy\"\n  github: \"acuppy\"\n  website: \"https://adamcuppy.com\"\n  slug: \"adam-cuppy\"\n- name: \"Adam Daniels\"\n  twitter: \"adamrdaniels\"\n  github: \"adam12\"\n  website: \"https://adamdaniels.ca\"\n  slug: \"adam-daniels\"\n- name: \"Adam Dawkins\"\n  github: \"\"\n  slug: \"adam-dawkins\"\n- name: \"Adam E. Hampton\"\n  github: \"adam-hampton-sp\"\n  slug: \"adam-e-hampton\"\n- name: \"Adam Fields\"\n  github: \"\"\n  slug: \"adam-fields\"\n- name: \"Adam Forsyth\"\n  github: \"agfor\"\n  slug: \"adam-forsyth\"\n- name: \"Adam Hawkins\"\n  twitter: \"ahawkins\"\n  github: \"ahawkins\"\n  website: \"https://hawkins.io\"\n  slug: \"adam-hawkins\"\n- name: \"Adam Hess\"\n  twitter: \"theHessParker\"\n  github: \"hparker\"\n  website: \"https://hparker.xyz/\"\n  slug: \"adam-hess\"\n- name: \"Adam Hodowany\"\n  twitter: \"adhodak\"\n  github: \"hodak\"\n  website: \"http://hodak.pl\"\n  slug: \"adam-hodowany\"\n- name: \"Adam Jahn\"\n  github: \"ajjahn\"\n  website: \"http://www.adamjahn.com\"\n  slug: \"adam-jahn\"\n- name: \"Adam Jonas\"\n  github: \"aj8gh\"\n  slug: \"adam-jonas\"\n- name: \"Adam Kalsey\"\n  github: \"\"\n  slug: \"adam-kalsey\"\n- name: \"Adam Keys\"\n  github: \"therealadam\"\n  website: \"http://therealadam.com\"\n  slug: \"adam-keys\"\n- name: \"Adam McCrea\"\n  twitter: \"adamlogic\"\n  github: \"adamlogic\"\n  website: \"https://railsautoscale.com\"\n  slug: \"adam-mccrea\"\n- name: \"Adam Niedzielski\"\n  github: \"adamniedzielski\"\n  website: \"http://blog.sundaycoding.com\"\n  slug: \"adam-niedzielski\"\n- name: \"Adam Okoń\"\n  github: \"aokon\"\n  slug: \"adam-okon\"\n- name: \"Adam Pallozzi\"\n  twitter: \"adampallozzi\"\n  github: \"adampal\"\n  slug: \"adam-pallozzi\"\n- name: \"Adam Piotrowski\"\n  github: \"panSarin\"\n  slug: \"adam-piotrowski\"\n- name: \"Adam Pohorecki\"\n  twitter: \"apohorecki\"\n  github: \"psyho\"\n  website: \"http://adam.pohorecki.pl\"\n  slug: \"adam-pohorecki\"\n- name: \"Adam Rice\"\n  github: \"\"\n  slug: \"adam-rice\"\n- name: \"Adam Sanderson\"\n  github: \"adamsanderson\"\n  website: \"https://monkeyandcrow.com\"\n  slug: \"adam-sanderson\"\n- name: \"Adam Skołuda\"\n  twitter: \"Skoda091\"\n  github: \"skoda091\"\n  website: \"https://twitter.com/Skoda091\"\n  slug: \"adam-skoluda\"\n- name: \"Adam Stacoviak\"\n  github: \"\"\n  slug: \"adam-stacoviak\"\n- name: \"Adam Walker\"\n  github: \"adamwalker\"\n  website: \"https://adamwalker.github.io/\"\n  slug: \"adam-walker\"\n- name: \"Adam Wathan\"\n  github: \"adamwathan\"\n  slug: \"adam-wathan\"\n- name: \"Adam Wiggins\"\n  github: \"adamwiggins\"\n  slug: \"adam-wiggins\"\n- name: \"Adarsh Pandit\"\n  twitter: \"adarshp\"\n  github: \"adarsh\"\n  website: \"http://cylinder.digital\"\n  slug: \"adarsh-pandit\"\n- name: \"Adel Smee\"\n  github: \"adelsmee\"\n  slug: \"adel-smee\"\n- name: \"Aditya Godbole\"\n  github: \"\"\n  slug: \"aditya-godbole\"\n- name: \"Aditya Mukerjee\"\n  github: \"chimeracoder\"\n  website: \"http://www.adityamukerjee.net\"\n  slug: \"aditya-mukerjee\"\n- name: \"Adrian Goh\"\n  github: \"adriangohjw\"\n  slug: \"adrian-goh\"\n  aliases:\n    - name: \"Adrian Goh Jun Wei\"\n      slug: \"adrian-goh-jun-wei\"\n- name: \"Adrian Marin\"\n  twitter: \"adrianthedev\"\n  github: \"adrianthedev\"\n  website: \"https://adrianthedev.com\"\n  slug: \"adrian-marin\"\n- name: \"Adrian Pike\"\n  github: \"adrianpike\"\n  slug: \"adrian-pike\"\n- name: \"Adrian Valenzuela\"\n  twitter: \"adrianvalenz_\"\n  github: \"adrianvalenz\"\n  website: \"https://www.adrianvalenz.com\"\n  slug: \"adrian-valenzuela\"\n- name: \"Adrian Zankich\"\n  github: \"zankich\"\n  slug: \"adrian-zankich\"\n- name: \"Adrianna Chang\"\n  twitter: \"adriannakchang\"\n  github: \"adrianna-chang-shopify\"\n  website: \"https://adriannachang.me\"\n  slug: \"adrianna-chang\"\n- name: \"Adrien Montagu\"\n  github: \"amontagu\"\n  website: \"http://adrienmontagu.com/\"\n  slug: \"adrien-montagu\"\n- name: \"Adrien Poly\"\n  github: \"\"\n  slug: \"adrien-poly\"\n- name: \"Adrien Siami\"\n  twitter: \"Intrepidd\"\n  github: \"intrepidd\"\n  website: \"https://blog.siami.fr\"\n  slug: \"adrien-siami\"\n- name: \"Adrián Mugnolo\"\n  github: \"xymbol\"\n  slug: \"adrian-mugnolo\"\n- name: \"Adviti Mishra\"\n  github: \"adviti-mishra\"\n  slug: \"adviti-mishra\"\n- name: \"Agathe Begault\"\n  github: \"begault\"\n  slug: \"agathe-begault\"\n- name: \"Agnieszka Małaszkiewicz\"\n  github: \"\"\n  slug: \"agnieszka-malaszkiewicz\"\n- name: \"Agus Fornio\"\n  github: \"\"\n  slug: \"agus-fornio\"\n- name: \"Agustin Peluffo\"\n  github: \"agustin-peluffo\"\n  slug: \"agustin-peluffo\"\n- name: \"Ahmad Elassuty\"\n  github: \"ahmad-elassuty\"\n  slug: \"ahmad-elassuty\"\n- name: \"Ahmed El Bialy\"\n  github: \"aelbialy\"\n  slug: \"ahmed-el-bialy\"\n- name: \"Ahmed Omran\"\n  github: \"aomran\"\n  website: \"http://www.aomran.com\"\n  slug: \"ahmed-omran\"\n- name: \"Ahmet Kaptan\"\n  github: \"codescaptain\"\n  slug: \"ahmet-kaptan\"\n- name: \"ahogappa\"\n  github: \"ahogappa\"\n  slug: \"ahogappa\"\n- name: \"Aidan Rudkovskyi\"\n  github: \"\"\n  slug: \"aidan-rudkovskyi\"\n- name: \"Aimee Simone\"\n  github: \"\"\n  slug: \"aimee-simone\"\n- name: \"Aitor Garcia Rey\"\n  twitter: \"_aitor\"\n  github: \"aitor\"\n  website: \"http://aitor.is\"\n  slug: \"aitor-garcia-rey\"\n- name: \"Aja Hammerly\"\n  twitter: \"the_thagomizer\"\n  github: \"thagomizer\"\n  website: \"http://www.thagomizer.com\"\n  slug: \"aja-hammerly\"\n- name: \"Ajey Gore\"\n  github: \"ajeygore\"\n  slug: \"ajey-gore\"\n- name: \"Akanksha Agarwal\"\n  github: \"Akanksha08\"\n  slug: \"akanksha-agarwal\"\n- name: \"Akash Chhetri\"\n  github: \"\"\n  slug: \"akash-chhetri\"\n- name: \"Aki Teliö\"\n  github: \"\"\n  slug: \"aki-telio\"\n- name: \"Akihito Uesada\"\n  github: \"\"\n  slug: \"akihito-uesada\"\n- name: \"Akiko Takano\"\n  github: \"\"\n  slug: \"akiko-takano\"\n- name: \"Akira Matsuda\"\n  twitter: \"a_matsuda\"\n  github: \"amatsuda\"\n  website: \"https://twitter.com/a_matsuda\"\n  slug: \"akira-matsuda\"\n- name: \"Akira Yagi\"\n  github: \"akira888\"\n  slug: \"akira-yagi\"\n- name: \"Al Gray\"\n  github: \"\"\n  slug: \"al-gray\"\n- name: \"Alaina Kafkes\"\n  github: \"\"\n  slug: \"alaina-kafkes\"\n- name: \"Alaina Percival\"\n  twitter: \"alaina\"\n  github: \"alaina\"\n  slug: \"alaina-percival\"\n- name: \"Alam Kasenally\"\n  github: \"\"\n  slug: \"alam-kasenally\"\n- name: \"Alan Bridger\"\n  github: \"\"\n  slug: \"alan-bridger\"\n- name: \"Alan Cohen\"\n  twitter: \"fwdstationdev\"\n  github: \"alandotcom\"\n  slug: \"alan-cohen\"\n- name: \"Alan Ridlehoover\"\n  github: \"aridlehoover\"\n  website: \"https://the.codegardener.com\"\n  slug: \"alan-ridlehoover\"\n- name: \"Alan Skorkin\"\n  github: \"skorks\"\n  website: \"http://www.skorks.com\"\n  slug: \"alan-skorkin\"\n- name: \"Alan Wu\"\n  twitter: \"alanwusx\"\n  github: \"xrxr\"\n  website: \"https://alanwu.space/\"\n  slug: \"alan-wu\"\n- name: \"Albert Brandolini\"\n  github: \"\"\n  slug: \"albert-brandolini\"\n- name: \"Albert Pai\"\n  github: \"apai4\"\n  slug: \"albert-pai\"\n- name: \"Albert Pazderin\"\n  github: \"bakaface\"\n  slug: \"albert-pazderin\"\n- name: \"Albert Song\"\n  github: \"\"\n  slug: \"albert-song\"\n- name: \"Alberto Barillà\"\n  github: \"\"\n  slug: \"alberto-barilla\"\n- name: \"Alberto Brandolini\"\n  twitter: \"ziobrando\"\n  github: \"ziobrando\"\n  website: \"http://ziobrando.blogspot.com\"\n  slug: \"alberto-brandolini\"\n- name: \"Alberto Colón Viera\"\n  twitter: \"alberti_co\"\n  github: \"albertico\"\n  slug: \"alberto-colon-viera\"\n- name: \"Alberto Leal\"\n  twitter: \"albertoleal\"\n  github: \"albertoleal\"\n  website: \"https://www.aleal.dev\"\n  slug: \"alberto-leal\"\n- name: \"Alberto Morales\"\n  github: \"\"\n  slug: \"alberto-morales\"\n- name: \"Alec Clarke\"\n  github: \"alecclarke\"\n  slug: \"alec-clarke\"\n- name: \"Alejandro Cadavid\"\n  github: \"acadavid\"\n  website: \"https://www.alcaisa.com\"\n  slug: \"alejandro-cadavid\"\n- name: \"Alejandro Corpeño\"\n  github: \"corp\"\n  slug: \"alejandro-corpeno\"\n- name: \"Alekander\"\n  github: \"\"\n  slug: \"alekander\"\n- name: \"Aleks Yanchuk\"\n  github: \"\"\n  slug: \"aleks-yanchuk\"\n- name: \"Aleksander Dąbrowski\"\n  github: \"tjeden\"\n  website: \"https://rubysfera.pl\"\n  slug: \"aleksander-dabrowski\"\n- name: \"Aleksander Kirillov\"\n  github: \"\"\n  slug: \"aleksander-kirillov\"\n- name: \"Aleksandr Kunin\"\n  github: \"skyksandr\"\n  slug: \"aleksandr-kunin\"\n- name: \"Alessandro Cinelli\"\n  github: \"\"\n  slug: \"alessandro-cinelli\"\n- name: \"Alessandro Fazzi\"\n  github: \"alessandro-fazzi\"\n  website: \"https://dev.welaika.com\"\n  slug: \"alessandro-fazzi\"\n- name: \"Alessandro Lepore\"\n  github: \"alepore\"\n  slug: \"alessandro-lepore\"\n- name: \"Alessandro Rizzo\"\n  github: \"arizz96\"\n  website: \"https://www.arizz96.dev/\"\n  slug: \"alessandro-rizzo\"\n- name: \"Alessandro Rodi\"\n  twitter: \"coorasse\"\n  github: \"coorasse\"\n  website: \"https://dev.to/coorasse\"\n  slug: \"alessandro-rodi\"\n- name: \"Alex Balhatchet\"\n  twitter: \"kaokun\"\n  github: \"kaoru\"\n  slug: \"alex-balhatchet\"\n- name: \"Alex Boster\"\n  github: \"tilthouse\"\n  slug: \"alex-boster\"\n- name: \"Alex Chaffee\"\n  github: \"alexch\"\n  website: \"http://alexch.github.com\"\n  slug: \"alex-chaffee\"\n- name: \"Alex Chan\"\n  github: \"\"\n  slug: \"alex-chan\"\n- name: \"Alex Coles\"\n  github: \"alexjcoles\"\n  slug: \"alex-coles\"\n- name: \"Alex Coomans\"\n  github: \"drcapulet\"\n  website: \"http://alexcoomans.com\"\n  slug: \"alex-coomans\"\n- name: \"Alex Evanczuk\"\n  github: \"alexevanczuk\"\n  slug: \"alex-evanczuk\"\n- name: \"Alex Jahraus\"\n  github: \"fanaugen\"\n  slug: \"alex-jahraus\"\n- name: \"Alex Kitchens\"\n  github: \"alexcameron89\"\n  website: \"http://alexkitchens.net\"\n  slug: \"alex-kitchens\"\n- name: \"Alex Koppel\"\n  github: \"arsduo\"\n  slug: \"alex-koppel\"\n- name: \"Alex MacCaw\"\n  github: \"maboroshi\"\n  slug: \"alex-maccaw\"\n- name: \"Alex Nguyen\"\n  github: \"\"\n  slug: \"alex-nguyen\"\n- name: \"Alex Peattie\"\n  github: \"alexpeattie\"\n  website: \"https://alexpeattie.com\"\n  slug: \"alex-peattie\"\n- name: \"Alex Qin\"\n  github: \"noidontdig\"\n  website: \"http://alexq.in\"\n  slug: \"alex-qin\"\n- name: \"Alex Reiff\"\n  github: \"alexreiff\"\n  slug: \"alex-reiff\"\n- name: \"Alex Robinson\"\n  github: \"a-robinson\"\n  website: \"https://twitter.com/alexwritescode\"\n  slug: \"alex-robinson\"\n- name: \"Alex Rodionov\"\n  github: \"p0deje\"\n  slug: \"alex-rodionov\"\n- name: \"Alex Rudall\"\n  github: \"alexrudall\"\n  slug: \"alex-rudall\"\n- name: \"Alex Sharp\"\n  twitter: \"ajsharp\"\n  github: \"ajsharp\"\n  website: \"https://ajsharp.com\"\n  slug: \"alex-sharp\"\n- name: \"Alex Stephen\"\n  twitter: \"rambleraptor\"\n  github: \"rambleraptor\"\n  website: \"https://alexstephen.me\"\n  slug: \"alex-stephen\"\n- name: \"Alex Sunderland\"\n  twitter: \"felltir\"\n  github: \"agentantelope\"\n  slug: \"alex-sunderland\"\n  aliases:\n    - name: \"fell Sunderland\"\n      slug: \"fell-sunderland\"\n    - name: \"Fell Sunderland\"\n      slug: \"fell-sunderland\"\n    - name: \"fell sunderland\"\n      slug: \"fell-sunderland\"\n- name: \"Alex Timofeev\"\n  github: \"query-string\"\n  slug: \"alex-timofeev\"\n- name: \"Alex Topalov\"\n  github: \"sharkzp\"\n  website: \"https://sharkzp.github.io\"\n  slug: \"alex-topalov\"\n- name: \"Alex Watt\"\n  twitter: \"alexcwatt\"\n  github: \"alexcwatt\"\n  website: \"https://alexcwatt.com/\"\n  slug: \"alex-watt\"\n- name: \"Alex Wheeler\"\n  github: \"alexwheeler\"\n  website: \"https://www.alexwheeler.io\"\n  slug: \"alex-wheeler\"\n- name: \"Alex Wood\"\n  twitter: \"alexwwood\"\n  github: \"awood45\"\n  website: \"https://alexwood.codes\"\n  slug: \"alex-wood\"\n- name: \"Alex Yarotsky\"\n  github: \"ayarotsky\"\n  slug: \"alex-yarotsky\"\n  aliases:\n    - name: \"Alexander Yarotsky\"\n      slug: \"alexander-yarotsky\"\n- name: \"Alexander Baygeldin\"\n  github: \"baygeldin\"\n  slug: \"alexander-baygeldin\"\n- name: \"Alexander Biryukov\"\n  twitter: \"_AlexBiryukov_\"\n  github: \"sanbir\"\n  website: \"https://www.linkedin.com/in/biryukovalexander\"\n  slug: \"alexander-biryukov\"\n- name: \"Alexander Coles\"\n  github: \"\"\n  slug: \"alexander-coles\"\n- name: \"Alexander Dymo\"\n  github: \"adymo\"\n  website: \"http://www.alexdymo.com\"\n  slug: \"alexander-dymo\"\n- name: \"Alexander Fiedler\"\n  github: \"\"\n  slug: \"alexander-fiedler\"\n- name: \"Alexander Ivanov\"\n  github: \"alehander92\"\n  slug: \"alexander-ivanov\"\n- name: \"Alexander Jahraus\"\n  github: \"alex-jahraus-solaris\"\n  slug: \"alexander-jahraus\"\n- name: \"Alexander Kirillov\"\n  github: \"\"\n  slug: \"alexander-kirillov\"\n- name: \"Alexander Mitchell\"\n  twitter: \"a_t_mitch\"\n  github: \"a-mitch\"\n  website: \"https://a-mitch.github.io/\"\n  slug: \"alexander-mitchell\"\n- name: \"Alexander Momchilov\"\n  github: \"amomchilov\"\n  website: \"https://momchilov.ca\"\n  slug: \"alexander-momchilov\"\n- name: \"Alexander Nicholson\"\n  github: \"alexandernicholson\"\n  website: \"https://alexander.town\"\n  slug: \"alexander-nicholson\"\n- name: \"Alexander Repnikov\"\n  github: \"arepnikov\"\n  slug: \"alexander-repnikov\"\n- name: \"Alexander Shestakov\"\n  github: \"\"\n  slug: \"alexander-shestakov\"\n- name: \"Alexander Sulim\"\n  github: \"soulim\"\n  slug: \"alexander-sulim\"\n- name: \"Alexandra Leisse\"\n  twitter: \"troubalex\"\n  github: \"troubalex\"\n  website: \"https://troubalex.com\"\n  slug: \"alexandra-leisse\"\n- name: \"Alexandra Millatmal\"\n  github: \"halfghaninne\"\n  website: \"https://alexandramillatmal.com\"\n  slug: \"alexandra-millatmal\"\n- name: \"Alexandre Calaça\"\n  github: \"alexcalaca\"\n  website: \"https://dev.to/alexandrecalaca\"\n  slug: \"alexandre-calaca\"\n- name: \"Alexandre de Oliveira\"\n  github: \"\"\n  slug: \"alexandre-de-oliveira\"\n- name: \"Alexandre Ignjatovic\"\n  github: \"bankair\"\n  website: \"http://polymerisation-des-concepts.fr\"\n  slug: \"alexandre-ignjatovic\"\n- name: \"Alexandre Lairan\"\n  github: \"\"\n  slug: \"alexandre-lairan\"\n- name: \"Alexandre Terrasa\"\n  github: \"morriar\"\n  slug: \"alexandre-terrasa\"\n- name: \"Alexandru Călinoiu\"\n  github: \"alexandru-calinoiu\"\n  slug: \"alexandru-calinoiu\"\n  aliases:\n    - name: \"Alexandru Calinoiu\"\n      slug: \"alexandru-calinoiu\"\n- name: \"Alexey Gaziev\"\n  github: \"\"\n  slug: \"alexey-gaziev\"\n- name: \"Alexey Vasiliev\"\n  github: \"\"\n  slug: \"alexey-vasiliev\"\n  aliases:\n    - name: \"Oleksiy Vasyliev\"\n      slug: \"oleksiy-vasyliev\"\n- name: \"Alexis Bernard\"\n  github: \"alexisbernard\"\n  website: \"http://alexis.bernard.io\"\n  slug: \"alexis-bernard\"\n- name: \"Alexis Kalderimis\"\n  slug: \"alexis-kalderimis\"\n  github: \"alexkalderimis\"\n  aliases:\n    - name: \"Alex Kalderimis\"\n      slug: \"alex-kalderimis\"\n- name: \"Alfredo Motta\"\n  github: \"mottalrd\"\n  slug: \"alfredo-motta\"\n- name: \"Ali Hamidi\"\n  github: \"ahamidi\"\n  website: \"http://ahamidi.com\"\n  slug: \"ali-hamidi\"\n- name: \"Ali Ibrahim\"\n  twitter: \"ibrahim_0814\"\n  github: \"ibrahim0814\"\n  slug: \"ali-ibrahim\"\n- name: \"Ali Ilman\"\n  github: \"\"\n  slug: \"ali-ilman\"\n- name: \"Ali Krynitsky\"\n  github: \"\"\n  slug: \"ali-krynitsky\"\n- name: \"Ali Najaf\"\n  github: \"Najaf\"\n  slug: \"ali-najaf\"\n  aliases:\n    - name: \"Najaf Ali\"\n      slug: \"najaf-ali\"\n- name: \"Alicia Rojas\"\n  github: \"aliciaorojas\"\n  slug: \"alicia-rojas\"\n- name: \"Alina Leskova\"\n  github: \"alyales\"\n  slug: \"alina-leskova\"\n- name: \"Aline Lerner\"\n  github: \"\"\n  slug: \"aline-lerner\"\n- name: \"Alistair Coburn\"\n  github: \"\"\n  slug: \"alistair-coburn\"\n- name: \"Alistair Cockburn\"\n  github: \"\"\n  slug: \"alistair-cockburn\"\n- name: \"Alistair McKinnell\"\n  github: \"amckinnell\"\n  slug: \"alistair-mckinnell\"\n- name: \"Alistair Norman\"\n  github: \"alistairnorman\"\n  slug: \"alistair-norman\"\n- name: \"Allan Espinosa\"\n  github: \"aespinosa\"\n  website: \"http://espinosa.io\"\n  slug: \"allan-espinosa\"\n- name: \"Allan Grant\"\n  twitter: \"allangrant\"\n  github: \"allangrant\"\n  website: \"http://www.talkable.com\"\n  slug: \"allan-grant\"\n- name: \"Allan Ottis\"\n  github: \"\"\n  slug: \"allan-ottis\"\n- name: \"Allan Wazacz\"\n  github: \"\"\n  slug: \"allan-wazacz\"\n- name: \"Allen Hsu\"\n  github: \"\"\n  slug: \"allen-hsu\"\n- name: \"Alli Zadrozny\"\n  github: \"\"\n  slug: \"alli-zadrozny\"\n- name: \"Allison Hill\"\n  github: \"allisonshill\"\n  website: \"https://AllisonSHill.github.io\"\n  slug: \"allison-hill\"\n- name: \"Allison McMillan\"\n  github: \"asheren\"\n  website: \"http://www.daydreamsinruby.com\"\n  slug: \"allison-mcmillan\"\n- name: \"Allison Zadrozny\"\n  github: \"\"\n  slug: \"allison-zadrozny\"\n- name: \"Ally Vogel\"\n  github: \"\"\n  slug: \"ally-vogel\"\n- name: \"alpaca-tc\"\n  github: \"\"\n  slug: \"alpaca-tc\"\n- name: \"Aly Fulton\"\n  github: \"sinthetix\"\n  slug: \"aly-fulton\"\n- name: \"Alyssa Ross\"\n  github: \"alyssais\"\n  slug: \"alyssa-ross\"\n- name: \"Aman Gupta\"\n  github: \"gupta2140\"\n  slug: \"aman-gupta\"\n- name: \"Aman King\"\n  github: \"\"\n  slug: \"aman-king\"\n- name: \"Amanda Bizzinotto\"\n  github: \"\"\n  slug: \"amanda-bizzinotto\"\n- name: \"Amanda Casari\"\n  github: \"\"\n  slug: \"amanda-casari\"\n- name: \"Amanda Chang\"\n  github: \"changamanda\"\n  slug: \"amanda-chang\"\n- name: \"Amanda Lundberg\"\n  github: \"\"\n  slug: \"amanda-lundberg\"\n- name: \"Amanda Perino\"\n  twitter: \"AmandaBPerino\"\n  github: \"amandaperino\"\n  slug: \"amanda-perino\"\n- name: \"Amanda Quaranto\"\n  github: \"aquaranto\"\n  website: \"https://twitter.com/aquaranto\"\n  slug: \"amanda-quaranto\"\n- name: \"Amanda Vikdal\"\n  github: \"avikdal\"\n  slug: \"amanda-vikdal\"\n- name: \"Amanda Wagener\"\n  github: \"awagener\"\n  website: \"http://www.awagener.com/\"\n  slug: \"amanda-wagener\"\n  aliases:\n    - name: \"Amanda Wagner\"\n      slug: \"amanda-wagner\"\n- name: \"Amani Kanu\"\n  github: \"\"\n  slug: \"amani-kanu\"\n- name: \"Amar Shah\"\n  github: \"amar47shah\"\n  website: \"http://amar47shah.github.io/\"\n  slug: \"amar-shah\"\n- name: \"Amelia Walter-Dzikowska\"\n  github: \"\"\n  slug: \"amelia-walter-dzikowska\"\n- name: \"Amina Adewusi\"\n  github: \"nirvikalpa108\"\n  slug: \"amina-adewusi\"\n- name: \"Amir Rajan\"\n  twitter: \"amirrajan\"\n  github: \"amirrajan\"\n  website: \"http://amirrajan.net\"\n  slug: \"amir-rajan\"\n- name: \"Amit Gaur\"\n  github: \"\"\n  slug: \"amit-gaur\"\n- name: \"Amit Kumar\"\n  twitter: \"iaktech\"\n  github: \"aktech\"\n  website: \"https://iamit.in\"\n  slug: \"amit-kumar\"\n- name: \"Amr Abdelwahab\"\n  twitter: \"amrAbdelwahab\"\n  github: \"amrabdelwahab\"\n  slug: \"amr-abdelwahab\"\n- name: \"Amulya Tanksale\"\n  github: \"Tanksale\"\n  slug: \"amulya-tanksale\"\n- name: \"Amy Chen\"\n  github: \"amy\"\n  website: \"https://www.youtube.com/AmyCodes\"\n  slug: \"amy-chen\"\n- name: \"Amy Howes\"\n  github: \"thecodeferret\"\n  website: \"https://www.linkedin.com/in/TheCodeFerret\"\n  slug: \"amy-howes\"\n- name: \"Amy Hupe\"\n  twitter: \"amy_hupe\"\n  github: \"amyhupe\"\n  website: \"https://amyhupe.co.uk\"\n  slug: \"amy-hupe\"\n- name: \"Amy Lynch\"\n  github: \"\"\n  slug: \"amy-lynch\"\n- name: \"Amy Newell\"\n  github: \"amynewell\"\n  slug: \"amy-newell\"\n- name: \"Amy Unger\"\n  twitter: \"cdwort\"\n  github: \"cdwort\"\n  website: \"https://amyunger.com\"\n  slug: \"amy-unger\"\n- name: \"Amy Wall\"\n  github: \"amymariewall\"\n  slug: \"amy-wall\"\n- name: \"Amy Wibowo\"\n  twitter: \"sailorhg\"\n  github: \"sailorhg\"\n  website: \"https://sailorhg.com/\"\n  slug: \"amy-wibowo\"\n- name: \"Amélie Certin\"\n  github: \"\"\n  slug: \"amelie-certin\"\n- name: \"Ana Martínez\"\n  github: \"\"\n  slug: \"ana-martinez\"\n- name: \"Ana María Martínez Gómez\"\n  twitter: \"anamma_06\"\n  github: \"ana06\"\n  website: \"https://anamaria.martinezgomez.name\"\n  slug: \"ana-maria-martinez-gomez\"\n- name: \"Anagha R\"\n  slug: \"anagha-r\"\n  github: \"Anagha22\"\n- name: \"Anand Agrawal\"\n  github: \"anandagrawal84\"\n  slug: \"anand-agrawal\"\n- name: \"Anandha Krishnan\"\n  twitter: \"anandhak\"\n  github: \"anandhak\"\n  slug: \"anandha-krishnan\"\n- name: \"Anas Alkhatib\"\n  github: \"alkhatib\"\n  website: \"https://www.anasalkhatib.ca\"\n  slug: \"anas-alkhatib\"\n- name: \"Anastasia Chicu\"\n  github: \"deepblueness\"\n  slug: \"anastasia-chicu\"\n- name: \"Anatoly Mikhaylov\"\n  github: \"mikhailov\"\n  slug: \"anatoly-mikhaylov\"\n- name: \"Anders Bälter\"\n  github: \"baelter\"\n  slug: \"anders-balter\"\n- name: \"Andi Idogawa\"\n  twitter: \"largo\"\n  github: \"largo\"\n  website: \"https://idogawa.com\"\n  slug: \"andi-idogawa\"\n- name: \"Andi Rugg\"\n  github: \"\"\n  slug: \"andi-rugg\"\n- name: \"Andras Kristof\"\n  github: \"\"\n  slug: \"andras-kristof\"\n- name: \"Andre Vidic\"\n  github: \"\"\n  slug: \"andre-vidic\"\n- name: \"Andrea Fomera\"\n  twitter: \"afomera\"\n  github: \"afomera\"\n  website: \"https://afomera.dev\"\n  slug: \"andrea-fomera\"\n- name: \"Andrea Guendelman\"\n  github: \"\"\n  slug: \"andrea-guendelman\"\n- name: \"Andrea O. K. Wright\"\n  github: \"A-OK\"\n  slug: \"andrea-o-k-wright\"\n- name: \"Andrea Reginato\"\n  github: \"\"\n  slug: \"andrea-reginato\"\n- name: \"Andrea Schiavini\"\n  github: \"\"\n  slug: \"andrea-schiavini\"\n- name: \"Andrea Wayte\"\n  github: \"andreasandpiper\"\n  website: \"https://andreawayte.com\"\n  slug: \"andrea-wayte\"\n- name: \"Andreas Erik\"\n  github: \"\"\n  slug: \"andreas-erik\"\n- name: \"Andreas Fast\"\n  github: \"afast\"\n  website: \"https://blog.qubika.com\"\n  slug: \"andreas-fast\"\n- name: \"Andreas Finger\"\n  twitter: \"mediafinger\"\n  github: \"mediafinger\"\n  website: \"https://mediafinger.com/\"\n  slug: \"andreas-finger\"\n- name: \"Andreas Maierhofer\"\n  twitter: \"tjahma\"\n  github: \"amaierhofer\"\n  slug: \"andreas-maierhofer\"\n- name: \"Andrei Beliankou\"\n  github: \"arbox\"\n  slug: \"andrei-beliankou\"\n- name: \"Andrei Bondarev\"\n  twitter: \"rushing_andrei\"\n  github: \"andreibondarev\"\n  website: \"https://www.sourcelabs.io\"\n  slug: \"andrei-bondarev\"\n- name: \"Andrei Gridnev\"\n  github: \"\"\n  slug: \"andrei-gridnev\"\n- name: \"Andrei Kaleshka\"\n  twitter: \"ka8725\"\n  github: \"ka8725\"\n  website: \"https://widefix.com\"\n  slug: \"andrei-kaleshka\"\n- name: \"Andrei Maxim\"\n  github: \"\"\n  slug: \"andrei-maxim\"\n- name: \"Andrei Savchenko\"\n  github: \"\"\n  slug: \"andrei-savchenko\"\n- name: \"Andrew Atkinson\"\n  twitter: \"andatki\"\n  github: \"andyatkinson\"\n  website: \"https://andyatkinson.com\"\n  slug: \"andrew-atkinson\"\n  aliases:\n    - name: \"Andy Atkinson\"\n      slug: \"andy-atkinson\"\n- name: \"Andrew Bloomgarden\"\n  github: \"aughr\"\n  slug: \"andrew-bloomgarden\"\n- name: \"Andrew Butterfield\"\n  github: \"\"\n  slug: \"andrew-butterfield\"\n- name: \"Andrew Cantino\"\n  twitter: \"tectonic\"\n  github: \"cantino\"\n  website: \"https://andrewcantino.com\"\n  slug: \"andrew-cantino\"\n- name: \"Andrew Carmer\"\n  github: \"carmer\"\n  slug: \"andrew-carmer\"\n- name: \"Andrew Carter\"\n  github: \"andrewcarteruk\"\n  website: \"http://andrewcarteruk.github.io/\"\n  slug: \"andrew-carter\"\n- name: \"Andrew Clay Shafer\"\n  github: \"\"\n  slug: \"andrew-clay-shafer\"\n- name: \"Andrew Culver\"\n  github: \"andrewculver\"\n  slug: \"andrew-culver\"\n- name: \"Andrew Ek\"\n  github: \"andrewek\"\n  slug: \"andrew-ek\"\n- name: \"Andrew Evans\"\n  twitter: \"AndrewEvans0102\"\n  github: \"andrewevans0102\"\n  website: \"https://andrewevans.dev\"\n  slug: \"andrew-evans\"\n- name: \"Andrew Faraday\"\n  github: \"ajfaraday\"\n  slug: \"andrew-faraday\"\n- name: \"Andrew Gauger\"\n  twitter: \"andygauge\"\n  github: \"andygauge\"\n  website: \"http://www.yetanother.site\"\n  slug: \"andrew-gauger\"\n- name: \"Andrew Grimm\"\n  github: \"\"\n  slug: \"andrew-grimm\"\n- name: \"Andrew Hao\"\n  twitter: \"andrewhao\"\n  github: \"andrewhao\"\n  website: \"http://www.g9labs.com\"\n  slug: \"andrew-hao\"\n- name: \"Andrew Harvey\"\n  github: \"andrewharvey\"\n  website: \"https://www.alantgeo.com.au\"\n  slug: \"andrew-harvey\"\n- name: \"Andrew Louis\"\n  github: \"hyfen\"\n  website: \"https://hyfen.net\"\n  slug: \"andrew-louis\"\n- name: \"Andrew Markle\"\n  github: \"andrewmarkle\"\n  slug: \"andrew-markle\"\n- name: \"Andrew Mason\"\n  github: \"andrewmcodes\"\n  slug: \"andrew-mason\"\n- name: \"Andrew Mcnamara\"\n  github: \"\"\n  slug: \"andrew-mcnamara\"\n- name: \"Andrew Metcalf\"\n  github: \"metcalf\"\n  slug: \"andrew-metcalf\"\n- name: \"Andrew Neely\"\n  github: \"andrew-neely-82\"\n  slug: \"andrew-neely\"\n- name: \"Andrew Nesbitt\"\n  twitter: \"teabass\"\n  github: \"andrew\"\n  website: \"https://nesbitt.io/\"\n  slug: \"andrew-nesbitt\"\n- name: \"Andrew Nordman\"\n  github: \"cadwallion\"\n  slug: \"andrew-nordman\"\n- name: \"Andrew Novoselac\"\n  github: \"andrewn617\"\n  slug: \"andrew-novoselac\"\n- name: \"Andrew Radev\"\n  twitter: \"AndrewRadev\"\n  github: \"andrewradev\"\n  website: \"https://andrewra.dev\"\n  slug: \"andrew-radev\"\n- name: \"Andrew Rosa\"\n  github: \"\"\n  slug: \"andrew-rosa\"\n- name: \"Andrew Shafer\"\n  github: \"\"\n  slug: \"andrew-shafer\"\n- name: \"Andrew Szczepanski\"\n  github: \"skipants\"\n  slug: \"andrew-szczepanski\"\n- name: \"Andrew Turley\"\n  github: \"aturley\"\n  slug: \"andrew-turley\"\n- name: \"Andrew Vit\"\n  github: \"avit\"\n  slug: \"andrew-vit\"\n- name: \"Andrew Warner\"\n  github: \"a-warner\"\n  website: \"https://www.strongopinionsweaklytyped.com/\"\n  slug: \"andrew-warner\"\n- name: \"Andrew White\"\n  twitter: \"pixeltrix\"\n  github: \"pixeltrix\"\n  website: \"https://unboxed.co\"\n  slug: \"andrew-white\"\n- name: \"Andrey Deryabin\"\n  github: \"\"\n  slug: \"andrey-deryabin\"\n- name: \"Andrey Kumanyaev\"\n  github: \"\"\n  slug: \"andrey-kumanyaev\"\n- name: \"Andrey Marchenko\"\n  github: \"anmarchenko\"\n  slug: \"andrey-marchenko\"\n- name: \"Andrey Novikov\"\n  twitter: \"Envek\"\n  github: \"envek\"\n  website: \"https://envek.name\"\n  slug: \"andrey-novikov\"\n- name: \"Andrey Sitnik\"\n  twitter: \"sitnikcode\"\n  github: \"ai\"\n  website: \"https://sitnik.ru\"\n  slug: \"andrey-sitnik\"\n- name: \"Andromeda Yelton\"\n  github: \"thatandromeda\"\n  website: \"http://andromedayelton.com\"\n  slug: \"andromeda-yelton\"\n- name: \"Andrzej Krzywda\"\n  twitter: \"andrzejkrzywda\"\n  github: \"andrzejkrzywda\"\n  website: \"https://andrzejkrzywda.com\"\n  slug: \"andrzej-krzywda\"\n- name: \"Andrzej Śliwa\"\n  twitter: \"andrzejsliwa\"\n  github: \"andrzejsliwa\"\n  website: \"https://medium.com/andrzej-%C5%9Bliwa\"\n  slug: \"andrzej-sliwa\"\n- name: \"André Arko\"\n  github: \"indirect\"\n  website: \"https://arko.net\"\n  slug: \"andre-arko\"\n  aliases:\n    - name: \"Andre Arko\"\n      slug: \"andre-arko\"\n- name: \"André Barbosa\"\n  github: \"\"\n  slug: \"andre-barbosa\"\n- name: \"André Cedik\"\n  github: \"acwebionate\"\n  website: \"http://www.webionate.de\"\n  slug: \"andre-cedik\"\n- name: \"André Kupkovski\"\n  github: \"\"\n  slug: \"andre-kupkovski\"\n- name: \"André Medeiros\"\n  github: \"\"\n  slug: \"andre-medeiros\"\n- name: \"Andrés Robalino\"\n  github: \"\"\n  slug: \"andres-robalino\"\n- name: \"Andy\"\n  github: \"\"\n  slug: \"andy\"\n- name: \"Andy Allan\"\n  github: \"\"\n  slug: \"andy-allan\"\n- name: \"Andy Andrea\"\n  github: \"andycandrea\"\n  website: \"https://www.linkedin.com/in/andycandrea\"\n  slug: \"andy-andrea\"\n- name: \"Andy Camp\"\n  github: \"andoq\"\n  slug: \"andy-camp\"\n- name: \"Andy Croll\"\n  twitter: \"andycroll\"\n  github: \"andycroll\"\n  website: \"http://andycroll.com/\"\n  slug: \"andy-croll\"\n- name: \"Andy Delcambre\"\n  github: \"adelcambre\"\n  slug: \"andy-delcambre\"\n- name: \"Andy Glass\"\n  github: \"andrewglass1\"\n  website: \"https://andyglass.net\"\n  slug: \"andy-glass\"\n- name: \"Andy Hunt\"\n  github: \"\"\n  slug: \"andy-hunt\"\n- name: \"Andy Lindeman\"\n  github: \"alindeman\"\n  website: \"https://andylindeman.com/\"\n  slug: \"andy-lindeman\"\n- name: \"Andy Maleh\"\n  twitter: \"AndyObtiva\"\n  github: \"andyobtiva\"\n  website: \"https://andymaleh.blogspot.com\"\n  slug: \"andy-maleh\"\n- name: \"Andy Nicholson\"\n  github: \"\"\n  slug: \"andy-nicholson\"\n- name: \"Andy Park\"\n  github: \"sohocoke\"\n  slug: \"andy-park\"\n- name: \"Andy Pfister\"\n  github: \"andyundso\"\n  slug: \"andy-pfister\"\n- name: \"Andy Pike\"\n  github: \"\"\n  slug: \"andy-pike\"\n- name: \"Andy Pliszka\"\n  twitter: \"AntiTyping\"\n  github: \"antityping\"\n  website: \"http://antityping.com\"\n  slug: \"andy-pliszka\"\n- name: \"Andy Schoenen\"\n  github: \"\"\n  slug: \"andy-schoenen\"\n- name: \"Andy Waite\"\n  twitter: \"andyw8\"\n  github: \"andyw8\"\n  website: \"https://www.andywaite.com\"\n  slug: \"andy-waite\"\n- name: \"Andy Wang\"\n  twitter: \"andywang\"\n  linkedin: \"a27wang\"\n  slug: \"andy-wang\"\n  github: \"\"\n- name: \"Aneika Simmons\"\n  github: \"\"\n  slug: \"aneika-simmons\"\n- name: \"Angel Malavar\"\n  github: \"\"\n  slug: \"angel-malavar\"\n- name: \"Angela Choi\"\n  twitter: \"angelamchoi\"\n  github: \"angelamchoi\"\n  website: \"https://angelachoi.netlify.app/\"\n  slug: \"angela-choi\"\n- name: \"Angela Harms\"\n  github: \"\"\n  slug: \"angela-harms\"\n- name: \"Anika Lindtner\"\n  github: \"\"\n  slug: \"anika-lindtner\"\n- name: \"Anika Simir\"\n  twitter: \"langziehohr\"\n  github: \"\"\n  slug: \"anika-simir\"\n- name: \"Aniket Rao\"\n  github: \"\"\n  slug: \"aniket-rao\"\n- name: \"Anil Wadghule\"\n  github: \"anildigital\"\n  website: \"https://anilwadghule.com\"\n  slug: \"anil-wadghule\"\n- name: \"Anita Jaszewska\"\n  github: \"letsleaveitempty\"\n  slug: \"anita-jaszewska\"\n  aliases:\n    - name: \"Anita Jaszeweska\"\n      slug: \"anita-jaszeweska\"\n- name: \"Aniyia Williams\"\n  github: \"\"\n  slug: \"aniyia-williams\"\n- name: \"Anja R.\"\n  github: \"\"\n  slug: \"anja-r\"\n- name: \"Anjuan Simmons\"\n  twitter: \"anjuan\"\n  github: \"anjuan\"\n  website: \"http://www.AnjuanSimmons.com\"\n  slug: \"anjuan-simmons\"\n- name: \"Ankita Gupta\"\n  github: \"\"\n  slug: \"ankita-gupta\"\n- name: \"Anmol Agarwal\"\n  github: \"\"\n  slug: \"anmol-agarwal\"\n- name: \"Ann Harter\"\n  github: \"\"\n  slug: \"ann-harter\"\n- name: \"Anna Fowles-Winkler\"\n  github: \"annawinkler\"\n  slug: \"anna-fowles-winkler\"\n- name: \"Anna Gluszak\"\n  github: \"ag-sile\"\n  slug: \"anna-gluszak\"\n- name: \"Anna Lopukhina\"\n  github: \"anuta555\"\n  slug: \"anna-lopukhina\"\n- name: \"Anna Rankin\"\n  github: \"annarankin\"\n  website: \"http://annarank.in\"\n  slug: \"anna-rankin\"\n- name: \"Anna Shcherbinina\"\n  github: \"gaar4ica\"\n  slug: \"anna-shcherbinina\"\n- name: \"Anne Sophie Rouaux\"\n  twitter: \"annesottise\"\n  github: \"annesottise\"\n  slug: \"anne-sophie-rouaux\"\n- name: \"Annie Kiley\"\n  github: \"albaer\"\n  slug: \"annie-kiley\"\n- name: \"Annie Lydens\"\n  github: \"aelydens\"\n  slug: \"annie-lydens\"\n- name: \"Annie Sexton\"\n  twitter: \"_anniebabannie_\"\n  github: \"anniebabannie\"\n  slug: \"annie-sexton\"\n- name: \"Anonoz Chong\"\n  twitter: \"anonoz\"\n  github: \"anonoz\"\n  website: \"https://anonoz.github.io\"\n  slug: \"anonoz-chong\"\n- name: \"Anthony Crumley\"\n  github: \"anthonycrumley\"\n  website: \"http://craftyco.de\"\n  slug: \"anthony-crumley\"\n- name: \"Anthony Eden\"\n  twitter: \"aeden\"\n  github: \"aeden\"\n  website: \"http://anthonyeden.com/\"\n  slug: \"anthony-eden\"\n- name: \"Anthony Gaidot\"\n  github: \"\"\n  slug: \"anthony-gaidot\"\n- name: \"Anthony Langhorne\"\n  github: \"\"\n  slug: \"anthony-langhorne\"\n- name: \"Anthony Navarre\"\n  github: \"anthonynavarre\"\n  slug: \"anthony-navarre\"\n- name: \"Anthony Zacharakis\"\n  github: \"\"\n  slug: \"anthony-zacharakis\"\n- name: \"Antoine Lecl\"\n  github: \"\"\n  slug: \"antoine-lecl\"\n- name: \"Anton Bangratz\"\n  github: \"\"\n  slug: \"anton-bangratz\"\n- name: \"Anton Davydov\"\n  twitter: \"anton_davydov\"\n  github: \"davydovanton\"\n  website: \"http://davydovanton.com\"\n  slug: \"anton-davydov\"\n- name: \"Anton Dimitrov\"\n  github: \"antonrd\"\n  slug: \"anton-dimitrov\"\n- name: \"Anton Katunin\"\n  github: \"\"\n  slug: \"anton-katunin\"\n- name: \"Anton Lvov\"\n  github: \"\"\n  slug: \"anton-lvov\"\n- name: \"Anton Paisov\"\n  github: \"antonpaisov\"\n  slug: \"anton-paisov\"\n- name: \"Anton Panteleev\"\n  github: \"\"\n  slug: \"anton-panteleev\"\n- name: \"Anton Senkovskiy\"\n  github: \"asenkovskiy\"\n  slug: \"anton-senkovskiy\"\n- name: \"Anton Tkachov\"\n  github: \"AntonTkachov\"\n  slug: \"anton-tkachov\"\n- name: \"Anton Volkov\"\n  github: \"\"\n  slug: \"anton-volkov\"\n- name: \"Antonio Carpentieri\"\n  github: \"\"\n  slug: \"antonio-carpentieri\"\n- name: \"Antti Merilehto\"\n  twitter: \"AnttiMerilehto\"\n  github: \"merilehto\"\n  website: \"https://www.merilehto.com/en/mainpage\"\n  slug: \"antti-merilehto\"\n- name: \"Anush Kumar\"\n  github: \"anush-kumar-s\"\n  slug: \"anush-kumar\"\n- name: \"Aotoki\"\n  twitter: \"elct9620\"\n  github: \"elct9620\"\n  website: \"https://blog.aotoki.me/en\"\n  slug: \"elct9620\"\n- name: \"Aotoki Tsuruya\"\n  github: \"\"\n  slug: \"aotoki-tsuruya\"\n- name: \"Apoorv Tiwari\"\n  github: \"\"\n  slug: \"apoorv-tiwari\"\n- name: \"April Wensel\"\n  github: \"\"\n  slug: \"april-wensel\"\n- name: \"Ara T. Howard\"\n  github: \"\"\n  slug: \"ara-t-howard\"\n- name: \"Arafat Khan\"\n  github: \"arafat-ar13\"\n  website: \"https://arafat-ar13.github.io\"\n  slug: \"arafat-khan\"\n  aliases:\n    - name: \"Arafat Dad Khan\"\n      slug: \"arafat-dad-khan\"\n- name: \"Aram Bhusal\"\n  twitter: \"phoenixwizard\"\n  github: \"phoenixwizard\"\n  slug: \"aram-bhusal\"\n- name: \"Arathi Premadevi\"\n  github: \"\"\n  slug: \"arathi-premadevi\"\n- name: \"Archon\"\n  github: \"\"\n  slug: \"archon\"\n- name: \"Ari Lerner\"\n  github: \"\"\n  slug: \"ari-lerner\"\n- name: \"Ariel Caplan\"\n  twitter: \"amcaplan\"\n  github: \"amcaplan\"\n  website: \"https://amcaplan.ninja\"\n  slug: \"ariel-caplan\"\n- name: \"Ariel Juodziukynas\"\n  github: \"\"\n  slug: \"ariel-juodziukynas\"\n- name: \"Ariel Valentin\"\n  github: \"arielvalentin\"\n  slug: \"ariel-valentin\"\n- name: \"Arihant Hirawat\"\n  github: \"\"\n  slug: \"arihant-hirawat\"\n- name: \"Arjun Sharma\"\n  github: \"arjun-sharma1\"\n  website: \"https://arjun-sharma.com\"\n  slug: \"arjun-sharma\"\n- name: \"Arjun Singh\"\n  github: \"arjun810\"\n  linkedin: \"arjun-singh-629216105\"\n  slug: \"arjun-singh\"\n- name: \"Arkadiusz Turlewicz\"\n  github: \"arekt\"\n  website: \"https://arekt.github.io/\"\n  slug: \"arkadiusz-turlewicz\"\n- name: \"Arkadiy Zabazhanov\"\n  github: \"pyromaniac\"\n  slug: \"arkadiy-zabazhanov\"\n- name: \"Armin Pašalić\"\n  twitter: \"krule\"\n  github: \"krule\"\n  website: \"https://pasalic.me\"\n  slug: \"armin-pasalic\"\n- name: \"Armin Ronacher\"\n  github: \"mitsuhiko\"\n  slug: \"armin-ronacher\"\n- name: \"Arnab Deka\"\n  github: \"\"\n  slug: \"arnab-deka\"\n- name: \"Arne Brasseur\"\n  twitter: \"plexus\"\n  github: \"plexus\"\n  website: \"http://www.arnebrasseur.net\"\n  slug: \"arne-brasseur\"\n- name: \"Arno Fleming\"\n  github: \"\"\n  slug: \"arno-fleming\"\n- name: \"Aron Wolf\"\n  twitter: \"wolf_aron\"\n  github: \"aronwolf90\"\n  slug: \"aron-wolf\"\n- name: \"Arthur Neves\"\n  github: \"\"\n  slug: \"arthur-neves\"\n- name: \"Arto Bendiken\"\n  twitter: \"bendiken\"\n  github: \"artob\"\n  website: \"https://ar.to\"\n  slug: \"arto-bendiken\"\n- name: \"Artur Dębski\"\n  github: \"mentero\"\n  slug: \"artur-debski\"\n- name: \"Artur Hebda\"\n  github: \"aenain\"\n  website: \"https://aenain.github.io\"\n  slug: \"artur-hebda\"\n- name: \"Artur Roszczyk\"\n  twitter: \"sevos\"\n  github: \"sevos\"\n  website: \"http://sevos.io/\"\n  slug: \"artur-roszczyk\"\n- name: \"Arturs Mekss\"\n  github: \"\"\n  slug: \"arturs-mekss\"\n- name: \"Arve Brasseur\"\n  github: \"\"\n  slug: \"arve-brasseur\"\n- name: \"Asayama Kodai\"\n  github: \"asayamakk\"\n  slug: \"asayama-kodai\"\n- name: \"Ashe Dryden\"\n  github: \"ashedryden\"\n  website: \"http://ashedryden.com\"\n  slug: \"ashe-dryden\"\n- name: \"Ashish Tendulkar\"\n  github: \"tfindiamooc\"\n  slug: \"ashish-tendulkar\"\n- name: \"Ashley Ellis Pierce\"\n  github: \"aellispierce\"\n  slug: \"ashley-ellis-pierce\"\n- name: \"Ashley Jean\"\n  github: \"a-jean\"\n  slug: \"ashley-jean\"\n- name: \"Aslak Hellesøy\"\n  github: \"\"\n  slug: \"aslak-hellesoy\"\n- name: \"Assaf Hefetz\"\n  github: \"\"\n  slug: \"assaf-hefetz\"\n- name: \"asumikam\"\n  github: \"asumikam\"\n  slug: \"asumikam\"\n- name: \"Atob\"\n  github: \"atober\"\n  slug: \"atob\"\n- name: \"Atsuhiro Tsuji\"\n  github: \"tsuji-108\"\n  slug: \"atsuhiro-tsuji\"\n- name: \"Atsushi Katsuura\"\n  github: \"ikaruga777\"\n  slug: \"atsushi-katsuura\"\n- name: \"Attila Domokos\"\n  github: \"adomokos\"\n  website: \"https://www.adomokos.com\"\n  slug: \"attila-domokos\"\n- name: \"Audrey Eschright\"\n  twitter: \"ameschright\"\n  github: \"aeschright\"\n  website: \"http://lifeofaudrey.com\"\n  slug: \"audrey-eschright\"\n- name: \"Audrey Troutt\"\n  twitter: \"auditty\"\n  github: \"atroutt\"\n  website: \"http://audreytroutt.com\"\n  slug: \"audrey-troutt\"\n- name: \"Augustin Gottlieb\"\n  github: \"aguspe\"\n  slug: \"augustin-gottlieb\"\n- name: \"Augusto Becciu\"\n  github: \"\"\n  slug: \"augusto-becciu\"\n- name: \"Aurora Nockert\"\n  github: \"auroranockert\"\n  website: \"http://blog.aventine.se/\"\n  slug: \"aurora-nockert\"\n- name: \"Austin Fonacier\"\n  github: \"austinrfnd\"\n  slug: \"austin-fonacier\"\n- name: \"Austin Putman\"\n  github: \"austinfromboston\"\n  website: \"http://rawfingertips.org\"\n  slug: \"austin-putman\"\n- name: \"Austin Seraphin\"\n  github: \"\"\n  slug: \"austin-seraphin\"\n- name: \"Austin Story\"\n  github: \"austio\"\n  website: \"https://austio.com\"\n  slug: \"austin-story\"\n- name: \"Austin Vance\"\n  github: \"\"\n  slug: \"austin-vance\"\n- name: \"Auston Bunsen\"\n  github: \"abunsen\"\n  slug: \"auston-bunsen\"\n- name: \"Avdi Grimm\"\n  twitter: \"avdi\"\n  github: \"avdi\"\n  website: \"http://avdi.codes\"\n  slug: \"avdi-grimm\"\n- name: \"Avi Bryant\"\n  github: \"avibryant\"\n  slug: \"avi-bryant\"\n- name: \"Avi Flombaum\"\n  twitter: \"aviflombaum\"\n  github: \"aviflombaum\"\n  website: \"http://www.aviflombaum.com\"\n  slug: \"avi-flombaum\"\n- name: \"Avinash Joshi\"\n  twitter: \"avinashjoshi\"\n  github: \"avinashjoshi\"\n  slug: \"avinash-joshi\"\n- name: \"aycabta\"\n  github: \"\"\n  slug: \"aycabta\"\n- name: \"Aymeric Serradeil\"\n  github: \"\"\n  slug: \"aymeric-serradeil\"\n- name: \"Ayush Newatia\"\n  twitter: \"ayushn21\"\n  github: \"ayushn21\"\n  website: \"https://radioactivetoy.tech\"\n  slug: \"ayush-newatia\"\n- name: \"B.J. Allen\"\n  github: \"\"\n  slug: \"b-j-allen\"\n- name: \"Baishampayan Ghose\"\n  github: \"\"\n  slug: \"baishampayan-ghose\"\n- name: \"Bala Kuma\"\n  github: \"sribalakumar\"\n  slug: \"bala-kuma\"\n- name: \"Baratunde Thurston\"\n  github: \"\"\n  slug: \"baratunde-thurston\"\n- name: \"Barbara Fusińska\"\n  github: \"\"\n  slug: \"barbara-fusinska\"\n- name: \"Barbara Tannenbaum\"\n  github: \"\"\n  slug: \"barbara-tannenbaum\"\n- name: \"Bari A Williams\"\n  github: \"\"\n  slug: \"bari-a-williams\"\n- name: \"Barnaba Siegel\"\n  github: \"\"\n  slug: \"barnaba-siegel\"\n- name: \"Barret Clark\"\n  github: \"\"\n  slug: \"barret-clark\"\n- name: \"Barrett Clark\"\n  twitter: \"barrettclark\"\n  github: \"barrettclark\"\n  slug: \"barrett-clark\"\n- name: \"Barry Hess\"\n  github: \"\"\n  slug: \"barry-hess\"\n- name: \"Bart Agapinan\"\n  github: \"viamin\"\n  slug: \"bart-agapinan\"\n- name: \"Bart de Water\"\n  github: \"bdewater\"\n  slug: \"bart-de-water\"\n- name: \"Bartosz Blimke\"\n  twitter: \"bartoszblimke\"\n  github: \"bblimke\"\n  slug: \"bartosz-blimke\"\n- name: \"Bartosz Bonisławski\"\n  github: \"bbonislawski\"\n  slug: \"bartosz-bonislawski\"\n- name: \"Bartosz Knapik\"\n  github: \"\"\n  slug: \"bartosz-knapik\"\n- name: \"bash\"\n  github: \"\"\n  slug: \"bash\"\n- name: \"Beau Harrington\"\n  github: \"bohford\"\n  slug: \"beau-harrington\"\n- name: \"Bekki Freeman\"\n  github: \"bekkii77\"\n  slug: \"bekki-freeman\"\n- name: \"Belén Albeza\"\n  github: \"\"\n  slug: \"belen-albeza\"\n- name: \"Ben Bleything\"\n  twitter: \"bleything\"\n  github: \"bleything\"\n  website: \"http://bleything.net\"\n  slug: \"ben-bleything\"\n- name: \"Ben Colon\"\n  github: \"bencolon\"\n  website: \"http://bencolon.com\"\n  slug: \"ben-colon\"\n- name: \"Ben Curtis\"\n  github: \"stympy\"\n  website: \"http://www.bencurtis.com/\"\n  slug: \"ben-curtis\"\n- name: \"Ben Dixon\"\n  twitter: \"talkingquickly\"\n  github: \"talkingquickly\"\n  website: \"https://www.talkingquickly.co.uk\"\n  slug: \"ben-dixon\"\n- name: \"Ben Eggett\"\n  github: \"\"\n  slug: \"ben-eggett\"\n- name: \"Ben Fritsch\"\n  github: \"beanieboi\"\n  website: \"https://abwesend.com\"\n  slug: \"ben-fritsch\"\n- name: \"Ben Greenberg\"\n  twitter: \"hummusonrails\"\n  github: \"hummusonrails\"\n  website: \"https://www.bengreenberg.dev\"\n  slug: \"ben-greenberg\"\n- name: \"Ben Griffiths\"\n  github: \"\"\n  slug: \"ben-griffiths\"\n- name: \"Ben Halpern\"\n  twitter: \"bendhalpern\"\n  github: \"benhalpern\"\n  website: \"https://dev.to/ben\"\n  slug: \"ben-halpern\"\n- name: \"Ben Hamill\"\n  github: \"\"\n  slug: \"ben-hamill\"\n- name: \"Ben Hoskings\"\n  github: \"\"\n  slug: \"ben-hoskings\"\n- name: \"Ben Jacobson\"\n  twitter: \"bjacobso\"\n  github: \"bjacobso\"\n  website: \"http://benjacobson.com\"\n  slug: \"ben-jacobson\"\n- name: \"Ben Klang\"\n  github: \"bklang\"\n  website: \"http://powerhrg.com\"\n  slug: \"ben-klang\"\n- name: \"Ben Lovell\"\n  github: \"benlovell\"\n  slug: \"ben-lovell\"\n- name: \"Ben Oakes\"\n  github: \"benjaminoakes\"\n  website: \"https://www.benjaminoakes.com/\"\n  slug: \"ben-oakes\"\n- name: \"Ben Orenstein\"\n  twitter: \"r00k\"\n  github: \"r00k\"\n  website: \"http://www.benorenstein.com\"\n  slug: \"ben-orenstein\"\n- name: \"Ben Rexin\"\n  github: \"\"\n  slug: \"ben-rexin\"\n- name: \"Ben Sanders\"\n  github: \"\"\n  slug: \"ben-sanders\"\n- name: \"Ben Scheirman\"\n  github: \"\"\n  slug: \"ben-scheirman\"\n- name: \"Ben Schwarz\"\n  github: \"\"\n  slug: \"ben-schwarz\"\n- name: \"Ben Scofield\"\n  twitter: \"bscofield\"\n  github: \"bscofield\"\n  website: \"https://benscofield.com\"\n  slug: \"ben-scofield\"\n- name: \"Ben Sheldon\"\n  twitter: \"bensheldon\"\n  github: \"bensheldon\"\n  website: \"https://island94.org\"\n  slug: \"ben-sheldon\"\n- name: \"Ben Shippee\"\n  github: \"benshippee\"\n  slug: \"ben-shippee\"\n- name: \"Ben Smith\"\n  github: \"binji\"\n  website: \"https://binji.github.io\"\n  slug: \"ben-smith\"\n- name: \"Ben Stein\"\n  github: \"bpstein\"\n  slug: \"ben-stein\"\n- name: \"Ben Taylor\"\n  github: \"\"\n  slug: \"ben-taylor\"\n- name: \"Ben Turner\"\n  github: \"\"\n  slug: \"ben-turner\"\n- name: \"Ben Woosley\"\n  github: \"\"\n  slug: \"ben-woosley\"\n- name: \"Bence Fulop\"\n  github: \"\"\n  slug: \"bence-fulop\"\n- name: \"Benedikt Deicke\"\n  twitter: \"benediktdeicke\"\n  github: \"benedikt\"\n  website: \"https://benediktdeicke.com\"\n  slug: \"benedikt-deicke\"\n- name: \"Benjamin Atkin\"\n  github: \"benatkin\"\n  website: \"https://benatkin.com/\"\n  slug: \"benjamin-atkin\"\n- name: \"Benjamin Combourieu\"\n  github: \"\"\n  slug: \"benjamin-combourieu\"\n- name: \"Benjamin Curtis\"\n  github: \"\"\n  slug: \"benjamin-curtis\"\n- name: \"Benjamin Deutscher\"\n  github: \"\"\n  slug: \"benjamin-deutscher\"\n- name: \"Benjamin Fleischer\"\n  github: \"bf4\"\n  website: \"http://benjaminfleischer.com\"\n  slug: \"benjamin-fleischer\"\n- name: \"Benjamin Orenstein\"\n  github: \"\"\n  slug: \"benjamin-orenstein\"\n- name: \"Benjamin Reitzammer\"\n  github: \"\"\n  slug: \"benjamin-reitzammer\"\n- name: \"Benjamin Robert\"\n  github: \"\"\n  slug: \"benjamin-robert\"\n- name: \"Benjamin Roth\"\n  github: \"apneadiving\"\n  website: \"http://about.me/apneadiving\"\n  slug: \"benjamin-roth\"\n- name: \"Benjamin Sandofsky\"\n  github: \"\"\n  slug: \"benjamin-sandofsky\"\n- name: \"Benjamin Smith\"\n  github: \"\"\n  slug: \"benjamin-smith\"\n- name: \"Benjamin Tan\"\n  github: \"\"\n  slug: \"benjamin-tan\"\n- name: \"Benjamin Tan Wei Hao\"\n  twitter: \"bentanweihao\"\n  github: \"benjamintanweihao\"\n  website: \"https://benjamintan.io/\"\n  slug: \"benjamin-tan-wei-hao\"\n- name: \"Benjamin Udink ten Cate\"\n  github: \"\"\n  slug: \"benjamin-udink-ten-cate\"\n- name: \"Benjamin Vetter\"\n  github: \"mrkamel\"\n  slug: \"benjamin-vetter\"\n- name: \"Benjamin Wood\"\n  twitter: \"benjaminwood\"\n  github: \"benjaminwood\"\n  website: \"http://hint.io\"\n  slug: \"benjamin-wood\"\n- name: \"Benji Lewis\"\n  github: \"benjilewis\"\n  slug: \"benji-lewis\"\n  aliases:\n    - name: \"Benjamin Lewis\"\n      slug: \"benjamin-lewis\"\n- name: \"Benoit Daloze\"\n  twitter: \"eregontp\"\n  github: \"eregon\"\n  website: \"https://eregon.me/blog/\"\n  slug: \"benoit-daloze\"\n- name: \"Benoit Tigeot\"\n  github: \"benoittgt\"\n  slug: \"benoit-tigeot\"\n- name: \"Bente Pieck\"\n  github: \"bpieck\"\n  slug: \"bente-pieck\"\n- name: \"Berkan Ünal\"\n  github: \"brkn\"\n  slug: \"berkan-unal\"\n- name: \"Bermon Painter\"\n  github: \"\"\n  slug: \"bermon-painter\"\n- name: \"Bernard Banta\"\n  twitter: \"Bantab\"\n  github: \"banta\"\n  slug: \"bernard-banta\"\n- name: \"Bernerd Schaefer\"\n  github: \"\"\n  slug: \"bernerd-schaefer\"\n- name: \"betachelsea\"\n  twitter: \"beta_chelsea\"\n  github: \"betachelsea\"\n  slug: \"betachelsea\"\n- name: \"Beth Haubert\"\n  github: \"bethanyhaubert\"\n  website: \"https://bethanyhaubert.com\"\n  slug: \"beth-haubert\"\n- name: \"Betsy Haibel\"\n  twitter: \"betsythemuffin\"\n  github: \"bhaibel\"\n  slug: \"betsy-haibel\"\n- name: \"Betty Li\"\n  github: \"bettymakes\"\n  slug: \"betty-li\"\n- name: \"Bheeshmar Redheendran\"\n  github: \"\"\n  slug: \"bheeshmar-redheendran\"\n- name: \"Bianca Escalante\"\n  github: \"bescalante\"\n  slug: \"bianca-escalante\"\n- name: \"Bianca Gibson\"\n  github: \"\"\n  slug: \"bianca-gibson\"\n- name: \"Bianca Power\"\n  github: \"\"\n  slug: \"bianca-power\"\n- name: \"Bilal Budhani\"\n  github: \"\"\n  slug: \"bilal-budhani\"\n- name: \"Bilawal Maheed\"\n  github: \"\"\n  slug: \"bilawal-maheed\"\n- name: \"Bill Chapman\"\n  github: \"\"\n  slug: \"bill-chapman\"\n- name: \"Bill Lapcevic\"\n  github: \"\"\n  slug: \"bill-lapcevic\"\n- name: \"Bill Sendewicz\"\n  github: \"Stackeduary\"\n  slug: \"bill-sendewicz\"\n- name: \"Billy Watson\"\n  github: \"nextbillyonair\"\n  website: \"https://nextbillyonair.github.io\"\n  slug: \"billy-watson\"\n- name: \"BJ Clark\"\n  github: \"\"\n  slug: \"bj-clark\"\n- name: \"Bjorn Freeman-Benson\"\n  github: \"\"\n  slug: \"bjorn-freeman-benson\"\n- name: \"Blake Gearin\"\n  github: \"blakegearin\"\n  website: \"https://blakegearin.com\"\n  slug: \"blake-gearin\"\n- name: \"Blake Mizerany\"\n  github: \"bmizerany\"\n  slug: \"blake-mizerany\"\n- name: \"Blithe Rocher\"\n  github: \"blithe\"\n  website: \"https://blitherocher.com\"\n  slug: \"blithe-rocher\"\n- name: \"Blythe Dunham\"\n  github: \"\"\n  slug: \"blythe-dunham\"\n- name: \"Boaz Yehezkel\"\n  github: \"\"\n  slug: \"boaz-yehezkel\"\n- name: \"Bob Walker\"\n  github: \"\"\n  slug: \"bob-walker\"\n- name: \"Bobby Matson\"\n  github: \"bomatson\"\n  slug: \"bobby-matson\"\n- name: \"Bobby Wilson\"\n  github: \"\"\n  slug: \"bobby-wilson\"\n- name: \"Bohdan Varshchuk\"\n  github: \"bvar\"\n  slug: \"bohdan-varshchuk\"\n- name: \"Bonzalo Rodriguez\"\n  github: \"\"\n  slug: \"bonzalo-rodriguez\"\n- name: \"Boris Bügling\"\n  github: \"\"\n  slug: \"boris-bugling\"\n- name: \"Boris Goryachev\"\n  github: \"\"\n  slug: \"boris-goryachev\"\n- name: \"Bozhidar Batsov\"\n  twitter: \"bbatsov\"\n  github: \"bbatsov\"\n  website: \"https://metaredux.com\"\n  slug: \"bozhidar-batsov\"\n- name: \"Bracken Mosbacker\"\n  github: \"\"\n  slug: \"bracken-mosbacker\"\n- name: \"Brad Gessler\"\n  twitter: \"bradgessler\"\n  github: \"bradgessler\"\n  website: \"http://bradgessler.com/\"\n  slug: \"brad-gessler\"\n- name: \"Brad Grzesiak\"\n  github: \"listrophy\"\n  slug: \"brad-grzesiak\"\n- name: \"Brad Leslie\"\n  github: \"\"\n  slug: \"brad-leslie\"\n- name: \"Brad Midgley\"\n  github: \"\"\n  slug: \"brad-midgley\"\n- name: \"Brad Urani\"\n  twitter: \"bradurani\"\n  github: \"bradurani\"\n  website: \"http://fractalbanana.com\"\n  slug: \"brad-urani\"\n- name: \"Brad Wilkening\"\n  github: \"bwilken\"\n  slug: \"brad-wilkening\"\n- name: \"Bradley Beddoes\"\n  github: \"\"\n  slug: \"bradley-beddoes\"\n- name: \"Bradley Grzesiak\"\n  github: \"bradg-vin\"\n  slug: \"bradley-grzesiak\"\n- name: \"Bradley Herman\"\n  github: \"\"\n  slug: \"bradley-herman\"\n- name: \"Bradley Schafer\"\n  github: \"\"\n  slug: \"bradley-schafer\"\n- name: \"Bradly Feeley\"\n  github: \"bradly\"\n  slug: \"bradly-feeley\"\n- name: \"Brady Kriss\"\n  github: \"\"\n  slug: \"brady-kriss\"\n- name: \"Bragadeesh Jegannathan\"\n  github: \"bragboy\"\n  slug: \"bragadeesh-jegannathan\"\n- name: \"Brandon Black\"\n  twitter: \"brndnblck\"\n  github: \"brndnblck\"\n  website: \"http://brblck.com\"\n  slug: \"brandon-black\"\n- name: \"Brandon Hays\"\n  github: \"tehviking\"\n  website: \"https://brandonhays.com/blog\"\n  slug: \"brandon-hays\"\n- name: \"Brandon Keepers\"\n  twitter: \"bkeepers\"\n  github: \"bkeepers\"\n  website: \"http://opensoul.org\"\n  slug: \"brandon-keepers\"\n- name: \"Brandon Rice\"\n  github: \"brandonium21\"\n  website: \"https://www.linkedin.com/in/brandonium21\"\n  slug: \"brandon-rice\"\n- name: \"Brandon Shar\"\n  github: \"brandonshar\"\n  slug: \"brandon-shar\"\n- name: \"Brandon Weaver\"\n  github: \"baweaver\"\n  website: \"https://hachyderm.io/@baweaver\"\n  slug: \"brandon-weaver\"\n- name: \"Brandt Sheets\"\n  github: \"\"\n  slug: \"brandt-sheets\"\n- name: \"Braulio Carreno\"\n  twitter: \"bcarreno\"\n  github: \"bcarreno\"\n  website: \"https://carreno.me\"\n  slug: \"braulio-carreno\"\n- name: \"Braulio Martinez\"\n  github: \"brauliomartinezlm\"\n  website: \"https://cedarcode.com\"\n  slug: \"braulio-martinez\"\n- name: \"Bree Thomas\"\n  github: \"breethomas\"\n  slug: \"bree-thomas\"\n- name: \"Brendan Lim\"\n  twitter: \"brendanlim\"\n  github: \"brendanlim\"\n  slug: \"brendan-lim\"\n- name: \"Brendan Loudermilk\"\n  twitter: \"bloudermilk\"\n  github: \"bloudermilk\"\n  website: \"https://www.bloudermilk.com\"\n  slug: \"brendan-loudermilk\"\n- name: \"Brendan Weibrecht\"\n  github: \"\"\n  slug: \"brendan-weibrecht\"\n- name: \"Brendon McLean\"\n  twitter: \"brendon9x\"\n  github: \"brendon9x\"\n  website: \"https://www.zappi.io/\"\n  slug: \"brendon-mclean\"\n- name: \"Brenna Flood\"\n  github: \"brennx0r\"\n  website: \"http://brennx0r.com\"\n  slug: \"brenna-flood\"\n- name: \"Breno Gazzola\"\n  github: \"brenogazzola\"\n  slug: \"breno-gazzola\"\n- name: \"Brett Beutell\"\n  github: \"\"\n  slug: \"brett-beutell\"\n- name: \"Brian Cardarella\"\n  github: \"bcardarella\"\n  website: \"http://dockyard.com\"\n  slug: \"brian-cardarella\"\n- name: \"Brian Casel\"\n  github: \"CasJam\"\n  website: \"https://buildermethods.com\"\n  slug: \"brian-casel\"\n- name: \"Brian Childress\"\n  twitter: \"_brianchildress\"\n  github: \"brian-childress\"\n  website: \"https://brianchildress.co\"\n  slug: \"brian-childress\"\n- name: \"Brian Cooke\"\n  github: \"\"\n  slug: \"brian-cooke\"\n- name: \"Brian Doll\"\n  github: \"\"\n  slug: \"brian-doll\"\n- name: \"Brian Douglas\"\n  github: \"\"\n  slug: \"brian-douglas\"\n- name: \"Brian Durand\"\n  github: \"bdurand\"\n  slug: \"brian-durand\"\n- name: \"Brian Ford\"\n  github: \"\"\n  slug: \"brian-ford\"\n- name: \"Brian Fountain\"\n  github: \"\"\n  slug: \"brian-fountain\"\n- name: \"Brian Garside\"\n  github: \"briangee\"\n  website: \"http://briangarside.com\"\n  slug: \"brian-garside\"\n- name: \"Brian Gugliemetti\"\n  github: \"briangug\"\n  slug: \"brian-gugliemetti\"\n- name: \"Brian Guthrie\"\n  github: \"\"\n  slug: \"brian-guthrie\"\n- name: \"Brian Hogan\"\n  github: \"napcs\"\n  slug: \"brian-hogan\"\n  aliases:\n    - name: \"Brian P. Hogan\"\n      slug: \"brian-p-hogan\"\n- name: \"Brian Knapp\"\n  github: \"\"\n  slug: \"brian-knapp\"\n- name: \"Brian Knoles\"\n  twitter: \"BrianKnoles\"\n  github: \"bknoles\"\n  slug: \"brian-knoles\"\n- name: \"Brian Leonard\"\n  twitter: \"bleonard\"\n  github: \"bleonard\"\n  slug: \"brian-leonard\"\n- name: \"Brian Lesperance\"\n  github: \"openbl\"\n  website: \"https://openbl.com\"\n  slug: \"brian-lesperance\"\n- name: \"Brian Marrick\"\n  github: \"\"\n  slug: \"brian-marrick\"\n- name: \"Brian Martinez\"\n  github: \"\"\n  slug: \"brian-martinez\"\n- name: \"Brian McElaney\"\n  github: \"mcelaney\"\n  website: \"https://www.mcelaney.com/\"\n  slug: \"brian-mcelaney\"\n- name: \"Brian Mitcheel\"\n  github: \"\"\n  slug: \"brian-mitcheel\"\n- name: \"Brian Morton\"\n  github: \"bmorton\"\n  slug: \"brian-morton\"\n- name: \"Brian Moseley\"\n  github: \"bcm\"\n  slug: \"brian-moseley\"\n- name: \"Brian Sam-Bodden\"\n  github: \"\"\n  slug: \"brian-sam-bodden\"\n- name: \"Brian Scalan\"\n  github: \"bscanlan\"\n  slug: \"brian-scalan\"\n- name: \"Brian Shirai\"\n  github: \"\"\n  slug: \"brian-shirai\"\n- name: \"Brian Smith\"\n  github: \"\"\n  slug: \"brian-smith\"\n- name: \"Brian Underwood\"\n  github: \"cheerfulstoic\"\n  website: \"http://www.brian-underwood.codes/\"\n  slug: \"brian-underwood\"\n- name: \"Britni Alexander\"\n  github: \"twitnithegirl\"\n  slug: \"britni-alexander\"\n- name: \"Brittany Alexander\"\n  github: \"britbrith4\"\n  website: \"https://bealexander.com\"\n  slug: \"brittany-alexander\"\n- name: \"Brittany Springer\"\n  github: \"brittanyjspringer\"\n  website: \"https://brittanymartin.dev/\"\n  slug: \"brittany-springer\"\n  aliases:\n    - name: \"Brittany (Martin) Springer\"\n      slug: \"brittany-martin-springer\"\n    - name: \"Brittany Martin\"\n      slug: \"brittany-martin\"\n    - name: \"regularlady\"\n      slug: \"regularlady\"\n- name: \"Brittany Storoz\"\n  github: \"\"\n  slug: \"brittany-storoz\"\n- name: \"Brock Whitten\"\n  github: \"\"\n  slug: \"brock-whitten\"\n- name: \"Brock Wilcox\"\n  twitter: \"awwaiid\"\n  github: \"awwaiid\"\n  website: \"http://thelackthereof.org/\"\n  slug: \"brock-wilcox\"\n- name: \"Bronwen Zande\"\n  twitter: \"bronwenz\"\n  github: \"bronwenz\"\n  website: \"http://soulsolutions.com.au\"\n  slug: \"bronwen-zande\"\n- name: \"Brook Kuhlmann\"\n  github: \"\"\n  slug: \"brook-kuhlmann\"\n- name: \"Brooke Kuhlmann\"\n  github: \"bkuhlmann\"\n  website: \"https://alchemists.io\"\n  slug: \"brooke-kuhlmann\"\n- name: \"Brooks Swinnerton\"\n  twitter: \"bswinnerton\"\n  github: \"bswinnerton\"\n  website: \"https://brooks.sh\"\n  slug: \"brooks-swinnerton\"\n- name: \"Bruce Li\"\n  twitter: \"ascendbruce\"\n  github: \"ascendbruce\"\n  website: \"http://www.bruceli.net/\"\n  slug: \"bruce-li\"\n- name: \"Bruce Tate\"\n  github: \"\"\n  slug: \"bruce-tate\"\n- name: \"Bruce Williams\"\n  github: \"\"\n  slug: \"bruce-williams\"\n- name: \"Bruno Aguirre\"\n  github: \"\"\n  slug: \"bruno-aguirre\"\n- name: \"Bruno Ghisi\"\n  twitter: \"brunogh\"\n  github: \"brunogh\"\n  website: \"http://brunoghisi.com\"\n  slug: \"bruno-ghisi\"\n- name: \"Bruno Miranda\"\n  github: \"brunomirand\"\n  website: \"https://www.linkedin.com/in/bruno-miranda-a6b510156/\"\n  slug: \"bruno-miranda\"\n- name: \"Bruno Prieto\"\n  twitter: \"brunoprietog\"\n  github: \"brunoprietog\"\n  slug: \"bruno-prieto\"\n- name: \"Bruno Sutic\"\n  twitter: \"brunosutic\"\n  github: \"bruno-\"\n  website: \"https://brunosutic.com\"\n  slug: \"bruno-sutic\"\n- name: \"Bryan Cantrill\"\n  github: \"bcantrill\"\n  website: \"https://dtrace.org/blogs/bmc\"\n  slug: \"bryan-cantrill\"\n- name: \"Bryan Frimin\"\n  twitter: \"gearnode\"\n  github: \"gearnode\"\n  website: \"https://www.frimin.fr/\"\n  slug: \"bryan-frimin\"\n- name: \"Bryan Guerrero\"\n  github: \"\"\n  slug: \"bryan-guerrero\"\n- name: \"Bryan Helmkamp\"\n  github: \"brynary\"\n  website: \"http://codeclimate.com\"\n  slug: \"bryan-helmkamp\"\n- name: \"Bryan Liles\"\n  github: \"bryanl\"\n  website: \"http://smartic.us\"\n  slug: \"bryan-liles\"\n- name: \"Bryan Powell\"\n  github: \"\"\n  slug: \"bryan-powell\"\n- name: \"Bryan Reinero\"\n  github: \"breinero-zz\"\n  website: \"http://bryanreinero.com/\"\n  slug: \"bryan-reinero\"\n- name: \"Bryan Thompson\"\n  github: \"\"\n  slug: \"bryan-thompson\"\n- name: \"Bryan Woods\"\n  github: \"bryanwoods\"\n  website: \"https://www.sayrhino.com\"\n  slug: \"bryan-woods\"\n- name: \"Bryana Knight\"\n  github: \"bryanaknight\"\n  slug: \"bryana-knight\"\n- name: \"Bryce Kerley\"\n  github: \"\"\n  slug: \"bryce-kerley\"\n- name: \"Bryce Simons\"\n  github: \"\"\n  slug: \"bryce-simons\"\n- name: \"Brynn Gitt\"\n  github: \"bgitt\"\n  slug: \"brynn-gitt\"\n- name: \"buty4649\"\n  github: \"\"\n  slug: \"buty4649\"\n- name: \"Byron Reese\"\n  github: \"\"\n  slug: \"byron-reese\"\n- name: \"Byron Woodfork\"\n  github: \"\"\n  slug: \"byron-woodfork\"\n- name: \"Caesar Chi\"\n  github: \"\"\n  slug: \"caesar-chi\"\n- name: \"Caio Almeida\"\n  github: \"caiosba\"\n  website: \"https://ca.ios.ba\"\n  slug: \"caio-almeida\"\n- name: \"Caitlin Palmer-Bright\"\n  github: \"\"\n  slug: \"caitlin-palmer-bright\"\n  aliases:\n    - name: \"Caitlin Palmer Bright\"\n      slug: \"caitlin-palmer-bright\"\n- name: \"Caleb Clausen\"\n  github: \"\"\n  slug: \"caleb-clausen\"\n- name: \"Caleb Denio\"\n  twitter: \"CalebDenio\"\n  github: \"cjdenio\"\n  website: \"https://calebden.io\"\n  slug: \"caleb-denio\"\n- name: \"Caleb Hearth\"\n  github: \"calebhearth\"\n  website: \"https://calebhearth.com\"\n  slug: \"caleb-hearth\"\n  aliases:\n    - name: \"Caleb Thompson\"\n      slug: \"caleb-thompson\"\n- name: \"Caleb Kaay\"\n  github: \"calebkm\"\n  slug: \"caleb-kaay\"\n  aliases:\n    - name: \"Caleb Matthiesen\"\n      slug: \"caleb-matthiesen\"\n- name: \"Caleb Muoki\"\n  github: \"\"\n  slug: \"caleb-muoki\"\n- name: \"Cameron Barrie\"\n  github: \"\"\n  slug: \"cameron-barrie\"\n- name: \"Cameron Daigle\"\n  github: \"camerond\"\n  website: \"http://camerondaigle.com\"\n  slug: \"cameron-daigle\"\n- name: \"Cameron Dutro\"\n  github: \"camertron\"\n  website: \"https://camerondutro.com\"\n  slug: \"cameron-dutro\"\n- name: \"Cameron Gose\"\n  github: \"goseinthemachine\"\n  slug: \"cameron-gose\"\n- name: \"Cameron Jacoby\"\n  github: \"cameronjacoby\"\n  slug: \"cameron-jacoby\"\n- name: \"Cameron Pope\"\n  github: \"theaboutbox\"\n  website: \"https://www.theaboutbox.com\"\n  slug: \"cameron-pope\"\n- name: \"Camille Fournier\"\n  github: \"\"\n  slug: \"camille-fournier\"\n- name: \"Camilo Lopez\"\n  github: \"\"\n  slug: \"camilo-lopez\"\n- name: \"Cang Shi Xian Ye (蒼時弦也)\"\n  github: \"\"\n  slug: \"cang-shi-xian-ye\"\n- name: \"Carina C. Zona\"\n  twitter: \"cczona\"\n  github: \"cczona\"\n  website: \"http://cczona.com\"\n  slug: \"carina-c-zona\"\n- name: \"Carl Coryell-Martin\"\n  github: \"\"\n  slug: \"carl-coryell-martin\"\n- name: \"Carl Lerche\"\n  twitter: \"carllerche\"\n  github: \"carllerche\"\n  slug: \"carl-lerche\"\n- name: \"Carl Woodward\"\n  github: \"\"\n  slug: \"carl-woodward\"\n- name: \"Carl Youngblood\"\n  github: \"\"\n  slug: \"carl-youngblood\"\n- name: \"Carla Urrea Stabile\"\n  twitter: \"CarlaStabile\"\n  github: \"carlastabile\"\n  website: \"https://carlastabile.tech\"\n  slug: \"carla-urrea-stabile\"\n- name: \"Carlo Flores\"\n  github: \"\"\n  slug: \"carlo-flores\"\n- name: \"Carlos Antonio da Silva\"\n  twitter: \"cantoniodasilva\"\n  github: \"carlosantoniodasilva\"\n  website: \"http://about.me/carlosantoniodasilva\"\n  slug: \"carlos-antonio-da-silva\"\n  aliases:\n    - name: \"Carlos Antonio\"\n      slug: \"carlos-antonio\"\n    - name: \"Carlos Antonio Da Silva\"\n      slug: \"carlos-antonio-da-silva\"\n- name: \"Carlos Brando\"\n  twitter: \"carlosbrando\"\n  github: \"carlosbrando\"\n  website: \"https://carlosbrando.com\"\n  slug: \"carlos-brando\"\n- name: \"Carlos Marchal\"\n  github: \"\"\n  slug: \"carlos-marchal\"\n- name: \"Carlos Rojas\"\n  github: \"\"\n  slug: \"carlos-rojas\"\n- name: \"Carlos Souza\"\n  twitter: \"caike\"\n  github: \"caike\"\n  website: \"https://csouza.me\"\n  slug: \"carlos-souza\"\n- name: \"Carme Mias\"\n  github: \"carmemias\"\n  website: \"https://carmemias.com\"\n  slug: \"carme-mias\"\n- name: \"Carmen Alvarez\"\n  github: \"\"\n  slug: \"carmen-alvarez\"\n- name: \"Carmen Chung\"\n  github: \"\"\n  slug: \"carmen-chung\"\n- name: \"Carmen Huidobro\"\n  twitter: \"hola_soy_milk\"\n  github: \"hola-soy-milk\"\n  website: \"https://carmenh.dev\"\n  slug: \"carmen-huidobro\"\n  aliases:\n    - name: \"Ramón Huidobro\"\n      slug: \"ramon-huidobro\"\n- name: \"Carmine Paolino\"\n  twitter: \"paolino\"\n  github: \"crmne\"\n  website: \"https://paolino.me\"\n  slug: \"carmine-paolino\"\n- name: \"Carolina Karklis\"\n  github: \"carolkarklis\"\n  website: \"https://twitter.com/carolkarklis\"\n  slug: \"carolina-karklis\"\n- name: \"Caroline Jobe\"\n  github: \"\"\n  slug: \"caroline-jobe\"\n- name: \"Caroline Salib\"\n  github: \"\"\n  slug: \"caroline-salib\"\n- name: \"Caroline Taymor\"\n  github: \"ctaymor\"\n  slug: \"caroline-taymor\"\n- name: \"Carolyn Cole\"\n  github: \"cec90\"\n  website: \"http://www.pitt.edu/~cec90/\"\n  slug: \"carolyn-cole\"\n- name: \"Carrick Rogers\"\n  github: \"carrickr\"\n  slug: \"carrick-rogers\"\n- name: \"Carrie Simon\"\n  github: \"\"\n  slug: \"carrie-simon\"\n- name: \"Casey Maucaulay\"\n  github: \"\"\n  slug: \"casey-maucaulay\"\n- name: \"Casey Rosenthal\"\n  github: \"\"\n  slug: \"casey-rosenthal\"\n- name: \"Casey Watts\"\n  twitter: \"heycaseywattsup\"\n  github: \"caseywatts\"\n  website: \"https://www.caseywatts.com\"\n  slug: \"casey-watts\"\n- name: \"Cassandra Cruz\"\n  github: \"lambdatastic\"\n  website: \"http://lambdatastic.github.io/\"\n  slug: \"cassandra-cruz\"\n- name: \"Cate Huston\"\n  github: \"\"\n  slug: \"cate-huston\"\n- name: \"Caterina Paun\"\n  github: \"\"\n  slug: \"caterina-paun\"\n- name: \"Catherine Jones\"\n  github: \"\"\n  slug: \"catherine-jones\"\n- name: \"Catherine Meyers\"\n  github: \"ccmeyers\"\n  slug: \"catherine-meyers\"\n- name: \"Catherine Ricafort McCreary\"\n  github: \"catherinerae\"\n  website: \"https://medium.com/confessions-of-a-bootcamp-grad\"\n  slug: \"catherine-ricafort-mccreary\"\n- name: \"Cecilia Rivero\"\n  github: \"\"\n  slug: \"cecilia-rivero\"\n- name: \"Cecy Correa\"\n  twitter: \"cecyc\"\n  github: \"cecyc\"\n  website: \"https://www.cecy.dev/\"\n  slug: \"cecy-correa\"\n- name: \"Celeen Rusk\"\n  github: \"celeen\"\n  slug: \"celeen-rusk\"\n- name: \"Celia King\"\n  github: \"\"\n  slug: \"celia-king\"\n- name: \"Celso Fernandes\"\n  twitter: \"celsovjf\"\n  github: \"fernandes\"\n  website: \"https://coding.com.br/\"\n  slug: \"celso-fernandes\"\n- name: \"Ceri Shaw\"\n  github: \"\"\n  slug: \"ceri-shaw\"\n- name: \"Cezary Kłos\"\n  twitter: \"cezaryklos\"\n  github: \"K4sku\"\n  slug: \"cezary-klos\"\n- name: \"Chad Dickerson\"\n  github: \"chaddickerson\"\n  slug: \"chad-dickerson\"\n- name: \"Chad Fowler\"\n  twitter: \"chadfowler\"\n  github: \"chad\"\n  website: \"http://chadfowler.com\"\n  slug: \"chad-fowler\"\n- name: \"Chad Pytel\"\n  github: \"cpytel\"\n  website: \"http://thoughtbot.com\"\n  slug: \"chad-pytel\"\n- name: \"Chad Woolley\"\n  github: \"thewoolleyman\"\n  linkedin: \"thewoolleyman\"\n  slug: \"chad-woolley\"\n- name: \"Chaitali Khangar\"\n  twitter: \"seeker_chaitali\"\n  github: \"chaitali-khangar\"\n  slug: \"chaitali-khangar\"\n- name: \"Chakri Uddaraju\"\n  github: \"\"\n  slug: \"chakri-uddaraju\"\n- name: \"Chakrit Wichian\"\n  twitter: \"chakrit\"\n  github: \"chakrit\"\n  website: \"http://chakrit.net\"\n  slug: \"chakrit-wichian\"\n- name: \"Chamod Gamage\"\n  github: \"chamod-gamage\"\n  slug: \"chamod-gamage\"\n  twitter: \"og_chamod\"\n- name: \"Chandra Carney\"\n  github: \"\"\n  slug: \"chandra-carney\"\n- name: \"Chanelle Henry\"\n  github: \"\"\n  slug: \"chanelle-henry\"\n- name: \"Chang Sau Sheong\"\n  github: \"sausheong\"\n  slug: \"chang-sau-sheong\"\n  aliases:\n    - name: \"Sau Sheong Chang\"\n      slug: \"sau-sheong-chang\"\n- name: \"Chantelle Isaacs\"\n  twitter: \"ChantelleBliss\"\n  github: \"chantelle-isaacs\"\n  website: \"https://chantelle-isaacs.github.io/\"\n  slug: \"chantelle-isaacs\"\n- name: \"Charity Majors\"\n  github: \"charity\"\n  website: \"https://twitter.com/mipsytipsy\"\n  slug: \"charity-majors\"\n- name: \"Charles Abbott\"\n  github: \"cwabbott\"\n  slug: \"charles-abbott\"\n- name: \"Charles Cornell\"\n  github: \"\"\n  slug: \"charles-cornell\"\n- name: \"Charles Lowell\"\n  twitter: \"cowboyd\"\n  github: \"cowboyd\"\n  website: \"https://frontside.com\"\n  slug: \"charles-lowell\"\n- name: \"Charles Max Wood\"\n  twitter: \"cmaxw\"\n  github: \"cmaxw\"\n  website: \"http://topenddevs.com\"\n  slug: \"charles-max-wood\"\n  aliases:\n    - name: \"Charles Wood\"\n      slug: \"charles-wood\"\n- name: \"Charles Oliver Nutter\"\n  twitter: \"headius\"\n  github: \"headius\"\n  website: \"https://blog.headius.com\"\n  slug: \"charles-oliver-nutter\"\n  aliases:\n    - name: \"Charles Nutter\"\n      slug: \"charles-nutter\"\n    - name: \"Charles O. Nutter\"\n      slug: \"charles-o-nutter\"\n- name: \"Charles Yeh\"\n  github: \"CharlesYeh\"\n  slug: \"charles-yeh\"\n- name: \"Charlie Hua\"\n  github: \"charlie-hua\"\n  slug: \"charlie-hua\"\n- name: \"Charlie Lee\"\n  github: \"\"\n  slug: \"charlie-lee\"\n- name: \"Charlie Savage\"\n  github: \"cfis\"\n  slug: \"charlie-savage\"\n- name: \"Charlie Somerville\"\n  github: \"\"\n  slug: \"charlie-somerville\"\n- name: \"Chase Douglas\"\n  github: \"\"\n  slug: \"chase-douglas\"\n- name: \"Chase McCarthy\"\n  github: \"code0100fun\"\n  website: \"https://code0100fun.com\"\n  slug: \"chase-mccarthy\"\n- name: \"Chelsea Kaufman\"\n  github: \"c-kaufman\"\n  slug: \"chelsea-kaufman\"\n- name: \"Chelsea Troy\"\n  twitter: \"HeyChelseaTroy\"\n  github: \"chelseatroy\"\n  website: \"http://www.chelseatroy.com\"\n  slug: \"chelsea-troy\"\n- name: \"Chen Zhao\"\n  github: \"\"\n  slug: \"chen-zhao\"\n- name: \"Cheryl Gore Schaefer\"\n  github: \"cherylschaefer\"\n  slug: \"cheryl-gore-schaefer\"\n- name: \"Cheryl Morgan\"\n  github: \"\"\n  slug: \"cheryl-morgan\"\n- name: \"Chie Kobayashi\"\n  github: \"cobachie\"\n  slug: \"chie-kobayashi\"\n- name: \"Chikahiro Tokoro\"\n  twitter: \"chikahirotokoro\"\n  github: \"kibitan\"\n  website: \"https://chikahirotokoro.com\"\n  slug: \"chikahiro-tokoro\"\n- name: \"Chinmay Naik\"\n  github: \"\"\n  slug: \"chinmay-naik\"\n- name: \"Chris Aitchison\"\n  github: \"\"\n  slug: \"chris-aitchison\"\n- name: \"Chris Arcand\"\n  twitter: \"chrisarcand\"\n  github: \"chrisarcand\"\n  website: \"https://www.chrisarcand.com\"\n  slug: \"chris-arcand\"\n- name: \"Chris Bloom\"\n  github: \"chrisbloom7\"\n  website: \"https://christopherbloom.com\"\n  slug: \"chris-bloom\"\n- name: \"Chris Boesch\"\n  github: \"\"\n  slug: \"chris-boesch\"\n- name: \"Chris Cha\"\n  github: \"lightucha\"\n  website: \"https://velog.io/@lightucha\"\n  slug: \"chris-cha\"\n- name: \"Chris Colòn\"\n  github: \"\"\n  slug: \"chris-colon\"\n- name: \"Chris Craybill\"\n  github: \"\"\n  slug: \"chris-craybill\"\n- name: \"Chris D'Aloisio\"\n  github: \"\"\n  slug: \"chris-d-aloisio\"\n- name: \"Chris Dillon\"\n  github: \"\"\n  slug: \"chris-dillon\"\n- name: \"Chris Dwan\"\n  github: \"cdwan\"\n  website: \"https://dwan.org\"\n  slug: \"chris-dwan\"\n- name: \"Chris Eppstein\"\n  github: \"chriseppstein\"\n  website: \"https://twitter.com/chriseppstein\"\n  slug: \"chris-eppstein\"\n- name: \"Chris Fung\"\n  github: \"aergonaut\"\n  website: \"https://chrisfung.dev\"\n  slug: \"chris-fung\"\n- name: \"Chris Gratigny\"\n  github: \"cgratigny\"\n  slug: \"chris-gratigny\"\n- name: \"Chris Hagmann\"\n  twitter: \"cdhagmann\"\n  github: \"chrishagmann-elaxus\"\n  slug: \"chris-hagmann\"\n  aliases:\n    - name: \"Chris Dean Hagmann\"\n      slug: \"chris-dean-hagmann\"\n    - name: \"Christopher Dean Hagmann\"\n      slug: \"christopher-dean-hagmann\"\n    - name: \"Christopher Hagmann\"\n      slug: \"christopher-hagmann\"\n    - name: \"chrishagmann-elaxus\"\n      slug: \"chrishagmann-elaxus\"\n- name: \"Chris Hasiński\"\n  twitter: \"khasinski\"\n  github: \"khasinski\"\n  slug: \"chris-hasinski\"\n  aliases:\n    - name: \"Chris Hasinski\"\n      slug: \"chris-hasinski\"\n    - name: \"Krzysztof Hasinski\"\n      slug: \"krzysztof-hasinski\"\n    - name: \"Krzysztof Hasiński\"\n      slug: \"krzysztof-hasinski\"\n- name: \"Chris Hobbs\"\n  github: \"ckhsponge\"\n  website: \"http://toonsy.net\"\n  slug: \"chris-hobbs\"\n- name: \"Chris Hoffman\"\n  github: \"chrishoffman\"\n  slug: \"chris-hoffman\"\n- name: \"Chris Howlett\"\n  twitter: \"chowlett09\"\n  github: \"asilano\"\n  slug: \"chris-howlett\"\n- name: \"Chris Hunt\"\n  twitter: \"chrishunt\"\n  github: \"chrishunt\"\n  website: \"http://www.chrishunt.co\"\n  slug: \"chris-hunt\"\n- name: \"Chris Kelly\"\n  github: \"amateurhuman\"\n  website: \"https://amateurhuman.com\"\n  slug: \"chris-kelly\"\n- name: \"Chris Kibble\"\n  github: \"\"\n  slug: \"chris-kibble\"\n- name: \"Chris Lawrence\"\n  github: \"mrchristoff\"\n  slug: \"chris-lawrence\"\n- name: \"Chris LoPresto\"\n  twitter: \"chrislopresto\"\n  github: \"chrislopresto\"\n  website: \"https://chrislopresto.com\"\n  slug: \"chris-lopresto\"\n- name: \"Chris Lowis\"\n  github: \"\"\n  slug: \"chris-lowis\"\n- name: \"Chris Maddox\"\n  github: \"tyre\"\n  slug: \"chris-maddox\"\n- name: \"Chris Mar\"\n  twitter: \"cmar\"\n  github: \"cmar\"\n  slug: \"chris-mar\"\n- name: \"Chris McCord\"\n  github: \"chrismccord\"\n  website: \"https://chrismccord.com\"\n  slug: \"chris-mccord\"\n- name: \"Chris Mckenzie\"\n  github: \"chrisface\"\n  slug: \"chris-mckenzie\"\n- name: \"Chris Morris\"\n  twitter: \"morriswchris\"\n  github: \"morriswchris\"\n  website: \"http://chris.themorrises.xyz\"\n  slug: \"chris-morris\"\n- name: \"Chris Nelson\"\n  github: \"\"\n  slug: \"chris-nelson\"\n- name: \"Chris O'Sullivan\"\n  twitter: \"thechrisoshow\"\n  github: \"thechrisoshow\"\n  website: \"https://www.thechrisoshow.com\"\n  slug: \"chris-o-sullivan\"\n- name: \"Chris Oliver\"\n  twitter: \"excid3\"\n  github: \"excid3\"\n  website: \"http://gorails.com\"\n  slug: \"chris-oliver\"\n- name: \"Chris Parsons\"\n  github: \"\"\n  slug: \"chris-parsons\"\n- name: \"Chris Power\"\n  twitter: \"typecraft_dev\"\n  github: \"cpow\"\n  website: \"https://typecraft.dev\"\n  slug: \"chris-power\"\n- name: \"Chris Powers\"\n  github: \"\"\n  slug: \"chris-powers\"\n- name: \"Chris Salzberg\"\n  github: \"shioyama\"\n  website: \"https://chrissalzberg.com\"\n  slug: \"chris-salzberg\"\n- name: \"Chris Seaton\"\n  twitter: \"ChrisGSeaton\"\n  github: \"chrisseaton\"\n  website: \"https://chrisseaton.com/\"\n  slug: \"chris-seaton\"\n- name: \"Chris Sexton\"\n  github: \"chrissexton\"\n  website: \"https://chrissexton.org\"\n  slug: \"chris-sexton\"\n- name: \"Chris Shea\"\n  github: \"\"\n  slug: \"chris-shea\"\n- name: \"Chris Smith\"\n  github: \"\"\n  slug: \"chris-smith\"\n- name: \"Chris Stringer\"\n  github: \"\"\n  slug: \"chris-stringer\"\n- name: \"Chris Vannoy\"\n  github: \"dummied\"\n  website: \"http://chrisvannoy.com\"\n  slug: \"chris-vannoy\"\n- name: \"Chris Wanstrath\"\n  github: \"defunkt\"\n  website: \"http://chriswanstrath.com/\"\n  slug: \"chris-wanstrath\"\n- name: \"Chris Waters\"\n  github: \"waters000\"\n  website: \"https://www.Hizzil.com\"\n  slug: \"chris-waters\"\n- name: \"Chris Williams\"\n  github: \"\"\n  slug: \"chris-williams\"\n- name: \"Chris Winslett\"\n  twitter: \"winsletts\"\n  github: \"winslett\"\n  website: \"http://winsletts.com/\"\n  slug: \"chris-winslett\"\n- name: \"Chris Wyckoff\"\n  github: \"\"\n  slug: \"chris-wyckoff\"\n- name: \"Chris Zetter\"\n  github: \"\"\n  slug: \"chris-zetter\"\n- name: \"Chris Zhu\"\n  github: \"czhu12\"\n  slug: \"chris-zhu\"\n- name: \"Chrissy Welsh\"\n  github: \"\"\n  slug: \"chrissy-welsh\"\n- name: \"Christen Rittiger\"\n  github: \"chr60\"\n  slug: \"christen-rittiger\"\n- name: \"Christian Bruckmayer\"\n  twitter: \"bruckmayer\"\n  github: \"chrisbr\"\n  website: \"https://bruckmayer.net\"\n  slug: \"christian-bruckmayer\"\n- name: \"Christian Gregg\"\n  github: \"\"\n  slug: \"christian-gregg\"\n- name: \"Christian Joudrey\"\n  github: \"\"\n  slug: \"christian-joudrey\"\n- name: \"Christian Koch\"\n  github: \"chriskoch\"\n  website: \"http://www.scandio.de\"\n  slug: \"christian-koch\"\n- name: \"Christian Sedlmair\"\n  github: \"\"\n  slug: \"christian-sedlmair\"\n- name: \"Christian Sousa\"\n  github: \"\"\n  slug: \"christian-sousa\"\n- name: \"Christina Gorton\"\n  github: \"\"\n  slug: \"christina-gorton\"\n- name: \"Christina Serra\"\n  github: \"\"\n  slug: \"christina-serra\"\n- name: \"Christine Seeman\"\n  twitter: \"tech_christine\"\n  github: \"cseeman\"\n  website: \"https://christine-seeman.com/\"\n  slug: \"christine-seeman\"\n- name: \"Christoph Gockel\"\n  github: \"\"\n  slug: \"christoph-gockel\"\n- name: \"Christoph Lipautz\"\n  twitter: \"lipdaguit\"\n  github: \"unused\"\n  slug: \"christoph-lipautz\"\n- name: \"Christophe Philemotte\"\n  github: \"toch\"\n  website: \"https://ibakesoftware.com\"\n  slug: \"christophe-philemotte\"\n- name: \"Christopher \\\"Aji\\\" Slater\"\n  github: \"doodlingdev\"\n  slug: \"christopher-aji-slater\"\n  aliases:\n    - name: \"Aji Slater\"\n      slug: \"aji-slater\"\n    - name: \"Ajina Slater\"\n      slug: \"ajina-slater\"\n- name: \"Christopher Bertels\"\n  github: \"\"\n  slug: \"christopher-bertels\"\n- name: \"Christopher Coleman\"\n  github: \"\"\n  slug: \"christopher-coleman\"\n- name: \"Christopher Greene\"\n  github: \"chigreene\"\n  slug: \"christopher-greene\"\n- name: \"Christopher Krailo\"\n  github: \"\"\n  slug: \"christopher-krailo\"\n- name: \"Christopher Rigor\"\n  github: \"crigor\"\n  slug: \"christopher-rigor\"\n- name: \"Christopher Saez\"\n  github: \"\"\n  slug: \"christopher-saez\"\n- name: \"Christopher Sexton\"\n  github: \"csexton\"\n  website: \"http://www.codeography.com/\"\n  slug: \"christopher-sexton\"\n- name: \"Christopher Turtle\"\n  github: \"\"\n  slug: \"christopher-turtle\"\n- name: \"Chuck Lauer Vose\"\n  github: \"vosechu\"\n  website: \"https://www.chuckvose.com\"\n  slug: \"chuck-lauer-vose\"\n- name: \"Chyrelle Lewis\"\n  github: \"\"\n  slug: \"chyrelle-lewis\"\n- name: \"Cindy Backman\"\n  github: \"\"\n  slug: \"cindy-backman\"\n- name: \"Cindy Liu\"\n  github: \"cindyliu923\"\n  slug: \"cindy-liu\"\n- name: \"Cirdes Henrique\"\n  twitter: \"cirdesh\"\n  github: \"cirdes\"\n  website: \"https://www.linkana.com\"\n  slug: \"cirdes-henrique\"\n- name: \"CJ Avilla\"\n  twitter: \"cjav_dev\"\n  github: \"cjavdev\"\n  website: \"http://cjav.dev\"\n  slug: \"cj-avilla\"\n- name: \"Claudio Andrei\"\n  github: \"\"\n  slug: \"claudio-andrei\"\n- name: \"Claudio Baccigalupo\"\n  github: \"claudiob\"\n  website: \"http://claudiob.github.io\"\n  slug: \"claudio-baccigalupo\"\n- name: \"Claus Lensbøl\"\n  github: \"\"\n  slug: \"claus-lensbol\"\n- name: \"Clayton Flesher\"\n  github: \"claytonflesher\"\n  slug: \"clayton-flesher\"\n- name: \"Clem Capel-Bird\"\n  github: \"\"\n  slug: \"clem-capel-bird\"\n- name: \"Clemens Helm\"\n  github: \"clemenshelm\"\n  slug: \"clemens-helm\"\n- name: \"Clint Gibler\"\n  github: \"\"\n  slug: \"clint-gibler\"\n- name: \"Clint Shryock\"\n  github: \"\"\n  slug: \"clint-shryock\"\n- name: \"Clément Prod'homme\"\n  github: \"\"\n  slug: \"clement-prod-homme\"\n- name: \"Coby Randquist\"\n  github: \"\"\n  slug: \"coby-randquist\"\n- name: \"Cody Norman\"\n  twitter: \"cnorm35\"\n  github: \"cnorm35\"\n  website: \"https://codynorman.com\"\n  slug: \"cody-norman\"\n- name: \"Cody Stringham\"\n  github: \"\"\n  slug: \"cody-stringham\"\n- name: \"Colby Swandale\"\n  twitter: \"oceanicpanda\"\n  github: \"colby-swandale\"\n  slug: \"colby-swandale\"\n- name: \"Cole Robertson\"\n  github: \"\"\n  slug: \"cole-robertson\"\n- name: \"Colin Fleming\"\n  github: \"cursive-ide\"\n  website: \"https://cursive-ide.com\"\n  slug: \"colin-fleming\"\n- name: \"Colin Fulton\"\n  github: \"\"\n  slug: \"colin-fulton\"\n- name: \"Colin Gemmell\"\n  github: \"pythonandchips\"\n  slug: \"colin-gemmell\"\n- name: \"Colin Jones\"\n  github: \"trptcolin\"\n  slug: \"colin-jones\"\n- name: \"Colin Kelley\"\n  github: \"ColinDKelley\"\n  slug: \"colin-kelley\"\n- name: \"Colin Loretz\"\n  twitter: \"colinloretz\"\n  github: \"colinloretz\"\n  website: \"https://colinloretz.com\"\n  slug: \"colin-loretz\"\n- name: \"Colin Pulton\"\n  github: \"\"\n  slug: \"colin-pulton\"\n- name: \"Colin Thomas-Arnold\"\n  github: \"\"\n  slug: \"colin-thomas-arnold\"\n- name: \"Colleen Lavin\"\n  github: \"\"\n  slug: \"colleen-lavin\"\n- name: \"Colleen Schnettler\"\n  twitter: \"leenyburger\"\n  github: \"leenyburger\"\n  website: \"https://www.hammerstone.dev\"\n  slug: \"colleen-schnettler\"\n- name: \"Collin Donnell\"\n  github: \"collindonnell\"\n  website: \"https://collindonnell.com\"\n  slug: \"collin-donnell\"\n- name: \"Collin Jilbert\"\n  twitter: \"collin_jilbert\"\n  github: \"cjilbert504\"\n  website: \"https://www.linkedin.com/in/collin-jilbert/\"\n  slug: \"collin-jilbert\"\n- name: \"Collis Ta'eed\"\n  github: \"\"\n  slug: \"collis-ta-eed\"\n- name: \"Conrad Irwin\"\n  twitter: \"conradirwin\"\n  github: \"conradirwin\"\n  website: \"http://twitter.com/ConradIrwin\"\n  slug: \"conrad-irwin\"\n- name: \"Coraline Ada Ehmke\"\n  twitter: \"CoralineAda\"\n  github: \"coralineada\"\n  website: \"http://where.coraline.codes/\"\n  slug: \"coraline-ada-ehmke\"\n  aliases:\n    - name: \"Coraline Ehmke\"\n      slug: \"coraline-ehmke\"\n- name: \"Coraline Clark\"\n  github: \"\"\n  slug: \"coraline-clark\"\n- name: \"Corey Donohoe\"\n  github: \"\"\n  slug: \"corey-donohoe\"\n- name: \"Corey Ehmke\"\n  github: \"\"\n  slug: \"corey-ehmke\"\n- name: \"Corey Haines\"\n  twitter: \"coreyhaines\"\n  github: \"coreyhaines\"\n  website: \"https://www.coreyhaines.com\"\n  slug: \"corey-haines\"\n- name: \"Corey Martin\"\n  github: \"csm123\"\n  slug: \"corey-martin\"\n- name: \"Corey Woodcox\"\n  github: \"\"\n  slug: \"corey-woodcox\"\n- name: \"Cory Chamblin\"\n  github: \"chamblin\"\n  website: \"http://chambl.in/\"\n  slug: \"cory-chamblin\"\n- name: \"Cory Flanigan\"\n  github: \"seeflanigan\"\n  slug: \"cory-flanigan\"\n- name: \"Cory Leistikow\"\n  github: \"bluevajra\"\n  website: \"https://www.bluevajra.com\"\n  slug: \"cory-leistikow\"\n- name: \"Cory Watson\"\n  github: \"gphat\"\n  website: \"http://www.onemogin.com\"\n  slug: \"cory-watson\"\n- name: \"Cosmo Martinez\"\n  github: \"\"\n  slug: \"cosmo-martinez\"\n- name: \"Costi\"\n  github: \"lucascosti\"\n  website: \"https://lucascosti.com\"\n  slug: \"costi\"\n- name: \"Courteney Ervin\"\n  github: \"\"\n  slug: \"courteney-ervin\"\n- name: \"Courtney Eckhardt\"\n  github: \"\"\n  slug: \"courtney-eckhardt\"\n- name: \"Craig Buchek\"\n  twitter: \"CraigBuchek\"\n  github: \"booch\"\n  website: \"http://craigbuchek.com\"\n  slug: \"craig-buchek\"\n- name: \"Craig Kerstiens\"\n  github: \"craigkerstiens\"\n  website: \"http://www.craigkerstiens.com\"\n  slug: \"craig-kerstiens\"\n- name: \"Craig Lehmann\"\n  github: \"craiglrock\"\n  slug: \"craig-lehmann\"\n- name: \"Craig Muth\"\n  github: \"\"\n  slug: \"craig-muth\"\n- name: \"Craig Norford\"\n  twitter: \"craignorford\"\n  github: \"CraigDoesCode\"\n  slug: \"craig-norford\"\n- name: \"Creating an Illustrated Talk\"\n  github: \"\"\n  slug: \"creating-an-illustrated-talk\"\n- name: \"Cristian Chirtos\"\n  github: \"\"\n  slug: \"cristian-chirtos\"\n- name: \"Cristian Planas\"\n  twitter: \"crplanas\"\n  github: \"gawyn\"\n  slug: \"cristian-planas\"\n- name: \"Cristian Rasch\"\n  github: \"\"\n  slug: \"cristian-rasch\"\n- name: \"Crystal Tia Martin\"\n  github: \"\"\n  slug: \"crystal-tia-martin\"\n- name: \"Cyril David\"\n  github: \"\"\n  slug: \"cyril-david\"\n- name: \"Cyril Duchon-Doris\"\n  github: \"\"\n  slug: \"cyril-duchon-doris\"\n- name: \"Cyril Kato\"\n  github: \"\"\n  slug: \"cyril-kato\"\n- name: \"Cyril Rohr\"\n  twitter: \"crohr\"\n  github: \"crohr\"\n  website: \"https://ouestcode.com\"\n  slug: \"cyril-rohr\"\n- name: \"Cyrille Courtiere\"\n  github: \"ccyrille\"\n  website: \"https://www.klaxit.com/\"\n  slug: \"cyrille-courtiere\"\n- name: \"César Eduardo\"\n  github: \"\"\n  slug: \"cesar-eduardo\"\n- name: \"Da Dou (大兜)\"\n  github: \"\"\n  slug: \"da-dou\"\n- name: \"Daichi Kamiyama\"\n  github: \"dak2\"\n  slug: \"daichi-kamiyama\"\n- name: \"Daichi KUDO\"\n  github: \"\"\n  slug: \"daichi-kudo\"\n- name: \"Daisuke Aritomo\"\n  twitter: \"osyoyu\"\n  github: \"osyoyu\"\n  website: \"https://osyoyu.com\"\n  slug: \"daisuke-aritomo\"\n- name: \"Daisuke Aritomo (@osyoyu)\"\n  github: \"\"\n  slug: \"daisuke-aritomo-osyoyu\"\n- name: \"Daisuke Fujimura\"\n  github: \"fd00\"\n  slug: \"daisuke-fujimura\"\n- name: \"Daisuke Inoue\"\n  github: \"\"\n  slug: \"daisuke-inoue\"\n- name: \"Daisuke Yamashita\"\n  twitter: \"yamaz\"\n  github: \"yamaz\"\n  slug: \"daisuke-yamashita\"\n- name: \"Dajana\"\n  github: \"\"\n  slug: \"dajana\"\n- name: \"Dajana Günther\"\n  github: \"\"\n  slug: \"dajana-guenther\"\n- name: \"Dallas Pool\"\n  github: \"\"\n  slug: \"dallas-pool\"\n- name: \"Dalma Boros\"\n  github: \"dalmaboros\"\n  slug: \"dalma-boros\"\n- name: \"Damian Janowsky\"\n  github: \"\"\n  slug: \"damian-janowsky\"\n- name: \"Damian Le Nouaille\"\n  github: \"\"\n  slug: \"damian-le-nouaille\"\n- name: \"Damian Legawiec\"\n  twitter: \"damianlegawiec\"\n  github: \"damianlegawiec\"\n  website: \"https://getvendo.com\"\n  slug: \"damian-legawiec\"\n- name: \"Damien Matthieu\"\n  github: \"\"\n  slug: \"damien-matthieu\"\n- name: \"Damir Svrtan\"\n  github: \"damirsvrtan\"\n  website: \"http://damir.svrtan.me/\"\n  slug: \"damir-svrtan\"\n- name: \"Damir Zekić\"\n  github: \"\"\n  slug: \"damir-zekic\"\n- name: \"Dan Bird\"\n  github: \"\"\n  slug: \"dan-bird\"\n- name: \"Dan Cheail\"\n  github: \"\"\n  slug: \"dan-cheail\"\n- name: \"Dan DiMaggio\"\n  github: \"\"\n  slug: \"dan-dimaggio\"\n- name: \"Dan Draper\"\n  github: \"\"\n  slug: \"dan-draper\"\n- name: \"Dan Fitzpatrick\"\n  github: \"dfitzpat\"\n  slug: \"dan-fitzpatrick\"\n- name: \"Dan Heintzelman\"\n  github: \"Dan-Heintzelman\"\n  slug: \"dan-heintzelman\"\n- name: \"Dan Hough\"\n  github: \"\"\n  slug: \"dan-hough\"\n- name: \"Dan Itsara\"\n  github: \"ditsara\"\n  slug: \"dan-itsara\"\n- name: \"Dan Kozlowski\"\n  github: \"dankozlowski\"\n  slug: \"dan-kozlowski\"\n- name: \"Dan Laush\"\n  github: \"\"\n  slug: \"dan-laush\"\n- name: \"Dan Lucraft\"\n  github: \"\"\n  slug: \"dan-lucraft\"\n- name: \"Dan Melton\"\n  github: \"danmelton\"\n  slug: \"dan-melton\"\n- name: \"Dan Meyer\"\n  twitter: \"DanMeyer\"\n  github: \"danmeyer\"\n  slug: \"dan-meyer\"\n- name: \"Dan Moore\"\n  twitter: \"mooreds\"\n  github: \"mooreds\"\n  website: \"https://fusionauth.io\"\n  slug: \"dan-moore\"\n- name: \"Dan Phillips\"\n  twitter: \"d_philla\"\n  github: \"dphilla\"\n  website: \"https://wasmchicago.org\"\n  slug: \"dan-phillips\"\n- name: \"Dan Quan\"\n  github: \"djquan\"\n  website: \"https://quan.io\"\n  slug: \"dan-quan\"\n- name: \"Dan Sharp\"\n  github: \"drsharp\"\n  website: \"http://about.me/drsharp\"\n  slug: \"dan-sharp\"\n- name: \"Dan Sinclair\"\n  github: \"\"\n  slug: \"dan-sinclair\"\n- name: \"Dan Singerman\"\n  github: \"\"\n  slug: \"dan-singerman\"\n- name: \"Dan Solo\"\n  github: \"\"\n  slug: \"dan-solo\"\n- name: \"Dan Webb\"\n  github: \"\"\n  slug: \"dan-webb\"\n- name: \"Dan Wellman\"\n  github: \"\"\n  slug: \"dan-wellman\"\n- name: \"Dan Yoder\"\n  github: \"\"\n  slug: \"dan-yoder\"\n- name: \"Dana Grey\"\n  github: \"\"\n  slug: \"dana-grey\"\n- name: \"Dana Scheider\"\n  github: \"\"\n  slug: \"dana-scheider\"\n- name: \"Dana Sherson\"\n  github: \"\"\n  slug: \"dana-sherson\"\n- name: \"Daniel\"\n  github: \"\"\n  slug: \"daniel\"\n- name: \"Daniel Ackerman\"\n  github: \"danieth\"\n  slug: \"daniel-ackerman\"\n- name: \"Daniel Azuma\"\n  twitter: \"danielazuma\"\n  github: \"dazuma\"\n  website: \"http://www.daniel-azuma.com/\"\n  slug: \"daniel-azuma\"\n- name: \"Daniel Baark\"\n  github: \"\"\n  slug: \"daniel-baark\"\n- name: \"Daniel Bengl\"\n  github: \"cuddlybunion341\"\n  website: \"https://cb341.net\"\n  slug: \"daniel-bengl\"\n- name: \"Daniel Bovensiepen\"\n  twitter: \"bovensiepen\"\n  github: \"bovi\"\n  slug: \"daniel-bovensiepen\"\n- name: \"Daniel Carral\"\n  github: \"dcarral\"\n  website: \"https://dcarral.org\"\n  slug: \"daniel-carral\"\n- name: \"Daniel Colson\"\n  github: \"composerinteralia\"\n  website: \"https://danieljamescolson.com\"\n  slug: \"daniel-colson\"\n- name: \"Daniel Curtis\"\n  github: \"\"\n  slug: \"daniel-curtis\"\n- name: \"Daniel Doubrovkine\"\n  twitter: \"dblockdotorg\"\n  github: \"dblock\"\n  website: \"https://code.dblock.org\"\n  slug: \"daniel-doubrovkine\"\n- name: \"Daniel Farina\"\n  github: \"fdr\"\n  slug: \"daniel-farina\"\n  aliases:\n    - name: \"Dan Farina\"\n      slug: \"dan-farina\"\n- name: \"Daniel Fone\"\n  github: \"danielfone\"\n  website: \"https://daniel.fone.net.nz\"\n  slug: \"daniel-fone\"\n- name: \"Daniel Huckstep\"\n  github: \"darkhelmet\"\n  website: \"https://verboselogging.com/\"\n  slug: \"daniel-huckstep\"\n- name: \"Daniel Huss\"\n  github: \"daniel-n-huss\"\n  slug: \"daniel-huss\"\n- name: \"Daniel Lucraft\"\n  github: \"\"\n  slug: \"daniel-lucraft\"\n- name: \"Daniel Magliola\"\n  twitter: \"dmagliola\"\n  github: \"dmagliola\"\n  website: \"http://danielmagliola.com\"\n  slug: \"daniel-magliola\"\n- name: \"Daniel Medina\"\n  github: \"fez3d\"\n  slug: \"daniel-medina\"\n- name: \"Daniel Neagaru\"\n  twitter: \"digeex_security\"\n  github: \"danielonsecurity\"\n  website: \"https://danielonsecurity.com/\"\n  slug: \"daniel-neagaru\"\n- name: \"Daniel Nguyen\"\n  github: \"\"\n  slug: \"daniel-nguyen\"\n- name: \"Daniel Nolan\"\n  github: \"danielnolan\"\n  website: \"http://danielnolan.com\"\n  slug: \"daniel-nolan\"\n- name: \"Daniel Paulus\"\n  github: \"\"\n  slug: \"daniel-paulus\"\n- name: \"Daniel Pritchett\"\n  twitter: \"dpritchett\"\n  github: \"dpritchett\"\n  mastodon: \"https://hachyderm.io/@dpritchett\"\n  website: \"https://dpritchett.net\"\n  slug: \"daniel-pritchett\"\n- name: \"Daniel Schadd\"\n  github: \"\"\n  slug: \"daniel-schadd\"\n- name: \"Daniel Schierbeck\"\n  github: \"\"\n  slug: \"daniel-schierbeck\"\n- name: \"Daniel Schweighöfer\"\n  github: \"\"\n  slug: \"daniel-schweighofer\"\n- name: \"Daniel Spector\"\n  github: \"\"\n  slug: \"daniel-spector\"\n- name: \"Daniel Susveila\"\n  github: \"\"\n  slug: \"daniel-susveila\"\n- name: \"Daniel Susviela\"\n  github: \"dsusviela\"\n  slug: \"daniel-susviela\"\n- name: \"Daniel Vartanov\"\n  github: \"danielvartanov\"\n  website: \"http://stackoverflow.com/users/203174/daniel-vartanov\"\n  slug: \"daniel-vartanov\"\n- name: \"Daniela Velasquez\"\n  github: \"danielavelasquez\"\n  slug: \"daniela-velasquez\"\n- name: \"Daniela Wellisz\"\n  github: \"\"\n  slug: \"daniela-wellisz\"\n- name: \"Daniele Bottillo\"\n  github: \"\"\n  slug: \"daniele-bottillo\"\n- name: \"Danielle Adams\"\n  twitter: \"adamzdanielle\"\n  github: \"danielleadams\"\n  website: \"https://danielle.lol\"\n  slug: \"danielle-adams\"\n- name: \"Danielle Gordon\"\n  twitter: \"danijadegordon\"\n  github: \"dani-g328\"\n  website: \"https://dani-g328.github.io/dgordon-Portfolio/\"\n  slug: \"danielle-gordon\"\n- name: \"Danilo Tupinambá\"\n  github: \"dantupi\"\n  website: \"https://www.linkedin.com/in/danilo-tupinamba\"\n  slug: \"danilo-tupinamba\"\n- name: \"Danish Khan\"\n  github: \"\"\n  slug: \"danish-khan\"\n- name: \"Danny Berzon\"\n  github: \"\"\n  slug: \"danny-berzon\"\n- name: \"Danny Blitz\"\n  github: \"\"\n  slug: \"danny-blitz\"\n- name: \"Danny Glunz\"\n  github: \"\"\n  slug: \"danny-glunz\"\n- name: \"Danny Guinther\"\n  twitter: \"dannyguinther\"\n  github: \"tdg5\"\n  website: \"http://tdg5.com\"\n  slug: \"danny-guinther\"\n- name: \"Danny Olson\"\n  github: \"dbolson\"\n  website: \"http://dbolson.github.io/\"\n  slug: \"danny-olson\"\n- name: \"Danny Ramos\"\n  twitter: \"muydanny\"\n  github: \"muydanny\"\n  slug: \"danny-ramos\"\n- name: \"Darcy Laycock\"\n  twitter: \"Sutto\"\n  github: \"sutto\"\n  website: \"https://sutto.net\"\n  slug: \"darcy-laycock\"\n- name: \"Darin Wilson\"\n  github: \"darin\"\n  website: \"http://darinwilson.info\"\n  slug: \"darin-wilson\"\n- name: \"Darius Murawski\"\n  github: \"dariusgm\"\n  website: \"https://murawski.blog\"\n  slug: \"darius-murawski\"\n- name: \"Darren Broemmer\"\n  github: \"dbroemme\"\n  slug: \"darren-broemmer\"\n- name: \"Darren Smith\"\n  github: \"\"\n  slug: \"darren-smith\"\n- name: \"Darío Macchi\"\n  github: \"vairix-dmacchi\"\n  slug: \"dario-macchi\"\n- name: \"Dave Allie\"\n  github: \"\"\n  slug: \"dave-allie\"\n- name: \"Dave Aronson\"\n  twitter: \"DaveAronson\"\n  github: \"davearonson\"\n  website: \"https://www.Codosaur.us\"\n  slug: \"dave-aronson\"\n- name: \"Dave Astels\"\n  github: \"\"\n  slug: \"dave-astels\"\n- name: \"Dave Doolin\"\n  github: \"doolin\"\n  website: \"http://dool.in\"\n  slug: \"dave-doolin\"\n- name: \"Dave Giunta\"\n  github: \"\"\n  slug: \"dave-giunta\"\n- name: \"Dave Herman\"\n  twitter: \"littlecalculist\"\n  github: \"dherman\"\n  website: \"https://dherman.dev\"\n  slug: \"dave-herman\"\n- name: \"Dave Hoover\"\n  twitter: \"davehoover\"\n  github: \"redsquirrel\"\n  slug: \"dave-hoover\"\n- name: \"Dave Kapp\"\n  github: \"\"\n  slug: \"dave-kapp\"\n- name: \"Dave McCrory\"\n  github: \"\"\n  slug: \"dave-mccrory\"\n- name: \"Dave Neary\"\n  github: \"\"\n  slug: \"dave-neary\"\n- name: \"Dave Ott\"\n  twitter: \"daveott\"\n  github: \"daveott\"\n  website: \"http://daveott.net\"\n  slug: \"dave-ott\"\n- name: \"Dave Rappin\"\n  github: \"\"\n  slug: \"dave-rappin\"\n- name: \"Dave Rupert\"\n  twitter: \"davatron5000\"\n  github: \"davatron5000\"\n  website: \"http://daverupert.com\"\n  slug: \"dave-rupert\"\n- name: \"Dave Tapley\"\n  twitter: \"davetapley\"\n  github: \"davetapley\"\n  website: \"https://davetapley.com\"\n  slug: \"dave-tapley\"\n- name: \"Dave Thomas\"\n  github: \"pragdave\"\n  website: \"https://pragdave.me\"\n  slug: \"dave-thomas\"\n- name: \"Dave Woodall\"\n  github: \"fakefarm\"\n  website: \"http://www.davewoodall.com\"\n  slug: \"dave-woodall\"\n- name: \"David A. Black\"\n  github: \"\"\n  slug: \"david-a-black\"\n- name: \"David Allen\"\n  github: \"\"\n  slug: \"david-allen\"\n- name: \"David Bock\"\n  twitter: \"bokmann\"\n  github: \"bokmann\"\n  website: \"http://LoudounCodes.org\"\n  slug: \"david-bock\"\n- name: \"David Brady\"\n  twitter: \"dbrady\"\n  github: \"dbrady\"\n  website: \"http://www.whydavewhy.com/\"\n  slug: \"david-brady\"\n- name: \"David Calavera\"\n  github: \"\"\n  slug: \"david-calavera\"\n- name: \"David Carlin\"\n  github: \"\"\n  slug: \"david-carlin\"\n- name: \"David Chelimsky\"\n  github: \"dchelimsky\"\n  slug: \"david-chelimsky\"\n- name: \"David Cohen\"\n  github: \"groovemonkey\"\n  website: \"https://tutorialinux.com\"\n  slug: \"david-cohen\"\n- name: \"David Cohen of TechStars\"\n  github: \"\"\n  slug: \"david-cohen-of-techstars\"\n- name: \"David Copeland\"\n  github: \"davetron5000\"\n  website: \"http://www.naildrivin5.com\"\n  slug: \"david-copeland\"\n  aliases:\n    - name: \"Dave Copeland\"\n      slug: \"dave-copeland\"\n- name: \"David Cornu\"\n  github: \"\"\n  slug: \"david-cornu\"\n- name: \"David Czarnecki\"\n  twitter: \"CzarneckiD\"\n  github: \"czarneckid\"\n  website: \"https://davidczarnecki.com\"\n  slug: \"david-czarnecki\"\n- name: \"David Dahl\"\n  github: \"daviddahl\"\n  website: \"https://txt.ist\"\n  slug: \"david-dahl\"\n- name: \"David Furber\"\n  github: \"\"\n  slug: \"david-furber\"\n- name: \"David Goodlad\"\n  github: \"\"\n  slug: \"david-goodlad\"\n- name: \"David Heinemeier Hansson\"\n  twitter: \"dhh\"\n  github: \"dhh\"\n  website: \"https://dhh.dk\"\n  slug: \"david-heinemeier-hansson\"\n- name: \"David Henner\"\n  twitter: \"drhenner\"\n  github: \"drhenner\"\n  website: \"http://www.ror-e.com\"\n  slug: \"david-henner\"\n- name: \"David Hill\"\n  github: \"esmale\"\n  slug: \"david-hill\"\n- name: \"David Kelly\"\n  github: \"\"\n  slug: \"david-kelly\"\n- name: \"David Kerber\"\n  github: \"\"\n  slug: \"david-kerber\"\n- name: \"David Koontz\"\n  github: \"\"\n  slug: \"david-koontz\"\n- name: \"David Lantos\"\n  github: \"\"\n  slug: \"david-lantos\"\n- name: \"David Masover\"\n  github: \"\"\n  slug: \"david-masover\"\n- name: \"David McDonald\"\n  github: \"david-pm\"\n  website: \"https://davidpm.io\"\n  slug: \"david-mcdonald\"\n- name: \"David Muto\"\n  twitter: \"pseudomuto\"\n  github: \"pseudomuto\"\n  website: \"https://pseudomuto.com/\"\n  slug: \"david-muto\"\n- name: \"David Padilla\"\n  github: \"dabit\"\n  slug: \"david-padilla\"\n- name: \"David Paluy\"\n  github: \"dpaluy\"\n  slug: \"david-paluy\"\n  twitter: \"dpaluy\"\n- name: \"David Peláez\"\n  github: \"\"\n  slug: \"david-pelaez\"\n- name: \"David Richards\"\n  github: \"\"\n  slug: \"david-richards\"\n- name: \"David Rogers\"\n  github: \"davidrogers-unity\"\n  website: \"http://www.unity3d.com\"\n  slug: \"david-rogers\"\n- name: \"David Ryder\"\n  github: \"\"\n  slug: \"david-ryder\"\n- name: \"David Smith\"\n  github: \"\"\n  slug: \"david-smith\"\n- name: \"David Somers\"\n  github: \"\"\n  slug: \"david-somers\"\n- name: \"David South\"\n  github: \"\"\n  slug: \"david-south\"\n- name: \"David Stephenson\"\n  github: \"davidystephenson\"\n  website: \"https://davidystephenson.com\"\n  slug: \"david-stephenson\"\n- name: \"David T. Crosby\"\n  github: \"\"\n  slug: \"david-t-crosby\"\n- name: \"David Trejo\"\n  github: \"dtrejo\"\n  website: \"https://duskk.com\"\n  slug: \"david-trejo\"\n- name: \"Davis Frank\"\n  github: \"infews\"\n  website: \"http://dwf.bigpencil.net\"\n  slug: \"davis-frank\"\n- name: \"Davis Weimer\"\n  github: \"dav1s-ops\"\n  website: \"https://www.dw-portfolio.com\"\n  slug: \"davis-weimer\"\n- name: \"Davy Stevenson\"\n  github: \"davy\"\n  slug: \"davy-stevenson\"\n- name: \"Dawid Jaskot\"\n  github: \"dajvido\"\n  website: \"https://dajvido.com\"\n  slug: \"dawid-jaskot\"\n- name: \"Dawid Pośliński\"\n  twitter: \"PoslinskiNet\"\n  github: \"poslinskinet\"\n  website: \"http://selleo.com\"\n  slug: \"dawid-poslinski\"\n- name: \"Dawn E. Collett\"\n  github: \"\"\n  slug: \"dawn-e-collett\"\n- name: \"Dawn Richardson\"\n  github: \"dawner\"\n  slug: \"dawn-richardson\"\n- name: \"Dayana Mick\"\n  github: \"aydamacink\"\n  slug: \"dayana-mick\"\n- name: \"Dean Wampler\"\n  github: \"\"\n  slug: \"dean-wampler\"\n- name: \"Debbie Teakle\"\n  github: \"\"\n  slug: \"debbie-teakle\"\n- name: \"Declan Whelan\"\n  github: \"dwhelan\"\n  website: \"http://dpwhelan.com/blog\"\n  slug: \"declan-whelan\"\n- name: \"DeeDee Lavinder\"\n  twitter: \"ddlavinder\"\n  github: \"deedeelavinder\"\n  slug: \"deedee-lavinder\"\n- name: \"Deepak Mahakale\"\n  github: \"\"\n  slug: \"deepak-mahakale\"\n- name: \"Deepan Kumar\"\n  github: \"\"\n  slug: \"deepan-kumar\"\n- name: \"Delmont\"\n  github: \"\"\n  slug: \"delmont\"\n- name: \"Delton Ding\"\n  twitter: \"DeltonDing\"\n  github: \"dsh0416\"\n  website: \"https://coderemixer.com\"\n  slug: \"delton-ding\"\n- name: \"Demir Zekić\"\n  github: \"\"\n  slug: \"demir-zekic\"\n- name: \"Demirhan Aydin\"\n  github: \"\"\n  slug: \"demirhan-aydin\"\n- name: \"Denis Defreyne\"\n  github: \"\"\n  slug: \"denis-defreyne\"\n- name: \"Denis Müller\"\n  github: \"denis-mueller\"\n  slug: \"denis-muller\"\n- name: \"Denise Yu\"\n  twitter: \"deniseyu21\"\n  github: \"deniseyu\"\n  website: \"https://deniseyu.io\"\n  slug: \"denise-yu\"\n- name: \"Denitsa Belogusheva\"\n  github: \"denitsa\"\n  slug: \"denitsa-belogusheva\"\n- name: \"Dennis Collinson\"\n  github: \"\"\n  slug: \"dennis-collinson\"\n- name: \"Dennis Eusebio\"\n  github: \"thoughtandtheory\"\n  website: \"http://www.thoughtandtheory.com/\"\n  slug: \"dennis-eusebio\"\n- name: \"Dennis Pacewicz\"\n  github: \"\"\n  slug: \"dennis-pacewicz\"\n- name: \"Dennis Ushakov\"\n  github: \"\"\n  slug: \"dennis-ushakov\"\n- name: \"Denny de la Haye\"\n  github: \"\"\n  slug: \"denny-de-la-haye\"\n- name: \"Denys Medynskyi\"\n  github: \"denys-medynskyi\"\n  slug: \"denys-medynskyi\"\n- name: \"Denys Yahofarov\"\n  github: \"denyago\"\n  slug: \"denys-yahofarov\"\n- name: \"Derek Carter\"\n  github: \"goozbach\"\n  website: \"http://blog.friocorte.com/\"\n  slug: \"derek-carter\"\n- name: \"Derek Prior\"\n  github: \"derekprior\"\n  website: \"http://prioritized.net\"\n  slug: \"derek-prior\"\n- name: \"Derek Sivers\"\n  github: \"\"\n  slug: \"derek-sivers\"\n- name: \"Derk-Jan Karrenbeld\"\n  github: \"\"\n  slug: \"derk-jan-karrenbeld\"\n- name: \"Derrick Ko\"\n  twitter: \"derrickko\"\n  github: \"derrickko\"\n  website: \"http://derrickko.com\"\n  slug: \"derrick-ko\"\n- name: \"Desi McAdam\"\n  github: \"\"\n  slug: \"desi-mcadam\"\n- name: \"Desmond Rawls\"\n  github: \"desmondrawls\"\n  slug: \"desmond-rawls\"\n- name: \"Devin Clark\"\n  github: \"devinclark\"\n  website: \"https://www.devin-clark.com\"\n  slug: \"devin-clark\"\n- name: \"Devlin Daley\"\n  github: \"\"\n  slug: \"devlin-daley\"\n- name: \"Devon Estes\"\n  twitter: \"devoncestes\"\n  github: \"devonestes\"\n  website: \"https://www.devonestes.com\"\n  slug: \"devon-estes\"\n- name: \"Dewayne VanHoozer\"\n  github: \"\"\n  slug: \"dewayne-vanhoozer\"\n- name: \"Deyan Dobrinov\"\n  github: \"\"\n  slug: \"deyan-dobrinov\"\n- name: \"Diane Delallée\"\n  github: \"dianedelallee\"\n  website: \"https://www.fatalement.com\"\n  slug: \"diane-delallee\"\n- name: \"Diego Algorta\"\n  twitter: \"oboxodo\"\n  github: \"oboxodo\"\n  website: \"https://ob.oxo.do\"\n  slug: \"diego-algorta\"\n- name: \"Diego Steiner\"\n  github: \"\"\n  slug: \"diego-steiner\"\n- name: \"Diesha Cooper\"\n  github: \"\"\n  slug: \"diesha-cooper\"\n- name: \"Dilum Navanjana\"\n  github: \"\"\n  slug: \"dilum-navanjana\"\n- name: \"Dima\"\n  github: \"\"\n  slug: \"dima\"\n- name: \"Dimitar Dimitrov\"\n  github: \"mitio\"\n  website: \"https://ddimitrov.name\"\n  slug: \"dimitar-dimitrov\"\n- name: \"Dimiter Petrov\"\n  github: \"crackofdusk\"\n  slug: \"dimiter-petrov\"\n- name: \"Dimitry Salahutdinov\"\n  github: \"\"\n  slug: \"dimitry-salahutdinov\"\n- name: \"Dinah Shi\"\n  github: \"dinahshi\"\n  slug: \"dinah-shi\"\n- name: \"Dinesh Kumar\"\n  github: \"\"\n  website: \"https://www.linkedin.com/in/railsfactory/\"\n  slug: \"dinesh-kumar\"\n- name: \"Dinshaw Gobhai\"\n  github: \"dinshaw\"\n  website: \"http://dinshawgobhai.com\"\n  slug: \"dinshaw-gobhai\"\n- name: \"Dirk Breuer\"\n  github: \"code-later\"\n  slug: \"dirk-breuer\"\n- name: \"Dirkjan Bussink\"\n  github: \"\"\n  slug: \"dirkjan-bussink\"\n- name: \"Dmitrijs Zubriks\"\n  github: \"dizlv\"\n  slug: \"dmitrijs-zubriks\"\n- name: \"Dmitry Non\"\n  github: \"\"\n  slug: \"dmitry-non\"\n- name: \"Dmitry Petrashko\"\n  github: \"darkdimius\"\n  website: \"https://d-d.me/\"\n  slug: \"dmitry-petrashko\"\n- name: \"Dmitry Pogrebnoy\"\n  github: \"dmitrypogrebnoy\"\n  website: \"https://pogrebnoy.inc@gmail.com\"\n  slug: \"dmitry-pogrebnoy\"\n- name: \"Dmitry Sadovnikov\"\n  github: \"\"\n  slug: \"dmitry-sadovnikov\"\n- name: \"Dmitry Salahutdinov\"\n  twitter: \"dsalahutdinov1\"\n  github: \"dsalahutdinov\"\n  website: \"https://dsalahutdinov.github.io/\"\n  slug: \"dmitry-salahutdinov\"\n  aliases:\n    - name: \"Dimitry Salahutdinov\"\n      slug: \"dimitry-salahutdinov\"\n- name: \"Dmitry Tsepelev\"\n  twitter: \"dmitrytsepelev\"\n  github: \"dmitrytsepelev\"\n  website: \"https://dmitrytsepelev.dev\"\n  slug: \"dmitry-tsepelev\"\n- name: \"Dmitry Vorotilin\"\n  twitter: \"rO_Oute\"\n  github: \"route\"\n  website: \"http://nopecode.com\"\n  slug: \"dmitry-vorotilin\"\n- name: \"Do Xuan Thanh\"\n  github: \"\"\n  slug: \"do-xuan-thanh\"\n- name: \"Doc Norton\"\n  twitter: \"DocOnDev\"\n  github: \"docondev\"\n  website: \"http://www.docondev.com/\"\n  slug: \"doc-norton\"\n- name: \"Dolganov Sergey\"\n  github: \"\"\n  slug: \"dolganov-sergey\"\n- name: \"Dominic Lizarraga\"\n  twitter: \"domlizarraga_\"\n  github: \"dominiclizarraga\"\n  website: \"https://dominiclizarraga.github.io/\"\n  slug: \"dominic-lizarraga\"\n- name: \"Dominique Flabbi\"\n  github: \"dominiquefl\"\n  slug: \"dominique-flabbi\"\n- name: \"Don Barlow\"\n  github: \"\"\n  slug: \"don-barlow\"\n- name: \"Don Morrison\"\n  github: \"\"\n  slug: \"don-morrison\"\n- name: \"Don Mullen\"\n  github: \"\"\n  slug: \"don-mullen\"\n- name: \"Don Pottinger\"\n  github: \"\"\n  slug: \"don-pottinger\"\n- name: \"Don Werve\"\n  twitter: \"matadon\"\n  github: \"matadon\"\n  website: \"http://werve.net\"\n  slug: \"don-werve\"\n- name: \"Donal McBreen\"\n  github: \"djmb\"\n  slug: \"donal-mcbreen\"\n- name: \"Dorian Becker\"\n  github: \"\"\n  slug: \"dorian-becker\"\n- name: \"Dorian Lupu\"\n  github: \"\"\n  slug: \"dorian-lupu\"\n- name: \"Dorian Marie\"\n  twitter: \"dorianmariefr\"\n  github: \"dorianmariefr\"\n  website: \"https://dorianmarie.fr\"\n  slug: \"dorian-marie\"\n- name: \"Dorothy Jane Wingrove\"\n  github: \"notthepoint\"\n  website: \"https://dotdoes.tech\"\n  slug: \"dorothy-jane-wingrove\"\n- name: \"Dot Wingrove\"\n  github: \"\"\n  slug: \"dot-wingrove\"\n- name: \"Doug Smith\"\n  twitter: \"dougbtv\"\n  github: \"dougbtv\"\n  website: \"http://www.dougbtv.com\"\n  slug: \"doug-smith\"\n- name: \"Dr. Nic Williams\"\n  twitter: \"drnic\"\n  github: \"drnic\"\n  website: \"https://mocra.com\"\n  slug: \"dr-nic-williams\"\n- name: \"Drew Blas\"\n  github: \"\"\n  slug: \"drew-blas\"\n- name: \"Drew Bragg\"\n  twitter: \"DRBragg\"\n  github: \"drbragg\"\n  website: \"https://www.drbragg.dev\"\n  slug: \"drew-bragg\"\n- name: \"Drew Hoskins\"\n  github: \"\"\n  slug: \"drew-hoskins\"\n- name: \"Drew Neil\"\n  github: \"nelstrom\"\n  website: \"http://drewneil.com\"\n  slug: \"drew-neil\"\n- name: \"Du Gia Huy\"\n  github: \"\"\n  slug: \"du-gia-huy\"\n- name: \"duck-falcon\"\n  github: \"\"\n  slug: \"duck-falcon\"\n- name: \"Duncan Brown\"\n  github: \"\"\n  slug: \"duncan-brown\"\n- name: \"Duncan Davidson\"\n  github: \"duncan\"\n  slug: \"duncan-davidson\"\n  website: \"https://duncan.dev\"\n  aliases:\n    - name: \"James Duncan Davidson\"\n      slug: \"james-duncan-davidson\"\n- name: \"Dusan Orlovic\"\n  github: \"\"\n  slug: \"dusan-orlovic\"\n- name: \"Dustin Haefele Tschan\"\n  github: \"\"\n  slug: \"dustin-haefele-tschan\"\n- name: \"Dustin Haefele-Tschanz\"\n  github: \"\"\n  slug: \"dustin-haefele-tschanz\"\n- name: \"Dutta Deshmukh\"\n  github: \"\"\n  slug: \"dutta-deshmukh\"\n- name: \"Dylan Andrews\"\n  github: \"dylanandrews\"\n  website: \"https://dylanandrews.dev\"\n  slug: \"dylan-andrews\"\n- name: \"Dylan Blakemore\"\n  github: \"\"\n  slug: \"dylan-blakemore\"\n- name: \"Dylan Lacey\"\n  twitter: \"_DLN_\"\n  github: \"dlnongithub\"\n  slug: \"dylan-lacey\"\n- name: \"Dávid Halász\"\n  twitter: \"halaszdavid\"\n  github: \"skateman\"\n  website: \"http://www.skateman.eu\"\n  slug: \"david-halasz\"\n  aliases:\n    - name: \"David Halasz\"\n      slug: \"david-halasz\"\n- name: \"Débora Fernandes\"\n  twitter: \"deboradeveloper\"\n  github: \"debborafernandess\"\n  website: \"https://www.linkedin.com/in/debborafernandess\"\n  slug: \"debora-fernandes\"\n  aliases:\n    - name: \"Debora Fernandes\"\n      slug: \"debora-fernandes\"\n- name: \"Ebi Patterson\"\n  github: \"ebiltwin\"\n  slug: \"ebi-patterson\"\n- name: \"Ebun Segun\"\n  github: \"\"\n  slug: \"ebun-segun\"\n- name: \"Ed Finkler\"\n  github: \"\"\n  slug: \"ed-finkler\"\n- name: \"Ed Robinson\"\n  github: \"\"\n  slug: \"ed-robinson\"\n- name: \"Ed Weng\"\n  github: \"\"\n  slug: \"ed-weng\"\n- name: \"Eddie Kao\"\n  github: \"\"\n  slug: \"eddie-kao\"\n- name: \"Edoardo Serra\"\n  github: \"eserra\"\n  slug: \"edoardo-serra\"\n- name: \"Edouard Chin\"\n  github: \"edouard-chin\"\n  website: \"https://catana.dev\"\n  slug: \"edouard-chin\"\n- name: \"Eduard Koller\"\n  github: \"\"\n  slug: \"eduard-koller\"\n- name: \"Eduardo Gutierrez\"\n  github: \"\"\n  slug: \"eduardo-gutierrez\"\n- name: \"Eduardo Hernández\"\n  github: \"\"\n  slug: \"eduardo-hernandez\"\n- name: \"Eduardo Nakanishi\"\n  github: \"\"\n  slug: \"eduardo-nakanishi\"\n- name: \"Edward Chiu\"\n  github: \"edwardchiu38\"\n  slug: \"edward-chiu\"\n- name: \"Edward Kim\"\n  github: \"\"\n  slug: \"edward-kim\"\n- name: \"Edward Ocampo-Gooding\"\n  github: \"\"\n  slug: \"edward-ocampo-gooding\"\n- name: \"Edy Silva\"\n  github: \"geeksilva97\"\n  website: \"https://codesilva.github.io\"\n  slug: \"edy-silva\"\n  aliases:\n    - name: \"Edigleysson Silva\"\n      slug: \"edigleysson-silva\"\n- name: \"Eemeli Aro\"\n  twitter: \"eemeli_aro\"\n  github: \"eemeli\"\n  website: \"https://mefi.social/@eemeli\"\n  slug: \"eemeli-aro\"\n- name: \"Eeva-Jonna Panula\"\n  github: \"\"\n  slug: \"eeva-jonna-panula\"\n- name: \"Egor Homakov\"\n  github: \"\"\n  slug: \"egor-homakov\"\n- name: \"Egor Iskrenkov\"\n  github: \"eiskrenkov\"\n  slug: \"egor-iskrenkov\"\n- name: \"ei-ei-eiichi\"\n  github: \"ei-ei-eiichi\"\n  slug: \"ei-ei-eiichi\"\n- name: \"Eileen Alayce\"\n  twitter: \"eileencodes\"\n  github: \"eileencodes\"\n  website: \"https://eileencodes.com\"\n  slug: \"eileen-alayce\"\n  aliases:\n    - name: \"Eileen M. Uchitelle\"\n      slug: \"eileen-m-uchitelle\"\n    - name: \"Eileen M Uchitelle\"\n      slug: \"eileen-m-uchitelle\"\n    - name: \"Eileen Uchitelle\"\n      slug: \"eileen-uchitelle\"\n- name: \"Ejay Canaria\"\n  github: \"\"\n  slug: \"ejay-canaria\"\n- name: \"Ekechi \\\"Iyke\\\" Ikenna\"\n  github: \"\"\n  slug: \"ekechi-iyke-ikenna\"\n- name: \"Elain Marina\"\n  github: \"\"\n  slug: \"elain-marina\"\n- name: \"Elaina Natario\"\n  github: \"enatario\"\n  website: \"https://elainanatario.com\"\n  slug: \"elaina-natario\"\n- name: \"Elaine Marino\"\n  github: \"\"\n  slug: \"elaine-marino\"\n- name: \"Elayne Juten\"\n  github: \"ejuten\"\n  slug: \"elayne-juten\"\n- name: \"Elcuervo\"\n  github: \"\"\n  slug: \"elcuervo\"\n- name: \"Eleanor Kiefel Haggerty\"\n  github: \"eleanorakh\"\n  website: \"https://eleanorkh.com\"\n  slug: \"eleanor-kiefel-haggerty\"\n- name: \"Eleanor McHugh\"\n  github: \"feyeleanor\"\n  website: \"http://about.me/eleanor_mchugh\"\n  slug: \"eleanor-mchugh\"\n- name: \"Eleanor Saitta\"\n  github: \"\"\n  slug: \"eleanor-saitta\"\n- name: \"Elena Tănăsoiu\"\n  github: \"elenatanasoiu\"\n  website: \"https://elenatanasoiu.com/\"\n  slug: \"elena-tanasoiu\"\n  aliases:\n    - name: \"Elena Tanasoiu\"\n      slug: \"elena-tanasoiu\"\n- name: \"Eli Barreto\"\n  github: \"\"\n  slug: \"eli-barreto\"\n- name: \"Eli Kroumova\"\n  github: \"elika\"\n  slug: \"eli-kroumova\"\n- name: \"Elia Gamberi\"\n  github: \"Gimbardo\"\n  slug: \"elia-gamberi\"\n  aliases:\n    - name: \"Gamberi Elia\"\n      slug: \"gamberi-elia\"\n- name: \"Elia Schito\"\n  github: \"elia\"\n  website: \"http://elia.schito.me\"\n  slug: \"elia-schito\"\n- name: \"Elisabeth Hendrickson\"\n  github: \"testobsessed\"\n  website: \"http://www.testobsessed.com\"\n  slug: \"elisabeth-hendrickson\"\n- name: \"Elise Huard\"\n  twitter: \"elise_huard\"\n  github: \"elisehuard\"\n  slug: \"elise-huard\"\n- name: \"Elise Shaffer\"\n  github: \"eliseshaffer\"\n  website: \"https://eliseshaffer.com\"\n  slug: \"elise-shaffer\"\n- name: \"Elise Worthy\"\n  github: \"\"\n  slug: \"elise-worthy\"\n- name: \"Elisha Tan\"\n  github: \"\"\n  slug: \"elisha-tan\"\n- name: \"Eliza de Jager\"\n  github: \"\"\n  slug: \"eliza-de-jager\"\n- name: \"Eliza Sorensen\"\n  github: \"\"\n  slug: \"eliza-sorensen\"\n- name: \"Elizabeth Barron\"\n  twitter: \"ElizabethN\"\n  github: \"elizabethn\"\n  slug: \"elizabeth-barron\"\n- name: \"Elizabeth Orwig\"\n  github: \"orwigeg\"\n  slug: \"elizabeth-orwig\"\n- name: \"Elle Meredith\"\n  twitter: \"aemeredith\"\n  github: \"elle\"\n  website: \"http://aemeredith.com\"\n  slug: \"elle-meredith\"\n- name: \"Ellen Koenig\"\n  github: \"\"\n  slug: \"ellen-koenig\"\n- name: \"Elliott Hilaire\"\n  github: \"\"\n  slug: \"elliott-hilaire\"\n- name: \"Elliott Kember\"\n  github: \"\"\n  slug: \"elliott-kember\"\n- name: \"Eloy Durán\"\n  github: \"\"\n  slug: \"eloy-duran\"\n  aliases:\n    - name: \"Eloy Duran\"\n      slug: \"eloy-duran\"\n- name: \"Elshadai Tegegn\"\n  twitter: \"pour_qua\"\n  github: \"elshadaik\"\n  website: \"https://elshadaik.github.io\"\n  slug: \"elshadai-tegegn\"\n- name: \"Ely Alvarado\"\n  github: \"elyalvarado\"\n  slug: \"ely-alvarado\"\n- name: \"Emanuele Delbono\"\n  twitter: \"emadb\"\n  github: \"emadb\"\n  website: \"http://emanueledelbono.it\"\n  slug: \"emanuele-delbono\"\n- name: \"Emi Imanishi\"\n  github: \"harembi\"\n  slug: \"emi-imanishi\"\n- name: \"Emil Ong\"\n  github: \"emilong\"\n  slug: \"emil-ong\"\n- name: \"Emil Stolarsky\"\n  twitter: \"EmilStolarsky\"\n  github: \"es\"\n  website: \"https://emil.dev\"\n  slug: \"emil-stolarsky\"\n- name: \"Emiliano Della Casa\"\n  github: \"emilianodellacasa\"\n  website: \"http://emilianodellacasa.com\"\n  slug: \"emiliano-della-casa\"\n- name: \"Emilio Gutter\"\n  github: \"\"\n  slug: \"emilio-gutter\"\n- name: \"Emily Freeman\"\n  github: \"emilyfreeman\"\n  website: \"http://www.emilyfreeman.io\"\n  slug: \"emily-freeman\"\n- name: \"Emily Harber\"\n  twitter: \"thecodepixi\"\n  github: \"thecodepixi\"\n  website: \"https://thecodepixi.dev\"\n  slug: \"emily-harber\"\n- name: \"Emily Samp\"\n  github: \"egiurleo\"\n  website: \"https://emilysamp.dev\"\n  slug: \"emily-samp\"\n  aliases:\n    - name: \"Emily Giurleo\"\n      slug: \"emily-giurleo\"\n- name: \"Emily Stolfo\"\n  twitter: \"EmStolfo\"\n  github: \"estolfo\"\n  slug: \"emily-stolfo\"\n- name: \"Emily Wangler\"\n  github: \"ewangler\"\n  slug: \"emily-wangler\"\n- name: \"Emily Xie\"\n  github: \"\"\n  slug: \"emily-xie\"\n- name: \"Emma Barnes\"\n  twitter: \"has_many_books\"\n  github: \"\"\n  slug: \"emma-barnes\"\n- name: \"Emma Beynon\"\n  github: \"\"\n  slug: \"emma-beynon\"\n- name: \"Emma Gabriel\"\n  twitter: \"emma_v_gabriel\"\n  github: \"emmaviolet\"\n  slug: \"emma-gabriel\"\n- name: \"Emma Haruka Iwao\"\n  twitter: \"Yuryu\"\n  github: \"yuryu\"\n  slug: \"emma-haruka-iwao\"\n- name: \"Emmanuel Hayford\"\n  twitter: \"siaw23\"\n  github: \"siaw23\"\n  slug: \"emmanuel-hayford\"\n- name: \"Ender Ahmet Yurt\"\n  twitter: \"eayurt\"\n  github: \"enderahmetyurt\"\n  website: \"https://enderahmetyurt.com\"\n  slug: \"ender-ahmet-yurt\"\n- name: \"Enrico Carlesso\"\n  github: \"carlesso\"\n  slug: \"enrico-carlesso\"\n- name: \"Enrico Teotti\"\n  twitter: \"agenteo\"\n  github: \"agenteo\"\n  website: \"https://enricoteotti.com\"\n  slug: \"enrico-teotti\"\n- name: \"Enrique Mogollán\"\n  github: \"mogox\"\n  website: \"https://mogox.tumblr.com/\"\n  slug: \"enrique-mogollan\"\n  aliases:\n    - name: \"Enrique Morellón\"\n      slug: \"enrique-morellon\"\n- name: \"Enzo Fabbiani\"\n  github: \"\"\n  slug: \"enzo-fabbiani\"\n- name: \"Eoin Coffey\"\n  github: \"ecoffey\"\n  website: \"https://eoinisawesome.com\"\n  slug: \"eoin-coffey\"\n- name: \"Eric Allam\"\n  github: \"\"\n  slug: \"eric-allam\"\n- name: \"Eric Allen\"\n  twitter: \"InterwebAlchemy\"\n  github: \"ericrallen\"\n  website: \"https://ericrallen.dev/\"\n  slug: \"eric-allen\"\n- name: \"Eric Halverson\"\n  twitter: \"elhalvers\"\n  github: \"elhalvers\"\n  slug: \"eric-halverson\"\n- name: \"Eric Hayes\"\n  github: \"hayesr\"\n  slug: \"eric-hayes\"\n- name: \"Eric Hodel\"\n  github: \"drbrain\"\n  website: \"http://blog.segment7.net\"\n  slug: \"eric-hodel\"\n- name: \"Eric Ivancich\"\n  github: \"\"\n  slug: \"eric-ivancich\"\n- name: \"Eric Lindvall\"\n  twitter: \"lindvall\"\n  github: \"eric\"\n  website: \"http://bitmonkey.net\"\n  slug: \"eric-lindvall\"\n- name: \"Eric Mahurin\"\n  github: \"\"\n  slug: \"eric-mahurin\"\n- name: \"Eric Mill\"\n  twitter: \"konklone\"\n  github: \"konklone\"\n  website: \"https://konklone.com\"\n  slug: \"eric-mill\"\n- name: \"Eric Mueller\"\n  github: \"nevinera\"\n  slug: \"eric-mueller\"\n- name: \"Eric Proulx\"\n  github: \"\"\n  slug: \"eric-proulx\"\n- name: \"Eric Redmond\"\n  twitter: \"coderoshi\"\n  github: \"coderoshi\"\n  website: \"https://www.linkedin.com/in/coderoshi\"\n  slug: \"eric-redmond\"\n- name: \"Eric Ries\"\n  github: \"\"\n  slug: \"eric-ries\"\n- name: \"Eric Roberts\"\n  github: \"ericroberts\"\n  website: \"http://ericroberts.ca\"\n  slug: \"eric-roberts\"\n- name: \"Eric Saupe\"\n  twitter: \"ericsaupe\"\n  github: \"ericsaupe\"\n  website: \"http://ericsaupe.com\"\n  slug: \"eric-saupe\"\n- name: \"Eric Saxby\"\n  github: \"sax\"\n  website: \"http://litp.org\"\n  slug: \"eric-saxby\"\n- name: \"Eric Tillberg\"\n  github: \"thrillberg\"\n  slug: \"eric-tillberg\"\n- name: \"Eric Weinstein\"\n  github: \"ericqweinstein\"\n  website: \"http://ericweinste.in/\"\n  slug: \"eric-weinstein\"\n- name: \"Eric West\"\n  github: \"edubkendo\"\n  website: \"http://ericwest.io\"\n  slug: \"eric-west\"\n- name: \"Erica Naughton\"\n  github: \"\"\n  slug: \"erica-naughton\"\n- name: \"Erica Sosa\"\n  github: \"esosa0\"\n  slug: \"erica-sosa\"\n- name: \"Erica Weistrand\"\n  github: \"weistrand\"\n  slug: \"erica-weistrand\"\n- name: \"Erie Mueller\"\n  github: \"\"\n  slug: \"erie-mueller\"\n- name: \"Erik Berlin\"\n  github: \"sferik\"\n  slug: \"erik-berlin\"\n  aliases:\n    - name: \"Erik Michaels-Ober\"\n      slug: \"erik-michaels-ober\"\n- name: \"Erik Guzman\"\n  twitter: \"talk2megooseman\"\n  github: \"talk2megooseman\"\n  website: \"https://twitch.tv/talk2megooseman\"\n  slug: \"erik-guzman\"\n- name: \"Erik Hatcher\"\n  github: \"\"\n  slug: \"erik-hatcher\"\n- name: \"Erika Carlson\"\n  github: \"erikakcarlson\"\n  slug: \"erika-carlson\"\n- name: \"Eriko Sugiyama\"\n  twitter: \"suuuuengch\"\n  github: \"ericgpks\"\n  slug: \"eriko-sugiyama\"\n- name: \"Erin Claudio\"\n  github: \"ErinClaudio\"\n  slug: \"erin-claudio\"\n- name: \"Erin Page\"\n  github: \"\"\n  slug: \"erin-page\"\n- name: \"Erin Paget\"\n  github: \"\"\n  slug: \"erin-paget\"\n- name: \"Erin Pintozzi\"\n  github: \"\"\n  slug: \"erin-pintozzi\"\n- name: \"Erin Quinn\"\n  github: \"equinn125\"\n  slug: \"erin-quinn\"\n- name: \"Ernesto Tagwerker\"\n  github: \"etagwerker\"\n  website: \"https://www.etagwerker.com\"\n  slug: \"ernesto-tagwerker\"\n- name: \"Ernie Miller\"\n  twitter: \"erniemiller\"\n  github: \"ernie\"\n  website: \"https://ernie.io\"\n  slug: \"ernie-miller\"\n- name: \"Errol Schmidt\"\n  twitter: \"esquaredesign\"\n  github: \"esquarenews\"\n  website: \"https://reinteractive.com\"\n  slug: \"errol-schmidt\"\n- name: \"Erwin Kroon\"\n  github: \"\"\n  slug: \"erwin-kroon\"\n- name: \"Eréndira García\"\n  github: \"\"\n  slug: \"erendira-garcia\"\n- name: \"Espartaco Palma\"\n  github: \"esparta\"\n  website: \"https://esparta.co\"\n  slug: \"espartaco-palma\"\n- name: \"Esther Barthel\"\n  github: \"\"\n  slug: \"esther-barthel\"\n- name: \"Esther Olatunde\"\n  twitter: \"MsEOlatunde\"\n  github: \"esteedqueen\"\n  website: \"https://estherolatunde.com\"\n  slug: \"esther-olatunde\"\n- name: \"Ethan Garofolo\"\n  twitter: \"ethangarofolo\"\n  github: \"juanpaco\"\n  slug: \"ethan-garofolo\"\n- name: \"Ethan Gunderson\"\n  github: \"\"\n  slug: \"ethan-gunderson\"\n- name: \"Ethan Vizitei\"\n  github: \"evizitei\"\n  slug: \"ethan-vizitei\"\n- name: \"Etrex Kuo\"\n  github: \"\"\n  slug: \"etrex-kuo\"\n- name: \"Eugene Kalenkovich\"\n  github: \"unclegene\"\n  slug: \"eugene-kalenkovich\"\n- name: \"Eugene Kenny\"\n  github: \"eugeneius\"\n  slug: \"eugene-kenny\"\n- name: \"Evan D. Light\"\n  github: \"\"\n  slug: \"evan-d-light\"\n- name: \"Evan Dorn\"\n  github: \"idahoev\"\n  website: \"http://idahoev.com\"\n  slug: \"evan-dorn\"\n- name: \"Evan Henshaw-Plath\"\n  github: \"\"\n  slug: \"evan-henshaw-plath\"\n- name: \"Evan Keller\"\n  github: \"\"\n  slug: \"evan-keller\"\n- name: \"Evan Light\"\n  github: \"\"\n  slug: \"evan-light\"\n- name: \"Evan Machnic\"\n  twitter: \"emachnic\"\n  github: \"emachnic\"\n  website: \"http://broadmac.net\"\n  slug: \"evan-machnic\"\n- name: \"Evan Petrie\"\n  github: \"\"\n  slug: \"evan-petrie\"\n- name: \"Evan Phoenix\"\n  twitter: \"evanphx\"\n  github: \"evanphx\"\n  website: \"https://evanphx.dev\"\n  slug: \"evan-phoenix\"\n- name: \"Evgeni Dzhelyov\"\n  github: \"edzhelyov\"\n  slug: \"evgeni-dzhelyov\"\n- name: \"Evgeni Kunev\"\n  github: \"\"\n  slug: \"evgeni-kunev\"\n- name: \"Evgeny Li\"\n  github: \"exAspArk\"\n  slug: \"evgeny-li\"\n- name: \"Ezekiel Templin\"\n  twitter: \"ezkl\"\n  github: \"ezkl\"\n  website: \"https://ezkl.dev\"\n  slug: \"ezekiel-templin\"\n- name: \"Ezra Zygmuntowicz\"\n  github: \"ezmobius\"\n  website: \"http://stuffstr.com\"\n  slug: \"ezra-zygmuntowicz\"\n- name: \"Fabian (afknapping)\"\n  github: \"\"\n  slug: \"fabian-afknapping\"\n- name: \"Fabiano Beselga\"\n  github: \"\"\n  slug: \"fabiano-beselga\"\n- name: \"Fabienne Bremond\"\n  github: \"\"\n  slug: \"fabienne-bremond\"\n- name: \"Fabio Akita\"\n  twitter: \"akitaonrails\"\n  github: \"akitaonrails\"\n  website: \"http://www.akitaonrails.com\"\n  slug: \"fabio-akita\"\n- name: \"Fabio Leandro Janiszevski\"\n  twitter: \"fabiosammy\"\n  github: \"fabiosammy\"\n  slug: \"fabio-leandro-janiszevski\"\n- name: \"Fabio Neves\"\n  github: \"\"\n  slug: \"fabio-neves\"\n- name: \"Fabrizio Monti\"\n  github: \"delphaber\"\n  slug: \"fabrizio-monti\"\n- name: \"Fable Tales\"\n  github: \"fables-tales\"\n  slug: \"fable-tales\"\n  website: \"https://penelope.zone\"\n  aliases:\n    - name: \"Penelope Phippen\"\n      slug: \"penelope-phippen\"\n    - name: \"Sam Phippen\"\n      slug: \"sam-phippen\"\n- name: \"Facundo Busto\"\n  github: \"\"\n  slug: \"facundo-busto\"\n- name: \"Fan Sheng You (范聖佑)\"\n  github: \"\"\n  slug: \"fan-sheng-you\"\n- name: \"Farrah Bostic\"\n  github: \"\"\n  slug: \"farrah-bostic\"\n- name: \"Federico Brubacher\"\n  github: \"\"\n  slug: \"federico-brubacher\"\n- name: \"Federico Brubacher y Bruno Aguirre\"\n  github: \"\"\n  slug: \"federico-brubacher-y-bruno-aguirre\"\n- name: \"Federico Builes\"\n  github: \"\"\n  slug: \"federico-builes\"\n- name: \"Federico Carrone\"\n  github: \"\"\n  slug: \"federico-carrone\"\n- name: \"Federico Parodi\"\n  github: \"jimmy2k\"\n  slug: \"federico-parodi\"\n- name: \"Federico Ramallo\"\n  github: \"framallo\"\n  slug: \"federico-ramallo\"\n- name: \"Federico Ramoso\"\n  github: \"\"\n  slug: \"federico-ramoso\"\n- name: \"Federico Soria\"\n  github: \"fedesoria\"\n  website: \"http://www.airbnb.com\"\n  slug: \"federico-soria\"\n- name: \"Felix Clack\"\n  github: \"\"\n  slug: \"felix-clack\"\n- name: \"Felix Dominguez\"\n  github: \"dacat\"\n  slug: \"felix-dominguez\"\n- name: \"Felix Stüber\"\n  github: \"\"\n  slug: \"felix-stueber\"\n- name: \"Ferdinand Niedermann\"\n  github: \"nerdinand\"\n  slug: \"ferdinand-niedermann\"\n- name: \"Ferdous Nasri\"\n  twitter: \"ferbsx\"\n  github: \"ferbsx\"\n  website: \"https://www.linkedin.com/in/ferbsx/\"\n  slug: \"ferdous-nasri\"\n- name: \"Fernand Galiana\"\n  github: \"\"\n  slug: \"fernand-galiana\"\n- name: \"Fernando Briano\"\n  github: \"\"\n  slug: \"fernando-briano\"\n- name: \"Fernando E. Silva Jacquier\"\n  github: \"\"\n  slug: \"fernando-e-silva-jacquier\"\n- name: \"Fernando Hamasaki de Amorim\"\n  twitter: \"Prodis\"\n  github: \"prodis\"\n  website: \"https://fernandohamasaki.com\"\n  slug: \"fernando-hamasaki-de-amorim\"\n- name: \"Fernando Martínez\"\n  github: \"oinak\"\n  slug: \"fernando-martinez\"\n- name: \"Fernando Mendes\"\n  twitter: \"0xfrm\"\n  github: \"frm\"\n  website: \"https://mendes.codes\"\n  slug: \"fernando-mendes\"\n- name: \"Fernando Perales\"\n  twitter: \"ferperalesm\"\n  github: \"ferperales\"\n  website: \"https://ferperales.net\"\n  slug: \"fernando-petrales\"\n- name: \"Filipe Abreu\"\n  twitter: \"filabreu\"\n  github: \"filabreu\"\n  website: \"http://labs.welaborate.com\"\n  slug: \"filipe-abreu\"\n- name: \"Filipe Costa\"\n  github: \"filipe-costa\"\n  website: \"https://www.filipec.dev\"\n  slug: \"filipe-costa\"\n- name: \"Filipe Mendez\"\n  github: \"\"\n  slug: \"filipe-mendez\"\n- name: \"Filippo Gangi Dino\"\n  github: \"mukkoo\"\n  slug: \"filippo-gangi-dino\"\n- name: \"Fin George\"\n  github: \"Finbob12\"\n  slug: \"fin-george\"\n  aliases:\n    - name: \"The_Sneaker_Dev\"\n      slug: \"the-sneaker-dev\"\n- name: \"Fiona Voss\"\n  github: \"fjvoss\"\n  linkedin: \"fionavoss\"\n  slug: \"fiona-voss\"\n- name: \"Fiona McCawley\"\n  github: \"\"\n  slug: \"fiona-mccawley\"\n- name: \"Fiona Tay\"\n  github: \"\"\n  slug: \"fiona-tay\"\n- name: \"Fito von Zastrow\"\n  github: \"fito\"\n  slug: \"fito-von-zastrow\"\n- name: \"Fletcher Nicol\"\n  github: \"\"\n  slug: \"fletcher-nicol\"\n- name: \"Flip Sasser\"\n  github: \"flipsasser\"\n  website: \"https://flipsasser.com\"\n  slug: \"flip-sasser\"\n- name: \"Floor Drees\"\n  twitter: \"DevOpsBarbie\"\n  github: \"floord\"\n  website: \"https://floor.dev\"\n  slug: \"floor-drees\"\n- name: \"Florian Gilcher\"\n  github: \"skade\"\n  website: \"https://ferrous-systems.com\"\n  slug: \"florian-gilcher\"\n- name: \"Florian Munz\"\n  github: \"theflow\"\n  website: \"https://twitter.com/theflow\"\n  slug: \"florian-munz\"\n- name: \"Florian Plank\"\n  github: \"\"\n  slug: \"florian-plank\"\n- name: \"Florian Weingarten\"\n  twitter: \"fw1729\"\n  github: \"fw42\"\n  slug: \"florian-weingarten\"\n- name: \"Forrest Chang\"\n  github: \"fkchang\"\n  website: \"https://funkworks.blogspot.com\"\n  slug: \"forrest-chang\"\n- name: \"Francesco Papini\"\n  github: \"\"\n  slug: \"francesco-papini\"\n- name: \"Francesco Vollero\"\n  github: \"\"\n  slug: \"francesco-vollero\"\n- name: \"Francis Fish\"\n  github: \"\"\n  slug: \"francis-fish\"\n- name: \"Francis Hwang\"\n  twitter: \"fhwang\"\n  github: \"fhwang\"\n  slug: \"francis-hwang\"\n- name: \"Francis Sullivan\"\n  github: \"\"\n  slug: \"francis-sullivan\"\n- name: \"Franck Verrot\"\n  github: \"franckverrot\"\n  website: \"http://franck.verrot.fr\"\n  slug: \"franck-verrot\"\n- name: \"Franco Olivera\"\n  github: \"frankete333\"\n  slug: \"franco-olivera\"\n- name: \"Francois Lapierre Messier\"\n  github: \"francoislapierremessier\"\n  slug: \"francois-lapierre-messier\"\n- name: \"François Pradel\"\n  github: \"sirdharma\"\n  slug: \"françois-pradel\"\n  aliases:\n    - name: \"Francois Pradel\"\n      slug: \"francois-pradel\"\n- name: \"Frank Kair\"\n  github: \"\"\n  slug: \"frank-kair\"\n- name: \"Frank Rietta\"\n  twitter: \"frankrietta\"\n  github: \"rietta\"\n  website: \"https://rietta.com\"\n  slug: \"frank-rietta\"\n- name: \"Frank Webber\"\n  github: \"\"\n  slug: \"frank-webber\"\n- name: \"Franz Fischbach\"\n  github: \"franz-fischbach\"\n  slug: \"franz-fischbach\"\n- name: \"François Belle\"\n  github: \"bellef\"\n  slug: \"francois-belle\"\n- name: \"François Ferrandis\"\n  github: \"francois-ferrandis\"\n  website: \"https://dailyverrou.fr/\"\n  slug: \"francois-ferrandis\"\n- name: \"Fred George\"\n  github: \"\"\n  slug: \"fred-george\"\n- name: \"Fred Jean\"\n  github: \"j-fred\"\n  slug: \"fred-jean\"\n- name: \"Frederic Jean\"\n  github: \"fredjean\"\n  website: \"http://fredjean.net\"\n  slug: \"frederic-jean\"\n- name: \"Frederic Wong\"\n  github: \"frederic-wong\"\n  website: \"https://fredwong.co.uk\"\n  slug: \"frederic-wong\"\n- name: \"Frederick Cheung\"\n  github: \"fcheung\"\n  website: \"http://www.spacevatican.org\"\n  slug: \"frederick-cheung\"\n  aliases:\n    - name: \"Fred Cheung\"\n      slug: \"fred-cheung\"\n- name: \"Frederico Linhares\"\n  twitter: \"fredolinhares\"\n  github: \"fredlinhares\"\n  website: \"http://linhares.blue\"\n  slug: \"frederico-linhares\"\n- name: \"Freedom Dumlao\"\n  twitter: \"APIguy\"\n  github: \"apiguy\"\n  website: \"http://apiguy.github.io\"\n  slug: \"freedom-dumlao\"\n- name: \"Fritz Meissner\"\n  github: \"iftheshoefritz\"\n  slug: \"fritz-meissner\"\n- name: \"Fu-ga\"\n  github: \"\"\n  slug: \"fu-ga\"\n- name: \"Fujimoto Seiji\"\n  github: \"fujimotos\"\n  website: \"https://ceptord.net/contact#about-author\"\n  slug: \"fujimoto-seiji\"\n- name: \"fukajun\"\n  github: \"\"\n  slug: \"fukajun\"\n- name: \"Fukumori\"\n  github: \"\"\n  slug: \"fukumori\"\n- name: \"Fumiaki MATSUSHIMA\"\n  twitter: \"mtsmfm\"\n  github: \"mtsmfm\"\n  website: \"https://mtsmfm.github.io\"\n  slug: \"fumiaki-matsushima\"\n- name: \"Gabe Enslein\"\n  github: \"\"\n  slug: \"gabe-enslein\"\n- name: \"Gabe Hollombe\"\n  github: \"\"\n  slug: \"gabe-hollombe\"\n- name: \"Gabe Scholz\"\n  github: \"\"\n  slug: \"gabe-scholz\"\n- name: \"Gabi Stefanini\"\n  twitter: \"lastgabs\"\n  github: \"lastgabs\"\n  website: \"http://www.lastgabs.com\"\n  slug: \"gabi-stefanini\"\n- name: \"Gabriel Fortuna\"\n  github: \"gee-forr\"\n  slug: \"gabriel-fortuna\"\n- name: \"Gabriel Halley\"\n  github: \"\"\n  slug: \"gabriel-halley\"\n- name: \"Gabriel Mazetto\"\n  github: \"\"\n  slug: \"gabriel-mazetto\"\n- name: \"Gabriel Terrien\"\n  github: \"rdeckard\"\n  slug: \"gabriel-terrien\"\n- name: \"Gabriela Luhova\"\n  twitter: \"gabriela_luhova\"\n  github: \"luhova\"\n  website: \"https://bio.site/gabrielaluhova\"\n  slug: \"gabriela-luhova\"\n- name: \"Gabrielle Ong Hui Min\"\n  github: \"\"\n  slug: \"gabrielle-ong-hui-min\"\n- name: \"Gael Jerop\"\n  github: \"\"\n  slug: \"gael-jerop\"\n- name: \"Galia Kraicheva\"\n  github: \"galiakraicheva\"\n  slug: \"galia-kraicheva\"\n- name: \"Ganesh Kunwar\"\n  github: \"\"\n  slug: \"ganesh-kunwar\"\n- name: \"Gannon McGibbon\"\n  github: \"gmcgibbon\"\n  website: \"http://gannon.io/\"\n  slug: \"gannon-mcgibbon\"\n- name: \"Garen Torikian\"\n  twitter: \"gjtorikian\"\n  github: \"gjtorikian\"\n  website: \"https://www.gjtorikian.com/\"\n  slug: \"garen-torikian\"\n- name: \"Gareth Marlow\"\n  github: \"\"\n  slug: \"gareth-marlow\"\n- name: \"Gareth Townsend\"\n  github: \"\"\n  slug: \"gareth-townsend\"\n- name: \"Garrett Dimon\"\n  twitter: \"garrettdimon\"\n  github: \"garrettdimon\"\n  website: \"https://garrettdimon.com\"\n  slug: \"garrett-dimon\"\n- name: \"Gary Bernhardt\"\n  github: \"\"\n  slug: \"gary-bernhardt\"\n- name: \"Gary Tou\"\n  twitter: \"garyhtou\"\n  github: \"garyhtou\"\n  website: \"https://garytou.com\"\n  slug: \"gary-tou\"\n- name: \"Gary Vaynerchuk\"\n  github: \"\"\n  slug: \"gary-vaynerchuk\"\n- name: \"Gary Ware\"\n  github: \"gware\"\n  website: \"http://www.bpcc.edu\"\n  slug: \"gary-ware\"\n- name: \"Gastón Ginestet\"\n  github: \"\"\n  slug: \"gaston-ginestet\"\n- name: \"Gaurav Kumar Singh\"\n  twitter: \"gauravks99\"\n  github: \"gauravks99\"\n  website: \"https://linktr.ee/gauravmp07\"\n  slug: \"gaurav-kumar-singh\"\n- name: \"Gaurav Singh\"\n  github: \"\"\n  slug: \"gaurav-singh\"\n- name: \"Gautam Rege\"\n  github: \"\"\n  slug: \"gautam-rege\"\n- name: \"Gauthier Monserand\"\n  github: \"simkim\"\n  slug: \"gauthier-monserand\"\n- name: \"Gavin McGimpsey\"\n  github: \"gavinmcgimpsey\"\n  slug: \"gavin-mcgimpsey\"\n- name: \"Gavin Morrice\"\n  twitter: \"morriceGavin\"\n  github: \"bodacious\"\n  website: \"https://handyrailstips.com\"\n  slug: \"gavin-morrice\"\n- name: \"Genadi Samokovarov\"\n  github: \"gsamokovarov\"\n  website: \"http://gsamokovarov.com\"\n  slug: \"genadi-samokovarov\"\n- name: \"Genar Trias Ortis\"\n  github: \"\"\n  slug: \"genar-trias-ortis\"\n- name: \"Gene Kim\"\n  github: \"\"\n  slug: \"gene-kim\"\n- name: \"Geoffrey Dagley\"\n  github: \"\"\n  slug: \"geoffrey-dagley\"\n- name: \"Geoffrey Donaldson\"\n  github: \"\"\n  slug: \"geoffrey-donaldson\"\n- name: \"Geoffrey Giesemann\"\n  github: \"\"\n  slug: \"geoffrey-giesemann\"\n- name: \"Geoffrey Grosenbach\"\n  github: \"\"\n  slug: \"geoffrey-grosenbach\"\n- name: \"Geoffrey Lessel\"\n  github: \"geolessel\"\n  website: \"https://geoffreylessel.com\"\n  slug: \"geoffrey-lessel\"\n- name: \"Geoffrey Litt\"\n  github: \"geoffreylitt\"\n  website: \"http://geoffreylitt.com\"\n  slug: \"geoffrey-litt\"\n- name: \"Geoffroy Dubruel\"\n  github: \"\"\n  slug: \"geoffroy-dubruel\"\n- name: \"Georg Leciejewski\"\n  github: \"schorsch\"\n  website: \"https://salesking.eu\"\n  slug: \"georg-leciejewski\"\n- name: \"George Apitz\"\n  github: \"\"\n  slug: \"george-apitz\"\n- name: \"George Brocklehurst\"\n  twitter: \"georgebrock\"\n  github: \"georgebrock\"\n  website: \"https://www.georgebrock.com\"\n  slug: \"george-brocklehurst\"\n- name: \"George Ma\"\n  github: \"george-ma\"\n  slug: \"george-ma\"\n- name: \"George Maharjan\"\n  github: \"\"\n  slug: \"george-maharjan\"\n- name: \"George Mauer\"\n  github: \"togakangaroo\"\n  website: \"https://georgemauer.net\"\n  slug: \"george-mauer\"\n- name: \"George Ogata\"\n  github: \"\"\n  slug: \"george-ogata\"\n- name: \"George Palmer\"\n  github: \"\"\n  slug: \"george-palmer\"\n- name: \"Georgina Robilliard\"\n  github: \"\"\n  slug: \"georgina-robilliard\"\n- name: \"Georgy Buranov\"\n  github: \"gburanov\"\n  website: \"http://gburanov.me\"\n  slug: \"georgy-buranov\"\n- name: \"Germán Escobar\"\n  github: \"\"\n  slug: \"german-escobar\"\n- name: \"Gerred Dillon\"\n  twitter: \"devgerred\"\n  github: \"gerred\"\n  slug: \"gerred-dillon\"\n- name: \"Getty Ritter\"\n  github: \"\"\n  slug: \"getty-ritter\"\n- name: \"Gharbi Mohammed\"\n  github: \"mgharbik\"\n  slug: \"gharbi-mohammed\"\n- name: \"Gheorghiță Hurmuz\"\n  github: \"\"\n  slug: \"gheorghi-a-hurmuz\"\n- name: \"Giacomo Bagnoli\"\n  github: \"gbagnoli\"\n  slug: \"giacomo-bagnoli\"\n- name: \"Gian Carlo Pace\"\n  github: \"\"\n  slug: \"gian-carlo-pace\"\n- name: \"Gianfranco Zas\"\n  github: \"snmgian\"\n  slug: \"gianfranco-zas\"\n- name: \"Giles Bowkett\"\n  github: \"\"\n  slug: \"giles-bowkett\"\n- name: \"ginkouno\"\n  github: \"\"\n  slug: \"ginkouno\"\n- name: \"Ginny Hendry\"\n  github: \"\"\n  slug: \"ginny-hendry\"\n- name: \"Giorgio Fochesato\"\n  github: \"\"\n  slug: \"giorgio-fochesato\"\n- name: \"Giovann Filippi\"\n  github: \"\"\n  slug: \"giovann-filippi\"\n- name: \"Giovanni Intini\"\n  github: \"\"\n  slug: \"giovanni-intini\"\n- name: \"Giovanni Panasiti\"\n  twitter: \"giovapanasiti\"\n  github: \"giovapanasiti\"\n  slug: \"giovanni-panasiti\"\n- name: \"Giovanni Sakti\"\n  twitter: \"giosakti\"\n  github: \"giosakti\"\n  website: \"https://bio.link/giosakti\"\n  slug: \"giovanni-sakti\"\n- name: \"Giulia Mialich\"\n  github: \"gmialich\"\n  slug: \"giulia-mialich\"\n- name: \"Giuseppe Modarelli\"\n  twitter: \"gmodarelli\"\n  github: \"gmodarelli\"\n  website: \"http://gmodarelli.com\"\n  slug: \"giuseppe-modarelli\"\n- name: \"Gleb Glazov\"\n  github: \"glebglazov\"\n  slug: \"gleb-glazov\"\n- name: \"Gleb Mazovetskiy\"\n  twitter: \"glebm\"\n  github: \"glebm\"\n  slug: \"gleb-mazovetskiy\"\n- name: \"Glenn Espinosa\"\n  github: \"gxespino\"\n  slug: \"glenn-espinosa\"\n- name: \"Glenn Gillen\"\n  github: \"\"\n  slug: \"glenn-gillen\"\n- name: \"Glenn Harmon\"\n  github: \"gharmonjr\"\n  slug: \"glenn-harmon\"\n- name: \"Glenn Vanderburg\"\n  twitter: \"glv\"\n  github: \"glv\"\n  website: \"http://vanderburg.org/\"\n  slug: \"glenn-vanderburg\"\n- name: \"Glynnis Ritchie\"\n  github: \"glynnis\"\n  slug: \"glynnis-ritchie\"\n- name: \"Go Sueyoshi\"\n  twitter: \"sue445\"\n  github: \"sue445\"\n  website: \"https://sue445.hatenablog.com/\"\n  slug: \"go-sueyoshi\"\n- name: \"Godfrey\"\n  github: \"\"\n  website: \"http://about.me/godfreychan\"\n  slug: \"godfrey\"\n- name: \"Godfrey Chan\"\n  github: \"chancancode\"\n  website: \"http://about.me/godfreychan\"\n  slug: \"godfrey-chan\"\n- name: \"gogutan\"\n  github: \"\"\n  slug: \"gogutan\"\n- name: \"Gonzalo Maldonado\"\n  github: \"\"\n  slug: \"gonzalo-maldonado\"\n- name: \"Gooi Liang Zheng\"\n  github: \"\"\n  slug: \"gooi-liang-zheng\"\n- name: \"Goose Mongeau\"\n  github: \"\"\n  slug: \"goose-mongeau\"\n- name: \"Gordon Diggs\"\n  github: \"gdiggs\"\n  website: \"http://www.gordondiggs.com\"\n  slug: \"gordon-diggs\"\n- name: \"Gosia Ksionek\"\n  github: \"\"\n  slug: \"gosia-ksionek\"\n- name: \"Goulven Champenois\"\n  github: \"goulvench\"\n  website: \"https://pro.userland.fr/\"\n  slug: \"goulven-champenois\"\n- name: \"Grace Chang\"\n  twitter: \"grehce\"\n  github: \"grehce\"\n  website: \"https://www.kintsugihello.com\"\n  slug: \"grace-chang\"\n- name: \"Graham Conzett\"\n  github: \"conzett\"\n  website: \"https://grahamconzett.com\"\n  slug: \"graham-conzett\"\n- name: \"Graham Lee\"\n  github: \"\"\n  slug: \"graham-lee\"\n- name: \"Grant Blakeman\"\n  github: \"gblakeman\"\n  website: \"https://grantblakeman.com\"\n  slug: \"grant-blakeman\"\n- name: \"Grant Drzyzga\"\n  github: \"\"\n  slug: \"grant-drzyzga\"\n- name: \"Grant Schofield\"\n  github: \"\"\n  slug: \"grant-schofield\"\n- name: \"Grayson Wright\"\n  github: \"\"\n  slug: \"grayson-wright\"\n- name: \"Greg Baugues\"\n  github: \"gregbaugues\"\n  website: \"http://baugues.com\"\n  slug: \"greg-baugues\"\n- name: \"Greg Belt\"\n  github: \"\"\n  slug: \"greg-belt\"\n- name: \"Greg Borenstein\"\n  github: \"\"\n  slug: \"greg-borenstein\"\n- name: \"Greg Brockman\"\n  github: \"\"\n  slug: \"greg-brockman\"\n- name: \"Greg Kaczorek\"\n  github: \"\"\n  slug: \"greg-kaczorek\"\n- name: \"Greg Karékinian\"\n  github: \"\"\n  slug: \"greg-karekinian\"\n- name: \"Greg Knox\"\n  github: \"\"\n  slug: \"greg-knox\"\n- name: \"Greg Molnar\"\n  twitter: \"gregmolnar\"\n  github: \"gregmolnar\"\n  website: \"https://greg.molnar.io\"\n  slug: \"greg-molnar\"\n- name: \"Gregg Pollack\"\n  github: \"gregg\"\n  website: \"https://www.greggpollack.com\"\n  slug: \"gregg-pollack\"\n- name: \"Greggory Rothmeier\"\n  github: \"greggroth\"\n  slug: \"greggory-rothmeier\"\n- name: \"Gregor Wassmann\"\n  github: \"gregorw\"\n  website: \"https://ko-fi.com/gregorw\"\n  slug: \"gregor-wassmann\"\n- name: \"Gregorio Setti\"\n  github: \"desmondhume\"\n  slug: \"gregorio-setti\"\n- name: \"Gregory Brown\"\n  github: \"practicingruby\"\n  website: \"http://twitter.com/practicingdev\"\n  slug: \"gregory-brown\"\n- name: \"Gregory Moeck\"\n  github: \"\"\n  slug: \"gregory-moeck\"\n- name: \"Greta Parks\"\n  github: \"gretap\"\n  slug: \"greta-parks\"\n- name: \"Gretchen Ziegler\"\n  github: \"gretchenziegler\"\n  slug: \"gretchen-ziegler\"\n- name: \"Grzegorz Jakubiak\"\n  github: \"\"\n  slug: \"grzegorz-jakubiak\"\n- name: \"Grzegorz Piwowarek\"\n  twitter: \"pivovarit\"\n  github: \"pivovarit\"\n  website: \"https://4comprehension.com\"\n  slug: \"grzegorz-piwowarek\"\n- name: \"Grzegorz Witek\"\n  github: \"\"\n  slug: \"grzegorz-witek\"\n- name: \"Grzegorz Łuszczek\"\n  github: \"grzlus\"\n  slug: \"grzegorz-luszczek\"\n- name: \"Gui Heurich\"\n  github: \"\"\n  slug: \"gui-heurich\"\n- name: \"Gui Vieira\"\n  github: \"guialbuk\"\n  slug: \"gui-vieira\"\n- name: \"Guilherme Carreiro\"\n  github: \"karreiro\"\n  website: \"https://karreiro.com\"\n  slug: \"guilherme-carreiro\"\n- name: \"Guilherme Orlandini Heurich\"\n  github: \"\"\n  slug: \"guilherme-orlandini-heurich\"\n- name: \"Guillaume Briday\"\n  twitter: \"guillaumebriday\"\n  github: \"guillaumebriday\"\n  website: \"https://guillaumebriday.fr\"\n  slug: \"guillaume-briday\"\n- name: \"Guillaume Terral\"\n  github: \"\"\n  slug: \"guillaume-terral\"\n- name: \"Guillaume Wrobel\"\n  github: \"\"\n  slug: \"guillaume-wrobel\"\n- name: \"Guillermo Aguirre\"\n  twitter: \"guillermoap_\"\n  github: \"guillermoap\"\n  website: \"https://guillermoaguirre.dev\"\n  slug: \"guillermo-aguirre\"\n- name: \"Guillermo Iguaran\"\n  twitter: \"guilleiguaran\"\n  github: \"guilleiguaran\"\n  website: \"https://‮\"\n  slug: \"guillermo-iguaran\"\n- name: \"Guillermo Moreno\"\n  github: \"\"\n  slug: \"guillermo-moreno\"\n- name: \"Guo Xiang Tan\"\n  github: \"\"\n  slug: \"guo-xiang-tan\"\n- name: \"Gus Shaw Stewart\"\n  github: \"\"\n  slug: \"gus-shaw-stewart\"\n- name: \"Gustavo Araújo\"\n  twitter: \"garaujodev\"\n  github: \"garaujodev\"\n  website: \"https://gustavoaraujo.dev\"\n  slug: \"gustavo-araujo\"\n  aliases:\n    - name: \"Gustavo Araujo\"\n      slug: \"gustavo-araujo\"\n- name: \"Gustavo Robles\"\n  github: \"gus4no\"\n  slug: \"gustavo-robles\"\n- name: \"Gusto Engineering Team\"\n  github: \"\"\n  slug: \"gusto-engineering-team\"\n- name: \"Guyren G. Howe\"\n  github: \"\"\n  slug: \"guyren-g-howe\"\n- name: \"Guyren Howe\"\n  twitter: \"unclouded\"\n  github: \"gisborne\"\n  website: \"http://relevantlogic.com\"\n  slug: \"guyren-howe\"\n- name: \"Gyani\"\n  github: \"gyaninascimento\"\n  slug: \"gyani\"\n- name: \"Gys Muller\"\n  github: \"\"\n  slug: \"gys-muller\"\n- name: \"H Masuyama\"\n  github: \"\"\n  slug: \"h-masuyama\"\n- name: \"H. Waterhouse\"\n  github: \"\"\n  slug: \"h-waterhouse\"\n- name: \"hachi\"\n  github: \"\"\n  slug: \"hachi\"\n- name: \"hadashiA\"\n  github: \"hadashiA\"\n  slug: \"hadashiA\"\n- name: \"Hadi Al Qawas\"\n  github: \"\"\n  slug: \"hadi-al-qawas\"\n- name: \"Haikel Guémar\"\n  github: \"\"\n  slug: \"haikel-guemar\"\n- name: \"Hailey Somerville\"\n  github: \"\"\n  slug: \"hailey-somerville\"\n- name: \"Hal Fulton\"\n  github: \"hal9000\"\n  slug: \"hal-fulton\"\n- name: \"Haley Anderson\"\n  github: \"\"\n  slug: \"haley-anderson\"\n- name: \"Halil Bagdadi\"\n  github: \"halilsacpapa\"\n  slug: \"halil-bagdadi\"\n- name: \"Hampton Catlin\"\n  github: \"hamptonmakes\"\n  website: \"https://www.hamptonmakes.com\"\n  slug: \"hampton-catlin\"\n- name: \"Hana Harenčárová\"\n  github: \"hharen\"\n  website: \"https://hharen.com\"\n  slug: \"hana-harencarova\"\n  aliases:\n    - name: \"Hana Harencarova\"\n      slug: \"hana-harencarova\"\n- name: \"Hannah Dwan\"\n  github: \"\"\n  slug: \"hannah-dwan\"\n- name: \"Hannah Howard\"\n  github: \"hannahhoward\"\n  website: \"https://lrdesign.com\"\n  slug: \"hannah-howard\"\n- name: \"Hanneli Tavante\"\n  github: \"\"\n  slug: \"hanneli-tavante\"\n- name: \"Hans Schnedlitz\"\n  twitter: \"hschnedlitz\"\n  github: \"hschne\"\n  website: \"https://hansschnedlitz.com\"\n  slug: \"hans-schnedlitz\"\n- name: \"Hao Wang\"\n  github: \"\"\n  slug: \"hao-wang\"\n- name: \"Hari Krishnan\"\n  github: \"\"\n  slug: \"hari-krishnan\"\n- name: \"Haris Amin\"\n  github: \"hamin\"\n  website: \"http://harisamin.com\"\n  slug: \"haris-amin\"\n- name: \"Harisankar P S\"\n  github: \"coderhs\"\n  website: \"https://hsps.in\"\n  slug: \"harisankar-p-s\"\n- name: \"Harley Davidson Karel\"\n  github: \"\"\n  website: \"https://www.linkedin.com/in/harleydavidsonkarel\"\n  slug: \"harley-davidson-karel\"\n- name: \"Harlow Ward\"\n  github: \"\"\n  slug: \"harlow-ward\"\n- name: \"Harman Sohanpal\"\n  github: \"\"\n  slug: \"harman-sohanpal\"\n- name: \"Harriet Oughton\"\n  twitter: \"chordsandcode\"\n  github: \"oughtputs\"\n  slug: \"harriet-oughton\"\n- name: \"Harrison Touw\"\n  github: \"\"\n  slug: \"harrison-touw\"\n- name: \"Harry Lascelles\"\n  github: \"\"\n  slug: \"harry-lascelles\"\n- name: \"Hartley McGuire\"\n  github: \"skipkayhil\"\n  slug: \"hartley-mcguire\"\n- name: \"Haruka Oguchi\"\n  github: \"\"\n  slug: \"haruka-oguchi\"\n- name: \"Haruna Tsujita\"\n  twitter: \"haruna_tsujita\"\n  github: \"haruna-tsujita\"\n  slug: \"haruna-tsujita\"\n- name: \"Haseeb Qureshi\"\n  github: \"haseeb-qureshi\"\n  website: \"http://haseebq.com\"\n  slug: \"haseeb-qureshi\"\n- name: \"Hashino Mikiko\"\n  github: \"\"\n  slug: \"hashino-mikiko\"\n- name: \"HASUMI Hitoshi\"\n  twitter: \"hasumikin\"\n  github: \"hasumikin\"\n  website: \"https://hasumikin.com/about\"\n  slug: \"hasumi-hitoshi\"\n  aliases:\n    - name: \"Hitoshi Hasumi\"\n      slug: \"hitoshi-hasumi\"\n    - name: \"Hitoshi HASUMI\"\n      slug: \"hitoshi-hasumi\"\n- name: \"hatsu38\"\n  twitter: \"hatsu_38\"\n  github: \"hatsu38\"\n  slug: \"hatsu38\"\n- name: \"Hayao Kimura\"\n  github: \"hayaokimura\"\n  slug: \"hayao-kimura\"\n- name: \"Hayato Kawai\"\n  github: \"hayato-kz\"\n  slug: \"hayato-kawai\"\n- name: \"Hayato OKUMOTO\"\n  github: \"falcon8823\"\n  slug: \"hayato-okumoto\"\n- name: \"Heather Corallo\"\n  github: \"\"\n  slug: \"heather-corallo\"\n- name: \"Heather Herrington\"\n  github: \"heatherherrington\"\n  website: \"http://heatherherrington.github.io/\"\n  slug: \"heather-herrington\"\n- name: \"Heather Roulston\"\n  github: \"\"\n  slug: \"heather-roulston\"\n- name: \"Hector Bustillos\"\n  github: \"hecbuma\"\n  website: \"http://hecbuma.herokuapp.com\"\n  slug: \"hector-bustillos\"\n- name: \"Hector Castro\"\n  github: \"\"\n  slug: \"hector-castro\"\n- name: \"Hector Miguel Rodriguez Muñiz\"\n  github: \"\"\n  slug: \"hector-miguel-rodriguez-muniz\"\n- name: \"Heidi Helfand\"\n  github: \"heidihelfand\"\n  website: \"http://www.heidihelfand.com\"\n  slug: \"heidi-helfand\"\n- name: \"Heidi Waterhouse\"\n  github: \"\"\n  slug: \"heidi-waterhouse\"\n- name: \"Helen Stonehouse\"\n  github: \"\"\n  slug: \"helen-stonehouse\"\n- name: \"Helio Cola\"\n  github: \"heliocola\"\n  website: \"https://hac-rods.me/\"\n  slug: \"helio-cola\"\n- name: \"Helmer Davila\"\n  twitter: \"helmerdavila\"\n  github: \"helmerdavila\"\n  website: \"https://www.helmerdavila.com\"\n  slug: \"helmer-davila\"\n- name: \"Hemal Varambhia\"\n  github: \"\"\n  slug: \"hemal-varambhia\"\n- name: \"Hemant Kumar\"\n  github: \"gnufied\"\n  website: \"http://gnufied.org\"\n  slug: \"hemant-kumar\"\n- name: \"Hemanth Haridas\"\n  github: \"hhemanth\"\n  slug: \"hemanth-haridas\"\n- name: \"Henning Koch\"\n  twitter: \"triskweline\"\n  github: \"triskweline\"\n  website: \"https://makandra.de/en\"\n  slug: \"henning-koch\"\n- name: \"Henrique Cardoso de Faria\"\n  github: \"henriquecf\"\n  slug: \"henrique-cardoso-de-faria\"\n- name: \"Henry Tseng\"\n  github: \"henrytseng\"\n  website: \"http://www.henrytseng.com\"\n  slug: \"henry-tseng\"\n- name: \"Herve Aniglo\"\n  twitter: \"tigerstechexp\"\n  github: \"hanuman1\"\n  slug: \"herve-aniglo\"\n- name: \"Hideaki Ishii\"\n  github: \"\"\n  slug: \"hideaki-ishii\"\n- name: \"Hideki Miura\"\n  github: \"miura1729\"\n  website: \"http://d.hatena.ne.jp/miura1729\"\n  slug: \"hideki-miura\"\n- name: \"Hieu Nguyen\"\n  github: \"\"\n  slug: \"hieu-nguyen\"\n- name: \"Hilary Stohs-Krause\"\n  twitter: \"hilarysk\"\n  github: \"hilarysk\"\n  slug: \"hilary-stohs-krause\"\n- name: \"Hiro Asari\"\n  github: \"\"\n  slug: \"hiro-asari\"\n- name: \"Hiro Tateyama\"\n  github: \"\"\n  slug: \"hiro-tateyama\"\n- name: \"Hiroaki Iwase\"\n  github: \"\"\n  slug: \"hiroaki-iwase\"\n- name: \"Hirokazu SUZUKI\"\n  twitter: \"heronshoes\"\n  github: \"heronshoes\"\n  slug: \"hirokazu-suzuki\"\n- name: \"Hiromasa Ishii\"\n  github: \"\"\n  slug: \"hiromasa-ishii\"\n- name: \"Hiromi Ogawa\"\n  github: \"\"\n  slug: \"hiromi-ogawa\"\n- name: \"Hiroshi Kawada\"\n  github: \"h-kawada\"\n  slug: \"hiroshi-kawada\"\n- name: \"Hiroshi Nakamura\"\n  twitter: \"nahi\"\n  github: \"nahi\"\n  slug: \"hiroshi-nakamura\"\n- name: \"Hiroshi SHIBATA\"\n  twitter: \"hsbt\"\n  github: \"hsbt\"\n  website: \"https://www.hsbt.org/\"\n  slug: \"hiroshi-shibata\"\n  aliases:\n    - name: \"Hiroshi Shibata\"\n      slug: \"hiroshi-shibata\"\n    - name: \"Shibata Hiroshi\"\n      slug: \"shibata-hiroshi\"\n    - name: \"hsbt\"\n      slug: \"hsbt\"\n- name: \"Hiroshi Shimoju\"\n  github: \"\"\n  slug: \"hiroshi-shimoju\"\n- name: \"Hirotaka Miyagi\"\n  github: \"\"\n  slug: \"hirotaka-miyagi\"\n- name: \"Hiroya Fujinami\"\n  twitter: \"make_now_just\"\n  github: \"makenowjust\"\n  website: \"https://quine.codes\"\n  slug: \"hiroya-fujinami\"\n- name: \"Hiroya Sakamoto\"\n  github: \"\"\n  slug: \"hiroya-sakamoto\"\n- name: \"Hiroya Shimamoto\"\n  github: \"\"\n  slug: \"hiroya-shimamoto\"\n- name: \"Hiroyuki Inoue\"\n  github: \"inoh\"\n  slug: \"hiroyuki-inoue\"\n- name: \"Hiroyuki Sano\"\n  github: \"sh19910711\"\n  slug: \"hiroyuki-sano\"\n- name: \"Hiten Parmar\"\n  github: \"hrp\"\n  slug: \"hiten-parmar\"\n- name: \"Hiếu Nguyễn\"\n  github: \"hieuk09\"\n  website: \"https://hieuk09.github.io\"\n  slug: \"hi-u-nguy-n\"\n- name: \"Ho Tse-Ching\"\n  github: \"\"\n  slug: \"ho-tse-ching\"\n  aliases:\n    - name: \"Tse-Ching Ho\"\n      slug: \"tse-ching-ho\"\n    - name: \"TseChing Ho\"\n      slug: \"tseching-ho\"\n- name: \"Hoa Newton\"\n  github: \"\"\n  slug: \"hoa-newton\"\n- name: \"Hongli Lai\"\n  github: \"foobarwidget\"\n  website: \"https://www.joyfulbikeshedding.com/\"\n  slug: \"hongli-lai\"\n- name: \"Howard Yeh\"\n  github: \"\"\n  slug: \"howard-yeh\"\n- name: \"Hristo Vladev\"\n  twitter: \"hvladev\"\n  github: \"hvladev\"\n  website: \"https://hvladev.com\"\n  slug: \"hristo-vladev\"\n- name: \"Hsing-Hui Hsu\"\n  github: \"\"\n  slug: \"hsing-hui-hsu\"\n- name: \"Hubert Łępicki\"\n  github: \"hubertlepicki\"\n  website: \"https://www.amberbit.com\"\n  slug: \"hubert-lepicki\"\n- name: \"Hugo Vast\"\n  github: \"just-the-v\"\n  slug: \"hugo-vast\"\n- name: \"Hung Harry Doan\"\n  github: \"\"\n  slug: \"hung-harry-doan\"\n- name: \"Huy Du\"\n  github: \"dugiahuy\"\n  website: \"https://dugiahuy.com\"\n  slug: \"huy-du\"\n- name: \"Hywel Carver\"\n  github: \"\"\n  slug: \"hywel-carver\"\n- name: \"i110\"\n  github: \"\"\n  slug: \"i110\"\n- name: \"Ian Duggan\"\n  github: \"ijcd\"\n  website: \"https://medium.com/@ijcd\"\n  slug: \"ian-duggan\"\n- name: \"Ian Hunter\"\n  github: \"\"\n  slug: \"ian-hunter\"\n- name: \"Ian Lourenço\"\n  github: \"ian-lourenco\"\n  slug: \"ian-lourenco\"\n- name: \"Ian McFarland\"\n  github: \"\"\n  slug: \"ian-mcfarland\"\n- name: \"Ian Norris\"\n  twitter: \"icStatic\"\n  github: \"iannorris\"\n  website: \"https://www.inorris.com\"\n  slug: \"ian-norris\"\n- name: \"Ian Warshak\"\n  github: \"\"\n  slug: \"ian-warshak\"\n- name: \"Ian Whitney\"\n  github: \"ianwhitney\"\n  slug: \"ian-whitney\"\n- name: \"Ifat Ribon\"\n  github: \"inveterateliterate\"\n  slug: \"ifat-ribon\"\n- name: \"Ignacio Alonso\"\n  github: \"\"\n  slug: \"ignacio-alonso\"\n- name: \"Ignacio Chiazzo Cardarello\"\n  github: \"ignacio-chiazzo\"\n  slug: \"ignacio-chiazzo-cardarello\"\n- name: \"Ignacio Huerta\"\n  github: \"iox\"\n  website: \"http://www.ihuerta.net\"\n  slug: \"ignacio-huerta\"\n- name: \"Ignacio Piantanida\"\n  github: \"\"\n  slug: \"ignacio-piantanida\"\n- name: \"Igor Aleksandrov\"\n  twitter: \"igor_alexandrov\"\n  github: \"igor-alexandrov\"\n  website: \"https://igor.works\"\n  slug: \"igor-alexandrov\"\n  aliases:\n    - name: \"Igor Alexandrov\"\n      slug: \"igor-alexandrov\"\n- name: \"Igor Jancev\"\n  github: \"igorj\"\n  slug: \"igor-jancev\"\n- name: \"Igor Kapkov\"\n  github: \"\"\n  slug: \"igor-kapkov\"\n- name: \"Igor Morozov\"\n  twitter: \"Morozzzko\"\n  github: \"morozzzko\"\n  website: \"https://www.morozov.is/\"\n  slug: \"igor-morozov\"\n- name: \"Igor Omokov\"\n  github: \"\"\n  slug: \"igor-omokov\"\n- name: \"Iheanyi Ekechukwu\"\n  github: \"\"\n  slug: \"iheanyi-ekechukwu\"\n- name: \"Ikuma Tadokoro\"\n  github: \"\"\n  slug: \"ikuma-tadokoro\"\n- name: \"ikuma-t\"\n  github: \"\"\n  slug: \"ikuma-t\"\n- name: \"Ilake Chang\"\n  github: \"\"\n  slug: \"ilake-chang\"\n- name: \"Iliana Hadzhiatanasova\"\n  github: \"ilianah\"\n  slug: \"iliana-hadzhiatanasova\"\n- name: \"Illia Zub\"\n  twitter: \"ilyazub_\"\n  github: \"ilyazub\"\n  slug: \"illia-zub\"\n- name: \"Ilya Grigorick\"\n  github: \"\"\n  slug: \"ilya-grigorick\"\n- name: \"Ilya Grigorik\"\n  twitter: \"igrigorik\"\n  github: \"igrigorik\"\n  website: \"https://ilya.grigorik.com\"\n  slug: \"ilya-grigorik\"\n- name: \"imadoki\"\n  github: \"\"\n  slug: \"imadoki\"\n- name: \"imaharu\"\n  github: \"\"\n  slug: \"imaharu\"\n- name: \"Ingrid Alongi\"\n  github: \"electromute\"\n  website: \"http://www.electromute.com\"\n  slug: \"ingrid-alongi\"\n- name: \"Ippei Obayashi\"\n  github: \"\"\n  slug: \"ippei-obayashi\"\n- name: \"Ippei Ogiwara\"\n  github: \"iogi\"\n  slug: \"ippei-ogiwara\"\n- name: \"Iratxe Garrido\"\n  github: \"iratxegarrido\"\n  website: \"https://iratxe-garrido.me/\"\n  slug: \"iratxe-garrido\"\n- name: \"Irina Lindt\"\n  github: \"alster-wasser\"\n  slug: \"irina-lindt\"\n- name: \"Irina Nazarova\"\n  twitter: \"inazarova\"\n  github: \"irinanazarova\"\n  website: \"https://evilmartians.com\"\n  slug: \"irina-nazarova\"\n- name: \"Irina Paraschiv\"\n  github: \"\"\n  slug: \"irina-paraschiv\"\n- name: \"Iryna Zayats\"\n  github: \"\"\n  slug: \"iryna-zayats\"\n- name: \"Isaac Sloan\"\n  github: \"elorest\"\n  website: \"https://isaacsloan.com\"\n  slug: \"isaac-sloan\"\n- name: \"Isabel Steiner\"\n  github: \"\"\n  slug: \"isabel-steiner\"\n- name: \"Isaiah Peng\"\n  github: \"\"\n  slug: \"isaiah-peng\"\n- name: \"Ishani Trivedi\"\n  github: \"\"\n  slug: \"ishani-trivedi\"\n- name: \"Ismael Celis\"\n  twitter: \"ismasan\"\n  github: \"ismasan\"\n  website: \"https://ismaelcelis.com\"\n  slug: \"ismael-celis\"\n- name: \"Issei Naruta\"\n  github: \"\"\n  slug: \"issei-naruta\"\n- name: \"It's been a minute!\"\n  github: \"\"\n  slug: \"it-s-been-a-minute\"\n- name: \"Italo Aurelio\"\n  github: \"\"\n  slug: \"italo-aurelio\"\n- name: \"ITOYANAGI Sakura\"\n  github: \"aycabta\"\n  slug: \"itoyanagi-sakura\"\n- name: \"Iulia Costea\"\n  github: \"\"\n  slug: \"iulia-costea\"\n- name: \"Ivan Alexandrov\"\n  github: \"\"\n  slug: \"ivan-alexandrov\"\n- name: \"Ivan Nemytchenko\"\n  twitter: \"inemation\"\n  github: \"inem\"\n  website: \"http://inem.at\"\n  slug: \"ivan-nemytchenko\"\n- name: \"Ivan Shamatov\"\n  github: \"\"\n  slug: \"ivan-shamatov\"\n- name: \"Ivan Tse\"\n  github: \"\"\n  slug: \"ivan-tse\"\n- name: \"Ivan Vanderbyl\"\n  github: \"\"\n  slug: \"ivan-vanderbyl\"\n- name: \"Ivan Zarea\"\n  github: \"\"\n  slug: \"ivan-zarea\"\n- name: \"Ivo Anjo\"\n  twitter: \"KnuX\"\n  github: \"ivoanjo\"\n  website: \"https://ivoanjo.me\"\n  slug: \"ivo-anjo\"\n- name: \"Ivy Evans\"\n  github: \"\"\n  slug: \"ivy-evans\"\n- name: \"Izabela Komorek\"\n  github: \"izuroxx\"\n  website: \"https://twitter.com/izuroxx\"\n  slug: \"izabela-komorek\"\n- name: \"izumitomo\"\n  twitter: \"12u3i_tomo\"\n  github: \"izumitomo\"\n  slug: \"izumitomo\"\n- name: \"J Austin Hughey\"\n  github: \"\"\n  slug: \"j-austin-hughey\"\n- name: \"Jacin Yan\"\n  github: \"\"\n  slug: \"jacin-yan\"\n- name: \"Jack Chen\"\n  github: \"\"\n  slug: \"jack-chen\"\n- name: \"Jack Chen Songyong\"\n  github: \"\"\n  slug: \"jack-chen-songyong\"\n- name: \"Jack Christensen\"\n  github: \"jackc\"\n  website: \"https://www.jackchristensen.com/\"\n  slug: \"jack-christensen\"\n- name: \"Jack Danger\"\n  github: \"jackdanger\"\n  website: \"http://jackdanger.com\"\n  slug: \"jack-danger\"\n- name: \"Jack Danger Canty\"\n  github: \"\"\n  slug: \"jack-danger-canty\"\n- name: \"Jack McCracken\"\n  github: \"jackmc\"\n  slug: \"jack-mccracken\"\n- name: \"Jack Permenter\"\n  github: \"interrogativepronoun\"\n  slug: \"jack-permenter\"\n- name: \"Jack Sharkey\"\n  twitter: \"jacksharkey11\"\n  github: \"sharkey11\"\n  website: \"https://whop.com\"\n  slug: \"jack-sharkey\"\n- name: \"Jackie Potts\"\n  github: \"\"\n  slug: \"jackie-potts\"\n- name: \"Jackie Ros\"\n  github: \"\"\n  slug: \"jackie-ros\"\n- name: \"Jacklyn Ma\"\n  github: \"jacklynhma\"\n  slug: \"jacklyn-ma\"\n- name: \"Jackson Pires\"\n  twitter: \"jackson_pires\"\n  github: \"jacksonpires\"\n  website: \"https://jacksonpires.com\"\n  slug: \"jackson-pires\"\n- name: \"Jacob\"\n  github: \"jacob-shops\"\n  slug: \"jacob\"\n- name: \"Jacob Burkhart\"\n  github: \"jacobo\"\n  slug: \"jacob-burkhart\"\n- name: \"Jacob Crofts\"\n  github: \"jacobcrofts\"\n  slug: \"jacob-crofts\"\n- name: \"Jacob Daddario\"\n  github: \"jacobdaddario\"\n  slug: \"jacob-daddario\"\n- name: \"Jacob Evelyn\"\n  github: \"jacobevelyn\"\n  website: \"https://ja.cob.land\"\n  slug: \"jacob-evelyn\"\n- name: \"Jacob Fugal\"\n  github: \"\"\n  slug: \"jacob-fugal\"\n- name: \"Jacob Stoebel\"\n  github: \"\"\n  slug: \"jacob-stoebel\"\n- name: \"Jacob Swanner\"\n  github: \"jswanner\"\n  website: \"https://jacobswanner.com\"\n  slug: \"jacob-swanner\"\n- name: \"Jade Dickinson\"\n  github: \"jadedickinson\"\n  slug: \"jade-dickinson\"\n- name: \"Jade Meskill\"\n  github: \"\"\n  slug: \"jade-meskill\"\n- name: \"Jade Stewart\"\n  github: \"jadekstewart3\"\n  slug: \"jade-stewart\"\n- name: \"Jaehurn Nam\"\n  github: \"\"\n  slug: \"jaehurn-nam\"\n- name: \"Jaime Andrés Dávila\"\n  github: \"\"\n  slug: \"jaime-andres-davila\"\n- name: \"Jaime Lyn Schatz\"\n  github: \"JaimeLynSchatz\"\n  slug: \"jaime-lyn-schatz\"\n- name: \"Jaime Zuberbuhler\"\n  github: \"\"\n  slug: \"jaime-zuberbuhler\"\n- name: \"Jairo Diaz\"\n  github: \"\"\n  slug: \"jairo-diaz\"\n- name: \"Jankees van Woezik\"\n  github: \"jankeesvw\"\n  slug: \"jankees-van-woezik\"\n  aliases:\n    - name: \"Jankees Van Woezik\"\n      slug: \"jankees-van-woezik\"\n- name: \"Jake\"\n  github: \"jakewharton\"\n  website: \"https://jakewharton.com\"\n  slug: \"jake\"\n- name: \"Jake Anderson\"\n  github: \"jedijakeiscool\"\n  website: \"https://jakeandersonwebdevelopment.com\"\n  slug: \"jake-anderson\"\n- name: \"Jake Gribschaw\"\n  github: \"chime-jake\"\n  slug: \"jake-gribschaw\"\n- name: \"Jake Howerton\"\n  github: \"jakehow\"\n  slug: \"jake-howerton\"\n- name: \"Jake Scruggs\"\n  github: \"\"\n  slug: \"jake-scruggs\"\n- name: \"Jake Varghese\"\n  github: \"jake3030\"\n  website: \"https://blog.flvorful.com\"\n  slug: \"jake-varghese\"\n- name: \"Jake Worth\"\n  github: \"jwworth\"\n  website: \"https://jakeworth.com\"\n  slug: \"jake-worth\"\n- name: \"Jake Zimmerman\"\n  github: \"jez\"\n  website: \"https://jez.io\"\n  slug: \"jake-zimmerman\"\n- name: \"Jakob Cosoroabă\"\n  twitter: \"jcsrb\"\n  github: \"jcsrb\"\n  website: \"https://jakob.cosoroaba.ro\"\n  slug: \"jakob-cosoroaba\"\n- name: \"Jakub Godawa\"\n  github: \"vysogot\"\n  website: \"https://rubydev.pl\"\n  slug: \"jakub-godawa\"\n- name: \"Jakub Malina\"\n  github: \"kuba108\"\n  slug: \"jakub-malina\"\n- name: \"Jakub Rodzik\"\n  github: \"rodzik\"\n  slug: \"jakub-rodzik\"\n- name: \"Jamed EdJo\"\n  github: \"\"\n  slug: \"jamed-edjo\"\n- name: \"James Adam\"\n  twitter: \"lazyatom\"\n  github: \"lazyatom\"\n  website: \"https://interblah.net\"\n  slug: \"james-adam\"\n- name: \"James Bell\"\n  github: \"sarcas\"\n  website: \"http://blog.zasperationbell.co.uk\"\n  slug: \"james-bell\"\n- name: \"James Britt\"\n  github: \"\"\n  slug: \"james-britt\"\n- name: \"James Carr\"\n  github: \"jd-stripe\"\n  slug: \"james-carr\"\n- name: \"James Casey\"\n  github: \"jamesc\"\n  website: \"http://about.me/james_casey\"\n  slug: \"james-casey\"\n- name: \"James Coglan\"\n  github: \"jcoglan\"\n  website: \"https://shop.jcoglan.com/\"\n  slug: \"james-coglan\"\n- name: \"James Corey\"\n  github: \"mmjames04\"\n  slug: \"james-corey\"\n- name: \"James Dabbs\"\n  twitter: \"jamesdabbs\"\n  github: \"jamesdabbs\"\n  website: \"http://jdabbs.com\"\n  slug: \"james-dabbs\"\n- name: \"James Edward Gray II\"\n  github: \"jeg2\"\n  website: \"http://graysoftinc.com/\"\n  slug: \"james-edward-gray-ii\"\n  aliases:\n    - name: \"James Edward Gray\"\n      slug: \"james-edward-gray\"\n- name: \"James Edward-Jones\"\n  github: \"\"\n  slug: \"james-edward-jones\"\n- name: \"James Edwards-Jones\"\n  github: \"\"\n  slug: \"james-edwards-jones\"\n- name: \"James Golick\"\n  github: \"jamesgolick\"\n  website: \"http://jamesgolick.com\"\n  slug: \"james-golick\"\n- name: \"James Hand\"\n  github: \"\"\n  slug: \"james-hand\"\n- name: \"James Kerr\"\n  twitter: \"specialCaseDev\"\n  github: \"jameskerr\"\n  website: \"https://www.jameskerr.blog\"\n  slug: \"james-kerr\"\n- name: \"James Kiesel\"\n  github: \"gdpelican\"\n  slug: \"james-kiesel\"\n- name: \"James MacAulay\"\n  github: \"\"\n  slug: \"james-macaulay\"\n- name: \"James Mead\"\n  github: \"\"\n  slug: \"james-mead\"\n- name: \"James Reid-Smith\"\n  github: \"\"\n  slug: \"james-reid-smith\"\n- name: \"James Roscoe\"\n  github: \"\"\n  slug: \"james-roscoe\"\n- name: \"James Rosen\"\n  github: \"\"\n  slug: \"james-rosen\"\n- name: \"James Smith\"\n  github: \"Floppy\"\n  slug: \"james-smith\"\n- name: \"James Stocks\"\n  github: \"james-stocks\"\n  slug: \"james-stocks\"\n- name: \"James Thompson\"\n  twitter: \"plainprogrammer\"\n  github: \"plainprogrammer\"\n  website: \"https://james.thomps.onl\"\n  slug: \"james-thompson\"\n- name: \"James Turnbull\"\n  github: \"\"\n  slug: \"james-turnbull\"\n- name: \"James W. McGuffee\"\n  github: \"\"\n  slug: \"james-w-mcguffee\"\n- name: \"Jameson Hampton\"\n  github: \"\"\n  slug: \"jameson-hampton\"\n- name: \"Jamie Alessio\"\n  github: \"jalessio\"\n  slug: \"jamie-alessio\"\n- name: \"Jamie Gaskins\"\n  twitter: \"jamie_gaskins\"\n  github: \"jgaskins\"\n  slug: \"jamie-gaskins\"\n- name: \"Jamie Riedesel\"\n  github: \"\"\n  slug: \"jamie-riedesel\"\n- name: \"Jamis Buck\"\n  twitter: \"jamis\"\n  github: \"jamis\"\n  website: \"http://weblog.jamisbuck.org\"\n  slug: \"jamis-buck\"\n- name: \"Jamon Holmgren\"\n  twitter: \"jamonholmgren\"\n  github: \"jamonholmgren\"\n  website: \"https://jamon.dev\"\n  slug: \"jamon-holmgren\"\n- name: \"Jan Dudek\"\n  twitter: \"_janek\"\n  github: \"jdudek\"\n  website: \"http://jandudek.com\"\n  slug: \"jan-dudek\"\n- name: \"Jan Dudulski\"\n  twitter: \"yanoo_\"\n  github: \"jandudulski\"\n  website: \"https://dudulski.pl\"\n  slug: \"jan-dudulski\"\n- name: \"Jan Filipowski\"\n  twitter: \"janfilipowski\"\n  github: \"yashke\"\n  website: \"https://yashke.tech\"\n  slug: \"jan-filipowski\"\n- name: \"Jan Grodowski\"\n  twitter: \"mrgrodo\"\n  github: \"grodowski\"\n  website: \"https://grodowski.com\"\n  slug: \"jan-grodowski\"\n- name: \"Jan Krutisch\"\n  twitter: \"halfbyte\"\n  github: \"halfbyte\"\n  website: \"https://jan.krutisch.de/\"\n  slug: \"jan-krutisch\"\n- name: \"Jan Kus\"\n  github: \"gasmotorenfabrik\"\n  slug: \"jan-kus\"\n- name: \"Jan Lehnardt\"\n  github: \"\"\n  slug: \"jan-lehnardt\"\n- name: \"Jan Lelis\"\n  github: \"janlelis\"\n  website: \"https://janlelis.com\"\n  slug: \"jan-lelis\"\n- name: \"Jan Stępień\"\n  github: \"jstepien\"\n  website: \"https://git.stępień.com\"\n  slug: \"jan-stepien\"\n- name: \"Jane Lenhardt\"\n  github: \"\"\n  slug: \"jane-lenhardt\"\n- name: \"Jane Portman\"\n  twitter: \"uibreakfast\"\n  github: \"uibreakfast\"\n  slug: \"jane-portman\"\n- name: \"Janek Grodowski\"\n  github: \"\"\n  slug: \"janek-grodowski\"\n- name: \"Janet Brown\"\n  github: \"\"\n  slug: \"janet-brown\"\n- name: \"Janet Crawford\"\n  github: \"\"\n  slug: \"janet-crawford\"\n- name: \"Janis Baiza\"\n  twitter: \"jbaiza\"\n  github: \"jbaiza\"\n  slug: \"janis-baiza\"\n- name: \"Janko Marohnić\"\n  github: \"janko\"\n  slug: \"janko-marohnic\"\n- name: \"Jano González\"\n  github: \"\"\n  slug: \"jano-gonzalez\"\n  aliases:\n    - name: \"Jano Gonzalez\"\n      slug: \"jano-gonzalez\"\n- name: \"Janusz Mordarski\"\n  github: \"januszm\"\n  website: \"http://www.mordarski.eu\"\n  slug: \"janusz-mordarski\"\n- name: \"Jany Mai\"\n  github: \"\"\n  slug: \"jany-mai\"\n- name: \"Jared Friedman\"\n  github: \"snowmaker\"\n  website: \"http://www.scribd.com\"\n  slug: \"jared-friedman\"\n- name: \"Jared Ning\"\n  github: \"ordinaryzelig\"\n  website: \"http://redningja.com/\"\n  slug: \"jared-ning\"\n- name: \"Jared Norman\"\n  twitter: \"jardonamron\"\n  github: \"jarednorman\"\n  website: \"https://jardo.dev\"\n  slug: \"jared-norman\"\n- name: \"Jared Richardson\"\n  github: \"\"\n  slug: \"jared-richardson\"\n- name: \"Jared Turner\"\n  github: \"\"\n  slug: \"jared-turner\"\n- name: \"Jared White\"\n  github: \"jaredcwhite\"\n  website: \"https://www.whitefusion.studio\"\n  slug: \"jared-white\"\n- name: \"Jarinko\"\n  github: \"\"\n  slug: \"jarinko\"\n- name: \"Jarka Košanová\"\n  github: \"jarkaK\"\n  slug: \"jarka-kosanova\"\n- name: \"Jarrod Reyes\"\n  github: \"reyes-dev\"\n  slug: \"jarrod-reyes\"\n- name: \"Jason Brennan\"\n  github: \"jbrennan\"\n  website: \"https://nearthespeedoflight.com\"\n  slug: \"jason-brennan\"\n- name: \"Jason Brown\"\n  github: \"\"\n  slug: \"jason-brown\"\n- name: \"Jason Charnes\"\n  twitter: \"jmcharnes\"\n  github: \"jasoncharnes\"\n  website: \"http://www.jasoncharnes.com\"\n  slug: \"jason-charnes\"\n- name: \"Jason Clark\"\n  twitter: \"jaclark\"\n  github: \"jasonclark\"\n  website: \"https://www.jasonclark.info\"\n  slug: \"jason-clark\"\n  aliases:\n    - name: \"Jason A. Clark\"\n      slug: \"jason-a-clark\"\n- name: \"Jason Derrett\"\n  github: \"\"\n  slug: \"jason-derrett\"\n- name: \"Jason Garber\"\n  github: \"\"\n  slug: \"jason-garber\"\n- name: \"Jason Goecke\"\n  github: \"\"\n  slug: \"jason-goecke\"\n- name: \"Jason Meller\"\n  twitter: \"jmeller\"\n  github: \"terracatta\"\n  website: \"https://kolide.com\"\n  slug: \"jason-meller\"\n- name: \"Jason Noble\"\n  github: \"jasonnoble\"\n  website: \"http://jasonnoble.org\"\n  slug: \"jason-noble\"\n- name: \"Jason Nochlin\"\n  twitter: \"jasonnochlin\"\n  github: \"hundredwatt\"\n  slug: \"jason-nochlin\"\n- name: \"Jason Ong\"\n  github: \"\"\n  slug: \"jason-ong\"\n- name: \"Jason Owen\"\n  twitter: \"jasonaowen\"\n  github: \"jasonaowen\"\n  website: \"https://jasonaowen.net\"\n  slug: \"jason-owen\"\n- name: \"Jason R. Clark\"\n  github: \"\"\n  slug: \"jason-r-clark\"\n- name: \"Jason Roelofs\"\n  github: \"\"\n  slug: \"jason-roelofs\"\n- name: \"Jason Seifer\"\n  github: \"\"\n  slug: \"jason-seifer\"\n- name: \"Jason Sisk\"\n  twitter: \"sisk\"\n  github: \"sisk\"\n  slug: \"jason-sisk\"\n- name: \"Jason Swett\"\n  twitter: \"jasonswett\"\n  github: \"jasonswett\"\n  website: \"http://www.codewithjason.com/\"\n  slug: \"jason-swett\"\n- name: \"Jason Weathered\"\n  github: \"\"\n  slug: \"jason-weathered\"\n- name: \"Jason Yeo\"\n  github: \"\"\n  slug: \"jason-yeo\"\n- name: \"Jasveen Sandral\"\n  github: \"jsxs0\"\n  slug: \"jasveen-sandral\"\n- name: \"Javi Ramirez\"\n  github: \"rameerez\"\n  slug: \"javi-rameerez\"\n- name: \"Javier Honduvilla Coto\"\n  github: \"\"\n  slug: \"javier-honduvilla-coto\"\n- name: \"Javier Ramirez\"\n  github: \"frjaraur\"\n  website: \"https://codegazers.github.io/\"\n  slug: \"javier-ramirez\"\n- name: \"Javier Treviño\"\n  github: \"\"\n  slug: \"javier-trevino\"\n- name: \"Javier Zon\"\n  github: \"jtomaszon\"\n  slug: \"javier-zon\"\n- name: \"Jay Austin Ewing\"\n  github: \"\"\n  slug: \"jay-austin-ewing\"\n- name: \"Jay Caines-Gooby\"\n  github: \"\"\n  slug: \"jay-caines-gooby\"\n- name: \"Jay Fields\"\n  twitter: \"thejayfields\"\n  github: \"jaycfields\"\n  website: \"http://www.jayfields.com\"\n  slug: \"jay-fields\"\n- name: \"Jay Hayes\"\n  twitter: \"iamvery\"\n  github: \"iamvery\"\n  website: \"https://iamvery.com\"\n  slug: \"jay-hayes\"\n- name: \"Jay McGavren\"\n  github: \"jaymcgavren\"\n  website: \"http://jay.mcgavren.com\"\n  slug: \"jay-mcgavren\"\n- name: \"Jay Moorthi\"\n  github: \"semipermeable\"\n  website: \"https://www.solanolabs.com\"\n  slug: \"jay-moorthi\"\n- name: \"Jay Ohms\"\n  github: \"jayohms\"\n  website: \"https://37signals.com/\"\n  slug: \"jay-ohms\"\n- name: \"Jay Phillips\"\n  github: \"jicksta\"\n  slug: \"jay-phillips\"\n- name: \"Jay Zeschin\"\n  github: \"jayzes\"\n  slug: \"jay-zeschin\"\n- name: \"Jaya Wijono\"\n  github: \"\"\n  slug: \"jaya-wijono\"\n- name: \"JC Grubbs\"\n  github: \"thegrubbsian\"\n  website: \"http://devmynd.com\"\n  slug: \"jc-grubbs\"\n- name: \"JD Harrington\"\n  github: \"psi\"\n  slug: \"jd-harrington\"\n- name: \"Jean Boussier\"\n  twitter: \"_byroot\"\n  github: \"byroot\"\n  slug: \"jean-boussier\"\n- name: \"Jean Pierre\"\n  github: \"\"\n  slug: \"jean-pierre\"\n- name: \"Jean-Charles Santi\"\n  twitter: \"_jcsanti\"\n  github: \"jcsanti\"\n  slug: \"jean-charles-santi\"\n- name: \"Jean-Michel Gigault\"\n  github: \"jgigault\"\n  slug: \"jean-michel-gigault\"\n- name: \"Jean-Paul Bonnetouche\"\n  github: \"\"\n  slug: \"jean-paul-bonnetouche\"\n- name: \"Jean-Sebastien Boulanger\"\n  github: \"\"\n  slug: \"jean-sebastien-boulanger\"\n- name: \"Jeannie Evans\"\n  github: \"jmevans0211\"\n  slug: \"jeannie-evans\"\n- name: \"Jeese Cooke\"\n  github: \"\"\n  slug: \"jeese-cooke\"\n- name: \"Jeff Atwood\"\n  github: \"coding-horror\"\n  website: \"http://www.codinghorror.com/blog\"\n  slug: \"jeff-atwood\"\n- name: \"Jeff Barczewski\"\n  github: \"\"\n  slug: \"jeff-barczewski\"\n- name: \"Jeff Casimir\"\n  github: \"jcasimir\"\n  website: \"http://turing.io\"\n  slug: \"jeff-casimir\"\n- name: \"Jeff Cohen\"\n  github: \"jeffcohen\"\n  website: \"https://www.jeffcohenonline.com\"\n  slug: \"jeff-cohen\"\n- name: \"Jeff Dean\"\n  github: \"zilkey\"\n  slug: \"jeff-dean\"\n- name: \"Jeff Foster\"\n  github: \"fffej\"\n  website: \"http://www.fatvat.co.uk/\"\n  slug: \"jeff-foster\"\n- name: \"Jeff Linwood\"\n  github: \"\"\n  slug: \"jeff-linwood\"\n- name: \"Jeff Norris\"\n  github: \"norrissoftware\"\n  slug: \"jeff-norris\"\n- name: \"Jeff Sacks\"\n  github: \"jrsacks\"\n  slug: \"jeff-sacks\"\n- name: \"Jeffery Davis\"\n  github: \"\"\n  slug: \"jeffery-davis\"\n- name: \"Jeffery L. Taylor\"\n  github: \"\"\n  slug: \"jeffery-l-taylor\"\n- name: \"Jeffery Matthias\"\n  github: \"\"\n  slug: \"jeffery-matthias\"\n- name: \"Jeffrey Cohen\"\n  github: \"jeffreycohenit\"\n  slug: \"jeffrey-cohen\"\n- name: \"Jeffrey Matthias\"\n  github: \"idlehands\"\n  website: \"http://idlehands.codes\"\n  slug: \"jeffrey-matthias\"\n- name: \"Jemma Issroff\"\n  twitter: \"JemmaIssroff\"\n  github: \"jemmaissroff\"\n  website: \"https://jemma.dev\"\n  slug: \"jemma-issroff\"\n- name: \"Jen Diamond\"\n  github: \"rubilicious\"\n  website: \"http://rubilicious.github.io/\"\n  slug: \"jen-diamond\"\n- name: \"Jen Meyers\"\n  github: \"\"\n  slug: \"jen-meyers\"\n- name: \"Jen Pengelly\"\n  twitter: \"jenpengelly\"\n  github: \"jenpen\"\n  slug: \"jen-pengelly\"\n- name: \"Jenda Tovarys\"\n  twitter: \"JanTovarys\"\n  github: \"jendatovarys\"\n  website: \"https://growthhackslist.com\"\n  slug: \"jenda-tovarys\"\n- name: \"Jenn Scheer\"\n  github: \"singleportrait\"\n  website: \"http://www.jennscheer.com\"\n  slug: \"jenn-scheer\"\n- name: \"Jenna Blumenthal\"\n  github: \"jennaleeb\"\n  slug: \"jenna-blumenthal\"\n- name: \"Jenner La Fave\"\n  twitter: \"jenrzzz\"\n  github: \"jenrzzz\"\n  website: \"http://jfave.com\"\n  slug: \"jenner-la-fave\"\n- name: \"Jennie Evans\"\n  github: \"Jenniered\"\n  slug: \"jennie-evans\"\n- name: \"Jennifer Tran\"\n  twitter: \"jkim_tran\"\n  github: \"jennifertrin\"\n  slug: \"jennifer-tran\"\n- name: \"Jennifer Tu\"\n  github: \"\"\n  slug: \"jennifer-tu\"\n- name: \"Jenny Allar\"\n  github: \"jennyallar\"\n  slug: \"jenny-allar\"\n- name: \"Jenny Gray\"\n  github: \"\"\n  slug: \"jenny-gray\"\n- name: \"Jenny Shen\"\n  twitter: \"jenshenny\"\n  github: \"jenshenny\"\n  slug: \"jenny-shen\"\n- name: \"Jenny Shih\"\n  twitter: \"jenny_codes\"\n  github: \"jenny-codes\"\n  website: \"https://jenny.sh\"\n  slug: \"jenny-shih\"\n- name: \"Jeppe Liisberg\"\n  github: \"jeppeliisberg\"\n  website: \"https://jeppe.liisberg.dk\"\n  slug: \"jeppe-liisberg\"\n- name: \"Jeramy Couts\"\n  github: \"\"\n  slug: \"jeramy-couts\"\n- name: \"Jeremiah Laravel\"\n  github: \"\"\n  slug: \"jeremiah-laravel\"\n- name: \"Jeremie Castagna\"\n  github: \"\"\n  slug: \"jeremie-castagna\"\n- name: \"Jeremy Ashkenas\"\n  github: \"jashkenas\"\n  slug: \"jeremy-ashkenas\"\n- name: \"Jeremy Daer\"\n  twitter: \"bitsweat\"\n  github: \"jeremy\"\n  website: \"https://jeremydaer.com\"\n  slug: \"jeremy-daer\"\n  aliases:\n    - name: \"Jeremy Kemper\"\n      slug: \"jeremy-kemper\"\n- name: \"Jeremy Evans\"\n  twitter: \"jeremyevans0\"\n  github: \"jeremyevans\"\n  website: \"http://code.jeremyevans.net\"\n  slug: \"jeremy-evans\"\n- name: \"Jeremy Fairbank\"\n  github: \"\"\n  slug: \"jeremy-fairbank\"\n- name: \"Jeremy Flores\"\n  github: \"jeremyflores\"\n  website: \"https://www.jeremyflor.es\"\n  slug: \"jeremy-flores\"\n- name: \"Jeremy Green\"\n  github: \"jagthedrummer\"\n  website: \"http://www.octolabs.com/\"\n  slug: \"jeremy-green\"\n- name: \"Jeremy Hanna\"\n  github: \"jeromatron\"\n  website: \"http://jeromatron.blogspot.com\"\n  slug: \"jeremy-hanna\"\n- name: \"Jeremy Hinegardner\"\n  github: \"copiousfreetime\"\n  website: \"http://copiousfreetime.org\"\n  slug: \"jeremy-hinegardner\"\n- name: \"Jeremy Kirkham\"\n  github: \"\"\n  slug: \"jeremy-kirkham\"\n- name: \"Jeremy McAnally\"\n  twitter: \"door_holder\"\n  github: \"jm\"\n  website: \"http://jeremymcanally.com\"\n  slug: \"jeremy-mcanally\"\n- name: \"Jeremy observations\"\n  github: \"\"\n  slug: \"jeremy-observations\"\n- name: \"Jeremy Perez\"\n  github: \"\"\n  slug: \"jeremy-perez\"\n- name: \"Jeremy Peterson\"\n  github: \"\"\n  slug: \"jeremy-peterson\"\n- name: \"Jeremy Schuurmans\"\n  github: \"jeremyschuurmans\"\n  website: \"https://jeremyschuurmans.com\"\n  slug: \"jeremy-schuurmans\"\n- name: \"Jeremy Smith\"\n  twitter: \"jeremysmithco\"\n  github: \"jeremysmithco\"\n  website: \"https://hybrd.co/\"\n  slug: \"jeremy-smith\"\n- name: \"Jeremy Stell-Smith\"\n  github: \"\"\n  slug: \"jeremy-stell-smith\"\n- name: \"Jeremy Walker\"\n  twitter: \"iHiD\"\n  github: \"iHiD\"\n  slug: \"jeremy-walker\"\n- name: \"Jerome Paul\"\n  github: \"\"\n  slug: \"jerome-paul\"\n- name: \"Jerry Cheung\"\n  github: \"jch\"\n  website: \"http://jch.github.io\"\n  slug: \"jerry-cheung\"\n- name: \"Jerry D'Antonio\"\n  github: \"jdantonio\"\n  website: \"http://www.jerrydantonio.com\"\n  slug: \"jerry-d-antonio\"\n- name: \"Jess Casimir\"\n  github: \"\"\n  slug: \"jess-casimir\"\n- name: \"Jess Eldredge\"\n  github: \"\"\n  slug: \"jess-eldredge\"\n- name: \"Jess Hottenstein\"\n  github: \"jhottenstein\"\n  slug: \"jess-hottenstein\"\n- name: \"Jess Martin\"\n  github: \"\"\n  slug: \"jess-martin\"\n- name: \"Jess Rudder\"\n  github: \"jessrudder\"\n  website: \"http://jessrudder.github.io\"\n  slug: \"jess-rudder\"\n- name: \"Jess Sullivan\"\n  twitter: \"JM_Sully\"\n  github: \"jm-sully\"\n  slug: \"jess-sullivan\"\n  aliases:\n    - name: \"Jessica Sullivan\"\n      slug: \"jessica-sullivan\"\n- name: \"Jess Szmajda\"\n  twitter: \"jszmajda\"\n  github: \"jszmajda\"\n  website: \"http://loki.ws\"\n  slug: \"jess-szmajda\"\n  aliases:\n    - name: \"Josh Szmajda\"\n      slug: \"josh-szmajda\"\n    - name: \"Joshua Szmajda\"\n      slug: \"joshua-szmajda\"\n- name: \"Jesse Belanger\"\n  github: \"jbelang\"\n  slug: \"jesse-belanger\"\n- name: \"Jesse Crouch\"\n  github: \"\"\n  slug: \"jesse-crouch\"\n- name: \"Jesse James\"\n  twitter: \"marginalchaos\"\n  github: \"jrjamespdx\"\n  slug: \"jesse-james\"\n- name: \"Jesse Newland\"\n  github: \"\"\n  slug: \"jesse-newland\"\n- name: \"Jesse Spevack\"\n  github: \"jesse-spevack\"\n  website: \"http://www.verynormal.info\"\n  slug: \"jesse-spevack\"\n- name: \"Jesse Storimer\"\n  github: \"\"\n  slug: \"jesse-storimer\"\n- name: \"Jesse Toth\"\n  github: \"\"\n  slug: \"jesse-toth\"\n- name: \"Jesse Wolgamott\"\n  github: \"jwo\"\n  website: \"http://jessewolgamott.com\"\n  slug: \"jesse-wolgamott\"\n- name: \"Jessica Dillon\"\n  github: \"\"\n  slug: \"jessica-dillon\"\n- name: \"Jessica Eldredge\"\n  github: \"jessabean\"\n  website: \"https://jessabean.dev\"\n  slug: \"jessica-eldredge\"\n- name: \"Jessica Goulding\"\n  github: \"\"\n  slug: \"jessica-goulding\"\n- name: \"Jessica Hilt\"\n  github: \"jessicahilt\"\n  slug: \"jessica-hilt\"\n- name: \"Jessica Kerr\"\n  twitter: \"jessitron\"\n  github: \"jessitron\"\n  website: \"https://jessitron.com\"\n  slug: \"jessica-kerr\"\n- name: \"Jessica Lawrence\"\n  github: \"jmlawrence1971\"\n  slug: \"jessica-lawrence\"\n- name: \"Jessica Roper\"\n  github: \"\"\n  slug: \"jessica-roper\"\n- name: \"Jessica Rudder\"\n  github: \"\"\n  slug: \"jessica-rudder\"\n- name: \"Jessica Suttles\"\n  github: \"\"\n  slug: \"jessica-suttles\"\n- name: \"Jessie Link\"\n  github: \"\"\n  slug: \"jessie-link\"\n- name: \"Jessie Shternshus\"\n  github: \"\"\n  slug: \"jessie-shternshus\"\n- name: \"Jevin Maltais\"\n  github: \"\"\n  slug: \"jevin-maltais\"\n- name: \"Jian Wei-Hang\"\n  github: \"\"\n  slug: \"jian-wei-hang\"\n- name: \"Jill Klang\"\n  github: \"that-jill\"\n  slug: \"jill-klang\"\n- name: \"Jillian Foley\"\n  github: \"\"\n  slug: \"jillian-foley\"\n- name: \"Jillian Rosile\"\n  github: \"jillianrosile\"\n  slug: \"jillian-rosile\"\n- name: \"Jim Denton\"\n  github: \"jimgerneer\"\n  slug: \"jim-denton\"\n- name: \"Jim Gay\"\n  twitter: \"saturnflyer\"\n  github: \"saturnflyer\"\n  website: \"http://clean-ruby.com\"\n  slug: \"jim-gay\"\n- name: \"Jim Holmes\"\n  github: \"jimholmes\"\n  website: \"http://frazzleddad.com\"\n  slug: \"jim-holmes\"\n- name: \"Jim Jones\"\n  github: \"aantix\"\n  website: \"http://www.aantix.com\"\n  slug: \"jim-jones\"\n- name: \"Jim Lindley\"\n  github: \"\"\n  slug: \"jim-lindley\"\n- name: \"Jim Liu\"\n  twitter: \"dotey\"\n  github: \"jimliu\"\n  slug: \"jim-liu\"\n- name: \"Jim Menard\"\n  github: \"\"\n  slug: \"jim-menard\"\n- name: \"Jim Meyer\"\n  github: \"\"\n  slug: \"jim-meyer\"\n- name: \"Jim Mulholland\"\n  github: \"\"\n  slug: \"jim-mulholland\"\n- name: \"Jim Mullholland\"\n  github: \"\"\n  slug: \"jim-mullholland\"\n- name: \"Jim Puls\"\n  github: \"puls\"\n  slug: \"jim-puls\"\n- name: \"Jim Remsik\"\n  twitter: \"jremsikjr\"\n  github: \"bigtiger\"\n  website: \"https://www.beflagrant.com\"\n  slug: \"jim-remsik\"\n- name: \"Jim Weirich\"\n  github: \"jimweirich\"\n  website: \"http://onestepback.org\"\n  slug: \"jim-weirich\"\n- name: \"Jimmy Wu\"\n  github: \"\"\n  slug: \"jimmy-wu\"\n- name: \"Jimmy Zimmerman\"\n  github: \"\"\n  slug: \"jimmy-zimmerman\"\n- name: \"Jing yi Chen\"\n  github: \"julientpu\"\n  slug: \"jing-yi-chen\"\n- name: \"Jingyi Chen\"\n  github: \"jingyi-chen\"\n  slug: \"jingyi-chen\"\n- name: \"Jinny Wong\"\n  twitter: \"shujinh\"\n  github: \"shujin\"\n  slug: \"jinny-wong\"\n- name: \"Jo Cranford\"\n  github: \"\"\n  slug: \"jo-cranford\"\n- name: \"Jo Ha\"\n  github: \"\"\n  slug: \"jo-ha\"\n- name: \"Joakim Antman\"\n  twitter: \"anakinj\"\n  github: \"anakinj\"\n  website: \"https://antman.dev\"\n  slug: \"joakim-antman\"\n- name: \"Joan Wolkerstorfer\"\n  github: \"\"\n  slug: \"joan-wolkerstorfer\"\n- name: \"Joannah Nanjekye\"\n  github: \"nanjekyejoannah\"\n  slug: \"joannah-nanjekye\"\n- name: \"Joanne Cheng\"\n  twitter: \"joannecheng\"\n  github: \"joannecheng\"\n  website: \"http://joannecheng.me/\"\n  slug: \"joanne-cheng\"\n- name: \"Joaquín Vicente\"\n  github: \"\"\n  slug: \"joaquin-vicente\"\n- name: \"Jochen Lillich\"\n  github: \"geewiz\"\n  slug: \"jochen-lillich\"\n- name: \"Joe\"\n  github: \"frontend-joe\"\n  website: \"https://frontendjoe.com\"\n  slug: \"joe\"\n- name: \"Joe Damato\"\n  github: \"ice799\"\n  slug: \"joe-damato\"\n- name: \"Joe Dean\"\n  github: \"\"\n  slug: \"joe-dean\"\n- name: \"Joe Ferguson\"\n  github: \"\"\n  slug: \"joe-ferguson\"\n- name: \"Joe Hart\"\n  twitter: \"JoeHart\"\n  github: \"joehart\"\n  website: \"https://www.joehart.co.uk\"\n  slug: \"joe-hart\"\n- name: \"Joe Kutner\"\n  github: \"jkutner\"\n  website: \"http://healthyprog.com\"\n  slug: \"joe-kutner\"\n- name: \"Joe Leo\"\n  github: \"jleo3\"\n  website: \"https://defmethod.com\"\n  slug: \"joe-leo\"\n- name: \"Joe Marinez\"\n  github: \"\"\n  slug: \"joe-marinez\"\n- name: \"Joe Masilotti\"\n  twitter: \"joemasilotti\"\n  github: \"joemasilotti\"\n  website: \"https://masilotti.com\"\n  slug: \"joe-masilotti\"\n- name: \"Joe Mastey\"\n  github: \"jmmastey\"\n  website: \"https://joemastey.com\"\n  slug: \"joe-mastey\"\n- name: \"Joe Moore\"\n  github: \"joemoore\"\n  website: \"http://remotepairprogramming.com\"\n  slug: \"joe-moore\"\n- name: \"Joe O'Brien\"\n  github: \"\"\n  slug: \"joe-o-brien\"\n- name: \"Joe Peck\"\n  twitter: \"fatcatt316\"\n  github: \"fatcatt316\"\n  website: \"https://peckyeah.com\"\n  slug: \"joe-peck\"\n- name: \"Joel Biffin\"\n  github: \"\"\n  slug: \"joel-biffin\"\n- name: \"Joel Chippindale\"\n  github: \"\"\n  slug: \"joel-chippindale\"\n- name: \"Joel Drapper\"\n  github: \"joeldrapper\"\n  website: \"https://joel.drapper.me\"\n  slug: \"joel-drapper\"\n- name: \"Joel Hawksley\"\n  twitter: \"joelhawksley\"\n  github: \"joelhawksley\"\n  website: \"https://hawksley.org\"\n  slug: \"joel-hawksley\"\n- name: \"Joel Turnbull\"\n  github: \"joelturnbull\"\n  slug: \"joel-turnbull\"\n- name: \"Joey @fergmastaflex\"\n  github: \"\"\n  slug: \"joey-fergmastaflex\"\n- name: \"Johan Launila\"\n  github: \"\"\n  slug: \"johan-launila\"\n- name: \"Johanna Lang\"\n  github: \"langjoh\"\n  slug: \"johanna-lang\"\n- name: \"Johannes Balk\"\n  github: \"\"\n  slug: \"johannes-balk\"\n- name: \"Johannes Daxböck\"\n  github: \"dingsdax\"\n  slug: \"johannes-daxbock\"\n- name: \"Johannes Müller\"\n  github: \"straight-shoota\"\n  slug: \"johannes-muller\"\n- name: \"Johannes Tuchscherer\"\n  github: \"jtuchscherer\"\n  slug: \"johannes-tuchscherer\"\n- name: \"John Allspaw\"\n  twitter: \"allspaw\"\n  github: \"jallspaw\"\n  website: \"https://www.adaptivecapacitylabs.com\"\n  slug: \"john-allspaw\"\n- name: \"John Athayde\"\n  twitter: \"johnathayde\"\n  github: \"jathayde\"\n  website: \"https://www.sfumatofarm.com\"\n  slug: \"john-athayde\"\n- name: \"John Backus\"\n  github: \"backus\"\n  website: \"http://johnback.us/\"\n  slug: \"john-backus\"\n- name: \"John Barnette\"\n  github: \"jbarnette\"\n  website: \"http://github.com/jbarnette\"\n  slug: \"john-barnette\"\n- name: \"John Barton\"\n  github: \"\"\n  slug: \"john-barton\"\n- name: \"John Beatty\"\n  twitter: \"onrailsjohn\"\n  github: \"johnbeatty\"\n  website: \"https://onrails.blog\"\n  slug: \"john-beatty\"\n- name: \"John Bender\"\n  twitter: \"johnbender\"\n  github: \"johnbender\"\n  website: \"http://johnbender.us\"\n  slug: \"john-bender\"\n- name: \"John Britton\"\n  github: \"\"\n  slug: \"john-britton\"\n- name: \"John Cinnamond\"\n  github: \"jcinnamond\"\n  slug: \"john-cinnamond\"\n- name: \"John Crepezzi\"\n  github: \"seejohnrun\"\n  website: \"http://johncrepezzi.com\"\n  slug: \"john-crepezzi\"\n- name: \"John Dalton\"\n  github: \"\"\n  slug: \"john-dalton\"\n- name: \"John DeSilva\"\n  github: \"Aesthetikx\"\n  slug: \"john-desilva\"\n- name: \"John Dewsnap\"\n  github: \"\"\n  slug: \"john-dewsnap\"\n- name: \"John DeWyze\"\n  github: \"dewyze\"\n  slug: \"john-dewyze\"\n- name: \"John Downey\"\n  twitter: \"jtdowney\"\n  github: \"jtdowney\"\n  website: \"https://jtdowney.com\"\n  slug: \"john-downey\"\n- name: \"John Duff\"\n  github: \"jduff\"\n  website: \"http://jduff.github.com/\"\n  slug: \"john-duff\"\n- name: \"John Epperson\"\n  github: \"kirillian\"\n  website: \"https://rockagile.io\"\n  slug: \"john-epperson\"\n- name: \"John Feminella\"\n  github: \"fj\"\n  website: \"http://www.linkedin.com/in/johnxf\"\n  slug: \"john-feminella\"\n- name: \"John Foley\"\n  github: \"jjfiv\"\n  website: \"https://jjfoley.me\"\n  slug: \"john-foley\"\n- name: \"John Gallagher\"\n  twitter: \"synapticmishap\"\n  github: \"johngallagher\"\n  website: \"https://joyfulprogramming.com\"\n  slug: \"john-gallagher\"\n- name: \"John Hawthorn\"\n  github: \"jhawthorn\"\n  website: \"https://john.hawthorn.website\"\n  slug: \"john-hawthorn\"\n- name: \"John Lam\"\n  twitter: \"john_lam\"\n  github: \"jflam\"\n  website: \"http://www.iunknown.com\"\n  slug: \"john-lam\"\n- name: \"John Lin\"\n  github: \"johnlinvc\"\n  website: \"https://johnlin.vc\"\n  slug: \"john-lin\"\n- name: \"John M. Willis\"\n  github: \"\"\n  slug: \"john-m-willis\"\n- name: \"John Mettraux\"\n  github: \"jmettraux\"\n  slug: \"john-mettraux\"\n- name: \"John Nunemaker\"\n  github: \"\"\n  slug: \"john-nunemaker\"\n- name: \"John Paul Ashenfelter\"\n  github: \"johnpaulashenfelter\"\n  website: \"http://www.transitionpoint.com\"\n  slug: \"john-paul-ashenfelter\"\n- name: \"John Phamvan\"\n  github: \"\"\n  slug: \"john-phamvan\"\n- name: \"John Pignata\"\n  github: \"jpignata\"\n  slug: \"john-pignata\"\n- name: \"John Pollard\"\n  twitter: \"johnlpollard\"\n  github: \"johnlpollard\"\n  slug: \"john-pollard\"\n- name: \"John Rowe\"\n  github: \"\"\n  slug: \"john-rowe\"\n- name: \"John Sawers\"\n  github: \"johnksawers\"\n  website: \"https://johnksawers.com\"\n  slug: \"john-sawers\"\n- name: \"John Schoeman\"\n  github: \"\"\n  slug: \"john-schoeman\"\n- name: \"John Sherwood\"\n  github: \"ponny\"\n  slug: \"john-sherwood\"\n- name: \"John Taber\"\n  github: \"\"\n  slug: \"john-taber\"\n- name: \"John Wilkinson\"\n  github: \"jcwilk\"\n  website: \"https://jcwilk.com\"\n  slug: \"john-wilkinson\"\n- name: \"John Woodell\"\n  twitter: \"JohnWoodell\"\n  github: \"woodie\"\n  website: \"https://medium.com/@JohnWoodell\"\n  slug: \"john-woodell\"\n- name: \"Johnny Shields\"\n  github: \"johnnyshields\"\n  website: \"https://www.tablecheck.com/en/join\"\n  slug: \"johnny-shields\"\n- name: \"Johnny T\"\n  github: \"\"\n  slug: \"johnny-t\"\n- name: \"Johnny Winn\"\n  github: \"\"\n  slug: \"johnny-winn\"\n- name: \"JohnnyT\"\n  twitter: \"johnny_t\"\n  github: \"johnnyt\"\n  website: \"https://johnnyt.github.com\"\n  slug: \"johnnyt\"\n- name: \"Johnson\"\n  github: \"\"\n  slug: \"johnson\"\n- name: \"Johnson Zhan\"\n  github: \"\"\n  slug: \"johnson-zhan\"\n- name: \"Johny Ho\"\n  github: \"jho406\"\n  slug: \"johny-ho\"\n- name: \"Joichiro Okoshi\"\n  github: \"\"\n  slug: \"joichiro-okoshi\"\n- name: \"Jolyon Pawlyn\"\n  github: \"\"\n  slug: \"jolyon-pawlyn\"\n- name: \"Jon Arnold\"\n  github: \"\"\n  slug: \"jon-arnold\"\n- name: \"Jon Crosby\"\n  github: \"\"\n  slug: \"jon-crosby\"\n- name: \"Jon Dahl\"\n  github: \"joda\"\n  slug: \"jon-dahl\"\n- name: \"Jon Druse\"\n  github: \"jondruse\"\n  website: \"http://jondruse.com\"\n  slug: \"jon-druse\"\n- name: \"Jon Evans\"\n  github: \"craftyjon\"\n  website: \"https://craftyjon.com\"\n  slug: \"jon-evans\"\n- name: \"Jon Guymon\"\n  github: \"\"\n  slug: \"jon-guymon\"\n- name: \"Jon Jensen\"\n  github: \"\"\n  slug: \"jon-jensen\"\n- name: \"Jon Leighton\"\n  github: \"\"\n  slug: \"jon-leighton\"\n- name: \"Jon McCartie\"\n  github: \"jmccartie\"\n  website: \"https://www.mccartie.com/tech/\"\n  slug: \"jon-mccartie\"\n- name: \"Jon Rowe\"\n  twitter: \"JonRowe\"\n  github: \"JonRowe\"\n  slug: \"jon-rowe\"\n- name: \"Jon Sullivan\"\n  github: \"jon-sully\"\n  website: \"https://jonsully.net\"\n  slug: \"jon-sullivan\"\n- name: \"Jonan Scheffler\"\n  twitter: \"thejonanshow\"\n  github: \"thejonanshow\"\n  website: \"https://thejonanshow.com\"\n  slug: \"jonan-scheffler\"\n- name: \"Jonan Schefler\"\n  github: \"\"\n  slug: \"jonan-schefler\"\n- name: \"Jonas Jabari\"\n  twitter: \"jonasjabari\"\n  github: \"jonasjabari\"\n  website: \"https://jonasjabari.dev\"\n  slug: \"jonas-jabari\"\n- name: \"Jonas Nicklas\"\n  github: \"jnicklas\"\n  website: \"https://blog.jnicklas.com/\"\n  slug: \"jonas-nicklas\"\n- name: \"Jonathan Boccara\"\n  github: \"\"\n  slug: \"jonathan-boccara\"\n- name: \"Jonathan Dahl\"\n  github: \"\"\n  slug: \"jonathan-dahl\"\n- name: \"Jonathan Jackson\"\n  github: \"\"\n  slug: \"jonathan-jackson\"\n- name: \"Jonathan James\"\n  github: \"\"\n  slug: \"jonathan-james\"\n- name: \"Jonathan Markwell\"\n  github: \"\"\n  slug: \"jonathan-markwell\"\n- name: \"Jonathan Martin\"\n  github: \"nybblr\"\n  website: \"https://jonathanleemartin.com\"\n  slug: \"jonathan-martin\"\n- name: \"Jonathan Palley\"\n  github: \"\"\n  slug: \"jonathan-palley\"\n- name: \"Jonathan Slate\"\n  twitter: \"jslate\"\n  github: \"jslate\"\n  slug: \"jonathan-slate\"\n- name: \"Jonathan Wallace\"\n  github: \"wallace\"\n  website: \"http://blog.jonathanrwallace.com\"\n  slug: \"jonathan-wallace\"\n- name: \"Jonathan Weiss\"\n  github: \"\"\n  slug: \"jonathan-weiss\"\n- name: \"Jonathan Woodard\"\n  github: \"\"\n  slug: \"jonathan-woodard\"\n- name: \"Jonathan Younger\"\n  github: \"\"\n  slug: \"jonathan-younger\"\n- name: \"Jonathon Slate\"\n  github: \"\"\n  slug: \"jonathon-slate\"\n- name: \"Jordan Bach\"\n  github: \"jbgo\"\n  website: \"http://opensolitude.com\"\n  slug: \"jordan-bach\"\n- name: \"Jordan Burke\"\n  github: \"pendragondevelopment\"\n  website: \"http://headway.io\"\n  slug: \"jordan-burke\"\n- name: \"Jordan Byron\"\n  github: \"jordanbyron\"\n  website: \"https://jordanbyron.com\"\n  slug: \"jordan-byron\"\n- name: \"Jordan Raine\"\n  github: \"jnraine\"\n  website: \"https://jordanraine.com\"\n  slug: \"jordan-raine\"\n- name: \"Jordan Reuter\"\n  github: \"jreut\"\n  slug: \"jordan-reuter\"\n- name: \"Jordan Trevino\"\n  github: \"\"\n  slug: \"jordan-trevino\"\n- name: \"Joren De Groof\"\n  github: \"\"\n  slug: \"joren-de-groof\"\n- name: \"Jorge Leites\"\n  github: \"jorgeleites\"\n  slug: \"jorge-leites\"\n- name: \"Jorge Manrubia\"\n  github: \"jorgemanrubia\"\n  website: \"https://jorgemanrubia.com\"\n  slug: \"jorge-manrubia\"\n- name: \"Joschka Schulz\"\n  github: \"joschkaschulz\"\n  slug: \"joschka-schulz\"\n- name: \"Jose Blanco\"\n  github: \"laicuRoot\"\n  slug: \"jose-blanco\"\n- name: \"Jose Castro\"\n  github: \"\"\n  slug: \"jose-castro\"\n- name: \"Jose Miguel Tomita Rodriguez\"\n  github: \"\"\n  slug: \"jose-miguel-tomita-rodriguez\"\n- name: \"Jose Rosello\"\n  github: \"jmr0\"\n  slug: \"jose-rosello\"\n- name: \"Josef Haider\"\n  github: \"djoooooe\"\n  slug: \"josef-haider\"\n- name: \"Josef Liška\"\n  github: \"phokz\"\n  website: \"https://www.virtualmaster.com/\"\n  slug: \"josef-liska\"\n- name: \"Josef Strzibny\"\n  github: \"strzibny\"\n  website: \"https://strzibny.name/\"\n  slug: \"josef-strzibny\"\n- name: \"Josep M. \\\"Tsux\\\" Bach\"\n  github: \"\"\n  slug: \"josep-m-tsux-bach\"\n- name: \"Joseph Blanchard\"\n  github: \"jpheos\"\n  slug: \"joseph-blanchard\"\n- name: \"Joseph Dean\"\n  github: \"\"\n  slug: \"joseph-dean\"\n- name: \"Joseph Ruscio\"\n  github: \"josephruscio\"\n  website: \"https://www.heavybit.com/\"\n  slug: \"joseph-ruscio\"\n- name: \"Joseph Wilk\"\n  twitter: \"josephwilk\"\n  github: \"josephwilk\"\n  website: \"http://art.josephwilk.net/\"\n  slug: \"joseph-wilk\"\n- name: \"Josh\"\n  github: \"\"\n  slug: \"josh\"\n- name: \"Josh Adams\"\n  github: \"knewter\"\n  website: \"https://www.dbadbadba.com\"\n  slug: \"josh-adams\"\n- name: \"Josh Bebbington\"\n  github: \"\"\n  slug: \"josh-bebbington\"\n- name: \"Josh Freeman\"\n  github: \"vekien\"\n  slug: \"josh-freeman\"\n- name: \"Josh Greenwood\"\n  github: \"joshgreenwood2003\"\n  slug: \"josh-greenwood\"\n- name: \"Josh Kalderimis\"\n  github: \"joshk\"\n  slug: \"josh-kalderimis\"\n- name: \"Josh Knowles\"\n  github: \"\"\n  slug: \"josh-knowles\"\n- name: \"Josh Lewis\"\n  twitter: \"joshwlewis\"\n  github: \"joshwlewis\"\n  website: \"http://joshwlewis.com/\"\n  slug: \"josh-lewis\"\n- name: \"Josh Loper\"\n  github: \"\"\n  slug: \"josh-loper\"\n- name: \"Josh Nichols\"\n  twitter: \"techpickles\"\n  github: \"technicalpickles\"\n  website: \"https://pickles.dev\"\n  slug: \"josh-nichols\"\n- name: \"Josh Price\"\n  github: \"\"\n  slug: \"josh-price\"\n- name: \"Josh Puetz\"\n  twitter: \"joshpuetz\"\n  github: \"joshpuetz\"\n  website: \"http://joshpuetz.com\"\n  slug: \"josh-puetz\"\n- name: \"Josh Schairbaum\"\n  github: \"\"\n  slug: \"josh-schairbaum\"\n- name: \"Josh Susser\"\n  github: \"joshsusser\"\n  website: \"http://blog.hasmanythrough.com\"\n  slug: \"josh-susser\"\n- name: \"Josh Susser (Fixed)\"\n  github: \"\"\n  slug: \"josh-susser-fixed\"\n- name: \"Josh Thompson\"\n  twitter: \"josh_works\"\n  github: \"josh-works\"\n  website: \"https://josh.works\"\n  slug: \"josh-thompson\"\n- name: \"Joshua Ballanco\"\n  github: \"\"\n  slug: \"joshua-ballanco\"\n- name: \"Joshua Hull\"\n  github: \"\"\n  slug: \"joshua-hull\"\n- name: \"Joshua Larson\"\n  github: \"\"\n  slug: \"joshua-larson\"\n- name: \"Joshua Maurer\"\n  github: \"\"\n  slug: \"joshua-maurer\"\n- name: \"Joshua Paine\"\n  github: \"midnightmonster\"\n  website: \"https://letterblock.com/\"\n  slug: \"joshua-paine\"\n- name: \"Joshua Quick\"\n  github: \"\"\n  slug: \"joshua-quick\"\n- name: \"Joshua Timberman\"\n  github: \"\"\n  slug: \"joshua-timberman\"\n- name: \"Joshua Wehner\"\n  github: \"\"\n  slug: \"joshua-wehner\"\n- name: \"Joshua Young\"\n  github: \"joshuay03\"\n  slug: \"joshua-young\"\n- name: \"Joss Paling\"\n  github: \"\"\n  slug: \"joss-paling\"\n- name: \"Josua Schmid\"\n  github: \"schmijos\"\n  website: \"https://schmijos.medium.com/\"\n  slug: \"josua-schmid\"\n- name: \"José Anchieta\"\n  github: \"anchietajunior\"\n  website: \"https://joseanchieta.dev\"\n  slug: \"jose-anchieta\"\n- name: \"José Augusto Dias Rosa\"\n  github: \"\"\n  linkedin: \"https://www.linkedin.com/in/joseaugustodev\"\n  slug: \"jose-augusto-dias-rosa\"\n- name: \"José Tomás Albornoz\"\n  github: \"\"\n  slug: \"jose-tomas-albornoz\"\n- name: \"José Valim\"\n  twitter: \"josevalim\"\n  github: \"josevalim\"\n  website: \"https://dashbit.co/\"\n  slug: \"jose-valim\"\n  aliases:\n    - name: \"Jose Valim\"\n      slug: \"jose-valim\"\n- name: \"Joy Heron\"\n  github: \"joyheron\"\n  website: \"http://joyheron.com\"\n  slug: \"joy-heron\"\n- name: \"Joy Paas\"\n  github: \"\"\n  slug: \"joy-paas\"\n- name: \"Joás Cabral\"\n  github: \"\"\n  bluesky: \"maltexto.armadilha.org\"\n  slug: \"joas-cabral\"\n- name: \"João Moura\"\n  twitter: \"joaomdmoura\"\n  github: \"joaomdmoura\"\n  website: \"https://crewai.com\"\n  slug: \"joao-moura\"\n  aliases:\n    - name: \"João M.D. Moura\"\n      slug: \"joao-md-moura\"\n- name: \"Joël Quenneville\"\n  twitter: \"joelquen\"\n  github: \"JoelQ\"\n  website: \"https://thoughtbot.com/blog/authors/joel-quenneville\"\n  slug: \"joel-quenneville\"\n  aliases:\n    - name: \"Joel Quenneville\"\n      slug: \"joel-quenneville\"\n- name: \"JP Camara\"\n  twitter: \"jpcamara\"\n  github: \"jpcamara\"\n  website: \"http://www.jpcamara.com\"\n  slug: \"jp-camara\"\n- name: \"JP Phillips\"\n  github: \"\"\n  slug: \"jp-phillips\"\n- name: \"Ju Liu\"\n  twitter: \"arkh4m\"\n  github: \"arkham\"\n  website: \"https://juliu.is\"\n  slug: \"ju-liu\"\n- name: \"Juan Barreneche\"\n  github: \"\"\n  slug: \"juan-barreneche\"\n- name: \"Juan C. Ruiz\"\n  github: \"\"\n  slug: \"juan-c-ruiz\"\n- name: \"Juan Carlos Ruiz\"\n  github: \"juancrg90\"\n  website: \"http://juancrg90.me/\"\n  slug: \"juan-carlos-ruiz\"\n- name: \"Juan Francisco Raposeiras\"\n  github: \"\"\n  slug: \"juan-francisco-raposeiras\"\n- name: \"Juan Pablo Balarini\"\n  github: \"jpbalarini\"\n  slug: \"jp-balarini\"\n- name: \"Juan Pablo Genovese\"\n  github: \"\"\n  slug: \"juan-pablo-genovese\"\n- name: \"Juan Pascual\"\n  github: \"\"\n  slug: \"juan-pascual\"\n- name: \"Juanito Fatas\"\n  twitter: \"JuanitoFatas\"\n  github: \"juanitofatas\"\n  website: \"https://juanitofatas.com\"\n  slug: \"juanito-fatas\"\n- name: \"Judit Ördög-Andrási\"\n  github: \"\"\n  slug: \"judit-ordog-andrasi\"\n- name: \"Jugyo\"\n  github: \"jugyo\"\n  slug: \"jugyo\"\n- name: \"Julia Cuppy\"\n  github: \"\"\n  slug: \"julia-cuppy\"\n- name: \"Julia Egorova\"\n  github: \"vankiru\"\n  slug: \"julia-egorova\"\n- name: \"Julia Evans\"\n  github: \"jvns\"\n  website: \"http://jvns.ca\"\n  slug: \"julia-evans\"\n- name: \"Julia Ferraioli\"\n  twitter: \"juliaferraioli\"\n  github: \"juliaferraioli\"\n  website: \"https://juliaferraioli.com\"\n  slug: \"julia-ferraioli\"\n- name: \"Julia Hurrelmann\"\n  github: \"\"\n  slug: \"julia-hurrelmann\"\n- name: \"Julia López\"\n  github: \"yukideluxe\"\n  slug: \"julia-lopez\"\n- name: \"Julian Cheal\"\n  twitter: \"juliancheal\"\n  github: \"juliancheal\"\n  website: \"https://juliancheal.co.uk\"\n  slug: \"julian-cheal\"\n- name: \"Julian Doherty\"\n  github: \"\"\n  slug: \"julian-doherty\"\n- name: \"Julian Giuca\"\n  github: \"juliangiuca\"\n  slug: \"julian-giuca\"\n- name: \"Julian Nadeau\"\n  github: \"jules2689\"\n  website: \"https://jnadeau.ca\"\n  slug: \"julian-nadeau\"\n- name: \"Julian Rubisch\"\n  twitter: \"julian_rubisch\"\n  github: \"julianrubisch\"\n  website: \"https://www.minthesize.com\"\n  slug: \"julian-rubisch\"\n- name: \"Julian Simioni\"\n  twitter: \"juliansimioni\"\n  github: \"orangejulius\"\n  website: \"https://juliansimioni.com\"\n  slug: \"julian-simioni\"\n- name: \"Julie Ann Horvath\"\n  github: \"\"\n  slug: \"julie-ann-horvath\"\n- name: \"Julie Gill\"\n  github: \"\"\n  slug: \"julie-gill\"\n- name: \"Julie J\"\n  twitter: \"codewithjulie\"\n  github: \"codewithjulie\"\n  website: \"https://codewithjulie.com\"\n  slug: \"julie-j\"\n- name: \"Julien Fitzpatrick\"\n  twitter: \"_jbfitz\"\n  github: \"julienfitz\"\n  website: \"https://dev.to/julienfitz\"\n  slug: \"julien-fitzpatrick\"\n- name: \"Julien Marseille\"\n  github: \"\"\n  slug: \"julien-marseille\"\n- name: \"Julien Perlot\"\n  github: \"\"\n  slug: \"julien-perlot\"\n- name: \"Juliette Audema\"\n  github: \"\"\n  slug: \"juliette-audema\"\n- name: \"Julik Tarkhanov\"\n  twitter: \"julikt\"\n  github: \"julik\"\n  website: \"http://blog.julik.nl\"\n  slug: \"julik-tarkhanov\"\n- name: \"Julio Agustin Lucero\"\n  github: \"\"\n  slug: \"julio-agustin-lucero\"\n- name: \"Julio Ody\"\n  github: \"\"\n  slug: \"julio-ody\"\n- name: \"Julián Pinzón Eslava\"\n  twitter: \"pinzonjulian\"\n  github: \"pinzonjulian\"\n  slug: \"julian-pinzon-eslava\"\n- name: \"Julián Pizon\"\n  github: \"\"\n  slug: \"julian-pizon\"\n- name: \"Jun Qi Tan\"\n  github: \"tjjjwxzq\"\n  slug: \"jun-qi-tan\"\n  aliases:\n    - name: \"Tan Jun Qi\"\n      slug: \"tan-jun-qi\"\n- name: \"Junichi Ito\"\n  twitter: \"jnchito\"\n  github: \"junichiito\"\n  website: \"https://blog.jnito.com\"\n  slug: \"junichi-ito\"\n- name: \"Junichi Kobayashi\"\n  twitter: \"junk0612\"\n  github: \"junk0612\"\n  slug: \"junichi-kobayashi\"\n- name: \"Junji Zhi\"\n  github: \"\"\n  slug: \"junji-zhi\"\n- name: \"Jupiter Haehn\"\n  github: \"julzerator\"\n  slug: \"jupiter-haehn\"\n- name: \"Juris Galang\"\n  github: \"\"\n  slug: \"juris-galang\"\n- name: \"Justin\"\n  github: \"\"\n  slug: \"justin\"\n- name: \"Justin Bowen\"\n  twitter: \"TonsOfFun111\"\n  github: \"tonsoffun\"\n  slug: \"justin-bowen\"\n- name: \"Justin Campbell\"\n  github: \"\"\n  slug: \"justin-campbell\"\n- name: \"Justin Collins\"\n  github: \"presidentbeef\"\n  website: \"https://presidentbeef.com\"\n  slug: \"justin-collins\"\n- name: \"Justin Daniel\"\n  github: \"justinddaniel\"\n  slug: \"justin-daniel\"\n- name: \"Justin Gehtland\"\n  github: \"\"\n  slug: \"justin-gehtland\"\n- name: \"Justin Gordon\"\n  twitter: \"railsonmaui\"\n  github: \"justin808\"\n  website: \"http://www.shakacode.com\"\n  slug: \"justin-gordon\"\n- name: \"Justin Herrick\"\n  twitter: \"jah2488\"\n  github: \"jah2488\"\n  website: \"https://justinherrick.com/\"\n  slug: \"justin-herrick\"\n- name: \"Justin Jones\"\n  twitter: \"justinhj\"\n  github: \"justinhj\"\n  website: \"https://justinhj.github.io\"\n  slug: \"justin-jones\"\n- name: \"Justin Leitgeb\"\n  github: \"jsl\"\n  website: \"https://www.stackbuilders.com/news/author/justin-leitgeb\"\n  slug: \"justin-leitgeb\"\n- name: \"Justin Love\"\n  github: \"justinlove\"\n  website: \"http://wondible.com\"\n  slug: \"justin-love\"\n- name: \"Justin Martin\"\n  github: \"\"\n  slug: \"justin-martin\"\n- name: \"Justin McNally\"\n  github: \"\"\n  slug: \"justin-mcnally\"\n- name: \"Justin Powers\"\n  github: \"dangerp\"\n  slug: \"justin-powers\"\n- name: \"Justin Searls\"\n  twitter: \"searls\"\n  github: \"searls\"\n  website: \"https://justin.searls.co\"\n  slug: \"justin-searls\"\n- name: \"Justin Tan\"\n  github: \"\"\n  slug: \"justin-tan\"\n- name: \"Justin Weiss\"\n  github: \"justinweiss\"\n  website: \"http://www.justinweiss.com\"\n  slug: \"justin-weiss\"\n- name: \"Justin Wienckowski\"\n  github: \"jwinky\"\n  slug: \"justin-wienckowski\"\n- name: \"Justine Arreche\"\n  github: \"\"\n  slug: \"justine-arreche\"\n- name: \"Justyna Wojtczak\"\n  twitter: \"justi84\"\n  github: \"justi\"\n  slug: \"justyna-wojtczak\"\n- name: \"Jérémy Lecour\"\n  github: \"\"\n  slug: \"jeremy-lecour\"\n- name: \"Jérôme Parent-Lévesque\"\n  github: \"\"\n  slug: \"jerome-parent-levesque\"\n- name: \"Jônatas Davi Paganini\"\n  twitter: \"jonatasdp\"\n  github: \"jonatas\"\n  website: \"https://ideia.me\"\n  slug: \"jonatas-davi-paganini\"\n  aliases:\n    - name: \"Jônatas Paganini\"\n      slug: \"jonatas-paganini\"\n- name: \"k0i\"\n  github: \"\"\n  slug: \"k0i\"\n- name: \"Kacper Walanus\"\n  github: \"kv109\"\n  slug: \"kacper-walanus\"\n- name: \"Kai Lemmetty\"\n  github: \"\"\n  slug: \"kai-lemmetty\"\n- name: \"kaibadash\"\n  twitter: \"kaiba\"\n  github: \"kaibadash\"\n  website: \"https://pokosho.com\"\n  slug: \"kaibadash\"\n- name: \"Kait Sewell\"\n  github: \"k8sewell\"\n  slug: \"kait-sewell\"\n- name: \"Kaitlyn Tierney\"\n  github: \"\"\n  slug: \"kaitlyn-tierney\"\n- name: \"Kaja Santro\"\n  twitter: \"alizenero\"\n  github: \"kajatiger\"\n  slug: \"kaja-santro\"\n- name: \"Kaja Witek\"\n  github: \"kajawitek\"\n  slug: \"kaja-witek\"\n- name: \"kakudooo\"\n  github: \"\"\n  slug: \"kakudooo\"\n- name: \"Kakutani Shintaro\"\n  github: \"kakutani\"\n  slug: \"kakutani-shintaro\"\n  aliases:\n    - name: \"Shintaro Kakutani\"\n      slug: \"shintaro-kakutani\"\n- name: \"Kamil Nicieja\"\n  twitter: \"kamil\"\n  github: \"nicieja\"\n  website: \"https://nicieja.co\"\n  slug: \"kamil-nicieja\"\n- name: \"Kane Baccigalupi\"\n  github: \"baccigalupi\"\n  slug: \"kane-baccigalupi\"\n- name: \"Kane Hooper\"\n  github: \"\"\n  slug: \"kane-hooper\"\n- name: \"Kanesaki Masanori\"\n  github: \"knsmr\"\n  slug: \"kanesaki-masanori\"\n- name: \"Kansai.rb Organizers\"\n  github: \"\"\n  slug: \"kansai-rb-organizers\"\n- name: \"Kara Bernert\"\n  github: \"beavz\"\n  slug: \"kara-bernert\"\n- name: \"Karan MV\"\n  github: \"\"\n  slug: \"karan-mv\"\n  aliases:\n    - name: \"MV Karan\"\n      slug: \"mv-karan\"\n- name: \"Karen G Lloyd\"\n  github: \"\"\n  slug: \"karen-g-lloyd\"\n- name: \"Karen Jex\"\n  github: \"karenjex\"\n  slug: \"karen-jex\"\n- name: \"Kari Silva\"\n  github: \"karibeari\"\n  slug: \"kari-silva\"\n- name: \"Karim Butt\"\n  github: \"\"\n  slug: \"karim-butt\"\n- name: \"Kariuki Gathitu\"\n  github: \"\"\n  slug: \"kariuki-gathitu\"\n- name: \"Karl Entwistle\"\n  github: \"karlentwistle\"\n  website: \"http://twitter.com/karlentwistle\"\n  slug: \"karl-entwistle\"\n- name: \"Karl Lingiah\"\n  github: \"\"\n  slug: \"karl-lingiah\"\n- name: \"Karl Weber\"\n  twitter: \"kowfm\"\n  github: \"karloscarweber\"\n  website: \"https://kow.fm\"\n  slug: \"karl-weber\"\n- name: \"karmajunkie\"\n  github: \"\"\n  slug: \"karmajunkie\"\n- name: \"Karol Szuster\"\n  github: \"kshalot\"\n  slug: \"karol-szuster\"\n- name: \"Karynn Ikeda\"\n  github: \"ktikeda\"\n  website: \"https://www.linkedin.com/in/ktikeda/\"\n  slug: \"karynn-ikeda\"\n- name: \"Kashyap\"\n  github: \"\"\n  slug: \"kashyap\"\n- name: \"Kasper Timm Hansen\"\n  twitter: \"kaspth\"\n  github: \"kaspth\"\n  website: \"https://kaspth.omg.lol\"\n  slug: \"kasper-timm-hansen\"\n- name: \"Kasumi Hanazuki\"\n  github: \"\"\n  slug: \"kasumi-hanazuki\"\n- name: \"Kat Drobnjakovic\"\n  github: \"katdrobnjakovic\"\n  website: \"http://katarina.rocks\"\n  slug: \"kat-drobnjakovic\"\n- name: \"katakyo\"\n  github: \"\"\n  slug: \"katakyo\"\n- name: \"Katarina Rossi\"\n  github: \"dischorde\"\n  slug: \"katarina-rossi\"\n- name: \"Katarzyna Turbiasz-Bugała\"\n  github: \"\"\n  slug: \"katarzyna-turbiasz-bugala\"\n- name: \"Kate Deutscher\"\n  github: \"\"\n  slug: \"kate-deutscher\"\n- name: \"Kate Harlan\"\n  github: \"\"\n  slug: \"kate-harlan\"\n- name: \"Kate Heddleston\"\n  github: \"\"\n  slug: \"kate-heddleston\"\n- name: \"Kate Rezentes\"\n  github: \"katerezentes\"\n  slug: \"kate-rezentes\"\n- name: \"Katelyn Hertel\"\n  twitter: \"katers_potaters\"\n  github: \"katerspotaters\"\n  slug: \"katelyn-hertel\"\n- name: \"Katherine McClintic\"\n  github: \"\"\n  slug: \"katherine-mcclintic\"\n- name: \"Katherine Wu\"\n  github: \"kwugirl\"\n  slug: \"katherine-wu\"\n- name: \"Kathryn Exline\"\n  github: \"\"\n  slug: \"kathryn-exline\"\n- name: \"Katie McLaughlin\"\n  github: \"\"\n  slug: \"katie-mclaughlin\"\n- name: \"Katie Miller\"\n  twitter: \"phedinkus\"\n  github: \"phedinkus\"\n  website: \"https://phedink.us\"\n  slug: \"katie-miller\"\n- name: \"Katie Walsh\"\n  github: \"kwals\"\n  slug: \"katie-walsh\"\n- name: \"Katlyn Parvin\"\n  github: \"\"\n  slug: \"katlyn-parvin\"\n- name: \"Katrina Owen\"\n  github: \"kytrinyx\"\n  slug: \"katrina-owen\"\n- name: \"Katrina Owens\"\n  github: \"\"\n  slug: \"katrina-owens\"\n- name: \"Katsuhiko Kageyama\"\n  github: \"kishima\"\n  website: \"http://silentworlds.info/\"\n  slug: \"katsuhiko-kageyama\"\n  aliases:\n    - name: \"kishima\"\n      slug: \"kishima\"\n- name: \"katsyoshi\"\n  github: \"\"\n  slug: \"katsyoshi\"\n- name: \"Katya Dreyer Oren\"\n  github: \"kdreyeroren\"\n  slug: \"katya-dreyer-oren\"\n- name: \"Katya Essina\"\n  github: \"\"\n  slug: \"katya-essina\"\n- name: \"Katya Sarmiento\"\n  github: \"kitkatnik\"\n  website: \"https://katyasarmiento.com\"\n  slug: \"katya-sarmiento\"\n- name: \"Kay Rhodes\"\n  github: \"\"\n  slug: \"kay-rhodes\"\n- name: \"Kay Sawada\"\n  github: \"\"\n  slug: \"kay-sawada\"\n- name: \"Kayla Reopelle\"\n  github: \"kreopelle\"\n  website: \"https://www.linkedin.com/in/kaylareopelle/\"\n  slug: \"kayla-reopelle\"\n- name: \"Kaylah Rose Mitchell\"\n  github: \"\"\n  slug: \"kaylah-rose-mitchell\"\n- name: \"Kazuaki Tanaka\"\n  github: \"kaz0505\"\n  slug: \"kazuaki-tanaka\"\n- name: \"Kazuhiko Yamashita\"\n  github: \"pyama86\"\n  website: \"http://ten-snapon.com\"\n  slug: \"kazuhiko-yamashita\"\n- name: \"Kazuhiro NISHIYAMA\"\n  twitter: \"znz\"\n  github: \"znz\"\n  website: \"https://www.n-z.jp/me.html\"\n  slug: \"kazuhiro-nishiyama\"\n- name: \"Kazuhiro Sera\"\n  github: \"\"\n  slug: \"kazuhiro-sera\"\n- name: \"Kazuhito Hokamura\"\n  github: \"\"\n  slug: \"kazuhito-hokamura\"\n- name: \"Kazuho Oku\"\n  github: \"kazuho\"\n  website: \"http://blog.kazuhooku.com/\"\n  slug: \"kazuho-oku\"\n- name: \"Kazuki Tsujimoto\"\n  twitter: \"k_tsj\"\n  github: \"k-tsj\"\n  slug: \"kazuki-tsujimoto\"\n- name: \"Kazuma Furuhashi\"\n  github: \"284km\"\n  slug: \"kazuma-furuhashi\"\n- name: \"Kazuma Murata\"\n  github: \"kazzix14\"\n  slug: \"kazuma-murata\"\n- name: \"Kazumi Karbowski\"\n  github: \"kaziski\"\n  website: \"https://codingmamakaz.github.io/\"\n  slug: \"kazumi-karbowski\"\n- name: \"Kazuyoshi Fukuda\"\n  github: \"\"\n  slug: \"kazuyoshi-fukuda\"\n- name: \"Keavy McMinn\"\n  github: \"keavy\"\n  website: \"https://keavy.com\"\n  slug: \"keavy-mcminn\"\n- name: \"Kei Inoue\"\n  github: \"inosnake\"\n  slug: \"kei-inoue\"\n- name: \"Kei Nawanda\"\n  github: \"\"\n  slug: \"kei-nawanda\"\n- name: \"Kei Sawada\"\n  twitter: \"remore\"\n  github: \"remore\"\n  slug: \"kei-sawada\"\n- name: \"Kei Shiratsuchi\"\n  github: \"\"\n  slug: \"kei-shiratsuchi\"\n- name: \"Keiju Ishitsuka\"\n  github: \"keiju\"\n  slug: \"keiju-ishitsuka\"\n- name: \"Keiko Kaneko\"\n  github: \"\"\n  slug: \"keiko-kaneko\"\n- name: \"Keita Sugiyama\"\n  github: \"\"\n  slug: \"keita-sugiyama\"\n- name: \"Keita Urashima\"\n  github: \"\"\n  slug: \"keita-urashima\"\n- name: \"Keith Bennett\"\n  twitter: \"keithrbennett\"\n  github: \"keithrbennett\"\n  website: \"http://www.bbs-software.com\"\n  slug: \"keith-bennett\"\n- name: \"Keith Gable\"\n  twitter: \"ZiggyTheHamster\"\n  github: \"ziggythehamster\"\n  website: \"https://ziggythehamster.sh/\"\n  slug: \"keith-gable\"\n- name: \"Keith Gaddis\"\n  github: \"karmajunkie\"\n  website: \"https://atx.pub/@kbg\"\n  slug: \"keith-gaddis\"\n- name: \"Keith Harper\"\n  github: \"\"\n  slug: \"keith-harper\"\n- name: \"Keith Pitt\"\n  twitter: \"keithpitt\"\n  github: \"keithpitt\"\n  website: \"http://keithpitt.com\"\n  slug: \"keith-pitt\"\n- name: \"Keith Pitty\"\n  github: \"\"\n  slug: \"keith-pitty\"\n- name: \"Keith Schacht\"\n  twitter: \"keithschacht\"\n  github: \"krschacht\"\n  website: \"https://keithschacht.com\"\n  slug: \"keith-schacht\"\n- name: \"Kelly Popko\"\n  github: \"kellyky\"\n  slug: \"kelly-popko\"\n- name: \"Kelly Ryan\"\n  twitter: \"rfkelly\"\n  github: \"rfk\"\n  website: \"http://www.rfk.id.au/\"\n  slug: \"kelly-ryan\"\n- name: \"Kelly Sutton\"\n  twitter: \"kellysutton\"\n  github: \"kellysutton\"\n  website: \"https://kellysutton.com\"\n  slug: \"kelly-sutton\"\n- name: \"Kelsey Pedersen\"\n  github: \"kelseypedersen\"\n  slug: \"kelsey-pedersen\"\n- name: \"Kelsey Pederson\"\n  github: \"\"\n  slug: \"kelsey-pederson\"\n- name: \"Ken Auer\"\n  github: \"\"\n  slug: \"ken-auer\"\n- name: \"Ken Decanio\"\n  github: \"justthisguy\"\n  website: \"https://41monkeys.com\"\n  slug: \"ken-decanio\"\n- name: \"Ken Maeshima\"\n  github: \"mononoken\"\n  slug: \"ken-maeshima\"\n- name: \"Ken Muryoi\"\n  github: \"\"\n  slug: \"ken-muryoi\"\n- name: \"Ken Nishimura\"\n  github: \"\"\n  slug: \"ken-nishimura\"\n- name: \"Ken Scrambler\"\n  github: \"\"\n  slug: \"ken-scrambler\"\n- name: \"Kengo Hamasaki\"\n  github: \"\"\n  slug: \"kengo-hamasaki\"\n- name: \"Kenichi Kanai\"\n  github: \"kenichikanai\"\n  slug: \"kenichi-kanai\"\n- name: \"Kenji Mori\"\n  github: \"\"\n  slug: \"kenji-mori\"\n- name: \"Kenji Sugihara\"\n  github: \"\"\n  slug: \"kenji-sugihara\"\n- name: \"Kenny Browne\"\n  github: \"\"\n  slug: \"kenny-browne\"\n- name: \"Kenny Hoxworth\"\n  github: \"hoxworth\"\n  website: \"http://starkiller.net\"\n  slug: \"kenny-hoxworth\"\n- name: \"Kenshi Shiode\"\n  github: \"\"\n  slug: \"kenshi-shiode\"\n- name: \"Kensuke Nagae\"\n  github: \"\"\n  slug: \"kensuke-nagae\"\n- name: \"Kent Beck\"\n  twitter: \"KentBeck\"\n  github: \"kentbeck\"\n  website: \"https://www.kentbeck.com\"\n  slug: \"kent-beck\"\n- name: \"Kenta Murata\"\n  twitter: \"KentaMurata\"\n  github: \"mrkn\"\n  website: \"http://mrkn.jp\"\n  slug: \"kenta-murata\"\n- name: \"Kentaro Goto\"\n  github: \"gotoken\"\n  slug: \"kentaro-goto\"\n- name: \"Kentaro Kuribayashi\"\n  github: \"\"\n  slug: \"kentaro-kuribayashi\"\n- name: \"Kerri Miller\"\n  github: \"kerrizor\"\n  website: \"http://kerrizor.com\"\n  slug: \"kerri-miller\"\n- name: \"Kerstin Puschke\"\n  github: \"titanoboa\"\n  slug: \"kerstin-puschke\"\n- name: \"Keshav Biswa\"\n  twitter: \"keshavbiswa21\"\n  github: \"keshavbiswa\"\n  website: \"https://keshavbiswa.com\"\n  slug: \"keshav-biswa\"\n- name: \"Kevin Burke\"\n  twitter: \"derivativeburke\"\n  github: \"kevinburke\"\n  website: \"https://kevin.burke.dev\"\n  slug: \"kevin-burke\"\n- name: \"Kevin Fallon\"\n  github: \"kgf\"\n  slug: \"kevin-fallon\"\n- name: \"Kevin Gilpin\"\n  github: \"kgilpin\"\n  website: \"https://appland.com\"\n  slug: \"kevin-gilpin\"\n- name: \"Kevin Gisi\"\n  github: \"\"\n  slug: \"kevin-gisi\"\n- name: \"Kevin Gorham\"\n  github: \"gmale\"\n  website: \"http://developerbits.blogspot.com\"\n  slug: \"kevin-gorham\"\n- name: \"Kevin Hurley\"\n  github: \"\"\n  slug: \"kevin-hurley\"\n- name: \"Kevin Kuchta\"\n  twitter: \"kkuchta\"\n  github: \"kkuchta\"\n  website: \"http://kevinkuchta.com\"\n  slug: \"kevin-kuchta\"\n- name: \"Kevin Lesht\"\n  github: \"klesht\"\n  website: \"http://kevinlesht.com\"\n  slug: \"kevin-lesht\"\n- name: \"Kevin Liebholz\"\n  twitter: \"kevinliebholz\"\n  github: \"kevkev300\"\n  website: \"https://kevin-liebholz.me\"\n  slug: \"kevin-liebholz\"\n- name: \"Kevin Litchfield\"\n  github: \"\"\n  slug: \"kevin-litchfield\"\n- name: \"Kevin McConnell\"\n  github: \"kevinmcconnell\"\n  slug: \"kevin-mcconnell\"\n- name: \"Kevin Menard\"\n  twitter: \"nirvdrum\"\n  github: \"nirvdrum\"\n  website: \"https://nirvdrum.com/\"\n  slug: \"kevin-menard\"\n- name: \"Kevin Miller\"\n  github: \"kevee\"\n  website: \"https://kevee.net\"\n  slug: \"kevin-miller\"\n- name: \"Kevin Murphy\"\n  twitter: \"kevin_j_m\"\n  github: \"kevin-j-m\"\n  website: \"https://kevinjmurphy.com/\"\n  slug: \"kevin-murphy\"\n- name: \"Kevin Newton\"\n  twitter: \"kddnewton\"\n  github: \"kddnewton\"\n  website: \"https://kddnewton.com\"\n  slug: \"kevin-newton\"\n  aliases:\n    - name: \"Kevin Deisz\"\n      slug: \"kevin-deisz\"\n- name: \"Kevin Sedgley\"\n  github: \"\"\n  slug: \"kevin-sedgley\"\n- name: \"Kevin Sherus\"\n  github: \"\"\n  slug: \"kevin-sherus\"\n- name: \"Kevin Stevens\"\n  twitter: \"kevdog\"\n  github: \"kevdog\"\n  slug: \"kevin-stevens\"\n- name: \"Kevin Tew\"\n  github: \"tewk\"\n  slug: \"kevin-tew\"\n- name: \"Kevin Triplett\"\n  twitter: \"kevintriplett\"\n  github: \"KevinTriplett\"\n  website: \"https://www.kevintriplett.com/\"\n  slug: \"kevin-triplett\"\n- name: \"Kevin Vanzandberghe\"\n  github: \"\"\n  slug: \"kevin-vanzandberghe\"\n- name: \"Kevin Whinnery\"\n  twitter: \"kevinwhinnery\"\n  github: \"kwhinnery\"\n  slug: \"kevin-whinnery\"\n- name: \"Kevin Yank\"\n  github: \"sentience\"\n  website: \"http://www.kevinyank.com/\"\n  slug: \"kevin-yank\"\n- name: \"Khash Sajadi\"\n  github: \"khash\"\n  website: \"http://www.cloud66.com\"\n  slug: \"khash-sajadi\"\n- name: \"Kieran Andrews\"\n  github: \"\"\n  slug: \"kieran-andrews\"\n- name: \"Kieran Klaassen\"\n  twitter: \"kieranklaassen\"\n  github: \"kieranklaassen\"\n  slug: \"kieran-klaassen\"\n- name: \"Kim Ahlström\"\n  github: \"\"\n  slug: \"kim-ahlstroem\"\n- name: \"Kim Barnes\"\n  github: \"\"\n  slug: \"kim-barnes\"\n- name: \"Kim Burgestrand\"\n  github: \"Burgestrand\"\n  slug: \"kim-burgestrand\"\n- name: \"Kim Diep\"\n  github: \"\"\n  slug: \"kim-diep\"\n- name: \"Kim Lambright\"\n  github: \"\"\n  slug: \"kim-lambright\"\n- name: \"Kimberly D. Barnes\"\n  github: \"\"\n  slug: \"kimberly-d-barnes\"\n- name: \"Kinga Kalinowska\"\n  github: \"\"\n  slug: \"kinga-kalinowska\"\n- name: \"kinoppyd\"\n  twitter: \"GhostBrain\"\n  github: \"kinoppyd\"\n  website: \"https://kinoppyd.dev\"\n  slug: \"kinoppyd\"\n- name: \"Kinsey Durham Grace\"\n  twitter: \"KinseyAnnDurham\"\n  github: \"kinseydurhamgrace\"\n  website: \"https://www.kinseyanndurham.com\"\n  slug: \"kinsey-durham-grace\"\n  aliases:\n    - name: \"Kinsey Durham\"\n      slug: \"kinsey-durham\"\n    - name: \"Kinsey Ann Durham\"\n      slug: \"kinsey-ann-durham\"\n- name: \"Kir Shatrov\"\n  github: \"kirs\"\n  website: \"http://kirshatrov.com\"\n  slug: \"kir-shatrov\"\n- name: \"Kiran Narasareddy\"\n  slug: \"kiran-narasareddy\"\n  github: \"kcore\"\n- name: \"Kirill Gorin\"\n  github: \"\"\n  slug: \"kirill-gorin\"\n- name: \"Kirill Kaiumov\"\n  github: \"\"\n  slug: \"kirill-kaiumov\"\n- name: \"Kirill Platonov\"\n  github: \"\"\n  slug: \"kirill-platonov\"\n- name: \"Kirk Haines\"\n  twitter: \"wyhaines\"\n  github: \"wyhaines\"\n  slug: \"kirk-haines\"\n- name: \"kiryuanzu\"\n  github: \"\"\n  slug: \"kiryuanzu\"\n- name: \"Kiwamu Kato\"\n  github: \"\"\n  slug: \"kiwamu-kato\"\n- name: \"Kiyoto Tamura\"\n  github: \"kiyoto\"\n  slug: \"kiyoto-tamura\"\n- name: \"KJ Tsanaktsidis\"\n  twitter: \"KJTsanaktidis\"\n  github: \"kjtsanaktsidis\"\n  slug: \"kj-tsanaktsidis\"\n- name: \"Klaas Jan Wierenga\"\n  github: \"\"\n  slug: \"klaas-jan-wierenga\"\n- name: \"Klaus Weidinger\"\n  github: \"dunkelziffer\"\n  slug: \"klaus-weidinger\"\n- name: \"KNR\"\n  github: \"\"\n  slug: \"knr\"\n- name: \"Kobe Rehnquist\"\n  github: \"\"\n  slug: \"kobe-rehnquist\"\n- name: \"Kodai Kinjo\"\n  github: \"aokabin\"\n  slug: \"kodai-kinjo\"\n- name: \"Kody C. Kendall\"\n  github: \"\"\n  slug: \"kody-c-kendall\"\n- name: \"Kody Kendall\"\n  github: \"KodyKendall\"\n  slug: \"kody-kendall\"\n- name: \"Kohei Suzuki\"\n  github: \"eagletmt\"\n  website: \"https://wanko.cc/\"\n  slug: \"kohei-suzuki\"\n- name: \"Kohei Yamada\"\n  twitter: \"nukumaro22\"\n  github: \"iberianpig\"\n  slug: \"kohei-yamada\"\n- name: \"Koichi ITO\"\n  twitter: \"koic\"\n  github: \"koic\"\n  website: \"https://koic.github.io\"\n  slug: \"koichi-ito\"\n- name: \"Koichi Sasada\"\n  twitter: \"_ko1\"\n  github: \"ko1\"\n  website: \"http://www.atdot.net/~ko1/\"\n  slug: \"koichi-sasada\"\n- name: \"Koichiro Eto\"\n  twitter: \"eto\"\n  github: \"eto\"\n  website: \"http://eto.com/\"\n  slug: \"koichiro-eto\"\n- name: \"Koji NAKAMURA\"\n  github: \"kozy4324\"\n  slug: \"koji-nakamura\"\n- name: \"Koji Shimada\"\n  github: \"snoozer05\"\n  website: \"https://www.enishi-tech.com/\"\n  slug: \"koji-shimada\"\n- name: \"Koji Shimba\"\n  github: \"\"\n  slug: \"koji-shimba\"\n- name: \"kokuyou\"\n  github: \"\"\n  slug: \"kokuyou\"\n- name: \"kokuyouwind\"\n  github: \"\"\n  slug: \"kokuyouwind\"\n- name: \"Kondo Uchio\"\n  twitter: \"udzura\"\n  github: \"udzura\"\n  website: \"https://github.com/udzura/slides\"\n  slug: \"kondo-uchio\"\n  aliases:\n    - name: \"Uchio KONDO\"\n      slug: \"uchio-kondo\"\n- name: \"Konstantin Gredeskoul\"\n  twitter: \"kig\"\n  github: \"kigster\"\n  website: \"https://kig.re/\"\n  slug: \"konstantin-gredeskoul\"\n- name: \"Konstantin Haase\"\n  twitter: \"konstantinhaase\"\n  github: \"rkh\"\n  slug: \"konstantin-haase\"\n- name: \"Konstantin Hasse\"\n  github: \"\"\n  slug: \"konstantin-hasse\"\n- name: \"Konstantin Tennhard\"\n  github: \"\"\n  slug: \"konstantin-tennhard\"\n- name: \"KOSAKI Motohiro\"\n  github: \"kosaki\"\n  slug: \"kosaki-motohiro\"\n- name: \"Kota Kusama\"\n  github: \"cc-kusama\"\n  slug: \"kota-kusama\"\n- name: \"Kota Weaver\"\n  github: \"kotaweav\"\n  slug: \"kota-weaver\"\n- name: \"Kouhei Sutou\"\n  github: \"kou\"\n  website: \"https://www.clear-code.com/\"\n  slug: \"kouhei-sutou\"\n  aliases:\n    - name: \"Sutou Kouhei\"\n      slug: \"sutou-kouhei\"\n- name: \"Kouji Takao\"\n  twitter: \"takaokouji\"\n  github: \"takaokouji\"\n  slug: \"kouji-takao\"\n- name: \"Kouta Kariyado\"\n  github: \"\"\n  slug: \"kouta-kariyado\"\n- name: \"Kowsik Guruswamy\"\n  github: \"\"\n  slug: \"kowsik-guruswamy\"\n- name: \"Koya Masuda\"\n  github: \"\"\n  slug: \"koya-masuda\"\n- name: \"Kozo Nishida\"\n  twitter: \"kozo2\"\n  github: \"kozo2\"\n  slug: \"kozo-nishida\"\n- name: \"Kriselda Rabino\"\n  github: \"\"\n  slug: \"kriselda-rabino\"\n- name: \"Krista Nelson\"\n  github: \"nelsonka\"\n  slug: \"krista-nelson\"\n- name: \"Kristen Ruben\"\n  github: \"\"\n  slug: \"kristen-ruben\"\n- name: \"Kristine Joy Paas\"\n  github: \"\"\n  slug: \"kristine-joy-paas\"\n- name: \"Kristine McBride\"\n  github: \"\"\n  slug: \"kristine-mcbride\"\n- name: \"Krystan\"\n  twitter: \"krystanhonour\"\n  github: \"krystan\"\n  website: \"http://www.krystanhonour.com\"\n  slug: \"krystan\"\n- name: \"Krystan HuffMenne\"\n  github: \"gitkrystan\"\n  slug: \"krystan-huffmenne\"\n- name: \"Krzysztof (Christopher) Wawer\"\n  github: \"\"\n  slug: \"krzysztof-christopher-wawer\"\n- name: \"Krzysztof Kowalik\"\n  github: \"nu7hatch\"\n  slug: \"krzysztof-kowalik\"\n- name: \"Krzysztof Kowalik y Pablo Astigarraga\"\n  github: \"\"\n  slug: \"krzysztof-kowalik-y-pablo-astigarraga\"\n- name: \"Krzysztof Wawer\"\n  github: \"\"\n  slug: \"krzysztof-wawer\"\n- name: \"Kuba Kuzma\"\n  github: \"\"\n  slug: \"kuba-kuzma\"\n- name: \"Kuba Suder\"\n  github: \"mackuba\"\n  slug: \"kuba-suder\"\n- name: \"Kubo Ayumu\"\n  github: \"\"\n  slug: \"kubo-ayumu\"\n- name: \"Kumari Surya\"\n  github: \"\"\n  slug: \"kumari-surya\"\n- name: \"Kuniaki Igarashi\"\n  twitter: \"igaiga555\"\n  github: \"igaiga\"\n  website: \"https://igarashikuniaki.net/diary/\"\n  slug: \"kuniaki-igarashi\"\n- name: \"Kunihiko Ito\"\n  github: \"kunitoo\"\n  slug: \"kunihiko-ito\"\n- name: \"Kyle Banker\"\n  github: \"\"\n  slug: \"kyle-banker\"\n- name: \"Kyle d'Oliveira\"\n  github: \"doliveirakn\"\n  slug: \"kyle-d-oliveira\"\n- name: \"Kyle Dolezal\"\n  github: \"KyleDolezal\"\n  slug: \"kyle-dolezal\"\n- name: \"Kyle Heironimus\"\n  github: \"heironimus\"\n  slug: \"kyle-heironimus\"\n- name: \"Kyle Maxwell\"\n  github: \"\"\n  slug: \"kyle-maxwell\"\n- name: \"Kyle Neath\"\n  github: \"\"\n  slug: \"kyle-neath\"\n- name: \"Kyle Rames\"\n  github: \"\"\n  slug: \"kyle-rames\"\n- name: \"Kylie Stradley\"\n  github: \"kyfast\"\n  website: \"https://kyfast.net\"\n  slug: \"kylie-stradley\"\n- name: \"Lachie Cox\"\n  github: \"\"\n  slug: \"lachie-cox\"\n- name: \"Lachlan Hardy\"\n  twitter: \"lachlanhardy\"\n  github: \"lachlanhardy\"\n  website: \"http://lachstock.com.au\"\n  slug: \"lachlan-hardy\"\n- name: \"Lance Ball\"\n  twitter: \"lanceball\"\n  github: \"lance\"\n  website: \"https://lanceball.dev\"\n  slug: \"lance-ball\"\n- name: \"Lance Carlson\"\n  github: \"\"\n  slug: \"lance-carlson\"\n- name: \"Lance Gleason\"\n  github: \"\"\n  slug: \"lance-gleason\"\n- name: \"Lance Ivy\"\n  github: \"cainlevy\"\n  website: \"http://cainlevy.net/\"\n  slug: \"lance-ivy\"\n- name: \"Landon Gray\"\n  twitter: \"thedayisntgray\"\n  github: \"thedayisntgray\"\n  website: \"https://thedayisntgray.github.io\"\n  slug: \"landon-gray\"\n- name: \"Lang Sharpe\"\n  github: \"\"\n  slug: \"lang-sharpe\"\n- name: \"LaNice Powell\"\n  github: \"\"\n  slug: \"lanice-powell\"\n- name: \"Larry Diehl\"\n  github: \"\"\n  slug: \"larry-diehl\"\n- name: \"Lars Vonk\"\n  github: \"\"\n  slug: \"lars-vonk\"\n- name: \"Latoya Allen\"\n  github: \"lna\"\n  website: \"http://latoya-allen.com/myrecordcollection\"\n  slug: \"latoya-allen\"\n- name: \"Laura Eck\"\n  twitter: \"laura_nobilis\"\n  github: \"morred\"\n  slug: \"laura-eck\"\n- name: \"Laura Gaetano\"\n  github: \"\"\n  slug: \"laura-gaetano\"\n- name: \"Laura Linda Laugwitz\"\n  github: \"\"\n  slug: \"laura-linda-laugwitz\"\n- name: \"Laura Maguire\"\n  github: \"mopie27\"\n  slug: \"laura-maguire\"\n- name: \"Laura Mosher\"\n  github: \"lauramosher\"\n  website: \"https://lauramosher.com\"\n  slug: \"laura-mosher\"\n- name: \"Laura Peralta\"\n  github: \"\"\n  slug: \"laura-peralta\"\n- name: \"Laura Tacho\"\n  twitter: \"rhein_wein\"\n  github: \"rheinwein\"\n  website: \"https://lauratacho.com\"\n  slug: \"laura-tacho\"\n  aliases:\n    - name: \"Laura Frank\"\n      slug: \"laura-frank\"\n- name: \"Lauren Auchter\"\n  twitter: \"LaurenAuchter\"\n  github: \"lsauchter\"\n  website: \"https://laurenauchter.now.sh\"\n  slug: \"lauren-auchter\"\n- name: \"Lauren Billington\"\n  github: \"blaurenb\"\n  slug: \"lauren-billington\"\n- name: \"Lauren Ellsworth\"\n  github: \"fh-lellsworth\"\n  slug: \"lauren-ellsworth\"\n- name: \"Lauren Hennessy\"\n  github: \"\"\n  slug: \"lauren-hennessy\"\n- name: \"Lauren Scott\"\n  github: \"devdame\"\n  slug: \"lauren-scott\"\n- name: \"Lauren Tan\"\n  github: \"\"\n  slug: \"lauren-tan\"\n- name: \"Lauren Voswinkel\"\n  github: \"valarissa\"\n  slug: \"lauren-voswinkel\"\n- name: \"Laurent Buffevant\"\n  github: \"\"\n  slug: \"laurent-buffevant\"\n- name: \"Laurent Sansonetti\"\n  github: \"lrz\"\n  website: \"https://hipbyte.com/~lrz\"\n  slug: \"laurent-sansonetti\"\n- name: \"Lauri Jutila\"\n  twitter: \"ljuti\"\n  github: \"ljuti\"\n  website: \"http://laurijutila.com\"\n  slug: \"lauri-jutila\"\n- name: \"Laurie Young\"\n  github: \"\"\n  slug: \"laurie-young\"\n- name: \"Layne McNish\"\n  twitter: \"laynemcnish\"\n  github: \"laynemcnish\"\n  slug: \"layne-mcnish\"\n- name: \"Lázaro Nixon\"\n  github: \"\"\n  slug: \"lazaro-nixon\"\n- name: \"Leah Sexton\"\n  github: \"\"\n  slug: \"leah-sexton\"\n- name: \"Leah Silber\"\n  twitter: \"wifelette\"\n  github: \"wifelette\"\n  slug: \"leah-silber\"\n- name: \"Lee Edwards\"\n  twitter: \"terronk\"\n  github: \"ledwards\"\n  website: \"http://root.vc\"\n  slug: \"lee-edwards\"\n- name: \"Lee McAlilly\"\n  twitter: \"leemcalilly\"\n  github: \"leemcalilly\"\n  website: \"https://mcalilly.com\"\n  slug: \"lee-mcalilly\"\n- name: \"Lee Richmond\"\n  twitter: \"richmolj\"\n  github: \"richmolj\"\n  website: \"https://www.graphiti.dev\"\n  slug: \"lee-richmond\"\n- name: \"Leena Gupte\"\n  github: \"\"\n  slug: \"leena-gupte\"\n- name: \"Leena S N\"\n  github: \"\"\n  slug: \"leena-s-n\"\n- name: \"Lei Guo\"\n  github: \"\"\n  slug: \"lei-guo\"\n- name: \"Lein Weber\"\n  github: \"\"\n  slug: \"lein-weber\"\n- name: \"Lena Plaksina\"\n  github: \"\"\n  slug: \"lena-plaksina\"\n- name: \"Lena Wiberg\"\n  twitter: \"LenaPejgan\"\n  github: \"lenapejgan\"\n  website: \"https://pejgan.se\"\n  slug: \"lena-wiberg\"\n- name: \"Leon Gersing\"\n  github: \"leongersing\"\n  slug: \"leon-gersing\"\n- name: \"Leon Hu\"\n  github: \"gdhucoder\"\n  website: \"https://gdhucoder.github.io/\"\n  slug: \"leon-hu\"\n- name: \"Leonard Chin\"\n  twitter: \"lchin\"\n  github: \"l15n\"\n  slug: \"leonard-chin\"\n  aliases:\n    - name: \"Lori Chin\"\n      slug: \"lori-chin\"\n- name: \"Leonard Garvey\"\n  github: \"\"\n  slug: \"leonard-garvey\"\n- name: \"Leonardo Tegon\"\n  github: \"tegon\"\n  slug: \"leonardo-tegon\"\n- name: \"Les Hill\"\n  github: \"\"\n  slug: \"les-hill\"\n- name: \"Leslie Hawthorn\"\n  twitter: \"lhawthorn\"\n  github: \"lhawthorn\"\n  slug: \"leslie-hawthorn\"\n- name: \"Leti Esperón\"\n  twitter: \"letiesperon\"\n  github: \"letiesperon\"\n  website: \"https://www.linkedin.com/in/leticia-esperon/\"\n  slug: \"leti-esperon\"\n- name: \"Levi Vaguez\"\n  github: \"\"\n  slug: \"levi-vaguez\"\n- name: \"Lew Parker\"\n  github: \"parkerl\"\n  slug: \"lew-parker\"\n- name: \"Lewis Buckley\"\n  twitter: \"lewispb\"\n  github: \"lewispb\"\n  website: \"http://www.lewisbuckley.co.uk\"\n  slug: \"lewis-buckley\"\n- name: \"Liam McNally\"\n  github: \"\"\n  slug: \"liam-mcnally\"\n- name: \"Liana Leahy\"\n  github: \"liana\"\n  website: \"http://liana.org\"\n  slug: \"liana-leahy\"\n- name: \"Lillie Chilen\"\n  github: \"\"\n  slug: \"lillie-chilen\"\n- name: \"Lily Stoney\"\n  github: \"\"\n  slug: \"lily-stoney\"\n- name: \"Lin Yu Hsiang\"\n  github: \"shawn1380\"\n  slug: \"lin-yu-hsiang\"\n- name: \"Lincoln Stoll\"\n  github: \"\"\n  slug: \"lincoln-stoll\"\n- name: \"Linda Liukas\"\n  github: \"\"\n  slug: \"linda-liukas\"\n- name: \"Linda Sandvik\"\n  github: \"\"\n  slug: \"linda-sandvik\"\n- name: \"Lindsay Holmwood\"\n  github: \"\"\n  slug: \"lindsay-holmwood\"\n- name: \"Lindsay Kelly\"\n  github: \"lindsaymkelly\"\n  website: \"https://www.linkedin.com/in/lindsay-kelly-438614124\"\n  slug: \"lindsay-kelly\"\n- name: \"Lindsey Christensen\"\n  github: \"\"\n  slug: \"lindsey-christensen\"\n- name: \"Lional Barrow\"\n  github: \"\"\n  slug: \"lional-barrow\"\n- name: \"Lionel Barrow\"\n  github: \"lionelbarrow\"\n  website: \"https://www.lionelbarrow.com\"\n  slug: \"lionel-barrow\"\n- name: \"Lisa Karlin Curtis\"\n  twitter: \"paprikati_eng\"\n  github: \"paprikati\"\n  website: \"https://paprikati.github.io\"\n  slug: \"lisa-karlin-curtis\"\n- name: \"Lisa Larson-Kelley\"\n  github: \"\"\n  slug: \"lisa-larson-kelley\"\n- name: \"Lisa van Gelder\"\n  github: \"lvgelder\"\n  slug: \"lisa-van-gelder\"\n- name: \"Lito Nicolai\"\n  twitter: \"litonico_\"\n  github: \"litonico\"\n  website: \"https://tinyletter.com/learntocomputer\"\n  slug: \"lito-nicolai\"\n- name: \"Liz Abinante\"\n  github: \"slothelle\"\n  slug: \"liz-abinante\"\n  speakerdeck: \"feministy\"\n  website: \"https://www.lizabinante.com\"\n  aliases:\n    - name: \"Liz Abenante\"\n      slug: \"liz-abenante\"\n- name: \"Liz Baillie\"\n  github: \"\"\n  slug: \"liz-baillie\"\n- name: \"Liz Certa\"\n  github: \"ecerta\"\n  slug: \"liz-certa\"\n- name: \"Liz Heym\"\n  github: \"lizheym\"\n  slug: \"liz-heym\"\n- name: \"Liz Pine\"\n  github: \"\"\n  slug: \"liz-pine\"\n- name: \"Liz Rush\"\n  github: \"lizrush\"\n  slug: \"liz-rush\"\n- name: \"Lizz Jennings\"\n  github: \"\"\n  slug: \"lizz-jennings\"\n- name: \"Ljubomir Marković\"\n  github: \"ljubomirm\"\n  slug: \"ljubomir-markovic\"\n  aliases:\n    - name: \"Ljubomir Markovic\"\n      slug: \"ljubomir-markovic\"\n- name: \"lni_T\"\n  github: \"\"\n  slug: \"lni_t\"\n- name: \"lnit\"\n  github: \"\"\n  slug: \"lnit\"\n- name: \"Logan Barnett\"\n  github: \"\"\n  slug: \"logan-barnett\"\n- name: \"Loraine Kanervisto\"\n  github: \"blip-lorist\"\n  slug: \"loraine-kanervisto\"\n- name: \"Loren Crawford\"\n  github: \"loren-m-crawford\"\n  website: \"http://lorencrawford.herokuapp.com/\"\n  slug: \"loren-crawford\"\n- name: \"Loren Segal\"\n  twitter: \"lsegal\"\n  github: \"lsegal\"\n  website: \"http://makelayers.com\"\n  slug: \"loren-segal\"\n- name: \"Lorenzo Barasti\"\n  github: \"\"\n  slug: \"lorenzo-barasti\"\n- name: \"Lori M Olson\"\n  github: \"wndxlori\"\n  website: \"http://www.wndx.com\"\n  slug: \"lori-m-olson\"\n  aliases:\n    - name: \"Lori Olson\"\n      slug: \"lori-olson\"\n- name: \"Lorin Thwaits\"\n  github: \"lorint\"\n  slug: \"lorin-thwaits\"\n- name: \"Louis Antonopoulos\"\n  github: \"louis-antonopoulos\"\n  website: \"https://www.thoughtbot.com\"\n  slug: \"louis-antonopoulos\"\n- name: \"Louis Simoneau\"\n  github: \"\"\n  slug: \"louis-simoneau\"\n- name: \"Louisa Barrett\"\n  github: \"louisabarrett\"\n  slug: \"louisa-barrett\"\n- name: \"Lourens Naudé\"\n  github: \"\"\n  slug: \"lourens-naude\"\n- name: \"Luc Castera\"\n  github: \"\"\n  slug: \"luc-castera\"\n- name: \"Luca Guidi\"\n  twitter: \"jodosha\"\n  github: \"jodosha\"\n  website: \"https://lucaguidi.com\"\n  slug: \"luca-guidi\"\n- name: \"Luca Mearelli\"\n  github: \"\"\n  slug: \"luca-mearelli\"\n- name: \"Lucas Allan\"\n  github: \"\"\n  slug: \"lucas-allan\"\n- name: \"Lucas Dohmen\"\n  github: \"moonglum\"\n  website: \"https://lucas.dohmen.io\"\n  slug: \"lucas-dohmen\"\n- name: \"Lucas Fittl\"\n  github: \"\"\n  slug: \"lucas-fittl\"\n- name: \"Lucas Florio\"\n  github: \"\"\n  slug: \"lucas-florio\"\n- name: \"Lucas Reisig\"\n  github: \"\"\n  slug: \"lucas-reisig\"\n- name: \"Lucas Tolchinsky\"\n  github: \"tonchis\"\n  slug: \"lucas-tolchinsky\"\n- name: \"Lucas Videla\"\n  github: \"\"\n  slug: \"lucas-videla\"\n- name: \"Lucian Ghindă\"\n  twitter: \"lucianghinda\"\n  github: \"lucianghinda\"\n  website: \"https://allaboutcoding.ghinda.com\"\n  slug: \"lucian-ghinda\"\n  aliases:\n    - name: \"Lucian Ghinda\"\n      slug: \"lucian-ghinda\"\n- name: \"Lucía Escanellas\"\n  github: \"\"\n  slug: \"lucia-escanellas\"\n- name: \"Lucy Chen\"\n  github: \"lucyscode\"\n  slug: \"lucy-chen\"\n- name: \"Luigi Montanez\"\n  github: \"\"\n  slug: \"luigi-montanez\"\n- name: \"Luis Ferreira\"\n  github: \"lgpinguim\"\n  slug: \"luis-ferreira\"\n- name: \"Luis Lavena\"\n  twitter: \"luislavena\"\n  github: \"luislavena\"\n  website: \"https://luislavena.info\"\n  slug: \"luis-lavena\"\n- name: \"Luismi Cavallé\"\n  github: \"\"\n  slug: \"luismi-cavalle\"\n  aliases:\n    - name: \"Luismi Cavalle\"\n      slug: \"luismi-cavalle\"\n- name: \"Luiz Carvalho\"\n  github: \"luizcarvalho\"\n  slug: \"luiz-carvalho\"\n- name: \"Lukas Bischof\"\n  github: \"lukasbischof\"\n  website: \"https://luk4s.dev\"\n  slug: \"lukas-bischof\"\n- name: \"Lukas Fittl\"\n  github: \"\"\n  slug: \"lukas-fittl\"\n- name: \"Lukas Nimmo\"\n  github: \"numbluk\"\n  slug: \"lukas-nimmo\"\n- name: \"Luke Evans\"\n  github: \"\"\n  slug: \"luke-evans\"\n- name: \"Luke Francl\"\n  twitter: \"lof\"\n  github: \"look\"\n  website: \"http://luke.francl.org\"\n  slug: \"luke-francl\"\n- name: \"Luke Gruber\"\n  github: \"luke-gruber\"\n  slug: \"luke-gruber\"\n- name: \"Luke Kanies\"\n  github: \"\"\n  slug: \"luke-kanies\"\n- name: \"Luke Melia\"\n  twitter: \"lukemelia\"\n  github: \"lukemelia\"\n  website: \"http://www.lukemelia.com/devblog\"\n  slug: \"luke-melia\"\n- name: \"Luke Miglia\"\n  github: \"\"\n  slug: \"luke-miglia\"\n- name: \"Luke Thomas\"\n  github: \"\"\n  slug: \"luke-thomas\"\n- name: \"lulalala\"\n  twitter: \"lulalala_it\"\n  github: \"lulalala\"\n  website: \"https://code.lulalala.com/\"\n  slug: \"lulalala\"\n- name: \"Lyle Mullican\"\n  twitter: \"mullican\"\n  github: \"mullican\"\n  slug: \"lyle-mullican\"\n- name: \"Maciej Korsan\"\n  twitter: \"maciejkorsan\"\n  github: \"maciejkorsan\"\n  website: \"https://korsan.dev\"\n  slug: \"maciej-korsan\"\n  aliases:\n    - name: \"Maciek Korsan\"\n      slug: \"maciek-korsan\"\n- name: \"Maciej Mensfeld\"\n  twitter: \"maciejmensfeld\"\n  github: \"mensfeld\"\n  website: \"http://mensfeld.pl\"\n  slug: \"maciej-mensfeld\"\n- name: \"Maciej Rząsa\"\n  github: \"mrzasa\"\n  slug: \"maciej-rzasa\"\n  aliases:\n    - name: \"Maciej Rzasa\"\n      slug: \"maciej-rzasa\"\n    - name: \"Maciek Rząsa\"\n      slug: \"maciek-rzasa\"\n    - name: \"Maciek Rzasa\"\n      slug: \"maciek-rzasa\"\n- name: \"Maciej Walusiak\"\n  github: \"rabsztok\"\n  slug: \"maciej-walusiak\"\n- name: \"Maciek Rząsa\"\n  github: \"\"\n  slug: \"maciek-rzasa\"\n- name: \"Maciek Stanisz\"\n  github: \"\"\n  slug: \"maciek-stanisz\"\n- name: \"Maciek Walusiak\"\n  github: \"\"\n  slug: \"maciek-walusiak\"\n- name: \"Madelyn Freed\"\n  github: \"\"\n  slug: \"madelyn-freed\"\n- name: \"Madison White\"\n  github: \"madison-white\"\n  slug: \"madison-white\"\n- name: \"Mae Beale\"\n  github: \"\"\n  slug: \"mae-beale\"\n- name: \"Maedi Prichard\"\n  github: \"maedi\"\n  slug: \"maedi-prichard\"\n- name: \"Maeve Revels\"\n  twitter: \"maeverevels\"\n  github: \"maeve\"\n  website: \"https://betteroff.dev\"\n  slug: \"maeve-revels\"\n- name: \"Magdalena Havlickova\"\n  github: \"\"\n  slug: \"magdalena-havlickova\"\n- name: \"Magesh S\"\n  twitter: \"iMagesh\"\n  github: \"imagesh\"\n  slug: \"magesh-s\"\n- name: \"Maggie Epps\"\n  github: \"mepps\"\n  slug: \"maggie-epps\"\n- name: \"Maheshwari Ramu\"\n  github: \"\"\n  slug: \"maheshwari-ramu\"\n- name: \"Mai Nguyen\"\n  github: \"khooinguyeen\"\n  website: \"https://khooinguyeen.github.io/mkn-react-portfolio/\"\n  slug: \"mai-nguyen\"\n- name: \"Maicol Bentancor\"\n  github: \"maicolben\"\n  slug: \"maicol-bentancor\"\n- name: \"Maicon Mares\"\n  github: \"\"\n  linkedin: \"https://www.linkedin.com/in/maicon-mares\"\n  slug: \"maicon-mares\"\n- name: \"maimu\"\n  github: \"\"\n  slug: \"maimu\"\n- name: \"makicamel\"\n  github: \"\"\n  slug: \"makicamel\"\n- name: \"Makoto Chiba\"\n  github: \"hypermkt\"\n  website: \"https://blog.hypermkt.jp/\"\n  slug: \"makoto-chiba\"\n- name: \"Makoto Inoue\"\n  github: \"\"\n  slug: \"makoto-inoue\"\n- name: \"Makoto Onoue\"\n  github: \"\"\n  slug: \"makoto-onoue\"\n- name: \"Malcom Arnold\"\n  github: \"\"\n  slug: \"malcom-arnold\"\n- name: \"Mando Escamila\"\n  github: \"\"\n  slug: \"mando-escamila\"\n- name: \"Mando Escamilla\"\n  github: \"\"\n  slug: \"mando-escamilla\"\n- name: \"Mandy Michael\"\n  github: \"\"\n  slug: \"mandy-michael\"\n- name: \"Manik Juneja\"\n  github: \"mjuneja\"\n  website: \"https://fromdelhi.com\"\n  slug: \"manik-juneja\"\n- name: \"Manu Janardhanan\"\n  github: \"j-manu\"\n  website: \"https://manu-j.com\"\n  slug: \"manu-janardhanan\"\n  aliases:\n    - name: \"Manu J\"\n      slug: \"manu-j\"\n- name: \"Manu Vanconcelos\"\n  github: \"\"\n  slug: \"manu-vanconcelos\"\n- name: \"Manuel Morales\"\n  twitter: \"manuelmorales\"\n  github: \"manuelmorales\"\n  website: \"https://impactful.engineering\"\n  slug: \"manuel-morales\"\n- name: \"Many People\"\n  github: \"\"\n  slug: \"many-people\"\n- name: \"Maple Ong\"\n  twitter: \"OngMaple\"\n  github: \"wildmaples\"\n  website: \"https://mapleong.com\"\n  slug: \"maple-ong\"\n- name: \"Marc Busqué\"\n  twitter: \"waiting_for_dev\"\n  github: \"waiting-for-dev\"\n  website: \"http://waiting-for-dev.github.io\"\n  slug: \"marc-busque\"\n- name: \"Marc Reynolds\"\n  github: \"marcreynolds\"\n  slug: \"marc-reynolds\"\n- name: \"Marc-André Cournoyer\"\n  twitter: \"macournoyer\"\n  github: \"macournoyer\"\n  website: \"http://macournoyer.com\"\n  slug: \"marc-andre-cournoyer\"\n- name: \"Marc-André Giroux\"\n  github: \"xuorig\"\n  slug: \"marc-andre-giroux\"\n- name: \"Marc-André Lafortune\"\n  github: \"marcandre\"\n  slug: \"marc-andre-lafortune\"\n- name: \"Marcel Molina\"\n  twitter: \"noradio\"\n  github: \"marcel\"\n  slug: \"marcel-molina\"\n- name: \"Marcelo De Polli\"\n  github: \"\"\n  slug: \"marcelo-de-polli\"\n- name: \"Marcin Bunsch\"\n  github: \"\"\n  slug: \"marcin-bunsch\"\n- name: \"Marcin Grzywaczewski\"\n  github: \"killavus\"\n  slug: \"marcin-grzywaczewski\"\n- name: \"Marcin Olichwirowicz\"\n  github: \"rodzyn\"\n  slug: \"marcin-olichwirowicz\"\n- name: \"Marcin Stecki\"\n  github: \"madsheep\"\n  slug: \"marcin-stecki\"\n- name: \"Marcin Wyszynski\"\n  github: \"marcinwyszynski\"\n  website: \"https://spacelift.io\"\n  slug: \"marcin-wyszynski\"\n- name: \"Marco Borromeo\"\n  github: \"\"\n  slug: \"marco-borromeo\"\n- name: \"Marco Heimeshoff\"\n  github: \"heimeshoff\"\n  website: \"https://www.heimeshoff.de\"\n  slug: \"marco-heimeshoff\"\n- name: \"Marco Otte-Witte\"\n  github: \"marcoow\"\n  slug: \"marco-otte-witte\"\n- name: \"Marco Rogers\"\n  github: \"polotek\"\n  website: \"https://marcorogers.com/\"\n  slug: \"marco-rogers\"\n- name: \"Marco Roth\"\n  twitter: \"marcoroth_\"\n  github: \"marcoroth\"\n  website: \"https://marcoroth.dev\"\n  slug: \"marco-roth\"\n- name: \"Marcos Castilho da Costa Matos\"\n  github: \"marcosccm\"\n  slug: \"marcos-castilho-da-costa-matos\"\n  aliases:\n    - name: \"Marcos Matos\"\n      slug: \"marcos-matos\"\n    - name: \"Marcos Castilho\"\n      slug: \"marcos-castilho\"\n- name: \"Marcus J. Carey\"\n  github: \"\"\n  slug: \"marcus-j-carey\"\n- name: \"Marcus Morrison\"\n  github: \"mmorrison\"\n  slug: \"marcus-morrison\"\n- name: \"Marek Piasecki\"\n  github: \"madmaniak\"\n  slug: \"marek-piasecki\"\n- name: \"Maren Heltsche\"\n  github: \"zaziemo\"\n  slug: \"maren-heltsche\"\n- name: \"Margaret Pagel\"\n  github: \"\"\n  slug: \"margaret-pagel\"\n- name: \"Margo Urey\"\n  github: \"margonline\"\n  website: \"http://www.margonline.co.uk\"\n  slug: \"margo-urey\"\n- name: \"Mari Imaizumi\"\n  twitter: \"ima1zumi\"\n  github: \"ima1zumi\"\n  slug: \"mari-imaizumi\"\n- name: \"Maria Gutierrez\"\n  github: \"mariagutierrez\"\n  slug: \"maria-gutierrez\"\n- name: \"Maria Moore\"\n  github: \"\"\n  slug: \"maria-moore\"\n- name: \"Maria Yudina\"\n  twitter: \"maria_developer\"\n  github: \"yudina-m\"\n  slug: \"maria-yudina\"\n- name: \"Marian Dumitru\"\n  twitter: \"marianbuilds\"\n  github: \"marianDdev\"\n  slug: \"marian-dumitru\"\n- name: \"Marian Posăceanu\"\n  twitter: \"dakull\"\n  github: \"marianposaceanu\"\n  website: \"https://marianposaceanu.com\"\n  slug: \"marian-posaceanu\"\n- name: \"Mariano Iglesias\"\n  github: \"\"\n  slug: \"mariano-iglesias\"\n- name: \"Marie-Therese Fischer\"\n  github: \"foxmerald\"\n  slug: \"marie-therese-fischer\"\n- name: \"Marija Mandić\"\n  github: \"\"\n  slug: \"marija-mandic\"\n- name: \"Mario Arias\"\n  github: \"\"\n  slug: \"mario-arias\"\n- name: \"Mario Chávez\"\n  twitter: \"mario_chavez\"\n  github: \"mariochavez\"\n  website: \"https://mariochavez.io\"\n  slug: \"mario-chavez\"\n  aliases:\n    - name: \"Mario Chavez\"\n      slug: \"mario-chavez\"\n    - name: \"Mario Alberto Chavez\"\n      slug: \"mario-alberto-chavez\"\n- name: \"Mario Fernandez\"\n  github: \"\"\n  slug: \"mario-fernandez\"\n- name: \"Mario Gintili\"\n  github: \"\"\n  slug: \"mario-gintili\"\n- name: \"Mario Gonzalez\"\n  github: \"\"\n  slug: \"mario-gonzalez\"\n- name: \"Mario Schüttel\"\n  github: \"lxxxvi\"\n  slug: \"mario-schuttel\"\n- name: \"Mario Visic\"\n  github: \"mariovisic\"\n  website: \"https://www.mariovisic.com\"\n  slug: \"mario-visic\"\n- name: \"Marion Schleifer\"\n  twitter: \"rubydwarf\"\n  github: \"marionschleifer\"\n  website: \"https://hasura.io\"\n  slug: \"marion-schleifer\"\n- name: \"Marisa Lopez\"\n  github: \"celina-lopez\"\n  website: \"https://www.worthyofapenny.com/code\"\n  slug: \"marisa-lopez\"\n- name: \"Mariusz Gil\"\n  twitter: \"mariuszgil\"\n  github: \"mariuszgil\"\n  website: \"https://bettersoftwaredesign.pl\"\n  slug: \"mariusz-gil\"\n- name: \"Mariusz Kozieł\"\n  twitter: \"KozieMariusz\"\n  github: \"adeptus\"\n  website: \"https://visuality.pl\"\n  slug: \"mariusz-koziel\"\n  aliases:\n    - name: \"Mariusz Koziel\"\n      slug: \"mariusz-koziel\"\n- name: \"Mariusz Łusiak\"\n  github: \"\"\n  slug: \"mariusz-lusiak\"\n- name: \"Mark\"\n  github: \"\"\n  slug: \"mark\"\n- name: \"Mark Bates\"\n  github: \"markbates\"\n  website: \"http://www.metabates.com\"\n  slug: \"mark-bates\"\n- name: \"Mark Burns\"\n  github: \"\"\n  slug: \"mark-burns\"\n- name: \"Mark Chao\"\n  github: \"lulalalalistia\"\n  slug: \"mark-chao\"\n- name: \"Mark Gelband\"\n  github: \"\"\n  slug: \"mark-gelband\"\n- name: \"Mark Hutter\"\n  github: \"mrkhutter\"\n  slug: \"mark-hutter\"\n- name: \"Mark Imbriaco\"\n  github: \"imbriaco\"\n  slug: \"mark-imbriaco\"\n- name: \"Mark Josef\"\n  github: \"\"\n  slug: \"mark-josef\"\n- name: \"Mark Locklear\"\n  github: \"marklocklear\"\n  slug: \"mark-locklear\"\n- name: \"Mark Lorenz\"\n  twitter: \"soodesune\"\n  github: \"markjlorenz\"\n  slug: \"mark-lorenz\"\n- name: \"Mark McDonald\"\n  github: \"\"\n  slug: \"mark-mcdonald\"\n- name: \"Mark McSpadden\"\n  github: \"markmcspadden\"\n  website: \"http://www.markmcspadden.net\"\n  slug: \"mark-mcspadden\"\n- name: \"Mark Menard\"\n  github: \"markmenard\"\n  website: \"http://www.enablelabs.com/\"\n  slug: \"mark-menard\"\n- name: \"Mark Siemers\"\n  github: \"marksiemers-msr\"\n  slug: \"mark-siemers\"\n- name: \"Mark Simoneau\"\n  github: \"marksim\"\n  website: \"https://quarternotecoda.com\"\n  slug: \"mark-simoneau\"\n- name: \"Mark Yoon\"\n  github: \"\"\n  slug: \"mark-yoon\"\n- name: \"Marko Bogdanović\"\n  github: \"bmarkons\"\n  website: \"https://markobogdanovic.dev\"\n  slug: \"marko-bogdanovic\"\n- name: \"Marko Ćilimković\"\n  github: \"cilim\"\n  website: \"https://infinum.com\"\n  slug: \"marko-cilimkovic\"\n- name: \"Markus Schirp\"\n  twitter: \"_m_b_j_\"\n  github: \"mbj\"\n  slug: \"markus-schirp\"\n- name: \"Marla Brizel Zeschin\"\n  github: \"\"\n  slug: \"marla-brizel-zeschin\"\n- name: \"Marla Zeschin\"\n  github: \"marlabrizel\"\n  website: \"https://www.marlazeschin.com\"\n  slug: \"marla-zeschin\"\n- name: \"Marlena Compton\"\n  github: \"marlena\"\n  website: \"http://marlenacompton.com\"\n  slug: \"marlena-compton\"\n- name: \"Marli Baumann\"\n  github: \"marli\"\n  slug: \"marli-baumann\"\n- name: \"Marshall Yount\"\n  github: \"\"\n  slug: \"marshall-yount\"\n- name: \"Marta Paciorkowska\"\n  github: \"xamebax\"\n  website: \"https://thatmarta.wordpress.com/\"\n  slug: \"marta-paciorkowska\"\n- name: \"Martin Atkins\"\n  github: \"\"\n  slug: \"martin-atkins\"\n- name: \"Martin Bosslet\"\n  github: \"emboss\"\n  slug: \"martin-bosslet\"\n  aliases:\n    - name: \"Martin Boßlet\"\n      slug: \"martin-bosslet\"\n- name: \"Martin Cavoj\"\n  github: \"macav\"\n  slug: \"martin-cavoj\"\n- name: \"Martin Chenu\"\n  github: \"\"\n  slug: \"martin-chenu\"\n- name: \"Martin Emde\"\n  github: \"martinemde\"\n  website: \"https://martinemde.com\"\n  slug: \"martin-emde\"\n- name: \"Martin Evans\"\n  github: \"\"\n  slug: \"martin-evans\"\n- name: \"Martin Gamsjaeger\"\n  github: \"snusnu\"\n  website: \"http://quasipartikel.at\"\n  slug: \"martin-gamsjaeger\"\n- name: \"Martin J. Dürst\"\n  github: \"duerst\"\n  slug: \"martin-j-durst\"\n- name: \"Martin Jaime\"\n  github: \"martinjaimem\"\n  slug: \"martin-jaime\"\n- name: \"Martin Kleppmann\"\n  github: \"\"\n  slug: \"martin-kleppmann\"\n- name: \"Martin Meyerhoff\"\n  github: \"\"\n  slug: \"martin-meyerhoff\"\n- name: \"Martin Sadler\"\n  github: \"\"\n  slug: \"martin-sadler\"\n- name: \"Martin Tomov\"\n  github: \"\"\n  slug: \"martin-tomov\"\n- name: \"Martin Verzilli\"\n  github: \"mverzilli\"\n  slug: \"martin-verzilli\"\n- name: \"Martina Koleva\"\n  github: \"martinakoleva\"\n  slug: \"martina-koleva\"\n- name: \"Martín Salías\"\n  github: \"\"\n  slug: \"martin-salias\"\n- name: \"Martín Sarsale\"\n  github: \"\"\n  slug: \"martin-sarsale\"\n- name: \"Marty Haught\"\n  github: \"mghaught\"\n  website: \"https://www.linkedin.com/in/martyhaught/\"\n  slug: \"marty-haught\"\n- name: \"Martín Barreto\"\n  github: \"\"\n  slug: \"martin-barreto\"\n- name: \"Mary Elizabeth Cutrali\"\n  github: \"\"\n  slug: \"mary-elizabeth-cutrali\"\n- name: \"Mary Lee\"\n  github: \"\"\n  slug: \"mary-lee\"\n- name: \"Mary Thengvall\"\n  twitter: \"mary_grace\"\n  github: \"mary-grace\"\n  bluesky: \"mary-grace.bsky.social\"\n  website: \"https://www.marythengvall.com\"\n  slug: \"mary-thengvall\"\n- name: \"Masahiro Ihara\"\n  github: \"ihara2525\"\n  website: \"https://bitjourney.com\"\n  slug: \"masahiro-ihara\"\n- name: \"Masahiro Nagano\"\n  twitter: \"kazeburo\"\n  github: \"kazeburo\"\n  website: \"https://blog.nomadscafe.jp/\"\n  slug: \"masahiro-nagano\"\n- name: \"Masahiro TANAKA\"\n  github: \"masahirotanaka\"\n  slug: \"masahiro-tanaka\"\n- name: \"Masaki Hara\"\n  twitter: \"qnighy\"\n  github: \"qnighy\"\n  slug: \"masaki-hara\"\n- name: \"Masaki Matsushita\"\n  twitter: \"_mmasaki\"\n  github: \"mmasaki\"\n  slug: \"masaki-matsushita\"\n- name: \"Masaomi Hatakeyama\"\n  github: \"\"\n  slug: \"masaomi-hatakeyama\"\n- name: \"Masataka Kuwabara\"\n  twitter: \"p_ck_\"\n  github: \"pocke\"\n  website: \"http://me.pocke.me\"\n  slug: \"masataka-kuwabara\"\n- name: \"Masataka Pocke Kuwabara\"\n  github: \"\"\n  slug: \"masataka-pocke-kuwabara\"\n- name: \"Masato Ohba\"\n  twitter: \"ohbarye\"\n  github: \"ohbarye\"\n  website: \"https://ohbarye.github.io/\"\n  slug: \"masato-ohba\"\n  aliases:\n    - name: \"ohbarye\"\n      slug: \"ohbarye\"\n- name: \"Masato Yamashita\"\n  github: \"\"\n  slug: \"masato-yamashita\"\n- name: \"Masatoshi Moritsuka\"\n  github: \"\"\n  slug: \"masatoshi-moritsuka\"\n- name: \"Masatoshi SEKI\"\n  github: \"seki\"\n  website: \"https://www.druby.org\"\n  slug: \"masatoshi-seki\"\n- name: \"Masaya Kudo\"\n  github: \"\"\n  slug: \"masaya-kudo\"\n- name: \"Masayoshi Takahashi\"\n  github: \"takahashim\"\n  website: \"http://twitter.com/takahashim\"\n  slug: \"masayoshi-takahashi\"\n- name: \"Masayoshi Takahasi\"\n  github: \"\"\n  slug: \"masayoshi-takahasi\"\n- name: \"Masayuki Mizuno\"\n  github: \"\"\n  slug: \"masayuki-mizuno\"\n- name: \"Mason Meirs\"\n  github: \"\"\n  slug: \"mason-meirs\"\n- name: \"Mat Brown\"\n  github: \"outoftime\"\n  website: \"https://outoftime.github.io\"\n  slug: \"mat-brown\"\n- name: \"Mat Schaffer\"\n  twitter: \"matschaffer\"\n  github: \"matschaffer\"\n  website: \"http://matschaffer.com\"\n  slug: \"mat-schaffer\"\n- name: \"Mateusz Kubiczek\"\n  github: \"\"\n  slug: \"mateusz-kubiczek\"\n- name: \"Mateusz Lenik\"\n  github: \"mlen\"\n  website: \"http://mlen.pl\"\n  slug: \"mateusz-lenik\"\n- name: \"Mateusz Nowak\"\n  github: \"\"\n  slug: \"mateusz-nowak\"\n- name: \"Mateusz Sagan\"\n  github: \"saganmateusz\"\n  slug: \"mateusz-sagan\"\n- name: \"Mateusz Woźniczka\"\n  github: \"mateusz-wozniczka\"\n  slug: \"mateusz-wozniczka\"\n- name: \"Matheus Mina\"\n  twitter: \"mfbmina\"\n  github: \"mfbmina\"\n  website: \"https://mfbmina.dev\"\n  slug: \"matheus-mina\"\n- name: \"Matheus Richard\"\n  twitter: \"matheusrich\"\n  github: \"matheusrich\"\n  website: \"https://matheusrich.com\"\n  slug: \"matheus-richard\"\n- name: \"Mathew Button\"\n  github: \"\"\n  slug: \"mathew-button\"\n- name: \"Mathieu Eustachy\"\n  github: \"mth0158\"\n  website: \"https://mathieu-eustachy.com/\"\n  slug: \"mathieu-eustachy\"\n- name: \"Mathieu Longe\"\n  github: \"\"\n  slug: \"mathieu-longe\"\n- name: \"Mathyas Papp\"\n  github: \"\"\n  slug: \"mathyas-papp\"\n- name: \"Matias Korhonen\"\n  github: \"matiaskorhonen\"\n  website: \"https://matiaskorhonen.fi/\"\n  slug: \"matias-korhonen\"\n- name: \"Matrin Sustrik\"\n  github: \"\"\n  slug: \"matrin-sustrik\"\n- name: \"MATSUMOTO Ryosuke\"\n  twitter: \"matsumotory\"\n  github: \"matsumotory\"\n  website: \"https://research.matsumoto-r.jp/\"\n  slug: \"matsumoto-ryosuke\"\n- name: \"Matt Aimonetti\"\n  github: \"\"\n  slug: \"matt-aimonetti\"\n- name: \"Matt Bee\"\n  github: \"\"\n  slug: \"matt-bee\"\n- name: \"Matt Conway\"\n  github: \"wr0ngway\"\n  website: \"http://cloudtruth.com\"\n  slug: \"matt-conway\"\n- name: \"Matt Duncan\"\n  github: \"mrduncan\"\n  website: \"https://mattduncan.org\"\n  slug: \"matt-duncan\"\n- name: \"Matt Duszynski\"\n  twitter: \"bsdzunk\"\n  github: \"dzunk\"\n  website: \"https://matt.dus.zyn.ski\"\n  slug: \"matt-duszynski\"\n- name: \"Matt Eagar\"\n  github: \"\"\n  slug: \"matt-eagar\"\n- name: \"Matt Hicks\"\n  github: \"\"\n  slug: \"matt-hicks\"\n- name: \"Matt Hood\"\n  github: \"\"\n  slug: \"matt-hood\"\n- name: \"Matt Hutchinson\"\n  twitter: \"matthutchin\"\n  github: \"matthutchinson\"\n  website: \"https://hiddenloop.com\"\n  slug: \"matt-hutchinson\"\n- name: \"Matt Jacobs\"\n  github: \"\"\n  slug: \"matt-jacobs\"\n- name: \"Matt Kirk\"\n  github: \"\"\n  slug: \"matt-kirk\"\n- name: \"Matt Konda\"\n  twitter: \"mkonda\"\n  github: \"mkonda\"\n  website: \"https://www.jemurai.com\"\n  slug: \"matt-konda\"\n- name: \"Matt Muller\"\n  github: \"mullermp\"\n  slug: \"matt-muller\"\n- name: \"Matt Parker\"\n  github: \"\"\n  slug: \"matt-parker\"\n- name: \"Matt Patterson\"\n  github: \"\"\n  slug: \"matt-patterson\"\n- name: \"Matt Rayner\"\n  twitter: \"mattrayner\"\n  github: \"mattrayner\"\n  website: \"https://matt.rayner.io\"\n  slug: \"matt-rayner\"\n- name: \"Matt Rogers\"\n  github: \"\"\n  slug: \"matt-rogers\"\n- name: \"Matt Rogish\"\n  github: \"mattrogish\"\n  website: \"https://mattrogish.com\"\n  slug: \"matt-rogish\"\n- name: \"Matt Sanders\"\n  github: \"nextmat\"\n  website: \"http://www.twitter.com/nextmat\"\n  slug: \"matt-sanders\"\n- name: \"Matt Sears\"\n  github: \"\"\n  slug: \"matt-sears\"\n- name: \"Matt Swanson\"\n  github: \"\"\n  slug: \"matt-swanson\"\n- name: \"Matt Thompson\"\n  github: \"\"\n  slug: \"matt-thompson\"\n- name: \"Matt Valentine-House\"\n  twitter: \"eightbitraptor\"\n  github: \"eightbitraptor\"\n  website: \"https://eightbitraptor.com\"\n  slug: \"matt-valentine-house\"\n  aliases:\n    - name: \"Matthew Valentine-House\"\n      slug: \"matthew-valentine-house\"\n- name: \"Matt Wang\"\n  github: \"\"\n  slug: \"matt-wang\"\n- name: \"Matt White\"\n  github: \"\"\n  slug: \"matt-white\"\n- name: \"Matt Wilson\"\n  github: \"hypomodern\"\n  website: \"http://hypomodern.com\"\n  slug: \"matt-wilson\"\n- name: \"Matt Wynne\"\n  twitter: \"mattwynne\"\n  github: \"mattwynne\"\n  website: \"https://mattwynne.net\"\n  slug: \"matt-wynne\"\n- name: \"Matt Yoho\"\n  github: \"\"\n  slug: \"matt-yoho\"\n- name: \"Matteo Collina\"\n  github: \"\"\n  slug: \"matteo-collina\"\n- name: \"Matteo Papadopoulos\"\n  twitter: \"spleenteo\"\n  github: \"spleenteo\"\n  website: \"https://www.datocms.com\"\n  slug: \"matteo-papadopoulos\"\n- name: \"Matteo Piotto\"\n  twitter: \"c1p8\"\n  github: \"namuit\"\n  website: \"https://matteopiotto.com\"\n  slug: \"matteo-piotto\"\n- name: \"Matteo Vaccari\"\n  github: \"\"\n  slug: \"matteo-vaccari\"\n- name: \"Matthew Bass\"\n  github: \"\"\n  slug: \"matthew-bass\"\n- name: \"Matthew Bloch\"\n  github: \"\"\n  slug: \"matthew-bloch\"\n- name: \"Matthew Borden\"\n  github: \"\"\n  slug: \"matthew-borden\"\n- name: \"Matthew Clark\"\n  github: \"\"\n  slug: \"matthew-clark\"\n- name: \"Matthew Conway\"\n  github: \"\"\n  slug: \"matthew-conway\"\n- name: \"Matthew Cooker\"\n  github: \"\"\n  slug: \"matthew-cooker\"\n- name: \"Matthew Deiters\"\n  github: \"\"\n  slug: \"matthew-deiters\"\n- name: \"Matthew Delves\"\n  github: \"\"\n  slug: \"matthew-delves\"\n- name: \"Matthew Draper\"\n  github: \"matthewd\"\n  slug: \"matthew-draper\"\n- name: \"Matthew Gaudet\"\n  github: \"mgaudet\"\n  website: \"https://mgaudet.ca\"\n  slug: \"matthew-gaudet\"\n- name: \"Matthew Kirk\"\n  github: \"\"\n  slug: \"matthew-kirk\"\n- name: \"Matthew Kocher\"\n  github: \"\"\n  slug: \"matthew-kocher\"\n- name: \"Matthew Langlois\"\n  github: \"\"\n  slug: \"matthew-langlois\"\n- name: \"Matthew Lindfield Seager\"\n  github: \"matt17r\"\n  slug: \"matthew-lindfield-seager\"\n- name: \"Matthew McCullough\"\n  github: \"\"\n  slug: \"matthew-mccullough\"\n- name: \"Matthew Mongeau\"\n  github: \"halogenandtoast\"\n  website: \"http://www.halogenandtoast.com\"\n  slug: \"matthew-mongeau\"\n- name: \"Matthew Nielsen\"\n  github: \"xunker\"\n  website: \"https://twitter.com/xunker\"\n  slug: \"matthew-nielsen\"\n- name: \"Matthew Nielson\"\n  github: \"mjnielso\"\n  slug: \"matthew-nielson\"\n- name: \"Matthew Rudy Jacobs\"\n  github: \"\"\n  slug: \"matthew-rudy-jacobs\"\n- name: \"Matthew Salerno\"\n  github: \"seldomatt\"\n  website: \"http://buoydev.com\"\n  slug: \"matthew-salerno\"\n- name: \"Matthew Thorley\"\n  github: \"\"\n  slug: \"matthew-thorley\"\n- name: \"Matthew Todd\"\n  github: \"\"\n  slug: \"matthew-todd\"\n- name: \"Matthias Günther\"\n  github: \"\"\n  slug: \"matthias-gunther\"\n- name: \"Matthias Lee\"\n  github: \"\"\n  slug: \"matthias-lee\"\n- name: \"Matthias Viehweger\"\n  github: \"kronn\"\n  website: \"http://kronn.de\"\n  slug: \"matthias-viehweger\"\n- name: \"Matti Paksula\"\n  twitter: \"mattipaksula\"\n  github: \"matti\"\n  slug: \"matti-paksula\"\n- name: \"Matías Lorenzo\"\n  github: \"matetecode\"\n  slug: \"matias-lorenzo\"\n- name: \"Mauricio A Chávez\"\n  github: \"\"\n  slug: \"mauricio-a-chavez\"\n- name: \"Mauricio Zsabo\"\n  github: \"\"\n  slug: \"mauricio-zsabo\"\n- name: \"Mauro Eldritch\"\n  twitter: \"mauroeldritch\"\n  github: \"mauroeldritch\"\n  website: \"https://www.twitter.com/mauroeldritch\"\n  slug: \"mauro-eldritch\"\n- name: \"Max Bernstein\"\n  github: \"tekknolagi\"\n  slug: \"max-bernstein\"\n- name: \"Max Gorin\"\n  twitter: \"elixirdrips\"\n  github: \"mxgrn\"\n  website: \"https://mxgrn.com\"\n  slug: \"max-gorin\"\n- name: \"Max Hatfull\"\n  github: \"MaxHatfull\"\n  slug: \"max-hatfull\"\n- name: \"Max Hawkins\"\n  github: \"maxhawkins\"\n  website: \"http://www.maxhawkins.me\"\n  slug: \"max-hawkins\"\n- name: \"Max Jacobson\"\n  github: \"maxjacobson\"\n  website: \"https://www.hardscrabble.net\"\n  slug: \"max-jacobson\"\n- name: \"Max Shelley\"\n  github: \"\"\n  slug: \"max-shelley\"\n- name: \"Max Tiu\"\n  github: \"maximumtiu\"\n  slug: \"max-tiu\"\n- name: \"Max VelDink\"\n  github: \"maxveldink\"\n  website: \"https://maxveld.ink\"\n  slug: \"max-veldink\"\n- name: \"Max Wofford\"\n  github: \"maxwofford\"\n  website: \"https://maxwofford.com/\"\n  slug: \"max-wofford\"\n- name: \"Maxim Gordienok\"\n  github: \"\"\n  slug: \"maxim-gordienok\"\n- name: \"Maxime Chevalier-Boisvert\"\n  twitter: \"Love2Code\"\n  github: \"maximecb\"\n  website: \"https://pointersgonewild.com\"\n  slug: \"maxime-chevalier-boisvert\"\n- name: \"Maxime Deveaux\"\n  github: \"\"\n  slug: \"maxime-deveaux\"\n- name: \"Maxime Personnic\"\n  github: \"maximepersonnic\"\n  slug: \"maxime-personnic\"\n- name: \"Maya Toussaint\"\n  github: \"\"\n  slug: \"maya-toussaint\"\n- name: \"Mayn E Kjæ\"\n  github: \"\"\n  slug: \"mayn-e-kjae\"\n- name: \"Mayra Lucia Navarro\"\n  twitter: \"mayralunavarro\"\n  github: \"luciagirasoles\"\n  website: \"https://www.linkedin.com/in/mayralucianavarro\"\n  slug: \"mayra-lucia-navarro\"\n  aliases:\n    - name: \"Mayra L. Navarro\"\n      slug: \"mayra-l-navarro\"\n- name: \"Maysayoshi Takahashi\"\n  github: \"\"\n  slug: \"maysayoshi-takahashi\"\n- name: \"Mayumi EMORI\"\n  twitter: \"emorima\"\n  github: \"emorima\"\n  website: \"https://emorima.love\"\n  slug: \"mayumi-emori\"\n- name: \"Mazin Power\"\n  twitter: \"mazin_power\"\n  github: \"muzfuz\"\n  website: \"https://muzfuz.com\"\n  slug: \"mazin-power\"\n- name: \"Meagan Waller\"\n  twitter: \"meaganewaller\"\n  github: \"meaganewaller\"\n  website: \"https://meaganwaller.com\"\n  slug: \"meagan-waller\"\n- name: \"Meet Shah\"\n  github: \"\"\n  slug: \"meet-shah\"\n- name: \"Megan Tiu\"\n  github: \"\"\n  slug: \"megan-tiu\"\n- name: \"Meghan Gutshall\"\n  github: \"meg-gutshall\"\n  slug: \"meghan-gutshall\"\n  aliases:\n    - name: \"Meg Gutshall\"\n      slug: \"meg-gutshall\"\n- name: \"Meghana Jagadeesh\"\n  github: \"\"\n  slug: \"meghana-jagadeesh\"\n- name: \"Mehdi Lahmam\"\n  twitter: \"mehlah\"\n  github: \"mehlah\"\n  slug: \"mehdi-lahmam\"\n- name: \"Mehdi Lahmam B.\"\n  github: \"\"\n  slug: \"mehdi-lahmam-b\"\n- name: \"Mehmet Çetin\"\n  github: \"\"\n  slug: \"mehmet-cetin\"\n- name: \"Meike Wiemann\"\n  github: \"\"\n  slug: \"meike-wiemann\"\n- name: \"Mel Kaulfuss\"\n  github: \"\"\n  slug: \"mel-kaulfuss\"\n- name: \"Melanie Gilman\"\n  github: \"mrgilman\"\n  slug: \"melanie-gilman\"\n- name: \"Melanie Keatley\"\n  twitter: \"Keatley\"\n  github: \"melkcodes\"\n  website: \"https://www.polywork.com/mmmellie\"\n  slug: \"melanie-keatley\"\n- name: \"Melinda Seckington\"\n  github: \"mseckington\"\n  website: \"http://missgeeky.com\"\n  slug: \"melinda-seckington\"\n- name: \"Melissa Hunt Glickman\"\n  github: \"mhuntglickman\"\n  slug: \"melissa-hunt-glickman\"\n- name: \"Melissa Jurkoic\"\n  github: \"\"\n  slug: \"melissa-jurkoic\"\n- name: \"Melissa Kaulfuss\"\n  github: \"\"\n  slug: \"melissa-kaulfuss\"\n- name: \"Melissa Wahnish\"\n  github: \"melissawahnish\"\n  slug: \"melissa-wahnish\"\n- name: \"Melony Erin Franchini\"\n  github: \"meltravelz\"\n  slug: \"melony-erin-franchini\"\n- name: \"Melvrick Goh\"\n  github: \"\"\n  slug: \"melvrick-goh\"\n- name: \"Melvyn Peignon\"\n  github: \"\"\n  slug: \"melvyn-peignon\"\n- name: \"Meng-Ying Tsai\"\n  github: \"\"\n  slug: \"meng-ying-tsai\"\n- name: \"Mercedes Bernard\"\n  github: \"mercedesb\"\n  slug: \"mercedes-bernard\"\n- name: \"Meredith Barry\"\n  github: \"\"\n  slug: \"meredith-barry\"\n- name: \"Meredith White\"\n  github: \"merwhite11\"\n  slug: \"meredith-white\"\n- name: \"Merrin Macleod\"\n  github: \"\"\n  slug: \"merrin-macleod\"\n- name: \"Mélanie Bérard\"\n  github: \"\"\n  slug: \"melanie-berard\"\n- name: \"Mia Szinek\"\n  github: \"\"\n  slug: \"mia-szinek\"\n- name: \"Micah Adams\"\n  github: \"brunchybit\"\n  website: \"https://focusedlabs.io\"\n  slug: \"micah-adams\"\n- name: \"Micah Gates\"\n  github: \"mgates\"\n  slug: \"micah-gates\"\n- name: \"Micah Martin\"\n  github: \"\"\n  slug: \"micah-martin\"\n- name: \"Michael\"\n  github: \"\"\n  slug: \"michael\"\n- name: \"Michael Bernstein\"\n  github: \"mrb\"\n  website: \"http://reifyworks.com\"\n  slug: \"michael-bernstein\"\n- name: \"Michael Bleigh\"\n  github: \"\"\n  slug: \"michael-bleigh\"\n- name: \"Michael Buckbee\"\n  twitter: \"mbuckbee\"\n  github: \"mbuckbee\"\n  website: \"https://expeditedsecurity.com\"\n  slug: \"michael-buckbee\"\n- name: \"Michael Cain\"\n  twitter: \"MCain310\"\n  github: \"cain310\"\n  website: \"https://www.linkedin.com/in/michael-cain-9902ba2\"\n  slug: \"michael-cain\"\n- name: \"Michael Chan\"\n  github: \"\"\n  slug: \"michael-chan\"\n- name: \"Michael Cheng\"\n  github: \"\"\n  slug: \"michael-cheng\"\n- name: \"Michael Crismali\"\n  github: \"crismali\"\n  slug: \"michael-crismali\"\n- name: \"Michael Dawson\"\n  github: \"\"\n  slug: \"michael-dawson\"\n- name: \"Michael de Hoog\"\n  github: \"mdehoog\"\n  slug: \"michael-de-hoog\"\n- name: \"Michael Edgar\"\n  github: \"\"\n  slug: \"michael-edgar\"\n- name: \"Michael Fairchild\"\n  github: \"fairchild\"\n  slug: \"michael-fairchild\"\n- name: \"Michael Fairley\"\n  twitter: \"michaelfairley\"\n  github: \"michaelfairley\"\n  website: \"https://michaelfairley.com\"\n  slug: \"michael-fairley\"\n- name: \"Michael Feathers\"\n  github: \"michaelfeathers\"\n  slug: \"michael-feathers\"\n- name: \"Michael Grosser\"\n  twitter: \"grosser\"\n  github: \"grosser\"\n  website: \"https://grosser.it\"\n  slug: \"michael-grosser\"\n- name: \"Michael Harper\"\n  github: \"\"\n  slug: \"michael-harper\"\n- name: \"Michael Hartl\"\n  twitter: \"mhartl\"\n  github: \"mhartl\"\n  website: \"https://www.michaelhartl.com/\"\n  slug: \"michael-hartl\"\n- name: \"Michael Herold\"\n  twitter: \"mherold\"\n  github: \"michaelherold\"\n  website: \"https://michaeljherold.com\"\n  slug: \"michael-herold\"\n- name: \"Michael Hewner\"\n  github: \"\"\n  slug: \"michael-hewner\"\n- name: \"Michael Jackson\"\n  github: \"mjackson\"\n  twitter: \"mjackson\"\n  slug: \"michael-jackson\"\n  aliases:\n    - name: \"Michael J. I. Jackson\"\n      slug: \"michael-j-i-jackson\"\n- name: \"Michael Kelly\"\n  github: \"\"\n  slug: \"michael-kelly\"\n- name: \"Michael Kimathi\"\n  github: \"\"\n  slug: \"michael-kimathi\"\n- name: \"Michael King\"\n  github: \"rgkjhshi\"\n  website: \"https://rgkjhshi.github.io/\"\n  slug: \"michael-king\"\n- name: \"Michael Koper\"\n  github: \"\"\n  slug: \"michael-koper\"\n- name: \"Michael Koziarski\"\n  github: \"\"\n  slug: \"michael-koziarski\"\n- name: \"Michael May\"\n  github: \"mmay\"\n  website: \"https://yo.mmay.net\"\n  slug: \"michael-may\"\n- name: \"Michael Mazour\"\n  github: \"\"\n  slug: \"michael-mazour\"\n- name: \"Michael Milewski\"\n  twitter: \"saramic\"\n  github: \"saramic\"\n  website: \"https://failure-driven.com/\"\n  slug: \"michael-milewski\"\n- name: \"Michael Morris\"\n  github: \"\"\n  slug: \"michael-morris\"\n- name: \"Michael Murphy\"\n  twitter: \"mmstick\"\n  github: \"mmstick\"\n  slug: \"michael-murphy\"\n- name: \"Michael Norton\"\n  github: \"norton-design\"\n  website: \"https://norton-design.github.io/\"\n  slug: \"michael-norton\"\n- name: \"Michael O'Brien\"\n  github: \"\"\n  slug: \"michael-o-brien\"\n- name: \"Michael Pope\"\n  github: \"\"\n  slug: \"michael-pope\"\n- name: \"Michael Prilop\"\n  github: \"\"\n  slug: \"michael-prilop\"\n- name: \"Michael Rau\"\n  github: \"oct1473254\"\n  website: \"http://michaelrau.com\"\n  slug: \"michael-rau\"\n- name: \"Michael Ries\"\n  github: \"\"\n  slug: \"michael-ries\"\n- name: \"Michael Sauter\"\n  github: \"\"\n  slug: \"michael-sauter\"\n- name: \"Michael Swieton\"\n  github: \"swieton\"\n  slug: \"michael-swieton\"\n- name: \"Michael Toppa\"\n  github: \"toppa\"\n  website: \"https://toppaware.com\"\n  slug: \"michael-toppa\"\n- name: \"Michael Wawra\"\n  github: \"xmjw\"\n  slug: \"michael-wawra\"\n- name: \"Michael Yu\"\n  github: \"\"\n  slug: \"michael-yu\"\n- name: \"Michal Kazmierczak\"\n  github: \"michal-kazmierczak\"\n  website: \"https://mkaz.me\"\n  slug: \"michal-kazmierczak\"\n- name: \"Michal Papis\"\n  twitter: \"mpapis\"\n  github: \"mpapis\"\n  website: \"http://niczsoft.com\"\n  slug: \"michal-papis\"\n- name: \"Michał Czyż\"\n  twitter: \"cs3b\"\n  github: \"cs3b\"\n  slug: \"michal-czyz\"\n- name: \"Michał Knapik\"\n  github: \"mknapik\"\n  slug: \"michal-knapik\"\n- name: \"Michał Konarski\"\n  twitter: \"mjkonarski\"\n  github: \"mjkonarski-b\"\n  website: \"https://mjk.space\"\n  slug: \"michal-konarski\"\n- name: \"Michał Krzyżanowski\"\n  github: \"krzyzak\"\n  website: \"https://krzyzak.dev\"\n  slug: \"michal-krzyzanowski\"\n- name: \"Michał Matyas\"\n  github: \"d4rky-pl\"\n  website: \"http://nerdblog.pl\"\n  slug: \"michal-matyas\"\n- name: \"Michał Muskała\"\n  github: \"michalmuskala\"\n  website: \"http://michal.muskala.eu\"\n  slug: \"michal-muskala\"\n- name: \"Michał Młoźniak\"\n  github: \"ronin\"\n  website: \"https://www.michalmlozniak.com\"\n  slug: \"michal-mlozniak\"\n- name: \"Michał Połtyn\"\n  github: \"holek\"\n  slug: \"michal-poltyn\"\n- name: \"Michał Taszycki\"\n  github: \"mehowte\"\n  website: \"https://www.twitter.com/mehowte\"\n  slug: \"michal-taszycki\"\n- name: \"Michał Zając\"\n  github: \"quintasan\"\n  website: \"https://michalzajac.me\"\n  slug: \"michal-zajac\"\n- name: \"Michał Zajączkowski de Mezer\"\n  github: \"\"\n  slug: \"michal-zajaczkowski-de-mezer\"\n- name: \"Michał Łomnicki\"\n  github: \"mlomnicki\"\n  website: \"http://mlomnicki.com\"\n  slug: \"michal-lomnicki\"\n- name: \"Michał Łęcicki\"\n  twitter: \"mlecicki\"\n  github: \"maikhel\"\n  website: \"https://maikhel.github.io\"\n  slug: \"michal-lecicki\"\n- name: \"Micheal Millewski\"\n  github: \"\"\n  slug: \"micheal-millewski\"\n- name: \"Michel Grootjans\"\n  github: \"\"\n  slug: \"michel-grootjans\"\n- name: \"Michel Jamati\"\n  github: \"\"\n  slug: \"michel-jamati\"\n- name: \"Michel Martens\"\n  twitter: \"soveran\"\n  github: \"soveran\"\n  website: \"https://soveran.com\"\n  slug: \"michel-martens\"\n- name: \"Michel Weksler\"\n  github: \"\"\n  slug: \"michel-weksler\"\n- name: \"Michele Franzin\"\n  github: \"fuzziness\"\n  slug: \"michele-franzin\"\n- name: \"Michele Guido\"\n  github: \"\"\n  slug: \"michele-guido\"\n- name: \"Michele Hansen\"\n  github: \"\"\n  slug: \"michele-hansen\"\n- name: \"Michele Titolo\"\n  github: \"\"\n  slug: \"michele-titolo\"\n- name: \"Michelle Guido\"\n  github: \"\"\n  slug: \"michelle-guido\"\n- name: \"Michelle Yuen\"\n  github: \"yuenmichelle1\"\n  slug: \"michelle-yuen\"\n- name: \"Miguel Marcondes Filho\"\n  github: \"miguelmarcondesf\"\n  slug: \"miguel-marcondes-filho\"\n- name: \"Miha Rekar\"\n  github: \"miharekar\"\n  website: \"https://mr.si/\"\n  slug: \"miha-rekar\"\n- name: \"Mihail Paleologu\"\n  github: \"\"\n  slug: \"mihail-paleologu\"\n- name: \"Mike\"\n  twitter: \"mbostock\"\n  github: \"mbostock\"\n  website: \"https://observablehq.com/@mbostock\"\n  slug: \"mike\"\n- name: \"Mike AbiEzzi\"\n  github: \"mikeabiezzi\"\n  website: \"https://mikeabiezzi.com\"\n  slug: \"mike-abiezzi\"\n- name: \"Mike Bernstein\"\n  github: \"\"\n  slug: \"mike-bernstein\"\n- name: \"Mike Bourgeous\"\n  github: \"mike-bourgeous\"\n  website: \"https://blog.mikebourgeous.com/\"\n  slug: \"mike-bourgeous\"\n- name: \"Mike Calhoun\"\n  github: \"comike011\"\n  website: \"http://www.michaelcalhoun.com\"\n  slug: \"mike-calhoun\"\n- name: \"Mike Chlipala\"\n  github: \"\"\n  slug: \"mike-chlipala\"\n- name: \"Mike Clark\"\n  github: \"\"\n  slug: \"mike-clark\"\n- name: \"Mike Coutermarsh\"\n  github: \"\"\n  slug: \"mike-coutermarsh\"\n- name: \"Mike Dalessio\"\n  twitter: \"flavorjones\"\n  github: \"flavorjones\"\n  website: \"https://mike.daless.io\"\n  slug: \"mike-dalessio\"\n  aliases:\n    - name: \"Michael Dalessio\"\n      slug: \"michael-dalessio\"\n- name: \"Mike Dalton\"\n  github: \"kcdragon\"\n  slug: \"mike-dalton\"\n- name: \"Mike Eduard\"\n  github: \"mikeeduard\"\n  website: \"http://znuny.com\"\n  slug: \"mike-eduard\"\n- name: \"Mike Fotinakis\"\n  github: \"\"\n  slug: \"mike-fotinakis\"\n- name: \"Mike Gee\"\n  twitter: \"mikegeecmu\"\n  github: \"mike-gee\"\n  slug: \"mike-gee\"\n- name: \"Mike Gehard\"\n  github: \"mikegehard\"\n  slug: \"mike-gehard\"\n- name: \"Mike Groseclose\"\n  github: \"\"\n  slug: \"mike-groseclose\"\n- name: \"Mike Hagedorn\"\n  github: \"\"\n  slug: \"mike-hagedorn\"\n- name: \"Mike Leone\"\n  github: \"\"\n  slug: \"mike-leone\"\n- name: \"Mike McQuaid\"\n  twitter: \"MikeMcQuaid\"\n  github: \"mikemcquaid\"\n  website: \"https://mikemcquaid.com\"\n  slug: \"mike-mcquaid\"\n- name: \"Mike Milner\"\n  github: \"\"\n  slug: \"mike-milner\"\n- name: \"Mike Moore\"\n  github: \"blowmage\"\n  website: \"http://blowmage.com/\"\n  slug: \"mike-moore\"\n- name: \"Mike Neville-O'Neill\"\n  github: \"\"\n  slug: \"mike-neville-o-neill\"\n- name: \"Mike Nicholaides\"\n  github: \"nicholaides\"\n  website: \"http://www.promptworks.com\"\n  slug: \"mike-nicholaides\"\n- name: \"Mike North\"\n  github: \"\"\n  slug: \"mike-north\"\n- name: \"Mike Perham\"\n  github: \"mperham\"\n  website: \"https://www.mikeperham.com\"\n  slug: \"mike-perham\"\n- name: \"Mike Presman\"\n  github: \"\"\n  slug: \"mike-presman\"\n- name: \"Mike Rogers\"\n  github: \"mikerogers0\"\n  slug: \"mike-rogers\"\n- name: \"Mike Scalnik\"\n  github: \"\"\n  slug: \"mike-scalnik\"\n- name: \"Mike Schutte\"\n  github: \"tmikeschu\"\n  website: \"https://tmikeschu.com\"\n  slug: \"mike-schutte\"\n- name: \"Mike Stowe\"\n  github: \"snoopsqueak\"\n  slug: \"mike-stowe\"\n- name: \"Mike Subelsky\"\n  github: \"\"\n  slug: \"mike-subelsky\"\n- name: \"Mike Toppa\"\n  github: \"\"\n  slug: \"mike-toppa\"\n- name: \"Mike Virata-Ston\"\n  github: \"\"\n  slug: \"mike-virata-ston\"\n- name: \"Mike Virata-Stone\"\n  github: \"\"\n  slug: \"mike-virata-stone\"\n- name: \"Mike Wheeler\"\n  github: \"myquealer\"\n  slug: \"mike-wheeler\"\n- name: \"Mike Yang\"\n  github: \"\"\n  slug: \"mike-yang\"\n- name: \"Mikel Lindsaar\"\n  twitter: \"lindsaar\"\n  github: \"mikel\"\n  website: \"https://lindsaar.net/\"\n  slug: \"mikel-lindsaar\"\n- name: \"Mikhail Bortnyk\"\n  github: \"\"\n  slug: \"mikhail-bortnyk\"\n- name: \"Miki Rezentes\"\n  github: \"mrezentes\"\n  slug: \"miki-rezentes\"\n- name: \"Mila Dymnikova\"\n  github: \"\"\n  slug: \"mila-dymnikova\"\n- name: \"Miles Forrest\"\n  github: \"miles\"\n  website: \"https://milesforrest.com\"\n  slug: \"miles-forrest\"\n- name: \"Miles Georgi\"\n  github: \"azimux\"\n  website: \"https://foobara.org/\"\n  slug: \"miles-georgi\"\n- name: \"Miles McGuire\"\n  twitter: \"_minuteman3\"\n  github: \"minuteman3\"\n  slug: \"miles-mcguire\"\n- name: \"Miles Woodroffe\"\n  twitter: \"tapster\"\n  github: \"tapster\"\n  website: \"https://mileswoodroffe.com\"\n  slug: \"miles-woodroffe\"\n- name: \"Miller Levert\"\n  github: \"\"\n  slug: \"miller-levert\"\n- name: \"MiMi Moore\"\n  github: \"\"\n  slug: \"mimi-moore\"\n- name: \"Mina Slater\"\n  twitter: \"Minar528\"\n  github: \"minaslater\"\n  website: \"https://minaslater.blog/\"\n  slug: \"mina-slater\"\n- name: \"Minero Aoki\"\n  github: \"\"\n  slug: \"minero-aoki\"\n- name: \"Minqi Pan\"\n  twitter: \"psvr\"\n  github: \"pmq20\"\n  website: \"https://www.minqi-pan.com\"\n  slug: \"minqi-pan\"\n- name: \"Miranda Heath\"\n  github: \"MirandaHeath\"\n  slug: \"miranda-heath\"\n- name: \"Mirek Pragłowski\"\n  github: \"\"\n  slug: \"mirek-praglowski\"\n- name: \"Miriam Tocino\"\n  github: \"miriamtocino\"\n  website: \"https://zerusandona.com/\"\n  slug: \"miriam-tocino\"\n- name: \"Miron Marczuk\"\n  github: \"morszczuk\"\n  slug: \"miron-marczuk\"\n- name: \"Misaki Shioi\"\n  github: \"shioimm\"\n  website: \"https://twitter.com/coe401_\"\n  slug: \"misaki-shioi\"\n- name: \"Mischa Lewis\"\n  github: \"mlewisno\"\n  website: \"http://mischa.house\"\n  slug: \"mischa-lewis\"\n- name: \"Mislav Marohnić\"\n  twitter: \"mislav\"\n  github: \"mislav\"\n  website: \"https://mislav.net\"\n  slug: \"mislav-marohnic\"\n- name: \"Mitchell Hashimoto\"\n  github: \"mitchellh\"\n  slug: \"mitchell-hashimoto\"\n- name: \"MITSUBOSH\"\n  github: \"mitsuboshi\"\n  slug: \"mitsubosh\"\n- name: \"Mitsutaka Mimura\"\n  github: \"takkanm\"\n  slug: \"mitsutaka-mimura\"\n- name: \"miyohide\"\n  github: \"miyohide\"\n  slug: \"miyohide\"\n- name: \"Miyuki Koshiba\"\n  github: \"ksbmyk\"\n  slug: \"miyuki-koshiba\"\n  aliases:\n    - name: \"chobishiba\"\n      slug: \"chobishiba\"\n- name: \"Miyuki Tomiyama\"\n  github: \"\"\n  slug: \"miyuki-tomiyama\"\n- name: \"Mizuki Asada\"\n  github: \"\"\n  slug: \"mizuki-asada\"\n- name: \"Mo O'Connor\"\n  github: \"\"\n  slug: \"mo-o-connor\"\n- name: \"moegi\"\n  github: \"moegi29\"\n  slug: \"moegi\"\n- name: \"Mohamed Hassan\"\n  twitter: \"oldmoe\"\n  github: \"oldmoe\"\n  website: \"https://www.oldmoe.blog\"\n  slug: \"mohamed-hassan\"\n- name: \"Mohit Thatte\"\n  github: \"\"\n  slug: \"mohit-thatte\"\n- name: \"Mohnish Jadwani\"\n  twitter: \"mohnishgj\"\n  github: \"boddhisattva\"\n  slug: \"mohnish-jadwani\"\n- name: \"Molly Black\"\n  github: \"\"\n  slug: \"molly-black\"\n- name: \"Molly Struve\"\n  twitter: \"molly_struve\"\n  github: \"mstruve\"\n  website: \"https://twitter.com/molly_struve\"\n  slug: \"molly-struve\"\n- name: \"Moncef Belyamani\"\n  twitter: \"monfresh\"\n  github: \"monfresh\"\n  website: \"https://www.moncefbelyamani.com\"\n  slug: \"moncef-belyamani\"\n- name: \"Money Forward\"\n  github: \"\"\n  slug: \"money-forward\"\n- name: \"Monica Giambitto\"\n  github: \"nirnaeth\"\n  website: \"https://monicag.me\"\n  slug: \"monica-giambitto\"\n- name: \"Monika M\"\n  github: \"\"\n  slug: \"monika-m\"\n- name: \"Morgan Fogarty\"\n  github: \"mofo37\"\n  slug: \"morgan-fogarty\"\n- name: \"Morgan Laco\"\n  github: \"\"\n  slug: \"morgan-laco\"\n- name: \"morihirok\"\n  github: \"\"\n  slug: \"morihirok\"\n- name: \"Moriyuki Hirata\"\n  github: \"\"\n  slug: \"moriyuki-hirata\"\n- name: \"MOROHASHI Kyosuke\"\n  github: \"moro\"\n  slug: \"morohashi-kyosuke\"\n  website: \"http://d.hatena.ne.jp/moro/\"\n  aliases:\n    - name: \"Kyosuke MOROHASHI\"\n      slug: \"kyosuke-morohashi\"\n    - name: \"moro\"\n      slug: \"moro\"\n- name: \"Mostafa Abdelraouf\"\n  github: \"\"\n  slug: \"mostafa-abdelraouf\"\n- name: \"moznion\"\n  github: \"\"\n  slug: \"moznion\"\n- name: \"Mu-Fan Teng\"\n  twitter: \"ryudoawaru\"\n  github: \"ryudoawaru\"\n  website: \"https://ryudo.tw\"\n  slug: \"mu-fan-teng\"\n- name: \"Mudit Maheshwari\"\n  github: \"\"\n  slug: \"mudit-maheshwari\"\n  website: \"https://medium.com/@hellomudit\"\n- name: \"Mugurel Chirica\"\n  github: \"\"\n  slug: \"mugurel-chirica\"\n- name: \"Muhamed Isabegović\"\n  github: \"misabegovic\"\n  slug: \"muhamed-isabegovic\"\n  aliases:\n    - name: \"Muhamed Isabegovic\"\n      slug: \"muhamed-isabegovic\"\n- name: \"Murad Iusufov\"\n  github: \"flood4life\"\n  slug: \"murad-iusufov\"\n- name: \"Murat Toygar\"\n  github: \"mtoygar\"\n  slug: \"murat-toygar\"\n- name: \"Murray Steele\"\n  github: \"h-lame\"\n  website: \"http://www.h-lame.com/\"\n  slug: \"murray-steele\"\n- name: \"Máximo Mussini\"\n  github: \"\"\n  slug: \"maximo-mussini\"\n- name: \"Nabeelah Yousuph\"\n  twitter: \"wanderluster_xo\"\n  github: \"nabeelahy\"\n  website: \"https://nabeelahyousuph.com/\"\n  slug: \"nabeelah-yousuph\"\n- name: \"Nadia Odunayo\"\n  twitter: \"nodunayo\"\n  github: \"nodunayo\"\n  website: \"https://nadiaodunayo.com\"\n  slug: \"nadia-odunayo\"\n- name: \"Nadia Vu\"\n  github: \"\"\n  slug: \"nadia-vu\"\n- name: \"Nagendra Hassan Dhanakeerthi\"\n  github: \"nagstler\"\n  slug: \"nagendra-hassan-dhanakeerthi\"\n- name: \"Naijeria Toweett\"\n  twitter: \"mumlovestech\"\n  github: \"nashthecoder\"\n  website: \"https://github.com/nashthecoder\"\n  slug: \"naijeria-toweett\"\n- name: \"NAITOH Jun\"\n  twitter: \"naitoh\"\n  github: \"naitoh\"\n  slug: \"naitoh-jun\"\n- name: \"namusyaka\"\n  twitter: \"namusyaka\"\n  github: \"namusyaka\"\n  website: \"https://namusyaka.com/\"\n  slug: \"namusyaka\"\n- name: \"Nancy Cai\"\n  github: \"\"\n  slug: \"nancy-cai\"\n- name: \"Nandini Singhal\"\n  github: \"\"\n  slug: \"nandini-singhal\"\n- name: \"Naofumi Kagami\"\n  twitter: \"naofumi\"\n  github: \"naofumi\"\n  slug: \"naofumi-kagami\"\n- name: \"Naohisa Goto\"\n  twitter: \"ngotogenome\"\n  github: \"ngoto\"\n  slug: \"naohisa-goto\"\n- name: \"Naoki Kishida\"\n  github: \"kishida\"\n  slug: \"naoki-kishida\"\n- name: \"Naoki Matsuda\"\n  github: \"NaokiMatsuda\"\n  slug: \"naoki-matsuda\"\n- name: \"Naomi Christie\"\n  github: \"\"\n  slug: \"naomi-christie\"\n- name: \"Naomi Freeman\"\n  github: \"\"\n  slug: \"naomi-freeman\"\n- name: \"Naotaka Harada\"\n  github: \"neotag\"\n  slug: \"naotaka-harada\"\n- name: \"Naoto Ono\"\n  github: \"ono-max\"\n  website: \"https://www.linkedin.com/in/naoto-ono-840981189\"\n  slug: \"naoto-ono\"\n- name: \"Naoto Yamaji\"\n  github: \"\"\n  slug: \"naoto-yamaji\"\n- name: \"Naotoshi Seo\"\n  github: \"sonots\"\n  website: \"https://twitter.com/sonots\"\n  slug: \"naotoshi-seo\"\n- name: \"Naoyuki Kataoka\"\n  github: \"katty0324\"\n  website: \"http://blog.katty.in/\"\n  slug: \"naoyuki-kataoka\"\n- name: \"Narendran\"\n  github: \"dudewhocode\"\n  slug: \"narendran\"\n- name: \"nari\"\n  github: \"\"\n  slug: \"nari\"\n- name: \"Narihiro Nakamura\"\n  github: \"\"\n  slug: \"narihiro-nakamura\"\n- name: \"NARUSE Yui\"\n  github: \"\"\n  slug: \"naruse-yui\"\n- name: \"Nat Buckley\"\n  github: \"\"\n  slug: \"nat-buckley\"\n- name: \"Nat Budin\"\n  github: \"nbudin\"\n  slug: \"nat-budin\"\n- name: \"Nate Berkopec\"\n  twitter: \"nateberkopec\"\n  github: \"nateberkopec\"\n  website: \"http://nateberkopec.com\"\n  slug: \"nate-berkopec\"\n- name: \"Nate Clark\"\n  github: \"\"\n  slug: \"nate-clark\"\n- name: \"Nate Peel\"\n  github: \"\"\n  slug: \"nate-peel\"\n- name: \"Nate Ranson\"\n  github: \"\"\n  slug: \"nate-ranson\"\n- name: \"Nathaly Villamor\"\n  twitter: \"nathalyvillamor\"\n  github: \"jinara\"\n  website: \"https://www.linkedin.com/in/nathalyvillamor\"\n  slug: \"nathaly-villamor\"\n- name: \"Nathan Artz\"\n  github: \"\"\n  slug: \"nathan-artz\"\n- name: \"Nathan Beyer\"\n  github: \"\"\n  slug: \"nathan-beyer\"\n- name: \"Nathan Bibler\"\n  github: \"\"\n  slug: \"nathan-bibler\"\n- name: \"Nathan Esquenazi\"\n  github: \"nesquena\"\n  website: \"http://codepath.com\"\n  slug: \"nathan-esquenazi\"\n- name: \"Nathan Hessler\"\n  github: \"nhessler\"\n  slug: \"nathan-hessler\"\n- name: \"Nathan L Walls\"\n  github: \"\"\n  slug: \"nathan-l-walls\"\n- name: \"Nathan Ladd\"\n  github: \"ntl\"\n  slug: \"nathan-ladd\"\n- name: \"Nathan Long\"\n  github: \"nathanl\"\n  website: \"https://nathanmlong.com\"\n  slug: \"nathan-long\"\n- name: \"Nathan ODonnell\"\n  github: \"\"\n  slug: \"nathan-odonnell\"\n- name: \"Nathan OtheDev\"\n  github: \"\"\n  slug: \"nathan-othedev\"\n- name: \"Nathan Smith\"\n  github: \"\"\n  slug: \"nathan-smith\"\n- name: \"Nathan Sobo\"\n  github: \"\"\n  slug: \"nathan-sobo\"\n- name: \"Nathan Walls\"\n  twitter: \"base10\"\n  github: \"base10\"\n  website: \"http://wallscorp.us/\"\n  slug: \"nathan-walls\"\n- name: \"Nathan Witmer\"\n  github: \"\"\n  slug: \"nathan-witmer\"\n- name: \"Nathaniel Bibler\"\n  github: \"nbibler\"\n  website: \"https://twitter.com/nbibler\"\n  slug: \"nathaniel-bibler\"\n- name: \"Nathaniel Talbott\"\n  github: \"\"\n  slug: \"nathaniel-talbott\"\n- name: \"Nathen Harvey\"\n  twitter: \"nathenharvey\"\n  github: \"nathenharvey\"\n  website: \"http://nathenharvey.com\"\n  slug: \"nathen-harvey\"\n- name: \"Nathen Harvey and Nell Shamrell-Harrington\"\n  github: \"\"\n  slug: \"nathen-harvey-and-nell-shamrell-harrington\"\n- name: \"Natsuko Nadoyama\"\n  github: \"pndcat\"\n  slug: \"natsuko-nadoyama\"\n- name: \"Navarasu Muthu\"\n  github: \"\"\n  slug: \"navarasu-muthu\"\n- name: \"Neal Ford\"\n  github: \"\"\n  slug: \"neal-ford\"\n- name: \"Neal Kemp\"\n  github: \"\"\n  slug: \"neal-kemp\"\n- name: \"Neha Abraham\"\n  github: \"nehaabraham\"\n  slug: \"neha-abraham\"\n- name: \"Neha Batra\"\n  twitter: \"nerdneha\"\n  github: \"nerdneha\"\n  slug: \"neha-batra\"\n- name: \"Neil Carvalho\"\n  github: \"\"\n  slug: \"neil-carvalho\"\n- name: \"Neil Hendren\"\n  github: \"neiltheseal\"\n  slug: \"neil-hendren\"\n- name: \"Neil Manvar\"\n  github: \"ndmanvar\"\n  slug: \"neil-manvar\"\n- name: \"Neil McGovern\"\n  github: \"neilmcgovern\"\n  slug: \"neil-mcgovern\"\n- name: \"Neil Middleton\"\n  github: \"\"\n  slug: \"neil-middleton\"\n- name: \"Nell Shamrell\"\n  twitter: \"nellshamrell\"\n  github: \"nellshamrell\"\n  website: \"http://www.nellshamrell.com\"\n  slug: \"nell-shamrell\"\n- name: \"Nell Shamrell-Harrington\"\n  github: \"\"\n  slug: \"nell-shamrell-harrington\"\n- name: \"Nelson Elhage\"\n  github: \"nelhage\"\n  website: \"http://blog.nelhage.com\"\n  slug: \"nelson-elhage\"\n- name: \"Nelson Wittwer\"\n  github: \"\"\n  slug: \"nelson-wittwer\"\n- name: \"Nephi Johnson\"\n  github: \"\"\n  slug: \"nephi-johnson\"\n- name: \"Nerkar Dnyaneshwar\"\n  github: \"\"\n  slug: \"nerkar-dnyaneshwar\"\n- name: \"Netto Farah\"\n  twitter: \"nettofarah\"\n  github: \"nettofarah\"\n  website: \"https://getkoala.com\"\n  slug: \"netto-farah\"\n- name: \"New Relic -\"\n  github: \"\"\n  slug: \"new-relic\"\n- name: \"Ngan Pham\"\n  github: \"ngan\"\n  slug: \"ngan-pham\"\n- name: \"Nic Benders\"\n  github: \"\"\n  slug: \"nic-benders\"\n- name: \"Nicholas Audo\"\n  github: \"\"\n  slug: \"nicholas-audo\"\n- name: \"Nicholas Barone\"\n  github: \"\"\n  slug: \"nicholas-barone\"\n- name: \"Nicholas Henry\"\n  twitter: \"nicholasjhenry\"\n  github: \"nicholasjhenry\"\n  website: \"https://www.linkedin.com/in/nicholasjhenry/\"\n  slug: \"nicholas-henry\"\n- name: \"Nicholas Schlueter\"\n  github: \"\"\n  slug: \"nicholas-schlueter\"\n- name: \"Nicholas Simmons\"\n  github: \"\"\n  slug: \"nicholas-simmons\"\n- name: \"Nick Barone\"\n  twitter: \"syniba\"\n  github: \"nbar1\"\n  slug: \"nick-barone\"\n- name: \"Nick Carvalho\"\n  github: \"nickcarvalho\"\n  slug: \"nick-carvalho\"\n- name: \"Nick Charlton\"\n  github: \"nickcharlton\"\n  website: \"https://nickcharlton.net\"\n  slug: \"nick-charlton\"\n- name: \"Nick Flückiger\"\n  github: \"\"\n  slug: \"nick-fluckiger\"\n- name: \"Nick Gauthier\"\n  github: \"\"\n  slug: \"nick-gauthier\"\n- name: \"Nick Grysimov\"\n  github: \"\"\n  slug: \"nick-grysimov\"\n- name: \"Nick Howard\"\n  github: \"nickhow83\"\n  slug: \"nick-howard\"\n- name: \"Nick Kirkwood\"\n  github: \"\"\n  slug: \"nick-kirkwood\"\n- name: \"Nick Marden\"\n  github: \"\"\n  slug: \"nick-marden\"\n- name: \"Nick Means\"\n  github: \"\"\n  slug: \"nick-means\"\n- name: \"Nick Merwin\"\n  github: \"\"\n  slug: \"nick-merwin\"\n- name: \"Nick Muerdter\"\n  github: \"\"\n  slug: \"nick-muerdter\"\n- name: \"Nick Quaranto\"\n  twitter: \"qrush\"\n  github: \"qrush\"\n  website: \"http://quaran.to\"\n  slug: \"nick-quaranto\"\n- name: \"Nick Reavill\"\n  github: \"\"\n  slug: \"nick-reavill\"\n- name: \"Nick Schwaderer\"\n  twitter: \"schwad_rb\"\n  github: \"schwad\"\n  website: \"https://schwad.github.io\"\n  slug: \"nick-schwaderer\"\n- name: \"Nick Sieger\"\n  twitter: \"nicksieger\"\n  github: \"nicksieger\"\n  slug: \"nick-sieger\"\n- name: \"Nick Sutterer\"\n  twitter: \"apotonick\"\n  github: \"apotonick\"\n  website: \"http://trailblazer.to\"\n  slug: \"nick-sutterer\"\n- name: \"Nick Wolf\"\n  github: \"\"\n  slug: \"nick-wolf\"\n- name: \"Nickolas Means\"\n  twitter: \"nmeans\"\n  github: \"nmeans\"\n  website: \"https://nmeans.dev\"\n  slug: \"nickolas-means\"\n- name: \"Nicky Thompson\"\n  twitter: \"knotnicky\"\n  github: \"\"\n  website: \"https://www.knotnicky.com\"\n  slug: \"nicky-thompson\"\n- name: \"Nicolas Barone\"\n  github: \"nicbarone\"\n  website: \"https://tryuniverse.com\"\n  slug: \"nicolas-barone\"\n- name: \"Nicolas Barrera\"\n  github: \"nbarrera\"\n  slug: \"nicolas-barrera\"\n- name: \"Nicolas Dermine\"\n  github: \"nicoder\"\n  slug: \"nicolas-dermine\"\n- name: \"Nicolas Dular\"\n  github: \"\"\n  slug: \"nicolas-dular\"\n- name: \"Nicolas Erlichman\"\n  github: \"nerlichman\"\n  slug: \"nicolas-erlichman\"\n- name: \"Nicolas Mérouze\"\n  github: \"\"\n  slug: \"nicolas-merouze\"\n- name: \"Nicolas Zermati\"\n  github: \"nicoolas25\"\n  website: \"https://n.zermati.eu\"\n  slug: \"nicolas-zermati\"\n- name: \"Nicole Carpenter\"\n  github: \"nicolecarpenter\"\n  slug: \"nicole-carpenter\"\n- name: \"Nicole Lopez\"\n  github: \"\"\n  slug: \"nicole-lopez\"\n- name: \"Nicolás Buero\"\n  github: \"nicolasvb23\"\n  slug: \"nicolas-buero\"\n- name: \"Nicolás Cerrini\"\n  github: \"\"\n  slug: \"nicolas-cerrini\"\n- name: \"Nicolás Hock\"\n  github: \"\"\n  slug: \"nicolas-hock\"\n- name: \"Nicolás Sanguinetti\"\n  github: \"\"\n  slug: \"nicolas-sanguinetti\"\n- name: \"Nicolás Sztabzyb\"\n  github: \"\"\n  slug: \"nicolas-sztabzyb\"\n- name: \"Nicolò Rebughini\"\n  github: \"nirebu\"\n  slug: \"nicolo-rebughini\"\n- name: \"Nigel Rausch\"\n  github: \"\"\n  slug: \"nigel-rausch\"\n- name: \"Nikita Vasilevsky\"\n  github: \"nvasilevski\"\n  slug: \"nikita-vasilevsky\"\n- name: \"Nikki Murray\"\n  github: \"\"\n  slug: \"nikki-murray\"\n- name: \"Nikkie\"\n  github: \"ftnext\"\n  slug: \"nikkie\"\n- name: \"Nikky Southerland\"\n  github: \"\"\n  slug: \"nikky-southerland\"\n- name: \"Niklas Hofer\"\n  github: \"\"\n  slug: \"niklas-hofer\"\n- name: \"Nikola Jichev\"\n  github: \"njichev\"\n  slug: \"nikola-jichev\"\n- name: \"Nikolai Ryzhikov\"\n  github: \"\"\n  slug: \"nikolai-ryzhikov\"\n- name: \"Nikolay Bienko\"\n  github: \"\"\n  slug: \"nikolay-bienko\"\n- name: \"Nikolay Nemshilov\"\n  github: \"\"\n  slug: \"nikolay-nemshilov\"\n- name: \"Nikolay Sverchkov\"\n  github: \"\"\n  slug: \"nikolay-sverchkov\"\n- name: \"Nils Löwe\"\n  github: \"\"\n  slug: \"nils-lowe\"\n- name: \"Nina Siessegger\"\n  github: \"sssggr\"\n  website: \"https://ninasiessegger.de\"\n  slug: \"nina-siessegger\"\n- name: \"Niranjan Paranjape\"\n  github: \"\"\n  slug: \"niranjan-paranjape\"\n- name: \"Nishant Modak\"\n  github: \"\"\n  slug: \"nishant-modak\"\n- name: \"Nitie Sharma\"\n  github: \"\"\n  slug: \"nitie-sharma\"\n- name: \"Nitin Dhaware\"\n  github: \"nitinzd\"\n  website: \"http://www.ndinfotronics.com\"\n  slug: \"nitin-dhaware\"\n- name: \"Nitish Rathi\"\n  github: \"\"\n  slug: \"nitish-rathi\"\n- name: \"Njonge Fred\"\n  github: \"\"\n  slug: \"njonge-fred\"\n- name: \"Noah Berman\"\n  github: \"\"\n  slug: \"noah-berman\"\n- name: \"Noah Durbin\"\n  github: \"\"\n  slug: \"noah-durbin\"\n- name: \"Noah Gibbs\"\n  github: \"noahgibbs\"\n  website: \"https://codefol.io\"\n  slug: \"noah-gibbs\"\n- name: \"Noah Matisoff\"\n  github: \"noahmatisoff\"\n  website: \"https://github.com/noahmatisoff\"\n  slug: \"noah-matisoff\"\n- name: \"Noah Zoschke\"\n  github: \"\"\n  slug: \"noah-zoschke\"\n- name: \"Nobert Wójtowicz\"\n  github: \"\"\n  slug: \"nobert-wojtowicz\"\n- name: \"Nobuyoshi Nakada\"\n  twitter: \"n0kada\"\n  github: \"nobu\"\n  slug: \"nobuyoshi-nakada\"\n- name: \"Nobuyuki Honda\"\n  github: \"nobyuki\"\n  slug: \"nobuyuki-honda\"\n- name: \"Noel Rappin\"\n  github: \"noelrappin\"\n  website: \"http://www.noelrappin.com\"\n  slug: \"noel-rappin\"\n- name: \"Noelia Cabane\"\n  github: \"\"\n  slug: \"noelia-cabane\"\n- name: \"Nora Howard\"\n  github: \"\"\n  slug: \"nora-howard\"\n- name: \"Norbert Wójtowicz\"\n  github: \"pithyless\"\n  website: \"http://twitter.com/pithyless\"\n  slug: \"norbert-wojtowicz\"\n  aliases:\n    - name: \"Norbert Wojtowicz\"\n      slug: \"norbert-wojtowicz\"\n- name: \"Norma Medrano\"\n  github: \"\"\n  slug: \"norma-medrano\"\n- name: \"Norma Miller\"\n  github: \"\"\n  slug: \"norma-miller\"\n- name: \"Norman Clarke\"\n  github: \"\"\n  slug: \"norman-clarke\"\n- name: \"Nuno Silva\"\n  github: \"\"\n  slug: \"nuno-silva\"\n- name: \"Nynne Just Christoffersen\"\n  github: \"nynnejc\"\n  website: \"http://nynnechristoffersen.com/\"\n  slug: \"nynne-just-christoffersen\"\n- name: \"Obie Fernandez\"\n  twitter: \"obie\"\n  github: \"obie\"\n  website: \"http://obiefernandez.com\"\n  slug: \"obie-fernandez\"\n- name: \"ODA Hirohito\"\n  github: \"jinroq\"\n  slug: \"oda-hirohito\"\n  aliases:\n    - name: \"oda-i3\"\n      slug: \"oda-i3\"\n- name: \"Odin Dutton\"\n  github: \"\"\n  slug: \"odin-dutton\"\n- name: \"Okan Davut\"\n  github: \"okandavut\"\n  slug: \"okan-davut\"\n- name: \"okkez\"\n  github: \"\"\n  slug: \"okkez\"\n- name: \"OKURA Masafumi\"\n  twitter: \"okuramasafumi\"\n  github: \"okuramasafumi\"\n  website: \"https://okuramasafumi.com\"\n  slug: \"okura-masafumi\"\n  aliases:\n    - name: \"Masafumi Okura\"\n      slug: \"masafumi-okura\"\n- name: \"Ola Bini\"\n  github: \"\"\n  slug: \"ola-bini\"\n- name: \"Ole Michaelis\"\n  twitter: \"OleMchls\"\n  github: \"olemchls\"\n  website: \"https://ole.mchls.works\"\n  slug: \"ole-michaelis\"\n- name: \"Oleksiy Vasyliev\"\n  github: \"\"\n  slug: \"oleksiy-vasyliev\"\n- name: \"Olga Goloshapova\"\n  github: \"\"\n  slug: \"olga-goloshapova\"\n- name: \"Olga Scott\"\n  twitter: \"olga_scott\"\n  github: \"olgascott\"\n  slug: \"olga-scott\"\n- name: \"Oliver Morgan\"\n  github: \"\"\n  slug: \"oliver-morgan\"\n- name: \"Oliver Sanford\"\n  github: \"oliverjesse\"\n  slug: \"oliver-sanford\"\n- name: \"Olivia Brundage\"\n  twitter: \"oliikit\"\n  github: \"oliikit\"\n  website: \"https://oliikit.dev\"\n  slug: \"olivia-brundage\"\n- name: \"Olivier Lacan\"\n  github: \"olivierlacan\"\n  website: \"http://olivierlacan.com\"\n  slug: \"olivier-lacan\"\n  aliases:\n    - name: \"Oliver Lacan\"\n      slug: \"oliver-lacan\"\n- name: \"Olivier Robert\"\n  github: \"olivierobert\"\n  website: \"https://olivierobert.com\"\n  slug: \"olivier-robert\"\n- name: \"Olle Jonsson\"\n  github: \"olleolleolle\"\n  slug: \"olle-jonsson\"\n- name: \"Olly Headey\"\n  github: \"lylo\"\n  website: \"https://olly.world\"\n  slug: \"olly-headey\"\n- name: \"Olya Boiaryntseva\"\n  github: \"\"\n  slug: \"olya-boiaryntseva\"\n- name: \"Omar\"\n  github: \"omar\"\n  website: \"http://omar.io\"\n  slug: \"omar\"\n- name: \"Omowale Oniyide\"\n  github: \"ladyoniyide\"\n  website: \"http://twitter.com/ladyoniyide\"\n  slug: \"omowale-oniyide\"\n- name: \"Ondřej Bartas\"\n  github: \"ondrejbartas\"\n  website: \"http://www.bartas.cz\"\n  slug: \"ondrej-bartas\"\n- name: \"Ontra\"\n  github: \"ontra-ai\"\n  website: \"https://ontra.ai\"\n  slug: \"ontra\"\n- name: \"Onur Ozer\"\n  github: \"onurozer\"\n  website: \"https://onurozer.me\"\n  slug: \"onur-ozer\"\n  aliases:\n    - name: \"Onur Özer\"\n      slug: \"onur-oezer\"\n- name: \"Ori Pekelman\"\n  github: \"OriPekelman\"\n  website: \"https://pekelman.com\"\n  slug: \"ori-pekelman\"\n- name: \"Osama Yu\"\n  github: \"\"\n  slug: \"osama-yu\"\n- name: \"Oscar Rendón\"\n  github: \"\"\n  slug: \"oscar-rendon\"\n- name: \"Oskar Lakner\"\n  github: \"oskarlakner\"\n  slug: \"oskar-lakner\"\n- name: \"Oskar Szrajer\"\n  twitter: \"oskarszrajer\"\n  github: \"gotar\"\n  website: \"http://gotar.info\"\n  slug: \"oskar-szrajer\"\n- name: \"Ostap Cherkashin\"\n  github: \"\"\n  slug: \"ostap-cherkashin\"\n- name: \"osyo-manga\"\n  github: \"osyo-manga\"\n  website: \"http://secret-garden.hatenablog.com/\"\n  slug: \"osyo\"\n- name: \"ota42y\"\n  github: \"ota42y\"\n  website: \"http://ota42y.com/\"\n  slug: \"ota42y\"\n- name: \"Pablo Astigarraga\"\n  github: \"\"\n  slug: \"pablo-astigarraga\"\n- name: \"Pablo Brasero\"\n  github: \"pablobm\"\n  website: \"https://www.pablobm.com/\"\n  slug: \"pablo-brasero\"\n- name: \"Pablo Curell Mompo\"\n  github: \"\"\n  slug: \"pablo-curell-mompo\"\n- name: \"Pablo Dejuan\"\n  github: \"pdjota\"\n  slug: \"pablo-dejuan\"\n  aliases:\n    - name: \"Pablo Dejuan Calzolari\"\n      slug: \"pablo-dejuan-calzolari\"\n- name: \"Pablo Duran\"\n  github: \"\"\n  slug: \"pablo-duran\"\n- name: \"Pallavi Shastry\"\n  github: \"\"\n  slug: \"pallavi-shastry\"\n- name: \"Pamela Assogba\"\n  github: \"pam-\"\n  slug: \"pamela-assogba\"\n- name: \"Pamela O. Vickers\"\n  github: \"pwnela\"\n  slug: \"pamela-o-vickers\"\n  aliases:\n    - name: \"Pamela Vickers\"\n      slug: \"pamela-vickers\"\n- name: \"Pamela Pavliscak\"\n  github: \"\"\n  slug: \"pamela-pavliscak\"\n- name: \"Pan Thomakos\"\n  twitter: \"panthomakos\"\n  github: \"panthomakos\"\n  website: \"https://ablogaboutcode.com\"\n  slug: \"pan-thomakos\"\n  aliases:\n    - name: \"Panayiotis Thomakos\"\n      slug: \"panayiotis-thomakos\"\n- name: \"Panos Matsinopoulos\"\n  github: \"\"\n  slug: \"panos-matsinopoulos\"\n- name: \"Paola Moretto\"\n  github: \"\"\n  slug: \"paola-moretto\"\n- name: \"Paolo \\\"Nusco\\\" Perrotta\"\n  github: \"nusco\"\n  website: \"http://ducktypo.blogspot.com\"\n  slug: \"paolo-nusco-perrotta\"\n  aliases:\n    - name: \"Paolo Perrotta\"\n      slug: \"paolo-perrotta\"\n- name: \"Paolo Fabbri\"\n  github: \"\"\n  slug: \"paolo-fabbri\"\n- name: \"Paolo Montrasio\"\n  github: \"pmontrasio\"\n  website: \"http://ilconnettivo.wordpress.com/\"\n  slug: \"paolo-montrasio\"\n- name: \"Parham Ashraf\"\n  github: \"\"\n  slug: \"parham-ashraf\"\n- name: \"Parker Moore\"\n  github: \"parkr\"\n  website: \"https://byparker.com\"\n  slug: \"parker-moore\"\n- name: \"Pascal Zumkehr\"\n  github: \"codez\"\n  website: \"http://codez.ch\"\n  slug: \"pascal-zumkehr\"\n- name: \"Pasta-K\"\n  github: \"pastak\"\n  slug: \"pastak\"\n  aliases:\n    - name: \"pastak\"\n      slug: \"pastak\"\n- name: \"Pat Allan\"\n  twitter: \"pat\"\n  github: \"pat\"\n  website: \"https://freelancing-gods.com\"\n  slug: \"pat-allan\"\n- name: \"Pat Allen\"\n  twitter: \"layer8packet\"\n  github: \"pallen182\"\n  website: \"https://breakingbytespod.io\"\n  slug: \"pat-allen\"\n- name: \"Pat Eyler\"\n  github: \"\"\n  slug: \"pat-eyler\"\n- name: \"Pat Maddox\"\n  github: \"\"\n  slug: \"pat-maddox\"\n- name: \"Pat Nakajima\"\n  github: \"nakajima\"\n  website: \"https://patstechweblog.com\"\n  slug: \"pat-nakajima\"\n- name: \"Pat Saughnessy\"\n  github: \"\"\n  slug: \"pat-saughnessy\"\n- name: \"Pat Shaughnessy\"\n  github: \"patshaughnessy\"\n  website: \"http://patshaughnessy.net\"\n  slug: \"pat-shaughnessy\"\n- name: \"Patel Alun\"\n  github: \"\"\n  slug: \"patel-alun\"\n- name: \"Patricia Cupueran\"\n  github: \"\"\n  slug: \"patricia-cupueran\"\n- name: \"Patricio Bruna\"\n  github: \"\"\n  slug: \"patricio-bruna\"\n- name: \"Patricio Mac Adden\"\n  github: \"\"\n  slug: \"patricio-mac-adden\"\n- name: \"Patrick Farley\"\n  github: \"\"\n  slug: \"patrick-farley\"\n- name: \"Patrick Franken\"\n  github: \"\"\n  slug: \"patrick-franken\"\n- name: \"Patrick Helm\"\n  twitter: \"htwk_pat\"\n  github: \"deradon\"\n  website: \"https://ruby.social/@deradon\"\n  slug: \"patrick-helm\"\n- name: \"Patrick Huesler\"\n  github: \"\"\n  slug: \"patrick-huesler\"\n- name: \"Patrick Joyce\"\n  github: \"keeperpat\"\n  website: \"http://pragmati.st\"\n  slug: \"patrick-joyce\"\n- name: \"Patrick Leonard\"\n  twitter: \"pj_leonard\"\n  github: \"pjleonard37\"\n  website: \"https://www.patrick-leonard.com\"\n  slug: \"patrick-leonard\"\n- name: \"Patrick McKenzie\"\n  twitter: \"patio11\"\n  github: \"patio11\"\n  website: \"http://www.kalzumeus.com\"\n  slug: \"patrick-mckenzie\"\n- name: \"Patrick McSweeny\"\n  github: \"\"\n  slug: \"patrick-mcsweeny\"\n- name: \"Patrick Mulder\"\n  github: \"mulderp\"\n  website: \"http://thinkingonthinking.com\"\n  slug: \"patrick-mulder\"\n- name: \"Patrick Peak\"\n  github: \"\"\n  slug: \"patrick-peak\"\n- name: \"Patrick Robertson\"\n  github: \"patricksrobertson\"\n  website: \"http://adequate.io\"\n  slug: \"patrick-robertson\"\n- name: \"Patrick Wendo\"\n  github: \"\"\n  slug: \"patrick-wendo\"\n- name: \"Patrik Ragnarsson\"\n  github: \"dentarg\"\n  slug: \"patrik-ragnarsson\"\n- name: \"Patrik Sopran\"\n  github: \"de-sopi\"\n  slug: \"patrik-sopran\"\n- name: \"Patryk Pastewski\"\n  github: \"\"\n  slug: \"patryk-pastewski\"\n- name: \"Patryk Ptasiński\"\n  github: \"ipepe\"\n  website: \"http://www.ipepe.pl/\"\n  slug: \"patryk-ptasinski\"\n- name: \"Paul Bahr\"\n  github: \"paulbahr\"\n  slug: \"paul-bahr\"\n- name: \"Paul Battley\"\n  github: \"threedaymonk\"\n  website: \"http://po-ru.com/\"\n  slug: \"paul-battley\"\n- name: \"Paul Biggar\"\n  github: \"\"\n  slug: \"paul-biggar\"\n- name: \"Paul Brannan\"\n  github: \"\"\n  slug: \"paul-brannan\"\n- name: \"Paul Campbell\"\n  github: \"\"\n  slug: \"paul-campbell\"\n- name: \"Paul Dawson\"\n  github: \"piisalie\"\n  website: \"http://cannot.into.computer\"\n  slug: \"paul-dawson\"\n- name: \"Paul Dix\"\n  twitter: \"pauldix\"\n  github: \"pauldix\"\n  slug: \"paul-dix\"\n- name: \"Paul Elliott\"\n  github: \"paulelliott\"\n  slug: \"paul-elliott\"\n- name: \"Paul Fioravanti\"\n  github: \"\"\n  slug: \"paul-fioravanti\"\n- name: \"Paul Gabriel\"\n  github: \"\"\n  slug: \"paul-gabriel\"\n- name: \"Paul Gallagher\"\n  github: \"\"\n  slug: \"paul-gallagher\"\n- name: \"Paul Gross\"\n  github: \"pgr0ss\"\n  website: \"http://www.pgrs.net\"\n  slug: \"paul-gross\"\n- name: \"Paul Hinze\"\n  github: \"\"\n  slug: \"paul-hinze\"\n- name: \"Paul Hoffer\"\n  github: \"phoffer\"\n  website: \"https://paulhoffer.com\"\n  slug: \"paul-hoffer\"\n- name: \"Paul Joe George\"\n  github: \"\"\n  slug: \"paul-joe-george\"\n- name: \"Paul Lahana\"\n  github: \"paultursuru\"\n  slug: \"paul-lahana\"\n- name: \"Paul Lamere\"\n  github: \"\"\n  slug: \"paul-lamere\"\n- name: \"Paul Lemus\"\n  github: \"helpotters\"\n  website: \"https://helpotters.com\"\n  slug: \"paul-lemus\"\n- name: \"Paul Martensen\"\n  github: \"haniyya\"\n  slug: \"paul-martensen\"\n- name: \"Paul Pagel\"\n  github: \"\"\n  slug: \"paul-pagel\"\n- name: \"Paul Reece\"\n  github: \"paulreece42\"\n  website: \"https://paulreece.com\"\n  slug: \"paul-reece\"\n- name: \"Paul Sadauskas\"\n  twitter: \"theamazingrando\"\n  github: \"paul\"\n  website: \"http://blog.theamazingrando.com\"\n  slug: \"paul-sadauskas\"\n- name: \"Paul smith\"\n  github: \"\"\n  slug: \"paul-smith\"\n- name: \"Paul Stefan Ort\"\n  twitter: \"PaulStefanOrt\"\n  github: \"PaulStefanOrt\"\n  slug: \"paul-stefan-ort\"\n- name: \"Paul Tagell\"\n  github: \"\"\n  slug: \"paul-tagell\"\n- name: \"Paul Tarjan\"\n  twitter: \"ptarjan\"\n  github: \"ptarjan\"\n  website: \"http://paultarjan.com\"\n  slug: \"paul-tarjan\"\n- name: \"Paul Zaich\"\n  github: \"pzaich\"\n  website: \"http://paulzaich.com\"\n  slug: \"paul-zaich\"\n- name: \"Paul-Armand Assus\"\n  github: \"\"\n  slug: \"paul-armand-assus\"\n- name: \"Paula Muldoon\"\n  github: \"\"\n  slug: \"paula-muldoon\"\n- name: \"Paulette Luftig\"\n  github: \"\"\n  slug: \"paulette-luftig\"\n- name: \"Pauline Rousset\"\n  github: \"\"\n  slug: \"pauline-rousset\"\n- name: \"Pavan Sudarshan\"\n  github: \"itspanzi\"\n  twitter: \"pavanks\"\n  slug: \"pavan-sudarshan\"\n- name: \"Paweł Dąbrowski\"\n  twitter: \"pdabrowski6\"\n  github: \"pdabrowski6\"\n  website: \"https://paweldabrowski.com\"\n  slug: \"pawel-dabrowski\"\n- name: \"Paweł Pacana\"\n  twitter: \"mostlyobvious\"\n  github: \"mostlyobvious\"\n  website: \"https://mostlyobvio.us\"\n  slug: \"pawel-pacana\"\n- name: \"Paweł Pokrywka\"\n  github: \"pepawel\"\n  website: \"https://blog.pawelpokrywka.com\"\n  slug: \"pawel-pokrywka\"\n- name: \"Paweł Strzałkowski\"\n  twitter: \"realPawelS\"\n  github: \"pstrzalk\"\n  slug: \"pawel-strzalkowski\"\n- name: \"Paweł Świątkowski\"\n  twitter: \"katafrakt_pl\"\n  github: \"katafrakt\"\n  website: \"https://katafrakt.me\"\n  slug: \"pawel-swiatkowski\"\n- name: \"Pedro Augusto Ramalho Duarte\"\n  github: \"PedroAugustoRamalhoDuarte\"\n  slug: \"pedro-augusto-ramalho-duarte\"\n- name: \"Pedro Belo\"\n  twitter: \"ped\"\n  github: \"pedro\"\n  slug: \"pedro-belo\"\n- name: \"Pedro Morte Rolo\"\n  github: \"\"\n  slug: \"pedro-morte-rolo\"\n- name: \"Pedro Schmitt\"\n  twitter: \"pedroschm\"\n  github: \"\"\n  slug: \"pedro-schmitt\"\n- name: \"Pete Forde\"\n  github: \"peteforde\"\n  slug: \"pete-forde\"\n- name: \"Pete Higgins\"\n  github: \"\"\n  slug: \"pete-higgins\"\n- name: \"Pete Hodgson\"\n  twitter: \"ph1\"\n  github: \"moredip\"\n  website: \"https://thepete.net\"\n  slug: \"pete-hodgson\"\n- name: \"Pete Holiday\"\n  github: \"toomuchpete\"\n  website: \"http://www.peteholiday.com\"\n  slug: \"pete-holiday\"\n- name: \"Peter Aitken\"\n  github: \"JiggyPete\"\n  slug: \"peter-aitken\"\n- name: \"Peter Bell\"\n  github: \"\"\n  slug: \"peter-bell\"\n- name: \"Peter Bhat Harkins\"\n  github: \"pushcx\"\n  website: \"https://push.cx\"\n  slug: \"peter-bhat-harkins\"\n  aliases:\n    - name: \"Peter Harkins\"\n      slug: \"peter-harkins\"\n- name: \"Peter Degen\"\n  github: \"\"\n  slug: \"peter-degen\"\n- name: \"Peter Evjan\"\n  github: \"\"\n  slug: \"peter-evjan\"\n- name: \"Peter Jaros\"\n  github: \"\"\n  slug: \"peter-jaros\"\n- name: \"Peter Philips\"\n  github: \"synth\"\n  slug: \"peter-philips\"\n- name: \"Peter Ramm\"\n  github: \"\"\n  slug: \"peter-ramm\"\n- name: \"Peter Saxton\"\n  github: \"\"\n  slug: \"peter-saxton\"\n- name: \"Peter Scholz\"\n  github: \"lefnord\"\n  slug: \"peter-scholz\"\n- name: \"Peter Shanley\"\n  github: \"\"\n  slug: \"peter-shanley\"\n- name: \"Peter Szinek\"\n  github: \"scrubber\"\n  website: \"http://www.rubyrailways.com\"\n  slug: \"peter-szinek\"\n- name: \"Peter Zhu\"\n  twitter: \"peterzhu2118\"\n  github: \"peterzhu2118\"\n  website: \"https://peterzhu.ca\"\n  slug: \"peter-zhu\"\n- name: \"Petr Chalupa\"\n  github: \"pitr-ch\"\n  slug: \"petr-chalupa\"\n- name: \"phigasui\"\n  twitter: \"phigasui\"\n  github: \"phigasui\"\n  website: \"https://phigasui.com\"\n  slug: \"phigasui\"\n- name: \"Phil Crissman\"\n  github: \"philcrissman\"\n  website: \"http://philcrissman.net\"\n  slug: \"phil-crissman\"\n- name: \"Phil Hagelberg\"\n  github: \"\"\n  slug: \"phil-hagelberg\"\n- name: \"Phil Matarese\"\n  github: \"\"\n  slug: \"phil-matarese\"\n- name: \"Phil Nash\"\n  twitter: \"philnash\"\n  github: \"philnash\"\n  website: \"https://philna.sh\"\n  slug: \"phil-nash\"\n- name: \"Phil Sturgeon\"\n  github: \"\"\n  slug: \"phil-sturgeon\"\n- name: \"Phil Toland\"\n  github: \"\"\n  slug: \"phil-toland\"\n- name: \"Philip Arndt\"\n  github: \"\"\n  slug: \"philip-arndt\"\n- name: \"Philip Poots\"\n  github: \"pootsbook\"\n  slug: \"philip-poots\"\n- name: \"Philip Szalwinski\"\n  github: \"\"\n  slug: \"philip-szalwinski\"\n- name: \"Philipp Tessenow\"\n  twitter: \"philipptessenow\"\n  github: \"tessi\"\n  website: \"https://tessenow.org\"\n  slug: \"philipp-tessenow\"\n- name: \"Philippe Creux\"\n  twitter: \"pcreux\"\n  github: \"pcreux\"\n  website: \"https://pcreux.com\"\n  slug: \"philippe-creux\"\n- name: \"Philippe Hanrigou\"\n  github: \"\"\n  slug: \"philippe-hanrigou\"\n- name: \"Phill MV\"\n  github: \"phillmv\"\n  website: \"http://okayfail.com\"\n  slug: \"phill-mv\"\n- name: \"Phillip Ante\"\n  github: \"\"\n  slug: \"phillip-ante\"\n- name: \"Phillip Campbell\"\n  github: \"\"\n  slug: \"phillip-campbell\"\n- name: \"Pierluigi Riti\"\n  github: \"pierluigiriti2\"\n  slug: \"pierluigi-riti\"\n- name: \"Pierre de Milly\"\n  github: \"\"\n  slug: \"pierre-de-milly\"\n- name: \"Pierre-Alexandre Pierulli\"\n  github: \"\"\n  slug: \"pierre-alexandre-pierulli\"\n- name: \"Pierre-Emmanuel Daigre\"\n  github: \"\"\n  slug: \"pierre-emmanuel-daigre\"\n- name: \"Pieter Lange\"\n  github: \"\"\n  slug: \"pieter-lange\"\n- name: \"Pieterjan Muller\"\n  github: \"\"\n  slug: \"pieterjan-muller\"\n- name: \"Pilar Andrea Huidobro Peltier\"\n  twitter: \"tamacodechi\"\n  github: \"tamacodechi\"\n  website: \"https://www.pilar.codes\"\n  slug: \"pilar-andrea-huidobro-peltier\"\n  aliases:\n    - name: \"Pilar Huidobro\"\n      slug: \"pilar-huidobro\"\n- name: \"Piotr Misiurek\"\n  github: \"\"\n  slug: \"piotr-misiurek\"\n- name: \"Piotr Murach\"\n  twitter: \"piotr_murach\"\n  github: \"piotrmurach\"\n  website: \"https://piotrmurach.com\"\n  slug: \"piotr-murach\"\n- name: \"Piotr Niełacny\"\n  github: \"lte\"\n  slug: \"piotr-nielacny\"\n- name: \"Piotr Sarnacki\"\n  twitter: \"drogus\"\n  github: \"drogus\"\n  website: \"https://itsallaboutthebit.com/\"\n  slug: \"piotr-sarnacki\"\n- name: \"Piotr Solnica\"\n  github: \"solnic\"\n  slug: \"piotr-solnica\"\n  aliases:\n    - name: \"Peter Solnica\"\n      slug: \"peter-solnica\"\n- name: \"Piotr Steininger\"\n  github: \"psteininger\"\n  website: \"http://piotrsteininger.com\"\n  slug: \"piotr-steininger\"\n- name: \"Piotr Szmielew\"\n  github: \"esse\"\n  website: \"http://piotr.szmielew.pl\"\n  slug: \"piotr-szmielew\"\n- name: \"Piotr Szotkowski\"\n  github: \"chastell\"\n  website: \"http://chastell.net\"\n  slug: \"piotr-szotkowski\"\n- name: \"Piotr Vestragowski\"\n  github: \"\"\n  slug: \"piotr-vestragowski\"\n- name: \"Piotr Wald\"\n  github: \"piotrwald\"\n  slug: \"piotr-wald\"\n- name: \"Piotr Walkowski\"\n  github: \"walu2\"\n  website: \"https://deluxe-soft.com\"\n  slug: \"piotr-walkowski\"\n- name: \"Piotr Witek\"\n  twitter: \"ppwitek\"\n  github: \"piowit\"\n  slug: \"piotr-witek\"\n- name: \"Piotr Włodarek\"\n  github: \"qertoip\"\n  website: \"https://qertoip.com\"\n  slug: \"piotr-wlodarek\"\n- name: \"Piotr Zolnierek\"\n  github: \"pzol\"\n  website: \"https://about.me/piotrzolnierek\"\n  slug: \"piotr-zolnierek\"\n- name: \"Piotrek Zientara\"\n  github: \"\"\n  slug: \"piotrek-zientara\"\n- name: \"Pitor Wasiak\"\n  github: \"\"\n  slug: \"pitor-wasiak\"\n- name: \"PJ Davis\"\n  github: \"\"\n  slug: \"pj-davis\"\n- name: \"PJ Hagerty\"\n  github: \"aspleenic\"\n  slug: \"pj-hagerty\"\n  aliases:\n    - name: \"Pj Hargety\"\n      slug: \"pj-hargety\"\n- name: \"PJ Heyett\"\n  github: \"\"\n  slug: \"pj-heyett\"\n- name: \"PJ Johnstone\"\n  github: \"\"\n  slug: \"pj-johnstone\"\n- name: \"Polly Schandorf\"\n  github: \"pollygee\"\n  slug: \"polly-schandorf\"\n- name: \"Pote\"\n  github: \"\"\n  slug: \"pote\"\n- name: \"Prabin Poudel\"\n  twitter: \"coolprobn\"\n  github: \"coolprobn\"\n  website: \"https://prabinpoudel.com.np\"\n  slug: \"prabin-poudel\"\n- name: \"Pradeep Elankumaran\"\n  twitter: \"pradeep24\"\n  github: \"skyfallsin\"\n  slug: \"pradeep-elankumaran\"\n- name: \"Prakash Murthy\"\n  github: \"\"\n  slug: \"prakash-murthy\"\n- name: \"Prakriti Gupta\"\n  github: \"prakriti-nith\"\n  slug: \"prakriti-gupta\"\n- name: \"Prakriti Mateti\"\n  github: \"itirkarp\"\n  slug: \"prakriti-mateti\"\n- name: \"Pramod Shinde\"\n  github: \"\"\n  slug: \"pramod-shinde\"\n- name: \"Pranav Garg\"\n  twitter: \"pgtgrly\"\n  github: \"pgtgrly\"\n  website: \"https://pranavgarg.in\"\n  slug: \"pranav-garg\"\n- name: \"Prarthana Shiva\"\n  twitter: \"prarthanas\"\n  github: \"prarthanashiva15\"\n  slug: \"prarthana-shiva\"\n- name: \"Prashant Throughout\"\n  github: \"\"\n  slug: \"prashant-throughout\"\n- name: \"Prasun Anand\"\n  github: \"prasunanand\"\n  website: \"http://prasunanand.com\"\n  slug: \"prasun-anand\"\n- name: \"Prateek Choudhary\"\n  github: \"\"\n  slug: \"prateek-choudhary\"\n- name: \"Prateek Dayal\"\n  github: \"\"\n  slug: \"prateek-dayal\"\n- name: \"Prathamesh S\"\n  github: \"\"\n  slug: \"prathamesh-s\"\n- name: \"Prathamesh Sonpatki\"\n  twitter: \"prathamesh2_\"\n  github: \"prathamesh-sonpatki\"\n  website: \"https://docs.last9.io\"\n  slug: \"prathamesh-sonpatki\"\n- name: \"Prathana Shiva\"\n  github: \"\"\n  slug: \"prathana-shiva\"\n- name: \"Prathmesh Ranaut\"\n  github: \"\"\n  slug: \"prathmesh-ranaut\"\n- name: \"Pratvrirash\"\n  github: \"\"\n  slug: \"pratvrirash\"\n- name: \"Prem Sichanugrist\"\n  github: \"sikachu\"\n  website: \"https://sikac.hu\"\n  slug: \"prem-sichanugrist\"\n- name: \"Prepsa Kayastha\"\n  github: \"\"\n  slug: \"prepsa-kayastha\"\n- name: \"Preston Lee\"\n  github: \"\"\n  slug: \"preston-lee\"\n- name: \"Przemysław Kowalczyk\"\n  github: \"\"\n  slug: \"przemyslaw-kowalczyk\"\n- name: \"Puneet Khushwani\"\n  github: \"puneet-khushwani-eth\"\n  website: \"https://www.coupa.com/\"\n  slug: \"puneet-khushwani\"\n- name: \"Purity Maina\"\n  github: \"\"\n  slug: \"purity-maina\"\n- name: \"Qiwei Lin\"\n  github: \"kiwi-x-kiwi\"\n  slug: \"qiwei-lin\"\n- name: \"Quentin Godfroy\"\n  github: \"conscritneuneu\"\n  slug: \"quentin-godfroy\"\n- name: \"Quinn Stearns\"\n  github: \"qstearns\"\n  slug: \"quinn-stearns\"\n- name: \"Ra'Shaun Stovall\"\n  github: \"\"\n  slug: \"ra-shaun-stovall\"\n- name: \"Rachael Wright-Munn\"\n  twitter: \"chaelcodes\"\n  github: \"chaelcodes\"\n  website: \"https://www.chael.codes\"\n  slug: \"rachael-wright-munn\"\n- name: \"Rachel Bingham\"\n  github: \"\"\n  slug: \"rachel-bingham\"\n- name: \"Rachel Green\"\n  github: \"rlgreen91\"\n  slug: \"rachel-green\"\n- name: \"Rachel Mathew\"\n  github: \"ronarachel\"\n  slug: \"rachel-mathew\"\n- name: \"Rachel Myers\"\n  twitter: \"rachelmyers\"\n  github: \"rachelmyers\"\n  website: \"https://rachelmyers.github.io\"\n  slug: \"rachel-myers\"\n- name: \"Rachel Serwetz\"\n  github: \"\"\n  slug: \"rachel-serwetz\"\n- name: \"Rachel Warbelow\"\n  github: \"rwarbelow\"\n  slug: \"rachel-warbelow\"\n- name: \"Radamanthus Batnag\"\n  github: \"\"\n  slug: \"radamanthus-batnag\"\n- name: \"Radamés Roriz\"\n  twitter: \"radamesroriz\"\n  github: \"roriz\"\n  website: \"https://roriz.dev\"\n  slug: \"radames-roriz\"\n- name: \"Radan Skorić\"\n  twitter: \"RadanSkoric\"\n  github: \"radanskoric\"\n  website: \"https://radanskoric.com/\"\n  slug: \"radan-skoric\"\n- name: \"Radoslav Stankov\"\n  twitter: \"rstankov\"\n  github: \"rstankov\"\n  website: \"https://rstankov.com\"\n  slug: \"radoslav-stankov\"\n- name: \"Rae Stanton\"\n  github: \"rae-stanton\"\n  slug: \"rae-stanton\"\n- name: \"Rafael Mendonça França\"\n  twitter: \"rafaelfranca\"\n  github: \"rafaelfranca\"\n  slug: \"rafael-mendonca-franca\"\n  aliases:\n    - name: \"Rafael França\"\n      slug: \"rafael-franca\"\n    - name: \"Rafael Franca\"\n      slug: \"rafael-franca\"\n    - name: \"Rafael Mendonca Franca\"\n      slug: \"rafael-mendonca-franca\"\n- name: \"Rafael Millán\"\n  github: \"rafaelmillan\"\n  website: \"https://rmillan.com\"\n  slug: \"rafael-millan\"\n- name: \"Rafael Nunes\"\n  github: \"\"\n  slug: \"rafael-nunes\"\n- name: \"Rafael Pestragis\"\n  github: \"\"\n  slug: \"rafael-pestragis\"\n- name: \"Rafael Peña-Azar\"\n  twitter: \"rpaweb\"\n  github: \"rpaweb\"\n  website: \"https://rpaweb.github.io\"\n  slug: \"rafael-pena-azar\"\n- name: \"Rafał Cymerys\"\n  twitter: \"rafalcymerys\"\n  github: \"rafalcymerys\"\n  website: \"https://upsidelab.io\"\n  slug: \"rafal-cymerys\"\n- name: \"Rafał Piekara\"\n  github: \"rafpiek\"\n  slug: \"rafal-piekara\"\n- name: \"Rafał Rothenberger\"\n  github: \"\"\n  slug: \"rafal-rothenberger\"\n- name: \"Rahul Mahale\"\n  github: \"\"\n  slug: \"rahul-mahale\"\n- name: \"Rahul Subramaniam EY\"\n  github: \"\"\n  slug: \"rahul-subramaniam-ey\"\n- name: \"Rahul Trikha\"\n  github: \"\"\n  slug: \"rahul-trikha\"\n- name: \"Raimond Garcia\"\n  github: \"voodoorai2000\"\n  slug: \"raimond-garcia\"\n- name: \"Raimonds Simanovskis\"\n  github: \"\"\n  slug: \"raimonds-simanovskis\"\n- name: \"Raj Kumar\"\n  github: \"\"\n  slug: \"raj-kumar\"\n- name: \"Rakesh Arunachalam\"\n  twitter: \"rakeshpetit\"\n  github: \"rakeshpetit\"\n  slug: \"rakesh-arunachalam\"\n- name: \"Rakesh Jha\"\n  github: \"\"\n  slug: \"rakesh-jha\"\n- name: \"Ralph von der Heyden\"\n  github: \"ralph\"\n  website: \"http://www.rvdh.de\"\n  slug: \"ralph-von-der-heyden\"\n- name: \"Ram Ramakrishnan\"\n  github: \"\"\n  slug: \"ram-ramakrishnan\"\n- name: \"Randall Thomas\"\n  github: \"devdevvy\"\n  website: \"https://randallthomasmusic.com\"\n  slug: \"randall-thomas\"\n- name: \"Randy Coulman\"\n  twitter: \"randycoulman\"\n  github: \"randycoulman\"\n  website: \"https://randycoulman.com\"\n  slug: \"randy-coulman\"\n- name: \"Ranjeet Singh\"\n  github: \"\"\n  slug: \"ranjeet-singh\"\n- name: \"Raphaela Wrede\"\n  github: \"rwrede\"\n  slug: \"raphaela-wrede\"\n- name: \"Rashmi Nagpal\"\n  twitter: \"iamrashminagpal\"\n  github: \"rn0311\"\n  slug: \"rashmi-nagpal\"\n- name: \"Ratnadeep Deshmane\"\n  twitter: \"rtdp\"\n  github: \"rtdp\"\n  website: \"http://rtdp.me\"\n  slug: \"ratnadeep-deshmane\"\n- name: \"Raven Covington\"\n  github: \"\"\n  slug: \"raven-covington\"\n- name: \"Ray Hightower\"\n  twitter: \"RayHightower\"\n  github: \"rayhightower\"\n  website: \"https://RayHightower.com\"\n  slug: \"ray-hightower\"\n  aliases:\n    - name: \"Raymond Hightower\"\n      slug: \"raymond-hightower\"\n    - name: \"Raymond T. Hightower\"\n      slug: \"raymond-t-hightower\"\n- name: \"Rayta van Rijswijk\"\n  github: \"\"\n  slug: \"rayta-van-rijswijk\"\n- name: \"Rebecca Fernandes\"\n  github: \"raiamusic\"\n  website: \"https://raia-art.weebly.com/about.html\"\n  slug: \"rebecca-fernandes\"\n- name: \"Rebecca Miller-Webster\"\n  twitter: \"rmillerwebster\"\n  github: \"rmw\"\n  website: \"https://www.rebeccamiller-webster.com/\"\n  slug: \"rebecca-miller-webster\"\n- name: \"Rebecca Poulson\"\n  github: \"rapoulson\"\n  slug: \"rebecca-poulson\"\n- name: \"Rebecca Sliter\"\n  github: \"rsliter\"\n  website: \"http://rebeccasliter.com\"\n  slug: \"rebecca-sliter\"\n- name: \"Reginald Braithwaite\"\n  github: \"pd-reg-braithwaite\"\n  slug: \"reginald-braithwaite\"\n- name: \"Regional.rb Organizers\"\n  github: \"\"\n  slug: \"regional-rb-organizers\"\n- name: \"Reid Gillette\"\n  github: \"\"\n  slug: \"reid-gillette\"\n- name: \"Reid Morrison\"\n  twitter: \"reidmorrison\"\n  github: \"reidmorrison\"\n  website: \"https://www.linkedin.com/in/reidmorrison/\"\n  slug: \"reid-morrison\"\n- name: \"Rein Hendrichs\"\n  github: \"\"\n  slug: \"rein-hendrichs\"\n- name: \"Rein Henrichs\"\n  github: \"reinh\"\n  website: \"http://reinh.com\"\n  slug: \"rein-henrichs\"\n- name: \"Remi Taylor\"\n  github: \"\"\n  slug: \"remi-taylor\"\n- name: \"Renato dos Santos Cerqueira\"\n  github: \"\"\n  slug: \"renato-dos-santos-cerqueira\"\n- name: \"Renée De Voursney\"\n  github: \"\"\n  slug: \"renee-de-voursney\"\n  aliases:\n    - name: \"Renee De Voursney\"\n      slug: \"renee-de-voursney\"\n- name: \"Renée Hendricksen\"\n  github: \"reneedv\"\n  slug: \"renee-hendricksen\"\n- name: \"Rhiana Heath\"\n  github: \"\"\n  slug: \"rhiana-heath\"\n- name: \"Rhiana Heppenstall\"\n  github: \"\"\n  slug: \"rhiana-heppenstall\"\n- name: \"Rhiannon Payne\"\n  twitter: \"rhiannon_io\"\n  github: \"rhiannon-io\"\n  website: \"https://www.rhiannon.io\"\n  slug: \"rhiannon-payne\"\n- name: \"Rian McGuire\"\n  github: \"\"\n  slug: \"rian-mcguire\"\n- name: \"Riaz Virani\"\n  github: \"rvirani1\"\n  website: \"https://riazv.me\"\n  slug: \"riaz-virani\"\n- name: \"Ricardo Carlesso\"\n  github: \"\"\n  slug: \"ricardo-carlesso\"\n- name: \"Ricardo Nacif\"\n  github: \"\"\n  slug: \"ricardo-nacif\"\n- name: \"Riccardo Carlesso\"\n  twitter: \"palladius\"\n  github: \"palladius\"\n  website: \"https://ricc.rocks/\"\n  slug: \"riccardo-carlesso\"\n- name: \"Rich Hickey\"\n  github: \"richhickey\"\n  website: \"http://clojure.org\"\n  slug: \"rich-hickey\"\n- name: \"Rich Kilmer\"\n  github: \"\"\n  slug: \"rich-kilmer\"\n- name: \"Rich Steinmetz\"\n  twitter: \"RichStoneIO\"\n  github: \"richstone\"\n  website: \"https://richstone.io\"\n  slug: \"rich-steinmetz\"\n- name: \"Richard Bishop\"\n  twitter: \"bitsandhops\"\n  github: \"rbishop\"\n  slug: \"richard-bishop\"\n- name: \"Richard Brooke\"\n  twitter: \"rubyforwork\"\n  github: \"rubyforbusiness\"\n  slug: \"richard-brooke\"\n- name: \"Richard Bützer\"\n  github: \"rbuetzer\"\n  slug: \"richard-buetzer\"\n  aliases:\n    - name: \"Richi Bützer\"\n      slug: \"richi-buetzer\"\n- name: \"Richard Crowley\"\n  github: \"\"\n  slug: \"richard-crowley\"\n- name: \"Richard Evans\"\n  twitter: \"RickEcon\"\n  github: \"rickecon\"\n  website: \"https://sites.google.com/site/rickecon/\"\n  slug: \"richard-evans\"\n- name: \"Richard Huang\"\n  twitter: \"flyerhzm\"\n  github: \"flyerhzm\"\n  website: \"https://synvert.net\"\n  slug: \"richard-huang\"\n- name: \"Richard Lee\"\n  twitter: \"dlackty\"\n  github: \"dlackty\"\n  slug: \"richard-lee\"\n- name: \"Richard McGain\"\n  github: \"\"\n  slug: \"richard-mcgain\"\n- name: \"Richard Schneeman\"\n  twitter: \"schneems\"\n  github: \"schneems\"\n  website: \"https://www.schneems.com\"\n  slug: \"richard-schneeman\"\n- name: \"Richie Khoo\"\n  github: \"\"\n  slug: \"richie-khoo\"\n- name: \"Rick Bradley\"\n  github: \"\"\n  slug: \"rick-bradley\"\n- name: \"Rick Carlino\"\n  github: \"rickcarlino\"\n  website: \"http://www.RickCarlino.com\"\n  slug: \"rick-carlino\"\n- name: \"Rick Liu\"\n  github: \"info-rick\"\n  slug: \"rick-liu\"\n- name: \"Rick Olson\"\n  github: \"\"\n  slug: \"rick-olson\"\n- name: \"Ridhwana Khan\"\n  twitter: \"Ridhwana_K\"\n  github: \"ridhwana\"\n  website: \"https://www.ridhwana.com\"\n  slug: \"ridhwana-khan\"\n- name: \"Ried Morrison\"\n  github: \"\"\n  slug: \"ried-morrison\"\n- name: \"Rikiya Ayukawa\"\n  github: \"\"\n  slug: \"rikiya-ayukawa\"\n- name: \"Rikke Rosenlund\"\n  github: \"\"\n  slug: \"rikke-rosenlund\"\n- name: \"Rin Raeuber\"\n  github: \"rin\"\n  slug: \"rin-raeuber\"\n  aliases:\n    - name: \"Rin Rauber\"\n      slug: \"rin-rauber\"\n- name: \"Risa Batta\"\n  github: \"\"\n  slug: \"risa-batta\"\n- name: \"Rishi Jain\"\n  twitter: \"jainrishi15\"\n  github: \"rishijain\"\n  slug: \"rishi-jain\"\n  aliases:\n    - name: \"Jain Rishi\"\n      slug: \"jain-rishi\"\n- name: \"Ritta Narita\"\n  github: \"naritta\"\n  slug: \"ritta-narita\"\n- name: \"rking\"\n  github: \"ryanjosephking\"\n  website: \"http://panoptic.com/rking\"\n  slug: \"rking\"\n- name: \"Rob Faldo\"\n  github: \"\"\n  slug: \"rob-faldo\"\n- name: \"Rob Head\"\n  github: \"\"\n  slug: \"rob-head\"\n- name: \"Rob Howard\"\n  github: \"\"\n  slug: \"rob-howard\"\n- name: \"Rob McKinnon\"\n  github: \"\"\n  slug: \"rob-mckinnon\"\n- name: \"Rob Miller\"\n  github: \"\"\n  slug: \"rob-miller\"\n- name: \"Rob Sanheim\"\n  github: \"\"\n  slug: \"rob-sanheim\"\n- name: \"Robb Kidd\"\n  github: \"\"\n  slug: \"robb-kidd\"\n- name: \"Robbie Clutton\"\n  twitter: \"robb1e\"\n  github: \"robb1e\"\n  website: \"http://robb1e.com\"\n  slug: \"robbie-clutton\"\n- name: \"Robby Russell\"\n  twitter: \"robbyrussell\"\n  github: \"robbyrussell\"\n  website: \"https://www.planetargon.com/robby\"\n  slug: \"robby-russell\"\n- name: \"Robert Beene\"\n  twitter: \"robert_beene\"\n  github: \"rbeene\"\n  slug: \"robert-beene\"\n- name: \"Robert Berger\"\n  github: \"\"\n  slug: \"robert-berger\"\n- name: \"Robert Dempsey\"\n  github: \"\"\n  slug: \"robert-dempsey\"\n- name: \"Robert Jackson\"\n  twitter: \"rwjblue\"\n  github: \"rwjblue\"\n  website: \"https://www.rwjblue.com\"\n  slug: \"robert-jackson\"\n- name: \"Robert Martin\"\n  github: \"\"\n  slug: \"robert-martin\"\n  aliases:\n    - name: \"Robert C. Martin\"\n      slug: \"robert-c-martin\"\n- name: \"Robert Mosolgo\"\n  github: \"rmosolgo\"\n  website: \"http://rmosolgo.github.io\"\n  slug: \"robert-mosolgo\"\n- name: \"Robert Pankowecki\"\n  github: \"paneq\"\n  website: \"https://robert.pankowecki.pl\"\n  slug: \"robert-pankowecki\"\n- name: \"Robert Pawlas\"\n  github: \"hedselu\"\n  slug: \"robert-pawlas\"\n- name: \"Robert Pitts\"\n  github: \"\"\n  slug: \"robert-pitts\"\n- name: \"Robert Postill\"\n  github: \"\"\n  slug: \"robert-postill\"\n- name: \"Robert Roach\"\n  github: \"\"\n  slug: \"robert-roach\"\n- name: \"Robert Ross\"\n  github: \"bobbytables\"\n  slug: \"robert-ross\"\n- name: \"Robert Young\"\n  github: \"robertyoung2\"\n  website: \"https://www.robertyoung.ie\"\n  slug: \"robert-young\"\n- name: \"Roberta Mataityte\"\n  github: \"\"\n  slug: \"roberta-mataityte\"\n- name: \"Robin Boening\"\n  github: \"\"\n  slug: \"robin-boening\"\n- name: \"Robin Bühler\"\n  github: \"\"\n  slug: \"robin-buehler\"\n- name: \"Robin Drexler\"\n  github: \"robin-drexler\"\n  website: \"https://www.robin-drexler.com/\"\n  slug: \"robin-drexler\"\n- name: \"Robin Steiner\"\n  twitter: \"Robin_481\"\n  github: \"robin481\"\n  slug: \"robin-steiner\"\n- name: \"Robson Port\"\n  github: \"\"\n  slug: \"robson-port\"\n- name: \"Rocio Delgado\"\n  github: \"rocio\"\n  slug: \"rocio-delgado\"\n- name: \"Rock Davenport\"\n  github: \"\"\n  slug: \"rock-davenport\"\n- name: \"Rod Cope\"\n  github: \"\"\n  slug: \"rod-cope\"\n- name: \"Rod Paddock\"\n  github: \"rodpaddock\"\n  slug: \"rod-paddock\"\n- name: \"Rodolfo Pilas\"\n  github: \"\"\n  slug: \"rodolfo-pilas\"\n- name: \"Rodrigo Franco\"\n  github: \"caffo\"\n  website: \"http://rodrigofranco.com/\"\n  slug: \"rodrigo-franco\"\n- name: \"Rodrigo Haenggi\"\n  github: \"therod\"\n  website: \"https://rodrigohaenggi.com\"\n  slug: \"rodrigo-haenggi\"\n- name: \"Rodrigo Serradura\"\n  github: \"serradura\"\n  slug: \"rodrigo-serradura\"\n- name: \"Rodrigo Urubatan\"\n  github: \"urubatan\"\n  website: \"http://www.sobrecodigo.com\"\n  slug: \"rodrigo-urubatan\"\n- name: \"Rogelio J. Samour\"\n  github: \"\"\n  slug: \"rogelio-j-samour\"\n- name: \"Rogelio Samour\"\n  github: \"\"\n  slug: \"rogelio-samour\"\n- name: \"Rohaa Mendon\"\n  github: \"\"\n  slug: \"rohaa-mendon\"\n- name: \"Rohit Mukherjee\"\n  github: \"\"\n  slug: \"rohit-mukherjee\"\n- name: \"Roland Lopez\"\n  github: \"letItCurl\"\n  slug: \"roland-lopez\"\n- name: \"Roland Studer\"\n  twitter: \"roli_on_rails\"\n  github: \"rolandstuder\"\n  website: \"https://rstuder.ch\"\n  slug: \"roland-studer\"\n- name: \"Rolen Le\"\n  github: \"rolentle\"\n  website: \"https://rolentle.com\"\n  slug: \"rolen-le\"\n- name: \"Romain Durritçague\"\n  github: \"\"\n  slug: \"romain-durritcague\"\n- name: \"Roman Dubrovsky\"\n  github: \"roman-dubrovsky\"\n  slug: \"roman-dubrovsky\"\n- name: \"Roman Kofman\"\n  github: \"rkofman\"\n  slug: \"roman-kofman\"\n- name: \"Roman Samoilov\"\n  github: \"rsamoilov\"\n  slug: \"roman-samoilov\"\n- name: \"Roman Turner\"\n  github: \"gandalfini\"\n  website: \"https://weedmaps.com\"\n  slug: \"roman-turner\"\n- name: \"Romeeka Gayhart\"\n  github: \"rrgayhart\"\n  website: \"http://www.romeeka.com\"\n  slug: \"romeeka-gayhart\"\n- name: \"Ron Evans\"\n  twitter: \"deadprogram\"\n  github: \"deadprogram\"\n  website: \"https://hybridgroup.com\"\n  slug: \"ron-evans\"\n- name: \"Ron Shinall\"\n  github: \"ron-shinall\"\n  slug: \"ron-shinall\"\n- name: \"Ronan Limon Duparcmeur\"\n  github: \"r3trofitted\"\n  website: \"https://2-45.pm\"\n  slug: \"ronan-limon-duparcmeur\"\n- name: \"Ronan Potage\"\n  github: \"capripot\"\n  website: \"https://ronan.nyc\"\n  slug: \"ronan-potage\"\n- name: \"Roonglit Chareonsupkul\"\n  github: \"roonglit\"\n  slug: \"roonglit-chareonsupkul\"\n- name: \"Rosa Fox\"\n  github: \"\"\n  slug: \"rosa-fox\"\n- name: \"Rosa Gutiérrez\"\n  twitter: \"rosapolis\"\n  github: \"rosa\"\n  website: \"https://rosa.codes\"\n  slug: \"rosa-gutierrez\"\n  aliases:\n    - name: \"Rosa Gutierrez\"\n      slug: \"rosa-gutierrez\"\n- name: \"Rose Wiegley\"\n  twitter: \"rose_w\"\n  github: \"rosew\"\n  slug: \"rose-wiegley\"\n- name: \"Rosie Hoyem\"\n  github: \"rosiehoyem\"\n  website: \"https://rosiehoyem.herokuapp.com\"\n  slug: \"rosie-hoyem\"\n- name: \"Ross Andrews\"\n  github: \"\"\n  slug: \"ross-andrews\"\n- name: \"Ross Baker\"\n  twitter: \"rossandrewbaker\"\n  github: \"r0ss26\"\n  slug: \"ross-baker\"\n  aliases:\n    - name: \"Ross A. Baker\"\n      slug: \"ross-a-baker\"\n- name: \"Ross Kaffenberger\"\n  twitter: \"rossta\"\n  github: \"rossta\"\n  website: \"https://joyofrails.com\"\n  slug: \"ross-kaffenberger\"\n- name: \"Rostislav Zhuravsky\"\n  twitter: \"w0arewe\"\n  github: \"woarewe\"\n  website: \"https://zhuravsky.dev\"\n  slug: \"rostislav-zhuravsky\"\n- name: \"Roy Tomeij\"\n  github: \"roytomeij\"\n  slug: \"roy-tomeij\"\n- name: \"Ruan Brandão\"\n  github: \"\"\n  slug: \"ruan-brandao\"\n- name: \"Ruby Committers\"\n  github: \"\"\n  slug: \"ruby-committers\"\n- name: \"Ruby Core Team\"\n  github: \"\"\n  slug: \"ruby-core-team\"\n- name: \"Ruby Manor Organizers\"\n  github: \"\"\n  slug: \"ruby-manor-organizers\"\n- name: \"Ruby off the Rails: Building a distributed system in Ruby\"\n  github: \"\"\n  slug: \"ruby-off-the-rails-building-a-distributed-system-in-ruby\"\n- name: \"Ruby Rogues\"\n  github: \"\"\n  slug: \"ruby-rogues\"\n- name: \"Rufo Sanchez\"\n  github: \"rufo\"\n  slug: \"rufo-sanchez\"\n- name: \"Rune Funch Søltoft\"\n  github: \"\"\n  slug: \"rune-funch-soltoft\"\n- name: \"Rushaine McBean\"\n  twitter: \"copasetickid\"\n  github: \"copasetickid\"\n  slug: \"rushaine-mcbean\"\n- name: \"Russ Olsen\"\n  github: \"\"\n  slug: \"russ-olsen\"\n- name: \"Ryan Alexander\"\n  github: \"notlion\"\n  website: \"http://onecm.com\"\n  slug: \"ryan-alexander\"\n- name: \"Ryan Alyea\"\n  github: \"rofish\"\n  website: \"http://rofish.net\"\n  slug: \"ryan-alyea\"\n- name: \"Ryan Angilly\"\n  github: \"ryana\"\n  website: \"https://ryanangilly.com\"\n  slug: \"ryan-angilly\"\n- name: \"Ryan Bigg\"\n  twitter: \"ryanbigg\"\n  github: \"radar\"\n  website: \"http://ryanbigg.com\"\n  slug: \"ryan-bigg\"\n- name: \"Ryan Biggs\"\n  github: \"ryanbiggs\"\n  website: \"https://ryanbiggs.co.uk\"\n  slug: \"ryan-biggs\"\n- name: \"Ryan Boone\"\n  github: \"falldowngoboone\"\n  slug: \"ryan-boone\"\n- name: \"Ryan Brown\"\n  github: \"\"\n  slug: \"ryan-brown\"\n- name: \"Ryan Brunner\"\n  github: \"ryanbrunner\"\n  slug: \"ryan-brunner\"\n- name: \"Ryan Brushett\"\n  github: \"ryanbrushett\"\n  website: \"https://ryanbrushett.com\"\n  slug: \"ryan-brushett\"\n- name: \"Ryan Choi\"\n  github: \"ryankicks\"\n  website: \"http://www.ryankicks.com\"\n  slug: \"ryan-choi\"\n- name: \"Ryan Davis\"\n  github: \"zenspider\"\n  website: \"https://www.zenspider.com/\"\n  slug: \"ryan-davis\"\n- name: \"Ryan Dlugosz\"\n  github: \"\"\n  slug: \"ryan-dlugosz\"\n- name: \"Ryan Erickson\"\n  github: \"ryan-erickson\"\n  website: \"https://ryanerickson.dev\"\n  slug: \"ryan-erickson\"\n- name: \"Ryan Findley\"\n  twitter: \"neomindryan\"\n  github: \"neomindryan\"\n  slug: \"ryan-findley\"\n- name: \"Ryan Florence\"\n  twitter: \"ryanflorence\"\n  github: \"ryanflorence\"\n  website: \"http://remix.run\"\n  slug: \"ryan-florence\"\n- name: \"Ryan Hageman\"\n  github: \"ryanhageman\"\n  slug: \"ryan-hageman\"\n- name: \"Ryan King\"\n  github: \"\"\n  slug: \"ryan-king\"\n- name: \"Ryan Laughlin\"\n  github: \"rofreg\"\n  website: \"https://rofreg.com\"\n  slug: \"ryan-laughlin\"\n- name: \"Ryan Levick\"\n  twitter: \"ryan_levick\"\n  github: \"ryanlevick\"\n  slug: \"ryan-levick\"\n- name: \"Ryan Lopopolo\"\n  twitter: \"_lopopolo\"\n  github: \"lopopolo\"\n  website: \"https://hyperbo.la\"\n  slug: \"ryan-lopopolo\"\n- name: \"Ryan MacInnes\"\n  github: \"goddamnyouryan\"\n  website: \"http://www.goddamnyouryan.com\"\n  slug: \"ryan-macinnes\"\n- name: \"Ryan McGeary\"\n  twitter: \"rmm5t\"\n  github: \"rmm5t\"\n  website: \"http://ryan.mcgeary.org\"\n  slug: \"ryan-mcgeary\"\n- name: \"Ryan McGillivray\"\n  github: \"\"\n  slug: \"ryan-mcgillivray\"\n- name: \"Ryan Melton\"\n  github: \"ryanmelt\"\n  slug: \"ryan-melton\"\n- name: \"Ryan O'Donnell\"\n  github: \"llenodo\"\n  slug: \"ryan-odonnell\"\n- name: \"Ryan Perry\"\n  github: \"rperry2174\"\n  website: \"https://pyroscope.io\"\n  slug: \"ryan-perry\"\n- name: \"Ryan R Hughes\"\n  github: \"\"\n  slug: \"ryan-r-hughes\"\n- name: \"Ryan Resella\"\n  twitter: \"ryanresella\"\n  github: \"ryanatwork\"\n  website: \"https://ryanresella.com\"\n  slug: \"ryan-resella\"\n- name: \"Ryan Sherlock\"\n  github: \"ryansherlock\"\n  slug: \"ryan-sherlock\"\n- name: \"Ryan Singer\"\n  twitter: \"rjs\"\n  github: \"rjs\"\n  website: \"https://feltpresence.com\"\n  slug: \"ryan-singer\"\n- name: \"Ryan Smith\"\n  github: \"\"\n  slug: \"ryan-smith\"\n- name: \"Ryan Stemmle\"\n  github: \"r-stemmle\"\n  slug: \"ryan-stemmle\"\n- name: \"Ryan Stout\"\n  twitter: \"ryanstout\"\n  github: \"ryanstout\"\n  website: \"http://www.witharsenal.com/\"\n  slug: \"ryan-stout\"\n- name: \"Ryan Tomayko\"\n  github: \"\"\n  slug: \"ryan-tomayko\"\n- name: \"Ryan Townsend\"\n  github: \"ryantownsend\"\n  slug: \"ryan-townsend\"\n- name: \"Ryan Twomey\"\n  github: \"rtwomey\"\n  website: \"http://www.ryantwomey.com\"\n  slug: \"ryan-twomey\"\n- name: \"Ryan Weald\"\n  github: \"\"\n  slug: \"ryan-weald\"\n- name: \"Ryann Richardson\"\n  github: \"\"\n  slug: \"ryann-richardson\"\n- name: \"Ryder Timberlake\"\n  github: \"yakryder\"\n  slug: \"ryder-timberlake\"\n- name: \"Ryo Ishigaki\"\n  github: \"\"\n  slug: \"ryo-ishigaki\"\n- name: \"Ryo Kajiwara\"\n  twitter: \"s01\"\n  github: \"sylph01\"\n  website: \"https://s01.ninja/\"\n  slug: \"ryo-kajiwara\"\n- name: \"ryopeko\"\n  github: \"\"\n  slug: \"ryopeko\"\n- name: \"ryosk7\"\n  github: \"\"\n  slug: \"ryosk7\"\n- name: \"Ryosuke Uchida\"\n  twitter: \"ryosk7\"\n  github: \"ryosk7\"\n  slug: \"ryosuke-uchida\"\n- name: \"Ryota Arai\"\n  github: \"\"\n  slug: \"ryota-arai\"\n- name: \"Ryota Egusa\"\n  twitter: \"gedorinku\"\n  github: \"gedorinku\"\n  slug: \"ryota-egusa\"\n- name: \"Ryunosuke Sato\"\n  github: \"\"\n  slug: \"ryunosuke-sato\"\n- name: \"Ryuta Kamizono\"\n  github: \"\"\n  slug: \"ryuta-kamizono\"\n- name: \"Rémi Mercier\"\n  github: \"\"\n  slug: \"remi-mercier\"\n- name: \"Rémy Hannequin\"\n  twitter: \"rhannequin\"\n  github: \"rhannequin\"\n  website: \"https://rhannequ.in\"\n  slug: \"remy-hannequin\"\n- name: \"S-H-GAMELINKS\"\n  github: \"S-H-GAMELINKS\"\n  slug: \"s-h-gamelinks\"\n- name: \"s4ichi\"\n  github: \"\"\n  slug: \"s4ichi\"\n- name: \"Sabrina Gannon\"\n  github: \"\"\n  slug: \"sabrina-gannon\"\n- name: \"Sabrina Leandro\"\n  github: \"\"\n  slug: \"sabrina-leandro\"\n- name: \"Sachin Shintre\"\n  github: \"shintre\"\n  slug: \"sachin-shintre\"\n- name: \"Sadayuki Furuhashi\"\n  github: \"frsyuki\"\n  website: \"http://twitter.com/frsyuki\"\n  slug: \"sadayuki-furuhashi\"\n- name: \"Sage Griffin\"\n  github: \"sgrif\"\n  slug: \"sage-griffin\"\n  aliases:\n    - name: \"Sean Griffin\"\n      slug: \"sean-griffin\"\n- name: \"sago35\"\n  github: \"\"\n  slug: \"sago35\"\n- name: \"Sahil Muthoo\"\n  github: \"\"\n  slug: \"sahil-muthoo\"\n- name: \"Sai Warang\"\n  github: \"cyprusad\"\n  slug: \"sai-warang\"\n- name: \"Saimon Sharif\"\n  github: \"saimonsharif\"\n  slug: \"saimon-sharif\"\n- name: \"sakahukamaki\"\n  github: \"sakahukamaki\"\n  slug: \"sakahukamaki\"\n- name: \"Sakchai Siripanyawuth\"\n  github: \"\"\n  slug: \"sakchai-siripanyawuth\"\n- name: \"Sakshi Jain\"\n  github: \"\"\n  slug: \"sakshi-jain\"\n- name: \"Salim Semaoune\"\n  twitter: \"salim_semaoune\"\n  github: \"sailor\"\n  website: \"https://twitter.com/salim_semaoune\"\n  slug: \"salim-semaoune\"\n- name: \"Sally Hall\"\n  github: \"sallyhall\"\n  slug: \"sally-hall\"\n- name: \"Salomón Charabati\"\n  twitter: \"salochara\"\n  github: \"salochara\"\n  website: \"https://salochara.github.io/\"\n  slug: \"salomon-charabati\"\n- name: \"Sam Aaron\"\n  twitter: \"samaaron\"\n  github: \"samaaron\"\n  website: \"http://sam.aaron.name\"\n  slug: \"sam-aaron\"\n- name: \"Sam Aarons\"\n  twitter: \"samaarons\"\n  github: \"saarons\"\n  slug: \"sam-aarons\"\n- name: \"Sam Galindo\"\n  github: \"\"\n  slug: \"sam-galindo\"\n- name: \"Sam Hammond\"\n  github: \"\"\n  slug: \"sam-hammond\"\n- name: \"Sam Joseph\"\n  github: \"\"\n  slug: \"sam-joseph\"\n- name: \"Sam Lambert\"\n  github: \"samlambert\"\n  slug: \"sam-lambert\"\n- name: \"Sam Livingston-Gray\"\n  twitter: \"geeksam\"\n  github: \"geeksam\"\n  website: \"https://resume.livingston-gray.com/\"\n  slug: \"sam-livingston-gray\"\n  aliases:\n    - name: \"Sam Livingston-Grey\"\n      slug: \"sam-livingston-grey\"\n- name: \"Sam Poder\"\n  twitter: \"sam_poder\"\n  github: \"sampoder\"\n  website: \"https://sampoder.com\"\n  slug: \"sam-poder\"\n- name: \"Sam Rawlins\"\n  github: \"\"\n  slug: \"sam-rawlins\"\n- name: \"Sam Reghenzi\"\n  github: \"\"\n  slug: \"sam-reghenzi\"\n- name: \"Sam Saffron\"\n  github: \"samsaffron\"\n  website: \"http://www.samsaffron.com\"\n  slug: \"sam-saffron\"\n- name: \"Sam Stephenson\"\n  github: \"\"\n  slug: \"sam-stephenson\"\n- name: \"Sam Woodard\"\n  github: \"shwoodard\"\n  website: \"https://google.com\"\n  slug: \"sam-woodard\"\n- name: \"Samantha Holstine\"\n  github: \"samanthaholstine\"\n  slug: \"samantha-holstine\"\n- name: \"Samantha John\"\n  github: \"\"\n  slug: \"samantha-john\"\n- name: \"Samat Galimov\"\n  github: \"\"\n  slug: \"samat-galimov\"\n- name: \"Samay Sharma\"\n  twitter: \"samay_sharma\"\n  github: \"samay-sharma\"\n  slug: \"samay-sharma\"\n- name: \"Sameer Deshmukh\"\n  github: \"v0dro\"\n  website: \"http://v0dro.in\"\n  slug: \"sameer-deshmukh\"\n- name: \"Sameer Kumar\"\n  github: \"\"\n  slug: \"sameer-kumar\"\n- name: \"Sameera Gayan\"\n  github: \"\"\n  slug: \"sameera-gayan\"\n- name: \"Sampo Kuokkanen\"\n  twitter: \"kuokkanensampo\"\n  github: \"sampokuokkanen\"\n  website: \"https://sampo.ltd\"\n  slug: \"sampo-kuokkanen\"\n- name: \"Samuel Cochran\"\n  github: \"\"\n  slug: \"samuel-cochran\"\n- name: \"Samuel Giddins\"\n  twitter: \"segiddins\"\n  github: \"segiddins\"\n  website: \"https://segiddins.me\"\n  slug: \"samuel-giddins\"\n- name: \"Samuel Seay\"\n  github: \"\"\n  slug: \"samuel-seay\"\n- name: \"Samuel Steiner\"\n  github: \"samuelsteiner\"\n  website: \"https://renuo.ch\"\n  slug: \"samuel-steiner\"\n- name: \"Samuel Williams\"\n  twitter: \"ioquatix\"\n  github: \"ioquatix\"\n  website: \"http://www.codeotaku.com\"\n  slug: \"samuel-williams\"\n- name: \"Sana Khan\"\n  github: \"\"\n  slug: \"sana-khan\"\n- name: \"Sander van der Burg\"\n  github: \"svanderburg\"\n  website: \"http://sandervanderburg.nl\"\n  slug: \"sander-van-der-burg\"\n- name: \"Sandi Metz\"\n  twitter: \"sandimetz\"\n  github: \"skmetz\"\n  website: \"https://sandimetz.com\"\n  slug: \"sandi-metz\"\n- name: \"Sandra Kpodar\"\n  github: \"\"\n  twitter: \"sandrakpodar\"\n  mastodon: \"https://hachyderm.io/@sandrakpodar\"\n  linkedin: \"sandrakpodar\"\n  slug: \"sandra-kpodar\"\n- name: \"Sandro Kalbermatter\"\n  github: \"kalsan\"\n  slug: \"sandro-kalbermatter\"\n- name: \"Sandro Paganotti\"\n  github: \"\"\n  slug: \"sandro-paganotti\"\n- name: \"Sangyong \\\"Shia\\\" Sim\"\n  github: \"riseshia\"\n  slug: \"sangyong-shia-sim\"\n  aliases:\n    - name: \"Sangyong Sim\"\n      slug: \"sangyong-sim\"\n    - name: \"Shia\"\n      slug: \"shia\"\n- name: \"Sante Rotondi\"\n  github: \"\"\n  slug: \"sante-rotondi\"\n- name: \"Santiago Bartesaghi\"\n  twitter: \"santib6_\"\n  github: \"santib\"\n  website: \"https://santib.com\"\n  slug: \"santiago-bartesaghi\"\n- name: \"Santiago Behak\"\n  github: \"sbehak\"\n  slug: \"santiago-behak\"\n- name: \"Santiago Díaz\"\n  github: \"\"\n  slug: \"santiago-diaz\"\n- name: \"Santiago Merlo\"\n  github: \"\"\n  slug: \"santiago-merlo\"\n- name: \"Santiago Pastorino\"\n  twitter: \"spastorino\"\n  github: \"spastorino\"\n  website: \"https://santiagopastorino.com\"\n  slug: \"santiago-pastorino\"\n- name: \"Santiago Rodriguez\"\n  github: \"santiagorodriguez96\"\n  slug: \"santiago-rodriguez\"\n- name: \"Santosh Shah\"\n  github: \"\"\n  slug: \"santosh-shah\"\n- name: \"Santosh Wadghule\"\n  github: \"\"\n  slug: \"santosh-wadghule\"\n- name: \"Sara Chipps\"\n  github: \"\"\n  slug: \"sara-chipps\"\n- name: \"Sara Dolganov\"\n  twitter: \"sara_s_dogan\"\n  github: \"sclinede\"\n  slug: \"sara-dolganov\"\n  aliases:\n    - name: \"Sergey Dolganov\"\n      slug: \"sergey-dolganov\"\n- name: \"Sara Jackson\"\n  github: \"sej3506\"\n  website: \"https://tbot.io/csara\"\n  slug: \"sara-jackson\"\n- name: \"Sara Regan\"\n  github: \"\"\n  slug: \"sara-regan\"\n- name: \"Sara Simon\"\n  github: \"smbsimon\"\n  slug: \"sara-simon\"\n- name: \"Sarah Allen\"\n  github: \"ultrasaurus\"\n  website: \"https://www.ultrasaurus.com\"\n  slug: \"sarah-allen\"\n- name: \"Sarah Brookfield\"\n  github: \"\"\n  slug: \"sarah-brookfield\"\n- name: \"Sarah Lima\"\n  twitter: \"sarahraquelsh\"\n  github: \"sarahraqueld\"\n  slug: \"sarah-lima\"\n- name: \"Sarah Mei\"\n  github: \"sarahmei\"\n  website: \"http://sarahmei.com/blog\"\n  slug: \"sarah-mei\"\n- name: \"Sarah O'Grady\"\n  github: \"\"\n  slug: \"sarah-o-grady\"\n- name: \"Sarah Reid\"\n  github: \"snreid\"\n  slug: \"sarah-reid\"\n- name: \"Sarah Sausan\"\n  github: \"\"\n  slug: \"sarah-sausan\"\n- name: \"Sarish\"\n  github: \"\"\n  slug: \"sarish\"\n- name: \"Saron Yitbarek\"\n  twitter: \"saronyitbarek\"\n  github: \"sarony\"\n  slug: \"saron-yitbarek\"\n- name: \"Sasha Gerrand\"\n  github: \"\"\n  slug: \"sasha-gerrand\"\n- name: \"Sasha Grodzins\"\n  github: \"\"\n  slug: \"sasha-grodzins\"\n- name: \"Sasha Romijn\"\n  github: \"mxsasha\"\n  slug: \"sasha-romijn\"\n- name: \"Satoshi Azuma\"\n  github: \"ytnobody\"\n  slug: \"satoshi-azuma\"\n- name: \"Satoshi Kobayashi\"\n  github: \"f-world21\"\n  slug: \"satoshi-kobayashi\"\n- name: \"Satoshi Namai\"\n  twitter: \"ainame\"\n  github: \"ainame\"\n  website: \"https://ainame.tokyo/\"\n  slug: \"satoshi-namai\"\n- name: \"Satoshi Tagomori\"\n  twitter: \"tagomoris\"\n  github: \"tagomoris\"\n  website: \"http://tagomoris.hatenablog.com/\"\n  slug: \"satoshi-tagomori\"\n  aliases:\n    - name: \"Satoshi \\\"moris\\\" Tagomori\"\n      slug: \"satoshi-moris-tagomori\"\n    - name: \"TAGOMORI \\\"moris\\\" Satoshi\"\n      slug: \"tagomori-moris-satoshi\"\n    - name: \"Tagomori Satoshi\"\n      slug: \"tagomori-satoshi\"\n- name: \"Satya Kalluri\"\n  github: \"\"\n  slug: \"satya-kalluri\"\n- name: \"SaVance Ford\"\n  github: \"\"\n  slug: \"savance-ford\"\n- name: \"Savannah Wolf\"\n  github: \"savwolf\"\n  website: \"https://savannahwolf.com\"\n  slug: \"savannah-wolf\"\n- name: \"Sayanee Basu\"\n  github: \"\"\n  slug: \"sayanee-basu\"\n- name: \"Schalk Neethling\"\n  github: \"\"\n  slug: \"schalk-neethling\"\n- name: \"Scott Bellware\"\n  github: \"sbellware\"\n  website: \"https://github.com/eventide-project\"\n  slug: \"scott-bellware\"\n- name: \"Scott Chacon\"\n  twitter: \"chacon\"\n  github: \"schacon\"\n  website: \"http://scottchacon.com\"\n  slug: \"scott-chacon\"\n- name: \"Scott Feinberg\"\n  github: \"\"\n  slug: \"scott-feinberg\"\n- name: \"Scott Istvan\"\n  github: \"\"\n  slug: \"scott-istvan\"\n- name: \"Scott Lesser\"\n  twitter: \"okcscott\"\n  github: \"okcscott\"\n  website: \"https://scottlesser.com\"\n  slug: \"scott-lesser\"\n- name: \"Scott Mascar\"\n  github: \"\"\n  slug: \"scott-mascar\"\n- name: \"Scott Matthewman\"\n  github: \"\"\n  slug: \"scott-matthewman\"\n- name: \"Scott Moore\"\n  github: \"thinkmoore\"\n  website: \"https://www.thinkmoore.net\"\n  slug: \"scott-moore\"\n- name: \"Scott Motte\"\n  twitter: \"motdotla\"\n  github: \"motdotla\"\n  website: \"https://mot.la\"\n  slug: \"scott-motte\"\n- name: \"Scott Parker\"\n  github: \"sparkertime\"\n  website: \"http://scottparker.co\"\n  slug: \"scott-parker\"\n- name: \"Scott Werner\"\n  twitter: \"scottwernerd\"\n  github: \"swerner\"\n  website: \"https://www.scottwernerd.com\"\n  slug: \"scott-werner\"\n- name: \"Sean Carroll\"\n  github: \"\"\n  website: \"https://gitlab.com/sean_carroll\"\n  slug: \"sean-carroll\"\n- name: \"Sean Collins\"\n  github: \"cllns\"\n  slug: \"sean-collins\"\n- name: \"Sean Cribbs\"\n  github: \"\"\n  slug: \"sean-cribbs\"\n- name: \"Sean Culver\"\n  github: \"seanculver\"\n  slug: \"sean-culver\"\n- name: \"Sean Marcia\"\n  github: \"seanmarcia\"\n  website: \"https://rubyforgood.org\"\n  slug: \"sean-marcia\"\n- name: \"Sean O'Halpin\"\n  github: \"\"\n  slug: \"sean-o-halpin\"\n- name: \"Seb Wilgosz\"\n  github: \"swilgosz\"\n  website: \"https://hanamimastery.com\"\n  slug: \"seb-wilgosz\"\n- name: \"Sebastian Burkhard\"\n  github: \"\"\n  slug: \"sebastian-burkhard\"\n- name: \"Sebastian Delmont\"\n  twitter: \"sd\"\n  github: \"sd\"\n  website: \"http://about.me/sdelmont\"\n  slug: \"sebastian-delmont\"\n- name: \"Sebastian Deutsch\"\n  github: \"\"\n  slug: \"sebastian-deutsch\"\n- name: \"Sebastian Eichner\"\n  github: \"\"\n  slug: \"sebastian-eichner\"\n- name: \"Sebastian Gräßl\"\n  github: \"\"\n  slug: \"sebastian-grassl\"\n- name: \"Sebastian Korfmann\"\n  github: \"\"\n  slug: \"sebastian-korfmann\"\n- name: \"Sebastian Pape\"\n  twitter: \"10xSebastian\"\n  github: \"10xsebastian\"\n  slug: \"sebastian-pape\"\n- name: \"Sebastian Siemianowski\"\n  github: \"\"\n  slug: \"sebastian-siemianowski\"\n- name: \"Sebastian Sogamoso\"\n  twitter: \"sebsogamoso\"\n  github: \"sogamoso\"\n  website: \"https://sogamo.so\"\n  slug: \"sebastian-sogamoso\"\n- name: \"Sebastian Tekieli\"\n  github: \"qiun\"\n  slug: \"sebastian-tekieli\"\n- name: \"Sebastian van Hesteren\"\n  github: \"\"\n  slug: \"sebastian-van-hesteren\"\n- name: \"Sebastian von Conrad\"\n  github: \"\"\n  slug: \"sebastian-von-conrad\"\n- name: \"Sebastian Wilgosz\"\n  github: \"\"\n  slug: \"sebastian-wilgosz\"\n- name: \"Sebastián Arcila\"\n  github: \"\"\n  slug: \"sebastian-arcila\"\n- name: \"Sebastián Buffo Sempé\"\n  github: \"\"\n  slug: \"sebastian-buffo-sempe\"\n- name: \"Seema Ullal\"\n  github: \"\"\n  slug: \"seema-ullal\"\n- name: \"Selena Small\"\n  github: \"selenasmall\"\n  website: \"http://www.selenasmall.com\"\n  slug: \"selena-small\"\n- name: \"Semen Bagreev\"\n  github: \"\"\n  slug: \"semen-bagreev\"\n- name: \"Senator Scott Ludlam\"\n  github: \"\"\n  slug: \"senator-scott-ludlam\"\n- name: \"Senem Soy\"\n  github: \"\"\n  slug: \"senem-soy\"\n- name: \"Seong-Heon Jung\"\n  github: \"forthoney\"\n  website: \"https://forthoney.github.io\"\n  slug: \"seong-heon-jung\"\n- name: \"Serdar Doğruyol\"\n  github: \"\"\n  slug: \"serdar-dogruyol\"\n- name: \"Serg Tyatin\"\n  github: \"\"\n  slug: \"serg-tyatin\"\n- name: \"Sergei Alekseenko\"\n  github: \"alekseenkoss77\"\n  slug: \"sergei-alekseenko\"\n- name: \"Sergey Karayev\"\n  github: \"\"\n  slug: \"sergey-karayev\"\n- name: \"Sergey Silnov\"\n  github: \"cr1stal165\"\n  slug: \"sergey-silnov\"\n- name: \"Sergy Sergyenko\"\n  twitter: \"sergyenko\"\n  github: \"sergyenko\"\n  slug: \"sergy-sergyenko\"\n  aliases:\n    - name: \"Sergey Sergyenko\"\n      slug: \"sergey-sergyenko\"\n- name: \"Seth Horsley\"\n  twitter: \"SethHorsley\"\n  github: \"sethhorsley\"\n  slug: \"seth-horsley\"\n- name: \"Seth Ladd\"\n  twitter: \"sethladd\"\n  github: \"sethladd\"\n  website: \"https://sethladd.com\"\n  slug: \"seth-ladd\"\n- name: \"Seth Vargo\"\n  twitter: \"sethvargo\"\n  github: \"sethvargo\"\n  website: \"https://www.sethvargo.com\"\n  slug: \"seth-vargo\"\n- name: \"Sethupathi Asokan\"\n  github: \"\"\n  slug: \"sethupathi-asokan\"\n- name: \"Severin Ráz\"\n  github: \"\"\n  slug: \"severin-raz\"\n- name: \"Seyed Nasehi\"\n  github: \"\"\n  slug: \"seyed-nasehi\"\n- name: \"Sérgio Gil\"\n  github: \"porras\"\n  slug: \"sergio-gil\"\n  aliases:\n    - name: \"Sergio Gil\"\n      slug: \"sergio-gil\"\n    - name: \"Sergio Gil Pérez de la Manga\"\n      slug: \"sergio-gil-perez-de-la-manga\"\n- name: \"Shai Rosenfeld\"\n  github: \"shaiguitar\"\n  website: \"http://shairosenfeld.com\"\n  slug: \"shai-rosenfeld\"\n- name: \"Shaila Man\"\n  github: \"\"\n  slug: \"shaila-man\"\n- name: \"Shailvi Wakhlu\"\n  github: \"shailviw\"\n  slug: \"shailvi-wakhlu\"\n- name: \"Shan Cureton\"\n  github: \"\"\n  slug: \"shan-cureton\"\n- name: \"Shana Moore\"\n  github: \"shanalmoore\"\n  slug: \"shana-moore\"\n- name: \"Shane Becker\"\n  github: \"veganstraightedge\"\n  website: \"https://veganstraightedge.com\"\n  slug: \"shane-becker\"\n- name: \"Shane Defazio\"\n  github: \"\"\n  slug: \"shane-defazio\"\n- name: \"Shani Boston\"\n  github: \"\"\n  slug: \"shani-boston\"\n- name: \"Shannon Skipper\"\n  twitter: \"_havenn\"\n  github: \"havenwood\"\n  slug: \"shannon-skipper\"\n- name: \"Shardly Romelus\"\n  github: \"\"\n  slug: \"shardly-romelus\"\n- name: \"Sharon DeCaro\"\n  github: \"\"\n  slug: \"sharon-decaro\"\n- name: \"Sharon Rosner\"\n  github: \"noteflakes\"\n  slug: \"sharon-rosner\"\n- name: \"Sharon Steed\"\n  github: \"sharonsteed\"\n  website: \"https://sharonsteed.co\"\n  slug: \"sharon-steed\"\n- name: \"Shashank Daté\"\n  github: \"shanko\"\n  slug: \"shashank-date\"\n  aliases:\n    - name: \"Shashank Date\"\n      slug: \"shashank-date\"\n- name: \"Shaunak Pagnis\"\n  slug: \"shaunak-pagnis\"\n  github: \"shaunakpp\"\n- name: \"Shawn Bachlet\"\n  github: \"\"\n  slug: \"shawn-bachlet\"\n- name: \"Shawn Herman\"\n  github: \"\"\n  slug: \"shawn-herman\"\n- name: \"Shawnee Gao\"\n  github: \"shawneegao\"\n  slug: \"shawnee-gao\"\n- name: \"Shay Arnett\"\n  github: \"\"\n  slug: \"shay-arnett\"\n- name: \"Shay Howe\"\n  twitter: \"shayhowe\"\n  github: \"shayhowe\"\n  website: \"http://shayhowe.com\"\n  slug: \"shay-howe\"\n- name: \"Shayon Mukherjee\"\n  twitter: \"shayonj\"\n  github: \"shayonj\"\n  slug: \"shayon-mukherjee\"\n- name: \"Shelby Kelly\"\n  github: \"\"\n  slug: \"shelby-kelly\"\n- name: \"Shelby Switzer\"\n  github: \"switzersc\"\n  website: \"http://shelbyswitzer.com\"\n  slug: \"shelby-switzer\"\n- name: \"Shen Sat\"\n  github: \"\"\n  slug: \"shen-sat\"\n- name: \"Sheng Loong Su\"\n  github: \"\"\n  slug: \"sheng-loong-su\"\n- name: \"Shenthuran Satkunarasa\"\n  github: \"\"\n  slug: \"shenthuran-satkunarasa\"\n- name: \"Shevaun Coker\"\n  github: \"\"\n  slug: \"shevaun-coker\"\n- name: \"Shigeru Nakajima\"\n  github: \"ledsun\"\n  slug: \"shigeru-nakajima\"\n- name: \"Shimpei Makimoto\"\n  github: \"makimoto\"\n  slug: \"shimpei-makimoto\"\n- name: \"Shinichi Maeshima\"\n  twitter: \"netwillnet\"\n  github: \"willnet\"\n  website: \"https://willnet.jp\"\n  slug: \"shinichi-maeshima\"\n- name: \"Shinichiro Hamaji\"\n  github: \"\"\n  slug: \"shinichiro-hamaji\"\n- name: \"shinkufencer\"\n  github: \"shinkufencer\"\n  slug: \"shinkufencer\"\n- name: \"Shinta Koyanagi\"\n  github: \"yancya\"\n  slug: \"shinta-koyanagi\"\n- name: \"Shintaro Otsuka\"\n  github: \"White-Green\"\n  slug: \"shintaro-otsuka\"\n- name: \"Shintaro Suzuki\"\n  github: \"materialofmouse\"\n  slug: \"shintaro-suzuki\"\n- name: \"Shipeng Xu\"\n  github: \"\"\n  slug: \"shipeng-xu\"\n- name: \"Shiv Kumar\"\n  github: \"matlus\"\n  website: \"http://www.matlus.com\"\n  slug: \"shiv-kumar\"\n- name: \"Shiv Kumar and Vince Foley\"\n  github: \"\"\n  slug: \"shiv-kumar-and-vince-foley\"\n- name: \"Shizuo Fujita\"\n  github: \"\"\n  slug: \"shizuo-fujita\"\n- name: \"Shloka Shah\"\n  github: \"\"\n  slug: \"shloka-shah\"\n- name: \"Sho Hashimoto\"\n  github: \"\"\n  slug: \"sho-hashimoto\"\n- name: \"Shobhit Bakliwal\"\n  twitter: \"shobhitic\"\n  github: \"shobhitic\"\n  slug: \"shobhit-bakliwal\"\n- name: \"Shogo Terai\"\n  github: \"\"\n  slug: \"shogo-terai\"\n- name: \"Shohei Kobayashi\"\n  github: \"\"\n  slug: \"shohei-kobayashi\"\n- name: \"Shohei Mitani\"\n  github: \"\"\n  slug: \"shohei-mitani\"\n- name: \"Shota\"\n  github: \"\"\n  slug: \"shota\"\n- name: \"Shota Fukumori\"\n  github: \"\"\n  slug: \"shota-fukumori\"\n- name: \"Shota Nakano\"\n  github: \"shotantan\"\n  slug: \"shota-nakano\"\n- name: \"Shu Oogawara\"\n  twitter: \"expajp\"\n  github: \"expajp\"\n  slug: \"shu-oogawara\"\n  aliases:\n    - name: \"Shu OGAWARA\"\n      slug: \"shu-ogawara\"\n- name: \"shu_numata\"\n  github: \"swamp09\"\n  slug: \"shu_numata\"\n- name: \"Shugo Maeda\"\n  github: \"shugo\"\n  slug: \"shugo-maeda\"\n- name: \"Shun Hiraoka\"\n  github: \"\"\n  slug: \"shun-hiraoka\"\n- name: \"Shunichi Shinohara\"\n  github: \"\"\n  slug: \"shunichi-shinohara\"\n- name: \"Shunsuke \\\"Kokuyou\\\" Mori\"\n  twitter: \"kokuyouwind\"\n  github: \"kokuyouwind\"\n  website: \"http://kokuyouwind.com/\"\n  slug: \"shunsuke-kokuyou-mori\"\n- name: \"Shunsuke Michii\"\n  twitter: \"harukasan\"\n  github: \"harukasan\"\n  slug: \"shunsuke-michii\"\n- name: \"Shunsuke Mori\"\n  github: \"smori0202\"\n  slug: \"shunsuke-mori\"\n- name: \"Shunsuke Onishi\"\n  github: \"\"\n  slug: \"shunsuke-onishi\"\n- name: \"Shunsuke Yamada\"\n  github: \"\"\n  slug: \"shunsuke-yamada\"\n- name: \"Shuta Mugikura\"\n  github: \"\"\n  slug: \"shuta-mugikura\"\n- name: \"Shuwei Fang\"\n  github: \"\"\n  slug: \"shuwei-fang\"\n- name: \"Shweta Kale\"\n  github: \"Shwetakale\"\n  slug: \"shweta-kale\"\n- name: \"Shyouhei Urabe\"\n  github: \"shyouhei\"\n  slug: \"shyouhei-urabe\"\n  aliases:\n    - name: \"Urabe Shyouhei\"\n      slug: \"urabe-shyouhei\"\n    - name: \"卜部昌平\"\n      slug: \"shyouhei-urabe\"\n    - name: \"shyouhei\"\n      slug: \"shyouhei\"\n- name: \"Siân Griffin\"\n  github: \"\"\n  slug: \"sian-griffin\"\n- name: \"Siddhant Chothe\"\n  twitter: \"sidnc86\"\n  github: \"sidnc86\"\n  website: \"https://tekvision.in\"\n  slug: \"siddhant-chothe\"\n- name: \"Siddharth Sharma\"\n  twitter: \"sharmas1ddharth\"\n  github: \"sharmas1ddharth\"\n  website: \"https://siddharthsharma.tech\"\n  slug: \"siddharth-sharma\"\n- name: \"Sidu Ponnappa\"\n  github: \"\"\n  slug: \"sidu-ponnappa\"\n- name: \"Sihui Huang\"\n  github: \"\"\n  slug: \"sihui-huang\"\n- name: \"Sijia Wu\"\n  github: \"sijiawu\"\n  slug: \"sijia-wu\"\n- name: \"Silumesii Maboshe\"\n  twitter: \"silumesii\"\n  github: \"smaboshe\"\n  slug: \"silumesii-maboshe\"\n- name: \"Silvano Stralla\"\n  github: \"sistrall\"\n  slug: \"silvano-stralla\"\n- name: \"Silvio Montanari\"\n  github: \"\"\n  slug: \"silvio-montanari\"\n- name: \"Simo Virtanen\"\n  github: \"simovir\"\n  website: \"https://simovirtanen.com\"\n  slug: \"simo-virtanen\"\n- name: \"Simon Chiang\"\n  github: \"thinkerbot\"\n  slug: \"simon-chiang\"\n- name: \"Simon Eskildsen\"\n  twitter: \"Sirupsen\"\n  github: \"sirupsen\"\n  website: \"http://turbopuffer.com\"\n  slug: \"simon-eskildsen\"\n- name: \"Simon Fish\"\n  github: \"\"\n  slug: \"simon-fish\"\n- name: \"Simon Hildebrandt\"\n  github: \"\"\n  slug: \"simon-hildebrandt\"\n- name: \"Simon Huber\"\n  github: \"sihu\"\n  website: \"https://www.sihu.ch\"\n  slug: \"simon-huber\"\n- name: \"Simon Isler\"\n  github: \"simon-isler\"\n  website: \"https://simonisler.ch\"\n  slug: \"simon-isler\"\n- name: \"Simon Kaleschke\"\n  github: \"\"\n  slug: \"simon-kaleschke\"\n- name: \"Simon Kröger\"\n  github: \"simonkro\"\n  slug: \"simon-kroger\"\n- name: \"Simon Robson\"\n  github: \"\"\n  slug: \"simon-robson\"\n- name: \"Simone Carletti\"\n  twitter: \"weppos\"\n  github: \"weppos\"\n  website: \"https://simonecarletti.com\"\n  slug: \"simone-carletti\"\n- name: \"Simone D'Amico\"\n  github: \"\"\n  slug: \"simone-d-amico\"\n- name: \"Smit Shah\"\n  github: \"\"\n  slug: \"smit-shah\"\n- name: \"Smith\"\n  github: \"\"\n  slug: \"smith\"\n- name: \"smudge\"\n  github: \"smudge\"\n  slug: \"nathan-griffith\"\n  aliases:\n    - name: \"Nathan Griffith\"\n      slug: \"nathan-griffith\"\n- name: \"Snehal Ahire\"\n  github: \"snehalahire\"\n  slug: \"snehal-ahire\"\n- name: \"Sofia Tania\"\n  github: \"\"\n  slug: \"sofia-tania\"\n- name: \"Sohei Takeno\"\n  github: \"\"\n  slug: \"sohei-takeno\"\n- name: \"Soichiro Isshiki\"\n  twitter: \"s_isshiki1969\"\n  github: \"sisshiki1969\"\n  slug: \"soichiro-isshiki\"\n  aliases:\n    - name: \"monochrome\"\n      slug: \"monochrome\"\n- name: \"Solomon Kahn\"\n  github: \"solomon\"\n  website: \"http://www.solomonkahn.com\"\n  slug: \"solomon-kahn\"\n- name: \"Someone at Shopify\"\n  github: \"\"\n  slug: \"someone-at-shopify\"\n- name: \"Sonal Sachdev\"\n  github: \"13-sonal\"\n  slug: \"sonal-sachdev\"\n- name: \"Sonja Hall\"\n  github: \"sonejah21\"\n  slug: \"sonja-hall\"\n- name: \"Sonja Heinen\"\n  twitter: \"sonjaheinen\"\n  github: \"sxosxo\"\n  slug: \"sonja-heinen\"\n- name: \"Sonja Peterson\"\n  github: \"sonjapeterson\"\n  slug: \"sonja-peterson\"\n- name: \"Sophia Castellarin\"\n  github: \"\"\n  slug: \"sophia-castellarin\"\n- name: \"Sorah Fukumori\"\n  twitter: \"sora_h\"\n  github: \"sorah\"\n  website: \"https://sorah.jp/\"\n  slug: \"sorah-fukumori\"\n- name: \"Soru\"\n  github: \"\"\n  slug: \"soru\"\n- name: \"soul\"\n  github: \"exSOUL\"\n  slug: \"soul\"\n- name: \"Soumya Ray\"\n  github: \"\"\n  slug: \"soumya-ray\"\n- name: \"Soutaro Matsumoto\"\n  twitter: \"soutaro\"\n  github: \"soutaro\"\n  slug: \"soutaro-matsumoto\"\n- name: \"Spike Ilacqua\"\n  github: \"spikex\"\n  website: \"http://stuff-things.net/\"\n  slug: \"spike-ilacqua\"\n- name: \"squixy\"\n  github: \"\"\n  slug: \"squixy\"\n- name: \"Sriram V\"\n  github: \"ruby-ist\"\n  website: \"https://srira.me\"\n  slug: \"sriram-v\"\n- name: \"Sroop Sunar\"\n  github: \"\"\n  slug: \"sroop-sunar\"\n- name: \"Srushti Ambekallu\"\n  github: \"\"\n  slug: \"srushti-ambekallu\"\n- name: \"Stacey McKnight\"\n  github: \"staceymck\"\n  slug: \"stacey-mcknight\"\n- name: \"Stafford Brunk\"\n  twitter: \"wingrunr21\"\n  github: \"wingrunr21\"\n  slug: \"stafford-brunk\"\n- name: \"Stan Lo\"\n  twitter: \"_st0012\"\n  github: \"st0012\"\n  website: \"https://st0012.dev\"\n  slug: \"stan-lo\"\n- name: \"Stan Ng\"\n  github: \"\"\n  slug: \"stan-ng\"\n- name: \"Stanislav German\"\n  github: \"\"\n  slug: \"stanislav-german\"\n- name: \"Stanislav Vasilev\"\n  github: \"madman10k\"\n  website: \"https://i-use-gentoo-btw.com/\"\n  slug: \"stanislav-vasilev\"\n- name: \"Starr Chen\"\n  github: \"starrchen\"\n  website: \"https://starrchen.com\"\n  slug: \"starr-chen\"\n- name: \"Starr Horne\"\n  github: \"starrhorne\"\n  website: \"http://starrhorne.com\"\n  slug: \"starr-horne\"\n- name: \"Stefan Bramble\"\n  github: \"\"\n  slug: \"stefan-bramble\"\n- name: \"Stefan Daschek\"\n  twitter: \"noniq\"\n  github: \"noniq\"\n  website: \"https://noniq.at\"\n  slug: \"stefan-daschek\"\n- name: \"Stefan Exner\"\n  twitter: \"tagolus\"\n  github: \"stex\"\n  website: \"https://stex.codes\"\n  slug: \"stefan-exner\"\n- name: \"Stefan Kanev\"\n  twitter: \"skanev\"\n  github: \"skanev\"\n  website: \"http://skanev.com/\"\n  slug: \"stefan-kanev\"\n- name: \"Stefan Wienert\"\n  github: \"zealot128\"\n  website: \"http://www.stefanwienert.de\"\n  slug: \"stefan-wienert\"\n- name: \"Stefan Wintermeyer\"\n  twitter: \"wintermeyer\"\n  github: \"wintermeyer\"\n  website: \"https://www.wintermeyer-consulting.de\"\n  slug: \"stefan-wintermeyer\"\n- name: \"Stefanni Brasil\"\n  twitter: \"stefannibrasil\"\n  github: \"stefannibrasil\"\n  website: \"https://stefannibrasil.me\"\n  slug: \"stefanni-brasil\"\n- name: \"Stefano Verna\"\n  twitter: \"steffoz\"\n  github: \"stefanoverna\"\n  website: \"https://squeaki.sh\"\n  slug: \"stefano-verna\"\n- name: \"Stella Cotton\"\n  github: \"stellaconyer\"\n  website: \"http://stellacotton.com\"\n  slug: \"stella-cotton\"\n- name: \"Stephan\"\n  twitter: \"shoyer\"\n  github: \"shoyer\"\n  website: \"http://stephanhoyer.com\"\n  slug: \"stephan\"\n- name: \"Stephan Eberle\"\n  github: \"steviee\"\n  slug: \"stephan-eberle\"\n- name: \"Stephan Hagemann\"\n  twitter: \"shageman\"\n  github: \"shageman\"\n  website: \"https://stephanhagemann.com\"\n  slug: \"stephan-hagemann\"\n- name: \"Stephanie Betancourt\"\n  github: \"\"\n  slug: \"stephanie-betancourt\"\n- name: \"Stephanie Marx\"\n  github: \"\"\n  slug: \"stephanie-marx\"\n- name: \"Stephanie Minn\"\n  github: \"stephanieminn\"\n  slug: \"stephanie-minn\"\n- name: \"Stephanie Nemeth\"\n  github: \"\"\n  slug: \"stephanie-nemeth\"\n- name: \"Stephanie Nemeth # Magic Solution to the Tech Gender Gap (18:22)\"\n  github: \"\"\n  slug: \"stephanie-nemeth-magic-solution-to-the-tech-gender-gap-18-22\"\n- name: \"Stephen Creedon\"\n  github: \"\"\n  slug: \"stephen-creedon\"\n- name: \"Stephen Houston\"\n  github: \"\"\n  slug: \"stephen-houston\"\n- name: \"Stephen Margheim\"\n  twitter: \"fractaledmind\"\n  github: \"fractaledmind\"\n  website: \"https://fractaledmind.github.io\"\n  slug: \"stephen-margheim\"\n- name: \"Stephen McKeon\"\n  github: \"stephenmckeon\"\n  slug: \"stephen-mckeon\"\n- name: \"Stephen Prater\"\n  github: \"stephenprater\"\n  website: \"https://stephenprater.com\"\n  slug: \"stephen-prater\"\n- name: \"Stephen Schor\"\n  github: \"\"\n  slug: \"stephen-schor\"\n- name: \"Steve Berry\"\n  github: \"thoughtmerchant\"\n  website: \"http://thoughtmerchants.com\"\n  slug: \"steve-berry\"\n- name: \"Steve Butterworth\"\n  github: \"\"\n  slug: \"steve-butterworth\"\n- name: \"Steve Crow\"\n  twitter: \"cr0wst\"\n  github: \"cr0wst\"\n  website: \"https://smcrow.com\"\n  slug: \"steve-crow\"\n- name: \"Steve Downie\"\n  github: \"\"\n  slug: \"steve-downie\"\n- name: \"Steve Hackley\"\n  github: \"\"\n  slug: \"steve-hackley\"\n- name: \"Steve Jang\"\n  github: \"cruiserx\"\n  website: \"http://www.linkedin.com/in/cruiserx\"\n  slug: \"steve-jang\"\n- name: \"Steve Kinney\"\n  github: \"\"\n  slug: \"steve-kinney\"\n- name: \"Steve Klabnik\"\n  twitter: \"steveklabnik\"\n  github: \"steveklabnik\"\n  website: \"http://steveklabnik.com\"\n  slug: \"steve-klabnik\"\n- name: \"Steve Lynch\"\n  github: \"stephen-andrew-lynch\"\n  slug: \"steve-lynch\"\n- name: \"Steve Reinke\"\n  github: \"\"\n  slug: \"steve-reinke\"\n- name: \"Steve Ringo\"\n  github: \"\"\n  slug: \"steve-ringo\"\n- name: \"Steve Sanderson\"\n  github: \"\"\n  slug: \"steve-sanderson\"\n- name: \"Steven Baker\"\n  twitter: \"srbaker\"\n  github: \"srbaker\"\n  website: \"http://stevenrbaker.com/\"\n  slug: \"steven-baker\"\n  aliases:\n    - name: \"Steven R. Baker\"\n      slug: \"steven-r-baker\"\n- name: \"Steven Harms\"\n  github: \"\"\n  slug: \"steven-harms\"\n- name: \"Steven Hicks\"\n  github: \"pepopowitz\"\n  slug: \"steven-hicks\"\n- name: \"Steven T Ancheta\"\n  github: \"stancheta\"\n  slug: \"steven-t-ancheta\"\n  aliases:\n    - name: \"Steven Ancheta\"\n      slug: \"steven-ancheta\"\n- name: \"Steven Talcott Smith\"\n  github: \"stalcottsmith\"\n  website: \"http://aelogica.com/\"\n  slug: \"steven-talcott-smith\"\n- name: \"Steven Yap\"\n  github: \"\"\n  slug: \"steven-yap\"\n- name: \"Strand McCutchen\"\n  github: \"\"\n  slug: \"strand-mccutchen\"\n- name: \"Stuart Halloway\"\n  github: \"\"\n  slug: \"stuart-halloway\"\n- name: \"Stuart Harrison\"\n  github: \"\"\n  slug: \"stuart-harrison\"\n- name: \"Stéphane Akkaoui\"\n  github: \"\"\n  slug: \"stephane-akkaoui\"\n- name: \"Stéphane Bisinger\"\n  twitter: \"SteBjoerne\"\n  github: \"kjir\"\n  website: \"https://www.sbisinger.ch/\"\n  slug: \"stephane-bisinger\"\n- name: \"Stéphane Hanser\"\n  github: \"\"\n  slug: \"stephane-hanser\"\n- name: \"Stéphanie Chhim\"\n  github: \"\"\n  slug: \"stephanie-chhim\"\n- name: \"Su Peng Han (蘇芃翰)\"\n  github: \"\"\n  slug: \"su-peng-han\"\n- name: \"Subin Siby\"\n  twitter: \"SubinSiby\"\n  github: \"subins2000\"\n  website: \"https://subinsb.com/projects\"\n  slug: \"subin-siby\"\n- name: \"Sue Smith\"\n  github: \"SueSmith\"\n  slug: \"sue-smith\"\n- name: \"Sugendran Ganess\"\n  github: \"\"\n  slug: \"sugendran-ganess\"\n- name: \"Sumana Harihareswara\"\n  twitter: \"brainwane\"\n  github: \"brainwane\"\n  website: \"http://www.changeset.nyc\"\n  slug: \"sumana-harihareswara\"\n- name: \"Sumeet Jain\"\n  twitter: \"sumeetjain\"\n  github: \"sumeetjain\"\n  website: \"http://sumeetjain.com\"\n  slug: \"sumeet-jain\"\n- name: \"Sumit Dey\"\n  github: \"sumitdey035\"\n  slug: \"sumit-dey\"\n- name: \"Sun Park\"\n  github: \"\"\n  slug: \"sun-park\"\n- name: \"Sun-Li Beatteay\"\n  github: \"\"\n  slug: \"sun-li-beatteay\"\n- name: \"Sunao Hogelog Komuro\"\n  github: \"hogelog\"\n  slug: \"sunao-hogelog-komuro\"\n  aliases:\n    - name: \"hogelog\"\n      slug: \"hogelog\"\n- name: \"Sunjay Armstead\"\n  github: \"sarmstead\"\n  website: \"https://sunjayarmstead.com\"\n  slug: \"sunjay-armstead\"\n- name: \"Sunny Ripert\"\n  github: \"sunny\"\n  website: \"https://sunfox.org/\"\n  slug: \"sunny-ripert\"\n- name: \"Surbhi Gupta\"\n  github: \"\"\n  slug: \"surbhi-gupta\"\n- name: \"Susan Jones\"\n  github: \"\"\n  slug: \"susan-jones\"\n- name: \"Suzan Bond\"\n  github: \"suzanbond\"\n  slug: \"suzan-bond\"\n- name: \"Sven Dittmer\"\n  github: \"\"\n  slug: \"sven-dittmer\"\n- name: \"Sven Fuchs\"\n  github: \"svenfuchs\"\n  slug: \"sven-fuchs\"\n- name: \"Svenja Schäfer\"\n  github: \"slickepinne\"\n  slug: \"svenja-schafer\"\n- name: \"Svyatoslav Kryukov\"\n  github: \"skryukov\"\n  slug: \"svyatoslav-kryukov\"\n- name: \"Swanand Pagnis\"\n  github: \"\"\n  slug: \"swanand-pagnis\"\n- name: \"Sweta Sanghavi\"\n  github: \"hellosweta\"\n  slug: \"sweta-sanghavi\"\n- name: \"Syed Faraaz Ahmad\"\n  twitter: \"Faraaz98\"\n  github: \"faraazahmad\"\n  website: \"https://faraazahmad.github.io\"\n  slug: \"syed-faraaz-ahmad\"\n- name: \"sylph01\"\n  github: \"\"\n  slug: \"sylph01\"\n- name: \"Sylvain Abélard\"\n  github: \"abelards\"\n  website: \"https://maitre-du-monde.fr\"\n  slug: \"sylvain-abelard\"\n- name: \"Sylvain Pontoreau\"\n  github: \"\"\n  slug: \"sylvain-pontoreau\"\n- name: \"Sylvia Choong\"\n  github: \"\"\n  slug: \"sylvia-choong\"\n- name: \"Szymon Fiedler\"\n  github: \"fidel\"\n  slug: \"szymon-fiedler\"\n- name: \"Sébastien Faure\"\n  github: \"\"\n  slug: \"sebastien-faure\"\n- name: \"Sławek Sobótka\"\n  github: \"slaweksobotka\"\n  website: \"https://www.bottega.com.pl\"\n  slug: \"slawek-sobotka\"\n- name: \"T.J. Schuck\"\n  github: \"\"\n  slug: \"t-j-schuck\"\n- name: \"ta1kt0me\"\n  github: \"\"\n  slug: \"ta1kt0me\"\n- name: \"Tadashi Saito\"\n  twitter: \"_tad_\"\n  github: \"tadd\"\n  slug: \"tadashi-saito\"\n- name: \"Tadej Murovec\"\n  twitter: \"tadejm\"\n  github: \"tadejm\"\n  slug: \"tadej-murovec\"\n- name: \"Tae Noppakun Wongsrinoppakun\"\n  github: \"\"\n  slug: \"tae-noppakun-wongsrinoppakun\"\n- name: \"Taiga ASANO\"\n  github: \"\"\n  slug: \"taiga-asano\"\n- name: \"Taiju Higashi\"\n  github: \"\"\n  slug: \"taiju-higashi\"\n- name: \"Takafumi ONAKA\"\n  twitter: \"onk\"\n  github: \"onk\"\n  slug: \"takafumi-onaka\"\n- name: \"Takaharu Yamamoto\"\n  github: \"\"\n  slug: \"takaharu-yamamoto\"\n- name: \"Takahiro Tsuchiya\"\n  github: \"corocn\"\n  slug: \"takahiro-tsuchiya\"\n- name: \"Takashi Hatakeyama\"\n  github: \"\"\n  slug: \"takashi-hatakeyama\"\n- name: \"Takashi Kokubun\"\n  twitter: \"k0kubun\"\n  github: \"k0kubun\"\n  slug: \"takashi-kokubun\"\n- name: \"Takashi Yoneuchi\"\n  twitter: \"y0n3uchy\"\n  github: \"lmt-swallow\"\n  website: \"https://shift-js.info\"\n  slug: \"takashi-yoneuchi\"\n- name: \"Takayuki Matsubara\"\n  twitter: \"ma2ge\"\n  github: \"ma2gedev\"\n  slug: \"takayuki-matsubara\"\n- name: \"Takeru Ushio\"\n  github: \"TakeruUshio\"\n  slug: \"takeru-ushio\"\n- name: \"Takeshi KOMIYA\"\n  github: \"\"\n  slug: \"takeshi-komiya\"\n- name: \"Takeshi Watanabe\"\n  github: \"take-cheeze\"\n  website: \"https://github.com/take-cheeze\"\n  slug: \"takeshi-watanabe\"\n- name: \"Takeshi Yabe\"\n  github: \"\"\n  slug: \"takeshi-yabe\"\n- name: \"Taketo Takashima\"\n  twitter: \"taketo1113\"\n  github: \"taketo1113\"\n  slug: \"taketo-takashima\"\n- name: \"Takumasa Ochi\"\n  github: \"aeroastro\"\n  website: \"https://twitter.com/NekomimiMaster\"\n  slug: \"takumasa-ochi\"\n- name: \"Takumi Shotoku\"\n  github: \"\"\n  slug: \"takumi-shotoku\"\n- name: \"Takuya Jumbo Nakamura\"\n  github: \"deckeye\"\n  slug: \"takuya-jumbo-nakamura\"\n- name: \"Takuya Matsumoto\"\n  github: \"\"\n  slug: \"takuya-matsumoto\"\n- name: \"Takuya Mukohira\"\n  github: \"\"\n  slug: \"takuya-mukohira\"\n- name: \"Takuya Nishimoto\"\n  twitter: \"24motz\"\n  github: \"nishimotz\"\n  website: \"https://ja.nishimotz.com\"\n  slug: \"takuya-nishimoto\"\n- name: \"Tal Safran\"\n  github: \"talsafran\"\n  website: \"http://talsafran.com\"\n  slug: \"tal-safran\"\n- name: \"Talysson Oliveira Cassiano\"\n  twitter: \"talyssonoc\"\n  github: \"talyssonoc\"\n  slug: \"talysson-oliveira-cassiano\"\n  aliases:\n    - name: \"Talysson de Oliveira Cassiano\"\n      slug: \"talysson-de-oliveira-cassiano\"\n    - name: \"Talysson Cassiano\"\n      slug: \"talysson-cassiano\"\n- name: \"Tammer Saleh\"\n  github: \"\"\n  slug: \"tammer-saleh\"\n- name: \"Tanaka Akira\"\n  github: \"akitana-airtanker\"\n  slug: \"tanaka-akira\"\n- name: \"Tanaka Mutakwa\"\n  github: \"\"\n  slug: \"tanaka-mutakwa\"\n- name: \"Tanin Na Nakorn\"\n  twitter: \"tanin\"\n  github: \"tanin47\"\n  website: \"https://superintendent.app\"\n  slug: \"tanin-na-nakorn\"\n- name: \"Tanner Burson\"\n  github: \"tannerburson\"\n  website: \"https://tannerburson.com\"\n  slug: \"tanner-burson\"\n- name: \"Tara Scherner de la Fuente\"\n  github: \"wisetara\"\n  slug: \"tara-scherner-de-la-fuente\"\n- name: \"Tash Postolovski\"\n  github: \"\"\n  slug: \"tash-postolovski\"\n- name: \"Tatiana Soukiassian\"\n  twitter: \"binaryberry\"\n  github: \"binaryberry\"\n  slug: \"tatiana-soukiassian\"\n- name: \"Tatiana Vasilyeva\"\n  github: \"tanushka816\"\n  slug: \"tatiana-vasilyeva\"\n- name: \"Tatsuhiro Ujihisa\"\n  github: \"\"\n  slug: \"tatsuhiro-ujihisa\"\n- name: \"Tatsuya Sonokawa\"\n  github: \"\"\n  slug: \"tatsuya-sonokawa\"\n- name: \"Tay DeHerrera Jimenez\"\n  github: \"tayjames\"\n  slug: \"tay-deherrera-jimenez\"\n- name: \"Tayfun Öziş Erikan\"\n  github: \"tayfunoziserikan\"\n  slug: \"tayfun-ozis-erikan\"\n- name: \"Taylor Jones\"\n  github: \"monitorjbl\"\n  website: \"http://monitorjbl.github.io\"\n  slug: \"taylor-jones\"\n- name: \"TBA\"\n  github: \"\"\n  slug: \"tba\"\n- name: \"TBD\"\n  github: \"\"\n  slug: \"tbd\"\n- name: \"Teck\"\n  github: \"teckliew\"\n  slug: \"teck\"\n- name: \"Ted Johansson\"\n  github: \"drenmi\"\n  slug: \"ted-johansson\"\n- name: \"Ted O'Meara\"\n  github: \"\"\n  slug: \"ted-o-meara\"\n- name: \"Ted Tash\"\n  github: \"\"\n  slug: \"ted-tash\"\n- name: \"Tejas Deinkar\"\n  github: \"\"\n  slug: \"tejas-deinkar\"\n- name: \"Tejas Dinkar\"\n  github: \"gja\"\n  slug: \"tejas-dinkar\"\n- name: \"Tekin Süleyman\"\n  twitter: \"tekin\"\n  github: \"tekin\"\n  website: \"https://tekin.co.uk\"\n  slug: \"tekin-suleyman\"\n- name: \"Terence Lee\"\n  twitter: \"hone02\"\n  github: \"hone\"\n  website: \"http://hone.heroku.com\"\n  slug: \"terence-lee\"\n- name: \"Teresa Martyny\"\n  github: \"\"\n  slug: \"teresa-martyny\"\n- name: \"Terian Koscik\"\n  github: \"spinecone\"\n  website: \"http://pineconedoesthings.com/\"\n  slug: \"terian-koscik\"\n- name: \"Tess Griffin\"\n  github: \"tessgriffin\"\n  slug: \"tess-griffin\"\n- name: \"Tetiana Chupryna\"\n  github: \"\"\n  slug: \"tetiana-chupryna\"\n- name: \"Tetsuya Hirota\"\n  github: \"sup-hirota\"\n  slug: \"tetsuya-hirota\"\n- name: \"Thai Wood\"\n  twitter: \"ThaiWoodHere\"\n  github: \"thaiwood\"\n  website: \"https://ResilienceRoundup.com\"\n  slug: \"thai-wood\"\n- name: \"Thatthep Vorrasing\"\n  github: \"\"\n  slug: \"thatthep-vorrasing\"\n- name: \"Thayer Prime\"\n  github: \"\"\n  slug: \"thayer-prime\"\n- name: \"the rubycorns\"\n  github: \"\"\n  slug: \"the-rubycorns\"\n- name: \"Thiago Massa\"\n  github: \"thiagofm\"\n  slug: \"thiago-massa\"\n- name: \"Thiago Pradi\"\n  github: \"\"\n  slug: \"thiago-pradi\"\n- name: \"Thiago Ribeiro\"\n  github: \"thiagovsk\"\n  slug: \"thiago-ribeiro\"\n- name: \"Thiago Scalone\"\n  github: \"scalone\"\n  slug: \"thiago-scalone\"\n- name: \"Thibault Villard\"\n  github: \"\"\n  slug: \"thibault-villard\"\n- name: \"Thibaut Barrère\"\n  github: \"thbar\"\n  website: \"https://www.kiba-etl.org\"\n  slug: \"thibaut-barrere\"\n- name: \"Thierry Deo\"\n  github: \"\"\n  slug: \"thierry-deo\"\n- name: \"Thijs Cadier\"\n  twitter: \"thijsc\"\n  github: \"thijsc\"\n  website: \"https://www.appsignal.com\"\n  slug: \"thijs-cadier\"\n- name: \"Thilo Utke\"\n  github: \"thilo\"\n  website: \"https://www.cobot.me\"\n  slug: \"thilo-utke\"\n- name: \"Third Coast Comedy Club\"\n  github: \"\"\n  slug: \"third-coast-comedy-club\"\n- name: \"Thomas Arni\"\n  github: \"sunsations\"\n  website: \"http://thomasarni.com\"\n  slug: \"thomas-arni\"\n- name: \"Thomas Cannon\"\n  github: \"tcannonfodder\"\n  slug: \"thomas-cannon\"\n- name: \"Thomas Carr\"\n  github: \"htcarr3\"\n  slug: \"thomas-carr\"\n- name: \"Thomas Countz\"\n  twitter: \"thomascountz\"\n  github: \"thomascountz\"\n  website: \"https://thomascountz.com\"\n  slug: \"thomas-countz\"\n- name: \"Thomas Darde\"\n  github: \"\"\n  slug: \"thomas-darde\"\n- name: \"Thomas E Enebo\"\n  github: \"enebo\"\n  website: \"http://blog.enebo.com/\"\n  slug: \"thomas-e-enebo\"\n  aliases:\n    - name: \"Thomas E. Enebo\"\n      slug: \"thomas-e-enebo\"\n    - name: \"Thomas Enebo\"\n      slug: \"thomas-enebo\"\n    - name: \"Tom Enebo\"\n      slug: \"tom-enebo\"\n    - name: \"Tom E Enebo\"\n      slug: \"tom-e-enebo\"\n    - name: \"Tom E. Enebo\"\n      slug: \"tom-e-enebo\"\n- name: \"Thomas Edward Figg\"\n  github: \"\"\n  slug: \"thomas-edward-figg\"\n- name: \"Thomas Frey\"\n  github: \"australianmint\"\n  slug: \"thomas-frey\"\n- name: \"Thomas Himawan\"\n  github: \"\"\n  slug: \"thomas-himawan\"\n- name: \"Thomas Leitner\"\n  github: \"gettalong\"\n  website: \"https://gettalong.org\"\n  slug: \"thomas-leitner\"\n- name: \"Thomas Mann\"\n  twitter: \"thomaspaulmann\"\n  github: \"thomaspaulmann\"\n  website: \"https://thomaspaulmann.com\"\n  slug: \"thomas-mann\"\n- name: \"Thomas Marshall\"\n  github: \"\"\n  slug: \"thomas-marshall\"\n- name: \"Thomas McGoey-Smith\"\n  github: \"\"\n  slug: \"thomas-mcgoey-smith\"\n- name: \"Thomas Meeks\"\n  github: \"thomas\"\n  slug: \"thomas-meeks\"\n- name: \"Thomas Pomfret\"\n  github: \"bob-p\"\n  slug: \"thomas-pomfret\"\n- name: \"Thomas Riboulet\"\n  github: \"\"\n  slug: \"thomas-riboulet\"\n- name: \"Thomas Ritter\"\n  github: \"nethad\"\n  website: \"https://www.nethad.io/\"\n  slug: \"thomas-ritter\"\n- name: \"Thomas Shafer\"\n  github: \"trshafer\"\n  slug: \"thomas-shafer\"\n- name: \"Thomas Witt\"\n  github: \"\"\n  slug: \"thomas-witt\"\n- name: \"Thong Kuah\"\n  github: \"\"\n  slug: \"thong-kuah\"\n- name: \"Thorben Schroder\"\n  github: \"\"\n  slug: \"thorben-schroder\"\n- name: \"Thorben Schröder\"\n  github: \"\"\n  slug: \"thorben-schroeder\"\n- name: \"Thorsten Ball\"\n  twitter: \"thorstenball\"\n  github: \"mrnugget\"\n  website: \"https://thorstenball.com\"\n  slug: \"thorsten-ball\"\n- name: \"Thursday Bram\"\n  github: \"\"\n  slug: \"thursday-bram\"\n- name: \"Tia Anderson\"\n  github: \"miss-tia\"\n  slug: \"tia-anderson\"\n- name: \"Tianwen (Tian) Chen\"\n  github: \"\"\n  slug: \"tianwen-tian-chen\"\n- name: \"Tijmen Brommet\"\n  github: \"tijmenb\"\n  slug: \"tijmen-brommet\"\n- name: \"Tillman Elser\"\n  github: \"trillville\"\n  slug: \"tillman-elser\"\n- name: \"Tim Breitkreutz\"\n  github: \"\"\n  slug: \"tim-breitkreutz\"\n- name: \"Tim C. Harper\"\n  github: \"\"\n  slug: \"tim-c-harper\"\n- name: \"Tim Carey\"\n  twitter: \"TimCareyCodez\"\n  github: \"tim-carey-code\"\n  website: \"https://timcarey.dev\"\n  slug: \"tim-carey\"\n- name: \"Tim Caswell\"\n  github: \"\"\n  slug: \"tim-caswell\"\n- name: \"Tim Clem\"\n  github: \"misterfifths\"\n  website: \"https://tim-clem.com\"\n  slug: \"tim-clem\"\n- name: \"Tim Connor\"\n  github: \"\"\n  slug: \"tim-connor\"\n- name: \"Tim Cowlishaw\"\n  github: \"\"\n  slug: \"tim-cowlishaw\"\n- name: \"Tim Felgentreff\"\n  github: \"timfel\"\n  website: \"https://timfelgentreff.de\"\n  slug: \"tim-felgentreff\"\n- name: \"Tim Gourley\"\n  github: \"\"\n  slug: \"tim-gourley\"\n- name: \"Tim Harper\"\n  github: \"\"\n  slug: \"tim-harper\"\n- name: \"Tim Kächele\"\n  twitter: \"timkaechele\"\n  github: \"timkaechele\"\n  website: \"https://blog.timkaechele.me\"\n  slug: \"tim-kachele\"\n- name: \"Tim Lossen\"\n  github: \"tlossen\"\n  website: \"http://tim.lossen.de\"\n  slug: \"tim-lossen\"\n- name: \"Tim Mertens\"\n  github: \"tmertens\"\n  slug: \"tim-mertens\"\n- name: \"Tim Morgan\"\n  twitter: \"timmrgn\"\n  github: \"seven1m\"\n  website: \"https://timmorgan.dev\"\n  slug: \"tim-morgan\"\n- name: \"Tim Oliver\"\n  github: \"\"\n  slug: \"tim-oliver\"\n- name: \"Tim Oxley\"\n  github: \"\"\n  slug: \"tim-oxley\"\n- name: \"Tim Pietrusky\"\n  github: \"\"\n  slug: \"tim-pietrusky\"\n- name: \"Tim Riley\"\n  twitter: \"timriley\"\n  github: \"timriley\"\n  website: \"https://timriley.info\"\n  slug: \"tim-riley\"\n- name: \"Tim Schmelmer\"\n  github: \"timbogit\"\n  website: \"http://www.timschmelmer.com\"\n  slug: \"tim-schmelmer\"\n- name: \"Tim Tyrrell\"\n  twitter: \"timtyrrell\"\n  github: \"timtyrrell\"\n  website: \"https://blog.tyrrell.io/\"\n  slug: \"tim-tyrrell\"\n- name: \"Tim Wei\"\n  github: \"\"\n  slug: \"tim-wei\"\n- name: \"Timmy Crawford\"\n  github: \"\"\n  slug: \"timmy-crawford\"\n- name: \"Timofey Tsvetkov\"\n  github: \"\"\n  slug: \"timofey-tsvetkov\"\n- name: \"Tinco Andringa\"\n  github: \"\"\n  slug: \"tinco-andringa\"\n- name: \"TjV\"\n  github: \"\"\n  slug: \"tjv\"\n- name: \"Tobi Lehman\"\n  github: \"\"\n  slug: \"tobi-lehman\"\n- name: \"Tobias Lütke\"\n  twitter: \"tobi\"\n  github: \"tobi\"\n  slug: \"tobias-lutke\"\n- name: \"Tobias Meyer\"\n  github: \"hope-it-works\"\n  website: \"https://hope-it-works.de\"\n  slug: \"tobias-meyer\"\n- name: \"Tobias Pfeiffer\"\n  twitter: \"PragTob\"\n  github: \"pragtob\"\n  website: \"http://pragtob.info/\"\n  slug: \"tobias-pfeiffer\"\n- name: \"Tobias Schulz-Hess\"\n  github: \"\"\n  slug: \"tobias-schulz-hess\"\n- name: \"Tobias Schwab\"\n  twitter: \"tobstarr\"\n  github: \"tobstarr\"\n  slug: \"tobias-schwab\"\n- name: \"Tobiasz Waszak\"\n  github: \"tobiaszwaszak\"\n  website: \"https://tobiaszwaszak.com\"\n  slug: \"tobiasz-waszak\"\n- name: \"Toby Hede\"\n  github: \"tobyhede\"\n  website: \"http://tobyhede.com/\"\n  slug: \"toby-hede\"\n- name: \"Toby Nieboer\"\n  github: \"\"\n  slug: \"toby-nieboer\"\n- name: \"Tod Beardsley\"\n  github: \"\"\n  slug: \"tod-beardsley\"\n- name: \"Todd Dickerson\"\n  github: \"\"\n  slug: \"todd-dickerson\"\n- name: \"Todd Kaufman\"\n  github: \"tkaufman\"\n  website: \"https://www.testdouble.com\"\n  slug: \"todd-kaufman\"\n- name: \"Todd Kummer\"\n  github: \"toddkummer\"\n  website: \"https://www.linkedin.com/in/rockridgesolutions/\"\n  slug: \"todd-kummer\"\n- name: \"Todd Schneider\"\n  github: \"tcs021\"\n  slug: \"todd-schneider\"\n- name: \"Todd Sedano\"\n  github: \"professor\"\n  slug: \"todd-sedano\"\n- name: \"TODO\"\n  github: \"\"\n  slug: \"todo\"\n- name: \"tokujiros\"\n  github: \"\"\n  slug: \"tokujiros\"\n- name: \"Tom Adams\"\n  github: \"\"\n  slug: \"tom-adams\"\n- name: \"Tom Black\"\n  twitter: \"blacktm\"\n  github: \"blacktm\"\n  website: \"https://blacktm.com\"\n  slug: \"tom-black\"\n- name: \"Tom Blomfield\"\n  github: \"\"\n  slug: \"tom-blomfield\"\n- name: \"Tom Brown\"\n  twitter: \"tomwiththeweath\"\n  github: \"herestomwiththeweather\"\n  website: \"https://herestomwiththeweather.com\"\n  slug: \"tom-brown\"\n- name: \"Tom Chambers\"\n  github: \"\"\n  slug: \"tom-chambers\"\n- name: \"Tom Dale\"\n  github: \"tomdale\"\n  website: \"http://tomdale.net\"\n  slug: \"tom-dale\"\n- name: \"Tom Dalling\"\n  github: \"\"\n  slug: \"tom-dalling\"\n- name: \"Tom de Bruijn\"\n  github: \"tombruijn\"\n  website: \"https://tomdebruijn.com\"\n  slug: \"tom-de-bruijn\"\n- name: \"Tom Gamon\"\n  github: \"\"\n  slug: \"tom-gamon\"\n- name: \"Tom Heina\"\n  github: \"\"\n  slug: \"tom-heina\"\n- name: \"Tom Lee\"\n  github: \"\"\n  slug: \"tom-lee\"\n- name: \"Tom Lord\"\n  github: \"\"\n  slug: \"tom-lord\"\n- name: \"Tom Macklin\"\n  github: \"tmacklin\"\n  slug: \"tom-macklin\"\n- name: \"Tom Mornini\"\n  github: \"\"\n  slug: \"tom-mornini\"\n- name: \"Tom Preston-Werner\"\n  github: \"mojombo\"\n  slug: \"tom-preston-werner\"\n  aliases:\n    - name: \"Tom Preston Werner\"\n      slug: \"tom-preston-werner\"\n- name: \"Tom Ridge\"\n  github: \"\"\n  slug: \"tom-ridge\"\n- name: \"Tom Rossi\"\n  twitter: \"tomrossi7\"\n  github: \"tomrossi7\"\n  website: \"https://www.higherpixels.com\"\n  slug: \"tom-rossi\"\n- name: \"Tom Stuart\"\n  twitter: \"tomstuart\"\n  github: \"tomstuart\"\n  website: \"https://tomstu.art/\"\n  slug: \"tom-stuart\"\n- name: \"Tom Stuart @mortice\"\n  github: \"rentalcustard\"\n  twitter: \"rentalcustard\"\n  website: \"http://www.tomstuart.co.uk\"\n  slug: \"tom-stuart-mortice\"\n  aliases:\n    - name: \"mortice\"\n      slug: \"mortice\"\n- name: \"Tom Wheeler\"\n  github: \"tomwheeler\"\n  slug: \"tom-wheeler\"\n- name: \"Tom Woo\"\n  github: \"\"\n  slug: \"tom-woo\"\n- name: \"Tomasz Cudziło\"\n  github: \"\"\n  slug: \"tomasz-cudzilo\"\n- name: \"Tomasz Donarski\"\n  github: \"\"\n  slug: \"tomasz-donarski\"\n- name: \"Tomasz Jóźwik\"\n  github: \"tjozwik\"\n  website: \"https://tjozwik.eu\"\n  slug: \"tomasz-jozwik\"\n- name: \"Tomasz Stachewicz\"\n  twitter: \"_tomash\"\n  github: \"tomash\"\n  website: \"https://tomash.wrug.eu\"\n  slug: \"tomasz-stachewicz\"\n- name: \"Tomasz TODO\"\n  github: \"\"\n  slug: \"tomasz-todo\"\n- name: \"Tomasz Wójcik\"\n  twitter: \"prgTW\"\n  github: \"prgtw\"\n  website: \"https://pl.linkedin.com/in/prgTW/en\"\n  slug: \"tomasz-wojcik\"\n- name: \"Tomek Rusiłko\"\n  github: \"rusilko\"\n  slug: \"tomek-rusilko\"\n- name: \"Tomek Skuta\"\n  github: \"tomekskuta\"\n  slug: \"tomek-skuta\"\n- name: \"Tomek W\"\n  github: \"\"\n  slug: \"tomek-w\"\n- name: \"Tomisin Alu\"\n  twitter: \"IamDexterity\"\n  github: \"MalcolmTomisin\"\n  slug: \"tomisin-alu\"\n- name: \"Tomohiro Hashidate\"\n  twitter: \"joker1007\"\n  github: \"joker1007\"\n  website: \"http://joker1007.hatenablog.com/\"\n  slug: \"tomohiro-hashidate\"\n  aliases:\n    - name: \"joker1007\"\n      slug: \"joker1007\"\n- name: \"Tomohiro Suwa\"\n  github: \"\"\n  slug: \"tomohiro-suwa\"\n- name: \"Tomoya Ishida\"\n  twitter: \"tompng\"\n  github: \"tompng\"\n  website: \"http://twitter.com/tompng/\"\n  slug: \"tomoya-ishida\"\n- name: \"Tomoya Kawanishi\"\n  github: \"\"\n  slug: \"tomoya-kawanishi\"\n- name: \"Tomoyuki Chikanaga\"\n  twitter: \"nagachika\"\n  github: \"nagachika\"\n  website: \"https://twitter.com/nagachika\"\n  slug: \"tomoyuki-chikanaga\"\n  aliases:\n    - name: \"nagachika\"\n      slug: \"nagachika\"\n- name: \"Tomáš Dundáček\"\n  github: \"tomasdundacek\"\n  website: \"http://tomas.dundacek.cz\"\n  slug: \"tomas-dundacek\"\n- name: \"Toni Rib\"\n  twitter: \"tonimarierib\"\n  github: \"tonirib\"\n  slug: \"toni-rib\"\n- name: \"Tony Arcieri\"\n  github: \"tarcieri\"\n  website: \"https://tonyarcieri.com\"\n  slug: \"tony-arcieri\"\n- name: \"Tony Drake\"\n  twitter: \"t27duck\"\n  github: \"t27duck\"\n  website: \"http://www.t27duck.com\"\n  slug: \"tony-drake\"\n- name: \"Tony Hansord\"\n  github: \"\"\n  slug: \"tony-hansord\"\n- name: \"Tony Navarre\"\n  github: \"\"\n  slug: \"tony-navarre\"\n- name: \"Tony Pitale\"\n  github: \"\"\n  slug: \"tony-pitale\"\n- name: \"Tony Vincent\"\n  twitter: \"TonyThayil\"\n  github: \"tonyvince\"\n  slug: \"tony-vincent\"\n- name: \"Tony Wieczorek\"\n  github: \"\"\n  slug: \"tony-wieczorek\"\n- name: \"Tony Yunker\"\n  github: \"\"\n  slug: \"tony-yunker\"\n- name: \"Tora Kouno\"\n  github: \"\"\n  slug: \"tora-kouno\"\n- name: \"Tori Machen\"\n  github: \"victoriamachen\"\n  slug: \"tori-machen\"\n- name: \"Torsten Rüger\"\n  github: \"rubydesign\"\n  website: \"https://codeberg.org/rubydesign\"\n  slug: \"torsten-ruger\"\n- name: \"Torsten Schönebaum\"\n  github: \"tosch\"\n  website: \"http://www.torstenschoenebaum.de\"\n  slug: \"torsten-schonebaum\"\n- name: \"Toru Kawamura\"\n  twitter: \"tkawa\"\n  github: \"tkawa\"\n  website: \"http://d.hatena.ne.jp/tkawa/\"\n  slug: \"toru-kawamura\"\n- name: \"Toshiaki \\\"bash\\\" KOSHIBA\"\n  github: \"bash0C7\"\n  slug: \"toshiaki-bash-koshiba\"\n- name: \"Toshiaki Koshiba\"\n  github: \"\"\n  slug: \"toshiaki-koshiba\"\n- name: \"toshimaru\"\n  github: \"\"\n  slug: \"toshimaru\"\n- name: \"Travis Dockter\"\n  twitter: \"travis_code\"\n  github: \"travisdock\"\n  bluesky: \"travis-code.bsky.social\"\n  slug: \"travis-dockter\"\n- name: \"Travis Hillery\"\n  github: \"\"\n  slug: \"travis-hillery\"\n- name: \"Travis Turner\"\n  github: \"travis-turner\"\n  website: \"https://evilmartians.com\"\n  slug: \"travis-turner\"\n- name: \"Tresor Bireke\"\n  github: \"\"\n  slug: \"tresor-bireke\"\n- name: \"Trever Yarrish\"\n  github: \"tyarrish\"\n  website: \"http://www.codingzeal.com\"\n  slug: \"trever-yarrish\"\n- name: \"Trevor Elliott\"\n  github: \"elliottt\"\n  website: \"http://elliottt.github.io\"\n  slug: \"trevor-elliott\"\n- name: \"Trevor Rowe\"\n  github: \"trevorrowe\"\n  slug: \"trevor-rowe\"\n- name: \"Trey Miller\"\n  github: \"trey-miller\"\n  slug: \"trey-miller\"\n- name: \"Tri Hari\"\n  github: \"\"\n  slug: \"tri-hari\"\n- name: \"Tricia Ball\"\n  github: \"tlball\"\n  slug: \"tricia-ball\"\n- name: \"Tristan Penman\"\n  github: \"\"\n  slug: \"tristan-penman\"\n- name: \"Trotter Cashion\"\n  github: \"trotter\"\n  website: \"http://trottercashion.com\"\n  slug: \"trotter-cashion\"\n- name: \"Troy Davis\"\n  github: \"\"\n  slug: \"troy-davis\"\n- name: \"Tsutomu Katsube\"\n  github: \"tikkss\"\n  slug: \"tsutomu-katsube\"\n- name: \"Tsvetelina Borisova\"\n  github: \"tborisova\"\n  slug: \"tsvetelina-borisova\"\n- name: \"Tung Nguyen\"\n  github: \"tung\"\n  website: \"https://tung.github.io\"\n  slug: \"tung-nguyen\"\n- name: \"Tushar Maroo\"\n  twitter: \"tusharmaroo\"\n  github: \"tusharmaroo\"\n  slug: \"tushar-maroo\"\n- name: \"Tute Costa\"\n  github: \"tute\"\n  website: \"https://www.tutecosta.com/software-developer/\"\n  slug: \"tute-costa\"\n- name: \"Tworit Kumar Dash\"\n  github: \"\"\n  slug: \"tworit-kumar-dash\"\n- name: \"Tyler Ackerman\"\n  github: \"uglyfuego\"\n  slug: \"tyler-ackerman\"\n- name: \"Tyler Bird\"\n  github: \"\"\n  slug: \"tyler-bird\"\n- name: \"Tyler Hunt\"\n  github: \"\"\n  slug: \"tyler-hunt\"\n- name: \"Tyler Jennings\"\n  github: \"\"\n  slug: \"tyler-jennings\"\n- name: \"Tyler Lemburg\"\n  github: \"tlemburg\"\n  slug: \"tyler-lemburg\"\n- name: \"Tyler McMullen\"\n  github: \"tyler\"\n  website: \"https://www.fastly.com\"\n  slug: \"tyler-mcmullen\"\n- name: \"Tyler Montgomery\"\n  github: \"ubermajestix\"\n  website: \"https://ubermajestix.com\"\n  slug: \"tyler-montgomery\"\n- name: \"Tymon Tobolski\"\n  twitter: \"iteamon\"\n  github: \"teamon\"\n  website: \"https://teamon.me\"\n  slug: \"tymon-tobolski\"\n- name: \"Tze Yang Ng\"\n  github: \"\"\n  slug: \"tze-yang-ng\"\n- name: \"Udbhav Gambhir\"\n  twitter: \"ngudbhav\"\n  github: \"ngudbhav\"\n  slug: \"udbhav-gambhir\"\n- name: \"Udit Gulati\"\n  github: \"uditgulati\"\n  website: \"https://uditgulati.github.io/\"\n  slug: \"udit-gulati\"\n- name: \"Ufuk Kayserilioglu\"\n  twitter: \"paracycle\"\n  github: \"paracycle\"\n  website: \"https://ufuk.dev\"\n  slug: \"ufuk-kayserilioglu\"\n- name: \"Uli Ramminger\"\n  github: \"uliramminger\"\n  website: \"https://urasepandia.de\"\n  slug: \"uli-ramminger\"\n- name: \"umeda-rizap\"\n  github: \"umeda-rizap\"\n  slug: \"umeda-rizap\"\n- name: \"unak\"\n  twitter: \"thonyunak1\"\n  github: \"uwemunak\"\n  slug: \"unak\"\n- name: \"Unknown\"\n  twitter: \"rohitscript\"\n  github: \"rohitscript\"\n  slug: \"unknown\"\n- name: \"uproad\"\n  github: \"\"\n  slug: \"uproad\"\n- name: \"Urszula Sołogub\"\n  github: \"urszulasologub\"\n  slug: \"urszula-sologub\"\n- name: \"Usaku NAKAMURA\"\n  github: \"\"\n  slug: \"usaku-nakamura\"\n- name: \"Vagmi Mudumbai\"\n  github: \"vagmi\"\n  slug: \"vagmi-mudumbai\"\n- name: \"Vaidehi Joshi\"\n  twitter: \"vaidehijoshi\"\n  github: \"vaidehijoshi\"\n  website: \"http://www.vaidehi.com\"\n  slug: \"vaidehi-joshi\"\n- name: \"Vaidy Bala\"\n  github: \"vaidybala\"\n  slug: \"vaidy-bala\"\n- name: \"Valentin Fondaratov\"\n  github: \"valich\"\n  slug: \"valentin-fondaratov\"\n- name: \"Valerie Woolard\"\n  twitter: \"valeriecodes\"\n  github: \"valeriecodes\"\n  website: \"http://valerie.codes\"\n  slug: \"valerie-woolard\"\n- name: \"Valiantsin Zavadski\"\n  github: \"Saicheg\"\n  slug: \"valiantsin-zavadski\"\n- name: \"Vamsee Kanakala\"\n  github: \"\"\n  slug: \"vamsee-kanakala\"\n- name: \"Vanessa Nimmo\"\n  github: \"\"\n  slug: \"vanessa-nimmo\"\n- name: \"Vanessa Shen\"\n  github: \"\"\n  slug: \"vanessa-shen\"\n- name: \"Varun Gandhi\"\n  github: \"typesanitizer\"\n  slug: \"varun-gandhi\"\n- name: \"Varun Sindwani\"\n  github: \"\"\n  slug: \"varun-sindwani\"\n- name: \"Vektra\"\n  github: \"vektra\"\n  website: \"http://www.vektra.com\"\n  slug: \"vektra\"\n- name: \"Ventsislav Nikolov\"\n  twitter: \"ventsislaf\"\n  github: \"ventsislaf\"\n  website: \"https://rubylift.com/\"\n  slug: \"ventsislav-nikolov\"\n- name: \"Verónica López\"\n  github: \"verolop\"\n  slug: \"veronica-lopez\"\n- name: \"Verónica Rebagliatte\"\n  github: \"\"\n  slug: \"veronica-rebagliatte\"\n- name: \"Vesa Vänskä\"\n  twitter: \"vesan\"\n  github: \"vesan\"\n  website: \"http://vesavanska.com\"\n  slug: \"vesa-vanska\"\n- name: \"Vicent Marti\"\n  github: \"\"\n  slug: \"vicent-marti\"\n- name: \"Vicky Madrid\"\n  twitter: \"VickyMadrid03\"\n  github: \"vickymadrid03\"\n  slug: \"vicky-madrid\"\n- name: \"Victor Motogna\"\n  github: \"victormotogna\"\n  website: \"https://victormotogna.github.io/\"\n  slug: \"victor-motogna\"\n- name: \"Victor Mours\"\n  github: \"\"\n  slug: \"victor-mours\"\n- name: \"Victor Shepelev\"\n  twitter: \"zverok\"\n  github: \"zverok\"\n  website: \"https://zverok.space\"\n  slug: \"victor-shepelev\"\n- name: \"Victor Turuthi\"\n  github: \"\"\n  slug: \"victor-turuthi\"\n- name: \"Victor Velazquez\"\n  twitter: \"zazvick\"\n  github: \"vicmaster\"\n  website: \"http://www.magmalabs.io\"\n  slug: \"victor-velazquez\"\n- name: \"Victoria Gonda\"\n  github: \"vgonda\"\n  website: \"http://www.victoriagonda.com/\"\n  slug: \"victoria-gonda\"\n- name: \"Victoria Guido\"\n  github: \"victoriaguido\"\n  slug: \"victoria-guido\"\n- name: \"Victoria Melnikova\"\n  twitter: \"vmelnikova_en\"\n  github: \"vicamelnikova\"\n  website: \"https://evilmartians.com/martians/victoria-melnikova\"\n  slug: \"victoria-melnikova\"\n- name: \"Vietor Davis\"\n  github: \"vietord\"\n  slug: \"vietor-davis\"\n- name: \"Vijayanand Nandam\"\n  github: \"\"\n  slug: \"vijayanand-nandam\"\n- name: \"Vikas Verma\"\n  github: \"\"\n  slug: \"vikas-verma\"\n- name: \"Viktor Fonic\"\n  github: \"\"\n  slug: \"viktor-fonic\"\n- name: \"Viktor Schmidt\"\n  twitter: \"viktorianer4\"\n  github: \"viktorianer\"\n  website: \"https://www.sternfreunde.berlin\"\n  slug: \"viktor-schmidt\"\n- name: \"Ville Lautanala\"\n  twitter: \"lautis\"\n  github: \"lautis\"\n  slug: \"ville-lautanala\"\n- name: \"Vinash\"\n  github: \"\"\n  slug: \"vinash\"\n- name: \"Vince Cabansag\"\n  github: \"\"\n  slug: \"vince-cabansag\"\n- name: \"Vince Foley\"\n  github: \"binaryseed\"\n  slug: \"vince-foley\"\n- name: \"Vincent Pochet\"\n  github: \"vincent-pochet\"\n  website: \"https://vincent.pochet.io/\"\n  slug: \"vincent-pochet\"\n- name: \"Vincent Rolea\"\n  twitter: \"vincentrolea\"\n  github: \"virolea\"\n  website: \"https://bytesbites.io\"\n  slug: \"vincent-rolea\"\n- name: \"Vincent Tourraine\"\n  github: \"\"\n  slug: \"vincent-tourraine\"\n- name: \"Vinícius Alonso\"\n  twitter: \"alonsoemacao\"\n  github: \"viniciusalonso\"\n  website: \"https://viniciusalonso.com\"\n  slug: \"vinicius-alonso\"\n  aliases:\n    - name: \"Vinicius Alonso\"\n      slug: \"vinicius-alonso\"\n- name: \"Vinícius Stock\"\n  twitter: \"vinistock\"\n  github: \"vinistock\"\n  website: \"https://vinistock.com\"\n  slug: \"vinicius-stock\"\n  aliases:\n    - name: \"Vinicius Stock\"\n      slug: \"vinicius-stock\"\n- name: \"Vipul A M\"\n  twitter: \"vipulnsward\"\n  github: \"vipulnsward\"\n  website: \"https://www.saeloun.com/team/vipul\"\n  slug: \"vipul-a-m\"\n  aliases:\n    - name: \"Vipul Am\"\n      slug: \"vipul-am\"\n- name: \"Vishal Chandnani\"\n  github: \"vshldc\"\n  slug: \"vishal-chandnani\"\n- name: \"Vishwajeetsingh Desurkar\"\n  twitter: \"VishwaDesurkar\"\n  github: \"selectus2\"\n  website: \"https://blog.vishwajeetsingh.in\"\n  slug: \"vishwajeetsingh-desurkar\"\n- name: \"Vitaly Pushkar\"\n  github: \"\"\n  slug: \"vitaly-pushkar\"\n- name: \"Vito Genovese\"\n  github: \"\"\n  slug: \"vito-genovese\"\n- name: \"Vitor Oliveira\"\n  github: \"vbrazo\"\n  website: \"imvitoroliveira\"\n  slug: \"vitor-oliveira\"\n- name: \"Vitor Pellegrino\"\n  github: \"\"\n  slug: \"vitor-pellegrino\"\n- name: \"Vlad Dyachenko\"\n  github: \"wowinter13\"\n  slug: \"vlad-dyachenko\"\n- name: \"Vladimir Dementyev\"\n  twitter: \"palkan_tula\"\n  github: \"palkan\"\n  website: \"https://twitter.com/palkan_tula\"\n  slug: \"vladimir-dementyev\"\n- name: \"Vladimir Gorodulin\"\n  github: \"\"\n  slug: \"vladimir-gorodulin\"\n- name: \"Vladimir Makarov\"\n  github: \"vnmakarov\"\n  slug: \"vladimir-makarov\"\n- name: \"Vladimir Yartsev\"\n  github: \"\"\n  slug: \"vladimir-yartsev\"\n- name: \"Vladislav Frolov\"\n  github: \"nnfrolovnn\"\n  slug: \"vladislav-frolov\"\n- name: \"Volodya Sveredyuk\"\n  github: \"sveredyuk\"\n  slug: \"volodya-sveredyuk\"\n- name: \"W. Idris Yasser\"\n  github: \"\"\n  slug: \"w-idris-yasser\"\n- name: \"Wade Winningham\"\n  github: \"wadewinningham\"\n  website: \"https://wadewinningham.com\"\n  slug: \"wade-winningham\"\n- name: \"Wagner Narde\"\n  twitter: \"wagner_n\"\n  github: \"wagner\"\n  website: \"https://wagnernarde.com\"\n  slug: \"wagner-narde\"\n- name: \"Wander Hillen\"\n  github: \"\"\n  slug: \"wander-hillen\"\n- name: \"Ward Cunningham\"\n  github: \"\"\n  slug: \"ward-cunningham\"\n- name: \"Warren Lyndes\"\n  github: \"wlyndes\"\n  slug: \"warren-lyndes\"\n- name: \"Warren Wong\"\n  twitter: \"wrrnwng\"\n  github: \"wrrnwng\"\n  website: \"https://warrenwong.org\"\n  slug: \"warren-wong\"\n- name: \"Wayne E. Seguin\"\n  twitter: \"wayneeseguin\"\n  github: \"wayneeseguin\"\n  slug: \"wayne-e-seguin\"\n  aliases:\n    - name: \"Wayne Seguin\"\n      slug: \"wayne-seguin\"\n- name: \"Weedmaps\"\n  github: \"ghostgroup\"\n  website: \"https://weedmaps.com\"\n  slug: \"weedmaps\"\n- name: \"Wei Lin Ngo\"\n  github: \"\"\n  slug: \"wei-lin-ngo\"\n- name: \"Wei Lu\"\n  github: \"\"\n  slug: \"wei-lu\"\n- name: \"Weiqing Toh\"\n  github: \"weiqingtoh\"\n  slug: \"weiqing-toh\"\n- name: \"Weldys Santos\"\n  github: \"weldyss\"\n  website: \"https://weldyss.tech\"\n  slug: \"weldys-santos\"\n- name: \"Wen-Tien Chang\"\n  github: \"ihower\"\n  website: \"https://ihower.tw\"\n  slug: \"wen-tien-chang\"\n  aliases:\n    - name: \"Wen Tien Chang\"\n      slug: \"wen-tien-chang\"\n- name: \"Wendy Calderón\"\n  github: \"riuswen\"\n  slug: \"wendy-calderon\"\n- name: \"Wesley Beary\"\n  github: \"geemus\"\n  website: \"http://geemus.com\"\n  slug: \"wesley-beary\"\n- name: \"Weston Platter\"\n  github: \"wgone\"\n  website: \"https://www.think602.com\"\n  slug: \"weston-platter\"\n- name: \"Weston Sewell\"\n  github: \"\"\n  slug: \"weston-sewell\"\n- name: \"White-Green\"\n  github: \"\"\n  slug: \"white-green\"\n- name: \"Wiktor Mociun\"\n  twitter: \"voter101\"\n  github: \"voter101\"\n  website: \"http://mociun.xyz\"\n  slug: \"wiktor-mociun\"\n- name: \"Wiktoria Dalach\"\n  github: \"dalach\"\n  website: \"https://hejo.berlin\"\n  slug: \"wiktoria-dalach\"\n- name: \"Wil Chung\"\n  github: \"\"\n  slug: \"wil-chung\"\n- name: \"Will Carey\"\n  github: \"willtcarey\"\n  slug: \"will-carey\"\n- name: \"Will Farrington\"\n  github: \"\"\n  slug: \"will-farrington\"\n- name: \"Will Jordan\"\n  github: \"wjordan\"\n  website: \"https://willjordan.us\"\n  slug: \"will-jordan\"\n- name: \"Will Leinweber\"\n  github: \"will\"\n  website: \"http://bitfission.com\"\n  slug: \"will-leinweber\"\n- name: \"Will Luongo\"\n  github: \"willluongo\"\n  slug: \"will-luongo\"\n- name: \"Will Mitchell\"\n  github: \"wvmitchell\"\n  website: \"https://www.linkedin.com/in/wvmitchell/\"\n  slug: \"will-mitchell\"\n- name: \"William Bereza\"\n  github: \"\"\n  slug: \"william-bereza\"\n- name: \"William Frey\"\n  github: \"will-frey\"\n  slug: \"william-frey\"\n- name: \"William Horton\"\n  twitter: \"hortonhearsafoo\"\n  github: \"wdhorton\"\n  slug: \"william-horton\"\n- name: \"William Jeffries\"\n  github: \"\"\n  slug: \"william-jeffries\"\n- name: \"William Notowidagdo\"\n  github: \"\"\n  slug: \"william-notowidagdo\"\n- name: \"Wilson\"\n  github: \"\"\n  slug: \"wilson\"\n- name: \"Wilson Bilkovich\"\n  github: \"\"\n  slug: \"wilson-bilkovich\"\n- name: \"Winfred Nadeau\"\n  github: \"\"\n  slug: \"winfred-nadeau\"\n- name: \"Winston Ferguson\"\n  github: \"\"\n  slug: \"winston-ferguson\"\n- name: \"Winston Lau\"\n  github: \"\"\n  slug: \"winston-lau\"\n- name: \"Winston Teo\"\n  github: \"\"\n  slug: \"winston-teo\"\n- name: \"Winston Teo Yong Wei\"\n  github: \"\"\n  slug: \"winston-teo-yong-wei\"\n- name: \"Wojciech Piekutowski\"\n  github: \"wpiekutowski\"\n  website: \"https://www.amberbit.com\"\n  slug: \"wojciech-piekutowski\"\n- name: \"Wojciech Rząsa\"\n  github: \"\"\n  slug: \"wojciech-rzasa\"\n- name: \"Wojciech Ziniewicz\"\n  github: \"wzin\"\n  website: \"https://wojtek.ziniewi.cz\"\n  slug: \"wojciech-ziniewicz\"\n- name: \"Wojtek Rząsa\"\n  github: \"\"\n  slug: \"wojtek-rzasa\"\n- name: \"Wojtek Wrona\"\n  github: \"wojtodzio\"\n  slug: \"wojtek-wrona\"\n- name: \"Wolfgang Hotwagner\"\n  github: \"\"\n  slug: \"wolfgang-hotwagner\"\n- name: \"Wolfram Arnold\"\n  twitter: \"wolframarnold\"\n  github: \"wolframarnold\"\n  website: \"https://www.linkedin.com/in/wolframarnold\"\n  slug: \"wolfram-arnold\"\n- name: \"Wrapbook\"\n  github: \"wrapbook\"\n  website: \"https://wrapbook.com\"\n  slug: \"wrapbook\"\n- name: \"wtnabe\"\n  github: \"\"\n  slug: \"wtnabe\"\n- name: \"Wyatt Ades\"\n  twitter: \"wyattades\"\n  github: \"wyattades\"\n  slug: \"wyatt-ades\"\n- name: \"Wynn Netherland\"\n  twitter: \"pengwynn\"\n  github: \"pengwynn\"\n  website: \"https://wynnnetherland.com\"\n  slug: \"wynn-netherland\"\n- name: \"Xavier Meunier\"\n  github: \"\"\n  slug: \"xavier-meunier\"\n- name: \"Xavier Noria\"\n  twitter: \"fxn\"\n  github: \"fxn\"\n  website: \"https://hashref.com\"\n  slug: \"xavier-noria\"\n- name: \"Xavier Riley\"\n  github: \"\"\n  slug: \"xavier-riley\"\n- name: \"Xavier Shay\"\n  github: \"\"\n  slug: \"xavier-shay\"\n- name: \"Xin Tian\"\n  github: \"\"\n  slug: \"xin-tian\"\n- name: \"Xiujiao Gao\"\n  github: \"xiujiao\"\n  website: \"http://www.xiujiaogao.com\"\n  slug: \"xiujiao-gao\"\n- name: \"Xuejie \\\"Rafael\\\" Xiao\"\n  github: \"\"\n  slug: \"xuejie-rafael-xiao\"\n- name: \"Yakau\"\n  github: \"\"\n  slug: \"yakau\"\n- name: \"YAMAP\"\n  github: \"\"\n  slug: \"yamap\"\n- name: \"yamori813\"\n  github: \"yamori813\"\n  slug: \"yamori813\"\n- name: \"Yan Matagne\"\n  github: \"\"\n  slug: \"yan-matagne\"\n- name: \"yana-gi\"\n  twitter: \"yana_gis\"\n  github: \"yana-gi\"\n  website: \"https://yana-g.hatenablog.com/\"\n  slug: \"yana-gi\"\n- name: \"Yang Chung\"\n  github: \"\"\n  slug: \"yang-chung\"\n- name: \"Yannick Schutz\"\n  github: \"\"\n  slug: \"yannick-schutz\"\n- name: \"Yannik González Alarcón\"\n  github: \"\"\n  slug: \"yannik-gonzalez-alarcon\"\n- name: \"Yannis Jaquet\"\n  twitter: \"yannis_\"\n  github: \"yannis\"\n  website: \"https://yannisjaquet.com\"\n  slug: \"yannis-jaquet\"\n- name: \"yappu\"\n  github: \"yappu0\"\n  slug: \"yappu\"\n  aliases:\n    - name: \"yappu0\"\n      slug: \"yappu0\"\n- name: \"Yara Debian\"\n  github: \"YaraDebian\"\n  slug: \"yara-debian\"\n- name: \"Yarden Laifenfeld\"\n  github: \"yardenlai\"\n  slug: \"yarden-laifenfeld\"\n- name: \"Yarik\"\n  github: \"\"\n  slug: \"yarik\"\n- name: \"Yaroslav Shmarov\"\n  twitter: \"yarotheslav\"\n  github: \"yshmarov\"\n  website: \"https://superails.com/playlists/turbo-native\"\n  slug: \"yaroslav-shmarov\"\n- name: \"Yasmin Archibald\"\n  github: \"\"\n  slug: \"yasmin-archibald\"\n- name: \"Yasodara Córdova\"\n  github: \"\"\n  slug: \"yasodara-cordova\"\n- name: \"Yasu Flores\"\n  github: \"yasuf\"\n  slug: \"yasu-flores\"\n- name: \"Yasuko Ohba\"\n  github: \"nay\"\n  website: \"http://ko.meadowy.net/~nay/\"\n  slug: \"yasuko-ohba\"\n- name: \"Yasuo Honda\"\n  twitter: \"yahonda\"\n  github: \"yahonda\"\n  slug: \"yasuo-honda\"\n- name: \"Yasushi Itoh\"\n  twitter: \"i2y_\"\n  github: \"i2y\"\n  website: \"http://i2y.hatenablog.com/\"\n  slug: \"yasushi-itoh\"\n- name: \"Yatish Mehta\"\n  github: \"yatish27\"\n  slug: \"yatish-mehta\"\n- name: \"Yauhen Karatkou\"\n  github: \"\"\n  slug: \"yauhen-karatkou\"\n- name: \"Yaşar Celep\"\n  twitter: \"yasaryuruyor\"\n  github: \"yasarcelep\"\n  website: \"https://yasarcelep.com\"\n  slug: \"yasar-celep\"\n- name: \"Ye Ding\"\n  github: \"dyng\"\n  slug: \"ye-ding\"\n  aliases:\n    - name: \"Ding ding Ye\"\n      slug: \"ding-ding-ye\"\n    - name: \"Ding-ding Ye\"\n      slug: \"ding-ding-ye\"\n- name: \"Yechiel Kalmenson\"\n  github: \"achasveachas\"\n  website: \"https://yechiel.me\"\n  slug: \"yechiel-kalmenson\"\n- name: \"Yehuda\"\n  twitter: \"wycats\"\n  github: \"\"\n  website: \"http://yehudakatz.com\"\n  slug: \"yehuda\"\n- name: \"Yehuda Katz\"\n  twitter: \"wycats\"\n  github: \"wycats\"\n  website: \"http://yehudakatz.com\"\n  slug: \"yehuda-katz\"\n- name: \"Yeonseok Kim\"\n  github: \"\"\n  slug: \"yeonseok-kim\"\n- name: \"Yevhenii Kurtov\"\n  github: \"\"\n  slug: \"yevhenii-kurtov\"\n- name: \"Yevhenii Yevtushenko\"\n  github: \"\"\n  slug: \"yevhenii-yevtushenko\"\n- name: \"Yi-Ting Cheng\"\n  github: \"xdite\"\n  website: \"http://xdite.com\"\n  slug: \"yi-ting-cheng\"\n  aliases:\n    - name: \"Xdite\"\n      slug: \"xdite\"\n    - name: \"Yi-Ting \\\"Xdite\\\" Cheng\"\n      slug: \"yi-ting-xdite-cheng\"\n    - name: \"YiTing \\\"Xdite\\\" Cheng\"\n      slug: \"yiting-xdite-cheng\"\n- name: \"Yichiro MASUI\"\n  github: \"\"\n  slug: \"yichiro-masui\"\n- name: \"ykpythemind\"\n  twitter: \"ykpythemind\"\n  github: \"ykpythemind\"\n  website: \"https://scrapbox.io/ykpythemind/ykpythemind\"\n  slug: \"ykpythemind\"\n- name: \"Yla Aioi\"\n  twitter: \"Little_Rubyist\"\n  github: \"little-rubyist\"\n  slug: \"yla-aioi\"\n- name: \"Ylan Segal\"\n  github: \"ylansegal\"\n  website: \"http://ylan.segal-family.com\"\n  slug: \"ylan-segal\"\n- name: \"Yoann Lecuyer\"\n  github: \"\"\n  slug: \"yoann-lecuyer\"\n- name: \"Yogi Kulkarni\"\n  github: \"\"\n  slug: \"yogi-kulkarni\"\n- name: \"Yoh Osaki\"\n  github: \"youchan\"\n  website: \"http://youchan.org\"\n  slug: \"yoh-osaki\"\n  aliases:\n    - name: \"youchan\"\n      slug: \"youchan\"\n- name: \"Yohei Yasukawa\"\n  github: \"yasulab\"\n  slug: \"yohei-yasukawa\"\n  aliases:\n    - name: \"Yasukawa Yohei\"\n      slug: \"yasukawa-yohei\"\n    - name: \"YASUKAWA Yohei\"\n      slug: \"yasukawa-yohei\"\n- name: \"Yohsuke Murase\"\n  github: \"\"\n  slug: \"yohsuke-murase\"\n- name: \"Yoko Harada\"\n  github: \"yokolet\"\n  website: \"https://yokolet.com/\"\n  slug: \"yoko-harada\"\n- name: \"Yonatan Bergman\"\n  twitter: \"yonbergman\"\n  github: \"yonbergman\"\n  website: \"http://yonbergman.com\"\n  slug: \"yonatan-bergman\"\n- name: \"Yonatan Miller\"\n  github: \"shushugah\"\n  website: \"https://shushugah.com/\"\n  slug: \"yonatan-miller\"\n- name: \"Yorick Jacquin\"\n  github: \"yjacquin\"\n  slug: \"yorick-jacquin\"\n- name: \"Yoshinori Kawasaki\"\n  twitter: \"kawasy\"\n  github: \"luvtechno\"\n  website: \"https://www.wantedly.com/id/kawasy\"\n  slug: \"yoshinori-kawasaki\"\n- name: \"Yoshiori Shoji\"\n  twitter: \"yoshiori\"\n  github: \"yoshiori\"\n  website: \"https://yoshiori.hatenablog.com/\"\n  slug: \"yoshiori-shoji\"\n- name: \"Yoskiyaki Hirano\"\n  github: \"\"\n  slug: \"yoskiyaki-hirano\"\n- name: \"Yossef Mendelssohn\"\n  github: \"\"\n  slug: \"yossef-mendelssohn\"\n- name: \"Yosuke Matsuda\"\n  twitter: \"ymtdzzz\"\n  github: \"ymtdzzz\"\n  website: \"https://ymtdzzz.dev\"\n  slug: \"yosuke-matsuda\"\n- name: \"Youssef Boulkaid\"\n  twitter: \"yboulkaid\"\n  github: \"yboulkaid\"\n  website: \"https://yboulkaid.com\"\n  slug: \"youssef-boulkaid\"\n- name: \"Youssef Chaker\"\n  twitter: \"ychaker\"\n  github: \"ychaker\"\n  website: \"http://youhoo.im\"\n  slug: \"youssef-chaker\"\n- name: \"Yudai Takada\"\n  twitter: \"ydah_\"\n  github: \"ydah\"\n  website: \"http://ydah.net/\"\n  slug: \"yudai-takada\"\n  aliases:\n    - name: \"ydah\"\n      slug: \"ydah\"\n- name: \"Yuhei Okazaki\"\n  github: \"yuuu\"\n  slug: \"yuhei-okazaki\"\n- name: \"Yuhi Sato\"\n  github: \"\"\n  slug: \"yuhi-sato\"\n- name: \"Yuichi Takeuchi\"\n  github: \"takeyuweb\"\n  website: \"https://takeyuweb.co.jp/\"\n  slug: \"yuichi-takeuchi\"\n- name: \"Yuichiro Kaneko\"\n  github: \"yui-knk\"\n  website: \"https://twitter.com/spikeolaf\"\n  slug: \"yuichiro-kaneko\"\n- name: \"Yuji Yokoo\"\n  github: \"yujiyokoo\"\n  slug: \"yuji-yokoo\"\n- name: \"Yuka Atsumi\"\n  github: \"attsumi\"\n  slug: \"yuka-atsumi\"\n- name: \"Yuka Kato\"\n  github: \"\"\n  slug: \"yuka-kato\"\n- name: \"Yuki Akamatsu\"\n  twitter: \"ukstudio\"\n  github: \"ukstudio\"\n  slug: \"yuki-akamatsu\"\n- name: \"Yuki Aki\"\n  github: \"freddi-kit\"\n  slug: \"yuki-aki\"\n- name: \"Yuki Kurihara\"\n  twitter: \"_ksss_\"\n  github: \"ksss\"\n  website: \"https://ksss.ink/\"\n  slug: \"yuki-kurihara\"\n- name: \"Yuki Nakata\"\n  twitter: \"chiku_wait\"\n  github: \"chikuwait\"\n  website: \"https://www.chikuwa.it/\"\n  slug: \"yuki-nakata\"\n- name: \"Yuki Nishijima\"\n  github: \"yuki24\"\n  website: \"http://blog.yukinishijima.net\"\n  slug: \"yuki-nishijima\"\n- name: \"Yuki Sasada\"\n  twitter: \"yotii23\"\n  github: \"\"\n  slug: \"yuki-sasada\"\n- name: \"Yuki Torii\"\n  github: \"yakitorii\"\n  slug: \"yuki-torii\"\n- name: \"Yukihiro \\\"Matz\\\" Matsumoto\"\n  twitter: \"yukihiro_matz\"\n  github: \"matz\"\n  website: \"https://matz.rubyist.net\"\n  slug: \"yukihiro-matz-matsumoto\"\n  aliases:\n    - name: \"Matz\"\n      slug: \"matz\"\n    - name: \"Yukihiro 'Matz' Matsumoto\"\n      slug: \"yukihiro-matz-matsumoto\"\n    - name: \"Yukihiro Matsumoto\"\n      slug: \"yukihiro-matsumoto\"\n    - name: \"Yukihiro Matz Matsumoto\"\n      slug: \"yukihiro-matz-matsumoto\"\n    - name: \"Yukihiro Matzumoto\"\n      slug: \"yukihiro-matzumoto\"\n- name: \"Yukimitsu Izawa\"\n  github: \"\"\n  slug: \"yukimitsu-izawa\"\n- name: \"Yulia Oletskaya\"\n  github: \"\"\n  slug: \"yulia-oletskaya\"\n- name: \"Yuliana Reyna\"\n  github: \"\"\n  slug: \"yuliana-reyna\"\n- name: \"Yuma Sawai\"\n  github: \"aaaa777\"\n  slug: \"yuma-sawai\"\n- name: \"yumu\"\n  github: \"\"\n  slug: \"yumu\"\n- name: \"Yuri Bocharov\"\n  github: \"\"\n  slug: \"yuri-bocharov\"\n- name: \"Yuri Sidorov\"\n  github: \"newstler\"\n  slug: \"yuri-sidorov\"\n- name: \"Yuri Veremeyenko\"\n  github: \"yurivm\"\n  slug: \"yuri-veremeyenko\"\n- name: \"Yurie Yamane\"\n  twitter: \"yuri_at_earth\"\n  github: \"yurie\"\n  slug: \"yurie-yamane\"\n- name: \"Yusaku Hatanaka\"\n  github: \"hatappi\"\n  slug: \"yusaku-hatanaka\"\n- name: \"Yusuke Endoh\"\n  twitter: \"mametter\"\n  github: \"mame\"\n  website: \"http://mametter.hatenablog.com/\"\n  slug: \"yusuke-endoh\"\n- name: \"Yusuke Ishimi\"\n  github: \"\"\n  slug: \"yusuke-ishimi\"\n- name: \"Yusuke Iwaki\"\n  github: \"yusukeiwaki\"\n  website: \"http://yusukeiwaki.hatenablog.com/\"\n  slug: \"yusuke-iwaki\"\n- name: \"Yusuke Matsumoto\"\n  github: \"uske\"\n  slug: \"yusuke-matsumoto\"\n- name: \"Yusuke Nakamura\"\n  twitter: \"yu_suke1994\"\n  github: \"unasuke\"\n  website: \"https://unasuke.com\"\n  slug: \"yusuke-nakamura\"\n- name: \"Yuta Kurotaki\"\n  twitter: \"kurotaky\"\n  github: \"kurotaky\"\n  website: \"https://mo-fu.org\"\n  slug: \"yuta-kurotaki\"\n- name: \"Yuta Nakashima\"\n  github: \"\"\n  slug: \"yuta-nakashima\"\n- name: \"Yuta Saito\"\n  twitter: \"kateinoigakukun\"\n  github: \"kateinoigakukun\"\n  website: \"https://katei.dev\"\n  slug: \"yuta-saito\"\n- name: \"Yutaka HARA\"\n  twitter: \"yhara\"\n  github: \"yhara\"\n  website: \"https://yhara.jp\"\n  slug: \"yutaka-hara\"\n- name: \"Yutaka Kamei\"\n  github: \"\"\n  slug: \"yutaka-kamei\"\n- name: \"Yutaro Taira\"\n  github: \"\"\n  slug: \"yutaro-taira\"\n- name: \"Yuto Urushima\"\n  github: \"\"\n  slug: \"yuto-urushima\"\n- name: \"Yutuka Hara\"\n  github: \"\"\n  slug: \"yutuka-hara\"\n- name: \"Yuuichi Tateno\"\n  twitter: \"hotchpotch\"\n  github: \"hotchpotch\"\n  slug: \"yuuichi-tateno\"\n- name: \"Yuya Fujiwara\"\n  twitter: \"asonas\"\n  github: \"asonas\"\n  website: \"http://ason.as\"\n  slug: \"yuya-fujiwara\"\n- name: \"Yves Hanoulle\"\n  github: \"\"\n  slug: \"yves-hanoulle\"\n- name: \"Yves Senn\"\n  github: \"senny\"\n  slug: \"yves-senn\"\n- name: \"Yvone Sanchez Reyes\"\n  github: \"\"\n  slug: \"yvone-sanchez-reyes\"\n- name: \"Zach Briggs\"\n  github: \"theotherzach\"\n  website: \"https://theotherzach.com\"\n  slug: \"zach-briggs\"\n- name: \"Zach Feldman\"\n  github: \"zachfeldman\"\n  website: \"http://zfeldman.com\"\n  slug: \"zach-feldman\"\n- name: \"Zach Holman\"\n  twitter: \"holman\"\n  github: \"holman\"\n  website: \"http://zachholman.com\"\n  slug: \"zach-holman\"\n- name: \"Zach Kamran\"\n  github: \"zachkamran\"\n  slug: \"zach-kamran\"\n- name: \"Zachary Briggs\"\n  github: \"\"\n  slug: \"zachary-briggs\"\n- name: \"Zachary Feldman\"\n  github: \"feldmanz66\"\n  slug: \"zachary-feldman\"\n- name: \"Zachary Schroeder\"\n  github: \"zschro\"\n  website: \"http://zschro.github.io/\"\n  slug: \"zachary-schroeder\"\n  aliases:\n    - name: \"Zackary Schroder\"\n      slug: \"zackary-schroder\"\n- name: \"Zachary Scott\"\n  github: \"zzak\"\n  slug: \"zachary-scott\"\n- name: \"Zack Mariscal\"\n  twitter: \"zackmariscal\"\n  github: \"zmariscal\"\n  website: \"https://zackmariscal.com\"\n  slug: \"zack-mariscal\"\n- name: \"Zahary Karadjov\"\n  github: \"\"\n  slug: \"zahary-karadjov\"\n- name: \"Zaid Zawaideh\"\n  github: \"zawaideh\"\n  slug: \"zaid-zawaideh\"\n- name: \"Zed A. Shaw\"\n  github: \"\"\n  slug: \"zed-a-shaw\"\n- name: \"Zee Spencer\"\n  github: \"\"\n  slug: \"zee-spencer\"\n- name: \"Zef Houssney\"\n  twitter: \"zefhous\"\n  github: \"zef\"\n  website: \"http://zef.studio\"\n  slug: \"zef-houssney\"\n- name: \"Zeno Davatz\"\n  github: \"\"\n  slug: \"zeno-davatz\"\n- name: \"Zhao Lu\"\n  github: \"\"\n  slug: \"zhao-lu\"\n- name: \"Zhi Ren Guoy\"\n  github: \"ghosteathuman\"\n  slug: \"zhi-ren-guoy\"\n- name: \"Zhiqiang Bian\"\n  github: \"\"\n  slug: \"zhiqiang-bian\"\n- name: \"Zoe Steinkamp\"\n  github: \"zoesteinkamp\"\n  website: \"http://apathtobetraveled.blogspot.com/\"\n  slug: \"zoe-steinkamp\"\n- name: \"zuckey\"\n  github: \"\"\n  slug: \"zuckey\"\n- name: \"zunda\"\n  twitter: \"zundan\"\n  github: \"zunda\"\n  website: \"https://zunda.ninja\"\n  slug: \"zunda\"\n- name: \"Zuri Hunter\"\n  twitter: \"ZuriHunter\"\n  github: \"thestrugglingblack\"\n  website: \"http://www.zurihunter.com\"\n  slug: \"zuri-hunter\"\n- name: \"Zuz Wróżka\"\n  github: \"\"\n  slug: \"zuz-wrozka\"\n- name: \"Zuzanna Kusznir\"\n  github: \"zkusznir\"\n  slug: \"zuzanna-kusznir\"\n- name: \"Çağrı Özkan\"\n  github: \"ccozkan\"\n  slug: \"cagri-ozkan\"\n- name: \"Émilie Paillous\"\n  github: \"\"\n  slug: \"emilie-paillous\"\n- name: \"Étienne Barrié\"\n  twitter: \"BiHi\"\n  github: \"etiennebarrie\"\n  slug: \"etienne-barrie\"\n- name: \"Łukasz Reszke\"\n  twitter: \"lreszke\"\n  github: \"lukaszreszke\"\n  slug: \"lukasz-reszke\"\n- name: \"Łukasz Szydło\"\n  github: \"\"\n  slug: \"lukasz-szydlo\"\n"
  },
  {
    "path": "data/steelcityruby/series.yml",
    "content": "---\nname: \"Steel City Ruby\"\nwebsite: \"https://2014.steelcityruby.org\"\ntwitter: \"\"\nmastodon: \"\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/steelcityruby/steelcityruby-2012/event.yml",
    "content": "---\nid: \"steelcityruby-2012\"\ntitle: \"Steel City Ruby 2012\"\ndescription: |-\n  Inviting Rubyists of all skill levels to a new, two-day conference in the heart of Steel City, USA. With an emphasis on learning and conversation, Steel City Ruby Conf is your ideal first Ruby conference.\nlocation: \"Pittsburgh, PA, United States\"\nkind: \"conference\"\nstart_date: \"2012-08-03\"\nend_date: \"2012-08-04\"\nwebsite: \"https://2012.steelcityruby.org\"\ncoordinates:\n  latitude: 40.4386612\n  longitude: -79.99723519999999\n"
  },
  {
    "path": "data/steelcityruby/steelcityruby-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/steelcityruby/steelcityruby-2013/event.yml",
    "content": "---\nid: \"steelcityruby-2013\"\ntitle: \"Steel City Ruby 2013\"\ndescription: |-\n  Inviting Rubyists from across the land to a two-day conference in the heart of the Steel City - Pittsburgh, Pennsylvania. With an emphasis on learning and conversation, Steel City Ruby Conf is the ultimate community experience for Rubyists of all skill levels.\nlocation: \"Pittsburgh, PA, United States\"\nkind: \"conference\"\nstart_date: \"2013-08-16\"\nend_date: \"2013-08-17\"\nwebsite: \"https://2013.steelcityruby.org\"\ncoordinates:\n  latitude: 40.4386612\n  longitude: -79.99723519999999\n"
  },
  {
    "path": "data/steelcityruby/steelcityruby-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/steelcityruby/steelcityruby-2014/event.yml",
    "content": "---\nid: \"steelcityruby-2014\"\ntitle: \"Steel City Ruby 2014\"\ndescription: |-\n  New Hazlett Theater\nlocation: \"Pittsburgh, PA, United States\"\nkind: \"conference\"\nstart_date: \"2014-08-15\"\nend_date: \"2014-08-16\"\nwebsite: \"https://2014.steelcityruby.org\"\ncoordinates:\n  latitude: 40.4386612\n  longitude: -79.99723519999999\n"
  },
  {
    "path": "data/steelcityruby/steelcityruby-2014/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ohio\"\n      description: |-\n        Gold level sponsors. Customized packages, many tickets, few spots available.\n      level: 1\n      sponsors:\n        - name: \"ModCloth\"\n          website: \"http://www.modcloth.com\"\n          slug: \"ModCloth\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/modcloth.png\"\n\n    - name: \"Allegheny\"\n      description: |-\n        Silver level sponsors with listed benefits such as name and URL in email blasts, logo in slideshow and videos.\n      level: 2\n      sponsors:\n        - name: \"LittleLines\"\n          website: \"http://www.littlelines.com/\"\n          slug: \"LittleLines\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/littlelines.png\"\n\n        - name: \"Not Invented Here\"\n          website: \"http://notinventedhe.re\"\n          slug: \"NotInventedHere\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/not_invented_here.png\"\n\n        - name: \"HoneyBadger\"\n          website: \"https://www.honeybadger.io/\"\n          slug: \"honeybadger\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/honeybadger.png\"\n\n        - name: \"New Relic\"\n          website: \"https://www.newrelic.com\"\n          slug: \"NewRelic\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/newrelic.png\"\n\n        - name: \"Stitch Fix\"\n          website: \"http://www.stitchfix.com\"\n          slug: \"StitchFix\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/stitchfix.png\"\n\n        - name: \"Branding Brand\"\n          website: \"http://www.brandingbrand.com\"\n          slug: \"BrandingBrand\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/brandingbrand.png\"\n\n        - name: \"UPMC\"\n          website: \"http://www.upmc.com/careers\"\n          slug: \"UPMC\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/upmc.png\"\n\n        - name: \"LivingSocial\"\n          website: \"http://www.livingsocial.com\"\n          slug: \"LivingSocial\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/livingsocial.png\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"DNSimple\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/dnsimple.png\"\n\n        - name: \"WePay\"\n          website: \"http://www.wepay.com\"\n          slug: \"WePay\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/wepay.png\"\n\n        - name: \"Think Through Math\"\n          website: \"http://www.thinkthroughmath.com\"\n          slug: \"ThinkThroughMath\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/ttm.png\"\n\n        - name: \"4moms\"\n          website: \"http://www.4moms.com\"\n          slug: \"4moms\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/4moms.png\"\n\n        - name: \"Carney+Co\"\n          website: \"http://carney.co\"\n          slug: \"CarneyCo\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/carneyco.png\"\n\n        - name: \"Chef\"\n          website: \"http://www.getchef.com\"\n          slug: \"Chef\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/chef.png\"\n\n        - name: \"Engine Yard\"\n          website: \"http://engineyard.com\"\n          slug: \"EngineYard\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/engineyard.png\"\n\n    - name: \"Monongahela\"\n      description: |-\n        Bronze level sponsors with benefits like listed on website, Twitter mention, swag option.\n      level: 3\n      sponsors:\n        - name: \"TeamSnap\"\n          website: \"http://teamsnap.com\"\n          slug: \"TeamSnap\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/teamsnap.png\"\n\n        - name: \"Pragmatic Programmers\"\n          website: \"http://www.pragprog.com\"\n          slug: \"PragmaticProgrammers\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/pragprog.png\"\n\n        - name: \"Zipcode Services\"\n          website: \"https://www.zipcodeservices.com\"\n          slug: \"ZipcodeServices\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/zipcodeservices.png\"\n\n        - name: \"The Grant T. Olson Endowment for the Arts and Sciences\"\n          website: \"http://bitcoin.org\"\n          slug: \"TheGrantTOlsonEndowmentfortheArtsandSciences\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/grant_endowment.png\"\n\n        - name: \"Bearded Studio\"\n          website: \"http://bearded.com\"\n          slug: \"BeardedStudio\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/bearded.png\"\n\n        - name: \"IBM\"\n          website: \"http://www.ibm.com/smarterplanet/us/en/ibmwatson/index.html\"\n          slug: \"IBM\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/ibm.png\"\n\n        - name: \"LeanDog\"\n          website: \"http://www.leandog.com/\"\n          slug: \"LeanDog\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/leandog.png\"\n\n        - name: \"Coffee and Code\"\n          website: \"http://coffeeandcode.com\"\n          slug: \"CoffeeandCode\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/coffeeandcode.png\"\n\n        - name: \"Wall-to-Wall Studios\"\n          website: \"http://walltowall.com\"\n          slug: \"WalltoWallStudios\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/walltowall.png\"\n\n        - name: \"Showclix\"\n          website: \"http://www.showclix.com\"\n          slug: \"Showclix\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/showclix.png\"\n\n        - name: \"Summa Technologies\"\n          website: \"http://www.summa-tech.com\"\n          slug: \"SummaTechnologies\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/summa.png\"\n\n        - name: \"MaxCDN\"\n          website: \"http://www.maxcdn.com\"\n          slug: \"MaxCDN\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/maxcdn.png\"\n\n        - name: \"Pittsburgh Cultural Trust\"\n          website: \"http://trustarts.org/\"\n          slug: \"PittsburghCulturalTrust\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/pghculturaltrust.png\"\n\n        - name: \"Sticker Mule\"\n          website: \"http://stickermule.com\"\n          slug: \"StickerMule\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/stickermule.png\"\n\n        - name: \"Atmosferiq\"\n          website: \"http://atmosferiq.com\"\n          slug: \"Atmosferiq\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/atmosferiq.png\"\n\n    - name: \"Media\"\n      description: |-\n        Media sponsors.\n      level: 4\n      sponsors:\n        - name: \"Pittsburgh Code & Supply\"\n          website: \"http://www.codeandsupply.co\"\n          slug: \"PittsburghCodeSupply\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/codeandsupply.png\"\n\n        - name: \"DevOpsDays Pittsburgh\"\n          website: \"http://devopsdays.org\"\n          slug: \"DevOpsDaysPittsburgh\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/devopsdays.png\"\n\n        - name: \"United Pixelworkers\"\n          website: \"http://unitedpixelworkers.com\"\n          slug: \"UnitedPixelworkers\"\n          logo_url: \"https://2014.steelcityruby.org/assets/img/sponsor_logos/unitedpixelworkers.png\"\n"
  },
  {
    "path": "data/steelcityruby/steelcityruby-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n---\n[]\n"
  },
  {
    "path": "data/the-rails-edge/series.yml",
    "content": "---\nname: \"The Rails Edge\"\ndescription: |-\n  Regional Rails and Ruby conferences where some of the best minds in the Rails and Ruby communities come together in a single-track environment.\n\n  The Rails Edge is where you come to sharpen your saw and keep up with the state of the art.\nkind: \"conference\"\nfrequency: \"irregular\"\nwebsite: \"https://web.archive.org/web/20070126074651/http://studio.pragprog.com/therailsedge/index.html\"\n"
  },
  {
    "path": "data/the-rails-edge/the-rails-edge-2007/event.yml",
    "content": "---\nid: \"the-rails-edge-2007\"\ntitle: \"The Rails Edge 2007\"\nlocation: \"Reston, VA, United States\"\nstart_date: \"2007-01-25\"\nend_date: \"2007-01-27\"\nkind: \"conference\"\nwebsite: \"https://web.archive.org/web/20070126074651/http://studio.pragprog.com/therailsedge/index.html\"\nbanner_background: \"#D5D6AA\"\nfeatured_background: \"#D5D6AA\"\nfeatured_color: \"#2F5830\"\ncoordinates:\n  latitude: 38.949847\n  longitude: -77.354404\n"
  },
  {
    "path": "data/the-rails-edge/the-rails-edge-2007/venue.yml",
    "content": "---\nname: \"Sheraton Reston Hotel\"\n\naddress:\n  street: \"11810 Sunrise Valley Drive\"\n  city: \"Reston\"\n  region: \"Virginia\"\n  postal_code: \"20191\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"11810 Sunrise Valley Drive, Reston, VA 20191, United States\"\n\ncoordinates:\n  latitude: 38.949847\n  longitude: -77.354404\n\nmaps:\n  google: \"https://maps.google.com/?q=Sheraton+Reston,+11810+Sunrise+Valley+Drive,+Reston,+VA+20191\"\n  apple:\n    \"https://maps.apple.com/place?address=11810%20Sunrise%20Valley%20Dr,%20Reston,%20VA%20%2020191,%20United%20States&coordinate=38.949847,-77.354404&name=Sheraton%20Reston%20H\\\n    otel&place-id=I81FCA827FD95AAA8&map=transit\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=38.949847&mlon=-77.354404\"\n"
  },
  {
    "path": "data/the-rails-edge/the-rails-edge-2007/videos.yml",
    "content": "---\n- id: \"dave-thomas-metaprogramming-ruby-the-rails-edge-2007\"\n  title: \"Metaprogramming Ruby\"\n  speakers:\n    - Dave Thomas\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-25\"\n  video_provider: \"not_recorded\"\n  video_id: \"dave-thomas-metaprogramming-ruby-the-rails-edge-2007\"\n  description: |-\n    Ever wonder just how Rails declarations such as \"has many\" and \"belongs_to\" work? Ever wished you could write your own code that worked the same way?\n\n    It turns out that this style of programming, often called metaprogramming, is easier than you might think. In this talk we'll see how Ruby's open classes, compile-time execution, and full meta-object model make it easy to write your own extensions. After this talk, you'll know how to adapt Ruby to express your intent directly, making your programs easier to write and maintain.\n\n- id: \"mike-clark-whats-new-in-rails-the-rails-edge-2007\"\n  title: \"What's New in Rails?\"\n  speakers:\n    - Mike Clark\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-25\"\n  video_provider: \"not_recorded\"\n  video_id: \"mike-clark-whats-new-in-rails-the-rails-edge-2007\"\n  description: |-\n    Rails is constantly evolving, and being on the inside track can help you better plan for the future. In this session we'll give you an overview of latest and greatest Rails features that you can start using today, the bleeding edge features that you'll want to start using tomorrow, and the up-to-the-minute thoughts on what's on the horizon.\n\n    Topics include REST, ActiveResource, Simply Helpful, Capistrano Goodies, and What's Coming in Rails 2.0.\n\n- id: \"marcel-molina-reusing-rjs-the-rails-edge-2007\"\n  title: \"Reusing RJS\"\n  speakers:\n    - Marcel Molina\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-25\"\n  video_provider: \"not_recorded\"\n  video_id: \"marcel-molina-reusing-rjs-the-rails-edge-2007\"\n  description: |-\n    RJS emerged in the Rails 1.1 release as a new approach to implementing sophisticated Ajax behavior. Now that we've all been using it for a while and our apps come to rely on it more and more, we're starting to run into age old problems like, \"How do I take this bit of RJS that I'm using here, and use it over here also?\". It turns out that there is no immediately obvious path to staying DRY with RJS.\n\n    This talk shows how to eliminate duplication in RJS, going step by step through various refactorings and finally ending with advice on how to avoid the problem altogether by recognizing when RJS might not be the best solution to some problems.\n\n- id: \"chad-fowler-the-meaning-of-crud-the-rails-edge-2007\"\n  title: \"The Meaning of CRUD\"\n  speakers:\n    - Chad Fowler\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-25\"\n  video_provider: \"not_recorded\"\n  video_id: \"chad-fowler-the-meaning-of-crud-the-rails-edge-2007\"\n  description: |-\n    David Heinemeier Hansson, the creator of Rails, is the first to step up and admit it: Rails is boring. It's filled with cliches. Faced with Rails for the first time, any experienced web developer would be hard pressed to find a major feature he or she hadn't encountered in a previous technology. The magic isn't in the \"what\". It's in the \"how\".\n\n    Rails weaves all this prior art together such that it gets out of the developer's way. The primary mechanism it uses to achieve this is what's known as Convention Over Configuration. Sacrificing configurability in favor of the \"Golden Path\" takes the task of making repetitive, mundane decisions out of the hands of the developers, freeing them to focus on creating applications that do something new.\n\n    Rails 1.2 brings us another powerful set of conventions in the form of its built in CRUD and REST support. Are these new conventions about writing web services more easily? Or about supporting Ajax and pure HTML clients more seamlessly? Yes. But these are just fortunate side effects.\n\n    This session will take you on a tour of the new and improved world of Rails RESTfulness, showing you the new conventions and how you can use them to focus on the fun parts of programming.\n\n- id: \"james-duncan-davidson-deployment-golden-path-the-rails-edge-2007\"\n  title: \"The Deployment Golden Path\"\n  speakers:\n    - Duncan Davidson\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-26\"\n  video_provider: \"not_recorded\"\n  video_id: \"james-duncan-davidson-deployment-golden-path-the-rails-edge-2007\"\n  description: |-\n    Up until recently, deploying Rails apps has been a hodge-podge of tricks and experimentation and there haven't been a lot of good solid answers. That's changing. Over the last few months, a growing awareness of the issues around Rails deployment has spread through the Rails community, as has a lot of discussion about how to best do it. And there's a growing consensus that proxy-based solutions using Mongrel behind Apache or Lighttpd are the most flexible and scalable way to go.\n\n    This session will directly address the difficulties associated with deployment and start you down a solid path for deploying your own applications. And, since this area of Rails is still in flux, we'll be sure to address all of the latest developments in the space.\n\n- id: \"bruce-williams-building-view-frameworks-the-rails-edge-2007\"\n  title: \"Building View Frameworks\"\n  speakers:\n    - Bruce Williams\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-26\"\n  video_provider: \"not_recorded\"\n  video_id: \"bruce-williams-building-view-frameworks-the-rails-edge-2007\"\n  description: |-\n    It's a sad, but universal truth in the world of web apps—developing the view layer of an application is tricky business. No matter what platform and language you're using, views can easily become repetitive messes that are hard to read, impossible to maintain, difficult to test—and worst of all, no fun to develop.\n\n    Although Rails isn't immune to these difficulties, it comes with more than enough facilities to pack a punch. In this session you'll pick up techniques to DRY up your views that go far beyond just making a few helpers and reusing partials. Learn how to build frameworks to generate UI and controller code, expand your knowledge of view-related Rails internals, and discover how to avoid common pitfalls along the way.\n\n- id: \"justin-gehtland-streamlined-the-rails-edge-2007\"\n  title: \"Streamlined: Accelerate your CRUD\"\n  speakers:\n    - Justin Gehtland\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-26\"\n  video_provider: \"not_recorded\"\n  video_id: \"justin-gehtland-streamlined-the-rails-edge-2007\"\n  description: |-\n    Streamlined is an open source framework which extends Rails to provide fast development for CRUD applications. With Streamlined, you get real-world scaffolding right out of the box. In addition, we've taken the declarative approach of ActiveRecord and applied it to the view layer, giving you a simpler way to customize the rendered portion of the app. On top of that, Streamlined is a meta-framework, allowing you to plug in other generators, display systems, layout managers, etc.\n\n    In this talk, you'll learn how to get started with the default features of Streamlined, from generating your application, to modifying the way relationships are represented and tracked, to overriding the default layouts and stylesheets. We'll look at the ways Streamlined extends or wraps parts of Rails, and how to extend it yourself to customize your applications. We'll also take a look at the upcoming releases and features of Streamlined.\n\n- id: \"chad-fowler-bruce-williams-rails-plugins-the-rails-edge-2007\"\n  title: \"Creating Rails Plugins\"\n  speakers:\n    - Chad Fowler\n    - Bruce Williams\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-26\"\n  video_provider: \"not_recorded\"\n  video_id: \"chad-fowler-bruce-williams-rails-plugins-the-rails-edge-2007\"\n  description: |-\n    How do you reuse models and other application functionality across multiple Rails applications? How do you flexibly extend your applications at runtime? How do you override or extend core Rails functionality without creating a mess of patched source files that have to be applied to every Rails project? The answer to all of these questions lies in the simple, powerful Rails plugin architecture.\n\n    This session will guide you step by step through creating a Rails plugin from scratch. You'll see how plugins can be used to distribute Rails models, views, and controllers. You'll learn how plugins can extend an application's functionality dynamically and transparently. You'll learn to add filters, callbacks and observers to controllers and models without muddying the application's source code.\n\n- id: \"marcel-molina-amazon-s3-the-rails-edge-2007\"\n  title: \"Amazon's S3 Web Service\"\n  speakers:\n    - Marcel Molina\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-26\"\n  video_provider: \"not_recorded\"\n  video_id: \"marcel-molina-amazon-s3-the-rails-edge-2007\"\n  description: |-\n    Amazon's S3 web service is starting to get a lot of attention from people building applications that need to store and serve up lots of data. S3 is inexpensive, robust and simple. The headache of administering file servers appears to soon be a thing of the past.\n\n    In this talk we'll learn the basic concepts of S3 then take a look at how you can integrate S3 into your Rails application.\n\n- id: \"justin-gehtland-rails-and-ajax-the-rails-edge-2007\"\n  title: \"Rails and Ajax\"\n  speakers:\n    - Justin Gehtland\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-27\"\n  video_provider: \"not_recorded\"\n  video_id: \"justin-gehtland-rails-and-ajax-the-rails-edge-2007\"\n  description: |-\n    Rails delivers on the promise of increased developer productivity —not only in classic web application development, but in the emerging Ajax-enabled web world, too. Its close coupling with Prototype and Script.aculo.us, as well as its ground-breaking RJS templates, make Rails one of the most productive environments for creating Ajax applications available today.\n\n    This talk will walk through Rails implementations of Ajax, including the helper methods that generate your JavaScript and the JavaScript that gets emitted. We'll examine how you can design your controllers and actions to differentiate between regular web requests and Ajax requests, and we'll dig into RJS templates and in-line RJS to look at code-centric Ajax, which solves some problems while creating others.\n\n- id: \"stuart-halloway-ruby-idioms-the-rails-edge-2007\"\n  title: \"Ruby Idioms for Rails Programmers\"\n  speakers:\n    - Stuart Halloway\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-27\"\n  video_provider: \"not_recorded\"\n  video_id: \"stuart-halloway-ruby-idioms-the-rails-edge-2007\"\n  description: |-\n    The success of Rails has enabled programmers to get great results without having a deep knowledge of Ruby. Nevertheless, a good understanding of Ruby idioms is essential to being a great Rails coder. Ruby style does not come overnight because \"There is More Than One Way To Do It\" (TMTOWDI).\n\n    In this talk we will look at the Rails codebase itself, Rails applications, and pure Ruby applications to get a sense of Ruby idioms and style. When there are many ways to do it, some are better than others. We'll find them.\n\n- id: \"jim-weirich-rake-the-rails-edge-2007\"\n  title: \"Rake: Building Up Ruby\"\n  speakers:\n    - Jim Weirich\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-27\"\n  video_provider: \"not_recorded\"\n  video_id: \"jim-weirich-rake-the-rails-edge-2007\"\n  description: |-\n    Most people have used rake in passing as part of a Rails project. What you might not realize is that Rake is a general purpose build tool that can do more than just automate simple tasks in Rails. Rake allows you to define complex task relationships and makes sure that everything gets done, in the right order, just in time as you need it. Best of all, the Rake recipe file (known as a Rakefile) is just pure Ruby, so you already know most of what you need to put Rake to good use.\n\n    This session will cover the basics of writing your own Rake tasks, creating dependencies, and managing your software builds. We will cover how to dynamically generate tasks at runtime and how to write rules that will allow Rake to automatically infer tasks when given the right hints. We will also see some some advanced features such as multitasking jobs and creating Rake plugins.\n\n    Rake is a powerful tool to have in your toolkit. By the time we are done, you will be able to use it effectively.\n\n- id: \"jim-weirich-red-green-refactor-the-rails-edge-2007\"\n  title: \"Red, Green, Refactor\"\n  speakers:\n    - Jim Weirich\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-27\"\n  video_provider: \"not_recorded\"\n  video_id: \"jim-weirich-red-green-refactor-the-rails-edge-2007\"\n  description: |-\n    One of the most practical practices coming out of the XP movement is the notion of Unit Tests. Whether you are actually doing some form of Agile development or not, unit tests are an important part of writing your software. The XP approach to writing unit tests is more than just writing the tests before you write the code. We like to call it \"Test-Driven\" because we use the unit test to incrementally drive the design and form of the production code.\n\n    The TDD approach is to write a little bit of unit test (that fails, hence \"red\"), then write only enough production code to make the test pass (that's the \"green\"). Then we examine the code and look for ways to improve it (finally \"refactor\"). The whole cycle from failing tests to passing tests to improved code is very short, often on the order of minutes.\n\n    This presentation will be a live demonstration of the Test Driven Design technique. We will use TDD to develop a small piece of functionality by following the Red, Green, Refactor cycle.\n\n- id: \"justin-gehtland-rinda-drb-the-rails-edge-2007\"\n  title: \"Rinda and DRB\"\n  speakers:\n    - Justin Gehtland\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-27\"\n  video_provider: \"not_recorded\"\n  video_id: \"justin-gehtland-rinda-drb-the-rails-edge-2007\"\n  description: |-\n    Learn about Ruby's support for simple work distribution. DRB is Ruby's built-in distributed object library, and Rinda is a message-delivery (technically tuple space) implementation on top of it. With Rinda, you can set up multiple parallel processes, distribute data, and manage work flows across applications.\n\n- id: \"james-duncan-davidson-rails-production-tricks-the-rails-edge-2007\"\n  title: \"Rails Production Tricks and Tips\"\n  speakers:\n    - Duncan Davidson\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-27\"\n  video_provider: \"not_recorded\"\n  video_id: \"james-duncan-davidson-rails-production-tricks-the-rails-edge-2007\"\n  description: |-\n    When you take your application into production, there are lots of obvious questions, such as, \"How many servers do I need?\" and \"How many Mongrel processes should I run?\" Every deployed application is different, but there are some lessons that can be learned from other deployed applications. This session will outline some obvious and not-so-obvious things that you should think about as you are taking your application into production, based on information from real life deployments.\n\n- id: \"dave-thomas-buried-treasure-the-rails-edge-2007\"\n  title: \"Buried Treasure: Hidden Rails Tips\"\n  speakers:\n    - Dave Thomas\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-27\"\n  video_provider: \"not_recorded\"\n  video_id: \"dave-thomas-buried-treasure-the-rails-edge-2007\"\n  description: |-\n    While writing the second edition of the Rails book, I've come across dozens of little, hidden Rails tips and techniques. They may not be obvious when you read the API documentation, or they may apply in different ways than you'd think. But they're more than curiosities—each of these tips and techniques has saved me time (or saved my butt) while writing real Rails applications.\n\n    From unexpected uses of with_options() to new kinds of rendering, from console tricks to TextMate addons, we'll have some fun while digging for treasure in Rails and Ruby. (And bring your own secrets too—there'll be a time to share.)\n\n- id: \"marcel-molina-presenter-pattern-the-rails-edge-2007\"\n  title: \"The Presenter Pattern\"\n  speakers:\n    - Marcel Molina\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-27\"\n  video_provider: \"not_recorded\"\n  video_id: \"marcel-molina-presenter-pattern-the-rails-edge-2007\"\n  description: |-\n    Keeping templates simple by extracting reused view logic into helpers is a good thing, but as your Rails application grows, so too will your helper files. After a while, it feels like you are trading off one evil for another as application_helper.rb balloons to hundreds of lines.\n\n    And a big helper file isn't your only problem. Some view logic gets sophisticated enough to require a handful of helpers to accomplish a single task, that themselves call there own set of helpers. These groups of methods also often need to pass some shared state around, and the functional nature of helpers makes for a clumsy experience. Now you not only have a big helper file, but its methods accomplish many unrelated tasks. Comprehending which methods accomplish what task and where becomes a lot of work. Refactoring gets harder and harder. Soon enough you have a real mess on your hands and you so you leave it be as Good Enough.\n\n    Rails is about making it simple to do the right thing, so from this pain, the Presenter pattern has emerged as a nice solution to combat the complexity of view logic. In this talk we'll take a quick look at the Presenter pattern: what it is and how it can be used to encapsulate sophisticated view logic. The Presenter pattern is shaping up to maybe be one of the next big extractions in Rails core. The jury is still out, but it's looking promising.\n\n- id: \"stuart-halloway-testing-rails-the-rails-edge-2007\"\n  title: \"Testing Rails Applications\"\n  speakers:\n    - Stuart Halloway\n  event_name: \"The Rails Edge 2007\"\n  date: \"2007-01-27\"\n  video_provider: \"not_recorded\"\n  video_id: \"stuart-halloway-testing-rails-the-rails-edge-2007\"\n  description: |-\n    Automated testing takes a lot of guesswork out of developing, maintaining, and refactoring applications. With a good test suite, you can aggressively improve your code over time.\n\n    Rails has a great support for automated testing. We'll take a quick tour through unit tests, functional tests, integration tests, and Rake tasks that support testing.\n\n    A comprehensive test plan takes more that just the testing support in Rails. We will integrate several other tools into the Rails testing process: rcov for code coverage, cerberus for continuous integration, FlexMock for mock and stub objects, and Selenium for browser-level integration testing.\n\n    Testing is not just good for applications, it is good for programmers. We will conclude by showing you how to use testing as an exploration tool when reading other people's code.\n"
  },
  {
    "path": "data/thoughtbot-open-summit/series.yml",
    "content": "---\nname: \"Thoughtbot Open Summit\"\nwebsite: \"https://thoughtbot.com/events/open-summit\"\nyoutube_channel_name: \"thoughtbot\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlanguage: \"english\"\ndefault_country_code: \"US\"\nyoutube_channel_id: \"UCUR1pFG_3XoZn3JNKjulqZg\"\nplaylist_matcher: \"thoughtbot Open Summit\"\n"
  },
  {
    "path": "data/thoughtbot-open-summit/thoughtbot-open-summit-2024/event.yml",
    "content": "---\nid: \"thoughtbot-open-summit-2024\"\ntitle: \"thoughtbot Open Summit 2024\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: \"\"\npublished_at: \"2024-11-06\"\nstart_date: \"2024-10-24\"\nend_date: \"2024-10-24\"\nchannel_id: \"UCUR1pFG_3XoZn3JNKjulqZg\"\nyear: 2024\nbanner_background: \"#F2F3FB\"\nfeatured_background: \"#F2F3FB\"\nfeatured_color: \"#393A41\"\ncoordinates: false\n"
  },
  {
    "path": "data/thoughtbot-open-summit/thoughtbot-open-summit-2024/videos.yml",
    "content": "---\n- id: \"open-source-bridging-the-gap-with-the-next-generation\"\n  title: \"Open Source: Bridging the gap with the next generation\"\n  raw_title: \"Opening keynote | thoughtbot Open Summit 2024\"\n  speakers:\n    - Silumesii Maboshe\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-06\"\n  description: |-\n    thoughtbot Senior Developer Silumesii Maboshe welcomes you to thoughtbot Open Summit, thoughtbot's first virtual day of open source collaboration with the community. This talk was originally live streamed Oct 25, 2024.\n  video_provider: \"youtube\"\n  video_id: \"zCF3QTi67Dc\"\n\n- id: \"commit-messages-to-the-rescue\"\n  title: \"Commit Messages to the Rescue\"\n  raw_title: \"Commit Messages to the Rescue | thoughtbot Open Summit 2024\"\n  speakers:\n    - 'Christopher \"Aji\" Slater'\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-06\"\n  description: |-\n    thoughtbot Development Team Lead Aji Slater gives a talk about writing great commit messages. This talk was originally live streamed Oct 25, 2024 as the mid-day talk for thoughtbot Open Summit.\n  video_provider: \"youtube\"\n  video_id: \"W_8CAFeRq9Q\"\n\n- id: \"why-work-in-public\"\n  title: \"Why Work in Public\"\n  raw_title: \"Why Work in Public | thoughtbot Open Summit 2024\"\n  speakers:\n    - Stefanni Brasil\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-06\"\n  description: |-\n    thoughtbot Senior Developer Stefanni Brasil gives a talk about how contributing to open source helps developers to work in public, and why that's important. This talk was originally live streamed Oct 25, 2024 as the closing talk for thoughtbot Open Summit.\n  video_provider: \"youtube\"\n  video_id: \"5p8YnddbsMs\"\n\n- id: \"gen-ai-landscape\"\n  title: \"Gen AI landscape\"\n  raw_title: \"Gen AI landscape | Langchain.rb track | thoughtbot Open Summit 2024\"\n  speakers:\n    - Andrei Bondarev\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-06\"\n  description: |-\n    Andrei Bondarev is the creator and maintainer of Langchain.rb, an open source tool that enables you to build LLM-powered applications in Ruby. To kick off the Langchain.rb session of thoughtbot Open Summit 2024, he sets the stage with a discussion of the Gen AI landscape.\n  video_provider: \"youtube\"\n  video_id: \"K-WGvECmuck\"\n\n- id: \"hacking-on-langchain-rb-to-build-llm-powered-apps-in-ruby\"\n  title: \"Hacking on Langchain.rb to build LLM-powered apps in Ruby \"\n  raw_title: \"Hacking on Langchain.rb to build LLM-powered apps in Ruby | thoughtbot Open Summit 2024\"\n  speakers:\n    - Andrei Bondarev\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-06\"\n  description: |-\n    Andrei Bondarev is the creator and maintainer of Langchain.rb, an open source tool that enables you to build LLM-powered applications in Ruby. Watch Andrei pair live on Langchain during thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"_aLeTE4JHvA\"\n\n- id: \"working-on-belt-a-cli-for-react-native-apps-part-1\"\n  title: \"Working on Belt, a CLI for React Native apps (Part 1)\"\n  raw_title: \"Working on Belt, a CLI for React Native apps (Part 1) | thoughtbot Open Summit 2024\"\n  speakers:\n    - Rakesh Arunachalam\n    - Tomisin Alu\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-06\"\n  description: |-\n    Senior Developer Rakesh Arunachalam and Developer Tomi Alu join forces to pair on Belt, a CLI open source project for starting new React Native applications. This is the first of several live pairing sessions on Belt during thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"JR-E-eiQkSU\"\n\n- id: \"working-on-belt-a-cli-for-react-native-apps-part-2\"\n  title: \"Working on Belt, a CLI for React Native apps (Part 2)\"\n  raw_title: \"Working on Belt, a CLI for React Native apps (Part 2) | thoughtbot Open Summit 2024\"\n  speakers:\n    - Rakesh Arunachalam\n    - Tomisin Alu\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-06\"\n  description: |-\n    Senior Developer Rakesh Arunachalam and Developer Tomi Alu join forces to pair on Belt, a CLI open source project for starting new React Native applications. This is the 2nd of 3 live pairing sessions on Belt during thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"jOz67qtYqSI\"\n\n- id: \"working-on-belt-a-cli-for-react-native-apps-part-3\"\n  title: \"Working on Belt, a CLI for React Native apps (Part 3)\"\n  raw_title: \"Working on Belt, a CLI for React Native apps (Part 3) | thoughtbot Open Summit 2024\"\n  speakers:\n    - Rakesh Arunachalam\n    - Tomisin Alu\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-06\"\n  description: |-\n    Senior Developer Rakesh Arunachalam and Developer Tomi Alu join forces to pair on Belt, a CLI open source project for starting new React Native applications. This is their third and final pairing sessions on Belt during thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"f6Xs-h81CEM\"\n\n- id: \"pairing-on-factorybot-part-1\"\n  title: \"Pairing on FactoryBot (Part 1)\"\n  raw_title: \"Pairing on FactoryBot (Part 1) | thoughtbot Open Summit 2024\"\n  speakers:\n    - Sarah Lima\n    - Silumesii Maboshe\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-06\"\n  description: |-\n    thoughtbot Senior Developers and FactoryBot maintainers Sarah Lima and Silumesii Maboshe join forces to work on FactoryBot live. factory_bot is a library for setting up Ruby objects as test data. This is the 1st of 4 sessions during the FactoryBot track of thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"_VbPbFmhQSg\"\n\n- id: \"pairing-on-factorybot-part-2\"\n  title: \"Pairing on FactoryBot (Part 2)\"\n  raw_title: \"Pairing on FactoryBot (Part 2) | thoughtbot Open Summit 2024\"\n  speakers:\n    - Sarah Lima\n    - Silumesii Maboshe\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-07\"\n  description: |-\n    thoughtbot Senior Developers and FactoryBot maintainers Sarah Lima and Silumesii Maboshe join forces to work on factory_bot which is a library for setting up Ruby objects as test data. They are later joined by Nick Charlton and the group answers some general open source questions from the audience. This is the 2nd of 4 sessions during the FactoryBot track of thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"hdGpBqdhEhA\"\n\n- id: \"pairing-on-factorybot-part-3\"\n  title: \"Pairing on FactoryBot (Part 3)\"\n  raw_title: \"Pairing on FactoryBot (Part 3) | thoughtbot Open Summit 2024\"\n  speakers:\n    - Fernando Perales\n    - 'Christopher \"Aji\" Slater'\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-13\"\n  description: |-\n    thoughtbot Development Team Leads Fernando Perales and Aji Slater take over the FactoryBot track! factory_bot is a library for setting up Ruby objects as test data. This is part 3 of 4 sessions of the FactoryBot track at thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"Kj9SsUufPlw\"\n\n- id: \"pairing-on-factorybot-part-4\"\n  title: \"Pairing on FactoryBot (Part 4)\"\n  raw_title: \"Pairing on FactoryBot (Part 4) thoughtbot Open Summit 2024\"\n  speakers:\n    - Fernando Perales\n    - Stefanni Brasil\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-27\"\n  description: |-\n    thoughtbot Development Team Lead Fernando Perales is joined by Stefanni Brasil to close out the FactoryBot track. factory_bot is a library for setting up Ruby objects as test data. This is part 4 of 4 sessions of the FactoryBot track at thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"rLPjnJTFQjE\"\n\n- id: \"administrate-hackathon-part-1\"\n  title: \"Administrate hackathon (Part 1)\"\n  raw_title: \"Administrate hackathon (Part 1) | thoughtbot Open Summit 2024\"\n  speakers:\n    - Nick Charlton\n    - Svenja Schäfer\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-27\"\n  description: |-\n    Development Team Lead and Administrate maintainer Nick Charlton, pairs with Team Lead Svenja Schäfer on Administrate, A Rails engine that helps you put together a super-flexible admin dashboard. This is the first of several live pairing sessions on Administrate during thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"xlRah8hOr3I\"\n\n- id: \"administrate-hackathon-part-2\"\n  title: \"Administrate hackathon (A short part 2)\"\n  raw_title: \"Administrate hackathon (A short part 2) | thoughtbot Open Summit 2024\"\n  speakers:\n    - Nick Charlton\n    - Svenja Schäfer\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-27\"\n  description: |-\n    Development Team Lead and Administrate maintainer Nick Charlton, rejoins Team Lead Svenja Schafer on Administrate, A Rails engine that helps you put together a super-flexible admin dashboard. This is part 2 of 3 live pairing sessions on Administrate during thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"NhHFroPG66w\"\n\n- id: \"administrate-hackathon-part-3\"\n  title: \"Administrate hackathon (Part 3)\"\n  raw_title: \"Administrate hackathon (Part 3) | thoughtbot Open Summit 2024\"\n  speakers:\n    - Nick Charlton\n    - Svenja Schäfer\n    - Sara Jackson\n  date: \"2025-10-25\"\n  event_name: \"thoughtbot Open Summit 2024\"\n  published_at: \"2024-11-27\"\n  description: |-\n    Development Team Lead and Administrate maintainer Nick Charlton, pairs with Team Lead Svenja Schäfer on Administrate. As Svenja heads out, Nick works solo for a bit, before being joined by Development Team Lead Sara Jackson to collaborate some more before ending the track for the day. This is the last of 3 live pairing sessions on Administrate during thoughtbot Open Summit 2024.\n  video_provider: \"youtube\"\n  video_id: \"gYddCs5nQ00\"\n"
  },
  {
    "path": "data/thoughtbot-open-summit/thoughtbot-open-summit-2025/event.yml",
    "content": "---\nid: \"thoughtbot-open-summit-2025\"\ntitle: \"thoughtbot Open Summit 2025\"\nkind: \"conference\"\nlocation: \"online\"\ndescription: \"\"\npublished_at: \"2025-11-12\"\nstart_date: \"2025-10-31\"\nend_date: \"2025-10-31\"\nchannel_id: \"UCUR1pFG_3XoZn3JNKjulqZg\"\nyear: 2025\nbanner_background: \"#3B104C\"\nfeatured_background: \"#3B104C\"\nfeatured_color: \"#FFFFFF\"\ncoordinates: false\n"
  },
  {
    "path": "data/thoughtbot-open-summit/thoughtbot-open-summit-2025/videos.yml",
    "content": "---\n- id: \"hanami-101-with-qa-from-tim-riley\"\n  title: \"A Ruby-based alternative to Rails, Hanami 101 with Q&A from Tim Riley\"\n  raw_title: \"A Ruby-based alternative to Rails, Hanami 101 with Q&A from Tim Riley | thoughtbot Open Summit 2025\"\n  speakers:\n    - Tim Riley\n  date: \"2025-10-31\"\n  event_name: \"thoughtbot Open Summit 2025\"\n  published_at: \"2025-11-12\"\n  description: |-\n    A crowd-favorite of thoughtbot Open Summit 2025, Hanami co-author Tim Riley gives an inspiring talk about stewardship of Ruby and open source. Along the way he thoughtfully connects the Hanami journey to the life of Haruki Murakami.\n  video_provider: \"youtube\"\n  video_id: \"imRNoII2BME\"\n\n- id: \"the-role-of-open-source-in-successful-products\"\n  title: \"The role of open source in successful products\"\n  raw_title: \"The role of open source in successful products | thoughtbot Open Summit 2025\"\n  speakers:\n    - Rémy Hannequin\n    - Jared Turner\n  date: \"2025-10-31\"\n  event_name: \"thoughtbot Open Summit 2025\"\n  published_at: \"2025-11-12\"\n  description: |-\n    Rémy Hannequin, Senior Developer, and Jared Turner, Senior Product Manager, kick off thoughtbot Open Summit with a keynote exploring how open source and successful products continuously strengthen each other in a self-reinforcing flywheel. They also trace thoughtbot’s 20+ years of open source leadership, from classics like factory_bot, Administrate, and Clearance to newer tools like Superglue, Belt, and Top Secret.\n  video_provider: \"youtube\"\n  video_id: \"md9YaVIpqro\"\n\n- id: \"bridging-react-and-rails-with-superglue\"\n  title: \"Bridging React and Rails with Superglue\"\n  raw_title: \"Bridging React and Rails with Superglue | thoughtbot Open Summit 2025\"\n  speakers:\n    - Johny Ho\n    - Sally Hall\n  date: \"2025-10-31\"\n  event_name: \"thoughtbot Open Summit 2025\"\n  published_at: \"2025-11-12\"\n  description: |-\n    Senior Developers Johny Ho and Sally Hall demonstrate how Rails teams can build highly interactive React applications without losing Rails’ simplicity and structure. To do this, they introduce open source project Superglue and show it in action as well as take live questions from the audience.\n\n    Johny is the author and maintainer of Superglue: https://github.com/thoughtbot/superglue\n  video_provider: \"youtube\"\n  video_id: \"3_esl1bqY88\"\n\n- id: \"ai-rails-workshop\"\n  title: \"AI + Rails Workshop\"\n  raw_title: \"AI + Rails Workshop | thoughtbot Open Summit 2025\"\n  speakers:\n    - Justin Bowen\n    - Chad Pytel\n  date: \"2025-10-31\"\n  event_name: \"thoughtbot Open Summit 2025\"\n  published_at: \"2025-11-18\"\n  description: |-\n    Justin Bowen, author of gem Active Agent, is joined by thoughtbot CEO Chad Pytel for a live workshop on implementing AI agents. They live code in the session, Justin debuts a new structured outputs feature, and generally discuss why Ruby and Rails are great for building AI features.\n  video_provider: \"youtube\"\n  video_id: \"kmJpTzmh-AE\"\n\n- id: \"fun-with-regular-expressions-workshop\"\n  title: \"Fun (?!) with Regular Expressions Workshop\"\n  raw_title: \"Fun (?!) with Regular Expressions Workshop | thoughtbot Open Summit 2025\"\n  speakers:\n    - Svenja Schäfer\n    - Sarah Lima\n  date: \"2025-10-31\"\n  event_name: \"thoughtbot Open Summit 2025\"\n  published_at: \"2025-11-18\"\n  description: |-\n    Become a stronger developer by building your confidence with Regular Expressions. This RegEx workshop was live at thoughtbot Open Summit 2025- led by Svenja Schäfer with help from Sarah Lima and a wonderful audience.\n  video_provider: \"youtube\"\n  video_id: \"GJslHXZVYEw\"\n\n- id: \"open-source-maintainer-panel\"\n  title: \"Open Source Maintainer Panel\"\n  raw_title: \"Open Source Maintainer Panel | thoughtbot Open Summit\"\n  speakers:\n    - Elaina Natario\n    - Johny Ho\n    - Nick Charlton\n    - Rémy Hannequin\n    - Lindsey Christensen\n  date: \"2025-10-31\"\n  event_name: \"thoughtbot Open Summit 2025\"\n  published_at: \"2025-11-18\"\n  description: |-\n    Project maintainers and authors from thoughtbot have a discussion on the challenges and opportunities we face in the next chapter of that collaborative project we call: the web! They share great tips for why and how to contribute to open source as part of your \"day job\".\n\n    Elaina Natario: Author of new CSS project: Roux\n    Johny Ho: Author of React + Rails project: Superglue\n    Nick Charlton: Long-time maintainer of Rails project Administrate - just launched v1\n    Rémy Hannequin: Author of scientific gem, Astronoby\n    Lindsey Christensen: Moderator\n  video_provider: \"youtube\"\n  video_id: \"clK-RqORMaY\"\n\n- id: \"reflections-on-phlogiston\"\n  title: \"Reflections on Phlogiston\"\n  raw_title: \"Closing Keynote from Aji Slater | thoughtbot Open Summit 2025\"\n  speakers:\n    - 'Christopher \"Aji\" Slater'\n  date: \"2025-10-31\"\n  event_name: \"thoughtbot Open Summit 2025\"\n  published_at: \"2025-11-26\"\n  description: |-\n    Aji Slater presents Reflections on Phlogiston: Elements of Open Source, in a New Systematic Order, Containing All the Modern Discoveries - like only they can! Enjoy this surprising tour of scientific research and innovation, starting back in the 30 years war.\n  video_provider: \"youtube\"\n  video_id: \"vvRjNLB4VbU\"\n\n- id: \"live-coding-on-administrate\"\n  title: \"Live coding on Administrate\"\n  raw_title: \"Live coding on Administrate | thoughtbot Open Summit 2025\"\n  speakers:\n    - Nick Charlton\n    - Pablo Brasero\n  date: \"2025-10-31\"\n  event_name: \"thoughtbot Open Summit 2025\"\n  published_at: \"2025-11-26\"\n  description: |-\n    Nick Charlton and Pablo Brasero did some live troubleshooting with the help of the audience to ship Administrate 1.0. Along the way they discussed the project and advanced use cases.\n  video_provider: \"youtube\"\n  video_id: \"NAO6t4l2jlU\"\n\n- id: \"live-coding-on-factory_bot\"\n  title: \"Live coding on factory_bot\"\n  raw_title: \"Live coding on factory_bot | thoughtbot Open Summit 2025\"\n  speakers:\n    - Neil Carvalho\n    - Jose Blanco\n  date: \"2025-10-31\"\n  event_name: \"thoughtbot Open Summit 2025\"\n  published_at: \"2025-11-26\"\n  description: |-\n    Neil Carvahlo and Jose Blanco show you how to extend factory_bot for your unique use cases through building a custom strategy.\n  video_provider: \"youtube\"\n  video_id: \"lCkxoOmcv8M\"\n"
  },
  {
    "path": "data/tiny-ruby-conf/series.yml",
    "content": "---\nname: \"tiny ruby #{conf}\"\nwebsite: \"https://helsinkiruby.fi\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"FI\"\nyoutube_channel_name: \"helsinkiruby\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCcoS038f4xA_Lz5AoD0ShzA\"\naliases:\n  - tiny ruby conf\n  - tiny ruby\n  - tinyruby\n  - tinyruby conf\n"
  },
  {
    "path": "data/tiny-ruby-conf/tiny-ruby-conf-2025/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/tinyruby\"\n  open_date: \"2025-05-27\"\n  close_date: \"2025-07-31\"\n"
  },
  {
    "path": "data/tiny-ruby-conf/tiny-ruby-conf-2025/event.yml",
    "content": "---\nid: \"tiny-ruby-conf\"\ntitle: \"tiny ruby #{conf} 2025\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlocation: \"Helsinki, Finland\"\ndescription: |-\n  tiny ruby #{conf} is an affordable, one day, single-track Ruby conference in Helsinki, Finland.\nstart_date: \"2025-11-21\"\nend_date: \"2025-11-21\"\npublished_at: \"2025-12-01\"\nyear: 2025\nbanner_background: \"#0A1936\"\nfeatured_background: \"#0A1936\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://helsinkiruby.fi/tinyruby/\"\ncoordinates:\n  latitude: 60.1839786\n  longitude: 24.9204603\n"
  },
  {
    "path": "data/tiny-ruby-conf/tiny-ruby-conf-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Matias Korhonen\n    - Simo Virtanen\n    - Eetu Mattila\n\n  organisations:\n    - Helsinki Ruby\n"
  },
  {
    "path": "data/tiny-ruby-conf/tiny-ruby-conf-2025/schedule.yml",
    "content": "# Schedule: https://helsinkiruby.fi/tinyruby/#schedule\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2025-11-21\"\n    grid:\n      - start_time: \"09:15\"\n        end_time: \"10:15\"\n        slots: 1\n        items:\n          - Doors open / registration\n\n      - start_time: \"10:15\"\n        end_time: \"10:30\"\n        slots: 1\n        items:\n          - Opening\n\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"13:15\"\n        slots: 1\n        items:\n          - Lunch break\n\n      - start_time: \"13:15\"\n        end_time: \"13:45\"\n        slots: 1\n\n      - start_time: \"13:45\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"14:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:15\"\n        slots: 1\n        items:\n          - Closing remarks\n\n      - start_time: \"18:00\"\n        end_time: \"23:00\"\n        slots: 1\n        items:\n          - Drinks at Odessa — hosted by GitButler\n\ntracks: []\n"
  },
  {
    "path": "data/tiny-ruby-conf/tiny-ruby-conf-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Avo\"\n          website: \"https://avohq.io/\"\n          slug: \"avo\"\n          logo_url: \"https://helsinkiruby.fi/_bridgetown/static/avo-3LBUGTFS.svg\"\n\n        - name: \"Kisko\"\n          website: \"https://www.kiskolabs.com/\"\n          slug: \"kisko\"\n          logo_url: \"https://helsinkiruby.fi/_bridgetown/static/kiskolabs-4VKKS2N7.svg\"\n\n    - name: \"Gold Sponsors\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Bezala\"\n          website: \"https://bezala.com/\"\n          slug: \"bezala\"\n          logo_url: \"https://helsinkiruby.fi/_bridgetown/static/bezala-NPIZ5UGR.svg\"\n\n        - name: \"Teamtailor\"\n          website: \"https://www.teamtailor.com/en/\"\n          slug: \"teamtailor\"\n          logo_url: \"https://helsinkiruby.fi/_bridgetown/static/teamtailor-PFDISK53.svg\"\n\n        - name: \"Maventa\"\n          website: \"https://maventa.com/\"\n          slug: \"maventa\"\n          logo_url: \"https://helsinkiruby.fi/_bridgetown/static/maventa-E4TCK7RA.svg\"\n\n    - name: \"Travel Sponsor\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"GitHub\"\n          website: \"https://github.com/\"\n          slug: \"github\"\n          logo_url: \"https://helsinkiruby.fi/_bridgetown/static/github-E5SQLMZP.svg\"\n\n    - name: \"Drinks Sponsor\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"GitButler\"\n          website: \"https://gitbutler.com/\"\n          slug: \"gitbutler\"\n          logo_url: \"https://helsinkiruby.fi/_bridgetown/static/gitbutler-KALLNA4Z.svg\"\n\n    - name: \"Bring a Friend Sponsor\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"Sakeus\"\n          website: \"https://sakeus.fi/\"\n          slug: \"sakeus\"\n          logo_url: \"https://helsinkiruby.fi/_bridgetown/static/sakeus-YILC6AJN.svg\"\n"
  },
  {
    "path": "data/tiny-ruby-conf/tiny-ruby-conf-2025/venue.yml",
    "content": "---\nname: \"Korjaamo Kino cinema\"\n\naddress:\n  street: \"51 B Töölönkatu\"\n  city: \"Helsinki\"\n  region: \"Uusimaa\"\n  postal_code: \"00250\"\n  country: \"Finland\"\n  country_code: \"FI\"\n  display: \"Töölönkatu 51 B, 00250 Helsinki, Finland\"\n\ncoordinates:\n  latitude: 60.1839786\n  longitude: 24.9204603\n\nmaps:\n  google: \"https://maps.google.com/?q=Korjaamo+Kino+cinema,60.1839786,24.9204603\"\n  apple: \"https://maps.apple.com/?q=Korjaamo+Kino+cinema&ll=60.1839786,24.9204603\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=60.1839786&mlon=24.9204603\"\n\nlocations:\n  - name: \"Café & Bar Odessa\"\n    kind: \"Afterparty Location\"\n    address:\n      street: \"Traverssikuja 3\"\n      city: \"Helsinki\"\n      postal_code: \"00510\"\n      country: \"Finland\"\n      country_code: \"FI\"\n      display: \"Traverssikuja 3, 00510 Helsinki, Finland\"\n    coordinates:\n      latitude: 60.194226\n      longitude: 24.945257\n    maps:\n      google: \"https://maps.app.goo.gl/GkGoH5ncTNtyhrF29\"\n      apple:\n        \"https://maps.apple.com/place?address=Traverssikuja%203,%2000510%20Helsinki,%20Finland&coordinate=60.194226,24.945257&name=Caf%C3%A9%20%26%20Bar%20Odessa&place-id=IF7222654\\\n        743E1550&map=explore\"\n      openstreetmap: \"https://www.openstreetmap.org/?mlat=60.194226&mlon=24.945257\"\n"
  },
  {
    "path": "data/tiny-ruby-conf/tiny-ruby-conf-2025/videos.yml",
    "content": "---\n- title: \"Even smaller Rubies\"\n  speakers:\n    - Chris Hasiński\n  event_name: \"tiny ruby #{conf} 2025\"\n  date: \"2025-11-21\"\n  published_at: \"2025-12-01\"\n  description: |-\n    There is more to Ruby than Rails. But at the same time there is...less. This talk explores both useful and plain weird use cases for mruby and mruby/c. Starting with game scripting, going through retro consoles and finishing with auto-focus glasses. From the author of Ruby on Playstation with <3.\n\n    Chris started programming as a kid on a Commodore 64 (which he still owns today). He enjoys working on web application performance and can often be found exploring APM tools to identify areas for optimization. He also has a strong interest in AI/ML workflows. Chris speaks just enough Japanese to hold a brief, two-minute conversation with Matz.\n  id: \"tinyruby-2025-even-smaller-rubies\"\n  video_provider: \"youtube\"\n  video_id: \"D6TArLQNxDk\"\n\n- title: \"Brewing potions with Ruby and linear programming\"\n  speakers:\n    - Youssef Boulkaid\n  event_name: \"tiny ruby #{conf} 2025\"\n  date: \"2025-11-21\"\n  published_at: \"2025-11-30\"\n  description: |-\n    Potionomics is a cozy game about running a potion shop and brewing potions. However, it can also lead down a deep rabbit hole of combinatorics, data modeling, and optimization. Join me in learning more about linear programming and how that can apply to fields from potion brewing to energy modeling.\n\n    Youssef is an energy researcher turned software developer. Throughout his career, he has often worked on developer tools, drawn to the leverage they provide and the satisfaction of helping other developers become more productive.\n  id: \"tinyruby-2025-brewing-potions\"\n  video_provider: \"youtube\"\n  video_id: \"CqyCn6kaKoY\"\n\n- title: \"Docker - Build the Perfect Home for Ruby\"\n  speakers:\n    - Matti Paksula\n  event_name: \"tiny ruby #{conf} 2025\"\n  date: \"2025-11-21\"\n  published_at: \"2025-11-29\"\n  description: |-\n    Rails includes a Dockerfile, but it can be optimized. Learn gem caching, layer strategies, multi-arch builds, and speeding up CI/CD. Use Docker effectively for development and production; it works for any Ruby app with or without Rails.\n\n    Matti Paksula is a seasoned startup and end-to-end testing, DevOps, and hosting specialist who started using Ruby on Rails in 2006 and Docker in 2014. He has written numerous tools that he publishes to GitHub under the name matti.\n\n    https://mattipaksula.com/tinyruby\n  id: \"tinyruby-2025-docker-perfect-home\"\n  video_provider: \"youtube\"\n  video_id: \"FMujxof3VLI\"\n  slides_url: \"https://docs.google.com/presentation/d/1ydkPGq1JZqPwx-G_KLv8QVEWvIRrIZ-evRbflVAwHnE/view\"\n\n- title: \"Unlocking the Rubetta Stones: Translating a Hoard of Ancient Tablets with Ractors and AI\"\n  speakers:\n    - Louis Antonopoulos\n  event_name: \"tiny ruby #{conf} 2025\"\n  date: \"2025-11-21\"\n  published_at: \"2025-11-28\"\n  description: |-\n    The Rubetta Stones were just uncovered in an archaeological dig near Helsinki. But they immediately started decaying when they were unearthed. Deciphering them seems impossible, but with the power of Ractors and a Ruby AI assistant, maybe we can break the code before it disappears forever.\n\n    Louis is a Rails developer, song-parody writer, and committed punster. He started as an iOS developer but fell in love with Rails, TDD, and the joy of not having to wait for app store approval.\n  id: \"tinyruby-2025-unlocking-the-rubetta-stones\"\n  video_provider: \"youtube\"\n  video_id: \"gmj86xf63LE\"\n\n- title: \"Revisiting Booleans in Ruby\"\n  speakers:\n    - Sarah Lima\n  event_name: \"tiny ruby #{conf} 2025\"\n  date: \"2025-11-21\"\n  published_at: \"2025-11-27\"\n  description: |-\n    Ruby's Booleans seem simple: just true and false, right? But under the hood and in practice, it's way messier. We'll talk about how Ruby interprets truth, why Booleans are often the wrong modeling tool, and how to model complex state the Ruby way.\n\n    Sarah is a Senior Development Consultant at thoughtbot, former maintainer of Factory Bot, and has extensive experience maintaining and growing Ruby applications.\n  id: \"tinyruby-2025-revisiting-booleans\"\n  video_provider: \"youtube\"\n  video_id: \"WsD_848tfgI\"\n\n- title: \"Level Up Your Engineering Career with Mentorship, Pairing, and AI\"\n  speakers:\n    - Hana Harenčárová\n  event_name: \"tiny ruby #{conf} 2025\"\n  date: \"2025-11-21\"\n  published_at: \"2025-11-26\"\n  description: |-\n    Feeling stuck in your technical growth? Don't learn alone. Discover how to tap into mentorship, pair programming, and AI to accelerate your skills. Whether you're early in career or going for senior roles, this session offers strategies to get there faster and enjoy the journey.\n\n    Hana is a Rubyist at heart and a software engineer at GitHub. A former judgment and decision-making researcher turned paragliding instructor turned developer, she shares her passion by teaching at Ruby Monstas Zurich, Rails Girls, and co-organising Helvetic Ruby.\n  id: \"tinyruby-2025-level-up-your-engineering-career\"\n  video_provider: \"youtube\"\n  video_id: \"W-6iI0pA-OQ\"\n"
  },
  {
    "path": "data/tiny-ruby-conf/tiny-ruby-conf-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://cfp.helsinkiruby.fi\"\n  open_date: \"2026-02-06\"\n  close_date: \"2026-06-14\"\n"
  },
  {
    "path": "data/tiny-ruby-conf/tiny-ruby-conf-2026/event.yml",
    "content": "---\nid: \"tiny-ruby-conf-2026\"\ntitle: \"tiny ruby #{conf} 2026\"\nkind: \"conference\"\nfrequency: \"yearly\"\nlocation: \"Helsinki, Finland\"\ndescription: |-\n  tiny ruby #{conf} is an affordable, one day, single-track Ruby conference in Helsinki, Finland.\nstart_date: \"2026-10-01\"\nend_date: \"2026-10-01\"\npublished_at: \"2025-12-10\"\ndate_precision: \"day\"\nyear: 2026\nbanner_background: \"#0A1936\"\nfeatured_background: \"#0A1936\"\nfeatured_color: \"#FFFFFF\"\nwebsite: \"https://helsinkiruby.fi/tinyruby/\"\ncoordinates:\n  latitude: 60.1640543\n  longitude: 24.9445715\n"
  },
  {
    "path": "data/tiny-ruby-conf/tiny-ruby-conf-2026/venue.yml",
    "content": "# docs/ADDING_VENUES.md\n# Delete unnecessary keys\n---\nname: \"G Livelab\"\ndescription: |-\n  G Livelab is a chance to experience live music in a context which enables the performance to succeed beyond expectations.\nurl: \"https://glivelab.fi\"\naddress:\n  street: \"3 Yrjönkatu\"\n  city: \"Helsinki\"\n  region: \"Uusimaa\"\n  postal_code: \"00120\"\n  country: \"Finland\"\n  country_code: \"fi\"\n  display: \"Yrjönkatu 3, Helsinki, Finland\"\n\ncoordinates:\n  latitude: 60.1640543\n  longitude: 24.9445715\n\nmaps:\n  google: \"https://maps.app.goo.gl/RdGdDY9bfazh1swR8\"\n  apple: \"https://maps.apple.com/place?address=Yrj%C3%B6nkatu%203,%2000120%20Helsinki,%20Finland&coordinate=60.164034,24.944537&name=G%20Livelab&place-id=I5B2ED7FBD4D933E9\"\n  openstreetmap: \"https://www.openstreetmap.org/#map=18/60.164055/24.944571\"\n\naccessibility:\n  wheelchair: true\n  elevators: true\n  accessible_restrooms: true\n"
  },
  {
    "path": "data/tokyo-rubykaigi/series.yml",
    "content": "---\nname: \"Tokyo RubyKaigi\"\nwebsite: \"https://regional.rubykaigi.org/tokyo12/\"\ntwitter: \"tokyork12\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\nyoutube_channel_id: \"\"\naliases:\n  - \"東京Ruby会議\"\n"
  },
  {
    "path": "data/tokyo-rubykaigi/tokyo-rubykaigi-10/event.yml",
    "content": "---\nid: \"tokyo-rubykaigi-10\"\ntitle: \"Tokyo RubyKaigi 10\"\ndescription: \"\"\nlocation: \"Mihama, Chiba, Japan\"\nkind: \"conference\"\nstart_date: \"2013-01-13\"\nend_date: \"2013-01-14\"\nwebsite: \"https://regional.rubykaigi.org/tokyo10/\"\noriginal_website: \"https://tokyo10.rubykaigi.info\"\nbanner_background: \"#000037\"\nfeatured_background: \"#000037\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 35.6764225\n  longitude: 139.650027\n"
  },
  {
    "path": "data/tokyo-rubykaigi/tokyo-rubykaigi-10/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://regional.rubykaigi.org/tokyo10/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/tokyo-rubykaigi/tokyo-rubykaigi-11/event.yml",
    "content": "---\nid: \"tokyo-rubykaigi-11\"\ntitle: \"Tokyo RubyKaigi 11\"\ndescription: \"\"\nlocation: \"Chiyoda City, Tokyo, Japan\"\nkind: \"conference\"\nstart_date: \"2016-05-28\"\nend_date: \"2016-05-28\"\nwebsite: \"https://regional.rubykaigi.org/tokyo11/\"\ncoordinates:\n  latitude: 35.6764225\n  longitude: 139.650027\n"
  },
  {
    "path": "data/tokyo-rubykaigi/tokyo-rubykaigi-11/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://regional.rubykaigi.org/tokyo11/\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/tokyo-rubykaigi/tokyo-rubykaigi-12/event.yml",
    "content": "---\nid: \"tokyo-rubykaigi-12\"\ntitle: \"Tokyo RubyKaigi 12\"\ndescription: \"\"\nlocation: \"Tsurumi, Yokohama, Japan\"\nkind: \"conference\"\nstart_date: \"2025-01-18\"\nend_date: \"2025-01-18\"\nwebsite: \"https://regional.rubykaigi.org/tokyo12/\"\ntwitter: \"tokyork12\"\nbanner_background: \"#DD451C\"\nfeatured_background: \"#DD451C\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 35.6764225\n  longitude: 139.650027\n"
  },
  {
    "path": "data/tokyo-rubykaigi/tokyo-rubykaigi-12/schedule.yml",
    "content": "# Schedule: https://regional.rubykaigi.org/tokyo12/schedule/\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2025-01-18\"\n    grid:\n      - start_time: \"10:30\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Door Open\n\n      - start_time: \"11:00\"\n        end_time: \"11:10\"\n        slots: 1\n        items:\n          - Opening\n\n      - start_time: \"11:10\"\n        end_time: \"11:50\"\n        slots: 1\n        # Keynote: John Hawthorn\n\n      - start_time: \"11:50\"\n        end_time: \"13:10\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:10\"\n        end_time: \"13:35\"\n        slots: 2\n        # 2 parallel talks (4F Hall & 3F Gallery)\n\n      - start_time: \"13:35\"\n        end_time: \"14:00\"\n        slots: 2\n        # 2 parallel talks (4F Hall & 3F Gallery)\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 2\n        # 2 parallel talks (4F Hall & 3F Gallery)\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - Long Break\n\n      - start_time: \"15:00\"\n        end_time: \"15:25\"\n        slots: 2\n        # 2 parallel talks (4F Hall & 3F Gallery)\n\n      - start_time: \"15:25\"\n        end_time: \"15:50\"\n        slots: 2\n        # 2 parallel talks (4F Hall & 3F Gallery)\n\n      - start_time: \"15:50\"\n        end_time: \"16:30\"\n        slots: 1\n        # Regional.rb and the Tokyo Metropolis\n\n      - start_time: \"16:30\"\n        end_time: \"16:50\"\n        slots: 1\n        items:\n          - Long Break\n\n      - start_time: \"16:50\"\n        end_time: \"17:50\"\n        slots: 1\n        # Keynote: Kohei Suzuki\n\n      - start_time: \"17:50\"\n        end_time: \"18:00\"\n        slots: 1\n        items:\n          - Closing\n\ntracks:\n  - name: \"4F Hall\"\n    color: \"#CC0000\"\n    text_color: \"#FFFFFF\"\n\n  - name: \"3F Gallery\"\n    color: \"#0066CC\"\n    text_color: \"#FFFFFF\"\n"
  },
  {
    "path": "data/tokyo-rubykaigi/tokyo-rubykaigi-12/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Ruby Sponsors\"\n      description: |-\n        Ruby Sponsors tier explicitly mentioned with a list of sponsoring companies with their descriptions and URLs.\n      level: 1\n      sponsors:\n        - name: \"TwoGate\"\n          badge: \"\"\n          website: \"https://twogate.com\"\n          slug: \"kabushikigaisha-twogate\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/twogate.com.DWbCFLKu.svg\"\n\n        - name: \"Cookpad\"\n          badge: \"\"\n          website: \"https://cookpad.careers/\"\n          slug: \"kukkupaddokabushikigaisha\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/cookpad.3gCjm6kZ.svg\"\n\n        - name: \"Livesense Inc.\"\n          badge: \"\"\n          website: \"https://job-draft.jp/\"\n          slug: \"tenshokudorafutokabushikigaishiribusensu\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/livesense.co.jp.BfoG-6L0.svg\"\n\n    - name: \"Gold Sponsors\"\n      description: |-\n        Gold Sponsors tier explicitly mentioned with a list of sponsoring companies with their descriptions and URLs.\n      level: 2\n      sponsors:\n        - name: \"SmartHR\"\n          badge: \"\"\n          website: \"https://hello-world.smarthr.co.jp/\"\n          slug: \"smarthr\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/SmartHR.Dt-llX7n.svg\"\n\n        - name: \"Timee, Inc.\"\n          badge: \"\"\n          website: \"https://timee.notion.site/timee/Timee-Product-Org-Entrance-Book-b7380eb4f6954e29b2664fe6f5e775f9\"\n          slug: \"kabushikigaishitaimii\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/timee.CaOYnE4u.svg\"\n\n        - name: \"ANDPAD Inc.\"\n          badge: \"\"\n          website: \"https://engineer.andpad.co.jp/\"\n          slug: \"andpad\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/ANDPAD.DQ8fxdkX.svg\"\n\n        - name: \"hacomono\"\n          badge: \"\"\n          website: \"https://www.hacomono.co.jp/recruit/engineer/\"\n          slug: \"kabushikigaishihacomono\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/hacomono.Cha5zb3S.svg\"\n\n    - name: \"Silver Sponsors\"\n      description: |-\n        Silver Sponsors tier explicitly mentioned with a list of sponsoring companies with their descriptions and URLs.\n      level: 3\n      sponsors:\n        - name: \"Topotal\"\n          badge: \"\"\n          website: \"https://topotal.com/\"\n          slug: \"kabushikigaishitopotal\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/topotal.CqeaCpeM.svg\"\n\n        - name: \"FjordBootCamp\"\n          badge: \"\"\n          website: \"https://bootcamp.fjord.jp\"\n          slug: \"fiyorudobuttokyanpu\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/FBC.RO6itOTF.svg\"\n\n        - name: \"A's Child Inc.\"\n          badge: \"\"\n          website: \"https://www.as-child.com/\"\n          slug: \"esuchairudokabushikigaisha\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/as-child.com.YGeLvKPK.svg\"\n\n        - name: \"Enishi Tech Inc.\"\n          badge: \"\"\n          website: \"https://www.enishi-tech.com/\"\n          slug: \"kabushikigaishienishitekku\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/enishi-tech.com.i1bGkQeY.svg\"\n\n        - name: \"ESM, Inc.\"\n          badge: \"\"\n          website: \"https://agile.esm.co.jp/\"\n          slug: \"kabushikigaishieisirusisutemumanejimento\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/esm.Bw0xKwzJ.svg\"\n\n        - name: \"株式会社スマートバンク\"\n          badge: \"\"\n          website: \"https://smartbank.co.jp/recruit/engineer-summary\"\n          slug: \"kabushikigaishisuma-tobank\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/smartbank.co.jp.BsM5Gud7.svg\"\n\n        - name: \"codeTakt Inc.\"\n          badge: \"\"\n          website: \"https://codetakt.com/\"\n          slug: \"kabushikigaishikodotakuto\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/codetakt.com.DMrnANhg.svg\"\n\n        - name: \"Bloomo Securities Inc.\"\n          badge: \"\"\n          website: \"https://bloomo.co.jp/\"\n          slug: \"buru-moshoukenkabushikigaisha\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/bloomo.BBTrA-8e.svg\"\n\n        - name: \"STORES, Inc.\"\n          badge: \"\"\n          website: \"https://jobs.st.inc/engineer\"\n          slug: \"stores\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/STORES.BJJsvSOG.svg\"\n\n        - name: \"Linkers Corporation\"\n          badge: \"\"\n          website: \"https://corp.linkers.net/\"\n          slug: \"rink-a-zukabushikigaisha\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/linkers.net.C7Ch1YkW.svg\"\n\n        - name: \"mov inc.\"\n          badge: \"\"\n          website: \"https://mov.am/\"\n          slug: \"kabushikigaishimov\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/mov.CUxy_Znc.svg\"\n\n        - name: \"Network Applied Communication Laboratory Ltd.\"\n          badge: \"\"\n          website: \"https://www.netlab.jp/\"\n          slug: \"kabushikigaishinettowakuouyoutsuushin-kenkyuusho\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/nacl-logo.20GC2eeF.svg\"\n\n        - name: \"esa LLC\"\n          badge: \"Tools Sponsor\"\n          website: \"https://esa.io/\"\n          slug: \"goudoushikaishiesa\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/esa.DXTQGjmQ.svg\"\n\n        - name: \"M3 Career, Inc.\"\n          badge: \"\"\n          website: \"https://www.m3career.com/\"\n          slug: \"emur-kyari-kabushikigaisha\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/m3career.DOmrO9NW.svg\"\n\n        - name: \"ROUTE06, Inc.\"\n          badge: \"\"\n          website: \"https://route06.com/\"\n          slug: \"kabushikigaishiroute06\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/route06.BDi2zJRT.svg\"\n\n        - name: \"giftee Inc.\"\n          badge: \"\"\n          website: \"https://giftee.co.jp/\"\n          slug: \"kabushikigaishigifuti\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/giftee.BEU05KfT.svg\"\n\n        - name: \"ANGLERS Inc.\"\n          badge: \"\"\n          website: \"https://corp.anglers.jp/recruit/\"\n          slug: \"kabushikigaishiangurazu\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/anglers.COmPnSBd.svg\"\n\n        - name: \"Research and Innovation Co.,Ltd.\"\n          badge: \"\"\n          website: \"https://r-n-i.jp/\"\n          slug: \"kabushikigaishirisachi-andoinobeshon\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/rni.CnrarMB6.svg\"\n\n        - name: \"Luxiar Co., Ltd.\"\n          badge: \"\"\n          website: \"https://www.luxiar.com/\"\n          slug: \"kabushikigaishiraguzaiya\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/luxiar.DDu4lyWL.svg\"\n\n        - name: \"Rentio Inc.\"\n          badge: \"\"\n          website: \"https://www.rentio.jp/\"\n          slug: \"rentio-kabushikigaisha\"\n          logo_url: \"https://regional.rubykaigi.org/tokyo12/_astro/rentio.DeCKfE41.svg\"\n"
  },
  {
    "path": "data/tokyo-rubykaigi/tokyo-rubykaigi-12/videos.yml",
    "content": "# Website: https://regional.rubykaigi.org/tokyo12/\n---\n- id: \"john-hawthorn-tokyo-rubykaigi-12\"\n  title: \"Keynote: Scaling Ruby @ GitHub\"\n  speakers:\n    - John Hawthorn\n  track: \"4F Hall\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"john-hawthorn-tokyo-rubykaigi-12\"\n  language: \"English\"\n  description: |-\n    Keynote by John Hawthorn, Ruby Committer and Rails Core member, Staff Engineer at GitHub\n  slides_url: \"\"\n\n- id: \"shugo-maeda-tokyo-rubykaigi-12\"\n  title: \"Ruby製テキストエディタでの生活\"\n  speakers:\n    - Shugo Maeda\n  track: \"4F Hall\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"shugo-maeda-tokyo-rubykaigi-12\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"tomoya-ishida-tokyo-rubykaigi-12\"\n  title: \"全てが同期する! Railsとフロントエンドのシームレスな連携の再考\"\n  speakers:\n    - Tomoya Ishida\n  track: \"3F Gallery\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"tomoya-ishida-tokyo-rubykaigi-12\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"yumu-tokyo-rubykaigi-12\"\n  title: \"Ruby×AWSで作る動画変換システム\"\n  speakers:\n    - yumu\n  track: \"4F Hall\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"yumu-tokyo-rubykaigi-12\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"hiromi-ogawa-tokyo-rubykaigi-12\"\n  title: \"Writing PDFs in Ruby DSL\"\n  speakers:\n    - Hiromi Ogawa\n  track: \"3F Gallery\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"hiromi-ogawa-tokyo-rubykaigi-12\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"morihirok-tokyo-rubykaigi-12\"\n  title: \"混沌とした例外処理とエラー監視に秩序をもたらす\"\n  speakers:\n    - morihirok\n  track: \"4F Hall\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"morihirok-tokyo-rubykaigi-12\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"moznion-tokyo-rubykaigi-12\"\n  title: \"simple組み合わせ村から大都会Railsにやってきた俺は\"\n  speakers:\n    - moznion\n  track: \"3F Gallery\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"moznion-tokyo-rubykaigi-12\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"tokujiros-tokyo-rubykaigi-12\"\n  title: \"ゼロからの、2Dレトロゲームエンジンの作り方\"\n  speakers:\n    - tokujiros\n  track: \"4F Hall\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"tokujiros-tokyo-rubykaigi-12\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"ryopeko-tokyo-rubykaigi-12\"\n  title: \"functionalなアプローチで動的要素を排除する\"\n  speakers:\n    - ryopeko\n  track: \"3F Gallery\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"ryopeko-tokyo-rubykaigi-12\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"buty4649-tokyo-rubykaigi-12\"\n  title: \"mrubyでワンバイナリーなテキストフィルタツールを作った\"\n  speakers:\n    - buty4649\n  track: \"4F Hall\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"buty4649-tokyo-rubykaigi-12\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"kasumi-hanazuki-tokyo-rubykaigi-12\"\n  title: \"Ruby meets secure DNS and modern Internet protocols\"\n  speakers:\n    - Kasumi Hanazuki\n  track: \"3F Gallery\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"kasumi-hanazuki-tokyo-rubykaigi-12\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"regional-rb-organizers-tokyo-rubykaigi-12\"\n  title: \"Regional.rb and the Tokyo Metropolis\"\n  speakers:\n    - Regional.rb Organizers\n  track: \"4F Hall\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"regional-rb-organizers-tokyo-rubykaigi-12\"\n  language: \"Japanese\"\n  description: \"\"\n  slides_url: \"\"\n\n- id: \"kohei-suzuki-tokyo-rubykaigi-12\"\n  title: \"Keynote: Ruby と Rust と私\"\n  speakers:\n    - Kohei Suzuki\n  track: \"4F Hall\"\n  event_name: \"Tokyo RubyKaigi 12\"\n  date: \"2025-01-18\"\n  video_provider: \"scheduled\"\n  video_id: \"kohei-suzuki-tokyo-rubykaigi-12\"\n  language: \"Japanese\"\n  description: |-\n    Keynote by Kohei Suzuki, SRE at Cookpad\n  slides_url: \"\"\n"
  },
  {
    "path": "data/topics.yml",
    "content": "---\n- A/B Testing\n- Accessibility (a11y)\n- ActionCable\n- ActionMailbox\n- ActionMailer\n- ActionPack\n- ActionText\n- ActionView\n- ActiveJob\n- ActiveModel\n- ActiveRecord\n- ActiveStorage\n- ActiveSupport\n- Algorithms\n- Android\n- Angular.js\n- Arel\n- Artificial Intelligence (AI)\n- Assembly\n- Authentication\n- Authorization\n- Automation\n- Awards\n- Background jobs\n- Behavior-Driven Development (BDD)\n- Blogging\n- Bootstrapping\n- Bundler\n- Business Logic\n- Business\n- Caching\n- Capybara\n- Career Development\n- CI/CD\n- Client-Side Rendering\n- Code Golfing\n- Code Organization\n- Code Quality\n- Command Line Interface (CLI)\n- Communication\n- Communication\n- Community\n- Compiling\n- Components\n- Computer Vision\n- Concurrency\n- Containers\n- Content Management System (CMS)\n- Content Management\n- Continuous Integration (CI)\n- Contributing\n- CRuby\n- Crystal\n- CSS\n- Data Analysis\n- Data Integrity\n- Data Migrations\n- Data Persistence\n- Data Processing\n- Database Sharding\n- Databases\n- Debugging\n- Dependency Management\n- Deployment\n- Design Patterns\n- Developer Expierience (DX)\n- Developer Tooling\n- Developer Tools\n- Developer Workflows\n- DevOps\n- Distributed Systems\n- Diversity & Inclusion\n- Docker\n- Documentation Tools\n- Documentation\n- Domain Driven Design\n- Domain Specific Language (DSL)\n- dry-rb\n- Duck Typing\n- E-Commerce\n- Early-Career Devlopers\n- Editor\n- Elm\n- Encoding\n- Encryption\n- Engineering Culture\n- Error Handling\n- Ethics\n- Event Sourcing\n- Fibers\n- Flaky Tests\n- Frontend\n- Functional Programming\n- Game Shows\n- Games\n- Geocoding\n- git\n- Go\n- Graphics\n- GraphQL\n- gRPC\n- Hacking\n- Hanami\n- Hotwire\n- HTML\n- HTTP API\n- Hybrid Apps\n- Indie Developer\n- Inspiration\n- Integrated Development Environment (IDE)\n- Integration Test\n- Internals\n- Internationalization (I18n)\n- Interview\n- iOS\n- Java Virtual Machine (JVM)\n- JavaScript\n- Job Interviewing\n- JRuby\n- JSON Web Tokens (JWT)\n- Just-In-Time (JIT)\n- Kafka\n- Keynote\n- Language Server Protocol (LSP)\n- Large Language Models (LLM)\n- Leadership\n- Legacy Applications\n- Licensing\n- Lightning Talks\n- Linters\n- Live Coding\n- Localization (L10N)\n- Logging\n- Machine Learning\n- Majestic Monolith\n- Markup\n- Math\n- Memory Managment\n- Mental Health\n- Mentorship\n- MFA/2FA\n- Microcontroller\n- Microservices\n- Minimum Viable Product (MVP)\n- Minitest\n- MJIT\n- Mocking\n- Model-View-Controller (MVC)\n- Monitoring\n- Monolith\n- mruby\n- Multitenancy\n- Music\n- MySQL\n- Naming\n- Native Apps\n- Native Extensions\n- Networking\n- Object-Oriented Programming (OOP)\n- Object-Relational Mapper (ORM)\n- Observability\n- Offline-First\n- Open Source\n- Organizational Skills\n- Pair Programming\n- Panel Discussion\n- Parallelism\n- Parsing\n- Passwords\n- People Skills\n- Performance\n- Personal Development\n- Phlex\n- Podcasts\n- PostgreSQL\n- Pricing\n- Privacy\n- Productivity\n- Profiling\n- Progressive Web Apps (PWA)\n- Project Planning\n- Quality Assurance (QA)\n- Questions and Anwsers (Q&A)\n- Rack\n- Ractors\n- Rails at Scale\n- Rails Engine\n- Rails Plugins\n- Rails Upgrades\n- Railties\n- React.js\n- Real-Time Applications\n- Refactoring\n- Regex\n- Remote Work\n- Reporting\n- REST API\n- REST\n- Rich Text Editor\n- RJIT\n- Robot\n- RPC\n- RSpec\n- Ruby Implementations\n- Ruby on Rails\n- Ruby VM\n- Rubygems\n- Rust\n- Scaling\n- Science\n- Security Vulnerability\n- Security\n- Selenium\n- Server-side Rendering\n- Servers\n- Service Objects\n- Shoes.rb\n- Sidekiq\n- Sinatra\n- Single Page Applications (SPA)\n- Software Architecture\n- Sonic Pi\n- Sorbet\n- SQLite\n- Startups\n- Static Typing\n- Stimulus.js\n- Structured Query Language (SQL)\n- Success Stories\n- Swift\n- Syntax\n- System Programming\n- System Test\n- Tailwind CSS\n- Teaching\n- Team Building\n- Teams\n- Teamwork\n- Templating\n- Template Engine\n- Test Coverage\n- Test Framework\n- Test-Driven Development\n- Testing\n- Threads\n- Timezones\n- Tips & Tricks\n- Trailblazer\n- Translation\n- Transpilation\n- TruffleRuby\n- Turbo Native\n- Turbo\n- Type Checking\n- Types\n- Typing\n- UI Design\n- Unit Test\n- Usability\n- User Interface (UI)\n- Version Control\n- ViewComponent\n- Views\n- Virtual Machine\n- Vue.js\n- Web Components\n- Web Server\n- Websockets\n- why the lucky stiff\n- Workshop\n- Writing\n- YARV (Yet Another Ruby VM)\n- YJIT (Yet Another Ruby JIT)\n"
  },
  {
    "path": "data/toronto-ruby/series.yml",
    "content": "---\nname: \"Toronto Ruby Meetup\"\nwebsite: \"https://toronto-ruby.com\"\ntwitter: \"toronto_ruby\"\nyoutube_channel_name: \"TorontoRuby\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"CA\"\nlanguage: \"english\"\nyoutube_channel_id: \"UClHJzi2-L5SA5K7GaV5p1JQ\"\n"
  },
  {
    "path": "data/toronto-ruby/toronto-ruby-meetup/event.yml",
    "content": "---\nid: \"toronto-ruby-meetup\"\ntitle: \"Toronto Ruby Meetup\"\nlocation: \"Toronto, Canada\"\ndescription: |-\n  We're a group of Ruby developers who meet up to talk about programming, the industry, and life. We're working to strengthen the local Ruby community and provide a positive space for everyone to connect.\nkind: \"meetup\"\nbanner_background: \"#FFF8EF\"\nfeatured_background: \"#FFF8EF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://toronto-ruby.com\"\ncoordinates:\n  latitude: 43.653226\n  longitude: -79.3831843\n"
  },
  {
    "path": "data/toronto-ruby/toronto-ruby-meetup/videos.yml",
    "content": "---\n- id: \"toronto-ruby-november-2023\"\n  title: \"Toronto Ruby November 2023\"\n  description: |\n    Inaugural Edition\n    Nov 23, 2023 @ 06:00PM\n\n    Workplace One\n    51 Wolseley St, Toronto ON\n    Lower level, enter through doors on Wolseley St.\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    6pm - Arrive, chat, and get pizza\n    7pm - Integer#even? Going stupidly deep on pointless performance questions, but hopefully learning something fun along the way by Matt Eagar\n\n    remainder of time until 9pm - Networking and drinks\n\n    https://toronto-ruby.com/events/inaugural-edition\n  event_name: \"Toronto Ruby November 2023\"\n  date: \"2023-11-23\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-november-2023\"\n  talks:\n    - title: \"Integer#even? Going stupidly deep on pointless performance questions, but hopefully learning something fun along the way\"\n      event_name: \"Toronto Ruby November 2023\"\n      speakers:\n        - Matt Eagar\n      video_provider: \"not_recorded\"\n      id: \"matt-eagar-toronto-ruby-november-2023\"\n      video_id: \"matt-eagar-toronto-ruby-november-2023\"\n      date: \"2023-11-23\"\n      description: \"\"\n\n- id: \"toronto-ruby-january-2024\"\n  title: \"Toronto Ruby January 2024\"\n  event_name: \"Toronto Ruby January 2024\"\n  date: \"2024-01-24\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-january-2024\"\n  description: |\n    January Edition\n    Jan 24, 2024 @ 06:00PM\n\n    Loop Financial\n    500-410 Adelaide Street West, Toronto, ON M5V 1S8\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    6pm - Arrive, chat, and get pizza\n    7pm - Rails and the Ruby Garbage Collector: How to Speed Up Your Rails App by Peter Zhu, Senior Developer at Shopify\n\n    remainder of time until 9pm - Networking and drinks\n\n    https://toronto-ruby.com/events/january-edition\n  talks:\n    - title: \"Rails and the Ruby Garbage Collector: How to Speed Up Your Rails App\"\n      event_name: \"Toronto Ruby January 2024\"\n      speakers:\n        - Peter Zhu\n      video_provider: \"youtube\"\n      id: \"peter-zhu-toronto-ruby-january-2024\"\n      video_id: \"uBpDcNCBwws\"\n      date: \"2024-01-24\"\n      published_at: \"2024-01-29\"\n      description: |-\n        Talk by Shopify's Peter Zhu for Toronto Ruby's Jan 24th Meetup hosted by Loop Financial.\n\n- id: \"toronto-ruby-february-2024\"\n  title: \"Toronto Ruby February 2024\"\n  event_name: \"Toronto Ruby February 2024\"\n  date: \"2024-02-29\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-february-2024\"\n  description: |\n    February Edition\n    Feb 29, 2024 @ 06:00PM\n\n    Workplace One\n    51 Wolseley St, Toronto ON\n    Lower level, enter through doors on Wolseley St.\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    6pm - Arrive, chat, and get pizza\n    7pm - All About the Ruby LSP by Vinicius Stock, Staff Developer at Shopify\n\n    remainder of time until 9pm - Networking and drinks\n\n    https://toronto-ruby.com/events/february-edition\n  talks:\n    - title: \"2 Years of the Ruby LSP\"\n      event_name: \"Toronto Ruby February 2024\"\n      speakers:\n        - Vinicius Stock\n      video_provider: \"youtube\"\n      id: \"vinicius-stock-toronto-ruby-february-2024\"\n      video_id: \"8RZVMf68MdE\"\n      date: \"2024-02-29\"\n      published_at: \"2024-03-05\"\n      description: |-\n        Talk by Shopify's Vinicius Stock for Toronto Ruby's Feb 29th Meetup hosted by Switch Growth.\n\n- id: \"toronto-ruby-april-2024\"\n  title: \"Toronto Ruby April 2024\"\n  event_name: \"Toronto Ruby April 2024\"\n  date: \"2024-04-03\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-april-2024\"\n  description: |\n    April Edition\n    Apr 03, 2024 @ 06:00PM\n\n    FinanceIt @ The Well\n    8 Spadina Ave\n    Suite 2400\n    Toronto, ON M5V 2H6\n\n    Please note that public access to the building is restricted at 7pm! Please arrive before then.\n    When you arrive at The Well, please take the high rise elevators (19-38) to the 214th floor to get to reception.\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    6pm - Arrive, chat, and get pizza\n    7pm - Using Rails introspection to supercharge your editor by Andy Waite, Senior Developer at Shopify\n\n    remainder of time until 9pm - Networking and drinks\n\n    https://toronto-ruby.com/events/april-edition\n  talks:\n    - title: \"Using Rails introspection to supercharge your editor\"\n      event_name: \"Toronto Ruby April 2024\"\n      speakers:\n        - Andy Waite\n      video_provider: \"not_recorded\"\n      id: \"andy-waite-toronto-ruby-april-2024\"\n      video_id: \"andy-waite-toronto-ruby-april-2024\"\n      date: \"2024-04-03\"\n      description: \"\"\n\n- id: \"toronto-ruby-may-2024\"\n  title: \"Toronto Ruby May 2024\"\n  event_name: \"Toronto Ruby May 2024\"\n  date: \"2024-05-22\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-may-2024\"\n  description: |\n    May Edition\n    May 22, 2024 @ 06:00PM\n\n    Workplace One\n    51 Wolseley St, Toronto ON\n    Lower level, enter through doors on Wolseley St.\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    6pm - Arrive, chat, and get pizza\n    7pm - Concurrency in Ruby by Raj Kumar, Director of Software Engineering at Stealth\n\n    remainder of time until 9pm - Networking and drinks\n\n    https://toronto-ruby.com/events/may-edition\n  talks:\n    - title: \"Concurrency in Ruby\"\n      event_name: \"Toronto Ruby May 2024\"\n      speakers:\n        - Raj Kumar\n      video_provider: \"not_recorded\"\n      id: \"raj-kumar-toronto-ruby-may-2024\"\n      video_id: \"raj-kumar-toronto-ruby-may-2024\"\n      date: \"2024-05-22\"\n      description: \"\"\n\n- id: \"toronto-ruby-june-2024\"\n  title: \"Toronto Ruby June 2024\"\n  event_name: \"Toronto Ruby June 2024\"\n  date: \"2024-06-20\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-june-2024\"\n  description: |\n    June Edition\n    Jun 20, 2024 @ 06:00PM\n\n    Workplace One\n    51 Wolseley St, Toronto ON\n    Lower level, enter through doors on Wolseley St.\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    6pm -  Arrive, chat, and get pizza\n    7pm - Creating A Dev Container Ecosystem For Rails 8 by Andrew Novoselac, Senior Software Developer at Shopify\n\n    remainder of time until 9pm - Networking and drinks\n\n    https://toronto-ruby.com/events/june-edition\n  talks:\n    - title: \"Creating A Dev Container Ecosystem For Rails 8\"\n      event_name: \"Toronto Ruby June 2024\"\n      speakers:\n        - Andrew Novoselac\n      video_provider: \"not_recorded\"\n      id: \"andrew-novoselac-toronto-ruby-june-2024\"\n      video_id: \"andrew-novoselac-toronto-ruby-june-2024\"\n      date: \"2024-06-20\"\n      description: \"\"\n\n- id: \"toronto-ruby-august-2024\"\n  title: \"Toronto Ruby August 2024\"\n  event_name: \"Toronto Ruby August 2024\"\n  date: \"2024-08-13\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-august-2024\"\n  description: |-\n    Summer of Rails World Edition\n    Aug 13, 2024 @ 06:00PM\n\n    Humi\n    207 Queens Quay W\n    #400\n    Toronto, Ontario\n    M5J 1A7\n\n    Unlock the full potential of R&D tax credits with Humi and get up to 64% of your R&D spend from the Canadian government back.\n\n    We will have an in-person Rails World ticket raffle for 2 tickets. There will be two draws, one for each ticket. Only folks in-person will be eligible to be drawn!\n\n    Getting to Humi's offices\n    1️⃣ Enter the building and head through to the back (skip the first set of elevators) - we're at the closest side to the water!\n    2️⃣ Take the glass elevators up to the 4th floor\n    3️⃣ Our suite (unit 400) is to the left when exiting elevators!\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    6pm - Arrive, chat, and get pizza\n    7pm - Ruby + IPv6 for fun and profit by Claus Michael Oest Lensbøl, Senior Software Engineer at Humi\n\n    remainder of time until 9pm - Networking and drinks\n\n    https://toronto-ruby.com/events/summer-of-rails-world-edition\n  talks:\n    - title: \"Ruby + IPv6 for fun and profit\"\n      event_name: \"Toronto Ruby August 2024\"\n      speakers:\n        - Claus Lensbøl\n      video_provider: \"youtube\"\n      id: \"claus-lensbl-toronto-ruby-august-2024\"\n      video_id: \"XMUQEjRGx4c\"\n      date: \"2024-08-13\"\n      published_at: \"2024-08-26\"\n      description: \"\"\n\n- id: \"toronto-ruby-october-2024\"\n  title: \"Toronto Ruby October 2024\"\n  event_name: \"Toronto Ruby October 2024\"\n  date: \"2024-10-24\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-october-2024\"\n  description: |-\n    October 2024 Edition\n    Oct 24, 2024 @ 06:00PM\n\n    Shopify\n    10th Floor\n    620 King Street West\n    Toronto, ON\n\n    Check in with security in the lobby to be let up. Elevators will be available for the duration of the event.\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    6pm - Arrive, chat, and get pizza\n    7pm - Unlocking the Potential of Lockable by Angela Choi, Technical Implementation Manager at Financeit\n    7:30pm - POROs to make Rails Soar-os by Andrew Szczepanski, Head of Engineering at Centah\n\n    remainder of time until 9pm - Networking and drinks\n\n    https://toronto-ruby.com/events/october-2024-edition\n\n  talks:\n    - title: \"Unlocking the Potential of Lockable\"\n      event_name: \"Toronto Ruby October 2024\"\n      speakers:\n        - Angela Choi\n      video_provider: \"not_recorded\"\n      id: \"angela-choi-toronto-ruby-october-2024\"\n      video_id: \"angela-choi-toronto-ruby-october-2024\"\n      date: \"2024-10-24\"\n      description: \"\"\n\n    - title: \"POROs to make Rails Soar-os\"\n      event_name: \"Toronto Ruby October 2024\"\n      speakers:\n        - Andrew Szczepanski\n      video_provider: \"not_recorded\"\n      id: \"andrew-szczepanski-toronto-ruby-october-2024\"\n      video_id: \"andrew-szczepanski-toronto-ruby-october-2024\"\n      date: \"2024-10-24\"\n      description: \"\"\n\n- id: \"toronto-ruby-november-2024\"\n  title: \"Toronto Ruby November 2024\"\n  event_name: \"Toronto Ruby November 2024\"\n  date: \"2024-11-25\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-november-2024\"\n  talks: []\n  description: |-\n    Toronto Ruby's One Year Anniversary\n    Nov 25, 2024 @ 06:00PM\n\n    CRAFT Beer Market\n    1 Adelaide Street E\n    Toronto, ON\n    Agenda\n    Toronto Ruby is 1 Year Old!\n\n    Join us for a casual get together and celebrate one year of Toronto Ruby! There's more to come, but we wanted to take a bit of a break and celebrate before the holidays!\n\n    Pre-orders for food encouraged, we got the space for a small minimum spend and if you're able to support us by helping us reach it, we'd appreciate it! You can view the menu here: https://www.craftbeermarket.ca/menu/\n\n    https://toronto-ruby.com/events/toronto-rubys-one-year-anniversary\n\n- id: \"toronto-ruby-january-2025\"\n  title: \"Toronto Ruby January 2025\"\n  event_name: \"Toronto Ruby January 2025\"\n  date: \"2025-01-28\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-january-2025\"\n  description: |-\n    January 2025 - Welcome to 2025 Edition\n    Jan 28, 2025 @ 06:00PM\n\n    Clio\n    16 York Street\n    30th Floor\n    Toronto, ON  M5J 0E6\n\n    Take elevators up to 30th floor and check in.\n\n    Agenda\n    6pm - Arrive, chat, and get pizza\n    7pm - Little Leaks Sink Your Tests by Erin Paget, Software Development Manager at Clio\n\n    remainder of time until 9pm - Networking and drinks\n\n    https://toronto-ruby.com/events/january-2025---welcome-to-2025-edition\n\n  talks:\n    - title: \"Little Leaks Sink Your Tests\"\n      event_name: \"Toronto Ruby January 2025\"\n      speakers:\n        - Erin Paget\n      video_provider: \"not_recorded\"\n      id: \"erin-paget-toronto-ruby-january-2025\"\n      video_id: \"erin-paget-toronto-ruby-january-2025\"\n      date: \"2025-01-28\"\n      description: \"\"\n\n- id: \"toronto-ruby-february-2025\"\n  title: \"Toronto Ruby February 2025\"\n  event_name: \"Toronto Ruby February 2025\"\n  date: \"2025-02-27\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-february-2025\"\n  description: |-\n    February 2025\n    Feb 27, 2025 @ 06:00PM\n\n    Workplace One\n    51 Wolseley St, Toronto ON\n    Lower level, enter through doors on Wolseley St.\n    Agenda\n    6pm - Arrival\n\n    7pm - When Things Break, We Build: The Story of Gemdocs by Adam Daniels, Principal Consultant\n\n    Remainder of time - Networking\n\n    https://toronto-ruby.com/events/february-2025\n\n  talks:\n    - title: \"When Things Break, We Build: The Story of Gemdocs\"\n      event_name: \"Toronto Ruby February 2025\"\n      speakers:\n        - Adam Daniels\n      video_provider: \"not_recorded\"\n      id: \"adam-daniels-toronto-ruby-february-2025\"\n      video_id: \"adam-daniels-toronto-ruby-february-2025\"\n      date: \"2025-02-27\"\n      description: \"\"\n\n- id: \"toronto-ruby-march-2025\"\n  title: \"Toronto Ruby March 2025\"\n  event_name: \"Toronto Ruby March 2025\"\n  date: \"2025-03-20\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-march-2025\"\n  description: |-\n    March 2025\n    Mar 20, 2025 @ 06:00PM\n\n    Shopify\n    10th Floor\n    620 King Street West\n    Toronto, ON\n\n    Check in with security in the lobby to be let up. Elevators will be available for the duration of the event.\n\n    Food and drinks provided by our sponsor.\n    Agenda\n    6pm - Arrive, chat, and get pizza\n\n    7pm - Presentations\n\n    Worldwide and the complexities of the address form by Dominique Flabbi, Developer @ Shopify\n    Lessons from 5 years of UI architecture at GitHub by Joel Hawksley, Staff Engineer @ GitHub\n\n    remainder of time until 9pm - Networking and drinks\n\n    https://toronto-ruby.com/events/march-2025\n\n  talks:\n    - title: \"Worldwide and the complexities of the address form\"\n      event_name: \"Toronto Ruby March 2025\"\n      speakers:\n        - Dominique Flabbi\n      video_provider: \"not_recorded\"\n      id: \"dominique-flabbi-toronto-ruby-march-2025\"\n      video_id: \"dominique-flabbi-toronto-ruby-march-2025\"\n      date: \"2025-03-20\"\n      description: \"\"\n\n    - title: \"Lessons from 5 years of UI architecture at GitHub\"\n      event_name: \"Toronto Ruby March 2025\"\n      speakers:\n        - Joel Hawksley\n      video_provider: \"not_recorded\"\n      id: \"joel-hawksley-toronto-ruby-march-2025\"\n      video_id: \"joel-hawksley-toronto-ruby-march-2025\"\n      date: \"2025-03-20\"\n      description: \"\"\n\n- id: \"toronto-ruby-april-2025\"\n  title: \"Toronto Ruby April 2025\"\n  event_name: \"Toronto Ruby April 2025\"\n  date: \"2025-04-29\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-april-2025\"\n  description: |-\n    April 2025 - No Foolin' Edition\n    Apr 29, 2025 @ 05:30PM\n\n    Clio\n    16 York Street\n    30th Floor\n    Toronto, ON  M5J 0E6\n\n    Take elevators up to 30th floor and check in.\n\n    Agenda\n    5:30pm - Arrive, chat, and get pizza\n    6pm - Presentations\n    Improving websocket performance at Clio by Dan Bird\n    How the Clio mobile team uses Ruby and learning + applying Ruby for non-Rubyists by Ahmed El Bialy\n    Topic TBD by Erin Paget Dees\n\n    remainder of time until 8pm - Networking and drinks\n\n    https://toronto-ruby.com/events/april-2025---no-foolin-edition\n\n  talks:\n    - title: \"Improving websocket performance at Clio\"\n      event_name: \"Toronto Ruby April 2025\"\n      speakers:\n        - Dan Bird\n      video_provider: \"not_recorded\"\n      id: \"dan-bird-toronto-ruby-april-2025\"\n      video_id: \"dan-bird-toronto-ruby-april-2025\"\n      date: \"2025-04-29\"\n      description: \"\"\n\n    - title: \"How the Clio mobile team uses Ruby and learning + applying Ruby for non-Rubyists\"\n      event_name: \"Toronto Ruby April 2025\"\n      speakers:\n        - Ahmed El Bialy\n      video_provider: \"not_recorded\"\n      id: \"ahmed-el-bialy-toronto-ruby-april-2025\"\n      video_id: \"ahmed-el-bialy-toronto-ruby-april-2025\"\n      date: \"2025-04-29\"\n      description: \"\"\n\n- id: \"toronto-ruby-may-2025\"\n  title: \"Toronto Ruby May 2025\"\n  event_name: \"Toronto Ruby May 2025\"\n  date: \"2025-05-27\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-may-2025\"\n  description: |-\n    May 2025 - Spring is Here\n    May 27, 2025 @ 05:30PM\n\n    Phoenix\n    200 Wellington St. West\n    Suite 1400\n    Toronto, ON. M5V 3C7\n\n    Agenda\n    5:30pm - Arrive, chat, and get pizza\n    6pm - Presentations\n    Exploring the Ruby AI Ecosystem by Andy Waite\n    Cognitive complexity in cooking, code & chores by James Edward-Jones @ MindfulChef\n    Access Granted (Sort Of): The Art of Output Masking & Permissions by James Roscoe @ ShoreCG\n\n    remainder of time until 8:30pm - Networking and drinks\n\n    https://toronto-ruby.com/events/may-2025---spring-is-here\n\n  talks:\n    - title: \"Exploring the Ruby AI Ecosystem\"\n      event_name: \"Toronto Ruby May 2025\"\n      speakers:\n        - Andy Waite\n      video_provider: \"scheduled\"\n      id: \"andy-waite-toronto-ruby-may-2025\"\n      video_id: \"andy-waite-toronto-ruby-may-2025\"\n      date: \"2025-05-27\"\n      description: \"\"\n\n    - title: \"Cognitive complexity in cooking, code & chores\"\n      event_name: \"Toronto Ruby May 2025\"\n      speakers:\n        - James Edward-Jones\n      video_provider: \"scheduled\"\n      id: \"james-edward-jones-toronto-ruby-may-2025\"\n      video_id: \"james-edward-jones-toronto-ruby-may-2025\"\n      date: \"2025-05-27\"\n      description: \"\"\n\n    - title: \"Access Granted (Sort Of): The Art of Output Masking & Permissions\"\n      event_name: \"Toronto Ruby May 2025\"\n      speakers:\n        - James Roscoe\n      video_provider: \"scheduled\"\n      id: \"james-roscoe-toronto-ruby-may-2025\"\n      video_id: \"james-roscoe-toronto-ruby-may-2025\"\n      date: \"2025-05-27\"\n      description: \"\"\n\n- id: \"toronto-ruby-june-2025\"\n  title: \"Toronto Ruby June 2025\"\n  event_name: \"Toronto Ruby June 2025\"\n  date: \"2025-06-17\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-june-2025\"\n  description: |-\n    The Start of Summer Edition\n    June 17, 2025 @ 6:00 PM\n\n    Loop Financial\n    410 Adelaide St W, Suite 500, Toronto, ON M5V 1S7, Canada\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    6 PM: Arrive, chat, and get pizza\n    7 PM: Presentations\n    Remainder of time until 8:30 PM: Networking and drinks\n\n    Speakers:\n    * Varun Sindwani (Fullscript) - \"Flying 7500kms for a ruby conference (A Ruby Kaigi reflection)\"\n    * Yan Matagne (Loop) - \"Orchestrating Payment Workflows Without Losing Your Mind with Temporal.io\"\n\n    Sponsored by Loop Financial\n\n    https://toronto-ruby.com/events/june-2025---the-start-of-summer-edition\n  talks:\n    - title: \"Flying 7500kms for a ruby conference (A Ruby Kaigi reflection)\"\n      event_name: \"Toronto Ruby June 2025\"\n      speakers:\n        - Varun Sindwani\n      video_provider: \"scheduled\"\n      id: \"varun-sindwani-toronto-ruby-june-2025\"\n      video_id: \"varun-sindwani-toronto-ruby-june-2025\"\n      date: \"2025-06-17\"\n      description: \"\"\n\n    - title: \"Orchestrating Payment Workflows Without Losing Your Mind with Temporal.io\"\n      event_name: \"Toronto Ruby June 2025\"\n      speakers:\n        - Yan Matagne\n      video_provider: \"scheduled\"\n      id: \"yan-matagne-toronto-ruby-june-2025\"\n      video_id: \"yan-matagne-toronto-ruby-june-2025\"\n      date: \"2025-06-17\"\n      description: \"\"\n\n- id: \"toronto-ruby-july-2025\"\n  title: \"Toronto Ruby July 2025\"\n  event_name: \"Toronto Ruby July 2025\"\n  date: \"2025-07-24\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-july-2025\"\n  description: |-\n    July 2025 Edition\n    July 24, 2025 @ 5:30 PM\n\n    51 Wolseley Street\n    Lower Level\n    Toronto, ON\n    M5T 1A5\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    5:30 PM: Arrive, chat, and get food\n    6:30 PM: Talks\n    Remainder of time until 8:30 PM: Networking and drinks\n\n    Speakers:\n    * Meet Shah (Fullscript) - \"Implementing a Rule-Based Taxonomy at Fullscript\"\n    * Kristine McBride - \"Accelerating our Admin Rebuild with Rails Generators\"\n    * Mike Presman - \"Docker Not Required: Instant Rails Onboarding with Nix\"\n\n    Sponsored by Fullscript\n\n    https://toronto-ruby.com/events/july-2025-edition\n  talks:\n    - title: \"Implementing a Rule-Based Taxonomy at Fullscript\"\n      event_name: \"Toronto Ruby July 2025\"\n      speakers:\n        - Meet Shah\n      video_provider: \"scheduled\"\n      id: \"meet-shah-toronto-ruby-july-2025\"\n      video_id: \"meet-shah-toronto-ruby-july-2025\"\n      date: \"2025-07-24\"\n      description: \"\"\n\n    - title: \"Accelerating our Admin Rebuild with Rails Generators\"\n      event_name: \"Toronto Ruby July 2025\"\n      speakers:\n        - Kristine McBride\n      video_provider: \"scheduled\"\n      id: \"kristine-mcbride-toronto-ruby-july-2025\"\n      video_id: \"kristine-mcbride-toronto-ruby-july-2025\"\n      date: \"2025-07-24\"\n      description: \"\"\n\n    - title: \"Docker Not Required: Instant Rails Onboarding with Nix\"\n      event_name: \"Toronto Ruby July 2025\"\n      speakers:\n        - Mike Presman\n      video_provider: \"scheduled\"\n      id: \"mike-presman-toronto-ruby-july-2025\"\n      video_id: \"mike-presman-toronto-ruby-july-2025\"\n      date: \"2025-07-24\"\n      description: \"\"\n\n- id: \"toronto-ruby-september-2025\"\n  title: \"Toronto Ruby September 2025\"\n  event_name: \"Toronto Ruby September 2025\"\n  date: \"2025-09-23\"\n  video_provider: \"children\"\n  video_id: \"toronto-ruby-september-2025\"\n  description: |-\n    September 2025 Edition\n    September 23, 2025 @ 5:30 PM\n\n    Clio\n    16 York Street\n    30th Floor\n    Toronto, ON M5J 0E6\n\n    Take elevators up to 30th floor and check in.\n\n    Food and drinks provided by our sponsor.\n\n    Agenda\n    5:30 PM: Arrive, chat, and get pizza\n    6:00 PM: Presentations begin\n    Remainder of time: Networking and drinks\n\n    Speakers:\n    * Fabio Neves - \"Write HTML Like It's the Year 3000\"\n    * Tom Heina - Talk Title TBD\n\n    Sponsored by Clio\n\n    https://toronto-ruby.com/events/september-2025-edition\n    https://lu.ma/jy77b1m0\n  talks:\n    - title: \"Write HTML Like It's the Year 3000\"\n      event_name: \"Toronto Ruby September 2025\"\n      speakers:\n        - Fabio Neves\n      video_provider: \"scheduled\"\n      id: \"fabio-neves-toronto-ruby-september-2025\"\n      video_id: \"fabio-neves-toronto-ruby-september-2025\"\n      date: \"2025-09-23\"\n      description: \"\"\n\n    - title: \"Talk by Tom Heina\"\n      event_name: \"Toronto Ruby September 2025\"\n      speakers:\n        - Tom Heina\n      video_provider: \"scheduled\"\n      id: \"tom-heina-toronto-ruby-september-2025\"\n      video_id: \"tom-heina-toronto-ruby-september-2025\"\n      date: \"2025-09-23\"\n      description: \"\"\n"
  },
  {
    "path": "data/tropicalrb/abril-pro-ruby-2012/event.yml",
    "content": "---\nid: \"abril-pro-ruby-2012\"\ntitle: \"Abril Pro Ruby 2012\"\ndescription: \"\"\nlocation: \"Recife, Brazil\"\nkind: \"conference\"\nstart_date: \"2012-04-21\"\nend_date: \"2012-04-21\"\nwebsite: \"https://web.archive.org/web/20140104165523/http://abrilproruby.com/2012\"\ntwitter: \"abrilproruby\"\ncoordinates:\n  latitude: -8.0578381\n  longitude: -34.8828969\n"
  },
  {
    "path": "data/tropicalrb/abril-pro-ruby-2012/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://web.archive.org/web/20140104165523/http://abrilproruby.com/2012\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/tropicalrb/abril-pro-ruby-2013/event.yml",
    "content": "---\nid: \"abril-pro-ruby-2013\"\ntitle: \"Abril Pro Ruby 2013\"\ndescription: \"\"\nlocation: \"Recife, Brazil\"\nkind: \"conference\"\nstart_date: \"2013-04-27\"\nend_date: \"2013-04-27\"\nwebsite: \"https://web.archive.org/web/20140104165537/http://abrilproruby.com/2013\"\ntwitter: \"abrilproruby\"\ncoordinates:\n  latitude: -8.0578381\n  longitude: -34.8828969\n"
  },
  {
    "path": "data/tropicalrb/abril-pro-ruby-2013/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: https://web.archive.org/web/20140104165537/http://abrilproruby.com/2013\n# Videos: -\n---\n[]\n"
  },
  {
    "path": "data/tropicalrb/abril-pro-ruby-2014/event.yml",
    "content": "---\nid: \"PL7a-mWnTar6v5cDC4MLDZKwD0RuMSDHHP\"\ntitle: \"Abril Pro Ruby 2014\"\ndescription: \"\"\nlocation: \"Porto de Galinhas, Brazil\"\nkind: \"conference\"\nstart_date: \"2014-04-24\"\nend_date: \"2014-04-27\"\nwebsite: \"https://web.archive.org/web/20140416142613/http://abrilproruby.com/en\"\ntwitter: \"abrilproruby\"\nplaylist: \"https://www.youtube.com/playlist?list=PL7a-mWnTar6v5cDC4MLDZKwD0RuMSDHHP\"\ncoordinates:\n  latitude: -8.5066276\n  longitude: -35.0057167\n"
  },
  {
    "path": "data/tropicalrb/abril-pro-ruby-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://tropicalrb.com/2014/en/\n# Videos: https://www.youtube.com/playlist?list=PL7a-mWnTar6v5cDC4MLDZKwD0RuMSDHHP\n---\n[]\n"
  },
  {
    "path": "data/tropicalrb/series.yml",
    "content": "# See: https://github.com/rubyevents/rubyevents/issues/1501\n# 2012-2014: Abril Pro Ruby (original website: \"http://abrilproruby.com/\")\n# 2015, 2024: Tropical.rb \n# 2025-: Tropical on Rails\n---\nname: \"Tropical on Rails\"\nwebsite: \"https://www.tropicalonrails.com\"\ntwitter: \"tropicalonrails\"\nkind: \"conference\"\nfrequency: \"yearly\"\ndefault_country_code: \"BR\"\nyoutube_channel_name: \"tropicalonrails\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCC3ljLfioI4qN2_zmG_kseQ\"\naliases:\n  - Abril Pro Ruby\n  - Tropical Ruby\n  - Tropical.rb\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2025/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/tropicalonrails\"\n  open_date: \"2024-11-26\"\n  close_date: \"2025-01-14\"\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2025/event.yml",
    "content": "---\nid: \"PLvOWTr3oa1dX-vzEjajdg-0mftpPD7xBk\"\ntitle: \"Tropical on Rails 2025\"\nkind: \"conference\"\nlocation: \"São Paulo, Brazil\"\ndescription: |-\n  Nearly twice as big, Tropical on Rails is back! Seasoned programmers, entrepreneurs, and students from all over Latin America and other countries, gathering for two days of top-notch content, international speakers, and networking!\npublished_at: \"2025-05-13\"\nstart_date: \"2025-04-03\"\nend_date: \"2025-04-04\"\nyear: 2025\nbanner_background: \"#2C1749\"\nfeatured_background: \"#2C1749\"\nfeatured_color: \"#0CDBB3\"\nwebsite: \"https://www.tropicalonrails.com/en/archive-2025\"\ncoordinates:\n  latitude: -23.595833177578946\n  longitude: -46.68451089446699\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Cirdes Henrique\n    - Rafael Mendonça França\n\n  organisations: []\n\n- name: \"Executive Production\"\n  users:\n    - Alexander Sette\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2025/schedule.yml",
    "content": "# Schedule: Tropical on Rails 2025\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2025-04-03\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Registration + Welcome Coffee ☕️\n\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening\n\n      - start_time: \"10:00\"\n        end_time: \"10:50\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:10\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch 🍛\n\n      - start_time: \"14:00\"\n        end_time: \"14:50\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n\n      - start_time: \"15:40\"\n        end_time: \"16:10\"\n        slots: 1\n\n      - start_time: \"16:10\"\n        end_time: \"16:50\"\n        slots: 1\n        items:\n          - Coffee Break ☕️\n\n      - start_time: \"16:50\"\n        end_time: \"17:20\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:10\"\n        end_time: \"19:00\"\n        slots: 1\n\n      - start_time: \"19:00\"\n        end_time: \"19:15\"\n        slots: 1\n        items:\n          - Closing\n\n  - name: \"Day 2\"\n    date: \"2025-04-04\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Networking + Welcome Coffee ☕️\n\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening\n\n      - start_time: \"10:00\"\n        end_time: \"10:50\"\n        slots: 1\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:40\"\n        end_time: \"12:10\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch 🍛\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"15:20\"\n        end_time: \"15:50\"\n        slots: 1\n\n      - start_time: \"15:50\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Coffee Break ☕️\n\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:10\"\n        end_time: \"19:00\"\n        slots: 1\n\n      - start_time: \"19:00\"\n        end_time: \"19:15\"\n        slots: 1\n        items:\n          - Closing\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Platinum\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com/br\"\n          slug: \"Shopify\"\n          logo_url: \"https://framerusercontent.com/images/Tg2p0q94jWn4vO2GcDUySMfd1tw.png\"\n\n        - name: \"Linkana\"\n          website: \"https://www.linkana.com/\"\n          slug: \"Linkana\"\n          logo_url: \"https://framerusercontent.com/images/kVdFurnVDGuHBvNV37RwvD6p3M.png\"\n\n    - name: \"Gold\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"Smartfit\"\n          website: \"https://www.smartfit.com.br/?utm_source=tropicalrb\"\n          slug: \"Smartfit\"\n          logo_url: \"https://framerusercontent.com/images/gJAqdY218KkjQ7Xu5mkA7Xq9iww.png\"\n\n        - name: \"Jetrockets\"\n          website: \"https://jetrockets.com/\"\n          slug: \"Jetrockets\"\n          logo_url: \"https://framerusercontent.com/images/sCmV0LsX5wIVyV00ArfYjxqx0Tg.svg\"\n\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/?utm_source=tropicalrb\"\n          slug: \"Appsignal\"\n          logo_url: \"https://framerusercontent.com/images/Ej8aWi209QFR5YrNB6Rl1aN8RqY.png\"\n\n        - name: \"Braze Careers\"\n          website:\n            \"https://www.braze.com/company/careers?gh_src=302f6f1a1us&utm_campaign=fy26-q1-latam-paid-partner-tropical-on-rails&utm_medium=event&utm_source=tropicalonrails&utm_conten\\\n            t=lp-website-logo&utm_term=website\"\n          slug: \"BrazeCareers\"\n          logo_url: \"https://framerusercontent.com/images/fVIWxIr5M93JRkyR5J46hNgnYY.png\"\n\n    - name: \"Silver\"\n      description: \"\"\n      level: 3\n      sponsors:\n        - name: \"Monde\"\n          website: \"https://monde.com.br/?utm_source=tropical&utm_medium=site&utm_campaign=tropical_onrails\"\n          slug: \"Monde\"\n          logo_url: \"https://framerusercontent.com/images/zdgdH66tdhoTErmjnMRb1wgNYc.png\"\n\n        - name: \"Codeminer42\"\n          website: \"https://www.codeminer42.com/?utm_source=tropical2025&utm_medium=website&utm_campaign=sponsor\"\n          slug: \"Codeminer42\"\n          logo_url: \"https://framerusercontent.com/images/ShTv6XGiSZybyQqAD649NjxU.png\"\n\n        - name: \"Publitas\"\n          website: \"https://www.publitas.com/jobs/\"\n          slug: \"Publitas\"\n          logo_url: \"https://framerusercontent.com/images/eDEs6OWdXJSU4sAtF6yaeHwoYA.svg\"\n\n        - name: \"Knowbe4 Careers\"\n          website: \"https://www.knowbe4.com/careers/locations/sao-paulo\"\n          slug: \"Knowbe4Careers\"\n          logo_url: \"https://framerusercontent.com/images/woQBKZz4XEfca3n19hDCylcT1lA.png\"\n\n        - name: \"Basecamp\"\n          website: \"https://basecamp.com/?utm_source=tropical\"\n          slug: \"Basecamp\"\n          logo_url: \"https://framerusercontent.com/images/r9JOAZ2kQzSd3LFmevBgRTzi2E.png\"\n\n        - name: \"v360\"\n          website: \"https://www.v360.io/\"\n          slug: \"v360\"\n          logo_url: \"https://framerusercontent.com/images/d3hn4fw3keeditsubxfe0uHcY.png\"\n\n        - name: \"Doximity\"\n          website: \"https://technology.doximity.com/\"\n          slug: \"Doximity\"\n          logo_url: \"https://framerusercontent.com/images/VsRrzLNrpm25vRcHSve1NF08Ds.png\"\n\n        - name: \"Agendor\"\n          website: \"https://www.agendor.com.br/\"\n          slug: \"Agendor\"\n          logo_url: \"https://framerusercontent.com/images/7vmBUnUJDRVM4OOXbS2ssRk3Tg.png\"\n\n        - name: \"Planet Argon\"\n          website: \"https://www.planetargon.com/\"\n          slug: \"PlanetArgon\"\n          logo_url: \"https://framerusercontent.com/images/FBbJtgRltWLdko4LfPHjkOFDY.png\"\n\n        - name: \"Incognia\"\n          website: \"https://www.incognia.com/pt/\"\n          slug: \"Incognia\"\n          logo_url: \"https://framerusercontent.com/images/mVIp5VCaifm5kjZRouky1l5f0s.png\"\n\n        - name: \"RDM Apps\"\n          website: \"https://www.rdmapps.com.br/\"\n          slug: \"RDMApps\"\n          logo_url: \"https://framerusercontent.com/images/uHDnE3TyrYWJyI5IiwyeM5J5BWo.png\"\n\n        - name: \"Irya Solutions\"\n          website: \"https://www.iryasolutions.com.br/\"\n          slug: \"IryaSolutions\"\n          logo_url: \"https://framerusercontent.com/images/30fmspAYqRFq09b8RghpQHi75A.png\"\n\n    - name: \"Happy Hour\"\n      description: \"\"\n      level: 4\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com/br\"\n          slug: \"Shopify\"\n          logo_url: \"https://framerusercontent.com/images/Tg2p0q94jWn4vO2GcDUySMfd1tw.png\"\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2025/venue.yml",
    "content": "---\nname: \"Pullman Auditorium\"\naddress:\n  street: \"R. Olimpíadas, 205 - Vila Olímpia\"\n  city: \"São Paulo\"\n  region: \"SP\"\n  postal_code: \"04551-000\"\n  country: \"Brazil\"\n  country_code: \"BR\"\n  display: \"R. Olimpíadas, 205 - Vila Olímpia, São Paulo - SP, 04551-000\"\ncoordinates:\n  latitude: -23.595833177578946\n  longitude: -46.68451089446699\nmaps:\n  google: \"https://maps.app.goo.gl/gmmMbBhojRo73Wjh8\"\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2025/videos.yml",
    "content": "---\n- title: \"Keynote: Startup on Rails 2025\"\n  raw_title: \"Keynote - Startup on Rails\"\n  speakers:\n    - Irina Nazarova\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-03\"\n  published_at: \"2025-04-25\"\n  announced_at: \"2024-10-23 18:00:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"_eLfPFxztjs\"\n  id: \"irina-nazarova-tropical-on-rails-2025\"\n  language: \"english\"\n  slides_url: \"https://speakerdeck.com/irinanazarova/startups-on-rails-2025-at-tropical-on-rails\"\n  description: |-\n    Carrying the incredible mission of supporting startups by building the missing tools and sharing her team's expertise on how to iterate and scale successfully.\n\n    Recently relocated to San Francisco, she's breathing new life into the tech scene by relaunching the SF Bay Area Ruby meetup—now a monthly gathering spot for over 100 developers.\n\n    CEO of Evil Martians and co-founder of AnyCable, is one of the brilliant minds joining us at Tropical On Rails 2025 to share her expertise, innovative techniques, and insights from her experiences.\n\n- title: \"Scaling Rails: The Journey to 200M Notifications\"\n  raw_title: \"Scaling Rails: The Journey to 200M Notifications\"\n  speakers:\n    - Gustavo Araújo\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-03\"\n  published_at: \"2025-05-06\"\n  announced_at: \"2025-01-29 17:23:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"O7fzUfAjZQA\"\n  id: \"gustavo-araujo-tropical-on-rails-2025\"\n  language: \"portuguese\"\n  slides_url: \"https://www.slideshare.net/slideshow/scalling-rails-the-journey-to-200m-notifications/277497024\"\n  description: |-\n    Senior Software Engineer at CloudWalk and passionate about building scalable and efficient software solutions. He has over a decade of experience in developing high-performance systems and currently contributes to the creation of InfinitePay, one of the leading payment solutions in Brazil.\n\n    In the talk \"Scaling Rails: The Journey to 200M Notifications\", he will share his experience in scaling a Ruby on Rails application to send millions of notifications, addressing challenges, trade-offs, and technical decisions to transform an MVP into a robust and scalable system.\n\n- title: \"Scaling RubyVideo.dev: The mission to index all Ruby conferences\"\n  raw_title: \"Scaling RubyVideo.dev: The mission to index all Ruby conferences\"\n  speakers:\n    - Marco Roth\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-03\"\n  published_at: \"2025-05-06\"\n  announced_at: \"2025-02-05 17:47:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"cmsSA41eWxs\"\n  id: \"marco-roth-tropical-on-rails-2025\"\n  language: \"english\"\n  slides_url: \"https://speakerdeck.com/marcoroth/scaling-rubyvideo-dot-dev-the-mission-to-index-all-ruby-conferences\"\n  description: |-\n    Marco is a full-stack Ruby on Rails developer and actively contributes to open-source. Focused on improving the developer experience, he collaborates on projects like Hotwire and StimulusReflex.\n\n    In his talk \"Scaling RubyVideo.dev: The mission to index all Ruby conferences\", Marco will share how he is building a comprehensive repository of Ruby talks. He will address technical challenges, strategies, and bring exclusive announcements!\n\n- title: \"Keynote: Strategic Standardization: Driving Innovation\"\n  raw_title: \"Keynote - Padronização estratégica: direcionando inovação\"\n  speakers:\n    - Vinicius Stock\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-03\"\n  published_at: \"2025-04-30\"\n  announced_at: \"2024-10-22 15:00:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"Syfa0wSzqdE\"\n  id: \"vinicius-stock-tropical-on-rails-2025\"\n  language: \"portuguese\"\n  description: |-\n    Software developer with a passion for tooling and developer experience. He started his career building products using Ruby on Rails, React, and TypeScript, and gradually transitioned into the developer tooling space.\n\n    In addition to coding, he's also a blog writer, conference speaker, and now he's joining us at Tropical On Rails 2025...\n\n    Vinicius Stock is another confirmed speaker for our event! Currently, Vini is the tech lead for the Ruby developer experience team at Shopify, the main author of the Ruby LSP, and a contributor to various other open-source technologies.\n\n- title: \"Hotwire meets The Platform™: a new way to build PWAs relying on native HTML APIs\"\n  raw_title: \"Hotwire meets The Platform™: a new way to build PWAs relying on native HTML APIs\"\n  speakers:\n    - Edigleysson Silva\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-03\"\n  published_at: \"2025-05-06\"\n  announced_at: \"2025-01-29 17:23:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"iG9ZOc103hk\"\n  id: \"edigleysson-silva-tropical-on-rails-2025\"\n  language: \"english\"\n  slides_url: \"https://docs.google.com/presentation/d/1Wk6f0VJ3G_GBXghl9AUskJQy2XAY9i63UyqOZxhHdgA/view\"\n  description: |-\n    Developer at CodeMiner42, has 10 years of experience creating software and sharing knowledge, is passionate about technology and also writes articles about Computer Science and Philosophy.\n\n    In the talk \"Hotwire meets The Platform™\",  he will show how to combine Rails + native APIs to create robust and offline-capable PWAs in an innovative and simple way.\n\n    Outside of coding, he enjoys the classics of Mark Twain and moments with his wife and daughter.\n\n- title: \"The Great Mobile Hack: Hotwire Native\"\n  raw_title: \"The Great Mobile Hack: Hotwire Native\"\n  speakers:\n    - Daniel Medina\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-03\"\n  published_at: \"2025-05-06\"\n  announced_at: \"2025-02-04 14:51:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"gVh3qzq3MAw\"\n  id: \"daniel-medina-tropical-on-rails-2025\"\n  language: \"english\"\n  description: |-\n    Software Engineer, graduated from the University of Yucatán (UADY), I have been working with Ruby on Rails for over 6 years, currently working as a Full-Stack developer at Telos Labs, being the Tech Lead of the non-profit application SaverLife.org.\n\n    In the talk \"The Great Mobile Hack: Hotwire Native\" we will explore how we migrated our web application from the conference that will be used at the Tropical on Rails 2025 event to a native mobile experience using Hotwire Native, maintaining the agility of Rails while delivering the smooth experience that users expect from a native application.\n\n- title: \"From React to Hotwire, the right path\"\n  raw_title: \"From React to Hotwire, the right path\"\n  speakers:\n    - Jackson Pires\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-03\"\n  published_at: \"2025-05-06\"\n  announced_at: \"2025-01-27 15:43:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"4dXtI4QyT6Y\"\n  id: \"jackson-pires-tropical-on-rails-2025\"\n  language: \"portuguese\"\n  description: |-\n    Jackson met Ruby on Rails in 2007 while developing his college thesis, and since then he has spread knowledge through his courses. In his free time, he enjoys playing with his son and having fun with his family.\n\n- title: \"Defying Front-End Inertia: Inertia.js on Rails\"\n  raw_title: \"Defying Front-End Inertia: Inertia.js on Rails\"\n  speakers:\n    - Svyatoslav Kryukov\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-03\"\n  published_at: \"2025-05-06\"\n  announced_at: \"2025-02-04 14:56:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"uLFItMoF_wA\"\n  id: \"svyatoslav-kryukov-tropical-on-rails-2025\"\n  slides_url: \"https://speakerdeck.com/skryukov/defying-front-end-inertia-inertia-dot-js-on-rails\"\n  language: \"english\"\n  description: |-\n    Dedicated to bridging the gap between backend and frontend worlds. Creator of tools like Skooma to define strong interfaces and TurboMount to enhance Hotwire with modern frontend widgets. A passionate contributor to Inertia Rails, making it easier for the Rails community to embrace modern frontend development.\n\n    In the talk \"Challenging Front-End Inertia: Inertia.js in Rails\" he will share with us how to unlock the power of modern frontend frameworks in Rails with Inertia.js! Building dynamic, single-page applications while maintaining the simplicity of Rails - without APIs, without client-side boilerplate.\n\n- title: \"Keynote: The Ruby in Zeitwerk\"\n  raw_title: \"Keynote - The Ruby in Zeitwerk\"\n  speakers:\n    - Xavier Noria\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-03\"\n  published_at: \"2025-04-29\"\n  announced_at: \"2024-10-24 18:50:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"94cEvPuy3no\"\n  id: \"xavier-noria-tropical-on-rails-2025\"\n  language: \"english\"\n  description: |-\n    Everlasting student · Rails Core · Zeitwerk · Freelance · Life lover\n\n## Day 2 - 2025-04-04\n\n- title: \"Keynote: Hotwire Demystified\"\n  raw_title: \"Keynote - Hotwire Demystified\"\n  speakers:\n    - Chris Oliver\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-04\"\n  published_at: \"2025-05-07\"\n  announced_at: \"2024-10-11 15:30:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"9LekwjCer3M\"\n  id: \"chris-oliver-tropical-on-rails-2025\"\n  slides_url: \"https://a.cl.ly/jkuBq5L9\"\n  language: \"english\"\n  description: |-\n    He's a Rails expert, creator of Jumpstart Pro (a starter kit for Rails) and http://Hatchbox.io (Rails hosting). He also hosts the Remote Ruby Podcast and shares weekly Ruby on Rails screencasts at http://GoRails.com.\n\n- title: \"Don't Rewrite Your Framework\"\n  raw_title: \"Don't Rewrite Your Framework\"\n  speakers:\n    - Vinícius Alonso\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-04\"\n  published_at: \"2025-05-13\"\n  announced_at: \"2025-02-05 17:39:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"QxoxgpQyZwQ\"\n  id: \"vinicius-alonso-tropical-on-rails-2025\"\n  language: \"portuguese\"\n  slides_url: \"https://speakerdeck.com/viniciusalonso/dont-rewrite-your-framework\"\n  description: |-\n    With more than 10 years of experience in development, he holds a master's degree in Applied Computing from UTFPR-CT and has spoken at events such as TDC, Laraconf, and FTSL.\n\n    In the talk \"Don't Rewrite Your Framework\", Vinícius will explore little-known features of Ruby on Rails that can prevent unnecessary rework. Based on studies of the documentation and discussions in communities, he brings valuable insights for those who want to write more efficient code.\n\n- title: \"Full Circle: How Modern Ruby Powers the Re-integration of High-Speed Microservices into Rails\"\n  raw_title: \"Full Circle: How Modern Ruby Powers the Re-integration of High-Speed Microservices into Rails\"\n  speakers:\n    - Cristian Planas\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-04\"\n  time: \"11:40h - 12:10h\"\n  published_at: \"2025-05-13\"\n  video_provider: \"youtube\"\n  video_id: \"0cI8OTDVfEs\"\n  id: \"cristian-planas-tropical-on-rails-2025\"\n  language: \"english\"\n  description: |-\n    Software engineer who has been primarily working with Ruby for over 15 years.\n    Founder of a startup as a solo engineer in 2012, later he joined the Zendesk headquarters in San Francisco, one of the leading companies using Ruby in the world. Performance optimization has been his obsession since the founding of his first startup. He currently holds the position of Group Tech Lead and Senior Staff Engineer.\n\n    In his talk, \"How Modern Ruby Powers High-Speed Microservices Reintegration in Rails\", he will guide us through the fascinating journey of the Zendesk Indexer—which was extracted from a Rails monolith to become a high-speed microservice and is now returning. Discover how Kubernetes and event-driven architecture are rewriting the rules of scalability, proving that sometimes the future is in the past.\n\n- title: \"Apache Pinot: A Tale of an Active Record Adapter\"\n  raw_title: \"Apache Pinot: A Tale of an Active Record Adapter\"\n  speakers:\n    - Celso Fernandes\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-04\"\n  published_at: \"2025-05-13\"\n  announced_at: \"2025-02-05 17:41:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"wt1j6I3Kt34\"\n  id: \"celso-fernandes-tropical-on-rails-2025\"\n  slides_url: \"https://drive.google.com/file/d/1-ly_ksIFu9wI3MfZpc8UYw7Qs2eS7048/view\"\n  language: \"english\"\n  description: |-\n    Celso has a journey that started as a sysadmin in 2005 and, since 2010, has dedicated himself to web development with Rails, dealing with large-scale operations.\n\n    In the talk \"Apache Pinot: An Active Record Adapter Tale\", he will share the challenge of writing an Active Record Adapter running in production and encourage the community to explore the core of Rails.\n\n- title: \"Kamal 2 - Get out of the cloud\"\n  raw_title: \"Kamal 2 - Get Out of Cloud\"\n  speakers:\n    - Igor Aleksandrov\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-04\"\n  published_at: \"2025-05-13\"\n  announced_at: \"2025-01-27 15:47:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"raUfWvlZLRQ\"\n  id: \"igor-alexandrov-tropical-on-rails-2025\"\n  language: \"english\"\n  slides_url: \"https://speakerdeck.com/aleksandrov/kamal-2-get-out-of-the-cloud\"\n  description: |-\n    Igor is an experienced Ruby engineer, a Docker Captain, a Chief Technology Officer, and the co-founder of JetRockets. He is a father of two children and enjoys diving when he can.\n\n- title: \"Ruby Internals: A Guide for Rails Developers\"\n  raw_title: \"Ruby Internals: A Guide for Rails Developers\"\n  speakers:\n    - Matheus Richard\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-04\"\n  published_at: \"2025-05-13\"\n  announced_at: \"2025-01-29 17:23:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"nFoOmIpMcm0\"\n  id: \"matheus-richard-tropical-on-rails-2025\"\n  language: \"english\"\n  slides_url: \"https://docs.google.com/presentation/d/1IdNgAU7z9umDeyx6xG8fv7wqauG3_QkfhpCM1sVXelw/view\"\n  description: |-\n    Senior Developer at thoughtbot and a member of the Rails issues team. With nearly 10 years of experience, Ruby has always been his favorite language. Besides coding, Matheus is passionate about music, games, and building interpreters.\n\n    In the talk \"Ruby Internals: A Guide for Rails Developers\", he will explore how Ruby interprets and executes code. A journey behind the scenes of the language and its impacts on Rails!\n\n- title: \"Resilient Jobs and Chaotic Tests\"\n  raw_title: \"Resilient Jobs and Chaotic Tests\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-04\"\n  published_at: \"2025-05-13\"\n  announced_at: \"2025-02-04 14:38:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"NGeyotdnJS4\"\n  id: \"stephen-margheim-tropical-on-rails-2025\"\n  language: \"english\"\n  description: |-\n    Stephen is an American expatriate living in Berlin. He is a regular contributor to Rails and the sqlite3-ruby gem, as well as having a handful of gems aimed at making Ruby and Rails the best platforms in the world for running SQLite projects.\n\n    In the talk \"Resilient Jobs and Chaotic Tests,\" he will share his experiences with various scenarios, mainly the most chaotic ones, and explore possibilities that help companies and development teams make work more reliable and resilient.\n\n- title: \"AI has already changed software development\"\n  raw_title: \"AI has already changed software development\"\n  speakers:\n    - Radamés Roriz\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-04\"\n  published_at: \"2025-05-13\"\n  announced_at: \"2025-01-27 15:41:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"CSnAOo9Y1Gs\"\n  id: \"radames-roriz-tropical-on-rails-2025\"\n  language: \"portuguese\"\n  description: |-\n    Senior Engineer @ Knowbe4 • Passionate about solving real problems and creating products that positively impact people's lives.\n\n- title: \"Keynote: The curious incident of the incomplete executor\"\n  raw_title: \"Keynote - The curious incident of the incomplete executor\"\n  speakers:\n    - Rosa Gutiérrez\n  event_name: \"Tropical on Rails 2025\"\n  date: \"2025-04-04\"\n  published_at: \"2025-05-08\"\n  announced_at: \"2024-10-16 15:59:00 UTC\"\n  video_provider: \"youtube\"\n  video_id: \"1y1N9Fa7VDA\"\n  id: \"rosa-gutierrez-tropical-on-rails-2025\"\n  language: \"english\"\n  slides_url: \"https://rosa.codes/executor2025/presentation/\"\n  description: |-\n    She's a lover of languages and math, Lead Programmer at the 37signals team, and she's coming to the Tropical On Rails 2025 stage to share a lot of knowledge with us.\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://cfp.tropicalonrails.com\"\n  open_date: \"2025-12-04\"\n  close_date: \"2026-01-14\"\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2026/event.yml",
    "content": "---\nid: \"tropical-on-rails-2026\"\ntitle: \"Tropical on Rails 2026\"\ndescription: \"\"\nlocation: \"São Paulo, Brazil\"\nkind: \"conference\"\nstart_date: \"2026-04-09\"\nend_date: \"2026-04-10\"\nwebsite: \"https://www.tropicalonrails.com/en\"\ntickets_url: \"https://www.sympla.com.br/evento/tropical-on-rails-2026-the-brazilian-rails-conference/3181423\"\ntwitter: \"tropicalonrails\"\nmastodon: \"https://ruby.social/@tropicalonrails\"\nbanner_background: \"#2E1A40\"\nfeatured_background: \"#2E1A40\"\nfeatured_color: \"#0CDBB3\"\ncoordinates:\n  latitude: -23.595833177578946\n  longitude: -46.68451089446699\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2026/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Cirdes Henrique\n    - Rafael Mendonça França\n\n  organisations:\n    - Linkana\n\n- name: \"Executive Production\"\n  users:\n    - Alexander Sette\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2026/schedule.yml",
    "content": "# docs/ADDING_SCHEDULES.md\n---\ndays:\n  - name: \"Workshops\"\n    date: \"2026-04-08\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"12:00\"\n        slots: 1\n      - start_time: \"14:00\"\n        end_time: \"18:00\"\n        slots: 1\n  - name: \"First day\"\n    date: \"2026-04-09\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Registration + Welcome Coffee ☕️\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening\n      - start_time: \"10:00\"\n        end_time: \"10:50\"\n        slots: 1\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n      - start_time: \"11:40\"\n        end_time: \"12:10\"\n        slots: 1\n      - start_time: \"12:10\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch 🍛\n      - start_time: \"14:00\"\n        end_time: \"14:50\"\n        slots: 1\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n      - start_time: \"15:40\"\n        end_time: \"16:10\"\n        slots: 1\n      - start_time: \"16:10\"\n        end_time: \"16:50\"\n        slots: 1\n        items:\n          - Coffee Break ☕️\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n      - start_time: \"17:10\"\n        end_time: \"17:40\"\n        slots: 1\n      - start_time: \"18:10\"\n        end_time: \"19:00\"\n        slots: 1\n      - start_time: \"19:00\"\n        end_time: \"19:15\"\n        slots: 1\n        items:\n          - Closing\n  - name: \"Second day\"\n    date: \"2026-04-10\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Networking + Welcome Coffee ☕️\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening\n      - start_time: \"10:00\"\n        end_time: \"10:50\"\n        slots: 1\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n      - start_time: \"11:40\"\n        end_time: \"12:10\"\n        slots: 1\n      - start_time: \"12:10\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch 🍛\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 1\n      - start_time: \"15:20\"\n        end_time: \"15:50\"\n        slots: 1\n      - start_time: \"15:50\"\n        end_time: \"16:30\"\n        slots: 1\n        items:\n          - Coffee Break ☕️\n      - start_time: \"16:30\"\n        end_time: \"17:00\"\n        slots: 1\n      - start_time: \"17:10\"\n        end_time: \"17:40\"\n        slots: 1\n      - start_time: \"17:50\"\n        end_time: \"18:40\"\n        slots: 1\n      - start_time: \"18:40\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - Closing\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2026/sponsors.yml",
    "content": "# docs/ADDING_SPONSORS.md\n---\n- tiers:\n    - name: \"Platinum\"\n      level: 1\n      sponsors:\n        - name: \"typesense\"\n          website: \"https://typesense.org/\"\n          slug: \"typesense\"\n        - name: \"braze\"\n          website:\n            \"https://www.braze.com/company/careers?gh_src=302f6f1a1us&utm_campaign=fy26-q1-latam-paid-partner-tropical-on-rails&utm_medium=event&utm_source=tropicalonrails&utm_conten\\\n            t=lp-website-logo&utm_term=website\"\n          slug: \"braze\"\n          logo_url: \"https://framerusercontent.com/images/fVIWxIr5M93JRkyR5J46hNgnYY.png?width=738&height=347\"\n        - name: \"jaya\"\n          website: \"https://jaya.tech/\"\n          slug: \"jaya\"\n          logo_url: \"https://framerusercontent.com/images/tDzGJP8PWswfeWahuFQDaCnvY.png?scale-down-to=1024&width=3195&height=1307\"\n        - name: \"Shopify\"\n          website: \"https://www.shopify.com/\"\n          slug: \"shopify\"\n    - name: \"Gold\"\n      level: 2\n      sponsors:\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/\"\n          slug: \"appsignal\"\n        - name: \"Publitas\"\n          website: \"https://www.publitas.com/\"\n          slug: \"publitas\"\n          logo_url: \"https://framerusercontent.com/images/eDEs6OWdXJSU4sAtF6yaeHwoYA.svg?width=259&height=84\"\n        - name: \"JetRockets\"\n          website: \"https://jetrockets.com/\"\n          slug: \"jetrockets\"\n        - name: \"Adaflow\"\n          website: \"https://www.adaflow.com/\"\n          slug: \"adaflow\"\n        - name: \"smartfit\"\n          website: \"https://gruposmartfit.99jobs.com/\"\n          slug: \"smartfit\"\n    - name: \"Silver\"\n      level: 3\n      sponsors:\n        - name: \"monde\"\n          website: \"https://monde.com.br/?utm_source=tropical&utm_medium=site&utm_campaign=tropical_onrails\"\n          slug: \"monde\"\n        - name: \"doximity\"\n          website: \"https://technology.doximity.com/\"\n          slug: \"doximity\"\n        - name: \"iryasolutions\"\n          website: \"https://www.iryasolutions.com.br/\"\n          slug: \"iryasolutions\"\n          logo_url: \"https://framerusercontent.com/images/30fmspAYqRFq09b8RghpQHi75A.png?width=1080&height=390\"\n        - name: \"cedarcode\"\n          website: \"https://www.cedarcode.com/\"\n          slug: \"cedarcode\"\n        - name: \"KnowBe4\"\n          website: \"https://www.knowbe4.com/careers/locations/sao-paulo\"\n          slug: \"knowbe4\"\n          logo_url: \"https://framerusercontent.com/images/woQBKZz4XEfca3n19hDCylcT1lA.png?width=1947&height=357\"\n        - name: \"PlanetArgon\"\n          website: \"https://www.planetargon.com/\"\n          slug: \"planetargon\"\n        - name: \"v360\"\n          website: \"https://www.v360.io/\"\n          slug: \"v360\"\n        - name: \"Saeloun\"\n          website: \"https://www.saeloun.com/\"\n          slug: \"saeloun\"\n        - name: \"capim\"\n          website: \"https://capim.com.br/\"\n          slug: \"capim\"\n        - name: \"Husky\"\n          website: \"https://www.husky.io/\"\n          slug: \"husky\"\n        - name: \"techfx\"\n          website: \"https://www.techfx.com.br/\"\n          slug: \"techfx\"\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2026/venue.yml",
    "content": "---\nname: \"Pullman Auditorium\"\naddress:\n  street: \"R. Olimpíadas, 205 - Vila Olímpia\"\n  city: \"São Paulo\"\n  region: \"SP\"\n  postal_code: \"04551-000\"\n  country: \"Brazil\"\n  country_code: \"BR\"\n  display: \"R. Olimpíadas, 205 - Vila Olímpia, São Paulo - SP, 04551-000\"\ncoordinates:\n  latitude: -23.595833177578946\n  longitude: -46.68451089446699\nmaps:\n  google: \"https://maps.app.goo.gl/gmmMbBhojRo73Wjh8\"\n"
  },
  {
    "path": "data/tropicalrb/tropical-on-rails-2026/videos.yml",
    "content": "# TODO: Add videos\n# Website: https://www.tropicalonrails.com/\n---\n- id: \"rodrigo-serradura-workshop-tropical-on-rails-2026\"\n  title: \"Modularizing Rails Applications in Practice\"\n  description: \"\"\n  kind: \"workshop\"\n  language: \"pt\"\n  date: \"2026-08-04\"\n  announced_at: \"2026-02-26\"\n  speakers:\n    - Rodrigo Serradura\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFYqAC5a8AodZDb?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFYqAC5a8AodZDb?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFYqAC5a8AodZDb?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFYqAC5a8AodZDb?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFYqAC5a8AodZDb?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"rodrigo-serradura-workshop-tropical-on-rails-2026\"\n\n- id: \"inertia-rails-from-rails-new-to-production-workshop-tropical-on-rails-2026\"\n  title: \"Inertia Rails: from rails new to production\"\n  description: \"\"\n  kind: \"workshop\"\n  language: \"en\"\n  date: \"2026-08-04\"\n  announced_at: \"2026-02-26\"\n  speakers:\n    - Svyatoslav Kryukov\n    - Brian Knoles\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFZucVqa8AEToIO?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFZucVqa8AEToIO?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFZucVqa8AEToIO?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFZucVqa8AEToIO?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFZucVqa8AEToIO?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"inertia-rails-from-rails-new-to-production-workshop-tropical-on-rails-2026\"\n\n- id: \"marco-roth-tropical-on-rails-2026\"\n  title: \"Keynote: Your Views Deserve a Grammar\"\n  raw_title: \"Your Views Deserve a Grammar\"\n  speakers:\n    - Marco Roth\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-09\"\n  announced_at: \"2025-10-27 13:30 UTC\"\n  description: |-\n    Rails has always been the \"batteries included\" framework, but the view layer never got the same treatment. HTML+ERB has been loosely defined for 20 years. What happens when you give it a proper grammar? You get a parser, a toolchain, and eventually, reactivity.\n\n    From a parser written in C, to a linter with 60+ rules, a language server, a rendering engine, and browser dev tools, all powered by the same syntax tree. We'll trace the evolution from Turbolinks to Hotwire, show where the current approach hits a ceiling, and introduce Herb and ReActionView: a path to reactive, server-rendered Rails views without leaving ERB behind.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFeB2mEbQAAJcRt?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFeB2mEbQAAJcRt?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFeB2mEbQAAJcRt?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFeB2mEbQAAJcRt?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFeB2mEbQAAJcRt?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"marco-roth-tropical-on-rails-2026\"\n  slides_url: \"https://speakerdeck.com/marcoroth/your-views-deserve-a-grammar-at-tropical-on-rails-2026-sao-paulo-brazil\"\n\n- id: \"rachael-wright-munn-tropical-on-rails-2026\"\n  title: \"Unboxing Devcontainers and Docker for Rubyists\"\n  raw_title: \"Unboxing Devcontainers and Docker for Rubyists\"\n  language: \"en\"\n  speakers:\n    - Rachael Wright-Munn\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-09\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    Rachael has been streaming open-source contributions and programming games on Twitch since 2019. As an avid open-source contributor, she often uses docker and devcontainer setups to facilitate integration. Recently, she contributed devcontainer setups for RubyEvents and Lobsters.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFeMw2fagAAHbYm?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFeMw2fagAAHbYm?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFeMw2fagAAHbYm?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFeMw2fagAAHbYm?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFeMw2fagAAHbYm?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"rachael-wright-munn-tropical-on-rails-2026\"\n\n- id: \"miguel-marcondes-filho-tropical-on-rails-2026\"\n  title: \"What Works (and What Doesn't) with ActiveRecord::Tenanted and SQLite\"\n  raw_title: \"What Works (and What Doesn't) with ActiveRecord::Tenanted and SQLite\"\n  language: \"en\"\n  speakers:\n    - Miguel Marcondes Filho\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-09\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    I am Miguel, a Technology Leader and contributor to Node.js/Node-API and ActiveRecord::Tenanted with Fullstack experience in React, TypeScript, Node.js, Ruby, and C++. I am passionate about open source and actively contribute to the tools I use daily.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFeStvOaYAAdFFt?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFeStvOaYAAdFFt?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFeStvOaYAAdFFt?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFeStvOaYAAdFFt?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFeStvOaYAAdFFt?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"miguel-marcondes-filho-tropical-on-rails-2026\"\n\n- id: \"nicolas-erlichman-tropical-on-rails-2026\"\n  title: \"Modeling Class Hierarchies in Active Record\"\n  raw_title: \"Modeling Class Hierarchies in Active Record\"\n  language: \"en\"\n  speakers:\n    - Nicolas Erlichman\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-09\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    I am a computer engineer from Canelones, a small city in Uruguay. Besides developing software, I have a passion for teaching and currently work as a university professor. I also love to travel, especially to attend conferences.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFez5vRbQAApAKz?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFez5vRbQAApAKz?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFez5vRbQAApAKz?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFez5vRbQAApAKz?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFez5vRbQAApAKz?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"nicolas-erlichman-tropical-on-rails-2026\"\n\n- id: \"igor-aleksandrov-tropical-on-rails-2026\"\n  title: \"Overreacting – from React to Hotwire\"\n  raw_title: \"Overreacting – from React to Hotwire\"\n  language: \"en\"\n  speakers:\n    - Igor Aleksandrov\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-09\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    I am Igor Aleksandrov, CTO and co-founder of JetRockets, a Rails agency in NYC, and technical leader of SafariPortal. With over 20 years of experience in development and leadership, I believe in choosing simple technology that really works, and I have experienced the complexity of both sides to prove it.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFe48CSbwAAeE06?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFe48CSbwAAeE06?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFe48CSbwAAeE06?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFe48CSbwAAeE06?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFe48CSbwAAeE06?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"igor-aleksandrov-tropical-on-rails-2026\"\n\n- id: \"braulio-martinez-tropical-on-rails-2026\"\n  title: \"Passkey Authentication on Rails\"\n  raw_title: \"Passkey Authentication on Rails\"\n  language: \"en\"\n  speakers:\n    - Braulio Martinez\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-09\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    Ruby fan since 2010. Advocate of OSS. Co-author and maintainer of webauthn-ruby. Proud father of 2 children. Former BJJ practitioner.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFfDsnWbQAADXGb?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFfDsnWbQAADXGb?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFfDsnWbQAADXGb?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFfDsnWbQAADXGb?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFfDsnWbQAADXGb?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"braulio-martinez-tropical-on-rails-2026\"\n\n- id: \"luiz-carvalho-tropical-on-rails-2026\"\n  title: \"DefGPT: AI agent platform on Rails\"\n  raw_title: \"DefGPT: AI agent platform on Rails\"\n  language: \"pt\"\n  speakers:\n    - Luiz Carvalho\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-09\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    Senior developer with 17 years of experience in Ruby on Rails and 9 years in AI. With a vast background in startups and innovation, he combines deep technical expertise with an entrepreneurial vision, applying AI and automation to transform ideas into scalable solutions. Frequent speaker at events such as TEDx and Campus Party.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFfWeIrbQAMYHXP?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFfWeIrbQAMYHXP?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFfWeIrbQAMYHXP?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFfWeIrbQAMYHXP?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFfWeIrbQAMYHXP?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"luiz-carvalho-tropical-on-rails-2026\"\n\n- id: \"rodrigo-serradura-tropical-on-rails-2026\"\n  title: \"The Monolith Strikes Back: Why AI Agents Love Rails Monoliths\"\n  raw_title: \"The Monolith Strikes Back: Why AI Agents Love Rails Monoliths\"\n  language: \"en\"\n  speakers:\n    - Rodrigo Serradura\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-09\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    Rubyst | Enthusiast of Software Design and Architecture | Creator of Solid Process and Ada.rb\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFfc4J0bQAEnG1V?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFfc4J0bQAEnG1V?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFfc4J0bQAEnG1V?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFfc4J0bQAEnG1V?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFfc4J0bQAEnG1V?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"rodrigo-serradura-tropical-on-rails-2026\"\n\n- id: \"adrianna-chang-tropical-on-rails-2026\"\n  title: \"Keynote by Adrianna Chang\"\n  raw_title: \"Keynote by Adrianna Chang\"\n  speakers:\n    - Adrianna Chang\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-09\"\n  announced_at: \"2025-10-22 12:30 UTC\"\n  description: |-\n    Adrianna is a Staff Engineer at Shopify, a Rails Issues team member, and the meetup organizer for the WNB.rb community. She lives in Ottawa, Canada's capital, with her husband and Rottweiler, Jasper. Outside of work, she loves spending time outdoors and racing in triathlons.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFfjDXga4AA-Km_?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFfjDXga4AA-Km_?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFfjDXga4AA-Km_?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFfjDXga4AA-Km_?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFfjDXga4AA-Km_?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"adrianna-chang-tropical-on-rails-2026\"\n\n- id: \"fabio-akita-keynote-tropical-on-rails-2026\"\n  title: \"Keynote — Fabio Akita\"\n  description: |-\n    Olá pessoal, Fabio Akita, ou M.Akita, sou programador faz 30 anos, ex-Youtuber, ex-consultor, ainda pesquisador e agora vibe codando como se não houvesse amanhã. Escrevendo todas as experiências em akitaonrails.com e na nova newsletter themakitachronicles.com\n  kind: \"keynote\"\n  language: \"pt\"\n  date: \"2026-04-10\"\n  speakers:\n    - Fabio Akita\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFjLI0PakAUOXMY?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFjLI0PakAUOXMY?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFjLI0PakAUOXMY?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFjLI0PakAUOXMY?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFjLI0PakAUOXMY?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"fabio-akita-keynote-tropical-on-rails-2026\"\n\n- id: \"talysson-de-oliveira-cassiano-tropical-on-rails-2026\"\n  title: \"Privacy on Rails - pragmatically complying to data protection laws\"\n  raw_title: \"Privacy on Rails - pragmatically complying to data protection laws\"\n  language: \"en\"\n  speakers:\n    - Talysson de Oliveira Cassiano\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-10\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    After more than a decade in the software world, I have learned that most difficult problems are not about code, but rather about decisions, trade-offs, and how we learn as a team. I like to question assumptions and share ideas that help people build software more consciously and responsibly.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFjYpP2akAM4fyH?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFjYpP2akAM4fyH?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFjYpP2akAM4fyH?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFjYpP2akAM4fyH?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFjYpP2akAM4fyH?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"talysson-de-oliveira-cassiano-tropical-on-rails-2026\"\n\n- id: \"ignacio-chiazzo-cardarello-tropical-on-rails-2026\"\n  title: \"Reordering items at scale: From O(n) to O(1)\"\n  raw_title: \"Reordering items at scale: From O(n) to O(1)\"\n  language: \"en\"\n  speakers:\n    - Ignacio Chiazzo Cardarello\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-10\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    Ignacio Chiazzo Cardarello is a Staff Software Engineer at Shopify. He is passionate about building scalable systems and entrepreneurship. Outside of work, Ignacio enjoys running and playing soccer.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFjbZa0bsAAeShE?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFjbZa0bsAAeShE?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFjbZa0bsAAeShE?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFjbZa0bsAAeShE?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFjbZa0bsAAeShE?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"ignacio-chiazzo-cardarello-tropical-on-rails-2026\"\n\n- id: \"lightning-talks-tropical-on-rails-2026\"\n  title: \"Lightning Talks ⚡\"\n  raw_title: \"Lightning Talks\"\n  date: \"2026-04-10\"\n  description: |-\n    A series of short talks by various speakers covering a range of topics related to Ruby on Rails and software development.\n  video_provider: \"scheduled\"\n  video_id: \"lightning-talks-tropical-on-rails-2026\"\n  talks: []\n\n- id: \"matheus-richard-tropical-on-rails-2026\"\n  title: \"Production Data Doesn't Have to Be Scary\"\n  raw_title: \"Production Data Doesn't Have to Be Scary\"\n  language: \"en\"\n  speakers:\n    - Matheus Richard\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-10\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    I am Matheus Richard, a senior developer 🇧🇷 at thoughtbot! I love playing guitar, gaming, and building interpreters. From day one, Ruby \"made sense\" to me. Almost 10 years later, I still feel joy every time I use it.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFkKUA8akAAUme_?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFkKUA8akAAUme_?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFkKUA8akAAUme_?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFkKUA8akAAUme_?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFkKUA8akAAUme_?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"matheus-richard-tropical-on-rails-2026\"\n\n- id: \"rafael-pena-azar-tropical-on-rails-2026\"\n  title: \"Generators Are APIs: Designing Better DX in Rails\"\n  raw_title: \"Generators Are APIs: Designing Better DX in Rails\"\n  language: \"en\"\n  speakers:\n    - Rafael Peña-Azar\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-10\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    Senior software engineer with over a decade of experience building and scaling Rails-based systems for startups and international teams. Founder of Ruby Santa Marta. Actively engaged with the Ruby community.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFkaGfHb0AAhG9O?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFkaGfHb0AAhG9O?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFkaGfHb0AAhG9O?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFkaGfHb0AAhG9O?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFkaGfHb0AAhG9O?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"rafael-pena-azar-tropical-on-rails-2026\"\n\n- id: \"greg-molnar-tropical-on-rails-2026\"\n  title: \"Build Secure Rails Apps: Overcoming the OWASP Top 10\"\n  raw_title: \"Build Secure Rails Apps: Overcoming the OWASP Top 10\"\n  language: \"en\"\n  speakers:\n    - Greg Molnar\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-10\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    I am an OSCP certified pentester and Rails developer.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFke6YrakAIDvSR?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFke6YrakAIDvSR?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFke6YrakAIDvSR?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFke6YrakAIDvSR?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFke6YrakAIDvSR?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"greg-molnar-tropical-on-rails-2026\"\n\n- id: \"pawel-strzalkowski-tropical-on-rails-2026\"\n  title: \"MCP & OAuth on Rails Building a Production-Ready AI App\"\n  raw_title: \"MCP & OAuth on Rails Building a Production-Ready AI App\"\n  language: \"en\"\n  speakers:\n    - Paweł Strzałkowski\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-10\"\n  announced_at: \"2026-01-28\"\n  description: |-\n    CTO, consultant and full-stack developer since the 90s. Author of many articles showcasing a creative approach to using Rails. Currently excited about the potential of AI and cross-tech discoveries. Frequent speaker at conferences/meetups and a strong supporter of the European Ruby scene. Creates games for fun.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFkjfQmbUAAcE_m?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFkjfQmbUAAcE_m?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFkjfQmbUAAcE_m?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFkjfQmbUAAcE_m?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFkjfQmbUAAcE_m?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"pawel-strzalkowski-tropical-on-rails-2026\"\n\n- id: \"vladimir-dementyev-tropical-on-rails-2026\"\n  title: \"Keynote by Vladimir Dementyev\"\n  raw_title: \"Keynote by Vladimir Dementyev\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"Tropical on Rails 2026\"\n  date: \"2026-04-10\"\n  announced_at: \"2025-10-06 12:30 UTC\"\n  description: |-\n    My name is Vladimir (or Вова), I am a mathematician and software developer passionate about open source technologies.\n  thumbnail_xs: \"https://pbs.twimg.com/media/HFku9FBboAA4bwI?format=jpg&name=small\"\n  thumbnail_sm: \"https://pbs.twimg.com/media/HFku9FBboAA4bwI?format=jpg&name=small\"\n  thumbnail_md: \"https://pbs.twimg.com/media/HFku9FBboAA4bwI?format=jpg\"\n  thumbnail_lg: \"https://pbs.twimg.com/media/HFku9FBboAA4bwI?format=jpg&name=large\"\n  thumbnail_xl: \"https://pbs.twimg.com/media/HFku9FBboAA4bwI?format=jpg&name=4096x4096\"\n  video_provider: \"scheduled\"\n  video_id: \"vladimir-dementyev-tropical-on-rails-2026\"\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2015/event.yml",
    "content": "---\nid: \"tropicalrb-2015\"\ntitle: \"Tropical.rb 2015\"\ndescription: |-\n  The Beach Ruby Conference - Enjoy amazing conversations, stunning landscapes and a superb nature. Come and talk with some of the best Rubyists in this tropical paradise.\nlocation: \"Porto de Galinhas, Brazil\"\nkind: \"conference\"\nstart_date: \"2015-03-05\"\nend_date: \"2015-03-08\"\nwebsite: \"https://web.archive.org/web/20150428132714/http://tropicalrb.com/en/\"\ntwitter: \"tropicalrb\"\nplaylist: \"http://tropicalrb.com/en/videos/\"\ncoordinates:\n  latitude: -8.5066276\n  longitude: -35.0057167\nbanner_background: \"#027991\"\nfeatured_background: \"#027991\"\nfeatured_color: \"#FAE5B1\"\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2015/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Lailson Bandeira\n    - Guilherme Cavalcanti\n    - Thiago Diniz\n\n  organisations:\n    - Guava\n    - Eloquent\n\n- name: \"Ambassador\"\n  users:\n    - Bruno Henrique\n    - Cirdes Henrique\n    - João Moura\n    - Juarez P.A. Filho\n    - Lucas Martins\n    - Renato Carvalho\n    - Thiago Guimarães\n\n  organisations: []\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2015/schedule.yml",
    "content": "# Day 1: https://web.archive.org/web/20150423051444/http://tropicalrb.com/en/schedule/march-6/\n# Day 2: https://web.archive.org/web/20150428132714/http://tropicalrb.com/en/schedule/march-7/\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2015-03-06\"\n    grid:\n      - start_time: \"05:30\"\n        end_time: \"08:00\"\n        slots: 1\n        items:\n          - Transfer from Recife to Porto de Galinhas\n\n      - start_time: \"08:00\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Buggy Ride\n\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Raft Boat Sail\n\n      - start_time: \"11:30\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"13:00\"\n        end_time: \"13:40\"\n        slots: 1\n\n      - start_time: \"13:40\"\n        end_time: \"14:10\"\n        slots: 1\n\n      - start_time: \"14:10\"\n        end_time: \"14:40\"\n        slots: 1\n\n      - start_time: \"14:40\"\n        end_time: \"15:10\"\n        slots: 1\n\n      - start_time: \"15:10\"\n        end_time: \"15:40\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"15:40\"\n        end_time: \"16:10\"\n        slots: 1\n\n      - start_time: \"16:10\"\n        end_time: \"16:40\"\n        slots: 1\n\n      - start_time: \"16:40\"\n        end_time: \"17:10\"\n        slots: 1\n\n      - start_time: \"17:10\"\n        end_time: \"17:50\"\n        slots: 1\n\n      - start_time: \"17:50\"\n        end_time: \"18:20\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"18:20\"\n        end_time: \"18:50\"\n        slots: 1\n\n      - start_time: \"18:50\"\n        end_time: \"19:20\"\n        slots: 1\n\n      - start_time: \"20:00\"\n        end_time: \"22:00\"\n        slots: 1\n        items:\n          - Transfer from Porto de Galinhas to Recife\n\n  - name: \"Day 2\"\n    date: \"2015-03-07\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Scuba Diving\n\n      - start_time: \"12:00\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"13:00\"\n        end_time: \"13:40\"\n        slots: 1\n\n      - start_time: \"13:40\"\n        end_time: \"14:10\"\n        slots: 1\n\n      - start_time: \"14:10\"\n        end_time: \"14:50\"\n        slots: 1\n\n      - start_time: \"14:50\"\n        end_time: \"15:20\"\n        slots: 1\n\n      - start_time: \"15:20\"\n        end_time: \"15:50\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"15:50\"\n        end_time: \"16:20\"\n        slots: 1\n\n      - start_time: \"16:20\"\n        end_time: \"16:50\"\n        slots: 1\n\n      - start_time: \"16:50\"\n        end_time: \"17:20\"\n        slots: 1\n\n      - start_time: \"17:20\"\n        end_time: \"17:50\"\n        slots: 1\n\n      - start_time: \"17:50\"\n        end_time: \"18:20\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"18:20\"\n        end_time: \"18:50\"\n        slots: 1\n\n      - start_time: \"18:50\"\n        end_time: \"19:20\"\n        slots: 1\n\ntracks: []\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2015/sponsors.yml",
    "content": "# docs/ADDING_SPONSORS.md\n# Sponsor page: https://web.archive.org/web/20150507033928/http://tropicalrb.com/en/sponsors\n---\n- tiers:\n    - name: \"Gold\"\n      level: 1\n      sponsors:\n        - name: \"NIC.br\"\n          slug: \"nic-br\"\n          website: \"https://www.nic.br/en/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-gold-nic@2x-fb28cd34.png\"\n          description: |-\n            The Brazilian Network Information Center (NIC.br) is a civil, not for profit entity, which implements the Brazilian Internet Steering Committee (CGI.br) decisions and projects. NIC.br activities include the coordination of domain names registration (Registro.br), handling Internet security incidents related to the Internet in Brazil (CERT.br), research and study on network and operations technologies (Ceptro.br), production of indicators on ICTs in Brazil (Cetic.br) and hosting the W3C Brazilian office.\n\n        - name: \"Mandrill\"\n          slug: \"mandrill\"\n          website: \"https://mailchimp.com/features/transactional-email/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-gold-mandrill@2x-c5846155.png\"\n          description: |-\n            Use Mandrill to send automated one-to-one email like password resets and welcome messages, as well as marketing emails and customized newsletters. Mandrill is quick to set up, easy to use, and ridiculously stable.\n\n        - name: \"Engine Yard\"\n          slug: \"engine-yard\"\n          website: \"https://www.engineyard.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-gold-engineyard@2x-09cbdc0f.png\"\n          description: |-\n            Engine Yard, the leading Rails hosting company, offers customers peace of mind, support and expertise when deploying their Ruby or Rails applications to the cloud.\n\n        - name: \"ThoughtWorks\"\n          slug: \"thoughtworks\"\n          website: \"https://www.thoughtworks.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-gold-thoughtworks@2x-3f5919fe.png\"\n          description: |-\n            ThoughtWorks is a software company and community of passionate, purpose-led individuals all while seeking to revolutionize the IT industry and create positive social change.\n\n    - name: \"Silver\"\n      level: 2\n      sponsors:\n        - name: \"GitHub\"\n          slug: \"github\"\n          website: \"https://github.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-silver-github@2x-6d038425.png\"\n          description: |-\n            GitHub is the best place to share code with friends, co-workers, classmates, and complete strangers. Over eight million people use GitHub to build amazing things together.\n\n        - name: \"Tempest\"\n          slug: \"tempest\"\n          website: \"https://tempest.com.br/en/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-silver-tempest@2x-24b46ea9.png\"\n          description: |-\n            Tempest Security Intelligence is a global cyber security consulting firm that has been delivering exceptional service quality to its clients since 2000.\n\n        - name: \"CERS Cursos Online\"\n          slug: \"cers-cursos-online\"\n          website: \"https://www.cers.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-silver-cers@2x-e066a9d5.png\"\n          description: |-\n            Quality, interactivity and innovation: these words define what CERS Cursos Online is. We are the biggest distance learning center of Brazil.\n\n        - name: \"Genius\"\n          slug: \"genius\"\n          website: \"https://genius.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-silver-genius@2x-f16d3380.png\"\n          description: |-\n            Genius is an online knowledge project whose goal is to annotate the world.\n\n        - name: \"LivingSocial\"\n          slug: \"livingsocial\"\n          website: \"https://www.livingsocial.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-silver-livingsocial@2x-c6a009e2.png\"\n          description: |-\n            LivingSocial is the local marketplace to buy and share the best things to do in your city.\n\n        - name: \"Amazon Web Services\"\n          slug: \"amazon-web-services\"\n          website: \"https://aws.amazon.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-silver-aws@2x-56ac22ca.png\"\n          description: |-\n            Launched in July 2002, the Amazon Web Services platform exposes technology and product data from Amazon and its affiliates, enabling developers to build innovative and entrepreneurial applications on their own.\n\n    - name: \"Bronze\"\n      level: 3\n      sponsors:\n        - name: \"E.life\"\n          slug: \"e-life\"\n          website: \"https://www.elife.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-elife@2x-92fd74b7.png\"\n\n        - name: \"In Loco Media\"\n          slug: \"in-loco-media\"\n          website: \"https://www.inlocomedia.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-inlocomedia@2x-7d9cfe41.png\"\n\n        - name: \"Toptal\"\n          slug: \"toptal\"\n          website: \"https://www.toptal.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-toptal@2x-339df4f1.png\"\n\n        - name: \"Getup\"\n          slug: \"getup\"\n          website: \"https://getupcloud.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-getup@2x-7997a38e.png\"\n\n        - name: \"L.A. Tecnologia em Saúde\"\n          slug: \"la-tecnologia-em-saude\"\n          website: \"https://www.latecnologiaemsaude.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-la@2x-5736693e.png\"\n\n        - name: \"Mesa\"\n          slug: \"mesa\"\n          website: \"https://www.mesainc.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-mesa@2x-83f0e8d9.png\"\n\n        - name: \"Mabuya Software\"\n          slug: \"mabuya-software\"\n          website: \"https://www.axon.com.br/portal/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-mabuya@2x-ec95ffe3.png\"\n\n        - name: \"Estuário\"\n          slug: \"estuario\"\n          website: \"https://www.estuarioti.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-estuario@2x-919f4bfe.png\"\n\n        - name: \"Chargify\"\n          slug: \"chargify\"\n          website: \"https://www.chargify.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-chargify@2x-d94e9a12.png\"\n\n        - name: \"Cloudwalk\"\n          slug: \"cloudwalk\"\n          website: \"https://www.cloudwalk.io/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-cloudwalk@2x-01427dbb.png\"\n\n        - name: \"DNSimple\"\n          slug: \"dnsimple\"\n          website: \"https://dnsimple.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-dnsimple@2x-d5566def.png\"\n\n        - name: \"Zertico\"\n          slug: \"zertico\"\n          website: \"https://www.zertico.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-zertico@2x-70e1a9a4.png\"\n\n        - name: \"Codeminer 42\"\n          slug: \"codeminer-42\"\n          website: \"https://www.codeminer42.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-bronze-codeminer@2x-637ac6d2.png\"\n\n    - name: \"Supporters\"\n      level: 4\n      sponsors:\n        - name: \"Ruby Central\"\n          slug: \"ruby-central\"\n          website: \"https://rubycentral.org/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-rubycentral@2x-52faacdc.png\"\n          badge: \"Advisory Support\"\n\n        - name: \"Impact Hub Recife\"\n          slug: \"impact-hub-recife\"\n          website: \"https://recife.impacthub.net/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-impacthub@2x-0a34cb00.png\"\n          badge: \"Advisory Support\"\n\n        - name: \"Casa Eventos Empresariais\"\n          slug: \"casa-eventos-empresariais\"\n          website: \"https://www.casaeventosempresariais.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-casaeventos@2x-d144bccf.png\"\n          badge: \"Executive Producer\"\n\n        - name: \"PontesTur\"\n          slug: \"pontestur\"\n          website: \"https://www.pontestur.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-pontestur@2x-4c799fae.png\"\n          badge: \"Travel Agency\"\n\n        - name: \"Eventick\"\n          slug: \"eventick\"\n          website: \"https://www.eventick.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-eventick@2x-cb99a7fb.png\"\n\n        - name: \"Portomídia\"\n          slug: \"portomidia\"\n          website: \"https://www.portomidia.org/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-portomidia@2x-3f71c0ed.png\"\n\n        - name: \"Porto Digital\"\n          slug: \"porto-digital\"\n          website: \"https://www.portodigital.org/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-portodigital@2x-9c4407ad.png\"\n\n        - name: \"Plataformatec\"\n          slug: \"plataformatec\"\n          website: \"https://plataformatec.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-plataformatec@2x-91b14159.png\"\n\n        - name: \"Citi\"\n          slug: \"citi\"\n          website: \"https://citi.org.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-citi@2x-9f0b09de.png\"\n\n        - name: \"Devbeers\"\n          slug: \"devbeers\"\n          website: \"https://www.devbeers.io/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-devbeers@2x-c5ee2510.png\"\n\n        - name: \"Novatec\"\n          slug: \"novatec\"\n          website: \"https://novatec.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-novatec@2x-59489398.png\"\n\n        - name: \"Recife Convention & Visitors Bureau\"\n          slug: \"recife-convention-visitors-bureau\"\n          website: \"https://www.recifecvb.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-cvb@2x-ce58f7e8.png\"\n\n        - name: \"Say2me\"\n          slug: \"say2me\"\n          website: \"https://www.say2me.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-say2me@2x-bcd1c34b.png\"\n\n        - name: \"Twitter\"\n          slug: \"twitter\"\n          website: \"https://twitter.com/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-twitter@2x-5f642098.png\"\n\n        - name: \"Locaweb\"\n          slug: \"locaweb\"\n          website: \"https://www.locaweb.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-locaweb@2x-5500dea7.png\"\n\n        - name: \"RubyMine by JetBrains\"\n          slug: \"rubymine-by-jetbrains\"\n          website: \"https://www.jetbrains.com/ruby/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-jetbrains@2x-ce6b1b44.png\"\n\n        - name: \"Compose\"\n          slug: \"compose\"\n          website: \"https://www.compose.io/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-compose@2x-86974ec9.png\"\n\n        - name: \"Gravento\"\n          slug: \"gravento\"\n          website: \"https://gravento.com.br/\"\n          logo_url: \"https://web.archive.org/web/20150507033928im_/http://tropicalrb.com/images/sponsor-support-gravento@2x-dfbf3492.png\"\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2015/venue.yml",
    "content": "---\nname: \"Summerville All Inclusive Resort\"\nurl: \"https://www.summervilleresort.com.br/\"\naddress:\n  street: \"Praia de Muro Alto\"\n  city: \"Ipojuca\"\n  region: \"PE\"\n  postal_code: \"55590-000\"\n  country: \"Brazil\"\n  country_code: \"BR\"\n  display: \"Praia de Muro Alto, Ipojuca - PE, 55590-000, Brazil\"\ncoordinates:\n  latitude: -8.5066276\n  longitude: -35.0057167\nmaps:\n  google: \"https://maps.google.com/?q=Summerville+All+Inclusive+Resort,+Praia+de+Muro+Alto,+Ipojuca,+PE,+Brazil\"\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2015/videos.yml",
    "content": "# Website: http://tropicalrb.com/\n# Videos: http://tropicalrb.com/en/videos/\n---\n- id: \"nick-sutterer-tropical-rb-2015\"\n  title: \"Keynote: See You On The Trail!\"\n  raw_title: \"Keynote: See You On The Trail!\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-06\"\n  kind: \"keynote\"\n  video_provider: \"not_recorded\"\n  video_id: \"nick-sutterer-tropical-rb-2015\"\n  language: \"english\"\n  description: \"\"\n\n- id: \"simone-carletti-tropical-rb-2015\"\n  title: \"Maintaining a 5yo Ruby project\"\n  raw_title: \"Maintaining a 5yo Ruby project\"\n  speakers:\n    - Simone Carletti\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-06\"\n  video_provider: \"not_recorded\"\n  video_id: \"simone-carletti-tropical-rb-2015\"\n  language: \"english\"\n  slides_url: \"https://speakerdeck.com/weppos/maintaining-a-5yo-ruby-project-shark-edition\"\n  description: |-\n    Maintaining a young, small Ruby product is simple, but time passes and your code becomes harder to maintain day after day. This talk illustrates the development techniques, Ruby patterns and best practices we use at DNSimple to develop new features and ensure long-term maintainability of our codebase.\n\n- id: \"christopher-rigor-tropical-rb-2015\"\n  title: \"Cryptography for Rails Developers\"\n  raw_title: \"Cryptography for Rails Developers\"\n  speakers:\n    - Christopher Rigor\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-06\"\n  video_provider: \"not_recorded\"\n  video_id: \"christopher-rigor-tropical-rb-2015\"\n  language: \"english\"\n  description: |-\n    You know HTTPS keeps your website secure but do you know how? Ruby just released a new version to address a vulnerability with SSL but do you know your app might still be vulnerable? Cryptography is a hard and huge topic and this talk will give you a great introduction. You don't need a background on cryptography, just an open mind! You will learn about the public key cryptography, SSL/TLS and Ruby tips that will make your app secure.\n\n- id: \"alex-coles-tropical-rb-2015\"\n  title: \"Frontend Choices\"\n  raw_title: \"Frontend Choices\"\n  speakers:\n    - Alex Coles\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-06\"\n  video_provider: \"not_recorded\"\n  video_id: \"alex-coles-tropical-rb-2015\"\n  language: \"english\"\n  description: |-\n    Rails was born in 2004, the time of the \"Ajax revolution\". With the help of a little bit of prototype, Scriptaculous and RJS, Rails made its mark in part because it facilitated creating beautiful and highly interactive web user interfaces in no time at all. Fast forward to 2013. Frameworks like Meteor and Hoodie are capturing increasing mindshare. Are we now in the decade of JavaScript? Is the \"Rails Way\" still relevant to the frontend?\n\n- id: \"ricardo-nacif-tropical-rb-2015\"\n  title: \"Writing Your Own DSL Using Ruby\"\n  raw_title: \"Writing Your Own DSL Using Ruby\"\n  speakers:\n    - Ricardo Nacif\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-06\"\n  video_provider: \"not_recorded\"\n  video_id: \"ricardo-nacif-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    In this talk we'll go through some concepts on the Ruby language that will help us creating our own custom Domain Specific Language. It's a very hands-on talk. We'll play with dynamic classes, dynamic methods, blocks, procs and method chaining, but our main goal is to write (and learn how) our own Pizza Menu DSL.\n\n- id: \"marcelo-de-polli-tropical-rb-2015\"\n  title: \"POROs to the Rescue\"\n  raw_title: \"POROs to the Rescue\"\n  speakers:\n    - Marcelo De Polli\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-06\"\n  video_provider: \"not_recorded\"\n  video_id: \"marcelo-de-polli-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    Being tasked with rescuing an ancient codebase and turning it into something workable and manageable is a predicament most of us have already found ourselves in. In the 10 years since we began using Ruby to write Web applications, a lot has changed concerning architectures and design patterns. How do you take your code in a time travel from the olden days to more current practices such as POROs, lean models, presenters and decorators? This talk will walk you through some easy practices that can make that trip less bumpy and allow you to survive to tell the story.\n\n- id: \"lucas-allan-tropical-rb-2015\"\n  title: \"Concurrent-Ruby: Ruby in the Concurrent World\"\n  raw_title: \"Concurrent-Ruby: Ruby in the Concurrent World\"\n  speakers:\n    - Lucas Allan\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-06\"\n  video_provider: \"not_recorded\"\n  video_id: \"lucas-allan-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    Rumor has it that you can't write concurrent programs in Ruby. People once believed that the world was flat and we all know how that turned out. Between the native threads introduced in MRI 1.9 and the JVM threading available to JRuby, Ruby is now a valid platform for concurrent applications. What we've been missing — until now — are the advanced concurrency tools available to other languages like Clojure, Scala, Erlang, and Go.\n\n- id: \"rafael-franca-tropical-rb-2015\"\n  title: \"Object Oriented Design, Rails and Why You Should Think Twice Before Leaving the Rails Way\"\n  raw_title: \"Object Oriented Design, Rails and Why You Should Think Twice Before Leaving the Rails Way\"\n  speakers:\n    - Rafael França\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-06\"\n  video_provider: \"not_recorded\"\n  video_id: \"rafael-franca-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    The Ruby community has been bombarded by a plethora of discussions about software design best practices. Acronyms such as SOLID, DCI and SOA are up in the community and all them promise to materialize the ghost of maintainability. What few of these discussions present is that applying these principles and techniques fervently also impacts the software maintenance.\n\n    In this talk I will present some of these concepts and show the symptoms that they can cause in yours projects if applied incorrectly.\n\n- id: \"yasodara-cordova-tropical-rb-2015\"\n  title: \"25 Minutes of Semantic Web\"\n  raw_title: \"25 Minutes of Semantic Web\"\n  speakers:\n    - Yasodara Córdova\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-06\"\n  video_provider: \"not_recorded\"\n  video_id: \"yasodara-cordova-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    The promise is: you'll understand in 10 minutes why use Semantic Web. The following 15 minutes of the talk will be used to show 15 applications using the concepts of Semantic Web, one per minute :-)\n\n- id: \"rafael-franca-carlos-antonio-celso-nanderson-nick-sutterer-tropical-rb-2015\"\n  title: \"Panel: The Rails Way vs. Trailblazer\"\n  raw_title: \"Panel: The Rails Way vs. Trailblazer\"\n  speakers:\n    - Rafael França\n    - Carlos Antonio\n    - Celso Fernandes\n    - Nick Sutterer\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-06\"\n  kind: \"panel\"\n  video_provider: \"not_recorded\"\n  video_id: \"rafael-franca-carlos-antonio-celso-nanderson-nick-sutterer-tropical-rb-2015\"\n  language: \"english\"\n  description: |-\n    Organizing and structuring Rails applications has been an ongoing discussion for years in the community. While some find in necessary to introduce new abstraction layers, indirection and encapsulation for a sustainable architecture, others defend we shouldn't abandon the Rails Way for the sake of conventions and compatibility.\n\n    In this panel both members from Rails core as well as the creator of Trailblazer are gonna discuss both approaches, their point of views, why they choose their way, and why they still can be friends.\n\n- id: \"rodrigo-franco-tropical-rb-2015\"\n  title: \"Keynote: Better Programmers\"\n  raw_title: \"Keynote: Better Programmers\"\n  speakers:\n    - Rodrigo Franco\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-07\"\n  kind: \"keynote\"\n  video_provider: \"not_recorded\"\n  video_id: \"rodrigo-franco-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: \"\"\n\n- id: \"john-crepezzi-tropical-rb-2015\"\n  title: \"On Memory\"\n  raw_title: \"On Memory\"\n  speakers:\n    - John Crepezzi\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-07\"\n  video_provider: \"not_recorded\"\n  video_id: \"john-crepezzi-tropical-rb-2015\"\n  language: \"english\"\n  description: |-\n    The fact that Ruby doesn't require developers to manage memory provides us a much less frustrating day-to-day. Still, there are scenarios where losing sight of the memory implications of our patterns and logic, will get us into trouble! In this talk, I'll go over common (and less common) memory pitfalls, how they work, and how to fix them.\n\n- id: \"netto-farah-tropical-rb-2015\"\n  title: \"Building a Single Page App. One Page at a Time.\"\n  raw_title: \"Building a Single Page App. One Page at a Time.\"\n  speakers:\n    - Netto Farah\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-07\"\n  video_provider: \"not_recorded\"\n  video_id: \"netto-farah-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    It may sound simple to build a single page app these days with so many tools such as AngularJs, Knockout, Backbone, etc. But very little is said about transforming an existing app into to a single page one.\n\n- id: \"fabiano-beselga-tropical-rb-2015\"\n  title: \"Clean Architecture\"\n  raw_title: \"Clean Architecture\"\n  speakers:\n    - Fabiano Beselga\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-07\"\n  video_provider: \"not_recorded\"\n  video_id: \"fabiano-beselga-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    Rails is an awesome framework to build something fast from scratch, but when the app starts to grow it becomes harder to maintain if you keep following only the folders that Rails's initial configuration provides. There are a lot of approaches to get around it, Uncle Bob's Clean Architecture that separates the logic of the app from the delivery mechanism and from the database.\n\n- id: \"carlos-antonio-tropical-rb-2015\"\n  title: \"Contributing to Open Source: From the Beginning to Lessons Learned\"\n  raw_title: \"Contributing to Open Source: From the Beginning to Lessons Learned\"\n  speakers:\n    - Carlos Antonio\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-07\"\n  video_provider: \"not_recorded\"\n  video_id: \"carlos-antonio-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    Many people have difficulties to do a first contribution to open source, while others try to keep actively contributing. They do not feel confident enough, wondering if are doing it right, if they are following \"patterns\", if they will make mistakes in public, and this list of questions just keeps growing. This talk will attend the problems I've faced in the last years contributing and maintaining open source projects. It will give tips on how to start and remain active in today's open source world, and preserve your sanity to avoid the burnout.\n\n- id: \"andrew-rosa-tropical-rb-2015\"\n  title: \"Property Testing on Rails\"\n  raw_title: \"Property Testing on Rails\"\n  speakers:\n    - Andrew Rosa\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-07\"\n  video_provider: \"not_recorded\"\n  video_id: \"andrew-rosa-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    The Ruby community is known by its strong culture of testing, but this is not an excuse to refuse alternative approaches. One of these are Property Testing. In those tools we do not express examples, but the possible input formats; instead of specific outputs, characteristics that must remain true. In this way our tools are capable of exhaustively generate test cases and look for failures. In this talk we'll see how to create lean suites with wide coverage using Clojure's power to test a Rails application.\n\n- id: \"thiago-scalone-tropical-rb-2015\"\n  title: \"MRuby: Change the Embedded Development Way\"\n  raw_title: \"MRuby: Change the Embedded Development Way\"\n  speakers:\n    - Thiago Scalone\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-07\"\n  video_provider: \"not_recorded\"\n  video_id: \"thiago-scalone-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    MRuby (Minimalistc Ruby) is a new Ruby implementation made with resources saving in mind. MRuby is a perfect fit for embedded systems world and for limited responsibility applications. Let's understand the state of embedded system development today from the payment devices perspective. In the talk we'll learn how beautiful and useful MRuby is on a device-browser integration or in command line tool.\n\n- id: \"marcos-matos-tropical-rb-2015\"\n  title: \"Micro Problems!\"\n  raw_title: \"Micro Problems!\"\n  speakers:\n    - Marcos Matos\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-07\"\n  video_provider: \"not_recorded\"\n  video_id: \"marcos-matos-tropical-rb-2015\"\n  language: \"portuguese\"\n  description: |-\n    Micro services are trend. It's a magic cure for complex projects. The problem is in the details! Like every trend topic, the problems and complications around this style are not discussed, topics like performance, scalability, integration tests and infrastructure. At this anti-talk we are going to show the traps lurking around micro services' architecture and how to avoid them.\n\n- id: \"pj-hagerty-tropical-rb-2015\"\n  title: \"Urban Legends: What You Code Makes You Who You Are\"\n  raw_title: \"Urban Legends: What You Code Makes You Who You Are\"\n  speakers:\n    - PJ Hagerty\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-07\"\n  video_provider: \"not_recorded\"\n  video_id: \"pj-hagerty-tropical-rb-2015\"\n  language: \"english\"\n  description: |-\n    If you were a carpenter, would your skills at building be more important than the tools you use to build? Skills, right? Tools are just a means to an end. So why do developers think the language they use defines the problems they solve?\n\n- id: \"avdi-grimm-tropical-rb-2015\"\n  title: \"Keynote: The Soul of Software\"\n  raw_title: \"Keynote: The Soul of Software\"\n  speakers:\n    - Avdi Grimm\n  event_name: \"Tropical.rb 2015\"\n  date: \"2015-03-07\"\n  kind: \"keynote\"\n  video_provider: \"not_recorded\"\n  video_id: \"avdi-grimm-tropical-rb-2015\"\n  language: \"english\"\n  description: \"\"\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2024/cfp.yml",
    "content": "---\n- link: \"https://www.papercall.io/tropical-rb\"\n  open_date: \"2023-11-28\"\n  close_date: \"2024-01-10\"\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2024/event.yml",
    "content": "---\nid: \"PLvOWTr3oa1dVFAtodH31zjwdue2QH7wdd\"\ntitle: \"Tropical.rb 2024\"\nkind: \"conference\"\nlocation: \"São Paulo, Brazil\"\ndescription: |-\n  Tropical.rb - The Latin America Rails Conference\npublished_at: \"2024-04-04\"\nstart_date: \"2024-04-04\"\nend_date: \"2024-04-05\"\nchannel_id: \"UCC3ljLfioI4qN2_zmG_kseQ\"\nyear: 2024\nbanner_background: \"#252B30\"\nfeatured_background: \"#252B30\"\nfeatured_color: \"#FEEB3B\"\nwebsite: \"https://www.tropicalonrails.com/en/archive-2024\"\ncoordinates:\n  latitude: -23.596509614780032\n  longitude: -46.68686643181197\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2024/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Cirdes Henrique\n    - Débora Fernandes\n    - Juliana Dias\n    - Rafael Mendonça França\n\n  organisations: []\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2024/schedule.yml",
    "content": "# Schedule: https://www.tropicalonrails.com/en/archive-2024#agenda2024\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2024-04-04\"\n    grid:\n      - start_time: \"08:30\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Registration\n\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening\n\n      - start_time: \"10:00\"\n        end_time: \"10:50\"\n        slots: 1\n\n      - start_time: \"10:50\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"12:40\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:40\"\n        end_time: \"12:10\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"14:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:50\"\n        end_time: \"15:20\"\n        slots: 1\n\n      - start_time: \"15:20\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:05\"\n        end_time: \"16:50\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"16:50\"\n        end_time: \"17:20\"\n        slots: 1\n\n      - start_time: \"17:20\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"18:10\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"18:10\"\n        end_time: \"19:00\"\n        slots: 1\n\n      - start_time: \"19:00\"\n        end_time: \"19:15\"\n        slots: 1\n        items:\n          - Closing\n\n  - name: \"Day 2\"\n    date: \"2024-04-05\"\n    grid:\n      - start_time: \"09:45\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - Opening\n\n      - start_time: \"10:00\"\n        end_time: \"10:50\"\n        slots: 1\n\n      - start_time: \"10:50\"\n        end_time: \"11:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:00\"\n        end_time: \"11:30\"\n        slots: 1\n\n      - start_time: \"11:30\"\n        end_time: \"11:40\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"11:40\"\n        end_time: \"12:10\"\n        slots: 1\n\n      - start_time: \"12:15\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"14:00\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"14:50\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:50\"\n        end_time: \"15:20\"\n        slots: 1\n\n      - start_time: \"15:20\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:05\"\n        end_time: \"16:50\"\n        slots: 1\n        items:\n          - Coffee Break\n\n      - start_time: \"16:50\"\n        end_time: \"17:20\"\n        slots: 1\n\n      - start_time: \"17:20\"\n        end_time: \"17:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"17:30\"\n        end_time: \"18:00\"\n        slots: 1\n\n      - start_time: \"18:00\"\n        end_time: \"18:10\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"18:10\"\n        end_time: \"19:00\"\n        slots: 1\n\n      - start_time: \"19:00\"\n        end_time: \"19:15\"\n        slots: 1\n        items:\n          - Closing\n\ntracks: []\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2024/sponsors.yml",
    "content": "# docs/ADDING_SPONSORS.md\n---\n- tiers:\n    - name: \"Platinum\"\n      level: 1\n      sponsors:\n        - name: \"shopify\"\n          website: \"https://www.shopify.com/br\"\n          slug: \"shopify\"\n        - name: \"Husky by Nomad\"\n          website: \"https://www.husky.io/corporate\"\n          slug: \"husky-by-nomad\"\n          logo_url: \"https://framerusercontent.com/images/m5sQ6ltQZc2StZvlaKHyzq55k.png\"\n\n    - name: \"Gold\"\n      level: 2\n      sponsors:\n        - name: \"codeminer\"\n          website: \"https://www.codeminer42.com/?utm_source=tropicalrb2024&utm_medium=website&utm_campaign=sponsor\"\n          slug: \"codeminer\"\n          logo_url: \"https://framerusercontent.com/images/Z6EzjuI5o9SHDIF995gykctl4w.png\"\n        - name: \"locaweb\"\n          website: \"https://www.locaweb.com.br/\"\n          slug: \"locaweb\"\n          logo_url: \"https://framerusercontent.com/images/V0fMqwGGEVwzLmS0cMpolcFrAGY.png?scale-down-to=1024&width=1907&height=724\"\n        - name: \"rebase\"\n          website: \"https://www.rebase.com.br/?utm_source=tropicalrb\"\n          slug: \"rebase\"\n          logo_url: \"https://framerusercontent.com/images/E8WTYL2xiyLiwrXbmf7L6PngRg.png\"\n        - name: \"AppSignal\"\n          website: \"https://www.appsignal.com/?utm_source=tropicalrb\"\n          slug: \"appsignal\"\n          logo_url: \"https://framerusercontent.com/images/Ej8aWi209QFR5YrNB6Rl1aN8RqY.png\"\n        - name: \"smartfit\"\n          website: \"https://www.smartfit.com.br/?utm_source=tropicalrb\"\n          slug: \"smartfit\"\n          logo_url: \"https://framerusercontent.com/images/nZXI7vyCsttCw6tsyZY4DY1Nnw.svg\"\n        - name: \"iugu\"\n          website: \"https://www.iugu.com/?utm_source=tropicalrb\"\n          slug: \"iugu\"\n          logo_url: \"https://framerusercontent.com/images/J5Qw1ZcYmwVwyMQUaNPad9CLno.png\"\n        - name: \"pipefy\"\n          website: \"https://www.pipefy.com\"\n          slug: \"pipefy\"\n          logo_url: \"https://framerusercontent.com/images/cJXvjvn4GBEBnlzqOGwxtGPf7VA.png\"\n          badge: \"Happy Hour Sponsor\"\n\n    - name: \"Silver\"\n      level: 3\n      sponsors:\n        - name: \"agendor\"\n          website: \"https://www.agendor.com.br/?utm_source=tropicalrb\"\n          slug: \"agendor\"\n          logo_url: \"https://framerusercontent.com/images/dezZNyV5WziBPR06SxVgk8VtxU.svg\"\n        - name: \"monde\"\n          website: \"https://monde.com.br/?utm_source=tropicalrb\"\n          slug: \"monde\"\n          logo_url: \"https://framerusercontent.com/images/uWOMpd19UQCH1JpPTiUNAI0dA5o.png\"\n        - name: \"cedarcode\"\n          website: \"https://www.cedarcode.com/?utm_source=tropicalrb\"\n          slug: \"cedarcode\"\n        - name: \"doximity\"\n          website: \"https://technology.doximity.com/\"\n          slug: \"doximity\"\n          logo_url: \"https://framerusercontent.com/images/HiEjn8GFLb33jKi7KJ9EsDBQ.svg?scale-down-to=512&width=1094&height=275\"\n        - name: \"KnowBe4\"\n          website: \"https://www.knowbe4.com/careers/locations/sao-paulo?utm_source=tropicalrb\"\n          slug: \"knowbe4\"\n          logo_url: \"https://framerusercontent.com/images/G0QBjpAO7bwqrLUrOPANVOQ.png?scale-down-to=512&width=1947&height=357\"\n        - name: \"Incognia\"\n          website: \"https://www.incognia.com/?utm_source=tropicalrb\"\n          slug: \"incognia\"\n          logo_url: \"https://framerusercontent.com/images/mVIp5VCaifm5kjZRouky1l5f0s.png?width=848&height=158\"\n        - name: \"Planet Argon\"\n          website: \"https://www.planetargon.com/?utm_source=tropicalrb\"\n          slug: \"planet-argon\"\n          logo_url: \"https://framerusercontent.com/images/C9n4yRJQMkbKrJDxAHjWt4ELHc.png?scale-down-to=512&width=12842&height=4189\"\n        - name: \"INK\"\n          website: \"https://www.reservaink.com.br/?utm_source=tropicalrb\"\n          slug: \"ink\"\n          logo_url: \"https://framerusercontent.com/images/BIMlOgvAEOvU2KaSMVfaLRp8xU.png?scale-down-to=512&width=2990&height=1132\"\n        - name: \"Adaflow\"\n          website: \"https://www.adaflow.com\"\n          slug: \"adaflow\"\n          logo_url: \"https://framerusercontent.com/images/Zsj8BBFcV8wc7mYEJ2fK5Mm3Xw.png?width=496&height=72\"\n        - name: \"gocase\"\n          website: \"https://www.gocase.com.br\"\n          slug: \"gocase\"\n          logo_url: \"https://framerusercontent.com/images/FIQ0OnaCLg7OGCrTgiN6WpO5kto.png?width=170&height=49\"\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2024/venue.yml",
    "content": "---\nname: \"Itaú Cube\"\naddress:\n  street: \"Vicente Pinzon Avenue, 54 - Vila Olímpia\"\n  city: \"São Paulo\"\n  region: \"SP\"\n  postal_code: \"04547-130\"\n  country: \"Brazil\"\n  country_code: \"BR\"\n  display: \"Vicente Pinzon Avenue, 54 - Vila Olímpia, São Paulo - SP - Brazil\"\ncoordinates:\n  latitude: -23.596509614780032\n  longitude: -46.68686643181197\nmaps:\n  google: \"https://maps.app.goo.gl/AoZVJfcPPE6yqtR28\"\n"
  },
  {
    "path": "data/tropicalrb/tropicalrb-2024/videos.yml",
    "content": "---\n# TODO: conference website\n# TODO: schedule website\n\n# Day 1\n\n- id: \"rafael-mendona-frana-tropicalrb-2024\"\n  title: \"Keynote: Investing In The Ruby Community\"\n  raw_title: \"Rafael França | Investing in the Ruby community\"\n  speakers:\n    - Rafael Mendonça França\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-04\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"Xk9hVfvnAuI\"\n  language: \"portuguese\"\n  description: |-\n    Opening Keynote\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"lazaro-nixon-tropicalrb-2024\"\n  title: \"Authentication: Reinventing The Wheel\"\n  raw_title: \"Lázaro Nixon | Authentication: Reinventing the wheel\"\n  speakers:\n    - Lázaro Nixon\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-04\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"t5UFLkcSORU\"\n  language: \"portuguese\"\n  description: |-\n    We all use Devise, it’s the defacto authentication approach in Rails, but if I told you that building your authentication is not that difficult, some years ago I created a library called authentication-zero and it has become very popular\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"alan-ridlehoover-tropicalrb-2024\"\n  title: \"A Brewer's Guide to Filtering out Complexity and Churn\"\n  raw_title: \"Alan Ridlehoover & Fito von Zastrow | A Brewer's Guide to Filtering out Complexity and Churn\"\n  speakers:\n    - Alan Ridlehoover\n    - Fito von Zastrow\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-04\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"ysTtQgQQSUA\"\n  language: \"english\"\n  description: |-\n    Complex code is expensive and risky to change. Most programmers are unaware of how their changes increase complexity over time. Eventually, complexity leads to pain and frustration. Without understanding the complexity, developers tend to blame Rails. Come learn how to keep complexity under control.\n\n- id: \"wagner-narde-tropicalrb-2024\"\n  title: \"Panel: Successful Brazilian Rails-powered Startups\"\n  raw_title: \"Panel | Successful Brazilian Rails-powered Startups\"\n  speakers:\n    - Wagner Narde\n    - Bruno Ghisi\n    - Carlos Brando\n    - Thiago Scalone\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-04\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"ONkfM68LieU\"\n  language: \"portuguese\"\n  description: |-\n    Startup panel with Wagner Narde (Glass Data), Bruno Ghisi (RD Station), Carlos Brando (Enjoei) and Thiago Scalone (CloudWalk)\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"danilo-tupinamb-tropicalrb-2024\"\n  title: \"Cloning Cookie Clicker to Debug jobs and Confirm What DHH Said\"\n  raw_title: \"Danilo Tupinambá | Cloning Cookie Clicker to Debug jobs and Confirm What DHH Said\"\n  speakers:\n    - Danilo Tupinambá\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-04\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"6tcLXliXrco\"\n  language: \"portuguese\"\n  description: |-\n    DHH did a talk on Rails World about using Solid Queue instead of the much loved/used Sidekiq + Redis. We did some tests at work, but I want to show in a more playful way how we can test jobs, cloning the Cookie Clicker javascript game and trying to break my web application.\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"weldys-santos-tropicalrb-2024\"\n  title: \"From React to Hotwire: The Adventures of a Frontend Migration\"\n  raw_title: \"Weldys Santos | From React to Hotwire: The Adventures of a Frontend Migration\"\n  speakers:\n    - Weldys Santos\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-04\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"7m-yMmXlZaA\"\n  language: \"portuguese\"\n  description: |-\n    How we managed to turn our frontend from React to Hotwire in 4 steps, after a migration to Rails 7 and we managed to reduce the size of the codebase and organize our frontend into something simpler.\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"mayra-l-navarro-tropicalrb-2024\"\n  title: \"Mastering Internationalization: A Journey through Cultures and i18n\"\n  raw_title: \"Mayra L. Navarro | Mastering Internationalization: A Journey through Cultures and i18n\"\n  speakers:\n    - Mayra L. Navarro\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-04\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"ULTdp9YtNww\"\n  language: \"spanish\"\n  description: |-\n    Crafting a Spanish webapp? Bravo! Picture LatAm expansion—tricky, right? Words change meaning with borders. Rails to the rescue! Unveil i18n wonders, mastering idiolects effortlessly. Say adiós to static strings. Rails equips you to adapt, translate, & flourish across LatAm’s diverse tapestry.\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"alexandre-calaa-tropicalrb-2024\"\n  title: \"Implementing Semantic Search in Rails Using Database Vectors\"\n  raw_title: \"Alexandre Calaça | Implementing Semantic Search in Rails Using Database Vectors\"\n  speakers:\n    - Alexandre Calaça\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-04\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"WFOoMNzl_JA\"\n  language: \"english\"\n  description: |-\n    Unlock the power of semantic search in Rails! Join me on a journey to implement cutting-edge database vectors, revolutionizing search functionality. Elevate your applications with intelligence and precision by using the Large Language Models provided by OpenAI. Don’t miss this transformative talk!\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"aaron-patterson-tropicalrb-2024\"\n  title: \"Keynote: Speeding up IVs\"\n  raw_title: \"Aaron Patterson - Tropical.rb Keynote\"\n  speakers:\n    - Aaron Patterson\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-04\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"Sav8S_7iWJc\"\n  language: \"english\"\n  description: |-\n    Keynote | Aaron Patterson\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n# Day 2\n\n- id: \"breno-gazzola-tropicalrb-2024\"\n  title: \"Opening Keynote\"\n  raw_title: \"Breno Gazzola | Opening Keynote\"\n  speakers:\n    - Breno Gazzola\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-05\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"xidwucjfw2w\"\n  language: \"portuguese\"\n  description: |-\n    Opening Keynote\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"adrian-marin-tropicalrb-2024\"\n  title: \"How To Build A Business on Rails and Open-Source\"\n  raw_title: \"Adrian Marin | How to build a business on Rails and Open-Source\"\n  speakers:\n    - Adrian Marin\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-05\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"9vJylqw915c\"\n  language: \"english\"\n  description: |-\n    As developers, coding is our comfort zone, but turning it into a business is another challenge. I'll share my journey from a side project to a full-time business, including the difficulties, common pitfalls, and helpful \"cheat codes\"\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"jos-anchieta-tropicalrb-2024\"\n  title: \"How to Start Creating Mobile Apps Using Rails and Turbo Native\"\n  raw_title: \"José Anchieta | How to Start Creating Mobile Apps Using Rails and Turbo Native\"\n  speakers:\n    - José Anchieta\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-05\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"Lm-FPn-LmZw\"\n  language: \"portuguese\"\n  description: |-\n    Discover Turbo, Turbo Native, and Strada in this talk, where we’ll dive into essential concepts like webviews and techniques for deploying Rails apps on iOS and Android. Learn about the advantages and challenges of this innovative method, opening new horizons for Rails developers.\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"robby-russell-tropicalrb-2024\"\n  title: \"Panel: Rails Foundation AMA\"\n  raw_title: \"Painel | Rails Foundation AMA\"\n  speakers:\n    - Robby Russell\n    - Amanda Perino\n    - Bruno Miranda\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-05\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"XrTtpRuCJLE\"\n  language: \"english\"\n  description: |-\n    Robby Russell, CEO of Planet Argon, presented questions from the community to Rails Foundation representatives Amanda Perino (Executive Director) and Bruno Miranda (Board Member)\n\n- id: \"radams-roriz-tropicalrb-2024\"\n  title: \"We Need Less Layers, Not More\"\n  raw_title: \"Radamés Roriz | We Need less Layers, Not More\"\n  speakers:\n    - Radamés Roriz\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-05\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"tMcS1oTsKh0\"\n  language: \"portuguese\"\n  description: |-\n    Complexity often silently grows, gradually complicating projects and clouding efficiency. This talk aims to debate the hidden costs of unnecessary layers. By embracing simplicity and leveraging Rails’ inherent strengths, we can enhance our software’s performance, maintainability, and pace.\n\n- id: \"dan-phillips-tropicalrb-2024\"\n  title: \"Deploy Your Next Rails App with WebAssembly (WASM): Smaller, Safer, Faster\"\n  raw_title: \"Dan Phillips | Deploy Your Next Rails App with WebAssembly (Wasm): Smaller, Safer, Faster\"\n  speakers:\n    - Dan Phillips\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-05\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"u46PQE-exbg\"\n  language: \"english\"\n  description: |-\n    This talk focuses on the unique advantages of using WebAssembly (Wasm) for deploying Ruby on Rails applications (yes, on the server). Wasm offers a groundbreaking approach that enables smaller, faster, and more secure server deployments, compared with existing strategies using VMs or Containers\n\n- id: \"john-hawthorn-tropicalrb-2024\"\n  title: \"Vernier: A next Generation Ruby Profiler\"\n  raw_title: \"John Hawthorn | Vernier: A next Generation Ruby Profiler\"\n  speakers:\n    - John Hawthorn\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-05\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"0LMjx3xkjlY\"\n  language: \"english\"\n  description: |-\n    This talk explores how to use a Ruby profiler, how one works, and new techniques Vernier uses to give more information more accurately with lower overhead\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n\n- id: \"matheus-richard-tropicalrb-2024\"\n  title: \"The Fast Lane: Asynchronous Rails\"\n  raw_title: \"Matheus Richard | The Fast Lane: Asynchronous Rails\"\n  speakers:\n    - Matheus Richard\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-05\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"CfC2blkrkys\"\n  language: \"english\"\n  description: |-\n    Oh no! Computers are not doubling in speed every two years anymore! How can we make software run faster? You and your Rails app cannot just wait doing nothing, so join me to explore how we can leverage concurrency and parallelism concepts to enhance performance and scalability!\n\n- id: \"eileen-m-uchitelle-tropicalrb-2024\"\n  title: \"Keynote: The Magic of Rails\"\n  raw_title: \"Eileen Uchitelle - Tropical.rb Keynote\"\n  speakers:\n    - Eileen M. Uchitelle\n  event_name: \"Tropical.rb 2024\"\n  date: \"2024-04-05\"\n  published_at: \"2024-05-01\"\n  video_provider: \"youtube\"\n  video_id: \"ow56D90FYpg\"\n  language: \"english\"\n  description: |-\n    Keynote | Eileen M. Uchitelle\n\n    Tropical.rb - The Latin America Rails Conference\n    https://www.tropicalrb.com/\n"
  },
  {
    "path": "data/umedarb/series.yml",
    "content": "---\nname: \"Umeda.rb\"\nwebsite: \"https://umedarb.connpass.com\"\nkind: \"meetup\"\nfrequency: \"irregular\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/umedarb/umedarb-meetup/event.yml",
    "content": "---\nid: \"umedarb-meetup\"\ntitle: \"Umeda.rb Meetup\"\nlocation: \"Osaka, Japan\"\ndescription: |-\n  A Ruby community centered on Umeda, Osaka, with in-person meetups for Rubyists and people interested in learning together.\nwebsite: \"https://umedarb.connpass.com\"\nkind: \"meetup\"\nbanner_background: \"#FFCFC3\"\nfeatured_background: \"#FFCFC3\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 34.7052911\n  longitude: 135.4983887\n"
  },
  {
    "path": "data/umedarb/umedarb-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/valencia-rb/series.yml",
    "content": "---\nname: \"Valencia.rb\"\nwebsite: \"https://valenciarb.org\"\ntwitter: \"valenciarb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"ES\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/valencia-rb/valencia-rb-meetup/event.yml",
    "content": "---\nid: \"valencia-rb-meetup\"\ntitle: \"Valencia.rb Meetup\"\nlocation: \"Valencia, Spain\"\ndescription: |-\n  A user-group for developers, techies & ruby lovers\nkind: \"meetup\"\npublished_at: \"2024-12-11\"\nyear: 2024\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://valenciarb.org/en/\"\ncoordinates:\n  latitude: 39.4738338\n  longitude: -0.3756348\n"
  },
  {
    "path": "data/valencia-rb/valencia-rb-meetup/videos.yml",
    "content": "---\n# Website: https://valenciarb.org/en\n\n# 2024\n\n- id: \"valencia-rb-december-2024\"\n  title: \"Valencia.rb December 2024\"\n  event_name: \"Valencia.rb December 2024\"\n  date: \"2024-12-11\"\n  video_provider: \"children\"\n  video_id: \"valencia-rb-december-2024\"\n  description: |-\n    Valencia.rb is being re-launched after a nearly 5 years hiatus.\n\n    Our re-launch event couldn't be better! The Ruby Europe initiative has given us the motivation we needed to start talking again about the language we’re so passionate about: Ruby.\n\n    At our next meeting, we are pleased to have Rosa Gutiérrez, a programmer at 37Signals, and [Yauhen Karatkou], Barcelona.rb organizer and Lead Ruby Developer at Tripledot Studios.\n\n    We also have the support of New Work Valencia who will let us meet in their offices.\n\n    We’ll see you on December 11th\n\n    You can’t miss it!\n\n    https://valenciarb.org/en/meetings/2024-12-11-relaunch\n  talks:\n    - title: \"Solid Queue Internals, Externals and all the things in between\"\n      event_name: \"Valencia.rb December 2024\"\n      date: \"2024-12-11\"\n      speakers:\n        - Rosa Gutiérrez\n      id: \"rosa-gutiérrez-valencia-rb-december-2024\"\n      video_id: \"rosa-gutiérrez-valencia-rb-december-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:tin7f6teieaisxohxovzo3wv/bafkreihtcqgpiosbwugmm3ief2xwteb6iqipmvdtdw2zhrw4vzfqla43ou@jpeg\"\n      thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:tin7f6teieaisxohxovzo3wv/bafkreihtcqgpiosbwugmm3ief2xwteb6iqipmvdtdw2zhrw4vzfqla43ou@jpeg\"\n      thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:tin7f6teieaisxohxovzo3wv/bafkreihtcqgpiosbwugmm3ief2xwteb6iqipmvdtdw2zhrw4vzfqla43ou@jpeg\"\n      thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:tin7f6teieaisxohxovzo3wv/bafkreihtcqgpiosbwugmm3ief2xwteb6iqipmvdtdw2zhrw4vzfqla43ou@jpeg\"\n      thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:tin7f6teieaisxohxovzo3wv/bafkreihtcqgpiosbwugmm3ief2xwteb6iqipmvdtdw2zhrw4vzfqla43ou@jpeg\"\n      description: |-\n        We've used Resque and Redis to run background jobs in multiple apps for many years at 37signals. However, performance, reliability, and our own apps’ idiosyncrasies led us to use a lot of different gems, some developed by us, some forked or patched to address our struggles.\n\n        After multiple war stories with background jobs, looking at our increasingly complex setup, we wanted something we could use out-of-the-box without having to port our collection of hacks to every new app and with fewer moving pieces.\n\n        After exploring existing alternatives, we decided to build our own and aim to make it the default for Rails 8.\n\n        In this talk, I’ll present Solid Queue, explain some of the problems we had over the years, how we designed Solid Queue to address them, and all the Fun™ we had doing that.\n\n    - title: \"Demystifying JIT Compilers with Ruby YJIT\"\n      event_name: \"Valencia.rb December 2024\"\n      date: \"2024-12-11\"\n      speakers:\n        - Yauhen Karatkou\n      id: \"yauhen-karatkou-valencia-rb-december-2024\"\n      video_id: \"yauhen-karatkou-valencia-rb-december-2024\"\n      video_provider: \"not_recorded\"\n      thumbnail_xs: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:tin7f6teieaisxohxovzo3wv/bafkreihzz3pbu3vx3ydrskxlg7nw6lr23to5lb2bfd2fmcyiaz2jodvy7u@jpeg\"\n      thumbnail_sm: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:tin7f6teieaisxohxovzo3wv/bafkreihzz3pbu3vx3ydrskxlg7nw6lr23to5lb2bfd2fmcyiaz2jodvy7u@jpeg\"\n      thumbnail_md: \"https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:tin7f6teieaisxohxovzo3wv/bafkreihzz3pbu3vx3ydrskxlg7nw6lr23to5lb2bfd2fmcyiaz2jodvy7u@jpeg\"\n      thumbnail_lg: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:tin7f6teieaisxohxovzo3wv/bafkreihzz3pbu3vx3ydrskxlg7nw6lr23to5lb2bfd2fmcyiaz2jodvy7u@jpeg\"\n      thumbnail_xl: \"https://cdn.bsky.app/img/feed_fullsize/plain/did:plc:tin7f6teieaisxohxovzo3wv/bafkreihzz3pbu3vx3ydrskxlg7nw6lr23to5lb2bfd2fmcyiaz2jodvy7u@jpeg\"\n      description: |-\n        In this talk, we will explore the wonderful world of Just-in-Time compilation, take a look at how Ruby JIT has evolved along with the language itself. And what impact the newest versions of Ruby can have on the performance of real applications\n\n# 2025\n\n- id: \"valencia-rb-february-2025\"\n  title: \"Valencia.rb February 2025\"\n  event_name: \"Valencia.rb February 2025\"\n  date: \"2025-02-05\"\n  published_at: \"2025-02-10\"\n  video_provider: \"children\"\n  video_id: \"valencia-rb-february-2025\"\n  thumbnail_xs: \"https://valenciarb.org/_astro/fido-openssl-ruby_small.DoykDLvb_Z1y7QEP.webp\"\n  thumbnail_sm: \"https://valenciarb.org/_astro/fido-openssl-ruby_small.DoykDLvb_Z1y7QEP.webp\"\n  thumbnail_md: \"https://valenciarb.org/_astro/fido-openssl-ruby_small.DoykDLvb_Z1y7QEP.webp\"\n  thumbnail_lg: \"https://valenciarb.org/_astro/fido-openssl-ruby_small.DoykDLvb_Z1y7QEP.webp\"\n  thumbnail_xl: \"https://valenciarb.org/_astro/fido-openssl-ruby_small.DoykDLvb_Z1y7QEP.webp\"\n  description: |-\n    Ignacio Huerta will explain how a bug report became an unfathomable mystery. In this talk, we will live a debugging adventure with FIDO, Ruby and OpenSSL. Ignacio will share with everyone stories about encryption peculiarities, lessons learned “the hard way” and key insights about the use of Ruby applied to manage “in-car” payments for a major automotive company.\n\n    On this occasion we have the support of Flywire Valencia that kindly lends us the space to meet and have a good time in community.\n\n    See you on Wednesday, February 5th!\n\n    https://valenciarb.org/en/meetings/2025-02-05-fido-openssl-ruby/\n  talks:\n    - title: \"Fido, Ruby, and OpenSSL – When Payments Randomly Fail\"\n      event_name: \"Valencia.rb February 2025\"\n      date: \"2025-02-05\"\n      published_at: \"2025-02-10\"\n      speakers:\n        - Ignacio Huerta\n      id: \"ignacio-huerta-valenciarb-february-2025\"\n      video_id: \"4HDfGcbF3aM\"\n      video_provider: \"youtube\"\n      description: |-\n        Ignacio Huerta will explain how a bug report became an unfathomable mystery. In this talk, we will live a debugging adventure with FIDO, Ruby and OpenSSL. Ignacio will share with everyone stories about encryption peculiarities, lessons learned “the hard way” and key insights about the use of Ruby applied to manage “in-car” payments for a major automotive company.\n"
  },
  {
    "path": "data/vienna-rb/series.yml",
    "content": "---\nname: \"Vienna.rb\"\nwebsite: \"https://ruby.wien\"\nmeetup: \"https://www.meetup.com/vienna-rb/\"\ntwitter: \"viennarb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"\"\ndefault_country_code: \"AT\"\nyoutube_channel_name: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\n"
  },
  {
    "path": "data/vienna-rb/vienna-rb-meetup/event.yml",
    "content": "---\nid: \"vienna-rb-meetup\"\ntitle: \"Vienna.rb Meetup\"\nlocation: \"Vienna, Austria\"\ndescription: |-\n  Vienna.rb: The Vienna Ruby Meetup\nkind: \"meetup\"\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#FF0000\"\nwebsite: \"https://ruby.wien\"\ncoordinates:\n  latitude: 48.20806959999999\n  longitude: 16.3713095\n"
  },
  {
    "path": "data/vienna-rb/vienna-rb-meetup/videos.yml",
    "content": "---\n# Website: https://ruby.wien\n\n# 2024\n\n- id: \"vienna-rb-december-2024\"\n  title: \"Vienna.rb December 2024\"\n  event_name: \"Vienna.rb December 2024\"\n  date: \"2024-12-05\"\n  video_provider: \"children\"\n  video_id: \"vienna-rb-december-2024\"\n  description: |-\n    Vienna.rb is back! Are you interested in the Ruby language or Ruby on Rails? Join us. We have great talks, good vibes, and cookies! 🍪\n\n    Talks\n    ~~~~~\n\n    🗣️ Grzegorz Jakubiak\n    ▶️ Refine Your Monkey Patch\n    🗒️ A practical guide to monkey patching without introducing unexpected bugs. Learn techniques to safely extend your code without unwanted side effects, using Ruby’s refinement feature—a tool Matz has labeled a failure. This talk will equip you with best practices for patching responsibly.\n\n    🗣️ Thomas Leitner\n    ▶️ 10 Years of HexaPDF\n    🗒️ A look at how HexaPDF came to be, from idea to running a business. The journey was (and still is) filled with challenges, happy moments and things one should -in hindsight - definitely not do! 🙂 The talk is light on the technical side of HexaPDF and focuses more on the things I did and learned.\n\n    🗣️ Nicolas Dular\n    ▶️ An Epic Migration\n    🗒️ Join me on our epic adventure of migrating GitLab epics! In this talk, I'll dive into the challenges of executing zero-downtime migrations at scale, why we opted for bi-directional syncing (and the struggles that came with it), and how we coordinated the project. Come for the tech insights, and stay for the stories of how we tracked down out-of-sync data!\n\n    Interested in delivering a talk? Let us know!\n\n    Location\n    ~~~~~~~~\n\n    Mariahilfer Str. 97/4,\n    1060 Wien\n\n    Sponsors\n    ~~~~~~~~~\n\n    ⭐ Meister\n\n    Founded in 2006 by Till Vollmer and Michael Hollauf, Meister’s journey from start-up to scale-up has been a story of continual growth. What started with a vision to create a simple visual mind-mapping tool has become not one but two collaborative tools that help teams everywhere focus on the work that matters.\n\n    Thank you to Meister for hosting and providing us with refreshments and snacks! 🙌\n\n    ⭐ Want to sponsor?\n    We are looking for more sponsors! If you are interested, contact us.\n\n    https://www.meetup.com/vienna-rb/events/304271765\n  talks:\n    - title: \"Refine Your Monkey Patch\"\n      event_name: \"Vienna.rb December 2024\"\n      date: \"2024-12-05\"\n      speakers:\n        - Grzegorz Jakubiak\n      id: \"grzegorz-jakubiak-vienna-rb-december-2024\"\n      video_id: \"grzegorz-jakubiak-vienna-rb-december-2024\"\n      video_provider: \"not_recorded\"\n      description: |-\n        A practical guide to monkey patching without introducing unexpected bugs. Learn techniques to safely extend your code without unwanted side effects, using Ruby’s refinement feature—a tool Matz has labeled a failure. This talk will equip you with best practices for patching responsibly.\n\n    - title: \"10 Years of HexaPDF\"\n      event_name: \"Vienna.rb December 2024\"\n      date: \"2024-12-05\"\n      speakers:\n        - Thomas Leitner\n      id: \"thomas-leitner-vienna-rb-december-2024\"\n      video_id: \"thomas-leitner-vienna-rb-december-2024\"\n      video_provider: \"not_recorded\"\n      description: |-\n        A look at how HexaPDF came to be, from idea to running a business. The journey was (and still is) filled with challenges, happy moments and things one should -in hindsight - definitely not do! 🙂 The talk is light on the technical side of HexaPDF and focuses more on the things I did and learned.\n\n        Blog Post: https://gettalong.org/blog/2024/10-years-of-hexapdf.html\n\n    - title: \"An Epic Migration\"\n      event_name: \"Vienna.rb December 2024\"\n      date: \"2024-12-05\"\n      speakers:\n        - Nicolas Dular\n      id: \"nicolas-dular-vienna-rb-december-2024\"\n      video_id: \"nicolas-dular-vienna-rb-december-2024\"\n      video_provider: \"not_recorded\"\n      description: |-\n        Join me on our epic adventure of migrating GitLab epics! In this talk, I'll dive into the challenges of executing zero-downtime migrations at scale, why we opted for bi-directional syncing (and the struggles that came with it), and how we coordinated the project. Come for the tech insights, and stay for the stories of how we tracked down out-of-sync data!\n\n# 2025\n\n- id: \"vienna-rb-march-2025\"\n  title: \"Vienna.rb March 2025\"\n  event_name: \"Vienna.rb March 2025\"\n  date: \"2025-03-06\"\n  announced_at: \"2025-02-03\"\n  published_at: \"2025-03-10\"\n  video_provider: \"children\"\n  video_id: \"vienna-rb-march-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/8/8/5/600_526206277.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/8/8/5/600_526206277.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/8/8/5/600_526206277.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/8/8/5/600_526206277.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/8/8/5/600_526206277.webp?w=750\"\n  description: |-\n    It's the Vienna.rb spring edition! 🌸 Are you interested in the Ruby language or Ruby on Rails? Join us. We have great talks, good vibes, and yummy snacks! 😋\n\n    We have something special this time: Lightning Talks! ⚡\n\n    Lightning talks are limited to 10 minutes and are an excellent opportunity for first-time speakers to try their hand at public speaking. Check it out!\n\n    Talks & Lightning Talks\n    ~~~~~~~~~~~~~~~~~~~~~~~\n\n    🗣️ Jan Grodowski\n    ▶️ Balancing Quality and Speed of Testing with the Undercover Gem\n    🗒️ We'll take a look at Ruby test coverage strategies and the variables that come into play when preventing faults in our software products. We'll discuss what makes tests good, what to test versus not to and when is the right time to do it. I'll introduce the undercover Ruby gem and additionally share a few stories about turning this idea and gem into a side hustle.\n\n    ⚡ Seth Horsley\n    ▶️ Building Beautiful UIs with ruby: A Rails-native Approach\n    🗒️ Tired of slow ERB templates and messy view logic? Discover how Phlex and RubyUI bring blazing-fast (12x!) and beautiful components to Rails while maintaining the Ruby way we all love. Let's see how we can build modern, accessible UIs without leaving the Rails ecosystem!\n\n    ⚡ Anton Bangratz\n    ▶️ Jujutsu: Will it replace Git?\n    🗒️ Jujutsu is a DVCS, or \"distributed version control system\". You are probably familiar with the biggest of those systems: Git. Jujutsiy is said to be easier and simpler than Git while being even more powerful. In this talk we'll find out if that's true!\n\n    ⚡ Johannes Daxböck\n    ▶️ Logical, Mr Matz: A Foray into Logic Programming in Ruby\n    🗒️ Ruby supports multiple programming paradigms, including object-oriented, functional, and imperative/procedural styles. However, it is rarely associated with logic programming. In this talk, I'll explore the concepts and applications of logic programming through its most prominent language, Prolog, and compare them to Ruby. We'll also dive into some Ruby archaeology, uncovering existing Ruby-based logic programming libraries.\n\n    Location\n    ~~~~~~~~\n\n    Platogo Interactive Entertainment GmbH\n    Sechskrügelgasse 10/17\n    1030 Wien\n\n    Sponsors\n    ~~~~~~~~~\n\n    ⭐ Platogo\n\n    Platogo is an international team based in Vienna, dedicated to creating innovative, multi-platform games enjoyed by millions of players worldwide. With a focus on creativity, collaboration, and fun, we develop top-ranking apps available in over 13 languages. What began as a small group of passionate friends has grown into a team of 20+ extraordinary people, united by curiosity and a shared love for gaming and cutting-edge technology, all while fostering a friendly and supportive workplace.\n\n    Huge thanks to Platogo for hosting and providing us with refreshments and snacks! 🙌\n\n    ⭐ Ruby Central & Fastly\n\n    Ruby Central is a nonprofit organization that has been a driving force in the Ruby community since 2001. It has helped organize major events such as RubyConf and RailsConf. Additionally, Ruby Central maintains tools such as Bundler and RubyGems through its Open Source Program.\n\n    One of Ruby Central's newest initiatives is a grant program to support local meetups like this one, thanks to generous sponsors like Fastly. Thank you to Ruby Central and Fastly for supporting Vienna.rb!\n    ~~~\n\n    ⭐ Looking to sponsor or give a talk?\n\n    We are looking for sponsors and speakers. If you are interested, contact us at organizers@ruby.wien!\n\n    https://www.meetup.com/vienna-rb/events/305607564\n  talks:\n    - title: \"Balancing Quality and Speed of Testing with the Undercover Gem\"\n      event_name: \"Vienna.rb March 2025\"\n      date: \"2025-03-06\"\n      published_at: \"2025-03-10\"\n      speakers:\n        - Jan Grodowski\n      id: \"jan-grodowski-vienna-rb-march-2025\"\n      video_id: \"G7kuYXr5oKA\"\n      video_provider: \"youtube\"\n      description: |-\n        We're joined by Jan Grodowski (https://x.com/mrgrodo), a Staff Engineer at Shopify. Jan dives deep into Ruby testing and shares what he has learned as a Solopreneur maintaining UndercoverCI ( https://undercover-ci.com ).\n\n        Thank you to Platogo for hosting!\n\n        Follow Vienna.rb on:\n        - https://www.meetup.com/vienna-rb\n        - https://x.com/vienna-rb\n        - https://bsky.app/profile/ruby.wien\n\n        Timestamps:\n        00:00 Start\n        23:25 Live Demo\n        49:40 Q&A\n\n    - title: \"Building Beautiful UIs with Ruby: A Rails-Native Approach\"\n      event_name: \"Vienna.rb March 2025\"\n      date: \"2025-03-06\"\n      published_at: \"2025-03-10\"\n      speakers:\n        - Seth Horsley\n      id: \"seth-horsley-vienna-rb-march-2025\"\n      video_id: \"rQOHlmwPHoo\"\n      video_provider: \"youtube\"\n      slides_url: \"https://speakerdeck.com/seth4242/building-a-beautiful-ui-with-phlex-and-rubyui\"\n      description: |-\n        We're joined by Seth Horsley (https://github.com/SethHorsley) from StateCert. Seth shares the future of Rails UIs with us. Creating amazing interfaces with plain Ruby using Ruby UI ( https://github.com/ruby-ui/ruby_ui ).\n\n        Thank you to Platogo for hosting!\n\n        Follow Vienna.rb on:\n        - https://www.meetup.com/vienna-rb\n        - https://x.com/vienna-rb\n        - https://bsky.app/profile/ruby.wien\n\n        Timestamps:\n        00:00 Start\n        4:08 Demo\n        7:13 Q&A\n      additional_resources:\n        - name: \"ruby-ui/ruby_ui\"\n          type: \"repo\"\n          url: \"https://github.com/ruby-ui/ruby_ui\"\n\n    - title: \"Jujutsu: Will it replace Git?\"\n      event_name: \"Vienna.rb March 2025\"\n      date: \"2025-03-06\"\n      published_at: \"2025-03-10\"\n      speakers:\n        - Anton Bangratz\n      id: \"anton-bangratz-vienna-rb-march-2025\"\n      video_id: \"6TMVcYxRjZ0\"\n      video_provider: \"youtube\"\n      description: |-\n        We're joined by Anton \"Tony\" Bangratz (https://github.com/abangratz). Anton is a veteran Ruby developer from Vienna who works at Platogo. In this talk, he shares his experience using Jujutsu ( https://jj-vcs.github.io/jj/latest/ ) and explains why you should probably use it too!\n\n        Thank you to Platogo for hosting!\n\n        Follow Vienna.rb on:\n        - https://www.meetup.com/vienna-rb\n        - https://x.com/vienna-rb\n        - https://bsky.app/profile/ruby.wien\n\n        Timestamps:\n        00:00 Start\n        0:52 What is Jujutsu\n        8:46 Q&A\n\n    - title: \"Logical, Mr Matz: A Foray into Logic Programming in Ruby\"\n      event_name: \"Vienna.rb March 2025\"\n      date: \"2025-03-06\"\n      published_at: \"2025-03-10\"\n      speakers:\n        - Johannes Daxböck\n      id: \"johannes-daxboeck-vienna-rb-march-2025\"\n      video_id: \"_rdIWfyfuK4\"\n      video_provider: \"youtube\"\n      description: |-\n        We're joined by Johannes Daxböck (https://www.linkedin.com/in/johdax). Johannes shares his exploration of logic programming in Ruby with us. If you have worked with Prolog at some point, this one might interest you. If you haven't, then too!\n\n        Thank you to Platogo for hosting!\n\n        Follow Vienna.rb on:\n        - https://www.meetup.com/vienna-rb\n        - https://x.com/vienna-rb\n        - https://bsky.app/profile/ruby.wien\n\n        Timestamps:\n        00:00 Start\n        00:51 Intro to logic programming\n        14:48 Q&A\n\n- id: \"vienna-rb-june-2025\"\n  title: \"Vienna.rb June 2025\"\n  event_name: \"Vienna.rb June 2025\"\n  date: \"2025-06-05\"\n  announced_at: \"2025-05-09\"\n  published_at: \"2025-06-11\"\n  video_provider: \"children\"\n  video_id: \"vienna-rb-june-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/a/0/5/5/highres_527921045.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/a/0/5/5/highres_527921045.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/a/0/5/5/highres_527921045.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/a/0/5/5/highres_527921045.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/a/0/5/5/highres_527921045.webp?w=750\"\n  description: |-\n    It's Summer; it's time for Vienna.rb! 🏖️\n\n    Are you interested in the Ruby language or Ruby on Rails? Join us. We have great talks, good vibes, and yummy snacks! 😋\n\n    We have something very special in store this time.\n\n    First, we're excited to host Hana Harencarova! Hana works at GitHub and is traveling all the way from Switzerland to give a talk. She's in love with Ruby and shares her passion by teaching at Ruby Monstas Zürich and co-organizing the Helvetic Ruby conference.\n\n    Second, we're happy to announce the first-ever Vienna.rb Ruby Quiz! Everyone can participate, and there will be awesome prizes, sponsored by the Ruby Community, to win! 🏆\n\n    Talks\n    ~~~~~~~~~~~~~~~~~~~~~~~\n\n    🗣️ Hana Harencarova\n    ▶️ How To Ship 1000+ Commits to a Rails Monolith Daily\n    🗒️ Rails helps us prototype quickly, but true velocity comes from delivering those changes to customers just as fast. At GitHub, we ship hundreds of commits to our Rails monolith every day through a deployment process built for speed, safety, and reliability. In this talk, you’ll learn the key practices and tools that help us ship fast and confidently at scale.\n\n    🗣️ Alexander Fiedler\n    ▶️ Building Buildings with Rails\n    🗒️ PlanRadar provides a platform for construction management, and that platform is built on Ruby on Rails! Let's learn how the team at PlanRadar uses Rails, and discover why they chose it in the first place.\n\n    Location\n    ~~~~~~~~\n\n    PlanRadar EU Zentrale\n    Kärntner Ring 5-7\n    Top 201\n    1010 Wien, Österreich\n\n    Sponsors\n    ~~~~~~~~~\n\n    ⭐ PlanRadar\n\n    PlanRadar is a leading platform for digital documentation, communication, and reporting in construction, facility management, and real estate projects. It enables customers to work more efficiently, enhance quality, and achieve full project transparency. By improving collaboration and providing access to real-time data, PlanRadar’s easy-to-use platform adds value to every person involved in a building’s lifecycle, with flexible capabilities for all company sizes and processes. Today, PlanRadar serves more than 150,000 users across 75+ countries.\n\n    Huge thanks to PlanRadar for hosting and providing us with refreshments and snacks! 🙌\n\n    ~~~\n\n    ⭐ Looking to sponsor or give a talk?\n\n    We are looking for sponsors and speakers. If you are interested, contact us at organizers@ruby.wien!\n\n    https://www.meetup.com/vienna-rb/events/307283556\n  talks:\n    - title: \"How To Ship 1000+ Commits to a Rails Monolith Daily\"\n      event_name: \"Vienna.rb June 2025\"\n      date: \"2025-06-05\"\n      published_at: \"2025-06-11\"\n      speakers:\n        - Hana Harencarova\n      id: \"hana-harencarova-vienna-rb-june-2025\"\n      video_id: \"iUfP60kJka4\"\n      video_provider: \"youtube\"\n      description: |-\n        We're joined by Hana Harencarova (https://hharen.com/). Hana works at GitHub and is traveling all the way from Switzerland to give a talk on how GitHub ships hundreds of commits to our Rails monolith every day through a deployment process built for speed, safety, and reliability.\n\n        Follow Vienna.rb on:\n        - https://www.meetup.com/vienna-rb\n        - https://x.com/vienna-rb\n        - https://bsky.app/profile/ruby.wien\n\n        Timestamps:\n        00:00 Intro\n        5:02 Talk\n        33:50 Q&A\n\n    - title: \"Building Buildings with Rails\"\n      event_name: \"Vienna.rb June 2025\"\n      date: \"2025-06-05\"\n      published_at: \"2025-06-11\"\n      speakers:\n        - Alexander Fiedler\n      id: \"alexander-fiedler-vienna-rb-june-2025\"\n      video_id: \"rHMF-1vbR3A\"\n      video_provider: \"youtube\"\n      description: |-\n        Alexander Fiedler works at our host Planradar. PlanRadar provides a platform for construction management, and that platform is built on Ruby on Rails! Let's learn how the team at PlanRadar uses Rails, and discover why they chose it in the first place.\n\n        Follow Vienna.rb on:\n        - https://www.meetup.com/vienna-rb\n        - https://x.com/vienna-rb\n        - https://bsky.app/profile/ruby.wien\n\n    - title: \"The Vienna.rb Ruby Quiz\"\n      event_name: \"Vienna.rb June 2025\"\n      date: \"2025-06-05\"\n      published_at: \"2025-06-11\"\n      speakers:\n        - Hans Schnedlitz\n      id: \"ruby-quiz-vienna-rb-june-2025\"\n      video_id: \"8fBmFEXoS-Q\"\n      video_provider: \"youtube\"\n      description: |-\n        Here's something different. We hosted a small Ruby Quiz - with actual prizes provided by the Ruby community! Thanks to Chris Oliver, Joe Masilotti, Andy Croll, and Ally Vogel!\n\n        Follow Vienna.rb on:\n        - https://www.meetup.com/vienna-rb\n        - https://x.com/vienna-rb\n        - https://bsky.app/profile/ruby.wien\n\n        Timestamps:\n        0:00 Intro\n        3:22 Quiz Starts\n        12:35 Results & Prizes\n\n- id: \"vienna-rb-september-2025\"\n  title: \"Vienna.rb September 2025\"\n  event_name: \"Vienna.rb September 2025\"\n  date: \"2025-09-04\"\n  announced_at: \"2025-08-07\"\n  video_provider: \"children\"\n  video_id: \"vienna-rb-september-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/f/2/d/highres_529503885.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/f/2/d/highres_529503885.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/f/2/d/highres_529503885.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/f/2/d/highres_529503885.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/f/2/d/highres_529503885.webp?w=750\"\n  description: |-\n    Vienna.rb #65 - Ruby Autumn Meetup\n\n    It's the Vienna.rb autumn edition! 🍂 Are you interested in the Ruby language or Ruby on Rails? Join us. We have great talks, good vibes, and yummy snacks!\n\n    Taking place alongside Rails World 2025!\n\n    Talks\n    ~~~~~\n\n    🗣️ Clemens Helm\n    ▶️ Smart Queries for Dumb Models\n    🗒️ Complex data filtering in Rails often leads us down a rabbit hole of custom scopes, service objects, and Arel acrobatics. But what if we let the database do what it’s best at? In this talk, you’ll see how SQL views paired with plain ActiveRecord and Ransack can turn messy logic into elegant, powerful queries — without giving up the Rails way.\n\n    🗣️ Wolfgang Hotwagner\n    ▶️ Know Your Weaknesses\n    🗒️  ‘We take care of security at the end of the project’ was the approach in the past. Today, software quality is improved by addressing security from the start. In this talk, I will demonstrate how to easily integrate security into your development process without expert knowledge, using an open-source Ruby application as an example.\n    Location\n\n    ~~~~~~~~\n\n    Platogo Interactive Entertainment GmbH\n    Sechskrügelgasse 10/17\n    1030 Wien\n\n    Sponsors\n    ~~~~~~~~~\n\n    ⭐ Platogo\n\n    Platogo is an international team based in Vienna, dedicated to creating innovative, multi-platform games enjoyed by millions of players worldwide. With a focus on creativity, collaboration, and fun, we develop top-ranking apps available in over 13 languages.\n\n    Thank you to Platogo for hosting and providing us with refreshments and snacks! 🙌\n\n    https://www.meetup.com/vienna-rb/events/310404842\n  talks:\n    - title: \"Smart Queries for Dumb Models\"\n      event_name: \"Vienna.rb September 2025\"\n      date: \"2025-09-04\"\n      announced_at: \"2025-08-07\"\n      published_at: \"2025-09-21\"\n      speakers:\n        - Clemens Helm\n      id: \"clemens-helm-vienna-rb-september-2025\"\n      video_id: \"6LOl7L2zALY\"\n      video_provider: \"youtube\"\n      description: |-\n        Due to a technical hickup, there are no slides for this talk :(\n\n        Clemens Helm is a seasoned Rails developer who believes good code is boring — in the best way. At railscraft.de, he helps teams modernize legacy Rails apps with clean architecture, sharp tools, and zero-nonsense pragmatism. In his talk, he discusses how to simplify your models by leveraging the power of the database using views and more.\n\n        Follow Vienna.rb on:\n          - https://www.meetup.com/vienna-rb\n          - https://x.com/vienna-rb\n          - https://bsky.app/profile/ruby.wien\n\n    - title: \"Know Your Weaknesses\"\n      event_name: \"Vienna.rb September 2025\"\n      date: \"2025-09-04\"\n      announced_at: \"2025-08-07\"\n      published_at: \"2025-09-21\"\n      speakers:\n        - Wolfgang Hotwagner\n      id: \"wolfgang-hotwagner-vienna-rb-september-2025\"\n      video_id: \"dKQJQ_Gn01U\"\n      video_provider: \"youtube\"\n      description: |-\n        Wolfgang Hotwagner is a Linux and Information Security enthusiast from Vienna. On top of all that he's also an avid Rubyist! In his talk he demonstrates how to easily integrate security into your development process without expert knowledge, using an open-source Ruby application as an example.\n\n        Follow Vienna.rb on:\n          - https://www.meetup.com/vienna-rb\n          - https://x.com/vienna-rb\n          - https://bsky.app/profile/ruby.wien\n\n- id: \"vienna-rb-december-2025\"\n  title: \"Vienna.rb December 2025\"\n  event_name: \"Vienna.rb December 2025\"\n  date: \"2025-12-03\"\n  announced_at: \"2025-11-04\"\n  published_at: \"2026-01-01\"\n  video_provider: \"children\"\n  video_id: \"vienna-rb-december-2025\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/1/d/9/d/highres_531127581.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/1/d/9/d/highres_531127581.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/1/d/9/d/highres_531127581.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/1/d/9/d/highres_531127581.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/1/d/9/d/highres_531127581.webp?w=750\"\n  description: |-\n    It's Christmas, it's time for Vienna.rb! 🎄 Are you interested in the Ruby language or Ruby on Rails? Join us. We have great talks, good vibes, and yummy snacks! 😋\n\n    Taking place on December 3rd, this meetup marks the one-year anniversary of this incarnation of Vienna.rb! To celebrate the occasion, we have something special in store for you.\n\n    We're proud to host two world-class speakers, coming to Vienna to give talks at Vienna.rb! Oh, and it's Christmas time, so we are going to have a little cookie exchange! See below for additional information 👇\n\n    Paweł Strzałkowski is the CTO of Visuality, and a full-stack developer since the 90s. He's the author of many articles showcasing a creative approach to using Rails, and a frequent speaker at conferences such as Rails World and the San Francisco Ruby Conference. He's currently excited about AI’s potential and cross-tech discoveries.\n\n    Rosa Gutiérrez is a principal programmer at 37Signals, whom you might know for her work on Solid Queue. She has spoken at conferences such as Rails World, RailsConf, and Tropical Ruby, among many others. She loves cities, mathematics, theoretical computer science, learning languages for humans and computers, puzzles & bicycles. Importantly, she's the human to Mochi 🐕\n\n    Cookie Exchange 🍪\n    ~~~~~~~~~~~~~~~~~~~~~~~\n\n    A cookie exchange is a fun and delicious way to share the joy of Christmas cookies with your fellow Rubyists. Just bring a batch of your favorite holiday cookies to share with others.\n\n    The cookie exchange is entirely voluntary! You're welcome to join, cookies or no cookies 🤗\n\n    Talks\n    ~~~~~~~~~~~~~~~~~~~~~~~\n\n    🗣️ Paweł Strzałkowski\n    ▶️ AI Interface in 5 Minutes - Model Context Protocol on Rails\n    🗒️ This talk delivers a low-risk, high-value AI strategy that applies to any Rails app, new or old. It proves the ecosystem's power to modernize existing assets in the AI era without the need for expensive rewrites. It teaches one of the key aspects of the modern AI tech stack, giving a competitive advantage.\n\n    🗣️ Rosa Gutiérrez\n    ▶️ Machines that talk about themselves\n    🗒️ We'll start with four symbols and a printing machine. From there, we'll explore how a mathematical crisis from the 1930s ended up shaping everything we do as programmers today. No math background needed, just your curiosity.\n\n    Location\n    ~~~~~~~~\n\n    Sentry Vienna\n    Jakov-Lind-Straße 5/4OG,\n    1020 Wien\n\n    Sponsors\n    ~~~~~~~~~\n\n    ⭐ Sentry\n\n    Sentry is more than just error monitoring software. They’re also performance monitoring software. Sentry's platform helps every developer diagnose, fix, and optimize the performance of their code. With Sentry, developers around the world save time, energy, and probably a few therapy sessions.\n\n    Sentry supports more than 100 coding languages, which obviously includes Ruby! They also integrate with a whole bunch of useful tools (and a few necessary evils), including but definitely not limited to GitHub, Slack, and Jira.\n\n    Huge thanks to Sentry for hosting and providing us with refreshments and snacks! 🙌\n\n    ~~~\n\n    ⭐ Looking to sponsor or give a talk?\n\n    We are looking for sponsors and speakers. If you are interested, contact us at organizers@ruby.wien!\n\n    https://www.meetup.com/vienna-rb/events/311836381\n  talks:\n    - title: \"AI Interface in 5 Minutes - Model Context Protocol on Rails\"\n      event_name: \"Vienna.rb December 2025\"\n      date: \"2025-12-03\"\n      announced_at: \"2025-11-04\"\n      speakers:\n        - Paweł Strzałkowski\n      id: \"pawel-strzalkowski-vienna-rb-december-2025\"\n      video_id: \"pawel-strzalkowski-vienna-rb-december-2025\"\n      video_provider: \"not_recorded\"\n      description: |-\n        This talk delivers a low-risk, high-value AI strategy that applies to any Rails app, new or old. It proves the ecosystem's power to modernize existing assets in the AI era without the need for expensive rewrites. It teaches one of the key aspects of the modern AI tech stack, giving a competitive advantage.\n    - title: \"Machines That Talk About Themselves\"\n      event_name: \"Vienna.rb December 2025\"\n      date: \"2025-12-03\"\n      announced_at: \"2025-11-04\"\n      speakers:\n        - Rosa Gutiérrez\n      id: \"rosa-gutierrez-vienna-rb-december-2025\"\n      video_id: \"rosa-gutierrez-vienna-rb-december-2025\"\n      video_provider: \"not_recorded\"\n      description: |-\n        We'll start with four symbols and a printing machine. From there, we'll explore how a mathematical crisis from the 1930s ended up shaping everything we do as programmers today. No math background needed, just your curiosity.\n\n# 2026\n\n- id: \"vienna-rb-march-2026\"\n  title: \"Vienna.rb March 2026\"\n  event_name: \"Vienna.rb March 2026\"\n  date: \"2026-03-05\"\n  announced_at: \"2026-02-09\"\n  published_at: \"2026-03-11\"\n  video_provider: \"children\"\n  video_id: \"vienna-rb-march-2026\"\n  thumbnail_xs: \"https://secure.meetupstatic.com/photos/event/b/6/3/0/highres_532666640.webp?w=750\"\n  thumbnail_sm: \"https://secure.meetupstatic.com/photos/event/b/6/3/0/highres_532666640.webp?w=750\"\n  thumbnail_md: \"https://secure.meetupstatic.com/photos/event/b/6/3/0/highres_532666640.webp?w=750\"\n  thumbnail_lg: \"https://secure.meetupstatic.com/photos/event/b/6/3/0/highres_532666640.webp?w=750\"\n  thumbnail_xl: \"https://secure.meetupstatic.com/photos/event/b/6/3/0/highres_532666640.webp?w=750\"\n  description: |-\n    Vienna.rb #67 - Ruby Spring Meetup\n\n    Join us for the first meetup in 2026! ⭐️\n\n    Are you interested in the Ruby language or Ruby on Rails? Join us. We have great talks, good vibes, and yummy snacks! 😋\n\n    Talks\n    ~~~~~~~~~~~~~~~~~~~~~~~\n\n    🗣️ Peter Solnica\n    ▶️ Structured Logging in Ruby: Where We Are and Where We're Heading\n    🗒️ Ruby's logging ecosystem is evolving, and there's a lot of momentum to build on. In this talk, we'll explore the current state of logging in Ruby and compare it with ecosystems like Elixir, where a more capable, well-designed logger is built right into the standard library. We'll dive into recent developments in Rails - including its new structured events API - and how they connect to the broader picture of structured logging, error handling, and tracing. Along the way, we'll build a vision for what Ruby's standard library could offer: a powerful, extendable logger that makes structured logging a natural part of every Ruby project.\n\n    🗣️ Marie-Therese Fischer\n    ▶️ Building Games with Ruby\n    🗒️ What do you end up with when you strip Rails from a Rails developer? Plain Ruby. Join me as I explore the language behind the framework through the lens of game development. By building a simple terminal game and a 2D platformer, I'll break down the essential building blocks every game is built on - from loops and input handling to visuals. We'll look at how stepping away from the 'magic' of Rails to build games can lead to a deeper understanding of Ruby logic and application structure.\n\n    🗣️ Christoph Lipautz\n    ▶️ The Art of Testing Nothing\n    🗒️ Traditional CI/CD pipelines often waste significant resources re-validating unchanged code, creating a bottleneck in the development lifecycle. This session explores the results of my attempts to shift from exhaustive execution to smart omission. I'll discuss how doing nothing turns into a technical strategic advantage while maintaining confidence.\n\n    Location\n    ~~~~~~~~\n\n    Mariahilfer Str. 97/4,\n    1060 Wien\n\n    Sponsors\n    ~~~~~~~~~\n\n    ⭐ Meister\n\n    Founded in 2006 by Till Vollmer and Michael Hollauf, Meister's journey from start-up to scale-up has been a story of continual growth. What started with a vision to create a simple visual mind-mapping tool has become not one but two collaborative tools that help teams everywhere focus on the work that matters.\n\n    Thank you to Meister for hosting and providing us with refreshments and snacks! 🙌\n\n    ⭐ Want to sponsor?\n    We are looking for more sponsors! If you are interested, contact us at organizers@ruby.wien!\n\n    https://www.meetup.com/vienna-rb/events/313282866\n  talks:\n    - title: \"Structured Logging in Ruby: Where We Are and Where We're Heading\"\n      event_name: \"Vienna.rb March 2026\"\n      date: \"2026-03-05\"\n      announced_at: \"2026-02-09\"\n      published_at: \"2026-03-11\"\n      speakers:\n        - Peter Solnica\n      id: \"peter-solnica-vienna-rb-march-2026\"\n      video_id: \"A367dhj3W4g\"\n      video_provider: \"youtube\"\n      description: |-\n        Ruby's logging ecosystem is evolving, and there's a lot of momentum to build on. In this talk, we'll explore the current state of logging in Ruby and compare it with ecosystems like Elixir, where a more capable, well-designed logger is built right into the standard library. We'll dive into recent developments in Rails - including its new structured events API - and how they connect to the broader picture of structured logging, error handling, and tracing. Along the way, we'll build a vision for what Ruby's standard library could offer: a powerful, extendable logger that makes structured logging a natural part of every Ruby project.\n    - title: \"Building Games with Ruby\"\n      event_name: \"Vienna.rb March 2026\"\n      date: \"2026-03-05\"\n      announced_at: \"2026-02-09\"\n      published_at: \"2026-03-11\"\n      speakers:\n        - Marie-Therese Fischer\n      id: \"marie-therese-fischer-vienna-rb-march-2026\"\n      video_id: \"ujNdn3OJn9A\"\n      video_provider: \"youtube\"\n      description: |-\n        What do you end up with when you strip Rails from a Rails developer? Plain Ruby. Join me as I explore the language behind the framework through the lens of game development. By building a simple terminal game and a 2D platformer, I'll break down the essential building blocks every game is built on - from loops and input handling to visuals. We'll look at how stepping away from the 'magic' of Rails to build games can lead to a deeper understanding of Ruby logic and application structure.\n    - title: \"The Art of Testing Nothing\"\n      event_name: \"Vienna.rb March 2026\"\n      date: \"2026-03-05\"\n      announced_at: \"2026-02-09\"\n      published_at: \"2026-03-11\"\n      speakers:\n        - Christoph Lipautz\n      id: \"christoph-lipautz-vienna-rb-march-2026\"\n      video_id: \"1CzJJ2KM3F8\"\n      video_provider: \"youtube\"\n      description: |-\n        Traditional CI/CD pipelines often waste significant resources re-validating unchanged code, creating a bottleneck in the development lifecycle. This session explores the results of my attempts to shift from exhaustive execution to smart omission. I'll discuss how doing nothing turns into a technical strategic advantage while maintaining confidence.\n"
  },
  {
    "path": "data/wakayama-rb/series.yml",
    "content": "---\nname: \"Wakayama.rb\"\nwebsite: \"https://wakayama-rb.connpass.com\"\nkind: \"meetup\"\nfrequency: \"irregular\"\ndefault_country_code: \"JP\"\nlanguage: \"japanese\"\n"
  },
  {
    "path": "data/wakayama-rb/wakayama-rb-meetup/event.yml",
    "content": "---\nid: \"wakayama-rb-meetup\"\ntitle: \"Wakayama.rb Meetup\"\nlocation: \"Wakayama, Japan\"\ndescription: |-\n  A study community in Wakayama for people interested in Ruby, Rails, and mruby. It mainly runs self-directed study sessions and sometimes collaborates with other local engineering communities.\nwebsite: \"https://wakayama-rb.connpass.com\"\nkind: \"meetup\"\nbanner_background: \"#FF7F26\"\nfeatured_background: \"#FF7F26\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 34.2342931\n  longitude: 135.1783549\n"
  },
  {
    "path": "data/wakayama-rb/wakayama-rb-meetup/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/windycityrails/series.yml",
    "content": "---\nname: \"WindyCityRails\"\nwebsite: \"http://www.windycityrails.org/\"\ntwitter: \"windycityrails\"\nyoutube_channel_name: \"\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"\"\nlanguage: \"english\"\nyoutube_channel_id: \"\"\naliases:\n  - Windy City Rails\n  - WindyCity Rails\n"
  },
  {
    "path": "data/windycityrails/windycityrails-2009/event.yml",
    "content": "---\nid: \"windycityrails-2009\"\ntitle: \"Windy City Rails 2009\"\ndescription: \"\"\nlocation: \"Chicago, IL, United States\"\nkind: \"conference\"\nstart_date: \"2009-09-12\"\nend_date: \"2009-09-12\"\noriginal_website: \"http://windycityrails.org/\"\ncoordinates:\n  latitude: 41.88325\n  longitude: -87.6323879\n"
  },
  {
    "path": "data/windycityrails/windycityrails-2009/videos.yml",
    "content": "---\n[]\n"
  },
  {
    "path": "data/windycityrails/windycityrails-2014/event.yml",
    "content": "---\nid: \"windycityrails-2014\"\ntitle: \"WindyCityRails 2014\"\ndescription: \"\"\nlocation: \"Chicago, IL, United States\"\nkind: \"conference\"\nstart_date: \"2014-09-04\"\nend_date: \"2014-09-05\"\nwebsite: \"http://www.windycityrails.org/\"\nplaylist: \"http://www.windycityrails.org/videos/2014/\"\ncoordinates:\n  latitude: 41.88325\n  longitude: -87.6323879\n"
  },
  {
    "path": "data/windycityrails/windycityrails-2014/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.windycityrails.org/\n# Videos: http://www.windycityrails.org/videos/2014/\n---\n[]\n"
  },
  {
    "path": "data/windycityrails/windycityrails-2015/event.yml",
    "content": "---\nid: \"windycityrails-2015\"\ntitle: \"WindyCityRails 2015\"\ndescription: \"\"\nlocation: \"Chicago, IL, United States\"\nkind: \"conference\"\nstart_date: \"2015-09-17\"\nend_date: \"2015-09-18\"\nwebsite: \"http://www.windycityrails.org/\"\nplaylist: \"https://windycityrails.com/videos/2015/\"\ncoordinates:\n  latitude: 41.88325\n  longitude: -87.6323879\n"
  },
  {
    "path": "data/windycityrails/windycityrails-2015/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.windycityrails.org/\n# Videos: https://windycityrails.com/videos/2015/\n---\n[]\n"
  },
  {
    "path": "data/windycityrails/windycityrails-2016/event.yml",
    "content": "---\nid: \"windycityrails-2016\"\ntitle: \"WindyCityRails 2016\"\ndescription: \"\"\nlocation: \"Chicago, IL, United States\"\nkind: \"conference\"\nstart_date: \"2016-09-15\"\nend_date: \"2016-09-16\"\nwebsite: \"http://www.windycityrails.org/\"\nplaylist: \"https://windycityrails.com/videos/2016/\"\ncoordinates:\n  latitude: 41.88325\n  longitude: -87.6323879\n"
  },
  {
    "path": "data/windycityrails/windycityrails-2016/videos.yml",
    "content": "# TODO: Add talks and videos\n\n# Website: http://www.windycityrails.org/\n# Videos: https://windycityrails.com/videos/2016/\n---\n[]\n"
  },
  {
    "path": "data/winnipeg-rb/series.yml",
    "content": "---\nname: \"Winnipeg.rb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"CA\"\nlanguage: \"english\"\nwebsite: \"https://winnipegrb.org/\"\ntwitter: \"winnipegrb\"\nmeetup: \"https://www.meetup.com/winnipegrb/\"\n"
  },
  {
    "path": "data/winnipeg-rb/winnipeg-rb-meetup/event.yml",
    "content": "---\nid: \"winnipeg-rb-meetup\"\ntitle: \"Winnipeg.rb Meetup\"\nlocation: \"Winnipeg, Canada\"\ndescription: |-\n  Founded in January 2010, Winnipeg.rb is a group of developers in Winnipeg, Manitoba with a common interest in all things Ruby, Rails, and related technologies. Everyone is welcome, from professional ruby programmers to those just beginning to program. The only requirement is passion.\nkind: \"meetup\"\nwebsite: \"https://winnipegrb.org/\"\nbanner_background: \"#252865\"\nfeatured_background: \"#252865\"\nfeatured_color: \"#FFFFFF\"\ncoordinates:\n  latitude: 49.896613120644595\n  longitude: -97.13656209024838\n"
  },
  {
    "path": "data/winnipeg-rb/winnipeg-rb-meetup/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Gannon McGibbon\n"
  },
  {
    "path": "data/winnipeg-rb/winnipeg-rb-meetup/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      level: 1 # Lower numbers = higher priority tiers\n      sponsors:\n        - name: \"Shopify\"\n          website: \"https://shopify.com\"\n          slug: \"shopify\"\n        - name: \"Launch Coworking\"\n          website: \"https://launchcoworking.ca\"\n          slug: \"launch-coworking\"\n        - name: \"Ruby Central\"\n          website: \"https://rubycentral.org\"\n          slug: \"ruby-central\"\n"
  },
  {
    "path": "data/winnipeg-rb/winnipeg-rb-meetup/venue.yml",
    "content": "---\nname: \"Launch Coworking\"\ndescription: |-\n  Exchange | Winnipeg | Shared Workspace | Office Space | Meeting & Event Space\ninstructions: \"Doors open at 6, and the talk starts at 6:30. Food and drinks will be provided at the venue.\"\naddress:\n  street: \"167 Lombard Ave suite 500\"\n  city: \"Winnipeg\"\n  region: \"MB\"\n  postal_code: \"R3B 3H8\"\n  country: \"Canada\"\n  country_code: \"CA\"\n  display: \"167 Lombard Ave suite 500 · Winnipeg, MB\"\ncoordinates:\n  latitude: 49.896613120644595\n  longitude: -97.13656209024838\nmaps:\n  google: \"https://maps.app.goo.gl/TYEfP5FdnXkDxpPy7\"\n"
  },
  {
    "path": "data/winnipeg-rb/winnipeg-rb-meetup/videos.yml",
    "content": "---\n- id: \"winnipeg-rb-meetup-august-2025\"\n  title: \"Winningpeg.rb Meetup August 2025\"\n  date: \"2025-08-20\"\n  description: |-\n    Winnipeg.rb Meetup August 2025\n  event_name: \"Winnipeg.rb Meetup August 2025\"\n  video_id: \"winnipeg-rb-meetup-august-2025\"\n  video_provider: \"children\"\n  talks:\n    - id: \"teaching-an-llm-new-tricks-winnipeg-rb-august-2025\"\n      title: \"Teaching an LLM New Tricks\"\n      date: \"2025-08-20\"\n      description: |-\n        Large Language Models (LLMs) are everywhere these days. Did you know that you can use them to interact with web applications too? In this talk, you'll learn about how to use the Model Context Protocol (MCP) and Ruby to teach AI agents new skills.\n      speakers:\n        - TODO\n      video_id: \"teaching-an-llm-new-tricks-winnipeg-rb-august-2025\"\n      video_provider: \"not_recorded\"\n\n- id: \"winnipeg-rb-meetup-october-2025\"\n  title: \"Winningpeg.rb Meetup October 2025\"\n  date: \"2025-10-29\"\n  description: |-\n    Winnipeg.rb Meetup October 2025\n  event_name: \"Winnipeg.rb Meetup October 2025\"\n  video_id: \"winnipeg-rb-meetup-october-2025\"\n  video_provider: \"children\"\n  talks:\n    - id: \"from-alert-fatigue-to-intelligent-investigation-winnipeg-rb-october-2025\"\n      title: \"From Alert Fatigue to Intelligent Investigation\"\n      date: \"2025-10-29\"\n      description: |-\n        When faults emerge in a distributed system with hundreds of microservices, thousands of pods, and millions of users, how do you find the actual problem without manually correlating metrics, logs, and traces across dozens of dashboards? This talk presents an automated investigation system that mimics how one SRE team is leveraging a blend of AI and Rails to debug production incidents as they happen.\n      event_name: \"Winnipeg.rb Meetup October 2025\"\n      speakers:\n        - TODO\n      video_id: \"from-alert-fatigue-to-intelligent-investigation-winnipeg-rb-october-2025\"\n      video_provider: \"not_recorded\"\n- id: \"winnipeg-rb-meetup-march-2026\"\n  title: \"Winnipeg.rb Meetup March 2026\"\n  date: \"2026-03-25\"\n  video_id: \"winnipeg-rb-meetup-march-2026\"\n  video_provider: \"scheduled\"\n  description: |-\n    Have you ever written code in a lower level language like C? Have you ever used machine code in a higher level language like Ruby? In this talk, we'll discuss how to build native extensions with Ruby, along with the benefits and tradeoffs. Doors open at 6, and the talk starts at 6:30. Food and drinks will be provided at the venue. This meetup is sponsored by Shopify, Launch Coworking, and Ruby Central.\n\n    https://www.meetup.com/winnipegrb/events/313724846/\n  talks: []\n"
  },
  {
    "path": "data/wnb-rb/series.yml",
    "content": "---\nname: \"WNB.rb\"\nwebsite: \"https://wnb-rb.dev\"\ntwitter: \"wnb_rb\"\nkind: \"meetup\"\nfrequency: \"monthly\"\nplaylist_matcher: \"WNB.rb\"\ndefault_country_code: \"\"\nyoutube_channel_name: \"wnbrb\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCZRVIPB8yQZpFZ-MnGuZMrg\"\naliases:\n  - wnbrb\n  - wnb.rb\n  - Wnb.rb\n  - wnb-rb\n  - wnb_rb\n  - Women & non-binary Rubyists\n  - Women & non-binary Ruby\n"
  },
  {
    "path": "data/wnb-rb/wnb-rb-meetup/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKUblwQt2zw8TcQUk7rUA166\"\ntitle: \"WNB.rb Meetup\"\nlocation: \"online\"\ndescription: |-\n  A virtual community for women & non-binary Rubyists.\nkind: \"meetup\"\nchannel_id: \"UCC3ljLfioI4qN2_zmG_kseQ\"\nbanner_background: \"#FFFFE5\"\nfeatured_background: \"#FFFFE5\"\nfeatured_color: \"#2E0880\"\nwebsite: \"https://www.wnb-rb.dev\"\ncoordinates: false\n"
  },
  {
    "path": "data/wnb-rb/wnb-rb-meetup/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Emerald\"\n      description: |-\n        Annual sponsorships of $5000 per year\n      level: 1\n      sponsors:\n        - name: \"Gusto\"\n          website: \"https://gusto.com/\"\n          slug: \"gusto\"\n          logo_url: \"https://www.wnb-rb.dev/packs/static/images/Gusto-logo-fbfed097feb08a784df3.png\"\n    - name: \"Opal\"\n      description: |-\n        Annual sponsorships of $1000 per year\n      level: 3\n      sponsors:\n        - name: \"Avo\"\n          website: \"https://avohq.io/\"\n          slug: \"Avo\"\n          logo_url: \"https://www.wnb-rb.dev/packs/static/images/avo-logo-026cd3797aa002c6deed.png\"\n        - name: \"FastRuby.io\"\n          website: \"https://www.fastruby.io/\"\n          slug: \"fastruby-io\"\n"
  },
  {
    "path": "data/wnb-rb/wnb-rb-meetup/videos.yml",
    "content": "---\n- id: \"wnb-rb-meetup-march-2021\"\n  title: \"WNB.rb Meetup March 2021\"\n  raw_title: \"WNB.rb Meetup March 2021\"\n  speakers:\n    - Brittany Martin\n  event_name: \"WNB.rb Meetup March 2021\"\n  date: \"2021-03-30\"\n  video_id: \"wnb-rb-meetup-march-2021\"\n  video_provider: \"children\"\n  description: |-\n    This is a collection of talks from the WNB.rb Meetup on March 30, 2021.\n\n    https://www.wnb-rb.dev/meetups/2021/03/30\n  talks:\n    - title: \"Gemless\"\n      raw_title: \"Gemless - Brittany Martin\"\n      speakers:\n        - Brittany Martin\n      event_name: \"WNB.rb Meetup March 2021\"\n      date: \"2021-03-30\"\n      description: |-\n        Brittany Martin talks about lessons learned as an Eng Lead during a project to build a lightweight script using AWS Lambda and Cloudwatch to funnel data from a variety of sources into S3 to create a data dashboard.\n\n        https://www.wnb-rb.dev/meetups/2021/03/30\n      video_provider: \"not_published\"\n      id: \"brittany-martin-wnb-rb-meetup-march-2021\"\n      video_id: \"brittany-martin-wnb-rb-meetup-march-2021\"\n\n    - title: \"Five Errors You Encounter When Upgrading Your Ruby Gems\"\n      raw_title: \"Five Errors You Encounter When Upgrading Your Ruby Gems - Emily Giurleo\"\n      speakers:\n        - Emily Giurleo\n      event_name: \"WNB.rb Meetup March 2021\"\n      date: \"2021-03-30\"\n      slides_url: \"https://docs.google.com/presentation/d/183ExC_6BEVV9L_E7jFbZDRK3g2S7RNaWuk_ENgnf8C4/edit\"\n      description: |-\n        Sometimes, upgrading your gems can cause errors in your application. These errors pop up when you're least expecting them, and they can often be categorized into common groups… kind of like Pokemon! In this talk, we'll discuss five types of errors you might see while upgrading dependencies, as well as the techniques (or \"moves\") we can use to solve them.\n\n        https://www.wnb-rb.dev/meetups/2021/03/30\n      video_provider: \"not_published\"\n      id: \"emily-giurleo-wnb-rb-meetup-march-2021\"\n      video_id: \"emily-giurleo-wnb-rb-meetup-march-2021\"\n\n# TODO: missing event: April 2021 Meetup - https://www.wnb-rb.dev/meetups/2021/04/27\n# TODO: missing event: May 2021 Meetup - https://www.wnb-rb.dev/meetups/2021/05/25\n# TODO: missing event: June 2021 Meetup - https://www.wnb-rb.dev/meetups/2021/06/28\n# TODO: missing event: Panel on Technical Speaking - https://www.wnb-rb.dev/meetups/2021/07/27\n# TODO: missing event: August 2021 Meetup - https://www.wnb-rb.dev/meetups/2021/08/31\n# TODO: missing event: September 2021 Meetup - https://www.wnb-rb.dev/meetups/2021/09/28\n# TODO: missing event: October 2021 Meetup - https://www.wnb-rb.dev/meetups/2021/10/26\n# TODO: missing event: WNB.rb Founders Panel - https://www.wnb-rb.dev/meetups/2021/11/30\n# TODO: missing event: December 2021 Meetup - https://www.wnb-rb.dev/meetups/2021/12/14\n# TODO: missing event: January 2022 Meetup - https://www.wnb-rb.dev/meetups/2022/01/25\n# TODO: missing event: WNB.rb Lightning Talks - https://www.wnb-rb.dev/meetups/2022/02/22\n# TODO: missing event: March 2022 Meetup - https://www.wnb-rb.dev/meetups/2022/03/29\n# TODO: missing event: Salary Negotiation Workshop - https://www.wnb-rb.dev/meetups/2022/04/26\n# TODO: missing event: May 2022 Meetup - https://www.wnb-rb.dev/meetups/2022/05/31\n# TODO: missing event: Special Meetup: Shopify Edition - https://www.wnb-rb.dev/meetups/2022/06/14\n# TODO: missing event: June 2022 Meetup - https://www.wnb-rb.dev/meetups/2022/06/28\n# TODO: missing event: July 2022 Meetup - https://www.wnb-rb.dev/meetups/2022/07/26\n# TODO: missing event: August 2022 Meetup - https://www.wnb-rb.dev/meetups/2022/08/30\n\n- id: \"wnb-rb-meetup-september-2022\"\n  title: \"WNB.rb Meetup September 2022\"\n  raw_title: \"WNB.rb Meetup September 2022\"\n  event_name: \"WNB.rb Meetup September 2022\"\n  date: \"2022-09-27\"\n  video_id: \"wnb-rb-meetup-september-2022\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2022/09/27\n  talks:\n    - title: \"Embarking on Your Journey Through the World of Unit Testing\"\n      raw_title: \"Embarking on Your Journey Through the World of Unit Testing - Kim Diep\"\n      speakers:\n        - Kim Diep\n      event_name: \"WNB.rb Meetup September 2022\"\n      date: \"2022-09-27\"\n      published_at: \"2023-01-07\"\n      description: |-\n        This talk was given at the WNB.rb meetup on September 27, 2022.\n\n        Are you new to unit testing? Maybe you've already written some unit tests and would like to refresh and expand your understanding? Well, you're in luck because this talk is just for you. How can we ensure that the software we build is fit-for-purpose, robust and meets users' needs? Well, that's where software testing comes in handy and even better, automated software testing. In this practical talk, I will demystify what software testing is and the purpose of unit testing. We'll have a look at the unit testing structure and a code example in the RSpec unit testing framework and I'll be sharing some unit testing top tips to help you get the most out of it.By this end of this talk, you'll be able to give software testing a go, start to use it in your learning projects or advocate for it within your teams. It's not as yucky as it sounds; automated testing is a key part of building great software and making your Software Engineering life sweeter!\n\n        Kim Diep is a Software Engineer at Butternut Box and she lives in London, England, UK. By day, she builds software with Ruby code. She also loves building things with the C# programming language, .NET ecosystem and Unity. She only just started Ruby a little over 3 months ago. Before then, she was working primarily in C#. She is passionate about creating things for tech education and loves sharing her experiences with the community to encourage others to learn and grow in their technical skills and confidence. She currently volunteers as a mentor for those who are underrepresented in tech and/or come from socially disadvantaged backgrounds. In Winter 2021, Kim created Curiously Code as a discovery platform providing technology, career and wellbeing inspiration for Curious Humans. By night and on the weekends, you can find Kim practising Kendo, working out at the gym or something random like playing video games and doing some Instax photography!\n\n        https://www.wnb-rb.dev/meetups/2022/09/27\n      video_provider: \"youtube\"\n      id: \"kim-diep-wnbrb-meetup-september-2022\"\n      video_id: \"gzzdEwZW7Uc\"\n\n- id: \"wnb-rb-meetup-october-2022\"\n  title: \"WNB.rb Meetup October 2022\"\n  raw_title: \"WNB.rb Meetup October 2022\"\n  event_name: \"WNB.rb Meetup October 2022\"\n  date: \"2022-10-25\"\n  video_id: \"wnb-rb-meetup-october-2022\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2022/10/25\n  talks:\n    - title: \"Stay DRY with Helper Methods\"\n      raw_title: \"Stay DRY with Helper Methods by Sam Galindo\"\n      speakers:\n        - Sam Galindo\n      event_name: \"WNB.rb Meetup October 2022\"\n      date: \"2022-10-25\"\n      published_at: \"2023-01-07\"\n      description: |-\n        This presentation offers a humble explanation of what helper methods are and how they can help you build a lighter and cleaner app.\n\n        Sam Galindo's pronouns are she/her/they/them. Sam is from Mexico but now lives in the U.S in Durham, North Carolina. She is a baby developer, and new to the Tech Industry. She is a libra that loves dancing, and going on hikes. When she is not glued to her computer reading about technology she is taking deep breaths or laughing with her 6-year-old kid\n\n        https://www.wnb-rb.dev/meetups/2022/10/25\n      video_provider: \"youtube\"\n      id: \"sam-galindo-wnbrb-meetup-october-2022\"\n      video_id: \"UzNeiPFOaW0\"\n\n    - title: \"Insights from Metaprogramming Ruby\"\n      raw_title: \"Insights from Metaprogramming Ruby - Mayra Navarro\"\n      speakers:\n        - Mayra Lucia Navarro\n      event_name: \"WNB.rb Meetup October 2022\"\n      date: \"2022-10-25\"\n      published_at: \"2023-01-08\"\n      description: |-\n        The book Metaprogramming Ruby by Paolo Perrotta changed my perspective on Ruby and led to the discovery of numerous better practices; I'd like to share some of what I've learned with the community.\n\n        Mayra Navarro is from Lima, Perú. Ruby and Rails developer for the last three years. Ruby Peru community's organizer. She enjoys Zumba classes when she is not coding with her cat. (Yes, her cat solves the bugs.)\n\n        https://www.wnb-rb.dev/meetups/2022/10/25\n      video_provider: \"youtube\"\n      id: \"mayra-lucia-navarro-wnbrb-meetup-october-2022\"\n      video_id: \"ZgkkED4NoOg\"\n\n# 2023\n\n- id: \"wnb-rb-meetup-january-2023\"\n  title: \"WNB.rb Meetup January 2023\"\n  raw_title: \"WNB.rb Meetup January 2023\"\n  event_name: \"WNB.rb Meetup January 2023\"\n  date: \"2023-01-31\"\n  video_id: \"wnb-rb-meetup-january-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/01/31\n  talks:\n    - title: \"Combatting attacks against Ruby Gems with Multi-factor Authentication\"\n      raw_title: \"Combatting attacks against Ruby Gems with Multi-factor Authentication by Jenny Shen\"\n      speakers:\n        - Jenny Shen\n      event_name: \"WNB.rb Meetup January 2023\"\n      date: \"2023-01-31\"\n      published_at: \"2023-02-18\"\n      description: |-\n        What do rest-client, strong-password and bootstrap-sass gems have in common? They all suffered malicious code injections that were preventable. Attackers aim to take control of a legitimate RubyGems.org user account, and use it to publish malicious gem version for their own benefit.\n\n        Multi-factor authentication (or MFA) prevents these account takeover attacks. In this talk, I'll be sharing a bit about how MFA works in a package ecosystem like RubyGems and how we started to enforce MFA on the RubyGems platform.\n\n        Jenny is a developer at Shopify where she works to help secure Ruby's supply chain. Over the past year, she has enjoyed contributing to RubyGems. As a relatively new Torontonian, she often spends her free time acting like a tourist, eating different cuisines and trying new activities in the city.\n\n        https://www.wnb-rb.dev/meetups/2023/01/31\n      video_provider: \"youtube\"\n      id: \"jenny-shen-wnbrb-meetup-january-2023\"\n      video_id: \"Uv0dLip4iXQ\"\n\n- id: \"wnb-rb-meetup-february-2023\"\n  title: \"WNB.rb Meetup February 2023\"\n  raw_title: \"WNB.rb Meetup February 2023\"\n  event_name: \"WNB.rb Meetup February 2023\"\n  date: \"2023-02-28\"\n  video_id: \"wnb-rb-meetup-february-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/02/28\n  talks:\n    - title: \"Ruby Security Gems\"\n      raw_title: \"Ruby Security Gems by Angela Choi\"\n      speakers:\n        - Angela Choi\n      event_name: \"WNB.rb Meetup February 2023\"\n      date: \"2023-02-28\"\n      published_at: \"2023-03-06\"\n      description: |-\n        Is your web application secured? Learn and discover some security gems you can implement in your project or at work. This talk will cover an overview of two security gems and when to use each of them.\n        https://www.wnb-rb.dev/meetups/2023/02/28\n      video_provider: \"youtube\"\n      id: \"angela-choi-wnbrb-meetup-february-2023\"\n      video_id: \"0XUKSy2M0Og\"\n\n    - title: \"Functional programming for fun and profit!!\"\n      raw_title: \"Functional programming for fun and profit!! by Jenny Shih\"\n      speakers:\n        - Jenny Shih\n      event_name: \"WNB.rb Meetup February 2023\"\n      date: \"2023-02-28\"\n      published_at: \"2023-03-06\"\n      description: |-\n        Functional programming brings you not just fun, but also profit! Have you ever felt curious towards functional programming (FP)? Were you, soon afterwards, intimidated by the mystic terms like monads and functors? Do you think FP is not related to your Ruby work and thus, useless? Guess what-you can actually apply FP to your Ruby projects and reap benefits from it before fully understanding what a monad is!This talk will walk you through the powerful mental models and tools that FP gives us, and how we can readily use them to improve our apps in a language that we all love and understand.\n        https://www.wnb-rb.dev/meetups/2023/02/28\n      video_provider: \"youtube\"\n      id: \"jenny-shih-wnbrb-meetup-february-2023\"\n      video_id: \"Vp7h9sARkwM\"\n\n- id: \"wnb-rb-meetup-march-2023\"\n  title: \"WNB.rb Meetup March 2023\"\n  raw_title: \"WNB.rb Meetup March 2023\"\n  event_name: \"WNB.rb Meetup March 2023\"\n  date: \"2023-03-28\"\n  video_id: \"wnb-rb-meetup-march-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/03/28\n  talks:\n    - title: \"Hanami 2.0 and You\"\n      raw_title: \"Hanami 2.0 and You by Christine Seeman\"\n      speakers:\n        - Christine Seeman\n      event_name: \"WNB.rb Meetup March 2023\"\n      date: \"2023-03-28\"\n      published_at: \"2023-05-10\"\n      description: |-\n        Let's chat about the new release of Hanami 2.0 Web Framework and what you can use it for. Let's learn how you can start with it, and some examples from an application that is already making use of Hanami in production.\n\n        Christine Seeman is a lifetime learner from Omaha, NE, where she likes to read too much and eats food that probably took too long to prepare. Professionally she's solving problems on the Identity team at WP Engine by writing secure, easy-to-read software that powers authorization and authentication.\n\n        https://www.wnb-rb.dev/meetups/2023/03/28\n      video_provider: \"youtube\"\n      id: \"christine-seeman-wnbrb-meetup-march-2023\"\n      video_id: \"CoGgG2kpi7I\"\n\n- id: \"wnb-rb-meetup-april-2023\"\n  title: \"WNB.rb Meetup April 2023\"\n  raw_title: \"WNB.rb Meetup April 2023\"\n  event_name: \"WNB.rb Meetup April 2023\"\n  date: \"2023-04-25\"\n  video_id: \"wnb-rb-meetup-april-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/04/25\n  talks:\n    - title: \"We Need Someone Technical on the Call\"\n      raw_title: \"We Need Someone Technical on the Call by Brittany Martin\"\n      speakers:\n        - Brittany Martin\n      event_name: \"WNB.rb Meetup April 2023\"\n      date: \"2023-05-02\"\n      published_at: \"2023-05-29\"\n      description: |-\n        A DM. The dreaded message. \"They want someone technical on the call.\" If that statement is terrifying, never fear. Being effective at these interactions can be a big opportunity for your career. Learn tactics on when to commit to calls and how to execute them while empowering your team, conserving your time and acing the follow through.\n\n        Brittany Martin is an Engineering Manager, Co-Host of The Ruby on Rails Podcast, proud Rubyist and now a returning roller derby skater under the pseudonym \"Merge Conflict\".\n\n        https://www.wnb-rb.dev/meetups/2023/05/02\n      video_provider: \"youtube\"\n      id: \"brittany-martin-wnbrb-meetup-april-2023\"\n      video_id: \"WhvSiNgtM7A\"\n\n- id: \"wnb-rb-meetup-may-2023\"\n  title: \"WNB.rb Meetup May 2023\"\n  raw_title: \"WNB.rb Meetup May 2023\"\n  event_name: \"WNB.rb Meetup May 2023\"\n  date: \"2023-05-30\"\n  video_id: \"wnb-rb-meetup-may-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/05/30\n  talks:\n    - title: \"Building an offline experience with a Rails-powered PWA\"\n      raw_title: \"Building an offline experience with a Rails-powered PWA by Alicia Rojas\"\n      speakers:\n        - Alicia Rojas\n      event_name: \"WNB.rb Meetup May 2023\"\n      date: \"2023-05-30\"\n      published_at: \"2023-08-01\"\n      description: |-\n        Progressive web applications (PWAs) allow us to provide rich offline experiences as native apps would, while still being easy to use and share, as web apps are. Come to learn how to turn your regular Rails application into a PWA, taking advantage of the new front-end tools that come with Rails by default since version 7.\n        https://www.wnb-rb.dev/meetups/2023/05/30\n      video_provider: \"youtube\"\n      id: \"alicia-rojas-wnbrb-meetup-may-2023\"\n      video_id: \"gRcB86Ro3vI\"\n\n    - title: \"The Magic of Ruby's method_missing\"\n      raw_title: \"The Magic of Ruby's method_missing by Kaylah Rose Mitchell\"\n      speakers:\n        - Kaylah Rose Mitchell\n      event_name: \"WNB.rb Meetup May 2023\"\n      date: \"2023-05-30\"\n      published_at: \"2023-08-01\"\n      description: |-\n        Discover the magic of method_missing and learn how to unleash its full potential in your Ruby applications. In this talk, we'll dive into the inner workings of method_missing and explore how it can be used to dynamically define methods on objects at runtime, handle missing method calls, and perform powerful metaprogramming tasks.\n        https://www.wnb-rb.dev/meetups/2023/05/30\n      video_provider: \"youtube\"\n      id: \"kaylah-rose-mitchell-wnbrb-meetup-may-2023\"\n      video_id: \"MAu158kEu04\"\n\n- id: \"wnb-rb-meetup-june-2023\"\n  title: \"WNB.rb Meetup June 2023\"\n  raw_title: \"WNB.rb Meetup June 2023\"\n  event_name: \"WNB.rb Meetup June 2023\"\n  date: \"2023-06-27\"\n  video_id: \"wnb-rb-meetup-june-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/06/27\n  talks:\n    - title: \"Deep End Diving: Getting Up to Speed on New Codebases\"\n      raw_title: \"Deep End Diving: Getting Up to Speed on New Codebases by Allison Hill\"\n      speakers:\n        - Allison Hill\n      event_name: \"WNB.rb Meetup June 2023\"\n      date: \"2023-06-27\"\n      published_at: \"2023-08-07\"\n      description: |-\n        Learning new tools and using them effectively is a fundamental component of being a developer. The more efficiently developers can get onboarded and oriented to your project or tool, the faster the return on investment is for everybody involved. For newbies, a smooth entry into a new role can help shake off imposter syndrome and encourage a growth mindset. For the rest of the team, it means more time spent collaborating, adding value to your product, and making things! In this talk, we will discuss some strategies you can use as a team to make onboarding smooth sailing.\n        https://www.wnb-rb.dev/meetups/2023/06/27\n      video_provider: \"youtube\"\n      id: \"allison-hill-wnbrb-meetup-june-2023\"\n      video_id: \"Zo8-z3n9sAc\"\n\n- id: \"wnb-rb-meetup-july-2023\"\n  title: \"WNB.rb Meetup July 2023\"\n  raw_title: \"WNB.rb Meetup July 2023\"\n  event_name: \"WNB.rb Meetup July 2023\"\n  date: \"2023-07-25\"\n  video_id: \"wnb-rb-meetup-july-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/07/25\n  talks:\n    - title: \"Unleashing the Power of Pair Presenting: Elevate Your Conference Impact\"\n      raw_title: \"Unleashing the Power of Pair Presenting: Elevate Your Conference Impact  by Selena Small\"\n      speakers:\n        - Selena Small\n      event_name: \"WNB.rb Meetup July 2023\"\n      date: \"2023-07-25\"\n      published_at: \"2023-08-01\"\n      description: |-\n        Discover the transformative potential of pair presenting at conferences in this captivating presentation. Explore the principles behind successful collaborations, understanding the advantages and disadvantages of this dynamic approach and how it can elevate your impact.\n\n        Gain insights into leveraging unique personalities and strengths, assessing the need for two speakers, and understanding the perception created, while incorporating engaging live code demonstrations and interactive elements.\n\n        Recognize the importance of strong male allies in fostering inclusivity and integration. Harness the power of pair presenting to maximize your conference impact, forge meaningful connections, and empower you to make a lasting impression on your audience.\n\n        https://www.wnb-rb.dev/meetups/2023/07/25\n      video_provider: \"youtube\"\n      id: \"selena-small-wnbrb-meetup-july-2023\"\n      video_id: \"6AzbwvlBrvs\"\n\n    - title: \"My favorite Ruby Style Guidelines\"\n      raw_title: \"My favorite Ruby Style Guidelines by Sarah Lima\"\n      speakers:\n        - Sarah Lima\n      event_name: \"WNB.rb Meetup July 2023\"\n      date: \"2023-07-25\"\n      published_at: \"2023-08-01\"\n      description: |-\n        Following style guidelines helps programmers avoid time-consuming discussions on trivial matters and facilitates collaboration as newcomers can quickly familiarize themselves with the code and start contributing effectively.\n\n        We're gonna dive into some of my favorite ruby style guidelines, discussing the rationale and the technical aspects that underpin them, and how they help us avoid common pitfalls.\n\n        https://www.wnb-rb.dev/meetups/2023/07/25\n      video_provider: \"youtube\"\n      id: \"sarah-lima-wnbrb-meetup-july-2023\"\n      video_id: \"vjDdZfamp6o\"\n\n- id: \"wnb-rb-meetup-august-2023\"\n  title: \"WNB.rb Meetup August 2023\"\n  raw_title: \"WNB.rb Meetup August 2023\"\n  event_name: \"WNB.rb Meetup August 2023\"\n  date: \"2023-08-29\"\n  video_id: \"wnb-rb-meetup-august-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/08/29\n  talks:\n    - title: \"How can I move forward when I don't know where I want to go?\"\n      raw_title: \"How can I move forward when I don't know where I want to go? by Mo O'Connor\"\n      speakers:\n        - Mo O'Connor\n      event_name: \"WNB.rb Meetup August 2023\"\n      date: \"2023-08-29\"\n      published_at: \"2023-09-29\"\n      description: |-\n        Most of us have a drive towards professional development and growing towards that next level, but what happens when the next level could be more than one thing? It could mean a promotion from mid-level to senior-level, taking on leadership responsibilities, or moving to a people-management role. What if I'm not sure which direction I want to go? In this talk, we'll discuss ways to move forward even when we haven't decided on the trajectory yet. You'll walk away with tools and tactics you can utilize to pave and navigate your own path forward.\n        https://www.wnb-rb.dev/meetups/2023/08/29\n      video_provider: \"youtube\"\n      id: \"mo-oconnor-wnbrb-meetup-august-2023\"\n      video_id: \"LPKbcNM-acA\"\n\n- id: \"wnb-rb-meetup-september-2023\"\n  title: \"WNB.rb Meetup September 2023\"\n  raw_title: \"WNB.rb Meetup September 2023\"\n  event_name: \"WNB.rb Meetup September 2023\"\n  date: \"2023-09-26\"\n  video_id: \"wnb-rb-meetup-september-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/09/26\n  talks:\n    - title: \"Everything you've ever wanted is sitting on the other side of fear\"\n      raw_title: \"Everything you've ever wanted is sitting on the other side of fear by Hoa Newton\"\n      speakers:\n        - Hoa Newton\n      event_name: \"WNB.rb Meetup September 2023\"\n      date: \"2023-09-26\"\n      published_at: \"2023-11-29\"\n      description: |-\n        The ever-changing, ever-evolving nature of the tech industry and its complexity make it such an exciting field to be in, but not without many challenges. Working in technology, we often have to stretch our limits, constantly learn new concepts, keep up with new technologies and methodologies. We constantly try to be better, more efficient, and do more... All of these often trigger fear. During my years of trying to figure out how to thrive at work, I have learned a few things that I am eager to share with you and to invite you on a journey of conquering fear to unlock your potential to succeed in the Tech industry.\n        https://www.wnb-rb.dev/meetups/2023/09/26\n      video_provider: \"youtube\"\n      id: \"hoa-newton-wnbrb-meetup-september-2023\"\n      video_id: \"GnngWab1Yik\"\n\n- id: \"wnb-rb-meetup-october-2023\"\n  title: \"WNB.rb Meetup October 2023\"\n  raw_title: \"WNB.rb Meetup October 2023\"\n  event_name: \"WNB.rb Meetup October 2023\"\n  date: \"2023-10-31\"\n  video_id: \"wnb-rb-meetup-october-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/10/31\n  talks:\n    - title: \"Understanding reCAPTCHA for Web Security\"\n      raw_title: \"Understanding reCAPTCHA for Web Security by Mayra Lucia Navarro\"\n      speakers:\n        - Mayra Lucia Navarro\n      event_name: \"WNB.rb Meetup October 2023\"\n      date: \"2023-10-31\"\n      published_at: \"2023-11-29\"\n      description: |-\n        Discover how to integrate reCAPTCHA seamlessly into your Ruby on Rails project to protect your web application from spam, fraud, and automated attacks. Learn about the different types of reCAPTCHA, implementation steps, and the benefits it brings to both security and user experience.\n        https://www.wnb-rb.dev/meetups/2023/10/31\n      video_provider: \"youtube\"\n      id: \"mayra-lucia-navarro-wnbrb-meetup-october-2023\"\n      video_id: \"HMYd2qkw67E\"\n\n    - title: \"The Command Pattern in Ruby\"\n      raw_title: \"The Command Pattern in Ruby by Annie Kiley\"\n      speakers:\n        - Annie Kiley\n      event_name: \"WNB.rb Meetup October 2023\"\n      date: \"2023-10-31\"\n      published_at: \"2023-11-29\"\n      description: |-\n        Let's talk about the command pattern and how it can be useful in object-oriented programming. We'll briefly go over what it is and using it with Ruby. Then we'll look at some real-world examples using the ActiveInteraction gem in a Ruby on Rails application.\n        https://www.wnb-rb.dev/meetups/2023/10/31\n      video_provider: \"youtube\"\n      id: \"annie-kiley-wnbrb-meetup-october-2023\"\n      video_id: \"WlOmb5rz3Q4\"\n\n- id: \"wnb-rb-meetup-november-2023\"\n  title: \"WNB.rb Meetup November 2023\"\n  raw_title: \"WNB.rb Meetup November 2023\"\n  event_name: \"WNB.rb Meetup November 2023\"\n  date: \"2023-11-28\"\n  video_id: \"wnb-rb-meetup-november-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/11/28\n  talks:\n    - title: \"RSpec Best Practices: Toni's Top Do's and Don'ts for Writing Great Tests\"\n      raw_title: \"RSpec Best Practices: Toni's Top Do's and Don'ts for Writing Great Tests by Toni Rib\"\n      speakers:\n        - Toni Rib\n      event_name: \"WNB.rb Meetup November 2023\"\n      date: \"2023-11-28\"\n      published_at: \"2023-12-19\"\n      description: |-\n        We've all been there: you're running tests in CI and a test not related to your PR fails for seemingly no reason. Or maybe you change code and the test that should have caught it doesn't fail. From many years of experience of using Test Driven Development to write tests, fixing hundreds of non-deterministic tests, and running the Testing Guild back when I worked at Gusto, this talk will cover my top things to watch out for while testing with RSpec.\n\n        https://www.wnb-rb.dev/meetups/2023/11/28\n      video_provider: \"youtube\"\n      id: \"toni-rib-wnbrb-meetup-november-2023\"\n      video_id: \"asCXmlMN5MY\"\n\n- id: \"wnb-rb-meetup-december-2023\"\n  title: \"WNB.rb Meetup December 2023\"\n  raw_title: \"WNB.rb Meetup December 2023\"\n  event_name: \"WNB.rb Meetup December 2023\"\n  date: \"2023-12-19\"\n  video_id: \"wnb-rb-meetup-december-2023\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2023/12/19\n  talks:\n    - title: \"Investing in the Future: Unlocking the Potential of Junior Developers\"\n      raw_title: \"Investing in the Future: Unlocking the Potential of Junior Developers by Hana Harencarova\"\n      speakers:\n        - Hana Harencarova\n      event_name: \"WNB.rb Meetup December 2023\"\n      date: \"2023-12-19\"\n      published_at: \"2024-01-03\"\n      description: |-\n        Let's talk about valuing junior developers more in the workplace because they're the future of our industry. Companies often struggle to find enough senior developers but overlook the chance to train their own. In this talk, we'll discuss ways to empower junior developers. As a senior, you'll learn effective ways to help their growth through hands-on learning and increasing their motivation. If you're a junior dev, we'll cover tips on advancing your career by leveraging your team. Join us to learn how investing in a strong, diverse team now benefits your company's future.\n        https://www.wnb-rb.dev/meetups/2023/12/19\n      video_provider: \"youtube\"\n      id: \"hana-harencarova-wnbrb-meetup-december-2023\"\n      video_id: \"op3wX8QRObY\"\n\n# 2024\n\n- id: \"wnb-rb-meetup-january-2024\"\n  title: \"WNB.rb Meetup January 2024\"\n  raw_title: \"WNB.rb Meetup January 2024\"\n  event_name: \"WNB.rb Meetup January 2024\"\n  date: \"2024-01-30\"\n  video_id: \"wnb-rb-meetup-january-2024\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2024/01/30\n  talks:\n    - title: \"What is your TimeScale? : An Introduction to TimeScaleDB\"\n      raw_title: \"What is your TimeScale? : An Introduction to TimeScaleDB by Michelle Yuen\"\n      speakers:\n        - Michelle Yuen\n      event_name: \"WNB.rb Meetup January 2024\"\n      date: \"2024-01-30\"\n      published_at: \"2024-03-13\"\n      description: |-\n        People create, capture and consume more data than ever before.  From recording price changes of a single stock, to tracking environmental values such as average high and low temps for consecutive days at a location, to calculating total number of COVID-19 hospitalizations per day, to application monitoring: the need for a time-series database has increased.  In this talk, we introduce some of the features of one such time-series database: TimeScaleDB.  We will briefly introduce Postgres Materialized Views, explore other data coolness, and go through how we can implement TimeScale features into our Rails apps.\n\n        https://www.wnb-rb.dev/meetups/2024/01/30\n      video_provider: \"youtube\"\n      id: \"michelle-yuen-wnbrb-meetup-january-2024\"\n      video_id: \"BqatFc08Ttw\"\n\n    - title: \"Open Source Search for Rails\"\n      raw_title: \"Open Source Search for Rails by Allison Zadrozny\"\n      speakers:\n        - Allison Zadrozny\n      event_name: \"WNB.rb Meetup January 2024\"\n      date: \"2024-01-30\"\n      published_at: \"2024-03-13\"\n      description: |-\n        A tiny how-to primer on the best way to structure your code to deliver relevant search results to users in a basic Rails app without the use of javascript. With some code examples and a demo repo, I'll briefly touch on why teams choose open source, best practices for your integration, things to look out for, and further resources.\n        https://www.wnb-rb.dev/meetups/2024/01/30\n      video_provider: \"youtube\"\n      id: \"allison-zadrozny-wnbrb-meetup-january-2024\"\n      video_id: \"HSmxRYQstB0\"\n\n- id: \"wnb-rb-meetup-february-2024\"\n  title: \"WNB.rb Meetup February 2024\"\n  raw_title: \"WNB.rb Meetup February 2024\"\n  event_name: \"WNB.rb Meetup February 2024\"\n  date: \"2024-02-27\"\n  video_id: \"wnb-rb-meetup-february-2024\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2024/02/27\n  talks:\n    - title: \"Why and how to introduce pairing to your team\"\n      raw_title: \"Why and how to introduce pairing to your team by Madelyn Freed\"\n      speakers:\n        - Madelyn Freed\n      event_name: \"WNB.rb Meetup February 2024\"\n      date: \"2024-02-27\"\n      published_at: \"2024-03-22\"\n      description: |-\n        Pair programming improves nearly every aspect of my technical work and transforms my job from lonely to joyful. In this talk, I make a case for why pairing improves code, products, and teams, and gives practical steps on how you can introduce it.\n        https://www.wnb-rb.dev/meetups/2024/02/27\n      video_provider: \"youtube\"\n      id: \"madelyn-freed-wnbrb-meetup-february-2024\"\n      video_id: \"5dj-rJsnTrc\"\n\n    - title: \"The Power of a Story\"\n      raw_title: \"The Power of a Story by Naijeria Toweett\"\n      speakers:\n        - Naijeria Toweett\n      event_name: \"WNB.rb Meetup February 2024\"\n      date: \"2024-02-27\"\n      published_at: \"2024-03-26\"\n      description: |-\n        It all began with someone else's transition story, where I saw fragments of myself. I was inspired into action. In this talk, I guide you through the process of telling my own transition story. I share my story not only to inspire and empower but also to provide insights into the art of storytelling. Weave your experiences into a compelling narrative that can serve as a catalyst for a positive and inclusive tech.\n        https://www.wnb-rb.dev/meetups/2024/02/27\n      video_provider: \"youtube\"\n      id: \"naijeria-toweett-wnbrb-meetup-february-2024\"\n      video_id: \"u2UDxVXyTNc\"\n\n- id: \"wnb-rb-meetup-march-2024\"\n  title: \"WNB.rb Meetup March 2024\"\n  raw_title: \"WNB.rb Meetup March 2024\"\n  event_name: \"WNB.rb Meetup March 2024\"\n  date: \"2024-03-12\"\n  video_id: \"wnb-rb-meetup-march-2024\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2024/03/12\n  talks:\n    - title: \"From Confusion to Clarity: Demystifying Active Record in Rails\"\n      raw_title: \"From Confusion to Clarity: Demystifying Active Record in Rails by Jess Sullivan\"\n      speakers:\n        - Jess Sullivan\n      event_name: \"WNB.rb Meetup March 2024\"\n      date: \"2024-03-12\"\n      published_at: \"2024-05-27\"\n      description: |-\n        Have you ever marvelled at the magic of Rails.new and how easy it is to go from zero to I've got a working app? It's fantastic, but it's also scary when you're three years into your career and wonder what really happens in database.yml or application.rb.\n\n        In this talk, I'll delve into the heart of this mystery by exploring Active Record and demystifying how Rails harnesses its power. Together, we'll unravel the Default Configuration, Gemfile intricacies, Database Configuration nuances, and the Model Generation process. By understanding these core components, you'll not only unlock some of the secrets of Rails but also gain the confidence to navigate its complexities with ease.\n\n        Join me on this journey to deepen your understanding of Rails internals and empower yourself as a developer!\n\n        https://www.wnb-rb.dev/meetups/2024/03/12\n      video_provider: \"youtube\"\n      id: \"jess-sullivan-wnbrb-meetup-march-2024\"\n      video_id: \"IYdZwcqvuSo\"\n\n- id: \"wnb-rb-meetup-april-2024\"\n  title: \"WNB.rb Meetup April 2024\"\n  raw_title: \"WNB.rb Meetup April 2024\"\n  event_name: \"WNB.rb Meetup April 2024\"\n  date: \"2024-04-30\"\n  video_id: \"wnb-rb-meetup-april-2024\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2024/04/30\n  talks:\n    - title: \"Beyond senior: lessons from the technical career path\"\n      raw_title: \"Beyond senior: lessons from the technical career path by Dawn Richardson\"\n      speakers:\n        - Dawn Richardson\n      event_name: \"WNB.rb Meetup April 2024\"\n      date: \"2024-04-30\"\n      published_at: \"2024-07-25\"\n      description: |-\n        Staff, principal, distinguished engineer - there is an alternate path to people management if continuing up the \"career ladder\" into technical leadership. As a relatively new 'Principal Engineer', I want to report back on my learnings so far; things I wish I had known before stepping into this role 3 years ago.\n        https://www.wnb-rb.dev/meetups/2024/04/30\n      video_provider: \"youtube\"\n      id: \"dawn-richardson-wnbrb-meetup-april-2024\"\n      video_id: \"9OpO4Onm9k0\"\n\n- id: \"wnb-rb-meetup-may-2024\"\n  title: \"WNB.rb Meetup May 2024\"\n  raw_title: \"WNB.rb Meetup May 2024\"\n  event_name: \"WNB.rb Meetup May 2024\"\n  date: \"2024-05-28\"\n  video_id: \"wnb-rb-meetup-may-2024\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2024/05/28\n  talks:\n    - title: \"So writing tests feels painful. What now?\"\n      raw_title: \"So writing tests feels painful. What now? by Stephanie Minn\"\n      speakers:\n        - Stephanie Minn\n      event_name: \"WNB.rb Meetup May 2024\"\n      date: \"2024-05-28\"\n      published_at: \"2024-07-24\"\n      description: |-\n        When you write tests, you are the first user of your code's design. Like any user experience, you may encounter friction. Stubbing endless methods to get to green. Fixing unrelated spec files after a minor change. Rather than push on, let this tedium guide you toward better object-oriented code.\n\n        With examples in RSpec, this talk will cover testing headaches familiar to any Rails developer. Join me in learning how to listen to your symptoms, diagnose the cause, and find the right treatment. You'll leave with newfound inspiration to write clear, maintainable tests in peace. Your future self will thank you!\n\n        https://www.wnb-rb.dev/meetups/2024/05/28\n      video_provider: \"youtube\"\n      id: \"stephanie-minn-wnbrb-meetup-may-2024\"\n      video_id: \"-MJQso0AfYg\"\n\n- id: \"wnb-rb-meetup-june-2024\"\n  title: \"WNB.rb Meetup June 2024\"\n  raw_title: \"WNB.rb Meetup June 2024\"\n  event_name: \"WNB.rb Meetup June 2024\"\n  date: \"2024-06-25\"\n  video_id: \"wnb-rb-meetup-june-2024\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2024/06/25\n  talks:\n    - title: \"What does an Infrastructure Engineer Do?\"\n      raw_title: \"What does an Infrastructure Engineer Do? by Toni Rib\"\n      speakers:\n        - Toni Rib\n      event_name: \"WNB.rb Meetup June 2024\"\n      date: \"2024-06-25\"\n      published_at: \"2024-07-24\"\n      description: |-\n        Lightning talk by Toni Rib about what an infrastructure engineer does.\n\n        https://www.wnb-rb.dev/meetups/2024/06/25\n      video_provider: \"youtube\"\n      id: \"toni-rib-wnbrb-meetup-june-2024\"\n      video_id: \"sauC6zanfvI\"\n\n    - title: \"Webhooks: The Easy Way\"\n      raw_title: \"Webhooks: The Easy Way by Mayra Lucia Navarro\"\n      speakers:\n        - Mayra Lucia Navarro\n      event_name: \"WNB.rb Meetup June 2024\"\n      date: \"2024-06-25\"\n      published_at: \"2024-07-30\"\n      description: |-\n        What are Webhooks? What problem do they solve? Let's learn a little about them and how to implement them in Rails.\n\n        https://www.wnb-rb.dev/meetups/2024/06/25\n      video_provider: \"youtube\"\n      id: \"mayra-lucia-navarro-wnbrb-meetup-june-2024\"\n      video_id: \"Nq2UP0XlPDw\"\n\n- id: \"wnb-rb-meetup-july-2024\"\n  title: \"WNB.rb Meetup July 2024\"\n  raw_title: \"WNB.rb Meetup July 2024\"\n  event_name: \"WNB.rb Meetup July 2024\"\n  date: \"2024-07-30\"\n  video_id: \"wnb-rb-meetup-july-2024\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2024/07/30\n  talks:\n    - title: \"How to Accessibility if You're Mostly Back-End\"\n      raw_title: \"How to Accessibility if You're Mostly Back-End by Hilary Stohs-Krause\"\n      speakers:\n        - Hilary Stohs-Krause\n      event_name: \"WNB.rb Meetup July 2024\"\n      date: \"2024-07-30\"\n      published_at: \"2024-09-13\"\n      description: |-\n        If you work mostly on the back-end of the tech stack, it's easy to assume that your role is disengaged from accessibility concerns. After all, that's the front-end's job! However, there are multiple, specific ways back-end devs can impact accessibility: primarily, for colleagues and fellow programmers.\n\n        https://www.wnb-rb.dev/meetups/2024/07/30\n      video_provider: \"youtube\"\n      id: \"hilary-stohs-krause-wnbrb-meetup-july-2024\"\n      video_id: \"Wu8VE2_iyOE\"\n\n- id: \"wnb-rb-meetup-august-2024\"\n  title: \"WNB.rb Meetup August 2024\"\n  raw_title: \"WNB.rb Meetup August 2024\"\n  event_name: \"WNB.rb Meetup August 2024\"\n  date: \"2024-08-27\"\n  video_id: \"wnb-rb-meetup-august-2024\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2024/08/27\n  talks:\n    - title: \"Observability on Rails\"\n      raw_title: \"Observability on Rails by Caroline Salib\"\n      speakers:\n        - Caroline Salib\n      event_name: \"WNB.rb Meetup August 2024\"\n      date: \"2024-08-30\"\n      published_at: \"2024-09-13\"\n      description: |-\n        If you're unsure about what observability is or haven't given it much thought, this talk is perfect for you! We'll cover the basics of observability and how it can boost your confidence when shipping code to production by improving your ability to manage and monitor your Ruby on Rails applications.\n        https://www.wnb-rb.dev/meetups/2024/08/30\n      video_provider: \"youtube\"\n      id: \"caroline-salib-wnbrb-meetup-august-2024\"\n      video_id: \"H_LHCn6aERQ\"\n\n- id: \"wnb-rb-meetup-october-2024\"\n  title: \"WNB.rb Meetup October 2024\"\n  raw_title: \"WNB.rb Meetup October 2024\"\n  event_name: \"WNB.rb Meetup October 2024\"\n  date: \"2024-10-29\"\n  video_id: \"wnb-rb-meetup-october-2024\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2024/10/29\n  talks:\n    - title: \"Parsing with Prism in Sorbet\"\n      raw_title: \"Parsing with Prism in Sorbet by Emily Samp\"\n      speakers:\n        - Emily Samp\n      event_name: \"WNB.rb Meetup October 2024\"\n      date: \"2024-10-29\"\n      published_at: \"2024-12-12\"\n      slides_url: \"https://docs.google.com/presentation/d/1sw_V2_FfqTBfge46hBxLYxYcXKVy_LIp7CkqgphP9Ss/edit#slide=id.p\"\n      description: |-\n        Sorbet is a gradual type checker for Ruby, and like many Ruby developer tools, it has its own parser. This means that every time a change is made to the Ruby language, teams at Stripe and Shopify need to implement those changes in Sorbet's parser. This process is labor-intensive, slow, and prone to errors. There must be a better way!\n\n        Enter, Prism. Prism is a new Ruby parser developed by Shopify. It is written in C and designed to be embedded in other Ruby tooling. In this talk, I'll describe how I replaced the existing Sorbet parser with Prism, eliminating the toil of maintaining the Sorbet parser and taking one step toward uniting Ruby's parsing ecosystem.\n\n        https://www.wnb-rb.dev/meetups/2024/10/29\n      video_provider: \"youtube\"\n      id: \"emily-samp-wnbrb-meetup-october-2024\"\n      video_id: \"rnGMDz-2YVE\"\n\n- id: \"wnb-rb-meetup-november-2024\"\n  title: \"WNB.rb Meetup November 2024\"\n  raw_title: \"WNB.rb Meetup November 2024\"\n  event_name: \"WNB.rb Meetup November 2024\"\n  date: \"2024-11-26\"\n  video_id: \"wnb-rb-meetup-november-2024\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2024/11/26\n  talks:\n    - title: \"An Upgrade Handbook to Rails 8\"\n      raw_title: \"An Upgrade Handbook to Rails 8 by Jenny Shen\"\n      speakers:\n        - Jenny Shen\n      event_name: \"WNB.rb Meetup November 2024\"\n      date: \"2024-11-26\"\n      published_at: \"2024-12-11\"\n      description: |-\n        Each new major version of Rails unlocks so many great features, and Rails 8 is no exception. However, let's face it, upgrading a Rails application can be difficult. Each upgrade is filled with numerous changes that need to be addressed carefully to keep your application running smoothly.\n\n        Today, I'll talk about some of the common deprecations and changes introduced in Rails 8, and how Shopify was able to automate the Rails upgrade process for hundreds of their applications.\n\n        https://www.wnb-rb.dev/meetups/2024/11/26\n      video_provider: \"youtube\"\n      id: \"jenny-shen-wnbrb-meetup-november-2024\"\n      video_id: \"dFzctqj7qrI\"\n\n# 2025\n\n- id: \"wnb-rb-meetup-january-2025\"\n  title: \"WNB.rb Meetup January 2025\"\n  raw_title: \"WNB.rb Meetup January 2025\"\n  event_name: \"WNB.rb Meetup January 2025\"\n  date: \"2025-01-25\"\n  video_id: \"wnb-rb-meetup-january-2025\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2025/01/25\n  talks:\n    - title: \"Staff Engineer Panel\"\n      raw_title: \"Staff Engineer Panel\"\n      speakers:\n        - Toni Rib\n        - Sweta Sanghavi\n        - Maple Ong\n        - Christine Seeman\n      event_name: \"WNB.rb Meetup January 2025\"\n      date: \"2025-01-25\"\n      published_at: \"2025-02-19\"\n      thumbnail_xs: \"https://cdn.masto.host/rubysocial/media_attachments/files/113/844/865/006/596/689/original/2a841e477cf117c6.png\"\n      thumbnail_sm: \"https://cdn.masto.host/rubysocial/media_attachments/files/113/844/865/006/596/689/original/2a841e477cf117c6.png\"\n      thumbnail_md: \"https://cdn.masto.host/rubysocial/media_attachments/files/113/844/865/006/596/689/original/2a841e477cf117c6.png\"\n      thumbnail_lg: \"https://cdn.masto.host/rubysocial/media_attachments/files/113/844/865/006/596/689/original/2a841e477cf117c6.png\"\n      thumbnail_xl: \"https://cdn.masto.host/rubysocial/media_attachments/files/113/844/865/006/596/689/original/2a841e477cf117c6.png\"\n      description: |-\n        Join us for an exciting WNB.rb meetup, now with 4 engineers on our Staff Engineer Panel 🎉\n\n        Get ready for an insightful and inspiring discussion full of real-world advice, and career journeys. Come with your questions—we'd love to see you there 👋\n      video_provider: \"youtube\"\n      id: \"toni-rib-wnbrb-meetup-january-2025\"\n      video_id: \"teiR0sUA7aA\"\n\n- id: \"wnb-rb-meetup-february-2025\"\n  title: \"WNB.rb Meetup February 2025\"\n  raw_title: \"WNB.rb Meetup February 2025\"\n  event_name: \"WNB.rb Meetup February 2025\"\n  date: \"2025-02-25\"\n  video_id: \"wnb-rb-meetup-february-2025\"\n  video_provider: \"children\"\n  description: \"\"\n  talks:\n    - title: \"Leveling Up Our Community: Migrating from Slack to Discord\"\n      raw_title: \"Leveling Up Our Community: Migrating from Slack to Discord by Iratxe and Emily Samp\"\n      speakers:\n        - Iratxe Garrido\n        - Emily Samp\n      event_name: \"WNB.rb Meetup February 2025\"\n      date: \"2025-02-25\"\n      description: |-\n        We'll cover the key advantages of Discord, customizable features, and robust moderation capabilities, showing you exactly how to use them to get the most out of our new platform. WNB.rb logo with people next to it.\n\n      video_provider: \"not_published\"\n      id: \"iratxe-emily-samp-wnb-rb-meetup-february-2025\"\n      video_id: \"iratxe-emily-samp-wnb-rb-meetup-february-2025\"\n\n- id: \"wnb-rb-meetup-march-2025\"\n  title: \"WNB.rb Meetup March 2025\"\n  raw_title: \"WNB.rb Meetup March 2025\"\n  event_name: \"WNB.rb Meetup March 2025\"\n  date: \"2025-03-25\"\n  video_id: \"wnb-rb-meetup-march-2025\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2025/03/25\n  talks:\n    - title: \"Deep Dive into All Things Networking\"\n      raw_title: \"Deep Dive into All Things Networking by Rachel Serwetz\"\n      speakers:\n        - Rachel Serwetz\n      event_name: \"WNB.rb Meetup March 2025\"\n      date: \"2025-03-25\"\n      published_at: \"2025-03-28\"\n      description: |-\n        Are you nervous to network? Not sure how, when, or why we should network with other professionals, or how it can help you? In this talk, CEO & Career Coach Rachel Serwetz will deep dive into what networking really means and doesn't mean, how to make it comfortable and strategic for you, who to reach out to, what to do once you connect, how to follow up, and so much more. Bring all of your career questions for an AMA at the end!\n\n        About the speaker:\n        Rachel Serwetz' early professional experience was at Goldman Sachs in Operations and at Bridgewater Associates in HR. From there, she was trained as a coach at NYU and became a certified coach through the International Coach Federation. After this, she worked in HR Research at Aon Hewitt and attained her Technology MBA at NYU Stern. Throughout her career, she has helped hundreds of professionals with career exploration and for the past 7+ years she has been building her company, WOKEN, which is an online career exploration platform to coach professionals through the process of clarifying their ideal job and career path. She has also served as an Adjunct Professor of Entrepreneurship at Binghamton University and as a Career Coach through the Flatiron School/WeWork, Columbia University, and Project Activate. Learn more about WOKEN here: iamwoken.com.\n      video_provider: \"youtube\"\n      id: \"rachel-serwetz-wnbrb-meetup-march-2025\"\n      video_id: \"salsNbWyx7c\"\n\n- id: \"wnb-rb-meetup-april-2025\"\n  title: \"WNB.rb Meetup April 2025\"\n  raw_title: \"WNB.rb Meetup April 2025\"\n  event_name: \"WNB.rb Meetup April 2025\"\n  date: \"2025-04-29\"\n  video_id: \"wnb-rb-meetup-april-2025\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2025/04/29\n  talks:\n    - title: \"Objects and Test Boundaries: Finding Balance\"\n      raw_title: \"Objects and Test Boundaries: Finding Balance by Liz Pine\"\n      speakers:\n        - Liz Pine\n      event_name: \"WNB.rb Meetup April 2025\"\n      date: \"2025-04-29\"\n      published_at: \"2025-05-15\"\n      description: |-\n        So you have a controller or a resolver that calls your domain objects, you feel confident in the test coverage, but over time the tests get slow. There are many well known and effective techniques for addressing slow tests, but what is at the core of this issue? That's what I want to explore in this talk, taking a step back and identifying where our boundaries lie.\n      video_provider: \"youtube\"\n      id: \"liz-pine-wnbrb-meetup-april-2025\"\n      video_id: \"vXLZ4yCd1ZE\"\n\n- id: \"wnb-rb-meetup-july-2025\"\n  title: \"WNB.rb Meetup July 2025\"\n  raw_title: \"WNB.rb Meetup July 2025\"\n  event_name: \"WNB.rb Meetup July 2025\"\n  date: \"2025-07-29\"\n  video_id: \"wnb-rb-meetup-july-2025\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2025/07/29\n  talks:\n    - title: \"Beyond Type Checking\"\n      raw_title: \"Beyond Type Checking by Emily Samp\"\n      speakers:\n        - Emily Samp\n      event_name: \"WNB.rb Meetup July 2025\"\n      date: \"2025-07-29\"\n      published_at: \"2025-07-31\"\n      description: |-\n        Many Ruby developers have remained skeptical of type checking, viewing it as unnecessary complexity in a language celebrated for its simplicity and flexibility. Behind the scenes, however, type checking advancements are driving dramatic improvements to Ruby developer tools. In this talk, we'll explore how static analysis has the potential to enable Ruby developer tooling that is as intelligent, accurate, and responsive as state-of-the-art tooling for other languages. We'll learn how these improvements will eventually benefit all Ruby developers — typing enthusiasts or not — and discover why the entire community should be excited about the era of Ruby developer tooling that's now on the horizon.\n\n        Emily is an Engineering Manager at Shopify, improving the Ruby development experience with open source tools like Sorbet and Prism, which she's going to talk us through. She is also an organizer of WNB.rb, a virtual community for women and non-binary Ruby developers.\n\n        https://www.wnb-rb.dev/meetups/2025/07/29\n      video_provider: \"youtube\"\n      id: \"emily-samp-wnbrb-meetup-july-2025\"\n      video_id: \"EGnWn8chWPo\"\n\n- id: \"wnb-rb-meetup-august-2025\"\n  title: \"WNB.rb Meetup August 2025\"\n  event_name: \"WNB.rb Meetup August 2025\"\n  date: \"2025-08-26\"\n  announced_at: \"2025-08-22T16:23:36.837Z\"\n  video_id: \"wnb-rb-meetup-august-2025\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2025/08/26\n  talks:\n    - title: \"Spinning Multiple Plates: A Guide to Concurrency in Rails\"\n      raw_title: \"Spinning Multiple Plates: A Guide to Concurrency in Rails by Harriet Oughton\"\n      speakers:\n        - Harriet Oughton\n      event_name: \"WNB.rb Meetup August 2025\"\n      date: \"2025-08-26\"\n      published_at: \"2025-10-28\"\n      description: |-\n        You feel safe in the knowledge that your application is kept performant by the familiar 'Rails magic'... but even so, do you occasionally want to check behind the curtain?! Let's demystify things to discover exactly how applications are kept performant and efficient by the cool concurrency and threading that is 'woven' (!) into the Rails framework. In this talk, you will first learn about the core principles of concurrency in software in an easy-to-understand way, then take a behind-the-scenes look at where these principles are built into Rails, and finally, gain insights about configuration that could improve the performance, reliability and data-safety of your application.\n\n        https://www.wnb-rb.dev/meetups/2025/08/26\n      video_provider: \"youtube\"\n      id: \"harriet-oughton-wnb-rb-meetup-august-2025\"\n      video_id: \"NVX1fvxrc98\"\n\n- id: \"wnb-rb-meetup-september-2025\"\n  title: \"WNB.rb Meetup September 2025\"\n  event_name: \"WNB.rb Meetup September 2025\"\n  date: \"2025-09-30\"\n  video_id: \"wnb-rb-meetup-september-2025\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2025/09/30\n  talks:\n    - title: \"Thoughtful Al for the Rubyist\"\n      speakers:\n        - Christine Seeman\n      event_name: \"WNB.rb Meetup September 2025\"\n      date: \"2025-09-30\"\n      description: |-\n        Ever wondered how to make AI work for you without losing that Ruby magic? We will walk through how to integrate AI tools into our workflow while keeping it intentional.\n      video_provider: \"not_published\"\n      id: \"christine-seeman-wnb-rb-meetup-september-2025\"\n      video_id: \"christine-seeman-wnb-rb-meetup-september-2025\"\n\n- id: \"wnb-rb-meetup-october-2025\"\n  title: \"WNB.rb Meetup October 2025\"\n  event_name: \"WNB.rb Meetup October 2025\"\n  date: \"2025-10-28\"\n  video_id: \"wnb-rb-meetup-october-2025\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2025/10/28\n  talks:\n    - title: \"A Rails Edge Upgrade Playbook\"\n      speakers:\n        - Jill Klang\n      event_name: \"WNB.rb Meetup October 2025\"\n      date: \"2025-10-28\"\n      description: \"\"\n      video_provider: \"not_published\"\n      id: \"jill-klang-wnb-rb-meetup-october-2025\"\n      video_id: \"jill-klang-wnb-rb-meetup-october-2025\"\n\n    - title: \"Composing Music with Ruby\"\n      speakers:\n        - Sandra Kpodar\n      event_name: \"WNB.rb Meetup October 2025\"\n      date: \"2025-10-28\"\n      description: \"\"\n      video_provider: \"not_published\"\n      id: \"sandra-kpodar-wnb-rb-meetup-october-2025\"\n      video_id: \"sandra-kpodar-wnb-rb-meetup-october-2025\"\n\n- id: \"wnb-rb-meetup-december-2025\"\n  title: \"WNB.rb Meetup December 2025\"\n  event_name: \"WNB.rb Meetup December 2025\"\n  date: \"2025-12-02\"\n  video_id: \"wnb-rb-meetup-december-2025\"\n  video_provider: \"children\"\n  description: |-\n    https://www.wnb-rb.dev/meetups/2025/12/02\n  talks:\n    - title: \"Meet the WNB.rb Community Leaders\"\n      speakers: []\n      event_name: \"WNB.rb Meetup December 2025\"\n      date: \"2025-12-02\"\n      published_at: \"TODO\"\n      description: |-\n        Meet WNB.rb's community leaders—Career Services, Meetups, Member Services, Partnerships, and Social Media directors. Connect and learn how to get involved.\n      video_provider: \"not_published\"\n      id: \"wnb-rb-community-leaders-wnb-rb-meetup-december-2025\"\n      video_id: \"wnb-rb-community-leaders-wnb-rb-meetup-december-2025\"\n\n# 2026\n\n- id: \"wnb-rb-meetup-january-2026\"\n  title: \"WNB.rb Meetup January 2026\"\n  event_name: \"WNB.rb Meetup January 2026\"\n  date: \"2026-01-27\"\n  video_id: \"wnb-rb-meetup-january-2026\"\n  video_provider: \"children\"\n  description: \"\"\n  talks:\n    - title: \"Fake Minds Think Alike: AI, Ruby & Similarity Search\"\n      speakers:\n        - Valerie Woolard\n      event_name: \"WNB.rb Meetup January 2026\"\n      date: \"2026-01-27\"\n      description: |-\n        Learn how vector data powers LLMs — plus a practical Ruby example.\n      video_provider: \"scheduled\"\n      id: \"valerie-woolard-wnb-rb-meetup-january-2026\"\n      video_id: \"valerie-woolard-wnb-rb-meetup-january-2026\"\n"
  },
  {
    "path": "data/wroclove-rb/series.yml",
    "content": "---\nname: \"wroclove.rb\"\nwebsite: \"https://wrocloverb.com\"\ntwitter: \"wrocloverb\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"wroclove.rb\"\ndefault_country_code: \"PL\"\nyoutube_channel_name: \"wrocloverb\"\nlanguage: \"english\"\nyoutube_channel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\naliases:\n  - wrocloverb\n  - wroc_love.rb\n  - Wroc_love.rb\n  - Wroclove.rb\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2012/event.yml",
    "content": "---\nid: \"PLEEED8A6DA34E6F5B\"\ntitle: \"wroclove.rb 2012\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: \"\"\nstart_date: \"2012-03-10\"\nend_date: \"2012-03-11\"\npublished_at: \"2012-04-07\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2012\nwebsite: \"https://2012.wrocloverb.com\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2012/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"steve-klabnik-wrocloverb-2012\"\n  title: \"Designing Hypermedia APIs\"\n  raw_title: \"Steve Klabnik: Designing Hypermedia APIs\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-07\"\n  video_provider: \"youtube\"\n  video_id: \"0PB_pO_jU38\"\n  description:\n    \"This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\\r\n\n    \\r\n\n    Rails did a lot to bring REST to developers, but its conception leaves the REST devotee feeling a bit empty. \\\"Where's the hypermedia?\\\" she says. \\\"REST isn't RPC,\\\" he may\n    cry. \\\"WTF??!?!\\\" you may think. \\\"I have it right there! resources :posts ! What more is there? RPC? Huh?\\\" \\r\n\n    \\r\n\n    In this talk, Steve will explain how to design your APIs so that they truly embrace the web and HTTP. Just as there's an impedance mismatch between our databases, our ORMs, and\n    our models, there's an equal mismatch between our applications, our APIs, and our clients. Pros and cons of this approach will be discussed, as well as why we aren't building\n    things this way yet.\"\n\n- id: \"roy-tomeij-wrocloverb-2012\"\n  title: \"Modular & reusable front-end code with HTML5, Sass and CoffeeScript\"\n  raw_title: \"Roy Tomeij: Modular & reusable front-end code with HTML5, Sass and CoffeeScript\"\n  speakers:\n    - Roy Tomeij\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-07\"\n  video_provider: \"youtube\"\n  video_id: \"T6-75HdADc8\"\n  description:\n    \"This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\\r\n\n    \\r\n\n    Most Ruby developers use Rails for their everyday projects. Often they toy around with front-end themselves or outsource it, ending up tangled in a web of\n    css-all-over-the-place.\\r\n\n    \\r\n\n    Keeping your front-end code clean is hard. Before you know it you're suffering from CSS specificity issues and not-really-generic partials. Find out how to keep things tidy\n    using the HTML5 document outline and modular Sass & CoffeeScript, for truly reusable code.\"\n\n- id: \"nicolas-barrera-wrocloverb-2012\"\n  title: \"Responsive Web Design\"\n  raw_title: \"Nicolas Barrera: Responsive Web Design\"\n  speakers:\n    - Nicolas Barrera\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-07\"\n  video_provider: \"youtube\"\n  video_id: \"MNZnHrnQ56U\"\n  description:\n    \"This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\\r\n\n    \\r\n\n    Responsive Web Design is all about having the same content visible in all devices, from tiny mobiles to huge monitors, preserving proper readability and adapting to the medium.\n    It also entails a new way of creating content, in which interaction between designers and programmers is more important. In the Ruby world programmers generally feel proud of\n    being \\\"agile\\\", however when you zoom out, you see that the interaction between designers and programmers is more waterfally than you'd want.\\r\n\n    \\r\n\n    In the talk I will present the concept of responsiveness and teach with examples how to make a layout responsive with the one-two punch of fluid layouts and media queries.\"\n\n- id: \"piotr-szotkowski-wrocloverb-2012\"\n  title: \"Panel: Rails vs. OOP\"\n  raw_title: \"Piotr Szotkowski, Steve Klabnik, Nick Sutterer, Jim Gay: Rails vs. OOP\"\n  speakers:\n    - Piotr Szotkowski\n    - Steve Klabnik\n    - Nick Sutterer\n    - Jim Gay\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-08\"\n  video_provider: \"youtube\"\n  video_id: \"jk8FEssfc90\"\n  description:\n    \"This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\\r\n\n    \\r\n\n    A lot has been said recently about the topic of Rails and OOP. We consider this issue very important in our community. This fight is all about the recent OOP movements in the\n    Rails world. There are quite a few problems that people focus on and quite a few proposed solutions.\"\n\n- id: \"micha-potyn-wrocloverb-2012\"\n  title: \"Fishbowl Discussion: Testing\"\n  raw_title: \"Testing fishbowl\"\n  speakers:\n    # TODO: moderator\n    - Michał Połtyn\n    - Jeppe Liisberg\n    - Michał Czyż\n    - Andrzej Krzywda\n    # TODO: and more\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"IoiZtvXWGjI\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    All you wanted to question about testing but was afraid to flame. In this heated debate where everyone could participate we focused on the following discussion starters: cucumber vs. object oriented tests, tdd vs. bdd, full-stack vs. frontend/backend testing, steak vs. bbq, rspec vs. minitest or just no-tests drama.\n\n    Discussion has been conducted under rules of a Fishbowl http://en.wikipedia.org/wiki/Fishbowl_(conversation)\n\n- id: \"micha-taszycki-wrocloverb-2012\"\n  title: \"Programming Workout\"\n  raw_title: \"Michał Taszycki: Programming Workout\"\n  speakers:\n    - Michał Taszycki\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-11\"\n  video_provider: \"youtube\"\n  video_id: \"wXQLil_SGCI\"\n  description:\n    \"This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\\r\n\n    \\r\n\n    Times are changing... Technology is moving forward... Command line tools are becoming obsolete... Programmers today don't need to touch type... Using mouse to copy and paste is\n    perfectly fine... You can always look up those design patterns on the web... Your IDE can do a lot of things for you so you don't need to think... Can you feel that? Can you\n    feel that this is TRUE? Then stop being UNPROFESSIONAL and think again! \\r\n\n    \\r\n\n    In this talk I'm gonna convince you that learning seemingly obsolete skills can have huge impact on your productivity. I'll show you how those skills and other seemingly\n    unimportant factors can impact your career. I will help you to find a way to improve them in order to become a better programmer. I'll also show you tools that can facilitate\n    this process. You will either leave this talk with strong resolution to level up, or curl up in your comfort zone with your lovely mouse and IDE. I will show you how\n    PROGRAMMERS WORK OUT.\"\n\n- id: \"matrin-sustrik-wrocloverb-2012\"\n  title: \"ØMQ - A way towards fully distributed architectures\"\n  raw_title: \"Matrin Sustrik: ØMQ - A way towards fully distributed architectures\"\n  speakers:\n    - Matrin Sustrik\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-11\"\n  video_provider: \"youtube\"\n  video_id: \"RcfT3b79UYM\"\n  description:\n    \"This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\\r\n\n    \\r\n\n    In this talk Martin shows basic ØMQ concepts and tells how Rubyists can take advantage of them.\"\n\n- id: \"ralph-von-der-heyden-wrocloverb-2012\"\n  title: \"Get out of the trap!\"\n  raw_title: \"Ralph von der Heyden, Georg Leciejewski and Jan Kus - Get out of the trap!\"\n  speakers:\n    - Ralph von der Heyden\n    - Georg Leciejewski\n    - Jan Kus\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-06-05\"\n  video_provider: \"youtube\"\n  video_id: \"TyfXJ5mydVc\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    In our talk we share some of the most interesting, absurd, or funny insights and moments we experienced in our past couple of years. As developers and business founders, we present the best of our own mistakes and show you how we got out of the pits we fell into. Believe us, we've been there as well and, hopefully, attending our talk will help you not making the mistakes we already made for you ;) It will be serious fun! The talk will cover both technical and other subjects.\n\n- id: \"krzysztof-kowalik-wrocloverb-2012\"\n  title: \"Distributed Hell\"\n  raw_title: \"Krzysztof Kowalik - Distributed Hell\"\n  speakers:\n    - Krzysztof Kowalik\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-12-08\"\n  video_provider: \"youtube\"\n  video_id: \"EGyrwqu_6vs\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    During this talk you gonna find out how to design and build cloud-ready distributed web applications correctly, how to scale them according to your needs and finally how to test and deploy them fast and easily.\n\n- id: \"piotr-sarnacki-wrocloverb-2012\"\n  title: \"Rails - past, present and the future\"\n  raw_title: \"Piotr Sarnacki: Rails - past, present and the future\"\n  speakers:\n    - Piotr Sarnacki\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-07\"\n  video_provider: \"youtube\"\n  video_id: \"wOYQDSeKthY\"\n  description:\n    \"This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\\r\n\n    \\r\n\n    Rails is getting older and there was a lot changes along the way, including The Big Rewrite from 2.3 to 3.0. Was it worth it? Where is rails heading now? In this talk I will\n    try to address these and other questions connected with rails status and progress.\"\n\n- id: \"jim-gay-wrocloverb-2012\"\n  title: \"It's Business Time\"\n  raw_title: \"Jim Gay: It's Business Time\"\n  speakers:\n    - Jim Gay\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-07\"\n  video_provider: \"youtube\"\n  video_id: \"lhFSc0dWsto\"\n  description:\n    \"This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\\r\n\n    \\r\n\n    Discover a complement to your MVC ways that puts your business needs in plain view. Learn how DCI (Data, Context, and Interaction) allows you to keep your application\n    architecture lean by turning your use cases into executable code. Make your application easy to read, easy to understand, and easy to reuse.\"\n\n- id: \"piotr-szotkowski-wrocloverb-2012-decoupling-persistence-like-th\"\n  title: \"Decoupling Persistence (Like There's Some Tomorrow)\"\n  raw_title: \"Piotr Szotkowski: Decoupling Persistence (Like There's Some Tomorrow)\"\n  speakers:\n    - Piotr Szotkowski\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-07\"\n  video_provider: \"youtube\"\n  video_id: \"w7Eol9N3jGI\"\n  slides_url: \"https://talks.chastell.net/src-2012\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow\n    us at https://twitter.com/wrocloverb. See you next year!\n\n    When I open up a Rails project and the models dir is full of 100% ActiveRecord classes I shudder. Model ≠ Persistence. — Ben Mabey\n\n    From DCI to presenters, from Uncle Bob’s architecture talk and Avdi Grimm’s Objects on Rails book to the proliferation of (competing? complementing?) database systems, it seems the time has come to seriously consider decoupling our objects’ persistence from the rest of the application.\n\n    This talk – after describing the general vices of strong object/database coupling and the all-too-usual rails g model-driven development – covers the various approaches to separating the objects’ persistence layer, along with their virtues (cleaner, simpler tests! backend independence! no RDBMS-related shortcuts impacting the design!) and potential vices (performance? perceived compexity? YAGNI?).\n\n- id: \"piotr-solnica-wrocloverb-2012\"\n  title: \"DataMapper 2\"\n  raw_title: \"Piotr Solnica: DataMapper 2\"\n  speakers:\n    - Piotr Solnica\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-09\"\n  video_provider: \"youtube\"\n  video_id: \"MU4RvuvpT8w\"\n  description:\n    \"This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\\r\n\n    \\r\n\n    I would like to describe all of the pieces that we're working on: new relational algebra engine, new model definition and introspection layers, new validation library and other\n    things that will become part of DM2 (better migrations, UoW library, optimizer layer). The talk would be in the context of a better way of handling business logic in Rails\n    apps.\"\n\n- id: \"florian-gilcher-wrocloverb-2012\"\n  title: \"Fear of adding processes\"\n  raw_title: \"Florian Gilcher: Fear of adding processes\"\n  speakers:\n    - Florian Gilcher\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-04-13\"\n  video_provider: \"youtube\"\n  video_id: \"BYmHOF58bDY\"\n  description:\n    \"This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\\r\n\n    \\r\n\n    In object-oriented programming, there is a well-known anti-pattern called 'Fear of Adding Classes'. It describes the fear of solving a problem by adding another class because\n    of the (often wrongfully) perceived added complexity. With systems moving towards a distributed nature through the usage of external services, a similar pattern can be seen:\n    the fear of adding dedicated components, mostly independent processes to the system, because of the fear of added management overhead through doing so.\"\n\n- id: \"nick-sutterer-wrocloverb-2012\"\n  title: \"It's All About Respect!\"\n  raw_title: \"Nick Sutterer - It's All About Respect!\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-12-08\"\n  video_provider: \"youtube\"\n  video_id: \"yDZKIHFdLX8\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    Open-Source is driven by innovation from the people. Controversial ideas often change the way software developers write software. It can be a tedious, awkward task to promote, develop and maintain such projects. But in the end of the day it feels just great, doesn't it?\n\n- id: \"micha-czy-wrocloverb-2012\"\n  title: \"User perspective testing, using Ruby\"\n  raw_title: \"Michał Czyż - User perspective testing, using Ruby\"\n  speakers:\n    - Michał Czyż\n  event_name: \"wroclove.rb 2012\"\n  date: \"2012-03-10\"\n  published_at: \"2012-12-08\"\n  video_provider: \"youtube\"\n  video_id: \"CJRswpVCKcM\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    In this video Michał will show you why he took more object oriented approach, taking user's perspective for writing integration and acceptance tests.\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2013/event.yml",
    "content": "---\nid: \"PLoGBNJiQoqRD4y6XcTGuxn2SE2zsFA03z\"\ntitle: \"wroclove.rb 2013\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: \"\"\nstart_date: \"2013-03-01\"\nend_date: \"2013-03-03\"\npublished_at: \"2013-04-10\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2013\nwebsite: \"https://2013.wrocloverb.com\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2013/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"andrzej-krzywda-wrocloverb-2013\"\n  title: \"Panel: FP vs OOP\"\n  raw_title: \"Day 1 - FP vs OOP (fight)\"\n  speakers:\n    - Andrzej Krzywda\n    - Piotr Zolnierek\n    - Norbert Wójtowicz\n    - Tymon Tobolski\n    - Przemysław Kowalczyk\n    - Jan Filipowski\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"q0BQMbwzPJw\"\n  description: |-\n    Andrzej Krzywda, Piotr Zolnierek, Norbert Wójtowicz, Tymon Tobolski, Przemysław Kowalczyk and Jan Filipowski\n\n- id: \"micha-taszycki-wrocloverb-2013\"\n  title: \"Fishbowl: Programmer Productivity\"\n  raw_title: \"Day 1 - Programmer Productivity fishbowl\"\n  speakers:\n    - Michał Taszycki\n    - Robert Pankowecki\n    - Alex Koppel\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"2pmQk27i1PM\"\n  description: |-\n    Michał Taszycki, Robert Pankowecki and Alex Koppel\n\n- id: \"lightning-talks-day-2-wroclove-rb-2013\"\n  title: \"Lightning Talks (Day 2)\"\n  raw_title: \"Day 2 - Lightning Talks\"\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"VO4tM5RcUlc\"\n  talks:\n    - title: \"Lightning Talk: Patrick Mulder\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"patrick-mulder-lighting-talk-wroclove-rb-2013\"\n      video_id: \"patrick-mulder-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Patrick Mulder\n\n    - title: \"Lightning Talk: Lucas Reisig\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"lucas-reisig-lighting-talk-wroclove-rb-2013\"\n      video_id: \"lucas-reisig-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Lucas Reisig\n\n    - title: \"Lightning Talk: Piotr Vestragowski\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"piotr-vestragowski-lighting-talk-wroclove-rb-2013\"\n      video_id: \"piotr-vestragowski-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Piotr Vestragowski\n\n    - title: \"Lightning Talk: Tim Lossen\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tim-lossen-lighting-talk-wroclove-rb-2013\"\n      video_id: \"tim-lossen-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Tim Lossen\n\n    - title: \"Lightning Talk: David Dahl\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"david-dahl-lighting-talk-wroclove-rb-2013\"\n      video_id: \"david-dahl-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - David Dahl\n\n    - title: \"Lightning Talk: Bryan Helmkamp\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"bryan-helmkamp-lighting-talk-wroclove-rb-2013\"\n      video_id: \"bryan-helmkamp-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Bryan Helmkamp\n\n    - title: \"Lightning Talk: Rafael Pestragis\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"rafael-pestragis-lighting-talk-wroclove-rb-2013\"\n      video_id: \"rafael-pestragis-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Rafael Pestragis\n\n    - title: \"Lightning Talk: Hubert Łępicki\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"hubert-lepicki-lighting-talk-wroclove-rb-2013\"\n      video_id: \"hubert-lepicki-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Hubert Łępicki\n\n    - title: \"Lightning Talk: Arve Brasseur\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"arve-brasseur-lighting-talk-wroclove-rb-2013\"\n      video_id: \"arve-brasseur-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Arve Brasseur\n\n    - title: \"Lightning Talk: Piotr Włodarek\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"piotr-wlodarek-lighting-talk-wroclove-rb-2013\"\n      video_id: \"piotr-wlodarek-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Piotr Włodarek\n\n- id: \"florian-gilcher-wrocloverb-2013\"\n  title: \"A la carte, please!\"\n  raw_title: \"Florian Gilcher - A la carte, please!\"\n  speakers:\n    - Florian Gilcher\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"tgHMLkMCvzs\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    Rails is omakase. In other words: it opinionates on everything, tries to hide the efforts of composition and is hard to argue against by people that already picked the meal. As an (now) outsider to the Rails community, I am going to take the liberty of questioning those values. This talk explains why you should pick 'a la carte' instead of 'omakase' for programming and keep culinary habits where they belong: to the restaurant.\n\n- id: \"david-dahl-wrocloverb-2013\"\n  title: \"Building a real-time analytics engine in JRuby\"\n  raw_title: \"David Dahl - Building a real-time analytics engine in JRuby\"\n  speakers:\n    - David Dahl\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"7GMXFMIx48M\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    When most people hear big data real time analytics, they think huge enterprise systems and tools like Java, Oracle and so on. Thats not the case at Burt. We're building a real time ad analytics engine in Ruby, and we're handling tens of thousands of requests per second so far. Thanks to JRuby we can have the best of two worlds, the ease of developing with Ruby, and the robustness of the Java echosystem. In this talk you'll discover how we built a massive crunching pipeline using only virtual servers on AWS and free tools like JRuby, MongoDB, RabbitMQ, Redis, Cassandra and Nginx.\n\n- id: \"florian-plank-wrocloverb-2013\"\n  title: \"Keynote: How to lie, cheat and steal\"\n  raw_title: \"Florian Plank - How to lie, cheat and steal\"\n  speakers:\n    - Florian Plank\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-08\"\n  video_provider: \"youtube\"\n  video_id: \"fW-i7bbfdlQ\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    Better browsers, more CPU cores, faster Javascript engines — performance on the client side has been improving rapidly over the past years. And with HTML5 web app developers now have more possibilities than ever to take advantage of all this power.\n\n    Time to move some of the heavy lifting from the server to the client. Time to \"lie, cheat, and steal\", as Aaron Patterson put it in his RubyConf keynote.\n\n    Experimentation is the foundation for this talk, so put on your lab coats. You might not want to put every bit of code you'll see into your production apps, but you may just get some new (and wild) ideas. Make the browser work for your (Rails) app!\n\n- id: \"piotr-sarnacki-wrocloverb-2013\"\n  title: \"Panel: Single Page Applications Frameworks\"\n  raw_title: \"Single Page Applications Frameworks (fight)\"\n  speakers:\n    - Piotr Sarnacki\n    - Andrzej Krzywda\n    - Patrick Mulder\n    - Adam Pohorecki\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-08\"\n  video_provider: \"youtube\"\n  video_id: \"h8XeZFW1Ad0\"\n  description: |-\n    Piotr Sarnacki, Andrzej Krzywda, Patrick Mulder, Adam Pohorecki\n\n- id: \"adam-hawkins-wrocloverb-2013\"\n  title: \"Dear God, what am I doing? Concurrency and parallel processing\"\n  raw_title: \"Adam Hawkins - Dear God, what am I doing? Concurrency and parallel processing\"\n  speakers:\n    - Adam Hawkins\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"8pFJaEMMX6g\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    Here's a situation we've all be in at one point. We have a program. We\n    want to make that program faster. We know about threads, processes,\n    fibers. Then you start programming and you have no clue what to do. I\n    was there. It sucks. This talk guides you down the rabbit hole and\n    brings out the other side.\n\n    Points covered:\n    Threads, Fibers\n    Processes, Forking, Detaching\n    Parellelism vs Concurrency\n    The many many different ways I crashed my computer learning these things\n    Gotchas of each\n    Common ways you shoot yourself in the foot\n    Celluoid\n\n    This is a learning and informative talk. It's target at intermediate\n    developers who have ruby experience but never written any multi threaded\n    code.\n\n- id: \"rune-funch-sltoft-wrocloverb-2013\"\n  title: \"DCI != #extend && DCI != use case in code\"\n  raw_title: \"Rune Funch Søltoft - DCI != #extend && DCI != use case in code\"\n  speakers:\n    - Rune Funch Søltoft\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-09\"\n  video_provider: \"youtube\"\n  video_id: \"ZUADinlqHwk\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n- id: \"tim-felgentreff-wrocloverb-2013\"\n  title: \"Topaz Ruby\"\n  raw_title: \"Tim Felgentreff - Topaz Ruby\"\n  speakers:\n    - Tim Felgentreff\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-09\"\n  video_provider: \"youtube\"\n  video_id: \"WS76YAUs1hg\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n- id: \"reginald-braithwaite-wrocloverb-2013\"\n  title: \"The Not-So-Big Software Design\"\n  raw_title: \"Reginald Braithwaite - The Not-So-Big Software Design\"\n  speakers:\n    - Reginald Braithwaite\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"arsK-CN5YDg\"\n  description: \"\"\n\n- id: \"lightning-talks-day-3-wroclove-rb-2013\"\n  title: \"Lightning Talks (Day 3)\"\n  raw_title: \"Day 3 - Lightning Talks\"\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"6CZjK97dMTE\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Tobias Pfeiffer\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tobias-pfeiffer-lighting-talk-wroclove-rb-2013\"\n      video_id: \"tobias-pfeiffer-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Tobias Pfeiffer\n\n    - title: \"Lightning Talk: Steve Klabnik\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"steve-klabnik-lighting-talk-wroclove-rb-2013\"\n      video_id: \"steve-klabnik-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Steve Klabnik\n\n    - title: \"Lightning Talk: Tomasz Wójcik\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tomasz-wojcik-lighting-talk-wroclove-rb-2013\"\n      video_id: \"tomasz-wojcik-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomasz Wójcik\n\n    - title: \"Lightning Talk: Zuz Wróżka\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"zuz-wrozka-lighting-talk-wroclove-rb-2013\"\n      video_id: \"zuz-wrozka-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Zuz Wróżka\n\n    - title: \"Lightning Talk: Norbert Wójtowicz\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"norbert-wojtowicz-lighting-talk-wroclove-rb-2013\"\n      video_id: \"norbert-wojtowicz-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Norbert Wójtowicz\n\n    - title: \"Lightning Talk: Parker Moore\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"parker-moore-lighting-talk-wroclove-rb-2013\"\n      video_id: \"parker-moore-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Parker Moore\n\n    - title: \"Lightning Talk: Hubert Łępicki\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"hubert-lepicki-lighting-talk-wroclove-rb-2013-lightning-talk-hubert-picki\"\n      video_id: \"hubert-lepicki-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Hubert Łępicki\n\n    - title: \"Lightning Talk: Mateusz Lenik\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"mateusz-lenik-lighting-talk-wroclove-rb-2013\"\n      video_id: \"mateusz-lenik-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Mateusz Lenik\n\n    - title: \"Lightning Talk: Marcin Stecki\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"marcin-stecki-lighting-talk-wroclove-rb-2013\"\n      video_id: \"marcin-stecki-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Marcin Stecki\n\n    - title: \"Lightning Talk: Tomasz Stachewicz\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tomasz-stachewicz-lighting-talk-wroclove-rb-2013\"\n      video_id: \"tomasz-stachewicz-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomasz Stachewicz\n\n    - title: \"Lightning Talk: Michal Papis\"\n      date: \"2013-03-01\"\n      published_at: \"2013-04-10\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-papis-lighting-talk-wroclove-rb-2013\"\n      video_id: \"michal-papis-lighting-talk-wroclove-rb-2013\"\n      video_provider: \"parent\"\n      speakers:\n        - Michal Papis\n\n- id: \"sawek-sobtka-wrocloverb-2013\"\n  title: \"Ports and Adapters architecture\"\n  raw_title: \"Sławek Sobótka - Ports and Adapters architecture\"\n  speakers:\n    - Sławek Sobótka\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"_Js-GEqB-8I\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    Ports and Adapters architecture is a synthesis of the modern software engineering.\n    In its flexible Micro Kernel we will find a place for Domain Driven Design, Command-query Responsibility Segregation, Event Sourcing and plugins.\n    Kernel is protected by hard shell of Ports, which provides testability, scalability and SOA-Ready strategy. However, the outer aura made of Adapters opens system for: multi-device capability, Event Driven Architecture, Rest and Saga.\n    Everything is integrated within elegant \"Hexagon\" where there is \"A place for everything and everything in its place\".\n    During the presentation, I'll encourage you to communicate and solve problems using visualizing techniques and your visual intelligence.\n\n- id: \"brian-morton-wrocloverb-2013\"\n  title: \"Services and Rails: The Shit They Don't Tell You\"\n  raw_title: \"Brian Morton - Services and Rails: The Shit They Don't Tell You\"\n  speakers:\n    - Brian Morton\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"A9rwSDMp-ls\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    Building services and integrating them into Rails is hard. We want smaller Rails apps and nicely encapsulated services, but services introduce complexity. If you go overboard in the beginning, you're doing extra work and getting some of it wrong. If you wait too long, you've got a mess.\n\n    At Yammer, we constantly clean up the mess that worked well in the early days, but has become troublesome to maintain and scale. We pull things out of the core Rails app, stand them up on their own, and make sure they work well and are fast. With 20+ services, we've learned some lessons along the way. Services that seem clean in the beginning can turn into development environment nightmares. Temporary double-dispatching solutions turn into developer confusion. Monitoring one app turns into monitoring a suite of apps and handling failure between them.\n\n    This talk looks at our mistakes and solutions, the tradeoffs, and how we're able to keep moving quickly. Having services and a smaller Rails codebase makes for scalable development teams, happier engineers, and predictable production environments. Getting there is full of hard decisions -- sometimes we're right, sometimes we fuck it up, but we usually have a story to tell.\n\n- id: \"richard-schneeman-wrocloverb-2013\"\n  title: \"Security, Secrets and Shenanigans\"\n  raw_title: \"Richard Schneeman - Security, Secrets and Shenanigans\"\n  speakers:\n    - Richard Schneeman\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"mEXRqti0Ikw\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    zOMG Rails is insecure, PHP is insecure, Java is insecure - Everyone re-write everything in Haskell now! As much as coders love hating on languages and frameworks, the biggest security risk to you code is you. Come get a history of web security, and a live demo of security exploits. Then learn how to avoid them in your own code. You'll walk away with actionable steps to make your apps more safer, and a better understanding and appreciation of what being secure really means.\n\n- id: \"bryan-helmkamp-wrocloverb-2013\"\n  title: \"Panel: Security\"\n  raw_title: \"Day 3 - Security Panel\"\n  speakers:\n    - Bryan Helmkamp\n    - Piotr Niełacny\n    - Richard Schneeman\n    - Arne Brasseur\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-09\"\n  video_provider: \"youtube\"\n  video_id: \"cqYKd6jPXKM\"\n  description: |-\n    Bryan Helmkamp, Piotr Niełacny, Richard Schneeman and Arne Brasseur\n\n- id: \"piotr-nieacny-wrocloverb-2013\"\n  title: \"Things you can't do in Ruby\"\n  raw_title: \"Piotr Niełacny - Things you can't do in Ruby\"\n  speakers:\n    - Piotr Niełacny\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"0Q42jqP5qnE\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    Ever since I learnt the Ruby language, I thought I can use it to programme virtually anything. Well, I was wrong and I'd like to share this sad story with all of you.\n\n- id: \"steve-klabnik-wrocloverb-2013\"\n  title: \"OO Design and the history of philosophy\"\n  raw_title: \"Steve Klabnik - OO Design and the history of philosophy\"\n  speakers:\n    - Steve Klabnik\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"6WQ_1vcgS9c\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    Actions are driven by ideas, and ideas are driven by philosophy. For a\n    deep understanding of our actions, we have to go the whole way back to\n    the philosophy that motivates them. So what's the philosophical basis\n    for Object Oriented Programming? In this talk, Steve will discuss\n    Plato's theory of forms, its relationship to Object Oriented\n    Programming, and its current relevance (or irrelevance) to modern\n    philosophy.\n\n- id: \"bryan-helmkamp-wrocloverb-2013-refactoring-fat-models-with-pa\"\n  title: \"Refactoring Fat Models with Patterns\"\n  raw_title: \"Bryan Helmkamp - Refactoring Fat Models with Patterns\"\n  speakers:\n    - Bryan Helmkamp\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"IqajIYxbPOI\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    \"Fat models\" cause maintenance issues in large apps. Only incrementally better than cluttering controllers with domain logic, they usually represent a failure to apply the Single Responsibility Principle (SRP). \"Anything related to what a user does\" is not a single responsibility.\n\n    Early on, SRP is easier to apply. ActiveRecord classes handle persistence, associations and not much else. But bit-by-bit, they grow. Objects that are inherently responsible for persistence become the de facto owner of all business logic as well. And a year or two later you have a User class with over 500 lines of code, and hundreds of methods in it's public interface. Callback hell ensues.\n\n    This talk will explore patterns to smoothly deal with increasing intrinsic complexity (read: features!) of your application. Transform fat models into a coordinated set of small, encapsulated objects working together in a veritable symphony.\n\n- id: \"jan-stpie-wrocloverb-2013\"\n  title: \"Embrace the static. Cherish the functional. Remain a Rubyist.\"\n  raw_title: \"Jan Stępień - Embrace the static. Cherish the functional. Remain a Rubyist.\"\n  speakers:\n    - Jan Stępień\n  event_name: \"wroclove.rb 2013\"\n  date: \"2013-03-01\"\n  published_at: \"2013-04-10\"\n  video_provider: \"youtube\"\n  video_id: \"P6_illGY_00\"\n  description: |-\n    This video was recorded on http://wrocloverb.com. You should follow us at https://twitter.com/wrocloverb. See you next year!\n\n    We, Rubists, are proud users of one of the most dynamic object oriented language in the industry. We juggle eigenclasses, modify methods at runtime, embrace duck typing and still tend to deliver working software. But there's more than our Ruby out there in the wild. Borders between functional and object-oriented paradigms and between dynamic and static languages aren't as thick as it seems. Several ideas adopted in Ruby originated from communities concentrated around functional languages. Similarly, various tools developed by Rubists are ported to fully static languages such as Haskell. It's hard to overstate benefits of this exchange of concepts. Don't get left behind; see how it can make you a better Rubist.\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2014/event.yml",
    "content": "---\nid: \"PLoGBNJiQoqRCYNOfsPoxVWChbT5x5D5WP\"\ntitle: \"wroclove.rb 2014\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: |-\n  March 14-16th 2014, Wrocław Poland\nstart_date: \"2014-03-14\"\nend_date: \"2014-03-16\"\npublished_at: \"2014-04-14\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2014\nwebsite: \"https://2014.wrocloverb.com\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2014/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"robert-pankowecki-wrocloverb-2014\"\n  title: \"Developer Oriented Project Management\"\n  raw_title: \"Robert Pankowecki - DEVELOPER ORIENTED PROJECT MANAGEMENT\"\n  speakers:\n    - Robert Pankowecki\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"0OxNxlGSAdQ\"\n  slides_url: \"http://pankowecki.pl/wrocloverb2014/index.html#/\"\n  description: |-\n    Do you work on projects managed in a way that is easiest for managers or customers? Focused around their priorities without taking developers needs into account? Can we strive to achieve work and project environment that would be friendly for programmers so that they enjoy working in our company and don't think about leaving it?\n    The first part of this talk is intended to demonstrate techniques for managing IT projects in a developer friendly way. So that developers can avoid feeling of burden and disconnection from the rest of the team. So that they can improve their skills and grow up in new areas, without stagnating in doing the same repetitious tasks and working on fenced areas of code. And so that they can be always sure that they are working on the most important task right now and avoid confusion.\n    It will be based on guidelines that we established at Arkency throughout years of working remotely. You can apply them to your project slowly and every one of them will help you improve some of the previously mentioned aspects. Together they make tremendous difference and let people enjoy a lot of benefits that a programming job can offer. They create a programmer friendly environment in which they can feel comfortable and productive. After all, IT teams mostly consists of programmers, so the project should be optimized for their efficiency and happiness. But it also creates a nice set of rules that makes the communication between customers, product owners and developers easier.\n    But that's not all. Agile provides great opportunity for people to step forward and become leaders. But do you and your company know how to let people enter the path of leadership? How to empower the developers so they can introduce changes that make them more effective? The second part of the talk will show how developers can play the role of project managers. Your company might not become second Valve or Github but you can certainly benefit from applying changes leading towards more flat organization structure. By delegating at least some of the classic project manager actives such as meeting with clients, prioritizing tasks and extracting stories to programmers, they are given a chance to understand the business side of the project more deeply and to collaborate directly with the customer. With the technical and business knowledge, programmers can become true leaders for the projects, capable of independently handling issues and delivering the results, without the need for much supervision.\n\n- id: \"jeppe-liisberg-wrocloverb-2014\"\n  title: \"The Story of Bringing Ideas to Life\"\n  raw_title: \"Jeppe Liisberg - THE STORY OF BRINGING IDEAS TO LIFE\"\n  speakers:\n    - Jeppe Liisberg\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"IFeiLvz9MuY\"\n  slides_url: \"https://www.dropbox.com/s/rmpkg3uj2yjcup7/bringing%20ideas%20to%20life.pdf\"\n  description: |-\n    This is the story about www.myphoner.com. It started as an idea almost 4 years ago and has been implemented without launch a couple of times, lived in the shadows of bigger ambitions, only to finally come to life as a pet project, starting to see it's first revenue.\n    The talk is also about an whole hearted entrepreneur, trying to find his way about life. The adventures of running 3-4 startups at the same time and the ups and downs in life.\n\n- id: \"marcin-stecki-wrocloverb-2014\"\n  title: \"15 Minutes Rails Application\"\n  raw_title: \"Marcin Stecki - 15 MINUTES RAILS APPLICATION\"\n  speakers:\n    - Marcin Stecki\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"cA-9wAPHamc\"\n  slides_url: \"http://talks.madsheep.pl/talks/rapid\"\n  description: |-\n    15 minutes apps with rails - where this will take you? Let's rant the 'easy application development with Rails' and show how fast can you go wrong.  The \"15 minutes legacy rails application\".\n\n- id: \"piotr-misiurek-wrocloverb-2014\"\n  title: \"Please Stand Up!\"\n  raw_title: \"Piotr Misiurek - PLEASE STAND UP!\"\n  speakers:\n    - Piotr Misiurek\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"OCeJ-OAg4ag\"\n  description: |-\n    What have critical value for developers? The soft skills. That's what make you unique, well-paid and not replaceable. Wozniak had great technical skills but it was nothing without Job's great soft skills. You have to have both Steves inside you if you want be successful and happy developer. It you don't want to be just another brick in the wall.\n  slides_url: \"https://docs.google.com/presentation/d/1PTpbaqKVAl05oyzaTlsWp0RpTQbKe1txSih5gc4Ja8w/edit#slide=id.p\"\n\n- id: \"markus-schirp-wrocloverb-2014\"\n  title: \"Maybe!\"\n  raw_title: \"Markus Schirp - CAN WE WRITE PERFECT TESTS? - MAYBE!\"\n  speakers:\n    - Markus Schirp\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"rz-lFKEioLk\"\n  slides_url: \"http://slid.es/markusschirp/mutation-testing-fight-2\"\n  description: |-\n    Or: Why mutation testing is as a game changer for unit tests. The pros of a solid unit test suite are well understood and accepted in the ruby community.\n    The problem: How to define solid? Traditional metrics like line-coverage, branch-coverage and even statement-coverage can be misleading. Having a statement executed once does not mean all edge cases are specified and bug-free!\n    Automated tools can be used to identify uncovered edge cases that will introduce bugs into your program. Mutation testing brings fuzzing to the implementation level. Unlike input fuzzing it modifies the implementation to check if the test suite can detect a huge set of automatically introduced behaviour changes.\n    This talk will elaborate the history of testing and the metrics that are used to define coverage. And how such metrics can and have misguided development direction. It will also show examples of projects that heavily adopted mutation testing. Especially the long term effects and how the (mutation)-metrics driven approach improved developer happiness and code stability. Showing what kind of actual bugs where caught and how code became naturally streamlined. Lastly the current and future limits of existing mutation testing tools will be presented. The idea is to create the \"MUST HAVE\"-Feeling in the audience. Finally, you can prove that you have good tests! Do not miss it!\n\n- id: \"adam-hawkins-wrocloverb-2014\"\n  title: \"Application Architecture: Boundaries, Object Roles, & Patterns\"\n  raw_title: \"Adam Hawkins - APPLICATION ARCHITECTURE: BOUNDARIES, OBJECT ROLES, & PATTERNS\"\n  speakers:\n    - Adam Hawkins\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"_u2w57QBIkU\"\n  description: |-\n    This talk is about something important in the community. The Ruby community is missing something fundamentally important. We don't know how to architect applications. We've grown accustomed to using frameworks for everything and we've lost our way. We no longer talk about making applications, we speak about applications built in frameworks. Example: Oh hey man, did you hear NewApp123 is built in Rails? I take offense to that. The application is not built in Rails, it's built in Ruby than Rails is used to put it online. This mentality is prevalent in the community. It's damaging and encourages technical debt. This talk is about changing everything.\n\n- id: \"lightning-talks-saturday-wroclove-rb-2014\"\n  title: \"Lightning Talks (Saturday)\"\n  raw_title: \"Lightning talks - Saturday - Wroclove.rb 2014\"\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"He4420gpkpQ\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Chef Browser - Read-only Chef UI\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"marta-paciorkowska-lighting-talk-wroclove-rb-2014\"\n      video_id: \"marta-paciorkowska-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Marta Paciorkowska\n\n    - title: \"Lightning Talk: Refactoring: Low Hanging Fruit\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"norbert-wojtowicz-lighting-talk-wroclove-rb-2014\"\n      video_id: \"norbert-wojtowicz-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Norbert Wójtowicz\n\n    - title: \"Lightning Talk: Ruby Philosophy: Do Ruby Objects exist?\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"piotrek-zientara-lighting-talk-wroclove-rb-2014\"\n      video_id: \"piotrek-zientara-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Piotrek Zientara\n\n    - title: \"Lightning Talk: DHH Code Ping Pong\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"marcin-stecki-lighting-talk-wroclove-rb-2014\"\n      video_id: \"marcin-stecki-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Marcin Stecki\n\n    - title: \"Lightning Talk: Java is cool\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"aleksander-dabrowski-lighting-talk-wroclove-rb-2014\"\n      video_id: \"aleksander-dabrowski-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Aleksander Dąbrowski\n\n    - title: \"Lightning Talk: React.js and Hexagonal.js\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"marcin-grzywaczewski-lighting-talk-wroclove-rb-2014\"\n      video_id: \"marcin-grzywaczewski-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Marcin Grzywaczewski\n\n    - title: \"Lightning Talk: Random considered harmful\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"mateusz-lenik-lighting-talk-wroclove-rb-2014\"\n      video_id: \"mateusz-lenik-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Mateusz Lenik\n\n    - title: \"Lightning Talk: Nobody Knows Ruby\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"arne-brasseur-lighting-talk-wroclove-rb-2014\"\n      video_id: \"arne-brasseur-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Arne Brasseur\n\n    - title: \"Lightning Talk: RVM\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-papis-lighting-talk-wroclove-rb-2014\"\n      video_id: \"michal-papis-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Michal Papis\n\n    - title: \"Lightning Talk: Make Conf Wifi work\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"thilo-utke-lighting-talk-wroclove-rb-2014\"\n      video_id: \"thilo-utke-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Thilo Utke\n\n    - title: \"Lightning Talk: How To Get Paid in $, €, £ and not get ripped off\"\n      date: \"2014-03-14\"\n      published_at: \"2014-03-15\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"mateusz-kubiczek-lighting-talk-wroclove-rb-2014\"\n      video_id: \"mateusz-kubiczek-lighting-talk-wroclove-rb-2014\"\n      video_provider: \"parent\"\n      speakers:\n        - Mateusz Kubiczek\n\n- id: \"piotr-szotkowski-wrocloverb-2014\"\n  title: \"Integration Tests Are Bogus\"\n  raw_title: \"Piotr Szotkowski - INTEGRATION TESTS ARE BOGUS\"\n  speakers:\n    - Piotr Szotkowski\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"7XI3H_rKmRU\"\n  slides_url: \"https://talks.chastell.net/rubyday-2016\"\n  description: |-\n    The Ruby community embraced testing early, with many developers switching full-time to test-driven development (and, more importantly, test-driven design); discovering the domain of a given problem and the mechanics required to make objects interact painlessly by implementing a system from outside in are oftentimes eye-opening experiences.\n\n    Whether you like to write well-isolated (and fast!) unit tests or need to implement the outside of a system without having the inside nits-and-bolts in place beforehand there’s a plethora of stubbing and mocking libraries to choose from. Unfortunately, heavy mocking and stubbing comes with a cost: even with the most well-tested-in-isolation objects you can’t really say anything about their proper wirings without some integration and end-to-end tests – and writing the former is often not a very enjoyable experience.\n\n    This talk covers a new player on the Ruby testing scene: [Bogus](https://github.com/psyho/bogus), a library for stubbing, mocking and spying that goes the extra mile and verifies whether your fakes have any connection with reality – whether the faked methods exist on the actual object, whether they take the right number of arguments and even whether tests for a given class verify the behaviour that the class’s fakes pretend to have.\n\n    With Bogus quite a few of the [famously derided integration tests](http://www.infoq.com/presentations/integration-tests-scam) come for free; a change to a method’s name or its signature will make all of the related fakes complain, and all the missing pieces of a system written from outside in will present themselves ready to be implemented.\n  additional_resources:\n    - name: \"psyho/bogus\"\n      type: \"repo\"\n      url: \"https://github.com/psyho/bogus\"\n\n- id: \"piotr-solnica-wrocloverb-2014\"\n  title: \"Q&A: Code Metrics\"\n  raw_title: \"Code Metrics Q&A by Piotr Solnica & Markus Schirp\"\n  speakers:\n    - Piotr Solnica\n    - Markus Schirp\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"LiRYqor9ogs\"\n  description: \"\"\n  additional_resources:\n    - name: \"Questions\"\n      type: \"link\"\n      url: \"https://hackpad.com/wroc_love.rb-2014-Code-Metrics-QA-01r86FOgdrr\"\n\n- id: \"jan-stpie-wrocloverb-2014\"\n  title: \"Migrating To Clojure. So Much Fn\"\n  raw_title: \"Jan Stępień - MIGRATING TO CLOJURE. SO MUCH FN\"\n  speakers:\n    - Jan Stępień\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"Hv4slaRydRM\"\n  description: |-\n    Migrating a technology stack to a new language is rarely a simple task. It's getting even more challenging when what is changed is not only the language but the whole paradigm. This talk covers a story of stylefruits, where we've been gradually replacing a Ruby-based technology stack serving five million monthly visitors with Clojure. What are the costs and benefits of such a transition? How to make the migration gradual and painless? How to make Ruby and Clojure work with each other on the way? How easy is it to switch from a dynamic, object-oriented language to a functional one based on immutability and laziness? These are just some takeaways from this straight-from-the-trenches report.\n\n- id: \"emanuele-delbono-wrocloverb-2014\"\n  title: \"From ActiveRecord to Events\"\n  raw_title: \"Emanuele Delbono - FROM ACTIVERECORD TO EVENTS\"\n  speakers:\n    - Emanuele Delbono\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"GaGBfDe7r9Y\"\n  description: |-\n    Emanuele Delbono with FROM ACTIVERECORD TO EVENTS\n    We are used to write our rails application with ActiveRecord and store in the database the\n    current state of our entities. This kind of storage is not lossless as we might think, we completely miss the story that took the entities in the current state. That's way new architectures are becoming popular, these architectures don't store the state of the models but their deltas. During this session we will give a look at the Event Driven architectures, what problems they solve and how can be implemented in ruby and rails applications.\n  slides_url: \"http://www.slideshare.net/emadb/wroclove-rb\"\n\n- id: \"michael-feathers-wrocloverb-2014\"\n  title: \"Ruby Arrays on Steroids\"\n  raw_title: \"RUBY ARRAYS ON STEROIDS - Michael Feathers\"\n  speakers:\n    - Michael Feathers\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-18\"\n  video_provider: \"youtube\"\n  video_id: \"UX7xmhpUoi4\"\n  description: |-\n    It's easy to believe that we have all of the tools we need to solve\n    problems - that all problems should yield nicely to Object-Oriented\n    and Functional Programming.  But there are forgotten paradigms with\n    unfamiliar tools that allow us to solve problems very concise elegant\n    ways. In this talk, Michael will outline the facilities available in\n    the APL-derived programming languages and demonstrate a gem that\n    brings their power to Ruby.\n\n- id: \"piotr-solnica-wrocloverb-2014-micro-libraries-ftw\"\n  title: \"Micro Libraries FTW\"\n  raw_title: \"MICRO LIBRARIES FTW - Piotr Solnica\"\n  speakers:\n    - Piotr Solnica\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-18\"\n  video_provider: \"youtube\"\n  video_id: \"urUEB8Kz6jY\"\n  description: |-\n    I'm dreaming about a ruby ecosystem that consists of plenty of awesome, kick-ass, small, focused, well-written, nicely documented, composable libraries. Micro-libraries. I want those libraries to work on all major ruby implementations. I want those libraries to use as little magic and monkey-patching as possible. I want to be able to compose bigger frameworks using those libraries. In this talk I will tell you WHY I want all those things and HOW we could achieve that.\n\n- id: \"danny-olson-wrocloverb-2014\"\n  title: \"Objectify Your Forms: Beyond Basic User Input\"\n  raw_title: \"OBJECTIFY YOUR FORMS: BEYOND BASIC USER INPUT - Danny Olson\"\n  speakers:\n    - Danny Olson\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-18\"\n  video_provider: \"youtube\"\n  video_id: \"NENkGg-wzx8\"\n  description: |-\n    User input contains a lot of potential complexity. A simple CRUD form can turn into an unmaintainable mess when we introduce accepts_nested_attributes_for to deal with associations, validating first this model then that one, manually adding validation errors, and finally saving\n    the whole thing.\n    What if we could use good old object oriented design principles to make forms a pleasure to deal with? Form objects give us a much simpler way to build any sort of form we want that is straight forward to build, test, and maintain.\n    We will build a complicated form using the default Rails helpers, and then we'll rebuild it with a form object and let the audience decide which method they prefer.\n  slides_url: \"http://www.slideshare.net/dannyolson315/objectify-your-forms\"\n\n- id: \"michael-feathers-wrocloverb-2014-qa-legacy-rails\"\n  title: \"Q&A: Legacy Rails\"\n  raw_title: \"Legacy Rails Q&A Michael Feathers, Adam Hawkins, Andrzej Krzywda\"\n  speakers:\n    - Michael Feathers\n    - Adam Hawkins\n    - Andrzej Krzywda\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-18\"\n  video_provider: \"youtube\"\n  video_id: \"csiK5GCcjt8\"\n  description: \"\"\n  additional_resources:\n    - name: \"Questions\"\n      type: \"link\"\n      url: \"https://hackpad.com/wroc_love.rb-2014-legacy-rails-QA-jkKZpT0WUdb\"\n\n- id: \"micha-taszycki-wrocloverb-2014\"\n  title: \"Ruby: Write Once, Run Anywhere\"\n  raw_title: \"RUBY: WRITE ONCE, RUN ANYWHERE - Michał Taszycki\"\n  speakers:\n    - Michał Taszycki\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"nNYgW7RwcTc\"\n  description: |-\n    Some people say that Ruby is dying. Bullshit! I'd say it's more alive than ever.\n    Ruby used to be a language associated scripting and web backends. Now, thanks to RubyMotion we can write desktop and mobile apps. While Opal allows us to execute Ruby in a browser. With these tools we can finally write cross-platform Ruby applications.\n    After this talk you'll know how and you'll be eager to try it yourself.\n\n- id: \"alex-coles-wrocloverb-2014\"\n  title: \"Frontend Choices\"\n  raw_title: \"FRONTEND CHOICES - Alex Coles\"\n  speakers:\n    - Alex Coles\n  event_name: \"wroclove.rb 2014\"\n  date: \"2014-03-14\"\n  published_at: \"2014-04-20\"\n  video_provider: \"youtube\"\n  video_id: \"Cad8wUUrXNY\"\n  description: |-\n    Rails was born in 2004, the time of the \"Ajax revolution\". With the help of a little bit of prototype, scriptaculous and RJS, Rails made its mark in part because it facilitated creating beautiful and highly interactive web user interfaces in no time at all.\n    Fast forward to 2013. Frameworks like Meteor and Hoodie are capturing increasing mindshare. Are we now in the decade of JavaScript? Is the \"Rails Way\" still relevant to the Front End?\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2015/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKUi0WDpNIHd2UJ989XlCuqW\"\ntitle: \"wroclove.rb 2015\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: |-\n  March 13-15th 2015, Wrocław, Poland\nstart_date: \"2015-03-13\"\nend_date: \"2015-03-15\"\npublished_at: \"2015-03-13\"\nchannel_id: \"UCnl2p1jpQo4ITeFq4yqmVuA\"\nyear: 2015\nwebsite: \"https://2015.wrocloverb.com\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2015/videos.yml",
    "content": "---\n# TODO: conference website\n\n# Day 1\n\n- id: \"thorsten-ball-wrocloverb-2015\"\n  title: \"Unicorn Unix Magic Tricks\"\n  raw_title: \"Unicorn Unix Magic Tricks - Thorsten Ball - wroc_love.rb 2015\"\n  speakers:\n    - Thorsten Ball\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ZSRE-rGcEPs\"\n\n- id: \"micha-taszycki-wrocloverb-2015\"\n  title: \"What if Clean Code is a Scam\"\n  raw_title: \"What if Clean Code is a scam - Michał Taszycki - wroc_love.rb 2015\"\n  speakers:\n    - Michał Taszycki\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"JIu889NJYbM\"\n\n- id: \"todo-wrocloverb-2015\"\n  title: \"Lightning Talks - Day 1\"\n  raw_title: \"Lightning Talks - Friday - wroc_love.rb 2015\"\n  speakers:\n    - TODO\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"4grD-1Cde08\"\n\n# Day 2\n\n- id: \"ryan-stout-wrocloverb-2015\"\n  title: \"Volt\"\n  raw_title: \"Volt - Ryan Stout - wroc_love.rb 2015\"\n  speakers:\n    - Ryan Stout\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FgOLP4bMX90\"\n\n- id: \"nick-sutterer-wrocloverb-2015\"\n  title: \"Trailblazer\"\n  raw_title: \"Trailblazer - Nick Sutterer - wroc_love.rb 2015\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"K7P7PcO8ra4\"\n\n- id: \"nick-sutterer-wrocloverb-2015-panel-post-rails-world\"\n  title: \"Panel: Post-Rails World\"\n  raw_title: 'Panel \"Post-Rails world\" - Nick Sutterer, Ryan Stout, Jim Gay - wroc_love.rb 2015'\n  speakers:\n    - Nick Sutterer\n    - Ryan Stout\n    - Jim Gay\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"X2sJMVGPZ_E\"\n\n- id: \"nicolas-dermine-wrocloverb-2015\"\n  title: \"Live Code Music\"\n  raw_title: \"Live Code Music - Nicolas Dermine - wroc_love.rb 2015\"\n  speakers:\n    - Nicolas Dermine\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5cZfqXiivdA\"\n\n- id: \"alberto-brandolini-wrocloverb-2015\"\n  title: \"Event Storming\"\n  raw_title: \"Event Storming - Alberto Brandolini - wroc_love.rb 2015\"\n  speakers:\n    - Alberto Brandolini\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"veTVAN0oEkQ\"\n\n- id: \"todo-wrocloverb-2015-lightning-talks-day-2\"\n  title: \"Lightning Talks - Day 2\"\n  raw_title: \"Lightning Talks - Saturday - wroc_love.rb 2015\"\n  speakers:\n    - TODO\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"5SpdE5doLog\"\n\n# Day 3\n\n- id: \"ivan-nemytchenko-wrocloverb-2015\"\n  title: \"From Rails-way to Modular Architecture\"\n  raw_title: \"From Rails-way to modular architecture - Ivan Nemytchenko - wroc_love.rb 2015\"\n  speakers:\n    - Ivan Nemytchenko\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"al2LZ-7qX7k\"\n\n- id: \"sebastian-sogamoso-wrocloverb-2015\"\n  title: \"Microservices\"\n  raw_title: \"Microservices - Sebastian Sogamoso - wroc_love.rb 2015\"\n  speakers:\n    - Sebastian Sogamoso\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"gphGTGzas98\"\n\n- id: \"albert-brandolini-wrocloverb-2015\"\n  title: \"Panel: DDD/CQRS/ES\"\n  raw_title: 'Panel \"DDD/CQRS/ES\" - wroc_love.rb 2015'\n  speakers:\n    - Albert Brandolini\n    - Andrzej Krzywda\n    - Mirek Pragłowski\n    - Sebastian Sogamoso\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: |-\n    Albert Brandolini, Andrzej Krzywda, Mirek Pragłowski, Sebastian Sogamoso\n  video_provider: \"youtube\"\n  video_id: \"Rh2A96rpGpY\"\n\n- id: \"jim-gay-wrocloverb-2015\"\n  title: \"The Missing System\"\n  raw_title: \"The Missing System - Jim Gay - wroc_love.rb 2015\"\n  speakers:\n    - Jim Gay\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"huRWC7iFZxM\"\n\n- id: \"norbert-wjtowicz-wrocloverb-2015\"\n  title: \"ClojureScript + React.js\"\n  raw_title: \"ClojureScript + React.js - Norbert Wójtowicz - wroc_love.rb 2015\"\n  speakers:\n    - Norbert Wójtowicz\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"6_mbxaRDA-s\"\n\n- id: \"todo-wrocloverb-2015-lightning-talks-day-3\"\n  title: \"Lightning Talks - Day 3\"\n  raw_title: \"Lightning Talks - Sunday - wroc_love.rb 2015\"\n  speakers:\n    - TODO\n  event_name: \"wroclove.rb 2015\"\n  date: \"2015-03-13\"\n  published_at: \"2015-04-10\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"C6zIIOwVX3Q\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2016/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKUEgWk1rjpGLgWclPKTbUWU\"\ntitle: \"wroclove.rb 2016\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: |-\n  March 11-13th 2016, Wrocław Poland\nstart_date: \"2016-03-11\"\nend_date: \"2016-03-13\"\npublished_at: \"2016-03-11\"\nchannel_id: \"UCnl2p1jpQo4ITeFq4yqmVuA\"\nyear: 2016\nwebsite: \"https://2016.wrocloverb.com\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2016/videos.yml",
    "content": "---\n# TODO: conference website\n\n# Day 1\n\n- id: \"andrzej-krzywda-wrocloverb-2016\"\n  title: \"From Rails Legacy to DDD\"\n  raw_title: \"From Rails legacy to DDD - Andrzej Krzywda - wroc_love.rb 2016\"\n  speakers:\n    - Andrzej Krzywda\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-11\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"LrSBrHgCLm8\"\n\n- id: \"elia-schito-wrocloverb-2016\"\n  title: \"Opal.rb\"\n  raw_title: \"Opal.rb - Elia Schito - wroc_love.rb 2016\"\n  speakers:\n    - Elia Schito\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-11\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"vhIrrlcWphU\"\n\n- id: \"lightning-talks-day-1-wroclove-rb-2016\"\n  title: \"Lightning Talks (Day 1)\"\n  raw_title: \"Lightning talks, day 1 - wroc_love.rb 2016\"\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-11\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"DgphJ_sYFMM\"\n  talks:\n    - title: \"Lightning Talk: Docker Cloud @ Codebeat\"\n      date: \"2016-03-11\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"janek-grodowski-lighting-talk-wroclove-rb-2016\"\n      video_id: \"janek-grodowski-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Janek Grodowski\n\n    - title: \"Lightning Talk: Difference Between Facebook and Snapchat\"\n      date: \"2016-03-11\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-lighting-talk-wroclove-rb-2016-1\"\n      video_id: \"todo-lighting-talk-wroclove-rb-2016-1\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing speaker name https://cln.sh/ChJw3H5C\n\n    - title: \"Lightning Talk: Haskell in Ruby\"\n      date: \"2016-03-11\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-zajac-lighting-talk-wroclove-rb-2016\"\n      video_id: \"michal-zajac-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Zając\n\n# Day 2\n\n- id: \"barbara-fusiska-wrocloverb-2016\"\n  title: \"The R language\"\n  raw_title: \"The R language - Barbara Fusińska - wroc_love.rb 2016\"\n  speakers:\n    - Barbara Fusińska\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-12\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"puPYAOdtFkE\"\n\n- id: \"robert-pankowecki-wrocloverb-2016\"\n  title: \"The Saga Pattern\"\n  raw_title: \"The Saga Pattern - Robert Pankowecki - wroc_love.rb 2016\"\n  speakers:\n    - Robert Pankowecki\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-12\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"ECvDJ5ULgN8\"\n\n- id: \"tatiana-vasilyeva-wrocloverb-2016\"\n  title: \"Ruby and Code Editors\" # TODO: use cues\n  raw_title: \"Ruby and Code Editors Fight - wroc_love.rb 2016\"\n  speakers:\n    - Tatiana Vasilyeva # RubyMine\n    - Elia Schito # TextMate\n    - Grzegorz Łuszczek # vim\n    - Wiktor Mociun # vim\n    - Thiago Massa # Emacs/Spacemacs\n    - Ondřej Bartas # Atom\n    - squixy # TODO: real name # Sublime # https://cln.sh/HjphZ2WJ\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-12\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"CSHmIzaYpf8\"\n\n- id: \"sander-van-der-burg-wrocloverb-2016\"\n  title: \"The NixOS project and deploying systems declaratively\"\n  raw_title: \"The NixOS project and deploying systems declaratively - Sander van der Burg - wroc_love.rb 2016\"\n  speakers:\n    - Sander van der Burg\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-12\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Ue7NrIlH4A0\"\n\n- id: \"wojciech-ziniewicz-wrocloverb-2016\"\n  title: \"ROS - ecosystem for things\"\n  raw_title: \"ROS - ecosystem for things - Wojciech Ziniewicz - wroc_love.rb 2016\"\n  speakers:\n    - Wojciech Ziniewicz\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-12\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"N89jx_Q666c\"\n\n- id: \"lightning-talks-day-2-wroclove-rb-2016\"\n  title: \"Lightning Talks (Day 2)\"\n  raw_title: \"Lightning talks, day 2 - wroc_love.rb 2016\"\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-12\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"lH17KGcwnqU\"\n  talks:\n    - title: \"Lightning Talk: Ruby Internships - What We Do To Teach Ruby?\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"maciek-rzasa-lighting-talk-wroclove-rb-2016\"\n      video_id: \"maciek-rzasa-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Maciek Rząsa\n\n    - title: \"Lightning Talk: What annoys you about the CI?\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-lighting-talk-wroclove-rb-2016-1-lightning-talk-what-annoys-you\"\n      video_id: \"todo-lighting-talk-wroclove-rb-2016-1\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name https://cln.sh/FWmmnGhc\n\n    - title: \"Lightning Talk: Estimating Anyone?\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tomek-rusilko-lighting-talk-wroclove-rb-2016\"\n      video_id: \"tomek-rusilko-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomek Rusiłko\n\n    - title: \"Lightning Talk: Spree Commerce\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"adam-jahn-lighting-talk-wroclove-rb-2016\"\n      video_id: \"adam-jahn-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Jahn\n\n    - title: \"Lightning Talk: ETag Tracking\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"adam-niedzielski-lighting-talk-wroclove-rb-2016\"\n      video_id: \"adam-niedzielski-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Niedzielski\n\n    - title: \"Lightning Talk: Features you probably don't know in RubyMine\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tatiana-vasilyeva-lighting-talk-wroclove-rb-2016\"\n      video_id: \"tatiana-vasilyeva-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Tatiana Vasilyeva\n\n    - title: \"Lightning Talk: Sonic Pi\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"nicolas-dermine-lighting-talk-wroclove-rb-2016\"\n      video_id: \"nicolas-dermine-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Nicolas Dermine\n\n    - title: \"Lightning Talk: Rubbish Ruby Code Contest\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-zajac-lighting-talk-wroclove-rb-2016-lightning-talk-rubbish-ruby-co\"\n      video_id: \"michal-zajac-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Zając\n\n    - title: \"Lightning Talk: Protocol Buffers @ Codebeat\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"marcin-wyszynski-lighting-talk-wroclove-rb-2016\"\n      video_id: \"marcin-wyszynski-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Marcin Wyszynski\n\n    - title: \"Lightning Talk: CPR with your client (or: How to deal with clients and stay sane)\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"mateusz-sagan-lighting-talk-wroclove-rb-2016\"\n      video_id: \"mateusz-sagan-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Mateusz Sagan\n\n    - title: \"Lightning Talk: Grape/Grape Swapper\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"peter-scholz-lighting-talk-wroclove-rb-2016\"\n      video_id: \"peter-scholz-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Peter Scholz\n\n    - title: \"Lightning Talk: How to keep your Junior Happy - and productive... and motivated\"\n      date: \"2016-03-12\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"gosia-ksionek-lighting-talk-wroclove-rb-2016\"\n      video_id: \"gosia-ksionek-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Gosia Ksionek\n\n# Day 3\n\n- id: \"oskar-szrajer-wrocloverb-2016\"\n  title: \"1 year with ROM on production\"\n  raw_title: \"1 year with ROM on production - Oskar Szrajer - wroc_love.rb 2016\"\n  speakers:\n    - Oskar Szrajer\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-13\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"GhPcW6D_qjY\"\n\n- id: \"kacper-walanus-wrocloverb-2016\"\n  title: \"Consumer Driven Contracts in Ruby on Rails\"\n  raw_title: \"Consumer Driven Contracts in Ruby on Rails - Kacper Walanus - wroc_love.rb 2016\"\n  speakers:\n    - Kacper Walanus\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-13\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"83tL6J_er7k\"\n\n- id: \"pawe-pacana-wrocloverb-2016\"\n  title: \"Panel: Rails Deployment\"\n  raw_title: \"Rails Deployment Panel - wroc_love.rb 2016\"\n  speakers:\n    - Paweł Pacana\n    - Michał Łomnicki\n    - Tymon Tobolski\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-13\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"C3w24NJxHeg\"\n\n- id: \"peter-bhat-harkins-wrocloverb-2016\"\n  title: \"Lessons of Liskov\"\n  raw_title: \"Lessons of Liskov - Peter Bhat Harkins - wroc_love.rb 2016\"\n  speakers:\n    - Peter Bhat Harkins\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-13\"\n  published_at: \"2016-05-07\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"tg3YjMqWNj0\"\n\n- id: \"lightning-talks-day-3-wroclove-rb-2016\"\n  title: \"Lightning Talks (Day 3)\"\n  raw_title: \"Lightning talks, day 3 - wroc_love.rb 2016\"\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-13\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"nvRgLtQjO0U\"\n  talks:\n    - title: \"Lightning Talk: Explore Your Coffee\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"anton-paisov-lighting-talk-wroclove-rb-2016\"\n      video_id: \"anton-paisov-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Anton Paisov\n\n    - title: \"Lightning Talk: AirHelp\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-lighting-talk-wroclove-rb-2016-1-lightning-talk-airhelp\"\n      video_id: \"todo-lighting-talk-wroclove-rb-2016-1\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing speaker name - https://cln.sh/GwhWdqrl\n\n    - title: \"Lightning Talk: Let's Talk About NPM\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"wiktor-mociun-lighting-talk-wroclove-rb-2016\"\n      video_id: \"wiktor-mociun-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Wiktor Mociun\n\n    - title: \"Lightning Talk: Image Processing Tips\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"thiago-massa-lighting-talk-wroclove-rb-2016\"\n      video_id: \"thiago-massa-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Thiago Massa\n\n    - title: \"Lightning Talk: Ruby and a Graph\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"piotr-walkowski-lighting-talk-wroclove-rb-2016\"\n      video_id: \"piotr-walkowski-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Piotr Walkowski\n\n    - title: \"Lightning Talk: Let's talk about git\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"patrick-helm-lighting-talk-wroclove-rb-2016\"\n      video_id: \"patrick-helm-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Patrick Helm\n\n    - title: \"Lightning Talk: Why no Windows 9?\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"wojciech-piekutowski-lighting-talk-wroclove-rb-2016\"\n      video_id: \"wojciech-piekutowski-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Wojciech Piekutowski\n\n    - title: \"Lightning Talk: How Meditation Helped Me Fight Procrastination\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tatiana-vasilyeva-lighting-talk-wroclove-rb-2016-lightning-talk-how-meditation-\"\n      video_id: \"tatiana-vasilyeva-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Tatiana Vasilyeva\n\n    - title: \"Lightning Talk: minirails\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tymon-tobolski-lighting-talk-wroclove-rb-2016\"\n      video_id: \"tymon-tobolski-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Tymon Tobolski\n\n    - title: \"Lightning Talk: Google Summer of Code\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-muskala-lighting-talk-wroclove-rb-2016\"\n      video_id: \"michal-muskala-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Muskała\n\n    - title: \"Lightning Talk: systemd examples\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pawel-pacana-lighting-talk-wroclove-rb-2016\"\n      video_id: \"pawel-pacana-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Paweł Pacana\n\n    - title: \"Lightning Talk: DRUGStock 2016\"\n      date: \"2016-03-13\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-lomnicki-lighting-talk-wroclove-rb-2016\"\n      video_id: \"michal-lomnicki-lighting-talk-wroclove-rb-2016\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Łomnicki\n\n- id: \"sebastian-sogamoso-wrocloverb-2016\"\n  title: \"When Making Money Becomes a Headache\"\n  raw_title: \"When making money becomes a headache - Sebastian Sogamoso - wroc_love.rb 2016\"\n  speakers:\n    - Sebastian Sogamoso\n  event_name: \"wroclove.rb 2016\"\n  date: \"2016-03-13\"\n  published_at: \"2016-04-20\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"py6JSeIIbWU\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2017/event.yml",
    "content": "---\nid: \"PLvpu5WTDxTKXWU8lq1V9rzJ4g4vOPvfP9\"\ntitle: \"wroclove.rb 2017\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: |-\n  March 17-19th 2017, Wrocław Poland\nstart_date: \"2017-03-17\"\nend_date: \"2017-03-19\"\npublished_at: \"2017-03-17\"\nchannel_id: \"UCnl2p1jpQo4ITeFq4yqmVuA\"\nyear: 2017\nwebsite: \"https://2017.wrocloverb.com\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2017/videos.yml",
    "content": "---\n# TODO: conference website\n\n# Day 1\n\n- id: \"maciej-mensfeld-wrocloverb-2017\"\n  title: \"Karafka - Place Where Ruby, Rails and Kafka Meet Together\"\n  raw_title: \"KARAFKA - PLACE WHERE RUBY, RAILS AND KAFKA MEET TOGETHER - Maciej Mensfeld - wroc_love.rb 2017\"\n  speakers:\n    - Maciej Mensfeld\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"FU0NGg385ZM\"\n\n- id: \"mariusz-gil-wrocloverb-2017\"\n  title: \"Machine Learning For The Rescue\"\n  raw_title: \"MACHINE LEARNING FOR THE RESCUE - Mariusz Gil - wroc_love.rb 2017\"\n  speakers:\n    - Mariusz Gil\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"0RUtb4GxdGs\"\n\n- id: \"lightning-talks-day-1-wroclove-rb-2017\"\n  title: \"Lightning Talks (Day 1)\"\n  raw_title: \"Lightning talks, day 1 - wroc_love.rb 2017\"\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3ECYpI55dj0\"\n  talks:\n    - title: \"Lightning Talk: Spree\"\n      date: \"2017-03-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"damian-legawiec-lighting-talk-wroclove-rb-2017\"\n      video_id: \"damian-legawiec-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Damian Legawiec\n\n    - title: \"Lightning Talk: Ruby is blazing fast - make Ruby great again\"\n      date: \"2017-03-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-lighting-talk-wroclove-rb-2017-1\"\n      video_id: \"todo-lighting-talk-wroclove-rb-2017-1\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name\n\n    - title: \"Lightning Talk: What is the Model?\"\n      date: \"2017-03-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jan-filipowski-lighting-talk-wroclove-rb-2017\"\n      video_id: \"jan-filipowski-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jan Filipowski\n\n    - title: \"Lightning Talk: The new old medium (at least for me)\"\n      date: \"2017-03-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"bartosz-bonislawski-lighting-talk-wroclove-rb-2017\"\n      video_id: \"bartosz-bonislawski-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Bartosz Bonisławski\n\n    - title: \"Lightning Talk: Symphony\"\n      date: \"2017-03-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"piotr-steininger-lighting-talk-wroclove-rb-2017\"\n      video_id: \"piotr-steininger-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Piotr Steininger\n\n    - title: \"Lightning Talk: Dairy Log\"\n      date: \"2017-03-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"niklas-hofer-lighting-talk-wroclove-rb-2017\"\n      video_id: \"niklas-hofer-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Niklas Hofer\n\n# Day 2\n\n- id: \"sebastian-sogamoso-wrocloverb-2017\"\n  title: \"The Overnight Failure\"\n  raw_title: \"THE OVERNIGHT FAILURE - Sebastian Sogamoso - wroc_love.rb 2017\"\n  speakers:\n    - Sebastian Sogamoso\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Q-KAfm0bx4E\"\n\n- id: \"hubert-picki-wrocloverb-2017\"\n  title: \"Fault Tolerance in Ruby\"\n  raw_title: \"FAULT TOLERANCE IN RUBY - Hubert Łępicki - wroc_love.rb 2017\"\n  speakers:\n    - Hubert Łępicki\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"XPvpZ2QgvBI\"\n\n- id: \"valentin-fondaratov-wrocloverb-2017\"\n  title: \"Automated Type Contracts Generation For Ruby\"\n  raw_title: \"AUTOMATED TYPE CONTRACTS GENERATION FOR RUBY - Valentin Fondaratov - wroc_love.rb 2017\"\n  speakers:\n    - Valentin Fondaratov\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"EPeQuy5SOGM\"\n\n- id: \"andrzej-krzywda-wrocloverb-2017\"\n  title: \"Panel: Elixir vs. Ruby\"\n  raw_title: \"PANEL - ELIXIR vs. RUBY FIGHT - wroc_love.rb 2017\"\n  speakers:\n    # - TODO # moderator # https://cln.sh/8KRFp56P\n    # - TODO # https://cln.sh/BPbmNwCg\n    # - TODO # https://cln.sh/CQPHqylG\n    - Andrzej Krzywda\n    # - TODO # https://cln.sh/qpG3rsWm\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"O5dzsG5grK4\"\n\n- id: \"piotr-szmielew-wrocloverb-2017\"\n  title: \"Bindings in Ruby - Behind the Magic of Blocks\"\n  raw_title: \"BINDINGS IN RUBY - BEHIND THE MAGIC OF BLOCKS - Piotr Szmielew - wroc_love.rb 2017\"\n  speakers:\n    - Piotr Szmielew\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"yiwvk240ZBM\"\n  slides_url: \"https://speakerdeck.com/esse/bindings-in-ruby-behind-the-magic-of-blocks\"\n\n- id: \"lightning-talks-day-2-wroclove-rb-2017\"\n  title: \"Lightning Talks - Day 2\"\n  raw_title: \"Lightning talks, day 2 - wroc_love.rb 2017\"\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-18\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"LEYrdNzgCUk\"\n  talks:\n    - title: \"Lightning Talk: How to Become a Better Ruby Programmer\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-konarski-lighting-talk-wroclove-rb-2017\"\n      video_id: \"michal-konarski-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Konarski\n\n    - title: \"Lightning Talk: Come to #pivorak\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"anton-paisov-lighting-talk-wroclove-rb-2017\"\n      video_id: \"anton-paisov-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Anton Paisov\n\n    - title: \"Lightning Talk: Reveal the Unicode\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jan-lelis-lighting-talk-wroclove-rb-2017\"\n      video_id: \"jan-lelis-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jan Lelis\n\n    - title: \"Lightning Talk: DRY System\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"krzysztof-wawer-lighting-talk-wroclove-rb-2017\"\n      video_id: \"krzysztof-wawer-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Krzysztof Wawer\n\n    - title: \"Lightning Talk: Say Hello with Nexmo\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"piotr-steininger-lighting-talk-wroclove-rb-2017-lightning-talk-say-hello-with-\"\n      video_id: \"piotr-steininger-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Piotr Steininger\n\n    - title: \"Lightning Talk: Calling Go From Ruby\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"alexander-biryukov-lighting-talk-wroclove-rb-2017\"\n      video_id: \"alexander-biryukov-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Alexander Biryukov\n\n    - title: \"Lightning Talk: tig - git tool\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-knapik-lighting-talk-wroclove-rb-2017\"\n      video_id: \"michal-knapik-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Knapik\n\n    - title: \"Lightning Talk: Rethink Sitting\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jan-dudek-lighting-talk-wroclove-rb-2017\"\n      video_id: \"jan-dudek-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Jan Dudek\n\n    - title: \"Lightning Talk: Platform for First Blog Bartosz Bonislawski\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"bartosz-bonislawski-lighting-talk-wroclove-rb-2017-lightning-talk-platform-for-fi\"\n      video_id: \"bartosz-bonislawski-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Bartosz Bonisławski\n\n    - title: \"Lightning Talk: Unexpected Case of Rescue Exception\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"artur-debski-lighting-talk-wroclove-rb-2017\"\n      video_id: \"artur-debski-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Artur Dębski\n\n    - title: \"Lightning Talk: Gravity of Code\"\n      date: \"2017-03-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"robert-pankowecki-lighting-talk-wroclove-rb-2017\"\n      video_id: \"robert-pankowecki-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Robert Pankowecki\n\n# Day 3\n\n- id: \"norbert-wjtowicz-wrocloverb-2017\"\n  title: \"The Babel Fish is Data: A Case Study\"\n  raw_title: \"THE BABEL FISH IS DATA: A CASE STUDY - Norbert Wójtowicz - wroc_love.rb 2017\"\n  speakers:\n    - Norbert Wójtowicz\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"l5ML_4WnAWg\"\n\n- id: \"maciej-rzsa-wrocloverb-2017\"\n  title: \"We All Build Distributed Systems\"\n  raw_title: \"WE ALL BUILD DISTRIBUTED SYSTEMS - Maciej Rząsa - wroc_love.rb 2017\"\n  speakers:\n    - Maciej Rząsa\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"2AvMrZtvQSc\"\n\n- id: \"wojciech-rzsa-wrocloverb-2017\"\n  title: \"Predicting Performance Changes of Distributed Applications\"\n  raw_title: \"PREDICTING PERFORMANCE CHANGES OF DISTRIBUTED APPLICATIONS - Wojciech Rząsa - wroc_love.rb 2017\"\n  speakers:\n    - Wojciech Rząsa\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"GmRVbmntenY\"\n\n- id: \"micha-czy-wrocloverb-2017\"\n  title: \"Panel: How to Survive in the JavaScript World\"\n  raw_title: \"PANEL - HOW TO SURVIVE IN THE JAVASCRIPT WORLD - wroc_love.rb 2017\"\n  speakers:\n    # - TODO # moderator # https://cln.sh/dQQ25jng\n    # - TODO # https://cln.sh/tLM93Ln3\n    - Michał Czyż\n    # - TODO # https://cln.sh/k0vqTM0H\n    # - TODO # https://cln.sh/y4RYtsfC\n    # - TODO # https://cln.sh/pHFt2cgG\n    # - TODO # https://cln.sh/xnmKzjCR\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"3swsZ5dOjOY\"\n\n- id: \"petr-chalupa-wrocloverb-2017\"\n  title: \"concurrent-ruby\"\n  raw_title: \"CONCURRENT-RUBY - Petr Chalupa - wroc_love.rb 2017\"\n  speakers:\n    - Petr Chalupa\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"WQ0pNulvl-Q\"\n\n- id: \"lightning-talks-day-3-wroclove-rb-2017\"\n  title: \"Lightning Talks (Day 3)\"\n  raw_title: \"Lightning talks, day 3 - wroc_love.rb 2017\"\n  event_name: \"wroclove.rb 2017\"\n  date: \"2017-03-17\"\n  published_at: \"2017-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"0u_h5cEFlLc\"\n  talks:\n    - title: \"Lightning Talk: Migrating database between projects\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"maciek-walusiak-lighting-talk-wroclove-rb-2017\"\n      video_id: \"maciek-walusiak-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Maciek Walusiak\n      slides_url: \"https://slides.com/maciekwalusiak/migrating-database\"\n\n    - title: \"Lightning Talk: Git Bisect - When problems get serious\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"dawid-jaskot-lighting-talk-wroclove-rb-2017\"\n      video_id: \"dawid-jaskot-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Dawid Jaskot\n\n    - title: \"Lightning Talk: Memory and Wikipedia\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"georgy-buranov-lighting-talk-wroclove-rb-2017\"\n      video_id: \"georgy-buranov-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Georgy Buranov\n\n    - title: \"Lightning Talk: Fun facts about Spree (and Damian Legawiec)\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"maciej-mensfeld-lighting-talk-wroclove-rb-2017\"\n      video_id: \"maciej-mensfeld-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Maciej Mensfeld\n\n    - title: \"Lightning Talk: Pattern Matching\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pawel-swiatkowski-lighting-talk-wroclove-rb-2017\"\n      video_id: \"pawel-swiatkowski-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Paweł Świątkowski\n\n    - title: \"Lightning Talk: Dealing with Technical Debt\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tomek-w-lighting-talk-wroclove-rb-2017\"\n      video_id: \"tomek-w-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomek W # TODO: missing lastname - https://cln.sh/LhpHmF8w\n\n    - title: \"Lightning Talk: discombobulate\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"norbert-wojtowicz-lighting-talk-wroclove-rb-2017\"\n      video_id: \"norbert-wojtowicz-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Norbert Wójtowicz\n\n    - title: \"Lightning Talk: Elixir is Awesome\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-muskala-lighting-talk-wroclove-rb-2017\"\n      video_id: \"michal-muskala-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Muskała\n\n    - title: \"Lightning Talk: Google Summer of Code\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"emmanuel-hayford-lighting-talk-wroclove-rb-2017\"\n      video_id: \"emmanuel-hayford-lighting-talk-wroclove-rb-2017\"\n      video_provider: \"parent\"\n      speakers:\n        - Emmanuel Hayford\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2018/event.yml",
    "content": "---\nid: \"PLoGBNJiQoqRDSMznObXnqyq5HbOqLucTz\"\ntitle: \"wroclove.rb 2018\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: \"\"\nstart_date: \"2018-04-16\"\nend_date: \"2018-04-18\"\npublished_at: \"2018-04-16\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2018\nwebsite: \"https://2018.wrocloverb.com\"\ncoordinates:\n  latitude: 51.10929480000001\n  longitude: 17.0386019\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2018/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"stefan-wintermeyer-wrocloverb-2018\"\n  title: \"Better WebPerformance with Rails\"\n  raw_title: \"Better WebPerformance with Rails - Stefan Wintermeyer - wroc_love.rb 2018\"\n  speakers:\n    - Stefan Wintermeyer\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"UIC0sM-VQj8\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"vladimir-dementyev-wrocloverb-2018\"\n  title: \"Cables! Cables! Cables!\"\n  raw_title: \"Cables! Cables! Cables! - Vladimir Dementyev - wroc_love.rb 2018\"\n  speakers:\n    - Vladimir Dementyev\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"AUxFFOehiy0\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://speakerdeck.com/palkan/wroc-love-dot-rb-2018-cables-cables-cables\"\n  # https://x.com/JacekCzarnecki/status/974962005378465793\n\n- id: \"ivan-nemytchenko-wrocloverb-2018\"\n  title: \"Counterintuitive Rails Pt. 1\"\n  raw_title: \"Counterintuitive Rails pt. 1 - Ivan Nemytchenko - wroc_love.rb 2018\"\n  speakers:\n    - Ivan Nemytchenko\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"KtD32fO_owU\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n  # https://x.com/JacekCzarnecki/status/974975962239651840\n\n- id: \"nick-sutterer-wrocloverb-2018\"\n  title: \"Panel: Enterprise Rails\"\n  raw_title: \"Enterprise Rails panel - wroc_love.rb 2018\"\n  speakers:\n    - Nick Sutterer\n    - Andrzej Krzywda\n    - Nathan Ladd\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"Tx2WsK0qD7k\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"nick-sutterer-wrocloverb-2018-super-aint-super-from-oop-to-f\"\n  title: \"Super Ain't Super: From OOP To FP and Beyond!\"\n  raw_title: \"SUPER AIN'T SUPER: From OOP To FP and Beyond! - Nick Sutterer - wroc_love.rb 2018\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"JRpNIm1-KgA\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n  # https://x.com/JacekCzarnecki/status/975036724429680640\n\n- id: \"nathan-ladd-wrocloverb-2018\"\n  title: \"Event Sourcing Anti Patterns and Failures\"\n  raw_title: \"Event Sourcing Anti Patterns and Failures - Nathan Ladd - wroc_love.rb 2018\"\n  speakers:\n    - Nathan Ladd\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"vh1QTk34350\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"andrzej-liwa-wrocloverb-2018\"\n  title: \"Applying CQRS & Event Sourcing on Rails applications\"\n  raw_title: \"Applying CQRS & Event Sourcing on Rails applications - Andrzej Śliwa - wroc_love.rb 2018\"\n  speakers:\n    - Andrzej Śliwa\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"cdwX1ZU623E\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n  # https://x.com/JacekCzarnecki/status/975068584534855680\n\n- id: \"ukasz-szydo-wrocloverb-2018\"\n  title: \"Understanding Coupling\"\n  raw_title: \"Understanding coupling - Łukasz Szydło - wroc_love.rb 2018\"\n  speakers:\n    - Łukasz Szydło\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"Jy6eS9QHJOM\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n  # https://x.com/JacekCzarnecki/status/975313307996434432\n\n- id: \"armin-paali-wrocloverb-2018\"\n  title: \"Beyond the Current State: Time Travel to the Rescue!\"\n  raw_title: \"Beyond the current state: Time travel to the rescue! - Armin Pašalić - wroc_love.rb 2018\"\n  speakers:\n    - Armin Pašalić\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"smqXOZRHG_Q\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"ivan-nemytchenko-wrocloverb-2018-counterintuitive-rails-pt-2\"\n  title: \"Counterintuitive Rails Pt. 2\"\n  raw_title: \"Counterintuitive Rails pt. 2 - Ivan Nemytchenko - wroc_love.rb 2018\"\n  speakers:\n    - Ivan Nemytchenko\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"kW2E2wK7_Fw\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"dawid-poliski-wrocloverb-2018\"\n  title: \"Panel: Modern JS\"\n  raw_title: \"Modern JS Panel - wroc_love.rb 2018\"\n  speakers:\n    - Dawid Pośliński\n    - Maciej Walusiak\n    # - TODO: one more panelist\n    # - TODO: moderator\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"vL0Mb1XY_UI\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"damir-zeki-wrocloverb-2018\"\n  title: \"Toolbelt of a Seasoned Bug Hunter\"\n  raw_title: \"Toolbelt of a Seasoned Bug Hunter - Damir Zekić - wroc_love.rb 2018\"\n  speakers:\n    - Damir Zekić\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"11Z4Fx8dXhc\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"micha-moniak-wrocloverb-2018\"\n  title: \"MVCC for Ruby developers\"\n  raw_title: \"MVCC for Ruby developers - Michał Młoźniak - wroc_love.rb 2018\"\n  speakers:\n    - Michał Młoźniak\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"hMLekHYXvJo\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"marco-heimeshoff-wrocloverb-2018\"\n  title: \"The Pillars of Domain Driven Design\"\n  raw_title: \"The pillars of Domain Driven Design - Marco Heimeshoff - wroc_love.rb 2018 / DDD Wrocław\"\n  speakers:\n    - Marco Heimeshoff\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-16\"\n  video_provider: \"youtube\"\n  video_id: \"FmJ6YMW92wA\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n  # https://x.com/JacekCzarnecki/status/974698486460551178\n\n- id: \"lightning-talks-day-2-wroclove-rb-2018\"\n  title: \"Lightning Talks (Day 2)\"\n  raw_title: \"Lightning talks Saturday - wroc_love.rb 2018\"\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-17\"\n  video_provider: \"youtube\"\n  video_id: \"tWu4gO187G0\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Serverless Ruby\"\n      date: \"2018-04-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"bartosz-bonislawski-lighting-talk-wroclove-rb-2018\"\n      video_id: \"bartosz-bonislawski-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Bartosz Bonisławski\n\n    - title: \"Lightning Talk: Ruby on $4 computer - mruby on esp32\"\n      date: \"2018-04-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"sergey-silnov-lighting-talk-wroclove-rb-2018\"\n      video_id: \"sergey-silnov-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Sergey Silnov\n\n    - title: \"Lightning Talk: How wroc_love.rb impacts developers and companies\"\n      date: \"2018-04-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"adam-skoluda-lighting-talk-wroclove-rb-2018\"\n      video_id: \"adam-skoluda-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Skołuda\n\n    - title: \"Lightning Talk: To Refine Or Not To Refine\"\n      date: \"2018-04-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"vladimir-dementyev-lighting-talk-wroclove-rb-2018\"\n      video_id: \"vladimir-dementyev-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Vladimir Dementyev\n      slides_url: \"https://speakerdeck.com/palkan/wroc-love-dot-rb-2018-lightning-talk-to-refine-or-not-to-refine\"\n\n    - title: \"Lightning Talk: Removing code like a pro\"\n      date: \"2018-04-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-mlozniak-lighting-talk-wroclove-rb-2018\"\n      video_id: \"michal-mlozniak-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Młoźniak\n\n    - title: \"Lightning Talk: Why We Love Ruby\"\n      date: \"2018-04-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"artur-roszczyk-lighting-talk-wroclove-rb-2018\"\n      video_id: \"artur-roszczyk-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Artur Roszczyk\n\n    - title: \"Lightning Talk: Thoughts: What it means to be a developer. Will computers replace us?\"\n      date: \"2018-04-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"maciek-stanisz-lighting-talk-wroclove-rb-2018\"\n      video_id: \"maciek-stanisz-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Maciek Stanisz\n\n    - title: \"Lightning Talk: How to break your browser by using a regexp\"\n      date: \"2018-04-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"maciek-rzasa-lighting-talk-wroclove-rb-2018\"\n      video_id: \"maciek-rzasa-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Maciek Rząsa\n\n- id: \"lightning-talks-day-3-wroclove-rb-2018\"\n  title: \"Lightning Talks (Day 3)\"\n  raw_title: \"Lightning talks Sunday - wroc_love.rb 2018\"\n  event_name: \"wroclove.rb 2018\"\n  date: \"2018-04-18\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"fp95RYuxIXQ\"\n  published_at: \"2018-04-16\"\n  language: \"English\"\n  talks:\n    - title: \"Lightning Talk: Ethereum\"\n      date: \"2018-04-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"dima-todo-lighting-talk-wroclove-rb-2018\"\n      video_id: \"dima-todo-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Dima # TODO: missing lastname\n\n    - title: \"Lightning Talk: Decoupling Ruby With a Bus\"\n      date: \"2018-04-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"armin-pasalic-lighting-talk-wroclove-rb-2018\"\n      video_id: \"armin-pasalic-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Armin Pašalić\n\n    - title: \"Lightning Talk: Refinement Use Cases\"\n      date: \"2018-04-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"vladimir-dementyev-lighting-talk-wroclove-rb-2018-lightning-talk-refinement-use-\"\n      video_id: \"vladimir-dementyev-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Vladimir Dementyev\n\n    - title: \"Lightning Talk: Discrations\"\n      date: \"2018-04-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tom-woo-lighting-talk-wroclove-rb-2018\"\n      video_id: \"tom-woo-lighting-talk-wroclove-rb-2018\"\n      video_provider: \"parent\"\n      speakers:\n        - Tom Woo\n\n    - title: \"Lightning Talk: Secrets of Ruby stdlib\"\n      date: \"2018-04-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-lighting-talk-wroclove-rb-2018-1\"\n      video_id: \"todo-lighting-talk-wroclove-rb-2018-1\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name\n\n    - title: \"Lightning Talk: How I play games using Ruby\"\n      date: \"2018-04-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-lighting-talk-wroclove-rb-2018-2\"\n      video_id: \"todo-lighting-talk-wroclove-rb-2018-2\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name\n\n    - title: \"Lightning Talk: Heavy Applications\"\n      date: \"2018-04-18\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"todo-lighting-talk-wroclove-rb-2018-3\"\n      video_id: \"todo-lighting-talk-wroclove-rb-2018-3\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing name\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2019/event.yml",
    "content": "---\nid: \"PLoGBNJiQoqRDJvwOYLuu7jnprRKhuc7Cp\"\ntitle: \"wroclove.rb 2019\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: \"\"\nstart_date: \"2019-03-22\"\nend_date: \"2019-03-24\"\npublished_at: \"2019-05-13\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2019\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://2019.wrocloverb.com\"\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2019/venue.yml",
    "content": "# https://2019.wrocloverb.com\n---\nname: \"University of Wrocław\"\n\ndescription: |-\n  Institute of Computer Science\n\naddress:\n  street: \"1 plac Uniwersytecki\"\n  city: \"Wrocław\"\n  region: \"Województwo dolnośląskie\"\n  postal_code: \"50-137\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"plac Uniwersytecki 1, 50-137 Wrocław, Poland\"\n\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n\nmaps:\n  google: \"https://maps.google.com/?q=University+of+Wrocław,+Institute+of+Computer+Science,51.1140053,17.034463\"\n  apple: \"https://maps.apple.com/?q=University+of+Wrocław,+Institute+of+Computer+Science&ll=51.1140053,17.034463\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=51.1140053&mlon=17.034463\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2019/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"ethan-garofolo-wrocloverb-2019\"\n  title: \"Building UIs for microservices\"\n  raw_title: \"Building uls for microservices - Ethan Garofolo - wroc_love.rb 2019\"\n  speakers:\n    - Ethan Garofolo\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"ArTS_AJ-smQ\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"janko-marohni-wrocloverb-2019\"\n  title: \"Handling File Uploads For A Modern Developer\"\n  raw_title: \"Handling file uploads for modern developer -  Janko Marohnic  - wroc_love.rb 2019\"\n  speakers:\n    - Janko Marohnić\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"fP2JGjTZU2s\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"martin-gamsjaeger-wrocloverb-2019\"\n  title: \"Development with Axioms\"\n  raw_title: \"Development with axioms - Martin Gamsjaeger - wroc_love.rb 2019\"\n  speakers:\n    - Martin Gamsjaeger\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"qTVeWbg2tKk\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"markus-schirp-wrocloverb-2019\"\n  title: \"Mutant on Steroids\"\n  raw_title: \"Mutant on steroids - Markus Schirp - wroc_love.rb 2019\"\n  speakers:\n    - Markus Schirp\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"j1Ze3pKNJ4A\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"norbert-wojtowicz-wrocloverb-2019\"\n  title: \"Spice up your life with EQL\"\n  raw_title: \"Spice up your life with eql - Norbert Wojtowicz - wroc_love.rb 2019\"\n  speakers:\n    - Norbert Wojtowicz\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"UvJEBMOtayk\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"dimitry-salahutdinov-wrocloverb-2019\"\n  title: \"Optimistic UI and Live Uupdates with Logux & Ruby\"\n  raw_title: \"Optimistic ul - Dimitry Salahutdinov - wroc_love.rb 2019\"\n  speakers:\n    - Dimitry Salahutdinov\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"KVcZAfjWtYk\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"victor-shepelev-wrocloverb-2019\"\n  title: \"Towards the Post Framework Future\"\n  raw_title: \"Towards the post framework future - Victor Shepelev - wroc_love.rb 2019\"\n  speakers:\n    - Victor Shepelev\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"5UiBQtfRDUI\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"micha-matyas-wrocloverb-2019\"\n  title: \"Orchestrating Video Transcoding in Ruby\"\n  raw_title: \"Orchestrating video transcoding in ruby - Michal Matyas - wroc_love.rb 2019\"\n  speakers:\n    - Michał Matyas\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"CXhd-We0Nhw\"\n  language: \"English\"\n  description: \"\"\n  slides_url: \"https://slides.com/sandwich/transcoding-videos-in-ruby-a-story\"\n\n- id: \"chris-seaton-wrocloverb-2019\"\n  title: \"The TruffleRuby Compilation Pipeline\"\n  raw_title: \"The truffleruby compilation pipeline - Chris Seaton - wroc_love.rb 2019\"\n  speakers:\n    - Chris Seaton\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"bf5pQVgux3c\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"anton-davydov-wrocloverb-2019\"\n  title: \"Events Events Events\"\n  raw_title: \"Events events events - Anton Davydov - wroc_love.rb 2019\"\n  speakers:\n    - Anton Davydov\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"VnCPxjRpv3o\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"dvid-halsz-wrocloverb-2019\"\n  title: \"How to Hijack\"\n  raw_title: \"How to hijack - David Halasz - wroc_love.rb 2019\"\n  speakers:\n    - Dávid Halász\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"YhNhVBUcPkI\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"andrzej-krzywda-wrocloverb-2019\"\n  title: \"Business Logic in Ruby\"\n  raw_title: \"Business logic in Ruby - Andrzej Krzywda - wroc_love.rb 2019\"\n  speakers:\n    - Andrzej Krzywda\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-22\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"bwUueshN6Rw\"\n  language: \"English\"\n  description: \"\"\n\n- id: \"lighting-talks-day-2-wroclove-rb-2019\"\n  title: \"Lighting Talks (Day 2)\"\n  raw_title: \"Lighting talks 1 - wroc_love.rb 2019\"\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-23\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"cPuhRsV6Pw4\"\n  language: \"English\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: wroc_love Spam\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pawel-pokrywka-lighting-talk-wroclove-rb-2019\"\n      video_id: \"pawel-pokrywka-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Paweł Pokrywka\n\n    - title: \"Lightning Talk: The only easy thing\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"maciek-rzasa-lighting-talk-wroclove-rb-2019\"\n      video_id: \"maciek-rzasa-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Maciek Rząsa\n\n    - title: \"Lightning Talk: Predicting Performance Changes of Distributed Applications\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"wojtek-rzasa-lighting-talk-wroclove-rb-2019\"\n      video_id: \"wojtek-rzasa-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Wojtek Rząsa\n\n    - title: \"Lightning Talk: Farewell To SciRuby\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"victor-shepelev-lighting-talk-wroclove-rb-2019\"\n      video_id: \"victor-shepelev-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Victor Shepelev\n\n    - title: \"Lightning Talk: Outdated Browser Detection with Browserslist\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"dmitry-salahutdinov-lighting-talk-wroclove-rb-2019\"\n      video_id: \"dmitry-salahutdinov-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Dmitry Salahutdinov\n      slides_url: \"https://speakerdeck.com/dsalahutdinov/outdated-browser-detection-with-browserslist\"\n\n    - title: \"Lightning Talk: Sonic Pi\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"nicolas-dermine-lighting-talk-wroclove-rb-2019\"\n      video_id: \"nicolas-dermine-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Nicolas Dermine\n\n- id: \"lighting-talks-day-3-wroclove-rb-2019\"\n  title: \"Lighting Talks (Day 3)\"\n  raw_title: \"Lighting talks 2 - wroc_love.rb 2019\"\n  event_name: \"wroclove.rb 2019\"\n  date: \"2019-03-23\"\n  published_at: \"2019-05-09\"\n  video_provider: \"youtube\"\n  video_id: \"9q9eLQ2nSwA\"\n  language: \"English\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Scratching The Surface of Hunky Dory Elixir Features\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"adam-hodowany-lighting-talk-wroclove-rb-2019\"\n      video_id: \"adam-hodowany-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Hodowany\n\n    - title: \"Lightning Talk: What and Why\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tomas-dundacek-lighting-talk-wroclove-rb-2019\"\n      video_id: \"tomas-dundacek-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomáš Dundáček\n\n    - title: \"Lightning Talk: Ruby & Elixir - Friend or Foe\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"adam-skoluda-lighting-talk-wroclove-rb-2019\"\n      video_id: \"adam-skoluda-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Skołuda\n\n    - title: \"Lightning Talk: People Hate Him, Why Ruby is not dead?, Thank you, Please Help, How (not) to meet new people on DRUGCamp\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"adam-piotrowski-lighting-talk-wroclove-rb-2019\"\n      video_id: \"adam-piotrowski-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Adam Piotrowski\n\n    - title: \"Lightning Talk: More Sonic Pi\"\n      date: \"2019-03-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"nicolas-dermine-lighting-talk-wroclove-rb-2019-lightning-talk-more-sonic-pi\"\n      video_id: \"nicolas-dermine-lighting-talk-wroclove-rb-2019\"\n      video_provider: \"parent\"\n      speakers:\n        - Nicolas Dermine\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2022/event.yml",
    "content": "---\nid: \"PLoGBNJiQoqRDWafhnWni-CwHkPJJuc0e5\"\ntitle: \"wroclove.rb 2022\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: \"\"\nstart_date: \"2022-09-16\"\nend_date: \"2022-09-18\"\npublished_at: \"2022-09-23\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2022\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://2022.wrocloverb.com\"\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2022/venue.yml",
    "content": "# https://2022.wrocloverb.com\n---\nname: \"University of Wrocław\"\n\ndescription: |-\n  Institute of Computer Science\n\naddress:\n  street: \"1 plac Uniwersytecki\"\n  city: \"Wrocław\"\n  region: \"Województwo dolnośląskie\"\n  postal_code: \"50-137\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"plac Uniwersytecki 1, 50-137 Wrocław, Poland\"\n\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n\nmaps:\n  google: \"https://maps.google.com/?q=University+of+Wrocław,+Institute+of+Computer+Science,51.1140053,17.034463\"\n  apple: \"https://maps.apple.com/?q=University+of+Wrocław,+Institute+of+Computer+Science&ll=51.1140053,17.034463\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=51.1140053&mlon=17.034463\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2022/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"nick-sutterer-wrocloverb-2022\"\n  title: \"10 Things You Never Wanted To Know About Reform 3\"\n  raw_title: \"Nick Sutterer - 10 Things You Never Wanted To Know About Reform 3 - wroc_love.rb 2022\"\n  speakers:\n    - Nick Sutterer\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"vNAUZ0rUcow\"\n  description: \"\"\n\n- id: \"yaroslav-shmarov-wrocloverb-2022\"\n  title: \"18 Months of Using Hotwire and ViewComponent in Production\"\n  raw_title: \"Yaroslav Shmarov - 18 months of using hotwire and viewcomponent in production - wroc_love.rb 2022\"\n  speakers:\n    - Yaroslav Shmarov\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"9-btmed9CMw\"\n  description: \"\"\n\n- id: \"adrian-marin-wrocloverb-2022\"\n  title: \"How to Package a Rails Engine Generation to Automation\"\n  raw_title: \"Adrian Marin - How To Package A Rails Engine Generation To Automation - wroc_love.rb 2022\"\n  speakers:\n    - Adrian Marin\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"ywOUPHhGzEo\"\n  description: \"\"\n\n- id: \"andrzej-krzywda-wrocloverb-2022\"\n  title: \"Typical DDDomains in Rails Apps\"\n  raw_title: \"Andrzej Krzywda - Typical DDDomains In Rails Apps - wroc_love.rb 2022\"\n  speakers:\n    - Andrzej Krzywda\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"Le0UCTVu89Y\"\n  description: \"\"\n\n- id: \"mariusz-gil-wrocloverb-2022\"\n  title: \"The good, the bad and the Remote Collaborative Domain Modeling with EventStorming\"\n  raw_title: \"Mariusz Gil - The good, the bad and the remote   collaborative domain modeling with EventStorming\"\n  speakers:\n    - Mariusz Gil\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"X1ZYkeDdh9s\"\n  description: \"\"\n\n- id: \"pawe-dbrowski-wrocloverb-2022\"\n  title: \"Under The Hood And On The Surface of Sidekiq\"\n  raw_title: \"Paweł Dąbrowski - Under The Hood And On The Surface Of Sidekiq - wroc_love.rb 2022\"\n  speakers:\n    - Paweł Dąbrowski\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"AJTzYK8yoL8\"\n  description: \"\"\n\n- id: \"micha-zajczkowski-de-mezer-wrocloverb-2022\"\n  title: \"How to Ensure Systems Do What We Want and Take Care of Themselves\"\n  raw_title: \"Michał Zajączkowski de Mezer - How To Ensure Systems Do What We Want And Take Care Of Themselves\"\n  speakers:\n    - Michał Zajączkowski de Mezer\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"HPSCeYaGAtw\"\n  description: \"\"\n\n- id: \"karol-szuster-wrocloverb-2022\"\n  title: \"Nightmare Neighbours Caveats of Rails Based Mutlitenancy\"\n  raw_title: \"Karol Szuster - Nightmare neighbours caveats of Rails based mutlitenancy - wroc_love.rb 2022\"\n  speakers:\n    - Karol Szuster\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"JFaBknFWIKo\"\n  description: \"\"\n\n- id: \"sergy-sergyenko-wrocloverb-2022\"\n  title: \"Data Management with Ruby\"\n  raw_title: \"Sergey Sergyenko - Data Management With Ruby - wroc_love.rb 2022\"\n  speakers:\n    - Sergy Sergyenko\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"yHj6va0HdIY\"\n  description: \"\"\n\n- id: \"anita-jaszewska-wrocloverb-2022\"\n  title: \"Dealing With A Project's Complexity In A Changing Environment\"\n  raw_title: \"Anita Jaszewska - Dealing With A Project's Complexity In A Changing Environment - wroc_love.rb 2022\"\n  speakers:\n    - Anita Jaszewska\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"e7QU81XXSB4\"\n  description: \"\"\n\n- id: \"rafa-rothenberger-wrocloverb-2022\"\n  title: \"Devise Pitfalls and Way to Tighten Security\"\n  raw_title: \"Rafał Rothenberger - Devise pitfalls and way to tighten security - wroc_love.rb 2022\"\n  speakers:\n    - Rafał Rothenberger\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"ISPYQvnLW9c\"\n  description: \"\"\n\n- id: \"chris-hasinski-wrocloverb-2022\"\n  title: \"Ever Shorter Feedback Loop\"\n  raw_title: \"Krzysztof Hasiński - Ever shorter feedback loop - wroc_love.rb 2022\"\n  speakers:\n    - Chris Hasinski\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"xTBBrPUJjGk\"\n  description: \"\"\n\n- id: \"norbert-wjtowicz-wrocloverb-2022\"\n  title: \"Grokking FP For The Practicing Rubyist\"\n  raw_title: \"Norbert Wójtowicz - Grokking FP For The Practicing Rubyist - wroc_love.rb 2022\"\n  speakers:\n    - Norbert Wójtowicz\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"BPLr8wkGEQs\"\n  description: \"\"\n\n- id: \"pawe-strzakowski-wrocloverb-2022\"\n  title: \"Introduction To Event Sourcing How To Use It With Ruby\"\n  raw_title: \"Paweł Strzałkowski - Introduction To Event Sourcing How To Use It With Ruby - wroc_love.rb 2022\"\n  speakers:\n    - Paweł Strzałkowski\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-16\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"o_PuVhFH6U0\"\n  description: \"\"\n\n- id: \"lighting-talks-day-2-wroclove-rb-2022\"\n  title: \"Lighting Talks (Day 2)\"\n  raw_title: \"Lighting talks 1 - wroc_love.rb 2022\"\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-17\"\n  published_at: \"2022-09-23\"\n  video_provider: \"youtube\"\n  video_id: \"ILssKgZiBNY\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Alina Leskova\"\n      date: \"2019-03-17\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"alina-leskova-lighting-talk-wroclove-rb-2022\"\n      video_id: \"alina-leskova-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Alina Leskova\n\n    - title: \"Lightning Talk: Nobert Wójtowicz\"\n      date: \"2019-03-17\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"nobert-wojtowicz-lighting-talk-wroclove-rb-2022\"\n      video_id: \"nobert-wojtowicz-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Nobert Wójtowicz\n\n    - title: \"Lightning Talk: Andrew\"\n      date: \"2019-03-17\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"andrew-lighting-talk-wroclove-rb-2022\"\n      video_id: \"andrew-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrew # TODO: missing last name\n\n    - title: \"Lightning Talk: Andrzej Krzywda\"\n      date: \"2019-03-17\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"andrzej-krzywda-lighting-talk-wroclove-rb-2022\"\n      video_id: \"andrzej-krzywda-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrzej Krzywda\n\n    - title: \"Lightning Talk: Jan Dudulski\"\n      date: \"2019-03-17\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"jan-dudulski-lighting-talk-wroclove-rb-2022\"\n      video_id: \"jan-dudulski-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Jan Dudulski\n\n    - title: \"Lightning Talk: Yaroslav Shmarov\"\n      date: \"2019-03-17\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"yaroslav-shmarov-lighting-talk-wroclove-rb-2022\"\n      video_id: \"yaroslav-shmarov-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Yaroslav Shmarov\n\n- id: \"lighting-talks-day-3-wroclove-rb-2022\"\n  title: \"Lighting Talks (Day 3)\"\n  raw_title: \"Lighting talks 2 - wroc_love.rb 2022\"\n  event_name: \"wroclove.rb 2022\"\n  date: \"2019-03-18\"\n  published_at: \"2022-09-23\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"tzZbovhCOBs\"\n  talks:\n    - title: \"Lightning Talk: Patryk Ptasiński\"\n      date: \"2019-03-18\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"patryk-ptasinski-lighting-talk-wroclove-rb-2022\"\n      video_id: \"patryk-ptasinski-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Patryk Ptasiński\n\n    - title: \"Lightning Talk: Tomek Skuta\"\n      date: \"2019-03-18\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tomek-skuta-lighting-talk-wroclove-rb-2022\"\n      video_id: \"tomek-skuta-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Tomek Skuta\n\n    - title: \"Lightning Talk: Tobiasz Waszak\"\n      date: \"2019-03-18\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"tobiasz-waszak-lighting-talk-wroclove-rb-2022\"\n      video_id: \"tobiasz-waszak-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Tobiasz Waszak\n\n    - title: \"Lightning Talk: Password\"\n      date: \"2019-03-18\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"password-talk-lighting-talk-wroclove-rb-2022\"\n      video_id: \"password-talk-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing speaker name\n\n    - title: \"Lightning Talk: Zimbabwe\"\n      date: \"2019-03-18\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"zimbabwe-talk-lighting-talk-wroclove-rb-2022\"\n      video_id: \"zimbabwe-talk-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - TODO # TODO: missing speaker name\n\n    - title: \"Lightning Talk: Kuba Kuzma\"\n      date: \"2019-03-18\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"kuba-kuzma-lighting-talk-wroclove-rb-2022\"\n      video_id: \"kuba-kuzma-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Kuba Kuzma\n\n    - title: \"Lightning Talk: Vladislav Frolov\"\n      date: \"2019-03-18\"\n      published_at: \"2022-09-23\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"vladislav-frolov-lighting-talk-wroclove-rb-2022\"\n      video_id: \"vladislav-frolov-lighting-talk-wroclove-rb-2022\"\n      video_provider: \"parent\"\n      speakers:\n        - Vladislav Frolov\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2023/event.yml",
    "content": "---\nid: \"PLoGBNJiQoqRDwTvPjY1F_7ccYO7O26RJ9\"\ntitle: \"wroclove.rb 2023\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: \"\"\nstart_date: \"2023-09-15\"\nend_date: \"2023-09-17\"\npublished_at: \"2023-09-19\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2023\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\nwebsite: \"https://2023.wrocloverb.com\"\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2023/venue.yml",
    "content": "# https://2023.wrocloverb.com\n---\nname: \"University of Wrocław\"\n\ndescription: |-\n  Institute of Computer Science\n\naddress:\n  street: \"1 plac Uniwersytecki\"\n  city: \"Wrocław\"\n  region: \"Województwo dolnośląskie\"\n  postal_code: \"50-137\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"plac Uniwersytecki 1, 50-137 Wrocław, Poland\"\n\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n\nmaps:\n  google: \"https://maps.google.com/?q=University+of+Wrocław,+Institute+of+Computer+Science,51.1140053,17.034463\"\n  apple: \"https://maps.apple.com/?q=University+of+Wrocław,+Institute+of+Computer+Science&ll=51.1140053,17.034463\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=51.1140053&mlon=17.034463\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2023/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"amelia-walter-dzikowska-wrocloverb-2023\"\n  title: \"International cooperation in IT teams\"\n  raw_title: \"Amelia Walter-Dzikowska - International cooperation in IT teams - wroc_love.rb 2023\"\n  speakers:\n    - Amelia Walter-Dzikowska\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"VMY_mSaB3Jc\"\n  description: |-\n    International cooperation in IT teams. Is our office a global village?\n\n- id: \"agnieszka-maaszkiewicz-wrocloverb-2023\"\n  title: \"Ruby Rendezvous: Method Call, Proc, and Beyond\"\n  raw_title: \"Agnieszka Małaszkiewicz - Ruby Rendezvous: Method Call, Proc, and Beyond - wroc_love.rb 2023\"\n  speakers:\n    - Agnieszka Małaszkiewicz\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"BtiUh6ItPUY\"\n  description: \"\"\n\n- id: \"nathan-ladd-wrocloverb-2023\"\n  title: \"An Introduction to Test Bench\"\n  raw_title: \"Nathan Ladd - An Introduction to Test Bench - wroc_love.rb 2023\"\n  speakers:\n    - Nathan Ladd\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"u1mf4LorGl0\"\n  description: \"\"\n\n- id: \"cristian-planas-wrocloverb-2023\"\n  title: \"A Rails Performance Guidebook: from 0 to 1B requests/day\"\n  raw_title: \"Cristian Planas - A Rails performance guidebook: from 0 to 1B requests/day - wroc_love.rb 2023\"\n  speakers:\n    - Cristian Planas\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"pJFqmYw4kNY\"\n  description: \"\"\n\n- id: \"scott-bellware-wrocloverb-2023\"\n  title: \"Panel: Event-driven Rails\"\n  raw_title: \"Panel: Event-driven Rails - wroc_love.rb 2023\"\n  speakers:\n    - Scott Bellware\n    - Nathan Ladd\n    - Andrzej Krzywda\n    - Paweł Pacana\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"rlSmYk_BSOI\"\n  description: \"\"\n\n- id: \"miron-marczuk-wrocloverb-2023\"\n  title: \"Multi-region Data Governance in Rails Application\"\n  raw_title: \"Miron Marczuk - Multi-region data governance in Rails application - wroc_love.rb 2023\"\n  speakers:\n    - Miron Marczuk\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"etmsQ-Txjx4\"\n  description: \"\"\n\n- id: \"jakub-rodzik-wrocloverb-2023\"\n  title: \"Testing Randomness\"\n  raw_title: \"Jakub Rodzik - Testing Randomness - wroc_love.rb 2023\"\n  speakers:\n    - Jakub Rodzik\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"ilzWIrCBqN4\"\n  description: \"\"\n\n- id: \"scott-bellware-wrocloverb-2023-doctrine-of-useful-objects-sep\"\n  title: \"Doctrine of Useful Objects: Separate Fact from Fiction in OOD\"\n  raw_title: \"Scott Bellware - Doctrine of Useful Objects: Separate Fact from Fiction in OOD - wroc_love.rb 2023\"\n  speakers:\n    - Scott Bellware\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"pKiq52FywjI\"\n  description: |-\n    Doctrine of Useful Objects: Separate Fact from Fiction in Object-Oriented Development\n\n- id: \"ayush-newatia-wrocloverb-2023\"\n  title: \"Native Apps are Dead, Long Live Native Apps\"\n  raw_title: \"Ayush Newatia - Native apps are dead, long live native apps - wroc_love.rb 2023\"\n  speakers:\n    - Ayush Newatia\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"fJNB9GSDu7Y\"\n  description: |-\n    Native apps are dead, long live native apps: Using Turbo Native to make hybrid apps that don’t suck\n\n- id: \"chris-hasiski-wrocloverb-2023\"\n  title: \"Fantastic Databases and Where to Find Them\"\n  raw_title: \"Chris Hasiński - Fantastic Databases and Where to Find Them - wroc_love.rb 2023\"\n  speakers:\n    - Chris Hasiński\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"XJ7qKPia9Wc\"\n  description: \"\"\n\n- id: \"rafa-cymerys-wrocloverb-2023\"\n  title: \"From Open Source to IPO\"\n  raw_title: \"Rafał Cymerys - From open source to IPO - wroc_love.rb 2023\"\n  speakers:\n    - Rafał Cymerys\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"fFY5flhVlow\"\n  description: |-\n    From open source to IPO - lessons learned from building a scalable open source framework on top of Rails\n\n- id: \"tomasz-donarski-wrocloverb-2023\"\n  title: \"Reforging (or rather rebrewing) the Support for Open-Source\"\n  raw_title: \"Tomasz Donarski - Reforging (or rather rebrewing) the support for open-source - wroc_love.rb 2023\"\n  speakers:\n    - Tomasz Donarski\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"S1TM28Amy6o\"\n  description: \"\"\n\n- id: \"ukasz-reszke-wrocloverb-2023\"\n  title: \"Working with RailsEventStore in Cashflow Management System\"\n  raw_title: \"Łukasz Reszke - Working with RailsEventStore in Cashflow Management System - wroc_love.rb 2023\"\n  speakers:\n    - Łukasz Reszke\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-15\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"c0T9137Cb-8\"\n  description: \"\"\n\n- id: \"lightning-talks-day-2-wroclove-rb-2023\"\n  title: \"Lightning Talks (Day 2)\"\n  raw_title: \"Lightning talks 1 - wroc_love.rb 2023\"\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-16\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"rT0ermnwUpY\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Paweł Strzałkowski\"\n      date: \"2023-09-16\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pawel-strzalkowski-lighting-talk-wroclove-rb-2023\"\n      video_id: \"pawel-strzalkowski-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Paweł Strzałkowski\n\n    - title: \"Lightning Talk: Andrei Kaleshka\"\n      date: \"2023-09-16\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"andrei-kaleshka-lighting-talk-wroclove-rb-2023\"\n      video_id: \"andrei-kaleshka-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrei Kaleshka\n\n    - title: \"Lightning Talk: Michał Krzyżanowski\"\n      date: \"2023-09-16\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-krzyzanowski-lighting-talk-wroclove-rb-2023\"\n      video_id: \"michal-krzyzanowski-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Krzyżanowski\n\n    - title: \"Lightning Talk: Andrzej Krzywda\"\n      date: \"2023-09-16\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"andrzej-krzywda-lighting-talk-wroclove-rb-2023\"\n      video_id: \"andrzej-krzywda-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Andrzej Krzywda\n\n    - title: \"Lightning Talk: Alexander Jahraus\"\n      date: \"2023-09-16\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"alexander-jahraus-lighting-talk-wroclove-rb-2023\"\n      video_id: \"alexander-jahraus-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Alexander Jahraus\n\n    - title: \"Lightning Talk: Michał Matyas\"\n      date: \"2023-09-16\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-matyas-lighting-talk-wroclove-rb-2023\"\n      video_id: \"michal-matyas-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Matyas\n\n    - title: \"Lightning Talk: Seb Wilgosz\"\n      date: \"2023-09-16\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"seb-wilgosz-lighting-talk-wroclove-rb-2023\"\n      video_id: \"seb-wilgosz-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Seb Wilgosz\n\n    - title: \"Lightning Talk: Paweł Świątkowski\"\n      date: \"2023-09-16\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pawel-swiatkowski-lighting-talk-wroclove-rb-2023\"\n      video_id: \"pawel-swiatkowski-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Paweł Świątkowski\n\n- id: \"lightning-talks-day-3-wroclove-rb-2023\"\n  title: \"Lightning Talks (Day 3)\"\n  raw_title: \"Lightning talks 2 - wroc_love.rb 2023\"\n  event_name: \"wroclove.rb 2023\"\n  date: \"2023-09-17\"\n  published_at: \"2023-09-19\"\n  video_provider: \"youtube\"\n  video_id: \"k_Ln9Bj0_ns\"\n  description: \"\"\n  talks:\n    - title: \"Lightning Talk: Łukasz Reszke\"\n      date: \"2023-09-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"lukasz-reszke-lighting-talk-wroclove-rb-2023\"\n      video_id: \"lukasz-reszke-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Łukasz Reszke\n\n    - title: \"Lightning Talk: Pitor Wasiak\"\n      date: \"2023-09-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"pitor-wasiak-lighting-talk-wroclove-rb-2023\"\n      video_id: \"pitor-wasiak-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Pitor Wasiak\n\n    - title: \"Lightning Talk: Ayush Newatia\"\n      date: \"2023-09-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"ayush-newatia-lighting-talk-wroclove-rb-2023\"\n      video_id: \"ayush-newatia-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Ayush Newatia\n\n    - title: \"Lightning Talk: Michał Matyas\"\n      date: \"2023-09-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"michal-matyas-lighting-talk-wroclove-rb-2023-lightning-talk-micha-matyas\"\n      video_id: \"michal-matyas-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Michał Matyas\n\n    - title: \"Lightning Talk: Alexander Jahraus\"\n      date: \"2023-09-17\"\n      start_cue: \"TODO\"\n      end_cue: \"TODO\"\n      id: \"alexander-jahraus-lighting-talk-wroclove-rb-2023-lightning-talk-alexander-jahra\"\n      video_id: \"alexander-jahraus-lighting-talk-wroclove-rb-2023\"\n      video_provider: \"parent\"\n      speakers:\n        - Alexander Jahraus\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2024/cfp.yml",
    "content": "---\n- link: \"https://forms.gle/bgTVhWZzjRV74F1x7\"\n  open_date: \"2023-12-11\"\n  close_date: \"2024-01-31\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2024/event.yml",
    "content": "---\nid: \"PLoGBNJiQoqRBCvceSUkayHJKvMAbbZq39\"\ntitle: \"wroclove.rb 2024\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: \"\"\npublished_at: \"2024-04-15\"\nstart_date: \"2024-04-12\"\nend_date: \"2024-04-14\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2024\nbanner_background: \"#fff\"\nfeatured_background: \"#fff\"\nfeatured_color: \"black\"\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2024/venue.yml",
    "content": "# https://2024.wrocloverb.com\n---\nname: \"University of Wrocław\"\n\ndescription: |-\n  Institute of Computer Science\n\naddress:\n  street: \"1 plac Uniwersytecki\"\n  city: \"Wrocław\"\n  region: \"Województwo dolnośląskie\"\n  postal_code: \"50-137\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"plac Uniwersytecki 1, 50-137 Wrocław, Poland\"\n\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n\nmaps:\n  google: \"https://maps.google.com/?q=University+of+Wrocław,+Institute+of+Computer+Science,51.1140053,17.034463\"\n  apple: \"https://maps.apple.com/?q=University+of+Wrocław,+Institute+of+Computer+Science&ll=51.1140053,17.034463\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=51.1140053&mlon=17.034463\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2024/videos.yml",
    "content": "---\n# TODO: talks running order\n# TODO: talk dates\n# TODO: conference website\n# TODO: schedule website\n\n- id: \"andrei-kaleshka-wrocloverb-2024\"\n  title: \"Prevent Account Sharing\"\n  raw_title: \"1. Andrei Kaleshka - Prevent account sharing - wroc_love.rb 2024\"\n  speakers:\n    - Andrei Kaleshka\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"54EfisI19Ho\"\n  description: \"\"\n\n- id: \"david-halasz-wrocloverb-2024\"\n  title: \"One machine please, make it Turing\"\n  raw_title: \"2. David Halasz - One machine please, make it Turing - wroc_love.rb 2024\"\n  speakers:\n    - David Halasz\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"eiuICTzH8Ck\"\n  description: \"\"\n\n- id: \"stephen-margheim-wrocloverb-2024\"\n  title: \"How (and why) to run SQLite in production\"\n  raw_title: \"3. Stephen Margheim - How (and why) to run SQLite in production - wroc_love.rb 2024\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  slides_url: \"https://speakerdeck.com/fractaledmind/wroclove-dot-rb-2024-how-and-why-to-run-sqlite-on-rails-in-production\"\n  video_provider: \"youtube\"\n  video_id: \"qwG5hjaZlN4\"\n  description: \"\"\n\n- id: \"caio-almeida-wrocloverb-2024\"\n  title: \"Optimizing performance in Rails apps with GraphQL layer\"\n  raw_title: \"4. Caio Almeida - Optimizing performance in Rails apps with GraphQL layer - wroc_love.rb 2024\"\n  speakers:\n    - Caio Almeida\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"j3J8UdnLkoQ\"\n  description: \"\"\n\n- id: \"maciej-rzsa-wrocloverb-2024\"\n  title: \"Debug Like a Scientist\"\n  raw_title: \"5. Maciej Rząsa - Debug like a scientist - wroc_love.rb 2024\"\n  speakers:\n    - Maciej Rząsa\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"iyuRIEJ4r_w\"\n  description: \"\"\n\n- id: \"panel-performance-problems-wroclove-rb-2024\"\n  title: \"Panel: Performance Problems in Rails Applications\"\n  raw_title: \"6. Panel Discusion - Performance problems in Rails applications - wroc_love.rb 2024\"\n  speakers:\n    - Stephen Margheim\n    - Caio Almeida\n    - Maciej Rząsa\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"-MMxVtDFAUM\"\n  description: \"\"\n\n- id: \"radoslav-stankov-wrocloverb-2024\"\n  title: \"Component Driven UI with ViewComponent\"\n  raw_title: \"7. Radoslav Stankov - Component Driven UI with ViewComponent - wroc_love.rb 2024\"\n  speakers:\n    - Radoslav Stankov\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"PLU0KH0FRNY\"\n  description: \"\"\n\n- id: \"bartosz-blimke-wrocloverb-2024\"\n  title: \"Webmock Unmocked\"\n  raw_title: \"8. Bartosz Blimke - Webmock unmocked - wroc_love.rb 2024\"\n  speakers:\n    - Bartosz Blimke\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"gANKD_okm_I\"\n  description: \"\"\n\n- id: \"alina-leskova-wrocloverb-2024\"\n  title: \"Lightning Talks Day 2\" # TODO: use cues\n  raw_title: \"9. Lightning Talks - wroc_love.rb 2024\"\n  speakers:\n    - Alina Leskova\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-13\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"AizKv4RRfOg\"\n  description: \"\"\n\n- id: \"andrei-bondarev-wrocloverb-2024\"\n  title: \"Building LLM powered applications in Ruby\"\n  raw_title: \"10. Andrei Bondarev - Building LLM powered applications in Ruby - wroc_love.rb 2024\"\n  speakers:\n    - Andrei Bondarev\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  slides_url: \"https://speakerdeck.com/andreibondarev/wroclove-dot-rb-2024-building-llm-powered-applications-in-ruby\"\n  video_provider: \"youtube\"\n  video_id: \"D6gWrPa803s\"\n  description: \"\"\n\n- id: \"pawe-pokrywka-wrocloverb-2024\"\n  title: \"How I brought LCP down to under 350 ms for Google-referred users\"\n  raw_title: \"11. Paweł Pokrywka - How I brought LCP down to under 350 ms - wroc_love.rb 2024\"\n  speakers:\n    - Paweł Pokrywka\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"RaJEXf3fBlA\"\n  description: \"\"\n\n- id: \"ivan-nemytchenko-wrocloverb-2024\"\n  title: \"The Curse of Service Object\"\n  raw_title: \"12. Ivan Nemytchenko - The Curse of Service Object - wroc_love.rb 2024\"\n  speakers:\n    - Ivan Nemytchenko\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"eOosB7Z1Q5U\"\n  description: \"\"\n\n- id: \"erwin-kroon-wrocloverb-2024\"\n  title: \"Introducing Sorbet Into Your Ruby Codebase\"\n  raw_title: \"13. Erwin Kroon - Introducing Sorbet into your Ruby codebase - wroc_love.rb 2024\"\n  speakers:\n    - Erwin Kroon\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"JTdj9_ojJek\"\n  description: \"\"\n\n- id: \"sebastian-wilgosz-wrocloverb-2024\"\n  title: \"Extracting Logic From Templates With Hanami Views\"\n  raw_title: \"14. Sebastian Wilgosz - Extracting logic from templates with Hanami Views - wroc_love.rb 2024\"\n  speakers:\n    - Sebastian Wilgosz\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-12\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"IqTfaIenWKg\"\n  description: \"\"\n\n- id: \"michael-prilop-wrocloverb-2024\"\n  title: \"Lightning Talks Day 3\" # TODO: use cues\n  raw_title: \"15. Lightning Talks 2 - wroc_love.rb 2024\"\n  speakers:\n    - Michael Prilop\n  event_name: \"wroclove.rb 2024\"\n  date: \"2024-04-14\"\n  published_at: \"2024-05-15\"\n  video_provider: \"youtube\"\n  video_id: \"C632Wu92Agc\"\n  description: \"\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2025/cfp.yml",
    "content": "---\n- link: \"https://docs.google.com/forms/d/e/1FAIpQLSdg-w3hF3V-Q7hNwXKzqEUv_y92oQaYWu4FSziFRhwEyMo3Hw/viewform\"\n  open_date: \"2025-01-20\"\n  close_date: \"2025-02-13\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2025/event.yml",
    "content": "---\nid: \"PLoGBNJiQoqRAIFrYXoYQmmJNqoOevonaP\"\ntitle: \"wroclove.rb 2025\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: \"\"\npublished_at: \"2025-04-16\"\nstart_date: \"2025-04-11\"\nend_date: \"2025-04-13\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2025\nbanner_background: \"#FDF9F9\"\nfeatured_background: \"#fff\"\nfeatured_color: \"black\"\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Supporters\"\n      description: |-\n        Supporting the mission section with sponsors logos and links.\n      level: 1\n      sponsors:\n        - name: \"Arkency\"\n          badge: \"\"\n          website: \"https://arkency.com\"\n          slug: \"arkency\"\n          logo_url: \"https://wrocloverb.com/supporters/arkency.svg\"\n\n        - name: \"Railsware\"\n          badge: \"\"\n          website: \"https://railsware.com/\"\n          slug: \"railsware\"\n          logo_url: \"https://wrocloverb.com/supporters/railsware.svg\"\n\n        - name: \"2n\"\n          badge: \"\"\n          website: \"https://www.2n.pl\"\n          slug: \"2n\"\n          logo_url: \"https://wrocloverb.com/supporters/2n.svg\"\n\n    - name: \"Partners\"\n      description: \"\"\n      level: 2\n      sponsors:\n        - name: \"University of Wrocław\"\n          badge: \"\"\n          website: \"https://ii.uni.wroc.pl\"\n          slug: \"university-of-wroclaw\"\n          logo_url: \"https://wrocloverb.com/partners/uwr.svg\"\n\n        - name: \"CodersCrew\"\n          badge: \"\"\n          website: \"https://coderscrew.pl/\"\n          slug: \"coderscrew\"\n          logo_url: \"https://wrocloverb.com/partners/coderscrew.png\"\n\n        - name: \"Pragmatic Bookshelf\"\n          badge: \"\"\n          website: \"https://pragprog.com\"\n          slug: \"pragmatic-bookshelf\"\n          logo_url: \"https://wrocloverb.com/partners/pragmatic_bookshelf.png\"\n\n        - name: \"JustCrosspost\"\n          badge: \"\"\n          website: \"https://justcrosspost.app/\"\n          slug: \"justcrosspost\"\n          logo_url: \"https://wrocloverb.com/partners/justcrosspost.png\"\n\n        - name: \"Ruby Community Conference\"\n          badge: \"\"\n          website: \"https://rubycommunityconference.com\"\n          slug: \"ruby-community-conference\"\n          logo_url: \"https://wrocloverb.com/partners/rwcc.png\"\n\n        - name: \"Rails Changelog\"\n          badge: \"\"\n          website: \"https://www.railschangelog.com\"\n          slug: \"rails-changelog\"\n          logo_url: \"https://wrocloverb.com/partners/rails_changelog.png\"\n\n        - name: \"Baltic Ruby\"\n          badge: \"\"\n          website: \"https://balticruby.org/\"\n          slug: \"baltic-ruby\"\n          logo_url: \"https://wrocloverb.com/partners/baltic_ruby.svg\"\n\n        - name: \"EuRuKo 2025\"\n          badge: \"\"\n          website: \"https://2025.euruko.org/\"\n          slug: \"euruko-2025\"\n          logo_url: \"https://wrocloverb.com/partners/euruko.svg\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2025/venue.yml",
    "content": "# https://2025.wrocloverb.com/agenda/\n---\nname: \"University of Wrocław\"\n\ndescription: |-\n  Institute of Computer Science, University of Wrocław, Fryderyka Joliot-Curie 15.\n\naddress:\n  street: \"1 plac Uniwersytecki\"\n  city: \"Wrocław\"\n  region: \"Województwo dolnośląskie\"\n  postal_code: \"50-137\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"plac Uniwersytecki 1, 50-137 Wrocław, Poland\"\n\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n\nmaps:\n  google: \"https://maps.google.com/?q=University+of+Wrocław,+Institute+of+Computer+Science,51.1140053,17.034463\"\n  apple: \"https://maps.apple.com/?q=University+of+Wrocław,+Institute+of+Computer+Science&ll=51.1140053,17.034463\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=51.1140053&mlon=17.034463\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2025/videos.yml",
    "content": "---\n- id: \"joel-drapper-wrocloverb-2025\"\n  title: \"Ruby has literally always had types\"\n  raw_title: \"1. Joel Drapper - Ruby has literally always had types - wroc_love.rb 2025\"\n  speakers:\n    - Joel Drapper\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"UxWhjK3Zc9Y\"\n\n- id: \"chris-hasiski-wrocloverb-2025\"\n  title: \"Next Token!\"\n  raw_title: \"2. Chris Hasiński - Next Token! - wroc_love.rb 2025\"\n  speakers:\n    - Chris Hasiński\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-11\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"Zg1vEZdkG2I\"\n\n- id: \"john-gallagher-wrocloverb-2025\"\n  title: \"Fix Production Bugs 20x Faster\"\n  raw_title: \"3. John Gallagher - Fix Production Bugs 20x Faster - wroc_love.rb 2025\"\n  speakers:\n    - John Gallagher\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-12\"\n  description: |-\n    Fix Production Bugs 20x Faster - The Power of Structured Logging\n  video_provider: \"youtube\"\n  video_id: \"k8ruReWZP18\"\n\n- id: \"stephen-margheim-wrocloverb-2025\"\n  title: \"On the tasteful journey to Yippee\"\n  raw_title: \"4. Stephen Margheim - On the tasteful journey to Yippee - wroc_love.rb 2025\"\n  speakers:\n    - Stephen Margheim\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-12\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"VWDfeMHBaH0\"\n\n- id: \"yatish-mehta-wrocloverb-2025\"\n  title: \"No 'Pundit' Intended\"\n  raw_title: \"5. Yatish Mehta - No 'Pundit' Intended - wroc_love.rb 2025\"\n  speakers:\n    - Yatish Mehta\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-12\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"CIZ04tCkWps\"\n\n- id: \"szymon-fiedler-wrocloverb-2025\"\n  title: \"Rewrite with confidence\"\n  raw_title: \"6. Szymon Fiedler - Rewrite with confidence - wroc_love.rb 2025\"\n  speakers:\n    - Szymon Fiedler\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-12\"\n  description: |-\n    Rewrite with confidence: validating business rules through isolated testing\n  video_provider: \"youtube\"\n  video_id: \"OnoOHE6qFX4\"\n\n- id: \"mateusz-nowak-wrocloverb-2025\"\n  title: \"Might & Magic of Domain-Driven Design\"\n  raw_title: \"7. Mateusz Nowak - Might & Magic of Domain-Driven Design - wroc_love.rb 2025\"\n  speakers:\n    - Mateusz Nowak\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-12\"\n  description: |-\n    Might & Magic of Domain-Driven Design through the lens of Heroes III\n  video_provider: \"youtube\"\n  video_id: \"0KjmEK2TAxc\"\n\n- id: \"norbert-wjtowicz-wrocloverb-2025\"\n  title: \"Gregorian Calendar\"\n  raw_title: \"8. Norbert Wójtowicz - Gregorian Calendar - wroc_love.rb 2025\"\n  speakers:\n    - Norbert Wójtowicz\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-12\"\n  description: |-\n    Gregorian Calendar - lessons learned maintaining 3000-year old codebase\n  video_provider: \"youtube\"\n  video_id: \"YiLlnsq2fJ4\"\n\n- id: \"todo-wrocloverb-2025\"\n  title: \"Lightning Talks\"\n  raw_title: \"9. Lightning Talks - wroc_love.rb 2025\"\n  speakers:\n    - TODO\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-12\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"wVmaqF8jVfo\"\n\n- id: \"chikahiro-tokoro-wrocloverb-2025\"\n  title: \"Is the monolith a problem?\"\n  raw_title: \"10. Chikahiro Tokoro - Is the monolith a problem? - wroc_love.rb 2025\"\n  speakers:\n    - Chikahiro Tokoro\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"vzLjVvfBIwk\"\n  slides_url: \"https://speakerdeck.com/kibitan/is-the-monolith-a-problem\"\n\n- id: \"seth-horsley-wrocloverb-2025\"\n  title: \"Building Beautiful UIs with Ruby: A Rails-Native Approach\"\n  raw_title: \"11. Seth Horsley - Building Beautiful UIs with Ruby: A Rails-Native Approach - wroc_love.rb 2025\"\n  speakers:\n    - Seth Horsley\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"zqvt68YYPuo\"\n\n- id: \"wojtek-wrona-wrocloverb-2025\"\n  title: \"From PostgreSQL to SQLite in Rails\"\n  raw_title: \"12. Wojtek Wrona - From PostgreSQL to SQLite in Rails - wroc_love.rb 2025\"\n  speakers:\n    - Wojtek Wrona\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-13\"\n  description: |-\n    From PostgreSQL to SQLite in Rails: Our Migration Journey, Challenges, and Lasting Trade Offs\n  video_provider: \"youtube\"\n  video_id: \"6DS0WaosX10\"\n\n- id: \"adam-piotrowski-wrocloverb-2025\"\n  title: \"It is not so bad, after all\"\n  raw_title: \"13. Adam Piotrowski - It is not so bad, after all - wroc_love.rb 2025\"\n  speakers:\n    - Adam Piotrowski\n  event_name: \"wroc_love.rb 2025\"\n  published_at: \"2025-04-16\"\n  date: \"2025-04-13\"\n  description: \"\"\n  video_provider: \"youtube\"\n  video_id: \"lqsbZIZacLw\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2026/cfp.yml",
    "content": "---\n- name: \"Call for Proposals\"\n  link: \"https://www.papercall.io/wrocloverb2026\"\n  open_date: \"2025-10-13\"\n  close_date: \"2026-01-13\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2026/event.yml",
    "content": "---\nid: \"wroclove-rb-2026\"\ntitle: \"wroclove.rb 2026\"\nkind: \"conference\"\nlocation: \"Wrocław, Poland\"\ndescription: \"\"\npublished_at: \"\"\nstart_date: \"2026-04-17\"\nend_date: \"2026-04-19\"\nchannel_id: \"UC_tX5G6twhuwWZQptcc3DOA\"\nyear: 2026\ntickets_url: \"https://wrocloverb2026.konfeo.com/en/groups\"\nbanner_background: \"#FDF9F9\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#000000\"\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2026/schedule.yml",
    "content": "# docs/ADDING_SCHEDULES.md\n---\ndays:\n  - name: \"Day 1\"\n    date: \"2026-04-17\"\n    grid:\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - title: \"Registration\"\n            description: |-\n              Registration is open from 13:00 to 14:00 at the venue — Institute of Computer Science, University of Wrocław, Fryderyka Joliot-Curie 15.\n      - start_time: \"14:00\"\n        end_time: \"17:00\"\n        slots: 4\n      - start_time: \"17:00\"\n        end_time: \"18:00\"\n        slots: 1\n      - start_time: \"18:00\"\n        end_time: \"19:00\"\n        slots: 1\n      - start_time: \"20:00\"\n        end_time: \"21:00\"\n        slots: 1\n        items:\n          - Party\n  - name: \"Day 2\"\n    date: \"2026-04-18\"\n    grid:\n      - start_time: \"9:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - title: \"Registration\"\n            description: |-\n              Registration is open from 9:00 to 10:00 at the venue — Institute of Computer Science, University of Wrocław, Fryderyka Joliot-Curie 15.\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n      - start_time: \"11:00\"\n        end_time: \"12:00\"\n        slots: 1\n      - start_time: \"12:00\"\n        end_time: \"13:30\"\n        slots: 1\n      - start_time: \"13:00\"\n        end_time: \"15:00\"\n        slots: 1\n        items:\n          - title: \"Lunch break\"\n            description: |-\n              Let us all have a lunch break, grab something to eat around the venue, and get ready for the afternoon sessions.\n      - start_time: \"15:00\"\n        end_time: \"16:00\"\n        slots: 1\n      - start_time: \"16:00\"\n        end_time: \"17:00\"\n        slots: 1\n      - start_time: \"17:00\"\n        end_time: \"18:00\"\n        slots: 1\n      - start_time: \"18:00\"\n        end_time: \"19:00\"\n        slots: 1\n      - start_time: \"18:00\"\n        end_time: \"19:00\"\n        slots: 1\n        items:\n          - Party\n  - name: \"Day 3\"\n    date: \"2026-04-19\"\n    grid:\n      - start_time: \"09:00\"\n        end_time: \"10:00\"\n        slots: 1\n        items:\n          - title: \"Registration\"\n            description: |-\n              Registration is open from 9:00 to 10:00 at the venue — Institute of Computer Science, University of Wrocław, Fryderyka Joliot-Curie 15.\n      - start_time: \"10:00\"\n        end_time: \"11:00\"\n        slots: 1\n      - start_time: \"11:00\"\n        end_time: \"12:00\"\n        slots: 1\n      - start_time: \"12:00\"\n        end_time: \"13:00\"\n        slots: 1\n      - start_time: \"13:00\"\n        end_time: \"14:00\"\n        slots: 1\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2026/sponsors.yml",
    "content": "# docs/ADDING_SPONSORS.md\n---\n- tiers:\n    - name: \"Supporters\"\n      level: 1\n      sponsors:\n        - name: \"arkency\"\n          website: \"https://arkency.com\"\n          slug: \"arkency\"\n          logo_url: \"https://wrocloverb.com/supporters/arkency.svg\"\n        - name: \"2N\"\n          website: \"https://2n.pl\"\n          slug: \"2n\"\n          logo_url: \"https://wrocloverb.com/supporters/2n.svg\"\n        - name: \"railsware\"\n          website: \"https://railsware.com\"\n          slug: \"railsware\"\n          logo_url: \"https://wrocloverb.com/supporters/railsware.svg\"\n        - name: \"typesense\"\n          website: \"https://typesense.org\"\n          slug: \"typesense\"\n          logo_url: \"https://wrocloverb.com/supporters/typesense.svg\"\n        - name: \"infakt\"\n          website: \"https://infakt.pl\"\n          slug: \"infakt\"\n          logo_url: \"https://wrocloverb.com/supporters/infakt.svg\"\n        - name: \"Momentum\"\n          website: \"https://themomentum.ai\"\n          slug: \"momentum\"\n          logo_url: \"https://wrocloverb.com/supporters/momentum.svg\"\n        - name: \"EverAI\"\n          website: \"https://www.everai.ai/\"\n          slug: \"everai\"\n          logo_url: \"https://wrocloverb.com/supporters/ever_ai.svg\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2026/venue.yml",
    "content": "# https://www.papercall.io/wrocloverb2026\n---\nname: \"University of Wrocław\"\n\ndescription: |-\n  Institute of Computer Science\n\naddress:\n  street: \"1 plac Uniwersytecki\"\n  city: \"Wrocław\"\n  region: \"Województwo dolnośląskie\"\n  postal_code: \"50-137\"\n  country: \"Poland\"\n  country_code: \"PL\"\n  display: \"plac Uniwersytecki 1, 50-137 Wrocław, Poland\"\n\ncoordinates:\n  latitude: 51.1140053\n  longitude: 17.034463\n\nmaps:\n  google: \"https://maps.google.com/?q=University+of+Wrocław,+Institute+of+Computer+Science,51.1140053,17.034463\"\n  apple: \"https://maps.apple.com/?q=University+of+Wrocław,+Institute+of+Computer+Science&ll=51.1140053,17.034463\"\n  openstreetmap: \"https://www.openstreetmap.org/?mlat=51.1140053&mlon=17.034463\"\n"
  },
  {
    "path": "data/wroclove-rb/wroclove-rb-2026/videos.yml",
    "content": "---\n- id: \"markus-schirp-workshop-wroclove-rb-2026\"\n  title: \"Setup and operation of mutation testing in agentic world\"\n  description: |-\n    AI writes your code. AI writes your tests. But who tests the tests? How do you know your tests actually test something? Markus is the creator of Mutant — a mutation testing tool for Ruby. In this workshop, he will guide you through setting up mutation testing and using it to truly verify your Ruby code.\n  kind: \"workshop\"\n  language: \"en\"\n  date: \"2026-04-17\"\n  speakers:\n    - Markus Schirp\n  video_provider: \"scheduled\"\n  video_id: \"markus-schirp-workshop-wroclove-rb-2026\"\n\n- id: \"greg-molnar-wrocloverb-2026\"\n  title: \"Securing Rails applications\"\n  raw_title: \"Securing Rails applications - Greg Molnar - wroc_love.rb 2026\"\n  kind: \"workshop\"\n  speakers:\n    - Greg Molnar\n  event_name: \"wroclove.rb 2026\"\n  published_at: \"TODO\"\n  date: \"2026-04-17\"\n  description: |-\n    Eager to elevate your security skills? This workshop is designed specifically for developers who aim to build robust, secure Rails applications! Greg, OSCP Certified Penetration Tester and a Ruby Developer since 2010, will bring his deep expertise to help you understand and apply best practices to secure your Rails applications.\n  video_id: \"greg-molnar-wrocloverb-2026\"\n  video_provider: \"scheduled\"\n\n- id: \"pawel-strzalkowski-workshop-wroclove-rb-2026\"\n  title: \"Building a Production-Ready AI App: MCP & OAuth on Rails\"\n  description: |-\n    Make all your Rails applications AI-native. Learn a production-ready method for adding Model Context Protocol to your Rails apps — start-up or legacy. This workshop brings the important piece that is missing in Rails + MCP integration — OAuth2.1 flow that lets an LLM act with user's context and permissions. Adding authorization is a highly needed skill, not covered by the existing tools but is required for production solutions. Paweł is a a veteran Rails developer, a CTO and a vetted conference speaker who combines his passion for AI with deep Rails experience.\n  kind: \"workshop\"\n  language: \"en\"\n  date: \"2026-04-17\"\n  speakers:\n    - Paweł Strzałkowski\n  video_provider: \"scheduled\"\n  video_id: \"pawel-strzalkowski-workshop-wroclove-rb-2026\"\n- id: \"andy-maleh-workshop-wroclove-rb-2026\"\n  title: \"Building Rails SPAs in Frontend Ruby with Glimmer DSL for Web\"\n  description: |-\n    Glimmer DSL for Web is a Ruby Frontend Framework for Rails that won a Fukuoka Prefecture Future IT Initiative 2025 award from Matz. It is the missing piece of the puzzle that finally enables devs to write the Frontend of Rails web apps in Ruby too. This workshops will cover its features and demo samples.\n  kind: \"workshop\"\n  language: \"en\"\n  date: \"2026-04-17\"\n  speakers:\n    - Andy Maleh\n  video_provider: \"scheduled\"\n  video_id: \"andy-maleh-workshop-wroclove-rb-2026\"\n\n- id: \"charles-nutter-wrocloverb-2026\"\n  title: \"JRuby: Professional-Grade Ruby\"\n  raw_title: \"JRuby: Professional-Grade Ruby - Charles Nutter - wroc_love.rb 2026\"\n  speakers:\n    - Charles Nutter\n  event_name: \"wroclove.rb 2026\"\n  published_at: \"TODO\"\n  date: \"2026-04-17\"\n  description: |-\n    Rubyists face many challenges these days, from scaling applications to thousands of users to handling enormous datasets to integrating with an AI-obsessed world. How can we keep Ruby moving forward and the Ruby community strong and healthy? The answer is JRuby! Charles has been working full time on JRuby for the past 20 years, trying to bring more opportunities to the Ruby world. In his talk, he will show how JRuby can help you bring true parallelism, pauseless garbage collection, and JIT optimizations to your Ruby and Rails applications. Get ready to level up your Ruby with JRuby!\n  video_id: \"charles-nutter-wrocloverb-2026\"\n  video_provider: \"scheduled\"\n\n- id: \"ryan-townsend-wroclove-rb-2026\"\n  title: \"No-build Utopia: Modern User Experiences with Rails & Web Standards\"\n  description: |-\n    Teams often reflexively reach for React/Vue, adding build complexity and maintenance overhead. But modern Web Platform APIs now deliver fluid, interactive experiences natively. No framework, no build. Let's explore a progressive approach to building modern UIs in Rails without the JavaScript baggage. With 20 years of experience developing with Rails, Ryan will share how much the web can do on its own these days.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-17\"\n  speakers:\n    - Ryan Townsend\n  video_provider: \"scheduled\"\n  video_id: \"ryan-townsend-wroclove-rb-2026\"\n\n- id: \"markus-schirp-wroclove-rb-2026\"\n  title: \"My core skill never was typing\"\n  description: |-\n    TODO - description\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-18\"\n  speakers:\n    - Markus Schirp\n  video_provider: \"scheduled\"\n  video_id: \"markus-schirp-wroclove-rb-2026\"\n\n- id: \"ismael-celis-wrocloverb-2026\"\n  title: \"Event Sourcing and Actor model in Ruby\"\n  raw_title: \"Event Sourcing and Actor model in Ruby - Ismael Celis - wroc_love.rb 2026\"\n  speakers:\n    - Ismael Celis\n  event_name: \"wroclove.rb 2026\"\n  published_at: \"TODO\"\n  date: \"2026-04-18\"\n  description: |-\n    Let's explore Event Sourcing and the Actor model in Ruby, and how this paradigm can open up entire mental models to think about problems, including concurrency as a domain-level concept, and embracing the eventually-consistent relationship between reality and the code designed to represent it. Ismael has been thinking about and exploring these ideas since 2016, both in Ruby and other stacks. In his talk, he will show how Event Sourcing can provide a cohesive, end-to-end programming model centred around workflows, where a small set of building blocks can enable auditable data, durable execution and reactive UIs by default. All with the simplicity of idiomatic Ruby.\n  video_id: \"ismael-celis-wrocloverb-2026\"\n  video_provider: \"scheduled\"\n\n- id: \"nicolo-rebughini-wroclove-rb-2026\"\n  title: \"Accidentally building a neural network — A Ruby product recommendation journey\"\n  description: |-\n    Machine Learning often feels like a black box reserved for Python data scientists. But what happens when you solve a complex product recommendation problem using Plain Old Ruby Objects, only to discover you've unknowingly recreated the architecture of a Neural Network? Nicolò will deconstruct a real-world recommendation engine that processes thousands of orders per week to prove that you do not not need heavy external services to solve AI problems — you need Ruby!\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-18\"\n  speakers:\n    - Nicolò Rebughini\n  video_provider: \"scheduled\"\n  video_id: \"nicolo-rebughini-wroclove-rb-2026\"\n\n- id: \"emiliano-della-casa-wroclove-rb-2026\"\n  title: \"When REST is Not Enough: Implementing Alternative Protocols in Ruby on Rails\"\n  description: |-\n    Stop forcing REST into every use case. Learn when and how to leverage gRPC for performance, MQTT for IoT, and MCP for AI integration within Ruby on Rails. For over a decade, REST has been the undisputed king of Rails communication. While it remains the standard for web APIs, modern engineering challenges (ranging from high-frequency microservices to IoT deployments and the rise of AI agents) often push HTTP/JSON to its breaking point. Emiliano has been working with Rails for nearly 20 years and spent significant time benchmarking and implementing non-RESTful interfaces in production Ruby environments. This session provides a technical deep dive into how Ruby on Rails can transcend the traditional request-response cycle by integrating three powerful alternatives: gRPC, MQTT and MCP.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-18\"\n  speakers:\n    - Emiliano Della Casa\n  video_provider: \"scheduled\"\n  video_id: \"emiliano-della-casa-wroclove-rb-2026\"\n\n- id: \"sharon-rosner-wroclove-rb-2026\"\n  title: \"UringMachine — High Performance Concurrency for Ruby Using io_uring\"\n  description: |-\n    UringMachine is a new Ruby gem that provides a fast low-level API for building concurrent applications, harnessing the Linux io_uring interface. Let's see how io_uring works, understand the design of UringMachine, and the performance advantages it brings for Ruby web apps. Sharon is a long-time Ruby programmer, and the author of multiple open-source Ruby gems, including Sequel, Extralite, Polyphony, and Papercraft. He is a recipient of a Japanese Ruby Association grant for working on UringMachine. If you are looking for an expert on this topic — you just found one!\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-18\"\n  speakers:\n    - Sharon Rosner\n  video_provider: \"scheduled\"\n  video_id: \"sharon-rosner-wroclove-rb-2026\"\n\n- id: \"josef-strzibny-wrocloverb-2026\"\n  title: \"Kamal is not harder than your PaaS\"\n  raw_title: \"Kamal is not harder than your PaaS - Josef Strzibny - wroc_love.rb 2026\"\n  speakers:\n    - Josef Strzibny\n  event_name: \"wroclove.rb 2026\"\n  published_at: \"TODO\"\n  date: \"2026-04-18\"\n  description: |-\n    Think implementing Kamal in your app is complicated? Josef will prove that it is actually no harder than using your favorite PaaS. Josef is a long time programmer previously working with Ruby/Rails, Elixir/Phoenix and as a Linux package manager and the author of Kamal handbook — the first ever book on Kamal. With this expertese, Josef will present everything you need to know about Kamal.\n  video_id: \"josef-strzibny-wrocloverb-2026\"\n  video_provider: \"scheduled\"\n\n- id: \"lightning-talks-wroclove-rb-2026\"\n  title: \"Lightning talks\"\n  description: |-\n    Lightning talks are a great way to learn about new ideas and share your thoughts. Throughout the day, we encourage you to add your topic to the whiteboard if you'd like to present.\n  kind: \"lightning_talk\"\n  language: \"en\"\n  date: \"2026-04-18\"\n  video_provider: \"scheduled\"\n  video_id: \"lightning-talks-wroclove-rb-2026\"\n  talks: []\n\n- id: \"julik-tarkhanov-wroclove-rb-2026\"\n  title: \"Adventures in durable execution\"\n  description: |-\n    Workflow engines are everywhere now, but Rails still does not have a good one. For more than a year Julik has been exploring workflows and durable execution in Rails — the likes of Vercel 'use workflow', Temporal and DBos. As a result, he has discovered that ActiveJob is an inadequate tool for the purpose — even with 'job continuations' introduced in Rails natively it is still subpar. In his talk, Julik will present a solution that integrates well with Rails without having the user do too much — a Rails-based gem for workflows.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-19\"\n  speakers:\n    - Julik Tarkhanov\n  video_provider: \"scheduled\"\n  video_id: \"julik-tarkhanov-wroclove-rb-2026\"\n\n- id: \"kuba-suder-wroclove-rb-2026\"\n  title: \"Building on Bluesky's AT Protocol with Ruby\"\n  description: |-\n    Ever heard of Authenticated Transfer Protocol? If you have a Bluesky social media account, you're already using it every day. Kuba discovered Bluesky and the AT Protocol in 2023 and he got so hooked that he has been spending all his time building things on it since then. With his curiosity about the AT Protocol, Kuba developed many Bluesky-related open source projects and tools and he takes the stage at wroclove.rb to explore the protocol in depth.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-19\"\n  speakers:\n    - Kuba Suder\n  video_provider: \"scheduled\"\n  video_id: \"kuba-suder-wroclove-rb-2026\"\n\n- id: \"louis-antonopoulos-wroclove-rb-2026\"\n  title: \"Rubyana Gems and the Ractorous Rubetta Stones!\"\n  description: |-\n    What if we had a severly time-constricted and CPU-intensive task that we wanted to solve with Ruby? How might we tackle it? Using the fictional discovery of The Rubetta Stones as our plot driver, and an hourglass that is rapidly running out, we will embark on a journey that leverages the power of Ractors alongside a cheeky AI assistant (trained in Ruby, linguistics, and cryptanalysis) to face this unprecedented challenge. The goal? Break 5 ciphers in 60 seconds to unlock the ultimate secret of the Rubetta Keystone. Join Louis on a whimsical adventure to learn about Ractors while collaborating with an AI for assistance with the linguistic tools that will help us unlock the mystery of The Rubetta Stones!\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-19\"\n  speakers:\n    - Louis Antonopoulos\n  video_provider: \"scheduled\"\n  video_id: \"louis-antonopoulos-wroclove-rb-2026\"\n\n- id: \"adam-okon-wroclove-rb-2026\"\n  title: \"Forms Are Dead: Building Agentic Workflows in Ruby\"\n  description: |-\n    Imagine replacing complex data entry forms with an agentic workflow. Instead of multi-field forms, users paste unstructured content — like emails — into a single text field. The LLM extracts structured data, pre-fills the remaining fields, and saves hours of manual work monthly. Join Adam's talk to discover why LLMs make traditional multi-field forms obsolete and how you can integrate agentic workflows into existing Rails applications.\n  kind: \"talk\"\n  language: \"en\"\n  date: \"2026-04-19\"\n  speakers:\n    - Adam Okoń\n  video_provider: \"scheduled\"\n  video_id: \"adam-okon-wroclove-rb-2026\"\n"
  },
  {
    "path": "data/xoruby/series.yml",
    "content": "---\nname: \"XO Ruby\"\nwebsite: \"https://xoruby.com\"\ntwitter: \"\"\nbsky: \"xoruby.com\"\nyoutube_channel_name: \"Confreaks\"\nkind: \"conference\"\nfrequency: \"yearly\"\nplaylist_matcher: \"XO Ruby\"\ndefault_country_code: \"US\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\naliases:\n  - XORuby\n"
  },
  {
    "path": "data/xoruby/xoruby-atlanta-2025/cfp.yml",
    "content": "---\n- link: \"https://www.xoruby.com/speak/\"\n  open_date: \"2025-07-29\"\n  close_date: \"2025-08-20\"\n"
  },
  {
    "path": "data/xoruby/xoruby-atlanta-2025/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcybWbst1yuhfCjjbwPUg8aTN\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\ntitle: \"XO Ruby Atlanta 2025\"\nkind: \"conference\"\nlocation: \"Atlanta, GA, United States\"\ndescription: |-\n  XO Ruby Atlanta is a single-day, single-track conference designed to draw folks in from the city and the region. An approachable $100 ticket price coupled with no need for a hotel or airfare means you can connect with your community without breaking the bank.\nstart_date: \"2025-09-13\"\nend_date: \"2025-09-13\"\npublished_at: \"2025-12-31\"\nyear: 2025\nwebsite: \"https://xoruby.com/event/atlanta/\"\nbanner_background: \"#230902\"\nfeatured_background: \"#230902\"\nfeatured_color: \"#FE470B\"\ncoordinates:\n  latitude: 33.75000945024761\n  longitude: -84.37730055582303\n"
  },
  {
    "path": "data/xoruby/xoruby-atlanta-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jim Remsik\n  organisations:\n    - Flagrant\n\n- name: \"Volunteer\"\n  users:\n    - Rajesh D\n    - Thomas B\n    - Alen Z\n    - Reuben\n"
  },
  {
    "path": "data/xoruby/xoruby-atlanta-2025/schedule.yml",
    "content": "# Schedule: https://www.xoruby.com/event/atlanta/\n---\ndays:\n  - name: \"XO Ruby Atlanta 2025\"\n    date: \"2025-09-13\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration / Set up\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Welcome\n\n      - start_time: \"09:15\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Fish Bowl Game\n\n      - start_time: \"09:45\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:15\"\n        end_time: \"13:45\"\n        slots: 1\n\n      - start_time: \"13:45\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:15\"\n        end_time: \"14:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:15\"\n        end_time: \"16:45\"\n        slots: 1\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Closing\n\ntracks: []\n"
  },
  {
    "path": "data/xoruby/xoruby-atlanta-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Confreaks\"\n          website: \"https://confreaks.tv\"\n          slug: \"confreaks\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w2000/format/avif/2025/09/confreaks-logo_Main--1-.png\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com\"\n          slug: \"dnsimple\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/08/logomark-classic.png\"\n\n        - name: \"JetRockets\"\n          website: \"https://jetrockets.com\"\n          slug: \"jetrockets\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/08/jetrockets.svg\"\n\n        - name: \"Hubstaff\"\n          website: \"https://hubstaff.com\"\n          slug: \"hubstaff\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/08/Hubstaff-icon.png\"\n\n        - name: \"Flagrant\"\n          website: \"https://www.flagrant.com\"\n          slug: \"flagrant\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/Flagrant_logo_stacked_1c_Orange_pms485U.jpg\"\n\n        - name: \"Cisco\"\n          website: \"https://www.cisco.com\"\n          slug: \"cisco\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/cisco.png\"\n"
  },
  {
    "path": "data/xoruby/xoruby-atlanta-2025/venue.yml",
    "content": "---\nname: \"Limelight Theate\"\ndescription: |-\n  Step into Limelight Theatre, a vibrant space where stories come alive and ideas take center stage. This dynamic venue invites bold presenters and curious audiences to connect, share, and learn through compelling storytelling and engaging conversations. It’s the perfect place to be inspired, challenged, and transformed by the power of authentic voices and fresh perspectives.\ninstructions:\n  \"Whether you’re driving or taking public transit, Limelight Theatre in Atlanta offers convenient access for all visitors. The venue is easily reachable by MARTA, with\n  King Memorial MARTA Station right a. If you choose to drive, street parking and nearby lots provide flexible options to suit your needs, making it simple to arrive ready.\"\naddress:\n  street: \"349 Decatur St. SE Suite L\"\n  city: \"Atlanta\"\n  region: \"GA\"\n  postal_code: \"30312\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"349 Decatur St. SE Suite L, Atlanta, GA 30312\"\ncoordinates:\n  latitude: 33.75000945024761\n  longitude: -84.37730055582303\nmaps:\n  google: \"https://maps.app.goo.gl/dBHgXXzjypc2XWNi7\"\n"
  },
  {
    "path": "data/xoruby/xoruby-atlanta-2025/videos.yml",
    "content": "---\n- id: \"alex-yarotsky-xoruby-atlanta-2025\"\n  title: \"Scaling PostgreSQL Beyond Query Optimization\"\n  event_name: \"XO Ruby Atlanta 2025\"\n  description: |-\n    As Rails apps grow, Postgres often becomes a silent bottleneck—not because of bad queries, but because default behaviors no longer hold up. This talk covers the practical side of scaling Postgres when query tuning alone isn’t enough. We’ll dig into memory tuning, how autovacuum can quietly fall behind, what to watch for in index and bloat maintenance, and when HOT updates make a difference. The focus is on techniques that are commonly overlooked but have a measurable impact in production. If your database feels like it’s fighting you, this talk will show you how to fight back.\n  speakers:\n    - Alex Yarotsky\n  date: \"2025-09-13\"\n  announced_at: \"2025-07-29\"\n  raw_title: \"XORuby Atlanta 2025 - Scaling PostgreSQL Beyond Query Optimization by Alex Yarotsky\"\n  published_at: \"2025-12-31\"\n  video_provider: \"youtube\"\n  video_id: \"OltlmEtKejM\"\n\n- id: \"rachael-wright-munn-xoruby-atlanta-2025\"\n  title: \"Play with your code\"\n  event_name: \"XO Ruby Atlanta 2025\"\n  description: |-\n    Why are programming games more fun than our day jobs? We're going to dig into this exact question and see what lessons we can learn from them, and how we can bring it back to our developer experience. Also, we're going to talk about some rad programming games you should play!\n  speakers:\n    - Rachael Wright-Munn\n  date: \"2025-09-13\"\n  announced_at: \"2025-07-29\"\n  raw_title: \"XO Ruby Atlanta 2025 - Play with your code by Rachael Wright Munn\"\n  published_at: \"2025-12-31\"\n  video_provider: \"youtube\"\n  video_id: \"A4-J6R_uu98\"\n\n- id: \"katya-sarmiento-xoruby-atlanta-2025\"\n  title: \"The Disability Dilemma\"\n  event_name: \"XO Ruby Atlanta 2025\"\n  description: |-\n    Through interactive exercises, we’ll explore the often unseen challenges people face and how they shape the way we work and build products. You’ll leave with a deeper understanding of how small shifts in awareness can spark lasting change.\n  speakers:\n    - Katya Sarmiento\n  date: \"2025-09-13\"\n  announced_at: \"2025-07-29\"\n  raw_title: \"XO Ruby Atlanta 2025 - The Disability Dilemma by Katya Sarmiento\"\n  published_at: \"2025-12-31\"\n  video_provider: \"youtube\"\n  video_id: \"Hzwf1JPDzP0\"\n\n- id: \"thomas-cannon-xoruby-atlanta-2025\"\n  title: \"Empty Pipeline, Empty Future\"\n  event_name: \"XO Ruby Atlanta 2025\"\n  description: |-\n    We've created a beautiful, fun language; but we need more juniors, stat! Let's talk about the benefits juniors bring, and the things you can do this month to help fix the pipeline problem.\n  speakers:\n    - Thomas Cannon\n  date: \"2025-09-13\"\n  announced_at: \"2025-07-29\"\n  raw_title: \"XO Ruby Atlanta 2025 - Empty Pipeline, Empty Future by Thomas Cannon\"\n  published_at: \"2025-12-31\"\n  video_provider: \"youtube\"\n  video_id: \"R2a_Hnv43TY\"\n\n- id: \"igor-aleksandrov-xoruby-atlanta-2025\"\n  title: \"Overreacting – from React to Hotwire\"\n  event_name: \"XO Ruby Atlanta 2025\"\n  description: |-\n    We built SafariPortal as a React SPA in 2020 when it made perfect sense – Hotwire didn’t exist, and we needed complex travel itinerary building. Fast-forward to 2023: we’re staring down an ambitious roadmap to transform our simple builder into a full travel CRM, and React’s ceremony is killing us. Redux boilerplate for every state change, frontend-backend coordination overhead, AI tools amplifying complexity instead of productivity. Meanwhile, our Hotwire experiments show one Rails developer shipping what used to take a specialized frontend-backend duo plus project management theater.\n    So we did something radical: we kept our React app running and started building new features in Rails. No big-bang rewrites, no developer trauma, just pragmatic coexistence while we proved Hotwire’s value. The results? 50% faster feature delivery, 93% smaller bundles, and team productivity through the roof. This isn’t about React being terrible or Rails being perfect – it’s about recognizing when you’ve outgrown your tools and having the courage to choose simplicity over complexity. I’ll share our complete hybrid migration strategy, real code patterns, honest gotchas, and a decision framework for when this approach makes sense for your team.\n  speakers:\n    - Igor Aleksandrov\n  date: \"2025-09-13\"\n  announced_at: \"2025-07-29\"\n  raw_title: \"XO Ruby Atlanta 2025 - Overreacting—From React to Hotwire by Igor Aleksandrov\"\n  published_at: \"2025-12-31\"\n  video_provider: \"youtube\"\n  video_id: \"DuZP9sBAeIo\"\n\n- id: \"jeremy-smith-xoruby-atlanta-2025\"\n  title: \"Refactoring Volatile Views into Cohesive Components\"\n  event_name: \"XO Ruby Atlanta 2025\"\n  description: |-\n    It's easy for models to grow unwieldy, accumulating methods, attributes, and responsibilities. But views can be even worse. Let's refactor the mess into clean, cohesive components with ViewComponent.\n  speakers:\n    - Jeremy Smith\n  date: \"2025-09-13\"\n  announced_at: \"2025-07-29\"\n  raw_title: \"XO Ruby Atlanta 2025 -  Refactoring Volatile Views into Cohesive Components by Jeremy Smith\"\n  published_at: \"2025-12-31\"\n  video_provider: \"youtube\"\n  video_id: \"Q2CjuVaAFC8\"\n\n- id: \"javier-zon-xoruby-atlanta-2025\"\n  title: \"From Expensive Queries to Smart Caching: A DBA’s Guide for Rails\"\n  event_name: \"XO Ruby Atlanta 2025\"\n  description: |-\n    If you’ve ever watched your Rails app drive up the MySQL bill, you know the pain. In this session, we’ll look at how ProxySQL and ReadySet can help, from query routing to smart caching and show how a little DBA magic can make your apps faster while keeping costs under control.\n  speakers:\n    - Javier Zon\n  date: \"2025-09-13\"\n  announced_at: \"2025-09-08\"\n  raw_title: \"XO Ruby Atlanta 2025, From Expensive Queries to Smart Caching: A DBA’s Guide for Rails by Javier Zon\"\n  published_at: \"2025-12-31\"\n  video_provider: \"youtube\"\n  video_id: \"oqx0el3RCz0\"\n\n- id: \"kylie-stradley-xoruby-atlanta-2025\"\n  title: \"SAST and Sensibility: A Rubyist’s Guide to Static Analysis Security Testing\"\n  event_name: \"XO Ruby Atlanta 2025\"\n  description: |-\n    You may already use tools like RuboCop or Brakeman, but are you getting the most out of static analysis? Ruby’s dynamic nature and metaprogramming invite creative security exploits and make SAST tricky. This talk explores how to choose the right tool, balancing sense and sensibility.\n  speakers:\n    - Kylie Stradley\n  date: \"2025-09-13\"\n  announced_at: \"2025-09-08\"\n  raw_title: \"XO Ruby Atlanta 2025 - SAST and Sensibility: A Rubyist’s Guide to Static... by Kylie Stradley\"\n  published_at: \"2025-12-31\"\n  video_provider: \"youtube\"\n  video_id: \"g354RNbB9ag\"\n"
  },
  {
    "path": "data/xoruby/xoruby-austin-2025/event.yml",
    "content": "---\nid: \"xoruby-austin-2025\"\ntitle: \"XO Ruby Austin 2025\"\nkind: \"conference\"\nlocation: \"Austin, TX, United States\"\ndescription: \"\"\nstart_date: \"2025-10-25\"\nend_date: \"2025-10-25\"\npublished_at: \"2026-01-09\"\nyear: 2025\nwebsite: \"https://xoruby.com/event/austin/\"\nbanner_background: \"#230902\"\nfeatured_background: \"#230902\"\nfeatured_color: \"#FE470B\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\ncoordinates:\n  latitude: 30.264805297233387\n  longitude: -97.73540044344846\n"
  },
  {
    "path": "data/xoruby/xoruby-austin-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jim Remsik\n  organisations:\n    - Flagrant\n\n- name: \"Volunteer\"\n  users:\n    - Rick Benavidez\n    - Michelle Doltzenrod\n    - Raluca Badoi\n    - Mando Escamilla\n"
  },
  {
    "path": "data/xoruby/xoruby-austin-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Confreaks\"\n          website: \"https://confreaks.tv\"\n          slug: \"confreaks\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w2000/format/avif/2025/09/confreaks-logo_Main--1-.png\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"dnsimple\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/08/logomark-classic.png\"\n\n        - name: \"Flagrant\"\n          website: \"https://www.flagrant.com/\"\n          slug: \"flagrant\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/Flagrant_logo_stacked_1c_Orange_pms485U.jpg\"\n\n        - name: \"Cisco\"\n          website: \"https://www.cisco.com/\"\n          slug: \"cisco\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/cisco.png\"\n"
  },
  {
    "path": "data/xoruby/xoruby-austin-2025/venue.yml",
    "content": "---\nname: \"The Cut ATX\"\ndescription: |-\n  Located in the heart Downtown Austin, Texas, The Cut ATX venue offers a curated, high-energy atmosphere that emphasizes a focus on music and community. Known for its after‑hours electronic music events, the venue is built with a broader vision in mind and occupies an intimate indoor space that aims for a strong sense of closeness between speakers and audience.\naddress:\n  street: \"401 Sabine Street\"\n  city: \"Austin\"\n  region: \"TX\"\n  postal_code: \"78701\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"401 Sabine Street Austin, TX 78701\"\ncoordinates:\n  latitude: 30.264805297233387\n  longitude: -97.73540044344846\nmaps:\n  google: \"https://maps.app.goo.gl/tRghChuz798KhHba7\"\n"
  },
  {
    "path": "data/xoruby/xoruby-austin-2025/videos.yml",
    "content": "---\n# Talks for XO Ruby Austin 2025\n# Event date: 2025-10-25\n# Website: https://www.xoruby.com/event/austin/\n\n- title: \"Intelligent Event Discovery with Ruby\"\n  raw_title: \"XO Ruby Austin 2025 - Rag Demystified by Landon Gray\"\n  speakers:\n    - Landon Gray\n  date: \"2025-10-25\"\n  published_at: \"2026-01-08\"\n  description: |-\n    What started as a simple side project to find things to do in my city evolved into a full AI-powered event recommendation engine. I'll share how I've been building an intelligent event discovery platform in my spare time using Ruby.\n  video_provider: \"youtube\"\n  video_id: \"VnPmgJXC29g\"\n  id: \"landon-gray-xoruby-austin-2025\"\n\n- title: \"TikTok on Rails\"\n  raw_title: \"XO Ruby Austin 2025 - TikTok on Rails by Cecy Correa 2\"\n  speakers:\n    - Cecy Correa\n  date: \"2025-10-25\"\n  published_at: \"2026-01-09\"\n  description: |-\n    What would it take to recreate the magic of TikTok, snappy feeds, endless scroll, and smart recommendations, using only Ruby on Rails? This talk explores just how far Rails can go as a full-stack framework, from building modern UIs to experimenting with feed algorithms that keep content engaging.\n  video_provider: \"youtube\"\n  video_id: \"uq3n8yVnbCw\"\n  id: \"cecy-correa-xoruby-austin-2025\"\n\n- title: \"Lost and Alone Over the Pacific\"\n  raw_title: \"XO Ruby Austin 2025 - Lost and Alone Over the Pacific by Nickolas Means\"\n  speakers:\n    - Nickolas Means\n  date: \"2025-10-25\"\n  published_at: \"2026-01-09\"\n  description: |-\n    On December 22, 1978, veteran US Navy pilot Jay Prochnow found himself lost over the Pacific in a tiny single-engine plane after a navigation failure during a solo ferry flight. With no land in sight and nightfall approaching, he had to find a way to survive. This is the story of how he navigated out of the crisis—and what we can learn from his experience.\n  video_provider: \"youtube\"\n  video_id: \"JH3082aApgo\"\n  id: \"nickolas-means-xoruby-austin-2025\"\n\n- title: \"Introducing ReActionView: A new ActionView-Compatible ERB Engine\"\n  raw_title: \"Introducing ReActionView: A new ActionView-Compatible ERB Engine\"\n  date: \"2025-10-25\"\n  announced_at: \"2025-10-25\"\n  location: \"Remote\"\n  speakers:\n    - Marco Roth\n  description: |-\n    This talk is the conclusion of a journey I've been sharing throughout 2025. At RubyKaigi, I introduced Herb: a new HTML-aware ERB parser and tooling ecosystem. At RailsConf, I released developer tools built on Herb, including a formatter, linter, and language server, alongside a vision for modernizing and improving the Rails view layer.\n\n    Now, I'll continue with ReActionView: a new ERB engine built on Herb, fully compatible with `.html.erb` but with HTML validation, better error feedback, reactive updates, and built-in tooling.\n  video_provider: \"scheduled\"\n  video_id: \"marco-roth-xoruby-austin-2025\"\n  id: \"marco-roth-xoruby-austin-2025\"\n  slides_url: \"https://speakerdeck.com/marcoroth/introducing-reactionview-a-new-actionview-compatible-erb-engine-at-xo-ruby-austin-2025\"\n\n- title: \"The Vibes Are Off In Tech (but we can fix them)\"\n  raw_title: \"XO Ruby Austin 2025 - The Vibes Are Off in Tech (but we can fix them) by Aaron Harpole\"\n  speakers:\n    - Aaron Harpole\n  date: \"2025-10-25\"\n  published_at: \"2026-01-09\"\n  description: |-\n    Tech as an industry is in a weird place right now. Far from being just for hobbyists, technology companies are the biggest companies in the world with market caps exceeding the GDP of many countries. Tech takes up an increasing amount of space in our lives while simultaneously becoming less fun than it once was.\n  video_provider: \"youtube\"\n  video_id: \"RnGL7qeqnbg\"\n  id: \"aaron-harpole-xoruby-austin-2025\"\n\n- title: \"Rewriting Localhost: A Modern Approach to Dev Environments\"\n  raw_title: \"XO Ruby Austin 2025 - Rewriting Localhost: A Modern Approach to Dev Environments by Nathan Hessler\"\n  speakers:\n    - Nathan Hessler\n  date: \"2025-10-25\"\n  published_at: \"2026-01-09\"\n  description: |-\n    Tired of wrestling with localhost ports in your Ruby projects? A reverse proxy can simplify your local development, align it with production, and make multi-app environments effortless. In this talk, we'll explore the evolution of reverse proxy solutions, their setup, and their role in Ruby development. Through practical examples and use cases, you'll discover flexible strategies to enhance your local dev workflow.\n  video_provider: \"youtube\"\n  video_id: \"Pr6xe4Xq4wE\"\n  id: \"nathan-hessler-xoruby-austin-2025\"\n"
  },
  {
    "path": "data/xoruby/xoruby-chicago-2025/cfp.yml",
    "content": "---\n- link: \"https://www.xoruby.com/speak/\"\n  open_date: \"2025-07-29\"\n  close_date: \"2025-08-13\"\n"
  },
  {
    "path": "data/xoruby/xoruby-chicago-2025/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyYQUbSLmwTdNRf3jE1RJY2S\"\ntitle: \"XO Ruby Chicago 2025\"\nkind: \"conference\"\nlocation: \"Chicago, IL, United States\"\ndescription: |-\n  Chicago has its own steady rhythm—each neighborhood with something different to offer. This event is for \"locals\" from St. Louis to Indianapolis who want to get together, learn something, and connect with others who are in search of the same.\n\n  XO Ruby is a single-day, single-track conference designed to draw folks in from the city and the region. An approachable $100 ticket price coupled with no need for a hotel or airfare means you can connect with your community without breaking the bank.\nstart_date: \"2025-09-06\"\nend_date: \"2025-09-06\"\npublished_at: \"2025-12-18\"\nyear: 2025\nwebsite: \"https://xoruby.com/event/chicago/\"\nbanner_background: \"#230902\"\nfeatured_background: \"#230902\"\nfeatured_color: \"#FE470B\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\ncoordinates:\n  latitude: 41.88918236302005\n  longitude: -87.67283327116462\n"
  },
  {
    "path": "data/xoruby/xoruby-chicago-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jim Remsik\n  organisations:\n    - Flagrant\n\n- name: \"Volunteer\"\n  users:\n    - Michelle Yuen\n    - Anton Tkachov\n    - Mina Slater\n    - Mark Yoon\n    - Jonathan G\n"
  },
  {
    "path": "data/xoruby/xoruby-chicago-2025/schedule.yml",
    "content": "# Schedule: https://www.xoruby.com/event/chicago/\n---\ndays:\n  - name: \"XO Ruby Chicago 2025\"\n    date: \"2025-09-06\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration / Set up\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Welcome\n\n      - start_time: \"09:15\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Fish Bowl Game\n\n      - start_time: \"09:45\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:15\"\n        end_time: \"13:45\"\n        slots: 1\n\n      - start_time: \"13:45\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:15\"\n        end_time: \"14:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"16:00\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"16:00\"\n        end_time: \"16:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:15\"\n        end_time: \"16:45\"\n        slots: 1\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Closing\n"
  },
  {
    "path": "data/xoruby/xoruby-chicago-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Confreaks\"\n          website: \"https://confreaks.tv\"\n          slug: \"confreaks\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w2000/format/avif/2025/09/confreaks-logo_Main--1-.png\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"dnsimple\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/08/logomark-classic.png\"\n\n        - name: \"Flagrant\"\n          website: \"https://www.flagrant.com/\"\n          slug: \"flagrant\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/Flagrant_logo_stacked_1c_Orange_pms485U.jpg\"\n\n        - name: \"Cisco\"\n          website: \"https://www.cisco.com/\"\n          slug: \"cisco\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/cisco.png\"\n"
  },
  {
    "path": "data/xoruby/xoruby-chicago-2025/venue.yml",
    "content": "---\nname: \"Fulton Street Collective\"\ndescription: |-\n  Fulton Street Collective is a creative space in Chicago’s West Town neighborhood. With big windows, frequently updated art on the walls, and an open layout, your creativity will run wild.\ninstructions:\n  \"Whether you drive or use public transit, Fulton Street Collective provides flexible and convenient transportation options. The venue is accessible via the CTA Green\n  and Pink Lines. The Damen and Ashland stations are both about a 7–9 minute walk from the venue and bus stops are a few minutes walk away. If you're coming from further away there\n  is a first come first served onsite parking lot.\"\naddress:\n  street: \"1821 W Hubbard St\"\n  city: \"Chicago\"\n  region: \"IL\"\n  postal_code: \"60622\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"1821 W Hubbard St, Chicago, IL 60622\"\ncoordinates:\n  latitude: 41.88918236302005\n  longitude: -87.67283327116462\nmaps:\n  google: \"https://maps.app.goo.gl/8LfXujb3kKTiZUX37\"\n"
  },
  {
    "path": "data/xoruby/xoruby-chicago-2025/videos.yml",
    "content": "---\n- id: \"scott-werner-xoruby-chicago-2025\"\n  title: \"We Were Voyagers. We Can Voyage Again!\"\n  raw_title: \"XO Ruby Chicago 2025 - We Were Voyagers. We Can Voyage Again! by Scott Werner\"\n  event_name: \"XO Ruby Chicago 2025\"\n  description: |-\n    Do you remember Ruby's \"Golden Age\"? The era of why the lucky stiff, when frameworks like Camping and Sinatra felt like artistic expressions, and every week brought a new, delightful experiment. Ruby was the language of developer happiness, defined by a magical duality: rock-solid productivity on one hand, and playful, creative exploration on the other.\n\n    In our collective journey to maturity, building stable, mission-critical applications, has some of that original spark been lost? Have we become so focused on the practical that we've forgotten the \"kind of silly\"?\n\n    This talk argues that the rise of Generative AI isn't just a new wave of productivity tools; it's a chance to reclaim our heritage as voyagers. It's an opportunity to bring back the magic, the art, and the sheer fun of creation.\n  speakers:\n    - Scott Werner\n  date: \"2025-09-06\"\n  announced_at: \"2025-07-29\"\n  published_at: \"2025-12-18\"\n  video_id: \"vSbC1sIl6qo\"\n  video_provider: \"youtube\"\n\n- id: \"erin-claudio-xoruby-chicago-2025\"\n  title: \"A Builder's Guide to Not-for-Profit Ruby on Rails\"\n  raw_title: \"XO Ruby Chicago 2025 - A Builder's Guide to Not-for-Profit Ruby on Rails by Erin Claudio\"\n  event_name: \"XO Ruby Chicago 2025\"\n  description: |-\n    This talk explores how working with Ruby on Rails in the not-for-profit sector can provide meaningful technical challenges while fostering personal growth, purpose, and sustainability in a developer’s career. Through real-world examples and practical advice, it highlights the unique opportunities, skills, and impact that come from building technology for social good.\n  speakers:\n    - Erin Claudio\n  date: \"2025-09-06\"\n  announced_at: \"2025-07-29\"\n  published_at: \"2025-12-18\"\n  video_id: \"zD-7bDnWYZg\"\n  video_provider: \"youtube\"\n\n- id: \"peter-bhat-harkins-xoruby-chicago-2025\"\n  title: \"Perfect is too expensive\"\n  raw_title: \"XO Ruby Chicago 2025 - Perfect is too expensive by Peter Bhat Harkins\"\n  event_name: \"XO Ruby Chicago 2025\"\n  description: |-\n    Every nontrivial database has invalid data in it. Records that can't pass their validations, NULLs where background jobs silently failed, records that combine to impossible states, and even errors introduced when fixing other bugs. There's a missing tool from our toolboxes. (No, it's not SQL constraints). Come learn how to catch these bugs before your users do.\n  speakers:\n    - Peter Bhat Harkins\n  date: \"2025-09-06\"\n  announced_at: \"2025-07-29\"\n  published_at: \"2025-12-18\"\n  video_id: \"BFUqj37_qqY\"\n  video_provider: \"youtube\"\n\n- id: \"yuri-bocharov-xoruby-chicago-2025\"\n  title: \"From fork() to Fibers: Concurrency in Ruby\"\n  raw_title: \"XO Ruby Chicago 2025 - Concurrency in Ruby: From fork() to Fiber by Yuri Bocharov\"\n  event_name: \"XO Ruby Chicago 2025\"\n  description: |-\n    We often rely on concurrency in Ruby without really understanding how it works under the hood. In this talk, we’ll build a simple TCP server and iteratively improve it using processes, threads, and fibers, measuring along the way. By connecting these primitives to real-world servers like Puma, Falcon, and Unicorn, you’ll come away with a clearer grasp of how Ruby handles concurrency and the tradeoffs behind each approach.\n  speakers:\n    - Yuri Bocharov\n  date: \"2025-09-06\"\n  announced_at: \"2025-07-29\"\n  published_at: \"2025-12-18\"\n  video_id: \"73H6z4CUUIs\"\n  video_provider: \"youtube\"\n\n- id: \"aji-slater-xoruby-chicago-2025\"\n  title: \"The TDD Treasure Map\"\n  raw_title: \"XO Ruby Chicago 2025 - The TDD Treasure Map by Aji Slater\"\n  event_name: \"XO Ruby Chicago 2025\"\n  description: |-\n    We know testing is vital and makes refactoring painless. But how to set sail to that TDD treasure? Yarr, we need to test to get experience, but need experience to test. Let’s draw a map with simple strategies for identifying test cases and building a robust test suite. X marks the spot w/ TDD tools for newbies and seasoned pirates alike.\n  speakers:\n    - Christopher \"Aji\" Slater\n  date: \"2025-09-06\"\n  announced_at: \"2025-07-29\"\n  published_at: \"2025-12-18\"\n  video_id: \"RAvaKii7V6A\"\n  video_provider: \"youtube\"\n\n- id: \"justin-herrick-xoruby-chicago-2025\"\n  title: \"A Tale at Any Scale\"\n  raw_title: \"XO Ruby Chicago 2025 - A Tale at Any Scale by Justin Herrick\"\n  event_name: \"XO Ruby Chicago 2025\"\n  description: |-\n    What really sets a 5-year-old Rails codebase apart from one that's been evolving for over 14 years? What patterns emerge when you work in a codebase with over a million commits and more than a decade of continuous development? In this talk, we'll dive into a few of the lessons learned from working inside a very old and very large Rails codebase. We will talk about what works (and what doesn't) as both your team and your codebase grow, which best practices stand the test of time, and how even the massive codebases share common traits with projects of all sizes. Whether you're maintaining a startup app or contributing to a legacy system, you'll leave with new insights you can apply to your work.\n  speakers:\n    - Justin Herrick\n  date: \"2025-09-06\"\n  announced_at: \"2025-07-29\"\n  published_at: \"2025-12-18\"\n  video_id: \"D0GBW_k_83c\"\n  video_provider: \"youtube\"\n\n- id: \"coraline-ada-ehmke-xoruby-chicago-2025\"\n  title: \"Dystopia: How We Got Here, and What We Can Do About It\"\n  raw_title: \"XO Ruby Chicao 2025 - Dystopia: How We Got Here, and What We Can Do About It by Coraline Ada Ehmke\"\n  event_name: \"XO Ruby Chicago 2025\"\n  description: |-\n    We truly live in the worst timeline, but should it really have come as a surprise? Learn the history of our present technosocial nightmare, and find the inspiration to start building what comes after.\n  speakers:\n    - Coraline Ada Ehmke\n  date: \"2025-09-06\"\n  announced_at: \"2025-07-29\"\n  published_at: \"2025-12-18\"\n  video_id: \"rUnJdjPOrAM\"\n  video_provider: \"youtube\"\n"
  },
  {
    "path": "data/xoruby/xoruby-new-orleans-2025/cfp.yml",
    "content": "---\n- link: \"https://www.xoruby.com/speak/\"\n  open_date: \"2025-07-29\"\n  close_date: \"2025-08-27\"\n"
  },
  {
    "path": "data/xoruby/xoruby-new-orleans-2025/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyZd2NLU8MrkipX_ofiyXjg9\"\ntitle: \"XO Ruby New Orleans 2025\"\nkind: \"conference\"\nlocation: \"New Orleans, LA, United States\"\ndescription: |-\n  XO Ruby New Orleans is a single-day, single-track conference designed to draw folks in from the city and the region. An approachable $100 ticket price coupled with no need for a hotel or airfare means you can connect with your community without breaking the bank.\nstart_date: \"2025-09-20\"\nend_date: \"2025-09-20\"\nyear: 2025\nwebsite: \"https://xoruby.com/event/new-orleans/\"\npublished_at: \"2025-12-26\"\nbanner_background: \"#230902\"\nfeatured_background: \"#230902\"\nfeatured_color: \"#FE470B\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\ncoordinates:\n  latitude: 29.96511330626241\n  longitude: -90.04925856237186\n"
  },
  {
    "path": "data/xoruby/xoruby-new-orleans-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jim Remsik\n  organisations:\n    - Flagrant\n\n- name: \"Volunteer\"\n  users:\n    - Natalie F\n    - Mike S\n    - Alex\n    - Cedric\n"
  },
  {
    "path": "data/xoruby/xoruby-new-orleans-2025/schedule.yml",
    "content": "# Schedule: https://www.xoruby.com/event/new-orleans/\n---\ndays:\n  - name: \"XO Ruby New Orleans 2025\"\n    date: \"2025-09-20\"\n    grid:\n      - start_time: \"07:30\"\n        end_time: \"08:30\"\n        slots: 1\n        items:\n          - Registration / Set up\n\n      - start_time: \"08:30\"\n        end_time: \"08:45\"\n        slots: 1\n        items:\n          - Welcome\n\n      - start_time: \"08:45\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Fish Bowl Game\n\n      - start_time: \"09:15\"\n        end_time: \"09:45\"\n        slots: 1\n\n      - start_time: \"9:45\"\n        end_time: \"10:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"13:00\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:00\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:00\"\n        end_time: \"14:30\"\n        slots: 1\n\n      - start_time: \"14:30\"\n        end_time: \"15:00\"\n        slots: 1\n\n      - start_time: \"15:00\"\n        end_time: \"15:30\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:30\"\n        end_time: \"16:00\"\n        slots: 1\n\n      - start_time: \"16:00\"\n        end_time: \"16:15\"\n        slots: 1\n        items:\n          - Closing\n"
  },
  {
    "path": "data/xoruby/xoruby-new-orleans-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Confreaks\"\n          website: \"https://confreaks.tv\"\n          slug: \"confreaks\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w2000/format/avif/2025/09/confreaks-logo_Main--1-.png\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"dnsimple\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/08/logomark-classic.png\"\n\n        - name: \"Flagrant\"\n          website: \"https://www.flagrant.com/\"\n          slug: \"flagrant\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/Flagrant_logo_stacked_1c_Orange_pms485U.jpg\"\n\n        - name: \"Cisco\"\n          website: \"https://www.cisco.com/\"\n          slug: \"cisco\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/cisco.png\"\n"
  },
  {
    "path": "data/xoruby/xoruby-new-orleans-2025/venue.yml",
    "content": "---\nname: \"Marigny Opera House\"\ndescription: |-\n  Once inside the Marigny Opera House, you’ll discover a one-of-a-kind venue that exudes old-world elegance and creative spirit. Housed in a beautifully restored former church dating back to the 19th century, this “Church of the Arts” welcomes artists, thinkers, and communities alike with its soaring architecture, graceful details, and a sun-drenched full lawn. Experience the magic of New Orleans’s in a place where history, beauty, and inspiration meet.\ninstructions:\n  \"The Marigny Opera House is easy to reach, whether you’re coming by car, streetcar, or bus. Enjoy free self-parking on site, with additional street parking available\n  for your convenience. Public transportation is straightforward—take the RTA bus lines 57, 8, or 80, all of which stop just a short walk away. For those exploring, the St. Claude\n  Avenue streetcar line is less than fifteen minutes on foot, connecting you quickly to the French Quarter and other parts of the city.\"\naddress:\n  street: \"725 St. Ferdinand Street\"\n  city: \"New Orleans\"\n  region: \"LA\"\n  postal_code: \"70117\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"725 St. Ferdinand Street, New Orleans, LA 70117\"\ncoordinates:\n  latitude: 29.96511330626241\n  longitude: -90.04925856237186\nmaps:\n  google: \"https://maps.app.goo.gl/Zb1RUfqnwY7y7Qv47\"\n"
  },
  {
    "path": "data/xoruby/xoruby-new-orleans-2025/videos.yml",
    "content": "---\n- id: \"glynnis-ritchie-xoruby-new-orleans-2025\"\n  title: \"The Dark Art of Designing for Dark Mode\"\n  raw_title: \"XO Ruby New Orleans 2025 - The Dark Art of Designing for Dark Mode by Glynnis Ritchie\"\n  event_name: \"XO Ruby New Orleans 2025\"\n  description: |-\n    Designing for dark mode requires a thoughtful approach to color, depth, and perception. Learn why your out-of-the-box dark theme and Tailwind's \".dark\" class might not be cutting it. We'll dig into color terminology like hue and saturation, debunk common misconceptions about dark mode, discuss accessibility and color, and explore how to convey elevation through light sources and shadow. Learn practical design tips about working with color that you can apply to any project.\n  speakers:\n    - Glynnis Ritchie\n  date: \"2025-09-20\"\n  announced_at: \"2025-09-16\"\n  published_at: \"2025-12-26\"\n  video_id: \"qwNFYzN300I\"\n  video_provider: \"youtube\"\n\n- id: \"thomas-carr-xoruby-new-orleans-2025\"\n  title: \"The State of the Ruby AI Toolbox\"\n  raw_title: \"XO Ruby New Orleans 2025 - The State of the Ruby AI Toolbox by Thomas Carr\"\n  event_name: \"XO Ruby New Orleans 2025\"\n  description: |-\n    The AI landscape is evolving rapidly, with new tools and libraries emerging all the time. In this talk, we'll explore the current state of AI development in Ruby, highlighting key libraries, frameworks, and tools that are shaping the way we build AI-powered applications. From machine learning to natural language processing, we'll cover the essentials you need to know to get started with AI in Ruby.\n  speakers:\n    - Thomas Carr\n  date: \"2025-09-20\"\n  announced_at: \"2025-09-16\"\n  published_at: \"2025-12-26\"\n  video_id: \"3m2ZioS2j3w\"\n  video_provider: \"youtube\"\n\n- id: \"robert-ross-xoruby-new-orleans-2025\"\n  title: \"If I did it again\"\n  raw_title: \"XO Ruby New Orleans 2025 - If I had it to do again by Robert Ross\"\n  event_name: \"XO Ruby New Orleans 2025\"\n  description: |-\n    If we could rebuild FireHydrant from scratch, what would we do differently? Which architectural bets paid off, and which became obstacles? This talk examines Laddertruck, the Rails codebase powering incident management for hundreds of thousands of outages annually. We’ll explore our engineering journey—technical debt that slowed us down, assets that accelerated growth, and the architectural decisions that later enabled seamless AI integration. Drawing from years of building a startup’s core platform, this session distills hard-won lessons into practical guidance for teams starting greenfield projects, helping you sidestep common pitfalls and make stronger architectural choices from day one.\n  speakers:\n    - Robert Ross\n  date: \"2025-09-20\"\n  announced_at: \"2025-09-16\"\n  published_at: \"2025-12-26\"\n  video_id: \"TW8B3HrBWVE\"\n  video_provider: \"youtube\"\n\n- id: \"george-mauer-xoruby-new-orleans-2025\"\n  title: \"Readme.md? We Can Do Better\"\n  raw_title: \"XO Ruby New Orleans 2025 - Readme.md? We Can Do Better by George Mauer\"\n  event_name: \"XO Ruby New Orleans 2025\"\n  description: |-\n    The venerable README file has a long history going back to at least the 1970s. Nowadays, when all code lives on Github it is basically a standard. README files are great and we all encourage more use of them except...can we do better? In this session we'll explore some other supported README formats and make a recommendation that yes, indeed, we can.\n  speakers:\n    - George Mauer\n  date: \"2025-09-20\"\n  announced_at: \"2025-09-16\"\n  published_at: \"2025-12-26\"\n  video_id: \"eTjOGpu4RJo\"\n  video_provider: \"youtube\"\n\n- id: \"john-paul-ashenfelter-xoruby-new-orleans-2025\"\n  title: \"Do the Right Thing\"\n  raw_title: \"XO Ruby New Orleans 2025 - Do the Right Thing: Practical lessons for your.. by John Paul Ashenfelter\"\n  event_name: \"XO Ruby New Orleans 2025\"\n  description: |-\n    Why do standards like HIPAA, PCI, SOC2, and FedRAMP matter, and what value do they bring to developers? Drawing on years of experience in highly regulated industries, this session shows how Ruby and open-source tools make it easier than ever to build secure applications and protect user data—something every developer should care about.\n  speakers:\n    - John Paul Ashenfelter\n  date: \"2025-09-20\"\n  announced_at: \"2025-09-16\"\n  published_at: \"2025-12-26\"\n  video_id: \"o61WEq_vnAA\"\n  video_provider: \"youtube\"\n\n- id: \"ryan-hageman-xoruby-new-orleans-2025\"\n  title: \"The Misconception About Models\"\n  raw_title: \"XO Ruby New Orleans 2025 - The Misconception About Models by Ryan Hageman\"\n  event_name: \"XO Ruby New Orleans 2025\"\n  description: |-\n    Developers follow mantras like 'fat model, skinny controller' and get into debates about service objects, form objects, and POROs. These debates happen because we see slightly different definitions of 'models' across patterns and frameworks, leaving us confused about what models actually are. In this talk, we'll step outside software to rediscover what models really represent. When we bring that insight back to code, some of these arguments fall apart entirely while others become simple organization decisions. You'll walk away with a mental model that makes decisions about code architecture and organization easier.\n  speakers:\n    - Ryan Hageman\n  date: \"2025-09-20\"\n  announced_at: \"2025-09-16\"\n  published_at: \"2025-12-31\"\n  video_id: \"sRZ_Rec-sug\"\n  video_provider: \"youtube\"\n"
  },
  {
    "path": "data/xoruby/xoruby-portland-2025/event.yml",
    "content": "---\nid: \"PLE7tQUdRKcyaY3KWcA0rivzadTyMNkE9A\"\ntitle: \"XO Ruby Portland 2025\"\nkind: \"conference\"\nlocation: \"Portland, OR, United States\"\ndescription: |-\n  XO Ruby Portland is a single-day, single-track conference designed to draw folks in from the city and the region. An approachable $100 ticket price coupled with no need for a hotel or airfare means you can connect with your community without breaking the bank.\nstart_date: \"2025-10-11\"\nend_date: \"2025-10-11\"\npublished_at: \"2025-12-26\"\nyear: 2025\nwebsite: \"https://xoruby.com/event/portland/\"\nbanner_background: \"#230902\"\nfeatured_background: \"#230902\"\nfeatured_color: \"#FE470B\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\ncoordinates:\n  latitude: 45.513189442609175\n  longitude: -122.6639331116672\n"
  },
  {
    "path": "data/xoruby/xoruby-portland-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jim Remsik\n  organisations:\n    - Flagrant\n\n- name: \"Volunteer\"\n  users:\n    - Kirsten Comandich\n    - Adam Hendrickson\n    - Steven Ancheta\n    - Lee Ann Bradford\n"
  },
  {
    "path": "data/xoruby/xoruby-portland-2025/schedule.yml",
    "content": "# Schedule: https://www.xoruby.com/event/portland/\n---\ndays:\n  - name: \"XO Ruby Portland 2025\"\n    date: \"2025-10-11\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration / Set up\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Welcome\n\n      - start_time: \"09:15\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Fish Bowl Game\n\n      - start_time: \"09:45\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:45\"\n        end_time: \"14:15\"\n        slots: 1\n\n      - start_time: \"14:15\"\n        end_time: \"14:45\"\n        slots: 1\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 1\n\n      - start_time: \"16:15\"\n        end_time: \"16:45\"\n        slots: 1\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Closing\n"
  },
  {
    "path": "data/xoruby/xoruby-portland-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Planet Argon\"\n          website: \"https://www.planetargon.com/\"\n          slug: \"planet-argon\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/08/pa-logo-765-1-.png\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"dnsimple\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/08/logomark-classic.png\"\n\n        - name: \"Flagrant\"\n          website: \"https://www.flagrant.com/\"\n          slug: \"flagrant\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/Flagrant_logo_stacked_1c_Orange_pms485U.jpg\"\n\n        - name: \"Cisco\"\n          website: \"https://www.cisco.com/\"\n          slug: \"cisco\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/cisco.png\"\n"
  },
  {
    "path": "data/xoruby/xoruby-portland-2025/venue.yml",
    "content": "---\nname: \"Bridge Space\"\ndescription: |-\n  Close to the river in an up-and-coming part of town and steps away from one of Portland's newest food pods. This flexible space has been used by community and artist groups to host meetings, conferences, workshops, dances and more. The industrial chic space feels expansive, with a stage area set up at the far side of the space, kitchen and food prep spaces, and bathrooms.\naddress:\n  street: \"133 SE Madison St\"\n  city: \"Portland\"\n  region: \"OR\"\n  postal_code: \"97214\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"133 SE Madison St, Portland, OR 97214\"\ncoordinates:\n  latitude: 45.513189442609175\n  longitude: -122.6639331116672\nmaps:\n  google: \"https://maps.app.goo.gl/MM9PwHFafSg8P8qL6\"\n"
  },
  {
    "path": "data/xoruby/xoruby-portland-2025/videos.yml",
    "content": "---\n# Videos for XO Ruby Portland 2025\n# Event date: 2025-10-11\n# Website: https://www.xoruby.com/event/portland/\n\n- id: \"ben-curtis-xoruby-portland-2025\"\n  title: \"Show & Tell with Honeybadger: Welcome to our OPS Meeting!\"\n  raw_title: \"XO Ruby Portland 2025 - Show & Tell with Honeybadger: Welcome to our OPS Meeting! by Ben Curtis\"\n  event_name: \"XO Ruby Portland 2025\"\n  description: \"\"\n  speakers:\n    - Ben Curtis\n  date: \"2025-10-11\"\n  published_at: \"2025-12-26\"\n  video_id: \"2JP20hxuvsE\"\n  video_provider: \"youtube\"\n\n- id: \"joe-masilotti-xoruby-portland-2025\"\n  title: \"Let's build a mobile app\"\n  raw_title: \"XO Ruby Portland 2025 - Let's build a mobile app by Joe Masilotti\"\n  event_name: \"XO Ruby Portland 2025\"\n  description: |-\n    Learn how to build mobile apps the Rails way with Hotwire Native. By reusing your existing HTML and CSS, you can keep your business logic on the server and stay productive in Rails - without needing to become a mobile expert. Learn how small teams are shipping faster, solo developers are doing the impossible, and Rails is once again leading the way.\n  speakers:\n    - Joe Masilotti\n  date: \"2025-10-11\"\n  published_at: \"2025-12-26\"\n  video_id: \"OcYEhtzx38k\"\n  video_provider: \"youtube\"\n\n- id: \"kayla-reopelle-xoruby-portland-2025\"\n  title: \"Using OpenTelemetry to Build More Human-Friendly Systems\"\n  raw_title: \"XO Ruby Portland 2025 - Using OpenTelemetry to Build More Human-Friendly Systems by Kayla Reopelle\"\n  event_name: \"XO Ruby Portland 2025\"\n  description: |-\n    Stop debugging with stress and start with empathy. This talk will show you how to use OpenTelemetry to build systems that are not only more reliable, but also kinder to your users and your team.\n  speakers:\n    - Kayla Reopelle\n  date: \"2025-10-11\"\n  published_at: \"2025-12-26\"\n  video_id: \"w6xflt7AWvE\"\n  video_provider: \"youtube\"\n\n- id: \"jason-clark-xoruby-portland-2025\"\n  title: \"Lightning Talk: Smooshing Ruby\"\n  raw_title: \"XO Ruby Portland 2025 - Lightning Talk: Smooshing Ruby by Jason Clark\"\n  event_name: \"XO Ruby Portland 2025\"\n  description: \"\"\n  speakers:\n    - Jason Clark\n  date: \"2025-10-11\"\n  published_at: \"2025-12-26\"\n  video_id: \"FPux18WVTcA\"\n  video_provider: \"youtube\"\n\n- id: \"renee-hendricksen-xoruby-portland-2025\"\n  title: \"I know Kung Fu! RubyGems for AI\"\n  raw_title: \"XO Ruby Portland 2025 - I know Kung Fu! RubyGems for AI by Renée Hendricksen\"\n  event_name: \"XO Ruby Portland 2025\"\n  description: |-\n    A smart person learns from their mistakes; a wise person learns from the mistakes of others; How can we make a wise AI? I started with the question: can AI get an app from idea to working production deployment faster than I can? The answer was a resounding No. However, this has lead me to thinking about where the gaps are and how we could better load the context an AI needs to be successful at a more complex task. Join me in my experiments of leveling up our AI Ruby friends!\n  speakers:\n    - Renée Hendricksen\n  date: \"2025-10-11\"\n  published_at: \"2025-12-26\"\n  video_id: \"hPfQwio6pxk\"\n  video_provider: \"youtube\"\n\n- id: \"aaron-patterson-xoruby-portland-2025\"\n  title: \"Profiling Tips and Tricks\"\n  raw_title: \"XO Ruby Portland 2025 - Profiling Tips and Tricks by Aaron Patterson\"\n  event_name: \"XO Ruby Portland 2025\"\n  description: |-\n    Lets look at how we can speed up our code with a real world use cases. We'll look at profiling code with Vernier, how to understand profiling output, and what to do about slow code.\n  speakers:\n    - Aaron Patterson\n  date: \"2025-10-11\"\n  published_at: \"2025-12-26\"\n  video_id: \"N2knxO5TvTI\"\n  video_provider: \"youtube\"\n\n- id: \"ryan-davis-xoruby-portland-2025\"\n  title: \"Let's Build a Computer\"\n  raw_title: \"XO Ruby Portland 2025 - Let's Build A Computer by Ryan Davis\"\n  event_name: \"XO Ruby Portland 2025\"\n  description: |-\n    Most of us treat our computers like magic, but under the hood they're just layers of simple logic stacked on top of each other. Using the Nand to Tetris curriculum, the Seattle.rb study group spent 12 weeks building a simulated computer entirely from the ground up—starting with a NAND gate, then constructing the hardware architecture, assembler, virtual machine, compiler, and even an operating system with games. In this talk, I will start with the nand gate, and build up a working computer explaining each layer as I go. You may not be able to build along with me in just a half hour, but I hope to infect you with my love for this curriculum and hopefully have it spread to your ruby/study group.\n  speakers:\n    - Ryan Davis\n  date: \"2025-10-11\"\n  published_at: \"2025-12-26\"\n  video_id: \"rK_J5dCtk6M\"\n  video_provider: \"youtube\"\n\n- id: \"sam-livingston-gray-xoruby-portland-2025\"\n  title: \"Randomness In Tests (Don't Do It)\"\n  raw_title: \"XO Ruby Portland 2025 - Randomness In Tests (Don't Do It) by Sam Livingston-Gray\"\n  event_name: \"XO Ruby Portland 2025\"\n  description: |-\n    Kent Beck wrote \"Tests are the Programmer's Stone, transmuting fear into boredom.\"  But I keep encountering tests with nondeterministic behavior, so clearly not everyone got the memo... I'll talk about what a PRNG is, when you should absolutely use one in your test suite, when existing uses are safe to politely ignore, and when you should #KillItWithFire.  I'll also share an incredibly obvious realization about flaky tests that only took me several years to stumble into!\n  speakers:\n    - Sam Livingston-Gray\n  date: \"2025-10-11\"\n  published_at: \"2025-12-26\"\n  video_id: \"-xwWEEa5ayE\"\n  video_provider: \"youtube\"\n"
  },
  {
    "path": "data/xoruby/xoruby-san-diego-2025/event.yml",
    "content": "---\nid: \"xoruby-san-diego-2025\"\ntitle: \"XO Ruby San Diego 2025\"\nkind: \"conference\"\nlocation: \"San Diego, CA, United States\"\ndescription: \"\"\nstart_date: \"2025-10-18\"\nend_date: \"2025-10-18\"\npublished_at: \"2026-01-10\"\nyear: 2025\nwebsite: \"https://xoruby.com/event/san-diego/\"\nbanner_background: \"#230902\"\nfeatured_background: \"#230902\"\nfeatured_color: \"#FE470B\"\nchannel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\"\ncoordinates:\n  latitude: 32.81217839642391\n  longitude: -117.2682015306403\n"
  },
  {
    "path": "data/xoruby/xoruby-san-diego-2025/involvements.yml",
    "content": "---\n- name: \"Organizer\"\n  users:\n    - Jim Remsik\n  organisations:\n    - Flagrant\n\n- name: \"Volunteer\"\n  users:\n    - Dominic Lizarraga\n    - Vanessa Bastien\n"
  },
  {
    "path": "data/xoruby/xoruby-san-diego-2025/schedule.yml",
    "content": "# Schedule: https://www.xoruby.com/event/san-diego/\n---\ndays:\n  - name: \"XO Ruby San Diego 2025\"\n    date: \"2025-10-11\"\n    grid:\n      - start_time: \"08:00\"\n        end_time: \"09:00\"\n        slots: 1\n        items:\n          - Registration / Set up\n\n      - start_time: \"09:00\"\n        end_time: \"09:15\"\n        slots: 1\n        items:\n          - Welcome\n\n      - start_time: \"09:15\"\n        end_time: \"09:45\"\n        slots: 1\n        items:\n          - Fish Bowl Game\n\n      - start_time: \"09:45\"\n        end_time: \"10:15\"\n        slots: 1\n\n      - start_time: \"10:15\"\n        end_time: \"10:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"10:45\"\n        end_time: \"11:15\"\n        slots: 1\n\n      - start_time: \"11:15\"\n        end_time: \"11:45\"\n        slots: 1\n\n      - start_time: \"11:45\"\n        end_time: \"13:30\"\n        slots: 1\n        items:\n          - Lunch\n\n      - start_time: \"13:30\"\n        end_time: \"14:00\"\n        slots: 1\n        items:\n          - Lightning Talks\n\n      - start_time: \"14:15\"\n        end_time: \"14:45\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"14:45\"\n        end_time: \"15:15\"\n        slots: 1\n\n      - start_time: \"15:15\"\n        end_time: \"15:45\"\n        slots: 1\n        items:\n          - TBA\n\n      - start_time: \"15:45\"\n        end_time: \"16:15\"\n        slots: 1\n        items:\n          - Break\n\n      - start_time: \"16:15\"\n        end_time: \"16:45\"\n        slots: 1\n        items:\n          - TBA\n\n      - start_time: \"16:45\"\n        end_time: \"17:00\"\n        slots: 1\n        items:\n          - Closing\n"
  },
  {
    "path": "data/xoruby/xoruby-san-diego-2025/sponsors.yml",
    "content": "---\n- tiers:\n    - name: \"Sponsors\"\n      description: \"\"\n      level: 1\n      sponsors:\n        - name: \"Confreaks\"\n          website: \"https://confreaks.tv\"\n          slug: \"confreaks\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w2000/format/avif/2025/09/confreaks-logo_Main--1-.png\"\n\n        - name: \"DNSimple\"\n          website: \"https://dnsimple.com/\"\n          slug: \"dnsimple\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/08/logomark-classic.png\"\n\n        - name: \"Flagrant\"\n          website: \"https://www.flagrant.com/\"\n          slug: \"flagrant\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/Flagrant_logo_stacked_1c_Orange_pms485U.jpg\"\n\n        - name: \"Cisco\"\n          website: \"https://www.cisco.com/\"\n          slug: \"cisco\"\n          logo_url: \"https://www.xoruby.com/content/images/size/w1200/2025/07/cisco.png\"\n"
  },
  {
    "path": "data/xoruby/xoruby-san-diego-2025/venue.yml",
    "content": "---\nname: \"Found Studio\"\ndescription: |-\n  Luxury space in the heart of Bird Rock La Jolla. A blank canvas space, our design studio space has plenty of natural light and breathing room for your group.\naddress:\n  street: \"5490 La Jolla Blvd\"\n  city: \"La Jolla\"\n  region: \"CA\"\n  postal_code: \"92037\"\n  country: \"United States\"\n  country_code: \"US\"\n  display: \"5490 La Jolla Blvd, La Jolla, CA 92037\"\ncoordinates:\n  latitude: 32.81217839642391\n  longitude: -117.2682015306403\nmaps:\n  google: \"https://maps.app.goo.gl/Fi9vqsRDp3ZyV6Uz9\"\n"
  },
  {
    "path": "data/xoruby/xoruby-san-diego-2025/videos.yml",
    "content": "---\n# Videos for XO San Diego 2025\n# Event date: 2025-10-18\n# Website: https://www.xoruby.com/event/san-diego/\n\n- id: \"claudio-baccigalupo-xoruby-san-diego-2025\"\n  title: \"Optimize for Developer Speed\"\n  raw_title: \"XO Ruby San Diego 2025 - Optimize for developer speed by Claudio Baccigalupo\"\n  event_name: \"XO Ruby San Diego 2025\"\n  published_at: \"2026-01-08\"\n  description: |-\n    Launching a Rails 8 app in two months as a single developer can sound scary. In this talk I will guide you through the choices made to deliver great value in time for a planned release. You will hear about the latest powers of Active Record, Active Job and Turbo 8. We will review system tests and take a look at Hotwire Native and Bridge components. You will learn why, twenty years after its release, Ruby on Rails is still the best single-developer web framework.\n  speakers:\n    - Claudio Baccigalupo\n  date: \"2025-10-18\"\n  video_id: \"Dcp2eCgdF90\"\n  video_provider: \"youtube\"\n\n- id: \"sunjay-armstead-xoruby-san-diego-2025\"\n  title: \"Never Fear, Unicorns Are Here!\"\n  raw_title: \"XO Ruby San Diego 2025 - Never Fear, Unicorns Are Here! by Sunjay Armstead\"\n  event_name: \"XO Ruby San Diego 2025\"\n  published_at: \"2026-01-08\"\n  description: |-\n    It's no secret that AI is having a moment and engineering as we know it is rapidly changing. But, if you're like me, you're likely feeling a bit nervous about how quickly our industry is evolving. What should our response be to this cultural moment and how do we thrive in the midst of change? In this session, I will teach you the best way to respond, why being a unicorn is essential to your flourishing, and how to become one.\n  speakers:\n    - Sunjay Armstead\n  date: \"2025-10-18\"\n  video_id: \"WTAmSvEq8eA\"\n  video_provider: \"youtube\"\n\n- id: \"karl-weber-xoruby-san-diego-2025\"\n  title: \"How to Fail\"\n  raw_title: \"XO Ruby San Diego 2025 - How to Fail by Karl Oscar Weber\"\n  event_name: \"XO Ruby San Diego 2025\"\n  published_at: \"2026-01-09\"\n  description: |-\n    KOW offers insights into a topic he is an expert in: Failure. How to do it, how to avoid it, and what to do when you do fail. Failure isn't the end, and being aware of common failure methods will help you to avoid them.\n\n    With a strong bias towards freelance work, but applicable to most effort driven endeavors, such as an agency, studio, or individual contributor, Karl offers lessons from his personal life about how to screw up, and how to avoid it. In the hopes that you may learn from his mistakes, and hopefully make some novel, unique mistakes all on your own.\n\n    Finally KOW will also share a statement of intent to start or support a new Ruby Foundation in the efforts to diversify and strengthen the Ruby ecosystem. And some direct lessons on how to organize and strengthen community, an imperative effort.\n  speakers:\n    - Karl Weber\n  date: \"2025-10-18\"\n  video_id: \"dtzSjLrbzlM\"\n  video_provider: \"youtube\"\n\n- id: \"craig-buchek-xoruby-san-diego-2025\"\n  title: \"Architecture\"\n  raw_title: \"XO Ruby San Diego 2025 - Architecture by Craig Buchek\"\n  event_name: \"XO Ruby San Diego 2025\"\n  published_at: \"2026-01-10\"\n  description: |-\n    We use the term \"architecture\" in computer programming quite a bit. But is it a valid and useful analogy (or borrowing of the term)? What could we learn by taking another look at the architecture of buildings? We'll take a look at the history of patterns in building architecture, and how our industry adopted a similar way of thinking. What have we missed? Why do we only consider large architectural issues, and ignore smaller issues that still might be considered architectural?\n  speakers:\n    - Craig Buchek\n  date: \"2025-10-18\"\n  video_id: \"938dqF7T9Fs\"\n  video_provider: \"youtube\"\n\n- id: \"chantelle-isaacs-xoruby-san-diego-2025\"\n  title: \"Dungeons and Developers: Uniting Experience Levels in Engineering Teams\"\n  raw_title: \"XO Ruby San Diego 2025 - Dungeons and Developers: Uniting Experience Levels... by Chantelle Isaacs\"\n  event_name: \"XO Ruby San Diego 2025\"\n  published_at: \"2026-01-09\"\n  description: |-\n    Join us in \"Dungeons and Developers,\" a unique exploration of team dynamics through the lens of Dungeons & Dragons. Discover how the roles and skills in D&D can enlighten the way we build, manage, and nurture diverse engineering teams. Whether you're a manager aiming to construct a formidable team (Constitution) or an individual seeking to self-assess and advance your career (Charisma), this talk will guide you in leveraging technical and transferable talents. Together we'll identify your developer archetype and complete a 'Developer Character Sheet'—our tool for highlighting abilities, proficiencies, and alignment in a fun, D&D-inspired format. Developers and managers alike will leave this talk with a newfound appreciation for the varied skills and talents each person brings to the table.\n  speakers:\n    - Chantelle Isaacs\n  date: \"2025-10-18\"\n  video_id: \"k5VfVmIU7KM\"\n  video_provider: \"youtube\"\n\n- id: \"tim-riley-xoruby-san-diego-2025\"\n  title: \"What I Talk About When I Talk About Ruby\"\n  raw_title: \"XO Ruby San Diego 2025 - What I Talk About When I Talk About Ruby by Tim Riley\"\n  event_name: \"XO Ruby San Diego 2025\"\n  published_at: \"2026-01-10\"\n  description: |-\n    Our path to a more diverse Ruby, and the rewards from the journey. A look at Hanami and more.\n  speakers:\n    - Tim Riley\n  date: \"2025-10-18\"\n  video_id: \"5---uZisFy0\"\n  video_provider: \"youtube\"\n\n- id: \"braulio-martinez-xoruby-san-diego-2025\"\n  title: \"Passkeys in Ruby\"\n  raw_title: \"XO Ruby San Diego 2025 - Passkeys in Ruby by Braulio Martinez\"\n  event_name: \"XO Ruby San Diego 2025\"\n  published_at: \"2026-01-10\"\n  description: |-\n    Nowadays, passwords are still our most common authentication method. However, they are not secure enough and have terrible UX.\n\n    Therefore, big industry players in the FIDO Alliance like Google, Apple, Yubico, 1Password (among others) collaborated together to find a solution. WebAuthn was born and eventually became a W3C standard enabling users to authenticate on the web using public-key cryptography together with biometrics.\n\n    This talk will allow you to learn what WebAuthn and Passkeys are and how they work. You'll also see how any Ruby app can easily get the level of authentication security and UX users deserve.\n  speakers:\n    - Braulio Martinez\n  date: \"2025-10-18\"\n  video_id: \"9D5JMJQq-Gg\"\n  video_provider: \"youtube\"\n"
  },
  {
    "path": "db/cache_migrate/20240516085648_create_solid_cache_entries.solid_cache.rb",
    "content": "# This migration comes from solid_cache (originally 20230724121448)\nclass CreateSolidCacheEntries < ActiveRecord::Migration[7.0]\n  def change\n    create_table :solid_cache_entries do |t|\n      t.binary :key, null: false, limit: 1024\n      t.binary :value, null: false, limit: 512.megabytes\n      t.datetime :created_at, null: false\n\n      t.index :key, unique: true\n    end\n  end\nend\n"
  },
  {
    "path": "db/cache_migrate/20240516085649_add_key_hash_and_byte_size_to_solid_cache_entries.solid_cache.rb",
    "content": "# This migration comes from solid_cache (originally 20240108155507)\nclass AddKeyHashAndByteSizeToSolidCacheEntries < ActiveRecord::Migration[7.0]\n  def change\n    change_table :solid_cache_entries do |t|\n      t.column :key_hash, :integer, null: true, limit: 8\n      t.column :byte_size, :integer, null: true, limit: 4\n    end\n  end\nend\n"
  },
  {
    "path": "db/cache_migrate/20240516085650_add_key_hash_and_byte_size_indexes_and_null_constraints_to_solid_cache_entries.solid_cache.rb",
    "content": "# This migration comes from solid_cache (originally 20240110111600)\nclass AddKeyHashAndByteSizeIndexesAndNullConstraintsToSolidCacheEntries < ActiveRecord::Migration[7.0]\n  def change\n    change_table :solid_cache_entries, bulk: true do |t|\n      t.change_null :key_hash, false\n      t.change_null :byte_size, false\n      t.index :key_hash, unique: true\n      t.index [:key_hash, :byte_size]\n      t.index :byte_size\n    end\n  end\nend\n"
  },
  {
    "path": "db/cache_migrate/20240516085651_remove_key_index_from_solid_cache_entries.solid_cache.rb",
    "content": "# This migration comes from solid_cache (originally 20240110111702)\nclass RemoveKeyIndexFromSolidCacheEntries < ActiveRecord::Migration[7.0]\n  def change\n    change_table :solid_cache_entries do |t|\n      t.remove_index :key, unique: true\n    end\n  end\nend\n"
  },
  {
    "path": "db/cache_schema.rb",
    "content": "# This file is auto-generated from the current state of the database. Instead\n# of editing this file, please use the migrations feature of Active Record to\n# incrementally modify your database, and then regenerate this schema definition.\n#\n# This file is the source Rails uses to define your schema when running `bin/rails\n# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to\n# be faster and is potentially less error prone than running all of your\n# migrations from scratch. Old migrations may fail to apply correctly if those\n# migrations use external dependencies or application code.\n#\n# It's strongly recommended that you check this file into your version control system.\n\nActiveRecord::Schema[8.2].define(version: 2024_05_16_085651) do\n  create_table \"solid_cache_entries\", force: :cascade do |t|\n    t.integer \"byte_size\", limit: 4, null: false\n    t.datetime \"created_at\", null: false\n    t.binary \"key\", limit: 1024, null: false\n    t.integer \"key_hash\", limit: 8, null: false\n    t.binary \"value\", limit: 536870912, null: false\n    t.index [\"byte_size\"], name: \"index_solid_cache_entries_on_byte_size\"\n    t.index [\"key_hash\", \"byte_size\"], name: \"index_solid_cache_entries_on_key_hash_and_byte_size\"\n    t.index [\"key_hash\"], name: \"index_solid_cache_entries_on_key_hash\", unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230512050041_create_speakers.rb",
    "content": "class CreateSpeakers < ActiveRecord::Migration[7.1]\n  def change\n    create_table :speakers do |t|\n      t.string :name, default: \"\", null: false\n      t.string :twitter, default: \"\", null: false\n      t.string :github, default: \"\", null: false\n      t.text :bio, default: \"\", null: false\n      t.string :website, default: \"\", null: false\n      t.string :slug, default: \"\", null: false\n\n      t.timestamps\n    end\n    add_index :speakers, :name\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230512051225_create_talks.rb",
    "content": "class CreateTalks < ActiveRecord::Migration[7.1]\n  def change\n    create_table :talks do |t|\n      t.string :title, default: \"\", null: false\n      t.text :description, default: \"\", null: false\n      t.string :slug, default: \"\", null: false\n      t.string :video_id, default: \"\", null: false\n      t.string :video_provider, default: \"\", null: false\n      t.string :thumbnail_sm, default: \"\", null: false\n      t.string :thumbnail_md, default: \"\", null: false\n      t.string :thumbnail_lg, default: \"\", null: false\n      t.integer :year\n\n      t.timestamps\n    end\n\n    add_index :talks, :title\n    add_index :talks, :slug\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230521202931_create_join_table_speakers_talks.rb",
    "content": "class CreateJoinTableSpeakersTalks < ActiveRecord::Migration[7.1]\n  def change\n    create_join_table :speakers, :talks, table_name: \"speaker_talks\" do |t|\n      t.index [:speaker_id, :talk_id]\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230521211825_add_talks_count_to_speaker.rb",
    "content": "class AddTalksCountToSpeaker < ActiveRecord::Migration[7.1]\n  def change\n    add_column :speakers, :talks_count, :integer, default: 0, null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230522051939_create_suggestions.rb",
    "content": "class CreateSuggestions < ActiveRecord::Migration[7.1]\n  def change\n    create_table :suggestions do |t|\n      t.text :content\n      t.integer :status, default: 0, null: false\n      t.references :suggestable, polymorphic: true, null: false\n\n      t.timestamps\n    end\n\n    # add_index :suggestions, [:suggestable_id, :suggestable_type], unique: true\n    add_index :suggestions, :status\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230522133312_create_users.rb",
    "content": "class CreateUsers < ActiveRecord::Migration[7.1]\n  def change\n    create_table :users do |t|\n      t.string :email, null: false, index: {unique: true}\n      t.string :password_digest, null: false\n      t.string :first_name, null: false, default: \"\"\n      t.string :last_name, null: false, default: \"\"\n\n      t.boolean :verified, null: false, default: false\n      t.boolean :admin, null: false, default: false\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230522133313_create_sessions.rb",
    "content": "class CreateSessions < ActiveRecord::Migration[7.1]\n  def change\n    create_table :sessions do |t|\n      t.references :user, null: false, foreign_key: true\n      t.string :user_agent\n      t.string :ip_address\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230522133314_create_password_reset_tokens.rb",
    "content": "class CreatePasswordResetTokens < ActiveRecord::Migration[7.1]\n  def change\n    create_table :password_reset_tokens do |t|\n      t.references :user, null: false, foreign_key: true\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230522133315_create_email_verification_tokens.rb",
    "content": "class CreateEmailVerificationTokens < ActiveRecord::Migration[7.1]\n  def change\n    create_table :email_verification_tokens do |t|\n      t.references :user, null: false, foreign_key: true\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230522212710_create_events.rb",
    "content": "class CreateEvents < ActiveRecord::Migration[7.1]\n  def change\n    create_table :events do |t|\n      t.string :name, default: \"\", null: false\n      t.text :description, default: \"\", null: false\n      t.string :website, default: \"\", null: false\n      t.integer :kind, default: 0, null: false\n      t.integer :frequency, default: 0, null: false\n\n      t.timestamps\n    end\n\n    add_index :events, :name\n    add_index :events, :kind\n    add_index :events, :frequency\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230522213244_add_event_references_to_talk.rb",
    "content": "class AddEventReferencesToTalk < ActiveRecord::Migration[7.1]\n  def change\n    add_reference :talks, :event, foreign_key: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230525132507_add_index_slug_to_speaker.rb",
    "content": "class AddIndexSlugToSpeaker < ActiveRecord::Migration[7.1]\n  def change\n    add_index :speakers, :slug, unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230604215247_create_ahoy_visits_and_events.rb",
    "content": "class CreateAhoyVisitsAndEvents < ActiveRecord::Migration[7.1]\n  def change\n    create_table :ahoy_visits do |t|\n      t.string :visit_token\n      t.string :visitor_token\n\n      # the rest are recommended but optional\n      # simply remove any you don't want\n\n      # user\n      t.references :user\n\n      # standard\n      t.string :ip\n      t.text :user_agent\n      t.text :referrer\n      t.string :referring_domain\n      t.text :landing_page\n\n      # technology\n      t.string :browser\n      t.string :os\n      t.string :device_type\n\n      # location\n      t.string :country\n      t.string :region\n      t.string :city\n      t.float :latitude\n      t.float :longitude\n\n      # utm parameters\n      t.string :utm_source\n      t.string :utm_medium\n      t.string :utm_term\n      t.string :utm_content\n      t.string :utm_campaign\n\n      # native apps\n      t.string :app_version\n      t.string :os_version\n      t.string :platform\n\n      t.datetime :started_at\n    end\n\n    add_index :ahoy_visits, :visit_token, unique: true\n\n    create_table :ahoy_events do |t|\n      t.references :visit\n      t.references :user\n\n      t.string :name\n      t.text :properties\n      t.datetime :time\n    end\n\n    add_index :ahoy_events, [:name, :time]\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230614230539_rename_event_table_to_organisation.rb",
    "content": "class RenameEventTableToOrganisation < ActiveRecord::Migration[7.1]\n  def change\n    rename_table :events, :organisations\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230614231651_create_new_events.rb",
    "content": "class CreateNewEvents < ActiveRecord::Migration[7.1]\n  def change\n    create_table :events do |t|\n      t.date :date\n      t.string :city\n      t.string :country_code\n      t.references :organisation, null: false, foreign_key: true\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230614232412_add_youtube_channel_id_to_organisation.rb",
    "content": "class AddYouTubeChannelIdToOrganisation < ActiveRecord::Migration[7.1]\n  def change\n    add_column :organisations, :youtube_channel_id, :string, default: \"\", null: false\n    add_column :organisations, :youtube_channel_name, :string, default: \"\", null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230614233712_add_slug_to_organisation.rb",
    "content": "class AddSlugToOrganisation < ActiveRecord::Migration[7.1]\n  def change\n    add_column :organisations, :slug, :string, default: \"\", null: false\n    add_index :organisations, :slug\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230614234246_add_name_to_event.rb",
    "content": "class AddNameToEvent < ActiveRecord::Migration[7.1]\n  def change\n    add_column :events, :name, :string, default: \"\", null: false\n    add_index :events, :name\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230615053959_add_slug_to_event.rb",
    "content": "class AddSlugToEvent < ActiveRecord::Migration[7.1]\n  def change\n    add_column :events, :slug, :string, default: \"\", null: false\n    add_index :events, :slug\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230615055319_add_thumbnails_to_talk.rb",
    "content": "class AddThumbnailsToTalk < ActiveRecord::Migration[7.1]\n  def change\n    add_column :talks, :thumbnail_xs, :string, default: \"\", null: false\n    add_column :talks, :thumbnail_xl, :string, default: \"\", null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230615055800_fix_foreign_constrain.rb",
    "content": "class FixForeignConstrain < ActiveRecord::Migration[7.1]\n  def change\n    reversible do |dir|\n      dir.up do\n        remove_foreign_key :talks, :organisations\n        add_foreign_key :talks, :events\n      end\n\n      dir.down do\n        remove_foreign_key :talks, :events\n        add_foreign_key :talks, :organisations, column: \"event_id\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230615105716_add_date_to_talk.rb",
    "content": "class AddDateToTalk < ActiveRecord::Migration[7.1]\n  def change\n    add_column :talks, :date, :date\n    add_index :talks, :date\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230622202051_add_upvotes_and_views_to_talks.rb",
    "content": "class AddUpvotesAndViewsToTalks < ActiveRecord::Migration[7.1]\n  def change\n    add_column :talks, :like_count, :integer\n    add_column :talks, :view_count, :integer\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230625215935_add_twitter_to_organisation.rb",
    "content": "class AddTwitterToOrganisation < ActiveRecord::Migration[7.1]\n  def change\n    add_column :organisations, :twitter, :string, default: \"\", null: false\n    add_column :organisations, :language, :string, default: \"\", null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230720104208_add_uniq_index_speaker_talk.rb",
    "content": "class AddUniqIndexSpeakerTalk < ActiveRecord::Migration[7.1]\n  def change\n    remove_index :speaker_talks, [:speaker_id, :talk_id], if_exists: true\n    add_index :speaker_talks, [:speaker_id, :talk_id], unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20230720151537_add_primary_key_to_speaker_talks.rb",
    "content": "class AddPrimaryKeyToSpeakerTalks < ActiveRecord::Migration[7.1]\n  def change\n    # if primary key does not exist, add it\n    if !ActiveRecord::Base.connection.column_exists?(:speaker_talks, :id)\n      add_column :speaker_talks, :id, :primary_key\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240611113918_add_transcript_to_talk.rb",
    "content": "class AddTranscriptToTalk < ActiveRecord::Migration[7.1]\n  def change\n    add_column :talks, :transcript, :text, default: \"\", null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240614060121_add_service_name_to_active_storage_blobs.active_storage.rb",
    "content": "# This migration comes from active_storage (originally 20190112182829)\nclass AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0]\n  def up\n    return unless table_exists?(:active_storage_blobs)\n\n    unless column_exists?(:active_storage_blobs, :service_name)\n      add_column :active_storage_blobs, :service_name, :string\n\n      if (configured_service = ActiveStorage::Blob.service.name)\n        ActiveStorage::Blob.unscoped.update_all(service_name: configured_service)\n      end\n\n      change_column :active_storage_blobs, :service_name, :string, null: false\n    end\n  end\n\n  def down\n    return unless table_exists?(:active_storage_blobs)\n\n    remove_column :active_storage_blobs, :service_name\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240614060122_create_active_storage_variant_records.active_storage.rb",
    "content": "# This migration comes from active_storage (originally 20191206030411)\nclass CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0]\n  def change\n    return unless table_exists?(:active_storage_blobs)\n\n    # Use Active Record's configured type for primary key\n    create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t|\n      t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type\n      t.string :variation_digest, null: false\n\n      t.index %i[blob_id variation_digest], name: \"index_active_storage_variant_records_uniqueness\", unique: true\n      t.foreign_key :active_storage_blobs, column: :blob_id\n    end\n  end\n\n  private\n\n  def primary_key_type\n    config = Rails.configuration.generators\n    config.options[config.orm][:primary_key_type] || :primary_key\n  end\n\n  def blobs_primary_key_type\n    pkey_name = connection.primary_key(:active_storage_blobs)\n    pkey_column = connection.columns(:active_storage_blobs).find { |c| c.name == pkey_name }\n    pkey_column.bigint? ? :bigint : pkey_column.type\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240614060123_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb",
    "content": "# This migration comes from active_storage (originally 20211119233751)\nclass RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[6.0]\n  def change\n    return unless table_exists?(:active_storage_blobs)\n\n    change_column_null(:active_storage_blobs, :checksum, true)\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240709194147_add_enhanced_transcript_to_talk.rb",
    "content": "class AddEnhancedTranscriptToTalk < ActiveRecord::Migration[7.1]\n  def change\n    add_column :talks, :enhanced_transcript, :text, default: \"\", null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240709200506_rename_transcript_in_talk.rb",
    "content": "class RenameTranscriptInTalk < ActiveRecord::Migration[7.1]\n  def change\n    rename_column :talks, :transcript, :raw_transcript\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240718202658_add_summary_to_talk.rb",
    "content": "class AddSummaryToTalk < ActiveRecord::Migration[7.2]\n  def change\n    add_column :talks, :summary, :text, default: \"\", null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240811121204_create_topics.rb",
    "content": "class CreateTopics < ActiveRecord::Migration[7.2]\n  def change\n    create_table :topics do |t|\n      t.string :name, index: {unique: true}\n      t.text :description\n      t.boolean :published, default: false\n      t.string :slug, null: false\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240811122145_create_talk_topics.rb",
    "content": "class CreateTalkTopics < ActiveRecord::Migration[7.2]\n  def change\n    create_table :talk_topics do |t|\n      t.references :talk, null: false, foreign_key: true\n      t.references :topic, null: false, foreign_key: true\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240815155647_add_uniq_index_on_talk_topic.rb",
    "content": "class AddUniqIndexOnTalkTopic < ActiveRecord::Migration[7.2]\n  def change\n    add_index :talk_topics, [:talk_id, :topic_id], unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240816074626_add_status_to_topic.rb",
    "content": "class AddStatusToTopic < ActiveRecord::Migration[7.2]\n  def change\n    add_column :topics, :status, :string, null: false, default: \"pending\"\n    add_index :topics, :status\n\n    Topic.where(published: true).update_all(status: \"approved\")\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240817083428_add_canonical_reference_to_topic.rb",
    "content": "class AddCanonicalReferenceToTopic < ActiveRecord::Migration[7.2]\n  def change\n    add_reference :topics, :canonical, foreign_key: {to_table: :topics}\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240818212042_add_language_to_talk.rb",
    "content": "class AddLanguageToTalk < ActiveRecord::Migration[7.2]\n  def change\n    add_column :talks, :language, :string, null: false, default: \"en\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240819134138_drop_year_from_talk.rb",
    "content": "class DropYearFromTalk < ActiveRecord::Migration[7.2]\n  def change\n    remove_column :talks, :year\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240821191208_add_talks_count_to_event.rb",
    "content": "class AddTalksCountToEvent < ActiveRecord::Migration[7.2]\n  def up\n    add_column :events, :talks_count, :integer, default: 0, null: false\n\n    Event.all.each do |event|\n      event.update_columns(talks_count: event.talks.count)\n    end\n  end\n\n  def down\n    remove_column :events, :talks_count\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240823221832_add_slides_url_to_talks.rb",
    "content": "class AddSlidesUrlToTalks < ActiveRecord::Migration[7.2]\n  def change\n    add_column :talks, :slides_url, :string\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240901163900_add_canonical_reference_to_speaker.rb",
    "content": "class AddCanonicalReferenceToSpeaker < ActiveRecord::Migration[7.2]\n  def change\n    add_reference :speakers, :canonical, foreign_key: {to_table: :speakers}\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240902204752_add_canonical_reference_to_event.rb",
    "content": "class AddCanonicalReferenceToEvent < ActiveRecord::Migration[7.2]\n  def change\n    add_reference :events, :canonical, foreign_key: {to_table: :events}\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240908072757_create_watch_list_talks.rb",
    "content": "class CreateWatchListTalks < ActiveRecord::Migration[7.0]\n  def change\n    create_table :watch_list_talks do |t|\n      t.references :watch_list, null: false, foreign_key: true\n      t.references :talk, null: false, foreign_key: true\n\n      t.timestamps\n    end\n\n    add_index :watch_list_talks, [:watch_list_id, :talk_id], unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240908072819_create_watch_lists.rb",
    "content": "class CreateWatchLists < ActiveRecord::Migration[7.0]\n  def change\n    create_table :watch_lists do |t|\n      t.references :user, null: false\n      t.string :name, null: false\n      t.text :description\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240909194059_create_connected_accounts.rb",
    "content": "class CreateConnectedAccounts < ActiveRecord::Migration[7.2]\n  def change\n    create_table :connected_accounts do |t|\n      t.string :uid\n      t.string :provider\n      t.string :username\n      t.references :user, null: false, foreign_key: true\n      t.string :access_token\n      t.datetime :expires_at\n\n      t.timestamps\n    end\n\n    add_index :connected_accounts, [:provider, :uid], unique: true\n    add_index :connected_accounts, [:provider, :username], unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240912163015_add_name_to_user.rb",
    "content": "class AddNameToUser < ActiveRecord::Migration[7.2]\n  def change\n    add_column :users, :name, :string\n    remove_column :users, :first_name, :string\n    remove_column :users, :last_name, :string\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240912163159_encrypt_user_fields.rb",
    "content": "class EncryptUserFields < ActiveRecord::Migration[7.2]\n  def up\n    User.all.each do |user|\n      user.encrypt\n    end\n  end\n\n  def down\n    User.all.each do |user|\n      user.decrypt\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240912164120_encrypt_connected_account_field.rb",
    "content": "class EncryptConnectedAccountField < ActiveRecord::Migration[7.2]\n  def up\n    ConnectedAccount.all.each do |connected_account|\n      connected_account.encrypt\n    end\n  end\n\n  def down\n    ConnectedAccount.all.each do |connected_account|\n      connected_account.decrypt\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240914162252_add_github_handle_to_user.rb",
    "content": "class AddGitHubHandleToUser < ActiveRecord::Migration[7.2]\n  def change\n    add_column :users, :github_handle, :string\n\n    add_index :users, :github_handle, unique: true, where: \"github_handle IS NOT NULL\"\n    ConnectedAccount.all.each do |connected_account|\n      connected_account.user.update(github_handle: connected_account.username)\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240918050951_add_approved_by_to_suggestion.rb",
    "content": "class AddApprovedByToSuggestion < ActiveRecord::Migration[7.2]\n  def change\n    add_reference :suggestions, :approved_by, foreign_key: {to_table: :users}\n\n    initial_approver = User.find_by(email: \"adrienpoly@gmail.com\") || User.where(admin: true).order(:created_at).first\n\n    if initial_approver\n      Suggestion.update_all(approved_by_id: initial_approver.id)\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240918215740_add_suggestor_to_suggestions.rb",
    "content": "class AddSuggestorToSuggestions < ActiveRecord::Migration[7.2]\n  def change\n    add_reference :suggestions, :suggested_by, foreign_key: {to_table: :users}\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240919193323_add_index_on_updated_at_for_talks.rb",
    "content": "class AddIndexOnUpdatedAtForTalks < ActiveRecord::Migration[7.2]\n  def change\n    add_index :talks, :updated_at\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240920054416_add_talks_count_to_topic.rb",
    "content": "class AddTalksCountToTopic < ActiveRecord::Migration[7.2]\n  def up\n    add_column :topics, :talks_count, :integer\n\n    TalkTopic.find_each do |talk_topic|\n      talk_topic.reset_topic_counter_cache\n    end\n  end\n\n  def down\n    remove_column :topics, :talks_count\n  end\nend\n"
  },
  {
    "path": "db/migrate/20240920154237_add_talks_count_to_watch_list.rb",
    "content": "class AddTalksCountToWatchList < ActiveRecord::Migration[7.2]\n  def up\n    add_column :watch_lists, :talks_count, :integer, default: 0\n\n    WatchListTalk.find_each do |watch_list_talk|\n      watch_list_talk.reset_watch_list_counter_cache\n    end\n  end\n\n  def down\n    remove_column :watch_lists, :talks_count\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241019135118_create_talk_fts.rb",
    "content": "class CreateTalkFTS < ActiveRecord::Migration[7.2]\n  def up\n    create_virtual_table :talks_search_index, :fts5, [\n      \"title\", \"summary\", \"speaker_names\",\n      \"tokenize = porter\"\n    ]\n  end\n\n  def down\n    drop_table :talks_search_index\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241020174649_add_speakerdeck_to_speaker.rb",
    "content": "class AddSpeakerdeckToSpeaker < ActiveRecord::Migration[8.0]\n  def change\n    add_column :speakers, :speakerdeck, :string, default: \"\", null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241022012631_add_summarized_using_ai_to_talk.rb",
    "content": "class AddSummarizedUsingAiToTalk < ActiveRecord::Migration[8.0]\n  def change\n    add_column :talks, :summarized_using_ai, :boolean, default: true, null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241023093844_add_pronouns_to_speaker.rb",
    "content": "class AddPronounsToSpeaker < ActiveRecord::Migration[8.0]\n  def change\n    add_column :speakers, :pronouns_type, :string, default: \"not_specified\", null: false\n    add_column :speakers, :pronouns, :string, default: \"\", null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241023150341_remove_index_talk_topics_on_talk_id.rb",
    "content": "class RemoveIndexTalkTopicsOnTalkId < ActiveRecord::Migration[8.0]\n  def change\n    remove_index :talk_topics, :talk_id, name: \"index_talk_topics_on_talk_id\"\n    remove_index :talk_topics, :topic_id, name: \"index_talk_topics_on_topic_id\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241023154126_recreate_talk_topic_indexes.rb",
    "content": "class RecreateTalkTopicIndexes < ActiveRecord::Migration[8.0]\n  def change\n    remove_index :talk_topics, name: \"index_talk_topics_on_talk_id_and_topic_id\", if_exists: true\n    add_index :talk_topics, :talk_id, name: \"index_talk_topics_on_talk_id\"\n    add_index :talk_topics, :topic_id, name: \"index_talk_topics_on_topic_id\"\n    add_index :talk_topics, [\"topic_id\", \"talk_id\"], name: \"index_talk_topics_on_topic_id_and_talk_id\", unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241029112719_add_mastodown_bluesky_linkedin_to_speaker.rb",
    "content": "class AddMastodownBlueskyLinkedinToSpeaker < ActiveRecord::Migration[8.0]\n  def change\n    add_column :speakers, :mastodon, :string, default: \"\", null: false\n    add_column :speakers, :bsky, :string, default: \"\", null: false\n    add_column :speakers, :linkedin, :string, default: \"\", null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241031112333_add_kind_to_talk.rb",
    "content": "class AddKindToTalk < ActiveRecord::Migration[8.0]\n  def change\n    add_column :talks, :kind, :string, null: false, default: \"talk\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241101185604_add_external_player_to_talk.rb",
    "content": "class AddExternalPlayerToTalk < ActiveRecord::Migration[8.0]\n  def change\n    add_column :talks, :external_player, :boolean, null: false, default: false\n    add_column :talks, :external_player_url, :string, null: false, default: \"\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241105143943_add_website_to_events.rb",
    "content": "class AddWebsiteToEvents < ActiveRecord::Migration[8.0]\n  def change\n    add_column :events, :website, :string, default: \"\", null: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241105151601_create_watched_talks.rb",
    "content": "class CreateWatchedTalks < ActiveRecord::Migration[8.0]\n  def change\n    create_table :watched_talks do |t|\n      t.belongs_to :user, null: false\n      t.belongs_to :talk, null: false\n\n      t.timestamps\n\n      t.index [:talk_id, :user_id], unique: true\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241108215612_add_indexes_speaker_talks.rb",
    "content": "class AddIndexesSpeakerTalks < ActiveRecord::Migration[8.0]\n  def change\n    add_index :speaker_talks, :speaker_id\n    add_index :speaker_talks, :talk_id\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241122155013_add_index_on_slug_for_topics.rb",
    "content": "class AddIndexOnSlugForTopics < ActiveRecord::Migration[8.0]\n  def change\n    change_column_default :topics, :slug, from: nil, to: \"\"\n    add_index :topics, :slug\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241122163052_add_index_on_kind_for_talks.rb",
    "content": "class AddIndexOnKindForTalks < ActiveRecord::Migration[8.0]\n  def change\n    add_index :talks, :kind\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241128073415_add_bsky_metadata_to_speaker.rb",
    "content": "class AddBskyMetadataToSpeaker < ActiveRecord::Migration[8.0]\n  def change\n    add_column :speakers, :bsky_metadata, :jsonb, null: false, default: {}\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241130095835_add_parent_talk_to_talk.rb",
    "content": "class AddParentTalkToTalk < ActiveRecord::Migration[8.0]\n  def change\n    add_reference :talks, :parent_talk, foreign_key: {to_table: :talks}, null: true\n    add_column :talks, :meta_talk, :boolean, default: false, null: false\n    add_column :talks, :start_seconds, :integer, null: true\n    add_column :talks, :end_seconds, :integer, null: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241203001515_add_github_metadata_to_speaker.rb",
    "content": "class AddGitHubMetadataToSpeaker < ActiveRecord::Migration[8.0]\n  def change\n    add_column :speakers, :github_metadata, :jsonb, null: false, default: {}\n  end\nend\n"
  },
  {
    "path": "db/migrate/20241227192232_add_duration_to_talk.rb",
    "content": "class AddDurationToTalk < ActiveRecord::Migration[8.0]\n  def change\n    add_column :talks, :duration_in_seconds, :integer\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250102175230_create_speaker_full_text_search.rb",
    "content": "class CreateSpeakerFullTextSearch < ActiveRecord::Migration[8.0]\n  def up\n    create_virtual_table :speakers_search_index, :fts5, [\n      \"name\", \"github\", \"tokenize = porter\"\n    ]\n  end\n\n  def down\n    drop_table :speakers_search_index\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250104095544_create_talk_transcript.rb",
    "content": "class CreateTalkTranscript < ActiveRecord::Migration[8.0]\n  def change\n    create_table :talk_transcripts do |t|\n      t.references :talk, null: false, foreign_key: true\n      t.text :raw_transcript\n      t.text :enhanced_transcript\n      t.timestamps\n    end\n\n    # Move existing data\n    execute <<-SQL\n        INSERT INTO talk_transcripts (talk_id, raw_transcript, enhanced_transcript, created_at, updated_at)\n        SELECT id, raw_transcript, enhanced_transcript, created_at, updated_at\n        FROM talks\n    SQL\n\n    remove_column :talks, :raw_transcript\n    remove_column :talks, :enhanced_transcript\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250104230927_create_rollups.rb",
    "content": "class CreateRollups < ActiveRecord::Migration[8.0]\n  def change\n    create_table :rollups do |t|\n      t.string :name, null: false\n      t.string :interval, null: false\n      t.datetime :time, null: false\n      t.json :dimensions, null: false, default: {}\n      t.float :value\n    end\n    add_index :rollups, [:name, :interval, :time, :dimensions], unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250108221813_set_view_count_default_on_talk.rb",
    "content": "class SetViewCountDefaultOnTalk < ActiveRecord::Migration[8.0]\n  def change\n    change_column_default :talks, :view_count, 0\n    change_column_default :talks, :like_count, 0\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250115215944_add_index_video_provider_to_talk.rb",
    "content": "class AddIndexVideoProviderToTalk < ActiveRecord::Migration[8.0]\n  def change\n    add_index :talks, [:video_provider, :date]\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250124210823_add_discarded_at_speaker_talk.rb",
    "content": "class AddDiscardedAtSpeakerTalk < ActiveRecord::Migration[8.0]\n  def change\n    add_column :speaker_talks, :discarded_at, :datetime\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250127012711_add_published_at_and_announced_at_to_talk.rb",
    "content": "class AddPublishedAtAndAnnouncedAtToTalk < ActiveRecord::Migration[8.0]\n  def change\n    add_column :talks, :announced_at, :datetime, null: true\n    add_column :talks, :published_at, :datetime, null: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250128070756_add_unique_index_on_github_in_speaker.rb",
    "content": "class AddUniqueIndexOnGitHubInSpeaker < ActiveRecord::Migration[8.0]\n  def up\n    # remove duplicate with no talks\n    # Speaker.group(:github).having(\"count(*) > 1\").pluck(:github).each do |github|\n    #   Speaker.where(github: github, talks_count: 0).update_all(github: \"\")\n    # end\n\n    # some speaker with a canonical speaker still have talks attached to them let's reasign them\n    # Speaker.not_canonical.where.not(talks_count: 0).each do |speaker|\n    #   speaker.assign_canonical_speaker!(canonical_speaker: speaker.canonical)\n    # end\n\n    # fix one by one - with nil checks for safety\n    # andrew_speaker = Speaker.find_by(name: \"Andrew\")\n    # andrew_nesbitt_speaker = Speaker.find_by(name: \"Andrew Nesbitt\")\n    # andrew_speaker&.assign_canonical_speaker!(canonical_speaker: andrew_nesbitt_speaker) if andrew_nesbitt_speaker\n\n    # hasumi_speaker = Speaker.find_by(name: \"HASUMI Hitoshi\")\n    # hitoshi_speaker = Speaker.find_by(name: \"Hitoshi Hasumi\")\n    # hasumi_speaker&.assign_canonical_speaker!(canonical_speaker: hitoshi_speaker) if hitoshi_speaker\n\n    # hogelog_speaker = Speaker.find_by(name: \"hogelog\")\n    # sunao_speaker = Speaker.find_by(name: \"Sunao Hogelog Komuro\")\n    # hogelog_speaker&.assign_canonical_speaker!(canonical_speaker: sunao_speaker) if sunao_speaker\n\n    # jonatas_speaker = Speaker.find_by(name: \"Jônatas Paganini\")\n    # jonatas_davi_speaker = Speaker.find_by(name: \"Jônatas Davi Paganini\")\n    # jonatas_speaker&.assign_canonical_speaker!(canonical_speaker: jonatas_davi_speaker) if jonatas_davi_speaker\n\n    # sutou_speaker = Speaker.find_by(name: \"Sutou Kouhei\")\n    # kouhei_speaker = Speaker.find_by(name: \"Kouhei Sutou\")\n    # sutou_speaker&.assign_canonical_speaker!(canonical_speaker: kouhei_speaker) if kouhei_speaker\n\n    # maciek_speaker = Speaker.find_by(slug: \"maciek-rzasa\")\n    # maciej_speaker = Speaker.find_by(slug: \"maciej-rzasa\")\n    # maciek_speaker&.assign_canonical_speaker!(canonical_speaker: maciej_speaker) if maciej_speaker\n\n    # mario_alberto_speaker = Speaker.find_by(slug: \"mario-alberto-chavez\")\n    # mario_speaker = Speaker.find_by(slug: \"mario-chavez\")\n    # mario_alberto_speaker&.assign_canonical_speaker!(canonical_speaker: mario_speaker) if mario_speaker\n\n    # enrique_morellon_speaker = Speaker.find_by(slug: \"enrique-morellon\")\n    # enrique_mogollan_speaker = Speaker.find_by(slug: \"enrique-mogollan\")\n    # enrique_morellon_speaker&.assign_canonical_speaker!(canonical_speaker: enrique_mogollan_speaker) if enrique_mogollan_speaker\n\n    # masafumi_speaker = Speaker.find_by(slug: \"masafumi-okura\")\n    # okura_speaker = Speaker.find_by(slug: \"okura-masafumi\")\n    # masafumi_speaker&.assign_canonical_speaker!(canonical_speaker: okura_speaker) if okura_speaker\n\n    # oliver_speaker = Speaker.find_by(slug: \"oliver-lacan\")\n    # olivier_speaker = Speaker.find_by(slug: \"olivier-lacan\")\n    # oliver_speaker&.assign_canonical_speaker!(canonical_speaker: olivier_speaker) if olivier_speaker\n    add_index :speakers, :github, unique: true, where: \"github IS NOT NULL AND github != ''\"\n  end\n\n  def down\n    remove_index :speakers, :github\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250128085252_remove_github_of_speaker_with_canonical.rb",
    "content": "class RemoveGitHubOfSpeakerWithCanonical < ActiveRecord::Migration[8.0]\n  def change\n    Speaker.where.not(canonical_id: nil).update_all(github: \"\")\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250218073648_normalize_github_handle.rb",
    "content": "class NormalizeGitHubHandle < ActiveRecord::Migration[8.0]\n  def change\n    User.all.each do |u|\n      next if u.github_handle.blank?\n      u.update_column(:github_handle, u.github_handle.strip.downcase)\n    end\n\n    ConnectedAccount.all.each do |ca|\n      next if ca.username.blank?\n\n      ca.update_column(:username, ca.username.strip.downcase)\n    end\n\n    Speaker.where.not(github: [nil, \"\"]).each do |s|\n      s.update_column(:github, s.github.strip.downcase)\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250426063312_add_llm_requests.rb",
    "content": "class AddLLMRequests < ActiveRecord::Migration[8.0]\n  def change\n    create_table :llm_requests do |t|\n      t.string :request_hash, null: false, index: {unique: true}\n      t.json :raw_response, null: false\n      t.float :duration, null: false\n      t.references :resource, polymorphic: true, null: false\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250427062021_add_success_to_llm_requests.rb",
    "content": "class AddSuccessToLLMRequests < ActiveRecord::Migration[8.0]\n  def change\n    add_column :llm_requests, :success, :boolean, null: false, default: false\n    add_column :llm_requests, :task_name, :string, null: false, default: \"\"\n\n    add_index :llm_requests, :task_name\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250521011731_add_original_title_to_talks.rb",
    "content": "class AddOriginalTitleToTalks < ActiveRecord::Migration[8.0]\n  def change\n    add_column :talks, :original_title, :string, default: \"\", null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250524174213_normalize_speaker_website.rb",
    "content": "class NormalizeSpeakerWebsite < ActiveRecord::Migration[8.0]\n  def change\n    Speaker.where.not(website: [nil, \"\"]).find_in_batches do |speakers|\n      speakers.each do |speaker|\n        speaker.normalize_attribute(:website)\n        speaker.save\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250605203429_add_start_and_end_date_to_event.rb",
    "content": "class AddStartAndEndDateToEvent < ActiveRecord::Migration[8.0]\n  def change\n    add_column :events, :start_date, :date\n    add_column :events, :end_date, :date\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250609072113_remove_talk_parent_id_self.rb",
    "content": "class RemoveTalkParentIdSelf < ActiveRecord::Migration[8.0]\n  def change\n    Talk.where(\"parent_talk_id = id\").update_all(parent_talk_id: nil)\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250614131810_add_kind_to_event.rb",
    "content": "class AddKindToEvent < ActiveRecord::Migration[8.0]\n  def up\n    add_column :events, :kind, :string, default: \"event\", null: false\n    add_index :events, :kind\n  end\n\n  def down\n    remove_index :events, :kind\n    remove_column :events, :kind\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250617115359_add_date_precision_to_events.rb",
    "content": "# frozen_string_literal: true\n\nclass AddDatePrecisionToEvents < ActiveRecord::Migration[8.0]\n  def change\n    add_column :events, :date_precision, :string, null: false, default: \"day\"\n\n    Event.all.each do |event|\n      event.update(start_date: event.static_metadata.start_date, end_date: event.static_metadata.end_date)\n    end\n\n    Event.find_in_batches.each do |events|\n      events.each do |event|\n        if event.static_metadata.meetup?\n          event.update!(kind: \"meetup\")\n        elsif event.static_metadata.conference?\n          event.update!(kind: \"conference\")\n        else\n          event.update!(kind: \"event\")\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250618000304_add_call_for_papers_to_events.rb",
    "content": "class AddCallForPapersToEvents < ActiveRecord::Migration[8.0]\n  def change\n    add_column :events, :cfp_link, :string\n    add_column :events, :cfp_open_date, :date\n    add_column :events, :cfp_close_date, :date\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250719180249_create_sponsors.rb",
    "content": "class CreateSponsors < ActiveRecord::Migration[8.0]\n  def change\n    create_table :sponsors do |t|\n      t.string :name\n      t.string :website\n      t.string :logo_url\n      t.text :description\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250719190411_add_slug_to_sponsors.rb",
    "content": "class AddSlugToSponsors < ActiveRecord::Migration[8.0]\n  def change\n    add_column :sponsors, :slug, :string\n    add_index :sponsors, :slug\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250719200918_create_event_sponsors.rb",
    "content": "class CreateEventSponsors < ActiveRecord::Migration[8.0]\n  def change\n    create_table :event_sponsors do |t|\n      t.references :event, null: false, foreign_key: true\n      t.references :sponsor, null: false, foreign_key: true\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250719204509_add_banner_url_to_sponsors.rb",
    "content": "class AddBannerUrlToSponsors < ActiveRecord::Migration[8.0]\n  def change\n    add_column :sponsors, :banner_url, :string\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250719205313_add_main_location_to_sponsors.rb",
    "content": "class AddMainLocationToSponsors < ActiveRecord::Migration[8.0]\n  def change\n    add_column :sponsors, :main_location, :string\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250719205756_remove_url_fields_from_sponsors.rb",
    "content": "class RemoveUrlFieldsFromSponsors < ActiveRecord::Migration[8.0]\n  def change\n    remove_column :sponsors, :logo_url, :string\n    remove_column :sponsors, :banner_url, :string\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250719225634_add_tier_to_event_sponsors.rb",
    "content": "class AddTierToEventSponsors < ActiveRecord::Migration[8.0]\n  def change\n    add_column :event_sponsors, :tier, :string\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250719231642_add_logo_url_to_sponsors.rb",
    "content": "class AddLogoUrlToSponsors < ActiveRecord::Migration[8.0]\n  def change\n    add_column :sponsors, :logo_url, :string\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250808095915_add_logo_urls_to_sponsors.rb",
    "content": "class AddLogoUrlsToSponsors < ActiveRecord::Migration[8.0]\n  def change\n    add_column :sponsors, :logo_urls, :json, default: []\n    add_column :sponsors, :domain, :string\n    add_column :sponsors, :logo_background, :string, default: \"white\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250808192916_clean_sponsor_website_urls.rb",
    "content": "class CleanSponsorWebsiteUrls < ActiveRecord::Migration[8.0]\n  def change\n    say_with_time \"Normalizing existing sponsor website URLs\" do\n      Sponsor.find_each do |sponsor|\n        if sponsor.website.present?\n          normalized = UrlNormalizable.normalize_url_string(sponsor.website)\n          if normalized != sponsor.website\n            sponsor.update_column(:website, normalized)\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250809194302_add_badge_to_event_sponsors.rb",
    "content": "class AddBadgeToEventSponsors < ActiveRecord::Migration[8.0]\n  def change\n    add_column :event_sponsors, :badge, :string\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250813211012_decrypt_user_name.rb",
    "content": "class DecryptUserName < ActiveRecord::Migration[8.0]\n  def up\n    User.in_batches(of: 1000) do |batch|\n      batch.each do |u|\n        plain = u.name\n        ActiveRecord::Encryption.without_encryption do\n          u.update_columns(name: plain)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250814214127_add_speaker_attributes_to_users.rb",
    "content": "class AddSpeakerAttributesToUsers < ActiveRecord::Migration[8.0]\n  def change\n    add_column :users, :bio, :text, default: \"\", null: false\n    add_column :users, :website, :string, default: \"\", null: false\n    add_column :users, :slug, :string, default: \"\", null: false\n    add_column :users, :twitter, :string, default: \"\", null: false\n    add_column :users, :bsky, :string, default: \"\", null: false\n    add_column :users, :mastodon, :string, default: \"\", null: false\n    add_column :users, :linkedin, :string, default: \"\", null: false\n    add_column :users, :speakerdeck, :string, default: \"\", null: false\n    add_column :users, :pronouns, :string, default: \"\", null: false\n    add_column :users, :pronouns_type, :string, default: \"not_specified\", null: false\n    add_column :users, :talks_count, :integer, default: 0, null: false\n    add_column :users, :canonical_id, :integer\n    add_column :users, :bsky_metadata, :json, default: {}, null: false\n    add_column :users, :github_metadata, :json, default: {}, null: false\n\n    # Add indexes similar to speakers table\n    add_index :users, :slug, unique: true, where: \"slug IS NOT NULL AND slug != ''\"\n    add_index :users, :canonical_id\n    add_index :users, :name, where: \"name IS NOT NULL AND name != ''\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250814214146_create_user_talks.rb",
    "content": "class CreateUserTalks < ActiveRecord::Migration[8.0]\n  def change\n    create_table :user_talks do |t|\n      t.references :user, null: false, foreign_key: true\n      t.references :talk, null: false, foreign_key: true\n      t.datetime :discarded_at\n\n      t.timestamps\n    end\n\n    add_index :user_talks, [:user_id, :talk_id], unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250814214412_create_users_search_index.rb",
    "content": "class CreateUsersSearchIndex < ActiveRecord::Migration[8.0]\n  def change\n    # Create the virtual FTS5 table for users\n    create_virtual_table \"users_search_index\", \"fts5\", [\"name\", \"github_handle\", \"tokenize = porter\"]\n\n    # up_only do\n    #   User.reindex_all\n    # end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250817060410_set_users_email_null_true.rb",
    "content": "class SetUsersEmailNullTrue < ActiveRecord::Migration[8.1]\n  def change\n    change_column_null :users, :email, true\n    change_column_null :users, :password_digest, true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250817223427_update_user_indexes.rb",
    "content": "class UpdateUserIndexes < ActiveRecord::Migration[8.1]\n  def change\n    remove_index :users, :github_handle, name: :index_users_on_github_handle\n    remove_index :users, :email, name: :index_users_on_email\n    remove_index :users, :name, name: :index_users_on_name\n    remove_index :users, :slug, name: :index_users_on_slug\n\n    add_index :users, :github_handle, unique: true, where: \"github_handle IS NOT NULL AND github_handle != ''\"\n    add_index :users, :email\n    add_index :users, :name\n    add_index :users, :slug, unique: true, where: \"slug IS NOT NULL AND slug != ''\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250819022348_create_cfps.rb",
    "content": "class CreateCfps < ActiveRecord::Migration[8.1]\n  def change\n    create_table :cfps do |t|\n      t.string :name\n      t.string :link\n      t.date :open_date\n      t.date :close_date\n      t.references :event, null: false, foreign_key: true\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250820183955_add_progress_seconds_to_watched_talks.rb",
    "content": "class AddProgressSecondsToWatchedTalks < ActiveRecord::Migration[8.1]\n  def change\n    add_column :watched_talks, :progress_seconds, :integer, default: 0, null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250820225005_add_watched_talks_count_to_users.rb",
    "content": "class AddWatchedTalksCountToUsers < ActiveRecord::Migration[8.1]\n  def change\n    add_column :users, :watched_talks_count, :integer, default: 0, null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250822175423_add_unique_index_to_event_sponsors.rb",
    "content": "class AddUniqueIndexToEventSponsors < ActiveRecord::Migration[8.1]\n  def up\n    add_index :event_sponsors, [:event_id, :sponsor_id, :tier],\n      unique: true,\n      name: \"index_event_sponsors_on_event_sponsor_tier_unique\"\n  end\n\n  def down\n    remove_index :event_sponsors, name: \"index_event_sponsors_on_event_sponsor_tier_unique\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250823020826_remove_cfp_fields_from_events.rb",
    "content": "class RemoveCFPFieldsFromEvents < ActiveRecord::Migration[8.1]\n  def change\n    remove_column :events, :cfp_link, :string\n    remove_column :events, :cfp_open_date, :date\n    remove_column :events, :cfp_close_date, :date\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250901185702_update_suggestions_suggestable.rb",
    "content": "class UpdateSuggestionsSuggestable < ActiveRecord::Migration[8.1]\n  def change\n    Suggestion.where(suggestable_type: \"Speaker\").each do |suggestion|\n      speaker = suggestion.suggestable\n      user = User.find_by(github_handle: speaker.github) || User.find_by(slug: speaker.slug) || User.find_by(name: speaker.name)\n      suggestion.update!(suggestable: user)\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250903125458_create_event_participations.rb",
    "content": "class CreateEventParticipations < ActiveRecord::Migration[8.1]\n  def change\n    create_table :event_participations do |t|\n      t.references :user, null: false, foreign_key: true\n      t.references :event, null: false, foreign_key: true\n      t.string :attended_as, null: false\n\n      t.timestamps\n    end\n\n    add_index :event_participations, [:user_id, :event_id, :attended_as], unique: true\n    add_index :event_participations, :attended_as\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250920194438_add_country_code_to_event.rb",
    "content": "class AddCountryCodeToEvent < ActiveRecord::Migration[8.1]\n  def up\n    Event.find_each.each do |event|\n      event.update_column(:country_code, event.static_metadata&.country&.alpha2)\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20250930165602_add_location_to_user.rb",
    "content": "class AddLocationToUser < ActiveRecord::Migration[8.1]\n  def change\n    add_column :users, :location, :string, default: \"\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251010092526_create_event_involvements.rb",
    "content": "class CreateEventInvolvements < ActiveRecord::Migration[8.1]\n  def change\n    create_table :event_involvements do |t|\n      t.references :involvementable, polymorphic: true, null: false\n      t.references :event, null: false, foreign_key: true\n      t.string :role, null: false\n      t.integer :position, default: 0\n\n      t.timestamps\n    end\n\n    add_index :event_involvements, [:involvementable_type, :involvementable_id, :event_id, :role], unique: true, name: \"idx_involvements_on_involvementable_and_event_and_role\"\n    add_index :event_involvements, :role\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251012114916_create_contributors.rb",
    "content": "class CreateContributors < ActiveRecord::Migration[8.1]\n  def change\n    create_table :contributors do |t|\n      t.string :login, null: false\n      t.string :name\n      t.string :avatar_url\n      t.string :html_url\n      t.references :user, foreign_key: true\n\n      t.timestamps\n    end\n\n    add_index :contributors, :login, unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251019071129_add_case_insensitive_github_handle_index_to_users.rb",
    "content": "class AddCaseInsensitiveGitHubHandleIndexToUsers < ActiveRecord::Migration[8.1]\n  def up\n    User.transaction do\n      User.find_by(github_handle: \"bodacious\")&.assign_canonical_user!(canonical_user: User.find_by(github_handle: \"Bodacious\")) if User.find_by(github_handle: \"Bodacious\")\n      User.find_by(github_handle: \"joschkaschulz\")&.assign_canonical_user!(canonical_user: User.find_by(github_handle: \"JoschkaSchulz\")) if User.find_by(github_handle: \"JoschkaSchulz\")\n      User.find_by(github_handle: \"kyfast\")&.assign_canonical_user!(canonical_user: User.find_by(github_handle: \"KyFaSt\")) if User.find_by(github_handle: \"KyFaSt\")\n      User.find_by(github_handle: \"nabeelahy\")&.assign_canonical_user!(canonical_user: User.find_by(github_handle: \"NabeelahY\")) if User.find_by(github_handle: \"NabeelahY\")\n      User.find_by(github_handle: \"ryanbrushett\")&.assign_canonical_user!(canonical_user: User.find_by(github_handle: \"RyanBrushett\")) if User.find_by(github_handle: \"RyanBrushett\")\n      User.find_by(github_handle: \"thomascountz\")&.assign_canonical_user!(canonical_user: User.find_by(github_handle: \"Thomascountz\")) if User.find_by(github_handle: \"Thomascountz\")\n      User.find_by(github_handle: \"tripple-a\")&.assign_canonical_user!(canonical_user: User.find_by(github_handle: \"Tripple-A\")) if User.find_by(github_handle: \"Tripple-A\")\n      User.find_by(github_handle: \"winslett\")&.assign_canonical_user!(canonical_user: User.find_by(github_handle: \"Winslett\")) if User.find_by(github_handle: \"Winslett\")\n    end\n    # Now add the case-insensitive unique index\n    add_index :users, \"lower(github_handle)\", name: \"index_users_on_lower_github_handle\",\n      unique: true, where: \"github_handle IS NOT NULL AND github_handle != ''\"\n    remove_index :users, name: \"index_users_on_github_handle\"\n  end\n\n  def down\n    remove_index :users, name: \"index_users_on_lower_github_handle\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251019212653_remove_badge_awards_table.rb",
    "content": "class RemoveBadgeAwardsTable < ActiveRecord::Migration[8.1]\n  def change\n    # this was added in an unmerged PR, so we need to remove it\n    drop_table :badge_awards, if_exists: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251028143012_create_aliases.rb",
    "content": "class CreateAliases < ActiveRecord::Migration[8.1]\n  def change\n    create_table :aliases do |t|\n      t.references :aliasable, polymorphic: true, null: false\n      t.string :name, null: false\n      t.string :slug, null: false\n\n      t.timestamps\n    end\n\n    add_index :aliases, [:aliasable_type, :name], unique: true, name: \"index_aliases_on_aliasable_type_and_name\"\n    add_index :aliases, [:aliasable_type, :slug], unique: true, name: \"index_aliases_on_aliasable_type_and_slug\"\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251028143916_add_marked_for_deletion_to_users.rb",
    "content": "class AddMarkedForDeletionToUsers < ActiveRecord::Migration[8.1]\n  def change\n    add_column :users, :marked_for_deletion, :boolean, default: false, null: false\n    add_index :users, :marked_for_deletion\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251028143917_migrate_canonical_users_to_aliases.rb",
    "content": "class MigrateCanonicalUsersToAliases < ActiveRecord::Migration[8.1]\n  def up\n    User.where.not(canonical_id: nil).find_each do |user|\n      next if user.name.blank?\n      next unless user.canonical.present?\n      next if user.slug.blank?\n\n      Alias.find_or_create_by!(\n        aliasable_type: \"User\",\n        aliasable_id: user.canonical_id,\n        name: user.name,\n        slug: user.slug\n      )\n\n      user.update_column(:marked_for_deletion, true)\n\n      puts \"Created alias '#{user.name}' (slug: #{user.slug}) for canonical user #{user.canonical.name}\"\n    end\n  end\n\n  def down\n    User.where(marked_for_deletion: true).update_all(marked_for_deletion: false)\n    Alias.where(aliasable_type: \"User\").delete_all\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251029032709_rename_organisation_to_event_series.rb",
    "content": "class RenameOrganisationToEventSeries < ActiveRecord::Migration[8.1]\n  def change\n    rename_table :organisations, :event_series\n    rename_column :events, :organisation_id, :event_series_id\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251126171800_rename_sponsor_to_organization.rb",
    "content": "class RenameSponsorToOrganization < ActiveRecord::Migration[8.1]\n  def change\n    rename_table :sponsors, :organizations\n\n    add_column :organizations, :kind, :integer, default: 0, null: false\n    add_index :organizations, :kind\n    rename_index :organizations, :index_sponsors_on_slug, :index_organizations_on_slug\n\n    rename_column :event_sponsors, :sponsor_id, :organization_id\n    rename_index :event_sponsors, :index_event_sponsors_on_sponsor_id, :index_event_sponsors_on_organization_id\n    remove_index :event_sponsors, name: :index_event_sponsors_on_event_sponsor_tier_unique\n\n    add_index :event_sponsors, [:event_id, :organization_id, :tier], unique: true, name: :index_event_sponsors_on_event_organization_tier_unique\n\n    execute <<-SQL\n      UPDATE aliases\n      SET aliasable_type = 'Organization'\n      WHERE aliasable_type = 'Sponsor'\n    SQL\n\n    execute <<-SQL\n      UPDATE event_involvements\n      SET involvementable_type = 'Organization'\n      WHERE involvementable_type = 'Sponsor'\n    SQL\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251126171948_rename_event_sponsor_to_sponsor.rb",
    "content": "class RenameEventSponsorToSponsor < ActiveRecord::Migration[8.1]\n  def change\n    rename_table :event_sponsors, :sponsors\n\n    rename_index :sponsors, :index_event_sponsors_on_event_id, :index_sponsors_on_event_id\n    rename_index :sponsors, :index_event_sponsors_on_organization_id, :index_sponsors_on_organization_id\n    rename_index :sponsors, :index_event_sponsors_on_event_organization_tier_unique, :index_sponsors_on_event_organization_tier_unique\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251126203734_add_coordinates_to_events.rb",
    "content": "class AddCoordinatesToEvents < ActiveRecord::Migration[8.1]\n  def change\n    add_column :events, :longitude, :decimal, precision: 10, scale: 6\n    add_column :events, :latitude, :decimal, precision: 10, scale: 6\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251201143109_add_event_names_to_talks_search_index.rb",
    "content": "class AddEventNamesToTalksSearchIndex < ActiveRecord::Migration[8.1]\n  def up\n    drop_table :talks_search_index\n\n    create_virtual_table :talks_search_index, :fts5, [\n      \"title\", \"summary\", \"speaker_names\", \"event_names\",\n      \"tokenize = porter\"\n    ]\n\n    # Talk.reindex_all\n  end\n\n  def down\n    drop_table :talks_search_index\n\n    create_virtual_table :talks_search_index, :fts5, [\n      \"title\", \"summary\", \"speaker_names\",\n      \"tokenize = porter\"\n    ]\n\n    # Talk.reindex_all\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251201144052_change_slug_to_optional_in_aliases.rb",
    "content": "class ChangeSlugToOptionalInAliases < ActiveRecord::Migration[8.1]\n  def change\n    change_column_null :aliases, :slug, true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251203110611_change_youtube_channel_id_nullable_on_event_series.rb",
    "content": "class ChangeYouTubeChannelIdNullableOnEventSeries < ActiveRecord::Migration[8.1]\n  def change\n    change_column_null :event_series, :youtube_channel_id, true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251203110659_change_youtube_channel_name_nullable_on_event_series.rb",
    "content": "class ChangeYouTubeChannelNameNullableOnEventSeries < ActiveRecord::Migration[8.1]\n  def change\n    change_column_null :event_series, :youtube_channel_name, true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251204145850_add_static_id_to_talks.rb",
    "content": "class AddStaticIdToTalks < ActiveRecord::Migration[8.1]\n  def change\n    add_column :talks, :static_id, :string\n    add_index :talks, :static_id, unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251204195048_change_static_id_null_constraint_on_talks.rb",
    "content": "class ChangeStaticIdNullConstraintOnTalks < ActiveRecord::Migration[8.1]\n  def change\n    change_column_null :talks, :static_id, false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20251206194409_add_additional_resources_to_talks.rb",
    "content": "class AddAdditionalResourcesToTalks < ActiveRecord::Migration[8.1]\n  def change\n    add_column :talks, :additional_resources, :json, default: [], null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260101090225_add_wrapped_public_to_users.rb",
    "content": "class AddWrappedPublicToUsers < ActiveRecord::Migration[8.1]\n  def change\n    add_column :users, :wrapped_public, :boolean, default: false, null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260101125732_create_active_storage_tables.active_storage.rb",
    "content": "# This migration comes from active_storage (originally 20170806125915)\nclass CreateActiveStorageTables < ActiveRecord::Migration[7.0]\n  def change\n    # Use Active Record's configured type for primary and foreign keys\n    primary_key_type, foreign_key_type = primary_and_foreign_key_types\n\n    create_table :active_storage_blobs, id: primary_key_type do |t|\n      t.string :key, null: false\n      t.string :filename, null: false\n      t.string :content_type\n      t.text :metadata\n      t.string :service_name, null: false\n      t.bigint :byte_size, null: false\n      t.string :checksum\n\n      if connection.supports_datetime_with_precision?\n        t.datetime :created_at, precision: 6, null: false\n      else\n        t.datetime :created_at, null: false\n      end\n\n      t.index [:key], unique: true\n    end\n\n    create_table :active_storage_attachments, id: primary_key_type do |t|\n      t.string :name, null: false\n      t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type\n      t.references :blob, null: false, type: foreign_key_type\n\n      if connection.supports_datetime_with_precision?\n        t.datetime :created_at, precision: 6, null: false\n      else\n        t.datetime :created_at, null: false\n      end\n\n      t.index [:record_type, :record_id, :name, :blob_id], name: :index_active_storage_attachments_uniqueness, unique: true\n      t.foreign_key :active_storage_blobs, column: :blob_id\n    end\n\n    create_table :active_storage_variant_records, id: primary_key_type do |t|\n      t.belongs_to :blob, null: false, index: false, type: foreign_key_type\n      t.string :variation_digest, null: false\n\n      t.index [:blob_id, :variation_digest], name: :index_active_storage_variant_records_uniqueness, unique: true\n      t.foreign_key :active_storage_blobs, column: :blob_id\n    end\n  end\n\n  private\n\n  def primary_and_foreign_key_types\n    config = Rails.configuration.generators\n    setting = config.options[config.orm][:primary_key_type]\n    primary_key_type = setting || :primary_key\n    foreign_key_type = setting || :bigint\n    [primary_key_type, foreign_key_type]\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260103114901_add_feedback_to_watched_talks.rb",
    "content": "class AddFeedbackToWatchedTalks < ActiveRecord::Migration[8.1]\n  def change\n    add_column :watched_talks, :watched_on, :string\n    add_column :watched_talks, :watched_at, :datetime\n    add_column :watched_talks, :feedback, :json, default: {}\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260103122047_add_feedback_shared_at_to_watched_talks.rb",
    "content": "class AddFeedbackSharedAtToWatchedTalks < ActiveRecord::Migration[8.1]\n  def change\n    add_column :watched_talks, :feedback_shared_at, :datetime\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260103125129_backfill_watched_at_on_watched_talks.rb",
    "content": "class BackfillWatchedAtOnWatchedTalks < ActiveRecord::Migration[8.1]\n  def up\n    execute <<-SQL\n      UPDATE watched_talks\n      SET watched_at = created_at\n      WHERE watched_at IS NULL\n    SQL\n\n    change_column_null :watched_talks, :watched_at, false\n  end\n\n  def down\n    change_column_null :watched_talks, :watched_at, true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260103130348_add_watched_to_watched_talks.rb",
    "content": "class AddWatchedToWatchedTalks < ActiveRecord::Migration[8.1]\n  def up\n    add_column :watched_talks, :watched, :boolean, default: false\n\n    execute <<-SQL\n      UPDATE watched_talks\n      SET watched = true\n    SQL\n\n    change_column_null :watched_talks, :watched, false\n  end\n\n  def down\n    remove_column :watched_talks, :watched\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260103134407_add_feedback_enabled_to_users.rb",
    "content": "class AddFeedbackEnabledToUsers < ActiveRecord::Migration[8.1]\n  def change\n    add_column :users, :feedback_enabled, :boolean, default: true, null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260103210603_add_settings_to_users.rb",
    "content": "class AddSettingsToUsers < ActiveRecord::Migration[8.2]\n  def up\n    add_column :users, :settings, :json, null: false, default: {}\n\n    execute <<-SQL\n      UPDATE users\n      SET settings = json_object(\n        'feedback_enabled', feedback_enabled,\n        'wrapped_public', wrapped_public\n      )\n    SQL\n\n    remove_column :users, :feedback_enabled\n    remove_column :users, :wrapped_public\n  end\n\n  def down\n    add_column :users, :feedback_enabled, :boolean, null: false, default: true\n    add_column :users, :wrapped_public, :boolean, null: false, default: false\n\n    execute <<-SQL\n      UPDATE users\n      SET feedback_enabled = COALESCE(json_extract(settings, '$.feedback_enabled'), 1),\n          wrapped_public = COALESCE(json_extract(settings, '$.wrapped_public'), 0)\n    SQL\n\n    remove_column :users, :settings\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260103232220_create_topic_gems.rb",
    "content": "class CreateTopicGems < ActiveRecord::Migration[8.2]\n  def change\n    create_table :topic_gems do |t|\n      t.references :topic, null: false, foreign_key: true\n      t.string :gem_name, null: false\n\n      t.timestamps\n    end\n\n    add_index :topic_gems, [:topic_id, :gem_name], unique: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260104181518_create_favorite_users.rb",
    "content": "class CreateFavoriteUsers < ActiveRecord::Migration[8.2]\n  def change\n    create_table :favorite_users do |t|\n      t.references :user, null: false, foreign_key: true\n      t.references :favorite_user, null: false, foreign_key: {to_table: :users}\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260105100000_add_indexes_to_ahoy_visits_for_cleanup.rb",
    "content": "class AddIndexesToAhoyVisitsForCleanup < ActiveRecord::Migration[8.0]\n  def change\n    # Composite index for the suspicious IP query\n    # Covers: WHERE started_at > X GROUP BY ip\n    add_index :ahoy_visits, [:started_at, :ip],\n      name: \"index_ahoy_visits_on_started_at_and_ip\",\n      if_not_exists: true\n\n    # Index on ip for the batch deletion queries\n    add_index :ahoy_visits, :ip,\n      name: \"index_ahoy_visits_on_ip\",\n      if_not_exists: true\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260105120000_add_video_provider_to_talks_search_index.rb",
    "content": "class AddVideoProviderToTalksSearchIndex < ActiveRecord::Migration[8.0]\n  def up\n    # Drop and recreate FTS table with video_provider as unindexed column\n    # Unindexed columns are stored but not searchable - perfect for filtering\n    drop_table :talks_search_index\n\n    create_virtual_table :talks_search_index, :fts5, [\n      \"title\",\n      \"summary\",\n      \"speaker_names\",\n      \"event_names\",\n      \"video_provider UNINDEXED\", # For filtering, not searching\n      \"tokenize = porter\"\n    ]\n\n    # Reindex all talks (this will be slow but only runs once)\n    Talk.includes(:speakers, :event).find_each do |talk|\n      execute <<~SQL.squish\n        INSERT INTO talks_search_index (rowid, title, summary, speaker_names, event_names, video_provider)\n        VALUES (\n          #{talk.id},\n          #{connection.quote(talk.title)},\n          #{connection.quote(talk.summary.to_s)},\n          #{connection.quote(talk.speaker_names)},\n          #{connection.quote(talk.event_names)},\n          #{connection.quote(talk.video_provider)}\n        )\n      SQL\n    end\n  end\n\n  def down\n    drop_table :talks_search_index\n\n    create_virtual_table :talks_search_index, :fts5, [\n      \"title\",\n      \"summary\",\n      \"speaker_names\",\n      \"event_names\",\n      \"tokenize = porter\"\n    ]\n\n    # Reindex all talks\n    Talk.includes(:speakers, :event).find_each do |talk|\n      execute <<~SQL.squish\n        INSERT INTO talks_search_index (rowid, title, summary, speaker_names, event_names)\n        VALUES (\n          #{talk.id},\n          #{connection.quote(talk.title)},\n          #{connection.quote(talk.summary.to_s)},\n          #{connection.quote(talk.speaker_names)},\n          #{connection.quote(talk.event_names)}\n        )\n      SQL\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260106092124_add_geocoding_to_users.rb",
    "content": "class AddGeocodingToUsers < ActiveRecord::Migration[8.2]\n  def change\n    add_column :users, :city, :string\n    add_column :users, :state, :string\n    add_column :users, :country_code, :string\n    add_column :users, :latitude, :decimal, precision: 10, scale: 6\n    add_column :users, :longitude, :decimal, precision: 10, scale: 6\n    add_column :users, :geocode_metadata, :json, default: {}, null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260106121436_add_state_to_events.rb",
    "content": "class AddStateToEvents < ActiveRecord::Migration[8.2]\n  def change\n    add_column :events, :state, :string\n    add_index :events, [:country_code, :state]\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260106121459_create_featured_cities.rb",
    "content": "class CreateFeaturedCities < ActiveRecord::Migration[8.2]\n  def change\n    create_table :featured_cities do |t|\n      t.string :name, null: false\n      t.string :slug, null: false\n      t.string :city, null: false\n      t.string :state_code\n      t.string :country_code, null: false\n      t.decimal :latitude, precision: 10, scale: 6\n      t.decimal :longitude, precision: 10, scale: 6\n\n      t.timestamps\n    end\n    add_index :featured_cities, :slug, unique: true\n    add_index :featured_cities, [:country_code, :city]\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260106135053_create_geocode_results.rb",
    "content": "class CreateGeocodeResults < ActiveRecord::Migration[8.2]\n  def change\n    create_table :geocode_results do |t|\n      t.string :query, null: false, index: {unique: true}\n      t.text :response_body, null: false\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260106141308_add_location_to_events.rb",
    "content": "class AddLocationToEvents < ActiveRecord::Migration[8.2]\n  def change\n    add_column :events, :location, :string\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260106232656_add_marked_suspicious_at_to_users.rb",
    "content": "class AddMarkedSuspiciousAtToUsers < ActiveRecord::Migration[8.2]\n  def change\n    add_column :users, :suspicion_marked_at, :datetime\n    add_column :users, :suspicion_cleared_at, :datetime\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260109095858_add_geocode_metadata_to_events.rb",
    "content": "class AddGeocodeMetadataToEvents < ActiveRecord::Migration[8.2]\n  def change\n    add_column :events, :geocode_metadata, :json, default: {}, null: false\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260109152525_change_aliases_slug_index.rb",
    "content": "class ChangeAliasesSlugIndex < ActiveRecord::Migration[8.2]\n  def change\n    remove_index :aliases, name: :index_aliases_on_aliasable_type_and_slug\n    add_index :aliases, :slug\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260110193214_rename_featured_cities_to_cities.rb",
    "content": "class RenameFeaturedCitiesToCities < ActiveRecord::Migration[8.2]\n  def change\n    rename_table :featured_cities, :cities\n\n    add_column :cities, :featured, :boolean, default: false, null: false\n    add_column :cities, :geocode_metadata, :json, default: {}, null: false\n\n    reversible do |dir|\n      dir.up do\n        execute \"UPDATE cities SET featured = true\"\n      end\n    end\n\n    add_index :cities, :featured\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260110194925_rename_state_to_state_code_on_events_and_users.rb",
    "content": "class RenameStateToStateCodeOnEventsAndUsers < ActiveRecord::Migration[8.2]\n  def change\n    rename_column :events, :state, :state_code\n    rename_column :users, :state, :state_code\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260110201634_remove_city_column_from_cities.rb",
    "content": "class RemoveCityColumnFromCities < ActiveRecord::Migration[8.2]\n  def change\n    remove_index :cities, [:country_code, :city]\n    remove_column :cities, :city, :string\n    add_index :cities, [:name, :country_code, :state_code]\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260112065507_add_youtube_thumbnail_checked_at_to_talks.rb",
    "content": "class AddYouTubeThumbnailCheckedAtToTalks < ActiveRecord::Migration[8.2]\n  def change\n    add_column :talks, :youtube_thumbnail_checked_at, :datetime\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260112071922_add_video_availability_fields_to_talks.rb",
    "content": "class AddVideoAvailabilityFieldsToTalks < ActiveRecord::Migration[8.2]\n  def change\n    add_column :talks, :video_unavailable_at, :datetime\n    add_column :talks, :video_availability_checked_at, :datetime\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260301182003_add_notes_to_favorite_user.rb",
    "content": "class AddNotesToFavoriteUser < ActiveRecord::Migration[8.2]\n  def change\n    add_column :favorite_users, :notes, :text\n  end\nend\n"
  },
  {
    "path": "db/migrate/20260306110802_add_level_to_sponsors.rb",
    "content": "class AddLevelToSponsors < ActiveRecord::Migration[8.2]\n  def change\n    add_column :sponsors, :level, :integer\n  end\nend\n"
  },
  {
    "path": "db/queue_migrate/20240516090838_create_solid_queue_tables.solid_queue.rb",
    "content": "# This migration comes from solid_queue (originally 20231211200639)\nclass CreateSolidQueueTables < ActiveRecord::Migration[7.0]\n  def change\n    create_table :solid_queue_jobs do |t|\n      t.string :queue_name, null: false\n      t.string :class_name, null: false, index: true\n      t.text :arguments\n      t.integer :priority, default: 0, null: false\n      t.string :active_job_id, index: true\n      t.datetime :scheduled_at\n      t.datetime :finished_at, index: true\n      t.string :concurrency_key\n\n      t.timestamps\n\n      t.index [:queue_name, :finished_at], name: \"index_solid_queue_jobs_for_filtering\"\n      t.index [:scheduled_at, :finished_at], name: \"index_solid_queue_jobs_for_alerting\"\n    end\n\n    create_table :solid_queue_scheduled_executions do |t|\n      t.references :job, index: {unique: true}, null: false\n      t.string :queue_name, null: false\n      t.integer :priority, default: 0, null: false\n      t.datetime :scheduled_at, null: false\n\n      t.datetime :created_at, null: false\n\n      t.index [:scheduled_at, :priority, :job_id], name: \"index_solid_queue_dispatch_all\"\n    end\n\n    create_table :solid_queue_ready_executions do |t|\n      t.references :job, index: {unique: true}, null: false\n      t.string :queue_name, null: false\n      t.integer :priority, default: 0, null: false\n\n      t.datetime :created_at, null: false\n\n      t.index [:priority, :job_id], name: \"index_solid_queue_poll_all\"\n      t.index [:queue_name, :priority, :job_id], name: \"index_solid_queue_poll_by_queue\"\n    end\n\n    create_table :solid_queue_claimed_executions do |t|\n      t.references :job, index: {unique: true}, null: false\n      t.bigint :process_id\n      t.datetime :created_at, null: false\n\n      t.index [:process_id, :job_id]\n    end\n\n    create_table :solid_queue_blocked_executions do |t|\n      t.references :job, index: {unique: true}, null: false\n      t.string :queue_name, null: false\n      t.integer :priority, default: 0, null: false\n      t.string :concurrency_key, null: false\n      t.datetime :expires_at, null: false\n\n      t.datetime :created_at, null: false\n\n      t.index [:expires_at, :concurrency_key], name: \"index_solid_queue_blocked_executions_for_maintenance\"\n    end\n\n    create_table :solid_queue_failed_executions do |t|\n      t.references :job, index: {unique: true}, null: false\n      t.text :error\n      t.datetime :created_at, null: false\n    end\n\n    create_table :solid_queue_pauses do |t|\n      t.string :queue_name, null: false, index: {unique: true}\n      t.datetime :created_at, null: false\n    end\n\n    create_table :solid_queue_processes do |t|\n      t.string :kind, null: false\n      t.datetime :last_heartbeat_at, null: false, index: true\n      t.bigint :supervisor_id, index: true\n\n      t.integer :pid, null: false\n      t.string :hostname\n      t.text :metadata\n\n      t.datetime :created_at, null: false\n    end\n\n    create_table :solid_queue_semaphores do |t|\n      t.string :key, null: false, index: {unique: true}\n      t.integer :value, default: 1, null: false\n      t.datetime :expires_at, null: false, index: true\n\n      t.timestamps\n\n      t.index [:key, :value], name: \"index_solid_queue_semaphores_on_key_and_value\"\n    end\n\n    add_foreign_key :solid_queue_blocked_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade\n    add_foreign_key :solid_queue_claimed_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade\n    add_foreign_key :solid_queue_failed_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade\n    add_foreign_key :solid_queue_ready_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade\n    add_foreign_key :solid_queue_scheduled_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade\n  end\nend\n"
  },
  {
    "path": "db/queue_migrate/20240516090839_add_missing_index_to_blocked_executions.solid_queue.rb",
    "content": "# This migration comes from solid_queue (originally 20240110143450)\nclass AddMissingIndexToBlockedExecutions < ActiveRecord::Migration[7.1]\n  def change\n    add_index :solid_queue_blocked_executions, [:concurrency_key, :priority, :job_id], name: \"index_solid_queue_blocked_executions_for_release\"\n  end\nend\n"
  },
  {
    "path": "db/queue_migrate/20240516090840_create_recurring_executions.solid_queue.rb",
    "content": "# This migration comes from solid_queue (originally 20240218110712)\nclass CreateRecurringExecutions < ActiveRecord::Migration[7.1]\n  def change\n    create_table :solid_queue_recurring_executions do |t|\n      t.references :job, index: {unique: true}, null: false\n      t.string :task_key, null: false\n      t.datetime :run_at, null: false\n      t.datetime :created_at, null: false\n\n      t.index [:task_key, :run_at], unique: true\n    end\n\n    add_foreign_key :solid_queue_recurring_executions, :solid_queue_jobs, column: :job_id, on_delete: :cascade\n  end\nend\n"
  },
  {
    "path": "db/queue_migrate/20240814230055_create_recurring_tasks.solid_queue.rb",
    "content": "# This migration comes from solid_queue (originally 20240719134516)\nclass CreateRecurringTasks < ActiveRecord::Migration[7.1]\n  def change\n    create_table :solid_queue_recurring_tasks do |t|\n      t.string :key, null: false, index: {unique: true}\n      t.string :schedule, null: false\n      t.string :command, limit: 2048\n      t.string :class_name\n      t.text :arguments\n\n      t.string :queue_name\n      t.integer :priority, default: 0\n\n      t.boolean :static, default: true, index: true\n\n      t.text :description\n\n      t.timestamps\n    end\n  end\nend\n"
  },
  {
    "path": "db/queue_migrate/20240908182634_add_name_to_processes.solid_queue.rb",
    "content": "# This migration comes from solid_queue (originally 20240811173327)\nclass AddNameToProcesses < ActiveRecord::Migration[7.1]\n  def change\n    add_column :solid_queue_processes, :name, :string\n  end\nend\n"
  },
  {
    "path": "db/queue_migrate/20240908191029_make_name_not_null.solid_queue.rb",
    "content": "# This migration comes from solid_queue (originally 20240813160053)\nclass MakeNameNotNull < ActiveRecord::Migration[7.1]\n  def up\n    SolidQueue::Process.where(name: nil).find_each do |process|\n      process.name ||= [process.kind.downcase, SecureRandom.hex(10)].join(\"-\")\n      process.save!\n    end\n\n    change_column :solid_queue_processes, :name, :string, null: false\n    add_index :solid_queue_processes, [:name, :supervisor_id], unique: true\n  end\n\n  def down\n    remove_index :solid_queue_processes, [:name, :supervisor_id]\n    change_column :solid_queue_processes, :name, :string, null: true\n  end\nend\n"
  },
  {
    "path": "db/queue_migrate/20240908191030_change_solid_queue_recurring_tasks_static_to_not_null.solid_queue.rb",
    "content": "# This migration comes from solid_queue (originally 20240819165045)\nclass ChangeSolidQueueRecurringTasksStaticToNotNull < ActiveRecord::Migration[7.1]\n  def change\n    change_column_null :solid_queue_recurring_tasks, :static, false, true\n  end\nend\n"
  },
  {
    "path": "db/queue_schema.rb",
    "content": "# This file is auto-generated from the current state of the database. Instead\n# of editing this file, please use the migrations feature of Active Record to\n# incrementally modify your database, and then regenerate this schema definition.\n#\n# This file is the source Rails uses to define your schema when running `bin/rails\n# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to\n# be faster and is potentially less error prone than running all of your\n# migrations from scratch. Old migrations may fail to apply correctly if those\n# migrations use external dependencies or application code.\n#\n# It's strongly recommended that you check this file into your version control system.\n\nActiveRecord::Schema[8.2].define(version: 2024_09_08_191030) do\n  create_table \"solid_queue_blocked_executions\", force: :cascade do |t|\n    t.string \"concurrency_key\", null: false\n    t.datetime \"created_at\", null: false\n    t.datetime \"expires_at\", null: false\n    t.integer \"job_id\", null: false\n    t.integer \"priority\", default: 0, null: false\n    t.string \"queue_name\", null: false\n    t.index [\"concurrency_key\", \"priority\", \"job_id\"], name: \"index_solid_queue_blocked_executions_for_release\"\n    t.index [\"expires_at\", \"concurrency_key\"], name: \"index_solid_queue_blocked_executions_for_maintenance\"\n    t.index [\"job_id\"], name: \"index_solid_queue_blocked_executions_on_job_id\", unique: true\n  end\n\n  create_table \"solid_queue_claimed_executions\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.integer \"job_id\", null: false\n    t.bigint \"process_id\"\n    t.index [\"job_id\"], name: \"index_solid_queue_claimed_executions_on_job_id\", unique: true\n    t.index [\"process_id\", \"job_id\"], name: \"index_solid_queue_claimed_executions_on_process_id_and_job_id\"\n  end\n\n  create_table \"solid_queue_failed_executions\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.text \"error\"\n    t.integer \"job_id\", null: false\n    t.index [\"job_id\"], name: \"index_solid_queue_failed_executions_on_job_id\", unique: true\n  end\n\n  create_table \"solid_queue_jobs\", force: :cascade do |t|\n    t.string \"active_job_id\"\n    t.text \"arguments\"\n    t.string \"class_name\", null: false\n    t.string \"concurrency_key\"\n    t.datetime \"created_at\", null: false\n    t.datetime \"finished_at\"\n    t.integer \"priority\", default: 0, null: false\n    t.string \"queue_name\", null: false\n    t.datetime \"scheduled_at\"\n    t.datetime \"updated_at\", null: false\n    t.index [\"active_job_id\"], name: \"index_solid_queue_jobs_on_active_job_id\"\n    t.index [\"class_name\"], name: \"index_solid_queue_jobs_on_class_name\"\n    t.index [\"finished_at\"], name: \"index_solid_queue_jobs_on_finished_at\"\n    t.index [\"queue_name\", \"finished_at\"], name: \"index_solid_queue_jobs_for_filtering\"\n    t.index [\"scheduled_at\", \"finished_at\"], name: \"index_solid_queue_jobs_for_alerting\"\n  end\n\n  create_table \"solid_queue_pauses\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.string \"queue_name\", null: false\n    t.index [\"queue_name\"], name: \"index_solid_queue_pauses_on_queue_name\", unique: true\n  end\n\n  create_table \"solid_queue_processes\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.string \"hostname\"\n    t.string \"kind\", null: false\n    t.datetime \"last_heartbeat_at\", null: false\n    t.text \"metadata\"\n    t.string \"name\", null: false\n    t.integer \"pid\", null: false\n    t.bigint \"supervisor_id\"\n    t.index [\"last_heartbeat_at\"], name: \"index_solid_queue_processes_on_last_heartbeat_at\"\n    t.index [\"name\", \"supervisor_id\"], name: \"index_solid_queue_processes_on_name_and_supervisor_id\", unique: true\n    t.index [\"supervisor_id\"], name: \"index_solid_queue_processes_on_supervisor_id\"\n  end\n\n  create_table \"solid_queue_ready_executions\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.integer \"job_id\", null: false\n    t.integer \"priority\", default: 0, null: false\n    t.string \"queue_name\", null: false\n    t.index [\"job_id\"], name: \"index_solid_queue_ready_executions_on_job_id\", unique: true\n    t.index [\"priority\", \"job_id\"], name: \"index_solid_queue_poll_all\"\n    t.index [\"queue_name\", \"priority\", \"job_id\"], name: \"index_solid_queue_poll_by_queue\"\n  end\n\n  create_table \"solid_queue_recurring_executions\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.integer \"job_id\", null: false\n    t.datetime \"run_at\", null: false\n    t.string \"task_key\", null: false\n    t.index [\"job_id\"], name: \"index_solid_queue_recurring_executions_on_job_id\", unique: true\n    t.index [\"task_key\", \"run_at\"], name: \"index_solid_queue_recurring_executions_on_task_key_and_run_at\", unique: true\n  end\n\n  create_table \"solid_queue_recurring_tasks\", force: :cascade do |t|\n    t.text \"arguments\"\n    t.string \"class_name\"\n    t.string \"command\", limit: 2048\n    t.datetime \"created_at\", null: false\n    t.text \"description\"\n    t.string \"key\", null: false\n    t.integer \"priority\", default: 0\n    t.string \"queue_name\"\n    t.string \"schedule\", null: false\n    t.boolean \"static\", default: true, null: false\n    t.datetime \"updated_at\", null: false\n    t.index [\"key\"], name: \"index_solid_queue_recurring_tasks_on_key\", unique: true\n    t.index [\"static\"], name: \"index_solid_queue_recurring_tasks_on_static\"\n  end\n\n  create_table \"solid_queue_scheduled_executions\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.integer \"job_id\", null: false\n    t.integer \"priority\", default: 0, null: false\n    t.string \"queue_name\", null: false\n    t.datetime \"scheduled_at\", null: false\n    t.index [\"job_id\"], name: \"index_solid_queue_scheduled_executions_on_job_id\", unique: true\n    t.index [\"scheduled_at\", \"priority\", \"job_id\"], name: \"index_solid_queue_dispatch_all\"\n  end\n\n  create_table \"solid_queue_semaphores\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.datetime \"expires_at\", null: false\n    t.string \"key\", null: false\n    t.datetime \"updated_at\", null: false\n    t.integer \"value\", default: 1, null: false\n    t.index [\"expires_at\"], name: \"index_solid_queue_semaphores_on_expires_at\"\n    t.index [\"key\", \"value\"], name: \"index_solid_queue_semaphores_on_key_and_value\"\n    t.index [\"key\"], name: \"index_solid_queue_semaphores_on_key\", unique: true\n  end\n\n  add_foreign_key \"solid_queue_blocked_executions\", \"solid_queue_jobs\", column: \"job_id\", on_delete: :cascade\n  add_foreign_key \"solid_queue_claimed_executions\", \"solid_queue_jobs\", column: \"job_id\", on_delete: :cascade\n  add_foreign_key \"solid_queue_failed_executions\", \"solid_queue_jobs\", column: \"job_id\", on_delete: :cascade\n  add_foreign_key \"solid_queue_ready_executions\", \"solid_queue_jobs\", column: \"job_id\", on_delete: :cascade\n  add_foreign_key \"solid_queue_recurring_executions\", \"solid_queue_jobs\", column: \"job_id\", on_delete: :cascade\n  add_foreign_key \"solid_queue_scheduled_executions\", \"solid_queue_jobs\", column: \"job_id\", on_delete: :cascade\nend\n"
  },
  {
    "path": "db/schema.rb",
    "content": "# This file is auto-generated from the current state of the database. Instead\n# of editing this file, please use the migrations feature of Active Record to\n# incrementally modify your database, and then regenerate this schema definition.\n#\n# This file is the source Rails uses to define your schema when running `bin/rails\n# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to\n# be faster and is potentially less error prone than running all of your\n# migrations from scratch. Old migrations may fail to apply correctly if those\n# migrations use external dependencies or application code.\n#\n# It's strongly recommended that you check this file into your version control system.\n\nActiveRecord::Schema[8.2].define(version: 2026_03_06_110802) do\n  create_table \"_litestream_lock\", id: false, force: :cascade do |t|\n    t.integer \"id\"\n  end\n\n  create_table \"_litestream_seq\", force: :cascade do |t|\n    t.integer \"seq\"\n  end\n\n  create_table \"active_storage_attachments\", force: :cascade do |t|\n    t.bigint \"blob_id\", null: false\n    t.datetime \"created_at\", null: false\n    t.string \"name\", null: false\n    t.bigint \"record_id\", null: false\n    t.string \"record_type\", null: false\n    t.index [\"blob_id\"], name: \"index_active_storage_attachments_on_blob_id\"\n    t.index [\"record_type\", \"record_id\", \"name\", \"blob_id\"], name: \"index_active_storage_attachments_uniqueness\", unique: true\n  end\n\n  create_table \"active_storage_blobs\", force: :cascade do |t|\n    t.bigint \"byte_size\", null: false\n    t.string \"checksum\"\n    t.string \"content_type\"\n    t.datetime \"created_at\", null: false\n    t.string \"filename\", null: false\n    t.string \"key\", null: false\n    t.text \"metadata\"\n    t.string \"service_name\", null: false\n    t.index [\"key\"], name: \"index_active_storage_blobs_on_key\", unique: true\n  end\n\n  create_table \"active_storage_variant_records\", force: :cascade do |t|\n    t.bigint \"blob_id\", null: false\n    t.string \"variation_digest\", null: false\n    t.index [\"blob_id\", \"variation_digest\"], name: \"index_active_storage_variant_records_uniqueness\", unique: true\n  end\n\n  create_table \"ahoy_events\", force: :cascade do |t|\n    t.string \"name\"\n    t.text \"properties\"\n    t.datetime \"time\"\n    t.integer \"user_id\"\n    t.integer \"visit_id\"\n    t.index [\"name\", \"time\"], name: \"index_ahoy_events_on_name_and_time\"\n    t.index [\"user_id\"], name: \"index_ahoy_events_on_user_id\"\n    t.index [\"visit_id\"], name: \"index_ahoy_events_on_visit_id\"\n  end\n\n  create_table \"ahoy_visits\", force: :cascade do |t|\n    t.string \"app_version\"\n    t.string \"browser\"\n    t.string \"city\"\n    t.string \"country\"\n    t.string \"device_type\"\n    t.string \"ip\"\n    t.text \"landing_page\"\n    t.float \"latitude\"\n    t.float \"longitude\"\n    t.string \"os\"\n    t.string \"os_version\"\n    t.string \"platform\"\n    t.text \"referrer\"\n    t.string \"referring_domain\"\n    t.string \"region\"\n    t.datetime \"started_at\"\n    t.text \"user_agent\"\n    t.integer \"user_id\"\n    t.string \"utm_campaign\"\n    t.string \"utm_content\"\n    t.string \"utm_medium\"\n    t.string \"utm_source\"\n    t.string \"utm_term\"\n    t.string \"visit_token\"\n    t.string \"visitor_token\"\n    t.index [\"ip\"], name: \"index_ahoy_visits_on_ip\"\n    t.index [\"started_at\", \"ip\"], name: \"index_ahoy_visits_on_started_at_and_ip\"\n    t.index [\"user_id\"], name: \"index_ahoy_visits_on_user_id\"\n    t.index [\"visit_token\"], name: \"index_ahoy_visits_on_visit_token\", unique: true\n  end\n\n  create_table \"aliases\", force: :cascade do |t|\n    t.integer \"aliasable_id\", null: false\n    t.string \"aliasable_type\", null: false\n    t.datetime \"created_at\", null: false\n    t.string \"name\", null: false\n    t.string \"slug\"\n    t.datetime \"updated_at\", null: false\n    t.index [\"aliasable_type\", \"aliasable_id\"], name: \"index_aliases_on_aliasable\"\n    t.index [\"aliasable_type\", \"name\"], name: \"index_aliases_on_aliasable_type_and_name\", unique: true\n    t.index [\"slug\"], name: \"index_aliases_on_slug\"\n  end\n\n  create_table \"cfps\", force: :cascade do |t|\n    t.date \"close_date\"\n    t.datetime \"created_at\", null: false\n    t.integer \"event_id\", null: false\n    t.string \"link\"\n    t.string \"name\"\n    t.date \"open_date\"\n    t.datetime \"updated_at\", null: false\n    t.index [\"event_id\"], name: \"index_cfps_on_event_id\"\n  end\n\n  create_table \"cities\", force: :cascade do |t|\n    t.string \"country_code\", null: false\n    t.datetime \"created_at\", null: false\n    t.boolean \"featured\", default: false, null: false\n    t.json \"geocode_metadata\", default: {}, null: false\n    t.decimal \"latitude\", precision: 10, scale: 6\n    t.decimal \"longitude\", precision: 10, scale: 6\n    t.string \"name\", null: false\n    t.string \"slug\", null: false\n    t.string \"state_code\"\n    t.datetime \"updated_at\", null: false\n    t.index [\"featured\"], name: \"index_cities_on_featured\"\n    t.index [\"name\", \"country_code\", \"state_code\"], name: \"index_cities_on_name_and_country_code_and_state_code\"\n    t.index [\"slug\"], name: \"index_cities_on_slug\", unique: true\n  end\n\n  create_table \"connected_accounts\", force: :cascade do |t|\n    t.string \"access_token\"\n    t.datetime \"created_at\", null: false\n    t.datetime \"expires_at\"\n    t.string \"provider\"\n    t.string \"uid\"\n    t.datetime \"updated_at\", null: false\n    t.integer \"user_id\", null: false\n    t.string \"username\"\n    t.index [\"provider\", \"uid\"], name: \"index_connected_accounts_on_provider_and_uid\", unique: true\n    t.index [\"provider\", \"username\"], name: \"index_connected_accounts_on_provider_and_username\", unique: true\n    t.index [\"user_id\"], name: \"index_connected_accounts_on_user_id\"\n  end\n\n  create_table \"contributors\", force: :cascade do |t|\n    t.string \"avatar_url\"\n    t.datetime \"created_at\", null: false\n    t.string \"html_url\"\n    t.string \"login\", null: false\n    t.string \"name\"\n    t.datetime \"updated_at\", null: false\n    t.integer \"user_id\"\n    t.index [\"login\"], name: \"index_contributors_on_login\", unique: true\n    t.index [\"user_id\"], name: \"index_contributors_on_user_id\"\n  end\n\n  create_table \"email_verification_tokens\", force: :cascade do |t|\n    t.integer \"user_id\", null: false\n    t.index [\"user_id\"], name: \"index_email_verification_tokens_on_user_id\"\n  end\n\n  create_table \"event_involvements\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.integer \"event_id\", null: false\n    t.integer \"involvementable_id\", null: false\n    t.string \"involvementable_type\", null: false\n    t.integer \"position\", default: 0\n    t.string \"role\", null: false\n    t.datetime \"updated_at\", null: false\n    t.index [\"event_id\"], name: \"index_event_involvements_on_event_id\"\n    t.index [\"involvementable_type\", \"involvementable_id\", \"event_id\", \"role\"], name: \"idx_involvements_on_involvementable_and_event_and_role\", unique: true\n    t.index [\"involvementable_type\", \"involvementable_id\"], name: \"index_event_involvements_on_involvementable\"\n    t.index [\"role\"], name: \"index_event_involvements_on_role\"\n  end\n\n  create_table \"event_participations\", force: :cascade do |t|\n    t.string \"attended_as\", null: false\n    t.datetime \"created_at\", null: false\n    t.integer \"event_id\", null: false\n    t.datetime \"updated_at\", null: false\n    t.integer \"user_id\", null: false\n    t.index [\"attended_as\"], name: \"index_event_participations_on_attended_as\"\n    t.index [\"event_id\"], name: \"index_event_participations_on_event_id\"\n    t.index [\"user_id\", \"event_id\", \"attended_as\"], name: \"idx_on_user_id_event_id_attended_as_ca0a2916e2\", unique: true\n    t.index [\"user_id\"], name: \"index_event_participations_on_user_id\"\n  end\n\n  create_table \"event_series\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.text \"description\", default: \"\", null: false\n    t.integer \"frequency\", default: 0, null: false\n    t.integer \"kind\", default: 0, null: false\n    t.string \"language\", default: \"\", null: false\n    t.string \"name\", default: \"\", null: false\n    t.string \"slug\", default: \"\", null: false\n    t.string \"twitter\", default: \"\", null: false\n    t.datetime \"updated_at\", null: false\n    t.string \"website\", default: \"\", null: false\n    t.string \"youtube_channel_id\", default: \"\"\n    t.string \"youtube_channel_name\", default: \"\"\n    t.index [\"frequency\"], name: \"index_event_series_on_frequency\"\n    t.index [\"kind\"], name: \"index_event_series_on_kind\"\n    t.index [\"name\"], name: \"index_event_series_on_name\"\n    t.index [\"slug\"], name: \"index_event_series_on_slug\"\n  end\n\n  create_table \"events\", force: :cascade do |t|\n    t.integer \"canonical_id\"\n    t.string \"city\"\n    t.string \"country_code\"\n    t.datetime \"created_at\", null: false\n    t.date \"date\"\n    t.string \"date_precision\", default: \"day\", null: false\n    t.date \"end_date\"\n    t.integer \"event_series_id\", null: false\n    t.json \"geocode_metadata\", default: {}, null: false\n    t.string \"kind\", default: \"event\", null: false\n    t.decimal \"latitude\", precision: 10, scale: 6\n    t.string \"location\"\n    t.decimal \"longitude\", precision: 10, scale: 6\n    t.string \"name\", default: \"\", null: false\n    t.string \"slug\", default: \"\", null: false\n    t.date \"start_date\"\n    t.string \"state_code\"\n    t.integer \"talks_count\", default: 0, null: false\n    t.datetime \"updated_at\", null: false\n    t.string \"website\", default: \"\"\n    t.index [\"canonical_id\"], name: \"index_events_on_canonical_id\"\n    t.index [\"country_code\", \"state_code\"], name: \"index_events_on_country_code_and_state_code\"\n    t.index [\"event_series_id\"], name: \"index_events_on_event_series_id\"\n    t.index [\"kind\"], name: \"index_events_on_kind\"\n    t.index [\"name\"], name: \"index_events_on_name\"\n    t.index [\"slug\"], name: \"index_events_on_slug\"\n  end\n\n  create_table \"favorite_users\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.integer \"favorite_user_id\", null: false\n    t.text \"notes\"\n    t.datetime \"updated_at\", null: false\n    t.integer \"user_id\", null: false\n    t.index [\"favorite_user_id\"], name: \"index_favorite_users_on_favorite_user_id\"\n    t.index [\"user_id\"], name: \"index_favorite_users_on_user_id\"\n  end\n\n  create_table \"geocode_results\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.string \"query\", null: false\n    t.text \"response_body\", null: false\n    t.datetime \"updated_at\", null: false\n    t.index [\"query\"], name: \"index_geocode_results_on_query\", unique: true\n  end\n\n  create_table \"llm_requests\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.float \"duration\", null: false\n    t.json \"raw_response\", null: false\n    t.string \"request_hash\", null: false\n    t.integer \"resource_id\", null: false\n    t.string \"resource_type\", null: false\n    t.boolean \"success\", default: false, null: false\n    t.string \"task_name\", default: \"\", null: false\n    t.datetime \"updated_at\", null: false\n    t.index [\"request_hash\"], name: \"index_llm_requests_on_request_hash\", unique: true\n    t.index [\"resource_type\", \"resource_id\"], name: \"index_llm_requests_on_resource\"\n    t.index [\"task_name\"], name: \"index_llm_requests_on_task_name\"\n  end\n\n  create_table \"organizations\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.text \"description\"\n    t.string \"domain\"\n    t.integer \"kind\", default: 0, null: false\n    t.string \"logo_background\", default: \"white\"\n    t.string \"logo_url\"\n    t.json \"logo_urls\", default: []\n    t.string \"main_location\"\n    t.string \"name\"\n    t.string \"slug\"\n    t.datetime \"updated_at\", null: false\n    t.string \"website\"\n    t.index [\"kind\"], name: \"index_organizations_on_kind\"\n    t.index [\"slug\"], name: \"index_organizations_on_slug\"\n  end\n\n  create_table \"password_reset_tokens\", force: :cascade do |t|\n    t.integer \"user_id\", null: false\n    t.index [\"user_id\"], name: \"index_password_reset_tokens_on_user_id\"\n  end\n\n  create_table \"rollups\", force: :cascade do |t|\n    t.json \"dimensions\", default: {}, null: false\n    t.string \"interval\", null: false\n    t.string \"name\", null: false\n    t.datetime \"time\", null: false\n    t.float \"value\"\n    t.index [\"name\", \"interval\", \"time\", \"dimensions\"], name: \"index_rollups_on_name_and_interval_and_time_and_dimensions\", unique: true\n  end\n\n  create_table \"sessions\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.string \"ip_address\"\n    t.datetime \"updated_at\", null: false\n    t.string \"user_agent\"\n    t.integer \"user_id\", null: false\n    t.index [\"user_id\"], name: \"index_sessions_on_user_id\"\n  end\n\n  create_table \"speaker_talks\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.datetime \"discarded_at\"\n    t.integer \"speaker_id\", null: false\n    t.integer \"talk_id\", null: false\n    t.datetime \"updated_at\", null: false\n    t.index [\"speaker_id\", \"talk_id\"], name: \"index_speaker_talks_on_speaker_id_and_talk_id\", unique: true\n    t.index [\"speaker_id\"], name: \"index_speaker_talks_on_speaker_id\"\n    t.index [\"talk_id\"], name: \"index_speaker_talks_on_talk_id\"\n  end\n\n  create_table \"speakers\", force: :cascade do |t|\n    t.text \"bio\", default: \"\", null: false\n    t.string \"bsky\", default: \"\", null: false\n    t.json \"bsky_metadata\", default: {}, null: false\n    t.integer \"canonical_id\"\n    t.datetime \"created_at\", null: false\n    t.string \"github\", default: \"\", null: false\n    t.json \"github_metadata\", default: {}, null: false\n    t.string \"linkedin\", default: \"\", null: false\n    t.string \"mastodon\", default: \"\", null: false\n    t.string \"name\", default: \"\", null: false\n    t.string \"pronouns\", default: \"\", null: false\n    t.string \"pronouns_type\", default: \"not_specified\", null: false\n    t.string \"slug\", default: \"\", null: false\n    t.string \"speakerdeck\", default: \"\", null: false\n    t.integer \"talks_count\", default: 0, null: false\n    t.string \"twitter\", default: \"\", null: false\n    t.datetime \"updated_at\", null: false\n    t.string \"website\", default: \"\", null: false\n    t.index [\"canonical_id\"], name: \"index_speakers_on_canonical_id\"\n    t.index [\"github\"], name: \"index_speakers_on_github\", unique: true, where: \"github IS NOT NULL AND github != ''\"\n    t.index [\"name\"], name: \"index_speakers_on_name\"\n    t.index [\"slug\"], name: \"index_speakers_on_slug\", unique: true\n  end\n\n  create_table \"sponsors\", force: :cascade do |t|\n    t.string \"badge\"\n    t.datetime \"created_at\", null: false\n    t.integer \"event_id\", null: false\n    t.integer \"level\"\n    t.integer \"organization_id\", null: false\n    t.string \"tier\"\n    t.datetime \"updated_at\", null: false\n    t.index [\"event_id\", \"organization_id\", \"tier\"], name: \"index_sponsors_on_event_organization_tier_unique\", unique: true\n    t.index [\"event_id\"], name: \"index_sponsors_on_event_id\"\n    t.index [\"organization_id\"], name: \"index_sponsors_on_organization_id\"\n  end\n\n  create_table \"suggestions\", force: :cascade do |t|\n    t.integer \"approved_by_id\"\n    t.text \"content\"\n    t.datetime \"created_at\", null: false\n    t.integer \"status\", default: 0, null: false\n    t.integer \"suggestable_id\", null: false\n    t.string \"suggestable_type\", null: false\n    t.integer \"suggested_by_id\"\n    t.datetime \"updated_at\", null: false\n    t.index [\"approved_by_id\"], name: \"index_suggestions_on_approved_by_id\"\n    t.index [\"status\"], name: \"index_suggestions_on_status\"\n    t.index [\"suggestable_type\", \"suggestable_id\"], name: \"index_suggestions_on_suggestable\"\n    t.index [\"suggested_by_id\"], name: \"index_suggestions_on_suggested_by_id\"\n  end\n\n  create_table \"talk_topics\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.integer \"talk_id\", null: false\n    t.integer \"topic_id\", null: false\n    t.datetime \"updated_at\", null: false\n    t.index [\"talk_id\"], name: \"index_talk_topics_on_talk_id\"\n    t.index [\"topic_id\", \"talk_id\"], name: \"index_talk_topics_on_topic_id_and_talk_id\", unique: true\n    t.index [\"topic_id\"], name: \"index_talk_topics_on_topic_id\"\n  end\n\n  create_table \"talk_transcripts\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.text \"enhanced_transcript\"\n    t.text \"raw_transcript\"\n    t.integer \"talk_id\", null: false\n    t.datetime \"updated_at\", null: false\n    t.index [\"talk_id\"], name: \"index_talk_transcripts_on_talk_id\"\n  end\n\n  create_table \"talks\", force: :cascade do |t|\n    t.json \"additional_resources\", default: [], null: false\n    t.datetime \"announced_at\"\n    t.datetime \"created_at\", null: false\n    t.date \"date\"\n    t.text \"description\", default: \"\", null: false\n    t.integer \"duration_in_seconds\"\n    t.integer \"end_seconds\"\n    t.integer \"event_id\"\n    t.boolean \"external_player\", default: false, null: false\n    t.string \"external_player_url\", default: \"\", null: false\n    t.string \"kind\", default: \"talk\", null: false\n    t.string \"language\", default: \"en\", null: false\n    t.integer \"like_count\", default: 0\n    t.boolean \"meta_talk\", default: false, null: false\n    t.string \"original_title\", default: \"\", null: false\n    t.integer \"parent_talk_id\"\n    t.datetime \"published_at\"\n    t.string \"slides_url\"\n    t.string \"slug\", default: \"\", null: false\n    t.integer \"start_seconds\"\n    t.string \"static_id\", null: false\n    t.boolean \"summarized_using_ai\", default: true, null: false\n    t.text \"summary\", default: \"\", null: false\n    t.string \"thumbnail_lg\", default: \"\", null: false\n    t.string \"thumbnail_md\", default: \"\", null: false\n    t.string \"thumbnail_sm\", default: \"\", null: false\n    t.string \"thumbnail_xl\", default: \"\", null: false\n    t.string \"thumbnail_xs\", default: \"\", null: false\n    t.string \"title\", default: \"\", null: false\n    t.datetime \"updated_at\", null: false\n    t.datetime \"video_availability_checked_at\"\n    t.string \"video_id\", default: \"\", null: false\n    t.string \"video_provider\", default: \"\", null: false\n    t.datetime \"video_unavailable_at\"\n    t.integer \"view_count\", default: 0\n    t.datetime \"youtube_thumbnail_checked_at\"\n    t.index [\"date\"], name: \"index_talks_on_date\"\n    t.index [\"event_id\"], name: \"index_talks_on_event_id\"\n    t.index [\"kind\"], name: \"index_talks_on_kind\"\n    t.index [\"parent_talk_id\"], name: \"index_talks_on_parent_talk_id\"\n    t.index [\"slug\"], name: \"index_talks_on_slug\"\n    t.index [\"static_id\"], name: \"index_talks_on_static_id\", unique: true\n    t.index [\"title\"], name: \"index_talks_on_title\"\n    t.index [\"updated_at\"], name: \"index_talks_on_updated_at\"\n    t.index [\"video_provider\", \"date\"], name: \"index_talks_on_video_provider_and_date\"\n  end\n\n  create_table \"topic_gems\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.string \"gem_name\", null: false\n    t.integer \"topic_id\", null: false\n    t.datetime \"updated_at\", null: false\n    t.index [\"topic_id\", \"gem_name\"], name: \"index_topic_gems_on_topic_id_and_gem_name\", unique: true\n    t.index [\"topic_id\"], name: \"index_topic_gems_on_topic_id\"\n  end\n\n  create_table \"topics\", force: :cascade do |t|\n    t.integer \"canonical_id\"\n    t.datetime \"created_at\", null: false\n    t.text \"description\"\n    t.string \"name\"\n    t.boolean \"published\", default: false\n    t.string \"slug\", default: \"\", null: false\n    t.string \"status\", default: \"pending\", null: false\n    t.integer \"talks_count\"\n    t.datetime \"updated_at\", null: false\n    t.index [\"canonical_id\"], name: \"index_topics_on_canonical_id\"\n    t.index [\"name\"], name: \"index_topics_on_name\", unique: true\n    t.index [\"slug\"], name: \"index_topics_on_slug\"\n    t.index [\"status\"], name: \"index_topics_on_status\"\n  end\n\n  create_table \"user_talks\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.datetime \"discarded_at\"\n    t.integer \"talk_id\", null: false\n    t.datetime \"updated_at\", null: false\n    t.integer \"user_id\", null: false\n    t.index [\"talk_id\"], name: \"index_user_talks_on_talk_id\"\n    t.index [\"user_id\", \"talk_id\"], name: \"index_user_talks_on_user_id_and_talk_id\", unique: true\n    t.index [\"user_id\"], name: \"index_user_talks_on_user_id\"\n  end\n\n  create_table \"users\", force: :cascade do |t|\n    t.boolean \"admin\", default: false, null: false\n    t.text \"bio\", default: \"\", null: false\n    t.string \"bsky\", default: \"\", null: false\n    t.json \"bsky_metadata\", default: {}, null: false\n    t.integer \"canonical_id\"\n    t.string \"city\"\n    t.string \"country_code\"\n    t.datetime \"created_at\", null: false\n    t.string \"email\"\n    t.json \"geocode_metadata\", default: {}, null: false\n    t.string \"github_handle\"\n    t.json \"github_metadata\", default: {}, null: false\n    t.decimal \"latitude\", precision: 10, scale: 6\n    t.string \"linkedin\", default: \"\", null: false\n    t.string \"location\", default: \"\"\n    t.decimal \"longitude\", precision: 10, scale: 6\n    t.boolean \"marked_for_deletion\", default: false, null: false\n    t.string \"mastodon\", default: \"\", null: false\n    t.string \"name\"\n    t.string \"password_digest\"\n    t.string \"pronouns\", default: \"\", null: false\n    t.string \"pronouns_type\", default: \"not_specified\", null: false\n    t.json \"settings\", default: {}, null: false\n    t.string \"slug\", default: \"\", null: false\n    t.string \"speakerdeck\", default: \"\", null: false\n    t.string \"state_code\"\n    t.datetime \"suspicion_cleared_at\"\n    t.datetime \"suspicion_marked_at\"\n    t.integer \"talks_count\", default: 0, null: false\n    t.string \"twitter\", default: \"\", null: false\n    t.datetime \"updated_at\", null: false\n    t.boolean \"verified\", default: false, null: false\n    t.integer \"watched_talks_count\", default: 0, null: false\n    t.string \"website\", default: \"\", null: false\n    t.index \"lower(github_handle)\", name: \"index_users_on_lower_github_handle\", unique: true, where: \"github_handle IS NOT NULL AND github_handle != ''\"\n    t.index [\"canonical_id\"], name: \"index_users_on_canonical_id\"\n    t.index [\"email\"], name: \"index_users_on_email\"\n    t.index [\"marked_for_deletion\"], name: \"index_users_on_marked_for_deletion\"\n    t.index [\"name\"], name: \"index_users_on_name\"\n    t.index [\"slug\"], name: \"index_users_on_slug\", unique: true, where: \"slug IS NOT NULL AND slug != ''\"\n  end\n\n  create_table \"watch_list_talks\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.integer \"talk_id\", null: false\n    t.datetime \"updated_at\", null: false\n    t.integer \"watch_list_id\", null: false\n    t.index [\"talk_id\"], name: \"index_watch_list_talks_on_talk_id\"\n    t.index [\"watch_list_id\", \"talk_id\"], name: \"index_watch_list_talks_on_watch_list_id_and_talk_id\", unique: true\n    t.index [\"watch_list_id\"], name: \"index_watch_list_talks_on_watch_list_id\"\n  end\n\n  create_table \"watch_lists\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.text \"description\"\n    t.string \"name\", null: false\n    t.integer \"talks_count\", default: 0\n    t.datetime \"updated_at\", null: false\n    t.integer \"user_id\", null: false\n    t.index [\"user_id\"], name: \"index_watch_lists_on_user_id\"\n  end\n\n  create_table \"watched_talks\", force: :cascade do |t|\n    t.datetime \"created_at\", null: false\n    t.json \"feedback\", default: {}\n    t.datetime \"feedback_shared_at\"\n    t.integer \"progress_seconds\", default: 0, null: false\n    t.integer \"talk_id\", null: false\n    t.datetime \"updated_at\", null: false\n    t.integer \"user_id\", null: false\n    t.boolean \"watched\", default: false, null: false\n    t.datetime \"watched_at\", null: false\n    t.string \"watched_on\"\n    t.index [\"talk_id\", \"user_id\"], name: \"index_watched_talks_on_talk_id_and_user_id\", unique: true\n    t.index [\"talk_id\"], name: \"index_watched_talks_on_talk_id\"\n    t.index [\"user_id\"], name: \"index_watched_talks_on_user_id\"\n  end\n\n  add_foreign_key \"active_storage_attachments\", \"active_storage_blobs\", column: \"blob_id\"\n  add_foreign_key \"active_storage_variant_records\", \"active_storage_blobs\", column: \"blob_id\"\n  add_foreign_key \"cfps\", \"events\"\n  add_foreign_key \"connected_accounts\", \"users\"\n  add_foreign_key \"contributors\", \"users\"\n  add_foreign_key \"email_verification_tokens\", \"users\"\n  add_foreign_key \"event_involvements\", \"events\"\n  add_foreign_key \"event_participations\", \"events\"\n  add_foreign_key \"event_participations\", \"users\"\n  add_foreign_key \"events\", \"event_series\"\n  add_foreign_key \"events\", \"events\", column: \"canonical_id\"\n  add_foreign_key \"favorite_users\", \"users\"\n  add_foreign_key \"favorite_users\", \"users\", column: \"favorite_user_id\"\n  add_foreign_key \"password_reset_tokens\", \"users\"\n  add_foreign_key \"sessions\", \"users\"\n  add_foreign_key \"speakers\", \"speakers\", column: \"canonical_id\"\n  add_foreign_key \"sponsors\", \"events\"\n  add_foreign_key \"sponsors\", \"organizations\"\n  add_foreign_key \"suggestions\", \"users\", column: \"approved_by_id\"\n  add_foreign_key \"suggestions\", \"users\", column: \"suggested_by_id\"\n  add_foreign_key \"talk_topics\", \"talks\"\n  add_foreign_key \"talk_topics\", \"topics\"\n  add_foreign_key \"talk_transcripts\", \"talks\"\n  add_foreign_key \"talks\", \"events\"\n  add_foreign_key \"talks\", \"talks\", column: \"parent_talk_id\"\n  add_foreign_key \"topic_gems\", \"topics\"\n  add_foreign_key \"topics\", \"topics\", column: \"canonical_id\"\n  add_foreign_key \"user_talks\", \"talks\"\n  add_foreign_key \"user_talks\", \"users\"\n  add_foreign_key \"watch_list_talks\", \"talks\"\n  add_foreign_key \"watch_list_talks\", \"watch_lists\"\n\n  # Virtual tables defined in this database.\n  # Note that virtual tables may not work with other database engines. Be careful if changing database.\n  create_virtual_table \"speakers_search_index\", \"fts5\", [\"name\", \"github\", \"tokenize = porter\"]\n  create_virtual_table \"talks_search_index\", \"fts5\", [\"title\", \"summary\", \"speaker_names\", \"event_names\", \"video_provider UNINDEXED\", \"tokenize = porter\"]\n  create_virtual_table \"users_search_index\", \"fts5\", [\"name\", \"github_handle\", \"tokenize = porter\"]\nend\n"
  },
  {
    "path": "db/seeds.rb",
    "content": "Search::Backend.without_indexing do\n  Static::City.import_all!\n  Static::Speaker.import_all!\n  Static::EventSeries.import_all_series!\n  Static::Event.import_recent!\n  Static::Event.import_meetups!\n  Static::Topic.import_all!\n\n  User.order(Arel.sql(\"RANDOM()\")).limit(5).each do |user|\n    user.watched_talk_seeder.seed_development_data\n  end\n\n  Rake::Task[\"backfill:speaker_participation\"].invoke\nend\n\nSearch::Backend.reindex_all\n"
  },
  {
    "path": "docker-compose.typesense.yml",
    "content": "# Docker Compose configuration for local Typesense development\n# Run with: docker compose -f docker-compose.typesense.yml up -d\n\nservices:\n  typesense:\n    image: typesense/typesense:29.0\n    container_name: rubyevents-typesense\n    restart: unless-stopped\n    ports:\n      - \"8108:8108\"\n    volumes:\n      - typesense-data:/data\n    environment:\n      - TYPESENSE_DATA_DIR=/data\n      - TYPESENSE_API_KEY=xyz\n      - TYPESENSE_ENABLE_CORS=true\n    command: [\"--data-dir\", \"/data\", \"--api-key\", \"xyz\", \"--enable-cors\", \"true\"]\n    healthcheck:\n      test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:8108/health\"]\n      interval: 30s\n      timeout: 10s\n      retries: 3\n      start_period: 10s\n\nvolumes:\n  typesense-data:\n    driver: local\n"
  },
  {
    "path": "docs/ADDING_CFPS.md",
    "content": "# Adding Call for Proposals to RubyEvents\n\nThis guide explains how to add a CFP for conferences and events in the RubyEvents platform.\n\n## Overview\n\nCFP data is stored in YAML files within the conference/event directories. Each conference can have its own cfp file that describes multiple CFPs.\n\n## File Structure\n\nCFPs are stored in YAML files at:\n```\ndata/{series-name}/{event-name}/cfp.yml\n```\n\nFor example:\n- [`data/blue-ridge-ruby/blue-ridge-ruby-2026/cfp.yml`](/data/blue-ridge-ruby/blue-ridge-ruby-2026/cfp.yml)\n- [`data/sfruby/sfruby-2025/cfp.yml`](/data/sfruby/sfruby-2025/cfp.yml)\n\nAll permitted fields are defined in [CFPSchema.](/app/schemas/cfp_schema.rb)\n\n## Generation\n\nGenerate a CFP using the CfpGenerator!\n\n```bash\nbin/rails g cfp --event-series=blue-ridge-ruby --event=blue-ridge-ruby-2026 --name=\"Call for Proposals\" --link=https://blueridgeruby.com/cfp --open-date=2025-12-15 -close-date=2026-02-03\n```\n\nCheck the usage instructions using help.\n\n```bash\nbin/rails g cfp --help\n```\n\nThis will create a cfp.yml with a single CFP in it.\n\nIf you need to add additional CFPs for start-up demos or lightning talks, run the generator again.\n\n```bash\nbin/rails g cfp --event-series rubyconf --event rubyconf-2026 --name \"Ruby Runway: Pitch Competition\" --link https://rubycentral.teamtailor.com/jobs/6963879-rubyconf-pitch-competition-the-ruby-runway --close-date \"2026-02-28\"\n```\n\nThis will add a second CFP using the same format as the first.\n\nIf you run the generator a second time with the same name as the CFP, it will update the existing CFP.\n\n## Step-by-Step Guide\n\n### 1. Check for Existing CFP File\n\nFirst, check if a cfp file already exists:\n\n```bash\nls data/{series-name}/{event}/cfp.yml\n```\n\n### 2. Create or Edit the cfp File\n\nIf the file doesn't exist, create it:\n\n```bash\nbin/rails g cfp --event-series=blue-ridge-ruby --event=blue-ridge-ruby-2026\n```\n\n### 3. Gather CFP Information\n\nCheck the event website or social media!\n\n### 4. Structure the YAML\n\nStart with the basic structure and add additional CFPs if necessary.\n\n> [!TIP]\n> Dates are structured as YEAR-MM-DD and stored as strings.\n\n### 5. Format your yaml\n\nRun the linter to automatically format and verify all required properties are present.\n\n```bash\nbin/lint\n```\n\n### 5. Run seeds to load data\n\nRun the event series seed to load data.\n\n```bash\nbundle exec rake db:seed:event_series[event-series-slug]\n```\n\n### 6. Review on your dev server\n\nStart the dev server and review the event.\n\n```bash\nbin/dev\n```\n\n## Troubleshooting\n\n### Common Issues\n\n- **Invalid YAML syntax**: Check indentation (use spaces, not tabs)\n- **Missing required fields**: Ensure all required properties are present\n\n## Submission Process\n\n1. Fork the RubyEvents repository\n2. Setup your dev environment following the steps in [CONTRIBUTING](/CONTRIBUTING.md)\n3. Create your cfp file in the appropriate directory\n4. Run `bin/lint`\n5. Run `bin/rails db:seed` (or `bin/rails db:seed:all` if the event happened more than 6 months ago)\n6. Run `bin/dev` and review the event on your dev server\n7. Submit a pull request\n\n## Need Help?\n\nIf you have questions about contributing cfps:\n- Open an issue on GitHub\n- Check existing cfp files for examples\n- Reference this documentation\n\nYour contributions help make RubyEvents a comprehensive resource for the Ruby community!\n"
  },
  {
    "path": "docs/ADDING_EVENTS.md",
    "content": "# Adding a new Conference/Meetup to RubyEvents\n\nThis guide explains how to add a new event or event series to RubyEvents.\n\nIf you are adding an event or event series that already has videos uploaded to YouTube, see the [ADDING_VIDEOS](/docs/ADDING_VIDEOS.md) guide instead.\n\n## Adding a New Event\n\n### Step 1 - Create the Series\n\nIf this is the first event of the series added to RubyEvents, you'll need to create the series first.\n\nCreate a new folder for your series and add a `series.yml` file:\n\n```bash\nmkdir -p data/my-conference\n```\n\nCreate `data/my-conference/series.yml`:\n\n```yaml\n---\nname: My Conference\nwebsite: https://myconference.org/\ntwitter: myconference\nyoutube_channel_name: myconference\nkind: conference # conference, meetup, retreat, or hackathon\nfrequency: yearly # yearly, monthly, quarterly, etc.\nlanguage: english\ndefault_country_code: US\nyoutube_channel_id: \"\" # Will be filled by prepare_series.rb\nplaylist_matcher: \"\" # Optional text to filter playlists\n```\n\n### Step 2 - Create the Event\n\nIf you are backfilling an event that has already happened, and has video recordings on YouTube, you can use a script to automatically generate the event and videos file using the steps in [ADDING_VIDEOS](/docs/ADDING_VIDEOS.md).\n\nOtherwise create the event using a generator:\n\n```bash\nbin/rails g event --event-series haggis-ruby --event haggis-ruby-2026 --name \"Haggis Ruby 2026\"\n```\n\nYou can create a venue file when the event is created.\n\n```bash\nbin/rails g event --event-series tropicalrb --event tropical-on-rails-2027 --name \"Tropical on Rails 2027\" --venue-name \"\" --venue-address \"R. Olimpíadas, 205 - Vila Olímpia, São Paulo - SP, 04551-000\"\n```\n\nThe full schema for an event is available in [EventSchema](app/schemas/event_schema.rb).\n\nCheck the usage instructions using `--help`.\n\n```bash\nbin/rails g event --help\n```\n\n### Step 3 - Add Visual Assets\n\nAdd visual assets (logos, banners, stickers, etc), using the [Adding Visual Assets Guide](docs/ADDING_VISUAL_ASSETS.md).\nYou can view all event assets at https://rubyevents.org/pages/assets.\nWe provide scripts to help generate those assets from a logo and background color.\n\n### Step 4 - Add additional information\n\nOnce you've added your event, see our other guides on how to add additional information.\n\n- [Adding a Schedule to an Event](docs/ADDING_SCHEDULES.md)\n- [Adding Sponsors to an Event](docs/ADDING_SPONSORS.md)\n- [Adding Venues to an Event](docs/ADDING_VENUES.md)\n\n## Troubleshooting\n\n### Common Issues\n\n- **Invalid YAML syntax**: Check indentation (use spaces, not tabs)\n- **Missing required fields**: Ensure all required properties are present\n- **No featured background found**:\n\n  `No featured background found for Blue Ridge Ruby 2026 :  undefined method 'banner_background' for nil. You might have to restart your Rails server.`\n\n  Remove the keys `banner_background`, `featured_background`, `featured_color`, and follow the steps to [add visual assets](docs/ADDING_VISUAL_ASSETS.md).\n\n### FAQ\n<details><summary>How do I handle events in other languages?</summary>\n  We prefer organizer-provided English copy.\n  The title in the original language should be added to the aliases.\n  If there is a latin-character version of the title or content, we prefer that.\n  Never translate titles or other content using automated tooling.\n</details>\n<details><summary>How do I handle online events?</summary>\nLike this!\n\n```yaml\n  location: \"online\"\n  coordinates: false\n```\n</details>\n<details><summary>What about meetups?</summary>\n  Meetups are modeled differently: one event per meetup group, and each monthly edition is an entry in <code>videos.yml</code>. See the dedicated guide: <a href=\"ADDING_MEETUPS.md\">ADDING_MEETUPS.md</a>.\n</details> \n<details><summary>How should I handle a cancelled event?</summary>\n  Cancelled events get an attribute of `status: \"cancelled\"` which will change how they're displayed on the site.\n  We include cancelled events on the site so people have a canonical answer for whether or not an event happened and to communicate an upcoming event is cancelled.\n  This also allows us to answer questions like, \"How many Ruby events were cancelled in 2020?\" or track event cancellations over the years.\n  If an event was planned, website created, and announced, even if it never made it to the venue or dates stage, we'd like to include it on the site as part of our mission to index all Ruby events.\n  However, we defer to the organizer when it comes to questions of how to represent their event, so if the organizer requests we remove a cancelled event from the history, we will.\n</details>\n\n## Submission Process\n\n1. Fork the RubyEvents repository.\n2. Setup your dev environment following the steps in [CONTRIBUTING](/CONTRIBUTING.md).\n3. Create your event file in the appropriate directory.\n4. Run `bin/lint`.\n5. Run `bin/rails db:seed:event_series[<series-slug>]` to seed just one event series.\n6. Run `bin/dev` and review the event on your dev server.\n7. Review \"todos\" panel on the event page to see if any can be resolved.\n8. Submit a pull request.\n\n## Need Help?\n\nIf you have questions about contributing events:\n\n- Open an issue on GitHub\n- Check existing event files for examples\n- Reference this documentation\n\nYour contributions help make RubyEvents a comprehensive resource for the Ruby community!\n"
  },
  {
    "path": "docs/ADDING_INVOLVEMENTS.md",
    "content": "# Adding Involvements to RubyEvents\n\nThis guide explains how to add involvement information (organizers, program committee members, volunteers, etc.) for conferences and events in the RubyEvents platform.\n\n## Overview\n\nInvolvement data is stored in YAML files within the conference/event directories. Each conference can have its own involvements file that defines the people and organisations involved in the event and their roles.\n\n## File Structure\n\nInvolvements are stored in YAML files at:\n```\ndata/{series-name}/{event-name}/involvements.yml\n```\n\nFor example:\n- [`data/sfruby/sfruby-2025/involvements.yml`](/data/sfruby/sfruby-2025/involvements.yml)\n- [`data/rubyconf/rubyconf-2024/involvements.yml`](/data/rubyconf/rubyconf-2024/involvements.yml)\n- [`data/rubyconfth/rubyconfth-2026/involvements.yml`](/data/rubyconfth/rubyconfth-2026/involvements.yml)\n\n## YAML Structure\n\n### Basic Structure\n\n```yaml\n---\n- name: \"Role Name\"\n  users:\n    - Person Name\n    - Another Person\n  organisations:  # Optional\n    - Organisation Name\n```\n\n### Complete Example\n\n```yaml\n---\n- name: \"Organizer\"\n  users:\n    - Irina Nazarova\n  organisations:\n    - Evil Martians\n\n- name: \"Program Committee Member\"\n  users:\n    - Maple Ong\n    - Cameron Dutro\n    - Noel Rappin\n    - Vladimir Dementyev\n\n- name: \"Volunteer\"\n  users:\n    - Daniel Azuma\n    - Todd Kummer\n    - Ken Decanio\n```\n\n## Field Descriptions\n\n### Role Fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | The role title (e.g., \"Organizer\", \"Program Committee Member\", \"MC\") |\n| `users` | Yes | Array of user names who have this role - matched to [speakers.yml](data/speakers.yml) |\n| `organisations` | No | Array of organisation names - matched with existing organisations |\n\n## Common Roles\n\nTypical roles used in involvements:\n\n- **Organizer** - Event organizers\n- **Program Committee Member** - People who review and select talks\n- **MC** - Master of ceremonies / host\n- **Volunteer** - Event volunteers\n- **Scholar** - Scholarship recipients\n- **Guide** - Mentors for scholars\n\n## Step-by-Step Guide\n\n### 1. Check for Existing Involvements File\n\nFirst, check if an involvements file already exists:\n\n```bash\nls data/{series-name}/{event}/involvements.yml\n```\n\n### 2. Create or Edit the Involvements File\n\nIf the file doesn't exist, create it:\n\n```bash\ntouch data/{series-name}/{event}/involvements.yml\n```\n\n### 3. Gather Involvement Information\n\nFor each role, collect:\n- The role title\n- Names of people who have this role\n- Any organisations associated with the role (optional)\n\n### 4. Structure the YAML\n\nCreate the basic template, and replace with your involvement information.\nIf you need to provide additional details for an organisation, you can add that organisation to sponsors.yml.\n(See RubyConf TH 2026 for an example.)\n\n```yaml\n---\n- name: \"Organizer\"\n  users:\n    - Name\n  organisations:\n    - Organisation Name\n\n- name: \"Volunteer\"\n  users:\n    - Volunteer One\n```\n\n## Troubleshooting\n\n### Common Issues\n\n- **Invalid YAML syntax**: Check indentation (use spaces, not tabs)\n- **Missing required fields**: Ensure `name` and `users` are present for each role entry\n- **Empty users list**: Use `users: []` if a role only has organisations\n\n## Submission Process\n\n1. Fork the RubyEvents repository\n2. Setup your dev environment following the steps in [CONTRIBUTING](/CONTRIBUTING.md)\n3. Create your involvements file in the appropriate directory\n4. Run `bin/rails db:seed` (or `bin/rails db:seed:all` if the event happened more than 6 months ago)\n5. Run `bin/lint`\n6. Run `bin/dev` and review the event on your dev server\n7. Submit a pull request\n\n## Need Help?\n\nIf you have questions about contributing involvements:\n- Open an issue on GitHub\n- Check existing involvements files for examples\n- Reference this documentation\n\nYour contributions help make RubyEvents a comprehensive resource for the Ruby community!\n"
  },
  {
    "path": "docs/ADDING_MEETUPS.md",
    "content": "# Adding a Meetup to RubyEvents\n\nThis guide explains how meetups differ from conferences and how to add or update meetup data. For the general process (series, event, assets), start with [ADDING_EVENTS](ADDING_EVENTS.md).\n\n## Meetups vs Conferences\n\n|                 | Conference                                                         | Meetup                                                                                                                        |\n| --------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- |\n| **Event model** | One Event per edition (e.g. RubyConf 2024, RubyConf 2025)          | **One Event per meetup** (e.g. \"ChicagoRuby Meetup\")                                                                          |\n| **Editions**    | Each edition has its own folder and `event.yml`                    | Each **monthly (or periodic) edition is a single entry in `videos.yml`**                                                      |\n| **Videos**      | One `videos.yml` per event edition; each talk is usually one video | One `videos.yml` for the whole meetup; **each entry = one edition** (one meetup night), even if that edition had no recording |\n\nSo for a meetup you have:\n\n- **One** `data/{series-slug}/{event-slug}/event.yml` — describes the meetup itself (name, location, website).\n- **One** `data/{series-slug}/{event-slug}/videos.yml` — list of **editions**. Each item is one meetup night (e.g. \"March 2024\"); it may have no video, one long video (with cues), or multiple child videos.\n\n## Series configuration\n\nIn `data/{series-slug}/series.yml`, set `kind: \"meetup\"` and typically `frequency: \"monthly\"`:\n\n```yaml\n---\nname: \"Amsterdam.rb\"\nwebsite: \"https://www.amsrb.org\"\nkind: \"meetup\"\nfrequency: \"monthly\"\ndefault_country_code: \"NL\"\nlanguage: \"english\"\nyoutube_channel_id: \"UCyExf-593j4hjN_cFCSnr2w\"\n```\n\nThe `\"name\"` will generally be the organizing group, e.g. Cityname.rb or \"Ruby Cityname\".\n\n## Event file (`event.yml`)\n\nThe meetup **event** is a single, ongoing group — one `event.yml` per meetup. Required fields and conventions are the same as in [ADDING_EVENTS](ADDING_EVENTS.md); `kind` should be `\"meetup\"`. You don't need start and end dates.\n\n**Example:** `data/chicagoruby/chicagoruby/event.yml`\n\n```yaml\n---\nid: \"chicagoruby-meetup\"\ntitle: \"ChicagoRuby Meetup\"\nkind: \"meetup\"\nlocation: \"Chicago, IL, United States\"\ndescription: |-\n  ChicagoRuby is a group of developers & designers who use Ruby, Rails, and related tech.\nbanner_background: \"#FFFFFF\"\nfeatured_background: \"#FFFFFF\"\nfeatured_color: \"#D0232B\"\nwebsite: \"https://chicagoruby.org\"\ncoordinates:\n  latitude: 41.88325\n  longitude: -87.6323879\n```\n\nMore examples: [Amsterdam.rb](https://github.com/rubyevents/rubyevents/blob/main/data/amsterdam-rb/amsterdam-rb-meetup/event.yml), [SF Bay Area Ruby](https://github.com/rubyevents/rubyevents/blob/main/data/sf-bay-area-ruby/sf-bay-area-ruby-meetup/event.yml), [Geneva.rb](https://github.com/rubyevents/rubyevents/blob/main/data/geneva-rb/geneva-rb-meetup/event.yml), [Barcelona.rb](https://github.com/rubyevents/rubyevents/blob/main/data/barcelona-rb/barcelona-rb-meetup/event.yml).\n\n---\n\n## Structuring `videos.yml` for meetups\n\nEach **entry** in `videos.yml` is **one edition** of the meetup (one evening/month). The `date` is the meetup date. Depending on how that edition was recorded, use one of the patterns below.\n\n### 1. No video for that meetup edition\n\nThe edition happened but nothing was recorded (or you only have a schedule). Still add one entry so the edition appears on the site; use `video_provider: \"children\"` and list talks with `video_provider: \"not_recorded\"`.\n\n**Real example:** Geneva.rb October 2023 — one edition, one talk, no recording.\n\n**File:** `data/geneva-rb/geneva-rb-meetup/videos.yml` (excerpt)\n\n```yaml\n- id: \"geneva-rb-october-2023\"\n  title: \"Geneva.rb October 2023\"\n  event_name: \"Geneva.rb October 2023\"\n  date: \"2023-10-30\"\n  video_provider: \"children\"\n  video_id: \"geneva-rb-october-2023\"\n  description: |-\n    This first meeting will be fairly informal. We'll do an initial round of introductions.\n    Yannis will then give a short presentation of a new feature of Ruby 3.2: The Data class.\n    https://www.meetup.com/geneva-rb/events/295865704\n  talks:\n    - title: \"New Feature of Ruby 3.2: The Data class\"\n      event_name: \"Geneva.rb October 2023\"\n      date: \"2023-10-03\"\n      speakers:\n        - Yannis Jaquet\n      id: \"yannis-jaquet-geneva-rb-october-2023\"\n      video_id: \"yannis-jaquet-geneva-rb-october-2023\"\n      video_provider: \"not_recorded\"\n      description: |-\n        Yannis will then give a short presentation of a new feature of Ruby 3.2: The Data class.\n```\n\nIf the edition had no talks at all, you can still add a single entry with `video_provider: \"not_recorded\"`, a unique `id` and `video_id`, and an optional `description`; `talks` can be omitted or empty.\n\n---\n\n### 2. One long video for the meetup (cue points)\n\nThe whole edition is one YouTube (or other) video; each “talk” is a segment with `start_cue` and `end_cue`. Use `video_provider: \"youtube\"` (or the real provider) on the edition and `video_provider: \"parent\"` on each talk.\n\n**Real example:** ChicagoRuby Meetup March 2025 — one YouTube video, multiple segments.\n\n**File:** `data/chicagoruby/chicagoruby/videos.yml` (excerpt)\n\n```yaml\n- id: \"chicagoruby-meetup-march-2025-chicagoruby\"\n  title: \"ChicagoRuby Meetup - March 2025\"\n  raw_title: \"ChicagoRuby Meetup at Adler Planetarium (March, 2025)\"\n  event_name: \"ChicagoRuby Meetup - March 2025\"\n  date: \"2025-03-05\"\n  published_at: \"2025-05-22\"\n  description: |-\n    Save the date! On March 5th we'll have the Ruby meetup at Adler Planetarium.\n    Speaker: Ifat Ribon\n    Speaker: Noel Rappin - \"Does Ruby Love Me Back? What Developer Happiness Means in Ruby\"\n    https://www.meetup.com/chicagoruby/events/305503069\n  video_provider: \"youtube\"\n  video_id: \"tA8Omrq0Px4\"\n  talks:\n    - title: \"Intro\"\n      date: \"2025-03-05\"\n      start_cue: \"00:00\"\n      end_cue: \"11:40\"\n      id: \"michelle-yuen-chicagoruby-meetup-march-2025\"\n      video_id: \"michelle-yuen-chicagoruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - March 2025\"\n      speakers:\n        - Michelle Yuen\n\n    - title: \"Build or Buy?\"\n      date: \"2025-03-05\"\n      start_cue: \"11:40\"\n      end_cue: \"41:30\"\n      id: \"ifat-ribon-chicagoruby-meetup-march-2025\"\n      video_id: \"ifat-ribon-chicagoruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - March 2025\"\n      description: |-\n        A practical talk that tackles the classic developer question: Should you build it yourself, use a gem, or go with an existing SaaS solution?\n      speakers:\n        - Ifat Ribon\n\n    - title: \"Does Ruby Love Me Back?\"\n      date: \"2025-03-05\"\n      start_cue: \"48:37\"\n      end_cue: \"1:23:00\"\n      thumbnail_cue: \"50:01\"\n      id: \"noel-rappin-chicagoruby-meetup-march-2025\"\n      video_id: \"noel-rappin-chicagoruby-meetup-march-2025\"\n      video_provider: \"parent\"\n      event_name: \"ChicagoRuby Meetup - March 2025\"\n      description: |-\n        A nostalgic and insightful journey into what makes Ruby uniquely expressive and joyful.\n      speakers:\n        - Noel Rappin\n```\n\nCue format: use timestamps like `\"04:30\"`, `\"1:15:45\"`, or `\"00:00:12\"` (HH:MM:SS). Each talk’s `end_cue` should match the next talk’s `start_cue` (or the end of the stream).\n\n---\n\n### 3. Multiple separate videos (one per talk)\n\nThe edition has several talks, each on its own YouTube (or other) video. Use `video_provider: \"children\"` on the edition and give each talk its own `video_provider: \"youtube\"` (or other) and `video_id`.\n\n**Real example:** Amsterdam.rb December 2019 — one edition, two separate videos.\n\n**File:** `data/amsterdam-rb/amsterdam-rb-meetup/videos.yml` (excerpt)\n\n```yaml\n- id: \"amsterdam-rb-2019-12\"\n  title: \"Amsterdam.rb Meetup December 2019\"\n  raw_title: \"Amsterdam.rb Meetup December 2019 - OPSDEV - Pieter Lange\"\n  date: \"2019-12-17\"\n  event_name: \"Amsterdam.rb Meetup December 2019\"\n  published_at: \"2019-12-17\"\n  video_provider: \"children\"\n  video_id: \"amsterdam-rb-2019-12\"\n  description: \"\"\n  talks:\n    - title: \"How Ruby devs can make the lives of their ops people easier / better / more enjoyable\"\n      raw_title: \"Amsterdam.rb Meetup December 2019 - OPSDEV - Pieter Lange\"\n      date: \"2019-12-17\"\n      event_name: \"Amsterdam.rb Meetup December 2019\"\n      published_at: \"2019-12-17\"\n      video_provider: \"youtube\"\n      id: \"pieter-lange-amsterdamrb-meetup-december-2019\"\n      video_id: \"NgSFh_hGQVk\"\n      speakers:\n        - Pieter Lange\n      description: |-\n        Live stream of the Amsterdam.rb Meetup of the 17th of December.\n        Talk 1: Pieter Lange on how Ruby devs can make the lives of their ops people easier.\n\n    - title: \"The Hippocratic license\"\n      raw_title: \"Amsterdam.rb Meetup December 2019 - Hippocratic license - Noah Berman\"\n      date: \"2019-12-17\"\n      event_name: \"Amsterdam.rb Meetup December 2019\"\n      published_at: \"2019-12-17\"\n      video_provider: \"youtube\"\n      id: \"noah-berman-amsterdamrb-meetup-december-2019\"\n      video_id: \"Yg9LapGCP4I\"\n      speakers:\n        - Noah Berman\n      description: |-\n        Noah Berman on the Hippocratic license, how it came about, what it means, what one should consider.\n```\n\nSummary of `video_provider` for meetup editions:\n\n| Situation                 | Edition `video_provider`     | Talk `video_provider`                 |\n| ------------------------- | ---------------------------- | ------------------------------------- |\n| No recording              | `children`                   | `not_recorded` (or omit talks)        |\n| One long video (cues)     | `youtube` (or real provider) | `parent`                              |\n| Multiple videos           | `children`                   | `youtube` (or real provider) per talk |\n| Planned, not yet recorded | `children`                   | `scheduled`                           |\n\n---\n\nFor seeding and PR steps, use the same process as in [ADDING_EVENTS](ADDING_EVENTS.md#submission-process) (e.g. `bin/rails db:seed:event_series[<series-slug>]`, `bin/lint`, `bin/dev`).\n"
  },
  {
    "path": "docs/ADDING_SCHEDULES.md",
    "content": "# Adding Conference Schedules to RubyEvents\n\nThis guide explains how to add schedule information for conferences and events in the RubyEvents platform.\n\n## Overview\n\nSchedule data is stored in YAML files within the conference/event directories.\nEach conference can have its own schedule file that defines the timing structure and tracks for the event.\n\nThe schedule works in conjunction with the conference's `videos.yml` file - talks are automatically mapped to empty time slots in chronological order. This means talks in `videos.yml` must be ordered according to their actual presentation sequence to display correctly in the schedule.\n\nFor multi-track conferences, each talk in `videos.yml` must have a `track` field that matches one of the track names defined in the schedule.\n\n## File Structure\n\nSchedules are stored in YAML files at:\n```\ndata/{series-name}/{event-name}/schedule.yml\n```\n\nFor example:\n- [`data/rails-world/rails-world-2024/schedule.yml`](https://github.com/rubyevents/rubyevents/blob/main/data/rails-world/rails-world-2024/schedule.yml)\n- [`data/rubyconf/rubyconf-2024/schedule.yml`](https://github.com/rubyevents/rubyevents/blob/main/data/rubyconf/rubyconf-2024/schedule.yml)\n- [`data/brightonruby/brightonruby-2024/schedule.yml`](https://github.com/rubyevents/rubyevents/blob/main/data/brightonruby/brightonruby-2024/schedule.yml)\n\nThe [ScheduleSchema](app/schemas/schedule_schema.rb) defines all valid attributes.\n\n## Generating a schedule\n\nUse the generator to build a basic schedule with talks, breakfast, lunch, and closing party.\n\n```bash\nbin/rails g schedule --event-series rbqconf --event rbqconf-2026 --break_duration 5\n```\n\nThe generator will pull information from the event about days and how many talks need to be scheduled and try to schedule accordingly.\n\nGet help on usage by calling help on the generator.\n\n```bash\nbin/rails g schedule --help\n```\n\n## Customising the file\n\nSchedules are different for every event.\nThis generator will give you a basic schedule with registration, lunch, and talks, but we expect that it will need to be customized by hand.\nIf you have a workshop track, you'll definitely need to customize the final yml.\n\n### Multi-track conferences\n\nIf there are multiple talks happening at the same time, update the slots option.\nThe entire schedule does not need to have the same number of slots.\nLunch and Breakfast can have 1 slot, and the talk slots can have more.\nThe generator supports setting slots on all talk slots.\nFor example, the below command creates 3 timeslots for talks running concurrently.\n\n```bash\nbin/rails g schedule --event-series rubyconf --event rubyconf-2026 --slots 3\n```\n\nSchedules also support tagging talks by track.\n\n**This is not currently supported by the generator and you will need to add it manually.**\n\nAdd a section at the bottom of the yml file with tracks. Each video must map exactly to a track.\nEnsure the color and text_color have enough contrast.\n\n```\ntracks:\n  - name: \"Main Track\"\n    color: \"#000000\"\n    text_color: \"#ffffff\"\n\n  - name: \"Technical Track\"\n    color: \"#0066CC\"\n    text_color: \"#ffffff\"\n\n  - name: \"Community Track\"\n    color: \"#CC6600\"\n    text_color: \"#ffffff\"\n\n  - name: \"Lightning Talks\"\n    color: \"#95BF47\"\n    text_color: \"#ffffff\"\n```\n\n### Unrecorded Activities\n\nTypical schedule-only items (activities without recordings, simple string format):\n- `Registration` - Check-in and badge pickup\n- `Break` - General breaks between sessions\n- `Coffee Break` - Coffee and networking time\n- `Lunch` - Meal break\n- `Breakfast` - Morning refreshments\n- `Opening` - Conference opening remarks (when not recorded)\n- `Closing` - Conference wrap-up (when not recorded)\n- `Welcome` - Welcome reception or gathering\n\nFor non-talk events you can add an items array which will map to each slot.\nItems can be text-only or have a title and description.\nThe ScheduleGenerator includes examples of using items.\n\n```yaml\nitems:\n  - \"Breakfast and Reception\"\n\n  - title: \"Sponsor Showcase\"\n    description: \"Meet our sponsors and learn about their products and services.\"\n```\n\n\n## Step-by-Step Guide\n\n### 1. Check for Existing Schedule File\n\nFirst, check if a schedule file already exists:\n\n```bash\nls data/{series-name}/{event}/schedule.yml\n```\n\n### 2. Gather Schedule Information\n\nFor each day, collect:\n- Official conference dates\n- Start and end times for each session\n- Break and meal times\n- Number of parallel tracks\n- Track names and any color preferences\n- Special events or activities\n\n### 3. Create or Edit the Schedule File\n\nIf the file doesn't exist, create it:\n\n```bash\nbin/rails g schedule --event-series series-slug --event event-slug\n```\n\n### 4. Add Time Slots\n\nFill in the time slots for each day. Remember:\n- Use 24-hour format (e.g., \"14:30\")\n- Include leading zeros (e.g., \"09:00\")\n- Empty slots (no `items`) automatically map to talks from `videos.yml`\n- Slots with `items` are schedule-only activities (breaks, meals, networking, etc.) without individual recordings\n\n**Important**: Empty time slots are filled with talks from the conference's `videos.yml` file in running order. The talks must be ordered chronologically in the `videos.yml` file to match the schedule grid timing.\n\n### 5. Configure Tracks\n\nIf the conference has multiple tracks, define them. **Important**: Track names must exactly match the `track` field values used in the conference's `videos.yml` file:\n\n```yaml\ntracks:\n  - name: \"Main Track\"      # Must match track: \"Main Track\" in videos.yml\n    color: \"#000000\"\n\n  - name: \"Lightning Talks\"  # Must match track: \"Lightning Talks\" in videos.yml\n    color: \"#95BF47\"\n```\n\n### 7. Validate the YAML\n\nEnsure the YAML is properly formatted:\n\n```bash\nbin/lint\n```\n\n## Finding Schedule Information\n\n### Official Sources\n1. **Conference website**: Look for \"Schedule\", \"Agenda\", or \"Program\" pages\n2. **Event platforms**: Check Sessionize, Eventbrite, or Luma event pages\n3. **Mobile apps**: Conference-specific mobile applications\n4. **Social media**: Official conference accounts may post schedules\n\n### Third-party Sources\n- Attendee blog posts with schedule screenshots\n- Video recordings showing schedule information\n- Conference programs (PDF downloads)\n- Archive sites (Wayback Machine) for past events\n\n## Time Format Guidelines\n\n- **Format**: Use 24-hour format (e.g., \"14:30\", not \"2:30 PM\")\n- **Leading zeros**: Include for single-digit hours (e.g., \"09:00\")\n- **Precision**: Most conferences use 15 or 30-minute intervals\n- **Lightning talks**: Can use precise times like \"15:36\" for short presentations\n- **Time zone**: Use conference local time consistently\n\n## Troubleshooting\n\n### Common Issues\n\n- **Invalid YAML syntax**: Check indentation (use spaces, not tabs)\n- **Missing required fields**: Ensure all required properties are present\n- **Time conflicts**: Verify start/end times don't overlap incorrectly\n- **Track mismatch**: Number of tracks should match maximum `slots` used\n- **Track name mismatch**: Track names in `schedule.yml` must exactly match `track` field values in `videos.yml`\n- **Talk order mismatch**: If talks appear in wrong schedule slots, check that `videos.yml` has talks in chronological order\n\n## FAQ\n\n### Schedules in other Languages\n\nWe prefer the English translation of the schedule if provided, otherwise use the content provided by the organizers.\n\n## Submission Process\n\n1. Fork the RubyEvents repository\n2. Setup your dev environment following the steps in [CONTRIBUTING](/CONTRIBUTING.md)\n3. Create your schedule file in the appropriate directory\n4. Run `bin/rails db:seed` (or `bin/rails db:seed:all` if the event happened more than 6 months ago)\n5. Run `bin/lint`\n6. Run `bin/dev` and review the event on your dev server\n7. Submit a pull request\n\n## Need Help?\n\nIf you have questions about contributing schedules:\n- Open an issue on GitHub\n- Check existing schedule files for examples\n- Reference this documentation\n\nYour contributions help make RubyEvents a comprehensive resource for the Ruby community!\n"
  },
  {
    "path": "docs/ADDING_SPONSORS.md",
    "content": "# Adding Sponsors to RubyEvents\n\nThis guide explains how to add sponsor information for conferences and events in the RubyEvents platform.\n\n## Overview\n\nSponsor data is stored in YAML files within the conference/event directories. Each conference can have its own sponsors file that defines sponsor tiers and individual sponsor information.\n\n## File Structure\n\nSponsors are stored in YAML files at:\n```\ndata/{series-name}/{event-name}/sponsors.yml\n```\n\nFor example:\n- [`data/rubykaigi/rubykaigi-2025/sponsors.yml`](https://github.com/rubyevents/rubyevents/blob/main/data/rubykaigi/rubykaigi-2025/sponsors.yml)\n- [`data/railsconf/railsconf-2025/sponsors.yml`](https://github.com/rubyevents/rubyevents/blob/main/data/railsconf/railsconf-2025/sponsors.yml)\n\nAll permitted fields are defined in [SponsorSchema.](/app/schemas/sponsor_schema.rb)\n\n## Common Sponsor Tiers\n\nTypical tier hierarchy (with suggested level values):\n\n1. **Diamond/Title Sponsors** (level: 1) - Highest tier, title sponsors\n2. **Platinum Sponsors** (level: 2) - Premium sponsors\n3. **Gold Sponsors** (level: 3) - Major sponsors\n4. **Silver Sponsors** (level: 4) - Standard sponsors\n5. **Bronze Sponsors** (level: 5) - Entry-level sponsors\n6. **Community Sponsors** (level: 6) - Community supporters\n7. **Media Partners** (level: 7) - Media and promotional partners\n\n## Special Sponsor Types\n\nSome sponsors may have special designations indicated by the `badge` field:\n\n- **Event-specific sponsors**: \"Opening Keynote Sponsor\", \"Closing Party Sponsor\"\n- **Service sponsors**: \"Video Sponsor\", \"Live Stream Sponsor\", \"WiFi Sponsor\"\n- **Amenity sponsors**: \"Coffee Sponsor\", \"Lunch Sponsor\", \"Snack Sponsor\"\n- **Activity sponsors**: \"Workshop Sponsor\", \"Hackathon Sponsor\"\n- **Support sponsors**: \"Scholarship Sponsor\", \"Diversity Sponsor\"\n\n## Generation\n\nGenerate a sponsors.yml in the correct folder using the SponsorsGenerator!\n\n```bash\nbin/rails g sponsors --event-series tropicalrb --event tropical-on-rails-2026\n```\n\nPass multiple sponsors at once, and list the sponsor tier.\nIf there is no tier, it will default to \"Sponsors\".\n\n```bash\nbin/rails g sponsors typesense|Platinum AppSignal|Gold JetRockets|Gold \"Planet Argon|Silver\" --event-series tropicalrb --event tropical-on-rails-2026\n```\n\nIf you are adding a new sponsor to an existing file, you can list all the sponsors as arguments and then use the merge tool when there's a conflict.\nIt'll feel very similar to resolving merge conflicts in git, but for different versions of the generated file.\nExpect improvements to the generator for changes soon!\n\nCheck the usage instructions using help.\n\n```bash\nbin/rails g sponsors --help\n```\n\n## Step-by-Step Guide\n\n### 1. Check for Existing Sponsors File\n\nFirst, check if a sponsors file already exists:\n\n```bash\nls data/{series-name}/{event}/sponsors.yml\n```\n\n### 2. Create or Edit the Sponsors File\n\nIf the file doesn't exist, create it:\n\n```bash\nbin/rails g sponsors --event-series tropicalrb --event tropical-on-rails-2026\n```\n\n### 3. Gather Sponsor Information\n\nFor each sponsor, collect:\n- Official company name\n- Company website URL\n- Logo image URL (preferably high-resolution)\n- Sponsorship tier\n- Any special designations\n\n### 4. Structure the YAML\n\nFill in the logo_url (from the event website) and website for each sponsor.\n\n```yml\n- name: \"AppSignal\"\n  website: \"https://www.appsignal.com/?utm_source=tropicalrb\"\n  slug: \"Appsignal\"\n  logo_url: \"https://framerusercontent.com/images/Ej8aWi209QFR5YrNB6Rl1aN8RqY.png\"\n```\n\nCheck for an existing sponsor in other sponsors files.\nEnsure the company names and slugs match.\nWe prefer the sponsor names to be in English and use latin characters if possible.\nA badge field can be added for special sponsor designations eg. \"Wifi Sponsor\"\n\n### 5. Format your yaml\n\nRun the linter to automatically format and verify all required properties are present.\n\n```bash\nbin/lint\n```\n\n### 5. Run seeds to load data\n\nRun the event series seed to load data.\n\n```bash\nbundle exec rake db:seed:event_series[event-series-slug]\n```\n\n### 6. Review on your dev server\n\nStart the dev server and review the event.\n\n```bash\nbin/dev\n```\n\n## Troubleshooting\n\n### Common Issues\n\n- **Invalid YAML syntax**: Check indentation (use spaces, not tabs)\n- **Missing required fields**: Ensure all required properties are present\n- **Old sponsor logos**: All sponsor logos listed in any sponsors file are associated with a sponsor, and the first logo stored is displayed\n\n## Submission Process\n\n1. Fork the RubyEvents repository\n2. Setup your dev environment following the steps in [CONTRIBUTING](/CONTRIBUTING.md)\n3. Create your sponsors file in the appropriate directory\n4. Run `bin/lint`\n5. Run `bin/rails db:seed` (or `bin/rails db:seed:all` if the event happened more than 6 months ago)\n6. Run `bin/dev` and review the event on your dev server\n7. Submit a pull request\n\n## Need Help?\n\nIf you have questions about contributing sponsors:\n- Open an issue on GitHub\n- Check existing sponsors files for examples\n- Reference this documentation\n\nYour contributions help make RubyEvents a comprehensive resource for the Ruby community!\n"
  },
  {
    "path": "docs/ADDING_UNPUBLISHED_TALKS.md",
    "content": "# Adding Unpublished Talks to RubyEvents\n\nThis guide explains how to add talk information for conferences and events in the RubyEvents platform, including scheduled talks that haven't been recorded yet.\n\n## Overview\n\nTalk data is stored in YAML files within the conference/event directories. Each conference has a videos.yml file that defines all talks, including those that are scheduled, recorded, or pending publication.\n\n## File Structure\n\nTalks are stored in YAML files at:\n```\ndata/{series-name}/{event-name}/videos.yml\n```\n\nFor example:\n- [`/data/ruby-community-conference/ruby-community-conference-winter-edition-2026/videos.yml`](/data/ruby-community-conference/ruby-community-conference-winter-edition-2026/videos.yml)\n- [`data/fukuoka-rubykaigi/fukuoka-rubyistkaigi-05/videos.yml`](/data/fukuoka-rubykaigi/fukuoka-rubyistkaigi-05/videos.yml)\n\nThe full schema for a video is available in [VideoSchema](app/schemas/video_schema.rb).\n\n### 1. Check for Existing Videos File\n\nFirst, check if a videos file already exists:\n\n```bash\nls data/{series-name}/{event-name}/videos.yml\n```\n\n### 2. Create or Edit the Videos File\n\nIf the file doesn't exist, create it by calling the generator with the first talk.\n\n```bash\nbin/rails generate talk --event blue-ridge-ruby-2026 --title \"Your first open-source contribution\" --speaker \"Rachael Wright-Munn\" --description \"\"\n```\n\nCheck the usage instructions using `--help`.\n\n```bash\nbin/rails g talk --help\n```\n\nCall the generator multiple times to add multiple talks to the event.\n\nPass multiple speakers per talk in by passing multiple names to the argument.\n\n```bash\nbin/rails generate talk --event blue-ridge-ruby-2026 --title \"RubyEvents is great!\" --speaker \"Marco Roth\" \"Rachael Wright-Munn\"\n```\n\nUpdate a talk by calling the generator again with new paramaters.\nIt will attempt to match based on the id.\nThe id can be manually passed, but we prefer that it does not change after generation, so it does not update if passed.\nAll values from the existing talk must be included.\n\n```bash\nbin/rails generate talk --event blue-ridge-ruby-2026 --id \"marco-roth-rachael-wright-munn-blue-ridge-ruby-2026\" --title \"RubyEvents is great!\" --speaker \"Rachael Wright-Munn\" --description \"Learn why RubyEvents is great and how to contribute!\"\n```\n\nTo add an empty lightning talk session that will have sub-talks for each lightning talk, use the following command:\n\n```bash\n  bin/rails g talk --event rubycon-2026 --lightning-talks\n```\n\nThe usual parameters, such as title, description, etc are available but not necessary.\n\n### 3. Gather Talk Information\n\nFor each talk, collect:\n- Talk title\n- Speaker name(s)\n- Date of the talk\n- Video URL (if available) or use \"scheduled\" for upcoming talks\n- Description (if available)\n- Any additional resources (slides, blog posts, etc.)\n\n### 5. Verify Speakers Exist\n\nCheck if the speaker exists in [speakers.yml](/data/speakers.yml).\nIf they do, no further action is necessary.\nIf they don't, create a new record for them, and try to include a GitHub handle.\nThe other fields are nice, but GitHub is how we deduplicate, auth, and populate the profile, so try to populate that one if you can find it.\n\n## Troubleshooting\n\n### Common Issues\n\n- **Invalid YAML syntax**: Check indentation (use spaces, not tabs)\n- **Missing required fields**: Ensure `id`, `date`, `video_provider`, and `video_id` are present\n- **Invalid video_provider**: Must be one of the allowed values - [scheduled, not_published, not_recorded, youtube, vimeo, mp4, parent, children]\n- **Invalid resource type**: Check that `additional_resources` use valid type values\n- **Date format**: Use YYYY-MM-DD format for dates\n\n### FAQ\n<details><summary>How do I handle talks that are not in English?</summary>\n  For talks that are not in English, we prefer English descriptions and titles if provided by the event.\n  If those are not provided, use the original language for the description, translate the title to English, and store the title in its original language in original_title.\n  The language field should be the 2 letter language code.\n  This will make it easier for people to find talks in their native language!\n\n  ```yaml\n  - id: \"name-talk-type-event-name-year\"\n    title: \"Talk title in English\"\n    language: \"ja\"\n    original_title: \"Talk title in original language\"\n    description: \"Description in original language\"\n  ```\n</details>\n\n## Submission Process\n\n1. Fork the RubyEvents repository\n2. Setup your dev environment following the steps in [CONTRIBUTING](/CONTRIBUTING.md)\n3. Create or update the videos.yml file in the appropriate directory\n4. Run `bin/lint`\n5. Run `bin/rails db:seed` (or `bin/rails db:seed:all` if the event happened more than 6 months ago)\n6. Run `bin/dev` and review the event on your dev server\n7. Submit a pull request\n\n## Need Help?\n\nIf you have questions about contributing talks:\n- Open an issue on GitHub\n- Check existing videos.yml files for examples (e.g., `data/rubyconfth/rubyconfth-2026/videos.yml`)\n- Reference this documentation\n\nYour contributions help make RubyEvents a comprehensive resource for the Ruby community!\n"
  },
  {
    "path": "docs/ADDING_VENUES.md",
    "content": "# Adding Conference Venues to RubyEvents\n\nThis guide explains how to add venue information for conferences and events in the RubyEvents platform.\n\n## Overview\n\nVenue data is stored in YAML files within the conference/event directories.\nEach conference can have its own venue file that describes the event venue, hotel information, and any secondary locations.\n\n## File Structure\n\nVenues are stored in YAML files at:\n\n```\ndata/{series-name}/{event-name}/venue.yml\n```\n\nFor example:\n\n- [`data/sfruby/sfruby-2025/venue.yml`](https://github.com/rubyevents/rubyevents/blob/main/data/sfruby/sfruby-2025/venue.yml)\n- [`data/railsconf/railsconf-2025/venue.yml`](https://github.com/rubyevents/rubyevents/blob/main/data/railsconf/railsconf-2025/venue.yml)\n- [`data/xoruby/xoruby-atlanta-2025/venue.yml`](https://github.com/rubyevents/rubyevents/blob/main/data/xoruby/xoruby-atlanta-2025/venue.yml)\n\nAll permitted fields are defined in [VenueSchema.](/app/schemas/venue_schema.rb)\n\n## Generation\n\nGenerate a venue.yml using the [VenueGenerator](/lib/generators/venue/venue_generator.rb)!\n\n```bash\nbin/rails g venue --event-series=tiny-ruby-conf --event=tiny-ruby-conf-2026 --name=\"Korjaamo Kino cinema\" --address \"Töölönkatu 51 A-B, 00250 Helsinki\"\n```\n\n> [!IMPORTANT]\n> The generator uses Geolocator to geocode the address, and fetch coordinates.\n> For more accurate results, set your GEOLOCATE_API_KEY in [.env](/.env) to a google api key.\n> Otherwise nominatim and open street map will be used for geolocation.\n\nThere are multiple optional sections in the venue information, including locations, hotels, rooms, spaces, accessbility, and nearby.\n\nTo include or exclude these sections, pass flags to the generator.\n\nThis includes all sections:\n\n```bash\nbin/rails g venue --event-series=tiny-ruby-conf --event=tiny-ruby-conf-2026 --name=\"Korjaamo Kino cinema\" --address \"Töölönkatu 51 A-B, 00250 Helsinki\" --accessbility --hotels --nearby --locations --rooms --spaces\n```\n\nThis includes only primary venue information:\n\n```bash\nbin/rails g venue --event-series=tiny-ruby-conf --event=tiny-ruby-conf-2026 --name=\"Korjaamo Kino cinema\" --address \"Töölönkatu 51 A-B, 00250 Helsinki\" --no-accessbility --no-hotels --no-nearby --no-locations --no-rooms --no-spaces\n```\n\nCheck the usage instructions using `--help`.\n\n```bash\nbin/rails g venue --help\n```\n\n## Step-by-Step Guide\n\n### 1. Check for Existing Venue File\n\nFirst, check if a venue file already exists:\n\n```bash\nls data/{series-name}/{event}/venue.yml\n```\n\n### 2. Create or Edit the Venue File\n\nIf the file doesn't exist, create it:\n\n```bash\nbin/rails g venue --event-series=tiny-ruby-conf --event=tiny-ruby-conf-2026 --name=\"Korjaamo Kino cinema\" --address \"Töölönkatu 51 A-B, 00250 Helsinki\"\n```\n\n### 3. Gather Venue Information\n\nCollect:\n\n- Event venue information\n- Event hotel information\n- Any additional locations information\n\n### 4. Structure the YAML\n\nFill in the template with all relevant information, delete any extraneous fields.\n\n### 5. Add Optional Location Details\n\n#### Accessibility information\n\n```yaml\naccessibility:\n  wheelchair:\n  elevators:\n  accessible_restrooms:\n  notes:\n```\n\n#### Nearby location details from the event organizers\n\n```yaml\nnearby:\n  public_transport:\n  parking:\n```\n\n#### Meeting rooms in the venue\n\n```yaml\nrooms:\n  - name:\n    floor:\n    capacity:\n    instructions:\n```\n\n#### Spaces in the venue\n\n```yaml\nspaces:\n  - name:\n    floor:\n    instructions:\n```\n\n#### Additional Locations\n\nThis is an array of additional event locations such as afterparties or secondary venues.\n\n```yaml\nlocations:\n  - name:\n    kind:\n    description:\n    address:\n    distance:\n    url:\n    coordinates:\n      latitude:\n      longitude:\n    maps:\n      google:\n      apple:\n```\n\n#### Hotel information\n\n```yaml\nhotels:\n  - name:\n    kind:\n    description:\n    address:\n    url:\n    distance:\n    coordinates:\n      latitude:\n      longitude:\n    maps:\n      google:\n      apple:\n```\n\n### 6. Format your yaml\n\nRun the linter to automatically format and verify all required properties are present.\n\n```bash\nbin/lint\n```\n\n### 5. Run seeds to load data\n\nRun the event series seed to load data.\n\n```bash\nbundle exec rake db:seed:event_series[event-series-slug]\n```\n\n### 6. Review on your dev server\n\nStart the dev server and review the event.\n\n```bash\nbin/dev\n```\n\n> [!IMPORTANT]\n> Verify the address is correct in the venue map, and all links go to the correct venue.\n\n## Finding Schedule Information\n\n### Official Sources\n\n1. **Conference website**: Look for \"Venue\" or \"About\" pages\n2. **Event platforms**: Check Sessionize, Eventbrite, or Luma event pages\n3. **Mobile apps**: Conference-specific mobile applications\n4. **Social media**: Official conference accounts may post venue\n\n### Third-party Sources\n\n- Attendee blog posts with venue information\n- Video recordings showing venue information\n- Conference programs (PDF downloads)\n- Archive sites (Wayback Machine) for past events\n\n## Troubleshooting\n\n### Common Issues\n\n- **Invalid YAML syntax**: Check indentation (use spaces, not tabs)\n- **Missing required fields**: Ensure all required properties are present\n- **Stringify postal_code**: postal_code must be a string\n- **No newlines in address**: Ensure there are no newlines in the address\n\n## Submission Process\n\n1. Fork the RubyEvents repository\n2. Setup your dev environment following the steps in [CONTRIBUTING](/CONTRIBUTING.md)\n3. Create your venue file in the appropriate directory\n4. Run `bin/lint`\n5. Run `bin/rails db:seed` (or `bin/rails db:seed:all` if the event happened more than 6 months ago)\n6. Run `bin/dev` and review the event on your dev server\n7. Submit a pull request\n\n## Need Help?\n\nIf you have questions about contributing venues:\n\n- Open an issue on GitHub\n- Check existing venue files for examples\n- Reference this documentation\n\nYour contributions help make RubyEvents a comprehensive resource for the Ruby community!\n"
  },
  {
    "path": "docs/ADDING_VIDEOS.md",
    "content": "# Adding Conference/Meetup Videos to RubyEvents\n\nThis guide provides steps on how to contribute new videos to the platform. If you wish to make a contribution, please submit a Pull Request (PR) with the necessary information detailed below.\n\nThe videos file represents talks that have happened at the event, whether they were recorded or not.\n\nThere are a few scripts available to help you build those data files by scraping the YouTube API. To use them, you must first create a YouTube API Key and add it to your .env file. Here are the guidelines to get a key https://developers.google.com/youtube/registering_an_application\n\n```\nYOUTUBE_API_KEY=some_key\n```\n\n## Adding a New Conference Series\n\n### Step 1 - Create the Series\n\nIf you do not already have an event series, create a new folder for your series and add a `series.yml` file:\n\n```bash\nmkdir -p data/my-conference\n```\n\nCreate `data/my-conference/series.yml`:\n\n```yaml\n---\nname: My Conference\nwebsite: https://myconference.org/\ntwitter: myconference\nyoutube_channel_name: myconference\nkind: conference  # conference, meetup, retreat, or hackathon\nfrequency: yearly # yearly, monthly, quarterly, etc.\nlanguage: english\ndefault_country_code: US\nyoutube_channel_id: \"\"  # Will be filled by prepare_series.rb\nplaylist_matcher: \"\"    # Optional text to filter playlists\n```\n\nThen run this script to fetch the YouTube channel ID:\n\n```bash\nbin/rails runner scripts/prepare_series.rb my-conference\n```\n\n### Step 2 - Create Events from YouTube Playlists\n\nIf your conference videos are organized as YouTube playlists (one playlist per event), run:\n\n```bash\nbin/rails runner scripts/create_events.rb my-conference\n```\n\nThis will create `event.yml` files for each playlist found. The script skips events that already exist.\n\n**Multi-Event Channels**\n\nSome YouTube channels host multiple conferences (e.g., Confreaks hosts both RubyConf and RailsConf). Use `playlist_matcher` in your `series.yml` to filter playlists:\n\n```yaml\n# data/railsconf/series.yml\nname: RailsConf\nyoutube_channel_id: UCWnPjmqvljcafA0z2U1fwKQ\nplaylist_matcher: rails  # Only matches playlists with \"rails\" in the title\n```\n\n### Step 3 - Extract Videos\n\nOnce your events are set up, extract the video information:\n\n```bash\n# Extract videos for all events in a series\nbin/rails runner scripts/extract_videos.rb my-conference\n\n# Or extract videos for a specific event\nbin/rails runner scripts/extract_videos.rb my-conference my-conference-2024\n```\n\n### Step 4 - Review and Edit\n\nReview the generated files and make any necessary edits:\n\n**event.yml** - Verify:\n- Event dates (`start_date`, `end_date`)\n- Location\n- Description\n\n**videos.yml** - Each video entry must have:\n- `speakers`: Array of speaker names (required - videos without speakers won't display)\n- `date`: Date the talk was presented in YYYY-MM-DD format (required)\n\nExample video entry:\n```yaml\n- title: \"What Rust can teach us about Ruby\"\n  event_name: \"RubyConf 2025\"\n  published_at: \"2025-10-12\"\n  description: \"A presentation about Rust and Ruby\"\n  video_provider: youtube\n  video_id: \"abc123xyz\"\n  speakers:\n    - \"Jane Doe\"\n  date: \"2025-10-11\"\n```\n\n## Custom Video Metadata Parsers\n\nThe default `YouTube::VideoMetadata` class tries to extract speaker names from video titles.\nIf this doesn't work well for your conference, you can create a custom parser and specify it in `event.yml`:\n\n```yaml\n# data/rubyconf-au/rubyconf-au-2015/event.yml\n---\nid: PL9_jjLrTYxc2uUcqG2wjZ1ppt-TkFG-gm\ntitle: RubyConf AU 2015\nmetadata_parser: \"YouTube::VideoMetadata::RubyConfAu\"\n```\n\n## Troubleshooting\n\n**'Psych::Parser#_native_parse': (<unknown>): found unknown escape character while parsing a quoted scalar at line 10 column 19 (Psych::SyntaxError)** - something is malformed - run `bin/lint` for a clearer error\n**formatter.mjs:29 const isValueString = typeof value.value === 'string'** - make sure your speakers and dates are valid values\n\n## Submission Process\n\n1. Fork the RubyEvents repository\n2. Setup your dev environment following the steps in [CONTRIBUTING](/CONTRIBUTING.md)\n3. Create your videos file in the appropriate directory\n4. Run `bin/rails db:seed` (or `bin/rails db:seed:all` if the event happened more than 6 months ago)\n5. Run `bin/lint`\n6. Run `bin/dev` and review the event on your dev server\n7. Submit a pull request\n\n## Need Help?\n\nIf you have questions about contributing events:\n- Open an issue on GitHub\n- Check existing event files for examples\n- Reference this documentation\n\nYour contributions help make RubyEvents a comprehensive resource for the Ruby community!"
  },
  {
    "path": "docs/ADDING_VISUAL_ASSETS.md",
    "content": "# Adding Visual Assets to Events\n\nThis guide explains how to add and manage visual assets (images) for events in RubyEvents.\n\n## Overview\n\nEach event can have multiple visual assets that are used throughout the platform for different purposes. These assets are stored in the `app/assets/images/events/{organization}/{event}/` directory.\n\n## Asset Types\n\nRubyEvents supports the following asset types:\n\n| Asset Type | Dimensions | Purpose |\n|------------|------------|---------|\n| `avatar.webp` | 256×256 | Small circular profile images, used in listings |\n| `banner.webp` | 1300×350 | Wide header images for event pages |\n| `card.webp` | 600×350 | Card thumbnails used in grid layouts |\n| `featured.webp` | 615×350 | Featured event displays on homepage |\n| `poster.webp` | 600×350 | Event poster/promotional image |\n| `sticker.webp` | 350×350 | Digital sticker graphics (can have multiple: sticker-1.webp, sticker-2.webp, etc.) |\n| `stamp.webp` | 512×512 | Digital stamp graphics (can have multiple: stamp.webp, stamp-1.webp, etc.) |\n\n## File Location\n\nAssets should be placed in:\n```\napp/assets/images/events/{organization-slug}/{event-slug}/\n```\n\nFor example:\n```\napp/assets/images/events/railsconf/railsconf-2025/\n├── avatar.webp\n├── banner.webp\n├── card.webp\n├── featured.webp\n├── poster.webp\n├── sticker.webp\n└── stamp.webp\n```\n\n## Image Format\n\n- All images must be in **WebP format** for optimal performance\n- Images should be exported at the exact dimensions specified above\n- Use `save-for-web` optimization when exporting\n\n## Brand Colors\n\nIn addition to images, you can specify brand colors for your event in its `event.yml` file:\n\n```yaml\n# data/railsconf/railsconf-2025/event.yml\n---\nid: railsconf-2025\ntitle: RailsConf 2025\n# ... other fields ...\nbanner_background: \"#FF0000\"      # Background color for banner\nfeatured_background: \"#000000\"    # Background color for featured display\nfeatured_color: \"#FFFFFF\"         # Text color for featured display\n```\n\nThese colors support:\n- Hex colors (e.g., `#FF0000`) - don't forget the `#`\n- RGB/RGBA colors (e.g., `rgb(255, 0, 0)`)\n- CSS gradients (e.g., `linear-gradient(90deg, #FF0000, #0000FF)`)\n\n## Automated Asset Generation\n\nYou can automatically generate all core assets from a single logo image using the `event:generate_assets` rake task. This is the fastest way to create consistent assets for a new event.\n\n### Prerequisites\n\n- **gum** - Interactive CLI tool (`brew install gum` on macOS)\n- **ImageMagick 7+** - Image processing (`brew install imagemagick` on macOS)\n- A logo image (PNG, SVG, or JPG with transparent background works best)\n- The event must already exist in the database\n\nThe wizard will check for these dependencies and provide install instructions if missing.\n\n### Usage\n\nRun the interactive wizard:\n\n```bash\nbin/rails event:generate_assets\n```\n\n### Example Session\n\n```\n==================================================\n  Event Asset Generator\n==================================================\n\nEvent slug (e.g., railsconf-2025): railsconf-2025\n  ✓ Found: RailsConf 2025\nLogo path: ~/Downloads/railsconf-logo.png\n  ✓ Found: 1024x1024 PNG\nBackground color [#000000]: #CC342D\n  ✓ Background: #CC342D\nText color [#FFFFFF - auto]:\n  ✓ Text color: #FFFFFF (auto-calculated)\n\n--------------------------------------------------\nSummary:\n  Event:      RailsConf 2025 (railsconf-2025)\n  Logo:       /Users/you/Downloads/railsconf-logo.png\n  Background: #CC342D\n  Text color: #FFFFFF\n\nAssets to generate:\n  - banner.webp (1300x350)\n  - card.webp (600x350)\n  - avatar.webp (256x256)\n  - featured.webp (615x350)\n  - poster.webp (600x350)\n\nWill update: data/railsconf/railsconf-2025/event.yml\n--------------------------------------------------\n\nProceed with asset generation? [Y/n]: y\n```\n\n### What It Does\n\n1. **Generates all core image assets:**\n   - `avatar.webp` (256×256)\n   - `banner.webp` (1300×350)\n   - `card.webp` (600×350)\n   - `featured.webp` (615×350)\n   - `poster.webp` (600×350)\n\n2. **Updates `event.yml` with brand colors:**\n   - `banner_background`\n   - `featured_background`\n   - `featured_color`\n\n### Tips for Best Results\n\n- **Use a logo with transparent background** - The logo will be composited over the solid background color\n- **Use high-resolution source logos** - At least 1000px wide for best quality\n- **Square logos work best** - They scale well across all asset dimensions\n- **Choose contrasting colors** - If not specifying text color, the task auto-calculates white or black based on background luminance\n- **SVG logos produce the sharpest results** - They scale without quality loss\n- **SVG logos sometimes don't work** - If imagemagick can't open it, try converting to PNG first.\n\n### After Generation\n\nThe generated assets are basic placeholders with centered logos. For events that need more elaborate designs:\n\n1. Use the generated assets as a starting point\n2. Edit them in your design tool (Sketch, Figma, etc.)\n3. Re-export as WebP at the same dimensions\n4. Replace the generated files\n\n## Exporting Assets from Sketch\n\nIf you're using the RubyEvents Sketch file, you can export assets using rake tasks:\n\n### Export all assets for a specific event:\n```bash\nrake export_assets[event-slug]\n```\n\n### Export all assets for all events:\n```bash\nrake export_assets\n```\n\n### Export stickers:\n```bash\nrake export_stickers\n```\n\n### Export stamps by country code:\n```bash\nrake export_stamps[US]\n```\n\n## Viewing All Assets\n\nYou can view all event assets and their status at:\n[https://rubyevents.org/pages/assets](https://rubyevents.org/pages/assets)\n\n\n## Default/Fallback Assets\n\nIf an event doesn't have specific assets, the system will fall back to:\n1. Organization-level defaults (in `app/assets/images/events/{organization}/default/`)\n2. Global defaults (in `app/assets/images/events/default/`)\n\n## Step-by-Step Guide\n\n### 1. Prepare Your Images\n\nCreate images at the correct dimensions in your design tool (Sketch, Figma, etc.).\n\n### 2. Export as WebP\n\nExport each image as WebP format with web optimization enabled.\n\n### 3. Name Your Files\n\nUse the exact filenames specified above:\n- `avatar.webp`\n- `banner.webp`\n- `card.webp`\n- `featured.webp`\n- `poster.webp`\n- `sticker.webp` (or `sticker-1.webp`, `sticker-2.webp` for multiple)\n- `stamp.webp` (or `stamp-1.webp`, `stamp-2.webp` for multiple)\n\n### 4. Place Files in Correct Directory\n\nCreate the directory structure if it doesn't exist:\n```bash\nmkdir -p app/assets/images/events/{organization-slug}/{event-slug}\n```\n\nCopy your assets to this directory.\n\n### 5. Add Brand Colors\n\nEdit the event's `event.yml` file at `data/{organization}/{event-slug}/event.yml` to add brand colors:\n\n```yaml\nbanner_background: \"#your-color\"\nfeatured_background: \"#your-color\"\nfeatured_color: \"#your-color\"\n```\n\n### 6. Verify Assets\n\nVisit https://rubyevents.org/pages/assets (or your local development server at http://localhost:3000/pages/assets) to verify all assets are displaying correctly.\n\n## Troubleshooting\n\n### Assets not appearing\n- Check the file path is correct\n- Verify the filename matches exactly (including `.webp` extension)\n- Ensure proper file permissions\n- Clear asset cache with `rails assets:clobber`\n\n### Wrong dimensions\n- Re-export the image at the correct dimensions\n- Don't rely on CSS to resize images\n\n### Color not applied\n- Verify the color value in `event.yml`\n- Check the color format is valid CSS\n- Restart the server after changing `event.yml`\n\n## Submission Process\n\n1. Fork the RubyEvents repository\n2. Setup your dev environment following the steps in [CONTRIBUTING](/CONTRIBUTING.md)\n3. Create your assets in the appropriate directory\n4. Run `bin/dev` and review the event on your dev server\n5. Submit a pull request\n\n## Need Help?\n\nIf you have questions about contributing assets:\n- Open an issue on GitHub\n- Check existing assets for examples\n- Reference this documentation\n\nYour contributions help make RubyEvents a comprehensive resource for the Ruby community!\n"
  },
  {
    "path": "docs/FIXING_PROFILE_NAMES.md",
    "content": "# Description\n\nFixing speaker/profile names is a pretty common occurance, and we have a few different strategies for it.\n\n## Common Truths\n\n- We use the GitHub profile as a unique identifier throughout the site.\n- If the name, slug, or GitHub stays the same, we find and update the existing record.\n- Aliases ensure that urls using the old name are redirected, we strongly encourage their use.\n- Aliases also ensure future or previous talks being uploaded are associated with the right user.\n- Test your changes by running `bundle exec rake db:seed:speakers`.\n\n### Creating an alias\n\nIn this example, we set up two aliases for Matz.\nAll future talks with Matz or Yukihiro 'Matz' Matsumoto will redirect to Yukihiro \"Matz\" Matsumoto.\n\n```yaml\n- name: \"Yukihiro \\\"Matz\\\" Matsumoto\"\n  github: \"matz\"\n  slug: \"yukihiro-matz-matsumoto\"\n  aliases:\n    - name: \"Matz\"\n      slug: \"matz\"\n    - name: \"Yukihiro 'Matz' Matsumoto\"\n      slug: \"yukihiro-matz-matsumoto\"\n```\n\n## Duplicate names in speakers.yml\n\nIf there are two instances of a user in `speakers.yml`, we create two users.\n\n- De-dupe the `/data/speakers.yml` - there should be one speaker with a name and GitHub handle.\n  - Create an alias in `speakers.yml` if the duplicated name is likely to be used again.\n- Update all talks to use the name of the de-duped speaker.\n- After merge:\n  - In the admin, delete the old user.\n  - Run the seeds on production\n\n## Two different GitHub profiles\n\n- Pick one canonical GitHub profile and put it in `speakers.yml`\n  - Add an alias for the old GitHub profile so it redirects to the new one\n- Remove the other speaker\n- All talks should reference the name from that profile\n\n## Missing GitHub profile on Speaker - Signed up as user\n\n- Update `/data/speakers.yml` with the GitHub handle\n- Run `bundle exec rake db:seed` to ensure there are no duplicates\n- Run seeds again in production\n\n## Updating your name\n\n- Update the name in `speakers.yml`\n- Update all references in the `videos.yml` and `involvements.yml` to the new name\n- Create an alias from the old name to redirect to the new name\n"
  },
  {
    "path": "lib/assets/.keep",
    "content": ""
  },
  {
    "path": "lib/authenticator.rb",
    "content": "module Authenticator\n  class AdminConstraint\n    def matches?(request)\n      session = Session.find_by_id(request.cookie_jar.signed[:session_token])\n\n      if session\n        session.user.admin?\n      else\n        false\n      end\n    end\n  end\n\n  class UserConstraint\n    def matches?(request)\n      session = Session.find_by_id(request.cookie_jar.signed[:session_token])\n\n      if session\n        session.user\n      else\n        false\n      end\n    end\n  end\n\n  class ForbiddenConstraint\n    def matches?(request) = false\n  end\n\n  ROLES = {\n    admin: AdminConstraint,\n    user: UserConstraint\n  }\n\n  def authenticate(role, &)\n    constraints(constraint_for(role), &)\n  end\n\n  private\n\n  def constraint_for(role)\n    ROLES[role.to_sym]&.new || ForbiddenConstraint.new\n  end\nend\n"
  },
  {
    "path": "lib/generators/cfp/USAGE",
    "content": "Description:\n    Generate a CFP for an event in an event series.\n\nExample:\n    bin/rails generate cfp --event-series=rubyconf --event=rubyconf-2026\n\n    This will create:\n        A CFP file in the correct directory for the event series and event.\n        The file will be pre-populated with a template for the CFP.\n        Call it twice with the same cfp name to update the existing CFP.\n        Call it twice with a different cfp name to append a new CFP to the end of the file.\n"
  },
  {
    "path": "lib/generators/cfp/cfp_generator.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"generators/event_base\"\n\nclass CfpGenerator < Generators::EventBase\n  source_root File.expand_path(\"templates\", __dir__)\n\n  class_option :name, type: :string, desc: \"CFP name\", default: \"Call for Proposals\", group: \"Fields\"\n  class_option :link, type: :string, desc: \"CFP link\", default: \"https://TODO.example.com/cfp\", group: \"Fields\"\n  class_option :open_date, type: :string, desc: \"CFP open date (YYYY-MM-DD)\", default: \"2026-01-01\", group: \"Fields\"\n  class_option :close_date, type: :string, desc: \"CFP close date (YYYY-MM-DD)\", default: \"2026-12-31\", group: \"Fields\"\n\n  def copy_cfp_file\n    cfp_file = File.join([event_directory, \"cfp.yml\"])\n    template \"header.yml.tt\", cfp_file unless File.exist?(cfp_file)\n\n    if File.read(cfp_file).include?(options[:name])\n      gsub_file cfp_file, /- name: \"#{options[:name]}\"\\s*(link: \"[^\"]*\"\\s*)(open_date: \"[^\"]*\"\\s*)?(close_date: \"[^\"]*\"\\s*)?/, template_content(\"cfp.yml.tt\")\n    else\n      append_to_file cfp_file, template_content(\"cfp.yml.tt\")\n    end\n  end\nend\n"
  },
  {
    "path": "lib/generators/cfp/templates/cfp.yml.tt",
    "content": "\n- name: \"<%= options[:name] %>\"\n  link: \"<%= options[:link] %>\"\n  open_date: \"<%= options[:open_date] %>\"\n  close_date: \"<%= options[:close_date] %>\"\n"
  },
  {
    "path": "lib/generators/cfp/templates/header.yml.tt",
    "content": "# docs/ADDING_CFPS.md\n---"
  },
  {
    "path": "lib/generators/event/USAGE",
    "content": "Description:\n    Generates an event.yml file for a new event in an event series.\n    Use this to add a new conference, meetup, workshop, or other Ruby event.\n    Can optionally generate a venue.yml file if venue details are provided.\n\nExample:\n    bin/rails generate event --event-series=rubyconf --event=rubyconf-2026 --name=\"RubyConf 2026\"\n\n    This will create:\n        /data/rubyconf/rubyconf-2026/event.yml\n\n    bin/rails generate event --event-series=tropicalrb --event=tropical-on-rails-2027 \\\n      --name=\"Tropical on Rails 2027\" --start-date=2027-04-01 --end-date=2027-04-03 \\\n      --venue-name=\"Hotel Grande\" --venue-address=\"R. Olimpíadas, 205 - Vila Olímpia, São Paulo - SP, 04551-000\"\n\n    This will create:\n        /data/tropicalrb/tropical-on-rails-2027/event.yml\n        /data/tropicalrb/tropical-on-rails-2027/venue.yml\n"
  },
  {
    "path": "lib/generators/event/event_generator.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"generators/event_base\"\n\nclass EventGenerator < Generators::EventBase\n  source_root File.expand_path(\"templates\", __dir__)\n  class_option :name, type: :string, desc: \"Event name\", group: \"Fields\", required: true\n  class_option :description, type: :string, desc: \"Event description\", default: \"TODO Event description\", group: \"Fields\"\n  class_option :kind, type: :string, enum: Event.kinds.keys, desc: \"Event kind (e.g. conference, meetup, workshop)\", default: \"conference\", group: \"Fields\"\n  class_option :start_date, type: :string, desc: \"Start date (YYYY-MM-DD)\", default: \"2026-01-01\", group: \"Fields\"\n  class_option :end_date, type: :string, desc: \"End date (YYYY-MM-DD)\", default: \"2026-12-31\", group: \"Fields\"\n  class_option :tickets_url, type: :string, desc: \"URL to purchase tickets (e.g., Tito, Eventbrite, Luma)\", default: \"https://www.TODO.example.com/tickets\", group: \"Fields\"\n  class_option :website, type: :string, desc: \"Event website URL\", default: \"https://www.TODO.example.com\", group: \"Fields\"\n  class_option :last_edition, type: :boolean, desc: \"Is this the last edition?\", default: false, group: \"Fields\"\n  # Location Details\n  class_option :online, type: :boolean, desc: \"Is this an online-only event?\", default: false, group: \"Fields\"\n  class_option :location, type: :string, desc: \"Location (City, Country)\", group: \"Fields\"\n  class_option :venue_name, type: :string, desc: \"TODO Venue name\", default: \"TODO\", group: \"Fields\"\n  class_option :venue_address, type: :string, desc: \"Venue address\", default: \"123 TODO St, City, State, ZIP, Country\", group: \"Fields\"\n  # TODO: Save YouTube playlists and videos for another day\n  # TODO: Save \"with-series\" option for another day\n\n  def initialize_values\n    @year = Date.parse(options[:start_date]).year\n    @geocoded_address = geocode_address(name: options[:venue_name], address: options[:venue_address] || options[:location])\n    @location = if options[:online]\n      \"online\"\n    else\n      options[:location].presence || [@geocoded_address.city, @geocoded_address.state, @geocoded_address.country_code].compact.join(\", \").presence || \"Earth\"\n    end\n  end\n\n  def copy_event_file\n    template \"event.yml.tt\", File.join([\"data\", options[:event_series], options[:event], \"event.yml\"])\n  end\n\n  def generate_venue_file\n    return if options[:online]\n    return if options[:venue_name].blank? && options[:venue_address].blank?\n    return if options[:venue_name] == \"TODO Venue name\" && options[:venue_address] == \"123 TODO St, City, State, ZIP, Country\"\n\n    Rails::Generators.invoke \"venue\", [\n      \"--event-series\", options[:event_series],\n      \"--event\", options[:event],\n      \"--name\", options[:venue_name],\n      \"--address\", options[:venue_address]\n    ], behavior: :invoke, destination_root: destination_root\n  end\nend\n"
  },
  {
    "path": "lib/generators/event/templates/event.yml.tt",
    "content": "# docs/ADDING_EVENTS.md\n---\nid: \"<%= options[:event] %>\"\ntitle: \"<%= options[:name] %>\"\nkind: \"<%= options[:kind] %>\"\ndescription: |-\n  <%= options[:description] %>\nstart_date: \"<%= options[:start_date] %>\"\nend_date: \"<%= options[:end_date] %>\"\nyear: <%= @year %>\ntickets_url: \"<%= options[:tickets_url] %>\"\nwebsite: \"<%= options[:website] %>\"\n<%- if options[:last_edition] -%>\nlast_edition: true\n<%- end -%>\nlocation: \"<%= @location %>\"\ncoordinates:\n<%- if options[:online] -%>\n  false\n<%- else -%>\n  latitude: <%= @geocoded_address.latitude %>\n  longitude: <%= @geocoded_address.longitude %>\n<%- end -%>\n"
  },
  {
    "path": "lib/generators/event_base.rb",
    "content": "require \"rails/generators\"\n\nmodule Generators\n  class EventBase < Rails::Generators::Base\n    class_option :event_series, type: :string, desc: \"Event series folder name - defaults to the series of the event\", required: false, group: \"Fields\"\n    class_option :event, type: :string, desc: \"Event folder name\", required: true, aliases: [\"-e\"], group: \"Fields\"\n\n    GeocodedAddress = Struct.new(:street_address, :city, :state, :postal_code, :country, :country_code, :latitude, :longitude)\n\n    def event_directory\n      @event_directory ||= File.join(destination_root, \"data\", event_series_slug, options[:event])\n    end\n\n    def event_series_slug\n      @series_slug ||= options[:event_series] || static_event&.series_slug\n    end\n\n    def static_event\n      @static_event ||= Static::Event.find_by_slug options[:event]\n    end\n\n    private\n\n    def destination_path(path)\n      File.join(destination_root, path)\n    end\n\n    def geocode_address(name:, address:)\n      if address != \"123 TODO St, City, State, ZIP, Country\" || name != \"TODO Venue name\"\n        # Combine venue name and address for better accuracy\n        search = [name, address].compact.join(\", \")\n        geocode_results = Geocoder.search(search)\n        # Nominatim works better with separate queries - doesn't find the combined one\n        geocode_results = Geocoder.search(address) if geocode_results.empty?\n        geocode_results = Geocoder.search(name) if geocode_results.empty?\n        # Nominatim works better with just the street address\n        geocode_results = Geocoder.search(address.split(\",\")[0]) if geocode_results.empty?\n      end\n\n      geocode_results&.first || GeocodedAddress.new(\n        street_address: \"123 Main St\",\n        city: \"City\",\n        state: \"State\",\n        postal_code: \"ZIP\",\n        country: \"Country\",\n        country_code: \"CC\",\n        latitude: 0.0,\n        longitude: 0.0\n      )\n    end\n\n    def template_content(source, &block)\n      source = File.expand_path(find_in_source_paths(source.to_s))\n      context = instance_eval(\"binding\", __FILE__, __LINE__)\n      capturable_erb = CapturableERB.new(::File.binread(source), trim_mode: \"-\", eoutvar: \"@output_buffer\")\n      content = capturable_erb.tap do |erb|\n        erb.filename = source\n      end.result(context)\n      content = yield(content) if block\n      content\n    end\n  end\nend\n\nclass CapturableERB < ERB\n  def set_eoutvar(compiler, eoutvar = \"_erbout\")\n    compiler.put_cmd = \"#{eoutvar}.concat\"\n    compiler.insert_cmd = \"#{eoutvar}.concat\"\n    compiler.pre_cmd = [\"#{eoutvar} = ''.dup\"]\n    compiler.post_cmd = [eoutvar]\n  end\nend\n"
  },
  {
    "path": "lib/generators/schedule/USAGE",
    "content": "Description:\n    Generates a schedule.yml file for an event in an event series, auto-filling talk slots from videos.yml.\n    Customize the generated file for multi-track events or special activities as needed.\n\nExample:\n    bin/rails generate schedule --event-series=SERIES_SLUG --event=EVENT_SLUG\n\n    This will create:\n        /data/SERIES_SLUG/EVENT_SLUG/schedule.yml\n    The file will be pre-populated with a basic schedule template for editing.\n"
  },
  {
    "path": "lib/generators/schedule/schedule_generator.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"generators/event_base\"\n\nclass ScheduleGenerator < Generators::EventBase\n  source_root File.expand_path(\"templates\", __dir__)\n\n  class_option :break_duration, type: :numeric, desc: \"The duration of breaks between talks in minutes\", default: 15, group: \"Fields\"\n  class_option :days, type: :array, desc: \"The days of the event in YYYY-MM-DD format (e.g. 2024-09-01) - calculated from event start and end dates if not provided\", group: \"Fields\"\n  class_option :day_start, type: :string, desc: \"The start time of each day in HH:MM format (e.g. 08:00)\", default: \"08:00\", group: \"Fields\"\n  class_option :slots, type: :numeric, desc: \"The number of concurrent talks per time slot\", default: 1, group: \"Fields\"\n  class_option :talk_duration, type: :numeric, desc: \"The duration of each talk in minutes\", default: 30, group: \"Fields\"\n  class_option :videos_count, type: :numeric, desc: \"The total number of videos to schedule - will be fetched from videos.yml if not provided\", group: \"Fields\"\n\n  def initialize_values\n    start_date = static_event.start_date\n    end_date = static_event.end_date\n    @days = options[:days] || (start_date..end_date).to_a\n    @day_start = Time.parse(options[:day_start])\n    videos_count = options[:videos_count] || Static::Video.where_event_slug(options[:event]).count\n    @talks_per_half_day = (videos_count / (@days.size * 2)).ceil\n  end\n\n  def create_schedule_file\n    template \"schedule.yml.tt\", File.join(event_directory, \"schedule.yml\")\n  end\nend\n"
  },
  {
    "path": "lib/generators/schedule/templates/schedule.yml.tt",
    "content": "# docs/ADDING_SCHEDULES.md\n---\ndays:\n<%- @days.each.with_index do |day, index| -%>\n  - name: \"Day <%= index + 1 %>\"\n    date: \"<%= day %>\"\n    grid:\n    <%- if index.zero? -%>\n      # Time slots for unrecorded events (not in videos.yml) \n      # Items replaces the talk\n    <%- end -%>\n      - start_time: \"<%= @day_start.strftime(\"%H:%M\") %>\"\n        end_time: \"<%= (@day_start + 1.hour).strftime(\"%H:%M\") %>\"\n        slots: 1\n        items:\n          - Breakfast<%= \" & Registration\" if index.zero? %>\n    <%- if index.zero? -%>\n      # Time slots for talks/sessions - NO \"items\" field\n      # These are automatically filled from videos.yml in order\n    <%- end -%>\n    <%- end_time = @talks_per_half_day.times.inject((@day_start + 1.hour)) do |start_time, _| -%>\n      - start_time: \"<%= start_time.strftime(\"%H:%M\") %>\"\n        end_time: \"<%= (start_time + options[:talk_duration].minutes).strftime(\"%H:%M\") %>\"\n        slots: <%= options[:slots] %>\n      <%- start_time + options[:talk_duration].minutes + options[:break_duration].minutes -%>\n    <%- end -%>\n      - start_time: \"<%= end_time.strftime(\"%H:%M\") %>\"\n        end_time: \"<%= (end_time + 1.hour).strftime(\"%H:%M\") %>\"\n        slots: 1\n        items:\n          - Lunch\n    <%- end_time = @talks_per_half_day.times.inject((end_time + 1.hour)) do |start_time, _| -%>\n      - start_time: \"<%= start_time.strftime(\"%H:%M\") %>\"\n        end_time: \"<%= (start_time + options[:talk_duration].minutes).strftime(\"%H:%M\") %>\"\n        slots: <%= options[:slots] %>\n      <%- start_time + options[:talk_duration].minutes + options[:break_duration].minutes -%>\n    <%- end -%>\n    <%- if index.zero? -%>\n      # You can optionally include a description for unrecorded events\n    <%- end -%>\n      - start_time: \"<%= end_time.strftime(\"%H:%M\") %>\"\n        end_time: \"<%= (end_time + 1.hour).strftime(\"%H:%M\") %>\"\n        slots: 1\n        items:\n          - title: \"Closing Party\"\n            description: \"Join us for drinks and networking!\"\n<%- end -%>\n"
  },
  {
    "path": "lib/generators/sponsors/USAGE",
    "content": "Description:\n    Generate a sponsors.yml file for an event series and event.\n    Provide sponsor names and tiers as arguments in the format \"Name:Tier\".\n    The first tier listed will be considered the highest tier.\n\nExample:\n    bin/rails generate sponsors typesense:Platinum AppSignal:Gold JetRockets:Gold\n      \"Planet Argon:Silver\" --event-series tropicalrb --event tropical-on-rails-2026\n\n    This will create:\n        /data/tropicalrb/tropical-on-rails-2026/sponsors.yml\n    with the sponsors organized into tiers accordingly.\n"
  },
  {
    "path": "lib/generators/sponsors/sponsors_generator.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"generators/event_base\"\n\nclass SponsorsGenerator < Generators::EventBase\n  source_root File.expand_path(\"templates\", __dir__)\n\n  class_option :event_series, type: :string, desc: \"Event series folder name\", required: true, group: \"Fields\"\n  class_option :event, type: :string, desc: \"Event folder name\", required: true, aliases: [\"-e\"], group: \"Fields\"\n  argument :sponsors, type: :array, default: [\"Sponsor Name|https://TODO.sponsor.url|Sponsors\"], banner: \"sponsor_name|url[|tier][|badge] sponsor_name|url[|tier]\"\n\n  def initialize(args, *options)\n    super\n    sponsors_data = sponsors.map do |sponsor_arg|\n      parts = sponsor_arg.split(\"|\")\n      {\n        name: parts[0],\n        url: parts[1],\n        tier: parts[2] || \"Sponsors\",\n        slug: parts[0].downcase.tr(\" \", \"-\"),\n        badge: parts[3]\n      }\n    end\n    @sponsors_by_tier = sponsors_data.group_by { |s| s[:tier] }\n  end\n\n  def copy_sponsors_file\n    template \"sponsors.yml.tt\", File.join([\"data\", options[:event_series], options[:event], \"sponsors.yml\"])\n  end\nend\n"
  },
  {
    "path": "lib/generators/sponsors/templates/sponsors.yml.tt",
    "content": "# docs/ADDING_SPONSORS.md\n# Do not remove todo until event is over and all sponsors are added.\n# TODO: Add missing sponsors.\n---\n- tiers:\n<%- level = 0 -%>\n<%- @sponsors_by_tier.each do |tier, sponsors| -%>\n    - name: \"<%= tier %>\"\n      level: <%= level += 1 %>\n      sponsors:\n        <%- sponsors.each do |sponsor| -%>\n        - name: \"<%= sponsor[:name] %>\"\n          website: \"https://TODO.sponsor.com\"\n          slug: \"<%= sponsor[:slug] %>\"\n          logo_url: \"https://TODO.example.com/sponsor.png\"\n          <%- if sponsor[:badge] -%>\n          badge: \"<%= sponsor[:badge] %>\"\n          <%- end -%>\n        <%- end -%>\n<%- end -%>"
  },
  {
    "path": "lib/generators/talk/USAGE",
    "content": "Description:\n  This generator creates a new video entry in videos.yml for an unpublished talk.\n  It will create the file if one does not exist, add a new talk to the file if\n  the file does exist, and update an existing talk if the id matches.\n\n  If you do not have data for a value, omit the parameter.\n  The generator will always produce a valid entry with default values for missing parameters.\n\nExample: |\n  To create a talk for event \"Blue Ridge Ruby 2026\" with only a title \n    \"Your first open-source contribution\" for the speaker \"Rachael Wright-Munn\"\n    use the following command:\n\n  bin/rails generate talk --event blue-ridge-ruby-2026 --title \"Your first open-source contribution\" --speaker \"Rachael Wright-Munn\"\n\n  This will create:\n      data/blue-ridge-ruby/blue-ridge-ruby-2026/videos.yml\n\n  To create a lightning talk for \"Ruby Community Conference Winter Edition 2026\"\n    with title \"Doom\" by \"Chris Hasiński\" use this command:\n\n  bin/rails g talk --event ruby-community-conference-winter-edition-2026 --speaker \"Chris Hasiński\" --title \"Doom\" --kind lightning_talk\n\n  This will create a lightning talk entry for Chris Hasiński's talk \"Doom\":\n      data/ruby-community-conference/ruby-community-conference-winter-edition-2026/videos.yml\n\n  If you need to add a lightning talk block where the lightning talks have not been defined:\n\n  bin/rails g talk --event rubycon-2026 --lightning-talks"
  },
  {
    "path": "lib/generators/talk/talk_generator.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"generators/event_base\"\n\nclass TalkGenerator < Generators::EventBase\n  source_root File.expand_path(\"templates\", __dir__)\n\n  class_option :id, type: :string, desc: \"ID of the talk (optional, will be generated from title and speaker if not provided)\", required: false, group: \"Fields\"\n  class_option :title, type: :string, desc: \"Title of the talk\", group: \"Fields\"\n  class_option :speakers, type: :array, default: [\"TODO\"], desc: \"Speaker names\", group: \"Fields\"\n  class_option :description, type: :string, desc: \"Description of the talk\", group: \"Fields\"\n  class_option :kind, type: :string, enum: Talk.kinds.keys, default: \"talk\", desc: \"Type of talk (e.g., 'keynote', 'lightning_talk')\", group: \"Fields\"\n  class_option :language, type: :string, default: \"en\", desc: \"Language of the talk (e.g., 'en', 'es')\", group: \"Fields\"\n\n  # dates\n  class_option :date, type: :string, desc: \"Date of the talk (YYYY-MM-DD)\", required: false, group: \"Fields\"\n  class_option :announced_at, type: :string, desc: \"Date when the talk was announced (YYYY-MM-DD)\", required: false, group: \"Fields\"\n\n  # Options\n  class_option :lightning_talks, type: :boolean, default: false, desc: \"Add empty group of lightning talks\", group: \"Options\"\n\n  class Talk\n    attr_accessor :event_slug, :event, :announced_at, :kind, :language, :speakers\n    attr_writer :id, :title, :date, :description\n\n    def initialize(**attributes)\n      attributes.each { |k, v| send(\"#{k}=\", v) }\n    end\n\n    def title\n      @title ||= \"#{kind.titlecase} by #{speakers.to_sentence}\"\n    end\n\n    def date\n      @date ||= (event&.start_date || Date.today).iso8601\n    end\n\n    def description\n      @description ||= [\"TODO\", title, \"Description\"].join(\" - \")\n    end\n\n    def id\n      @id ||= generate_talk_id\n    end\n\n    def event_name\n      @event.name\n    end\n\n    def generate_talk_id\n      talk_id_parts = []\n      if speakers.length > 2 || speakers.length.zero?\n        talk_id_parts << title.parameterize\n      else\n        talk_id_parts.concat(speakers.map(&:parameterize))\n      end\n      talk_id_parts << kind unless kind.in? [\"talk\", \"panel\"]\n      talk_id_parts << event_slug\n      talk_id_parts.join(\"-\")\n    end\n  end\n\n  class LightningTalk < Talk\n    def id\n      @id ||= \"lightning-talks-#{event_slug}\"\n    end\n\n    def title\n      @title ||= \"Lightning Talks\"\n    end\n\n    def description\n      @description ||= \"Lightning talks.\"\n    end\n  end\n\n  def initialize_values\n    attributes = options\n      .slice(*VideoSchema.properties.keys)\n      .merge({\n        event: static_event,\n        event_slug: options[:event]\n      })\n    @talk = options[:lightning_talks] ? LightningTalk.new(**attributes) : Talk.new(**attributes)\n  end\n\n  def videos_file_path\n    @videos_file_path ||= File.join(event_directory, \"videos.yml\")\n  end\n\n  def add_talk_to_file\n    template \"videos.yml.tt\", videos_file_path unless File.exist?(videos_file_path)\n    talk_template = options[:lightning_talks] ? \"lightning_talks.yml.tt\" : \"talk.yml.tt\"\n\n    if File.read(videos_file_path).match?(/- id: \"#{@talk.id}\"/)\n      match_one_talk = /\\n- id: \"#{@talk.id}\"[\\s\\S]*video_id: \"#{@talk.id}\"\\n/\n      gsub_file videos_file_path, match_one_talk, template_content(talk_template)\n    else\n      append_to_file videos_file_path, template_content(talk_template)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/generators/talk/templates/lightning_talks.yml.tt",
    "content": "\n- id: \"<%= @talk.id %>\"\n  title: \"<%= @talk.title %>\"\n  description: |-\n    <%= @talk.description %>\n  kind: \"lightning_talk\"\n  language: \"<%= @talk.language %>\"\n  date: \"<%= @talk.date %>\"\n  talks: []\n  video_provider: \"scheduled\"\n  video_id: \"<%= @talk.id %>\"\n"
  },
  {
    "path": "lib/generators/talk/templates/talk.yml.tt",
    "content": "\n- id: \"<%= @talk.id %>\"\n  title: \"<%= @talk.title %>\"<%= options[:title] ? \"\" : \" # TODO\" %>\n  description: |-\n<%= optimize_indentation(@talk.description, 4) %>\n  kind: \"<%= @talk.kind %>\"\n  language: \"<%= @talk.language %>\"\n  date: \"<%= @talk.date %>\"\n<%- if options[:announced_at] -%>\n  announced_at: \"<%= @talk.announced_at %>\"\n<%- end -%>\n  speakers:\n  <%- @talk.speakers.each do |speaker| -%>\n    - <%= speaker %>\n  <%- end -%>\n  video_provider: \"scheduled\"\n  video_id: \"<%= @talk.id %>\"\n"
  },
  {
    "path": "lib/generators/talk/templates/videos.yml.tt",
    "content": "# TODO: Add all talks - docs/ADDING_UNPUBLISHED_TALKS.md\n# TODO: Reorder talks for schedule - docs/ADDING_SCHEDULES.md\n# TODO: Add recordings - docs/ADDING_VIDEOS.md\n---\n\n"
  },
  {
    "path": "lib/generators/venue/USAGE",
    "content": "Description:\n  Generates a venue.yml file for a specific event in an event series.\n  This will attempt to geocode the provided address and include the coordinates  and full address info in the generated file.\n  We use nominatim (openstreetmap) by default, but including a Google Maps API key in .env may improve your results.\n\nExample:\n  bin/rails g venue --event=tiny-ruby-conf-2026 --name=\"Korjaamo Kino cinema\" --address \"Töölönkatu 51 A-B, 00250 Helsinki\"\n\n  This will create a venue file with geocoded coordinates and all address values.\n    data/tiny-ruby-conf/tiny-ruby-conf-2026/venue.yml\n"
  },
  {
    "path": "lib/generators/venue/templates/location.yml.tt",
    "content": "  - name: \"<%= options[:name] %>\"\n    description: \"<%= options[:description] %>\"\n    url: \"<%= options[:url] %>\"\n\n    address:\n      street: \"<%= @geocoded_address.street_address %>\"\n      city: \"<%= @geocoded_address.city %>\"\n      region: \"<%= @geocoded_address.state %>\"\n      postal_code: \"<%= @geocoded_address.postal_code %>\"\n      country: \"<%= @geocoded_address.country %>\"\n      country_code: \"<%= @geocoded_address.country_code %>\"\n      display: \"<%= options[:address] || @geocoded_address.address %>\"\n\n    coordinates:\n      latitude: <%= @geocoded_address.latitude %>\n      longitude: <%= @geocoded_address.longitude %>\n\n    maps:\n      google: \"\"\n      apple: \"\"\n      openstreetmap: \"\"\n"
  },
  {
    "path": "lib/generators/venue/templates/venue.yml.tt",
    "content": "# docs/ADDING_VENUES.md\n---\nname: \"<%= options[:name] %>\"\ndescription: \"<%= options[:description] %>\"\ninstructions: \"Instructions for getting to the venue - Optional\"\nurl: \"Venue website url - Optional\"\n\naddress:\n  street: \"<%= @geocoded_address.street_address %>\"\n  city: \"<%= @geocoded_address.city %>\"\n  region: \"<%= @geocoded_address.state %>\"\n  postal_code: \"<%= @geocoded_address.postal_code %>\"\n  country: \"<%= @geocoded_address.country %>\"\n  country_code: \"<%= @geocoded_address.country_code %>\"\n  display: \"<%= options[:address] %>\"\n\ncoordinates:\n  latitude: <%= @geocoded_address.latitude %>\n  longitude: <%= @geocoded_address.longitude %>\n\nmaps:\n  google: \"\"\n  apple: \"\"\n  openstreetmap: \"\"\n\n<%- if options[:locations] -%>\nlocations:\n  - name: \"location name\"\n    kind: \"Type of location (e.g., 'After Party Location')\"\n    description: \"Location description\"\n    address:\n      street: \"\"\n      city: \"\"\n      region: \"\"\n      postal_code: \"\"\n      country: \"\"\n      country_code: \"\"\n      display: \"\"\n    distance: \"Distance from main venue - Optional\"\n    url: \"\"\n    coordinates:\n      latitude: 0.0\n      longitude: 0.0\n    maps:\n      google: \"\"\n      apple: \"\"\n      openstreetmap: \"\"\n\n<%- end -%>\n<%- if options[:hotels] -%>\nhotels:\n  - name: \"Hotel name\"\n    kind: \"Type of hotel (eg. 'Speaker Hotel')\"\n    description: \"Hotel description\"\n    address:\n      street: \"\"\n      city: \"\"\n      region: \"\"\n      postal_code: \"\"\n      country: \"\"\n      country_code: \"\"\n      display: \"\"\n    coordinates:\n      latitude: 0.0\n      longitude: 0.0\n    distance: \"Distance from the venue\"\n    url: \"hotel website\"\n    maps:\n      google: \"\"\n      apple: \"\"\n      openstreetmap: \"\"\n\n<%- end -%>\n<%- if options[:rooms] -%>\nrooms:\n  - name: \"\"\n    floor: \"\"\n    capacity: 0\n    instructions: \"\"\n\n<%- end -%>\n<%- if options[:spaces] -%>\nspaces:\n  - name: \"\"\n    floor: \"\"\n    instructions: \"\"\n\n<%- end -%>\n<%- if options[:accessibility] -%>\naccessibility:\n  wheelchair: true\n  elevators: true\n  accessible_restrooms: true\n  notes: \"Addional accessibility notes\"\n\n<%- end -%>\n<%- if options[:nearby] -%>\nnearby:\n  public_transport: \"\"\n  parking: \"\"\n\n<%- end -%>"
  },
  {
    "path": "lib/generators/venue/venue_generator.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"generators/event_base\"\n\nclass VenueGenerator < Generators::EventBase\n  source_root File.expand_path(\"templates\", __dir__)\n\n  class_option :name, type: :string, desc: \"Venue name\", default: \"TODO Venue name\", group: \"Fields\"\n  class_option :address, type: :string, desc: \"Venue address\", default: \"123 TODO St, City, State, ZIP, Country\", group: \"Fields\"\n  class_option :accessibility, type: :boolean, desc: \"Include accessibility information section\", default: true, group: \"Fields\"\n  class_option :description, type: :string, desc: \"Description of venue\", default: \"TODO - Description of the venue - Optional\"\n  class_option :url, type: :string, desc: \"Hotel website\", default: \"https://TODO.example.com\"\n\n  # Add Section\n  class_option :hotels, type: :boolean, desc: \"Include hotel information section\", default: false, group: \"Fields\"\n  class_option :nearby, type: :boolean, desc: \"Include nearby amenities section\", default: false, group: \"Fields\"\n  class_option :locations, type: :boolean, desc: \"Include additional locations section\", default: false, group: \"Fields\"\n  class_option :rooms, type: :boolean, desc: \"Include rooms section\", default: false, group: \"Fields\"\n  class_option :spaces, type: :boolean, desc: \"Include spaces section\", default: false, group: \"Fields\"\n\n  def copy_venue_file\n    venue_file = File.join([event_directory, \"venue.yml\"])\n    @geocoded_address = geocode_address(name: options[:name], address: options[:address])\n\n    if File.exist?(venue_file)\n      append_to_file(venue_file, template_content(\"location.yml.tt\"))\n    else\n      template \"venue.yml.tt\", venue_file\n    end\n  end\nend\n"
  },
  {
    "path": "lib/guard/data_import.rb",
    "content": "require \"guard/plugin\"\nrequire \"fileutils\"\n\nmodule Guard\n  class DataImport < Plugin\n    def run_on_modifications(paths)\n      process_paths(paths)\n    end\n\n    def run_on_additions(paths)\n      process_paths(paths)\n    end\n\n    private\n\n    def process_paths(paths)\n      return if paths.empty?\n\n      UI.info \"Processing #{paths.size} file(s)...\"\n\n      success_count = 0\n\n      paths.each do |path|\n        success_count += 1 if import_for_path(path)\n      end\n\n      if success_count > 0\n        trigger_vite_reload\n        UI.info \"Finished processing #{success_count} file(s)\"\n      end\n    end\n\n    def import_for_path(path)\n      UI.info \"File changed: #{path}\"\n\n      case path\n      when \"data/speakers.yml\"\n        import_speakers\n      when \"data/topics.yml\"\n        import_topics\n      when \"data/featured_cities.yml\"\n        import_featured_cities\n      when %r{^data/([^/]+)/series\\.yml$}\n        import_series($1)\n      when %r{^data/([^/]+)/([^/]+)/event\\.yml$}\n        import_event($1, $2)\n      when %r{^data/([^/]+)/([^/]+)/videos\\.yml$}\n        import_videos($1, $2)\n      when %r{^data/([^/]+)/([^/]+)/cfp\\.yml$}\n        import_cfps($1, $2)\n      when %r{^data/([^/]+)/([^/]+)/sponsors\\.yml$}\n        import_sponsors($1, $2)\n      when %r{^data/([^/]+)/([^/]+)/schedule\\.yml$}\n        UI.info \"Schedule file changed - no import action needed\"\n\n        true\n      else\n        UI.warning \"Unknown file pattern: #{path}\"\n\n        false\n      end\n    rescue => e\n      UI.error \"Error importing #{path}: #{e.message}\"\n      UI.error e.backtrace.first(5).join(\"\\n\")\n\n      false\n    end\n\n    def import_speakers\n      UI.info \"Importing all speakers...\"\n      run_rails_runner(\"Static::Speaker.import_all!\")\n    end\n\n    def import_topics\n      UI.info \"Importing all topics...\"\n      run_rails_runner(\"Static::Topic.import_all!\")\n    end\n\n    def import_featured_cities\n      UI.info \"Importing all featured cities...\"\n      run_rails_runner(\"Static::FeaturedCity.import_all!\")\n    end\n\n    def import_series(series_slug)\n      UI.info \"Importing series: #{series_slug}\"\n      run_rails_runner(\"Static::EventSeries.find_by_slug('#{series_slug}')&.import!\")\n    end\n\n    def import_event(series_slug, event_slug)\n      UI.info \"Importing event: #{series_slug}/#{event_slug}\"\n      run_rails_runner(\"Static::Event.find_by_slug('#{event_slug}')&.import!\")\n    end\n\n    def import_videos(series_slug, event_slug)\n      UI.info \"Importing videos for: #{series_slug}/#{event_slug}\"\n      run_rails_runner(<<~RUBY)\n        event = Event.find_by(slug: '#{event_slug}')\n        if event\n          Static::Event.find_by_slug('#{event_slug}')&.import_videos!(event)\n        else\n          puts \"Event '#{event_slug}' not found in database. Import event first.\"\n        end\n      RUBY\n    end\n\n    def import_cfps(series_slug, event_slug)\n      UI.info \"Importing CFPs for: #{series_slug}/#{event_slug}\"\n      run_rails_runner(<<~RUBY)\n        event = Event.find_by(slug: '#{event_slug}')\n        if event\n          Static::Event.find_by_slug('#{event_slug}')&.import_cfps!(event)\n        else\n          puts \"Event '#{event_slug}' not found in database. Import event first.\"\n        end\n      RUBY\n    end\n\n    def import_sponsors(series_slug, event_slug)\n      UI.info \"Importing sponsors for: #{series_slug}/#{event_slug}\"\n      run_rails_runner(<<~RUBY)\n        event = Event.find_by(slug: '#{event_slug}')\n        if event\n          Static::Event.find_by_slug('#{event_slug}')&.import_sponsors!(event)\n        else\n          puts \"Event '#{event_slug}' not found in database. Import event first.\"\n        end\n      RUBY\n    end\n\n    def run_rails_runner(code)\n      system(\"bin/rails\", \"runner\", code)\n    end\n\n    def trigger_vite_reload\n      reload_file = File.join(Dir.pwd, \"tmp\", \"vite-reload\")\n      FileUtils.mkdir_p(File.dirname(reload_file))\n      FileUtils.touch(reload_file)\n\n      UI.info \"Triggered Vite reload\"\n    end\n  end\nend\n"
  },
  {
    "path": "lib/protobuf/message_type.rb",
    "content": "# frozen_string_literal: true\n\n# Generated by the protocol buffer compiler.  DO NOT EDIT!\n# source: message.proto\n\nrequire \"google/protobuf\"\n\ndescriptor_data = \"\\n\\rmessage.proto\\\"'\\n\\x0bMessageType\\x12\\x0b\\n\\x03one\\x18\\x01 \\x01(\\t\\x12\\x0b\\n\\x03two\\x18\\x02 \\x01(\\tb\\x06proto3\"\n\npool = Google::Protobuf::DescriptorPool.generated_pool\n\nbegin\n  pool.add_serialized_file(descriptor_data)\nrescue TypeError\n  # Compatibility code: will be removed in the next major version.\n  require \"google/protobuf/descriptor_pb\"\n  parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)\n  parsed.clear_dependency\n  serialized = parsed.class.encode(parsed)\n  file = pool.add_serialized_file(serialized)\n  warn \"Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}\"\n  imports = []\n  imports.each do |type_name, expected_filename|\n    import_file = pool.lookup(type_name).file_descriptor\n    if import_file.name != expected_filename\n      warn \"- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}\"\n    end\n  end\n  warn \"Each proto file must use a consistent fully-qualified name.\"\n  warn \"This will become an error in the next major version.\"\nend\n\nMessageType = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(\"MessageType\").msgclass\n"
  },
  {
    "path": "lib/schemas/address_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"street\": {\n      \"type\": \"string\",\n      \"description\": \"Street address\"\n    },\n    \"city\": {\n      \"type\": \"string\",\n      \"description\": \"City name\"\n    },\n    \"region\": {\n      \"type\": \"string\",\n      \"description\": \"State/Province/Region\"\n    },\n    \"postal_code\": {\n      \"type\": \"string\",\n      \"description\": \"Postal/ZIP code\"\n    },\n    \"country\": {\n      \"type\": \"string\",\n      \"description\": \"Country name\"\n    },\n    \"country_code\": {\n      \"type\": \"string\",\n      \"description\": \"ISO country code (e.g., 'US', 'CA', 'JP')\"\n    },\n    \"display\": {\n      \"type\": \"string\",\n      \"description\": \"Full formatted address for display\"\n    }\n  },\n  \"required\": [\n    \"street\",\n    \"city\",\n    \"country\",\n    \"country_code\",\n    \"display\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/cfp_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"link\": {\n      \"type\": \"string\",\n      \"description\": \"CFP link\"\n    },\n    \"name\": {\n      \"type\": \"string\",\n      \"description\": \"Name for the CFP (default: \\\"Call for Proposals\\\")\"\n    },\n    \"open_date\": {\n      \"type\": \"string\",\n      \"description\": \"CFP open date (YYYY-MM-DD format)\"\n    },\n    \"close_date\": {\n      \"type\": \"string\",\n      \"description\": \"CFP close date (YYYY-MM-DD format)\"\n    }\n  },\n  \"required\": [\n    \"link\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/cfps_schema.json",
    "content": "{\n  \"type\": \"array\",\n  \"items\": {\n    \"$ref\": \"cfp_schema.json\"\n  }\n}"
  },
  {
    "path": "lib/schemas/coordinates_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"latitude\": {\n      \"type\": \"number\",\n      \"description\": \"Latitude coordinate\"\n    },\n    \"longitude\": {\n      \"type\": \"number\",\n      \"description\": \"Longitude coordinate\"\n    }\n  },\n  \"required\": [\n    \"latitude\",\n    \"longitude\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/event_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"id\": {\n      \"type\": \"string\",\n      \"description\": \"Unique identifier for the event (YouTube playlist ID or custom slug)\"\n    },\n    \"title\": {\n      \"type\": \"string\",\n      \"description\": \"Full name of the event (e.g., 'RailsConf 2024')\"\n    },\n    \"description\": {\n      \"type\": \"string\",\n      \"description\": \"Description of the event\"\n    },\n    \"aliases\": {\n      \"type\": \"array\",\n      \"description\": \"Alternative names for the event\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"kind\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"conference\",\n        \"meetup\",\n        \"retreat\",\n        \"hackathon\",\n        \"event\",\n        \"workshop\"\n      ],\n      \"description\": \"Type of event\"\n    },\n    \"hybrid\": {\n      \"type\": \"boolean\",\n      \"description\": \"Whether the event has both in-person and online attendance\"\n    },\n    \"status\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"cancelled\",\n        \"postponed\",\n        \"scheduled\"\n      ],\n      \"description\": \"Event status\"\n    },\n    \"last_edition\": {\n      \"type\": \"boolean\",\n      \"description\": \"Whether this is the last edition of the event\"\n    },\n    \"start_date\": {\n      \"type\": \"string\",\n      \"description\": \"Start date of the event (YYYY-MM-DD format)\"\n    },\n    \"end_date\": {\n      \"type\": \"string\",\n      \"description\": \"End date of the event (YYYY-MM-DD format)\"\n    },\n    \"published_at\": {\n      \"type\": \"string\",\n      \"description\": \"Date when videos were published (YYYY-MM-DD format)\"\n    },\n    \"announced_on\": {\n      \"type\": \"string\",\n      \"description\": \"Date when the event was announced (YYYY-MM-DD format)\"\n    },\n    \"year\": {\n      \"type\": \"integer\",\n      \"description\": \"Year of the event\"\n    },\n    \"date_precision\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"year\",\n        \"month\",\n        \"day\"\n      ],\n      \"description\": \"Precision of the date (when exact dates are unknown)\"\n    },\n    \"frequency\": {\n      \"type\": \"string\",\n      \"description\": \"How often the event occurs (for recurring meetups)\"\n    },\n    \"location\": {\n      \"type\": \"string\",\n      \"description\": \"Location in 'City, Country' format (e.g., 'Detroit, MI' or 'Tokyo, Japan')\"\n    },\n    \"venue\": {\n      \"type\": \"string\",\n      \"description\": \"Name of the venue\"\n    },\n    \"channel_id\": {\n      \"type\": \"string\",\n      \"description\": \"YouTube channel ID (starts with UC...)\"\n    },\n    \"playlist\": {\n      \"type\": \"string\",\n      \"description\": \"YouTube playlist/Vimeo showcase link\"\n    },\n    \"website\": {\n      \"type\": \"string\",\n      \"description\": \"Official event website URL\"\n    },\n    \"original_website\": {\n      \"type\": \"string\",\n      \"description\": \"Original/archived website URL\"\n    },\n    \"twitter\": {\n      \"type\": \"string\",\n      \"description\": \"Twitter/X handle (without @)\"\n    },\n    \"mastodon\": {\n      \"type\": \"string\",\n      \"description\": \"Full Mastodon profile URL\"\n    },\n    \"github\": {\n      \"type\": \"string\",\n      \"description\": \"GitHub organization or repository URL\"\n    },\n    \"meetup\": {\n      \"type\": \"string\",\n      \"description\": \"Meetup.com group URL\"\n    },\n    \"luma\": {\n      \"type\": \"string\",\n      \"description\": \"Luma event URL\"\n    },\n    \"youtube\": {\n      \"type\": \"string\",\n      \"description\": \"YouTube channel or video URL\"\n    },\n    \"tickets_url\": {\n      \"type\": \"string\",\n      \"description\": \"URL to purchase tickets (e.g., Tito, Eventbrite, Luma)\"\n    },\n    \"banner_background\": {\n      \"type\": \"string\",\n      \"description\": \"CSS background value for the banner (color or gradient)\"\n    },\n    \"featured_background\": {\n      \"type\": \"string\",\n      \"description\": \"CSS background color for featured cards\"\n    },\n    \"featured_color\": {\n      \"type\": \"string\",\n      \"description\": \"CSS text color for featured cards\"\n    },\n    \"coordinates\": {\n      \"description\": \"Geographic coordinates (use 'coordinates: false' for online events)\",\n      \"anyOf\": [\n        {\n          \"type\": \"object\",\n          \"properties\": {\n            \"latitude\": {\n              \"type\": \"number\",\n              \"description\": \"Latitude coordinate\"\n            },\n            \"longitude\": {\n              \"type\": \"number\",\n              \"description\": \"Longitude coordinate\"\n            }\n          },\n          \"required\": [\n            \"latitude\",\n            \"longitude\"\n          ],\n          \"additionalProperties\": false\n        },\n        {\n          \"type\": \"boolean\"\n        }\n      ]\n    }\n  },\n  \"required\": [\n    \"id\",\n    \"title\",\n    \"kind\",\n    \"location\",\n    \"coordinates\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/featured_city_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\",\n      \"description\": \"Full city name\"\n    },\n    \"slug\": {\n      \"type\": \"string\",\n      \"description\": \"URL-friendly slug for the city\"\n    },\n    \"state_code\": {\n      \"type\": [\n        \"string\",\n        \"null\"\n      ],\n      \"description\": \"State or province code\"\n    },\n    \"country_code\": {\n      \"type\": \"string\",\n      \"description\": \"ISO 3166-1 alpha-2 country code\"\n    },\n    \"latitude\": {\n      \"type\": \"number\",\n      \"description\": \"Geographic latitude\"\n    },\n    \"longitude\": {\n      \"type\": \"number\",\n      \"description\": \"Geographic longitude\"\n    },\n    \"aliases\": {\n      \"type\": \"array\",\n      \"description\": \"Alternative names or abbreviations\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    }\n  },\n  \"required\": [\n    \"name\",\n    \"slug\",\n    \"country_code\",\n    \"latitude\",\n    \"longitude\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/hotel_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\",\n      \"description\": \"Hotel name\"\n    },\n    \"kind\": {\n      \"type\": \"string\",\n      \"description\": \"Type of hotel (e.g., 'Speaker Hotel')\"\n    },\n    \"description\": {\n      \"type\": \"string\",\n      \"description\": \"Hotel description\"\n    },\n    \"address\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"street\": {\n          \"type\": \"string\",\n          \"description\": \"Street address\"\n        },\n        \"city\": {\n          \"type\": \"string\",\n          \"description\": \"City name\"\n        },\n        \"region\": {\n          \"type\": \"string\",\n          \"description\": \"State/Province/Region\"\n        },\n        \"postal_code\": {\n          \"type\": \"string\",\n          \"description\": \"Postal/ZIP code\"\n        },\n        \"country\": {\n          \"type\": \"string\",\n          \"description\": \"Country name\"\n        },\n        \"country_code\": {\n          \"type\": \"string\",\n          \"description\": \"ISO country code (e.g., 'US', 'CA', 'JP')\"\n        },\n        \"display\": {\n          \"type\": \"string\",\n          \"description\": \"Full formatted address for display\"\n        }\n      },\n      \"required\": [\n        \"street\",\n        \"city\",\n        \"country\",\n        \"country_code\",\n        \"display\"\n      ],\n      \"additionalProperties\": false,\n      \"description\": \"Hotel address\"\n    },\n    \"url\": {\n      \"type\": \"string\",\n      \"description\": \"Hotel website URL\"\n    },\n    \"distance\": {\n      \"type\": \"string\",\n      \"description\": \"Distance from venue\"\n    },\n    \"coordinates\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"latitude\": {\n          \"type\": \"number\",\n          \"description\": \"Latitude coordinate\"\n        },\n        \"longitude\": {\n          \"type\": \"number\",\n          \"description\": \"Longitude coordinate\"\n        }\n      },\n      \"required\": [\n        \"latitude\",\n        \"longitude\"\n      ],\n      \"additionalProperties\": false\n    },\n    \"maps\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"google\": {\n          \"type\": \"string\",\n          \"description\": \"Google Maps URL\"\n        },\n        \"apple\": {\n          \"type\": \"string\",\n          \"description\": \"Apple Maps URL\"\n        },\n        \"openstreetmap\": {\n          \"type\": \"string\",\n          \"description\": \"OpenStreetMap URL\"\n        }\n      },\n      \"required\": [],\n      \"additionalProperties\": false\n    }\n  },\n  \"required\": [\n    \"name\",\n    \"address\",\n    \"coordinates\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/involvement_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\",\n      \"description\": \"Role or involvement type (e.g., 'Organizer', 'Program Committee member')\"\n    },\n    \"users\": {\n      \"type\": \"array\",\n      \"description\": \"Person names involved in this role\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"organisations\": {\n      \"type\": \"array\",\n      \"description\": \"Organization names involved in this role\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    }\n  },\n  \"required\": [\n    \"name\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/location_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\",\n      \"description\": \"Location name\"\n    },\n    \"kind\": {\n      \"type\": \"string\",\n      \"description\": \"Type of location (e.g., 'After Party Location')\"\n    },\n    \"description\": {\n      \"type\": \"string\",\n      \"description\": \"Location description\"\n    },\n    \"address\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"street\": {\n          \"type\": \"string\",\n          \"description\": \"Street address\"\n        },\n        \"city\": {\n          \"type\": \"string\",\n          \"description\": \"City name\"\n        },\n        \"region\": {\n          \"type\": \"string\",\n          \"description\": \"State/Province/Region\"\n        },\n        \"postal_code\": {\n          \"type\": \"string\",\n          \"description\": \"Postal/ZIP code\"\n        },\n        \"country\": {\n          \"type\": \"string\",\n          \"description\": \"Country name\"\n        },\n        \"country_code\": {\n          \"type\": \"string\",\n          \"description\": \"ISO country code (e.g., 'US', 'CA', 'JP')\"\n        },\n        \"display\": {\n          \"type\": \"string\",\n          \"description\": \"Full formatted address for display\"\n        }\n      },\n      \"required\": [\n        \"street\",\n        \"city\",\n        \"country\",\n        \"country_code\",\n        \"display\"\n      ],\n      \"additionalProperties\": false,\n      \"description\": \"Location address\"\n    },\n    \"distance\": {\n      \"type\": \"string\",\n      \"description\": \"Distance from main venue\"\n    },\n    \"url\": {\n      \"type\": \"string\",\n      \"description\": \"Location website URL\"\n    },\n    \"coordinates\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"latitude\": {\n          \"type\": \"number\",\n          \"description\": \"Latitude coordinate\"\n        },\n        \"longitude\": {\n          \"type\": \"number\",\n          \"description\": \"Longitude coordinate\"\n        }\n      },\n      \"required\": [\n        \"latitude\",\n        \"longitude\"\n      ],\n      \"additionalProperties\": false\n    },\n    \"maps\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"google\": {\n          \"type\": \"string\",\n          \"description\": \"Google Maps URL\"\n        },\n        \"apple\": {\n          \"type\": \"string\",\n          \"description\": \"Apple Maps URL\"\n        },\n        \"openstreetmap\": {\n          \"type\": \"string\",\n          \"description\": \"OpenStreetMap URL\"\n        }\n      },\n      \"required\": [],\n      \"additionalProperties\": false\n    }\n  },\n  \"required\": [\n    \"name\",\n    \"kind\",\n    \"coordinates\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/maps_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"google\": {\n      \"type\": \"string\",\n      \"description\": \"Google Maps URL\"\n    },\n    \"apple\": {\n      \"type\": \"string\",\n      \"description\": \"Apple Maps URL\"\n    },\n    \"openstreetmap\": {\n      \"type\": \"string\",\n      \"description\": \"OpenStreetMap URL\"\n    }\n  },\n  \"required\": [],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/schedule_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"days\": {\n      \"type\": \"array\",\n      \"description\": \"List of conference days\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\",\n            \"description\": \"Name of the day (e.g., 'Day 1', 'Workshop Day')\"\n          },\n          \"date\": {\n            \"type\": \"string\",\n            \"description\": \"Date of the day (YYYY-MM-DD format)\"\n          },\n          \"grid\": {\n            \"type\": \"array\",\n            \"description\": \"Time slots for the day\",\n            \"items\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"start_time\": {\n                  \"type\": \"string\",\n                  \"description\": \"Start time (HH:MM format)\"\n                },\n                \"end_time\": {\n                  \"type\": \"string\",\n                  \"description\": \"End time (HH:MM format)\"\n                },\n                \"slots\": {\n                  \"type\": \"integer\",\n                  \"description\": \"Number of parallel tracks/slots\"\n                },\n                \"description\": {\n                  \"type\": \"string\",\n                  \"description\": \"Description of the time slot\"\n                },\n                \"items\": {\n                  \"type\": \"array\",\n                  \"description\": \"Items in this time slot\",\n                  \"items\": {\n                    \"anyOf\": [\n                      {\n                        \"type\": \"string\",\n                        \"description\": \"Simple item name (e.g., 'Lunch', 'Break')\"\n                      },\n                      {\n                        \"type\": \"object\",\n                        \"properties\": {\n                          \"title\": {\n                            \"type\": \"string\",\n                            \"description\": \"Title of the session\"\n                          },\n                          \"description\": {\n                            \"type\": \"string\",\n                            \"description\": \"Description of the session\"\n                          },\n                          \"speakers\": {\n                            \"type\": \"array\",\n                            \"description\": \"List of speaker names\",\n                            \"items\": {\n                              \"type\": \"string\"\n                            }\n                          },\n                          \"track\": {\n                            \"type\": \"string\",\n                            \"description\": \"Track name\"\n                          },\n                          \"room\": {\n                            \"type\": \"string\",\n                            \"description\": \"Room name/number\"\n                          }\n                        },\n                        \"required\": [\n                          \"title\"\n                        ],\n                        \"additionalProperties\": false\n                      }\n                    ]\n                  }\n                }\n              },\n              \"required\": [\n                \"start_time\",\n                \"end_time\"\n              ],\n              \"additionalProperties\": false\n            }\n          }\n        },\n        \"required\": [\n          \"name\",\n          \"date\"\n        ],\n        \"additionalProperties\": false\n      }\n    },\n    \"tracks\": {\n      \"type\": \"array\",\n      \"description\": \"Track definitions for the schedule\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\",\n            \"description\": \"Track name\"\n          },\n          \"color\": {\n            \"type\": \"string\",\n            \"description\": \"Track color (hex)\"\n          },\n          \"text_color\": {\n            \"type\": \"string\",\n            \"description\": \"Text color for the track (hex)\"\n          }\n        },\n        \"required\": [\n          \"name\"\n        ],\n        \"additionalProperties\": false\n      }\n    }\n  },\n  \"required\": [\n    \"days\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/series_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\",\n      \"description\": \"Name of the event series (e.g., 'RailsConf')\"\n    },\n    \"description\": {\n      \"type\": \"string\",\n      \"description\": \"Description of the event series\"\n    },\n    \"kind\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"conference\",\n        \"meetup\",\n        \"retreat\",\n        \"hackathon\",\n        \"event\",\n        \"podcast\",\n        \"online\",\n        \"organisation\",\n        \"workshop\"\n      ],\n      \"description\": \"Type of event series\"\n    },\n    \"frequency\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"yearly\",\n        \"monthly\",\n        \"weekly\",\n        \"irregular\",\n        \"biweekly\",\n        \"biyearly\",\n        \"quarterly\"\n      ],\n      \"description\": \"How often the event occurs\"\n    },\n    \"ended\": {\n      \"type\": \"boolean\",\n      \"description\": \"Whether the event series has ended\"\n    },\n    \"default_country_code\": {\n      \"type\": \"string\",\n      \"description\": \"Default ISO country code (e.g., 'US', 'JP')\"\n    },\n    \"language\": {\n      \"type\": \"string\",\n      \"description\": \"Primary language of the event (e.g., 'english', 'japanese')\"\n    },\n    \"website\": {\n      \"type\": \"string\",\n      \"description\": \"Official website URL\"\n    },\n    \"original_website\": {\n      \"type\": \"string\",\n      \"description\": \"Original/archived website URL\"\n    },\n    \"twitter\": {\n      \"type\": \"string\",\n      \"description\": \"Twitter/X handle (without @)\"\n    },\n    \"mastodon\": {\n      \"type\": \"string\",\n      \"description\": \"Full Mastodon profile URL\"\n    },\n    \"bsky\": {\n      \"type\": \"string\",\n      \"description\": \"Bluesky handle\"\n    },\n    \"github\": {\n      \"type\": \"string\",\n      \"description\": \"GitHub organization or repository\"\n    },\n    \"linkedin\": {\n      \"type\": \"string\",\n      \"description\": \"LinkedIn page URL\"\n    },\n    \"meetup\": {\n      \"type\": \"string\",\n      \"description\": \"Meetup.com group URL\"\n    },\n    \"luma\": {\n      \"type\": \"string\",\n      \"description\": \"Luma event URL\"\n    },\n    \"guild\": {\n      \"type\": \"string\",\n      \"description\": \"Guild.host URL\"\n    },\n    \"vimeo\": {\n      \"type\": \"string\",\n      \"description\": \"Vimeo channel URL\"\n    },\n    \"youtube_channel_id\": {\n      \"type\": \"string\",\n      \"description\": \"YouTube channel ID (starts with UC...)\"\n    },\n    \"youtube_channel_name\": {\n      \"type\": \"string\",\n      \"description\": \"YouTube channel name\"\n    },\n    \"playlist_matcher\": {\n      \"type\": \"string\",\n      \"description\": \"Pattern to match playlists for this series\"\n    },\n    \"aliases\": {\n      \"type\": \"array\",\n      \"description\": \"Alternative names for the series\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    }\n  },\n  \"required\": [\n    \"name\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/speaker_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\",\n      \"description\": \"Full name of the speaker\"\n    },\n    \"slug\": {\n      \"type\": \"string\",\n      \"description\": \"URL-friendly slug for the speaker\"\n    },\n    \"github\": {\n      \"type\": \"string\",\n      \"description\": \"GitHub username\"\n    },\n    \"twitter\": {\n      \"type\": \"string\",\n      \"description\": \"Twitter/X handle (without @)\"\n    },\n    \"website\": {\n      \"type\": \"string\",\n      \"description\": \"Personal website URL\"\n    },\n    \"mastodon\": {\n      \"type\": \"string\",\n      \"description\": \"Full Mastodon profile URL\"\n    },\n    \"bluesky\": {\n      \"type\": \"string\",\n      \"description\": \"Bluesky handle\"\n    },\n    \"linkedin\": {\n      \"type\": \"string\",\n      \"description\": \"LinkedIn profile URL\"\n    },\n    \"speakerdeck\": {\n      \"type\": \"string\",\n      \"description\": \"Speakerdeck profile URL\"\n    },\n    \"aliases\": {\n      \"type\": \"array\",\n      \"description\": \"Alternative names for the speaker\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\"\n          },\n          \"slug\": {\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [\n          \"name\",\n          \"slug\"\n        ],\n        \"additionalProperties\": false\n      }\n    },\n    \"canonical_slug\": {\n      \"type\": \"string\",\n      \"description\": \"Slug of the canonical speaker profile (for deduplication)\"\n    }\n  },\n  \"required\": [\n    \"name\",\n    \"slug\",\n    \"github\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/sponsors_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"tiers\": {\n      \"type\": \"array\",\n      \"description\": \"List of sponsorship tiers\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\",\n            \"description\": \"Sponsorship Tier Name\"\n          },\n          \"description\": {\n            \"type\": \"string\",\n            \"description\": \"Description of the sponsorship tier\"\n          },\n          \"level\": {\n            \"type\": \"integer\",\n            \"description\": \"Sponsorship level (lower number indicates higher level)\"\n          },\n          \"sponsors\": {\n            \"type\": \"array\",\n            \"description\": \"List of sponsors in this tier\",\n            \"items\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\",\n                  \"description\": \"Sponsor Name\"\n                },\n                \"slug\": {\n                  \"type\": \"string\",\n                  \"description\": \"Sponsor identifier slug\"\n                },\n                \"website\": {\n                  \"type\": \"string\",\n                  \"description\": \"Sponsor's website URL\"\n                },\n                \"description\": {\n                  \"type\": \"string\",\n                  \"description\": \"Description of the sponsor\"\n                },\n                \"logo_url\": {\n                  \"type\": \"string\",\n                  \"description\": \"URL to the sponsor's logo image\"\n                },\n                \"badge\": {\n                  \"type\": \"string\",\n                  \"description\": \"Sponsor badge text\"\n                }\n              },\n              \"required\": [\n                \"name\",\n                \"slug\",\n                \"website\"\n              ],\n              \"additionalProperties\": false\n            }\n          }\n        },\n        \"required\": [\n          \"sponsors\"\n        ],\n        \"additionalProperties\": false\n      }\n    }\n  },\n  \"required\": [\n    \"tiers\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/tiers_sponsors_schema.json",
    "content": "{\n  \"type\": \"array\",\n  \"items\": {\n    \"$ref\": \"sponsors_schema.json\"\n  }\n}"
  },
  {
    "path": "lib/schemas/transcript_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"video_id\": {\n      \"type\": \"string\",\n      \"description\": \"Video ID on the provider platform\"\n    },\n    \"cues\": {\n      \"type\": \"array\",\n      \"description\": \"Transcript cues\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"start_time\": {\n            \"type\": \"string\",\n            \"description\": \"Start timestamp (HH:MM:SS.mmm)\"\n          },\n          \"end_time\": {\n            \"type\": \"string\",\n            \"description\": \"End timestamp (HH:MM:SS.mmm)\"\n          },\n          \"text\": {\n            \"type\": \"string\",\n            \"description\": \"Transcript text for this cue\"\n          }\n        },\n        \"required\": [\n          \"start_time\",\n          \"end_time\",\n          \"text\"\n        ],\n        \"additionalProperties\": false\n      }\n    }\n  },\n  \"required\": [\n    \"video_id\",\n    \"cues\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/venue_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\",\n      \"description\": \"Name of the venue\"\n    },\n    \"description\": {\n      \"type\": \"string\",\n      \"description\": \"Description of the venue\"\n    },\n    \"instructions\": {\n      \"type\": \"string\",\n      \"description\": \"Instructions for getting to the venue\"\n    },\n    \"url\": {\n      \"type\": \"string\",\n      \"description\": \"Venue website URL\"\n    },\n    \"address\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"street\": {\n          \"type\": \"string\",\n          \"description\": \"Street address\"\n        },\n        \"city\": {\n          \"type\": \"string\",\n          \"description\": \"City name\"\n        },\n        \"region\": {\n          \"type\": \"string\",\n          \"description\": \"State/Province/Region\"\n        },\n        \"postal_code\": {\n          \"type\": \"string\",\n          \"description\": \"Postal/ZIP code\"\n        },\n        \"country\": {\n          \"type\": \"string\",\n          \"description\": \"Country name\"\n        },\n        \"country_code\": {\n          \"type\": \"string\",\n          \"description\": \"ISO country code (e.g., 'US', 'CA', 'JP')\"\n        },\n        \"display\": {\n          \"type\": \"string\",\n          \"description\": \"Full formatted address for display\"\n        }\n      },\n      \"required\": [\n        \"street\",\n        \"city\",\n        \"country\",\n        \"country_code\",\n        \"display\"\n      ],\n      \"additionalProperties\": false,\n      \"description\": \"Physical address of the venue\"\n    },\n    \"coordinates\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"latitude\": {\n          \"type\": \"number\",\n          \"description\": \"Latitude coordinate\"\n        },\n        \"longitude\": {\n          \"type\": \"number\",\n          \"description\": \"Longitude coordinate\"\n        }\n      },\n      \"required\": [\n        \"latitude\",\n        \"longitude\"\n      ],\n      \"additionalProperties\": false,\n      \"description\": \"Geographic coordinates\"\n    },\n    \"maps\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"google\": {\n          \"type\": \"string\",\n          \"description\": \"Google Maps URL\"\n        },\n        \"apple\": {\n          \"type\": \"string\",\n          \"description\": \"Apple Maps URL\"\n        },\n        \"openstreetmap\": {\n          \"type\": \"string\",\n          \"description\": \"OpenStreetMap URL\"\n        }\n      },\n      \"required\": [],\n      \"additionalProperties\": false,\n      \"description\": \"Links to various map services\"\n    },\n    \"locations\": {\n      \"type\": \"array\",\n      \"description\": \"Additional event locations\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\",\n            \"description\": \"Location name\"\n          },\n          \"kind\": {\n            \"type\": \"string\",\n            \"description\": \"Type of location (e.g., 'After Party Location')\"\n          },\n          \"description\": {\n            \"type\": \"string\",\n            \"description\": \"Location description\"\n          },\n          \"address\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"street\": {\n                \"type\": \"string\",\n                \"description\": \"Street address\"\n              },\n              \"city\": {\n                \"type\": \"string\",\n                \"description\": \"City name\"\n              },\n              \"region\": {\n                \"type\": \"string\",\n                \"description\": \"State/Province/Region\"\n              },\n              \"postal_code\": {\n                \"type\": \"string\",\n                \"description\": \"Postal/ZIP code\"\n              },\n              \"country\": {\n                \"type\": \"string\",\n                \"description\": \"Country name\"\n              },\n              \"country_code\": {\n                \"type\": \"string\",\n                \"description\": \"ISO country code (e.g., 'US', 'CA', 'JP')\"\n              },\n              \"display\": {\n                \"type\": \"string\",\n                \"description\": \"Full formatted address for display\"\n              }\n            },\n            \"required\": [\n              \"street\",\n              \"city\",\n              \"country\",\n              \"country_code\",\n              \"display\"\n            ],\n            \"additionalProperties\": false,\n            \"description\": \"Location address\"\n          },\n          \"distance\": {\n            \"type\": \"string\",\n            \"description\": \"Distance from main venue\"\n          },\n          \"url\": {\n            \"type\": \"string\",\n            \"description\": \"Location website URL\"\n          },\n          \"coordinates\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"latitude\": {\n                \"type\": \"number\",\n                \"description\": \"Latitude coordinate\"\n              },\n              \"longitude\": {\n                \"type\": \"number\",\n                \"description\": \"Longitude coordinate\"\n              }\n            },\n            \"required\": [\n              \"latitude\",\n              \"longitude\"\n            ],\n            \"additionalProperties\": false\n          },\n          \"maps\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"google\": {\n                \"type\": \"string\",\n                \"description\": \"Google Maps URL\"\n              },\n              \"apple\": {\n                \"type\": \"string\",\n                \"description\": \"Apple Maps URL\"\n              },\n              \"openstreetmap\": {\n                \"type\": \"string\",\n                \"description\": \"OpenStreetMap URL\"\n              }\n            },\n            \"required\": [],\n            \"additionalProperties\": false\n          }\n        },\n        \"required\": [\n          \"name\",\n          \"kind\",\n          \"coordinates\"\n        ],\n        \"additionalProperties\": false\n      }\n    },\n    \"hotels\": {\n      \"type\": \"array\",\n      \"description\": \"Recommended hotels near the venue\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\",\n            \"description\": \"Hotel name\"\n          },\n          \"kind\": {\n            \"type\": \"string\",\n            \"description\": \"Type of hotel (e.g., 'Speaker Hotel')\"\n          },\n          \"description\": {\n            \"type\": \"string\",\n            \"description\": \"Hotel description\"\n          },\n          \"address\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"street\": {\n                \"type\": \"string\",\n                \"description\": \"Street address\"\n              },\n              \"city\": {\n                \"type\": \"string\",\n                \"description\": \"City name\"\n              },\n              \"region\": {\n                \"type\": \"string\",\n                \"description\": \"State/Province/Region\"\n              },\n              \"postal_code\": {\n                \"type\": \"string\",\n                \"description\": \"Postal/ZIP code\"\n              },\n              \"country\": {\n                \"type\": \"string\",\n                \"description\": \"Country name\"\n              },\n              \"country_code\": {\n                \"type\": \"string\",\n                \"description\": \"ISO country code (e.g., 'US', 'CA', 'JP')\"\n              },\n              \"display\": {\n                \"type\": \"string\",\n                \"description\": \"Full formatted address for display\"\n              }\n            },\n            \"required\": [\n              \"street\",\n              \"city\",\n              \"country\",\n              \"country_code\",\n              \"display\"\n            ],\n            \"additionalProperties\": false,\n            \"description\": \"Hotel address\"\n          },\n          \"url\": {\n            \"type\": \"string\",\n            \"description\": \"Hotel website URL\"\n          },\n          \"distance\": {\n            \"type\": \"string\",\n            \"description\": \"Distance from venue\"\n          },\n          \"coordinates\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"latitude\": {\n                \"type\": \"number\",\n                \"description\": \"Latitude coordinate\"\n              },\n              \"longitude\": {\n                \"type\": \"number\",\n                \"description\": \"Longitude coordinate\"\n              }\n            },\n            \"required\": [\n              \"latitude\",\n              \"longitude\"\n            ],\n            \"additionalProperties\": false\n          },\n          \"maps\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"google\": {\n                \"type\": \"string\",\n                \"description\": \"Google Maps URL\"\n              },\n              \"apple\": {\n                \"type\": \"string\",\n                \"description\": \"Apple Maps URL\"\n              },\n              \"openstreetmap\": {\n                \"type\": \"string\",\n                \"description\": \"OpenStreetMap URL\"\n              }\n            },\n            \"required\": [],\n            \"additionalProperties\": false\n          }\n        },\n        \"required\": [\n          \"name\",\n          \"address\",\n          \"coordinates\"\n        ],\n        \"additionalProperties\": false\n      }\n    },\n    \"rooms\": {\n      \"type\": \"array\",\n      \"description\": \"Rooms within the venue\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\",\n            \"description\": \"Room name\"\n          },\n          \"floor\": {\n            \"type\": \"string\",\n            \"description\": \"Floor location\"\n          },\n          \"capacity\": {\n            \"type\": \"integer\",\n            \"description\": \"Room capacity\"\n          },\n          \"instructions\": {\n            \"type\": \"string\",\n            \"description\": \"Instructions for finding the room\"\n          }\n        },\n        \"required\": [\n          \"name\"\n        ],\n        \"additionalProperties\": false\n      }\n    },\n    \"spaces\": {\n      \"type\": \"array\",\n      \"description\": \"Other spaces within the venue\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\",\n            \"description\": \"Space name\"\n          },\n          \"floor\": {\n            \"type\": \"string\",\n            \"description\": \"Floor location\"\n          },\n          \"instructions\": {\n            \"type\": \"string\",\n            \"description\": \"Instructions for finding the space\"\n          }\n        },\n        \"required\": [\n          \"name\"\n        ],\n        \"additionalProperties\": false\n      }\n    },\n    \"accessibility\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"wheelchair\": {\n          \"type\": \"boolean\",\n          \"description\": \"Wheelchair accessible\"\n        },\n        \"elevators\": {\n          \"type\": \"boolean\",\n          \"description\": \"Elevators available\"\n        },\n        \"accessible_restrooms\": {\n          \"type\": \"boolean\",\n          \"description\": \"Accessible restrooms available\"\n        },\n        \"notes\": {\n          \"type\": \"string\",\n          \"description\": \"Additional accessibility notes\"\n        }\n      },\n      \"required\": [],\n      \"additionalProperties\": false,\n      \"description\": \"Accessibility information\"\n    },\n    \"nearby\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"public_transport\": {\n          \"type\": \"string\",\n          \"description\": \"Public transportation options\"\n        },\n        \"parking\": {\n          \"type\": \"string\",\n          \"description\": \"Parking information\"\n        }\n      },\n      \"required\": [],\n      \"additionalProperties\": false,\n      \"description\": \"Nearby amenities and transportation\"\n    }\n  },\n  \"required\": [\n    \"name\",\n    \"address\",\n    \"coordinates\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/video_schema.json",
    "content": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"id\": {\n      \"type\": \"string\",\n      \"description\": \"Unique identifier for the video\"\n    },\n    \"title\": {\n      \"type\": \"string\",\n      \"description\": \"Title of the talk\"\n    },\n    \"raw_title\": {\n      \"type\": \"string\",\n      \"description\": \"Original/raw title from the video source\"\n    },\n    \"original_title\": {\n      \"type\": \"string\",\n      \"description\": \"Original title in native language\"\n    },\n    \"description\": {\n      \"type\": \"string\",\n      \"description\": \"Description of the talk\"\n    },\n    \"slug\": {\n      \"type\": \"string\",\n      \"description\": \"URL-friendly slug\"\n    },\n    \"kind\": {\n      \"type\": \"string\",\n      \"description\": \"Type of video (e.g., 'keynote', 'lightning')\"\n    },\n    \"status\": {\n      \"type\": \"string\",\n      \"description\": \"Status of the video\"\n    },\n    \"speakers\": {\n      \"type\": \"array\",\n      \"description\": \"List of speaker names\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"talks\": {\n      \"type\": \"array\",\n      \"description\": \"Sub-talks for panel discussions\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"id\": {\n            \"type\": \"string\"\n          },\n          \"title\": {\n            \"type\": \"string\"\n          },\n          \"raw_title\": {\n            \"type\": \"string\"\n          },\n          \"description\": {\n            \"type\": \"string\"\n          },\n          \"speakers\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"event_name\": {\n            \"type\": \"string\"\n          },\n          \"date\": {\n            \"type\": \"string\"\n          },\n          \"published_at\": {\n            \"type\": \"string\"\n          },\n          \"announced_at\": {\n            \"type\": \"string\"\n          },\n          \"video_provider\": {\n            \"type\": \"string\",\n            \"description\": \"Use 'parent' if there is one video\"\n          },\n          \"video_id\": {\n            \"type\": \"string\"\n          },\n          \"language\": {\n            \"type\": \"string\"\n          },\n          \"track\": {\n            \"type\": \"string\"\n          },\n          \"location\": {\n            \"type\": \"string\",\n            \"description\": \"Location within the venue\"\n          },\n          \"start_cue\": {\n            \"type\": \"string\",\n            \"description\": \"Start time cue in video\"\n          },\n          \"end_cue\": {\n            \"type\": \"string\",\n            \"description\": \"End time cue in video\"\n          },\n          \"thumbnail_cue\": {\n            \"type\": \"string\",\n            \"description\": \"Thumbnail time cue\"\n          },\n          \"slides_url\": {\n            \"type\": \"string\"\n          },\n          \"additional_resources\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"name\": {\n                  \"type\": \"string\"\n                },\n                \"url\": {\n                  \"type\": \"string\"\n                },\n                \"type\": {\n                  \"type\": \"string\",\n                  \"enum\": [\n                    \"write-up\",\n                    \"blog\",\n                    \"article\",\n                    \"source-code\",\n                    \"code\",\n                    \"repo\",\n                    \"github\",\n                    \"documentation\",\n                    \"docs\",\n                    \"presentation\",\n                    \"video\",\n                    \"podcast\",\n                    \"audio\",\n                    \"gem\",\n                    \"library\",\n                    \"transcript\",\n                    \"handout\",\n                    \"notes\",\n                    \"photos\",\n                    \"link\"\n                  ]\n                },\n                \"title\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"required\": [\n                \"name\",\n                \"url\",\n                \"type\"\n              ],\n              \"additionalProperties\": false\n            }\n          },\n          \"thumbnail_xs\": {\n            \"type\": \"string\"\n          },\n          \"thumbnail_sm\": {\n            \"type\": \"string\"\n          },\n          \"thumbnail_md\": {\n            \"type\": \"string\"\n          },\n          \"thumbnail_lg\": {\n            \"type\": \"string\"\n          },\n          \"thumbnail_xl\": {\n            \"type\": \"string\"\n          },\n          \"thumbnail_classes\": {\n            \"type\": \"string\"\n          },\n          \"alternative_recordings\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"title\": {\n                  \"type\": \"string\"\n                },\n                \"raw_title\": {\n                  \"type\": \"string\"\n                },\n                \"published_at\": {\n                  \"type\": \"string\"\n                },\n                \"speakers\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"video_provider\": {\n                  \"type\": \"string\"\n                },\n                \"video_id\": {\n                  \"type\": \"string\"\n                },\n                \"url\": {\n                  \"type\": \"string\"\n                }\n              },\n              \"required\": [],\n              \"additionalProperties\": false\n            }\n          }\n        },\n        \"required\": [\n          \"id\",\n          \"video_provider\",\n          \"video_id\"\n        ],\n        \"additionalProperties\": false\n      }\n    },\n    \"event_name\": {\n      \"type\": \"string\",\n      \"description\": \"Name of the event (e.g., 'RailsConf 2024')\"\n    },\n    \"date\": {\n      \"type\": \"string\",\n      \"description\": \"Date of the talk (YYYY-MM-DD format)\"\n    },\n    \"time\": {\n      \"type\": \"string\",\n      \"description\": \"Time of the talk\"\n    },\n    \"published_at\": {\n      \"type\": \"string\",\n      \"description\": \"Date when the video was published (YYYY-MM-DD format)\"\n    },\n    \"announced_at\": {\n      \"type\": \"string\",\n      \"description\": \"Date when the talk was announced\"\n    },\n    \"location\": {\n      \"type\": \"string\",\n      \"description\": \"Location within the venue\"\n    },\n    \"video_provider\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"youtube\",\n        \"vimeo\",\n        \"not_recorded\",\n        \"scheduled\",\n        \"mp4\",\n        \"parent\",\n        \"children\",\n        \"not_published\"\n      ],\n      \"description\": \"Video hosting provider\"\n    },\n    \"video_id\": {\n      \"type\": \"string\",\n      \"description\": \"Video ID on the provider platform\"\n    },\n    \"external_player\": {\n      \"type\": \"boolean\",\n      \"description\": \"Whether to use external player\"\n    },\n    \"external_player_url\": {\n      \"type\": \"string\",\n      \"description\": \"URL for external player\"\n    },\n    \"alternative_recordings\": {\n      \"type\": \"array\",\n      \"description\": \"Alternative video recordings\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"title\": {\n            \"type\": \"string\"\n          },\n          \"raw_title\": {\n            \"type\": \"string\"\n          },\n          \"language\": {\n            \"type\": \"string\"\n          },\n          \"date\": {\n            \"type\": \"string\"\n          },\n          \"description\": {\n            \"type\": \"string\"\n          },\n          \"published_at\": {\n            \"type\": \"string\"\n          },\n          \"event_name\": {\n            \"type\": \"string\"\n          },\n          \"speakers\": {\n            \"type\": \"array\",\n            \"items\": {\n              \"type\": \"string\"\n            }\n          },\n          \"video_provider\": {\n            \"type\": \"string\"\n          },\n          \"video_id\": {\n            \"type\": \"string\"\n          },\n          \"external_url\": {\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [],\n        \"additionalProperties\": false\n      }\n    },\n    \"track\": {\n      \"type\": \"string\",\n      \"description\": \"Conference track (e.g., 'Main Stage', 'Workshop')\"\n    },\n    \"language\": {\n      \"type\": \"string\",\n      \"description\": \"Language of the talk\"\n    },\n    \"slides_url\": {\n      \"type\": \"string\",\n      \"description\": \"URL to the slides\"\n    },\n    \"additional_resources\": {\n      \"type\": \"array\",\n      \"description\": \"Additional resources related to the talk\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"name\": {\n            \"type\": \"string\",\n            \"description\": \"Display name for the resource\"\n          },\n          \"url\": {\n            \"type\": \"string\",\n            \"description\": \"URL to the resource\"\n          },\n          \"type\": {\n            \"type\": \"string\",\n            \"enum\": [\n              \"write-up\",\n              \"blog\",\n              \"article\",\n              \"source-code\",\n              \"code\",\n              \"repo\",\n              \"github\",\n              \"documentation\",\n              \"docs\",\n              \"presentation\",\n              \"video\",\n              \"podcast\",\n              \"audio\",\n              \"gem\",\n              \"library\",\n              \"transcript\",\n              \"handout\",\n              \"notes\",\n              \"photos\",\n              \"link\",\n              \"book\"\n            ],\n            \"description\": \"Type of resource\"\n          },\n          \"title\": {\n            \"type\": \"string\",\n            \"description\": \"Full title of the resource\"\n          }\n        },\n        \"required\": [\n          \"name\",\n          \"url\",\n          \"type\"\n        ],\n        \"additionalProperties\": false\n      }\n    },\n    \"thumbnail_xs\": {\n      \"type\": \"string\",\n      \"description\": \"Extra small thumbnail URL\"\n    },\n    \"thumbnail_sm\": {\n      \"type\": \"string\",\n      \"description\": \"Small thumbnail URL\"\n    },\n    \"thumbnail_md\": {\n      \"type\": \"string\",\n      \"description\": \"Medium thumbnail URL\"\n    },\n    \"thumbnail_lg\": {\n      \"type\": \"string\",\n      \"description\": \"Large thumbnail URL\"\n    },\n    \"thumbnail_xl\": {\n      \"type\": \"string\",\n      \"description\": \"Extra large thumbnail URL\"\n    },\n    \"thumbnail_classes\": {\n      \"type\": \"string\",\n      \"description\": \"CSS classes for thumbnail\"\n    }\n  },\n  \"required\": [\n    \"id\",\n    \"title\",\n    \"description\",\n    \"date\",\n    \"video_provider\",\n    \"video_id\"\n  ],\n  \"additionalProperties\": false,\n  \"strict\": true\n}"
  },
  {
    "path": "lib/schemas/videos_schema.json",
    "content": "{\n  \"type\": \"array\",\n  \"items\": {\n    \"$ref\": \"video_schema.json\"\n  }\n}"
  },
  {
    "path": "lib/tasks/annotate_rb.rake",
    "content": "# This rake task was added by annotate_rb gem.\n\n# Can set `ANNOTATERB_SKIP_ON_DB_TASKS` to be anything to skip this\nif Rails.env.development? && ENV[\"ANNOTATERB_SKIP_ON_DB_TASKS\"].nil?\n  require \"annotate_rb\"\n\n  AnnotateRb::Core.load_rake_tasks\nend\n"
  },
  {
    "path": "lib/tasks/assets.rake",
    "content": "desc \"Export Conference assets\"\ntask :export_assets, [:conference_name] => :environment do |t, args|\n  sketchtool = \"/Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool\"\n  sketch_file = ENV.fetch(\"SKETCH_FILE\", Rails.root.join(\"RubyEvents.sketch\"))\n\n  response = JSON.parse(Command.run(\"#{sketchtool} metadata document #{sketch_file}\"))\n\n  pages = response[\"pagesAndArtboards\"]\n\n  conference_pages = pages.select { |_id, page|\n    page[\"artboards\"].any? # && Static::Playlist.where(title: page[\"name\"]).any?\n  }\n\n  if (conference_name = args[:conference_name])\n    series = EventSeries.find_by(name: conference_name) || EventSeries.find_by(slug: conference_name)\n\n    conference_pages = conference_pages.select { |_id, page|\n      event = Event.preload(:series).find_by(name: page[\"name\"])\n\n      if series && event\n        event.series == series\n      elsif event\n        page[\"name\"] == conference_name || event.slug == conference_name\n      else\n        page[\"name\"] == conference_name\n      end\n    }\n  end\n\n  conference_pages.each do |id, page|\n    artboard_exports = page[\"artboards\"].select { |id, artboard|\n      artboard[\"name\"].in?([\"card\", \"featured\", \"avatar\", \"banner\", \"poster\"]) ||\n        artboard[\"name\"].downcase.start_with?(\"sticker\")\n    }\n    event = Event.includes(:series).find_by(name: page[\"name\"])\n    page_series = EventSeries.find_by(name: page[\"name\"]) || EventSeries.find_by(slug: page[\"name\"]) unless event\n\n    next if event.nil? && page_series.nil?\n\n    item_ids = artboard_exports.keys.join(\",\")\n    target_directory = if event\n      Rails.root.join(\"app\", \"assets\", \"images\", \"events\", event.series.slug, event.slug)\n    else\n      Rails.root.join(\"app\", \"assets\", \"images\", \"events\", page_series.slug, \"default\")\n    end\n\n    Command.run \"#{sketchtool} export artboards #{sketch_file} --items=#{item_ids} --output=#{target_directory} --save-for-web=YES --formats=webp\"\n  end\nend\n\ndesc \"Export Sticker assets\"\ntask export_stickers: :environment do\n  sketchtool = \"/Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool\"\n  sketch_file = ENV.fetch(\"SKETCH_FILE\", Rails.root.join(\"RubyEvents.sketch\"))\n\n  response = JSON.parse(Command.run(\"#{sketchtool} metadata document #{sketch_file}\"))\n\n  pages = response[\"pagesAndArtboards\"].select { |_id, page| page[\"artboards\"].any? }\n\n  pages.each do |id, page|\n    artboard_exports = page[\"artboards\"].select { |id, artboard| artboard[\"name\"].downcase.start_with?(\"sticker\") }\n    event = Event.includes(:series).find_by(name: page[\"name\"])\n\n    next if event.nil?\n    next if artboard_exports.keys.empty?\n\n    item_ids = artboard_exports.keys.join(\",\")\n    target_directory = Rails.root.join(\"app\", \"assets\", \"images\", \"events\", event.series.slug, event.slug)\n\n    Command.run \"#{sketchtool} export artboards #{sketch_file} --items=#{item_ids} --output=#{target_directory} --save-for-web=YES --formats=webp\"\n  end\nend\n\ndesc \"Export Stamp assets\"\ntask :export_stamps, [:country_code] => :environment do |t, args|\n  sketchtool = \"/Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool\"\n  sketch_file = ENV.fetch(\"STAMPS_SKETCH_FILE\", Rails.root.join(\"stamps.sketch\"))\n\n  response = JSON.parse(Command.run(\"#{sketchtool} metadata document #{sketch_file}\"))\n\n  pages = response[\"pagesAndArtboards\"].select { |_id, page| page[\"artboards\"].any? }\n  target_directory = Rails.root.join(\"app\", \"assets\", \"images\", \"stamps\")\n\n  FileUtils.mkdir_p(target_directory) unless File.directory?(target_directory)\n\n  exported_count = 0\n\n  pages.each do |_page_id, page|\n    page[\"artboards\"].each do |artboard_id, artboard|\n      artboard_name = artboard[\"name\"]\n\n      if artboard_name.downcase == \"ignore\"\n        puts \"Skipping artboard '#{artboard_name}' - marked as ignore\"\n        next\n      end\n\n      if args[:country_code]\n        next unless artboard_name.upcase == args[:country_code].upcase\n      end\n\n      stamp_filename = artboard_name.downcase\n\n      Command.run \"#{sketchtool} export artboards #{sketch_file} --items=#{artboard_id} --output=#{target_directory} --save-for-web=YES --formats=webp --use-id-for-name=NO\"\n\n      exported_file = Dir.glob(File.join(target_directory, \"#{artboard_name}.webp\")).first ||\n        Dir.glob(File.join(target_directory, \"*.webp\")).max_by { |f| File.mtime(f) }\n\n      if exported_file && File.exist?(exported_file)\n        new_filename = File.join(target_directory, \"#{stamp_filename}.webp\")\n\n        if exported_file != new_filename\n          FileUtils.mv(exported_file, new_filename, force: true)\n          puts \"Exported stamp '#{artboard_name}' → #{stamp_filename}.webp\"\n        else\n          puts \"Exported stamp '#{artboard_name}'\"\n        end\n        exported_count += 1\n      end\n    end\n  end\n\n  if args[:country_code] && exported_count == 0\n    puts \"No stamp found for country code '#{args[:country_code]}'\"\n  else\n    puts \"Exported #{exported_count} stamp(s)\"\n  end\nend\n"
  },
  {
    "path": "lib/tasks/backfill_event_involvements.rake",
    "content": "namespace :backfill do\n  desc \"Backfill Event Involvements records from involvements.yml files\"\n  task event_involvements: :environment do\n    puts \"Starting backfill of event involvement records from YAML files...\"\n\n    events_processed = 0\n    error_count = 0\n\n    Static::Event.all.each do |static_event|\n      next unless static_event.imported?\n      next unless static_event.event_record.involvements_file.exist?\n\n      events_processed += 1\n      print \".\"\n\n      static_event.import_involvements!(static_event.event_record)\n    rescue => e\n      puts \"\\nError processing event #{static_event.slug}: #{e.message}\"\n      error_count += 1\n    end\n\n    puts \"\\n\\nBackfill completed!\"\n    puts \"Events processed: #{events_processed}\"\n    puts \"Errors: #{error_count}\"\n  end\nend\n"
  },
  {
    "path": "lib/tasks/backfill_speaker_participation.rake",
    "content": "namespace :backfill do\n  require \"gum\"\n\n  def render_progress_bar(current, total, width: 40)\n    return unless $stdin.tty?\n    return if total.zero?\n\n    percentage = (current.to_f / total * 100).round(1)\n    filled = (current.to_f / total * width).round\n    empty = width - filled\n\n    bar = \"█\" * filled + \"░\" * empty\n    \"\\r\\e[K#{bar} #{percentage}% (#{current}/#{total})\"\n  end\n\n  desc \"Backfill EventParticipation records for existing speakers\"\n  task speaker_participation: :environment do\n    puts Gum.style(\"Backfilling speaker participation records\", border: \"rounded\", padding: \"0 2\", border_foreground: \"5\")\n    puts\n\n    # Query all UserTalk records with discarded_at: nil\n    user_talks = UserTalk.includes(:user, talk: :event).where(discarded_at: nil)\n    total_count = user_talks.count\n    processed_count = 0\n    created_count = 0\n    error_count = 0\n\n    puts \"Found #{total_count} user-talk relationships to process\"\n    puts\n\n    # Process in batches\n    user_talks.find_in_batches(batch_size: 1000) do |batch|\n      batch.each do |user_talk|\n        begin\n          user = user_talk.user\n          talk = user_talk.talk\n          event = talk.event\n\n          next unless user && talk && event\n\n          # Determine participation type based on talk kind\n          participation_type = case talk.kind\n          when \"keynote\"\n            \"keynote_speaker\"\n          else\n            \"speaker\"\n          end\n\n          # Create EventParticipation record if it doesn't exist\n          participation = EventParticipation.find_or_create_by(user: user, event: event, attended_as: participation_type)\n\n          if participation.persisted?\n            created_count += 1 if participation.previously_new_record?\n          else\n            print \"\\r\\e[K\"\n            puts Gum.style(\"❌ Failed: user #{user.id} at event #{event.id}: #{participation.errors.full_messages.join(\", \")}\", foreground: \"1\")\n            error_count += 1\n          end\n        rescue => e\n          print \"\\r\\e[K\"\n          puts Gum.style(\"❌ Error processing user_talk #{user_talk.id}: #{e.message}\", foreground: \"1\")\n          error_count += 1\n        end\n\n        processed_count += 1\n        print render_progress_bar(processed_count, total_count)\n      end\n    end\n\n    puts \"\\n\"\n\n    if error_count > 0\n      puts Gum.style(\"Backfill completed with errors\", border: \"rounded\", padding: \"0 2\", foreground: \"3\", border_foreground: \"3\")\n    else\n      puts Gum.style(\"Backfill completed!\", border: \"rounded\", padding: \"0 2\", foreground: \"2\", border_foreground: \"2\")\n    end\n\n    puts\n    puts \"Total processed: #{processed_count}\"\n    puts Gum.style(\"✓ New participations created: #{created_count}\", foreground: \"2\")\n    puts Gum.style(\"#{(error_count > 0) ? \"❌\" : \"✓\"} Errors: #{error_count}\", foreground: (error_count > 0) ? \"1\" : \"2\")\n  end\nend\n"
  },
  {
    "path": "lib/tasks/cities.rake",
    "content": "# frozen_string_literal: true\n\nnamespace :cities do\n  desc \"Create cities from all event and user locations\"\n  task create: :environment do\n    puts \"Creating cities from events and users...\"\n\n    created_count = 0\n    skipped_count = 0\n\n    event_locations = Event\n      .where.not(city: [nil, \"\"])\n      .where.not(country_code: [nil, \"\"])\n      .distinct\n      .pluck(:city, :country_code, :state_code, :latitude, :longitude)\n\n    puts \"Found #{event_locations.size} unique event locations\"\n\n    event_locations.each do |city, country_code, state_code, latitude, longitude|\n      result = City.find_or_create_for(\n        city: city,\n        country_code: country_code,\n        state_code: state_code,\n        latitude: latitude,\n        longitude: longitude\n      )\n\n      if result&.previously_new_record?\n        created_count += 1\n        puts \"  Created: #{city}, #{state_code}, #{country_code}\"\n      else\n        skipped_count += 1\n      end\n    end\n\n    user_locations = User\n      .where.not(city: [nil, \"\"])\n      .where.not(country_code: [nil, \"\"])\n      .distinct\n      .pluck(:city, :country_code, :state_code, :latitude, :longitude)\n\n    puts \"Found #{user_locations.size} unique user locations\"\n\n    user_locations.each do |city, country_code, state_code, latitude, longitude|\n      result = City.find_or_create_for(\n        city: city,\n        country_code: country_code,\n        state_code: state_code,\n        latitude: latitude,\n        longitude: longitude\n      )\n\n      if result&.previously_new_record?\n        created_count += 1\n        puts \"  Created: #{city}, #{state_code}, #{country_code}\"\n      else\n        skipped_count += 1\n      end\n    end\n\n    puts \"\"\n    puts \"Done! Created #{created_count} cities, skipped #{skipped_count} existing\"\n    puts \"Total cities in database: #{City.count}\"\n  end\n\n  desc \"Geocode cities that are missing coordinates\"\n  task geocode: :environment do\n    cities = City.where(latitude: nil).or(City.where(longitude: nil))\n    total = cities.count\n\n    puts \"Geocoding #{total} cities without coordinates...\"\n\n    cities.find_each.with_index do |city, index|\n      print \"\\r  Processing #{index + 1}/#{total}: #{city.name}, #{city.country_code}...\"\n\n      begin\n        city.geocode\n        if city.geocoded?\n          city.save!\n          print \" ✓\"\n        else\n          print \" (no results)\"\n        end\n      rescue => e\n        print \" ERROR: #{e.message}\"\n      end\n\n      sleep 0.1\n    end\n\n    puts \"\"\n    puts \"Done!\"\n  end\n\n  desc \"Remove cities that are actually countries, states, or regions\"\n  task cleanup: :environment do\n    puts \"Finding invalid city names...\"\n\n    invalid_cities = City.all.select do |city|\n      city.valid?\n      city.errors[:name].any?\n    end\n\n    if invalid_cities.empty?\n      puts \"No invalid cities found.\"\n    else\n      puts \"Found #{invalid_cities.size} invalid cities:\"\n\n      invalid_cities.each do |city|\n        city.valid?\n        reasons = city.errors[:name].join(\", \")\n        location = [city.name, city.state_code, city.country_code].compact.join(\", \")\n        types = city.geocode_metadata&.dig(\"types\")&.join(\", \") || \"unknown\"\n\n        puts \"  - #{location} (geocoded as: #{types}): #{reasons}\"\n      end\n\n      print \"\\nDelete these cities? [y/N] \"\n\n      if ENV[\"FORCE\"] == \"true\" || $stdin.gets&.strip&.downcase == \"y\"\n        invalid_cities.each(&:destroy)\n        puts \"Deleted #{invalid_cities.size} invalid cities.\"\n      else\n        puts \"Aborted.\"\n      end\n    end\n  end\n\n  desc \"List cities with event and user counts\"\n  task stats: :environment do\n    puts \"City Statistics\"\n    puts \"=\" * 60\n\n    cities = City.all.map do |city|\n      {\n        name: city.name,\n        state: city.state_code,\n        country: city.country_code,\n        events: city.events_count,\n        users: city.users_count,\n        geocoded: city.geocoded?\n      }\n    end\n\n    cities.sort_by! { |c| -(c[:events] + c[:users]) }\n\n    cities.each do |city|\n      location = [city[:name], city[:state], city[:country]].compact.join(\", \")\n      geo = city[:geocoded] ? \"✓\" : \"✗\"\n      puts \"#{geo} #{location.ljust(40)} Events: #{city[:events].to_s.rjust(3)} | Users: #{city[:users].to_s.rjust(3)}\"\n    end\n\n    puts \"\"\n    puts \"Total: #{City.count} cities\"\n    puts \"Geocoded: #{City.where.not(latitude: nil).count}\"\n    puts \"Not geocoded: #{City.where(latitude: nil).count}\"\n  end\nend\n"
  },
  {
    "path": "lib/tasks/cleanup_ahoy_visits.rake",
    "content": "namespace :ahoy do\n  desc \"Delete Ahoy visits from IPs with more than 200 visits\"\n  task cleanup_suspicious_visits: :environment do\n    # Find IPs with more than 200 visits\n    suspicious_ips = Ahoy::Visit\n      .group(:ip)\n      .having(\"COUNT(*) > 200\")\n      .pluck(:ip)\n\n    if suspicious_ips.any?\n      puts \"Found #{suspicious_ips.count} IPs with suspicious activity\"\n\n      # Delete all visits from those IPs\n      events_count = Ahoy::Event.where(visit_id: Ahoy::Visit.where(ip: suspicious_ips).select(:id)).delete_all\n      deleted_count = Ahoy::Visit.where(ip: suspicious_ips).delete_all\n\n      puts \"Successfully deleted #{deleted_count} visits and #{events_count} events\"\n    else\n      puts \"No suspicious IP activity found\"\n    end\n  end\nend\n"
  },
  {
    "path": "lib/tasks/contributors.rake",
    "content": "namespace :contributors do\n  desc \"Fetch GitHub contributors and save to database\"\n  task fetch: :environment do\n    Recurring::FetchContributorsJob.perform_now\n  end\nend\n"
  },
  {
    "path": "lib/tasks/db.rake",
    "content": "# to dump the db:\n# first stop the app and all processes that are using the db\n# then bin/dump_prod.sh\n# then rake db:anonymize_and_compact\n\nnamespace :db do\n  desc \"compact the db and anonymize the email addresses\"\n  task anonymize_and_compact: :environment do\n    raise unless Rails.env.development?\n\n    puts \"Deleting Ahoy events and visits\"\n    Ahoy::Event.delete_all\n    puts \"Deleting Ahoy visits\"\n    Ahoy::Visit.delete_all\n\n    puts \"Anonymizing email addresses and decrypting email addresses\"\n    User.all.each do |user|\n      user.update_column(:email, \"#{user.slug}@rubyevents.org\")\n    end\n\n    puts \"Vacuuming the db\"\n    ActiveRecord::Base.connection.execute(\"VACUUM\")\n    puts \"Done\"\n\n    db_path = ActiveRecord::Base.connection_db_config.database\n    db_size_bytes = File.size(db_path)\n    db_size_gb = db_size_bytes / (1024.0**3)\n    puts \"The db file size is #{db_size_gb.round(2)} GB (#{db_size_bytes} bytes)\"\n  end\nend\n"
  },
  {
    "path": "lib/tasks/download.rake",
    "content": "desc \"Download mp4 files for all meta talks\"\ntask download_meta_talks: :environment do |t, args|\n  Talk.where(meta_talk: true).each do |meta_talk|\n    meta_talk.downloader.download!\n  end\nend\n\ndesc \"Download mp4 files for all meta talks with missing thumbnails\"\ntask download_missing_meta_talks: :environment do |t, args|\n  meta_talks = Talk.where(meta_talk: true)\n  extractable_meta_talks = meta_talks.select { |talk| talk.thumbnails.extractable? }\n  missing_talks = extractable_meta_talks.reject { |talk| talk.thumbnails.extracted? }\n  missing_talks_without_downloads = missing_talks.reject { |talk| talk.downloader.downloaded? }\n\n  puts \"Found #{missing_talks_without_downloads.size} missing talks without downloaded videos.\"\n\n  missing_talks_without_downloads.each do |talk|\n    talk.downloader.download!\n  end\nend\n"
  },
  {
    "path": "lib/tasks/dump.rake",
    "content": "TALKS_SLUGS_FILE = \"data/talks_slugs.yml\"\nAPI_ENDPOINT = \"https://www.rubyevents.org/talks.json\"\n# API_ENDPOINT = \"http://localhost:3000/talks.json\"\n\nnamespace :dump do\n  desc \"dump talks slugs to a local yml file\"\n  task talks_slugs: :environment do\n    data = YAML.load_file(TALKS_SLUGS_FILE)\n    dump_updated_at = data&.dig(\"updated_at\")\n\n    talks_slugs = data&.dig(\"talks_slugs\") || {}\n    current_page = 1\n\n    loop do\n      uri = URI(\"#{API_ENDPOINT}?page=#{current_page}&limit=500&all=true&sort=created_at_asc&created_after=#{dump_updated_at}\")\n      response = Net::HTTP.get(uri)\n      parsed_response = JSON.parse(response)\n\n      parsed_response[\"talks\"].each do |talk|\n        video_id = talk[\"video_id\"]\n        next if video_id.nil? || video_id == \"\"\n\n        talks_slugs[video_id] = talk.dig(\"slug\")\n      end\n\n      current_page += 1\n      total_pages = parsed_response.dig(\"pagination\", \"total_pages\")\n      break if parsed_response.dig(\"pagination\", \"next_page\").nil? || current_page > total_pages\n    end\n    data = {\"updated_at\" => Time.current.to_date.to_s, \"talks_slugs\" => talks_slugs}.to_yaml\n    File.write(\"data/talks_slugs.yml\", data)\n\n    data = YAML.load_file(TALKS_SLUGS_FILE)\n    puts \"Total talks slugs: #{data.dig(\"talks_slugs\").size}\"\n  end\nend\n"
  },
  {
    "path": "lib/tasks/event_assets.rake",
    "content": "require \"mini_magick\"\nrequire \"fileutils\"\nrequire \"gum\"\n\nnamespace :event do\n  desc \"Generate event assets from a logo and background color (interactive wizard)\"\n  task generate_assets: :environment do\n    wizard = EventAssetWizard.new\n    wizard.run\n  end\nend\n\nclass EventAssetWizard\n  def run\n    check_dependencies!\n    print_header\n    event = prompt_for_event\n    logo_path = prompt_for_logo\n    background_color = prompt_for_background_color(event)\n    text_color = prompt_for_text_color(background_color)\n\n    print_summary(event, logo_path, background_color, text_color)\n\n    return unless Gum.confirm(\"Proceed with asset generation?\")\n\n    generator = EventAssetGenerator.new(\n      event: event,\n      logo_path: logo_path,\n      background_color: background_color,\n      text_color: text_color\n    )\n\n    generate_with_spinner(generator)\n\n    puts Gum.style(\"✓ Asset generation complete!\", border: \"rounded\", foreground: \"2\", padding: \"0 1\")\n  end\n\n  private\n\n  def check_dependencies!\n    check_imagemagick_installed!\n  end\n\n  def check_imagemagick_installed!\n    unless system(\"which magick > /dev/null 2>&1\")\n      puts \"Error: ImageMagick 7+ is required\"\n      puts \"\"\n      puts \"Install with:\"\n      puts \"  brew install imagemagick\"\n      puts \"\"\n      puts \"Or see: https://imagemagick.org/script/download.php\"\n      exit 1\n    end\n\n    version_output = `magick --version 2>&1`.lines.first.to_s\n    version_match = version_output.match(/ImageMagick (\\d+)\\./)\n\n    unless version_match && version_match[1].to_i >= 7\n      puts \"Error: ImageMagick 7+ is required (found: #{version_output.strip})\"\n      puts \"\"\n      puts \"Upgrade with:\"\n      puts \"  brew upgrade imagemagick\"\n      exit 1\n    end\n  end\n\n  def print_header\n    puts Gum.style(\"Event Asset Generator\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n  end\n\n  def prompt_for_event\n    all_slugs = Event.order(:slug).pluck(:slug)\n\n    puts Gum.style(\"Missing an event? Run bin/rails db:seed:all to sync all from data/\", foreground: \"8\")\n    slug = Gum.filter(all_slugs, header: \"Select event:\", placeholder: \"Type to filter...\")\n\n    if slug.blank?\n      puts Gum.style(\"No event selected\", foreground: \"1\")\n      if Gum.confirm(\"Try again?\")\n        return prompt_for_event\n      else\n        exit 1\n      end\n    end\n\n    event = Event.find_by(slug: slug)\n\n    puts Gum.style(\"✓ #{event.name}\", foreground: \"2\")\n    event\n  end\n\n  def prompt_for_logo\n    puts Gum.style(\"Select logo file (ESC to enter path manually):\", foreground: \"6\")\n    path = Gum.file(height: 15)\n\n    if path.blank?\n      path = Gum.input(header: \"Enter logo path:\", placeholder: \"~/Downloads/logo.png\")\n\n      if path.blank?\n        puts Gum.style(\"No file selected\", foreground: \"1\")\n        if Gum.confirm(\"Try again?\")\n          return prompt_for_logo\n        else\n          exit 1\n        end\n      end\n    end\n\n    expanded_path = File.expand_path(path)\n\n    unless File.exist?(expanded_path)\n      puts Gum.style(\"File not found: #{expanded_path}\", foreground: \"1\")\n      if Gum.confirm(\"Try again?\")\n        return prompt_for_logo\n      else\n        exit 1\n      end\n    end\n\n    begin\n      image = MiniMagick::Image.open(expanded_path)\n      puts Gum.style(\"✓ #{File.basename(path)} (#{image.width}x#{image.height} #{image.type})\", foreground: \"2\")\n    rescue => e\n      puts Gum.style(\"Invalid image: #{e.message}\", foreground: \"1\")\n      if Gum.confirm(\"Try again?\")\n        return prompt_for_logo\n      else\n        exit 1\n      end\n    end\n\n    expanded_path\n  end\n\n  def prompt_for_background_color(event)\n    default = begin\n      event.static_metadata.featured_background\n    rescue\n      nil\n    end\n    default ||= \"#000000\"\n\n    color = Gum.input(header: \"Background color:\", placeholder: default, value: default)\n    color = default if color.blank?\n    color = \"##{color}\" unless color.start_with?(\"#\")\n\n    unless valid_hex_color?(color)\n      Gum.style(\"Invalid hex color. Use format like #CC342D\", foreground: \"1\")\n      return prompt_for_background_color(event)\n    end\n\n    Gum.style(\"✓ Background: #{color}\", foreground: \"2\")\n    color\n  end\n\n  def prompt_for_text_color(background_color)\n    auto_color = calculate_text_color(background_color)\n\n    choice = Gum.choose([\"Auto (#{auto_color})\", \"Custom\"])\n\n    if choice.start_with?(\"Auto\")\n      Gum.style(\"✓ Text color: #{auto_color} (auto)\", foreground: \"2\")\n      return auto_color\n    end\n\n    color = Gum.input(header: \"Text color:\", placeholder: \"#FFFFFF\")\n    color = \"##{color}\" unless color.start_with?(\"#\")\n\n    unless valid_hex_color?(color)\n      Gum.style(\"Invalid hex color\", foreground: \"1\")\n      return prompt_for_text_color(background_color)\n    end\n\n    Gum.style(\"✓ Text color: #{color}\", foreground: \"2\")\n    color\n  end\n\n  def print_summary(event, logo_path, background_color, text_color)\n    assets_list = EventAssetGenerator::ASSETS.map { |name, dims| \"  • #{name}.webp (#{dims[:width]}x#{dims[:height]})\" }.join(\"\\n\")\n\n    summary = <<~SUMMARY\n      Event:      #{event.name} (#{event.slug})\n      Logo:       #{File.basename(logo_path)}\n      Background: #{background_color}\n      Text:       #{text_color}\n\n      Assets to generate:\n      #{assets_list}\n\n      Output: #{event.data_folder}\n    SUMMARY\n\n    puts Gum.style(summary.gsub(\"'\", \"\\\\'\"), border: \"rounded\", padding: \"0 1\", margin: \"1 0\", border_foreground: \"6\")\n  end\n\n  def generate_with_spinner(generator)\n    puts \"\"\n\n    generator.ensure_output_dir!\n\n    EventAssetGenerator::ASSETS.each do |name, dimensions|\n      Gum.spin(\"Generating #{name}.webp...\", spinner: \"dot\") do\n        generator.generate_asset(name, dimensions[:width], dimensions[:height])\n      end\n    end\n\n    Gum.spin(\"Updating event.yml...\", spinner: \"dot\") do\n      generator.update_event_yml\n    end\n  end\n\n  def valid_hex_color?(color)\n    color.match?(/^#[0-9A-Fa-f]{6}$/)\n  end\n\n  def calculate_text_color(bg_color)\n    hex = bg_color.delete(\"#\")\n    r = hex[0..1].to_i(16)\n    g = hex[2..3].to_i(16)\n    b = hex[4..5].to_i(16)\n\n    luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255\n\n    (luminance > 0.5) ? \"#000000\" : \"#FFFFFF\"\n  end\nend\n\nclass EventAssetGenerator\n  ASSETS = {\n    banner: {width: 1300, height: 350},\n    card: {width: 600, height: 350},\n    avatar: {width: 256, height: 256},\n    featured: {width: 615, height: 350},\n    poster: {width: 600, height: 350}\n  }.freeze\n\n  LOGO_PADDING_RATIO = 0.15\n\n  attr_reader :event, :logo_path, :background_color, :text_color, :output_dir\n\n  def initialize(event:, logo_path:, background_color:, text_color: nil)\n    @event = event\n    @logo_path = logo_path\n    @background_color = normalize_color(background_color)\n    @text_color = text_color.present? ? normalize_color(text_color) : calculate_text_color(@background_color)\n    @output_dir = Rails.root.join(\"app\", \"assets\", \"images\", \"events\", event.series.slug, event.slug)\n  end\n\n  def ensure_output_dir!\n    FileUtils.mkdir_p(output_dir)\n  end\n\n  def generate_all\n    ensure_output_dir!\n\n    puts \"Generating assets for #{event.name}...\"\n    puts \"  Logo: #{logo_path}\"\n    puts \"  Background: #{background_color}\"\n    puts \"  Output: #{output_dir}\"\n    puts \"\"\n\n    ASSETS.each do |name, dimensions|\n      generate_asset(name, dimensions[:width], dimensions[:height])\n    end\n\n    puts \"\"\n    puts \"Done! Generated #{ASSETS.size} assets.\"\n  end\n\n  def generate_asset(name, width, height)\n    output_path = output_dir.join(\"#{name}.webp\")\n\n    logo = MiniMagick::Image.open(logo_path)\n    logo_aspect = logo.width.to_f / logo.height.to_f\n\n    padding = [width, height].min * LOGO_PADDING_RATIO\n    max_logo_width = width - (padding * 2)\n    max_logo_height = height - (padding * 2)\n\n    if max_logo_width / logo_aspect <= max_logo_height\n      scaled_width = max_logo_width.round\n      scaled_height = (max_logo_width / logo_aspect).round\n    else\n      scaled_height = max_logo_height.round\n      scaled_width = (max_logo_height * logo_aspect).round\n    end\n\n    cmd = [\n      \"magick\",\n      \"-size\", \"#{width}x#{height}\",\n      \"xc:#{background_color}\",\n      \"(\", logo_path, \"-resize\", \"#{scaled_width}x#{scaled_height}\", \")\",\n      \"-gravity\", \"center\",\n      \"-composite\",\n      \"-quality\", \"90\",\n      output_path.to_s\n    ]\n\n    system(*cmd, exception: true)\n\n    puts \"  Created #{name}.webp (#{width}x#{height})\"\n  rescue => e\n    puts \"  Error creating #{name}.webp: #{e.message}\"\n    puts \"    #{e.backtrace.first(3).join(\"\\n    \")}\"\n  end\n\n  def update_event_yml\n    event_yml_path = event.data_folder.join(\"event.yml\")\n\n    unless event_yml_path.exist?\n      puts \"Warning: event.yml not found at #{event_yml_path}\"\n      return\n    end\n\n    content = File.read(event_yml_path)\n\n    if content.match?(/^banner_background:/)\n      content.gsub!(/^banner_background:.*$/, \"banner_background: \\\"#{background_color}\\\"\")\n    else\n      content = content.rstrip + \"\\nbanner_background: \\\"#{background_color}\\\"\\n\"\n    end\n\n    if content.match?(/^featured_background:/)\n      content.gsub!(/^featured_background:.*$/, \"featured_background: \\\"#{background_color}\\\"\")\n    else\n      content = content.rstrip + \"\\nfeatured_background: \\\"#{background_color}\\\"\\n\"\n    end\n\n    if content.match?(/^featured_color:/)\n      content.gsub!(/^featured_color:.*$/, \"featured_color: \\\"#{text_color}\\\"\")\n    else\n      content = content.rstrip + \"\\nfeatured_color: \\\"#{text_color}\\\"\\n\"\n    end\n    updated = true\n\n    if updated\n      File.write(event_yml_path, content)\n      puts \"\"\n      puts \"Updated event.yml:\"\n      puts \"  banner_background: #{background_color}\"\n      puts \"  featured_background: #{background_color}\"\n      puts \"  featured_color: #{text_color}\"\n    end\n  end\n\n  private\n\n  def normalize_color(color)\n    return color if color.start_with?(\"#\")\n\n    \"##{color}\"\n  end\n\n  def calculate_text_color(bg_color)\n    hex = bg_color.delete(\"#\")\n    r = hex[0..1].to_i(16)\n    g = hex[2..3].to_i(16)\n    b = hex[4..5].to_i(16)\n\n    luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255\n\n    (luminance > 0.5) ? \"#000000\" : \"#FFFFFF\"\n  end\nend\n"
  },
  {
    "path": "lib/tasks/geolocate.thor",
    "content": "require \"bundler/setup\"\nrequire \"dotenv/load\"\nrequire \"parallel\"\nrequire_relative \"../../config/environment\"\n\nclass Geolocate < Thor\n  desc \"files [FILES...]\", \"Geolocate event.yml files based on location field\"\n  option :overwrite, type: :boolean, default: false, desc: \"Overwrite existing coordinates\"\n  def files(*file_patterns)\n    file_patterns = [\"data/**/event.yml\"] if file_patterns.empty?\n\n    files = file_patterns.flat_map { |pattern| Dir.glob(pattern) }.uniq\n    if files.empty?\n      puts \"No files found matching patterns: #{file_patterns.join(\", \")}\"\n      exit 1\n    end\n\n    Parallel.each(files, in_threads: 5) do |file_path|\n      process_event_file(file_path, options[:overwrite])\n    end\n  end\n\n  desc \"events\", \"Geolocate events from the database based on location field\"\n  option :overwrite, type: :boolean, default: false, desc: \"Overwrite existing coordinates\"\n  def events\n    events_to_geocode = if options[:overwrite]\n      Event.all\n    else\n      Event.where(longitude: nil).or(Event.where(latitude: nil))\n    end\n\n    if events_to_geocode.empty?\n      puts \"No events to geocode\"\n      return\n    end\n\n    Parallel.each(events_to_geocode, in_threads: 5) do |event|\n      process_event(event, options[:overwrite])\n    end\n  end\n\n  private\n\n  def process_event_file(file_path, overwrite)\n    data = YAML.load_file(file_path)\n\n    unless data.is_a?(Hash)\n      puts \"⚠ Skipping #{file_path}, invalid YAML structure\"\n      return\n    end\n\n    # Prioritize venue.yml if it exists and has coordinates\n    venue_file = File.join(File.dirname(file_path), \"venue.yml\")\n    if File.exist?(venue_file)\n      venue_data = YAML.load_file(venue_file)\n      venue_coordinates = venue_data[\"coordinates\"]\n      if venue_coordinates && venue_coordinates[\"latitude\"] && venue_coordinates[\"longitude\"]\n        if data[\"coordinates\"] != venue_coordinates || overwrite\n          data[\"coordinates\"] = venue_coordinates\n          File.write(file_path, YAML.dump(data))\n          puts \"✓ #{file_path}: Updated from venue.yml -> #{venue_coordinates}\"\n        else\n          puts \"⚠ Skipping #{file_path}: Already has coordinates from venue\"\n        end\n        return\n      end\n    end\n\n    location = data[\"location\"]\n    unless location.present?\n      puts \"⚠ Skipping #{file_path}: No location field\"\n      return\n    end\n\n    if data[\"coordinates\"] && !overwrite\n      puts \"⚠ Skipping #{file_path}: Already has coordinates\"\n      return\n    end\n\n    coordinates = geocode_location(location)\n\n    if coordinates\n      data[\"coordinates\"] = coordinates\n      File.write(file_path, YAML.dump(data))\n      puts \"✓ #{file_path}: #{data[\"title\"]} (#{location}) -> #{coordinates}\"\n    else\n      puts \"✗ #{file_path}: Failed to geocode (#{location})\"\n    end\n  rescue => e\n    puts \"✗ Error processing #{file_path}: #{e.message}\"\n  end\n\n  def process_event(event, overwrite)\n    coordinates = event.venue.exist? ? event.venue.coordinates : event.static_metadata&.coordinates\n    unless coordinates.present?\n      puts \"⚠ Skipping #{event.name}: No coordinates in venue or metadata\"\n      return\n    end\n\n    if event.longitude.present? && event.latitude.present? && !overwrite\n      puts \"⚠ Skipping #{event.name}: Already has coordinates\"\n      return\n    end\n\n    if coordinates\n      lat = coordinates[\"latitude\"]\n      lng = coordinates[\"longitude\"]\n      event.update(longitude: lng, latitude: lat)\n      puts \"✓ #{event.name} -> #{lat}, #{lng}\"\n    else\n      puts \"✗ Failed to geocode #{event.name}\"\n    end\n  rescue => e\n    puts \"✗ Error processing #{event.name}: #{e.message}\"\n  end\n\n  def geocode_location(location)\n    result = Geocoder.search(location).first\n    return nil unless result\n\n    {\"latitude\" => result.latitude, \"longitude\" => result.longitude}\n  rescue => e\n    puts \"    Error: #{e.message}\"\n    nil\n  end\nend\n"
  },
  {
    "path": "lib/tasks/schema.rake",
    "content": "namespace :schema do\n  # This is to support validating schemas using the YAML language tools\n  # aka the VS Code YAML extension\n  desc \"Export all schemas as JSON Schemas to lib/schemas\"\n  task export: :environment do\n    require \"fileutils\"\n\n    schema_files = Dir.glob(Rails.root.join(\"app/schemas/*_schema.rb\"))\n    schema_files.each do |file|\n      base = File.basename(file, \".rb\")\n      schema_class = base.camelize.constantize\n      json_schema_path = Rails.root.join(\"lib/schemas/#{base}.json\")\n      json_schema = JSON.pretty_generate(schema_class.new.to_json_schema[:schema])\n      File.write(json_schema_path, json_schema)\n      puts \"Exported #{schema_class} to #{json_schema_path}\"\n    end\n  end\nend\n"
  },
  {
    "path": "lib/tasks/search.rake",
    "content": "# frozen_string_literal: true\n\nmodule SearchTaskHelper\n  def self.perform_search(backend, query)\n    print \"Searching for: #{query} \"\n\n    searches = {}\n\n    searches[:talks] = backend.search_talks(query, limit: 5)\n    print \".\"\n\n    searches[:speakers] = backend.search_speakers(query, limit: 5)\n    print \".\"\n\n    searches[:events] = backend.search_events(query, limit: 5)\n    print \".\"\n\n    searches[:topics] = backend.search_topics(query, limit: 5)\n    print \".\"\n\n    searches[:series] = backend.search_series(query, limit: 5)\n    print \".\"\n\n    searches[:organizations] = backend.search_organizations(query, limit: 5)\n    print \".\"\n\n    if backend.respond_to?(:search_locations)\n      searches[:locations] = backend.search_locations(query, limit: 10)\n      print \".\"\n    end\n\n    searches[:languages] = backend.search_languages(query, limit: 10)\n    puts \" done!\\n\\n\"\n\n    searches\n  end\n\n  def self.print_results(searches, query, backend_name)\n    total_results = searches.values.sum { |_, count| count }\n\n    puts \"=\" * 60\n    puts \"Search Results for: \\\"#{query}\\\" (#{backend_name})\"\n    puts \"Total: #{total_results} results across #{searches.size} collections\"\n    puts \"=\" * 60\n\n    results, count = searches[:talks]\n    puts \"\\n📚 Talks (#{count} found):\"\n\n    if results.any?\n      results.each do |talk|\n        puts \"   - #{talk.title}\"\n        puts \"     by #{talk.speaker_names} at #{talk.event_name}\"\n      end\n    else\n      puts \"   (no results)\"\n    end\n\n    results, count = searches[:speakers]\n    puts \"\\n👤 Speakers (#{count} found):\"\n\n    if results.any?\n      results.each do |user|\n        puts \"   - #{user.name} (#{user.talks_count} talks)\"\n      end\n    else\n      puts \"   (no results)\"\n    end\n\n    results, count = searches[:events]\n    puts \"\\n📅 Events (#{count} found):\"\n\n    if results.any?\n      results.each do |event|\n        puts \"   - #{event.name} (#{event.talks_count} talks)\"\n      end\n    else\n      puts \"   (no results)\"\n    end\n\n    results, count = searches[:topics]\n    puts \"\\n🏷️  Topics (#{count} found):\"\n\n    if results.any?\n      results.each do |topic|\n        puts \"   - #{topic.name} (#{topic.talks_count} talks)\"\n      end\n    else\n      puts \"   (no results)\"\n    end\n\n    results, count = searches[:series]\n    puts \"\\n🗓️ Series (#{count} found):\"\n\n    if results.any?\n      results.each do |series|\n        puts \"   - #{series.name}\"\n      end\n    else\n      puts \"   (no results)\"\n    end\n\n    results, count = searches[:organizations]\n    puts \"\\n🏢 Organizations (#{count} found):\"\n\n    if results.any?\n      results.each do |org|\n        puts \"   - #{org.name}\"\n      end\n    else\n      puts \"   (no results)\"\n    end\n\n    if searches[:locations]\n      results, count = searches[:locations]\n      puts \"\\n🌍 Locations (#{count} found):\"\n\n      if results.any?\n        results.each do |loc|\n          type_emoji = {continent: \"🌍\", country: \"🏳️\", state: \"🗺️\", city: \"🏙️\"}[loc[:type].to_sym] || \"📍\"\n          puts \"   #{type_emoji} #{loc[:emoji_flag]} #{loc[:name]} (#{loc[:type]}, #{loc[:event_count]} events)\"\n        end\n      else\n        puts \"   (no results)\"\n      end\n    end\n\n    results, count = searches[:languages]\n    puts \"\\n🗣️ Languages (#{count} found):\"\n\n    if results.any?\n      results.each do |lang|\n        puts \"   - #{lang[:name]} (#{lang[:code]}, #{lang[:talk_count]} talks)\"\n      end\n    else\n      puts \"   (no results)\"\n    end\n\n    if backend_name == \"SQLite FTS\"\n      puts \"\\n⚠️  Note: Locations and Kinds search not supported in SQLite FTS\"\n    end\n\n    puts \"\\n\" + \"=\" * 60\n    puts \"Summary:\"\n    puts \"-\" * 60\n    puts \"  📚 Talks:          %6d\" % searches[:talks][1]\n    puts \"  👤 Speakers:       %6d\" % searches[:speakers][1]\n    puts \"  📅 Events:         %6d\" % searches[:events][1]\n    puts \"  🏷️ Topics:         %6d\" % searches[:topics][1]\n    puts \"  🗓️ Series:         %6d\" % searches[:series][1]\n    puts \"  🏢 Organizations:  %6d\" % searches[:organizations][1]\n    puts \"  🌍 Locations:      %6d\" % (searches[:locations]&.dig(1) || 0) if searches[:locations]\n    puts \"  🗣️ Languages:      %6d\" % searches[:languages][1]\n    puts \"-\" * 60\n    puts \"  Total:             %6d\" % total_results\n    puts \"=\" * 60\n  end\nend\n\nnamespace :search do\n  desc \"Reindex all search backends\"\n  task reindex: :environment do\n    puts \"Starting search reindex...\"\n    start_time = Time.current\n\n    Search::Backend.reindex_all\n\n    duration = Time.current - start_time\n    puts \"\\n🎉 Search reindex completed in #{duration.round(2)} seconds\"\n  end\n\n  desc \"Show search backend status\"\n  task status: :environment do\n    puts \"\\n📊 Search Backend Status\\n\"\n\n    Search::Backend.backends.each do |name, backend|\n      status = backend.available? ? \"✅ Available\" : \"❌ Unavailable\"\n      puts \"#{name}: #{status}\"\n    end\n\n    puts \"\\nDefault backend: #{Search::Backend.default_backend.name}\"\n  end\nend\n\nnamespace :typesense do\n  desc \"Reindex all Typesense collections (zero-downtime using aliases)\"\n  task reindex: :environment do\n    puts \"Starting Typesense reindex...\"\n\n    start_time = Time.current\n\n    Rake::Task[\"typesense:reindex:talks\"].invoke\n    Rake::Task[\"typesense:reindex:events\"].invoke\n    Rake::Task[\"typesense:reindex:users\"].invoke\n    Rake::Task[\"typesense:reindex:topics\"].invoke\n    Rake::Task[\"typesense:reindex:series\"].invoke\n    Rake::Task[\"typesense:reindex:organizations\"].invoke\n    Rake::Task[\"typesense:reindex:locations\"].invoke\n    Rake::Task[\"typesense:reindex:kinds\"].invoke\n    Rake::Task[\"typesense:reindex:languages\"].invoke\n\n    duration = Time.current - start_time\n    puts \"\\n🎉 Typesense reindex completed in #{duration.round(2)} seconds\"\n  end\n\n  namespace :reindex do\n    desc \"Reindex Talks collection\"\n    task talks: :environment do\n      unless Talk.respond_to?(:typesense_index)\n        puts \"Typesense not enabled for Talk model\"\n        next\n      end\n\n      count = Talk.count\n      puts \"\\n📚 Reindexing #{count} Talks...\"\n      start = Time.current\n      Search::Backend::Typesense::Indexer.reindex_talks\n      puts \"   ✅ Talks reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Events collection\"\n    task events: :environment do\n      unless Event.respond_to?(:typesense_index)\n        puts \"Typesense not enabled for Event model\"\n        next\n      end\n\n      count = Event.canonical.count\n      puts \"\\n📅 Reindexing #{count} Events...\"\n      start = Time.current\n      Search::Backend::Typesense::Indexer.reindex_events\n      puts \"   ✅ Events reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Users/Speakers collection\"\n    task users: :environment do\n      unless User.respond_to?(:typesense_index)\n        puts \"Typesense not enabled for User model\"\n        next\n      end\n\n      count = User.where(\"talks_count > 0\").where(canonical_id: nil).count\n      puts \"\\n👤 Reindexing #{count} Users...\"\n      start = Time.current\n      Search::Backend::Typesense::Indexer.reindex_users\n      puts \"   ✅ Users reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Topics collection\"\n    task topics: :environment do\n      unless Topic.respond_to?(:typesense_index)\n        puts \"Typesense not enabled for Topic model\"\n        next\n      end\n\n      count = Topic.approved.canonical.with_talks.count\n      puts \"\\n🏷️  Reindexing #{count} Topics...\"\n      start = Time.current\n      Search::Backend::Typesense::Indexer.reindex_topics\n      puts \"   ✅ Topics reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex EventSeries collection\"\n    task series: :environment do\n      unless EventSeries.respond_to?(:typesense_index)\n        puts \"Typesense not enabled for EventSeries model\"\n        next\n      end\n\n      count = EventSeries.joins(:events).distinct.count\n      puts \"\\n🗓️ Reindexing #{count} Event Series...\"\n      start = Time.current\n      Search::Backend::Typesense::Indexer.reindex_series\n      puts \"   ✅ Event Series reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Organizations collection\"\n    task organizations: :environment do\n      unless Organization.respond_to?(:typesense_index)\n        puts \"Typesense not enabled for Organization model\"\n        next\n      end\n\n      count = Organization.joins(:sponsors).distinct.count\n      puts \"\\n🏢 Reindexing #{count} Organizations...\"\n      start = Time.current\n      Search::Backend::Typesense::Indexer.reindex_organizations\n      puts \"   ✅ Organizations reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Locations collection (continents, countries, states, cities)\"\n    task locations: :environment do\n      puts \"\\n🌍 Reindexing Locations...\"\n      start = Time.current\n      Search::Backend::Typesense::LocationIndexer.reindex_all\n      puts \"   ✅ Locations reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Kinds collection (talk and event types)\"\n    task kinds: :environment do\n      puts \"\\n🏷️ Reindexing Kinds...\"\n      start = Time.current\n      Search::Backend::Typesense::KindIndexer.reindex_all\n      puts \"   ✅ Kinds reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Languages collection\"\n    task languages: :environment do\n      count = Language.used.count\n      puts \"\\n🗣️ Reindexing #{count} Languages...\"\n      start = Time.current\n      Search::Backend::Typesense::LanguageIndexer.reindex_all\n      puts \"   ✅ Languages reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Continents\"\n    task continents: :environment do\n      puts \"\\n🌍 Reindexing Continents...\"\n      start = Time.current\n      Search::Backend::Typesense::LocationIndexer.ensure_collection!\n      Search::Backend::Typesense::LocationIndexer.index_continents\n      puts \"   ✅ Continents reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Countries\"\n    task countries: :environment do\n      puts \"\\n🏳️ Reindexing Countries...\"\n      start = Time.current\n      Search::Backend::Typesense::LocationIndexer.ensure_collection!\n      Search::Backend::Typesense::LocationIndexer.index_countries\n      puts \"   ✅ Countries reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex States\"\n    task states: :environment do\n      puts \"\\n🗺️ Reindexing States...\"\n      start = Time.current\n      Search::Backend::Typesense::LocationIndexer.ensure_collection!\n      Search::Backend::Typesense::LocationIndexer.index_states\n      puts \"   ✅ States reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Cities\"\n    task cities: :environment do\n      puts \"\\n🏙️ Reindexing Cities...\"\n      start = Time.current\n      Search::Backend::Typesense::LocationIndexer.ensure_collection!\n      Search::Backend::Typesense::LocationIndexer.index_cities\n      puts \"   ✅ Cities reindexed in #{(Time.current - start).round(2)}s\"\n    end\n  end\n\n  desc \"Index a single record (usage: rake typesense:index[Talk,123] or typesense:index[Event,railsconf-2024])\"\n  task :index, [:model, :id] => :environment do |_t, args|\n    model_name = args[:model]\n    id = args[:id]\n\n    unless model_name && id\n      puts \"Usage: rake typesense:index[Model,id]\"\n      puts \"Examples:\"\n      puts \"  rake typesense:index[Talk,123]\"\n      puts \"  rake typesense:index[Talk,my-talk-slug]\"\n      puts \"  rake typesense:index[Event,railsconf-2024]\"\n      puts \"  rake typesense:index[User,456]\"\n      next\n    end\n\n    model = model_name.constantize\n    record = model.find_by(id: id) || model.find_by(slug: id)\n\n    unless record\n      puts \"❌ #{model_name} with id/slug '#{id}' not found\"\n      next\n    end\n\n    Search::Backend::Typesense::Indexer.index(record)\n    puts \"✅ Indexed #{model_name} ##{record.id}: #{record.try(:title) || record.try(:name)}\"\n  end\n\n  desc \"Remove a single record from index (usage: rake typesense:remove[Talk,123])\"\n  task :remove, [:model, :id] => :environment do |_t, args|\n    model_name = args[:model]\n    id = args[:id]\n\n    unless model_name && id\n      puts \"Usage: rake typesense:remove[Model,id]\"\n      next\n    end\n\n    model = model_name.constantize\n    record = model.find_by(id: id) || model.find_by(slug: id)\n\n    unless record\n      puts \"❌ #{model_name} with id/slug '#{id}' not found\"\n      next\n    end\n\n    Search::Backend::Typesense::Indexer.remove(record)\n    puts \"✅ Removed #{model_name} ##{record.id} from index\"\n  end\n\n  desc \"Incrementally index recent records (usage: rake typesense:index_recent or typesense:index_recent[48])\"\n  task :index_recent, [:hours] => :environment do |_t, args|\n    hours = (args[:hours] || 24).to_i\n    since = hours.hours.ago\n\n    puts \"Indexing records modified in the last #{hours} hours...\"\n\n    if Talk.respond_to?(:typesense_index!)\n      talks = Talk.where(\"updated_at > ?\", since)\n      puts \"\\n📚 Indexing #{talks.count} talks...\"\n      talks.find_each { |t| Search::Backend::Typesense::Indexer.index(t) }\n    end\n\n    if Event.respond_to?(:typesense_index!)\n      events = Event.canonical.where(\"updated_at > ?\", since)\n      puts \"📅 Indexing #{events.count} events...\"\n      events.find_each { |e| Search::Backend::Typesense::Indexer.index(e) }\n    end\n\n    if User.respond_to?(:typesense_index!)\n      users = User.where(\"talks_count > 0\").where(canonical_id: nil).where(\"updated_at > ?\", since)\n      puts \"👤 Indexing #{users.count} users...\"\n      users.find_each { |u| Search::Backend::Typesense::Indexer.index(u) }\n    end\n\n    if Topic.respond_to?(:typesense_index!)\n      topics = Topic.approved.canonical.with_talks.where(\"updated_at > ?\", since)\n      puts \"🏷️  Indexing #{topics.count} topics...\"\n      topics.find_each { |t| Search::Backend::Typesense::Indexer.index(t) }\n    end\n\n    puts \"\\n✅ Done!\"\n  end\n\n  desc \"Clear all Typesense collections\"\n  task clear: :environment do\n    puts \"Clearing all Typesense collections...\"\n\n    [Talk, Event, User, Topic].each do |model|\n      if model.respond_to?(:clear_index!)\n        begin\n          model.clear_index!\n        rescue\n          nil\n        end\n        puts \"   Cleared #{model.name} collection\"\n      end\n    end\n\n    puts \"✅ All collections cleared!\"\n  end\n\n  namespace :clear do\n    desc \"Clear Talks collection\"\n    task talks: :environment do\n      Talk.clear_index! if Talk.respond_to?(:clear_index!)\n      puts \"✅ Talk collection cleared\"\n    end\n\n    desc \"Clear Events collection\"\n    task events: :environment do\n      Event.clear_index! if Event.respond_to?(:clear_index!)\n      puts \"✅ Event collection cleared\"\n    end\n\n    desc \"Clear Users collection\"\n    task users: :environment do\n      User.clear_index! if User.respond_to?(:clear_index!)\n      puts \"✅ User collection cleared\"\n    end\n\n    desc \"Clear Topics collection\"\n    task topics: :environment do\n      Topic.clear_index! if Topic.respond_to?(:clear_index!)\n      puts \"✅ Topic collection cleared\"\n    end\n  end\n\n  desc \"Drop all Typesense collections (deletes schema, requires reindex)\"\n  task drop: :environment do\n    puts \"Dropping all Typesense collections...\"\n    client = Typesense::Client.new(Typesense.configuration)\n\n    %w[Talk Event User Topic EventSeries Organization locations kinds languages].each do |name|\n      client.collections[name].delete\n      puts \"   Dropped #{name} collection\"\n    rescue Typesense::Error::ObjectNotFound\n      puts \"   #{name} collection not found (skipping)\"\n    end\n\n    puts \"✅ All collections dropped!\"\n  end\n\n  namespace :drop do\n    desc \"Drop Talks collection (deletes schema)\"\n    task talks: :environment do\n      client = Typesense::Client.new(Typesense.configuration)\n      client.collections[\"Talk\"].delete\n      puts \"✅ Talk collection dropped\"\n    rescue Typesense::Error::ObjectNotFound\n      puts \"Talk collection not found\"\n    end\n\n    desc \"Drop Events collection (deletes schema)\"\n    task events: :environment do\n      client = Typesense::Client.new(Typesense.configuration)\n      client.collections[\"Event\"].delete\n      puts \"✅ Event collection dropped\"\n    rescue Typesense::Error::ObjectNotFound\n      puts \"Event collection not found\"\n    end\n\n    desc \"Drop Users collection (deletes schema)\"\n    task users: :environment do\n      client = Typesense::Client.new(Typesense.configuration)\n      client.collections[\"User\"].delete\n      puts \"✅ User collection dropped\"\n    rescue Typesense::Error::ObjectNotFound\n      puts \"User collection not found\"\n    end\n\n    desc \"Drop Topics collection (deletes schema)\"\n    task topics: :environment do\n      client = Typesense::Client.new(Typesense.configuration)\n      client.collections[\"Topic\"].delete\n      puts \"✅ Topic collection dropped\"\n    rescue Typesense::Error::ObjectNotFound\n      puts \"Topic collection not found\"\n    end\n\n    desc \"Drop EventSeries collection (deletes schema)\"\n    task series: :environment do\n      client = Typesense::Client.new(Typesense.configuration)\n      client.collections[\"EventSeries\"].delete\n      puts \"✅ EventSeries collection dropped\"\n    rescue Typesense::Error::ObjectNotFound\n      puts \"EventSeries collection not found\"\n    end\n\n    desc \"Drop Organizations collection (deletes schema)\"\n    task organizations: :environment do\n      client = Typesense::Client.new(Typesense.configuration)\n      client.collections[\"Organization\"].delete\n      puts \"✅ Organization collection dropped\"\n    rescue Typesense::Error::ObjectNotFound\n      puts \"Organization collection not found\"\n    end\n\n    desc \"Drop locations collection (deletes schema)\"\n    task locations: :environment do\n      client = Typesense::Client.new(Typesense.configuration)\n      client.collections[\"locations\"].delete\n      puts \"✅ locations collection dropped\"\n    rescue Typesense::Error::ObjectNotFound\n      puts \"locations collection not found\"\n    end\n\n    desc \"Drop kinds collection (deletes schema)\"\n    task kinds: :environment do\n      client = Typesense::Client.new(Typesense.configuration)\n      client.collections[\"kinds\"].delete\n      puts \"✅ kinds collection dropped\"\n    rescue Typesense::Error::ObjectNotFound\n      puts \"kinds collection not found\"\n    end\n\n    desc \"Drop languages collection (deletes schema)\"\n    task languages: :environment do\n      client = Typesense::Client.new(Typesense.configuration)\n      client.collections[\"languages\"].delete\n      puts \"✅ languages collection dropped\"\n    rescue Typesense::Error::ObjectNotFound\n      puts \"languages collection not found\"\n    end\n  end\n\n  desc \"Show Typesense collection stats\"\n  task stats: :environment do\n    puts \"\\n📊 Typesense Collection Stats\\n\"\n\n    begin\n      client = Typesense::Client.new(Typesense.configuration)\n      collections = client.collections.retrieve\n\n      if collections.empty?\n        puts \"No collections found.\"\n        next\n      end\n\n      collections.sort_by { |c| c[\"name\"] }.each do |collection|\n        puts \"#{collection[\"name\"]}:\"\n        puts \"   Documents: #{collection[\"num_documents\"]}\"\n        puts \"   Fields: #{collection[\"fields\"].size}\"\n        puts \"\"\n      end\n\n      puts \"Database counts:\"\n      puts \"   Talks (all): #{Talk.count}\"\n      puts \"   Events (canonical): #{Event.canonical.count}\"\n      puts \"   Users (speakers): #{User.where(\"talks_count > 0\").where(canonical_id: nil).count}\"\n      puts \"   Topics (approved): #{Topic.approved.canonical.with_talks.count}\"\n    rescue => e\n      puts \"Error: #{e.message}\"\n    end\n  end\n\n  desc \"Test Typesense connection\"\n  task health: :environment do\n    puts \"Testing Typesense connection...\"\n\n    available = Search::Backend::Typesense.available?\n\n    if available\n      puts \"✅ Typesense is healthy!\"\n    else\n      puts \"❌ Typesense is not available\"\n      puts \"\"\n      puts \"Make sure Typesense is running:\"\n      puts \"   docker compose -f docker-compose.typesense.yml up -d\"\n    end\n  end\n\n  desc \"Search across all collections (usage: rake typesense:search[query])\"\n  task :search, [:query] => :environment do |_t, args|\n    query = args[:query] || \"*\"\n    backend = Search::Backend::Typesense\n    searches = SearchTaskHelper.perform_search(backend, query)\n    SearchTaskHelper.print_results(searches, query, \"Typesense\")\n  end\nend\n\nnamespace :sqlite_fts do\n  desc \"Reindex all SQLite FTS indexes\"\n  task reindex: :environment do\n    puts \"Starting SQLite FTS reindex...\"\n    start_time = Time.current\n\n    Search::Backend::SQLiteFTS::Indexer.reindex_all\n\n    duration = Time.current - start_time\n    puts \"\\n🎉 SQLite FTS reindex completed in #{duration.round(2)} seconds\"\n  end\n\n  namespace :reindex do\n    desc \"Reindex Talks FTS index\"\n    task talks: :environment do\n      count = Talk.count\n      puts \"\\n📚 Reindexing #{count} Talks...\"\n      start = Time.current\n      Search::Backend::SQLiteFTS::Indexer.reindex_talks\n      puts \"   ✅ Talks reindexed in #{(Time.current - start).round(2)}s\"\n    end\n\n    desc \"Reindex Users FTS index\"\n    task users: :environment do\n      count = User.indexable.count\n      puts \"\\n👤 Reindexing #{count} Users...\"\n      start = Time.current\n      Search::Backend::SQLiteFTS::Indexer.reindex_users\n      puts \"   ✅ Users reindexed in #{(Time.current - start).round(2)}s\"\n    end\n  end\n\n  desc \"Search across all collections using SQLite FTS (usage: rake sqlite_fts:search[query])\"\n  task :search, [:query] => :environment do |_t, args|\n    query = args[:query] || \"*\"\n    backend = Search::Backend::SQLiteFTS\n    searches = SearchTaskHelper.perform_search(backend, query)\n    SearchTaskHelper.print_results(searches, query, \"SQLite FTS\")\n  end\nend\n"
  },
  {
    "path": "lib/tasks/seed.rake",
    "content": "namespace :db do\n  namespace :seed do\n    desc \"Seed all contributions, event, speaker, and more data\"\n    task all: :environment do\n      Search::Backend.without_indexing do\n        puts \"Importing Cities...\"\n        Static::City.import_all!\n\n        puts \"Importing Speakers...\"\n        Static::Speaker.import_all!\n\n        puts \"Importing Event Series and Events...\"\n        Static::EventSeries.import_all!\n\n        puts \"Importing Topics...\"\n        Static::Topic.import_all!\n\n        Rake::Task[\"backfill:speaker_participation\"].invoke\n        Rake::Task[\"backfill:event_involvements\"].invoke\n        Rake::Task[\"speakerdeck:set_usernames_from_slides_url\"].invoke\n      end\n\n      # Search::Backend.reindex_all\n    end\n\n    desc \"Seed one event series by passing the event series slug - db:seed:event_series[rubyconf]\"\n    task :event_series, [:slug] => :environment do |task, args|\n      event = Static::EventSeries.find_by_slug(args[:slug])\n      if event\n        event.import!\n      else\n        puts \"Event Series with slug '#{args[:slug]}' not found.\"\n      end\n    end\n\n    desc \"Seed all events without series - will error on new event series\"\n    task events: :environment do\n      Static::Event.import_all!\n    end\n\n    desc \"Seed all speakers\"\n    task speakers: :environment do\n      Static::Speaker.import_all!\n    end\n  end\nend\n"
  },
  {
    "path": "lib/tasks/speakerdeck.rake",
    "content": "namespace :speakerdeck do\n  require \"gum\"\n\n  def render_progress_bar(current, total, width: 40)\n    return if total.zero?\n    return unless $stdin.tty?\n\n    percentage = (current.to_f / total * 100).round(1)\n    filled = (current.to_f / total * width).round\n    empty = width - filled\n\n    bar = \"█\" * filled + \"░\" * empty\n    \"\\r\\e[K#{bar} #{percentage}% (#{current}/#{total})\"\n  end\n\n  desc \"Set speakerdeck name from slides_url\"\n  task set_usernames_from_slides_url: :environment do\n    puts Gum.style(\"Setting SpeakerDeck usernames from slides URLs\", border: \"rounded\", padding: \"0 2\", border_foreground: \"5\")\n    puts\n\n    users = User.distinct.where(speakerdeck: \"\").where.associated(:talks)\n    total_count = users.count\n    updated = 0\n    processed = 0\n\n    puts \"Found #{total_count} speakers with no SpeakerDeck name\"\n    puts\n\n    users.find_in_batches do |batch|\n      batch.each do |user|\n        speakerdeck_name = user.speakerdeck_user_from_slides_url\n\n        if speakerdeck_name\n          user.update!(speakerdeck: speakerdeck_name)\n          print \"\\r\\e[K\"\n          puts Gum.style(\"✓ #{user.name} → #{speakerdeck_name}\", foreground: \"2\")\n          updated += 1\n        end\n\n        processed += 1\n        print render_progress_bar(processed, total_count)\n      end\n    end\n\n    puts \"\\n\"\n\n    if updated > 0\n      puts Gum.style(\"Updated #{updated} speakers!\", border: \"rounded\", padding: \"0 2\", foreground: \"2\", border_foreground: \"2\")\n    else\n      puts Gum.style(\"No speakers updated\", border: \"rounded\", padding: \"0 2\", foreground: \"3\", border_foreground: \"3\")\n    end\n  end\nend\n"
  },
  {
    "path": "lib/tasks/speakers.rake",
    "content": "namespace :speakers do\n  desc \"Migrate speaker data to users table\"\n  task migrate_to_users: :environment do\n    puts \"Starting migration of canonical speakers to users...\"\n    Speaker.canonical.each do |speaker|\n      user = speaker.user || (speaker.slug.present? ? User.find_by(slug: speaker.slug) : nil)\n      attributes = speaker.attributes.except(\"id\", \"created_at\", \"updated_at\", \"canonical_id\", \"github\")\n      attributes[\"github_handle\"] = speaker.github\n      if user.present?\n\n        puts \"Updating user #{user.name} with speaker data\"\n        user.update!(**attributes)\n\n      else\n\n        puts \"Creating user #{speaker.name} with speaker data\"\n        user = User.create!(**attributes)\n        speaker.update!(user: user)\n\n      end\n\n      # Create UserTalk records for each SpeakerTalk\n      puts \"Creating UserTalk records for #{speaker.name}\"\n      speaker.reload.speaker_talks.each do |speaker_talk|\n        UserTalk.find_or_create_by(user: user, talk: speaker_talk.talk) do |user_talk|\n          user_talk.discarded_at = speaker_talk.discarded_at\n          user_talk.created_at = speaker_talk.created_at\n          user_talk.updated_at = speaker_talk.updated_at\n        end\n      end\n    end\n\n    puts \"Processing non-canonical speakers\"\n    Speaker.not_canonical.each do |speaker|\n      puts \"Processing speaker #{speaker.name}\"\n      @user = speaker.user || User.find_by(slug: speaker.slug)\n      attributes = speaker.attributes.except(\"id\", \"created_at\", \"updated_at\", \"canonical_id\", \"github\")\n      attributes[\"github_handle\"] = speaker.github\n      @canonical_user = speaker.canonical.user\n\n      next if @user == @canonical_user\n\n      if @user\n        @user.update!(**attributes)\n      else\n        @user = User.create!(**attributes)\n        speaker.update!(user: @user)\n      end\n\n      @user.update!(canonical: @canonical_user)\n    end\n\n    puts \"Migration completed successfully!\"\n    puts \"Summary:\"\n    puts \"  Total users: #{User.count}\"\n    puts \"  Total users with github_handle: #{User.with_github.count}\"\n    puts \"  Total users canonical: #{User.canonical.count}\"\n    puts \"  Users with talks: #{User.where.not(talks_count: 0).count}\"\n    puts \"  Total user_talks: #{UserTalk.count}\"\n    puts \"  Users with canonical relationships: #{User.where.not(canonical_id: nil).count}\"\n  end\n\n  desc \"Verify the migration was successful\"\n  task verify_migration: :environment do\n    puts \"Verifying migration...\"\n\n    # Check that all speakers have corresponding users\n    total_speakers = Speaker.count\n    speakers_with_users = Speaker.joins(:user).count\n\n    puts \"Speakers: #{total_speakers}\"\n    puts \"Speakers with users: #{speakers_with_users}\"\n    puts \"Users created from speakers: #{User.where(\"email LIKE ?\", \"%@rubyvideo.org\").count}\"\n\n    # Check talk relationships\n    total_speaker_talks = SpeakerTalk.count\n    total_user_talks = UserTalk.count\n\n    puts \"SpeakerTalks: #{total_speaker_talks}\"\n    puts \"UserTalks: #{total_user_talks}\"\n\n    # Check for any missing relationships\n    talks_missing_users = Talk.left_joins(:user_talks).where(user_talks: {id: nil}).count\n    puts \"Talks without user relationships: #{talks_missing_users}\"\n\n    if talks_missing_users == 0 && total_user_talks >= total_speaker_talks\n      puts \"✅ Migration verification passed!\"\n    else\n      puts \"❌ Migration verification failed!\"\n    end\n  end\nend\n"
  },
  {
    "path": "lib/tasks/thumbnails.rake",
    "content": "desc \"Fetch thumbnails for meta talks for all cues\"\ntask extract_thumbnails: :environment do |t, args|\n  Talk.where(meta_talk: true).each do |meta_video|\n    meta_video.thumbnails.extract!\n  end\nend\n\ndesc \"Verify all talks with start_cue have thumbnails\"\ntask verify_thumbnails: :environment do |t, args|\n  thumbnails_count = 0\n  child_talks_with_missing_thumbnails = []\n\n  Talk.where(meta_talk: true).flat_map(&:child_talks).each do |child_talk|\n    if child_talk.static_metadata\n      if child_talk.static_metadata.start_cue.present? && child_talk.static_metadata.start_cue != \"TODO\"\n        if child_talk.thumbnails.path.exist?\n          thumbnails_count += 1\n        else\n          puts \"missing thumbnail for child_talk: #{child_talk.video_id} at: #{child_talk.thumbnails.path}\"\n          child_talks_with_missing_thumbnails << child_talk\n        end\n      end\n    else\n      puts \"missing static_metadata for child_talk: #{child_talk.video_id}\"\n      child_talks_with_missing_thumbnails << child_talk\n    end\n  end\n\n  if child_talks_with_missing_thumbnails.any?\n    raise \"missing #{child_talks_with_missing_thumbnails.count} thumbnails\"\n  else\n    puts \"All #{thumbnails_count} thumbnails present!\"\n  end\nend\n"
  },
  {
    "path": "lib/tasks/topics.rake",
    "content": "namespace :topics do\n  desc \"Use LLM to suggest gem mappings for topics\"\n  task suggest_gems: :environment do\n    require \"json\"\n\n    limit = ENV.fetch(\"LIMIT\", 50).to_i\n    offset = ENV.fetch(\"OFFSET\", 0).to_i\n    min_talks = ENV.fetch(\"MIN_TALKS\", 3).to_i\n\n    topics = Topic\n      .approved\n      .canonical\n      .left_joins(:topic_gems)\n      .where(topic_gems: {id: nil})\n      .where(\"talks_count >= ?\", min_talks)\n      .order(talks_count: :desc)\n      .offset(offset)\n      .limit(limit)\n\n    if topics.empty?\n      puts \"No topics without gem mappings found.\"\n      exit\n    end\n\n    puts \"Found #{topics.count} topics without gem mappings (min #{min_talks} talks, offset #{offset})\"\n    puts \"Sending to LLM for suggestions...\\n\\n\"\n\n    prompt = Prompts::Topic::SuggestGems.new(topics: topics)\n    client = OpenAI::Client.new\n\n    response = client.chat(parameters: prompt.to_params)\n\n    content = response.dig(\"choices\", 0, \"message\", \"content\")\n    suggestions = JSON.parse(content)[\"suggestions\"]\n\n    puts \"=\" * 60\n    puts \"GEM MAPPING SUGGESTIONS\"\n    puts \"=\" * 60\n    puts\n\n    accepted = []\n    skipped = []\n\n    suggestions.each do |suggestion|\n      topic_name = suggestion[\"topic_name\"]\n      gem_names = suggestion[\"gem_names\"]\n      confidence = suggestion[\"confidence\"]\n      reasoning = suggestion[\"reasoning\"]\n\n      topic = topics.find { |t| t.name == topic_name }\n      next unless topic\n\n      if gem_names.empty?\n        puts \"#{topic_name} (#{topic.talks_count} talks)\"\n        puts \"  No gems suggested: #{reasoning}\"\n        puts\n        next\n      end\n\n      puts \"-\" * 60\n      puts \"Topic: #{topic_name} (#{topic.talks_count} talks)\"\n      puts \"Suggested gems: #{gem_names.join(\", \")}\"\n      puts \"Confidence: #{confidence}\"\n      puts \"Reasoning: #{reasoning}\"\n      puts\n\n      valid_gems = gem_names.select do |gem_name|\n        info = Gems.info(gem_name)\n\n        if info.is_a?(Hash)\n          puts \"  ✓ #{gem_name} exists (v#{info[\"version\"]}, #{ActiveSupport::NumberHelper.number_to_human(info[\"downloads\"])} downloads)\"\n          true\n        else\n          puts \"  ✗ #{gem_name} not found on RubyGems\"\n          false\n        end\n      rescue => e\n        puts \"  ✗ #{gem_name} error: #{e.message}\"\n        false\n      end\n\n      if valid_gems.empty?\n        puts \"  No valid gems found, skipping.\"\n        puts\n        next\n      end\n\n      print \"\\nAccept mapping? [y]es / [n]o / [s]kip all / [a]ccept all: \"\n      input = $stdin.gets&.strip&.downcase\n\n      case input\n      when \"y\", \"yes\"\n        valid_gems.each do |gem_name|\n          TopicGem.find_or_create_by!(topic: topic, gem_name: gem_name)\n          puts \"  → Added #{gem_name} to #{topic_name}\"\n        end\n        accepted << {topic: topic_name, gems: valid_gems}\n\n      when \"a\", \"accept all\"\n        valid_gems.each do |gem_name|\n          TopicGem.find_or_create_by!(topic: topic, gem_name: gem_name)\n          puts \"  → Added #{gem_name} to #{topic_name}\"\n        end\n\n        accepted << {topic: topic_name, gems: valid_gems}\n\n        remaining = suggestions[suggestions.index(suggestion) + 1..]\n\n        remaining&.each do |remaining_suggestion|\n          remaining_topic = topics.find { |t| t.name == remaining_suggestion[\"topic_name\"] }\n          next unless remaining_topic\n\n          remaining_gems = remaining_suggestion[\"gem_names\"].select do |gem_name|\n            Gems.info(gem_name).is_a?(Hash)\n          rescue\n            false\n          end\n\n          remaining_gems.each do |gem_name|\n            TopicGem.find_or_create_by!(topic: remaining_topic, gem_name: gem_name)\n            puts \"  → Added #{gem_name} to #{remaining_suggestion[\"topic_name\"]}\"\n          end\n          accepted << {topic: remaining_suggestion[\"topic_name\"], gems: remaining_gems} if remaining_gems.any?\n        end\n\n        break\n      when \"s\", \"skip all\"\n        skipped << {topic: topic_name, gems: valid_gems}\n        break\n      else\n        skipped << {topic: topic_name, gems: valid_gems}\n        puts \"  Skipped.\"\n      end\n\n      puts\n    end\n\n    puts\n    puts \"=\" * 60\n    puts \"SUMMARY\"\n    puts \"=\" * 60\n    puts \"Accepted: #{accepted.count} topics\"\n    accepted.each { |a| puts \"  - #{a[:topic]}: #{a[:gems].join(\", \")}\" }\n    puts \"Skipped: #{skipped.count} topics\"\n    puts\n  end\n\n  desc \"List topics with gem mappings\"\n  task list_gems: :environment do\n    topics = Topic.approved.joins(:topic_gems).distinct.order(:name)\n\n    puts \"Topics with gem mappings:\"\n    puts \"-\" * 40\n\n    topics.each do |topic|\n      gems = topic.topic_gems.pluck(:gem_name).join(\", \")\n      puts \"#{topic.name}: #{gems}\"\n    end\n\n    puts\n    puts \"Total: #{topics.count} topics with gem mappings\"\n    puts \"Total gem mappings: #{TopicGem.count}\"\n  end\nend\n"
  },
  {
    "path": "lib/tasks/transcripts.rake",
    "content": "namespace :transcripts do\n  desc \"Extract YouTube transcripts using yt-dlp for talks without transcripts\"\n  task :extract, [:event_slug] => :environment do |_t, args|\n    event_slug = args[:event_slug]\n\n    talks = Talk.where(date: Date.new(2025, 1, 1)..Date.new(2026, 1, 2)).youtube.left_joins(:talk_transcript).where(talk_transcripts: {id: nil})\n\n    if event_slug.present?\n      talks = talks.joins(:event).where(events: {slug: event_slug})\n    end\n\n    total_count = talks.count\n    puts \"Found #{total_count} YouTube talks without transcripts\"\n\n    # Configurable delay between requests to avoid rate limiting\n    delay_seconds = ENV.fetch(\"TRANSCRIPT_DELAY\", 10).to_i\n\n    talks.find_each.with_index do |talk, index|\n      puts \"\\n[#{index + 1}/#{total_count}]\"\n      TranscriptExtractor.new(talk, delay: delay_seconds).extract!\n    end\n  end\n\n  desc \"Import transcripts from YAML files into the database\"\n  task import: :environment do\n    Static::Transcript.import_all!\n    puts \"Imported #{Static::Transcript.count} transcripts\"\n  end\nend\n\nclass TranscriptExtractor\n  YTDLP_BIN = ENV.fetch(\"YTDLP_BIN\", \"yt-dlp\")\n  MAX_RETRIES = 5\n  INITIAL_BACKOFF = 30 # seconds\n\n  attr_reader :talk, :delay\n\n  def initialize(talk, delay: 10)\n    @talk = talk\n    @delay = delay\n  end\n\n  def extract!\n    return unless talk.youtube?\n    return unless talk.event&.series\n\n    puts \"Extracting transcript for: #{talk.title} (#{talk.video_id})\"\n\n    vtt_content = download_transcript_with_retry\n    return if vtt_content.blank?\n\n    transcript = Transcript.create_from_vtt(vtt_content)\n    return unless transcript.present?\n\n    save_to_yaml(transcript)\n    puts \"  -> Saved transcript with #{transcript.cues.size} cues\"\n\n    # Add delay between successful requests to avoid rate limiting\n    puts \"  -> Waiting #{delay}s before next request...\"\n    sleep(delay)\n  rescue => e\n    puts \"  -> Error extracting transcript: #{e.message}\"\n  end\n\n  private\n\n  def download_transcript_with_retry\n    retries = 0\n\n    loop do\n      result = download_transcript\n\n      # Check if we got rate limited\n      if result[:rate_limited]\n        retries += 1\n\n        if retries > MAX_RETRIES\n          puts \"  -> Max retries (#{MAX_RETRIES}) exceeded. Skipping...\"\n          return nil\n        end\n\n        backoff = INITIAL_BACKOFF * (2**(retries - 1)) # Exponential backoff: 30s, 60s, 120s, 240s, 480s\n        puts \"  -> Rate limited! Retry #{retries}/#{MAX_RETRIES} in #{backoff}s...\"\n        sleep(backoff)\n      else\n        return result[:content]\n      end\n    end\n  end\n\n  def download_transcript\n    tmp_dir = Rails.root.join(\"tmp\", \"transcripts\")\n    FileUtils.mkdir_p(tmp_dir)\n\n    output_template = tmp_dir.join(talk.video_id)\n\n    # Download auto-generated subtitles with yt-dlp retry options\n    command = [\n      YTDLP_BIN,\n      \"--write-auto-sub\",\n      \"--sub-lang\", \"en\",\n      \"--sub-format\", \"vtt\",\n      \"--skip-download\",\n      \"--no-warnings\",\n      \"--output\", \"\\\"#{output_template}\\\"\",\n      \"\\\"#{talk.provider_url}\\\"\"\n    ].join(\" \")\n\n    puts \"  -> Running: #{command}\"\n    output = `#{command} 2>&1`\n\n    # Check for rate limiting in the output\n    if output.include?(\"429\") || output.include?(\"Too Many Requests\")\n      return {rate_limited: true, content: nil}\n    end\n\n    # Find the downloaded VTT file\n    vtt_file = Dir.glob(\"#{output_template}*.vtt\").first\n    return {rate_limited: false, content: nil} unless vtt_file && File.exist?(vtt_file)\n\n    content = File.read(vtt_file)\n    File.delete(vtt_file) # Clean up\n    {rate_limited: false, content: content}\n  end\n\n  def save_to_yaml(transcript)\n    series_slug = talk.event.series.slug\n    event_slug = talk.event.slug\n    transcripts_file = Rails.root.join(\"data\", series_slug, event_slug, \"transcripts.yml\")\n\n    # Load existing transcripts or start fresh\n    existing_transcripts = if File.exist?(transcripts_file)\n      YAML.load_file(transcripts_file) || []\n    else\n      []\n    end\n\n    # Remove any existing entry for this video_id\n    existing_transcripts.reject! { |t| t[\"video_id\"] == talk.video_id }\n\n    # Add the new transcript\n    transcript_data = {\n      \"video_id\" => talk.video_id,\n      \"cues\" => transcript.to_h.map { |cue|\n        {\n          \"start_time\" => cue[:start_time],\n          \"end_time\" => cue[:end_time],\n          \"text\" => cue[:text]\n        }\n      }\n    }\n\n    existing_transcripts << transcript_data\n\n    # Write to file\n    File.write(transcripts_file, existing_transcripts.to_yaml)\n  end\nend\n"
  },
  {
    "path": "lib/tasks/update_video_statistics.rake",
    "content": "# lib/tasks/update_video_statistics.rake\n\nnamespace :update_video_statistics do\n  desc \"Update view_count and like_count in Talk table\"\n  task update: :environment do\n    client = YouTube::Video.new\n\n    Talk.find_each do |talk|\n      stats = client.get_statistics(talk.video_id)\n      if stats\n        talk.update(\n          view_count: stats[:view_count],\n          like_count: stats[:like_count]\n        )\n      else\n        puts \"Skipping talk with ID: #{talk.id} due to missing stats\"\n      end\n    end\n\n    puts \"Updated video statistics for all talks\"\n  end\nend\n"
  },
  {
    "path": "lib/tasks/users.rake",
    "content": "namespace :users do\n  desc \"add missing slugs to users\"\n  task add_missing_slugs: :environment do\n    User.where(slug: [nil, \"\"]).find_each do |user|\n      puts \"Adding slug to user #{user.github_handle}\"\n      user.update!(slug: user.github_handle)\n    end\n  end\n\n  desc \"Update user locations from GitHub metadata\"\n  task update_locations: :environment do\n    users = User.where(location: [nil, \"\"]).where.not(github_metadata: {})\n    updated_count = 0\n\n    users.each do |user|\n      location = user.github_metadata.dig(\"profile\", \"location\")\n\n      next if location.blank?\n\n      user.update(location: location)\n\n      updated_count += 1\n\n      puts \"Updated location for #{user.name}: #{location}\"\n    end\n\n    puts \"Updated #{updated_count} user locations\"\n  end\nend\n"
  },
  {
    "path": "lib/tasks/validate.rake",
    "content": "# frozen_string_literal: true\n\nnamespace :validate do\n  require \"gum\"\n  require \"json_schemer\"\n  require \"yaml\"\n\n  def validate_files(glob_pattern, schema_class, file_type, &custom_validation)\n    schema = JSON.parse(schema_class.new.to_json_schema[:schema].to_json)\n    schemer = JSONSchemer.schema(schema)\n\n    files = Dir.glob(Rails.root.join(glob_pattern))\n    valid_count = 0\n    invalid_files = []\n\n    files.each do |file|\n      data = YAML.load_file(file)\n      errors = schemer.validate(data).to_a\n\n      custom_validation&.call(data, errors)\n\n      if errors.empty?\n        valid_count += 1\n      else\n        relative_path = file.sub(\"#{Rails.root}/data/\", \"\")\n        invalid_files << {path: relative_path, errors: errors}\n      end\n    end\n\n    if invalid_files.any?\n      puts Gum.style(\"Invalid #{file_type} files (#{invalid_files.count}):\", foreground: \"1\")\n      puts\n      invalid_files.each do |file|\n        puts Gum.style(\"❌ #{file[:path]}\", foreground: \"1\")\n        gh_action_anotation = (ENV[\"GITHUB_ACTIONS\"] == \"true\") ? \"::error file=data/#{file[:path]},line=1::\" : \"::error::\"\n        file[:errors].each { |e| puts \"#{gh_action_anotation} #{e[\"error\"]} at #{e[\"data_pointer\"]}\" }\n        puts\n      end\n    end\n\n    if invalid_files.any?\n      puts Gum.style(\"#{file_type}: #{valid_count} valid, #{invalid_files.count} invalid out of #{files.count} files\", foreground: \"1\")\n    else\n      puts Gum.style(\"#{file_type}: #{valid_count} valid out of #{files.count} files\", foreground: \"2\")\n    end\n\n    invalid_files.empty?\n  end\n\n  def validate_array_files(glob_pattern, schema_class, file_type)\n    schema = JSON.parse(schema_class.new.to_json_schema[:schema].to_json)\n    schemer = JSONSchemer.schema(schema)\n\n    files = Dir.glob(Rails.root.join(glob_pattern))\n    valid_count = 0\n    invalid_files = []\n\n    files.each do |file|\n      data = YAML.load_file(file)\n      file_errors = []\n\n      Array(data).each_with_index do |item, index|\n        errors = schemer.validate(item).to_a\n\n        errors.each do |error|\n          error[\"data_pointer\"] = \"/#{index}#{error[\"data_pointer\"]}\"\n          error[\"item_label\"] = item[\"name\"] || item[\"title\"] || item[\"id\"] || \"index #{index}\"\n          file_errors << error\n        end\n      end\n\n      if file_errors.empty?\n        valid_count += 1\n      else\n        relative_path = file.sub(\"#{Rails.root}/data/\", \"\")\n        invalid_files << {path: relative_path, errors: file_errors}\n      end\n    end\n\n    if invalid_files.any?\n      puts Gum.style(\"Invalid #{file_type} files (#{invalid_files.count}):\", foreground: \"1\")\n      puts\n      invalid_files.each do |file|\n        puts Gum.style(\"❌ #{file[:path]}\", foreground: \"1\")\n        file[:errors].first(10).each do |e|\n          gh_action_annotation = (ENV[\"GITHUB_ACTIONS\"] == \"true\") ? \"::error file=data/#{file[:path]},line=1::\" : \"::error::\"\n          puts \" #{gh_action_annotation} #{e[\"error\"]} at #{e[\"data_pointer\"]} (#{e[\"item_label\"]})\"\n        end\n        puts \"   ... and #{file[:errors].count - 10} more errors\" if file[:errors].count > 10\n        puts\n      end\n    end\n\n    if invalid_files.any?\n      puts Gum.style(\"#{file_type}: #{valid_count} valid, #{invalid_files.count} invalid out of #{files.count} files\", foreground: \"1\")\n    else\n      puts Gum.style(\"#{file_type}: #{valid_count} valid out of #{files.count} files\", foreground: \"2\")\n    end\n\n    invalid_files.empty?\n  end\n\n  desc \"Validate all cfp.yml files against CFPSchema\"\n  task cfps: :environment do\n    success = validate_array_files(\"data/**/cfp.yml\", CFPSchema, \"cfp.yml\")\n    exit 1 unless success\n  end\n\n  desc \"Validate all event.yml files against EventSchema\"\n  task events: :environment do\n    success = validate_files(\"data/**/event.yml\", EventSchema, \"event.yml\") do |data, errors|\n      is_meetup = data[\"kind\"] == \"meetup\"\n\n      unless is_meetup\n        if data[\"start_date\"].nil? || data[\"start_date\"].to_s.strip.empty?\n          errors << {\"error\" => \"start_date is required for non-meetup events\", \"data_pointer\" => \"/start_date\"}\n        end\n\n        if data[\"end_date\"].nil? || data[\"end_date\"].to_s.strip.empty?\n          errors << {\"error\" => \"end_date is required for non-meetup events\", \"data_pointer\" => \"/end_date\"}\n        end\n      end\n    end\n\n    exit 1 unless success\n  end\n\n  desc \"Validate all series.yml files against SeriesSchema\"\n  task series: :environment do\n    success = validate_files(\"data/*/series.yml\", SeriesSchema, \"series.yml\")\n    exit 1 unless success\n  end\n\n  desc \"Validate all sponsors.yml files against SeriesSchema\"\n  task sponsors: :environment do\n    success = validate_array_files(\"data/**/sponsors.yml\", SponsorsSchema, \"sponsors.yml\")\n    exit 1 unless success\n  end\n\n  desc \"Validate all venue.yml files against VenueSchema\"\n  task venues: :environment do\n    success = validate_files(\"data/**/venue.yml\", VenueSchema, \"venue.yml\")\n    exit 1 unless success\n  end\n\n  desc \"Validate speakers.yml against SpeakerSchema\"\n  task speakers: :environment do\n    success = validate_array_files(\"data/speakers.yml\", SpeakerSchema, \"speakers.yml\")\n    exit 1 unless success\n  end\n\n  desc \"Validate all videos.yml files against VideoSchema\"\n  task videos: :environment do\n    success = validate_array_files(\"data/**/videos.yml\", VideoSchema, \"videos.yml\")\n    exit 1 unless success\n  end\n\n  desc \"Validate all schedule.yml files against ScheduleSchema\"\n  task schedules: :environment do\n    success = validate_files(\"data/**/schedule.yml\", ScheduleSchema, \"schedule.yml\")\n    exit 1 unless success\n  end\n\n  desc \"Validate featured_cities.yml against FeaturedCitySchema\"\n  task featured_cities: :environment do\n    success = validate_array_files(\"data/featured_cities.yml\", FeaturedCitySchema, \"featured_cities.yml\")\n    exit 1 unless success\n  end\n\n  desc \"Validate all involvements.yml files against InvolvementSchema\"\n  task involvements: :environment do\n    success = validate_array_files(\"data/**/involvements.yml\", InvolvementSchema, \"involvements.yml\")\n    exit 1 unless success\n  end\n\n  desc \"Validate all transcripts.yml files against TranscriptSchema\"\n  task transcripts: :environment do\n    success = validate_array_files(\"data/**/transcripts.yml\", TranscriptSchema, \"transcripts.yml\")\n    exit 1 unless success\n  end\n\n  def validate_unique_speaker_fields\n    speakers = YAML.load_file(Rails.root.join(\"data/speakers.yml\"))\n    success = true\n\n    slug_duplicates = speakers.map { |s| s[\"slug\"] }.compact.tally.select { |_, count| count > 1 }\n    github_duplicates = speakers.map { |s| s[\"github\"] }.select(&:present?).tally.select { |_, count| count > 1 }\n\n    if slug_duplicates.any?\n      puts Gum.style(\"Duplicate speaker slugs found (#{slug_duplicates.count}):\", foreground: \"1\")\n      puts\n      slug_duplicates.each do |slug, count|\n        puts Gum.style(\"❌ #{slug} (#{count} occurrences)\", foreground: \"1\")\n      end\n      puts\n      success = false\n    else\n      puts Gum.style(\"✓ All speaker slugs are unique\", foreground: \"2\")\n    end\n\n    if github_duplicates.any?\n      puts Gum.style(\"Duplicate speaker GitHub handles found (#{github_duplicates.count}):\", foreground: \"1\")\n      puts\n      github_duplicates.each do |github, count|\n        puts Gum.style(\"❌ #{github} (#{count} occurrences)\", foreground: \"1\")\n      end\n      puts\n      success = false\n    else\n      puts Gum.style(\"✓ All speaker GitHub handles are unique\", foreground: \"2\")\n    end\n\n    success\n  end\n\n  desc \"Validate that speaker slugs and GitHub handles are unique\"\n  task unique_speakers: :environment do\n    exit 1 unless validate_unique_speaker_fields\n  end\n\n  def validate_speakers_in_videos\n    speakers_data = YAML.load_file(Rails.root.join(\"data/speakers.yml\"))\n    known_names = Set.new\n\n    speakers_data.each do |speaker|\n      known_names << speaker[\"name\"]\n      Array(speaker[\"aliases\"]).each { |a| known_names << a[\"name\"] }\n    end\n\n    files = Dir.glob(Rails.root.join(\"data/**/videos.yml\"))\n    missing = []\n\n    files.each do |file|\n      data = YAML.load_file(file)\n      relative_path = file.sub(\"#{Rails.root}/data/\", \"\")\n\n      Array(data).each do |video|\n        Array(video[\"speakers\"]).each do |name|\n          unless known_names.include?(name)\n            missing << {path: relative_path, speaker: name}\n          end\n        end\n\n        Array(video[\"talks\"]).each do |talk|\n          Array(talk[\"speakers\"]).each do |name|\n            unless known_names.include?(name)\n              missing << {path: relative_path, speaker: name}\n            end\n          end\n        end\n      end\n    end\n\n    if missing.any?\n      unique_speakers = missing.map { |m| m[:speaker] }.uniq.sort\n\n      puts Gum.style(\"Speakers referenced in videos.yml but missing from speakers.yml (#{unique_speakers.count}):\", foreground: \"1\")\n      puts\n\n      missing.group_by { |m| m[:speaker] }.sort_by { |name, _| name }.each do |name, occurrences|\n        puts Gum.style(\"❌ #{name}\", foreground: \"1\")\n        occurrences.each { |o| puts \"   #{o[:path]}\" }\n      end\n\n      puts\n      false\n    else\n      puts Gum.style(\"✓ All speakers in videos.yml exist in speakers.yml\", foreground: \"2\")\n      true\n    end\n  end\n\n  desc \"Validate that all speakers in videos.yml exist in speakers.yml\"\n  task speakers_in_videos: :environment do\n    exit 1 unless validate_speakers_in_videos\n  end\n\n  desc \"Validate that all Static::Video records have unique ids\"\n  task unique_video_ids: :environment do\n    all_ids = []\n\n    Static::Video.all.each do |video|\n      all_ids << video.id\n      video.talks.each { |talk| all_ids << talk.id }\n    end\n\n    duplicates = all_ids.tally.select { |_id, count| count > 1 }\n\n    if duplicates.any?\n      puts Gum.style(\"Duplicate video ids found (#{duplicates.count}):\", foreground: \"1\")\n      puts\n\n      duplicates.each do |id, count|\n        puts Gum.style(\"❌ #{id} (#{count} occurrences)\", foreground: \"1\")\n      end\n\n      puts\n\n      exit 1\n    else\n      puts Gum.style(\"✓ All video ids are unique\", foreground: \"2\")\n    end\n  end\n\n  desc \"Validate that all YouTube videos have a published_at date\"\n  task youtube_published_at: :environment do\n    missing_published_at = []\n\n    Static::Video.all.each do |video|\n      if video.video_provider == \"youtube\" && (video.published_at.blank? || video.published_at == \"TODO\")\n        missing_published_at << video\n      end\n\n      video.talks.each do |talk|\n        if talk.video_provider == \"youtube\" && (talk.published_at.blank? || talk.published_at == \"TODO\")\n          missing_published_at << talk\n        end\n      end\n    end\n\n    if missing_published_at.any?\n      puts Gum.style(\"YouTube videos missing published_at date (#{missing_published_at.count}):\", foreground: \"1\")\n      puts\n\n      missing_published_at.each do |video|\n        puts Gum.style(\"❌ #{video.id} (#{video.title})\", foreground: \"1\")\n      end\n\n      puts\n\n      exit 1\n    else\n      puts Gum.style(\"✓ All YouTube videos have a published_at date\", foreground: \"2\")\n    end\n  end\n\n  def validate_speaker_duplicates\n    report = Gum.spin(\"Checking for speaker duplicates...\", spinner: \"dot\") do\n      User::DuplicateDetector.report\n    end\n\n    has_duplicates = report != \"No duplicates found.\"\n\n    if has_duplicates\n      puts Gum.style(report, foreground: \"1\")\n      puts\n      puts Gum.style(\"To fix: Make sure the name in speakers.yml matches the reference in the videos.yml files.\", foreground: \"3\")\n      puts\n    else\n      puts Gum.style(\"✓ No unresolved speaker duplicates found\", foreground: \"2\")\n    end\n\n    !has_duplicates\n  end\n\n  desc \"Validate that there are no unresolved speaker duplicates\"\n  task speaker_duplicates: :environment do\n    exit 1 unless validate_speaker_duplicates\n  end\n\n  def build_city_alias_lookup\n    alias_to_canonical = {}\n\n    Static::City.all.each do |city|\n      Array(city.aliases).each do |alias_name|\n        alias_to_canonical[alias_name.downcase] = city.name\n      end\n    end\n\n    alias_to_canonical\n  end\n\n  def validate_event_city_names\n    alias_to_canonical = build_city_alias_lookup\n    files = Dir.glob(Rails.root.join(\"data/**/event.yml\"))\n    issues = []\n\n    files.each do |file|\n      data = YAML.load_file(file)\n      location = data[\"location\"]\n\n      next if location.blank?\n\n      city_part = location.split(\",\").first&.strip\n\n      next if city_part.blank?\n\n      canonical = alias_to_canonical[city_part.downcase]\n\n      if canonical && canonical.downcase != city_part.downcase\n        relative_path = file.sub(\"#{Rails.root}/data/\", \"\")\n\n        issues << {\n          path: relative_path,\n          field: \"location\",\n          current: city_part,\n          canonical: canonical,\n          value: location\n        }\n      end\n    end\n\n    if issues.any?\n      puts Gum.style(\"Events using city aliases instead of canonical names (#{issues.count}):\", foreground: \"1\")\n      puts\n\n      issues.each do |issue|\n        puts Gum.style(\"❌ #{issue[:path]}\", foreground: \"1\")\n        puts \"   #{issue[:field]}: \\\"#{issue[:value]}\\\"\"\n        puts \"   Should use \\\"#{issue[:canonical]}\\\" instead of \\\"#{issue[:current]}\\\"\"\n        puts\n      end\n\n      false\n    else\n      puts Gum.style(\"✓ All events use canonical city names\", foreground: \"2\")\n\n      true\n    end\n  end\n\n  def check_city_alias(city_name, field, path, alias_to_canonical, issues)\n    return if city_name.blank?\n\n    canonical = alias_to_canonical[city_name.downcase]\n\n    if canonical && canonical.downcase != city_name.downcase\n      issues << {\n        path: path,\n        field: field,\n        current: city_name,\n        canonical: canonical,\n        value: city_name\n      }\n    end\n  end\n\n  desc \"Validate that event locations use canonical city names (not aliases)\"\n  task event_city_names: :environment do\n    exit 1 unless validate_event_city_names\n  end\n\n  def validate_video_city_names\n    alias_to_canonical = build_city_alias_lookup\n    files = Dir.glob(Rails.root.join(\"data/**/videos.yml\"))\n    issues = []\n\n    files.each do |file|\n      data = YAML.load_file(file)\n      relative_path = file.sub(\"#{Rails.root}/data/\", \"\")\n\n      Array(data).each_with_index do |video, index|\n        location = video[\"location\"]\n\n        next if location.blank?\n\n        city_part = location.split(\",\").first&.strip\n\n        next if city_part.blank?\n        next if city_part.downcase == \"online\" || city_part.downcase == \"remote\"\n\n        canonical = alias_to_canonical[city_part.downcase]\n\n        if canonical && canonical.downcase != city_part.downcase\n          video_id = video[\"video_id\"] || video[\"id\"] || \"index #{index}\"\n\n          issues << {\n            path: relative_path,\n            field: \"videos[#{video_id}].location\",\n            current: city_part,\n            canonical: canonical,\n            value: location\n          }\n        end\n      end\n    end\n\n    if issues.any?\n      puts Gum.style(\"Videos using city aliases instead of canonical names (#{issues.count}):\", foreground: \"1\")\n      puts\n      issues.each do |issue|\n        puts Gum.style(\"❌ #{issue[:path]}\", foreground: \"1\")\n        puts \"   #{issue[:field]}: \\\"#{issue[:value]}\\\"\"\n        puts \"   Should use \\\"#{issue[:canonical]}\\\" instead of \\\"#{issue[:current]}\\\"\"\n        puts\n      end\n      false\n    else\n      puts Gum.style(\"✓ All videos use canonical city names\", foreground: \"2\")\n      true\n    end\n  end\n\n  desc \"Validate that video locations use canonical city names (not aliases)\"\n  task video_city_names: :environment do\n    exit 1 unless validate_video_city_names\n  end\n\n  desc \"Validate all city-related data\"\n  task cities: [:event_city_names, :video_city_names]\n\n  desc \"Validate all YAML files\"\n  task all: :environment do\n    results = []\n\n    puts Gum.style(\"Validating event.yml files\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_files(\"data/**/event.yml\", EventSchema, \"event.yml\") do |data, errors|\n      is_meetup = data[\"kind\"] == \"meetup\"\n      unless is_meetup\n        if data[\"start_date\"].nil? || data[\"start_date\"].to_s.strip.empty?\n          errors << {\"error\" => \"start_date is required for non-meetup events\", \"data_pointer\" => \"/start_date\"}\n        end\n        if data[\"end_date\"].nil? || data[\"end_date\"].to_s.strip.empty?\n          errors << {\"error\" => \"end_date is required for non-meetup events\", \"data_pointer\" => \"/end_date\"}\n        end\n      end\n    end\n\n    puts Gum.style(\"Validating series.yml files\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_files(\"data/*/series.yml\", SeriesSchema, \"series.yml\")\n\n    puts Gum.style(\"Validating cfp.yml files\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_array_files(\"data/**/cfp.yml\", CFPSchema, \"cfp.yml\")\n\n    puts Gum.style(\"Validating sponsors.yml files\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_array_files(\"data/**/sponsors.yml\", SponsorsSchema, \"sponsors.yml\")\n\n    puts Gum.style(\"Validating venue.yml files\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_files(\"data/**/venue.yml\", VenueSchema, \"venue.yml\")\n\n    puts Gum.style(\"Validating speakers.yml\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_array_files(\"data/speakers.yml\", SpeakerSchema, \"speakers.yml\")\n\n    puts Gum.style(\"Validating videos.yml files\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_array_files(\"data/**/videos.yml\", VideoSchema, \"videos.yml\")\n\n    puts Gum.style(\"Validating schedule.yml files\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_files(\"data/**/schedule.yml\", ScheduleSchema, \"schedule.yml\")\n\n    puts Gum.style(\"Validating featured_cities.yml\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_array_files(\"data/featured_cities.yml\", FeaturedCitySchema, \"featured_cities.yml\")\n\n    puts Gum.style(\"Validating involvements.yml files\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_array_files(\"data/**/involvements.yml\", InvolvementSchema, \"involvements.yml\")\n\n    puts Gum.style(\"Validating transcripts.yml files\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_array_files(\"data/**/transcripts.yml\", TranscriptSchema, \"transcripts.yml\")\n\n    puts Gum.style(\"Validating unique speaker slugs and GitHub handles\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_unique_speaker_fields\n\n    puts Gum.style(\"Validating unique video ids\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n\n    all_ids = []\n\n    Static::Video.all.each do |video|\n      all_ids << video.id\n      video.talks.each { |talk| all_ids << talk.id }\n    end\n\n    duplicates = all_ids.tally.select { |_id, count| count > 1 }\n\n    if duplicates.any?\n      puts Gum.style(\"Duplicate video ids found (#{duplicates.count}):\", foreground: \"1\")\n      puts\n\n      duplicates.each do |id, count|\n        puts Gum.style(\"❌ #{id} (#{count} occurrences)\", foreground: \"1\")\n      end\n\n      puts\n\n      results << false\n    else\n      puts Gum.style(\"✓ All video ids are unique\", foreground: \"2\")\n\n      results << true\n    end\n\n    puts Gum.style(\"Validating YouTube videos have published_at\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n\n    missing_published_at = []\n\n    Static::Video.all.each do |video|\n      if video.video_provider == \"youtube\" && (video.published_at.blank? || video.published_at == \"TODO\")\n        missing_published_at << video\n      end\n\n      video.talks.each do |talk|\n        if talk.video_provider == \"youtube\" && (talk.published_at.blank? || talk.published_at == \"TODO\")\n          missing_published_at << talk\n        end\n      end\n    end\n\n    if missing_published_at.any?\n      puts Gum.style(\"YouTube videos missing published_at date (#{missing_published_at.count}):\", foreground: \"1\")\n      puts\n\n      missing_published_at.each do |video|\n        puts Gum.style(\"❌ #{video.id} (#{video.title})\", foreground: \"1\")\n      end\n\n      puts\n\n      results << false\n    else\n      puts Gum.style(\"✓ All YouTube videos have a published_at date\", foreground: \"2\")\n\n      results << true\n    end\n\n    if Rails.env.development?\n      puts Gum.style(\"Validating speaker duplicates\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n      results << validate_speaker_duplicates\n    end\n\n    puts Gum.style(\"Validating event city names\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_event_city_names\n\n    puts Gum.style(\"Validating video city names\", border: \"rounded\", padding: \"0 2\", margin: \"1 0\", border_foreground: \"5\")\n    results << validate_video_city_names\n\n    puts\n    if results.all?\n      puts Gum.style(\"All validations passed!\", border: \"rounded\", padding: \"0 2\", foreground: \"2\", border_foreground: \"2\")\n    else\n      puts Gum.style(\"Some validations failed\", border: \"rounded\", padding: \"0 2\", foreground: \"1\", border_foreground: \"1\")\n    end\n\n    exit 1 unless results.all?\n  end\nend\n"
  },
  {
    "path": "lib/templates/erb/scaffold/_form.html.erb.tt",
    "content": "<%%= form_with(model: <%= model_resource_name %>, class: \"contents\") do |form| %>\n  <%% if <%= singular_table_name %>.errors.any? %>\n    <div id=\"error_explanation\" class=\"bg-red-50 text-red-500 px-3 py-2 font-medium rounded-lg mt-3\">\n      <h2><%%= pluralize(<%= singular_table_name %>.errors.count, \"error\") %> prohibited this <%= singular_table_name %> from being saved:</h2>\n\n      <ul>\n        <%% <%= singular_table_name %>.errors.each do |error| %>\n          <li><%%= error.full_message %></li>\n        <%% end %>\n      </ul>\n    </div>\n  <%% end %>\n\n<% attributes.each do |attribute| -%>\n  <div class=\"my-5\">\n<% if attribute.password_digest? -%>\n    <%%= form.label :password %>\n    <%%= form.password_field :password %>\n</div>\n\n<div class=\"my-5\">\n    <%%= form.label :password_confirmation %>\n    <%%= form.password_field :password_confirmation, class: \"input input-bordered w-full\" %>\n<% elsif attribute.attachments? -%>\n    <%%= form.label :<%= attribute.column_name %> %>\n    <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, multiple: true, class: \"input input-bordered w-full\" %>\n<% else -%>\n    <%%= form.label :<%= attribute.column_name %> %>\n<% if attribute.field_type == :text_area -%>\n    <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, rows: 4, class: \"input input-bordered w-full\" %>\n<% elsif attribute.field_type == :check_box -%>\n    <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, class: \"block mt-2 h-5 w-5\" %>\n<% else -%>\n    <%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, class: \"input input-bordered w-full\" %>\n<% end -%>\n<% end -%>\n  </div>\n\n<% end -%>\n  <div class=\"inline\">\n    <%%= form.submit class: \"rounded-lg py-3 px-5 bg-blue-600 text-white inline-block font-medium cursor-pointer\" %>\n  </div>\n<%% end %>\n"
  },
  {
    "path": "lib/templates/erb/scaffold/edit.html.erb.tt",
    "content": "<div class=\"mx-auto md:w-2/3 w-full\">\n  <h1 class=\"font-bold text-4xl\">Editing <%= human_name.downcase %></h1>\n\n  <%%= render \"form\", <%= singular_table_name %>: @<%= singular_table_name %> %>\n\n  <%%= link_to \"Show this <%= human_name.downcase %>\", @<%= singular_table_name %>, class: \"ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium\" %>\n  <%%= link_to \"Back to <%= human_name.pluralize.downcase %>\", <%= index_helper %>_path, class: \"ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium\" %>\n</div>\n"
  },
  {
    "path": "lib/templates/erb/scaffold/index.html.erb.tt",
    "content": "<div class=\"w-full\">\n  <%% if notice.present? %>\n    <p class=\"py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block\" id=\"notice\"><%%= notice %></p>\n  <%% end %>\n\n  <div class=\"flex justify-between items-center\">\n    <h1 class=\"font-bold text-4xl\"><%= human_name.pluralize %></h1>\n    <%%= link_to 'New <%= human_name.downcase %>', new_<%= singular_route_name %>_path, class: \"rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium\" %>\n  </div>\n\n  <div id=\"<%= plural_table_name %>\" class=\"min-w-full\">\n    <%%= render @<%= plural_table_name %> %>\n  </div>\n</div>\n"
  },
  {
    "path": "lib/templates/erb/scaffold/new.html.erb.tt",
    "content": "<div class=\"mx-auto md:w-2/3 w-full\">\n  <h1 class=\"font-bold text-4xl\">New <%= human_name.downcase %></h1>\n\n  <%%= render \"form\", <%= singular_table_name %>: @<%= singular_table_name %> %>\n\n  <%%= link_to 'Back to <%= human_name.pluralize.downcase %>', <%= index_helper %>_path, class: \"ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium\" %>\n</div>\n"
  },
  {
    "path": "lib/templates/erb/scaffold/partial.html.erb.tt",
    "content": "<div id=\"<%%= dom_id <%= singular_name %> %>\">\n<% attributes.reject(&:password_digest?).each do |attribute| -%>\n  <p class=\"my-5\">\n    <strong class=\"block font-medium mb-1\"><%= attribute.human_name %>:</strong>\n<% if attribute.attachment? -%>\n    <%%= link_to <%= singular_name %>.<%= attribute.column_name %>.filename, <%= singular_name %>.<%= attribute.column_name %> if <%= singular_name %>.<%= attribute.column_name %>.attached? %>\n<% elsif attribute.attachments? -%>\n    <%% <%= singular_name %>.<%= attribute.column_name %>.each do |<%= attribute.singular_name %>| %>\n      <div><%%= link_to <%= attribute.singular_name %>.filename, <%= attribute.singular_name %> %></div>\n    <%% end %>\n<% else -%>\n    <%%= <%= singular_name %>.<%= attribute.column_name %> %>\n<% end -%>\n  </p>\n\n<% end -%>\n  <%% if action_name != \"show\" %>\n    <%%= link_to \"Show this <%= human_name.downcase %>\", <%= singular_name %>, class: \"rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium\" %>\n    <%%= link_to 'Edit this <%= human_name.downcase %>', edit_<%= singular_name %>_path(<%= singular_name %>), class: \"rounded-lg py-3 ml-2 px-5 bg-gray-100 inline-block font-medium\" %>\n    <hr class=\"mt-6\">\n  <%% end %>\n</div>\n"
  },
  {
    "path": "lib/templates/erb/scaffold/show.html.erb.tt",
    "content": "<div class=\"mx-auto md:w-2/3 w-full flex\">\n  <div class=\"mx-auto\">\n    <%% if notice.present? %>\n      <p class=\"py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block\" id=\"notice\"><%%= notice %></p>\n    <%% end %>\n\n    <%%= render @<%= singular_table_name %> %>\n\n    <%%= link_to 'Edit this <%= singular_table_name %>', edit_<%= singular_table_name %>_path(@<%= singular_table_name %>), class: \"mt-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium\" %>\n    <div class=\"inline-block ml-2\">\n      <%%= button_to 'Destroy this <%= singular_table_name %>', <%= singular_table_name %>_path(@<%= singular_table_name %>), method: :delete, class: \"mt-2 rounded-lg py-3 px-5 bg-gray-100 font-medium\" %>\n    </div>\n    <%%= link_to 'Back to <%= plural_table_name %>', <%= index_helper %>_path, class: \"ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium\" %>\n  </div>\n</div>\n"
  },
  {
    "path": "log/.keep",
    "content": ""
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"app\",\n  \"private\": \"true\",\n  \"dependencies\": {\n    \"@appsignal/javascript\": \"^1.3.26\",\n    \"@github/combobox-nav\": \"^3.0.1\",\n    \"@hotwired/hotwire-native-bridge\": \"^1.1.0\",\n    \"@hotwired/stimulus\": \"^3.2.1\",\n    \"@hotwired/turbo-rails\": \"^8.0.4\",\n    \"@josefarias/hotwire_combobox\": \"^0.4.0\",\n    \"@rails/request.js\": \"^0.0.11\",\n    \"@splidejs/splide\": \"^4.1.4\",\n    \"@tailwindcss/forms\": \"^0.5.3\",\n    \"@tailwindcss/typography\": \"^0.5.15\",\n    \"chart.js\": \"^4.3.0\",\n    \"chartkick\": \"^5.0.1\",\n    \"flag-icons\": \"^7.5.0\",\n    \"maplibre-gl\": \"^5.15.0\",\n    \"rfs\": \"^10.0.0\",\n    \"stimulus-use\": \"^0.52.0\",\n    \"tippy.js\": \"^6.3.7\",\n    \"vlitejs\": \"^7.3.2\",\n    \"yaml\": \"^2.7.1\"\n  },\n  \"scripts\": {\n    \"build\": \"bin/vite build\",\n    \"lint\": \"standard\",\n    \"lint:yml\": \"yarn prettier --check data/**/**/*.yml\",\n    \"format\": \"standard --fix\",\n    \"format:yml\": \"node yaml/enforce_strings.mjs && yarn run lint:yml --write\",\n    \"herb:lint\": \"herb-lint\"\n  },\n  \"packageManager\": \"yarn@1.22.19\",\n  \"devDependencies\": {\n    \"@herb-tools/linter\": \"^0.9.2\",\n    \"autoprefixer\": \"^10.4.14\",\n    \"daisyui\": \"^4.12.14\",\n    \"postcss\": \"^8.4.38\",\n    \"postcss-import\": \"^16.1.0\",\n    \"postcss-nested\": \"^6.0.1\",\n    \"prettier\": \"^2.8.8\",\n    \"prettier-plugin-tailwindcss\": \"^0.3.0\",\n    \"standard\": \"^17.1.0\",\n    \"stimulus-vite-helpers\": \"^3.1.0\",\n    \"tailwindcss\": \"^3.4.4\",\n    \"vite\": \"^6.4.1\",\n    \"vite-plugin-rails\": \"^0.5.0\"\n  },\n  \"standard\": {\n    \"globals\": [\n      \"requestAnimationFrame\"\n    ]\n  }\n}\n"
  },
  {
    "path": "postcss.config.js",
    "content": "module.exports = {\n  plugins: {\n    'postcss-import': {},\n    'tailwindcss/nesting': {},\n    tailwindcss: {},\n    rfs: {\n      twoDimensional: false,\n      baseValue: 14,\n      unit: 'rem',\n      breakpoint: 1200,\n      breakpointUnit: 'px',\n      factor: 5,\n      safariIframeResizeBugFix: false\n    },\n    autoprefixer: {}\n  }\n}\n"
  },
  {
    "path": "public/400.html",
    "content": "<!doctype html>\n\n<html lang=\"en\">\n\n  <head>\n\n    <title>The server cannot process the request due to a client error (400 Bad Request)</title>\n\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"initial-scale=1, width=device-width\">\n    <meta name=\"robots\" content=\"noindex, nofollow\">\n\n    <style>\n\n      *, *::before, *::after {\n        box-sizing: border-box;\n      }\n\n      * {\n        margin: 0;\n      }\n\n      html {\n        font-size: 16px;\n      }\n\n      body {\n        background: #FFF;\n        color: #261B23;\n        display: grid;\n        font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Aptos, Roboto, \"Segoe UI\", \"Helvetica Neue\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n        font-size: clamp(1rem, 2.5vw, 2rem);\n        -webkit-font-smoothing: antialiased;\n        font-style: normal;\n        font-weight: 400;\n        letter-spacing: -0.0025em;\n        line-height: 1.4;\n        min-height: 100vh;\n        place-items: center;\n        text-rendering: optimizeLegibility;\n        -webkit-text-size-adjust: 100%;\n      }\n\n      a {\n        color: inherit;\n        font-weight: 700;\n        text-decoration: underline;\n        text-underline-offset: 0.0925em;\n      }\n\n      b, strong {\n        font-weight: 700;\n      }\n\n      i, em {\n        font-style: italic;\n      }\n\n      main {\n        display: grid;\n        gap: 1em;\n        padding: 2em;\n        place-items: center;\n        text-align: center;\n      }\n\n      main header {\n        width: min(100%, 12em);\n      }\n\n      main header svg {\n        height: auto;\n        max-width: 100%;\n        width: 100%;\n      }\n\n      main article {\n        width: min(100%, 30em);\n      }\n\n      main article p {\n        font-size: 75%;\n      }\n\n      main article br {\n\n        display: none;\n\n        @media(min-width: 48em) {\n          display: inline;\n        }\n\n      }\n\n    </style>\n\n  </head>\n\n  <body>\n\n    <!-- This file lives in public/400.html -->\n\n    <main>\n      <header>\n        <svg height=\"172\" viewBox=\"0 0 480 172\" width=\"480\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m124.48 3.00509-45.6889 100.02991h26.2239v-28.1168h38.119v28.1168h21.628v35.145h-21.628v30.82h-37.308v-30.82h-72.1833v-31.901l50.2851-103.27391zm115.583 168.69891c-40.822 0-64.884-35.146-64.884-85.7015 0-50.5554 24.062-85.700907 64.884-85.700907 40.823 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.061 85.7015-64.884 85.7015zm0-133.2831c-17.572 0-22.709 21.8984-22.709 47.5816 0 25.6835 5.137 47.5815 22.709 47.5815 17.303 0 22.71-21.898 22.71-47.5815 0-25.6832-5.407-47.5816-22.71-47.5816zm140.456 133.2831c-40.823 0-64.884-35.146-64.884-85.7015 0-50.5554 24.061-85.700907 64.884-85.700907 40.822 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.062 85.7015-64.884 85.7015zm0-133.2831c-17.573 0-22.71 21.8984-22.71 47.5816 0 25.6835 5.137 47.5815 22.71 47.5815 17.302 0 22.709-21.898 22.709-47.5815 0-25.6832-5.407-47.5816-22.709-47.5816z\" fill=\"#f0eff0\"/><path d=\"m123.606 85.4445c3.212 1.0523 5.538 4.2089 5.538 8.0301 0 6.1472-4.209 9.5254-11.298 9.5254h-15.617v-34.0033h14.565c7.089 0 11.353 3.1566 11.353 9.2484 0 3.6551-2.049 6.3134-4.541 7.1994zm-12.904-2.9905h5.095c2.603 0 3.988-.9968 3.988-3.1013 0-2.1044-1.385-3.0459-3.988-3.0459h-5.095zm0 6.6456v6.5902h5.981c2.492 0 3.877-1.3291 3.877-3.2674 0-2.049-1.385-3.3228-3.877-3.3228zm43.786 13.9004h-8.362v-1.274c-.831.831-3.323 1.717-5.981 1.717-4.929 0-9.083-2.769-9.083-8.0301 0-4.818 4.154-7.9193 9.581-7.9193 2.049 0 4.486.6646 5.483 1.3845v-1.606c0-1.606-.942-2.9905-3.046-2.9905-1.606 0-2.548.7199-2.935 1.8275h-8.197c.72-4.8181 4.985-8.6393 11.409-8.6393 7.088 0 11.131 3.7659 11.131 10.2453zm-8.362-6.9779v-1.4399c-.554-1.0522-2.049-1.7167-3.655-1.7167-1.717 0-3.434.7199-3.434 2.3813 0 1.7168 1.717 2.4367 3.434 2.4367 1.606 0 3.101-.6645 3.655-1.6614zm27.996 6.9779v-1.994c-1.163 1.329-3.599 2.548-6.147 2.548-7.199 0-11.131-5.8151-11.131-13.0145s3.932-13.0143 11.131-13.0143c2.548 0 4.984 1.2184 6.147 2.5475v-13.0697h8.695v35.997zm0-9.1931v-6.5902c-.664-1.3291-2.159-2.326-3.821-2.326-2.99 0-4.763 2.4368-4.763 5.6488s1.773 5.5934 4.763 5.5934c1.717 0 3.157-.9415 3.821-2.326zm35.471-2.049h-3.101v11.2421h-8.806v-34.0033h15.285c7.31 0 12.35 4.1535 12.35 11.5744 0 5.1503-2.603 8.6947-6.757 10.2453l7.975 12.1836h-9.858zm-3.101-15.2849v8.1962h5.538c3.156 0 4.596-1.606 4.596-4.0981s-1.44-4.0981-4.596-4.0981zm36.957 17.8323h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.643 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.515-13.0143 7.643 0 11.962 5.095 11.962 12.5159v2.1598h-16.115c.277 2.9905 1.827 4.5965 4.32 4.5965 1.772 0 3.156-.7753 3.655-2.4921zm-3.822-10.0237c-2.049 0-3.433 1.2737-3.987 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.545-3.5997zm30.98 27.5234v-10.799c-1.163 1.329-3.6 2.548-6.147 2.548-7.2 0-11.132-5.9259-11.132-13.0145 0-7.144 3.932-13.0143 11.132-13.0143 2.547 0 4.984 1.2184 6.147 2.5475v-1.9937h8.695v33.726zm0-17.9981v-6.5902c-.665-1.3291-2.105-2.326-3.821-2.326-2.991 0-4.763 2.4368-4.763 5.6488s1.772 5.5934 4.763 5.5934c1.661 0 3.156-.9415 3.821-2.326zm36.789-15.7279v24.921h-8.695v-2.16c-1.329 1.551-3.821 2.714-6.646 2.714-5.482 0-8.75-3.5999-8.75-9.1379v-16.3371h8.64v14.288c0 2.1045.996 3.5997 3.212 3.5997 1.606 0 3.101-1.0522 3.544-2.769v-15.1187zm19.084 16.2263h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.643 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.515-13.0143 7.643 0 11.963 5.095 11.963 12.5159v2.1598h-16.116c.277 2.9905 1.828 4.5965 4.32 4.5965 1.772 0 3.156-.7753 3.655-2.4921zm-3.822-10.0237c-2.049 0-3.433 1.2737-3.987 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.545-3.5997zm13.428 11.0206h8.474c.387 1.3845 1.606 2.1598 3.156 2.1598 1.44 0 2.548-.5538 2.548-1.7168 0-.9414-.72-1.2737-1.939-1.5506l-4.873-.9969c-4.154-.886-6.867-2.8797-6.867-7.2547 0-5.3165 4.762-8.4178 10.633-8.4178 6.812 0 10.522 3.1567 11.297 8.0855h-8.03c-.277-1.0522-1.052-1.9937-3.046-1.9937-1.273 0-2.326.5538-2.326 1.6614 0 .7753.554 1.163 1.717 1.3845l4.929 1.163c4.541 1.0522 6.978 3.4335 6.978 7.4763 0 5.3168-4.818 8.2518-10.91 8.2518-6.369 0-10.965-2.88-11.741-8.2518zm27.538-.8861v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.584v6.8671h5.205v6.7564h-5.205v8.307c0 1.9383.941 2.769 2.658 2.769.941 0 1.993-.2216 2.769-.5538v7.3654c-.997.443-2.88.775-4.818.775-5.871 0-9.193-2.769-9.193-9.0819z\" fill=\"#d30001\"/></svg>\n      </header>\n      <article>\n        <p><strong>The server cannot process the request due to a client error.</strong> Please check the request and try again. If you’re the application owner check the logs for more information.</p>\n      </article>\n    </main>\n\n  </body>\n\n</html>\n"
  },
  {
    "path": "public/404.html",
    "content": "<!doctype html>\n\n<html lang=\"en\">\n\n  <head>\n\n    <title>The page you were looking for doesn’t exist (404 Not found)</title>\n\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"initial-scale=1, width=device-width\">\n    <meta name=\"robots\" content=\"noindex, nofollow\">\n\n    <style>\n\n      *, *::before, *::after {\n        box-sizing: border-box;\n      }\n\n      * {\n        margin: 0;\n      }\n\n      html {\n        font-size: 16px;\n      }\n\n      body {\n        background: #FFF;\n        color: #261B23;\n        display: grid;\n        font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Aptos, Roboto, \"Segoe UI\", \"Helvetica Neue\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n        font-size: clamp(1rem, 2.5vw, 2rem);\n        -webkit-font-smoothing: antialiased;\n        font-style: normal;\n        font-weight: 400;\n        letter-spacing: -0.0025em;\n        line-height: 1.4;\n        min-height: 100vh;\n        place-items: center;\n        text-rendering: optimizeLegibility;\n        -webkit-text-size-adjust: 100%;\n      }\n\n      a {\n        color: inherit;\n        font-weight: 700;\n        text-decoration: underline;\n        text-underline-offset: 0.0925em;\n      }\n\n      b, strong {\n        font-weight: 700;\n      }\n\n      i, em {\n        font-style: italic;\n      }\n\n      main {\n        display: grid;\n        gap: 1em;\n        padding: 2em;\n        place-items: center;\n        text-align: center;\n      }\n\n      main header {\n        width: min(100%, 12em);\n      }\n\n      main header svg {\n        height: auto;\n        max-width: 100%;\n        width: 100%;\n      }\n\n      main article {\n        width: min(100%, 30em);\n      }\n\n      main article p {\n        font-size: 75%;\n      }\n\n      main article br {\n\n        display: none;\n\n        @media(min-width: 48em) {\n          display: inline;\n        }\n\n      }\n\n    </style>\n\n  </head>\n\n  <body>\n\n    <!-- This file lives in public/404.html -->\n\n    <main>\n      <header>\n        <svg height=\"172\" viewBox=\"0 0 480 172\" width=\"480\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m124.48 3.00509-45.6889 100.02991h26.2239v-28.1168h38.119v28.1168h21.628v35.145h-21.628v30.82h-37.308v-30.82h-72.1833v-31.901l50.2851-103.27391zm115.583 168.69891c-40.822 0-64.884-35.146-64.884-85.7015 0-50.5554 24.062-85.700907 64.884-85.700907 40.823 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.061 85.7015-64.884 85.7015zm0-133.2831c-17.572 0-22.709 21.8984-22.709 47.5816 0 25.6835 5.137 47.5815 22.709 47.5815 17.303 0 22.71-21.898 22.71-47.5815 0-25.6832-5.407-47.5816-22.71-47.5816zm165.328-35.41581-45.689 100.02991h26.224v-28.1168h38.119v28.1168h21.628v35.145h-21.628v30.82h-37.308v-30.82h-72.184v-31.901l50.285-103.27391z\" fill=\"#f0eff0\"/><path d=\"m157.758 68.9967v34.0033h-7.199l-14.233-19.8814v19.8814h-8.584v-34.0033h8.307l13.125 18.7184v-18.7184zm28.454 21.5428c0 7.6978-5.15 13.0145-12.737 13.0145-7.532 0-12.738-5.3167-12.738-13.0145s5.206-13.0143 12.738-13.0143c7.587 0 12.737 5.3165 12.737 13.0143zm-8.528 0c0-3.4336-1.496-5.8703-4.209-5.8703-2.659 0-4.154 2.4367-4.154 5.8703s1.495 5.8149 4.154 5.8149c2.713 0 4.209-2.3813 4.209-5.8149zm13.184 3.8766v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.584v6.8671h5.205v6.7564h-5.205v8.307c0 1.9383.941 2.769 2.658 2.769.941 0 1.994-.2216 2.769-.5538v7.3654c-.997.443-2.88.775-4.818.775-5.87 0-9.193-2.769-9.193-9.0819zm37.027 8.5839h-8.806v-34.0033h23.924v7.6978h-15.118v6.7564h13.9v7.5316h-13.9zm41.876-12.4605c0 7.6978-5.15 13.0145-12.737 13.0145-7.532 0-12.738-5.3167-12.738-13.0145s5.206-13.0143 12.738-13.0143c7.587 0 12.737 5.3165 12.737 13.0143zm-8.529 0c0-3.4336-1.495-5.8703-4.208-5.8703-2.659 0-4.154 2.4367-4.154 5.8703s1.495 5.8149 4.154 5.8149c2.713 0 4.208-2.3813 4.208-5.8149zm35.337-12.4605v24.921h-8.695v-2.16c-1.329 1.551-3.821 2.714-6.646 2.714-5.482 0-8.75-3.5999-8.75-9.1379v-16.3371h8.64v14.288c0 2.1045.997 3.5997 3.212 3.5997 1.606 0 3.101-1.0522 3.544-2.769v-15.1187zm4.076 24.921v-24.921h8.694v2.1598c1.385-1.5506 3.822-2.7136 6.701-2.7136 5.538 0 8.806 3.5997 8.806 9.1377v16.3371h-8.639v-14.2327c0-2.049-1.053-3.5443-3.268-3.5443-1.717 0-3.156.9969-3.6 2.7136v15.0634zm44.113 0v-1.994c-1.163 1.329-3.6 2.548-6.147 2.548-7.2 0-11.132-5.8151-11.132-13.0145s3.932-13.0143 11.132-13.0143c2.547 0 4.984 1.2184 6.147 2.5475v-13.0697h8.695v35.997zm0-9.1931v-6.5902c-.665-1.3291-2.16-2.326-3.821-2.326-2.991 0-4.763 2.4368-4.763 5.6488s1.772 5.5934 4.763 5.5934c1.717 0 3.156-.9415 3.821-2.326z\" fill=\"#d30001\"/></svg>\n      </header>\n      <article>\n        <p><strong>The page you were looking for doesn’t exist.</strong> You may have mistyped the address or the page may have moved. If you’re the application owner check the logs for more information.</p>\n      </article>\n    </main>\n\n  </body>\n\n</html>\n"
  },
  {
    "path": "public/406-unsupported-browser.html",
    "content": "<!doctype html>\n\n<html lang=\"en\">\n\n  <head>\n\n    <title>Your browser is not supported (406 Not Acceptable)</title>\n\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"initial-scale=1, width=device-width\">\n    <meta name=\"robots\" content=\"noindex, nofollow\">\n\n    <style>\n\n      *, *::before, *::after {\n        box-sizing: border-box;\n      }\n\n      * {\n        margin: 0;\n      }\n\n      html {\n        font-size: 16px;\n      }\n\n      body {\n        background: #FFF;\n        color: #261B23;\n        display: grid;\n        font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Aptos, Roboto, \"Segoe UI\", \"Helvetica Neue\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n        font-size: clamp(1rem, 2.5vw, 2rem);\n        -webkit-font-smoothing: antialiased;\n        font-style: normal;\n        font-weight: 400;\n        letter-spacing: -0.0025em;\n        line-height: 1.4;\n        min-height: 100vh;\n        place-items: center;\n        text-rendering: optimizeLegibility;\n        -webkit-text-size-adjust: 100%;\n      }\n\n      a {\n        color: inherit;\n        font-weight: 700;\n        text-decoration: underline;\n        text-underline-offset: 0.0925em;\n      }\n\n      b, strong {\n        font-weight: 700;\n      }\n\n      i, em {\n        font-style: italic;\n      }\n\n      main {\n        display: grid;\n        gap: 1em;\n        padding: 2em;\n        place-items: center;\n        text-align: center;\n      }\n\n      main header {\n        width: min(100%, 12em);\n      }\n\n      main header svg {\n        height: auto;\n        max-width: 100%;\n        width: 100%;\n      }\n\n      main article {\n        width: min(100%, 30em);\n      }\n\n      main article p {\n        font-size: 75%;\n      }\n\n      main article br {\n\n        display: none;\n\n        @media(min-width: 48em) {\n          display: inline;\n        }\n\n      }\n\n    </style>\n\n  </head>\n\n  <body>\n\n    <!-- This file lives in public/406-unsupported-browser.html -->\n\n    <main>\n      <header>\n        <svg height=\"172\" viewBox=\"0 0 480 172\" width=\"480\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m124.48 3.00509-45.6889 100.02991h26.2239v-28.1168h38.119v28.1168h21.628v35.145h-21.628v30.82h-37.308v-30.82h-72.1833v-31.901l50.2851-103.27391zm115.583 168.69891c-40.822 0-64.884-35.146-64.884-85.7015 0-50.5554 24.062-85.700907 64.884-85.700907 40.823 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.061 85.7015-64.884 85.7015zm0-133.2831c-17.572 0-22.709 21.8984-22.709 47.5816 0 25.6835 5.137 47.5815 22.709 47.5815 17.303 0 22.71-21.898 22.71-47.5815 0-25.6832-5.407-47.5816-22.71-47.5816zm202.906 9.7326h-41.093c-2.433-7.2994-7.84-12.4361-17.302-12.4361-16.221 0-25.413 17.5728-25.954 34.8752v1.3517c5.137-7.0291 16.221-12.4361 30.82-12.4361 33.524 0 54.881 24.0612 54.881 53.7998 0 33.253-23.791 58.396-61.64 58.396-21.628 0-39.741-10.003-50.825-27.576-9.733-14.599-13.788-32.442-13.788-54.3406 0-51.9072 24.331-89.485807 66.236-89.485807 32.712 0 53.258 18.654107 58.665 47.851907zm-82.727 66.2355c0 13.247 9.463 22.439 22.71 22.439 12.977 0 22.439-9.192 22.439-22.439 0-13.517-9.462-22.7091-22.439-22.7091-13.247 0-22.71 9.1921-22.71 22.7091z\" fill=\"#f0eff0\"/><path d=\"m100.761 68.9967v34.0033h-7.1991l-14.2326-19.8814v19.8814h-8.5839v-34.0033h8.307l13.125 18.7184v-18.7184zm28.454 21.5428c0 7.6978-5.15 13.0145-12.737 13.0145-7.532 0-12.738-5.3167-12.738-13.0145s5.206-13.0143 12.738-13.0143c7.587 0 12.737 5.3165 12.737 13.0143zm-8.529 0c0-3.4336-1.495-5.8703-4.208-5.8703-2.659 0-4.154 2.4367-4.154 5.8703s1.495 5.8149 4.154 5.8149c2.713 0 4.208-2.3813 4.208-5.8149zm13.185 3.8766v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.584v6.8671h5.205v6.7564h-5.205v8.307c0 1.9383.941 2.769 2.658 2.769.941 0 1.994-.2216 2.769-.5538v7.3654c-.997.443-2.88.775-4.818.775-5.87 0-9.193-2.769-9.193-9.0819zm39.02-25.4194h9.083l12.958 34.0033h-9.027l-2.436-6.5902h-12.35l-2.381 6.5902h-8.806zm4.431 10.5222-3.489 9.5807h6.978zm17.44 11.0206c0-7.6978 5.095-13.0143 12.572-13.0143 6.701 0 10.854 3.9874 11.574 9.8023h-8.418c-.221-1.4953-1.384-2.6029-3.156-2.6029-2.437 0-3.988 2.2706-3.988 5.8149s1.551 5.7595 3.988 5.7595c1.772 0 2.935-1.0522 3.156-2.5475h8.418c-.72 5.7596-4.873 9.8025-11.574 9.8025-7.477 0-12.572-5.3167-12.572-13.0145zm25.676 0c0-7.6978 5.095-13.0143 12.572-13.0143 6.701 0 10.854 3.9874 11.574 9.8023h-8.418c-.221-1.4953-1.384-2.6029-3.156-2.6029-2.437 0-3.988 2.2706-3.988 5.8149s1.551 5.7595 3.988 5.7595c1.772 0 2.935-1.0522 3.156-2.5475h8.418c-.72 5.7596-4.873 9.8025-11.574 9.8025-7.477 0-12.572-5.3167-12.572-13.0145zm42.013 3.7658h8.031c-.887 5.7597-5.206 9.2487-11.686 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.317-13.0143 12.516-13.0143 7.643 0 11.962 5.095 11.962 12.5159v2.1598h-16.115c.277 2.9905 1.827 4.5965 4.319 4.5965 1.773 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.433 1.2737-3.987 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.545-3.5997zm23.4 16.7244v10.799h-8.694v-33.726h8.694v1.9937c1.163-1.3291 3.6-2.5475 6.148-2.5475 7.199 0 11.131 5.8703 11.131 13.0143 0 7.0886-3.932 13.0145-11.131 13.0145-2.548 0-4.985-1.219-6.148-2.548zm0-13.7893v6.5902c.665 1.3845 2.16 2.326 3.822 2.326 2.99 0 4.762-2.3814 4.762-5.5934s-1.772-5.6488-4.762-5.6488c-1.717 0-3.157.9969-3.822 2.326zm21.892 7.1994v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.584v6.8671h5.206v6.7564h-5.206v8.307c0 1.9383.941 2.769 2.658 2.769.942 0 1.994-.2216 2.769-.5538v7.3654c-.997.443-2.88.775-4.818.775-5.87 0-9.193-2.769-9.193-9.0819zm39.458 8.5839h-8.363v-1.274c-.83.831-3.322 1.717-5.981 1.717-4.928 0-9.082-2.769-9.082-8.0301 0-4.818 4.154-7.9193 9.581-7.9193 2.049 0 4.486.6646 5.482 1.3845v-1.606c0-1.606-.941-2.9905-3.045-2.9905-1.606 0-2.548.7199-2.936 1.8275h-8.196c.72-4.8181 4.984-8.6393 11.408-8.6393 7.089 0 11.132 3.7659 11.132 10.2453zm-8.363-6.9779v-1.4399c-.553-1.0522-2.049-1.7167-3.655-1.7167-1.716 0-3.433.7199-3.433 2.3813 0 1.7168 1.717 2.4367 3.433 2.4367 1.606 0 3.102-.6645 3.655-1.6614zm20.742 4.9839v1.994h-8.694v-35.997h8.694v13.0697c1.163-1.3291 3.6-2.5475 6.148-2.5475 7.199 0 11.131 5.8149 11.131 13.0143s-3.932 13.0145-11.131 13.0145c-2.548 0-4.985-1.219-6.148-2.548zm0-13.7893v6.5902c.665 1.3845 2.105 2.326 3.822 2.326 2.99 0 4.762-2.3814 4.762-5.5934s-1.772-5.6488-4.762-5.6488c-1.662 0-3.157.9969-3.822 2.326zm28.759-20.2137v35.997h-8.695v-35.997zm19.172 27.3023h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.643 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.516-13.0143 7.642 0 11.962 5.095 11.962 12.5159v2.1598h-16.116c.277 2.9905 1.828 4.5965 4.32 4.5965 1.772 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.434 1.2737-3.988 3.5997h7.532c-.111-2.0491-1.384-3.5997-3.544-3.5997z\" fill=\"#d30001\"/></svg>\n      </header>\n      <article>\n        <p><strong>Your browser is not supported.</strong><br> Please upgrade your browser to continue.</p>\n      </article>\n    </main>\n\n  </body>\n\n</html>\n"
  },
  {
    "path": "public/422.html",
    "content": "<!doctype html>\n\n<html lang=\"en\">\n\n  <head>\n\n    <title>The change you wanted was rejected (422 Unprocessable Entity)</title>\n\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"initial-scale=1, width=device-width\">\n    <meta name=\"robots\" content=\"noindex, nofollow\">\n\n    <style>\n\n      *, *::before, *::after {\n        box-sizing: border-box;\n      }\n\n      * {\n        margin: 0;\n      }\n\n      html {\n        font-size: 16px;\n      }\n\n      body {\n        background: #FFF;\n        color: #261B23;\n        display: grid;\n        font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Aptos, Roboto, \"Segoe UI\", \"Helvetica Neue\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n        font-size: clamp(1rem, 2.5vw, 2rem);\n        -webkit-font-smoothing: antialiased;\n        font-style: normal;\n        font-weight: 400;\n        letter-spacing: -0.0025em;\n        line-height: 1.4;\n        min-height: 100vh;\n        place-items: center;\n        text-rendering: optimizeLegibility;\n        -webkit-text-size-adjust: 100%;\n      }\n\n      a {\n        color: inherit;\n        font-weight: 700;\n        text-decoration: underline;\n        text-underline-offset: 0.0925em;\n      }\n\n      b, strong {\n        font-weight: 700;\n      }\n\n      i, em {\n        font-style: italic;\n      }\n\n      main {\n        display: grid;\n        gap: 1em;\n        padding: 2em;\n        place-items: center;\n        text-align: center;\n      }\n\n      main header {\n        width: min(100%, 12em);\n      }\n\n      main header svg {\n        height: auto;\n        max-width: 100%;\n        width: 100%;\n      }\n\n      main article {\n        width: min(100%, 30em);\n      }\n\n      main article p {\n        font-size: 75%;\n      }\n\n      main article br {\n\n        display: none;\n\n        @media(min-width: 48em) {\n          display: inline;\n        }\n\n      }\n\n    </style>\n\n  </head>\n\n  <body>\n\n    <!-- This file lives in public/422.html -->\n\n    <main>\n      <header>\n        <svg height=\"172\" viewBox=\"0 0 480 172\" width=\"480\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m124.48 3.00509-45.6889 100.02991h26.2239v-28.1168h38.119v28.1168h21.628v35.145h-21.628v30.82h-37.308v-30.82h-72.1833v-31.901l50.2851-103.27391zm130.453 51.63681c0-8.9215-6.218-15.4099-15.681-15.4099-10.273 0-15.95 7.5698-16.491 16.4913h-44.608c3.244-30.8199 25.683-55.421707 61.099-55.421707 36.498 0 59.477 20.816907 59.477 51.636807 0 21.3577-14.869 36.7676-31.901 52.7186l-27.305 27.035h59.747v37.308h-120.306v-27.846l57.044-56.7736c11.084-11.8954 18.925-20.0059 18.925-29.7385zm140.455 0c0-8.9215-6.218-15.4099-15.68-15.4099-10.274 0-15.951 7.5698-16.492 16.4913h-44.608c3.245-30.8199 25.684-55.421707 61.1-55.421707 36.497 0 59.477 20.816907 59.477 51.636807 0 21.3577-14.87 36.7676-31.902 52.7186l-27.305 27.035h59.747v37.308h-120.305v-27.846l57.043-56.7736c11.085-11.8954 18.925-20.0059 18.925-29.7385z\" fill=\"#f0eff0\"/><path d=\"m19.3936 103.554c-8.9715 0-14.84183-5.0952-14.84183-14.4544v-20.1029h8.86083v19.3276c0 4.8181 2.2706 7.3102 5.981 7.3102 3.6551 0 5.9257-2.4921 5.9257-7.3102v-19.3276h8.8608v20.1583c0 9.3038-5.8149 14.399-14.7865 14.399zm18.734-.554v-24.921h8.6947v2.1598c1.3845-1.5506 3.8212-2.7136 6.701-2.7136 5.538 0 8.8054 3.5997 8.8054 9.1377v16.3371h-8.6393v-14.2327c0-2.049-1.0522-3.5443-3.2674-3.5443-1.7168 0-3.1567.9969-3.5997 2.7136v15.0634zm36.8584-1.994v10.799h-8.6946v-33.726h8.6946v1.9937c1.163-1.3291 3.5997-2.5475 6.1472-2.5475 7.1994 0 11.1314 5.8703 11.1314 13.0143 0 7.0886-3.932 13.0145-11.1314 13.0145-2.5475 0-4.9842-1.219-6.1472-2.548zm0-13.7893v6.5902c.6646 1.3845 2.1599 2.326 3.8213 2.326 2.9905 0 4.7626-2.3814 4.7626-5.5934s-1.7721-5.6488-4.7626-5.6488c-1.7168 0-3.1567.9969-3.8213 2.326zm36.789-9.2485v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.6949v-24.921h8.6949v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm26.769 12.5713c0 7.6978-5.15 13.0145-12.737 13.0145-7.532 0-12.738-5.3167-12.738-13.0145s5.206-13.0143 12.738-13.0143c7.587 0 12.737 5.3165 12.737 13.0143zm-8.528 0c0-3.4336-1.496-5.8703-4.209-5.8703-2.659 0-4.154 2.4367-4.154 5.8703s1.495 5.8149 4.154 5.8149c2.713 0 4.209-2.3813 4.209-5.8149zm10.352 0c0-7.6978 5.095-13.0143 12.571-13.0143 6.701 0 10.855 3.9874 11.574 9.8023h-8.417c-.222-1.4953-1.385-2.6029-3.157-2.6029-2.437 0-3.987 2.2706-3.987 5.8149s1.55 5.7595 3.987 5.7595c1.772 0 2.935-1.0522 3.157-2.5475h8.417c-.719 5.7596-4.873 9.8025-11.574 9.8025-7.476 0-12.571-5.3167-12.571-13.0145zm42.013 3.7658h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.643 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.516-13.0143 7.642 0 11.962 5.095 11.962 12.5159v2.1598h-16.116c.277 2.9905 1.828 4.5965 4.32 4.5965 1.772 0 3.156-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.434 1.2737-3.988 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.544-3.5997zm13.428 11.0206h8.473c.387 1.3845 1.606 2.1598 3.156 2.1598 1.44 0 2.548-.5538 2.548-1.7168 0-.9414-.72-1.2737-1.938-1.5506l-4.874-.9969c-4.153-.886-6.867-2.8797-6.867-7.2547 0-5.3165 4.763-8.4178 10.633-8.4178 6.812 0 10.522 3.1567 11.297 8.0855h-8.03c-.277-1.0522-1.052-1.9937-3.046-1.9937-1.273 0-2.326.5538-2.326 1.6614 0 .7753.554 1.163 1.717 1.3845l4.929 1.163c4.541 1.0522 6.978 3.4335 6.978 7.4763 0 5.3168-4.818 8.2518-10.91 8.2518-6.369 0-10.965-2.88-11.74-8.2518zm24.269 0h8.474c.387 1.3845 1.606 2.1598 3.156 2.1598 1.44 0 2.548-.5538 2.548-1.7168 0-.9414-.72-1.2737-1.939-1.5506l-4.873-.9969c-4.154-.886-6.867-2.8797-6.867-7.2547 0-5.3165 4.763-8.4178 10.633-8.4178 6.812 0 10.522 3.1567 11.297 8.0855h-8.03c-.277-1.0522-1.052-1.9937-3.046-1.9937-1.273 0-2.326.5538-2.326 1.6614 0 .7753.554 1.163 1.717 1.3845l4.929 1.163c4.541 1.0522 6.978 3.4335 6.978 7.4763 0 5.3168-4.818 8.2518-10.91 8.2518-6.369 0-10.965-2.88-11.741-8.2518zm47.918 7.6978h-8.363v-1.274c-.831.831-3.323 1.717-5.981 1.717-4.929 0-9.082-2.769-9.082-8.0301 0-4.818 4.153-7.9193 9.581-7.9193 2.049 0 4.485.6646 5.482 1.3845v-1.606c0-1.606-.941-2.9905-3.046-2.9905-1.606 0-2.547.7199-2.935 1.8275h-8.196c.72-4.8181 4.984-8.6393 11.408-8.6393 7.089 0 11.132 3.7659 11.132 10.2453zm-8.363-6.9779v-1.4399c-.554-1.0522-2.049-1.7167-3.655-1.7167-1.717 0-3.434.7199-3.434 2.3813 0 1.7168 1.717 2.4367 3.434 2.4367 1.606 0 3.101-.6645 3.655-1.6614zm20.742 4.9839v1.994h-8.695v-35.997h8.695v13.0697c1.163-1.3291 3.6-2.5475 6.147-2.5475 7.2 0 11.132 5.8149 11.132 13.0143s-3.932 13.0145-11.132 13.0145c-2.547 0-4.984-1.219-6.147-2.548zm0-13.7893v6.5902c.665 1.3845 2.105 2.326 3.821 2.326 2.991 0 4.763-2.3814 4.763-5.5934s-1.772-5.6488-4.763-5.6488c-1.661 0-3.156.9969-3.821 2.326zm28.759-20.2137v35.997h-8.695v-35.997zm19.172 27.3023h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.643 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.515-13.0143 7.643 0 11.962 5.095 11.962 12.5159v2.1598h-16.115c.277 2.9905 1.827 4.5965 4.32 4.5965 1.772 0 3.156-.7753 3.655-2.4921zm-3.822-10.0237c-2.049 0-3.433 1.2737-3.987 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.545-3.5997zm25.461-15.2849h24.311v7.6424h-15.561v5.3165h14.232v7.4763h-14.232v5.8703h15.561v7.6978h-24.311zm27.942 34.0033v-24.921h8.694v2.1598c1.385-1.5506 3.822-2.7136 6.701-2.7136 5.538 0 8.806 3.5997 8.806 9.1377v16.3371h-8.639v-14.2327c0-2.049-1.053-3.5443-3.268-3.5443-1.717 0-3.157.9969-3.6 2.7136v15.0634zm29.991-8.5839v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.584v6.8671h5.206v6.7564h-5.206v8.307c0 1.9383.941 2.769 2.658 2.769.942 0 1.994-.2216 2.769-.5538v7.3654c-.997.443-2.88.775-4.818.775-5.87 0-9.193-2.769-9.193-9.0819zm26.161-16.3371v24.921h-8.694v-24.921zm.61-6.7564c0 2.8244-2.271 4.652-4.929 4.652s-4.929-1.8276-4.929-4.652c0-2.8797 2.271-4.7073 4.929-4.7073s4.929 1.8276 4.929 4.7073zm5.382 23.0935v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.584v6.8671h5.206v6.7564h-5.206v8.307c0 1.9383.941 2.769 2.658 2.769.941 0 1.994-.2216 2.769-.5538v7.3654c-.997.443-2.88.775-4.818.775-5.87 0-9.193-2.769-9.193-9.0819zm29.22 17.3889h-8.584l3.655-9.414-9.303-24.312h9.026l4.763 14.1773 4.652-14.1773h8.639z\" fill=\"#d30001\"/></svg>\n      </header>\n      <article>\n        <p><strong>The change you wanted was rejected.</strong> Maybe you tried to change something you didn’t have access to. If you’re the application owner check the logs for more information.</p>\n      </article>\n    </main>\n\n  </body>\n\n</html>\n"
  },
  {
    "path": "public/500.html",
    "content": "<!doctype html>\n\n<html lang=\"en\">\n\n  <head>\n\n    <title>We’re sorry, but something went wrong (500 Internal Server Error)</title>\n\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"initial-scale=1, width=device-width\">\n    <meta name=\"robots\" content=\"noindex, nofollow\">\n\n    <style>\n\n      *, *::before, *::after {\n        box-sizing: border-box;\n      }\n\n      * {\n        margin: 0;\n      }\n\n      html {\n        font-size: 16px;\n      }\n\n      body {\n        background: #FFF;\n        color: #261B23;\n        display: grid;\n        font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Aptos, Roboto, \"Segoe UI\", \"Helvetica Neue\", Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n        font-size: clamp(1rem, 2.5vw, 2rem);\n        -webkit-font-smoothing: antialiased;\n        font-style: normal;\n        font-weight: 400;\n        letter-spacing: -0.0025em;\n        line-height: 1.4;\n        min-height: 100vh;\n        place-items: center;\n        text-rendering: optimizeLegibility;\n        -webkit-text-size-adjust: 100%;\n      }\n\n      a {\n        color: inherit;\n        font-weight: 700;\n        text-decoration: underline;\n        text-underline-offset: 0.0925em;\n      }\n\n      b, strong {\n        font-weight: 700;\n      }\n\n      i, em {\n        font-style: italic;\n      }\n\n      main {\n        display: grid;\n        gap: 1em;\n        padding: 2em;\n        place-items: center;\n        text-align: center;\n      }\n\n      main header {\n        width: min(100%, 12em);\n      }\n\n      main header svg {\n        height: auto;\n        max-width: 100%;\n        width: 100%;\n      }\n\n      main article {\n        width: min(100%, 30em);\n      }\n\n      main article p {\n        font-size: 75%;\n      }\n\n      main article br {\n\n        display: none;\n\n        @media(min-width: 48em) {\n          display: inline;\n        }\n\n      }\n\n    </style>\n\n  </head>\n\n  <body>\n\n    <!-- This file lives in public/500.html -->\n\n    <main>\n      <header>\n        <svg height=\"172\" viewBox=\"0 0 480 172\" width=\"480\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"m101.23 93.8427c-8.1103 0-15.4098 3.7849-19.7354 8.3813h-36.2269v-99.21891h103.8143v37.03791h-68.3984v24.8722c5.1366-2.7035 15.1396-5.9477 24.6014-5.9477 35.146 0 56.233 22.7094 56.233 55.4215 0 34.605-23.791 57.315-60.558 57.315-37.8492 0-61.64-22.169-63.8028-55.963h42.9857c1.0814 10.814 9.1919 19.195 21.6281 19.195 11.355 0 19.465-8.381 19.465-20.547 0-11.625-7.299-20.5463-20.006-20.5463zm138.833 77.8613c-40.822 0-64.884-35.146-64.884-85.7015 0-50.5554 24.062-85.700907 64.884-85.700907 40.823 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.061 85.7015-64.884 85.7015zm0-133.2831c-17.572 0-22.709 21.8984-22.709 47.5816 0 25.6835 5.137 47.5815 22.709 47.5815 17.303 0 22.71-21.898 22.71-47.5815 0-25.6832-5.407-47.5816-22.71-47.5816zm140.456 133.2831c-40.823 0-64.884-35.146-64.884-85.7015 0-50.5554 24.061-85.700907 64.884-85.700907 40.822 0 64.884 35.145507 64.884 85.700907 0 50.5555-24.062 85.7015-64.884 85.7015zm0-133.2831c-17.573 0-22.71 21.8984-22.71 47.5816 0 25.6835 5.137 47.5815 22.71 47.5815 17.302 0 22.709-21.898 22.709-47.5815 0-25.6832-5.407-47.5816-22.709-47.5816z\" fill=\"#f0eff0\"/><path d=\"m23.1377 68.9967v34.0033h-8.9162v-34.0033zm4.3157 34.0033v-24.921h8.6947v2.1598c1.3845-1.5506 3.8212-2.7136 6.701-2.7136 5.538 0 8.8054 3.5997 8.8054 9.1377v16.3371h-8.6393v-14.2327c0-2.049-1.0522-3.5443-3.2674-3.5443-1.7168 0-3.1567.9969-3.5997 2.7136v15.0634zm29.9913-8.5839v-9.5807h-3.655v-6.7564h3.655v-6.8671h8.5839v6.8671h5.2058v6.7564h-5.2058v8.307c0 1.9383.9415 2.769 2.6583 2.769.9414 0 1.9937-.2216 2.769-.5538v7.3654c-.9969.443-2.8798.775-4.8181.775-5.8703 0-9.1931-2.769-9.1931-9.0819zm32.3666-.1108h8.0301c-.8861 5.7597-5.2057 9.2487-11.6852 9.2487-7.6424 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.3165-13.0143 12.5159-13.0143 7.6424 0 11.9621 5.095 11.9621 12.5159v2.1598h-16.1156c.2769 2.9905 1.8275 4.5965 4.3196 4.5965 1.7722 0 3.1567-.7753 3.6551-2.4921zm-3.8212-10.0237c-2.0491 0-3.4336 1.2737-3.9874 3.5997h7.5317c-.1107-2.0491-1.3845-3.5997-3.5443-3.5997zm31.4299-6.3134v8.3624c-1.052-.5538-2.215-.7753-3.599-.7753-2.382 0-3.988 1.0522-4.431 2.8244v14.6203h-8.694v-24.921h8.694v2.2152c1.219-1.6614 3.157-2.769 5.649-2.769 1.108 0 1.994.2215 2.381.443zm2.949 25.0318v-24.921h8.694v2.1598c1.385-1.5506 3.821-2.7136 6.701-2.7136 5.538 0 8.806 3.5997 8.806 9.1377v16.3371h-8.64v-14.2327c0-2.049-1.052-3.5443-3.267-3.5443-1.717 0-3.157.9969-3.6 2.7136v15.0634zm50.371 0h-8.363v-1.274c-.83.831-3.323 1.717-5.981 1.717-4.929 0-9.082-2.769-9.082-8.0301 0-4.818 4.153-7.9193 9.581-7.9193 2.049 0 4.485.6646 5.482 1.3845v-1.606c0-1.606-.941-2.9905-3.046-2.9905-1.606 0-2.547.7199-2.935 1.8275h-8.196c.72-4.8181 4.984-8.6393 11.408-8.6393 7.089 0 11.132 3.7659 11.132 10.2453zm-8.363-6.9779v-1.4399c-.554-1.0522-2.049-1.7167-3.655-1.7167-1.717 0-3.433.7199-3.433 2.3813 0 1.7168 1.716 2.4367 3.433 2.4367 1.606 0 3.101-.6645 3.655-1.6614zm20.742-29.0191v35.997h-8.694v-35.997zm13.036 25.9178h9.248c.72 2.326 2.714 3.489 5.483 3.489 2.713 0 4.596-1.163 4.596-3.2674 0-1.6061-1.052-2.326-3.212-2.8244l-6.534-1.3845c-4.985-1.1076-8.751-3.7105-8.751-9.47 0-6.6456 5.538-11.0206 13.07-11.0206 8.307 0 13.014 4.5411 13.956 10.4114h-8.695c-.72-1.8829-2.27-3.3228-5.205-3.3228-2.548 0-4.265 1.1076-4.265 2.9905 0 1.4953 1.052 2.326 2.825 2.7137l6.645 1.5506c5.815 1.3845 9.027 4.5412 9.027 9.8023 0 6.9778-5.87 10.9654-13.291 10.9654-8.141 0-13.679-3.9322-14.897-10.6332zm46.509 1.3845h8.031c-.887 5.7597-5.206 9.2487-11.686 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.317-13.0143 12.516-13.0143 7.643 0 11.962 5.095 11.962 12.5159v2.1598h-16.115c.277 2.9905 1.827 4.5965 4.319 4.5965 1.773 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.433 1.2737-3.987 3.5997h7.532c-.111-2.0491-1.385-3.5997-3.545-3.5997zm31.431-6.3134v8.3624c-1.053-.5538-2.216-.7753-3.6-.7753-2.381 0-3.988 1.0522-4.431 2.8244v14.6203h-8.694v-24.921h8.694v2.2152c1.219-1.6614 3.157-2.769 5.649-2.769 1.108 0 1.994.2215 2.382.443zm18.288 25.0318h-7.809l-9.47-24.921h8.861l4.763 14.288 4.652-14.288h8.528zm25.614-8.6947h8.03c-.886 5.7597-5.206 9.2487-11.685 9.2487-7.642 0-12.682-5.2613-12.682-13.0145 0-7.6978 5.316-13.0143 12.516-13.0143 7.642 0 11.962 5.095 11.962 12.5159v2.1598h-16.116c.277 2.9905 1.828 4.5965 4.32 4.5965 1.772 0 3.157-.7753 3.655-2.4921zm-3.821-10.0237c-2.049 0-3.434 1.2737-3.988 3.5997h7.532c-.111-2.0491-1.384-3.5997-3.544-3.5997zm31.43-6.3134v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.157-2.769 5.649-2.769 1.107 0 1.993.2215 2.381.443zm13.703-8.9715h24.312v7.6424h-15.562v5.3165h14.232v7.4763h-14.232v5.8703h15.562v7.6978h-24.312zm44.667 8.9715v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm19.673 0v8.3624c-1.053-.5538-2.216-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.156-2.769 5.648-2.769 1.108 0 1.994.2215 2.382.443zm26.769 12.5713c0 7.6978-5.15 13.0145-12.737 13.0145-7.532 0-12.738-5.3167-12.738-13.0145s5.206-13.0143 12.738-13.0143c7.587 0 12.737 5.3165 12.737 13.0143zm-8.529 0c0-3.4336-1.495-5.8703-4.208-5.8703-2.659 0-4.154 2.4367-4.154 5.8703s1.495 5.8149 4.154 5.8149c2.713 0 4.208-2.3813 4.208-5.8149zm28.082-12.5713v8.3624c-1.052-.5538-2.215-.7753-3.6-.7753-2.381 0-3.987 1.0522-4.43 2.8244v14.6203h-8.695v-24.921h8.695v2.2152c1.218-1.6614 3.157-2.769 5.649-2.769 1.107 0 1.993.2215 2.381.443z\" fill=\"#d30001\"/></svg>\n      </header>\n      <article>\n        <p><strong>We’re sorry, but something went wrong.</strong><br> If you’re the application owner check the logs for more information.</p>\n      </article>\n    </main>\n\n  </body>\n\n</html>\n"
  },
  {
    "path": "public/robots.txt",
    "content": "# See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file\n"
  },
  {
    "path": "scripts/create_events.rb",
    "content": "# start this script with the rails runner command\n# $ rails runner scripts/create_events.rb\n#\n# This script fetches YouTube playlists for each series and creates event.yml files.\n# You can optionally pass a series slug to only process that series:\n#   rails runner scripts/create_events.rb railsconf\n\ndef create_events_for_series(series_file_path)\n  series_slug = File.basename(File.dirname(series_file_path))\n  series_data = YAML.load_file(series_file_path)\n\n  return if series_data[\"youtube_channel_id\"].blank?\n\n  puts \"Processing: #{series_slug}\"\n\n  playlists = YouTube::Playlists.new.all(\n    channel_id: series_data[\"youtube_channel_id\"],\n    title_matcher: series_data[\"playlist_matcher\"]\n  )\n  playlists.sort_by! { |playlist| playlist.year.to_i }\n  playlists.select! { |playlist| playlist.videos_count.positive? }\n\n  puts \"  Found #{playlists.count} playlists\"\n\n  playlists.each do |playlist|\n    event_dir = \"#{Rails.root}/data/#{series_slug}/#{playlist.slug}\"\n    event_file = \"#{event_dir}/event.yml\"\n\n    # Skip if event.yml already exists\n    if File.exist?(event_file)\n      puts \"  Skipping (exists): #{playlist.slug}\"\n      next\n    end\n\n    FileUtils.mkdir_p(event_dir)\n    File.write(event_file, YAML.dump(playlist.to_h.except(:videos_count, :metadata_parser, :slug).stringify_keys))\n    puts \"  Created: #{playlist.slug}/event.yml\"\n  end\nend\n\n# Main\nif ARGV[0]\n  # Process a specific series\n  series_file = \"#{Rails.root}/data/#{ARGV[0]}/series.yml\"\n  if File.exist?(series_file)\n    create_events_for_series(series_file)\n  else\n    puts \"Series not found: #{ARGV[0]}\"\n    puts \"Expected file: #{series_file}\"\n    exit 1\n  end\nelse\n  # Process all series\n  series_files = Dir.glob(\"#{Rails.root}/data/*/series.yml\")\n  puts \"Found #{series_files.count} series to process\"\n  puts\n\n  series_files.each do |series_file_path|\n    create_events_for_series(series_file_path)\n  end\nend\n\nputs\nputs \"Done!\"\n"
  },
  {
    "path": "scripts/create_videos_yml.rb",
    "content": "# start this script with the rails runner command\n# $ rails runner scripts/create_videos_yml.rb [playlist_id]\n#\n\nplaylist_id = ARGV[0]\n\nif playlist_id.blank?\n  puts \"Please provide a playlist id\"\n  exit 1\nend\n\nputs YouTube::PlaylistItems.new\n  .all(playlist_id: playlist_id)\n  .map { |metadata| YouTube::VideoMetadata.new(metadata: metadata, event_name: \"TODO\").cleaned }\n  .map { |item| item.to_h.stringify_keys }\n  .to_yaml\n  .gsub(\"- title:\", \"\\n- title:\") # Visually separate the talks with a newline\n"
  },
  {
    "path": "scripts/dump_speakers.rb",
    "content": "# This script will query the API and dump the speakers data to a YAML file\n# speaker data can we updated in production, this is a way to sync our seed data to reflect as closely as possible the prod environment\n\nrequire \"net/http\"\nrequire \"json\"\nrequire \"yaml\"\n\nAPI_ENDPOINT = \"https://www.rubyevents.org/speakers.json\"\n# API_ENDPOINT = \"http://localhost:3000/speakers.json\"\nOUTPUT_FILE = \"data/speakers.yml\"\n\ndef fetch_speakers\n  speakers = []\n  current_page = 1\n\n  loop do\n    uri = URI(\"#{API_ENDPOINT}?page=#{current_page}&with_talks=false\")\n    response = Net::HTTP.get(uri)\n    parsed_response = JSON.parse(response)\n\n    speakers.concat(parsed_response[\"speakers\"].map { |speaker| speaker.except(\"id\", \"updated_at\", \"created_at\", \"talks_count\") })\n    current_page += 1\n\n    next_page = parsed_response.dig(\"pagination\", \"next_page\")\n    break if next_page.nil?\n  end\n\n  speakers\nend\n\ndef save_to_yaml(data, file_name)\n  File.write(file_name, data.to_yaml)\nend\n\nspeakers_data = fetch_speakers\nsave_to_yaml(speakers_data, OUTPUT_FILE)\n\nputs \"Speakers data saved to #{OUTPUT_FILE}\"\n\nputs \"formating with Prettier...\"\n\nsystem(\"yarn prettier --write #{OUTPUT_FILE}\")\n\nputs \"Done!\"\n"
  },
  {
    "path": "scripts/dump_talks.rb",
    "content": "# This script will query the API and dump the speakers data to a YAML file\n# speaker data can we updated in production, this is a way to sync our seed data to reflect as closely as possible the prod environment\n\nrequire \"net/http\"\nrequire \"json\"\nrequire \"yaml\"\n\nAPI_ENDPOINT = \"https://www.rubyevents.org/talks.json\"\n# API_ENDPOINT = \"http://localhost:3000/talks.json\"\nOUTPUT_FILE = \"data/talks.yml\"\n\ndef fetch_talks\n  talks = []\n  current_page = 1\n\n  loop do\n    uri = URI(\"#{API_ENDPOINT}?page=#{current_page}&limit=1000\")\n    puts uri.inspect\n\n    response = Net::HTTP.get(uri)\n    parsed_response = JSON.parse(response)\n\n    talks.concat(parsed_response[\"talks\"].map { |talk| talk.slice(\"static_id\", \"slug\", \"title\", \"video_id\", \"video_provider\") })\n    current_page += 1\n    break if parsed_response.dig(\"pagination\", \"next_page\").nil?\n  end\n\n  talks\nend\n\ndef save_to_yaml(data)\n  File.write(OUTPUT_FILE, data.to_yaml)\nend\n\nputs talks_data = fetch_talks\nsave_to_yaml(talks_data)\n\nputs \"Talks data saved to #{OUTPUT_FILE}\"\n\nputs \"formating with Prettier...\"\n\nsystem(\"yarn prettier --write #{OUTPUT_FILE}\")\n\nputs \"Done!\"\n"
  },
  {
    "path": "scripts/extract_videos.rb",
    "content": "# start this script with the rails runner command\n# $ rails runner scripts/extract_videos.rb\n#\n# This script extracts videos from YouTube playlists for each event.\n# You can optionally pass a series slug to only process that series:\n#   rails runner scripts/extract_videos.rb railsconf\n# Or pass both series and event slug:\n#   rails runner scripts/extract_videos.rb railsconf railsconf-2024\n\ndef extract_videos_for_event(event_file_path)\n  event_slug = File.basename(File.dirname(event_file_path))\n  File.basename(File.dirname(event_file_path, 2))\n  event_data = YAML.load_file(event_file_path)\n  event = OpenStruct.new(event_data.merge(\"slug\" => event_slug))\n\n  # Skip if no playlist ID\n  return if event.id.blank?\n\n  puts \"  Extracting videos for: #{event.title || event_slug}\"\n\n  playlist_videos = YouTube::PlaylistItems.new.all(playlist_id: event.id)\n  playlist_videos.sort_by! { |video| video.published_at }\n\n  # by default we use YouTube::VideoMetadata but in event.yml you can specify a different parser\n  parser = event.metadata_parser&.constantize || YouTube::NullParser\n  playlist_videos.map! { |metadata| parser.new(metadata: metadata, event_name: event.title).cleaned }\n\n  videos_file = File.join(File.dirname(event_file_path), \"videos.yml\")\n  puts \"  #{playlist_videos.length} videos extracted\"\n\n  yaml = playlist_videos.map { |item| item.to_h.stringify_keys }.to_yaml\n\n  yaml = yaml\n    .gsub(\"- title:\", \"\\n- title:\") # Visually separate the talks with a newline\n    .gsub(\"speakers:\\n  -\", \"speakers:\\n    -\") # Indent the first speaker name for readability\n\n  File.write(videos_file, yaml)\n  puts \"  Written to: #{videos_file}\"\nend\n\ndef extract_videos_for_series(series_slug)\n  puts \"Processing series: #{series_slug}\"\n\n  event_files = Dir.glob(\"#{Rails.root}/data/#{series_slug}/*/event.yml\")\n  puts \"Found #{event_files.count} events\"\n\n  event_files.each do |event_file_path|\n    extract_videos_for_event(event_file_path)\n  end\nend\n\n# Main\nif ARGV[0] && ARGV[1]\n  # Process a specific event\n  event_file = \"#{Rails.root}/data/#{ARGV[0]}/#{ARGV[1]}/event.yml\"\n  if File.exist?(event_file)\n    extract_videos_for_event(event_file)\n  else\n    puts \"Event not found: #{ARGV[0]}/#{ARGV[1]}\"\n    puts \"Expected file: #{event_file}\"\n    exit 1\n  end\nelsif ARGV[0]\n  # Process a specific series\n  series_dir = \"#{Rails.root}/data/#{ARGV[0]}\"\n  if Dir.exist?(series_dir)\n    extract_videos_for_series(ARGV[0])\n  else\n    puts \"Series not found: #{ARGV[0]}\"\n    exit 1\n  end\nelse\n  # Process all series\n  series_dirs = Dir.glob(\"#{Rails.root}/data/*/series.yml\").map { |f| File.dirname(f) }\n  puts \"Found #{series_dirs.count} series to process\"\n  puts\n\n  series_dirs.each do |series_dir|\n    series_slug = File.basename(series_dir)\n    extract_videos_for_series(series_slug)\n    puts\n  end\nend\n\nputs \"Done!\"\n"
  },
  {
    "path": "scripts/import_event.rb",
    "content": "series_slug = ARGV[0]\n\nif series_slug.blank?\n  series_slugs = Static::EventSeries.all.map(&:slug).sort\n\n  series_slug = IO.popen([\"fzy\"], \"r+\") do |fzy|\n    fzy.puts(series_slugs.join(\"\\n\"))\n    fzy.close_write\n    fzy.gets&.strip\n  end\n\n  if series_slug.blank?\n    puts \"No series selected\"\n    exit 1\n  end\nend\n\nstatic_series = Static::EventSeries.find_by_slug(series_slug)\n\nraise \"Event series '#{series_slug}' not found in static data\" if static_series.nil?\n\nstatic_series.import!\n"
  },
  {
    "path": "scripts/prepare_series.rb",
    "content": "# start this script with the rails runner command\n# $ rails runner scripts/prepare_series.rb\n#\n# This script updates series.yml files with youtube_channel_id if missing.\n# You can optionally pass a series slug to only process that series:\n#   rails runner scripts/prepare_series.rb railsconf\n\ndef add_youtube_channel_id(series_data)\n  return series_data if series_data[\"youtube_channel_id\"].present?\n  return series_data if series_data[\"youtube_channel_name\"].blank?\n\n  youtube_channel_id = YouTube::Channels.new.id_by_name(channel_name: series_data[\"youtube_channel_name\"])\n\n  puts \"  youtube_channel_id: #{youtube_channel_id}\"\n  series_data[\"youtube_channel_id\"] = youtube_channel_id\n  series_data\nend\n\ndef process_series(series_file_path)\n  series_slug = File.basename(File.dirname(series_file_path))\n  puts \"Processing: #{series_slug}\"\n\n  series_data = YAML.load_file(series_file_path)\n  series_data = add_youtube_channel_id(series_data)\n\n  File.write(series_file_path, YAML.dump(series_data))\n  puts \"  Updated: #{series_file_path}\"\nend\n\n# Main\nif ARGV[0]\n  # Process a specific series\n  series_file = \"#{Rails.root}/data/#{ARGV[0]}/series.yml\"\n  if File.exist?(series_file)\n    process_series(series_file)\n  else\n    puts \"Series not found: #{ARGV[0]}\"\n    puts \"Expected file: #{series_file}\"\n    exit 1\n  end\nelse\n  # Process all series\n  series_files = Dir.glob(\"#{Rails.root}/data/*/series.yml\")\n  puts \"Found #{series_files.count} series to process\"\n  puts\n\n  series_files.each do |series_file_path|\n    process_series(series_file_path)\n  end\nend\n\nputs\nputs \"Done!\"\n"
  },
  {
    "path": "scripts/sort_speakers.rb",
    "content": "# Re-sorts the ./data/speakers.yml file by name\n# This avoids the large reformatting diff if we were to just load and resave as YAML\n\nPATH_TO_DATA = \"./data/speakers.yml\"\n\ndef speaker_sort_key(block)\n  block\n    .split(\"\\n\")\n    .first\n    .sub(/^- name:\\s*[\"']/, \"\")\n    .sub(/[\"']\\s*$/, \"\")\n    .strip\n    .downcase\nend\n\nraw = File.read(PATH_TO_DATA)\nparts = raw.split(/\\n(?=- name: )/)\n\npreamble = parts.first\nchunks = parts[1..].sort_by { |block| speaker_sort_key(block) }\n\nFile.write(PATH_TO_DATA, [preamble, *chunks].join(\"\\n\"))\n\nputs \"Sorted #{chunks.size} speakers and rewrote to #{PATH_TO_DATA}\"\n"
  },
  {
    "path": "storage/.keep",
    "content": ""
  },
  {
    "path": "tailwind.config.js",
    "content": "const defaultTheme = require('daisyui/src/theming/themes.js')['[data-theme=light]']\nconst defaultTailwindTheme = require('tailwindcss/defaultTheme')\nconst plugin = require('tailwindcss/plugin')\n\nmodule.exports = {\n  content: [\n    './app/views/**/*.html.erb',\n    './app/components/**/*',\n    './app/helpers/**/*.rb',\n    './app/models/**/*.rb',\n    './app/assets/stylesheets/**/*.css',\n    './app/javascript/**/*.js',\n    './config/initializers/*.rb',\n    './data/**/**'\n  ],\n  theme: {\n    container: {\n      center: true,\n      padding: {\n        DEFAULT: '1rem',\n        sm: '1rem'\n        // lg: \"4rem\",\n        // xl: \"5rem\",\n        // \"2xl\": \"6rem\",\n      }\n    },\n    fontFamily: {\n      sans: ['Inter', ...defaultTailwindTheme.fontFamily.sans],\n      serif: ['Nunito', ...defaultTailwindTheme.fontFamily.serif]\n    },\n    extend: {\n      fontSize: {\n        xs: ['0.75rem', { lineHeight: '1rem' }],\n        sm: ['0.875rem', { lineHeight: 'rfs(1.25rem)' }],\n        base: ['rfs(1rem)', { lineHeight: 'rfs(1.5rem)' }],\n        lg: ['rfs(1.125rem)', { lineHeight: 'rfs(1.75rem)' }],\n        xl: ['rfs(1.25rem)', { lineHeight: 'rfs(1.75rem)' }],\n        '2xl': ['rfs(1.5rem)', { lineHeight: 'rfs(2rem)' }],\n        '3xl': ['rfs(1.875rem)', { lineHeight: 'rfs(2.25rem)' }],\n        '4xl': ['rfs(2.25rem)', { lineHeight: 'rfs(2.5rem)' }],\n        '5xl': ['rfs(3rem)', { lineHeight: '1' }],\n        '6xl': ['rfs(3.75rem)', { lineHeight: '1' }],\n        '7xl': ['rfs(4.5rem)', { lineHeight: '1' }],\n        '8xl': ['rfs(6rem)', { lineHeight: '1' }],\n        '9xl': ['rfs(8rem)', { lineHeight: '1' }]\n      },\n      keyframes: {\n        'fade-in': {\n          '0%': { opacity: '0' },\n          '100%': { opacity: '1' }\n        },\n        'fade-out': {\n          '0%': { opacity: '1' },\n          '100%': { opacity: '0' }\n        }\n      }\n    }\n  },\n  safelist: [\n    { pattern: /grid-cols-(1|2|3|4|5|6|7|8|9|10)/ },\n    { pattern: /col-span-(1|2|3|4|5|6|7|8|9|10)/ }\n  ],\n  daisyui: {\n    logs: false,\n    themes: [\n      {\n        rubyvideoLight: {\n          ...defaultTheme,\n          '--btn-text-case': 'none',\n          primary: '#DC143C',\n          'primary-content': '#ffffff',\n          secondary: '#7A4EC2',\n          'secondary-content': '#ffffff',\n          accent: '#1DA1F2',\n          'accent-content': '#ffffff',\n          neutral: '#261B23',\n          'neutral-content': '#ffffff',\n          'base-100': '#F8F9FA',\n          '--animation-btn': 'none'\n          // 'base-200': '#FFFFFF',\n          // 'base-content': '#2F2F2F'\n          // 'base-100': '#ffffff',\n          // info: '#3abff8',\n          // success: '#36d399',\n          // warning: '#fbbd23',\n          // error: '#f87272'\n        }\n      }\n    ]\n  },\n  plugins: [\n    require('@tailwindcss/typography'),\n    require('daisyui'),\n    plugin(function ({ addVariant }) {\n      addVariant('hotwire-native', 'html[data-hotwire-native-app] &')\n      addVariant('non-hotwire-native', 'html:not([data-hotwire-native-app]) &')\n    })\n  ]\n}\n"
  },
  {
    "path": "test/application_system_test_case.rb",
    "content": "require \"test_helper\"\n\nCapybara.register_driver :headless_chrome do |app|\n  options = ::Selenium::WebDriver::Chrome::Options.new\n  options.add_argument(\"--headless\") unless ActiveModel::Type::Boolean.new.cast(ENV[\"HEADFUL\"])\n  options.add_argument(\"--window-size=1920,1080\")\n\n  client = Selenium::WebDriver::Remote::Http::Default.new\n  client.read_timeout = 240\n\n  Capybara::Selenium::Driver.new(app, browser: :chrome, capabilities: [options], http_client: client)\nend\n\nCapybara.javascript_driver = :headless_chrome\n\nclass ApplicationSystemTestCase < ActionDispatch::SystemTestCase\n  driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400]\n\n  def sign_in_as(user)\n    visit new_session_url\n    fill_in :email, with: user.email\n    fill_in :password, with: \"Secret1*3*5*\"\n    click_on \"Sign in\"\n\n    assert_current_path root_url\n    user\n  end\n\n  def wait_for_turbo(timeout = 2)\n    if has_css?(\".turbo-progress-bar\", visible: true, wait: 0.25.seconds)\n      has_no_css?(\".turbo-progress-bar\", wait: timeout)\n    end\n  end\n\n  def wait_for_turbo_stream_connected(streamable: nil)\n    if streamable\n      signed_stream_name = Turbo::StreamsChannel.signed_stream_name(streamable)\n      assert_selector(\"turbo-cable-stream-source[connected][channel=\\\"Turbo::StreamsChannel\\\"][signed-stream-name=\\\"#{signed_stream_name}\\\"]\", visible: :all)\n    else\n      assert_selector(\"turbo-cable-stream-source[connected][channel=\\\"Turbo::StreamsChannel\\\"]\", visible: :all)\n    end\n  end\nend\n\nCapybara.default_max_wait_time = 5 # Set the wait time in seconds\n"
  },
  {
    "path": "test/channels/application_cable/connection_test.rb",
    "content": "require \"test_helper\"\n\nmodule ApplicationCable\n  class ConnectionTest < ActionCable::Connection::TestCase\n    # test \"connects with cookies\" do\n    #   cookies.signed[:user_id] = 42\n    #\n    #   connect\n    #\n    #   assert_equal connection.user_id, \"42\"\n    # end\n  end\nend\n"
  },
  {
    "path": "test/clients/youtube/channels_test.rb",
    "content": "require \"test_helper\"\nclass YouTube::ChannelsTest < ActiveSupport::TestCase\n  setup do\n  end\n\n  test \"should retreive the channel id from the user name\" do\n    VCR.use_cassette(\"youtube/channels\", match_requests_on: [:method]) do\n      channel_id = YouTube::Channels.new.id_by_name(channel_name: \"confreaks\")\n      assert_equal \"UCWnPjmqvljcafA0z2U1fwKQ\", channel_id\n    end\n  end\n\n  test \"should retreive the channel id from the user name with dash\" do\n    VCR.use_cassette(\"youtube/channels-scrapping\", match_requests_on: [:method]) do\n      channel_id = YouTube::Channels.new.id_by_name(channel_name: \"paris-rb\")\n      assert_equal \"UCFKE6QHGPAkISMj1SQdqnnw\", channel_id\n    end\n  end\nend\n"
  },
  {
    "path": "test/clients/youtube/playlist_items_test.rb",
    "content": "require \"test_helper\"\n\nclass YouTube::PlaylistItemsTest < ActiveSupport::TestCase\n  test \"should retreive the playlist of a channel\" do\n    VCR.use_cassette(\"youtube/playlist_items/all\", match_requests_on: [:method]) do\n      items = YouTube::PlaylistItems.new.all(playlist_id: \"PLE7tQUdRKcyZYz0O3d9ZDdo0-BkOWhrSk\")\n      assert items.is_a?(Array)\n      assert items.length > 50\n    end\n  end\nend\n"
  },
  {
    "path": "test/clients/youtube/playlists_test.rb",
    "content": "require \"test_helper\"\n\nclass YouTube::PlaylistsTest < ActiveSupport::TestCase\n  test \"should retreive the playlist of a channel\" do\n    VCR.use_cassette(\"youtube/playlists/all\", match_requests_on: [:method]) do\n      playlists = YouTube::Playlists.new.all(channel_id: \"UCWnPjmqvljcafA0z2U1fwKQ\")\n\n      assert playlists.is_a?(Array)\n      assert playlists.length > 50\n\n      ruby_and_rails_playlists = playlists.filter do |playlist|\n        playlist.title.match(/(rails|ruby)/i)\n      end\n\n      assert ruby_and_rails_playlists.length < playlists.length\n    end\n  end\nend\n"
  },
  {
    "path": "test/clients/youtube/transcript_test.rb",
    "content": "require \"test_helper\"\n\nclass YouTube::TranscriptTest < ActiveSupport::TestCase\n  def setup\n    @client = YouTube::Transcript.new\n  end\n\n  test \"fetch the trasncript from a video in vtt format\" do\n    video_id = \"9LfmrkyP81M\"\n\n    VCR.use_cassette(\"youtube_video_transcript\", match_requests_on: [:method]) do\n      transcript = @client.get(video_id)\n      assert_not_nil transcript\n\n      transcript = Transcript.create_from_youtube_transcript(transcript)\n      assert_not_empty transcript.cues\n      assert transcript.cues.first.is_a?(Cue)\n    end\n  end\nend\n"
  },
  {
    "path": "test/clients/youtube/video_test.rb",
    "content": "require \"test_helper\"\n\nmodule YouTube\n  class VideoTest < ActiveSupport::TestCase\n    def setup\n      @client = YouTube::Video.new\n    end\n\n    test \"should return statistics for a valid video\" do\n      video_id = \"9LfmrkyP81M\"\n\n      VCR.use_cassette(\"youtube_statistics\", match_requests_on: [:method]) do\n        stats = @client.get_statistics(video_id)\n        assert_not_nil stats\n        assert stats[video_id].has_key?(:view_count)\n        assert stats[video_id].has_key?(:like_count)\n      end\n    end\n\n    test \"should return nil for an invalid video\" do\n      video_id = \"invalid_video_id\"\n\n      VCR.use_cassette(\"youtube_statistics_invalid\", match_requests_on: [:method]) do\n        stats = @client.get_statistics(video_id)\n        assert_nil stats\n      end\n    end\n\n    test \"should return duration for a valid video\" do\n      video_id = \"9LfmrkyP81M\"\n\n      VCR.use_cassette(\"youtube_duration\", match_requests_on: [:method]) do\n        stats = @client.duration(video_id)\n        assert_not_nil stats\n        assert stats.is_a?(Integer)\n        assert stats > 0\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/components/application_component_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass ApplicationComponentTest < ViewComponent::TestCase\n  class ButtonComponent < ApplicationComponent\n    option :text, default: proc { \"Click me\" }\n\n    def call\n      content_tag(:span, text, **attributes)\n    end\n  end\n\n  def test_preserves_attributes\n    render_inline(ButtonComponent.new(text: \"Click me\", data: {controller: \"button\"}))\n    assert_selector(\"span[data-controller=\\\"button\\\"]\")\n    refute_selector(\"span[title=\\\"Click me\\\"]\")\n    assert_content(\"Click me\")\n  end\nend\n"
  },
  {
    "path": "test/components/events/upcoming_event_banner_component/helper_methods_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Events::UpcomingEventBannerComponent::HelperMethodsTest < ViewComponent::TestCase\n  class TestableComponent < Events::UpcomingEventBannerComponent\n    attr_writer :test_upcoming_event\n\n    def upcoming_event\n      @test_upcoming_event\n    end\n  end\n\n  setup do\n    @event = events(:brightonruby_2024)\n  end\n\n  test \"background_style returns featured_background for solid color\" do\n    static_metadata = Struct.new(:featured_background, :featured_color).new(\"#cc342d\", \"white\")\n    mock_event = Struct.new(:static_metadata).new(static_metadata)\n\n    component = TestableComponent.new(event: @event)\n    component.test_upcoming_event = mock_event\n\n    assert_equal \"#cc342d\", component.background_style\n  end\n\n  test \"background_style returns url format for data URLs\" do\n    static_metadata = Struct.new(:featured_background, :featured_color).new(\"data:image/png;base64,abc123\", \"white\")\n    mock_event = Struct.new(:static_metadata).new(static_metadata)\n\n    component = TestableComponent.new(event: @event)\n    component.test_upcoming_event = mock_event\n\n    assert_match(/url\\('data:image\\/png;base64,abc123'\\)/, component.background_style)\n  end\n\n  test \"background_color returns color for solid color\" do\n    static_metadata = Struct.new(:featured_background, :featured_color).new(\"#cc342d\", \"white\")\n    mock_event = Struct.new(:static_metadata).new(static_metadata)\n\n    component = TestableComponent.new(event: @event)\n    component.test_upcoming_event = mock_event\n\n    assert_equal \"#cc342d\", component.background_color\n  end\n\n  test \"background_color returns black for data URLs\" do\n    static_metadata = Struct.new(:featured_background, :featured_color).new(\"data:image/png;base64,abc123\", \"white\")\n    mock_event = Struct.new(:static_metadata).new(static_metadata)\n\n    component = TestableComponent.new(event: @event)\n    component.test_upcoming_event = mock_event\n\n    assert_equal \"#000000\", component.background_color\n  end\n\n  test \"text_color returns featured_color\" do\n    static_metadata = Struct.new(:featured_background, :featured_color).new(\"#cc342d\", \"white\")\n    mock_event = Struct.new(:static_metadata).new(static_metadata)\n\n    component = TestableComponent.new(event: @event)\n    component.test_upcoming_event = mock_event\n\n    assert_equal \"white\", component.text_color\n  end\nend\n"
  },
  {
    "path": "test/components/events/upcoming_event_banner_component_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Events::UpcomingEventBannerComponentTest < ViewComponent::TestCase\n  setup do\n    @past_event = events(:brightonruby_2024)\n    @future_event = events(:future_conference)\n    @series = event_series(:brightonruby)\n  end\n\n  test \"does not render when event has no upcoming event with tickets in series\" do\n    render_inline(Events::UpcomingEventBannerComponent.new(event: @past_event))\n\n    assert_no_selector \"a\"\n  end\n\n  test \"does not render when event is not past\" do\n    render_inline(Events::UpcomingEventBannerComponent.new(event: @future_event))\n\n    assert_no_selector \"a\"\n  end\n\n  test \"component has render? method that checks for upcoming event\" do\n    component = Events::UpcomingEventBannerComponent.new(event: @past_event)\n\n    refute component.render?\n  end\n\n  test \"component accepts event option\" do\n    component = Events::UpcomingEventBannerComponent.new(event: @past_event)\n\n    assert_equal @past_event, component.event\n  end\n\n  test \"component accepts event_series option\" do\n    component = Events::UpcomingEventBannerComponent.new(event_series: @series)\n\n    assert_equal @series, component.event_series\n  end\n\n  test \"upcoming_event returns nil when event has no upcoming event with tickets\" do\n    component = Events::UpcomingEventBannerComponent.new(event: @past_event)\n\n    assert_nil component.upcoming_event\n  end\n\n  test \"upcoming_event returns nil when event_series has no upcoming event with tickets\" do\n    component = Events::UpcomingEventBannerComponent.new(event_series: @series)\n\n    assert_nil component.upcoming_event\n  end\n\n  test \"component with both event and event_series prefers event\" do\n    component = Events::UpcomingEventBannerComponent.new(event: @past_event, event_series: @series)\n\n    assert_equal @past_event, component.event\n  end\nend\n"
  },
  {
    "path": "test/components/tito/button_component_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Tito::ButtonComponentTest < ViewComponent::TestCase\n  setup do\n    @past_event = events(:brightonruby_2024)\n    @future_event = events(:future_conference)\n  end\n\n  test \"does not render when tickets are not available\" do\n    render_inline(Tito::ButtonComponent.new(event: @past_event))\n\n    assert_no_text \"Tickets\"\n  end\n\n  test \"does not render for past events\" do\n    render_inline(Tito::ButtonComponent.new(event: @past_event))\n\n    assert_no_text \"Tickets\"\n  end\n\n  test \"does not render for future events without tickets\" do\n    render_inline(Tito::ButtonComponent.new(event: @future_event))\n\n    assert_no_text \"Tickets\"\n  end\n\n  test \"component has correct classes method\" do\n    component = Tito::ButtonComponent.new(event: @past_event)\n\n    assert_equal \"btn btn-primary btn-sm w-full no-animation\", component.classes\n  end\n\n  test \"component has default label\" do\n    component = Tito::ButtonComponent.new(event: @past_event)\n\n    assert_equal \"Tickets\", component.label\n  end\n\n  test \"component accepts custom label\" do\n    component = Tito::ButtonComponent.new(event: @past_event, label: \"Get Your Tickets\")\n\n    assert_equal \"Get Your Tickets\", component.label\n  end\nend\n"
  },
  {
    "path": "test/components/tito/widget_component_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Tito::WidgetComponentTest < ViewComponent::TestCase\n  setup do\n    @past_event = events(:brightonruby_2024)\n    @future_event = events(:future_conference)\n  end\n\n  test \"does not render when event is past\" do\n    render_inline(Tito::WidgetComponent.new(event: @past_event))\n\n    assert_no_selector \"tito-widget\"\n  end\n\n  test \"does not render for future events without tito tickets\" do\n    render_inline(Tito::WidgetComponent.new(event: @future_event))\n\n    assert_no_selector \"tito-widget\"\n  end\n\n  test \"component has wrapper option defaulting to true\" do\n    component = Tito::WidgetComponent.new(event: @past_event)\n\n    assert component.wrapper\n  end\n\n  test \"component accepts wrapper false option\" do\n    component = Tito::WidgetComponent.new(event: @past_event, wrapper: false)\n\n    refute component.wrapper\n  end\n\n  test \"event_slug delegates to tickets.tito_event_slug\" do\n    component = Tito::WidgetComponent.new(event: @past_event)\n\n    assert_nil component.event_slug\n  end\nend\n"
  },
  {
    "path": "test/components/ui/avatar_component_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Ui::AvatarComponentTest < ViewComponent::TestCase\n  setup do\n    @speaker = users(:one)\n  end\n\n  def test_render_image_when_there_is_a_custom_avatar\n    @speaker.update!(github_handle: \"testtest\")\n    render_inline(Ui::AvatarComponent.new(@speaker))\n\n    assert_selector(\"img\")\n  end\n\n  def test_render_initials_when_there_is_no_custom_avatar\n    @speaker.update!(github_handle: \"\", name: \"Max Mustermann\")\n    render_inline(Ui::AvatarComponent.new(@speaker))\n\n    refute_selector(\"img\")\n    assert_text(\"MM\")\n  end\n\n  def test_renders_by_default_md\n    @speaker.update!(github_handle: \"testtest\")\n    render_inline(Ui::AvatarComponent.new(@speaker))\n\n    assert_selector(\".w-12\")\n  end\n\n  def test_renders_non_default_sizes\n    @speaker.update!(github_handle: \"testtest\")\n    render_inline(Ui::AvatarComponent.new(@speaker, size: :lg))\n\n    assert_selector(\".w-40\")\n  end\nend\n"
  },
  {
    "path": "test/components/ui/badge_component_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Ui::BadgeComponentTest < ViewComponent::TestCase\n  def test_render_a_badge_with_text\n    render_inline(Ui::BadgeComponent.new(\"New\"))\n    assert_text(\"New\")\n  end\n\n  def test_render_default_primary_badge\n    render_inline(Ui::BadgeComponent.new(\"New\"))\n    assert_selector(\".badge.badge-primary\")\n  end\n\n  def test_render_secondary_badge\n    render_inline(Ui::BadgeComponent.new(\"New\", kind: :secondary))\n    assert_selector(\".badge.badge-secondary\")\n  end\n\n  def test_render_with_custom_size\n    render_inline(Ui::BadgeComponent.new(\"New\", size: :lg))\n    assert_selector(\".badge.badge-lg\")\n  end\n\n  def test_render_with_outline\n    render_inline(Ui::BadgeComponent.new(\"New\", outline: true))\n    assert_selector(\".badge.badge-outline\")\n  end\n\n  def test_render_with_custom_attributes\n    render_inline(Ui::BadgeComponent.new(\"New\", data: {controller: \"hello\"}))\n    assert_selector(\"span[data-controller=\\\"hello\\\"]\")\n  end\n\n  def test_render_with_content\n    render_inline(Ui::BadgeComponent.new.with_content(\"New\"))\n    assert_text(\"New\")\n  end\nend\n"
  },
  {
    "path": "test/components/ui/button_component_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Ui::ButtonComponentTest < ViewComponent::TestCase\n  def test_render_a_button_with_text\n    render_inline(Ui::ButtonComponent.new(\"click me\"))\n    assert_text(\"click me\")\n  end\n\n  def test_render_with_custom_attributes\n    render_inline(Ui::ButtonComponent.new(\"click me\", data: {controller: \"hello\"}))\n    assert_selector(\"button[data-controller=\\\"hello\\\"]\")\n  end\n\n  def test_render_default_primary_button\n    render_inline(Ui::ButtonComponent.new(\"click me\"))\n    assert_selector(\".btn.btn-primary\")\n  end\n\n  def test_render_secondary_button\n    render_inline(Ui::ButtonComponent.new(\"click me\", kind: :secondary))\n    assert_selector(\".btn.btn-secondary\")\n  end\n\n  def test_render_with_content\n    render_inline(Ui::ButtonComponent.new.with_content(\"click me\"))\n    assert_text(\"click me\")\n  end\n\n  def test_render_button_to_form\n    render_inline(Ui::ButtonComponent.new(\"click me\", url: \"https://example.com\", method: :post))\n    assert_selector(\"form[action=\\\"https://example.com\\\"][method=post]\")\n  end\n\n  def test_render_link_to\n    render_inline(Ui::ButtonComponent.new(\"click me\", url: \"https://example.com\"))\n    assert_selector(\"a[href=\\\"https://example.com\\\"]\")\n  end\nend\n"
  },
  {
    "path": "test/components/ui/stamp_component_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Ui::StampComponentTest < ViewComponent::TestCase\n  setup do\n    @country_stamp = Stamp.for(country_code: \"BE\").first\n\n    @contributor_stamp = Stamp.contributor_stamp\n  end\n\n  test \"renders country stamp as link\" do\n    render_inline(Ui::StampComponent.new(@country_stamp))\n\n    assert_selector(\"a[href='/countries/belgium']\")\n    assert_selector(\"img[alt='Belgium passport stamp']\")\n  end\n\n  test \"renders contributor stamp as link\" do\n    render_inline(Ui::StampComponent.new(@contributor_stamp))\n\n    assert_selector(\"a[href='/contributors']\")\n    assert_selector(\"img[alt='RubyEvents Contributor passport stamp']\")\n  end\n\n  test \"renders with default size full\" do\n    render_inline(Ui::StampComponent.new(@country_stamp))\n\n    assert_selector(\".w-full.h-full\")\n  end\n\n  test \"renders with custom size lg\" do\n    render_inline(Ui::StampComponent.new(@country_stamp, size: :lg))\n\n    assert_selector(\".w-20.h-20\")\n  end\n\n  test \"renders with all size variants\" do\n    Ui::StampComponent::SIZE_MAPPING.except(:unset).keys.each do |size|\n      render_inline(Ui::StampComponent.new(@country_stamp, size: size))\n\n      expected_class = Ui::StampComponent::SIZE_MAPPING[size]\n      assert_selector(\".#{expected_class.split.join(\".\")}\")\n    end\n  end\n\n  test \"renders as static when interactive false\" do\n    render_inline(Ui::StampComponent.new(@country_stamp, interactive: false))\n\n    refute_selector(\"a\")\n  end\n\n  test \"applies random rotation\" do\n    render_inline(Ui::StampComponent.new(@country_stamp, rotate: true))\n\n    assert_selector(\"img[style*='transform: rotate(']\")\n  end\n\n  test \"uses lazy loading\" do\n    render_inline(Ui::StampComponent.new(@country_stamp))\n\n    assert_selector(\"img[loading='lazy']\")\n  end\n\n  test \"applies custom classes\" do\n    render_inline(Ui::StampComponent.new(@country_stamp, class: \"custom-class\"))\n\n    assert_selector(\".custom-class\")\n  end\n\n  test \"passes through custom attributes\" do\n    render_inline(Ui::StampComponent.new(@country_stamp, data: {test: \"value\"}))\n\n    assert_selector(\"[data-test='value']\")\n  end\nend\n"
  },
  {
    "path": "test/controllers/analytics/dashboards_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Analytics::DashboardsControllerTest < ActionDispatch::IntegrationTest\n  test \"should get show\" do\n    get analytics_dashboards_path\n    assert_response :success\n  end\n\n  test \"only return the last 60 days of data excluding today\" do\n    travel_to Time.new(2023, 8, 26, 12, 0, 0) do\n      visit_1 = Ahoy::Visit.create!(started_at: Time.current)\n      Ahoy::Event.create!(name: \"Some Page during visit_1\", visit: visit_1, time: Time.current)\n      Recurring::RollupJob.new.perform\n    end\n\n    travel_to Time.new(2023, 8, 27, 12, 0, 0) do\n      visit_2 = Ahoy::Visit.create!(started_at: Time.current)\n      Ahoy::Event.create!(name: \"Some Page during visit_2\", visit: visit_2, time: Time.current)\n      Recurring::RollupJob.new.perform\n      get daily_page_views_analytics_dashboards_path\n      assert_response :success\n      yesterday_page_views = assigns(:daily_page_views)[Date.new(2023, 8, 26)]\n      today_page_views = assigns(:daily_page_views)[Date.new(2023, 8, 27)]\n      assert_equal 1, yesterday_page_views\n      assert_nil today_page_views\n    end\n  end\n\n  test \"should aggregate daily_visits with rollup\" do\n    travel_to Time.new(2023, 8, 26, 12, 0, 0) do\n      visit_1 = Ahoy::Visit.create!(started_at: Time.current)\n      Ahoy::Event.create!(name: \"Some Page during visit_1\", visit: visit_1, time: Time.current)\n      Recurring::RollupJob.new.perform\n    end\n\n    # Travel to a fixed time for a consistent test environment\n    travel_to Time.new(2023, 8, 27, 12, 0, 0) do\n      # Make first call to populate cache\n      get daily_visits_analytics_dashboards_path\n      assert_response :success\n\n      yesterday_page_views = assigns(:daily_visits)[Date.new(2023, 8, 26)]\n      today_page_views = assigns(:daily_visits)[Date.new(2023, 8, 27)]\n      assert_equal 1, yesterday_page_views\n      assert_nil today_page_views\n\n      # Create a new page view today\n      visit_2 = Ahoy::Visit.create!(started_at: Time.current)\n      Ahoy::Event.create!(name: \"Some Page during visit 2\", visit: visit_2, time: Time.current)\n\n      Recurring::RollupJob.new.perform\n\n      # Make second call, length should not change because we only display the last 60 days up to yesterday\n      get daily_visits_analytics_dashboards_path\n      assert_response :success\n      yesterday_page_views = assigns(:daily_visits)[Date.new(2023, 8, 26)]\n      today_page_views = assigns(:daily_visits)[Date.new(2023, 8, 27)]\n      assert_equal 1, yesterday_page_views\n      assert_nil today_page_views\n    end\n\n    # Travel to the next morning, cache should expire\n    travel_to Time.new(2023, 8, 28, 12, 0, 0) do\n      # Make third call, length should change by 1\n      get daily_visits_analytics_dashboards_path\n      assert_response :success\n      day_before_yesterday_page_views = assigns(:daily_visits)[Date.new(2023, 8, 27)]\n      yesterday_page_views = assigns(:daily_visits)[Date.new(2023, 8, 27)]\n      today_page_views = assigns(:daily_visits)[Date.new(2023, 8, 28)]\n      assert_equal 1, day_before_yesterday_page_views\n      assert_equal 1, yesterday_page_views\n      assert_nil today_page_views\n    end\n  end\nend\n"
  },
  {
    "path": "test/controllers/announcements_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass AnnouncementsControllerTest < ActionDispatch::IntegrationTest\n  test \"index returns success\" do\n    get announcements_path\n    assert_response :success\n  end\n\n  test \"show returns success for existing announcement\" do\n    announcement = Announcement.published.first\n    skip \"No published announcements\" if announcement.nil?\n\n    get announcement_path(announcement.slug)\n    assert_response :success\n  end\n\n  test \"show returns 404 for nonexistent announcement\" do\n    get announcement_path(\"nonexistent-slug\")\n    assert_response :not_found\n  end\n\n  test \"feed returns RSS\" do\n    get feed_announcements_path(format: :rss)\n    assert_response :success\n    assert_equal \"application/rss+xml; charset=utf-8\", response.content_type\n  end\nend\n"
  },
  {
    "path": "test/controllers/cfp_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass CFPControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @event = events(:future_conference)\n  end\n\n  test \"should get index\" do\n    get cfp_index_path\n    assert_response :success\n    assert_select \"h1\", /Open Call for Proposals/i\n  end\n\n  test \"should get call4papers link\" do\n    get cfp_index_path\n    assert_select \"link\", href: @event.cfps.first.link\n  end\n\n  test \"should get call4papers open in future\" do\n    get cfp_index_path\n    assert_select \"div\", /opens on/i\n  end\n\n  test \"should get index call4papers opened\" do\n    @event.cfps.first.update(open_date: 1.week.ago, close_date: 1.day.from_now)\n\n    get cfp_index_path\n    assert_select \"div\", /closes on/i\n  end\nend\n"
  },
  {
    "path": "test/controllers/countries_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass CountriesControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @railsconf_event = events(:railsconf_2017)\n    @rubyconfth_event = events(:rubyconfth_2022)\n    @rails_world_event = events(:rails_world_2023)\n    @tropical_rb_event = events(:tropical_rb_2024)\n    @brightonruby_event = events(:brightonruby_2024)\n  end\n\n  test \"should get index\" do\n    get countries_path\n    assert_response :success\n    assert_select \"h1\", /Countries/i\n  end\n\n  test \"should display countries grouped by continent on index\" do\n    get countries_path\n    assert_response :success\n\n    # Verify that @countries_by_continent is assigned\n    assert_not_nil assigns(:countries_by_continent)\n    assert_not_nil assigns(:events_by_country)\n    assert_not_nil assigns(:users_by_country)\n\n    # Check that the assigned variables are hashes\n    assert_kind_of Hash, assigns(:countries_by_continent)\n    assert_kind_of Hash, assigns(:events_by_country)\n    assert_kind_of Hash, assigns(:users_by_country)\n  end\n\n  test \"should handle invalid country parameter\" do\n    get country_path(\"nonexistent-country\")\n    assert_redirected_to countries_path\n  end\n\n  test \"should filter events and users by country on show page\" do\n    # Test the filtering logic by checking that events and users are properly filtered\n    get country_path(\"united-states\")\n    assert_response :success\n\n    events = assigns(:events)\n    users = assigns(:users)\n    assert_not_nil events\n    assert_not_nil users\n    assert_kind_of ActiveRecord::Relation, events\n    assert_kind_of ActiveRecord::Relation, users\n\n    # All events should either match the country or be filtered out\n    # The controller filters events where event.country == @country\n    country = assigns(:country)\n    if country.present?\n      events.each do |event|\n        # Each event should either have matching country or be included due to the filtering logic\n        assert event.static_metadata.nil? || event.country == country || event.country.nil?\n      end\n    end\n  end\n\n  test \"should sort events by start_date in reverse order on show page\" do\n    get country_path(\"united-states\")\n    assert_response :success\n\n    events = assigns(:events)\n    assert_not_nil events\n    assert_kind_of ActiveRecord::Relation, events\n\n    # Check that events are sorted in reverse order (most recent first)\n    if events.size > 1\n      dates = events.map(&:start_date)\n      assert_equal dates.sort { |a, b| (b || Date.new(0)) <=> (a || Date.new(0)) }, dates, \"Events should be sorted by start_date in reverse order\"\n    end\n  end\n\n  test \"should handle special characters in country parameter\" do\n    # Test with country parameter containing special characters\n    get country_path(\"united-kingdom\")\n    assert_response :success\n\n    assert_not_nil assigns(:events)\n    assert_kind_of ActiveRecord::Relation, assigns(:events)\n  end\n\n  test \"should handle case sensitivity in country parameter\" do\n    # Test with different case variations\n    get country_path(\"United-States\")\n    assert_response :success\n\n    assert_not_nil assigns(:events)\n    assert_kind_of ActiveRecord::Relation, assigns(:events)\n  end\n\n  test \"country_path helper works with Country instance via to_param\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_equal \"/countries/germany\", country_path(country)\n  end\n\n  test \"country_path helper works with multi-word country names\" do\n    country = Country.find_by(country_code: \"US\")\n\n    assert_equal \"/countries/united-states\", country_path(country)\n  end\n\n  test \"can navigate to country page using Country instance\" do\n    country = Country.find_by(country_code: \"US\")\n\n    get country_path(country)\n\n    assert_response :success\n    assert_equal country.alpha2, assigns(:country).alpha2\n  end\nend\n"
  },
  {
    "path": "test/controllers/events/archive_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Events::ArchiveControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @conference = events(:brightonruby_2024)\n    @meetup = events(:wnb_rb_meetup)\n  end\n\n  test \"should get index with all filter\" do\n    get archive_events_path(kind: \"all\")\n    assert_response :success\n    assert_includes @response.body, @conference.name\n    assert_includes @response.body, @meetup.name\n  end\n\n  test \"should get index with meetup filter\" do\n    get archive_events_path(kind: \"meetup\")\n    assert_response :success\n    assert_includes @response.body, @meetup.name\n    assert_not_includes @response.body, @conference.name\n  end\nend\n"
  },
  {
    "path": "test/controllers/events/meetups_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Events::MeetupsControllerTest < ActionDispatch::IntegrationTest\n  test \"should show meetup\" do\n    active_meetup = events(:wnb_rb_meetup)\n    events(:new_rb_meetup).destroy\n\n    get meetups_events_url\n    assert_response :success\n    assert_match active_meetup.name, response.body\n  end\nend\n"
  },
  {
    "path": "test/controllers/events/participations_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Events::ParticipationsControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @event = events(:rails_world_2023)\n    @user = users(:one)\n    @event.event_participations.create!(user: @user, attended_as: \"visitor\")\n  end\n\n  test \"should get index\" do\n    get event_participants_url(@event)\n    assert_response :success\n    assert_select \"div\", /#{@user.name}/\n  end\n\n  test \"should get index for signed in user\" do\n    sign_in_as @user\n    get event_participants_url(@event)\n    assert_response :success\n    assert_select \"div\", /#{@user.name}/\n  end\n\n  test \"should redirect to root path if event is not found\" do\n    get event_participants_url(event_slug: \"react-conf\")\n    assert_redirected_to root_path\n  end\nend\n"
  },
  {
    "path": "test/controllers/events/related_talks_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Events::RelatedTalksControllerTest < ActionDispatch::IntegrationTest\n  test \"should get index\" do\n    @event = events(:rails_world_2023)\n    @talks = @event.talks\n    @talk = @talks.first\n    get event_related_talks_path(@event, active_talk: @talk.slug)\n    assert_response :success\n    assert_equal @event, assigns(:event)\n    assert_equal @event.talks, assigns(:talks)\n    assert_equal @talk, assigns(:active_talk)\n  end\nend\n"
  },
  {
    "path": "test/controllers/events/schedule_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Events::ScheduleControllerTest < ActionDispatch::IntegrationTest\n  # test \"the truth\" do\n  #   assert true\n  # end\nend\n"
  },
  {
    "path": "test/controllers/events/series_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Events::SeriesControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @event_series = event_series(:railsconf)\n  end\n\n  test \"should get index\" do\n    get series_index_url\n    assert_response :success\n  end\n\n  test \"should show event series\" do\n    get series_url(@event_series)\n    assert_response :success\n  end\n\n  test \"should redirect to root for wrong slugs\" do\n    get series_url(\"wrong-slug\")\n    assert_response :moved_permanently\n    assert_redirected_to root_path\n  end\n\n  test \"should redirect to correct series slug when accessed via alias\" do\n    @event_series.aliases.create!(name: \"Rails Conference\", slug: \"rails-conference\")\n\n    get series_url(\"rails-conference\")\n    assert_response :moved_permanently\n    assert_redirected_to series_path(@event_series)\n  end\nend\n"
  },
  {
    "path": "test/controllers/events/sponsors_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Events::SponsorsControllerTest < ActionDispatch::IntegrationTest\n  test \"should get index\" do\n    get event_sponsors_path(sponsors(:one).event)\n    assert_response :success\n  end\n\n  test \"should get index with sponsors ordered by tier\" do\n    event = sponsors(:one).event\n    get event_sponsors_path(event)\n    assert_response :success\n\n    sponsors_by_tier = assigns(:sponsors_by_tier)\n\n    assert_not_nil sponsors_by_tier, \"sponsors_by_tier should not be nil\"\n    assert_equal sponsors(:one).organization.name, sponsors_by_tier[\"gold\"].first.organization.name\n    assert_equal sponsors(:two).organization.name, sponsors_by_tier[\"silver\"].first.organization.name\n    assert_equal sponsors(:three).organization.name, sponsors_by_tier[\"bronze\"].first.organization.name\n  end\nend\n"
  },
  {
    "path": "test/controllers/events_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass EventsControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @event = events(:railsconf_2017)\n    @user = users(:lazaro_nixon)\n  end\n\n  test \"should get index\" do\n    get archive_events_url\n    assert_response :success\n    assert_select \"h1\", /Events Archive/i\n    assert_select \"##{dom_id(@event)}\", 1\n  end\n\n  test \"should get index with search results\" do\n    get archive_events_url(s: \"rails\")\n    assert_response :success\n    assert_select \"h1\", /Events Archive/i\n    assert_select \"div\", /search results for \"rails\"/i\n    assert_select \"##{dom_id(@event)}\", 1\n  end\n\n  test \"should get index and return events in the correct order\" do\n    event_names = %i[brightonruby_2024 no_sponsors_event new_rb_meetup railsconf_2017 future_conference rails_world_2023 tropical_rb_2024 rubyconfth_2022 wnb_rb_meetup].map { |event| events(event) }.map(&:name)\n\n    get archive_events_url\n\n    assert_response :success\n\n    assert_select \".event .event-name\", count: event_names.size do |nodes|\n      assert_equal event_names, nodes.map(&:text)\n    end\n  end\n\n  test \"should get index search result\" do\n    get archive_events_url(letter: \"T\")\n    assert_response :success\n    assert_select \"span\", text: \"Tropical Ruby 2024\"\n  end\n\n  test \"should show event\" do\n    get event_url(@event)\n    assert_response :success\n  end\n\n  test \"should show event talks\" do\n    get event_talks_url(@event)\n    assert_response :success\n  end\n\n  test \"should show event events\" do\n    get event_events_url(@event)\n    assert_response :success\n  end\n\n  test \"should redirect to canonical event\" do\n    @talk = talks(:one)\n    @talk.update(event: @event)\n    canonical_event = events(:rubyconfth_2022)\n    @event.assign_canonical_event!(canonical_event: canonical_event)\n    get event_url(@event)\n\n    assert_redirected_to event_url(canonical_event)\n  end\n\n  test \"should redirect to root for wrong slugs\" do\n    get event_url(\"wrong-slug\")\n    assert_response :moved_permanently\n    assert_redirected_to root_path\n  end\n\n  test \"should redirect to correct event slug when accessed via alias\" do\n    @event.slug_aliases.create!(name: \"Old Name\", slug: \"old-event-slug\")\n\n    get event_url(\"old-event-slug\")\n    assert_response :moved_permanently\n    assert_redirected_to event_path(@event)\n  end\n\n  test \"should get edit\" do\n    sign_in_as @user\n    get edit_event_url(@event)\n    assert_response :success\n  end\n\n  test \"should create a pending suggestion for anonymous users\" do\n    assert_difference \"Suggestion.pending.count\", 1 do\n      patch event_url(@event), params: {event: {city: \"Paris\", country_code: \"FR\"}}\n    end\n\n    assert_redirected_to event_url(@event)\n  end\n\n  test \"should create a pending suggestion for signed in users\" do\n    sign_in_as @user\n\n    assert_difference \"Suggestion.pending.count\", 1 do\n      patch event_url(@event), params: {event: {city: \"Paris\", country_code: \"FR\"}}\n    end\n\n    assert_redirected_to event_url(@event)\n  end\n\n  test \"should update directly the content for admins\" do\n    sign_in_as users(:admin)\n    assert_difference \"Suggestion.approved.count\", 1 do\n      patch event_url(@event), params: {event: {city: \"Paris\", country_code: \"FR\"}}\n    end\n\n    assert_equal \"Paris\", @event.reload.city\n    assert_equal \"FR\", @event.reload.country_code\n    assert_redirected_to event_url(@event)\n  end\n\n  test \"should display an empty state message when no events are found\" do\n    Event.destroy_all\n\n    get archive_events_url\n\n    assert_response :success\n    assert_select \"p\", text: \"No events found\"\n  end\nend\n"
  },
  {
    "path": "test/controllers/favorite_users_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass FavoriteUsersControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:one)\n    sign_in_as @user\n  end\n\n  test \"should get index\" do\n    get favorite_users_url\n    assert_response :success\n  end\n\n  test \"should create favorite_user\" do\n    fav_user = users :marco\n\n    assert_difference(\"FavoriteUser.count\") do\n      post favorite_users_url, params: {favorite_user: {favorite_user_id: fav_user.id}}\n    end\n\n    assert_redirected_to favorite_users_url\n  end\n\n  test \"should destroy favorite_user\" do\n    favorite_user = favorite_users(:one)\n\n    assert_difference(\"FavoriteUser.count\", -1) do\n      delete favorite_user_url(favorite_user)\n    end\n\n    assert_redirected_to favorite_users_url\n  end\n\n  test \"should update favorite_user notes\" do\n    favorite_user = favorite_users(:one)\n    patch favorite_user_url(favorite_user), params: {favorite_user: {notes: \"Met at dinner at Blue Ridge Ruby\"}}\n    assert_redirected_to favorite_users_url\n    favorite_user.reload\n    assert_equal \"Met at dinner at Blue Ridge Ruby\", favorite_user.notes\n  end\n\n  test \"User is unfavorited while taking notes\" do\n    favorite_user = favorite_users(:one)\n    delete favorite_user_url(favorite_user)\n    patch favorite_user_url(favorite_user), params: {favorite_user: {notes: \"This note should not be saved\"}}\n    assert_response :not_found\n  end\nend\n"
  },
  {
    "path": "test/controllers/locations/users_controller_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Locations::UsersControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    # Create a user with US location and coordinates\n    @us_user = User.create!(\n      name: \"US Ruby Developer\",\n      email: \"us_dev@example.com\",\n      slug: \"us-ruby-developer\",\n      location: \"San Francisco, CA\",\n      city: \"San Francisco\",\n      state_code: \"CA\",\n      country_code: \"US\",\n      latitude: 37.7749,\n      longitude: -122.4194\n    )\n    cities(:san_francisco)\n  end\n\n  # Country Tests\n  test \"should get users index for country and display user\" do\n    get country_users_path(\"united-states\")\n    assert_response :success\n    assert_select \"body\", text: /#{@us_user.name}/\n  end\n\n  test \"should handle invalid country gracefully\" do\n    get country_users_path(\"nonexistent-country\")\n    assert_redirected_to countries_path\n  end\n\n  # City Tests\n  test \"should get users index for city\" do\n    get city_users_path(\"san-francisco\")\n    assert_response :success\n    assert_select \"body\", text: /#{@us_user.name}/\n  end\n\n  # State Tests\n  test \"should get users index for state\" do\n    get state_users_path(\"us\", \"california\")\n    assert_response :success\n    assert_select \"body\", text: /#{@us_user.name}/\n  end\n\n  test \"should handle invalid state gracefully\" do\n    get state_users_path(\"us\", \"nonexistent-state\")\n    assert_redirected_to country_path(\"united-states\")\n  end\n\n  # Continent Tests\n  test \"should get users index for continent\" do\n    get continent_users_path(\"north-america\")\n    assert_response :success\n    assert_select \"body\", text: /#{@us_user.name}/\n  end\n\n  test \"should handle invalid continent gracefully\" do\n    get continent_users_path(\"nonexistent-continent\")\n    assert_redirected_to continents_path\n  end\n\n  # Coordinate Location Tests\n  test \"should get users index for coordinates\" do\n    get coordinates_users_path(\"38.0639,-122.8397\")\n    assert_response :success\n    assert_select \"body\", text: /#{@us_user.name}/\n  end\nend\n"
  },
  {
    "path": "test/controllers/organizations/logos_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Organizations::LogosControllerTest < ActionDispatch::IntegrationTest\n  test \"should get 401 as a non-admin\" do\n    sign_in_as(users(:one))\n    get organization_logos_path(organizations(:one))\n    assert_response :unauthorized\n  end\n\n  test \"should get show as an admin\" do\n    sign_in_as(users(:admin))\n    get organization_logos_path(organizations(:one))\n    assert_response :success\n  end\n\n  test \"should get show with organization\" do\n    sign_in_as(users(:admin))\n    get organization_logos_path(organizations(:one))\n    assert_response :success\n    assert_equal assigns(:organization), organizations(:one)\n  end\n\n  test \"should get moved permanently if organization not found\" do\n    sign_in_as(users(:admin))\n    get organization_logos_path(\"not-found\")\n    assert_response :moved_permanently\n    assert_redirected_to organizations_path\n    assert_equal \"Organization not found\", flash[:notice]\n  end\n\n  test \"should update logo if user is admin\" do\n    sign_in_as(users(:admin))\n    patch organization_logos_path(organizations(:one)), params: {organization: {logo_url: \"https://example.com/logo.png\", logo_background: \"transparent\"}}\n    assert_response :redirect\n    assert_redirected_to organization_logos_path(organizations(:one))\n    assert_equal \"https://example.com/logo.png\", assigns(:organization).logo_url\n    assert_equal \"transparent\", assigns(:organization).logo_background\n    assert_equal \"Updated successfully.\", flash[:notice]\n  end\n\n  test \"should not update logo if user is not admin\" do\n    sign_in_as(users(:one))\n    patch organization_logos_path(organizations(:one)), params: {organization: {logo_url: \"https://example.com/logo.png\", logo_background: \"transparent\"}}\n    assert_response :unauthorized\n  end\n\n  test \"should redirect old sponsors logos path to organizations logos\" do\n    sign_in_as(users(:admin))\n    get \"/sponsors/#{organizations(:one).slug}/logos\"\n    assert_redirected_to organization_logos_path(organizations(:one))\n  end\nend\n"
  },
  {
    "path": "test/controllers/organizations/wrapped_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Organizations::WrappedControllerTest < ActionDispatch::IntegrationTest\n  test \"should get index\" do\n    organization = organizations(:one)\n    get organization_wrapped_index_path(organization_slug: organization.slug)\n    assert_response :success\n  end\n\n  test \"should render organization wrapped content\" do\n    organization = organizations(:one)\n    get organization_wrapped_index_path(organization_slug: organization.slug)\n    assert_select \"h1\", text: /2025/\n  end\n\n  test \"returns 404 for unknown organization\" do\n    get organization_wrapped_index_path(organization_slug: \"nonexistent\")\n    assert_response :not_found\n  end\nend\n"
  },
  {
    "path": "test/controllers/organizations_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass OrganizationsControllerTest < ActionDispatch::IntegrationTest\n  test \"should get index\" do\n    get organizations_url\n    assert_response :success\n  end\n\n  test \"should get show\" do\n    organization = organizations(:one)\n    get organization_url(organization)\n    assert_response :success\n  end\n\n  test \"should redirect old sponsors path to organizations\" do\n    get \"/sponsors\"\n    assert_redirected_to organizations_path\n  end\n\n  test \"should redirect old sponsor show path to organization\" do\n    organization = organizations(:one)\n    get \"/sponsors/#{organization.slug}\"\n    assert_redirected_to organization_path(organization)\n  end\nend\n"
  },
  {
    "path": "test/controllers/page_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass PageControllerTest < ActionDispatch::IntegrationTest\n  test \"should get home page\" do\n    get root_path\n    assert_response :success\n  end\n\n  test \"should get uses page\" do\n    get uses_path\n    assert_response :success\n  end\n\n  test \"should set global meta tags\" do\n    get root_path\n    assert_response :success\n\n    assert_select \"title\", Metadata::DEFAULT_TITLE\n    assert_select \"meta[name=description][content=?]\", Metadata::DEFAULT_DESC\n    assert_select \"link[rel='canonical'][href=?]\", request.original_url\n\n    expected_logo_url = @controller.view_context.image_url(\"logo_og_image.png\")\n\n    # OpenGraph\n    assert_select \"meta[property='og:title'][content=?]\", Metadata::DEFAULT_TITLE\n    assert_select \"meta[property='og:description'][content=?]\", Metadata::DEFAULT_DESC\n    assert_select \"meta[property='og:site_name'][content=?]\", Metadata::SITE_NAME\n    assert_select \"meta[property='og:url'][content=?]\", request.original_url\n    assert_select \"meta[property='og:type'][content=website]\"\n    assert_select \"meta[property='og:image'][content=?]\", expected_logo_url\n\n    # Twitter\n    assert_select \"meta[name='twitter:title'][content=?]\", Metadata::DEFAULT_TITLE\n    assert_select \"meta[name='twitter:description'][content=?]\", Metadata::DEFAULT_DESC\n    assert_select \"meta[name='twitter:card'][content=summary_large_image]\"\n    assert_select \"meta[name='twitter:image'][content=?]\", expected_logo_url\n  end\nend\n"
  },
  {
    "path": "test/controllers/profiles/connect_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Profiles::ConnectControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:one)\n    @user.connected_accounts.create(provider: \"passport\", uid: \"123456\")\n\n    @lazaro = users(:lazaro_nixon)\n    @lazaro.connected_accounts.create(provider: \"passport\", uid: \"ABCDEF\")\n  end\n\n  test \"should redirect to root path\" do\n    get profiles_connect_index_path\n    assert_redirected_to root_path\n  end\n\n  test \"guest should see the claim profile page\" do\n    get profiles_connect_path(id: \"marco\")\n    assert_response :success\n    assert_includes response.body, \"is available to Claim!\"\n    assert_select \".pt-4 a.btn.btn-primary[data-turbo-frame='modal']\", text: \"Claim my Passport\"\n  end\n\n  # for now this feature is disabled\n  # test \"guest should see the friend prompt page\" do\n  #   get profiles_connect_path(id: \"one\")\n  #   assert_response :success\n  #   assert_includes response.body, \"🎉 Awesome! You Discovered a Friend\"\n  #   assert_includes response.body, \"Sign In and Connect\"\n  # end\n\n  # test \"user should see the friend prompt page\" do\n  #   sign_in_as @lazaro\n  #   get profiles_connect_path(id: \"one\")\n  #   assert_response :success\n  #   assert_includes response.body, \"🎉 Awesome! You Discovered a Friend\"\n  #   # enable this when we have a way to connect to other users\n  #   # assert_select \".pt-4 a.btn.btn-primary.btn-disabled.hidden\", text: \"Connect\"\n  # end\n\n  test \"guest visiting a claimed profile should be redirected to the claimed profile page\" do\n    get profiles_connect_path(id: @user.passports.first.uid)\n    assert_redirected_to profile_path(@user)\n  end\n\n  # test \"user should see no profile found page\" do\n  #   sign_in_as @lazaro\n  #   get profiles_connect_path(id: \"123457\")\n  #   assert_response :success\n  #   assert_includes response.body, \"🤷‍♂️ No Profile Found Here\"\n  #   assert_select \".pt-4 a.btn.btn-primary\", text: \"Browse Talks\"\n  #   assert_select \".pt-4 a.btn.btn-secondary\", text: \"View Events\"\n  # end\n\n  test \"user should get redirected if they land on their connect page\" do\n    sign_in_as @lazaro\n    get profiles_connect_path(id: \"ABCDEF\")\n    assert_redirected_to profile_path(@lazaro)\n    assert_equal \"You did it. You landed on your profile page 🙌\", flash[:notice]\n  end\n\n  test \"user should be able to claim a profile\" do\n    sign_in_as users(:admin)\n    get profiles_connect_path(id: \"not_a_user\")\n    assert_includes response.body, \"is available to Claim!\"\n    # This is a POST request to claim a profile for themselves\n    assert_select \".pt-4 a.btn.btn-primary[data-turbo-method=\\\"post\\\"]\"\n  end\nend\n"
  },
  {
    "path": "test/controllers/profiles/enhance_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Profiles::EnhanceControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = sign_in_as(users(:admin))\n  end\n\n  test \"#patch\" do\n    user = users(:marco)\n\n    assert_nil user.github_metadata.dig(\"profile\", \"login\")\n\n    assert_enqueued_jobs 2 do\n      patch profiles_enhance_url(user, {format: :turbo_stream})\n      assert_response :success\n    end\n\n    VCR.use_cassette(\"profiles/enhance_controller_test/patch\") do\n      perform_enqueued_jobs\n    end\n\n    user.reload\n\n    assert_equal \"marcoroth\", user.github_metadata.dig(\"profile\", \"login\")\n  end\n\n  test \"#patch with github_handle different from slug\" do\n    user = users(:yaroslav)\n\n    assert_equal \"yshmarov\", user.github_handle\n    assert_equal \"yaroslav-shmarov\", user.slug\n    assert_equal \"yshmarov\", user.to_param\n\n    assert_enqueued_jobs 2 do\n      patch profiles_enhance_url(user, {format: :turbo_stream})\n      assert_response :success\n    end\n  end\nend\n"
  },
  {
    "path": "test/controllers/profiles/involvements_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Profiles::InvolvementsControllerTest < ActionDispatch::IntegrationTest\n  test \"user with event involvements\" do\n    user = users(:one)\n    event = events(:railsconf_2017)\n    EventInvolvement.create!(involvementable: user, event: event, role: \"volunteer\")\n\n    get profile_involvements_path(user)\n\n    assert_response :success\n  end\n\n  test \"user without involvements\" do\n    user = users(:one)\n\n    get profile_involvements_path(user)\n\n    assert_response :success\n  end\n\n  test \"user with event and meetup involvements\" do\n    user = users(:one)\n    event = events(:tropical_rb_2024)\n    meetup = events(:wnb_rb_meetup)\n    EventInvolvement.create!(involvementable: user, event: event, role: \"organizer\")\n    EventInvolvement.create!(involvementable: user, event: meetup, role: \"organizer\")\n\n    get profile_involvements_path(user)\n\n    assert_response :success\n  end\nend\n"
  },
  {
    "path": "test/controllers/profiles/map_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Profiles::MapControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:yaroslav)\n    sign_in_as(@user)\n  end\n\n  test \"should redirect user if GitHub handle is different than profile slug\" do\n    get profile_map_index_path(profile_slug: @user.slug)\n    assert_response :redirect\n    assert_redirected_to profile_map_index_path(profile_slug: @user.github_handle)\n    follow_redirect!\n    assert_response :success\n  end\nend\n"
  },
  {
    "path": "test/controllers/profiles/notes_controller_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Profiles::NotesControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:lazaro_nixon)\n    @profile = users(:chael)\n  end\n\n  test \"if user is not logged in - redirects\" do\n    get profile_notes_path(@profile)\n    assert_response :redirect\n    assert_redirected_to profile_path(@profile)\n  end\n\n  test \"if user is not favorited - redirects\" do\n    sign_in_as(@user)\n    get profile_notes_path(@profile)\n    assert_response :redirect\n    assert_redirected_to profile_path(@profile)\n  end\n\n  test \"if user is favorited - shows notes\" do\n    sign_in_as(@user)\n    @profile.favorited_by.create(user: @user, notes: \"This is a note about the user\")\n    get profile_notes_path(@profile)\n    assert_response :success\n    assert_includes response.body, \"This is a note about the user\"\n  end\n\n  test \"edit existing notes\" do\n    sign_in_as(@user)\n    @profile.favorited_by.create(user: @user, notes: \"This is a note about the user\")\n    get edit_profile_notes_path(@profile)\n    assert_response :success\n    assert_includes response.body, \"This is a note about the user\"\n  end\nend\n"
  },
  {
    "path": "test/controllers/profiles/wrapped_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Profiles::WrappedControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:lazaro_nixon)\n    sign_in_as(@user)\n  end\n\n  test \"should get wrapped page for user\" do\n    get profile_wrapped_index_path(profile_slug: @user.slug)\n    assert_response :success\n    assert_includes response.body, \"2025\"\n    assert_includes response.body, \"Wrapped\"\n    assert_includes response.body, @user.name\n  end\n\n  test \"should show watching stats section\" do\n    get profile_wrapped_index_path(profile_slug: @user.slug)\n    assert_response :success\n    assert_includes response.body, \"Your Watching Journey\"\n    assert_includes response.body, \"Talks Watched\"\n  end\n\n  test \"should show top topics section\" do\n    get profile_wrapped_index_path(profile_slug: @user.slug)\n    assert_response :success\n    assert_includes response.body, \"Your Top Topics\"\n  end\n\n  test \"should show events attended section\" do\n    get profile_wrapped_index_path(profile_slug: @user.slug)\n    assert_response :success\n    assert_includes response.body, \"Events Attended\"\n  end\n\n  test \"should show closing page\" do\n    get profile_wrapped_index_path(profile_slug: @user.slug)\n    assert_response :success\n    assert_includes response.body, \"That's a Wrap!\"\n    assert_includes response.body, \"RubyEvents.org\"\n  end\n\n  test \"should generate og image\" do\n    skip \"flaky test\" if ENV[\"CI\"]\n\n    get og_image_profile_wrapped_index_path(profile_slug: @user.slug)\n    assert_response :redirect\n    assert_match %r{active_storage/blobs}, response.location\n  end\nend\n"
  },
  {
    "path": "test/controllers/profiles_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass ProfilesControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:one)\n    @user_with_talk = users(:marco)\n  end\n\n  test \"should show profile\" do\n    get profile_url(@user)\n    assert_response :success\n  end\n\n  test \"should show profile with talks\" do\n    get profile_url(@user_with_talk)\n    assert_response :success\n    assert_equal @user_with_talk.talks_count, assigns(:talks).length\n  end\n\n  test \"should redirect to canonical user\" do\n    talk = @user_with_talk.talks.first\n    original_slug = @user_with_talk.slug\n\n    @user_with_talk.assign_canonical_speaker!(canonical_speaker: @user)\n    @user_with_talk.reload\n\n    assert_equal @user, @user_with_talk.canonical\n    assert @user.talks.ids.include?(talk.id)\n    assert @user_with_talk.talks.empty?\n\n    get profile_url(original_slug)\n    assert_redirected_to profile_url(@user)\n  end\n\n  # test \"should redirect to github handle user when slug and github handle are different\" do\n  #   user = users(:one)\n  #   user.github_handle = \"new-github\"\n  #   user.save\n  #   get profile_url(user.slug)\n  #   assert_redirected_to profile_url(user.github_handle)\n  # end\n\n  test \"should get edit in a remote modal\" do\n    get edit_profile_url(@user), headers: {\"Turbo-Frame\" => \"modal\"}\n    assert_response :success\n    assert_template \"profiles/edit\"\n  end\n\n  test \"should redirect to root when not in a remote modal\" do\n    get edit_profile_url(@user)\n    assert_response :redirect\n    assert_redirected_to root_url\n  end\n\n  test \"should create a suggestion for user\" do\n    patch profile_url(@user), params: {user: {bio: \"new bio\", github: \"new-github\", name: \"new-name\", slug: \"new-slug\", twitter: \"new-twitter\", website: \"new-website\"}}\n\n    @user.reload\n\n    assert_redirected_to profile_url(@user)\n    assert_not_equal @user.reload.bio, \"new bio\"\n    assert_equal 1, @user.suggestions.pending.count\n  end\n\n  test \"admin can update directly the user\" do\n    assert_equal 0, @user.suggestions.pending.count\n    sign_in_as users(:admin)\n    patch profile_url(@user), params: {user: {bio: \"new bio\", github: \"new-github\", name: \"new-name\", twitter: \"new-twitter\", website: \"new-website\"}}\n\n    @user.reload\n\n    assert_redirected_to profile_path(@user)\n    assert_equal \"new bio\", @user.reload.bio\n    assert_equal 0, @user.suggestions.pending.count\n    assert_equal users(:admin).id, @user.suggestions.last.suggested_by_id\n  end\n\n  test \"owner can update the user directly\" do\n    sign_in_as @user\n\n    assert_no_changes -> { @user.suggestions.pending.count } do\n      patch profile_url(@user), params: {user: {bio: \"new bio\", twitter: \"new-twitter\", website: \"new-website\"}}\n    end\n\n    assert_redirected_to profile_url(@user)\n    assert_equal \"new bio\", @user.reload.bio\n    assert_equal @user.twitter, \"new-twitter\"\n    assert_equal @user.website, \"https://new-website\"\n    assert_equal @user.id, @user.suggestions.last.suggested_by_id\n  end\n\n  test \"owner cannot update their name\" do\n    sign_in_as @user\n    original_name = @user.name\n\n    patch profile_url(@user), params: {user: {name: \"new-name\"}}\n\n    assert_equal original_name, @user.reload.name\n  end\n\n  test \"should redirect when user not found\" do\n    get profile_url(\"non-existent-slug\")\n    assert_redirected_to speakers_path\n    assert_equal \"User not found\", flash[:notice]\n  end\n\n  test \"discarded speaker_talks\" do\n    user = users(:marco)\n    assert user.talks_count.positive?\n\n    user.user_talks.each(&:discard)\n\n    get profile_url(user)\n    assert_response :success\n    assert_equal 0, assigns(:talks).count\n  end\n\n  test \"should find user by alias slug and redirect to canonical slug\" do\n    user = User.create!(name: \"Test User\", github_handle: \"test-controller-user\")\n    user.aliases.create!(name: \"Old Name\", slug: \"old-controller-slug\")\n\n    get profile_url(\"old-controller-slug\")\n    assert_redirected_to profile_url(user)\n  end\n\n  test \"should redirect from alias slug to canonical user when user has canonical\" do\n    canonical_user = User.create!(name: \"Canonical User\", github_handle: \"canonical-controller\")\n    duplicate_user = User.create!(name: \"Duplicate User\", github_handle: \"duplicate-controller\")\n\n    duplicate_user.assign_canonical_user!(canonical_user: canonical_user)\n    duplicate_user.reload\n\n    alias_record = Alias.find_by(slug: \"duplicate-controller\")\n    assert_not_nil alias_record\n    assert_equal canonical_user.id, alias_record.aliasable_id\n\n    get profile_url(\"duplicate-controller\")\n    assert_redirected_to profile_url(canonical_user)\n  end\nend\n"
  },
  {
    "path": "test/controllers/recommendations_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass RecommendationsControllerTest < ActionDispatch::IntegrationTest\n  test \"should redirect to login when accessing recommendations without authentication\" do\n    get recommendations_path\n    assert_redirected_to new_session_path\n  end\n\n  test \"should get recommendations page when authenticated\" do\n    user = users(:one)\n    sign_in_as user\n\n    get recommendations_path\n    assert_response :success\n    assert_select \"h1\", \"Recommended for you\"\n    assert_select \"h2\", \"No recommendations yet\"\n  end\n\n  test \"should display no recommendations message when user has no watch history\" do\n    user = users(:one)\n    sign_in_as user\n\n    get recommendations_path\n    assert_response :success\n    assert_select \"p\", text: /Watch some talks to get personalized recommendations based on your interests and viewing history./\n  end\nend\n"
  },
  {
    "path": "test/controllers/sessions/omniauth_controller_test copy.rb",
    "content": "require \"test_helper\"\n\nclass Sessions::OmniauthControllerTest < ActionDispatch::IntegrationTest\n  def setup\n    OmniAuth.config.test_mode = true\n    developer = connected_accounts(:developer_connected_account)\n    @developer_user = developer.user\n    @developer_auth = OmniAuth::AuthHash.new(developer.attributes\n                                                      .slice(\"provider\", \"uid\")\n                                                      .merge({info: {email: developer.user.email}}))\n\n    github = connected_accounts(:github_connected_account)\n    @user = github.user\n    @github_auth = OmniAuth::AuthHash.new(github.attributes\n                                          .slice(\"provider\", \"uid\")\n                                          .merge({info: {email: github.user.email}}))\n  end\n\n  def teardown\n    OmniAuth.config.test_mode = false\n    OmniAuth.config.mock_auth[:github] = nil\n    OmniAuth.config.mock_auth[:developer] = nil\n  end\n\n  test \"creates a new user if not exists (developer)\" do\n    OmniAuth.config.mock_auth[:developer] = OmniAuth::AuthHash.new(uid: \"12345\", info: {github_handle: \"new-user\", name: \"New User\"})\n\n    assert_difference \"User.count\", 1 do\n      post \"/auth/developer/callback\"\n    end\n    user = User.find_by_github_handle(\"new-user\")\n    assert_equal 1, user.connected_accounts.count\n    OmniAuth.config.mock_auth[:developer] = nil\n  end\n\n  test \"creates a new user if not exists (github)\" do\n    OmniAuth.config.add_mock(:github, uid: \"12345\", info: {email: \"twitter@example.com\", nickname: \"twitter\"}, credentials: {token: 1, expires_in: 100})\n    assert_difference \"User.count\", 1 do\n      post \"/auth/github/callback\"\n    end\n\n    assert_equal \"twitter\", User.last.connected_accounts.last.username\n    assert_equal \"twitter\", User.last.github_handle\n    OmniAuth.config.mock_auth[:github] = nil\n  end\n\n  test \"finds existing user if already exists (developer)\" do\n    OmniAuth.config.mock_auth[:developer] = @developer_auth\n    assert_no_difference \"User.count\" do\n      post \"/auth/developer/callback\"\n    end\n    assert_redirected_to root_path\n    OmniAuth.config.mock_auth[:developer] = nil\n  end\n\n  test \"finds existing user if already exists (github)\" do\n    OmniAuth.config.mock_auth[:github] = @github_auth\n    assert_no_difference \"User.count\" do\n      post \"/auth/github/callback\"\n    end\n    assert_redirected_to root_path\n    OmniAuth.config.mock_auth[:github] = nil\n  end\n\n  test \"assign a passport to the existing user (github)\" do\n    connected_account = connected_accounts(:github_connected_account)\n\n    OmniAuth.config.before_callback_phase = lambda do |env|\n      env[\"omniauth.params\"] = {\"redirect_to\" => \"/\", \"state\" => \"connect_id:abcde34\"}\n    end\n\n    OmniAuth.config.mock_auth[:github] = OmniAuth::AuthHash.new(\n      provider: :github,\n      uid: connected_account.uid,\n      info: {email: @user.email},\n      params: {\n        redirect_to: profile_path(@user),\n        state: \"connect_id:123456\"\n      }\n    )\n    assert_no_difference \"User.count\" do\n      post \"/auth/github/callback\"\n    end\n\n    assert_redirected_to profile_path(@user)\n    OmniAuth.config.mock_auth[:github] = nil\n  end\n\n  test \"full oauth flow\" do\n    OmniAuth.config.mock_auth[:github] = @github_auth\n    state = \"connect_id:123456\"\n\n    # Start the auth request with the state\n    post \"/auth/github?state=#{state}\"\n    follow_redirect!  # goes to /auth/github/callback\n\n    assert_redirected_to profile_path(@user)\n    OmniAuth.config.mock_auth[:github] = nil\n  end\n\n  test \"finds existing user by email if already exists and creates a new connected account(github)\" do\n    user = users(:one)\n    OmniAuth.config.add_mock(:github, uid: \"12345\", info: {email: user.email, nickname: \"one\"})\n    assert user.connected_accounts.empty?\n    assert_difference \"ConnectedAccount.count\", 1 do\n      post \"/auth/github/callback\"\n    end\n    assert_equal ConnectedAccount.last.user, user\n    assert_equal ConnectedAccount.last.username, \"one\"\n    assert_redirected_to root_path\n    OmniAuth.config.mock_auth[:github] = nil\n  end\n\n  test \"creates a new session for the user\" do\n    OmniAuth.config.mock_auth[:developer] = @developer_auth\n    assert_difference \"Session.count\", 1 do\n      post \"/auth/developer/callback\"\n    end\n  end\n\n  test \"sets a session token cookie\" do\n    OmniAuth.config.mock_auth[:developer] = @developer_auth\n    post \"/auth/developer/callback\"\n    assert_not_nil cookies[\"session_token\"]\n    OmniAuth.config.mock_auth[:developer] = nil\n  end\n\n  test \"redirects to root_path with a success notice\" do\n    OmniAuth.config.mock_auth[:developer] = @developer_auth\n    post \"/auth/developer/callback\"\n    assert_redirected_to root_path\n    assert_equal \"Signed in successfully\", flash[:notice]\n    OmniAuth.config.mock_auth[:developer] = nil\n  end\nend\n"
  },
  {
    "path": "test/controllers/sessions/omniauth_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Sessions::OmniauthControllerTest < ActionDispatch::IntegrationTest\n  def setup\n    OmniAuth.config.test_mode = true\n    developer = connected_accounts(:developer_connected_account)\n    @developer_user = developer.user\n    @developer_auth = OmniAuth::AuthHash.new(developer.attributes\n                                                      .slice(\"provider\", \"uid\")\n                                                      .merge({info: {email: developer.user.email}}))\n\n    github = connected_accounts(:github_connected_account)\n    @user = github.user\n    @github_auth = OmniAuth::AuthHash.new(github.attributes\n                                          .slice(\"provider\", \"uid\")\n                                          .merge(info: {nickname: github.user.github_handle, email: github.user.email}))\n  end\n\n  def teardown\n    OmniAuth.config.test_mode = false\n    OmniAuth.config.mock_auth[:github] = nil\n    OmniAuth.config.mock_auth[:developer] = nil\n    OmniAuth.config.before_callback_phase = nil\n  end\n\n  test \"creates a new user if not exists (developer)\" do\n    OmniAuth.config.mock_auth[:developer] = OmniAuth::AuthHash.new(uid: \"12345\", info: {github_handle: \"new-user\", name: \"New User\"})\n\n    assert_difference \"User.count\", 1 do\n      post \"/auth/developer/callback\"\n    end\n    user = User.find_by_github_handle(\"new-user\")\n    assert_equal 1, user.connected_accounts.count\n  end\n\n  test \"creates a new user if not exists (github)\" do\n    OmniAuth.config.add_mock(:github, uid: \"12345\", info: {email: \"twitter@example.com\", nickname: \"rosa\"}, credentials: {token: 1, expires_in: 100})\n    assert_difference \"User.count\", 1 do\n      post \"/auth/github/callback\"\n    end\n\n    assert_equal \"rosa\", User.last.connected_accounts.last.username\n    assert_equal \"rosa\", User.last.github_handle\n\n    VCR.use_cassette(\"sessions/omniauth_controller_test/creates_a_new_user_if_not_exists_github\") do\n      perform_enqueued_jobs\n    end\n\n    user = User.last\n    assert_equal \"https://rosa.codes\", user.website\n  end\n\n  test \"finds existing user if already exists (developer)\" do\n    OmniAuth.config.mock_auth[:developer] = @developer_auth\n    assert_no_difference \"User.count\" do\n      post \"/auth/developer/callback\"\n    end\n    assert_redirected_to root_path\n  end\n\n  test \"finds existing user if already exists (github)\" do\n    OmniAuth.config.mock_auth[:github] = @github_auth\n    assert_no_difference \"User.count\" do\n      post \"/auth/github/callback\"\n    end\n    assert_redirected_to root_path\n  end\n\n  test \"finds existing user if already exists (github) with different casing\" do\n    github = connected_accounts(:github_connected_account)\n    @user = github.user\n    OmniAuth.config.mock_auth[:github] = OmniAuth::AuthHash.new(github.attributes\n                                          .slice(\"provider\", \"uid\")\n                                          .merge({username: github.user.github_handle.upcase, info: {nickname: github.user.github_handle.upcase, email: github.user.email}}))\n    assert_no_difference \"User.count\" do\n      post \"/auth/github/callback\"\n    end\n    assert_redirected_to root_path\n  end\n\n  test \"assign a passport to the existing user (github)\" do\n    connected_account = connected_accounts(:github_connected_account)\n\n    OmniAuth.config.before_callback_phase = lambda do |env|\n      env[\"omniauth.params\"] = {\"redirect_to\" => \"/\", \"state\" => \"connect_id:abcde34\"}\n    end\n\n    OmniAuth.config.mock_auth[:github] = OmniAuth::AuthHash.new(\n      provider: :github,\n      uid: connected_account.uid,\n      info: {nickname: connected_account.username, email: @user.email}\n    )\n    assert_no_difference \"User.count\" do\n      post \"/auth/github/callback\"\n    end\n\n    assert_redirected_to profile_path(@user)\n  end\n\n  test \"assign redirect_to (github)\" do\n    connected_account = connected_accounts(:github_connected_account)\n\n    OmniAuth.config.before_callback_phase = lambda do |env|\n      env[\"omniauth.params\"] = {\"redirect_to\" => \"/events\"}\n    end\n\n    OmniAuth.config.mock_auth[:github] = OmniAuth::AuthHash.new(\n      provider: :github,\n      uid: connected_account.uid,\n      info: {email: @user.email}\n    )\n\n    post \"/auth/github/callback\"\n\n    assert_redirected_to events_path\n  end\n\n  test \"full oauth flow\" do\n    OmniAuth.config.mock_auth[:github] = @github_auth\n    state = \"connect_id:123456\"\n\n    # Start the auth request with the state\n    post \"/auth/github?state=#{state}\"\n    follow_redirect!  # goes to /auth/github/callback\n\n    assert_redirected_to profile_path(@user)\n  end\n\n  test \"finds existing user by email if already exists and creates a new connected account(github)\" do\n    user = users(:one)\n    OmniAuth.config.add_mock(:github, uid: \"12345\", info: {email: user.email, nickname: \"one\"})\n    assert user.connected_accounts.empty?\n    assert_difference \"ConnectedAccount.count\", 1 do\n      post \"/auth/github/callback\"\n    end\n    assert_equal ConnectedAccount.last.user, user\n    assert_equal ConnectedAccount.last.username, \"one\"\n    assert_redirected_to root_path\n  end\n\n  test \"creates a new session for the user\" do\n    OmniAuth.config.mock_auth[:developer] = @developer_auth\n    assert_difference \"Session.count\", 1 do\n      post \"/auth/developer/callback\"\n    end\n  end\n\n  test \"sets a session token cookie\" do\n    OmniAuth.config.mock_auth[:developer] = @developer_auth\n    post \"/auth/developer/callback\"\n    assert_not_nil cookies[\"session_token\"]\n  end\n\n  test \"redirects to root_path with a success notice\" do\n    OmniAuth.config.mock_auth[:developer] = @developer_auth\n    post \"/auth/developer/callback\"\n    assert_redirected_to root_path\n    assert_equal \"Signed in successfully\", flash[:notice]\n  end\nend\n"
  },
  {
    "path": "test/controllers/sessions_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass SessionsControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:lazaro_nixon)\n  end\n\n  test \"should get new in a remote modal\" do\n    get new_session_url, headers: {\"Turbo-Frame\" => \"modal\"}\n    assert_response :success\n    assert_template \"sessions/new\"\n  end\n\n  test \"should redirect to root when not in a remote modal\" do\n    get new_session_url\n    assert_response :redirect\n    assert_redirected_to root_url\n  end\n\n  test \"should sign in\" do\n    post sessions_url, params: {email: @user.email, password: \"Secret1*3*5*\"}\n    assert_redirected_to root_url\n\n    get root_url\n    assert_response :success\n  end\n\n  test \"should not sign in with wrong credentials\" do\n    post sessions_url, params: {email: @user.email, password: \"SecretWrong1*3\"}\n    assert_redirected_to new_session_url(email_hint: @user.email)\n    assert_equal \"That email or password is incorrect\", flash[:alert]\n\n    get admin_suggestions_url\n    assert_redirected_to new_session_url\n  end\n\n  test \"should sign out\" do\n    sign_in_as @user\n\n    delete session_url(@user.sessions.last)\n    assert_redirected_to root_url\n  end\nend\n"
  },
  {
    "path": "test/controllers/speakers_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass SpeakersControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @speaker = users(:zero_talks)\n    @speaker_with_talk = users(:marco)\n  end\n\n  test \"should get index\" do\n    get speakers_url\n    assert_response :success\n\n    assert_select \"##{dom_id(@speaker)}\", 0\n    assert_select \"##{dom_id(@speaker_with_talk)}\", 1\n  end\n\n  test \"should get index with search results\" do\n    get speakers_url(s: \"John\")\n    assert_response :success\n    assert_select \"h1\", /Speakers/i\n    assert_select \"h1\", /search results for \"John\"/i\n  end\n\n  test \"should show speaker\" do\n    get speaker_url(@speaker)\n    assert_response :moved_permanently\n  end\n\n  test \"should get index as JSON\" do\n    speaker = users(:one)\n    canonical = users(:marco)\n    speaker.assign_canonical_speaker!(canonical_speaker: canonical)\n    speaker.reload\n    assert_equal speaker.canonical, canonical\n    assert_equal speaker.canonical_slug, canonical.slug\n\n    get speakers_url(canonical: false, with_talks: false), as: :json\n    assert_response :success\n\n    json_response = JSON.parse(response.body)\n    speaker_names = json_response[\"speakers\"].map { |speaker_data| speaker_data[\"name\"] }\n\n    assert_includes speaker_names, @speaker_with_talk.name\n  end\n\n  test \"should get index as JSON with all canonical speakers including speakers without talks\" do\n    get speakers_url(with_talks: false), as: :json\n    assert_response :success\n\n    json_response = JSON.parse(response.body)\n    speaker_names = json_response[\"speakers\"].map { |speaker_data| speaker_data[\"name\"] }\n\n    assert_equal speaker_names.count, User.speakers.count\n  end\nend\n"
  },
  {
    "path": "test/controllers/sponsors/missing_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Sponsors::MissingControllerTest < ActionDispatch::IntegrationTest\n  test \"should get index\" do\n    get sponsors_missing_index_url\n    assert_response :success\n  end\nend\n"
  },
  {
    "path": "test/controllers/spotlight/events_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Spotlight::EventsControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @series = event_series(:railsconf)\n    @event = events(:railsconf_2017)\n  end\n\n  test \"should get index with turbo stream format\" do\n    get spotlight_events_url(format: :turbo_stream)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should get index with search query\" do\n    get spotlight_events_url(format: :turbo_stream, s: @event.name)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n    assert_equal @event.id, assigns(:events).first.id\n  end\n\n  test \"should limit events results\" do\n    20.times { |i| Event.create!(name: \"Event #{i}\", series: @series, end_date: 1.month.ago) }\n\n    get spotlight_events_url(format: :turbo_stream)\n    assert_response :success\n    assert_equal 15, assigns(:events).size\n  end\n\n  test \"should not track analytics\" do\n    assert_no_difference \"Ahoy::Event.count\" do\n      with_event_tracking do\n        get spotlight_events_url(format: :turbo_stream)\n        assert_response :success\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/controllers/spotlight/languages_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Spotlight::LanguagesControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    Search::Backend::SQLiteFTS.reset_cache!\n  end\n\n  test \"returns empty results when no query provided\" do\n    get spotlight_languages_path(format: :turbo_stream)\n\n    assert_response :success\n    assert_match \"languages_search_results\", response.body\n    assert_match \"hidden\", response.body\n  end\n\n  test \"returns matching languages when query matches language name\" do\n    talk = talks(:one)\n    talk.update!(language: \"ja\")\n    Search::Backend::SQLiteFTS.reset_cache!\n\n    get spotlight_languages_path(format: :turbo_stream, s: \"japan\")\n\n    assert_response :success\n    assert_match \"languages_search_results\", response.body\n    assert_match \"Japanese\", response.body\n  end\n\n  test \"returns matching languages when query matches language code\" do\n    talk = talks(:one)\n    talk.update!(language: \"ja\")\n    Search::Backend::SQLiteFTS.reset_cache!\n\n    get spotlight_languages_path(format: :turbo_stream, s: \"ja\")\n\n    assert_response :success\n    assert_match \"languages_search_results\", response.body\n    assert_match \"Japanese\", response.body\n  end\n\n  test \"does not include English in results\" do\n    get spotlight_languages_path(format: :turbo_stream, s: \"english\")\n\n    assert_response :success\n    refute_match \"English\", response.body\n  end\n\n  test \"returns empty results for non-matching query\" do\n    get spotlight_languages_path(format: :turbo_stream, s: \"zzzznotfound\")\n\n    assert_response :success\n    assert_match \"hidden\", response.body\n  end\nend\n"
  },
  {
    "path": "test/controllers/spotlight/locations_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Spotlight::LocationsControllerTest < ActionDispatch::IntegrationTest\n  test \"should get index with turbo stream format\" do\n    get spotlight_locations_url(format: :turbo_stream)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should get index with search query for country\" do\n    event = events(:rails_world_2023)\n    event.update(country_code: \"US\")\n\n    get spotlight_locations_url(format: :turbo_stream, s: \"united\")\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should get index with search query for city\" do\n    event = events(:rails_world_2023)\n    event.update(city: \"Amsterdam\", country_code: \"NL\")\n\n    get spotlight_locations_url(format: :turbo_stream, s: \"amsterdam\")\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should not track analytics\" do\n    assert_no_difference \"Ahoy::Event.count\" do\n      with_event_tracking do\n        get spotlight_locations_url(format: :turbo_stream)\n        assert_response :success\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/controllers/spotlight/organizations_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Spotlight::OrganizationsControllerTest < ActionDispatch::IntegrationTest\n  test \"should get index with turbo stream format\" do\n    get spotlight_organizations_url(format: :turbo_stream)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should get index with search query\" do\n    get spotlight_organizations_url(format: :turbo_stream, s: \"shopify\")\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should not track analytics\" do\n    assert_no_difference \"Ahoy::Event.count\" do\n      with_event_tracking do\n        get spotlight_organizations_url(format: :turbo_stream)\n        assert_response :success\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/controllers/spotlight/series_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Spotlight::SeriesControllerTest < ActionDispatch::IntegrationTest\n  test \"should get index with turbo stream format\" do\n    get spotlight_series_index_url(format: :turbo_stream)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should get index with search query\" do\n    get spotlight_series_index_url(format: :turbo_stream, s: \"rails\")\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should not track analytics\" do\n    assert_no_difference \"Ahoy::Event.count\" do\n      with_event_tracking do\n        get spotlight_series_index_url(format: :turbo_stream)\n        assert_response :success\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/controllers/spotlight/speakers_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Spotlight::SpeakersControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @speaker = users(:marco)\n  end\n\n  test \"should get index with turbo stream format\" do\n    get spotlight_speakers_url(format: :turbo_stream)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should get index with search query\" do\n    get spotlight_speakers_url(format: :turbo_stream, s: @speaker.name)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n    assert_equal @speaker.id, assigns(:speakers).first.id\n  end\n\n  test \"should limit speakers results\" do\n    16.times { |i| User.create!(name: \"Speaker #{i}\", talks_count: 1, email: \"speaker#{i}@rubyevents.org\", password: \"password\") }\n\n    get spotlight_speakers_url(format: :turbo_stream)\n    assert_response :success\n    assert_equal 15, assigns(:speakers).size\n  end\n\n  test \"should filter out unbalanced quotes\" do\n    get spotlight_speakers_url(format: :turbo_stream, s: 'marco\"')\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should filter out invalid quotes\" do\n    get spotlight_speakers_url(format: :turbo_stream, s: \"'\")\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should filter out invalid quotes with single quotes\" do\n    get spotlight_speakers_url(format: :turbo_stream, s: \"marco'\")\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should not track analytics\" do\n    assert_no_difference \"Ahoy::Event.count\" do\n      with_event_tracking do\n        get spotlight_speakers_url(format: :turbo_stream)\n        assert_response :success\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/controllers/spotlight/talks_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Spotlight::TalksControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @talk = talks(:one)\n    @event = events(:rails_world_2023)\n    @talk.update(event: @event)\n  end\n\n  test \"should get index with turbo stream format\" do\n    get spotlight_talks_url(format: :turbo_stream)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should get index with search query\" do\n    get spotlight_talks_url(format: :turbo_stream, s: @talk.title)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should filter out unbalanced quotes\" do\n    get spotlight_talks_url(format: :turbo_stream, s: 'Hotwire\"')\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should filter out invalid quotes\" do\n    get spotlight_talks_url(format: :turbo_stream, s: \"'\")\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should filter out invalid search characters\" do\n    get spotlight_talks_url(format: :turbo_stream, s: \"Hotwire\\nCookbook\")\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should limit talks results\" do\n    15.times do |i|\n      Talk.create!(\n        title: \"Talk #{i}\",\n        event: @event,\n        date: Time.current,\n        static_id: \"test-spotlight-talk-#{i}\"\n      )\n    end\n\n    get spotlight_talks_url(format: :turbo_stream)\n    assert_response :success\n    assert_equal 10, assigns(:talks).size\n  end\n\n  test \"should not track analytics\" do\n    assert_no_difference \"Ahoy::Event.count\" do\n      with_event_tracking do\n        get spotlight_talks_url(format: :turbo_stream)\n        assert_response :success\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/controllers/spotlight/topics_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Spotlight::TopicsControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @topic = Topic.approved.canonical.with_talks.first\n  end\n\n  test \"should get index with turbo stream format\" do\n    get spotlight_topics_url(format: :turbo_stream)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should get index with search query\" do\n    skip \"No approved topics with talks\" unless @topic\n    get spotlight_topics_url(format: :turbo_stream, s: @topic.name)\n    assert_response :success\n    assert_equal \"text/vnd.turbo-stream.html\", @response.media_type\n  end\n\n  test \"should limit topics results\" do\n    get spotlight_topics_url(format: :turbo_stream)\n    assert_response :success\n    assert assigns(:topics).size <= Spotlight::TopicsController::LIMIT\n  end\n\n  test \"should not track analytics\" do\n    assert_no_difference \"Ahoy::Event.count\" do\n      with_event_tracking do\n        get spotlight_topics_url(format: :turbo_stream)\n        assert_response :success\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/controllers/suggestions_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass SuggestionsControllerTest < ActionDispatch::IntegrationTest\n  # test \"the truth\" do\n  #   assert true\n  # end\nend\n"
  },
  {
    "path": "test/controllers/talks/recommendations_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Talks::RecommendationsControllerTest < ActionDispatch::IntegrationTest\n  def setup\n    @talk = talks(:one)\n  end\n\n  test \"should get index with a turbo stream request\" do\n    get talk_recommendations_url(@talk), headers: {\"Turbo-Frame\" => \"true\"}\n    assert_response :success\n    assert_equal assigns(:talk).id, @talk.id\n    assert_not_nil assigns(:talks)\n  end\n\n  test \"should return random talk if no talk is found\" do\n    get talk_recommendations_url(\"999999999\"), headers: {\"Turbo-Frame\" => \"true\"}\n    assert_response :success\n    assert_not_nil assigns(:talks)\n  end\n\n  test \"a none turbo stream request should redirect to the talk\" do\n    get talk_recommendations_url(@talk)\n    assert_redirected_to talk_url(@talk)\n  end\nend\n"
  },
  {
    "path": "test/controllers/talks/slides_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Talks::SlidesControllerTest < ActionDispatch::IntegrationTest\n  def setup\n    @talk = talks(:one)\n  end\n\n  test \"should get show\" do\n    get talk_slides_path(@talk), headers: {\"Turbo-Frame\" => \"true\"}\n    assert_response :ok\n    assert_template \"talks/slides/show\"\n  end\nend\n"
  },
  {
    "path": "test/controllers/talks/watched_talks_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass Talks::WatchedTalksControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:one)\n    @talk = talks(:one)\n    @watched_talk = watched_talks(:one)\n  end\n\n  test \"should update watched talk progress for authenticated user\" do\n    sign_in_as @user\n\n    initial_progress = @watched_talk.progress_seconds\n    new_progress = 150\n\n    patch talk_watched_talk_path(@talk), params: {\n      watched_talk: {progress_seconds: new_progress}\n    }, as: :turbo_stream\n\n    assert_response :no_content\n    assert_equal new_progress, @watched_talk.reload.progress_seconds\n    assert_not_equal initial_progress, @watched_talk.progress_seconds\n  end\nend\n"
  },
  {
    "path": "test/controllers/talks_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass TalksControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @talk = talks(:one)\n    @event = events(:rails_world_2023)\n    @talk.update(event: @event)\n  end\n\n  test \"should get index\" do\n    get talks_url\n    assert_response :success\n  end\n\n  test \"should get index with search results\" do\n    get talks_url(s: \"rails\")\n    assert_response :success\n    assert_select \"h1\", /Talks/i\n    assert_select \"h1\", /search results for \"rails\"/i\n  end\n\n  test \"should get index with topic\" do\n    get talks_url(topic: \"activerecord\")\n    assert_response :success\n    assert assigns(:talks).size.positive?\n    assert assigns(:talks).all? { |talk| talk.topics.map(&:slug).include?(\"activerecord\") }\n  end\n\n  test \"should get index with event\" do\n    get talks_url(event: \"rails-world-2023\")\n    assert_response :success\n    assert assigns(:talks).size.positive?\n    assert assigns(:talks).all? { |talk| talk.event.slug == \"rails-world-2023\" }\n  end\n\n  test \"should get index with speaker\" do\n    get talks_url(speaker: \"yaroslav-shmarov\")\n    assert_response :success\n    assert assigns(:talks).size.positive?\n    assert assigns(:talks).all? { |talk| talk.speakers.map(&:slug).include?(\"yaroslav-shmarov\") }\n  end\n\n  test \"should show talk\" do\n    get talk_url(@talk)\n    assert_select \"div\", /#{@talk.title}/\n    assert_select \"div\", /#{@talk.event.name}/\n    assert_select \"div\", /#{@talk.speakers.first.name}/\n    assert_response :success\n  end\n\n  test \"should redirect to talks for wrong slugs\" do\n    get talk_url(\"wrong-slug\")\n    assert_response :moved_permanently\n    assert_redirected_to talks_path\n  end\n\n  test \"should redirect to correct talk slug when accessed via alias\" do\n    @talk.aliases.create!(name: \"Old Title\", slug: \"old-talk-slug\")\n\n    get talk_url(\"old-talk-slug\")\n    assert_response :moved_permanently\n    assert_redirected_to talk_path(@talk)\n  end\n\n  test \"should get edit\" do\n    get edit_talk_url(@talk), headers: {\"Turbo-Frame\" => \"modal\"}\n    assert_response :success\n  end\n\n  test \"anonymous user can suggest a modification\" do\n    patch talk_url(@talk), params: {talk: {description: \"new description\", slug: \"new-slug\", title: \"new title\", date: \"2024-01-01\"}}\n    assert_redirected_to talk_url(@talk)\n    assert_equal \"Your suggestion was successfully created and will be reviewed soon.\", flash[:notice]\n    assert_equal 1, @talk.suggestions.pending.count\n    assert_not_equal \"new description\", @talk.reload.description\n    assert_not_equal \"new title\", @talk.title\n    assert_not_equal \"2024-01-01\", @talk.date.to_s\n  end\n\n  test \"admin user can update talk\" do\n    @user = users(:admin)\n    sign_in_as @user\n\n    patch talk_url(@talk), params: {talk: {summary: \"new summary\", description: \"new description\", slug: \"new-slug\", title: \"new title\", date: \"2024-01-01\"}}\n    assert_redirected_to talk_url(@talk)\n    assert_equal \"Modification approved!\", flash[:notice]\n    assert_equal 1, @talk.suggestions.approved.count\n    assert_equal \"new description\", @talk.reload.description\n    assert_equal \"new summary\", @talk.summary\n    assert_equal \"new title\", @talk.title\n    assert_equal \"2024-01-01\", @talk.date.to_s\n\n    # some attributes cannot be changed\n    assert_not_equal \"new-slug\", @talk.slug\n  end\n\n  test \"owner can update directly the talk\" do\n    user = @talk.users.first\n    sign_in_as user\n\n    patch talk_url(@talk), params: {talk: {summary: \"new summary\", description: \"new description\", slug: \"new-slug\", title: \"new title\", date: \"2024-01-01\"}}\n    assert_redirected_to talk_url(@talk)\n    assert_equal \"Modification approved!\", flash[:notice]\n    assert_equal 1, @talk.suggestions.approved.count\n    assert_equal \"new description\", @talk.reload.description\n    assert_equal \"new summary\", @talk.summary\n    assert_equal \"new title\", @talk.title\n    assert_equal \"2024-01-01\", @talk.date.to_s\n\n    # some attributes cannot be changed\n    assert_not_equal \"new-slug\", @talk.slug\n  end\n\n  test \"should show topics\" do\n    # to remove when we remove the poor man FF for the topics\n    @user = users(:admin)\n    sign_in_as @user\n\n    get talk_url(@talk)\n    assert_select \"a .badge\", count: 1, text: \"#activerecord\"\n    assert_select \"a .badge\", count: 0, text: \"#rejected\"\n  end\n\n  test \"should get index as JSON\" do\n    get talks_url(format: :json)\n    assert_response :success\n\n    json_response = JSON.parse(response.body)\n    talk = Talk.watchable.order(date: :desc).first\n\n    assert_equal talk.slug, json_response[\"talks\"].first[\"slug\"]\n  end\n\n  test \"should get index as JSON with a custom per_page\" do\n    assert Talk.watchable.count > 2\n    get talks_url(format: :json, limit: 2)\n    assert_response :success\n\n    json_response = JSON.parse(response.body)\n\n    assert_equal 2, json_response[\"talks\"].size\n  end\n\n  test \"should get show as JSON\" do\n    get talk_url(@talk, format: :json)\n    assert_response :success\n\n    json_response = JSON.parse(response.body)\n    assert_equal @talk.slug, json_response[\"talk\"][\"slug\"]\n  end\n\n  test \"should get index with created_after\" do\n    talk = Talk.create!(title: \"test\", description: \"test\", date: \"2023-01-01\", created_at: \"2023-01-01\", video_provider: \"youtube\", static_id: \"test-created-after-2023\")\n    talk_2 = Talk.create!(title: \"test 2\", description: \"test\", date: \"2025-01-01\", created_at: \"2025-01-01\", video_provider: \"youtube\", static_id: \"test-created-after-2025\")\n\n    get talks_url(created_after: \"2024-01-01\")\n    assert_response :success\n    assert assigns(:talks).size.positive?\n    refute assigns(:talks).ids.include?(talk.id)\n    assert assigns(:talks).ids.include?(talk_2.id)\n    assert assigns(:talks).all? { |talk| talk.created_at >= Date.parse(\"2024-01-01\") }\n  end\n\n  test \"should get index with invalid created_after\" do\n    get talks_url(created_after: \"wrong-date\")\n    assert_response :success\n    assert assigns(:talks).size.positive?\n  end\nend\n"
  },
  {
    "path": "test/controllers/topics_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass TopicsControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @topic1 = Topic.create(name: \"New Topic 1\", status: :approved)\n    @topic2 = Topic.create(name: \"New Topic 2\", status: :pending)\n\n    @talk = talks(:one)\n    @topic1.talks << @talk\n  end\n\n  test \"should get index\" do\n    get topics_url\n    assert_response :success\n    assert_select \"h1\", \"Topics\"\n    assert_select \"##{dom_id(@topic1)} > span\", \"1\"\n    assert_select \"##{dom_id(@topic2)}\", 0\n\n    @topic2.approved!\n    get topics_url\n    assert_response :success\n    assert_select \"##{dom_id(@topic2)}\", 0\n  end\n\n  test \"should get index with invalid page number\" do\n    get topics_url(page: \"'\")\n    assert_response :success\n    assert_select \"h1\", \"Topics\"\n    assert_select \"##{dom_id(@topic1)} > span\", \"1\"\n    assert_select \"##{dom_id(@topic2)}\", 0\n  end\n\n  test \"should get show\" do\n    get topic_url(@topic1)\n    assert_response :success\n    assert_select \"h1\", @topic1.name\n    assert_select \"#topic-talks > div\", 1\n    assert_select \"##{dom_id(@talk)} h2\", @talk.title\n\n    get topic_url(@topic2)\n    assert_response :success\n    assert_select \"h1\", @topic2.name\n    assert_select \"#topic-talks > div\", 0\n  end\nend\n"
  },
  {
    "path": "test/controllers/watch_list_talks_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass WatchListTalksControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:one)\n    @watch_list = watch_lists(:one)\n    @talk = talks(:one)\n    sign_in_as @user\n  end\n\n  test \"should add talk to watch_list\" do\n    assert_difference(\"WatchListTalk.count\") do\n      post watch_list_talks_url(@watch_list), params: {talk_id: @talk.id}\n    end\n\n    assert_redirected_to watch_list_url(@watch_list)\n    assert_includes @watch_list.talks, @talk\n  end\n\n  test \"should remove talk from watch_list\" do\n    WatchListTalk.create!(watch_list: @watch_list, talk: @talk)\n\n    assert_difference(\"WatchListTalk.count\", -1) do\n      delete watch_list_talk_url(@watch_list, @talk.id)\n    end\n\n    assert_redirected_to watch_list_url(@watch_list)\n    assert_not_includes @watch_list.talks, @talk\n  end\nend\n"
  },
  {
    "path": "test/controllers/watch_lists_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass WatchListsControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:one)\n    @watch_list = watch_lists(:one)\n    sign_in_as @user\n  end\n\n  test \"should get index\" do\n    get watch_lists_url\n    assert_response :success\n  end\n\n  test \"should get new\" do\n    get new_watch_list_url\n    assert_response :success\n  end\n\n  test \"should create watch_list\" do\n    assert_difference(\"WatchList.count\") do\n      post watch_lists_url, params: {watch_list: {name: \"New WatchList\", description: \"Description\"}}\n    end\n\n    assert_redirected_to watch_list_url(WatchList.last)\n  end\n\n  test \"should show watch_list\" do\n    get watch_list_url(@watch_list)\n    assert_response :success\n  end\n\n  test \"should get edit\" do\n    get edit_watch_list_url(@watch_list)\n    assert_response :success\n  end\n\n  test \"should update watch_list\" do\n    patch watch_list_url(@watch_list), params: {watch_list: {name: \"Updated WatchList\"}}\n    assert_redirected_to watch_list_url(@watch_list)\n    @watch_list.reload\n    assert_equal \"Updated WatchList\", @watch_list.name\n  end\n\n  test \"should destroy watch_list\" do\n    assert_difference(\"WatchList.count\", -1) do\n      delete watch_list_url(@watch_list)\n    end\n\n    assert_redirected_to watch_lists_url\n  end\nend\n"
  },
  {
    "path": "test/controllers/watched_talks_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass WatchedTalksControllerTest < ActionDispatch::IntegrationTest\n  setup do\n    @user = users(:one)\n    @user_two = users(:two)\n    @watched_talk = watched_talks(:one)\n    @other_watched_talk = watched_talks(:two)\n  end\n\n  test \"should show only current user's watched talks\" do\n    sign_in_as @user\n\n    get watched_talks_url\n    assert_response :success\n\n    watched_talks_by_date = assigns(:watched_talks_by_date)\n    talk_ids = watched_talks_by_date.values.flatten.map(&:talk_id)\n    user_watched_talk_ids = @user.watched_talks.watched.pluck(:talk_id)\n\n    assert_equal user_watched_talk_ids.sort, talk_ids.sort\n  end\n\n  test \"should destroy watched talk for current user\" do\n    sign_in_as @user\n\n    delete watched_talk_path(@watched_talk)\n\n    assert_redirected_to watched_talks_path\n\n    assert_not WatchedTalk.exists?(@watched_talk.id)\n  end\n\n  test \"should destroy watched talk with turbo stream\" do\n    sign_in_as @user\n\n    delete watched_talk_path(@watched_talk), headers: {\"Accept\" => \"text/vnd.turbo-stream.html\"}\n\n    assert_turbo_stream action: \"remove\", target: dom_id(@watched_talk.talk, :card_horizontal)\n\n    assert_not WatchedTalk.exists?(@watched_talk.id)\n  end\nend\n"
  },
  {
    "path": "test/controllers/wrapped_controller_test.rb",
    "content": "require \"test_helper\"\n\nclass WrappedControllerTest < ActionDispatch::IntegrationTest\n  test \"index shows wrapped landing page\" do\n    get wrapped_path\n\n    assert_response :success\n    assert_select \"h1\", \"2025\"\n  end\n\n  test \"index shows sign in link when not logged in\" do\n    get wrapped_path\n\n    assert_response :success\n    assert_select \"a\", text: /Sign in to see your Wrapped/\n  end\n\n  test \"index shows view your wrapped link when logged in\" do\n    user = users(:one)\n    sign_in_as(user)\n\n    get wrapped_path\n\n    assert_response :success\n    assert_select \"a[href=?]\", profile_wrapped_index_path(profile_slug: user.slug), text: /View Your 2025 Wrapped/\n  end\n\n  test \"index shows public user avatars\" do\n    user = users(:one)\n    user.update!(wrapped_public: true)\n\n    get wrapped_path\n\n    assert_response :success\n    assert_select \"a[href=?]\", profile_wrapped_index_path(profile_slug: user.slug)\n  end\nend\n"
  },
  {
    "path": "test/fixtures/cfps.yml",
    "content": "# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html\n\n# == Schema Information\n#\n# Table name: cfps\n# Database name: primary\n#\n#  id         :integer          not null, primary key\n#  close_date :date\n#  link       :string\n#  name       :string\n#  open_date  :date\n#  created_at :datetime         not null\n#  updated_at :datetime         not null\n#  event_id   :integer          not null, indexed\n#\n# Indexes\n#\n#  index_cfps_on_event_id  (event_id)\n#\n# Foreign Keys\n#\n#  event_id  (event_id => events.id)\n#\none:\n  link: https://www.futureconference.com/cfp\n  open_date: <%= 1.week.from_now %>\n  close_date: <%= 2.weeks.from_now %>\n  event: future_conference\n  name: Future Conference 2024 CFP\n"
  },
  {
    "path": "test/fixtures/cities.yml",
    "content": "# == Schema Information\n#\n# Table name: cities\n# Database name: primary\n#\n#  id               :integer          not null, primary key\n#  country_code     :string           not null, indexed => [name, state_code]\n#  featured         :boolean          default(FALSE), not null, indexed\n#  geocode_metadata :json             not null\n#  latitude         :decimal(10, 6)\n#  longitude        :decimal(10, 6)\n#  name             :string           not null, indexed => [country_code, state_code]\n#  slug             :string           not null, uniquely indexed\n#  state_code       :string           indexed => [name, country_code]\n#  created_at       :datetime         not null\n#  updated_at       :datetime         not null\n#\n# Indexes\n#\n#  index_cities_on_featured                              (featured)\n#  index_cities_on_name_and_country_code_and_state_code  (name,country_code,state_code)\n#  index_cities_on_slug                                  (slug) UNIQUE\n#\namsterdam:\n  name: \"Amsterdam\"\n  slug: \"amsterdam\"\n  country_code: \"NL\"\n  state_code: \"\"\n  latitude: 52.3676\n  longitude: 4.9041\n\nsan_francisco:\n  name: \"San Francisco\"\n  slug: \"san-francisco\"\n  country_code: \"US\"\n  state_code: \"CA\"\n  latitude: 37.7749\n  longitude: -122.4194\n"
  },
  {
    "path": "test/fixtures/connected_accounts.yml",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: connected_accounts\n# Database name: primary\n#\n#  id           :integer          not null, primary key\n#  access_token :string\n#  expires_at   :datetime\n#  provider     :string           uniquely indexed => [uid], uniquely indexed => [username]\n#  uid          :string           uniquely indexed => [provider]\n#  username     :string           uniquely indexed => [provider]\n#  created_at   :datetime         not null\n#  updated_at   :datetime         not null\n#  user_id      :integer          not null, indexed\n#\n# Indexes\n#\n#  index_connected_accounts_on_provider_and_uid       (provider,uid) UNIQUE\n#  index_connected_accounts_on_provider_and_username  (provider,username) UNIQUE\n#  index_connected_accounts_on_user_id                (user_id)\n#\n# Foreign Keys\n#\n#  user_id  (user_id => users.id)\n#\n# rubocop:enable Layout/LineLength\n\ndeveloper_connected_account:\n  provider: developer\n  uid: \"123456\"\n  user: developer_oauth\n  access_token: \"123456\"\n\ngithub_connected_account:\n  provider: github\n  uid: \"789012\"\n  user: github_user\n  access_token: \"789012\"\n  username: \"github_user\"\n"
  },
  {
    "path": "test/fixtures/contributors.yml",
    "content": "# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html\n\n# == Schema Information\n#\n# Table name: contributors\n# Database name: primary\n#\n#  id         :integer          not null, primary key\n#  avatar_url :string\n#  html_url   :string\n#  login      :string           not null, uniquely indexed\n#  name       :string\n#  created_at :datetime         not null\n#  updated_at :datetime         not null\n#  user_id    :integer          indexed\n#\n# Indexes\n#\n#  index_contributors_on_login    (login) UNIQUE\n#  index_contributors_on_user_id  (user_id)\n#\n# Foreign Keys\n#\n#  user_id  (user_id => users.id)\n#\none:\n  login: user_one\n  name: MyString\n  avatar_url: MyString\n  html_url: MyString\n\ntwo:\n  login: user_two\n  name: MyString\n  avatar_url: MyString\n  html_url: MyString\n"
  },
  {
    "path": "test/fixtures/event_series.yml",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: event_series\n# Database name: primary\n#\n#  id                   :integer          not null, primary key\n#  description          :text             default(\"\"), not null\n#  frequency            :integer          default(\"unknown\"), not null, indexed\n#  kind                 :integer          default(\"conference\"), not null, indexed\n#  language             :string           default(\"\"), not null\n#  name                 :string           default(\"\"), not null, indexed\n#  slug                 :string           default(\"\"), not null, indexed\n#  twitter              :string           default(\"\"), not null\n#  website              :string           default(\"\"), not null\n#  youtube_channel_name :string           default(\"\")\n#  created_at           :datetime         not null\n#  updated_at           :datetime         not null\n#  youtube_channel_id   :string           default(\"\")\n#\n# Indexes\n#\n#  index_event_series_on_frequency  (frequency)\n#  index_event_series_on_kind       (kind)\n#  index_event_series_on_name       (name)\n#  index_event_series_on_slug       (slug)\n#\n# rubocop:enable Layout/LineLength\n\nrailsconf:\n  name: RailsConf\n  description: RailsConf organized by Ruby central\n  website: https://railsconf.org/\n  kind: 1\n  frequency: 1\n  youtube_channel_id: UCWnPjmqvljcafA0z2U1fwKQ\n  youtube_channel_name: confreaks\n  slug: railsconf\n\nrubyconfth:\n  name: RubyConfTH\n  description: Ruby Rails Thailand\n  website: https://rubyconfth.com/\n  kind: 1\n  frequency: 1\n  youtube_channel_id: UCWnPjmqvljcsqsdafA0z2U1fwKQ\n  youtube_channel_name: rubyconfth\n  slug: railsconfth\n\nrails_world:\n  name: RailsWorld\n  description: Rails World\n  website: https://rubyonrails.org/world\n  kind: 1\n  frequency: 1\n  youtube_channel_id: UC9zbLaqReIdoFfzdUbh13Nw\n  youtube_channel_name: railsofficial\n  slug: rails-world\n  twitter: rails\n\nbrightonruby:\n  name: Brighton Ruby\n  description: Brighton Ruby\n  website: https://brightonruby.com/\n  kind: 1\n  frequency: 1\n  slug: brightonruby\n\nwnb_rb:\n  name: WNB.rb\n  description: A virtual community for women & non-binary Rubyists.\n  website: https://www.wnb-rb.dev\n  kind: 2\n  frequency: 3\n  slug: wnb-rb\n\nnew_rb:\n  name: New\n  description: A test meetup series\n  kind: 2\n  frequency: 3\n  slug: new-rb\n"
  },
  {
    "path": "test/fixtures/events.yml",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: events\n# Database name: primary\n#\n#  id               :integer          not null, primary key\n#  city             :string\n#  country_code     :string           indexed => [state_code]\n#  date             :date\n#  date_precision   :string           default(\"day\"), not null\n#  end_date         :date\n#  geocode_metadata :json             not null\n#  kind             :string           default(\"event\"), not null, indexed\n#  latitude         :decimal(10, 6)\n#  location         :string\n#  longitude        :decimal(10, 6)\n#  name             :string           default(\"\"), not null, indexed\n#  slug             :string           default(\"\"), not null, indexed\n#  start_date       :date\n#  state_code       :string           indexed => [country_code]\n#  talks_count      :integer          default(0), not null\n#  website          :string           default(\"\")\n#  created_at       :datetime         not null\n#  updated_at       :datetime         not null\n#  canonical_id     :integer          indexed\n#  event_series_id  :integer          not null, indexed\n#\n# Indexes\n#\n#  index_events_on_canonical_id                 (canonical_id)\n#  index_events_on_country_code_and_state_code  (country_code,state_code)\n#  index_events_on_event_series_id              (event_series_id)\n#  index_events_on_kind                         (kind)\n#  index_events_on_name                         (name)\n#  index_events_on_slug                         (slug)\n#\n# Foreign Keys\n#\n#  canonical_id     (canonical_id => events.id)\n#  event_series_id  (event_series_id => event_series.id)\n#\n\nrailsconf_2017:\n  date: 2017-05-01\n  start_date: 2017-05-01\n  end_date: 2017-05-01\n  series: railsconf\n  city: Phoenix\n  country_code: US\n  state_code: AZ\n  kind: conference\n  name: RailsConf 2017\n  slug: railsconf-2017\n\nrubyconfth_2022:\n  date: 2022-05-01\n  start_date: 2022-05-01\n  end_date: 2022-05-01\n  series: rubyconfth\n  city: Bangkok\n  country_code: TH\n  kind: conference\n  name: RubyConf TH 2022\n  slug: rubyconfth-2022\n\nrails_world_2023:\n  date: 2023-10-26\n  start_date: 2023-10-26\n  end_date: 2023-10-26\n  series: rails_world\n  city: Amsterdam\n  country_code: NL\n  state_code: \"\"\n  name: Rails World 2023\n  kind: conference\n  slug: rails-world-2023\n\ntropical_rb_2024:\n  date: 2024-04-04\n  start_date: 2024-04-04\n  end_date: 2024-04-04\n  series: rails_world\n  city: São Paulo\n  country_code: BR\n  state_code: SP\n  name: Tropical Ruby 2024\n  kind: conference\n  slug: tropical-rb-2024\n\nbrightonruby_2024:\n  date: 2024-06-28\n  start_date: 2024-06-28\n  end_date: 2024-06-28\n  series: brightonruby\n  city: Brighton\n  country_code: GB\n  state_code: ENG\n  name: Brighton Ruby 2024\n  kind: conference\n  slug: brightonruby-2024\n\nfuture_conference:\n  date: <%= 3.weeks.from_now %>\n  series: rails_world\n  name: Future Conference\n  kind: conference\n  slug: future-conference\n\n# Event specifically for testing sponsors missing page - should NEVER have sponsors added\nno_sponsors_event:\n  date: 2025-03-15\n  start_date: 2025-03-15\n  end_date: 2025-03-15\n  series: brightonruby\n  city: Brighton\n  country_code: GB\n  state_code: ENG\n  kind: conference\n  name: Test Conference Without Sponsors\n  slug: no_sponsors_event\n\nwnb_rb_meetup:\n  series: wnb_rb\n  kind: meetup\n  name: WNB.rb Meetup\n  slug: wnb-rb-meetup\n\nnew_rb_meetup:\n  series: new_rb\n  kind: meetup\n  name: new Meetup\n  slug: new-rb-meetup\n"
  },
  {
    "path": "test/fixtures/favorite_users.yml",
    "content": "# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html\n\n# == Schema Information\n#\n# Table name: favorite_users\n# Database name: primary\n#\n#  id               :integer          not null, primary key\n#  notes            :text\n#  created_at       :datetime         not null\n#  updated_at       :datetime         not null\n#  favorite_user_id :integer          not null, indexed\n#  user_id          :integer          not null, indexed\n#\n# Indexes\n#\n#  index_favorite_users_on_favorite_user_id  (favorite_user_id)\n#  index_favorite_users_on_user_id           (user_id)\n#\n# Foreign Keys\n#\n#  favorite_user_id  (favorite_user_id => users.id)\n#  user_id           (user_id => users.id)\n#\none:\n  user: :one\n  favorite_user: :two\n\ntwo:\n  user: :two\n  favorite_user: :one\n"
  },
  {
    "path": "test/fixtures/files/.keep",
    "content": ""
  },
  {
    "path": "test/fixtures/organizations.yml",
    "content": "# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html\n\n# == Schema Information\n#\n# Table name: organizations\n# Database name: primary\n#\n#  id              :integer          not null, primary key\n#  description     :text\n#  domain          :string\n#  kind            :integer          default(\"unknown\"), not null, indexed\n#  logo_background :string           default(\"white\")\n#  logo_url        :string\n#  logo_urls       :json\n#  main_location   :string\n#  name            :string\n#  slug            :string           indexed\n#  website         :string\n#  created_at      :datetime         not null\n#  updated_at      :datetime         not null\n#\n# Indexes\n#\n#  index_organizations_on_kind  (kind)\n#  index_organizations_on_slug  (slug)\n#\n\none:\n  name: A Sponsor\n  website: https://sponsorone.com\n  description: A Sponsor is a sponsor\n  slug: sponsor-one\n  logo_url: https://sponsorone.com/logo.png\n  logo_background: white\n  domain: sponsorone.com\n  main_location: San Francisco, CA\n\ntwo:\n  name: B Sponsor\n  website: https://sponsortwo.com\n  description: B Sponsor is a sponsor\n  slug: sponsor-two\n  logo_url: https://sponsortwo.com/logo.png\n  logo_background: white\n  domain: sponsortwo.com\n  main_location: New York, NY\n\nthree:\n  name: C Sponsor\n  website: https://sponsorthree.com\n  description: C Sponsor is a sponsor\n  slug: sponsor-three\n  logo_url: https://sponsorthree.com/logo.png\n  logo_background: white\n  domain: sponsorthree.com\n  main_location: London, UK\n"
  },
  {
    "path": "test/fixtures/sponsors.yml",
    "content": "# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html\n\n# == Schema Information\n#\n# Table name: sponsors\n# Database name: primary\n#\n#  id              :integer          not null, primary key\n#  badge           :string\n#  level           :integer\n#  tier            :string           uniquely indexed => [event_id, organization_id]\n#  created_at      :datetime         not null\n#  updated_at      :datetime         not null\n#  event_id        :integer          not null, indexed, uniquely indexed => [organization_id, tier]\n#  organization_id :integer          not null, uniquely indexed => [event_id, tier], indexed\n#\n# Indexes\n#\n#  index_sponsors_on_event_id                        (event_id)\n#  index_sponsors_on_event_organization_tier_unique  (event_id,organization_id,tier) UNIQUE\n#  index_sponsors_on_organization_id                 (organization_id)\n#\n# Foreign Keys\n#\n#  event_id         (event_id => events.id)\n#  organization_id  (organization_id => organizations.id)\n#\n\none:\n  tier: \"gold\"\n  badge: \"Gold Sponsor\"\n  event: railsconf_2017\n  organization: one\n\ntwo:\n  tier: \"silver\"\n  badge: \"Silver Sponsor\"\n  event: railsconf_2017\n  organization: two\n\nthree:\n  tier: \"bronze\"\n  badge: \"Bronze Sponsor\"\n  event: railsconf_2017\n  organization: three\n"
  },
  {
    "path": "test/fixtures/suggestions.yml",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: suggestions\n# Database name: primary\n#\n#  id               :integer          not null, primary key\n#  content          :text\n#  status           :integer          default(\"pending\"), not null, indexed\n#  suggestable_type :string           not null, indexed => [suggestable_id]\n#  created_at       :datetime         not null\n#  updated_at       :datetime         not null\n#  approved_by_id   :integer          indexed\n#  suggestable_id   :integer          not null, indexed => [suggestable_type]\n#  suggested_by_id  :integer          indexed\n#\n# Indexes\n#\n#  index_suggestions_on_approved_by_id   (approved_by_id)\n#  index_suggestions_on_status           (status)\n#  index_suggestions_on_suggestable      (suggestable_type,suggestable_id)\n#  index_suggestions_on_suggested_by_id  (suggested_by_id)\n#\n# Foreign Keys\n#\n#  approved_by_id   (approved_by_id => users.id)\n#  suggested_by_id  (suggested_by_id => users.id)\n#\n# rubocop:enable Layout/LineLength\n\none:\n  content: MyText\n  suggestable: one\n  suggestable_type: Suggestable\n\ntwo:\n  content: MyText\n  suggestable: two\n  suggestable_type: Suggestable\n"
  },
  {
    "path": "test/fixtures/talk/transcripts.yml",
    "content": "# == Schema Information\n#\n# Table name: talk_transcripts\n# Database name: primary\n#\n#  id                  :integer          not null, primary key\n#  enhanced_transcript :text\n#  raw_transcript      :text\n#  created_at          :datetime         not null\n#  updated_at          :datetime         not null\n#  talk_id             :integer          not null, indexed\n#\n# Indexes\n#\n#  index_talk_transcripts_on_talk_id  (talk_id)\n#\n# Foreign Keys\n#\n#  talk_id  (talk_id => talks.id)\n#\none:\n  talk: one\n  raw_transcript: '[{\"start_time\": \"00:00:15.280\", \"end_time\": \"00:00:21.320\", \"text\": \"so nice to be here with you thank you all for coming so uh my name is uh\"}, {\"start_time\": \"00:00:21.320\", \"end_time\": \"00:00:27.800\", \"text\": \"yaroslav I m from Ukraine you might know me from my blog or from my super Al\"}, {\"start_time\": \"00:00:27.800\", \"end_time\": \"00:00:34.399\", \"text\": \"YouTube channel where I post a lot of stuff about trby and especially about hot fire so I originate from Ukraine\"}, {\"start_time\": \"00:00:34.399\", \"end_time\": \"00:00:40.239\", \"text\": \"from the north of Ukraine so right now it is liberated so that is Kev Chernobyl\"}, {\"start_time\": \"00:00:40.239\", \"end_time\": \"00:00:45.920\", \"text\": \"and chern so I used to live 80 kmers away from Chernobyl great\"}, {\"start_time\": \"00:00:45.920\", \"end_time\": \"00:00:52.680\", \"text\": \"place yeah and uh that is my family s home so it got boned in one of the first\"}, {\"start_time\": \"00:00:52.680\", \"end_time\": \"00:01:00.000\", \"text\": \"days of war that is my godfather he went to defend Ukraine and uh I mean we are\"}, {\"start_time\": \"00:01:00.000\", \"end_time\": \"00:01:05.799\", \"text\": \"he has such a beautiful venue but there is the war going on and like just today\"}, {\"start_time\": \"00:01:05.799\", \"end_time\": \"00:01:13.159\", \"text\": \"the city of har was randomly boned by the Russians and there are many Ruby\"}, {\"start_time\": \"00:01:13.159\", \"end_time\": \"00:01:19.520\", \"text\": \"rails people from Ukraine some of them are actually fighting this is verok he contributed to Ruby and he is actually\"}, {\"start_time\": \"00:01:19.520\", \"end_time\": \"00:01:27.960\", \"text\": \"defending Ukraine right now but on a positive note I just recently became a father\"}, {\"start_time\": \"00:01:27.960\", \"end_time\": \"00:01:35.000\", \"text\": \"so yeah um it is uh just 2 and a half months ago in uh France and uh today we\"}, {\"start_time\": \"00:01:35.000\", \"end_time\": \"00:01:35.000\", \"text\": \"are going to talk about hot fire\"}]'\n"
  },
  {
    "path": "test/fixtures/talk_topics.yml",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: talk_topics\n# Database name: primary\n#\n#  id         :integer          not null, primary key\n#  created_at :datetime         not null\n#  updated_at :datetime         not null\n#  talk_id    :integer          not null, indexed, uniquely indexed => [topic_id]\n#  topic_id   :integer          not null, indexed, uniquely indexed => [talk_id]\n#\n# Indexes\n#\n#  index_talk_topics_on_talk_id               (talk_id)\n#  index_talk_topics_on_topic_id              (topic_id)\n#  index_talk_topics_on_topic_id_and_talk_id  (topic_id,talk_id) UNIQUE\n#\n# Foreign Keys\n#\n#  talk_id   (talk_id => talks.id)\n#  topic_id  (topic_id => topics.id)\n#\n# rubocop:enable Layout/LineLength\n\none:\n  talk: one\n  topic: one\n\none_activerecord:\n  talk: one\n  topic: activerecord\n\none_rejected:\n  talk: one\n  topic: rejected\n\ntwo:\n  talk: two\n  topic: activesupport\n"
  },
  {
    "path": "test/fixtures/talks.yml",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: talks\n# Database name: primary\n#\n#  id                            :integer          not null, primary key\n#  additional_resources          :json             not null\n#  announced_at                  :datetime\n#  date                          :date             indexed, indexed => [video_provider]\n#  description                   :text             default(\"\"), not null\n#  duration_in_seconds           :integer\n#  end_seconds                   :integer\n#  external_player               :boolean          default(FALSE), not null\n#  external_player_url           :string           default(\"\"), not null\n#  kind                          :string           default(\"talk\"), not null, indexed\n#  language                      :string           default(\"en\"), not null\n#  like_count                    :integer          default(0)\n#  meta_talk                     :boolean          default(FALSE), not null\n#  original_title                :string           default(\"\"), not null\n#  published_at                  :datetime\n#  slides_url                    :string\n#  slug                          :string           default(\"\"), not null, indexed\n#  start_seconds                 :integer\n#  summarized_using_ai           :boolean          default(TRUE), not null\n#  summary                       :text             default(\"\"), not null\n#  thumbnail_lg                  :string           default(\"\"), not null\n#  thumbnail_md                  :string           default(\"\"), not null\n#  thumbnail_sm                  :string           default(\"\"), not null\n#  thumbnail_xl                  :string           default(\"\"), not null\n#  thumbnail_xs                  :string           default(\"\"), not null\n#  title                         :string           default(\"\"), not null, indexed\n#  video_availability_checked_at :datetime\n#  video_provider                :string           default(\"youtube\"), not null, indexed => [date]\n#  video_unavailable_at          :datetime\n#  view_count                    :integer          default(0)\n#  youtube_thumbnail_checked_at  :datetime\n#  created_at                    :datetime         not null\n#  updated_at                    :datetime         not null, indexed\n#  event_id                      :integer          indexed\n#  parent_talk_id                :integer          indexed\n#  static_id                     :string           not null, uniquely indexed\n#  video_id                      :string           default(\"\"), not null\n#\n# Indexes\n#\n#  index_talks_on_date                     (date)\n#  index_talks_on_event_id                 (event_id)\n#  index_talks_on_kind                     (kind)\n#  index_talks_on_parent_talk_id           (parent_talk_id)\n#  index_talks_on_slug                     (slug)\n#  index_talks_on_static_id                (static_id) UNIQUE\n#  index_talks_on_title                    (title)\n#  index_talks_on_updated_at               (updated_at)\n#  index_talks_on_video_provider_and_date  (video_provider,date)\n#\n# Foreign Keys\n#\n#  event_id        (event_id => events.id)\n#  parent_talk_id  (parent_talk_id => talks.id)\n#\n# rubocop:enable Layout/LineLength\n\none:\n  title: \"Hotwire Cookbook: Common Uses, Essential Patterns & Best Practices\"\n  description: |\n    @SupeRails creator and Rails mentor Yaroslav Shmarov shares how some of the most common frontend problems can be solved with Hotwire.\n\n    He covers:\n    - Pagination, search and filtering, modals, live updates, dynamic forms, inline editing, drag & drop, live previews, lazy loading & more\n    - How to achieve more by combining tools (Frames + Streams, StimulusJS, RequestJS, Kredis & more)\n    - What are the limits of Hotwire?\n    - How to write readable and maintainable Hotwire code\n    - Bad practices\n  slug: yaroslav-shmarov-hotwire-cookbook-common-uses-essential-patterns-best-practices-rails-world\n  video_provider: youtube\n  video_id: F75k4Oc6g9Q\n  kind: \"talk\"\n  event: rails_world_2023\n  date: \"2023-10-05\"\n  static_id: yaroslav-shmarov-rails-world-2023\n\ntwo:\n  title: talk title 2\n  description: talk descritpion 2\n  slug: talk-title-2\n  kind: \"talk\"\n  date: \"2025-01-31\"\n  video_provider: youtube\n  static_id: talk-title-2\n\nthree:\n  title: talk title 3\n  description: talk descritpion 3\n  slug: talk-title-3\n  kind: \"talk\"\n  date: \"2025-01-31\"\n  video_provider: youtube\n  static_id: talk-title-3\n\nlightning_talk:\n  title: Lightning Talks\n  description: All of the lightning talks\n  slug: lightning-talks\n  kind: \"lightning_talk\"\n  video_provider: youtube\n  date: \"2024-08-15\"\n  static_id: lightning-talk-title\n\nbrightonruby_2024_one:\n  title: Getting to Two Million Users as a One Woman Dev Team\n  description: talk descritpion 2\n  slug: getting-to-two-million-users-as-a-one-woman-dev-team\n  kind: \"talk\"\n  video_provider: mp4\n  external_player: true\n  event: brightonruby_2024\n  date: \"2024-06-30\"\n  static_id: nadia-odunayo-brightonruby-2024-fixture\n\nnon_english_talk_one:\n  title: Non English Talk Title\n  original_title: Palestra não em inglês\n  description: Non English talk description\n  slug: non-english-talk-title\n  kind: \"talk\"\n  video_provider: mp4\n  external_player: true\n  date: \"2025-05-20\"\n  static_id: non-english-talk-title\n\nmeetup_past_talk:\n  title: talk title 3\n  description: talk descritpion 3\n  slug: talk-title-3\n  kind: \"talk\"\n  event: wnb_rb_meetup\n  date: <%= 1.day.ago %>\n  video_provider: youtube\n  static_id: talk-title-4\n\nmeetup_upcoming_talk:\n  title: talk title 5\n  description: talk descritpion 5\n  slug: talk-title-5\n  date: <%= 1.day.from_now %>\n  kind: \"talk\"\n  event: new_rb_meetup\n  static_id: talk-title-5\n\n"
  },
  {
    "path": "test/fixtures/topics.yml",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: topics\n# Database name: primary\n#\n#  id           :integer          not null, primary key\n#  description  :text\n#  name         :string           uniquely indexed\n#  published    :boolean          default(FALSE)\n#  slug         :string           default(\"\"), not null, indexed\n#  status       :string           default(\"pending\"), not null, indexed\n#  talks_count  :integer\n#  created_at   :datetime         not null\n#  updated_at   :datetime         not null\n#  canonical_id :integer          indexed\n#\n# Indexes\n#\n#  index_topics_on_canonical_id  (canonical_id)\n#  index_topics_on_name          (name) UNIQUE\n#  index_topics_on_slug          (slug)\n#  index_topics_on_status        (status)\n#\n# Foreign Keys\n#\n#  canonical_id  (canonical_id => topics.id)\n#\n# rubocop:enable Layout/LineLength\n\none:\n  name: Topic 1\n  slug: topic-1\n  status: approved\n\nactiverecord:\n  name: ActiveRecord\n  slug: activerecord\n  status: approved\n\nactivesupport:\n  name: ActiveSupport\n  slug: activesupport\n  status: approved\n\nrejected:\n  name: Rejected\n  slug: rejected\n  status: rejected\n"
  },
  {
    "path": "test/fixtures/user_talks.yml",
    "content": "# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html\n\n# == Schema Information\n#\n# Table name: user_talks\n# Database name: primary\n#\n#  id           :integer          not null, primary key\n#  discarded_at :datetime\n#  created_at   :datetime         not null\n#  updated_at   :datetime         not null\n#  talk_id      :integer          not null, indexed, uniquely indexed => [user_id]\n#  user_id      :integer          not null, indexed, uniquely indexed => [talk_id]\n#\n# Indexes\n#\n#  index_user_talks_on_talk_id              (talk_id)\n#  index_user_talks_on_user_id              (user_id)\n#  index_user_talks_on_user_id_and_talk_id  (user_id,talk_id) UNIQUE\n#\n# Foreign Keys\n#\n#  talk_id  (talk_id => talks.id)\n#  user_id  (user_id => users.id)\n#\none:\n  user: yaroslav\n  talk: one\n\ntwo:\n  user: two\n  talk: two\n\nmarco_talk_one:\n  user: marco\n  talk: two\n\nmarco_talk_two:\n  user: marco\n  talk: three\n\nyaroslav_lightning_talk:\n  user: yaroslav\n  talk: lightning_talk\n\nmarco_lightning_talk:\n  user: marco\n  talk: lightning_talk\n\nchael_lightning_talk:\n  user: chael\n  talk: lightning_talk\n\none_lightning_talk:\n  user: one\n  talk: lightning_talk\n\ntwo_lightning_talk:\n  user: two\n  talk: lightning_talk\n\nlazaro_nixon_lightning_talk:\n  user: lazaro_nixon\n  talk: lightning_talk\n"
  },
  {
    "path": "test/fixtures/users.yml",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: users\n# Database name: primary\n#\n#  id                   :integer          not null, primary key\n#  admin                :boolean          default(FALSE), not null\n#  bio                  :text             default(\"\"), not null\n#  bsky                 :string           default(\"\"), not null\n#  bsky_metadata        :json             not null\n#  city                 :string\n#  country_code         :string\n#  email                :string           indexed\n#  geocode_metadata     :json             not null\n#  github_handle        :string\n#  github_metadata      :json             not null\n#  latitude             :decimal(10, 6)\n#  linkedin             :string           default(\"\"), not null\n#  location             :string           default(\"\")\n#  longitude            :decimal(10, 6)\n#  marked_for_deletion  :boolean          default(FALSE), not null, indexed\n#  mastodon             :string           default(\"\"), not null\n#  name                 :string           indexed\n#  password_digest      :string\n#  pronouns             :string           default(\"\"), not null\n#  pronouns_type        :string           default(\"not_specified\"), not null\n#  settings             :json             not null\n#  slug                 :string           default(\"\"), not null, uniquely indexed\n#  speakerdeck          :string           default(\"\"), not null\n#  state_code           :string\n#  suspicion_cleared_at :datetime\n#  suspicion_marked_at  :datetime\n#  talks_count          :integer          default(0), not null\n#  twitter              :string           default(\"\"), not null\n#  verified             :boolean          default(FALSE), not null\n#  watched_talks_count  :integer          default(0), not null\n#  website              :string           default(\"\"), not null\n#  created_at           :datetime         not null\n#  updated_at           :datetime         not null\n#  canonical_id         :integer          indexed\n#\n# Indexes\n#\n#  index_users_on_canonical_id         (canonical_id)\n#  index_users_on_email                (email)\n#  index_users_on_lower_github_handle  (lower(github_handle)) UNIQUE WHERE github_handle IS NOT NULL AND github_handle != ''\n#  index_users_on_marked_for_deletion  (marked_for_deletion)\n#  index_users_on_name                 (name)\n#  index_users_on_slug                 (slug) UNIQUE WHERE slug IS NOT NULL AND slug != ''\n#\n# rubocop:enable Layout/LineLength\n\nzero_talks:\n  email: zero_talks_user@rubyevents.org\n  name: Zero Talks\n  twitter: zero_talks\n  github_handle: zero_talks\n  bio: \"Zero Talks\"\n  slug: zero_talks\n  password_digest: <%= BCrypt::Password.create(\"Secret1*3*5*\") %>\n\none:\n  email: one@rubyevents.org\n  name: One\n  twitter: one\n  github_handle: one\n  bio: \"One\"\n  website: https://one.com/\n  slug: one\n  password_digest: <%= BCrypt::Password.create(\"Secret1*3*5*\") %>\n\ntwo:\n  email: two@rubyevents.org\n  name: Two\n  twitter: two\n  github_handle: two\n  bio: \"Two\"\n  website: https://two.com/\n  slug: two\n  password_digest: <%= BCrypt::Password.create(\"Secret1*3*5*\") %>\n\nchael:\n  email: chaelcodes@rubyevents.org\n  password_digest: <%= BCrypt::Password.create(\"Secret1*3*5*\") %>\n  name: Rachael Wright-Munn\n  github_handle: chaelcodes\n  slug: rachael-wright-munn\n  talks_count: 5\n\nmarco:\n  email: marcoroth@rubyevents.org\n  password_digest: <%= BCrypt::Password.create(\"Secret1*3*5*\") %>\n  name: Marco Roth\n  twitter: marcoroth\n  github_handle: marcoroth\n  bio: \"Marco\"\n  website: https://marcoroth.dev\n  slug: marcoroth\n  talks_count: 42\n\nyaroslav:\n  email: yaroslav@rubyevents.org\n  password_digest: <%= BCrypt::Password.create(\"Secret1*3*5*\") %>\n  name: Yaroslav Shmarov\n  twitter: yarotheslav\n  github_handle: yshmarov\n  bio: \"Source code for My Ruby on Rails tutorials: @corsego\"\n  website: https://superails.com/\n  slug: yaroslav-shmarov\n\nlazaro_nixon:\n  name: Lazaro Nixon\n  slug: lazaro-nixon\n  email: lazaronixon@hotmail.com\n  password_digest: <%= BCrypt::Password.create(\"Secret1*3*5*\") %>\n\nadmin:\n  name: Admin\n  slug: admin\n  email: admin@rubyevents.org\n  password_digest: <%= BCrypt::Password.create(\"Secret1*3*5*\") %>\n  admin: true\n\ndeveloper_oauth:\n  name: Developer OAuth\n  slug: developer-oauth\n  email: developer@example.com\n  password_digest: <%= BCrypt::Password.create(\"password\") %>\n\ngithub_user:\n  name: Github User\n  slug: github-user\n  github_handle: GitHub_user\n  email: github_user@example.com\n  password_digest: <%= BCrypt::Password.create(\"password\") %>\n"
  },
  {
    "path": "test/fixtures/watch_lists.yml",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: watch_lists\n# Database name: primary\n#\n#  id          :integer          not null, primary key\n#  description :text\n#  name        :string           not null\n#  talks_count :integer          default(0)\n#  created_at  :datetime         not null\n#  updated_at  :datetime         not null\n#  user_id     :integer          not null, indexed\n#\n# Indexes\n#\n#  index_watch_lists_on_user_id  (user_id)\n#\n# rubocop:enable Layout/LineLength\none:\n  user: one\n  name: favorites\n"
  },
  {
    "path": "test/fixtures/watched_talks.yml",
    "content": "# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html\n\n# == Schema Information\n#\n# Table name: watched_talks\n# Database name: primary\n#\n#  id                 :integer          not null, primary key\n#  feedback           :json\n#  feedback_shared_at :datetime\n#  progress_seconds   :integer          default(0), not null\n#  watched            :boolean          default(FALSE), not null\n#  watched_at         :datetime         not null\n#  watched_on         :string\n#  created_at         :datetime         not null\n#  updated_at         :datetime         not null\n#  talk_id            :integer          not null, indexed, uniquely indexed => [user_id]\n#  user_id            :integer          not null, uniquely indexed => [talk_id], indexed\n#\n# Indexes\n#\n#  index_watched_talks_on_talk_id              (talk_id)\n#  index_watched_talks_on_talk_id_and_user_id  (talk_id,user_id) UNIQUE\n#  index_watched_talks_on_user_id              (user_id)\n#\n\none:\n  user: one\n  talk: one\n  progress_seconds: 0\n  watched_at: <%= Time.current %>\n  watched: true\n\ntwo:\n  user: two\n  talk: two\n  progress_seconds: 150\n  watched_at: <%= Time.current %>\n  watched: true\n"
  },
  {
    "path": "test/helpers/event_tracking_helper.rb",
    "content": "# frozen_string_literal: true\n\nmodule EventTrackingHelper\n  def with_event_tracking\n    Ahoy.track_bots = true\n    yield\n  ensure\n    Ahoy.track_bots = false\n  end\nend\n"
  },
  {
    "path": "test/helpers/icon_helper_test.rb",
    "content": "require \"test_helper\"\n\nclass IconHelperTest < ActionView::TestCase\n  setup do\n    IconHelper.clear_cache\n    @icon = \"icons/fontawesome/pen-solid.svg\"\n  end\n\n  test \"caches the SVG content\" do\n    first_result = cached_inline_svg(@icon)\n    second_result = cached_inline_svg(@icon)\n    assert_equal first_result, second_result\n  end\n\n  test \"adds class attribute\" do\n    result = cached_inline_svg(@icon, class: \"icon-class\")\n    assert_includes result, 'class=\"icon-class\"'\n  end\n\n  test \"adds data attributes\" do\n    result = cached_inline_svg(@icon, data: {test: \"value\"})\n    assert_includes result, 'data-test=\"value\"'\n  end\n\n  test \"adds aria attributes\" do\n    result = cached_inline_svg(@icon, aria: {label: \"Test Icon\"})\n    assert_includes result, 'aria-label=\"Test Icon\"'\n  end\n\n  test \"preserves existing viewBox attribute while adding new attributes\" do\n    result = cached_inline_svg(@icon, class: \"icon-class\")\n    assert_includes result, 'viewBox=\"0 0 512 512\"'\n    assert_includes result, 'class=\"icon-class\"'\n    assert_not_includes result, 'hidden=\"true\"'\n  end\n\n  test \"handles multiple attributes\" do\n    result = cached_inline_svg(@icon,\n      class: \"icon-class\",\n      data: {test: \"value\"},\n      aria: {label: \"Test Icon\"},\n      role: \"img\")\n\n    assert_includes result, 'class=\"icon-class\"'\n    assert_includes result, 'data-test=\"value\"'\n    assert_includes result, 'aria-label=\"Test Icon\"'\n    assert_includes result, 'role=\"img\"'\n  end\n\n  test \"escapes attribute values\" do\n    result = cached_inline_svg(@icon, data: {test: 'value\"with\"quotes'})\n    assert_includes result, 'data-test=\"value&quot;with&quot;quotes\"'\n  end\n\n  test \"raises helpful error with fontawesome search URL when icon not found\" do\n    error = assert_raises(ArgumentError) do\n      cached_inline_svg(\"icons/fontawesome/nonexistent-icon-solid.svg\")\n    end\n\n    assert_includes error.message, \"Icon not found. Download from\\n\"\n    assert_includes error.message, \"https://fontawesome.com/search?q=nonexistent-icon\"\n    assert_includes error.message, \"\\nand save to\\n\"\n    assert_includes error.message, \"app/assets/images/icons/fontawesome/nonexistent-icon-solid.svg\"\n    assert_includes error.message, \"Or run the following curl command (only works for free icons, not Pro):\\ncurl -f -o\"\n    assert_includes error.message, \"https://raw.githubusercontent.com/FortAwesome/Font-Awesome/7.x/svgs-full/solid/nonexistent-icon.svg\"\n  end\nend\n"
  },
  {
    "path": "test/integration/.keep",
    "content": ""
  },
  {
    "path": "test/jobs/geocode_record_job_test.rb",
    "content": "require \"test_helper\"\n\nclass GeocodeRecordJobTest < ActiveJob::TestCase\n  setup do\n    Geocoder::Lookup::Test.add_stub(\n      \"San Francisco, CA\", [\n        {\n          \"coordinates\" => [37.7749, -122.4194],\n          \"address\" => \"San Francisco, CA, USA\",\n          \"city\" => \"San Francisco\",\n          \"state\" => \"California\",\n          \"state_code\" => \"CA\",\n          \"postal_code\" => \"94102\",\n          \"country\" => \"United States\",\n          \"country_code\" => \"US\"\n        }\n      ]\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"San Francisco, California, United States\", [\n        {\n          \"coordinates\" => [37.7749, -122.4194],\n          \"city\" => \"San Francisco\",\n          \"state_code\" => \"CA\",\n          \"country_code\" => \"US\"\n        }\n      ]\n    )\n  end\n\n  teardown do\n    Geocoder::Lookup::Test.reset\n  end\n\n  test \"geocodes user with valid location\" do\n    user = User.create!(name: \"Test User\", location: \"San Francisco, CA\")\n\n    GeocodeRecordJob.perform_now(user)\n\n    user.reload\n    assert_equal \"San Francisco\", user.city\n    assert_equal \"CA\", user.state_code\n    assert_equal \"US\", user.country_code\n    assert_in_delta 37.7749, user.latitude.to_f, 0.01\n  end\n\n  test \"geocodes event with valid location\" do\n    series = event_series(:railsconf)\n    event = Event.create!(\n      name: \"Test Conf 2024\",\n      series: series,\n      location: \"San Francisco, CA\"\n    )\n\n    GeocodeRecordJob.perform_now(event)\n\n    event.reload\n    assert_equal \"San Francisco\", event.city\n    assert_equal \"CA\", event.state_code\n    assert_equal \"US\", event.country_code\n  end\n\n  test \"skips user without location\" do\n    user = User.create!(name: \"Test User\", location: nil)\n\n    GeocodeRecordJob.perform_now(user)\n\n    user.reload\n    assert_nil user.city\n    assert_nil user.latitude\n  end\n\n  test \"skips user with blank location\" do\n    user = User.create!(name: \"Test User\", location: \"\")\n\n    GeocodeRecordJob.perform_now(user)\n\n    user.reload\n    assert_nil user.city\n    assert_nil user.latitude\n  end\n\n  test \"skips event without location\" do\n    series = event_series(:railsconf)\n    event = Event.create!(\n      name: \"Test Conf 2024\",\n      series: series,\n      location: nil\n    )\n\n    GeocodeRecordJob.perform_now(event)\n\n    event.reload\n    assert_nil event.city\n    assert_nil event.latitude\n  end\n\n  test \"saves geocoded data to database\" do\n    user = User.create!(name: \"Test User\", location: \"San Francisco, CA\")\n\n    GeocodeRecordJob.perform_now(user)\n\n    fresh_user = User.find(user.id)\n    assert_equal \"San Francisco\", fresh_user.city\n    assert_in_delta 37.7749, fresh_user.latitude.to_f, 0.01\n  end\nend\n"
  },
  {
    "path": "test/jobs/recurring/rollup_job_test.rb",
    "content": "require \"test_helper\"\n\nclass Recurring::RollupJobTest < ActiveJob::TestCase\n  test \"creates a rollup for today\" do\n    visit_1 = Ahoy::Visit.create!(started_at: Time.current)\n    Ahoy::Event.create!(name: \"Some Page during visit_1\", visit: visit_1, time: Time.current)\n    Recurring::RollupJob.new.perform\n    assert_equal 1, Rollup.where(name: \"ahoy_visits\", interval: :day).count\n    assert_equal 1, Rollup.where(name: \"ahoy_visits\", interval: :month).count\n    assert_equal 1, Rollup.where(name: \"ahoy_events\", interval: :day).count\n    assert_equal 1, Rollup.where(name: \"ahoy_events\", interval: :month).count\n  end\nend\n"
  },
  {
    "path": "test/jobs/recurring/youtube_thumbnail_validation_job_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Recurring::YouTubeThumbnailValidationJobTest < ActiveJob::TestCase\n  setup do\n    @talk = talks(:one)\n    @talk.update_columns(video_provider: \"youtube\", video_id: \"dQw4w9WgXcQ\", youtube_thumbnail_checked_at: nil)\n\n    Talk.where.not(id: @talk.id).update_all(video_provider: \"vimeo\")\n  end\n\n  test \"skips non-YouTube talks\" do\n    @talk.update_column(:video_provider, \"vimeo\")\n\n    Recurring::YouTubeThumbnailValidationJob.perform_now\n\n    assert_nil @talk.reload.youtube_thumbnail_checked_at\n  end\n\n  test \"skips recently checked talks\" do\n    @talk.update_column(:youtube_thumbnail_checked_at, 1.month.ago)\n\n    Recurring::YouTubeThumbnailValidationJob.perform_now\n\n    # Should not update the timestamp since it was recently checked\n    assert @talk.reload.youtube_thumbnail_checked_at < 1.day.ago\n  end\n\n  test \"rechecks talks older than 3 months\" do\n    @talk.update_column(:youtube_thumbnail_checked_at, 4.months.ago)\n\n    stub_thumbnail_with_fixture(\"maxresdefault\", 10000, \"1920x1080.jpg\")\n\n    Recurring::YouTubeThumbnailValidationJob.perform_now\n\n    assert @talk.reload.youtube_thumbnail_checked_at > 1.minute.ago\n  end\n\n  test \"updates checked_at even when no valid thumbnail found\" do\n    stub_all_thumbnails_as_default\n\n    Recurring::YouTubeThumbnailValidationJob.perform_now\n\n    assert @talk.reload.youtube_thumbnail_checked_at.present?\n  end\n\n  test \"prefers 16:9 thumbnail over larger 4:3 thumbnail\" do\n    stub_thumbnail_as_default(\"maxresdefault\")\n    stub_thumbnail_as_default(\"sddefault\")\n    stub_thumbnail_as_default(\"hqdefault\")\n    stub_thumbnail_with_fixture(\"mqdefault\", 8000, \"320x180.jpg\")\n\n    Recurring::YouTubeThumbnailValidationJob.perform_now\n\n    assert_equal \"https://i.ytimg.com/vi/#{@talk.video_id}/mqdefault.jpg\", @talk.reload.thumbnail_xl\n  end\n\n  test \"falls back to 4:3 thumbnail when no 16:9 available\" do\n    stub_thumbnail_as_default(\"maxresdefault\")\n    stub_thumbnail_as_default(\"sddefault\")\n    stub_thumbnail_as_default(\"mqdefault\")\n    stub_thumbnail_with_fixture(\"hqdefault\", 13000, \"480x360.jpg\")\n    stub_thumbnail_as_default(\"default\")\n\n    Recurring::YouTubeThumbnailValidationJob.perform_now\n\n    assert_equal \"https://i.ytimg.com/vi/#{@talk.video_id}/hqdefault.jpg\", @talk.reload.thumbnail_xl\n  end\n\n  test \"selects largest 16:9 thumbnail available\" do\n    stub_thumbnail_with_fixture(\"maxresdefault\", 100000, \"1920x1080.jpg\")\n    stub_thumbnail_with_fixture(\"sddefault\", 50000, \"640x360.jpg\")\n    stub_thumbnail_with_fixture(\"hqdefault\", 13000, \"480x360.jpg\")\n    stub_thumbnail_with_fixture(\"mqdefault\", 8000, \"320x180.jpg\")\n\n    Recurring::YouTubeThumbnailValidationJob.perform_now\n\n    @talk.reload\n    assert_equal \"https://i.ytimg.com/vi/#{@talk.video_id}/maxresdefault.jpg\", @talk.thumbnail_xl\n    assert_equal \"https://i.ytimg.com/vi/#{@talk.video_id}/sddefault.jpg\", @talk.thumbnail_lg\n  end\n\n  test \"sets thumbnail_lg to best available starting from sddefault\" do\n    stub_thumbnail_with_fixture(\"maxresdefault\", 100000, \"1920x1080.jpg\")\n    stub_thumbnail_as_default(\"sddefault\")\n    stub_thumbnail_with_fixture(\"hqdefault\", 13000, \"480x360.jpg\")\n    stub_thumbnail_with_fixture(\"mqdefault\", 8000, \"320x180.jpg\")\n\n    Recurring::YouTubeThumbnailValidationJob.perform_now\n\n    @talk.reload\n\n    assert_equal \"https://i.ytimg.com/vi/#{@talk.video_id}/maxresdefault.jpg\", @talk.thumbnail_xl\n    assert_equal \"https://i.ytimg.com/vi/#{@talk.video_id}/mqdefault.jpg\", @talk.thumbnail_lg\n  end\n\n  private\n\n  def stub_all_thumbnails_as_default\n    YouTube::Thumbnail::SIZES.each do |size|\n      stub_thumbnail_as_default(size)\n    end\n  end\n\n  def stub_thumbnail_as_default(size)\n    url = \"https://i.ytimg.com/vi/#{@talk.video_id}/#{size}.jpg\"\n\n    stub_request(:head, url).to_return(\n      status: 200,\n      headers: {\"Content-Length\" => \"1000\"}\n    )\n  end\n\n  def stub_thumbnail_with_fixture(size, content_length, fixture_filename)\n    url = \"https://i.ytimg.com/vi/#{@talk.video_id}/#{size}.jpg\"\n\n    stub_request(:head, url).to_return(\n      status: 200,\n      headers: {\"Content-Length\" => content_length.to_s}\n    )\n\n    image_body = File.binread(Rails.root.join(\"test/fixtures/files/thumbnails/#{fixture_filename}\"))\n\n    stub_request(:get, url).to_return(\n      status: 200,\n      body: image_body,\n      headers: {\"Content-Type\" => \"image/jpeg\"}\n    )\n  end\nend\n"
  },
  {
    "path": "test/jobs/recurring/youtube_video_availability_job_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Recurring::YouTubeVideoAvailabilityJobTest < ActiveJob::TestCase\n  setup do\n    @talk = talks(:one)\n    @talk.update_columns(\n      video_provider: \"youtube\",\n      video_id: \"dQw4w9WgXcQ\",\n      video_availability_checked_at: nil,\n      video_unavailable_at: nil\n    )\n\n    # Make sure other talks don't interfere\n    Talk.where.not(id: @talk.id).update_all(video_provider: \"vimeo\")\n  end\n\n  test \"skips non-YouTube talks\" do\n    @talk.update_column(:video_provider, \"vimeo\")\n\n    Recurring::YouTubeVideoAvailabilityJob.perform_now\n\n    assert_nil @talk.reload.video_availability_checked_at\n  end\n\n  test \"skips recently checked talks\" do\n    @talk.update_column(:video_availability_checked_at, 1.week.ago)\n\n    Recurring::YouTubeVideoAvailabilityJob.perform_now\n\n    # Should not update the timestamp since it was recently checked\n    assert @talk.reload.video_availability_checked_at < 1.day.ago\n  end\n\n  test \"rechecks talks older than 1 month\" do\n    @talk.update_column(:video_availability_checked_at, 2.months.ago)\n\n    stub_video_available\n\n    Recurring::YouTubeVideoAvailabilityJob.perform_now\n\n    assert @talk.reload.video_availability_checked_at > 1.minute.ago\n  end\n\n  test \"marks video as available when API returns data\" do\n    @talk.update_column(:video_unavailable_at, 1.week.ago)\n\n    stub_video_available\n\n    Recurring::YouTubeVideoAvailabilityJob.perform_now\n\n    @talk.reload\n    assert_nil @talk.video_unavailable_at\n    assert @talk.video_availability_checked_at.present?\n  end\n\n  test \"marks video as unavailable when API returns no data\" do\n    stub_video_unavailable\n\n    Recurring::YouTubeVideoAvailabilityJob.perform_now\n\n    @talk.reload\n    assert @talk.video_unavailable_at.present?\n    assert @talk.video_availability_checked_at.present?\n  end\n\n  test \"preserves original unavailable_at timestamp on subsequent checks\" do\n    original_time = 1.week.ago\n    @talk.update_columns(video_unavailable_at: original_time, video_availability_checked_at: 2.months.ago)\n\n    stub_video_unavailable\n\n    Recurring::YouTubeVideoAvailabilityJob.perform_now\n\n    @talk.reload\n    assert_in_delta original_time, @talk.video_unavailable_at, 1.second\n  end\n\n  private\n\n  def stub_video_available\n    stub_request(:get, %r{youtube\\.googleapis\\.com/youtube/v3/videos})\n      .to_return(\n        status: 200,\n        body: {items: [{id: @talk.video_id, status: {privacyStatus: \"public\"}}]}.to_json,\n        headers: {\"Content-Type\" => \"application/json\"}\n      )\n  end\n\n  def stub_video_unavailable\n    stub_request(:get, %r{youtube\\.googleapis\\.com/youtube/v3/videos})\n      .to_return(\n        status: 200,\n        body: {items: []}.to_json,\n        headers: {\"Content-Type\" => \"application/json\"}\n      )\n  end\nend\n"
  },
  {
    "path": "test/jobs/recurring/youtube_video_statistics_job_test.rb",
    "content": "require \"test_helper\"\n\nclass Recurring::YouTubeVideoStatisticsJobTest < ActiveJob::TestCase\n  test \"should update view_count and like_count for youtube talks\" do\n    VCR.use_cassette(\"recurring_youtube_statistics_job\", match_requests_on: [:method]) do\n      talk = talks(:one)\n\n      assert_not talk.view_count.positive?\n      assert_not talk.like_count.positive?\n\n      Recurring::YouTubeVideoStatisticsJob.new.perform\n\n      assert talk.reload.view_count.positive?\n      assert talk.like_count.positive?\n    end\n  end\nend\n"
  },
  {
    "path": "test/lib/download_sponsors_test.rb",
    "content": "require \"test_helper\"\nrequire \"webrick\"\nrequire \"socket\"\n\nclass DownloadSponsorsTest < ActiveSupport::TestCase\n  def self.find_free_port\n    server = TCPServer.new(\"127.0.0.1\", 0)\n    port = server.addr[1]\n    server.close\n    port\n  end\n\n  def setup\n    @download_sponsors = DownloadSponsors.new\n\n    # Start a local test server\n    @port = self.class.find_free_port\n    @base_url = \"http://127.0.0.1:#{@port}\"\n\n    @server_thread = Thread.new do\n      @server = WEBrick::HTTPServer.new(Port: @port, Logger: WEBrick::Log.new(File::NULL), AccessLog: [])\n      @server.mount_proc \"/\" do |req, res|\n        handle_test_request(req, res)\n      end\n      @server.start\n    end\n\n    # Wait for server to start\n    sleep 0.1\n  end\n\n  def teardown\n    @server&.shutdown\n    @server_thread&.kill\n  end\n\n  private\n\n  def handle_test_request(req, res)\n    res.status = 200\n    res[\"Content-Type\"] = \"text/html\"\n    res.body = @current_html_content || \"<html><body></body></html>\"\n  end\n\n  test \"find_sponsor_page returns sponsor link when found\" do\n    @current_html_content = <<~HTML\n      <html>\n        <body>\n          <a href=\"/about\">About Us</a>\n          <a href=\"/sponsors\">Our Sponsors</a>\n          <a href=\"/contact\">Contact</a>\n        </body>\n      </html>\n    HTML\n\n    result = @download_sponsors.find_sponsor_page(@base_url)\n\n    assert_equal \"#{@base_url}/sponsors\", result\n  end\n\n  test \"find_sponsor_page returns nil when no sponsor link found\" do\n    @current_html_content = <<~HTML\n      <html>\n        <body>\n          <a href=\"/about\">About Us</a>\n          <a href=\"/contact\">Contact</a>\n          <a href=\"/team\">Our Team</a>\n        </body>\n      </html>\n    HTML\n\n    result = @download_sponsors.find_sponsor_page(@base_url)\n\n    assert_nil result\n  end\n\n  test \"find_sponsor_page finds link by href containing sponsor\" do\n    @current_html_content = <<~HTML\n      <html>\n        <body>\n          <a href=\"/about\">About Us</a>\n          <a href=\"/sponsorship-info\">Learn More</a>\n          <a href=\"/contact\">Contact</a>\n        </body>\n      </html>\n    HTML\n\n    result = @download_sponsors.find_sponsor_page(@base_url)\n\n    assert_equal \"#{@base_url}/sponsorship-info\", result\n  end\n\n  test \"find_sponsor_page finds link by text containing sponsor\" do\n    @current_html_content = <<~HTML\n      <html>\n        <body>\n          <a href=\"/about\">About Us</a>\n          <a href=\"/partners\">Become a Sponsor</a>\n          <a href=\"/contact\">Contact</a>\n        </body>\n      </html>\n    HTML\n\n    result = @download_sponsors.find_sponsor_page(@base_url)\n\n    assert_equal \"#{@base_url}/partners\", result\n  end\n\n  test \"find_sponsor_page ignores fragment links\" do\n    @current_html_content = <<~HTML\n      <html>\n        <body>\n          <a href=\"/about\">About Us</a>\n          <a href=\"#sponsors\">Sponsors</a>\n          <a href=\"/contact\">Contact</a>\n        </body>\n      </html>\n    HTML\n\n    result = @download_sponsors.find_sponsor_page(@base_url)\n\n    assert_nil result\n  end\n\n  test \"find_sponsor_page ignores links with images\" do\n    @current_html_content = <<~HTML\n      <html>\n        <body>\n          <a href=\"/about\">About Us</a>\n          <a href=\"/sponsors\">\n            <img src=\"sponsors-logo.png\" alt=\"Sponsors\">\n            Sponsors\n          </a>\n          <a href=\"/contact\">Contact</a>\n        </body>\n      </html>\n    HTML\n\n    result = @download_sponsors.find_sponsor_page(@base_url)\n\n    assert_nil result\n  end\n\n  test \"find_sponsor_page handles relative URLs correctly\" do\n    @current_html_content = <<~HTML\n      <html>\n        <body>\n          <a href=\"/about\">About Us</a>\n          <a href=\"sponsors.html\">Our Sponsors</a>\n          <a href=\"/contact\">Contact</a>\n        </body>\n      </html>\n    HTML\n\n    result = @download_sponsors.find_sponsor_page(\"#{@base_url}/conference\")\n\n    assert_equal \"#{@base_url}/sponsors.html\", result\n  end\nend\n"
  },
  {
    "path": "test/lib/generators/cfp_generator_test.rb",
    "content": "require \"test_helper\"\nrequire \"generators/cfp/cfp_generator\"\nrequire \"#{Rails.root}/app/schemas/cfp_schema\"\nrequire \"json_schemer\"\nrequire \"yaml\"\n\nclass CFPGeneratorTest < Rails::Generators::TestCase\n  tests CfpGenerator\n  destination Rails.root.join(\"tmp/generators/cfp\")\n\n  test \"generator runs without errors\" do\n    assert_nothing_raised do\n      run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2021\"]\n    end\n  end\n\n  test \"creates cfp.yml with valid yaml\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2022\"]\n\n    assert_file \"data/rubyconf/2022/cfp.yml\" do |content|\n      assert_match(/\\S/, content) # Verify file has content\n    end\n\n    cfp_file_path = File.join(destination_root, \"data/rubyconf/2022/cfp.yml\")\n    validate_cfp_file(cfp_file_path)\n\n    File.delete cfp_file_path\n  end\n\n  test \"update cfp.yml if called twice\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2023\"]\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2023\", \"--name\", \"Call for Proposals\", \"--link\", \"https://example.com/cfp\"]\n\n    assert_file \"data/rubyconf/2023/cfp.yml\" do |content|\n      assert_match(%r{https://example.com/cfp}, content)\n      assert_no_match(%r{https://TODO.example.com/cfp}, content)\n    end\n\n    cfp_file_path = File.join(destination_root, \"data/rubyconf/2023/cfp.yml\")\n    validate_cfp_file(cfp_file_path)\n\n    File.delete cfp_file_path\n  end\n\n  test \"append to cfp.yml if called with a different name\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2024\"]\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2024\", \"--name\", \"CFP TWO\"]\n\n    assert_file \"data/rubyconf/2024/cfp.yml\" do |content|\n      assert_match(/Call for Proposals/, content)\n      assert_match(/CFP TWO/, content)\n    end\n\n    cfp_file_path = File.join(destination_root, \"data/rubyconf/2024/cfp.yml\")\n    validate_cfp_file(cfp_file_path)\n\n    File.delete cfp_file_path\n  end\n\n  def validate_cfp_file(path)\n    data = YAML.load_file(path)\n\n    schema = JSON.parse(CFPSchema.new.to_json_schema[:schema].to_json)\n    schemer = JSONSchemer.schema(schema)\n\n    errors = []\n    Array(data).each_with_index do |item, index|\n      errs = schemer.validate(item).to_a\n      errors.append(errs) unless errs.empty?\n    end\n\n    assert_empty errors, \"CFP YAML does not conform to schema: #{errors.join(\", \")}\"\n  end\nend\n"
  },
  {
    "path": "test/lib/generators/event_generator_test.rb",
    "content": "require \"test_helper\"\nrequire \"generators/event/event_generator\"\nrequire \"#{Rails.root}/app/schemas/event_schema\"\nrequire \"json_schemer\"\nrequire \"yaml\"\n\nclass EventGeneratorTest < Rails::Generators::TestCase\n  tests EventGenerator\n  destination Rails.root.join(\"tmp/generators/event\")\n\n  test \"creates event.yml in correct directory\" do\n    assert_nothing_raised do\n      run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2024\", \"--name\", \"RubyConf 2024\"]\n    end\n\n    assert_file \"data/rubyconf/2024/event.yml\" do |content|\n      assert_match(/\\S/, content) # Verify file has content\n    end\n\n    File.delete(File.join(destination_root, \"data/rubyconf/2024/event.yml\"))\n  end\n\n  test \"creates venue.yml\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2025\", \"--name\", \"RubyConf 2025\", \"--venue-name\", \"RubyConf 2025 Venue\", \"--venue-address\", \"123 Main St, Test City\"]\n    assert_file \"data/rubyconf/2025/venue.yml\" do |content|\n      assert_match(/RubyConf 2025 Venue/, content)\n      assert_match(/123 Main St/, content)\n    end\n\n    File.delete(File.join(destination_root, \"data/rubyconf/2025/event.yml\"))\n    File.delete(File.join(destination_root, \"data/rubyconf/2025/venue.yml\"))\n  end\n\n  test \"event.yml passes schema validation\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2026\", \"--name\", \"RubyConf 2026\"]\n\n    event_file_path = File.join(destination_root, \"data/rubyconf/2026/event.yml\")\n    validate_event_schema event_file_path\n\n    File.delete event_file_path\n  end\n\n  test \"event with all flags passes schema validation\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2027\", \"--name\", \"RubyConf 2027\", \"--kind\", \"retreat\", \"--hybrid\", \"--last-edition\"]\n\n    event_file_path = File.join(destination_root, \"data/rubyconf/2027/event.yml\")\n    validate_event_schema event_file_path\n    File.delete event_file_path\n  end\n\n  test \"event with all flags off passes schema validation\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2028\", \"--name\", \"RubyConf 2028\", \"--no-hybrid\", \"--no-last-edition\"]\n\n    event_file_path = File.join(destination_root, \"data/rubyconf/2028/event.yml\")\n    validate_event_schema event_file_path\n\n    File.delete event_file_path\n  end\n\n  def validate_event_schema(file_path)\n    data = YAML.load_file(file_path)\n\n    schema = JSON.parse(EventSchema.new.to_json_schema[:schema].to_json)\n    schemer = JSONSchemer.schema(schema)\n\n    errors = schemer.validate(data).to_a\n    assert_empty errors, \"Event YAML does not conform to schema: #{errors.join(\", \")}\"\n  end\nend\n"
  },
  {
    "path": "test/lib/generators/schedule_generator_test.rb",
    "content": "require \"test_helper\"\nrequire \"generators/schedule/schedule_generator\"\n\nclass ScheduleGeneratorTest < Rails::Generators::TestCase\n  tests ScheduleGenerator\n  destination Rails.root.join(\"tmp/generators/schedule\")\n\n  test \"creates schedule.yml in correct directory\" do\n    assert_nothing_raised do\n      run_generator [\"--event-series\", \"rbqconf\", \"--event\", \"rbqconf-2026\"]\n    end\n\n    assert_file \"data/rbqconf/rbqconf-2026/schedule.yml\" do |content|\n      assert_match(/\\S/, content) # Verify file has content\n    end\n\n    schedule_file_path = File.join(destination_root, \"data/rbqconf/rbqconf-2026/schedule.yml\")\n    validate_schedule_schema schedule_file_path\n\n    File.delete schedule_file_path\n  end\n\n  def validate_schedule_schema(file_path)\n    require \"#{Rails.root}/app/schemas/schedule_schema\"\n    require \"json_schemer\"\n    require \"yaml\"\n\n    data = YAML.load_file(file_path)\n    schema = JSON.parse(ScheduleSchema.new.to_json_schema[:schema].to_json)\n    schemer = JSONSchemer.schema(schema)\n    errors = schemer.validate(data).to_a\n    assert_empty errors, \"Schedule YAML does not conform to schema: #{errors.join(\", \")}\"\n  end\nend\n"
  },
  {
    "path": "test/lib/generators/sponsors_generator_test.rb",
    "content": "require \"test_helper\"\nrequire \"generators/sponsors/sponsors_generator\"\nrequire \"#{Rails.root}/app/schemas/sponsors_schema\"\nrequire \"json_schemer\"\nrequire \"yaml\"\n\nclass SponsorsGeneratorTest < Rails::Generators::TestCase\n  tests SponsorsGenerator\n  destination Rails.root.join(\"tmp/generators/sponsors\")\n  setup :prepare_destination\n\n  test \"generator populates sponsors.yml with arguments\" do\n    assert_nothing_raised do\n      run_generator [\"typesense:platinum\", \"braze:platinum\", \"AppSignal:Gold\", \"--event_series\", \"tropicalrb\", \"--event\", \"tropical-on-rails-2026\"]\n    end\n\n    assert_file \"data/tropicalrb/tropical-on-rails-2026/sponsors.yml\" do |content|\n      assert_match(/platinum/, content, \"platinum Tier missing\")\n      assert_match(/Gold/, content, \"Gold Tier missing\")\n      assert_match(/typesense/, content, \"typesense sponsor missing\")\n      assert_match(/appsignal/, content, \"AppSignal sponsor missing\")\n    end\n\n    File.delete File.join(destination_root, \"data/tropicalrb/tropical-on-rails-2026/sponsors.yml\")\n  end\n\n  test \"sponsors.yml passes schema validation\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2024\"]\n\n    sponsor_file_path = File.join(destination_root, \"data/rubyconf/2024/sponsors.yml\")\n    data = YAML.load_file(sponsor_file_path)\n\n    schema = JSON.parse(SponsorsSchema.new.to_json_schema[:schema].to_json)\n    schemer = JSONSchemer.schema(schema)\n\n    errors = []\n    Array(data).each_with_index do |item, index|\n      errs = schemer.validate(item).to_a\n      errors.append(errs) unless errs.empty?\n    end\n\n    assert_empty errors, \"Sponsors YAML does not conform to schema: #{errors.join(\", \")}\"\n\n    File.delete sponsor_file_path\n  end\nend\n"
  },
  {
    "path": "test/lib/generators/talk_generator_test.rb",
    "content": "require \"test_helper\"\nrequire \"generators/talk/talk_generator\"\nrequire \"#{Rails.root}/app/schemas/video_schema\"\nrequire \"json_schemer\"\n\nclass TalkGeneratorTest < Rails::Generators::TestCase\n  tests TalkGenerator\n  destination Rails.root.join(\"tmp/generators/talk\")\n\n  test \"generator runs without errors\" do\n    assert_nothing_raised do\n      # This must be a real event - tests Static::Event lookup\n      run_generator [\"--event\", \"rubyconf-2024\"]\n    end\n\n    File.delete(File.join(destination_root, \"data/rubyconf/rubyconf-2024/videos.yml\"))\n  end\n\n  test \"creates videos.yml with valid yaml\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2025\"]\n\n    assert_file \"data/rubyconf/2025/videos.yml\" do |content|\n      assert_match(/\\S/, content)\n    end\n\n    videos_file_path = File.join(destination_root, \"data/rubyconf/2025/videos.yml\")\n    validate_talk_file(videos_file_path)\n\n    File.delete(videos_file_path)\n  end\n\n  test \"update videos.yml if called twice\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2026\", \"--title\", \"Keynote: Jane Doe\", \"--speakers\", \"Jane Doe\"]\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2026\", \"--title\", \"Keynote: Talks about Talks\", \"--speakers\", \"Jane Doe\"]\n\n    assert_file \"data/rubyconf/2026/videos.yml\" do |content|\n      assert_no_match(%r{title: \"Keynote: Jane Doe\"}, content)\n      assert_match(%r{title: \"Keynote: Talks about Talks\"}, content)\n    end\n\n    videos_file_path = File.join(destination_root, \"data/rubyconf/2026/videos.yml\")\n    validate_talk_file(videos_file_path)\n\n    File.delete(videos_file_path)\n  end\n\n  test \"append to videos.yml if called with a different details\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2027\", \"--title\", \"Keynote: Jane Doe\", \"--speakers\", \"Jane Doe\", \"--kind\", \"keynote\"]\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2027\", \"--title\", \"RubyEvents is great\", \"--speakers\", \"Rachael Wright-Munn\", \"Marco Roth\"]\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2027\", \"--title\", \"Future of Ruby Panel\", \"--kind\", \"panel\", \"--speakers\", \"Rachael Wright-Munn\", \"Marco Roth\", \"Jane Doe\", \"Another Speaker\"]\n\n    assert_file \"data/rubyconf/2027/videos.yml\" do |content|\n      assert_match(/Keynote: Jane Doe/, content)\n      assert_match(/id: \"jane-doe-keynote-2027\"/, content)\n      assert_match(/RubyEvents is great/, content)\n      assert_match(/- Jane Doe/, content)\n      assert_match(/- Rachael Wright-Munn/, content)\n      assert_match(/- Marco Roth/, content)\n      assert_match(/Future of Ruby Panel/, content)\n      assert_match(/id: \"future-of-ruby-panel-2027\"/, content)\n    end\n\n    videos_file_path = File.join(destination_root, \"data/rubyconf/2027/videos.yml\")\n    validate_talk_file(videos_file_path)\n\n    File.delete(videos_file_path)\n  end\n\n  test \"finds event series from static event if not provided\" do\n    run_generator [\"--event\", \"tropical-on-rails-2026\", \"--title\", \"Keynote: Marco Roth\", \"--speakers\", \"Marco Roth\"]\n\n    assert_file \"data/tropicalrb/tropical-on-rails-2026/videos.yml\" do |content|\n      assert_match(/\\S/, content)\n    end\n\n    File.delete(File.join(destination_root, \"data/tropicalrb/tropical-on-rails-2026/videos.yml\"))\n  end\n\n  test \"creates lightning talk entry when lightning_talks option is true\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2028\", \"--title\", \"Lightning Round\", \"--description\", \"Quick talks\", \"--language\", \"en\", \"--lightning-talks\"]\n\n    assert_file \"data/rubyconf/2028/videos.yml\" do |content|\n      assert_match(/kind: \"lightning_talk\"/, content)\n      assert_match(/title: \"Lightning Round\"/, content)\n      assert_match(/description: |-\\n\\sLightning talks\\./, content)\n      assert_match(/language: \"en\"/, content)\n      assert_match(/talks: \\[\\]/, content)\n    end\n\n    videos_file_path = File.join(destination_root, \"data/rubyconf/2028/videos.yml\")\n    validate_talk_file(videos_file_path)\n    File.delete(videos_file_path)\n  end\n\n  def validate_talk_file(path)\n    data = YAML.load_file(path)\n    schema = JSON.parse(VideoSchema.new.to_json_schema[:schema].to_json)\n    schemer = JSONSchemer.schema(schema)\n\n    errors = []\n    Array(data).each_with_index do |item, index|\n      errs = schemer.validate(item).to_a\n      errors.append(errs) unless errs.empty?\n    end\n\n    assert_empty errors, \"Videos YAML does not conform to schema: #{errors.join(\", \")}\"\n  end\nend\n"
  },
  {
    "path": "test/lib/generators/venue_generator_test.rb",
    "content": "require \"test_helper\"\nrequire \"generators/venue/venue_generator\"\nrequire \"#{Rails.root}/app/schemas/venue_schema\"\nrequire \"json_schemer\"\nrequire \"yaml\"\n\nclass VenueGeneratorTest < Rails::Generators::TestCase\n  tests VenueGenerator\n  destination Rails.root.join(\"tmp/generators/venue\")\n\n  test \"creates venue.yml in correct directory\" do\n    assert_nothing_raised do\n      run_generator [\"--event\", \"rubyconf-2001\"]\n    end\n\n    assert_file \"data/rubyconf/rubyconf-2001/venue.yml\" do |content|\n      assert_match(/\\S/, content) # Verify file has content\n    end\n\n    File.delete File.join(destination_root, \"data/rubyconf/rubyconf-2001/venue.yml\")\n  end\n\n  test \"venue.yml passes schema validation\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2002\"]\n\n    venue_file_path = File.join(destination_root, \"data/rubyconf/2002/venue.yml\")\n    validate_venue_schema venue_file_path\n\n    File.delete venue_file_path\n  end\n\n  test \"venue with all flags passes schema validation\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2003\", \"--hotel\", \"--nearby\", \"--locations\", \"--rooms\", \"--spaces\", \"--accessibility\"]\n\n    venue_file_path = File.join(destination_root, \"data/rubyconf/2003/venue.yml\")\n    validate_venue_schema venue_file_path\n\n    File.delete venue_file_path\n  end\n\n  test \"venue with all flags off passes schema validation\" do\n    run_generator [\"--event-series\", \"rubyconf\", \"--event\", \"2004\", \"--no-hotel\", \"--no-nearby\", \"--no-locations\", \"--no-rooms\", \"--no-spaces\", \"--no-accessibility\"]\n\n    venue_file_path = File.join(destination_root, \"data/rubyconf/2004/venue.yml\")\n    validate_venue_schema venue_file_path\n\n    File.delete venue_file_path\n  end\n\n  def validate_venue_schema(file_path)\n    data = YAML.load_file(file_path)\n\n    schema = JSON.parse(VenueSchema.new.to_json_schema[:schema].to_json)\n    schemer = JSONSchemer.schema(schema)\n\n    errors = schemer.validate(data).to_a\n    assert_empty errors, \"Venue YAML does not conform to schema: #{errors.join(\", \")}\"\n  end\nend\n"
  },
  {
    "path": "test/lib/schema_export_test.rb",
    "content": "require \"test_helper\"\nrequire \"json\"\n\nclass SchemaExportTest < ActiveSupport::TestCase\n  SCHEMA_DIR = Rails.root.join(\"app/schemas\")\n  JSON_DIR = Rails.root.join(\"lib/schemas\")\n\n  Dir.glob(SCHEMA_DIR.join(\"*_schema.rb\")).each do |schema_file|\n    base = File.basename(schema_file, \".rb\")\n    test \"#{base} generates matching JSON schema\" do\n      schema_class = base.camelize.constantize\n      generated = JSON.pretty_generate(schema_class.new.to_json_schema[:schema])\n      json_path = JSON_DIR.join(\"#{base}.json\")\n      assert File.exist?(json_path), \"Missing JSON schema for #{base}. Run `bin/rails schema:export` to generate it.\"\n      expected = File.read(json_path)\n      assert_equal expected, generated, \"Schema for #{base} is out of date. Run `bin/rails schema:export` to update it.\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/models/ahoy/visit_test.rb",
    "content": "require \"test_helper\"\n\nclass Ahoy::VisitTest < ActiveSupport::TestCase\n  test \"should respond to rollup methods\" do\n    assert_respond_to Ahoy::Visit, :rollup\n    assert_respond_to Ahoy::Visit, :rollup_default_column\n  end\n\n  test \"should set rollup default column\" do\n    Ahoy::Visit.rollup_default_column(:started_at)\n    assert_equal :started_at, Ahoy::Visit.rollup_column\n  end\n\n  test \"rollup method should perform aggregation\" do\n    @visit = Ahoy::Visit.create!(started_at: Time.now)\n    @visit_2 = Ahoy::Visit.create!(started_at: Time.now - 1.day)\n    @visit_3 = Ahoy::Visit.create!(started_at: Time.now - 2.days)\n    @visit_3_2 = Ahoy::Visit.create!(started_at: Time.now - 2.days)\n\n    result = Ahoy::Visit.rollup(:some_metric, interval: \"day\")\n    assert_nil result # Since rollup method returns nil\n    assert_equal 3, Rollup.count\n    assert_equal 3, Rollup.series(\"some_metric\", interval: \"day\").count\n    assert_equal [2, 1, 1], Rollup.series(\"some_metric\", interval: \"day\").values\n  end\n\n  test \"rollup method should perform aggregation with group\" do\n    @visit = Ahoy::Visit.create!(started_at: Time.now, browser: \"Chrome\")\n    @visit_2 = Ahoy::Visit.create!(started_at: Time.now - 1.day, browser: \"Firefox\")\n    @visit_3 = Ahoy::Visit.create!(started_at: Time.now - 2.days, browser: \"Safari\")\n    @visit_3_2 = Ahoy::Visit.create!(started_at: Time.now - 2.days, browser: \"Safari\")\n\n    result = Ahoy::Visit.group(:browser).rollup(:some_metric, interval: \"day\")\n    assert_nil result # Since rollup method returns nil\n    assert_equal 9, Rollup.count\n    assert_equal [2, 1, 1], Rollup.series(\"some_metric\", interval: \"day\").values\n    assert_equal [2, 0, 0], Rollup.with_dimensions(browser: \"Safari\").series(\"some_metric\", interval: \"day\").values\n    assert_equal [0, 1, 0], Rollup.with_dimensions(browser: \"Firefox\").series(\"some_metric\", interval: \"day\").values\n    assert_equal [2, 1, 0], Rollup.with_dimensions(browser: [\"Firefox\", \"Safari\"]).series(\"some_metric\", interval: \"day\").values\n  end\nend\n"
  },
  {
    "path": "test/models/alias_test.rb",
    "content": "require \"test_helper\"\n\nclass AliasTest < ActiveSupport::TestCase\n  test \"can create an alias for a user\" do\n    user = User.create!(name: \"Test User\", github_handle: \"test-user-alias\")\n    alias_record = user.aliases.create!(name: \"Alias Name\", slug: \"alias-name\")\n\n    assert_equal \"Alias Name\", alias_record.name\n    assert_equal \"alias-name\", alias_record.slug\n    assert_equal user, alias_record.aliasable\n  end\n\n  test \"requires name to be present\" do\n    user = User.create!(name: \"Test User\", github_handle: \"test-user-alias-2\")\n    alias_record = user.aliases.build(slug: \"test-slug\")\n\n    assert_not alias_record.valid?\n    assert_includes alias_record.errors[:name], \"can't be blank\"\n  end\n\n  test \"slug is optional\" do\n    user = User.create!(name: \"Test User\", github_handle: \"test-user-alias-3\")\n    alias_record = user.aliases.build(name: \"Test Name\", slug: nil)\n\n    assert alias_record.valid?\n  end\n\n  test \"slug must be globally unique across all aliasable types\" do\n    user1 = User.create!(name: \"User One\", github_handle: \"user-one-alias\")\n    user2 = User.create!(name: \"User Two\", github_handle: \"user-two-alias\")\n\n    user1.aliases.create!(name: \"Name One\", slug: \"shared-slug\")\n    alias2 = user2.aliases.build(name: \"Name Two\", slug: \"shared-slug\")\n\n    assert_not alias2.valid?\n    assert_includes alias2.errors[:slug], \"has already been taken\"\n  end\n\n  test \"same aliasable can have multiple aliases with the same slug\" do\n    user = User.create!(name: \"Test User\", github_handle: \"user-slug-reuse\")\n    user.aliases.create!(name: \"Name Variant One\", slug: \"same-slug\")\n    alias2 = user.aliases.build(name: \"Name Variant Two\", slug: \"same-slug\")\n\n    assert alias2.valid?\n    alias2.save!\n\n    assert_equal 2, user.aliases.where(slug: \"same-slug\").count\n  end\n\n  test \"name must be unique per aliasable_type\" do\n    user1 = User.create!(name: \"User One\", github_handle: \"test-user-alias-4\")\n    user2 = User.create!(name: \"User Two\", github_handle: \"test-user-alias-5\")\n\n    user1.aliases.create!(name: \"Duplicate Name\", slug: \"slug-one\")\n    alias2 = user2.aliases.build(name: \"Duplicate Name\", slug: \"slug-two\")\n\n    assert_not alias2.valid?\n    assert_includes alias2.errors[:name], \"has already been taken\"\n  end\n\n  test \"same name can be used for different aliasable types\" do\n    user = User.create!(name: \"User One\", github_handle: \"user-one-alias-2\")\n    user_alias = user.aliases.create!(name: \"Shared Name\", slug: \"slug-user-one\")\n\n    assert user_alias.valid?\n    assert_equal \"Shared Name\", user_alias.name\n  end\n\n  test \"slug must be unique even when different aliasable types have the same id\" do\n    user = User.create!(name: \"Test User\", github_handle: \"user-same-id-test\")\n    event_series = EventSeries.create!(name: \"Test Series\", slug: \"test-series-same-id\")\n\n    user.aliases.create!(name: \"User Alias\", slug: \"globally-unique-slug\")\n    series_alias = event_series.aliases.build(name: \"Series Alias\", slug: \"globally-unique-slug\")\n\n    assert_not series_alias.valid?\n    assert_includes series_alias.errors[:slug], \"has already been taken\"\n  end\n\n  test \"same aliasable cannot have duplicate names\" do\n    user = User.create!(name: \"Test User\", github_handle: \"user-duplicate-name\")\n    user.aliases.create!(name: \"Same Name\", slug: \"slug-one\")\n    alias2 = user.aliases.build(name: \"Same Name\", slug: \"slug-two\")\n\n    assert_not alias2.valid?\n    assert_includes alias2.errors[:name], \"has already been taken\"\n  end\n\n  test \"polymorphic association works with different types\" do\n    user = User.create!(name: \"Test User\", github_handle: \"test-user-alias-6\")\n    user_alias = user.aliases.create!(name: \"User Alias\", slug: \"user-alias-poly\")\n\n    assert_equal \"User\", user_alias.aliasable_type\n    assert_equal user.id, user_alias.aliasable_id\n    assert_equal user, user_alias.aliasable\n  end\nend\n"
  },
  {
    "path": "test/models/announcement_test.rb",
    "content": "require \"test_helper\"\n\nclass AnnouncementTest < ActiveSupport::TestCase\n  test \"all returns announcements from content directory\" do\n    announcements = Announcement.all\n    assert_kind_of Array, announcements\n  end\n\n  test \"published filters only published announcements\" do\n    announcements = Announcement.published\n    assert announcements.all?(&:published?)\n  end\n\n  test \"find_by_slug returns announcement with matching slug\" do\n    # Create a test announcement file\n    announcement = Announcement.all.first\n    skip \"No announcements in content directory\" if announcement.nil?\n\n    found = Announcement.find_by_slug(announcement.slug)\n    assert_equal announcement.slug, found.slug\n  end\n\n  test \"find_by_slug! raises error for missing slug\" do\n    assert_raises(ActiveRecord::RecordNotFound) do\n      Announcement.find_by_slug!(\"nonexistent-slug\")\n    end\n  end\n\n  test \"parses frontmatter correctly\" do\n    announcement = Announcement.all.first\n    skip \"No announcements in content directory\" if announcement.nil?\n\n    assert announcement.title.present?\n    assert announcement.slug.present?\n    assert announcement.date.present?\n  end\n\n  test \"to_param returns slug\" do\n    announcement = Announcement.all.first\n    skip \"No announcements in content directory\" if announcement.nil?\n\n    assert_equal announcement.slug, announcement.to_param\n  end\nend\n\nclass AnnouncementCollectionTest < ActiveSupport::TestCase\n  def setup\n    @published_ruby = Announcement.new(\n      title: \"Ruby News\",\n      slug: \"ruby-news\",\n      date: Date.today,\n      published: true,\n      tags: [\"ruby\", \"news\"]\n    )\n    @published_rails = Announcement.new(\n      title: \"Rails Update\",\n      slug: \"rails-update\",\n      date: Date.today - 1,\n      published: true,\n      tags: [\"rails\", \"news\"]\n    )\n    @draft_ruby = Announcement.new(\n      title: \"Draft Ruby Post\",\n      slug: \"draft-ruby\",\n      date: Date.today,\n      published: false,\n      tags: [\"ruby\", \"draft\"]\n    )\n    @no_tags = Announcement.new(\n      title: \"No Tags Post\",\n      slug: \"no-tags\",\n      date: Date.today,\n      published: true,\n      tags: []\n    )\n\n    @collection = Announcement::Collection.new([@published_ruby, @published_rails, @draft_ruby, @no_tags])\n  end\n\n  test \"Collection is an Array subclass\" do\n    assert_kind_of Array, @collection\n  end\n\n  test \"published returns only published announcements\" do\n    result = @collection.published\n\n    assert_kind_of Announcement::Collection, result\n    assert_equal 3, result.size\n    assert result.all?(&:published?)\n    assert_includes result, @published_ruby\n    assert_includes result, @published_rails\n    assert_includes result, @no_tags\n    refute_includes result, @draft_ruby\n  end\n\n  test \"by_tag filters announcements by tag\" do\n    result = @collection.by_tag(\"ruby\")\n\n    assert_kind_of Announcement::Collection, result\n    assert_equal 2, result.size\n    assert_includes result, @published_ruby\n    assert_includes result, @draft_ruby\n  end\n\n  test \"by_tag is case insensitive\" do\n    result_lower = @collection.by_tag(\"ruby\")\n    result_upper = @collection.by_tag(\"RUBY\")\n    result_mixed = @collection.by_tag(\"Ruby\")\n\n    assert_equal result_lower.size, result_upper.size\n    assert_equal result_lower.size, result_mixed.size\n  end\n\n  test \"by_tag returns empty collection when no matches\" do\n    result = @collection.by_tag(\"nonexistent\")\n\n    assert_kind_of Announcement::Collection, result\n    assert_empty result\n  end\n\n  test \"all_tags returns unique sorted tags\" do\n    result = @collection.all_tags\n\n    assert_equal [\"draft\", \"news\", \"rails\", \"ruby\"], result\n  end\n\n  test \"all_tags returns empty array when no tags\" do\n    collection = Announcement::Collection.new([@no_tags])\n    result = collection.all_tags\n\n    assert_equal [], result\n  end\n\n  test \"scopes can be chained: published.by_tag\" do\n    result = @collection.published.by_tag(\"ruby\")\n\n    assert_kind_of Announcement::Collection, result\n    assert_equal 1, result.size\n    assert_includes result, @published_ruby\n    refute_includes result, @draft_ruby\n  end\n\n  test \"scopes can be chained: by_tag.published\" do\n    result = @collection.by_tag(\"ruby\").published\n\n    assert_kind_of Announcement::Collection, result\n    assert_equal 1, result.size\n    assert_includes result, @published_ruby\n  end\n\n  test \"scopes can be chained: published.by_tag.all_tags\" do\n    result = @collection.published.by_tag(\"news\").all_tags\n\n    assert_equal [\"news\", \"rails\", \"ruby\"], result\n  end\n\n  test \"chaining multiple by_tag narrows results\" do\n    result = @collection.by_tag(\"ruby\").by_tag(\"news\")\n\n    assert_equal 1, result.size\n    assert_includes result, @published_ruby\n  end\n\n  test \"find_by_slug returns announcement with matching slug\" do\n    result = @collection.find_by_slug(\"ruby-news\")\n\n    assert_equal @published_ruby, result\n  end\n\n  test \"find_by_slug returns nil when not found\" do\n    result = @collection.find_by_slug(\"nonexistent\")\n\n    assert_nil result\n  end\n\n  test \"find_by_slug! returns announcement with matching slug\" do\n    result = @collection.find_by_slug!(\"ruby-news\")\n\n    assert_equal @published_ruby, result\n  end\n\n  test \"find_by_slug! raises error when not found\" do\n    assert_raises(ActiveRecord::RecordNotFound) do\n      @collection.find_by_slug!(\"nonexistent\")\n    end\n  end\n\n  test \"published.find_by_slug finds published announcement\" do\n    result = @collection.published.find_by_slug(\"ruby-news\")\n\n    assert_equal @published_ruby, result\n  end\n\n  test \"published.find_by_slug returns nil for draft\" do\n    result = @collection.published.find_by_slug(\"draft-ruby\")\n\n    assert_nil result\n  end\n\n  test \"by_tag.find_by_slug! chains correctly\" do\n    result = @collection.by_tag(\"news\").find_by_slug!(\"rails-update\")\n\n    assert_equal @published_rails, result\n  end\nend\n"
  },
  {
    "path": "test/models/cfp_test.rb",
    "content": "require \"test_helper\"\n\nclass CFPTest < ActiveSupport::TestCase\n  # test \"the truth\" do\n  #   assert true\n  # end\nend\n"
  },
  {
    "path": "test/models/city_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass CityTest < ActiveSupport::TestCase\n  def create_city(name:, country_code:, state_code: nil, **attrs)\n    city = City.new(\n      name: name,\n      country_code: country_code,\n      state_code: state_code,\n      latitude: attrs[:latitude] || 45.5,\n      longitude: attrs[:longitude] || -122.6,\n      geocode_metadata: attrs[:geocode_metadata] || {\"geocoder_city\" => name},\n      featured: attrs.fetch(:featured, false)\n    )\n\n    city.define_singleton_method(:geocode) {}\n    city.save!\n\n    city\n  end\n\n  def build_city(name:, country_code:, state_code: nil, skip_geocode: true, **attrs)\n    city = City.new(\n      name: name,\n      country_code: country_code,\n      state_code: state_code,\n      latitude: attrs[:latitude] || 45.5,\n      longitude: attrs[:longitude] || -122.6,\n      geocode_metadata: attrs[:geocode_metadata] || {\"geocoder_city\" => name},\n      featured: attrs.fetch(:featured, false)\n    )\n\n    city.define_singleton_method(:geocode) {} if skip_geocode\n\n    city\n  end\n\n  test \"validates presence of name\" do\n    city = City.new(country_code: \"US\")\n    assert_not city.valid?\n    assert_includes city.errors[:name], \"can't be blank\"\n  end\n\n  test \"validates presence of country_code\" do\n    city = City.new(name: \"Portland\")\n    assert_not city.valid?\n    assert_includes city.errors[:country_code], \"can't be blank\"\n  end\n\n  test \"validates uniqueness of name scoped to country_code and state_code\" do\n    create_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n\n    duplicate = build_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n    assert_not duplicate.valid?\n    assert_includes duplicate.errors[:name], \"has already been taken\"\n  end\n\n  test \"allows same city name in different states\" do\n    create_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n\n    different_state = build_city(name: \"Portland\", country_code: \"US\", state_code: \"ME\")\n    assert different_state.valid?\n  end\n\n  test \"allows same city name in different countries\" do\n    create_city(name: \"London\", country_code: \"GB\", state_code: \"ENG\")\n\n    different_country = build_city(name: \"London\", country_code: \"CA\", state_code: \"ON\")\n    assert different_country.valid?\n  end\n\n  test \"rejects location when geocoder returns no city\" do\n    city = build_city(name: \"California\", country_code: \"US\", latitude: 36.0, longitude: -119.0,\n      geocode_metadata: {\"geocoder_city\" => nil})\n\n    assert_not city.valid?\n    assert city.errors[:name].any? { |e| e.include?(\"not a valid city\") }\n  end\n\n  test \"accepts location when geocoder returns a city\" do\n    city = build_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\", latitude: 45.5, longitude: -122.6,\n      geocode_metadata: {\"geocoder_city\" => \"Portland\"})\n\n    assert city.valid?\n    assert_empty city.errors[:name]\n  end\n\n  test \"clears state_code for countries without subdivisions\" do\n    city = City.new(name: \"Oranjestad\", country_code: \"AW\", state_code: \"XX\")\n    city.valid?\n\n    assert_nil city.state_code\n  end\n\n  test \"keeps state_code for supported countries\" do\n    city = City.new(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n    city.valid?\n\n    assert_equal \"OR\", city.state_code\n  end\n\n  test \"#country returns Country instance\" do\n    city = City.new(name: \"Portland\", country_code: \"US\")\n\n    assert_kind_of Country, city.country\n    assert_equal \"US\", city.country.alpha2\n  end\n\n  test \"#country returns nil for blank country_code\" do\n    city = City.new(name: \"Portland\", country_code: nil)\n\n    assert_nil city.country\n  end\n\n  test \"#state returns State for supported country\" do\n    city = City.new(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n\n    assert_kind_of State, city.state\n    assert_equal \"OR\", city.state.code\n  end\n\n  test \"#state returns nil for country without subdivisions\" do\n    city = City.new(name: \"Oranjestad\", country_code: \"AW\", state_code: \"XX\")\n\n    assert_nil city.state\n  end\n\n  test \"#state returns nil when state_code is blank\" do\n    city = City.new(name: \"Portland\", country_code: \"US\", state_code: nil)\n\n    assert_nil city.state\n  end\n\n  test \"#geocoded? returns true when lat/lng present\" do\n    city = City.new(latitude: 45.5, longitude: -122.6)\n\n    assert city.geocoded?\n  end\n\n  test \"#geocoded? returns false when lat/lng missing\" do\n    city = City.new(name: \"Portland\")\n\n    assert_not city.geocoded?\n  end\n\n  test \"#geocodeable? returns true when name and country_code present\" do\n    city = City.new(name: \"Portland\", country_code: \"US\")\n\n    assert city.geocodeable?\n  end\n\n  test \"#geocodeable? returns false when name missing\" do\n    city = City.new(country_code: \"US\")\n\n    assert_not city.geocodeable?\n  end\n\n  test \"#coordinates returns [lat, lng] when geocoded\" do\n    city = City.new(latitude: 45.5, longitude: -122.6)\n\n    assert_equal [45.5, -122.6], city.coordinates\n  end\n\n  test \"#coordinates returns nil when not geocoded\" do\n    city = City.new(name: \"Portland\")\n\n    assert_nil city.coordinates\n  end\n\n  test \"#location_string includes state for US cities\" do\n    city = City.new(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n\n    assert_equal \"Portland, OR\", city.location_string\n  end\n\n  test \"#location_string includes country for non-US cities\" do\n    city = City.new(name: \"London\", country_code: \"GB\")\n\n    assert_equal \"London, United Kingdom\", city.location_string\n  end\n\n  test \"#geocode_query includes city, state, and country\" do\n    city = City.new(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n\n    assert_equal \"Portland, Oregon, United States\", city.geocode_query\n  end\n\n  test \"#geocode_query excludes nil values\" do\n    city = City.new(name: \"Paris\", country_code: \"FR\")\n\n    assert_equal \"Paris, France\", city.geocode_query\n  end\n\n  test \"#bounds returns bounding box when geocoded\" do\n    city = City.new(latitude: 45.5, longitude: -122.6)\n    bounds = city.bounds\n\n    assert_equal({southwest: [-123.1, 45.0], northeast: [-122.1, 46.0]}, bounds)\n  end\n\n  test \"#bounds returns nil when not geocoded\" do\n    city = City.new(name: \"Portland\")\n\n    assert_nil city.bounds\n  end\n\n  test \"#continent returns Continent via country\" do\n    city = City.new(name: \"Portland\", country_code: \"US\")\n\n    assert_kind_of Continent, city.continent\n    assert_equal \"North America\", city.continent.name\n  end\n\n  test \"#feature! sets featured to true\" do\n    city = create_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\", featured: false)\n\n    city.feature!\n\n    assert city.featured?\n  end\n\n  test \"#unfeature! sets featured to false\" do\n    city = create_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\", featured: true)\n\n    city.unfeature!\n\n    assert_not city.featured?\n  end\n\n  test \".find_for finds city by name and country\" do\n    city = create_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n\n    found = City.find_for(city: \"Portland\", country_code: \"US\", state_code: \"OR\")\n\n    assert_equal city, found\n  end\n\n  test \".find_for returns nil when not found\" do\n    found = City.find_for(city: \"Nonexistent\", country_code: \"US\")\n\n    assert_nil found\n  end\n\n  test \".find_or_create_for returns existing city\" do\n    city = create_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n\n    found = City.find_or_create_for(city: \"Portland\", country_code: \"US\", state_code: \"OR\")\n\n    assert_equal city, found\n  end\n\n  test \".find_or_create_for creates new city when geocoded as locality\" do\n    result = City.find_or_create_for(city: \"Seattle\", country_code: \"US\", state_code: \"WA\")\n\n    assert result.nil? || result.is_a?(City)\n  end\n\n  test \".find_or_create_for returns nil for blank city\" do\n    result = City.find_or_create_for(city: \"\", country_code: \"US\")\n\n    assert_nil result\n  end\n\n  test \".find_or_create_for returns nil for non-city locations\" do\n    result = City.find_or_create_for(city: \"San Francisco Bay Area\", country_code: \"US\")\n\n    assert_nil result\n    assert_not City.exists?(name: \"San Francisco Bay Area\", country_code: \"US\")\n  end\n\n  test \".find_or_create_for returns nil for blank country_code\" do\n    result = City.find_or_create_for(city: \"Portland\", country_code: \"\")\n\n    assert_nil result\n  end\n\n  test \".featured returns only featured cities\" do\n    featured = create_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\", featured: true)\n    create_city(name: \"Seattle\", country_code: \"US\", state_code: \"WA\", featured: false)\n\n    assert_includes City.featured, featured\n    assert_equal 1, City.featured.count\n  end\n\n  test \".for_country returns cities in country\" do\n    us_city = create_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n    create_city(name: \"London\", country_code: \"GB\", state_code: \"ENG\")\n\n    assert_includes City.for_country(\"US\"), us_city\n    assert_equal 2, City.for_country(\"US\").count\n  end\n\n  test \".for_state returns cities in state\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n    or_city = create_city(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n    create_city(name: \"Seattle\", country_code: \"US\", state_code: \"WA\")\n\n    assert_includes City.for_state(state), or_city\n    assert_equal 1, City.for_state(state).count\n  end\n\n  test \"#to_location returns Location with city and state for US city\" do\n    city = City.new(name: \"Portland\", country_code: \"US\", state_code: \"OR\")\n    location = city.to_location\n\n    assert_kind_of Location, location\n    assert_equal \"Portland, OR, United States\", location.to_text\n  end\n\n  test \"#to_location returns Location with city and country for non-US city\" do\n    city = City.new(name: \"Paris\", country_code: \"FR\")\n    location = city.to_location\n\n    assert_equal \"Paris, France\", location.to_text\n  end\n\n  test \"#to_location returns Location with city and country for GB city\" do\n    city = City.new(name: \"London\", country_code: \"GB\", state_code: \"ENG\")\n    location = city.to_location\n\n    assert_equal \"London, England, United Kingdom\", location.to_text\n  end\n\n  test \"#sync_aliases_from_list creates aliases\" do\n    city = create_city(name: \"Zürich\", country_code: \"CH\", state_code: \"ZH\")\n\n    city.sync_aliases_from_list([\"zurich\", \"zrh\"])\n\n    city_aliases = Alias.where(aliasable_type: \"City\", aliasable_id: city.id)\n\n    assert_equal 2, city_aliases.count\n    assert city_aliases.exists?(name: \"zurich\")\n    assert city_aliases.exists?(name: \"zrh\")\n  end\n\n  test \"#sync_aliases_from_list does not create duplicate aliases\" do\n    city = create_city(name: \"Zürich\", country_code: \"CH\", state_code: \"ZH\")\n\n    city.sync_aliases_from_list([\"zurich\"])\n    city.sync_aliases_from_list([\"zurich\", \"zrh\"])\n\n    city_aliases = Alias.where(aliasable_type: \"City\", aliasable_id: city.id)\n\n    assert_equal 2, city_aliases.count\n  end\n\n  test \".find_by_alias finds city by alias name\" do\n    city = create_city(name: \"Zürich\", country_code: \"CH\", state_code: \"ZH\")\n    city.sync_aliases_from_list([\"zurich\", \"zrh\"])\n\n    found = City.find_by_alias(\"zurich\", country_code: \"CH\")\n\n    assert_equal city, found\n  end\n\n  test \".find_by_alias finds city by alias name case-insensitively\" do\n    city = create_city(name: \"Zürich\", country_code: \"CH\", state_code: \"ZH\")\n    city.sync_aliases_from_list([\"zurich\"])\n\n    found = City.find_by_alias(\"ZURICH\", country_code: \"CH\")\n\n    assert_equal city, found\n  end\n\n  test \".find_by_alias returns nil for wrong country\" do\n    city = create_city(name: \"Zürich\", country_code: \"CH\", state_code: \"ZH\")\n    city.sync_aliases_from_list([\"zurich\"])\n\n    found = City.find_by_alias(\"zurich\", country_code: \"DE\")\n\n    assert_nil found\n  end\n\n  test \".find_for finds city by alias\" do\n    city = create_city(name: \"Zürich\", country_code: \"CH\", state_code: \"ZH\")\n    city.sync_aliases_from_list([\"zurich\"])\n\n    found = City.find_for(city: \"zurich\", country_code: \"CH\")\n\n    assert_equal city, found\n  end\n\n  test \".find_or_create_for returns existing city when searching by alias\" do\n    city = create_city(name: \"Zürich\", country_code: \"CH\", state_code: \"ZH\")\n    city.sync_aliases_from_list([\"zurich\"])\n\n    found = City.find_or_create_for(city: \"Zurich\", country_code: \"CH\")\n\n    assert_equal city, found\n    assert_equal 1, City.where(country_code: \"CH\").count\n  end\nend\n"
  },
  {
    "path": "test/models/concerns/geocodeable_test.rb",
    "content": "require \"test_helper\"\n\nclass GeocodeableTest < ActiveSupport::TestCase\n  setup do\n    Geocoder::Lookup::Test.add_stub(\n      \"San Francisco, CA\", [\n        {\n          \"coordinates\" => [37.7749, -122.4194],\n          \"address\" => \"San Francisco, CA, USA\",\n          \"city\" => \"San Francisco\",\n          \"state\" => \"California\",\n          \"state_code\" => \"CA\",\n          \"postal_code\" => \"94102\",\n          \"country\" => \"United States\",\n          \"country_code\" => \"US\"\n        }\n      ]\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"Berlin, Germany\", [\n        {\n          \"coordinates\" => [52.52, 13.405],\n          \"address\" => \"Berlin, Germany\",\n          \"city\" => \"Berlin\",\n          \"state\" => \"Berlin\",\n          \"state_code\" => \"BE\",\n          \"postal_code\" => \"10115\",\n          \"country\" => \"Germany\",\n          \"country_code\" => \"DE\"\n        }\n      ]\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"Unknown Location XYZ123\", []\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"San Francisco, California, United States\", [\n        {\n          \"coordinates\" => [37.7749, -122.4194],\n          \"city\" => \"San Francisco\",\n          \"state_code\" => \"CA\",\n          \"country_code\" => \"US\"\n        }\n      ]\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"Berlin, Berlin, Germany\", [\n        {\n          \"coordinates\" => [52.52, 13.405],\n          \"city\" => \"Berlin\",\n          \"state_code\" => \"BE\",\n          \"country_code\" => \"DE\"\n        }\n      ]\n    )\n  end\n\n  teardown do\n    Geocoder::Lookup::Test.reset\n  end\n\n  test \"geocodeable? returns true when location is present\" do\n    user = User.new(name: \"Test\", location: \"San Francisco, CA\")\n    assert user.geocodeable?\n  end\n\n  test \"geocodeable? returns false when location is blank\" do\n    user = User.new(name: \"Test\", location: \"\")\n    assert_not user.geocodeable?\n  end\n\n  test \"geocodeable? returns false when location is nil\" do\n    user = User.new(name: \"Test\", location: nil)\n    assert_not user.geocodeable?\n  end\n\n  test \"clear_geocode clears all geocode data\" do\n    user = User.create!(\n      name: \"Test User\",\n      location: \"San Francisco, CA\",\n      latitude: 37.7749,\n      longitude: -122.4194,\n      city: \"San Francisco\",\n      state_code: \"CA\",\n      country_code: \"US\",\n      geocode_metadata: {\"foo\" => \"bar\"}\n    )\n\n    user.clear_geocode\n\n    assert_nil user.latitude\n    assert_nil user.longitude\n    assert_nil user.city\n    assert_nil user.state_code\n    assert_nil user.country_code\n    assert_equal({}, user.geocode_metadata)\n  end\n\n  test \"regeocode clears existing data and geocodes fresh\" do\n    user = User.create!(\n      name: \"Test User\",\n      location: \"Berlin, Germany\",\n      latitude: 37.7749,\n      longitude: -122.4194,\n      city: \"San Francisco\",\n      state_code: \"CA\",\n      country_code: \"US\"\n    )\n\n    user.regeocode\n\n    assert_equal \"Berlin\", user.city\n    assert_equal \"BE\", user.state_code\n    assert_equal \"DE\", user.country_code\n    assert_in_delta 52.52, user.latitude.to_f, 0.01\n    assert_in_delta 13.405, user.longitude.to_f, 0.01\n  end\n\n  test \"regeocode works when no previous geocode data exists\" do\n    user = User.create!(name: \"Test User\", location: \"San Francisco, CA\")\n\n    user.regeocode\n\n    assert_equal \"San Francisco\", user.city\n    assert_equal \"CA\", user.state_code\n    assert_equal \"US\", user.country_code\n  end\n\n  test \"geocode overwrites existing latitude with new geocoded value\" do\n    user = User.create!(\n      name: \"Test User\",\n      location: \"San Francisco, CA\",\n      latitude: 99.999\n    )\n\n    user.geocode\n\n    assert_in_delta 37.7749, user.latitude.to_f, 0.01\n  end\n\n  test \"geocode overwrites existing longitude with new geocoded value\" do\n    user = User.create!(\n      name: \"Test User\",\n      location: \"San Francisco, CA\",\n      longitude: -99.999\n    )\n\n    user.geocode\n\n    assert_in_delta(-122.4194, user.longitude.to_f, 0.01)\n  end\n\n  test \"geocode fills in missing latitude when longitude is present\" do\n    user = User.create!(\n      name: \"Test User\",\n      location: \"San Francisco, CA\",\n      longitude: -122.4194\n    )\n\n    user.geocode\n\n    assert_in_delta 37.7749, user.latitude.to_f, 0.01\n    assert_in_delta(-122.4194, user.longitude.to_f, 0.01)\n  end\n\n  test \"with_coordinates scope returns records with both lat and long\" do\n    with_coords = User.create!(name: \"With\", latitude: 37.7749, longitude: -122.4194)\n    without_coords = User.create!(name: \"Without\")\n    partial = User.create!(name: \"Partial\", latitude: 37.7749)\n\n    assert_includes User.with_coordinates, with_coords\n    assert_not_includes User.with_coordinates, without_coords\n    assert_not_includes User.with_coordinates, partial\n  end\n\n  test \"without_coordinates scope returns records missing lat or long\" do\n    with_coords = User.create!(name: \"With\", latitude: 37.7749, longitude: -122.4194)\n    without_coords = User.create!(name: \"Without\")\n    partial = User.create!(name: \"Partial\", latitude: 37.7749)\n\n    assert_not_includes User.without_coordinates, with_coords\n    assert_includes User.without_coordinates, without_coords\n    assert_includes User.without_coordinates, partial\n  end\n\n  test \"geocode stores metadata with timestamp\" do\n    user = User.create!(name: \"Test User\", location: \"San Francisco, CA\")\n\n    freeze_time do\n      user.geocode\n      user.save!\n\n      assert user.geocode_metadata[\"geocoded_at\"].present?\n      assert_equal Time.current.iso8601, user.geocode_metadata[\"geocoded_at\"]\n    end\n  end\nend\n"
  },
  {
    "path": "test/models/connected_account_test.rb",
    "content": "require \"test_helper\"\n\nclass ConnectedAccountTest < ActiveSupport::TestCase\n  setup do\n    @user = users(:one)\n  end\n\n  test \"passport_accounts association\" do\n    @user.connected_accounts.create(provider: \"passport\", uid: \"123456\")\n    assert_equal @user.passports.first.uid, \"123456\"\n  end\n\n  test \"a user can have multiple passports\" do\n    assert_nothing_raised do\n      @user.connected_accounts.create(provider: \"passport\", uid: \"123456\")\n      @user.connected_accounts.create(provider: \"passport\", uid: \"123457\")\n    end\n  end\n\n  test \"a user can't have multiple passports with the same uid\" do\n    assert_raise do\n      @user.connected_accounts.create(provider: \"passport\", uid: \"123456\")\n      @user.connected_accounts.create(provider: \"passport\", uid: \"123456\")\n    end\n  end\n\n  test \"a user can have multiple github connected_accounts\" do\n    assert_nothing_raised do\n      @user.connected_accounts.create!(provider: \"github\", uid: \"123456\")\n      @user.connected_accounts.create!(provider: \"github\", uid: \"123457\")\n    end\n  end\n\n  test \"a user can have a passport and a github connected_account with teh same uid\" do\n    assert_nothing_raised do\n      @user.connected_accounts.create(provider: \"github\", uid: \"123456\")\n      @user.connected_accounts.create(provider: \"passport\", uid: \"123456\")\n    end\n  end\nend\n"
  },
  {
    "path": "test/models/continent_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass ContinentTest < ActiveSupport::TestCase\n  test \"find returns Continent for valid slug\" do\n    continent = Continent.find(\"europe\")\n\n    assert_not_nil continent\n    assert_equal \"Europe\", continent.name\n  end\n\n  test \"find returns nil for invalid slug\" do\n    assert_nil Continent.find(\"invalid\")\n  end\n\n  test \"find returns nil for blank\" do\n    assert_nil Continent.find(nil)\n    assert_nil Continent.find(\"\")\n  end\n\n  test \"find_by_name returns Continent for valid name\" do\n    continent = Continent.find_by_name(\"Europe\")\n\n    assert_not_nil continent\n    assert_equal \"europe\", continent.slug\n  end\n\n  test \"all returns array of Continent instances\" do\n    continents = Continent.all\n\n    assert continents.is_a?(Array)\n    assert_equal 7, continents.size\n    assert continents.first.is_a?(Continent)\n  end\n\n  test \"slugs returns array of continent slugs\" do\n    slugs = Continent.slugs\n\n    assert_includes slugs, \"europe\"\n    assert_includes slugs, \"north-america\"\n    assert_includes slugs, \"asia\"\n  end\n\n  test \"name returns continent name\" do\n    continent = Continent.find(\"europe\")\n\n    assert_equal \"Europe\", continent.name\n  end\n\n  test \"alpha2 returns continent code\" do\n    continent = Continent.find(\"europe\")\n\n    assert_equal \"EU\", continent.alpha2\n  end\n\n  test \"emoji_flag returns continent emoji\" do\n    continent = Continent.find(\"europe\")\n\n    assert_equal continent.emoji_flag, continent.emoji_flag\n  end\n\n  test \"path returns continents path with slug\" do\n    continent = Continent.find(\"europe\")\n\n    assert_equal \"/continents/europe\", continent.path\n  end\n\n  test \"to_param returns slug\" do\n    continent = Continent.find(\"europe\")\n\n    assert_equal \"europe\", continent.to_param\n  end\n\n  test \"bounds returns bounding box\" do\n    continent = Continent.find(\"europe\")\n    bounds = continent.bounds\n\n    assert bounds.is_a?(Hash)\n    assert bounds.key?(:southwest)\n    assert bounds.key?(:northeast)\n  end\n\n  test \"countries returns array of Country instances\" do\n    continent = Continent.find(\"europe\")\n    countries = continent.countries\n\n    assert countries.is_a?(Array)\n    assert countries.any?\n    assert countries.first.is_a?(Country)\n  end\n\n  test \"country_codes returns alpha2 codes for countries\" do\n    continent = Continent.find(\"europe\")\n    codes = continent.country_codes\n\n    assert_includes codes, \"DE\"\n    assert_includes codes, \"FR\"\n    assert_includes codes, \"GB\"\n  end\n\n  test \"two continents with same slug are equal\" do\n    continent1 = Continent.find(\"europe\")\n    continent2 = Continent.find(\"europe\")\n\n    assert_equal continent1, continent2\n  end\n\n  test \"two continents with different slugs are not equal\" do\n    continent1 = Continent.find(\"europe\")\n    continent2 = Continent.find(\"asia\")\n\n    assert_not_equal continent1, continent2\n  end\n\n  test \"to_location returns Location with continent name\" do\n    continent = Continent.find(\"europe\")\n    location = continent.to_location\n\n    assert_kind_of Location, location\n    assert_equal \"Europe\", location.to_text\n  end\n\n  test \"to_location for North America\" do\n    continent = Continent.find(\"north-america\")\n    location = continent.to_location\n\n    assert_equal \"North America\", location.to_text\n  end\n\n  test \"to_location for all continents returns name\" do\n    Continent.all.each do |continent|\n      location = continent.to_location\n\n      assert_equal continent.name, location.to_text, \"Expected to_location.to_text for #{continent.slug} to return #{continent.name}\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/models/contributor_test.rb",
    "content": "require \"test_helper\"\n\nclass ContributorTest < ActiveSupport::TestCase\n  # test \"the truth\" do\n  #   assert true\n  # end\nend\n"
  },
  {
    "path": "test/models/country_test.rb",
    "content": "require \"test_helper\"\n\nclass CountryTest < ActiveSupport::TestCase\n  test \"find_by returns country for valid country code\" do\n    country = Country.find_by(country_code: \"US\")\n\n    assert_not_nil country\n    assert_equal \"US\", country.alpha2\n    assert_equal \"United States of America (the)\", country.iso_short_name\n  end\n\n  test \"find_by returns country for lowercase country code\" do\n    country = Country.find_by(country_code: \"de\")\n\n    assert_not_nil country\n    assert_equal \"DE\", country.alpha2\n  end\n\n  test \"find_by returns nil for invalid code\" do\n    assert_nil Country.find_by(country_code: \"XX\")\n  end\n\n  test \"find_by returns nil for blank code\" do\n    assert_nil Country.find_by(country_code: nil)\n    assert_nil Country.find_by(country_code: \"\")\n  end\n\n  test \"find returns country by name\" do\n    country = Country.find(\"Germany\")\n\n    assert_not_nil country\n    assert_equal \"DE\", country.alpha2\n  end\n\n  test \"find returns country by unofficial name\" do\n    country = Country.find(\"USA\")\n\n    assert_not_nil country\n    assert_equal \"US\", country.alpha2\n  end\n\n  test \"find returns nil for empty string\" do\n    assert_nil Country.find(\"\")\n  end\n\n  test \"find returns nil for nil\" do\n    assert_nil Country.find(nil)\n  end\n\n  test \"find returns nil for online\" do\n    assert_nil Country.find(\"online\")\n    assert_nil Country.find(\"online\")\n  end\n\n  test \"find returns nil for earth\" do\n    assert_nil Country.find(\"earth\")\n    assert_nil Country.find(\"Earth\")\n  end\n\n  test \"find returns nil for unknown\" do\n    assert_nil Country.find(\"unknown\")\n    assert_nil Country.find(\"Unknown\")\n  end\n\n  test \"find returns US for US state abbreviations that don't conflict with country codes\" do\n    country = Country.find(\"NY\")\n\n    assert_not_nil country\n    assert_equal \"US\", country.alpha2\n  end\n\n  test \"find prioritizes country codes over US state abbreviations\" do\n    country = Country.find(\"CA\")\n\n    assert_not_nil country\n    assert_equal \"CA\", country.alpha2\n    assert_equal \"Canada\", country.name\n  end\n\n  test \"find returns GB for UK\" do\n    country = Country.find(\"UK\")\n\n    assert_not_nil country\n    assert_equal \"GB\", country.alpha2\n  end\n\n  test \"find returns UKNation for Scotland\" do\n    country = Country.find(\"Scotland\")\n\n    assert_not_nil country\n    assert_instance_of UKNation, country\n    assert_equal \"GB-SCT\", country.alpha2\n    assert_equal \"Scotland\", country.name\n  end\n\n  test \"find handles hyphenated terms\" do\n    country = Country.find(\"united-states\")\n\n    assert_not_nil country\n    assert_equal \"US\", country.alpha2\n  end\n\n  test \"all returns array of Country instances\" do\n    countries = Country.all\n\n    assert countries.is_a?(Array)\n    assert countries.first.is_a?(Country)\n  end\n\n  test \"all_by_slug returns hash of countries by slug\" do\n    countries = Country.all_by_slug\n\n    assert countries.is_a?(Hash)\n    assert countries.key?(\"germany\")\n    assert countries[\"germany\"].is_a?(Country)\n  end\n\n  test \"slugs returns array of country slugs\" do\n    slugs = Country.slugs\n\n    assert slugs.is_a?(Array)\n    assert_includes slugs, \"germany\"\n  end\n\n  test \"name returns English translation\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_equal \"Germany\", country.name\n  end\n\n  test \"name returns United States for US\" do\n    country = Country.find_by(country_code: \"US\")\n\n    assert_equal \"United States\", country.name\n  end\n\n  test \"slug returns parameterized name\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_equal \"germany\", country.slug\n  end\n\n  test \"slug handles multi-word names\" do\n    country = Country.find_by(country_code: \"US\")\n\n    assert_equal \"united-states\", country.slug\n  end\n\n  test \"slug preserves transliterated diacritics for backward compatibility\" do\n    country = Country.find_by(country_code: \"TR\")\n\n    assert_equal \"tuerkiye\", country.slug\n  end\n\n  test \"find returns country by slug with diacritics stripped\" do\n    country = Country.find(\"turkiye\")\n\n    assert_not_nil country\n    assert_equal \"TR\", country.alpha2\n  end\n\n  test \"find returns country by transliterated slug\" do\n    country = Country.find(\"tuerkiye\")\n\n    assert_not_nil country\n    assert_equal \"TR\", country.alpha2\n  end\n\n  test \"path returns countries path with slug\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_equal \"/countries/germany\", country.path\n  end\n\n  test \"code returns lowercase alpha2\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_equal \"de\", country.code\n  end\n\n  test \"to_param returns slug for use in Rails path helpers\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_equal \"germany\", country.to_param\n  end\n\n  test \"two countries with same alpha2 are equal\" do\n    country1 = Country.find_by(country_code: \"DE\")\n    country2 = Country.find_by(country_code: \"DE\")\n\n    assert_equal country1, country2\n  end\n\n  test \"two countries with different alpha2 are not equal\" do\n    country1 = Country.find_by(country_code: \"DE\")\n    country2 = Country.find_by(country_code: \"US\")\n\n    assert_not_equal country1, country2\n  end\n\n  test \"country is not equal to non-Country objects\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_not_equal country, \"DE\"\n    assert_not_equal country, nil\n  end\n\n  test \"eql? returns true for countries with same alpha2\" do\n    country1 = Country.find_by(country_code: \"DE\")\n    country2 = Country.find_by(country_code: \"DE\")\n\n    assert country1.eql?(country2)\n  end\n\n  test \"hash is same for countries with same alpha2\" do\n    country1 = Country.find_by(country_code: \"DE\")\n    country2 = Country.find_by(country_code: \"DE\")\n\n    assert_equal country1.hash, country2.hash\n  end\n\n  test \"countries can be used as hash keys\" do\n    country1 = Country.find_by(country_code: \"DE\")\n    country2 = Country.find_by(country_code: \"DE\")\n\n    hash = {country1 => \"value\"}\n\n    assert_equal \"value\", hash[country2]\n  end\n\n  test \"record returns underlying ISO3166::Country\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert country.record.is_a?(ISO3166::Country)\n    assert_equal \"DE\", country.record.alpha2\n  end\n\n  test \"delegates alpha2 to record\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_equal \"DE\", country.alpha2\n  end\n\n  test \"continent returns Continent instance\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_kind_of Continent, country.continent\n    assert_equal \"Europe\", country.continent.name\n  end\n\n  test \"continent_name returns continent name string\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_equal \"Europe\", country.continent_name\n  end\n\n  test \"delegates emoji_flag to record\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_equal \"🇩🇪\", country.emoji_flag\n  end\n\n  test \"select_options returns array of [name, alpha2] pairs\" do\n    options = Country.select_options\n\n    assert options.is_a?(Array)\n    assert options.first.is_a?(Array)\n    assert_equal 2, options.first.size\n\n    names = options.map(&:first)\n    assert_equal names.sort, names\n  end\n\n  test \"select_options contains expected countries\" do\n    options = Country.select_options\n    option_map = options.to_h\n\n    assert_equal \"DE\", option_map[\"Germany\"]\n    assert_equal \"US\", option_map[\"United States\"]\n  end\n\n  test \"events returns ActiveRecord::Relation\" do\n    country = Country.find_by(country_code: \"NL\")\n\n    assert country.events.is_a?(ActiveRecord::Relation)\n  end\n\n  test \"events returns events matching country_code\" do\n    country = Country.find_by(country_code: \"NL\")\n    event = events(:rails_world_2023)\n    event.update!(country_code: \"NL\")\n\n    assert_includes country.events, event\n  end\n\n  test \"events does not include events from other countries\" do\n    country = Country.find_by(country_code: \"NL\")\n    event = events(:rails_world_2023)\n    event.update!(country_code: \"DE\")\n\n    assert_not_includes country.events, event\n  end\n\n  test \"users returns ActiveRecord::Relation\" do\n    country = Country.find_by(country_code: \"US\")\n\n    assert country.users.is_a?(ActiveRecord::Relation)\n  end\n\n  test \"users returns geocoded indexable users matching country_code\" do\n    country = Country.find_by(country_code: \"US\")\n    user = User.create!(name: \"Test User\", country_code: \"US\", latitude: 40.7128, longitude: -74.0060)\n\n    assert_includes country.users, user\n  end\n\n  test \"users does not include users from other countries\" do\n    country = Country.find_by(country_code: \"US\")\n    user = User.create!(name: \"Test User\", country_code: \"DE\", latitude: 52.52, longitude: 13.405)\n\n    assert_not_includes country.users, user\n  end\n\n  test \"users does not include non-geocoded users\" do\n    country = Country.find_by(country_code: \"US\")\n    user = User.create!(name: \"Test User\", country_code: \"US\")\n\n    assert_not_includes country.users, user\n  end\n\n  test \"stamps returns array of stamps for the country\" do\n    country = Country.find_by(country_code: \"NL\")\n\n    assert country.stamps.is_a?(Array)\n  end\n\n  test \"stamps returns stamps matching country\" do\n    country = Country.find_by(country_code: \"NL\")\n    stamps = country.stamps\n\n    stamps.each do |stamp|\n      assert stamp.has_country?\n      assert_equal \"NL\", stamp.country.alpha2\n    end\n  end\n\n  test \"held_in_sentence returns sentence for regular country\" do\n    country = Country.find_by(country_code: \"DE\")\n\n    assert_equal \" held in Germany\", country.held_in_sentence\n  end\n\n  test \"held_in_sentence returns sentence with 'the' for United countries\" do\n    country = Country.find_by(country_code: \"US\")\n\n    assert_equal \" held in the United States\", country.held_in_sentence\n  end\n\n  test \"held_in_sentence returns sentence with 'the' for United Kingdom\" do\n    country = Country.find_by(country_code: \"GB\")\n\n    assert_equal \" held in the United Kingdom\", country.held_in_sentence\n  end\n\n  test \"to_location returns Location with country and continent\" do\n    country = Country.find_by(country_code: \"US\")\n    location = country.to_location\n\n    assert_kind_of Location, location\n    assert_equal \"United States\", location.to_text\n  end\n\n  test \"to_location returns Location with European country\" do\n    country = Country.find_by(country_code: \"DE\")\n    location = country.to_location\n\n    assert_equal \"Germany\", location.to_text\n  end\n\n  test \"to_location returns Location with Asian country\" do\n    country = Country.find_by(country_code: \"JP\")\n    location = country.to_location\n\n    assert_equal \"Japan\", location.to_text\n  end\nend\n"
  },
  {
    "path": "test/models/event/assets_test.rb",
    "content": "require \"test_helper\"\n\nclass Event::AssetsTest < ActiveSupport::TestCase\n  setup do\n    @event = events(:future_conference)\n  end\n\n  test \"base_path returns correct path\" do\n    expected = \"events/#{@event.series.slug}/#{@event.slug}\"\n    assert_equal expected, @event.assets.base_path\n  end\n\n  test \"default_path returns global default path\" do\n    assert_equal \"events/default\", @event.assets.default_path\n  end\n\n  test \"default_series_path returns series default path\" do\n    expected = \"events/#{@event.series.slug}/default\"\n    assert_equal expected, @event.assets.default_series_path\n  end\n\n  test \"image_path_for falls back to global default when file does not exist\" do\n    result = @event.assets.image_path_for(\"nonexistent.webp\")\n    assert_equal \"events/default/nonexistent.webp\", result\n  end\n\n  test \"image_path_if_exists returns nil when image does not exist\" do\n    result = @event.assets.image_path_if_exists(\"nonexistent.webp\")\n    assert_nil result\n  end\nend\n"
  },
  {
    "path": "test/models/event/static_metadata_test.rb",
    "content": "require \"test_helper\"\n\nclass Event::StaticMetadataTest < ActiveSupport::TestCase\nend\n"
  },
  {
    "path": "test/models/event/tickets/provider_detection_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Event::Tickets::ProviderDetectionTest < ActiveSupport::TestCase\n  def tickets_for(url)\n    event = events(:brightonruby_2024)\n    tickets = Event::Tickets.new(event: event)\n    tickets.define_singleton_method(:url) { url }\n    tickets\n  end\n\n  test \"tito? returns true for ti.to URL\" do\n    assert tickets_for(\"https://ti.to/goodscary/brightonruby-2024\").tito?\n  end\n\n  test \"tito? returns true for tito.io URL\" do\n    assert tickets_for(\"https://tito.io/goodscary/brightonruby-2024\").tito?\n  end\n\n  test \"tito? returns false for non-tito URL\" do\n    refute tickets_for(\"https://eventbrite.com/event/123\").tito?\n  end\n\n  test \"luma? returns true for lu.ma URL\" do\n    assert tickets_for(\"https://lu.ma/my-event\").luma?\n  end\n\n  test \"luma? returns false for non-luma URL\" do\n    refute tickets_for(\"https://ti.to/org/event\").luma?\n  end\n\n  test \"meetup? returns true for meetup.com URL\" do\n    assert tickets_for(\"https://www.meetup.com/group/events/123\").meetup?\n  end\n\n  test \"meetup? returns false for non-meetup URL\" do\n    refute tickets_for(\"https://ti.to/org/event\").meetup?\n  end\n\n  test \"tito_event_slug extracts slug from ti.to URL\" do\n    assert_equal \"goodscary/brightonruby-2024\", tickets_for(\"https://ti.to/goodscary/brightonruby-2024\").tito_event_slug\n  end\n\n  test \"tito_event_slug extracts slug from tito.io URL\" do\n    assert_equal \"goodscary/brightonruby-2024\", tickets_for(\"https://tito.io/goodscary/brightonruby-2024\").tito_event_slug\n  end\n\n  test \"tito_event_slug returns nil for non-tito URL\" do\n    assert_nil tickets_for(\"https://eventbrite.com/event/123\").tito_event_slug\n  end\n\n  test \"provider_name returns Tito for ti.to URLs\" do\n    assert_equal \"Tito\", tickets_for(\"https://ti.to/goodscary/brightonruby-2024\").provider_name\n  end\n\n  test \"provider_name returns Luma for lu.ma URLs\" do\n    assert_equal \"Luma\", tickets_for(\"https://lu.ma/my-event\").provider_name\n  end\n\n  test \"provider_name returns Meetup for meetup.com URLs\" do\n    assert_equal \"Meetup\", tickets_for(\"https://www.meetup.com/group/events/123\").provider_name\n  end\n\n  test \"provider_name returns Eventbrite for eventbrite URLs\" do\n    assert_equal \"Eventbrite\", tickets_for(\"https://www.eventbrite.com/e/123\").provider_name\n  end\n\n  test \"provider_name returns Pretix for pretix URLs\" do\n    assert_equal \"Pretix\", tickets_for(\"https://pretix.eu/org/event\").provider_name\n  end\n\n  test \"provider_name returns nil for unknown URLs\" do\n    assert_nil tickets_for(\"https://unknown-ticketing.com/event\").provider_name\n  end\n\n  test \"tito? returns false when ti.to appears in path only\" do\n    refute tickets_for(\"https://example.com/redirect?url=ti.to/event\").tito?\n  end\n\n  test \"luma? returns false when lu.ma appears in path only\" do\n    refute tickets_for(\"https://example.com/events/lu.ma-style\").luma?\n  end\n\n  test \"meetup? returns false when meetup.com appears in query string\" do\n    refute tickets_for(\"https://example.com/redirect?to=meetup.com/group\").meetup?\n  end\n\n  test \"provider_name returns nil when eventbrite appears in path\" do\n    assert_nil tickets_for(\"https://example.com/compare-to-eventbrite\").provider_name\n  end\n\n  test \"provider_name handles invalid URLs gracefully\" do\n    assert_nil tickets_for(\"not a valid url at all\").provider_name\n  end\n\n  test \"provider_name handles empty URL\" do\n    assert_nil tickets_for(\"\").provider_name\n  end\n\n  test \"provider_name handles nil URL\" do\n    assert_nil tickets_for(nil).provider_name\n  end\n\n  test \"tito? works with www subdomain\" do\n    assert tickets_for(\"https://www.ti.to/goodscary/brightonruby-2024\").tito?\n  end\n\n  test \"meetup? works with www subdomain\" do\n    assert tickets_for(\"https://www.meetup.com/ruby-group/events/123\").meetup?\n  end\n\n  test \"provider_name returns Connpass for connpass.com URLs\" do\n    assert_equal \"Connpass\", tickets_for(\"https://connpass.com/event/123\").provider_name\n  end\n\n  test \"provider_name returns Sympla for sympla.com.br URLs\" do\n    assert_equal \"Sympla\", tickets_for(\"https://www.sympla.com.br/evento/123\").provider_name\n  end\n\n  test \"provider_name returns Sympla for sympla.com.br without subdomain\" do\n    assert_equal \"Sympla\", tickets_for(\"https://sympla.com.br/evento/123\").provider_name\n  end\n\n  test \"provider_name returns TicketTailor for tickettailor URLs\" do\n    assert_equal \"TicketTailor\", tickets_for(\"https://www.tickettailor.com/events/org/123\").provider_name\n  end\n\n  test \"provider_name returns Eventpop for eventpop.me URLs\" do\n    assert_equal \"Eventpop\", tickets_for(\"https://www.eventpop.me/e/123\").provider_name\n  end\n\n  test \"provider returns a StringInquirer\" do\n    assert_kind_of ActiveSupport::StringInquirer, tickets_for(\"https://ti.to/org/event\").provider\n  end\n\n  test \"provider.tito? returns true for tito URLs\" do\n    assert tickets_for(\"https://ti.to/org/event\").provider.tito?\n  end\n\n  test \"provider.luma? returns true for luma URLs\" do\n    assert tickets_for(\"https://lu.ma/my-event\").provider.luma?\n  end\n\n  test \"provider.meetup? returns true for meetup URLs\" do\n    assert tickets_for(\"https://meetup.com/group/events/123\").provider.meetup?\n  end\n\n  test \"provider.eventbrite? returns true for eventbrite URLs\" do\n    assert tickets_for(\"https://eventbrite.com/e/123\").provider.eventbrite?\n  end\n\n  test \"provider.tito? returns false for non-tito URLs\" do\n    refute tickets_for(\"https://lu.ma/my-event\").provider.tito?\n  end\n\n  test \"provider inquiry returns false for unknown provider\" do\n    tickets = tickets_for(\"https://unknown.com/event\")\n    refute tickets.provider.tito?\n    refute tickets.provider.luma?\n    refute tickets.provider.unknown?\n  end\n\n  test \"provider equals empty string for unknown URLs\" do\n    assert_equal \"\", tickets_for(\"https://unknown.com/event\").provider\n  end\n\n  test \"provider equals provider name downcased\" do\n    assert_equal \"tito\", tickets_for(\"https://ti.to/org/event\").provider\n  end\nend\n"
  },
  {
    "path": "test/models/event/tickets_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Event::TicketsTest < ActiveSupport::TestCase\n  setup do\n    @event = events(:brightonruby_2024)\n    @future_event = events(:future_conference)\n  end\n\n  test \"exist? returns false when no tickets_url is set\" do\n    refute @event.tickets.exist?\n  end\n\n  test \"available? returns false when no tickets_url is set\" do\n    refute @event.tickets.available?\n  end\n\n  test \"url returns nil when no tickets_url is set\" do\n    assert_nil @event.tickets.url\n  end\n\n  test \"tito? returns false when url is nil\" do\n    refute @event.tickets.tito?\n  end\n\n  test \"luma? returns false when url is nil\" do\n    refute @event.tickets.luma?\n  end\n\n  test \"meetup? returns false when url is nil\" do\n    refute @event.tickets.meetup?\n  end\n\n  test \"tito_event_slug returns nil when url is nil\" do\n    assert_nil @event.tickets.tito_event_slug\n  end\n\n  test \"provider_name returns nil when url is nil\" do\n    assert_nil @event.tickets.provider_name\n  end\n\n  test \"event.tickets? returns false when no tickets exist\" do\n    refute @event.tickets?\n  end\n\n  test \"event.next_upcoming_event_with_tickets returns nil when series is nil\" do\n    event = Event.new(name: \"Test\")\n    assert_nil event.next_upcoming_event_with_tickets\n  end\n\n  test \"event.next_upcoming_event_with_tickets returns nil when no upcoming events with tickets\" do\n    assert_nil @event.next_upcoming_event_with_tickets\n  end\nend\n"
  },
  {
    "path": "test/models/event/videos_file_test.rb",
    "content": "require \"test_helper\"\n\nclass Event::VideosFileTest < ActiveSupport::TestCase\n  setup do\n    @event = events(:future_conference)\n  end\n\n  test \"file_path returns correct path\" do\n    expected = Rails.root.join(\"data\", @event.series.slug, @event.slug, \"videos.yml\")\n    assert_equal expected, @event.videos_file.file_path\n  end\n\n  test \"exist? returns false when file does not exist\" do\n    assert_not @event.videos_file.exist?\n  end\n\n  test \"entries returns empty array when file does not exist\" do\n    assert_equal [], @event.videos_file.entries\n  end\n\n  test \"ids returns empty array when file does not exist\" do\n    assert_equal [], @event.videos_file.ids\n  end\n\n  test \"count returns zero when file does not exist\" do\n    assert_equal 0, @event.videos_file.count\n  end\n\n  test \"find_by_id returns nil when file does not exist\" do\n    assert_nil @event.videos_file.find_by_id(\"nonexistent\")\n  end\n\n  test \"entries returns parsed YAML content\" do\n    videos_file = @event.videos_file\n    videos = [{\"id\" => \"video1\", \"title\" => \"Talk 1\"}, {\"id\" => \"video2\", \"title\" => \"Talk 2\"}]\n\n    with_temp_yaml(videos) do |path|\n      videos_file.define_singleton_method(:file_path) { path }\n      assert_equal videos, videos_file.entries\n    end\n  end\n\n  test \"ids returns all video ids without child talks\" do\n    videos_file = @event.videos_file\n    videos = [\n      {\"id\" => \"video1\"},\n      {\"id\" => \"video2\"},\n      {\"id\" => \"video3\"}\n    ]\n\n    with_temp_yaml(videos) do |path|\n      videos_file.define_singleton_method(:file_path) { path }\n      assert_equal %w[video1 video2 video3], videos_file.ids(child_talks: false)\n    end\n  end\n\n  test \"ids includes child talk ids when child_talks is true\" do\n    videos_file = @event.videos_file\n    videos = [\n      {\"id\" => \"video1\", \"talks\" => [{\"id\" => \"child1\"}, {\"id\" => \"child2\"}]},\n      {\"id\" => \"video2\"}\n    ]\n\n    with_temp_yaml(videos) do |path|\n      videos_file.define_singleton_method(:file_path) { path }\n      assert_equal %w[video1 child1 child2 video2], videos_file.ids(child_talks: true)\n    end\n  end\n\n  test \"find_by_id returns matching entry\" do\n    videos_file = @event.videos_file\n    videos = [\n      {\"id\" => \"video1\", \"title\" => \"Talk 1\"},\n      {\"id\" => \"video2\", \"title\" => \"Talk 2\"}\n    ]\n\n    with_temp_yaml(videos) do |path|\n      videos_file.define_singleton_method(:file_path) { path }\n      result = videos_file.find_by_id(\"video2\")\n      assert_equal({\"id\" => \"video2\", \"title\" => \"Talk 2\"}, result)\n    end\n  end\n\n  test \"find_by_id returns nil when not found\" do\n    videos_file = @event.videos_file\n    videos = [{\"id\" => \"video1\"}]\n\n    with_temp_yaml(videos) do |path|\n      videos_file.define_singleton_method(:file_path) { path }\n      assert_nil videos_file.find_by_id(\"nonexistent\")\n    end\n  end\n\n  test \"count returns number of entries\" do\n    videos_file = @event.videos_file\n    videos = [{\"id\" => \"video1\"}, {\"id\" => \"video2\"}, {\"id\" => \"video3\"}]\n\n    with_temp_yaml(videos) do |path|\n      videos_file.define_singleton_method(:file_path) { path }\n      assert_equal 3, videos_file.count\n    end\n  end\n\n  private\n\n  def with_temp_yaml(content)\n    file = Tempfile.new([\"videos\", \".yml\"])\n    file.write(content.to_yaml)\n    file.close\n    yield Pathname.new(file.path)\n  ensure\n    file.unlink\n  end\nend\n"
  },
  {
    "path": "test/models/event_geocoding_test.rb",
    "content": "require \"test_helper\"\nrequire \"ostruct\"\n\nclass EventGeocodingTest < ActiveSupport::TestCase\n  setup do\n    Geocoder::Lookup::Test.add_stub(\n      \"San Francisco, CA\", [\n        {\n          \"coordinates\" => [37.7749, -122.4194],\n          \"address\" => \"San Francisco, CA, USA\",\n          \"city\" => \"San Francisco\",\n          \"state\" => \"California\",\n          \"state_code\" => \"CA\",\n          \"postal_code\" => \"94102\",\n          \"country\" => \"United States\",\n          \"country_code\" => \"US\"\n        }\n      ]\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"Chicago, IL\", [\n        {\n          \"coordinates\" => [41.8781, -87.6298],\n          \"address\" => \"Chicago, IL, USA\",\n          \"city\" => \"Chicago\",\n          \"state\" => \"Illinois\",\n          \"state_code\" => \"IL\",\n          \"postal_code\" => \"60601\",\n          \"country\" => \"United States\",\n          \"country_code\" => \"US\"\n        }\n      ]\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"San Francisco, California, United States\", [\n        {\n          \"coordinates\" => [37.7749, -122.4194],\n          \"city\" => \"San Francisco\",\n          \"state_code\" => \"CA\",\n          \"country_code\" => \"US\"\n        }\n      ]\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"Chicago, Illinois, United States\", [\n        {\n          \"coordinates\" => [41.8781, -87.6298],\n          \"city\" => \"Chicago\",\n          \"state_code\" => \"IL\",\n          \"country_code\" => \"US\"\n        }\n      ]\n    )\n\n    @series = event_series(:railsconf)\n  end\n\n  teardown do\n    Geocoder::Lookup::Test.reset\n  end\n\n  test \"geocode with valid location\" do\n    event = Event.create!(\n      name: \"Test Conf 2024\",\n      series: @series,\n      location: \"San Francisco, CA\"\n    )\n\n    event.geocode\n    event.save!\n\n    assert_equal \"San Francisco\", event.city\n    assert_equal \"CA\", event.state_code\n    assert_equal \"US\", event.country_code\n    assert_in_delta 37.7749, event.latitude.to_f, 0.01\n    assert_in_delta(-122.4194, event.longitude.to_f, 0.01)\n  end\n\n  test \"geocode stores metadata\" do\n    event = Event.create!(\n      name: \"Test Conf 2024\",\n      series: @series,\n      location: \"San Francisco, CA\"\n    )\n\n    event.geocode\n    event.save!\n\n    assert event.geocode_metadata.present?\n    assert event.geocode_metadata[\"geocoded_at\"].present?\n  end\n\n  test \"event geocodeable? returns true when location present\" do\n    event = Event.new(name: \"Test\", series: @series, location: \"San Francisco, CA\")\n    assert event.geocodeable?\n  end\n\n  test \"event geocodeable? returns false when location blank\" do\n    event = Event.new(name: \"Test\", series: @series, location: \"\")\n    assert_not event.geocodeable?\n  end\n\n  test \"event clear_geocode clears all geocode data\" do\n    event = Event.create!(\n      name: \"Test Conf 2024\",\n      series: @series,\n      location: \"San Francisco, CA\",\n      latitude: 37.7749,\n      longitude: -122.4194,\n      city: \"San Francisco\",\n      state_code: \"CA\",\n      country_code: \"US\",\n      geocode_metadata: {\"foo\" => \"bar\"}\n    )\n\n    event.clear_geocode\n\n    assert_nil event.latitude\n    assert_nil event.longitude\n    assert_nil event.city\n    assert_nil event.state_code\n    assert_nil event.country_code\n    assert_equal({}, event.geocode_metadata)\n  end\n\n  test \"event regeocode clears and geocodes fresh\" do\n    event = Event.create!(\n      name: \"Test Conf 2024\",\n      series: @series,\n      location: \"Chicago, IL\",\n      latitude: 37.7749,\n      longitude: -122.4194,\n      city: \"San Francisco\",\n      state_code: \"CA\",\n      country_code: \"US\"\n    )\n\n    event.regeocode\n\n    assert_equal \"Chicago\", event.city\n    assert_equal \"IL\", event.state_code\n    assert_equal \"US\", event.country_code\n    assert_in_delta 41.8781, event.latitude.to_f, 0.01\n    assert_in_delta(-87.6298, event.longitude.to_f, 0.01)\n  end\n\n  test \"with_coordinates scope works for events\" do\n    with_coords = Event.create!(\n      name: \"With Coords\",\n      series: @series,\n      latitude: 37.7749,\n      longitude: -122.4194\n    )\n\n    without_coords = Event.create!(\n      name: \"Without Coords\",\n      series: @series\n    )\n\n    assert_includes Event.with_coordinates, with_coords\n    assert_not_includes Event.with_coordinates, without_coords\n  end\n\n  test \"without_coordinates scope works for events\" do\n    with_coords = Event.create!(\n      name: \"With Coords\",\n      series: @series,\n      latitude: 37.7749,\n      longitude: -122.4194\n    )\n\n    without_coords = Event.create!(\n      name: \"Without Coords\",\n      series: @series\n    )\n\n    assert_not_includes Event.without_coordinates, with_coords\n    assert_includes Event.without_coordinates, without_coords\n  end\n\n  test \"geocode uses venue coordinates when venue exists\" do\n    event = Event.create!(\n      name: \"Test Conf 2024\",\n      series: @series,\n      location: \"San Francisco, CA\"\n    )\n\n    venue_stub = OpenStruct.new(\n      exist?: true,\n      coordinates: {\"latitude\" => 40.7128, \"longitude\" => -74.0060}\n    )\n\n    event.define_singleton_method(:venue) { venue_stub }\n\n    event.geocode\n\n    assert_in_delta 40.7128, event.latitude.to_f, 0.01\n    assert_in_delta(-74.0060, event.longitude.to_f, 0.01)\n\n    assert_equal \"San Francisco\", event.city\n    assert_equal \"CA\", event.state_code\n    assert_equal \"US\", event.country_code\n  end\n\n  test \"geocode uses geocoder coordinates when venue has no coordinates\" do\n    event = Event.create!(\n      name: \"Test Conf 2024\",\n      series: @series,\n      location: \"San Francisco, CA\"\n    )\n\n    venue_stub = OpenStruct.new(exist?: true, coordinates: {})\n    event.define_singleton_method(:venue) { venue_stub }\n\n    event.geocode\n\n    assert_in_delta 37.7749, event.latitude.to_f, 0.01\n    assert_in_delta(-122.4194, event.longitude.to_f, 0.01)\n  end\n\n  test \"geocode uses geocoder coordinates when venue does not exist\" do\n    event = Event.create!(\n      name: \"Test Conf 2024\",\n      series: @series,\n      location: \"San Francisco, CA\"\n    )\n\n    venue_stub = OpenStruct.new(exist?: false)\n    event.define_singleton_method(:venue) { venue_stub }\n\n    event.geocode\n\n    assert_in_delta 37.7749, event.latitude.to_f, 0.01\n    assert_in_delta(-122.4194, event.longitude.to_f, 0.01)\n  end\n\n  test \"geocode preserves venue coordinates on regeocode\" do\n    event = Event.create!(\n      name: \"Test Conf 2024\",\n      series: @series,\n      location: \"San Francisco, CA\",\n      latitude: 99.0,\n      longitude: -99.0\n    )\n\n    venue_stub = OpenStruct.new(\n      exist?: true,\n      coordinates: {\"latitude\" => 40.7128, \"longitude\" => -74.0060}\n    )\n\n    event.define_singleton_method(:venue) { venue_stub }\n\n    event.regeocode\n\n    assert_in_delta 40.7128, event.latitude.to_f, 0.01\n    assert_in_delta(-74.0060, event.longitude.to_f, 0.01)\n  end\nend\n"
  },
  {
    "path": "test/models/event_participation_test.rb",
    "content": "require \"test_helper\"\n\nclass EventParticipationTest < ActiveSupport::TestCase\n  test \"validates the main participation\" do\n    user = users(:one)\n    user2 = users(:two)\n    event = events(:rails_world_2023)\n    EventParticipation.create(user: user2, event: event, attended_as: \"keynote_speaker\")\n    EventParticipation.create(user: user, event: event, attended_as: \"speaker\")\n    EventParticipation.create(user: user, event: event, attended_as: \"keynote_speaker\")\n    EventParticipation.create(user: user, event: event, attended_as: \"visitor\")\n    EventParticipation.create(user: user2, event: event, attended_as: \"speaker\")\n    EventParticipation.create(user: user2, event: event, attended_as: \"visitor\")\n    assert_equal 3, user.event_participations.count\n    assert_equal \"keynote_speaker\", user.main_participation_to(event).attended_as\n  end\nend\n"
  },
  {
    "path": "test/models/event_series_test.rb",
    "content": "require \"test_helper\"\n\nclass EventSeriesTest < ActiveSupport::TestCase\n  setup do\n    @series = event_series(:railsconf)\n  end\n\n  test \"find_by_name_or_alias finds series by name\" do\n    found = EventSeries.find_by_name_or_alias(@series.name)\n\n    assert_equal @series, found\n  end\n\n  test \"find_by_name_or_alias finds series by alias name\" do\n    @series.aliases.create!(name: \"Rails Conference\", slug: \"rails-conference\")\n\n    found = EventSeries.find_by_name_or_alias(\"Rails Conference\")\n\n    assert_equal @series, found\n  end\n\n  test \"find_by_name_or_alias returns nil for non-existent name\" do\n    assert_nil EventSeries.find_by_name_or_alias(\"Non Existent Series\")\n  end\n\n  test \"find_by_name_or_alias returns nil for blank name\" do\n    assert_nil EventSeries.find_by_name_or_alias(nil)\n    assert_nil EventSeries.find_by_name_or_alias(\"\")\n  end\n\n  test \"find_by_slug_or_alias finds series by slug\" do\n    found = EventSeries.find_by_slug_or_alias(@series.slug)\n\n    assert_equal @series, found\n  end\n\n  test \"find_by_slug_or_alias finds series by alias slug\" do\n    @series.aliases.create!(name: \"Rails Conference\", slug: \"rails-conference\")\n\n    found = EventSeries.find_by_slug_or_alias(\"rails-conference\")\n\n    assert_equal @series, found\n  end\n\n  test \"find_by_slug_or_alias returns nil for non-existent slug\" do\n    assert_nil EventSeries.find_by_slug_or_alias(\"non-existent-slug\")\n  end\n\n  test \"find_by_slug_or_alias returns nil for blank slug\" do\n    assert_nil EventSeries.find_by_slug_or_alias(nil)\n    assert_nil EventSeries.find_by_slug_or_alias(\"\")\n  end\n\n  test \"sync_aliases_from_list creates aliases from array\" do\n    aliases = [\"Rails Conference\", \"RailsConf US\", \"RC\"]\n\n    assert_difference \"@series.aliases.count\", 3 do\n      @series.sync_aliases_from_list(aliases)\n    end\n\n    assert_equal \"Rails Conference\", @series.aliases.find_by(slug: \"rails-conference\").name\n    assert_equal \"RailsConf US\", @series.aliases.find_by(slug: \"railsconf-us\").name\n    assert_equal \"RC\", @series.aliases.find_by(slug: \"rc\").name\n  end\n\n  test \"sync_aliases_from_list does not create duplicates\" do\n    @series.aliases.create!(name: \"Rails Conference\", slug: \"rails-conference\")\n\n    aliases = [\"Rails Conference\", \"RailsConf US\"]\n\n    assert_difference \"@series.aliases.count\", 1 do\n      @series.sync_aliases_from_list(aliases)\n    end\n  end\n\n  test \"sync_aliases_from_list handles nil gracefully\" do\n    assert_no_difference \"@series.aliases.count\" do\n      @series.sync_aliases_from_list(nil)\n    end\n  end\n\n  test \"supports weekly and biweekly frequencies\" do\n    @series.frequency = :weekly\n    assert_predicate @series, :weekly?\n\n    @series.frequency = :biweekly\n    assert_predicate @series, :biweekly?\n  end\nend\n"
  },
  {
    "path": "test/models/event_test.rb",
    "content": "require \"test_helper\"\n\nclass EventTest < ActiveSupport::TestCase\n  setup do\n    @series = event_series(:railsconf)\n    @series.update(website: \"https://railsconf.org\")\n  end\n\n  test \"validates the country code \" do\n    assert Event.new(name: \"test\", country_code: \"NL\", series: @series).valid?\n    assert Event.new(name: \"test\", country_code: \"AU\", series: @series).valid?\n    refute Event.new(name: \"test\", country_code: \"France\", series: @series).valid?\n  end\n\n  test \"allows nil country code\" do\n    assert Event.new(name: \"test\", country_code: nil, series: @series).valid?\n  end\n\n  test \"returns event website if present\" do\n    event = Event.new(name: \"test\", series: @series, website: \"https://event-website.com\")\n    assert_equal \"https://event-website.com\", event.website\n  end\n\n  test \"returns event series website if event website is not present\" do\n    event = Event.new(name: \"test\", series: @series, website: nil)\n    assert_equal \"https://railsconf.org\", event.website\n  end\n\n  test \"don't create a unique slug in case of collison\" do\n    event = Event.create(name: \"test\")\n    assert_equal \"test\", event.slug\n\n    event = Event.create(name: \"test\")\n    assert_equal \"test\", event.slug\n    refute event.valid?\n  end\n\n  test \"find_by_slug_or_alias finds event by slug\" do\n    event = events(:rails_world_2023)\n    found = Event.find_by_slug_or_alias(event.slug)\n\n    assert_equal event, found\n  end\n\n  test \"find_by_slug_or_alias finds event by alias slug\" do\n    event = events(:rails_world_2023)\n    event.slug_aliases.create!(name: \"Old Name\", slug: \"old-event-slug\")\n\n    found = Event.find_by_slug_or_alias(\"old-event-slug\")\n\n    assert_equal event, found\n  end\n\n  test \"find_by_slug_or_alias returns nil for non-existent slug\" do\n    found = Event.find_by_slug_or_alias(\"non-existent-slug\")\n\n    assert_nil found\n  end\n\n  test \"find_by_slug_or_alias returns nil for blank slug\" do\n    assert_nil Event.find_by_slug_or_alias(nil)\n    assert_nil Event.find_by_slug_or_alias(\"\")\n  end\n\n  test \"find_by_name_or_alias finds event by name\" do\n    event = events(:rails_world_2023)\n    found = Event.find_by_name_or_alias(event.name)\n\n    assert_equal event, found\n  end\n\n  test \"find_by_name_or_alias finds event by alias name\" do\n    event = events(:rails_world_2023)\n    event.slug_aliases.create!(name: \"RW 2023\", slug: \"rw-2023\")\n\n    found = Event.find_by_name_or_alias(\"RW 2023\")\n\n    assert_equal event, found\n  end\n\n  test \"find_by_name_or_alias returns nil for non-existent name\" do\n    assert_nil Event.find_by_name_or_alias(\"Non Existent Event\")\n  end\n\n  test \"find_by_name_or_alias returns nil for blank name\" do\n    assert_nil Event.find_by_name_or_alias(nil)\n    assert_nil Event.find_by_name_or_alias(\"\")\n  end\n\n  test \"sync_aliases_from_list creates aliases from array\" do\n    event = events(:rails_world_2023)\n    aliases = [\"RW 2023\", \"Rails World Amsterdam\", \"RailsWorld23\"]\n\n    assert_difference \"event.slug_aliases.count\", 3 do\n      event.sync_aliases_from_list(aliases)\n    end\n\n    assert_equal \"RW 2023\", event.slug_aliases.find_by(slug: \"rw-2023\").name\n    assert_equal \"Rails World Amsterdam\", event.slug_aliases.find_by(slug: \"rails-world-amsterdam\").name\n    assert_equal \"RailsWorld23\", event.slug_aliases.find_by(slug: \"railsworld23\").name\n  end\n\n  test \"sync_aliases_from_list does not create duplicates\" do\n    event = events(:rails_world_2023)\n    event.slug_aliases.create!(name: \"RW 2023\", slug: \"rw-2023\")\n\n    aliases = [\"RW 2023\", \"Rails World Amsterdam\"]\n\n    assert_difference \"event.slug_aliases.count\", 1 do\n      event.sync_aliases_from_list(aliases)\n    end\n  end\n\n  test \"sync_aliases_from_list handles nil gracefully\" do\n    event = events(:rails_world_2023)\n\n    assert_no_difference \"event.slug_aliases.count\" do\n      event.sync_aliases_from_list(nil)\n    end\n  end\n\n  test \"ft_search finds event by name\" do\n    event = events(:rails_world_2023)\n\n    results = Event.ft_search(\"Rails World\")\n    assert_includes results, event\n  end\n\n  test \"ft_search finds event by alias name\" do\n    event = events(:rails_world_2023)\n    event.slug_aliases.create!(name: \"RW 2023\", slug: \"rw-2023\")\n\n    results = Event.ft_search(\"RW 2023\")\n    assert_includes results, event\n  end\n\n  test \"ft_search is case insensitive\" do\n    event = events(:rails_world_2023)\n    event.slug_aliases.create!(name: \"RW 2023\", slug: \"rw-2023\")\n\n    results = Event.ft_search(\"rw 2023\")\n    assert_includes results, event\n  end\n\n  test \"ft_search finds event by series name\" do\n    event = events(:rails_world_2023)\n\n    results = Event.ft_search(event.series.name)\n    assert_includes results, event\n  end\n\n  test \"ft_search finds event by series alias name\" do\n    event = events(:rails_world_2023)\n    event.series.aliases.create!(name: \"RW Conference\", slug: \"rw-conference\")\n\n    results = Event.ft_search(\"RW Conference\")\n    assert_includes results, event\n  end\n\n  test \"country returns Country object when country_code present\" do\n    event = Event.new(name: \"Test Event\", series: @series, country_code: \"US\")\n\n    assert_not_nil event.country\n    assert_equal \"US\", event.country.alpha2\n  end\n\n  test \"country returns Country object for different country codes\" do\n    event = Event.new(name: \"Test Event\", series: @series, country_code: \"DE\")\n\n    assert_not_nil event.country\n    assert_equal \"DE\", event.country.alpha2\n  end\n\n  test \"country returns nil when country_code is blank\" do\n    event = Event.new(name: \"Test Event\", series: @series, country_code: \"\")\n\n    assert_nil event.country\n  end\n\n  test \"country returns nil when country_code is nil\" do\n    event = Event.new(name: \"Test Event\", series: @series, country_code: nil)\n\n    assert_nil event.country\n  end\n\n  test \"country.name returns English translation when country present\" do\n    event = Event.new(name: \"Test Event\", series: @series, country_code: \"DE\")\n\n    assert_equal \"Germany\", event.country.name\n  end\n\n  test \"country.name returns translation for US\" do\n    event = Event.new(name: \"Test Event\", series: @series, country_code: \"US\")\n\n    assert_equal \"United States\", event.country.name\n  end\n\n  test \"country.path returns country path when country present\" do\n    event = events(:rails_world_2023)\n    event.update!(country_code: \"NL\")\n\n    assert_equal \"/countries/netherlands\", event.country.path\n  end\n\n  test \"grouped_by_country returns countries with their events\" do\n    event = events(:rails_world_2023)\n    event.update!(country_code: \"NL\")\n\n    result = Event.where(id: event.id).grouped_by_country\n\n    assert result.is_a?(Array)\n    assert_equal 1, result.size\n\n    country, events = result.first\n    assert_equal \"NL\", country.alpha2\n    assert_includes events, event\n  end\n\n  test \"grouped_by_country sorts by country name\" do\n    event1 = events(:rails_world_2023)\n    event1.update!(country_code: \"NL\")\n\n    event2 = Event.create!(name: \"Test Event\", country_code: \"DE\", series: @series)\n\n    result = Event.where(id: [event1.id, event2.id]).grouped_by_country\n\n    assert_equal \"DE\", result.first.first.alpha2  # Germany comes before Netherlands\n    assert_equal \"NL\", result.last.first.alpha2\n  end\n\n  test \"grouped_by_country excludes events without country\" do\n    event = events(:rails_world_2023)\n    event.update!(country_code: nil)\n\n    result = Event.where(id: event.id).grouped_by_country\n\n    assert_empty result\n  end\n\n  test \"belongs to city\" do\n    event = events(:rails_world_2023)\n\n    assert_equal \"Amsterdam\", event.city_record.name\n    assert event.city_record.events.include?(event)\n  end\n\n  test \"today? conference is not today\" do\n    event = Event.new(start_date: 3.days.ago, end_date: 2.days.ago, kind: :conference)\n    assert !event.today?\n  end\n\n  test \"today? conference is today\" do\n    event = Event.new(start_date: 1.day.ago, end_date: 2.days.from_now, kind: :conference)\n    assert event.today?\n  end\n\n  test \"today? meetup is not today\" do\n    event = events(:wnb_rb_meetup)\n    talk = talks(:non_english_talk_one)\n    talk.update!(date: 3.days.ago, event: event)\n\n    assert !event.today?\n  end\n\n  test \"today? meetup is today\" do\n    event = events(:wnb_rb_meetup)\n    talk = talks(:non_english_talk_one)\n    talk.update!(date: Date.today, event: event)\n\n    assert event.today?\n  end\nend\n"
  },
  {
    "path": "test/models/favorite_user_test.rb",
    "content": "require \"test_helper\"\n\nclass FavoriteUserTest < ActiveSupport::TestCase\n  test \"mutual_favorite_user association\" do\n    chael = users(:chael)\n    marco = users(:marco)\n\n    favorite1 = FavoriteUser.create!(user: chael, favorite_user: marco)\n    favorite2 = FavoriteUser.create!(user: marco, favorite_user: chael)\n    favorite3 = FavoriteUser.create!(user: chael, favorite_user: users(:yaroslav))\n\n    assert_equal favorite2, favorite1.mutual_favorite_user\n    assert_equal favorite1, favorite2.mutual_favorite_user\n    assert_nil favorite3.mutual_favorite_user\n  end\n\n  test \"build mutual_favorite_user\" do\n    chael = users(:chael)\n    marco = users(:marco)\n\n    favorite1 = FavoriteUser.create!(user: chael, favorite_user: marco)\n    favorite2 = favorite1.build_mutual_favorite_user(user: marco, favorite_user: chael)\n\n    assert_equal marco, favorite2.user\n    assert_equal chael, favorite2.favorite_user\n  end\n\n  test \"recommendations_for user with limited watched talks\" do\n    talk = talks(:lightning_talk)\n    user = users(:chael)\n    WatchedTalk.create!(user: user, talk: talk, progress_seconds: 100)\n    recommendations = FavoriteUser.recommendations_for(user)\n\n    assert recommendations.all? { |fu| fu.user == user }\n    assert_equal 5, recommendations.count\n    assert recommendations.map(&:favorite_user).all? { |speaker| speaker.talks.any? { |talk| user.watched_talks.exists?(talk_id: talk.id) } }\n  end\nend\n"
  },
  {
    "path": "test/models/language_test.rb",
    "content": "require \"test_helper\"\n\nclass LanguageTest < ActiveSupport::TestCase\n  test \"all\" do\n    assert_equal Hash, Language.all.class\n    assert_equal 184, Language.all.length\n  end\n\n  test \"all lookup\" do\n    assert_equal \"English\", Language.all[\"en\"]\n    assert_equal \"French\", Language.all[\"fr\"]\n    assert_equal \"German\", Language.all[\"de\"]\n    assert_equal \"Japanese\", Language.all[\"ja\"]\n    assert_equal \"Portuguese\", Language.all[\"pt\"]\n    assert_equal \"Spanish\", Language.all[\"es\"]\n  end\n\n  test \"alpha2_codes\" do\n    assert_equal Array, Language.alpha2_codes.class\n    assert_equal 184, Language.alpha2_codes.length\n  end\n\n  test \"english_names\" do\n    assert_equal Array, Language.english_names.class\n    assert_equal 184, Language.english_names.length\n  end\n\n  test \"find by full name\" do\n    assert_equal \"en\", Language.find(\"English\").alpha2\n    assert_equal \"en\", Language.find(\"english\").alpha2\n\n    assert_equal \"ja\", Language.find(\"Japanese\").alpha2\n    assert_equal \"ja\", Language.find(\"japanese\").alpha2\n\n    assert_nil Language.find(\"random\")\n    assert_nil Language.find(\"nonexistent\")\n  end\n\n  test \"find by alpha2 code\" do\n    assert_equal \"English\", Language.find(\"en\").english_name\n    assert_equal \"English\", Language.find(\"en\").english_name\n\n    assert_equal \"Japanese\", Language.find(\"ja\").english_name\n    assert_equal \"Japanese\", Language.find(\"ja\").english_name\n  end\n\n  test \"find by alpha3 code\" do\n    assert_equal \"English\", Language.find(\"eng\").english_name\n    assert_equal \"English\", Language.find(\"eng\").english_name\n\n    assert_equal \"Japanese\", Language.find(\"jpn\").english_name\n    assert_equal \"Japanese\", Language.find(\"jpn\").english_name\n  end\n\n  test \"used\" do\n    assert_equal 1, Language.used.length\n    assert_equal [\"en\"], Language.used.keys\n\n    talk = talks(:two)\n    talk.language = \"Spanish\"\n    talk.save\n\n    assert_equal 2, Language.used.length\n    assert_equal [\"en\", \"es\"], Language.used.keys\n  end\n\n  test \"find_by_code\" do\n    record = Language.find_by_code(\"de\")\n\n    assert_not_nil record\n    assert_equal \"de\", record.alpha2\n    assert_equal \"German\", record.english_name\n    assert_equal \"allemand\", record.french_name\n  end\n\n  test \"find_by_code returns nil for invalid code\" do\n    assert_nil Language.find_by_code(\"invalid\")\n    assert_nil Language.find_by_code(\"\")\n  end\n\n  test \"talks returns ActiveRecord relation\" do\n    talks = Language.talks(\"en\")\n\n    assert_kind_of ActiveRecord::Relation, talks\n    assert talks.count >= 0\n  end\n\n  test \"talks filters by language code\" do\n    talk = talks(:one)\n    talk.update!(language: \"ja\")\n\n    japanese_talks = Language.talks(\"ja\")\n\n    assert_includes japanese_talks, talk\n  end\n\n  test \"talks_count returns integer\" do\n    count = Language.talks_count(\"en\")\n\n    assert_kind_of Integer, count\n    assert count >= 0\n  end\n\n  test \"native_name returns native name for known languages\" do\n    assert_equal \"deutsch\", Language.native_name(\"de\")\n    assert_equal \"日本語\", Language.native_name(\"ja\")\n    assert_equal \"español\", Language.native_name(\"es\")\n    assert_equal \"français\", Language.native_name(\"fr\")\n    assert_equal \"português\", Language.native_name(\"pt\")\n    assert_equal \"русский\", Language.native_name(\"ru\")\n    assert_equal \"中文\", Language.native_name(\"zh\")\n  end\n\n  test \"native_name returns nil for unknown languages\" do\n    assert_nil Language.native_name(\"en\")\n    assert_nil Language.native_name(\"invalid\")\n  end\n\n  test \"synonyms_for returns array of synonyms\" do\n    synonyms = Language.synonyms_for(\"de\")\n\n    assert_kind_of Array, synonyms\n    assert_includes synonyms, \"ger\"\n    assert_includes synonyms, \"german\"\n    assert_includes synonyms, \"allemand\"\n    assert_includes synonyms, \"deutsch\"\n  end\n\n  test \"synonyms_for splits multiple names\" do\n    synonyms = Language.synonyms_for(\"es\")\n\n    assert_includes synonyms, \"spanish\"\n    assert_includes synonyms, \"castilian\"\n    assert_includes synonyms, \"espagnol\"\n    assert_includes synonyms, \"castillan\"\n    assert_includes synonyms, \"español\"\n  end\n\n  test \"synonyms_for returns empty array for invalid code\" do\n    assert_equal [], Language.synonyms_for(\"invalid\")\n    assert_equal [], Language.synonyms_for(\"\")\n  end\n\n  test \"all_synonyms returns hash for used languages\" do\n    talk = talks(:one)\n    talk.update!(language: \"ja\")\n\n    synonyms = Language.all_synonyms\n\n    assert_kind_of Hash, synonyms\n    assert synonyms.key?(\"ja-language-synonym\")\n    assert_includes synonyms[\"ja-language-synonym\"][\"synonyms\"], \"ja\"\n    assert_includes synonyms[\"ja-language-synonym\"][\"synonyms\"], \"japanese\"\n    assert_includes synonyms[\"ja-language-synonym\"][\"synonyms\"], \"日本語\"\n  end\nend\n"
  },
  {
    "path": "test/models/location_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass LocationTest < ActiveSupport::TestCase\n  test \".from_record creates location from event fixture\" do\n    event = events(:future_conference)\n    location = Location.from_record(event)\n\n    assert_kind_of Location, location\n    assert_nil location.city if event.city.nil?\n    assert_nil location.state_code if event.state_code.nil?\n    assert_nil location.country_code if event.country_code.nil?\n  end\n\n  test \".from_record creates location with full event data\" do\n    event = OpenStruct.new(\n      city: \"Portland\",\n      state_code: \"OR\",\n      country_code: \"US\",\n      latitude: 45.5,\n      longitude: -122.6,\n      location: \"Portland, OR, USA\"\n    )\n\n    location = Location.from_record(event)\n\n    assert_equal \"Portland\", location.city\n    assert_equal \"OR\", location.state_code\n    assert_equal \"US\", location.country_code\n    assert_equal 45.5, location.latitude\n    assert_equal(-122.6, location.longitude)\n    assert_equal \"Portland, OR, USA\", location.raw_location\n  end\n\n  test \".from_string creates location from raw string\" do\n    location = Location.from_string(\"Paris, France\")\n\n    assert_equal \"Paris, France\", location.raw_location\n    assert_equal \"Paris, France\", location.to_s\n  end\n\n  test \"#geocoded? returns true when lat/lng present\" do\n    location = Location.new(latitude: 45.5, longitude: -122.6)\n    assert location.geocoded?\n  end\n\n  test \"#geocoded? returns false when lat/lng missing\" do\n    location = Location.new(city: \"Portland\")\n    refute location.geocoded?\n  end\n\n  test \"#geocoded? returns false when only latitude present\" do\n    location = Location.new(latitude: 45.5)\n    refute location.geocoded?\n  end\n\n  test \"#state returns State for US location\" do\n    location = Location.new(city: \"Portland\", state_code: \"OR\", country_code: \"US\")\n\n    assert_kind_of State, location.state\n    assert_equal \"OR\", location.state.code\n  end\n\n  test \"#city_object returns City for US location\" do\n    location = Location.new(city: \"Portland\", state_code: \"OR\", country_code: \"US\")\n\n    assert_kind_of City, location.city_object\n    assert_equal \"portland\", location.city_object.slug\n  end\n\n  test \"#state returns State for GB location\" do\n    location = Location.new(city: \"London\", state_code: \"ENG\", country_code: \"GB\")\n\n    assert_kind_of State, location.state\n    assert_equal \"England\", location.state.name\n  end\n\n  test \"#state returns State for AU location\" do\n    location = Location.new(city: \"Sydney\", state_code: \"NSW\", country_code: \"AU\")\n\n    assert_kind_of State, location.state\n    assert_equal \"NSW\", location.state.code\n  end\n\n  test \"#state returns State for CA location\" do\n    location = Location.new(city: \"Toronto\", state_code: \"ON\", country_code: \"CA\")\n\n    assert_kind_of State, location.state\n    assert_equal \"ON\", location.state.code\n  end\n\n  test \"#state returns nil for country without subdivisions\" do\n    location = Location.new(city: \"Oranjestad\", state_code: \"XX\", country_code: \"AW\")\n\n    assert_nil location.state\n  end\n\n  test \"#country returns Country object\" do\n    location = Location.new(country_code: \"US\")\n\n    assert_kind_of Country, location.country\n    assert_equal \"US\", location.country.alpha2\n  end\n\n  test \"#country returns nil without country_code\" do\n    location = Location.new(city: \"Portland\")\n    assert_nil location.country\n  end\n\n  test \"#city_path returns path via city_object\" do\n    location = Location.new(city: \"Portland\", state_code: \"OR\", country_code: \"US\", latitude: 45.5, longitude: -122.6)\n\n    assert_match %r{/cities/}, location.city_path\n  end\n\n  test \"#state_path returns path for US state\" do\n    location = Location.new(state_code: \"OR\", country_code: \"US\")\n\n    assert_equal \"/states/us/oregon\", location.state_path\n  end\n\n  test \"#state_path returns country path for GB nation\" do\n    location = Location.new(state_code: \"ENG\", country_code: \"GB\")\n\n    assert_equal \"/countries/england\", location.state_path\n  end\n\n  test \"#state_path returns nil for country without subdivisions\" do\n    location = Location.new(state_code: \"XX\", country_code: \"AW\")\n\n    assert_nil location.state_path\n  end\n\n  test \"#country_path returns country path\" do\n    location = Location.new(country_code: \"US\")\n\n    assert_equal \"/countries/united-states\", location.country_path\n  end\n\n  test \"#state_display_name returns abbreviation for US state by code\" do\n    location = Location.new(state_code: \"OR\", country_code: \"US\")\n\n    assert_equal \"OR\", location.state_display_name\n  end\n\n  test \"#state_display_name returns abbreviation for US state by name\" do\n    location = Location.new(state_code: \"Oregon\", country_code: \"US\")\n\n    assert_equal \"OR\", location.state_display_name\n  end\n\n  test \"#state_display_name returns full name for GB\" do\n    location = Location.new(state_code: \"ENG\", country_code: \"GB\")\n\n    assert_equal \"England\", location.state_display_name\n  end\n\n  test \"#state_display_name returns raw state for country without subdivisions\" do\n    location = Location.new(state_code: \"XX\", country_code: \"AW\")\n\n    assert_equal \"XX\", location.state_display_name\n  end\n\n  test \"#display_city includes state for US location\" do\n    location = Location.new(city: \"Portland\", state_code: \"OR\", country_code: \"US\")\n\n    assert_equal \"Portland, OR\", location.display_city\n  end\n\n  test \"#display_city returns just city for non-state country\" do\n    location = Location.new(city: \"Paris\", country_code: \"FR\")\n\n    assert_equal \"Paris\", location.display_city\n  end\n\n  test \"#display_city returns state display name when city equals state display\" do\n    location = Location.new(city: \"OR\", state_code: \"OR\", country_code: \"US\")\n\n    assert_equal \"OR\", location.display_city\n  end\n\n  test \"#display_city includes both when city is state full name\" do\n    location = Location.new(city: \"Oregon\", state_code: \"OR\", country_code: \"US\")\n\n    assert_equal \"Oregon, OR\", location.display_city\n  end\n\n  test \"#has_state? returns true when state_path exists\" do\n    location = Location.new(state_code: \"OR\", country_code: \"US\")\n\n    assert location.has_state?\n  end\n\n  test \"#has_state? returns false for country without subdivisions\" do\n    location = Location.new(state_code: \"XX\", country_code: \"AW\")\n\n    refute location.has_state?\n  end\n\n  test \"#has_city? requires both city and country\" do\n    assert Location.new(city: \"Portland\", country_code: \"US\").has_city?\n    refute Location.new(city: \"Portland\").has_city?\n    refute Location.new(country_code: \"US\").has_city?\n  end\n\n  test \"#present? with city\" do\n    assert Location.new(city: \"Portland\").present?\n  end\n\n  test \"#present? with country_code\" do\n    assert Location.new(country_code: \"US\").present?\n  end\n\n  test \"#present? with raw_location\" do\n    assert Location.new(raw_location: \"Somewhere\").present?\n  end\n\n  test \"#blank? when empty\" do\n    assert Location.new.blank?\n  end\n\n  test \"#to_s returns raw_location when present\" do\n    location = Location.new(raw_location: \"Custom Location\", city: \"Portland\", country_code: \"US\")\n\n    assert_equal \"Custom Location\", location.to_s\n  end\n\n  test \"#to_s builds from city and country\" do\n    location = Location.new(city: \"Portland\", state_code: \"OR\", country_code: \"US\")\n\n    assert_equal \"Portland, OR, United States\", location.to_s\n  end\n\n  test \"#to_s returns just country when no city\" do\n    location = Location.new(country_code: \"US\")\n\n    assert_equal \"United States\", location.to_s\n  end\n\n  test \"#to_html returns empty string for blank location\" do\n    location = Location.new\n\n    assert_equal \"\", location.to_html\n  end\n\n  test \"#to_html renders raw text for non-geocoded location\" do\n    location = Location.new(raw_location: \"Somewhere\")\n    html = location.to_html\n\n    assert_includes html, \"Somewhere\"\n    refute_includes html, \"<a\"\n  end\n\n  test \"#to_html renders city, state, country with links for US location\" do\n    location = Location.new(\n      city: \"Portland\",\n      state_code: \"OR\",\n      country_code: \"US\",\n      latitude: 45.5,\n      longitude: -122.6\n    )\n    html = location.to_html\n\n    assert_includes html, \"Portland\"\n    assert_includes html, \"OR\"\n    assert_includes html, \"United States\"\n    assert_includes html, \"<a\"\n    assert_includes html, 'class=\"link\"'\n    assert_equal 3, html.scan(\"<a\").count\n  end\n\n  test \"#to_html renders city, country for non-state country\" do\n    location = Location.new(\n      city: \"Paris\",\n      country_code: \"FR\",\n      latitude: 48.8,\n      longitude: 2.3\n    )\n    html = location.to_html\n\n    assert_includes html, \"Paris\"\n    assert_includes html, \"France\"\n    assert_equal 2, html.scan(\"<a\").count\n  end\n\n  test \"#to_html renders without links when show_links: false\" do\n    location = Location.new(\n      city: \"Portland\",\n      state_code: \"OR\",\n      country_code: \"US\",\n      latitude: 45.5,\n      longitude: -122.6\n    )\n    html = location.to_html(show_links: false)\n\n    refute_includes html, \"<a\"\n    assert_includes html, \"Portland\"\n    assert_includes html, \"OR\"\n    assert_includes html, \"United States\"\n  end\n\n  test \"#to_html uses custom link_class\" do\n    location = Location.new(\n      city: \"Portland\",\n      country_code: \"US\",\n      latitude: 45.5,\n      longitude: -122.6\n    )\n    html = location.to_html(link_class: \"custom-link\")\n\n    assert_includes html, 'class=\"custom-link\"'\n  end\n\n  test \"#to_html renders span for non-geocoded with country\" do\n    location = Location.new(raw_location: \"Paris, France\", country_code: \"FR\")\n    html = location.to_html\n\n    assert_includes html, \"Paris, France\"\n    assert_includes html, \"<span\"\n    refute_includes html, \"<a\"\n  end\n\n  test \"#to_html renders GB nation correctly\" do\n    location = Location.new(\n      city: \"London\",\n      state_code: \"ENG\",\n      country_code: \"GB\",\n      latitude: 51.5,\n      longitude: -0.1\n    )\n    html = location.to_html\n\n    assert_includes html, \"London\"\n    assert_includes html, \"England\"\n    assert_includes html, \"United Kingdom\"\n  end\n\n  test \"#to_html handles AU state\" do\n    location = Location.new(\n      city: \"Sydney\",\n      state_code: \"NSW\",\n      country_code: \"AU\",\n      latitude: -33.8,\n      longitude: 151.2\n    )\n    html = location.to_html\n\n    assert_includes html, \"Sydney\"\n    assert_includes html, \"NSW\"\n    assert_includes html, \"Australia\"\n  end\n\n  test \"#to_html handles CA province\" do\n    location = Location.new(\n      city: \"Toronto\",\n      state_code: \"ON\",\n      country_code: \"CA\",\n      latitude: 43.6,\n      longitude: -79.3\n    )\n    html = location.to_html\n\n    assert_includes html, \"Toronto\"\n    assert_includes html, \"ON\"\n    assert_includes html, \"Canada\"\n  end\n\n  test \"#to_html renders only country when geocoded but no city\" do\n    location = Location.new(\n      country_code: \"US\",\n      latitude: 40.0,\n      longitude: -100.0\n    )\n    html = location.to_html\n\n    assert_includes html, \"United States\"\n    assert_includes html, \"<a\"\n  end\n\n  test \"#to_text returns same as to_s\" do\n    location = Location.new(city: \"Portland\", country_code: \"US\")\n\n    assert_equal location.to_s, location.to_text\n  end\n\n  test \".online creates online location\" do\n    location = Location.online\n\n    assert_equal \"online\", location.raw_location\n    assert location.online?\n  end\n\n  test \"#to_text returns raw_location when nothing else is present\" do\n    location = Location.new(raw_location: \"Custom Location\", city: \"\", country_code: \"\")\n\n    assert_equal \"Custom Location\", location.to_text\n  end\n\n  test \"#online? returns true for 'Online' location\" do\n    location = Location.new(raw_location: \"online\")\n    assert location.online?\n  end\n\n  test \"#online? returns true for 'online' (lowercase)\" do\n    location = Location.new(raw_location: \"online\")\n    assert location.online?\n  end\n\n  test \"#online? returns true for 'virtual'\" do\n    location = Location.new(raw_location: \"virtual\")\n    assert location.online?\n  end\n\n  test \"#online? returns true for 'remote'\" do\n    location = Location.new(raw_location: \"remote\")\n    assert location.online?\n  end\n\n  test \"#online? returns false for geocoded location\" do\n    location = Location.new(raw_location: \"online\", latitude: 45.5, longitude: -122.6)\n    refute location.online?\n  end\n\n  test \"#online? returns false for regular location\" do\n    location = Location.new(raw_location: \"Portland, OR\")\n    refute location.online?\n  end\n\n  test \"#online_path returns online path\" do\n    location = Location.online\n    assert_equal \"/locations/online\", location.online_path\n  end\n\n  test \"#to_html renders online location with link\" do\n    location = Location.online\n    html = location.to_html\n\n    assert_includes html, \"online\"\n    assert_includes html, \"<a\"\n    assert_includes html, \"/online\"\n  end\n\n  test \"#to_html renders online location without link when show_links: false\" do\n    location = Location.online\n    html = location.to_html(show_links: false)\n\n    assert_includes html, \"online\"\n    refute_includes html, \"<a\"\n  end\n\n  test \"#continent returns Continent instance\" do\n    location = Location.new(country_code: \"US\")\n\n    assert_kind_of Continent, location.continent\n    assert_equal \"North America\", location.continent.name\n  end\n\n  test \"#continent returns nil without country\" do\n    location = Location.new(city: \"Portland\")\n\n    assert_nil location.continent\n  end\n\n  test \"#continent_name returns continent name string\" do\n    location = Location.new(country_code: \"US\")\n\n    assert_equal \"North America\", location.continent_name\n  end\n\n  test \"#continent_path returns continent path\" do\n    location = Location.new(country_code: \"FR\")\n\n    assert_equal \"/continents/europe\", location.continent_path\n  end\n\n  test \"#to_html with upto: :city returns just city\" do\n    location = Location.new(\n      city: \"Portland\",\n      state_code: \"OR\",\n      country_code: \"US\",\n      latitude: 45.5,\n      longitude: -122.6\n    )\n    html = location.to_html(upto: :city)\n\n    assert_includes html, \"Portland\"\n    assert_includes html, \"OR\"\n    refute_includes html, \"United States\"\n    assert_equal 1, html.scan(\"<a\").count\n  end\n\n  test \"#to_html with upto: :state returns city and state\" do\n    location = Location.new(\n      city: \"Portland\",\n      state_code: \"OR\",\n      country_code: \"US\",\n      latitude: 45.5,\n      longitude: -122.6\n    )\n    html = location.to_html(upto: :state)\n\n    assert_includes html, \"Portland\"\n    assert_includes html, \"OR\"\n    refute_includes html, \"United States\"\n    assert_equal 2, html.scan(\"<a\").count\n  end\n\n  test \"#to_html with upto: :continent includes continent\" do\n    location = Location.new(\n      city: \"Paris\",\n      country_code: \"FR\",\n      latitude: 48.8,\n      longitude: 2.3\n    )\n    html = location.to_html(upto: :continent)\n\n    assert_includes html, \"Paris\"\n    assert_includes html, \"France\"\n    assert_includes html, \"Europe\"\n    assert_equal 3, html.scan(\"<a\").count\n  end\n\n  test \"#to_html with upto: :continent for US location\" do\n    location = Location.new(\n      city: \"Portland\",\n      state_code: \"OR\",\n      country_code: \"US\",\n      latitude: 45.5,\n      longitude: -122.6\n    )\n    html = location.to_html(upto: :continent)\n\n    assert_includes html, \"Portland\"\n    assert_includes html, \"OR\"\n    assert_includes html, \"United States\"\n    assert_includes html, \"North America\"\n    assert_equal 4, html.scan(\"<a\").count\n  end\n\n  test \"#to_html with upto: :city for non-state country\" do\n    location = Location.new(\n      city: \"Paris\",\n      country_code: \"FR\",\n      latitude: 48.8,\n      longitude: 2.3\n    )\n    html = location.to_html(upto: :city)\n\n    assert_includes html, \"Paris\"\n    refute_includes html, \"France\"\n    assert_equal 1, html.scan(\"<a\").count\n  end\n\n  test \"#to_html with upto: and show_links: false\" do\n    location = Location.new(\n      city: \"Portland\",\n      state_code: \"OR\",\n      country_code: \"US\",\n      latitude: 45.5,\n      longitude: -122.6\n    )\n    html = location.to_html(upto: :continent, show_links: false)\n\n    assert_includes html, \"Portland\"\n    assert_includes html, \"OR\"\n    assert_includes html, \"United States\"\n    assert_includes html, \"North America\"\n    refute_includes html, \"<a\"\n  end\n\n  test \"#to_text returns plain text for location\" do\n    location = Location.new(city: \"Portland\", state_code: \"OR\", country_code: \"US\")\n\n    assert_equal \"Portland, OR, United States\", location.to_text\n  end\n\n  test \"#to_text with upto: :city\" do\n    location = Location.new(city: \"Portland\", state_code: \"OR\", country_code: \"US\")\n\n    assert_equal \"Portland, OR\", location.to_text(upto: :city)\n  end\n\n  test \"#to_text with upto: :state\" do\n    location = Location.new(city: \"Portland\", state_code: \"OR\", country_code: \"US\")\n\n    assert_equal \"Portland, OR\", location.to_text(upto: :state)\n  end\n\n  test \"#to_text with upto: :continent\" do\n    location = Location.new(city: \"Portland\", state_code: \"OR\", country_code: \"US\")\n\n    assert_equal \"Portland, OR, United States, North America\", location.to_text(upto: :continent)\n  end\n\n  test \"#to_text for non-state country\" do\n    location = Location.new(city: \"Paris\", country_code: \"FR\")\n\n    assert_equal \"Paris, France\", location.to_text\n    assert_equal \"Paris\", location.to_text(upto: :city)\n    assert_equal \"Paris, France, Europe\", location.to_text(upto: :continent)\n  end\n\n  test \"#to_text returns Online for online location\" do\n    location = Location.online\n\n    assert_equal \"online\", location.to_text\n  end\n\n  test \"#to_text returns empty string for blank location\" do\n    location = Location.new\n\n    assert_equal \"\", location.to_text\n  end\n\n  test \"#hybrid? returns true when hybrid is true\" do\n    location = Location.new(city: \"Tokyo\", country_code: \"JP\", hybrid: true)\n\n    assert location.hybrid?\n  end\n\n  test \"#hybrid? returns false when hybrid is false\" do\n    location = Location.new(city: \"Tokyo\", country_code: \"JP\", hybrid: false)\n\n    refute location.hybrid?\n  end\n\n  test \"#hybrid? returns false by default\" do\n    location = Location.new(city: \"Tokyo\", country_code: \"JP\")\n\n    refute location.hybrid?\n  end\n\n  test \"#to_html appends & online for hybrid locations\" do\n    location = Location.new(\n      city: \"Tokyo\",\n      country_code: \"JP\",\n      latitude: 35.6,\n      longitude: 139.7,\n      hybrid: true\n    )\n    html = location.to_html\n\n    assert_includes html, \"Tokyo\"\n    assert_includes html, \"Japan\"\n    assert_includes html, \"& \"\n    assert_includes html, \"online\"\n    assert_includes html, \"/online\"\n  end\n\n  test \"#to_html renders hybrid without online link when show_links: false\" do\n    location = Location.new(\n      city: \"Tokyo\",\n      country_code: \"JP\",\n      latitude: 35.6,\n      longitude: 139.7,\n      hybrid: true\n    )\n    html = location.to_html(show_links: false)\n\n    assert_includes html, \"Tokyo\"\n    assert_includes html, \"Japan\"\n    assert_includes html, \"& \"\n    assert_includes html, \"online\"\n    assert_includes html, \"<span\"\n  end\n\n  test \"#to_text appends & online for hybrid locations\" do\n    location = Location.new(\n      city: \"Tokyo\",\n      country_code: \"JP\",\n      hybrid: true\n    )\n\n    assert_equal \"Tokyo, Japan & online\", location.to_text\n  end\n\n  test \"#to_text with upto: option still appends & online for hybrid\" do\n    location = Location.new(\n      city: \"Tokyo\",\n      country_code: \"JP\",\n      hybrid: true\n    )\n\n    assert_equal \"Tokyo & online\", location.to_text(upto: :city)\n    assert_equal \"Tokyo, Japan & online\", location.to_text(upto: :country)\n    assert_equal \"Tokyo, Japan, Asia & online\", location.to_text(upto: :continent)\n  end\n\n  test \"hybrid does not affect online-only locations\" do\n    location = Location.online\n\n    refute location.hybrid?\n    assert_equal \"online\", location.to_text\n  end\n\n  test \"#to_text appends & online for hybrid US location with state\" do\n    location = Location.new(\n      city: \"Portland\",\n      state_code: \"OR\",\n      country_code: \"US\",\n      hybrid: true\n    )\n\n    assert_equal \"Portland, OR, United States & online\", location.to_text\n  end\n\n  test \"#to_text appends & online for hybrid GB location\" do\n    location = Location.new(\n      city: \"London\",\n      state_code: \"ENG\",\n      country_code: \"GB\",\n      hybrid: true\n    )\n\n    assert_equal \"London, England, United Kingdom & online\", location.to_text\n  end\n\n  test \"#to_text appends & online for hybrid country-only location\" do\n    location = Location.new(\n      country_code: \"JP\",\n      hybrid: true\n    )\n\n    assert_equal \"Japan & online\", location.to_text\n  end\n\n  test \"#to_html appends & online for hybrid US location\" do\n    location = Location.new(\n      city: \"Portland\",\n      state_code: \"OR\",\n      country_code: \"US\",\n      latitude: 45.5,\n      longitude: -122.6,\n      hybrid: true\n    )\n    html = location.to_html\n\n    assert_includes html, \"Portland\"\n    assert_includes html, \"OR\"\n    assert_includes html, \"United States\"\n    assert_includes html, \"& \"\n    assert_includes html, \"online\"\n    assert_includes html, \"/online\"\n  end\n\n  test \"#to_html with upto: :city for hybrid location\" do\n    location = Location.new(\n      city: \"Portland\",\n      state_code: \"OR\",\n      country_code: \"US\",\n      latitude: 45.5,\n      longitude: -122.6,\n      hybrid: true\n    )\n    html = location.to_html(upto: :city)\n\n    assert_includes html, \"Portland\"\n    assert_includes html, \"OR\"\n    refute_includes html, \"United States\"\n    assert_includes html, \"& \"\n    assert_includes html, \"online\"\n  end\n\n  test \"#to_html with upto: :continent for hybrid location\" do\n    location = Location.new(\n      city: \"Paris\",\n      country_code: \"FR\",\n      latitude: 48.8,\n      longitude: 2.3,\n      hybrid: true\n    )\n    html = location.to_html(upto: :continent)\n\n    assert_includes html, \"Paris\"\n    assert_includes html, \"France\"\n    assert_includes html, \"Europe\"\n    assert_includes html, \"& \"\n    assert_includes html, \"online\"\n  end\n\n  test \"hybrid with raw_location fallback\" do\n    location = Location.new(\n      raw_location: \"Custom Venue, City\",\n      hybrid: true\n    )\n\n    assert_equal \"Custom Venue, City & online\", location.to_text\n  end\n\n  test \"hybrid with non-geocoded raw_location renders as span\" do\n    location = Location.new(\n      raw_location: \"Conference Center\",\n      hybrid: true\n    )\n    html = location.to_html\n\n    assert_includes html, \"Conference Center\"\n    assert_includes html, \"<span\"\n  end\n\n  test \"hybrid with geocoded country renders country and online\" do\n    location = Location.new(\n      country_code: \"JP\",\n      latitude: 35.6,\n      longitude: 139.7,\n      hybrid: true\n    )\n    html = location.to_html\n\n    assert_includes html, \"Japan\"\n    assert_includes html, \"& \"\n    assert_includes html, \"online\"\n  end\n\n  test \"#from_record preserves hybrid from static_metadata\" do\n    event = OpenStruct.new(\n      city: \"Tokyo\",\n      state_code: nil,\n      country_code: \"JP\",\n      latitude: 35.6,\n      longitude: 139.7,\n      location: \"Tokyo, Japan\",\n      static_metadata: OpenStruct.new(hybrid?: true)\n    )\n\n    location = Location.from_record(event)\n\n    assert location.hybrid?\n    assert_equal \"Tokyo, Japan & online\", location.to_text\n  end\n\n  test \"#from_record defaults hybrid to false when no static_metadata\" do\n    event = OpenStruct.new(\n      city: \"Tokyo\",\n      state_code: nil,\n      country_code: \"JP\",\n      latitude: 35.6,\n      longitude: 139.7,\n      location: \"Tokyo, Japan\"\n    )\n\n    location = Location.from_record(event)\n\n    refute location.hybrid?\n    assert_equal \"Tokyo, Japan\", location.to_text\n  end\nend\n"
  },
  {
    "path": "test/models/online_location_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass OnlineLocationTest < ActiveSupport::TestCase\n  test \"instance returns singleton instance\" do\n    instance1 = OnlineLocation.instance\n    instance2 = OnlineLocation.instance\n\n    assert_same instance1, instance2\n  end\n\n  test \"name returns Online\" do\n    location = OnlineLocation.instance\n\n    assert_equal \"online\", location.name\n  end\n\n  test \"slug returns online\" do\n    location = OnlineLocation.instance\n\n    assert_equal \"online\", location.slug\n  end\n\n  test \"emoji_flag returns globe emoji\" do\n    location = OnlineLocation.instance\n\n    assert_equal location.emoji_flag, location.emoji_flag\n  end\n\n  test \"path returns online path\" do\n    location = OnlineLocation.instance\n\n    assert_equal \"/locations/online\", location.path\n  end\n\n  test \"past_path returns online past path\" do\n    location = OnlineLocation.instance\n\n    assert_equal \"/locations/online/past\", location.past_path\n  end\n\n  test \"users_path returns nil\" do\n    location = OnlineLocation.instance\n\n    assert_nil location.users_path\n  end\n\n  test \"cities_path returns nil\" do\n    location = OnlineLocation.instance\n\n    assert_nil location.cities_path\n  end\n\n  test \"stamps_path returns nil\" do\n    location = OnlineLocation.instance\n\n    assert_nil location.stamps_path\n  end\n\n  test \"map_path returns nil\" do\n    location = OnlineLocation.instance\n\n    assert_nil location.map_path\n  end\n\n  test \"has_routes? returns true\" do\n    location = OnlineLocation.instance\n\n    assert location.has_routes?\n  end\n\n  test \"events returns not geocoded events\" do\n    location = OnlineLocation.instance\n\n    assert location.events.is_a?(ActiveRecord::Relation)\n  end\n\n  test \"users returns empty relation\" do\n    location = OnlineLocation.instance\n\n    assert_equal 0, location.users.count\n  end\n\n  test \"stamps returns empty array\" do\n    location = OnlineLocation.instance\n\n    assert_equal [], location.stamps\n  end\n\n  test \"users_count returns 0\" do\n    location = OnlineLocation.instance\n\n    assert_equal 0, location.users_count\n  end\n\n  test \"geocoded? returns false\" do\n    location = OnlineLocation.instance\n\n    refute location.geocoded?\n  end\n\n  test \"coordinates returns nil\" do\n    location = OnlineLocation.instance\n\n    assert_nil location.coordinates\n  end\n\n  test \"to_coordinates returns nil\" do\n    location = OnlineLocation.instance\n\n    assert_nil location.to_coordinates\n  end\n\n  test \"bounds returns nil\" do\n    location = OnlineLocation.instance\n\n    assert_nil location.bounds\n  end\n\n  test \"to_location returns Location with virtual events text\" do\n    location = OnlineLocation.instance\n    to_location = location.to_location\n\n    assert_kind_of Location, to_location\n    assert_equal \"online\", to_location.to_text\n  end\nend\n"
  },
  {
    "path": "test/models/organization_test.rb",
    "content": "require \"test_helper\"\n\nclass OrganizationTest < ActiveSupport::TestCase\n  test \"should generate slug from name\" do\n    organization = Organization.new(name: \"Example Corp\")\n    organization.valid?\n    assert_equal \"example-corp\", organization.slug\n  end\n\n  test \"should validate presence of name\" do\n    organization = Organization.new(name: \"\")\n    assert_not organization.valid?\n    assert_includes organization.errors[:name], \"can't be blank\"\n  end\n\n  test \"should validate uniqueness of name\" do\n    Organization.create!(name: \"Unique Corp\")\n    duplicate_organization = Organization.new(name: \"Unique Corp\")\n    assert_not duplicate_organization.valid?\n    assert_includes duplicate_organization.errors[:name], \"has already been taken\"\n  end\n\n  test \"should normalize website with https prefix\" do\n    organization = Organization.new(name: \"Test Corp\", website: \"example.com\")\n    organization.save!\n    assert_equal \"https://example.com\", organization.website\n  end\n\n  test \"should preserve https:// prefix in website\" do\n    organization = Organization.new(name: \"Test Corp\", website: \"https://example.com\")\n    organization.save!\n    assert_equal \"https://example.com\", organization.website\n  end\n\n  test \"should preserve http:// prefix in website\" do\n    organization = Organization.new(name: \"Test Corp\", website: \"http://example.com\")\n    organization.save!\n    assert_equal \"http://example.com\", organization.website\n  end\n\n  test \"should handle blank website\" do\n    organization = Organization.new(name: \"Test Corp\", website: \"\")\n    organization.save!\n    assert_equal \"\", organization.website\n  end\n\n  test \"should handle nil website\" do\n    organization = Organization.create!(name: \"Test Corp\", website: nil)\n    assert_nil organization.website\n  end\n\n  test \"should strip query params from website\" do\n    organization = Organization.create!(name: \"Query Corp\", website: \"https://example.com?utm_source=newsletter&ref=123\")\n    assert_equal \"https://example.com\", organization.website\n  end\n\n  test \"should strip fragment from website\" do\n    organization = Organization.create!(name: \"Fragment Corp\", website: \"https://example.com/path#section\")\n    assert_equal \"https://example.com/path\", organization.website\n  end\n\n  test \"should prepend https and strip params if missing scheme\" do\n    organization = Organization.create!(name: \"Coerce Corp\", website: \"example.com/?utm_campaign=abc#top\")\n    assert_equal \"https://example.com/\", organization.website\n  end\n\n  test \"should default to unknown kind\" do\n    organization = Organization.create!(name: \"Default Corp\")\n    assert_equal \"unknown\", organization.kind\n  end\n\n  test \"should allow setting kind to community\" do\n    organization = Organization.create!(name: \"Community Group\", kind: :community)\n    assert_equal \"community\", organization.kind\n  end\n\n  test \"should allow setting kind to foundation\" do\n    organization = Organization.create!(name: \"Test Foundation\", kind: :foundation)\n    assert_equal \"foundation\", organization.kind\n  end\n\n  test \"should allow setting kind to non_profit\" do\n    organization = Organization.create!(name: \"Test Nonprofit\", kind: :non_profit)\n    assert_equal \"non_profit\", organization.kind\n  end\n\n  test \"should default logo_background to white\" do\n    organization = Organization.create!(name: \"Logo Background Corp\")\n    assert_equal \"white\", organization.logo_background\n  end\n\n  test \"should generate correct organization_image_path\" do\n    organization = Organization.create!(name: \"Image Test Corp\")\n    expected_path = \"organizations/#{organization.slug}\"\n    assert_equal expected_path, organization.organization_image_path\n  end\n\n  test \"should generate correct default_organization_image_path\" do\n    organization = Organization.create!(name: \"Default Image Corp\")\n    assert_equal \"organizations/default\", organization.default_organization_image_path\n  end\n\n  test \"should generate correct avatar_image_path\" do\n    organization = Organization.create!(name: \"Avatar Corp\")\n    expected_path = \"organizations/default/avatar.webp\"\n    assert_equal expected_path, organization.avatar_image_path\n  end\n\n  test \"should generate correct banner_image_path\" do\n    organization = Organization.create!(name: \"Banner Corp\")\n    expected_path = \"organizations/default/banner.webp\"\n    assert_equal expected_path, organization.banner_image_path\n  end\n\n  test \"should generate correct logo_image_path\" do\n    organization = Organization.create!(name: \"Logo Corp\")\n    expected_path = \"organizations/default/logo.webp\"\n    assert_equal expected_path, organization.logo_image_path\n  end\n\n  test \"should fallback to logo_url when local logo doesn't exist\" do\n    organization = Organization.create!(name: \"Logo URL Corp\", logo_url: \"https://example.com/logo.png\")\n    assert_equal \"https://example.com/logo.png\", organization.logo_image_path\n  end\n\n  test \"should not add duplicate logo_urls\" do\n    organization = Organization.create!(name: \"Duplicate Logo Corp\")\n    organization.add_logo_url(\"https://example.com/logo.png\")\n    organization.add_logo_url(\"https://example.com/logo.png\")\n\n    assert_equal 1, organization.logo_urls.count\n  end\n\n  test \"should not add blank logo_urls\" do\n    organization = Organization.create!(name: \"Blank Logo Corp\")\n    organization.add_logo_url(\"\")\n    organization.add_logo_url(nil)\n\n    assert_empty organization.logo_urls\n  end\n\n  test \"should ensure unique logo_urls on save\" do\n    organization = Organization.create!(name: \"Unique Logo Corp\")\n    organization.logo_urls = [\"https://example.com/logo.png\", \"https://example.com/logo.png\", \"https://example.com/other.png\"]\n    organization.save!\n\n    assert_equal 2, organization.logo_urls.count\n    assert_includes organization.logo_urls, \"https://example.com/logo.png\"\n    assert_includes organization.logo_urls, \"https://example.com/other.png\"\n  end\n\n  test \"find_by_name_or_alias finds organization by name\" do\n    organization = Organization.create!(name: \"Name Test Corp\")\n\n    found_organization = Organization.find_by_name_or_alias(\"Name Test Corp\")\n    assert_equal organization.id, found_organization.id\n  end\n\n  test \"find_by_name_or_alias finds organization by alias name\" do\n    organization = Organization.create!(name: \"Current Corp Name\")\n    organization.aliases.create!(name: \"Old Corp Name\", slug: \"old-corp-name\")\n\n    found_organization = Organization.find_by_name_or_alias(\"Old Corp Name\")\n    assert_equal organization.id, found_organization.id\n  end\n\n  test \"find_by_name_or_alias returns nil for non-existent name\" do\n    found_organization = Organization.find_by_name_or_alias(\"Nonexistent Corp\")\n    assert_nil found_organization\n  end\n\n  test \"find_by_name_or_alias returns nil for blank name\" do\n    assert_nil Organization.find_by_name_or_alias(\"\")\n    assert_nil Organization.find_by_name_or_alias(nil)\n  end\n\n  test \"find_by_name_or_alias prioritizes name over alias\" do\n    org1 = Organization.create!(name: \"Real Corp\")\n    org2 = Organization.create!(name: \"Other Corp\")\n    org2.aliases.create!(name: \"Real Corp Alias\", slug: \"real-corp\")\n\n    found_organization = Organization.find_by_name_or_alias(\"Real Corp\")\n    assert_equal org1.id, found_organization.id\n  end\n\n  test \"find_by_slug_or_alias finds organization by slug\" do\n    organization = Organization.create!(name: \"Slug Test Corp\")\n\n    found_organization = Organization.find_by_slug_or_alias(organization.slug)\n    assert_equal organization.id, found_organization.id\n  end\n\n  test \"find_by_slug_or_alias finds organization by alias slug\" do\n    organization = Organization.create!(name: \"Primary Corp\")\n    organization.aliases.create!(name: \"Old Corp Name\", slug: \"old-corp\")\n\n    found_organization = Organization.find_by_slug_or_alias(\"old-corp\")\n    assert_equal organization.id, found_organization.id\n  end\n\n  test \"find_by_slug_or_alias returns nil for non-existent slug\" do\n    found_organization = Organization.find_by_slug_or_alias(\"nonexistent-slug\")\n    assert_nil found_organization\n  end\n\n  test \"find_by_slug_or_alias returns nil for blank slug\" do\n    assert_nil Organization.find_by_slug_or_alias(\"\")\n    assert_nil Organization.find_by_slug_or_alias(nil)\n  end\n\n  test \"find_by_slug_or_alias prioritizes slug over alias\" do\n    org1 = Organization.create!(name: \"Organization One\")\n    org2 = Organization.create!(name: \"Organization Two\")\n    org2.aliases.create!(name: \"Alias\", slug: org1.slug)\n\n    found_organization = Organization.find_by_slug_or_alias(org1.slug)\n    assert_equal org1.id, found_organization.id\n  end\nend\n"
  },
  {
    "path": "test/models/rollup_test.rb",
    "content": "require \"test_helper\"\n\nclass RollupTest < ActiveSupport::TestCase\n  def setup\n    @rollup = Rollup.new(name: \"Test Rollup\", interval: \"day\", time: Time.now)\n  end\n\n  test \"should be valid with valid attributes\" do\n    assert @rollup.valid?\n  end\n\n  test \"should require a name\" do\n    @rollup.name = nil\n    assert_not @rollup.valid?\n  end\n\n  test \"should require an interval\" do\n    @rollup.interval = nil\n    assert_not @rollup.valid?\n  end\n\n  test \"should require a time\" do\n    @rollup.time = nil\n    assert_not @rollup.valid?\n  end\n\n  test \"time_zone should return default time zone if not set\" do\n    assert Rollup.time_zone.is_a?(ActiveSupport::TimeZone)\n  end\n\n  test \"series method should return correct series\" do\n    Rollup.create(name: \"Test Rollup\", interval: \"day\", time: Time.now, value: 1)\n    series = Rollup.series(\"Test Rollup\", interval: \"day\")\n    assert_not_empty series\n  end\n\n  test \"rename method should update rollup names\" do\n    Rollup.create!(name: \"Old Name\", interval: \"day\", time: Time.now)\n    Rollup.rename(\"Old Name\", \"New Name\")\n    assert Rollup.where(name: \"New Name\").exists?\n    assert_not Rollup.where(name: \"Old Name\").exists?\n  end\nend\n"
  },
  {
    "path": "test/models/search/backend/sqlite_fts/indexer_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Search::Backend::SQLiteFTS::IndexerTest < ActiveSupport::TestCase\n  setup do\n    @talk = talks(:one)\n    @user = users(:one)\n  end\n\n  test \"index handles a talk without raising\" do\n    assert_nothing_raised do\n      Search::Backend::SQLiteFTS::Indexer.index(@talk)\n    end\n  end\n\n  test \"index handles a user without raising\" do\n    assert_nothing_raised do\n      Search::Backend::SQLiteFTS::Indexer.index(@user)\n    end\n  end\n\n  test \"remove handles a talk without raising\" do\n    assert_nothing_raised do\n      Search::Backend::SQLiteFTS::Indexer.remove(@talk)\n    end\n  end\n\n  test \"remove handles a user without raising\" do\n    assert_nothing_raised do\n      Search::Backend::SQLiteFTS::Indexer.remove(@user)\n    end\n  end\nend\n"
  },
  {
    "path": "test/models/search/backend/sqlite_fts_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Search::Backend::SQLiteFTSTest < ActiveSupport::TestCase\n  test \"available? returns true\" do\n    assert Search::Backend::SQLiteFTS.available?\n  end\n\n  test \"name returns :sqlite_fts\" do\n    assert_equal :sqlite_fts, Search::Backend::SQLiteFTS.name\n  end\n\n  test \"search_talks returns results and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_talks(\"ruby\", limit: 10)\n\n    assert_kind_of ActiveRecord::Relation, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_talks respects limit\" do\n    results, _count = Search::Backend::SQLiteFTS.search_talks(\"ruby\", limit: 1)\n\n    assert results.size <= 1\n  end\n\n  test \"search_speakers returns results and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_speakers(\"test\", limit: 10)\n\n    assert_kind_of ActiveRecord::Relation, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_events returns results and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_events(\"conference\", limit: 10)\n\n    assert_kind_of ActiveRecord::Relation, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_topics returns results and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_topics(\"record\", limit: 10)\n\n    assert_kind_of ActiveRecord::Relation, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_series returns results and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_series(\"rails\", limit: 10)\n\n    assert_kind_of ActiveRecord::Relation, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_organizations returns results and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_organizations(\"ruby\", limit: 10)\n\n    assert_kind_of ActiveRecord::Relation, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_languages returns array and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_languages(\"german\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_languages returns empty for blank query\" do\n    results, count = Search::Backend::SQLiteFTS.search_languages(\"\", limit: 10)\n\n    assert_equal [], results\n    assert_equal 0, count\n  end\n\n  test \"search_locations returns array and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_locations(\"united\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_locations returns empty for blank query\" do\n    results, count = Search::Backend::SQLiteFTS.search_locations(\"\", limit: 10)\n\n    assert_equal [], results\n    assert_equal 0, count\n  end\n\n  test \"search_continents returns array and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_continents(\"europe\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_continents returns empty for blank query\" do\n    results, count = Search::Backend::SQLiteFTS.search_continents(\"\", limit: 10)\n\n    assert_equal [], results\n    assert_equal 0, count\n  end\n\n  test \"search_countries returns array and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_countries(\"united\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_countries returns empty for blank query\" do\n    results, count = Search::Backend::SQLiteFTS.search_countries(\"\", limit: 10)\n\n    assert_equal [], results\n    assert_equal 0, count\n  end\n\n  test \"search_states returns array and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_states(\"california\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_states returns empty for blank query\" do\n    results, count = Search::Backend::SQLiteFTS.search_states(\"\", limit: 10)\n\n    assert_equal [], results\n    assert_equal 0, count\n  end\n\n  test \"search_cities returns array and count\" do\n    results, count = Search::Backend::SQLiteFTS.search_cities(\"new york\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_cities returns empty for blank query\" do\n    results, count = Search::Backend::SQLiteFTS.search_cities(\"\", limit: 10)\n\n    assert_equal [], results\n    assert_equal 0, count\n  end\nend\n"
  },
  {
    "path": "test/models/search/backend/typesense/indexer_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Search::Backend::Typesense::IndexerTest < ActiveSupport::TestCase\n  test \"indexer class exists\" do\n    assert defined?(Search::Backend::Typesense::Indexer)\n  end\n\n  test \"indexer responds to index\" do\n    assert Search::Backend::Typesense::Indexer.respond_to?(:index)\n  end\n\n  test \"indexer responds to remove\" do\n    assert Search::Backend::Typesense::Indexer.respond_to?(:remove)\n  end\n\n  test \"indexer responds to reindex_all\" do\n    assert Search::Backend::Typesense::Indexer.respond_to?(:reindex_all)\n  end\n\n  test \"indexer responds to reindex_talks\" do\n    assert Search::Backend::Typesense::Indexer.respond_to?(:reindex_talks)\n  end\n\n  test \"indexer responds to reindex_users\" do\n    assert Search::Backend::Typesense::Indexer.respond_to?(:reindex_users)\n  end\n\n  test \"indexer responds to reindex_events\" do\n    assert Search::Backend::Typesense::Indexer.respond_to?(:reindex_events)\n  end\n\n  test \"indexer responds to reindex_topics\" do\n    assert Search::Backend::Typesense::Indexer.respond_to?(:reindex_topics)\n  end\n\n  test \"indexer responds to reindex_series\" do\n    assert Search::Backend::Typesense::Indexer.respond_to?(:reindex_series)\n  end\n\n  test \"indexer responds to reindex_organizations\" do\n    assert Search::Backend::Typesense::Indexer.respond_to?(:reindex_organizations)\n  end\nend\n"
  },
  {
    "path": "test/models/search/backend/typesense/language_indexer_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Search::Backend::Typesense::LanguageIndexerTest < ActiveSupport::TestCase\n  test \"language indexer class exists\" do\n    assert defined?(Search::Backend::Typesense::LanguageIndexer)\n  end\n\n  test \"collection_schema returns valid schema\" do\n    schema = Search::Backend::Typesense::LanguageIndexer.collection_schema\n\n    assert_equal \"languages\", schema[\"name\"]\n    assert_kind_of Array, schema[\"fields\"]\n    assert schema[\"fields\"].any? { |f| f[\"name\"] == \"id\" }\n    assert schema[\"fields\"].any? { |f| f[\"name\"] == \"code\" }\n    assert schema[\"fields\"].any? { |f| f[\"name\"] == \"name\" }\n    assert schema[\"fields\"].any? { |f| f[\"name\"] == \"emoji_flag\" }\n    assert schema[\"fields\"].any? { |f| f[\"name\"] == \"talk_count\" }\n  end\n\n  test \"collection_schema has correct default_sorting_field\" do\n    schema = Search::Backend::Typesense::LanguageIndexer.collection_schema\n\n    assert_equal \"talk_count\", schema[\"default_sorting_field\"]\n  end\n\n  test \"responds to reindex_all\" do\n    assert Search::Backend::Typesense::LanguageIndexer.respond_to?(:reindex_all)\n  end\n\n  test \"responds to index_languages\" do\n    assert Search::Backend::Typesense::LanguageIndexer.respond_to?(:index_languages)\n  end\n\n  test \"responds to search\" do\n    assert Search::Backend::Typesense::LanguageIndexer.respond_to?(:search)\n  end\n\n  test \"responds to create_synonyms!\" do\n    assert Search::Backend::Typesense::LanguageIndexer.respond_to?(:create_synonyms!)\n  end\n\n  test \"responds to drop_collection!\" do\n    assert Search::Backend::Typesense::LanguageIndexer.respond_to?(:drop_collection!)\n  end\n\n  test \"responds to ensure_collection!\" do\n    assert Search::Backend::Typesense::LanguageIndexer.respond_to?(:ensure_collection!)\n  end\n\n  test \"build_language_documents returns array\" do\n    documents = Search::Backend::Typesense::LanguageIndexer.send(:build_language_documents)\n\n    assert_kind_of Array, documents\n  end\n\n  test \"build_language_documents contains expected fields\" do\n    documents = Search::Backend::Typesense::LanguageIndexer.send(:build_language_documents)\n\n    skip \"No talks with languages in test data\" if documents.empty?\n\n    document = documents.first\n\n    assert document.key?(:id)\n    assert document.key?(:code)\n    assert document.key?(:name)\n    assert document.key?(:emoji_flag)\n    assert document.key?(:talk_count)\n  end\n\n  test \"build_language_documents id is prefixed with language_\" do\n    documents = Search::Backend::Typesense::LanguageIndexer.send(:build_language_documents)\n\n    skip \"No talks with languages in test data\" if documents.empty?\n\n    documents.each do |document|\n      assert document[:id].start_with?(\"language_\"), \"Expected id to start with 'language_', got: #{document[:id]}\"\n    end\n  end\n\n  test \"build_language_documents talk_count is an integer\" do\n    documents = Search::Backend::Typesense::LanguageIndexer.send(:build_language_documents)\n\n    skip \"No talks with languages in test data\" if documents.empty?\n\n    documents.each do |document|\n      assert_kind_of Integer, document[:talk_count]\n    end\n  end\nend\n"
  },
  {
    "path": "test/models/search/backend/typesense/location_indexer_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Search::Backend::Typesense::LocationIndexerTest < ActiveSupport::TestCase\n  test \"location indexer class exists\" do\n    assert defined?(Search::Backend::Typesense::LocationIndexer)\n  end\n\n  test \"collection_schema returns valid schema\" do\n    schema = Search::Backend::Typesense::LocationIndexer.collection_schema\n\n    assert_equal \"locations\", schema[\"name\"]\n    assert_kind_of Array, schema[\"fields\"]\n    assert schema[\"fields\"].any? { |f| f[\"name\"] == \"name\" }\n    assert schema[\"fields\"].any? { |f| f[\"name\"] == \"type\" }\n    assert schema[\"fields\"].any? { |f| f[\"name\"] == \"event_count\" }\n  end\n\n  test \"responds to reindex_all\" do\n    assert Search::Backend::Typesense::LocationIndexer.respond_to?(:reindex_all)\n  end\n\n  test \"responds to index_continents\" do\n    assert Search::Backend::Typesense::LocationIndexer.respond_to?(:index_continents)\n  end\n\n  test \"responds to index_countries\" do\n    assert Search::Backend::Typesense::LocationIndexer.respond_to?(:index_countries)\n  end\n\n  test \"responds to index_states\" do\n    assert Search::Backend::Typesense::LocationIndexer.respond_to?(:index_states)\n  end\n\n  test \"responds to index_cities\" do\n    assert Search::Backend::Typesense::LocationIndexer.respond_to?(:index_cities)\n  end\n\n  test \"responds to search\" do\n    assert Search::Backend::Typesense::LocationIndexer.respond_to?(:search)\n  end\n\n  test \"build_continent_documents returns array\" do\n    documents = Search::Backend::Typesense::LocationIndexer.send(:build_continent_documents)\n\n    assert_kind_of Array, documents\n  end\n\n  test \"build_country_documents returns array\" do\n    documents = Search::Backend::Typesense::LocationIndexer.send(:build_country_documents)\n\n    assert_kind_of Array, documents\n  end\n\n  test \"build_state_documents returns array\" do\n    documents = Search::Backend::Typesense::LocationIndexer.send(:build_state_documents)\n\n    assert_kind_of Array, documents\n  end\n\n  test \"build_city_documents returns array\" do\n    documents = Search::Backend::Typesense::LocationIndexer.send(:build_city_documents)\n\n    assert_kind_of Array, documents\n  end\nend\n"
  },
  {
    "path": "test/models/search/backend/typesense_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Search::Backend::TypesenseTest < ActiveSupport::TestCase\n  test \"name returns :typesense\" do\n    assert_equal :typesense, Search::Backend::Typesense.name\n  end\n\n  test \"search_languages delegates to SQLiteFTS\" do\n    results, count = Search::Backend::Typesense.search_languages(\"german\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_locations delegates to SQLiteFTS\" do\n    results, count = Search::Backend::Typesense.search_locations(\"united\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_continents delegates to SQLiteFTS\" do\n    results, count = Search::Backend::Typesense.search_continents(\"europe\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_countries delegates to SQLiteFTS\" do\n    results, count = Search::Backend::Typesense.search_countries(\"united\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_states delegates to SQLiteFTS\" do\n    results, count = Search::Backend::Typesense.search_states(\"california\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\n\n  test \"search_cities delegates to SQLiteFTS\" do\n    results, count = Search::Backend::Typesense.search_cities(\"new york\", limit: 10)\n\n    assert_kind_of Array, results\n    assert_kind_of Integer, count\n  end\nend\n"
  },
  {
    "path": "test/models/search/backend_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Search::BackendTest < ActiveSupport::TestCase\n  test \"resolve returns SQLiteFTS by default in test environment\" do\n    assert_equal Search::Backend::SQLiteFTS, Search::Backend.resolve\n  end\n\n  test \"resolve returns SQLiteFTS when preferred is sqlite_fts\" do\n    assert_equal Search::Backend::SQLiteFTS, Search::Backend.resolve(:sqlite_fts)\n  end\n\n  test \"resolve returns SQLiteFTS when preferred is sqlite_fts string\" do\n    assert_equal Search::Backend::SQLiteFTS, Search::Backend.resolve(\"sqlite_fts\")\n  end\n\n  test \"resolve returns default backend for unknown preference\" do\n    assert_equal Search::Backend::SQLiteFTS, Search::Backend.resolve(:unknown)\n  end\n\n  test \"backends hash contains both backends\" do\n    assert_equal Search::Backend::SQLiteFTS, Search::Backend.backends[:sqlite_fts]\n  end\n\n  test \"index does not raise for valid record\" do\n    record = talks(:one)\n\n    assert_nothing_raised do\n      Search::Backend.index(record)\n    end\n  end\n\n  test \"remove does not raise for valid record\" do\n    record = talks(:one)\n\n    assert_nothing_raised do\n      Search::Backend.remove(record)\n    end\n  end\nend\n"
  },
  {
    "path": "test/models/sponsor_test.rb",
    "content": "require \"test_helper\"\n\nclass SponsorTest < ActiveSupport::TestCase\n  def setup\n    @event = events(:railsconf_2017)\n    @other_event = events(:rubyconfth_2022)\n    @organization = organizations(:one)\n    @other_organization = organizations(:two)\n  end\n\n  test \"allows same organization for same event with different tiers\" do\n    assert_nothing_raised do\n      Sponsor.create!(event: @event, organization: @organization, tier: \"platinum\")\n    end\n  end\n\n  test \"prevents duplicate organization for same event and tier\" do\n    duplicate = Sponsor.new(event: @event, organization: @organization, tier: \"gold\")\n\n    assert_not duplicate.valid?\n    assert_includes duplicate.errors[:organization_id], \"is already associated with this event for the same tier\"\n  end\n\n  test \"allows same organization for different events with same tier\" do\n    Sponsor.create!(event: @event, organization: @other_organization, tier: \"diamond\")\n\n    assert_nothing_raised do\n      Sponsor.create!(event: @other_event, organization: @other_organization, tier: \"diamond\")\n    end\n  end\n\n  test \"handles nil tiers correctly\" do\n    org = Organization.create!(name: \"Nil Tier Test Org\")\n    Sponsor.create!(event: @event, organization: org, tier: nil)\n\n    duplicate = Sponsor.new(event: @event, organization: org, tier: nil)\n\n    assert_not duplicate.valid?\n    assert_includes duplicate.errors[:organization_id],\n      \"is already associated with this event for the same tier\"\n  end\n\n  test \"treats empty string tier as nil\" do\n    org = Organization.create!(name: \"Empty Tier Test Org\")\n    Sponsor.create!(event: @event, organization: org, tier: \"\")\n\n    duplicate = Sponsor.new(event: @event, organization: org, tier: nil)\n\n    assert_not duplicate.valid?\n  end\n\n  test \"belongs to event\" do\n    sponsor = sponsors(:one)\n    assert_instance_of Event, sponsor.event\n  end\n\n  test \"belongs to organization\" do\n    sponsor = sponsors(:one)\n    assert_instance_of Organization, sponsor.organization\n  end\n\n  test \"requires event\" do\n    sponsor = Sponsor.new(organization: @organization, tier: \"gold\")\n    assert_not sponsor.valid?\n    assert_includes sponsor.errors[:event], \"must exist\"\n  end\n\n  test \"requires organization\" do\n    sponsor = Sponsor.new(event: @event, tier: \"gold\")\n    assert_not sponsor.valid?\n    assert_includes sponsor.errors[:organization], \"must exist\"\n  end\nend\n"
  },
  {
    "path": "test/models/state_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass StateTest < ActiveSupport::TestCase\n  test \"find returns State for valid US state\" do\n    country = Country.find(\"US\")\n    state = State.find(country: country, term: \"OR\")\n\n    assert_not_nil state\n    assert_equal \"OR\", state.code\n    assert_equal \"Oregon\", state.name\n  end\n\n  test \"find returns State for full state name\" do\n    country = Country.find(\"US\")\n    state = State.find(country: country, term: \"Oregon\")\n\n    assert_not_nil state\n    assert_equal \"OR\", state.code\n  end\n\n  test \"find returns State for state slug\" do\n    country = Country.find(\"US\")\n    state = State.find(country: country, term: \"oregon\")\n\n    assert_not_nil state\n    assert_equal \"OR\", state.code\n  end\n\n  test \"find returns nil for blank term\" do\n    country = Country.find(\"US\")\n\n    assert_nil State.find(country: country, term: nil)\n    assert_nil State.find(country: country, term: \"\")\n  end\n\n  test \"find returns nil for excluded country\" do\n    country = Country.find(\"PL\")\n\n    assert_nil State.find(country: country, term: \"Warsaw\")\n  end\n\n  test \"find_by_code returns State for code\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n\n    assert_not_nil state\n    assert_equal \"Oregon\", state.name\n  end\n\n  test \"find_by_name returns State for name\" do\n    state = State.find_by_name(\"Oregon\", country: Country.find(\"US\"))\n\n    assert_not_nil state\n    assert_equal \"OR\", state.code\n  end\n\n  test \"for_country returns array of States\" do\n    country = Country.find(\"US\")\n    states = State.for_country(country)\n\n    assert states.is_a?(Array)\n    assert states.any?\n    assert states.first.is_a?(State)\n  end\n\n  test \"supported_country? returns true for US\" do\n    country = Country.find(\"US\")\n\n    assert State.supported_country?(country)\n  end\n\n  test \"supported_country? returns false for excluded countries\" do\n    country = Country.find(\"PL\")\n\n    refute State.supported_country?(country)\n  end\n\n  test \"name returns English translation\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n\n    assert_equal \"Oregon\", state.name\n  end\n\n  test \"code returns state code\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n\n    assert_equal \"OR\", state.code\n  end\n\n  test \"slug returns parameterized name\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n\n    assert_equal \"oregon\", state.slug\n  end\n\n  test \"display_name returns abbreviation for US states\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n\n    assert_equal \"OR\", state.display_name\n  end\n\n  test \"display_name returns full name for GB nations\" do\n    state = State.find_by_code(\"ENG\", country: Country.find(\"GB\"))\n\n    assert_equal \"England\", state.display_name\n  end\n\n  test \"path returns states path for US state\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n\n    assert_equal \"/states/us/oregon\", state.path\n  end\n\n  test \"path returns countries path for GB nation\" do\n    state = State.find_by_code(\"ENG\", country: Country.find(\"GB\"))\n\n    assert_equal \"/countries/england\", state.path\n  end\n\n  test \"to_param returns slug\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n\n    assert_equal \"oregon\", state.to_param\n  end\n\n  test \"country returns associated Country\" do\n    country = Country.find(\"US\")\n    state = State.find_by_code(\"OR\", country: country)\n\n    assert_equal country, state.country\n  end\n\n  test \"alpha2 returns country alpha2\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n\n    assert_equal \"US\", state.alpha2\n  end\n\n  test \"two states with same code and country are equal\" do\n    country = Country.find(\"US\")\n    state1 = State.find_by_code(\"OR\", country: country)\n    state2 = State.find_by_code(\"OR\", country: country)\n\n    assert_equal state1, state2\n  end\n\n  test \"two states with different codes are not equal\" do\n    country = Country.find(\"US\")\n    state1 = State.find_by_code(\"OR\", country: country)\n    state2 = State.find_by_code(\"CA\", country: country)\n\n    assert_not_equal state1, state2\n  end\n\n  test \"events returns ActiveRecord::Relation\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n\n    assert state.events.is_a?(ActiveRecord::Relation)\n  end\n\n  test \"users returns ActiveRecord::Relation\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n\n    assert state.users.is_a?(ActiveRecord::Relation)\n  end\n\n  test \"to_location returns Location with state and country\" do\n    state = State.find_by_code(\"OR\", country: Country.find(\"US\"))\n    location = state.to_location\n\n    assert_kind_of Location, location\n    assert_equal \"OR, United States\", location.to_text\n  end\n\n  test \"to_location for GB nation\" do\n    state = State.find_by_code(\"ENG\", country: Country.find(\"GB\"))\n    location = state.to_location\n\n    assert_equal \"England, United Kingdom\", location.to_text\n  end\n\n  test \"to_location for AU state\" do\n    state = State.find_by_code(\"NSW\", country: Country.find(\"AU\"))\n    location = state.to_location\n\n    assert_equal \"NSW, Australia\", location.to_text\n  end\n\n  test \"to_location for CA province\" do\n    state = State.find_by_code(\"ON\", country: Country.find(\"CA\"))\n    location = state.to_location\n\n    assert_equal \"ON, Canada\", location.to_text\n  end\nend\n"
  },
  {
    "path": "test/models/static/city_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire \"test_helper\"\n\nclass Static::CityTest < ActiveSupport::TestCase\n  def create_city(name:, country_code:, state_code: nil, **attrs)\n    city = City.new(\n      name: name,\n      country_code: country_code,\n      state_code: state_code,\n      latitude: attrs[:latitude] || 45.5,\n      longitude: attrs[:longitude] || -122.6,\n      geocode_metadata: attrs[:geocode_metadata] || {\"geocoder_city\" => name},\n      featured: attrs.fetch(:featured, false)\n    )\n\n    city.define_singleton_method(:geocode) {}\n    city.save!\n\n    city\n  end\n\n  def reload_city(city)\n    City.find_by(id: city.id)\n  end\n\n  test \"import! creates a new city when none exists\" do\n    static_city = Static::City.find_by(slug: \"zurich\")\n\n    assert_difference \"City.count\", 1 do\n      static_city.import!(index: false)\n    end\n\n    city = City.find_by(slug: \"zurich\")\n    assert_equal \"Zurich\", city.name\n    assert_equal \"CH\", city.country_code\n    assert city.featured?\n  end\n\n  test \"import! finds existing city by slug\" do\n    existing = create_city(name: \"Old Zurich Name\", country_code: \"CH\", state_code: \"ZH\")\n    existing.update!(slug: \"zurich\")\n\n    static_city = Static::City.find_by(slug: \"zurich\")\n\n    assert_no_difference \"City.count\" do\n      static_city.import!(index: false)\n    end\n\n    updated = reload_city(existing)\n    assert_equal \"Zurich\", updated.name\n    assert updated.featured?\n  end\n\n  test \"import! finds existing city by exact name\" do\n    existing = create_city(name: \"Zurich\", country_code: \"CH\", state_code: \"ZH\")\n    existing.update!(slug: \"different-slug\")\n\n    static_city = Static::City.find_by(slug: \"zurich\")\n\n    assert_no_difference \"City.count\" do\n      static_city.import!(index: false)\n    end\n\n    updated = reload_city(existing)\n    assert_equal \"zurich\", updated.slug\n    assert updated.featured?\n  end\n\n  test \"import! finds existing city when YAML alias matches city name (case-insensitive)\" do\n    existing = create_city(name: \"Zürich\", country_code: \"CH\", state_code: \"ZH\")\n    existing.update!(slug: \"zuerich-geocoded\")\n\n    static_city = Static::City.find_by(slug: \"zurich\")\n\n    assert_no_difference \"City.count\" do\n      static_city.import!(index: false)\n    end\n\n    updated = reload_city(existing)\n\n    assert_equal \"Zurich\", updated.name\n    assert_equal \"zurich\", updated.slug\n    assert updated.featured?\n  end\n\n  test \"import! finds existing city when YAML alias matches city name zrh\" do\n    existing = create_city(name: \"ZRH\", country_code: \"CH\", state_code: \"ZH\")\n    existing.update!(slug: \"zrh-airport\")\n\n    static_city = Static::City.find_by(slug: \"zurich\")\n\n    assert_no_difference \"City.count\" do\n      static_city.import!(index: false)\n    end\n\n    updated = reload_city(existing)\n    assert_equal \"Zurich\", updated.name\n    assert updated.featured?\n  end\n\n  test \"import! finds existing city when YAML alias matches existing database alias\" do\n    existing = create_city(name: \"Zuerich\", country_code: \"CH\", state_code: \"ZH\")\n    existing.update!(slug: \"zuerich-old\")\n    existing.sync_aliases_from_list([\"Zürich\"])\n\n    static_city = Static::City.find_by(slug: \"zurich\")\n\n    assert_no_difference \"City.count\" do\n      static_city.import!(index: false)\n    end\n\n    updated = reload_city(existing)\n    assert_equal \"Zurich\", updated.name\n    assert updated.featured?\n  end\n\n  test \"import! syncs aliases from YAML\" do\n    static_city = Static::City.find_by(slug: \"zurich\")\n    static_city.import!(index: false)\n\n    city = City.find_by(slug: \"zurich\")\n    city_aliases = Alias.where(aliasable_type: \"City\", aliasable_id: city.id).pluck(:name)\n\n    assert_includes city_aliases, \"ZRH\"\n    assert_includes city_aliases, \"Zürich\"\n  end\n\n  test \"import! does not create duplicate city for Zürich alias variation\" do\n    static_city = Static::City.find_by(slug: \"zurich\")\n    static_city.import!(index: false)\n\n    result = City.find_or_create_for(city: \"Zürich\", country_code: \"CH\", state_code: \"ZH\")\n\n    assert_equal 1, City.where(country_code: \"CH\").where(\"LOWER(name) LIKE ?\", \"%zurich%\").count\n    assert_equal \"Zurich\", result.name\n  end\n\n  test \"import! does not create duplicate city for ZRH alias variation\" do\n    static_city = Static::City.find_by(slug: \"zurich\")\n    static_city.import!(index: false)\n\n    result = City.find_or_create_for(city: \"ZRH\", country_code: \"CH\", state_code: \"ZH\")\n\n    assert_equal 1, City.where(country_code: \"CH\").where(\"LOWER(name) LIKE ?\", \"%zurich%\").count\n    assert_equal \"Zurich\", result.name\n  end\nend\n"
  },
  {
    "path": "test/models/static/event_test.rb",
    "content": "require \"test_helper\"\n\nclass Static::EventTest < ActiveSupport::TestCase\n  test \"import_involvements!\" do\n    event = Static::Event.find_by_slug(\"xoruby-portland-2025\")\n    event.import_event!\n    event_record = event.event_record\n    event.import_involvements!(event_record)\n    involvements = event_record.reload.event_involvements.pluck(:id)\n    event.import_involvements!(event_record)\n    assert_equal involvements, event_record.reload.event_involvements.pluck(:id)\n    assert_equal 6, event_record.event_involvements.count\n  end\n\n  test \"today? returns false if event is in the past\" do\n    event = Static::Event.find_by_slug(\"railsconf-2025\")\n    assert_not event.today?\n  end\nend\n"
  },
  {
    "path": "test/models/suggestion_test.rb",
    "content": "require \"test_helper\"\n\nclass SuggestionTest < ActiveSupport::TestCase\n  setup do\n    @talk = talks(:one)\n  end\n\n  test \"serialize the content\" do\n    suggestion = Suggestion.create!(content: {title: \"Hello World\"}, suggestable: @talk)\n\n    assert suggestion.persisted?\n    assert suggestion[:content].is_a?(Hash)\n  end\n\n  test \"approve the suggestion\" do\n    suggestion = Suggestion.create!(content: {title: \"Hello World\"}, suggestable: @talk)\n\n    assert suggestion.pending?\n\n    suggestion.approved!(approver: users(:one))\n\n    assert suggestion.approved?\n    assert_equal \"Hello World\", @talk.reload.title\n  end\nend\n"
  },
  {
    "path": "test/models/talk_test.rb",
    "content": "require \"test_helper\"\n\nclass TalkTest < ActiveSupport::TestCase\n  include ActiveJob::TestHelper\n\n  test \"should handle empty transcript\" do\n    talk = Talk.new(title: \"Sample Talk\", date: Date.today, static_id: \"test-sample-talk\", talk_transcript_attributes: {raw_transcript: Transcript.new})\n    assert talk.save\n\n    loaded_talk = Talk.find(talk.id)\n    assert_equal loaded_talk.transcript.cues, []\n    assert_equal \"Sample Talk\", loaded_talk.title\n  end\n\n  test \"should update transcript\" do\n    @talk = talks(:one)\n\n    VCR.use_cassette(\"youtube/transcript\") do\n      perform_enqueued_jobs do\n        @talk.fetch_and_update_raw_transcript!\n      end\n    end\n\n    assert @talk.transcript.is_a?(Transcript)\n    assert @talk.transcript.cues.first.is_a?(Cue)\n    assert @talk.transcript.cues.length > 100\n  end\n\n  test \"when the talk doesn't have any transcript yet\" do\n    @talk = Talk.create!(title: \"Express Your Ideas by Writing Your Own Gems\", video_id: \"Md90cwnmGc8\", video_provider: \"youtube\", date: Date.today, static_id: \"test-express-ideas-gems\")\n\n    VCR.use_cassette(\"youtube/transcript_not_available\") do\n      perform_enqueued_jobs do\n        @talk.fetch_and_update_raw_transcript!\n      end\n    end\n\n    assert @talk.reload.transcript.is_a?(Transcript)\n    assert @talk.transcript.cues.first.is_a?(Cue)\n    assert @talk.transcript.cues.length > 100\n  end\n\n  test \"should guess kind from title\" do\n    kind_with_titles = {\n      talk: [\"I love Ruby\", \"Beyond Code: Crafting effective discussions to further technical decision-making\", \"From LALR to IELR: A Lrama's Next Step\"],\n      keynote: [\"Keynote: Something \", \"Opening keynote Something\", \"closing keynote Something\", \"Keynote\", \"Keynote by Someone\", \"Opening Keynote\", \"Closing Keynote\"],\n      lightning_talk: [\"Lightning Talk: Something\", \"lightning talk: Something\", \"Lightning talk: Something\", \"lightning talk\", \"Lightning Talks\", \"Lightning talks\", \"lightning talks\", \"Lightning Talks Day 1\", \"Lightning Talks (Day 1)\", \"Lightning Talks - Day 1\", \"Micro Talk: Something\", \"micro talk: Something\", \"micro talk: Something\", \"micro talk\"],\n      panel: [\"Panel: foo\", \"Panel\", \"Something Panel\"],\n      workshop: [\"Workshop: Something\", \"workshop: Something\"],\n      gameshow: [\"Gameshow\", \"Game Show\", \"Gameshow: Something\", \"Game Show: Something\"],\n      podcast: [\"Podcast: Something\", \"Podcast Recording: Something\", \"Live Podcast: Something\"],\n      q_and_a: [\"Q&A\", \"Q&A: Something\", \"Something AMA\", \"Q&A with Somebody\", \"Ruby Committers vs The World\", \"Ruby Committers and the World\", \"AMA: Rails Core\"],\n      discussion: [\"Discussion: Something\", \"Discussion\", \"Fishbowl: Topic\", \"Fishbowl Discussion: Topic\"],\n      fireside_chat: [\"Fireside Chat: Something\", \"Fireside Chat\"],\n      interview: [\"Interview with Matz\", \"Interview: Something\"],\n      award: [\"Award: Something\", \"Award Show\", \"Ruby Heroes Awards\", \"Ruby Heroes Award\", \"Rails Luminary\"],\n      demo: [\"Demo: Something\", \"Demo of New Features\", \"Product Demo\"]\n    }\n\n    kind_with_titles.each do |kind, titles|\n      titles.each_with_index do |title, index|\n        talk = Talk.new(title:, date: Date.today, static_id: \"test-kind-#{kind}-#{index}\")\n        talk.save!\n\n        assert_equal [kind.to_s, title], [talk.kind, talk.title]\n\n        talk.destroy!\n      end\n    end\n  end\n\n  test \"should not guess a kind if it's provided\" do\n    talk = Talk.create!(title: \"foo\", kind: \"panel\", date: Date.today, static_id: \"test-panel-foo\")\n\n    assert_equal \"panel\", talk.kind\n  end\n\n  test \"should not guess a kind if it's provided in the static metadata\" do\n    talk = Talk.create!(\n      title: \"Who Wants to be a Ruby Engineer?\",\n      video_provider: \"mp4\",\n      video_id: \"https://videos.brightonruby.com/videos/2024/drew-bragg-who-wants-to-be-a-ruby-engineer.mp4\",\n      date: Date.today,\n      static_id: \"drew-bragg-who-wants-to-be-a-ruby-engineer\"\n    )\n\n    assert_equal \"gameshow\", talk.kind\n  end\n\n  test \"transcript should default to raw_transcript\" do\n    raw_transcript = Transcript.new(cues: [Cue.new(start_time: 0, end_time: 1, text: \"Hello\")])\n    talk = Talk.new(title: \"Sample Talk\", date: Date.today, static_id: \"test-transcript-default\", talk_transcript_attributes: {raw_transcript: raw_transcript})\n    assert talk.save\n\n    loaded_talk = Talk.find(talk.id)\n    assert_equal loaded_talk.transcript.cues.first.text, \"Hello\"\n  end\n\n  test \"talks one has a valid transcript\" do\n    talk = talks(:one)\n    assert talk.transcript.is_a?(Transcript)\n    assert talk.transcript.cues.first.is_a?(Cue)\n  end\n\n  test \"enhance talk transcript\" do\n    @talk = talks(:one)\n    @talk = Talk.includes(event: :series).find(@talk.id)\n\n    refute @talk.enhanced_transcript.cues.present?\n    VCR.use_cassette(\"talks/transcript-enhancement\") do\n      assert_changes \"@talk.reload.updated_at\" do\n        assert_changes \"@talk.reload.enhanced_transcript.cues.count\" do\n          perform_enqueued_jobs do\n            @talk.agents.improve_transcript_later\n          end\n        end\n      end\n      assert @talk.enhanced_transcript.cues.present?\n    end\n  end\n\n  test \"summarize talk\" do\n    @talk = talks(:one)\n    @talk = Talk.includes(event: :series).find(@talk.id)\n\n    refute @talk.summary.present?\n    VCR.use_cassette(\"talks/summarize\") do\n      assert_changes \"@talk.reload.summary.present?\" do\n        perform_enqueued_jobs do\n          @talk.agents.summarize_later\n        end\n      end\n      assert @talk.summary.present?\n    end\n  end\n\n  test \"extract topics\" do\n    @talk = talks(:one)\n\n    VCR.use_cassette(\"talks/extract_topics\") do\n      assert_changes \"@talk.topics.count\" do\n        perform_enqueued_jobs do\n          @talk.agents.analyze_topics_later\n        end\n      end\n    end\n  end\n\n  test \"does not create duplicate topics\" do\n    @talk = talks(:one)\n\n    perform_enqueued_jobs do\n      VCR.use_cassette(\"talks/extract_topics\", allow_playback_repeats: true) do\n        @talk.agents.analyze_topics_later\n        assert_no_changes \"@talk.topics.count\" do\n          @talk.agents.analyze_topics_later\n        end\n      end\n    end\n  end\n\n  test \"update_from_yml_metadata\" do\n    @talk = talks(:one)\n    @event = events(:rails_world_2023)\n    @talk.update!(title: \"New title\", description: \"New description\", event: @event)\n\n    assert_equal \"New title\", @talk.title\n    assert_equal \"New description\", @talk.description\n\n    @talk.update_from_yml_metadata!\n\n    assert_equal \"Hotwire Cookbook: Common Uses, Essential Patterns & Best Practices\", @talk.title\n  end\n\n  test \"update_from_yml_metadata creates alias when slug changes\" do\n    @talk = talks(:one)\n    original_title = @talk.title\n\n    old_slug = \"old-legacy-slug\"\n\n    @talk.update_columns(slug: old_slug)\n    @talk.update_from_yml_metadata!\n\n    assert_not_equal old_slug, @talk.slug\n    assert_equal \"Hotwire Cookbook: Common Uses, Essential Patterns & Best Practices\", @talk.title\n\n    alias_record = @talk.aliases.find_by(slug: old_slug)\n\n    assert_not_nil alias_record\n    assert_equal original_title, alias_record.name\n  end\n\n  test \"update_from_yml_metadata does not create duplicate aliases\" do\n    @talk = talks(:one)\n    old_slug = \"old-legacy-slug\"\n\n    @talk.aliases.create!(name: @talk.title, slug: old_slug)\n    @talk.update_columns(slug: old_slug)\n\n    assert_no_difference \"@talk.aliases.count\" do\n      @talk.update_from_yml_metadata!\n    end\n  end\n\n  test \"find_by_slug_or_alias finds talk by slug\" do\n    @talk = talks(:one)\n    found = Talk.find_by_slug_or_alias(@talk.slug)\n\n    assert_equal @talk, found\n  end\n\n  test \"find_by_slug_or_alias finds talk by alias slug\" do\n    @talk = talks(:one)\n    @talk.aliases.create!(name: \"Old Title\", slug: \"old-talk-slug\")\n\n    found = Talk.find_by_slug_or_alias(\"old-talk-slug\")\n\n    assert_equal @talk, found\n  end\n\n  test \"find_by_slug_or_alias returns nil for non-existent slug\" do\n    found = Talk.find_by_slug_or_alias(\"non-existent-slug\")\n\n    assert_nil found\n  end\n\n  test \"find_by_slug_or_alias returns nil for blank slug\" do\n    assert_nil Talk.find_by_slug_or_alias(nil)\n    assert_nil Talk.find_by_slug_or_alias(\"\")\n  end\n\n  test \"unused_slugs excludes slugs used as aliases by other talks\" do\n    @talk = talks(:one)\n    other_talk = talks(:two)\n\n    candidate_slug = @talk.slug_candidates.first\n    other_talk.aliases.create!(name: \"Some Title\", slug: candidate_slug)\n\n    assert_not_includes @talk.unused_slugs, candidate_slug\n  end\n\n  test \"unused_slugs allows talk to keep its own alias slug\" do\n    @talk = talks(:one)\n\n    candidate_slug = @talk.slug_candidates.second\n    @talk.aliases.create!(name: \"Old Title\", slug: candidate_slug)\n\n    assert_includes @talk.unused_slugs, candidate_slug\n  end\n\n  test \"language is english by default\" do\n    assert_equal \"en\", Talk.new.language\n  end\n\n  test \"language is normalized to alpha2 code\" do\n    assert_equal \"en\", Talk.new(language: \"English\").language\n    assert_equal \"en\", Talk.new(language: \"english\").language\n    assert_equal \"en\", Talk.new(language: \"en\").language\n\n    assert_equal \"ja\", Talk.new(language: \"Japanese\").language\n    assert_equal \"ja\", Talk.new(language: \"japanese\").language\n    assert_equal \"ja\", Talk.new(language: \"ja\").language\n\n    assert_nil Talk.new(language: \"doesntexist\").language\n    assert_nil Talk.new(language: \"random\").language\n  end\n\n  test \"language must be valid and present\" do\n    talk = talks(:one)\n    talk.language = \"random\"\n    talk.valid?\n\n    assert_equal 2, talk.errors.size\n    assert_equal [\"Language can't be blank\", \"Language  is not a valid IS0-639 alpha2 code\"],\n      talk.errors.map(&:full_message)\n  end\n\n  test \"create a new talk with a nil language\" do\n    talk = Talk.create!(title: \"New title\", language: nil, date: Date.today, static_id: \"test-new-title-nil-language\")\n    assert_equal \"en\", talk.language\n    assert talk.valid?\n  end\n\n  test \"full text search on title\" do\n    @talk = talks(:one)\n    assert_equal [@talk], Talk.ft_search(\"Hotwire Cookbook\")\n    assert_equal [@talk], Talk.ft_search(\"Hotwire Cookbook: Common Uses, Essential Patterns\")\n    assert_equal [@talk], Talk.ft_search('Hotwire\"') # with an escaped quote\n\n    @talk.fts_index.destroy!\n    @talk.reload.reindex_fts # Need to reload or we get a FrozenError from trying to update attributes on the destroyed index record.\n    assert_equal [@talk], Talk.ft_search(\"Hotwire Cookbook\")\n  end\n\n  test \"full text search creating and deleting a talk\" do\n    talk = Talk.create!(title: \"Full text seach with Sqlite\", summary: \"On using sqlite full text search with an ActiveRecord backed virtual table\", date: Time.current, static_id: \"kasper-timm-hansen-full-text-search-test\")\n    talk.users.create!(name: \"Kasper Timm Hansen\")\n\n    assert_equal [talk], Talk.ft_search(\"sqlite full text search\") # title\n    assert_equal [talk], Talk.ft_search(\"ActiveRecord backed virtual table\") # summary\n    assert_equal [talk], Talk.ft_search(\"Kasper Timm Hansen\") # speaker\n\n    talk.destroy\n    assert_empty Talk.ft_search(\"sqlite full text search\")\n    assert_empty Talk.ft_search(\"ActiveRecord backed virtual table\")\n    assert_empty Talk.ft_search(\"Kasper Timm Hansen\")\n  end\n\n  test \"full text search on title with snippets\" do\n    @talk = talks(:one)\n    assert_equal [@talk], Talk.ft_search(\"Hotwire Cookbook\").with_snippets\n    first_result = Talk.ft_search(\"Hotwire Cookbook\").with_snippets.first\n    assert_equal \"<mark>Hotwire</mark> <mark>Cookbook</mark>: Common Uses, Essential Patterns & Best Practices\",\n      first_result.title_snippet\n  end\n\n  test \"full text search on summary\" do\n    @talk = talks(:one)\n    @talk.update! summary: <<~HEREDOC\n      Do ad cupidatat aliqua magna incididunt Lorem cillum velit voluptate duis dolore magna.\n      Veniam aute labore non excepteur id pariatur ut exercitation labore.\n      Dolor eu amet cupidatat dolore nisi nostrud elit tempor officia.\n      Cupidatat exercitation voluptate esse officia tempor anim tempor adipisicing adipisicing commodo sint.\n      In ea adipisicing dolore esse dolor velit nulla enim mollit est velit laboris laborum.\n      Dolor ea non voluptate et et excepteur laborum tempor.\n    HEREDOC\n\n    assert_equal [@talk], Talk.ft_search(\"incididunt\")\n    assert_equal [@talk], Talk.ft_search(\"incid*\")\n  end\n\n  test \"full text search on summary with snippets\" do\n    @talk = talks(:one)\n    @talk.update! summary: <<~HEREDOC\n      Do ad cupidatat aliqua magna incididunt Lorem cillum velit voluptate duis dolore magna.\n      Veniam aute labore non excepteur id pariatur ut exercitation labore.\n      Dolor eu amet cupidatat dolore nisi nostrud elit tempor officia.\n      Cupidatat exercitation voluptate esse officia tempor anim tempor adipisicing adipisicing commodo sint.\n      In ea adipisicing dolore esse dolor velit nulla enim mollit est velit laboris laborum.\n      Dolor ea non voluptate et et excepteur laborum tempor.\n    HEREDOC\n\n    assert_equal [@talk], Talk.ft_search(\"incididunt\").with_snippets\n    first_result = Talk.ft_search(\"incididunt\").with_snippets.first\n    assert_match \"<mark>incididunt</mark>\", first_result.summary_snippet\n  end\n\n  test \"mark talk as watched\" do\n    talk = talks(:two)\n    Current.user = users(:one)\n    watched_talks(:two).delete\n\n    assert_equal 0, talk.watched_talks.count\n\n    talk.mark_as_watched!\n\n    assert_equal 1, talk.watched_talks.count\n    assert talk.watched?\n  end\n\n  test \"unmark talk as watched\" do\n    watched_talk = watched_talks(:one)\n    talk = watched_talk.talk\n    Current.user = users(:one)\n\n    talk.unmark_as_watched!\n\n    assert_equal 0, talk.watched_talks.count\n    assert_not talk.watched?\n  end\n\n  test \"should return a valid youtube thumbnail url\" do\n    talk = talks(:one)\n\n    assert_match %r{^https://i.ytimg.com/vi/.*/sddefault.jpg$}, talk.thumbnail\n  end\n\n  test \"should return a specific size youtube thumbnail url\" do\n    talk = talks(:one)\n\n    assert_match %r{^https://i.ytimg.com/vi/.*/maxresdefault.jpg$}, talk.thumbnail(:thumbnail_xl)\n  end\n\n  test \"should return the event thumbnail for non youtube talks\" do\n    talk = talks(:brightonruby_2024_one).tap do |t|\n      ActiveRecord::Associations::Preloader.new(records: [t], associations: [event: :series]).call\n    end\n\n    assert_match %r{^/assets/events/brightonruby/brightonruby-2024/poster-.*.webp$}, talk.thumbnail\n    assert_match %r{^/assets/events/brightonruby/brightonruby-2024/poster-.*.webp$}, talk.thumbnail(:thumbnail_xl)\n  end\n\n  test \"for_topic\" do\n    talk = talks(:one)\n    assert_includes Talk.for_topic(\"activerecord\"), talk\n  end\n\n  test \"discarded user_talks\" do\n    talk = talks(:one)\n    user_talk = talk.user_talks.first\n    assert_equal 2, user_talk.user.talks_count\n    user_talk.discard\n    assert_equal 1, talk.user_talks.count\n    assert_equal 0, talk.kept_user_talks.count\n    assert_equal 1, user_talk.user.talks_count\n  end\n\n  test \"should return original title\" do\n    talk = talks(:non_english_talk_one)\n\n    assert_equal \"Palestra não em inglês\", talk.original_title\n  end\n  test \"llm request caching for transcript enhancement\" do\n    @talk = talks(:one)\n    @talk = Talk.includes(event: :series).find(@talk.id)\n\n    refute @talk.enhanced_transcript.cues.present?\n    VCR.use_cassette(\"talks/transcript-enhancement\") do\n      assert_changes \"@talk.reload.updated_at\" do\n        assert_changes \"@talk.reload.enhanced_transcript.cues.count\" do\n          perform_enqueued_jobs do\n            @talk.agents.improve_transcript_later\n          end\n        end\n      end\n      assert @talk.enhanced_transcript.cues.present?\n\n      # Verify LLM request was created\n      assert_equal 1, LLM::Request.count\n      request = LLM::Request.first\n      assert_equal @talk, request.resource\n      assert request.duration > 0\n      assert request.raw_response.present?\n\n      # Second call should use cache\n      assert_no_changes \"LLM::Request.count\" do\n        perform_enqueued_jobs do\n          @talk.agents.improve_transcript_later\n        end\n      end\n    end\n  end\n\n  test \"llm request caching for summarization\" do\n    @talk = talks(:one)\n    @talk = Talk.includes(event: :series).find(@talk.id)\n\n    refute @talk.summary.present?\n    VCR.use_cassette(\"talks/summarize\") do\n      assert_changes \"@talk.reload.summary.present?\" do\n        perform_enqueued_jobs do\n          @talk.agents.summarize_later\n        end\n      end\n      assert @talk.summary.present?\n\n      # Verify LLM request was created\n      assert_equal 1, LLM::Request.count\n      request = LLM::Request.first\n      assert_equal @talk, request.resource\n      assert request.duration > 0\n      assert request.raw_response.present?\n\n      # Second call should use cache\n      assert_no_changes \"LLM::Request.count\" do\n        perform_enqueued_jobs do\n          @talk.agents.summarize_later\n        end\n      end\n    end\n  end\n\n  test \"llm request caching for topic analysis\" do\n    @talk = talks(:one)\n\n    VCR.use_cassette(\"talks/extract_topics\") do\n      assert_changes \"@talk.topics.count\" do\n        perform_enqueued_jobs do\n          @talk.agents.analyze_topics_later\n        end\n      end\n\n      # Verify LLM request was created\n      assert_equal 1, LLM::Request.count\n      request = LLM::Request.first\n      assert_equal @talk, request.resource\n      assert request.duration > 0\n      assert request.raw_response.present?\n\n      # Second call should use cache\n      assert_no_changes \"LLM::Request.count\" do\n        perform_enqueued_jobs do\n          @talk.agents.analyze_topics_later\n        end\n      end\n    end\n  end\n\n  test \"llm request caching with successful response\" do\n    @talk = talks(:one)\n    @talk = Talk.includes(event: :series).find(@talk.id)\n\n    VCR.use_cassette(\"talks/transcript-enhancement\") do\n      # First call should succeed and create a successful request\n      assert_changes \"@talk.reload.enhanced_transcript.cues.count\" do\n        perform_enqueued_jobs do\n          @talk.agents.improve_transcript_later\n        end\n      end\n\n      # Verify successful request was created\n      assert_equal 1, LLM::Request.count\n      request = LLM::Request.first\n      assert_equal @talk, request.resource\n      assert request.duration > 0\n      assert request.raw_response.present?\n      assert request.success\n\n      # Second call should use cache\n      assert_no_changes \"LLM::Request.count\" do\n        perform_enqueued_jobs do\n          @talk.agents.improve_transcript_later\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/models/talk_topic_test.rb",
    "content": "require \"test_helper\"\n\nclass TalkTopicTest < ActiveSupport::TestCase\n  # test \"the truth\" do\n  #   assert true\n  # end\nend\n"
  },
  {
    "path": "test/models/template_test.rb",
    "content": "require \"test_helper\"\n\nclass TemplateTest < ActiveSupport::TestCase\n  test \"serializes basic template to YAML\" do\n    template = Template.new(\n      title: \"Test Talk\",\n      event_name: \"Test Event\",\n      date: Date.new(2025, 1, 15),\n      speakers: \"John Doe, Jane Smith\"\n    )\n\n    parsed = YAML.safe_load(template.to_yaml).first\n\n    assert_equal \"Test Talk\", parsed[\"title\"]\n    assert_equal \"Test Event\", parsed[\"event_name\"]\n    assert_equal \"2025-01-15\", parsed[\"date\"]\n    assert_equal [\"John Doe\", \"Jane Smith\"], parsed[\"speakers\"]\n  end\n\n  test \"serializes template with video information\" do\n    template = Template.new(\n      title: \"Video Talk\",\n      event_name: \"Video Event\",\n      date: Date.current,\n      video_provider: \"youtube\",\n      video_id: \"abc123\",\n      start_cue: Time.parse(\"00:02:30\"),\n      end_cue: Time.parse(\"00:45:00\")\n    )\n\n    parsed = YAML.safe_load(template.to_yaml).first\n\n    assert_equal \"youtube\", parsed[\"video_provider\"]\n    assert_equal \"abc123\", parsed[\"video_id\"]\n    assert_equal \"00:02:30\", parsed[\"start_cue\"]\n    assert_equal \"00:45:00\", parsed[\"end_cue\"]\n  end\n\n  test \"serializes template with children\" do\n    template = Template.new(\n      title: \"Parent Talk\",\n      event_name: \"Multi-talk Event\",\n      date: Date.current\n    )\n\n    child = Template.new(\n      title: \"Child Talk\",\n      speakers: \"Child Speaker\"\n    )\n\n    template.children << child\n\n    parsed = YAML.safe_load(template.to_yaml).first\n\n    assert_equal \"children\", parsed[\"video_provider\"]\n    assert_equal 1, parsed[\"talks\"].length\n    assert_equal \"Child Talk\", parsed[\"talks\"].first[\"title\"]\n    assert_equal [\"Child Speaker\"], parsed[\"talks\"].first[\"speakers\"]\n  end\n\n  test \"validates required fields\" do\n    template = Template.new\n\n    refute template.valid?\n    assert_not_nil template.errors[:title]\n    assert_not_nil template.errors[:event_name]\n    assert_not_nil template.errors[:date]\n  end\nend\n"
  },
  {
    "path": "test/models/topic_test.rb",
    "content": "require \"test_helper\"\n\nclass TopicTest < ActiveSupport::TestCase\n  test \"create_from_list\" do\n    topics = [\"Rails\", \"Ruby\", \"Ruby on Rails\"]\n    statuses = [\"pending\", \"approved\", \"rejected\"]\n\n    statuses.each do |status|\n      created_topics = Topic.create_from_list(topics, status: status)\n      assert_equal [status], created_topics.pluck(:status).uniq\n      Topic.where(name: topics).destroy_all\n    end\n  end\n\n  test \"create_from_list shoudln't update status of exiting topic\" do\n    topic = Topic.create(name: \"Ruby on Rails\", status: :approved)\n    assert_equal \"approved\", topic.status\n\n    created_topics = Topic.create_from_list([topic.name], status: :pending)\n\n    assert_equal 1, created_topics.length\n    assert_equal \"approved\", created_topics.first.status\n  end\n\n  test \"create_from_list with duplicated topics\" do\n    topics = [\"Rails\", \"Rails\", \"Ruby\", \"Rails on Rails\"]\n\n    assert_changes \"Topic.count\", 3 do\n      Topic.create_from_list(topics)\n    end\n  end\n\n  test \"can assign_canonical_topic!\" do\n    @talk = talks(:one)\n    duplicate_topic = Topic.create(name: \"Rails\")\n    TalkTopic.create!(topic: duplicate_topic, talk: @talk)\n    canonical_topic = Topic.create(name: \"Ruby on Rails\")\n\n    assert duplicate_topic.talks.ids.include?(@talk.id)\n    duplicate_topic.assign_canonical_topic!(canonical_topic: canonical_topic)\n\n    assert_equal canonical_topic, duplicate_topic.reload.canonical\n    assert duplicate_topic.duplicate?\n    assert duplicate_topic.reload.talks.empty?\n    assert canonical_topic.reload.talks.ids.include?(@talk.id)\n  end\n\n  test \"create_from_list with canonical topic\" do\n    topics = [\"Rails\", \"Ruby on Rails\"]\n    canonical_topic = Topic.create(name: \"Ruby on Rails\", status: :approved)\n    topic = Topic.create(name: \"Rails\", canonical: canonical_topic, status: :duplicate)\n\n    assert_equal topic.primary_topic, canonical_topic\n    assert_no_changes \"Topic.count\" do\n      @topics = Topic.create_from_list(topics)\n    end\n\n    assert_equal 1, @topics.length\n    assert_equal \"Ruby on Rails\", @topics.first.name\n  end\n\n  test \"reject invalid topics\" do\n    @topic = topics(:one)\n    assert @topic.talks.count.positive?\n    @topic.rejected!\n    assert @topic.talks.count.zero?\n  end\nend\n"
  },
  {
    "path": "test/models/uk_nation_test.rb",
    "content": "require \"test_helper\"\n\nclass UKNationTest < ActiveSupport::TestCase\n  test \"initialize creates UKNation with correct attributes\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_equal \"scotland\", nation.slug\n    assert_equal \"SCT\", nation.state_code\n    assert_equal \"Scotland\", nation.nation_name\n  end\n\n  test \"name returns nation name\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_equal \"Scotland\", nation.name\n  end\n\n  test \"alpha2 returns GB prefixed state code\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_equal \"GB-SCT\", nation.alpha2\n  end\n\n  test \"code returns gb for all UK nations\" do\n    %w[england scotland wales northern-ireland].each do |slug|\n      nation = UKNation.new(slug)\n\n      assert_equal \"gb\", nation.code, \"Expected code to be 'gb' for #{slug}\"\n    end\n  end\n\n  test \"code is compatible with 2-letter alpha2 route constraints\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_match(/\\A[a-z]{2}\\z/, nation.code)\n  end\n\n  test \"path returns countries path with slug\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_equal \"/countries/scotland\", nation.path\n  end\n\n  test \"to_param returns slug\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_equal \"scotland\", nation.to_param\n  end\n\n  test \"continent returns Continent object\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_kind_of Continent, nation.continent\n    assert_equal \"Europe\", nation.continent.name\n  end\n\n  test \"continent_name returns Europe\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_equal \"Europe\", nation.continent_name\n  end\n\n  test \"cities returns ActiveRecord::Relation for GB cities in nation\" do\n    nation = UKNation.new(\"england\")\n\n    assert nation.cities.is_a?(ActiveRecord::Relation)\n  end\n\n  test \"emoji_flag returns GB flag\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_equal \"\\u{1F1EC}\\u{1F1E7}\", nation.emoji_flag\n  end\n\n  test \"uk_nation? returns true\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert nation.uk_nation?\n  end\n\n  test \"states? returns false\" do\n    nation = UKNation.new(\"scotland\")\n\n    refute nation.states?\n  end\n\n  test \"parent_country returns GB Country\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_equal \"GB\", nation.parent_country.alpha2\n  end\n\n  test \"two UKNations with same slug are equal\" do\n    nation1 = UKNation.new(\"scotland\")\n    nation2 = UKNation.new(\"scotland\")\n\n    assert_equal nation1, nation2\n  end\n\n  test \"two UKNations with different slugs are not equal\" do\n    nation1 = UKNation.new(\"scotland\")\n    nation2 = UKNation.new(\"england\")\n\n    assert_not_equal nation1, nation2\n  end\n\n  test \"UKNation is not equal to Country\" do\n    nation = UKNation.new(\"scotland\")\n    country = Country.find_by(country_code: \"GB\")\n\n    assert_not_equal nation, country\n  end\n\n  test \"eql? returns true for nations with same slug\" do\n    nation1 = UKNation.new(\"scotland\")\n    nation2 = UKNation.new(\"scotland\")\n\n    assert nation1.eql?(nation2)\n  end\n\n  test \"hash is same for nations with same slug\" do\n    nation1 = UKNation.new(\"scotland\")\n    nation2 = UKNation.new(\"scotland\")\n\n    assert_equal nation1.hash, nation2.hash\n  end\n\n  test \"nations can be used as hash keys\" do\n    nation1 = UKNation.new(\"scotland\")\n    nation2 = UKNation.new(\"scotland\")\n\n    hash = {nation1 => \"value\"}\n\n    assert_equal \"value\", hash[nation2]\n  end\n\n  test \"events returns events matching GB country_code and state\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert nation.events.is_a?(ActiveRecord::Relation)\n  end\n\n  test \"users returns users matching GB country_code and state\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert nation.users.is_a?(ActiveRecord::Relation)\n  end\n\n  test \"stamps\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_equal 1, nation.stamps.length\n    assert_equal \"GB-SCT\", nation.stamps.first.code\n  end\n\n  test \"held_in_sentence returns sentence with nation name\" do\n    nation = UKNation.new(\"scotland\")\n\n    assert_equal \" held in Scotland\", nation.held_in_sentence\n  end\n\n  test \"all UK nations can be created\" do\n    nations = Country::UK_NATIONS.keys.map { |slug| UKNation.new(slug) }\n\n    assert_equal 4, nations.size\n    assert_equal %w[England Northern\\ Ireland Scotland Wales], nations.map(&:name).sort\n  end\n\n  test \"to_location returns Location with nation and Europe\" do\n    nation = UKNation.new(\"scotland\")\n    location = nation.to_location\n\n    assert_kind_of Location, location\n    assert_equal \"Scotland, United Kingdom\", location.to_text\n  end\n\n  test \"to_location for all UK nations includes Europe\" do\n    Country::UK_NATIONS.keys.each do |slug|\n      nation = UKNation.new(slug)\n      location = nation.to_location\n\n      assert_includes location.to_text, \", United Kingdom\", \"Expected #{nation.name} to include United Kingdom\"\n      assert_not_includes location.to_text, \", Europe\", \"Expected #{nation.name} to not include Europe\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/models/user/duplicate_detector_test.rb",
    "content": "require \"test_helper\"\n\nclass User::DuplicateDetectorTest < ActiveSupport::TestCase\n  test \"reversed_name returns name parts in reverse order\" do\n    user = User.create!(name: \"John Smith\")\n\n    assert_equal \"Smith John\", user.duplicate_detector.reversed_name\n  end\n\n  test \"reversed_name handles single word names\" do\n    user = User.create!(name: \"Yukihiro\")\n\n    assert_equal \"Yukihiro\", user.duplicate_detector.reversed_name\n  end\n\n  test \"reversed_name handles three word names\" do\n    user = User.create!(name: \"Mary Jane Watson\")\n\n    assert_equal \"Watson Jane Mary\", user.duplicate_detector.reversed_name\n  end\n\n  test \"reversed_name returns nil for blank name\" do\n    user = User.create!(name: \"Test User\")\n    user.update_column(:name, \"\")\n\n    assert_nil user.duplicate_detector.reversed_name\n  end\n\n  test \"normalized_name returns sorted lowercase name parts\" do\n    user = User.create!(name: \"John Smith\")\n\n    assert_equal \"john smith\", user.duplicate_detector.normalized_name\n  end\n\n  test \"normalized_name is same for reversed names\" do\n    user1 = User.create!(name: \"John Smith\")\n    user2 = User.create!(name: \"Smith John\")\n\n    assert_equal user1.duplicate_detector.normalized_name,\n      user2.duplicate_detector.normalized_name\n  end\n\n  test \"potential_duplicates_by_reversed_name finds reversed name matches\" do\n    user1 = User.create!(name: \"John Smith\")\n    user2 = User.create!(name: \"Smith John\")\n\n    duplicates = user1.duplicate_detector.potential_duplicates_by_reversed_name\n\n    assert_includes duplicates, user2\n  end\n\n  test \"potential_duplicates_by_reversed_name finds matches with different capitalization\" do\n    user1 = User.create!(name: \"Masafumi OKURA\")\n    user2 = User.create!(name: \"Okura Masafumi\")\n\n    duplicates = user1.duplicate_detector.potential_duplicates_by_reversed_name\n\n    assert_includes duplicates, user2\n  end\n\n  test \"potential_duplicates_by_reversed_name excludes self\" do\n    user = User.create!(name: \"John Smith\")\n\n    duplicates = user.duplicate_detector.potential_duplicates_by_reversed_name\n\n    assert_not_includes duplicates, user\n  end\n\n  test \"potential_duplicates_by_reversed_name excludes canonical aliases\" do\n    canonical = User.create!(name: \"John Smith\")\n    alias_user = User.create!(name: \"Smith John\", canonical_id: canonical.id)\n\n    duplicates = canonical.duplicate_detector.potential_duplicates_by_reversed_name\n\n    assert_not_includes duplicates, alias_user\n  end\n\n  test \"potential_duplicates_by_reversed_name excludes marked for deletion\" do\n    user1 = User.create!(name: \"John Smith\")\n    user2 = User.create!(name: \"Smith John\", marked_for_deletion: true)\n\n    duplicates = user1.duplicate_detector.potential_duplicates_by_reversed_name\n\n    assert_not_includes duplicates, user2\n  end\n\n  test \"potential_duplicates_by_reversed_name returns none for blank name\" do\n    user = User.create!(name: \"Test User\")\n    user.update_column(:name, \"\")\n\n    assert_empty user.duplicate_detector.potential_duplicates_by_reversed_name\n  end\n\n  test \"has_reversed_name_duplicate? returns true when duplicate exists\" do\n    user1 = User.create!(name: \"John Smith\")\n    User.create!(name: \"Smith John\")\n\n    assert user1.duplicate_detector.has_reversed_name_duplicate?\n  end\n\n  test \"has_reversed_name_duplicate? returns false when no duplicate\" do\n    user = User.create!(name: \"John Smith\")\n\n    assert_not user.duplicate_detector.has_reversed_name_duplicate?\n  end\n\n  test \"find_all_reversed_name_duplicates finds all duplicate pairs\" do\n    User.create!(name: \"John Smith\")\n    User.create!(name: \"Smith John\")\n    User.create!(name: \"Jane Doe\")\n    User.create!(name: \"Doe Jane\")\n\n    duplicates = User::DuplicateDetector.find_all_reversed_name_duplicates\n\n    assert_equal 2, duplicates.count\n  end\n\n  test \"find_all_reversed_name_duplicates finds pairs with different capitalization\" do\n    user1 = User.create!(name: \"Masafumi OKURA\")\n    user2 = User.create!(name: \"Okura Masafumi\")\n\n    duplicates = User::DuplicateDetector.find_all_reversed_name_duplicates\n\n    assert_equal 1, duplicates.count\n    pair = duplicates.first\n    assert_includes pair, user1\n    assert_includes pair, user2\n  end\n\n  test \"find_all_reversed_name_duplicates skips palindromic names\" do\n    User.create!(name: \"Ali Ali\")\n\n    duplicates = User::DuplicateDetector.find_all_reversed_name_duplicates\n\n    assert_empty duplicates\n  end\n\n  test \"find_all_reversed_name_duplicates returns unique pairs\" do\n    user1 = User.create!(name: \"John Smith\")\n    user2 = User.create!(name: \"Smith John\")\n\n    duplicates = User::DuplicateDetector.find_all_reversed_name_duplicates\n\n    # Should only return one pair, not two\n    assert_equal 1, duplicates.count\n    pair = duplicates.first\n    assert_includes pair, user1\n    assert_includes pair, user2\n  end\n\n  test \"find_all_reversed_name_duplicates excludes canonical users\" do\n    canonical = User.create!(name: \"John Smith\")\n    User.create!(name: \"Smith John\", canonical_id: canonical.id)\n\n    duplicates = User::DuplicateDetector.find_all_reversed_name_duplicates\n\n    assert_empty duplicates\n  end\n\n  test \"find_all_reversed_name_duplicates excludes marked for deletion\" do\n    User.create!(name: \"John Smith\")\n    User.create!(name: \"Smith John\", marked_for_deletion: true)\n\n    duplicates = User::DuplicateDetector.find_all_reversed_name_duplicates\n\n    assert_empty duplicates\n  end\n\n  test \"report returns message when no duplicates\" do\n    report = User::DuplicateDetector.report\n\n    assert_equal \"No duplicates found.\", report\n  end\n\n  test \"report returns formatted output when duplicates exist\" do\n    User.create!(name: \"John Smith\", talks_count: 5, github_handle: \"johnsmith\")\n    User.create!(name: \"Smith John\", talks_count: 0)\n\n    report = User::DuplicateDetector.report\n\n    assert_includes report, \"Reversed Name Duplicates\"\n    assert_includes report, \"John Smith\"\n    assert_includes report, \"Smith John\"\n    assert_includes report, \"talks=5\"\n    assert_includes report, \"github=johnsmith\"\n  end\n\n  test \"with_reversed_name_duplicate scope returns users with duplicates\" do\n    user1 = User.create!(name: \"John Smith\")\n    user2 = User.create!(name: \"Smith John\")\n    User.create!(name: \"No Duplicate\")\n\n    users_with_duplicates = User.with_reversed_name_duplicate\n\n    assert_includes users_with_duplicates, user1\n    assert_includes users_with_duplicates, user2\n    assert_equal 2, users_with_duplicates.count\n  end\n\n  test \"with_reversed_name_duplicate scope excludes users without duplicates\" do\n    User.create!(name: \"Unique Name\")\n\n    users_with_duplicates = User.with_reversed_name_duplicate\n\n    assert_empty users_with_duplicates\n  end\n\n  test \"with_reversed_name_duplicate scope excludes canonical users\" do\n    canonical = User.create!(name: \"John Smith\")\n    User.create!(name: \"Smith John\", canonical_id: canonical.id)\n\n    users_with_duplicates = User.with_reversed_name_duplicate\n\n    assert_not_includes users_with_duplicates, canonical\n  end\n\n  test \"with_reversed_name_duplicate scope finds matches with different capitalization\" do\n    user1 = User.create!(name: \"Masafumi OKURA\")\n    user2 = User.create!(name: \"Okura Masafumi\")\n\n    users_with_duplicates = User.with_reversed_name_duplicate\n\n    assert_includes users_with_duplicates, user1\n    assert_includes users_with_duplicates, user2\n  end\nend\n"
  },
  {
    "path": "test/models/user/profiles_test.rb",
    "content": "require \"test_helper\"\n\nclass User::ProfilesTest < ActiveSupport::TestCase\n  test \"enhance_with_github with GitHub profile\" do\n    VCR.use_cassette(\"user/enhance_profile_job_test\") do\n      user = User.create!(name: \"Aaron Patterson\", github_handle: \"tenderlove\", email: \"aaron@tenderlove.com\", password: \"password\")\n\n      user.profiles.enhance_with_github\n      user.reload\n\n      assert_equal \"tenderlove\", user.github_handle\n      assert_equal \"tenderlove\", user.twitter\n      assert_equal \"tenderlove.dev\", user.bsky\n      assert_equal \"https://mastodon.social/@tenderlove\", user.mastodon\n\n      assert user.bio?\n      assert user.github_metadata?\n\n      assert_equal 3124, user.github_metadata.dig(\"profile\", \"id\")\n      assert_equal \"https://twitter.com/tenderlove\", user.github_metadata.dig(\"socials\", 0, \"url\")\n    end\n  end\n\n  test \"enhance_with_github with no GitHub handle\" do\n    user = User.create!(name: \"Nathan Bibler\", email: \"nathan@rubyevents.org\", password: \"password\")\n\n    user.profiles.enhance_with_github\n    user.reload\n\n    assert user.github_handle.blank?\n    assert_equal({}, user.github_metadata)\n  end\nend\n"
  },
  {
    "path": "test/models/user/suspicion_detector_test.rb",
    "content": "require \"test_helper\"\n\nclass User::SuspicionDetectorTest < ActiveSupport::TestCase\n  include ActiveJob::TestHelper\n\n  test \"calculate_suspicious? returns false for unverified users\" do\n    user = User.create!(\n      name: \"Unverified User\",\n      github_handle: \"unverified-test\",\n      bio: \"Check out https://spam.com\",\n      talks_count: 0,\n      watched_talks_count: 0,\n      github_metadata: {\n        \"profile\" => {\n          \"created_at\" => 1.day.ago.iso8601,\n          \"public_repos\" => 0,\n          \"followers\" => 0,\n          \"following\" => 0\n        }\n      }\n    )\n\n    assert_not user.verified?\n    assert_not user.suspicion_detector.calculate_suspicious?\n  end\n\n  test \"calculate_suspicious? returns false for verified user with few signals\" do\n    user = User.create!(\n      name: \"Legit User\",\n      github_handle: \"legit-user-test\",\n      bio: \"Ruby developer\",\n      talks_count: 5,\n      watched_talks_count: 10,\n      github_metadata: {\n        \"profile\" => {\n          \"created_at\" => 2.years.ago.iso8601,\n          \"public_repos\" => 50,\n          \"followers\" => 100,\n          \"following\" => 50\n        }\n      }\n    )\n    user.connected_accounts.create!(provider: \"github\", uid: \"12345\")\n\n    assert user.verified?\n    assert_not user.suspicion_detector.calculate_suspicious?\n  end\n\n  test \"calculate_suspicious? returns true for verified user with 3+ signals\" do\n    user = User.create!(\n      name: \"Spam User\",\n      github_handle: \"spam-user-test\",\n      bio: \"Buy trailers at https://spam.com\",\n      talks_count: 0,\n      watched_talks_count: 0,\n      github_metadata: {\n        \"profile\" => {\n          \"created_at\" => 1.month.ago.iso8601,\n          \"public_repos\" => 0,\n          \"followers\" => 0,\n          \"following\" => 0\n        }\n      }\n    )\n    user.connected_accounts.create!(provider: \"github\", uid: \"67890\")\n\n    assert user.verified?\n    assert user.suspicion_detector.calculate_suspicious?\n  end\n\n  test \"calculate_suspicious? returns false for verified user with exactly 2 signals\" do\n    user = User.create!(\n      name: \"Edge Case User\",\n      github_handle: \"edge-case-test\",\n      bio: \"Normal bio without URLs\",\n      talks_count: 0,\n      watched_talks_count: 0,\n      github_metadata: {\n        \"profile\" => {\n          \"created_at\" => 1.year.ago.iso8601,\n          \"public_repos\" => 10,\n          \"followers\" => 5,\n          \"following\" => 5\n        }\n      }\n    )\n    user.connected_accounts.create!(provider: \"github\", uid: \"11111\")\n\n    assert user.verified?\n    assert_not user.suspicion_detector.calculate_suspicious?\n  end\n\n  test \"github_account_newer_than? returns true for new account\" do\n    user = User.create!(\n      name: \"New GitHub User\",\n      github_metadata: {\"profile\" => {\"created_at\" => 1.month.ago.iso8601}}\n    )\n\n    assert user.github_account_newer_than?(6.months)\n  end\n\n  test \"github_account_newer_than? returns false for old account\" do\n    user = User.create!(\n      name: \"Old GitHub User\",\n      github_metadata: {\"profile\" => {\"created_at\" => 2.years.ago.iso8601}}\n    )\n\n    assert_not user.github_account_newer_than?(6.months)\n  end\n\n  test \"github_account_newer_than? returns false when metadata blank\" do\n    user = User.create!(name: \"No Metadata User\", github_metadata: {})\n\n    assert_not user.github_account_newer_than?(6.months)\n  end\n\n  test \"suspicion_detector.github_account_empty? returns true when all counts are zero\" do\n    user = User.create!(\n      name: \"Empty GitHub User\",\n      github_metadata: {\n        \"profile\" => {\n          \"public_repos\" => 0,\n          \"followers\" => 0,\n          \"following\" => 0\n        }\n      }\n    )\n\n    assert user.suspicion_detector.github_account_empty?\n  end\n\n  test \"suspicion_detector.github_account_empty? returns false when has repos\" do\n    user = User.create!(\n      name: \"Active GitHub User\",\n      github_metadata: {\n        \"profile\" => {\n          \"public_repos\" => 5,\n          \"followers\" => 0,\n          \"following\" => 0\n        }\n      }\n    )\n\n    assert_not user.suspicion_detector.github_account_empty?\n  end\n\n  test \"suspicion_detector.github_account_empty? returns false when has followers\" do\n    user = User.create!(\n      name: \"Popular GitHub User\",\n      github_metadata: {\n        \"profile\" => {\n          \"public_repos\" => 0,\n          \"followers\" => 10,\n          \"following\" => 0\n        }\n      }\n    )\n\n    assert_not user.suspicion_detector.github_account_empty?\n  end\n\n  test \"suspicion_detector.github_account_empty? returns false when metadata blank\" do\n    user = User.create!(name: \"No Metadata User 2\", github_metadata: {})\n\n    assert_not user.suspicion_detector.github_account_empty?\n  end\n\n  test \"suspicion_detector.bio_contains_url? returns true when bio has http URL\" do\n    user = User.create!(name: \"URL Bio User\", bio: \"Check out http://example.com\")\n\n    assert user.suspicion_detector.bio_contains_url?\n  end\n\n  test \"suspicion_detector.bio_contains_url? returns true when bio has https URL\" do\n    user = User.create!(name: \"HTTPS Bio User\", bio: \"Visit https://example.com for more\")\n\n    assert user.suspicion_detector.bio_contains_url?\n  end\n\n  test \"suspicion_detector.bio_contains_url? returns false for normal bio\" do\n    user = User.create!(name: \"Normal Bio User\", bio: \"Ruby developer from Berlin\")\n\n    assert_not user.suspicion_detector.bio_contains_url?\n  end\n\n  test \"suspicion_detector.bio_contains_url? returns false for blank bio\" do\n    user = User.create!(name: \"Blank Bio User\", bio: \"\")\n\n    assert_not user.suspicion_detector.bio_contains_url?\n  end\n\n  test \"suspicion_cleared? returns false when suspicion_cleared_at is nil\" do\n    user = User.create!(name: \"Uncleared User\", suspicion_cleared_at: nil)\n\n    assert_not user.suspicion_cleared?\n  end\n\n  test \"suspicion_cleared? returns true when suspicion_cleared_at is present\" do\n    user = User.create!(name: \"Cleared User\", suspicion_cleared_at: Time.current)\n\n    assert user.suspicion_cleared?\n  end\n\n  test \"clear_suspicion! sets suspicion_cleared_at and clears suspicion_marked_at\" do\n    user = User.create!(name: \"User To Clear\", suspicion_marked_at: Time.current)\n\n    assert_nil user.suspicion_cleared_at\n    assert_not_nil user.suspicion_marked_at\n\n    user.clear_suspicion!\n\n    assert_not_nil user.suspicion_cleared_at\n    assert_nil user.suspicion_marked_at\n    assert user.suspicion_cleared?\n    assert_not user.suspicious?\n  end\n\n  test \"unclear_suspicion! resets suspicion_cleared_at to nil\" do\n    user = User.create!(name: \"User To Unclear\", suspicion_cleared_at: Time.current)\n\n    assert user.suspicion_cleared?\n\n    user.unclear_suspicion!\n\n    assert_nil user.suspicion_cleared_at\n    assert_not user.suspicion_cleared?\n  end\n\n  test \"mark_suspicious! returns true and sets suspicion_marked_at when signals match\" do\n    user = User.create!(\n      name: \"Spam User\",\n      github_handle: \"mark-suspicious-true\",\n      bio: \"Buy stuff at https://spam.com\",\n      talks_count: 0,\n      watched_talks_count: 0,\n      github_metadata: {\n        \"profile\" => {\n          \"created_at\" => 1.month.ago.iso8601,\n          \"public_repos\" => 0,\n          \"followers\" => 0,\n          \"following\" => 0\n        }\n      }\n    )\n    user.connected_accounts.create!(provider: \"github\", uid: \"mark-true-123\")\n\n    assert_nil user.suspicion_marked_at\n    assert user.mark_suspicious!\n    assert_not_nil user.suspicion_marked_at\n  end\n\n  test \"mark_suspicious! returns false and does not set suspicion_marked_at when signals do not match\" do\n    user = User.create!(\n      name: \"Legit User\",\n      github_handle: \"mark-suspicious-false\",\n      bio: \"Ruby developer\",\n      talks_count: 5,\n      watched_talks_count: 10,\n      github_metadata: {\n        \"profile\" => {\n          \"created_at\" => 2.years.ago.iso8601,\n          \"public_repos\" => 50,\n          \"followers\" => 100,\n          \"following\" => 50\n        }\n      }\n    )\n    user.connected_accounts.create!(provider: \"github\", uid: \"mark-false-123\")\n\n    assert_nil user.suspicion_marked_at\n    assert_not user.mark_suspicious!\n    assert_nil user.suspicion_marked_at\n  end\n\n  test \"suspicious? returns true when suspicion_marked_at is set and not cleared\" do\n    user = User.create!(name: \"Marked User\", suspicion_marked_at: Time.current)\n\n    assert user.suspicious?\n  end\n\n  test \"suspicious? returns false when suspicion_marked_at is nil\" do\n    user = User.create!(name: \"Unmarked User\", suspicion_marked_at: nil)\n\n    assert_not user.suspicious?\n  end\n\n  test \"suspicious? returns false when marked but also cleared\" do\n    user = User.create!(\n      name: \"Marked And Cleared User\",\n      suspicion_marked_at: Time.current,\n      suspicion_cleared_at: Time.current\n    )\n\n    assert_not user.suspicious?\n  end\n\n  test \"calculate_suspicious? returns false for cleared user even with suspicious signals\" do\n    user = User.create!(\n      name: \"Cleared Spam User\",\n      github_handle: \"cleared-spam-test\",\n      bio: \"Buy stuff at https://spam.com\",\n      talks_count: 0,\n      watched_talks_count: 0,\n      suspicion_cleared_at: Time.current,\n      github_metadata: {\n        \"profile\" => {\n          \"created_at\" => 1.month.ago.iso8601,\n          \"public_repos\" => 0,\n          \"followers\" => 0,\n          \"following\" => 0\n        }\n      }\n    )\n    user.connected_accounts.create!(provider: \"github\", uid: \"cleared123\")\n\n    assert user.verified?\n    assert user.suspicion_cleared?\n    assert_not user.suspicion_detector.calculate_suspicious?\n  end\n\n  test \"calculate_suspicious? returns true for uncleared user with suspicious signals\" do\n    user = User.create!(\n      name: \"Uncleared Spam User\",\n      github_handle: \"uncleared-spam-test\",\n      bio: \"Buy stuff at https://spam.com\",\n      talks_count: 0,\n      watched_talks_count: 0,\n      suspicion_cleared_at: nil,\n      github_metadata: {\n        \"profile\" => {\n          \"created_at\" => 1.month.ago.iso8601,\n          \"public_repos\" => 0,\n          \"followers\" => 0,\n          \"following\" => 0\n        }\n      }\n    )\n    user.connected_accounts.create!(provider: \"github\", uid: \"uncleared123\")\n\n    assert user.verified?\n    assert_not user.suspicion_cleared?\n    assert user.suspicion_detector.calculate_suspicious?\n  end\n\n  test \"suspicious scope returns only users with suspicion_marked_at and no suspicion_cleared_at\" do\n    suspicious_user = User.create!(name: \"Suspicious\", suspicion_marked_at: Time.current)\n    cleared_user = User.create!(name: \"Cleared\", suspicion_marked_at: Time.current, suspicion_cleared_at: Time.current)\n    normal_user = User.create!(name: \"Normal\")\n\n    suspicious_users = User.suspicious\n\n    assert_includes suspicious_users, suspicious_user\n    assert_not_includes suspicious_users, cleared_user\n    assert_not_includes suspicious_users, normal_user\n  end\n\n  test \"not_suspicious scope returns users without suspicion_marked_at or with suspicion_cleared_at\" do\n    suspicious_user = User.create!(name: \"Suspicious\", suspicion_marked_at: Time.current)\n    cleared_user = User.create!(name: \"Cleared\", suspicion_marked_at: Time.current, suspicion_cleared_at: Time.current)\n    normal_user = User.create!(name: \"Normal\")\n\n    not_suspicious_users = User.not_suspicious\n\n    assert_not_includes not_suspicious_users, suspicious_user\n    assert_includes not_suspicious_users, cleared_user\n    assert_includes not_suspicious_users, normal_user\n  end\n\n  test \"suspicion_cleared scope returns only users with suspicion_cleared_at\" do\n    cleared_user = User.create!(name: \"Cleared\", suspicion_cleared_at: Time.current)\n    not_cleared_user = User.create!(name: \"Not Cleared\")\n\n    cleared_users = User.suspicion_cleared\n\n    assert_includes cleared_users, cleared_user\n    assert_not_includes cleared_users, not_cleared_user\n  end\n\n  test \"suspicion_not_cleared scope returns only users without suspicion_cleared_at\" do\n    cleared_user = User.create!(name: \"Cleared\", suspicion_cleared_at: Time.current)\n    not_cleared_user = User.create!(name: \"Not Cleared\")\n\n    not_cleared_users = User.suspicion_not_cleared\n\n    assert_not_includes not_cleared_users, cleared_user\n    assert_includes not_cleared_users, not_cleared_user\n  end\n\n  test \"calculate_suspicious? returns false for user with passport even with suspicious signals\" do\n    user = User.create!(\n      name: \"Passport User\",\n      github_handle: \"passport-user-test\",\n      bio: \"Buy stuff at https://spam.com\",\n      talks_count: 0,\n      watched_talks_count: 0,\n      github_metadata: {\n        \"profile\" => {\n          \"created_at\" => 1.month.ago.iso8601,\n          \"public_repos\" => 0,\n          \"followers\" => 0,\n          \"following\" => 0\n        }\n      }\n    )\n    user.connected_accounts.create!(provider: \"github\", uid: \"passport123\")\n    user.connected_accounts.create!(provider: \"passport\", uid: \"ruby-passport-123\")\n\n    assert user.verified?\n    assert user.ruby_passport_claimed?\n    assert_not user.suspicion_detector.calculate_suspicious?\n  end\nend\n"
  },
  {
    "path": "test/models/user/talk_recommendations_test.rb",
    "content": "require \"test_helper\"\n\nclass User::TalkRecommendationsTest < ActiveSupport::TestCase\n  def setup\n    @user = users(:one)\n    @other_user = users(:two)\n    @talk1 = talks(:one)\n    @talk2 = talks(:two)\n    @talk3 = talks(:three)\n\n    @user.watched_talks.delete_all\n    @other_user.watched_talks.delete_all\n  end\n\n  test \"returns empty recommendations for user with no watched talks\" do\n    recommendations = @user.talk_recommender.talks\n\n    assert_empty recommendations\n  end\n\n  test \"collaborative filtering finds similar users\" do\n    @user.watched_talks.create!(talk: @talk1, watched: true)\n    @user.watched_talks.create!(talk: @talk2, watched: true)\n\n    @other_user.watched_talks.create!(talk: @talk1, watched: true)\n    @other_user.watched_talks.create!(talk: @talk2, watched: true)\n    @other_user.watched_talks.create!(talk: @talk3, watched: true)\n\n    recommendations = @user.talk_recommender.talks\n\n    assert_includes recommendations.map(&:id), @talk3.id, \"Should recommend talks watched by similar users\"\n  end\n\n  test \"content-based recommendations use topics and speakers\" do\n    topic = topics(:activerecord)\n    @talk1.topics << topic unless @talk1.topics.include?(topic)\n    @talk2.topics << topic unless @talk2.topics.include?(topic)\n\n    @user.watched_talks.create!(talk: @talk1, watched: true)\n\n    recommendations = @user.talk_recommender.talks\n\n    assert_not_empty recommendations, \"Should provide content-based recommendations\"\n  end\n\n  test \"filters out already watched talks\" do\n    @user.watched_talks.create!(talk: @talk1, watched: true)\n    @user.watched_talks.create!(talk: @talk2, watched: true)\n\n    recommendations = @user.talk_recommender.talks\n\n    watched_ids = @user.watched_talks.watched.pluck(:talk_id)\n    recommended_ids = recommendations.map(&:id)\n\n    assert_empty (watched_ids & recommended_ids), \"Should not recommend already watched talks\"\n  end\n\n  test \"respects limit parameter\" do\n    limit = 3\n    recommendations = @user.talk_recommender.talks(limit: limit)\n\n    assert recommendations.length <= limit, \"Should respect the limit parameter\"\n  end\n\n  test \"only recommends watchable talks\" do\n    @user.watched_talks.create!(talk: @talk1, watched: true)\n\n    recommendations = @user.talk_recommender.talks\n\n    watchable_providers = Talk::WATCHABLE_PROVIDERS\n    recommendations.each do |talk|\n      assert_includes watchable_providers, talk.video_provider, \"Should only recommend watchable talks\"\n    end\n\n    assert_not_nil recommendations, \"Should return recommendations array\"\n  end\nend\n"
  },
  {
    "path": "test/models/user_geocoding_test.rb",
    "content": "require \"test_helper\"\n\nclass UserGeocodingTest < ActiveSupport::TestCase\n  setup do\n    Geocoder::Lookup::Test.add_stub(\n      \"San Francisco, CA\", [\n        {\n          \"coordinates\" => [37.7749, -122.4194],\n          \"address\" => \"San Francisco, CA, USA\",\n          \"city\" => \"San Francisco\",\n          \"state\" => \"California\",\n          \"state_code\" => \"CA\",\n          \"postal_code\" => \"94102\",\n          \"country\" => \"United States\",\n          \"country_code\" => \"US\"\n        }\n      ]\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"Berlin, Germany\", [\n        {\n          \"coordinates\" => [52.52, 13.405],\n          \"address\" => \"Berlin, Germany\",\n          \"city\" => \"Berlin\",\n          \"state\" => \"Berlin\",\n          \"state_code\" => \"BE\",\n          \"postal_code\" => \"10115\",\n          \"country\" => \"Germany\",\n          \"country_code\" => \"DE\"\n        }\n      ]\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"Unknown Location XYZ123\", []\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"San Francisco, California, United States\", [\n        {\n          \"coordinates\" => [37.7749, -122.4194],\n          \"city\" => \"San Francisco\",\n          \"state_code\" => \"CA\",\n          \"country_code\" => \"US\"\n        }\n      ]\n    )\n\n    Geocoder::Lookup::Test.add_stub(\n      \"Berlin, Berlin, Germany\", [\n        {\n          \"coordinates\" => [52.52, 13.405],\n          \"city\" => \"Berlin\",\n          \"state_code\" => \"BE\",\n          \"country_code\" => \"DE\"\n        }\n      ]\n    )\n  end\n\n  teardown do\n    Geocoder::Lookup::Test.reset\n  end\n\n  test \"geocode with valid location\" do\n    user = User.create!(name: \"Test User\", location: \"San Francisco, CA\")\n\n    user.geocode\n    user.save!\n\n    assert_equal \"San Francisco\", user.city\n    assert_equal \"CA\", user.state_code\n    assert_equal \"US\", user.country_code\n    assert_in_delta 37.7749, user.latitude.to_f, 0.01\n    assert_in_delta(-122.4194, user.longitude.to_f, 0.01)\n    assert user.geocode_metadata.present?\n    assert user.geocode_metadata[\"geocoded_at\"].present?\n  end\n\n  test \"geocode with blank location does nothing\" do\n    user = User.create!(name: \"Test User\", location: \"\")\n\n    user.geocode\n\n    assert_nil user.city\n    assert_nil user.state_code\n    assert_nil user.country_code\n    assert_nil user.latitude\n    assert_nil user.longitude\n  end\n\n  test \"geocode with nil location does nothing\" do\n    user = User.create!(name: \"Test User\", location: nil)\n\n    user.geocode\n\n    assert_nil user.city\n    assert_nil user.latitude\n  end\n\n  test \"geocode with no results does nothing\" do\n    user = User.create!(name: \"Test User\", location: \"Unknown Location XYZ123\")\n\n    user.geocode\n\n    assert_nil user.city\n    assert_nil user.latitude\n  end\n\n  test \"geocoded? returns true when coordinates present\" do\n    user = User.create!(name: \"Test User\", latitude: 37.7749, longitude: -122.4194)\n\n    assert user.geocoded?\n  end\n\n  test \"geocoded? returns false when coordinates missing\" do\n    user = User.create!(name: \"Test User\")\n\n    assert_not user.geocoded?\n  end\n\n  test \"geocoded? returns false when only latitude present\" do\n    user = User.create!(name: \"Test User\", latitude: 37.7749)\n\n    assert_not user.geocoded?\n  end\n\n  test \"geocoded scope returns geocoded users\" do\n    geocoded_user = User.create!(name: \"Geocoded\", latitude: 37.7749, longitude: -122.4194)\n    not_geocoded_user = User.create!(name: \"Not Geocoded\")\n\n    assert_includes User.geocoded, geocoded_user\n    assert_not_includes User.geocoded, not_geocoded_user\n  end\n\n  test \"not_geocoded scope returns users without coordinates\" do\n    geocoded_user = User.create!(name: \"Geocoded\", latitude: 37.7749, longitude: -122.4194)\n    not_geocoded_user = User.create!(name: \"Not Geocoded\")\n\n    assert_includes User.not_geocoded, not_geocoded_user\n    assert_not_includes User.not_geocoded, geocoded_user\n  end\n\n  test \"geocode stores raw result data in metadata\" do\n    user = User.create!(name: \"Test User\", location: \"San Francisco, CA\")\n\n    user.geocode\n    user.save!\n\n    assert user.geocode_metadata[\"geocoded_at\"].present?\n    assert_equal \"San Francisco, CA, USA\", user.geocode_metadata[\"address\"]\n    assert_equal \"United States\", user.geocode_metadata[\"country\"]\n    assert_equal [37.7749, -122.4194], user.geocode_metadata[\"coordinates\"]\n  end\n\n  test \"geocode with different location\" do\n    user = User.create!(name: \"Test User\", location: \"Berlin, Germany\")\n\n    user.geocode\n    user.save!\n\n    assert_equal \"Berlin\", user.city\n    assert_equal \"BE\", user.state_code\n    assert_equal \"DE\", user.country_code\n    assert_in_delta 52.52, user.latitude.to_f, 0.01\n    assert_in_delta 13.405, user.longitude.to_f, 0.01\n  end\nend\n"
  },
  {
    "path": "test/models/user_talk_test.rb",
    "content": "require \"test_helper\"\n\nclass UserTalkTest < ActiveSupport::TestCase\n  # test \"the truth\" do\n  #   assert true\n  # end\nend\n"
  },
  {
    "path": "test/models/user_test.rb",
    "content": "require \"test_helper\"\n\nclass UserTest < ActiveSupport::TestCase\n  include ActiveJob::TestHelper\n\n  test \"can create a user with just a name\" do\n    user = User.create!(name: \"John Doe\")\n    assert_equal \"john-doe\", user.slug\n  end\n\n  test \"the slug provided is used\" do\n    user = User.create!(name: \"John Doe\", slug: \"john-doe-2\")\n    assert_equal \"john-doe-2\", user.slug\n  end\n\n  test \"not downcasing github_handle\" do\n    user = User.create!(name: \"John Doe\", github_handle: \"TEKIN\")\n    assert_equal \"TEKIN\", user.github_handle\n    assert_equal \"tekin\", user.slug\n  end\n\n  test \"should normalize github_handle by stripping URL, www, and @\" do\n    user = users(:one)\n\n    user.github_handle = \"Https://www.github.com/tekin\"\n    user.save\n    assert_equal \"tekin\", user.github_handle\n\n    user.github_handle = \"github.com/tekin\"\n    user.save\n    assert_equal \"tekin\", user.github_handle\n\n    user.github_handle = \"@tekin\"\n    user.save\n    assert_equal \"tekin\", user.github_handle\n  end\n\n  test \"find_by_name_or_alias finds user by exact name\" do\n    user = User.create!(name: \"Yukihiro Matsumoto\", github_handle: \"matz-test-1\")\n\n    found_user = User.find_by_name_or_alias(\"Yukihiro Matsumoto\")\n    assert_equal user.id, found_user.id\n  end\n\n  test \"find_by_name_or_alias finds user by alias name\" do\n    user = User.create!(name: \"Yukihiro Matsumoto\", github_handle: \"matz-test-2\")\n    user.aliases.create!(name: \"Matz\", slug: \"matz-alias-test\")\n\n    found_user = User.find_by_name_or_alias(\"Matz\")\n    assert_equal user.id, found_user.id\n  end\n\n  test \"find_by_name_or_alias returns nil for non-existent name\" do\n    found_user = User.find_by_name_or_alias(\"Nonexistent Person\")\n    assert_nil found_user\n  end\n\n  test \"find_by_name_or_alias returns nil for blank name\" do\n    assert_nil User.find_by_name_or_alias(\"\")\n    assert_nil User.find_by_name_or_alias(nil)\n  end\n\n  test \"find_by_name_or_alias prioritizes exact name match over alias\" do\n    user1 = User.create!(name: \"John Doe\", github_handle: \"john-test-1\")\n    user2 = User.create!(name: \"Jane Doe\", github_handle: \"jane-test-1\")\n    user2.aliases.create!(name: \"John Doe\", slug: \"john-doe-alias\")\n\n    found_user = User.find_by_name_or_alias(\"John Doe\")\n    assert_equal user1.id, found_user.id\n  end\n\n  test \"assign_canonical_user! marks user for deletion\" do\n    user = User.create!(name: \"Duplicate User\", github_handle: \"duplicate-test\")\n    canonical_user = User.create!(name: \"Canonical User\", github_handle: \"canonical-test\")\n\n    assert_equal false, user.marked_for_deletion\n\n    user.assign_canonical_user!(canonical_user: canonical_user)\n    user.reload\n\n    assert_equal true, user.marked_for_deletion\n    assert_equal canonical_user, user.canonical\n  end\n\n  test \"assign_canonical_user! creates an alias on the canonical user\" do\n    user = User.create!(name: \"Old Name\", github_handle: \"old-name-test\")\n    canonical_user = User.create!(name: \"New Name\", github_handle: \"new-name-test\")\n\n    user.assign_canonical_user!(canonical_user: canonical_user)\n\n    alias_record = canonical_user.aliases.find_by(name: \"Old Name\")\n    assert_not_nil alias_record\n    assert_equal \"old-name-test\", alias_record.slug\n  end\n\n  test \"marked_for_deletion scope returns only marked users\" do\n    user1 = User.create!(name: \"User 1\", github_handle: \"user-1-marked\", marked_for_deletion: true)\n    user2 = User.create!(name: \"User 2\", github_handle: \"user-2-not-marked\", marked_for_deletion: false)\n\n    marked_users = User.marked_for_deletion\n    assert_includes marked_users, user1\n    assert_not_includes marked_users, user2\n  end\n\n  test \"find_by_slug_or_alias finds user by slug\" do\n    user = User.create!(name: \"Test User\", github_handle: \"test-slug-user\")\n\n    found_user = User.find_by_slug_or_alias(user.slug)\n    assert_equal user.id, found_user.id\n  end\n\n  test \"find_by_slug_or_alias finds user by alias slug\" do\n    user = User.create!(name: \"Primary User\", github_handle: \"primary-slug-user\")\n    user.aliases.create!(name: \"Old Name\", slug: \"old-slug\")\n\n    found_user = User.find_by_slug_or_alias(\"old-slug\")\n    assert_equal user.id, found_user.id\n  end\n\n  test \"find_by_slug_or_alias returns nil for non-existent slug\" do\n    found_user = User.find_by_slug_or_alias(\"nonexistent-slug\")\n    assert_nil found_user\n  end\n\n  test \"find_by_slug_or_alias returns nil for blank slug\" do\n    assert_nil User.find_by_slug_or_alias(\"\")\n    assert_nil User.find_by_slug_or_alias(nil)\n  end\n\n  test \"find_by_slug_or_alias prioritizes slug over alias\" do\n    user1 = User.create!(name: \"User One\", github_handle: \"user-one-slug\")\n    user2 = User.create!(name: \"User Two\", github_handle: \"user-two-slug\")\n    user2.aliases.create!(name: \"Alias\", slug: user1.slug)\n\n    found_user = User.find_by_slug_or_alias(user1.slug)\n    assert_equal user1.id, found_user.id\n  end\n\n  test \"assign_canonical_user! reassigns all user talks\" do\n    user = User.create!(name: \"Speaker\", github_handle: \"speaker-talks\")\n    canonical_user = User.create!(name: \"Canonical Speaker\", github_handle: \"canonical-talks\")\n    talk1 = talks(:one)\n    talk2 = talks(:two)\n\n    UserTalk.create!(user: user, talk: talk1)\n    UserTalk.create!(user: user, talk: talk2)\n\n    assert_equal 2, user.talks.count\n    assert_equal 0, canonical_user.talks.count\n\n    user.assign_canonical_user!(canonical_user: canonical_user)\n    user.reload\n    canonical_user.reload\n\n    assert_equal 0, user.talks.count\n    assert_equal 2, canonical_user.talks.count\n\n    assert_includes canonical_user.talks, talk1\n    assert_includes canonical_user.talks, talk2\n  end\n\n  test \"assign_canonical_user! reassigns event participations\" do\n    user = User.create!(name: \"Participant\", github_handle: \"participant-events\")\n    canonical_user = User.create!(name: \"Canonical Participant\", github_handle: \"canonical-events\")\n    series = EventSeries.create!(name: \"Test Series\", slug: \"test-series\")\n    event = Event.create!(name: \"Test Event\", slug: \"test-event\", series: series, date: Date.today)\n\n    EventParticipation.create!(user: user, event: event, attended_as: :speaker)\n\n    assert_equal 1, user.event_participations.count\n    assert_equal 0, canonical_user.event_participations.count\n\n    user.assign_canonical_user!(canonical_user: canonical_user)\n    user.reload\n    canonical_user.reload\n\n    assert_equal 0, user.event_participations.count\n    assert_equal 1, canonical_user.event_participations.count\n    assert_equal event, canonical_user.participated_events.first\n  end\n\n  test \"assign_canonical_user! preserves event participation attributes\" do\n    user = User.create!(name: \"Keynote Speaker\", github_handle: \"keynote-speaker\")\n    canonical_user = User.create!(name: \"Canonical Keynote\", github_handle: \"canonical-keynote\")\n    series = EventSeries.create!(name: \"Test seriesAttrs\", slug: \"test-org-attrs\")\n    event = Event.create!(name: \"Test Event Attrs\", slug: \"test-event-attrs\", series: series, date: Date.today)\n\n    EventParticipation.create!(\n      user: user,\n      event: event,\n      attended_as: :keynote_speaker\n    )\n\n    user.assign_canonical_user!(canonical_user: canonical_user)\n    canonical_user.reload\n\n    new_participation = canonical_user.event_participations.first\n    assert_not_nil new_participation\n    assert_equal \"keynote_speaker\", new_participation.attended_as\n    assert_equal event.id, new_participation.event_id\n  end\n\n  test \"assign_canonical_user! reassigns event involvements\" do\n    user = User.create!(name: \"Organizer\", github_handle: \"organizer-events\")\n    canonical_user = User.create!(name: \"Canonical Organizer\", github_handle: \"canonical-organizer\")\n    series = EventSeries.create!(name: \"Test series2\", slug: \"test-org-2\")\n    event = Event.create!(name: \"Test Event 2\", slug: \"test-event-2\", series: series, date: Date.today)\n\n    EventInvolvement.create!(involvementable: user, event: event, role: :organizer, position: 1)\n\n    assert_equal 1, user.event_involvements.count\n    assert_equal 0, canonical_user.event_involvements.count\n\n    user.assign_canonical_user!(canonical_user: canonical_user)\n    user.reload\n    canonical_user.reload\n\n    assert_equal 0, user.event_involvements.count\n    assert_equal 1, canonical_user.event_involvements.count\n    assert_equal event, canonical_user.involved_events.first\n  end\n\n  test \"assign_canonical_user! preserves event involvement attributes\" do\n    user = User.create!(name: \"MC\", github_handle: \"mc-host\")\n    canonical_user = User.create!(name: \"Canonical MC\", github_handle: \"canonical-mc\")\n    series = EventSeries.create!(name: \"Test Series\", slug: \"test-series\")\n    event = Event.create!(name: \"Test Event Involvement\", slug: \"test-event-involvement\", series: series, date: Date.today)\n\n    EventInvolvement.create!(\n      involvementable: user,\n      event: event,\n      role: :mc,\n      position: 5\n    )\n\n    user.assign_canonical_user!(canonical_user: canonical_user)\n    canonical_user.reload\n\n    new_involvement = canonical_user.event_involvements.first\n    assert_not_nil new_involvement\n    assert_equal \"mc\", new_involvement.role\n    assert_equal 5, new_involvement.position\n    assert_equal event.id, new_involvement.event_id\n  end\n\n  test \"assign_canonical_speaker! calls assign_canonical_user!\" do\n    user = User.create!(name: \"Old Method User\", github_handle: \"old-method\")\n    canonical_user = User.create!(name: \"Canonical\", github_handle: \"canonical-old\")\n\n    user.assign_canonical_speaker!(canonical_speaker: canonical_user)\n    user.reload\n\n    assert_equal true, user.marked_for_deletion\n    assert_equal canonical_user, user.canonical\n    assert_not_nil canonical_user.aliases.find_by(name: \"Old Method User\")\n  end\n\n  test \"find_by_name_or_alias excludes users marked for deletion\" do\n    user = User.create!(name: \"Marked User\", github_handle: \"marked-for-deletion-test\")\n    user.update_column(:marked_for_deletion, true)\n\n    found_user = User.find_by_name_or_alias(\"Marked User\")\n    assert_nil found_user\n  end\n\n  test \"find_by_name_or_alias finds alias even if original user is marked for deletion\" do\n    canonical_user = User.create!(name: \"Canonical User\", github_handle: \"canonical-marked-test\")\n    marked_user = User.create!(name: \"Duplicate User\", github_handle: \"duplicate-marked-test\")\n\n    marked_user.assign_canonical_user!(canonical_user: canonical_user)\n    marked_user.reload\n\n    alias_record = Alias.find_by(aliasable_type: \"User\", name: \"Duplicate User\")\n    assert_not_nil alias_record\n    assert_equal canonical_user.id, alias_record.aliasable_id\n\n    found_via_alias = User.find_by_name_or_alias(\"Duplicate User\")\n    assert_equal canonical_user.id, found_via_alias.id\n  end\n\n  test \"find_by_slug_or_alias excludes users marked for deletion\" do\n    user = User.create!(name: \"Slug Marked User\", github_handle: \"slug-marked-test\")\n    original_slug = user.slug\n    user.update_column(:marked_for_deletion, true)\n\n    found_user = User.find_by_slug_or_alias(original_slug)\n    assert_nil found_user\n  end\n\n  test \"find_by_slug_or_alias finds alias even if original user is marked for deletion\" do\n    canonical_user = User.create!(name: \"Canonical Slug User\", github_handle: \"canonical-slug-marked\")\n    marked_user = User.create!(name: \"Duplicate Slug User\", github_handle: \"duplicate-slug-marked\")\n    original_slug = marked_user.slug\n\n    marked_user.assign_canonical_user!(canonical_user: canonical_user)\n    marked_user.reload\n\n    alias_record = Alias.find_by(aliasable_type: \"User\", slug: original_slug)\n    assert_not_nil alias_record\n    assert_equal canonical_user.id, alias_record.aliasable_id\n\n    found_user = User.find_by_slug_or_alias(original_slug)\n    assert_equal canonical_user.id, found_user.id\n  end\n\n  test \"updating location enqueues geocoding job\" do\n    user = User.create!(name: \"Geo User\", github_handle: \"geo-user\")\n\n    assert_enqueued_with(job: GeocodeRecordJob) do\n      user.update!(location: \"Berlin, Germany\")\n    end\n  end\n\n  test \"updating location does not enqueue job when location unchanged\" do\n    user = User.create!(name: \"Geo User 2\", github_handle: \"geo-user-2\", location: \"Berlin, Germany\")\n\n    assert_no_enqueued_jobs(only: GeocodeRecordJob) do\n      user.update!(name: \"New Name\")\n    end\n  end\n\n  test \"country returns Country object when country_code present\" do\n    user = User.create!(name: \"Test User\", country_code: \"US\")\n\n    assert_not_nil user.country\n    assert_equal \"US\", user.country.alpha2\n    assert_equal \"United States\", user.country.name\n  end\n\n  test \"country returns Country object for different country codes\" do\n    user = User.create!(name: \"Test User\", country_code: \"DE\")\n\n    assert_not_nil user.country\n    assert_equal \"DE\", user.country.alpha2\n    assert_equal \"Germany\", user.country.name\n  end\n\n  test \"country returns nil when country_code is blank\" do\n    user = User.create!(name: \"Test User\", country_code: \"\")\n\n    assert_nil user.country\n  end\n\n  test \"country returns nil when country_code is nil\" do\n    user = User.create!(name: \"Test User\", country_code: nil)\n\n    assert_nil user.country\n  end\n\n  test \"meta_description returns generic profile description for user with no talks\" do\n    user = User.create!(name: \"No Talks User\", github_handle: \"no-talks-user\", talks_count: 0)\n\n    assert_equal \"No Talks User's profile on RubyEvents.org\", user.meta_description\n  end\n\n  test \"meta_description returns fallback topic text for user with talks but no topics\" do\n    user = User.create!(name: \"Speaker No Topics\", github_handle: \"speaker-no-topics\")\n    talk = talks(:one)\n\n    UserTalk.create!(user: user, talk: talk)\n    user.update_column(:talks_count, 1)\n\n    talk.talk_topics.destroy_all\n\n    expected = \"Discover all the talks given by Speaker No Topics on subjects related to Ruby language and Ruby Frameworks such as Rails, Hanami and others.\"\n    assert_equal expected, user.meta_description\n  end\n\n  test \"meta_description includes top topics for user with talks and topics\" do\n    user = User.create!(name: \"Speaker With Topics\", github_handle: \"speaker-with-topics\")\n\n    talk1 = talks(:one)\n    talk2 = talks(:two)\n\n    UserTalk.create!(user: user, talk: talk1)\n    UserTalk.create!(user: user, talk: talk2)\n    user.update_column(:talks_count, 2)\n\n    topic_rails = Topic.create!(name: \"Rails\", slug: \"rails\", status: \"approved\")\n    topic_ruby = Topic.create!(name: \"Ruby\", slug: \"ruby\", status: \"approved\")\n\n    talk1.talk_topics.destroy_all\n    talk2.talk_topics.destroy_all\n\n    TalkTopic.create!(talk: talk1, topic: topic_rails)\n    TalkTopic.create!(talk: talk2, topic: topic_rails)\n    TalkTopic.create!(talk: talk1, topic: topic_ruby)\n\n    expected = \"Discover all the talks given by Speaker With Topics on subjects related to Rails and Ruby.\"\n    assert_equal expected, user.meta_description\n  end\n\n  test \"meta_description limits to top 3 topics by frequency\" do\n    user = User.create!(name: \"Prolific Speaker\", github_handle: \"prolific-speaker\")\n\n    talk1 = talks(:one)\n    talk2 = talks(:two)\n\n    UserTalk.create!(user: user, talk: talk1)\n    UserTalk.create!(user: user, talk: talk2)\n    user.update_column(:talks_count, 2)\n\n    topic1 = Topic.create!(name: \"Topic A\", slug: \"topic-a\", status: \"approved\")\n    topic2 = Topic.create!(name: \"Topic B\", slug: \"topic-b\", status: \"approved\")\n    topic3 = Topic.create!(name: \"Topic C\", slug: \"topic-c\", status: \"approved\")\n    topic4 = Topic.create!(name: \"Topic D\", slug: \"topic-d\", status: \"approved\")\n\n    talk1.talk_topics.destroy_all\n    talk2.talk_topics.destroy_all\n\n    TalkTopic.create!(talk: talk1, topic: topic1)\n    TalkTopic.create!(talk: talk2, topic: topic1)\n    TalkTopic.create!(talk: talk1, topic: topic2)\n    TalkTopic.create!(talk: talk2, topic: topic2)\n    TalkTopic.create!(talk: talk1, topic: topic3)\n    TalkTopic.create!(talk: talk2, topic: topic3)\n    TalkTopic.create!(talk: talk1, topic: topic4)\n\n    expected = \"Discover all the talks given by Prolific Speaker on subjects related to Topic A, Topic B, and Topic C.\"\n    assert_equal expected, user.meta_description\n  end\n\n  test \"searchable scope returns users with searchable setting enabled\" do\n    searchable_user = User.create!(name: \"Searchable User\", github_handle: \"searchable-user\")\n    non_searchable_user = User.create!(name: \"Non Searchable User\", github_handle: \"non-searchable-user\")\n    non_searchable_user.update!(searchable: false)\n\n    assert_includes User.searchable, searchable_user\n    assert_not_includes User.searchable, non_searchable_user\n  end\n\n  test \"indexable scope includes speakers regardless of searchable setting\" do\n    speaker = User.create!(name: \"Speaker User\", github_handle: \"speaker-indexable\", talks_count: 5)\n    speaker.update!(searchable: false)\n\n    assert_includes User.indexable, speaker\n  end\n\n  test \"indexable scope includes non-speakers with searchable enabled\" do\n    user = User.create!(name: \"Regular User\", github_handle: \"regular-indexable\", talks_count: 0)\n\n    assert_includes User.indexable, user\n  end\n\n  test \"indexable scope excludes non-speakers with searchable disabled\" do\n    user = User.create!(name: \"Hidden User\", github_handle: \"hidden-indexable\", talks_count: 0)\n    user.update!(searchable: false)\n\n    assert_not_includes User.indexable, user\n  end\n\n  test \"indexable scope excludes users marked for deletion\" do\n    user = User.create!(name: \"Deleted User\", github_handle: \"deleted-indexable\", marked_for_deletion: true)\n\n    assert_not_includes User.indexable, user\n  end\n\n  test \"indexable scope excludes non-canonical users\" do\n    canonical = User.create!(name: \"Canonical\", github_handle: \"canonical-indexable\")\n    non_canonical = User.create!(name: \"Non Canonical\", github_handle: \"non-canonical-indexable\", canonical_id: canonical.id)\n\n    assert_includes User.indexable, canonical\n    assert_not_includes User.indexable, non_canonical\n  end\n\n  test \"indexable? returns true for speakers regardless of searchable setting\" do\n    speaker = User.create!(name: \"Speaker\", github_handle: \"speaker-method\", talks_count: 5)\n    speaker.update!(searchable: false)\n\n    assert speaker.indexable?\n  end\n\n  test \"indexable? returns true for non-speakers with searchable enabled\" do\n    user = User.create!(name: \"Regular\", github_handle: \"regular-method\", talks_count: 0)\n\n    assert user.indexable?\n  end\n\n  test \"indexable? returns false for non-speakers with searchable disabled\" do\n    user = User.create!(name: \"Hidden\", github_handle: \"hidden-method\", talks_count: 0)\n    user.update!(searchable: false)\n\n    assert_not user.indexable?\n  end\n\n  test \"indexable? returns false for users marked for deletion\" do\n    user = User.create!(name: \"Deleted\", github_handle: \"deleted-method\", marked_for_deletion: true)\n\n    assert_not user.indexable?\n  end\n\n  test \"indexable? returns false for non-canonical users\" do\n    canonical = User.create!(name: \"Canonical\", github_handle: \"canonical-method\")\n    non_canonical = User.create!(name: \"Non Canonical\", github_handle: \"non-canonical-method\", canonical_id: canonical.id)\n\n    assert_not non_canonical.indexable?\n  end\n\n  test \"creates alias when verified user changes name\" do\n    user = User.create!(name: \"Original Name\", github_handle: \"alias-test-user\")\n    user.connected_accounts.create!(provider: \"github\", uid: \"12345\")\n\n    user.update!(name: \"New Name\")\n\n    assert_equal 1, user.aliases.count\n    alias_record = user.aliases.first\n    assert_equal \"Original Name\", alias_record.name\n    assert_equal \"original-name\", alias_record.slug\n  end\n\n  test \"does not create alias when user without connected account changes name\" do\n    user = User.create!(name: \"Original Name\", github_handle: \"no-account-alias-test\")\n\n    user.update!(name: \"New Name\")\n\n    assert_equal 0, user.aliases.count\n  end\n\n  test \"does not create duplicate alias when name changes back\" do\n    user = User.create!(name: \"Original Name\", github_handle: \"duplicate-alias-test\")\n    user.connected_accounts.create!(provider: \"github\", uid: \"67890\")\n\n    user.update!(name: \"New Name\")\n    user.update!(name: \"Another Name\")\n    user.update!(name: \"Original Name\")\n    user.update!(name: \"Original Name\")\n\n    assert_equal 3, user.aliases.count\n    assert user.aliases.exists?(name: \"Original Name\")\n    assert user.aliases.exists?(name: \"New Name\")\n    assert user.aliases.exists?(name: \"Another Name\")\n\n    user.update!(name: \"New Name\")\n    assert_equal 3, user.aliases.count\n  end\n\n  test \"does not create alias when name is blank\" do\n    user = User.create!(name: \"Has Name\", github_handle: \"blank-name-alias-test\")\n    user.connected_accounts.create!(provider: \"github\", uid: \"11111\")\n\n    user.update_columns(name: \"\")\n    user.reload\n    user.update!(name: \"New Name\")\n\n    assert_not user.aliases.exists?(name: \"\")\n  end\n\n  test \"find_by_name_or_alias finds user by previous name after rename\" do\n    user = User.create!(name: \"Speaker Original\", github_handle: \"speaker-rename-test\")\n    user.connected_accounts.create!(provider: \"github\", uid: \"22222\")\n\n    user.update!(name: \"Speaker New Name\")\n\n    found_user = User.find_by_name_or_alias(\"Speaker Original\")\n    assert_equal user.id, found_user.id\n  end\n\n  test \"belongs to city record\" do\n    user = User.create!(\n      name: \"Amsterdam User\",\n      github_handle: \"amsterdam-user\",\n      city: \"Amsterdam\",\n      country_code: \"NL\",\n      state_code: \"\",\n      latitude: 52.3676,\n      longitude: 4.9041,\n      geocode_metadata: {\"geocoder_city\" => \"Amsterdam\"}\n    )\n    assert_equal \"Amsterdam\", user.city_record.name\n    assert user.city_record.users.include?(user)\n  end\nend\n"
  },
  {
    "path": "test/models/youtube/video_metadata_rails_worldtest.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: events\n#\n#  id              :integer          not null, primary key\n#  date            :date\n#  city            :string\n#  country_code    :string\n#  organisation_id :integer          not null\n#  created_at      :datetime         not null\n#  updated_at      :datetime         not null\n#  name            :string           default(\"\"), not null\n#  slug            :string           default(\"\"), not null\n#\n# rubocop:enable Layout/LineLength\nrequire \"test_helper\"\n\nclass YouTube::VideoMetadataRailsWorldTest < ActiveSupport::TestCase\n  test \"remove the event name from the title and preserve the keynote mention\" do\n    metadata = OpenStruct.new({\n      title: \"Nikita Vasilevsky - Implementing Native Composite Primary Key Support in Rails 7.1 - Rails World '23\",\n      description: \"RailsWorld 2023 lorem ipsum\"\n    })\n    results = YouTube::VideoMetadataRailsWorld.new(metadata: metadata, event_name: \"Rails World 23\")\n    assert_equal results.cleaned.title, \"Implementing Native Composite Primary Key Support in Rails 7.1\"\n    refute results.keynote?\n  end\nend\n"
  },
  {
    "path": "test/models/youtube/video_metadata_test.rb",
    "content": "# rubocop:disable Layout/LineLength\n# == Schema Information\n#\n# Table name: events\n#\n#  id              :integer          not null, primary key\n#  date            :date\n#  city            :string\n#  country_code    :string\n#  organisation_id :integer          not null\n#  created_at      :datetime         not null\n#  updated_at      :datetime         not null\n#  name            :string           default(\"\"), not null\n#  slug            :string           default(\"\"), not null\n#\n# rubocop:enable Layout/LineLength\nrequire \"test_helper\"\n\nclass YouTube::VideoMetadataTest < ActiveSupport::TestCase\n  test \"remove the event name from the title and preserve the keynote mention\" do\n    metadata = OpenStruct.new({\n      title: \"RailsConf 2021: Keynote: Eileen M. Uchitelle - All the Things I Thought I Couldn't Do\",\n      description: \"RailsConf 2021 lorem ipsum\"\n    })\n    results = YouTube::VideoMetadata.new(metadata: metadata, event_name: \"RailsConf 2021\")\n    assert_equal \"Keynote: Eileen M. Uchitelle - All the Things I Thought I Couldn't Do\", results.cleaned.title\n    assert results.keynote?\n  end\n\n  test \"extract mutiple speakers\" do\n    metadata = OpenStruct.new({\n      title: \"RailsConf 2022 - Spacecraft! The care and keeping of a legacy ... by Annie Lydens & Jenny Allar\",\n      description: \"lorem ipsum\"\n    })\n    results = YouTube::VideoMetadata.new(metadata: metadata, event_name: \"RailsConf 2022\").cleaned\n    assert_equal \"Spacecraft! The care and keeping of a legacy ...\", results.title\n    assert_equal [\"Annie Lydens\", \"Jenny Allar\"], results.speakers\n  end\n\n  test \"extract mutiple speakers with 'and' in the name\" do\n    metadata = OpenStruct.new({\n      title: \"RubyConf AU 2013: From Stubbies to Longnecks by Geoffrey Giesemann\",\n      description: \"lorem ipsum\"\n    })\n    results = YouTube::VideoMetadata.new(metadata: metadata, event_name: \"RubyConf AU 2013\").cleaned\n    assert_equal \"From Stubbies to Longnecks\", results.title\n    assert_equal [\"Geoffrey Giesemann\"], results.speakers\n  end\n\n  test \"lighting talks\" do\n    metadata = OpenStruct.new({\n      title: \"RubyConf AU 2013: Lightning Talks\",\n      description: \"lorem ipsum\"\n    })\n\n    results = YouTube::VideoMetadata.new(metadata: metadata, event_name: \"RubyConf AU 2013\").cleaned\n    assert_equal \"Lightning Talks\", results.title\n    assert_equal [], results.speakers\n  end\n\n  test \"speaker name containing and\" do\n    metadata = OpenStruct.new({\n      title: \"RubyConf AU 2017 - Writing a Gameboy emulator in Ruby, by Colby Swandale\"\n    })\n\n    results = YouTube::VideoMetadata.new(metadata: metadata, event_name: \"RubyConf AU 2017\").cleaned\n    assert_equal [\"Colby Swandale\"], results.speakers\n    assert_equal \"Writing a Gameboy emulator in Ruby\", results.title\n  end\n\n  # test \"speaker name containing &\" do\n  #   metadata = OpenStruct.new({\n  #     title: \"RubyConf AU 2017 - VR backend rails vs serverless: froth or future? Ram Ramakrishnan & Janet Brown\"\n  #   })\n\n  #   results = YouTube::VideoMetadata.new(metadata: metadata, event_name: \"RubyConf AU 2017\").cleaned\n  #   assert_equal [\"Ram Ramakrishnan\", \"Janet Brown\"], results.speakers\n  #   assert_equal \"VR backend rails vs serverless: froth or future?\", results.title\n  # end\n\n  # test \"By separator should be case insensitive\" do\n  #   metadata = OpenStruct.new({\n  #     title: \"RubyConf AU 2017 - Simple and Awesome Database Tricks, By Barrett Clark\"\n  #   })\n\n  #   results = YouTube::VideoMetadata.new(metadata: metadata, event_name: \"RubyConf AU 2017\").cleaned\n  #   assert_equal [\"Barrett Clark\"], results.speakers\n  #   assert_equal \"Simple and Awesome Database Tricks\", results.title\n  # end\nend\n"
  },
  {
    "path": "test/system/call_for_papers_test.rb",
    "content": "require \"application_system_test_case\"\n\nclass CallForPapersTest < ApplicationSystemTestCase\n  setup do\n    @event = events(:future_conference)\n  end\n\n  test \"visiting the index\" do\n    skip\n    visit root_url\n\n    click_on \"CFP\"\n    assert_selector \"h1\", text: \"Open Call for Proposals\"\n  end\nend\n"
  },
  {
    "path": "test/system/events_test.rb",
    "content": "require \"application_system_test_case\"\n\nclass EventsTest < ApplicationSystemTestCase\n  setup do\n    @event = events(:railsconf_2017)\n  end\n\n  test \"visiting the index\" do\n    events(:tropical_rb_2024)\n    visit root_url\n\n    click_on \"Events\"\n    assert_selector \"h1\", text: \"Upcoming Events\"\n\n    click_on \"Archive\"\n    assert_selector \"h1\", text: \"Events Archive\"\n\n    find(\"a#t\", text: \"T\").click\n    assert_selector \"span\", text: \"Tropical Ruby\"\n  end\n\n  test \"visiting the show\" do\n    visit event_url(@event)\n    assert_selector \"h1\", text: @event.name\n  end\n\n  # Currently this test fails for 2 reasons:\n  # 1. The \"Edit this event\" button is on events_url\n  # 2. 'Description', 'Frequency', 'Kind' and 'Website' are attributes of the event's organisation, not the even itself\n  # The update method and the form would need to be amended for the method to work\n  # test \"should update Event\" do\n  #   visit event_url(@event)\n  #   click_on \"Edit this event\", match: :first\n\n  #   fill_in \"Description\", with: @event.description\n  #   fill_in \"Frequency\", with: @event.frequency\n  #   fill_in \"Kind\", with: @event.kind\n  #   fill_in \"Name\", with: @event.name\n  #   fill_in \"Website\", with: @event.website\n  #   click_on \"Update Event\"\n\n  #   assert_text \"Event was successfully updated\"\n  #   click_on \"Back\"\n  # end\nend\n"
  },
  {
    "path": "test/system/sessions_test.rb",
    "content": "# require \"application_system_test_case\"\n\n# class SessionsTest < ApplicationSystemTestCase\n#   setup do\n#     @user = users(:lazaro_nixon)\n#   end\n\n#   test \"visiting the index\" do\n#     sign_in_as @user\n#     visit sessions_path\n\n#     assert_selector \"h1\", text: \"Sessions\"\n#   end\n\n#   test \"signing in\" do\n#     visit sessions_url\n#     fill_in \"Email\", with: @user.email\n#     fill_in \"Password\", with: \"Secret1*3*5*\"\n#     click_on \"Sign in\"\n\n#     assert_text \"Signed in successfully\"\n#   end\n\n#   # test \"signing out\" do\n#   #   sign_in_as @user\n\n#   #   click_on \"Log out\"\n#   #   assert_text \"That session has been logged out\"\n#   # end\n# end\n"
  },
  {
    "path": "test/system/speakers_test.rb",
    "content": "require \"application_system_test_case\"\n\nclass SpeakersTest < ApplicationSystemTestCase\n  setup do\n    @speaker = users(:marco)\n  end\n\n  test \"broadcast a speaker about partial\" do\n    # ensure Turbo Stream broadcast is working with Litestack\n    visit speaker_url(@speaker)\n    wait_for_turbo_stream_connected(streamable: @speaker)\n\n    @speaker.update(bio: \"New bio\")\n    @speaker.broadcast_header\n\n    assert_text \"New bio\"\n  end\nend\n"
  },
  {
    "path": "test/system/sponsors_test.rb",
    "content": "require \"application_system_test_case\"\n\nclass SponsorsTest < ApplicationSystemTestCase\n  def setup\n    @sponsor_one = sponsors(:one)\n    @sponsor_two = sponsors(:two)\n    @sponsor_three = sponsors(:three)\n    @organization_one = organizations(:one)\n    @organization_two = organizations(:two)\n    @organization_three = organizations(:three)\n    @railsconf_2017 = events(:railsconf_2017)\n    @no_sponsors_event = events(:no_sponsors_event)\n  end\n\n  test \"visiting the index, clicking on a sponsor from scroll list, and seeing the sponsor's details\" do\n    visit root_url\n\n    assert_link \"Organizations\"\n    click_on \"Organizations\"\n\n    assert_selector \"h1\", text: \"Organizations\"\n\n    within '[data-controller=\"scroll\"]' do\n      assert_text @organization_one.name\n      assert_text @organization_two.name\n      assert_text @organization_three.name\n\n      assert_link @organization_one.name\n      click_on @organization_one.name\n    end\n\n    assert_text @organization_one.name\n    assert_text @organization_one.description\n    assert_text @organization_one.main_location\n    assert_link @organization_one.domain.to_s\n    assert_selector \"img[src*='#{@organization_one.logo_url}']\"\n\n    assert_selector \"input[aria-label='Supported Events (1)'][checked]\"\n    within \".tab-content\" do\n      assert_selector \"h2\", text: @railsconf_2017.start_date.year.to_s\n      assert_text @railsconf_2017.name\n      assert_selector \"a[href='/events/#{@railsconf_2017.slug}']\"\n    end\n\n    assert_selector \"input[aria-label='Statistics']\"\n    find(\"input[aria-label='Statistics']\").click\n    within \".tab-content\" do\n      assert_text \"Total Events Sponsored\\n1\\n#{@railsconf_2017.start_date.year} - #{@railsconf_2017.start_date.year}\\n\"\n\n      assert_text \"Talks at Sponsored Events\\n0\\nSupporting knowledge sharing\\n\"\n\n      assert_text \"Event Series\\n1\\nUnique partnerships\\n\"\n\n      assert_text \"Sponsorship Tiers\\n#{@sponsor_one.tier.capitalize}\\n1\\n\"\n\n      assert_text \"Event Scale\\n⏳\\nEvent Awaiting Content\\n1\\n\"\n\n      assert_text \"Top Supported Event Series\\n#{@railsconf_2017.series.name}\\n1 event\\n\"\n\n      assert_text \"Additional Sponsorships\\n#{@sponsor_one.badge}\\nat\\n#{@railsconf_2017.name}\\n(#{@railsconf_2017.start_date.year})\"\n    end\n\n    assert_link \"Back to Organizations\"\n    click_on \"Back to Organizations\"\n\n    within \"#organizations\" do\n      assert_link @organization_one.name\n      assert_link @organization_two.name\n      assert_link @organization_three.name\n    end\n  end\n\n  test \"visiting the index, clicking on a letter, and seeing the sponsors that start with that letter\" do\n    visit root_url\n\n    assert_link \"Organizations\"\n    click_on \"Organizations\"\n\n    assert_selector \"h1\", text: \"Organizations\"\n\n    within \"#organizations\" do\n      assert_link @organization_one.name\n      assert_link @organization_two.name\n      assert_link @organization_three.name\n    end\n\n    assert_link \"A\"\n    click_on \"A\"\n    within \"#organizations\" do\n      assert_link @organization_one.name\n      assert_no_link @organization_two.name\n      assert_no_link @organization_three.name\n    end\n\n    assert_link \"B\"\n    click_on \"B\"\n    within \"#organizations\" do\n      assert_no_link @organization_one.name\n      assert_link @organization_two.name\n      assert_no_link @organization_three.name\n    end\n\n    assert_link \"C\"\n    click_on \"C\"\n    within \"#organizations\" do\n      assert_no_link @organization_one.name\n      assert_no_link @organization_two.name\n      assert_link @organization_three.name\n    end\n  end\n\n  test \"visiting the index, clicking on the incomplete data notice, and seeing the events that need data\" do\n    visit root_url\n\n    assert_link \"Organizations\"\n    click_on \"Organizations\"\n\n    assert_selector \"h1\", text: \"Organizations\"\n\n    assert_text \"Organization data is incomplete\"\n    assert_text \"Many conferences are still missing sponsor information. Help us complete the database!\"\n    assert_link \"View conferences missing sponsor data\"\n    click_on \"View conferences missing sponsor data\"\n\n    assert_selector \"h1\", text: \"Conferences Missing Sponsor Data\"\n\n    assert_text @no_sponsors_event.name\n    assert_selector \"h2\", text: \"#{@no_sponsors_event.start_date.year} (1 event)\"\n    within \"a[href='/events/#{@no_sponsors_event.slug}']\" do\n      assert_text @no_sponsors_event.name\n      assert_text @no_sponsors_event.series.name\n      assert_text @no_sponsors_event.start_date.strftime(\"%B %Y\")\n      assert_text \"#{@no_sponsors_event.city}, #{@no_sponsors_event.country_code}\"\n    end\n\n    assert_text \"Total conferences missing sponsor data: #{Event.conference.left_joins(:sponsors).where(sponsors: {id: nil}).past.count}\"\n  end\nend\n"
  },
  {
    "path": "test/system/spotlight_search_test.rb",
    "content": "require \"application_system_test_case\"\n\nclass SpotlightSearchTest < ApplicationSystemTestCase\n  test \"show the spotlight search with results\" do\n    visit root_url\n\n    assert_no_selector \"#spotlight-search\"\n\n    assert_selector \"#magnifying-glass\"\n    find(\"#magnifying-glass\").click\n\n    assert_selector \"#spotlight-search\"\n\n    fill_in \"query\", with: \"a\"\n    assert_selector \"#talks_search_results\"\n  end\n\n  test \"open the spotlight search with cmd + k\" do\n    visit root_url\n    find(\"body\").send_keys([:meta, \"k\"])\n    assert_selector \"#spotlight-search\"\n  end\nend\n"
  },
  {
    "path": "test/system/talks_test.rb",
    "content": "require \"application_system_test_case\"\n\nclass TalksTest < ApplicationSystemTestCase\n  setup do\n    @talk = talks(:one)\n    @event = events(:rails_world_2023)\n    @talk.update(event: @event)\n  end\n\n  test \"visiting the index\" do\n    visit talks_url\n    assert_selector \"h1\", text: \"Video Recordings of Talks\"\n  end\n\n  test \"should update Talk\" do\n    visit talk_url(@talk)\n    click_on \"Edit\", match: :first\n\n    fill_in \"Description\", with: @talk.description\n    fill_in \"Title\", with: @talk.title\n    click_on \"Suggest modifications\"\n\n    assert_text \"Your suggestion was successfully created and will be reviewed soon.\"\n  end\n\n  test \"should provide a link to the event of the talk\" do\n    visit talk_url(@talk)\n\n    find(\"#explore-event\").click\n\n    assert_current_path event_path(@event)\n    assert_text @event.name\n  end\n\n  # test \"renders some related talks\" do\n  #   visit talk_url(@talk)\n\n  #   assert_selector \"#recommended_talks\"\n  #   assert_selector \"[data-talk-horizontal-card]\", count: [Talk.excluding(@talk).count, 6].min\n  # end\nend\n"
  },
  {
    "path": "test/tasks/db_seed_test.rb",
    "content": "require \"test_helper\"\n\nclass DbSeedTest < ActiveSupport::TestCase\n  if ENV[\"SEED_SMOKE_TEST\"]\n    self.use_transactional_tests = false # don't use fixtures for this test\n\n    setup do\n      # ensure that the db is pristine\n      ActiveRecord::FixtureSet.reset_cache\n      ActiveRecord::Base.connection.disable_referential_integrity do\n        ActiveRecord::Base.connection.tables.each do |table|\n          ActiveRecord::Base.connection.execute(\"DELETE FROM #{table}\")\n          # Reset SQLite sequences\n          ActiveRecord::Base.connection.execute(\"DELETE FROM sqlite_sequence WHERE name='#{table}'\")\n        end\n      end\n\n      Rails.application.load_tasks\n      Rake::Task[\"db:environment:set\"].reenable\n      Rake::Task[\"db:schema:load\"].invoke\n    end\n\n    test \"db:seed runs successfully\" do\n      assert_nothing_raised do\n        Rake::Task[\"db:seed\"].invoke\n      end\n\n      # ensure that all talks have a date\n      assert_equal Talk.where(date: nil).count, 0\n\n      # Ensuring idempotency\n      assert_no_difference \"Talk.maximum(:created_at)\" do\n        Rake::Task[\"db:seed\"].reenable\n        Rake::Task[\"db:seed\"].invoke\n      end\n\n      static_video_ids = Static::Video.pluck(:video_id)\n      duplicate_ids = static_video_ids.tally.select { |_, count| count > 1 }\n\n      assert User.speakers.count >= 3000\n      assert Talk.count >= 200\n      assert Event.count >= 10\n      assert_equal({}, duplicate_ids)\n    end\n  end\nend\n"
  },
  {
    "path": "test/tasks/seed_test.rb",
    "content": "require \"test_helper\"\n\nclass SeedTest < ActiveSupport::TestCase\n  if ENV[\"SEED_SMOKE_TEST\"]\n    self.use_transactional_tests = false # don't use fixtures for this test\n\n    setup do\n      # ensure that the db is pristine\n      ActiveRecord::FixtureSet.reset_cache\n      ActiveRecord::Base.connection.disable_referential_integrity do\n        ActiveRecord::Base.connection.tables.each do |table|\n          ActiveRecord::Base.connection.execute(\"DELETE FROM #{table}\")\n          # Reset SQLite sequences\n          ActiveRecord::Base.connection.execute(\"DELETE FROM sqlite_sequence WHERE name='#{table}'\")\n        end\n      end\n\n      Rails.application.load_tasks\n      Rake::Task[\"db:environment:set\"].reenable\n      Rake::Task[\"db:schema:load\"].invoke\n    end\n\n    test \"seed:all runs successfully\" do\n      assert_nothing_raised do\n        Rake::Task[\"db:seed:all\"].invoke\n      end\n\n      # ensure that all talks have a date\n      assert_equal Talk.where(date: nil).count, 0\n\n      static_video_ids = Static::Video.pluck(:video_id)\n      talk_video_ids = Talk.all.pluck(:video_id)\n      duplicate_ids = static_video_ids.tally.select { |_, count| count > 1 }\n      assert User.speakers.count >= 3000\n\n      assert_equal({}, duplicate_ids)\n\n      not_created_videos_id = static_video_ids - talk_video_ids\n      events = Static::Video.where(video_id: not_created_videos_id).map(&:event_name)\n\n      events.tally.each do |event_name, missing_count|\n        all_talk_count = Static::Video.where(event_name: event_name).count\n\n        puts \"#{event_name} - All: #{all_talk_count}, missing: #{missing_count}\"\n\n        if missing_count != all_talk_count\n          Static::Video.where(event_name: event_name, video_id: not_created_videos_id).each do |missing_talk|\n            puts \"Missing talk for #{event_name}: #{missing_talk.raw_title}\"\n          end\n          puts \"\"\n        end\n        puts \"---\"\n      end\n\n      assert_equal({}, events.tally)\n      assert_equal 0, not_created_videos_id.count\n    end\n  end\nend\n"
  },
  {
    "path": "test/test_helper.rb",
    "content": "ENV[\"RAILS_ENV\"] ||= \"test\"\nrequire_relative \"../config/environment\"\nrequire \"rails/test_help\"\nrequire \"webmock/minitest\"\nrequire \"vcr\"\nrequire_relative \"helpers/event_tracking_helper\"\n\nVCR.configure do |c|\n  c.cassette_library_dir = \"test/vcr_cassettes\"\n  c.hook_into :webmock\n  c.ignore_localhost = true\n  c.ignore_hosts \"chromedriver.storage.googleapis.com\", \"googlechromelabs.github.io\", \"edgedl.me.gvt1.com\"\n  c.filter_sensitive_data(\"<YOUTUBE_API_KEY>\") { ENV[\"YOUTUBE_API_KEY\"] }\n  c.filter_sensitive_data(\"<GITHUB_TOKEN>\") { ENV[\"RUBYVIDEO_GITHUB_TOKEN\"] }\n  c.filter_sensitive_data(\"<OPENAI_API_KEY>\") { ENV[\"OPENAI_ACCESS_TOKEN\"] }\n  c.filter_sensitive_data(\"<OPENAI_ORGANIZATION_ID>\") { ENV[\"OPENAI_ORGANIZATION_ID\"] }\nend\n\nSearch::Backend.default_backend_key = :sqlite_fts\n\nGeocoder.configure(lookup: :test, ip_lookup: :test)\n\nGeocoder::Lookup::Test.set_default_stub(\n  [\n    {\n      \"coordinates\" => [0.0, 0.0],\n      \"address\" => \"Unknown Location\",\n      \"city\" => nil,\n      \"state\" => nil,\n      \"state_code\" => nil,\n      \"country\" => nil,\n      \"country_code\" => nil\n    }\n  ]\n)\n\nclass ActiveSupport::TestCase\n  include EventTrackingHelper\n\n  setup do\n    Search::Backend.reindex_all\n    User.reset_talks_counts\n\n    Geocoder::Lookup::Test.set_default_stub(\n      [\n        {\n          \"coordinates\" => [0.0, 0.0],\n          \"address\" => \"Unknown Location\",\n          \"city\" => nil,\n          \"state\" => nil,\n          \"state_code\" => nil,\n          \"country\" => nil,\n          \"country_code\" => nil\n        }\n      ]\n    )\n  end\n\n  # Run tests in parallel with specified workers\n  parallelize(workers: :number_of_processors)\n\n  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.\n  fixtures :all\n\n  # Add more helper methods to be used by all tests here...\n  def sign_in_as(user)\n    post(sessions_url, params: {email: user.email, password: \"Secret1*3*5*\"})\n    user\n  end\nend\n"
  },
  {
    "path": "test/tools/cfp_create_tool_test.rb",
    "content": "require \"test_helper\"\nrequire_relative \"../../app/tools/cfp_create_tool\"\n\nclass CFPCreateToolTest < ActiveSupport::TestCase\n  setup do\n    @event = events(:rails_world_2023)\n    @tmp_dir = Dir.mktmpdir\n    @data_folder = Pathname.new(@tmp_dir)\n  end\n\n  teardown do\n    FileUtils.remove_entry(@tmp_dir) if @tmp_dir && File.exist?(@tmp_dir)\n  end\n\n  test \"creates cfp.yml file when it does not exist\" do\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://cfp.example.com\",\n      open_date: \"2025-01-01\",\n      close_date: \"2025-02-01\"\n    )\n\n    assert result[:success]\n    assert_equal @event.name, result[:event]\n    assert File.exist?(File.join(@tmp_dir, \"cfp.yml\"))\n\n    assert_equal <<~STRING, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: Call for Proposals\n        link: https://cfp.example.com\n        open_date: '2025-01-01'\n        close_date: '2025-02-01'\n    STRING\n\n    cfp_content = YAML.load_file(File.join(@tmp_dir, \"cfp.yml\"))\n    assert_equal 1, cfp_content.size\n    assert_equal \"Call for Proposals\", cfp_content.first[\"name\"]\n    assert_equal \"https://cfp.example.com\", cfp_content.first[\"link\"]\n    assert_equal \"2025-01-01\", cfp_content.first[\"open_date\"]\n    assert_equal \"2025-02-01\", cfp_content.first[\"close_date\"]\n  end\n\n  test \"adds to existing cfp.yml file\" do\n    existing_cfp = [{\"name\" => \"Existing CFP\", \"link\" => \"https://existing-cfp.com\", \"open_date\" => \"2024-01-01\"}]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), existing_cfp.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://new-cfp.example.com\",\n      open_date: \"2025-01-01\"\n    )\n\n    assert result[:success]\n\n    assert_equal <<~YAML, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: Existing CFP\n        link: https://existing-cfp.com\n        open_date: '2024-01-01'\n      - name: Call for Proposals\n        link: https://new-cfp.example.com\n        open_date: '2025-01-01'\n    YAML\n  end\n\n  test \"returns error when event is not found\" do\n    tool = CFPCreateTool.new\n\n    result = tool.execute(\n      event_query: \"non-existent-event\",\n      link: \"https://cfp.example.com\"\n    )\n\n    assert result[:error]\n    assert_match(/not found/i, result[:error])\n  end\n\n  test \"returns error when CFP with same link already exists\" do\n    existing_cfp = [{\"link\" => \"https://cfp.example.com\", \"open_date\" => \"2024-01-01\"}]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), existing_cfp.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://cfp.example.com\"\n    )\n\n    assert result[:error]\n    assert_match(/already exists/i, result[:error])\n  end\n\n  test \"does not include open_date when not provided\" do\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://cfp.example.com\"\n    )\n\n    assert result[:success]\n\n    assert_equal <<~YAML, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: Call for Proposals\n        link: https://cfp.example.com\n    YAML\n  end\n\n  test \"includes optional name field when provided\" do\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://cfp.example.com\",\n      name: \"Lightning Talks CFP\"\n    )\n\n    assert result[:success]\n\n    assert_equal <<~YAML, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: Lightning Talks CFP\n        link: https://cfp.example.com\n    YAML\n  end\n\n  test \"finds event by name\" do\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.name,\n      link: \"https://cfp.example.com\"\n    )\n\n    assert result[:success]\n    assert_equal @event.name, result[:event]\n\n    assert_equal <<~YAML, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: Call for Proposals\n        link: https://cfp.example.com\n    YAML\n  end\n\n  test \"finds event by partial search\" do\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: \"Rails World\",\n      link: \"https://cfp.example.com\"\n    )\n\n    assert result[:success]\n    assert_equal @event.name, result[:event]\n\n    assert_equal <<~YAML, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: Call for Proposals\n        link: https://cfp.example.com\n    YAML\n  end\n\n  private\n\n  def build_tool_with_tmp_data_folder\n    data_folder = @data_folder\n    event = @event\n\n    tool = CFPCreateTool.new\n    tool.define_singleton_method(:find_event) do |query|\n      found = Event.find_by(slug: query) ||\n        Event.find_by(slug: query.parameterize) ||\n        Event.find_by(name: query) ||\n        Event.ft_search(query).first\n\n      return nil unless found\n      return found unless found.id == event.id\n\n      # Override data_folder for the matched event\n      found.define_singleton_method(:data_folder) { data_folder }\n      found\n    end\n    tool\n  end\nend\n"
  },
  {
    "path": "test/tools/cfp_info_tool_test.rb",
    "content": "require \"test_helper\"\nrequire_relative \"../../app/tools/cfp_info_tool\"\n\nclass CFPInfoToolTest < ActiveSupport::TestCase\n  setup do\n    @event = events(:rails_world_2023)\n    @tmp_dir = Dir.mktmpdir\n    @data_folder = Pathname.new(@tmp_dir)\n  end\n\n  teardown do\n    FileUtils.remove_entry(@tmp_dir) if @tmp_dir && File.exist?(@tmp_dir)\n  end\n\n  test \"returns CFP information when CFP exists\" do\n    cfp_data = [\n      {\n        \"name\" => \"Call for Proposals\",\n        \"link\" => \"https://cfp.example.com\",\n        \"open_date\" => \"2024-01-01\",\n        \"close_date\" => \"2024-02-01\"\n      }\n    ]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), cfp_data.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(event_query: @event.slug)\n\n    assert_equal @event.name, result[:event]\n    assert_equal 1, result[:cfps].size\n\n    cfp = result[:cfps].first\n    assert_equal \"Call for Proposals\", cfp[:name]\n    assert_equal \"https://cfp.example.com\", cfp[:link]\n    assert_equal \"2024-01-01\", cfp[:open_date]\n    assert_equal \"2024-02-01\", cfp[:close_date]\n  end\n\n  test \"returns empty array when no CFP file exists\" do\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(event_query: @event.slug)\n\n    assert_equal @event.name, result[:event]\n    assert_equal [], result[:cfps]\n    assert_equal \"No CFPs found for this event\", result[:message]\n  end\n\n  test \"returns error when event is not found\" do\n    tool = CFPInfoTool.new\n\n    result = tool.execute(event_query: \"non-existent-event\")\n\n    assert result[:error]\n    assert_match(/not found/i, result[:error])\n  end\n\n  test \"returns multiple CFPs when event has multiple\" do\n    cfp_data = [\n      {\"name\" => \"Main CFP\", \"link\" => \"https://cfp.example.com\"},\n      {\"name\" => \"Lightning Talks\", \"link\" => \"https://lightning.example.com\"}\n    ]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), cfp_data.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(event_query: @event.slug)\n\n    assert_equal 2, result[:cfps].size\n    assert_equal \"Main CFP\", result[:cfps][0][:name]\n    assert_equal \"Lightning Talks\", result[:cfps][1][:name]\n  end\n\n  test \"status is closed when close_date is in the past\" do\n    cfp_data = [\n      {\n        \"name\" => \"CFP\",\n        \"link\" => \"https://cfp.example.com\",\n        \"open_date\" => \"2020-01-01\",\n        \"close_date\" => \"2020-02-01\"\n      }\n    ]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), cfp_data.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(event_query: @event.slug)\n\n    assert_equal \"closed\", result[:cfps].first[:status]\n  end\n\n  test \"status is upcoming when open_date is in the future\" do\n    cfp_data = [\n      {\n        \"name\" => \"CFP\",\n        \"link\" => \"https://cfp.example.com\",\n        \"open_date\" => \"2099-01-01\",\n        \"close_date\" => \"2099-02-01\"\n      }\n    ]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), cfp_data.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(event_query: @event.slug)\n\n    assert_equal \"upcoming\", result[:cfps].first[:status]\n  end\n\n  test \"status is open when today is between open and close dates\" do\n    today = Date.current\n    cfp_data = [\n      {\n        \"name\" => \"CFP\",\n        \"link\" => \"https://cfp.example.com\",\n        \"open_date\" => (today - 10.days).to_s,\n        \"close_date\" => (today + 10.days).to_s\n      }\n    ]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), cfp_data.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(event_query: @event.slug)\n\n    assert_equal \"open\", result[:cfps].first[:status]\n  end\n\n  test \"status is open when only open_date is set and it is in the past\" do\n    cfp_data = [\n      {\n        \"name\" => \"CFP\",\n        \"link\" => \"https://cfp.example.com\",\n        \"open_date\" => \"2020-01-01\"\n      }\n    ]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), cfp_data.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(event_query: @event.slug)\n\n    assert_equal \"open\", result[:cfps].first[:status]\n  end\n\n  test \"status is unknown when no dates are set\" do\n    cfp_data = [\n      {\n        \"name\" => \"CFP\",\n        \"link\" => \"https://cfp.example.com\"\n      }\n    ]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), cfp_data.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(event_query: @event.slug)\n\n    assert_equal \"unknown\", result[:cfps].first[:status]\n  end\n\n  test \"finds event by name\" do\n    cfp_data = [{\"link\" => \"https://cfp.example.com\"}]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), cfp_data.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(event_query: @event.name)\n\n    assert_equal @event.name, result[:event]\n  end\n\n  private\n\n  def build_tool_with_tmp_data_folder\n    data_folder = @data_folder\n    event = @event\n\n    tool = CFPInfoTool.new\n    tool.define_singleton_method(:find_event) do |query|\n      found = Event.find_by(slug: query) ||\n        Event.find_by(slug: query.parameterize) ||\n        Event.find_by(name: query) ||\n        Event.ft_search(query).first\n\n      return nil unless found\n      return found unless found.id == event.id\n\n      found.define_singleton_method(:data_folder) { data_folder }\n      found\n    end\n\n    tool\n  end\nend\n"
  },
  {
    "path": "test/tools/cfp_update_tool_test.rb",
    "content": "require \"test_helper\"\nrequire_relative \"../../app/tools/cfp_update_tool\"\n\nclass CFPUpdateToolTest < ActiveSupport::TestCase\n  setup do\n    @event = events(:rails_world_2023)\n    @tmp_dir = Dir.mktmpdir\n    @data_folder = Pathname.new(@tmp_dir)\n  end\n\n  teardown do\n    FileUtils.remove_entry(@tmp_dir) if @tmp_dir && File.exist?(@tmp_dir)\n  end\n\n  test \"updates close_date on existing CFP\" do\n    existing_cfp = [{\"name\" => \"Call for Proposal\", \"link\" => \"https://cfp.example.com\", \"open_date\" => \"2025-01-01\"}]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), existing_cfp.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://cfp.example.com\",\n      close_date: \"2025-02-15\"\n    )\n\n    assert result[:success]\n\n    assert_equal <<~YAML, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: Call for Proposal\n        link: https://cfp.example.com\n        open_date: '2025-01-01'\n        close_date: '2025-02-15'\n    YAML\n  end\n\n  test \"updates open_date on existing CFP\" do\n    existing_cfp = [{\"name\" => \"Call for Proposal\", \"link\" => \"https://cfp.example.com\"}]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), existing_cfp.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://cfp.example.com\",\n      open_date: \"2025-01-15\"\n    )\n\n    assert result[:success]\n\n    assert_equal <<~YAML, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: Call for Proposal\n        link: https://cfp.example.com\n        open_date: '2025-01-15'\n    YAML\n  end\n\n  test \"updates name on existing CFP\" do\n    existing_cfp = [{\"name\" => \"Old Name\", \"link\" => \"https://cfp.example.com\"}]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), existing_cfp.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://cfp.example.com\",\n      name: \"New Name\"\n    )\n\n    assert result[:success]\n\n    assert_equal <<~YAML, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: New Name\n        link: https://cfp.example.com\n    YAML\n  end\n\n  test \"updates multiple fields at once\" do\n    existing_cfp = [{\"name\" => \"Call for Proposal\", \"link\" => \"https://cfp.example.com\"}]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), existing_cfp.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://cfp.example.com\",\n      open_date: \"2025-01-01\",\n      close_date: \"2025-02-28\"\n    )\n\n    assert result[:success]\n\n    assert_equal <<~YAML, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: Call for Proposal\n        link: https://cfp.example.com\n        open_date: '2025-01-01'\n        close_date: '2025-02-28'\n    YAML\n  end\n\n  test \"returns error when CFP does not exist\" do\n    existing_cfp = [{\"name\" => \"Call for Proposal\", \"link\" => \"https://other-cfp.com\"}]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), existing_cfp.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://cfp.example.com\",\n      close_date: \"2025-02-15\"\n    )\n\n    assert result[:error]\n    assert_match(/no cfp found/i, result[:error])\n  end\n\n  test \"returns error when event is not found\" do\n    tool = CFPUpdateTool.new\n\n    result = tool.execute(\n      event_query: \"non-existent-event\",\n      link: \"https://cfp.example.com\",\n      close_date: \"2025-02-15\"\n    )\n\n    assert result[:error]\n    assert_match(/not found/i, result[:error])\n  end\n\n  test \"only updates the matching CFP when multiple exist\" do\n    existing_cfps = [\n      {\"name\" => \"Main CFP\", \"link\" => \"https://main-cfp.com\", \"open_date\" => \"2025-01-01\"},\n      {\"name\" => \"Lightning Talks\", \"link\" => \"https://lightning-cfp.com\", \"open_date\" => \"2025-03-01\"}\n    ]\n    File.write(File.join(@tmp_dir, \"cfp.yml\"), existing_cfps.to_yaml)\n\n    tool = build_tool_with_tmp_data_folder\n\n    result = tool.execute(\n      event_query: @event.slug,\n      link: \"https://lightning-cfp.com\",\n      close_date: \"2025-04-15\"\n    )\n\n    assert result[:success]\n\n    assert_equal <<~YAML, File.read(File.join(@tmp_dir, \"cfp.yml\"))\n      ---\n      - name: Main CFP\n        link: https://main-cfp.com\n        open_date: '2025-01-01'\n      - name: Lightning Talks\n        link: https://lightning-cfp.com\n        open_date: '2025-03-01'\n        close_date: '2025-04-15'\n    YAML\n  end\n\n  private\n\n  def build_tool_with_tmp_data_folder\n    data_folder = @data_folder\n    event = @event\n\n    tool = CFPUpdateTool.new\n    tool.define_singleton_method(:find_event) do |query|\n      found = Event.find_by(slug: query) ||\n        Event.find_by(slug: query.parameterize) ||\n        Event.find_by(name: query) ||\n        Event.ft_search(query).first\n\n      return nil unless found\n      return found unless found.id == event.id\n\n      found.define_singleton_method(:data_folder) { data_folder }\n      found\n    end\n    tool\n  end\nend\n"
  },
  {
    "path": "test/vcr_cassettes/profiles/enhance_controller_test/patch.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: get\n    uri: https://api.github.com/users/marcoroth\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept:\n      - application/vnd.github+json\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Wed, 27 Aug 2025 06:28:34 GMT\n      Content-Type:\n      - application/json; charset=utf-8\n      Cache-Control:\n      - public, max-age=60, s-maxage=60\n      Vary:\n      - Accept,Accept-Encoding, Accept, X-Requested-With\n      Etag:\n      - W/\"72353cef35ce731c840751dfc2bb90b148226491dc37794c1b5a105b1a544a6d\"\n      Last-Modified:\n      - Thu, 31 Jul 2025 00:01:14 GMT\n      X-Github-Media-Type:\n      - github.v3; format=json\n      X-Github-Api-Version-Selected:\n      - '2022-11-28'\n      Access-Control-Expose-Headers:\n      - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining,\n        X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes,\n        X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO,\n        X-GitHub-Request-Id, Deprecation, Sunset\n      Access-Control-Allow-Origin:\n      - \"*\"\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubdomains; preload\n      X-Frame-Options:\n      - deny\n      X-Content-Type-Options:\n      - nosniff\n      X-Xss-Protection:\n      - '0'\n      Referrer-Policy:\n      - origin-when-cross-origin, strict-origin-when-cross-origin\n      Content-Security-Policy:\n      - default-src 'none'\n      Server:\n      - github.com\n      Accept-Ranges:\n      - bytes\n      X-Ratelimit-Limit:\n      - '60'\n      X-Ratelimit-Remaining:\n      - '41'\n      X-Ratelimit-Reset:\n      - '1756278627'\n      X-Ratelimit-Resource:\n      - core\n      X-Ratelimit-Used:\n      - '19'\n      Content-Length:\n      - '1308'\n      X-Github-Request-Id:\n      - 8CEB:12AD:308CA60:2DDAC18:68AEA592\n    body:\n      encoding: ASCII-8BIT\n      string: '{\"login\":\"marcoroth\",\"id\":6411752,\"node_id\":\"MDQ6VXNlcjY0MTE3NTI=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/6411752?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/marcoroth\",\"html_url\":\"https://github.com/marcoroth\",\"followers_url\":\"https://api.github.com/users/marcoroth/followers\",\"following_url\":\"https://api.github.com/users/marcoroth/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/marcoroth/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/marcoroth/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/marcoroth/subscriptions\",\"organizations_url\":\"https://api.github.com/users/marcoroth/orgs\",\"repos_url\":\"https://api.github.com/users/marcoroth/repos\",\"events_url\":\"https://api.github.com/users/marcoroth/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/marcoroth/received_events\",\"type\":\"User\",\"user_view_type\":\"public\",\"site_admin\":false,\"name\":\"Marco\n        Roth\",\"company\":null,\"blog\":\"https://marcoroth.dev\",\"location\":\"Basel, Switzerland\",\"email\":null,\"hireable\":true,\"bio\":\"Rubyist,\n        Full-Stack Devloper and Open Source Contributor\",\"twitter_username\":\"marcoroth_\",\"public_repos\":235,\"public_gists\":1,\"followers\":757,\"following\":1259,\"created_at\":\"2014-01-15T17:12:11Z\",\"updated_at\":\"2025-07-31T00:01:14Z\"}'\n  recorded_at: Wed, 27 Aug 2025 06:28:34 GMT\n- request:\n    method: get\n    uri: https://api.github.com/users/marcoroth/social_accounts\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept:\n      - application/vnd.github+json\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Wed, 27 Aug 2025 06:28:35 GMT\n      Content-Type:\n      - application/json; charset=utf-8\n      Cache-Control:\n      - public, max-age=60, s-maxage=60\n      Vary:\n      - Accept,Accept-Encoding, Accept, X-Requested-With\n      Etag:\n      - W/\"f08849f5816b536d0a1684db14dfa38b6caaa6fe37648fe70d4a1cd16cb6869b\"\n      X-Github-Media-Type:\n      - github.v3; format=json\n      X-Github-Api-Version-Selected:\n      - '2022-11-28'\n      Access-Control-Expose-Headers:\n      - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining,\n        X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes,\n        X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO,\n        X-GitHub-Request-Id, Deprecation, Sunset\n      Access-Control-Allow-Origin:\n      - \"*\"\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubdomains; preload\n      X-Frame-Options:\n      - deny\n      X-Content-Type-Options:\n      - nosniff\n      X-Xss-Protection:\n      - '0'\n      Referrer-Policy:\n      - origin-when-cross-origin, strict-origin-when-cross-origin\n      Content-Security-Policy:\n      - default-src 'none'\n      Server:\n      - github.com\n      Accept-Ranges:\n      - bytes\n      X-Ratelimit-Limit:\n      - '60'\n      X-Ratelimit-Remaining:\n      - '40'\n      X-Ratelimit-Reset:\n      - '1756278627'\n      X-Ratelimit-Resource:\n      - core\n      X-Ratelimit-Used:\n      - '20'\n      Content-Length:\n      - '263'\n      X-Github-Request-Id:\n      - 8CEC:3B804F:1A660A8:19686CE:68AEA592\n    body:\n      encoding: ASCII-8BIT\n      string: '[{\"provider\":\"twitter\",\"url\":\"https://twitter.com/marcoroth_\"},{\"provider\":\"mastodon\",\"url\":\"https://ruby.social/@marcoroth\"},{\"provider\":\"bluesky\",\"url\":\"https://bsky.app/profile/marcoroth.dev\"},{\"provider\":\"linkedin\",\"url\":\"https://linkedin.com/in/marco-roth\"}]'\n  recorded_at: Wed, 27 Aug 2025 06:28:35 GMT\n- request:\n    method: get\n    uri: https://api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=marcoroth.dev\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n      Host:\n      - api.bsky.app\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      X-Powered-By:\n      - Express\n      Access-Control-Allow-Origin:\n      - \"*\"\n      Atproto-Content-Labelers:\n      - did:plc:ar7c4by46qjdydhdevvrndac;redact\n      Content-Type:\n      - application/json; charset=utf-8\n      Etag:\n      - W/\"45c-2YZVFNvJPNAbbVzaGZ6VbgrCZF0\"\n      Vary:\n      - Accept-Encoding\n      Date:\n      - Wed, 27 Aug 2025 06:28:35 GMT\n      Keep-Alive:\n      - timeout=90\n      Transfer-Encoding:\n      - chunked\n      Strict-Transport-Security:\n      - max-age=63072000\n    body:\n      encoding: ASCII-8BIT\n      string: !binary |-\n        eyJkaWQiOiJkaWQ6cGxjOmZ2YW1nYmxldWRzemFvMnVmdDNzeXN1YiIsImhhbmRsZSI6Im1hcmNvcm90aC5kZXYiLCJkaXNwbGF5TmFtZSI6Ik1hcmNvIFJvdGgiLCJhdmF0YXIiOiJodHRwczovL2Nkbi5ic2t5LmFwcC9pbWcvYXZhdGFyL3BsYWluL2RpZDpwbGM6ZnZhbWdibGV1ZHN6YW8ydWZ0M3N5c3ViL2JhZmtyZWlkZnB5c3A3cXprdHEzcjdjcTRqanZnZ2p4ZTRma2p6N3h5a3E2aWFoNmdpN3p4ZG9pZWNlQGpwZWciLCJhc3NvY2lhdGVkIjp7Imxpc3RzIjowLCJmZWVkZ2VucyI6MCwic3RhcnRlclBhY2tzIjowLCJsYWJlbGVyIjpmYWxzZSwiYWN0aXZpdHlTdWJzY3JpcHRpb24iOnsiYWxsb3dTdWJzY3JpcHRpb25zIjoiZm9sbG93ZXJzIn19LCJsYWJlbHMiOltdLCJjcmVhdGVkQXQiOiIyMDIzLTExLTExVDE2OjQ5OjQ5LjM1NloiLCJkZXNjcmlwdGlvbiI6IkZ1bGwtU3RhY2sgV2ViIERldmVsb3BlciDigKIgT1NTIENvbnRyaWJ1dG9yIOKAoiBFbGVjdHJvbmljIE11c2ljIEFkZGljdCDigKIgUnVieS9SYWlscywgSmF2YVNjcmlwdC9TdGltdWx1cywgQ3J5c3RhbCDigKIgSG90d2lyZSBDb250cmlidXRvcnMgVGVhbSDigKIgU3RpbXVsdXNSZWZsZXggQ29yZS5cclxuXG5XZWJzaXRlOiBtYXJjb3JvdGguZGV2XG5cbkJ1aWxkaW5nOiBydWJ5ZXZlbnRzLm9yZyB8IHJ1Ynljb25mZXJlbmNlcy5vcmcgfCBnZW0uc2ggfCBob3R3aXJlLmlvIiwiaW5kZXhlZEF0IjoiMjAyNS0wNy0xMVQwNzozNzowMC45MzJaIiwiYmFubmVyIjoiaHR0cHM6Ly9jZG4uYnNreS5hcHAvaW1nL2Jhbm5lci9wbGFpbi9kaWQ6cGxjOmZ2YW1nYmxldWRzemFvMnVmdDNzeXN1Yi9iYWZrcmVpZm5pY21pb3hobjZ5eGs1cWNncnFicnQ2NGxycWpoeHp0dWZlcGk2NjRndWJ4ZWc0Y3RlaUBqcGVnIiwiZm9sbG93ZXJzQ291bnQiOjE3ODQsImZvbGxvd3NDb3VudCI6MjYyLCJwb3N0c0NvdW50Ijo2MjUsInBpbm5lZFBvc3QiOnsiY2lkIjoiYmFmeXJlaWVucXFnNmdwY3Z5eWE3djc2d2VvY21vbTU1ZGo0Z2FvYXl4ZW1rcGZ1dmZ4dTR5czZlaG0iLCJ1cmkiOiJhdDovL2RpZDpwbGM6ZnZhbWdibGV1ZHN6YW8ydWZ0M3N5c3ViL2FwcC5ic2t5LmZlZWQucG9zdC8zbGx3Z3dxcHRmMjJsIn19\n  recorded_at: Wed, 27 Aug 2025 06:28:35 GMT\nrecorded_with: VCR 6.3.1\n"
  },
  {
    "path": "test/vcr_cassettes/recurring_youtube_statistics_job.yml",
    "content": "---\nhttp_interactions:\n  - request:\n      method: get\n      uri: https://youtube.googleapis.com/youtube/v3/videos?id=F75k4Oc6g9Q&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&part=statistics\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 200\n        message: OK\n      headers:\n        Content-Type:\n          - application/json; charset=UTF-8\n        Vary:\n          - Origin\n          - Referer\n          - X-Origin\n        Date:\n          - Wed, 08 Jan 2025 22:23:33 GMT\n        Server:\n          - scaffolding on HTTPServer2\n        X-Xss-Protection:\n          - \"0\"\n        X-Frame-Options:\n          - SAMEORIGIN\n        X-Content-Type-Options:\n          - nosniff\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n        Transfer-Encoding:\n          - chunked\n      body:\n        encoding: ASCII-8BIT\n        string: |\n          {\n            \"kind\": \"youtube#videoListResponse\",\n            \"etag\": \"V60dqYQfDUoSn3bi_kr_AEZP2KU\",\n            \"items\": [\n              {\n                \"kind\": \"youtube#video\",\n                \"etag\": \"pVbmMiy3eNUSosIwPZ4Fgc5MK2o\",\n                \"id\": \"F75k4Oc6g9Q\",\n                \"statistics\": {\n                  \"viewCount\": \"13105\",\n                  \"likeCount\": \"371\",\n                  \"favoriteCount\": \"0\",\n                  \"commentCount\": \"31\"\n                }\n              }\n            ],\n            \"pageInfo\": {\n              \"totalResults\": 1,\n              \"resultsPerPage\": 1\n            }\n          }\n    recorded_at: Wed, 08 Jan 2025 22:23:33 GMT\nrecorded_with: VCR 6.3.1\n"
  },
  {
    "path": "test/vcr_cassettes/sessions/omniauth_controller_test/creates_a_new_user_if_not_exists_github.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: get\n    uri: https://api.github.com/users/rosa\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept:\n      - application/vnd.github+json\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Thu, 04 Sep 2025 20:44:06 GMT\n      Content-Type:\n      - application/json; charset=utf-8\n      Cache-Control:\n      - public, max-age=60, s-maxage=60\n      Vary:\n      - Accept,Accept-Encoding, Accept, X-Requested-With\n      Etag:\n      - W/\"557215aefe6aa7b52f7f941daf7ff34b8581484dd3b163cde3401a7de0b5135e\"\n      Last-Modified:\n      - Wed, 03 Sep 2025 12:43:41 GMT\n      X-Github-Media-Type:\n      - github.v3; format=json\n      X-Github-Api-Version-Selected:\n      - '2022-11-28'\n      Access-Control-Expose-Headers:\n      - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining,\n        X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes,\n        X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO,\n        X-GitHub-Request-Id, Deprecation, Sunset\n      Access-Control-Allow-Origin:\n      - \"*\"\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubdomains; preload\n      X-Frame-Options:\n      - deny\n      X-Content-Type-Options:\n      - nosniff\n      X-Xss-Protection:\n      - '0'\n      Referrer-Policy:\n      - origin-when-cross-origin, strict-origin-when-cross-origin\n      Content-Security-Policy:\n      - default-src 'none'\n      Server:\n      - github.com\n      Accept-Ranges:\n      - bytes\n      X-Ratelimit-Limit:\n      - '60'\n      X-Ratelimit-Remaining:\n      - '59'\n      X-Ratelimit-Reset:\n      - '1757022246'\n      X-Ratelimit-Resource:\n      - core\n      X-Ratelimit-Used:\n      - '1'\n      Content-Length:\n      - '1200'\n      X-Github-Request-Id:\n      - CB06:15E08C:2712EE:236A82:68B9FA16\n    body:\n      encoding: ASCII-8BIT\n      string: '{\"login\":\"rosa\",\"id\":813033,\"node_id\":\"MDQ6VXNlcjgxMzAzMw==\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/813033?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/rosa\",\"html_url\":\"https://github.com/rosa\",\"followers_url\":\"https://api.github.com/users/rosa/followers\",\"following_url\":\"https://api.github.com/users/rosa/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/rosa/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/rosa/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/rosa/subscriptions\",\"organizations_url\":\"https://api.github.com/users/rosa/orgs\",\"repos_url\":\"https://api.github.com/users/rosa/repos\",\"events_url\":\"https://api.github.com/users/rosa/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/rosa/received_events\",\"type\":\"User\",\"user_view_type\":\"public\",\"site_admin\":false,\"name\":\"Rosa\n        Gutierrez\",\"company\":\"@37signals \",\"blog\":\"https://rosa.codes\",\"location\":\"Madrid\",\"email\":null,\"hireable\":null,\"bio\":\"Programming\n        at 37signals\",\"twitter_username\":null,\"public_repos\":20,\"public_gists\":3,\"followers\":667,\"following\":1,\"created_at\":\"2011-05-26T21:10:32Z\",\"updated_at\":\"2025-09-03T12:43:41Z\"}'\n  recorded_at: Thu, 04 Sep 2025 20:44:06 GMT\n- request:\n    method: get\n    uri: https://api.github.com/users/rosa/social_accounts\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept:\n      - application/vnd.github+json\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Thu, 04 Sep 2025 20:44:06 GMT\n      Content-Type:\n      - application/json; charset=utf-8\n      Cache-Control:\n      - public, max-age=60, s-maxage=60\n      Vary:\n      - Accept,Accept-Encoding, Accept, X-Requested-With\n      Etag:\n      - W/\"fcdfd3602cf2a3a5e00200fd6f7f351ffca9e99168b8be37c405883ab0071a17\"\n      X-Github-Media-Type:\n      - github.v3; format=json\n      X-Github-Api-Version-Selected:\n      - '2022-11-28'\n      Access-Control-Expose-Headers:\n      - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining,\n        X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes,\n        X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO,\n        X-GitHub-Request-Id, Deprecation, Sunset\n      Access-Control-Allow-Origin:\n      - \"*\"\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubdomains; preload\n      X-Frame-Options:\n      - deny\n      X-Content-Type-Options:\n      - nosniff\n      X-Xss-Protection:\n      - '0'\n      Referrer-Policy:\n      - origin-when-cross-origin, strict-origin-when-cross-origin\n      Content-Security-Policy:\n      - default-src 'none'\n      Server:\n      - github.com\n      Accept-Ranges:\n      - bytes\n      X-Ratelimit-Limit:\n      - '60'\n      X-Ratelimit-Remaining:\n      - '58'\n      X-Ratelimit-Reset:\n      - '1757022246'\n      X-Ratelimit-Resource:\n      - core\n      X-Ratelimit-Used:\n      - '2'\n      Content-Length:\n      - '68'\n      X-Github-Request-Id:\n      - CB0B:C557F:2AFC05:26F053:68B9FA16\n    body:\n      encoding: ASCII-8BIT\n      string: '[{\"provider\":\"bluesky\",\"url\":\"https://bsky.app/profile/rosa.codes\"}]'\n  recorded_at: Thu, 04 Sep 2025 20:44:06 GMT\nrecorded_with: VCR 6.3.1\n"
  },
  {
    "path": "test/vcr_cassettes/talks/extract_topics.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: post\n    uri: https://api.openai.com/v1/chat/completions\n    body:\n      encoding: UTF-8\n      string: '{\"model\":\"gpt-4o-mini\",\"response_format\":{\"type\":\"json_schema\",\"json_schema\":{\"name\":\"talk_topics\",\"schema\":{\"type\":\"object\",\"strict\":true,\"properties\":{\"topics\":{\"type\":\"array\",\"description\":\"A\n        list of topics related to the \",\"items\":{\"type\":\"string\",\"description\":\"A\n        single topic.\"}}},\"required\":[\"topics\"],\"additionalProperties\":false}}},\"messages\":[{\"role\":\"system\",\"content\":\"You\n        are a helpful assistant skilled in assigned a list of predefined topics to\n        a transcript.\"},{\"role\":\"user\",\"content\":\"You are tasked with figuring out\n        of the list of provided topics matches a transcript based on the transcript\n        and its metadata. Follow these steps carefully:\\n\\n1. First, review the metadata\n        of the video:\\n\\u003cmetadata\\u003e\\n  - title: Hotwire Cookbook: Common Uses,\n        Essential Patterns \\u0026 Best Practices\\n  - description: @SupeRails creator\n        and Rails mentor Yaroslav Shmarov shares how some of the most common frontend\n        problems can be solved with Hotwire.\\n\\nHe covers:\\n- Pagination, search and\n        filtering, modals, live updates, dynamic forms, inline editing, drag \\u0026\n        drop, live previews, lazy loading \\u0026 more\\n- How to achieve more by combining\n        tools (Frames + Streams, StimulusJS, RequestJS, Kredis \\u0026 more)\\n- What\n        are the limits of Hotwire?\\n- How to write readable and maintainable Hotwire\n        code\\n- Bad practices\\n\\n  - speaker name: Yaroslav Shmarov\\n  - event name:\n        Rails World 2023\\n\\u003c/metadata\\u003e\\n\\n2. Next, carefully read through\n        the entire transcript:\\nNote: The transcript is not perfect, it''s a transcription\n        of the video, so it might have some errors.\\n\\u003ctranscript\\u003e\\nso nice\n        to be here with you thank you all for coming so uh my name is uh\\n\\nyaroslav\n        I m from Ukraine you might know me from my blog or from my super Al\\n\\nYouTube\n        channel where I post a lot of stuff about trby and especially about hot fire\n        so I originate from Ukraine\\n\\nfrom the north of Ukraine so right now it is\n        liberated so that is Kev Chernobyl\\n\\nand chern so I used to live 80 kmers\n        away from Chernobyl great\\n\\nplace yeah and uh that is my family s home so\n        it got boned in one of the first\\n\\ndays of war that is my godfather he went\n        to defend Ukraine and uh I mean we are\\n\\nhe has such a beautiful venue but\n        there is the war going on and like just today\\n\\nthe city of har was randomly\n        boned by the Russians and there are many Ruby\\n\\nrails people from Ukraine\n        some of them are actually fighting this is verok he contributed to Ruby and\n        he is actually\\n\\ndefending Ukraine right now but on a positive note I just\n        recently became a father\\n\\nso yeah um it is uh just 2 and a half months ago\n        in uh France and uh today we\\n\\nare going to talk about hot fire\\n\\u003c/transcript\\u003e\\n\\n3.\n        Read through the entire list of exisiting topics for other talks.\\n\\u003ctopics\\u003e\\n  ActiveRecord,\n        ActiveSupport, Topic 1\\n\\u003c/topics\\u003e\\n\\n3 bis. Read through the entire\n        list of topics that we have already rejected for other talks.\\n\\u003crejected_topics\\u003e\\n  Rejected\\n\\u003c/rejected_topics\\u003e\\n\\n4.\n        Pick 5 to 7 topics that would describe the talk best.\\n  You can pick any\n        topic from the list of exisiting topics or create a new one.\\n\\n  If you create\n        a new topic, please ensure that it is relevant to the content of the transcript\n        and match the recommended topics kind.\\n  Also for new topics please ensure\n        they are not a synonym of an existing topic.\\n    - Make sure it fits the\n        overall theme of this website, it''s a website for Ruby related videos, so\n        it should have something to do with Ruby, Web, Programming, Teams, People\n        or Tech.\\n    - Ruby framework names (examples: Rails, Sinatra, Hanami, Ruby\n        on Rails, ...)\\n    - Ruby gem names\\n    - Design patterns names (examples:\n        MVC, MVP, Singleton, Observer, Strategy, Command, Decorator, Composite, Facade,\n        Proxy, Mediator, Memento, Observer, State, Template Method, Visitor, ...)\\n    -\n        Database names (examples: PostgreSQL, MySQL, MongoDB, Redis, Elasticsearch,\n        Cassandra, CouchDB, SQLite, ...)\\n    - front end frameworks names (examples:\n        React, Vue, Angular, Ember, Svelte, Stimulus, Preact, Hyperapp, Inferno, Solid,\n        Mithril, Riot, Polymer, Web Components, Hotwire, Turbo, StimulusReflex, Strada\n        ...)\\n    - front end CSS libraries and framework names (examples: Tailwind,\n        Bootstrap, Bulma, Material UI, Foundation, ...)\\n    - front end JavaScript\n        libraries names (examples: jQuery, D3, Chart.js, Lodash, Moment.js, ...)\\n\\n  Topics\n        are typically one or two words long, with some exceptions such as \\\"Ruby on\n        Rails\\\"\\n\\n5. Format your topics you picked as a JSON object with the following\n        schema:\\n  {\\n    \\\"topics\\\": [\\\"topic1\\\", \\\"topic2\\\", \\\"topic3\\\"]\\n  }\\n\\n6.\n        Ensure that your summary is:\\n  - relevant to the content of the transcript\n        and match the recommended topics kind\\n  - Free of personal opinions or external\n        information not present in the provided content\\n\\n7. Output your JSON object\n        containing the list of topics in the JSON format.\\n\"}]}'\n    headers:\n      Content-Type:\n      - application/json\n      Authorization:\n      - Bearer <OPENAI_API_KEY>\n      Openai-Organization:\n      - \"<OPENAI_ORGANIZATION_ID>\"\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Wed, 11 Dec 2024 06:38:25 GMT\n      Content-Type:\n      - application/json\n      Transfer-Encoding:\n      - chunked\n      Connection:\n      - keep-alive\n      Access-Control-Expose-Headers:\n      - X-Request-ID\n      Openai-Organization:\n      - user-cnr3hw7frpcuxb74nqkxv0ci\n      Openai-Processing-Ms:\n      - '926'\n      Openai-Version:\n      - '2020-10-01'\n      X-Ratelimit-Limit-Requests:\n      - '5000'\n      X-Ratelimit-Limit-Tokens:\n      - '4000000'\n      X-Ratelimit-Remaining-Requests:\n      - '4999'\n      X-Ratelimit-Remaining-Tokens:\n      - '3998893'\n      X-Ratelimit-Reset-Requests:\n      - 12ms\n      X-Ratelimit-Reset-Tokens:\n      - 16ms\n      X-Request-Id:\n      - req_fb495483882657f426d87ed755410795\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubDomains; preload\n      Cf-Cache-Status:\n      - DYNAMIC\n      Set-Cookie:\n      - __cf_bm=yXrEXHm9cbYwiX6oqLKJwS06QV7EJsOACW35AhOUZAI-1733899105-1.0.1.1-polXcWhn4TpwkWora3bcpUggI_XK8lNcRNmMwa2SqvOmdoMvoQ9Pk_EALNPC5J938QUD5akO0n3voZQSUYdsFQ;\n        path=/; expires=Wed, 11-Dec-24 07:08:25 GMT; domain=.api.openai.com; HttpOnly;\n        Secure; SameSite=None\n      - _cfuvid=u2uD7q9qBtds7VKvREvCIQFKo8aX3uLEDB.jC8I.t.g-1733899105145-0.0.1.1-604800000;\n        path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None\n      X-Content-Type-Options:\n      - nosniff\n      Server:\n      - cloudflare\n      Cf-Ray:\n      - 8f0378b79d417006-CDG\n      Alt-Svc:\n      - h3=\":443\"; ma=86400\n    body:\n      encoding: ASCII-8BIT\n      string: |\n        {\n          \"id\": \"chatcmpl-AdAeWrJ95XzyeA1WUHEmIftd39TAM\",\n          \"object\": \"chat.completion\",\n          \"created\": 1733899104,\n          \"model\": \"gpt-4o-mini-2024-07-18\",\n          \"choices\": [\n            {\n              \"index\": 0,\n              \"message\": {\n                \"role\": \"assistant\",\n                \"content\": \"{\\\"topics\\\":[\\\"Hotwire\\\",\\\"Ruby on Rails\\\",\\\"Frontend Development\\\",\\\"StimulusJS\\\",\\\"Dynamic Forms\\\",\\\"Live Updates\\\",\\\"Web Development\\\"]}\",\n                \"refusal\": null\n              },\n              \"logprobs\": null,\n              \"finish_reason\": \"stop\"\n            }\n          ],\n          \"usage\": {\n            \"prompt_tokens\": 1081,\n            \"completion_tokens\": 27,\n            \"total_tokens\": 1108,\n            \"prompt_tokens_details\": {\n              \"cached_tokens\": 0,\n              \"audio_tokens\": 0\n            },\n            \"completion_tokens_details\": {\n              \"reasoning_tokens\": 0,\n              \"audio_tokens\": 0,\n              \"accepted_prediction_tokens\": 0,\n              \"rejected_prediction_tokens\": 0\n            }\n          },\n          \"system_fingerprint\": \"fp_bba3c8e70b\"\n        }\n  recorded_at: Wed, 11 Dec 2024 06:38:25 GMT\nrecorded_with: VCR 6.3.1\n"
  },
  {
    "path": "test/vcr_cassettes/talks/summarize.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: post\n    uri: https://api.openai.com/v1/chat/completions\n    body:\n      encoding: UTF-8\n      string: '{\"model\":\"gpt-4o-mini\",\"response_format\":{\"type\":\"json_schema\",\"json_schema\":{\"strict\":true,\"name\":\"talk_summary\",\"schema\":{\"type\":\"object\",\"additionalProperties\":false,\"required\":[\"summary\",\"keywords\"],\"properties\":{\"summary\":{\"type\":\"string\"},\"keywords\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}}}}}},\"messages\":[{\"role\":\"system\",\"content\":\"You\n        are a helpful assistant skilled in processing and summarizing transcripts.\"},{\"role\":\"user\",\"content\":\"You\n        are tasked with creating a summary of a video based on its transcript and\n        metadata. Follow these steps carefully:\\n\\n1. First, review the metadata of\n        the video:\\n\\u003cmetadata\\u003e\\n  - title: Hotwire Cookbook: Common Uses,\n        Essential Patterns \\u0026 Best Practices\\n  - description: @SupeRails creator\n        and Rails mentor Yaroslav Shmarov shares how some of the most common frontend\n        problems can be solved with Hotwire.\\n\\nHe covers:\\n- Pagination, search and\n        filtering, modals, live updates, dynamic forms, inline editing, drag \\u0026\n        drop, live previews, lazy loading \\u0026 more\\n- How to achieve more by combining\n        tools (Frames + Streams, StimulusJS, RequestJS, Kredis \\u0026 more)\\n- What\n        are the limits of Hotwire?\\n- How to write readable and maintainable Hotwire\n        code\\n- Bad practices\\n\\n  - speaker name: Yaroslav Shmarov\\n  - event name:\n        Rails World 2023\\n\\u003c/metadata\\u003e\\n\\n2. Next, carefully read through\n        the entire transcript:\\n\\u003ctranscript\\u003e\\nso nice to be here with you\n        thank you all for coming so uh my name is uh\\n\\nyaroslav I m from Ukraine\n        you might know me from my blog or from my super Al\\n\\nYouTube channel where\n        I post a lot of stuff about trby and especially about hot fire so I originate\n        from Ukraine\\n\\nfrom the north of Ukraine so right now it is liberated so\n        that is Kev Chernobyl\\n\\nand chern so I used to live 80 kmers away from Chernobyl\n        great\\n\\nplace yeah and uh that is my family s home so it got boned in one\n        of the first\\n\\ndays of war that is my godfather he went to defend Ukraine\n        and uh I mean we are\\n\\nhe has such a beautiful venue but there is the war\n        going on and like just today\\n\\nthe city of har was randomly boned by the\n        Russians and there are many Ruby\\n\\nrails people from Ukraine some of them\n        are actually fighting this is verok he contributed to Ruby and he is actually\\n\\ndefending\n        Ukraine right now but on a positive note I just recently became a father\\n\\nso\n        yeah um it is uh just 2 and a half months ago in uh France and uh today we\\n\\nare\n        going to talk about hot fire\\n\\u003c/transcript\\u003e\\n\\n3. To summarize the\n        video:\\n  a) Identify the main topic or theme of the video.\\n  b) Determine\n        the key points discussed throughout the video.\\n  c) Note any significant\n        examples, case studies, or anecdotes used to illustrate points.\\n  d) Capture\n        any important conclusions or takeaways presented.\\n  e) Keep in mind the context\n        provided by the metadata (title, description, speaker(s), and event).\\n\\n4.\n        Create a summary that:\\n  - Introduces the main topic\\n  - Outlines the key\n        points in a logical order\\n  - Includes relevant examples or illustrations\n        if they are crucial to understanding the content\\n  - Concludes with the main\n        takeaways or conclusions from the video\\n  - Is between 400-500 words in length\\n  -\n        format it using markdown\\n  - use bullets for the key points\\n\\n5. exctract\n        keywords\\n  - create a list of keywords to describe this video\\n  - 5 to 10\n        keywords\\n  - mostly teachnical keywords\\n\\n6. Format your summary as a JSON\n        object with the following schema:\\n  {\\n    \\\"summary\\\": \\\"Your summary text\n        here\\\",\\n    \\\"keywords\\\": [\\\"keyword1\\\", \\\"keyword2\\\", \\\"keyword3\\\"]\\n  }\\n\\n7.\n        Ensure that your summary is:\\n  - Objective and factual, based solely on the\n        content of the transcript and metadata\\n  - Written in clear, concise language\\n  -\n        Free of personal opinions or external information not present in the provided\n        content\\n\\n8. Output your JSON object containing the summary, ensuring it\n        is properly formatted and enclosed in \\u003canswer\\u003e tags.\\n\"}]}'\n    headers:\n      Content-Type:\n      - application/json\n      Authorization:\n      - Bearer <OPENAI_API_KEY>\n      Openai-Organization:\n      - \"<OPENAI_ORGANIZATION_ID>\"\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Tue, 10 Dec 2024 22:25:29 GMT\n      Content-Type:\n      - application/json\n      Transfer-Encoding:\n      - chunked\n      Connection:\n      - keep-alive\n      Access-Control-Expose-Headers:\n      - X-Request-ID\n      Openai-Organization:\n      - user-cnr3hw7frpcuxb74nqkxv0ci\n      Openai-Processing-Ms:\n      - '5621'\n      Openai-Version:\n      - '2020-10-01'\n      X-Ratelimit-Limit-Requests:\n      - '5000'\n      X-Ratelimit-Limit-Tokens:\n      - '4000000'\n      X-Ratelimit-Remaining-Requests:\n      - '4999'\n      X-Ratelimit-Remaining-Tokens:\n      - '3999115'\n      X-Ratelimit-Reset-Requests:\n      - 12ms\n      X-Ratelimit-Reset-Tokens:\n      - 13ms\n      X-Request-Id:\n      - req_9fc4276dfe35665ee44f6bb25642cd26\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubDomains; preload\n      Cf-Cache-Status:\n      - DYNAMIC\n      Set-Cookie:\n      - __cf_bm=barhuO2M6x5OuDPuQNG.TJR9FyBIzSRcO.1aRdwZ4jc-1733869529-1.0.1.1-9DhjsOINEgLpZB.jAruLlrLjCUhbnN_ghu1lAG9De9N0qYZaU..go5hb77MYFNY2M9FW96R5rT90a46.h2rHqA;\n        path=/; expires=Tue, 10-Dec-24 22:55:29 GMT; domain=.api.openai.com; HttpOnly;\n        Secure; SameSite=None\n      - _cfuvid=jfs9Sc0z01Gv5MN2YGs4SJszIFni6neFMGqFFSrpLts-1733869529388-0.0.1.1-604800000;\n        path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None\n      X-Content-Type-Options:\n      - nosniff\n      Server:\n      - cloudflare\n      Cf-Ray:\n      - 8f00a689bab29e67-CDG\n      Alt-Svc:\n      - h3=\":443\"; ma=86400\n    body:\n      encoding: ASCII-8BIT\n      string: !binary |-\n        ewogICJpZCI6ICJjaGF0Y21wbC1BZDJ4UFVadUt5VEZyTkFDZ3lxYnJ5RVBGdFJHNyIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTczMzg2OTUyMywKICAibW9kZWwiOiAiZ3B0LTRvLW1pbmktMjAyNC0wNy0xOCIsCiAgImNob2ljZXMiOiBbCiAgICB7CiAgICAgICJpbmRleCI6IDAsCiAgICAgICJtZXNzYWdlIjogewogICAgICAgICJyb2xlIjogImFzc2lzdGFudCIsCiAgICAgICAgImNvbnRlbnQiOiAie1wic3VtbWFyeVwiOlwiSW4gdGhpcyB2aWRlbyB0aXRsZWQgXFxcIkhvdHdpcmUgQ29va2Jvb2s6IENvbW1vbiBVc2VzLCBFc3NlbnRpYWwgUGF0dGVybnMgJiBCZXN0IFByYWN0aWNlcyxcXFwiIFlhcm9zbGF2IFNobWFyb3YsIGEgUmFpbHMgbWVudG9yLCBkaXNjdXNzZXMgdmFyaW91cyBhcHBsaWNhdGlvbnMgb2YgSG90d2lyZSB0byByZXNvbHZlIGNvbW1vbiBmcm9udC1lbmQgY2hhbGxlbmdlcy4gSGUgYmVnaW5zIGJ5IHByb3ZpZGluZyBhIGJyaWVmIGludHJvZHVjdGlvbiBhYm91dCBoaW1zZWxmIGFuZCBzaGFyaW5nIHNvbWUgcGVyc29uYWwgYW5lY2RvdGVzIHJlZ2FyZGluZyB0aGUgb25nb2luZyB3YXIgaW4gVWtyYWluZSwgd2hpbGUgYWxzbyBjZWxlYnJhdGluZyBhIHJlY2VudCBwZXJzb25hbCBtaWxlc3RvbmUgb2YgYmVjb21pbmcgYSBmYXRoZXIuIFxcblxcblRoZSBtYWluIGNvbnRlbnQgb2YgdGhlIHByZXNlbnRhdGlvbiBpcyBmb2N1c2VkIG9uIGhvdyBIb3R3aXJlIGNhbiBiZSB1dGlsaXplZCBlZmZlY3RpdmVseSBieSBkZXZlbG9wZXJzLiBLZXkgcG9pbnRzIGRpc2N1c3NlZCBpbmNsdWRlOlxcblxcbi0gKipDb21tb24gVXNlIENhc2VzIGZvciBIb3R3aXJlOioqIFNobWFyb3YgaGlnaGxpZ2h0cyBzZXZlcmFsIHNjZW5hcmlvcyB3aGVyZSBIb3R3aXJlIGV4Y2Vscywgc3VjaCBhcyBwYWdpbmF0aW9uLCBzZWFyY2ggYW5kIGZpbHRlcmluZywgbW9kYWxzLCBsaXZlIHVwZGF0ZXMsIGR5bmFtaWMgZm9ybXMsIGlubGluZSBlZGl0aW5nLCBkcmFnICYgZHJvcCBjYXBhYmlsaXRpZXMsIGxpdmUgcHJldmlld3MsIGFuZCBsYXp5IGxvYWRpbmcuXFxuLSAqKkNvbWJpbmluZyBUb29scyBmb3IgRW5oYW5jZWQgRnVuY3Rpb25hbGl0eToqKiBIZSBleHBsYWlucyBob3cgZGV2ZWxvcGVycyBjYW4gZ2FpbiBpbXByb3ZlZCByZXN1bHRzIGJ5IGNvbWJpbmluZyBkaWZmZXJlbnQgdG9vbHMgbGlrZSBGcmFtZXMgYW5kIFN0cmVhbXMsIFN0aW11bHVzSlMsIFJlcXVlc3RKUywgYW5kIEtyZWRpcywgdGh1cyBvcHRpbWl6aW5nIHRoZSBhcHBsaWNhdGlvbuKAmXMgcGVyZm9ybWFuY2UgYW5kIHVzZXIgZXhwZXJpZW5jZS5cXG4tICoqVW5kZXJzdGFuZGluZyB0aGUgTGltaXRzIG9mIEhvdHdpcmU6KiogU2htYXJvdiBvdXRsaW5lcyBzb21lIGxpbWl0YXRpb25zIHRvIGJlIGF3YXJlIG9mIHdoZW4gd29ya2luZyB3aXRoIEhvdHdpcmUsIGFkdmlzaW5nIGRldmVsb3BlcnMgb24gcG90ZW50aWFsIHBpdGZhbGxzLlxcbi0gKipCZXN0IFByYWN0aWNlcyBmb3IgUmVhZGFibGUgYW5kIE1haW50YWluYWJsZSBDb2RlOioqIEhlIHNoYXJlcyBpbnNpZ2h0cyBvbiBob3cgdG8gbWFpbnRhaW4gY29kZSB0aGF0IGlzIG5vdCBvbmx5IGZ1bmN0aW9uYWwgYnV0IGFsc28gZWFzeSB0byByZWFkIGFuZCB1bmRlcnN0YW5kLCBlbXBoYXNpemluZyB0aGUgaW1wb3J0YW5jZSBvZiBjbGFyaXR5IGluIHByb2dyYW1taW5nLlxcbi0gKipDb21tb24gQmFkIFByYWN0aWNlcyB0byBBdm9pZDoqKiBUaGUgZGlzY3Vzc2lvbiBhbHNvIGRlbHZlcyBpbnRvIHZhcmlvdXMgcHJhY3RpY2VzIHRoYXQgY291bGQgbGVhZCB0byBpc3N1ZXMgaW4gY29kaW5nIHdpdGggSG90d2lyZSwgcmVpbmZvcmNpbmcgdGhlIGltcG9ydGFuY2Ugb2YgZm9sbG93aW5nIGVzdGFibGlzaGVkIHBhdHRlcm5zLlxcblxcblRoZSB0YWxrIGNvbmNsdWRlcyB3aXRoIGVtcGhhc2lzIG9uIHRoZSBrZXkgdGFrZWF3YXlzLCBpbmNsdWRpbmcgdGhlIGltcG9ydGFuY2Ugb2YganVkaWNpb3VzbHkgY2hvb3NpbmcgdGhlIHJpZ2h0IHRvb2xzIGFuZCBtZXRob2RzIHRvIGFkZHJlc3MgZnJvbnQtZW5kIGNoYWxsZW5nZXMgd2hpbGUgYWxzbyB3cml0aW5nIG1haW50YWluYWJsZSBjb2RlLiBUaGlzIHByZXNlbnRhdGlvbiBpcyBwYXJ0aWN1bGFybHkgYmVuZWZpY2lhbCBmb3IgZGV2ZWxvcGVycyBsb29raW5nIHRvIGVuaGFuY2UgdGhlaXIgdW5kZXJzdGFuZGluZyBhbmQgYXBwbGljYXRpb24gb2YgSG90d2lyZSBpbiByZWFsLXdvcmxkIHNjZW5hcmlvcy5cIixcImtleXdvcmRzXCI6W1wiSG90d2lyZVwiLFwiUmFpbHNcIixcIllhcm9zbGF2IFNobWFyb3ZcIixcImZyb250ZW5kIGRldmVsb3BtZW50XCIsXCJwYWdpbmF0aW9uXCIsXCJsaXZlIHVwZGF0ZXNcIixcImR5bmFtaWMgZm9ybXNcIixcImJlc3QgcHJhY3RpY2VzXCIsXCJTdGltdWx1c0pTXCIsXCJSZXF1ZXN0SlNcIl19IiwKICAgICAgICAicmVmdXNhbCI6IG51bGwKICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAic3RvcCIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogODQ5LAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogNDE0LAogICAgInRvdGFsX3Rva2VucyI6IDEyNjMsCiAgICAicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjogewogICAgICAiY2FjaGVkX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwCiAgICB9LAogICAgImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJyZWFzb25pbmdfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAsCiAgICAgICJhY2NlcHRlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAsCiAgICAgICJyZWplY3RlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAKICAgIH0KICB9LAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfYmJhM2M4ZTcwYiIKfQo=\n  recorded_at: Tue, 10 Dec 2024 22:25:29 GMT\nrecorded_with: VCR 6.3.1\n"
  },
  {
    "path": "test/vcr_cassettes/talks/transcript-enhancement.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: post\n    uri: https://api.openai.com/v1/chat/completions\n    body:\n      encoding: UTF-8\n      string: '{\"model\":\"gpt-4o-mini\",\"response_format\":{\"type\":\"json_schema\",\"json_schema\":{\"name\":\"talk_transcript\",\"schema\":{\"type\":\"object\",\"properties\":{\"transcript\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"start_time\":{\"type\":\"string\"},\"end_time\":{\"type\":\"string\"},\"text\":{\"type\":\"string\"}}}}},\"required\":[\"transcript\"],\"additionalProperties\":false}}},\"messages\":[{\"role\":\"system\",\"content\":\"You\n        are a helpful assistant skilled in processing and summarizing transcripts.\"},{\"role\":\"user\",\"content\":\"You\n        are tasked with improving and formatting a raw VTT transcript. Your goal is\n        to correct and enhance the text, organize it into paragraphs, and format it\n        into a specific JSON structure. Follow these instructions carefully to complete\n        the task.\\n\\nFirst, here is the metadata for the transcript:\\n  - title: Hotwire\n        Cookbook: Common Uses, Essential Patterns \\u0026 Best Practices\\n  - description:\n        @SupeRails creator and Rails mentor Yaroslav Shmarov shares how some of the\n        most common frontend problems can be solved with Hotwire.\\n\\nHe covers:\\n-\n        Pagination, search and filtering, modals, live updates, dynamic forms, inline\n        editing, drag \\u0026 drop, live previews, lazy loading \\u0026 more\\n- How\n        to achieve more by combining tools (Frames + Streams, StimulusJS, RequestJS,\n        Kredis \\u0026 more)\\n- What are the limits of Hotwire?\\n- How to write readable\n        and maintainable Hotwire code\\n- Bad practices\\n\\n  - speaker name: Yaroslav\n        Shmarov\\n  - event name: Rails World 2023\\n\\nNow, let''s process the raw VTT\n        transcript. Here''s what you need to do:\\n\\n1. Read through the entire raw\n        transcript carefully.\\n\\n2. Correct any spelling, grammar, or punctuation\n        errors you find in the text.\\n\\n3. Improve the overall readability and coherence\n        of the text without changing its meaning.\\n\\n4. Group related sentences into\n        paragraphs. Each paragraph should contain a complete thought or topic.\\n\\n5.\n        For each paragraph, use the start time of its first sentence as the paragraph''s\n        start time, and the end time of its last sentence as the paragraph''s end\n        time.\\n\\n6. Format the improved transcript into a JSON structure using this\n        schema:\\n{\\\"transcript\\\": [{start_time: \\\"00:00:00\\\", end_time: \\\"00:00:05\\\",\n        text: \\\"Hello, world!\\\"},...]}\\n\\nHere is the raw VTT transcript to process:\\n\\n\\u003craw_transcript\\u003e\\nWEBVTT\\n\\n1\\n00:00:15.280\n        --\\u003e 00:00:21.320\\nso nice to be here with you thank you all for coming\n        so uh my name is uh\\n\\n2\\n00:00:21.320 --\\u003e 00:00:27.800\\nyaroslav I m\n        from Ukraine you might know me from my blog or from my super Al\\n\\n3\\n00:00:27.800\n        --\\u003e 00:00:34.399\\nYouTube channel where I post a lot of stuff about trby\n        and especially about hot fire so I originate from Ukraine\\n\\n4\\n00:00:34.399\n        --\\u003e 00:00:40.239\\nfrom the north of Ukraine so right now it is liberated\n        so that is Kev Chernobyl\\n\\n5\\n00:00:40.239 --\\u003e 00:00:45.920\\nand chern\n        so I used to live 80 kmers away from Chernobyl great\\n\\n6\\n00:00:45.920 --\\u003e\n        00:00:52.680\\nplace yeah and uh that is my family s home so it got boned in\n        one of the first\\n\\n7\\n00:00:52.680 --\\u003e 00:01:00.000\\ndays of war that\n        is my godfather he went to defend Ukraine and uh I mean we are\\n\\n8\\n00:01:00.000\n        --\\u003e 00:01:05.799\\nhe has such a beautiful venue but there is the war\n        going on and like just today\\n\\n9\\n00:01:05.799 --\\u003e 00:01:13.159\\nthe\n        city of har was randomly boned by the Russians and there are many Ruby\\n\\n10\\n00:01:13.159\n        --\\u003e 00:01:19.520\\nrails people from Ukraine some of them are actually\n        fighting this is verok he contributed to Ruby and he is actually\\n\\n11\\n00:01:19.520\n        --\\u003e 00:01:27.960\\ndefending Ukraine right now but on a positive note\n        I just recently became a father\\n\\n12\\n00:01:27.960 --\\u003e 00:01:35.000\\nso\n        yeah um it is uh just 2 and a half months ago in uh France and uh today we\\n\\n13\\n00:01:35.000\n        --\\u003e 00:01:35.000\\nare going to talk about hot fire\\n\\n\\n\\u003c/raw_transcript\\u003e\\n\\nTo\n        complete this task, follow these steps:\\n\\n1. Read through the entire raw\n        transcript.\\n2. Make necessary corrections to spelling, grammar, and punctuation.\\n3.\n        Improve the text for clarity and coherence.\\n4. Group related sentences into\n        paragraphs.\\n5. Determine the start and end times for each paragraph.\\n6.\n        Format the improved transcript into the specified JSON structure.\\n\\nRemember\n        to preserve the original meaning of the content while making improvements.\n        Ensure that each JSON object in the array represents a paragraph with its\n        corresponding start time, end time, and improved text.\\n\"}]}'\n    headers:\n      Content-Type:\n      - application/json\n      Authorization:\n      - Bearer <OPENAI_API_KEY>\n      Openai-Organization:\n      - \"<OPENAI_ORGANIZATION_ID>\"\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Sat, 04 Jan 2025 22:05:13 GMT\n      Content-Type:\n      - application/json\n      Transfer-Encoding:\n      - chunked\n      Connection:\n      - keep-alive\n      Access-Control-Expose-Headers:\n      - X-Request-ID\n      Openai-Organization:\n      - user-cnr3hw7frpcuxb74nqkxv0ci\n      Openai-Processing-Ms:\n      - '2758'\n      Openai-Version:\n      - '2020-10-01'\n      X-Ratelimit-Limit-Requests:\n      - '5000'\n      X-Ratelimit-Limit-Tokens:\n      - '4000000'\n      X-Ratelimit-Remaining-Requests:\n      - '4999'\n      X-Ratelimit-Remaining-Tokens:\n      - '3999008'\n      X-Ratelimit-Reset-Requests:\n      - 12ms\n      X-Ratelimit-Reset-Tokens:\n      - 14ms\n      X-Request-Id:\n      - req_92d07cd36ef07130e64daa0636193255\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubDomains; preload\n      Cf-Cache-Status:\n      - DYNAMIC\n      Set-Cookie:\n      - __cf_bm=1W0G0Rn4HrcTx6lL4LUar4sWtOsBZi6s_6NtUqQqsnk-1736028313-1.0.1.1-qYeFKEfIYfCumCuZCL6Gk6L3z5pBpmjqNTOl46kqwU6g603URVB5KZJXZkNvyp.rwaq2ZjZ4EroBND1f9cbhpQ;\n        path=/; expires=Sat, 04-Jan-25 22:35:13 GMT; domain=.api.openai.com; HttpOnly;\n        Secure; SameSite=None\n      - _cfuvid=E111y0rBSbIatglJUbEDzp31Yb30yAscGteVqR6UAiE-1736028313711-0.0.1.1-604800000;\n        path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None\n      X-Content-Type-Options:\n      - nosniff\n      Server:\n      - cloudflare\n      Cf-Ray:\n      - 8fce874aadce48cd-LHR\n      Alt-Svc:\n      - h3=\":443\"; ma=86400\n    body:\n      encoding: ASCII-8BIT\n      string: !binary |-\n        ewogICJpZCI6ICJjaGF0Y21wbC1BbTZZWW1WYnRtM01vUUtCQWJTeHNwTGpRT09tUiIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTczNjAyODMxMCwKICAibW9kZWwiOiAiZ3B0LTRvLW1pbmktMjAyNC0wNy0xOCIsCiAgImNob2ljZXMiOiBbCiAgICB7CiAgICAgICJpbmRleCI6IDAsCiAgICAgICJtZXNzYWdlIjogewogICAgICAgICJyb2xlIjogImFzc2lzdGFudCIsCiAgICAgICAgImNvbnRlbnQiOiAie1widHJhbnNjcmlwdFwiOlt7XCJzdGFydF90aW1lXCI6XCIwMDowMDoxNS4yODBcIixcImVuZF90aW1lXCI6XCIwMDowMDozNC4zOTlcIixcInRleHRcIjpcIlNvIG5pY2UgdG8gYmUgaGVyZSB3aXRoIHlvdS4gVGhhbmsgeW91IGFsbCBmb3IgY29taW5nLiBNeSBuYW1lIGlzIFlhcm9zbGF2LCBhbmQgSSdtIGZyb20gVWtyYWluZS4gWW91IG1pZ2h0IGtub3cgbWUgZnJvbSBteSBibG9nIG9yIGZyb20gbXkgU3VwZXIgQWwgWW91VHViZSBjaGFubmVsLCB3aGVyZSBJIHBvc3QgYSBsb3Qgb2YgY29udGVudCBhYm91dCBSdWJ5LCBhbmQgZXNwZWNpYWxseSBhYm91dCBIb3R3aXJlLiBJIG9yaWdpbmF0ZSBmcm9tIHRoZSBub3J0aCBvZiBVa3JhaW5lLCBzcGVjaWZpY2FsbHkgZnJvbSBhIHRvd24gdGhhdCBpcyBub3cgbGliZXJhdGVkLCBuZWFyIEt5aXYgYW5kIENoZXJub2J5bC4gSSB1c2VkIHRvIGxpdmUgYWJvdXQgODAga2lsb21ldGVycyBhd2F5IGZyb20gQ2hlcm5vYnlsLlwifSx7XCJzdGFydF90aW1lXCI6XCIwMDowMDozNC4zOTlcIixcImVuZF90aW1lXCI6XCIwMDowMToxMy4xNTlcIixcInRleHRcIjpcIlRoYXQgcGxhY2UgaG9sZHMgYSBsb3Qgb2YgbWVtb3JpZXMgZm9yIG1lLCBhcyBpdCB3YXMgbXkgZmFtaWx5J3MgaG9tZS4gVW5mb3J0dW5hdGVseSwgaXQgd2FzIGRlc3Ryb3llZCBpbiB0aGUgZWFybHkgZGF5cyBvZiB0aGUgd2FyLiBNeSBnb2RmYXRoZXIgd2VudCB0byBkZWZlbmQgVWtyYWluZS4gSXQncyBhIGJlYXV0aWZ1bCB2ZW51ZSwgYnV0IGFtaWRzdCB0aGUgYmVhdXR5LCB0aGVyZSdzIGEgd2FyIGdvaW5nIG9uLiBKdXN0IHRvZGF5LCB0aGUgY2l0eSBvZiBLaGFya2l2IHdhcyByYW5kb21seSBib21iZWQgYnkgdGhlIFJ1c3NpYW5zLCBhbmQgbWFueSBSdWJ5IG9uIFJhaWxzIGRldmVsb3BlcnMgZnJvbSBVa3JhaW5lIGFyZSBhZmZlY3RlZOKAlHNvbWUgb2YgdGhlbSBhcmUgZXZlbiBmaWdodGluZy5cIn0se1wic3RhcnRfdGltZVwiOlwiMDA6MDE6MTMuMTU5XCIsXCJlbmRfdGltZVwiOlwiMDA6MDE6MzUuMDAwXCIsXCJ0ZXh0XCI6XCJPbmUgb2YgdGhlbSBpcyBWZXJvaywgd2hvIGNvbnRyaWJ1dGVkIHRvIFJ1YnkgYW5kIGlzIGN1cnJlbnRseSBkZWZlbmRpbmcgVWtyYWluZS4gT24gYSBtb3JlIHBvc2l0aXZlIG5vdGUsIEkgcmVjZW50bHkgYmVjYW1lIGEgZmF0aGVyIGp1c3QgdHdvIGFuZCBhIGhhbGYgbW9udGhzIGFnbyBpbiBGcmFuY2UuIFRvZGF5LCB3ZSdyZSBnb2luZyB0byB0YWxrIGFib3V0IEhvdHdpcmUuXCJ9XX0iLAogICAgICAgICJyZWZ1c2FsIjogbnVsbAogICAgICB9LAogICAgICAibG9ncHJvYnMiOiBudWxsLAogICAgICAiZmluaXNoX3JlYXNvbiI6ICJzdG9wIgogICAgfQogIF0sCiAgInVzYWdlIjogewogICAgInByb21wdF90b2tlbnMiOiAxMDg4LAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogMzE1LAogICAgInRvdGFsX3Rva2VucyI6IDE0MDMsCiAgICAicHJvbXB0X3Rva2Vuc19kZXRhaWxzIjogewogICAgICAiY2FjaGVkX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwCiAgICB9LAogICAgImNvbXBsZXRpb25fdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJyZWFzb25pbmdfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAsCiAgICAgICJhY2NlcHRlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAsCiAgICAgICJyZWplY3RlZF9wcmVkaWN0aW9uX3Rva2VucyI6IDAKICAgIH0KICB9LAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfMGFhOGQzZTIwYiIKfQo=\n  recorded_at: Sat, 04 Jan 2025 22:05:13 GMT\n- request:\n    method: post\n    uri: https://api.openai.com/v1/chat/completions\n    body:\n      encoding: UTF-8\n      string: '{\"model\":\"gpt-4o-mini\",\"response_format\":{\"type\":\"json_schema\",\"json_schema\":{\"name\":\"talk_transcript\",\"schema\":{\"type\":\"object\",\"properties\":{\"transcript\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"start_time\":{\"type\":\"string\"},\"end_time\":{\"type\":\"string\"},\"text\":{\"type\":\"string\"}}}}},\"required\":[\"transcript\"],\"additionalProperties\":false}}},\"messages\":[{\"role\":\"system\",\"content\":\"You\n        are a helpful assistant skilled in processing and summarizing transcripts.\"},{\"role\":\"user\",\"content\":\"You\n        are tasked with improving and formatting a raw VTT transcript. Your goal is\n        to correct and enhance the text, organize it into paragraphs, and format it\n        into a specific JSON structure. Follow these instructions carefully to complete\n        the task.\\n\\nFirst, here is the metadata for the transcript:\\n  - title: Hotwire\n        Cookbook: Common Uses, Essential Patterns \\u0026 Best Practices\\n  - description:\n        @SupeRails creator and Rails mentor Yaroslav Shmarov shares how some of the\n        most common frontend problems can be solved with Hotwire.\\n\\nHe covers:\\n-\n        Pagination, search and filtering, modals, live updates, dynamic forms, inline\n        editing, drag \\u0026 drop, live previews, lazy loading \\u0026 more\\n- How\n        to achieve more by combining tools (Frames + Streams, StimulusJS, RequestJS,\n        Kredis \\u0026 more)\\n- What are the limits of Hotwire?\\n- How to write readable\n        and maintainable Hotwire code\\n- Bad practices\\n\\n  - speaker name: Yaroslav\n        Shmarov\\n  - event name: Rails World 2023\\n\\nNow, let''s process the raw VTT\n        transcript. Here''s what you need to do:\\n\\n1. Read through the entire raw\n        transcript carefully.\\n\\n2. Correct any spelling, grammar, or punctuation\n        errors you find in the text.\\n\\n3. Improve the overall readability and coherence\n        of the text without changing its meaning.\\n\\n4. Group related sentences into\n        paragraphs. Each paragraph should contain a complete thought or topic.\\n\\n5.\n        For each paragraph, use the start time of its first sentence as the paragraph''s\n        start time, and the end time of its last sentence as the paragraph''s end\n        time.\\n\\n6. Format the improved transcript into a JSON structure using this\n        schema:\\n{\\\"transcript\\\": [{start_time: \\\"00:00:00\\\", end_time: \\\"00:00:05\\\",\n        text: \\\"Hello, world!\\\"},...]}\\n\\nHere is the raw VTT transcript to process:\\n\\n\\u003craw_transcript\\u003e\\nWEBVTT\\n\\n1\\n00:00:15.280\n        --\\u003e 00:00:21.320\\nso nice to be here with you thank you all for coming\n        so uh my name is uh\\n\\n2\\n00:00:21.320 --\\u003e 00:00:27.800\\nyaroslav I m\n        from Ukraine you might know me from my blog or from my super Al\\n\\n3\\n00:00:27.800\n        --\\u003e 00:00:34.399\\nYouTube channel where I post a lot of stuff about trby\n        and especially about hot fire so I originate from Ukraine\\n\\n4\\n00:00:34.399\n        --\\u003e 00:00:40.239\\nfrom the north of Ukraine so right now it is liberated\n        so that is Kev Chernobyl\\n\\n5\\n00:00:40.239 --\\u003e 00:00:45.920\\nand chern\n        so I used to live 80 kmers away from Chernobyl great\\n\\n6\\n00:00:45.920 --\\u003e\n        00:00:52.680\\nplace yeah and uh that is my family s home so it got boned in\n        one of the first\\n\\n7\\n00:00:52.680 --\\u003e 00:01:00.000\\ndays of war that\n        is my godfather he went to defend Ukraine and uh I mean we are\\n\\n8\\n00:01:00.000\n        --\\u003e 00:01:05.799\\nhe has such a beautiful venue but there is the war\n        going on and like just today\\n\\n9\\n00:01:05.799 --\\u003e 00:01:13.159\\nthe\n        city of har was randomly boned by the Russians and there are many Ruby\\n\\n10\\n00:01:13.159\n        --\\u003e 00:01:19.520\\nrails people from Ukraine some of them are actually\n        fighting this is verok he contributed to Ruby and he is actually\\n\\n11\\n00:01:19.520\n        --\\u003e 00:01:27.960\\ndefending Ukraine right now but on a positive note\n        I just recently became a father\\n\\n12\\n00:01:27.960 --\\u003e 00:01:35.000\\nso\n        yeah um it is uh just 2 and a half months ago in uh France and uh today we\\n\\n13\\n00:01:35.000\n        --\\u003e 00:01:35.000\\nare going to talk about hot fire\\n\\n\\n\\u003c/raw_transcript\\u003e\\n\\nTo\n        complete this task, follow these steps:\\n\\n1. Read through the entire raw\n        transcript.\\n2. Make necessary corrections to spelling, grammar, and punctuation.\\n3.\n        Improve the text for clarity and coherence.\\n4. Group related sentences into\n        paragraphs.\\n5. Determine the start and end times for each paragraph.\\n6.\n        Format the improved transcript into the specified JSON structure.\\n\\nRemember\n        to preserve the original meaning of the content while making improvements.\n        Ensure that each JSON object in the array represents a paragraph with its\n        corresponding start time, end time, and improved text.\\n\"}]}'\n    headers:\n      Content-Type:\n      - application/json\n      Authorization:\n      - Bearer <OPENAI_API_KEY>\n      Openai-Organization:\n      - \"<OPENAI_ORGANIZATION_ID>\"\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Sat, 04 Jan 2025 22:05:18 GMT\n      Content-Type:\n      - application/json\n      Transfer-Encoding:\n      - chunked\n      Connection:\n      - keep-alive\n      Access-Control-Expose-Headers:\n      - X-Request-ID\n      Openai-Organization:\n      - user-cnr3hw7frpcuxb74nqkxv0ci\n      Openai-Processing-Ms:\n      - '4380'\n      Openai-Version:\n      - '2020-10-01'\n      X-Ratelimit-Limit-Requests:\n      - '5000'\n      X-Ratelimit-Limit-Tokens:\n      - '4000000'\n      X-Ratelimit-Remaining-Requests:\n      - '4999'\n      X-Ratelimit-Remaining-Tokens:\n      - '3999007'\n      X-Ratelimit-Reset-Requests:\n      - 12ms\n      X-Ratelimit-Reset-Tokens:\n      - 14ms\n      X-Request-Id:\n      - req_c84e253ff5103c23c984296ddc43a416\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubDomains; preload\n      Cf-Cache-Status:\n      - DYNAMIC\n      Set-Cookie:\n      - __cf_bm=4Imddd5FW7DL20GBf58TQC953ITLU.jICRkVwDmGqmM-1736028318-1.0.1.1-QL1WwP8AYgPEdRX.hRJxEBn3.RaoIl6n8zsL_l3mR1iISgVWyIMxnObJeU7L5xEIxhtMD5OgF.hDIbMTF7geNA;\n        path=/; expires=Sat, 04-Jan-25 22:35:18 GMT; domain=.api.openai.com; HttpOnly;\n        Secure; SameSite=None\n      - _cfuvid=KVw4UlGAoWN9KYPImoZ1TdWrQDhxNFL9Onom3Gzhius-1736028318498-0.0.1.1-604800000;\n        path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None\n      X-Content-Type-Options:\n      - nosniff\n      Server:\n      - cloudflare\n      Cf-Ray:\n      - 8fce8761ef2d3864-LHR\n      Alt-Svc:\n      - h3=\":443\"; ma=86400\n    body:\n      encoding: ASCII-8BIT\n      string: !binary |-\n        ewogICJpZCI6ICJjaGF0Y21wbC1BbTZZY3htRTVQYUxLUmhSTEVYQXNudDRHMDBlNiIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTczNjAyODMxNCwKICAibW9kZWwiOiAiZ3B0LTRvLW1pbmktMjAyNC0wNy0xOCIsCiAgImNob2ljZXMiOiBbCiAgICB7CiAgICAgICJpbmRleCI6IDAsCiAgICAgICJtZXNzYWdlIjogewogICAgICAgICJyb2xlIjogImFzc2lzdGFudCIsCiAgICAgICAgImNvbnRlbnQiOiAie1widHJhbnNjcmlwdFwiOlt7XCJzdGFydF90aW1lXCI6XCIwMDowMDoxNS4yODBcIixcImVuZF90aW1lXCI6XCIwMDowMDoyMS4zMjBcIixcInRleHRcIjpcIkhlbGxvLCBldmVyeW9uZSEgSXQncyBncmVhdCB0byBiZSBoZXJlIHdpdGggeW91IHRvZGF5LCBhbmQgSSB3YW50IHRvIHRoYW5rIHlvdSBhbGwgZm9yIGNvbWluZy4gTXkgbmFtZSBpcyBZYXJvc2xhdiwgYW5kIEnigJltIGZyb20gVWtyYWluZS5cIn0se1wic3RhcnRfdGltZVwiOlwiMDA6MDA6MjEuMzIwXCIsXCJlbmRfdGltZVwiOlwiMDA6MDA6MzQuMzk5XCIsXCJ0ZXh0XCI6XCJZb3UgbWF5IGtub3cgbWUgZnJvbSBteSBibG9nIG9yIG15IFlvdVR1YmUgY2hhbm5lbCwgd2hlcmUgSSBzaGFyZSBhIGxvdCBvZiBjb250ZW50IGFib3V0IFJ1YnkgYW5kIHNwZWNpZmljYWxseSBhYm91dCBIb3R3aXJlLlwifSx7XCJzdGFydF90aW1lXCI6XCIwMDowMDozNC4zOTlcIixcImVuZF90aW1lXCI6XCIwMDowMDo0NS45MjBcIixcInRleHRcIjpcIkkgb3JpZ2luYWxseSBjb21lIGZyb20gbm9ydGhlcm4gVWtyYWluZSwgc3BlY2lmaWNhbGx5IGZyb20gYSBwbGFjZSBjbG9zZSB0byBDaGVybm9ieWwsIHdoaWNoIGlzIG5vdyBsaWJlcmF0ZWQuIEl04oCZcyBhYm91dCA4MCBraWxvbWV0ZXJzIGF3YXkgZnJvbSBDaGVybm9ieWwuXCJ9LHtcInN0YXJ0X3RpbWVcIjpcIjAwOjAwOjQ1LjkyMFwiLFwiZW5kX3RpbWVcIjpcIjAwOjAxOjAwLjAwMFwiLFwidGV4dFwiOlwiVW5mb3J0dW5hdGVseSwgbXkgZmFtaWx5J3MgaG9tZSB3YXMgZGVzdHJveWVkIGR1cmluZyB0aGUgZWFybHkgZGF5cyBvZiB0aGUgd2FyLiBNeSBnb2RmYXRoZXIgd2VudCB0byBkZWZlbmQgVWtyYWluZS5cIn0se1wic3RhcnRfdGltZVwiOlwiMDA6MDE6MDAuMDAwXCIsXCJlbmRfdGltZVwiOlwiMDA6MDE6MTMuMTU5XCIsXCJ0ZXh0XCI6XCJJdOKAmXMgYSBiZWF1dGlmdWwgdmVudWUsIGJ1dCB0aGUgd2FyIGNvbnRpbnVlcyB0byBpbXBhY3QgdXMgZ3JlYXRseS4gSnVzdCB0b2RheSwgdGhlIGNpdHkgb2YgS2hhcmtpdiB3YXMgcmFuZG9tbHkgYm9tYmVkIGJ5IFJ1c3NpYW4gZm9yY2VzLlwifSx7XCJzdGFydF90aW1lXCI6XCIwMDowMToxMy4xNTlcIixcImVuZF90aW1lXCI6XCIwMDowMToyNy45NjBcIixcInRleHRcIjpcIlRoZXJlIGFyZSBtYW55IFJ1Ynkgb24gUmFpbHMgZGV2ZWxvcGVycyBmcm9tIFVrcmFpbmUsIGFuZCBzb21lIGFyZSBhY3R1YWxseSBmaWdodGluZyBmb3Igb3VyIGNvdW50cnkuIEZvciBpbnN0YW5jZSwgdGhlcmXigJlzIFZlcm9rLCB3aG8gaGFzIGNvbnRyaWJ1dGVkIHRvIFJ1YnkgYW5kIGlzIGN1cnJlbnRseSBkZWZlbmRpbmcgVWtyYWluZS5cIn0se1wic3RhcnRfdGltZVwiOlwiMDA6MDE6MjcuOTYwXCIsXCJlbmRfdGltZVwiOlwiMDA6MDE6MzUuMDAwXCIsXCJ0ZXh0XCI6XCJPbiBhIHBvc2l0aXZlIG5vdGUsIEkgcmVjZW50bHkgYmVjYW1lIGEgZmF0aGVyIGp1c3QgdHdvIGFuZCBhIGhhbGYgbW9udGhzIGFnbyBpbiBGcmFuY2UuIFRvZGF5LCB3ZSBhcmUgZ29pbmcgdG8gdGFsayBhYm91dCBIb3R3aXJlLlwifV19IiwKICAgICAgICAicmVmdXNhbCI6IG51bGwKICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAic3RvcCIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogMTA4OCwKICAgICJjb21wbGV0aW9uX3Rva2VucyI6IDQwNCwKICAgICJ0b3RhbF90b2tlbnMiOiAxNDkyLAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic3lzdGVtX2ZpbmdlcnByaW50IjogImZwXzBhYThkM2UyMGIiCn0K\n  recorded_at: Sat, 04 Jan 2025 22:05:18 GMT\n- request:\n    method: post\n    uri: https://api.openai.com/v1/chat/completions\n    body:\n      encoding: UTF-8\n      string: '{\"model\":\"gpt-4o-mini\",\"response_format\":{\"type\":\"json_schema\",\"json_schema\":{\"name\":\"talk_transcript\",\"schema\":{\"type\":\"object\",\"properties\":{\"transcript\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"start_time\":{\"type\":\"string\"},\"end_time\":{\"type\":\"string\"},\"text\":{\"type\":\"string\"}}}}},\"required\":[\"transcript\"],\"additionalProperties\":false}}},\"messages\":[{\"role\":\"system\",\"content\":\"You\n        are a helpful assistant skilled in processing and summarizing transcripts.\"},{\"role\":\"user\",\"content\":\"You\n        are tasked with improving and formatting a raw VTT transcript. Your goal is\n        to correct and enhance the text, organize it into paragraphs, and format it\n        into a specific JSON structure. Follow these instructions carefully to complete\n        the task.\\n\\nFirst, here is the metadata for the transcript:\\n  - title: Hotwire\n        Cookbook: Common Uses, Essential Patterns \\u0026 Best Practices\\n  - description:\n        @SupeRails creator and Rails mentor Yaroslav Shmarov shares how some of the\n        most common frontend problems can be solved with Hotwire.\\n\\nHe covers:\\n-\n        Pagination, search and filtering, modals, live updates, dynamic forms, inline\n        editing, drag \\u0026 drop, live previews, lazy loading \\u0026 more\\n- How\n        to achieve more by combining tools (Frames + Streams, StimulusJS, RequestJS,\n        Kredis \\u0026 more)\\n- What are the limits of Hotwire?\\n- How to write readable\n        and maintainable Hotwire code\\n- Bad practices\\n\\n  - speaker name: Yaroslav\n        Shmarov\\n  - event name: Rails World 2023\\n\\nNow, let''s process the raw VTT\n        transcript. Here''s what you need to do:\\n\\n1. Read through the entire raw\n        transcript carefully.\\n\\n2. Correct any spelling, grammar, or punctuation\n        errors you find in the text.\\n\\n3. Improve the overall readability and coherence\n        of the text without changing its meaning.\\n\\n4. Group related sentences into\n        paragraphs. Each paragraph should contain a complete thought or topic.\\n\\n5.\n        For each paragraph, use the start time of its first sentence as the paragraph''s\n        start time, and the end time of its last sentence as the paragraph''s end\n        time.\\n\\n6. Format the improved transcript into a JSON structure using this\n        schema:\\n{\\\"transcript\\\": [{start_time: \\\"00:00:00\\\", end_time: \\\"00:00:05\\\",\n        text: \\\"Hello, world!\\\"},...]}\\n\\nHere is the raw VTT transcript to process:\\n\\n\\u003craw_transcript\\u003e\\nWEBVTT\\n\\n1\\n00:00:15.280\n        --\\u003e 00:00:21.320\\nso nice to be here with you thank you all for coming\n        so uh my name is uh\\n\\n2\\n00:00:21.320 --\\u003e 00:00:27.800\\nyaroslav I m\n        from Ukraine you might know me from my blog or from my super Al\\n\\n3\\n00:00:27.800\n        --\\u003e 00:00:34.399\\nYouTube channel where I post a lot of stuff about trby\n        and especially about hot fire so I originate from Ukraine\\n\\n4\\n00:00:34.399\n        --\\u003e 00:00:40.239\\nfrom the north of Ukraine so right now it is liberated\n        so that is Kev Chernobyl\\n\\n5\\n00:00:40.239 --\\u003e 00:00:45.920\\nand chern\n        so I used to live 80 kmers away from Chernobyl great\\n\\n6\\n00:00:45.920 --\\u003e\n        00:00:52.680\\nplace yeah and uh that is my family s home so it got boned in\n        one of the first\\n\\n7\\n00:00:52.680 --\\u003e 00:01:00.000\\ndays of war that\n        is my godfather he went to defend Ukraine and uh I mean we are\\n\\n8\\n00:01:00.000\n        --\\u003e 00:01:05.799\\nhe has such a beautiful venue but there is the war\n        going on and like just today\\n\\n9\\n00:01:05.799 --\\u003e 00:01:13.159\\nthe\n        city of har was randomly boned by the Russians and there are many Ruby\\n\\n10\\n00:01:13.159\n        --\\u003e 00:01:19.520\\nrails people from Ukraine some of them are actually\n        fighting this is verok he contributed to Ruby and he is actually\\n\\n11\\n00:01:19.520\n        --\\u003e 00:01:27.960\\ndefending Ukraine right now but on a positive note\n        I just recently became a father\\n\\n12\\n00:01:27.960 --\\u003e 00:01:35.000\\nso\n        yeah um it is uh just 2 and a half months ago in uh France and uh today we\\n\\n13\\n00:01:35.000\n        --\\u003e 00:01:35.000\\nare going to talk about hot fire\\n\\n\\n\\u003c/raw_transcript\\u003e\\n\\nTo\n        complete this task, follow these steps:\\n\\n1. Read through the entire raw\n        transcript.\\n2. Make necessary corrections to spelling, grammar, and punctuation.\\n3.\n        Improve the text for clarity and coherence.\\n4. Group related sentences into\n        paragraphs.\\n5. Determine the start and end times for each paragraph.\\n6.\n        Format the improved transcript into the specified JSON structure.\\n\\nRemember\n        to preserve the original meaning of the content while making improvements.\n        Ensure that each JSON object in the array represents a paragraph with its\n        corresponding start time, end time, and improved text.\\n\"}]}'\n    headers:\n      Content-Type:\n      - application/json\n      Authorization:\n      - Bearer <OPENAI_API_KEY>\n      Openai-Organization:\n      - \"<OPENAI_ORGANIZATION_ID>\"\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Sat, 04 Jan 2025 22:05:22 GMT\n      Content-Type:\n      - application/json\n      Transfer-Encoding:\n      - chunked\n      Connection:\n      - keep-alive\n      Access-Control-Expose-Headers:\n      - X-Request-ID\n      Openai-Organization:\n      - user-cnr3hw7frpcuxb74nqkxv0ci\n      Openai-Processing-Ms:\n      - '4009'\n      Openai-Version:\n      - '2020-10-01'\n      X-Ratelimit-Limit-Requests:\n      - '5000'\n      X-Ratelimit-Limit-Tokens:\n      - '4000000'\n      X-Ratelimit-Remaining-Requests:\n      - '4999'\n      X-Ratelimit-Remaining-Tokens:\n      - '3999008'\n      X-Ratelimit-Reset-Requests:\n      - 12ms\n      X-Ratelimit-Reset-Tokens:\n      - 14ms\n      X-Request-Id:\n      - req_b0731f2ee1de331d44258d856bda6106\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubDomains; preload\n      Cf-Cache-Status:\n      - DYNAMIC\n      Set-Cookie:\n      - __cf_bm=VMF6sHLfH63iWUBUDWPsI60F3t7JA5c9nSykAoHbDok-1736028322-1.0.1.1-DtV30ouOjKAoQH7UlC2GIoPVooXPmYCQd_ZkscgyVzqYxjyMXgSdrpNk54Pyk7qzMXaxH8iSswfe2ZB8_4nYCg;\n        path=/; expires=Sat, 04-Jan-25 22:35:22 GMT; domain=.api.openai.com; HttpOnly;\n        Secure; SameSite=None\n      - _cfuvid=Y9dXTw3nljsvnBWRFeJnPBFe_ZOzDdsQS2rYzDKwl8w-1736028322903-0.0.1.1-604800000;\n        path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None\n      X-Content-Type-Options:\n      - nosniff\n      Server:\n      - cloudflare\n      Cf-Ray:\n      - 8fce877fa999bebc-LHR\n      Alt-Svc:\n      - h3=\":443\"; ma=86400\n    body:\n      encoding: ASCII-8BIT\n      string: |\n        {\n          \"id\": \"chatcmpl-Am6Ygz2uAoMLjV2r19fZSDNJ4wUhF\",\n          \"object\": \"chat.completion\",\n          \"created\": 1736028318,\n          \"model\": \"gpt-4o-mini-2024-07-18\",\n          \"choices\": [\n            {\n              \"index\": 0,\n              \"message\": {\n                \"role\": \"assistant\",\n                \"content\": \"{\\\"transcript\\\":[{\\\"start_time\\\":\\\"00:00:15.280\\\",\\\"end_time\\\":\\\"00:00:21.320\\\",\\\"text\\\":\\\"So nice to be here with you! Thank you all for coming. My name is Yaroslav, and I'm from Ukraine. You might know me from my blog or from my Super Al YouTube channel, where I post a lot of content about Ruby, especially about Hotwire.\\\"},{\\\"start_time\\\":\\\"00:00:21.320\\\",\\\"end_time\\\":\\\"00:00:34.399\\\",\\\"text\\\":\\\"I originate from northern Ukraine, near Kyiv and Chernobyl. Fortunately, the area I come from has been liberated, but it is close to where I used to live, just 80 kilometers away from Chernobyl. It is a great place.\\\"},{\\\"start_time\\\":\\\"00:00:34.399\\\",\\\"end_time\\\":\\\"00:01:00.000\\\",\\\"text\\\":\\\"This is my family's home, which was burned in the early days of the war. My godfather went to defend Ukraine, and it has been challenging with the ongoing conflict. Just today, the city of Kharkiv was randomly bombed by the Russians. There are many Ruby on Rails developers from Ukraine, and some of them are actually fighting.\\\"},{\\\"start_time\\\":\\\"00:01:00.000\\\",\\\"end_time\\\":\\\"00:01:19.520\\\",\\\"text\\\":\\\"For instance, this is Verok, who has contributed to Ruby and is currently defending our country. On a more positive note, I recently became a father just two and a half months ago while in France. Today, we are going to talk about Hotwire.\\\"}]}\",\n                \"refusal\": null\n              },\n              \"logprobs\": null,\n              \"finish_reason\": \"stop\"\n            }\n          ],\n          \"usage\": {\n            \"prompt_tokens\": 1088,\n            \"completion_tokens\": 338,\n            \"total_tokens\": 1426,\n            \"prompt_tokens_details\": {\n              \"cached_tokens\": 0,\n              \"audio_tokens\": 0\n            },\n            \"completion_tokens_details\": {\n              \"reasoning_tokens\": 0,\n              \"audio_tokens\": 0,\n              \"accepted_prediction_tokens\": 0,\n              \"rejected_prediction_tokens\": 0\n            }\n          },\n          \"system_fingerprint\": \"fp_0aa8d3e20b\"\n        }\n  recorded_at: Sat, 04 Jan 2025 22:05:22 GMT\nrecorded_with: VCR 6.3.1\n"
  },
  {
    "path": "test/vcr_cassettes/user/enhance_profile_job_test.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: get\n    uri: https://api.github.com/users/tenderlove\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept:\n      - application/vnd.github+json\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Sat, 16 Aug 2025 08:54:33 GMT\n      Content-Type:\n      - application/json; charset=utf-8\n      Cache-Control:\n      - public, max-age=60, s-maxage=60\n      Vary:\n      - Accept,Accept-Encoding, Accept, X-Requested-With\n      Etag:\n      - W/\"3b41446cfe0c5032858fa5be75266d21de7baae4f4d6be0d675269b4f5567c8e\"\n      Last-Modified:\n      - Sat, 19 Jul 2025 22:54:24 GMT\n      X-Github-Media-Type:\n      - github.v3; format=json\n      X-Github-Api-Version-Selected:\n      - '2022-11-28'\n      Access-Control-Expose-Headers:\n      - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining,\n        X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes,\n        X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO,\n        X-GitHub-Request-Id, Deprecation, Sunset\n      Access-Control-Allow-Origin:\n      - \"*\"\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubdomains; preload\n      X-Frame-Options:\n      - deny\n      X-Content-Type-Options:\n      - nosniff\n      X-Xss-Protection:\n      - '0'\n      Referrer-Policy:\n      - origin-when-cross-origin, strict-origin-when-cross-origin\n      Content-Security-Policy:\n      - default-src 'none'\n      Server:\n      - github.com\n      Accept-Ranges:\n      - bytes\n      X-Ratelimit-Limit:\n      - '60'\n      X-Ratelimit-Remaining:\n      - '59'\n      X-Ratelimit-Reset:\n      - '1755338073'\n      X-Ratelimit-Resource:\n      - core\n      X-Ratelimit-Used:\n      - '1'\n      Content-Length:\n      - '1302'\n      X-Github-Request-Id:\n      - 2EBD:2BC522:C62E93:B75624:68A04749\n    body:\n      encoding: ASCII-8BIT\n      string: !binary |-\n        eyJsb2dpbiI6InRlbmRlcmxvdmUiLCJpZCI6MzEyNCwibm9kZV9pZCI6Ik1EUTZWWE5sY2pNeE1qUT0iLCJhdmF0YXJfdXJsIjoiaHR0cHM6Ly9hdmF0YXJzLmdpdGh1YnVzZXJjb250ZW50LmNvbS91LzMxMjQ/dj00IiwiZ3JhdmF0YXJfaWQiOiIiLCJ1cmwiOiJodHRwczovL2FwaS5naXRodWIuY29tL3VzZXJzL3RlbmRlcmxvdmUiLCJodG1sX3VybCI6Imh0dHBzOi8vZ2l0aHViLmNvbS90ZW5kZXJsb3ZlIiwiZm9sbG93ZXJzX3VybCI6Imh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vdXNlcnMvdGVuZGVybG92ZS9mb2xsb3dlcnMiLCJmb2xsb3dpbmdfdXJsIjoiaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS91c2Vycy90ZW5kZXJsb3ZlL2ZvbGxvd2luZ3svb3RoZXJfdXNlcn0iLCJnaXN0c191cmwiOiJodHRwczovL2FwaS5naXRodWIuY29tL3VzZXJzL3RlbmRlcmxvdmUvZ2lzdHN7L2dpc3RfaWR9Iiwic3RhcnJlZF91cmwiOiJodHRwczovL2FwaS5naXRodWIuY29tL3VzZXJzL3RlbmRlcmxvdmUvc3RhcnJlZHsvb3duZXJ9ey9yZXBvfSIsInN1YnNjcmlwdGlvbnNfdXJsIjoiaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS91c2Vycy90ZW5kZXJsb3ZlL3N1YnNjcmlwdGlvbnMiLCJvcmdhbml6YXRpb25zX3VybCI6Imh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vdXNlcnMvdGVuZGVybG92ZS9vcmdzIiwicmVwb3NfdXJsIjoiaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS91c2Vycy90ZW5kZXJsb3ZlL3JlcG9zIiwiZXZlbnRzX3VybCI6Imh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vdXNlcnMvdGVuZGVybG92ZS9ldmVudHN7L3ByaXZhY3l9IiwicmVjZWl2ZWRfZXZlbnRzX3VybCI6Imh0dHBzOi8vYXBpLmdpdGh1Yi5jb20vdXNlcnMvdGVuZGVybG92ZS9yZWNlaXZlZF9ldmVudHMiLCJ0eXBlIjoiVXNlciIsInVzZXJfdmlld190eXBlIjoicHVibGljIiwic2l0ZV9hZG1pbiI6ZmFsc2UsIm5hbWUiOiJBYXJvbiBQYXR0ZXJzb24iLCJjb21wYW55IjoiQFNob3BpZnkiLCJibG9nIjoiaHR0cHM6Ly90ZW5kZXJsb3ZlbWFraW5nLmNvbS8iLCJsb2NhdGlvbiI6IlNlYXR0bGUiLCJlbWFpbCI6bnVsbCwiaGlyZWFibGUiOm51bGwsImJpbyI6IvCfkpjwn5KZ8J+SnPCfkpfwn5Ka4p2k8J+Sk/Cfkpvwn5Ka8J+SlyIsInR3aXR0ZXJfdXNlcm5hbWUiOiJ0ZW5kZXJsb3ZlIiwicHVibGljX3JlcG9zIjozNzEsInB1YmxpY19naXN0cyI6NzQ0LCJmb2xsb3dlcnMiOjk1NDYsImZvbGxvd2luZyI6MjcsImNyZWF0ZWRfYXQiOiIyMDA4LTAzLTE0VDIwOjA0OjE3WiIsInVwZGF0ZWRfYXQiOiIyMDI1LTA3LTE5VDIyOjU0OjI0WiJ9\n  recorded_at: Sat, 16 Aug 2025 08:54:33 GMT\n- request:\n    method: get\n    uri: https://api.github.com/users/tenderlove/social_accounts\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept:\n      - application/vnd.github+json\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Date:\n      - Sat, 16 Aug 2025 08:54:34 GMT\n      Content-Type:\n      - application/json; charset=utf-8\n      Cache-Control:\n      - public, max-age=60, s-maxage=60\n      Vary:\n      - Accept,Accept-Encoding, Accept, X-Requested-With\n      Etag:\n      - W/\"ff04595e00b95e7785a7aad59ef928670062c2fe5cc030202c99aa260bc40925\"\n      X-Github-Media-Type:\n      - github.v3; format=json\n      X-Github-Api-Version-Selected:\n      - '2022-11-28'\n      Access-Control-Expose-Headers:\n      - ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining,\n        X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes,\n        X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO,\n        X-GitHub-Request-Id, Deprecation, Sunset\n      Access-Control-Allow-Origin:\n      - \"*\"\n      Strict-Transport-Security:\n      - max-age=31536000; includeSubdomains; preload\n      X-Frame-Options:\n      - deny\n      X-Content-Type-Options:\n      - nosniff\n      X-Xss-Protection:\n      - '0'\n      Referrer-Policy:\n      - origin-when-cross-origin, strict-origin-when-cross-origin\n      Content-Security-Policy:\n      - default-src 'none'\n      Server:\n      - github.com\n      Accept-Ranges:\n      - bytes\n      X-Ratelimit-Limit:\n      - '60'\n      X-Ratelimit-Remaining:\n      - '58'\n      X-Ratelimit-Reset:\n      - '1755338073'\n      X-Ratelimit-Resource:\n      - core\n      X-Ratelimit-Used:\n      - '2'\n      Content-Length:\n      - '269'\n      X-Github-Request-Id:\n      - 393B:28A69B:B2CB34:A4C6D0:68A0474A\n    body:\n      encoding: ASCII-8BIT\n      string: '[{\"provider\":\"twitter\",\"url\":\"https://twitter.com/tenderlove\"},{\"provider\":\"mastodon\",\"url\":\"https://mastodon.social/@tenderlove\"},{\"provider\":\"generic\",\"url\":\"https://www.threads.net/@tenderlove\"},{\"provider\":\"bluesky\",\"url\":\"https://bsky.app/profile/tenderlove.dev\"}]'\n  recorded_at: Sat, 16 Aug 2025 08:54:34 GMT\nrecorded_with: VCR 6.3.1\n"
  },
  {
    "path": "test/vcr_cassettes/youtube/channels-scrapping.yml",
    "content": "---\nhttp_interactions:\n  - request:\n      method: get\n      uri: https://youtube.googleapis.com/youtube/v3/channels?forUsername=%22paris-rb%22&key=REDACTED_YOUTUBE_API_KEY&part=snippet,contentDetails,statistics\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 200\n        message: OK\n      headers:\n        Content-Type:\n          - application/json; charset=UTF-8\n        Vary:\n          - Origin\n          - Referer\n          - X-Origin\n        Date:\n          - Thu, 08 Jun 2023 18:33:56 GMT\n        Server:\n          - scaffolding on HTTPServer2\n        Cache-Control:\n          - private\n        X-Xss-Protection:\n          - \"0\"\n        X-Frame-Options:\n          - SAMEORIGIN\n        X-Content-Type-Options:\n          - nosniff\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n        Transfer-Encoding:\n          - chunked\n      body:\n        encoding: ASCII-8BIT\n        string: |\n          {\n            \"kind\": \"youtube#channelListResponse\",\n            \"etag\": \"RuuXzTIr0OoDqI4S0RU6n4FqKEM\",\n            \"pageInfo\": {\n              \"totalResults\": 0,\n              \"resultsPerPage\": 5\n            }\n          }\n    recorded_at: Thu, 08 Jun 2023 18:33:55 GMT\n  - request:\n      method: get\n      uri: https://www.youtube.com/@paris-rb\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 302\n        message: Found\n      headers:\n        Content-Type:\n          - application/binary\n        X-Content-Type-Options:\n          - nosniff\n        Cache-Control:\n          - no-cache, no-store, max-age=0, must-revalidate\n        Pragma:\n          - no-cache\n        Expires:\n          - Mon, 01 Jan 1990 00:00:00 GMT\n        Date:\n          - Thu, 08 Jun 2023 18:33:56 GMT\n        Location:\n          - https://consent.youtube.com/m?continue=https%3A%2F%2Fwww.youtube.com%2F%40paris-rb%3Fcbrd%3D1&gl=FR&m=0&pc=yt&cm=2&hl=fr&src=1\n        Strict-Transport-Security:\n          - max-age=31536000\n        X-Frame-Options:\n          - SAMEORIGIN\n        Cross-Origin-Opener-Policy:\n          - same-origin-allow-popups; report-to=\"youtube_main\"\n        Permissions-Policy:\n          - ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*,\n            ch-ua-model=*, ch-ua-wow64=*, ch-ua-form-factor=*, ch-ua-platform=*, ch-ua-platform-version=*\n        Report-To:\n          - '{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}'\n        Origin-Trial:\n          - AvC9UlR6RDk2crliDsFl66RWLnTbHrDbp+DiY6AYz/PNQ4G4tdUTjrHYr2sghbkhGQAVxb7jaPTHpEVBz0uzQwkAAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTcxOTUzMjc5OSwiaXNTdWJkb21haW4iOnRydWV9\n        P3p:\n          - CP=\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl=fr\n            for more info.\"\n        Server:\n          - ESF\n        Content-Length:\n          - \"0\"\n        X-Xss-Protection:\n          - \"0\"\n        Set-Cookie:\n          - CONSENT=PENDING+056; expires=Sat, 07-Jun-2025 18:33:56 GMT; path=/; domain=.youtube.com;\n            Secure\n          - SOCS=CAAaBgiAtISkBg; Domain=.youtube.com; Expires=Sun, 07-Jul-2024 18:33:56\n            GMT; Path=/; Secure; SameSite=lax\n          - VISITOR_INFO1_LIVE=; Domain=.youtube.com; Expires=Fri, 11-Sep-2020 18:33:56\n            GMT; Path=/; Secure; HttpOnly; SameSite=none\n          - YSC=mSrXmXELwWU; Domain=.youtube.com; Path=/; Secure; HttpOnly; SameSite=none\n          - __Secure-YEC=CgtjNlVXVGpMaGZRVSiUvoikBg%3D%3D; Domain=.youtube.com; Expires=Sun,\n            07-Jul-2024 18:33:55 GMT; Path=/; Secure; HttpOnly; SameSite=lax\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      body:\n        encoding: UTF-8\n        string: \"\"\n    recorded_at: Thu, 08 Jun 2023 18:33:56 GMT\n  - request:\n      method: get\n      uri: https://consent.youtube.com/m?cm=2&continue=https://www.youtube.com/@paris-rb?cbrd=1&gl=FR&hl=fr&m=0&pc=yt&src=1\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 303\n        message: See Other\n      headers:\n        Content-Type:\n          - application/binary\n        Vary:\n          - Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site\n        Cache-Control:\n          - no-cache, no-store, max-age=0, must-revalidate\n        Pragma:\n          - no-cache\n        Expires:\n          - Mon, 01 Jan 1990 00:00:00 GMT\n        Date:\n          - Thu, 08 Jun 2023 18:33:56 GMT\n        Location:\n          - https://www.youtube.com/@paris-rb?cbrd=1&ucbcb=1\n        Cross-Origin-Opener-Policy:\n          - unsafe-none\n        Content-Security-Policy:\n          - require-trusted-types-for 'script';report-uri /_/ConsentUi/cspreport\n          - script-src 'report-sample' 'nonce-Tu_7iug6_ZaKX0Ex2P6HxQ' 'unsafe-inline';object-src\n            'none';base-uri 'self';report-uri /_/ConsentUi/cspreport;worker-src 'self'\n        Cross-Origin-Resource-Policy:\n          - same-site\n        Permissions-Policy:\n          - ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*,\n            ch-ua-model=*, ch-ua-wow64=*, ch-ua-form-factor=*, ch-ua-platform=*, ch-ua-platform-version=*\n        Accept-Ch:\n          - Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Full-Version-List,\n            Sec-CH-UA-Model, Sec-CH-UA-WoW64, Sec-CH-UA-Form-Factor, Sec-CH-UA-Platform,\n            Sec-CH-UA-Platform-Version\n        Server:\n          - ESF\n        Content-Length:\n          - \"0\"\n        X-Xss-Protection:\n          - \"0\"\n        X-Frame-Options:\n          - SAMEORIGIN\n        X-Content-Type-Options:\n          - nosniff\n        Set-Cookie:\n          - CONSENT=PENDING+932; expires=Sat, 07-Jun-2025 18:33:56 GMT; path=/; domain=.youtube.com;\n            Secure\n        P3p:\n          - CP=\"This is not a P3P policy! See g.co/p3phelp for more info.\"\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      body:\n        encoding: UTF-8\n        string: \"\"\n    recorded_at: Thu, 08 Jun 2023 18:33:56 GMT\n  - request:\n      method: get\n      uri: https://www.youtube.com/@paris-rb?cbrd=1&ucbcb=1\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 200\n        message: OK\n      headers:\n        Content-Type:\n          - text/html; charset=utf-8\n        X-Content-Type-Options:\n          - nosniff\n        Cache-Control:\n          - no-cache, no-store, max-age=0, must-revalidate\n        Pragma:\n          - no-cache\n        Expires:\n          - Mon, 01 Jan 1990 00:00:00 GMT\n        Date:\n          - Thu, 08 Jun 2023 18:33:56 GMT\n        X-Frame-Options:\n          - SAMEORIGIN\n        Strict-Transport-Security:\n          - max-age=31536000\n        Report-To:\n          - '{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}'\n        Origin-Trial:\n          - AvC9UlR6RDk2crliDsFl66RWLnTbHrDbp+DiY6AYz/PNQ4G4tdUTjrHYr2sghbkhGQAVxb7jaPTHpEVBz0uzQwkAAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTcxOTUzMjc5OSwiaXNTdWJkb21haW4iOnRydWV9\n        Cross-Origin-Opener-Policy:\n          - same-origin-allow-popups; report-to=\"youtube_main\"\n        Permissions-Policy:\n          - ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*,\n            ch-ua-model=*, ch-ua-wow64=*, ch-ua-form-factor=*, ch-ua-platform=*, ch-ua-platform-version=*\n        P3p:\n          - CP=\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl=fr\n            for more info.\"\n        Server:\n          - ESF\n        X-Xss-Protection:\n          - \"0\"\n        Set-Cookie:\n          - CONSENT=PENDING+199; expires=Sat, 07-Jun-2025 18:33:56 GMT; path=/; domain=.youtube.com;\n            Secure\n          - VISITOR_INFO1_LIVE=; Domain=.youtube.com; Expires=Fri, 11-Sep-2020 18:33:56\n            GMT; Path=/; Secure; HttpOnly; SameSite=none\n          - YSC=ZlcjgJsn8jo; Domain=.youtube.com; Path=/; Secure; HttpOnly; SameSite=none\n          - __Secure-YEC=CgtBbl9yblgwWHlrayiUvoikBg%3D%3D; Domain=.youtube.com; Expires=Sun,\n            07-Jul-2024 18:33:55 GMT; Path=/; Secure; HttpOnly; SameSite=lax\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n        Transfer-Encoding:\n          - chunked\n      body:\n        encoding: ASCII-8BIT\n        string: !binary |-\n          PCFET0NUWVBFIGh0bWw+PGh0bWwgc3R5bGU9ImZvbnQtc2l6ZTogMTBweDtmb250LWZhbWlseTogUm9ib3RvLCBBcmlhbCwgc2Fucy1zZXJpZjsiIGxhbmc9ImZyLUZSIiBzeXN0ZW0taWNvbnMgdHlwb2dyYXBoeSB0eXBvZ3JhcGh5LXNwYWNpbmcgZGFya2VyLWRhcmstdGhlbWUgZGFya2VyLWRhcmstdGhlbWUtZGVwcmVjYXRlPjxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IlgtVUEtQ29tcGF0aWJsZSIgY29udGVudD0iSUU9ZWRnZSIvPjxtZXRhIGh0dHAtZXF1aXY9Im9yaWdpbi10cmlhbCIgY29udGVudD0iQXB2SzY3b2NpSGdyMmVnZDZjMlpqcmZQdVJzOEJIY3ZTZ2dvZ0lPUFFOSDdHSjNjVmx5SjFOT3EvQ09DZGowK3p4c2txSHQ5SGdMTEVUYzhxcUQrdndzQUFBQnRleUp2Y21sbmFXNGlPaUpvZEhSd2N6b3ZMM2x2ZFhSMVltVXVZMjl0T2pRME15SXNJbVpsWVhSMWNtVWlPaUpRY21sMllXTjVVMkZ1WkdKdmVFRmtjMEZRU1hNaUxDSmxlSEJwY25raU9qRTJPVFV4TmpjNU9Ua3NJbWx6VTNWaVpHOXRZV2x1SWpwMGNuVmxmUT09Ii8+PHNjcmlwdCBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+dmFyIHl0Y2ZnPXtkOmZ1bmN0aW9uKCl7cmV0dXJuIHdpbmRvdy55dCYmeXQuY29uZmlnX3x8eXRjZmcuZGF0YV98fCh5dGNmZy5kYXRhXz17fSl9LGdldDpmdW5jdGlvbihrLG8pe3JldHVybiBrIGluIHl0Y2ZnLmQoKT95dGNmZy5kKClba106b30sc2V0OmZ1bmN0aW9uKCl7dmFyIGE9YXJndW1lbnRzO2lmKGEubGVuZ3RoPjEpeXRjZmcuZCgpW2FbMF1dPWFbMV07ZWxzZXt2YXIgaztmb3IoayBpbiBhWzBdKXl0Y2ZnLmQoKVtrXT1hWzBdW2tdfX19Owp3aW5kb3cueXRjZmcuc2V0KCdFTUVSR0VOQ1lfQkFTRV9VUkwnLCAnXC9lcnJvcl8yMDQ/dFx4M2Rqc2Vycm9yXHgyNmxldmVsXHgzZEVSUk9SXHgyNmNsaWVudC5uYW1lXHgzZDFceDI2Y2xpZW50LnZlcnNpb25ceDNkMi4yMDIzMDYwNy4wNi4wMCcpOzwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPihmdW5jdGlvbigpe3dpbmRvdy55dGVycj13aW5kb3cueXRlcnJ8fHRydWU7d2luZG93LnVuaGFuZGxlZEVycm9yTWVzc2FnZXM9e307d2luZG93LnVuaGFuZGxlZEVycm9yQ291bnQ9MDsKd2luZG93Lm9uZXJyb3I9ZnVuY3Rpb24obXNnLHVybCxsaW5lLGNvbHVtbk51bWJlcixlcnJvcil7dmFyIGVycjtpZihlcnJvcillcnI9ZXJyb3I7ZWxzZXtlcnI9bmV3IEVycm9yO2Vyci5zdGFjaz0iIjtlcnIubWVzc2FnZT1tc2c7ZXJyLmZpbGVOYW1lPXVybDtlcnIubGluZU51bWJlcj1saW5lO2lmKCFpc05hTihjb2x1bW5OdW1iZXIpKWVyclsiY29sdW1uTnVtYmVyIl09Y29sdW1uTnVtYmVyfXZhciBtZXNzYWdlPVN0cmluZyhlcnIubWVzc2FnZSk7aWYoIWVyci5tZXNzYWdlfHxtZXNzYWdlIGluIHdpbmRvdy51bmhhbmRsZWRFcnJvck1lc3NhZ2VzfHx3aW5kb3cudW5oYW5kbGVkRXJyb3JDb3VudD49NSlyZXR1cm47d2luZG93LnVuaGFuZGxlZEVycm9yQ291bnQrPTE7d2luZG93LnVuaGFuZGxlZEVycm9yTWVzc2FnZXNbbWVzc2FnZV09dHJ1ZTt2YXIgaW1nPW5ldyBJbWFnZTt3aW5kb3cuZW1lcmdlbmN5VGltZW91dEltZz1pbWc7aW1nLm9ubG9hZD1pbWcub25lcnJvcj1mdW5jdGlvbigpe2RlbGV0ZSB3aW5kb3cuZW1lcmdlbmN5VGltZW91dEltZ307CnZhciBjb21iaW5lZExpbmVBbmRDb2x1bW49ZXJyLmxpbmVOdW1iZXI7aWYoIWlzTmFOKGVyclsiY29sdW1uTnVtYmVyIl0pKWNvbWJpbmVkTGluZUFuZENvbHVtbj1jb21iaW5lZExpbmVBbmRDb2x1bW4rKCI6IitlcnJbImNvbHVtbk51bWJlciJdKTt2YXIgc3RhY2s9ZXJyLnN0YWNrfHwiIjt2YXIgdmFsdWVzPXsibXNnIjptZXNzYWdlLCJ0eXBlIjplcnIubmFtZSwiY2xpZW50LnBhcmFtcyI6InVuaGFuZGxlZCB3aW5kb3cgZXJyb3IiLCJmaWxlIjplcnIuZmlsZU5hbWUsImxpbmUiOmNvbWJpbmVkTGluZUFuZENvbHVtbiwic3RhY2siOnN0YWNrLnN1YnN0cigwLDUwMCl9O3ZhciB0aGlyZFBhcnR5U2NyaXB0PSFlcnIuZmlsZU5hbWV8fGVyci5maWxlTmFtZT09PSI8YW5vbnltb3VzPiJ8fHN0YWNrLmluZGV4T2YoImV4dGVuc2lvbjovLyIpPj0wO3ZhciByZXBsYWNlZD1zdGFjay5yZXBsYWNlKC9odHRwczpcL1wvd3d3LnlvdXR1YmUuY29tXC8vZywiIik7aWYocmVwbGFjZWQubWF0Y2goL2h0dHBzPzpcL1wvW14vXStcLy8pKXRoaXJkUGFydHlTY3JpcHQ9CnRydWU7ZWxzZSBpZihzdGFjay5pbmRleE9mKCJ0cmFwUHJvcCIpPj0wJiZzdGFjay5pbmRleE9mKCJ0cmFwQ2hhaW4iKT49MCl0aGlyZFBhcnR5U2NyaXB0PXRydWU7ZWxzZSBpZihtZXNzYWdlLmluZGV4T2YoInJlZGVmaW5lIG5vbi1jb25maWd1cmFibGUiKT49MCl0aGlyZFBhcnR5U2NyaXB0PXRydWU7dmFyIGJhc2VVcmw9d2luZG93WyJ5dGNmZyJdLmdldCgiRU1FUkdFTkNZX0JBU0VfVVJMIiwiaHR0cHM6Ly93d3cueW91dHViZS5jb20vZXJyb3JfMjA0P3Q9anNlcnJvciZsZXZlbD1FUlJPUiIpO3ZhciB1bnN1cHBvcnRlZD1tZXNzYWdlLmluZGV4T2YoIndpbmRvdy5jdXN0b21FbGVtZW50cyBpcyB1bmRlZmluZWQiKT49MDtpZih0aGlyZFBhcnR5U2NyaXB0fHx1bnN1cHBvcnRlZCliYXNlVXJsPWJhc2VVcmwucmVwbGFjZSgibGV2ZWw9RVJST1IiLCJsZXZlbD1XQVJOSU5HIik7dmFyIHBhcnRzPVtiYXNlVXJsXTt2YXIga2V5O2ZvcihrZXkgaW4gdmFsdWVzKXt2YXIgdmFsdWU9CnZhbHVlc1trZXldO2lmKHZhbHVlKXBhcnRzLnB1c2goa2V5KyI9IitlbmNvZGVVUklDb21wb25lbnQodmFsdWUpKX1pbWcuc3JjPXBhcnRzLmpvaW4oIiYiKX07CihmdW5jdGlvbigpe2Z1bmN0aW9uIF9nZXRFeHRlbmRlZE5hdGl2ZVByb3RvdHlwZSh0YWcpe3ZhciBwPXRoaXMuX25hdGl2ZVByb3RvdHlwZXNbdGFnXTtpZighcCl7cD1PYmplY3QuY3JlYXRlKHRoaXMuZ2V0TmF0aXZlUHJvdG90eXBlKHRhZykpO3ZhciBwJD1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh3aW5kb3dbIlBvbHltZXIiXS5CYXNlKTt2YXIgaT0wO3ZhciBuPXZvaWQgMDtmb3IoO2k8cCQubGVuZ3RoJiYobj1wJFtpXSk7aSsrKWlmKCF3aW5kb3dbIlBvbHltZXIiXS5CYXNlRGVzY3JpcHRvcnNbbl0pdHJ5e3Bbbl09d2luZG93WyJQb2x5bWVyIl0uQmFzZVtuXX1jYXRjaChlKXt0aHJvdyBuZXcgRXJyb3IoIkVycm9yIHdoaWxlIGNvcHlpbmcgcHJvcGVydHk6ICIrbisiLiBUYWcgaXMgIit0YWcpO310cnl7T2JqZWN0LmRlZmluZVByb3BlcnRpZXMocCx3aW5kb3dbIlBvbHltZXIiXS5CYXNlRGVzY3JpcHRvcnMpfWNhdGNoKGUkMCl7dGhyb3cgbmV3IEVycm9yKCJQb2x5bWVyIGRlZmluZSBwcm9wZXJ0eSBmYWlsZWQgZm9yICIrCk9iamVjdC5rZXlzKHApKTt9dGhpcy5fbmF0aXZlUHJvdG90eXBlc1t0YWddPXB9cmV0dXJuIHB9ZnVuY3Rpb24gaGFuZGxlUG9seW1lckVycm9yKG1zZyl7d2luZG93Lm9uZXJyb3IobXNnLHdpbmRvdy5sb2NhdGlvbi5ocmVmLDAsMCxuZXcgRXJyb3IoQXJyYXkucHJvdG90eXBlLmpvaW4uY2FsbChhcmd1bWVudHMsIiwiKSkpfXZhciBvcmlnUG9seW1lcj13aW5kb3dbIlBvbHltZXIiXTt2YXIgbmV3UG9seW1lcj1mdW5jdGlvbihjb25maWcpe2lmKCFvcmlnUG9seW1lci5feXRJbnRlcmNlcHRlZCYmd2luZG93WyJQb2x5bWVyIl0uQmFzZSl7b3JpZ1BvbHltZXIuX3l0SW50ZXJjZXB0ZWQ9dHJ1ZTt3aW5kb3dbIlBvbHltZXIiXS5CYXNlLl9nZXRFeHRlbmRlZE5hdGl2ZVByb3RvdHlwZT1fZ2V0RXh0ZW5kZWROYXRpdmVQcm90b3R5cGU7d2luZG93WyJQb2x5bWVyIl0uQmFzZS5fZXJyb3I9aGFuZGxlUG9seW1lckVycm9yO3dpbmRvd1siUG9seW1lciJdLkJhc2UuX3dhcm49aGFuZGxlUG9seW1lckVycm9yfXJldHVybiBvcmlnUG9seW1lci5hcHBseSh0aGlzLAphcmd1bWVudHMpfTt2YXIgb3JpZ0Rlc2NyaXB0b3I9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih3aW5kb3csIlBvbHltZXIiKTtPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LCJQb2x5bWVyIix7c2V0OmZ1bmN0aW9uKHApe2lmKG9yaWdEZXNjcmlwdG9yJiZvcmlnRGVzY3JpcHRvci5zZXQmJm9yaWdEZXNjcmlwdG9yLmdldCl7b3JpZ0Rlc2NyaXB0b3Iuc2V0KHApO29yaWdQb2x5bWVyPW9yaWdEZXNjcmlwdG9yLmdldCgpfWVsc2Ugb3JpZ1BvbHltZXI9cDtpZih0eXBlb2Ygb3JpZ1BvbHltZXI9PT0iZnVuY3Rpb24iKU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csIlBvbHltZXIiLHt2YWx1ZTpvcmlnUG9seW1lcixjb25maWd1cmFibGU6dHJ1ZSxlbnVtZXJhYmxlOnRydWUsd3JpdGFibGU6dHJ1ZX0pfSxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdHlwZW9mIG9yaWdQb2x5bWVyPT09ImZ1bmN0aW9uIj9uZXdQb2x5bWVyOm9yaWdQb2x5bWVyfSxjb25maWd1cmFibGU6dHJ1ZSwKZW51bWVyYWJsZTp0cnVlfSl9KSgpO30pLmNhbGwodGhpcyk7Cjwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPndpbmRvdy5Qb2x5bWVyPXdpbmRvdy5Qb2x5bWVyfHx7fTt3aW5kb3cuUG9seW1lci5sZWdhY3lPcHRpbWl6YXRpb25zPXRydWU7d2luZG93LlBvbHltZXIuc2V0UGFzc2l2ZVRvdWNoR2VzdHVyZXM9dHJ1ZTt3aW5kb3cuU2hhZHlET009e2ZvcmNlOnRydWUscHJlZmVyUGVyZm9ybWFuY2U6dHJ1ZSxub1BhdGNoOnRydWV9Owp3aW5kb3cucG9seW1lclNraXBMb2FkaW5nRm9udFJvYm90byA9IHRydWU7PC9zY3JpcHQ+PGxpbmsgcmVsPSJzaG9ydGN1dCBpY29uIiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9zL2Rlc2t0b3AvMzc0ZmFhZDUvaW1nL2Zhdmljb24uaWNvIiB0eXBlPSJpbWFnZS94LWljb24iPjxsaW5rIHJlbD0iaWNvbiIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2ltZy9mYXZpY29uXzMyeDMyLnBuZyIgc2l6ZXM9IjMyeDMyIj48bGluayByZWw9Imljb24iIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9pbWcvZmF2aWNvbl80OHg0OC5wbmciIHNpemVzPSI0OHg0OCI+PGxpbmsgcmVsPSJpY29uIiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9zL2Rlc2t0b3AvMzc0ZmFhZDUvaW1nL2Zhdmljb25fOTZ4OTYucG5nIiBzaXplcz0iOTZ4OTYiPjxsaW5rIHJlbD0iaWNvbiIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2ltZy9mYXZpY29uXzE0NHgxNDQucG5nIiBzaXplcz0iMTQ0eDE0NCI+PHNjcmlwdCBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+dmFyIHl0Y3NpPXtndDpmdW5jdGlvbihuKXtuPShufHwiIikrImRhdGFfIjtyZXR1cm4geXRjc2lbbl18fCh5dGNzaVtuXT17dGljazp7fSxpbmZvOnt9fSl9LG5vdzp3aW5kb3cucGVyZm9ybWFuY2UmJndpbmRvdy5wZXJmb3JtYW5jZS50aW1pbmcmJndpbmRvdy5wZXJmb3JtYW5jZS5ub3cmJndpbmRvdy5wZXJmb3JtYW5jZS50aW1pbmcubmF2aWdhdGlvblN0YXJ0P2Z1bmN0aW9uKCl7cmV0dXJuIHdpbmRvdy5wZXJmb3JtYW5jZS50aW1pbmcubmF2aWdhdGlvblN0YXJ0K3dpbmRvdy5wZXJmb3JtYW5jZS5ub3coKX06ZnVuY3Rpb24oKXtyZXR1cm4obmV3IERhdGUpLmdldFRpbWUoKX0sdGljazpmdW5jdGlvbihsLHQsbil7dmFyIHRpY2tzPXl0Y3NpLmd0KG4pLnRpY2s7dmFyIHY9dHx8eXRjc2kubm93KCk7aWYodGlja3NbbF0pe3RpY2tzWyJfIitsXT10aWNrc1siXyIrbF18fFt0aWNrc1tsXV07dGlja3NbIl8iK2xdLnB1c2godil9dGlja3NbbF09dn0saW5mbzpmdW5jdGlvbihrLAp2LG4pe3l0Y3NpLmd0KG4pLmluZm9ba109dn0sc2V0U3RhcnQ6ZnVuY3Rpb24odCxuKXt5dGNzaS50aWNrKCJfc3RhcnQiLHQsbil9fTsKKGZ1bmN0aW9uKHcsZCl7ZnVuY3Rpb24gaXNHZWNrbygpe2lmKCF3Lm5hdmlnYXRvcilyZXR1cm4gZmFsc2U7dHJ5e2lmKHcubmF2aWdhdG9yLnVzZXJBZ2VudERhdGEmJncubmF2aWdhdG9yLnVzZXJBZ2VudERhdGEuYnJhbmRzJiZ3Lm5hdmlnYXRvci51c2VyQWdlbnREYXRhLmJyYW5kcy5sZW5ndGgpe3ZhciBicmFuZHM9dy5uYXZpZ2F0b3IudXNlckFnZW50RGF0YS5icmFuZHM7dmFyIGk9MDtmb3IoO2k8YnJhbmRzLmxlbmd0aDtpKyspaWYoYnJhbmRzW2ldJiZicmFuZHNbaV0uYnJhbmQ9PT0iRmlyZWZveCIpcmV0dXJuIHRydWU7cmV0dXJuIGZhbHNlfX1jYXRjaChlKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhyb3cgZTt9KX1pZighdy5uYXZpZ2F0b3IudXNlckFnZW50KXJldHVybiBmYWxzZTt2YXIgdWE9dy5uYXZpZ2F0b3IudXNlckFnZW50O3JldHVybiB1YS5pbmRleE9mKCJHZWNrbyIpPjAmJnVhLnRvTG93ZXJDYXNlKCkuaW5kZXhPZigid2Via2l0Iik8MCYmdWEuaW5kZXhPZigiRWRnZSIpPAowJiZ1YS5pbmRleE9mKCJUcmlkZW50Iik8MCYmdWEuaW5kZXhPZigiTVNJRSIpPDB9eXRjc2kuc2V0U3RhcnQody5wZXJmb3JtYW5jZT93LnBlcmZvcm1hbmNlLnRpbWluZy5yZXNwb25zZVN0YXJ0Om51bGwpO3ZhciBpc1ByZXJlbmRlcj0oZC52aXNpYmlsaXR5U3RhdGV8fGQud2Via2l0VmlzaWJpbGl0eVN0YXRlKT09InByZXJlbmRlciI7dmFyIHZOYW1lPSFkLnZpc2liaWxpdHlTdGF0ZSYmZC53ZWJraXRWaXNpYmlsaXR5U3RhdGU/IndlYmtpdHZpc2liaWxpdHljaGFuZ2UiOiJ2aXNpYmlsaXR5Y2hhbmdlIjtpZihpc1ByZXJlbmRlcil7dmFyIHN0YXJ0VGljaz1mdW5jdGlvbigpe3l0Y3NpLnNldFN0YXJ0KCk7ZC5yZW1vdmVFdmVudExpc3RlbmVyKHZOYW1lLHN0YXJ0VGljayl9O2QuYWRkRXZlbnRMaXN0ZW5lcih2TmFtZSxzdGFydFRpY2ssZmFsc2UpfWlmKGQuYWRkRXZlbnRMaXN0ZW5lcilkLmFkZEV2ZW50TGlzdGVuZXIodk5hbWUsZnVuY3Rpb24oKXt5dGNzaS50aWNrKCJ2YyIpfSwKZmFsc2UpO2lmKGlzR2Vja28oKSl7dmFyIGlzSGlkZGVuPShkLnZpc2liaWxpdHlTdGF0ZXx8ZC53ZWJraXRWaXNpYmlsaXR5U3RhdGUpPT0iaGlkZGVuIjtpZihpc0hpZGRlbil5dGNzaS50aWNrKCJ2YyIpfXZhciBzbHQ9ZnVuY3Rpb24oZWwsdCl7c2V0VGltZW91dChmdW5jdGlvbigpe3ZhciBuPXl0Y3NpLm5vdygpO2VsLmxvYWRUaW1lPW47aWYoZWwuc2x0KWVsLnNsdCgpfSx0KX07dy5fX3l0UklMPWZ1bmN0aW9uKGVsKXtpZighZWwuZ2V0QXR0cmlidXRlKCJkYXRhLXRodW1iIikpaWYody5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24oKXtzbHQoZWwsMCl9KTtlbHNlIHNsdChlbCwxNil9fSkod2luZG93LGRvY3VtZW50KTsKPC9zY3JpcHQ+PHNjcmlwdCBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+KGZ1bmN0aW9uKCkge3ZhciBpbWcgPSBuZXcgSW1hZ2UoKS5zcmMgPSAiaHR0cHM6Ly9pLnl0aW1nLmNvbS9nZW5lcmF0ZV8yMDQiO30pKCk7PC9zY3JpcHQ+PHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9qc2Jpbi93ZWItYW5pbWF0aW9ucy1uZXh0LWxpdGUubWluLnZmbHNldC93ZWItYW5pbWF0aW9ucy1uZXh0LWxpdGUubWluLmpzIiBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+PC9zY3JpcHQ+PHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9qc2Jpbi93ZWJjb21wb25lbnRzLWFsbC1ub1BhdGNoLnZmbHNldC93ZWJjb21wb25lbnRzLWFsbC1ub1BhdGNoLmpzIiBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+PC9zY3JpcHQ+PHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9qc2Jpbi9mZXRjaC1wb2x5ZmlsbC52ZmxzZXQvZmV0Y2gtcG9seWZpbGwuanMiIG5vbmNlPSJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIj48L3NjcmlwdD48c2NyaXB0IHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL2ludGVyc2VjdGlvbi1vYnNlcnZlci5taW4udmZsc2V0L2ludGVyc2VjdGlvbi1vYnNlcnZlci5taW4uanMiIG5vbmNlPSJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIj48L3NjcmlwdD48c2NyaXB0IG5vbmNlPSJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIj5pZiAod2luZG93Lnl0Y3NpKSB7d2luZG93Lnl0Y3NpLnRpY2soJ2xwY3MnLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPihmdW5jdGlvbigpIHt3aW5kb3cueXRwbGF5ZXI9e307Cnl0Y2ZnLnNldCh7IkNMSUVOVF9DQU5BUllfU1RBVEUiOiJub25lIiwiREVWSUNFIjoiY2VuZ1x1MDAzZFVTRVJfREVGSU5FRFx1MDAyNmNwbGF0Zm9ybVx1MDAzZERFU0tUT1AiLCJESVNBQkxFX1lUX0lNR19ERUxBWV9MT0FESU5HIjpmYWxzZSwiRUxFTUVOVF9QT09MX0RFRkFVTFRfQ0FQIjo3NSwiRVZFTlRfSUQiOiJGQi1DWk83WEtwcVcxd2JfNWF2WUJ3IiwiRVhQRVJJTUVOVF9GTEFHUyI6eyJINV9lbmFibGVfZnVsbF9wYWNmX2xvZ2dpbmciOnRydWUsIkg1X3VzZV9hc3luY19sb2dnaW5nIjp0cnVlLCJhY3Rpb25fY29tcGFuaW9uX2NlbnRlcl9hbGlnbl9kZXNjcmlwdGlvbiI6dHJ1ZSwiYWxsb3dfc2tpcF9uZXR3b3JrbGVzcyI6dHJ1ZSwiYXR0X3dlYl9yZWNvcmRfbWV0cmljcyI6dHJ1ZSwiYXV0b2VzY2FwZV90ZW1wZGF0YV91cmwiOnRydWUsImJyb3dzZV9uZXh0X2NvbnRpbnVhdGlvbnNfbWlncmF0aW9uX3BsYXlsaXN0Ijp0cnVlLCJjM193YXRjaF9wYWdlX2NvbXBvbmVudCI6dHJ1ZSwiY2FjaGVfdXRjX29mZnNldF9taW51dGVzX2luX3ByZWZfY29va2llIjp0cnVlLCJjYW5jZWxfcGVuZGluZ19uYXZzIjp0cnVlLCJjaGVja191c2VyX2xhY3RfYXRfcHJvbXB0X3Nob3duX3RpbWVfb25fd2ViIjp0cnVlLCJjbGVhcl91c2VyX3BhcnRpdGlvbmVkX2xzIjp0cnVlLCJjbGllbnRfcmVzcGVjdF9hdXRvcGxheV9zd2l0Y2hfYnV0dG9uX3JlbmRlcmVyIjp0cnVlLCJjb2xkX21pc3NpbmdfaGlzdG9yeSI6dHJ1ZSwiY29tcHJlc3NfZ2VsIjp0cnVlLCJjb25maWdfYWdlX3JlcG9ydF9raWxsc3dpdGNoIjp0cnVlLCJjc2lfb25fZ2VsIjp0cnVlLCJkZWNvcmF0ZV9hdXRvcGxheV9yZW5kZXJlciI6dHJ1ZSwiZGVmZXJfbWVudXMiOnRydWUsImRlZmVyX292ZXJsYXlzIjp0cnVlLCJkZWZlcl9yZW5kZXJpbmdfb3V0c2lkZV92aXNpYmxlX2FyZWEiOnRydWUsImRlcHJlY2F0ZV9jc2lfaGFzX2luZm8iOnRydWUsImRlcHJlY2F0ZV9wYWlyX3NlcnZsZXRfZW5hYmxlZCI6dHJ1ZSwiZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19jaGlsZCI6dHJ1ZSwiZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19wYXJlbnQiOnRydWUsImRlc2t0b3BfYWRkX3RvX3BsYXlsaXN0X3JlbmRlcmVyX2RpYWxvZ19wb3B1cCI6dHJ1ZSwiZGVza3RvcF9hZGp1c3RfdG91Y2hfdGFyZ2V0Ijp0cnVlLCJkZXNrdG9wX2FuaW1hdGVfbWluaXBsYXllciI6dHJ1ZSwiZGVza3RvcF9jbGllbnRfcmVsZWFzZSI6dHJ1ZSwiZGVza3RvcF9kZWxheV9wbGF5ZXJfcmVzaXppbmciOnRydWUsImRlc2t0b3BfZW5hYmxlX2RtcGFuZWxfY2xpY2tfZHJhZ19zY3JvbGwiOnRydWUsImRlc2t0b3BfZW5hYmxlX2RtcGFuZWxfc2Nyb2xsIjp0cnVlLCJkZXNrdG9wX2VuYWJsZV9kbXBhbmVsX3doZWVsX3Njcm9sbCI6dHJ1ZSwiZGVza3RvcF9pbWFnZV9jdGFfbm9fYmFja2dyb3VuZCI6dHJ1ZSwiZGVza3RvcF9rZXlib2FyZF9jYXB0dXJlX2tleWRvd25fa2lsbHN3aXRjaCI6dHJ1ZSwiZGVza3RvcF9sb2dfaW1nX2NsaWNrX2xvY2F0aW9uIjp0cnVlLCJkZXNrdG9wX21peF91c2Vfc2FtcGxlZF9jb2xvcl9mb3JfYm90dG9tX2JhciI6dHJ1ZSwiZGVza3RvcF9taXhfdXNlX3NhbXBsZWRfY29sb3JfZm9yX2JvdHRvbV9iYXJfc2VhcmNoIjp0cnVlLCJkZXNrdG9wX21peF91c2Vfc2FtcGxlZF9jb2xvcl9mb3JfYm90dG9tX2Jhcl93YXRjaF9uZXh0Ijp0cnVlLCJkZXNrdG9wX25vdGlmaWNhdGlvbl9oaWdoX3ByaW9yaXR5X2lnbm9yZV9wdXNoIjp0cnVlLCJkZXNrdG9wX25vdGlmaWNhdGlvbl9zZXRfdGl0bGVfYmFyIjp0cnVlLCJkZXNrdG9wX3BlcnNpc3RlbnRfbWVudSI6dHJ1ZSwiZGVza3RvcF9zZWFyY2hfcHJvbWluZW50X3RodW1icyI6dHJ1ZSwiZGVza3RvcF9zcGFya2xlc19saWdodF9jdGFfYnV0dG9uIjp0cnVlLCJkZXNrdG9wX3N3aXBlYWJsZV9ndWlkZSI6dHJ1ZSwiZGVza3RvcF90aGVtZWFibGVfdnVsY2FuIjp0cnVlLCJkZXNrdG9wX3VzZV9uZXdfaGlzdG9yeV9tYW5hZ2VyIjp0cnVlLCJkaXNhYmxlX2NoaWxkX25vZGVfYXV0b19mb3JtYXR0ZWRfc3RyaW5ncyI6dHJ1ZSwiZGlzYWJsZV9kZXBlbmRlbmN5X2luamVjdGlvbiI6dHJ1ZSwiZGlzYWJsZV9mZWF0dXJlc19mb3Jfc3VwZXgiOnRydWUsImRpc2FibGVfbGVnYWN5X2Rlc2t0b3BfcmVtb3RlX3F1ZXVlIjp0cnVlLCJkaXNhYmxlX3BhY2ZfbG9nZ2luZ19mb3JfbWVtb3J5X2xpbWl0ZWRfdHYiOnRydWUsImRpc2FibGVfcmljaF9ncmlkX2lubGluZV9wbGF5ZXJfcG9wX291dCI6dHJ1ZSwiZGlzYWJsZV9zaW1wbGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzIjp0cnVlLCJkaXNhYmxlX3RodW1ibmFpbF9wcmVsb2FkaW5nIjp0cnVlLCJlbWJlZHNfd2ViX2VuYWJsZV9yZXBsYWNlX3VubG9hZF93X3BhZ2VoaWRlIjp0cnVlLCJlbWJlZHNfd2ViX253bF9kaXNhYmxlX25vY29va2llIjp0cnVlLCJlbmFibGVfYWJfcnBfaW50Ijp0cnVlLCJlbmFibGVfYnJvd3Nlcl9jb29raWVfc3RhdHVzX21vbml0b3JpbmciOnRydWUsImVuYWJsZV9idXR0b25fYmVoYXZpb3JfcmV1c2UiOnRydWUsImVuYWJsZV9jYWxsX3RvX2FjdGlvbl9jbGFyaWZpY2F0aW9uX3JlbmRlcmVyX2JvdHRvbV9zZWN0aW9uX2NvbmRpdGlvbnMiOnRydWUsImVuYWJsZV9jaGFubmVsX3BhZ2VfbW9kZXJuX3Byb2ZpbGVfc2VjdGlvbiI6dHJ1ZSwiZW5hYmxlX2NsaWVudF9zbGlfbG9nZ2luZyI6dHJ1ZSwiZW5hYmxlX2NsaWVudF9zdHJlYW16X3dlYiI6dHJ1ZSwiZW5hYmxlX2Rlc2t0b3BfYW1zdGVyZGFtX2luZm9fcGFuZWxzIjp0cnVlLCJlbmFibGVfZGlzbWlzc19sb2FkaW5nX21hbnVhbGx5Ijp0cnVlLCJlbmFibGVfZG1hX3dlYl90b2FzdCI6dHJ1ZSwiZW5hYmxlX2RvY2tlZF9jaGF0X21lc3NhZ2VzIjp0cnVlLCJlbmFibGVfZ2VsX2xvZ19jb21tYW5kcyI6dHJ1ZSwiZW5hYmxlX2dldF9hY2NvdW50X3N3aXRjaGVyX2VuZHBvaW50X29uX3dlYmZlIjp0cnVlLCJlbmFibGVfaDVfaW5zdHJlYW1fd2F0Y2hfbmV4dF9wYXJhbXNfb2FybGliIjp0cnVlLCJlbmFibGVfaDVfdmlkZW9fYWRzX29hcmxpYiI6dHJ1ZSwiZW5hYmxlX2hhbmRsZXNfYWNjb3VudF9tZW51X3N3aXRjaGVyIjp0cnVlLCJlbmFibGVfaGFuZGxlc19pbl9tZW50aW9uX3N1Z2dlc3RfcG9zdHMiOnRydWUsImVuYWJsZV9obHBfY2xpZW50X2ljb25fcGljayI6dHJ1ZSwiZW5hYmxlX2ltYWdlX3BvbGxfcG9zdF9jcmVhdGlvbiI6dHJ1ZSwiZW5hYmxlX2lubGluZV9zaG9ydHNfb25fd24iOnRydWUsImVuYWJsZV9sZWdhbF9kaXNjbGFpbWVyX3VwZGF0ZXNfYWZmaWxpYXRlX2dhIjp0cnVlLCJlbmFibGVfbWFkaXNvbl9zZWFyY2hfbWlncmF0aW9uIjp0cnVlLCJlbmFibGVfbWFzdGhlYWRfcXVhcnRpbGVfcGluZ19maXgiOnRydWUsImVuYWJsZV9tZW1iZXJzaGlwc19hbmRfcHVyY2hhc2VzIjp0cnVlLCJlbmFibGVfbWVudGlvbnNfaW5fcmVwb3N0cyI6dHJ1ZSwiZW5hYmxlX21pY3JvZm9ybWF0X2RhdGEiOnRydWUsImVuYWJsZV9taW5pX2FwcF9jb250YWluZXIiOnRydWUsImVuYWJsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3MiOnRydWUsImVuYWJsZV9tdWx0aV9pbWFnZV9wb3N0X2NyZWF0aW9uIjp0cnVlLCJlbmFibGVfbmFtZXNfaGFuZGxlc19hY2NvdW50X3N3aXRjaGVyIjp0cnVlLCJlbmFibGVfb2ZmZXJfc3VwcHJlc3Npb24iOnRydWUsImVuYWJsZV9vbl95dF9jb21tYW5kX2V4ZWN1dG9yX2NvbW1hbmRfdG9fbmF2aWdhdGUiOnRydWUsImVuYWJsZV9wYWNmX3Nsb3RfYXNkZV9wbGF5ZXJfYnl0ZV9oNSI6dHJ1ZSwiZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2Ijp0cnVlLCJlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZfZm9yX3BhZ2VfdG9wX2Zvcm1hdHMiOnRydWUsImVuYWJsZV9wYWNmX3Rocm91Z2hfeXNmZV90diI6dHJ1ZSwiZW5hYmxlX3Bhc3Nfc2RjX2dldF9hY2NvdW50c19saXN0Ijp0cnVlLCJlbmFibGVfcGxfcl9jIjp0cnVlLCJlbmFibGVfcG9sbF9jaG9pY2VfYm9yZGVyX29uX3dlYiI6dHJ1ZSwiZW5hYmxlX3BvbHltZXJfcmVzaW4iOnRydWUsImVuYWJsZV9wb2x5bWVyX3Jlc2luX21pZ3JhdGlvbiI6dHJ1ZSwiZW5hYmxlX3Bvc3RfY2N0X2xpbmtzIjp0cnVlLCJlbmFibGVfcG9zdF9zY2hlZHVsaW5nIjp0cnVlLCJlbmFibGVfcHJlbWl1bV92b2x1bnRhcnlfcGF1c2UiOnRydWUsImVuYWJsZV9wcm9ncmFtbWVkX3BsYXlsaXN0X2NvbG9yX3NhbXBsZSI6dHJ1ZSwiZW5hYmxlX3Byb2dyYW1tZWRfcGxheWxpc3RfcmVkZXNpZ24iOnRydWUsImVuYWJsZV9wdXJjaGFzZV9hY3Rpdml0eV9pbl9wYWlkX21lbWJlcnNoaXBzIjp0cnVlLCJlbmFibGVfcXVpel9jcmVhdGlvbiI6dHJ1ZSwiZW5hYmxlX3JlZWxfd2F0Y2hfc2VxdWVuY2UiOnRydWUsImVuYWJsZV9zZWVkbGVzc19zaG9ydHNfdXJsIjp0cnVlLCJlbmFibGVfc2VydmVyX3N0aXRjaGVkX2RhaSI6dHJ1ZSwiZW5hYmxlX3NlcnZpY2VfYWpheF9jc24iOnRydWUsImVuYWJsZV9zZXJ2bGV0X2Vycm9yc19zdHJlYW16Ijp0cnVlLCJlbmFibGVfc2VydmxldF9zdHJlYW16Ijp0cnVlLCJlbmFibGVfc2Z2X2F1ZGlvX3Bpdm90X3VybCI6dHJ1ZSwiZW5hYmxlX3Nob3J0c19zaW5nbGV0b25fY2hhbm5lbF93ZWIiOnRydWUsImVuYWJsZV9zaWduYWxzIjp0cnVlLCJlbmFibGVfc2tpcF9hZF9ndWlkYW5jZV9wcm9tcHQiOnRydWUsImVuYWJsZV9za2lwcGFibGVfYWRzX2Zvcl91bnBsdWdnZWRfYWRfcG9kIjp0cnVlLCJlbmFibGVfc3BhcmtsZXNfd2ViX2NsaWNrYWJsZV9kZXNjcmlwdGlvbiI6dHJ1ZSwiZW5hYmxlX3NxdWlmZmxlX2dpZl9oYW5kbGVzX2xhbmRpbmdfcGFnZSI6dHJ1ZSwiZW5hYmxlX3N0cmVhbWxpbmVfcmVwb3N0X2Zsb3ciOnRydWUsImVuYWJsZV9zdHJ1Y3R1cmVkX2Rlc2NyaXB0aW9uX3Nob3J0c193ZWJfbXdlYiI6dHJ1ZSwiZW5hYmxlX3RlY3RvbmljX2FkX3V4X2Zvcl9oYWxmdGltZSI6dHJ1ZSwiZW5hYmxlX3RoaXJkX3BhcnR5X2luZm8iOnRydWUsImVuYWJsZV90b3Bzb2lsX3d0YV9mb3JfaGFsZnRpbWVfbGl2ZV9pbmZyYSI6dHJ1ZSwiZW5hYmxlX3VuYXZhaWxhYmxlX3ZpZGVvc193YXRjaF9wYWdlIjp0cnVlLCJlbmFibGVfd2F0Y2hfbmV4dF9wYXVzZV9hdXRvcGxheV9sYWN0Ijp0cnVlLCJlbmFibGVfd2ViX2tldGNodXBfaGVyb19hbmltYXRpb24iOnRydWUsImVuYWJsZV93ZWJfcG9zdGVyX2hvdmVyX2FuaW1hdGlvbiI6dHJ1ZSwiZW5hYmxlX3dlYl9zY2hlZHVsZXJfc2lnbmFscyI6dHJ1ZSwiZW5hYmxlX3dlYl9zaG9ydHNfYXVkaW9fcGl2b3QiOnRydWUsImVuYWJsZV93aW5kb3dfY29uc3RyYWluZWRfYnV5X2Zsb3dfZGlhbG9nIjp0cnVlLCJlbmFibGVfeW9vZGxlIjp0cnVlLCJlbmFibGVfeXBjX3NwaW5uZXJzIjp0cnVlLCJlbmFibGVfeXRfYXRhX2lmcmFtZV9hdXRodXNlciI6dHJ1ZSwiZW5hYmxlX3l0Y19yZWZ1bmRzX3N1Ym1pdF9mb3JtX3NpZ25hbF9hY3Rpb24iOnRydWUsImVuYWJsZV95dGNfc2VsZl9zZXJ2ZV9yZWZ1bmRzIjp0cnVlLCJlbmRwb2ludF9oYW5kbGVyX2xvZ2dpbmdfY2xlYW51cF9raWxsc3dpdGNoIjp0cnVlLCJleHBvcnRfbmV0d29ya2xlc3Nfb3B0aW9ucyI6dHJ1ZSwiZXh0ZXJuYWxfZnVsbHNjcmVlbiI6dHJ1ZSwiZXh0ZXJuYWxfZnVsbHNjcmVlbl93aXRoX2VkdSI6dHJ1ZSwiZmlsbF9zaW5nbGVfdmlkZW9fd2l0aF9ub3RpZnlfdG9fbGFzciI6dHJ1ZSwiZml4X3NjcnViYmVyX292ZXJsYXlfdHJhbnNpdGlvbiI6dHJ1ZSwiZ2NmX2NvbmZpZ19zdG9yZV9lbmFibGVkIjp0cnVlLCJnZGFfZW5hYmxlX3BsYXlsaXN0X2Rvd25sb2FkIjp0cnVlLCJnbG9iYWxfc3BhY2ViYXJfcGF1c2UiOnRydWUsImdwYV9zcGFya2xlc190ZW5fcGVyY2VudF9sYXllciI6dHJ1ZSwiaDVfY29tcGFuaW9uX2VuYWJsZV9hZGNwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzIjp0cnVlLCJoNV9lbmFibGVfZ2VuZXJpY19lcnJvcl9sb2dnaW5nX2V2ZW50Ijp0cnVlLCJoNV9pbnBsYXllcl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5ncyI6dHJ1ZSwiaDVfcmVzZXRfY2FjaGVfYW5kX2ZpbHRlcl9iZWZvcmVfdXBkYXRlX21hc3RoZWFkIjp0cnVlLCJoYW5kbGVzX2luX21lbnRpb25fc3VnZ2VzdF9wb3N0cyI6dHJ1ZSwiaGlkZV9lbmRwb2ludF9vdmVyZmxvd19vbl95dGRfZGlzcGxheV9hZF9yZW5kZXJlciI6dHJ1ZSwiaHRtbDVfZW5hYmxlX2Fkc19jbGllbnRfbW9uaXRvcmluZ19sb2dfdHYiOnRydWUsImh0bWw1X2VuYWJsZV9zaW5nbGVfdmlkZW9fdm9kX2l2YXJfb25fcGFjZiI6dHJ1ZSwiaHRtbDVfbG9nX3RyaWdnZXJfZXZlbnRzX3dpdGhfZGVidWdfZGF0YSI6dHJ1ZSwiaHRtbDVfcmVjb2duaXplX3ByZWRpY3Rfc3RhcnRfY3VlX3BvaW50Ijp0cnVlLCJodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2dyb3VwIjp0cnVlLCJodG1sNV93ZWJfZW5hYmxlX2hhbGZ0aW1lX3ByZXJvbGwiOnRydWUsImlsX3VzZV92aWV3X21vZGVsX2xvZ2dpbmdfY29udGV4dCI6dHJ1ZSwiaW5jbHVkZV9hdXRvcGxheV9jb3VudF9pbl9wbGF5bGlzdHMiOnRydWUsImlzX3BhcnRfb2ZfYW55X3VzZXJfZW5nYWdlbWVudF9leHBlcmltZW50Ijp0cnVlLCJqc29uX2NvbmRlbnNlZF9yZXNwb25zZSI6dHJ1ZSwia2V2bGFyX2FwcF9zaG9ydGN1dHMiOnRydWUsImtldmxhcl9hcHBiZWhhdmlvcl9hdHRhY2hfc3RhcnR1cF90YXNrcyI6dHJ1ZSwia2V2bGFyX2FwcGVuZF90b2dnbGVkX2VuZ2FnZW1lbnRfcGFuZWxzX3RvcCI6dHJ1ZSwia2V2bGFyX2F1dG9mb2N1c19tZW51X29uX2tleWJvYXJkX25hdiI6dHJ1ZSwia2V2bGFyX2F1dG9uYXZfcG9wdXBfZmlsdGVyaW5nIjp0cnVlLCJrZXZsYXJfYXZfZWxpbWluYXRlX3BvbGxpbmciOnRydWUsImtldmxhcl9iYWNrZ3JvdW5kX2NvbG9yX3VwZGF0ZSI6dHJ1ZSwia2V2bGFyX2NhY2hlX2NvbGRfbG9hZF9yZXNwb25zZSI6dHJ1ZSwia2V2bGFyX2NhY2hlX29uX3R0bF9wbGF5ZXIiOnRydWUsImtldmxhcl9jYWNoZV9vbl90dGxfc2VhcmNoIjp0cnVlLCJrZXZsYXJfY2FsY3VsYXRlX2dyaWRfY29sbGFwc2libGUiOnRydWUsImtldmxhcl9jYW5jZWxfc2NoZWR1bGVkX2NvbW1lbnRfam9ic19vbl9uYXZpZ2F0ZSI6dHJ1ZSwia2V2bGFyX2NlbnRlcl9zZWFyY2hfcmVzdWx0cyI6dHJ1ZSwia2V2bGFyX2NoYW5uZWxfY3JlYXRpb25fZm9ybV9yZXNvbHZlciI6dHJ1ZSwia2V2bGFyX2NoYW5uZWxfdHJhaWxlcl9tdWx0aV9hdHRhY2giOnRydWUsImtldmxhcl9jaGFwdGVyc19saXN0X3ZpZXdfc2Vla19ieV9jaGFwdGVyIjp0cnVlLCJrZXZsYXJfY2xlYXJfZHVwbGljYXRlX3ByZWZfY29va2llIjp0cnVlLCJrZXZsYXJfY2xlYXJfbm9uX2Rpc3BsYXlhYmxlX3VybF9wYXJhbXMiOnRydWUsImtldmxhcl9jbGllbnRfc2lkZV9zY3JlZW5zIjp0cnVlLCJrZXZsYXJfY29tbWFuZF9oYW5kbGVyIjp0cnVlLCJrZXZsYXJfY29tbWFuZF9oYW5kbGVyX2NsaWNrcyI6dHJ1ZSwia2V2bGFyX2NvbW1hbmRfaGFuZGxlcl9mb3JtYXR0ZWRfc3RyaW5nIjp0cnVlLCJrZXZsYXJfY29tbWFuZF91cmwiOnRydWUsImtldmxhcl9jb250aW51ZV9wbGF5YmFja193aXRob3V0X3BsYXllcl9yZXNwb25zZSI6dHJ1ZSwia2V2bGFyX2RlY29yYXRlX2VuZHBvaW50X3dpdGhfb25lc2llX2NvbmZpZyI6dHJ1ZSwia2V2bGFyX2RlbGF5X3dhdGNoX2luaXRpYWxfZGF0YSI6dHJ1ZSwia2V2bGFyX2Rpc2FibGVfYmFja2dyb3VuZF9wcmVmZXRjaCI6dHJ1ZSwia2V2bGFyX2Rpc2FibGVfcGVuZGluZ19jb21tYW5kIjp0cnVlLCJrZXZsYXJfZHJhZ2Ryb3BfZmFzdF9zY3JvbGwiOnRydWUsImtldmxhcl9kcm9wZG93bl9maXgiOnRydWUsImtldmxhcl9kcm9wcGFibGVfcHJlZmV0Y2hhYmxlX3JlcXVlc3RzIjp0cnVlLCJrZXZsYXJfZWFybHlfcG9wdXBfY2xvc2UiOnRydWUsImtldmxhcl9lbmFibGVfZWRpdGFibGVfcGxheWxpc3RzIjp0cnVlLCJrZXZsYXJfZW5hYmxlX2VtX29mZmxpbmVhYmxlX2Rpc2NvdmVyeSI6dHJ1ZSwia2V2bGFyX2VuYWJsZV9yZW9yZGVyYWJsZV9wbGF5bGlzdHMiOnRydWUsImtldmxhcl9lbmFibGVfc2hvcnRzX3ByZWZldGNoX2luX3NlcXVlbmNlIjp0cnVlLCJrZXZsYXJfZW5hYmxlX3Nob3J0c19yZXNwb25zZV9jaHVua2luZyI6dHJ1ZSwia2V2bGFyX2VuYWJsZV91cF9hcnJvdyI6dHJ1ZSwia2V2bGFyX2VuYWJsZV91cHNlbGxfb25fdmlkZW9fbWVudSI6dHJ1ZSwia2V2bGFyX2VuYWJsZV95YnBfb3BfZm9yX3Nob3B0dWJlIjp0cnVlLCJrZXZsYXJfZXhpdF9mdWxsc2NyZWVuX2xlYXZpbmdfd2F0Y2giOnRydWUsImtldmxhcl9maWxsX29mZmxpbmVfYXZhaWxhYmlsaXR5X3R5cGVfZm9yX2dkYSI6dHJ1ZSwia2V2bGFyX2ZpeF9wbGF5bGlzdF9jb250aW51YXRpb24iOnRydWUsImtldmxhcl9mbGV4aWJsZV9tZW51Ijp0cnVlLCJrZXZsYXJfZmx1aWRfdG91Y2hfc2Nyb2xsIjp0cnVlLCJrZXZsYXJfZnJvbnRlbmRfcXVldWVfcmVjb3ZlciI6dHJ1ZSwia2V2bGFyX2dlbF9lcnJvcl9yb3V0aW5nIjp0cnVlLCJrZXZsYXJfZ3VpZGVfcmVmcmVzaCI6dHJ1ZSwia2V2bGFyX2hlbHBfdXNlX2xvY2FsZSI6dHJ1ZSwia2V2bGFyX2hpZGVfcGxheWxpc3RfcGxheWJhY2tfc3RhdHVzIjp0cnVlLCJrZXZsYXJfaGlkZV9wcF91cmxfcGFyYW0iOnRydWUsImtldmxhcl9oaWRlX3RpbWVfY29udGludWVfdXJsX3BhcmFtIjp0cnVlLCJrZXZsYXJfaG9tZV9za2VsZXRvbiI6dHJ1ZSwia2V2bGFyX2hvbWVfc2tlbGV0b25faGlkZV9sYXRlciI6dHJ1ZSwia2V2bGFyX2pzX2ZpeGVzIjp0cnVlLCJrZXZsYXJfa2V5Ym9hcmRfYnV0dG9uX2ZvY3VzIjp0cnVlLCJrZXZsYXJfbGFyZ2VyX3RocmVlX2RvdF90YXAiOnRydWUsImtldmxhcl9sYXp5X2xpc3RfcmVzdW1lX2Zvcl9hdXRvZmlsbCI6dHJ1ZSwia2V2bGFyX2xlZ2FjeV9icm93c2VycyI6dHJ1ZSwia2V2bGFyX2xvY2FsX2lubmVydHViZV9yZXNwb25zZSI6dHJ1ZSwia2V2bGFyX21hY3JvX21hcmtlcnNfa2V5Ym9hcmRfc2hvcnRjdXQiOnRydWUsImtldmxhcl9tYXN0aGVhZF9zdG9yZSI6dHJ1ZSwia2V2bGFyX21lYWxiYXJfYWJvdmVfcGxheWVyIjp0cnVlLCJrZXZsYXJfbWluaXBsYXllciI6dHJ1ZSwia2V2bGFyX21pbmlwbGF5ZXJfZXhwYW5kX3RvcCI6dHJ1ZSwia2V2bGFyX21pbmlwbGF5ZXJfcGxheV9wYXVzZV9vbl9zY3JpbSI6dHJ1ZSwia2V2bGFyX21pbmlwbGF5ZXJfcXVldWVfdXNlcl9hY3RpdmF0aW9uIjp0cnVlLCJrZXZsYXJfbWl4X2hhbmRsZV9maXJzdF9lbmRwb2ludF9kaWZmZXJlbnQiOnRydWUsImtldmxhcl9tb2Rlcm5fc2QiOnRydWUsImtldmxhcl9uZXh0X2NvbGRfb25fYXV0aF9jaGFuZ2VfZGV0ZWN0ZWQiOnRydWUsImtldmxhcl9uaXRyYXRlX2RyaXZlbl90b29sdGlwcyI6dHJ1ZSwia2V2bGFyX25vX2F1dG9zY3JvbGxfb25fcGxheWxpc3RfaG92ZXIiOnRydWUsImtldmxhcl9vcF9pbmZyYSI6dHJ1ZSwia2V2bGFyX29wX3dhcm1fcGFnZXMiOnRydWUsImtldmxhcl9wYW5kb3duX3BvbHlmaWxsIjp0cnVlLCJrZXZsYXJfcGFzc2l2ZV9ldmVudF9saXN0ZW5lcnMiOnRydWUsImtldmxhcl9wbGF5YmFja19hc3NvY2lhdGVkX3F1ZXVlIjp0cnVlLCJrZXZsYXJfcGxheWVyX2NhY2hlZF9sb2FkX2NvbmZpZyI6dHJ1ZSwia2V2bGFyX3BsYXllcl9jaGVja19hZF9zdGF0ZV9vbl9zdG9wIjp0cnVlLCJrZXZsYXJfcGxheWVyX2xvYWRfcGxheWVyX25vX29wIjp0cnVlLCJrZXZsYXJfcGxheWVyX25ld19ib290c3RyYXBfYWRvcHRpb24iOnRydWUsImtldmxhcl9wbGF5ZXJfcGxheWxpc3RfdXNlX2xvY2FsX2luZGV4Ijp0cnVlLCJrZXZsYXJfcGxheWVyX3dhdGNoX2VuZHBvaW50X25hdmlnYXRpb24iOnRydWUsImtldmxhcl9wbGF5bGlzdF9kcmFnX2hhbmRsZXMiOnRydWUsImtldmxhcl9wbGF5bGlzdF91c2VfeF9jbG9zZV9idXR0b24iOnRydWUsImtldmxhcl9wcmVmZXRjaCI6dHJ1ZSwia2V2bGFyX3ByZXZlbnRfcG9seW1lcl9keW5hbWljX2ZvbnRfbG9hZCI6dHJ1ZSwia2V2bGFyX3F1ZXVlX3VzZV91cGRhdGVfYXBpIjp0cnVlLCJrZXZsYXJfcmVmcmVzaF9nZXN0dXJlIjp0cnVlLCJrZXZsYXJfcmVmcmVzaF9vbl90aGVtZV9jaGFuZ2UiOnRydWUsImtldmxhcl9yZW5kZXJlcnN0YW1wZXJfZXZlbnRfbGlzdGVuZXIiOnRydWUsImtldmxhcl9yZXBsYWNlX3Nob3J0X3RvX3Nob3J0X2hpc3Rvcnlfc3RhdGUiOnRydWUsImtldmxhcl9yZXF1ZXN0X3NlcXVlbmNpbmciOnRydWUsImtldmxhcl9yZXNvbHZlX2NvbW1hbmRfZm9yX2NvbmZpcm1fZGlhbG9nIjp0cnVlLCJrZXZsYXJfcmVzb2x2ZV9wbGF5bGlzdF9lbmRwb2ludF9hc193YXRjaF9lbmRwb2ludCI6dHJ1ZSwia2V2bGFyX3Jlc3BvbnNlX2NvbW1hbmRfcHJvY2Vzc29yX3BhZ2UiOnRydWUsImtldmxhcl9zY3JvbGxfY2hpcHNfb25fdG91Y2giOnRydWUsImtldmxhcl9zY3JvbGxiYXJfcmV3b3JrIjp0cnVlLCJrZXZsYXJfc2VydmljZV9jb21tYW5kX2NoZWNrIjp0cnVlLCJrZXZsYXJfc2V0X2ludGVybmFsX3BsYXllcl9zaXplIjp0cnVlLCJrZXZsYXJfc2hlbGxfZm9yX2Rvd25sb2Fkc19wYWdlIjp0cnVlLCJrZXZsYXJfc2hvdWxkX21haW50YWluX3N0YWJsZV9saXN0Ijp0cnVlLCJrZXZsYXJfc2hvd19lbV9kbF9idG4iOnRydWUsImtldmxhcl9zaG93X2VtX2RsX21lbnVfaXRlbSI6dHJ1ZSwia2V2bGFyX3Nob3dfZW1fZGxfc2V0dGluZ3NfdGFiIjp0cnVlLCJrZXZsYXJfc2hvd19wbGF5bGlzdF9kbF9idG4iOnRydWUsImtldmxhcl9zaW1wX3Nob3J0c19yZXNldF9zY3JvbGwiOnRydWUsImtldmxhcl9zbWFydF9kb3dubG9hZHMiOnRydWUsImtldmxhcl9zbWFydF9kb3dubG9hZHNfc2V0dGluZyI6dHJ1ZSwia2V2bGFyX3N0YXJ0dXBfbGlmZWN5Y2xlIjp0cnVlLCJrZXZsYXJfc3RydWN0dXJlZF9kZXNjcmlwdGlvbl9jb250ZW50X2lubGluZSI6dHJ1ZSwia2V2bGFyX3N5c3RlbV9pY29ucyI6dHJ1ZSwia2V2bGFyX3RhYnNfZ2VzdHVyZSI6dHJ1ZSwia2V2bGFyX3RleHRfaW5saW5lX2V4cGFuZGVyX2Zvcm1hdHRlZF9zbmlwcGV0Ijp0cnVlLCJrZXZsYXJfdGhyZWVfZG90X2luayI6dHJ1ZSwia2V2bGFyX3RodW1ibmFpbF9mbHVpZCI6dHJ1ZSwia2V2bGFyX3RvYXN0X21hbmFnZXIiOnRydWUsImtldmxhcl90b3BiYXJfbG9nb19mYWxsYmFja19ob21lIjp0cnVlLCJrZXZsYXJfdG91Y2hfZmVlZGJhY2siOnRydWUsImtldmxhcl90b3VjaF9mZWVkYmFja19sb2NrdXBzIjp0cnVlLCJrZXZsYXJfdG91Y2hfZ2VzdHVyZV92ZXMiOnRydWUsImtldmxhcl90cmFuc2NyaXB0X2VuZ2FnZW1lbnRfcGFuZWwiOnRydWUsImtldmxhcl90dW5lcl9ydW5fZGVmYXVsdF9jb21tZW50c19kZWxheSI6dHJ1ZSwia2V2bGFyX3R1bmVyX3Nob3VsZF9kZWZlcl9kZXRhY2giOnRydWUsImtldmxhcl90eXBvZ3JhcGh5X3NwYWNpbmdfdXBkYXRlIjp0cnVlLCJrZXZsYXJfdHlwb2dyYXBoeV91cGRhdGUiOnRydWUsImtldmxhcl91bmF2YWlsYWJsZV92aWRlb19lcnJvcl91aV9jbGllbnQiOnRydWUsImtldmxhcl91bmlmaWVkX2Vycm9yc19pbml0Ijp0cnVlLCJrZXZsYXJfdXNlX3Jlc3BvbnNlX3R0bF90b19pbnZhbGlkYXRlX2NhY2hlIjp0cnVlLCJrZXZsYXJfdXNlX3ZpbWlvX2JlaGF2aW9yIjp0cnVlLCJrZXZsYXJfdXNlX3dpbF9pY29ucyI6dHJ1ZSwia2V2bGFyX3VzZV95dGRfcGxheWVyIjp0cnVlLCJrZXZsYXJfdmFyaWFibGVfeW91dHViZV9zYW5zIjp0cnVlLCJrZXZsYXJfdmltaW9fdXNlX3NoYXJlZF9tb25pdG9yIjp0cnVlLCJrZXZsYXJfdm9pY2VfbG9nZ2luZ19maXgiOnRydWUsImtldmxhcl92b2ljZV9zZWFyY2giOnRydWUsImtldmxhcl93YXRjaF9jaW5lbWF0aWNzIjp0cnVlLCJrZXZsYXJfd2F0Y2hfY29sb3JfdXBkYXRlIjp0cnVlLCJrZXZsYXJfd2F0Y2hfY29tbWVudHNfZXBfZGlzYWJsZV90aGVhdGVyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfY29udGVudHNfZGF0YV9wcm92aWRlciI6dHJ1ZSwia2V2bGFyX3dhdGNoX2NvbnRlbnRzX2RhdGFfcHJvdmlkZXJfcGVyc2lzdGVudCI6dHJ1ZSwia2V2bGFyX3dhdGNoX2Rpc2FibGVfbGVnYWN5X21ldGFkYXRhX3VwZGF0ZXMiOnRydWUsImtldmxhcl93YXRjaF9kcmFnX2hhbmRsZXMiOnRydWUsImtldmxhcl93YXRjaF9mbGV4eV9mdWxsc2NyZWVuX21hbmFnZXIiOnRydWUsImtldmxhcl93YXRjaF9mbGV4eV9sb2FkaW5nX3N0YXRlX21hbmFnZXIiOnRydWUsImtldmxhcl93YXRjaF9mbGV4eV9taW5pcGxheWVyX21hbmFnZXIiOnRydWUsImtldmxhcl93YXRjaF9mbGV4eV9uYXZpZ2F0aW9uX21hbmFnZXIiOnRydWUsImtldmxhcl93YXRjaF9mbGV4eV9wbGF5ZXJfbG9vcF9tYW5hZ2VyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfZmxleHlfc2Nyb2xsX21hbmFnZXIiOnRydWUsImtldmxhcl93YXRjaF9mbGV4eV90aXRsZV9tYW5hZ2VyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfZmxleHlfdXNlX2NvbnRyb2xsZXIiOnRydWUsImtldmxhcl93YXRjaF9mb2N1c19vbl9lbmdhZ2VtZW50X3BhbmVscyI6dHJ1ZSwia2V2bGFyX3dhdGNoX2dlc3R1cmVfcGFuZG93biI6dHJ1ZSwia2V2bGFyX3dhdGNoX2hpZGVfY29tbWVudHNfdGVhc2VyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfaGlkZV9jb21tZW50c193aGlsZV9wYW5lbF9vcGVuIjp0cnVlLCJrZXZsYXJfd2F0Y2hfanNfcGFuZWxfaGVpZ2h0Ijp0cnVlLCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaCI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2hfYXR0YWNoZWRfc3Vic2NyaWJlIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF9jbGlja2FibGVfZGVzY3JpcHRpb24iOnRydWUsImtldmxhcl93YXRjaF9tZXRhZGF0YV9yZWZyZXNoX2NvbXBhY3Rfdmlld19jb3VudCI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2hfZGVzY3JpcHRpb25faW5mb19kZWRpY2F0ZWRfbGluZSI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2hfZGVzY3JpcHRpb25faW5saW5lX2V4cGFuZGVyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF9kZXNjcmlwdGlvbl9wcmltYXJ5X2NvbG9yIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF9mb3JfbGl2ZV9raWxsc3dpdGNoIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF9mdWxsX3dpZHRoX2Rlc2NyaXB0aW9uIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF9sZWZ0X2FsaWduZWRfdmlkZW9fYWN0aW9ucyI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2hfbG93ZXJfY2FzZV92aWRlb19hY3Rpb25zIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF9uYXJyb3dlcl9pdGVtX3dyYXAiOnRydWUsImtldmxhcl93YXRjaF9tZXRhZGF0YV9yZWZyZXNoX3JlbGF0aXZlX2RhdGUiOnRydWUsImtldmxhcl93YXRjaF9tZXRhZGF0YV9yZWZyZXNoX3RvcF9hbGlnbmVkX2FjdGlvbnMiOnRydWUsImtldmxhcl93YXRjaF9tb2Rlcm5fbWV0YXBhbmVsIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbW9kZXJuX3BhbmVscyI6dHJ1ZSwia2V2bGFyX3dhdGNoX3BhbmVsX2hlaWdodF9tYXRjaGVzX3BsYXllciI6dHJ1ZSwia2V2bGFyX3dvZmZsZV9mYWxsYmFja19pbWFnZSI6dHJ1ZSwia2V2bGFyX3l0Yl9saXZlX2JhZGdlcyI6dHJ1ZSwia2lsbHN3aXRjaF90b2dnbGVfYnV0dG9uX2JlaGF2aW9yX3Jlc29sdmVfY29tbWFuZCI6dHJ1ZSwibGl2ZV9jaGF0X2Jhbm5lcl9leHBhbnNpb25fZml4Ijp0cnVlLCJsaXZlX2NoYXRfZW5hYmxlX21vZF92aWV3Ijp0cnVlLCJsaXZlX2NoYXRfZW5hYmxlX3FuYV9iYW5uZXJfb3ZlcmZsb3dfbWVudV9hY3Rpb25zIjp0cnVlLCJsaXZlX2NoYXRfZW5hYmxlX3FuYV9jaGFubmVsIjp0cnVlLCJsaXZlX2NoYXRfZmlsdGVyX2Vtb2ppX3N1Z2dlc3Rpb25zIjp0cnVlLCJsaXZlX2NoYXRfaW5jcmVhc2VkX21pbl9oZWlnaHQiOnRydWUsImxpdmVfY2hhdF9vdmVyX3BsYXlsaXN0Ijp0cnVlLCJsaXZlX2NoYXRfd2ViX2VuYWJsZV9jb21tYW5kX2hhbmRsZXIiOnRydWUsImxpdmVfY2hhdF93ZWJfdXNlX2Vtb2ppX21hbmFnZXJfc2luZ2xldG9uIjp0cnVlLCJsb2dfZXJyb3JzX3Rocm91Z2hfbndsX29uX3JldHJ5Ijp0cnVlLCJsb2dfZ2VsX2NvbXByZXNzaW9uX2xhdGVuY3kiOnRydWUsImxvZ19oZWFydGJlYXRfd2l0aF9saWZlY3ljbGVzIjp0cnVlLCJsb2dfdmlzX29uX3RhYl9jaGFuZ2UiOnRydWUsImxvZ193ZWJfZW5kcG9pbnRfdG9fbGF5ZXIiOnRydWUsIm1keF9lbmFibGVfcHJpdmFjeV9kaXNjbG9zdXJlX3VpIjp0cnVlLCJtZHhfbG9hZF9jYXN0X2FwaV9ib290c3RyYXBfc2NyaXB0Ijp0cnVlLCJtaWdyYXRlX2V2ZW50c190b190cyI6dHJ1ZSwibXVzaWNfb25fbWFpbl9oYW5kbGVfcGxheWxpc3RfZWRpdF92aWRlb19hZGRlZF9yZXN1bHRfZGF0YSI6dHJ1ZSwibXVzaWNfb25fbWFpbl9vcGVuX3BsYXlsaXN0X3JlY29tbWVuZGVkX3ZpZGVvc19pbl9taW5pcGxheWVyIjp0cnVlLCJtd2ViX2FjdGlvbnNfY29tbWFuZF9oYW5kbGVyIjp0cnVlLCJtd2ViX2NvbW1hbmRfaGFuZGxlciI6dHJ1ZSwibXdlYl9kaXNhYmxlX3NldF9hdXRvbmF2X3N0YXRlX2luX3BsYXllciI6dHJ1ZSwibXdlYl9lbmFibGVfY29uc2lzdGVuY3lfc2VydmljZSI6dHJ1ZSwibXdlYl9lbmFibGVfaGxwIjp0cnVlLCJtd2ViX2xvZ29fdXNlX2hvbWVfcGFnZV92ZSI6dHJ1ZSwibXdlYl9yZW5kZXJfY3Jhd2xlcl9kZXNjcmlwdGlvbiI6dHJ1ZSwibXdlYl9zdG9wX3RydW5jYXRpbmdfbWV0YV90YWdzIjp0cnVlLCJtd2ViX3VzZV9kZXNrdG9wX2Nhbm9uaWNhbF91cmwiOnRydWUsIm13ZWJfdXNlX2VuZHBvaW50X21lbnVfaXRlbSI6dHJ1ZSwibmV0d29ya2xlc3NfZ2VsIjp0cnVlLCJuZXR3b3JrbGVzc19sb2dnaW5nIjp0cnVlLCJub19zdWJfY291bnRfb25fc3ViX2J1dHRvbiI6dHJ1ZSwibndsX3NlbmRfZmFzdF9vbl91bmxvYWQiOnRydWUsIm53bF9zZW5kX2Zyb21fbWVtb3J5X3doZW5fb25saW5lIjp0cnVlLCJvZmZsaW5lX2Vycm9yX2hhbmRsaW5nIjp0cnVlLCJwYWdlaWRfYXNfaGVhZGVyX3dlYiI6dHJ1ZSwicGF1c2VfYWRfdmlkZW9fb25fZGVza3RvcF9lbmdhZ2VtZW50X3BhbmVsX2NsaWNrIjp0cnVlLCJwZGdfZW5hYmxlX2Zsb3dfbG9nZ2luZ19mb3Jfc3VwZXJfY2hhdCI6dHJ1ZSwicGRnX2VuYWJsZV9mbG93X2xvZ2dpbmdfZm9yX3N1cGVyX3N0aWNrZXJzIjp0cnVlLCJwbGF5ZXJfYWxsb3dfYXV0b25hdl9hZnRlcl9wbGF5bGlzdCI6dHJ1ZSwicGxheWVyX2Jvb3RzdHJhcF9tZXRob2QiOnRydWUsInBsYXllcl9kb3VibGV0YXBfdG9fc2VlayI6dHJ1ZSwicGxheWVyX2VuYWJsZV9wbGF5YmFja19wbGF5bGlzdF9jaGFuZ2UiOnRydWUsInBsYXllcl9lbmRzY3JlZW5fZWxsaXBzaXNfZml4Ijp0cnVlLCJwb2x5bWVyMl9ub3Rfc2hhZHlfYnVpbGQiOnRydWUsInBvbHltZXJfYmFkX2J1aWxkX2xhYmVscyI6dHJ1ZSwicG9seW1lcl90YXNrX21hbmFnZXJfcHJveGllZF9wcm9taXNlIjp0cnVlLCJwb2x5bWVyX3ZlcmlmaXlfYXBwX3N0YXRlIjp0cnVlLCJwb2x5bWVyX3ZpZGVvX3JlbmRlcmVyX2RlZmVyX21lbnUiOnRydWUsInBvbHltZXJfeXRkaV9lbmFibGVfZ2xvYmFsX2luamVjdG9yIjp0cnVlLCJwcm9ibGVtX3dhbGt0aHJvdWdoX3NkIjp0cnVlLCJxb2Vfc2VuZF9hbmRfd3JpdGUiOnRydWUsInJlY29yZF9hcHBfY3Jhc2hlZF93ZWIiOnRydWUsInJlbG9hZF93aXRob3V0X3BvbHltZXJfaW5uZXJ0dWJlIjp0cnVlLCJyZW1vdmVfd2ViX2NvbW1lbnRfaWRfY2FjaGUiOnRydWUsInJlbW92ZV95dF9zaW1wbGVfZW5kcG9pbnRfZnJvbV9kZXNrdG9wX2Rpc3BsYXlfYWRfdGl0bGUiOnRydWUsInJpY2hfZ3JpZF9yZXNpemVfb2JzZXJ2ZXIiOnRydWUsInJpY2hfZ3JpZF9yZXNpemVfb2JzZXJ2ZXJfb25seSI6dHJ1ZSwicmljaF9ncmlkX3dhdGNoX2Rpc2FibGVfbWluaXBsYXllciI6dHJ1ZSwicmljaF9ncmlkX3dhdGNoX2hpZGVfcm93c19hYm92ZSI6dHJ1ZSwicmljaF9ncmlkX3dhdGNoX21ldGFfc2lkZSI6dHJ1ZSwic2NoZWR1bGVyX3VzZV9yYWZfYnlfZGVmYXVsdCI6dHJ1ZSwic2VhcmNoX3VpX2VuYWJsZV9wdmVfYnV5X2J1dHRvbiI6dHJ1ZSwic2VhcmNoX3VpX29mZmljaWFsX2NhcmRzX2VuYWJsZV9wYWlkX3ZpcnR1YWxfZXZlbnRfYnV5X2J1dHRvbiI6dHJ1ZSwic2VhcmNoYm94X3JlcG9ydGluZyI6dHJ1ZSwic2VydmVfcGRwX2F0X2Nhbm9uaWNhbF91cmwiOnRydWUsInNlcnZpY2Vfd29ya2VyX2VuYWJsZWQiOnRydWUsInNlcnZpY2Vfd29ya2VyX3B1c2hfZW5hYmxlZCI6dHJ1ZSwic2VydmljZV93b3JrZXJfcHVzaF9ob21lX3BhZ2VfcHJvbXB0Ijp0cnVlLCJzZXJ2aWNlX3dvcmtlcl9wdXNoX3dhdGNoX3BhZ2VfcHJvbXB0Ijp0cnVlLCJzZXJ2aWNlX3dvcmtlcl9zdWJzY3JpYmVfd2l0aF92YXBpZF9rZXkiOnRydWUsInNob3J0c19kZXNrdG9wX3dhdGNoX3doaWxlX3AyIjp0cnVlLCJzaG9ydHNfZW5hYmxlX3NuYXBfc3RvcCI6dHJ1ZSwic2hvcnRzX2lubGluZV9wbGF5YmFja19kaXNhYmxlX3BvcG91dCI6dHJ1ZSwic2hvcnRzX3Byb2ZpbGVfaGVhZGVyX2MzcG8iOnRydWUsInNob3VsZF9jbGVhcl92aWRlb19kYXRhX29uX3BsYXllcl9jdWVkX3Vuc3RhcnRlZCI6dHJ1ZSwic2hvd19jaXZfcmVtaW5kZXJfb25fd2ViIjp0cnVlLCJza2lwX2ludmFsaWRfeXRjc2lfdGlja3MiOnRydWUsInNraXBfbHNfZ2VsX3JldHJ5Ijp0cnVlLCJza2lwX3NldHRpbmdfaW5mb19pbl9jc2lfZGF0YV9vYmplY3QiOnRydWUsInNwb25zb3JzaGlwc19naWZ0aW5nX2VuYWJsZV9vcHRfaW4iOnRydWUsInN0YXJ0X2NsaWVudF9nY2YiOnRydWUsInN0YXJ0X2NsaWVudF9nY2ZfZm9yX3BsYXllciI6dHJ1ZSwic3RhcnRfc2VuZGluZ19jb25maWdfaGFzaCI6dHJ1ZSwic3VwZXJfc3RpY2tlcl9lbW9qaV9waWNrZXJfY2F0ZWdvcnlfYnV0dG9uX2ljb25fZmlsbGVkIjp0cnVlLCJzdXBwcmVzc19lcnJvcl8yMDRfbG9nZ2luZyI6dHJ1ZSwidHJhbnNwb3J0X3VzZV9zY2hlZHVsZXIiOnRydWUsInVwZGF0ZV9sb2dfZXZlbnRfY29uZmlnIjp0cnVlLCJ1c2VfYWRzX2VuZ2FnZW1lbnRfcGFuZWxfZGVza3RvcF9mb290ZXJfY3RhIjp0cnVlLCJ1c2VfYmV0dGVyX3Bvc3RfZGlzbWlzc2FscyI6dHJ1ZSwidXNlX2JvcmRlcl9hbmRfZ3JpZF93cmFwcGluZ19vbl9kZXNrdG9wX3BhbmVsX3RpbGVzIjp0cnVlLCJ1c2VfY29yZV9zbSI6dHJ1ZSwidXNlX25ld19jbWwiOnRydWUsInVzZV9uZXdfaW5fbWVtb3J5X3N0b3JhZ2UiOnRydWUsInVzZV9uZXdfbndsX2luaXRpYWxpemF0aW9uIjp0cnVlLCJ1c2VfbmV3X253bF9zYXciOnRydWUsInVzZV9uZXdfbndsX3N0dyI6dHJ1ZSwidXNlX25ld19ud2xfd3RzIjp0cnVlLCJ1c2VfcGxheWVyX2FidXNlX2JnX2xpYnJhcnkiOnRydWUsInVzZV9wcm9maWxlcGFnZV9ldmVudF9sYWJlbF9pbl9jYXJvdXNlbF9wbGF5YmFja3MiOnRydWUsInVzZV9yZXF1ZXN0X3RpbWVfbXNfaGVhZGVyIjp0cnVlLCJ1c2Vfc2Vzc2lvbl9iYXNlZF9zYW1wbGluZyI6dHJ1ZSwidXNlX3NvdXJjZV9lbGVtZW50X2lmX3ByZXNlbnRfZm9yX2FjdGlvbnMiOnRydWUsInVzZV90c192aXNpYmlsaXR5bG9nZ2VyIjp0cnVlLCJ1c2Vfd2F0Y2hfZnJhZ21lbnRzMiI6dHJ1ZSwidmVyaWZ5X2Fkc19pdGFnX2Vhcmx5Ijp0cnVlLCJ2c3NfZmluYWxfcGluZ19zZW5kX2FuZF93cml0ZSI6dHJ1ZSwidnNzX3BsYXliYWNrX3VzZV9zZW5kX2FuZF93cml0ZSI6dHJ1ZSwid2FybV9sb2FkX25hdl9zdGFydF93ZWIiOnRydWUsIndhcm1fb3BfY3NuX2NsZWFudXAiOnRydWUsIndlYl9hbHdheXNfbG9hZF9jaGF0X3N1cHBvcnQiOnRydWUsIndlYl9hbXN0ZXJkYW1fcGxheWxpc3RzIjp0cnVlLCJ3ZWJfYW1zdGVyZGFtX3Bvc3RfbXZwX3BsYXlsaXN0cyI6dHJ1ZSwid2ViX2FuaW1hdGVkX2xpa2UiOnRydWUsIndlYl9hbmltYXRlZF9saWtlX2xhenlfbG9hZCI6dHJ1ZSwid2ViX2FwaV91cmwiOnRydWUsIndlYl9hdXRvbmF2X2FsbG93X29mZl9ieV9kZWZhdWx0Ijp0cnVlLCJ3ZWJfYnV0dG9uX3Jld29yayI6dHJ1ZSwid2ViX2NpbmVtYXRpY19tYXN0aGVhZCI6dHJ1ZSwid2ViX2Rhcmtlcl9kYXJrX3RoZW1lIjp0cnVlLCJ3ZWJfZGFya2VyX2RhcmtfdGhlbWVfZGVwcmVjYXRlIjp0cnVlLCJ3ZWJfZGFya2VyX2RhcmtfdGhlbWVfbGl2ZV9jaGF0Ijp0cnVlLCJ3ZWJfZGVkdXBlX3ZlX2dyYWZ0aW5nIjp0cnVlLCJ3ZWJfZGVmZXJfc2hvcnRzX3VpIjp0cnVlLCJ3ZWJfZGVmZXJfc2hvcnRzX3VpX3BoYXNlMiI6dHJ1ZSwid2ViX2RlcHJlY2F0ZV9zZXJ2aWNlX2FqYXhfbWFwX2RlcGVuZGVuY3kiOnRydWUsIndlYl9lbmFibGVfZXJyb3JfMjA0Ijp0cnVlLCJ3ZWJfZW5hYmxlX2hpc3RvcnlfY2FjaGVfbWFwIjp0cnVlLCJ3ZWJfZW5hYmxlX2ltcF9hdWRpb19jYyI6dHJ1ZSwid2ViX2VuYWJsZV9pbnN0cmVhbV9hZHNfbGlua19kZWZpbml0aW9uX2ExMXlfYnVnZml4Ijp0cnVlLCJ3ZWJfZW5hYmxlX3BkcF9taW5pX3BsYXllciI6dHJ1ZSwid2ViX2VuYWJsZV92aWRlb19wcmV2aWV3X21pZ3JhdGlvbiI6dHJ1ZSwid2ViX2VuYWJsZV92b3pfYXVkaW9fZmVlZGJhY2siOnRydWUsIndlYl9lbmdhZ2VtZW50X3BhbmVsX3Nob3dfZGVzY3JpcHRpb24iOnRydWUsIndlYl9maWxsZWRfc3Vic2NyaWJlZF9idXR0b24iOnRydWUsIndlYl9maXhfZmluZV9zY3J1YmJpbmdfZHJhZyI6dHJ1ZSwid2ViX2ZvcndhcmRfY29tbWFuZF9vbl9wYmoiOnRydWUsIndlYl9nZWxfdGltZW91dF9jYXAiOnRydWUsIndlYl9ndWlkZV91aV9yZWZyZXNoIjp0cnVlLCJ3ZWJfaGlkZV9hdXRvbmF2X2hlYWRsaW5lIjp0cnVlLCJ3ZWJfaGlkZV9hdXRvbmF2X2tleWxpbmUiOnRydWUsIndlYl9pbXBfdGh1bWJuYWlsX2NsaWNrX2ZpeF9lbmFibGVkIjp0cnVlLCJ3ZWJfaW5saW5lX3BsYXllcl9lbmFibGVkIjp0cnVlLCJ3ZWJfaW5saW5lX3BsYXllcl9ub19wbGF5YmFja191aV9jbGlja19oYW5kbGVyIjp0cnVlLCJ3ZWJfa2V2bGFyX2VuYWJsZV9hZGFwdGl2ZV9zaWduYWxzIjp0cnVlLCJ3ZWJfbG9nX21lbW9yeV90b3RhbF9rYnl0ZXMiOnRydWUsIndlYl9sb2dfcGxheWVyX3dhdGNoX25leHRfdGlja3MiOnRydWUsIndlYl9sb2dfcmVlbHNfdGlja3MiOnRydWUsIndlYl9tb2Rlcm5fYWRzIjp0cnVlLCJ3ZWJfbW9kZXJuX2J1dHRvbnMiOnRydWUsIndlYl9tb2Rlcm5fYnV0dG9uc19ibF9zdXJ2ZXkiOnRydWUsIndlYl9tb2Rlcm5fY2hpcHMiOnRydWUsIndlYl9tb2Rlcm5fY29sbGVjdGlvbnMiOnRydWUsIndlYl9tb2Rlcm5fZGlhbG9ncyI6dHJ1ZSwid2ViX21vZGVybl9wbGF5bGlzdHMiOnRydWUsIndlYl9tb2Rlcm5fc2NydWJiZXIiOnRydWUsIndlYl9tb2Rlcm5fc3Vic2NyaWJlIjp0cnVlLCJ3ZWJfbW92ZV9hdXRvcGxheV92aWRlb191bmRlcl9jaGlwIjp0cnVlLCJ3ZWJfbW92ZWRfc3VwZXJfdGl0bGVfbGluayI6dHJ1ZSwid2ViX29uZV9wbGF0Zm9ybV9lcnJvcl9oYW5kbGluZyI6dHJ1ZSwid2ViX3BhdXNlZF9vbmx5X21pbmlwbGF5ZXJfc2hvcnRjdXRfZXhwYW5kIjp0cnVlLCJ3ZWJfcGxheWVyX2FkZF92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdG9fb3V0Ym91bmRfbGlua3MiOnRydWUsIndlYl9wbGF5ZXJfYWx3YXlzX2VuYWJsZV9hdXRvX3RyYW5zbGF0aW9uIjp0cnVlLCJ3ZWJfcGxheWVyX2F1dG9uYXZfZW1wdHlfc3VnZ2VzdGlvbnNfZml4Ijp0cnVlLCJ3ZWJfcGxheWVyX2F1dG9uYXZfdG9nZ2xlX2Fsd2F5c19saXN0ZW4iOnRydWUsIndlYl9wbGF5ZXJfYXV0b25hdl91c2Vfc2VydmVyX3Byb3ZpZGVkX3N0YXRlIjp0cnVlLCJ3ZWJfcGxheWVyX2RlY291cGxlX2F1dG9uYXYiOnRydWUsIndlYl9wbGF5ZXJfZGlzYWJsZV9pbmxpbmVfc2NydWJiaW5nIjp0cnVlLCJ3ZWJfcGxheWVyX2VuYWJsZV9lYXJseV93YXJuaW5nX3NuYWNrYmFyIjp0cnVlLCJ3ZWJfcGxheWVyX2VuYWJsZV9mZWF0dXJlZF9wcm9kdWN0X2Jhbm5lcl9vbl9kZXNrdG9wIjp0cnVlLCJ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9pbl9oNV9hcGkiOnRydWUsIndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX3BsYXliYWNrX2NhcCI6dHJ1ZSwid2ViX3BsYXllcl9lbnRpdGllc19taWRkbGV3YXJlIjp0cnVlLCJ3ZWJfcGxheWVyX2xvZ19jbGlja19iZWZvcmVfZ2VuZXJhdGluZ192ZV9jb252ZXJzaW9uX3BhcmFtcyI6dHJ1ZSwid2ViX3BsYXllcl9tb3ZlX2F1dG9uYXZfdG9nZ2xlIjp0cnVlLCJ3ZWJfcGxheWVyX211dGFibGVfZXZlbnRfbGFiZWwiOnRydWUsIndlYl9wbGF5ZXJfc2hvdWxkX2hvbm9yX2luY2x1ZGVfYXNyX3NldHRpbmciOnRydWUsIndlYl9wbGF5ZXJfc21hbGxfaGJwX3NldHRpbmdzX21lbnUiOnRydWUsIndlYl9wbGF5ZXJfdG9waWZ5X3N1YnRpdGxlc19mb3Jfc2hvcnRzIjp0cnVlLCJ3ZWJfcGxheWVyX3RvdWNoX21vZGVfaW1wcm92ZW1lbnRzIjp0cnVlLCJ3ZWJfcGxheWVyX3VzZV9uZXdfYXBpX2Zvcl9xdWFsaXR5X3B1bGxiYWNrIjp0cnVlLCJ3ZWJfcGxheWVyX3ZlX2NvbnZlcnNpb25fZml4ZXNfZm9yX2NoYW5uZWxfaW5mbyI6dHJ1ZSwid2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlIjp0cnVlLCJ3ZWJfcHJlZmV0Y2hfcHJlbG9hZF92aWRlbyI6dHJ1ZSwid2ViX3Byc190ZXN0aW5nX21vZGVfa2lsbHN3aXRjaCI6dHJ1ZSwid2ViX3JlcGxhY2VfdGh1bWJuYWlsX3dpdGhfaW1hZ2UiOnRydWUsIndlYl9yb3VuZGVkX3RodW1ibmFpbHMiOnRydWUsIndlYl9zZWFyY2hfaW5saW5lX3BsYXliYWNrX21vdXNlX2VudGVyIjp0cnVlLCJ3ZWJfc2VnbWVudGVkX2xpa2VfZGlzbGlrZV9idXR0b24iOnRydWUsIndlYl9zZXRfaW5saW5lX3ByZXZpZXdfc2V0dGluZ19pbl9ob21lX2Jyb3dzZV9yZXF1ZXN0Ijp0cnVlLCJ3ZWJfc2hlZXRzX3VpX3JlZnJlc2giOnRydWUsIndlYl9zaG9ydHNfZWFybHlfcGxheWVyX2xvYWQiOnRydWUsIndlYl9zaG9ydHNfbnZjX2RhcmsiOnRydWUsIndlYl9zaG9ydHNfcHJvZ3Jlc3NfYmFyIjp0cnVlLCJ3ZWJfc2hvcnRzX3NoZWxmX29uX3NlYXJjaCI6dHJ1ZSwid2ViX3Nob3J0c19za2lwX2xvYWRpbmdfc2FtZV9pbmRleCI6dHJ1ZSwid2ViX3NtYXJ0aW1hdGlvbnNfa2lsbHN3aXRjaCI6dHJ1ZSwid2ViX3NuYWNrYmFyX3VpX3JlZnJlc2giOnRydWUsIndlYl9zdHJ1Y3R1cmVkX2Rlc2NyaXB0aW9uX3Nob3dfbW9yZSI6dHJ1ZSwid2ViX3N1Z2dlc3Rpb25fYm94X2JvbGRlciI6dHJ1ZSwid2ViX3N1Z2dlc3Rpb25fYm94X3Jlc3R5bGUiOnRydWUsIndlYl90dXJuX29mZl9pbXBfb25fdGh1bWJuYWlsX21vdXNlZG93biI6dHJ1ZSwid2ViX3VzZV9jYWNoZV9mb3JfaW1hZ2VfZmFsbGJhY2siOnRydWUsIndlYl93YXRjaF9jaGlwc19tYXNrX2ZhZGUiOnRydWUsIndlYl93YXRjaF9jaW5lbWF0aWNzX3ByZWZlcnJlZF9yZWR1Y2VkX21vdGlvbl9kZWZhdWx0X2Rpc2FibGVkIjp0cnVlLCJ3ZWJfeXRfY29uZmlnX2NvbnRleHQiOnRydWUsIndpbF9pY29uX3JlbmRlcl93aGVuX2lkbGUiOnRydWUsIndvZmZsZV9jbGVhbl91cF9hZnRlcl9lbnRpdHlfbWlncmF0aW9uIjp0cnVlLCJ3b2ZmbGVfZW5hYmxlX2Rvd25sb2FkX3N0YXR1cyI6dHJ1ZSwid29mZmxlX3BsYXlsaXN0X29wdGltaXphdGlvbiI6dHJ1ZSwieW91cl9kYXRhX2VudHJ5cG9pbnQiOnRydWUsInl0X25ldHdvcmtfbWFuYWdlcl9jb21wb25lbnRfdG9fbGliX2tpbGxzd2l0Y2giOnRydWUsInl0aWRiX2NsZWFyX2VtYmVkZGVkX3BsYXllciI6dHJ1ZSwieXRpZGJfZmV0Y2hfZGF0YXN5bmNfaWRzX2Zvcl9kYXRhX2NsZWFudXAiOnRydWUsIkg1X2FzeW5jX2xvZ2dpbmdfZGVsYXlfbXMiOjMwMDAwLjAsImFkZHRvX2FqYXhfbG9nX3dhcm5pbmdfZnJhY3Rpb24iOjAuMSwiYXV0b3BsYXlfcGF1c2VfYnlfbGFjdF9zYW1wbGluZ19mcmFjdGlvbiI6MC4wLCJicm93c2VfYWpheF9sb2dfd2FybmluZ19mcmFjdGlvbiI6MS4wLCJjaW5lbWF0aWNfd2F0Y2hfZWZmZWN0X29wYWNpdHkiOjAuNCwiZm9ybWF0dGVkX2Rlc2NyaXB0aW9uX2xvZ193YXJuaW5nX2ZyYWN0aW9uIjowLjAxLCJrZXZsYXJfdHVuZXJfY2xhbXBfZGV2aWNlX3BpeGVsX3JhdGlvIjoyLjAsImtldmxhcl90dW5lcl90aHVtYm5haWxfZmFjdG9yIjoxLjAsImtldmxhcl91bmlmaWVkX3BsYXllcl9sb2dnaW5nX3RocmVzaG9sZCI6MS4wLCJsb2dfd2luZG93X29uZXJyb3JfZnJhY3Rpb24iOjAuMSwicG9seW1lcl9yZXBvcnRfY2xpZW50X3VybF9yZXF1ZXN0ZWRfcmF0ZSI6MC4wMDEsInBvbHltZXJfcmVwb3J0X21pc3Npbmdfd2ViX25hdmlnYXRpb25fZW5kcG9pbnRfcmF0ZSI6MC4wMDEsInByZWZldGNoX2Nvb3JkaW5hdG9yX2Vycm9yX2xvZ2dpbmdfc2FtcGxpbmdfcmF0ZSI6MS4wLCJ0dl9wYWNmX2xvZ2dpbmdfc2FtcGxlX3JhdGUiOjAuMDEsIndlYl9zaG9ydHNfZXJyb3JfbG9nZ2luZ190aHJlc2hvbGQiOjAuMDAxLCJ3ZWJfc2hvcnRzX2ludGVyc2VjdGlvbl9vYnNlcnZlcl90aHJlc2hvbGRfb3ZlcnJpZGUiOjAuMCwid2ViX3N5c3RlbV9oZWFsdGhfZnJhY3Rpb24iOjAuMDEsInl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXQiOjAuMDIsInl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfc2Vzc2lvbiI6MC4yLCJ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0X3RyYW5zYWN0aW9uIjowLjEsImF1dG9wbGF5X3BhdXNlX2J5X2xhY3Rfc2VjIjowLCJhdXRvcGxheV90aW1lIjo4MDAwLCJhdXRvcGxheV90aW1lX2Zvcl9mdWxsc2NyZWVuIjozMDAwLCJhdXRvcGxheV90aW1lX2Zvcl9tdXNpY19jb250ZW50IjozMDAwLCJib3RndWFyZF9hc3luY19zbmFwc2hvdF90aW1lb3V0X21zIjozMDAwLCJjaGVja19uYXZpZ2F0b3JfYWNjdXJhY3lfdGltZW91dF9tcyI6MCwiY2luZW1hdGljX3dhdGNoX2Nzc19maWx0ZXJfYmx1cl9zdHJlbmd0aCI6NDAsImNpbmVtYXRpY193YXRjaF9mYWRlX291dF9kdXJhdGlvbiI6NTAwLCJjbGllbnRfc3RyZWFtel93ZWJfZmx1c2hfY291bnQiOjEwMCwiY2xpZW50X3N0cmVhbXpfd2ViX2ZsdXNoX2ludGVydmFsX3NlY29uZHMiOjYwLCJjbG91ZF9zYXZlX2dhbWVfZGF0YV9yYXRlX2xpbWl0X21zIjozMDAwLCJjb21wcmVzc2lvbl9kaXNhYmxlX3BvaW50IjoxMCwiY29tcHJlc3Npb25fcGVyZm9ybWFuY2VfdGhyZXNob2xkIjoyNTAsImRlc2t0b3Bfc2VhcmNoX3N1Z2dlc3Rpb25fdGFwX3RhcmdldCI6MCwiZXh0ZXJuYWxfZnVsbHNjcmVlbl9idXR0b25fY2xpY2tfdGhyZXNob2xkIjoyLCJleHRlcm5hbF9mdWxsc2NyZWVuX2J1dHRvbl9zaG93bl90aHJlc2hvbGQiOjEwLCJnZWxfcXVldWVfdGltZW91dF9tYXhfbXMiOjMwMDAwMCwiZ2V0X2FzeW5jX3RpbWVvdXRfbXMiOjYwMDAwLCJoaWdoX3ByaW9yaXR5X2ZseW91dF9mcmVxdWVuY3kiOjMsImluaXRpYWxfZ2VsX2JhdGNoX3RpbWVvdXQiOjIwMDAsImtldmxhcl9taW5pX2d1aWRlX3dpZHRoX3RocmVzaG9sZCI6NzkxLCJrZXZsYXJfcGVyc2lzdGVudF9ndWlkZV93aWR0aF90aHJlc2hvbGQiOjEzMTIsImtldmxhcl90aW1lX2NhY2hpbmdfZW5kX3RocmVzaG9sZCI6MTUsImtldmxhcl90aW1lX2NhY2hpbmdfc3RhcnRfdGhyZXNob2xkIjoxNSwia2V2bGFyX3Rvb2x0aXBfaW1wcmVzc2lvbl9jYXAiOjIsImtldmxhcl90dW5lcl9kZWZhdWx0X2NvbW1lbnRzX2RlbGF5IjoxMDAwLCJrZXZsYXJfdHVuZXJfc2NoZWR1bGVyX3NvZnRfc3RhdGVfdGltZXJfbXMiOjgwMCwia2V2bGFyX3R1bmVyX3Zpc2liaWxpdHlfdGltZV9iZXR3ZWVuX2pvYnNfbXMiOjEwMCwia2V2bGFyX3dhdGNoX2ZsZXh5X21ldGFkYXRhX2hlaWdodCI6MTM2LCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF9kZXNjcmlwdGlvbl9saW5lcyI6MywibGl2ZV9jaGF0X2NodW5rX3JlbmRlcmluZyI6MCwibGl2ZV9jaGF0X2Vtb2ppX3BpY2tlcl9yZXN0eWxlX2JvdHRvbV9weCI6MCwibGl2ZV9jaGF0X2Vtb2ppX3BpY2tlcl9yZXN0eWxlX2hlaWdodF9wZXJjZW50IjowLCJsaXZlX2NoYXRfZW1vamlfcGlja2VyX3Jlc3R5bGVfaGVpZ2h0X3B4IjowLCJsaXZlX2NoYXRfZW1vamlfcGlja2VyX3Jlc3R5bGVfd2lkdGhfcHgiOjAsImxpdmVfY2hhdF9tYXhfY2h1bmtfc2l6ZSI6NSwibGl2ZV9jaGF0X21pbl9jaHVua19pbnRlcnZhbF9tcyI6MzAwLCJsb2dfd2ViX21ldGFfaW50ZXJ2YWxfbXMiOjAsIm1heF9ib2R5X3NpemVfdG9fY29tcHJlc3MiOjUwMDAwMCwibWF4X2R1cmF0aW9uX3RvX2NvbnNpZGVyX21vdXNlb3Zlcl9hc19ob3ZlciI6NjAwMDAwLCJtYXhfcHJlZmV0Y2hfd2luZG93X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb24iOjAsIm1pbl9tb3VzZV9zdGlsbF9kdXJhdGlvbiI6MTAwLCJtaW5fcHJlZmV0Y2hfb2Zmc2V0X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb24iOjEwLCJtaW5pbXVtX2R1cmF0aW9uX3RvX2NvbnNpZGVyX21vdXNlb3Zlcl9hc19ob3ZlciI6NTAwLCJtd2ViX2hpc3RvcnlfbWFuYWdlcl9jYWNoZV9zaXplIjoxMDAsIm5ldHdvcmtfcG9sbGluZ19pbnRlcnZhbCI6MzAwMDAsInBhY2ZfbG9nZ2luZ19kZWxheV9taWxsaXNlY29uZHNfdGhyb3VnaF95YmZlX3R2IjozMDAwMCwicGJqX25hdmlnYXRlX2xpbWl0IjotMSwicGxheV9waW5nX2ludGVydmFsX21zIjozMDAwMCwicG9seW1lcl9sb2dfcHJvcF9jaGFuZ2Vfb2JzZXJ2ZXJfcGVyY2VudCI6MCwicG9zdF90eXBlX2ljb25zX3JlYXJyYW5nZSI6MSwicHJlZmV0Y2hfY29tbWVudHNfbXNfYWZ0ZXJfdmlkZW8iOjAsInByZWZldGNoX2Nvb3JkaW5hdG9yX2NvbW1hbmRfdGltZW91dF9tcyI6NjAwMDAsInByZWZldGNoX2Nvb3JkaW5hdG9yX21heF9pbmZsaWdodF9yZXF1ZXN0cyI6MSwicmljaF9ncmlkX21heF9pdGVtX3dpZHRoIjozNjAsInJpY2hfZ3JpZF9taW5faXRlbV93aWR0aCI6MzIwLCJyaWNoX2dyaWRfdHJ1ZV9pbmxpbmVfcGxheWJhY2tfdHJpZ2dlcl9kZWxheSI6MCwic2VuZF9jb25maWdfaGFzaF90aW1lciI6MCwic2VydmljZV93b3JrZXJfcHVzaF9sb2dnZWRfb3V0X3Byb21wdF93YXRjaGVzIjotMSwic2VydmljZV93b3JrZXJfcHVzaF9wcm9tcHRfY2FwIjotMSwic2VydmljZV93b3JrZXJfcHVzaF9wcm9tcHRfZGVsYXlfbWljcm9zZWNvbmRzIjozODg4MDAwMDAwMDAwLCJzaG9ydHNfaW5saW5lX3BsYXllcl90cmlnZ2VyaW5nX2RlbGF5Ijo1MDAsInNsb3dfY29tcHJlc3Npb25zX2JlZm9yZV9hYmFuZG9uX2NvdW50Ijo0LCJ1c2VyX2VuZ2FnZW1lbnRfZXhwZXJpbWVudHNfcmF0ZV9saW1pdF9tcyI6ODY0MDAwMDAsInVzZXJfbWVudGlvbl9zdWdnZXN0aW9uc19lZHVfaW1wcmVzc2lvbl9jYXAiOjEwLCJ2aXNpYmlsaXR5X3RpbWVfYmV0d2Vlbl9qb2JzX21zIjoxMDAsIndhdGNoX25leHRfcGF1c2VfYXV0b3BsYXlfbGFjdF9zZWMiOjQ1MDAsIndlYl9lbXVsYXRlZF9pZGxlX2NhbGxiYWNrX2RlbGF5IjowLCJ3ZWJfZm9yZWdyb3VuZF9oZWFydGJlYXRfaW50ZXJ2YWxfbXMiOjI4MDAwLCJ3ZWJfZ2VsX2RlYm91bmNlX21zIjo2MDAwMCwid2ViX2hvbWVfZmVlZF9yZWxvYWRfZGVsYXkiOjE0NDAsIndlYl9pbmxpbmVfcGxheWVyX3RyaWdnZXJpbmdfZGVsYXkiOjEwMDAsIndlYl9sb2dnaW5nX21heF9iYXRjaCI6MTUwLCJ3ZWJfcGxheWVyX2NhcHRpb25fbGFuZ3VhZ2VfcHJlZmVyZW5jZV9zdGlja2luZXNzX2R1cmF0aW9uIjozMCwid2ViX3NlYXJjaF9pbmxpbmVfcGxheWVyX3RyaWdnZXJpbmdfZGVsYXkiOjUwMCwid2ViX3NlYXJjaF9zaG9ydHNfaW5saW5lX3BsYXliYWNrX2R1cmF0aW9uX21zIjowLCJ3ZWJfc2hvcnRzX2lubGluZV9wbGF5YmFja19wcmV2aWV3X21zIjowLCJ3ZWJfc2hvcnRzX3NjcnViYmVyX3RocmVzaG9sZF9zZWMiOjAsIndlYl9zaG9ydHNfc2hlbGZfZml4ZWRfcG9zaXRpb24iOjksIndlYl9zaG9ydHNfc3Rvcnlib2FyZF90aHJlc2hvbGRfc2Vjb25kcyI6MCwid2ViX3Ntb290aG5lc3NfdGVzdF9kdXJhdGlvbl9tcyI6MCwid2ViX3Ntb290aG5lc3NfdGVzdF9tZXRob2QiOjAsInlvb2RsZV9lbmRfdGltZV91dGMiOjAsInlvb2RsZV9zdGFydF90aW1lX3V0YyI6MCwieXRpZGJfcmVtYWtlX2RiX3JldHJpZXMiOjEsInl0aWRiX3Jlb3Blbl9kYl9yZXRyaWVzIjowLCJXZWJDbGllbnRSZWxlYXNlUHJvY2Vzc0NyaXRpY2FsX195b3V0dWJlX3dlYl9jbGllbnRfdmVyc2lvbl9vdmVycmlkZSI6IiIsImRlYnVnX2ZvcmNlZF9pbnRlcm5hbGNvdW50cnljb2RlIjoiIiwiZGVza3RvcF9zZWFyY2hfYmlnZ2VyX3RodW1ic19zdHlsZSI6IkRFRkFVTFQiLCJkZXNrdG9wX3NlYXJjaGJhcl9zdHlsZSI6ImRlZmF1bHQiLCJlbWJlZHNfd2ViX3N5bnRoX2NoX2hlYWRlcnNfYmFubmVkX3VybHNfcmVnZXgiOiIiLCJrZXZsYXJfZHVwbGljYXRlX3ByZWZfY29va2llX2RvbWFpbl9vdmVycmlkZSI6IiIsImtldmxhcl9saW5rX2NhcHR1cmluZ19tb2RlIjoiIiwibGl2ZV9jaGF0X2Vtb2ppX3BpY2tlcl9yZXN0eWxlX2hlaWdodCI6IiIsImxpdmVfY2hhdF9lbW9qaV9waWNrZXJfcmVzdHlsZV93aWR0aCI6IiIsImxpdmVfY2hhdF91bmljb2RlX2Vtb2ppX2pzb25fdXJsIjoiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20veW91dHViZS9pbWcvZW1vamlzL2Vtb2ppcy1zdmctOS5qc29uIiwicG9seW1lcl90YXNrX21hbmFnZXJfc3RhdHVzIjoicHJvZHVjdGlvbiIsInNlcnZpY2Vfd29ya2VyX3B1c2hfZm9yY2Vfbm90aWZpY2F0aW9uX3Byb21wdF90YWciOiIxIiwic2VydmljZV93b3JrZXJfc2NvcGUiOiIvIiwid2ViX2FzeW5jX2NvbnRleHRfcHJvY2Vzc29yX2ltcGwiOiJzdGFuZGFsb25lIiwid2ViX2NsaWVudF92ZXJzaW9uX292ZXJyaWRlIjoiIiwid2ViX2hvbWVfZmVlZF9yZWxvYWRfZXhwZXJpZW5jZSI6Im5vbmUiLCJ3ZWJfbW9kZXJuX3N1YnNjcmliZV9zdHlsZSI6ImZpbGxlZCIsIndlYl9zaG9ydHNfZXhwYW5kZWRfb3ZlcmxheV90eXBlIjoiREVGQVVMVCIsIndlYl9zaG9ydHNfb3ZlcmxheV92ZXJ0aWNhbF9vcmllbnRhdGlvbiI6ImJvdHRvbSIsInlvb2RsZV9iYXNlX3VybCI6IiIsInlvb2RsZV93ZWJwX2Jhc2VfdXJsIjoiIiwiY29uZGl0aW9uYWxfbGFiX2lkcyI6W10sImd1aWRlX2J1c2luZXNzX2luZm9fY291bnRyaWVzIjpbIktSIl0sImd1aWRlX2xlZ2FsX2Zvb3Rlcl9lbmFibGVkX2NvdW50cmllcyI6WyJOTCIsIkVTIl0sImtldmxhcl9jb21tYW5kX2hhbmRsZXJfY29tbWFuZF9iYW5saXN0IjpbXSwia2V2bGFyX3BhZ2Vfc2VydmljZV91cmxfcHJlZml4X2NhcnZlb3V0cyI6W10sIndlYl9vcF9zaWduYWxfdHlwZV9iYW5saXN0IjpbXX0sIkdBUElfSElOVF9QQVJBTVMiOiJtOy9fL3Njcy9hYmMtc3RhdGljL18vanMva1x1MDAzZGdhcGkuZ2FwaS5lbi5LMUxXdGhBemViNC5PL2RcdTAwM2QxL3JzXHUwMDNkQUhwT29vLVRRVHFudjdod2lqcnNlUDRKS0oxWFk4M0VoZy9tXHUwMDNkX19mZWF0dXJlc19fIiwiR0FQSV9IT1NUIjoiaHR0cHM6Ly9hcGlzLmdvb2dsZS5jb20iLCJHQVBJX0xPQ0FMRSI6ImZyX0ZSIiwiR0wiOiJGUiIsIkdPT0dMRV9GRUVEQkFDS19QUk9EVUNUX0lEIjoiNTkiLCJHT09HTEVfRkVFREJBQ0tfUFJPRFVDVF9EQVRBIjp7InBvbHltZXIiOiJhY3RpdmUiLCJwb2x5bWVyMiI6ImFjdGl2ZSIsImFjY2VwdF9sYW5ndWFnZSI6IiJ9LCJITCI6ImZyIiwiSFRNTF9ESVIiOiJsdHIiLCJIVE1MX0xBTkciOiJmci1GUiIsIklOTkVSVFVCRV9BUElfS0VZIjoiQUl6YVN5QU9fRkoyU2xxVThRNFNURUhMR0NpbHdfWTlfMTFxY1c4IiwiSU5ORVJUVUJFX0FQSV9WRVJTSU9OIjoidjEiLCJJTk5FUlRVQkVfQ0xJRU5UX05BTUUiOiJXRUIiLCJJTk5FUlRVQkVfQ0xJRU5UX1ZFUlNJT04iOiIyLjIwMjMwNjA3LjA2LjAwIiwiSU5ORVJUVUJFX0NPTlRFWFQiOnsiY2xpZW50Ijp7ImhsIjoiZnIiLCJnbCI6IkZSIiwicmVtb3RlSG9zdCI6IjM3LjE3MS4yMDAuNTkiLCJkZXZpY2VNYWtlIjoiIiwiZGV2aWNlTW9kZWwiOiIiLCJ2aXNpdG9yRGF0YSI6IkNndEJibDl5Ymxnd1dIbHJheWlVdm9pa0JnJTNEJTNEIiwidXNlckFnZW50IjoiUnVieSxnemlwKGdmZSkiLCJjbGllbnROYW1lIjoiV0VCIiwiY2xpZW50VmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJvc1ZlcnNpb24iOiIiLCJvcmlnaW5hbFVybCI6Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL0BwYXJpcy1yYj9jYnJkXHUwMDNkMVx1MDAyNnVjYmNiXHUwMDNkMSIsInBsYXRmb3JtIjoiREVTS1RPUCIsImNsaWVudEZvcm1GYWN0b3IiOiJVTktOT1dOX0ZPUk1fRkFDVE9SIiwiY29uZmlnSW5mbyI6eyJhcHBJbnN0YWxsRGF0YSI6IkNKUy1pS1FHRUtxeV9oSVF6Ti11QlJDbHd2NFNFUGkxcndVUTdxS3ZCUkRLdks4RkVOU2hyd1VRNEtldkJSQ1Z2NjhGRU5XMnJ3VVF6SzctRWhEaTFLNEZFSW5vcmdVUXBabXZCUkQtdGE4RkVMcTByd1VRNUxQLUVoQzM0SzRGRUtPMHJ3VVFncDJ2QlJDUG82OEZFT2YzcmdVUW91eXVCUkRNdF80U0VLbV9yd1VRODZpdkJSRDd2cThGRVA3dXJnVVEyNi12QlJDOXRxNEZFTGlMcmdVUXc3Zi1FaENHMGY0U0VORHlyZ1VROGJhdkJRJTNEJTNEIn0sImFjY2VwdEhlYWRlciI6IiovKiIsImRldmljZUV4cGVyaW1lbnRJZCI6IkNoeE9la2t3VFdwTk5FNVVUWGxOYW1kNFRucFplazU2YTNoT1VUMDlFSlMtaUtRR0dKUy1pS1FHIn0sInVzZXIiOnsibG9ja2VkU2FmZXR5TW9kZSI6ZmFsc2V9LCJyZXF1ZXN0Ijp7InVzZVNzbCI6dHJ1ZX0sImNsaWNrVHJhY2tpbmciOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkloTUk3ckdHOXFlMC93SVZHc3ZWQ2gzLzhncDcifX0sIklOTkVSVFVCRV9DT05URVhUX0NMSUVOVF9OQU1FIjoxLCJJTk5FUlRVQkVfQ09OVEVYVF9DTElFTlRfVkVSU0lPTiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJJTk5FUlRVQkVfQ09OVEVYVF9HTCI6IkZSIiwiSU5ORVJUVUJFX0NPTlRFWFRfSEwiOiJmciIsIkxBVEVTVF9FQ0FUQ0hFUl9TRVJWSUNFX1RSQUNLSU5HX1BBUkFNUyI6eyJjbGllbnQubmFtZSI6IldFQiJ9LCJMT0dHRURfSU4iOmZhbHNlLCJQQUdFX0JVSUxEX0xBQkVMIjoieW91dHViZS5kZXNrdG9wLndlYl8yMDIzMDYwN18wNl9SQzAwIiwiUEFHRV9DTCI6NTM4NTA0OTQ0LCJzY2hlZHVsZXIiOnsidXNlUmFmIjp0cnVlLCJ0aW1lb3V0IjoyMH0sIlNFUlZFUl9OQU1FIjoiV2ViRkUiLCJTRVNTSU9OX0lOREVYIjoiIiwiU0lHTklOX1VSTCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9TZXJ2aWNlTG9naW4/c2VydmljZVx1MDAzZHlvdXR1YmVcdTAwMjZ1aWxlbFx1MDAzZDNcdTAwMjZwYXNzaXZlXHUwMDNkdHJ1ZVx1MDAyNmNvbnRpbnVlXHUwMDNkaHR0cHMlM0ElMkYlMkZ3d3cueW91dHViZS5jb20lMkZzaWduaW4lM0ZhY3Rpb25faGFuZGxlX3NpZ25pbiUzRHRydWUlMjZhcHAlM0RkZXNrdG9wJTI2aGwlM0RmciUyNm5leHQlM0RodHRwcyUyNTNBJTI1MkYlMjUyRnd3dy55b3V0dWJlLmNvbSUyNTJGJTI1NDBwYXJpcy1yYiUyNTNGY2JyZCUyNTNEMSUyNTI2dWNiY2IlMjUzRDElMjZmZWF0dXJlJTNEX19GRUFUVVJFX19cdTAwMjZobFx1MDAzZGZyIiwiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR1MiOnsiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfV0FUQ0giOnsidHJhbnNwYXJlbnRCYWNrZ3JvdW5kIjp0cnVlLCJzaG93TWluaXBsYXllckJ1dHRvbiI6dHJ1ZSwiZXh0ZXJuYWxGdWxsc2NyZWVuIjp0cnVlLCJzaG93TWluaXBsYXllclVpV2hlbk1pbmltaXplZCI6dHJ1ZSwicm9vdEVsZW1lbnRJZCI6Im1vdmllX3BsYXllciIsImpzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3BsYXllcl9pYXMudmZsc2V0L2ZyX0ZSL2Jhc2UuanMiLCJjc3NVcmwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvd3d3LXBsYXllci5jc3MiLCJjb250ZXh0SWQiOiJXRUJfUExBWUVSX0NPTlRFWFRfQ09ORklHX0lEX0tFVkxBUl9XQVRDSCIsImV2ZW50TGFiZWwiOiJkZXRhaWxwYWdlIiwiY29udGVudFJlZ2lvbiI6IkZSIiwiaGwiOiJmcl9GUiIsImhvc3RMYW5ndWFnZSI6ImZyIiwicGxheWVyU3R5bGUiOiJkZXNrdG9wLXBvbHltZXIiLCJpbm5lcnR1YmVBcGlLZXkiOiJBSXphU3lBT19GSjJTbHFVOFE0U1RFSExHQ2lsd19ZOV8xMXFjVzgiLCJpbm5lcnR1YmVBcGlWZXJzaW9uIjoidjEiLCJpbm5lcnR1YmVDb250ZXh0Q2xpZW50VmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJkZXZpY2UiOnsiYnJhbmQiOiIiLCJtb2RlbCI6IiIsInBsYXRmb3JtIjoiREVTS1RPUCIsImludGVyZmFjZU5hbWUiOiJXRUIiLCJpbnRlcmZhY2VWZXJzaW9uIjoiMi4yMDIzMDYwNy4wNi4wMCJ9LCJzZXJpYWxpemVkRXhwZXJpbWVudElkcyI6IjIzOTgzMjk2LDI0MDA0NjQ0LDI0MDA3MjQ2LDI0MDA3NjEzLDI0MDgwNzM4LDI0MTM1MzEwLDI0MzYzMTE0LDI0MzY0Nzg5LDI0MzY1NTM0LDI0MzY2OTE3LDI0MzcyNzYxLDI0Mzc1MTAxLDI0Mzc2Nzg1LDI0NDE1ODY0LDI0NDE2MjkwLDI0NDMzNjc5LDI0NDM3NTc3LDI0NDM5MzYxLDI0NDQzMzMxLDI0NDk5NTMyLDI0NTMyODU1LDI0NTUwNDU4LDI0NTUwOTUxLDI0NTU1NTY3LDI0NTU4NjQxLDI0NTU5MzI3LDI0Njk5ODk5LDM5MzIzMDc0Iiwic2VyaWFsaXplZEV4cGVyaW1lbnRGbGFncyI6Ikg1X2FzeW5jX2xvZ2dpbmdfZGVsYXlfbXNcdTAwM2QzMDAwMC4wXHUwMDI2SDVfZW5hYmxlX2Z1bGxfcGFjZl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNkg1X3VzZV9hc3luY19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmFjdGlvbl9jb21wYW5pb25fY2VudGVyX2FsaWduX2Rlc2NyaXB0aW9uXHUwMDNkdHJ1ZVx1MDAyNmFkX3BvZF9kaXNhYmxlX2NvbXBhbmlvbl9wZXJzaXN0X2Fkc19xdWFsaXR5XHUwMDNkdHJ1ZVx1MDAyNmFkZHRvX2FqYXhfbG9nX3dhcm5pbmdfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZhbGlnbl9hZF90b192aWRlb19wbGF5ZXJfbGlmZWN5Y2xlX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X2xpdmVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2YWxsb3dfcG9sdGVyZ3VzdF9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19za2lwX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNmF0dF93ZWJfcmVjb3JkX21ldHJpY3NcdTAwM2R0cnVlXHUwMDI2YXV0b3BsYXlfdGltZVx1MDAzZDgwMDBcdTAwMjZhdXRvcGxheV90aW1lX2Zvcl9mdWxsc2NyZWVuXHUwMDNkMzAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX211c2ljX2NvbnRlbnRcdTAwM2QzMDAwXHUwMDI2Ymdfdm1fcmVpbml0X3RocmVzaG9sZFx1MDAzZDcyMDAwMDBcdTAwMjZibG9ja2VkX3BhY2thZ2VzX2Zvcl9zcHNcdTAwM2RbXVx1MDAyNmJvdGd1YXJkX2FzeW5jX3NuYXBzaG90X3RpbWVvdXRfbXNcdTAwM2QzMDAwXHUwMDI2Y2hlY2tfYWRfdWlfc3RhdHVzX2Zvcl9td2ViX3NhZmFyaVx1MDAzZHRydWVcdTAwMjZjaGVja19uYXZpZ2F0b3JfYWNjdXJhY3lfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZjbGVhcl91c2VyX3BhcnRpdGlvbmVkX2xzXHUwMDNkdHJ1ZVx1MDAyNmNsaWVudF9yZXNwZWN0X2F1dG9wbGF5X3N3aXRjaF9idXR0b25fcmVuZGVyZXJcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3NfZ2VsXHUwMDNkdHJ1ZVx1MDAyNmNvbXByZXNzaW9uX2Rpc2FibGVfcG9pbnRcdTAwM2QxMFx1MDAyNmNvbXByZXNzaW9uX3BlcmZvcm1hbmNlX3RocmVzaG9sZFx1MDAzZDI1MFx1MDAyNmNzaV9vbl9nZWxcdTAwM2R0cnVlXHUwMDI2ZGFzaF9tYW5pZmVzdF92ZXJzaW9uXHUwMDNkNVx1MDAyNmRlYnVnX2JhbmRhaWRfaG9zdG5hbWVcdTAwM2RcdTAwMjZkZWJ1Z19zaGVybG9nX3VzZXJuYW1lXHUwMDNkXHUwMDI2ZGVsYXlfYWRzX2d2aV9jYWxsX29uX2J1bGxlaXRfbGl2aW5nX3Jvb21fbXNcdTAwM2QwXHUwMDI2ZGVwcmVjYXRlX2NzaV9oYXNfaW5mb1x1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfcGFpcl9zZXJ2bGV0X2VuYWJsZWRcdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19jaGlsZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX3BhcmVudFx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX2ltYWdlX2N0YV9ub19iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfbG9nX2ltZ19jbGlja19sb2NhdGlvblx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX3NwYXJrbGVzX2xpZ2h0X2N0YV9idXR0b25cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9jaGFubmVsX2lkX2NoZWNrX2Zvcl9zdXNwZW5kZWRfY2hhbm5lbHNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9jaGlsZF9ub2RlX2F1dG9fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9kZWZlcl9hZG1vZHVsZV9vbl9hZHZlcnRpc2VyX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfZmVhdHVyZXNfZm9yX3N1cGV4XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbGVnYWN5X2Rlc2t0b3BfcmVtb3RlX3F1ZXVlXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbWR4X2Nvbm5lY3Rpb25faW5fbWR4X21vZHVsZV9mb3JfbXVzaWNfd2ViXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbmV3X3BhdXNlX3N0YXRlM1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3BhY2ZfbG9nZ2luZ19mb3JfbWVtb3J5X2xpbWl0ZWRfdHZcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9yb3VuZGluZ19hZF9ub3RpZnlcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zaW1wbGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfc3NkYWlfb25fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGFiYmluZ19iZWZvcmVfZmx5b3V0X2FkX2VsZW1lbnRzX2FwcGVhclx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3RodW1ibmFpbF9wcmVsb2FkaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc19kaXNhYmxlX3Byb2dyZXNzX2Jhcl9jb250ZXh0X21lbnVfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2VuYWJsZV9hbGxvd193YXRjaF9hZ2Fpbl9lbmRzY3JlZW5fZm9yX2VsaWdpYmxlX3Nob3J0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfdmVfY29udmVyc2lvbl9wYXJhbV9yZW5hbWluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9hdXRvcGxheV9ub3Rfc3VwcG9ydGVkX2xvZ2dpbmdfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2N1ZV92aWRlb191bnBsYXlhYmxlX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9ob3VzZV9icmFuZF9hbmRfeXRfY29leGlzdGVuY2VcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9hZF9wbGF5ZXJfZnJvbV9wYWdlX3Nob3dcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nX3NwbGF5X2FzX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvZ2dpbmdfZXZlbnRfaGFuZGxlcnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX21vYmlsZV9kdHRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX25ld19jb250ZXh0X21lbnVfdHJpZ2dlcmluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wYXVzZV9vdmVybGF5X3duX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZW1fZG9tYWluX2ZpeF9mb3JfYWRfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGZwX3VuYnJhbmRlZF9lbF9kZXByZWNhdGlvblx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9yY2F0X2FsbG93bGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9yZXBsYWNlX3VubG9hZF93X3BhZ2VoaWRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3NjcmlwdGVkX3BsYXliYWNrX2Jsb2NrZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfdmVfY29udmVyc2lvbl9sb2dnaW5nX3RyYWNraW5nX25vX2FsbG93X2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9oaWRlX3VuZmlsbGVkX21vcmVfdmlkZW9zX3N1Z2dlc3Rpb25zXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfbGl0ZV9tb2RlXHUwMDNkMVx1MDAyNmVtYmVkc193ZWJfbndsX2Rpc2FibGVfbm9jb29raWVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zaG9wcGluZ19vdmVybGF5X25vX3dhaXRfZm9yX3BhaWRfY29udGVudF9vdmVybGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfc3ludGhfY2hfaGVhZGVyc19iYW5uZWRfdXJsc19yZWdleFx1MDAzZFx1MDAyNmVuYWJsZV9hYl9ycF9pbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FkX2Nwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9hcHBfcHJvbW9fZW5kY2FwX2VtbF9vbl90YWJsZXRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Nhc3RfZm9yX3dlYl91bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Nhc3Rfb25fbXVzaWNfd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jbGllbnRfcGFnZV9pZF9oZWFkZXJfZm9yX2ZpcnN0X3BhcnR5X3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jbGllbnRfc2xpX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Rpc2NyZXRlX2xpdmVfcHJlY2lzZV9lbWJhcmdvc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkX3dlYl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkX3dlYl9jbGllbnRfY2hlY2tcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkc19pY29uX3dlYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXZpY3Rpb25fcHJvdGVjdGlvbl9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZ2VsX2xvZ19jb21tYW5kc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfaDVfaW5zdHJlYW1fd2F0Y2hfbmV4dF9wYXJhbXNfb2FybGliXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV92aWRlb19hZHNfb2FybGliXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oYW5kbGVzX2FjY291bnRfbWVudV9zd2l0Y2hlclx1MDAzZHRydWVcdTAwMjZlbmFibGVfa2FidWtpX2NvbW1lbnRzX29uX3Nob3J0c1x1MDAzZGRpc2FibGVkXHUwMDI2ZW5hYmxlX2xpdmVfcHJlbWllcmVfd2ViX3BsYXllcl9pbmRpY2F0b3JcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2xyX2hvbWVfaW5mZWVkX2Fkc19pbmxpbmVfcGxheWJhY2tfcHJvZ3Jlc3NfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX21peGVkX2RpcmVjdGlvbl9mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbXdlYl9lbmRjYXBfY2xpY2thYmxlX2ljb25fZGVzY3JpcHRpb25cdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX213ZWJfbGl2ZXN0cmVhbV91aV91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX25ld19wYWlkX3Byb2R1Y3RfcGxhY2VtZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Nsb3RfYXNkZV9wbGF5ZXJfYnl0ZV9oNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2X2Zvcl9wYWdlX3RvcF9mb3JtYXRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeXNmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFzc19zZGNfZ2V0X2FjY291bnRzX2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BsX3JfY1x1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9maXhfb25fdHZodG1sNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9pbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zZXJ2ZXJfc3RpdGNoZWRfZGFpXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zaG9ydHNfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwX2FkX2d1aWRhbmNlX3Byb21wdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2tpcHBhYmxlX2Fkc19mb3JfdW5wbHVnZ2VkX2FkX3BvZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfdGVjdG9uaWNfYWRfdXhfZm9yX2hhbGZ0aW1lXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90aGlyZF9wYXJ0eV9pbmZvXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90b3Bzb2lsX3d0YV9mb3JfaGFsZnRpbWVfbGl2ZV9pbmZyYVx1MDAzZHRydWVcdTAwMjZlbmFibGVfd2ViX21lZGlhX3Nlc3Npb25fbWV0YWRhdGFfZml4XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfc2NoZWR1bGVyX3NpZ25hbHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3duX2luZm9jYXJkc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfeXRfYXRhX2lmcmFtZV9hdXRodXNlclx1MDAzZHRydWVcdTAwMjZlcnJvcl9tZXNzYWdlX2Zvcl9nc3VpdGVfbmV0d29ya19yZXN0cmljdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZXhwb3J0X25ldHdvcmtsZXNzX29wdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZXh0ZXJuYWxfZnVsbHNjcmVlbl93aXRoX2VkdVx1MDAzZHRydWVcdTAwMjZmYXN0X2F1dG9uYXZfaW5fYmFja2dyb3VuZFx1MDAzZHRydWVcdTAwMjZmZXRjaF9hdHRfaW5kZXBlbmRlbnRseVx1MDAzZHRydWVcdTAwMjZmaWxsX3NpbmdsZV92aWRlb193aXRoX25vdGlmeV90b19sYXNyXHUwMDNkdHJ1ZVx1MDAyNmZpbHRlcl92cDlfZm9yX2NzZGFpXHUwMDNkdHJ1ZVx1MDAyNmZpeF9hZHNfdHJhY2tpbmdfZm9yX3N3Zl9jb25maWdfZGVwcmVjYXRpb25fbXdlYlx1MDAzZHRydWVcdTAwMjZnY2ZfY29uZmlnX3N0b3JlX2VuYWJsZWRcdTAwM2R0cnVlXHUwMDI2Z2VsX3F1ZXVlX3RpbWVvdXRfbWF4X21zXHUwMDNkMzAwMDAwXHUwMDI2Z3BhX3NwYXJrbGVzX3Rlbl9wZXJjZW50X2xheWVyXHUwMDNkdHJ1ZVx1MDAyNmd2aV9jaGFubmVsX2NsaWVudF9zY3JlZW5cdTAwM2R0cnVlXHUwMDI2aDVfY29tcGFuaW9uX2VuYWJsZV9hZGNwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmg1X2VuYWJsZV9nZW5lcmljX2Vycm9yX2xvZ2dpbmdfZXZlbnRcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX3VuaWZpZWRfY3NpX3ByZXJvbGxcdTAwM2R0cnVlXHUwMDI2aDVfaW5wbGF5ZXJfZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfcmVzZXRfY2FjaGVfYW5kX2ZpbHRlcl9iZWZvcmVfdXBkYXRlX21hc3RoZWFkXHUwMDNkdHJ1ZVx1MDAyNmhlYXRzZWVrZXJfZGVjb3JhdGlvbl90aHJlc2hvbGRcdTAwM2QwLjBcdTAwMjZoZnJfZHJvcHBlZF9mcmFtZXJhdGVfZmFsbGJhY2tfdGhyZXNob2xkXHUwMDNkMFx1MDAyNmhpZGVfZW5kcG9pbnRfb3ZlcmZsb3dfb25feXRkX2Rpc3BsYXlfYWRfcmVuZGVyZXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWRfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZodG1sNV9hZHNfcHJlcm9sbF9sb2NrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QxNTAwMFx1MDAyNmh0bWw1X2FsbG93X2Rpc2NvbnRpZ3VvdXNfc2xpY2VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2FsbG93X3ZpZGVvX2tleWZyYW1lX3dpdGhvdXRfYXVkaW9cdTAwM2R0cnVlXHUwMDI2aHRtbDVfYXR0YWNoX251bV9yYW5kb21fYnl0ZXNfdG9fYmFuZGFpZFx1MDAzZDBcdTAwMjZodG1sNV9hdHRhY2hfcG9fdG9rZW5fdG9fYmFuZGFpZFx1MDAzZHRydWVcdTAwMjZodG1sNV9hdXRvbmF2X2NhcF9pZGxlX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfYXV0b25hdl9xdWFsaXR5X2NhcFx1MDAzZDcyMFx1MDAyNmh0bWw1X2F1dG9wbGF5X2RlZmF1bHRfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfYmxvY2tfcGlwX3NhZmFyaV9kZWxheVx1MDAzZDBcdTAwMjZodG1sNV9ibWZmX25ld19mb3VyY2NfY2hlY2tcdTAwM2R0cnVlXHUwMDI2aHRtbDVfY29iYWx0X2RlZmF1bHRfYnVmZmVyX3NpemVfaW5fYnl0ZXNcdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X21heF9zaXplX2Zvcl9pbW1lZF9qb2JcdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X21pbl9wcm9jZXNzb3JfY250X3RvX29mZmxvYWRfYWxnb1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfb3ZlcnJpZGVfcXVpY1x1MDAzZDBcdTAwMjZodG1sNV9jb25zdW1lX21lZGlhX2J5dGVzX3NsaWNlX2luZm9zXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlX2R1cGVfY29udGVudF92aWRlb19sb2Fkc19pbl9saWZlY3ljbGVfYXBpXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlYnVnX2RhdGFfbG9nX3Byb2JhYmlsaXR5XHUwMDNkMC4xXHUwMDI2aHRtbDVfZGVjb2RlX3RvX3RleHR1cmVfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlZmF1bHRfYWRfZ2Fpblx1MDAzZDAuNVx1MDAyNmh0bWw1X2RlZmF1bHRfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfYWRfbW9kdWxlX21zXHUwMDNkMFx1MDAyNmh0bWw1X2RlZmVyX2ZldGNoX2F0dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9kZWZlcl9tb2R1bGVzX2RlbGF5X3RpbWVfbWlsbGlzXHUwMDNkMFx1MDAyNmh0bWw1X2RlbGF5ZWRfcmV0cnlfY291bnRcdTAwM2QxXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9kZWxheV9tc1x1MDAzZDUwMDBcdTAwMjZodG1sNV9kZXByZWNhdGVfdmlkZW9fdGFnX3Bvb2xcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVza3RvcF92cjE4MF9hbGxvd19wYW5uaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RmX2Rvd25ncmFkZV90aHJlc2hcdTAwM2QwLjJcdTAwMjZodG1sNV9kaXNhYmxlX2NzaV9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNhYmxlX21vdmVfcHNzaF90b19tb292XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbm9uX2NvbnRpZ3VvdXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzcGxheWVkX2ZyYW1lX3JhdGVfZG93bmdyYWRlX3RocmVzaG9sZFx1MDAzZDQ1XHUwMDI2aHRtbDVfZHJtX2NoZWNrX2FsbF9rZXlfZXJyb3Jfc3RhdGVzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RybV9jcGlfbGljZW5zZV9rZXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2FjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWRzX2NsaWVudF9tb25pdG9yaW5nX2xvZ190dlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2FwdGlvbl9jaGFuZ2VzX2Zvcl9tb3NhaWNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NsaWVudF9oaW50c19vdmVycmlkZVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY29tcG9zaXRlX2VtYmFyZ29cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2VhYzNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2VtYmVkZGVkX3BsYXllcl92aXNpYmlsaXR5X3NpZ25hbHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX25vbl9ub3RpZnlfY29tcG9zaXRlX3ZvZF9sc2FyX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3NpbmdsZV92aWRlb192b2RfaXZhcl9vbl9wYWNmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV90dm9zX2Rhc2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZW5jcnlwdGVkX3ZwOVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfd2lkZXZpbmVfZm9yX2FsY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfd2lkZXZpbmVfZm9yX2Zhc3RfbGluZWFyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuY291cmFnZV9hcnJheV9jb2FsZXNjaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2dhcGxlc3NfZW5kZWRfdHJhbnNpdGlvbl9idWZmZXJfbXNcdTAwM2QyMDBcdTAwMjZodG1sNV9nZW5lcmF0ZV9zZXNzaW9uX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2dsX2Zwc190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aHRtbDVfaGRjcF9wcm9iaW5nX3N0cmVhbV91cmxcdTAwM2RcdTAwMjZodG1sNV9oZnJfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfaGlnaF9yZXNfbG9nZ2luZ19wZXJjZW50XHUwMDNkMS4wXHUwMDI2aHRtbDVfaWRsZV9yYXRlX2xpbWl0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9mYWlycGxheVx1MDAzZHRydWVcdTAwMjZodG1sNV9pbm5lcnR1YmVfaGVhcnRiZWF0c19mb3JfcGxheXJlYWR5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl93aWRldmluZVx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3M0X3NlZWtfYWJvdmVfemVyb1x1MDAzZHRydWVcdTAwMjZodG1sNV9pb3M3X2ZvcmNlX3BsYXlfb25fc3RhbGxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW9zX2ZvcmNlX3NlZWtfdG9femVyb19vbl9zdG9wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2p1bWJvX21vYmlsZV9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRcdTAwM2QzLjBcdTAwMjZodG1sNV9qdW1ib191bGxfbm9uc3RyZWFtaW5nX21mZmFfbXNcdTAwM2Q0MDAwXHUwMDI2aHRtbDVfanVtYm9fdWxsX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDEuM1x1MDAyNmh0bWw1X2xpY2Vuc2VfY29uc3RyYWludF9kZWxheVx1MDAzZDUwMDBcdTAwMjZodG1sNV9saXZlX2Ficl9oZWFkX21pc3NfZnJhY3Rpb25cdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX2Ficl9yZXByZWRpY3RfZnJhY3Rpb25cdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX2J5dGVyYXRlX2ZhY3Rvcl9mb3JfcmVhZGFoZWFkXHUwMDNkMS4zXHUwMDI2aHRtbDVfbGl2ZV9sb3dfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbGl2ZV9ub3JtYWxfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9saXZlX3VsdHJhX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9sb2dfYXVkaW9fYWJyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19leHBlcmltZW50X2lkX2Zyb21fcGxheWVyX3Jlc3BvbnNlX3RvX2N0bXBcdTAwM2RcdTAwMjZodG1sNV9sb2dfZmlyc3Rfc3NkYWlfcmVxdWVzdHNfa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfcmVidWZmZXJfZXZlbnRzXHUwMDNkNVx1MDAyNmh0bWw1X2xvZ19zc2RhaV9mYWxsYmFja19hZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX3RyaWdnZXJfZXZlbnRzX3dpdGhfZGVidWdfZGF0YVx1MDAzZHRydWVcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl9uZXdfZWxlbV9zaG9ydHNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl90aHJlc2hvbGRfbXNcdTAwM2QzMDAwMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc19zZWdfZHJpZnRfbGltaXRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9tYW5pZmVzdGxlc3NfdW5wbHVnZ2VkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc192cDlfb3RmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21heF9kcmlmdF9wZXJfdHJhY2tfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X21heF9oZWFkbV9mb3Jfc3RyZWFtaW5nX3hoclx1MDAzZDBcdTAwMjZodG1sNV9tYXhfbGl2ZV9kdnJfd2luZG93X3BsdXNfbWFyZ2luX3NlY3NcdTAwM2Q0NjgwMC4wXHUwMDI2aHRtbDVfbWF4X3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9tYXhfcmVkaXJlY3RfcmVzcG9uc2VfbGVuZ3RoXHUwMDNkODE5Mlx1MDAyNmh0bWw1X21heF9zZWxlY3RhYmxlX3F1YWxpdHlfb3JkaW5hbFx1MDAzZDBcdTAwMjZodG1sNV9tYXhfc291cmNlX2J1ZmZlcl9hcHBlbmRfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9tYXhpbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWVkaWFfZnVsbHNjcmVlblx1MDAzZHRydWVcdTAwMjZodG1sNV9tZmxfZXh0ZW5kX21heF9yZXF1ZXN0X3RpbWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfY2FwX3NlY3NcdTAwM2Q2MFx1MDAyNmh0bWw1X21pbl9yZWFkYmVoaW5kX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX2FkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5fc3RhcnR1cF9idWZmZXJlZF9tZWRpYV9kdXJhdGlvbl9zZWNzXHUwMDNkMS4yXHUwMDI2aHRtbDVfbWluaW11bV9yZWFkYWhlYWRfc2Vjb25kc1x1MDAzZDAuMFx1MDAyNmh0bWw1X25vX3BsYWNlaG9sZGVyX3JvbGxiYWNrc1x1MDAzZHRydWVcdTAwMjZodG1sNV9ub25fbmV0d29ya19yZWJ1ZmZlcl9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZodG1sNV9ub25fb25lc2llX2F0dGFjaF9wb190b2tlblx1MDAzZHRydWVcdTAwMjZodG1sNV9ub3RfcmVnaXN0ZXJfZGlzcG9zYWJsZXNfd2hlbl9jb3JlX2xpc3RlbnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb2ZmbGluZV9mYWlsdXJlX3JldHJ5X2xpbWl0XHUwMDNkMlx1MDAyNmh0bWw1X29uZXNpZV9kZWZlcl9jb250ZW50X2xvYWRlcl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfaG9zdF9yYWNpbmdfY2FwX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9pZ25vcmVfaW5uZXJ0dWJlX2FwaV9rZXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX2xpdmVfdHRsX3NlY3NcdTAwM2Q4XHUwMDI2aHRtbDVfb25lc2llX25vbnplcm9fcGxheWJhY2tfc3RhcnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX25vdGlmeV9jdWVwb2ludF9tYW5hZ2VyX29uX2NvbXBsZXRpb25cdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1fY29vbGRvd25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1faW50ZXJ2YWxfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1fbWF4X2xhY3RfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlZGlyZWN0b3JfdGltZW91dFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9yZXF1ZXN0X3RpbWVvdXRfbXNcdTAwM2QxMDAwXHUwMDI2aHRtbDVfb25lc2llX3N0aWNreV9zZXJ2ZXJfc2lkZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wYXVzZV9vbl9ub25mb3JlZ3JvdW5kX3BsYXRmb3JtX2Vycm9yc1x1MDAzZHRydWVcdTAwMjZodG1sNV9wZWFrX3NoYXZlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZfY2FwX292ZXJyaWRlX3N0aWNreVx1MDAzZHRydWVcdTAwMjZodG1sNV9wZXJmb3JtYW5jZV9jYXBfZmxvb3JcdTAwM2QzNjBcdTAwMjZodG1sNV9wZXJmb3JtYW5jZV9pbXBhY3RfcHJvZmlsaW5nX3RpbWVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X3BlcnNlcnZlX2F2MV9wZXJmX2NhcFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF0Zm9ybV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfcGxheWVyX2F1dG9uYXZfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfZHluYW1pY19ib3R0b21fZ3JhZGllbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxheWVyX21pbl9idWlsZF9jbFx1MDAzZC0xXHUwMDI2aHRtbDVfcGxheWVyX3ByZWxvYWRfYWRfZml4XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Bvc3RfaW50ZXJydXB0X3JlYWRhaGVhZFx1MDAzZDIwXHUwMDI2aHRtbDVfcHJlZmVyX3NlcnZlcl9id2UzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ByZWxvYWRfd2FpdF90aW1lX3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9wcm9iZV9wcmltYXJ5X2RlbGF5X2Jhc2VfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcHJvY2Vzc19hbGxfZW5jcnlwdGVkX2V2ZW50c1x1MDAzZHRydWVcdTAwMjZodG1sNV9xb2VfbGhfbWF4X3JlcG9ydF9jb3VudFx1MDAzZDBcdTAwMjZodG1sNV9xb2VfbGhfbWluX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X3F1ZXJ5X3N3X3NlY3VyZV9jcnlwdG9fZm9yX2FuZHJvaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmFuZG9tX3BsYXliYWNrX2NhcFx1MDAzZDBcdTAwMjZodG1sNV9yZWNvZ25pemVfcHJlZGljdF9zdGFydF9jdWVfcG9pbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX2NvbW1hbmRfdHJpZ2dlcmVkX2NvbXBhbmlvbnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX25vdF9zZXJ2YWJsZV9jaGVja19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbmFtZV9hcGJzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9mYXRhbF9kcm1fcmVzdHJpY3RlZF9lcnJvcl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9zbG93X2Fkc19hc19lcnJvclx1MDAzZHRydWVcdTAwMjZodG1sNV9yZXF1ZXN0X29ubHlfaGRyX29yX3Nkcl9rZXlzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfc2l6aW5nX211bHRpcGxpZXJcdTAwM2QwLjhcdTAwMjZodG1sNV9yZXNldF9tZWRpYV9zdHJlYW1fb25fdW5yZXN1bWFibGVfc2xpY2VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Jlc291cmNlX2JhZF9zdGF0dXNfZGVsYXlfc2NhbGluZ1x1MDAzZDEuNVx1MDAyNmh0bWw1X3Jlc3RyaWN0X3N0cmVhbWluZ194aHJfb25fc3FsZXNzX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NhZmFyaV9kZXNrdG9wX2VtZV9taW5fdmVyc2lvblx1MDAzZDBcdTAwMjZodG1sNV9zYW1zdW5nX2thbnRfbGltaXRfbWF4X2JpdHJhdGVcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19qaWdnbGVfY210X2RlbGF5X21zXHUwMDNkODAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fZGVsYXlfbXNcdTAwM2QxMjAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2J1ZmZlcl9yYW5nZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c192cnNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9jZmxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX3NldF9jbXRfZGVsYXlfbXNcdTAwM2QyMDAwXHUwMDI2aHRtbDVfc2Vla190aW1lb3V0X2RlbGF5X21zXHUwMDNkMjAwMDBcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2RlY29yYXRlZF91cmxfcmV0cnlfbGltaXRcdTAwM2Q1XHUwMDI2aHRtbDVfc2VydmVyX3N0aXRjaGVkX2RhaV9ncm91cFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZXNzaW9uX3BvX3Rva2VuX2ludGVydmFsX3RpbWVfbXNcdTAwM2Q5MDAwMDBcdTAwMjZodG1sNV9za2lwX29vYl9zdGFydF9zZWNvbmRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NraXBfc2xvd19hZF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfc2tpcF9zdWJfcXVhbnR1bV9kaXNjb250aW51aXR5X3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X25vX21lZGlhX3NvdXJjZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NzZGFpX2FkZmV0Y2hfZHluYW1pY190aW1lb3V0X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X3NzZGFpX2VuYWJsZV9uZXdfc2Vla19sb2dpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9zdGF0ZWZ1bF9hdWRpb19taW5fYWRqdXN0bWVudF92YWx1ZVx1MDAzZDBcdTAwMjZodG1sNV9zdGF0aWNfYWJyX3Jlc29sdXRpb25fc2hlbGZcdTAwM2QwXHUwMDI2aHRtbDVfc3RvcmVfeGhyX2hlYWRlcnNfcmVhZGFibGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbG9hZF9zcGVlZF9jaGVja19pbnRlcnZhbFx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjI1XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc19vbl90aW1lb3V0XHUwMDNkMC4xXHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2xvYWRfc3BlZWRcdTAwM2QxLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9zZWVrX2xhdGVuY3lfZnVkZ2VcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRfYnVmZmVyX2hlYWx0aF9zZWNzXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGltZW91dF9zZWNzXHUwMDNkMi4wXHUwMDI2aHRtbDVfdWdjX2xpdmVfYXVkaW9fNTFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdWdjX3ZvZF9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91bnJlcG9ydGVkX3NlZWtfcmVzZWVrX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3VucmVzdHJpY3RlZF9sYXllcl9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QwLjBcdTAwMjZodG1sNV91cmxfcGFkZGluZ19sZW5ndGhcdTAwM2QwXHUwMDI2aHRtbDVfdXJsX3NpZ25hdHVyZV9leHBpcnlfdGltZV9ob3Vyc1x1MDAzZDBcdTAwMjZodG1sNV91c2VfcG9zdF9mb3JfbWVkaWFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdXNlX3VtcFx1MDAzZHRydWVcdTAwMjZodG1sNV92aWRlb190YmRfbWluX2tiXHUwMDNkMFx1MDAyNmh0bWw1X3ZpZXdwb3J0X3VuZGVyc2VuZF9tYXhpbXVtXHUwMDNkMC4wXHUwMDI2aHRtbDVfdm9sdW1lX3NsaWRlcl90b29sdGlwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYl9lbmFibGVfaGFsZnRpbWVfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZodG1sNV93ZWJwb19pZGxlX3ByaW9yaXR5X2pvYlx1MDAzZHRydWVcdTAwMjZodG1sNV93b2ZmbGVfcmVzdW1lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvcmthcm91bmRfZGVsYXlfdHJpZ2dlclx1MDAzZHRydWVcdTAwMjZodG1sNV95dHZscl9lbmFibGVfc2luZ2xlX3NlbGVjdF9zdXJ2ZXlcdTAwM2R0cnVlXHUwMDI2aWdub3JlX292ZXJsYXBwaW5nX2N1ZV9wb2ludHNfb25fZW5kZW1pY19saXZlX2h0bWw1XHUwMDNkdHJ1ZVx1MDAyNmlsX3VzZV92aWV3X21vZGVsX2xvZ2dpbmdfY29udGV4dFx1MDAzZHRydWVcdTAwMjZpbml0aWFsX2dlbF9iYXRjaF90aW1lb3V0XHUwMDNkMjAwMFx1MDAyNmluamVjdGVkX2xpY2Vuc2VfaGFuZGxlcl9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNmluamVjdGVkX2xpY2Vuc2VfaGFuZGxlcl9saWNlbnNlX3N0YXR1c1x1MDAzZDBcdTAwMjZpdGRybV9pbmplY3RlZF9saWNlbnNlX3NlcnZpY2VfZXJyb3JfY29kZVx1MDAzZDBcdTAwMjZpdGRybV93aWRldmluZV9oYXJkZW5lZF92bXBfbW9kZVx1MDAzZGxvZ1x1MDAyNmpzb25fY29uZGVuc2VkX3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9jb21tYW5kX2hhbmRsZXJfY29tbWFuZF9iYW5saXN0XHUwMDNkW11cdTAwMjZrZXZsYXJfZHJvcGRvd25fZml4XHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9nZWxfZXJyb3Jfcm91dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllclx1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllcl9leHBhbmRfdG9wXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX3BsYXlfcGF1c2Vfb25fc2NyaW1cdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3BsYXliYWNrX2Fzc29jaWF0ZWRfcXVldWVcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3F1ZXVlX3VzZV91cGRhdGVfYXBpXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zaW1wX3Nob3J0c19yZXNldF9zY3JvbGxcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NtYXJ0X2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzX3NldHRpbmdcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3ZpbWlvX3VzZV9zaGFyZWRfbW9uaXRvclx1MDAzZHRydWVcdTAwMjZsaXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZsaXZlX2ZyZXNjYV92Mlx1MDAzZHRydWVcdTAwMjZsb2dfZXJyb3JzX3Rocm91Z2hfbndsX29uX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19nZWxfY29tcHJlc3Npb25fbGF0ZW5jeVx1MDAzZHRydWVcdTAwMjZsb2dfaGVhcnRiZWF0X3dpdGhfbGlmZWN5Y2xlc1x1MDAzZHRydWVcdTAwMjZsb2dfd2ViX2VuZHBvaW50X3RvX2xheWVyXHUwMDNkdHJ1ZVx1MDAyNmxvZ193aW5kb3dfb25lcnJvcl9mcmFjdGlvblx1MDAzZDAuMVx1MDAyNm1hbmlmZXN0bGVzc19wb3N0X2xpdmVcdTAwM2R0cnVlXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZV91ZnBoXHUwMDNkdHJ1ZVx1MDAyNm1heF9ib2R5X3NpemVfdG9fY29tcHJlc3NcdTAwM2Q1MDAwMDBcdTAwMjZtYXhfcHJlZmV0Y2hfd2luZG93X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb25cdTAwM2QwXHUwMDI2bWF4X3Jlc29sdXRpb25fZm9yX3doaXRlX25vaXNlXHUwMDNkMzYwXHUwMDI2bWR4X2VuYWJsZV9wcml2YWN5X2Rpc2Nsb3N1cmVfdWlcdTAwM2R0cnVlXHUwMDI2bWR4X2xvYWRfY2FzdF9hcGlfYm9vdHN0cmFwX3NjcmlwdFx1MDAzZHRydWVcdTAwMjZtaWdyYXRlX2V2ZW50c190b190c1x1MDAzZHRydWVcdTAwMjZtaW5fcHJlZmV0Y2hfb2Zmc2V0X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb25cdTAwM2QxMFx1MDAyNm11c2ljX2VuYWJsZV9zaGFyZWRfYXVkaW9fdGllcl9sb2dpY1x1MDAzZHRydWVcdTAwMjZtd2ViX2MzX2VuZHNjcmVlblx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9jdXN0b21fY29udHJvbF9zaGFyZWRcdTAwM2R0cnVlXHUwMDI2bXdlYl9lbmFibGVfc2tpcHBhYmxlc19vbl9qaW9fcGhvbmVcdTAwM2R0cnVlXHUwMDI2bXdlYl9tdXRlZF9hdXRvcGxheV9hbmltYXRpb25cdTAwM2RzaHJpbmtcdTAwMjZtd2ViX25hdGl2ZV9jb250cm9sX2luX2ZhdXhfZnVsbHNjcmVlbl9zaGFyZWRcdTAwM2R0cnVlXHUwMDI2bmV0d29ya19wb2xsaW5nX2ludGVydmFsXHUwMDNkMzAwMDBcdTAwMjZuZXR3b3JrbGVzc19nZWxcdTAwM2R0cnVlXHUwMDI2bmV0d29ya2xlc3NfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZuZXdfY29kZWNzX3N0cmluZ19hcGlfdXNlc19sZWdhY3lfc3R5bGVcdTAwM2R0cnVlXHUwMDI2bndsX3NlbmRfZmFzdF9vbl91bmxvYWRcdTAwM2R0cnVlXHUwMDI2bndsX3NlbmRfZnJvbV9tZW1vcnlfd2hlbl9vbmxpbmVcdTAwM2R0cnVlXHUwMDI2b2ZmbGluZV9lcnJvcl9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZwYWNmX2xvZ2dpbmdfZGVsYXlfbWlsbGlzZWNvbmRzX3Rocm91Z2hfeWJmZV90dlx1MDAzZDMwMDAwXHUwMDI2cGFnZWlkX2FzX2hlYWRlcl93ZWJcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Fkc19zZXRfYWRmb3JtYXRfb25fY2xpZW50XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9hbGxvd19hdXRvbmF2X2FmdGVyX3BsYXlsaXN0XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9ib290c3RyYXBfbWV0aG9kXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9kZWZlcl9jYXB0aW9uX2Rpc3BsYXlcdTAwM2QxMDAwXHUwMDI2cGxheWVyX2Rlc3Ryb3lfb2xkX3ZlcnNpb25cdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RvdWJsZXRhcF90b19zZWVrXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9lbmFibGVfcGxheWJhY2tfcGxheWxpc3RfY2hhbmdlXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9lbmRzY3JlZW5fZWxsaXBzaXNfZml4XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl91bmRlcmxheV9taW5fcGxheWVyX3dpZHRoXHUwMDNkNzY4LjBcdTAwMjZwbGF5ZXJfdW5kZXJsYXlfdmlkZW9fd2lkdGhfZnJhY3Rpb25cdTAwM2QwLjZcdTAwMjZwbGF5ZXJfd2ViX2NhbmFyeV9zdGFnZVx1MDAzZDBcdTAwMjZwbGF5cmVhZHlfZmlyc3RfcGxheV9leHBpcmF0aW9uXHUwMDNkLTFcdTAwMjZwb2x5bWVyX2JhZF9idWlsZF9sYWJlbHNcdTAwM2R0cnVlXHUwMDI2cG9seW1lcl9sb2dfcHJvcF9jaGFuZ2Vfb2JzZXJ2ZXJfcGVyY2VudFx1MDAzZDBcdTAwMjZwb2x5bWVyX3ZlcmlmaXlfYXBwX3N0YXRlXHUwMDNkdHJ1ZVx1MDAyNnByZXNraXBfYnV0dG9uX3N0eWxlX2Fkc19iYWNrZW5kXHUwMDNkY291bnRkb3duX25leHRfdG9fdGh1bWJuYWlsXHUwMDI2cW9lX253bF9kb3dubG9hZHNcdTAwM2R0cnVlXHUwMDI2cW9lX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnJlY29yZF9hcHBfY3Jhc2hlZF93ZWJcdTAwM2R0cnVlXHUwMDI2cmVwbGFjZV9wbGF5YWJpbGl0eV9yZXRyaWV2ZXJfaW5fd2F0Y2hcdTAwM2R0cnVlXHUwMDI2c2NoZWR1bGVyX3VzZV9yYWZfYnlfZGVmYXVsdFx1MDAzZHRydWVcdTAwMjZzZWxmX3BvZGRpbmdfaGVhZGVyX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19pbnRlcnN0aXRpYWxfbWVzc2FnZVx1MDAyNnNlbGZfcG9kZGluZ19oaWdobGlnaHRfbm9uX2RlZmF1bHRfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZV9zdHJpbmdfdGVtcGxhdGVcdTAwM2RzZWxmX3BvZGRpbmdfbWlkcm9sbF9jaG9pY2VcdTAwMjZzZW5kX2NvbmZpZ19oYXNoX3RpbWVyXHUwMDNkMFx1MDAyNnNldF9pbnRlcnN0aXRpYWxfYWR2ZXJ0aXNlcnNfcXVlc3Rpb25fdGV4dFx1MDAzZHRydWVcdTAwMjZzaG9ydF9zdGFydF90aW1lX3ByZWZlcl9wdWJsaXNoX2luX3dhdGNoX2xvZ1x1MDAzZHRydWVcdTAwMjZzaG9ydHNfbW9kZV90b19wbGF5ZXJfYXBpXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19ub19zdG9wX3ZpZGVvX2NhbGxcdTAwM2R0cnVlXHUwMDI2c2hvdWxkX2NsZWFyX3ZpZGVvX2RhdGFfb25fcGxheWVyX2N1ZWRfdW5zdGFydGVkXHUwMDNkdHJ1ZVx1MDAyNnNpbXBseV9lbWJlZGRlZF9lbmFibGVfYm90Z3VhcmRcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbmxpbmVfbXV0ZWRfbGljZW5zZV9zZXJ2aWNlX2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNnNraXBfaW52YWxpZF95dGNzaV90aWNrc1x1MDAzZHRydWVcdTAwMjZza2lwX2xzX2dlbF9yZXRyeVx1MDAzZHRydWVcdTAwMjZza2lwX3NldHRpbmdfaW5mb19pbl9jc2lfZGF0YV9vYmplY3RcdTAwM2R0cnVlXHUwMDI2c2xvd19jb21wcmVzc2lvbnNfYmVmb3JlX2FiYW5kb25fY291bnRcdTAwM2Q0XHUwMDI2c3BlZWRtYXN0ZXJfY2FuY2VsbGF0aW9uX21vdmVtZW50X2RwXHUwMDNkMFx1MDAyNnNwZWVkbWFzdGVyX3BsYXliYWNrX3JhdGVcdTAwM2QwLjBcdTAwMjZzcGVlZG1hc3Rlcl90b3VjaF9hY3RpdmF0aW9uX21zXHUwMDNkMFx1MDAyNnN0YXJ0X2NsaWVudF9nY2ZcdTAwM2R0cnVlXHUwMDI2c3RhcnRfY2xpZW50X2djZl9mb3JfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNnN0YXJ0X3NlbmRpbmdfY29uZmlnX2hhc2hcdTAwM2R0cnVlXHUwMDI2c3RyZWFtaW5nX2RhdGFfZW1lcmdlbmN5X2l0YWdfYmxhY2tsaXN0XHUwMDNkW11cdTAwMjZzdWJzdGl0dXRlX2FkX2Nwbl9tYWNyb19pbl9zc2RhaVx1MDAzZHRydWVcdTAwMjZzdXBwcmVzc19lcnJvcl8yMDRfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZ0cmFuc3BvcnRfdXNlX3NjaGVkdWxlclx1MDAzZHRydWVcdTAwMjZ0dl9wYWNmX2xvZ2dpbmdfc2FtcGxlX3JhdGVcdTAwM2QwLjAxXHUwMDI2dHZodG1sNV91bnBsdWdnZWRfcHJlbG9hZF9jYWNoZV9zaXplXHUwMDNkNVx1MDAyNnVuY292ZXJfYWRfYmFkZ2Vfb25fUlRMX3Rpbnlfd2luZG93XHUwMDNkdHJ1ZVx1MDAyNnVucGx1Z2dlZF9kYWlfbGl2ZV9jaHVua19yZWFkYWhlYWRcdTAwM2QzXHUwMDI2dW5wbHVnZ2VkX3R2aHRtbDVfdmlkZW9fcHJlbG9hZF9vbl9mb2N1c19kZWxheV9tc1x1MDAzZDBcdTAwMjZ1cGRhdGVfbG9nX2V2ZW50X2NvbmZpZ1x1MDAzZHRydWVcdTAwMjZ1c2VfYWNjZXNzaWJpbGl0eV9kYXRhX29uX2Rlc2t0b3BfcGxheWVyX2J1dHRvblx1MDAzZHRydWVcdTAwMjZ1c2VfY29yZV9zbVx1MDAzZHRydWVcdTAwMjZ1c2VfaW5saW5lZF9wbGF5ZXJfcnBjXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfY21sXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfaW5fbWVtb3J5X3N0b3JhZ2VcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfaW5pdGlhbGl6YXRpb25cdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc2F3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3N0d1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF93dHNcdTAwM2R0cnVlXHUwMDI2dXNlX3BsYXllcl9hYnVzZV9iZ19saWJyYXJ5XHUwMDNkdHJ1ZVx1MDAyNnVzZV9wcm9maWxlcGFnZV9ldmVudF9sYWJlbF9pbl9jYXJvdXNlbF9wbGF5YmFja3NcdTAwM2R0cnVlXHUwMDI2dXNlX3JlcXVlc3RfdGltZV9tc19oZWFkZXJcdTAwM2R0cnVlXHUwMDI2dXNlX3Nlc3Npb25fYmFzZWRfc2FtcGxpbmdcdTAwM2R0cnVlXHUwMDI2dXNlX3RzX3Zpc2liaWxpdHlsb2dnZXJcdTAwM2R0cnVlXHUwMDI2dmFyaWFibGVfYnVmZmVyX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2dmVyaWZ5X2Fkc19pdGFnX2Vhcmx5XHUwMDNkdHJ1ZVx1MDAyNnZwOV9kcm1fbGl2ZVx1MDAzZHRydWVcdTAwMjZ2c3NfZmluYWxfcGluZ19zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZ2c3NfcGluZ3NfdXNpbmdfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2dnNzX3BsYXliYWNrX3VzZV9zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfYXBpX3VybFx1MDAzZHRydWVcdTAwMjZ3ZWJfYXN5bmNfY29udGV4dF9wcm9jZXNzb3JfaW1wbFx1MDAzZHN0YW5kYWxvbmVcdTAwMjZ3ZWJfY2luZW1hdGljX3dhdGNoX3NldHRpbmdzXHUwMDNkdHJ1ZVx1MDAyNndlYl9jbGllbnRfdmVyc2lvbl9vdmVycmlkZVx1MDAzZFx1MDAyNndlYl9kZWR1cGVfdmVfZ3JhZnRpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX2RlcHJlY2F0ZV9zZXJ2aWNlX2FqYXhfbWFwX2RlcGVuZGVuY3lcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV9lcnJvcl8yMDRcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV9pbnN0cmVhbV9hZHNfbGlua19kZWZpbml0aW9uX2ExMXlfYnVnZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfdm96X2F1ZGlvX2ZlZWRiYWNrXHUwMDNkdHJ1ZVx1MDAyNndlYl9maXhfZmluZV9zY3J1YmJpbmdfZHJhZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZm9yZWdyb3VuZF9oZWFydGJlYXRfaW50ZXJ2YWxfbXNcdTAwM2QyODAwMFx1MDAyNndlYl9mb3J3YXJkX2NvbW1hbmRfb25fcGJqXHUwMDNkdHJ1ZVx1MDAyNndlYl9nZWxfZGVib3VuY2VfbXNcdTAwM2Q2MDAwMFx1MDAyNndlYl9nZWxfdGltZW91dF9jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX2lubGluZV9wbGF5ZXJfbm9fcGxheWJhY2tfdWlfY2xpY2tfaGFuZGxlclx1MDAzZHRydWVcdTAwMjZ3ZWJfa2V5X21vbWVudHNfbWFya2Vyc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nX21lbW9yeV90b3RhbF9rYnl0ZXNcdTAwM2R0cnVlXHUwMDI2d2ViX2xvZ2dpbmdfbWF4X2JhdGNoXHUwMDNkMTUwXHUwMDI2d2ViX21vZGVybl9hZHNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fYnV0dG9uc19ibF9zdXJ2ZXlcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zY3J1YmJlclx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3N1YnNjcmliZVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3N1YnNjcmliZV9zdHlsZVx1MDAzZGZpbGxlZFx1MDAyNndlYl9uZXdfYXV0b25hdl9jb3VudGRvd25cdTAwM2R0cnVlXHUwMDI2d2ViX29uZV9wbGF0Zm9ybV9lcnJvcl9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfb3Bfc2lnbmFsX3R5cGVfYmFubGlzdFx1MDAzZFtdXHUwMDI2d2ViX3BhdXNlZF9vbmx5X21pbmlwbGF5ZXJfc2hvcnRjdXRfZXhwYW5kXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5YmFja19hc3NvY2lhdGVkX2xvZ19jdHRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfdmVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hZGRfdmVfY29udmVyc2lvbl9sb2dnaW5nX3RvX291dGJvdW5kX2xpbmtzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYWx3YXlzX2VuYWJsZV9hdXRvX3RyYW5zbGF0aW9uXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXBpX2xvZ2dpbmdfZnJhY3Rpb25cdTAwM2QwLjAxXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X2VtcHR5X3N1Z2dlc3Rpb25zX2ZpeFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdG9nZ2xlX2Fsd2F5c19saXN0ZW5cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X3VzZV9zZXJ2ZXJfcHJvdmlkZWRfc3RhdGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9jYXB0aW9uX2xhbmd1YWdlX3ByZWZlcmVuY2Vfc3RpY2tpbmVzc19kdXJhdGlvblx1MDAzZDMwXHUwMDI2d2ViX3BsYXllcl9kZWNvdXBsZV9hdXRvbmF2XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZGlzYWJsZV9pbmxpbmVfc2NydWJiaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX2Vhcmx5X3dhcm5pbmdfc25hY2tiYXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZmVhdHVyZWRfcHJvZHVjdF9iYW5uZXJfb25fZGVza3RvcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9pbl9oNV9hcGlcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfcHJlbWl1bV9oYnJfcGxheWJhY2tfY2FwXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaW5uZXJ0dWJlX3BsYXlsaXN0X3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2lwcF9jYW5hcnlfdHlwZV9mb3JfbG9nZ2luZ1x1MDAzZFx1MDAyNndlYl9wbGF5ZXJfbGl2ZV9tb25pdG9yX2Vudlx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2xvZ19jbGlja19iZWZvcmVfZ2VuZXJhdGluZ192ZV9jb252ZXJzaW9uX3BhcmFtc1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX21vdmVfYXV0b25hdl90b2dnbGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9tdXNpY192aXN1YWxpemVyX3RyZWF0bWVudFx1MDAzZGZha2VcdTAwMjZ3ZWJfcGxheWVyX211dGFibGVfZXZlbnRfbGFiZWxcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9uaXRyYXRlX3Byb21vX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9vZmZsaW5lX3BsYXlsaXN0X2F1dG9fcmVmcmVzaFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Jlc3BvbnNlX3BsYXliYWNrX3RyYWNraW5nX3BhcnNpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZWVrX2NoYXB0ZXJzX2J5X3Nob3J0Y3V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2VudGluZWxfaXNfdW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2hvdWxkX2hvbm9yX2luY2x1ZGVfYXNyX3NldHRpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG93X211c2ljX2luX3RoaXNfdmlkZW9fZ3JhcGhpY1x1MDAzZHZpZGVvX3RodW1ibmFpbFx1MDAyNndlYl9wbGF5ZXJfc21hbGxfaGJwX3NldHRpbmdzX21lbnVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zc19kYWlfYWRfZmV0Y2hpbmdfdGltZW91dF9tc1x1MDAzZDE1MDAwXHUwMDI2d2ViX3BsYXllcl9zc19tZWRpYV90aW1lX29mZnNldFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RvcGlmeV9zdWJ0aXRsZXNfZm9yX3Nob3J0c1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RvdWNoX21vZGVfaW1wcm92ZW1lbnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdHJhbnNmZXJfdGltZW91dF90aHJlc2hvbGRfbXNcdTAwM2QxMDgwMDAwMFx1MDAyNndlYl9wbGF5ZXJfdW5zZXRfZGVmYXVsdF9jc25fa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3VzZV9uZXdfYXBpX2Zvcl9xdWFsaXR5X3B1bGxiYWNrXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdmVfY29udmVyc2lvbl9maXhlc19mb3JfY2hhbm5lbF9pbmZvXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3dhdGNoX25leHRfcmVzcG9uc2VfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcHJlZmV0Y2hfcHJlbG9hZF92aWRlb1x1MDAzZHRydWVcdTAwMjZ3ZWJfcm91bmRlZF90aHVtYm5haWxzXHUwMDNkdHJ1ZVx1MDAyNndlYl9zZXR0aW5nc19tZW51X2ljb25zXHUwMDNkdHJ1ZVx1MDAyNndlYl9zbW9vdGhuZXNzX3Rlc3RfZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9tZXRob2RcdTAwM2QwXHUwMDI2d2ViX3l0X2NvbmZpZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNndpbF9pY29uX3JlbmRlcl93aGVuX2lkbGVcdTAwM2R0cnVlXHUwMDI2d29mZmxlX2NsZWFuX3VwX2FmdGVyX2VudGl0eV9taWdyYXRpb25cdTAwM2R0cnVlXHUwMDI2d29mZmxlX2VuYWJsZV9kb3dubG9hZF9zdGF0dXNcdTAwM2R0cnVlXHUwMDI2d29mZmxlX3BsYXlsaXN0X29wdGltaXphdGlvblx1MDAzZHRydWVcdTAwMjZ5dGlkYl9jbGVhcl9lbWJlZGRlZF9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2eXRpZGJfZmV0Y2hfZGF0YXN5bmNfaWRzX2Zvcl9kYXRhX2NsZWFudXBcdTAwM2R0cnVlXHUwMDI2eXRpZGJfcmVtYWtlX2RiX3JldHJpZXNcdTAwM2QxXHUwMDI2eXRpZGJfcmVvcGVuX2RiX3JldHJpZXNcdTAwM2QwXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdFx1MDAzZDAuMDJcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0X3Nlc3Npb25cdTAwM2QwLjJcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0X3RyYW5zYWN0aW9uXHUwMDNkMC4xIiwiY3NwTm9uY2UiOiJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIiwiY2FuYXJ5U3RhdGUiOiJub25lIiwiZW5hYmxlQ3NpTG9nZ2luZyI6dHJ1ZSwiY3NpUGFnZVR5cGUiOiJ3YXRjaCIsImRhdGFzeW5jSWQiOiJWMjAyMTdmYzZ8fCIsImFsbG93V29mZmxlTWFuYWdlbWVudCI6dHJ1ZSwiY2luZW1hdGljU2V0dGluZ3NBdmFpbGFibGUiOnRydWV9LCJXRUJfUExBWUVSX0NPTlRFWFRfQ09ORklHX0lEX0tFVkxBUl9DSEFOTkVMX1RSQUlMRVIiOnsicm9vdEVsZW1lbnRJZCI6ImM0LXBsYXllciIsImpzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3BsYXllcl9pYXMudmZsc2V0L2ZyX0ZSL2Jhc2UuanMiLCJjc3NVcmwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvd3d3LXBsYXllci5jc3MiLCJjb250ZXh0SWQiOiJXRUJfUExBWUVSX0NPTlRFWFRfQ09ORklHX0lEX0tFVkxBUl9DSEFOTkVMX1RSQUlMRVIiLCJldmVudExhYmVsIjoicHJvZmlsZXBhZ2UiLCJjb250ZW50UmVnaW9uIjoiRlIiLCJobCI6ImZyX0ZSIiwiaG9zdExhbmd1YWdlIjoiZnIiLCJwbGF5ZXJTdHlsZSI6ImRlc2t0b3AtcG9seW1lciIsImlubmVydHViZUFwaUtleSI6IkFJemFTeUFPX0ZKMlNscVU4UTRTVEVITEdDaWx3X1k5XzExcWNXOCIsImlubmVydHViZUFwaVZlcnNpb24iOiJ2MSIsImlubmVydHViZUNvbnRleHRDbGllbnRWZXJzaW9uIjoiMi4yMDIzMDYwNy4wNi4wMCIsImRldmljZSI6eyJicmFuZCI6IiIsIm1vZGVsIjoiIiwicGxhdGZvcm0iOiJERVNLVE9QIiwiaW50ZXJmYWNlTmFtZSI6IldFQiIsImludGVyZmFjZVZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIn0sInNlcmlhbGl6ZWRFeHBlcmltZW50SWRzIjoiMjM5ODMyOTYsMjQwMDQ2NDQsMjQwMDcyNDYsMjQwMDc2MTMsMjQwODA3MzgsMjQxMzUzMTAsMjQzNjMxMTQsMjQzNjQ3ODksMjQzNjU1MzQsMjQzNjY5MTcsMjQzNzI3NjEsMjQzNzUxMDEsMjQzNzY3ODUsMjQ0MTU4NjQsMjQ0MTYyOTAsMjQ0MzM2NzksMjQ0Mzc1NzcsMjQ0MzkzNjEsMjQ0NDMzMzEsMjQ0OTk1MzIsMjQ1MzI4NTUsMjQ1NTA0NTgsMjQ1NTA5NTEsMjQ1NTU1NjcsMjQ1NTg2NDEsMjQ1NTkzMjcsMjQ2OTk4OTksMzkzMjMwNzQiLCJzZXJpYWxpemVkRXhwZXJpbWVudEZsYWdzIjoiSDVfYXN5bmNfbG9nZ2luZ19kZWxheV9tc1x1MDAzZDMwMDAwLjBcdTAwMjZINV9lbmFibGVfZnVsbF9wYWNmX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2SDVfdXNlX2FzeW5jX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2YWN0aW9uX2NvbXBhbmlvbl9jZW50ZXJfYWxpZ25fZGVzY3JpcHRpb25cdTAwM2R0cnVlXHUwMDI2YWRfcG9kX2Rpc2FibGVfY29tcGFuaW9uX3BlcnNpc3RfYWRzX3F1YWxpdHlcdTAwM2R0cnVlXHUwMDI2YWRkdG9fYWpheF9sb2dfd2FybmluZ19mcmFjdGlvblx1MDAzZDAuMVx1MDAyNmFsaWduX2FkX3RvX3ZpZGVvX3BsYXllcl9saWZlY3ljbGVfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2YWxsb3dfbGl2ZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19wb2x0ZXJndXN0X2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X3NraXBfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2YXR0X3dlYl9yZWNvcmRfbWV0cmljc1x1MDAzZHRydWVcdTAwMjZhdXRvcGxheV90aW1lXHUwMDNkODAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX2Z1bGxzY3JlZW5cdTAwM2QzMDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfbXVzaWNfY29udGVudFx1MDAzZDMwMDBcdTAwMjZiZ192bV9yZWluaXRfdGhyZXNob2xkXHUwMDNkNzIwMDAwMFx1MDAyNmJsb2NrZWRfcGFja2FnZXNfZm9yX3Nwc1x1MDAzZFtdXHUwMDI2Ym90Z3VhcmRfYXN5bmNfc25hcHNob3RfdGltZW91dF9tc1x1MDAzZDMwMDBcdTAwMjZjaGVja19hZF91aV9zdGF0dXNfZm9yX213ZWJfc2FmYXJpXHUwMDNkdHJ1ZVx1MDAyNmNoZWNrX25hdmlnYXRvcl9hY2N1cmFjeV90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmNsZWFyX3VzZXJfcGFydGl0aW9uZWRfbHNcdTAwM2R0cnVlXHUwMDI2Y2xpZW50X3Jlc3BlY3RfYXV0b3BsYXlfc3dpdGNoX2J1dHRvbl9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZjb21wcmVzc19nZWxcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3Npb25fZGlzYWJsZV9wb2ludFx1MDAzZDEwXHUwMDI2Y29tcHJlc3Npb25fcGVyZm9ybWFuY2VfdGhyZXNob2xkXHUwMDNkMjUwXHUwMDI2Y3NpX29uX2dlbFx1MDAzZHRydWVcdTAwMjZkYXNoX21hbmlmZXN0X3ZlcnNpb25cdTAwM2Q1XHUwMDI2ZGVidWdfYmFuZGFpZF9ob3N0bmFtZVx1MDAzZFx1MDAyNmRlYnVnX3NoZXJsb2dfdXNlcm5hbWVcdTAwM2RcdTAwMjZkZWxheV9hZHNfZ3ZpX2NhbGxfb25fYnVsbGVpdF9saXZpbmdfcm9vbV9tc1x1MDAzZDBcdTAwMjZkZXByZWNhdGVfY3NpX2hhc19pbmZvXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV9wYWlyX3NlcnZsZXRfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX2NoaWxkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfcGFyZW50XHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfaW1hZ2VfY3RhX25vX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9sb2dfaW1nX2NsaWNrX2xvY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3Bfc3BhcmtsZXNfbGlnaHRfY3RhX2J1dHRvblx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoYW5uZWxfaWRfY2hlY2tfZm9yX3N1c3BlbmRlZF9jaGFubmVsc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoaWxkX25vZGVfYXV0b19mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2RlZmVyX2FkbW9kdWxlX29uX2FkdmVydGlzZXJfdmlkZW9cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9mZWF0dXJlc19mb3Jfc3VwZXhcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9sZWdhY3lfZGVza3RvcF9yZW1vdGVfcXVldWVcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9tZHhfY29ubmVjdGlvbl9pbl9tZHhfbW9kdWxlX2Zvcl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9uZXdfcGF1c2Vfc3RhdGUzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcGFjZl9sb2dnaW5nX2Zvcl9tZW1vcnlfbGltaXRlZF90dlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3JvdW5kaW5nX2FkX25vdGlmeVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NpbXBsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zc2RhaV9vbl9lcnJvcnNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90YWJiaW5nX2JlZm9yZV9mbHlvdXRfYWRfZWxlbWVudHNfYXBwZWFyXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGh1bWJuYWlsX3ByZWxvYWRpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2Rpc2FibGVfcHJvZ3Jlc3NfYmFyX2NvbnRleHRfbWVudV9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZW5hYmxlX2FsbG93X3dhdGNoX2FnYWluX2VuZHNjcmVlbl9mb3JfZWxpZ2libGVfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc192ZV9jb252ZXJzaW9uX3BhcmFtX3JlbmFtaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2F1dG9wbGF5X25vdF9zdXBwb3J0ZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfY3VlX3ZpZGVvX3VucGxheWFibGVfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2hvdXNlX2JyYW5kX2FuZF95dF9jb2V4aXN0ZW5jZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2FkX3BsYXllcl9mcm9tX3BhZ2Vfc2hvd1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dfc3BsYXlfYXNfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nZ2luZ19ldmVudF9oYW5kbGVyc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2R0dHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbmV3X2NvbnRleHRfbWVudV90cmlnZ2VyaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BhdXNlX292ZXJsYXlfd25fdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BlbV9kb21haW5fZml4X2Zvcl9hZF9yZXF1ZXN0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZnBfdW5icmFuZGVkX2VsX2RlcHJlY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JjYXRfYWxsb3dsaXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JlcGxhY2VfdW5sb2FkX3dfcGFnZWhpZGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfc2NyaXB0ZWRfcGxheWJhY2tfYmxvY2tlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdHJhY2tpbmdfbm9fYWxsb3dfbGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2hpZGVfdW5maWxsZWRfbW9yZV92aWRlb3Nfc3VnZ2VzdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9saXRlX21vZGVcdTAwM2QxXHUwMDI2ZW1iZWRzX3dlYl9ud2xfZGlzYWJsZV9ub2Nvb2tpZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3Nob3BwaW5nX292ZXJsYXlfbm9fd2FpdF9mb3JfcGFpZF9jb250ZW50X292ZXJsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zeW50aF9jaF9oZWFkZXJzX2Jhbm5lZF91cmxzX3JlZ2V4XHUwMDNkXHUwMDI2ZW5hYmxlX2FiX3JwX2ludFx1MDAzZHRydWVcdTAwMjZlbmFibGVfYWRfY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FwcF9wcm9tb19lbmRjYXBfZW1sX29uX3RhYmxldFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9mb3Jfd2ViX3VucGx1Z2dlZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9vbl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9wYWdlX2lkX2hlYWRlcl9mb3JfZmlyc3RfcGFydHlfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9zbGlfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZGlzY3JldGVfbGl2ZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudF9jaGVja1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRzX2ljb25fd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9ldmljdGlvbl9wcm90ZWN0aW9uX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9nZWxfbG9nX2NvbW1hbmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV9pbnN0cmVhbV93YXRjaF9uZXh0X3BhcmFtc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X3ZpZGVvX2Fkc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2hhbmRsZXNfYWNjb3VudF9tZW51X3N3aXRjaGVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9rYWJ1a2lfY29tbWVudHNfb25fc2hvcnRzXHUwMDNkZGlzYWJsZWRcdTAwMjZlbmFibGVfbGl2ZV9wcmVtaWVyZV93ZWJfcGxheWVyX2luZGljYXRvclx1MDAzZHRydWVcdTAwMjZlbmFibGVfbHJfaG9tZV9pbmZlZWRfYWRzX2lubGluZV9wbGF5YmFja19wcm9ncmVzc19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9td2ViX2VuZGNhcF9jbGlja2FibGVfaWNvbl9kZXNjcmlwdGlvblx1MDAzZHRydWVcdTAwMjZlbmFibGVfbXdlYl9saXZlc3RyZWFtX3VpX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbmFibGVfbmV3X3BhaWRfcHJvZHVjdF9wbGFjZW1lbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2Zfc2xvdF9hc2RlX3BsYXllcl9ieXRlX2g1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZfZm9yX3BhZ2VfdG9wX2Zvcm1hdHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95c2ZlX3R2XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYXNzX3NkY19nZXRfYWNjb3VudHNfbGlzdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGxfcl9jXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2ZpeF9vbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2luX3R2aHRtbDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NlcnZlcl9zdGl0Y2hlZF9kYWlcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Nob3J0c19wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NraXBfYWRfZ3VpZGFuY2VfcHJvbXB0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwcGFibGVfYWRzX2Zvcl91bnBsdWdnZWRfYWRfcG9kXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90ZWN0b25pY19hZF91eF9mb3JfaGFsZnRpbWVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RoaXJkX3BhcnR5X2luZm9cdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RvcHNvaWxfd3RhX2Zvcl9oYWxmdGltZV9saXZlX2luZnJhXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfbWVkaWFfc2Vzc2lvbl9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3dlYl9zY2hlZHVsZXJfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfd25faW5mb2NhcmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV95dF9hdGFfaWZyYW1lX2F1dGh1c2VyXHUwMDNkdHJ1ZVx1MDAyNmVycm9yX21lc3NhZ2VfZm9yX2dzdWl0ZV9uZXR3b3JrX3Jlc3RyaWN0aW9uc1x1MDAzZHRydWVcdTAwMjZleHBvcnRfbmV0d29ya2xlc3Nfb3B0aW9uc1x1MDAzZHRydWVcdTAwMjZleHRlcm5hbF9mdWxsc2NyZWVuX3dpdGhfZWR1XHUwMDNkdHJ1ZVx1MDAyNmZhc3RfYXV0b25hdl9pbl9iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmZldGNoX2F0dF9pbmRlcGVuZGVudGx5XHUwMDNkdHJ1ZVx1MDAyNmZpbGxfc2luZ2xlX3ZpZGVvX3dpdGhfbm90aWZ5X3RvX2xhc3JcdTAwM2R0cnVlXHUwMDI2ZmlsdGVyX3ZwOV9mb3JfY3NkYWlcdTAwM2R0cnVlXHUwMDI2Zml4X2Fkc190cmFja2luZ19mb3Jfc3dmX2NvbmZpZ19kZXByZWNhdGlvbl9td2ViXHUwMDNkdHJ1ZVx1MDAyNmdjZl9jb25maWdfc3RvcmVfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZnZWxfcXVldWVfdGltZW91dF9tYXhfbXNcdTAwM2QzMDAwMDBcdTAwMjZncGFfc3BhcmtsZXNfdGVuX3BlcmNlbnRfbGF5ZXJcdTAwM2R0cnVlXHUwMDI2Z3ZpX2NoYW5uZWxfY2xpZW50X3NjcmVlblx1MDAzZHRydWVcdTAwMjZoNV9jb21wYW5pb25fZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX2dlbmVyaWNfZXJyb3JfbG9nZ2luZ19ldmVudFx1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfdW5pZmllZF9jc2lfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZoNV9pbnBsYXllcl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9yZXNldF9jYWNoZV9hbmRfZmlsdGVyX2JlZm9yZV91cGRhdGVfbWFzdGhlYWRcdTAwM2R0cnVlXHUwMDI2aGVhdHNlZWtlcl9kZWNvcmF0aW9uX3RocmVzaG9sZFx1MDAzZDAuMFx1MDAyNmhmcl9kcm9wcGVkX2ZyYW1lcmF0ZV9mYWxsYmFja190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aGlkZV9lbmRwb2ludF9vdmVyZmxvd19vbl95dGRfZGlzcGxheV9hZF9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZodG1sNV9hZF90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2Fkc19wcmVyb2xsX2xvY2tfdGltZW91dF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfYWxsb3dfZGlzY29udGlndW91c19zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWxsb3dfdmlkZW9fa2V5ZnJhbWVfd2l0aG91dF9hdWRpb1x1MDAzZHRydWVcdTAwMjZodG1sNV9hdHRhY2hfbnVtX3JhbmRvbV9ieXRlc190b19iYW5kYWlkXHUwMDNkMFx1MDAyNmh0bWw1X2F0dGFjaF9wb190b2tlbl90b19iYW5kYWlkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F1dG9uYXZfY2FwX2lkbGVfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9hdXRvbmF2X3F1YWxpdHlfY2FwXHUwMDNkNzIwXHUwMDI2aHRtbDVfYXV0b3BsYXlfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9ibG9ja19waXBfc2FmYXJpX2RlbGF5XHUwMDNkMFx1MDAyNmh0bWw1X2JtZmZfbmV3X2ZvdXJjY19jaGVja1x1MDAzZHRydWVcdTAwMjZodG1sNV9jb2JhbHRfZGVmYXVsdF9idWZmZXJfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWF4X3NpemVfZm9yX2ltbWVkX2pvYlx1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWluX3Byb2Nlc3Nvcl9jbnRfdG9fb2ZmbG9hZF9hbGdvXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9vdmVycmlkZV9xdWljXHUwMDNkMFx1MDAyNmh0bWw1X2NvbnN1bWVfbWVkaWFfYnl0ZXNfc2xpY2VfaW5mb3NcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVfZHVwZV9jb250ZW50X3ZpZGVvX2xvYWRzX2luX2xpZmVjeWNsZV9hcGlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVidWdfZGF0YV9sb2dfcHJvYmFiaWxpdHlcdTAwM2QwLjFcdTAwMjZodG1sNV9kZWNvZGVfdG9fdGV4dHVyZV9jYXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVmYXVsdF9hZF9nYWluXHUwMDNkMC41XHUwMDI2aHRtbDVfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9hZF9tb2R1bGVfbXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfZmV0Y2hfYXR0X21zXHUwMDNkMTAwMFx1MDAyNmh0bWw1X2RlZmVyX21vZHVsZXNfZGVsYXlfdGltZV9taWxsaXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9jb3VudFx1MDAzZDFcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2RlbGF5X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X2RlcHJlY2F0ZV92aWRlb190YWdfcG9vbFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZXNrdG9wX3ZyMTgwX2FsbG93X3Bhbm5pbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGZfZG93bmdyYWRlX3RocmVzaFx1MDAzZDAuMlx1MDAyNmh0bWw1X2Rpc2FibGVfY3NpX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbW92ZV9wc3NoX3RvX21vb3ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9ub25fY29udGlndW91c1x1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNwbGF5ZWRfZnJhbWVfcmF0ZV9kb3duZ3JhZGVfdGhyZXNob2xkXHUwMDNkNDVcdTAwMjZodG1sNV9kcm1fY2hlY2tfYWxsX2tleV9lcnJvcl9zdGF0ZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZHJtX2NwaV9saWNlbnNlX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hZHNfY2xpZW50X21vbml0b3JpbmdfbG9nX3R2XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jYXB0aW9uX2NoYW5nZXNfZm9yX21vc2FpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2xpZW50X2hpbnRzX292ZXJyaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jb21wb3NpdGVfZW1iYXJnb1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZWFjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZW1iZWRkZWRfcGxheWVyX3Zpc2liaWxpdHlfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbm9uX25vdGlmeV9jb21wb3NpdGVfdm9kX2xzYXJfcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfc2luZ2xlX3ZpZGVvX3ZvZF9pdmFyX29uX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZGFzaFx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19lbmNyeXB0ZWRfdnA5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfYWxjXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfZmFzdF9saW5lYXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5jb3VyYWdlX2FycmF5X2NvYWxlc2NpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2FwbGVzc19lbmRlZF90cmFuc2l0aW9uX2J1ZmZlcl9tc1x1MDAzZDIwMFx1MDAyNmh0bWw1X2dlbmVyYXRlX3Nlc3Npb25fcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2xfZnBzX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZodG1sNV9oZGNwX3Byb2Jpbmdfc3RyZWFtX3VybFx1MDAzZFx1MDAyNmh0bWw1X2hmcl9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QxLjBcdTAwMjZodG1sNV9pZGxlX3JhdGVfbGltaXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX2ZhaXJwbGF5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9wbGF5cmVhZHlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3dpZGV2aW5lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczRfc2Vla19hYm92ZV96ZXJvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczdfZm9yY2VfcGxheV9vbl9zdGFsbFx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3NfZm9yY2Vfc2Vla190b196ZXJvX29uX3N0b3BcdTAwM2R0cnVlXHUwMDI2aHRtbDVfanVtYm9fbW9iaWxlX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDMuMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9ub25zdHJlYW1pbmdfbWZmYV9tc1x1MDAzZDQwMDBcdTAwMjZodG1sNV9qdW1ib191bGxfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMS4zXHUwMDI2aHRtbDVfbGljZW5zZV9jb25zdHJhaW50X2RlbGF5XHUwMDNkNTAwMFx1MDAyNmh0bWw1X2xpdmVfYWJyX2hlYWRfbWlzc19mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYWJyX3JlcHJlZGljdF9mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYnl0ZXJhdGVfZmFjdG9yX2Zvcl9yZWFkYWhlYWRcdTAwM2QxLjNcdTAwMjZodG1sNV9saXZlX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9saXZlX25vcm1hbF9sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2xpdmVfdWx0cmFfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xvZ19hdWRpb19hYnJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX2V4cGVyaW1lbnRfaWRfZnJvbV9wbGF5ZXJfcmVzcG9uc2VfdG9fY3RtcFx1MDAzZFx1MDAyNmh0bWw1X2xvZ19maXJzdF9zc2RhaV9yZXF1ZXN0c19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19yZWJ1ZmZlcl9ldmVudHNcdTAwM2Q1XHUwMDI2aHRtbDVfbG9nX3NzZGFpX2ZhbGxiYWNrX2Fkc1x1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfdHJpZ2dlcl9ldmVudHNfd2l0aF9kZWJ1Z19kYXRhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX3RocmVzaG9sZF9tc1x1MDAzZDMwMDAwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3NlZ19kcmlmdF9saW1pdF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc191bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3ZwOV9vdGZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWF4X2RyaWZ0X3Blcl90cmFja19zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWF4X2hlYWRtX2Zvcl9zdHJlYW1pbmdfeGhyXHUwMDNkMFx1MDAyNmh0bWw1X21heF9saXZlX2R2cl93aW5kb3dfcGx1c19tYXJnaW5fc2Vjc1x1MDAzZDQ2ODAwLjBcdTAwMjZodG1sNV9tYXhfcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21heF9yZWRpcmVjdF9yZXNwb25zZV9sZW5ndGhcdTAwM2Q4MTkyXHUwMDI2aHRtbDVfbWF4X3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21heF9zb3VyY2VfYnVmZmVyX2FwcGVuZF9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X21heGltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9tZWRpYV9mdWxsc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21mbF9leHRlbmRfbWF4X3JlcXVlc3RfdGltZVx1MDAzZHRydWVcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9jYXBfc2Vjc1x1MDAzZDYwXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9taW5fc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfYWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbm9fcGxhY2Vob2xkZXJfcm9sbGJhY2tzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vbl9uZXR3b3JrX3JlYnVmZmVyX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X25vbl9vbmVzaWVfYXR0YWNoX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vdF9yZWdpc3Rlcl9kaXNwb3NhYmxlc193aGVuX2NvcmVfbGlzdGVuc1x1MDAzZHRydWVcdTAwMjZodG1sNV9vZmZsaW5lX2ZhaWx1cmVfcmV0cnlfbGltaXRcdTAwM2QyXHUwMDI2aHRtbDVfb25lc2llX2RlZmVyX2NvbnRlbnRfbG9hZGVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9ob3N0X3JhY2luZ19jYXBfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2lnbm9yZV9pbm5lcnR1YmVfYXBpX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbGl2ZV90dGxfc2Vjc1x1MDAzZDhcdTAwMjZodG1sNV9vbmVzaWVfbm9uemVyb19wbGF5YmFja19zdGFydFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbm90aWZ5X2N1ZXBvaW50X21hbmFnZXJfb25fY29tcGxldGlvblx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9jb29sZG93bl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9pbnRlcnZhbF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9tYXhfbGFjdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlcXVlc3RfdGltZW91dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9vbmVzaWVfc3RpY2t5X3NlcnZlcl9zaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BhdXNlX29uX25vbmZvcmVncm91bmRfcGxhdGZvcm1fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlYWtfc2hhdmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZl9jYXBfb3ZlcnJpZGVfc3RpY2t5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2NhcF9mbG9vclx1MDAzZDM2MFx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2ltcGFjdF9wcm9maWxpbmdfdGltZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcGVyc2VydmVfYXYxX3BlcmZfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX21pbmltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9wbGF5ZXJfYXV0b25hdl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXllcl9keW5hbWljX2JvdHRvbV9ncmFkaWVudFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfbWluX2J1aWxkX2NsXHUwMDNkLTFcdTAwMjZodG1sNV9wbGF5ZXJfcHJlbG9hZF9hZF9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcG9zdF9pbnRlcnJ1cHRfcmVhZGFoZWFkXHUwMDNkMjBcdTAwMjZodG1sNV9wcmVmZXJfc2VydmVyX2J3ZTNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcHJlbG9hZF93YWl0X3RpbWVfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Byb2JlX3ByaW1hcnlfZGVsYXlfYmFzZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9wcm9jZXNzX2FsbF9lbmNyeXB0ZWRfZXZlbnRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3FvZV9saF9tYXhfcmVwb3J0X2NvdW50XHUwMDNkMFx1MDAyNmh0bWw1X3FvZV9saF9taW5fZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfcXVlcnlfc3dfc2VjdXJlX2NyeXB0b19mb3JfYW5kcm9pZFx1MDAzZHRydWVcdTAwMjZodG1sNV9yYW5kb21fcGxheWJhY2tfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X3JlY29nbml6ZV9wcmVkaWN0X3N0YXJ0X2N1ZV9wb2ludFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfY29tbWFuZF90cmlnZ2VyZWRfY29tcGFuaW9uc1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfbm90X3NlcnZhYmxlX2NoZWNrX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVuYW1lX2FwYnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X2ZhdGFsX2RybV9yZXN0cmljdGVkX2Vycm9yX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X3Nsb3dfYWRzX2FzX2Vycm9yXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfb25seV9oZHJfb3Jfc2RyX2tleXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVxdWVzdF9zaXppbmdfbXVsdGlwbGllclx1MDAzZDAuOFx1MDAyNmh0bWw1X3Jlc2V0X21lZGlhX3N0cmVhbV9vbl91bnJlc3VtYWJsZV9zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVzb3VyY2VfYmFkX3N0YXR1c19kZWxheV9zY2FsaW5nXHUwMDNkMS41XHUwMDI2aHRtbDVfcmVzdHJpY3Rfc3RyZWFtaW5nX3hocl9vbl9zcWxlc3NfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2FmYXJpX2Rlc2t0b3BfZW1lX21pbl92ZXJzaW9uXHUwMDNkMFx1MDAyNmh0bWw1X3NhbXN1bmdfa2FudF9saW1pdF9tYXhfYml0cmF0ZVx1MDAzZDBcdTAwMjZodG1sNV9zZWVrX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2Q4MDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9kZWxheV9tc1x1MDAzZDEyMDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfYnVmZmVyX3JhbmdlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX3Zyc19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2NmbFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfc2V0X2NtdF9kZWxheV9tc1x1MDAzZDIwMDBcdTAwMjZodG1sNV9zZWVrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NlcnZlcl9zdGl0Y2hlZF9kYWlfZGVjb3JhdGVkX3VybF9yZXRyeV9saW1pdFx1MDAzZDVcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2dyb3VwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Nlc3Npb25fcG9fdG9rZW5faW50ZXJ2YWxfdGltZV9tc1x1MDAzZDkwMDAwMFx1MDAyNmh0bWw1X3NraXBfb29iX3N0YXJ0X3NlY29uZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2tpcF9zbG93X2FkX2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9za2lwX3N1Yl9xdWFudHVtX2Rpc2NvbnRpbnVpdHlfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfbm9fbWVkaWFfc291cmNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfdGltZW91dF9kZWxheV9tc1x1MDAzZDIwMDAwXHUwMDI2aHRtbDVfc3NkYWlfYWRmZXRjaF9keW5hbWljX3RpbWVvdXRfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfc3NkYWlfZW5hYmxlX25ld19zZWVrX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N0YXRlZnVsX2F1ZGlvX21pbl9hZGp1c3RtZW50X3ZhbHVlXHUwMDNkMFx1MDAyNmh0bWw1X3N0YXRpY19hYnJfcmVzb2x1dGlvbl9zaGVsZlx1MDAzZDBcdTAwMjZodG1sNV9zdG9yZV94aHJfaGVhZGVyc19yZWFkYWJsZVx1MDAzZHRydWVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9sb2FkX3NwZWVkX2NoZWNrX2ludGVydmFsXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuMjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzX29uX3RpbWVvdXRcdTAwM2QwLjFcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fbG9hZF9zcGVlZFx1MDAzZDEuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3NlZWtfbGF0ZW5jeV9mdWRnZVx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldF9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90aW1lb3V0X3NlY3NcdTAwM2QyLjBcdTAwMjZodG1sNV91Z2NfbGl2ZV9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91Z2Nfdm9kX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VucmVwb3J0ZWRfc2Vla19yZXNlZWtfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfdW5yZXN0cmljdGVkX2xheWVyX2hpZ2hfcmVzX2xvZ2dpbmdfcGVyY2VudFx1MDAzZDAuMFx1MDAyNmh0bWw1X3VybF9wYWRkaW5nX2xlbmd0aFx1MDAzZDBcdTAwMjZodG1sNV91cmxfc2lnbmF0dXJlX2V4cGlyeV90aW1lX2hvdXJzXHUwMDNkMFx1MDAyNmh0bWw1X3VzZV9wb3N0X2Zvcl9tZWRpYVx1MDAzZHRydWVcdTAwMjZodG1sNV91c2VfdW1wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ZpZGVvX3RiZF9taW5fa2JcdTAwM2QwXHUwMDI2aHRtbDVfdmlld3BvcnRfdW5kZXJzZW5kX21heGltdW1cdTAwM2QwLjBcdTAwMjZodG1sNV92b2x1bWVfc2xpZGVyX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2ViX2VuYWJsZV9oYWxmdGltZV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYnBvX2lkbGVfcHJpb3JpdHlfam9iXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvZmZsZV9yZXN1bWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29ya2Fyb3VuZF9kZWxheV90cmlnZ2VyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3l0dmxyX2VuYWJsZV9zaW5nbGVfc2VsZWN0X3N1cnZleVx1MDAzZHRydWVcdTAwMjZpZ25vcmVfb3ZlcmxhcHBpbmdfY3VlX3BvaW50c19vbl9lbmRlbWljX2xpdmVfaHRtbDVcdTAwM2R0cnVlXHUwMDI2aWxfdXNlX3ZpZXdfbW9kZWxfbG9nZ2luZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNmluaXRpYWxfZ2VsX2JhdGNoX3RpbWVvdXRcdTAwM2QyMDAwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2xpY2Vuc2Vfc3RhdHVzXHUwMDNkMFx1MDAyNml0ZHJtX2luamVjdGVkX2xpY2Vuc2Vfc2VydmljZV9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNml0ZHJtX3dpZGV2aW5lX2hhcmRlbmVkX3ZtcF9tb2RlXHUwMDNkbG9nXHUwMDI2anNvbl9jb25kZW5zZWRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2NvbW1hbmRfaGFuZGxlcl9jb21tYW5kX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNmtldmxhcl9kcm9wZG93bl9maXhcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2dlbF9lcnJvcl9yb3V0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX2V4cGFuZF90b3BcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfcGxheV9wYXVzZV9vbl9zY3JpbVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcGxheWJhY2tfYXNzb2NpYXRlZF9xdWV1ZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcXVldWVfdXNlX3VwZGF0ZV9hcGlcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NpbXBfc2hvcnRzX3Jlc2V0X3Njcm9sbFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfdmltaW9fdXNlX3NoYXJlZF9tb25pdG9yXHUwMDNkdHJ1ZVx1MDAyNmxpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNmxpdmVfZnJlc2NhX3YyXHUwMDNkdHJ1ZVx1MDAyNmxvZ19lcnJvcnNfdGhyb3VnaF9ud2xfb25fcmV0cnlcdTAwM2R0cnVlXHUwMDI2bG9nX2dlbF9jb21wcmVzc2lvbl9sYXRlbmN5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19oZWFydGJlYXRfd2l0aF9saWZlY3ljbGVzXHUwMDNkdHJ1ZVx1MDAyNmxvZ193ZWJfZW5kcG9pbnRfdG9fbGF5ZXJcdTAwM2R0cnVlXHUwMDI2bG9nX3dpbmRvd19vbmVycm9yX2ZyYWN0aW9uXHUwMDNkMC4xXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZVx1MDAzZHRydWVcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlX3VmcGhcdTAwM2R0cnVlXHUwMDI2bWF4X2JvZHlfc2l6ZV90b19jb21wcmVzc1x1MDAzZDUwMDAwMFx1MDAyNm1heF9wcmVmZXRjaF93aW5kb3dfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDBcdTAwMjZtYXhfcmVzb2x1dGlvbl9mb3Jfd2hpdGVfbm9pc2VcdTAwM2QzNjBcdTAwMjZtZHhfZW5hYmxlX3ByaXZhY3lfZGlzY2xvc3VyZV91aVx1MDAzZHRydWVcdTAwMjZtZHhfbG9hZF9jYXN0X2FwaV9ib290c3RyYXBfc2NyaXB0XHUwMDNkdHJ1ZVx1MDAyNm1pZ3JhdGVfZXZlbnRzX3RvX3RzXHUwMDNkdHJ1ZVx1MDAyNm1pbl9wcmVmZXRjaF9vZmZzZXRfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDEwXHUwMDI2bXVzaWNfZW5hYmxlX3NoYXJlZF9hdWRpb190aWVyX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfYzNfZW5kc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX2N1c3RvbV9jb250cm9sX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9za2lwcGFibGVzX29uX2ppb19waG9uZVx1MDAzZHRydWVcdTAwMjZtd2ViX211dGVkX2F1dG9wbGF5X2FuaW1hdGlvblx1MDAzZHNocmlua1x1MDAyNm13ZWJfbmF0aXZlX2NvbnRyb2xfaW5fZmF1eF9mdWxsc2NyZWVuX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrX3BvbGxpbmdfaW50ZXJ2YWxcdTAwM2QzMDAwMFx1MDAyNm5ldHdvcmtsZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrbGVzc19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNm5ld19jb2RlY3Nfc3RyaW5nX2FwaV91c2VzX2xlZ2FjeV9zdHlsZVx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mYXN0X29uX3VubG9hZFx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mcm9tX21lbW9yeV93aGVuX29ubGluZVx1MDAzZHRydWVcdTAwMjZvZmZsaW5lX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNnBhY2ZfbG9nZ2luZ19kZWxheV9taWxsaXNlY29uZHNfdGhyb3VnaF95YmZlX3R2XHUwMDNkMzAwMDBcdTAwMjZwYWdlaWRfYXNfaGVhZGVyX3dlYlx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWRzX3NldF9hZGZvcm1hdF9vbl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2FsbG93X2F1dG9uYXZfYWZ0ZXJfcGxheWxpc3RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Jvb3RzdHJhcF9tZXRob2RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RlZmVyX2NhcHRpb25fZGlzcGxheVx1MDAzZDEwMDBcdTAwMjZwbGF5ZXJfZGVzdHJveV9vbGRfdmVyc2lvblx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZG91YmxldGFwX3RvX3NlZWtcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuYWJsZV9wbGF5YmFja19wbGF5bGlzdF9jaGFuZ2VcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuZHNjcmVlbl9lbGxpcHNpc19maXhcdTAwM2R0cnVlXHUwMDI2cGxheWVyX3VuZGVybGF5X21pbl9wbGF5ZXJfd2lkdGhcdTAwM2Q3NjguMFx1MDAyNnBsYXllcl91bmRlcmxheV92aWRlb193aWR0aF9mcmFjdGlvblx1MDAzZDAuNlx1MDAyNnBsYXllcl93ZWJfY2FuYXJ5X3N0YWdlXHUwMDNkMFx1MDAyNnBsYXlyZWFkeV9maXJzdF9wbGF5X2V4cGlyYXRpb25cdTAwM2QtMVx1MDAyNnBvbHltZXJfYmFkX2J1aWxkX2xhYmVsc1x1MDAzZHRydWVcdTAwMjZwb2x5bWVyX2xvZ19wcm9wX2NoYW5nZV9vYnNlcnZlcl9wZXJjZW50XHUwMDNkMFx1MDAyNnBvbHltZXJfdmVyaWZpeV9hcHBfc3RhdGVcdTAwM2R0cnVlXHUwMDI2cHJlc2tpcF9idXR0b25fc3R5bGVfYWRzX2JhY2tlbmRcdTAwM2Rjb3VudGRvd25fbmV4dF90b190aHVtYm5haWxcdTAwMjZxb2VfbndsX2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZxb2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2cmVjb3JkX2FwcF9jcmFzaGVkX3dlYlx1MDAzZHRydWVcdTAwMjZyZXBsYWNlX3BsYXlhYmlsaXR5X3JldHJpZXZlcl9pbl93YXRjaFx1MDAzZHRydWVcdTAwMjZzY2hlZHVsZXJfdXNlX3JhZl9ieV9kZWZhdWx0XHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19oZWFkZXJfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX2ludGVyc3RpdGlhbF9tZXNzYWdlXHUwMDI2c2VsZl9wb2RkaW5nX2hpZ2hsaWdodF9ub25fZGVmYXVsdF9idXR0b25cdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZVx1MDAyNnNlbmRfY29uZmlnX2hhc2hfdGltZXJcdTAwM2QwXHUwMDI2c2V0X2ludGVyc3RpdGlhbF9hZHZlcnRpc2Vyc19xdWVzdGlvbl90ZXh0XHUwMDNkdHJ1ZVx1MDAyNnNob3J0X3N0YXJ0X3RpbWVfcHJlZmVyX3B1Ymxpc2hfaW5fd2F0Y2hfbG9nXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19tb2RlX3RvX3BsYXllcl9hcGlcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX25vX3N0b3BfdmlkZW9fY2FsbFx1MDAzZHRydWVcdTAwMjZzaG91bGRfY2xlYXJfdmlkZW9fZGF0YV9vbl9wbGF5ZXJfY3VlZF91bnN0YXJ0ZWRcdTAwM2R0cnVlXHUwMDI2c2ltcGx5X2VtYmVkZGVkX2VuYWJsZV9ib3RndWFyZFx1MDAzZHRydWVcdTAwMjZza2lwX2lubGluZV9tdXRlZF9saWNlbnNlX3NlcnZpY2VfY2hlY2tcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbnZhbGlkX3l0Y3NpX3RpY2tzXHUwMDNkdHJ1ZVx1MDAyNnNraXBfbHNfZ2VsX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNnNraXBfc2V0dGluZ19pbmZvX2luX2NzaV9kYXRhX29iamVjdFx1MDAzZHRydWVcdTAwMjZzbG93X2NvbXByZXNzaW9uc19iZWZvcmVfYWJhbmRvbl9jb3VudFx1MDAzZDRcdTAwMjZzcGVlZG1hc3Rlcl9jYW5jZWxsYXRpb25fbW92ZW1lbnRfZHBcdTAwM2QwXHUwMDI2c3BlZWRtYXN0ZXJfcGxheWJhY2tfcmF0ZVx1MDAzZDAuMFx1MDAyNnNwZWVkbWFzdGVyX3RvdWNoX2FjdGl2YXRpb25fbXNcdTAwM2QwXHUwMDI2c3RhcnRfY2xpZW50X2djZlx1MDAzZHRydWVcdTAwMjZzdGFydF9jbGllbnRfZ2NmX2Zvcl9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2c3RhcnRfc2VuZGluZ19jb25maWdfaGFzaFx1MDAzZHRydWVcdTAwMjZzdHJlYW1pbmdfZGF0YV9lbWVyZ2VuY3lfaXRhZ19ibGFja2xpc3RcdTAwM2RbXVx1MDAyNnN1YnN0aXR1dGVfYWRfY3BuX21hY3JvX2luX3NzZGFpXHUwMDNkdHJ1ZVx1MDAyNnN1cHByZXNzX2Vycm9yXzIwNF9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNnRyYW5zcG9ydF91c2Vfc2NoZWR1bGVyXHUwMDNkdHJ1ZVx1MDAyNnR2X3BhY2ZfbG9nZ2luZ19zYW1wbGVfcmF0ZVx1MDAzZDAuMDFcdTAwMjZ0dmh0bWw1X3VucGx1Z2dlZF9wcmVsb2FkX2NhY2hlX3NpemVcdTAwM2Q1XHUwMDI2dW5jb3Zlcl9hZF9iYWRnZV9vbl9SVExfdGlueV93aW5kb3dcdTAwM2R0cnVlXHUwMDI2dW5wbHVnZ2VkX2RhaV9saXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZ1bnBsdWdnZWRfdHZodG1sNV92aWRlb19wcmVsb2FkX29uX2ZvY3VzX2RlbGF5X21zXHUwMDNkMFx1MDAyNnVwZGF0ZV9sb2dfZXZlbnRfY29uZmlnXHUwMDNkdHJ1ZVx1MDAyNnVzZV9hY2Nlc3NpYmlsaXR5X2RhdGFfb25fZGVza3RvcF9wbGF5ZXJfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9jb3JlX3NtXHUwMDNkdHJ1ZVx1MDAyNnVzZV9pbmxpbmVkX3BsYXllcl9ycGNcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19jbWxcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19pbl9tZW1vcnlfc3RvcmFnZVx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9pbml0aWFsaXphdGlvblx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zYXdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc3R3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3d0c1x1MDAzZHRydWVcdTAwMjZ1c2VfcGxheWVyX2FidXNlX2JnX2xpYnJhcnlcdTAwM2R0cnVlXHUwMDI2dXNlX3Byb2ZpbGVwYWdlX2V2ZW50X2xhYmVsX2luX2Nhcm91c2VsX3BsYXliYWNrc1x1MDAzZHRydWVcdTAwMjZ1c2VfcmVxdWVzdF90aW1lX21zX2hlYWRlclx1MDAzZHRydWVcdTAwMjZ1c2Vfc2Vzc2lvbl9iYXNlZF9zYW1wbGluZ1x1MDAzZHRydWVcdTAwMjZ1c2VfdHNfdmlzaWJpbGl0eWxvZ2dlclx1MDAzZHRydWVcdTAwMjZ2YXJpYWJsZV9idWZmZXJfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZ2ZXJpZnlfYWRzX2l0YWdfZWFybHlcdTAwM2R0cnVlXHUwMDI2dnA5X2RybV9saXZlXHUwMDNkdHJ1ZVx1MDAyNnZzc19maW5hbF9waW5nX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnZzc19waW5nc191c2luZ19uZXR3b3JrbGVzc1x1MDAzZHRydWVcdTAwMjZ2c3NfcGxheWJhY2tfdXNlX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9hcGlfdXJsXHUwMDNkdHJ1ZVx1MDAyNndlYl9hc3luY19jb250ZXh0X3Byb2Nlc3Nvcl9pbXBsXHUwMDNkc3RhbmRhbG9uZVx1MDAyNndlYl9jaW5lbWF0aWNfd2F0Y2hfc2V0dGluZ3NcdTAwM2R0cnVlXHUwMDI2d2ViX2NsaWVudF92ZXJzaW9uX292ZXJyaWRlXHUwMDNkXHUwMDI2d2ViX2RlZHVwZV92ZV9ncmFmdGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZGVwcmVjYXRlX3NlcnZpY2VfYWpheF9tYXBfZGVwZW5kZW5jeVx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2Vycm9yXzIwNFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2luc3RyZWFtX2Fkc19saW5rX2RlZmluaXRpb25fYTExeV9idWdmaXhcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV92b3pfYXVkaW9fZmVlZGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX2ZpeF9maW5lX3NjcnViYmluZ19kcmFnXHUwMDNkdHJ1ZVx1MDAyNndlYl9mb3JlZ3JvdW5kX2hlYXJ0YmVhdF9pbnRlcnZhbF9tc1x1MDAzZDI4MDAwXHUwMDI2d2ViX2ZvcndhcmRfY29tbWFuZF9vbl9wYmpcdTAwM2R0cnVlXHUwMDI2d2ViX2dlbF9kZWJvdW5jZV9tc1x1MDAzZDYwMDAwXHUwMDI2d2ViX2dlbF90aW1lb3V0X2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfaW5saW5lX3BsYXllcl9ub19wbGF5YmFja191aV9jbGlja19oYW5kbGVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9rZXlfbW9tZW50c19tYXJrZXJzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dfbWVtb3J5X3RvdGFsX2tieXRlc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nZ2luZ19tYXhfYmF0Y2hcdTAwM2QxNTBcdTAwMjZ3ZWJfbW9kZXJuX2Fkc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zX2JsX3N1cnZleVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3NjcnViYmVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlX3N0eWxlXHUwMDNkZmlsbGVkXHUwMDI2d2ViX25ld19hdXRvbmF2X2NvdW50ZG93blx1MDAzZHRydWVcdTAwMjZ3ZWJfb25lX3BsYXRmb3JtX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9vcF9zaWduYWxfdHlwZV9iYW5saXN0XHUwMDNkW11cdTAwMjZ3ZWJfcGF1c2VkX29ubHlfbWluaXBsYXllcl9zaG9ydGN1dF9leHBhbmRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfbG9nX2N0dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF92ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FkZF92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdG9fb3V0Ym91bmRfbGlua3NcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hbHdheXNfZW5hYmxlX2F1dG9fdHJhbnNsYXRpb25cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hcGlfbG9nZ2luZ19mcmFjdGlvblx1MDAzZDAuMDFcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfZW1wdHlfc3VnZ2VzdGlvbnNfZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl90b2dnbGVfYWx3YXlzX2xpc3Rlblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdXNlX3NlcnZlcl9wcm92aWRlZF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2NhcHRpb25fbGFuZ3VhZ2VfcHJlZmVyZW5jZV9zdGlja2luZXNzX2R1cmF0aW9uXHUwMDNkMzBcdTAwMjZ3ZWJfcGxheWVyX2RlY291cGxlX2F1dG9uYXZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9kaXNhYmxlX2lubGluZV9zY3J1YmJpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZWFybHlfd2FybmluZ19zbmFja2Jhclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9mZWF0dXJlZF9wcm9kdWN0X2Jhbm5lcl9vbl9kZXNrdG9wXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX2luX2g1X2FwaVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9wbGF5YmFja19jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pbm5lcnR1YmVfcGxheWxpc3RfdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaXBwX2NhbmFyeV90eXBlX2Zvcl9sb2dnaW5nXHUwMDNkXHUwMDI2d2ViX3BsYXllcl9saXZlX21vbml0b3JfZW52XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbG9nX2NsaWNrX2JlZm9yZV9nZW5lcmF0aW5nX3ZlX2NvbnZlcnNpb25fcGFyYW1zXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbW92ZV9hdXRvbmF2X3RvZ2dsZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX211c2ljX3Zpc3VhbGl6ZXJfdHJlYXRtZW50XHUwMDNkZmFrZVx1MDAyNndlYl9wbGF5ZXJfbXV0YWJsZV9ldmVudF9sYWJlbFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX25pdHJhdGVfcHJvbW9fdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX29mZmxpbmVfcGxheWxpc3RfYXV0b19yZWZyZXNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfcmVzcG9uc2VfcGxheWJhY2tfdHJhY2tpbmdfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlZWtfY2hhcHRlcnNfYnlfc2hvcnRjdXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZW50aW5lbF9pc191bmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG91bGRfaG9ub3JfaW5jbHVkZV9hc3Jfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3dfbXVzaWNfaW5fdGhpc192aWRlb19ncmFwaGljXHUwMDNkdmlkZW9fdGh1bWJuYWlsXHUwMDI2d2ViX3BsYXllcl9zbWFsbF9oYnBfc2V0dGluZ3NfbWVudVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NzX2RhaV9hZF9mZXRjaGluZ190aW1lb3V0X21zXHUwMDNkMTUwMDBcdTAwMjZ3ZWJfcGxheWVyX3NzX21lZGlhX3RpbWVfb2Zmc2V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG9waWZ5X3N1YnRpdGxlc19mb3Jfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG91Y2hfbW9kZV9pbXByb3ZlbWVudHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90cmFuc2Zlcl90aW1lb3V0X3RocmVzaG9sZF9tc1x1MDAzZDEwODAwMDAwXHUwMDI2d2ViX3BsYXllcl91bnNldF9kZWZhdWx0X2Nzbl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdXNlX25ld19hcGlfZm9yX3F1YWxpdHlfcHVsbGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl92ZV9jb252ZXJzaW9uX2ZpeGVzX2Zvcl9jaGFubmVsX2luZm9cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZV9wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wcmVmZXRjaF9wcmVsb2FkX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNndlYl9yb3VuZGVkX3RodW1ibmFpbHNcdTAwM2R0cnVlXHUwMDI2d2ViX3NldHRpbmdzX21lbnVfaWNvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X21ldGhvZFx1MDAzZDBcdTAwMjZ3ZWJfeXRfY29uZmlnX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2d2lsX2ljb25fcmVuZGVyX3doZW5faWRsZVx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfY2xlYW5fdXBfYWZ0ZXJfZW50aXR5X21pZ3JhdGlvblx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfZW5hYmxlX2Rvd25sb2FkX3N0YXR1c1x1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfcGxheWxpc3Rfb3B0aW1pemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2NsZWFyX2VtYmVkZGVkX3BsYXllclx1MDAzZHRydWVcdTAwMjZ5dGlkYl9mZXRjaF9kYXRhc3luY19pZHNfZm9yX2RhdGFfY2xlYW51cFx1MDAzZHRydWVcdTAwMjZ5dGlkYl9yZW1ha2VfZGJfcmV0cmllc1x1MDAzZDFcdTAwMjZ5dGlkYl9yZW9wZW5fZGJfcmV0cmllc1x1MDAzZDBcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0XHUwMDNkMC4wMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfc2Vzc2lvblx1MDAzZDAuMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfdHJhbnNhY3Rpb25cdTAwM2QwLjEiLCJjc3BOb25jZSI6Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiLCJjYW5hcnlTdGF0ZSI6Im5vbmUiLCJlbmFibGVDc2lMb2dnaW5nIjp0cnVlLCJjc2lQYWdlVHlwZSI6ImNoYW5uZWxzIiwiZGF0YXN5bmNJZCI6IlYyMDIxN2ZjNnx8In0sIldFQl9QTEFZRVJfQ09OVEVYVF9DT05GSUdfSURfS0VWTEFSX1BMQVlMSVNUX09WRVJWSUVXIjp7InJvb3RFbGVtZW50SWQiOiJjNC1wbGF5ZXIiLCJqc1VybCI6Ii9zL3BsYXllci9iMTI4ZGRhMC9wbGF5ZXJfaWFzLnZmbHNldC9mcl9GUi9iYXNlLmpzIiwiY3NzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3d3dy1wbGF5ZXIuY3NzIiwiY29udGV4dElkIjoiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfUExBWUxJU1RfT1ZFUlZJRVciLCJldmVudExhYmVsIjoicGxheWxpc3RvdmVydmlldyIsImNvbnRlbnRSZWdpb24iOiJGUiIsImhsIjoiZnJfRlIiLCJob3N0TGFuZ3VhZ2UiOiJmciIsInBsYXllclN0eWxlIjoiZGVza3RvcC1wb2x5bWVyIiwiaW5uZXJ0dWJlQXBpS2V5IjoiQUl6YVN5QU9fRkoyU2xxVThRNFNURUhMR0NpbHdfWTlfMTFxY1c4IiwiaW5uZXJ0dWJlQXBpVmVyc2lvbiI6InYxIiwiaW5uZXJ0dWJlQ29udGV4dENsaWVudFZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIiwiZGV2aWNlIjp7ImJyYW5kIjoiIiwibW9kZWwiOiIiLCJwbGF0Zm9ybSI6IkRFU0tUT1AiLCJpbnRlcmZhY2VOYW1lIjoiV0VCIiwiaW50ZXJmYWNlVmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAifSwic2VyaWFsaXplZEV4cGVyaW1lbnRJZHMiOiIyMzk4MzI5NiwyNDAwNDY0NCwyNDAwNzI0NiwyNDAwNzYxMywyNDA4MDczOCwyNDEzNTMxMCwyNDM2MzExNCwyNDM2NDc4OSwyNDM2NTUzNCwyNDM2NjkxNywyNDM3Mjc2MSwyNDM3NTEwMSwyNDM3Njc4NSwyNDQxNTg2NCwyNDQxNjI5MCwyNDQzMzY3OSwyNDQzNzU3NywyNDQzOTM2MSwyNDQ0MzMzMSwyNDQ5OTUzMiwyNDUzMjg1NSwyNDU1MDQ1OCwyNDU1MDk1MSwyNDU1NTU2NywyNDU1ODY0MSwyNDU1OTMyNywyNDY5OTg5OSwzOTMyMzA3NCIsInNlcmlhbGl6ZWRFeHBlcmltZW50RmxhZ3MiOiJINV9hc3luY19sb2dnaW5nX2RlbGF5X21zXHUwMDNkMzAwMDAuMFx1MDAyNkg1X2VuYWJsZV9mdWxsX3BhY2ZfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZINV91c2VfYXN5bmNfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZhY3Rpb25fY29tcGFuaW9uX2NlbnRlcl9hbGlnbl9kZXNjcmlwdGlvblx1MDAzZHRydWVcdTAwMjZhZF9wb2RfZGlzYWJsZV9jb21wYW5pb25fcGVyc2lzdF9hZHNfcXVhbGl0eVx1MDAzZHRydWVcdTAwMjZhZGR0b19hamF4X2xvZ193YXJuaW5nX2ZyYWN0aW9uXHUwMDNkMC4xXHUwMDI2YWxpZ25fYWRfdG9fdmlkZW9fcGxheWVyX2xpZmVjeWNsZV9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZhbGxvd19saXZlX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X3BvbHRlcmd1c3RfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2YWxsb3dfc2tpcF9uZXR3b3JrbGVzc1x1MDAzZHRydWVcdTAwMjZhdHRfd2ViX3JlY29yZF9tZXRyaWNzXHUwMDNkdHJ1ZVx1MDAyNmF1dG9wbGF5X3RpbWVcdTAwM2Q4MDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfZnVsbHNjcmVlblx1MDAzZDMwMDBcdTAwMjZhdXRvcGxheV90aW1lX2Zvcl9tdXNpY19jb250ZW50XHUwMDNkMzAwMFx1MDAyNmJnX3ZtX3JlaW5pdF90aHJlc2hvbGRcdTAwM2Q3MjAwMDAwXHUwMDI2YmxvY2tlZF9wYWNrYWdlc19mb3Jfc3BzXHUwMDNkW11cdTAwMjZib3RndWFyZF9hc3luY19zbmFwc2hvdF90aW1lb3V0X21zXHUwMDNkMzAwMFx1MDAyNmNoZWNrX2FkX3VpX3N0YXR1c19mb3JfbXdlYl9zYWZhcmlcdTAwM2R0cnVlXHUwMDI2Y2hlY2tfbmF2aWdhdG9yX2FjY3VyYWN5X3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2Y2xlYXJfdXNlcl9wYXJ0aXRpb25lZF9sc1x1MDAzZHRydWVcdTAwMjZjbGllbnRfcmVzcGVjdF9hdXRvcGxheV9zd2l0Y2hfYnV0dG9uX3JlbmRlcmVyXHUwMDNkdHJ1ZVx1MDAyNmNvbXByZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZjb21wcmVzc2lvbl9kaXNhYmxlX3BvaW50XHUwMDNkMTBcdTAwMjZjb21wcmVzc2lvbl9wZXJmb3JtYW5jZV90aHJlc2hvbGRcdTAwM2QyNTBcdTAwMjZjc2lfb25fZ2VsXHUwMDNkdHJ1ZVx1MDAyNmRhc2hfbWFuaWZlc3RfdmVyc2lvblx1MDAzZDVcdTAwMjZkZWJ1Z19iYW5kYWlkX2hvc3RuYW1lXHUwMDNkXHUwMDI2ZGVidWdfc2hlcmxvZ191c2VybmFtZVx1MDAzZFx1MDAyNmRlbGF5X2Fkc19ndmlfY2FsbF9vbl9idWxsZWl0X2xpdmluZ19yb29tX21zXHUwMDNkMFx1MDAyNmRlcHJlY2F0ZV9jc2lfaGFzX2luZm9cdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3BhaXJfc2VydmxldF9lbmFibGVkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfY2hpbGRcdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19wYXJlbnRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9pbWFnZV9jdGFfbm9fYmFja2dyb3VuZFx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX2xvZ19pbWdfY2xpY2tfbG9jYXRpb25cdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9zcGFya2xlc19saWdodF9jdGFfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfY2hhbm5lbF9pZF9jaGVja19mb3Jfc3VzcGVuZGVkX2NoYW5uZWxzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfY2hpbGRfbm9kZV9hdXRvX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfZGVmZXJfYWRtb2R1bGVfb25fYWR2ZXJ0aXNlcl92aWRlb1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2ZlYXR1cmVzX2Zvcl9zdXBleFx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2xlZ2FjeV9kZXNrdG9wX3JlbW90ZV9xdWV1ZVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX21keF9jb25uZWN0aW9uX2luX21keF9tb2R1bGVfZm9yX211c2ljX3dlYlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX25ld19wYXVzZV9zdGF0ZTNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9wYWNmX2xvZ2dpbmdfZm9yX21lbW9yeV9saW1pdGVkX3R2XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcm91bmRpbmdfYWRfbm90aWZ5XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfc2ltcGxlX21peGVkX2RpcmVjdGlvbl9mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NzZGFpX29uX2Vycm9yc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3RhYmJpbmdfYmVmb3JlX2ZseW91dF9hZF9lbGVtZW50c19hcHBlYXJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90aHVtYm5haWxfcHJlbG9hZGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZGlzYWJsZV9wcm9ncmVzc19iYXJfY29udGV4dF9tZW51X2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc19lbmFibGVfYWxsb3dfd2F0Y2hfYWdhaW5fZW5kc2NyZWVuX2Zvcl9lbGlnaWJsZV9zaG9ydHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3ZlX2NvbnZlcnNpb25fcGFyYW1fcmVuYW1pbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfYXV0b3BsYXlfbm90X3N1cHBvcnRlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9jdWVfdmlkZW9fdW5wbGF5YWJsZV9maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfaG91c2VfYnJhbmRfYW5kX3l0X2NvZXhpc3RlbmNlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvYWRfcGxheWVyX2Zyb21fcGFnZV9zaG93XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvZ19zcGxheV9hc19hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dnaW5nX2V2ZW50X2hhbmRsZXJzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX21vYmlsZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfZHR0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9uZXdfY29udGV4dF9tZW51X3RyaWdnZXJpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGF1c2Vfb3ZlcmxheV93bl91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGVtX2RvbWFpbl9maXhfZm9yX2FkX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BmcF91bmJyYW5kZWRfZWxfZGVwcmVjYXRpb25cdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcmNhdF9hbGxvd2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcmVwbGFjZV91bmxvYWRfd19wYWdlaGlkZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9zY3JpcHRlZF9wbGF5YmFja19ibG9ja2VkX2xvZ2dpbmdfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3ZlX2NvbnZlcnNpb25fbG9nZ2luZ190cmFja2luZ19ub19hbGxvd19saXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfaGlkZV91bmZpbGxlZF9tb3JlX3ZpZGVvc19zdWdnZXN0aW9uc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2xpdGVfbW9kZVx1MDAzZDFcdTAwMjZlbWJlZHNfd2ViX253bF9kaXNhYmxlX25vY29va2llXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfc2hvcHBpbmdfb3ZlcmxheV9ub193YWl0X2Zvcl9wYWlkX2NvbnRlbnRfb3ZlcmxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3N5bnRoX2NoX2hlYWRlcnNfYmFubmVkX3VybHNfcmVnZXhcdTAwM2RcdTAwMjZlbmFibGVfYWJfcnBfaW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9hZF9jcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfYXBwX3Byb21vX2VuZGNhcF9lbWxfb25fdGFibGV0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jYXN0X2Zvcl93ZWJfdW5wbHVnZ2VkXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jYXN0X29uX211c2ljX3dlYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2xpZW50X3BhZ2VfaWRfaGVhZGVyX2Zvcl9maXJzdF9wYXJ0eV9waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfY2xpZW50X3NsaV9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9kaXNjcmV0ZV9saXZlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZF93ZWJfY2xpZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZF93ZWJfY2xpZW50X2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZHNfaWNvbl93ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2V2aWN0aW9uX3Byb3RlY3Rpb25fZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2dlbF9sb2dfY29tbWFuZHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X2luc3RyZWFtX3dhdGNoX25leHRfcGFyYW1zX29hcmxpYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfaDVfdmlkZW9fYWRzX29hcmxpYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfaGFuZGxlc19hY2NvdW50X21lbnVfc3dpdGNoZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2thYnVraV9jb21tZW50c19vbl9zaG9ydHNcdTAwM2RkaXNhYmxlZFx1MDAyNmVuYWJsZV9saXZlX3ByZW1pZXJlX3dlYl9wbGF5ZXJfaW5kaWNhdG9yXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9scl9ob21lX2luZmVlZF9hZHNfaW5saW5lX3BsYXliYWNrX3Byb2dyZXNzX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX213ZWJfZW5kY2FwX2NsaWNrYWJsZV9pY29uX2Rlc2NyaXB0aW9uXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9td2ViX2xpdmVzdHJlYW1fdWlfdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9uZXdfcGFpZF9wcm9kdWN0X3BsYWNlbWVudFx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl9zbG90X2FzZGVfcGxheWVyX2J5dGVfaDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90dl9mb3JfcGFnZV90b3BfZm9ybWF0c1x1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3lzZmVfdHZcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Bhc3Nfc2RjX2dldF9hY2NvdW50c19saXN0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wbF9yX2NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Bvc3RfYWRfcGVyY2VwdGlvbl9zdXJ2ZXlfZml4X29uX3R2aHRtbDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Bvc3RfYWRfcGVyY2VwdGlvbl9zdXJ2ZXlfaW5fdHZodG1sNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcHJlY2lzZV9lbWJhcmdvc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfc2VydmVyX3N0aXRjaGVkX2RhaVx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2hvcnRzX3BsYXllclx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2tpcF9hZF9ndWlkYW5jZV9wcm9tcHRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NraXBwYWJsZV9hZHNfZm9yX3VucGx1Z2dlZF9hZF9wb2RcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RlY3RvbmljX2FkX3V4X2Zvcl9oYWxmdGltZVx1MDAzZHRydWVcdTAwMjZlbmFibGVfdGhpcmRfcGFydHlfaW5mb1x1MDAzZHRydWVcdTAwMjZlbmFibGVfdG9wc29pbF93dGFfZm9yX2hhbGZ0aW1lX2xpdmVfaW5mcmFcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3dlYl9tZWRpYV9zZXNzaW9uX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZlbmFibGVfd2ViX3NjaGVkdWxlcl9zaWduYWxzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93bl9pbmZvY2FyZHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3l0X2F0YV9pZnJhbWVfYXV0aHVzZXJcdTAwM2R0cnVlXHUwMDI2ZXJyb3JfbWVzc2FnZV9mb3JfZ3N1aXRlX25ldHdvcmtfcmVzdHJpY3Rpb25zXHUwMDNkdHJ1ZVx1MDAyNmV4cG9ydF9uZXR3b3JrbGVzc19vcHRpb25zXHUwMDNkdHJ1ZVx1MDAyNmV4dGVybmFsX2Z1bGxzY3JlZW5fd2l0aF9lZHVcdTAwM2R0cnVlXHUwMDI2ZmFzdF9hdXRvbmF2X2luX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZmV0Y2hfYXR0X2luZGVwZW5kZW50bHlcdTAwM2R0cnVlXHUwMDI2ZmlsbF9zaW5nbGVfdmlkZW9fd2l0aF9ub3RpZnlfdG9fbGFzclx1MDAzZHRydWVcdTAwMjZmaWx0ZXJfdnA5X2Zvcl9jc2RhaVx1MDAzZHRydWVcdTAwMjZmaXhfYWRzX3RyYWNraW5nX2Zvcl9zd2ZfY29uZmlnX2RlcHJlY2F0aW9uX213ZWJcdTAwM2R0cnVlXHUwMDI2Z2NmX2NvbmZpZ19zdG9yZV9lbmFibGVkXHUwMDNkdHJ1ZVx1MDAyNmdlbF9xdWV1ZV90aW1lb3V0X21heF9tc1x1MDAzZDMwMDAwMFx1MDAyNmdwYV9zcGFya2xlc190ZW5fcGVyY2VudF9sYXllclx1MDAzZHRydWVcdTAwMjZndmlfY2hhbm5lbF9jbGllbnRfc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmg1X2NvbXBhbmlvbl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfZ2VuZXJpY19lcnJvcl9sb2dnaW5nX2V2ZW50XHUwMDNkdHJ1ZVx1MDAyNmg1X2VuYWJsZV91bmlmaWVkX2NzaV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmg1X2lucGxheWVyX2VuYWJsZV9hZGNwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmg1X3Jlc2V0X2NhY2hlX2FuZF9maWx0ZXJfYmVmb3JlX3VwZGF0ZV9tYXN0aGVhZFx1MDAzZHRydWVcdTAwMjZoZWF0c2Vla2VyX2RlY29yYXRpb25fdGhyZXNob2xkXHUwMDNkMC4wXHUwMDI2aGZyX2Ryb3BwZWRfZnJhbWVyYXRlX2ZhbGxiYWNrX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZoaWRlX2VuZHBvaW50X292ZXJmbG93X29uX3l0ZF9kaXNwbGF5X2FkX3JlbmRlcmVyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2FkX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfYWRzX3ByZXJvbGxfbG9ja190aW1lb3V0X2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9hbGxvd19kaXNjb250aWd1b3VzX3NsaWNlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9hbGxvd192aWRlb19rZXlmcmFtZV93aXRob3V0X2F1ZGlvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F0dGFjaF9udW1fcmFuZG9tX2J5dGVzX3RvX2JhbmRhaWRcdTAwM2QwXHUwMDI2aHRtbDVfYXR0YWNoX3BvX3Rva2VuX3RvX2JhbmRhaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYXV0b25hdl9jYXBfaWRsZV9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X2F1dG9uYXZfcXVhbGl0eV9jYXBcdTAwM2Q3MjBcdTAwMjZodG1sNV9hdXRvcGxheV9kZWZhdWx0X3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2Jsb2NrX3BpcF9zYWZhcmlfZGVsYXlcdTAwM2QwXHUwMDI2aHRtbDVfYm1mZl9uZXdfZm91cmNjX2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2NvYmFsdF9kZWZhdWx0X2J1ZmZlcl9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9tYXhfc2l6ZV9mb3JfaW1tZWRfam9iXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9taW5fcHJvY2Vzc29yX2NudF90b19vZmZsb2FkX2FsZ29cdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X292ZXJyaWRlX3F1aWNcdTAwM2QwXHUwMDI2aHRtbDVfY29uc3VtZV9tZWRpYV9ieXRlc19zbGljZV9pbmZvc1x1MDAzZHRydWVcdTAwMjZodG1sNV9kZV9kdXBlX2NvbnRlbnRfdmlkZW9fbG9hZHNfaW5fbGlmZWN5Y2xlX2FwaVx1MDAzZHRydWVcdTAwMjZodG1sNV9kZWJ1Z19kYXRhX2xvZ19wcm9iYWJpbGl0eVx1MDAzZDAuMVx1MDAyNmh0bWw1X2RlY29kZV90b190ZXh0dXJlX2NhcFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZWZhdWx0X2FkX2dhaW5cdTAwM2QwLjVcdTAwMjZodG1sNV9kZWZhdWx0X3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2RlZmVyX2FkX21vZHVsZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9mZXRjaF9hdHRfbXNcdTAwM2QxMDAwXHUwMDI2aHRtbDVfZGVmZXJfbW9kdWxlc19kZWxheV90aW1lX21pbGxpc1x1MDAzZDBcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2NvdW50XHUwMDNkMVx1MDAyNmh0bWw1X2RlbGF5ZWRfcmV0cnlfZGVsYXlfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfZGVwcmVjYXRlX3ZpZGVvX3RhZ19wb29sXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rlc2t0b3BfdnIxODBfYWxsb3dfcGFubmluZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9kZl9kb3duZ3JhZGVfdGhyZXNoXHUwMDNkMC4yXHUwMDI2aHRtbDVfZGlzYWJsZV9jc2lfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9tb3ZlX3Bzc2hfdG9fbW9vdlx1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNhYmxlX25vbl9jb250aWd1b3VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc3BsYXllZF9mcmFtZV9yYXRlX2Rvd25ncmFkZV90aHJlc2hvbGRcdTAwM2Q0NVx1MDAyNmh0bWw1X2RybV9jaGVja19hbGxfa2V5X2Vycm9yX3N0YXRlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9kcm1fY3BpX2xpY2Vuc2Vfa2V5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hYzNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2Fkc19jbGllbnRfbW9uaXRvcmluZ19sb2dfdHZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NhcHRpb25fY2hhbmdlc19mb3JfbW9zYWljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jbGllbnRfaGludHNfb3ZlcnJpZGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NvbXBvc2l0ZV9lbWJhcmdvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9lYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9lbWJlZGRlZF9wbGF5ZXJfdmlzaWJpbGl0eV9zaWduYWxzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9ub25fbm90aWZ5X2NvbXBvc2l0ZV92b2RfbHNhcl9wYWNmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9zaW5nbGVfdmlkZW9fdm9kX2l2YXJfb25fcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19kYXNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV90dm9zX2VuY3J5cHRlZF92cDlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3dpZGV2aW5lX2Zvcl9hbGNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3dpZGV2aW5lX2Zvcl9mYXN0X2xpbmVhclx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmNvdXJhZ2VfYXJyYXlfY29hbGVzY2luZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9nYXBsZXNzX2VuZGVkX3RyYW5zaXRpb25fYnVmZmVyX21zXHUwMDNkMjAwXHUwMDI2aHRtbDVfZ2VuZXJhdGVfc2Vzc2lvbl9wb190b2tlblx1MDAzZHRydWVcdTAwMjZodG1sNV9nbF9mcHNfdGhyZXNob2xkXHUwMDNkMFx1MDAyNmh0bWw1X2hkY3BfcHJvYmluZ19zdHJlYW1fdXJsXHUwMDNkXHUwMDI2aHRtbDVfaGZyX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2hpZ2hfcmVzX2xvZ2dpbmdfcGVyY2VudFx1MDAzZDEuMFx1MDAyNmh0bWw1X2lkbGVfcmF0ZV9saW1pdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9pbm5lcnR1YmVfaGVhcnRiZWF0c19mb3JfZmFpcnBsYXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3BsYXlyZWFkeVx1MDAzZHRydWVcdTAwMjZodG1sNV9pbm5lcnR1YmVfaGVhcnRiZWF0c19mb3Jfd2lkZXZpbmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW9zNF9zZWVrX2Fib3ZlX3plcm9cdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW9zN19mb3JjZV9wbGF5X29uX3N0YWxsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvc19mb3JjZV9zZWVrX3RvX3plcm9fb25fc3RvcFx1MDAzZHRydWVcdTAwMjZodG1sNV9qdW1ib19tb2JpbGVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMy4wXHUwMDI2aHRtbDVfanVtYm9fdWxsX25vbnN0cmVhbWluZ19tZmZhX21zXHUwMDNkNDAwMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRcdTAwM2QxLjNcdTAwMjZodG1sNV9saWNlbnNlX2NvbnN0cmFpbnRfZGVsYXlcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfbGl2ZV9hYnJfaGVhZF9taXNzX2ZyYWN0aW9uXHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9hYnJfcmVwcmVkaWN0X2ZyYWN0aW9uXHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9ieXRlcmF0ZV9mYWN0b3JfZm9yX3JlYWRhaGVhZFx1MDAzZDEuM1x1MDAyNmh0bWw1X2xpdmVfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfbWV0YWRhdGFfZml4XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xpdmVfbm9ybWFsX2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfbGl2ZV91bHRyYV9sb3dfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbG9nX2F1ZGlvX2Ficlx1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfZXhwZXJpbWVudF9pZF9mcm9tX3BsYXllcl9yZXNwb25zZV90b19jdG1wXHUwMDNkXHUwMDI2aHRtbDVfbG9nX2ZpcnN0X3NzZGFpX3JlcXVlc3RzX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX3JlYnVmZmVyX2V2ZW50c1x1MDAzZDVcdTAwMjZodG1sNV9sb2dfc3NkYWlfZmFsbGJhY2tfYWRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ190cmlnZ2VyX2V2ZW50c193aXRoX2RlYnVnX2RhdGFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl9qaWdnbGVfY210X2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfbmV3X2VsZW1fc2hvcnRzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfdGhyZXNob2xkX21zXHUwMDNkMzAwMDBcdTAwMjZodG1sNV9tYW5pZmVzdGxlc3Nfc2VnX2RyaWZ0X2xpbWl0X3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3VucGx1Z2dlZFx1MDAzZHRydWVcdTAwMjZodG1sNV9tYW5pZmVzdGxlc3NfdnA5X290Zlx1MDAzZHRydWVcdTAwMjZodG1sNV9tYXhfZHJpZnRfcGVyX3RyYWNrX3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9tYXhfaGVhZG1fZm9yX3N0cmVhbWluZ194aHJcdTAwM2QwXHUwMDI2aHRtbDVfbWF4X2xpdmVfZHZyX3dpbmRvd19wbHVzX21hcmdpbl9zZWNzXHUwMDNkNDY4MDAuMFx1MDAyNmh0bWw1X21heF9yZWFkYmVoaW5kX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfbWF4X3JlZGlyZWN0X3Jlc3BvbnNlX2xlbmd0aFx1MDAzZDgxOTJcdTAwMjZodG1sNV9tYXhfc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWF4X3NvdXJjZV9idWZmZXJfYXBwZW5kX3NpemVfaW5fYnl0ZXNcdTAwM2QwXHUwMDI2aHRtbDVfbWF4aW11bV9yZWFkYWhlYWRfc2Vjb25kc1x1MDAzZDAuMFx1MDAyNmh0bWw1X21lZGlhX2Z1bGxzY3JlZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWZsX2V4dGVuZF9tYXhfcmVxdWVzdF90aW1lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21pbl9yZWFkYmVoaW5kX2NhcF9zZWNzXHUwMDNkNjBcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21pbl9zZWxlY3RhYmxlX3F1YWxpdHlfb3JkaW5hbFx1MDAzZDBcdTAwMjZodG1sNV9taW5fc3RhcnR1cF9idWZmZXJlZF9hZF9tZWRpYV9kdXJhdGlvbl9zZWNzXHUwMDNkMS4yXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbmltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9ub19wbGFjZWhvbGRlcl9yb2xsYmFja3NcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbm9uX25ldHdvcmtfcmVidWZmZXJfZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfbm9uX29uZXNpZV9hdHRhY2hfcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfbm90X3JlZ2lzdGVyX2Rpc3Bvc2FibGVzX3doZW5fY29yZV9saXN0ZW5zXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29mZmxpbmVfZmFpbHVyZV9yZXRyeV9saW1pdFx1MDAzZDJcdTAwMjZodG1sNV9vbmVzaWVfZGVmZXJfY29udGVudF9sb2FkZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2hvc3RfcmFjaW5nX2NhcF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfaWdub3JlX2lubmVydHViZV9hcGlfa2V5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9saXZlX3R0bF9zZWNzXHUwMDNkOFx1MDAyNmh0bWw1X29uZXNpZV9ub256ZXJvX3BsYXliYWNrX3N0YXJ0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9ub3RpZnlfY3VlcG9pbnRfbWFuYWdlcl9vbl9jb21wbGV0aW9uXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9wcmV3YXJtX2Nvb2xkb3duX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9wcmV3YXJtX2ludGVydmFsX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9wcmV3YXJtX21heF9sYWN0X21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX3JlZGlyZWN0b3JfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVxdWVzdF90aW1lb3V0X21zXHUwMDNkMTAwMFx1MDAyNmh0bWw1X29uZXNpZV9zdGlja3lfc2VydmVyX3NpZGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGF1c2Vfb25fbm9uZm9yZWdyb3VuZF9wbGF0Zm9ybV9lcnJvcnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVha19zaGF2ZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wZXJmX2NhcF9vdmVycmlkZV9zdGlja3lcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZm9ybWFuY2VfY2FwX2Zsb29yXHUwMDNkMzYwXHUwMDI2aHRtbDVfcGVyZm9ybWFuY2VfaW1wYWN0X3Byb2ZpbGluZ190aW1lcl9tc1x1MDAzZDBcdTAwMjZodG1sNV9wZXJzZXJ2ZV9hdjFfcGVyZl9jYXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxhdGZvcm1fbWluaW11bV9yZWFkYWhlYWRfc2Vjb25kc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3BsYXllcl9hdXRvbmF2X2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxheWVyX2R5bmFtaWNfYm90dG9tX2dyYWRpZW50XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXllcl9taW5fYnVpbGRfY2xcdTAwM2QtMVx1MDAyNmh0bWw1X3BsYXllcl9wcmVsb2FkX2FkX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9wb3N0X2ludGVycnVwdF9yZWFkYWhlYWRcdTAwM2QyMFx1MDAyNmh0bWw1X3ByZWZlcl9zZXJ2ZXJfYndlM1x1MDAzZHRydWVcdTAwMjZodG1sNV9wcmVsb2FkX3dhaXRfdGltZV9zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfcHJvYmVfcHJpbWFyeV9kZWxheV9iYXNlX21zXHUwMDNkMFx1MDAyNmh0bWw1X3Byb2Nlc3NfYWxsX2VuY3J5cHRlZF9ldmVudHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcW9lX2xoX21heF9yZXBvcnRfY291bnRcdTAwM2QwXHUwMDI2aHRtbDVfcW9lX2xoX21pbl9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZodG1sNV9xdWVyeV9zd19zZWN1cmVfY3J5cHRvX2Zvcl9hbmRyb2lkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JhbmRvbV9wbGF5YmFja19jYXBcdTAwM2QwXHUwMDI2aHRtbDVfcmVjb2duaXplX3ByZWRpY3Rfc3RhcnRfY3VlX3BvaW50XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbW92ZV9jb21tYW5kX3RyaWdnZXJlZF9jb21wYW5pb25zXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbW92ZV9ub3Rfc2VydmFibGVfY2hlY2tfa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZW5hbWVfYXBic1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZXBvcnRfZmF0YWxfZHJtX3Jlc3RyaWN0ZWRfZXJyb3Jfa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZXBvcnRfc2xvd19hZHNfYXNfZXJyb3JcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVxdWVzdF9vbmx5X2hkcl9vcl9zZHJfa2V5c1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZXF1ZXN0X3NpemluZ19tdWx0aXBsaWVyXHUwMDNkMC44XHUwMDI2aHRtbDVfcmVzZXRfbWVkaWFfc3RyZWFtX29uX3VucmVzdW1hYmxlX3NsaWNlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZXNvdXJjZV9iYWRfc3RhdHVzX2RlbGF5X3NjYWxpbmdcdTAwM2QxLjVcdTAwMjZodG1sNV9yZXN0cmljdF9zdHJlYW1pbmdfeGhyX29uX3NxbGVzc19yZXF1ZXN0c1x1MDAzZHRydWVcdTAwMjZodG1sNV9zYWZhcmlfZGVza3RvcF9lbWVfbWluX3ZlcnNpb25cdTAwM2QwXHUwMDI2aHRtbDVfc2Ftc3VuZ19rYW50X2xpbWl0X21heF9iaXRyYXRlXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDgwMDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX2RlbGF5X21zXHUwMDNkMTIwMDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c19idWZmZXJfcmFuZ2VfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfdnJzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X21lZGlhX3NvdXJjZV9zaG9ydHNfcmV1c2VfY2ZsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NlZWtfbmV3X21lZGlhX3NvdXJjZV9zaG9ydHNfcmV1c2VfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19zZXRfY210X2RlbGF5X21zXHUwMDNkMjAwMFx1MDAyNmh0bWw1X3NlZWtfdGltZW91dF9kZWxheV9tc1x1MDAzZDIwMDAwXHUwMDI2aHRtbDVfc2VydmVyX3N0aXRjaGVkX2RhaV9kZWNvcmF0ZWRfdXJsX3JldHJ5X2xpbWl0XHUwMDNkNVx1MDAyNmh0bWw1X3NlcnZlcl9zdGl0Y2hlZF9kYWlfZ3JvdXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2Vzc2lvbl9wb190b2tlbl9pbnRlcnZhbF90aW1lX21zXHUwMDNkOTAwMDAwXHUwMDI2aHRtbDVfc2tpcF9vb2Jfc3RhcnRfc2Vjb25kc1x1MDAzZHRydWVcdTAwMjZodG1sNV9za2lwX3Nsb3dfYWRfZGVsYXlfbXNcdTAwM2QxNTAwMFx1MDAyNmh0bWw1X3NraXBfc3ViX3F1YW50dW1fZGlzY29udGludWl0eV9zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfc2xvd19zdGFydF9ub19tZWRpYV9zb3VyY2VfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2xvd19zdGFydF90aW1lb3V0X2RlbGF5X21zXHUwMDNkMjAwMDBcdTAwMjZodG1sNV9zc2RhaV9hZGZldGNoX2R5bmFtaWNfdGltZW91dF9tc1x1MDAzZDUwMDBcdTAwMjZodG1sNV9zc2RhaV9lbmFibGVfbmV3X3NlZWtfbG9naWNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3RhdGVmdWxfYXVkaW9fbWluX2FkanVzdG1lbnRfdmFsdWVcdTAwM2QwXHUwMDI2aHRtbDVfc3RhdGljX2Ficl9yZXNvbHV0aW9uX3NoZWxmXHUwMDNkMFx1MDAyNmh0bWw1X3N0b3JlX3hocl9oZWFkZXJzX3JlYWRhYmxlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX2xvYWRfc3BlZWRfY2hlY2tfaW50ZXJ2YWxcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzXHUwMDNkMC4yNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9idWZmZXJfaGVhbHRoX3NlY3Nfb25fdGltZW91dFx1MDAzZDAuMVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9sb2FkX3NwZWVkXHUwMDNkMS41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfc2Vla19sYXRlbmN5X2Z1ZGdlXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0X2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RpbWVvdXRfc2Vjc1x1MDAzZDIuMFx1MDAyNmh0bWw1X3VnY19saXZlX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VnY192b2RfYXVkaW9fNTFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdW5yZXBvcnRlZF9zZWVrX3Jlc2Vla19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV91bnJlc3RyaWN0ZWRfbGF5ZXJfaGlnaF9yZXNfbG9nZ2luZ19wZXJjZW50XHUwMDNkMC4wXHUwMDI2aHRtbDVfdXJsX3BhZGRpbmdfbGVuZ3RoXHUwMDNkMFx1MDAyNmh0bWw1X3VybF9zaWduYXR1cmVfZXhwaXJ5X3RpbWVfaG91cnNcdTAwM2QwXHUwMDI2aHRtbDVfdXNlX3Bvc3RfZm9yX21lZGlhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VzZV91bXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdmlkZW9fdGJkX21pbl9rYlx1MDAzZDBcdTAwMjZodG1sNV92aWV3cG9ydF91bmRlcnNlbmRfbWF4aW11bVx1MDAzZDAuMFx1MDAyNmh0bWw1X3ZvbHVtZV9zbGlkZXJfdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZodG1sNV93ZWJfZW5hYmxlX2hhbGZ0aW1lX3ByZXJvbGxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2VicG9faWRsZV9wcmlvcml0eV9qb2JcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29mZmxlX3Jlc3VtZVx1MDAzZHRydWVcdTAwMjZodG1sNV93b3JrYXJvdW5kX2RlbGF5X3RyaWdnZXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfeXR2bHJfZW5hYmxlX3NpbmdsZV9zZWxlY3Rfc3VydmV5XHUwMDNkdHJ1ZVx1MDAyNmlnbm9yZV9vdmVybGFwcGluZ19jdWVfcG9pbnRzX29uX2VuZGVtaWNfbGl2ZV9odG1sNVx1MDAzZHRydWVcdTAwMjZpbF91c2Vfdmlld19tb2RlbF9sb2dnaW5nX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2aW5pdGlhbF9nZWxfYmF0Y2hfdGltZW91dFx1MDAzZDIwMDBcdTAwMjZpbmplY3RlZF9saWNlbnNlX2hhbmRsZXJfZXJyb3JfY29kZVx1MDAzZDBcdTAwMjZpbmplY3RlZF9saWNlbnNlX2hhbmRsZXJfbGljZW5zZV9zdGF0dXNcdTAwM2QwXHUwMDI2aXRkcm1faW5qZWN0ZWRfbGljZW5zZV9zZXJ2aWNlX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aXRkcm1fd2lkZXZpbmVfaGFyZGVuZWRfdm1wX21vZGVcdTAwM2Rsb2dcdTAwMjZqc29uX2NvbmRlbnNlZF9yZXNwb25zZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfY29tbWFuZF9oYW5kbGVyX2NvbW1hbmRfYmFubGlzdFx1MDAzZFtdXHUwMDI2a2V2bGFyX2Ryb3Bkb3duX2ZpeFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfZ2VsX2Vycm9yX3JvdXRpbmdcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfZXhwYW5kX3RvcFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllcl9wbGF5X3BhdXNlX29uX3NjcmltXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9wbGF5YmFja19hc3NvY2lhdGVkX3F1ZXVlXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9xdWV1ZV91c2VfdXBkYXRlX2FwaVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc2ltcF9zaG9ydHNfcmVzZXRfc2Nyb2xsXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NtYXJ0X2Rvd25sb2Fkc19zZXR0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl92aW1pb191c2Vfc2hhcmVkX21vbml0b3JcdTAwM2R0cnVlXHUwMDI2bGl2ZV9jaHVua19yZWFkYWhlYWRcdTAwM2QzXHUwMDI2bGl2ZV9mcmVzY2FfdjJcdTAwM2R0cnVlXHUwMDI2bG9nX2Vycm9yc190aHJvdWdoX253bF9vbl9yZXRyeVx1MDAzZHRydWVcdTAwMjZsb2dfZ2VsX2NvbXByZXNzaW9uX2xhdGVuY3lcdTAwM2R0cnVlXHUwMDI2bG9nX2hlYXJ0YmVhdF93aXRoX2xpZmVjeWNsZXNcdTAwM2R0cnVlXHUwMDI2bG9nX3dlYl9lbmRwb2ludF90b19sYXllclx1MDAzZHRydWVcdTAwMjZsb2dfd2luZG93X29uZXJyb3JfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlXHUwMDNkdHJ1ZVx1MDAyNm1hbmlmZXN0bGVzc19wb3N0X2xpdmVfdWZwaFx1MDAzZHRydWVcdTAwMjZtYXhfYm9keV9zaXplX3RvX2NvbXByZXNzXHUwMDNkNTAwMDAwXHUwMDI2bWF4X3ByZWZldGNoX3dpbmRvd19zZWNfZm9yX2xpdmVzdHJlYW1fb3B0aW1pemF0aW9uXHUwMDNkMFx1MDAyNm1heF9yZXNvbHV0aW9uX2Zvcl93aGl0ZV9ub2lzZVx1MDAzZDM2MFx1MDAyNm1keF9lbmFibGVfcHJpdmFjeV9kaXNjbG9zdXJlX3VpXHUwMDNkdHJ1ZVx1MDAyNm1keF9sb2FkX2Nhc3RfYXBpX2Jvb3RzdHJhcF9zY3JpcHRcdTAwM2R0cnVlXHUwMDI2bWlncmF0ZV9ldmVudHNfdG9fdHNcdTAwM2R0cnVlXHUwMDI2bWluX3ByZWZldGNoX29mZnNldF9zZWNfZm9yX2xpdmVzdHJlYW1fb3B0aW1pemF0aW9uXHUwMDNkMTBcdTAwMjZtdXNpY19lbmFibGVfc2hhcmVkX2F1ZGlvX3RpZXJfbG9naWNcdTAwM2R0cnVlXHUwMDI2bXdlYl9jM19lbmRzY3JlZW5cdTAwM2R0cnVlXHUwMDI2bXdlYl9lbmFibGVfY3VzdG9tX2NvbnRyb2xfc2hhcmVkXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX3NraXBwYWJsZXNfb25famlvX3Bob25lXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfbXV0ZWRfYXV0b3BsYXlfYW5pbWF0aW9uXHUwMDNkc2hyaW5rXHUwMDI2bXdlYl9uYXRpdmVfY29udHJvbF9pbl9mYXV4X2Z1bGxzY3JlZW5fc2hhcmVkXHUwMDNkdHJ1ZVx1MDAyNm5ldHdvcmtfcG9sbGluZ19pbnRlcnZhbFx1MDAzZDMwMDAwXHUwMDI2bmV0d29ya2xlc3NfZ2VsXHUwMDNkdHJ1ZVx1MDAyNm5ldHdvcmtsZXNzX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2bmV3X2NvZGVjc19zdHJpbmdfYXBpX3VzZXNfbGVnYWN5X3N0eWxlXHUwMDNkdHJ1ZVx1MDAyNm53bF9zZW5kX2Zhc3Rfb25fdW5sb2FkXHUwMDNkdHJ1ZVx1MDAyNm53bF9zZW5kX2Zyb21fbWVtb3J5X3doZW5fb25saW5lXHUwMDNkdHJ1ZVx1MDAyNm9mZmxpbmVfZXJyb3JfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2cGFjZl9sb2dnaW5nX2RlbGF5X21pbGxpc2Vjb25kc190aHJvdWdoX3liZmVfdHZcdTAwM2QzMDAwMFx1MDAyNnBhZ2VpZF9hc19oZWFkZXJfd2ViXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9hZHNfc2V0X2FkZm9ybWF0X29uX2NsaWVudFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWxsb3dfYXV0b25hdl9hZnRlcl9wbGF5bGlzdFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYm9vdHN0cmFwX21ldGhvZFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZGVmZXJfY2FwdGlvbl9kaXNwbGF5XHUwMDNkMTAwMFx1MDAyNnBsYXllcl9kZXN0cm95X29sZF92ZXJzaW9uXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9kb3VibGV0YXBfdG9fc2Vla1x1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZW5hYmxlX3BsYXliYWNrX3BsYXlsaXN0X2NoYW5nZVx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZW5kc2NyZWVuX2VsbGlwc2lzX2ZpeFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfdW5kZXJsYXlfbWluX3BsYXllcl93aWR0aFx1MDAzZDc2OC4wXHUwMDI2cGxheWVyX3VuZGVybGF5X3ZpZGVvX3dpZHRoX2ZyYWN0aW9uXHUwMDNkMC42XHUwMDI2cGxheWVyX3dlYl9jYW5hcnlfc3RhZ2VcdTAwM2QwXHUwMDI2cGxheXJlYWR5X2ZpcnN0X3BsYXlfZXhwaXJhdGlvblx1MDAzZC0xXHUwMDI2cG9seW1lcl9iYWRfYnVpbGRfbGFiZWxzXHUwMDNkdHJ1ZVx1MDAyNnBvbHltZXJfbG9nX3Byb3BfY2hhbmdlX29ic2VydmVyX3BlcmNlbnRcdTAwM2QwXHUwMDI2cG9seW1lcl92ZXJpZml5X2FwcF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZwcmVza2lwX2J1dHRvbl9zdHlsZV9hZHNfYmFja2VuZFx1MDAzZGNvdW50ZG93bl9uZXh0X3RvX3RodW1ibmFpbFx1MDAyNnFvZV9ud2xfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNnFvZV9zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZyZWNvcmRfYXBwX2NyYXNoZWRfd2ViXHUwMDNkdHJ1ZVx1MDAyNnJlcGxhY2VfcGxheWFiaWxpdHlfcmV0cmlldmVyX2luX3dhdGNoXHUwMDNkdHJ1ZVx1MDAyNnNjaGVkdWxlcl91c2VfcmFmX2J5X2RlZmF1bHRcdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX2hlYWRlcl9zdHJpbmdfdGVtcGxhdGVcdTAwM2RzZWxmX3BvZGRpbmdfaW50ZXJzdGl0aWFsX21lc3NhZ2VcdTAwMjZzZWxmX3BvZGRpbmdfaGlnaGxpZ2h0X25vbl9kZWZhdWx0X2J1dHRvblx1MDAzZHRydWVcdTAwMjZzZWxmX3BvZGRpbmdfbWlkcm9sbF9jaG9pY2Vfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlXHUwMDI2c2VuZF9jb25maWdfaGFzaF90aW1lclx1MDAzZDBcdTAwMjZzZXRfaW50ZXJzdGl0aWFsX2FkdmVydGlzZXJzX3F1ZXN0aW9uX3RleHRcdTAwM2R0cnVlXHUwMDI2c2hvcnRfc3RhcnRfdGltZV9wcmVmZXJfcHVibGlzaF9pbl93YXRjaF9sb2dcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX21vZGVfdG9fcGxheWVyX2FwaVx1MDAzZHRydWVcdTAwMjZzaG9ydHNfbm9fc3RvcF92aWRlb19jYWxsXHUwMDNkdHJ1ZVx1MDAyNnNob3VsZF9jbGVhcl92aWRlb19kYXRhX29uX3BsYXllcl9jdWVkX3Vuc3RhcnRlZFx1MDAzZHRydWVcdTAwMjZzaW1wbHlfZW1iZWRkZWRfZW5hYmxlX2JvdGd1YXJkXHUwMDNkdHJ1ZVx1MDAyNnNraXBfaW5saW5lX211dGVkX2xpY2Vuc2Vfc2VydmljZV9jaGVja1x1MDAzZHRydWVcdTAwMjZza2lwX2ludmFsaWRfeXRjc2lfdGlja3NcdTAwM2R0cnVlXHUwMDI2c2tpcF9sc19nZWxfcmV0cnlcdTAwM2R0cnVlXHUwMDI2c2tpcF9zZXR0aW5nX2luZm9faW5fY3NpX2RhdGFfb2JqZWN0XHUwMDNkdHJ1ZVx1MDAyNnNsb3dfY29tcHJlc3Npb25zX2JlZm9yZV9hYmFuZG9uX2NvdW50XHUwMDNkNFx1MDAyNnNwZWVkbWFzdGVyX2NhbmNlbGxhdGlvbl9tb3ZlbWVudF9kcFx1MDAzZDBcdTAwMjZzcGVlZG1hc3Rlcl9wbGF5YmFja19yYXRlXHUwMDNkMC4wXHUwMDI2c3BlZWRtYXN0ZXJfdG91Y2hfYWN0aXZhdGlvbl9tc1x1MDAzZDBcdTAwMjZzdGFydF9jbGllbnRfZ2NmXHUwMDNkdHJ1ZVx1MDAyNnN0YXJ0X2NsaWVudF9nY2ZfZm9yX3BsYXllclx1MDAzZHRydWVcdTAwMjZzdGFydF9zZW5kaW5nX2NvbmZpZ19oYXNoXHUwMDNkdHJ1ZVx1MDAyNnN0cmVhbWluZ19kYXRhX2VtZXJnZW5jeV9pdGFnX2JsYWNrbGlzdFx1MDAzZFtdXHUwMDI2c3Vic3RpdHV0ZV9hZF9jcG5fbWFjcm9faW5fc3NkYWlcdTAwM2R0cnVlXHUwMDI2c3VwcHJlc3NfZXJyb3JfMjA0X2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2dHJhbnNwb3J0X3VzZV9zY2hlZHVsZXJcdTAwM2R0cnVlXHUwMDI2dHZfcGFjZl9sb2dnaW5nX3NhbXBsZV9yYXRlXHUwMDNkMC4wMVx1MDAyNnR2aHRtbDVfdW5wbHVnZ2VkX3ByZWxvYWRfY2FjaGVfc2l6ZVx1MDAzZDVcdTAwMjZ1bmNvdmVyX2FkX2JhZGdlX29uX1JUTF90aW55X3dpbmRvd1x1MDAzZHRydWVcdTAwMjZ1bnBsdWdnZWRfZGFpX2xpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNnVucGx1Z2dlZF90dmh0bWw1X3ZpZGVvX3ByZWxvYWRfb25fZm9jdXNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2dXBkYXRlX2xvZ19ldmVudF9jb25maWdcdTAwM2R0cnVlXHUwMDI2dXNlX2FjY2Vzc2liaWxpdHlfZGF0YV9vbl9kZXNrdG9wX3BsYXllcl9idXR0b25cdTAwM2R0cnVlXHUwMDI2dXNlX2NvcmVfc21cdTAwM2R0cnVlXHUwMDI2dXNlX2lubGluZWRfcGxheWVyX3JwY1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X2NtbFx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X2luX21lbW9yeV9zdG9yYWdlXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX2luaXRpYWxpemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3Nhd1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zdHdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfd3RzXHUwMDNkdHJ1ZVx1MDAyNnVzZV9wbGF5ZXJfYWJ1c2VfYmdfbGlicmFyeVx1MDAzZHRydWVcdTAwMjZ1c2VfcHJvZmlsZXBhZ2VfZXZlbnRfbGFiZWxfaW5fY2Fyb3VzZWxfcGxheWJhY2tzXHUwMDNkdHJ1ZVx1MDAyNnVzZV9yZXF1ZXN0X3RpbWVfbXNfaGVhZGVyXHUwMDNkdHJ1ZVx1MDAyNnVzZV9zZXNzaW9uX2Jhc2VkX3NhbXBsaW5nXHUwMDNkdHJ1ZVx1MDAyNnVzZV90c192aXNpYmlsaXR5bG9nZ2VyXHUwMDNkdHJ1ZVx1MDAyNnZhcmlhYmxlX2J1ZmZlcl90aW1lb3V0X21zXHUwMDNkMFx1MDAyNnZlcmlmeV9hZHNfaXRhZ19lYXJseVx1MDAzZHRydWVcdTAwMjZ2cDlfZHJtX2xpdmVcdTAwM2R0cnVlXHUwMDI2dnNzX2ZpbmFsX3Bpbmdfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2dnNzX3BpbmdzX3VzaW5nX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNnZzc19wbGF5YmFja191c2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2d2ViX2FwaV91cmxcdTAwM2R0cnVlXHUwMDI2d2ViX2FzeW5jX2NvbnRleHRfcHJvY2Vzc29yX2ltcGxcdTAwM2RzdGFuZGFsb25lXHUwMDI2d2ViX2NpbmVtYXRpY193YXRjaF9zZXR0aW5nc1x1MDAzZHRydWVcdTAwMjZ3ZWJfY2xpZW50X3ZlcnNpb25fb3ZlcnJpZGVcdTAwM2RcdTAwMjZ3ZWJfZGVkdXBlX3ZlX2dyYWZ0aW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9kZXByZWNhdGVfc2VydmljZV9hamF4X21hcF9kZXBlbmRlbmN5XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfZXJyb3JfMjA0XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfaW5zdHJlYW1fYWRzX2xpbmtfZGVmaW5pdGlvbl9hMTF5X2J1Z2ZpeFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX3Zvel9hdWRpb19mZWVkYmFja1x1MDAzZHRydWVcdTAwMjZ3ZWJfZml4X2ZpbmVfc2NydWJiaW5nX2RyYWdcdTAwM2R0cnVlXHUwMDI2d2ViX2ZvcmVncm91bmRfaGVhcnRiZWF0X2ludGVydmFsX21zXHUwMDNkMjgwMDBcdTAwMjZ3ZWJfZm9yd2FyZF9jb21tYW5kX29uX3Bialx1MDAzZHRydWVcdTAwMjZ3ZWJfZ2VsX2RlYm91bmNlX21zXHUwMDNkNjAwMDBcdTAwMjZ3ZWJfZ2VsX3RpbWVvdXRfY2FwXHUwMDNkdHJ1ZVx1MDAyNndlYl9pbmxpbmVfcGxheWVyX25vX3BsYXliYWNrX3VpX2NsaWNrX2hhbmRsZXJcdTAwM2R0cnVlXHUwMDI2d2ViX2tleV9tb21lbnRzX21hcmtlcnNcdTAwM2R0cnVlXHUwMDI2d2ViX2xvZ19tZW1vcnlfdG90YWxfa2J5dGVzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dnaW5nX21heF9iYXRjaFx1MDAzZDE1MFx1MDAyNndlYl9tb2Rlcm5fYWRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fYnV0dG9uc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNfYmxfc3VydmV5XHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc2NydWJiZXJcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zdWJzY3JpYmVcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zdWJzY3JpYmVfc3R5bGVcdTAwM2RmaWxsZWRcdTAwMjZ3ZWJfbmV3X2F1dG9uYXZfY291bnRkb3duXHUwMDNkdHJ1ZVx1MDAyNndlYl9vbmVfcGxhdGZvcm1fZXJyb3JfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX29wX3NpZ25hbF90eXBlX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNndlYl9wYXVzZWRfb25seV9taW5pcGxheWVyX3Nob3J0Y3V0X2V4cGFuZFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF9sb2dfY3R0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5YmFja19hc3NvY2lhdGVkX3ZlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYWRkX3ZlX2NvbnZlcnNpb25fbG9nZ2luZ190b19vdXRib3VuZF9saW5rc1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2Fsd2F5c19lbmFibGVfYXV0b190cmFuc2xhdGlvblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FwaV9sb2dnaW5nX2ZyYWN0aW9uXHUwMDNkMC4wMVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl9lbXB0eV9zdWdnZXN0aW9uc19maXhcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X3RvZ2dsZV9hbHdheXNfbGlzdGVuXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl91c2Vfc2VydmVyX3Byb3ZpZGVkX3N0YXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfY2FwdGlvbl9sYW5ndWFnZV9wcmVmZXJlbmNlX3N0aWNraW5lc3NfZHVyYXRpb25cdTAwM2QzMFx1MDAyNndlYl9wbGF5ZXJfZGVjb3VwbGVfYXV0b25hdlx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2Rpc2FibGVfaW5saW5lX3NjcnViYmluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9lYXJseV93YXJuaW5nX3NuYWNrYmFyXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX2ZlYXR1cmVkX3Byb2R1Y3RfYmFubmVyX29uX2Rlc2t0b3BcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfcHJlbWl1bV9oYnJfaW5faDVfYXBpXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX3BsYXliYWNrX2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2lubmVydHViZV9wbGF5bGlzdF91cGRhdGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pcHBfY2FuYXJ5X3R5cGVfZm9yX2xvZ2dpbmdcdTAwM2RcdTAwMjZ3ZWJfcGxheWVyX2xpdmVfbW9uaXRvcl9lbnZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9sb2dfY2xpY2tfYmVmb3JlX2dlbmVyYXRpbmdfdmVfY29udmVyc2lvbl9wYXJhbXNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9tb3ZlX2F1dG9uYXZfdG9nZ2xlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbXVzaWNfdmlzdWFsaXplcl90cmVhdG1lbnRcdTAwM2RmYWtlXHUwMDI2d2ViX3BsYXllcl9tdXRhYmxlX2V2ZW50X2xhYmVsXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbml0cmF0ZV9wcm9tb190b29sdGlwXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfb2ZmbGluZV9wbGF5bGlzdF9hdXRvX3JlZnJlc2hcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9yZXNwb25zZV9wbGF5YmFja190cmFja2luZ19wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2Vla19jaGFwdGVyc19ieV9zaG9ydGN1dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlbnRpbmVsX2lzX3VuaXBsYXllclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3VsZF9ob25vcl9pbmNsdWRlX2Fzcl9zZXR0aW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2hvd19tdXNpY19pbl90aGlzX3ZpZGVvX2dyYXBoaWNcdTAwM2R2aWRlb190aHVtYm5haWxcdTAwMjZ3ZWJfcGxheWVyX3NtYWxsX2hicF9zZXR0aW5nc19tZW51XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc3NfZGFpX2FkX2ZldGNoaW5nX3RpbWVvdXRfbXNcdTAwM2QxNTAwMFx1MDAyNndlYl9wbGF5ZXJfc3NfbWVkaWFfdGltZV9vZmZzZXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90b3BpZnlfc3VidGl0bGVzX2Zvcl9zaG9ydHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90b3VjaF9tb2RlX2ltcHJvdmVtZW50c1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RyYW5zZmVyX3RpbWVvdXRfdGhyZXNob2xkX21zXHUwMDNkMTA4MDAwMDBcdTAwMjZ3ZWJfcGxheWVyX3Vuc2V0X2RlZmF1bHRfY3NuX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl91c2VfbmV3X2FwaV9mb3JfcXVhbGl0eV9wdWxsYmFja1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3ZlX2NvbnZlcnNpb25fZml4ZXNfZm9yX2NoYW5uZWxfaW5mb1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3dhdGNoX25leHRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlX3BhcnNpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3ByZWZldGNoX3ByZWxvYWRfdmlkZW9cdTAwM2R0cnVlXHUwMDI2d2ViX3JvdW5kZWRfdGh1bWJuYWlsc1x1MDAzZHRydWVcdTAwMjZ3ZWJfc2V0dGluZ3NfbWVudV9pY29uc1x1MDAzZHRydWVcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNndlYl9zbW9vdGhuZXNzX3Rlc3RfbWV0aG9kXHUwMDNkMFx1MDAyNndlYl95dF9jb25maWdfY29udGV4dFx1MDAzZHRydWVcdTAwMjZ3aWxfaWNvbl9yZW5kZXJfd2hlbl9pZGxlXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9jbGVhbl91cF9hZnRlcl9lbnRpdHlfbWlncmF0aW9uXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9lbmFibGVfZG93bmxvYWRfc3RhdHVzXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9wbGF5bGlzdF9vcHRpbWl6YXRpb25cdTAwM2R0cnVlXHUwMDI2eXRpZGJfY2xlYXJfZW1iZWRkZWRfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2ZldGNoX2RhdGFzeW5jX2lkc19mb3JfZGF0YV9jbGVhbnVwXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX3JlbWFrZV9kYl9yZXRyaWVzXHUwMDNkMVx1MDAyNnl0aWRiX3Jlb3Blbl9kYl9yZXRyaWVzXHUwMDNkMFx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRcdTAwM2QwLjAyXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdF9zZXNzaW9uXHUwMDNkMC4yXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdF90cmFuc2FjdGlvblx1MDAzZDAuMSIsImRpc2FibGVTaGFyaW5nIjp0cnVlLCJoaWRlSW5mbyI6dHJ1ZSwiZGlzYWJsZVdhdGNoTGF0ZXIiOnRydWUsImNzcE5vbmNlIjoib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSIsImNhbmFyeVN0YXRlIjoibm9uZSIsImVuYWJsZUNzaUxvZ2dpbmciOnRydWUsImNzaVBhZ2VUeXBlIjoicGxheWxpc3Rfb3ZlcnZpZXciLCJkYXRhc3luY0lkIjoiVjIwMjE3ZmM2fHwifSwiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfVkVSVElDQUxfTEFORElOR19QQUdFX1BST01PIjp7InJvb3RFbGVtZW50SWQiOiJ5dGQtZGVmYXVsdC1wcm9tby1wYW5lbC1yZW5kZXJlci1pbmxpbmUtcGxheWJhY2stcmVuZGVyZXIiLCJqc1VybCI6Ii9zL3BsYXllci9iMTI4ZGRhMC9wbGF5ZXJfaWFzLnZmbHNldC9mcl9GUi9iYXNlLmpzIiwiY3NzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3d3dy1wbGF5ZXIuY3NzIiwiY29udGV4dElkIjoiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfVkVSVElDQUxfTEFORElOR19QQUdFX1BST01PIiwiZXZlbnRMYWJlbCI6InByb2ZpbGVwYWdlIiwiY29udGVudFJlZ2lvbiI6IkZSIiwiaGwiOiJmcl9GUiIsImhvc3RMYW5ndWFnZSI6ImZyIiwicGxheWVyU3R5bGUiOiJkZXNrdG9wLXBvbHltZXIiLCJpbm5lcnR1YmVBcGlLZXkiOiJBSXphU3lBT19GSjJTbHFVOFE0U1RFSExHQ2lsd19ZOV8xMXFjVzgiLCJpbm5lcnR1YmVBcGlWZXJzaW9uIjoidjEiLCJpbm5lcnR1YmVDb250ZXh0Q2xpZW50VmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJjb250cm9sc1R5cGUiOjAsImRpc2FibGVSZWxhdGVkVmlkZW9zIjp0cnVlLCJhbm5vdGF0aW9uc0xvYWRQb2xpY3kiOjMsImRldmljZSI6eyJicmFuZCI6IiIsIm1vZGVsIjoiIiwicGxhdGZvcm0iOiJERVNLVE9QIiwiaW50ZXJmYWNlTmFtZSI6IldFQiIsImludGVyZmFjZVZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIn0sInNlcmlhbGl6ZWRFeHBlcmltZW50SWRzIjoiMjM5ODMyOTYsMjQwMDQ2NDQsMjQwMDcyNDYsMjQwMDc2MTMsMjQwODA3MzgsMjQxMzUzMTAsMjQzNjMxMTQsMjQzNjQ3ODksMjQzNjU1MzQsMjQzNjY5MTcsMjQzNzI3NjEsMjQzNzUxMDEsMjQzNzY3ODUsMjQ0MTU4NjQsMjQ0MTYyOTAsMjQ0MzM2NzksMjQ0Mzc1NzcsMjQ0MzkzNjEsMjQ0NDMzMzEsMjQ0OTk1MzIsMjQ1MzI4NTUsMjQ1NTA0NTgsMjQ1NTA5NTEsMjQ1NTU1NjcsMjQ1NTg2NDEsMjQ1NTkzMjcsMjQ2OTk4OTksMzkzMjMwNzQiLCJzZXJpYWxpemVkRXhwZXJpbWVudEZsYWdzIjoiSDVfYXN5bmNfbG9nZ2luZ19kZWxheV9tc1x1MDAzZDMwMDAwLjBcdTAwMjZINV9lbmFibGVfZnVsbF9wYWNmX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2SDVfdXNlX2FzeW5jX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2YWN0aW9uX2NvbXBhbmlvbl9jZW50ZXJfYWxpZ25fZGVzY3JpcHRpb25cdTAwM2R0cnVlXHUwMDI2YWRfcG9kX2Rpc2FibGVfY29tcGFuaW9uX3BlcnNpc3RfYWRzX3F1YWxpdHlcdTAwM2R0cnVlXHUwMDI2YWRkdG9fYWpheF9sb2dfd2FybmluZ19mcmFjdGlvblx1MDAzZDAuMVx1MDAyNmFsaWduX2FkX3RvX3ZpZGVvX3BsYXllcl9saWZlY3ljbGVfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2YWxsb3dfbGl2ZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19wb2x0ZXJndXN0X2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X3NraXBfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2YXR0X3dlYl9yZWNvcmRfbWV0cmljc1x1MDAzZHRydWVcdTAwMjZhdXRvcGxheV90aW1lXHUwMDNkODAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX2Z1bGxzY3JlZW5cdTAwM2QzMDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfbXVzaWNfY29udGVudFx1MDAzZDMwMDBcdTAwMjZiZ192bV9yZWluaXRfdGhyZXNob2xkXHUwMDNkNzIwMDAwMFx1MDAyNmJsb2NrZWRfcGFja2FnZXNfZm9yX3Nwc1x1MDAzZFtdXHUwMDI2Ym90Z3VhcmRfYXN5bmNfc25hcHNob3RfdGltZW91dF9tc1x1MDAzZDMwMDBcdTAwMjZjaGVja19hZF91aV9zdGF0dXNfZm9yX213ZWJfc2FmYXJpXHUwMDNkdHJ1ZVx1MDAyNmNoZWNrX25hdmlnYXRvcl9hY2N1cmFjeV90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmNsZWFyX3VzZXJfcGFydGl0aW9uZWRfbHNcdTAwM2R0cnVlXHUwMDI2Y2xpZW50X3Jlc3BlY3RfYXV0b3BsYXlfc3dpdGNoX2J1dHRvbl9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZjb21wcmVzc19nZWxcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3Npb25fZGlzYWJsZV9wb2ludFx1MDAzZDEwXHUwMDI2Y29tcHJlc3Npb25fcGVyZm9ybWFuY2VfdGhyZXNob2xkXHUwMDNkMjUwXHUwMDI2Y3NpX29uX2dlbFx1MDAzZHRydWVcdTAwMjZkYXNoX21hbmlmZXN0X3ZlcnNpb25cdTAwM2Q1XHUwMDI2ZGVidWdfYmFuZGFpZF9ob3N0bmFtZVx1MDAzZFx1MDAyNmRlYnVnX3NoZXJsb2dfdXNlcm5hbWVcdTAwM2RcdTAwMjZkZWxheV9hZHNfZ3ZpX2NhbGxfb25fYnVsbGVpdF9saXZpbmdfcm9vbV9tc1x1MDAzZDBcdTAwMjZkZXByZWNhdGVfY3NpX2hhc19pbmZvXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV9wYWlyX3NlcnZsZXRfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX2NoaWxkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfcGFyZW50XHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfaW1hZ2VfY3RhX25vX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9sb2dfaW1nX2NsaWNrX2xvY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3Bfc3BhcmtsZXNfbGlnaHRfY3RhX2J1dHRvblx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoYW5uZWxfaWRfY2hlY2tfZm9yX3N1c3BlbmRlZF9jaGFubmVsc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoaWxkX25vZGVfYXV0b19mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2RlZmVyX2FkbW9kdWxlX29uX2FkdmVydGlzZXJfdmlkZW9cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9mZWF0dXJlc19mb3Jfc3VwZXhcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9sZWdhY3lfZGVza3RvcF9yZW1vdGVfcXVldWVcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9tZHhfY29ubmVjdGlvbl9pbl9tZHhfbW9kdWxlX2Zvcl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9uZXdfcGF1c2Vfc3RhdGUzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcGFjZl9sb2dnaW5nX2Zvcl9tZW1vcnlfbGltaXRlZF90dlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3JvdW5kaW5nX2FkX25vdGlmeVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NpbXBsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zc2RhaV9vbl9lcnJvcnNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90YWJiaW5nX2JlZm9yZV9mbHlvdXRfYWRfZWxlbWVudHNfYXBwZWFyXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGh1bWJuYWlsX3ByZWxvYWRpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2Rpc2FibGVfcHJvZ3Jlc3NfYmFyX2NvbnRleHRfbWVudV9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZW5hYmxlX2FsbG93X3dhdGNoX2FnYWluX2VuZHNjcmVlbl9mb3JfZWxpZ2libGVfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc192ZV9jb252ZXJzaW9uX3BhcmFtX3JlbmFtaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2F1dG9wbGF5X25vdF9zdXBwb3J0ZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfY3VlX3ZpZGVvX3VucGxheWFibGVfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2hvdXNlX2JyYW5kX2FuZF95dF9jb2V4aXN0ZW5jZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2FkX3BsYXllcl9mcm9tX3BhZ2Vfc2hvd1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dfc3BsYXlfYXNfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nZ2luZ19ldmVudF9oYW5kbGVyc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2R0dHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbmV3X2NvbnRleHRfbWVudV90cmlnZ2VyaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BhdXNlX292ZXJsYXlfd25fdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BlbV9kb21haW5fZml4X2Zvcl9hZF9yZXF1ZXN0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZnBfdW5icmFuZGVkX2VsX2RlcHJlY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JjYXRfYWxsb3dsaXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JlcGxhY2VfdW5sb2FkX3dfcGFnZWhpZGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfc2NyaXB0ZWRfcGxheWJhY2tfYmxvY2tlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdHJhY2tpbmdfbm9fYWxsb3dfbGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2hpZGVfdW5maWxsZWRfbW9yZV92aWRlb3Nfc3VnZ2VzdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9saXRlX21vZGVcdTAwM2QxXHUwMDI2ZW1iZWRzX3dlYl9ud2xfZGlzYWJsZV9ub2Nvb2tpZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3Nob3BwaW5nX292ZXJsYXlfbm9fd2FpdF9mb3JfcGFpZF9jb250ZW50X292ZXJsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zeW50aF9jaF9oZWFkZXJzX2Jhbm5lZF91cmxzX3JlZ2V4XHUwMDNkXHUwMDI2ZW5hYmxlX2FiX3JwX2ludFx1MDAzZHRydWVcdTAwMjZlbmFibGVfYWRfY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FwcF9wcm9tb19lbmRjYXBfZW1sX29uX3RhYmxldFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9mb3Jfd2ViX3VucGx1Z2dlZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9vbl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9wYWdlX2lkX2hlYWRlcl9mb3JfZmlyc3RfcGFydHlfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9zbGlfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZGlzY3JldGVfbGl2ZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudF9jaGVja1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRzX2ljb25fd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9ldmljdGlvbl9wcm90ZWN0aW9uX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9nZWxfbG9nX2NvbW1hbmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV9pbnN0cmVhbV93YXRjaF9uZXh0X3BhcmFtc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X3ZpZGVvX2Fkc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2hhbmRsZXNfYWNjb3VudF9tZW51X3N3aXRjaGVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9rYWJ1a2lfY29tbWVudHNfb25fc2hvcnRzXHUwMDNkZGlzYWJsZWRcdTAwMjZlbmFibGVfbGl2ZV9wcmVtaWVyZV93ZWJfcGxheWVyX2luZGljYXRvclx1MDAzZHRydWVcdTAwMjZlbmFibGVfbHJfaG9tZV9pbmZlZWRfYWRzX2lubGluZV9wbGF5YmFja19wcm9ncmVzc19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9td2ViX2VuZGNhcF9jbGlja2FibGVfaWNvbl9kZXNjcmlwdGlvblx1MDAzZHRydWVcdTAwMjZlbmFibGVfbXdlYl9saXZlc3RyZWFtX3VpX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbmFibGVfbmV3X3BhaWRfcHJvZHVjdF9wbGFjZW1lbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2Zfc2xvdF9hc2RlX3BsYXllcl9ieXRlX2g1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZfZm9yX3BhZ2VfdG9wX2Zvcm1hdHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95c2ZlX3R2XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYXNzX3NkY19nZXRfYWNjb3VudHNfbGlzdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGxfcl9jXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2ZpeF9vbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2luX3R2aHRtbDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NlcnZlcl9zdGl0Y2hlZF9kYWlcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Nob3J0c19wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NraXBfYWRfZ3VpZGFuY2VfcHJvbXB0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwcGFibGVfYWRzX2Zvcl91bnBsdWdnZWRfYWRfcG9kXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90ZWN0b25pY19hZF91eF9mb3JfaGFsZnRpbWVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RoaXJkX3BhcnR5X2luZm9cdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RvcHNvaWxfd3RhX2Zvcl9oYWxmdGltZV9saXZlX2luZnJhXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfbWVkaWFfc2Vzc2lvbl9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3dlYl9zY2hlZHVsZXJfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfd25faW5mb2NhcmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV95dF9hdGFfaWZyYW1lX2F1dGh1c2VyXHUwMDNkdHJ1ZVx1MDAyNmVycm9yX21lc3NhZ2VfZm9yX2dzdWl0ZV9uZXR3b3JrX3Jlc3RyaWN0aW9uc1x1MDAzZHRydWVcdTAwMjZleHBvcnRfbmV0d29ya2xlc3Nfb3B0aW9uc1x1MDAzZHRydWVcdTAwMjZleHRlcm5hbF9mdWxsc2NyZWVuX3dpdGhfZWR1XHUwMDNkdHJ1ZVx1MDAyNmZhc3RfYXV0b25hdl9pbl9iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmZldGNoX2F0dF9pbmRlcGVuZGVudGx5XHUwMDNkdHJ1ZVx1MDAyNmZpbGxfc2luZ2xlX3ZpZGVvX3dpdGhfbm90aWZ5X3RvX2xhc3JcdTAwM2R0cnVlXHUwMDI2ZmlsdGVyX3ZwOV9mb3JfY3NkYWlcdTAwM2R0cnVlXHUwMDI2Zml4X2Fkc190cmFja2luZ19mb3Jfc3dmX2NvbmZpZ19kZXByZWNhdGlvbl9td2ViXHUwMDNkdHJ1ZVx1MDAyNmdjZl9jb25maWdfc3RvcmVfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZnZWxfcXVldWVfdGltZW91dF9tYXhfbXNcdTAwM2QzMDAwMDBcdTAwMjZncGFfc3BhcmtsZXNfdGVuX3BlcmNlbnRfbGF5ZXJcdTAwM2R0cnVlXHUwMDI2Z3ZpX2NoYW5uZWxfY2xpZW50X3NjcmVlblx1MDAzZHRydWVcdTAwMjZoNV9jb21wYW5pb25fZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX2dlbmVyaWNfZXJyb3JfbG9nZ2luZ19ldmVudFx1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfdW5pZmllZF9jc2lfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZoNV9pbnBsYXllcl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9yZXNldF9jYWNoZV9hbmRfZmlsdGVyX2JlZm9yZV91cGRhdGVfbWFzdGhlYWRcdTAwM2R0cnVlXHUwMDI2aGVhdHNlZWtlcl9kZWNvcmF0aW9uX3RocmVzaG9sZFx1MDAzZDAuMFx1MDAyNmhmcl9kcm9wcGVkX2ZyYW1lcmF0ZV9mYWxsYmFja190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aGlkZV9lbmRwb2ludF9vdmVyZmxvd19vbl95dGRfZGlzcGxheV9hZF9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZodG1sNV9hZF90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2Fkc19wcmVyb2xsX2xvY2tfdGltZW91dF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfYWxsb3dfZGlzY29udGlndW91c19zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWxsb3dfdmlkZW9fa2V5ZnJhbWVfd2l0aG91dF9hdWRpb1x1MDAzZHRydWVcdTAwMjZodG1sNV9hdHRhY2hfbnVtX3JhbmRvbV9ieXRlc190b19iYW5kYWlkXHUwMDNkMFx1MDAyNmh0bWw1X2F0dGFjaF9wb190b2tlbl90b19iYW5kYWlkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F1dG9uYXZfY2FwX2lkbGVfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9hdXRvbmF2X3F1YWxpdHlfY2FwXHUwMDNkNzIwXHUwMDI2aHRtbDVfYXV0b3BsYXlfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9ibG9ja19waXBfc2FmYXJpX2RlbGF5XHUwMDNkMFx1MDAyNmh0bWw1X2JtZmZfbmV3X2ZvdXJjY19jaGVja1x1MDAzZHRydWVcdTAwMjZodG1sNV9jb2JhbHRfZGVmYXVsdF9idWZmZXJfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWF4X3NpemVfZm9yX2ltbWVkX2pvYlx1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWluX3Byb2Nlc3Nvcl9jbnRfdG9fb2ZmbG9hZF9hbGdvXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9vdmVycmlkZV9xdWljXHUwMDNkMFx1MDAyNmh0bWw1X2NvbnN1bWVfbWVkaWFfYnl0ZXNfc2xpY2VfaW5mb3NcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVfZHVwZV9jb250ZW50X3ZpZGVvX2xvYWRzX2luX2xpZmVjeWNsZV9hcGlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVidWdfZGF0YV9sb2dfcHJvYmFiaWxpdHlcdTAwM2QwLjFcdTAwMjZodG1sNV9kZWNvZGVfdG9fdGV4dHVyZV9jYXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVmYXVsdF9hZF9nYWluXHUwMDNkMC41XHUwMDI2aHRtbDVfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9hZF9tb2R1bGVfbXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfZmV0Y2hfYXR0X21zXHUwMDNkMTAwMFx1MDAyNmh0bWw1X2RlZmVyX21vZHVsZXNfZGVsYXlfdGltZV9taWxsaXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9jb3VudFx1MDAzZDFcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2RlbGF5X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X2RlcHJlY2F0ZV92aWRlb190YWdfcG9vbFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZXNrdG9wX3ZyMTgwX2FsbG93X3Bhbm5pbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGZfZG93bmdyYWRlX3RocmVzaFx1MDAzZDAuMlx1MDAyNmh0bWw1X2Rpc2FibGVfY3NpX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbW92ZV9wc3NoX3RvX21vb3ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9ub25fY29udGlndW91c1x1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNwbGF5ZWRfZnJhbWVfcmF0ZV9kb3duZ3JhZGVfdGhyZXNob2xkXHUwMDNkNDVcdTAwMjZodG1sNV9kcm1fY2hlY2tfYWxsX2tleV9lcnJvcl9zdGF0ZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZHJtX2NwaV9saWNlbnNlX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hZHNfY2xpZW50X21vbml0b3JpbmdfbG9nX3R2XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jYXB0aW9uX2NoYW5nZXNfZm9yX21vc2FpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2xpZW50X2hpbnRzX292ZXJyaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jb21wb3NpdGVfZW1iYXJnb1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZWFjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZW1iZWRkZWRfcGxheWVyX3Zpc2liaWxpdHlfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbm9uX25vdGlmeV9jb21wb3NpdGVfdm9kX2xzYXJfcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfc2luZ2xlX3ZpZGVvX3ZvZF9pdmFyX29uX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZGFzaFx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19lbmNyeXB0ZWRfdnA5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfYWxjXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfZmFzdF9saW5lYXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5jb3VyYWdlX2FycmF5X2NvYWxlc2NpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2FwbGVzc19lbmRlZF90cmFuc2l0aW9uX2J1ZmZlcl9tc1x1MDAzZDIwMFx1MDAyNmh0bWw1X2dlbmVyYXRlX3Nlc3Npb25fcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2xfZnBzX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZodG1sNV9oZGNwX3Byb2Jpbmdfc3RyZWFtX3VybFx1MDAzZFx1MDAyNmh0bWw1X2hmcl9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QxLjBcdTAwMjZodG1sNV9pZGxlX3JhdGVfbGltaXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX2ZhaXJwbGF5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9wbGF5cmVhZHlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3dpZGV2aW5lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczRfc2Vla19hYm92ZV96ZXJvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczdfZm9yY2VfcGxheV9vbl9zdGFsbFx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3NfZm9yY2Vfc2Vla190b196ZXJvX29uX3N0b3BcdTAwM2R0cnVlXHUwMDI2aHRtbDVfanVtYm9fbW9iaWxlX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDMuMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9ub25zdHJlYW1pbmdfbWZmYV9tc1x1MDAzZDQwMDBcdTAwMjZodG1sNV9qdW1ib191bGxfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMS4zXHUwMDI2aHRtbDVfbGljZW5zZV9jb25zdHJhaW50X2RlbGF5XHUwMDNkNTAwMFx1MDAyNmh0bWw1X2xpdmVfYWJyX2hlYWRfbWlzc19mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYWJyX3JlcHJlZGljdF9mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYnl0ZXJhdGVfZmFjdG9yX2Zvcl9yZWFkYWhlYWRcdTAwM2QxLjNcdTAwMjZodG1sNV9saXZlX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9saXZlX25vcm1hbF9sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2xpdmVfdWx0cmFfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xvZ19hdWRpb19hYnJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX2V4cGVyaW1lbnRfaWRfZnJvbV9wbGF5ZXJfcmVzcG9uc2VfdG9fY3RtcFx1MDAzZFx1MDAyNmh0bWw1X2xvZ19maXJzdF9zc2RhaV9yZXF1ZXN0c19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19yZWJ1ZmZlcl9ldmVudHNcdTAwM2Q1XHUwMDI2aHRtbDVfbG9nX3NzZGFpX2ZhbGxiYWNrX2Fkc1x1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfdHJpZ2dlcl9ldmVudHNfd2l0aF9kZWJ1Z19kYXRhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX3RocmVzaG9sZF9tc1x1MDAzZDMwMDAwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3NlZ19kcmlmdF9saW1pdF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc191bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3ZwOV9vdGZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWF4X2RyaWZ0X3Blcl90cmFja19zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWF4X2hlYWRtX2Zvcl9zdHJlYW1pbmdfeGhyXHUwMDNkMFx1MDAyNmh0bWw1X21heF9saXZlX2R2cl93aW5kb3dfcGx1c19tYXJnaW5fc2Vjc1x1MDAzZDQ2ODAwLjBcdTAwMjZodG1sNV9tYXhfcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21heF9yZWRpcmVjdF9yZXNwb25zZV9sZW5ndGhcdTAwM2Q4MTkyXHUwMDI2aHRtbDVfbWF4X3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21heF9zb3VyY2VfYnVmZmVyX2FwcGVuZF9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X21heGltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9tZWRpYV9mdWxsc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21mbF9leHRlbmRfbWF4X3JlcXVlc3RfdGltZVx1MDAzZHRydWVcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9jYXBfc2Vjc1x1MDAzZDYwXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9taW5fc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfYWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbm9fcGxhY2Vob2xkZXJfcm9sbGJhY2tzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vbl9uZXR3b3JrX3JlYnVmZmVyX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X25vbl9vbmVzaWVfYXR0YWNoX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vdF9yZWdpc3Rlcl9kaXNwb3NhYmxlc193aGVuX2NvcmVfbGlzdGVuc1x1MDAzZHRydWVcdTAwMjZodG1sNV9vZmZsaW5lX2ZhaWx1cmVfcmV0cnlfbGltaXRcdTAwM2QyXHUwMDI2aHRtbDVfb25lc2llX2RlZmVyX2NvbnRlbnRfbG9hZGVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9ob3N0X3JhY2luZ19jYXBfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2lnbm9yZV9pbm5lcnR1YmVfYXBpX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbGl2ZV90dGxfc2Vjc1x1MDAzZDhcdTAwMjZodG1sNV9vbmVzaWVfbm9uemVyb19wbGF5YmFja19zdGFydFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbm90aWZ5X2N1ZXBvaW50X21hbmFnZXJfb25fY29tcGxldGlvblx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9jb29sZG93bl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9pbnRlcnZhbF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9tYXhfbGFjdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlcXVlc3RfdGltZW91dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9vbmVzaWVfc3RpY2t5X3NlcnZlcl9zaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BhdXNlX29uX25vbmZvcmVncm91bmRfcGxhdGZvcm1fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlYWtfc2hhdmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZl9jYXBfb3ZlcnJpZGVfc3RpY2t5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2NhcF9mbG9vclx1MDAzZDM2MFx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2ltcGFjdF9wcm9maWxpbmdfdGltZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcGVyc2VydmVfYXYxX3BlcmZfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX21pbmltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9wbGF5ZXJfYXV0b25hdl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXllcl9keW5hbWljX2JvdHRvbV9ncmFkaWVudFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfbWluX2J1aWxkX2NsXHUwMDNkLTFcdTAwMjZodG1sNV9wbGF5ZXJfcHJlbG9hZF9hZF9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcG9zdF9pbnRlcnJ1cHRfcmVhZGFoZWFkXHUwMDNkMjBcdTAwMjZodG1sNV9wcmVmZXJfc2VydmVyX2J3ZTNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcHJlbG9hZF93YWl0X3RpbWVfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Byb2JlX3ByaW1hcnlfZGVsYXlfYmFzZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9wcm9jZXNzX2FsbF9lbmNyeXB0ZWRfZXZlbnRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3FvZV9saF9tYXhfcmVwb3J0X2NvdW50XHUwMDNkMFx1MDAyNmh0bWw1X3FvZV9saF9taW5fZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfcXVlcnlfc3dfc2VjdXJlX2NyeXB0b19mb3JfYW5kcm9pZFx1MDAzZHRydWVcdTAwMjZodG1sNV9yYW5kb21fcGxheWJhY2tfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X3JlY29nbml6ZV9wcmVkaWN0X3N0YXJ0X2N1ZV9wb2ludFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfY29tbWFuZF90cmlnZ2VyZWRfY29tcGFuaW9uc1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfbm90X3NlcnZhYmxlX2NoZWNrX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVuYW1lX2FwYnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X2ZhdGFsX2RybV9yZXN0cmljdGVkX2Vycm9yX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X3Nsb3dfYWRzX2FzX2Vycm9yXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfb25seV9oZHJfb3Jfc2RyX2tleXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVxdWVzdF9zaXppbmdfbXVsdGlwbGllclx1MDAzZDAuOFx1MDAyNmh0bWw1X3Jlc2V0X21lZGlhX3N0cmVhbV9vbl91bnJlc3VtYWJsZV9zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVzb3VyY2VfYmFkX3N0YXR1c19kZWxheV9zY2FsaW5nXHUwMDNkMS41XHUwMDI2aHRtbDVfcmVzdHJpY3Rfc3RyZWFtaW5nX3hocl9vbl9zcWxlc3NfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2FmYXJpX2Rlc2t0b3BfZW1lX21pbl92ZXJzaW9uXHUwMDNkMFx1MDAyNmh0bWw1X3NhbXN1bmdfa2FudF9saW1pdF9tYXhfYml0cmF0ZVx1MDAzZDBcdTAwMjZodG1sNV9zZWVrX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2Q4MDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9kZWxheV9tc1x1MDAzZDEyMDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfYnVmZmVyX3JhbmdlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX3Zyc19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2NmbFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfc2V0X2NtdF9kZWxheV9tc1x1MDAzZDIwMDBcdTAwMjZodG1sNV9zZWVrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NlcnZlcl9zdGl0Y2hlZF9kYWlfZGVjb3JhdGVkX3VybF9yZXRyeV9saW1pdFx1MDAzZDVcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2dyb3VwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Nlc3Npb25fcG9fdG9rZW5faW50ZXJ2YWxfdGltZV9tc1x1MDAzZDkwMDAwMFx1MDAyNmh0bWw1X3NraXBfb29iX3N0YXJ0X3NlY29uZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2tpcF9zbG93X2FkX2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9za2lwX3N1Yl9xdWFudHVtX2Rpc2NvbnRpbnVpdHlfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfbm9fbWVkaWFfc291cmNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfdGltZW91dF9kZWxheV9tc1x1MDAzZDIwMDAwXHUwMDI2aHRtbDVfc3NkYWlfYWRmZXRjaF9keW5hbWljX3RpbWVvdXRfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfc3NkYWlfZW5hYmxlX25ld19zZWVrX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N0YXRlZnVsX2F1ZGlvX21pbl9hZGp1c3RtZW50X3ZhbHVlXHUwMDNkMFx1MDAyNmh0bWw1X3N0YXRpY19hYnJfcmVzb2x1dGlvbl9zaGVsZlx1MDAzZDBcdTAwMjZodG1sNV9zdG9yZV94aHJfaGVhZGVyc19yZWFkYWJsZVx1MDAzZHRydWVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9sb2FkX3NwZWVkX2NoZWNrX2ludGVydmFsXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuMjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzX29uX3RpbWVvdXRcdTAwM2QwLjFcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fbG9hZF9zcGVlZFx1MDAzZDEuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3NlZWtfbGF0ZW5jeV9mdWRnZVx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldF9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90aW1lb3V0X3NlY3NcdTAwM2QyLjBcdTAwMjZodG1sNV91Z2NfbGl2ZV9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91Z2Nfdm9kX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VucmVwb3J0ZWRfc2Vla19yZXNlZWtfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfdW5yZXN0cmljdGVkX2xheWVyX2hpZ2hfcmVzX2xvZ2dpbmdfcGVyY2VudFx1MDAzZDAuMFx1MDAyNmh0bWw1X3VybF9wYWRkaW5nX2xlbmd0aFx1MDAzZDBcdTAwMjZodG1sNV91cmxfc2lnbmF0dXJlX2V4cGlyeV90aW1lX2hvdXJzXHUwMDNkMFx1MDAyNmh0bWw1X3VzZV9wb3N0X2Zvcl9tZWRpYVx1MDAzZHRydWVcdTAwMjZodG1sNV91c2VfdW1wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ZpZGVvX3RiZF9taW5fa2JcdTAwM2QwXHUwMDI2aHRtbDVfdmlld3BvcnRfdW5kZXJzZW5kX21heGltdW1cdTAwM2QwLjBcdTAwMjZodG1sNV92b2x1bWVfc2xpZGVyX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2ViX2VuYWJsZV9oYWxmdGltZV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYnBvX2lkbGVfcHJpb3JpdHlfam9iXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvZmZsZV9yZXN1bWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29ya2Fyb3VuZF9kZWxheV90cmlnZ2VyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3l0dmxyX2VuYWJsZV9zaW5nbGVfc2VsZWN0X3N1cnZleVx1MDAzZHRydWVcdTAwMjZpZ25vcmVfb3ZlcmxhcHBpbmdfY3VlX3BvaW50c19vbl9lbmRlbWljX2xpdmVfaHRtbDVcdTAwM2R0cnVlXHUwMDI2aWxfdXNlX3ZpZXdfbW9kZWxfbG9nZ2luZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNmluaXRpYWxfZ2VsX2JhdGNoX3RpbWVvdXRcdTAwM2QyMDAwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2xpY2Vuc2Vfc3RhdHVzXHUwMDNkMFx1MDAyNml0ZHJtX2luamVjdGVkX2xpY2Vuc2Vfc2VydmljZV9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNml0ZHJtX3dpZGV2aW5lX2hhcmRlbmVkX3ZtcF9tb2RlXHUwMDNkbG9nXHUwMDI2anNvbl9jb25kZW5zZWRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2NvbW1hbmRfaGFuZGxlcl9jb21tYW5kX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNmtldmxhcl9kcm9wZG93bl9maXhcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2dlbF9lcnJvcl9yb3V0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX2V4cGFuZF90b3BcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfcGxheV9wYXVzZV9vbl9zY3JpbVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcGxheWJhY2tfYXNzb2NpYXRlZF9xdWV1ZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcXVldWVfdXNlX3VwZGF0ZV9hcGlcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NpbXBfc2hvcnRzX3Jlc2V0X3Njcm9sbFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfdmltaW9fdXNlX3NoYXJlZF9tb25pdG9yXHUwMDNkdHJ1ZVx1MDAyNmxpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNmxpdmVfZnJlc2NhX3YyXHUwMDNkdHJ1ZVx1MDAyNmxvZ19lcnJvcnNfdGhyb3VnaF9ud2xfb25fcmV0cnlcdTAwM2R0cnVlXHUwMDI2bG9nX2dlbF9jb21wcmVzc2lvbl9sYXRlbmN5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19oZWFydGJlYXRfd2l0aF9saWZlY3ljbGVzXHUwMDNkdHJ1ZVx1MDAyNmxvZ193ZWJfZW5kcG9pbnRfdG9fbGF5ZXJcdTAwM2R0cnVlXHUwMDI2bG9nX3dpbmRvd19vbmVycm9yX2ZyYWN0aW9uXHUwMDNkMC4xXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZVx1MDAzZHRydWVcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlX3VmcGhcdTAwM2R0cnVlXHUwMDI2bWF4X2JvZHlfc2l6ZV90b19jb21wcmVzc1x1MDAzZDUwMDAwMFx1MDAyNm1heF9wcmVmZXRjaF93aW5kb3dfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDBcdTAwMjZtYXhfcmVzb2x1dGlvbl9mb3Jfd2hpdGVfbm9pc2VcdTAwM2QzNjBcdTAwMjZtZHhfZW5hYmxlX3ByaXZhY3lfZGlzY2xvc3VyZV91aVx1MDAzZHRydWVcdTAwMjZtZHhfbG9hZF9jYXN0X2FwaV9ib290c3RyYXBfc2NyaXB0XHUwMDNkdHJ1ZVx1MDAyNm1pZ3JhdGVfZXZlbnRzX3RvX3RzXHUwMDNkdHJ1ZVx1MDAyNm1pbl9wcmVmZXRjaF9vZmZzZXRfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDEwXHUwMDI2bXVzaWNfZW5hYmxlX3NoYXJlZF9hdWRpb190aWVyX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfYzNfZW5kc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX2N1c3RvbV9jb250cm9sX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9za2lwcGFibGVzX29uX2ppb19waG9uZVx1MDAzZHRydWVcdTAwMjZtd2ViX211dGVkX2F1dG9wbGF5X2FuaW1hdGlvblx1MDAzZHNocmlua1x1MDAyNm13ZWJfbmF0aXZlX2NvbnRyb2xfaW5fZmF1eF9mdWxsc2NyZWVuX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrX3BvbGxpbmdfaW50ZXJ2YWxcdTAwM2QzMDAwMFx1MDAyNm5ldHdvcmtsZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrbGVzc19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNm5ld19jb2RlY3Nfc3RyaW5nX2FwaV91c2VzX2xlZ2FjeV9zdHlsZVx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mYXN0X29uX3VubG9hZFx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mcm9tX21lbW9yeV93aGVuX29ubGluZVx1MDAzZHRydWVcdTAwMjZvZmZsaW5lX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNnBhY2ZfbG9nZ2luZ19kZWxheV9taWxsaXNlY29uZHNfdGhyb3VnaF95YmZlX3R2XHUwMDNkMzAwMDBcdTAwMjZwYWdlaWRfYXNfaGVhZGVyX3dlYlx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWRzX3NldF9hZGZvcm1hdF9vbl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2FsbG93X2F1dG9uYXZfYWZ0ZXJfcGxheWxpc3RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Jvb3RzdHJhcF9tZXRob2RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RlZmVyX2NhcHRpb25fZGlzcGxheVx1MDAzZDEwMDBcdTAwMjZwbGF5ZXJfZGVzdHJveV9vbGRfdmVyc2lvblx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZG91YmxldGFwX3RvX3NlZWtcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuYWJsZV9wbGF5YmFja19wbGF5bGlzdF9jaGFuZ2VcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuZHNjcmVlbl9lbGxpcHNpc19maXhcdTAwM2R0cnVlXHUwMDI2cGxheWVyX3VuZGVybGF5X21pbl9wbGF5ZXJfd2lkdGhcdTAwM2Q3NjguMFx1MDAyNnBsYXllcl91bmRlcmxheV92aWRlb193aWR0aF9mcmFjdGlvblx1MDAzZDAuNlx1MDAyNnBsYXllcl93ZWJfY2FuYXJ5X3N0YWdlXHUwMDNkMFx1MDAyNnBsYXlyZWFkeV9maXJzdF9wbGF5X2V4cGlyYXRpb25cdTAwM2QtMVx1MDAyNnBvbHltZXJfYmFkX2J1aWxkX2xhYmVsc1x1MDAzZHRydWVcdTAwMjZwb2x5bWVyX2xvZ19wcm9wX2NoYW5nZV9vYnNlcnZlcl9wZXJjZW50XHUwMDNkMFx1MDAyNnBvbHltZXJfdmVyaWZpeV9hcHBfc3RhdGVcdTAwM2R0cnVlXHUwMDI2cHJlc2tpcF9idXR0b25fc3R5bGVfYWRzX2JhY2tlbmRcdTAwM2Rjb3VudGRvd25fbmV4dF90b190aHVtYm5haWxcdTAwMjZxb2VfbndsX2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZxb2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2cmVjb3JkX2FwcF9jcmFzaGVkX3dlYlx1MDAzZHRydWVcdTAwMjZyZXBsYWNlX3BsYXlhYmlsaXR5X3JldHJpZXZlcl9pbl93YXRjaFx1MDAzZHRydWVcdTAwMjZzY2hlZHVsZXJfdXNlX3JhZl9ieV9kZWZhdWx0XHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19oZWFkZXJfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX2ludGVyc3RpdGlhbF9tZXNzYWdlXHUwMDI2c2VsZl9wb2RkaW5nX2hpZ2hsaWdodF9ub25fZGVmYXVsdF9idXR0b25cdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZVx1MDAyNnNlbmRfY29uZmlnX2hhc2hfdGltZXJcdTAwM2QwXHUwMDI2c2V0X2ludGVyc3RpdGlhbF9hZHZlcnRpc2Vyc19xdWVzdGlvbl90ZXh0XHUwMDNkdHJ1ZVx1MDAyNnNob3J0X3N0YXJ0X3RpbWVfcHJlZmVyX3B1Ymxpc2hfaW5fd2F0Y2hfbG9nXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19tb2RlX3RvX3BsYXllcl9hcGlcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX25vX3N0b3BfdmlkZW9fY2FsbFx1MDAzZHRydWVcdTAwMjZzaG91bGRfY2xlYXJfdmlkZW9fZGF0YV9vbl9wbGF5ZXJfY3VlZF91bnN0YXJ0ZWRcdTAwM2R0cnVlXHUwMDI2c2ltcGx5X2VtYmVkZGVkX2VuYWJsZV9ib3RndWFyZFx1MDAzZHRydWVcdTAwMjZza2lwX2lubGluZV9tdXRlZF9saWNlbnNlX3NlcnZpY2VfY2hlY2tcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbnZhbGlkX3l0Y3NpX3RpY2tzXHUwMDNkdHJ1ZVx1MDAyNnNraXBfbHNfZ2VsX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNnNraXBfc2V0dGluZ19pbmZvX2luX2NzaV9kYXRhX29iamVjdFx1MDAzZHRydWVcdTAwMjZzbG93X2NvbXByZXNzaW9uc19iZWZvcmVfYWJhbmRvbl9jb3VudFx1MDAzZDRcdTAwMjZzcGVlZG1hc3Rlcl9jYW5jZWxsYXRpb25fbW92ZW1lbnRfZHBcdTAwM2QwXHUwMDI2c3BlZWRtYXN0ZXJfcGxheWJhY2tfcmF0ZVx1MDAzZDAuMFx1MDAyNnNwZWVkbWFzdGVyX3RvdWNoX2FjdGl2YXRpb25fbXNcdTAwM2QwXHUwMDI2c3RhcnRfY2xpZW50X2djZlx1MDAzZHRydWVcdTAwMjZzdGFydF9jbGllbnRfZ2NmX2Zvcl9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2c3RhcnRfc2VuZGluZ19jb25maWdfaGFzaFx1MDAzZHRydWVcdTAwMjZzdHJlYW1pbmdfZGF0YV9lbWVyZ2VuY3lfaXRhZ19ibGFja2xpc3RcdTAwM2RbXVx1MDAyNnN1YnN0aXR1dGVfYWRfY3BuX21hY3JvX2luX3NzZGFpXHUwMDNkdHJ1ZVx1MDAyNnN1cHByZXNzX2Vycm9yXzIwNF9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNnRyYW5zcG9ydF91c2Vfc2NoZWR1bGVyXHUwMDNkdHJ1ZVx1MDAyNnR2X3BhY2ZfbG9nZ2luZ19zYW1wbGVfcmF0ZVx1MDAzZDAuMDFcdTAwMjZ0dmh0bWw1X3VucGx1Z2dlZF9wcmVsb2FkX2NhY2hlX3NpemVcdTAwM2Q1XHUwMDI2dW5jb3Zlcl9hZF9iYWRnZV9vbl9SVExfdGlueV93aW5kb3dcdTAwM2R0cnVlXHUwMDI2dW5wbHVnZ2VkX2RhaV9saXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZ1bnBsdWdnZWRfdHZodG1sNV92aWRlb19wcmVsb2FkX29uX2ZvY3VzX2RlbGF5X21zXHUwMDNkMFx1MDAyNnVwZGF0ZV9sb2dfZXZlbnRfY29uZmlnXHUwMDNkdHJ1ZVx1MDAyNnVzZV9hY2Nlc3NpYmlsaXR5X2RhdGFfb25fZGVza3RvcF9wbGF5ZXJfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9jb3JlX3NtXHUwMDNkdHJ1ZVx1MDAyNnVzZV9pbmxpbmVkX3BsYXllcl9ycGNcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19jbWxcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19pbl9tZW1vcnlfc3RvcmFnZVx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9pbml0aWFsaXphdGlvblx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zYXdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc3R3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3d0c1x1MDAzZHRydWVcdTAwMjZ1c2VfcGxheWVyX2FidXNlX2JnX2xpYnJhcnlcdTAwM2R0cnVlXHUwMDI2dXNlX3Byb2ZpbGVwYWdlX2V2ZW50X2xhYmVsX2luX2Nhcm91c2VsX3BsYXliYWNrc1x1MDAzZHRydWVcdTAwMjZ1c2VfcmVxdWVzdF90aW1lX21zX2hlYWRlclx1MDAzZHRydWVcdTAwMjZ1c2Vfc2Vzc2lvbl9iYXNlZF9zYW1wbGluZ1x1MDAzZHRydWVcdTAwMjZ1c2VfdHNfdmlzaWJpbGl0eWxvZ2dlclx1MDAzZHRydWVcdTAwMjZ2YXJpYWJsZV9idWZmZXJfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZ2ZXJpZnlfYWRzX2l0YWdfZWFybHlcdTAwM2R0cnVlXHUwMDI2dnA5X2RybV9saXZlXHUwMDNkdHJ1ZVx1MDAyNnZzc19maW5hbF9waW5nX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnZzc19waW5nc191c2luZ19uZXR3b3JrbGVzc1x1MDAzZHRydWVcdTAwMjZ2c3NfcGxheWJhY2tfdXNlX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9hcGlfdXJsXHUwMDNkdHJ1ZVx1MDAyNndlYl9hc3luY19jb250ZXh0X3Byb2Nlc3Nvcl9pbXBsXHUwMDNkc3RhbmRhbG9uZVx1MDAyNndlYl9jaW5lbWF0aWNfd2F0Y2hfc2V0dGluZ3NcdTAwM2R0cnVlXHUwMDI2d2ViX2NsaWVudF92ZXJzaW9uX292ZXJyaWRlXHUwMDNkXHUwMDI2d2ViX2RlZHVwZV92ZV9ncmFmdGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZGVwcmVjYXRlX3NlcnZpY2VfYWpheF9tYXBfZGVwZW5kZW5jeVx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2Vycm9yXzIwNFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2luc3RyZWFtX2Fkc19saW5rX2RlZmluaXRpb25fYTExeV9idWdmaXhcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV92b3pfYXVkaW9fZmVlZGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX2ZpeF9maW5lX3NjcnViYmluZ19kcmFnXHUwMDNkdHJ1ZVx1MDAyNndlYl9mb3JlZ3JvdW5kX2hlYXJ0YmVhdF9pbnRlcnZhbF9tc1x1MDAzZDI4MDAwXHUwMDI2d2ViX2ZvcndhcmRfY29tbWFuZF9vbl9wYmpcdTAwM2R0cnVlXHUwMDI2d2ViX2dlbF9kZWJvdW5jZV9tc1x1MDAzZDYwMDAwXHUwMDI2d2ViX2dlbF90aW1lb3V0X2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfaW5saW5lX3BsYXllcl9ub19wbGF5YmFja191aV9jbGlja19oYW5kbGVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9rZXlfbW9tZW50c19tYXJrZXJzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dfbWVtb3J5X3RvdGFsX2tieXRlc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nZ2luZ19tYXhfYmF0Y2hcdTAwM2QxNTBcdTAwMjZ3ZWJfbW9kZXJuX2Fkc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zX2JsX3N1cnZleVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3NjcnViYmVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlX3N0eWxlXHUwMDNkZmlsbGVkXHUwMDI2d2ViX25ld19hdXRvbmF2X2NvdW50ZG93blx1MDAzZHRydWVcdTAwMjZ3ZWJfb25lX3BsYXRmb3JtX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9vcF9zaWduYWxfdHlwZV9iYW5saXN0XHUwMDNkW11cdTAwMjZ3ZWJfcGF1c2VkX29ubHlfbWluaXBsYXllcl9zaG9ydGN1dF9leHBhbmRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfbG9nX2N0dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF92ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FkZF92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdG9fb3V0Ym91bmRfbGlua3NcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hbHdheXNfZW5hYmxlX2F1dG9fdHJhbnNsYXRpb25cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hcGlfbG9nZ2luZ19mcmFjdGlvblx1MDAzZDAuMDFcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfZW1wdHlfc3VnZ2VzdGlvbnNfZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl90b2dnbGVfYWx3YXlzX2xpc3Rlblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdXNlX3NlcnZlcl9wcm92aWRlZF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2NhcHRpb25fbGFuZ3VhZ2VfcHJlZmVyZW5jZV9zdGlja2luZXNzX2R1cmF0aW9uXHUwMDNkMzBcdTAwMjZ3ZWJfcGxheWVyX2RlY291cGxlX2F1dG9uYXZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9kaXNhYmxlX2lubGluZV9zY3J1YmJpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZWFybHlfd2FybmluZ19zbmFja2Jhclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9mZWF0dXJlZF9wcm9kdWN0X2Jhbm5lcl9vbl9kZXNrdG9wXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX2luX2g1X2FwaVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9wbGF5YmFja19jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pbm5lcnR1YmVfcGxheWxpc3RfdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaXBwX2NhbmFyeV90eXBlX2Zvcl9sb2dnaW5nXHUwMDNkXHUwMDI2d2ViX3BsYXllcl9saXZlX21vbml0b3JfZW52XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbG9nX2NsaWNrX2JlZm9yZV9nZW5lcmF0aW5nX3ZlX2NvbnZlcnNpb25fcGFyYW1zXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbW92ZV9hdXRvbmF2X3RvZ2dsZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX211c2ljX3Zpc3VhbGl6ZXJfdHJlYXRtZW50XHUwMDNkZmFrZVx1MDAyNndlYl9wbGF5ZXJfbXV0YWJsZV9ldmVudF9sYWJlbFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX25pdHJhdGVfcHJvbW9fdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX29mZmxpbmVfcGxheWxpc3RfYXV0b19yZWZyZXNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfcmVzcG9uc2VfcGxheWJhY2tfdHJhY2tpbmdfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlZWtfY2hhcHRlcnNfYnlfc2hvcnRjdXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZW50aW5lbF9pc191bmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG91bGRfaG9ub3JfaW5jbHVkZV9hc3Jfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3dfbXVzaWNfaW5fdGhpc192aWRlb19ncmFwaGljXHUwMDNkdmlkZW9fdGh1bWJuYWlsXHUwMDI2d2ViX3BsYXllcl9zbWFsbF9oYnBfc2V0dGluZ3NfbWVudVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NzX2RhaV9hZF9mZXRjaGluZ190aW1lb3V0X21zXHUwMDNkMTUwMDBcdTAwMjZ3ZWJfcGxheWVyX3NzX21lZGlhX3RpbWVfb2Zmc2V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG9waWZ5X3N1YnRpdGxlc19mb3Jfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG91Y2hfbW9kZV9pbXByb3ZlbWVudHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90cmFuc2Zlcl90aW1lb3V0X3RocmVzaG9sZF9tc1x1MDAzZDEwODAwMDAwXHUwMDI2d2ViX3BsYXllcl91bnNldF9kZWZhdWx0X2Nzbl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdXNlX25ld19hcGlfZm9yX3F1YWxpdHlfcHVsbGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl92ZV9jb252ZXJzaW9uX2ZpeGVzX2Zvcl9jaGFubmVsX2luZm9cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZV9wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wcmVmZXRjaF9wcmVsb2FkX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNndlYl9yb3VuZGVkX3RodW1ibmFpbHNcdTAwM2R0cnVlXHUwMDI2d2ViX3NldHRpbmdzX21lbnVfaWNvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X21ldGhvZFx1MDAzZDBcdTAwMjZ3ZWJfeXRfY29uZmlnX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2d2lsX2ljb25fcmVuZGVyX3doZW5faWRsZVx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfY2xlYW5fdXBfYWZ0ZXJfZW50aXR5X21pZ3JhdGlvblx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfZW5hYmxlX2Rvd25sb2FkX3N0YXR1c1x1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfcGxheWxpc3Rfb3B0aW1pemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2NsZWFyX2VtYmVkZGVkX3BsYXllclx1MDAzZHRydWVcdTAwMjZ5dGlkYl9mZXRjaF9kYXRhc3luY19pZHNfZm9yX2RhdGFfY2xlYW51cFx1MDAzZHRydWVcdTAwMjZ5dGlkYl9yZW1ha2VfZGJfcmV0cmllc1x1MDAzZDFcdTAwMjZ5dGlkYl9yZW9wZW5fZGJfcmV0cmllc1x1MDAzZDBcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0XHUwMDNkMC4wMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfc2Vzc2lvblx1MDAzZDAuMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfdHJhbnNhY3Rpb25cdTAwM2QwLjEiLCJoaWRlSW5mbyI6dHJ1ZSwic3RhcnRNdXRlZCI6dHJ1ZSwiZW5hYmxlTXV0ZWRBdXRvcGxheSI6dHJ1ZSwiY3NwTm9uY2UiOiJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIiwiY2FuYXJ5U3RhdGUiOiJub25lIiwiZW5hYmxlQ3NpTG9nZ2luZyI6dHJ1ZSwiY3NpUGFnZVR5cGUiOiJjaGFubmVscyIsImRhdGFzeW5jSWQiOiJWMjAyMTdmYzZ8fCJ9LCJXRUJfUExBWUVSX0NPTlRFWFRfQ09ORklHX0lEX0tFVkxBUl9TSE9SVFMiOnsicm9vdEVsZW1lbnRJZCI6InNob3J0cy1wbGF5ZXIiLCJqc1VybCI6Ii9zL3BsYXllci9iMTI4ZGRhMC9wbGF5ZXJfaWFzLnZmbHNldC9mcl9GUi9iYXNlLmpzIiwiY3NzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3d3dy1wbGF5ZXIuY3NzIiwiY29udGV4dElkIjoiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfU0hPUlRTIiwiZXZlbnRMYWJlbCI6InNob3J0c3BhZ2UiLCJjb250ZW50UmVnaW9uIjoiRlIiLCJobCI6ImZyX0ZSIiwiaG9zdExhbmd1YWdlIjoiZnIiLCJwbGF5ZXJTdHlsZSI6ImRlc2t0b3AtcG9seW1lciIsImlubmVydHViZUFwaUtleSI6IkFJemFTeUFPX0ZKMlNscVU4UTRTVEVITEdDaWx3X1k5XzExcWNXOCIsImlubmVydHViZUFwaVZlcnNpb24iOiJ2MSIsImlubmVydHViZUNvbnRleHRDbGllbnRWZXJzaW9uIjoiMi4yMDIzMDYwNy4wNi4wMCIsImNvbnRyb2xzVHlwZSI6MCwiZGlzYWJsZUtleWJvYXJkQ29udHJvbHMiOnRydWUsImRpc2FibGVSZWxhdGVkVmlkZW9zIjp0cnVlLCJhbm5vdGF0aW9uc0xvYWRQb2xpY3kiOjMsImRldmljZSI6eyJicmFuZCI6IiIsIm1vZGVsIjoiIiwicGxhdGZvcm0iOiJERVNLVE9QIiwiaW50ZXJmYWNlTmFtZSI6IldFQiIsImludGVyZmFjZVZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIn0sInNlcmlhbGl6ZWRFeHBlcmltZW50SWRzIjoiMjM5ODMyOTYsMjQwMDQ2NDQsMjQwMDcyNDYsMjQwMDc2MTMsMjQwODA3MzgsMjQxMzUzMTAsMjQzNjMxMTQsMjQzNjQ3ODksMjQzNjU1MzQsMjQzNjY5MTcsMjQzNzI3NjEsMjQzNzUxMDEsMjQzNzY3ODUsMjQ0MTU4NjQsMjQ0MTYyOTAsMjQ0MzM2NzksMjQ0Mzc1NzcsMjQ0MzkzNjEsMjQ0NDMzMzEsMjQ0OTk1MzIsMjQ1MzI4NTUsMjQ1NTA0NTgsMjQ1NTA5NTEsMjQ1NTU1NjcsMjQ1NTg2NDEsMjQ1NTkzMjcsMjQ2OTk4OTksMzkzMjMwNzQiLCJzZXJpYWxpemVkRXhwZXJpbWVudEZsYWdzIjoiSDVfYXN5bmNfbG9nZ2luZ19kZWxheV9tc1x1MDAzZDMwMDAwLjBcdTAwMjZINV9lbmFibGVfZnVsbF9wYWNmX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2SDVfdXNlX2FzeW5jX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2YWN0aW9uX2NvbXBhbmlvbl9jZW50ZXJfYWxpZ25fZGVzY3JpcHRpb25cdTAwM2R0cnVlXHUwMDI2YWRfcG9kX2Rpc2FibGVfY29tcGFuaW9uX3BlcnNpc3RfYWRzX3F1YWxpdHlcdTAwM2R0cnVlXHUwMDI2YWRkdG9fYWpheF9sb2dfd2FybmluZ19mcmFjdGlvblx1MDAzZDAuMVx1MDAyNmFsaWduX2FkX3RvX3ZpZGVvX3BsYXllcl9saWZlY3ljbGVfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2YWxsb3dfbGl2ZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19wb2x0ZXJndXN0X2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X3NraXBfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2YXR0X3dlYl9yZWNvcmRfbWV0cmljc1x1MDAzZHRydWVcdTAwMjZhdXRvcGxheV90aW1lXHUwMDNkODAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX2Z1bGxzY3JlZW5cdTAwM2QzMDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfbXVzaWNfY29udGVudFx1MDAzZDMwMDBcdTAwMjZiZ192bV9yZWluaXRfdGhyZXNob2xkXHUwMDNkNzIwMDAwMFx1MDAyNmJsb2NrZWRfcGFja2FnZXNfZm9yX3Nwc1x1MDAzZFtdXHUwMDI2Ym90Z3VhcmRfYXN5bmNfc25hcHNob3RfdGltZW91dF9tc1x1MDAzZDMwMDBcdTAwMjZjaGVja19hZF91aV9zdGF0dXNfZm9yX213ZWJfc2FmYXJpXHUwMDNkdHJ1ZVx1MDAyNmNoZWNrX25hdmlnYXRvcl9hY2N1cmFjeV90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmNsZWFyX3VzZXJfcGFydGl0aW9uZWRfbHNcdTAwM2R0cnVlXHUwMDI2Y2xpZW50X3Jlc3BlY3RfYXV0b3BsYXlfc3dpdGNoX2J1dHRvbl9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZjb21wcmVzc19nZWxcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3Npb25fZGlzYWJsZV9wb2ludFx1MDAzZDEwXHUwMDI2Y29tcHJlc3Npb25fcGVyZm9ybWFuY2VfdGhyZXNob2xkXHUwMDNkMjUwXHUwMDI2Y3NpX29uX2dlbFx1MDAzZHRydWVcdTAwMjZkYXNoX21hbmlmZXN0X3ZlcnNpb25cdTAwM2Q1XHUwMDI2ZGVidWdfYmFuZGFpZF9ob3N0bmFtZVx1MDAzZFx1MDAyNmRlYnVnX3NoZXJsb2dfdXNlcm5hbWVcdTAwM2RcdTAwMjZkZWxheV9hZHNfZ3ZpX2NhbGxfb25fYnVsbGVpdF9saXZpbmdfcm9vbV9tc1x1MDAzZDBcdTAwMjZkZXByZWNhdGVfY3NpX2hhc19pbmZvXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV9wYWlyX3NlcnZsZXRfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX2NoaWxkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfcGFyZW50XHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfaW1hZ2VfY3RhX25vX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9sb2dfaW1nX2NsaWNrX2xvY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3Bfc3BhcmtsZXNfbGlnaHRfY3RhX2J1dHRvblx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoYW5uZWxfaWRfY2hlY2tfZm9yX3N1c3BlbmRlZF9jaGFubmVsc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoaWxkX25vZGVfYXV0b19mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2RlZmVyX2FkbW9kdWxlX29uX2FkdmVydGlzZXJfdmlkZW9cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9mZWF0dXJlc19mb3Jfc3VwZXhcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9sZWdhY3lfZGVza3RvcF9yZW1vdGVfcXVldWVcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9tZHhfY29ubmVjdGlvbl9pbl9tZHhfbW9kdWxlX2Zvcl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9uZXdfcGF1c2Vfc3RhdGUzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcGFjZl9sb2dnaW5nX2Zvcl9tZW1vcnlfbGltaXRlZF90dlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3JvdW5kaW5nX2FkX25vdGlmeVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NpbXBsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zc2RhaV9vbl9lcnJvcnNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90YWJiaW5nX2JlZm9yZV9mbHlvdXRfYWRfZWxlbWVudHNfYXBwZWFyXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGh1bWJuYWlsX3ByZWxvYWRpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2Rpc2FibGVfcHJvZ3Jlc3NfYmFyX2NvbnRleHRfbWVudV9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZW5hYmxlX2FsbG93X3dhdGNoX2FnYWluX2VuZHNjcmVlbl9mb3JfZWxpZ2libGVfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc192ZV9jb252ZXJzaW9uX3BhcmFtX3JlbmFtaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2F1dG9wbGF5X25vdF9zdXBwb3J0ZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfY3VlX3ZpZGVvX3VucGxheWFibGVfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2hvdXNlX2JyYW5kX2FuZF95dF9jb2V4aXN0ZW5jZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2FkX3BsYXllcl9mcm9tX3BhZ2Vfc2hvd1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dfc3BsYXlfYXNfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nZ2luZ19ldmVudF9oYW5kbGVyc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2R0dHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbmV3X2NvbnRleHRfbWVudV90cmlnZ2VyaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BhdXNlX292ZXJsYXlfd25fdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BlbV9kb21haW5fZml4X2Zvcl9hZF9yZXF1ZXN0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZnBfdW5icmFuZGVkX2VsX2RlcHJlY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JjYXRfYWxsb3dsaXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JlcGxhY2VfdW5sb2FkX3dfcGFnZWhpZGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfc2NyaXB0ZWRfcGxheWJhY2tfYmxvY2tlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdHJhY2tpbmdfbm9fYWxsb3dfbGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2hpZGVfdW5maWxsZWRfbW9yZV92aWRlb3Nfc3VnZ2VzdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9saXRlX21vZGVcdTAwM2QxXHUwMDI2ZW1iZWRzX3dlYl9ud2xfZGlzYWJsZV9ub2Nvb2tpZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3Nob3BwaW5nX292ZXJsYXlfbm9fd2FpdF9mb3JfcGFpZF9jb250ZW50X292ZXJsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zeW50aF9jaF9oZWFkZXJzX2Jhbm5lZF91cmxzX3JlZ2V4XHUwMDNkXHUwMDI2ZW5hYmxlX2FiX3JwX2ludFx1MDAzZHRydWVcdTAwMjZlbmFibGVfYWRfY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FwcF9wcm9tb19lbmRjYXBfZW1sX29uX3RhYmxldFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9mb3Jfd2ViX3VucGx1Z2dlZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9vbl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9wYWdlX2lkX2hlYWRlcl9mb3JfZmlyc3RfcGFydHlfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9zbGlfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZGlzY3JldGVfbGl2ZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudF9jaGVja1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRzX2ljb25fd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9ldmljdGlvbl9wcm90ZWN0aW9uX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9nZWxfbG9nX2NvbW1hbmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV9pbnN0cmVhbV93YXRjaF9uZXh0X3BhcmFtc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X3ZpZGVvX2Fkc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2hhbmRsZXNfYWNjb3VudF9tZW51X3N3aXRjaGVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9rYWJ1a2lfY29tbWVudHNfb25fc2hvcnRzXHUwMDNkZGlzYWJsZWRcdTAwMjZlbmFibGVfbGl2ZV9wcmVtaWVyZV93ZWJfcGxheWVyX2luZGljYXRvclx1MDAzZHRydWVcdTAwMjZlbmFibGVfbHJfaG9tZV9pbmZlZWRfYWRzX2lubGluZV9wbGF5YmFja19wcm9ncmVzc19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9td2ViX2VuZGNhcF9jbGlja2FibGVfaWNvbl9kZXNjcmlwdGlvblx1MDAzZHRydWVcdTAwMjZlbmFibGVfbXdlYl9saXZlc3RyZWFtX3VpX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbmFibGVfbmV3X3BhaWRfcHJvZHVjdF9wbGFjZW1lbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2Zfc2xvdF9hc2RlX3BsYXllcl9ieXRlX2g1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZfZm9yX3BhZ2VfdG9wX2Zvcm1hdHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95c2ZlX3R2XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYXNzX3NkY19nZXRfYWNjb3VudHNfbGlzdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGxfcl9jXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2ZpeF9vbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2luX3R2aHRtbDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NlcnZlcl9zdGl0Y2hlZF9kYWlcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Nob3J0c19wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NraXBfYWRfZ3VpZGFuY2VfcHJvbXB0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwcGFibGVfYWRzX2Zvcl91bnBsdWdnZWRfYWRfcG9kXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90ZWN0b25pY19hZF91eF9mb3JfaGFsZnRpbWVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RoaXJkX3BhcnR5X2luZm9cdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RvcHNvaWxfd3RhX2Zvcl9oYWxmdGltZV9saXZlX2luZnJhXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfbWVkaWFfc2Vzc2lvbl9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3dlYl9zY2hlZHVsZXJfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfd25faW5mb2NhcmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV95dF9hdGFfaWZyYW1lX2F1dGh1c2VyXHUwMDNkdHJ1ZVx1MDAyNmVycm9yX21lc3NhZ2VfZm9yX2dzdWl0ZV9uZXR3b3JrX3Jlc3RyaWN0aW9uc1x1MDAzZHRydWVcdTAwMjZleHBvcnRfbmV0d29ya2xlc3Nfb3B0aW9uc1x1MDAzZHRydWVcdTAwMjZleHRlcm5hbF9mdWxsc2NyZWVuX3dpdGhfZWR1XHUwMDNkdHJ1ZVx1MDAyNmZhc3RfYXV0b25hdl9pbl9iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmZldGNoX2F0dF9pbmRlcGVuZGVudGx5XHUwMDNkdHJ1ZVx1MDAyNmZpbGxfc2luZ2xlX3ZpZGVvX3dpdGhfbm90aWZ5X3RvX2xhc3JcdTAwM2R0cnVlXHUwMDI2ZmlsdGVyX3ZwOV9mb3JfY3NkYWlcdTAwM2R0cnVlXHUwMDI2Zml4X2Fkc190cmFja2luZ19mb3Jfc3dmX2NvbmZpZ19kZXByZWNhdGlvbl9td2ViXHUwMDNkdHJ1ZVx1MDAyNmdjZl9jb25maWdfc3RvcmVfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZnZWxfcXVldWVfdGltZW91dF9tYXhfbXNcdTAwM2QzMDAwMDBcdTAwMjZncGFfc3BhcmtsZXNfdGVuX3BlcmNlbnRfbGF5ZXJcdTAwM2R0cnVlXHUwMDI2Z3ZpX2NoYW5uZWxfY2xpZW50X3NjcmVlblx1MDAzZHRydWVcdTAwMjZoNV9jb21wYW5pb25fZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX2dlbmVyaWNfZXJyb3JfbG9nZ2luZ19ldmVudFx1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfdW5pZmllZF9jc2lfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZoNV9pbnBsYXllcl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9yZXNldF9jYWNoZV9hbmRfZmlsdGVyX2JlZm9yZV91cGRhdGVfbWFzdGhlYWRcdTAwM2R0cnVlXHUwMDI2aGVhdHNlZWtlcl9kZWNvcmF0aW9uX3RocmVzaG9sZFx1MDAzZDAuMFx1MDAyNmhmcl9kcm9wcGVkX2ZyYW1lcmF0ZV9mYWxsYmFja190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aGlkZV9lbmRwb2ludF9vdmVyZmxvd19vbl95dGRfZGlzcGxheV9hZF9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZodG1sNV9hZF90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2Fkc19wcmVyb2xsX2xvY2tfdGltZW91dF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfYWxsb3dfZGlzY29udGlndW91c19zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWxsb3dfdmlkZW9fa2V5ZnJhbWVfd2l0aG91dF9hdWRpb1x1MDAzZHRydWVcdTAwMjZodG1sNV9hdHRhY2hfbnVtX3JhbmRvbV9ieXRlc190b19iYW5kYWlkXHUwMDNkMFx1MDAyNmh0bWw1X2F0dGFjaF9wb190b2tlbl90b19iYW5kYWlkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F1dG9uYXZfY2FwX2lkbGVfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9hdXRvbmF2X3F1YWxpdHlfY2FwXHUwMDNkNzIwXHUwMDI2aHRtbDVfYXV0b3BsYXlfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9ibG9ja19waXBfc2FmYXJpX2RlbGF5XHUwMDNkMFx1MDAyNmh0bWw1X2JtZmZfbmV3X2ZvdXJjY19jaGVja1x1MDAzZHRydWVcdTAwMjZodG1sNV9jb2JhbHRfZGVmYXVsdF9idWZmZXJfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWF4X3NpemVfZm9yX2ltbWVkX2pvYlx1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWluX3Byb2Nlc3Nvcl9jbnRfdG9fb2ZmbG9hZF9hbGdvXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9vdmVycmlkZV9xdWljXHUwMDNkMFx1MDAyNmh0bWw1X2NvbnN1bWVfbWVkaWFfYnl0ZXNfc2xpY2VfaW5mb3NcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVfZHVwZV9jb250ZW50X3ZpZGVvX2xvYWRzX2luX2xpZmVjeWNsZV9hcGlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVidWdfZGF0YV9sb2dfcHJvYmFiaWxpdHlcdTAwM2QwLjFcdTAwMjZodG1sNV9kZWNvZGVfdG9fdGV4dHVyZV9jYXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVmYXVsdF9hZF9nYWluXHUwMDNkMC41XHUwMDI2aHRtbDVfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9hZF9tb2R1bGVfbXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfZmV0Y2hfYXR0X21zXHUwMDNkMTAwMFx1MDAyNmh0bWw1X2RlZmVyX21vZHVsZXNfZGVsYXlfdGltZV9taWxsaXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9jb3VudFx1MDAzZDFcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2RlbGF5X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X2RlcHJlY2F0ZV92aWRlb190YWdfcG9vbFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZXNrdG9wX3ZyMTgwX2FsbG93X3Bhbm5pbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGZfZG93bmdyYWRlX3RocmVzaFx1MDAzZDAuMlx1MDAyNmh0bWw1X2Rpc2FibGVfY3NpX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbW92ZV9wc3NoX3RvX21vb3ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9ub25fY29udGlndW91c1x1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNwbGF5ZWRfZnJhbWVfcmF0ZV9kb3duZ3JhZGVfdGhyZXNob2xkXHUwMDNkNDVcdTAwMjZodG1sNV9kcm1fY2hlY2tfYWxsX2tleV9lcnJvcl9zdGF0ZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZHJtX2NwaV9saWNlbnNlX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hZHNfY2xpZW50X21vbml0b3JpbmdfbG9nX3R2XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jYXB0aW9uX2NoYW5nZXNfZm9yX21vc2FpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2xpZW50X2hpbnRzX292ZXJyaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jb21wb3NpdGVfZW1iYXJnb1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZWFjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZW1iZWRkZWRfcGxheWVyX3Zpc2liaWxpdHlfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbm9uX25vdGlmeV9jb21wb3NpdGVfdm9kX2xzYXJfcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfc2luZ2xlX3ZpZGVvX3ZvZF9pdmFyX29uX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZGFzaFx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19lbmNyeXB0ZWRfdnA5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfYWxjXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfZmFzdF9saW5lYXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5jb3VyYWdlX2FycmF5X2NvYWxlc2NpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2FwbGVzc19lbmRlZF90cmFuc2l0aW9uX2J1ZmZlcl9tc1x1MDAzZDIwMFx1MDAyNmh0bWw1X2dlbmVyYXRlX3Nlc3Npb25fcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2xfZnBzX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZodG1sNV9oZGNwX3Byb2Jpbmdfc3RyZWFtX3VybFx1MDAzZFx1MDAyNmh0bWw1X2hmcl9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QxLjBcdTAwMjZodG1sNV9pZGxlX3JhdGVfbGltaXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX2ZhaXJwbGF5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9wbGF5cmVhZHlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3dpZGV2aW5lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczRfc2Vla19hYm92ZV96ZXJvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczdfZm9yY2VfcGxheV9vbl9zdGFsbFx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3NfZm9yY2Vfc2Vla190b196ZXJvX29uX3N0b3BcdTAwM2R0cnVlXHUwMDI2aHRtbDVfanVtYm9fbW9iaWxlX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDMuMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9ub25zdHJlYW1pbmdfbWZmYV9tc1x1MDAzZDQwMDBcdTAwMjZodG1sNV9qdW1ib191bGxfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMS4zXHUwMDI2aHRtbDVfbGljZW5zZV9jb25zdHJhaW50X2RlbGF5XHUwMDNkNTAwMFx1MDAyNmh0bWw1X2xpdmVfYWJyX2hlYWRfbWlzc19mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYWJyX3JlcHJlZGljdF9mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYnl0ZXJhdGVfZmFjdG9yX2Zvcl9yZWFkYWhlYWRcdTAwM2QxLjNcdTAwMjZodG1sNV9saXZlX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9saXZlX25vcm1hbF9sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2xpdmVfdWx0cmFfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xvZ19hdWRpb19hYnJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX2V4cGVyaW1lbnRfaWRfZnJvbV9wbGF5ZXJfcmVzcG9uc2VfdG9fY3RtcFx1MDAzZFx1MDAyNmh0bWw1X2xvZ19maXJzdF9zc2RhaV9yZXF1ZXN0c19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19yZWJ1ZmZlcl9ldmVudHNcdTAwM2Q1XHUwMDI2aHRtbDVfbG9nX3NzZGFpX2ZhbGxiYWNrX2Fkc1x1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfdHJpZ2dlcl9ldmVudHNfd2l0aF9kZWJ1Z19kYXRhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX3RocmVzaG9sZF9tc1x1MDAzZDMwMDAwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3NlZ19kcmlmdF9saW1pdF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc191bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3ZwOV9vdGZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWF4X2RyaWZ0X3Blcl90cmFja19zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWF4X2hlYWRtX2Zvcl9zdHJlYW1pbmdfeGhyXHUwMDNkMFx1MDAyNmh0bWw1X21heF9saXZlX2R2cl93aW5kb3dfcGx1c19tYXJnaW5fc2Vjc1x1MDAzZDQ2ODAwLjBcdTAwMjZodG1sNV9tYXhfcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21heF9yZWRpcmVjdF9yZXNwb25zZV9sZW5ndGhcdTAwM2Q4MTkyXHUwMDI2aHRtbDVfbWF4X3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21heF9zb3VyY2VfYnVmZmVyX2FwcGVuZF9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X21heGltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9tZWRpYV9mdWxsc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21mbF9leHRlbmRfbWF4X3JlcXVlc3RfdGltZVx1MDAzZHRydWVcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9jYXBfc2Vjc1x1MDAzZDYwXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9taW5fc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfYWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbm9fcGxhY2Vob2xkZXJfcm9sbGJhY2tzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vbl9uZXR3b3JrX3JlYnVmZmVyX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X25vbl9vbmVzaWVfYXR0YWNoX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vdF9yZWdpc3Rlcl9kaXNwb3NhYmxlc193aGVuX2NvcmVfbGlzdGVuc1x1MDAzZHRydWVcdTAwMjZodG1sNV9vZmZsaW5lX2ZhaWx1cmVfcmV0cnlfbGltaXRcdTAwM2QyXHUwMDI2aHRtbDVfb25lc2llX2RlZmVyX2NvbnRlbnRfbG9hZGVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9ob3N0X3JhY2luZ19jYXBfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2lnbm9yZV9pbm5lcnR1YmVfYXBpX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbGl2ZV90dGxfc2Vjc1x1MDAzZDhcdTAwMjZodG1sNV9vbmVzaWVfbm9uemVyb19wbGF5YmFja19zdGFydFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbm90aWZ5X2N1ZXBvaW50X21hbmFnZXJfb25fY29tcGxldGlvblx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9jb29sZG93bl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9pbnRlcnZhbF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9tYXhfbGFjdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlcXVlc3RfdGltZW91dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9vbmVzaWVfc3RpY2t5X3NlcnZlcl9zaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BhdXNlX29uX25vbmZvcmVncm91bmRfcGxhdGZvcm1fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlYWtfc2hhdmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZl9jYXBfb3ZlcnJpZGVfc3RpY2t5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2NhcF9mbG9vclx1MDAzZDM2MFx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2ltcGFjdF9wcm9maWxpbmdfdGltZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcGVyc2VydmVfYXYxX3BlcmZfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX21pbmltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9wbGF5ZXJfYXV0b25hdl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXllcl9keW5hbWljX2JvdHRvbV9ncmFkaWVudFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfbWluX2J1aWxkX2NsXHUwMDNkLTFcdTAwMjZodG1sNV9wbGF5ZXJfcHJlbG9hZF9hZF9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcG9zdF9pbnRlcnJ1cHRfcmVhZGFoZWFkXHUwMDNkMjBcdTAwMjZodG1sNV9wcmVmZXJfc2VydmVyX2J3ZTNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcHJlbG9hZF93YWl0X3RpbWVfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Byb2JlX3ByaW1hcnlfZGVsYXlfYmFzZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9wcm9jZXNzX2FsbF9lbmNyeXB0ZWRfZXZlbnRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3FvZV9saF9tYXhfcmVwb3J0X2NvdW50XHUwMDNkMFx1MDAyNmh0bWw1X3FvZV9saF9taW5fZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfcXVlcnlfc3dfc2VjdXJlX2NyeXB0b19mb3JfYW5kcm9pZFx1MDAzZHRydWVcdTAwMjZodG1sNV9yYW5kb21fcGxheWJhY2tfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X3JlY29nbml6ZV9wcmVkaWN0X3N0YXJ0X2N1ZV9wb2ludFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfY29tbWFuZF90cmlnZ2VyZWRfY29tcGFuaW9uc1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfbm90X3NlcnZhYmxlX2NoZWNrX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVuYW1lX2FwYnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X2ZhdGFsX2RybV9yZXN0cmljdGVkX2Vycm9yX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X3Nsb3dfYWRzX2FzX2Vycm9yXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfb25seV9oZHJfb3Jfc2RyX2tleXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVxdWVzdF9zaXppbmdfbXVsdGlwbGllclx1MDAzZDAuOFx1MDAyNmh0bWw1X3Jlc2V0X21lZGlhX3N0cmVhbV9vbl91bnJlc3VtYWJsZV9zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVzb3VyY2VfYmFkX3N0YXR1c19kZWxheV9zY2FsaW5nXHUwMDNkMS41XHUwMDI2aHRtbDVfcmVzdHJpY3Rfc3RyZWFtaW5nX3hocl9vbl9zcWxlc3NfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2FmYXJpX2Rlc2t0b3BfZW1lX21pbl92ZXJzaW9uXHUwMDNkMFx1MDAyNmh0bWw1X3NhbXN1bmdfa2FudF9saW1pdF9tYXhfYml0cmF0ZVx1MDAzZDBcdTAwMjZodG1sNV9zZWVrX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2Q4MDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9kZWxheV9tc1x1MDAzZDEyMDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfYnVmZmVyX3JhbmdlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX3Zyc19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2NmbFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfc2V0X2NtdF9kZWxheV9tc1x1MDAzZDIwMDBcdTAwMjZodG1sNV9zZWVrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NlcnZlcl9zdGl0Y2hlZF9kYWlfZGVjb3JhdGVkX3VybF9yZXRyeV9saW1pdFx1MDAzZDVcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2dyb3VwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Nlc3Npb25fcG9fdG9rZW5faW50ZXJ2YWxfdGltZV9tc1x1MDAzZDkwMDAwMFx1MDAyNmh0bWw1X3NraXBfb29iX3N0YXJ0X3NlY29uZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2tpcF9zbG93X2FkX2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9za2lwX3N1Yl9xdWFudHVtX2Rpc2NvbnRpbnVpdHlfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfbm9fbWVkaWFfc291cmNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfdGltZW91dF9kZWxheV9tc1x1MDAzZDIwMDAwXHUwMDI2aHRtbDVfc3NkYWlfYWRmZXRjaF9keW5hbWljX3RpbWVvdXRfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfc3NkYWlfZW5hYmxlX25ld19zZWVrX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N0YXRlZnVsX2F1ZGlvX21pbl9hZGp1c3RtZW50X3ZhbHVlXHUwMDNkMFx1MDAyNmh0bWw1X3N0YXRpY19hYnJfcmVzb2x1dGlvbl9zaGVsZlx1MDAzZDBcdTAwMjZodG1sNV9zdG9yZV94aHJfaGVhZGVyc19yZWFkYWJsZVx1MDAzZHRydWVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9sb2FkX3NwZWVkX2NoZWNrX2ludGVydmFsXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuMjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzX29uX3RpbWVvdXRcdTAwM2QwLjFcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fbG9hZF9zcGVlZFx1MDAzZDEuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3NlZWtfbGF0ZW5jeV9mdWRnZVx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldF9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90aW1lb3V0X3NlY3NcdTAwM2QyLjBcdTAwMjZodG1sNV91Z2NfbGl2ZV9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91Z2Nfdm9kX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VucmVwb3J0ZWRfc2Vla19yZXNlZWtfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfdW5yZXN0cmljdGVkX2xheWVyX2hpZ2hfcmVzX2xvZ2dpbmdfcGVyY2VudFx1MDAzZDAuMFx1MDAyNmh0bWw1X3VybF9wYWRkaW5nX2xlbmd0aFx1MDAzZDBcdTAwMjZodG1sNV91cmxfc2lnbmF0dXJlX2V4cGlyeV90aW1lX2hvdXJzXHUwMDNkMFx1MDAyNmh0bWw1X3VzZV9wb3N0X2Zvcl9tZWRpYVx1MDAzZHRydWVcdTAwMjZodG1sNV91c2VfdW1wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ZpZGVvX3RiZF9taW5fa2JcdTAwM2QwXHUwMDI2aHRtbDVfdmlld3BvcnRfdW5kZXJzZW5kX21heGltdW1cdTAwM2QwLjBcdTAwMjZodG1sNV92b2x1bWVfc2xpZGVyX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2ViX2VuYWJsZV9oYWxmdGltZV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYnBvX2lkbGVfcHJpb3JpdHlfam9iXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvZmZsZV9yZXN1bWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29ya2Fyb3VuZF9kZWxheV90cmlnZ2VyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3l0dmxyX2VuYWJsZV9zaW5nbGVfc2VsZWN0X3N1cnZleVx1MDAzZHRydWVcdTAwMjZpZ25vcmVfb3ZlcmxhcHBpbmdfY3VlX3BvaW50c19vbl9lbmRlbWljX2xpdmVfaHRtbDVcdTAwM2R0cnVlXHUwMDI2aWxfdXNlX3ZpZXdfbW9kZWxfbG9nZ2luZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNmluaXRpYWxfZ2VsX2JhdGNoX3RpbWVvdXRcdTAwM2QyMDAwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2xpY2Vuc2Vfc3RhdHVzXHUwMDNkMFx1MDAyNml0ZHJtX2luamVjdGVkX2xpY2Vuc2Vfc2VydmljZV9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNml0ZHJtX3dpZGV2aW5lX2hhcmRlbmVkX3ZtcF9tb2RlXHUwMDNkbG9nXHUwMDI2anNvbl9jb25kZW5zZWRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2NvbW1hbmRfaGFuZGxlcl9jb21tYW5kX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNmtldmxhcl9kcm9wZG93bl9maXhcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2dlbF9lcnJvcl9yb3V0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX2V4cGFuZF90b3BcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfcGxheV9wYXVzZV9vbl9zY3JpbVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcGxheWJhY2tfYXNzb2NpYXRlZF9xdWV1ZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcXVldWVfdXNlX3VwZGF0ZV9hcGlcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NpbXBfc2hvcnRzX3Jlc2V0X3Njcm9sbFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfdmltaW9fdXNlX3NoYXJlZF9tb25pdG9yXHUwMDNkdHJ1ZVx1MDAyNmxpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNmxpdmVfZnJlc2NhX3YyXHUwMDNkdHJ1ZVx1MDAyNmxvZ19lcnJvcnNfdGhyb3VnaF9ud2xfb25fcmV0cnlcdTAwM2R0cnVlXHUwMDI2bG9nX2dlbF9jb21wcmVzc2lvbl9sYXRlbmN5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19oZWFydGJlYXRfd2l0aF9saWZlY3ljbGVzXHUwMDNkdHJ1ZVx1MDAyNmxvZ193ZWJfZW5kcG9pbnRfdG9fbGF5ZXJcdTAwM2R0cnVlXHUwMDI2bG9nX3dpbmRvd19vbmVycm9yX2ZyYWN0aW9uXHUwMDNkMC4xXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZVx1MDAzZHRydWVcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlX3VmcGhcdTAwM2R0cnVlXHUwMDI2bWF4X2JvZHlfc2l6ZV90b19jb21wcmVzc1x1MDAzZDUwMDAwMFx1MDAyNm1heF9wcmVmZXRjaF93aW5kb3dfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDBcdTAwMjZtYXhfcmVzb2x1dGlvbl9mb3Jfd2hpdGVfbm9pc2VcdTAwM2QzNjBcdTAwMjZtZHhfZW5hYmxlX3ByaXZhY3lfZGlzY2xvc3VyZV91aVx1MDAzZHRydWVcdTAwMjZtZHhfbG9hZF9jYXN0X2FwaV9ib290c3RyYXBfc2NyaXB0XHUwMDNkdHJ1ZVx1MDAyNm1pZ3JhdGVfZXZlbnRzX3RvX3RzXHUwMDNkdHJ1ZVx1MDAyNm1pbl9wcmVmZXRjaF9vZmZzZXRfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDEwXHUwMDI2bXVzaWNfZW5hYmxlX3NoYXJlZF9hdWRpb190aWVyX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfYzNfZW5kc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX2N1c3RvbV9jb250cm9sX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9za2lwcGFibGVzX29uX2ppb19waG9uZVx1MDAzZHRydWVcdTAwMjZtd2ViX211dGVkX2F1dG9wbGF5X2FuaW1hdGlvblx1MDAzZHNocmlua1x1MDAyNm13ZWJfbmF0aXZlX2NvbnRyb2xfaW5fZmF1eF9mdWxsc2NyZWVuX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrX3BvbGxpbmdfaW50ZXJ2YWxcdTAwM2QzMDAwMFx1MDAyNm5ldHdvcmtsZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrbGVzc19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNm5ld19jb2RlY3Nfc3RyaW5nX2FwaV91c2VzX2xlZ2FjeV9zdHlsZVx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mYXN0X29uX3VubG9hZFx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mcm9tX21lbW9yeV93aGVuX29ubGluZVx1MDAzZHRydWVcdTAwMjZvZmZsaW5lX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNnBhY2ZfbG9nZ2luZ19kZWxheV9taWxsaXNlY29uZHNfdGhyb3VnaF95YmZlX3R2XHUwMDNkMzAwMDBcdTAwMjZwYWdlaWRfYXNfaGVhZGVyX3dlYlx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWRzX3NldF9hZGZvcm1hdF9vbl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2FsbG93X2F1dG9uYXZfYWZ0ZXJfcGxheWxpc3RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Jvb3RzdHJhcF9tZXRob2RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RlZmVyX2NhcHRpb25fZGlzcGxheVx1MDAzZDEwMDBcdTAwMjZwbGF5ZXJfZGVzdHJveV9vbGRfdmVyc2lvblx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZG91YmxldGFwX3RvX3NlZWtcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuYWJsZV9wbGF5YmFja19wbGF5bGlzdF9jaGFuZ2VcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuZHNjcmVlbl9lbGxpcHNpc19maXhcdTAwM2R0cnVlXHUwMDI2cGxheWVyX3VuZGVybGF5X21pbl9wbGF5ZXJfd2lkdGhcdTAwM2Q3NjguMFx1MDAyNnBsYXllcl91bmRlcmxheV92aWRlb193aWR0aF9mcmFjdGlvblx1MDAzZDAuNlx1MDAyNnBsYXllcl93ZWJfY2FuYXJ5X3N0YWdlXHUwMDNkMFx1MDAyNnBsYXlyZWFkeV9maXJzdF9wbGF5X2V4cGlyYXRpb25cdTAwM2QtMVx1MDAyNnBvbHltZXJfYmFkX2J1aWxkX2xhYmVsc1x1MDAzZHRydWVcdTAwMjZwb2x5bWVyX2xvZ19wcm9wX2NoYW5nZV9vYnNlcnZlcl9wZXJjZW50XHUwMDNkMFx1MDAyNnBvbHltZXJfdmVyaWZpeV9hcHBfc3RhdGVcdTAwM2R0cnVlXHUwMDI2cHJlc2tpcF9idXR0b25fc3R5bGVfYWRzX2JhY2tlbmRcdTAwM2Rjb3VudGRvd25fbmV4dF90b190aHVtYm5haWxcdTAwMjZxb2VfbndsX2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZxb2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2cmVjb3JkX2FwcF9jcmFzaGVkX3dlYlx1MDAzZHRydWVcdTAwMjZyZXBsYWNlX3BsYXlhYmlsaXR5X3JldHJpZXZlcl9pbl93YXRjaFx1MDAzZHRydWVcdTAwMjZzY2hlZHVsZXJfdXNlX3JhZl9ieV9kZWZhdWx0XHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19oZWFkZXJfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX2ludGVyc3RpdGlhbF9tZXNzYWdlXHUwMDI2c2VsZl9wb2RkaW5nX2hpZ2hsaWdodF9ub25fZGVmYXVsdF9idXR0b25cdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZVx1MDAyNnNlbmRfY29uZmlnX2hhc2hfdGltZXJcdTAwM2QwXHUwMDI2c2V0X2ludGVyc3RpdGlhbF9hZHZlcnRpc2Vyc19xdWVzdGlvbl90ZXh0XHUwMDNkdHJ1ZVx1MDAyNnNob3J0X3N0YXJ0X3RpbWVfcHJlZmVyX3B1Ymxpc2hfaW5fd2F0Y2hfbG9nXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19tb2RlX3RvX3BsYXllcl9hcGlcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX25vX3N0b3BfdmlkZW9fY2FsbFx1MDAzZHRydWVcdTAwMjZzaG91bGRfY2xlYXJfdmlkZW9fZGF0YV9vbl9wbGF5ZXJfY3VlZF91bnN0YXJ0ZWRcdTAwM2R0cnVlXHUwMDI2c2ltcGx5X2VtYmVkZGVkX2VuYWJsZV9ib3RndWFyZFx1MDAzZHRydWVcdTAwMjZza2lwX2lubGluZV9tdXRlZF9saWNlbnNlX3NlcnZpY2VfY2hlY2tcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbnZhbGlkX3l0Y3NpX3RpY2tzXHUwMDNkdHJ1ZVx1MDAyNnNraXBfbHNfZ2VsX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNnNraXBfc2V0dGluZ19pbmZvX2luX2NzaV9kYXRhX29iamVjdFx1MDAzZHRydWVcdTAwMjZzbG93X2NvbXByZXNzaW9uc19iZWZvcmVfYWJhbmRvbl9jb3VudFx1MDAzZDRcdTAwMjZzcGVlZG1hc3Rlcl9jYW5jZWxsYXRpb25fbW92ZW1lbnRfZHBcdTAwM2QwXHUwMDI2c3BlZWRtYXN0ZXJfcGxheWJhY2tfcmF0ZVx1MDAzZDAuMFx1MDAyNnNwZWVkbWFzdGVyX3RvdWNoX2FjdGl2YXRpb25fbXNcdTAwM2QwXHUwMDI2c3RhcnRfY2xpZW50X2djZlx1MDAzZHRydWVcdTAwMjZzdGFydF9jbGllbnRfZ2NmX2Zvcl9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2c3RhcnRfc2VuZGluZ19jb25maWdfaGFzaFx1MDAzZHRydWVcdTAwMjZzdHJlYW1pbmdfZGF0YV9lbWVyZ2VuY3lfaXRhZ19ibGFja2xpc3RcdTAwM2RbXVx1MDAyNnN1YnN0aXR1dGVfYWRfY3BuX21hY3JvX2luX3NzZGFpXHUwMDNkdHJ1ZVx1MDAyNnN1cHByZXNzX2Vycm9yXzIwNF9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNnRyYW5zcG9ydF91c2Vfc2NoZWR1bGVyXHUwMDNkdHJ1ZVx1MDAyNnR2X3BhY2ZfbG9nZ2luZ19zYW1wbGVfcmF0ZVx1MDAzZDAuMDFcdTAwMjZ0dmh0bWw1X3VucGx1Z2dlZF9wcmVsb2FkX2NhY2hlX3NpemVcdTAwM2Q1XHUwMDI2dW5jb3Zlcl9hZF9iYWRnZV9vbl9SVExfdGlueV93aW5kb3dcdTAwM2R0cnVlXHUwMDI2dW5wbHVnZ2VkX2RhaV9saXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZ1bnBsdWdnZWRfdHZodG1sNV92aWRlb19wcmVsb2FkX29uX2ZvY3VzX2RlbGF5X21zXHUwMDNkMFx1MDAyNnVwZGF0ZV9sb2dfZXZlbnRfY29uZmlnXHUwMDNkdHJ1ZVx1MDAyNnVzZV9hY2Nlc3NpYmlsaXR5X2RhdGFfb25fZGVza3RvcF9wbGF5ZXJfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9jb3JlX3NtXHUwMDNkdHJ1ZVx1MDAyNnVzZV9pbmxpbmVkX3BsYXllcl9ycGNcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19jbWxcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19pbl9tZW1vcnlfc3RvcmFnZVx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9pbml0aWFsaXphdGlvblx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zYXdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc3R3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3d0c1x1MDAzZHRydWVcdTAwMjZ1c2VfcGxheWVyX2FidXNlX2JnX2xpYnJhcnlcdTAwM2R0cnVlXHUwMDI2dXNlX3Byb2ZpbGVwYWdlX2V2ZW50X2xhYmVsX2luX2Nhcm91c2VsX3BsYXliYWNrc1x1MDAzZHRydWVcdTAwMjZ1c2VfcmVxdWVzdF90aW1lX21zX2hlYWRlclx1MDAzZHRydWVcdTAwMjZ1c2Vfc2Vzc2lvbl9iYXNlZF9zYW1wbGluZ1x1MDAzZHRydWVcdTAwMjZ1c2VfdHNfdmlzaWJpbGl0eWxvZ2dlclx1MDAzZHRydWVcdTAwMjZ2YXJpYWJsZV9idWZmZXJfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZ2ZXJpZnlfYWRzX2l0YWdfZWFybHlcdTAwM2R0cnVlXHUwMDI2dnA5X2RybV9saXZlXHUwMDNkdHJ1ZVx1MDAyNnZzc19maW5hbF9waW5nX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnZzc19waW5nc191c2luZ19uZXR3b3JrbGVzc1x1MDAzZHRydWVcdTAwMjZ2c3NfcGxheWJhY2tfdXNlX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9hcGlfdXJsXHUwMDNkdHJ1ZVx1MDAyNndlYl9hc3luY19jb250ZXh0X3Byb2Nlc3Nvcl9pbXBsXHUwMDNkc3RhbmRhbG9uZVx1MDAyNndlYl9jaW5lbWF0aWNfd2F0Y2hfc2V0dGluZ3NcdTAwM2R0cnVlXHUwMDI2d2ViX2NsaWVudF92ZXJzaW9uX292ZXJyaWRlXHUwMDNkXHUwMDI2d2ViX2RlZHVwZV92ZV9ncmFmdGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZGVwcmVjYXRlX3NlcnZpY2VfYWpheF9tYXBfZGVwZW5kZW5jeVx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2Vycm9yXzIwNFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2luc3RyZWFtX2Fkc19saW5rX2RlZmluaXRpb25fYTExeV9idWdmaXhcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV92b3pfYXVkaW9fZmVlZGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX2ZpeF9maW5lX3NjcnViYmluZ19kcmFnXHUwMDNkdHJ1ZVx1MDAyNndlYl9mb3JlZ3JvdW5kX2hlYXJ0YmVhdF9pbnRlcnZhbF9tc1x1MDAzZDI4MDAwXHUwMDI2d2ViX2ZvcndhcmRfY29tbWFuZF9vbl9wYmpcdTAwM2R0cnVlXHUwMDI2d2ViX2dlbF9kZWJvdW5jZV9tc1x1MDAzZDYwMDAwXHUwMDI2d2ViX2dlbF90aW1lb3V0X2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfaW5saW5lX3BsYXllcl9ub19wbGF5YmFja191aV9jbGlja19oYW5kbGVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9rZXlfbW9tZW50c19tYXJrZXJzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dfbWVtb3J5X3RvdGFsX2tieXRlc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nZ2luZ19tYXhfYmF0Y2hcdTAwM2QxNTBcdTAwMjZ3ZWJfbW9kZXJuX2Fkc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zX2JsX3N1cnZleVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3NjcnViYmVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlX3N0eWxlXHUwMDNkZmlsbGVkXHUwMDI2d2ViX25ld19hdXRvbmF2X2NvdW50ZG93blx1MDAzZHRydWVcdTAwMjZ3ZWJfb25lX3BsYXRmb3JtX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9vcF9zaWduYWxfdHlwZV9iYW5saXN0XHUwMDNkW11cdTAwMjZ3ZWJfcGF1c2VkX29ubHlfbWluaXBsYXllcl9zaG9ydGN1dF9leHBhbmRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfbG9nX2N0dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF92ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FkZF92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdG9fb3V0Ym91bmRfbGlua3NcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hbHdheXNfZW5hYmxlX2F1dG9fdHJhbnNsYXRpb25cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hcGlfbG9nZ2luZ19mcmFjdGlvblx1MDAzZDAuMDFcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfZW1wdHlfc3VnZ2VzdGlvbnNfZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl90b2dnbGVfYWx3YXlzX2xpc3Rlblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdXNlX3NlcnZlcl9wcm92aWRlZF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2NhcHRpb25fbGFuZ3VhZ2VfcHJlZmVyZW5jZV9zdGlja2luZXNzX2R1cmF0aW9uXHUwMDNkMzBcdTAwMjZ3ZWJfcGxheWVyX2RlY291cGxlX2F1dG9uYXZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9kaXNhYmxlX2lubGluZV9zY3J1YmJpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZWFybHlfd2FybmluZ19zbmFja2Jhclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9mZWF0dXJlZF9wcm9kdWN0X2Jhbm5lcl9vbl9kZXNrdG9wXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX2luX2g1X2FwaVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9wbGF5YmFja19jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pbm5lcnR1YmVfcGxheWxpc3RfdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaXBwX2NhbmFyeV90eXBlX2Zvcl9sb2dnaW5nXHUwMDNkXHUwMDI2d2ViX3BsYXllcl9saXZlX21vbml0b3JfZW52XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbG9nX2NsaWNrX2JlZm9yZV9nZW5lcmF0aW5nX3ZlX2NvbnZlcnNpb25fcGFyYW1zXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbW92ZV9hdXRvbmF2X3RvZ2dsZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX211c2ljX3Zpc3VhbGl6ZXJfdHJlYXRtZW50XHUwMDNkZmFrZVx1MDAyNndlYl9wbGF5ZXJfbXV0YWJsZV9ldmVudF9sYWJlbFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX25pdHJhdGVfcHJvbW9fdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX29mZmxpbmVfcGxheWxpc3RfYXV0b19yZWZyZXNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfcmVzcG9uc2VfcGxheWJhY2tfdHJhY2tpbmdfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlZWtfY2hhcHRlcnNfYnlfc2hvcnRjdXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZW50aW5lbF9pc191bmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG91bGRfaG9ub3JfaW5jbHVkZV9hc3Jfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3dfbXVzaWNfaW5fdGhpc192aWRlb19ncmFwaGljXHUwMDNkdmlkZW9fdGh1bWJuYWlsXHUwMDI2d2ViX3BsYXllcl9zbWFsbF9oYnBfc2V0dGluZ3NfbWVudVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NzX2RhaV9hZF9mZXRjaGluZ190aW1lb3V0X21zXHUwMDNkMTUwMDBcdTAwMjZ3ZWJfcGxheWVyX3NzX21lZGlhX3RpbWVfb2Zmc2V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG9waWZ5X3N1YnRpdGxlc19mb3Jfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG91Y2hfbW9kZV9pbXByb3ZlbWVudHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90cmFuc2Zlcl90aW1lb3V0X3RocmVzaG9sZF9tc1x1MDAzZDEwODAwMDAwXHUwMDI2d2ViX3BsYXllcl91bnNldF9kZWZhdWx0X2Nzbl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdXNlX25ld19hcGlfZm9yX3F1YWxpdHlfcHVsbGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl92ZV9jb252ZXJzaW9uX2ZpeGVzX2Zvcl9jaGFubmVsX2luZm9cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZV9wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wcmVmZXRjaF9wcmVsb2FkX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNndlYl9yb3VuZGVkX3RodW1ibmFpbHNcdTAwM2R0cnVlXHUwMDI2d2ViX3NldHRpbmdzX21lbnVfaWNvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X21ldGhvZFx1MDAzZDBcdTAwMjZ3ZWJfeXRfY29uZmlnX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2d2lsX2ljb25fcmVuZGVyX3doZW5faWRsZVx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfY2xlYW5fdXBfYWZ0ZXJfZW50aXR5X21pZ3JhdGlvblx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfZW5hYmxlX2Rvd25sb2FkX3N0YXR1c1x1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfcGxheWxpc3Rfb3B0aW1pemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2NsZWFyX2VtYmVkZGVkX3BsYXllclx1MDAzZHRydWVcdTAwMjZ5dGlkYl9mZXRjaF9kYXRhc3luY19pZHNfZm9yX2RhdGFfY2xlYW51cFx1MDAzZHRydWVcdTAwMjZ5dGlkYl9yZW1ha2VfZGJfcmV0cmllc1x1MDAzZDFcdTAwMjZ5dGlkYl9yZW9wZW5fZGJfcmV0cmllc1x1MDAzZDBcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0XHUwMDNkMC4wMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfc2Vzc2lvblx1MDAzZDAuMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfdHJhbnNhY3Rpb25cdTAwM2QwLjEiLCJoaWRlSW5mbyI6dHJ1ZSwiZGlzYWJsZUZ1bGxzY3JlZW4iOnRydWUsImNzcE5vbmNlIjoib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSIsImNhbmFyeVN0YXRlIjoibm9uZSIsImVuYWJsZUNzaUxvZ2dpbmciOnRydWUsImRhdGFzeW5jSWQiOiJWMjAyMTdmYzZ8fCIsInN0b3JlVXNlclZvbHVtZSI6dHJ1ZSwiZGlzYWJsZVNlZWsiOnRydWUsImRpc2FibGVQYWlkQ29udGVudE92ZXJsYXkiOnRydWUsInByZWZlckdhcGxlc3MiOnRydWV9LCJXRUJfUExBWUVSX0NPTlRFWFRfQ09ORklHX0lEX0tFVkxBUl9TUE9OU09SU0hJUFNfT0ZGRVIiOnsicm9vdEVsZW1lbnRJZCI6Inl0ZC1zcG9uc29yc2hpcHMtb2ZmZXItd2l0aC12aWRlby1yZW5kZXJlciIsImpzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3BsYXllcl9pYXMudmZsc2V0L2ZyX0ZSL2Jhc2UuanMiLCJjc3NVcmwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvd3d3LXBsYXllci5jc3MiLCJjb250ZXh0SWQiOiJXRUJfUExBWUVSX0NPTlRFWFRfQ09ORklHX0lEX0tFVkxBUl9TUE9OU09SU0hJUFNfT0ZGRVIiLCJldmVudExhYmVsIjoic3BvbnNvcnNoaXBzb2ZmZXIiLCJjb250ZW50UmVnaW9uIjoiRlIiLCJobCI6ImZyX0ZSIiwiaG9zdExhbmd1YWdlIjoiZnIiLCJwbGF5ZXJTdHlsZSI6ImRlc2t0b3AtcG9seW1lciIsImlubmVydHViZUFwaUtleSI6IkFJemFTeUFPX0ZKMlNscVU4UTRTVEVITEdDaWx3X1k5XzExcWNXOCIsImlubmVydHViZUFwaVZlcnNpb24iOiJ2MSIsImlubmVydHViZUNvbnRleHRDbGllbnRWZXJzaW9uIjoiMi4yMDIzMDYwNy4wNi4wMCIsImRpc2FibGVSZWxhdGVkVmlkZW9zIjp0cnVlLCJhbm5vdGF0aW9uc0xvYWRQb2xpY3kiOjMsImRldmljZSI6eyJicmFuZCI6IiIsIm1vZGVsIjoiIiwicGxhdGZvcm0iOiJERVNLVE9QIiwiaW50ZXJmYWNlTmFtZSI6IldFQiIsImludGVyZmFjZVZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIn0sInNlcmlhbGl6ZWRFeHBlcmltZW50SWRzIjoiMjM5ODMyOTYsMjQwMDQ2NDQsMjQwMDcyNDYsMjQwMDc2MTMsMjQwODA3MzgsMjQxMzUzMTAsMjQzNjMxMTQsMjQzNjQ3ODksMjQzNjU1MzQsMjQzNjY5MTcsMjQzNzI3NjEsMjQzNzUxMDEsMjQzNzY3ODUsMjQ0MTU4NjQsMjQ0MTYyOTAsMjQ0MzM2NzksMjQ0Mzc1NzcsMjQ0MzkzNjEsMjQ0NDMzMzEsMjQ0OTk1MzIsMjQ1MzI4NTUsMjQ1NTA0NTgsMjQ1NTA5NTEsMjQ1NTU1NjcsMjQ1NTg2NDEsMjQ1NTkzMjcsMjQ2OTk4OTksMzkzMjMwNzQiLCJzZXJpYWxpemVkRXhwZXJpbWVudEZsYWdzIjoiSDVfYXN5bmNfbG9nZ2luZ19kZWxheV9tc1x1MDAzZDMwMDAwLjBcdTAwMjZINV9lbmFibGVfZnVsbF9wYWNmX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2SDVfdXNlX2FzeW5jX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2YWN0aW9uX2NvbXBhbmlvbl9jZW50ZXJfYWxpZ25fZGVzY3JpcHRpb25cdTAwM2R0cnVlXHUwMDI2YWRfcG9kX2Rpc2FibGVfY29tcGFuaW9uX3BlcnNpc3RfYWRzX3F1YWxpdHlcdTAwM2R0cnVlXHUwMDI2YWRkdG9fYWpheF9sb2dfd2FybmluZ19mcmFjdGlvblx1MDAzZDAuMVx1MDAyNmFsaWduX2FkX3RvX3ZpZGVvX3BsYXllcl9saWZlY3ljbGVfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2YWxsb3dfbGl2ZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19wb2x0ZXJndXN0X2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X3NraXBfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2YXR0X3dlYl9yZWNvcmRfbWV0cmljc1x1MDAzZHRydWVcdTAwMjZhdXRvcGxheV90aW1lXHUwMDNkODAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX2Z1bGxzY3JlZW5cdTAwM2QzMDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfbXVzaWNfY29udGVudFx1MDAzZDMwMDBcdTAwMjZiZ192bV9yZWluaXRfdGhyZXNob2xkXHUwMDNkNzIwMDAwMFx1MDAyNmJsb2NrZWRfcGFja2FnZXNfZm9yX3Nwc1x1MDAzZFtdXHUwMDI2Ym90Z3VhcmRfYXN5bmNfc25hcHNob3RfdGltZW91dF9tc1x1MDAzZDMwMDBcdTAwMjZjaGVja19hZF91aV9zdGF0dXNfZm9yX213ZWJfc2FmYXJpXHUwMDNkdHJ1ZVx1MDAyNmNoZWNrX25hdmlnYXRvcl9hY2N1cmFjeV90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmNsZWFyX3VzZXJfcGFydGl0aW9uZWRfbHNcdTAwM2R0cnVlXHUwMDI2Y2xpZW50X3Jlc3BlY3RfYXV0b3BsYXlfc3dpdGNoX2J1dHRvbl9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZjb21wcmVzc19nZWxcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3Npb25fZGlzYWJsZV9wb2ludFx1MDAzZDEwXHUwMDI2Y29tcHJlc3Npb25fcGVyZm9ybWFuY2VfdGhyZXNob2xkXHUwMDNkMjUwXHUwMDI2Y3NpX29uX2dlbFx1MDAzZHRydWVcdTAwMjZkYXNoX21hbmlmZXN0X3ZlcnNpb25cdTAwM2Q1XHUwMDI2ZGVidWdfYmFuZGFpZF9ob3N0bmFtZVx1MDAzZFx1MDAyNmRlYnVnX3NoZXJsb2dfdXNlcm5hbWVcdTAwM2RcdTAwMjZkZWxheV9hZHNfZ3ZpX2NhbGxfb25fYnVsbGVpdF9saXZpbmdfcm9vbV9tc1x1MDAzZDBcdTAwMjZkZXByZWNhdGVfY3NpX2hhc19pbmZvXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV9wYWlyX3NlcnZsZXRfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX2NoaWxkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfcGFyZW50XHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfaW1hZ2VfY3RhX25vX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9sb2dfaW1nX2NsaWNrX2xvY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3Bfc3BhcmtsZXNfbGlnaHRfY3RhX2J1dHRvblx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoYW5uZWxfaWRfY2hlY2tfZm9yX3N1c3BlbmRlZF9jaGFubmVsc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoaWxkX25vZGVfYXV0b19mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2RlZmVyX2FkbW9kdWxlX29uX2FkdmVydGlzZXJfdmlkZW9cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9mZWF0dXJlc19mb3Jfc3VwZXhcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9sZWdhY3lfZGVza3RvcF9yZW1vdGVfcXVldWVcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9tZHhfY29ubmVjdGlvbl9pbl9tZHhfbW9kdWxlX2Zvcl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9uZXdfcGF1c2Vfc3RhdGUzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcGFjZl9sb2dnaW5nX2Zvcl9tZW1vcnlfbGltaXRlZF90dlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3JvdW5kaW5nX2FkX25vdGlmeVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NpbXBsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zc2RhaV9vbl9lcnJvcnNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90YWJiaW5nX2JlZm9yZV9mbHlvdXRfYWRfZWxlbWVudHNfYXBwZWFyXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGh1bWJuYWlsX3ByZWxvYWRpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2Rpc2FibGVfcHJvZ3Jlc3NfYmFyX2NvbnRleHRfbWVudV9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZW5hYmxlX2FsbG93X3dhdGNoX2FnYWluX2VuZHNjcmVlbl9mb3JfZWxpZ2libGVfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc192ZV9jb252ZXJzaW9uX3BhcmFtX3JlbmFtaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2F1dG9wbGF5X25vdF9zdXBwb3J0ZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfY3VlX3ZpZGVvX3VucGxheWFibGVfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2hvdXNlX2JyYW5kX2FuZF95dF9jb2V4aXN0ZW5jZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2FkX3BsYXllcl9mcm9tX3BhZ2Vfc2hvd1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dfc3BsYXlfYXNfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nZ2luZ19ldmVudF9oYW5kbGVyc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2R0dHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbmV3X2NvbnRleHRfbWVudV90cmlnZ2VyaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BhdXNlX292ZXJsYXlfd25fdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BlbV9kb21haW5fZml4X2Zvcl9hZF9yZXF1ZXN0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZnBfdW5icmFuZGVkX2VsX2RlcHJlY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JjYXRfYWxsb3dsaXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JlcGxhY2VfdW5sb2FkX3dfcGFnZWhpZGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfc2NyaXB0ZWRfcGxheWJhY2tfYmxvY2tlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdHJhY2tpbmdfbm9fYWxsb3dfbGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2hpZGVfdW5maWxsZWRfbW9yZV92aWRlb3Nfc3VnZ2VzdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9saXRlX21vZGVcdTAwM2QxXHUwMDI2ZW1iZWRzX3dlYl9ud2xfZGlzYWJsZV9ub2Nvb2tpZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3Nob3BwaW5nX292ZXJsYXlfbm9fd2FpdF9mb3JfcGFpZF9jb250ZW50X292ZXJsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zeW50aF9jaF9oZWFkZXJzX2Jhbm5lZF91cmxzX3JlZ2V4XHUwMDNkXHUwMDI2ZW5hYmxlX2FiX3JwX2ludFx1MDAzZHRydWVcdTAwMjZlbmFibGVfYWRfY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FwcF9wcm9tb19lbmRjYXBfZW1sX29uX3RhYmxldFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9mb3Jfd2ViX3VucGx1Z2dlZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9vbl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9wYWdlX2lkX2hlYWRlcl9mb3JfZmlyc3RfcGFydHlfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9zbGlfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZGlzY3JldGVfbGl2ZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudF9jaGVja1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRzX2ljb25fd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9ldmljdGlvbl9wcm90ZWN0aW9uX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9nZWxfbG9nX2NvbW1hbmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV9pbnN0cmVhbV93YXRjaF9uZXh0X3BhcmFtc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X3ZpZGVvX2Fkc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2hhbmRsZXNfYWNjb3VudF9tZW51X3N3aXRjaGVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9rYWJ1a2lfY29tbWVudHNfb25fc2hvcnRzXHUwMDNkZGlzYWJsZWRcdTAwMjZlbmFibGVfbGl2ZV9wcmVtaWVyZV93ZWJfcGxheWVyX2luZGljYXRvclx1MDAzZHRydWVcdTAwMjZlbmFibGVfbHJfaG9tZV9pbmZlZWRfYWRzX2lubGluZV9wbGF5YmFja19wcm9ncmVzc19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9td2ViX2VuZGNhcF9jbGlja2FibGVfaWNvbl9kZXNjcmlwdGlvblx1MDAzZHRydWVcdTAwMjZlbmFibGVfbXdlYl9saXZlc3RyZWFtX3VpX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbmFibGVfbmV3X3BhaWRfcHJvZHVjdF9wbGFjZW1lbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2Zfc2xvdF9hc2RlX3BsYXllcl9ieXRlX2g1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZfZm9yX3BhZ2VfdG9wX2Zvcm1hdHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95c2ZlX3R2XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYXNzX3NkY19nZXRfYWNjb3VudHNfbGlzdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGxfcl9jXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2ZpeF9vbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2luX3R2aHRtbDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NlcnZlcl9zdGl0Y2hlZF9kYWlcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Nob3J0c19wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NraXBfYWRfZ3VpZGFuY2VfcHJvbXB0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwcGFibGVfYWRzX2Zvcl91bnBsdWdnZWRfYWRfcG9kXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90ZWN0b25pY19hZF91eF9mb3JfaGFsZnRpbWVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RoaXJkX3BhcnR5X2luZm9cdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RvcHNvaWxfd3RhX2Zvcl9oYWxmdGltZV9saXZlX2luZnJhXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfbWVkaWFfc2Vzc2lvbl9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3dlYl9zY2hlZHVsZXJfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfd25faW5mb2NhcmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV95dF9hdGFfaWZyYW1lX2F1dGh1c2VyXHUwMDNkdHJ1ZVx1MDAyNmVycm9yX21lc3NhZ2VfZm9yX2dzdWl0ZV9uZXR3b3JrX3Jlc3RyaWN0aW9uc1x1MDAzZHRydWVcdTAwMjZleHBvcnRfbmV0d29ya2xlc3Nfb3B0aW9uc1x1MDAzZHRydWVcdTAwMjZleHRlcm5hbF9mdWxsc2NyZWVuX3dpdGhfZWR1XHUwMDNkdHJ1ZVx1MDAyNmZhc3RfYXV0b25hdl9pbl9iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmZldGNoX2F0dF9pbmRlcGVuZGVudGx5XHUwMDNkdHJ1ZVx1MDAyNmZpbGxfc2luZ2xlX3ZpZGVvX3dpdGhfbm90aWZ5X3RvX2xhc3JcdTAwM2R0cnVlXHUwMDI2ZmlsdGVyX3ZwOV9mb3JfY3NkYWlcdTAwM2R0cnVlXHUwMDI2Zml4X2Fkc190cmFja2luZ19mb3Jfc3dmX2NvbmZpZ19kZXByZWNhdGlvbl9td2ViXHUwMDNkdHJ1ZVx1MDAyNmdjZl9jb25maWdfc3RvcmVfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZnZWxfcXVldWVfdGltZW91dF9tYXhfbXNcdTAwM2QzMDAwMDBcdTAwMjZncGFfc3BhcmtsZXNfdGVuX3BlcmNlbnRfbGF5ZXJcdTAwM2R0cnVlXHUwMDI2Z3ZpX2NoYW5uZWxfY2xpZW50X3NjcmVlblx1MDAzZHRydWVcdTAwMjZoNV9jb21wYW5pb25fZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX2dlbmVyaWNfZXJyb3JfbG9nZ2luZ19ldmVudFx1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfdW5pZmllZF9jc2lfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZoNV9pbnBsYXllcl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9yZXNldF9jYWNoZV9hbmRfZmlsdGVyX2JlZm9yZV91cGRhdGVfbWFzdGhlYWRcdTAwM2R0cnVlXHUwMDI2aGVhdHNlZWtlcl9kZWNvcmF0aW9uX3RocmVzaG9sZFx1MDAzZDAuMFx1MDAyNmhmcl9kcm9wcGVkX2ZyYW1lcmF0ZV9mYWxsYmFja190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aGlkZV9lbmRwb2ludF9vdmVyZmxvd19vbl95dGRfZGlzcGxheV9hZF9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZodG1sNV9hZF90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2Fkc19wcmVyb2xsX2xvY2tfdGltZW91dF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfYWxsb3dfZGlzY29udGlndW91c19zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWxsb3dfdmlkZW9fa2V5ZnJhbWVfd2l0aG91dF9hdWRpb1x1MDAzZHRydWVcdTAwMjZodG1sNV9hdHRhY2hfbnVtX3JhbmRvbV9ieXRlc190b19iYW5kYWlkXHUwMDNkMFx1MDAyNmh0bWw1X2F0dGFjaF9wb190b2tlbl90b19iYW5kYWlkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F1dG9uYXZfY2FwX2lkbGVfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9hdXRvbmF2X3F1YWxpdHlfY2FwXHUwMDNkNzIwXHUwMDI2aHRtbDVfYXV0b3BsYXlfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9ibG9ja19waXBfc2FmYXJpX2RlbGF5XHUwMDNkMFx1MDAyNmh0bWw1X2JtZmZfbmV3X2ZvdXJjY19jaGVja1x1MDAzZHRydWVcdTAwMjZodG1sNV9jb2JhbHRfZGVmYXVsdF9idWZmZXJfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWF4X3NpemVfZm9yX2ltbWVkX2pvYlx1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWluX3Byb2Nlc3Nvcl9jbnRfdG9fb2ZmbG9hZF9hbGdvXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9vdmVycmlkZV9xdWljXHUwMDNkMFx1MDAyNmh0bWw1X2NvbnN1bWVfbWVkaWFfYnl0ZXNfc2xpY2VfaW5mb3NcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVfZHVwZV9jb250ZW50X3ZpZGVvX2xvYWRzX2luX2xpZmVjeWNsZV9hcGlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVidWdfZGF0YV9sb2dfcHJvYmFiaWxpdHlcdTAwM2QwLjFcdTAwMjZodG1sNV9kZWNvZGVfdG9fdGV4dHVyZV9jYXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVmYXVsdF9hZF9nYWluXHUwMDNkMC41XHUwMDI2aHRtbDVfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9hZF9tb2R1bGVfbXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfZmV0Y2hfYXR0X21zXHUwMDNkMTAwMFx1MDAyNmh0bWw1X2RlZmVyX21vZHVsZXNfZGVsYXlfdGltZV9taWxsaXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9jb3VudFx1MDAzZDFcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2RlbGF5X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X2RlcHJlY2F0ZV92aWRlb190YWdfcG9vbFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZXNrdG9wX3ZyMTgwX2FsbG93X3Bhbm5pbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGZfZG93bmdyYWRlX3RocmVzaFx1MDAzZDAuMlx1MDAyNmh0bWw1X2Rpc2FibGVfY3NpX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbW92ZV9wc3NoX3RvX21vb3ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9ub25fY29udGlndW91c1x1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNwbGF5ZWRfZnJhbWVfcmF0ZV9kb3duZ3JhZGVfdGhyZXNob2xkXHUwMDNkNDVcdTAwMjZodG1sNV9kcm1fY2hlY2tfYWxsX2tleV9lcnJvcl9zdGF0ZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZHJtX2NwaV9saWNlbnNlX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hZHNfY2xpZW50X21vbml0b3JpbmdfbG9nX3R2XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jYXB0aW9uX2NoYW5nZXNfZm9yX21vc2FpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2xpZW50X2hpbnRzX292ZXJyaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jb21wb3NpdGVfZW1iYXJnb1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZWFjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZW1iZWRkZWRfcGxheWVyX3Zpc2liaWxpdHlfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbm9uX25vdGlmeV9jb21wb3NpdGVfdm9kX2xzYXJfcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfc2luZ2xlX3ZpZGVvX3ZvZF9pdmFyX29uX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZGFzaFx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19lbmNyeXB0ZWRfdnA5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfYWxjXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfZmFzdF9saW5lYXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5jb3VyYWdlX2FycmF5X2NvYWxlc2NpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2FwbGVzc19lbmRlZF90cmFuc2l0aW9uX2J1ZmZlcl9tc1x1MDAzZDIwMFx1MDAyNmh0bWw1X2dlbmVyYXRlX3Nlc3Npb25fcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2xfZnBzX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZodG1sNV9oZGNwX3Byb2Jpbmdfc3RyZWFtX3VybFx1MDAzZFx1MDAyNmh0bWw1X2hmcl9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QxLjBcdTAwMjZodG1sNV9pZGxlX3JhdGVfbGltaXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX2ZhaXJwbGF5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9wbGF5cmVhZHlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3dpZGV2aW5lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczRfc2Vla19hYm92ZV96ZXJvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczdfZm9yY2VfcGxheV9vbl9zdGFsbFx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3NfZm9yY2Vfc2Vla190b196ZXJvX29uX3N0b3BcdTAwM2R0cnVlXHUwMDI2aHRtbDVfanVtYm9fbW9iaWxlX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDMuMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9ub25zdHJlYW1pbmdfbWZmYV9tc1x1MDAzZDQwMDBcdTAwMjZodG1sNV9qdW1ib191bGxfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMS4zXHUwMDI2aHRtbDVfbGljZW5zZV9jb25zdHJhaW50X2RlbGF5XHUwMDNkNTAwMFx1MDAyNmh0bWw1X2xpdmVfYWJyX2hlYWRfbWlzc19mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYWJyX3JlcHJlZGljdF9mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYnl0ZXJhdGVfZmFjdG9yX2Zvcl9yZWFkYWhlYWRcdTAwM2QxLjNcdTAwMjZodG1sNV9saXZlX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9saXZlX25vcm1hbF9sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2xpdmVfdWx0cmFfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xvZ19hdWRpb19hYnJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX2V4cGVyaW1lbnRfaWRfZnJvbV9wbGF5ZXJfcmVzcG9uc2VfdG9fY3RtcFx1MDAzZFx1MDAyNmh0bWw1X2xvZ19maXJzdF9zc2RhaV9yZXF1ZXN0c19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19yZWJ1ZmZlcl9ldmVudHNcdTAwM2Q1XHUwMDI2aHRtbDVfbG9nX3NzZGFpX2ZhbGxiYWNrX2Fkc1x1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfdHJpZ2dlcl9ldmVudHNfd2l0aF9kZWJ1Z19kYXRhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX3RocmVzaG9sZF9tc1x1MDAzZDMwMDAwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3NlZ19kcmlmdF9saW1pdF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc191bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3ZwOV9vdGZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWF4X2RyaWZ0X3Blcl90cmFja19zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWF4X2hlYWRtX2Zvcl9zdHJlYW1pbmdfeGhyXHUwMDNkMFx1MDAyNmh0bWw1X21heF9saXZlX2R2cl93aW5kb3dfcGx1c19tYXJnaW5fc2Vjc1x1MDAzZDQ2ODAwLjBcdTAwMjZodG1sNV9tYXhfcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21heF9yZWRpcmVjdF9yZXNwb25zZV9sZW5ndGhcdTAwM2Q4MTkyXHUwMDI2aHRtbDVfbWF4X3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21heF9zb3VyY2VfYnVmZmVyX2FwcGVuZF9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X21heGltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9tZWRpYV9mdWxsc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21mbF9leHRlbmRfbWF4X3JlcXVlc3RfdGltZVx1MDAzZHRydWVcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9jYXBfc2Vjc1x1MDAzZDYwXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9taW5fc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfYWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbm9fcGxhY2Vob2xkZXJfcm9sbGJhY2tzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vbl9uZXR3b3JrX3JlYnVmZmVyX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X25vbl9vbmVzaWVfYXR0YWNoX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vdF9yZWdpc3Rlcl9kaXNwb3NhYmxlc193aGVuX2NvcmVfbGlzdGVuc1x1MDAzZHRydWVcdTAwMjZodG1sNV9vZmZsaW5lX2ZhaWx1cmVfcmV0cnlfbGltaXRcdTAwM2QyXHUwMDI2aHRtbDVfb25lc2llX2RlZmVyX2NvbnRlbnRfbG9hZGVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9ob3N0X3JhY2luZ19jYXBfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2lnbm9yZV9pbm5lcnR1YmVfYXBpX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbGl2ZV90dGxfc2Vjc1x1MDAzZDhcdTAwMjZodG1sNV9vbmVzaWVfbm9uemVyb19wbGF5YmFja19zdGFydFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbm90aWZ5X2N1ZXBvaW50X21hbmFnZXJfb25fY29tcGxldGlvblx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9jb29sZG93bl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9pbnRlcnZhbF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9tYXhfbGFjdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlcXVlc3RfdGltZW91dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9vbmVzaWVfc3RpY2t5X3NlcnZlcl9zaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BhdXNlX29uX25vbmZvcmVncm91bmRfcGxhdGZvcm1fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlYWtfc2hhdmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZl9jYXBfb3ZlcnJpZGVfc3RpY2t5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2NhcF9mbG9vclx1MDAzZDM2MFx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2ltcGFjdF9wcm9maWxpbmdfdGltZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcGVyc2VydmVfYXYxX3BlcmZfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX21pbmltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9wbGF5ZXJfYXV0b25hdl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXllcl9keW5hbWljX2JvdHRvbV9ncmFkaWVudFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfbWluX2J1aWxkX2NsXHUwMDNkLTFcdTAwMjZodG1sNV9wbGF5ZXJfcHJlbG9hZF9hZF9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcG9zdF9pbnRlcnJ1cHRfcmVhZGFoZWFkXHUwMDNkMjBcdTAwMjZodG1sNV9wcmVmZXJfc2VydmVyX2J3ZTNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcHJlbG9hZF93YWl0X3RpbWVfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Byb2JlX3ByaW1hcnlfZGVsYXlfYmFzZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9wcm9jZXNzX2FsbF9lbmNyeXB0ZWRfZXZlbnRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3FvZV9saF9tYXhfcmVwb3J0X2NvdW50XHUwMDNkMFx1MDAyNmh0bWw1X3FvZV9saF9taW5fZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfcXVlcnlfc3dfc2VjdXJlX2NyeXB0b19mb3JfYW5kcm9pZFx1MDAzZHRydWVcdTAwMjZodG1sNV9yYW5kb21fcGxheWJhY2tfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X3JlY29nbml6ZV9wcmVkaWN0X3N0YXJ0X2N1ZV9wb2ludFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfY29tbWFuZF90cmlnZ2VyZWRfY29tcGFuaW9uc1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfbm90X3NlcnZhYmxlX2NoZWNrX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVuYW1lX2FwYnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X2ZhdGFsX2RybV9yZXN0cmljdGVkX2Vycm9yX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X3Nsb3dfYWRzX2FzX2Vycm9yXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfb25seV9oZHJfb3Jfc2RyX2tleXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVxdWVzdF9zaXppbmdfbXVsdGlwbGllclx1MDAzZDAuOFx1MDAyNmh0bWw1X3Jlc2V0X21lZGlhX3N0cmVhbV9vbl91bnJlc3VtYWJsZV9zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVzb3VyY2VfYmFkX3N0YXR1c19kZWxheV9zY2FsaW5nXHUwMDNkMS41XHUwMDI2aHRtbDVfcmVzdHJpY3Rfc3RyZWFtaW5nX3hocl9vbl9zcWxlc3NfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2FmYXJpX2Rlc2t0b3BfZW1lX21pbl92ZXJzaW9uXHUwMDNkMFx1MDAyNmh0bWw1X3NhbXN1bmdfa2FudF9saW1pdF9tYXhfYml0cmF0ZVx1MDAzZDBcdTAwMjZodG1sNV9zZWVrX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2Q4MDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9kZWxheV9tc1x1MDAzZDEyMDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfYnVmZmVyX3JhbmdlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX3Zyc19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2NmbFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfc2V0X2NtdF9kZWxheV9tc1x1MDAzZDIwMDBcdTAwMjZodG1sNV9zZWVrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NlcnZlcl9zdGl0Y2hlZF9kYWlfZGVjb3JhdGVkX3VybF9yZXRyeV9saW1pdFx1MDAzZDVcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2dyb3VwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Nlc3Npb25fcG9fdG9rZW5faW50ZXJ2YWxfdGltZV9tc1x1MDAzZDkwMDAwMFx1MDAyNmh0bWw1X3NraXBfb29iX3N0YXJ0X3NlY29uZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2tpcF9zbG93X2FkX2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9za2lwX3N1Yl9xdWFudHVtX2Rpc2NvbnRpbnVpdHlfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfbm9fbWVkaWFfc291cmNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfdGltZW91dF9kZWxheV9tc1x1MDAzZDIwMDAwXHUwMDI2aHRtbDVfc3NkYWlfYWRmZXRjaF9keW5hbWljX3RpbWVvdXRfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfc3NkYWlfZW5hYmxlX25ld19zZWVrX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N0YXRlZnVsX2F1ZGlvX21pbl9hZGp1c3RtZW50X3ZhbHVlXHUwMDNkMFx1MDAyNmh0bWw1X3N0YXRpY19hYnJfcmVzb2x1dGlvbl9zaGVsZlx1MDAzZDBcdTAwMjZodG1sNV9zdG9yZV94aHJfaGVhZGVyc19yZWFkYWJsZVx1MDAzZHRydWVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9sb2FkX3NwZWVkX2NoZWNrX2ludGVydmFsXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuMjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzX29uX3RpbWVvdXRcdTAwM2QwLjFcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fbG9hZF9zcGVlZFx1MDAzZDEuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3NlZWtfbGF0ZW5jeV9mdWRnZVx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldF9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90aW1lb3V0X3NlY3NcdTAwM2QyLjBcdTAwMjZodG1sNV91Z2NfbGl2ZV9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91Z2Nfdm9kX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VucmVwb3J0ZWRfc2Vla19yZXNlZWtfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfdW5yZXN0cmljdGVkX2xheWVyX2hpZ2hfcmVzX2xvZ2dpbmdfcGVyY2VudFx1MDAzZDAuMFx1MDAyNmh0bWw1X3VybF9wYWRkaW5nX2xlbmd0aFx1MDAzZDBcdTAwMjZodG1sNV91cmxfc2lnbmF0dXJlX2V4cGlyeV90aW1lX2hvdXJzXHUwMDNkMFx1MDAyNmh0bWw1X3VzZV9wb3N0X2Zvcl9tZWRpYVx1MDAzZHRydWVcdTAwMjZodG1sNV91c2VfdW1wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ZpZGVvX3RiZF9taW5fa2JcdTAwM2QwXHUwMDI2aHRtbDVfdmlld3BvcnRfdW5kZXJzZW5kX21heGltdW1cdTAwM2QwLjBcdTAwMjZodG1sNV92b2x1bWVfc2xpZGVyX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2ViX2VuYWJsZV9oYWxmdGltZV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYnBvX2lkbGVfcHJpb3JpdHlfam9iXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvZmZsZV9yZXN1bWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29ya2Fyb3VuZF9kZWxheV90cmlnZ2VyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3l0dmxyX2VuYWJsZV9zaW5nbGVfc2VsZWN0X3N1cnZleVx1MDAzZHRydWVcdTAwMjZpZ25vcmVfb3ZlcmxhcHBpbmdfY3VlX3BvaW50c19vbl9lbmRlbWljX2xpdmVfaHRtbDVcdTAwM2R0cnVlXHUwMDI2aWxfdXNlX3ZpZXdfbW9kZWxfbG9nZ2luZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNmluaXRpYWxfZ2VsX2JhdGNoX3RpbWVvdXRcdTAwM2QyMDAwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2xpY2Vuc2Vfc3RhdHVzXHUwMDNkMFx1MDAyNml0ZHJtX2luamVjdGVkX2xpY2Vuc2Vfc2VydmljZV9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNml0ZHJtX3dpZGV2aW5lX2hhcmRlbmVkX3ZtcF9tb2RlXHUwMDNkbG9nXHUwMDI2anNvbl9jb25kZW5zZWRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2NvbW1hbmRfaGFuZGxlcl9jb21tYW5kX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNmtldmxhcl9kcm9wZG93bl9maXhcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2dlbF9lcnJvcl9yb3V0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX2V4cGFuZF90b3BcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfcGxheV9wYXVzZV9vbl9zY3JpbVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcGxheWJhY2tfYXNzb2NpYXRlZF9xdWV1ZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcXVldWVfdXNlX3VwZGF0ZV9hcGlcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NpbXBfc2hvcnRzX3Jlc2V0X3Njcm9sbFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfdmltaW9fdXNlX3NoYXJlZF9tb25pdG9yXHUwMDNkdHJ1ZVx1MDAyNmxpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNmxpdmVfZnJlc2NhX3YyXHUwMDNkdHJ1ZVx1MDAyNmxvZ19lcnJvcnNfdGhyb3VnaF9ud2xfb25fcmV0cnlcdTAwM2R0cnVlXHUwMDI2bG9nX2dlbF9jb21wcmVzc2lvbl9sYXRlbmN5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19oZWFydGJlYXRfd2l0aF9saWZlY3ljbGVzXHUwMDNkdHJ1ZVx1MDAyNmxvZ193ZWJfZW5kcG9pbnRfdG9fbGF5ZXJcdTAwM2R0cnVlXHUwMDI2bG9nX3dpbmRvd19vbmVycm9yX2ZyYWN0aW9uXHUwMDNkMC4xXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZVx1MDAzZHRydWVcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlX3VmcGhcdTAwM2R0cnVlXHUwMDI2bWF4X2JvZHlfc2l6ZV90b19jb21wcmVzc1x1MDAzZDUwMDAwMFx1MDAyNm1heF9wcmVmZXRjaF93aW5kb3dfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDBcdTAwMjZtYXhfcmVzb2x1dGlvbl9mb3Jfd2hpdGVfbm9pc2VcdTAwM2QzNjBcdTAwMjZtZHhfZW5hYmxlX3ByaXZhY3lfZGlzY2xvc3VyZV91aVx1MDAzZHRydWVcdTAwMjZtZHhfbG9hZF9jYXN0X2FwaV9ib290c3RyYXBfc2NyaXB0XHUwMDNkdHJ1ZVx1MDAyNm1pZ3JhdGVfZXZlbnRzX3RvX3RzXHUwMDNkdHJ1ZVx1MDAyNm1pbl9wcmVmZXRjaF9vZmZzZXRfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDEwXHUwMDI2bXVzaWNfZW5hYmxlX3NoYXJlZF9hdWRpb190aWVyX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfYzNfZW5kc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX2N1c3RvbV9jb250cm9sX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9za2lwcGFibGVzX29uX2ppb19waG9uZVx1MDAzZHRydWVcdTAwMjZtd2ViX211dGVkX2F1dG9wbGF5X2FuaW1hdGlvblx1MDAzZHNocmlua1x1MDAyNm13ZWJfbmF0aXZlX2NvbnRyb2xfaW5fZmF1eF9mdWxsc2NyZWVuX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrX3BvbGxpbmdfaW50ZXJ2YWxcdTAwM2QzMDAwMFx1MDAyNm5ldHdvcmtsZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrbGVzc19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNm5ld19jb2RlY3Nfc3RyaW5nX2FwaV91c2VzX2xlZ2FjeV9zdHlsZVx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mYXN0X29uX3VubG9hZFx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mcm9tX21lbW9yeV93aGVuX29ubGluZVx1MDAzZHRydWVcdTAwMjZvZmZsaW5lX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNnBhY2ZfbG9nZ2luZ19kZWxheV9taWxsaXNlY29uZHNfdGhyb3VnaF95YmZlX3R2XHUwMDNkMzAwMDBcdTAwMjZwYWdlaWRfYXNfaGVhZGVyX3dlYlx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWRzX3NldF9hZGZvcm1hdF9vbl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2FsbG93X2F1dG9uYXZfYWZ0ZXJfcGxheWxpc3RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Jvb3RzdHJhcF9tZXRob2RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RlZmVyX2NhcHRpb25fZGlzcGxheVx1MDAzZDEwMDBcdTAwMjZwbGF5ZXJfZGVzdHJveV9vbGRfdmVyc2lvblx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZG91YmxldGFwX3RvX3NlZWtcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuYWJsZV9wbGF5YmFja19wbGF5bGlzdF9jaGFuZ2VcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuZHNjcmVlbl9lbGxpcHNpc19maXhcdTAwM2R0cnVlXHUwMDI2cGxheWVyX3VuZGVybGF5X21pbl9wbGF5ZXJfd2lkdGhcdTAwM2Q3NjguMFx1MDAyNnBsYXllcl91bmRlcmxheV92aWRlb193aWR0aF9mcmFjdGlvblx1MDAzZDAuNlx1MDAyNnBsYXllcl93ZWJfY2FuYXJ5X3N0YWdlXHUwMDNkMFx1MDAyNnBsYXlyZWFkeV9maXJzdF9wbGF5X2V4cGlyYXRpb25cdTAwM2QtMVx1MDAyNnBvbHltZXJfYmFkX2J1aWxkX2xhYmVsc1x1MDAzZHRydWVcdTAwMjZwb2x5bWVyX2xvZ19wcm9wX2NoYW5nZV9vYnNlcnZlcl9wZXJjZW50XHUwMDNkMFx1MDAyNnBvbHltZXJfdmVyaWZpeV9hcHBfc3RhdGVcdTAwM2R0cnVlXHUwMDI2cHJlc2tpcF9idXR0b25fc3R5bGVfYWRzX2JhY2tlbmRcdTAwM2Rjb3VudGRvd25fbmV4dF90b190aHVtYm5haWxcdTAwMjZxb2VfbndsX2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZxb2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2cmVjb3JkX2FwcF9jcmFzaGVkX3dlYlx1MDAzZHRydWVcdTAwMjZyZXBsYWNlX3BsYXlhYmlsaXR5X3JldHJpZXZlcl9pbl93YXRjaFx1MDAzZHRydWVcdTAwMjZzY2hlZHVsZXJfdXNlX3JhZl9ieV9kZWZhdWx0XHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19oZWFkZXJfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX2ludGVyc3RpdGlhbF9tZXNzYWdlXHUwMDI2c2VsZl9wb2RkaW5nX2hpZ2hsaWdodF9ub25fZGVmYXVsdF9idXR0b25cdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZVx1MDAyNnNlbmRfY29uZmlnX2hhc2hfdGltZXJcdTAwM2QwXHUwMDI2c2V0X2ludGVyc3RpdGlhbF9hZHZlcnRpc2Vyc19xdWVzdGlvbl90ZXh0XHUwMDNkdHJ1ZVx1MDAyNnNob3J0X3N0YXJ0X3RpbWVfcHJlZmVyX3B1Ymxpc2hfaW5fd2F0Y2hfbG9nXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19tb2RlX3RvX3BsYXllcl9hcGlcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX25vX3N0b3BfdmlkZW9fY2FsbFx1MDAzZHRydWVcdTAwMjZzaG91bGRfY2xlYXJfdmlkZW9fZGF0YV9vbl9wbGF5ZXJfY3VlZF91bnN0YXJ0ZWRcdTAwM2R0cnVlXHUwMDI2c2ltcGx5X2VtYmVkZGVkX2VuYWJsZV9ib3RndWFyZFx1MDAzZHRydWVcdTAwMjZza2lwX2lubGluZV9tdXRlZF9saWNlbnNlX3NlcnZpY2VfY2hlY2tcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbnZhbGlkX3l0Y3NpX3RpY2tzXHUwMDNkdHJ1ZVx1MDAyNnNraXBfbHNfZ2VsX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNnNraXBfc2V0dGluZ19pbmZvX2luX2NzaV9kYXRhX29iamVjdFx1MDAzZHRydWVcdTAwMjZzbG93X2NvbXByZXNzaW9uc19iZWZvcmVfYWJhbmRvbl9jb3VudFx1MDAzZDRcdTAwMjZzcGVlZG1hc3Rlcl9jYW5jZWxsYXRpb25fbW92ZW1lbnRfZHBcdTAwM2QwXHUwMDI2c3BlZWRtYXN0ZXJfcGxheWJhY2tfcmF0ZVx1MDAzZDAuMFx1MDAyNnNwZWVkbWFzdGVyX3RvdWNoX2FjdGl2YXRpb25fbXNcdTAwM2QwXHUwMDI2c3RhcnRfY2xpZW50X2djZlx1MDAzZHRydWVcdTAwMjZzdGFydF9jbGllbnRfZ2NmX2Zvcl9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2c3RhcnRfc2VuZGluZ19jb25maWdfaGFzaFx1MDAzZHRydWVcdTAwMjZzdHJlYW1pbmdfZGF0YV9lbWVyZ2VuY3lfaXRhZ19ibGFja2xpc3RcdTAwM2RbXVx1MDAyNnN1YnN0aXR1dGVfYWRfY3BuX21hY3JvX2luX3NzZGFpXHUwMDNkdHJ1ZVx1MDAyNnN1cHByZXNzX2Vycm9yXzIwNF9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNnRyYW5zcG9ydF91c2Vfc2NoZWR1bGVyXHUwMDNkdHJ1ZVx1MDAyNnR2X3BhY2ZfbG9nZ2luZ19zYW1wbGVfcmF0ZVx1MDAzZDAuMDFcdTAwMjZ0dmh0bWw1X3VucGx1Z2dlZF9wcmVsb2FkX2NhY2hlX3NpemVcdTAwM2Q1XHUwMDI2dW5jb3Zlcl9hZF9iYWRnZV9vbl9SVExfdGlueV93aW5kb3dcdTAwM2R0cnVlXHUwMDI2dW5wbHVnZ2VkX2RhaV9saXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZ1bnBsdWdnZWRfdHZodG1sNV92aWRlb19wcmVsb2FkX29uX2ZvY3VzX2RlbGF5X21zXHUwMDNkMFx1MDAyNnVwZGF0ZV9sb2dfZXZlbnRfY29uZmlnXHUwMDNkdHJ1ZVx1MDAyNnVzZV9hY2Nlc3NpYmlsaXR5X2RhdGFfb25fZGVza3RvcF9wbGF5ZXJfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9jb3JlX3NtXHUwMDNkdHJ1ZVx1MDAyNnVzZV9pbmxpbmVkX3BsYXllcl9ycGNcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19jbWxcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19pbl9tZW1vcnlfc3RvcmFnZVx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9pbml0aWFsaXphdGlvblx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zYXdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc3R3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3d0c1x1MDAzZHRydWVcdTAwMjZ1c2VfcGxheWVyX2FidXNlX2JnX2xpYnJhcnlcdTAwM2R0cnVlXHUwMDI2dXNlX3Byb2ZpbGVwYWdlX2V2ZW50X2xhYmVsX2luX2Nhcm91c2VsX3BsYXliYWNrc1x1MDAzZHRydWVcdTAwMjZ1c2VfcmVxdWVzdF90aW1lX21zX2hlYWRlclx1MDAzZHRydWVcdTAwMjZ1c2Vfc2Vzc2lvbl9iYXNlZF9zYW1wbGluZ1x1MDAzZHRydWVcdTAwMjZ1c2VfdHNfdmlzaWJpbGl0eWxvZ2dlclx1MDAzZHRydWVcdTAwMjZ2YXJpYWJsZV9idWZmZXJfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZ2ZXJpZnlfYWRzX2l0YWdfZWFybHlcdTAwM2R0cnVlXHUwMDI2dnA5X2RybV9saXZlXHUwMDNkdHJ1ZVx1MDAyNnZzc19maW5hbF9waW5nX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnZzc19waW5nc191c2luZ19uZXR3b3JrbGVzc1x1MDAzZHRydWVcdTAwMjZ2c3NfcGxheWJhY2tfdXNlX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9hcGlfdXJsXHUwMDNkdHJ1ZVx1MDAyNndlYl9hc3luY19jb250ZXh0X3Byb2Nlc3Nvcl9pbXBsXHUwMDNkc3RhbmRhbG9uZVx1MDAyNndlYl9jaW5lbWF0aWNfd2F0Y2hfc2V0dGluZ3NcdTAwM2R0cnVlXHUwMDI2d2ViX2NsaWVudF92ZXJzaW9uX292ZXJyaWRlXHUwMDNkXHUwMDI2d2ViX2RlZHVwZV92ZV9ncmFmdGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZGVwcmVjYXRlX3NlcnZpY2VfYWpheF9tYXBfZGVwZW5kZW5jeVx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2Vycm9yXzIwNFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2luc3RyZWFtX2Fkc19saW5rX2RlZmluaXRpb25fYTExeV9idWdmaXhcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV92b3pfYXVkaW9fZmVlZGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX2ZpeF9maW5lX3NjcnViYmluZ19kcmFnXHUwMDNkdHJ1ZVx1MDAyNndlYl9mb3JlZ3JvdW5kX2hlYXJ0YmVhdF9pbnRlcnZhbF9tc1x1MDAzZDI4MDAwXHUwMDI2d2ViX2ZvcndhcmRfY29tbWFuZF9vbl9wYmpcdTAwM2R0cnVlXHUwMDI2d2ViX2dlbF9kZWJvdW5jZV9tc1x1MDAzZDYwMDAwXHUwMDI2d2ViX2dlbF90aW1lb3V0X2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfaW5saW5lX3BsYXllcl9ub19wbGF5YmFja191aV9jbGlja19oYW5kbGVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9rZXlfbW9tZW50c19tYXJrZXJzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dfbWVtb3J5X3RvdGFsX2tieXRlc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nZ2luZ19tYXhfYmF0Y2hcdTAwM2QxNTBcdTAwMjZ3ZWJfbW9kZXJuX2Fkc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zX2JsX3N1cnZleVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3NjcnViYmVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlX3N0eWxlXHUwMDNkZmlsbGVkXHUwMDI2d2ViX25ld19hdXRvbmF2X2NvdW50ZG93blx1MDAzZHRydWVcdTAwMjZ3ZWJfb25lX3BsYXRmb3JtX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9vcF9zaWduYWxfdHlwZV9iYW5saXN0XHUwMDNkW11cdTAwMjZ3ZWJfcGF1c2VkX29ubHlfbWluaXBsYXllcl9zaG9ydGN1dF9leHBhbmRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfbG9nX2N0dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF92ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FkZF92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdG9fb3V0Ym91bmRfbGlua3NcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hbHdheXNfZW5hYmxlX2F1dG9fdHJhbnNsYXRpb25cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hcGlfbG9nZ2luZ19mcmFjdGlvblx1MDAzZDAuMDFcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfZW1wdHlfc3VnZ2VzdGlvbnNfZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl90b2dnbGVfYWx3YXlzX2xpc3Rlblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdXNlX3NlcnZlcl9wcm92aWRlZF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2NhcHRpb25fbGFuZ3VhZ2VfcHJlZmVyZW5jZV9zdGlja2luZXNzX2R1cmF0aW9uXHUwMDNkMzBcdTAwMjZ3ZWJfcGxheWVyX2RlY291cGxlX2F1dG9uYXZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9kaXNhYmxlX2lubGluZV9zY3J1YmJpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZWFybHlfd2FybmluZ19zbmFja2Jhclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9mZWF0dXJlZF9wcm9kdWN0X2Jhbm5lcl9vbl9kZXNrdG9wXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX2luX2g1X2FwaVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9wbGF5YmFja19jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pbm5lcnR1YmVfcGxheWxpc3RfdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaXBwX2NhbmFyeV90eXBlX2Zvcl9sb2dnaW5nXHUwMDNkXHUwMDI2d2ViX3BsYXllcl9saXZlX21vbml0b3JfZW52XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbG9nX2NsaWNrX2JlZm9yZV9nZW5lcmF0aW5nX3ZlX2NvbnZlcnNpb25fcGFyYW1zXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbW92ZV9hdXRvbmF2X3RvZ2dsZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX211c2ljX3Zpc3VhbGl6ZXJfdHJlYXRtZW50XHUwMDNkZmFrZVx1MDAyNndlYl9wbGF5ZXJfbXV0YWJsZV9ldmVudF9sYWJlbFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX25pdHJhdGVfcHJvbW9fdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX29mZmxpbmVfcGxheWxpc3RfYXV0b19yZWZyZXNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfcmVzcG9uc2VfcGxheWJhY2tfdHJhY2tpbmdfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlZWtfY2hhcHRlcnNfYnlfc2hvcnRjdXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZW50aW5lbF9pc191bmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG91bGRfaG9ub3JfaW5jbHVkZV9hc3Jfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3dfbXVzaWNfaW5fdGhpc192aWRlb19ncmFwaGljXHUwMDNkdmlkZW9fdGh1bWJuYWlsXHUwMDI2d2ViX3BsYXllcl9zbWFsbF9oYnBfc2V0dGluZ3NfbWVudVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NzX2RhaV9hZF9mZXRjaGluZ190aW1lb3V0X21zXHUwMDNkMTUwMDBcdTAwMjZ3ZWJfcGxheWVyX3NzX21lZGlhX3RpbWVfb2Zmc2V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG9waWZ5X3N1YnRpdGxlc19mb3Jfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG91Y2hfbW9kZV9pbXByb3ZlbWVudHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90cmFuc2Zlcl90aW1lb3V0X3RocmVzaG9sZF9tc1x1MDAzZDEwODAwMDAwXHUwMDI2d2ViX3BsYXllcl91bnNldF9kZWZhdWx0X2Nzbl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdXNlX25ld19hcGlfZm9yX3F1YWxpdHlfcHVsbGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl92ZV9jb252ZXJzaW9uX2ZpeGVzX2Zvcl9jaGFubmVsX2luZm9cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZV9wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wcmVmZXRjaF9wcmVsb2FkX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNndlYl9yb3VuZGVkX3RodW1ibmFpbHNcdTAwM2R0cnVlXHUwMDI2d2ViX3NldHRpbmdzX21lbnVfaWNvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X21ldGhvZFx1MDAzZDBcdTAwMjZ3ZWJfeXRfY29uZmlnX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2d2lsX2ljb25fcmVuZGVyX3doZW5faWRsZVx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfY2xlYW5fdXBfYWZ0ZXJfZW50aXR5X21pZ3JhdGlvblx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfZW5hYmxlX2Rvd25sb2FkX3N0YXR1c1x1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfcGxheWxpc3Rfb3B0aW1pemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2NsZWFyX2VtYmVkZGVkX3BsYXllclx1MDAzZHRydWVcdTAwMjZ5dGlkYl9mZXRjaF9kYXRhc3luY19pZHNfZm9yX2RhdGFfY2xlYW51cFx1MDAzZHRydWVcdTAwMjZ5dGlkYl9yZW1ha2VfZGJfcmV0cmllc1x1MDAzZDFcdTAwMjZ5dGlkYl9yZW9wZW5fZGJfcmV0cmllc1x1MDAzZDBcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0XHUwMDNkMC4wMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfc2Vzc2lvblx1MDAzZDAuMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfdHJhbnNhY3Rpb25cdTAwM2QwLjEiLCJkaXNhYmxlRnVsbHNjcmVlbiI6dHJ1ZSwiY3NwTm9uY2UiOiJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIiwiY2FuYXJ5U3RhdGUiOiJub25lIiwiZGF0YXN5bmNJZCI6IlYyMDIxN2ZjNnx8In0sIldFQl9QTEFZRVJfQ09OVEVYVF9DT05GSUdfSURfS0VWTEFSX0lOTElORV9QUkVWSUVXIjp7InJvb3RFbGVtZW50SWQiOiJpbmxpbmUtcHJldmlldy1wbGF5ZXIiLCJqc1VybCI6Ii9zL3BsYXllci9iMTI4ZGRhMC9wbGF5ZXJfaWFzLnZmbHNldC9mcl9GUi9iYXNlLmpzIiwiY3NzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3d3dy1wbGF5ZXIuY3NzIiwiY29udGV4dElkIjoiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfSU5MSU5FX1BSRVZJRVciLCJldmVudExhYmVsIjoiZGV0YWlscGFnZSIsImNvbnRlbnRSZWdpb24iOiJGUiIsImhsIjoiZnJfRlIiLCJob3N0TGFuZ3VhZ2UiOiJmciIsInBsYXllclN0eWxlIjoiZGVza3RvcC1wb2x5bWVyIiwiaW5uZXJ0dWJlQXBpS2V5IjoiQUl6YVN5QU9fRkoyU2xxVThRNFNURUhMR0NpbHdfWTlfMTFxY1c4IiwiaW5uZXJ0dWJlQXBpVmVyc2lvbiI6InYxIiwiaW5uZXJ0dWJlQ29udGV4dENsaWVudFZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIiwiZGlzYWJsZUtleWJvYXJkQ29udHJvbHMiOnRydWUsImRldmljZSI6eyJicmFuZCI6IiIsIm1vZGVsIjoiIiwicGxhdGZvcm0iOiJERVNLVE9QIiwiaW50ZXJmYWNlTmFtZSI6IldFQiIsImludGVyZmFjZVZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIn0sInNlcmlhbGl6ZWRFeHBlcmltZW50SWRzIjoiMjM5ODMyOTYsMjQwMDQ2NDQsMjQwMDcyNDYsMjQwMDc2MTMsMjQwODA3MzgsMjQxMzUzMTAsMjQzNjMxMTQsMjQzNjQ3ODksMjQzNjU1MzQsMjQzNjY5MTcsMjQzNzI3NjEsMjQzNzUxMDEsMjQzNzY3ODUsMjQ0MTU4NjQsMjQ0MTYyOTAsMjQ0MzM2NzksMjQ0Mzc1NzcsMjQ0MzkzNjEsMjQ0NDMzMzEsMjQ0OTk1MzIsMjQ1MzI4NTUsMjQ1NTA0NTgsMjQ1NTA5NTEsMjQ1NTU1NjcsMjQ1NTg2NDEsMjQ1NTkzMjcsMjQ2OTk4OTksMzkzMjMwNzQiLCJzZXJpYWxpemVkRXhwZXJpbWVudEZsYWdzIjoiSDVfYXN5bmNfbG9nZ2luZ19kZWxheV9tc1x1MDAzZDMwMDAwLjBcdTAwMjZINV9lbmFibGVfZnVsbF9wYWNmX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2SDVfdXNlX2FzeW5jX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2YWN0aW9uX2NvbXBhbmlvbl9jZW50ZXJfYWxpZ25fZGVzY3JpcHRpb25cdTAwM2R0cnVlXHUwMDI2YWRfcG9kX2Rpc2FibGVfY29tcGFuaW9uX3BlcnNpc3RfYWRzX3F1YWxpdHlcdTAwM2R0cnVlXHUwMDI2YWRkdG9fYWpheF9sb2dfd2FybmluZ19mcmFjdGlvblx1MDAzZDAuMVx1MDAyNmFsaWduX2FkX3RvX3ZpZGVvX3BsYXllcl9saWZlY3ljbGVfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2YWxsb3dfbGl2ZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19wb2x0ZXJndXN0X2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X3NraXBfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2YXR0X3dlYl9yZWNvcmRfbWV0cmljc1x1MDAzZHRydWVcdTAwMjZhdXRvcGxheV90aW1lXHUwMDNkODAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX2Z1bGxzY3JlZW5cdTAwM2QzMDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfbXVzaWNfY29udGVudFx1MDAzZDMwMDBcdTAwMjZiZ192bV9yZWluaXRfdGhyZXNob2xkXHUwMDNkNzIwMDAwMFx1MDAyNmJsb2NrZWRfcGFja2FnZXNfZm9yX3Nwc1x1MDAzZFtdXHUwMDI2Ym90Z3VhcmRfYXN5bmNfc25hcHNob3RfdGltZW91dF9tc1x1MDAzZDMwMDBcdTAwMjZjaGVja19hZF91aV9zdGF0dXNfZm9yX213ZWJfc2FmYXJpXHUwMDNkdHJ1ZVx1MDAyNmNoZWNrX25hdmlnYXRvcl9hY2N1cmFjeV90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmNsZWFyX3VzZXJfcGFydGl0aW9uZWRfbHNcdTAwM2R0cnVlXHUwMDI2Y2xpZW50X3Jlc3BlY3RfYXV0b3BsYXlfc3dpdGNoX2J1dHRvbl9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZjb21wcmVzc19nZWxcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3Npb25fZGlzYWJsZV9wb2ludFx1MDAzZDEwXHUwMDI2Y29tcHJlc3Npb25fcGVyZm9ybWFuY2VfdGhyZXNob2xkXHUwMDNkMjUwXHUwMDI2Y3NpX29uX2dlbFx1MDAzZHRydWVcdTAwMjZkYXNoX21hbmlmZXN0X3ZlcnNpb25cdTAwM2Q1XHUwMDI2ZGVidWdfYmFuZGFpZF9ob3N0bmFtZVx1MDAzZFx1MDAyNmRlYnVnX3NoZXJsb2dfdXNlcm5hbWVcdTAwM2RcdTAwMjZkZWxheV9hZHNfZ3ZpX2NhbGxfb25fYnVsbGVpdF9saXZpbmdfcm9vbV9tc1x1MDAzZDBcdTAwMjZkZXByZWNhdGVfY3NpX2hhc19pbmZvXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV9wYWlyX3NlcnZsZXRfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX2NoaWxkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfcGFyZW50XHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfaW1hZ2VfY3RhX25vX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9sb2dfaW1nX2NsaWNrX2xvY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3Bfc3BhcmtsZXNfbGlnaHRfY3RhX2J1dHRvblx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoYW5uZWxfaWRfY2hlY2tfZm9yX3N1c3BlbmRlZF9jaGFubmVsc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoaWxkX25vZGVfYXV0b19mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2RlZmVyX2FkbW9kdWxlX29uX2FkdmVydGlzZXJfdmlkZW9cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9mZWF0dXJlc19mb3Jfc3VwZXhcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9sZWdhY3lfZGVza3RvcF9yZW1vdGVfcXVldWVcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9tZHhfY29ubmVjdGlvbl9pbl9tZHhfbW9kdWxlX2Zvcl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9uZXdfcGF1c2Vfc3RhdGUzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcGFjZl9sb2dnaW5nX2Zvcl9tZW1vcnlfbGltaXRlZF90dlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3JvdW5kaW5nX2FkX25vdGlmeVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NpbXBsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zc2RhaV9vbl9lcnJvcnNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90YWJiaW5nX2JlZm9yZV9mbHlvdXRfYWRfZWxlbWVudHNfYXBwZWFyXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGh1bWJuYWlsX3ByZWxvYWRpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2Rpc2FibGVfcHJvZ3Jlc3NfYmFyX2NvbnRleHRfbWVudV9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZW5hYmxlX2FsbG93X3dhdGNoX2FnYWluX2VuZHNjcmVlbl9mb3JfZWxpZ2libGVfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc192ZV9jb252ZXJzaW9uX3BhcmFtX3JlbmFtaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2F1dG9wbGF5X25vdF9zdXBwb3J0ZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfY3VlX3ZpZGVvX3VucGxheWFibGVfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2hvdXNlX2JyYW5kX2FuZF95dF9jb2V4aXN0ZW5jZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2FkX3BsYXllcl9mcm9tX3BhZ2Vfc2hvd1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dfc3BsYXlfYXNfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nZ2luZ19ldmVudF9oYW5kbGVyc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2R0dHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbmV3X2NvbnRleHRfbWVudV90cmlnZ2VyaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BhdXNlX292ZXJsYXlfd25fdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BlbV9kb21haW5fZml4X2Zvcl9hZF9yZXF1ZXN0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZnBfdW5icmFuZGVkX2VsX2RlcHJlY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JjYXRfYWxsb3dsaXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JlcGxhY2VfdW5sb2FkX3dfcGFnZWhpZGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfc2NyaXB0ZWRfcGxheWJhY2tfYmxvY2tlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdHJhY2tpbmdfbm9fYWxsb3dfbGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2hpZGVfdW5maWxsZWRfbW9yZV92aWRlb3Nfc3VnZ2VzdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9saXRlX21vZGVcdTAwM2QxXHUwMDI2ZW1iZWRzX3dlYl9ud2xfZGlzYWJsZV9ub2Nvb2tpZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3Nob3BwaW5nX292ZXJsYXlfbm9fd2FpdF9mb3JfcGFpZF9jb250ZW50X292ZXJsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zeW50aF9jaF9oZWFkZXJzX2Jhbm5lZF91cmxzX3JlZ2V4XHUwMDNkXHUwMDI2ZW5hYmxlX2FiX3JwX2ludFx1MDAzZHRydWVcdTAwMjZlbmFibGVfYWRfY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FwcF9wcm9tb19lbmRjYXBfZW1sX29uX3RhYmxldFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9mb3Jfd2ViX3VucGx1Z2dlZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9vbl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9wYWdlX2lkX2hlYWRlcl9mb3JfZmlyc3RfcGFydHlfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9zbGlfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZGlzY3JldGVfbGl2ZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudF9jaGVja1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRzX2ljb25fd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9ldmljdGlvbl9wcm90ZWN0aW9uX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9nZWxfbG9nX2NvbW1hbmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV9pbnN0cmVhbV93YXRjaF9uZXh0X3BhcmFtc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X3ZpZGVvX2Fkc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2hhbmRsZXNfYWNjb3VudF9tZW51X3N3aXRjaGVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9rYWJ1a2lfY29tbWVudHNfb25fc2hvcnRzXHUwMDNkZGlzYWJsZWRcdTAwMjZlbmFibGVfbGl2ZV9wcmVtaWVyZV93ZWJfcGxheWVyX2luZGljYXRvclx1MDAzZHRydWVcdTAwMjZlbmFibGVfbHJfaG9tZV9pbmZlZWRfYWRzX2lubGluZV9wbGF5YmFja19wcm9ncmVzc19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9td2ViX2VuZGNhcF9jbGlja2FibGVfaWNvbl9kZXNjcmlwdGlvblx1MDAzZHRydWVcdTAwMjZlbmFibGVfbXdlYl9saXZlc3RyZWFtX3VpX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbmFibGVfbmV3X3BhaWRfcHJvZHVjdF9wbGFjZW1lbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2Zfc2xvdF9hc2RlX3BsYXllcl9ieXRlX2g1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZfZm9yX3BhZ2VfdG9wX2Zvcm1hdHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95c2ZlX3R2XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYXNzX3NkY19nZXRfYWNjb3VudHNfbGlzdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGxfcl9jXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2ZpeF9vbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2luX3R2aHRtbDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NlcnZlcl9zdGl0Y2hlZF9kYWlcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Nob3J0c19wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NraXBfYWRfZ3VpZGFuY2VfcHJvbXB0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwcGFibGVfYWRzX2Zvcl91bnBsdWdnZWRfYWRfcG9kXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90ZWN0b25pY19hZF91eF9mb3JfaGFsZnRpbWVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RoaXJkX3BhcnR5X2luZm9cdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RvcHNvaWxfd3RhX2Zvcl9oYWxmdGltZV9saXZlX2luZnJhXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfbWVkaWFfc2Vzc2lvbl9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3dlYl9zY2hlZHVsZXJfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfd25faW5mb2NhcmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV95dF9hdGFfaWZyYW1lX2F1dGh1c2VyXHUwMDNkdHJ1ZVx1MDAyNmVycm9yX21lc3NhZ2VfZm9yX2dzdWl0ZV9uZXR3b3JrX3Jlc3RyaWN0aW9uc1x1MDAzZHRydWVcdTAwMjZleHBvcnRfbmV0d29ya2xlc3Nfb3B0aW9uc1x1MDAzZHRydWVcdTAwMjZleHRlcm5hbF9mdWxsc2NyZWVuX3dpdGhfZWR1XHUwMDNkdHJ1ZVx1MDAyNmZhc3RfYXV0b25hdl9pbl9iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmZldGNoX2F0dF9pbmRlcGVuZGVudGx5XHUwMDNkdHJ1ZVx1MDAyNmZpbGxfc2luZ2xlX3ZpZGVvX3dpdGhfbm90aWZ5X3RvX2xhc3JcdTAwM2R0cnVlXHUwMDI2ZmlsdGVyX3ZwOV9mb3JfY3NkYWlcdTAwM2R0cnVlXHUwMDI2Zml4X2Fkc190cmFja2luZ19mb3Jfc3dmX2NvbmZpZ19kZXByZWNhdGlvbl9td2ViXHUwMDNkdHJ1ZVx1MDAyNmdjZl9jb25maWdfc3RvcmVfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZnZWxfcXVldWVfdGltZW91dF9tYXhfbXNcdTAwM2QzMDAwMDBcdTAwMjZncGFfc3BhcmtsZXNfdGVuX3BlcmNlbnRfbGF5ZXJcdTAwM2R0cnVlXHUwMDI2Z3ZpX2NoYW5uZWxfY2xpZW50X3NjcmVlblx1MDAzZHRydWVcdTAwMjZoNV9jb21wYW5pb25fZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX2dlbmVyaWNfZXJyb3JfbG9nZ2luZ19ldmVudFx1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfdW5pZmllZF9jc2lfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZoNV9pbnBsYXllcl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9yZXNldF9jYWNoZV9hbmRfZmlsdGVyX2JlZm9yZV91cGRhdGVfbWFzdGhlYWRcdTAwM2R0cnVlXHUwMDI2aGVhdHNlZWtlcl9kZWNvcmF0aW9uX3RocmVzaG9sZFx1MDAzZDAuMFx1MDAyNmhmcl9kcm9wcGVkX2ZyYW1lcmF0ZV9mYWxsYmFja190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aGlkZV9lbmRwb2ludF9vdmVyZmxvd19vbl95dGRfZGlzcGxheV9hZF9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZodG1sNV9hZF90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2Fkc19wcmVyb2xsX2xvY2tfdGltZW91dF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfYWxsb3dfZGlzY29udGlndW91c19zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWxsb3dfdmlkZW9fa2V5ZnJhbWVfd2l0aG91dF9hdWRpb1x1MDAzZHRydWVcdTAwMjZodG1sNV9hdHRhY2hfbnVtX3JhbmRvbV9ieXRlc190b19iYW5kYWlkXHUwMDNkMFx1MDAyNmh0bWw1X2F0dGFjaF9wb190b2tlbl90b19iYW5kYWlkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F1dG9uYXZfY2FwX2lkbGVfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9hdXRvbmF2X3F1YWxpdHlfY2FwXHUwMDNkNzIwXHUwMDI2aHRtbDVfYXV0b3BsYXlfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9ibG9ja19waXBfc2FmYXJpX2RlbGF5XHUwMDNkMFx1MDAyNmh0bWw1X2JtZmZfbmV3X2ZvdXJjY19jaGVja1x1MDAzZHRydWVcdTAwMjZodG1sNV9jb2JhbHRfZGVmYXVsdF9idWZmZXJfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWF4X3NpemVfZm9yX2ltbWVkX2pvYlx1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWluX3Byb2Nlc3Nvcl9jbnRfdG9fb2ZmbG9hZF9hbGdvXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9vdmVycmlkZV9xdWljXHUwMDNkMFx1MDAyNmh0bWw1X2NvbnN1bWVfbWVkaWFfYnl0ZXNfc2xpY2VfaW5mb3NcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVfZHVwZV9jb250ZW50X3ZpZGVvX2xvYWRzX2luX2xpZmVjeWNsZV9hcGlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVidWdfZGF0YV9sb2dfcHJvYmFiaWxpdHlcdTAwM2QwLjFcdTAwMjZodG1sNV9kZWNvZGVfdG9fdGV4dHVyZV9jYXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVmYXVsdF9hZF9nYWluXHUwMDNkMC41XHUwMDI2aHRtbDVfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9hZF9tb2R1bGVfbXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfZmV0Y2hfYXR0X21zXHUwMDNkMTAwMFx1MDAyNmh0bWw1X2RlZmVyX21vZHVsZXNfZGVsYXlfdGltZV9taWxsaXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9jb3VudFx1MDAzZDFcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2RlbGF5X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X2RlcHJlY2F0ZV92aWRlb190YWdfcG9vbFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZXNrdG9wX3ZyMTgwX2FsbG93X3Bhbm5pbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGZfZG93bmdyYWRlX3RocmVzaFx1MDAzZDAuMlx1MDAyNmh0bWw1X2Rpc2FibGVfY3NpX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbW92ZV9wc3NoX3RvX21vb3ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9ub25fY29udGlndW91c1x1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNwbGF5ZWRfZnJhbWVfcmF0ZV9kb3duZ3JhZGVfdGhyZXNob2xkXHUwMDNkNDVcdTAwMjZodG1sNV9kcm1fY2hlY2tfYWxsX2tleV9lcnJvcl9zdGF0ZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZHJtX2NwaV9saWNlbnNlX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hZHNfY2xpZW50X21vbml0b3JpbmdfbG9nX3R2XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jYXB0aW9uX2NoYW5nZXNfZm9yX21vc2FpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2xpZW50X2hpbnRzX292ZXJyaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jb21wb3NpdGVfZW1iYXJnb1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZWFjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZW1iZWRkZWRfcGxheWVyX3Zpc2liaWxpdHlfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbm9uX25vdGlmeV9jb21wb3NpdGVfdm9kX2xzYXJfcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfc2luZ2xlX3ZpZGVvX3ZvZF9pdmFyX29uX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZGFzaFx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19lbmNyeXB0ZWRfdnA5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfYWxjXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfZmFzdF9saW5lYXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5jb3VyYWdlX2FycmF5X2NvYWxlc2NpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2FwbGVzc19lbmRlZF90cmFuc2l0aW9uX2J1ZmZlcl9tc1x1MDAzZDIwMFx1MDAyNmh0bWw1X2dlbmVyYXRlX3Nlc3Npb25fcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2xfZnBzX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZodG1sNV9oZGNwX3Byb2Jpbmdfc3RyZWFtX3VybFx1MDAzZFx1MDAyNmh0bWw1X2hmcl9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QxLjBcdTAwMjZodG1sNV9pZGxlX3JhdGVfbGltaXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX2ZhaXJwbGF5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9wbGF5cmVhZHlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3dpZGV2aW5lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczRfc2Vla19hYm92ZV96ZXJvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczdfZm9yY2VfcGxheV9vbl9zdGFsbFx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3NfZm9yY2Vfc2Vla190b196ZXJvX29uX3N0b3BcdTAwM2R0cnVlXHUwMDI2aHRtbDVfanVtYm9fbW9iaWxlX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDMuMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9ub25zdHJlYW1pbmdfbWZmYV9tc1x1MDAzZDQwMDBcdTAwMjZodG1sNV9qdW1ib191bGxfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMS4zXHUwMDI2aHRtbDVfbGljZW5zZV9jb25zdHJhaW50X2RlbGF5XHUwMDNkNTAwMFx1MDAyNmh0bWw1X2xpdmVfYWJyX2hlYWRfbWlzc19mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYWJyX3JlcHJlZGljdF9mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYnl0ZXJhdGVfZmFjdG9yX2Zvcl9yZWFkYWhlYWRcdTAwM2QxLjNcdTAwMjZodG1sNV9saXZlX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9saXZlX25vcm1hbF9sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2xpdmVfdWx0cmFfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xvZ19hdWRpb19hYnJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX2V4cGVyaW1lbnRfaWRfZnJvbV9wbGF5ZXJfcmVzcG9uc2VfdG9fY3RtcFx1MDAzZFx1MDAyNmh0bWw1X2xvZ19maXJzdF9zc2RhaV9yZXF1ZXN0c19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19yZWJ1ZmZlcl9ldmVudHNcdTAwM2Q1XHUwMDI2aHRtbDVfbG9nX3NzZGFpX2ZhbGxiYWNrX2Fkc1x1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfdHJpZ2dlcl9ldmVudHNfd2l0aF9kZWJ1Z19kYXRhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX3RocmVzaG9sZF9tc1x1MDAzZDMwMDAwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3NlZ19kcmlmdF9saW1pdF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc191bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3ZwOV9vdGZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWF4X2RyaWZ0X3Blcl90cmFja19zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWF4X2hlYWRtX2Zvcl9zdHJlYW1pbmdfeGhyXHUwMDNkMFx1MDAyNmh0bWw1X21heF9saXZlX2R2cl93aW5kb3dfcGx1c19tYXJnaW5fc2Vjc1x1MDAzZDQ2ODAwLjBcdTAwMjZodG1sNV9tYXhfcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21heF9yZWRpcmVjdF9yZXNwb25zZV9sZW5ndGhcdTAwM2Q4MTkyXHUwMDI2aHRtbDVfbWF4X3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21heF9zb3VyY2VfYnVmZmVyX2FwcGVuZF9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X21heGltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9tZWRpYV9mdWxsc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21mbF9leHRlbmRfbWF4X3JlcXVlc3RfdGltZVx1MDAzZHRydWVcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9jYXBfc2Vjc1x1MDAzZDYwXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9taW5fc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfYWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbm9fcGxhY2Vob2xkZXJfcm9sbGJhY2tzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vbl9uZXR3b3JrX3JlYnVmZmVyX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X25vbl9vbmVzaWVfYXR0YWNoX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vdF9yZWdpc3Rlcl9kaXNwb3NhYmxlc193aGVuX2NvcmVfbGlzdGVuc1x1MDAzZHRydWVcdTAwMjZodG1sNV9vZmZsaW5lX2ZhaWx1cmVfcmV0cnlfbGltaXRcdTAwM2QyXHUwMDI2aHRtbDVfb25lc2llX2RlZmVyX2NvbnRlbnRfbG9hZGVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9ob3N0X3JhY2luZ19jYXBfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2lnbm9yZV9pbm5lcnR1YmVfYXBpX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbGl2ZV90dGxfc2Vjc1x1MDAzZDhcdTAwMjZodG1sNV9vbmVzaWVfbm9uemVyb19wbGF5YmFja19zdGFydFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbm90aWZ5X2N1ZXBvaW50X21hbmFnZXJfb25fY29tcGxldGlvblx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9jb29sZG93bl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9pbnRlcnZhbF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9tYXhfbGFjdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlcXVlc3RfdGltZW91dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9vbmVzaWVfc3RpY2t5X3NlcnZlcl9zaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BhdXNlX29uX25vbmZvcmVncm91bmRfcGxhdGZvcm1fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlYWtfc2hhdmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZl9jYXBfb3ZlcnJpZGVfc3RpY2t5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2NhcF9mbG9vclx1MDAzZDM2MFx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2ltcGFjdF9wcm9maWxpbmdfdGltZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcGVyc2VydmVfYXYxX3BlcmZfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX21pbmltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9wbGF5ZXJfYXV0b25hdl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXllcl9keW5hbWljX2JvdHRvbV9ncmFkaWVudFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfbWluX2J1aWxkX2NsXHUwMDNkLTFcdTAwMjZodG1sNV9wbGF5ZXJfcHJlbG9hZF9hZF9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcG9zdF9pbnRlcnJ1cHRfcmVhZGFoZWFkXHUwMDNkMjBcdTAwMjZodG1sNV9wcmVmZXJfc2VydmVyX2J3ZTNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcHJlbG9hZF93YWl0X3RpbWVfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Byb2JlX3ByaW1hcnlfZGVsYXlfYmFzZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9wcm9jZXNzX2FsbF9lbmNyeXB0ZWRfZXZlbnRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3FvZV9saF9tYXhfcmVwb3J0X2NvdW50XHUwMDNkMFx1MDAyNmh0bWw1X3FvZV9saF9taW5fZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfcXVlcnlfc3dfc2VjdXJlX2NyeXB0b19mb3JfYW5kcm9pZFx1MDAzZHRydWVcdTAwMjZodG1sNV9yYW5kb21fcGxheWJhY2tfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X3JlY29nbml6ZV9wcmVkaWN0X3N0YXJ0X2N1ZV9wb2ludFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfY29tbWFuZF90cmlnZ2VyZWRfY29tcGFuaW9uc1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfbm90X3NlcnZhYmxlX2NoZWNrX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVuYW1lX2FwYnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X2ZhdGFsX2RybV9yZXN0cmljdGVkX2Vycm9yX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X3Nsb3dfYWRzX2FzX2Vycm9yXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfb25seV9oZHJfb3Jfc2RyX2tleXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVxdWVzdF9zaXppbmdfbXVsdGlwbGllclx1MDAzZDAuOFx1MDAyNmh0bWw1X3Jlc2V0X21lZGlhX3N0cmVhbV9vbl91bnJlc3VtYWJsZV9zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVzb3VyY2VfYmFkX3N0YXR1c19kZWxheV9zY2FsaW5nXHUwMDNkMS41XHUwMDI2aHRtbDVfcmVzdHJpY3Rfc3RyZWFtaW5nX3hocl9vbl9zcWxlc3NfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2FmYXJpX2Rlc2t0b3BfZW1lX21pbl92ZXJzaW9uXHUwMDNkMFx1MDAyNmh0bWw1X3NhbXN1bmdfa2FudF9saW1pdF9tYXhfYml0cmF0ZVx1MDAzZDBcdTAwMjZodG1sNV9zZWVrX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2Q4MDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9kZWxheV9tc1x1MDAzZDEyMDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfYnVmZmVyX3JhbmdlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX3Zyc19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2NmbFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfc2V0X2NtdF9kZWxheV9tc1x1MDAzZDIwMDBcdTAwMjZodG1sNV9zZWVrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NlcnZlcl9zdGl0Y2hlZF9kYWlfZGVjb3JhdGVkX3VybF9yZXRyeV9saW1pdFx1MDAzZDVcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2dyb3VwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Nlc3Npb25fcG9fdG9rZW5faW50ZXJ2YWxfdGltZV9tc1x1MDAzZDkwMDAwMFx1MDAyNmh0bWw1X3NraXBfb29iX3N0YXJ0X3NlY29uZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2tpcF9zbG93X2FkX2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9za2lwX3N1Yl9xdWFudHVtX2Rpc2NvbnRpbnVpdHlfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfbm9fbWVkaWFfc291cmNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfdGltZW91dF9kZWxheV9tc1x1MDAzZDIwMDAwXHUwMDI2aHRtbDVfc3NkYWlfYWRmZXRjaF9keW5hbWljX3RpbWVvdXRfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfc3NkYWlfZW5hYmxlX25ld19zZWVrX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N0YXRlZnVsX2F1ZGlvX21pbl9hZGp1c3RtZW50X3ZhbHVlXHUwMDNkMFx1MDAyNmh0bWw1X3N0YXRpY19hYnJfcmVzb2x1dGlvbl9zaGVsZlx1MDAzZDBcdTAwMjZodG1sNV9zdG9yZV94aHJfaGVhZGVyc19yZWFkYWJsZVx1MDAzZHRydWVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9sb2FkX3NwZWVkX2NoZWNrX2ludGVydmFsXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuMjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzX29uX3RpbWVvdXRcdTAwM2QwLjFcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fbG9hZF9zcGVlZFx1MDAzZDEuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3NlZWtfbGF0ZW5jeV9mdWRnZVx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldF9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90aW1lb3V0X3NlY3NcdTAwM2QyLjBcdTAwMjZodG1sNV91Z2NfbGl2ZV9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91Z2Nfdm9kX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VucmVwb3J0ZWRfc2Vla19yZXNlZWtfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfdW5yZXN0cmljdGVkX2xheWVyX2hpZ2hfcmVzX2xvZ2dpbmdfcGVyY2VudFx1MDAzZDAuMFx1MDAyNmh0bWw1X3VybF9wYWRkaW5nX2xlbmd0aFx1MDAzZDBcdTAwMjZodG1sNV91cmxfc2lnbmF0dXJlX2V4cGlyeV90aW1lX2hvdXJzXHUwMDNkMFx1MDAyNmh0bWw1X3VzZV9wb3N0X2Zvcl9tZWRpYVx1MDAzZHRydWVcdTAwMjZodG1sNV91c2VfdW1wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ZpZGVvX3RiZF9taW5fa2JcdTAwM2QwXHUwMDI2aHRtbDVfdmlld3BvcnRfdW5kZXJzZW5kX21heGltdW1cdTAwM2QwLjBcdTAwMjZodG1sNV92b2x1bWVfc2xpZGVyX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2ViX2VuYWJsZV9oYWxmdGltZV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYnBvX2lkbGVfcHJpb3JpdHlfam9iXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvZmZsZV9yZXN1bWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29ya2Fyb3VuZF9kZWxheV90cmlnZ2VyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3l0dmxyX2VuYWJsZV9zaW5nbGVfc2VsZWN0X3N1cnZleVx1MDAzZHRydWVcdTAwMjZpZ25vcmVfb3ZlcmxhcHBpbmdfY3VlX3BvaW50c19vbl9lbmRlbWljX2xpdmVfaHRtbDVcdTAwM2R0cnVlXHUwMDI2aWxfdXNlX3ZpZXdfbW9kZWxfbG9nZ2luZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNmluaXRpYWxfZ2VsX2JhdGNoX3RpbWVvdXRcdTAwM2QyMDAwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2xpY2Vuc2Vfc3RhdHVzXHUwMDNkMFx1MDAyNml0ZHJtX2luamVjdGVkX2xpY2Vuc2Vfc2VydmljZV9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNml0ZHJtX3dpZGV2aW5lX2hhcmRlbmVkX3ZtcF9tb2RlXHUwMDNkbG9nXHUwMDI2anNvbl9jb25kZW5zZWRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2NvbW1hbmRfaGFuZGxlcl9jb21tYW5kX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNmtldmxhcl9kcm9wZG93bl9maXhcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2dlbF9lcnJvcl9yb3V0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX2V4cGFuZF90b3BcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfcGxheV9wYXVzZV9vbl9zY3JpbVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcGxheWJhY2tfYXNzb2NpYXRlZF9xdWV1ZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcXVldWVfdXNlX3VwZGF0ZV9hcGlcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NpbXBfc2hvcnRzX3Jlc2V0X3Njcm9sbFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfdmltaW9fdXNlX3NoYXJlZF9tb25pdG9yXHUwMDNkdHJ1ZVx1MDAyNmxpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNmxpdmVfZnJlc2NhX3YyXHUwMDNkdHJ1ZVx1MDAyNmxvZ19lcnJvcnNfdGhyb3VnaF9ud2xfb25fcmV0cnlcdTAwM2R0cnVlXHUwMDI2bG9nX2dlbF9jb21wcmVzc2lvbl9sYXRlbmN5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19oZWFydGJlYXRfd2l0aF9saWZlY3ljbGVzXHUwMDNkdHJ1ZVx1MDAyNmxvZ193ZWJfZW5kcG9pbnRfdG9fbGF5ZXJcdTAwM2R0cnVlXHUwMDI2bG9nX3dpbmRvd19vbmVycm9yX2ZyYWN0aW9uXHUwMDNkMC4xXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZVx1MDAzZHRydWVcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlX3VmcGhcdTAwM2R0cnVlXHUwMDI2bWF4X2JvZHlfc2l6ZV90b19jb21wcmVzc1x1MDAzZDUwMDAwMFx1MDAyNm1heF9wcmVmZXRjaF93aW5kb3dfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDBcdTAwMjZtYXhfcmVzb2x1dGlvbl9mb3Jfd2hpdGVfbm9pc2VcdTAwM2QzNjBcdTAwMjZtZHhfZW5hYmxlX3ByaXZhY3lfZGlzY2xvc3VyZV91aVx1MDAzZHRydWVcdTAwMjZtZHhfbG9hZF9jYXN0X2FwaV9ib290c3RyYXBfc2NyaXB0XHUwMDNkdHJ1ZVx1MDAyNm1pZ3JhdGVfZXZlbnRzX3RvX3RzXHUwMDNkdHJ1ZVx1MDAyNm1pbl9wcmVmZXRjaF9vZmZzZXRfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDEwXHUwMDI2bXVzaWNfZW5hYmxlX3NoYXJlZF9hdWRpb190aWVyX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfYzNfZW5kc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX2N1c3RvbV9jb250cm9sX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9za2lwcGFibGVzX29uX2ppb19waG9uZVx1MDAzZHRydWVcdTAwMjZtd2ViX211dGVkX2F1dG9wbGF5X2FuaW1hdGlvblx1MDAzZHNocmlua1x1MDAyNm13ZWJfbmF0aXZlX2NvbnRyb2xfaW5fZmF1eF9mdWxsc2NyZWVuX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrX3BvbGxpbmdfaW50ZXJ2YWxcdTAwM2QzMDAwMFx1MDAyNm5ldHdvcmtsZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrbGVzc19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNm5ld19jb2RlY3Nfc3RyaW5nX2FwaV91c2VzX2xlZ2FjeV9zdHlsZVx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mYXN0X29uX3VubG9hZFx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mcm9tX21lbW9yeV93aGVuX29ubGluZVx1MDAzZHRydWVcdTAwMjZvZmZsaW5lX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNnBhY2ZfbG9nZ2luZ19kZWxheV9taWxsaXNlY29uZHNfdGhyb3VnaF95YmZlX3R2XHUwMDNkMzAwMDBcdTAwMjZwYWdlaWRfYXNfaGVhZGVyX3dlYlx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWRzX3NldF9hZGZvcm1hdF9vbl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2FsbG93X2F1dG9uYXZfYWZ0ZXJfcGxheWxpc3RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Jvb3RzdHJhcF9tZXRob2RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RlZmVyX2NhcHRpb25fZGlzcGxheVx1MDAzZDEwMDBcdTAwMjZwbGF5ZXJfZGVzdHJveV9vbGRfdmVyc2lvblx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZG91YmxldGFwX3RvX3NlZWtcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuYWJsZV9wbGF5YmFja19wbGF5bGlzdF9jaGFuZ2VcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuZHNjcmVlbl9lbGxpcHNpc19maXhcdTAwM2R0cnVlXHUwMDI2cGxheWVyX3VuZGVybGF5X21pbl9wbGF5ZXJfd2lkdGhcdTAwM2Q3NjguMFx1MDAyNnBsYXllcl91bmRlcmxheV92aWRlb193aWR0aF9mcmFjdGlvblx1MDAzZDAuNlx1MDAyNnBsYXllcl93ZWJfY2FuYXJ5X3N0YWdlXHUwMDNkMFx1MDAyNnBsYXlyZWFkeV9maXJzdF9wbGF5X2V4cGlyYXRpb25cdTAwM2QtMVx1MDAyNnBvbHltZXJfYmFkX2J1aWxkX2xhYmVsc1x1MDAzZHRydWVcdTAwMjZwb2x5bWVyX2xvZ19wcm9wX2NoYW5nZV9vYnNlcnZlcl9wZXJjZW50XHUwMDNkMFx1MDAyNnBvbHltZXJfdmVyaWZpeV9hcHBfc3RhdGVcdTAwM2R0cnVlXHUwMDI2cHJlc2tpcF9idXR0b25fc3R5bGVfYWRzX2JhY2tlbmRcdTAwM2Rjb3VudGRvd25fbmV4dF90b190aHVtYm5haWxcdTAwMjZxb2VfbndsX2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZxb2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2cmVjb3JkX2FwcF9jcmFzaGVkX3dlYlx1MDAzZHRydWVcdTAwMjZyZXBsYWNlX3BsYXlhYmlsaXR5X3JldHJpZXZlcl9pbl93YXRjaFx1MDAzZHRydWVcdTAwMjZzY2hlZHVsZXJfdXNlX3JhZl9ieV9kZWZhdWx0XHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19oZWFkZXJfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX2ludGVyc3RpdGlhbF9tZXNzYWdlXHUwMDI2c2VsZl9wb2RkaW5nX2hpZ2hsaWdodF9ub25fZGVmYXVsdF9idXR0b25cdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZVx1MDAyNnNlbmRfY29uZmlnX2hhc2hfdGltZXJcdTAwM2QwXHUwMDI2c2V0X2ludGVyc3RpdGlhbF9hZHZlcnRpc2Vyc19xdWVzdGlvbl90ZXh0XHUwMDNkdHJ1ZVx1MDAyNnNob3J0X3N0YXJ0X3RpbWVfcHJlZmVyX3B1Ymxpc2hfaW5fd2F0Y2hfbG9nXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19tb2RlX3RvX3BsYXllcl9hcGlcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX25vX3N0b3BfdmlkZW9fY2FsbFx1MDAzZHRydWVcdTAwMjZzaG91bGRfY2xlYXJfdmlkZW9fZGF0YV9vbl9wbGF5ZXJfY3VlZF91bnN0YXJ0ZWRcdTAwM2R0cnVlXHUwMDI2c2ltcGx5X2VtYmVkZGVkX2VuYWJsZV9ib3RndWFyZFx1MDAzZHRydWVcdTAwMjZza2lwX2lubGluZV9tdXRlZF9saWNlbnNlX3NlcnZpY2VfY2hlY2tcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbnZhbGlkX3l0Y3NpX3RpY2tzXHUwMDNkdHJ1ZVx1MDAyNnNraXBfbHNfZ2VsX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNnNraXBfc2V0dGluZ19pbmZvX2luX2NzaV9kYXRhX29iamVjdFx1MDAzZHRydWVcdTAwMjZzbG93X2NvbXByZXNzaW9uc19iZWZvcmVfYWJhbmRvbl9jb3VudFx1MDAzZDRcdTAwMjZzcGVlZG1hc3Rlcl9jYW5jZWxsYXRpb25fbW92ZW1lbnRfZHBcdTAwM2QwXHUwMDI2c3BlZWRtYXN0ZXJfcGxheWJhY2tfcmF0ZVx1MDAzZDAuMFx1MDAyNnNwZWVkbWFzdGVyX3RvdWNoX2FjdGl2YXRpb25fbXNcdTAwM2QwXHUwMDI2c3RhcnRfY2xpZW50X2djZlx1MDAzZHRydWVcdTAwMjZzdGFydF9jbGllbnRfZ2NmX2Zvcl9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2c3RhcnRfc2VuZGluZ19jb25maWdfaGFzaFx1MDAzZHRydWVcdTAwMjZzdHJlYW1pbmdfZGF0YV9lbWVyZ2VuY3lfaXRhZ19ibGFja2xpc3RcdTAwM2RbXVx1MDAyNnN1YnN0aXR1dGVfYWRfY3BuX21hY3JvX2luX3NzZGFpXHUwMDNkdHJ1ZVx1MDAyNnN1cHByZXNzX2Vycm9yXzIwNF9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNnRyYW5zcG9ydF91c2Vfc2NoZWR1bGVyXHUwMDNkdHJ1ZVx1MDAyNnR2X3BhY2ZfbG9nZ2luZ19zYW1wbGVfcmF0ZVx1MDAzZDAuMDFcdTAwMjZ0dmh0bWw1X3VucGx1Z2dlZF9wcmVsb2FkX2NhY2hlX3NpemVcdTAwM2Q1XHUwMDI2dW5jb3Zlcl9hZF9iYWRnZV9vbl9SVExfdGlueV93aW5kb3dcdTAwM2R0cnVlXHUwMDI2dW5wbHVnZ2VkX2RhaV9saXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZ1bnBsdWdnZWRfdHZodG1sNV92aWRlb19wcmVsb2FkX29uX2ZvY3VzX2RlbGF5X21zXHUwMDNkMFx1MDAyNnVwZGF0ZV9sb2dfZXZlbnRfY29uZmlnXHUwMDNkdHJ1ZVx1MDAyNnVzZV9hY2Nlc3NpYmlsaXR5X2RhdGFfb25fZGVza3RvcF9wbGF5ZXJfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9jb3JlX3NtXHUwMDNkdHJ1ZVx1MDAyNnVzZV9pbmxpbmVkX3BsYXllcl9ycGNcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19jbWxcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19pbl9tZW1vcnlfc3RvcmFnZVx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9pbml0aWFsaXphdGlvblx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zYXdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc3R3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3d0c1x1MDAzZHRydWVcdTAwMjZ1c2VfcGxheWVyX2FidXNlX2JnX2xpYnJhcnlcdTAwM2R0cnVlXHUwMDI2dXNlX3Byb2ZpbGVwYWdlX2V2ZW50X2xhYmVsX2luX2Nhcm91c2VsX3BsYXliYWNrc1x1MDAzZHRydWVcdTAwMjZ1c2VfcmVxdWVzdF90aW1lX21zX2hlYWRlclx1MDAzZHRydWVcdTAwMjZ1c2Vfc2Vzc2lvbl9iYXNlZF9zYW1wbGluZ1x1MDAzZHRydWVcdTAwMjZ1c2VfdHNfdmlzaWJpbGl0eWxvZ2dlclx1MDAzZHRydWVcdTAwMjZ2YXJpYWJsZV9idWZmZXJfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZ2ZXJpZnlfYWRzX2l0YWdfZWFybHlcdTAwM2R0cnVlXHUwMDI2dnA5X2RybV9saXZlXHUwMDNkdHJ1ZVx1MDAyNnZzc19maW5hbF9waW5nX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnZzc19waW5nc191c2luZ19uZXR3b3JrbGVzc1x1MDAzZHRydWVcdTAwMjZ2c3NfcGxheWJhY2tfdXNlX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9hcGlfdXJsXHUwMDNkdHJ1ZVx1MDAyNndlYl9hc3luY19jb250ZXh0X3Byb2Nlc3Nvcl9pbXBsXHUwMDNkc3RhbmRhbG9uZVx1MDAyNndlYl9jaW5lbWF0aWNfd2F0Y2hfc2V0dGluZ3NcdTAwM2R0cnVlXHUwMDI2d2ViX2NsaWVudF92ZXJzaW9uX292ZXJyaWRlXHUwMDNkXHUwMDI2d2ViX2RlZHVwZV92ZV9ncmFmdGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZGVwcmVjYXRlX3NlcnZpY2VfYWpheF9tYXBfZGVwZW5kZW5jeVx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2Vycm9yXzIwNFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2luc3RyZWFtX2Fkc19saW5rX2RlZmluaXRpb25fYTExeV9idWdmaXhcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV92b3pfYXVkaW9fZmVlZGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX2ZpeF9maW5lX3NjcnViYmluZ19kcmFnXHUwMDNkdHJ1ZVx1MDAyNndlYl9mb3JlZ3JvdW5kX2hlYXJ0YmVhdF9pbnRlcnZhbF9tc1x1MDAzZDI4MDAwXHUwMDI2d2ViX2ZvcndhcmRfY29tbWFuZF9vbl9wYmpcdTAwM2R0cnVlXHUwMDI2d2ViX2dlbF9kZWJvdW5jZV9tc1x1MDAzZDYwMDAwXHUwMDI2d2ViX2dlbF90aW1lb3V0X2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfaW5saW5lX3BsYXllcl9ub19wbGF5YmFja191aV9jbGlja19oYW5kbGVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9rZXlfbW9tZW50c19tYXJrZXJzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dfbWVtb3J5X3RvdGFsX2tieXRlc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nZ2luZ19tYXhfYmF0Y2hcdTAwM2QxNTBcdTAwMjZ3ZWJfbW9kZXJuX2Fkc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zX2JsX3N1cnZleVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3NjcnViYmVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlX3N0eWxlXHUwMDNkZmlsbGVkXHUwMDI2d2ViX25ld19hdXRvbmF2X2NvdW50ZG93blx1MDAzZHRydWVcdTAwMjZ3ZWJfb25lX3BsYXRmb3JtX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9vcF9zaWduYWxfdHlwZV9iYW5saXN0XHUwMDNkW11cdTAwMjZ3ZWJfcGF1c2VkX29ubHlfbWluaXBsYXllcl9zaG9ydGN1dF9leHBhbmRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfbG9nX2N0dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF92ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FkZF92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdG9fb3V0Ym91bmRfbGlua3NcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hbHdheXNfZW5hYmxlX2F1dG9fdHJhbnNsYXRpb25cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hcGlfbG9nZ2luZ19mcmFjdGlvblx1MDAzZDAuMDFcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfZW1wdHlfc3VnZ2VzdGlvbnNfZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl90b2dnbGVfYWx3YXlzX2xpc3Rlblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdXNlX3NlcnZlcl9wcm92aWRlZF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2NhcHRpb25fbGFuZ3VhZ2VfcHJlZmVyZW5jZV9zdGlja2luZXNzX2R1cmF0aW9uXHUwMDNkMzBcdTAwMjZ3ZWJfcGxheWVyX2RlY291cGxlX2F1dG9uYXZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9kaXNhYmxlX2lubGluZV9zY3J1YmJpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZWFybHlfd2FybmluZ19zbmFja2Jhclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9mZWF0dXJlZF9wcm9kdWN0X2Jhbm5lcl9vbl9kZXNrdG9wXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX2luX2g1X2FwaVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9wbGF5YmFja19jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pbm5lcnR1YmVfcGxheWxpc3RfdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaXBwX2NhbmFyeV90eXBlX2Zvcl9sb2dnaW5nXHUwMDNkXHUwMDI2d2ViX3BsYXllcl9saXZlX21vbml0b3JfZW52XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbG9nX2NsaWNrX2JlZm9yZV9nZW5lcmF0aW5nX3ZlX2NvbnZlcnNpb25fcGFyYW1zXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbW92ZV9hdXRvbmF2X3RvZ2dsZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX211c2ljX3Zpc3VhbGl6ZXJfdHJlYXRtZW50XHUwMDNkZmFrZVx1MDAyNndlYl9wbGF5ZXJfbXV0YWJsZV9ldmVudF9sYWJlbFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX25pdHJhdGVfcHJvbW9fdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX29mZmxpbmVfcGxheWxpc3RfYXV0b19yZWZyZXNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfcmVzcG9uc2VfcGxheWJhY2tfdHJhY2tpbmdfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlZWtfY2hhcHRlcnNfYnlfc2hvcnRjdXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZW50aW5lbF9pc191bmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG91bGRfaG9ub3JfaW5jbHVkZV9hc3Jfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3dfbXVzaWNfaW5fdGhpc192aWRlb19ncmFwaGljXHUwMDNkdmlkZW9fdGh1bWJuYWlsXHUwMDI2d2ViX3BsYXllcl9zbWFsbF9oYnBfc2V0dGluZ3NfbWVudVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NzX2RhaV9hZF9mZXRjaGluZ190aW1lb3V0X21zXHUwMDNkMTUwMDBcdTAwMjZ3ZWJfcGxheWVyX3NzX21lZGlhX3RpbWVfb2Zmc2V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG9waWZ5X3N1YnRpdGxlc19mb3Jfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG91Y2hfbW9kZV9pbXByb3ZlbWVudHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90cmFuc2Zlcl90aW1lb3V0X3RocmVzaG9sZF9tc1x1MDAzZDEwODAwMDAwXHUwMDI2d2ViX3BsYXllcl91bnNldF9kZWZhdWx0X2Nzbl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdXNlX25ld19hcGlfZm9yX3F1YWxpdHlfcHVsbGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl92ZV9jb252ZXJzaW9uX2ZpeGVzX2Zvcl9jaGFubmVsX2luZm9cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZV9wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wcmVmZXRjaF9wcmVsb2FkX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNndlYl9yb3VuZGVkX3RodW1ibmFpbHNcdTAwM2R0cnVlXHUwMDI2d2ViX3NldHRpbmdzX21lbnVfaWNvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X21ldGhvZFx1MDAzZDBcdTAwMjZ3ZWJfeXRfY29uZmlnX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2d2lsX2ljb25fcmVuZGVyX3doZW5faWRsZVx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfY2xlYW5fdXBfYWZ0ZXJfZW50aXR5X21pZ3JhdGlvblx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfZW5hYmxlX2Rvd25sb2FkX3N0YXR1c1x1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfcGxheWxpc3Rfb3B0aW1pemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2NsZWFyX2VtYmVkZGVkX3BsYXllclx1MDAzZHRydWVcdTAwMjZ5dGlkYl9mZXRjaF9kYXRhc3luY19pZHNfZm9yX2RhdGFfY2xlYW51cFx1MDAzZHRydWVcdTAwMjZ5dGlkYl9yZW1ha2VfZGJfcmV0cmllc1x1MDAzZDFcdTAwMjZ5dGlkYl9yZW9wZW5fZGJfcmV0cmllc1x1MDAzZDBcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0XHUwMDNkMC4wMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfc2Vzc2lvblx1MDAzZDAuMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfdHJhbnNhY3Rpb25cdTAwM2QwLjEiLCJkaXNhYmxlRnVsbHNjcmVlbiI6dHJ1ZSwiY3NwTm9uY2UiOiJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIiwiY2FuYXJ5U3RhdGUiOiJub25lIiwiZW5hYmxlQ3NpTG9nZ2luZyI6dHJ1ZSwiY3NpUGFnZVR5cGUiOiJ3YXRjaCIsImRpc2FibGVNZHhDYXN0Ijp0cnVlLCJkYXRhc3luY0lkIjoiVjIwMjE3ZmM2fHwiLCJzaG93SW5saW5lUHJldmlld1VpIjp0cnVlfSwiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9IQU5ETEVTX0NMQUlNSU5HIjp7InJvb3RFbGVtZW50SWQiOiJ5dGQtaGFuZGxlcy1jbGFpbWluZy12aWRlby1pdGVtLXJlbmRlcmVyIiwianNVcmwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvcGxheWVyX2lhcy52ZmxzZXQvZnJfRlIvYmFzZS5qcyIsImNzc1VybCI6Ii9zL3BsYXllci9iMTI4ZGRhMC93d3ctcGxheWVyLmNzcyIsImNvbnRleHRJZCI6IldFQl9QTEFZRVJfQ09OVEVYVF9DT05GSUdfSURfSEFORExFU19DTEFJTUlORyIsImV2ZW50TGFiZWwiOiJoYW5kbGVzY2xhaW1pbmciLCJjb250ZW50UmVnaW9uIjoiRlIiLCJobCI6ImZyX0ZSIiwiaG9zdExhbmd1YWdlIjoiZnIiLCJwbGF5ZXJTdHlsZSI6ImRlc2t0b3AtcG9seW1lciIsImlubmVydHViZUFwaUtleSI6IkFJemFTeUFPX0ZKMlNscVU4UTRTVEVITEdDaWx3X1k5XzExcWNXOCIsImlubmVydHViZUFwaVZlcnNpb24iOiJ2MSIsImlubmVydHViZUNvbnRleHRDbGllbnRWZXJzaW9uIjoiMi4yMDIzMDYwNy4wNi4wMCIsImRpc2FibGVSZWxhdGVkVmlkZW9zIjp0cnVlLCJkZXZpY2UiOnsiYnJhbmQiOiIiLCJtb2RlbCI6IiIsInBsYXRmb3JtIjoiREVTS1RPUCIsImludGVyZmFjZU5hbWUiOiJXRUIiLCJpbnRlcmZhY2VWZXJzaW9uIjoiMi4yMDIzMDYwNy4wNi4wMCJ9LCJzZXJpYWxpemVkRXhwZXJpbWVudElkcyI6IjIzOTgzMjk2LDI0MDA0NjQ0LDI0MDA3MjQ2LDI0MDA3NjEzLDI0MDgwNzM4LDI0MTM1MzEwLDI0MzYzMTE0LDI0MzY0Nzg5LDI0MzY1NTM0LDI0MzY2OTE3LDI0MzcyNzYxLDI0Mzc1MTAxLDI0Mzc2Nzg1LDI0NDE1ODY0LDI0NDE2MjkwLDI0NDMzNjc5LDI0NDM3NTc3LDI0NDM5MzYxLDI0NDQzMzMxLDI0NDk5NTMyLDI0NTMyODU1LDI0NTUwNDU4LDI0NTUwOTUxLDI0NTU1NTY3LDI0NTU4NjQxLDI0NTU5MzI3LDI0Njk5ODk5LDM5MzIzMDc0Iiwic2VyaWFsaXplZEV4cGVyaW1lbnRGbGFncyI6Ikg1X2FzeW5jX2xvZ2dpbmdfZGVsYXlfbXNcdTAwM2QzMDAwMC4wXHUwMDI2SDVfZW5hYmxlX2Z1bGxfcGFjZl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNkg1X3VzZV9hc3luY19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmFjdGlvbl9jb21wYW5pb25fY2VudGVyX2FsaWduX2Rlc2NyaXB0aW9uXHUwMDNkdHJ1ZVx1MDAyNmFkX3BvZF9kaXNhYmxlX2NvbXBhbmlvbl9wZXJzaXN0X2Fkc19xdWFsaXR5XHUwMDNkdHJ1ZVx1MDAyNmFkZHRvX2FqYXhfbG9nX3dhcm5pbmdfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZhbGlnbl9hZF90b192aWRlb19wbGF5ZXJfbGlmZWN5Y2xlX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X2xpdmVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2YWxsb3dfcG9sdGVyZ3VzdF9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19za2lwX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNmF0dF93ZWJfcmVjb3JkX21ldHJpY3NcdTAwM2R0cnVlXHUwMDI2YXV0b3BsYXlfdGltZVx1MDAzZDgwMDBcdTAwMjZhdXRvcGxheV90aW1lX2Zvcl9mdWxsc2NyZWVuXHUwMDNkMzAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX211c2ljX2NvbnRlbnRcdTAwM2QzMDAwXHUwMDI2Ymdfdm1fcmVpbml0X3RocmVzaG9sZFx1MDAzZDcyMDAwMDBcdTAwMjZibG9ja2VkX3BhY2thZ2VzX2Zvcl9zcHNcdTAwM2RbXVx1MDAyNmJvdGd1YXJkX2FzeW5jX3NuYXBzaG90X3RpbWVvdXRfbXNcdTAwM2QzMDAwXHUwMDI2Y2hlY2tfYWRfdWlfc3RhdHVzX2Zvcl9td2ViX3NhZmFyaVx1MDAzZHRydWVcdTAwMjZjaGVja19uYXZpZ2F0b3JfYWNjdXJhY3lfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZjbGVhcl91c2VyX3BhcnRpdGlvbmVkX2xzXHUwMDNkdHJ1ZVx1MDAyNmNsaWVudF9yZXNwZWN0X2F1dG9wbGF5X3N3aXRjaF9idXR0b25fcmVuZGVyZXJcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3NfZ2VsXHUwMDNkdHJ1ZVx1MDAyNmNvbXByZXNzaW9uX2Rpc2FibGVfcG9pbnRcdTAwM2QxMFx1MDAyNmNvbXByZXNzaW9uX3BlcmZvcm1hbmNlX3RocmVzaG9sZFx1MDAzZDI1MFx1MDAyNmNzaV9vbl9nZWxcdTAwM2R0cnVlXHUwMDI2ZGFzaF9tYW5pZmVzdF92ZXJzaW9uXHUwMDNkNVx1MDAyNmRlYnVnX2JhbmRhaWRfaG9zdG5hbWVcdTAwM2RcdTAwMjZkZWJ1Z19zaGVybG9nX3VzZXJuYW1lXHUwMDNkXHUwMDI2ZGVsYXlfYWRzX2d2aV9jYWxsX29uX2J1bGxlaXRfbGl2aW5nX3Jvb21fbXNcdTAwM2QwXHUwMDI2ZGVwcmVjYXRlX2NzaV9oYXNfaW5mb1x1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfcGFpcl9zZXJ2bGV0X2VuYWJsZWRcdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19jaGlsZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX3BhcmVudFx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX2ltYWdlX2N0YV9ub19iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfbG9nX2ltZ19jbGlja19sb2NhdGlvblx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX3NwYXJrbGVzX2xpZ2h0X2N0YV9idXR0b25cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9jaGFubmVsX2lkX2NoZWNrX2Zvcl9zdXNwZW5kZWRfY2hhbm5lbHNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9jaGlsZF9ub2RlX2F1dG9fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9kZWZlcl9hZG1vZHVsZV9vbl9hZHZlcnRpc2VyX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfZmVhdHVyZXNfZm9yX3N1cGV4XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbGVnYWN5X2Rlc2t0b3BfcmVtb3RlX3F1ZXVlXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbWR4X2Nvbm5lY3Rpb25faW5fbWR4X21vZHVsZV9mb3JfbXVzaWNfd2ViXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbmV3X3BhdXNlX3N0YXRlM1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3BhY2ZfbG9nZ2luZ19mb3JfbWVtb3J5X2xpbWl0ZWRfdHZcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9yb3VuZGluZ19hZF9ub3RpZnlcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zaW1wbGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfc3NkYWlfb25fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGFiYmluZ19iZWZvcmVfZmx5b3V0X2FkX2VsZW1lbnRzX2FwcGVhclx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3RodW1ibmFpbF9wcmVsb2FkaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc19kaXNhYmxlX3Byb2dyZXNzX2Jhcl9jb250ZXh0X21lbnVfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2VuYWJsZV9hbGxvd193YXRjaF9hZ2Fpbl9lbmRzY3JlZW5fZm9yX2VsaWdpYmxlX3Nob3J0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfdmVfY29udmVyc2lvbl9wYXJhbV9yZW5hbWluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9hdXRvcGxheV9ub3Rfc3VwcG9ydGVkX2xvZ2dpbmdfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2N1ZV92aWRlb191bnBsYXlhYmxlX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9ob3VzZV9icmFuZF9hbmRfeXRfY29leGlzdGVuY2VcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9hZF9wbGF5ZXJfZnJvbV9wYWdlX3Nob3dcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nX3NwbGF5X2FzX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvZ2dpbmdfZXZlbnRfaGFuZGxlcnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX21vYmlsZV9kdHRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX25ld19jb250ZXh0X21lbnVfdHJpZ2dlcmluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wYXVzZV9vdmVybGF5X3duX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZW1fZG9tYWluX2ZpeF9mb3JfYWRfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGZwX3VuYnJhbmRlZF9lbF9kZXByZWNhdGlvblx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9yY2F0X2FsbG93bGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9yZXBsYWNlX3VubG9hZF93X3BhZ2VoaWRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3NjcmlwdGVkX3BsYXliYWNrX2Jsb2NrZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfdmVfY29udmVyc2lvbl9sb2dnaW5nX3RyYWNraW5nX25vX2FsbG93X2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9oaWRlX3VuZmlsbGVkX21vcmVfdmlkZW9zX3N1Z2dlc3Rpb25zXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfbGl0ZV9tb2RlXHUwMDNkMVx1MDAyNmVtYmVkc193ZWJfbndsX2Rpc2FibGVfbm9jb29raWVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zaG9wcGluZ19vdmVybGF5X25vX3dhaXRfZm9yX3BhaWRfY29udGVudF9vdmVybGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfc3ludGhfY2hfaGVhZGVyc19iYW5uZWRfdXJsc19yZWdleFx1MDAzZFx1MDAyNmVuYWJsZV9hYl9ycF9pbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FkX2Nwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9hcHBfcHJvbW9fZW5kY2FwX2VtbF9vbl90YWJsZXRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Nhc3RfZm9yX3dlYl91bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Nhc3Rfb25fbXVzaWNfd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jbGllbnRfcGFnZV9pZF9oZWFkZXJfZm9yX2ZpcnN0X3BhcnR5X3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jbGllbnRfc2xpX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Rpc2NyZXRlX2xpdmVfcHJlY2lzZV9lbWJhcmdvc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkX3dlYl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkX3dlYl9jbGllbnRfY2hlY2tcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkc19pY29uX3dlYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXZpY3Rpb25fcHJvdGVjdGlvbl9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZ2VsX2xvZ19jb21tYW5kc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfaDVfaW5zdHJlYW1fd2F0Y2hfbmV4dF9wYXJhbXNfb2FybGliXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV92aWRlb19hZHNfb2FybGliXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oYW5kbGVzX2FjY291bnRfbWVudV9zd2l0Y2hlclx1MDAzZHRydWVcdTAwMjZlbmFibGVfa2FidWtpX2NvbW1lbnRzX29uX3Nob3J0c1x1MDAzZGRpc2FibGVkXHUwMDI2ZW5hYmxlX2xpdmVfcHJlbWllcmVfd2ViX3BsYXllcl9pbmRpY2F0b3JcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2xyX2hvbWVfaW5mZWVkX2Fkc19pbmxpbmVfcGxheWJhY2tfcHJvZ3Jlc3NfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX21peGVkX2RpcmVjdGlvbl9mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbXdlYl9lbmRjYXBfY2xpY2thYmxlX2ljb25fZGVzY3JpcHRpb25cdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX213ZWJfbGl2ZXN0cmVhbV91aV91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX25ld19wYWlkX3Byb2R1Y3RfcGxhY2VtZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Nsb3RfYXNkZV9wbGF5ZXJfYnl0ZV9oNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2X2Zvcl9wYWdlX3RvcF9mb3JtYXRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeXNmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFzc19zZGNfZ2V0X2FjY291bnRzX2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BsX3JfY1x1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9maXhfb25fdHZodG1sNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9pbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zZXJ2ZXJfc3RpdGNoZWRfZGFpXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zaG9ydHNfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwX2FkX2d1aWRhbmNlX3Byb21wdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2tpcHBhYmxlX2Fkc19mb3JfdW5wbHVnZ2VkX2FkX3BvZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfdGVjdG9uaWNfYWRfdXhfZm9yX2hhbGZ0aW1lXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90aGlyZF9wYXJ0eV9pbmZvXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90b3Bzb2lsX3d0YV9mb3JfaGFsZnRpbWVfbGl2ZV9pbmZyYVx1MDAzZHRydWVcdTAwMjZlbmFibGVfd2ViX21lZGlhX3Nlc3Npb25fbWV0YWRhdGFfZml4XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfc2NoZWR1bGVyX3NpZ25hbHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3duX2luZm9jYXJkc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfeXRfYXRhX2lmcmFtZV9hdXRodXNlclx1MDAzZHRydWVcdTAwMjZlcnJvcl9tZXNzYWdlX2Zvcl9nc3VpdGVfbmV0d29ya19yZXN0cmljdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZXhwb3J0X25ldHdvcmtsZXNzX29wdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZXh0ZXJuYWxfZnVsbHNjcmVlbl93aXRoX2VkdVx1MDAzZHRydWVcdTAwMjZmYXN0X2F1dG9uYXZfaW5fYmFja2dyb3VuZFx1MDAzZHRydWVcdTAwMjZmZXRjaF9hdHRfaW5kZXBlbmRlbnRseVx1MDAzZHRydWVcdTAwMjZmaWxsX3NpbmdsZV92aWRlb193aXRoX25vdGlmeV90b19sYXNyXHUwMDNkdHJ1ZVx1MDAyNmZpbHRlcl92cDlfZm9yX2NzZGFpXHUwMDNkdHJ1ZVx1MDAyNmZpeF9hZHNfdHJhY2tpbmdfZm9yX3N3Zl9jb25maWdfZGVwcmVjYXRpb25fbXdlYlx1MDAzZHRydWVcdTAwMjZnY2ZfY29uZmlnX3N0b3JlX2VuYWJsZWRcdTAwM2R0cnVlXHUwMDI2Z2VsX3F1ZXVlX3RpbWVvdXRfbWF4X21zXHUwMDNkMzAwMDAwXHUwMDI2Z3BhX3NwYXJrbGVzX3Rlbl9wZXJjZW50X2xheWVyXHUwMDNkdHJ1ZVx1MDAyNmd2aV9jaGFubmVsX2NsaWVudF9zY3JlZW5cdTAwM2R0cnVlXHUwMDI2aDVfY29tcGFuaW9uX2VuYWJsZV9hZGNwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmg1X2VuYWJsZV9nZW5lcmljX2Vycm9yX2xvZ2dpbmdfZXZlbnRcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX3VuaWZpZWRfY3NpX3ByZXJvbGxcdTAwM2R0cnVlXHUwMDI2aDVfaW5wbGF5ZXJfZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfcmVzZXRfY2FjaGVfYW5kX2ZpbHRlcl9iZWZvcmVfdXBkYXRlX21hc3RoZWFkXHUwMDNkdHJ1ZVx1MDAyNmhlYXRzZWVrZXJfZGVjb3JhdGlvbl90aHJlc2hvbGRcdTAwM2QwLjBcdTAwMjZoZnJfZHJvcHBlZF9mcmFtZXJhdGVfZmFsbGJhY2tfdGhyZXNob2xkXHUwMDNkMFx1MDAyNmhpZGVfZW5kcG9pbnRfb3ZlcmZsb3dfb25feXRkX2Rpc3BsYXlfYWRfcmVuZGVyZXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWRfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZodG1sNV9hZHNfcHJlcm9sbF9sb2NrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QxNTAwMFx1MDAyNmh0bWw1X2FsbG93X2Rpc2NvbnRpZ3VvdXNfc2xpY2VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2FsbG93X3ZpZGVvX2tleWZyYW1lX3dpdGhvdXRfYXVkaW9cdTAwM2R0cnVlXHUwMDI2aHRtbDVfYXR0YWNoX251bV9yYW5kb21fYnl0ZXNfdG9fYmFuZGFpZFx1MDAzZDBcdTAwMjZodG1sNV9hdHRhY2hfcG9fdG9rZW5fdG9fYmFuZGFpZFx1MDAzZHRydWVcdTAwMjZodG1sNV9hdXRvbmF2X2NhcF9pZGxlX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfYXV0b25hdl9xdWFsaXR5X2NhcFx1MDAzZDcyMFx1MDAyNmh0bWw1X2F1dG9wbGF5X2RlZmF1bHRfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfYmxvY2tfcGlwX3NhZmFyaV9kZWxheVx1MDAzZDBcdTAwMjZodG1sNV9ibWZmX25ld19mb3VyY2NfY2hlY2tcdTAwM2R0cnVlXHUwMDI2aHRtbDVfY29iYWx0X2RlZmF1bHRfYnVmZmVyX3NpemVfaW5fYnl0ZXNcdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X21heF9zaXplX2Zvcl9pbW1lZF9qb2JcdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X21pbl9wcm9jZXNzb3JfY250X3RvX29mZmxvYWRfYWxnb1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfb3ZlcnJpZGVfcXVpY1x1MDAzZDBcdTAwMjZodG1sNV9jb25zdW1lX21lZGlhX2J5dGVzX3NsaWNlX2luZm9zXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlX2R1cGVfY29udGVudF92aWRlb19sb2Fkc19pbl9saWZlY3ljbGVfYXBpXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlYnVnX2RhdGFfbG9nX3Byb2JhYmlsaXR5XHUwMDNkMC4xXHUwMDI2aHRtbDVfZGVjb2RlX3RvX3RleHR1cmVfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlZmF1bHRfYWRfZ2Fpblx1MDAzZDAuNVx1MDAyNmh0bWw1X2RlZmF1bHRfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfYWRfbW9kdWxlX21zXHUwMDNkMFx1MDAyNmh0bWw1X2RlZmVyX2ZldGNoX2F0dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9kZWZlcl9tb2R1bGVzX2RlbGF5X3RpbWVfbWlsbGlzXHUwMDNkMFx1MDAyNmh0bWw1X2RlbGF5ZWRfcmV0cnlfY291bnRcdTAwM2QxXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9kZWxheV9tc1x1MDAzZDUwMDBcdTAwMjZodG1sNV9kZXByZWNhdGVfdmlkZW9fdGFnX3Bvb2xcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVza3RvcF92cjE4MF9hbGxvd19wYW5uaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RmX2Rvd25ncmFkZV90aHJlc2hcdTAwM2QwLjJcdTAwMjZodG1sNV9kaXNhYmxlX2NzaV9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNhYmxlX21vdmVfcHNzaF90b19tb292XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbm9uX2NvbnRpZ3VvdXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzcGxheWVkX2ZyYW1lX3JhdGVfZG93bmdyYWRlX3RocmVzaG9sZFx1MDAzZDQ1XHUwMDI2aHRtbDVfZHJtX2NoZWNrX2FsbF9rZXlfZXJyb3Jfc3RhdGVzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RybV9jcGlfbGljZW5zZV9rZXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2FjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWRzX2NsaWVudF9tb25pdG9yaW5nX2xvZ190dlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2FwdGlvbl9jaGFuZ2VzX2Zvcl9tb3NhaWNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NsaWVudF9oaW50c19vdmVycmlkZVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY29tcG9zaXRlX2VtYmFyZ29cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2VhYzNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2VtYmVkZGVkX3BsYXllcl92aXNpYmlsaXR5X3NpZ25hbHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX25vbl9ub3RpZnlfY29tcG9zaXRlX3ZvZF9sc2FyX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3NpbmdsZV92aWRlb192b2RfaXZhcl9vbl9wYWNmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV90dm9zX2Rhc2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZW5jcnlwdGVkX3ZwOVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfd2lkZXZpbmVfZm9yX2FsY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfd2lkZXZpbmVfZm9yX2Zhc3RfbGluZWFyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuY291cmFnZV9hcnJheV9jb2FsZXNjaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2dhcGxlc3NfZW5kZWRfdHJhbnNpdGlvbl9idWZmZXJfbXNcdTAwM2QyMDBcdTAwMjZodG1sNV9nZW5lcmF0ZV9zZXNzaW9uX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2dsX2Zwc190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aHRtbDVfaGRjcF9wcm9iaW5nX3N0cmVhbV91cmxcdTAwM2RcdTAwMjZodG1sNV9oZnJfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfaGlnaF9yZXNfbG9nZ2luZ19wZXJjZW50XHUwMDNkMS4wXHUwMDI2aHRtbDVfaWRsZV9yYXRlX2xpbWl0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9mYWlycGxheVx1MDAzZHRydWVcdTAwMjZodG1sNV9pbm5lcnR1YmVfaGVhcnRiZWF0c19mb3JfcGxheXJlYWR5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl93aWRldmluZVx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3M0X3NlZWtfYWJvdmVfemVyb1x1MDAzZHRydWVcdTAwMjZodG1sNV9pb3M3X2ZvcmNlX3BsYXlfb25fc3RhbGxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW9zX2ZvcmNlX3NlZWtfdG9femVyb19vbl9zdG9wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2p1bWJvX21vYmlsZV9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRcdTAwM2QzLjBcdTAwMjZodG1sNV9qdW1ib191bGxfbm9uc3RyZWFtaW5nX21mZmFfbXNcdTAwM2Q0MDAwXHUwMDI2aHRtbDVfanVtYm9fdWxsX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDEuM1x1MDAyNmh0bWw1X2xpY2Vuc2VfY29uc3RyYWludF9kZWxheVx1MDAzZDUwMDBcdTAwMjZodG1sNV9saXZlX2Ficl9oZWFkX21pc3NfZnJhY3Rpb25cdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX2Ficl9yZXByZWRpY3RfZnJhY3Rpb25cdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX2J5dGVyYXRlX2ZhY3Rvcl9mb3JfcmVhZGFoZWFkXHUwMDNkMS4zXHUwMDI2aHRtbDVfbGl2ZV9sb3dfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbGl2ZV9ub3JtYWxfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9saXZlX3VsdHJhX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9sb2dfYXVkaW9fYWJyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19leHBlcmltZW50X2lkX2Zyb21fcGxheWVyX3Jlc3BvbnNlX3RvX2N0bXBcdTAwM2RcdTAwMjZodG1sNV9sb2dfZmlyc3Rfc3NkYWlfcmVxdWVzdHNfa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfcmVidWZmZXJfZXZlbnRzXHUwMDNkNVx1MDAyNmh0bWw1X2xvZ19zc2RhaV9mYWxsYmFja19hZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX3RyaWdnZXJfZXZlbnRzX3dpdGhfZGVidWdfZGF0YVx1MDAzZHRydWVcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl9uZXdfZWxlbV9zaG9ydHNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl90aHJlc2hvbGRfbXNcdTAwM2QzMDAwMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc19zZWdfZHJpZnRfbGltaXRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9tYW5pZmVzdGxlc3NfdW5wbHVnZ2VkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc192cDlfb3RmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21heF9kcmlmdF9wZXJfdHJhY2tfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X21heF9oZWFkbV9mb3Jfc3RyZWFtaW5nX3hoclx1MDAzZDBcdTAwMjZodG1sNV9tYXhfbGl2ZV9kdnJfd2luZG93X3BsdXNfbWFyZ2luX3NlY3NcdTAwM2Q0NjgwMC4wXHUwMDI2aHRtbDVfbWF4X3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9tYXhfcmVkaXJlY3RfcmVzcG9uc2VfbGVuZ3RoXHUwMDNkODE5Mlx1MDAyNmh0bWw1X21heF9zZWxlY3RhYmxlX3F1YWxpdHlfb3JkaW5hbFx1MDAzZDBcdTAwMjZodG1sNV9tYXhfc291cmNlX2J1ZmZlcl9hcHBlbmRfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9tYXhpbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWVkaWFfZnVsbHNjcmVlblx1MDAzZHRydWVcdTAwMjZodG1sNV9tZmxfZXh0ZW5kX21heF9yZXF1ZXN0X3RpbWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfY2FwX3NlY3NcdTAwM2Q2MFx1MDAyNmh0bWw1X21pbl9yZWFkYmVoaW5kX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX2FkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5fc3RhcnR1cF9idWZmZXJlZF9tZWRpYV9kdXJhdGlvbl9zZWNzXHUwMDNkMS4yXHUwMDI2aHRtbDVfbWluaW11bV9yZWFkYWhlYWRfc2Vjb25kc1x1MDAzZDAuMFx1MDAyNmh0bWw1X25vX3BsYWNlaG9sZGVyX3JvbGxiYWNrc1x1MDAzZHRydWVcdTAwMjZodG1sNV9ub25fbmV0d29ya19yZWJ1ZmZlcl9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZodG1sNV9ub25fb25lc2llX2F0dGFjaF9wb190b2tlblx1MDAzZHRydWVcdTAwMjZodG1sNV9ub3RfcmVnaXN0ZXJfZGlzcG9zYWJsZXNfd2hlbl9jb3JlX2xpc3RlbnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb2ZmbGluZV9mYWlsdXJlX3JldHJ5X2xpbWl0XHUwMDNkMlx1MDAyNmh0bWw1X29uZXNpZV9kZWZlcl9jb250ZW50X2xvYWRlcl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfaG9zdF9yYWNpbmdfY2FwX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9pZ25vcmVfaW5uZXJ0dWJlX2FwaV9rZXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX2xpdmVfdHRsX3NlY3NcdTAwM2Q4XHUwMDI2aHRtbDVfb25lc2llX25vbnplcm9fcGxheWJhY2tfc3RhcnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX25vdGlmeV9jdWVwb2ludF9tYW5hZ2VyX29uX2NvbXBsZXRpb25cdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1fY29vbGRvd25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1faW50ZXJ2YWxfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1fbWF4X2xhY3RfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlZGlyZWN0b3JfdGltZW91dFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9yZXF1ZXN0X3RpbWVvdXRfbXNcdTAwM2QxMDAwXHUwMDI2aHRtbDVfb25lc2llX3N0aWNreV9zZXJ2ZXJfc2lkZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wYXVzZV9vbl9ub25mb3JlZ3JvdW5kX3BsYXRmb3JtX2Vycm9yc1x1MDAzZHRydWVcdTAwMjZodG1sNV9wZWFrX3NoYXZlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZfY2FwX292ZXJyaWRlX3N0aWNreVx1MDAzZHRydWVcdTAwMjZodG1sNV9wZXJmb3JtYW5jZV9jYXBfZmxvb3JcdTAwM2QzNjBcdTAwMjZodG1sNV9wZXJmb3JtYW5jZV9pbXBhY3RfcHJvZmlsaW5nX3RpbWVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X3BlcnNlcnZlX2F2MV9wZXJmX2NhcFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF0Zm9ybV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfcGxheWVyX2F1dG9uYXZfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfZHluYW1pY19ib3R0b21fZ3JhZGllbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxheWVyX21pbl9idWlsZF9jbFx1MDAzZC0xXHUwMDI2aHRtbDVfcGxheWVyX3ByZWxvYWRfYWRfZml4XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Bvc3RfaW50ZXJydXB0X3JlYWRhaGVhZFx1MDAzZDIwXHUwMDI2aHRtbDVfcHJlZmVyX3NlcnZlcl9id2UzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ByZWxvYWRfd2FpdF90aW1lX3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9wcm9iZV9wcmltYXJ5X2RlbGF5X2Jhc2VfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcHJvY2Vzc19hbGxfZW5jcnlwdGVkX2V2ZW50c1x1MDAzZHRydWVcdTAwMjZodG1sNV9xb2VfbGhfbWF4X3JlcG9ydF9jb3VudFx1MDAzZDBcdTAwMjZodG1sNV9xb2VfbGhfbWluX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X3F1ZXJ5X3N3X3NlY3VyZV9jcnlwdG9fZm9yX2FuZHJvaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmFuZG9tX3BsYXliYWNrX2NhcFx1MDAzZDBcdTAwMjZodG1sNV9yZWNvZ25pemVfcHJlZGljdF9zdGFydF9jdWVfcG9pbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX2NvbW1hbmRfdHJpZ2dlcmVkX2NvbXBhbmlvbnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX25vdF9zZXJ2YWJsZV9jaGVja19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbmFtZV9hcGJzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9mYXRhbF9kcm1fcmVzdHJpY3RlZF9lcnJvcl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9zbG93X2Fkc19hc19lcnJvclx1MDAzZHRydWVcdTAwMjZodG1sNV9yZXF1ZXN0X29ubHlfaGRyX29yX3Nkcl9rZXlzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfc2l6aW5nX211bHRpcGxpZXJcdTAwM2QwLjhcdTAwMjZodG1sNV9yZXNldF9tZWRpYV9zdHJlYW1fb25fdW5yZXN1bWFibGVfc2xpY2VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Jlc291cmNlX2JhZF9zdGF0dXNfZGVsYXlfc2NhbGluZ1x1MDAzZDEuNVx1MDAyNmh0bWw1X3Jlc3RyaWN0X3N0cmVhbWluZ194aHJfb25fc3FsZXNzX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NhZmFyaV9kZXNrdG9wX2VtZV9taW5fdmVyc2lvblx1MDAzZDBcdTAwMjZodG1sNV9zYW1zdW5nX2thbnRfbGltaXRfbWF4X2JpdHJhdGVcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19qaWdnbGVfY210X2RlbGF5X21zXHUwMDNkODAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fZGVsYXlfbXNcdTAwM2QxMjAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2J1ZmZlcl9yYW5nZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c192cnNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9jZmxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX3NldF9jbXRfZGVsYXlfbXNcdTAwM2QyMDAwXHUwMDI2aHRtbDVfc2Vla190aW1lb3V0X2RlbGF5X21zXHUwMDNkMjAwMDBcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2RlY29yYXRlZF91cmxfcmV0cnlfbGltaXRcdTAwM2Q1XHUwMDI2aHRtbDVfc2VydmVyX3N0aXRjaGVkX2RhaV9ncm91cFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZXNzaW9uX3BvX3Rva2VuX2ludGVydmFsX3RpbWVfbXNcdTAwM2Q5MDAwMDBcdTAwMjZodG1sNV9za2lwX29vYl9zdGFydF9zZWNvbmRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NraXBfc2xvd19hZF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfc2tpcF9zdWJfcXVhbnR1bV9kaXNjb250aW51aXR5X3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X25vX21lZGlhX3NvdXJjZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NzZGFpX2FkZmV0Y2hfZHluYW1pY190aW1lb3V0X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X3NzZGFpX2VuYWJsZV9uZXdfc2Vla19sb2dpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9zdGF0ZWZ1bF9hdWRpb19taW5fYWRqdXN0bWVudF92YWx1ZVx1MDAzZDBcdTAwMjZodG1sNV9zdGF0aWNfYWJyX3Jlc29sdXRpb25fc2hlbGZcdTAwM2QwXHUwMDI2aHRtbDVfc3RvcmVfeGhyX2hlYWRlcnNfcmVhZGFibGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbG9hZF9zcGVlZF9jaGVja19pbnRlcnZhbFx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjI1XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc19vbl90aW1lb3V0XHUwMDNkMC4xXHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2xvYWRfc3BlZWRcdTAwM2QxLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9zZWVrX2xhdGVuY3lfZnVkZ2VcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRfYnVmZmVyX2hlYWx0aF9zZWNzXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGltZW91dF9zZWNzXHUwMDNkMi4wXHUwMDI2aHRtbDVfdWdjX2xpdmVfYXVkaW9fNTFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdWdjX3ZvZF9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91bnJlcG9ydGVkX3NlZWtfcmVzZWVrX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3VucmVzdHJpY3RlZF9sYXllcl9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QwLjBcdTAwMjZodG1sNV91cmxfcGFkZGluZ19sZW5ndGhcdTAwM2QwXHUwMDI2aHRtbDVfdXJsX3NpZ25hdHVyZV9leHBpcnlfdGltZV9ob3Vyc1x1MDAzZDBcdTAwMjZodG1sNV91c2VfcG9zdF9mb3JfbWVkaWFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdXNlX3VtcFx1MDAzZHRydWVcdTAwMjZodG1sNV92aWRlb190YmRfbWluX2tiXHUwMDNkMFx1MDAyNmh0bWw1X3ZpZXdwb3J0X3VuZGVyc2VuZF9tYXhpbXVtXHUwMDNkMC4wXHUwMDI2aHRtbDVfdm9sdW1lX3NsaWRlcl90b29sdGlwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYl9lbmFibGVfaGFsZnRpbWVfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZodG1sNV93ZWJwb19pZGxlX3ByaW9yaXR5X2pvYlx1MDAzZHRydWVcdTAwMjZodG1sNV93b2ZmbGVfcmVzdW1lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvcmthcm91bmRfZGVsYXlfdHJpZ2dlclx1MDAzZHRydWVcdTAwMjZodG1sNV95dHZscl9lbmFibGVfc2luZ2xlX3NlbGVjdF9zdXJ2ZXlcdTAwM2R0cnVlXHUwMDI2aWdub3JlX292ZXJsYXBwaW5nX2N1ZV9wb2ludHNfb25fZW5kZW1pY19saXZlX2h0bWw1XHUwMDNkdHJ1ZVx1MDAyNmlsX3VzZV92aWV3X21vZGVsX2xvZ2dpbmdfY29udGV4dFx1MDAzZHRydWVcdTAwMjZpbml0aWFsX2dlbF9iYXRjaF90aW1lb3V0XHUwMDNkMjAwMFx1MDAyNmluamVjdGVkX2xpY2Vuc2VfaGFuZGxlcl9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNmluamVjdGVkX2xpY2Vuc2VfaGFuZGxlcl9saWNlbnNlX3N0YXR1c1x1MDAzZDBcdTAwMjZpdGRybV9pbmplY3RlZF9saWNlbnNlX3NlcnZpY2VfZXJyb3JfY29kZVx1MDAzZDBcdTAwMjZpdGRybV93aWRldmluZV9oYXJkZW5lZF92bXBfbW9kZVx1MDAzZGxvZ1x1MDAyNmpzb25fY29uZGVuc2VkX3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9jb21tYW5kX2hhbmRsZXJfY29tbWFuZF9iYW5saXN0XHUwMDNkW11cdTAwMjZrZXZsYXJfZHJvcGRvd25fZml4XHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9nZWxfZXJyb3Jfcm91dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllclx1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllcl9leHBhbmRfdG9wXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX3BsYXlfcGF1c2Vfb25fc2NyaW1cdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3BsYXliYWNrX2Fzc29jaWF0ZWRfcXVldWVcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3F1ZXVlX3VzZV91cGRhdGVfYXBpXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zaW1wX3Nob3J0c19yZXNldF9zY3JvbGxcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NtYXJ0X2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzX3NldHRpbmdcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3ZpbWlvX3VzZV9zaGFyZWRfbW9uaXRvclx1MDAzZHRydWVcdTAwMjZsaXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZsaXZlX2ZyZXNjYV92Mlx1MDAzZHRydWVcdTAwMjZsb2dfZXJyb3JzX3Rocm91Z2hfbndsX29uX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19nZWxfY29tcHJlc3Npb25fbGF0ZW5jeVx1MDAzZHRydWVcdTAwMjZsb2dfaGVhcnRiZWF0X3dpdGhfbGlmZWN5Y2xlc1x1MDAzZHRydWVcdTAwMjZsb2dfd2ViX2VuZHBvaW50X3RvX2xheWVyXHUwMDNkdHJ1ZVx1MDAyNmxvZ193aW5kb3dfb25lcnJvcl9mcmFjdGlvblx1MDAzZDAuMVx1MDAyNm1hbmlmZXN0bGVzc19wb3N0X2xpdmVcdTAwM2R0cnVlXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZV91ZnBoXHUwMDNkdHJ1ZVx1MDAyNm1heF9ib2R5X3NpemVfdG9fY29tcHJlc3NcdTAwM2Q1MDAwMDBcdTAwMjZtYXhfcHJlZmV0Y2hfd2luZG93X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb25cdTAwM2QwXHUwMDI2bWF4X3Jlc29sdXRpb25fZm9yX3doaXRlX25vaXNlXHUwMDNkMzYwXHUwMDI2bWR4X2VuYWJsZV9wcml2YWN5X2Rpc2Nsb3N1cmVfdWlcdTAwM2R0cnVlXHUwMDI2bWR4X2xvYWRfY2FzdF9hcGlfYm9vdHN0cmFwX3NjcmlwdFx1MDAzZHRydWVcdTAwMjZtaWdyYXRlX2V2ZW50c190b190c1x1MDAzZHRydWVcdTAwMjZtaW5fcHJlZmV0Y2hfb2Zmc2V0X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb25cdTAwM2QxMFx1MDAyNm11c2ljX2VuYWJsZV9zaGFyZWRfYXVkaW9fdGllcl9sb2dpY1x1MDAzZHRydWVcdTAwMjZtd2ViX2MzX2VuZHNjcmVlblx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9jdXN0b21fY29udHJvbF9zaGFyZWRcdTAwM2R0cnVlXHUwMDI2bXdlYl9lbmFibGVfc2tpcHBhYmxlc19vbl9qaW9fcGhvbmVcdTAwM2R0cnVlXHUwMDI2bXdlYl9tdXRlZF9hdXRvcGxheV9hbmltYXRpb25cdTAwM2RzaHJpbmtcdTAwMjZtd2ViX25hdGl2ZV9jb250cm9sX2luX2ZhdXhfZnVsbHNjcmVlbl9zaGFyZWRcdTAwM2R0cnVlXHUwMDI2bmV0d29ya19wb2xsaW5nX2ludGVydmFsXHUwMDNkMzAwMDBcdTAwMjZuZXR3b3JrbGVzc19nZWxcdTAwM2R0cnVlXHUwMDI2bmV0d29ya2xlc3NfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZuZXdfY29kZWNzX3N0cmluZ19hcGlfdXNlc19sZWdhY3lfc3R5bGVcdTAwM2R0cnVlXHUwMDI2bndsX3NlbmRfZmFzdF9vbl91bmxvYWRcdTAwM2R0cnVlXHUwMDI2bndsX3NlbmRfZnJvbV9tZW1vcnlfd2hlbl9vbmxpbmVcdTAwM2R0cnVlXHUwMDI2b2ZmbGluZV9lcnJvcl9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZwYWNmX2xvZ2dpbmdfZGVsYXlfbWlsbGlzZWNvbmRzX3Rocm91Z2hfeWJmZV90dlx1MDAzZDMwMDAwXHUwMDI2cGFnZWlkX2FzX2hlYWRlcl93ZWJcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Fkc19zZXRfYWRmb3JtYXRfb25fY2xpZW50XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9hbGxvd19hdXRvbmF2X2FmdGVyX3BsYXlsaXN0XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9ib290c3RyYXBfbWV0aG9kXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9kZWZlcl9jYXB0aW9uX2Rpc3BsYXlcdTAwM2QxMDAwXHUwMDI2cGxheWVyX2Rlc3Ryb3lfb2xkX3ZlcnNpb25cdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RvdWJsZXRhcF90b19zZWVrXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9lbmFibGVfcGxheWJhY2tfcGxheWxpc3RfY2hhbmdlXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9lbmRzY3JlZW5fZWxsaXBzaXNfZml4XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl91bmRlcmxheV9taW5fcGxheWVyX3dpZHRoXHUwMDNkNzY4LjBcdTAwMjZwbGF5ZXJfdW5kZXJsYXlfdmlkZW9fd2lkdGhfZnJhY3Rpb25cdTAwM2QwLjZcdTAwMjZwbGF5ZXJfd2ViX2NhbmFyeV9zdGFnZVx1MDAzZDBcdTAwMjZwbGF5cmVhZHlfZmlyc3RfcGxheV9leHBpcmF0aW9uXHUwMDNkLTFcdTAwMjZwb2x5bWVyX2JhZF9idWlsZF9sYWJlbHNcdTAwM2R0cnVlXHUwMDI2cG9seW1lcl9sb2dfcHJvcF9jaGFuZ2Vfb2JzZXJ2ZXJfcGVyY2VudFx1MDAzZDBcdTAwMjZwb2x5bWVyX3ZlcmlmaXlfYXBwX3N0YXRlXHUwMDNkdHJ1ZVx1MDAyNnByZXNraXBfYnV0dG9uX3N0eWxlX2Fkc19iYWNrZW5kXHUwMDNkY291bnRkb3duX25leHRfdG9fdGh1bWJuYWlsXHUwMDI2cW9lX253bF9kb3dubG9hZHNcdTAwM2R0cnVlXHUwMDI2cW9lX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnJlY29yZF9hcHBfY3Jhc2hlZF93ZWJcdTAwM2R0cnVlXHUwMDI2cmVwbGFjZV9wbGF5YWJpbGl0eV9yZXRyaWV2ZXJfaW5fd2F0Y2hcdTAwM2R0cnVlXHUwMDI2c2NoZWR1bGVyX3VzZV9yYWZfYnlfZGVmYXVsdFx1MDAzZHRydWVcdTAwMjZzZWxmX3BvZGRpbmdfaGVhZGVyX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19pbnRlcnN0aXRpYWxfbWVzc2FnZVx1MDAyNnNlbGZfcG9kZGluZ19oaWdobGlnaHRfbm9uX2RlZmF1bHRfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZV9zdHJpbmdfdGVtcGxhdGVcdTAwM2RzZWxmX3BvZGRpbmdfbWlkcm9sbF9jaG9pY2VcdTAwMjZzZW5kX2NvbmZpZ19oYXNoX3RpbWVyXHUwMDNkMFx1MDAyNnNldF9pbnRlcnN0aXRpYWxfYWR2ZXJ0aXNlcnNfcXVlc3Rpb25fdGV4dFx1MDAzZHRydWVcdTAwMjZzaG9ydF9zdGFydF90aW1lX3ByZWZlcl9wdWJsaXNoX2luX3dhdGNoX2xvZ1x1MDAzZHRydWVcdTAwMjZzaG9ydHNfbW9kZV90b19wbGF5ZXJfYXBpXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19ub19zdG9wX3ZpZGVvX2NhbGxcdTAwM2R0cnVlXHUwMDI2c2hvdWxkX2NsZWFyX3ZpZGVvX2RhdGFfb25fcGxheWVyX2N1ZWRfdW5zdGFydGVkXHUwMDNkdHJ1ZVx1MDAyNnNpbXBseV9lbWJlZGRlZF9lbmFibGVfYm90Z3VhcmRcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbmxpbmVfbXV0ZWRfbGljZW5zZV9zZXJ2aWNlX2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNnNraXBfaW52YWxpZF95dGNzaV90aWNrc1x1MDAzZHRydWVcdTAwMjZza2lwX2xzX2dlbF9yZXRyeVx1MDAzZHRydWVcdTAwMjZza2lwX3NldHRpbmdfaW5mb19pbl9jc2lfZGF0YV9vYmplY3RcdTAwM2R0cnVlXHUwMDI2c2xvd19jb21wcmVzc2lvbnNfYmVmb3JlX2FiYW5kb25fY291bnRcdTAwM2Q0XHUwMDI2c3BlZWRtYXN0ZXJfY2FuY2VsbGF0aW9uX21vdmVtZW50X2RwXHUwMDNkMFx1MDAyNnNwZWVkbWFzdGVyX3BsYXliYWNrX3JhdGVcdTAwM2QwLjBcdTAwMjZzcGVlZG1hc3Rlcl90b3VjaF9hY3RpdmF0aW9uX21zXHUwMDNkMFx1MDAyNnN0YXJ0X2NsaWVudF9nY2ZcdTAwM2R0cnVlXHUwMDI2c3RhcnRfY2xpZW50X2djZl9mb3JfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNnN0YXJ0X3NlbmRpbmdfY29uZmlnX2hhc2hcdTAwM2R0cnVlXHUwMDI2c3RyZWFtaW5nX2RhdGFfZW1lcmdlbmN5X2l0YWdfYmxhY2tsaXN0XHUwMDNkW11cdTAwMjZzdWJzdGl0dXRlX2FkX2Nwbl9tYWNyb19pbl9zc2RhaVx1MDAzZHRydWVcdTAwMjZzdXBwcmVzc19lcnJvcl8yMDRfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZ0cmFuc3BvcnRfdXNlX3NjaGVkdWxlclx1MDAzZHRydWVcdTAwMjZ0dl9wYWNmX2xvZ2dpbmdfc2FtcGxlX3JhdGVcdTAwM2QwLjAxXHUwMDI2dHZodG1sNV91bnBsdWdnZWRfcHJlbG9hZF9jYWNoZV9zaXplXHUwMDNkNVx1MDAyNnVuY292ZXJfYWRfYmFkZ2Vfb25fUlRMX3Rpbnlfd2luZG93XHUwMDNkdHJ1ZVx1MDAyNnVucGx1Z2dlZF9kYWlfbGl2ZV9jaHVua19yZWFkYWhlYWRcdTAwM2QzXHUwMDI2dW5wbHVnZ2VkX3R2aHRtbDVfdmlkZW9fcHJlbG9hZF9vbl9mb2N1c19kZWxheV9tc1x1MDAzZDBcdTAwMjZ1cGRhdGVfbG9nX2V2ZW50X2NvbmZpZ1x1MDAzZHRydWVcdTAwMjZ1c2VfYWNjZXNzaWJpbGl0eV9kYXRhX29uX2Rlc2t0b3BfcGxheWVyX2J1dHRvblx1MDAzZHRydWVcdTAwMjZ1c2VfY29yZV9zbVx1MDAzZHRydWVcdTAwMjZ1c2VfaW5saW5lZF9wbGF5ZXJfcnBjXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfY21sXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfaW5fbWVtb3J5X3N0b3JhZ2VcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfaW5pdGlhbGl6YXRpb25cdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc2F3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3N0d1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF93dHNcdTAwM2R0cnVlXHUwMDI2dXNlX3BsYXllcl9hYnVzZV9iZ19saWJyYXJ5XHUwMDNkdHJ1ZVx1MDAyNnVzZV9wcm9maWxlcGFnZV9ldmVudF9sYWJlbF9pbl9jYXJvdXNlbF9wbGF5YmFja3NcdTAwM2R0cnVlXHUwMDI2dXNlX3JlcXVlc3RfdGltZV9tc19oZWFkZXJcdTAwM2R0cnVlXHUwMDI2dXNlX3Nlc3Npb25fYmFzZWRfc2FtcGxpbmdcdTAwM2R0cnVlXHUwMDI2dXNlX3RzX3Zpc2liaWxpdHlsb2dnZXJcdTAwM2R0cnVlXHUwMDI2dmFyaWFibGVfYnVmZmVyX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2dmVyaWZ5X2Fkc19pdGFnX2Vhcmx5XHUwMDNkdHJ1ZVx1MDAyNnZwOV9kcm1fbGl2ZVx1MDAzZHRydWVcdTAwMjZ2c3NfZmluYWxfcGluZ19zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZ2c3NfcGluZ3NfdXNpbmdfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2dnNzX3BsYXliYWNrX3VzZV9zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfYXBpX3VybFx1MDAzZHRydWVcdTAwMjZ3ZWJfYXN5bmNfY29udGV4dF9wcm9jZXNzb3JfaW1wbFx1MDAzZHN0YW5kYWxvbmVcdTAwMjZ3ZWJfY2luZW1hdGljX3dhdGNoX3NldHRpbmdzXHUwMDNkdHJ1ZVx1MDAyNndlYl9jbGllbnRfdmVyc2lvbl9vdmVycmlkZVx1MDAzZFx1MDAyNndlYl9kZWR1cGVfdmVfZ3JhZnRpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX2RlcHJlY2F0ZV9zZXJ2aWNlX2FqYXhfbWFwX2RlcGVuZGVuY3lcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV9lcnJvcl8yMDRcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV9pbnN0cmVhbV9hZHNfbGlua19kZWZpbml0aW9uX2ExMXlfYnVnZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfdm96X2F1ZGlvX2ZlZWRiYWNrXHUwMDNkdHJ1ZVx1MDAyNndlYl9maXhfZmluZV9zY3J1YmJpbmdfZHJhZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZm9yZWdyb3VuZF9oZWFydGJlYXRfaW50ZXJ2YWxfbXNcdTAwM2QyODAwMFx1MDAyNndlYl9mb3J3YXJkX2NvbW1hbmRfb25fcGJqXHUwMDNkdHJ1ZVx1MDAyNndlYl9nZWxfZGVib3VuY2VfbXNcdTAwM2Q2MDAwMFx1MDAyNndlYl9nZWxfdGltZW91dF9jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX2lubGluZV9wbGF5ZXJfbm9fcGxheWJhY2tfdWlfY2xpY2tfaGFuZGxlclx1MDAzZHRydWVcdTAwMjZ3ZWJfa2V5X21vbWVudHNfbWFya2Vyc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nX21lbW9yeV90b3RhbF9rYnl0ZXNcdTAwM2R0cnVlXHUwMDI2d2ViX2xvZ2dpbmdfbWF4X2JhdGNoXHUwMDNkMTUwXHUwMDI2d2ViX21vZGVybl9hZHNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fYnV0dG9uc19ibF9zdXJ2ZXlcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zY3J1YmJlclx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3N1YnNjcmliZVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3N1YnNjcmliZV9zdHlsZVx1MDAzZGZpbGxlZFx1MDAyNndlYl9uZXdfYXV0b25hdl9jb3VudGRvd25cdTAwM2R0cnVlXHUwMDI2d2ViX29uZV9wbGF0Zm9ybV9lcnJvcl9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfb3Bfc2lnbmFsX3R5cGVfYmFubGlzdFx1MDAzZFtdXHUwMDI2d2ViX3BhdXNlZF9vbmx5X21pbmlwbGF5ZXJfc2hvcnRjdXRfZXhwYW5kXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5YmFja19hc3NvY2lhdGVkX2xvZ19jdHRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfdmVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hZGRfdmVfY29udmVyc2lvbl9sb2dnaW5nX3RvX291dGJvdW5kX2xpbmtzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYWx3YXlzX2VuYWJsZV9hdXRvX3RyYW5zbGF0aW9uXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXBpX2xvZ2dpbmdfZnJhY3Rpb25cdTAwM2QwLjAxXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X2VtcHR5X3N1Z2dlc3Rpb25zX2ZpeFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdG9nZ2xlX2Fsd2F5c19saXN0ZW5cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X3VzZV9zZXJ2ZXJfcHJvdmlkZWRfc3RhdGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9jYXB0aW9uX2xhbmd1YWdlX3ByZWZlcmVuY2Vfc3RpY2tpbmVzc19kdXJhdGlvblx1MDAzZDMwXHUwMDI2d2ViX3BsYXllcl9kZWNvdXBsZV9hdXRvbmF2XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZGlzYWJsZV9pbmxpbmVfc2NydWJiaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX2Vhcmx5X3dhcm5pbmdfc25hY2tiYXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZmVhdHVyZWRfcHJvZHVjdF9iYW5uZXJfb25fZGVza3RvcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9pbl9oNV9hcGlcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfcHJlbWl1bV9oYnJfcGxheWJhY2tfY2FwXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaW5uZXJ0dWJlX3BsYXlsaXN0X3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2lwcF9jYW5hcnlfdHlwZV9mb3JfbG9nZ2luZ1x1MDAzZFx1MDAyNndlYl9wbGF5ZXJfbGl2ZV9tb25pdG9yX2Vudlx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2xvZ19jbGlja19iZWZvcmVfZ2VuZXJhdGluZ192ZV9jb252ZXJzaW9uX3BhcmFtc1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX21vdmVfYXV0b25hdl90b2dnbGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9tdXNpY192aXN1YWxpemVyX3RyZWF0bWVudFx1MDAzZGZha2VcdTAwMjZ3ZWJfcGxheWVyX211dGFibGVfZXZlbnRfbGFiZWxcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9uaXRyYXRlX3Byb21vX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9vZmZsaW5lX3BsYXlsaXN0X2F1dG9fcmVmcmVzaFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Jlc3BvbnNlX3BsYXliYWNrX3RyYWNraW5nX3BhcnNpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZWVrX2NoYXB0ZXJzX2J5X3Nob3J0Y3V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2VudGluZWxfaXNfdW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2hvdWxkX2hvbm9yX2luY2x1ZGVfYXNyX3NldHRpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG93X211c2ljX2luX3RoaXNfdmlkZW9fZ3JhcGhpY1x1MDAzZHZpZGVvX3RodW1ibmFpbFx1MDAyNndlYl9wbGF5ZXJfc21hbGxfaGJwX3NldHRpbmdzX21lbnVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zc19kYWlfYWRfZmV0Y2hpbmdfdGltZW91dF9tc1x1MDAzZDE1MDAwXHUwMDI2d2ViX3BsYXllcl9zc19tZWRpYV90aW1lX29mZnNldFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RvcGlmeV9zdWJ0aXRsZXNfZm9yX3Nob3J0c1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RvdWNoX21vZGVfaW1wcm92ZW1lbnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdHJhbnNmZXJfdGltZW91dF90aHJlc2hvbGRfbXNcdTAwM2QxMDgwMDAwMFx1MDAyNndlYl9wbGF5ZXJfdW5zZXRfZGVmYXVsdF9jc25fa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3VzZV9uZXdfYXBpX2Zvcl9xdWFsaXR5X3B1bGxiYWNrXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdmVfY29udmVyc2lvbl9maXhlc19mb3JfY2hhbm5lbF9pbmZvXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3dhdGNoX25leHRfcmVzcG9uc2VfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcHJlZmV0Y2hfcHJlbG9hZF92aWRlb1x1MDAzZHRydWVcdTAwMjZ3ZWJfcm91bmRlZF90aHVtYm5haWxzXHUwMDNkdHJ1ZVx1MDAyNndlYl9zZXR0aW5nc19tZW51X2ljb25zXHUwMDNkdHJ1ZVx1MDAyNndlYl9zbW9vdGhuZXNzX3Rlc3RfZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9tZXRob2RcdTAwM2QwXHUwMDI2d2ViX3l0X2NvbmZpZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNndpbF9pY29uX3JlbmRlcl93aGVuX2lkbGVcdTAwM2R0cnVlXHUwMDI2d29mZmxlX2NsZWFuX3VwX2FmdGVyX2VudGl0eV9taWdyYXRpb25cdTAwM2R0cnVlXHUwMDI2d29mZmxlX2VuYWJsZV9kb3dubG9hZF9zdGF0dXNcdTAwM2R0cnVlXHUwMDI2d29mZmxlX3BsYXlsaXN0X29wdGltaXphdGlvblx1MDAzZHRydWVcdTAwMjZ5dGlkYl9jbGVhcl9lbWJlZGRlZF9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2eXRpZGJfZmV0Y2hfZGF0YXN5bmNfaWRzX2Zvcl9kYXRhX2NsZWFudXBcdTAwM2R0cnVlXHUwMDI2eXRpZGJfcmVtYWtlX2RiX3JldHJpZXNcdTAwM2QxXHUwMDI2eXRpZGJfcmVvcGVuX2RiX3JldHJpZXNcdTAwM2QwXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdFx1MDAzZDAuMDJcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0X3Nlc3Npb25cdTAwM2QwLjJcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0X3RyYW5zYWN0aW9uXHUwMDNkMC4xIiwiY3NwTm9uY2UiOiJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIiwiY2FuYXJ5U3RhdGUiOiJub25lIiwiZGF0YXN5bmNJZCI6IlYyMDIxN2ZjNnx8In19LCJYU1JGX0ZJRUxEX05BTUUiOiJzZXNzaW9uX3Rva2VuIiwiWFNSRl9UT0tFTiI6IlFVRkZMVWhxYTAxMmQyNUROVWhzY0MxbVpsRkliVlpOT1hWSmFYRkpibTB4UVh4QlEzSnRjMHRzU21SaVNucGhRak5uT1dKdlZFUnNiVzFsWkRnMWMwZGtOVzAxV0RoV1lWZDRiMDUxVUVoTFV6UmpNa3RIU3pod1FUbEVhMDl3WDI5aFNEaEZhbUZSVld4MWJXUXhWMDlUVWpaT1Nsa3pXRkJRYXpCQlYzZEZaR280V1VGTFpFcDVkRFpmTWxwaU5XdExPRGhsTUhOSVdRXHUwMDNkXHUwMDNkIiwiWVBDX01CX1VSTCI6Imh0dHBzOi8vcGF5bWVudHMueW91dHViZS5jb20vcGF5bWVudHMvdjQvanMvaW50ZWdyYXRvci5qcz9zc1x1MDAzZG1kIiwiWVRSX0ZBTUlMWV9DUkVBVElPTl9VUkwiOiJodHRwczovL2ZhbWlsaWVzLmdvb2dsZS5jb20vd2ViY3JlYXRpb24/dXNlZ2FwaVx1MDAzZDEiLCJTRVJWRVJfVkVSU0lPTiI6InByb2QiLCJSRVVTRV9DT01QT05FTlRTIjp0cnVlLCJTVEFNUEVSX1NUQUJMRV9MSVNUIjp0cnVlLCJEQVRBU1lOQ19JRCI6IlYyMDIxN2ZjNnx8IiwiU0VSSUFMSVpFRF9DTElFTlRfQ09ORklHX0RBVEEiOiJDSlMtaUtRR0VLcXlfaElRek4tdUJSQ2x3djRTRVBpMXJ3VVE3cUt2QlJES3ZLOEZFTlNocndVUTRLZXZCUkNWdjY4RkVOVzJyd1VReks3LUVoRGkxSzRGRUlub3JnVVFwWm12QlJELXRhOEZFTHEwcndVUTVMUC1FaEMzNEs0RkVLTzByd1VRZ3AydkJSQ1BvNjhGRU9mM3JnVVFvdXl1QlJETXRfNFNFS21fcndVUTg2aXZCUkQ3dnE4RkVQN3VyZ1VRMjYtdkJSQzl0cTRGRUxpTHJnVVF3N2YtRWhDRzBmNFNFTkR5cmdVUThiYXZCUSUzRCUzRCIsIkxJVkVfQ0hBVF9CQVNFX1RBTkdPX0NPTkZJRyI6eyJhcGlLZXkiOiJBSXphU3lEWk5reUMtQXRST3dNQnBMZmV2SXZxWWstR2ZpOFpPZW8iLCJjaGFubmVsVXJpIjoiaHR0cHM6Ly9jbGllbnQtY2hhbm5lbC5nb29nbGUuY29tL2NsaWVudC1jaGFubmVsL2NsaWVudCIsImNsaWVudE5hbWUiOiJ5dC1saXZlLWNvbW1lbnRzIiwicmVxdWlyZXNBdXRoVG9rZW4iOnRydWUsInNlbmRlclVyaSI6Imh0dHBzOi8vY2xpZW50czQuZ29vZ2xlLmNvbS9pbnZhbGlkYXRpb24vbGNzL2NsaWVudCIsInVzZU5ld1RhbmdvIjp0cnVlfSwiRkVYUF9FWFBFUklNRU5UUyI6WzIzOTgzMjk2LDI0MDA0NjQ0LDI0MDA3MjQ2LDI0MDA3NjEzLDI0MDgwNzM4LDI0MTM1MzEwLDI0MzYzMTE0LDI0MzY0Nzg5LDI0MzY1NTM0LDI0MzY2OTE3LDI0MzcyNzYxLDI0Mzc1MTAxLDI0Mzc2Nzg1LDI0NDE1ODY0LDI0NDE2MjkwLDI0NDMzNjc5LDI0NDM3NTc3LDI0NDM5MzYxLDI0NDQzMzMxLDI0NDk5NTMyLDI0NTMyODU1LDI0NTUwNDU4LDI0NTUwOTUxLDI0NTU1NTY3LDI0NTU4NjQxLDI0NTU5MzI3LDI0Njk5ODk5LDM5MzIzMDc0XSwiTElWRV9DSEFUX1NFTkRfTUVTU0FHRV9BQ1RJT04iOiJsaXZlX2NoYXQvd2F0Y2hfcGFnZS9zZW5kIiwiUk9PVF9WRV9UWVBFIjozNjExLCJDTElFTlRfUFJPVE9DT0wiOiJIVFRQLzEuMSIsIkNMSUVOVF9UUkFOU1BPUlQiOiJ0Y3AiLCJFT01fVklTSVRPUl9EQVRBIjoiQ2d0QmJsOXlibGd3V0hscmF5aVV2b2lrQmclM0QlM0QiLCJUSU1FX0NSRUFURURfTVMiOjE2ODYyNDkyMzY3MjEsIkJVVFRPTl9SRVdPUksiOnRydWUsIlZBTElEX1NFU1NJT05fVEVNUERBVEFfRE9NQUlOUyI6WyJ5b3V0dWJlLmNvbSIsInd3dy55b3V0dWJlLmNvbSIsIndlYi1ncmVlbi1xYS55b3V0dWJlLmNvbSIsIndlYi1yZWxlYXNlLXFhLnlvdXR1YmUuY29tIiwid2ViLWludGVncmF0aW9uLXFhLnlvdXR1YmUuY29tIiwibS55b3V0dWJlLmNvbSIsIm13ZWItZ3JlZW4tcWEueW91dHViZS5jb20iLCJtd2ViLXJlbGVhc2UtcWEueW91dHViZS5jb20iLCJtd2ViLWludGVncmF0aW9uLXFhLnlvdXR1YmUuY29tIiwic3R1ZGlvLnlvdXR1YmUuY29tIiwic3R1ZGlvLWdyZWVuLXFhLnlvdXR1YmUuY29tIiwic3R1ZGlvLWludGVncmF0aW9uLXFhLnlvdXR1YmUuY29tIl0sIldPUktFUl9QRVJGT1JNQU5DRV9VUkwiOnsicHJpdmF0ZURvTm90QWNjZXNzT3JFbHNlVHJ1c3RlZFJlc291cmNlVXJsV3JhcHBlZFZhbHVlIjoiL3MvZGVza3RvcC8zNzRmYWFkNS9qc2Jpbi93b3JrZXItcGVyZm9ybWFuY2UudmZsc2V0L3dvcmtlci1wZXJmb3JtYW5jZS5qcyJ9LCJSQVdfQ09MRF9DT05GSUdfR1JPVVAiOnsiY29uZmlnRGF0YSI6IkNKUy1pS1FHRU9xZHJRVVE3THF0QlJDTThxMEZFUGVJcmdVUXVJdXVCUkRGbXE0RkVLZWRyZ1VRaWJHdUJSQ0N0YTRGRUlhMXJnVVF2YmF1QlJDZ3VhNEZFT2JOcmdVUTR0U3VCUkRrMXE0RkVNemZyZ1VRNXVDdUJSRG40YTRGRUlub3JnVVF1T211QlJDaTdLNEZFUDd1cmdVUTBQS3VCUkRuOTY0RkVPXzZyZ1VROF9xdUJSRDEtcTRGRUlXTnJ3VVFoWkd2QlJESGs2OEZFTi1VcndVUTZKV3ZCUkNsbWE4RkVJS2Ryd1VRMDU2dkJSRHBucThGRU1LZnJ3VVExS0d2QlJEVm9xOEZFTzZpcndVUWo2T3ZCUkRSbzY4RkVNLWxyd1VRNEtldkJSRG9xSzhGRVBPb3J3VVFtYXV2QlJDUXI2OEZFTnV2cndVUWlyS3ZCUkNqdEs4RkVMcTByd1VRLUxXdkJSRC10YThGRU5XMnJ3VVFfN2F2QlJENnVLOEZFS3E1cndVUTRicXZCUkRhdTY4RkVNcThyd1VRLTc2dkJSQ1Z2NjhGRUttX3J3VVEzY0N2QlJEOHdLOEZHakpCU1VwT1NHaEdTMDlPUlU5S1JtNVpUWEptY2poV2FsZG9URko1TVdSb01VWTBNVXRvWXpaWk1WQXRZMUJmVm5aVmR5SXlRVWxLVGtob1JrdFBUa1ZQU2tadVdVMXlabkk0Vm1wWGFFeFNlVEZrYURGR05ERkxhR00yV1RGUUxXTlFYMVoyVlhjcVBFTkJUVk5MVVRCWVozQmhiMEYwTkVVNFozSXRRbG80UlRsb1YxSkNVbFZUY1UxVVNVUlBURWRCVFRocE1VdEZSak50UzJSTU5HdHVhamRyUlElM0QlM0QiLCJtYWluQXBwQ29sZENvbmZpZyI6eyJpb3NTc29TYWZhcmlGc2lQcm9tb0VuYWJsZWQiOnRydWUsImlvc1RvZGF5V2lkZ2V0RW5hYmxlZCI6ZmFsc2UsImlvc0VuYWJsZUR5bmFtaWNGb250U2l6aW5nIjpmYWxzZSwiZW5hYmxlTW9iaWxlQXV0b09mZmxpbmUiOmZhbHNlLCJhbmRyb2lkRW5hYmxlUGlwIjpmYWxzZSwicG9zdHNWMiI6ZmFsc2UsImVuYWJsZURldGFpbGVkTmV0d29ya1N0YXR1c1JlcG9ydGluZyI6ZmFsc2UsImhvdXJUb1JlcG9ydE5ldHdvcmtTdGF0dXMiOjAsIm5ldHdvcmtTdGF0dXNSZXBvcnRpbmdXaW5kb3dTZWNzIjowLCJpb3NTZWFyY2h2aWV3UmVmYWN0b3J5RW5hYmxlZCI6ZmFsc2UsIm5nd0ZsZXh5RW5hYmxlZCI6ZmFsc2UsImlvc1dhdGNoRXhwYW5kVHJhbnNpdGlvbldpdGhvdXRTbmFwc2hvdCI6ZmFsc2UsImFuZHJvaWROZ3dVaUVuYWJsZWQiOmZhbHNlLCJhbmRyb2lkVGh1bWJuYWlsTW9uaXRvckVuYWJsZWQiOmZhbHNlLCJhbmRyb2lkVGh1bWJuYWlsTW9uaXRvckNvdW50IjowLCJhbmRyb2lkVGh1bWJuYWlsTW9uaXRvck1pbmltdW1XaWR0aCI6MCwiZW5hYmxlR2hvc3RDYXJkcyI6ZmFsc2UsImVuYWJsZUlubGluZU11dGVkIjpmYWxzZSwibmd3RmxleHlNYXhDcm9wUmF0aW8iOjEuMCwiYW5kcm9pZFJlc3RvcmVCcm93c2VDb250ZW50c0Zyb21CYWNrU3RhY2siOmZhbHNlLCJzZWFyY2hIaW50RXhwIjoic2VhcmNoX3lvdXR1YmUifSwiZXhwZXJpbWVudEZsYWdzIjp7IjQ1Mzg4NzQyIjp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM3NDMwNiI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNjYyNjYiOnsiaW50RmxhZ1ZhbHVlIjo2MDAwMH0sIjQ1MzY2MjY3Ijp7ImludEZsYWdWYWx1ZSI6MX0sIjQ1MzY0OTkzIjp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2ODc4NyI6eyJpbnRGbGFnVmFsdWUiOjIwMH0sIjQ1Mzc0ODYwIjp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2ODM4NiI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNjYyNjgiOnsiZG91YmxlRmxhZ1ZhbHVlIjoxLjB9LCI0NTM3OTg1NSI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNzU1NjQiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzUyMTgwIjp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2ODQ5OCI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNTMzOTciOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzcwOTYxIjp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM3NTU2NSI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDU0MDczMzAiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzY3OTg3Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM3MjgxNCI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNTgxNDUiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX19fSwiUkFXX0hPVF9DT05GSUdfR1JPVVAiOnsibWFpbkFwcEhvdENvbmZpZyI6eyJpb3NXYXRjaEV4cGFuZFRyYW5zaXRpb24iOmZhbHNlLCJpb3NFYXJseVNldFdhdGNoVHJhbnNpdGlvbiI6ZmFsc2UsImV4cG9zZUNvbmZpZ1JlZnJlc2hTZXR0aW5nIjpmYWxzZSwiaW9zRW5hYmxlU2VhcmNoQnV0dG9uT25QbGF5ZXJPdmVybGF5IjpmYWxzZSwiaW9zTWluaW11bVRvb2x0aXBEdXJhdGlvbk1zZWNzIjoxMDAwLCJpb3NGcmVzaEhvbWVJbnRlcnZhbFNlY3MiOjAsImlvc0ZyZXNoU3Vic2NyaXB0aW9uc0ludGVydmFsU2VjcyI6MCwiaW9zVG9kYXlXaWRnZXRSZWZyZXNoSW50ZXJ2YWxTZWNzIjoyODgwMCwiaW9zRnJlc2hOb3RpZmljYXRpb25zSW5ib3hJbnRlcnZhbFNlY3MiOjAsInNpZ25lZE91dE5vdGlmaWNhdGlvbnNJb3NQcm9tcHQiOnRydWUsImlvc0ZyZXNoRnVsbFJlZnJlc2giOmZhbHNlfSwibG9nZ2luZ0hvdENvbmZpZyI6eyJldmVudExvZ2dpbmdDb25maWciOnsiZW5hYmxlZCI6dHJ1ZSwibWF4QWdlSG91cnMiOjcyMCwicmVxdWVzdFJldHJ5RW5hYmxlZCI6dHJ1ZSwicmV0cnlDb25maWciOnsiZml4ZWRCYXRjaFJldHJ5RW5hYmxlZCI6ZmFsc2V9LCJzaG91bGRGb3JjZVNldEFsbFBheWxvYWRzVG9JbW1lZGlhdGVUaWVyIjpmYWxzZX19LCJleHBlcmltZW50RmxhZ3MiOnsiNDUzNjUxMzciOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzY3Mjg5Ijp7ImRvdWJsZUZsYWdWYWx1ZSI6Mi4wfSwiNDUzNzEyODciOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1Mzc1NDQ1Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2ODEzMiI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNjk1NTIiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzYyMjk3Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM1MzMzOCI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNzc3MzciOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzU1Mzc4Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM1Njk1NCI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzODIxNDIiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzY4MDExIjp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM3NzA4MSI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNjU4NDMiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1Mzc5MTY5Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM3NTI5MiI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNjg5NDkiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzU2OTc5Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2MjM4NiI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzODkwNDMiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzYwODY0Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2Njk0MyI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfX19LCJTRVJJQUxJWkVEX0hPVF9IQVNIX0RBVEEiOiJDSlMtaUtRR0VoTTVPVGcwT0RrNU16azBNVGMwT1RBME1UY3lHSlMtaUtRR0tKVGtfQklvbnZfOEVpamNrXzBTS09Hc19SSW95NjM5RWlqR3N2MFNLS3EwX1JJb3pzRDlFaWlaeHYwU0tLWFFfUklvZ1BQOUVpakotZjBTS09pQ19oSW95WVQtRWlqS2hfNFNLTi1JX2hJbzc0bi1FaWp4aWY0U0tQaUxfaElvclpELUVpaWVrZjRTS05XZ19oSW9ncUwtRWlpR3B2NFNLUGlwX2hJb21xMy1FaWpNcnY0U0tQQ3dfaElvcXJMLUVpamtzXzRTS05tMl9oSW82TGItRWlqRHRfNFNLTXkzX2hJb2libi1FaWlPdXY0U0tMLTZfaElvN2J2LUVpakx2XzRTS0xuQl9oSW9wY0wtRWlpeXd2NFNLTXJDX2hJb3hNYi1FaWpneF80U0tKWElfaElveHNqLUVpaVF5ZjRTS0pmS19oSW9nc3YtRWlqQnlfNFNLS0hRX2hJb3A5RC1FaWlHMGY0U01qSkJTVXBPU0doR1MwOU9SVTlLUm01WlRYSm1jamhXYWxkb1RGSjVNV1JvTVVZME1VdG9ZelpaTVZBdFkxQmZWblpWZHpveVFVbEtUa2hvUmt0UFRrVlBTa1p1V1UxeVpuSTRWbXBYYUV4U2VURmthREZHTkRGTGFHTTJXVEZRTFdOUVgxWjJWWGRDTUVOQlRWTkpRVEJNYjNSbU5rWmlORjk1WjBOTlRuRlJTMFpTWm1SNk9FbE5jVXB6UTJrdE5FSnlkV2RNZW5WalJBJTNEJTNEIiwiU0VSSUFMSVpFRF9DT0xEX0hBU0hfREFUQSI6IkNKUy1pS1FHRWhReE1UQXlOakUwTkRnM056ZzNNak15TURNMk5SaVV2b2lrQmpJeVFVbEtUa2hvUmt0UFRrVlBTa1p1V1UxeVpuSTRWbXBYYUV4U2VURmthREZHTkRGTGFHTTJXVEZRTFdOUVgxWjJWWGM2TWtGSlNrNUlhRVpMVDA1RlQwcEdibGxOY21aeU9GWnFWMmhNVW5reFpHZ3hSalF4UzJoak5sa3hVQzFqVUY5V2RsVjNRanhEUVUxVFMxRXdXR2R3WVc5QmREUkZPR2R5TFVKYU9FVTVhRmRTUWxKVlUzRk5WRWxFVDB4SFFVMDRhVEZMUlVZemJVdGtURFJyYm1vM2EwVSUzRCIsIlBFUlNJU1RfSURFTlRJVFlfSUZSQU1FX1VSTCI6eyJwcml2YXRlRG9Ob3RBY2Nlc3NPckVsc2VUcnVzdGVkUmVzb3VyY2VVcmxXcmFwcGVkVmFsdWUiOiJodHRwczovL3N0dWRpby55b3V0dWJlLmNvbS9wZXJzaXN0X2lkZW50aXR5In0sIlZJU0lCSUxJVFlfVElNRV9CRVRXRUVOX0pPQlNfTVMiOjEwMCwiU1RBUlRfSU5fVEhFQVRFUl9NT0RFIjpmYWxzZSwiU1RBUlRfSU5fRlVMTF9XSU5ET1dfTU9ERSI6ZmFsc2UsIlNFUlZJQ0VfV09SS0VSX1BST01QVF9OT1RJRklDQVRJT05TIjp0cnVlLCJTQk9YX0xBQkVMUyI6eyJTVUdHRVNUSU9OX0RJU01JU1NfTEFCRUwiOiJTdXBwcmltZXIiLCJTVUdHRVNUSU9OX0RJU01JU1NFRF9MQUJFTCI6IlN1Z2dlc3Rpb24gc3VwcHJpbcOpZSJ9LCJPTkVfUElDS19VUkwiOiIiLCJOT19FTVBUWV9EQVRBX0lNRyI6dHJ1ZSwiTUVOVElPTlNfRURVX0hFTFBfTElOSyI6Imh0dHBzOi8vc3VwcG9ydC5nb29nbGUuY29tL3lvdXR1YmUvP3BcdTAwM2RjcmVhdG9yX2NvbW11bml0eSIsIkRFRkVSUkVEX0RFVEFDSCI6dHJ1ZSwiUkVDQVBUQ0hBX1YzX1NJVEVLRVkiOiI2TGVkb09jVUFBQUFBSEE0Q0ZHOXpScGFDTmpZajMzU1lqelE5Y1R5IiwiUExBWUVSX0pTX1VSTCI6Ii9zL3BsYXllci9iMTI4ZGRhMC9wbGF5ZXJfaWFzLnZmbHNldC9mcl9GUi9iYXNlLmpzIiwiUExBWUVSX0NTU19VUkwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvd3d3LXBsYXllci5jc3MiLCJMSU5LX0dBTF9ET01BSU4iOiJodHRwczovL2FjY291bnRsaW5raW5nLXBhLWNsaWVudHM2LnlvdXR1YmUuY29tIiwiTElOS19PSVNfRE9NQUlOIjoib2F1dGhpbnRlZ3JhdGlvbnMtY2xpZW50czYueW91dHViZS5jb20iLCJJU19UQUJMRVQiOmZhbHNlLCJMSU5LX0FQSV9LRVkiOiJBSXphU3lEb3BoQVF1eXlpQnI4aDBueXBFd1hVS296SC1CRXN3RDAiLCJESVNBQkxFX1dBUk1fTE9BRFMiOmZhbHNlLCJWT1pfQVBJX0tFWSI6IkFJemFTeUJVMnhFX0pIdkI2d2FnM3RNZmh4WHBnMlFfVzh4bk0tSSIsIlNUUyI6MTk1MTMsIlNCT1hfU0VUVElOR1MiOnsiSEFTX09OX1NDUkVFTl9LRVlCT0FSRCI6ZmFsc2UsIklTX0ZVU0lPTiI6ZmFsc2UsIklTX1BPTFlNRVIiOnRydWUsIlJFUVVFU1RfRE9NQUlOIjoiZnIiLCJSRVFVRVNUX0xBTkdVQUdFIjoiZnIiLCJTRU5EX1ZJU0lUT1JfREFUQSI6dHJ1ZSwiU0VBUkNIQk9YX0JFSEFWSU9SX0VYUEVSSU1FTlQiOiJ6ZXJvLXByZWZpeCIsIlNFQVJDSEJPWF9FTkFCTEVfUkVGSU5FTUVOVF9TVUdHRVNUIjp0cnVlLCJTRUFSQ0hCT1hfVEFQX1RBUkdFVF9FWFBFUklNRU5UIjowLCJTRUFSQ0hCT1hfWkVST19UWVBJTkdfU1VHR0VTVF9VU0VfUkVHVUxBUl9TVUdHRVNUIjoiYWx3YXlzIiwiU1VHR19FWFBfSUQiOiJ5dG5lX2MsY2Zyb1x1MDAzZDEseXRwby5iby5tZVx1MDAzZDEseXRwby5iby52by5udHRcdTAwM2QyLHl0cG8uYm8udm8uYmlzXHUwMDNkMSx5dHBvLmJvLnZvLm1zZlx1MDAzZDAuNSx5dHBvLmJvLnZvLmlzYlx1MDAzZDEwLHl0cG9zby5iby5tZVx1MDAzZDEseXRwb3NvLmJvLnZvLm50dFx1MDAzZDIseXRwb3NvLmJvLnZvLmJpc1x1MDAzZDEseXRwb3NvLmJvLnZvLm1zZlx1MDAzZDAuNSx5dHBvc28uYm8udm8uaXNiXHUwMDNkMTAiLCJWSVNJVE9SX0RBVEEiOiJDZ3RCYmw5eWJsZ3dXSGxyYXlpVXZvaWtCZyUzRCUzRCIsIlNFQVJDSEJPWF9IT1NUX09WRVJSSURFIjoic3VnZ2VzdHF1ZXJpZXMtY2xpZW50czYueW91dHViZS5jb20iLCJISURFX1JFTU9WRV9MSU5LIjpmYWxzZX0sIlNCT1hfSlNfVVJMIjoiaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL3d3dy1zZWFyY2hib3gudmZsc2V0L3d3dy1zZWFyY2hib3guanMifSk7IHdpbmRvdy55dGNmZy5vYmZ1c2NhdGVkRGF0YV8gPSBbXTt2YXIgc2V0TWVzc2FnZT1mdW5jdGlvbihtc2cpe2lmKHdpbmRvdy55dCYmeXQuc2V0TXNnKXl0LnNldE1zZyhtc2cpO2Vsc2V7d2luZG93Lnl0Y2ZnPXdpbmRvdy55dGNmZ3x8e307eXRjZmcubXNncz1tc2d9fTsKc2V0TWVzc2FnZSh7IkFEREVEX1RPX1FVRVVFIjoiQWpvdXTDqWUgw6AgbGEgZmlsZSBkXHUwMDI3YXR0ZW50ZSIsIkFERF9UT19EUk9QRE9XTl9MQUJFTCI6IkVucmVnaXN0cmVyIGRhbnMuLi4iLCJBRF9CQURHRV9URVhUIjoiQW5ub25jZSIsIkFEX1RJVExFIjoiQW5ub25jZcKgOiAkdGl0bGUuIiwiQkFDS19BTFRfTEFCRUwiOiJSZXRvdXIiLCJCQUNLX09OTElORSI6IkRlIG5vdXZlYXUgY29ubmVjdMOpIMOgIEludGVybmV0IiwiQ0FOQ0VMIjoiQW5udWxlciIsIkNBUFRJT05fT0ZGX1RPQVNUIjoiU291cy10aXRyZXMgZMOpc2FjdGl2w6lzIiwiQ0FQVElPTl9PTl9UT0FTVCI6IlNvdXMtdGl0cmVzIGFjdGl2w6lzIiwiQ0hFQ0tfQ09OTkVDVElPTl9PUl9ET1dOTE9BRFMiOiJWZXVpbGxleiB2w6lyaWZpZXIgdm90cmUgY29ubmV4aW9uIG91IHJlZ2FyZGVyIHZvcyB2aWTDqW9zIHTDqWzDqWNoYXJnw6llcy4iLCJDTEVBUiI6IlN1cHByaW1lciIsIkNMT1NFIjoiRmVybWVyIiwiQ0xPU0VEX0NBUFRJT05TX0RJU0FCTEVEIjoiUGFzIGRlIHNvdXMtdGl0cmVzIGRpc3BvbmlibGVzIHBvdXIgY2V0dGUgdmlkw6lvLiIsIkNPTU1FTlRfTEFCRUwiOiJDb21tZW50ZXIiLCJDT05ORUNUX1RPX1RIRV9JTlRFUk5FVCI6IkNvbm5lY3Rlei12b3VzIMOgIEludGVybmV0IiwiQ09OVElOVUVfV0FUQ0hJTkciOiJDb250aW51ZXIgw6AgcmVnYXJkZXIiLCJERUxFVEUiOiJTdXBwcmltZXIiLCJERUxFVEVEX1BMQVlMSVNUIjoiUGxheWxpc3Qgc3VwcHJpbcOpZSBkZXMgdMOpbMOpY2hhcmdlbWVudHMuIiwiREVMRVRFRF9WSURFTyI6IlZpZMOpbyBzdXBwcmltw6llIGRlcyB0w6lsw6ljaGFyZ2VtZW50cy4iLCJERUxFVEVfQUxMX0RPV05MT0FEU19QUk9NUFQiOiJTdXBwcmltZXIgdG91cyBsZXMgdMOpbMOpY2hhcmdlbWVudHPCoD8iLCJERUxFVEVfRlJPTV9ET1dOTE9BRFMiOiJTdXBwcmltZXIgZGVzIHTDqWzDqWNoYXJnZW1lbnRzIiwiREVMRVRJTkdfQUxMIjoiU3VwcHJlc3Npb24gZGVzIHTDqWzDqWNoYXJnZW1lbnRz4oCmIiwiRElTTElLRV9MQUJFTCI6IkplIG5cdTAwMjdhaW1lIHBhcyIsIkRJU01JU1MiOiJJZ25vcmVyIiwiRE1BX0NPTlNFTlRfQ09ORklSTUFUSU9OIjoiVm90cmUgY2hvaXggcHJlbmRyYSBlZmZldCBsZSA2wqBtYXJzwqAyMDI0LiBWb3VzIHBvdXZleiBtb2RpZmllciB2b3Mgb3B0aW9ucyDDoCB0b3V0IG1vbWVudCBkYW5zIHZvdHJlIGNvbXB0ZcKgR29vZ2xlLiIsIkRNQV9DT05TRU5UX0dFTkVSQUxfRVJST1IiOiJVbmUgZXJyZXVyIHNcdTAwMjdlc3QgcHJvZHVpdGUgbG9ycyBkdSBjaGFyZ2VtZW50IiwiRE1BX0NPTlNFTlRfUkVDT1JEX0VSUk9SIjoiVW5lIGVycmV1ciBhIGVtcMOqY2jDqSBsXHUwMDI3ZW5yZWdpc3RyZW1lbnQgZGUgdm9zIGNob2l4IiwiRE9XTkxPQUQiOiJUw6lsw6ljaGFyZ2VyIiwiRE9XTkxPQURFRCI6IlTDqWzDqWNoYXJnw6llIiwiRE9XTkxPQURJTkciOiJUw6lsw6ljaGFyZ2VtZW50IiwiRE9XTkxPQURJTkdfUEVSQ0VOVCI6IlTDqWzDqWNoYXJnZW1lbnTigKYgJHBlcmNlbnQlIiwiRE9XTkxPQURTIjoiVMOpbMOpY2hhcmdlbWVudHMiLCJET1dOTE9BRFNfQVZBSUxBQklMSVRZIjoiTGVzIHTDqWzDqWNoYXJnZW1lbnRzIHJlc3RlbnQgZGlzcG9uaWJsZXMgdGFudCBxdWUgdm90cmUgYXBwYXJlaWwgc2UgY29ubmVjdGUgw6AgSW50ZXJuZXQgYXUgbW9pbnMgdW5lIGZvaXMgdG91cyBsZXMgMzDCoGpvdXJzLiIsIkRPV05MT0FEU19TRVRUSU5HUyI6IlBhcmFtw6h0cmVzIGRlcyB0w6lsw6ljaGFyZ2VtZW50cyIsIkRPV05MT0FEX0VYUElSRUQiOiJUw6lsw6ljaGFyZ2VtZW50IGV4cGlyw6kiLCJET1dOTE9BRF9QQVVTRUQiOiJUw6lsw6ljaGFyZ2VtZW50IG1pcyBlbiBwYXVzZSIsIkRPV05MT0FEX1FVQUxJVFkiOiJRdWFsaXTDqSBkZSB0w6lsw6ljaGFyZ2VtZW50IiwiRE9fTk9UX0hBVkVfRE9XTkxPQURTIjoiVm91cyBuXHUwMDI3YXZleiB0w6lsw6ljaGFyZ8OpIGF1Y3VuZSB2aWTDqW8iLCJFRElUX0FWQVRBUl9MQUJFTCI6Ik1vZGlmaWVyIGxhIHBob3RvIGRlIHByb2ZpbCIsIkVEVV9HT1RfSVQiOiJPSyIsIkVORF9PRl9QTEFZTElTVCI6IkZpbiBkZSBsYSBwbGF5bGlzdCIsIkVOVEVSX0RBVEVfT1JfRUFSTElFUiI6IlNhaXNpc3NleiAkYWxsb3dlZF9kYXRlIG91IHVuZSBkYXRlIGFudMOpcmlldXJlIiwiRU5URVJfREFURV9PUl9MQVRFUiI6IlNhaXNpc3NleiAkYWxsb3dlZF9kYXRlIG91IHVuZSBkYXRlIHVsdMOpcmlldXJlIiwiRlJFRUJJRV9KT0lOX01FTUJFUlNISVBfRURVX1RFWFQiOiJDZXR0ZSBjaGHDrm5lIHByb3Bvc2UgdW5lIG9mZnJlIGRlIHNvdXNjcmlwdGlvbi4gQXZlYyBZb3VUdWJlwqBQcmVtaXVtLCB2b3VzIHBvdXZleiB2b3VzIHkgaW5zY3JpcmUgZ3JhdHVpdGVtZW50LiIsIkdFVF9QUkVNSVVNIjoiT2J0ZW5pciBQcmVtaXVtIiwiR09fVE9fRE9XTkxPQURTIjoiVm9pciBsZXMgdMOpbMOpY2hhcmdlbWVudHMiLCJHVUlERV9BTFRfTEFCRUwiOiJHdWlkZSIsIkhPUklaT05UQUxfTElTVF9ORVhUX0xBQkVMIjoiU3VpdmFudCIsIkhPUklaT05UQUxfTElTVF9QUkVWSU9VU19MQUJFTCI6IlByw6ljw6lkZW50IiwiSU1BR0VfSE9SSVpPTlRBTF9QT1NJVElPTl9MQUJFTCI6IkxlIGNlbnRyZSBkZSBsXHUwMDI3YXBlcsOndSBzZSB0cm91dmUgw6AgJHhfcGVyY2VudMKgJSBkdSBib3JkIGdhdWNoZSBldCDDoCAkeV9wZXJjZW50wqAlIGR1IGJvcmQgZHJvaXQgZGUgbFx1MDAyN2ltYWdlLiIsIklNQUdFX1ZFUlRJQ0FMX1BPU0lUSU9OX0xBQkVMIjoiTGUgY2VudHJlIGRlIGxcdTAwMjdhcGVyw6d1IHNlIHRyb3V2ZSDDoCAkeF9wZXJjZW50wqAlIGR1IGhhdXQgZXQgw6AgJHlfcGVyY2VudMKgJSBkdSBiYXMgZGUgbFx1MDAyN2ltYWdlLiIsIklOVkFMSURfREFURV9FUlJPUiI6IkRhdGUgaW5jb3JyZWN0ZSIsIkpPSU5fTUVNQkVSU0hJUF9FRFVfVEVYVCI6IkLDqW7DqWZpY2lleiBkXHUwMDI3YXZhbnRhZ2VzIGV4Y2x1c2lmcyBlbiBzb3VzY3JpdmFudCDDoCBjZXR0ZSBjaGHDrm5lLiIsIkpPSU5fTUVNQkVSU0hJUF9FRFVfVElUTEUiOiJTb3VzY3JpcHRpb24iLCJLRUVQX09QRU4iOiJHYXJkZXogbGEgZmVuw6p0cmUgb3V2ZXJ0ZSBwb3VyIGNvbnRpbnVlciIsIkxJQlJBUllfR1VJREVfSVRFTV9FRFVfVEVYVCI6IlZvdXMgeSB0cm91dmVyZXogdm90cmUgaGlzdG9yaXF1ZSwgdm9zIHBsYXlsaXN0cywgdm9zIGFjaGF0cyBldCBwbHVzIGVuY29yZS4iLCJMSUJSQVJZX0dVSURFX0lURU1fRURVX1RJVExFIjoiRMOpY291dnJleiB2b3RyZSBub3V2ZWxsZSBiaWJsaW90aMOocXVlIiwiTElLRV9MQUJFTCI6IkpcdTAwMjdhaW1lIiwiTE9DQUxfVElNRV9MQUJFTCI6IkhldXJlIGxvY2FsZSIsIkxPR09fQUxUX0xBQkVMIjoiQWNjdWVpbCBZb3VUdWJlIiwiTUFJTl9BUFBfV0VCX0NPTU1FTlRfVEVBU0VSX1RPT0xUSVAiOiJDbGlxdWV6IGljaSBwb3VyIGxpcmUgbGVzIGNvbW1lbnRhaXJlcyB0b3V0IGVuIHJlZ2FyZGFudCBsYSB2aWTDqW8uIiwiTUFOQUdFX01FTUJFUlNISVBfRURVX1RFWFQiOiJBY2PDqWRleiDDoCB2b3MgYXZhbnRhZ2VzIGV0IGfDqXJleiB2b3RyZSBzb3VzY3JpcHRpb24uIiwiTUVOVElPTlNfRURVX1RFWFQiOiJDb25zdWx0ZXogbGUgY2VudHJlIGRcdTAwMjdhaWRlIHBvdXIgZW4gc2F2b2lyIHBsdXMgc3VyIGxlIGZvbmN0aW9ubmVtZW50IGRlcyBtZW50aW9ucyBzdXIgWW91VHViZS4iLCJNRU5USU9OU19FRFVfVElUTEUiOiJFbiBzYXZvaXIgcGx1cyIsIk1JTklQTEFZRVJfQ0xPU0UiOiJGZXJtZXIgbGUgbGVjdGV1ciIsIk1JTklQTEFZRVJfQ09MTEFQU0VfTEFCRUwiOiJSw6lkdWlyZSIsIk1JTklQTEFZRVJfRVhQQU5EX0xBQkVMIjoiRMOpdmVsb3BwZXIiLCJORVhUX1ZJREVPX0xBQkVMIjoiVmlkw6lvIHN1aXZhbnRlIiwiTk9fQU5HTEVfQlJBQ0tFVF9MQUJFTCI6IkxlIHRpdHJlIGRlIGxhIHBsYXlsaXN0IG5lIHBldXQgcGFzIGNvbnRlbmlyIFx1MDAzYyBvdSBcdTAwM2UiLCJOT19ET1dOTE9BRFMiOiJBdWN1biB0w6lsw6ljaGFyZ2VtZW50IiwiTk9fSU5URVJORVRfQ09OTkVDVElPTiI6IkF1Y3VuZSBjb25uZXhpb24gSW50ZXJuZXQiLCJPRkZMSU5FX0NIRUNLX0NPTk5FQ1RJT04iOiJWb3VzIG5cdTAwMjfDqnRlcyBwYXMgY29ubmVjdMOpLiBWw6lyaWZpZXogdm90cmUgY29ubmV4aW9uLiIsIlBBVVNFX0RPV05MT0FESU5HIjoiTWV0dHJlIGVuIHBhdXNlIGxlIHTDqWzDqWNoYXJnZW1lbnQiLCJQTEFZRVJfTEFCRUxfTVVURSI6IkNvdXBlciBsZSBzb27CoChtKSIsIlBMQVlFUl9MQUJFTF9QQVVTRSI6IlBhdXNlwqAoaykiLCJQTEFZRVJfTEFCRUxfUExBWSI6IkxlY3R1cmXCoChrKSIsIlBMQVlFUl9MQUJFTF9VTk1VVEUiOiJSw6lhY3RpdmVyIGxlIHNvbsKgKG0pIiwiUExBWUxJU1RfTkVYVF9WSURFT19USVRMRSI6IsOAIHN1aXZyZcKgOiAkdmlkZW9fdGl0bGUiLCJQTEFZX0FMTCI6IlRvdXQgbGlyZSIsIlBSRVBBUklOR19UT19ET1dOTE9BRCI6IlByw6lwYXJhdGlvbiBkdSB0w6lsw6ljaGFyZ2VtZW504oCmIiwiUFJFVklPVVNfVklERU9fTEFCRUwiOiJWaWTDqW8gcHLDqWPDqWRlbnRlIiwiUVVFVUUiOiJGaWxlIGRcdTAwMjdhdHRlbnRlIiwiUVVFVUVfQ0xFQVJFRCI6Intjb3VudCxwbHVyYWwsIFx1MDAzZDF7McKgdmlkw6lvIHN1cHByaW3DqWUgZGUgbGEgZmlsZSBkXHUwMDI3YXR0ZW50ZX1vbmV7IyB2aWRlb3MgaW4gdGhlIHF1ZXVlIHJlbW92ZWR9b3RoZXJ7I8Kgdmlkw6lvcyBzdXBwcmltw6llcyBkZSBsYSBmaWxlIGRcdTAwMjdhdHRlbnRlfX0iLCJRVUVVRV9DTEVBUkVEX1VOUExVUkFMSVpFRCI6IkZpbGUgZFx1MDAyN2F0dGVudGUgZWZmYWPDqWUiLCJRVUVVRV9DTE9TRV9NSU5JUExBWUVSX0NPTkZJUk1fQk9EWV9URVhUIjoiVm91bGV6LXZvdXMgdnJhaW1lbnQgZmVybWVyIGxlIGxlY3RldXLCoD8iLCJRVUVVRV9DTE9TRV9NSU5JUExBWUVSX0NPTkZJUk1fVElUTEUiOiJMYSBmaWxlIGRcdTAwMjdhdHRlbnRlIHNlcmEgZWZmYWPDqWUiLCJRVUVVRV9SRUNPVkVSX0JVVFRPTiI6IlJlc3RhdXJlciIsIlFVRVVFX1JFQ09WRVJfTUVTU0FHRSI6IlLDqWN1cMOpcmVyIGxhIGZpbGUgZFx1MDAyN2F0dGVudGUiLCJSRUFDSF9CT1RUT01fT0ZfSU1BR0VfVEVYVCI6IlZvdXMgYXZleiBhdHRlaW50IGxlIGJhcyBkZSBsXHUwMDI3aW1hZ2UiLCJSRUFDSF9MRUZUX09GX0lNQUdFX1RFWFQiOiJWb3VzIGF2ZXogYXR0ZWludCBsZSBib3JkIGdhdWNoZSBkZSBsXHUwMDI3aW1hZ2UiLCJSRUFDSF9SSUdIVF9PRl9JTUFHRV9URVhUIjoiVm91cyBhdmV6IGF0dGVpbnQgbGUgYm9yZCBkcm9pdCBkZSBsXHUwMDI3aW1hZ2UiLCJSRUFDSF9UT1BfT0ZfSU1BR0VfVEVYVCI6IlZvdXMgYXZleiBhdHRlaW50IGxlIGhhdXQgZGUgbFx1MDAyN2ltYWdlIiwiUkVNRU1CRVJfTVlfU0VUVElOR1MiOiJFbnJlZ2lzdHJlciBtZXMgcGFyYW3DqHRyZXMiLCJSRU1FTUJFUl9NWV9TRVRUSU5HU19OX0RBWVMiOiJFbnJlZ2lzdHJlciBtZXMgcGFyYW3DqHRyZXMgcGVuZGFudCAkZGF5c190aWxsX2V4cGlyZWTCoGpvdXJzIiwiUkVQT1NJVElPTl9JTUFHRV9IT1JJWk9OVEFMTFlfTEFCRUwiOiJVdGlsaXNleiBsZXMgdG91Y2hlcyBmbMOpY2jDqWVzIGdhdWNoZSBldCBkcm9pdGUgcG91ciByZXBvc2l0aW9ubmVyIGxcdTAwMjdhcGVyw6d1IiwiUkVQT1NJVElPTl9JTUFHRV9WRVJUSUNBTExZX0xBQkVMIjoiVXRpbGlzZXogbGVzIHRvdWNoZXMgZmzDqWNow6llcyB2ZXJzIGxlIGhhdXQgb3UgdmVycyBsZSBiYXMgcG91ciByZXBvc2l0aW9ubmVyIGxcdTAwMjdhcGVyw6d1IiwiUkVRVUlSRURfTEFCRUwiOiJPYmxpZ2F0b2lyZSIsIlJFU1VNRV9ET1dOTE9BRCI6IlJlcHJlbmRyZSBsZSB0w6lsw6ljaGFyZ2VtZW50IiwiUkVUUlkiOiJSw6llc3NheWVyIiwiU0JPWF9JTkFQUFJPUFJJQVRFX0FERElUSU9OQUwiOiJJbmRpcXVleiBkZXMgZMOpdGFpbHMgc3VwcGzDqW1lbnRhaXJlcyAoZmFjdWx0YXRpZikiLCJTQk9YX0lOQVBQUk9QUklBVEVfQ0FOQ0VMIjoiQW5udWxlciIsIlNCT1hfSU5BUFBST1BSSUFURV9DQVRFR09SWSI6IkxlcyBwcsOpZGljdGlvbnMgc8OpbGVjdGlvbm7DqWVzIHByw6lzZW50ZW50IGxlIHByb2Jsw6htZSBzdWl2YW50wqA6IiwiU0JPWF9JTkFQUFJPUFJJQVRFX0RBTkdFUk9VUyI6IkNhcmFjdMOocmUgZGFuZ2VyZXV4IiwiU0JPWF9JTkFQUFJPUFJJQVRFX0VYUExJQ0lUIjoiQ2FyYWN0w6hyZSBzZXh1ZWwgZXhwbGljaXRlIiwiU0JPWF9JTkFQUFJPUFJJQVRFX0hBVEVGVUwiOiJJbmNpdGF0aW9uIMOgIGxhIGhhaW5lIiwiU0JPWF9JTkFQUFJPUFJJQVRFX09USEVSIjoiQXV0cmUiLCJTQk9YX0lOQVBQUk9QUklBVEVfUFJPTVBUIjoiU2lnbmFsZXIgZGVzIHByw6lkaWN0aW9ucyBkZSByZWNoZXJjaGUiLCJTQk9YX0lOQVBQUk9QUklBVEVfUkVBU09OIjoiTW90aWYgKG9ibGlnYXRvaXJlKSIsIlNCT1hfSU5BUFBST1BSSUFURV9SRVBPUlQiOiJTaWduYWxlciIsIlNCT1hfSU5BUFBST1BSSUFURV9TVUJNSVQiOiJFbnZveWVyIiwiU0JPWF9JTkFQUFJPUFJJQVRFX1NVR0dFU1RJT05TIjoiU8OpbGVjdGlvbm5leiBsZXMgcHLDqWRpY3Rpb25zIHF1ZSB2b3VzIHNvdWhhaXRleiBzaWduYWxlcsKgOiIsIlNCT1hfSU5BUFBST1BSSUFURV9USVRMRSI6IlNpZ25hbGVyIGRlcyBwcsOpZGljdGlvbnMgZGUgcmVjaGVyY2hlIiwiU0JPWF9JTkFQUFJPUFJJQVRFX1RPQVNUIjoiTWVyY2kgcG91ciB2b3MgY29tbWVudGFpcmVzwqAhIiwiU0JPWF9JTkFQUFJPUFJJQVRFX1ZJT0xFTlQiOiJWaW9sZW5jZSIsIlNCT1hfUExBQ0VIT0xERVIiOiJSZWNoZXJjaGVyIiwiU0JPWF9WT0lDRV9PVkVSTEFZX1BMQUNFSE9MREVSIjoiw4ljb3V0ZeKApiIsIlNIQVJFX0xBQkVMIjoiUGFydGFnZXIiLCJTSEFSRV9QT1NUX0VEVV9URVhUIjoiVm91cyBwb3V2ZXogZMOpc29ybWFpcyBwYXJ0YWdlciBkZXMgcG9zdHMgc3VyIFlvdVR1YmUiLCJTSE9XX0xFU1MiOiJNb2lucyIsIlNIT1dfTU9SRSI6IlBsdXMiLCJTSUdOX0lOX0xBQkVMIjoiQ29ubmV4aW9uIiwiU01BUlRfRE9XTkxPQURTIjoiVMOpbMOpY2hhcmdlbWVudHMgaW50ZWxsaWdlbnRzIiwiU1RPUkFHRV9GVUxMIjoiTcOpbW9pcmUgcGxlaW5lIiwiU1VCU0NSSUJFX0xBQkVMIjoiU1x1MDAyN2Fib25uZXIiLCJTVUJTX0ZJTFRFUl9FRFVfQ0hBTk5FTF9URVhUIjoiQWZmaWNoYWdlIGRlcyBub3V2ZWxsZXMgdmlkw6lvcyBkZSBjZXR0ZSBjaGHDrm5lLiIsIlNVQlNfRklMVEVSX0VEVV9URVhUIjoiQ29uc3VsdGVyIGxlcyBub3V2ZWxsZXMgdmlkw6lvcyBkZSBjaGFxdWUgY2hhw65uZSIsIlNVQlNfR1VJREVfSVRFTV9FRFVfVEVYVCI6IkNvbnN1bHRlciBsZXMgbm91dmVsbGVzIHZpZMOpb3MgZGUgdG91cyB2b3MgYWJvbm5lbWVudHMiLCJUSU1FWk9ORV9GT1JNQVQiOiIoJHV0Y19vZmZzZXRfdGV4dCkgJGNpdHlfbmFtZSIsIlRSQU5TRkVSX0ZBSUxFRCI6IsOJY2hlYyBkdSB0w6lsw6ljaGFyZ2VtZW50IiwiVFJZX0FHQUlOX0xBVEVSIjoiVW4gcHJvYmzDqG1lIGVzdCBzdXJ2ZW51LiBWZXVpbGxleiByw6llc3NheWVyIHBsdXMgdGFyZC4iLCJUVVJOX09GRiI6IkTDqXNhY3RpdmVyIiwiVFVSTl9PTiI6IkFjdGl2ZXIiLCJVTkFWQUlMQUJMRV9PRkZMSU5FIjoiSW5kaXNwb25pYmxlIGhvcnMgY29ubmV4aW9uIiwiVU5ETyI6IkFubnVsZXIiLCJVTkRPX0FDVElPTiI6IkFubnVsZXIiLCJVUERBVEVEX1RJTUUiOiJNaXNlIMOgIGpvdXLCoDogJHJlbGF0aXZlX3RpbWUiLCJVUERBVEVfU01BUlRfRE9XTkxPQURTX05PVyI6Ik1ldHRyZSDDoCBqb3VyIiwiVVBEQVRJTkciOiJNaXNlIMOgIGpvdXLigKYiLCJVVENfT0ZGU0VUX0ZPUk1BVCI6IkdNVCR1dGNfb2Zmc2V0IiwiVklERU9TX0RPV05MT0FESU5HIjp7ImNhc2UxIjoiVMOpbMOpY2hhcmdlbWVudCBkZSAxwqB2aWTDqW/igKYiLCJvbmUiOiJUw6lsw6ljaGFyZ2VtZW50IGRlICPCoHZpZMOpb+KApiIsIm90aGVyIjoiVMOpbMOpY2hhcmdlbWVudCBkZSAjwqB2aWTDqW9z4oCmIn0sIlZJREVPU19ET1dOTE9BRElOR19SQVRJTyI6IlTDqWzDqWNoYXJnZW1lbnTigKYgJGRvd25sb2FkZWQvJHRvdGFsIiwiVklERU9fQUNUSU9OX01FTlUiOiJNZW51IGRcdTAwMjdhY3Rpb25zIiwiVklFV19ET1dOTE9BRFMiOiJBZmZpY2hlciIsIlZJRVdfRlVMTF9QTEFZTElTVCI6IkFmZmljaGVyIGxhIHBsYXlsaXN0IGNvbXBsw6h0ZSIsIldBSVRJTkdfRk9SX0lOVEVSTkVUIjoiRW4gYXR0ZW50ZSBkZSBsYSBjb25uZXhpb24gSW50ZXJuZXTigKYiLCJXQUlUSU5HX1RPX0RPV05MT0FEIjoiRW4gYXR0ZW50ZSBkZSB0w6lsw6ljaGFyZ2VtZW504oCmIiwiWU9VX0FSRV9PRkZMSU5FIjoiVm91cyDDqnRlcyBob3JzIGNvbm5leGlvbiIsIl9fbGFuZ19fIjoiZnIifSk7fSkoKTt5dGNmZy5zZXQoImluaXRpYWxJbm5lcldpZHRoIix3aW5kb3cuaW5uZXJXaWR0aCk7eXRjZmcuc2V0KCJpbml0aWFsSW5uZXJIZWlnaHQiLHdpbmRvdy5pbm5lckhlaWdodCk7Cjwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnbHBjZicsIG51bGwsICcnKTt9PC9zY3JpcHQ+PHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9qc2Jpbi9zY2hlZHVsZXIudmZsc2V0L3NjaGVkdWxlci5qcyIgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPjwvc2NyaXB0PjxzY3JpcHQgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9zL2Rlc2t0b3AvMzc0ZmFhZDUvanNiaW4vd3d3LWkxOG4tY29uc3RhbnRzLWZyX0ZSLnZmbHNldC93d3ctaTE4bi1jb25zdGFudHMuanMiIG5vbmNlPSJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIj48L3NjcmlwdD48c2NyaXB0IHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL3d3dy10YW1wZXJpbmcudmZsc2V0L3d3dy10YW1wZXJpbmcuanMiIG5vbmNlPSJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIj48L3NjcmlwdD48c2NyaXB0IHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL3NwZi52ZmxzZXQvc3BmLmpzIiBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+PC9zY3JpcHQ+PHNjcmlwdCBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+aWYod2luZG93WyJfc3BmX3N0YXRlIl0pd2luZG93WyJfc3BmX3N0YXRlIl0uY29uZmlnPXsiYXNzdW1lLWFsbC1qc29uLXJlcXVlc3RzLWNodW5rZWQiOnRydWV9Owo8L3NjcmlwdD48c2NyaXB0IHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL25ldHdvcmsudmZsc2V0L25ldHdvcmsuanMiIG5vbmNlPSJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIj48L3NjcmlwdD48c2NyaXB0IG5vbmNlPSJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIj5pZiAod2luZG93Lnl0Y3NpKSB7d2luZG93Lnl0Y3NpLnRpY2soJ2NzbCcsIG51bGwsICcnKTt9PC9zY3JpcHQ+PGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSIvL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2NzczI/ZmFtaWx5PVJvYm90bzp3Z2h0QDMwMDs0MDA7NTAwOzcwMCZmYW1pbHk9WW91VHViZStTYW5zOndnaHRAMzAwLi45MDAmZGlzcGxheT1zd2FwIiBub25jZT0id0txeDI1NzIwdWp1bWFVdkJILVR4USI+PHNjcmlwdCBuYW1lPSJ3d3ctcm9ib3RvIiBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+aWYgKGRvY3VtZW50LmZvbnRzICYmIGRvY3VtZW50LmZvbnRzLmxvYWQpIHtkb2N1bWVudC5mb250cy5sb2FkKCI0MDAgMTBwdCBSb2JvdG8iLCAiIik7IGRvY3VtZW50LmZvbnRzLmxvYWQoIjUwMCAxMHB0IFJvYm90byIsICIiKTt9PC9zY3JpcHQ+PGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9zL2Rlc2t0b3AvMzc0ZmFhZDUvY3NzYmluL3d3dy1vbmVwaWNrLmNzcyIgbm9uY2U9IndLcXgyNTcyMHVqdW1hVXZCSC1UeFEiPjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9fL3l0bWFpbmFwcHdlYi9fL3NzL2s9eXRtYWluYXBwd2ViLmtldmxhcl9iYXNlLjNla2RIMDIza1NZLkwuWC5PL2FtPUFBVS9kPTAvcnM9QUdLTXl3R0hpZVdLVnBEc0NtYnAwSUVPRklCQnNmdmtmUSIgbm9uY2U9IndLcXgyNTcyMHVqdW1hVXZCSC1UeFEiPjxzdHlsZSBjbGFzcz0iZ2xvYmFsX3N0eWxlcyIgbm9uY2U9IndLcXgyNTcyMHVqdW1hVXZCSC1UeFEiPmJvZHl7cGFkZGluZzowO21hcmdpbjowO292ZXJmbG93LXk6c2Nyb2xsfWJvZHkuYXV0b3Njcm9sbHtvdmVyZmxvdy15OmF1dG99Ym9keS5uby1zY3JvbGx7b3ZlcmZsb3c6aGlkZGVufWJvZHkubm8teS1zY3JvbGx7b3ZlcmZsb3cteTpoaWRkZW59LmhpZGRlbntkaXNwbGF5Om5vbmV9dGV4dGFyZWF7LS1wYXBlci1pbnB1dC1jb250YWluZXItaW5wdXRfLV93aGl0ZS1zcGFjZTpwcmUtd3JhcH0uZ3JlY2FwdGNoYS1iYWRnZXt2aXNpYmlsaXR5OmhpZGRlbn08L3N0eWxlPjxzdHlsZSBjbGFzcz0ibWFzdGhlYWRfc2hlbGwiIG5vbmNlPSJ3S3F4MjU3MjB1anVtYVV2QkgtVHhRIj55dGQtbWFzdGhlYWQuc2hlbGx7YmFja2dyb3VuZC1jb2xvcjojZmZmIWltcG9ydGFudDtwb3NpdGlvbjpmaXhlZDt0b3A6MDtyaWdodDowO2xlZnQ6MDtkaXNwbGF5Oi1tcy1mbGV4O2Rpc3BsYXk6LXdlYmtpdC1mbGV4O2Rpc3BsYXk6LXdlYmtpdC1ib3g7ZGlzcGxheTotbW96LWJveDtkaXNwbGF5Oi1tcy1mbGV4Ym94O2Rpc3BsYXk6ZmxleDtoZWlnaHQ6NTZweDstbXMtZmxleC1hbGlnbjpjZW50ZXI7LXdlYmtpdC1hbGlnbi1pdGVtczpjZW50ZXI7LXdlYmtpdC1ib3gtYWxpZ246Y2VudGVyOy1tb3otYm94LWFsaWduOmNlbnRlcjthbGlnbi1pdGVtczpjZW50ZXJ9eXRkLW1hc3RoZWFkLnNoZWxsICNtZW51LWljb257bWFyZ2luLWxlZnQ6MTZweH15dGQtYXBwPnl0ZC1tYXN0aGVhZC5jaHVua2Vke3Bvc2l0aW9uOmZpeGVkO3RvcDowO3dpZHRoOjEwMCV9eXRkLW1hc3RoZWFkLnNoZWxsLmRhcmsseXRkLW1hc3RoZWFkLnNoZWxsLnRoZWF0ZXJ7YmFja2dyb3VuZC1jb2xvcjojMGYwZjBmIWltcG9ydGFudH15dGQtbWFzdGhlYWQuc2hlbGwuZnVsbC13aW5kb3ctbW9kZXtiYWNrZ3JvdW5kLWNvbG9yOiMwZjBmMGYhaW1wb3J0YW50O29wYWNpdHk6MDstd2Via2l0LXRyYW5zZm9ybTp0cmFuc2xhdGVZKGNhbGMoLTEwMCUgLSA1cHgpKTt0cmFuc2Zvcm06dHJhbnNsYXRlWShjYWxjKC0xMDAlIC0gNXB4KSl9eXRkLW1hc3RoZWFkLnNoZWxsPjpmaXJzdC1jaGlsZHtwYWRkaW5nLWxlZnQ6MTZweH15dGQtbWFzdGhlYWQuc2hlbGw+Omxhc3QtY2hpbGR7cGFkZGluZy1yaWdodDoxNnB4fXl0ZC1tYXN0aGVhZCAjbWFzdGhlYWQtbG9nb3tkaXNwbGF5Oi1tcy1mbGV4O2Rpc3BsYXk6LXdlYmtpdC1mbGV4O2Rpc3BsYXk6LXdlYmtpdC1ib3g7ZGlzcGxheTotbW96LWJveDtkaXNwbGF5Oi1tcy1mbGV4Ym94O2Rpc3BsYXk6ZmxleH15dGQtbWFzdGhlYWQgI21hc3RoZWFkLWxvZ28gI2NvdW50cnktY29kZXttYXJnaW4tcmlnaHQ6MnB4fXl0ZC1tYXN0aGVhZC5zaGVsbCAjeXQtbG9nby1yZWQtc3ZnLHl0ZC1tYXN0aGVhZC5zaGVsbCAjeXQtbG9nby1yZWQtdXBkYXRlZC1zdmcseXRkLW1hc3RoZWFkLnNoZWxsICN5dC1sb2dvLXN2Zyx5dGQtbWFzdGhlYWQuc2hlbGwgI3l0LWxvZ28tdXBkYXRlZC1zdmd7LXdlYmtpdC1hbGlnbi1zZWxmOmNlbnRlcjstbXMtZmxleC1pdGVtLWFsaWduOmNlbnRlcjthbGlnbi1zZWxmOmNlbnRlcjttYXJnaW4tbGVmdDo4cHg7cGFkZGluZzowO2NvbG9yOiMwMDB9eXRkLW1hc3RoZWFkLnNoZWxsICNhMTF5LXNraXAtbmF2e2Rpc3BsYXk6bm9uZX15dGQtbWFzdGhlYWQuc2hlbGwgc3Zne3dpZHRoOjQwcHg7aGVpZ2h0OjQwcHg7cGFkZGluZzo4cHg7bWFyZ2luLXJpZ2h0OjhweDstbW96LWJveC1zaXppbmc6Ym9yZGVyLWJveDtib3gtc2l6aW5nOmJvcmRlci1ib3g7Y29sb3I6IzYwNjA2MDtmaWxsOmN1cnJlbnRDb2xvcn15dGQtbWFzdGhlYWQgLmV4dGVybmFsLWljb257d2lkdGg6MjRweDtoZWlnaHQ6MjRweH15dGQtbWFzdGhlYWQgLnl0LWljb25zLWV4dHtmaWxsOmN1cnJlbnRDb2xvcjtjb2xvcjojNjA2MDYwfXl0ZC1tYXN0aGVhZC5zaGVsbC5kYXJrIC55dC1pY29ucy1leHQgeXRkLW1hc3RoZWFkLnNoZWxsLnRoZWF0ZXIgLnl0LWljb25zLWV4dHtmaWxsOiNmZmZ9eXRkLW1hc3RoZWFkIHN2ZyN5dC1sb2dvLXN2Z3t3aWR0aDo4MHB4fXl0ZC1tYXN0aGVhZCBzdmcjeXQtbG9nby1yZWQtc3Zne3dpZHRoOjEwNi40cHh9eXRkLW1hc3RoZWFkIHN2ZyN5dC1sb2dvLXVwZGF0ZWQtc3Zne3dpZHRoOjkwcHh9eXRkLW1hc3RoZWFkIHN2ZyN5dC1sb2dvLXJlZC11cGRhdGVkLXN2Z3t3aWR0aDo5N3B4fUBtZWRpYSAobWF4LXdpZHRoOjY1NnB4KXt5dGQtbWFzdGhlYWQuc2hlbGw+OmZpcnN0LWNoaWxke3BhZGRpbmctbGVmdDo4cHh9eXRkLW1hc3RoZWFkLnNoZWxsPjpsYXN0LWNoaWxke3BhZGRpbmctcmlnaHQ6OHB4fXl0ZC1tYXN0aGVhZC5zaGVsbCBzdmd7bWFyZ2luLXJpZ2h0OjB9eXRkLW1hc3RoZWFkICNtYXN0aGVhZC1sb2dvey1tcy1mbGV4OjEgMSAwLjAwMDAwMDAwMXB4Oy13ZWJraXQtZmxleDoxOy13ZWJraXQtYm94LWZsZXg6MTstbW96LWJveC1mbGV4OjE7ZmxleDoxOy13ZWJraXQtZmxleC1iYXNpczowLjAwMDAwMDAwMXB4Oy1tcy1mbGV4LXByZWZlcnJlZC1zaXplOjAuMDAwMDAwMDAxcHg7ZmxleC1iYXNpczowLjAwMDAwMDAwMXB4fXl0ZC1tYXN0aGVhZC5zaGVsbCAjeXQtbG9nby1yZWQtc3ZnLHl0ZC1tYXN0aGVhZC5zaGVsbCAjeXQtbG9nby1zdmd7bWFyZ2luLWxlZnQ6NHB4fX1AbWVkaWEgKG1pbi13aWR0aDo4NzZweCl7eXRkLW1hc3RoZWFkICNtYXN0aGVhZC1sb2dve3dpZHRoOjEyOXB4fX0jbWFzdGhlYWQtc2tlbGV0b24taWNvbnN7ZGlzcGxheTotd2Via2l0LWJveDtkaXNwbGF5Oi13ZWJraXQtZmxleDtkaXNwbGF5Oi1tb3otYm94O2Rpc3BsYXk6LW1zLWZsZXhib3g7ZGlzcGxheTpmbGV4Oy13ZWJraXQtYm94LWZsZXg6MTstd2Via2l0LWZsZXg6MTstbW96LWJveC1mbGV4OjE7LW1zLWZsZXg6MTtmbGV4OjE7LXdlYmtpdC1ib3gtb3JpZW50Omhvcml6b250YWw7LXdlYmtpdC1ib3gtZGlyZWN0aW9uOm5vcm1hbDstd2Via2l0LWZsZXgtZGlyZWN0aW9uOnJvdzstbW96LWJveC1vcmllbnQ6aG9yaXpvbnRhbDstbW96LWJveC1kaXJlY3Rpb246bm9ybWFsOy1tcy1mbGV4LWRpcmVjdGlvbjpyb3c7ZmxleC1kaXJlY3Rpb246cm93Oy13ZWJraXQtYm94LXBhY2s6ZW5kOy13ZWJraXQtanVzdGlmeS1jb250ZW50OmZsZXgtZW5kOy1tb3otYm94LXBhY2s6ZW5kOy1tcy1mbGV4LXBhY2s6ZW5kO2p1c3RpZnktY29udGVudDpmbGV4LWVuZH15dGQtbWFzdGhlYWQubWFzdGhlYWQtZmluaXNoICNtYXN0aGVhZC1za2VsZXRvbi1pY29uc3tkaXNwbGF5Om5vbmV9Lm1hc3RoZWFkLXNrZWxldG9uLWljb257Ym9yZGVyLXJhZGl1czo1MCU7aGVpZ2h0OjMycHg7d2lkdGg6MzJweDttYXJnaW46MCA4cHg7YmFja2dyb3VuZC1jb2xvcjojZTNlM2UzfXl0ZC1tYXN0aGVhZC5kYXJrIC5tYXN0aGVhZC1za2VsZXRvbi1pY29ue2JhY2tncm91bmQtY29sb3I6IzI5MjkyOX08L3N0eWxlPjxzdHlsZSBjbGFzcz0ibWFzdGhlYWRfY3VzdG9tX3N0eWxlcyIgaXM9ImN1c3RvbS1zdHlsZSIgaWQ9ImV4dC1zdHlsZXMiIG5vbmNlPSJ3S3F4MjU3MjB1anVtYVV2QkgtVHhRIj46LXN0di1zZXQtZWxzZXdoZXJley0teXQtc3BlYy1pY29uLWFjdGl2ZS1vdGhlcjppbml0aWFsfXl0ZC1tYXN0aGVhZCAueXQtaWNvbnMtZXh0e2NvbG9yOnZhcigtLXl0LXNwZWMtaWNvbi1hY3RpdmUtb3RoZXIpfXl0ZC1tYXN0aGVhZCBzdmcjeXQtbG9nby1yZWQtc3ZnICN5b3V0dWJlLXJlZC1wYXRocyBwYXRoLHl0ZC1tYXN0aGVhZCBzdmcjeXQtbG9nby1yZWQtdXBkYXRlZC1zdmcgI3lvdXR1YmUtcmVkLXBhdGhzIHBhdGgseXRkLW1hc3RoZWFkIHN2ZyN5dC1sb2dvLXN2ZyAjeW91dHViZS1wYXRocyBwYXRoLHl0ZC1tYXN0aGVhZCBzdmcjeXQtbG9nby11cGRhdGVkLXN2ZyAjeW91dHViZS1wYXRocyBwYXRoe2ZpbGw6IzI4MjgyOH15dGQtbWFzdGhlYWQuZGFyayBzdmcjeXQtbG9nby1yZWQtc3ZnICN5b3V0dWJlLXJlZC1wYXRocyBwYXRoLHl0ZC1tYXN0aGVhZC5kYXJrIHN2ZyN5dC1sb2dvLXJlZC11cGRhdGVkLXN2ZyAjeW91dHViZS1yZWQtcGF0aHMgcGF0aCx5dGQtbWFzdGhlYWQuZGFyayBzdmcjeXQtbG9nby1zdmcgI3lvdXR1YmUtcGF0aHMgcGF0aCx5dGQtbWFzdGhlYWQuZGFyayBzdmcjeXQtbG9nby11cGRhdGVkLXN2ZyAjeW91dHViZS1wYXRocyBwYXRoLHl0ZC1tYXN0aGVhZC50aGVhdGVyIHN2ZyN5dC1sb2dvLXJlZC1zdmcgI3lvdXR1YmUtcmVkLXBhdGhzIHBhdGgseXRkLW1hc3RoZWFkLnRoZWF0ZXIgc3ZnI3l0LWxvZ28tc3ZnICN5b3V0dWJlLXBhdGhzIHBhdGh7ZmlsbDojZmZmfTwvc3R5bGU+PHN0eWxlIGNsYXNzPSJzZWFyY2hib3giIG5vbmNlPSJ3S3F4MjU3MjB1anVtYVV2QkgtVHhRIj4jc2VhcmNoLWlucHV0Lnl0ZC1zZWFyY2hib3gtc3B0IGlucHV0ey13ZWJraXQtYXBwZWFyYW5jZTpub25lOy13ZWJraXQtZm9udC1zbW9vdGhpbmc6YW50aWFsaWFzZWQ7YmFja2dyb3VuZC1jb2xvcjp0cmFuc3BhcmVudDtib3JkZXI6bm9uZTtib3gtc2hhZG93Om5vbmU7Y29sb3I6aW5oZXJpdDtmb250LWZhbWlseTpSb2JvdG8sTm90byxzYW5zLXNlcmlmO2ZvbnQtc2l6ZToxNnB4O2ZvbnQtd2VpZ2h0OjQwMDtsaW5lLWhlaWdodDoyNHB4O21hcmdpbi1sZWZ0OjRweDttYXgtd2lkdGg6MTAwJTtvdXRsaW5lOm5vbmU7dGV4dC1hbGlnbjppbmhlcml0O3dpZHRoOjEwMCU7LW1zLWZsZXg6MSAxIDAuMDAwMDAwMDAxcHg7LXdlYmtpdC1mbGV4OjE7LXdlYmtpdC1ib3gtZmxleDoxOy1tb3otYm94LWZsZXg6MTtmbGV4OjE7LXdlYmtpdC1mbGV4LWJhc2lzOjAuMDAwMDAwMDAxcHg7LW1zLWZsZXgtcHJlZmVycmVkLXNpemU6MC4wMDAwMDAwMDFweDtmbGV4LWJhc2lzOjAuMDAwMDAwMDAxcHh9I3NlYXJjaC1jb250YWluZXIueXRkLXNlYXJjaGJveC1zcHR7cG9pbnRlci1ldmVudHM6bm9uZTtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtyaWdodDowO2JvdHRvbTowO2xlZnQ6MH0jc2VhcmNoLWlucHV0Lnl0ZC1zZWFyY2hib3gtc3B0ICNzZWFyY2g6Oi13ZWJraXQtaW5wdXQtcGxhY2Vob2xkZXJ7Y29sb3I6Izg4OH0jc2VhcmNoLWlucHV0Lnl0ZC1zZWFyY2hib3gtc3B0ICNzZWFyY2g6Oi1tb3otaW5wdXQtcGxhY2Vob2xkZXJ7Y29sb3I6Izg4OH0jc2VhcmNoLWlucHV0Lnl0ZC1zZWFyY2hib3gtc3B0ICNzZWFyY2g6LW1zLWlucHV0LXBsYWNlaG9sZGVye2NvbG9yOiM4ODh9PC9zdHlsZT48c3R5bGUgY2xhc3M9Imtldmxhcl9nbG9iYWxfc3R5bGVzIiBub25jZT0id0txeDI1NzIwdWp1bWFVdkJILVR4USI+aHRtbHtiYWNrZ3JvdW5kLWNvbG9yOiNmZmYhaW1wb3J0YW50Oy13ZWJraXQtdGV4dC1zaXplLWFkanVzdDpub25lfWh0bWxbZGFya117YmFja2dyb3VuZC1jb2xvcjojMGYwZjBmIWltcG9ydGFudH0jbG9nby1yZWQtaWNvbi1jb250YWluZXIueXRkLXRvcGJhci1sb2dvLXJlbmRlcmVye3dpZHRoOjg2cHh9PC9zdHlsZT48bWV0YSBuYW1lPSJ0aGVtZS1jb2xvciIgY29udGVudD0icmdiYSgyNTUsIDI1NSwgMjU1LCAwLjk4KSI+PGxpbmsgcmVsPSJzZWFyY2giIHR5cGU9ImFwcGxpY2F0aW9uL29wZW5zZWFyY2hkZXNjcmlwdGlvbit4bWwiIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL29wZW5zZWFyY2g/bG9jYWxlPWZyX0ZSIiB0aXRsZT0iWW91VHViZSI+PGxpbmsgcmVsPSJtYW5pZmVzdCIgaHJlZj0iL21hbmlmZXN0LndlYm1hbmlmZXN0IiBjcm9zc29yaWdpbj0idXNlLWNyZWRlbnRpYWxzIj48L2hlYWQ+PGJvZHkgZGlyPSJsdHIiPjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnYnMnLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPnl0Y2ZnLnNldCgnaW5pdGlhbEJvZHlDbGllbnRXaWR0aCcsIGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGgpOzwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnYWknLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxpZnJhbWUgbmFtZT0icGFzc2l2ZV9zaWduaW4iIHNyYz0iaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tL1NlcnZpY2VMb2dpbj9zZXJ2aWNlPXlvdXR1YmUmYW1wO3VpbGVsPTMmYW1wO3Bhc3NpdmU9dHJ1ZSZhbXA7Y29udGludWU9aHR0cHMlM0ElMkYlMkZ3d3cueW91dHViZS5jb20lMkZzaWduaW4lM0ZhY3Rpb25faGFuZGxlX3NpZ25pbiUzRHRydWUlMjZhcHAlM0RkZXNrdG9wJTI2aGwlM0RmciUyNm5leHQlM0QlMjUyRnNpZ25pbl9wYXNzaXZlJTI2ZmVhdHVyZSUzRHBhc3NpdmUmYW1wO2hsPWZyIiBzdHlsZT0iZGlzcGxheTogbm9uZSI+PC9pZnJhbWU+PHl0ZC1hcHA+PHl0ZC1tYXN0aGVhZCBpZD0ibWFzdGhlYWQiIGxvZ28tdHlwZT0iWU9VVFVCRV9MT0dPIiBzbG90PSJtYXN0aGVhZCIgY2xhc3M9InNoZWxsICI+PGRpdiBpZD0ic2VhcmNoLWNvbnRhaW5lciIgY2xhc3M9Inl0ZC1zZWFyY2hib3gtc3B0IiBzbG90PSJzZWFyY2gtY29udGFpbmVyIj48L2Rpdj48ZGl2IGlkPSJzZWFyY2gtaW5wdXQiIGNsYXNzPSJ5dGQtc2VhcmNoYm94LXNwdCIgc2xvdD0ic2VhcmNoLWlucHV0Ij48aW5wdXQgaWQ9InNlYXJjaCIgYXV0b2NhcGl0YWxpemU9Im5vbmUiIGF1dG9jb21wbGV0ZT0ib2ZmIiBhdXRvY29ycmVjdD0ib2ZmIiBoaWRkZW4gbmFtZT0ic2VhcmNoX3F1ZXJ5IiB0YWJpbmRleD0iMCIgdHlwZT0idGV4dCIgc3BlbGxjaGVjaz0iZmFsc2UiPjwvZGl2PjxzdmcgaWQ9Im1lbnUtaWNvbiIgY2xhc3M9ImV4dGVybmFsLWljb24iIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiPjxnIGlkPSJtZW51IiBjbGFzcz0ieXQtaWNvbnMtZXh0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik0yMSw2SDNWNWgxOFY2eiBNMjEsMTFIM3YxaDE4VjExeiBNMjEsMTdIM3YxaDE4VjE3eiIvPjwvZz48L3N2Zz48ZGl2IGlkPSJtYXN0aGVhZC1sb2dvIiBzbG90PSJtYXN0aGVhZC1sb2dvIj48YSBzdHlsZT0iZGlzcGxheTogbm9uZTsiIGhyZWY9Ii8iIHRpdGxlPSJZb3VUdWJlIj48c3ZnIGlkPSJ5dC1sb2dvLXVwZGF0ZWQtc3ZnIiBjbGFzcz0iZXh0ZXJuYWwtaWNvbiIgdmlld0JveD0iMCAwIDkwIDIwIj48ZyBpZD0ieXQtbG9nby11cGRhdGVkIiB2aWV3Qm94PSIwIDAgOTAgMjAiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiPjxnPjxwYXRoIGQ9Ik0yNy45NzI3IDMuMTIzMjRDMjcuNjQzNSAxLjg5MzIzIDI2LjY3NjggMC45MjY2MjMgMjUuNDQ2OCAwLjU5NzM2NkMyMy4yMTk3IDIuMjQyODhlLTA3IDE0LjI4NSAwIDE0LjI4NSAwQzE0LjI4NSAwIDUuMzUwNDIgMi4yNDI4OGUtMDcgMy4xMjMyMyAwLjU5NzM2NkMxLjg5MzIzIDAuOTI2NjIzIDAuOTI2NjIzIDEuODkzMjMgMC41OTczNjYgMy4xMjMyNEMyLjI0Mjg4ZS0wNyA1LjM1MDQyIDAgMTAgMCAxMEMwIDEwIDIuMjQyODhlLTA3IDE0LjY0OTYgMC41OTczNjYgMTYuODc2OEMwLjkyNjYyMyAxOC4xMDY4IDEuODkzMjMgMTkuMDczNCAzLjEyMzIzIDE5LjQwMjZDNS4zNTA0MiAyMCAxNC4yODUgMjAgMTQuMjg1IDIwQzE0LjI4NSAyMCAyMy4yMTk3IDIwIDI1LjQ0NjggMTkuNDAyNkMyNi42NzY4IDE5LjA3MzQgMjcuNjQzNSAxOC4xMDY4IDI3Ljk3MjcgMTYuODc2OEMyOC41NzAxIDE0LjY0OTYgMjguNTcwMSAxMCAyOC41NzAxIDEwQzI4LjU3MDEgMTAgMjguNTY3NyA1LjM1MDQyIDI3Ljk3MjcgMy4xMjMyNFoiIGZpbGw9IiNGRjAwMDAiLz48cGF0aCBkPSJNMTEuNDI1MyAxNC4yODU0TDE4Ljg0NzcgMTAuMDAwNEwxMS40MjUzIDUuNzE1MzNWMTQuMjg1NFoiIGZpbGw9IndoaXRlIi8+PC9nPjxnPjxnIGlkPSJ5b3V0dWJlLXBhdGhzIj48cGF0aCBkPSJNMzQuNjAyNCAxMy4wMDM2TDMxLjM5NDUgMS40MTg0NkgzNC4xOTMyTDM1LjMxNzQgNi42NzAxQzM1LjYwNDMgNy45NjM2MSAzNS44MTM2IDkuMDY2NjIgMzUuOTUgOS45NzkxM0gzNi4wMzIzQzM2LjEyNjQgOS4zMjUzMiAzNi4zMzgxIDguMjI5MzcgMzYuNjY1IDYuNjg4OTJMMzcuODI5MSAxLjQxODQ2SDQwLjYyNzhMMzcuMzc5OSAxMy4wMDM2VjE4LjU2MUgzNC42MDAxVjEzLjAwMzZIMzQuNjAyNFoiLz48cGF0aCBkPSJNNDEuNDY5NyAxOC4xOTM3QzQwLjkwNTMgMTcuODEyNyA0MC41MDMxIDE3LjIyIDQwLjI2MzIgMTYuNDE1N0M0MC4wMjU3IDE1LjYxMTQgMzkuOTA1OCAxNC41NDM3IDM5LjkwNTggMTMuMjA3OFYxMS4zODk4QzM5LjkwNTggMTAuMDQyMiA0MC4wNDIyIDguOTU4MDUgNDAuMzE1IDguMTQxOTZDNDAuNTg3OCA3LjMyNTg4IDQxLjAxMzUgNi43Mjg1MSA0MS41OTIgNi4zNTQ1N0M0Mi4xNzA2IDUuOTgwNjMgNDIuOTMwMiA1Ljc5MjQ4IDQzLjg3MSA1Ljc5MjQ4QzQ0Ljc5NzYgNS43OTI0OCA0NS41Mzg0IDUuOTgyOTggNDYuMDk4MSA2LjM2Mzk4QzQ2LjY1NTUgNi43NDQ5NyA0Ny4wNjQ3IDcuMzQyMzQgNDcuMzIzNCA4LjE1MTM3QzQ3LjU4MjEgOC45NjI3NSA0Ny43MTE1IDEwLjA0MjIgNDcuNzExNSAxMS4zODk4VjEzLjIwNzhDNDcuNzExNSAxNC41NDM3IDQ3LjU4NDUgMTUuNjE2MSA0Ny4zMzI5IDE2LjQyNTFDNDcuMDgxMiAxNy4yMzY1IDQ2LjY3MiAxNy44MjkyIDQ2LjEwNzUgMTguMjAzMUM0NS41NDMxIDE4LjU3NzEgNDQuNzc2NCAxOC43NjUyIDQzLjgwOTggMTguNzY1MkM0Mi44MTI2IDE4Ljc2NzUgNDIuMDM0MiAxOC41NzQ3IDQxLjQ2OTcgMTguMTkzN1pNNDQuNjM1MyAxNi4yMzIzQzQ0Ljc5MDUgMTUuODIzMSA0NC44NzA1IDE1LjE1NzUgNDQuODcwNSAxNC4yMzA5VjEwLjMyOTJDNDQuODcwNSA5LjQzMDc3IDQ0Ljc5MjkgOC43NzIyNSA0NC42MzUzIDguMzU4MzNDNDQuNDc3NyA3Ljk0MjA2IDQ0LjIwMjYgNy43MzUxIDQzLjgwNzQgNy43MzUxQzQzLjQyNjUgNy43MzUxIDQzLjE1NiA3Ljk0MjA2IDQzLjAwMDggOC4zNTgzM0M0Mi44NDMyIDguNzc0NjEgNDIuNzY1NiA5LjQzMDc3IDQyLjc2NTYgMTAuMzI5MlYxNC4yMzA5QzQyLjc2NTYgMTUuMTU3NSA0Mi44NDA4IDE1LjgyNTQgNDIuOTkxNCAxNi4yMzIzQzQzLjE0MTkgMTYuNjQxNSA0My40MTIzIDE2Ljg0NjEgNDMuODA3NCAxNi44NDYxQzQ0LjIwMjYgMTYuODQ2MSA0NC40Nzc3IDE2LjY0MTUgNDQuNjM1MyAxNi4yMzIzWiIvPjxwYXRoIGQ9Ik01Ni44MTU0IDE4LjU2MzRINTQuNjA5NEw1NC4zNjQ4IDE3LjAzSDU0LjMwMzdDNTMuNzAzOSAxOC4xODcxIDUyLjgwNTUgMTguNzY1NiA1MS42MDYxIDE4Ljc2NTZDNTAuNzc1OSAxOC43NjU2IDUwLjE2MjEgMTguNDkyOCA0OS43NjcgMTcuOTQ5NkM0OS4zNzE5IDE3LjQwMzkgNDkuMTc0MyAxNi41NTI2IDQ5LjE3NDMgMTUuMzk1NVY2LjAzNzUxSDUxLjk5NDJWMTUuMjMwOEM1MS45OTQyIDE1Ljc5MDYgNTIuMDU1MyAxNi4xODggNTIuMTc3NiAxNi40MjU2QzUyLjI5OTkgMTYuNjYzMSA1Mi41MDQ1IDE2Ljc4MyA1Mi43OTE0IDE2Ljc4M0M1My4wMzYgMTYuNzgzIDUzLjI3MTIgMTYuNzA3OCA1My40OTcgMTYuNTU3M0M1My43MjI4IDE2LjQwNjcgNTMuODg3NCAxNi4yMTYyIDUzLjk5NzkgMTUuOTg1OFY2LjAzNTE2SDU2LjgxNTRWMTguNTYzNFoiLz48cGF0aCBkPSJNNjQuNDc1NSAzLjY4NzU4SDYxLjY3NjhWMTguNTYyOUg1OC45MTgxVjMuNjg3NThINTYuMTE5NFYxLjQyMDQxSDY0LjQ3NTVWMy42ODc1OFoiLz48cGF0aCBkPSJNNzEuMjc2OCAxOC41NjM0SDY5LjA3MDhMNjguODI2MiAxNy4wM0g2OC43NjUxQzY4LjE2NTQgMTguMTg3MSA2Ny4yNjcgMTguNzY1NiA2Ni4wNjc1IDE4Ljc2NTZDNjUuMjM3MyAxOC43NjU2IDY0LjYyMzUgMTguNDkyOCA2NC4yMjg0IDE3Ljk0OTZDNjMuODMzMyAxNy40MDM5IDYzLjYzNTcgMTYuNTUyNiA2My42MzU3IDE1LjM5NTVWNi4wMzc1MUg2Ni40NTU2VjE1LjIzMDhDNjYuNDU1NiAxNS43OTA2IDY2LjUxNjcgMTYuMTg4IDY2LjYzOSAxNi40MjU2QzY2Ljc2MTMgMTYuNjYzMSA2Ni45NjU5IDE2Ljc4MyA2Ny4yNTI5IDE2Ljc4M0M2Ny40OTc0IDE2Ljc4MyA2Ny43MzI2IDE2LjcwNzggNjcuOTU4NCAxNi41NTczQzY4LjE4NDIgMTYuNDA2NyA2OC4zNDg4IDE2LjIxNjIgNjguNDU5MyAxNS45ODU4VjYuMDM1MTZINzEuMjc2OFYxOC41NjM0WiIvPjxwYXRoIGQ9Ik04MC42MDkgOC4wMzg3QzgwLjQzNzMgNy4yNDg0OSA4MC4xNjIxIDYuNjc2OTkgNzkuNzgxMiA2LjMyMTg2Qzc5LjQwMDIgNS45NjY3NCA3OC44NzU3IDUuNzkwMzUgNzguMjA3OCA1Ljc5MDM1Qzc3LjY5MDQgNS43OTAzNSA3Ny4yMDU5IDUuOTM2MTYgNzYuNzU2NyA2LjIzMDE0Qzc2LjMwNzUgNi41MjQxMiA3NS45NTk0IDYuOTA3NDcgNzUuNzE0OCA3LjM4NDg5SDc1LjY5MzdWMC43ODU2NDVINzIuOTc3M1YxOC41NjA4SDc1LjMwNTZMNzUuNTkyNSAxNy4zNzU1SDc1LjY1MzdDNzUuODcyNCAxNy43OTg4IDc2LjE5OTMgMTguMTMwNCA3Ni42MzQ0IDE4LjM3NzRDNzcuMDY5NSAxOC42MjIgNzcuNTU0IDE4Ljc0NDMgNzguMDg1NSAxOC43NDQzQzc5LjAzOCAxOC43NDQzIDc5Ljc0MTIgMTguMzA0NSA4MC4xOTA0IDE3LjQyNzJDODAuNjM5NiAxNi41NDc2IDgwLjg2NTMgMTUuMTc2NSA4MC44NjUzIDEzLjMwOTJWMTEuMzI2NkM4MC44NjUzIDkuOTI3MjIgODAuNzc4MyA4LjgyODkyIDgwLjYwOSA4LjAzODdaTTc4LjAyNDMgMTMuMTQ5MkM3OC4wMjQzIDE0LjA2MTcgNzcuOTg2NyAxNC43NzY3IDc3LjkxMTQgMTUuMjk0MUM3Ny44MzYyIDE1LjgxMTUgNzcuNzExNSAxNi4xODA4IDc3LjUzMjggMTYuMzk3MUM3Ny4zNTY0IDE2LjYxNTggNzcuMTE2NSAxNi43MjQgNzYuODE3OCAxNi43MjRDNzYuNTg1IDE2LjcyNCA3Ni4zNzEgMTYuNjY5OSA3Ni4xNzM0IDE2LjU1OTRDNzUuOTc1OSAxNi40NTEyIDc1LjgxNiAxNi4yODY2IDc1LjY5MzcgMTYuMDcwMlY4Ljk2MDYyQzc1Ljc4NzcgOC42MTk2IDc1Ljk1MjQgOC4zNDIwOSA3Ni4xODUyIDguMTIzMzdDNzYuNDE1NyA3LjkwNDY1IDc2LjY2OTcgNy43OTY0NiA3Ni45NDAxIDcuNzk2NDZDNzcuMjI3MSA3Ljc5NjQ2IDc3LjQ0ODEgNy45MDkzNSA3Ny42MDM0IDguMTMyNzhDNzcuNzYwOSA4LjM1ODU1IDc3Ljg2OTEgOC43MzQ4NSA3Ny45MzAzIDkuMjY2MzZDNzcuOTkxNCA5Ljc5Nzg3IDc4LjAyMiAxMC41NTI4IDc4LjAyMiAxMS41MzM1VjEzLjE0OTJINzguMDI0M1oiLz48cGF0aCBkPSJNODQuODY1NyAxMy44NzEyQzg0Ljg2NTcgMTQuNjc1NSA4NC44ODkyIDE1LjI3NzYgODQuOTM2MyAxNS42Nzk4Qzg0Ljk4MzMgMTYuMDgxOSA4NS4wODIxIDE2LjM3MzYgODUuMjMyNiAxNi41NTk0Qzg1LjM4MzEgMTYuNzQyOCA4NS42MTM2IDE2LjgzNDUgODUuOTI2NCAxNi44MzQ1Qzg2LjM0NzQgMTYuODM0NSA4Ni42MzkgMTYuNjY5OSA4Ni43OTQyIDE2LjM0M0M4Ni45NTE4IDE2LjAxNjEgODcuMDM2NSAxNS40NzA1IDg3LjA1MDYgMTQuNzA4NUw4OS40ODI0IDE0Ljg1MTlDODkuNDk2NSAxNC45NjAxIDg5LjUwMzUgMTUuMTEwNiA4OS41MDM1IDE1LjMwMTFDODkuNTAzNSAxNi40NTgyIDg5LjE4NiAxNy4zMjM3IDg4LjU1MzQgMTcuODk1MkM4Ny45MjA4IDE4LjQ2NjcgODcuMDI0NyAxOC43NTM2IDg1Ljg2NzYgMTguNzUzNkM4NC40Nzc3IDE4Ljc1MzYgODMuNTA0IDE4LjMxODUgODIuOTQ2NiAxNy40NDZDODIuMzg2OSAxNi41NzM1IDgyLjEwOTQgMTUuMjI1OSA4Mi4xMDk0IDEzLjQwMDhWMTEuMjEzNkM4Mi4xMDk0IDkuMzM0NTIgODIuMzk4NyA3Ljk2MTA1IDgyLjk3NzIgNy4wOTU1OEM4My41NTU4IDYuMjMwMSA4NC41NDU5IDUuNzk3MzYgODUuOTQ5OSA1Ljc5NzM2Qzg2LjkxNjUgNS43OTczNiA4Ny42NTk3IDUuOTczNzUgODguMTc3MSA2LjMyODg4Qzg4LjY5NDUgNi42ODQgODkuMDU5IDcuMjM0MzMgODkuMjcwNyA3Ljk4NDU3Qzg5LjQ4MjQgOC43MzQ4IDg5LjU4ODIgOS43Njk2MSA4OS41ODgyIDExLjA5MTNWMTMuMjM2Mkg4NC44NjU3VjEzLjg3MTJaTTg1LjIyMzIgNy45NjgxMUM4NS4wNzk3IDguMTQ0NDkgODQuOTg1NyA4LjQzMzc3IDg0LjkzNjMgOC44MzU5M0M4NC44ODkyIDkuMjM4MSA4NC44NjU3IDkuODQ3MjIgODQuODY1NyAxMC42NjU3VjExLjU2NDFIODYuOTI4M1YxMC42NjU3Qzg2LjkyODMgOS44NjEzMyA4Ni45MDAxIDkuMjUyMjEgODYuODQ2IDguODM1OTNDODYuNzkxOSA4LjQxOTY2IDg2LjY5MzEgOC4xMjgwMyA4Ni41NDk2IDcuOTU2MzVDODYuNDA2MiA3Ljc4NzAyIDg2LjE4NTEgNy43IDg1Ljg4NjQgNy43Qzg1LjU4NTQgNy43MDIzNSA4NS4zNjQzIDcuNzkxNzIgODUuMjIzMiA3Ljk2ODExWiIvPjwvZz48L2c+PC9nPjwvc3ZnPjwvYT48YSBzdHlsZT0iZGlzcGxheTogbm9uZTsiIGhyZWY9Ii8iIHRpdGxlPSJZb3VUdWJlIj48c3ZnIGlkPSJ5dC1sb2dvLXJlZC11cGRhdGVkLXN2ZyIgY2xhc3M9ImV4dGVybmFsLWljb24iIHZpZXdCb3g9IjAgMCA5NyAyMCIgc3R5bGU9IndpZHRoOiA5N3B4OyI+PGcgaWQ9Inl0LWxvZ28tcmVkLXVwZGF0ZWQiIHZpZXdCb3g9IjAgMCA5NyAyMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQgbWVldCI+PGc+PHBhdGggZD0iTTI3Ljk3MDQgMy4xMjMyNEMyNy42NDExIDEuODkzMjMgMjYuNjc0NSAwLjkyNjYyMyAyNS40NDQ1IDAuNTk3MzY2QzIzLjIxNzMgMi4yNDI4OGUtMDcgMTQuMjgyNyAwIDE0LjI4MjcgMEMxNC4yODI3IDAgNS4zNDgwNyAyLjI0Mjg4ZS0wNyAzLjEyMDg4IDAuNTk3MzY2QzEuODkzMjMgMC45MjY2MjMgMC45MjQyNzEgMS44OTMyMyAwLjU5NTAxNCAzLjEyMzI0Qy0yLjgwMzZlLTA3IDUuMzUwNDIgMCAxMCAwIDEwQzAgMTAgLTEuNTcwMDJlLTA2IDE0LjY0OTYgMC41OTczNjQgMTYuODc2OEMwLjkyNjYyMSAxOC4xMDY4IDEuODkzMjMgMTkuMDczNCAzLjEyMzI0IDE5LjQwMjZDNS4zNTA0MiAyMCAxNC4yODUgMjAgMTQuMjg1IDIwQzE0LjI4NSAyMCAyMy4yMTk3IDIwIDI1LjQ0NjggMTkuNDAyNkMyNi42NzY5IDE5LjA3MzQgMjcuNjQzNSAxOC4xMDY4IDI3Ljk3MjcgMTYuODc2OEMyOC41NzAxIDE0LjY0OTYgMjguNTcwMSAxMCAyOC41NzAxIDEwQzI4LjU3MDEgMTAgMjguNTY3NyA1LjM1MDQyIDI3Ljk3MDQgMy4xMjMyNFoiIGZpbGw9IiNGRjAwMDAiLz48cGF0aCBkPSJNMTEuNDI3NSAxNC4yODU0TDE4Ljg0NzUgMTAuMDAwNEwxMS40Mjc1IDUuNzE1MzNWMTQuMjg1NFoiIGZpbGw9IndoaXRlIi8+PC9nPjxnIGlkPSJ5b3V0dWJlLXJlZC1wYXRocyI+PHBhdGggZD0iTTQwLjA1NjYgNi4zNDUyNFY3LjAzNjY4QzQwLjA1NjYgMTAuNDkxNSAzOC41MjU1IDEyLjUxMTggMzUuMTc0MiAxMi41MTE4SDM0LjY2MzhWMTguNTU4M0gzMS45MjYzVjEuNDIyODVIMzUuNDE0QzM4LjYwNzggMS40MjI4NSA0MC4wNTY2IDIuNzcyOCA0MC4wNTY2IDYuMzQ1MjRaTTM3LjE3NzkgNi41OTIxOEMzNy4xNzc5IDQuMDk5MjQgMzYuNzI4NyAzLjUwNjU4IDM1LjE3NjUgMy41MDY1OEgzNC42NjYyVjEwLjQ3MjdIMzUuMTM2NUMzNi42MDY0IDEwLjQ3MjcgMzcuMTgwMyA5LjQwOTY4IDM3LjE4MDMgNy4xMDI1M0wzNy4xNzc5IDYuNTkyMThaIi8+PHBhdGggZD0iTTQ2LjUzMzYgNS44MzQ1TDQ2LjM5MDEgOS4wODIzOEM0NS4yMjU5IDguODM3NzkgNDQuMjY0IDkuMDIxMjMgNDMuODM2IDkuNzczODJWMTguNTU3OUg0MS4xMTk2VjYuMDM5MUg0My4yODU3TDQzLjUzMDMgOC43NTMxMkg0My42MzM3QzQzLjkxODMgNi43NzI4OCA0NC44Mzc5IDUuNzcxIDQ2LjAyMzIgNS43NzFDNDYuMTk0OSA1Ljc3NTcgNDYuMzY2NiA1Ljc5Njg3IDQ2LjUzMzYgNS44MzQ1WiIvPjxwYXRoIGQ9Ik00OS42NTY3IDEzLjI0NTZWMTMuODc4MkM0OS42NTY3IDE2LjA4NDIgNDkuNzc5IDE2Ljg0MTUgNTAuNzE5OCAxNi44NDE1QzUxLjYxODIgMTYuODQxNSA1MS44MjI4IDE2LjE1MDEgNTEuODQzOSAxNC43MTc4TDU0LjI3MzQgMTQuODYxM0M1NC40NTY4IDE3LjU1NjUgNTMuMDQ4MSAxOC43NjMgNTAuNjU4NiAxOC43NjNDNDcuNzU4OCAxOC43NjMgNDYuOTAwNCAxNi44NjI3IDQ2LjkwMDQgMTMuNDEyNlYxMS4yMjNDNDYuOTAwNCA3LjU4NzA3IDQ3Ljg1OTkgNS44MDkwOCA1MC43NDA5IDUuODA5MDhDNTMuNjQwNyA1LjgwOTA4IDU0LjM3NjkgNy4zMjEzMSA1NC4zNzY5IDExLjA5ODRWMTMuMjQ1Nkg0OS42NTY3Wk00OS42NTY3IDEwLjY3MDNWMTEuNTY4N0g1MS43MTkzVjEwLjY3NUM1MS43MTkzIDguMzcyNTggNTEuNTU0NyA3LjcxMTcyIDUwLjY4MjEgNy43MTE3MkM0OS44MDk2IDcuNzExNzIgNDkuNjU2NyA4LjM4NjY5IDQ5LjY1NjcgMTAuNjc1VjEwLjY3MDNaIi8+PHBhdGggZD0iTTY4LjQxMDMgOS4wOTkwMlYxOC41NTU3SDY1LjU5MjhWOS4zMDgzNEM2NS41OTI4IDguMjg3NjQgNjUuMzI3IDcuNzc3MjkgNjQuNzEzMiA3Ljc3NzI5QzY0LjIyMTYgNy43NzcyOSA2My43NzI0IDguMDYxODYgNjMuNDY2NyA4LjU5MzM4QzYzLjQ4MzIgOC43NjI3MSA2My40OTAyIDguOTM0MzkgNjMuNDg3OSA5LjEwMzczVjE4LjU2MDVINjAuNjY4VjkuMzA4MzRDNjAuNjY4IDguMjg3NjQgNjAuNDAyMiA3Ljc3NzI5IDU5Ljc4ODQgNy43NzcyOUM1OS4yOTY5IDcuNzc3MjkgNTguODY2NSA4LjA2MTg2IDU4LjU2MzEgOC41NzQ1NlYxOC41NjI4SDU1Ljc0NTZWNi4wMzkyOUg1Ny45NzI4TDU4LjIyMjEgNy42MzM4M0g1OC4yNjIxQzU4Ljg5NDcgNi40Mjk2OSA1OS45MTc4IDUuNzc1ODggNjEuMTIxOSA1Ljc3NTg4QzYyLjMwNzIgNS43NzU4OCA2Mi45Nzk5IDYuMzY4NTQgNjMuMjg4IDcuNDMxNTdDNjMuOTQxOCA2LjM0OTczIDY0LjkyMjUgNS43NzU4OCA2Ni4wNDQzIDUuNzc1ODhDNjcuNzU2NCA1Ljc3NTg4IDY4LjQxMDMgNy4wMDExOSA2OC40MTAzIDkuMDk5MDJaIi8+PHBhdGggZD0iTTY5LjgxOTEgMi44MzM4QzY5LjgxOTEgMS40ODYyIDcwLjMxMDYgMS4wOTgxNCA3MS4zNTAxIDEuMDk4MTRDNzIuNDEzMiAxLjA5ODE0IDcyLjg4MTIgMS41NDczNCA3Mi44ODEyIDIuODMzOEM3Mi44ODEyIDQuMjIzNzMgNzIuNDEwOCA0LjU3MTgxIDcxLjM1MDEgNC41NzE4MUM3MC4zMTA2IDQuNTY5NDUgNjkuODE5MSA0LjIyMTM4IDY5LjgxOTEgMi44MzM4Wk02OS45ODM3IDYuMDM5MzVINzIuNjc4OVYxOC41NjI5SDY5Ljk4MzdWNi4wMzkzNVoiLz48cGF0aCBkPSJNODEuODkxIDYuMDM5NTVWMTguNTYzMUg3OS42ODQ5TDc5LjQ0MDMgMTcuMDMySDc5LjM3OTJDNzguNzQ2NiAxOC4yNTczIDc3LjgyNyAxOC43Njc3IDc2LjY4NCAxOC43Njc3Qzc1LjAwOTUgMTguNzY3NyA3NC4yNTIyIDE3LjcwNDYgNzQuMjUyMiAxNS4zOTc1VjYuMDQxOUg3Ny4wNjk3VjE1LjIzNTJDNzcuMDY5NyAxNi4zMzgyIDc3LjMwMDIgMTYuNzg3NCA3Ny44NjcgMTYuNzg3NEM3OC4zODQ0IDE2Ljc2NjMgNzguODQ3NyAxNi40NTgyIDc5LjA2ODggMTUuOTkwMlY2LjA0MTlIODEuODkxVjYuMDM5NTVaIi8+PHBhdGggZD0iTTk2LjE5MDEgOS4wOTg5M1YxOC41NTU3SDkzLjM3MjZWOS4zMDgyNUM5My4zNzI2IDguMjg3NTUgOTMuMTA2OCA3Ljc3NzIgOTIuNDkzIDcuNzc3MkM5Mi4wMDE1IDcuNzc3MiA5MS41NTIzIDguMDYxNzcgOTEuMjQ2NSA4LjU5MzI5QzkxLjI2MyA4Ljc2MDI3IDkxLjI3MDEgOC45Mjk2IDkxLjI2NzcgOS4wOTg5M1YxOC41NTU3SDg4LjQ1MDJWOS4zMDgyNUM4OC40NTAyIDguMjg3NTUgODguMTg0NSA3Ljc3NzIgODcuNTcwNiA3Ljc3NzJDODcuMDc5MSA3Ljc3NzIgODYuNjQ4NyA4LjA2MTc3IDg2LjM0NTMgOC41NzQ0N1YxOC41NjI3SDgzLjUyNzhWNi4wMzkySDg1Ljc1MjdMODUuOTk3MyA3LjYzMTM5SDg2LjAzNzJDODYuNjY5OSA2LjQyNzI1IDg3LjY5MjkgNS43NzM0NCA4OC44OTcxIDUuNzczNDRDOTAuMDgyNCA1Ljc3MzQ0IDkwLjc1NSA2LjM2NjEgOTEuMDYzMSA3LjQyOTEzQzkxLjcxNjkgNi4zNDcyOSA5Mi42OTc2IDUuNzczNDQgOTMuODE5NCA1Ljc3MzQ0Qzk1LjU0MSA1Ljc3NTc5IDk2LjE5MDEgNy4wMDExIDk2LjE5MDEgOS4wOTg5M1oiLz48cGF0aCBkPSJNNDAuMDU2NiA2LjM0NTI0VjcuMDM2NjhDNDAuMDU2NiAxMC40OTE1IDM4LjUyNTUgMTIuNTExOCAzNS4xNzQyIDEyLjUxMThIMzQuNjYzOFYxOC41NTgzSDMxLjkyNjNWMS40MjI4NUgzNS40MTRDMzguNjA3OCAxLjQyMjg1IDQwLjA1NjYgMi43NzI4IDQwLjA1NjYgNi4zNDUyNFpNMzcuMTc3OSA2LjU5MjE4QzM3LjE3NzkgNC4wOTkyNCAzNi43Mjg3IDMuNTA2NTggMzUuMTc2NSAzLjUwNjU4SDM0LjY2NjJWMTAuNDcyN0gzNS4xMzY1QzM2LjYwNjQgMTAuNDcyNyAzNy4xODAzIDkuNDA5NjggMzcuMTgwMyA3LjEwMjUzTDM3LjE3NzkgNi41OTIxOFoiLz48L2c+PC9nPjwvc3ZnPjwvYT48c3BhbiBpZD0iY291bnRyeS1jb2RlIj48L3NwYW4+PC9kaXY+PGRpdiBpZD0ibWFzdGhlYWQtc2tlbGV0b24taWNvbnMiIHNsb3Q9Im1hc3RoZWFkLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJtYXN0aGVhZC1za2VsZXRvbi1pY29uIj48L2Rpdj48ZGl2IGNsYXNzPSJtYXN0aGVhZC1za2VsZXRvbi1pY29uIj48L2Rpdj48ZGl2IGNsYXNzPSJtYXN0aGVhZC1za2VsZXRvbi1pY29uIj48L2Rpdj48ZGl2IGNsYXNzPSJtYXN0aGVhZC1za2VsZXRvbi1pY29uIj48L2Rpdj48L2Rpdj48L3l0ZC1tYXN0aGVhZD48YSBzbG90PSJndWlkZS1saW5rcy1wcmltYXJ5IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9hYm91dC8iIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+UHLDqXNlbnRhdGlvbjwvYT48YSBzbG90PSJndWlkZS1saW5rcy1wcmltYXJ5IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9hYm91dC9wcmVzcy8iIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+UHJlc3NlPC9hPjxhIHNsb3Q9Imd1aWRlLWxpbmtzLXByaW1hcnkiIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2Fib3V0L2NvcHlyaWdodC8iIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+RHJvaXRzIGQmIzM5O2F1dGV1cjwvYT48YSBzbG90PSJndWlkZS1saW5rcy1wcmltYXJ5IiBocmVmPSIvdC9jb250YWN0X3VzLyIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij5Ob3VzIGNvbnRhY3RlcjwvYT48YSBzbG90PSJndWlkZS1saW5rcy1wcmltYXJ5IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jcmVhdG9ycy8iIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+Q3LDqWF0ZXVyczwvYT48YSBzbG90PSJndWlkZS1saW5rcy1wcmltYXJ5IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9hZHMvIiBzdHlsZT0iZGlzcGxheTogbm9uZTsiPlB1YmxpY2l0w6k8L2E+PGEgc2xvdD0iZ3VpZGUtbGlua3MtcHJpbWFyeSIgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20veW91dHViZSIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij5Ew6l2ZWxvcHBldXJzPC9hPjxhIHNsb3Q9Imd1aWRlLWxpbmtzLXByaW1hcnkiIGhyZWY9Imh0dHBzOi8vc3VwcG9ydC5nb29nbGUuY29tL3lvdXR1YmUvY29udGFjdC9GUl9Db21wbGFpbnRzIiBzdHlsZT0iZGlzcGxheTogbm9uZTsiPlNpZ25hbGV6IHVuIGNvbnRlbnUgaGFpbmV1eCBjb25mb3Jtw6ltZW50IMOgIGxhIExDRU48L2E+PGEgc2xvdD0iZ3VpZGUtbGlua3Mtc2Vjb25kYXJ5IiBocmVmPSIvdC90ZXJtcyIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij5Db25kaXRpb25zIGQmIzM5O3V0aWxpc2F0aW9uPC9hPjxhIHNsb3Q9Imd1aWRlLWxpbmtzLXNlY29uZGFyeSIgaHJlZj0iL3QvcHJpdmFjeSIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij5Db25maWRlbnRpYWxpdMOpPC9hPjxhIHNsb3Q9Imd1aWRlLWxpbmtzLXNlY29uZGFyeSIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vYWJvdXQvcG9saWNpZXMvIiBzdHlsZT0iZGlzcGxheTogbm9uZTsiPlLDqGdsZXMgZXQgc8OpY3VyaXTDqTwvYT48YSBzbG90PSJndWlkZS1saW5rcy1zZWNvbmRhcnkiIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2hvd3lvdXR1YmV3b3Jrcz91dG1fY2FtcGFpZ249eXRnZW4mYW1wO3V0bV9zb3VyY2U9eXRocCZhbXA7dXRtX21lZGl1bT1MZWZ0TmF2JmFtcDt1dG1fY29udGVudD10eHQmYW1wO3U9aHR0cHMlM0ElMkYlMkZ3d3cueW91dHViZS5jb20lMkZob3d5b3V0dWJld29ya3MlM0Z1dG1fc291cmNlJTNEeXRocCUyNnV0bV9tZWRpdW0lM0RMZWZ0TmF2JTI2dXRtX2NhbXBhaWduJTNEeXRnZW4iIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+UHJlbWllcnMgcGFzIHN1ciBZb3VUdWJlPC9hPjxhIHNsb3Q9Imd1aWRlLWxpbmtzLXNlY29uZGFyeSIgaHJlZj0iL25ldyIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij5UZXN0ZXIgZGUgbm91dmVsbGVzIGZvbmN0aW9ubmFsaXTDqXM8L2E+PGRpdiBpZD0iY29weXJpZ2h0IiBzbG90PSJjb3B5cmlnaHQiIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+PGRpdiBkaXI9Imx0ciIgc3R5bGU9ImRpc3BsYXk6aW5saW5lIj4mY29weTsgMjAyMyBHb29nbGUgTExDPC9kaXY+PC9kaXY+PC95dGQtYXBwPjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnbmNfcGonLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygncnNiZV9kcGonLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnanNfbGQnLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgaWQ9ImJhc2UtanMiIHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL2Rlc2t0b3BfcG9seW1lcl9lbmFibGVfd2lsX2ljb25zLnZmbHNldC9kZXNrdG9wX3BvbHltZXJfZW5hYmxlX3dpbF9pY29ucy5qcyIgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPjwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygncnNlZl9kcGonLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygncnNhZV9kcGonLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnanNfcicsIG51bGwsICcnKTt9PC9zY3JpcHQ+PHNjcmlwdCBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+aWYgKHdpbmRvdy55dGNzaSkge3dpbmRvdy55dGNzaS50aWNrKCdhYycsIG51bGwsICcnKTt9PC9zY3JpcHQ+PHNjcmlwdCBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+dmFyIG9uUG9seW1lclJlYWR5ID0gZnVuY3Rpb24oZSkge3dpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JpcHQtbG9hZC1kcGonLCBvblBvbHltZXJSZWFkeSk7aWYgKHdpbmRvdy55dGNzaSkge3dpbmRvdy55dGNzaS50aWNrKCdhcHInLCBudWxsLCAnJyk7fX07IGlmICh3aW5kb3cuUG9seW1lciAmJiBQb2x5bWVyLlJlbmRlclN0YXR1cykge29uUG9seW1lclJlYWR5KCk7fSBlbHNlIHt3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignc2NyaXB0LWxvYWQtZHBqJywgb25Qb2x5bWVyUmVhZHkpO308L3NjcmlwdD48bGluayByZWw9ImNhbm9uaWNhbCIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciPjxsaW5rIHJlbD0iYWx0ZXJuYXRlIiBtZWRpYT0iaGFuZGhlbGQiIGhyZWY9Imh0dHBzOi8vbS55b3V0dWJlLmNvbS9AcGFyaXMtcmIiPjxsaW5rIHJlbD0iYWx0ZXJuYXRlIiBtZWRpYT0ib25seSBzY3JlZW4gYW5kIChtYXgtd2lkdGg6IDY0MHB4KSIgaHJlZj0iaHR0cHM6Ly9tLnlvdXR1YmUuY29tL0BwYXJpcy1yYiI+PHRpdGxlPlBhcmlzUkIgLSBZb3VUdWJlPC90aXRsZT48bWV0YSBuYW1lPSJkZXNjcmlwdGlvbiIgY29udGVudD0iUGFydGFnZXogdm9zIHZpZMOpb3MgYXZlYyB2b3MgYW1pcywgdm9zIHByb2NoZXMgZXQgbGUgbW9uZGUgZW50aWVyIj48bWV0YSBuYW1lPSJrZXl3b3JkcyIgY29udGVudD0idmlkw6lvLCBwYXJ0YWdlLCB0w6lsw6lwaG9uZS1hcHBhcmVpbCBwaG90bywgdmlzaW9waG9uZSwgZ3JhdHVpdCwgZW52b2kiPjxsaW5rIHJlbD0iYWx0ZXJuYXRlIiB0eXBlPSJhcHBsaWNhdGlvbi9yc3MreG1sIiB0aXRsZT0iUlNTIiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9mZWVkcy92aWRlb3MueG1sP2NoYW5uZWxfaWQ9VUNGS0U2UUhHUEFrSVNNajFTUWRxbm53Ij48bWV0YSBwcm9wZXJ0eT0ib2c6dGl0bGUiIGNvbnRlbnQ9IlBhcmlzUkIiPjxsaW5rIHJlbD0iaW1hZ2Vfc3JjIiBocmVmPSJodHRwczovL3l0My5nb29nbGV1c2VyY29udGVudC5jb20vdENiUFFhUTdrckhBNWp6OWlxY0VXN29aSXFRN3lBblRxVkNuRlExaWdRLXNQQ3V1czF2WHNQUGVGRWRwczdfTEQ5bUN5TmFTR0E9czkwMC1jLWstYzB4MDBmZmZmZmYtbm8tcmoiPjxtZXRhIHByb3BlcnR5PSJvZzpzaXRlX25hbWUiIGNvbnRlbnQ9IllvdVR1YmUiPjxtZXRhIHByb3BlcnR5PSJvZzp1cmwiIGNvbnRlbnQ9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53Ij48bWV0YSBwcm9wZXJ0eT0ib2c6aW1hZ2UiIGNvbnRlbnQ9Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS90Q2JQUWFRN2tySEE1ano5aXFjRVc3b1pJcVE3eUFuVHFWQ25GUTFpZ1Etc1BDdXVzMXZYc1BQZUZFZHBzN19MRDltQ3lOYVNHQT1zOTAwLWMtay1jMHgwMGZmZmZmZi1uby1yaiI+PG1ldGEgcHJvcGVydHk9Im9nOmltYWdlOndpZHRoIiBjb250ZW50PSI5MDAiPjxtZXRhIHByb3BlcnR5PSJvZzppbWFnZTpoZWlnaHQiIGNvbnRlbnQ9IjkwMCI+PG1ldGEgcHJvcGVydHk9ImFsOmlvczphcHBfc3RvcmVfaWQiIGNvbnRlbnQ9IjU0NDAwNzY2NCI+PG1ldGEgcHJvcGVydHk9ImFsOmlvczphcHBfbmFtZSIgY29udGVudD0iWW91VHViZSI+PG1ldGEgcHJvcGVydHk9ImFsOmlvczp1cmwiIGNvbnRlbnQ9InZuZC55b3V0dWJlOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53Ij48bWV0YSBwcm9wZXJ0eT0iYWw6YW5kcm9pZDp1cmwiIGNvbnRlbnQ9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53P2ZlYXR1cmU9YXBwbGlua3MiPjxtZXRhIHByb3BlcnR5PSJhbDphbmRyb2lkOmFwcF9uYW1lIiBjb250ZW50PSJZb3VUdWJlIj48bWV0YSBwcm9wZXJ0eT0iYWw6YW5kcm9pZDpwYWNrYWdlIiBjb250ZW50PSJjb20uZ29vZ2xlLmFuZHJvaWQueW91dHViZSI+PG1ldGEgcHJvcGVydHk9ImFsOndlYjp1cmwiIGNvbnRlbnQ9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53P2ZlYXR1cmU9YXBwbGlua3MiPjxtZXRhIHByb3BlcnR5PSJvZzp0eXBlIiBjb250ZW50PSJwcm9maWxlIj48bWV0YSBwcm9wZXJ0eT0iZmI6YXBwX2lkIiBjb250ZW50PSI4Nzc0MTEyNDMwNSI+PG1ldGEgbmFtZT0idHdpdHRlcjpjYXJkIiBjb250ZW50PSJzdW1tYXJ5Ij48bWV0YSBuYW1lPSJ0d2l0dGVyOnNpdGUiIGNvbnRlbnQ9IkB5b3V0dWJlIj48bWV0YSBuYW1lPSJ0d2l0dGVyOnVybCIgY29udGVudD0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciPjxtZXRhIG5hbWU9InR3aXR0ZXI6dGl0bGUiIGNvbnRlbnQ9IlBhcmlzUkIiPjxtZXRhIG5hbWU9InR3aXR0ZXI6ZGVzY3JpcHRpb24iIGNvbnRlbnQ9IiI+PG1ldGEgbmFtZT0idHdpdHRlcjppbWFnZSIgY29udGVudD0iaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3RDYlBRYVE3a3JIQTVqejlpcWNFVzdvWklxUTd5QW5UcVZDbkZRMWlnUS1zUEN1dXMxdlhzUFBlRkVkcHM3X0xEOW1DeU5hU0dBPXM5MDAtYy1rLWMweDAwZmZmZmZmLW5vLXJqIj48bWV0YSBuYW1lPSJ0d2l0dGVyOmFwcDpuYW1lOmlwaG9uZSIgY29udGVudD0iWW91VHViZSI+PG1ldGEgbmFtZT0idHdpdHRlcjphcHA6aWQ6aXBob25lIiBjb250ZW50PSI1NDQwMDc2NjQiPjxtZXRhIG5hbWU9InR3aXR0ZXI6YXBwOm5hbWU6aXBhZCIgY29udGVudD0iWW91VHViZSI+PG1ldGEgbmFtZT0idHdpdHRlcjphcHA6aWQ6aXBhZCIgY29udGVudD0iNTQ0MDA3NjY0Ij48bWV0YSBuYW1lPSJ0d2l0dGVyOmFwcDp1cmw6aXBob25lIiBjb250ZW50PSJ2bmQueW91dHViZTovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udyI+PG1ldGEgbmFtZT0idHdpdHRlcjphcHA6dXJsOmlwYWQiIGNvbnRlbnQ9InZuZC55b3V0dWJlOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53Ij48bWV0YSBuYW1lPSJ0d2l0dGVyOmFwcDpuYW1lOmdvb2dsZXBsYXkiIGNvbnRlbnQ9IllvdVR1YmUiPjxtZXRhIG5hbWU9InR3aXR0ZXI6YXBwOmlkOmdvb2dsZXBsYXkiIGNvbnRlbnQ9ImNvbS5nb29nbGUuYW5kcm9pZC55b3V0dWJlIj48bWV0YSBuYW1lPSJ0d2l0dGVyOmFwcDp1cmw6Z29vZ2xlcGxheSIgY29udGVudD0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciPjxsaW5rIGl0ZW1wcm9wPSJ1cmwiIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53Ij48bWV0YSBpdGVtcHJvcD0ibmFtZSIgY29udGVudD0iUGFyaXNSQiI+PG1ldGEgaXRlbXByb3A9ImRlc2NyaXB0aW9uIiBjb250ZW50PSIiPjxtZXRhIGl0ZW1wcm9wPSJyZXF1aXJlc1N1YnNjcmlwdGlvbiIgY29udGVudD0iRmFsc2UiPjxtZXRhIGl0ZW1wcm9wPSJpZGVudGlmaWVyIiBjb250ZW50PSJVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciPjxzcGFuIGl0ZW1wcm9wPSJhdXRob3IiIGl0ZW1zY29wZSBpdGVtdHlwZT0iaHR0cDovL3NjaGVtYS5vcmcvUGVyc29uIj48bGluayBpdGVtcHJvcD0idXJsIiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udyI+PGxpbmsgaXRlbXByb3A9Im5hbWUiIGNvbnRlbnQ9IlBhcmlzUkIiPjwvc3Bhbj48c2NyaXB0IHR5cGU9ImFwcGxpY2F0aW9uL2xkK2pzb24iIG5vbmNlPSJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIj57IkBjb250ZXh0IjogImh0dHA6Ly9zY2hlbWEub3JnIiwgIkB0eXBlIjogIkJyZWFkY3J1bWJMaXN0IiwgIml0ZW1MaXN0RWxlbWVudCI6IFt7IkB0eXBlIjogIkxpc3RJdGVtIiwgInBvc2l0aW9uIjogMSwgIml0ZW0iOiB7IkBpZCI6ICJodHRwczpcL1wvd3d3LnlvdXR1YmUuY29tXC9jaGFubmVsXC9VQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCAibmFtZSI6ICJQYXJpc1JCIn19XX08L3NjcmlwdD48bGluayBpdGVtcHJvcD0idGh1bWJuYWlsVXJsIiBocmVmPSJodHRwczovL3l0My5nb29nbGV1c2VyY29udGVudC5jb20vdENiUFFhUTdrckhBNWp6OWlxY0VXN29aSXFRN3lBblRxVkNuRlExaWdRLXNQQ3V1czF2WHNQUGVGRWRwczdfTEQ5bUN5TmFTR0E9czkwMC1jLWstYzB4MDBmZmZmZmYtbm8tcmoiPjxzcGFuIGl0ZW1wcm9wPSJ0aHVtYm5haWwiIGl0ZW1zY29wZSBpdGVtdHlwZT0iaHR0cDovL3NjaGVtYS5vcmcvSW1hZ2VPYmplY3QiPjxsaW5rIGl0ZW1wcm9wPSJ1cmwiIGhyZWY9Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS90Q2JQUWFRN2tySEE1ano5aXFjRVc3b1pJcVE3eUFuVHFWQ25GUTFpZ1Etc1BDdXVzMXZYc1BQZUZFZHBzN19MRDltQ3lOYVNHQT1zOTAwLWMtay1jMHgwMGZmZmZmZi1uby1yaiI+PG1ldGEgaXRlbXByb3A9IndpZHRoIiBjb250ZW50PSI5MDAiPjxtZXRhIGl0ZW1wcm9wPSJoZWlnaHQiIGNvbnRlbnQ9IjkwMCI+PC9zcGFuPjxtZXRhIGl0ZW1wcm9wPSJpc0ZhbWlseUZyaWVuZGx5IiBjb250ZW50PSJ0cnVlIj48bWV0YSBpdGVtcHJvcD0icmVnaW9uc0FsbG93ZWQiIGNvbnRlbnQ9Ik1PLEJKLE1ILE5PLEdHLEZKLFNWLEtFLEdGLEJSLExBLE1aLFBLLENBLEhVLEJXLExLLFROLEJNLEtOLFNILFRILENGLEdRLEFXLFRWLFRMLElULENLLEJaLEpPLFNELEdVLElFLEVILEFVLEdZLE1ULFJFLFpNLEJULERNLENYLFpXLElOLExJLEdXLEdSLElNLERKLERPLEZNLE5aLFNZLERFLE5MLEVULENWLEdOLEVTLEJWLExZLFNaLFRLLFZHLENSLEFaLE1BLEJRLEVDLE1YLExVLE1ZLENaLE5VLEFGLFNYLEFYLFVBLEZPLE5JLEZJLEtaLE1HLERLLEJILFRSLEFJLFBGLElMLEJCLEpNLEJOLFRXLE5DLFZDLEtQLENELFBMLElELFRELEtXLE9NLEFNLEJTLE5SLE1NLEdBLE1XLFNCLFBOLE1FLFRGLEhULFBFLENMLFRPLENXLEVHLFNDLFNPLFlULE5QLEFHLEJELElRLExTLE1GLFJXLFBZLENZLEJHLEFELEpQLEJBLEhNLEtNLE5FLFNTLEFTLExDLEFSLERaLENNLFdGLEhSLEFRLEdMLFNHLE1VLFRHLE1LLE1RLEtILFFBLEtJLFNOLFRaLExCLFBXLE5HLE1TLFZJLE1WLFVHLFVTLFRKLElPLEVSLElTLFBNLEFMLEtHLE5BLFBILFVaLFZOLFBBLEhLLEJZLEFFLEhOLEJGLExULEFPLFNLLEpFLFJPLEZSLEFULE1SLENOLENJLFNULFBULENPLFdTLFlFLFZBLEZLLEVFLFBHLENVLEJMLEtZLEdFLEdTLFNNLFRNLExWLFVZLFJVLENDLEdNLEdULEdJLFBSLE1OLENHLEdELE1ELENILEJPLE1MLFRDLElSLE1QLEdQLFNKLFBTLEJJLFpBLE5GLFJTLFNMLE1DLEdCLFVNLEJFLFNFLFNSLFZFLExSLFRULFNBLFNJLEtSLEdILFZVIj48bGluayByZWw9ImFsdGVybmF0ZSIgaHJlZj0iYW5kcm9pZC1hcHA6Ly9jb20uZ29vZ2xlLmFuZHJvaWQueW91dHViZS9odHRwL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udyI+PGxpbmsgcmVsPSJhbHRlcm5hdGUiIGhyZWY9Imlvcy1hcHA6Ly81NDQwMDc2NjQvdm5kLnlvdXR1YmUvd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53Ij48c2NyaXB0IG5vbmNlPSJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIj5pZiAod2luZG93Lnl0Y3NpKSB7d2luZG93Lnl0Y3NpLnRpY2soJ3BkYycsIG51bGwsICcnKTt9PC9zY3JpcHQ+PHNjcmlwdCBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+dmFyIHl0SW5pdGlhbERhdGEgPSB7InJlc3BvbnNlQ29udGV4dCI6eyJzZXJ2aWNlVHJhY2tpbmdQYXJhbXMiOlt7InNlcnZpY2UiOiJHRkVFREJBQ0siLCJwYXJhbXMiOlt7ImtleSI6InJvdXRlIiwidmFsdWUiOiJjaGFubmVsLiJ9LHsia2V5IjoiaXNfY2FzdWFsIiwidmFsdWUiOiJmYWxzZSJ9LHsia2V5IjoiaXNfb3duZXIiLCJ2YWx1ZSI6ImZhbHNlIn0seyJrZXkiOiJpc19tb25ldGl6YXRpb25fZW5hYmxlZCIsInZhbHVlIjoiZmFsc2UifSx7ImtleSI6Im51bV9zaGVsdmVzIiwidmFsdWUiOiIxIn0seyJrZXkiOiJpc19hbGNfc3VyZmFjZSIsInZhbHVlIjoiZmFsc2UifSx7ImtleSI6ImJyb3dzZV9pZCIsInZhbHVlIjoiVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53In0seyJrZXkiOiJicm93c2VfaWRfcHJlZml4IiwidmFsdWUiOiIifSx7ImtleSI6ImxvZ2dlZF9pbiIsInZhbHVlIjoiMCJ9LHsia2V5IjoiZSIsInZhbHVlIjoiMjM4MDQyODEsMjM5MTg1OTcsMjM5NDY0MjAsMjM5NjYyMDgsMjM5ODMyOTYsMjM5OTgwNTYsMjQwMDQ2NDQsMjQwMDcyNDYsMjQwMDc2MTMsMjQwMzQxNjgsMjQwMzY5NDcsMjQwNzcyNDEsMjQwODA3MzgsMjQxMjA4MTksMjQxMzUzMTAsMjQxNDAyNDcsMjQxNjY4NjcsMjQxODExNzQsMjQxODcwNDMsMjQxODczNzcsMjQyMTExNzgsMjQyMTk3MTMsMjQyMzgzMDAsMjQyNDEzNzgsMjQyNTU1NDMsMjQyNTU1NDUsMjQyNjIzNDYsMjQyODg2NjQsMjQyOTA5NzEsMjQyOTE4NTcsMjQzNjA4OTQsMjQzNjExODcsMjQzNjE2NjgsMjQzNjIwOTUsMjQzNjIyODMsMjQzNjMxMTQsMjQzNjQ3ODksMjQzNjU1NzIsMjQzNjU1ODQsMjQzNjYwNzMsMjQzNjYwODQsMjQzNjY5MTcsMjQzNjc4MjYsMjQzNjgzMDIsMjQzNjgzMTQsMjQzNjg3NTAsMjQzNjkzNDgsMjQzNzA1MTAsMjQzNzA5ODIsMjQzNzEzNzUsMjQzNzE2MzYsMjQzNzIwOTksMjQzNzIxMTAsMjQzNzIzNjQsMjQzNzM5MTcsMjQzNzQzMTEsMjQzNzQ1OTMsMjQzNzUxMDEsMjQzNzU1MzEsMjQzNzU1NzQsMjQzNzY3ODUsMjQzNzgyMTAsMjQzNzkxMjcsMjQzNzkzNTIsMjQzNzk1MjksMjQzNzk1NDYsMjQzODA2NjMsMjQzOTA2NzUsMjQ0MDQ2NDAsMjQ0MDcxOTEsMjQ0MDk0MTcsMjQ0MTU4NjQsMjQ0MTYyOTAsMjQ0Mjg3ODgsMjQ0MzM2NzksMjQ0Mzc1NzcsMjQ0MzkzNjEsMjQ0NDAxMzIsMjQ0NDMzMzEsMjQ0NTEzMTksMjQ0NTM5ODksMjQ0NTczODQsMjQ0NTgzMTcsMjQ0NTgzMjQsMjQ0NTgzMjksMjQ0NTg4MzksMjQ0NTk0MzYsMjQ0NjM4NzIsMjQ0NjUwMTEsMjQ0NjYzNzEsMjQ0Njg3MjQsMjQ0ODI0MzMsMjQ0ODQ2ODAsMjQ0ODUyMzksMjQ0ODU0MjEsMjQ0ODgxODgsMjQ0OTUwNjAsMjQ0OTgzMDAsMjQ0OTk1MzIsMjQ1MTUzNjYsMjQ1MTU0MjMsMjQ1MTg0NTIsMjQ1MTkxMDIsMjQ1MzA0OTYsMjQ1MzA5NDgsMjQ1MzEyMjIsMjQ1MzIxNDYsMjQ1MzI4NTUsMjQ1MzU4OTgsMjQ1MzcyMDAsMjQ1Mzc2NjEsMjQ1NTAyODUsMjQ1NTA0NTgsMjQ1NTA5NTEsMjQ1NTExMzAsMjQ1NTI2MDYsMjQ1NTM0MzQsMjQ1NTQxMzksMjQ1NTU1NjcsMjQ1NTgxNTksMjQ1NTg2NDEsMjQ1NTkzMjcsMjQ2OTA0OTUsMjQ2OTEzMzQsMjQ2OTU1MTcsMjQ2OTY3NTIsMjQ2OTcwMTEsMjQ2OTcwOTgsMjQ2OTg0NTIsMjQ2OTg4ODAsMjQ2OTk1OTgsMjQ2OTk4NjAsMjQ2OTk4OTksMzkzMjMwNzQsMzkzMjMzNDEsMzkzMjM4NzIifV19LHsic2VydmljZSI6IkdPT0dMRV9IRUxQIiwicGFyYW1zIjpbeyJrZXkiOiJicm93c2VfaWQiLCJ2YWx1ZSI6IlVDRktFNlFIR1BBa0lTTWoxU1FkcW5udyJ9LHsia2V5IjoiYnJvd3NlX2lkX3ByZWZpeCIsInZhbHVlIjoiIn1dfSx7InNlcnZpY2UiOiJDU0kiLCJwYXJhbXMiOlt7ImtleSI6ImMiLCJ2YWx1ZSI6IldFQiJ9LHsia2V5IjoiY3ZlciIsInZhbHVlIjoiMi4yMDIzMDYwNy4wNi4wMCJ9LHsia2V5IjoieXRfbGkiLCJ2YWx1ZSI6IjAifSx7ImtleSI6IkdldENoYW5uZWxQYWdlX3JpZCIsInZhbHVlIjoiMHgxNzRjNjliMWI3YWI4YmNkIn1dfSx7InNlcnZpY2UiOiJHVUlERURfSEVMUCIsInBhcmFtcyI6W3sia2V5IjoibG9nZ2VkX2luIiwidmFsdWUiOiIwIn1dfSx7InNlcnZpY2UiOiJFQ0FUQ0hFUiIsInBhcmFtcyI6W3sia2V5IjoiY2xpZW50LnZlcnNpb24iLCJ2YWx1ZSI6IjIuMjAyMzA2MDcifSx7ImtleSI6ImNsaWVudC5uYW1lIiwidmFsdWUiOiJXRUIifSx7ImtleSI6ImNsaWVudC5mZXhwIiwidmFsdWUiOiIyNDAzNjk0NywyNDAwNzI0NiwyNDM2MDg5NCwyNDAwNzYxMywyNDE4MTE3NCwyNDY5NTUxNywyNDQyODc4OCwyNDQ5ODMwMCwyNDM2MjA5NSwyNDU1MjYwNiwyNDQ2NTAxMSwyNDQ1NzM4NCwyNDQ5NTA2MCwyMzk4MzI5NiwyNDUzMjE0NiwyNDI4ODY2NCwyNDM2OTM0OCwyNDE4NzM3NywyNDU1MzQzNCwyNDEyMDgxOSwyNDUxOTEwMiwyNDY5NzA5OCwyNDQ2NjM3MSwyNDQ4MjQzMywyNDM3MjExMCwyNDM3OTEyNywyNDAwNDY0NCwyNDM3NTEwMSwyNDA3NzI0MSwyNDUzNTg5OCwyNDE0MDI0NywyNDI5MDk3MSwyNDU1MDQ1OCwyNDU1NDEzOSwyNDM2MTE4NywyNDY5NzAxMSwyNDM2ODMxNCwyNDM3MTYzNiwyNDQ1ODgzOSwyNDU1MDI4NSwyNDQ1OTQzNiwyNDY5Njc1MiwyNDM3MDk4MiwyNDM3NDMxMSwyNDY5ODg4MCwyNDU1ODY0MSwyNDQwNzE5MSwyNDU1ODE1OSwyNDM2NjA4NCwyNDM2MzExNCwzOTMyMzA3NCwyNDIzODMwMCwyNDI1NTU0NSwzOTMyMzg3MiwyNDY5OTg2MCwyNDM2NzgyNiwyNDY5MDQ5NSwyNDM3MzkxNywyNDM2NDc4OSwyNDM3OTU0NiwyNDM2MTY2OCwyNDA4MDczOCwyNDM2NjkxNywyNDM3OTM1MiwyMzk5ODA1NiwyNDQ4NTIzOSwyMzk2NjIwOCwyNDM3Njc4NSwyNDQ1MTMxOSwyNDM2NTU3MiwyNDUxNTQyMywyNDM4MDY2MywyNDUzMDQ5NiwyNDM2ODMwMiwyNDE2Njg2NywyNDQwNDY0MCwyNDI1NTU0MywyNDUxNTM2NiwyNDM3NDU5MywyNDM3MjM2NCwyNDUzMTIyMiwyNDQ0MDEzMiwyNDQxNjI5MCwyMzkxODU5NywyNDU1OTMyNywyNDQ4NTQyMSwyNDM3MDUxMCwyNDM3ODIxMCwyNDQxNTg2NCwyNDU1MDk1MSwyNDE4NzA0MywyNDQ4ODE4OCwyNDQ2Mzg3MiwyNDUzMDk0OCwyNDU1MTEzMCwyNDM3MjA5OSwyNDQ1ODMyOSwyNDI0MTM3OCwzOTMyMzM0MSwyNDQ4NDY4MCwyNDUxODQ1MiwyNDQ0MzMzMSwyNDUzNzIwMCwyNDQzOTM2MSwyNDU1NTU2NywyMzgwNDI4MSwyNDM2NjA3MywyNDM3OTUyOSwyNDQ1ODMxNywyNDM2NTU4NCwyNDY5MTMzNCwyNDY5OTg5OSwyMzk0NjQyMCwyNDM5MDY3NSwyNDQ1Mzk4OSwyNDQ5OTUzMiwyNDM3NTUzMSwyNDM2ODc1MCwyNDAzNDE2OCwyNDQzNzU3NywyNDI2MjM0NiwyNDUzNzY2MSwyNDEzNTMxMCwyNDQzMzY3OSwyNDQ1ODMyNCwyNDY5ODQ1MiwyNDI5MTg1NywyNDQwOTQxNywyNDY5OTU5OCwyNDM2MjI4MywyNDIxMTE3OCwyNDUzMjg1NSwyNDQ2ODcyNCwyNDM3MTM3NSwyNDIxOTcxMywyNDM3NTU3NCJ9XX1dLCJtYXhBZ2VTZWNvbmRzIjozMDAsIm1haW5BcHBXZWJSZXNwb25zZUNvbnRleHQiOnsibG9nZ2VkT3V0Ijp0cnVlLCJ0cmFja2luZ1BhcmFtIjoia3hfZm1QeGhvUFpSVHhhZEl0QWdqNGRFUUR4QnZ1eW9IRjFfRTZrWFhrRzZZOXdSZ2t1c3dtSUJ3T2NDRTU5VER0c2xMS1BRLVNTIn0sIndlYlJlc3BvbnNlQ29udGV4dEV4dGVuc2lvbkRhdGEiOnsieXRDb25maWdEYXRhIjp7InZpc2l0b3JEYXRhIjoiQ2d0QmJsOXlibGd3V0hscmF5aVV2b2lrQmclM0QlM0QiLCJyb290VmlzdWFsRWxlbWVudFR5cGUiOjM2MTF9LCJoYXNEZWNvcmF0ZWQiOnRydWV9fSwiY29udGVudHMiOnsidHdvQ29sdW1uQnJvd3NlUmVzdWx0c1JlbmRlcmVyIjp7InRhYnMiOlt7InRhYlJlbmRlcmVyIjp7ImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQlVROEpNQkdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQHBhcmlzLXJiL2ZlYXR1cmVkIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53IiwicGFyYW1zIjoiRWdobVpXRjBkWEpsWlBJR0JBb0NNZ0ElM0QiLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BwYXJpcy1yYiJ9fSwidGl0bGUiOiJBY2N1ZWlsIiwic2VsZWN0ZWQiOnRydWUsImNvbnRlbnQiOnsic2VjdGlvbkxpc3RSZW5kZXJlciI6eyJjb250ZW50cyI6W3siaXRlbVNlY3Rpb25SZW5kZXJlciI6eyJjb250ZW50cyI6W3sic2hlbGZSZW5kZXJlciI6eyJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiVmlkw6lvcyIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0dFUTNCd1lBQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL0BwYXJpcy1yYi92aWRlb3M/dmlldz0wXHUwMDI2c29ydD1kZFx1MDAyNnNoZWxmX2lkPTAiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCJwYXJhbXMiOiJFZ1oyYVdSbGIzTVlBeUFBY0FEeUJnc0tDVG9DQ0FHaUFRSUlBUSUzRCUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQHBhcmlzLXJiIn19fV19LCJlbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0dFUTNCd1lBQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL0BwYXJpcy1yYi92aWRlb3M/dmlldz0wXHUwMDI2c29ydD1kZFx1MDAyNnNoZWxmX2lkPTAiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCJwYXJhbXMiOiJFZ1oyYVdSbGIzTVlBeUFBY0FEeUJnc0tDVG9DQ0FHaUFRSUlBUSUzRCUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQHBhcmlzLXJiIn19LCJjb250ZW50Ijp7Imhvcml6b250YWxMaXN0UmVuZGVyZXIiOnsiaXRlbXMiOlt7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJYbGU5Um1GX3dDWSIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1hsZTlSbUZfd0NZL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMRDk0S1gyWHV4RGZ1RFVVdWxSQVY4SV96eHVSZyIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9YbGU5Um1GX3dDWS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEJ2NXNZOEtWbEdDcHFaR1FUYXVPbTFKeEJIYUEiLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1hsZTlSbUZfd0NZL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ2RGYl9RWk13T01lbUFfSG9PT1ZQX1JHRE0zQSIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvWGxlOVJtRl93Q1kvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xEc29FemxndjJ4MEtnRTNOWHlidlBCeGswZjZRIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJOdW3DqXJpcXVlIFJlc3BvbnNhYmxlIC0gSW50cm9kdWN0aW9uIGRlIFBhcmlzUkIgaWwgeSBhIDEgbW9pcyA0MCBtaW51dGVzIDQzwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiTnVtw6lyaXF1ZSBSZXNwb25zYWJsZSAtIEludHJvZHVjdGlvbiJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDEgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiI0M8KgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKMEJFSlExR0FBaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZ3lDbWN0YUdsbmFDMWpjblphR0ZWRFJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkNW9CQlJEeU9CaG1xZ0VhVlZWTVJrWkxSVFpSU0VkUVFXdEpVMDFxTVZOUlpIRnVibmM9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1YbGU5Um1GX3dDWSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJYbGU5Um1GX3dDWSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjgtLS1zbi00Z3h4LTI1Z2VlLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZiZWlkcz0yNDM1MDAxOFx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTVlNTdiZDQ2NjE3ZmMwMjZcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NDU3NTAwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPSJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDSjBCRUpRMUdBQWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGhBcG9EX2ktYW83NnRlcWdFYVZWVk1Sa1pMUlRaUlNFZFFRV3RKVTAxcU1WTlJaSEZ1Ym5jPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNDPCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiI0M8KgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLRUJFUDZZQkJnRkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLRUJFUDZZQkJnRkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IlhsZTlSbUZfd0NZIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLRUJFUDZZQkJnRkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJYbGU5Um1GX3dDWSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIlhsZTlSbUZfd0NZIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDS0VCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSjBCRUpRMUdBQWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0WWJHVTVVbTFHWDNkRFdRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSjBCRUpRMUdBQWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDS0FCRUk1aUloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDSjBCRUpRMUdBQWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNKMEJFSlExR0FBaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNDAgbWludXRlcyBldCA3wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjQwOjA3In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0o4QkVQbm5BeGdCSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiWGxlOVJtRl93Q1kiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKOEJFUG5uQXhnQkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IlhsZTlSbUZfd0NZIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0o4QkVQbm5BeGdCSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSjRCRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSjRCRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJYbGU5Um1GX3dDWSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSjRCRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiWGxlOVJtRl93Q1kiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJYbGU5Um1GX3dDWSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNKNEJFTWZzQkJnQ0loTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoidktqd2E4ZmllOEUiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92S2p3YThmaWU4RS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTERKeVR4blpNU3JnbjQ3SkxpTUNYUDM5MEJkQXciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvdktqd2E4ZmllOEUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xCbXRPWnR3X25kYzNxcS04Q3BJbERsTl9SNml3Iiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92S2p3YThmaWU4RS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEFfRW1XbWM2eTcwWVJmNlJYSmZrbzRVVkljWXciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3ZLandhOGZpZThFL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ3hHNWs4U2VCcnZrRHR4dFRnaXFkSHJZU2dGQSIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQSBEaWZmZXJlbnQgV2F5IHRvIFRoaW5rIEFib3V0IFJhaWxzIE1vZGVscyBbRU5dIGRlIFBhcmlzUkIgaWwgeSBhIDEgbW9pcyAyNSBtaW51dGVzIDE3OMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IkEgRGlmZmVyZW50IFdheSB0byBUaGluayBBYm91dCBSYWlscyBNb2RlbHMgW0VOXSJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDEgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIxNzjCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSmdCRUpRMUdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGd5Q21jdGFHbG5hQzFqY25aYUdGVkRSa3RGTmxGSVIxQkJhMGxUVFdveFUxRmtjVzV1ZDVvQkJSRHlPQmhtcWdFYVZWVk1Sa1pMUlRaUlNFZFFRV3RKVTAxcU1WTlJaSEZ1Ym5jPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9dktqd2E4ZmllOEUiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoidktqd2E4ZmllOEUiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIxNC0tLXNuLTRneHgtMjVnZWwuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNmJlaWRzPTI0MzUwMDE4XHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9YmNhOGYwNmJjN2UyN2JjMVx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz00NTc1MDBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNKZ0JFSlExR0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEaEF3ZmVKdjd5TnZOUzhBYW9CR2xWVlRFWkdTMFUyVVVoSFVFRnJTVk5OYWpGVFVXUnhibTUzIiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxNzjCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIxNzjCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSndCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSndCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJ2S2p3YThmaWU4RSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSndCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsidktqd2E4ZmllOEUiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJ2S2p3YThmaWU4RSJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0p3QkVQNllCQmdGSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pnQkVKUTFHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndDJTMnAzWVRobWFXVTRSUSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pnQkVKUTFHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0pzQkVJNWlJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0pnQkVKUTFHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDSmdCRUpRMUdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjI1IG1pbnV0ZXMgZXQgMzLCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiMjU6MzIifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSm9CRVBubkF4Z0JJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJ2S2p3YThmaWU4RSIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pvQkVQbm5BeGdCSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoidktqd2E4ZmllOEUifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDSm9CRVBubkF4Z0JJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0In19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKa0JFTWZzQkJnQ0loTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKa0JFTWZzQkJnQ0loTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6InZLandhOGZpZThFIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKa0JFTWZzQkJnQ0loTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJ2S2p3YThmaWU4RSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbInZLandhOGZpZThFIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0prQkVNZnNCQmdDSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJsYzdIcDFsTDN4NCIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2xjN0hwMWxMM3g0L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMRFNzczBIYUxCdW8yUkxDMV9JbmhaVmdDVW4yZyIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9sYzdIcDFsTDN4NC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEMxaURUQ1lKNkFTOGJ5SU1BRGEtV3dveHRKb3ciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2xjN0hwMWxMM3g0L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQzVSS29zSExoQTNya2JSWTQxOEduM2R1ODRmdyIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvbGM3SHAxbEwzeDQvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xDWHpjSllGaUhCVlh1ZGZ1Z1lxMGgxblNwNm93Iiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJSb1JkbGUsIFJ1Ynkgb24gUmFpbHMgd29yZGxlIGRlIFBhcmlzUkIgaWwgeSBhIDEgbW9pcyA5IG1pbnV0ZXMgZXQgNTjCoHNlY29uZGVzIDM3wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiUm9SZGxlLCBSdWJ5IG9uIFJhaWxzIHdvcmRsZSJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDEgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIzN8KgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKTUJFSlExR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZ3lDbWN0YUdsbmFDMWpjblphR0ZWRFJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkNW9CQlJEeU9CaG1xZ0VhVlZWTVJrWkxSVFpSU0VkUVFXdEpVMDFxTVZOUlpIRnVibmM9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1sYzdIcDFsTDN4NCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJsYzdIcDFsTDN4NCIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjEwLS0tc24tNGd4eC0yNWdlbC5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD05NWNlYzdhNzU5NGJkZjFlXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTQ1NzUwMFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0pNQkVKUTFHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RoQW5yNnZ5dlgwc2VlVkFhb0JHbFZWVEVaR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTMiLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjM3wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMzfCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSmNCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSmNCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJsYzdIcDFsTDN4NCIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSmNCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsibGM3SHAxbEwzeDQiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJsYzdIcDFsTDN4NCJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0pjQkVQNllCQmdGSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pNQkVKUTFHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndHNZemRJY0RGc1RETjROQSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pNQkVKUTFHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0pZQkVJNWlJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0pNQkVKUTFHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDSk1CRUpRMUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjkgbWludXRlcyBldCA1OMKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiI5OjU4In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pVQkVQbm5BeGdCSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoibGM3SHAxbEwzeDQiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKVUJFUG5uQXhnQkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6ImxjN0hwMWxMM3g0In1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0pVQkVQbm5BeGdCSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSlFCRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSlFCRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJsYzdIcDFsTDN4NCIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSlFCRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsibGM3SHAxbEwzeDQiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJsYzdIcDFsTDN4NCJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNKUUJFTWZzQkJnQ0loTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiQXVQZXd3UFM2cU0iLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9BdVBld3dQUzZxTS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTENBMEtzenlXV0ZqRkZ0V0Q5dXRrMkYtYWFUTHciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvQXVQZXd3UFM2cU0vaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xDbXFLekdWOTNORVVRVVdBa2NRUU1DOE1DNC1BIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9BdVBld3dQUzZxTS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTENwUnpfZVFGM0RENkFtRncxcVBwaUJVVUk5eEEiLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0F1UGV3d1BTNnFNL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMRDQ1S1ZXNXJ6dHNJSU5KYlZTUmFzOWlKVGl1ZyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiUG91cnF1b2kgcXVpdHRlciBsYSB0ZWNoID8gZGUgUGFyaXNSQiBpbCB5IGEgMyBtb2lzIDE4IG1pbnV0ZXMgMTUywqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiUG91cnF1b2kgcXVpdHRlciBsYSB0ZWNoID8ifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSAzIG1vaXMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMTUywqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0k0QkVKUTFHQU1pRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RneUNtY3RhR2xuYUMxamNuWmFHRlZEUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWQ1b0JCUkR5T0JobXFnRWFWVlZNUmtaTFJUWlJTRWRRUVd0SlUwMXFNVk5SWkhGdWJuYz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PUF1UGV3d1BTNnFNIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IkF1UGV3d1BTNnFNIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNy0tLXNuLTRneHgtMjVnZWwuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNmJlaWRzPTI0MzUwMDE4XHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9MDJlM2RlYzMwM2QyZWFhM1x1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz00NTc1MDBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNJNEJFSlExR0FNaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEaEFvOVhMbnJEWTlfRUNxZ0VhVlZWTVJrWkxSVFpSU0VkUVFXdEpVMDFxTVZOUlpIRnVibmM9Iiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxNTLCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIxNTLCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSklCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSklCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJBdVBld3dQUzZxTSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSklCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiQXVQZXd3UFM2cU0iXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJBdVBld3dQUzZxTSJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0pJQkVQNllCQmdGSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0k0QkVKUTFHQU1pRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndEJkVkJsZDNkUVV6WnhUUSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0k0QkVKUTFHQU1pRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0pFQkVJNWlJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0k0QkVKUTFHQU1pRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDSTRCRUpRMUdBTWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjE4IG1pbnV0ZXMgZXQgNTbCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiMTg6NTYifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSkFCRVBubkF4Z0JJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJBdVBld3dQUzZxTSIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pBQkVQbm5BeGdCSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiQXVQZXd3UFM2cU0ifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDSkFCRVBubkF4Z0JJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0In19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJOEJFTWZzQkJnQ0loTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJOEJFTWZzQkJnQ0loTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IkF1UGV3d1BTNnFNIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJOEJFTWZzQkJnQ0loTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJBdVBld3dQUzZxTSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIkF1UGV3d1BTNnFNIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0k4QkVNZnNCQmdDSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJaRmM0SWFHRHZzUSIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1pGYzRJYUdEdnNRL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQnZLaGtVUmNRU1hyUm4ySUJWM2lkOVozMnppQSIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9aRmM0SWFHRHZzUS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEIyRnVmRlkxeU5GZmNvdGlGTTg4UWNSY2NfM2ciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1pGYzRJYUdEdnNRL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ1RXX3I3QVhhakd5MXRJVkFMNUw2MXlCem1KQSIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvWkZjNElhR0R2c1EvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xEb3dCS3JoemE3SlRXZWhadzl1cU5VX3Fkb0VBIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJEZXMgZXNwYWNlcyBzw7tycyBwb3VyIGxlcyBkw6l2ZWxvcHBldXNlcyBkZSBQYXJpc1JCIGlsIHkgYSAzIG1vaXMgMzIgbWludXRlcyAx4oCvMjA3wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiRGVzIGVzcGFjZXMgc8O7cnMgcG91ciBsZXMgZMOpdmVsb3BwZXVzZXMifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSAzIG1vaXMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMeKArzIwN8KgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJa0JFSlExR0FRaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZ3lDbWN0YUdsbmFDMWpjblphR0ZWRFJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkNW9CQlJEeU9CaG1xZ0VhVlZWTVJrWkxSVFpSU0VkUVFXdEpVMDFxTVZOUlpIRnVibmM9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1aRmM0SWFHRHZzUSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJaRmM0SWFHRHZzUSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjctLS1zbi00Z3h4LTI1Z2VlLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZiZWlkcz0yNDM1MDAxOFx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTY0NTczODIxYTE4M2JlYzRcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NDU3NTAwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPSJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDSWtCRUpRMUdBUWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGhBeFAyT2pKcUV6cXRrcWdFYVZWVk1Sa1pMUlRaUlNFZFFRV3RKVTAxcU1WTlJaSEZ1Ym5jPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMSwyIG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMSwywqBrwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0kwQkVQNllCQmdGSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0kwQkVQNllCQmdGSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiWkZjNElhR0R2c1EiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0kwQkVQNllCQmdGSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIlpGYzRJYUdEdnNRIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiWkZjNElhR0R2c1EiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNJMEJFUDZZQkJnRkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJa0JFSlExR0FRaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RhUm1NMFNXRkhSSFp6VVElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJa0JFSlExR0FRaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNJd0JFSTVpSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNJa0JFSlExR0FRaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0lrQkVKUTFHQVFpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIzMiBtaW51dGVzIGV0IDM4wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjMyOjM4In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lzQkVQbm5BeGdCSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiWkZjNElhR0R2c1EiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJc0JFUG5uQXhnQkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IlpGYzRJYUdEdnNRIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0lzQkVQbm5BeGdCSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSW9CRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSW9CRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJaRmM0SWFHRHZzUSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSW9CRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiWkZjNElhR0R2c1EiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJaRmM0SWFHRHZzUSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNJb0JFTWZzQkJnQ0loTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiTlg2Ymd5QjAxbWsiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OWDZiZ3lCMDFtay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEQ1T2YybGluc2ZkSW5wZnVxa1ZsdGh4dXUzc3ciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvTlg2Ymd5QjAxbWsvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xEbFIwM2gxQm5UWUwyQWZ1MlNKMnhaZldDWm5BIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OWDZiZ3lCMDFtay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEJSbHMtM09KZ2duZFZJSjQwUVBRWVZfUlBNTXciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL05YNmJneUIwMW1rL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQkN5ZUptNkxKcFFaN3VUd0otQl9scDFjV2o3dyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiUmFpbHMgOiBHw6lyZXIgc2VzIG1pZ3JhdGlvbnMgc2FucyBkb3dudGltZSBkZSBQYXJpc1JCIGlsIHkgYSAzIG1vaXMgMzIgbWludXRlcyAyNDPCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJSYWlscyA6IEfDqXJlciBzZXMgbWlncmF0aW9ucyBzYW5zIGRvd250aW1lIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgMyBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjI0M8KgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJUUJFSlExR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZ3lDbWN0YUdsbmFDMWpjblphR0ZWRFJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkNW9CQlJEeU9CaG1xZ0VhVlZWTVJrWkxSVFpSU0VkUVFXdEpVMDFxTVZOUlpIRnVibmM9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1OWDZiZ3lCMDFtayIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJOWDZiZ3lCMDFtayIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjQtLS1zbi0yNWdsZW5sei5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD0zNTdlOWI4MzIwNzRkNjY5XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTY0ODc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0lRQkVKUTFHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RoQTZhelRnN0x3cHI4MXFnRWFWVlZNUmtaTFJUWlJTRWRRUVd0SlUwMXFNVk5SWkhGdWJuYz0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjI0M8KgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjI0M8KgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJZ0JFUDZZQkJnRkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJZ0JFUDZZQkJnRkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6Ik5YNmJneUIwMW1rIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJZ0JFUDZZQkJnRkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJOWDZiZ3lCMDFtayJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIk5YNmJneUIwMW1rIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDSWdCRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSVFCRUpRMUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0T1dEWmlaM2xDTURGdGF3JTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSVFCRUpRMUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDSWNCRUk1aUloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDSVFCRUpRMUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNJUUJFSlExR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMzIgbWludXRlcyBldCAzNcKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIzMjozNSJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJWUJFUG5uQXhnQkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6Ik5YNmJneUIwMW1rIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSVlCRVBubkF4Z0JJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJOWDZiZ3lCMDFtayJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNJWUJFUG5uQXhnQkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lVQkVNZnNCQmdDSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lVQkVNZnNCQmdDSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiTlg2Ymd5QjAxbWsiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lVQkVNZnNCQmdDSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIk5YNmJneUIwMW1rIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiTlg2Ymd5QjAxbWsiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDSVVCRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6IjNpdEl0VVlPRkNFIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvM2l0SXRVWU9GQ0UvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xBamJBSXpJYW9iQnJ0TlRDTmVyckV3RFNSLUd3Iiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzNpdEl0VVlPRkNFL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMREhmbzRIeTFERjU4OXF3SHZTV0xQaW83b0o4dyIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvM2l0SXRVWU9GQ0UvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xBdF9CMmpnTlphU1MxbFVzS2J2MURmNXlxLXp3Iiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8zaXRJdFVZT0ZDRS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEM0aFBodjJGVHZMWEo5WDlhTGJBYi01UkFaUUEiLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1pZ3JlciBzZXJlaW5lbWVudCBkdSBNb25vbGl0aGUgYXV4IG1pY3Jvc2VydmljZXMgZGUgUGFyaXNSQiBpbCB5IGEgMyBtb2lzIDUxIG1pbnV0ZXMgNDA3wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiTWlncmVyIHNlcmVpbmVtZW50IGR1IE1vbm9saXRoZSBhdXggbWljcm9zZXJ2aWNlcyJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDMgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiI0MDfCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSDhRbERVWUJpSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRElLWnkxb2FXZG9MV055ZGxvWVZVTkdTMFUyVVVoSFVFRnJTVk5OYWpGVFVXUnhibTUzbWdFRkVQSTRHR2FxQVJwVlZVeEdSa3RGTmxGSVIxQkJhMGxUVFdveFUxRmtjVzV1ZHc9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9M2l0SXRVWU9GQ0UiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiM2l0SXRVWU9GQ0UiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIzLS0tc24tMjVnbGVubDYuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNmJlaWRzPTI0MzUwMDE4XHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9ZGUyYjQ4YjU0NjBlMTQyMVx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MzM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNIOFFsRFVZQmlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9FQ2hxTGl3MUpiU2xkNEJxZ0VhVlZWTVJrWkxSVFpSU0VkUVFXdEpVMDFxTVZOUlpIRnVibmM9Iiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI0MDfCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiI0MDfCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSU1CRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSU1CRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiIzaXRJdFVZT0ZDRSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSU1CRVA2WUJCZ0ZJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiM2l0SXRVWU9GQ0UiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyIzaXRJdFVZT0ZDRSJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0lNQkVQNllCQmdGSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0g4UWxEVVlCaUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNnc3phWFJKZEZWWlQwWkRSUSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0g4UWxEVVlCaUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0lJQkVJNWlJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0g4UWxEVVlCaUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDSDhRbERVWUJpSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjUxIG1pbnV0ZXMgZXQgNsKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiI1MTowNiJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJRUJFUG5uQXhnQkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6IjNpdEl0VVlPRkNFIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSUVCRVBubkF4Z0JJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiIzaXRJdFVZT0ZDRSJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNJRUJFUG5uQXhnQkloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lBQkVNZnNCQmdDSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lBQkVNZnNCQmdDSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiM2l0SXRVWU9GQ0UiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lBQkVNZnNCQmdDSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjNpdEl0VVlPRkNFIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiM2l0SXRVWU9GQ0UiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDSUFCRU1mc0JCZ0NJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6InBrSW40bzVLdHQ0IiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvcGtJbjRvNUt0dDQvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xCRlJVVUdvcFd3ZTRiSFhLY0tld0RJb2p4OW5BIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3BrSW40bzVLdHQ0L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQ3Q3NmlVVS1naGVpbkh2UEpiRjFEOXhCanVWUSIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvcGtJbjRvNUt0dDQvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xDdGcyUWlSZkhKakprREJJR003M0poMmxJcEt3Iiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wa0luNG81S3R0NC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTENOOG51SFdWeS1WVGFCcjQ2YWc5Wkd3c1QyWWciLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IlRlc3RpbmcgYmVzdCBwcmFjdGljZXMgZGUgUGFyaXNSQiBpbCB5IGEgMyBtb2lzIDMxIG1pbnV0ZXMgMTU1wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiVGVzdGluZyBiZXN0IHByYWN0aWNlcyJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDMgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIxNTXCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSG9RbERVWUJ5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRElLWnkxb2FXZG9MV055ZGxvWVZVTkdTMFUyVVVoSFVFRnJTVk5OYWpGVFVXUnhibTUzbWdFRkVQSTRHR2FxQVJwVlZVeEdSa3RGTmxGSVIxQkJhMGxUVFdveFUxRmtjVzV1ZHc9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9cGtJbjRvNUt0dDQiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoicGtJbjRvNUt0dDQiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIxNi0tLXNuLTRneHgtMjVnZWUuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNmJlaWRzPTI0MzUwMDE4XHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9YTY0MjI3ZTI4ZTRhYjZkZVx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz00NTc1MDBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNIb1FsRFVZQnlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9FRGU3YXJ5cVB5Sm9hWUJxZ0VhVlZWTVJrWkxSVFpSU0VkUVFXdEpVMDFxTVZOUlpIRnVibmM9Iiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxNTXCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIxNTXCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSDRRX3BnRUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSDRRX3BnRUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJwa0luNG81S3R0NCIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSDRRX3BnRUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsicGtJbjRvNUt0dDQiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJwa0luNG81S3R0NCJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0g0UV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hvUWxEVVlCeUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndHdhMGx1Tkc4MVMzUjBOQSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hvUWxEVVlCeUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0gwUWptSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0hvUWxEVVlCeUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDSG9RbERVWUJ5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjMxIG1pbnV0ZXMgZXQgNDHCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiMzE6NDEifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSHdRLWVjREdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJwa0luNG81S3R0NCIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0h3US1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoicGtJbjRvNUt0dDQifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDSHdRLWVjREdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIc1F4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIc1F4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6InBrSW40bzVLdHQ0IiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIc1F4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJwa0luNG81S3R0NCJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbInBrSW40bzVLdHQ0Il19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0hzUXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJrTDYyeDQyTGRwVSIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2tMNjJ4NDJMZHBVL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQmlWUnIxYXFlMUY5Ul9RbU1fdkY3bUJpQldVdyIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rTDYyeDQyTGRwVS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTERyVGx4M3BzM19JeTRycXdGbDR4R29oVk9Pa2ciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2tMNjJ4NDJMZHBVL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQjlvV2hHV0RIOTdpaTJjUGhsZXo3LVpCVkhWdyIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkva0w2Mng0MkxkcFUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xDcHNBUDN2RFZpUnNleE04RFVVT0hWb3FaRk1RIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDiWxpbWluZXIgZMOpZmluaXRpdmVtZW50IHZvcyBidWdzIGdyw6JjZSDDoCBsYSBtw6l0aG9kZSBQSVNDQVJFIGRlIFBhcmlzUkIgaWwgeSBhIDQgbW9pcyAyNiBtaW51dGVzIDI5NsKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IsOJbGltaW5lciBkw6lmaW5pdGl2ZW1lbnQgdm9zIGJ1Z3MgZ3LDomNlIMOgIGxhIG3DqXRob2RlIFBJU0NBUkUifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSA0IG1vaXMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMjk2wqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hVUWxEVVlDQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0RJS1p5MW9hV2RvTFdOeWRsb1lWVU5HUzBVMlVVaEhVRUZyU1ZOTmFqRlRVV1J4Ym01M21nRUZFUEk0R0dhcUFScFZWVXhHUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3PT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PWtMNjJ4NDJMZHBVIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6ImtMNjJ4NDJMZHBVIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMTYtLS1zbi00Z3h4LTI1Z2VsLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZiZWlkcz0yNDM1MDAxOFx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTkwYmViNmM3OGQ4Yjc2OTVcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NDU3NTAwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPSJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDSFVRbERVWUNDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRUNWN2Ezcy1OaXQzNUFCcWdFYVZWVk1Sa1pMUlRaUlNFZFFRV3RKVTAxcU1WTlJaSEZ1Ym5jPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMjk2wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMjk2wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hrUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hrUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoia0w2Mng0MkxkcFUiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hrUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbImtMNjJ4NDJMZHBVIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsia0w2Mng0MkxkcFUiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNIa1FfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIVVFsRFVZQ0NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RyVERZeWVEUXlUR1J3VlElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIVVFsRFVZQ0NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNIZ1FqbUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNIVVFsRFVZQ0NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0hVUWxEVVlDQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIyNiBtaW51dGVzIGV0IDU0wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjI2OjU0In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hjUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoia0w2Mng0MkxkcFUiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIY1EtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6ImtMNjJ4NDJMZHBVIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0hjUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSFlReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSFlReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJrTDYyeDQyTGRwVSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSFlReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsia0w2Mng0MkxkcFUiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJrTDYyeDQyTGRwVSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNIWVF4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiRTlsZWNGNmdYZWsiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FOWxlY0Y2Z1hlay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTERfd1MwWGhxSWgwOGxsQ25xV01QQlZualJWdFEiLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvRTlsZWNGNmdYZWsvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xBVzU3UWVtQzdOWFU3a0RYbnZkM3VHZUFzZlNnIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FOWxlY0Y2Z1hlay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTENVaDFNTGVNbWFSZnZqM19kMDNLWlR1QXp3cnciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0U5bGVjRjZnWGVrL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQUhBOFhMczRVWkstTXBnTGNrbGpNQTFza3d1dyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciBsYSB2aXNpYmlsaXTDqSBkZXMgQ1ZFcyBkYW5zIHJ1YnlnZW1zLm9yZyBkZSBQYXJpc1JCIGlsIHkgYSA0IG1vaXMgMTQgbWludXRlcyBldCA1NcKgc2Vjb25kZXMgNzHCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJBam91dGVyIGxhIHZpc2liaWxpdMOpIGRlcyBDVkVzIGRhbnMgcnVieWdlbXMub3JnIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgNCBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjcxwqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hBUWxEVVlDU0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0RJS1p5MW9hV2RvTFdOeWRsb1lWVU5HUzBVMlVVaEhVRUZyU1ZOTmFqRlRVV1J4Ym01M21nRUZFUEk0R0dhcUFScFZWVXhHUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3PT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PUU5bGVjRjZnWGVrIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IkU5bGVjRjZnWGVrIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNy0tLXNuLTRneHgtMjVnZWwuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNmJlaWRzPTI0MzUwMDE4XHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9MTNkOTVlNzA1ZWEwNWRlOVx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz00NTc1MDBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNIQVFsRFVZQ1NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9FRHB1NEgxaGM3WDdCT3FBUnBWVlV4R1JrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09Iiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI3McKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjcxwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hRUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hRUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiRTlsZWNGNmdYZWsiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hRUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIkU5bGVjRjZnWGVrIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiRTlsZWNGNmdYZWsiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNIUVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIQVFsRFVZQ1NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RGT1d4bFkwWTJaMWhsYXclM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIQVFsRFVZQ1NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNITVFqbUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNIQVFsRFVZQ1NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0hBUWxEVVlDU0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxNCBtaW51dGVzIGV0IDU1wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjE0OjU1In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hJUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiRTlsZWNGNmdYZWsiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNISVEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IkU5bGVjRjZnWGVrIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0hJUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSEVReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSEVReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJFOWxlY0Y2Z1hlayIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSEVReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiRTlsZWNGNmdYZWsiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJFOWxlY0Y2Z1hlayJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNIRVF4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiNThkY05xZlpPeXciLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS81OGRjTnFmWk95dy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTERqeGdUUXFCMzYtLXJZSkZVeDVSeTlPZVRYZmciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNThkY05xZlpPeXcvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xCWVRNcGYwU1ZsdGdWdWFpU0hRYmlvWW1nSEZBIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS81OGRjTnFmWk95dy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEJNTktWN19pSGlUU203TVk1OV9HeFVkNWlTaWciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzU4ZGNOcWZaT3l3L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMRFl6cWpILWNMdU1qb2VqMTZQT3ZTYmRJZ2JQdyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiVmlvbGVuY2VzIHNleHVlbGxlcyBldCBzZXhpc3RlcyBldCBhdmVuaXIgZGUgUGFyaXMucmIgZGUgUGFyaXNSQiBpbCB5IGEgNSBtb2lzIDEyIG1pbnV0ZXMgZXQgNTfCoHNlY29uZGVzIDE1OMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IlZpb2xlbmNlcyBzZXh1ZWxsZXMgZXQgc2V4aXN0ZXMgZXQgYXZlbmlyIGRlIFBhcmlzLnJiIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgNSBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjE1OMKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHc1FsRFVZQ2lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9ESUtaeTFvYVdkb0xXTnlkbG9ZVlVOR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTNtZ0VGRVBJNEdHYXFBUnBWVlV4R1JrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj01OGRjTnFmWk95dyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiI1OGRjTnFmWk95dyIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjEwLS0tc24tNGd4eC0yNWd5Lmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZiZWlkcz0yNDM1MDAxOFx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWU3Yzc1YzM2YTdkOTNiMmNcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9MzkxMjUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPSJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDR3NRbERVWUNpSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRUNzOXVTLTZvYlg0LWNCcWdFYVZWVk1Sa1pMUlRaUlNFZFFRV3RKVTAxcU1WTlJaSEZ1Ym5jPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTU4wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTU4wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0c4UV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0c4UV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiNThkY05xZlpPeXciLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0c4UV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjU4ZGNOcWZaT3l3Il0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiNThkY05xZlpPeXciXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNHOFFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHc1FsRFVZQ2lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3MxT0dSalRuRm1Xazk1ZHclM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHc1FsRFVZQ2lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNHNFFqbUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNHc1FsRFVZQ2lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0dzUWxEVVlDaUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxMiBtaW51dGVzIGV0IDU3wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjEyOjU3In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0cwUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiNThkY05xZlpPeXciLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHMFEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IjU4ZGNOcWZaT3l3In1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0cwUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR3dReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR3dReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiI1OGRjTnFmWk95dyIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR3dReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiNThkY05xZlpPeXciXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyI1OGRjTnFmWk95dyJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNHd1F4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiTnV1X2NXaXV1ZEkiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OdXVfY1dpdXVkSS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTENRaVh6bTZ2aXlTT2oxR05IeE83d3dXOVMzVmciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvTnV1X2NXaXV1ZEkvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xBZnJtamlHRWFxOGtOS3lPUXp6MjE4QjQwTEd3Iiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OdXVfY1dpdXVkSS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTER2dWQ5N0w4QU5jXzYzN2FWX2w2ZjhCV05LR1EiLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL051dV9jV2l1dWRJL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQjVJUFpmbW51OU8tcVViVjdBQUMwNXBHRlJiZyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQ29tbWVudCBub3VzIGF2b25zIGRpdmlzw6kgbGVzIGJ1Z3MgcGFyIDMuNSBlbiB1biBhbiBkZSBQYXJpc1JCIGlsIHkgYSA1IG1vaXMgMjggbWludXRlcyAxNzjCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJDb21tZW50IG5vdXMgYXZvbnMgZGl2aXPDqSBsZXMgYnVncyBwYXIgMy41IGVuIHVuIGFuIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgNSBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjE3OMKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHWVFsRFVZQ3lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9ESUtaeTFvYVdkb0xXTnlkbG9ZVlVOR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTNtZ0VGRVBJNEdHYXFBUnBWVlV4R1JrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1OdXVfY1dpdXVkSSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJOdXVfY1dpdXVkSSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjUtLS1zbi0yNWdsZW5sei5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD0zNmViYmY3MTY4YWViOWQyXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTY0ODc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0dZUWxEVVlDeUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0VEUzg3ckZsdTd2OVRhcUFScFZWVXhHUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3PT0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjE3OMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjE3OMKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHb1FfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHb1FfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6Ik51dV9jV2l1dWRJIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHb1FfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJOdXVfY1dpdXVkSSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIk51dV9jV2l1dWRJIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDR29RX3BnRUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR1lRbERVWUN5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0T2RYVmZZMWRwZFhWa1NRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR1lRbERVWUN5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDR2tRam1JaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDR1lRbERVWUN5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNHWVFsRFVZQ3lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMjggbWludXRlcyBldCA0NcKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIyODo0NSJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHZ1EtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6Ik51dV9jV2l1dWRJIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR2dRLWVjREdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJOdXVfY1dpdXVkSSJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNHZ1EtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0djUXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0djUXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiTnV1X2NXaXV1ZEkiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0djUXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIk51dV9jV2l1dWRJIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiTnV1X2NXaXV1ZEkiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDR2NReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19XSwidHJhY2tpbmdQYXJhbXMiOiJDR01ReGpraUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJ2aXNpYmxlSXRlbUNvdW50Ijo0LCJuZXh0QnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfREVGQVVMVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwiaWNvbiI6eyJpY29uVHlwZSI6IkNIRVZST05fUklHSFQifSwiYWNjZXNzaWJpbGl0eSI6eyJsYWJlbCI6IlN1aXZhbnQifSwidHJhY2tpbmdQYXJhbXMiOiJDR1VROEZzaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0sInByZXZpb3VzQnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfREVGQVVMVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwiaWNvbiI6eyJpY29uVHlwZSI6IkNIRVZST05fTEVGVCJ9LCJhY2Nlc3NpYmlsaXR5Ijp7ImxhYmVsIjoiUHLDqWPDqWRlbnRlIn0sInRyYWNraW5nUGFyYW1zIjoiQ0dRUThGc2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0dFUTNCd1lBQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsInBsYXlBbGxCdXR0b24iOnsiYnV0dG9uUmVuZGVyZXIiOnsic3R5bGUiOiJTVFlMRV9URVhUIiwic2l6ZSI6IlNJWkVfREVGQVVMVCIsImlzRGlzYWJsZWQiOmZhbHNlLCJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJUb3V0IGxpcmUifV19LCJpY29uIjp7Imljb25UeXBlIjoiUExBWV9BTEwifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR0lROEZzaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PVhsZTlSbUZfd0NZXHUwMDI2bGlzdD1VVUxGRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJYbGU5Um1GX3dDWSIsInBsYXlsaXN0SWQiOiJVVUxGRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdocFZWVXhHUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3JTNEJTNEIn19LCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnI4LS0tc24tNGd4eC0yNWdlZS5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD01ZTU3YmQ0NjYxN2ZjMDI2XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTQ1NzUwMFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0dJUThGc2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19fX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNHQVF1eThZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0ifX0seyJpdGVtU2VjdGlvblJlbmRlcmVyIjp7ImNvbnRlbnRzIjpbeyJzaGVsZlJlbmRlcmVyIjp7InRpdGxlIjp7InJ1bnMiOlt7InRleHQiOiJQYXJpcy5yYiIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZvUTNCd1lBQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3BsYXlsaXN0P2xpc3Q9UExtMnQ5d0dIZk0wcmpKSWdwS1RMdGo4bEVGb1Y5Um5lZyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9QTEFZTElTVCIsInJvb3RWZSI6NTc1NCwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJWTFBMbTJ0OXdHSGZNMHJqSklncEtUTHRqOGxFRm9WOVJuZWcifX19XX0sImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRm9RM0J3WUFDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvcGxheWxpc3Q/bGlzdD1QTG0ydDl3R0hmTTByakpJZ3BLVEx0ajhsRUZvVjlSbmVnIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1BMQVlMSVNUIiwicm9vdFZlIjo1NzU0LCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlZMUExtMnQ5d0dIZk0wcmpKSWdwS1RMdGo4bEVGb1Y5Um5lZyJ9fSwiY29udGVudCI6eyJleHBhbmRlZFNoZWxmQ29udGVudHNSZW5kZXJlciI6eyJpdGVtcyI6W3sidmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiNThkY05xZlpPeXciLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS81OGRjTnFmWk95dy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTERqeGdUUXFCMzYtLXJZSkZVeDVSeTlPZVRYZmciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNThkY05xZlpPeXcvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xCWVRNcGYwU1ZsdGdWdWFpU0hRYmlvWW1nSEZBIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS81OGRjTnFmWk95dy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEJNTktWN19pSGlUU203TVk1OV9HeFVkNWlTaWciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzU4ZGNOcWZaT3l3L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMRFl6cWpILWNMdU1qb2VqMTZQT3ZTYmRJZ2JQdyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiVmlvbGVuY2VzIHNleHVlbGxlcyBldCBzZXhpc3RlcyBldCBhdmVuaXIgZGUgUGFyaXMucmIgZGUgUGFyaXNSQiBpbCB5IGEgNSBtb2lzIDEyIG1pbnV0ZXMgZXQgNTfCoHNlY29uZGVzIDE1OMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IlZpb2xlbmNlcyBzZXh1ZWxsZXMgZXQgc2V4aXN0ZXMgZXQgYXZlbmlyIGRlIFBhcmlzLnJiIn0sImRlc2NyaXB0aW9uU25pcHBldCI6eyJydW5zIjpbeyJ0ZXh0IjoiTWVldHVwIFBhcmlzLnJiIGR1IDYgZMOpY2VtYnJlIDIwMjJcblxuRGVwdWlzIGxhIHNvcnRpZSBkZSBjZSBjb21tdW5pcXXDqSwgbm91cyBhdm9ucyBhcHByaXMgbCdleGlzdGVuY2UgZCd1bmUgbm91dmVsbGUgdmljdGltZSBkZSB2aW9sZW5jZXMgc2V4aXN0ZXMgZGUgbGEgcGFydCBkZSBNb25zaWV1ciBBc3N1cyBhdSBzZWluIGRlIGxhLi4uIn1dfSwibG9uZ0J5bGluZVRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcmlzUkIiLCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGc1EzREFZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AcGFyaXMtcmIiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BwYXJpcy1yYiJ9fX1dfSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSA1IG1vaXMifSwibGVuZ3RoVGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTIgbWludXRlcyBldCA1N8Kgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIxMjo1NyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIxNTjCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRnNRM0RBWUFDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRElHWnkxb2FXZG9XaGhWUTBaTFJUWlJTRWRRUVd0SlUwMXFNVk5SWkhGdWJuZWFBUVVROGpnWVpLb0JJbEJNYlRKME9YZEhTR1pOTUhKcVNrbG5jRXRVVEhScU9HeEZSbTlXT1ZKdVpXYz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PTU4ZGNOcWZaT3l3Iiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IjU4ZGNOcWZaT3l3Iiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMTAtLS1zbi00Z3h4LTI1Z3kuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNmJlaWRzPTI0MzUwMDE4XHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9ZTdjNzVjMzZhN2Q5M2IyY1x1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz0zOTEyNTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9In19fX19LCJvd25lclRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcmlzUkIiLCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGc1EzREFZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AcGFyaXMtcmIiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BwYXJpcy1yYiJ9fX1dfSwic2hvcnRCeWxpbmVUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJpc1JCIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRnNRM0RBWUFDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQHBhcmlzLXJiIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53IiwiY2Fub25pY2FsQmFzZVVybCI6Ii9AcGFyaXMtcmIifX19XX0sInRyYWNraW5nUGFyYW1zIjoiQ0ZzUTNEQVlBQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0VDczl1Uy02b2JYNC1jQnFnRWlVRXh0TW5RNWQwZElaazB3Y21wS1NXZHdTMVJNZEdvNGJFVkdiMVk1VW01bFp3PT0iLCJzaG93QWN0aW9uTWVudSI6ZmFsc2UsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTU4wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTU4wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0Y4UV9wZ0VHQVlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0Y4UV9wZ0VHQVlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiNThkY05xZlpPeXciLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0Y4UV9wZ0VHQVlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjU4ZGNOcWZaT3l3Il0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiNThkY05xZlpPeXciXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNGOFFfcGdFR0FZaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGc1EzREFZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3MxT0dSalRuRm1Xazk1ZHclM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGc1EzREFZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNGNFFqbUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNGc1EzREFZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0ZzUTNEQVlBQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJjaGFubmVsVGh1bWJuYWlsU3VwcG9ydGVkUmVuZGVyZXJzIjp7ImNoYW5uZWxUaHVtYm5haWxXaXRoTGlua1JlbmRlcmVyIjp7InRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL3l0My5nb29nbGV1c2VyY29udGVudC5jb20vdENiUFFhUTdrckhBNWp6OWlxY0VXN29aSXFRN3lBblRxVkNuRlExaWdRLXNQQ3V1czF2WHNQUGVGRWRwczdfTEQ5bUN5TmFTR0E9czY4LWMtay1jMHgwMGZmZmZmZi1uby1yaiIsIndpZHRoIjo2OCwiaGVpZ2h0Ijo2OH1dfSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRnNRM0RBWUFDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQHBhcmlzLXJiIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53IiwiY2Fub25pY2FsQmFzZVVybCI6Ii9AcGFyaXMtcmIifX0sImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBY2PDqWRlciDDoCBsYSBjaGHDrm5lIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjEyIG1pbnV0ZXMgZXQgNTfCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiMTI6NTcifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRjBRLWVjREdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiI1OGRjTnFmWk95dyIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0YwUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiNThkY05xZlpPeXcifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRjBRLWVjREdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGd1F4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGd1F4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IjU4ZGNOcWZaT3l3IiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGd1F4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyI1OGRjTnFmWk95dyJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIjU4ZGNOcWZaT3l3Il19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0Z3UXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fV0sInNob3dNb3JlVGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGx1cyJ9XX19fSwidHJhY2tpbmdQYXJhbXMiOiJDRm9RM0J3WUFDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09In19XSwidHJhY2tpbmdQYXJhbXMiOiJDRmtRdXk4WUFTSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09In19LHsiaXRlbVNlY3Rpb25SZW5kZXJlciI6eyJjb250ZW50cyI6W3sic2hlbGZSZW5kZXJlciI6eyJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiVmlkw6lvcyBwb3B1bGFpcmVzIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQmdRM0J3WUFDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQHBhcmlzLXJiL3ZpZGVvcz92aWV3PTBcdTAwMjZzb3J0PXBcdTAwMjZzaGVsZl9pZD0wIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53IiwicGFyYW1zIjoiRWdaMmFXUmxiM01ZQVNBQWNBRHlCZ3NLQ1RvQ0NBS2lBUUlJQVElM0QlM0QiLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BwYXJpcy1yYiJ9fX1dfSwiZW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNCZ1EzQndZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AcGFyaXMtcmIvdmlkZW9zP3ZpZXc9MFx1MDAyNnNvcnQ9cFx1MDAyNnNoZWxmX2lkPTAiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCJwYXJhbXMiOiJFZ1oyYVdSbGIzTVlBU0FBY0FEeUJnc0tDVG9DQ0FLaUFRSUlBUSUzRCUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQHBhcmlzLXJiIn19LCJjb250ZW50Ijp7Imhvcml6b250YWxMaXN0UmVuZGVyZXIiOnsiaXRlbXMiOlt7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJaRmM0SWFHRHZzUSIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1pGYzRJYUdEdnNRL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQnZLaGtVUmNRU1hyUm4ySUJWM2lkOVozMnppQSIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9aRmM0SWFHRHZzUS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEIyRnVmRlkxeU5GZmNvdGlGTTg4UWNSY2NfM2ciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1pGYzRJYUdEdnNRL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ1RXX3I3QVhhakd5MXRJVkFMNUw2MXlCem1KQSIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvWkZjNElhR0R2c1EvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xEb3dCS3JoemE3SlRXZWhadzl1cU5VX3Fkb0VBIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJEZXMgZXNwYWNlcyBzw7tycyBwb3VyIGxlcyBkw6l2ZWxvcHBldXNlcyBkZSBQYXJpc1JCIGlsIHkgYSAzIG1vaXMgMzIgbWludXRlcyAx4oCvMjA3wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiRGVzIGVzcGFjZXMgc8O7cnMgcG91ciBsZXMgZMOpdmVsb3BwZXVzZXMifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSAzIG1vaXMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMeKArzIwN8KgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGUVFsRFVZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9ESUtaeTFvYVdkb0xXTndkbG9ZVlVOR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTNtZ0VGRVBJNEdHV3FBUnBWVlV4UVJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1aRmM0SWFHRHZzUSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJaRmM0SWFHRHZzUSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjctLS1zbi00Z3h4LTI1Z2VlLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZiZWlkcz0yNDM1MDAxOFx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTY0NTczODIxYTE4M2JlYzRcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NDU3NTAwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPSJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDRlFRbERVWUFDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRURFX1k2TW1vVE9xMlNxQVJwVlZVeFFSa3RGTmxGSVIxQkJhMGxUVFdveFUxRmtjVzV1ZHc9PSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMSwyIG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMSwywqBrwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZnUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZnUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiWkZjNElhR0R2c1EiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZnUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIlpGYzRJYUdEdnNRIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiWkZjNElhR0R2c1EiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNGZ1FfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGUVFsRFVZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RhUm1NMFNXRkhSSFp6VVElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGUVFsRFVZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNGY1FqbUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNGUVFsRFVZQUNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0ZRUWxEVVlBQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIzMiBtaW51dGVzIGV0IDM4wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjMyOjM4In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZZUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiWkZjNElhR0R2c1EiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGWVEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IlpGYzRJYUdEdnNRIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0ZZUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRlVReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRlVReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJaRmM0SWFHRHZzUSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRlVReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiWkZjNElhR0R2c1EiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJaRmM0SWFHRHZzUSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNGVVF4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiM2l0SXRVWU9GQ0UiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8zaXRJdFVZT0ZDRS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEFqYkFJeklhb2JCcnROVENOZXJyRXdEU1ItR3ciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvM2l0SXRVWU9GQ0UvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xESGZvNEh5MURGNTg5cXdIdlNXTFBpbzdvSjh3Iiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8zaXRJdFVZT0ZDRS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEF0X0IyamdOWmFTUzFsVXNLYnYxRGY1eXEtenciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzNpdEl0VVlPRkNFL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQzRoUGh2MkZUdkxYSjlYOWFMYkFiLTVSQVpRQSIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWlncmVyIHNlcmVpbmVtZW50IGR1IE1vbm9saXRoZSBhdXggbWljcm9zZXJ2aWNlcyBkZSBQYXJpc1JCIGlsIHkgYSAzIG1vaXMgNTEgbWludXRlcyA0MDfCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJNaWdyZXIgc2VyZWluZW1lbnQgZHUgTW9ub2xpdGhlIGF1eCBtaWNyb3NlcnZpY2VzIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgMyBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjQwN8KgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFOFFsRFVZQVNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9ESUtaeTFvYVdkb0xXTndkbG9ZVlVOR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTNtZ0VGRVBJNEdHV3FBUnBWVlV4UVJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj0zaXRJdFVZT0ZDRSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiIzaXRJdFVZT0ZDRSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjMtLS1zbi0yNWdsZW5sNi5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1kZTJiNDhiNTQ2MGUxNDIxXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYzMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0U4UWxEVVlBU0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0VDaHFMaXcxSmJTbGQ0QnFnRWFWVlZNVUVaTFJUWlJTRWRRUVd0SlUwMXFNVk5SWkhGdWJuYz0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjQwN8KgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjQwN8KgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGTVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGTVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IjNpdEl0VVlPRkNFIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGTVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyIzaXRJdFVZT0ZDRSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIjNpdEl0VVlPRkNFIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRk1RX3BnRUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRThRbERVWUFTSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2dzemFYUkpkRlZaVDBaRFJRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRThRbERVWUFTSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDRklRam1JaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRThRbERVWUFTSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNFOFFsRFVZQVNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNTEgbWludXRlcyBldCA2wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjUxOjA2In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZFUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiM2l0SXRVWU9GQ0UiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGRVEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IjNpdEl0VVlPRkNFIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0ZFUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRkFReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRkFReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiIzaXRJdFVZT0ZDRSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRkFReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiM2l0SXRVWU9GQ0UiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyIzaXRJdFVZT0ZDRSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNGQVF4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiMUx2cjBIcl9vdDAiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8xTHZyMEhyX290MC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTENlVmRFRWFwajJIcWJmTk1NdUhGSkV4d0tZa1EiLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvMUx2cjBIcl9vdDAvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xEYS1fdkk3M3licG4xZTBLYjRSUloyYVRLdFdBIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8xTHZyMEhyX290MC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTERFb3ptWWlpVUZjMDZzY1B4ejBjMDRtcGNCN3ciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzFMdnIwSHJfb3QwL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQTRobTR0ZTdnSnpiakMyNlhDQnFlcWtGZVpudyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQ29tbWl0IGNvbW1lIHVuIGhpcHN0ZXIgYXZlYyBHaXRtb2ppICEgZGUgUGFyaXNSQiBpbCB5IGEgMTEgbW9pcyAxMSBtaW51dGVzIGV0IDUwwqBzZWNvbmRlcyAzODDCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJDb21taXQgY29tbWUgdW4gaGlwc3RlciBhdmVjIEdpdG1vamkgISJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDExIG1vaXMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMzgwwqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VvUWxEVVlBaUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0RJS1p5MW9hV2RvTFdOd2Rsb1lWVU5HUzBVMlVVaEhVRUZyU1ZOTmFqRlRVV1J4Ym01M21nRUZFUEk0R0dXcUFScFZWVXhRUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3PT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PTFMdnIwSHJfb3QwIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IjFMdnIwSHJfb3QwIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNC0tLXNuLTI1Z2U3bnprLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZiZWlkcz0yNDM1MDAxOFx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWQ0YmJlYmQwN2FmZmEyZGRcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjQ4NzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPSJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDRW9RbERVWUFpSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRURkeGY3WGhfcjYzZFFCcWdFYVZWVk1VRVpMUlRaUlNFZFFRV3RKVTAxcU1WTlJaSEZ1Ym5jPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMzgwwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMzgwwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0U0UV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0U0UV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiMUx2cjBIcl9vdDAiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0U0UV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjFMdnIwSHJfb3QwIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiMUx2cjBIcl9vdDAiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNFNFFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFb1FsRFVZQWlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3N4VEhaeU1FaHlYMjkwTUElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFb1FsRFVZQWlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNFMFFqbUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNFb1FsRFVZQWlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0VvUWxEVVlBaUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxMSBtaW51dGVzIGV0IDUwwqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjExOjUwIn0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0V3US1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiMUx2cjBIcl9vdDAiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFd1EtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IjFMdnIwSHJfb3QwIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0V3US1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRXNReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRXNReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiIxTHZyMEhyX290MCIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRXNReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiMUx2cjBIcl9vdDAiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyIxTHZyMEhyX290MCJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNFc1F4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoia0w2Mng0MkxkcFUiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rTDYyeDQyTGRwVS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEJpVlJyMWFxZTFGOVJfUW1NX3ZGN21CaUJXVXciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkva0w2Mng0MkxkcFUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xEclRseDNwczNfSXk0cnF3Rmw0eEdvaFZPT2tnIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rTDYyeDQyTGRwVS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEI5b1doR1dESDk3aWkyY1BobGV6Ny1aQlZIVnciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2tMNjJ4NDJMZHBVL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ3BzQVAzdkRWaVJzZXhNOERVVU9IVm9xWkZNUSIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4lsaW1pbmVyIGTDqWZpbml0aXZlbWVudCB2b3MgYnVncyBncsOiY2Ugw6AgbGEgbcOpdGhvZGUgUElTQ0FSRSBkZSBQYXJpc1JCIGlsIHkgYSA0IG1vaXMgMjYgbWludXRlcyAyOTbCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiLDiWxpbWluZXIgZMOpZmluaXRpdmVtZW50IHZvcyBidWdzIGdyw6JjZSDDoCBsYSBtw6l0aG9kZSBQSVNDQVJFIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgNCBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjI5NsKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFVVFsRFVZQXlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9ESUtaeTFvYVdkb0xXTndkbG9ZVlVOR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTNtZ0VGRVBJNEdHV3FBUnBWVlV4UVJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1rTDYyeDQyTGRwVSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJrTDYyeDQyTGRwVSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjE2LS0tc24tNGd4eC0yNWdlbC5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD05MGJlYjZjNzhkOGI3Njk1XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTQ1NzUwMFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0VVUWxEVVlBeUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0VDVjdhM3MtTml0MzVBQnFnRWFWVlZNVUVaTFJUWlJTRWRRUVd0SlUwMXFNVk5SWkhGdWJuYz0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjI5NsKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjI5NsKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFa1FfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFa1FfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6ImtMNjJ4NDJMZHBVIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFa1FfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJrTDYyeDQyTGRwVSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbImtMNjJ4NDJMZHBVIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRWtRX3BnRUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRVVRbERVWUF5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0clREWXllRFF5VEdSd1ZRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRVVRbERVWUF5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDRWdRam1JaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRVVRbERVWUF5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNFVVFsRFVZQXlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMjYgbWludXRlcyBldCA1NMKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIyNjo1NCJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFY1EtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6ImtMNjJ4NDJMZHBVIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRWNRLWVjREdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJrTDYyeDQyTGRwVSJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNFY1EtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VZUXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VZUXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoia0w2Mng0MkxkcFUiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VZUXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbImtMNjJ4NDJMZHBVIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsia0w2Mng0MkxkcFUiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRVlReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6IkdULTJQOTRVOS1VIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvR1QtMlA5NFU5LVUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xETGhLdHZQdTRLdEp6OWtjTWNGOGFqckZMbjlnIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0dULTJQOTRVOS1VL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQUZtRGRMZTNId2dINlVDUVRZSFFSV0FoSU9fUSIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvR1QtMlA5NFU5LVUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xEc2dQMWxuZE1TTFpKcU9iZDl2NkxneDRWclJBIiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9HVC0yUDk0VTktVS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEJqdkNaS0dseXZyNDVmN3Vxc0JGaTcyTDZqc0EiLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik9wdGltaXNhdGlvbiBUQ1A6IGxlIGNsYXNoIGRlIFBhcmlzUkIgaWwgeSBhIDYgbW9pcyAxMyBtaW51dGVzIGV0IDTCoHNlY29uZGVzIDI1MMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6Ik9wdGltaXNhdGlvbiBUQ1A6IGxlIGNsYXNoIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgNiBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjI1MMKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFQVFsRFVZQkNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9ESUtaeTFvYVdkb0xXTndkbG9ZVlVOR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTNtZ0VGRVBJNEdHV3FBUnBWVlV4UVJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1HVC0yUDk0VTktVSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJHVC0yUDk0VTktVSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjEtLS1zbi0yNWdsZW5sZC5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD0xOTNmYjYzZmRlMTRmN2U1XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTY0ODc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0VBUWxEVVlCQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0VEbDc5UHdfY2Z0bnhtcUFScFZWVXhRUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3PT0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjI1MMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjI1MMKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFUVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFUVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IkdULTJQOTRVOS1VIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFUVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJHVC0yUDk0VTktVSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIkdULTJQOTRVOS1VIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRVFRX3BnRUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRUFRbERVWUJDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0SFZDMHlVRGswVlRrdFZRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRUFRbERVWUJDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDRU1Ram1JaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRUFRbERVWUJDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNFQVFsRFVZQkNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTMgbWludXRlcyBldCA0wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjEzOjA0In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VJUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiR1QtMlA5NFU5LVUiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFSVEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IkdULTJQOTRVOS1VIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0VJUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRUVReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRUVReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJHVC0yUDk0VTktVSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRUVReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiR1QtMlA5NFU5LVUiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJHVC0yUDk0VTktVSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNFRVF4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiTlg2Ymd5QjAxbWsiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OWDZiZ3lCMDFtay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEQ1T2YybGluc2ZkSW5wZnVxa1ZsdGh4dXUzc3ciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvTlg2Ymd5QjAxbWsvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xEbFIwM2gxQm5UWUwyQWZ1MlNKMnhaZldDWm5BIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OWDZiZ3lCMDFtay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEJSbHMtM09KZ2duZFZJSjQwUVBRWVZfUlBNTXciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL05YNmJneUIwMW1rL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQkN5ZUptNkxKcFFaN3VUd0otQl9scDFjV2o3dyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiUmFpbHMgOiBHw6lyZXIgc2VzIG1pZ3JhdGlvbnMgc2FucyBkb3dudGltZSBkZSBQYXJpc1JCIGlsIHkgYSAzIG1vaXMgMzIgbWludXRlcyAyNDPCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJSYWlscyA6IEfDqXJlciBzZXMgbWlncmF0aW9ucyBzYW5zIGRvd250aW1lIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgMyBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjI0M8KgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEc1FsRFVZQlNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9ESUtaeTFvYVdkb0xXTndkbG9ZVlVOR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTNtZ0VGRVBJNEdHV3FBUnBWVlV4UVJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1OWDZiZ3lCMDFtayIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJOWDZiZ3lCMDFtayIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjQtLS1zbi0yNWdsZW5sei5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD0zNTdlOWI4MzIwNzRkNjY5XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTY0ODc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0RzUWxEVVlCU0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0VEcHJOT0RzdkNtdnpXcUFScFZWVXhRUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3PT0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjI0M8KgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjI0M8KgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEOFFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEOFFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6Ik5YNmJneUIwMW1rIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEOFFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJOWDZiZ3lCMDFtayJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIk5YNmJneUIwMW1rIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRDhRX3BnRUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRHNRbERVWUJTSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0T1dEWmlaM2xDTURGdGF3JTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRHNRbERVWUJTSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDRDRRam1JaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRHNRbERVWUJTSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNEc1FsRFVZQlNJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMzIgbWludXRlcyBldCAzNcKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIzMjozNSJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEMFEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6Ik5YNmJneUIwMW1rIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRDBRLWVjREdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJOWDZiZ3lCMDFtayJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNEMFEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0R3UXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0R3UXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiTlg2Ymd5QjAxbWsiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0R3UXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIk5YNmJneUIwMW1rIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiTlg2Ymd5QjAxbWsiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRHdReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6InZLandhOGZpZThFIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvdktqd2E4ZmllOEUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xESnlUeG5aTVNyZ240N0pMaU1DWFAzOTBCZEF3Iiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3ZLandhOGZpZThFL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQm10T1p0d19uZGMzcXEtOENwSWxEbE5fUjZpdyIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvdktqd2E4ZmllOEUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xBX0VtV21jNnk3MFlSZjZSWEpma280VVZJY1l3Iiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92S2p3YThmaWU4RS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEN4RzVrOFNlQnJ2a0R0eHRUZ2lxZEhyWVNnRkEiLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkEgRGlmZmVyZW50IFdheSB0byBUaGluayBBYm91dCBSYWlscyBNb2RlbHMgW0VOXSBkZSBQYXJpc1JCIGlsIHkgYSAxIG1vaXMgMjUgbWludXRlcyAxNzjCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJBIERpZmZlcmVudCBXYXkgdG8gVGhpbmsgQWJvdXQgUmFpbHMgTW9kZWxzIFtFTl0ifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSAxIG1vaXMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMTc4wqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RZUWxEVVlCaUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0RJS1p5MW9hV2RvTFdOd2Rsb1lWVU5HUzBVMlVVaEhVRUZyU1ZOTmFqRlRVV1J4Ym01M21nRUZFUEk0R0dXcUFScFZWVXhRUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3PT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PXZLandhOGZpZThFIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6InZLandhOGZpZThFIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMTQtLS1zbi00Z3h4LTI1Z2VsLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZiZWlkcz0yNDM1MDAxOFx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWJjYThmMDZiYzdlMjdiYzFcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NDU3NTAwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPSJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDRFlRbERVWUJpSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRURCOTRtX3ZJMjgxTHdCcWdFYVZWVk1VRVpMUlRaUlNFZFFRV3RKVTAxcU1WTlJaSEZ1Ym5jPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTc4wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTc4wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RvUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RvUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoidktqd2E4ZmllOEUiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RvUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbInZLandhOGZpZThFIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsidktqd2E4ZmllOEUiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNEb1FfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEWVFsRFVZQmlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3QyUzJwM1lUaG1hV1U0UlElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEWVFsRFVZQmlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNEa1FqbUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNEWVFsRFVZQmlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0RZUWxEVVlCaUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIyNSBtaW51dGVzIGV0IDMywqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjI1OjMyIn0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RnUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoidktqd2E4ZmllOEUiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEZ1EtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6InZLandhOGZpZThFIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0RnUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRGNReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRGNReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJ2S2p3YThmaWU4RSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRGNReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsidktqd2E4ZmllOEUiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJ2S2p3YThmaWU4RSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNEY1F4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiTnV1X2NXaXV1ZEkiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OdXVfY1dpdXVkSS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTENRaVh6bTZ2aXlTT2oxR05IeE83d3dXOVMzVmciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvTnV1X2NXaXV1ZEkvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xBZnJtamlHRWFxOGtOS3lPUXp6MjE4QjQwTEd3Iiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OdXVfY1dpdXVkSS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTER2dWQ5N0w4QU5jXzYzN2FWX2w2ZjhCV05LR1EiLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL051dV9jV2l1dWRJL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQjVJUFpmbW51OU8tcVViVjdBQUMwNXBHRlJiZyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQ29tbWVudCBub3VzIGF2b25zIGRpdmlzw6kgbGVzIGJ1Z3MgcGFyIDMuNSBlbiB1biBhbiBkZSBQYXJpc1JCIGlsIHkgYSA1IG1vaXMgMjggbWludXRlcyAxNzjCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJDb21tZW50IG5vdXMgYXZvbnMgZGl2aXPDqSBsZXMgYnVncyBwYXIgMy41IGVuIHVuIGFuIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgNSBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjE3OMKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNERVFsRFVZQnlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9ESUtaeTFvYVdkb0xXTndkbG9ZVlVOR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTNtZ0VGRVBJNEdHV3FBUnBWVlV4UVJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1OdXVfY1dpdXVkSSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJOdXVfY1dpdXVkSSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjUtLS1zbi0yNWdsZW5sei5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD0zNmViYmY3MTY4YWViOWQyXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTY0ODc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0RFUWxEVVlCeUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0VEUzg3ckZsdTd2OVRhcUFScFZWVXhRUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3PT0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjE3OMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjE3OMKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEVVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEVVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6Ik51dV9jV2l1dWRJIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEVVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJOdXVfY1dpdXVkSSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIk51dV9jV2l1dWRJIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRFVRX3BnRUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDREVRbERVWUJ5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0T2RYVmZZMWRwZFhWa1NRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDREVRbERVWUJ5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDRFFRam1JaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDREVRbERVWUJ5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNERVFsRFVZQnlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMjggbWludXRlcyBldCA0NcKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIyODo0NSJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNETVEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6Ik51dV9jV2l1dWRJIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRE1RLWVjREdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJOdXVfY1dpdXVkSSJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNETVEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RJUXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RJUXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiTnV1X2NXaXV1ZEkiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RJUXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIk51dV9jV2l1dWRJIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiTnV1X2NXaXV1ZEkiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRElReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6IkRScklEUHppcnpFIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvRFJySURQemlyekUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xCZ2g5cFhmeVI1Z19PUTVJZnpiRkJORXppcHhBIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0RScklEUHppcnpFL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQ2YtQlBsaTBEY1RhVVhBOFZSREh5S01tSUIyUSIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvRFJySURQemlyekUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xEYXMxVWNqRmxxaE9zYWhuOG5iNXZTZnZyajRRIiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9EUnJJRFB6aXJ6RS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTERScnkzejVKeHByeTBhVnNtelQ5MUZwQU1QZUEiLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IlNvcmJldCBpbiBwcmFjdGljZSBkZSBQYXJpc1JCIGlsIHkgYSA2IG1vaXMgMjIgbWludXRlcyAxNzPCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJTb3JiZXQgaW4gcHJhY3RpY2UifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSA2IG1vaXMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMTczwqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0N3UWxEVVlDQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0RJS1p5MW9hV2RvTFdOd2Rsb1lWVU5HUzBVMlVVaEhVRUZyU1ZOTmFqRlRVV1J4Ym01M21nRUZFUEk0R0dXcUFScFZWVXhRUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3PT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PURScklEUHppcnpFIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IkRScklEUHppcnpFIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNS0tLXNuLTI1Z2xlbmxkLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZiZWlkcz0yNDM1MDAxOFx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTBkMWFjODBjZmNlMmFmMzFcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjMzNzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPSJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDQ3dRbERVWUNDSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRUN4M29ybno0R3lqUTJxQVJwVlZVeFFSa3RGTmxGSVIxQkJhMGxUVFdveFUxRmtjVzV1ZHc9PSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTczwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTczwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RBUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RBUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiRFJySURQemlyekUiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RBUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIkRScklEUHppcnpFIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiRFJySURQemlyekUiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNEQVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDd1FsRFVZQ0NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RFVW5KSlJGQjZhWEo2UlElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDd1FsRFVZQ0NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNDOFFqbUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNDd1FsRFVZQ0NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0N3UWxEVVlDQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIyMiBtaW51dGVzIGV0IDUxwqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjIyOjUxIn0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0M0US1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiRFJySURQemlyekUiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDNFEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IkRScklEUHppcnpFIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0M0US1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQzBReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQzBReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJEUnJJRFB6aXJ6RSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQzBReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiRFJySURQemlyekUiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJEUnJJRFB6aXJ6RSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNDMFF4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiNGFDWXI3ZC1Gb2siLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS80YUNZcjdkLUZvay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTENrbTd4ZXNXVkxxdXRIaENpUXFfSzgycU05d3ciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNGFDWXI3ZC1Gb2svaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xBblE0MHFYYW1aSmNXenBiUG1UT3lKVlZHSjRnIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS80YUNZcjdkLUZvay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTERoNGNmckJ1b1RxRGJhRktNRjlEYjNiR3Z3dHciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzRhQ1lyN2QtRm9rL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ1VaTmZaWjc0WTBQMnZWbWFNUnZycm1EeHhidyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiUmVhY3Qgb24gUmFpbHMsIGxlIG1laWxsZXVyIGRlcyBkZXV4IG1vbmRlcyBkZSBQYXJpc1JCIGlsIHkgYSAxIGFuIDI5IG1pbnV0ZXMgMTY5wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiUmVhY3Qgb24gUmFpbHMsIGxlIG1laWxsZXVyIGRlcyBkZXV4IG1vbmRlcyJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDEgYW4ifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMTY5wqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NjUWxEVVlDU0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0RJS1p5MW9hV2RvTFdOd2Rsb1lWVU5HUzBVMlVVaEhVRUZyU1ZOTmFqRlRVV1J4Ym01M21nRUZFUEk0R0dXcUFScFZWVXhRUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3PT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PTRhQ1lyN2QtRm9rIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IjRhQ1lyN2QtRm9rIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMi0tLXNuLTI1Z2U3bnprLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZiZWlkcz0yNDM1MDAxOFx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWUxYTA5OGFmYjc3ZTE2ODlcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjA1MDAwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPSJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDQ2NRbERVWUNTSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRUNKcmZpNy01V20wT0VCcWdFYVZWVk1VRVpMUlRaUlNFZFFRV3RKVTAxcU1WTlJaSEZ1Ym5jPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTY5wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTY5wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NzUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NzUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiNGFDWXI3ZC1Gb2siLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NzUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjRhQ1lyN2QtRm9rIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiNGFDWXI3ZC1Gb2siXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNDc1FfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDY1FsRFVZQ1NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3MwWVVOWmNqZGtMVVp2YXclM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDY1FsRFVZQ1NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNDb1FqbUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNDY1FsRFVZQ1NJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0NjUWxEVVlDU0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIyOSBtaW51dGVzIGV0IDMxwqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjI5OjMxIn0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NrUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiNGFDWXI3ZC1Gb2siLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDa1EtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IjRhQ1lyN2QtRm9rIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0NrUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ2dReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ2dReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiI0YUNZcjdkLUZvayIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ2dReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiNGFDWXI3ZC1Gb2siXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyI0YUNZcjdkLUZvayJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNDZ1F4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiNThkY05xZlpPeXciLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS81OGRjTnFmWk95dy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTERqeGdUUXFCMzYtLXJZSkZVeDVSeTlPZVRYZmciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNThkY05xZlpPeXcvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xCWVRNcGYwU1ZsdGdWdWFpU0hRYmlvWW1nSEZBIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS81OGRjTnFmWk95dy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEJNTktWN19pSGlUU203TVk1OV9HeFVkNWlTaWciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzU4ZGNOcWZaT3l3L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMRFl6cWpILWNMdU1qb2VqMTZQT3ZTYmRJZ2JQdyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiVmlvbGVuY2VzIHNleHVlbGxlcyBldCBzZXhpc3RlcyBldCBhdmVuaXIgZGUgUGFyaXMucmIgZGUgUGFyaXNSQiBpbCB5IGEgNSBtb2lzIDEyIG1pbnV0ZXMgZXQgNTfCoHNlY29uZGVzIDE1OMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IlZpb2xlbmNlcyBzZXh1ZWxsZXMgZXQgc2V4aXN0ZXMgZXQgYXZlbmlyIGRlIFBhcmlzLnJiIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgNSBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjE1OMKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDSVFsRFVZQ2lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9ESUtaeTFvYVdkb0xXTndkbG9ZVlVOR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTNtZ0VGRVBJNEdHV3FBUnBWVlV4UVJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj01OGRjTnFmWk95dyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiI1OGRjTnFmWk95dyIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjEwLS0tc24tNGd4eC0yNWd5Lmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZiZWlkcz0yNDM1MDAxOFx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWU3Yzc1YzM2YTdkOTNiMmNcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9MzkxMjUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPSJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDQ0lRbERVWUNpSVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPRUNzOXVTLTZvYlg0LWNCcWdFYVZWVk1VRVpMUlRaUlNFZFFRV3RKVTAxcU1WTlJaSEZ1Ym5jPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTU4wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTU4wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NZUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NZUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiNThkY05xZlpPeXciLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NZUV9wZ0VHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjU4ZGNOcWZaT3l3Il0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiNThkY05xZlpPeXciXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNDWVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDSVFsRFVZQ2lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3MxT0dSalRuRm1Xazk1ZHclM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDSVFsRFVZQ2lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNDVVFqbUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNDSVFsRFVZQ2lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0NJUWxEVVlDaUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxMiBtaW51dGVzIGV0IDU3wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjEyOjU3In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NRUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiNThkY05xZlpPeXciLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDUVEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IjU4ZGNOcWZaT3l3In1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0NRUS1lY0RHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ01ReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ01ReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiI1OGRjTnFmWk95dyIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ01ReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiNThkY05xZlpPeXciXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyI1OGRjTnFmWk95dyJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNDTVF4LXdFR0FJaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoicGtJbjRvNUt0dDQiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wa0luNG81S3R0NC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEJGUlVVR29wV3dlNGJIWEtjS2V3RElvang5bkEiLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvcGtJbjRvNUt0dDQvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xDdDc2aVVVLWdoZWluSHZQSmJGMUQ5eEJqdVZRIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wa0luNG81S3R0NC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEN0ZzJRaVJmSEpqSmtEQklHTTczSmgybElwS3ciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3BrSW40bzVLdHQ0L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ044bnVIV1Z5LVZUYUJyNDZhZzlaR3dzVDJZZyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiVGVzdGluZyBiZXN0IHByYWN0aWNlcyBkZSBQYXJpc1JCIGlsIHkgYSAzIG1vaXMgMzEgbWludXRlcyAxNTXCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJUZXN0aW5nIGJlc3QgcHJhY3RpY2VzIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgMyBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjE1NcKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNCMFFsRFVZQ3lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9ESUtaeTFvYVdkb0xXTndkbG9ZVlVOR1MwVTJVVWhIVUVGclNWTk5hakZUVVdSeGJtNTNtZ0VGRVBJNEdHV3FBUnBWVlV4UVJrdEZObEZJUjFCQmEwbFRUV294VTFGa2NXNXVkdz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1wa0luNG81S3R0NCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJwa0luNG81S3R0NCIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjE2LS0tc24tNGd4eC0yNWdlZS5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1hNjQyMjdlMjhlNGFiNmRlXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTQ1NzUwMFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0IwUWxEVVlDeUlUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0VEZTdhcnlxUHlKb2FZQnFnRWFWVlZNVUVaTFJUWlJTRWRRUVd0SlUwMXFNVk5SWkhGdWJuYz0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjE1NcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjE1NcKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDRVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDRVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6InBrSW40bzVLdHQ0IiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDRVFfcGdFR0FVaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJwa0luNG81S3R0NCJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbInBrSW40bzVLdHQ0Il19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDQ0VRX3BnRUdBVWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQjBRbERVWUN5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0d2EwbHVORzgxUzNSME5BJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQjBRbERVWUN5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDQ0FRam1JaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDQjBRbERVWUN5SVRDTFd4aVBhbnRQOENGYzhjQmdBZFM4Z0lPQT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNCMFFsRFVZQ3lJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMzEgbWludXRlcyBldCA0McKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIzMTo0MSJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNCOFEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6InBrSW40bzVLdHQ0IiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQjhRLWVjREdBRWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJwa0luNG81S3R0NCJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNCOFEtZWNER0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0I0UXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0I0UXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoicGtJbjRvNUt0dDQiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0I0UXgtd0VHQUlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbInBrSW40bzVLdHQ0Il0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsicGtJbjRvNUt0dDQiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDQjRReC13RUdBSWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19XSwidHJhY2tpbmdQYXJhbXMiOiJDQm9ReGpraUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJ2aXNpYmxlSXRlbUNvdW50Ijo0LCJuZXh0QnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfREVGQVVMVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwiaWNvbiI6eyJpY29uVHlwZSI6IkNIRVZST05fUklHSFQifSwiYWNjZXNzaWJpbGl0eSI6eyJsYWJlbCI6IlN1aXZhbnQifSwidHJhY2tpbmdQYXJhbXMiOiJDQndROEZzaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0sInByZXZpb3VzQnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfREVGQVVMVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwiaWNvbiI6eyJpY29uVHlwZSI6IkNIRVZST05fTEVGVCJ9LCJhY2Nlc3NpYmlsaXR5Ijp7ImxhYmVsIjoiUHLDqWPDqWRlbnRlIn0sInRyYWNraW5nUGFyYW1zIjoiQ0JzUThGc2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0JnUTNCd1lBQ0lUQ0xXeGlQYW50UDhDRmM4Y0JnQWRTOGdJT0E9PSIsInBsYXlBbGxCdXR0b24iOnsiYnV0dG9uUmVuZGVyZXIiOnsic3R5bGUiOiJTVFlMRV9URVhUIiwic2l6ZSI6IlNJWkVfREVGQVVMVCIsImlzRGlzYWJsZWQiOmZhbHNlLCJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJUb3V0IGxpcmUifV19LCJpY29uIjp7Imljb25UeXBlIjoiUExBWV9BTEwifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQmtROEZzaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PVpGYzRJYUdEdnNRXHUwMDI2bGlzdD1VVUxQRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJaRmM0SWFHRHZzUSIsInBsYXlsaXN0SWQiOiJVVUxQRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdocFZWVXhRUmt0Rk5sRklSMUJCYTBsVFRXb3hVMUZrY1c1dWR3JTNEJTNEIn19LCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnI3LS0tc24tNGd4eC0yNWdlZS5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2YmVpZHM9MjQzNTAwMThcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD02NDU3MzgyMWExODNiZWM0XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTQ1NzUwMFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz0ifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0JrUThGc2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19fX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNCY1F1eThZQWlJVENMV3hpUGFudFA4Q0ZjOGNCZ0FkUzhnSU9BPT0ifX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNCWVF1aThpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInRhcmdldElkIjoiYnJvd3NlLWZlZWRVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubndmZWF0dXJlZCIsImRpc2FibGVQdWxsVG9SZWZyZXNoIjp0cnVlfX0sInRyYWNraW5nUGFyYW1zIjoiQ0JVUThKTUJHQVVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRhYlJlbmRlcmVyIjp7ImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQlFROEpNQkdBWWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQHBhcmlzLXJiL3ZpZGVvcyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9DSEFOTkVMIiwicm9vdFZlIjozNjExLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlVDRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsInBhcmFtcyI6IkVnWjJhV1JsYjNQeUJnUUtBam9BIiwiY2Fub25pY2FsQmFzZVVybCI6Ii9AcGFyaXMtcmIifX0sInRpdGxlIjoiVmlkw6lvcyIsInRyYWNraW5nUGFyYW1zIjoiQ0JRUThKTUJHQVlpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRhYlJlbmRlcmVyIjp7ImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQk1ROEpNQkdBY2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQHBhcmlzLXJiL3BsYXlsaXN0cyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9DSEFOTkVMIiwicm9vdFZlIjozNjExLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlVDRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsInBhcmFtcyI6IkVnbHdiR0Y1YkdsemRIUHlCZ1FLQWtJQSIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQHBhcmlzLXJiIn19LCJ0aXRsZSI6IlBsYXlsaXN0cyIsInRyYWNraW5nUGFyYW1zIjoiQ0JNUThKTUJHQWNpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSx7InRhYlJlbmRlcmVyIjp7ImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQklROEpNQkdBZ2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQHBhcmlzLXJiL2NvbW11bml0eSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9DSEFOTkVMIiwicm9vdFZlIjozNjExLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlVDRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsInBhcmFtcyI6IkVnbGpiMjF0ZFc1cGRIbnlCZ1FLQWtvQSIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQHBhcmlzLXJiIn19LCJ0aXRsZSI6IkNvbW11bmF1dMOpIiwidHJhY2tpbmdQYXJhbXMiOiJDQklROEpNQkdBZ2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsidGFiUmVuZGVyZXIiOnsiZW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNCRVE4Sk1CR0FraUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AcGFyaXMtcmIvY2hhbm5lbHMiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCJwYXJhbXMiOiJFZ2hqYUdGdWJtVnNjX0lHQkFvQ1VnQSUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQHBhcmlzLXJiIn19LCJ0aXRsZSI6IkNoYcOubmVzIiwidHJhY2tpbmdQYXJhbXMiOiJDQkVROEpNQkdBa2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsidGFiUmVuZGVyZXIiOnsiZW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNCQVE4Sk1CR0FvaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AcGFyaXMtcmIvYWJvdXQiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCJwYXJhbXMiOiJFZ1ZoWW05MWRQSUdCQW9DRWdBJTNEIiwiY2Fub25pY2FsQmFzZVVybCI6Ii9AcGFyaXMtcmIifX0sInRpdGxlIjoiw4AgcHJvcG9zIiwidHJhY2tpbmdQYXJhbXMiOiJDQkFROEpNQkdBb2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9In19LHsiZXhwYW5kYWJsZVRhYlJlbmRlcmVyIjp7ImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQUFRaEdjaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AcGFyaXMtcmIvc2VhcmNoIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53IiwicGFyYW1zIjoiRWdaelpXRnlZMmp5QmdRS0Fsb0EiLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BwYXJpcy1yYiJ9fSwidGl0bGUiOiJSZWNoZXJjaGUiLCJzZWxlY3RlZCI6ZmFsc2V9fV19fSwiaGVhZGVyIjp7ImM0VGFiYmVkSGVhZGVyUmVuZGVyZXIiOnsiY2hhbm5lbElkIjoiVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53IiwidGl0bGUiOiJQYXJpc1JCIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQTBROERzaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AcGFyaXMtcmIiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BwYXJpcy1yYiJ9fSwiYXZhdGFyIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS90Q2JQUWFRN2tySEE1ano5aXFjRVc3b1pJcVE3eUFuVHFWQ25GUTFpZ1Etc1BDdXVzMXZYc1BQZUZFZHBzN19MRDltQ3lOYVNHQT1zNDgtYy1rLWMweDAwZmZmZmZmLW5vLXJqIiwid2lkdGgiOjQ4LCJoZWlnaHQiOjQ4fSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS90Q2JQUWFRN2tySEE1ano5aXFjRVc3b1pJcVE3eUFuVHFWQ25GUTFpZ1Etc1BDdXVzMXZYc1BQZUZFZHBzN19MRDltQ3lOYVNHQT1zODgtYy1rLWMweDAwZmZmZmZmLW5vLXJqIiwid2lkdGgiOjg4LCJoZWlnaHQiOjg4fSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS90Q2JQUWFRN2tySEE1ano5aXFjRVc3b1pJcVE3eUFuVHFWQ25GUTFpZ1Etc1BDdXVzMXZYc1BQZUZFZHBzN19MRDltQ3lOYVNHQT1zMTc2LWMtay1jMHgwMGZmZmZmZi1uby1yaiIsIndpZHRoIjoxNzYsImhlaWdodCI6MTc2fV19LCJiYW5uZXIiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3dIMVp2NVZSOUpNVzNFYjI4Q0k0Y3pnaEZCaWtZMjlmQ2lOcmp6Z1llS0draUtibGIwZE1pTDRqcDBPODUtVUVyWVFFQk11Q1lBPXcxMDYwLWZjcm9wNjQ9MSwwMDAwNWE1N2ZmZmZhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MTA2MCwiaGVpZ2h0IjoxNzV9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3dIMVp2NVZSOUpNVzNFYjI4Q0k0Y3pnaEZCaWtZMjlmQ2lOcmp6Z1llS0draUtibGIwZE1pTDRqcDBPODUtVUVyWVFFQk11Q1lBPXcxMTM4LWZjcm9wNjQ9MSwwMDAwNWE1N2ZmZmZhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MTEzOCwiaGVpZ2h0IjoxODh9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3dIMVp2NVZSOUpNVzNFYjI4Q0k0Y3pnaEZCaWtZMjlmQ2lOcmp6Z1llS0draUtibGIwZE1pTDRqcDBPODUtVUVyWVFFQk11Q1lBPXcxNzA3LWZjcm9wNjQ9MSwwMDAwNWE1N2ZmZmZhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MTcwNywiaGVpZ2h0IjoyODN9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3dIMVp2NVZSOUpNVzNFYjI4Q0k0Y3pnaEZCaWtZMjlmQ2lOcmp6Z1llS0draUtibGIwZE1pTDRqcDBPODUtVUVyWVFFQk11Q1lBPXcyMTIwLWZjcm9wNjQ9MSwwMDAwNWE1N2ZmZmZhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MjEyMCwiaGVpZ2h0IjozNTF9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3dIMVp2NVZSOUpNVzNFYjI4Q0k0Y3pnaEZCaWtZMjlmQ2lOcmp6Z1llS0draUtibGIwZE1pTDRqcDBPODUtVUVyWVFFQk11Q1lBPXcyMjc2LWZjcm9wNjQ9MSwwMDAwNWE1N2ZmZmZhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MjI3NiwiaGVpZ2h0IjozNzd9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3dIMVp2NVZSOUpNVzNFYjI4Q0k0Y3pnaEZCaWtZMjlmQ2lOcmp6Z1llS0draUtibGIwZE1pTDRqcDBPODUtVUVyWVFFQk11Q1lBPXcyNTYwLWZjcm9wNjQ9MSwwMDAwNWE1N2ZmZmZhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MjU2MCwiaGVpZ2h0Ijo0MjR9XX0sImhlYWRlckxpbmtzIjp7ImNoYW5uZWxIZWFkZXJMaW5rc1JlbmRlcmVyIjp7InByaW1hcnlMaW5rcyI6W3sibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQTBROERzaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3JlZGlyZWN0P2V2ZW50PWNoYW5uZWxfYmFubmVyXHUwMDI2cmVkaXJfdG9rZW49UVVGRkxVaHFhMk5PWkcxVmFuVnFTVUpVYlhadlMxQTBORFpPV1RWMVltNWZVWHhCUTNKdGMwdHJjM0pTUkc1VmQwZG5lR0ZJTmsxMlZqQlBMUzFDWWtwdE5HZFdhakJFUVVFMlNHdzNXVU5SWlZSVFVsQkdiV3c1Y1dZdGJtcFFabWRJVGt0elltZDZSVmR0YWxVMGJsQkdOMUJOYjNWTVN6QmlkVWM0WDA1dWNITklVVk5FUzFKMGJFaHNZekl0ZEhSWlNHeEVRa2RHT0FcdTAwMjZxPWh0dHBzJTNBJTJGJTJGd3d3LnR3aXRjaC50diUyRnBhcmlzX3JiIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1VOS05PV04iLCJyb290VmUiOjgzNzY5fX0sInVybEVuZHBvaW50Ijp7InVybCI6Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3JlZGlyZWN0P2V2ZW50PWNoYW5uZWxfYmFubmVyXHUwMDI2cmVkaXJfdG9rZW49UVVGRkxVaHFhMk5PWkcxVmFuVnFTVUpVYlhadlMxQTBORFpPV1RWMVltNWZVWHhCUTNKdGMwdHJjM0pTUkc1VmQwZG5lR0ZJTmsxMlZqQlBMUzFDWWtwdE5HZFdhakJFUVVFMlNHdzNXVU5SWlZSVFVsQkdiV3c1Y1dZdGJtcFFabWRJVGt0elltZDZSVmR0YWxVMGJsQkdOMUJOYjNWTVN6QmlkVWM0WDA1dWNITklVVk5FUzFKMGJFaHNZekl0ZEhSWlNHeEVRa2RHT0FcdTAwMjZxPWh0dHBzJTNBJTJGJTJGd3d3LnR3aXRjaC50diUyRnBhcmlzX3JiIiwidGFyZ2V0IjoiVEFSR0VUX05FV19XSU5ET1ciLCJub2ZvbGxvdyI6dHJ1ZX19LCJpY29uIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vZW5jcnlwdGVkLXRibjMuZ3N0YXRpYy5jb20vZmF2aWNvbi10Ym4/cT10Ym46QU5kOUdjU1ZWYlNHdUN6Y0VQamhhMkI5SlIyRFl1eEduWi1Fem1oc2xvVEpJX21wazJxR2pXZjBuRWhaTWJqaXdIUklXZEZ2amtCNVlMN1RlSFl4M3BsVnZWY2J4a3pySC12MDBtXzVPanBYQzg2akVBU2sifV19LCJ0aXRsZSI6eyJzaW1wbGVUZXh0IjoiVHdpdGNoIn19XSwic2Vjb25kYXJ5TGlua3MiOlt7Im5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0EwUThEc2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiJodHRwczovL3d3dy55b3V0dWJlLmNvbS9yZWRpcmVjdD9ldmVudD1jaGFubmVsX2Jhbm5lclx1MDAyNnJlZGlyX3Rva2VuPVFVRkZMVWhxYlVoeU1UbGFZbWMyWm14RmQyeFVjbXB3V0RoZmFXRmpSVVJMUVh4QlEzSnRjMHRyV2xGbWNGWjRiSFp5T1VkQ01qaFBOVmx2UjJSdlYwTkxaRzlHYUZJd2VHUjFZMEZRUWpOUWQzcGpWVlJyV1ZGNmQwVlJiMHBWYkcwMWFteGlaVmhVVUZWWlMwOW5kMnRHZDFnMFV6Wm5SV2xzT0c0NFJVTXpNVWhhZUZCWVZHSktTRXRrTXpWR1prSnNjMU5IU2tSUE9BXHUwMDI2cT1odHRwcyUzQSUyRiUyRnd3dy5tZWV0dXAuY29tJTJGcGFyaXNfcmIlMkYiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfVU5LTk9XTiIsInJvb3RWZSI6ODM3Njl9fSwidXJsRW5kcG9pbnQiOnsidXJsIjoiaHR0cHM6Ly93d3cueW91dHViZS5jb20vcmVkaXJlY3Q/ZXZlbnQ9Y2hhbm5lbF9iYW5uZXJcdTAwMjZyZWRpcl90b2tlbj1RVUZGTFVocWJVaHlNVGxhWW1jMlpteEZkMnhVY21wd1dEaGZhV0ZqUlVSTFFYeEJRM0p0YzB0cldsRm1jRlo0YkhaeU9VZENNamhQTlZsdlIyUnZWME5MWkc5R2FGSXdlR1IxWTBGUVFqTlFkM3BqVlZScldWRjZkMFZSYjBwVmJHMDFhbXhpWlZoVVVGVlpTMDluZDJ0R2QxZzBVelpuUldsc09HNDRSVU16TVVoYWVGQllWR0pLU0V0a016Vkdaa0pzYzFOSFNrUlBPQVx1MDAyNnE9aHR0cHMlM0ElMkYlMkZ3d3cubWVldHVwLmNvbSUyRnBhcmlzX3JiJTJGIiwidGFyZ2V0IjoiVEFSR0VUX05FV19XSU5ET1ciLCJub2ZvbGxvdyI6dHJ1ZX19LCJpY29uIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vZW5jcnlwdGVkLXRibjAuZ3N0YXRpYy5jb20vZmF2aWNvbi10Ym4/cT10Ym46QU5kOUdjVHJncHg2T1YwaFh3blc1VUhibUVWRTM5bU9LR2Vkb0Zma01neEhqNjRQYW9uUFRIZGl2cTdrTERTdURqLXZBS3F2NkxwTlhuS3BIZVhHRWRYSkNmZHdGcTVBcVI3NlRMWlpUeHR2aTZLX0piOExPZyJ9XX0sInRpdGxlIjp7InNpbXBsZVRleHQiOiJNZWV0dXAifX0seyJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBMFE4RHNpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiaHR0cHM6Ly93d3cueW91dHViZS5jb20vcmVkaXJlY3Q/ZXZlbnQ9Y2hhbm5lbF9iYW5uZXJcdTAwMjZyZWRpcl90b2tlbj1RVUZGTFVocWJWcEhORGRYTmt4eGMzTmxZWGg1UjJsRlVWZExlamMxVjJWTVFYeEJRM0p0YzB0dUxWOTBXVFpIWkZOVFQyTTNaR0YwY2xJeU1rVlNSM1ZXYUhKbVJFNWZUVU14WWkwMmRYWm1kMDFZWkY5RGRtSmtNSFpSUjBOVGNEWm1RVEIzZVU1VFZVUmtkWGc0T1VjMWNtcE9iRFJsTVVoYVFVZFhVbUl3YUhSWmREUjVZMUZaUW1samRsVjRZV0ZGTnpsMFJXZ3pWUVx1MDAyNnE9aHR0cHMlM0ElMkYlMkZwYXJpcy1yYi5vcmciLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfVU5LTk9XTiIsInJvb3RWZSI6ODM3Njl9fSwidXJsRW5kcG9pbnQiOnsidXJsIjoiaHR0cHM6Ly93d3cueW91dHViZS5jb20vcmVkaXJlY3Q/ZXZlbnQ9Y2hhbm5lbF9iYW5uZXJcdTAwMjZyZWRpcl90b2tlbj1RVUZGTFVocWJWcEhORGRYTmt4eGMzTmxZWGg1UjJsRlVWZExlamMxVjJWTVFYeEJRM0p0YzB0dUxWOTBXVFpIWkZOVFQyTTNaR0YwY2xJeU1rVlNSM1ZXYUhKbVJFNWZUVU14WWkwMmRYWm1kMDFZWkY5RGRtSmtNSFpSUjBOVGNEWm1RVEIzZVU1VFZVUmtkWGc0T1VjMWNtcE9iRFJsTVVoYVFVZFhVbUl3YUhSWmREUjVZMUZaUW1samRsVjRZV0ZGTnpsMFJXZ3pWUVx1MDAyNnE9aHR0cHMlM0ElMkYlMkZwYXJpcy1yYi5vcmciLCJ0YXJnZXQiOiJUQVJHRVRfTkVXX1dJTkRPVyIsIm5vZm9sbG93Ijp0cnVlfX0sImljb24iOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9lbmNyeXB0ZWQtdGJuMC5nc3RhdGljLmNvbS9mYXZpY29uLXRibj9xPXRibjpBTmQ5R2NUWnk0Wjc0N0I0TmlGTV8zWnExWDl6REdGUWUyeWVDQ1k4RVJzU0JSdjV0MVVYOGRxcXh1MzZyX3hEeThWTDQwcHY3eXJGMlBlTUNjMEgtV0VlVnBtenljckR1RFRPR3dFdUxzSlZuQXhhTkpvIn1dfSwidGl0bGUiOnsic2ltcGxlVGV4dCI6IlNpdGUifX1dfX0sInN1YnNjcmliZUJ1dHRvbiI6eyJidXR0b25SZW5kZXJlciI6eyJzdHlsZSI6IlNUWUxFX0RFU1RSVUNUSVZFIiwic2l6ZSI6IlNJWkVfREVGQVVMVCIsImlzRGlzYWJsZWQiOmZhbHNlLCJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJTJ2Fib25uZXIifV19LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBNFE4RnNpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsiaWdub3JlTmF2aWdhdGlvbiI6dHJ1ZX19LCJtb2RhbEVuZHBvaW50Ijp7Im1vZGFsIjp7Im1vZGFsV2l0aFRpdGxlQW5kQnV0dG9uUmVuZGVyZXIiOnsidGl0bGUiOnsic2ltcGxlVGV4dCI6IlZvdWxlei12b3VzIHZvdXMgYWJvbm5lciDDoCBjZXR0ZSBjaGHDrm5lwqA/In0sImNvbnRlbnQiOnsic2ltcGxlVGV4dCI6IkNvbm5lY3Rlei12b3VzIHBvdXIgdm91cyBhYm9ubmVyIMOgIGNldHRlIGNoYcOubmUuIn0sImJ1dHRvbiI6eyJidXR0b25SZW5kZXJlciI6eyJzdHlsZSI6IlNUWUxFX0JMVUVfVEVYVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwidGV4dCI6eyJzaW1wbGVUZXh0IjoiU2UgY29ubmVjdGVyIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0E4UV9ZWUVJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0TWdsemRXSnpZM0pwWW1VPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tL1NlcnZpY2VMb2dpbj9zZXJ2aWNlPXlvdXR1YmVcdTAwMjZ1aWxlbD0zXHUwMDI2cGFzc2l2ZT10cnVlXHUwMDI2Y29udGludWU9aHR0cHMlM0ElMkYlMkZ3d3cueW91dHViZS5jb20lMkZzaWduaW4lM0ZhY3Rpb25faGFuZGxlX3NpZ25pbiUzRHRydWUlMjZhcHAlM0RkZXNrdG9wJTI2aGwlM0RmciUyNm5leHQlM0QlMjUyRiUyNTQwcGFyaXMtcmIlMjZjb250aW51ZV9hY3Rpb24lM0RRVUZGTFVocWJIQlNhRWxKWmxvdGNrNXNjak5oZW1SMGVWTkZUVVZTUVdsWlFYeEJRM0p0YzB0dFVHVk1NSHAzV20xNmRYWTJkMWx6V0RST2FGUlhVbFpIVGtsSGVYaGpSWEJaUTFwT1FYaGFPR3RsZVhCc1UyeE1kRnBLUVRKMVpHMTRTRm96VWtnMFoya3RkbTUxTVUxMFpHWlNNbFowZVhWek9FWnVWMjVHTkdGNmNVNXVXSGwwWTNGWVNuQndVRGM1VmpZNVlXOHRkVTk1ZGkxS2NHSTJSSFoxUkZZd1IwNUJNbTVSYVVvd1VVNU1jRTV1U25SMk1scEtPRWRUZUVwdVpXNVVTRlF6Wm0xdVRHaGhVVWRZZDBsSWMxQlZaMk5xYVRKVFRteHpWMUpHVDJsYVowVTNYMUYzUmtNXHUwMDI2aGw9ZnJcdTAwMjZlYz02NjQyOSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9VTktOT1dOIiwicm9vdFZlIjo4Mzc2OX19LCJzaWduSW5FbmRwb2ludCI6eyJuZXh0RW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBOFFfWVlFSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL0BwYXJpcy1yYiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9DSEFOTkVMIiwicm9vdFZlIjozNjExLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlVDRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsInBhcmFtcyI6IkVnQSUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQHBhcmlzLXJiIn19LCJjb250aW51ZUFjdGlvbiI6IlFVRkZMVWhxYkhCU2FFbEpabG90Y2s1c2NqTmhlbVIwZVZORlRVVlNRV2xaUVh4QlEzSnRjMHR0VUdWTU1IcDNXbTE2ZFhZMmQxbHpXRFJPYUZSWFVsWkhUa2xIZVhoalJYQlpRMXBPUVhoYU9HdGxlWEJzVTJ4TWRGcEtRVEoxWkcxNFNGb3pVa2cwWjJrdGRtNTFNVTEwWkdaU01sWjBlWFZ6T0VadVYyNUdOR0Y2Y1U1dVdIbDBZM0ZZU25Cd1VEYzVWalk1WVc4dGRVOTVkaTFLY0dJMlJIWjFSRll3UjA1Qk1tNVJhVW93VVU1TWNFNXVTblIyTWxwS09FZFRlRXB1Wlc1VVNGUXpabTF1VEdoaFVVZFlkMGxJYzFCVloyTnFhVEpUVG14elYxSkdUMmxhWjBVM1gxRjNSa00iLCJpZGFtVGFnIjoiNjY0MjkifX0sInRyYWNraW5nUGFyYW1zIjoiQ0E4UV9ZWUVJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0In19fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDQTRROEZzaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0ifX0sInN1YnNjcmliZXJDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjE1NcKgYWJvbm7DqXMifX0sInNpbXBsZVRleHQiOiIxNTXCoGFib25uw6lzIn0sInR2QmFubmVyIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS93SDFadjVWUjlKTVczRWIyOENJNGN6Z2hGQmlrWTI5ZkNpTnJqemdZZUtHa2lLYmxiMGRNaUw0anAwTzg1LVVFcllRRUJNdUNZQT13MzIwLWZjcm9wNjQ9MSwwMDAwMDAwMGZmZmZmZmZmLWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MzIwLCJoZWlnaHQiOjE4MH0seyJ1cmwiOiJodHRwczovL3l0My5nb29nbGV1c2VyY29udGVudC5jb20vd0gxWnY1VlI5Sk1XM0ViMjhDSTRjemdoRkJpa1kyOWZDaU5yanpnWWVLR2tpS2JsYjBkTWlMNGpwME84NS1VRXJZUUVCTXVDWUE9dzg1NC1mY3JvcDY0PTEsMDAwMDAwMDBmZmZmZmZmZi1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjg1NCwiaGVpZ2h0Ijo0ODB9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3dIMVp2NVZSOUpNVzNFYjI4Q0k0Y3pnaEZCaWtZMjlmQ2lOcmp6Z1llS0draUtibGIwZE1pTDRqcDBPODUtVUVyWVFFQk11Q1lBPXcxMjgwLWZjcm9wNjQ9MSwwMDAwMDAwMGZmZmZmZmZmLWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MTI4MCwiaGVpZ2h0Ijo3MjB9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3dIMVp2NVZSOUpNVzNFYjI4Q0k0Y3pnaEZCaWtZMjlmQ2lOcmp6Z1llS0draUtibGIwZE1pTDRqcDBPODUtVUVyWVFFQk11Q1lBPXcxOTIwLWZjcm9wNjQ9MSwwMDAwMDAwMGZmZmZmZmZmLWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MTkyMCwiaGVpZ2h0IjoxMDgwfSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS93SDFadjVWUjlKTVczRWIyOENJNGN6Z2hGQmlrWTI5ZkNpTnJqemdZZUtHa2lLYmxiMGRNaUw0anAwTzg1LVVFcllRRUJNdUNZQT13MjEyMC1mY3JvcDY0PTEsMDAwMDAwMDBmZmZmZmZmZi1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjIxMjAsImhlaWdodCI6MTE5Mn1dfSwibW9iaWxlQmFubmVyIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS93SDFadjVWUjlKTVczRWIyOENJNGN6Z2hGQmlrWTI5ZkNpTnJqemdZZUtHa2lLYmxiMGRNaUw0anAwTzg1LVVFcllRRUJNdUNZQT13MzIwLWZjcm9wNjQ9MSwzMmI3NWE1N2NkNDhhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MzIwLCJoZWlnaHQiOjg4fSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS93SDFadjVWUjlKTVczRWIyOENJNGN6Z2hGQmlrWTI5ZkNpTnJqemdZZUtHa2lLYmxiMGRNaUw0anAwTzg1LVVFcllRRUJNdUNZQT13NjQwLWZjcm9wNjQ9MSwzMmI3NWE1N2NkNDhhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6NjQwLCJoZWlnaHQiOjE3NX0seyJ1cmwiOiJodHRwczovL3l0My5nb29nbGV1c2VyY29udGVudC5jb20vd0gxWnY1VlI5Sk1XM0ViMjhDSTRjemdoRkJpa1kyOWZDaU5yanpnWWVLR2tpS2JsYjBkTWlMNGpwME84NS1VRXJZUUVCTXVDWUE9dzk2MC1mY3JvcDY0PTEsMzJiNzVhNTdjZDQ4YTVhOC1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjk2MCwiaGVpZ2h0IjoyNjN9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3dIMVp2NVZSOUpNVzNFYjI4Q0k0Y3pnaEZCaWtZMjlmQ2lOcmp6Z1llS0draUtibGIwZE1pTDRqcDBPODUtVUVyWVFFQk11Q1lBPXcxMjgwLWZjcm9wNjQ9MSwzMmI3NWE1N2NkNDhhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MTI4MCwiaGVpZ2h0IjozNTF9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3dIMVp2NVZSOUpNVzNFYjI4Q0k0Y3pnaEZCaWtZMjlmQ2lOcmp6Z1llS0draUtibGIwZE1pTDRqcDBPODUtVUVyWVFFQk11Q1lBPXcxNDQwLWZjcm9wNjQ9MSwzMmI3NWE1N2NkNDhhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MTQ0MCwiaGVpZ2h0IjozOTV9XX0sInRyYWNraW5nUGFyYW1zIjoiQ0EwUThEc2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY2hhbm5lbEhhbmRsZVRleHQiOnsicnVucyI6W3sidGV4dCI6IkBwYXJpcy1yYiJ9XX0sInN0eWxlIjoiQzRfVEFCQkVEX0hFQURFUl9SRU5ERVJFUl9TVFlMRV9NT0RFUk4iLCJ2aWRlb3NDb3VudFRleHQiOnsicnVucyI6W3sidGV4dCI6IjM0In0seyJ0ZXh0IjoiwqB2aWTDqW9zIn1dfSwidGFnbGluZSI6eyJjaGFubmVsVGFnbGluZVJlbmRlcmVyIjp7ImNvbnRlbnQiOiJFbiBzYXZvaXIgcGx1cyBzdXIgY2V0dGUgY2hhw65uZSIsIm1heExpbmVzIjoxLCJtb3JlTGFiZWwiOiIuLi4gYWZmaWNoZXIgcGx1cyIsIm1vcmVFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0EwUThEc2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQHBhcmlzLXJiL2Fib3V0Iiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53IiwicGFyYW1zIjoiRWdWaFltOTFkUElHQkFvQ0VnQSUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQHBhcmlzLXJiIn19LCJtb3JlSWNvbiI6eyJpY29uVHlwZSI6IkNIRVZST05fUklHSFQifX19fX0sIm1ldGFkYXRhIjp7ImNoYW5uZWxNZXRhZGF0YVJlbmRlcmVyIjp7InRpdGxlIjoiUGFyaXNSQiIsImRlc2NyaXB0aW9uIjoiIiwicnNzVXJsIjoiaHR0cHM6Ly93d3cueW91dHViZS5jb20vZmVlZHMvdmlkZW9zLnhtbD9jaGFubmVsX2lkPVVDRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsImV4dGVybmFsSWQiOiJVQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCJrZXl3b3JkcyI6IiIsIm93bmVyVXJscyI6WyJodHRwOi8vd3d3LnlvdXR1YmUuY29tL0BwYXJpcy1yYiJdLCJhdmF0YXIiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3RDYlBRYVE3a3JIQTVqejlpcWNFVzdvWklxUTd5QW5UcVZDbkZRMWlnUS1zUEN1dXMxdlhzUFBlRkVkcHM3X0xEOW1DeU5hU0dBPXM5MDAtYy1rLWMweDAwZmZmZmZmLW5vLXJqIiwid2lkdGgiOjkwMCwiaGVpZ2h0Ijo5MDB9XX0sImNoYW5uZWxVcmwiOiJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsImlzRmFtaWx5U2FmZSI6dHJ1ZSwiYXZhaWxhYmxlQ291bnRyeUNvZGVzIjpbIk1PIiwiQkoiLCJNSCIsIk5PIiwiR0ciLCJGSiIsIlNWIiwiS0UiLCJHRiIsIkJSIiwiTEEiLCJNWiIsIlBLIiwiQ0EiLCJIVSIsIkJXIiwiTEsiLCJUTiIsIkJNIiwiS04iLCJTSCIsIlRIIiwiQ0YiLCJHUSIsIkFXIiwiVFYiLCJUTCIsIklUIiwiQ0siLCJCWiIsIkpPIiwiU0QiLCJHVSIsIklFIiwiRUgiLCJBVSIsIkdZIiwiTVQiLCJSRSIsIlpNIiwiQlQiLCJETSIsIkNYIiwiWlciLCJJTiIsIkxJIiwiR1ciLCJHUiIsIklNIiwiREoiLCJETyIsIkZNIiwiTloiLCJTWSIsIkRFIiwiTkwiLCJFVCIsIkNWIiwiR04iLCJFUyIsIkJWIiwiTFkiLCJTWiIsIlRLIiwiVkciLCJDUiIsIkFaIiwiTUEiLCJCUSIsIkVDIiwiTVgiLCJMVSIsIk1ZIiwiQ1oiLCJOVSIsIkFGIiwiU1giLCJBWCIsIlVBIiwiRk8iLCJOSSIsIkZJIiwiS1oiLCJNRyIsIkRLIiwiQkgiLCJUUiIsIkFJIiwiUEYiLCJJTCIsIkJCIiwiSk0iLCJCTiIsIlRXIiwiTkMiLCJWQyIsIktQIiwiQ0QiLCJQTCIsIklEIiwiVEQiLCJLVyIsIk9NIiwiQU0iLCJCUyIsIk5SIiwiTU0iLCJHQSIsIk1XIiwiU0IiLCJQTiIsIk1FIiwiVEYiLCJIVCIsIlBFIiwiQ0wiLCJUTyIsIkNXIiwiRUciLCJTQyIsIlNPIiwiWVQiLCJOUCIsIkFHIiwiQkQiLCJJUSIsIkxTIiwiTUYiLCJSVyIsIlBZIiwiQ1kiLCJCRyIsIkFEIiwiSlAiLCJCQSIsIkhNIiwiS00iLCJORSIsIlNTIiwiQVMiLCJMQyIsIkFSIiwiRFoiLCJDTSIsIldGIiwiSFIiLCJBUSIsIkdMIiwiU0ciLCJNVSIsIlRHIiwiTUsiLCJNUSIsIktIIiwiUUEiLCJLSSIsIlNOIiwiVFoiLCJMQiIsIlBXIiwiTkciLCJNUyIsIlZJIiwiTVYiLCJVRyIsIlVTIiwiVEoiLCJJTyIsIkVSIiwiSVMiLCJQTSIsIkFMIiwiS0ciLCJOQSIsIlBIIiwiVVoiLCJWTiIsIlBBIiwiSEsiLCJCWSIsIkFFIiwiSE4iLCJCRiIsIkxUIiwiQU8iLCJTSyIsIkpFIiwiUk8iLCJGUiIsIkFUIiwiTVIiLCJDTiIsIkNJIiwiU1QiLCJQVCIsIkNPIiwiV1MiLCJZRSIsIlZBIiwiRksiLCJFRSIsIlBHIiwiQ1UiLCJCTCIsIktZIiwiR0UiLCJHUyIsIlNNIiwiVE0iLCJMViIsIlVZIiwiUlUiLCJDQyIsIkdNIiwiR1QiLCJHSSIsIlBSIiwiTU4iLCJDRyIsIkdEIiwiTUQiLCJDSCIsIkJPIiwiTUwiLCJUQyIsIklSIiwiTVAiLCJHUCIsIlNKIiwiUFMiLCJCSSIsIlpBIiwiTkYiLCJSUyIsIlNMIiwiTUMiLCJHQiIsIlVNIiwiQkUiLCJTRSIsIlNSIiwiVkUiLCJMUiIsIlRUIiwiU0EiLCJTSSIsIktSIiwiR0giLCJWVSJdLCJhbmRyb2lkRGVlcExpbmsiOiJhbmRyb2lkLWFwcDovL2NvbS5nb29nbGUuYW5kcm9pZC55b3V0dWJlL2h0dHAvd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53IiwiYW5kcm9pZEFwcGluZGV4aW5nTGluayI6ImFuZHJvaWQtYXBwOi8vY29tLmdvb2dsZS5hbmRyb2lkLnlvdXR1YmUvaHR0cC93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnciLCJpb3NBcHBpbmRleGluZ0xpbmsiOiJpb3MtYXBwOi8vNTQ0MDA3NjY0L3ZuZC55b3V0dWJlL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsInZhbml0eUNoYW5uZWxVcmwiOiJodHRwOi8vd3d3LnlvdXR1YmUuY29tL0BwYXJpcy1yYiJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDQUFRaEdjaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJ0b3BiYXIiOnsiZGVza3RvcFRvcGJhclJlbmRlcmVyIjp7ImxvZ28iOnsidG9wYmFyTG9nb1JlbmRlcmVyIjp7Imljb25JbWFnZSI6eyJpY29uVHlwZSI6IllPVVRVQkVfTE9HTyJ9LCJ0b29sdGlwVGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWNjdWVpbCBZb3VUdWJlIn1dfSwiZW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBd1FzVjRpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiLyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9CUk9XU0UiLCJyb290VmUiOjM4NTQsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiRkV3aGF0X3RvX3dhdGNoIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNBd1FzVjRpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsIm92ZXJyaWRlRW50aXR5S2V5IjoiRWdaMGIzQmlZWElnOVFFb0FRJTNEJTNEIn19LCJzZWFyY2hib3giOnsiZnVzaW9uU2VhcmNoYm94UmVuZGVyZXIiOnsiaWNvbiI6eyJpY29uVHlwZSI6IlNFQVJDSCJ9LCJwbGFjZWhvbGRlclRleHQiOnsicnVucyI6W3sidGV4dCI6IlJlY2hlcmNoZXIifV19LCJjb25maWciOnsid2ViU2VhcmNoYm94Q29uZmlnIjp7InJlcXVlc3RMYW5ndWFnZSI6ImZyIiwicmVxdWVzdERvbWFpbiI6ImZyIiwiaGFzT25zY3JlZW5LZXlib2FyZCI6ZmFsc2UsImZvY3VzU2VhcmNoYm94Ijp0cnVlfX0sInRyYWNraW5nUGFyYW1zIjoiQ0FvUTdWQWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9Iiwic2VhcmNoRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBb1E3VkFpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3Jlc3VsdHM/c2VhcmNoX3F1ZXJ5PSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9TRUFSQ0giLCJyb290VmUiOjQ3MjR9fSwic2VhcmNoRW5kcG9pbnQiOnsicXVlcnkiOiIifX0sImNsZWFyQnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfREVGQVVMVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwiaWNvbiI6eyJpY29uVHlwZSI6IkNMT1NFIn0sInRyYWNraW5nUGFyYW1zIjoiQ0FzUThGc2lFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWNjZXNzaWJpbGl0eURhdGEiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJFZmZhY2VyIGxhIHJlcXXDqnRlIGRlIHJlY2hlcmNoZSJ9fX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0FFUXE2d0JJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0IiwiY291bnRyeUNvZGUiOiJGUiIsInRvcGJhckJ1dHRvbnMiOlt7InRvcGJhck1lbnVCdXR0b25SZW5kZXJlciI6eyJpY29uIjp7Imljb25UeXBlIjoiTU9SRV9WRVJUIn0sIm1lbnVSZXF1ZXN0Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQWdRX3FzQkdBQWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2FjY291bnQvYWNjb3VudF9tZW51In19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiR0VUX0FDQ09VTlRfTUVOVSIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQWdRX3FzQkdBQWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7Im11bHRpUGFnZU1lbnVSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNBa1FfNnNCSWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsInN0eWxlIjoiTVVMVElfUEFHRV9NRU5VX1NUWUxFX1RZUEVfU1lTVEVNIiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRST1BET1dOIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDQWdRX3FzQkdBQWlFd2kxc1lqMnA3VF9BaFhQSEFZQUhVdklDRGc9IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IlBhcmFtw6h0cmVzIn19LCJ0b29sdGlwIjoiUGFyYW3DqHRyZXMiLCJzdHlsZSI6IlNUWUxFX0RFRkFVTFQifX0seyJidXR0b25SZW5kZXJlciI6eyJzdHlsZSI6IlNUWUxFX1NVR0dFU1RJVkUiLCJzaXplIjoiU0laRV9TTUFMTCIsInRleHQiOnsicnVucyI6W3sidGV4dCI6IlNlIGNvbm5lY3RlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBVkFUQVJfTE9HR0VEX09VVCJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBY1ExSUFFR0FFaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9TZXJ2aWNlTG9naW4/c2VydmljZT15b3V0dWJlXHUwMDI2dWlsZWw9M1x1MDAyNnBhc3NpdmU9dHJ1ZVx1MDAyNmNvbnRpbnVlPWh0dHBzJTNBJTJGJTJGd3d3LnlvdXR1YmUuY29tJTJGc2lnbmluJTNGYWN0aW9uX2hhbmRsZV9zaWduaW4lM0R0cnVlJTI2YXBwJTNEZGVza3RvcCUyNmhsJTNEZnIlMjZuZXh0JTNEaHR0cHMlMjUzQSUyNTJGJTI1MkZ3d3cueW91dHViZS5jb20lMjUyRiUyNTQwcGFyaXMtcmIlMjUzRmNicmQlMjUzRDElMjUyNnVjYmNiJTI1M0QxXHUwMDI2aGw9ZnJcdTAwMjZlYz02NTYyMCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9VTktOT1dOIiwicm9vdFZlIjo4Mzc2OX19LCJzaWduSW5FbmRwb2ludCI6eyJpZGFtVGFnIjoiNjU2MjAifX0sInRyYWNraW5nUGFyYW1zIjoiQ0FjUTFJQUVHQUVpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInRhcmdldElkIjoidG9wYmFyLXNpZ25pbiJ9fV0sImhvdGtleURpYWxvZyI6eyJob3RrZXlEaWFsb2dSZW5kZXJlciI6eyJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiUmFjY291cmNpcyBjbGF2aWVyIn1dfSwic2VjdGlvbnMiOlt7ImhvdGtleURpYWxvZ1NlY3Rpb25SZW5kZXJlciI6eyJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiTGVjdHVyZSJ9XX0sIm9wdGlvbnMiOlt7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiTGVjdHVyZS9QYXVzZSJ9XX0sImhvdGtleSI6ImsifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IlJldmVuaXIgZW4gYXJyacOocmUgZGUgMTDCoHNlY29uZGVzIn1dfSwiaG90a2V5IjoiaiJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiQXZhbmNlciBkZSAxMMKgc2Vjb25kZXMifV19LCJob3RrZXkiOiJsIn19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJWaWTDqW8gcHLDqWPDqWRlbnRlIn1dfSwiaG90a2V5IjoiUCAoTUFKwqArIHApIn19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJWaWTDqW8gc3VpdmFudGUifV19LCJob3RrZXkiOiJOIChNQUrCoCsgbikifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkltYWdlIHByw6ljw6lkZW50ZSAoZW4gcGF1c2UpIn1dfSwiaG90a2V5IjoiLCIsImhvdGtleUFjY2Vzc2liaWxpdHlMYWJlbCI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IlZpcmd1bGUifX19fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiSW1hZ2Ugc3VpdmFudGUgKGVuIHBhdXNlKSJ9XX0sImhvdGtleSI6Ii4iLCJob3RrZXlBY2Nlc3NpYmlsaXR5TGFiZWwiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJQb2ludCJ9fX19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJEaW1pbnVlciBsYSB2aXRlc3NlIGRlIGxlY3R1cmUifV19LCJob3RrZXkiOiJcdTAwM2MgKFNISUZUKywpIiwiaG90a2V5QWNjZXNzaWJpbGl0eUxhYmVsIjp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQ2FyYWN0w6hyZSBpbmbDqXJpZXVyIG91IE1haiArIHZpcmd1bGUifX19fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiQXVnbWVudGVyIGxhIHZpdGVzc2UgZGUgbGVjdHVyZSJ9XX0sImhvdGtleSI6Ilx1MDAzZSAoU0hJRlQrLikiLCJob3RrZXlBY2Nlc3NpYmlsaXR5TGFiZWwiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJDYXJhY3TDqHJlIHN1cMOpcmlldXIgb3UgTWFqwqArIHBvaW50In19fX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkF0dGVpbmRyZSB1biBtb21lbnQgc3DDqWNpZmlxdWUgZGUgbGEgdmlkw6lvICg3IGNvcnJlc3BvbmQgw6AgNzDCoCUgZGUgbGEgZHVyw6llKSJ9XX0sImhvdGtleSI6IjAuLjkifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkFjY8OpZGVyIGF1IGNoYXBpdHJlIHByw6ljw6lkZW50In1dfSwiaG90a2V5IjoiQ09OVFLDlExFwqArIOKGkCJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWNjw6lkZXIgYXUgY2hhcGl0cmUgc3VpdmFudCJ9XX0sImhvdGtleSI6IkNPTlRSw5RMRcKgKyDihpIifX1dfX0seyJob3RrZXlEaWFsb2dTZWN0aW9uUmVuZGVyZXIiOnsidGl0bGUiOnsicnVucyI6W3sidGV4dCI6IkfDqW7DqXJhbCJ9XX0sIm9wdGlvbnMiOlt7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWN0aXZlci9kw6lzYWN0aXZlciBsZSBtb2RlIHBsZWluIMOpY3JhbiJ9XX0sImhvdGtleSI6ImYifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkFjdGl2ZXIvRMOpc2FjdGl2ZXIgbGUgbW9kZSBjaW7DqW1hIn1dfSwiaG90a2V5IjoidCJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWN0aXZlci9Ew6lzYWN0aXZlciBsZSBsZWN0ZXVyIHLDqWR1aXQifV19LCJob3RrZXkiOiJpIn19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJGZXJtZXIgbGUgbGVjdGV1ciByw6lkdWl0IG91IGxhIGJvw650ZSBkZSBkaWFsb2d1ZSBhY3R1ZWxsZSJ9XX0sImhvdGtleSI6IsOJQ0hBUCJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWN0aXZlci9Ew6lzYWN0aXZlciBsZSBzb24ifV19LCJob3RrZXkiOiJtIn19XX19LHsiaG90a2V5RGlhbG9nU2VjdGlvblJlbmRlcmVyIjp7InRpdGxlIjp7InJ1bnMiOlt7InRleHQiOiJTb3VzLXRpdHJlcyJ9XX0sIm9wdGlvbnMiOlt7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiU2kgbGEgdmlkw6lvIGVzdCBjb21wYXRpYmxlIGF2ZWMgbGVzIHNvdXMtdGl0cmVzLCBsZXMgYWN0aXZlciBvdSBsZXMgZMOpc2FjdGl2ZXIifV19LCJob3RrZXkiOiJjIn19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJBbHRlcm5lciBlbnRyZSBsZXMgZGlmZsOpcmVudHMgbml2ZWF1eCBkJ29wYWNpdMOpIGR1IHRleHRlIn1dfSwiaG90a2V5IjoibyJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWx0ZXJuZXIgZW50cmUgbGVzIGRpZmbDqXJlbnRzIG5pdmVhdXggZCdvcGFjaXTDqSBkZSBsYSBmZW7DqnRyZSJ9XX0sImhvdGtleSI6IncifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkFsdGVybmVyIGVudHJlIGxlcyB0YWlsbGVzIGRlIHBvbGljZSAoYXVnbWVudGF0aW9uKSJ9XX0sImhvdGtleSI6IisifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkFsdGVybmVyIGVudHJlIGxlcyB0YWlsbGVzIGRlIHBvbGljZSAoZGltaW51dGlvbikifV19LCJob3RrZXkiOiItIiwiaG90a2V5QWNjZXNzaWJpbGl0eUxhYmVsIjp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTW9pbnMifX19fV19fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25SZW5kZXJlciI6eyJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiVmlkw6lvcyBzcGjDqXJpcXVlcyJ9XX0sIm9wdGlvbnMiOlt7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiRMOpcGxhY2VyIHZlcnMgbGUgaGF1dCJ9XX0sImhvdGtleSI6IncifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IlBhbm9yYW1pcXVlIHZlcnMgbGEgZ2F1Y2hlIn1dfSwiaG90a2V5IjoiYSJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFub3JhbWlxdWUgdmVycyBsZSBiYXMifV19LCJob3RrZXkiOiJzIn19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJQYW5vcmFtaXF1ZSB2ZXJzIGxhIGRyb2l0ZSJ9XX0sImhvdGtleSI6ImQifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkZhaXJlIHVuIHpvb20gYXZhbnQifV19LCJob3RrZXkiOiIrIHN1ciBsZSBwYXbDqSBudW3DqXJpcXVlIG91IF0iLCJob3RrZXlBY2Nlc3NpYmlsaXR5TGFiZWwiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJDYXJhY3TDqHJlIHBsdXMgc3VyIGxlIGNsYXZpZXIgbnVtw6lyaXF1ZSBvdSBjcm9jaGV0IGZlcm1hbnQifX19fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiRmFpcmUgdW4gem9vbSBhcnJpw6hyZSJ9XX0sImhvdGtleSI6Ii0gc3VyIGxlIHBhdsOpIG51bcOpcmlxdWUgb3UgWyIsImhvdGtleUFjY2Vzc2liaWxpdHlMYWJlbCI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkNhcmFjdMOocmUgbW9pbnMgc3VyIGxlIGNsYXZpZXIgbnVtw6lyaXF1ZSBvdSBjcm9jaGV0IG91dnJhbnQifX19fV19fV0sImRpc21pc3NCdXR0b24iOnsiYnV0dG9uUmVuZGVyZXIiOnsic3R5bGUiOiJTVFlMRV9CTFVFX1RFWFQiLCJzaXplIjoiU0laRV9ERUZBVUxUIiwiaXNEaXNhYmxlZCI6ZmFsc2UsInRleHQiOnsicnVucyI6W3sidGV4dCI6Iklnbm9yZXIifV19LCJ0cmFja2luZ1BhcmFtcyI6IkNBWVE4RnNpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDQVVRdGVZREloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQifX0sImJhY2tCdXR0b24iOnsiYnV0dG9uUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDQVFRdklZREloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQVFRdklZREloTUl0YkdJOXFlMF93SVZ6eHdHQUIxTHlBZzQiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBUVF2SVlESWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsInNpZ25hbEFjdGlvbiI6eyJzaWduYWwiOiJISVNUT1JZX0JBQ0sifX1dfX19fSwiZm9yd2FyZEJ1dHRvbiI6eyJidXR0b25SZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNBTVF2WVlESWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBTVF2WVlESWhNSXRiR0k5cWUwX3dJVnp4d0dBQjFMeUFnNCIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0FNUXZZWURJaE1JdGJHSTlxZTBfd0lWenh3R0FCMUx5QWc0Iiwic2lnbmFsQWN0aW9uIjp7InNpZ25hbCI6IkhJU1RPUllfRk9SV0FSRCJ9fV19fX19LCJhMTF5U2tpcE5hdmlnYXRpb25CdXR0b24iOnsiYnV0dG9uUmVuZGVyZXIiOnsic3R5bGUiOiJTVFlMRV9ERUZBVUxUIiwic2l6ZSI6IlNJWkVfREVGQVVMVCIsImlzRGlzYWJsZWQiOmZhbHNlLCJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJJZ25vcmVyIGxlcyBsaWVucyBkZSBuYXZpZ2F0aW9uIn1dfSwidHJhY2tpbmdQYXJhbXMiOiJDQUlROEZzaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQUlROEZzaUV3aTFzWWoycDdUX0FoWFBIQVlBSFV2SUNEZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBSVE4RnNpRXdpMXNZajJwN1RfQWhYUEhBWUFIVXZJQ0RnPSIsInNpZ25hbEFjdGlvbiI6eyJzaWduYWwiOiJTS0lQX05BVklHQVRJT04ifX1dfX19fX19LCJtaWNyb2Zvcm1hdCI6eyJtaWNyb2Zvcm1hdERhdGFSZW5kZXJlciI6eyJ1cmxDYW5vbmljYWwiOiJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsInRpdGxlIjoiUGFyaXNSQiIsImRlc2NyaXB0aW9uIjoiIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS90Q2JQUWFRN2tySEE1ano5aXFjRVc3b1pJcVE3eUFuVHFWQ25GUTFpZ1Etc1BDdXVzMXZYc1BQZUZFZHBzN19MRDltQ3lOYVNHQT1zMjAwLWMtay1jMHgwMGZmZmZmZi1uby1yaj9kYXlzX3NpbmNlX2Vwb2NoPTE5NTE2Iiwid2lkdGgiOjIwMCwiaGVpZ2h0IjoyMDB9XX0sInNpdGVOYW1lIjoiWW91VHViZSIsImFwcE5hbWUiOiJZb3VUdWJlIiwiYW5kcm9pZFBhY2thZ2UiOiJjb20uZ29vZ2xlLmFuZHJvaWQueW91dHViZSIsImlvc0FwcFN0b3JlSWQiOiI1NDQwMDc2NjQiLCJpb3NBcHBBcmd1bWVudHMiOiJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udyIsIm9nVHlwZSI6Inl0LWZiLWFwcDpjaGFubmVsIiwidXJsQXBwbGlua3NXZWIiOiJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udz9mZWF0dXJlPWFwcGxpbmtzIiwidXJsQXBwbGlua3NJb3MiOiJ2bmQueW91dHViZTovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udz9mZWF0dXJlPWFwcGxpbmtzIiwidXJsQXBwbGlua3NBbmRyb2lkIjoidm5kLnlvdXR1YmU6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ0ZLRTZRSEdQQWtJU01qMVNRZHFubnc/ZmVhdHVyZT1hcHBsaW5rcyIsInVybFR3aXR0ZXJJb3MiOiJ2bmQueW91dHViZTovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udz9mZWF0dXJlPXR3aXR0ZXItZGVlcC1saW5rIiwidXJsVHdpdHRlckFuZHJvaWQiOiJ2bmQueW91dHViZTovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDRktFNlFIR1BBa0lTTWoxU1FkcW5udz9mZWF0dXJlPXR3aXR0ZXItZGVlcC1saW5rIiwidHdpdHRlckNhcmRUeXBlIjoic3VtbWFyeSIsInR3aXR0ZXJTaXRlSGFuZGxlIjoiQFlvdVR1YmUiLCJzY2hlbWFEb3RPcmdUeXBlIjoiaHR0cDovL3NjaGVtYS5vcmcvaHR0cDovL3NjaGVtYS5vcmcvWW91dHViZUNoYW5uZWxWMiIsIm5vaW5kZXgiOmZhbHNlLCJ1bmxpc3RlZCI6ZmFsc2UsImZhbWlseVNhZmUiOnRydWUsImF2YWlsYWJsZUNvdW50cmllcyI6WyJNTyIsIkJKIiwiTUgiLCJOTyIsIkdHIiwiRkoiLCJTViIsIktFIiwiR0YiLCJCUiIsIkxBIiwiTVoiLCJQSyIsIkNBIiwiSFUiLCJCVyIsIkxLIiwiVE4iLCJCTSIsIktOIiwiU0giLCJUSCIsIkNGIiwiR1EiLCJBVyIsIlRWIiwiVEwiLCJJVCIsIkNLIiwiQloiLCJKTyIsIlNEIiwiR1UiLCJJRSIsIkVIIiwiQVUiLCJHWSIsIk1UIiwiUkUiLCJaTSIsIkJUIiwiRE0iLCJDWCIsIlpXIiwiSU4iLCJMSSIsIkdXIiwiR1IiLCJJTSIsIkRKIiwiRE8iLCJGTSIsIk5aIiwiU1kiLCJERSIsIk5MIiwiRVQiLCJDViIsIkdOIiwiRVMiLCJCViIsIkxZIiwiU1oiLCJUSyIsIlZHIiwiQ1IiLCJBWiIsIk1BIiwiQlEiLCJFQyIsIk1YIiwiTFUiLCJNWSIsIkNaIiwiTlUiLCJBRiIsIlNYIiwiQVgiLCJVQSIsIkZPIiwiTkkiLCJGSSIsIktaIiwiTUciLCJESyIsIkJIIiwiVFIiLCJBSSIsIlBGIiwiSUwiLCJCQiIsIkpNIiwiQk4iLCJUVyIsIk5DIiwiVkMiLCJLUCIsIkNEIiwiUEwiLCJJRCIsIlREIiwiS1ciLCJPTSIsIkFNIiwiQlMiLCJOUiIsIk1NIiwiR0EiLCJNVyIsIlNCIiwiUE4iLCJNRSIsIlRGIiwiSFQiLCJQRSIsIkNMIiwiVE8iLCJDVyIsIkVHIiwiU0MiLCJTTyIsIllUIiwiTlAiLCJBRyIsIkJEIiwiSVEiLCJMUyIsIk1GIiwiUlciLCJQWSIsIkNZIiwiQkciLCJBRCIsIkpQIiwiQkEiLCJITSIsIktNIiwiTkUiLCJTUyIsIkFTIiwiTEMiLCJBUiIsIkRaIiwiQ00iLCJXRiIsIkhSIiwiQVEiLCJHTCIsIlNHIiwiTVUiLCJURyIsIk1LIiwiTVEiLCJLSCIsIlFBIiwiS0kiLCJTTiIsIlRaIiwiTEIiLCJQVyIsIk5HIiwiTVMiLCJWSSIsIk1WIiwiVUciLCJVUyIsIlRKIiwiSU8iLCJFUiIsIklTIiwiUE0iLCJBTCIsIktHIiwiTkEiLCJQSCIsIlVaIiwiVk4iLCJQQSIsIkhLIiwiQlkiLCJBRSIsIkhOIiwiQkYiLCJMVCIsIkFPIiwiU0siLCJKRSIsIlJPIiwiRlIiLCJBVCIsIk1SIiwiQ04iLCJDSSIsIlNUIiwiUFQiLCJDTyIsIldTIiwiWUUiLCJWQSIsIkZLIiwiRUUiLCJQRyIsIkNVIiwiQkwiLCJLWSIsIkdFIiwiR1MiLCJTTSIsIlRNIiwiTFYiLCJVWSIsIlJVIiwiQ0MiLCJHTSIsIkdUIiwiR0kiLCJQUiIsIk1OIiwiQ0ciLCJHRCIsIk1EIiwiQ0giLCJCTyIsIk1MIiwiVEMiLCJJUiIsIk1QIiwiR1AiLCJTSiIsIlBTIiwiQkkiLCJaQSIsIk5GIiwiUlMiLCJTTCIsIk1DIiwiR0IiLCJVTSIsIkJFIiwiU0UiLCJTUiIsIlZFIiwiTFIiLCJUVCIsIlNBIiwiU0kiLCJLUiIsIkdIIiwiVlUiXSwibGlua0FsdGVybmF0ZXMiOlt7ImhyZWZVcmwiOiJodHRwczovL20ueW91dHViZS5jb20vY2hhbm5lbC9VQ0ZLRTZRSEdQQWtJU01qMVNRZHFubncifSx7ImhyZWZVcmwiOiJhbmRyb2lkLWFwcDovL2NvbS5nb29nbGUuYW5kcm9pZC55b3V0dWJlL2h0dHAveW91dHViZS5jb20vY2hhbm5lbC9VQ0ZLRTZRSEdQQWtJU01qMVNRZHFubncifSx7ImhyZWZVcmwiOiJpb3MtYXBwOi8vNTQ0MDA3NjY0L2h0dHAveW91dHViZS5jb20vY2hhbm5lbC9VQ0ZLRTZRSEdQQWtJU01qMVNRZHFubncifV19fX07PC9zY3JpcHQ+PHNjcmlwdCBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+aWYgKHdpbmRvdy55dGNzaSkge3dpbmRvdy55dGNzaS50aWNrKCdwZHInLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPihmdW5jdGlvbiBzZXJ2ZXJDb250cmFjdCgpIHt3aW5kb3dbJ3l0UGFnZVR5cGUnXSA9ICJjaGFubmVsIjt3aW5kb3dbJ3l0Q29tbWFuZCddID0geyJjbGlja1RyYWNraW5nUGFyYW1zIjoiSWhNSXVJcUg5cWUwX3dJVmtkM1ZDaDFueEFhZ01naGxlSFJsY201aGJBPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AcGFyaXMtcmIiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9LCJyZXNvbHZlVXJsQ29tbWFuZE1ldGFkYXRhIjp7ImlzVmFuaXR5VXJsIjp0cnVlfX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNGS0U2UUhHUEFrSVNNajFTUWRxbm53IiwicGFyYW1zIjoiRWdDNEFRQ1NBd0R5QmdRS0FqSUEifX07d2luZG93Wyd5dFVybCddID0gJ1wvQHBhcmlzLXJiP2NicmRceDNkMVx4MjZ1Y2JjYlx4M2QxJzt2YXIgYT13aW5kb3c7KGZ1bmN0aW9uKGUpe3ZhciBjPXdpbmRvdztjLmdldEluaXRpYWxDb21tYW5kPWZ1bmN0aW9uKCl7cmV0dXJuIGV9O2MubG9hZEluaXRpYWxDb21tYW5kJiZjLmxvYWRJbml0aWFsQ29tbWFuZChjLmdldEluaXRpYWxDb21tYW5kKCkpfSkoYS55dENvbW1hbmQpOwooZnVuY3Rpb24oZSxjLGwsZixnLGgsayl7dmFyIGQ9d2luZG93O2QuZ2V0SW5pdGlhbERhdGE9ZnVuY3Rpb24oKXt2YXIgYj13aW5kb3c7Yi55dGNzaSYmYi55dGNzaS50aWNrKCJwciIsbnVsbCwiIik7Yj17cGFnZTplLGVuZHBvaW50OmMscmVzcG9uc2U6bH07ZiYmKGIucGxheWVyUmVzcG9uc2U9Zik7ZyYmKGIucmVlbFdhdGNoU2VxdWVuY2VSZXNwb25zZT1nKTtrJiYoYi51cmw9ayk7aCYmKGIucHJldmlvdXNDc249aCk7cmV0dXJuIGJ9O2QubG9hZEluaXRpYWxEYXRhJiZkLmxvYWRJbml0aWFsRGF0YShkLmdldEluaXRpYWxEYXRhKCkpfSkoYS55dFBhZ2VUeXBlLGEueXRDb21tYW5kLGEueXRJbml0aWFsRGF0YSxhLnl0SW5pdGlhbFBsYXllclJlc3BvbnNlLGEueXRJbml0aWFsUmVlbFdhdGNoU2VxdWVuY2VSZXNwb25zZSxhLnl0UHJldmlvdXNDc24sYS55dFVybCk7Cn0pKCk7PC9zY3JpcHQ+PGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9zL2Rlc2t0b3AvMzc0ZmFhZDUvY3NzYmluL3d3dy1tYWluLWRlc2t0b3Atd2F0Y2gtcGFnZS1za2VsZXRvbi5jc3MiIG5hbWU9Ind3dy1tYWluLWRlc2t0b3Atd2F0Y2gtcGFnZS1za2VsZXRvbiIgbm9uY2U9IndLcXgyNTcyMHVqdW1hVXZCSC1UeFEiPjxkaXYgaWQ9IndhdGNoLXBhZ2Utc2tlbGV0b24iIGNsYXNzPSJ3YXRjaC1za2VsZXRvbiAgaGlkZGVuIj48ZGl2IGlkPSJjb250YWluZXIiPjxkaXYgaWQ9InJlbGF0ZWQiPjxkaXYgY2xhc3M9ImF1dG9wbGF5IHNrZWxldG9uLWxpZ2h0LWJvcmRlci1ib3R0b20iPjxkaXYgaWQ9InVwbmV4dCIgY2xhc3M9InNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1za2VsZXRvbiI+PGRpdiBjbGFzcz0idmlkZW8tZGV0YWlscyI+PGRpdiBjbGFzcz0idGh1bWJuYWlsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJkZXRhaWxzIGZsZXgtMSI+PGRpdiBjbGFzcz0idmlkZW8tdGl0bGUgdGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0idmlkZW8tbWV0YSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1za2VsZXRvbiI+PGRpdiBjbGFzcz0idmlkZW8tZGV0YWlscyI+PGRpdiBjbGFzcz0idGh1bWJuYWlsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJkZXRhaWxzIGZsZXgtMSI+PGRpdiBjbGFzcz0idmlkZW8tdGl0bGUgdGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0idmlkZW8tbWV0YSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1za2VsZXRvbiI+PGRpdiBjbGFzcz0idmlkZW8tZGV0YWlscyI+PGRpdiBjbGFzcz0idGh1bWJuYWlsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJkZXRhaWxzIGZsZXgtMSI+PGRpdiBjbGFzcz0idmlkZW8tdGl0bGUgdGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0idmlkZW8tbWV0YSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1za2VsZXRvbiI+PGRpdiBjbGFzcz0idmlkZW8tZGV0YWlscyI+PGRpdiBjbGFzcz0idGh1bWJuYWlsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJkZXRhaWxzIGZsZXgtMSI+PGRpdiBjbGFzcz0idmlkZW8tdGl0bGUgdGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0idmlkZW8tbWV0YSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1za2VsZXRvbiI+PGRpdiBjbGFzcz0idmlkZW8tZGV0YWlscyI+PGRpdiBjbGFzcz0idGh1bWJuYWlsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJkZXRhaWxzIGZsZXgtMSI+PGRpdiBjbGFzcz0idmlkZW8tdGl0bGUgdGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0idmlkZW8tbWV0YSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1za2VsZXRvbiI+PGRpdiBjbGFzcz0idmlkZW8tZGV0YWlscyI+PGRpdiBjbGFzcz0idGh1bWJuYWlsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJkZXRhaWxzIGZsZXgtMSI+PGRpdiBjbGFzcz0idmlkZW8tdGl0bGUgdGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0idmlkZW8tbWV0YSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1za2VsZXRvbiI+PGRpdiBjbGFzcz0idmlkZW8tZGV0YWlscyI+PGRpdiBjbGFzcz0idGh1bWJuYWlsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJkZXRhaWxzIGZsZXgtMSI+PGRpdiBjbGFzcz0idmlkZW8tdGl0bGUgdGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0idmlkZW8tbWV0YSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1za2VsZXRvbiI+PGRpdiBjbGFzcz0idmlkZW8tZGV0YWlscyI+PGRpdiBjbGFzcz0idGh1bWJuYWlsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJkZXRhaWxzIGZsZXgtMSI+PGRpdiBjbGFzcz0idmlkZW8tdGl0bGUgdGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0idmlkZW8tbWV0YSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1za2VsZXRvbiI+PGRpdiBjbGFzcz0idmlkZW8tZGV0YWlscyI+PGRpdiBjbGFzcz0idGh1bWJuYWlsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJkZXRhaWxzIGZsZXgtMSI+PGRpdiBjbGFzcz0idmlkZW8tdGl0bGUgdGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0idmlkZW8tbWV0YSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1za2VsZXRvbiI+PGRpdiBjbGFzcz0idmlkZW8tZGV0YWlscyI+PGRpdiBjbGFzcz0idGh1bWJuYWlsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJkZXRhaWxzIGZsZXgtMSI+PGRpdiBjbGFzcz0idmlkZW8tdGl0bGUgdGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0idmlkZW8tbWV0YSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGlkPSJpbmZvLWNvbnRhaW5lciI+PGRpdiBpZD0icHJpbWFyeS1pbmZvIiBjbGFzcz0ic2tlbGV0b24tbGlnaHQtYm9yZGVyLWJvdHRvbSI+PGRpdiBpZD0idGl0bGUiIGNsYXNzPSJ0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGlkPSJpbmZvIj48ZGl2IGlkPSJjb3VudCIgY2xhc3M9InRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImZsZXgtMSI+PC9kaXY+PGRpdiBpZD0ibWVudSI+PGRpdiBjbGFzcz0ibWVudS1idXR0b24gc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9Im1lbnUtYnV0dG9uIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJtZW51LWJ1dHRvbiBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0ibWVudS1idXR0b24gc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9Im1lbnUtYnV0dG9uIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48ZGl2IGlkPSJzZWNvbmRhcnktaW5mbyIgY2xhc3M9InNrZWxldG9uLWxpZ2h0LWJvcmRlci1ib3R0b20iPjxkaXYgaWQ9InRvcC1yb3ciPjxkaXYgaWQ9InZpZGVvLW93bmVyIiBjbGFzcz0iZmxleC0xIj48ZGl2IGlkPSJjaGFubmVsLWljb24iIGNsYXNzPSJza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBpZD0idXBsb2FkLWluZm8iIGNsYXNzPSJmbGV4LTEiPjxkaXYgaWQ9Im93bmVyLW5hbWUiIGNsYXNzPSJ0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGlkPSJwdWJsaXNoZWQtZGF0ZSIgY2xhc3M9InRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgaWQ9InN1YnNjcmliZS1idXR0b24iIGNsYXNzPSJza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+PC9kaXY+PHNjcmlwdCBub25jZT0ib3U2cEJMV2ZNQ3dqdjRhWVF1TWdZUSI+aWYgKHdpbmRvdy55dGNzaSkge3dpbmRvdy55dGNzaS50aWNrKCdnY2MnLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9Im91NnBCTFdmTUN3anY0YVlRdU1nWVEiPnl0Y2ZnLnNldCh7IkNTSV9TRVJWSUNFX05BTUUiOiAneW91dHViZScsICJUSU1JTkdfSU5GTyI6IHt9fSk8L3NjcmlwdD48c2NyaXB0IG5vbmNlPSJvdTZwQkxXZk1Dd2p2NGFZUXVNZ1lRIj5pZiAod2luZG93Lnl0Y3NpKSB7d2luZG93Lnl0Y3NpLmluZm8oJ3N0JywgIDE0MS4wICwgJycpO308L3NjcmlwdD48L2JvZHk+PC9odG1sPg==\n    recorded_at: Thu, 08 Jun 2023 18:33:56 GMT\nrecorded_with: VCR 6.1.0\n"
  },
  {
    "path": "test/vcr_cassettes/youtube/channels.yml",
    "content": "---\nhttp_interactions:\n  - request:\n      method: get\n      uri: https://youtube.googleapis.com/youtube/v3/channels?forUsername=%22confreaks%22&key=REDACTED_YOUTUBE_API_KEY&part=snippet,contentDetails,statistics\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 200\n        message: OK\n      headers:\n        Content-Type:\n          - application/json; charset=UTF-8\n        Vary:\n          - Origin\n          - Referer\n          - X-Origin\n        Date:\n          - Thu, 08 Jun 2023 18:33:57 GMT\n        Server:\n          - scaffolding on HTTPServer2\n        Cache-Control:\n          - private\n        X-Xss-Protection:\n          - \"0\"\n        X-Frame-Options:\n          - SAMEORIGIN\n        X-Content-Type-Options:\n          - nosniff\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n        Transfer-Encoding:\n          - chunked\n      body:\n        encoding: ASCII-8BIT\n        string: |\n          {\n            \"kind\": \"youtube#channelListResponse\",\n            \"etag\": \"RuuXzTIr0OoDqI4S0RU6n4FqKEM\",\n            \"pageInfo\": {\n              \"totalResults\": 0,\n              \"resultsPerPage\": 5\n            }\n          }\n    recorded_at: Thu, 08 Jun 2023 18:33:57 GMT\n  - request:\n      method: get\n      uri: https://www.youtube.com/@confreaks\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 302\n        message: Found\n      headers:\n        Content-Type:\n          - application/binary\n        X-Content-Type-Options:\n          - nosniff\n        Cache-Control:\n          - no-cache, no-store, max-age=0, must-revalidate\n        Pragma:\n          - no-cache\n        Expires:\n          - Mon, 01 Jan 1990 00:00:00 GMT\n        Date:\n          - Thu, 08 Jun 2023 18:33:57 GMT\n        Location:\n          - https://consent.youtube.com/m?continue=https%3A%2F%2Fwww.youtube.com%2F%40confreaks%3Fcbrd%3D1&gl=FR&m=0&pc=yt&cm=2&hl=fr&src=1\n        Strict-Transport-Security:\n          - max-age=31536000\n        X-Frame-Options:\n          - SAMEORIGIN\n        Report-To:\n          - '{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}'\n        Origin-Trial:\n          - AvC9UlR6RDk2crliDsFl66RWLnTbHrDbp+DiY6AYz/PNQ4G4tdUTjrHYr2sghbkhGQAVxb7jaPTHpEVBz0uzQwkAAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTcxOTUzMjc5OSwiaXNTdWJkb21haW4iOnRydWV9\n        Permissions-Policy:\n          - ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*,\n            ch-ua-model=*, ch-ua-wow64=*, ch-ua-form-factor=*, ch-ua-platform=*, ch-ua-platform-version=*\n        Cross-Origin-Opener-Policy:\n          - same-origin-allow-popups; report-to=\"youtube_main\"\n        P3p:\n          - CP=\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl=fr\n            for more info.\"\n        Server:\n          - ESF\n        Content-Length:\n          - \"0\"\n        X-Xss-Protection:\n          - \"0\"\n        Set-Cookie:\n          - CONSENT=PENDING+708; expires=Sat, 07-Jun-2025 18:33:57 GMT; path=/; domain=.youtube.com;\n            Secure\n          - SOCS=CAAaBgiAtISkBg; Domain=.youtube.com; Expires=Sun, 07-Jul-2024 18:33:57\n            GMT; Path=/; Secure; SameSite=lax\n          - VISITOR_INFO1_LIVE=; Domain=.youtube.com; Expires=Fri, 11-Sep-2020 18:33:57\n            GMT; Path=/; Secure; HttpOnly; SameSite=none\n          - YSC=oBIS4L9qp_U; Domain=.youtube.com; Path=/; Secure; HttpOnly; SameSite=none\n          - __Secure-YEC=CgtFQzRpZ19QX1J0byiVvoikBg%3D%3D; Domain=.youtube.com; Expires=Sun,\n            07-Jul-2024 18:33:56 GMT; Path=/; Secure; HttpOnly; SameSite=lax\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      body:\n        encoding: UTF-8\n        string: \"\"\n    recorded_at: Thu, 08 Jun 2023 18:33:57 GMT\n  - request:\n      method: get\n      uri: https://consent.youtube.com/m?cm=2&continue=https://www.youtube.com/@confreaks?cbrd=1&gl=FR&hl=fr&m=0&pc=yt&src=1\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 303\n        message: See Other\n      headers:\n        Content-Type:\n          - application/binary\n        Cache-Control:\n          - no-cache, no-store, max-age=0, must-revalidate\n        Pragma:\n          - no-cache\n        Expires:\n          - Mon, 01 Jan 1990 00:00:00 GMT\n        Date:\n          - Thu, 08 Jun 2023 18:33:57 GMT\n        Location:\n          - https://www.youtube.com/@confreaks?cbrd=1&ucbcb=1\n        Server:\n          - ESF\n        Content-Length:\n          - \"0\"\n        X-Xss-Protection:\n          - \"0\"\n        X-Frame-Options:\n          - SAMEORIGIN\n        X-Content-Type-Options:\n          - nosniff\n        Set-Cookie:\n          - CONSENT=PENDING+787; expires=Sat, 07-Jun-2025 18:33:57 GMT; path=/; domain=.youtube.com;\n            Secure\n        P3p:\n          - CP=\"This is not a P3P policy! See g.co/p3phelp for more info.\"\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      body:\n        encoding: UTF-8\n        string: \"\"\n    recorded_at: Thu, 08 Jun 2023 18:33:57 GMT\n  - request:\n      method: get\n      uri: https://www.youtube.com/@confreaks?cbrd=1&ucbcb=1\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 200\n        message: OK\n      headers:\n        Content-Type:\n          - text/html; charset=utf-8\n        X-Content-Type-Options:\n          - nosniff\n        Cache-Control:\n          - no-cache, no-store, max-age=0, must-revalidate\n        Pragma:\n          - no-cache\n        Expires:\n          - Mon, 01 Jan 1990 00:00:00 GMT\n        Date:\n          - Thu, 08 Jun 2023 18:33:58 GMT\n        X-Frame-Options:\n          - SAMEORIGIN\n        Strict-Transport-Security:\n          - max-age=31536000\n        Report-To:\n          - '{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}'\n        Origin-Trial:\n          - AvC9UlR6RDk2crliDsFl66RWLnTbHrDbp+DiY6AYz/PNQ4G4tdUTjrHYr2sghbkhGQAVxb7jaPTHpEVBz0uzQwkAAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTcxOTUzMjc5OSwiaXNTdWJkb21haW4iOnRydWV9\n        Cross-Origin-Opener-Policy:\n          - same-origin-allow-popups; report-to=\"youtube_main\"\n        Permissions-Policy:\n          - ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*,\n            ch-ua-model=*, ch-ua-wow64=*, ch-ua-form-factor=*, ch-ua-platform=*, ch-ua-platform-version=*\n        P3p:\n          - CP=\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl=fr\n            for more info.\"\n        Server:\n          - ESF\n        X-Xss-Protection:\n          - \"0\"\n        Set-Cookie:\n          - CONSENT=PENDING+075; expires=Sat, 07-Jun-2025 18:33:57 GMT; path=/; domain=.youtube.com;\n            Secure\n          - VISITOR_INFO1_LIVE=; Domain=.youtube.com; Expires=Fri, 11-Sep-2020 18:33:58\n            GMT; Path=/; Secure; HttpOnly; SameSite=none\n          - YSC=AszNT4kFf2s; Domain=.youtube.com; Path=/; Secure; HttpOnly; SameSite=none\n          - __Secure-YEC=CgtsZW5SVk5lbkNWSSiWvoikBg%3D%3D; Domain=.youtube.com; Expires=Sun,\n            07-Jul-2024 18:33:57 GMT; Path=/; Secure; HttpOnly; SameSite=lax\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n        Transfer-Encoding:\n          - chunked\n      body:\n        encoding: ASCII-8BIT\n        string: !binary |-\n          PCFET0NUWVBFIGh0bWw+PGh0bWwgc3R5bGU9ImZvbnQtc2l6ZTogMTBweDtmb250LWZhbWlseTogUm9ib3RvLCBBcmlhbCwgc2Fucy1zZXJpZjsiIGxhbmc9ImZyLUZSIiBzeXN0ZW0taWNvbnMgdHlwb2dyYXBoeSB0eXBvZ3JhcGh5LXNwYWNpbmcgZGFya2VyLWRhcmstdGhlbWUgZGFya2VyLWRhcmstdGhlbWUtZGVwcmVjYXRlPjxoZWFkPjxtZXRhIGh0dHAtZXF1aXY9IlgtVUEtQ29tcGF0aWJsZSIgY29udGVudD0iSUU9ZWRnZSIvPjxtZXRhIGh0dHAtZXF1aXY9Im9yaWdpbi10cmlhbCIgY29udGVudD0iQXB2SzY3b2NpSGdyMmVnZDZjMlpqcmZQdVJzOEJIY3ZTZ2dvZ0lPUFFOSDdHSjNjVmx5SjFOT3EvQ09DZGowK3p4c2txSHQ5SGdMTEVUYzhxcUQrdndzQUFBQnRleUp2Y21sbmFXNGlPaUpvZEhSd2N6b3ZMM2x2ZFhSMVltVXVZMjl0T2pRME15SXNJbVpsWVhSMWNtVWlPaUpRY21sMllXTjVVMkZ1WkdKdmVFRmtjMEZRU1hNaUxDSmxlSEJwY25raU9qRTJPVFV4TmpjNU9Ua3NJbWx6VTNWaVpHOXRZV2x1SWpwMGNuVmxmUT09Ii8+PHNjcmlwdCBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+dmFyIHl0Y2ZnPXtkOmZ1bmN0aW9uKCl7cmV0dXJuIHdpbmRvdy55dCYmeXQuY29uZmlnX3x8eXRjZmcuZGF0YV98fCh5dGNmZy5kYXRhXz17fSl9LGdldDpmdW5jdGlvbihrLG8pe3JldHVybiBrIGluIHl0Y2ZnLmQoKT95dGNmZy5kKClba106b30sc2V0OmZ1bmN0aW9uKCl7dmFyIGE9YXJndW1lbnRzO2lmKGEubGVuZ3RoPjEpeXRjZmcuZCgpW2FbMF1dPWFbMV07ZWxzZXt2YXIgaztmb3IoayBpbiBhWzBdKXl0Y2ZnLmQoKVtrXT1hWzBdW2tdfX19Owp3aW5kb3cueXRjZmcuc2V0KCdFTUVSR0VOQ1lfQkFTRV9VUkwnLCAnXC9lcnJvcl8yMDQ/dFx4M2Rqc2Vycm9yXHgyNmxldmVsXHgzZEVSUk9SXHgyNmNsaWVudC5uYW1lXHgzZDFceDI2Y2xpZW50LnZlcnNpb25ceDNkMi4yMDIzMDYwNy4wNi4wMCcpOzwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPihmdW5jdGlvbigpe3dpbmRvdy55dGVycj13aW5kb3cueXRlcnJ8fHRydWU7d2luZG93LnVuaGFuZGxlZEVycm9yTWVzc2FnZXM9e307d2luZG93LnVuaGFuZGxlZEVycm9yQ291bnQ9MDsKd2luZG93Lm9uZXJyb3I9ZnVuY3Rpb24obXNnLHVybCxsaW5lLGNvbHVtbk51bWJlcixlcnJvcil7dmFyIGVycjtpZihlcnJvcillcnI9ZXJyb3I7ZWxzZXtlcnI9bmV3IEVycm9yO2Vyci5zdGFjaz0iIjtlcnIubWVzc2FnZT1tc2c7ZXJyLmZpbGVOYW1lPXVybDtlcnIubGluZU51bWJlcj1saW5lO2lmKCFpc05hTihjb2x1bW5OdW1iZXIpKWVyclsiY29sdW1uTnVtYmVyIl09Y29sdW1uTnVtYmVyfXZhciBtZXNzYWdlPVN0cmluZyhlcnIubWVzc2FnZSk7aWYoIWVyci5tZXNzYWdlfHxtZXNzYWdlIGluIHdpbmRvdy51bmhhbmRsZWRFcnJvck1lc3NhZ2VzfHx3aW5kb3cudW5oYW5kbGVkRXJyb3JDb3VudD49NSlyZXR1cm47d2luZG93LnVuaGFuZGxlZEVycm9yQ291bnQrPTE7d2luZG93LnVuaGFuZGxlZEVycm9yTWVzc2FnZXNbbWVzc2FnZV09dHJ1ZTt2YXIgaW1nPW5ldyBJbWFnZTt3aW5kb3cuZW1lcmdlbmN5VGltZW91dEltZz1pbWc7aW1nLm9ubG9hZD1pbWcub25lcnJvcj1mdW5jdGlvbigpe2RlbGV0ZSB3aW5kb3cuZW1lcmdlbmN5VGltZW91dEltZ307CnZhciBjb21iaW5lZExpbmVBbmRDb2x1bW49ZXJyLmxpbmVOdW1iZXI7aWYoIWlzTmFOKGVyclsiY29sdW1uTnVtYmVyIl0pKWNvbWJpbmVkTGluZUFuZENvbHVtbj1jb21iaW5lZExpbmVBbmRDb2x1bW4rKCI6IitlcnJbImNvbHVtbk51bWJlciJdKTt2YXIgc3RhY2s9ZXJyLnN0YWNrfHwiIjt2YXIgdmFsdWVzPXsibXNnIjptZXNzYWdlLCJ0eXBlIjplcnIubmFtZSwiY2xpZW50LnBhcmFtcyI6InVuaGFuZGxlZCB3aW5kb3cgZXJyb3IiLCJmaWxlIjplcnIuZmlsZU5hbWUsImxpbmUiOmNvbWJpbmVkTGluZUFuZENvbHVtbiwic3RhY2siOnN0YWNrLnN1YnN0cigwLDUwMCl9O3ZhciB0aGlyZFBhcnR5U2NyaXB0PSFlcnIuZmlsZU5hbWV8fGVyci5maWxlTmFtZT09PSI8YW5vbnltb3VzPiJ8fHN0YWNrLmluZGV4T2YoImV4dGVuc2lvbjovLyIpPj0wO3ZhciByZXBsYWNlZD1zdGFjay5yZXBsYWNlKC9odHRwczpcL1wvd3d3LnlvdXR1YmUuY29tXC8vZywiIik7aWYocmVwbGFjZWQubWF0Y2goL2h0dHBzPzpcL1wvW14vXStcLy8pKXRoaXJkUGFydHlTY3JpcHQ9CnRydWU7ZWxzZSBpZihzdGFjay5pbmRleE9mKCJ0cmFwUHJvcCIpPj0wJiZzdGFjay5pbmRleE9mKCJ0cmFwQ2hhaW4iKT49MCl0aGlyZFBhcnR5U2NyaXB0PXRydWU7ZWxzZSBpZihtZXNzYWdlLmluZGV4T2YoInJlZGVmaW5lIG5vbi1jb25maWd1cmFibGUiKT49MCl0aGlyZFBhcnR5U2NyaXB0PXRydWU7dmFyIGJhc2VVcmw9d2luZG93WyJ5dGNmZyJdLmdldCgiRU1FUkdFTkNZX0JBU0VfVVJMIiwiaHR0cHM6Ly93d3cueW91dHViZS5jb20vZXJyb3JfMjA0P3Q9anNlcnJvciZsZXZlbD1FUlJPUiIpO3ZhciB1bnN1cHBvcnRlZD1tZXNzYWdlLmluZGV4T2YoIndpbmRvdy5jdXN0b21FbGVtZW50cyBpcyB1bmRlZmluZWQiKT49MDtpZih0aGlyZFBhcnR5U2NyaXB0fHx1bnN1cHBvcnRlZCliYXNlVXJsPWJhc2VVcmwucmVwbGFjZSgibGV2ZWw9RVJST1IiLCJsZXZlbD1XQVJOSU5HIik7dmFyIHBhcnRzPVtiYXNlVXJsXTt2YXIga2V5O2ZvcihrZXkgaW4gdmFsdWVzKXt2YXIgdmFsdWU9CnZhbHVlc1trZXldO2lmKHZhbHVlKXBhcnRzLnB1c2goa2V5KyI9IitlbmNvZGVVUklDb21wb25lbnQodmFsdWUpKX1pbWcuc3JjPXBhcnRzLmpvaW4oIiYiKX07CihmdW5jdGlvbigpe2Z1bmN0aW9uIF9nZXRFeHRlbmRlZE5hdGl2ZVByb3RvdHlwZSh0YWcpe3ZhciBwPXRoaXMuX25hdGl2ZVByb3RvdHlwZXNbdGFnXTtpZighcCl7cD1PYmplY3QuY3JlYXRlKHRoaXMuZ2V0TmF0aXZlUHJvdG90eXBlKHRhZykpO3ZhciBwJD1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh3aW5kb3dbIlBvbHltZXIiXS5CYXNlKTt2YXIgaT0wO3ZhciBuPXZvaWQgMDtmb3IoO2k8cCQubGVuZ3RoJiYobj1wJFtpXSk7aSsrKWlmKCF3aW5kb3dbIlBvbHltZXIiXS5CYXNlRGVzY3JpcHRvcnNbbl0pdHJ5e3Bbbl09d2luZG93WyJQb2x5bWVyIl0uQmFzZVtuXX1jYXRjaChlKXt0aHJvdyBuZXcgRXJyb3IoIkVycm9yIHdoaWxlIGNvcHlpbmcgcHJvcGVydHk6ICIrbisiLiBUYWcgaXMgIit0YWcpO310cnl7T2JqZWN0LmRlZmluZVByb3BlcnRpZXMocCx3aW5kb3dbIlBvbHltZXIiXS5CYXNlRGVzY3JpcHRvcnMpfWNhdGNoKGUkMCl7dGhyb3cgbmV3IEVycm9yKCJQb2x5bWVyIGRlZmluZSBwcm9wZXJ0eSBmYWlsZWQgZm9yICIrCk9iamVjdC5rZXlzKHApKTt9dGhpcy5fbmF0aXZlUHJvdG90eXBlc1t0YWddPXB9cmV0dXJuIHB9ZnVuY3Rpb24gaGFuZGxlUG9seW1lckVycm9yKG1zZyl7d2luZG93Lm9uZXJyb3IobXNnLHdpbmRvdy5sb2NhdGlvbi5ocmVmLDAsMCxuZXcgRXJyb3IoQXJyYXkucHJvdG90eXBlLmpvaW4uY2FsbChhcmd1bWVudHMsIiwiKSkpfXZhciBvcmlnUG9seW1lcj13aW5kb3dbIlBvbHltZXIiXTt2YXIgbmV3UG9seW1lcj1mdW5jdGlvbihjb25maWcpe2lmKCFvcmlnUG9seW1lci5feXRJbnRlcmNlcHRlZCYmd2luZG93WyJQb2x5bWVyIl0uQmFzZSl7b3JpZ1BvbHltZXIuX3l0SW50ZXJjZXB0ZWQ9dHJ1ZTt3aW5kb3dbIlBvbHltZXIiXS5CYXNlLl9nZXRFeHRlbmRlZE5hdGl2ZVByb3RvdHlwZT1fZ2V0RXh0ZW5kZWROYXRpdmVQcm90b3R5cGU7d2luZG93WyJQb2x5bWVyIl0uQmFzZS5fZXJyb3I9aGFuZGxlUG9seW1lckVycm9yO3dpbmRvd1siUG9seW1lciJdLkJhc2UuX3dhcm49aGFuZGxlUG9seW1lckVycm9yfXJldHVybiBvcmlnUG9seW1lci5hcHBseSh0aGlzLAphcmd1bWVudHMpfTt2YXIgb3JpZ0Rlc2NyaXB0b3I9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih3aW5kb3csIlBvbHltZXIiKTtPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LCJQb2x5bWVyIix7c2V0OmZ1bmN0aW9uKHApe2lmKG9yaWdEZXNjcmlwdG9yJiZvcmlnRGVzY3JpcHRvci5zZXQmJm9yaWdEZXNjcmlwdG9yLmdldCl7b3JpZ0Rlc2NyaXB0b3Iuc2V0KHApO29yaWdQb2x5bWVyPW9yaWdEZXNjcmlwdG9yLmdldCgpfWVsc2Ugb3JpZ1BvbHltZXI9cDtpZih0eXBlb2Ygb3JpZ1BvbHltZXI9PT0iZnVuY3Rpb24iKU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3csIlBvbHltZXIiLHt2YWx1ZTpvcmlnUG9seW1lcixjb25maWd1cmFibGU6dHJ1ZSxlbnVtZXJhYmxlOnRydWUsd3JpdGFibGU6dHJ1ZX0pfSxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdHlwZW9mIG9yaWdQb2x5bWVyPT09ImZ1bmN0aW9uIj9uZXdQb2x5bWVyOm9yaWdQb2x5bWVyfSxjb25maWd1cmFibGU6dHJ1ZSwKZW51bWVyYWJsZTp0cnVlfSl9KSgpO30pLmNhbGwodGhpcyk7Cjwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPndpbmRvdy5Qb2x5bWVyPXdpbmRvdy5Qb2x5bWVyfHx7fTt3aW5kb3cuUG9seW1lci5sZWdhY3lPcHRpbWl6YXRpb25zPXRydWU7d2luZG93LlBvbHltZXIuc2V0UGFzc2l2ZVRvdWNoR2VzdHVyZXM9dHJ1ZTt3aW5kb3cuU2hhZHlET009e2ZvcmNlOnRydWUscHJlZmVyUGVyZm9ybWFuY2U6dHJ1ZSxub1BhdGNoOnRydWV9Owp3aW5kb3cucG9seW1lclNraXBMb2FkaW5nRm9udFJvYm90byA9IHRydWU7PC9zY3JpcHQ+PGxpbmsgcmVsPSJzaG9ydGN1dCBpY29uIiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9zL2Rlc2t0b3AvMzc0ZmFhZDUvaW1nL2Zhdmljb24uaWNvIiB0eXBlPSJpbWFnZS94LWljb24iPjxsaW5rIHJlbD0iaWNvbiIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2ltZy9mYXZpY29uXzMyeDMyLnBuZyIgc2l6ZXM9IjMyeDMyIj48bGluayByZWw9Imljb24iIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9pbWcvZmF2aWNvbl80OHg0OC5wbmciIHNpemVzPSI0OHg0OCI+PGxpbmsgcmVsPSJpY29uIiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9zL2Rlc2t0b3AvMzc0ZmFhZDUvaW1nL2Zhdmljb25fOTZ4OTYucG5nIiBzaXplcz0iOTZ4OTYiPjxsaW5rIHJlbD0iaWNvbiIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2ltZy9mYXZpY29uXzE0NHgxNDQucG5nIiBzaXplcz0iMTQ0eDE0NCI+PHNjcmlwdCBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+dmFyIHl0Y3NpPXtndDpmdW5jdGlvbihuKXtuPShufHwiIikrImRhdGFfIjtyZXR1cm4geXRjc2lbbl18fCh5dGNzaVtuXT17dGljazp7fSxpbmZvOnt9fSl9LG5vdzp3aW5kb3cucGVyZm9ybWFuY2UmJndpbmRvdy5wZXJmb3JtYW5jZS50aW1pbmcmJndpbmRvdy5wZXJmb3JtYW5jZS5ub3cmJndpbmRvdy5wZXJmb3JtYW5jZS50aW1pbmcubmF2aWdhdGlvblN0YXJ0P2Z1bmN0aW9uKCl7cmV0dXJuIHdpbmRvdy5wZXJmb3JtYW5jZS50aW1pbmcubmF2aWdhdGlvblN0YXJ0K3dpbmRvdy5wZXJmb3JtYW5jZS5ub3coKX06ZnVuY3Rpb24oKXtyZXR1cm4obmV3IERhdGUpLmdldFRpbWUoKX0sdGljazpmdW5jdGlvbihsLHQsbil7dmFyIHRpY2tzPXl0Y3NpLmd0KG4pLnRpY2s7dmFyIHY9dHx8eXRjc2kubm93KCk7aWYodGlja3NbbF0pe3RpY2tzWyJfIitsXT10aWNrc1siXyIrbF18fFt0aWNrc1tsXV07dGlja3NbIl8iK2xdLnB1c2godil9dGlja3NbbF09dn0saW5mbzpmdW5jdGlvbihrLAp2LG4pe3l0Y3NpLmd0KG4pLmluZm9ba109dn0sc2V0U3RhcnQ6ZnVuY3Rpb24odCxuKXt5dGNzaS50aWNrKCJfc3RhcnQiLHQsbil9fTsKKGZ1bmN0aW9uKHcsZCl7ZnVuY3Rpb24gaXNHZWNrbygpe2lmKCF3Lm5hdmlnYXRvcilyZXR1cm4gZmFsc2U7dHJ5e2lmKHcubmF2aWdhdG9yLnVzZXJBZ2VudERhdGEmJncubmF2aWdhdG9yLnVzZXJBZ2VudERhdGEuYnJhbmRzJiZ3Lm5hdmlnYXRvci51c2VyQWdlbnREYXRhLmJyYW5kcy5sZW5ndGgpe3ZhciBicmFuZHM9dy5uYXZpZ2F0b3IudXNlckFnZW50RGF0YS5icmFuZHM7dmFyIGk9MDtmb3IoO2k8YnJhbmRzLmxlbmd0aDtpKyspaWYoYnJhbmRzW2ldJiZicmFuZHNbaV0uYnJhbmQ9PT0iRmlyZWZveCIpcmV0dXJuIHRydWU7cmV0dXJuIGZhbHNlfX1jYXRjaChlKXtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhyb3cgZTt9KX1pZighdy5uYXZpZ2F0b3IudXNlckFnZW50KXJldHVybiBmYWxzZTt2YXIgdWE9dy5uYXZpZ2F0b3IudXNlckFnZW50O3JldHVybiB1YS5pbmRleE9mKCJHZWNrbyIpPjAmJnVhLnRvTG93ZXJDYXNlKCkuaW5kZXhPZigid2Via2l0Iik8MCYmdWEuaW5kZXhPZigiRWRnZSIpPAowJiZ1YS5pbmRleE9mKCJUcmlkZW50Iik8MCYmdWEuaW5kZXhPZigiTVNJRSIpPDB9eXRjc2kuc2V0U3RhcnQody5wZXJmb3JtYW5jZT93LnBlcmZvcm1hbmNlLnRpbWluZy5yZXNwb25zZVN0YXJ0Om51bGwpO3ZhciBpc1ByZXJlbmRlcj0oZC52aXNpYmlsaXR5U3RhdGV8fGQud2Via2l0VmlzaWJpbGl0eVN0YXRlKT09InByZXJlbmRlciI7dmFyIHZOYW1lPSFkLnZpc2liaWxpdHlTdGF0ZSYmZC53ZWJraXRWaXNpYmlsaXR5U3RhdGU/IndlYmtpdHZpc2liaWxpdHljaGFuZ2UiOiJ2aXNpYmlsaXR5Y2hhbmdlIjtpZihpc1ByZXJlbmRlcil7dmFyIHN0YXJ0VGljaz1mdW5jdGlvbigpe3l0Y3NpLnNldFN0YXJ0KCk7ZC5yZW1vdmVFdmVudExpc3RlbmVyKHZOYW1lLHN0YXJ0VGljayl9O2QuYWRkRXZlbnRMaXN0ZW5lcih2TmFtZSxzdGFydFRpY2ssZmFsc2UpfWlmKGQuYWRkRXZlbnRMaXN0ZW5lcilkLmFkZEV2ZW50TGlzdGVuZXIodk5hbWUsZnVuY3Rpb24oKXt5dGNzaS50aWNrKCJ2YyIpfSwKZmFsc2UpO2lmKGlzR2Vja28oKSl7dmFyIGlzSGlkZGVuPShkLnZpc2liaWxpdHlTdGF0ZXx8ZC53ZWJraXRWaXNpYmlsaXR5U3RhdGUpPT0iaGlkZGVuIjtpZihpc0hpZGRlbil5dGNzaS50aWNrKCJ2YyIpfXZhciBzbHQ9ZnVuY3Rpb24oZWwsdCl7c2V0VGltZW91dChmdW5jdGlvbigpe3ZhciBuPXl0Y3NpLm5vdygpO2VsLmxvYWRUaW1lPW47aWYoZWwuc2x0KWVsLnNsdCgpfSx0KX07dy5fX3l0UklMPWZ1bmN0aW9uKGVsKXtpZighZWwuZ2V0QXR0cmlidXRlKCJkYXRhLXRodW1iIikpaWYody5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24oKXtzbHQoZWwsMCl9KTtlbHNlIHNsdChlbCwxNil9fSkod2luZG93LGRvY3VtZW50KTsKPC9zY3JpcHQ+PHNjcmlwdCBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+KGZ1bmN0aW9uKCkge3ZhciBpbWcgPSBuZXcgSW1hZ2UoKS5zcmMgPSAiaHR0cHM6Ly9pLnl0aW1nLmNvbS9nZW5lcmF0ZV8yMDQiO30pKCk7PC9zY3JpcHQ+PHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9qc2Jpbi93ZWItYW5pbWF0aW9ucy1uZXh0LWxpdGUubWluLnZmbHNldC93ZWItYW5pbWF0aW9ucy1uZXh0LWxpdGUubWluLmpzIiBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+PC9zY3JpcHQ+PHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9qc2Jpbi93ZWJjb21wb25lbnRzLWFsbC1ub1BhdGNoLnZmbHNldC93ZWJjb21wb25lbnRzLWFsbC1ub1BhdGNoLmpzIiBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+PC9zY3JpcHQ+PHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9qc2Jpbi9mZXRjaC1wb2x5ZmlsbC52ZmxzZXQvZmV0Y2gtcG9seWZpbGwuanMiIG5vbmNlPSJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIj48L3NjcmlwdD48c2NyaXB0IHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL2ludGVyc2VjdGlvbi1vYnNlcnZlci5taW4udmZsc2V0L2ludGVyc2VjdGlvbi1vYnNlcnZlci5taW4uanMiIG5vbmNlPSJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIj48L3NjcmlwdD48c2NyaXB0IG5vbmNlPSJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIj5pZiAod2luZG93Lnl0Y3NpKSB7d2luZG93Lnl0Y3NpLnRpY2soJ2xwY3MnLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPihmdW5jdGlvbigpIHt3aW5kb3cueXRwbGF5ZXI9e307Cnl0Y2ZnLnNldCh7IkNMSUVOVF9DQU5BUllfU1RBVEUiOiJub25lIiwiREVWSUNFIjoiY2VuZ1x1MDAzZFVTRVJfREVGSU5FRFx1MDAyNmNwbGF0Zm9ybVx1MDAzZERFU0tUT1AiLCJESVNBQkxFX1lUX0lNR19ERUxBWV9MT0FESU5HIjpmYWxzZSwiRUxFTUVOVF9QT09MX0RFRkFVTFRfQ0FQIjo3NSwiRVZFTlRfSUQiOiJGUi1DWktUMlBJT2V2ZElQaU5DQm1BbyIsIkVYUEVSSU1FTlRfRkxBR1MiOnsiSDVfZW5hYmxlX2Z1bGxfcGFjZl9sb2dnaW5nIjp0cnVlLCJINV91c2VfYXN5bmNfbG9nZ2luZyI6dHJ1ZSwiYWN0aW9uX2NvbXBhbmlvbl9jZW50ZXJfYWxpZ25fZGVzY3JpcHRpb24iOnRydWUsImFsbG93X3NraXBfbmV0d29ya2xlc3MiOnRydWUsImF1dG9lc2NhcGVfdGVtcGRhdGFfdXJsIjp0cnVlLCJicm93c2VfbmV4dF9jb250aW51YXRpb25zX21pZ3JhdGlvbl9wbGF5bGlzdCI6dHJ1ZSwiYzNfd2F0Y2hfcGFnZV9jb21wb25lbnQiOnRydWUsImNhY2hlX3V0Y19vZmZzZXRfbWludXRlc19pbl9wcmVmX2Nvb2tpZSI6dHJ1ZSwiY2FuY2VsX3BlbmRpbmdfbmF2cyI6dHJ1ZSwiY2hlY2tfdXNlcl9sYWN0X2F0X3Byb21wdF9zaG93bl90aW1lX29uX3dlYiI6dHJ1ZSwiY2xlYXJfdXNlcl9wYXJ0aXRpb25lZF9scyI6dHJ1ZSwiY2xpZW50X3Jlc3BlY3RfYXV0b3BsYXlfc3dpdGNoX2J1dHRvbl9yZW5kZXJlciI6dHJ1ZSwiY29sZF9taXNzaW5nX2hpc3RvcnkiOnRydWUsImNvbXByZXNzX2dlbCI6dHJ1ZSwiY29uZmlnX2FnZV9yZXBvcnRfa2lsbHN3aXRjaCI6dHJ1ZSwiY3NpX29uX2dlbCI6dHJ1ZSwiZGVjb3JhdGVfYXV0b3BsYXlfcmVuZGVyZXIiOnRydWUsImRlZmVyX21lbnVzIjp0cnVlLCJkZWZlcl9vdmVybGF5cyI6dHJ1ZSwiZGVmZXJfcmVuZGVyaW5nX291dHNpZGVfdmlzaWJsZV9hcmVhIjp0cnVlLCJkZXByZWNhdGVfY3NpX2hhc19pbmZvIjp0cnVlLCJkZXByZWNhdGVfcGFpcl9zZXJ2bGV0X2VuYWJsZWQiOnRydWUsImRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfY2hpbGQiOnRydWUsImRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfcGFyZW50Ijp0cnVlLCJkZXNrdG9wX2FkZF90b19wbGF5bGlzdF9yZW5kZXJlcl9kaWFsb2dfcG9wdXAiOnRydWUsImRlc2t0b3BfYWRqdXN0X3RvdWNoX3RhcmdldCI6dHJ1ZSwiZGVza3RvcF9hbmltYXRlX21pbmlwbGF5ZXIiOnRydWUsImRlc2t0b3BfY2xpZW50X3JlbGVhc2UiOnRydWUsImRlc2t0b3BfZGVsYXlfcGxheWVyX3Jlc2l6aW5nIjp0cnVlLCJkZXNrdG9wX2VuYWJsZV9kbXBhbmVsX2NsaWNrX2RyYWdfc2Nyb2xsIjp0cnVlLCJkZXNrdG9wX2VuYWJsZV9kbXBhbmVsX3Njcm9sbCI6dHJ1ZSwiZGVza3RvcF9lbmFibGVfZG1wYW5lbF93aGVlbF9zY3JvbGwiOnRydWUsImRlc2t0b3BfaW1hZ2VfY3RhX25vX2JhY2tncm91bmQiOnRydWUsImRlc2t0b3Bfa2V5Ym9hcmRfY2FwdHVyZV9rZXlkb3duX2tpbGxzd2l0Y2giOnRydWUsImRlc2t0b3BfbG9nX2ltZ19jbGlja19sb2NhdGlvbiI6dHJ1ZSwiZGVza3RvcF9taXhfdXNlX3NhbXBsZWRfY29sb3JfZm9yX2JvdHRvbV9iYXIiOnRydWUsImRlc2t0b3BfbWl4X3VzZV9zYW1wbGVkX2NvbG9yX2Zvcl9ib3R0b21fYmFyX3NlYXJjaCI6dHJ1ZSwiZGVza3RvcF9taXhfdXNlX3NhbXBsZWRfY29sb3JfZm9yX2JvdHRvbV9iYXJfd2F0Y2hfbmV4dCI6dHJ1ZSwiZGVza3RvcF9ub3RpZmljYXRpb25faGlnaF9wcmlvcml0eV9pZ25vcmVfcHVzaCI6dHJ1ZSwiZGVza3RvcF9ub3RpZmljYXRpb25fc2V0X3RpdGxlX2JhciI6dHJ1ZSwiZGVza3RvcF9wZXJzaXN0ZW50X21lbnUiOnRydWUsImRlc2t0b3Bfc2VhcmNoX3Byb21pbmVudF90aHVtYnMiOnRydWUsImRlc2t0b3Bfc3BhcmtsZXNfbGlnaHRfY3RhX2J1dHRvbiI6dHJ1ZSwiZGVza3RvcF9zd2lwZWFibGVfZ3VpZGUiOnRydWUsImRlc2t0b3BfdGhlbWVhYmxlX3Z1bGNhbiI6dHJ1ZSwiZGVza3RvcF91c2VfbmV3X2hpc3RvcnlfbWFuYWdlciI6dHJ1ZSwiZGlzYWJsZV9jaGlsZF9ub2RlX2F1dG9fZm9ybWF0dGVkX3N0cmluZ3MiOnRydWUsImRpc2FibGVfZGVwZW5kZW5jeV9pbmplY3Rpb24iOnRydWUsImRpc2FibGVfZmVhdHVyZXNfZm9yX3N1cGV4Ijp0cnVlLCJkaXNhYmxlX2xlZ2FjeV9kZXNrdG9wX3JlbW90ZV9xdWV1ZSI6dHJ1ZSwiZGlzYWJsZV9wYWNmX2xvZ2dpbmdfZm9yX21lbW9yeV9saW1pdGVkX3R2Ijp0cnVlLCJkaXNhYmxlX3JpY2hfZ3JpZF9pbmxpbmVfcGxheWVyX3BvcF9vdXQiOnRydWUsImRpc2FibGVfc2ltcGxlX21peGVkX2RpcmVjdGlvbl9mb3JtYXR0ZWRfc3RyaW5ncyI6dHJ1ZSwiZGlzYWJsZV90aHVtYm5haWxfcHJlbG9hZGluZyI6dHJ1ZSwiZW1iZWRzX3dlYl9lbmFibGVfcmVwbGFjZV91bmxvYWRfd19wYWdlaGlkZSI6dHJ1ZSwiZW1iZWRzX3dlYl9ud2xfZGlzYWJsZV9ub2Nvb2tpZSI6dHJ1ZSwiZW5hYmxlX2FiX3JwX2ludCI6dHJ1ZSwiZW5hYmxlX2Jyb3dzZXJfY29va2llX3N0YXR1c19tb25pdG9yaW5nIjp0cnVlLCJlbmFibGVfYnV0dG9uX2JlaGF2aW9yX3JldXNlIjp0cnVlLCJlbmFibGVfY2FsbF90b19hY3Rpb25fY2xhcmlmaWNhdGlvbl9yZW5kZXJlcl9ib3R0b21fc2VjdGlvbl9jb25kaXRpb25zIjp0cnVlLCJlbmFibGVfY2hhbm5lbF9wYWdlX21vZGVybl9wcm9maWxlX3NlY3Rpb24iOnRydWUsImVuYWJsZV9jbGllbnRfc2xpX2xvZ2dpbmciOnRydWUsImVuYWJsZV9jbGllbnRfc3RyZWFtel93ZWIiOnRydWUsImVuYWJsZV9kZXNrdG9wX2Ftc3RlcmRhbV9pbmZvX3BhbmVscyI6dHJ1ZSwiZW5hYmxlX2Rpc21pc3NfbG9hZGluZ19tYW51YWxseSI6dHJ1ZSwiZW5hYmxlX2RtYV93ZWJfdG9hc3QiOnRydWUsImVuYWJsZV9kb2NrZWRfY2hhdF9tZXNzYWdlcyI6dHJ1ZSwiZW5hYmxlX2dlbF9sb2dfY29tbWFuZHMiOnRydWUsImVuYWJsZV9nZXRfYWNjb3VudF9zd2l0Y2hlcl9lbmRwb2ludF9vbl93ZWJmZSI6dHJ1ZSwiZW5hYmxlX2g1X2luc3RyZWFtX3dhdGNoX25leHRfcGFyYW1zX29hcmxpYiI6dHJ1ZSwiZW5hYmxlX2g1X3ZpZGVvX2Fkc19vYXJsaWIiOnRydWUsImVuYWJsZV9oYW5kbGVzX2FjY291bnRfbWVudV9zd2l0Y2hlciI6dHJ1ZSwiZW5hYmxlX2hhbmRsZXNfaW5fbWVudGlvbl9zdWdnZXN0X3Bvc3RzIjp0cnVlLCJlbmFibGVfaGxwX2NsaWVudF9pY29uX3BpY2siOnRydWUsImVuYWJsZV9pbWFnZV9wb2xsX3Bvc3RfY3JlYXRpb24iOnRydWUsImVuYWJsZV9pbmxpbmVfc2hvcnRzX29uX3duIjp0cnVlLCJlbmFibGVfbGVnYWxfZGlzY2xhaW1lcl91cGRhdGVzX2FmZmlsaWF0ZV9nYSI6dHJ1ZSwiZW5hYmxlX21hZGlzb25fc2VhcmNoX21pZ3JhdGlvbiI6dHJ1ZSwiZW5hYmxlX21hc3RoZWFkX3F1YXJ0aWxlX3BpbmdfZml4Ijp0cnVlLCJlbmFibGVfbWVtYmVyc2hpcHNfYW5kX3B1cmNoYXNlcyI6dHJ1ZSwiZW5hYmxlX21lbnRpb25zX2luX3JlcG9zdHMiOnRydWUsImVuYWJsZV9taWNyb2Zvcm1hdF9kYXRhIjp0cnVlLCJlbmFibGVfbWluaV9hcHBfY29udGFpbmVyIjp0cnVlLCJlbmFibGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzIjp0cnVlLCJlbmFibGVfbXVsdGlfaW1hZ2VfcG9zdF9jcmVhdGlvbiI6dHJ1ZSwiZW5hYmxlX25hbWVzX2hhbmRsZXNfYWNjb3VudF9zd2l0Y2hlciI6dHJ1ZSwiZW5hYmxlX29mZmVyX3N1cHByZXNzaW9uIjp0cnVlLCJlbmFibGVfb25feXRfY29tbWFuZF9leGVjdXRvcl9jb21tYW5kX3RvX25hdmlnYXRlIjp0cnVlLCJlbmFibGVfcGFjZl9zbG90X2FzZGVfcGxheWVyX2J5dGVfaDUiOnRydWUsImVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90diI6dHJ1ZSwiZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2X2Zvcl9wYWdlX3RvcF9mb3JtYXRzIjp0cnVlLCJlbmFibGVfcGFjZl90aHJvdWdoX3lzZmVfdHYiOnRydWUsImVuYWJsZV9wYXNzX3NkY19nZXRfYWNjb3VudHNfbGlzdCI6dHJ1ZSwiZW5hYmxlX3BsX3JfYyI6dHJ1ZSwiZW5hYmxlX3BvbGxfY2hvaWNlX2JvcmRlcl9vbl93ZWIiOnRydWUsImVuYWJsZV9wb2x5bWVyX3Jlc2luIjp0cnVlLCJlbmFibGVfcG9seW1lcl9yZXNpbl9taWdyYXRpb24iOnRydWUsImVuYWJsZV9wb3N0X2NjdF9saW5rcyI6dHJ1ZSwiZW5hYmxlX3Bvc3Rfc2NoZWR1bGluZyI6dHJ1ZSwiZW5hYmxlX3ByZW1pdW1fdm9sdW50YXJ5X3BhdXNlIjp0cnVlLCJlbmFibGVfcHJvZ3JhbW1lZF9wbGF5bGlzdF9jb2xvcl9zYW1wbGUiOnRydWUsImVuYWJsZV9wcm9ncmFtbWVkX3BsYXlsaXN0X3JlZGVzaWduIjp0cnVlLCJlbmFibGVfcHVyY2hhc2VfYWN0aXZpdHlfaW5fcGFpZF9tZW1iZXJzaGlwcyI6dHJ1ZSwiZW5hYmxlX3F1aXpfY3JlYXRpb24iOnRydWUsImVuYWJsZV9yZWVsX3dhdGNoX3NlcXVlbmNlIjp0cnVlLCJlbmFibGVfc2VlZGxlc3Nfc2hvcnRzX3VybCI6dHJ1ZSwiZW5hYmxlX3NlcnZlcl9zdGl0Y2hlZF9kYWkiOnRydWUsImVuYWJsZV9zZXJ2aWNlX2FqYXhfY3NuIjp0cnVlLCJlbmFibGVfc2VydmxldF9lcnJvcnNfc3RyZWFteiI6dHJ1ZSwiZW5hYmxlX3NlcnZsZXRfc3RyZWFteiI6dHJ1ZSwiZW5hYmxlX3Nmdl9hdWRpb19waXZvdF91cmwiOnRydWUsImVuYWJsZV9zaG9ydHNfc2luZ2xldG9uX2NoYW5uZWxfd2ViIjp0cnVlLCJlbmFibGVfc2lnbmFscyI6dHJ1ZSwiZW5hYmxlX3NraXBfYWRfZ3VpZGFuY2VfcHJvbXB0Ijp0cnVlLCJlbmFibGVfc2tpcHBhYmxlX2Fkc19mb3JfdW5wbHVnZ2VkX2FkX3BvZCI6dHJ1ZSwiZW5hYmxlX3NwYXJrbGVzX3dlYl9jbGlja2FibGVfZGVzY3JpcHRpb24iOnRydWUsImVuYWJsZV9zcXVpZmZsZV9naWZfaGFuZGxlc19sYW5kaW5nX3BhZ2UiOnRydWUsImVuYWJsZV9zdHJlYW1saW5lX3JlcG9zdF9mbG93Ijp0cnVlLCJlbmFibGVfc3RydWN0dXJlZF9kZXNjcmlwdGlvbl9zaG9ydHNfd2ViX213ZWIiOnRydWUsImVuYWJsZV90ZWN0b25pY19hZF91eF9mb3JfaGFsZnRpbWUiOnRydWUsImVuYWJsZV90aGlyZF9wYXJ0eV9pbmZvIjp0cnVlLCJlbmFibGVfdG9wc29pbF93dGFfZm9yX2hhbGZ0aW1lX2xpdmVfaW5mcmEiOnRydWUsImVuYWJsZV91bmF2YWlsYWJsZV92aWRlb3Nfd2F0Y2hfcGFnZSI6dHJ1ZSwiZW5hYmxlX3dhdGNoX25leHRfcGF1c2VfYXV0b3BsYXlfbGFjdCI6dHJ1ZSwiZW5hYmxlX3dlYl9rZXRjaHVwX2hlcm9fYW5pbWF0aW9uIjp0cnVlLCJlbmFibGVfd2ViX3Bvc3Rlcl9ob3Zlcl9hbmltYXRpb24iOnRydWUsImVuYWJsZV93ZWJfc2NoZWR1bGVyX3NpZ25hbHMiOnRydWUsImVuYWJsZV93ZWJfc2hvcnRzX2F1ZGlvX3Bpdm90Ijp0cnVlLCJlbmFibGVfd2luZG93X2NvbnN0cmFpbmVkX2J1eV9mbG93X2RpYWxvZyI6dHJ1ZSwiZW5hYmxlX3lvb2RsZSI6dHJ1ZSwiZW5hYmxlX3lwY19zcGlubmVycyI6dHJ1ZSwiZW5hYmxlX3l0X2F0YV9pZnJhbWVfYXV0aHVzZXIiOnRydWUsImVuYWJsZV95dGNfcmVmdW5kc19zdWJtaXRfZm9ybV9zaWduYWxfYWN0aW9uIjp0cnVlLCJlbmFibGVfeXRjX3NlbGZfc2VydmVfcmVmdW5kcyI6dHJ1ZSwiZW5kcG9pbnRfaGFuZGxlcl9sb2dnaW5nX2NsZWFudXBfa2lsbHN3aXRjaCI6dHJ1ZSwiZXhwb3J0X25ldHdvcmtsZXNzX29wdGlvbnMiOnRydWUsImV4dGVybmFsX2Z1bGxzY3JlZW4iOnRydWUsImV4dGVybmFsX2Z1bGxzY3JlZW5fd2l0aF9lZHUiOnRydWUsImZpbGxfc2luZ2xlX3ZpZGVvX3dpdGhfbm90aWZ5X3RvX2xhc3IiOnRydWUsImZpeF9zY3J1YmJlcl9vdmVybGF5X3RyYW5zaXRpb24iOnRydWUsImdjZl9jb25maWdfc3RvcmVfZW5hYmxlZCI6dHJ1ZSwiZ2RhX2VuYWJsZV9wbGF5bGlzdF9kb3dubG9hZCI6dHJ1ZSwiZ2xvYmFsX3NwYWNlYmFyX3BhdXNlIjp0cnVlLCJncGFfc3BhcmtsZXNfdGVuX3BlcmNlbnRfbGF5ZXIiOnRydWUsImg1X2NvbXBhbmlvbl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5ncyI6dHJ1ZSwiaDVfZW5hYmxlX2dlbmVyaWNfZXJyb3JfbG9nZ2luZ19ldmVudCI6dHJ1ZSwiaDVfaW5wbGF5ZXJfZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3MiOnRydWUsImg1X3Jlc2V0X2NhY2hlX2FuZF9maWx0ZXJfYmVmb3JlX3VwZGF0ZV9tYXN0aGVhZCI6dHJ1ZSwiaGFuZGxlc19pbl9tZW50aW9uX3N1Z2dlc3RfcG9zdHMiOnRydWUsImhpZGVfZW5kcG9pbnRfb3ZlcmZsb3dfb25feXRkX2Rpc3BsYXlfYWRfcmVuZGVyZXIiOnRydWUsImh0bWw1X2VuYWJsZV9hZHNfY2xpZW50X21vbml0b3JpbmdfbG9nX3R2Ijp0cnVlLCJodG1sNV9lbmFibGVfc2luZ2xlX3ZpZGVvX3ZvZF9pdmFyX29uX3BhY2YiOnRydWUsImh0bWw1X2xvZ190cmlnZ2VyX2V2ZW50c193aXRoX2RlYnVnX2RhdGEiOnRydWUsImh0bWw1X3JlY29nbml6ZV9wcmVkaWN0X3N0YXJ0X2N1ZV9wb2ludCI6dHJ1ZSwiaHRtbDVfc2VydmVyX3N0aXRjaGVkX2RhaV9ncm91cCI6dHJ1ZSwiaHRtbDVfd2ViX2VuYWJsZV9oYWxmdGltZV9wcmVyb2xsIjp0cnVlLCJpbF91c2Vfdmlld19tb2RlbF9sb2dnaW5nX2NvbnRleHQiOnRydWUsImluY2x1ZGVfYXV0b3BsYXlfY291bnRfaW5fcGxheWxpc3RzIjp0cnVlLCJpc19wYXJ0X29mX2FueV91c2VyX2VuZ2FnZW1lbnRfZXhwZXJpbWVudCI6dHJ1ZSwianNvbl9jb25kZW5zZWRfcmVzcG9uc2UiOnRydWUsImtldmxhcl9hcHBfc2hvcnRjdXRzIjp0cnVlLCJrZXZsYXJfYXBwYmVoYXZpb3JfYXR0YWNoX3N0YXJ0dXBfdGFza3MiOnRydWUsImtldmxhcl9hcHBlbmRfdG9nZ2xlZF9lbmdhZ2VtZW50X3BhbmVsc190b3AiOnRydWUsImtldmxhcl9hdXRvZm9jdXNfbWVudV9vbl9rZXlib2FyZF9uYXYiOnRydWUsImtldmxhcl9hdXRvbmF2X3BvcHVwX2ZpbHRlcmluZyI6dHJ1ZSwia2V2bGFyX2F2X2VsaW1pbmF0ZV9wb2xsaW5nIjp0cnVlLCJrZXZsYXJfYmFja2dyb3VuZF9jb2xvcl91cGRhdGUiOnRydWUsImtldmxhcl9jYWNoZV9jb2xkX2xvYWRfcmVzcG9uc2UiOnRydWUsImtldmxhcl9jYWNoZV9vbl90dGxfcGxheWVyIjp0cnVlLCJrZXZsYXJfY2FjaGVfb25fdHRsX3NlYXJjaCI6dHJ1ZSwia2V2bGFyX2NhbGN1bGF0ZV9ncmlkX2NvbGxhcHNpYmxlIjp0cnVlLCJrZXZsYXJfY2FuY2VsX3NjaGVkdWxlZF9jb21tZW50X2pvYnNfb25fbmF2aWdhdGUiOnRydWUsImtldmxhcl9jZW50ZXJfc2VhcmNoX3Jlc3VsdHMiOnRydWUsImtldmxhcl9jaGFubmVsX2NyZWF0aW9uX2Zvcm1fcmVzb2x2ZXIiOnRydWUsImtldmxhcl9jaGFubmVsX3RyYWlsZXJfbXVsdGlfYXR0YWNoIjp0cnVlLCJrZXZsYXJfY2hhcHRlcnNfbGlzdF92aWV3X3NlZWtfYnlfY2hhcHRlciI6dHJ1ZSwia2V2bGFyX2NsZWFyX2R1cGxpY2F0ZV9wcmVmX2Nvb2tpZSI6dHJ1ZSwia2V2bGFyX2NsZWFyX25vbl9kaXNwbGF5YWJsZV91cmxfcGFyYW1zIjp0cnVlLCJrZXZsYXJfY2xpZW50X3NpZGVfc2NyZWVucyI6dHJ1ZSwia2V2bGFyX2NvbW1hbmRfaGFuZGxlciI6dHJ1ZSwia2V2bGFyX2NvbW1hbmRfaGFuZGxlcl9jbGlja3MiOnRydWUsImtldmxhcl9jb21tYW5kX2hhbmRsZXJfZm9ybWF0dGVkX3N0cmluZyI6dHJ1ZSwia2V2bGFyX2NvbW1hbmRfdXJsIjp0cnVlLCJrZXZsYXJfY29udGludWVfcGxheWJhY2tfd2l0aG91dF9wbGF5ZXJfcmVzcG9uc2UiOnRydWUsImtldmxhcl9kZWNvcmF0ZV9lbmRwb2ludF93aXRoX29uZXNpZV9jb25maWciOnRydWUsImtldmxhcl9kZWxheV93YXRjaF9pbml0aWFsX2RhdGEiOnRydWUsImtldmxhcl9kaXNhYmxlX2JhY2tncm91bmRfcHJlZmV0Y2giOnRydWUsImtldmxhcl9kaXNhYmxlX3BlbmRpbmdfY29tbWFuZCI6dHJ1ZSwia2V2bGFyX2RyYWdkcm9wX2Zhc3Rfc2Nyb2xsIjp0cnVlLCJrZXZsYXJfZHJvcGRvd25fZml4Ijp0cnVlLCJrZXZsYXJfZHJvcHBhYmxlX3ByZWZldGNoYWJsZV9yZXF1ZXN0cyI6dHJ1ZSwia2V2bGFyX2Vhcmx5X3BvcHVwX2Nsb3NlIjp0cnVlLCJrZXZsYXJfZW5hYmxlX2VkaXRhYmxlX3BsYXlsaXN0cyI6dHJ1ZSwia2V2bGFyX2VuYWJsZV9yZW9yZGVyYWJsZV9wbGF5bGlzdHMiOnRydWUsImtldmxhcl9lbmFibGVfc2hvcnRzX3ByZWZldGNoX2luX3NlcXVlbmNlIjp0cnVlLCJrZXZsYXJfZW5hYmxlX3Nob3J0c19yZXNwb25zZV9jaHVua2luZyI6dHJ1ZSwia2V2bGFyX2VuYWJsZV91cF9hcnJvdyI6dHJ1ZSwia2V2bGFyX2VuYWJsZV91cHNlbGxfb25fdmlkZW9fbWVudSI6dHJ1ZSwia2V2bGFyX2VuYWJsZV95YnBfb3BfZm9yX3Nob3B0dWJlIjp0cnVlLCJrZXZsYXJfZXhpdF9mdWxsc2NyZWVuX2xlYXZpbmdfd2F0Y2giOnRydWUsImtldmxhcl9maXhfcGxheWxpc3RfY29udGludWF0aW9uIjp0cnVlLCJrZXZsYXJfZmxleGlibGVfbWVudSI6dHJ1ZSwia2V2bGFyX2ZsdWlkX3RvdWNoX3Njcm9sbCI6dHJ1ZSwia2V2bGFyX2Zyb250ZW5kX3F1ZXVlX3JlY292ZXIiOnRydWUsImtldmxhcl9nZWxfZXJyb3Jfcm91dGluZyI6dHJ1ZSwia2V2bGFyX2d1aWRlX3JlZnJlc2giOnRydWUsImtldmxhcl9oZWxwX3VzZV9sb2NhbGUiOnRydWUsImtldmxhcl9oaWRlX3BsYXlsaXN0X3BsYXliYWNrX3N0YXR1cyI6dHJ1ZSwia2V2bGFyX2hpZGVfcHBfdXJsX3BhcmFtIjp0cnVlLCJrZXZsYXJfaGlkZV90aW1lX2NvbnRpbnVlX3VybF9wYXJhbSI6dHJ1ZSwia2V2bGFyX2hvbWVfc2tlbGV0b24iOnRydWUsImtldmxhcl9ob21lX3NrZWxldG9uX2hpZGVfbGF0ZXIiOnRydWUsImtldmxhcl9qc19maXhlcyI6dHJ1ZSwia2V2bGFyX2tleWJvYXJkX2J1dHRvbl9mb2N1cyI6dHJ1ZSwia2V2bGFyX2xhcmdlcl90aHJlZV9kb3RfdGFwIjp0cnVlLCJrZXZsYXJfbGF6eV9saXN0X3Jlc3VtZV9mb3JfYXV0b2ZpbGwiOnRydWUsImtldmxhcl9sZWdhY3lfYnJvd3NlcnMiOnRydWUsImtldmxhcl9sb2NhbF9pbm5lcnR1YmVfcmVzcG9uc2UiOnRydWUsImtldmxhcl9tYWNyb19tYXJrZXJzX2tleWJvYXJkX3Nob3J0Y3V0Ijp0cnVlLCJrZXZsYXJfbWFzdGhlYWRfc3RvcmUiOnRydWUsImtldmxhcl9tZWFsYmFyX2Fib3ZlX3BsYXllciI6dHJ1ZSwia2V2bGFyX21pbmlwbGF5ZXIiOnRydWUsImtldmxhcl9taW5pcGxheWVyX2V4cGFuZF90b3AiOnRydWUsImtldmxhcl9taW5pcGxheWVyX3BsYXlfcGF1c2Vfb25fc2NyaW0iOnRydWUsImtldmxhcl9taW5pcGxheWVyX3F1ZXVlX3VzZXJfYWN0aXZhdGlvbiI6dHJ1ZSwia2V2bGFyX21peF9oYW5kbGVfZmlyc3RfZW5kcG9pbnRfZGlmZmVyZW50Ijp0cnVlLCJrZXZsYXJfbW9kZXJuX3NkIjp0cnVlLCJrZXZsYXJfbmV4dF9jb2xkX29uX2F1dGhfY2hhbmdlX2RldGVjdGVkIjp0cnVlLCJrZXZsYXJfbml0cmF0ZV9kcml2ZW5fdG9vbHRpcHMiOnRydWUsImtldmxhcl9ub19hdXRvc2Nyb2xsX29uX3BsYXlsaXN0X2hvdmVyIjp0cnVlLCJrZXZsYXJfb3BfaW5mcmEiOnRydWUsImtldmxhcl9vcF93YXJtX3BhZ2VzIjp0cnVlLCJrZXZsYXJfcGFuZG93bl9wb2x5ZmlsbCI6dHJ1ZSwia2V2bGFyX3Bhc3NpdmVfZXZlbnRfbGlzdGVuZXJzIjp0cnVlLCJrZXZsYXJfcGxheWJhY2tfYXNzb2NpYXRlZF9xdWV1ZSI6dHJ1ZSwia2V2bGFyX3BsYXllcl9jYWNoZWRfbG9hZF9jb25maWciOnRydWUsImtldmxhcl9wbGF5ZXJfY2hlY2tfYWRfc3RhdGVfb25fc3RvcCI6dHJ1ZSwia2V2bGFyX3BsYXllcl9sb2FkX3BsYXllcl9ub19vcCI6dHJ1ZSwia2V2bGFyX3BsYXllcl9uZXdfYm9vdHN0cmFwX2Fkb3B0aW9uIjp0cnVlLCJrZXZsYXJfcGxheWVyX3BsYXlsaXN0X3VzZV9sb2NhbF9pbmRleCI6dHJ1ZSwia2V2bGFyX3BsYXllcl93YXRjaF9lbmRwb2ludF9uYXZpZ2F0aW9uIjp0cnVlLCJrZXZsYXJfcGxheWxpc3RfZHJhZ19oYW5kbGVzIjp0cnVlLCJrZXZsYXJfcGxheWxpc3RfdXNlX3hfY2xvc2VfYnV0dG9uIjp0cnVlLCJrZXZsYXJfcHJlZmV0Y2giOnRydWUsImtldmxhcl9wcmV2ZW50X3BvbHltZXJfZHluYW1pY19mb250X2xvYWQiOnRydWUsImtldmxhcl9xdWV1ZV91c2VfdXBkYXRlX2FwaSI6dHJ1ZSwia2V2bGFyX3JlZnJlc2hfZ2VzdHVyZSI6dHJ1ZSwia2V2bGFyX3JlZnJlc2hfb25fdGhlbWVfY2hhbmdlIjp0cnVlLCJrZXZsYXJfcmVuZGVyZXJzdGFtcGVyX2V2ZW50X2xpc3RlbmVyIjp0cnVlLCJrZXZsYXJfcmVwbGFjZV9zaG9ydF90b19zaG9ydF9oaXN0b3J5X3N0YXRlIjp0cnVlLCJrZXZsYXJfcmVxdWVzdF9zZXF1ZW5jaW5nIjp0cnVlLCJrZXZsYXJfcmVzb2x2ZV9jb21tYW5kX2Zvcl9jb25maXJtX2RpYWxvZyI6dHJ1ZSwia2V2bGFyX3Jlc29sdmVfcGxheWxpc3RfZW5kcG9pbnRfYXNfd2F0Y2hfZW5kcG9pbnQiOnRydWUsImtldmxhcl9yZXNwb25zZV9jb21tYW5kX3Byb2Nlc3Nvcl9wYWdlIjp0cnVlLCJrZXZsYXJfc2Nyb2xsX2NoaXBzX29uX3RvdWNoIjp0cnVlLCJrZXZsYXJfc2Nyb2xsYmFyX3Jld29yayI6dHJ1ZSwia2V2bGFyX3NlcnZpY2VfY29tbWFuZF9jaGVjayI6dHJ1ZSwia2V2bGFyX3NldF9pbnRlcm5hbF9wbGF5ZXJfc2l6ZSI6dHJ1ZSwia2V2bGFyX3NoZWxsX2Zvcl9kb3dubG9hZHNfcGFnZSI6dHJ1ZSwia2V2bGFyX3Nob3VsZF9tYWludGFpbl9zdGFibGVfbGlzdCI6dHJ1ZSwia2V2bGFyX3Nob3dfcGxheWxpc3RfZGxfYnRuIjp0cnVlLCJrZXZsYXJfc2ltcF9zaG9ydHNfcmVzZXRfc2Nyb2xsIjp0cnVlLCJrZXZsYXJfc21hcnRfZG93bmxvYWRzIjp0cnVlLCJrZXZsYXJfc21hcnRfZG93bmxvYWRzX3NldHRpbmciOnRydWUsImtldmxhcl9zdGFydHVwX2xpZmVjeWNsZSI6dHJ1ZSwia2V2bGFyX3N0cnVjdHVyZWRfZGVzY3JpcHRpb25fY29udGVudF9pbmxpbmUiOnRydWUsImtldmxhcl9zeXN0ZW1faWNvbnMiOnRydWUsImtldmxhcl90YWJzX2dlc3R1cmUiOnRydWUsImtldmxhcl90ZXh0X2lubGluZV9leHBhbmRlcl9mb3JtYXR0ZWRfc25pcHBldCI6dHJ1ZSwia2V2bGFyX3RocmVlX2RvdF9pbmsiOnRydWUsImtldmxhcl90aHVtYm5haWxfZmx1aWQiOnRydWUsImtldmxhcl90b2FzdF9tYW5hZ2VyIjp0cnVlLCJrZXZsYXJfdG9wYmFyX2xvZ29fZmFsbGJhY2tfaG9tZSI6dHJ1ZSwia2V2bGFyX3RvdWNoX2ZlZWRiYWNrIjp0cnVlLCJrZXZsYXJfdG91Y2hfZmVlZGJhY2tfbG9ja3VwcyI6dHJ1ZSwia2V2bGFyX3RvdWNoX2dlc3R1cmVfdmVzIjp0cnVlLCJrZXZsYXJfdHJhbnNjcmlwdF9lbmdhZ2VtZW50X3BhbmVsIjp0cnVlLCJrZXZsYXJfdHVuZXJfcnVuX2RlZmF1bHRfY29tbWVudHNfZGVsYXkiOnRydWUsImtldmxhcl90dW5lcl9zaG91bGRfZGVmZXJfZGV0YWNoIjp0cnVlLCJrZXZsYXJfdHlwb2dyYXBoeV9zcGFjaW5nX3VwZGF0ZSI6dHJ1ZSwia2V2bGFyX3R5cG9ncmFwaHlfdXBkYXRlIjp0cnVlLCJrZXZsYXJfdW5hdmFpbGFibGVfdmlkZW9fZXJyb3JfdWlfY2xpZW50Ijp0cnVlLCJrZXZsYXJfdW5pZmllZF9lcnJvcnNfaW5pdCI6dHJ1ZSwia2V2bGFyX3VzZV9yZXNwb25zZV90dGxfdG9faW52YWxpZGF0ZV9jYWNoZSI6dHJ1ZSwia2V2bGFyX3VzZV92aW1pb19iZWhhdmlvciI6dHJ1ZSwia2V2bGFyX3VzZV93aWxfaWNvbnMiOnRydWUsImtldmxhcl91c2VfeXRkX3BsYXllciI6dHJ1ZSwia2V2bGFyX3ZhcmlhYmxlX3lvdXR1YmVfc2FucyI6dHJ1ZSwia2V2bGFyX3ZpbWlvX3VzZV9zaGFyZWRfbW9uaXRvciI6dHJ1ZSwia2V2bGFyX3ZvaWNlX2xvZ2dpbmdfZml4Ijp0cnVlLCJrZXZsYXJfdm9pY2Vfc2VhcmNoIjp0cnVlLCJrZXZsYXJfd2F0Y2hfY2luZW1hdGljcyI6dHJ1ZSwia2V2bGFyX3dhdGNoX2NvbG9yX3VwZGF0ZSI6dHJ1ZSwia2V2bGFyX3dhdGNoX2NvbW1lbnRzX2VwX2Rpc2FibGVfdGhlYXRlciI6dHJ1ZSwia2V2bGFyX3dhdGNoX2NvbnRlbnRzX2RhdGFfcHJvdmlkZXIiOnRydWUsImtldmxhcl93YXRjaF9jb250ZW50c19kYXRhX3Byb3ZpZGVyX3BlcnNpc3RlbnQiOnRydWUsImtldmxhcl93YXRjaF9kaXNhYmxlX2xlZ2FjeV9tZXRhZGF0YV91cGRhdGVzIjp0cnVlLCJrZXZsYXJfd2F0Y2hfZHJhZ19oYW5kbGVzIjp0cnVlLCJrZXZsYXJfd2F0Y2hfZmxleHlfZnVsbHNjcmVlbl9tYW5hZ2VyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfZmxleHlfbG9hZGluZ19zdGF0ZV9tYW5hZ2VyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfZmxleHlfbWluaXBsYXllcl9tYW5hZ2VyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfZmxleHlfbmF2aWdhdGlvbl9tYW5hZ2VyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfZmxleHlfcGxheWVyX2xvb3BfbWFuYWdlciI6dHJ1ZSwia2V2bGFyX3dhdGNoX2ZsZXh5X3Njcm9sbF9tYW5hZ2VyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfZmxleHlfdGl0bGVfbWFuYWdlciI6dHJ1ZSwia2V2bGFyX3dhdGNoX2ZsZXh5X3VzZV9jb250cm9sbGVyIjp0cnVlLCJrZXZsYXJfd2F0Y2hfZm9jdXNfb25fZW5nYWdlbWVudF9wYW5lbHMiOnRydWUsImtldmxhcl93YXRjaF9nZXN0dXJlX3BhbmRvd24iOnRydWUsImtldmxhcl93YXRjaF9oaWRlX2NvbW1lbnRzX3RlYXNlciI6dHJ1ZSwia2V2bGFyX3dhdGNoX2hpZGVfY29tbWVudHNfd2hpbGVfcGFuZWxfb3BlbiI6dHJ1ZSwia2V2bGFyX3dhdGNoX2pzX3BhbmVsX2hlaWdodCI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2giOnRydWUsImtldmxhcl93YXRjaF9tZXRhZGF0YV9yZWZyZXNoX2F0dGFjaGVkX3N1YnNjcmliZSI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2hfY2xpY2thYmxlX2Rlc2NyaXB0aW9uIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF9jb21wYWN0X3ZpZXdfY291bnQiOnRydWUsImtldmxhcl93YXRjaF9tZXRhZGF0YV9yZWZyZXNoX2Rlc2NyaXB0aW9uX2luZm9fZGVkaWNhdGVkX2xpbmUiOnRydWUsImtldmxhcl93YXRjaF9tZXRhZGF0YV9yZWZyZXNoX2Rlc2NyaXB0aW9uX2lubGluZV9leHBhbmRlciI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2hfZGVzY3JpcHRpb25fcHJpbWFyeV9jb2xvciI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2hfZm9yX2xpdmVfa2lsbHN3aXRjaCI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2hfZnVsbF93aWR0aF9kZXNjcmlwdGlvbiI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2hfbGVmdF9hbGlnbmVkX3ZpZGVvX2FjdGlvbnMiOnRydWUsImtldmxhcl93YXRjaF9tZXRhZGF0YV9yZWZyZXNoX2xvd2VyX2Nhc2VfdmlkZW9fYWN0aW9ucyI6dHJ1ZSwia2V2bGFyX3dhdGNoX21ldGFkYXRhX3JlZnJlc2hfbmFycm93ZXJfaXRlbV93cmFwIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF9yZWxhdGl2ZV9kYXRlIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF90b3BfYWxpZ25lZF9hY3Rpb25zIjp0cnVlLCJrZXZsYXJfd2F0Y2hfbW9kZXJuX21ldGFwYW5lbCI6dHJ1ZSwia2V2bGFyX3dhdGNoX21vZGVybl9wYW5lbHMiOnRydWUsImtldmxhcl93YXRjaF9wYW5lbF9oZWlnaHRfbWF0Y2hlc19wbGF5ZXIiOnRydWUsImtldmxhcl93b2ZmbGVfZmFsbGJhY2tfaW1hZ2UiOnRydWUsImtldmxhcl95dGJfbGl2ZV9iYWRnZXMiOnRydWUsImtpbGxzd2l0Y2hfdG9nZ2xlX2J1dHRvbl9iZWhhdmlvcl9yZXNvbHZlX2NvbW1hbmQiOnRydWUsImxpdmVfY2hhdF9iYW5uZXJfZXhwYW5zaW9uX2ZpeCI6dHJ1ZSwibGl2ZV9jaGF0X2VuYWJsZV9tb2RfdmlldyI6dHJ1ZSwibGl2ZV9jaGF0X2VuYWJsZV9xbmFfYmFubmVyX292ZXJmbG93X21lbnVfYWN0aW9ucyI6dHJ1ZSwibGl2ZV9jaGF0X2VuYWJsZV9xbmFfY2hhbm5lbCI6dHJ1ZSwibGl2ZV9jaGF0X2ZpbHRlcl9lbW9qaV9zdWdnZXN0aW9ucyI6dHJ1ZSwibGl2ZV9jaGF0X2luY3JlYXNlZF9taW5faGVpZ2h0Ijp0cnVlLCJsaXZlX2NoYXRfb3Zlcl9wbGF5bGlzdCI6dHJ1ZSwibGl2ZV9jaGF0X3dlYl9lbmFibGVfY29tbWFuZF9oYW5kbGVyIjp0cnVlLCJsaXZlX2NoYXRfd2ViX3VzZV9lbW9qaV9tYW5hZ2VyX3NpbmdsZXRvbiI6dHJ1ZSwibG9nX2Vycm9yc190aHJvdWdoX253bF9vbl9yZXRyeSI6dHJ1ZSwibG9nX2dlbF9jb21wcmVzc2lvbl9sYXRlbmN5Ijp0cnVlLCJsb2dfaGVhcnRiZWF0X3dpdGhfbGlmZWN5Y2xlcyI6dHJ1ZSwibG9nX3Zpc19vbl90YWJfY2hhbmdlIjp0cnVlLCJsb2dfd2ViX2VuZHBvaW50X3RvX2xheWVyIjp0cnVlLCJtZHhfZW5hYmxlX3ByaXZhY3lfZGlzY2xvc3VyZV91aSI6dHJ1ZSwibWR4X2xvYWRfY2FzdF9hcGlfYm9vdHN0cmFwX3NjcmlwdCI6dHJ1ZSwibWlncmF0ZV9ldmVudHNfdG9fdHMiOnRydWUsIm11c2ljX29uX21haW5faGFuZGxlX3BsYXlsaXN0X2VkaXRfdmlkZW9fYWRkZWRfcmVzdWx0X2RhdGEiOnRydWUsIm11c2ljX29uX21haW5fb3Blbl9wbGF5bGlzdF9yZWNvbW1lbmRlZF92aWRlb3NfaW5fbWluaXBsYXllciI6dHJ1ZSwibXdlYl9hY3Rpb25zX2NvbW1hbmRfaGFuZGxlciI6dHJ1ZSwibXdlYl9jb21tYW5kX2hhbmRsZXIiOnRydWUsIm13ZWJfZGlzYWJsZV9zZXRfYXV0b25hdl9zdGF0ZV9pbl9wbGF5ZXIiOnRydWUsIm13ZWJfZW5hYmxlX2NvbnNpc3RlbmN5X3NlcnZpY2UiOnRydWUsIm13ZWJfZW5hYmxlX2hscCI6dHJ1ZSwibXdlYl9sb2dvX3VzZV9ob21lX3BhZ2VfdmUiOnRydWUsIm13ZWJfcmVuZGVyX2NyYXdsZXJfZGVzY3JpcHRpb24iOnRydWUsIm13ZWJfc3RvcF90cnVuY2F0aW5nX21ldGFfdGFncyI6dHJ1ZSwibXdlYl91c2VfZGVza3RvcF9jYW5vbmljYWxfdXJsIjp0cnVlLCJtd2ViX3VzZV9lbmRwb2ludF9tZW51X2l0ZW0iOnRydWUsIm5ldHdvcmtsZXNzX2dlbCI6dHJ1ZSwibmV0d29ya2xlc3NfbG9nZ2luZyI6dHJ1ZSwibm9fc3ViX2NvdW50X29uX3N1Yl9idXR0b24iOnRydWUsIm53bF9zZW5kX2Zhc3Rfb25fdW5sb2FkIjp0cnVlLCJud2xfc2VuZF9mcm9tX21lbW9yeV93aGVuX29ubGluZSI6dHJ1ZSwib2ZmbGluZV9lcnJvcl9oYW5kbGluZyI6dHJ1ZSwicGFnZWlkX2FzX2hlYWRlcl93ZWIiOnRydWUsInBhdXNlX2FkX3ZpZGVvX29uX2Rlc2t0b3BfZW5nYWdlbWVudF9wYW5lbF9jbGljayI6dHJ1ZSwicGRnX2VuYWJsZV9mbG93X2xvZ2dpbmdfZm9yX3N1cGVyX2NoYXQiOnRydWUsInBkZ19lbmFibGVfZmxvd19sb2dnaW5nX2Zvcl9zdXBlcl9zdGlja2VycyI6dHJ1ZSwicGxheWVyX2FsbG93X2F1dG9uYXZfYWZ0ZXJfcGxheWxpc3QiOnRydWUsInBsYXllcl9ib290c3RyYXBfbWV0aG9kIjp0cnVlLCJwbGF5ZXJfZG91YmxldGFwX3RvX3NlZWsiOnRydWUsInBsYXllcl9lbmFibGVfcGxheWJhY2tfcGxheWxpc3RfY2hhbmdlIjp0cnVlLCJwbGF5ZXJfZW5kc2NyZWVuX2VsbGlwc2lzX2ZpeCI6dHJ1ZSwicG9seW1lcjJfbm90X3NoYWR5X2J1aWxkIjp0cnVlLCJwb2x5bWVyX2JhZF9idWlsZF9sYWJlbHMiOnRydWUsInBvbHltZXJfdGFza19tYW5hZ2VyX3Byb3hpZWRfcHJvbWlzZSI6dHJ1ZSwicG9seW1lcl92ZXJpZml5X2FwcF9zdGF0ZSI6dHJ1ZSwicG9seW1lcl92aWRlb19yZW5kZXJlcl9kZWZlcl9tZW51Ijp0cnVlLCJwb2x5bWVyX3l0ZGlfZW5hYmxlX2dsb2JhbF9pbmplY3RvciI6dHJ1ZSwicHJvYmxlbV93YWxrdGhyb3VnaF9zZCI6dHJ1ZSwicW9lX3NlbmRfYW5kX3dyaXRlIjp0cnVlLCJyZWNvcmRfYXBwX2NyYXNoZWRfd2ViIjp0cnVlLCJyZWxvYWRfd2l0aG91dF9wb2x5bWVyX2lubmVydHViZSI6dHJ1ZSwicmVtb3ZlX3dlYl9jb21tZW50X2lkX2NhY2hlIjp0cnVlLCJyZW1vdmVfeXRfc2ltcGxlX2VuZHBvaW50X2Zyb21fZGVza3RvcF9kaXNwbGF5X2FkX3RpdGxlIjp0cnVlLCJyaWNoX2dyaWRfcmVzaXplX29ic2VydmVyIjp0cnVlLCJyaWNoX2dyaWRfcmVzaXplX29ic2VydmVyX29ubHkiOnRydWUsInJpY2hfZ3JpZF93YXRjaF9kaXNhYmxlX21pbmlwbGF5ZXIiOnRydWUsInJpY2hfZ3JpZF93YXRjaF9oaWRlX3Jvd3NfYWJvdmUiOnRydWUsInJpY2hfZ3JpZF93YXRjaF9tZXRhX3NpZGUiOnRydWUsInNjaGVkdWxlcl91c2VfcmFmX2J5X2RlZmF1bHQiOnRydWUsInNlYXJjaF91aV9lbmFibGVfcHZlX2J1eV9idXR0b24iOnRydWUsInNlYXJjaF91aV9vZmZpY2lhbF9jYXJkc19lbmFibGVfcGFpZF92aXJ0dWFsX2V2ZW50X2J1eV9idXR0b24iOnRydWUsInNlYXJjaGJveF9yZXBvcnRpbmciOnRydWUsInNlcnZlX3BkcF9hdF9jYW5vbmljYWxfdXJsIjp0cnVlLCJzZXJ2aWNlX3dvcmtlcl9lbmFibGVkIjp0cnVlLCJzZXJ2aWNlX3dvcmtlcl9wdXNoX2VuYWJsZWQiOnRydWUsInNlcnZpY2Vfd29ya2VyX3B1c2hfaG9tZV9wYWdlX3Byb21wdCI6dHJ1ZSwic2VydmljZV93b3JrZXJfcHVzaF93YXRjaF9wYWdlX3Byb21wdCI6dHJ1ZSwic2VydmljZV93b3JrZXJfc3Vic2NyaWJlX3dpdGhfdmFwaWRfa2V5Ijp0cnVlLCJzaG9ydHNfZGVza3RvcF93YXRjaF93aGlsZV9wMiI6dHJ1ZSwic2hvcnRzX2VuYWJsZV9zbmFwX3N0b3AiOnRydWUsInNob3J0c19pbmxpbmVfcGxheWJhY2tfZGlzYWJsZV9wb3BvdXQiOnRydWUsInNob3J0c19wcm9maWxlX2hlYWRlcl9jM3BvIjp0cnVlLCJzaG91bGRfY2xlYXJfdmlkZW9fZGF0YV9vbl9wbGF5ZXJfY3VlZF91bnN0YXJ0ZWQiOnRydWUsInNob3dfY2l2X3JlbWluZGVyX29uX3dlYiI6dHJ1ZSwic2tpcF9pbnZhbGlkX3l0Y3NpX3RpY2tzIjp0cnVlLCJza2lwX2xzX2dlbF9yZXRyeSI6dHJ1ZSwic2tpcF9zZXR0aW5nX2luZm9faW5fY3NpX2RhdGFfb2JqZWN0Ijp0cnVlLCJzcG9uc29yc2hpcHNfZ2lmdGluZ19lbmFibGVfb3B0X2luIjp0cnVlLCJzdGFydF9jbGllbnRfZ2NmIjp0cnVlLCJzdGFydF9jbGllbnRfZ2NmX2Zvcl9wbGF5ZXIiOnRydWUsInN0YXJ0X3NlbmRpbmdfY29uZmlnX2hhc2giOnRydWUsInN1cGVyX3N0aWNrZXJfZW1vamlfcGlja2VyX2NhdGVnb3J5X2J1dHRvbl9pY29uX2ZpbGxlZCI6dHJ1ZSwic3VwcHJlc3NfZXJyb3JfMjA0X2xvZ2dpbmciOnRydWUsInRyYW5zcG9ydF91c2Vfc2NoZWR1bGVyIjp0cnVlLCJ1cGRhdGVfbG9nX2V2ZW50X2NvbmZpZyI6dHJ1ZSwidXNlX2Fkc19lbmdhZ2VtZW50X3BhbmVsX2Rlc2t0b3BfZm9vdGVyX2N0YSI6dHJ1ZSwidXNlX2JldHRlcl9wb3N0X2Rpc21pc3NhbHMiOnRydWUsInVzZV9ib3JkZXJfYW5kX2dyaWRfd3JhcHBpbmdfb25fZGVza3RvcF9wYW5lbF90aWxlcyI6dHJ1ZSwidXNlX2NvcmVfc20iOnRydWUsInVzZV9uZXdfY21sIjp0cnVlLCJ1c2VfbmV3X2luX21lbW9yeV9zdG9yYWdlIjp0cnVlLCJ1c2VfbmV3X253bF9pbml0aWFsaXphdGlvbiI6dHJ1ZSwidXNlX25ld19ud2xfc2F3Ijp0cnVlLCJ1c2VfbmV3X253bF9zdHciOnRydWUsInVzZV9uZXdfbndsX3d0cyI6dHJ1ZSwidXNlX3BsYXllcl9hYnVzZV9iZ19saWJyYXJ5Ijp0cnVlLCJ1c2VfcHJvZmlsZXBhZ2VfZXZlbnRfbGFiZWxfaW5fY2Fyb3VzZWxfcGxheWJhY2tzIjp0cnVlLCJ1c2VfcmVxdWVzdF90aW1lX21zX2hlYWRlciI6dHJ1ZSwidXNlX3Nlc3Npb25fYmFzZWRfc2FtcGxpbmciOnRydWUsInVzZV9zb3VyY2VfZWxlbWVudF9pZl9wcmVzZW50X2Zvcl9hY3Rpb25zIjp0cnVlLCJ1c2VfdHNfdmlzaWJpbGl0eWxvZ2dlciI6dHJ1ZSwidXNlX3dhdGNoX2ZyYWdtZW50czIiOnRydWUsInZlcmlmeV9hZHNfaXRhZ19lYXJseSI6dHJ1ZSwidnNzX2ZpbmFsX3Bpbmdfc2VuZF9hbmRfd3JpdGUiOnRydWUsInZzc19wbGF5YmFja191c2Vfc2VuZF9hbmRfd3JpdGUiOnRydWUsIndhcm1fbG9hZF9uYXZfc3RhcnRfd2ViIjp0cnVlLCJ3YXJtX29wX2Nzbl9jbGVhbnVwIjp0cnVlLCJ3ZWJfYWx3YXlzX2xvYWRfY2hhdF9zdXBwb3J0Ijp0cnVlLCJ3ZWJfYW1zdGVyZGFtX3BsYXlsaXN0cyI6dHJ1ZSwid2ViX2Ftc3RlcmRhbV9wb3N0X212cF9wbGF5bGlzdHMiOnRydWUsIndlYl9hbmltYXRlZF9saWtlIjp0cnVlLCJ3ZWJfYW5pbWF0ZWRfbGlrZV9sYXp5X2xvYWQiOnRydWUsIndlYl9hcGlfdXJsIjp0cnVlLCJ3ZWJfYXV0b25hdl9hbGxvd19vZmZfYnlfZGVmYXVsdCI6dHJ1ZSwid2ViX2J1dHRvbl9yZXdvcmsiOnRydWUsIndlYl9jaW5lbWF0aWNfbWFzdGhlYWQiOnRydWUsIndlYl9kYXJrZXJfZGFya190aGVtZSI6dHJ1ZSwid2ViX2Rhcmtlcl9kYXJrX3RoZW1lX2RlcHJlY2F0ZSI6dHJ1ZSwid2ViX2Rhcmtlcl9kYXJrX3RoZW1lX2xpdmVfY2hhdCI6dHJ1ZSwid2ViX2RlZHVwZV92ZV9ncmFmdGluZyI6dHJ1ZSwid2ViX2RlZmVyX3Nob3J0c191aSI6dHJ1ZSwid2ViX2RlZmVyX3Nob3J0c191aV9waGFzZTIiOnRydWUsIndlYl9kZXByZWNhdGVfc2VydmljZV9hamF4X21hcF9kZXBlbmRlbmN5Ijp0cnVlLCJ3ZWJfZW5hYmxlX2Vycm9yXzIwNCI6dHJ1ZSwid2ViX2VuYWJsZV9oaXN0b3J5X2NhY2hlX21hcCI6dHJ1ZSwid2ViX2VuYWJsZV9pbXBfYXVkaW9fY2MiOnRydWUsIndlYl9lbmFibGVfaW5zdHJlYW1fYWRzX2xpbmtfZGVmaW5pdGlvbl9hMTF5X2J1Z2ZpeCI6dHJ1ZSwid2ViX2VuYWJsZV9wZHBfbWluaV9wbGF5ZXIiOnRydWUsIndlYl9lbmFibGVfdmlkZW9fcHJldmlld19taWdyYXRpb24iOnRydWUsIndlYl9lbmFibGVfdm96X2F1ZGlvX2ZlZWRiYWNrIjp0cnVlLCJ3ZWJfZW5nYWdlbWVudF9wYW5lbF9zaG93X2Rlc2NyaXB0aW9uIjp0cnVlLCJ3ZWJfZmlsbGVkX3N1YnNjcmliZWRfYnV0dG9uIjp0cnVlLCJ3ZWJfZml4X2ZpbmVfc2NydWJiaW5nX2RyYWciOnRydWUsIndlYl9mb3J3YXJkX2NvbW1hbmRfb25fcGJqIjp0cnVlLCJ3ZWJfZ2VsX3RpbWVvdXRfY2FwIjp0cnVlLCJ3ZWJfZ3VpZGVfdWlfcmVmcmVzaCI6dHJ1ZSwid2ViX2hpZGVfYXV0b25hdl9oZWFkbGluZSI6dHJ1ZSwid2ViX2hpZGVfYXV0b25hdl9rZXlsaW5lIjp0cnVlLCJ3ZWJfaW1wX3RodW1ibmFpbF9jbGlja19maXhfZW5hYmxlZCI6dHJ1ZSwid2ViX2lubGluZV9wbGF5ZXJfZW5hYmxlZCI6dHJ1ZSwid2ViX2lubGluZV9wbGF5ZXJfbm9fcGxheWJhY2tfdWlfY2xpY2tfaGFuZGxlciI6dHJ1ZSwid2ViX2tldmxhcl9lbmFibGVfYWRhcHRpdmVfc2lnbmFscyI6dHJ1ZSwid2ViX2xvZ19tZW1vcnlfdG90YWxfa2J5dGVzIjp0cnVlLCJ3ZWJfbG9nX3BsYXllcl93YXRjaF9uZXh0X3RpY2tzIjp0cnVlLCJ3ZWJfbG9nX3JlZWxzX3RpY2tzIjp0cnVlLCJ3ZWJfbW9kZXJuX2FkcyI6dHJ1ZSwid2ViX21vZGVybl9idXR0b25zIjp0cnVlLCJ3ZWJfbW9kZXJuX2J1dHRvbnNfYmxfc3VydmV5Ijp0cnVlLCJ3ZWJfbW9kZXJuX2NoaXBzIjp0cnVlLCJ3ZWJfbW9kZXJuX2NvbGxlY3Rpb25zIjp0cnVlLCJ3ZWJfbW9kZXJuX2RpYWxvZ3MiOnRydWUsIndlYl9tb2Rlcm5fcGxheWxpc3RzIjp0cnVlLCJ3ZWJfbW9kZXJuX3NjcnViYmVyIjp0cnVlLCJ3ZWJfbW9kZXJuX3N1YnNjcmliZSI6dHJ1ZSwid2ViX21vdmVfYXV0b3BsYXlfdmlkZW9fdW5kZXJfY2hpcCI6dHJ1ZSwid2ViX21vdmVkX3N1cGVyX3RpdGxlX2xpbmsiOnRydWUsIndlYl9vbmVfcGxhdGZvcm1fZXJyb3JfaGFuZGxpbmciOnRydWUsIndlYl9wYXVzZWRfb25seV9taW5pcGxheWVyX3Nob3J0Y3V0X2V4cGFuZCI6dHJ1ZSwid2ViX3BsYXllcl9hZGRfdmVfY29udmVyc2lvbl9sb2dnaW5nX3RvX291dGJvdW5kX2xpbmtzIjp0cnVlLCJ3ZWJfcGxheWVyX2Fsd2F5c19lbmFibGVfYXV0b190cmFuc2xhdGlvbiI6dHJ1ZSwid2ViX3BsYXllcl9hdXRvbmF2X2VtcHR5X3N1Z2dlc3Rpb25zX2ZpeCI6dHJ1ZSwid2ViX3BsYXllcl9hdXRvbmF2X3RvZ2dsZV9hbHdheXNfbGlzdGVuIjp0cnVlLCJ3ZWJfcGxheWVyX2F1dG9uYXZfdXNlX3NlcnZlcl9wcm92aWRlZF9zdGF0ZSI6dHJ1ZSwid2ViX3BsYXllcl9kZWNvdXBsZV9hdXRvbmF2Ijp0cnVlLCJ3ZWJfcGxheWVyX2Rpc2FibGVfaW5saW5lX3NjcnViYmluZyI6dHJ1ZSwid2ViX3BsYXllcl9lbmFibGVfZWFybHlfd2FybmluZ19zbmFja2JhciI6dHJ1ZSwid2ViX3BsYXllcl9lbmFibGVfZmVhdHVyZWRfcHJvZHVjdF9iYW5uZXJfb25fZGVza3RvcCI6dHJ1ZSwid2ViX3BsYXllcl9lbmFibGVfcHJlbWl1bV9oYnJfaW5faDVfYXBpIjp0cnVlLCJ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9wbGF5YmFja19jYXAiOnRydWUsIndlYl9wbGF5ZXJfZW50aXRpZXNfbWlkZGxld2FyZSI6dHJ1ZSwid2ViX3BsYXllcl9sb2dfY2xpY2tfYmVmb3JlX2dlbmVyYXRpbmdfdmVfY29udmVyc2lvbl9wYXJhbXMiOnRydWUsIndlYl9wbGF5ZXJfbW92ZV9hdXRvbmF2X3RvZ2dsZSI6dHJ1ZSwid2ViX3BsYXllcl9tdXRhYmxlX2V2ZW50X2xhYmVsIjp0cnVlLCJ3ZWJfcGxheWVyX3Nob3VsZF9ob25vcl9pbmNsdWRlX2Fzcl9zZXR0aW5nIjp0cnVlLCJ3ZWJfcGxheWVyX3NtYWxsX2hicF9zZXR0aW5nc19tZW51Ijp0cnVlLCJ3ZWJfcGxheWVyX3RvcGlmeV9zdWJ0aXRsZXNfZm9yX3Nob3J0cyI6dHJ1ZSwid2ViX3BsYXllcl90b3VjaF9tb2RlX2ltcHJvdmVtZW50cyI6dHJ1ZSwid2ViX3BsYXllcl91c2VfbmV3X2FwaV9mb3JfcXVhbGl0eV9wdWxsYmFjayI6dHJ1ZSwid2ViX3BsYXllcl92ZV9jb252ZXJzaW9uX2ZpeGVzX2Zvcl9jaGFubmVsX2luZm8iOnRydWUsIndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZSI6dHJ1ZSwid2ViX3ByZWZldGNoX3ByZWxvYWRfdmlkZW8iOnRydWUsIndlYl9wcnNfdGVzdGluZ19tb2RlX2tpbGxzd2l0Y2giOnRydWUsIndlYl9yZXBsYWNlX3RodW1ibmFpbF93aXRoX2ltYWdlIjp0cnVlLCJ3ZWJfcm91bmRlZF90aHVtYm5haWxzIjp0cnVlLCJ3ZWJfc2VhcmNoX2lubGluZV9wbGF5YmFja19tb3VzZV9lbnRlciI6dHJ1ZSwid2ViX3NlZ21lbnRlZF9saWtlX2Rpc2xpa2VfYnV0dG9uIjp0cnVlLCJ3ZWJfc2V0X2lubGluZV9wcmV2aWV3X3NldHRpbmdfaW5faG9tZV9icm93c2VfcmVxdWVzdCI6dHJ1ZSwid2ViX3NoZWV0c191aV9yZWZyZXNoIjp0cnVlLCJ3ZWJfc2hvcnRzX2Vhcmx5X3BsYXllcl9sb2FkIjp0cnVlLCJ3ZWJfc2hvcnRzX252Y19kYXJrIjp0cnVlLCJ3ZWJfc2hvcnRzX3Byb2dyZXNzX2JhciI6dHJ1ZSwid2ViX3Nob3J0c19zaGVsZl9vbl9zZWFyY2giOnRydWUsIndlYl9zaG9ydHNfc2tpcF9sb2FkaW5nX3NhbWVfaW5kZXgiOnRydWUsIndlYl9zbWFydGltYXRpb25zX2tpbGxzd2l0Y2giOnRydWUsIndlYl9zbmFja2Jhcl91aV9yZWZyZXNoIjp0cnVlLCJ3ZWJfc3RydWN0dXJlZF9kZXNjcmlwdGlvbl9zaG93X21vcmUiOnRydWUsIndlYl90dXJuX29mZl9pbXBfb25fdGh1bWJuYWlsX21vdXNlZG93biI6dHJ1ZSwid2ViX3VzZV9jYWNoZV9mb3JfaW1hZ2VfZmFsbGJhY2siOnRydWUsIndlYl93YXRjaF9jaGlwc19tYXNrX2ZhZGUiOnRydWUsIndlYl93YXRjaF9jaW5lbWF0aWNzX3ByZWZlcnJlZF9yZWR1Y2VkX21vdGlvbl9kZWZhdWx0X2Rpc2FibGVkIjp0cnVlLCJ3ZWJfeXRfY29uZmlnX2NvbnRleHQiOnRydWUsIndpbF9pY29uX3JlbmRlcl93aGVuX2lkbGUiOnRydWUsIndvZmZsZV9jbGVhbl91cF9hZnRlcl9lbnRpdHlfbWlncmF0aW9uIjp0cnVlLCJ3b2ZmbGVfZW5hYmxlX2Rvd25sb2FkX3N0YXR1cyI6dHJ1ZSwid29mZmxlX3BsYXlsaXN0X29wdGltaXphdGlvbiI6dHJ1ZSwieW91cl9kYXRhX2VudHJ5cG9pbnQiOnRydWUsInl0X25ldHdvcmtfbWFuYWdlcl9jb21wb25lbnRfdG9fbGliX2tpbGxzd2l0Y2giOnRydWUsInl0aWRiX2NsZWFyX2VtYmVkZGVkX3BsYXllciI6dHJ1ZSwieXRpZGJfZmV0Y2hfZGF0YXN5bmNfaWRzX2Zvcl9kYXRhX2NsZWFudXAiOnRydWUsIkg1X2FzeW5jX2xvZ2dpbmdfZGVsYXlfbXMiOjMwMDAwLjAsImFkZHRvX2FqYXhfbG9nX3dhcm5pbmdfZnJhY3Rpb24iOjAuMSwiYXV0b3BsYXlfcGF1c2VfYnlfbGFjdF9zYW1wbGluZ19mcmFjdGlvbiI6MC4wLCJicm93c2VfYWpheF9sb2dfd2FybmluZ19mcmFjdGlvbiI6MS4wLCJjaW5lbWF0aWNfd2F0Y2hfZWZmZWN0X29wYWNpdHkiOjAuNCwiZm9ybWF0dGVkX2Rlc2NyaXB0aW9uX2xvZ193YXJuaW5nX2ZyYWN0aW9uIjowLjAxLCJrZXZsYXJfdHVuZXJfY2xhbXBfZGV2aWNlX3BpeGVsX3JhdGlvIjoyLjAsImtldmxhcl90dW5lcl90aHVtYm5haWxfZmFjdG9yIjoxLjAsImtldmxhcl91bmlmaWVkX3BsYXllcl9sb2dnaW5nX3RocmVzaG9sZCI6MS4wLCJsb2dfd2luZG93X29uZXJyb3JfZnJhY3Rpb24iOjAuMSwicG9seW1lcl9yZXBvcnRfY2xpZW50X3VybF9yZXF1ZXN0ZWRfcmF0ZSI6MC4wMDEsInBvbHltZXJfcmVwb3J0X21pc3Npbmdfd2ViX25hdmlnYXRpb25fZW5kcG9pbnRfcmF0ZSI6MC4wMDEsInByZWZldGNoX2Nvb3JkaW5hdG9yX2Vycm9yX2xvZ2dpbmdfc2FtcGxpbmdfcmF0ZSI6MS4wLCJ0dl9wYWNmX2xvZ2dpbmdfc2FtcGxlX3JhdGUiOjAuMDEsIndlYl9zaG9ydHNfZXJyb3JfbG9nZ2luZ190aHJlc2hvbGQiOjAuMDAxLCJ3ZWJfc2hvcnRzX2ludGVyc2VjdGlvbl9vYnNlcnZlcl90aHJlc2hvbGRfb3ZlcnJpZGUiOjAuMCwid2ViX3N5c3RlbV9oZWFsdGhfZnJhY3Rpb24iOjAuMDEsInl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXQiOjAuMDIsInl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfc2Vzc2lvbiI6MC4yLCJ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0X3RyYW5zYWN0aW9uIjowLjEsImF1dG9wbGF5X3BhdXNlX2J5X2xhY3Rfc2VjIjowLCJhdXRvcGxheV90aW1lIjo4MDAwLCJhdXRvcGxheV90aW1lX2Zvcl9mdWxsc2NyZWVuIjozMDAwLCJhdXRvcGxheV90aW1lX2Zvcl9tdXNpY19jb250ZW50IjozMDAwLCJib3RndWFyZF9hc3luY19zbmFwc2hvdF90aW1lb3V0X21zIjozMDAwLCJjaGVja19uYXZpZ2F0b3JfYWNjdXJhY3lfdGltZW91dF9tcyI6MCwiY2luZW1hdGljX3dhdGNoX2Nzc19maWx0ZXJfYmx1cl9zdHJlbmd0aCI6NDAsImNpbmVtYXRpY193YXRjaF9mYWRlX291dF9kdXJhdGlvbiI6NTAwLCJjbGllbnRfc3RyZWFtel93ZWJfZmx1c2hfY291bnQiOjEwMCwiY2xpZW50X3N0cmVhbXpfd2ViX2ZsdXNoX2ludGVydmFsX3NlY29uZHMiOjYwLCJjbG91ZF9zYXZlX2dhbWVfZGF0YV9yYXRlX2xpbWl0X21zIjozMDAwLCJjb21wcmVzc2lvbl9kaXNhYmxlX3BvaW50IjoxMCwiY29tcHJlc3Npb25fcGVyZm9ybWFuY2VfdGhyZXNob2xkIjoyNTAsImRlc2t0b3Bfc2VhcmNoX3N1Z2dlc3Rpb25fdGFwX3RhcmdldCI6MCwiZXh0ZXJuYWxfZnVsbHNjcmVlbl9idXR0b25fY2xpY2tfdGhyZXNob2xkIjoyLCJleHRlcm5hbF9mdWxsc2NyZWVuX2J1dHRvbl9zaG93bl90aHJlc2hvbGQiOjEwLCJnZWxfcXVldWVfdGltZW91dF9tYXhfbXMiOjMwMDAwMCwiZ2V0X2FzeW5jX3RpbWVvdXRfbXMiOjYwMDAwLCJoaWdoX3ByaW9yaXR5X2ZseW91dF9mcmVxdWVuY3kiOjMsImluaXRpYWxfZ2VsX2JhdGNoX3RpbWVvdXQiOjIwMDAsImtldmxhcl9taW5pX2d1aWRlX3dpZHRoX3RocmVzaG9sZCI6NzkxLCJrZXZsYXJfcGVyc2lzdGVudF9ndWlkZV93aWR0aF90aHJlc2hvbGQiOjEzMTIsImtldmxhcl90aW1lX2NhY2hpbmdfZW5kX3RocmVzaG9sZCI6MTUsImtldmxhcl90aW1lX2NhY2hpbmdfc3RhcnRfdGhyZXNob2xkIjoxNSwia2V2bGFyX3Rvb2x0aXBfaW1wcmVzc2lvbl9jYXAiOjIsImtldmxhcl90dW5lcl9kZWZhdWx0X2NvbW1lbnRzX2RlbGF5IjoxMDAwLCJrZXZsYXJfdHVuZXJfc2NoZWR1bGVyX3NvZnRfc3RhdGVfdGltZXJfbXMiOjgwMCwia2V2bGFyX3R1bmVyX3Zpc2liaWxpdHlfdGltZV9iZXR3ZWVuX2pvYnNfbXMiOjEwMCwia2V2bGFyX3dhdGNoX2ZsZXh5X21ldGFkYXRhX2hlaWdodCI6MTM2LCJrZXZsYXJfd2F0Y2hfbWV0YWRhdGFfcmVmcmVzaF9kZXNjcmlwdGlvbl9saW5lcyI6MywibGl2ZV9jaGF0X2NodW5rX3JlbmRlcmluZyI6MCwibGl2ZV9jaGF0X2Vtb2ppX3BpY2tlcl9yZXN0eWxlX2JvdHRvbV9weCI6MCwibGl2ZV9jaGF0X2Vtb2ppX3BpY2tlcl9yZXN0eWxlX2hlaWdodF9wZXJjZW50IjowLCJsaXZlX2NoYXRfZW1vamlfcGlja2VyX3Jlc3R5bGVfaGVpZ2h0X3B4IjowLCJsaXZlX2NoYXRfZW1vamlfcGlja2VyX3Jlc3R5bGVfd2lkdGhfcHgiOjAsImxpdmVfY2hhdF9tYXhfY2h1bmtfc2l6ZSI6NSwibGl2ZV9jaGF0X21pbl9jaHVua19pbnRlcnZhbF9tcyI6MzAwLCJsb2dfd2ViX21ldGFfaW50ZXJ2YWxfbXMiOjAsIm1heF9ib2R5X3NpemVfdG9fY29tcHJlc3MiOjUwMDAwMCwibWF4X2R1cmF0aW9uX3RvX2NvbnNpZGVyX21vdXNlb3Zlcl9hc19ob3ZlciI6NjAwMDAwLCJtYXhfcHJlZmV0Y2hfd2luZG93X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb24iOjAsIm1pbl9tb3VzZV9zdGlsbF9kdXJhdGlvbiI6MTAwLCJtaW5fcHJlZmV0Y2hfb2Zmc2V0X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb24iOjEwLCJtaW5pbXVtX2R1cmF0aW9uX3RvX2NvbnNpZGVyX21vdXNlb3Zlcl9hc19ob3ZlciI6NTAwLCJtd2ViX2hpc3RvcnlfbWFuYWdlcl9jYWNoZV9zaXplIjoxMDAsIm5ldHdvcmtfcG9sbGluZ19pbnRlcnZhbCI6MzAwMDAsInBhY2ZfbG9nZ2luZ19kZWxheV9taWxsaXNlY29uZHNfdGhyb3VnaF95YmZlX3R2IjozMDAwMCwicGJqX25hdmlnYXRlX2xpbWl0IjotMSwicGxheV9waW5nX2ludGVydmFsX21zIjozMDAwMCwicG9seW1lcl9sb2dfcHJvcF9jaGFuZ2Vfb2JzZXJ2ZXJfcGVyY2VudCI6MCwicG9zdF90eXBlX2ljb25zX3JlYXJyYW5nZSI6MSwicHJlZmV0Y2hfY29tbWVudHNfbXNfYWZ0ZXJfdmlkZW8iOjAsInByZWZldGNoX2Nvb3JkaW5hdG9yX2NvbW1hbmRfdGltZW91dF9tcyI6NjAwMDAsInByZWZldGNoX2Nvb3JkaW5hdG9yX21heF9pbmZsaWdodF9yZXF1ZXN0cyI6MSwicmljaF9ncmlkX21heF9pdGVtX3dpZHRoIjozNjAsInJpY2hfZ3JpZF9taW5faXRlbV93aWR0aCI6MzIwLCJyaWNoX2dyaWRfdHJ1ZV9pbmxpbmVfcGxheWJhY2tfdHJpZ2dlcl9kZWxheSI6MCwic2VuZF9jb25maWdfaGFzaF90aW1lciI6MCwic2VydmljZV93b3JrZXJfcHVzaF9sb2dnZWRfb3V0X3Byb21wdF93YXRjaGVzIjotMSwic2VydmljZV93b3JrZXJfcHVzaF9wcm9tcHRfY2FwIjotMSwic2VydmljZV93b3JrZXJfcHVzaF9wcm9tcHRfZGVsYXlfbWljcm9zZWNvbmRzIjozODg4MDAwMDAwMDAwLCJzaG9ydHNfaW5saW5lX3BsYXllcl90cmlnZ2VyaW5nX2RlbGF5Ijo1MDAsInNsb3dfY29tcHJlc3Npb25zX2JlZm9yZV9hYmFuZG9uX2NvdW50Ijo0LCJ1c2VyX2VuZ2FnZW1lbnRfZXhwZXJpbWVudHNfcmF0ZV9saW1pdF9tcyI6ODY0MDAwMDAsInVzZXJfbWVudGlvbl9zdWdnZXN0aW9uc19lZHVfaW1wcmVzc2lvbl9jYXAiOjEwLCJ2aXNpYmlsaXR5X3RpbWVfYmV0d2Vlbl9qb2JzX21zIjoxMDAsIndhdGNoX25leHRfcGF1c2VfYXV0b3BsYXlfbGFjdF9zZWMiOjQ1MDAsIndlYl9lbXVsYXRlZF9pZGxlX2NhbGxiYWNrX2RlbGF5IjowLCJ3ZWJfZm9yZWdyb3VuZF9oZWFydGJlYXRfaW50ZXJ2YWxfbXMiOjI4MDAwLCJ3ZWJfZ2VsX2RlYm91bmNlX21zIjo2MDAwMCwid2ViX2hvbWVfZmVlZF9yZWxvYWRfZGVsYXkiOjE0NDAsIndlYl9pbmxpbmVfcGxheWVyX3RyaWdnZXJpbmdfZGVsYXkiOjEwMDAsIndlYl9sb2dnaW5nX21heF9iYXRjaCI6MTUwLCJ3ZWJfcGxheWVyX2NhcHRpb25fbGFuZ3VhZ2VfcHJlZmVyZW5jZV9zdGlja2luZXNzX2R1cmF0aW9uIjozMCwid2ViX3NlYXJjaF9pbmxpbmVfcGxheWVyX3RyaWdnZXJpbmdfZGVsYXkiOjUwMCwid2ViX3NlYXJjaF9zaG9ydHNfaW5saW5lX3BsYXliYWNrX2R1cmF0aW9uX21zIjowLCJ3ZWJfc2hvcnRzX2lubGluZV9wbGF5YmFja19wcmV2aWV3X21zIjowLCJ3ZWJfc2hvcnRzX3NjcnViYmVyX3RocmVzaG9sZF9zZWMiOjAsIndlYl9zaG9ydHNfc2hlbGZfZml4ZWRfcG9zaXRpb24iOjksIndlYl9zaG9ydHNfc3Rvcnlib2FyZF90aHJlc2hvbGRfc2Vjb25kcyI6MCwid2ViX3Ntb290aG5lc3NfdGVzdF9kdXJhdGlvbl9tcyI6MCwid2ViX3Ntb290aG5lc3NfdGVzdF9tZXRob2QiOjAsInlvb2RsZV9lbmRfdGltZV91dGMiOjAsInlvb2RsZV9zdGFydF90aW1lX3V0YyI6MCwieXRpZGJfcmVtYWtlX2RiX3JldHJpZXMiOjEsInl0aWRiX3Jlb3Blbl9kYl9yZXRyaWVzIjowLCJXZWJDbGllbnRSZWxlYXNlUHJvY2Vzc0NyaXRpY2FsX195b3V0dWJlX3dlYl9jbGllbnRfdmVyc2lvbl9vdmVycmlkZSI6IiIsImRlYnVnX2ZvcmNlZF9pbnRlcm5hbGNvdW50cnljb2RlIjoiIiwiZGVza3RvcF9zZWFyY2hfYmlnZ2VyX3RodW1ic19zdHlsZSI6IkRFRkFVTFQiLCJkZXNrdG9wX3NlYXJjaGJhcl9zdHlsZSI6ImRlZmF1bHQiLCJlbWJlZHNfd2ViX3N5bnRoX2NoX2hlYWRlcnNfYmFubmVkX3VybHNfcmVnZXgiOiIiLCJrZXZsYXJfZHVwbGljYXRlX3ByZWZfY29va2llX2RvbWFpbl9vdmVycmlkZSI6IiIsImtldmxhcl9saW5rX2NhcHR1cmluZ19tb2RlIjoiIiwibGl2ZV9jaGF0X2Vtb2ppX3BpY2tlcl9yZXN0eWxlX2hlaWdodCI6IiIsImxpdmVfY2hhdF9lbW9qaV9waWNrZXJfcmVzdHlsZV93aWR0aCI6IiIsImxpdmVfY2hhdF91bmljb2RlX2Vtb2ppX2pzb25fdXJsIjoiaHR0cHM6Ly93d3cuZ3N0YXRpYy5jb20veW91dHViZS9pbWcvZW1vamlzL2Vtb2ppcy1zdmctOS5qc29uIiwicG9seW1lcl90YXNrX21hbmFnZXJfc3RhdHVzIjoicHJvZHVjdGlvbiIsInNlcnZpY2Vfd29ya2VyX3B1c2hfZm9yY2Vfbm90aWZpY2F0aW9uX3Byb21wdF90YWciOiIxIiwic2VydmljZV93b3JrZXJfc2NvcGUiOiIvIiwid2ViX2FzeW5jX2NvbnRleHRfcHJvY2Vzc29yX2ltcGwiOiJzdGFuZGFsb25lIiwid2ViX2NsaWVudF92ZXJzaW9uX292ZXJyaWRlIjoiIiwid2ViX2hvbWVfZmVlZF9yZWxvYWRfZXhwZXJpZW5jZSI6Im5vbmUiLCJ3ZWJfbW9kZXJuX3N1YnNjcmliZV9zdHlsZSI6ImZpbGxlZCIsIndlYl9zaG9ydHNfZXhwYW5kZWRfb3ZlcmxheV90eXBlIjoiREVGQVVMVCIsIndlYl9zaG9ydHNfb3ZlcmxheV92ZXJ0aWNhbF9vcmllbnRhdGlvbiI6ImJvdHRvbSIsInlvb2RsZV9iYXNlX3VybCI6IiIsInlvb2RsZV93ZWJwX2Jhc2VfdXJsIjoiIiwiY29uZGl0aW9uYWxfbGFiX2lkcyI6W10sImd1aWRlX2J1c2luZXNzX2luZm9fY291bnRyaWVzIjpbIktSIl0sImd1aWRlX2xlZ2FsX2Zvb3Rlcl9lbmFibGVkX2NvdW50cmllcyI6WyJOTCIsIkVTIl0sImtldmxhcl9jb21tYW5kX2hhbmRsZXJfY29tbWFuZF9iYW5saXN0IjpbXSwia2V2bGFyX3BhZ2Vfc2VydmljZV91cmxfcHJlZml4X2NhcnZlb3V0cyI6W10sIndlYl9vcF9zaWduYWxfdHlwZV9iYW5saXN0IjpbXX0sIkdBUElfSElOVF9QQVJBTVMiOiJtOy9fL3Njcy9hYmMtc3RhdGljL18vanMva1x1MDAzZGdhcGkuZ2FwaS5lbi5LMUxXdGhBemViNC5PL2RcdTAwM2QxL3JzXHUwMDNkQUhwT29vLVRRVHFudjdod2lqcnNlUDRKS0oxWFk4M0VoZy9tXHUwMDNkX19mZWF0dXJlc19fIiwiR0FQSV9IT1NUIjoiaHR0cHM6Ly9hcGlzLmdvb2dsZS5jb20iLCJHQVBJX0xPQ0FMRSI6ImZyX0ZSIiwiR0wiOiJGUiIsIkdPT0dMRV9GRUVEQkFDS19QUk9EVUNUX0lEIjoiNTkiLCJHT09HTEVfRkVFREJBQ0tfUFJPRFVDVF9EQVRBIjp7InBvbHltZXIiOiJhY3RpdmUiLCJwb2x5bWVyMiI6ImFjdGl2ZSIsImFjY2VwdF9sYW5ndWFnZSI6IiJ9LCJITCI6ImZyIiwiSFRNTF9ESVIiOiJsdHIiLCJIVE1MX0xBTkciOiJmci1GUiIsIklOTkVSVFVCRV9BUElfS0VZIjoiQUl6YVN5QU9fRkoyU2xxVThRNFNURUhMR0NpbHdfWTlfMTFxY1c4IiwiSU5ORVJUVUJFX0FQSV9WRVJTSU9OIjoidjEiLCJJTk5FUlRVQkVfQ0xJRU5UX05BTUUiOiJXRUIiLCJJTk5FUlRVQkVfQ0xJRU5UX1ZFUlNJT04iOiIyLjIwMjMwNjA3LjA2LjAwIiwiSU5ORVJUVUJFX0NPTlRFWFQiOnsiY2xpZW50Ijp7ImhsIjoiZnIiLCJnbCI6IkZSIiwicmVtb3RlSG9zdCI6IjM3LjE3MS4yMDAuNTkiLCJkZXZpY2VNYWtlIjoiIiwiZGV2aWNlTW9kZWwiOiIiLCJ2aXNpdG9yRGF0YSI6IkNndHNaVzVTVms1bGJrTldTU2lXdm9pa0JnJTNEJTNEIiwidXNlckFnZW50IjoiUnVieSxnemlwKGdmZSkiLCJjbGllbnROYW1lIjoiV0VCIiwiY2xpZW50VmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJvc1ZlcnNpb24iOiIiLCJvcmlnaW5hbFVybCI6Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL0Bjb25mcmVha3M/Y2JyZFx1MDAzZDFcdTAwMjZ1Y2JjYlx1MDAzZDEiLCJwbGF0Zm9ybSI6IkRFU0tUT1AiLCJjbGllbnRGb3JtRmFjdG9yIjoiVU5LTk9XTl9GT1JNX0ZBQ1RPUiIsImNvbmZpZ0luZm8iOnsiYXBwSW5zdGFsbERhdGEiOiJDSmEtaUtRR0VNeTNfaElReTd5dkJSRC10YThGRU5TaHJ3VVE4Nml2QlJENHRhOEZFTXpmcmdVUXJMZXZCUkNsbWE4RkVPNmlyd1VRajZPdkJSQzI0SzRGRUxxMHJ3VVFvdXl1QlJERHRfNFNFS3F5X2hJUTVMUC1FaEM5dHE0RkVPQ25yd1VRNV9ldUJSRGJyNjhGRUtpX3J3VVFncDJ2QlJETXJ2NFNFT0xVcmdVUV91NnVCUkM0aTY0RkVLTzByd1VRaWVpdUJSRFZ0cThGRUtYQ19oSVFtTkgtRWclM0QlM0QifSwiYWNjZXB0SGVhZGVyIjoiKi8qIiwiZGV2aWNlRXhwZXJpbWVudElkIjoiQ2h4T2Vra3dUV3BOTkU1VVRYcE5SRlY0VFZSQmQwMVVZek5OVVQwOUVKYS1pS1FHR0phLWlLUUcifSwidXNlciI6eyJsb2NrZWRTYWZldHlNb2RlIjpmYWxzZX0sInJlcXVlc3QiOnsidXNlU3NsIjp0cnVlfSwiY2xpY2tUcmFja2luZyI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiSWhNSTVOVFY5cWUwL3dJVkEwOVBCQjBJYUFDaiJ9fSwiSU5ORVJUVUJFX0NPTlRFWFRfQ0xJRU5UX05BTUUiOjEsIklOTkVSVFVCRV9DT05URVhUX0NMSUVOVF9WRVJTSU9OIjoiMi4yMDIzMDYwNy4wNi4wMCIsIklOTkVSVFVCRV9DT05URVhUX0dMIjoiRlIiLCJJTk5FUlRVQkVfQ09OVEVYVF9ITCI6ImZyIiwiTEFURVNUX0VDQVRDSEVSX1NFUlZJQ0VfVFJBQ0tJTkdfUEFSQU1TIjp7ImNsaWVudC5uYW1lIjoiV0VCIn0sIkxPR0dFRF9JTiI6ZmFsc2UsIlBBR0VfQlVJTERfTEFCRUwiOiJ5b3V0dWJlLmRlc2t0b3Aud2ViXzIwMjMwNjA3XzA2X1JDMDAiLCJQQUdFX0NMIjo1Mzg1MDQ5NDQsInNjaGVkdWxlciI6eyJ1c2VSYWYiOnRydWUsInRpbWVvdXQiOjIwfSwiU0VSVkVSX05BTUUiOiJXZWJGRSIsIlNFU1NJT05fSU5ERVgiOiIiLCJTSUdOSU5fVVJMIjoiaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tL1NlcnZpY2VMb2dpbj9zZXJ2aWNlXHUwMDNkeW91dHViZVx1MDAyNnVpbGVsXHUwMDNkM1x1MDAyNnBhc3NpdmVcdTAwM2R0cnVlXHUwMDI2Y29udGludWVcdTAwM2RodHRwcyUzQSUyRiUyRnd3dy55b3V0dWJlLmNvbSUyRnNpZ25pbiUzRmFjdGlvbl9oYW5kbGVfc2lnbmluJTNEdHJ1ZSUyNmFwcCUzRGRlc2t0b3AlMjZobCUzRGZyJTI2bmV4dCUzRGh0dHBzJTI1M0ElMjUyRiUyNTJGd3d3LnlvdXR1YmUuY29tJTI1MkYlMjU0MGNvbmZyZWFrcyUyNTNGY2JyZCUyNTNEMSUyNTI2dWNiY2IlMjUzRDElMjZmZWF0dXJlJTNEX19GRUFUVVJFX19cdTAwMjZobFx1MDAzZGZyIiwiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR1MiOnsiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfV0FUQ0giOnsidHJhbnNwYXJlbnRCYWNrZ3JvdW5kIjp0cnVlLCJzaG93TWluaXBsYXllckJ1dHRvbiI6dHJ1ZSwiZXh0ZXJuYWxGdWxsc2NyZWVuIjp0cnVlLCJzaG93TWluaXBsYXllclVpV2hlbk1pbmltaXplZCI6dHJ1ZSwicm9vdEVsZW1lbnRJZCI6Im1vdmllX3BsYXllciIsImpzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3BsYXllcl9pYXMudmZsc2V0L2ZyX0ZSL2Jhc2UuanMiLCJjc3NVcmwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvd3d3LXBsYXllci5jc3MiLCJjb250ZXh0SWQiOiJXRUJfUExBWUVSX0NPTlRFWFRfQ09ORklHX0lEX0tFVkxBUl9XQVRDSCIsImV2ZW50TGFiZWwiOiJkZXRhaWxwYWdlIiwiY29udGVudFJlZ2lvbiI6IkZSIiwiaGwiOiJmcl9GUiIsImhvc3RMYW5ndWFnZSI6ImZyIiwicGxheWVyU3R5bGUiOiJkZXNrdG9wLXBvbHltZXIiLCJpbm5lcnR1YmVBcGlLZXkiOiJBSXphU3lBT19GSjJTbHFVOFE0U1RFSExHQ2lsd19ZOV8xMXFjVzgiLCJpbm5lcnR1YmVBcGlWZXJzaW9uIjoidjEiLCJpbm5lcnR1YmVDb250ZXh0Q2xpZW50VmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJkZXZpY2UiOnsiYnJhbmQiOiIiLCJtb2RlbCI6IiIsInBsYXRmb3JtIjoiREVTS1RPUCIsImludGVyZmFjZU5hbWUiOiJXRUIiLCJpbnRlcmZhY2VWZXJzaW9uIjoiMi4yMDIzMDYwNy4wNi4wMCJ9LCJzZXJpYWxpemVkRXhwZXJpbWVudElkcyI6IjIzODU4MDU3LDIzOTgzMjk2LDIzOTg2MDMzLDI0MDA0NjQ0LDI0MDA3MjQ2LDI0MDgwNzM4LDI0MTM1MzEwLDI0MzYyNjg1LDI0MzYyNjg4LDI0MzYzMTE0LDI0MzY0Nzg5LDI0MzY2OTE3LDI0MzcwODk4LDI0Mzc3MzQ2LDI0NDE1ODY0LDI0NDMzNjc5LDI0NDM3NTc3LDI0NDM5MzYxLDI0NDkyNTQ3LDI0NTMyODU1LDI0NTUwNDU4LDI0NTUwOTUxLDI0NTU4NjQxLDI0NTU5MzI2LDI0Njk5ODk5LDM5MzIzMDc0Iiwic2VyaWFsaXplZEV4cGVyaW1lbnRGbGFncyI6Ikg1X2FzeW5jX2xvZ2dpbmdfZGVsYXlfbXNcdTAwM2QzMDAwMC4wXHUwMDI2SDVfZW5hYmxlX2Z1bGxfcGFjZl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNkg1X3VzZV9hc3luY19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmFjdGlvbl9jb21wYW5pb25fY2VudGVyX2FsaWduX2Rlc2NyaXB0aW9uXHUwMDNkdHJ1ZVx1MDAyNmFkX3BvZF9kaXNhYmxlX2NvbXBhbmlvbl9wZXJzaXN0X2Fkc19xdWFsaXR5XHUwMDNkdHJ1ZVx1MDAyNmFkZHRvX2FqYXhfbG9nX3dhcm5pbmdfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZhbGlnbl9hZF90b192aWRlb19wbGF5ZXJfbGlmZWN5Y2xlX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X2xpdmVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2YWxsb3dfcG9sdGVyZ3VzdF9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19za2lwX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNmF1dG9wbGF5X3RpbWVcdTAwM2Q4MDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfZnVsbHNjcmVlblx1MDAzZDMwMDBcdTAwMjZhdXRvcGxheV90aW1lX2Zvcl9tdXNpY19jb250ZW50XHUwMDNkMzAwMFx1MDAyNmJnX3ZtX3JlaW5pdF90aHJlc2hvbGRcdTAwM2Q3MjAwMDAwXHUwMDI2YmxvY2tlZF9wYWNrYWdlc19mb3Jfc3BzXHUwMDNkW11cdTAwMjZib3RndWFyZF9hc3luY19zbmFwc2hvdF90aW1lb3V0X21zXHUwMDNkMzAwMFx1MDAyNmNoZWNrX2FkX3VpX3N0YXR1c19mb3JfbXdlYl9zYWZhcmlcdTAwM2R0cnVlXHUwMDI2Y2hlY2tfbmF2aWdhdG9yX2FjY3VyYWN5X3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2Y2xlYXJfdXNlcl9wYXJ0aXRpb25lZF9sc1x1MDAzZHRydWVcdTAwMjZjbGllbnRfcmVzcGVjdF9hdXRvcGxheV9zd2l0Y2hfYnV0dG9uX3JlbmRlcmVyXHUwMDNkdHJ1ZVx1MDAyNmNvbXByZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZjb21wcmVzc2lvbl9kaXNhYmxlX3BvaW50XHUwMDNkMTBcdTAwMjZjb21wcmVzc2lvbl9wZXJmb3JtYW5jZV90aHJlc2hvbGRcdTAwM2QyNTBcdTAwMjZjc2lfb25fZ2VsXHUwMDNkdHJ1ZVx1MDAyNmRhc2hfbWFuaWZlc3RfdmVyc2lvblx1MDAzZDVcdTAwMjZkZWJ1Z19iYW5kYWlkX2hvc3RuYW1lXHUwMDNkXHUwMDI2ZGVidWdfc2hlcmxvZ191c2VybmFtZVx1MDAzZFx1MDAyNmRlbGF5X2Fkc19ndmlfY2FsbF9vbl9idWxsZWl0X2xpdmluZ19yb29tX21zXHUwMDNkMFx1MDAyNmRlcHJlY2F0ZV9jc2lfaGFzX2luZm9cdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3BhaXJfc2VydmxldF9lbmFibGVkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfY2hpbGRcdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19wYXJlbnRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9pbWFnZV9jdGFfbm9fYmFja2dyb3VuZFx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX2xvZ19pbWdfY2xpY2tfbG9jYXRpb25cdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9zcGFya2xlc19saWdodF9jdGFfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfY2hhbm5lbF9pZF9jaGVja19mb3Jfc3VzcGVuZGVkX2NoYW5uZWxzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfY2hpbGRfbm9kZV9hdXRvX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfZGVmZXJfYWRtb2R1bGVfb25fYWR2ZXJ0aXNlcl92aWRlb1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2ZlYXR1cmVzX2Zvcl9zdXBleFx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2xlZ2FjeV9kZXNrdG9wX3JlbW90ZV9xdWV1ZVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX21keF9jb25uZWN0aW9uX2luX21keF9tb2R1bGVfZm9yX211c2ljX3dlYlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX25ld19wYXVzZV9zdGF0ZTNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9wYWNmX2xvZ2dpbmdfZm9yX21lbW9yeV9saW1pdGVkX3R2XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcm91bmRpbmdfYWRfbm90aWZ5XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfc2ltcGxlX21peGVkX2RpcmVjdGlvbl9mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NzZGFpX29uX2Vycm9yc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3RhYmJpbmdfYmVmb3JlX2ZseW91dF9hZF9lbGVtZW50c19hcHBlYXJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90aHVtYm5haWxfcHJlbG9hZGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZGlzYWJsZV9wcm9ncmVzc19iYXJfY29udGV4dF9tZW51X2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc19lbmFibGVfYWxsb3dfd2F0Y2hfYWdhaW5fZW5kc2NyZWVuX2Zvcl9lbGlnaWJsZV9zaG9ydHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3ZlX2NvbnZlcnNpb25fcGFyYW1fcmVuYW1pbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfYXV0b3BsYXlfbm90X3N1cHBvcnRlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9jdWVfdmlkZW9fdW5wbGF5YWJsZV9maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfaG91c2VfYnJhbmRfYW5kX3l0X2NvZXhpc3RlbmNlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvYWRfcGxheWVyX2Zyb21fcGFnZV9zaG93XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvZ19zcGxheV9hc19hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dnaW5nX2V2ZW50X2hhbmRsZXJzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX21vYmlsZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfZHR0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9uZXdfY29udGV4dF9tZW51X3RyaWdnZXJpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGF1c2Vfb3ZlcmxheV93bl91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGVtX2RvbWFpbl9maXhfZm9yX2FkX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BmcF91bmJyYW5kZWRfZWxfZGVwcmVjYXRpb25cdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcmNhdF9hbGxvd2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcmVwbGFjZV91bmxvYWRfd19wYWdlaGlkZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9zY3JpcHRlZF9wbGF5YmFja19ibG9ja2VkX2xvZ2dpbmdfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3ZlX2NvbnZlcnNpb25fbG9nZ2luZ190cmFja2luZ19ub19hbGxvd19saXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfaGlkZV91bmZpbGxlZF9tb3JlX3ZpZGVvc19zdWdnZXN0aW9uc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2xpdGVfbW9kZVx1MDAzZDFcdTAwMjZlbWJlZHNfd2ViX253bF9kaXNhYmxlX25vY29va2llXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfc2hvcHBpbmdfb3ZlcmxheV9ub193YWl0X2Zvcl9wYWlkX2NvbnRlbnRfb3ZlcmxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3N5bnRoX2NoX2hlYWRlcnNfYmFubmVkX3VybHNfcmVnZXhcdTAwM2RcdTAwMjZlbmFibGVfYWJfcnBfaW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9hZF9jcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfYXBwX3Byb21vX2VuZGNhcF9lbWxfb25fdGFibGV0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jYXN0X2Zvcl93ZWJfdW5wbHVnZ2VkXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jYXN0X29uX211c2ljX3dlYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2xpZW50X3BhZ2VfaWRfaGVhZGVyX2Zvcl9maXJzdF9wYXJ0eV9waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfY2xpZW50X3NsaV9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9kaXNjcmV0ZV9saXZlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZF93ZWJfY2xpZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZF93ZWJfY2xpZW50X2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZHNfaWNvbl93ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2V2aWN0aW9uX3Byb3RlY3Rpb25fZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2dlbF9sb2dfY29tbWFuZHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X2luc3RyZWFtX3dhdGNoX25leHRfcGFyYW1zX29hcmxpYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfaDVfdmlkZW9fYWRzX29hcmxpYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfaGFuZGxlc19hY2NvdW50X21lbnVfc3dpdGNoZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2thYnVraV9jb21tZW50c19vbl9zaG9ydHNcdTAwM2RkaXNhYmxlZFx1MDAyNmVuYWJsZV9saXZlX3ByZW1pZXJlX3dlYl9wbGF5ZXJfaW5kaWNhdG9yXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9scl9ob21lX2luZmVlZF9hZHNfaW5saW5lX3BsYXliYWNrX3Byb2dyZXNzX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX213ZWJfbGl2ZXN0cmVhbV91aV91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX25ld19wYWlkX3Byb2R1Y3RfcGxhY2VtZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Nsb3RfYXNkZV9wbGF5ZXJfYnl0ZV9oNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2X2Zvcl9wYWdlX3RvcF9mb3JtYXRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeXNmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFzc19zZGNfZ2V0X2FjY291bnRzX2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BsX3JfY1x1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9maXhfb25fdHZodG1sNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9pbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zZXJ2ZXJfc3RpdGNoZWRfZGFpXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zaG9ydHNfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwX2FkX2d1aWRhbmNlX3Byb21wdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2tpcHBhYmxlX2Fkc19mb3JfdW5wbHVnZ2VkX2FkX3BvZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfdGVjdG9uaWNfYWRfdXhfZm9yX2hhbGZ0aW1lXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90aGlyZF9wYXJ0eV9pbmZvXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90b3Bzb2lsX3d0YV9mb3JfaGFsZnRpbWVfbGl2ZV9pbmZyYVx1MDAzZHRydWVcdTAwMjZlbmFibGVfd2ViX21lZGlhX3Nlc3Npb25fbWV0YWRhdGFfZml4XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfc2NoZWR1bGVyX3NpZ25hbHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3l0X2F0YV9pZnJhbWVfYXV0aHVzZXJcdTAwM2R0cnVlXHUwMDI2ZXJyb3JfbWVzc2FnZV9mb3JfZ3N1aXRlX25ldHdvcmtfcmVzdHJpY3Rpb25zXHUwMDNkdHJ1ZVx1MDAyNmV4cG9ydF9uZXR3b3JrbGVzc19vcHRpb25zXHUwMDNkdHJ1ZVx1MDAyNmV4dGVybmFsX2Z1bGxzY3JlZW5fd2l0aF9lZHVcdTAwM2R0cnVlXHUwMDI2ZmFzdF9hdXRvbmF2X2luX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZmV0Y2hfYXR0X2luZGVwZW5kZW50bHlcdTAwM2R0cnVlXHUwMDI2ZmlsbF9zaW5nbGVfdmlkZW9fd2l0aF9ub3RpZnlfdG9fbGFzclx1MDAzZHRydWVcdTAwMjZmaWx0ZXJfdnA5X2Zvcl9jc2RhaVx1MDAzZHRydWVcdTAwMjZmaXhfYWRzX3RyYWNraW5nX2Zvcl9zd2ZfY29uZmlnX2RlcHJlY2F0aW9uX213ZWJcdTAwM2R0cnVlXHUwMDI2Z2NmX2NvbmZpZ19zdG9yZV9lbmFibGVkXHUwMDNkdHJ1ZVx1MDAyNmdlbF9xdWV1ZV90aW1lb3V0X21heF9tc1x1MDAzZDMwMDAwMFx1MDAyNmdwYV9zcGFya2xlc190ZW5fcGVyY2VudF9sYXllclx1MDAzZHRydWVcdTAwMjZndmlfY2hhbm5lbF9jbGllbnRfc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmg1X2NvbXBhbmlvbl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfZ2VuZXJpY19lcnJvcl9sb2dnaW5nX2V2ZW50XHUwMDNkdHJ1ZVx1MDAyNmg1X2VuYWJsZV91bmlmaWVkX2NzaV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmg1X2lucGxheWVyX2VuYWJsZV9hZGNwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmg1X3Jlc2V0X2NhY2hlX2FuZF9maWx0ZXJfYmVmb3JlX3VwZGF0ZV9tYXN0aGVhZFx1MDAzZHRydWVcdTAwMjZoZWF0c2Vla2VyX2RlY29yYXRpb25fdGhyZXNob2xkXHUwMDNkMC4wXHUwMDI2aGZyX2Ryb3BwZWRfZnJhbWVyYXRlX2ZhbGxiYWNrX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZoaWRlX2VuZHBvaW50X292ZXJmbG93X29uX3l0ZF9kaXNwbGF5X2FkX3JlbmRlcmVyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2FkX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfYWRzX3ByZXJvbGxfbG9ja190aW1lb3V0X2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9hbGxvd19kaXNjb250aWd1b3VzX3NsaWNlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9hbGxvd192aWRlb19rZXlmcmFtZV93aXRob3V0X2F1ZGlvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F0dGFjaF9udW1fcmFuZG9tX2J5dGVzX3RvX2JhbmRhaWRcdTAwM2QwXHUwMDI2aHRtbDVfYXR0YWNoX3BvX3Rva2VuX3RvX2JhbmRhaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYXV0b25hdl9jYXBfaWRsZV9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X2F1dG9uYXZfcXVhbGl0eV9jYXBcdTAwM2Q3MjBcdTAwMjZodG1sNV9hdXRvcGxheV9kZWZhdWx0X3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2Jsb2NrX3BpcF9zYWZhcmlfZGVsYXlcdTAwM2QwXHUwMDI2aHRtbDVfYm1mZl9uZXdfZm91cmNjX2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2NvYmFsdF9kZWZhdWx0X2J1ZmZlcl9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9tYXhfc2l6ZV9mb3JfaW1tZWRfam9iXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9taW5fcHJvY2Vzc29yX2NudF90b19vZmZsb2FkX2FsZ29cdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X292ZXJyaWRlX3F1aWNcdTAwM2QwXHUwMDI2aHRtbDVfY29uc3VtZV9tZWRpYV9ieXRlc19zbGljZV9pbmZvc1x1MDAzZHRydWVcdTAwMjZodG1sNV9kZV9kdXBlX2NvbnRlbnRfdmlkZW9fbG9hZHNfaW5fbGlmZWN5Y2xlX2FwaVx1MDAzZHRydWVcdTAwMjZodG1sNV9kZWJ1Z19kYXRhX2xvZ19wcm9iYWJpbGl0eVx1MDAzZDAuMVx1MDAyNmh0bWw1X2RlY29kZV90b190ZXh0dXJlX2NhcFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZWZhdWx0X2FkX2dhaW5cdTAwM2QwLjVcdTAwMjZodG1sNV9kZWZhdWx0X3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2RlZmVyX2FkX21vZHVsZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9mZXRjaF9hdHRfbXNcdTAwM2QxMDAwXHUwMDI2aHRtbDVfZGVmZXJfbW9kdWxlc19kZWxheV90aW1lX21pbGxpc1x1MDAzZDBcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2NvdW50XHUwMDNkMVx1MDAyNmh0bWw1X2RlbGF5ZWRfcmV0cnlfZGVsYXlfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfZGVwcmVjYXRlX3ZpZGVvX3RhZ19wb29sXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rlc2t0b3BfdnIxODBfYWxsb3dfcGFubmluZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9kZl9kb3duZ3JhZGVfdGhyZXNoXHUwMDNkMC4yXHUwMDI2aHRtbDVfZGlzYWJsZV9jc2lfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9tb3ZlX3Bzc2hfdG9fbW9vdlx1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNhYmxlX25vbl9jb250aWd1b3VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc3BsYXllZF9mcmFtZV9yYXRlX2Rvd25ncmFkZV90aHJlc2hvbGRcdTAwM2Q0NVx1MDAyNmh0bWw1X2RybV9jaGVja19hbGxfa2V5X2Vycm9yX3N0YXRlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9kcm1fY3BpX2xpY2Vuc2Vfa2V5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hYzNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2Fkc19jbGllbnRfbW9uaXRvcmluZ19sb2dfdHZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NhcHRpb25fY2hhbmdlc19mb3JfbW9zYWljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jbGllbnRfaGludHNfb3ZlcnJpZGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NvbXBvc2l0ZV9lbWJhcmdvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9lYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9lbWJlZGRlZF9wbGF5ZXJfdmlzaWJpbGl0eV9zaWduYWxzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9uZXdfaHZjX2VuY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbm9uX25vdGlmeV9jb21wb3NpdGVfdm9kX2xzYXJfcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfc2luZ2xlX3ZpZGVvX3ZvZF9pdmFyX29uX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZGFzaFx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19lbmNyeXB0ZWRfdnA5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfYWxjXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfZmFzdF9saW5lYXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5jb3VyYWdlX2FycmF5X2NvYWxlc2NpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2FwbGVzc19lbmRlZF90cmFuc2l0aW9uX2J1ZmZlcl9tc1x1MDAzZDIwMFx1MDAyNmh0bWw1X2dlbmVyYXRlX3Nlc3Npb25fcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2xfZnBzX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZodG1sNV9oZGNwX3Byb2Jpbmdfc3RyZWFtX3VybFx1MDAzZFx1MDAyNmh0bWw1X2hmcl9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QxLjBcdTAwMjZodG1sNV9pZGxlX3JhdGVfbGltaXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX2ZhaXJwbGF5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9wbGF5cmVhZHlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3dpZGV2aW5lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczRfc2Vla19hYm92ZV96ZXJvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczdfZm9yY2VfcGxheV9vbl9zdGFsbFx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3NfZm9yY2Vfc2Vla190b196ZXJvX29uX3N0b3BcdTAwM2R0cnVlXHUwMDI2aHRtbDVfanVtYm9fbW9iaWxlX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDMuMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9ub25zdHJlYW1pbmdfbWZmYV9tc1x1MDAzZDQwMDBcdTAwMjZodG1sNV9qdW1ib191bGxfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMS4zXHUwMDI2aHRtbDVfbGljZW5zZV9jb25zdHJhaW50X2RlbGF5XHUwMDNkNTAwMFx1MDAyNmh0bWw1X2xpdmVfYWJyX2hlYWRfbWlzc19mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYWJyX3JlcHJlZGljdF9mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYnl0ZXJhdGVfZmFjdG9yX2Zvcl9yZWFkYWhlYWRcdTAwM2QxLjNcdTAwMjZodG1sNV9saXZlX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9saXZlX25vcm1hbF9sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2xpdmVfdWx0cmFfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xvZ19hdWRpb19hYnJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX2V4cGVyaW1lbnRfaWRfZnJvbV9wbGF5ZXJfcmVzcG9uc2VfdG9fY3RtcFx1MDAzZFx1MDAyNmh0bWw1X2xvZ19maXJzdF9zc2RhaV9yZXF1ZXN0c19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19yZWJ1ZmZlcl9ldmVudHNcdTAwM2Q1XHUwMDI2aHRtbDVfbG9nX3NzZGFpX2ZhbGxiYWNrX2Fkc1x1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfdHJpZ2dlcl9ldmVudHNfd2l0aF9kZWJ1Z19kYXRhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX3RocmVzaG9sZF9tc1x1MDAzZDMwMDAwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3NlZ19kcmlmdF9saW1pdF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc191bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3ZwOV9vdGZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWF4X2RyaWZ0X3Blcl90cmFja19zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWF4X2hlYWRtX2Zvcl9zdHJlYW1pbmdfeGhyXHUwMDNkMFx1MDAyNmh0bWw1X21heF9saXZlX2R2cl93aW5kb3dfcGx1c19tYXJnaW5fc2Vjc1x1MDAzZDQ2ODAwLjBcdTAwMjZodG1sNV9tYXhfcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21heF9yZWRpcmVjdF9yZXNwb25zZV9sZW5ndGhcdTAwM2Q4MTkyXHUwMDI2aHRtbDVfbWF4X3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21heF9zb3VyY2VfYnVmZmVyX2FwcGVuZF9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X21heGltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9tZWRpYV9mdWxsc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21mbF9leHRlbmRfbWF4X3JlcXVlc3RfdGltZVx1MDAzZHRydWVcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9jYXBfc2Vjc1x1MDAzZDYwXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9taW5fc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfYWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbm9fcGxhY2Vob2xkZXJfcm9sbGJhY2tzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vbl9uZXR3b3JrX3JlYnVmZmVyX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X25vbl9vbmVzaWVfYXR0YWNoX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vdF9yZWdpc3Rlcl9kaXNwb3NhYmxlc193aGVuX2NvcmVfbGlzdGVuc1x1MDAzZHRydWVcdTAwMjZodG1sNV9vZmZsaW5lX2ZhaWx1cmVfcmV0cnlfbGltaXRcdTAwM2QyXHUwMDI2aHRtbDVfb25lc2llX2RlZmVyX2NvbnRlbnRfbG9hZGVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9ob3N0X3JhY2luZ19jYXBfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2lnbm9yZV9pbm5lcnR1YmVfYXBpX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbGl2ZV90dGxfc2Vjc1x1MDAzZDhcdTAwMjZodG1sNV9vbmVzaWVfbm9uemVyb19wbGF5YmFja19zdGFydFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbm90aWZ5X2N1ZXBvaW50X21hbmFnZXJfb25fY29tcGxldGlvblx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9jb29sZG93bl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9pbnRlcnZhbF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9tYXhfbGFjdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlcXVlc3RfdGltZW91dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9vbmVzaWVfc3RpY2t5X3NlcnZlcl9zaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BhdXNlX29uX25vbmZvcmVncm91bmRfcGxhdGZvcm1fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlYWtfc2hhdmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZl9jYXBfb3ZlcnJpZGVfc3RpY2t5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2NhcF9mbG9vclx1MDAzZDM2MFx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2ltcGFjdF9wcm9maWxpbmdfdGltZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcGVyc2VydmVfYXYxX3BlcmZfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX2JhY2twcmVzc3VyZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF0Zm9ybV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfcGxheWVyX2F1dG9uYXZfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfZHluYW1pY19ib3R0b21fZ3JhZGllbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxheWVyX21pbl9idWlsZF9jbFx1MDAzZC0xXHUwMDI2aHRtbDVfcGxheWVyX3ByZWxvYWRfYWRfZml4XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Bvc3RfaW50ZXJydXB0X3JlYWRhaGVhZFx1MDAzZDIwXHUwMDI2aHRtbDVfcHJlZmVyX3NlcnZlcl9id2UzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ByZWxvYWRfd2FpdF90aW1lX3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9wcm9iZV9wcmltYXJ5X2RlbGF5X2Jhc2VfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcHJvY2Vzc19hbGxfZW5jcnlwdGVkX2V2ZW50c1x1MDAzZHRydWVcdTAwMjZodG1sNV9xb2VfbGhfbWF4X3JlcG9ydF9jb3VudFx1MDAzZDBcdTAwMjZodG1sNV9xb2VfbGhfbWluX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X3F1ZXJ5X3N3X3NlY3VyZV9jcnlwdG9fZm9yX2FuZHJvaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmFuZG9tX3BsYXliYWNrX2NhcFx1MDAzZDBcdTAwMjZodG1sNV9yZWNvZ25pemVfcHJlZGljdF9zdGFydF9jdWVfcG9pbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX2NvbW1hbmRfdHJpZ2dlcmVkX2NvbXBhbmlvbnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX25vdF9zZXJ2YWJsZV9jaGVja19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbmFtZV9hcGJzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9mYXRhbF9kcm1fcmVzdHJpY3RlZF9lcnJvcl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9zbG93X2Fkc19hc19lcnJvclx1MDAzZHRydWVcdTAwMjZodG1sNV9yZXF1ZXN0X29ubHlfaGRyX29yX3Nkcl9rZXlzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfc2l6aW5nX211bHRpcGxpZXJcdTAwM2QwLjhcdTAwMjZodG1sNV9yZXNldF9tZWRpYV9zdHJlYW1fb25fdW5yZXN1bWFibGVfc2xpY2VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Jlc291cmNlX2JhZF9zdGF0dXNfZGVsYXlfc2NhbGluZ1x1MDAzZDEuNVx1MDAyNmh0bWw1X3Jlc3RyaWN0X3N0cmVhbWluZ194aHJfb25fc3FsZXNzX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NhZmFyaV9kZXNrdG9wX2VtZV9taW5fdmVyc2lvblx1MDAzZDBcdTAwMjZodG1sNV9zYW1zdW5nX2thbnRfbGltaXRfbWF4X2JpdHJhdGVcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19qaWdnbGVfY210X2RlbGF5X21zXHUwMDNkODAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fZGVsYXlfbXNcdTAwM2QxMjAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2J1ZmZlcl9yYW5nZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c192cnNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9jZmxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX3NldF9jbXRfZGVsYXlfbXNcdTAwM2QyMDAwXHUwMDI2aHRtbDVfc2Vla190aW1lb3V0X2RlbGF5X21zXHUwMDNkMjAwMDBcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2RlY29yYXRlZF91cmxfcmV0cnlfbGltaXRcdTAwM2Q1XHUwMDI2aHRtbDVfc2VydmVyX3N0aXRjaGVkX2RhaV9ncm91cFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZXNzaW9uX3BvX3Rva2VuX2ludGVydmFsX3RpbWVfbXNcdTAwM2Q5MDAwMDBcdTAwMjZodG1sNV9za2lwX29vYl9zdGFydF9zZWNvbmRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NraXBfc2xvd19hZF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfc2tpcF9zdWJfcXVhbnR1bV9kaXNjb250aW51aXR5X3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X25vX21lZGlhX3NvdXJjZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NzZGFpX2FkZmV0Y2hfZHluYW1pY190aW1lb3V0X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X3NzZGFpX2VuYWJsZV9uZXdfc2Vla19sb2dpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9zdGF0ZWZ1bF9hdWRpb19taW5fYWRqdXN0bWVudF92YWx1ZVx1MDAzZDBcdTAwMjZodG1sNV9zdGF0aWNfYWJyX3Jlc29sdXRpb25fc2hlbGZcdTAwM2QwXHUwMDI2aHRtbDVfc3RvcmVfeGhyX2hlYWRlcnNfcmVhZGFibGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3RyZWFtaW5nX3hocl9leHBhbmRfcmVxdWVzdF9zaXplXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX2xvYWRfc3BlZWRfY2hlY2tfaW50ZXJ2YWxcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzXHUwMDNkMC4yNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9idWZmZXJfaGVhbHRoX3NlY3Nfb25fdGltZW91dFx1MDAzZDAuMVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9sb2FkX3NwZWVkXHUwMDNkMS41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfc2Vla19sYXRlbmN5X2Z1ZGdlXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0X2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RpbWVvdXRfc2Vjc1x1MDAzZDIuMFx1MDAyNmh0bWw1X3VnY19saXZlX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VnY192b2RfYXVkaW9fNTFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdW5yZXBvcnRlZF9zZWVrX3Jlc2Vla19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV91bnJlc3RyaWN0ZWRfbGF5ZXJfaGlnaF9yZXNfbG9nZ2luZ19wZXJjZW50XHUwMDNkMC4wXHUwMDI2aHRtbDVfdXJsX3BhZGRpbmdfbGVuZ3RoXHUwMDNkMFx1MDAyNmh0bWw1X3VybF9zaWduYXR1cmVfZXhwaXJ5X3RpbWVfaG91cnNcdTAwM2QwXHUwMDI2aHRtbDVfdXNlX3Bvc3RfZm9yX21lZGlhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VzZV91bXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdmlkZW9fdGJkX21pbl9rYlx1MDAzZDBcdTAwMjZodG1sNV92aWV3cG9ydF91bmRlcnNlbmRfbWF4aW11bVx1MDAzZDAuMFx1MDAyNmh0bWw1X3ZvbHVtZV9zbGlkZXJfdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZodG1sNV93ZWJfZW5hYmxlX2hhbGZ0aW1lX3ByZXJvbGxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2VicG9faWRsZV9wcmlvcml0eV9qb2JcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29mZmxlX3Jlc3VtZVx1MDAzZHRydWVcdTAwMjZodG1sNV93b3JrYXJvdW5kX2RlbGF5X3RyaWdnZXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfeXR2bHJfZW5hYmxlX3NpbmdsZV9zZWxlY3Rfc3VydmV5XHUwMDNkdHJ1ZVx1MDAyNmlnbm9yZV9vdmVybGFwcGluZ19jdWVfcG9pbnRzX29uX2VuZGVtaWNfbGl2ZV9odG1sNVx1MDAzZHRydWVcdTAwMjZpbF91c2Vfdmlld19tb2RlbF9sb2dnaW5nX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2aW5pdGlhbF9nZWxfYmF0Y2hfdGltZW91dFx1MDAzZDIwMDBcdTAwMjZpbmplY3RlZF9saWNlbnNlX2hhbmRsZXJfZXJyb3JfY29kZVx1MDAzZDBcdTAwMjZpbmplY3RlZF9saWNlbnNlX2hhbmRsZXJfbGljZW5zZV9zdGF0dXNcdTAwM2QwXHUwMDI2aXRkcm1faW5qZWN0ZWRfbGljZW5zZV9zZXJ2aWNlX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aXRkcm1fd2lkZXZpbmVfaGFyZGVuZWRfdm1wX21vZGVcdTAwM2Rsb2dcdTAwMjZqc29uX2NvbmRlbnNlZF9yZXNwb25zZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfY29tbWFuZF9oYW5kbGVyX2NvbW1hbmRfYmFubGlzdFx1MDAzZFtdXHUwMDI2a2V2bGFyX2Ryb3Bkb3duX2ZpeFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfZ2VsX2Vycm9yX3JvdXRpbmdcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfZXhwYW5kX3RvcFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllcl9wbGF5X3BhdXNlX29uX3NjcmltXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9wbGF5YmFja19hc3NvY2lhdGVkX3F1ZXVlXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9xdWV1ZV91c2VfdXBkYXRlX2FwaVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc2ltcF9zaG9ydHNfcmVzZXRfc2Nyb2xsXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NtYXJ0X2Rvd25sb2Fkc19zZXR0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl92aW1pb191c2Vfc2hhcmVkX21vbml0b3JcdTAwM2R0cnVlXHUwMDI2bGl2ZV9jaHVua19yZWFkYWhlYWRcdTAwM2QzXHUwMDI2bGl2ZV9mcmVzY2FfdjJcdTAwM2R0cnVlXHUwMDI2bG9nX2Vycm9yc190aHJvdWdoX253bF9vbl9yZXRyeVx1MDAzZHRydWVcdTAwMjZsb2dfZ2VsX2NvbXByZXNzaW9uX2xhdGVuY3lcdTAwM2R0cnVlXHUwMDI2bG9nX2hlYXJ0YmVhdF93aXRoX2xpZmVjeWNsZXNcdTAwM2R0cnVlXHUwMDI2bG9nX3dlYl9lbmRwb2ludF90b19sYXllclx1MDAzZHRydWVcdTAwMjZsb2dfd2luZG93X29uZXJyb3JfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlXHUwMDNkdHJ1ZVx1MDAyNm1hbmlmZXN0bGVzc19wb3N0X2xpdmVfdWZwaFx1MDAzZHRydWVcdTAwMjZtYXhfYm9keV9zaXplX3RvX2NvbXByZXNzXHUwMDNkNTAwMDAwXHUwMDI2bWF4X3ByZWZldGNoX3dpbmRvd19zZWNfZm9yX2xpdmVzdHJlYW1fb3B0aW1pemF0aW9uXHUwMDNkMFx1MDAyNm1heF9yZXNvbHV0aW9uX2Zvcl93aGl0ZV9ub2lzZVx1MDAzZDM2MFx1MDAyNm1keF9lbmFibGVfcHJpdmFjeV9kaXNjbG9zdXJlX3VpXHUwMDNkdHJ1ZVx1MDAyNm1keF9sb2FkX2Nhc3RfYXBpX2Jvb3RzdHJhcF9zY3JpcHRcdTAwM2R0cnVlXHUwMDI2bWlncmF0ZV9ldmVudHNfdG9fdHNcdTAwM2R0cnVlXHUwMDI2bWluX3ByZWZldGNoX29mZnNldF9zZWNfZm9yX2xpdmVzdHJlYW1fb3B0aW1pemF0aW9uXHUwMDNkMTBcdTAwMjZtdXNpY19lbmFibGVfc2hhcmVkX2F1ZGlvX3RpZXJfbG9naWNcdTAwM2R0cnVlXHUwMDI2bXdlYl9jM19lbmRzY3JlZW5cdTAwM2R0cnVlXHUwMDI2bXdlYl9lbmFibGVfY3VzdG9tX2NvbnRyb2xfc2hhcmVkXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX3NraXBwYWJsZXNfb25famlvX3Bob25lXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfbXV0ZWRfYXV0b3BsYXlfYW5pbWF0aW9uXHUwMDNkc2hyaW5rXHUwMDI2bXdlYl9uYXRpdmVfY29udHJvbF9pbl9mYXV4X2Z1bGxzY3JlZW5fc2hhcmVkXHUwMDNkdHJ1ZVx1MDAyNm5ldHdvcmtfcG9sbGluZ19pbnRlcnZhbFx1MDAzZDMwMDAwXHUwMDI2bmV0d29ya2xlc3NfZ2VsXHUwMDNkdHJ1ZVx1MDAyNm5ldHdvcmtsZXNzX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2bmV3X2NvZGVjc19zdHJpbmdfYXBpX3VzZXNfbGVnYWN5X3N0eWxlXHUwMDNkdHJ1ZVx1MDAyNm53bF9zZW5kX2Zhc3Rfb25fdW5sb2FkXHUwMDNkdHJ1ZVx1MDAyNm53bF9zZW5kX2Zyb21fbWVtb3J5X3doZW5fb25saW5lXHUwMDNkdHJ1ZVx1MDAyNm9mZmxpbmVfZXJyb3JfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2cGFjZl9sb2dnaW5nX2RlbGF5X21pbGxpc2Vjb25kc190aHJvdWdoX3liZmVfdHZcdTAwM2QzMDAwMFx1MDAyNnBhZ2VpZF9hc19oZWFkZXJfd2ViXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9hZHNfc2V0X2FkZm9ybWF0X29uX2NsaWVudFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWxsb3dfYXV0b25hdl9hZnRlcl9wbGF5bGlzdFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYm9vdHN0cmFwX21ldGhvZFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZGVmZXJfY2FwdGlvbl9kaXNwbGF5XHUwMDNkMTAwMFx1MDAyNnBsYXllcl9kZXN0cm95X29sZF92ZXJzaW9uXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9kb3VibGV0YXBfdG9fc2Vla1x1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZW5hYmxlX3BsYXliYWNrX3BsYXlsaXN0X2NoYW5nZVx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZW5kc2NyZWVuX2VsbGlwc2lzX2ZpeFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfdW5kZXJsYXlfbWluX3BsYXllcl93aWR0aFx1MDAzZDc2OC4wXHUwMDI2cGxheWVyX3VuZGVybGF5X3ZpZGVvX3dpZHRoX2ZyYWN0aW9uXHUwMDNkMC42XHUwMDI2cGxheWVyX3dlYl9jYW5hcnlfc3RhZ2VcdTAwM2QwXHUwMDI2cGxheXJlYWR5X2ZpcnN0X3BsYXlfZXhwaXJhdGlvblx1MDAzZC0xXHUwMDI2cG9seW1lcl9iYWRfYnVpbGRfbGFiZWxzXHUwMDNkdHJ1ZVx1MDAyNnBvbHltZXJfbG9nX3Byb3BfY2hhbmdlX29ic2VydmVyX3BlcmNlbnRcdTAwM2QwXHUwMDI2cG9seW1lcl92ZXJpZml5X2FwcF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZwcmVza2lwX2J1dHRvbl9zdHlsZV9hZHNfYmFja2VuZFx1MDAzZGNvdW50ZG93bl9uZXh0X3RvX3RodW1ibmFpbFx1MDAyNnFvZV9ud2xfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNnFvZV9zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZyZWNvcmRfYXBwX2NyYXNoZWRfd2ViXHUwMDNkdHJ1ZVx1MDAyNnJlcGxhY2VfcGxheWFiaWxpdHlfcmV0cmlldmVyX2luX3dhdGNoXHUwMDNkdHJ1ZVx1MDAyNnNjaGVkdWxlcl91c2VfcmFmX2J5X2RlZmF1bHRcdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX2hlYWRlcl9zdHJpbmdfdGVtcGxhdGVcdTAwM2RzZWxmX3BvZGRpbmdfaW50ZXJzdGl0aWFsX21lc3NhZ2VcdTAwMjZzZWxmX3BvZGRpbmdfaGlnaGxpZ2h0X25vbl9kZWZhdWx0X2J1dHRvblx1MDAzZHRydWVcdTAwMjZzZWxmX3BvZGRpbmdfbWlkcm9sbF9jaG9pY2Vfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlXHUwMDI2c2VuZF9jb25maWdfaGFzaF90aW1lclx1MDAzZDBcdTAwMjZzZXRfaW50ZXJzdGl0aWFsX2FkdmVydGlzZXJzX3F1ZXN0aW9uX3RleHRcdTAwM2R0cnVlXHUwMDI2c2hvcnRfc3RhcnRfdGltZV9wcmVmZXJfcHVibGlzaF9pbl93YXRjaF9sb2dcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX21vZGVfdG9fcGxheWVyX2FwaVx1MDAzZHRydWVcdTAwMjZzaG9ydHNfbm9fc3RvcF92aWRlb19jYWxsXHUwMDNkdHJ1ZVx1MDAyNnNob3VsZF9jbGVhcl92aWRlb19kYXRhX29uX3BsYXllcl9jdWVkX3Vuc3RhcnRlZFx1MDAzZHRydWVcdTAwMjZzaW1wbHlfZW1iZWRkZWRfZW5hYmxlX2JvdGd1YXJkXHUwMDNkdHJ1ZVx1MDAyNnNraXBfaW5saW5lX211dGVkX2xpY2Vuc2Vfc2VydmljZV9jaGVja1x1MDAzZHRydWVcdTAwMjZza2lwX2ludmFsaWRfeXRjc2lfdGlja3NcdTAwM2R0cnVlXHUwMDI2c2tpcF9sc19nZWxfcmV0cnlcdTAwM2R0cnVlXHUwMDI2c2tpcF9zZXR0aW5nX2luZm9faW5fY3NpX2RhdGFfb2JqZWN0XHUwMDNkdHJ1ZVx1MDAyNnNsb3dfY29tcHJlc3Npb25zX2JlZm9yZV9hYmFuZG9uX2NvdW50XHUwMDNkNFx1MDAyNnNwZWVkbWFzdGVyX2NhbmNlbGxhdGlvbl9tb3ZlbWVudF9kcFx1MDAzZDBcdTAwMjZzcGVlZG1hc3Rlcl9wbGF5YmFja19yYXRlXHUwMDNkMC4wXHUwMDI2c3BlZWRtYXN0ZXJfdG91Y2hfYWN0aXZhdGlvbl9tc1x1MDAzZDBcdTAwMjZzdGFydF9jbGllbnRfZ2NmXHUwMDNkdHJ1ZVx1MDAyNnN0YXJ0X2NsaWVudF9nY2ZfZm9yX3BsYXllclx1MDAzZHRydWVcdTAwMjZzdGFydF9zZW5kaW5nX2NvbmZpZ19oYXNoXHUwMDNkdHJ1ZVx1MDAyNnN0cmVhbWluZ19kYXRhX2VtZXJnZW5jeV9pdGFnX2JsYWNrbGlzdFx1MDAzZFtdXHUwMDI2c3VwcHJlc3NfZXJyb3JfMjA0X2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2dHJhbnNwb3J0X3VzZV9zY2hlZHVsZXJcdTAwM2R0cnVlXHUwMDI2dHZfcGFjZl9sb2dnaW5nX3NhbXBsZV9yYXRlXHUwMDNkMC4wMVx1MDAyNnR2aHRtbDVfdW5wbHVnZ2VkX3ByZWxvYWRfY2FjaGVfc2l6ZVx1MDAzZDVcdTAwMjZ1bmNvdmVyX2FkX2JhZGdlX29uX1JUTF90aW55X3dpbmRvd1x1MDAzZHRydWVcdTAwMjZ1bnBsdWdnZWRfZGFpX2xpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNnVucGx1Z2dlZF90dmh0bWw1X3ZpZGVvX3ByZWxvYWRfb25fZm9jdXNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2dXBkYXRlX2xvZ19ldmVudF9jb25maWdcdTAwM2R0cnVlXHUwMDI2dXNlX2FjY2Vzc2liaWxpdHlfZGF0YV9vbl9kZXNrdG9wX3BsYXllcl9idXR0b25cdTAwM2R0cnVlXHUwMDI2dXNlX2NvcmVfc21cdTAwM2R0cnVlXHUwMDI2dXNlX2lubGluZWRfcGxheWVyX3JwY1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X2NtbFx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X2luX21lbW9yeV9zdG9yYWdlXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX2luaXRpYWxpemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3Nhd1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zdHdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfd3RzXHUwMDNkdHJ1ZVx1MDAyNnVzZV9wbGF5ZXJfYWJ1c2VfYmdfbGlicmFyeVx1MDAzZHRydWVcdTAwMjZ1c2VfcHJvZmlsZXBhZ2VfZXZlbnRfbGFiZWxfaW5fY2Fyb3VzZWxfcGxheWJhY2tzXHUwMDNkdHJ1ZVx1MDAyNnVzZV9yZXF1ZXN0X3RpbWVfbXNfaGVhZGVyXHUwMDNkdHJ1ZVx1MDAyNnVzZV9zZXNzaW9uX2Jhc2VkX3NhbXBsaW5nXHUwMDNkdHJ1ZVx1MDAyNnVzZV90c192aXNpYmlsaXR5bG9nZ2VyXHUwMDNkdHJ1ZVx1MDAyNnZhcmlhYmxlX2J1ZmZlcl90aW1lb3V0X21zXHUwMDNkMFx1MDAyNnZlcmlmeV9hZHNfaXRhZ19lYXJseVx1MDAzZHRydWVcdTAwMjZ2cDlfZHJtX2xpdmVcdTAwM2R0cnVlXHUwMDI2dnNzX2ZpbmFsX3Bpbmdfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2dnNzX3BpbmdzX3VzaW5nX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNnZzc19wbGF5YmFja191c2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2d2ViX2FwaV91cmxcdTAwM2R0cnVlXHUwMDI2d2ViX2FzeW5jX2NvbnRleHRfcHJvY2Vzc29yX2ltcGxcdTAwM2RzdGFuZGFsb25lXHUwMDI2d2ViX2NpbmVtYXRpY193YXRjaF9zZXR0aW5nc1x1MDAzZHRydWVcdTAwMjZ3ZWJfY2xpZW50X3ZlcnNpb25fb3ZlcnJpZGVcdTAwM2RcdTAwMjZ3ZWJfZGVkdXBlX3ZlX2dyYWZ0aW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9kZXByZWNhdGVfc2VydmljZV9hamF4X21hcF9kZXBlbmRlbmN5XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfZXJyb3JfMjA0XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfaW5zdHJlYW1fYWRzX2xpbmtfZGVmaW5pdGlvbl9hMTF5X2J1Z2ZpeFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX3Zvel9hdWRpb19mZWVkYmFja1x1MDAzZHRydWVcdTAwMjZ3ZWJfZml4X2ZpbmVfc2NydWJiaW5nX2RyYWdcdTAwM2R0cnVlXHUwMDI2d2ViX2ZvcmVncm91bmRfaGVhcnRiZWF0X2ludGVydmFsX21zXHUwMDNkMjgwMDBcdTAwMjZ3ZWJfZm9yd2FyZF9jb21tYW5kX29uX3Bialx1MDAzZHRydWVcdTAwMjZ3ZWJfZ2VsX2RlYm91bmNlX21zXHUwMDNkNjAwMDBcdTAwMjZ3ZWJfZ2VsX3RpbWVvdXRfY2FwXHUwMDNkdHJ1ZVx1MDAyNndlYl9pbmxpbmVfcGxheWVyX25vX3BsYXliYWNrX3VpX2NsaWNrX2hhbmRsZXJcdTAwM2R0cnVlXHUwMDI2d2ViX2tleV9tb21lbnRzX21hcmtlcnNcdTAwM2R0cnVlXHUwMDI2d2ViX2xvZ19tZW1vcnlfdG90YWxfa2J5dGVzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dnaW5nX21heF9iYXRjaFx1MDAzZDE1MFx1MDAyNndlYl9tb2Rlcm5fYWRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fYnV0dG9uc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNfYmxfc3VydmV5XHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc2NydWJiZXJcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zdWJzY3JpYmVcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zdWJzY3JpYmVfc3R5bGVcdTAwM2RmaWxsZWRcdTAwMjZ3ZWJfbmV3X2F1dG9uYXZfY291bnRkb3duXHUwMDNkdHJ1ZVx1MDAyNndlYl9vbmVfcGxhdGZvcm1fZXJyb3JfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX29wX3NpZ25hbF90eXBlX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNndlYl9wYXVzZWRfb25seV9taW5pcGxheWVyX3Nob3J0Y3V0X2V4cGFuZFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF9sb2dfY3R0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5YmFja19hc3NvY2lhdGVkX3ZlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYWRkX3ZlX2NvbnZlcnNpb25fbG9nZ2luZ190b19vdXRib3VuZF9saW5rc1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2Fsd2F5c19lbmFibGVfYXV0b190cmFuc2xhdGlvblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FwaV9sb2dnaW5nX2ZyYWN0aW9uXHUwMDNkMC4wMVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl9lbXB0eV9zdWdnZXN0aW9uc19maXhcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X3RvZ2dsZV9hbHdheXNfbGlzdGVuXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl91c2Vfc2VydmVyX3Byb3ZpZGVkX3N0YXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfY2FwdGlvbl9sYW5ndWFnZV9wcmVmZXJlbmNlX3N0aWNraW5lc3NfZHVyYXRpb25cdTAwM2QzMFx1MDAyNndlYl9wbGF5ZXJfZGVjb3VwbGVfYXV0b25hdlx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2Rpc2FibGVfaW5saW5lX3NjcnViYmluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9lYXJseV93YXJuaW5nX3NuYWNrYmFyXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX2ZlYXR1cmVkX3Byb2R1Y3RfYmFubmVyX29uX2Rlc2t0b3BcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfcHJlbWl1bV9oYnJfaW5faDVfYXBpXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX3BsYXliYWNrX2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2lubmVydHViZV9wbGF5bGlzdF91cGRhdGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pcHBfY2FuYXJ5X3R5cGVfZm9yX2xvZ2dpbmdcdTAwM2RcdTAwMjZ3ZWJfcGxheWVyX2xpdmVfbW9uaXRvcl9lbnZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9sb2dfY2xpY2tfYmVmb3JlX2dlbmVyYXRpbmdfdmVfY29udmVyc2lvbl9wYXJhbXNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9tb3ZlX2F1dG9uYXZfdG9nZ2xlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbXVzaWNfdmlzdWFsaXplcl90cmVhdG1lbnRcdTAwM2RmYWtlXHUwMDI2d2ViX3BsYXllcl9tdXRhYmxlX2V2ZW50X2xhYmVsXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbml0cmF0ZV9wcm9tb190b29sdGlwXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfb2ZmbGluZV9wbGF5bGlzdF9hdXRvX3JlZnJlc2hcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9yZXNwb25zZV9wbGF5YmFja190cmFja2luZ19wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2Vla19jaGFwdGVyc19ieV9zaG9ydGN1dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlbnRpbmVsX2lzX3VuaXBsYXllclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3VsZF9ob25vcl9pbmNsdWRlX2Fzcl9zZXR0aW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2hvd19tdXNpY19pbl90aGlzX3ZpZGVvX2dyYXBoaWNcdTAwM2R2aWRlb190aHVtYm5haWxcdTAwMjZ3ZWJfcGxheWVyX3NtYWxsX2hicF9zZXR0aW5nc19tZW51XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc3NfZGFpX2FkX2ZldGNoaW5nX3RpbWVvdXRfbXNcdTAwM2QxNTAwMFx1MDAyNndlYl9wbGF5ZXJfc3NfbWVkaWFfdGltZV9vZmZzZXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90b3BpZnlfc3VidGl0bGVzX2Zvcl9zaG9ydHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90b3VjaF9tb2RlX2ltcHJvdmVtZW50c1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RyYW5zZmVyX3RpbWVvdXRfdGhyZXNob2xkX21zXHUwMDNkMTA4MDAwMDBcdTAwMjZ3ZWJfcGxheWVyX3Vuc2V0X2RlZmF1bHRfY3NuX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl91c2VfbmV3X2FwaV9mb3JfcXVhbGl0eV9wdWxsYmFja1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3ZlX2NvbnZlcnNpb25fZml4ZXNfZm9yX2NoYW5uZWxfaW5mb1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3dhdGNoX25leHRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlX3BhcnNpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3ByZWZldGNoX3ByZWxvYWRfdmlkZW9cdTAwM2R0cnVlXHUwMDI2d2ViX3JvdW5kZWRfdGh1bWJuYWlsc1x1MDAzZHRydWVcdTAwMjZ3ZWJfc2V0dGluZ3NfbWVudV9pY29uc1x1MDAzZHRydWVcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNndlYl9zbW9vdGhuZXNzX3Rlc3RfbWV0aG9kXHUwMDNkMFx1MDAyNndlYl95dF9jb25maWdfY29udGV4dFx1MDAzZHRydWVcdTAwMjZ3aWxfaWNvbl9yZW5kZXJfd2hlbl9pZGxlXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9jbGVhbl91cF9hZnRlcl9lbnRpdHlfbWlncmF0aW9uXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9lbmFibGVfZG93bmxvYWRfc3RhdHVzXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9wbGF5bGlzdF9vcHRpbWl6YXRpb25cdTAwM2R0cnVlXHUwMDI2eXRpZGJfY2xlYXJfZW1iZWRkZWRfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2ZldGNoX2RhdGFzeW5jX2lkc19mb3JfZGF0YV9jbGVhbnVwXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX3JlbWFrZV9kYl9yZXRyaWVzXHUwMDNkMVx1MDAyNnl0aWRiX3Jlb3Blbl9kYl9yZXRyaWVzXHUwMDNkMFx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRcdTAwM2QwLjAyXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdF9zZXNzaW9uXHUwMDNkMC4yXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdF90cmFuc2FjdGlvblx1MDAzZDAuMSIsImNzcE5vbmNlIjoiaGFFb1loak96WUdqQngyNENYUkJ5USIsImNhbmFyeVN0YXRlIjoibm9uZSIsImVuYWJsZUNzaUxvZ2dpbmciOnRydWUsImNzaVBhZ2VUeXBlIjoid2F0Y2giLCJkYXRhc3luY0lkIjoiVmVhMzA3OWZifHwiLCJhbGxvd1dvZmZsZU1hbmFnZW1lbnQiOnRydWUsImNpbmVtYXRpY1NldHRpbmdzQXZhaWxhYmxlIjp0cnVlfSwiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfQ0hBTk5FTF9UUkFJTEVSIjp7InJvb3RFbGVtZW50SWQiOiJjNC1wbGF5ZXIiLCJqc1VybCI6Ii9zL3BsYXllci9iMTI4ZGRhMC9wbGF5ZXJfaWFzLnZmbHNldC9mcl9GUi9iYXNlLmpzIiwiY3NzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3d3dy1wbGF5ZXIuY3NzIiwiY29udGV4dElkIjoiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfQ0hBTk5FTF9UUkFJTEVSIiwiZXZlbnRMYWJlbCI6InByb2ZpbGVwYWdlIiwiY29udGVudFJlZ2lvbiI6IkZSIiwiaGwiOiJmcl9GUiIsImhvc3RMYW5ndWFnZSI6ImZyIiwicGxheWVyU3R5bGUiOiJkZXNrdG9wLXBvbHltZXIiLCJpbm5lcnR1YmVBcGlLZXkiOiJBSXphU3lBT19GSjJTbHFVOFE0U1RFSExHQ2lsd19ZOV8xMXFjVzgiLCJpbm5lcnR1YmVBcGlWZXJzaW9uIjoidjEiLCJpbm5lcnR1YmVDb250ZXh0Q2xpZW50VmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJkZXZpY2UiOnsiYnJhbmQiOiIiLCJtb2RlbCI6IiIsInBsYXRmb3JtIjoiREVTS1RPUCIsImludGVyZmFjZU5hbWUiOiJXRUIiLCJpbnRlcmZhY2VWZXJzaW9uIjoiMi4yMDIzMDYwNy4wNi4wMCJ9LCJzZXJpYWxpemVkRXhwZXJpbWVudElkcyI6IjIzODU4MDU3LDIzOTgzMjk2LDIzOTg2MDMzLDI0MDA0NjQ0LDI0MDA3MjQ2LDI0MDgwNzM4LDI0MTM1MzEwLDI0MzYyNjg1LDI0MzYyNjg4LDI0MzYzMTE0LDI0MzY0Nzg5LDI0MzY2OTE3LDI0MzcwODk4LDI0Mzc3MzQ2LDI0NDE1ODY0LDI0NDMzNjc5LDI0NDM3NTc3LDI0NDM5MzYxLDI0NDkyNTQ3LDI0NTMyODU1LDI0NTUwNDU4LDI0NTUwOTUxLDI0NTU4NjQxLDI0NTU5MzI2LDI0Njk5ODk5LDM5MzIzMDc0Iiwic2VyaWFsaXplZEV4cGVyaW1lbnRGbGFncyI6Ikg1X2FzeW5jX2xvZ2dpbmdfZGVsYXlfbXNcdTAwM2QzMDAwMC4wXHUwMDI2SDVfZW5hYmxlX2Z1bGxfcGFjZl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNkg1X3VzZV9hc3luY19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmFjdGlvbl9jb21wYW5pb25fY2VudGVyX2FsaWduX2Rlc2NyaXB0aW9uXHUwMDNkdHJ1ZVx1MDAyNmFkX3BvZF9kaXNhYmxlX2NvbXBhbmlvbl9wZXJzaXN0X2Fkc19xdWFsaXR5XHUwMDNkdHJ1ZVx1MDAyNmFkZHRvX2FqYXhfbG9nX3dhcm5pbmdfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZhbGlnbl9hZF90b192aWRlb19wbGF5ZXJfbGlmZWN5Y2xlX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X2xpdmVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2YWxsb3dfcG9sdGVyZ3VzdF9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19za2lwX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNmF1dG9wbGF5X3RpbWVcdTAwM2Q4MDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfZnVsbHNjcmVlblx1MDAzZDMwMDBcdTAwMjZhdXRvcGxheV90aW1lX2Zvcl9tdXNpY19jb250ZW50XHUwMDNkMzAwMFx1MDAyNmJnX3ZtX3JlaW5pdF90aHJlc2hvbGRcdTAwM2Q3MjAwMDAwXHUwMDI2YmxvY2tlZF9wYWNrYWdlc19mb3Jfc3BzXHUwMDNkW11cdTAwMjZib3RndWFyZF9hc3luY19zbmFwc2hvdF90aW1lb3V0X21zXHUwMDNkMzAwMFx1MDAyNmNoZWNrX2FkX3VpX3N0YXR1c19mb3JfbXdlYl9zYWZhcmlcdTAwM2R0cnVlXHUwMDI2Y2hlY2tfbmF2aWdhdG9yX2FjY3VyYWN5X3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2Y2xlYXJfdXNlcl9wYXJ0aXRpb25lZF9sc1x1MDAzZHRydWVcdTAwMjZjbGllbnRfcmVzcGVjdF9hdXRvcGxheV9zd2l0Y2hfYnV0dG9uX3JlbmRlcmVyXHUwMDNkdHJ1ZVx1MDAyNmNvbXByZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZjb21wcmVzc2lvbl9kaXNhYmxlX3BvaW50XHUwMDNkMTBcdTAwMjZjb21wcmVzc2lvbl9wZXJmb3JtYW5jZV90aHJlc2hvbGRcdTAwM2QyNTBcdTAwMjZjc2lfb25fZ2VsXHUwMDNkdHJ1ZVx1MDAyNmRhc2hfbWFuaWZlc3RfdmVyc2lvblx1MDAzZDVcdTAwMjZkZWJ1Z19iYW5kYWlkX2hvc3RuYW1lXHUwMDNkXHUwMDI2ZGVidWdfc2hlcmxvZ191c2VybmFtZVx1MDAzZFx1MDAyNmRlbGF5X2Fkc19ndmlfY2FsbF9vbl9idWxsZWl0X2xpdmluZ19yb29tX21zXHUwMDNkMFx1MDAyNmRlcHJlY2F0ZV9jc2lfaGFzX2luZm9cdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3BhaXJfc2VydmxldF9lbmFibGVkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfY2hpbGRcdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19wYXJlbnRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9pbWFnZV9jdGFfbm9fYmFja2dyb3VuZFx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX2xvZ19pbWdfY2xpY2tfbG9jYXRpb25cdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9zcGFya2xlc19saWdodF9jdGFfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfY2hhbm5lbF9pZF9jaGVja19mb3Jfc3VzcGVuZGVkX2NoYW5uZWxzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfY2hpbGRfbm9kZV9hdXRvX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfZGVmZXJfYWRtb2R1bGVfb25fYWR2ZXJ0aXNlcl92aWRlb1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2ZlYXR1cmVzX2Zvcl9zdXBleFx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2xlZ2FjeV9kZXNrdG9wX3JlbW90ZV9xdWV1ZVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX21keF9jb25uZWN0aW9uX2luX21keF9tb2R1bGVfZm9yX211c2ljX3dlYlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX25ld19wYXVzZV9zdGF0ZTNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9wYWNmX2xvZ2dpbmdfZm9yX21lbW9yeV9saW1pdGVkX3R2XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcm91bmRpbmdfYWRfbm90aWZ5XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfc2ltcGxlX21peGVkX2RpcmVjdGlvbl9mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NzZGFpX29uX2Vycm9yc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3RhYmJpbmdfYmVmb3JlX2ZseW91dF9hZF9lbGVtZW50c19hcHBlYXJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90aHVtYm5haWxfcHJlbG9hZGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZGlzYWJsZV9wcm9ncmVzc19iYXJfY29udGV4dF9tZW51X2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc19lbmFibGVfYWxsb3dfd2F0Y2hfYWdhaW5fZW5kc2NyZWVuX2Zvcl9lbGlnaWJsZV9zaG9ydHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3ZlX2NvbnZlcnNpb25fcGFyYW1fcmVuYW1pbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfYXV0b3BsYXlfbm90X3N1cHBvcnRlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9jdWVfdmlkZW9fdW5wbGF5YWJsZV9maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfaG91c2VfYnJhbmRfYW5kX3l0X2NvZXhpc3RlbmNlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvYWRfcGxheWVyX2Zyb21fcGFnZV9zaG93XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvZ19zcGxheV9hc19hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dnaW5nX2V2ZW50X2hhbmRsZXJzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX21vYmlsZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfZHR0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9uZXdfY29udGV4dF9tZW51X3RyaWdnZXJpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGF1c2Vfb3ZlcmxheV93bl91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGVtX2RvbWFpbl9maXhfZm9yX2FkX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BmcF91bmJyYW5kZWRfZWxfZGVwcmVjYXRpb25cdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcmNhdF9hbGxvd2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcmVwbGFjZV91bmxvYWRfd19wYWdlaGlkZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9zY3JpcHRlZF9wbGF5YmFja19ibG9ja2VkX2xvZ2dpbmdfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3ZlX2NvbnZlcnNpb25fbG9nZ2luZ190cmFja2luZ19ub19hbGxvd19saXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfaGlkZV91bmZpbGxlZF9tb3JlX3ZpZGVvc19zdWdnZXN0aW9uc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2xpdGVfbW9kZVx1MDAzZDFcdTAwMjZlbWJlZHNfd2ViX253bF9kaXNhYmxlX25vY29va2llXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfc2hvcHBpbmdfb3ZlcmxheV9ub193YWl0X2Zvcl9wYWlkX2NvbnRlbnRfb3ZlcmxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3N5bnRoX2NoX2hlYWRlcnNfYmFubmVkX3VybHNfcmVnZXhcdTAwM2RcdTAwMjZlbmFibGVfYWJfcnBfaW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9hZF9jcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfYXBwX3Byb21vX2VuZGNhcF9lbWxfb25fdGFibGV0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jYXN0X2Zvcl93ZWJfdW5wbHVnZ2VkXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jYXN0X29uX211c2ljX3dlYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2xpZW50X3BhZ2VfaWRfaGVhZGVyX2Zvcl9maXJzdF9wYXJ0eV9waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfY2xpZW50X3NsaV9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9kaXNjcmV0ZV9saXZlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZF93ZWJfY2xpZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZF93ZWJfY2xpZW50X2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZHNfaWNvbl93ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2V2aWN0aW9uX3Byb3RlY3Rpb25fZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2dlbF9sb2dfY29tbWFuZHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X2luc3RyZWFtX3dhdGNoX25leHRfcGFyYW1zX29hcmxpYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfaDVfdmlkZW9fYWRzX29hcmxpYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfaGFuZGxlc19hY2NvdW50X21lbnVfc3dpdGNoZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2thYnVraV9jb21tZW50c19vbl9zaG9ydHNcdTAwM2RkaXNhYmxlZFx1MDAyNmVuYWJsZV9saXZlX3ByZW1pZXJlX3dlYl9wbGF5ZXJfaW5kaWNhdG9yXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9scl9ob21lX2luZmVlZF9hZHNfaW5saW5lX3BsYXliYWNrX3Byb2dyZXNzX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX213ZWJfbGl2ZXN0cmVhbV91aV91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX25ld19wYWlkX3Byb2R1Y3RfcGxhY2VtZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Nsb3RfYXNkZV9wbGF5ZXJfYnl0ZV9oNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2X2Zvcl9wYWdlX3RvcF9mb3JtYXRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeXNmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFzc19zZGNfZ2V0X2FjY291bnRzX2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BsX3JfY1x1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9maXhfb25fdHZodG1sNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9pbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zZXJ2ZXJfc3RpdGNoZWRfZGFpXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zaG9ydHNfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwX2FkX2d1aWRhbmNlX3Byb21wdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2tpcHBhYmxlX2Fkc19mb3JfdW5wbHVnZ2VkX2FkX3BvZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfdGVjdG9uaWNfYWRfdXhfZm9yX2hhbGZ0aW1lXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90aGlyZF9wYXJ0eV9pbmZvXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90b3Bzb2lsX3d0YV9mb3JfaGFsZnRpbWVfbGl2ZV9pbmZyYVx1MDAzZHRydWVcdTAwMjZlbmFibGVfd2ViX21lZGlhX3Nlc3Npb25fbWV0YWRhdGFfZml4XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfc2NoZWR1bGVyX3NpZ25hbHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3l0X2F0YV9pZnJhbWVfYXV0aHVzZXJcdTAwM2R0cnVlXHUwMDI2ZXJyb3JfbWVzc2FnZV9mb3JfZ3N1aXRlX25ldHdvcmtfcmVzdHJpY3Rpb25zXHUwMDNkdHJ1ZVx1MDAyNmV4cG9ydF9uZXR3b3JrbGVzc19vcHRpb25zXHUwMDNkdHJ1ZVx1MDAyNmV4dGVybmFsX2Z1bGxzY3JlZW5fd2l0aF9lZHVcdTAwM2R0cnVlXHUwMDI2ZmFzdF9hdXRvbmF2X2luX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZmV0Y2hfYXR0X2luZGVwZW5kZW50bHlcdTAwM2R0cnVlXHUwMDI2ZmlsbF9zaW5nbGVfdmlkZW9fd2l0aF9ub3RpZnlfdG9fbGFzclx1MDAzZHRydWVcdTAwMjZmaWx0ZXJfdnA5X2Zvcl9jc2RhaVx1MDAzZHRydWVcdTAwMjZmaXhfYWRzX3RyYWNraW5nX2Zvcl9zd2ZfY29uZmlnX2RlcHJlY2F0aW9uX213ZWJcdTAwM2R0cnVlXHUwMDI2Z2NmX2NvbmZpZ19zdG9yZV9lbmFibGVkXHUwMDNkdHJ1ZVx1MDAyNmdlbF9xdWV1ZV90aW1lb3V0X21heF9tc1x1MDAzZDMwMDAwMFx1MDAyNmdwYV9zcGFya2xlc190ZW5fcGVyY2VudF9sYXllclx1MDAzZHRydWVcdTAwMjZndmlfY2hhbm5lbF9jbGllbnRfc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmg1X2NvbXBhbmlvbl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfZ2VuZXJpY19lcnJvcl9sb2dnaW5nX2V2ZW50XHUwMDNkdHJ1ZVx1MDAyNmg1X2VuYWJsZV91bmlmaWVkX2NzaV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmg1X2lucGxheWVyX2VuYWJsZV9hZGNwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmg1X3Jlc2V0X2NhY2hlX2FuZF9maWx0ZXJfYmVmb3JlX3VwZGF0ZV9tYXN0aGVhZFx1MDAzZHRydWVcdTAwMjZoZWF0c2Vla2VyX2RlY29yYXRpb25fdGhyZXNob2xkXHUwMDNkMC4wXHUwMDI2aGZyX2Ryb3BwZWRfZnJhbWVyYXRlX2ZhbGxiYWNrX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZoaWRlX2VuZHBvaW50X292ZXJmbG93X29uX3l0ZF9kaXNwbGF5X2FkX3JlbmRlcmVyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2FkX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfYWRzX3ByZXJvbGxfbG9ja190aW1lb3V0X2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9hbGxvd19kaXNjb250aWd1b3VzX3NsaWNlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9hbGxvd192aWRlb19rZXlmcmFtZV93aXRob3V0X2F1ZGlvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F0dGFjaF9udW1fcmFuZG9tX2J5dGVzX3RvX2JhbmRhaWRcdTAwM2QwXHUwMDI2aHRtbDVfYXR0YWNoX3BvX3Rva2VuX3RvX2JhbmRhaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYXV0b25hdl9jYXBfaWRsZV9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X2F1dG9uYXZfcXVhbGl0eV9jYXBcdTAwM2Q3MjBcdTAwMjZodG1sNV9hdXRvcGxheV9kZWZhdWx0X3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2Jsb2NrX3BpcF9zYWZhcmlfZGVsYXlcdTAwM2QwXHUwMDI2aHRtbDVfYm1mZl9uZXdfZm91cmNjX2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2NvYmFsdF9kZWZhdWx0X2J1ZmZlcl9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9tYXhfc2l6ZV9mb3JfaW1tZWRfam9iXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9taW5fcHJvY2Vzc29yX2NudF90b19vZmZsb2FkX2FsZ29cdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X292ZXJyaWRlX3F1aWNcdTAwM2QwXHUwMDI2aHRtbDVfY29uc3VtZV9tZWRpYV9ieXRlc19zbGljZV9pbmZvc1x1MDAzZHRydWVcdTAwMjZodG1sNV9kZV9kdXBlX2NvbnRlbnRfdmlkZW9fbG9hZHNfaW5fbGlmZWN5Y2xlX2FwaVx1MDAzZHRydWVcdTAwMjZodG1sNV9kZWJ1Z19kYXRhX2xvZ19wcm9iYWJpbGl0eVx1MDAzZDAuMVx1MDAyNmh0bWw1X2RlY29kZV90b190ZXh0dXJlX2NhcFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZWZhdWx0X2FkX2dhaW5cdTAwM2QwLjVcdTAwMjZodG1sNV9kZWZhdWx0X3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2RlZmVyX2FkX21vZHVsZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9mZXRjaF9hdHRfbXNcdTAwM2QxMDAwXHUwMDI2aHRtbDVfZGVmZXJfbW9kdWxlc19kZWxheV90aW1lX21pbGxpc1x1MDAzZDBcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2NvdW50XHUwMDNkMVx1MDAyNmh0bWw1X2RlbGF5ZWRfcmV0cnlfZGVsYXlfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfZGVwcmVjYXRlX3ZpZGVvX3RhZ19wb29sXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rlc2t0b3BfdnIxODBfYWxsb3dfcGFubmluZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9kZl9kb3duZ3JhZGVfdGhyZXNoXHUwMDNkMC4yXHUwMDI2aHRtbDVfZGlzYWJsZV9jc2lfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9tb3ZlX3Bzc2hfdG9fbW9vdlx1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNhYmxlX25vbl9jb250aWd1b3VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc3BsYXllZF9mcmFtZV9yYXRlX2Rvd25ncmFkZV90aHJlc2hvbGRcdTAwM2Q0NVx1MDAyNmh0bWw1X2RybV9jaGVja19hbGxfa2V5X2Vycm9yX3N0YXRlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9kcm1fY3BpX2xpY2Vuc2Vfa2V5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hYzNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2Fkc19jbGllbnRfbW9uaXRvcmluZ19sb2dfdHZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NhcHRpb25fY2hhbmdlc19mb3JfbW9zYWljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jbGllbnRfaGludHNfb3ZlcnJpZGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NvbXBvc2l0ZV9lbWJhcmdvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9lYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9lbWJlZGRlZF9wbGF5ZXJfdmlzaWJpbGl0eV9zaWduYWxzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9uZXdfaHZjX2VuY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbm9uX25vdGlmeV9jb21wb3NpdGVfdm9kX2xzYXJfcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfc2luZ2xlX3ZpZGVvX3ZvZF9pdmFyX29uX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZGFzaFx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19lbmNyeXB0ZWRfdnA5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfYWxjXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfZmFzdF9saW5lYXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5jb3VyYWdlX2FycmF5X2NvYWxlc2NpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2FwbGVzc19lbmRlZF90cmFuc2l0aW9uX2J1ZmZlcl9tc1x1MDAzZDIwMFx1MDAyNmh0bWw1X2dlbmVyYXRlX3Nlc3Npb25fcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2xfZnBzX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZodG1sNV9oZGNwX3Byb2Jpbmdfc3RyZWFtX3VybFx1MDAzZFx1MDAyNmh0bWw1X2hmcl9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QxLjBcdTAwMjZodG1sNV9pZGxlX3JhdGVfbGltaXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX2ZhaXJwbGF5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9wbGF5cmVhZHlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3dpZGV2aW5lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczRfc2Vla19hYm92ZV96ZXJvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczdfZm9yY2VfcGxheV9vbl9zdGFsbFx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3NfZm9yY2Vfc2Vla190b196ZXJvX29uX3N0b3BcdTAwM2R0cnVlXHUwMDI2aHRtbDVfanVtYm9fbW9iaWxlX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDMuMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9ub25zdHJlYW1pbmdfbWZmYV9tc1x1MDAzZDQwMDBcdTAwMjZodG1sNV9qdW1ib191bGxfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMS4zXHUwMDI2aHRtbDVfbGljZW5zZV9jb25zdHJhaW50X2RlbGF5XHUwMDNkNTAwMFx1MDAyNmh0bWw1X2xpdmVfYWJyX2hlYWRfbWlzc19mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYWJyX3JlcHJlZGljdF9mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYnl0ZXJhdGVfZmFjdG9yX2Zvcl9yZWFkYWhlYWRcdTAwM2QxLjNcdTAwMjZodG1sNV9saXZlX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9saXZlX25vcm1hbF9sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2xpdmVfdWx0cmFfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xvZ19hdWRpb19hYnJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX2V4cGVyaW1lbnRfaWRfZnJvbV9wbGF5ZXJfcmVzcG9uc2VfdG9fY3RtcFx1MDAzZFx1MDAyNmh0bWw1X2xvZ19maXJzdF9zc2RhaV9yZXF1ZXN0c19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19yZWJ1ZmZlcl9ldmVudHNcdTAwM2Q1XHUwMDI2aHRtbDVfbG9nX3NzZGFpX2ZhbGxiYWNrX2Fkc1x1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfdHJpZ2dlcl9ldmVudHNfd2l0aF9kZWJ1Z19kYXRhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX3RocmVzaG9sZF9tc1x1MDAzZDMwMDAwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3NlZ19kcmlmdF9saW1pdF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc191bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3ZwOV9vdGZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWF4X2RyaWZ0X3Blcl90cmFja19zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWF4X2hlYWRtX2Zvcl9zdHJlYW1pbmdfeGhyXHUwMDNkMFx1MDAyNmh0bWw1X21heF9saXZlX2R2cl93aW5kb3dfcGx1c19tYXJnaW5fc2Vjc1x1MDAzZDQ2ODAwLjBcdTAwMjZodG1sNV9tYXhfcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21heF9yZWRpcmVjdF9yZXNwb25zZV9sZW5ndGhcdTAwM2Q4MTkyXHUwMDI2aHRtbDVfbWF4X3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21heF9zb3VyY2VfYnVmZmVyX2FwcGVuZF9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X21heGltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9tZWRpYV9mdWxsc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21mbF9leHRlbmRfbWF4X3JlcXVlc3RfdGltZVx1MDAzZHRydWVcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9jYXBfc2Vjc1x1MDAzZDYwXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9taW5fc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfYWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbm9fcGxhY2Vob2xkZXJfcm9sbGJhY2tzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vbl9uZXR3b3JrX3JlYnVmZmVyX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X25vbl9vbmVzaWVfYXR0YWNoX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vdF9yZWdpc3Rlcl9kaXNwb3NhYmxlc193aGVuX2NvcmVfbGlzdGVuc1x1MDAzZHRydWVcdTAwMjZodG1sNV9vZmZsaW5lX2ZhaWx1cmVfcmV0cnlfbGltaXRcdTAwM2QyXHUwMDI2aHRtbDVfb25lc2llX2RlZmVyX2NvbnRlbnRfbG9hZGVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9ob3N0X3JhY2luZ19jYXBfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2lnbm9yZV9pbm5lcnR1YmVfYXBpX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbGl2ZV90dGxfc2Vjc1x1MDAzZDhcdTAwMjZodG1sNV9vbmVzaWVfbm9uemVyb19wbGF5YmFja19zdGFydFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbm90aWZ5X2N1ZXBvaW50X21hbmFnZXJfb25fY29tcGxldGlvblx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9jb29sZG93bl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9pbnRlcnZhbF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9tYXhfbGFjdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlcXVlc3RfdGltZW91dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9vbmVzaWVfc3RpY2t5X3NlcnZlcl9zaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BhdXNlX29uX25vbmZvcmVncm91bmRfcGxhdGZvcm1fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlYWtfc2hhdmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZl9jYXBfb3ZlcnJpZGVfc3RpY2t5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2NhcF9mbG9vclx1MDAzZDM2MFx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2ltcGFjdF9wcm9maWxpbmdfdGltZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcGVyc2VydmVfYXYxX3BlcmZfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX2JhY2twcmVzc3VyZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF0Zm9ybV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfcGxheWVyX2F1dG9uYXZfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfZHluYW1pY19ib3R0b21fZ3JhZGllbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxheWVyX21pbl9idWlsZF9jbFx1MDAzZC0xXHUwMDI2aHRtbDVfcGxheWVyX3ByZWxvYWRfYWRfZml4XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Bvc3RfaW50ZXJydXB0X3JlYWRhaGVhZFx1MDAzZDIwXHUwMDI2aHRtbDVfcHJlZmVyX3NlcnZlcl9id2UzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ByZWxvYWRfd2FpdF90aW1lX3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9wcm9iZV9wcmltYXJ5X2RlbGF5X2Jhc2VfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcHJvY2Vzc19hbGxfZW5jcnlwdGVkX2V2ZW50c1x1MDAzZHRydWVcdTAwMjZodG1sNV9xb2VfbGhfbWF4X3JlcG9ydF9jb3VudFx1MDAzZDBcdTAwMjZodG1sNV9xb2VfbGhfbWluX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X3F1ZXJ5X3N3X3NlY3VyZV9jcnlwdG9fZm9yX2FuZHJvaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmFuZG9tX3BsYXliYWNrX2NhcFx1MDAzZDBcdTAwMjZodG1sNV9yZWNvZ25pemVfcHJlZGljdF9zdGFydF9jdWVfcG9pbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX2NvbW1hbmRfdHJpZ2dlcmVkX2NvbXBhbmlvbnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX25vdF9zZXJ2YWJsZV9jaGVja19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbmFtZV9hcGJzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9mYXRhbF9kcm1fcmVzdHJpY3RlZF9lcnJvcl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9zbG93X2Fkc19hc19lcnJvclx1MDAzZHRydWVcdTAwMjZodG1sNV9yZXF1ZXN0X29ubHlfaGRyX29yX3Nkcl9rZXlzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfc2l6aW5nX211bHRpcGxpZXJcdTAwM2QwLjhcdTAwMjZodG1sNV9yZXNldF9tZWRpYV9zdHJlYW1fb25fdW5yZXN1bWFibGVfc2xpY2VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Jlc291cmNlX2JhZF9zdGF0dXNfZGVsYXlfc2NhbGluZ1x1MDAzZDEuNVx1MDAyNmh0bWw1X3Jlc3RyaWN0X3N0cmVhbWluZ194aHJfb25fc3FsZXNzX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NhZmFyaV9kZXNrdG9wX2VtZV9taW5fdmVyc2lvblx1MDAzZDBcdTAwMjZodG1sNV9zYW1zdW5nX2thbnRfbGltaXRfbWF4X2JpdHJhdGVcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19qaWdnbGVfY210X2RlbGF5X21zXHUwMDNkODAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fZGVsYXlfbXNcdTAwM2QxMjAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2J1ZmZlcl9yYW5nZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c192cnNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9jZmxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX3NldF9jbXRfZGVsYXlfbXNcdTAwM2QyMDAwXHUwMDI2aHRtbDVfc2Vla190aW1lb3V0X2RlbGF5X21zXHUwMDNkMjAwMDBcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2RlY29yYXRlZF91cmxfcmV0cnlfbGltaXRcdTAwM2Q1XHUwMDI2aHRtbDVfc2VydmVyX3N0aXRjaGVkX2RhaV9ncm91cFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZXNzaW9uX3BvX3Rva2VuX2ludGVydmFsX3RpbWVfbXNcdTAwM2Q5MDAwMDBcdTAwMjZodG1sNV9za2lwX29vYl9zdGFydF9zZWNvbmRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NraXBfc2xvd19hZF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfc2tpcF9zdWJfcXVhbnR1bV9kaXNjb250aW51aXR5X3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X25vX21lZGlhX3NvdXJjZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NzZGFpX2FkZmV0Y2hfZHluYW1pY190aW1lb3V0X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X3NzZGFpX2VuYWJsZV9uZXdfc2Vla19sb2dpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9zdGF0ZWZ1bF9hdWRpb19taW5fYWRqdXN0bWVudF92YWx1ZVx1MDAzZDBcdTAwMjZodG1sNV9zdGF0aWNfYWJyX3Jlc29sdXRpb25fc2hlbGZcdTAwM2QwXHUwMDI2aHRtbDVfc3RvcmVfeGhyX2hlYWRlcnNfcmVhZGFibGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3RyZWFtaW5nX3hocl9leHBhbmRfcmVxdWVzdF9zaXplXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX2xvYWRfc3BlZWRfY2hlY2tfaW50ZXJ2YWxcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzXHUwMDNkMC4yNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9idWZmZXJfaGVhbHRoX3NlY3Nfb25fdGltZW91dFx1MDAzZDAuMVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9sb2FkX3NwZWVkXHUwMDNkMS41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfc2Vla19sYXRlbmN5X2Z1ZGdlXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0X2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RpbWVvdXRfc2Vjc1x1MDAzZDIuMFx1MDAyNmh0bWw1X3VnY19saXZlX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VnY192b2RfYXVkaW9fNTFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdW5yZXBvcnRlZF9zZWVrX3Jlc2Vla19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV91bnJlc3RyaWN0ZWRfbGF5ZXJfaGlnaF9yZXNfbG9nZ2luZ19wZXJjZW50XHUwMDNkMC4wXHUwMDI2aHRtbDVfdXJsX3BhZGRpbmdfbGVuZ3RoXHUwMDNkMFx1MDAyNmh0bWw1X3VybF9zaWduYXR1cmVfZXhwaXJ5X3RpbWVfaG91cnNcdTAwM2QwXHUwMDI2aHRtbDVfdXNlX3Bvc3RfZm9yX21lZGlhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VzZV91bXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdmlkZW9fdGJkX21pbl9rYlx1MDAzZDBcdTAwMjZodG1sNV92aWV3cG9ydF91bmRlcnNlbmRfbWF4aW11bVx1MDAzZDAuMFx1MDAyNmh0bWw1X3ZvbHVtZV9zbGlkZXJfdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZodG1sNV93ZWJfZW5hYmxlX2hhbGZ0aW1lX3ByZXJvbGxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2VicG9faWRsZV9wcmlvcml0eV9qb2JcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29mZmxlX3Jlc3VtZVx1MDAzZHRydWVcdTAwMjZodG1sNV93b3JrYXJvdW5kX2RlbGF5X3RyaWdnZXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfeXR2bHJfZW5hYmxlX3NpbmdsZV9zZWxlY3Rfc3VydmV5XHUwMDNkdHJ1ZVx1MDAyNmlnbm9yZV9vdmVybGFwcGluZ19jdWVfcG9pbnRzX29uX2VuZGVtaWNfbGl2ZV9odG1sNVx1MDAzZHRydWVcdTAwMjZpbF91c2Vfdmlld19tb2RlbF9sb2dnaW5nX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2aW5pdGlhbF9nZWxfYmF0Y2hfdGltZW91dFx1MDAzZDIwMDBcdTAwMjZpbmplY3RlZF9saWNlbnNlX2hhbmRsZXJfZXJyb3JfY29kZVx1MDAzZDBcdTAwMjZpbmplY3RlZF9saWNlbnNlX2hhbmRsZXJfbGljZW5zZV9zdGF0dXNcdTAwM2QwXHUwMDI2aXRkcm1faW5qZWN0ZWRfbGljZW5zZV9zZXJ2aWNlX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aXRkcm1fd2lkZXZpbmVfaGFyZGVuZWRfdm1wX21vZGVcdTAwM2Rsb2dcdTAwMjZqc29uX2NvbmRlbnNlZF9yZXNwb25zZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfY29tbWFuZF9oYW5kbGVyX2NvbW1hbmRfYmFubGlzdFx1MDAzZFtdXHUwMDI2a2V2bGFyX2Ryb3Bkb3duX2ZpeFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfZ2VsX2Vycm9yX3JvdXRpbmdcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfZXhwYW5kX3RvcFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllcl9wbGF5X3BhdXNlX29uX3NjcmltXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9wbGF5YmFja19hc3NvY2lhdGVkX3F1ZXVlXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9xdWV1ZV91c2VfdXBkYXRlX2FwaVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc2ltcF9zaG9ydHNfcmVzZXRfc2Nyb2xsXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NtYXJ0X2Rvd25sb2Fkc19zZXR0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl92aW1pb191c2Vfc2hhcmVkX21vbml0b3JcdTAwM2R0cnVlXHUwMDI2bGl2ZV9jaHVua19yZWFkYWhlYWRcdTAwM2QzXHUwMDI2bGl2ZV9mcmVzY2FfdjJcdTAwM2R0cnVlXHUwMDI2bG9nX2Vycm9yc190aHJvdWdoX253bF9vbl9yZXRyeVx1MDAzZHRydWVcdTAwMjZsb2dfZ2VsX2NvbXByZXNzaW9uX2xhdGVuY3lcdTAwM2R0cnVlXHUwMDI2bG9nX2hlYXJ0YmVhdF93aXRoX2xpZmVjeWNsZXNcdTAwM2R0cnVlXHUwMDI2bG9nX3dlYl9lbmRwb2ludF90b19sYXllclx1MDAzZHRydWVcdTAwMjZsb2dfd2luZG93X29uZXJyb3JfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlXHUwMDNkdHJ1ZVx1MDAyNm1hbmlmZXN0bGVzc19wb3N0X2xpdmVfdWZwaFx1MDAzZHRydWVcdTAwMjZtYXhfYm9keV9zaXplX3RvX2NvbXByZXNzXHUwMDNkNTAwMDAwXHUwMDI2bWF4X3ByZWZldGNoX3dpbmRvd19zZWNfZm9yX2xpdmVzdHJlYW1fb3B0aW1pemF0aW9uXHUwMDNkMFx1MDAyNm1heF9yZXNvbHV0aW9uX2Zvcl93aGl0ZV9ub2lzZVx1MDAzZDM2MFx1MDAyNm1keF9lbmFibGVfcHJpdmFjeV9kaXNjbG9zdXJlX3VpXHUwMDNkdHJ1ZVx1MDAyNm1keF9sb2FkX2Nhc3RfYXBpX2Jvb3RzdHJhcF9zY3JpcHRcdTAwM2R0cnVlXHUwMDI2bWlncmF0ZV9ldmVudHNfdG9fdHNcdTAwM2R0cnVlXHUwMDI2bWluX3ByZWZldGNoX29mZnNldF9zZWNfZm9yX2xpdmVzdHJlYW1fb3B0aW1pemF0aW9uXHUwMDNkMTBcdTAwMjZtdXNpY19lbmFibGVfc2hhcmVkX2F1ZGlvX3RpZXJfbG9naWNcdTAwM2R0cnVlXHUwMDI2bXdlYl9jM19lbmRzY3JlZW5cdTAwM2R0cnVlXHUwMDI2bXdlYl9lbmFibGVfY3VzdG9tX2NvbnRyb2xfc2hhcmVkXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX3NraXBwYWJsZXNfb25famlvX3Bob25lXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfbXV0ZWRfYXV0b3BsYXlfYW5pbWF0aW9uXHUwMDNkc2hyaW5rXHUwMDI2bXdlYl9uYXRpdmVfY29udHJvbF9pbl9mYXV4X2Z1bGxzY3JlZW5fc2hhcmVkXHUwMDNkdHJ1ZVx1MDAyNm5ldHdvcmtfcG9sbGluZ19pbnRlcnZhbFx1MDAzZDMwMDAwXHUwMDI2bmV0d29ya2xlc3NfZ2VsXHUwMDNkdHJ1ZVx1MDAyNm5ldHdvcmtsZXNzX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2bmV3X2NvZGVjc19zdHJpbmdfYXBpX3VzZXNfbGVnYWN5X3N0eWxlXHUwMDNkdHJ1ZVx1MDAyNm53bF9zZW5kX2Zhc3Rfb25fdW5sb2FkXHUwMDNkdHJ1ZVx1MDAyNm53bF9zZW5kX2Zyb21fbWVtb3J5X3doZW5fb25saW5lXHUwMDNkdHJ1ZVx1MDAyNm9mZmxpbmVfZXJyb3JfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2cGFjZl9sb2dnaW5nX2RlbGF5X21pbGxpc2Vjb25kc190aHJvdWdoX3liZmVfdHZcdTAwM2QzMDAwMFx1MDAyNnBhZ2VpZF9hc19oZWFkZXJfd2ViXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9hZHNfc2V0X2FkZm9ybWF0X29uX2NsaWVudFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWxsb3dfYXV0b25hdl9hZnRlcl9wbGF5bGlzdFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYm9vdHN0cmFwX21ldGhvZFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZGVmZXJfY2FwdGlvbl9kaXNwbGF5XHUwMDNkMTAwMFx1MDAyNnBsYXllcl9kZXN0cm95X29sZF92ZXJzaW9uXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9kb3VibGV0YXBfdG9fc2Vla1x1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZW5hYmxlX3BsYXliYWNrX3BsYXlsaXN0X2NoYW5nZVx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZW5kc2NyZWVuX2VsbGlwc2lzX2ZpeFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfdW5kZXJsYXlfbWluX3BsYXllcl93aWR0aFx1MDAzZDc2OC4wXHUwMDI2cGxheWVyX3VuZGVybGF5X3ZpZGVvX3dpZHRoX2ZyYWN0aW9uXHUwMDNkMC42XHUwMDI2cGxheWVyX3dlYl9jYW5hcnlfc3RhZ2VcdTAwM2QwXHUwMDI2cGxheXJlYWR5X2ZpcnN0X3BsYXlfZXhwaXJhdGlvblx1MDAzZC0xXHUwMDI2cG9seW1lcl9iYWRfYnVpbGRfbGFiZWxzXHUwMDNkdHJ1ZVx1MDAyNnBvbHltZXJfbG9nX3Byb3BfY2hhbmdlX29ic2VydmVyX3BlcmNlbnRcdTAwM2QwXHUwMDI2cG9seW1lcl92ZXJpZml5X2FwcF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZwcmVza2lwX2J1dHRvbl9zdHlsZV9hZHNfYmFja2VuZFx1MDAzZGNvdW50ZG93bl9uZXh0X3RvX3RodW1ibmFpbFx1MDAyNnFvZV9ud2xfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNnFvZV9zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZyZWNvcmRfYXBwX2NyYXNoZWRfd2ViXHUwMDNkdHJ1ZVx1MDAyNnJlcGxhY2VfcGxheWFiaWxpdHlfcmV0cmlldmVyX2luX3dhdGNoXHUwMDNkdHJ1ZVx1MDAyNnNjaGVkdWxlcl91c2VfcmFmX2J5X2RlZmF1bHRcdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX2hlYWRlcl9zdHJpbmdfdGVtcGxhdGVcdTAwM2RzZWxmX3BvZGRpbmdfaW50ZXJzdGl0aWFsX21lc3NhZ2VcdTAwMjZzZWxmX3BvZGRpbmdfaGlnaGxpZ2h0X25vbl9kZWZhdWx0X2J1dHRvblx1MDAzZHRydWVcdTAwMjZzZWxmX3BvZGRpbmdfbWlkcm9sbF9jaG9pY2Vfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlXHUwMDI2c2VuZF9jb25maWdfaGFzaF90aW1lclx1MDAzZDBcdTAwMjZzZXRfaW50ZXJzdGl0aWFsX2FkdmVydGlzZXJzX3F1ZXN0aW9uX3RleHRcdTAwM2R0cnVlXHUwMDI2c2hvcnRfc3RhcnRfdGltZV9wcmVmZXJfcHVibGlzaF9pbl93YXRjaF9sb2dcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX21vZGVfdG9fcGxheWVyX2FwaVx1MDAzZHRydWVcdTAwMjZzaG9ydHNfbm9fc3RvcF92aWRlb19jYWxsXHUwMDNkdHJ1ZVx1MDAyNnNob3VsZF9jbGVhcl92aWRlb19kYXRhX29uX3BsYXllcl9jdWVkX3Vuc3RhcnRlZFx1MDAzZHRydWVcdTAwMjZzaW1wbHlfZW1iZWRkZWRfZW5hYmxlX2JvdGd1YXJkXHUwMDNkdHJ1ZVx1MDAyNnNraXBfaW5saW5lX211dGVkX2xpY2Vuc2Vfc2VydmljZV9jaGVja1x1MDAzZHRydWVcdTAwMjZza2lwX2ludmFsaWRfeXRjc2lfdGlja3NcdTAwM2R0cnVlXHUwMDI2c2tpcF9sc19nZWxfcmV0cnlcdTAwM2R0cnVlXHUwMDI2c2tpcF9zZXR0aW5nX2luZm9faW5fY3NpX2RhdGFfb2JqZWN0XHUwMDNkdHJ1ZVx1MDAyNnNsb3dfY29tcHJlc3Npb25zX2JlZm9yZV9hYmFuZG9uX2NvdW50XHUwMDNkNFx1MDAyNnNwZWVkbWFzdGVyX2NhbmNlbGxhdGlvbl9tb3ZlbWVudF9kcFx1MDAzZDBcdTAwMjZzcGVlZG1hc3Rlcl9wbGF5YmFja19yYXRlXHUwMDNkMC4wXHUwMDI2c3BlZWRtYXN0ZXJfdG91Y2hfYWN0aXZhdGlvbl9tc1x1MDAzZDBcdTAwMjZzdGFydF9jbGllbnRfZ2NmXHUwMDNkdHJ1ZVx1MDAyNnN0YXJ0X2NsaWVudF9nY2ZfZm9yX3BsYXllclx1MDAzZHRydWVcdTAwMjZzdGFydF9zZW5kaW5nX2NvbmZpZ19oYXNoXHUwMDNkdHJ1ZVx1MDAyNnN0cmVhbWluZ19kYXRhX2VtZXJnZW5jeV9pdGFnX2JsYWNrbGlzdFx1MDAzZFtdXHUwMDI2c3VwcHJlc3NfZXJyb3JfMjA0X2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2dHJhbnNwb3J0X3VzZV9zY2hlZHVsZXJcdTAwM2R0cnVlXHUwMDI2dHZfcGFjZl9sb2dnaW5nX3NhbXBsZV9yYXRlXHUwMDNkMC4wMVx1MDAyNnR2aHRtbDVfdW5wbHVnZ2VkX3ByZWxvYWRfY2FjaGVfc2l6ZVx1MDAzZDVcdTAwMjZ1bmNvdmVyX2FkX2JhZGdlX29uX1JUTF90aW55X3dpbmRvd1x1MDAzZHRydWVcdTAwMjZ1bnBsdWdnZWRfZGFpX2xpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNnVucGx1Z2dlZF90dmh0bWw1X3ZpZGVvX3ByZWxvYWRfb25fZm9jdXNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2dXBkYXRlX2xvZ19ldmVudF9jb25maWdcdTAwM2R0cnVlXHUwMDI2dXNlX2FjY2Vzc2liaWxpdHlfZGF0YV9vbl9kZXNrdG9wX3BsYXllcl9idXR0b25cdTAwM2R0cnVlXHUwMDI2dXNlX2NvcmVfc21cdTAwM2R0cnVlXHUwMDI2dXNlX2lubGluZWRfcGxheWVyX3JwY1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X2NtbFx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X2luX21lbW9yeV9zdG9yYWdlXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX2luaXRpYWxpemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3Nhd1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zdHdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfd3RzXHUwMDNkdHJ1ZVx1MDAyNnVzZV9wbGF5ZXJfYWJ1c2VfYmdfbGlicmFyeVx1MDAzZHRydWVcdTAwMjZ1c2VfcHJvZmlsZXBhZ2VfZXZlbnRfbGFiZWxfaW5fY2Fyb3VzZWxfcGxheWJhY2tzXHUwMDNkdHJ1ZVx1MDAyNnVzZV9yZXF1ZXN0X3RpbWVfbXNfaGVhZGVyXHUwMDNkdHJ1ZVx1MDAyNnVzZV9zZXNzaW9uX2Jhc2VkX3NhbXBsaW5nXHUwMDNkdHJ1ZVx1MDAyNnVzZV90c192aXNpYmlsaXR5bG9nZ2VyXHUwMDNkdHJ1ZVx1MDAyNnZhcmlhYmxlX2J1ZmZlcl90aW1lb3V0X21zXHUwMDNkMFx1MDAyNnZlcmlmeV9hZHNfaXRhZ19lYXJseVx1MDAzZHRydWVcdTAwMjZ2cDlfZHJtX2xpdmVcdTAwM2R0cnVlXHUwMDI2dnNzX2ZpbmFsX3Bpbmdfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2dnNzX3BpbmdzX3VzaW5nX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNnZzc19wbGF5YmFja191c2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2d2ViX2FwaV91cmxcdTAwM2R0cnVlXHUwMDI2d2ViX2FzeW5jX2NvbnRleHRfcHJvY2Vzc29yX2ltcGxcdTAwM2RzdGFuZGFsb25lXHUwMDI2d2ViX2NpbmVtYXRpY193YXRjaF9zZXR0aW5nc1x1MDAzZHRydWVcdTAwMjZ3ZWJfY2xpZW50X3ZlcnNpb25fb3ZlcnJpZGVcdTAwM2RcdTAwMjZ3ZWJfZGVkdXBlX3ZlX2dyYWZ0aW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9kZXByZWNhdGVfc2VydmljZV9hamF4X21hcF9kZXBlbmRlbmN5XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfZXJyb3JfMjA0XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfaW5zdHJlYW1fYWRzX2xpbmtfZGVmaW5pdGlvbl9hMTF5X2J1Z2ZpeFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX3Zvel9hdWRpb19mZWVkYmFja1x1MDAzZHRydWVcdTAwMjZ3ZWJfZml4X2ZpbmVfc2NydWJiaW5nX2RyYWdcdTAwM2R0cnVlXHUwMDI2d2ViX2ZvcmVncm91bmRfaGVhcnRiZWF0X2ludGVydmFsX21zXHUwMDNkMjgwMDBcdTAwMjZ3ZWJfZm9yd2FyZF9jb21tYW5kX29uX3Bialx1MDAzZHRydWVcdTAwMjZ3ZWJfZ2VsX2RlYm91bmNlX21zXHUwMDNkNjAwMDBcdTAwMjZ3ZWJfZ2VsX3RpbWVvdXRfY2FwXHUwMDNkdHJ1ZVx1MDAyNndlYl9pbmxpbmVfcGxheWVyX25vX3BsYXliYWNrX3VpX2NsaWNrX2hhbmRsZXJcdTAwM2R0cnVlXHUwMDI2d2ViX2tleV9tb21lbnRzX21hcmtlcnNcdTAwM2R0cnVlXHUwMDI2d2ViX2xvZ19tZW1vcnlfdG90YWxfa2J5dGVzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dnaW5nX21heF9iYXRjaFx1MDAzZDE1MFx1MDAyNndlYl9tb2Rlcm5fYWRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fYnV0dG9uc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNfYmxfc3VydmV5XHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc2NydWJiZXJcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zdWJzY3JpYmVcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zdWJzY3JpYmVfc3R5bGVcdTAwM2RmaWxsZWRcdTAwMjZ3ZWJfbmV3X2F1dG9uYXZfY291bnRkb3duXHUwMDNkdHJ1ZVx1MDAyNndlYl9vbmVfcGxhdGZvcm1fZXJyb3JfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX29wX3NpZ25hbF90eXBlX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNndlYl9wYXVzZWRfb25seV9taW5pcGxheWVyX3Nob3J0Y3V0X2V4cGFuZFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF9sb2dfY3R0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5YmFja19hc3NvY2lhdGVkX3ZlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYWRkX3ZlX2NvbnZlcnNpb25fbG9nZ2luZ190b19vdXRib3VuZF9saW5rc1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2Fsd2F5c19lbmFibGVfYXV0b190cmFuc2xhdGlvblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FwaV9sb2dnaW5nX2ZyYWN0aW9uXHUwMDNkMC4wMVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl9lbXB0eV9zdWdnZXN0aW9uc19maXhcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X3RvZ2dsZV9hbHdheXNfbGlzdGVuXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl91c2Vfc2VydmVyX3Byb3ZpZGVkX3N0YXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfY2FwdGlvbl9sYW5ndWFnZV9wcmVmZXJlbmNlX3N0aWNraW5lc3NfZHVyYXRpb25cdTAwM2QzMFx1MDAyNndlYl9wbGF5ZXJfZGVjb3VwbGVfYXV0b25hdlx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2Rpc2FibGVfaW5saW5lX3NjcnViYmluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9lYXJseV93YXJuaW5nX3NuYWNrYmFyXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX2ZlYXR1cmVkX3Byb2R1Y3RfYmFubmVyX29uX2Rlc2t0b3BcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfcHJlbWl1bV9oYnJfaW5faDVfYXBpXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX3BsYXliYWNrX2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2lubmVydHViZV9wbGF5bGlzdF91cGRhdGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pcHBfY2FuYXJ5X3R5cGVfZm9yX2xvZ2dpbmdcdTAwM2RcdTAwMjZ3ZWJfcGxheWVyX2xpdmVfbW9uaXRvcl9lbnZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9sb2dfY2xpY2tfYmVmb3JlX2dlbmVyYXRpbmdfdmVfY29udmVyc2lvbl9wYXJhbXNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9tb3ZlX2F1dG9uYXZfdG9nZ2xlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbXVzaWNfdmlzdWFsaXplcl90cmVhdG1lbnRcdTAwM2RmYWtlXHUwMDI2d2ViX3BsYXllcl9tdXRhYmxlX2V2ZW50X2xhYmVsXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbml0cmF0ZV9wcm9tb190b29sdGlwXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfb2ZmbGluZV9wbGF5bGlzdF9hdXRvX3JlZnJlc2hcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9yZXNwb25zZV9wbGF5YmFja190cmFja2luZ19wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2Vla19jaGFwdGVyc19ieV9zaG9ydGN1dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlbnRpbmVsX2lzX3VuaXBsYXllclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3VsZF9ob25vcl9pbmNsdWRlX2Fzcl9zZXR0aW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2hvd19tdXNpY19pbl90aGlzX3ZpZGVvX2dyYXBoaWNcdTAwM2R2aWRlb190aHVtYm5haWxcdTAwMjZ3ZWJfcGxheWVyX3NtYWxsX2hicF9zZXR0aW5nc19tZW51XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc3NfZGFpX2FkX2ZldGNoaW5nX3RpbWVvdXRfbXNcdTAwM2QxNTAwMFx1MDAyNndlYl9wbGF5ZXJfc3NfbWVkaWFfdGltZV9vZmZzZXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90b3BpZnlfc3VidGl0bGVzX2Zvcl9zaG9ydHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90b3VjaF9tb2RlX2ltcHJvdmVtZW50c1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RyYW5zZmVyX3RpbWVvdXRfdGhyZXNob2xkX21zXHUwMDNkMTA4MDAwMDBcdTAwMjZ3ZWJfcGxheWVyX3Vuc2V0X2RlZmF1bHRfY3NuX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl91c2VfbmV3X2FwaV9mb3JfcXVhbGl0eV9wdWxsYmFja1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3ZlX2NvbnZlcnNpb25fZml4ZXNfZm9yX2NoYW5uZWxfaW5mb1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3dhdGNoX25leHRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlX3BhcnNpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3ByZWZldGNoX3ByZWxvYWRfdmlkZW9cdTAwM2R0cnVlXHUwMDI2d2ViX3JvdW5kZWRfdGh1bWJuYWlsc1x1MDAzZHRydWVcdTAwMjZ3ZWJfc2V0dGluZ3NfbWVudV9pY29uc1x1MDAzZHRydWVcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNndlYl9zbW9vdGhuZXNzX3Rlc3RfbWV0aG9kXHUwMDNkMFx1MDAyNndlYl95dF9jb25maWdfY29udGV4dFx1MDAzZHRydWVcdTAwMjZ3aWxfaWNvbl9yZW5kZXJfd2hlbl9pZGxlXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9jbGVhbl91cF9hZnRlcl9lbnRpdHlfbWlncmF0aW9uXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9lbmFibGVfZG93bmxvYWRfc3RhdHVzXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9wbGF5bGlzdF9vcHRpbWl6YXRpb25cdTAwM2R0cnVlXHUwMDI2eXRpZGJfY2xlYXJfZW1iZWRkZWRfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2ZldGNoX2RhdGFzeW5jX2lkc19mb3JfZGF0YV9jbGVhbnVwXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX3JlbWFrZV9kYl9yZXRyaWVzXHUwMDNkMVx1MDAyNnl0aWRiX3Jlb3Blbl9kYl9yZXRyaWVzXHUwMDNkMFx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRcdTAwM2QwLjAyXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdF9zZXNzaW9uXHUwMDNkMC4yXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdF90cmFuc2FjdGlvblx1MDAzZDAuMSIsImNzcE5vbmNlIjoiaGFFb1loak96WUdqQngyNENYUkJ5USIsImNhbmFyeVN0YXRlIjoibm9uZSIsImVuYWJsZUNzaUxvZ2dpbmciOnRydWUsImNzaVBhZ2VUeXBlIjoiY2hhbm5lbHMiLCJkYXRhc3luY0lkIjoiVmVhMzA3OWZifHwifSwiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfUExBWUxJU1RfT1ZFUlZJRVciOnsicm9vdEVsZW1lbnRJZCI6ImM0LXBsYXllciIsImpzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3BsYXllcl9pYXMudmZsc2V0L2ZyX0ZSL2Jhc2UuanMiLCJjc3NVcmwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvd3d3LXBsYXllci5jc3MiLCJjb250ZXh0SWQiOiJXRUJfUExBWUVSX0NPTlRFWFRfQ09ORklHX0lEX0tFVkxBUl9QTEFZTElTVF9PVkVSVklFVyIsImV2ZW50TGFiZWwiOiJwbGF5bGlzdG92ZXJ2aWV3IiwiY29udGVudFJlZ2lvbiI6IkZSIiwiaGwiOiJmcl9GUiIsImhvc3RMYW5ndWFnZSI6ImZyIiwicGxheWVyU3R5bGUiOiJkZXNrdG9wLXBvbHltZXIiLCJpbm5lcnR1YmVBcGlLZXkiOiJBSXphU3lBT19GSjJTbHFVOFE0U1RFSExHQ2lsd19ZOV8xMXFjVzgiLCJpbm5lcnR1YmVBcGlWZXJzaW9uIjoidjEiLCJpbm5lcnR1YmVDb250ZXh0Q2xpZW50VmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJkZXZpY2UiOnsiYnJhbmQiOiIiLCJtb2RlbCI6IiIsInBsYXRmb3JtIjoiREVTS1RPUCIsImludGVyZmFjZU5hbWUiOiJXRUIiLCJpbnRlcmZhY2VWZXJzaW9uIjoiMi4yMDIzMDYwNy4wNi4wMCJ9LCJzZXJpYWxpemVkRXhwZXJpbWVudElkcyI6IjIzODU4MDU3LDIzOTgzMjk2LDIzOTg2MDMzLDI0MDA0NjQ0LDI0MDA3MjQ2LDI0MDgwNzM4LDI0MTM1MzEwLDI0MzYyNjg1LDI0MzYyNjg4LDI0MzYzMTE0LDI0MzY0Nzg5LDI0MzY2OTE3LDI0MzcwODk4LDI0Mzc3MzQ2LDI0NDE1ODY0LDI0NDMzNjc5LDI0NDM3NTc3LDI0NDM5MzYxLDI0NDkyNTQ3LDI0NTMyODU1LDI0NTUwNDU4LDI0NTUwOTUxLDI0NTU4NjQxLDI0NTU5MzI2LDI0Njk5ODk5LDM5MzIzMDc0Iiwic2VyaWFsaXplZEV4cGVyaW1lbnRGbGFncyI6Ikg1X2FzeW5jX2xvZ2dpbmdfZGVsYXlfbXNcdTAwM2QzMDAwMC4wXHUwMDI2SDVfZW5hYmxlX2Z1bGxfcGFjZl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNkg1X3VzZV9hc3luY19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmFjdGlvbl9jb21wYW5pb25fY2VudGVyX2FsaWduX2Rlc2NyaXB0aW9uXHUwMDNkdHJ1ZVx1MDAyNmFkX3BvZF9kaXNhYmxlX2NvbXBhbmlvbl9wZXJzaXN0X2Fkc19xdWFsaXR5XHUwMDNkdHJ1ZVx1MDAyNmFkZHRvX2FqYXhfbG9nX3dhcm5pbmdfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZhbGlnbl9hZF90b192aWRlb19wbGF5ZXJfbGlmZWN5Y2xlX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X2xpdmVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2YWxsb3dfcG9sdGVyZ3VzdF9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19za2lwX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNmF1dG9wbGF5X3RpbWVcdTAwM2Q4MDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfZnVsbHNjcmVlblx1MDAzZDMwMDBcdTAwMjZhdXRvcGxheV90aW1lX2Zvcl9tdXNpY19jb250ZW50XHUwMDNkMzAwMFx1MDAyNmJnX3ZtX3JlaW5pdF90aHJlc2hvbGRcdTAwM2Q3MjAwMDAwXHUwMDI2YmxvY2tlZF9wYWNrYWdlc19mb3Jfc3BzXHUwMDNkW11cdTAwMjZib3RndWFyZF9hc3luY19zbmFwc2hvdF90aW1lb3V0X21zXHUwMDNkMzAwMFx1MDAyNmNoZWNrX2FkX3VpX3N0YXR1c19mb3JfbXdlYl9zYWZhcmlcdTAwM2R0cnVlXHUwMDI2Y2hlY2tfbmF2aWdhdG9yX2FjY3VyYWN5X3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2Y2xlYXJfdXNlcl9wYXJ0aXRpb25lZF9sc1x1MDAzZHRydWVcdTAwMjZjbGllbnRfcmVzcGVjdF9hdXRvcGxheV9zd2l0Y2hfYnV0dG9uX3JlbmRlcmVyXHUwMDNkdHJ1ZVx1MDAyNmNvbXByZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZjb21wcmVzc2lvbl9kaXNhYmxlX3BvaW50XHUwMDNkMTBcdTAwMjZjb21wcmVzc2lvbl9wZXJmb3JtYW5jZV90aHJlc2hvbGRcdTAwM2QyNTBcdTAwMjZjc2lfb25fZ2VsXHUwMDNkdHJ1ZVx1MDAyNmRhc2hfbWFuaWZlc3RfdmVyc2lvblx1MDAzZDVcdTAwMjZkZWJ1Z19iYW5kYWlkX2hvc3RuYW1lXHUwMDNkXHUwMDI2ZGVidWdfc2hlcmxvZ191c2VybmFtZVx1MDAzZFx1MDAyNmRlbGF5X2Fkc19ndmlfY2FsbF9vbl9idWxsZWl0X2xpdmluZ19yb29tX21zXHUwMDNkMFx1MDAyNmRlcHJlY2F0ZV9jc2lfaGFzX2luZm9cdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3BhaXJfc2VydmxldF9lbmFibGVkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfY2hpbGRcdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19wYXJlbnRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9pbWFnZV9jdGFfbm9fYmFja2dyb3VuZFx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX2xvZ19pbWdfY2xpY2tfbG9jYXRpb25cdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9zcGFya2xlc19saWdodF9jdGFfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfY2hhbm5lbF9pZF9jaGVja19mb3Jfc3VzcGVuZGVkX2NoYW5uZWxzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfY2hpbGRfbm9kZV9hdXRvX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfZGVmZXJfYWRtb2R1bGVfb25fYWR2ZXJ0aXNlcl92aWRlb1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2ZlYXR1cmVzX2Zvcl9zdXBleFx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2xlZ2FjeV9kZXNrdG9wX3JlbW90ZV9xdWV1ZVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX21keF9jb25uZWN0aW9uX2luX21keF9tb2R1bGVfZm9yX211c2ljX3dlYlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX25ld19wYXVzZV9zdGF0ZTNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9wYWNmX2xvZ2dpbmdfZm9yX21lbW9yeV9saW1pdGVkX3R2XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcm91bmRpbmdfYWRfbm90aWZ5XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfc2ltcGxlX21peGVkX2RpcmVjdGlvbl9mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NzZGFpX29uX2Vycm9yc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3RhYmJpbmdfYmVmb3JlX2ZseW91dF9hZF9lbGVtZW50c19hcHBlYXJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90aHVtYm5haWxfcHJlbG9hZGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZGlzYWJsZV9wcm9ncmVzc19iYXJfY29udGV4dF9tZW51X2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc19lbmFibGVfYWxsb3dfd2F0Y2hfYWdhaW5fZW5kc2NyZWVuX2Zvcl9lbGlnaWJsZV9zaG9ydHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3ZlX2NvbnZlcnNpb25fcGFyYW1fcmVuYW1pbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfYXV0b3BsYXlfbm90X3N1cHBvcnRlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9jdWVfdmlkZW9fdW5wbGF5YWJsZV9maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfaG91c2VfYnJhbmRfYW5kX3l0X2NvZXhpc3RlbmNlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvYWRfcGxheWVyX2Zyb21fcGFnZV9zaG93XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvZ19zcGxheV9hc19hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dnaW5nX2V2ZW50X2hhbmRsZXJzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX21vYmlsZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfZHR0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9uZXdfY29udGV4dF9tZW51X3RyaWdnZXJpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGF1c2Vfb3ZlcmxheV93bl91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGVtX2RvbWFpbl9maXhfZm9yX2FkX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BmcF91bmJyYW5kZWRfZWxfZGVwcmVjYXRpb25cdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcmNhdF9hbGxvd2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcmVwbGFjZV91bmxvYWRfd19wYWdlaGlkZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9zY3JpcHRlZF9wbGF5YmFja19ibG9ja2VkX2xvZ2dpbmdfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3ZlX2NvbnZlcnNpb25fbG9nZ2luZ190cmFja2luZ19ub19hbGxvd19saXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfaGlkZV91bmZpbGxlZF9tb3JlX3ZpZGVvc19zdWdnZXN0aW9uc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2xpdGVfbW9kZVx1MDAzZDFcdTAwMjZlbWJlZHNfd2ViX253bF9kaXNhYmxlX25vY29va2llXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfc2hvcHBpbmdfb3ZlcmxheV9ub193YWl0X2Zvcl9wYWlkX2NvbnRlbnRfb3ZlcmxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3N5bnRoX2NoX2hlYWRlcnNfYmFubmVkX3VybHNfcmVnZXhcdTAwM2RcdTAwMjZlbmFibGVfYWJfcnBfaW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9hZF9jcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfYXBwX3Byb21vX2VuZGNhcF9lbWxfb25fdGFibGV0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jYXN0X2Zvcl93ZWJfdW5wbHVnZ2VkXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jYXN0X29uX211c2ljX3dlYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2xpZW50X3BhZ2VfaWRfaGVhZGVyX2Zvcl9maXJzdF9wYXJ0eV9waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfY2xpZW50X3NsaV9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9kaXNjcmV0ZV9saXZlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZF93ZWJfY2xpZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZF93ZWJfY2xpZW50X2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZHNfaWNvbl93ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2V2aWN0aW9uX3Byb3RlY3Rpb25fZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2dlbF9sb2dfY29tbWFuZHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X2luc3RyZWFtX3dhdGNoX25leHRfcGFyYW1zX29hcmxpYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfaDVfdmlkZW9fYWRzX29hcmxpYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfaGFuZGxlc19hY2NvdW50X21lbnVfc3dpdGNoZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2thYnVraV9jb21tZW50c19vbl9zaG9ydHNcdTAwM2RkaXNhYmxlZFx1MDAyNmVuYWJsZV9saXZlX3ByZW1pZXJlX3dlYl9wbGF5ZXJfaW5kaWNhdG9yXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9scl9ob21lX2luZmVlZF9hZHNfaW5saW5lX3BsYXliYWNrX3Byb2dyZXNzX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX213ZWJfbGl2ZXN0cmVhbV91aV91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX25ld19wYWlkX3Byb2R1Y3RfcGxhY2VtZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Nsb3RfYXNkZV9wbGF5ZXJfYnl0ZV9oNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2X2Zvcl9wYWdlX3RvcF9mb3JtYXRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeXNmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFzc19zZGNfZ2V0X2FjY291bnRzX2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BsX3JfY1x1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9maXhfb25fdHZodG1sNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9pbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zZXJ2ZXJfc3RpdGNoZWRfZGFpXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zaG9ydHNfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwX2FkX2d1aWRhbmNlX3Byb21wdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2tpcHBhYmxlX2Fkc19mb3JfdW5wbHVnZ2VkX2FkX3BvZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfdGVjdG9uaWNfYWRfdXhfZm9yX2hhbGZ0aW1lXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90aGlyZF9wYXJ0eV9pbmZvXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90b3Bzb2lsX3d0YV9mb3JfaGFsZnRpbWVfbGl2ZV9pbmZyYVx1MDAzZHRydWVcdTAwMjZlbmFibGVfd2ViX21lZGlhX3Nlc3Npb25fbWV0YWRhdGFfZml4XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfc2NoZWR1bGVyX3NpZ25hbHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3l0X2F0YV9pZnJhbWVfYXV0aHVzZXJcdTAwM2R0cnVlXHUwMDI2ZXJyb3JfbWVzc2FnZV9mb3JfZ3N1aXRlX25ldHdvcmtfcmVzdHJpY3Rpb25zXHUwMDNkdHJ1ZVx1MDAyNmV4cG9ydF9uZXR3b3JrbGVzc19vcHRpb25zXHUwMDNkdHJ1ZVx1MDAyNmV4dGVybmFsX2Z1bGxzY3JlZW5fd2l0aF9lZHVcdTAwM2R0cnVlXHUwMDI2ZmFzdF9hdXRvbmF2X2luX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZmV0Y2hfYXR0X2luZGVwZW5kZW50bHlcdTAwM2R0cnVlXHUwMDI2ZmlsbF9zaW5nbGVfdmlkZW9fd2l0aF9ub3RpZnlfdG9fbGFzclx1MDAzZHRydWVcdTAwMjZmaWx0ZXJfdnA5X2Zvcl9jc2RhaVx1MDAzZHRydWVcdTAwMjZmaXhfYWRzX3RyYWNraW5nX2Zvcl9zd2ZfY29uZmlnX2RlcHJlY2F0aW9uX213ZWJcdTAwM2R0cnVlXHUwMDI2Z2NmX2NvbmZpZ19zdG9yZV9lbmFibGVkXHUwMDNkdHJ1ZVx1MDAyNmdlbF9xdWV1ZV90aW1lb3V0X21heF9tc1x1MDAzZDMwMDAwMFx1MDAyNmdwYV9zcGFya2xlc190ZW5fcGVyY2VudF9sYXllclx1MDAzZHRydWVcdTAwMjZndmlfY2hhbm5lbF9jbGllbnRfc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmg1X2NvbXBhbmlvbl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfZ2VuZXJpY19lcnJvcl9sb2dnaW5nX2V2ZW50XHUwMDNkdHJ1ZVx1MDAyNmg1X2VuYWJsZV91bmlmaWVkX2NzaV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmg1X2lucGxheWVyX2VuYWJsZV9hZGNwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmg1X3Jlc2V0X2NhY2hlX2FuZF9maWx0ZXJfYmVmb3JlX3VwZGF0ZV9tYXN0aGVhZFx1MDAzZHRydWVcdTAwMjZoZWF0c2Vla2VyX2RlY29yYXRpb25fdGhyZXNob2xkXHUwMDNkMC4wXHUwMDI2aGZyX2Ryb3BwZWRfZnJhbWVyYXRlX2ZhbGxiYWNrX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZoaWRlX2VuZHBvaW50X292ZXJmbG93X29uX3l0ZF9kaXNwbGF5X2FkX3JlbmRlcmVyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2FkX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfYWRzX3ByZXJvbGxfbG9ja190aW1lb3V0X2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9hbGxvd19kaXNjb250aWd1b3VzX3NsaWNlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9hbGxvd192aWRlb19rZXlmcmFtZV93aXRob3V0X2F1ZGlvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F0dGFjaF9udW1fcmFuZG9tX2J5dGVzX3RvX2JhbmRhaWRcdTAwM2QwXHUwMDI2aHRtbDVfYXR0YWNoX3BvX3Rva2VuX3RvX2JhbmRhaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYXV0b25hdl9jYXBfaWRsZV9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X2F1dG9uYXZfcXVhbGl0eV9jYXBcdTAwM2Q3MjBcdTAwMjZodG1sNV9hdXRvcGxheV9kZWZhdWx0X3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2Jsb2NrX3BpcF9zYWZhcmlfZGVsYXlcdTAwM2QwXHUwMDI2aHRtbDVfYm1mZl9uZXdfZm91cmNjX2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2NvYmFsdF9kZWZhdWx0X2J1ZmZlcl9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9tYXhfc2l6ZV9mb3JfaW1tZWRfam9iXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9taW5fcHJvY2Vzc29yX2NudF90b19vZmZsb2FkX2FsZ29cdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X292ZXJyaWRlX3F1aWNcdTAwM2QwXHUwMDI2aHRtbDVfY29uc3VtZV9tZWRpYV9ieXRlc19zbGljZV9pbmZvc1x1MDAzZHRydWVcdTAwMjZodG1sNV9kZV9kdXBlX2NvbnRlbnRfdmlkZW9fbG9hZHNfaW5fbGlmZWN5Y2xlX2FwaVx1MDAzZHRydWVcdTAwMjZodG1sNV9kZWJ1Z19kYXRhX2xvZ19wcm9iYWJpbGl0eVx1MDAzZDAuMVx1MDAyNmh0bWw1X2RlY29kZV90b190ZXh0dXJlX2NhcFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZWZhdWx0X2FkX2dhaW5cdTAwM2QwLjVcdTAwMjZodG1sNV9kZWZhdWx0X3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2RlZmVyX2FkX21vZHVsZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9mZXRjaF9hdHRfbXNcdTAwM2QxMDAwXHUwMDI2aHRtbDVfZGVmZXJfbW9kdWxlc19kZWxheV90aW1lX21pbGxpc1x1MDAzZDBcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2NvdW50XHUwMDNkMVx1MDAyNmh0bWw1X2RlbGF5ZWRfcmV0cnlfZGVsYXlfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfZGVwcmVjYXRlX3ZpZGVvX3RhZ19wb29sXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rlc2t0b3BfdnIxODBfYWxsb3dfcGFubmluZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9kZl9kb3duZ3JhZGVfdGhyZXNoXHUwMDNkMC4yXHUwMDI2aHRtbDVfZGlzYWJsZV9jc2lfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9tb3ZlX3Bzc2hfdG9fbW9vdlx1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNhYmxlX25vbl9jb250aWd1b3VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc3BsYXllZF9mcmFtZV9yYXRlX2Rvd25ncmFkZV90aHJlc2hvbGRcdTAwM2Q0NVx1MDAyNmh0bWw1X2RybV9jaGVja19hbGxfa2V5X2Vycm9yX3N0YXRlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9kcm1fY3BpX2xpY2Vuc2Vfa2V5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hYzNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2Fkc19jbGllbnRfbW9uaXRvcmluZ19sb2dfdHZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NhcHRpb25fY2hhbmdlc19mb3JfbW9zYWljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jbGllbnRfaGludHNfb3ZlcnJpZGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NvbXBvc2l0ZV9lbWJhcmdvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9lYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9lbWJlZGRlZF9wbGF5ZXJfdmlzaWJpbGl0eV9zaWduYWxzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9uZXdfaHZjX2VuY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbm9uX25vdGlmeV9jb21wb3NpdGVfdm9kX2xzYXJfcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfc2luZ2xlX3ZpZGVvX3ZvZF9pdmFyX29uX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZGFzaFx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19lbmNyeXB0ZWRfdnA5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfYWxjXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfZmFzdF9saW5lYXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5jb3VyYWdlX2FycmF5X2NvYWxlc2NpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2FwbGVzc19lbmRlZF90cmFuc2l0aW9uX2J1ZmZlcl9tc1x1MDAzZDIwMFx1MDAyNmh0bWw1X2dlbmVyYXRlX3Nlc3Npb25fcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2xfZnBzX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZodG1sNV9oZGNwX3Byb2Jpbmdfc3RyZWFtX3VybFx1MDAzZFx1MDAyNmh0bWw1X2hmcl9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QxLjBcdTAwMjZodG1sNV9pZGxlX3JhdGVfbGltaXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX2ZhaXJwbGF5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9wbGF5cmVhZHlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3dpZGV2aW5lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczRfc2Vla19hYm92ZV96ZXJvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczdfZm9yY2VfcGxheV9vbl9zdGFsbFx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3NfZm9yY2Vfc2Vla190b196ZXJvX29uX3N0b3BcdTAwM2R0cnVlXHUwMDI2aHRtbDVfanVtYm9fbW9iaWxlX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDMuMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9ub25zdHJlYW1pbmdfbWZmYV9tc1x1MDAzZDQwMDBcdTAwMjZodG1sNV9qdW1ib191bGxfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMS4zXHUwMDI2aHRtbDVfbGljZW5zZV9jb25zdHJhaW50X2RlbGF5XHUwMDNkNTAwMFx1MDAyNmh0bWw1X2xpdmVfYWJyX2hlYWRfbWlzc19mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYWJyX3JlcHJlZGljdF9mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYnl0ZXJhdGVfZmFjdG9yX2Zvcl9yZWFkYWhlYWRcdTAwM2QxLjNcdTAwMjZodG1sNV9saXZlX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9saXZlX25vcm1hbF9sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2xpdmVfdWx0cmFfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xvZ19hdWRpb19hYnJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX2V4cGVyaW1lbnRfaWRfZnJvbV9wbGF5ZXJfcmVzcG9uc2VfdG9fY3RtcFx1MDAzZFx1MDAyNmh0bWw1X2xvZ19maXJzdF9zc2RhaV9yZXF1ZXN0c19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19yZWJ1ZmZlcl9ldmVudHNcdTAwM2Q1XHUwMDI2aHRtbDVfbG9nX3NzZGFpX2ZhbGxiYWNrX2Fkc1x1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfdHJpZ2dlcl9ldmVudHNfd2l0aF9kZWJ1Z19kYXRhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX3RocmVzaG9sZF9tc1x1MDAzZDMwMDAwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3NlZ19kcmlmdF9saW1pdF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc191bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3ZwOV9vdGZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWF4X2RyaWZ0X3Blcl90cmFja19zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWF4X2hlYWRtX2Zvcl9zdHJlYW1pbmdfeGhyXHUwMDNkMFx1MDAyNmh0bWw1X21heF9saXZlX2R2cl93aW5kb3dfcGx1c19tYXJnaW5fc2Vjc1x1MDAzZDQ2ODAwLjBcdTAwMjZodG1sNV9tYXhfcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21heF9yZWRpcmVjdF9yZXNwb25zZV9sZW5ndGhcdTAwM2Q4MTkyXHUwMDI2aHRtbDVfbWF4X3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21heF9zb3VyY2VfYnVmZmVyX2FwcGVuZF9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X21heGltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9tZWRpYV9mdWxsc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21mbF9leHRlbmRfbWF4X3JlcXVlc3RfdGltZVx1MDAzZHRydWVcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9jYXBfc2Vjc1x1MDAzZDYwXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9taW5fc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfYWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbm9fcGxhY2Vob2xkZXJfcm9sbGJhY2tzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vbl9uZXR3b3JrX3JlYnVmZmVyX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X25vbl9vbmVzaWVfYXR0YWNoX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vdF9yZWdpc3Rlcl9kaXNwb3NhYmxlc193aGVuX2NvcmVfbGlzdGVuc1x1MDAzZHRydWVcdTAwMjZodG1sNV9vZmZsaW5lX2ZhaWx1cmVfcmV0cnlfbGltaXRcdTAwM2QyXHUwMDI2aHRtbDVfb25lc2llX2RlZmVyX2NvbnRlbnRfbG9hZGVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9ob3N0X3JhY2luZ19jYXBfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2lnbm9yZV9pbm5lcnR1YmVfYXBpX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbGl2ZV90dGxfc2Vjc1x1MDAzZDhcdTAwMjZodG1sNV9vbmVzaWVfbm9uemVyb19wbGF5YmFja19zdGFydFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbm90aWZ5X2N1ZXBvaW50X21hbmFnZXJfb25fY29tcGxldGlvblx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9jb29sZG93bl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9pbnRlcnZhbF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9tYXhfbGFjdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlcXVlc3RfdGltZW91dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9vbmVzaWVfc3RpY2t5X3NlcnZlcl9zaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BhdXNlX29uX25vbmZvcmVncm91bmRfcGxhdGZvcm1fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlYWtfc2hhdmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZl9jYXBfb3ZlcnJpZGVfc3RpY2t5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2NhcF9mbG9vclx1MDAzZDM2MFx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2ltcGFjdF9wcm9maWxpbmdfdGltZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcGVyc2VydmVfYXYxX3BlcmZfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX2JhY2twcmVzc3VyZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF0Zm9ybV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfcGxheWVyX2F1dG9uYXZfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfZHluYW1pY19ib3R0b21fZ3JhZGllbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxheWVyX21pbl9idWlsZF9jbFx1MDAzZC0xXHUwMDI2aHRtbDVfcGxheWVyX3ByZWxvYWRfYWRfZml4XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Bvc3RfaW50ZXJydXB0X3JlYWRhaGVhZFx1MDAzZDIwXHUwMDI2aHRtbDVfcHJlZmVyX3NlcnZlcl9id2UzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ByZWxvYWRfd2FpdF90aW1lX3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9wcm9iZV9wcmltYXJ5X2RlbGF5X2Jhc2VfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcHJvY2Vzc19hbGxfZW5jcnlwdGVkX2V2ZW50c1x1MDAzZHRydWVcdTAwMjZodG1sNV9xb2VfbGhfbWF4X3JlcG9ydF9jb3VudFx1MDAzZDBcdTAwMjZodG1sNV9xb2VfbGhfbWluX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X3F1ZXJ5X3N3X3NlY3VyZV9jcnlwdG9fZm9yX2FuZHJvaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmFuZG9tX3BsYXliYWNrX2NhcFx1MDAzZDBcdTAwMjZodG1sNV9yZWNvZ25pemVfcHJlZGljdF9zdGFydF9jdWVfcG9pbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX2NvbW1hbmRfdHJpZ2dlcmVkX2NvbXBhbmlvbnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX25vdF9zZXJ2YWJsZV9jaGVja19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbmFtZV9hcGJzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9mYXRhbF9kcm1fcmVzdHJpY3RlZF9lcnJvcl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9zbG93X2Fkc19hc19lcnJvclx1MDAzZHRydWVcdTAwMjZodG1sNV9yZXF1ZXN0X29ubHlfaGRyX29yX3Nkcl9rZXlzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfc2l6aW5nX211bHRpcGxpZXJcdTAwM2QwLjhcdTAwMjZodG1sNV9yZXNldF9tZWRpYV9zdHJlYW1fb25fdW5yZXN1bWFibGVfc2xpY2VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Jlc291cmNlX2JhZF9zdGF0dXNfZGVsYXlfc2NhbGluZ1x1MDAzZDEuNVx1MDAyNmh0bWw1X3Jlc3RyaWN0X3N0cmVhbWluZ194aHJfb25fc3FsZXNzX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NhZmFyaV9kZXNrdG9wX2VtZV9taW5fdmVyc2lvblx1MDAzZDBcdTAwMjZodG1sNV9zYW1zdW5nX2thbnRfbGltaXRfbWF4X2JpdHJhdGVcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19qaWdnbGVfY210X2RlbGF5X21zXHUwMDNkODAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fZGVsYXlfbXNcdTAwM2QxMjAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2J1ZmZlcl9yYW5nZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c192cnNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9jZmxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX3NldF9jbXRfZGVsYXlfbXNcdTAwM2QyMDAwXHUwMDI2aHRtbDVfc2Vla190aW1lb3V0X2RlbGF5X21zXHUwMDNkMjAwMDBcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2RlY29yYXRlZF91cmxfcmV0cnlfbGltaXRcdTAwM2Q1XHUwMDI2aHRtbDVfc2VydmVyX3N0aXRjaGVkX2RhaV9ncm91cFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZXNzaW9uX3BvX3Rva2VuX2ludGVydmFsX3RpbWVfbXNcdTAwM2Q5MDAwMDBcdTAwMjZodG1sNV9za2lwX29vYl9zdGFydF9zZWNvbmRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NraXBfc2xvd19hZF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfc2tpcF9zdWJfcXVhbnR1bV9kaXNjb250aW51aXR5X3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X25vX21lZGlhX3NvdXJjZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NzZGFpX2FkZmV0Y2hfZHluYW1pY190aW1lb3V0X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X3NzZGFpX2VuYWJsZV9uZXdfc2Vla19sb2dpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9zdGF0ZWZ1bF9hdWRpb19taW5fYWRqdXN0bWVudF92YWx1ZVx1MDAzZDBcdTAwMjZodG1sNV9zdGF0aWNfYWJyX3Jlc29sdXRpb25fc2hlbGZcdTAwM2QwXHUwMDI2aHRtbDVfc3RvcmVfeGhyX2hlYWRlcnNfcmVhZGFibGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3RyZWFtaW5nX3hocl9leHBhbmRfcmVxdWVzdF9zaXplXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX2xvYWRfc3BlZWRfY2hlY2tfaW50ZXJ2YWxcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzXHUwMDNkMC4yNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9idWZmZXJfaGVhbHRoX3NlY3Nfb25fdGltZW91dFx1MDAzZDAuMVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9sb2FkX3NwZWVkXHUwMDNkMS41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfc2Vla19sYXRlbmN5X2Z1ZGdlXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0X2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RpbWVvdXRfc2Vjc1x1MDAzZDIuMFx1MDAyNmh0bWw1X3VnY19saXZlX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VnY192b2RfYXVkaW9fNTFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdW5yZXBvcnRlZF9zZWVrX3Jlc2Vla19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV91bnJlc3RyaWN0ZWRfbGF5ZXJfaGlnaF9yZXNfbG9nZ2luZ19wZXJjZW50XHUwMDNkMC4wXHUwMDI2aHRtbDVfdXJsX3BhZGRpbmdfbGVuZ3RoXHUwMDNkMFx1MDAyNmh0bWw1X3VybF9zaWduYXR1cmVfZXhwaXJ5X3RpbWVfaG91cnNcdTAwM2QwXHUwMDI2aHRtbDVfdXNlX3Bvc3RfZm9yX21lZGlhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VzZV91bXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdmlkZW9fdGJkX21pbl9rYlx1MDAzZDBcdTAwMjZodG1sNV92aWV3cG9ydF91bmRlcnNlbmRfbWF4aW11bVx1MDAzZDAuMFx1MDAyNmh0bWw1X3ZvbHVtZV9zbGlkZXJfdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZodG1sNV93ZWJfZW5hYmxlX2hhbGZ0aW1lX3ByZXJvbGxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2VicG9faWRsZV9wcmlvcml0eV9qb2JcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29mZmxlX3Jlc3VtZVx1MDAzZHRydWVcdTAwMjZodG1sNV93b3JrYXJvdW5kX2RlbGF5X3RyaWdnZXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfeXR2bHJfZW5hYmxlX3NpbmdsZV9zZWxlY3Rfc3VydmV5XHUwMDNkdHJ1ZVx1MDAyNmlnbm9yZV9vdmVybGFwcGluZ19jdWVfcG9pbnRzX29uX2VuZGVtaWNfbGl2ZV9odG1sNVx1MDAzZHRydWVcdTAwMjZpbF91c2Vfdmlld19tb2RlbF9sb2dnaW5nX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2aW5pdGlhbF9nZWxfYmF0Y2hfdGltZW91dFx1MDAzZDIwMDBcdTAwMjZpbmplY3RlZF9saWNlbnNlX2hhbmRsZXJfZXJyb3JfY29kZVx1MDAzZDBcdTAwMjZpbmplY3RlZF9saWNlbnNlX2hhbmRsZXJfbGljZW5zZV9zdGF0dXNcdTAwM2QwXHUwMDI2aXRkcm1faW5qZWN0ZWRfbGljZW5zZV9zZXJ2aWNlX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aXRkcm1fd2lkZXZpbmVfaGFyZGVuZWRfdm1wX21vZGVcdTAwM2Rsb2dcdTAwMjZqc29uX2NvbmRlbnNlZF9yZXNwb25zZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfY29tbWFuZF9oYW5kbGVyX2NvbW1hbmRfYmFubGlzdFx1MDAzZFtdXHUwMDI2a2V2bGFyX2Ryb3Bkb3duX2ZpeFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfZ2VsX2Vycm9yX3JvdXRpbmdcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfZXhwYW5kX3RvcFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllcl9wbGF5X3BhdXNlX29uX3NjcmltXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9wbGF5YmFja19hc3NvY2lhdGVkX3F1ZXVlXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9xdWV1ZV91c2VfdXBkYXRlX2FwaVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc2ltcF9zaG9ydHNfcmVzZXRfc2Nyb2xsXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NtYXJ0X2Rvd25sb2Fkc19zZXR0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl92aW1pb191c2Vfc2hhcmVkX21vbml0b3JcdTAwM2R0cnVlXHUwMDI2bGl2ZV9jaHVua19yZWFkYWhlYWRcdTAwM2QzXHUwMDI2bGl2ZV9mcmVzY2FfdjJcdTAwM2R0cnVlXHUwMDI2bG9nX2Vycm9yc190aHJvdWdoX253bF9vbl9yZXRyeVx1MDAzZHRydWVcdTAwMjZsb2dfZ2VsX2NvbXByZXNzaW9uX2xhdGVuY3lcdTAwM2R0cnVlXHUwMDI2bG9nX2hlYXJ0YmVhdF93aXRoX2xpZmVjeWNsZXNcdTAwM2R0cnVlXHUwMDI2bG9nX3dlYl9lbmRwb2ludF90b19sYXllclx1MDAzZHRydWVcdTAwMjZsb2dfd2luZG93X29uZXJyb3JfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlXHUwMDNkdHJ1ZVx1MDAyNm1hbmlmZXN0bGVzc19wb3N0X2xpdmVfdWZwaFx1MDAzZHRydWVcdTAwMjZtYXhfYm9keV9zaXplX3RvX2NvbXByZXNzXHUwMDNkNTAwMDAwXHUwMDI2bWF4X3ByZWZldGNoX3dpbmRvd19zZWNfZm9yX2xpdmVzdHJlYW1fb3B0aW1pemF0aW9uXHUwMDNkMFx1MDAyNm1heF9yZXNvbHV0aW9uX2Zvcl93aGl0ZV9ub2lzZVx1MDAzZDM2MFx1MDAyNm1keF9lbmFibGVfcHJpdmFjeV9kaXNjbG9zdXJlX3VpXHUwMDNkdHJ1ZVx1MDAyNm1keF9sb2FkX2Nhc3RfYXBpX2Jvb3RzdHJhcF9zY3JpcHRcdTAwM2R0cnVlXHUwMDI2bWlncmF0ZV9ldmVudHNfdG9fdHNcdTAwM2R0cnVlXHUwMDI2bWluX3ByZWZldGNoX29mZnNldF9zZWNfZm9yX2xpdmVzdHJlYW1fb3B0aW1pemF0aW9uXHUwMDNkMTBcdTAwMjZtdXNpY19lbmFibGVfc2hhcmVkX2F1ZGlvX3RpZXJfbG9naWNcdTAwM2R0cnVlXHUwMDI2bXdlYl9jM19lbmRzY3JlZW5cdTAwM2R0cnVlXHUwMDI2bXdlYl9lbmFibGVfY3VzdG9tX2NvbnRyb2xfc2hhcmVkXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX3NraXBwYWJsZXNfb25famlvX3Bob25lXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfbXV0ZWRfYXV0b3BsYXlfYW5pbWF0aW9uXHUwMDNkc2hyaW5rXHUwMDI2bXdlYl9uYXRpdmVfY29udHJvbF9pbl9mYXV4X2Z1bGxzY3JlZW5fc2hhcmVkXHUwMDNkdHJ1ZVx1MDAyNm5ldHdvcmtfcG9sbGluZ19pbnRlcnZhbFx1MDAzZDMwMDAwXHUwMDI2bmV0d29ya2xlc3NfZ2VsXHUwMDNkdHJ1ZVx1MDAyNm5ldHdvcmtsZXNzX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2bmV3X2NvZGVjc19zdHJpbmdfYXBpX3VzZXNfbGVnYWN5X3N0eWxlXHUwMDNkdHJ1ZVx1MDAyNm53bF9zZW5kX2Zhc3Rfb25fdW5sb2FkXHUwMDNkdHJ1ZVx1MDAyNm53bF9zZW5kX2Zyb21fbWVtb3J5X3doZW5fb25saW5lXHUwMDNkdHJ1ZVx1MDAyNm9mZmxpbmVfZXJyb3JfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2cGFjZl9sb2dnaW5nX2RlbGF5X21pbGxpc2Vjb25kc190aHJvdWdoX3liZmVfdHZcdTAwM2QzMDAwMFx1MDAyNnBhZ2VpZF9hc19oZWFkZXJfd2ViXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9hZHNfc2V0X2FkZm9ybWF0X29uX2NsaWVudFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWxsb3dfYXV0b25hdl9hZnRlcl9wbGF5bGlzdFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYm9vdHN0cmFwX21ldGhvZFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZGVmZXJfY2FwdGlvbl9kaXNwbGF5XHUwMDNkMTAwMFx1MDAyNnBsYXllcl9kZXN0cm95X29sZF92ZXJzaW9uXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9kb3VibGV0YXBfdG9fc2Vla1x1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZW5hYmxlX3BsYXliYWNrX3BsYXlsaXN0X2NoYW5nZVx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZW5kc2NyZWVuX2VsbGlwc2lzX2ZpeFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfdW5kZXJsYXlfbWluX3BsYXllcl93aWR0aFx1MDAzZDc2OC4wXHUwMDI2cGxheWVyX3VuZGVybGF5X3ZpZGVvX3dpZHRoX2ZyYWN0aW9uXHUwMDNkMC42XHUwMDI2cGxheWVyX3dlYl9jYW5hcnlfc3RhZ2VcdTAwM2QwXHUwMDI2cGxheXJlYWR5X2ZpcnN0X3BsYXlfZXhwaXJhdGlvblx1MDAzZC0xXHUwMDI2cG9seW1lcl9iYWRfYnVpbGRfbGFiZWxzXHUwMDNkdHJ1ZVx1MDAyNnBvbHltZXJfbG9nX3Byb3BfY2hhbmdlX29ic2VydmVyX3BlcmNlbnRcdTAwM2QwXHUwMDI2cG9seW1lcl92ZXJpZml5X2FwcF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZwcmVza2lwX2J1dHRvbl9zdHlsZV9hZHNfYmFja2VuZFx1MDAzZGNvdW50ZG93bl9uZXh0X3RvX3RodW1ibmFpbFx1MDAyNnFvZV9ud2xfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNnFvZV9zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZyZWNvcmRfYXBwX2NyYXNoZWRfd2ViXHUwMDNkdHJ1ZVx1MDAyNnJlcGxhY2VfcGxheWFiaWxpdHlfcmV0cmlldmVyX2luX3dhdGNoXHUwMDNkdHJ1ZVx1MDAyNnNjaGVkdWxlcl91c2VfcmFmX2J5X2RlZmF1bHRcdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX2hlYWRlcl9zdHJpbmdfdGVtcGxhdGVcdTAwM2RzZWxmX3BvZGRpbmdfaW50ZXJzdGl0aWFsX21lc3NhZ2VcdTAwMjZzZWxmX3BvZGRpbmdfaGlnaGxpZ2h0X25vbl9kZWZhdWx0X2J1dHRvblx1MDAzZHRydWVcdTAwMjZzZWxmX3BvZGRpbmdfbWlkcm9sbF9jaG9pY2Vfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlXHUwMDI2c2VuZF9jb25maWdfaGFzaF90aW1lclx1MDAzZDBcdTAwMjZzZXRfaW50ZXJzdGl0aWFsX2FkdmVydGlzZXJzX3F1ZXN0aW9uX3RleHRcdTAwM2R0cnVlXHUwMDI2c2hvcnRfc3RhcnRfdGltZV9wcmVmZXJfcHVibGlzaF9pbl93YXRjaF9sb2dcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX21vZGVfdG9fcGxheWVyX2FwaVx1MDAzZHRydWVcdTAwMjZzaG9ydHNfbm9fc3RvcF92aWRlb19jYWxsXHUwMDNkdHJ1ZVx1MDAyNnNob3VsZF9jbGVhcl92aWRlb19kYXRhX29uX3BsYXllcl9jdWVkX3Vuc3RhcnRlZFx1MDAzZHRydWVcdTAwMjZzaW1wbHlfZW1iZWRkZWRfZW5hYmxlX2JvdGd1YXJkXHUwMDNkdHJ1ZVx1MDAyNnNraXBfaW5saW5lX211dGVkX2xpY2Vuc2Vfc2VydmljZV9jaGVja1x1MDAzZHRydWVcdTAwMjZza2lwX2ludmFsaWRfeXRjc2lfdGlja3NcdTAwM2R0cnVlXHUwMDI2c2tpcF9sc19nZWxfcmV0cnlcdTAwM2R0cnVlXHUwMDI2c2tpcF9zZXR0aW5nX2luZm9faW5fY3NpX2RhdGFfb2JqZWN0XHUwMDNkdHJ1ZVx1MDAyNnNsb3dfY29tcHJlc3Npb25zX2JlZm9yZV9hYmFuZG9uX2NvdW50XHUwMDNkNFx1MDAyNnNwZWVkbWFzdGVyX2NhbmNlbGxhdGlvbl9tb3ZlbWVudF9kcFx1MDAzZDBcdTAwMjZzcGVlZG1hc3Rlcl9wbGF5YmFja19yYXRlXHUwMDNkMC4wXHUwMDI2c3BlZWRtYXN0ZXJfdG91Y2hfYWN0aXZhdGlvbl9tc1x1MDAzZDBcdTAwMjZzdGFydF9jbGllbnRfZ2NmXHUwMDNkdHJ1ZVx1MDAyNnN0YXJ0X2NsaWVudF9nY2ZfZm9yX3BsYXllclx1MDAzZHRydWVcdTAwMjZzdGFydF9zZW5kaW5nX2NvbmZpZ19oYXNoXHUwMDNkdHJ1ZVx1MDAyNnN0cmVhbWluZ19kYXRhX2VtZXJnZW5jeV9pdGFnX2JsYWNrbGlzdFx1MDAzZFtdXHUwMDI2c3VwcHJlc3NfZXJyb3JfMjA0X2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2dHJhbnNwb3J0X3VzZV9zY2hlZHVsZXJcdTAwM2R0cnVlXHUwMDI2dHZfcGFjZl9sb2dnaW5nX3NhbXBsZV9yYXRlXHUwMDNkMC4wMVx1MDAyNnR2aHRtbDVfdW5wbHVnZ2VkX3ByZWxvYWRfY2FjaGVfc2l6ZVx1MDAzZDVcdTAwMjZ1bmNvdmVyX2FkX2JhZGdlX29uX1JUTF90aW55X3dpbmRvd1x1MDAzZHRydWVcdTAwMjZ1bnBsdWdnZWRfZGFpX2xpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNnVucGx1Z2dlZF90dmh0bWw1X3ZpZGVvX3ByZWxvYWRfb25fZm9jdXNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2dXBkYXRlX2xvZ19ldmVudF9jb25maWdcdTAwM2R0cnVlXHUwMDI2dXNlX2FjY2Vzc2liaWxpdHlfZGF0YV9vbl9kZXNrdG9wX3BsYXllcl9idXR0b25cdTAwM2R0cnVlXHUwMDI2dXNlX2NvcmVfc21cdTAwM2R0cnVlXHUwMDI2dXNlX2lubGluZWRfcGxheWVyX3JwY1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X2NtbFx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X2luX21lbW9yeV9zdG9yYWdlXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX2luaXRpYWxpemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3Nhd1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zdHdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfd3RzXHUwMDNkdHJ1ZVx1MDAyNnVzZV9wbGF5ZXJfYWJ1c2VfYmdfbGlicmFyeVx1MDAzZHRydWVcdTAwMjZ1c2VfcHJvZmlsZXBhZ2VfZXZlbnRfbGFiZWxfaW5fY2Fyb3VzZWxfcGxheWJhY2tzXHUwMDNkdHJ1ZVx1MDAyNnVzZV9yZXF1ZXN0X3RpbWVfbXNfaGVhZGVyXHUwMDNkdHJ1ZVx1MDAyNnVzZV9zZXNzaW9uX2Jhc2VkX3NhbXBsaW5nXHUwMDNkdHJ1ZVx1MDAyNnVzZV90c192aXNpYmlsaXR5bG9nZ2VyXHUwMDNkdHJ1ZVx1MDAyNnZhcmlhYmxlX2J1ZmZlcl90aW1lb3V0X21zXHUwMDNkMFx1MDAyNnZlcmlmeV9hZHNfaXRhZ19lYXJseVx1MDAzZHRydWVcdTAwMjZ2cDlfZHJtX2xpdmVcdTAwM2R0cnVlXHUwMDI2dnNzX2ZpbmFsX3Bpbmdfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2dnNzX3BpbmdzX3VzaW5nX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNnZzc19wbGF5YmFja191c2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2d2ViX2FwaV91cmxcdTAwM2R0cnVlXHUwMDI2d2ViX2FzeW5jX2NvbnRleHRfcHJvY2Vzc29yX2ltcGxcdTAwM2RzdGFuZGFsb25lXHUwMDI2d2ViX2NpbmVtYXRpY193YXRjaF9zZXR0aW5nc1x1MDAzZHRydWVcdTAwMjZ3ZWJfY2xpZW50X3ZlcnNpb25fb3ZlcnJpZGVcdTAwM2RcdTAwMjZ3ZWJfZGVkdXBlX3ZlX2dyYWZ0aW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9kZXByZWNhdGVfc2VydmljZV9hamF4X21hcF9kZXBlbmRlbmN5XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfZXJyb3JfMjA0XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfaW5zdHJlYW1fYWRzX2xpbmtfZGVmaW5pdGlvbl9hMTF5X2J1Z2ZpeFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX3Zvel9hdWRpb19mZWVkYmFja1x1MDAzZHRydWVcdTAwMjZ3ZWJfZml4X2ZpbmVfc2NydWJiaW5nX2RyYWdcdTAwM2R0cnVlXHUwMDI2d2ViX2ZvcmVncm91bmRfaGVhcnRiZWF0X2ludGVydmFsX21zXHUwMDNkMjgwMDBcdTAwMjZ3ZWJfZm9yd2FyZF9jb21tYW5kX29uX3Bialx1MDAzZHRydWVcdTAwMjZ3ZWJfZ2VsX2RlYm91bmNlX21zXHUwMDNkNjAwMDBcdTAwMjZ3ZWJfZ2VsX3RpbWVvdXRfY2FwXHUwMDNkdHJ1ZVx1MDAyNndlYl9pbmxpbmVfcGxheWVyX25vX3BsYXliYWNrX3VpX2NsaWNrX2hhbmRsZXJcdTAwM2R0cnVlXHUwMDI2d2ViX2tleV9tb21lbnRzX21hcmtlcnNcdTAwM2R0cnVlXHUwMDI2d2ViX2xvZ19tZW1vcnlfdG90YWxfa2J5dGVzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dnaW5nX21heF9iYXRjaFx1MDAzZDE1MFx1MDAyNndlYl9tb2Rlcm5fYWRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fYnV0dG9uc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNfYmxfc3VydmV5XHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc2NydWJiZXJcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zdWJzY3JpYmVcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zdWJzY3JpYmVfc3R5bGVcdTAwM2RmaWxsZWRcdTAwMjZ3ZWJfbmV3X2F1dG9uYXZfY291bnRkb3duXHUwMDNkdHJ1ZVx1MDAyNndlYl9vbmVfcGxhdGZvcm1fZXJyb3JfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX29wX3NpZ25hbF90eXBlX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNndlYl9wYXVzZWRfb25seV9taW5pcGxheWVyX3Nob3J0Y3V0X2V4cGFuZFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF9sb2dfY3R0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5YmFja19hc3NvY2lhdGVkX3ZlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYWRkX3ZlX2NvbnZlcnNpb25fbG9nZ2luZ190b19vdXRib3VuZF9saW5rc1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2Fsd2F5c19lbmFibGVfYXV0b190cmFuc2xhdGlvblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FwaV9sb2dnaW5nX2ZyYWN0aW9uXHUwMDNkMC4wMVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl9lbXB0eV9zdWdnZXN0aW9uc19maXhcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X3RvZ2dsZV9hbHdheXNfbGlzdGVuXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl91c2Vfc2VydmVyX3Byb3ZpZGVkX3N0YXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfY2FwdGlvbl9sYW5ndWFnZV9wcmVmZXJlbmNlX3N0aWNraW5lc3NfZHVyYXRpb25cdTAwM2QzMFx1MDAyNndlYl9wbGF5ZXJfZGVjb3VwbGVfYXV0b25hdlx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2Rpc2FibGVfaW5saW5lX3NjcnViYmluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9lYXJseV93YXJuaW5nX3NuYWNrYmFyXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX2ZlYXR1cmVkX3Byb2R1Y3RfYmFubmVyX29uX2Rlc2t0b3BcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfcHJlbWl1bV9oYnJfaW5faDVfYXBpXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX3BsYXliYWNrX2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2lubmVydHViZV9wbGF5bGlzdF91cGRhdGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pcHBfY2FuYXJ5X3R5cGVfZm9yX2xvZ2dpbmdcdTAwM2RcdTAwMjZ3ZWJfcGxheWVyX2xpdmVfbW9uaXRvcl9lbnZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9sb2dfY2xpY2tfYmVmb3JlX2dlbmVyYXRpbmdfdmVfY29udmVyc2lvbl9wYXJhbXNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9tb3ZlX2F1dG9uYXZfdG9nZ2xlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbXVzaWNfdmlzdWFsaXplcl90cmVhdG1lbnRcdTAwM2RmYWtlXHUwMDI2d2ViX3BsYXllcl9tdXRhYmxlX2V2ZW50X2xhYmVsXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbml0cmF0ZV9wcm9tb190b29sdGlwXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfb2ZmbGluZV9wbGF5bGlzdF9hdXRvX3JlZnJlc2hcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9yZXNwb25zZV9wbGF5YmFja190cmFja2luZ19wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2Vla19jaGFwdGVyc19ieV9zaG9ydGN1dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlbnRpbmVsX2lzX3VuaXBsYXllclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3VsZF9ob25vcl9pbmNsdWRlX2Fzcl9zZXR0aW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2hvd19tdXNpY19pbl90aGlzX3ZpZGVvX2dyYXBoaWNcdTAwM2R2aWRlb190aHVtYm5haWxcdTAwMjZ3ZWJfcGxheWVyX3NtYWxsX2hicF9zZXR0aW5nc19tZW51XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc3NfZGFpX2FkX2ZldGNoaW5nX3RpbWVvdXRfbXNcdTAwM2QxNTAwMFx1MDAyNndlYl9wbGF5ZXJfc3NfbWVkaWFfdGltZV9vZmZzZXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90b3BpZnlfc3VidGl0bGVzX2Zvcl9zaG9ydHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90b3VjaF9tb2RlX2ltcHJvdmVtZW50c1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RyYW5zZmVyX3RpbWVvdXRfdGhyZXNob2xkX21zXHUwMDNkMTA4MDAwMDBcdTAwMjZ3ZWJfcGxheWVyX3Vuc2V0X2RlZmF1bHRfY3NuX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl91c2VfbmV3X2FwaV9mb3JfcXVhbGl0eV9wdWxsYmFja1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3ZlX2NvbnZlcnNpb25fZml4ZXNfZm9yX2NoYW5uZWxfaW5mb1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3dhdGNoX25leHRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlX3BhcnNpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3ByZWZldGNoX3ByZWxvYWRfdmlkZW9cdTAwM2R0cnVlXHUwMDI2d2ViX3JvdW5kZWRfdGh1bWJuYWlsc1x1MDAzZHRydWVcdTAwMjZ3ZWJfc2V0dGluZ3NfbWVudV9pY29uc1x1MDAzZHRydWVcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNndlYl9zbW9vdGhuZXNzX3Rlc3RfbWV0aG9kXHUwMDNkMFx1MDAyNndlYl95dF9jb25maWdfY29udGV4dFx1MDAzZHRydWVcdTAwMjZ3aWxfaWNvbl9yZW5kZXJfd2hlbl9pZGxlXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9jbGVhbl91cF9hZnRlcl9lbnRpdHlfbWlncmF0aW9uXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9lbmFibGVfZG93bmxvYWRfc3RhdHVzXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9wbGF5bGlzdF9vcHRpbWl6YXRpb25cdTAwM2R0cnVlXHUwMDI2eXRpZGJfY2xlYXJfZW1iZWRkZWRfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2ZldGNoX2RhdGFzeW5jX2lkc19mb3JfZGF0YV9jbGVhbnVwXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX3JlbWFrZV9kYl9yZXRyaWVzXHUwMDNkMVx1MDAyNnl0aWRiX3Jlb3Blbl9kYl9yZXRyaWVzXHUwMDNkMFx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRcdTAwM2QwLjAyXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdF9zZXNzaW9uXHUwMDNkMC4yXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdF90cmFuc2FjdGlvblx1MDAzZDAuMSIsImRpc2FibGVTaGFyaW5nIjp0cnVlLCJoaWRlSW5mbyI6dHJ1ZSwiZGlzYWJsZVdhdGNoTGF0ZXIiOnRydWUsImNzcE5vbmNlIjoiaGFFb1loak96WUdqQngyNENYUkJ5USIsImNhbmFyeVN0YXRlIjoibm9uZSIsImVuYWJsZUNzaUxvZ2dpbmciOnRydWUsImNzaVBhZ2VUeXBlIjoicGxheWxpc3Rfb3ZlcnZpZXciLCJkYXRhc3luY0lkIjoiVmVhMzA3OWZifHwifSwiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfVkVSVElDQUxfTEFORElOR19QQUdFX1BST01PIjp7InJvb3RFbGVtZW50SWQiOiJ5dGQtZGVmYXVsdC1wcm9tby1wYW5lbC1yZW5kZXJlci1pbmxpbmUtcGxheWJhY2stcmVuZGVyZXIiLCJqc1VybCI6Ii9zL3BsYXllci9iMTI4ZGRhMC9wbGF5ZXJfaWFzLnZmbHNldC9mcl9GUi9iYXNlLmpzIiwiY3NzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3d3dy1wbGF5ZXIuY3NzIiwiY29udGV4dElkIjoiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfVkVSVElDQUxfTEFORElOR19QQUdFX1BST01PIiwiZXZlbnRMYWJlbCI6InByb2ZpbGVwYWdlIiwiY29udGVudFJlZ2lvbiI6IkZSIiwiaGwiOiJmcl9GUiIsImhvc3RMYW5ndWFnZSI6ImZyIiwicGxheWVyU3R5bGUiOiJkZXNrdG9wLXBvbHltZXIiLCJpbm5lcnR1YmVBcGlLZXkiOiJBSXphU3lBT19GSjJTbHFVOFE0U1RFSExHQ2lsd19ZOV8xMXFjVzgiLCJpbm5lcnR1YmVBcGlWZXJzaW9uIjoidjEiLCJpbm5lcnR1YmVDb250ZXh0Q2xpZW50VmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJjb250cm9sc1R5cGUiOjAsImRpc2FibGVSZWxhdGVkVmlkZW9zIjp0cnVlLCJhbm5vdGF0aW9uc0xvYWRQb2xpY3kiOjMsImRldmljZSI6eyJicmFuZCI6IiIsIm1vZGVsIjoiIiwicGxhdGZvcm0iOiJERVNLVE9QIiwiaW50ZXJmYWNlTmFtZSI6IldFQiIsImludGVyZmFjZVZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIn0sInNlcmlhbGl6ZWRFeHBlcmltZW50SWRzIjoiMjM4NTgwNTcsMjM5ODMyOTYsMjM5ODYwMzMsMjQwMDQ2NDQsMjQwMDcyNDYsMjQwODA3MzgsMjQxMzUzMTAsMjQzNjI2ODUsMjQzNjI2ODgsMjQzNjMxMTQsMjQzNjQ3ODksMjQzNjY5MTcsMjQzNzA4OTgsMjQzNzczNDYsMjQ0MTU4NjQsMjQ0MzM2NzksMjQ0Mzc1NzcsMjQ0MzkzNjEsMjQ0OTI1NDcsMjQ1MzI4NTUsMjQ1NTA0NTgsMjQ1NTA5NTEsMjQ1NTg2NDEsMjQ1NTkzMjYsMjQ2OTk4OTksMzkzMjMwNzQiLCJzZXJpYWxpemVkRXhwZXJpbWVudEZsYWdzIjoiSDVfYXN5bmNfbG9nZ2luZ19kZWxheV9tc1x1MDAzZDMwMDAwLjBcdTAwMjZINV9lbmFibGVfZnVsbF9wYWNmX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2SDVfdXNlX2FzeW5jX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2YWN0aW9uX2NvbXBhbmlvbl9jZW50ZXJfYWxpZ25fZGVzY3JpcHRpb25cdTAwM2R0cnVlXHUwMDI2YWRfcG9kX2Rpc2FibGVfY29tcGFuaW9uX3BlcnNpc3RfYWRzX3F1YWxpdHlcdTAwM2R0cnVlXHUwMDI2YWRkdG9fYWpheF9sb2dfd2FybmluZ19mcmFjdGlvblx1MDAzZDAuMVx1MDAyNmFsaWduX2FkX3RvX3ZpZGVvX3BsYXllcl9saWZlY3ljbGVfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2YWxsb3dfbGl2ZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19wb2x0ZXJndXN0X2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X3NraXBfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2YXV0b3BsYXlfdGltZVx1MDAzZDgwMDBcdTAwMjZhdXRvcGxheV90aW1lX2Zvcl9mdWxsc2NyZWVuXHUwMDNkMzAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX211c2ljX2NvbnRlbnRcdTAwM2QzMDAwXHUwMDI2Ymdfdm1fcmVpbml0X3RocmVzaG9sZFx1MDAzZDcyMDAwMDBcdTAwMjZibG9ja2VkX3BhY2thZ2VzX2Zvcl9zcHNcdTAwM2RbXVx1MDAyNmJvdGd1YXJkX2FzeW5jX3NuYXBzaG90X3RpbWVvdXRfbXNcdTAwM2QzMDAwXHUwMDI2Y2hlY2tfYWRfdWlfc3RhdHVzX2Zvcl9td2ViX3NhZmFyaVx1MDAzZHRydWVcdTAwMjZjaGVja19uYXZpZ2F0b3JfYWNjdXJhY3lfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZjbGVhcl91c2VyX3BhcnRpdGlvbmVkX2xzXHUwMDNkdHJ1ZVx1MDAyNmNsaWVudF9yZXNwZWN0X2F1dG9wbGF5X3N3aXRjaF9idXR0b25fcmVuZGVyZXJcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3NfZ2VsXHUwMDNkdHJ1ZVx1MDAyNmNvbXByZXNzaW9uX2Rpc2FibGVfcG9pbnRcdTAwM2QxMFx1MDAyNmNvbXByZXNzaW9uX3BlcmZvcm1hbmNlX3RocmVzaG9sZFx1MDAzZDI1MFx1MDAyNmNzaV9vbl9nZWxcdTAwM2R0cnVlXHUwMDI2ZGFzaF9tYW5pZmVzdF92ZXJzaW9uXHUwMDNkNVx1MDAyNmRlYnVnX2JhbmRhaWRfaG9zdG5hbWVcdTAwM2RcdTAwMjZkZWJ1Z19zaGVybG9nX3VzZXJuYW1lXHUwMDNkXHUwMDI2ZGVsYXlfYWRzX2d2aV9jYWxsX29uX2J1bGxlaXRfbGl2aW5nX3Jvb21fbXNcdTAwM2QwXHUwMDI2ZGVwcmVjYXRlX2NzaV9oYXNfaW5mb1x1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfcGFpcl9zZXJ2bGV0X2VuYWJsZWRcdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19jaGlsZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX3BhcmVudFx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX2ltYWdlX2N0YV9ub19iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfbG9nX2ltZ19jbGlja19sb2NhdGlvblx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX3NwYXJrbGVzX2xpZ2h0X2N0YV9idXR0b25cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9jaGFubmVsX2lkX2NoZWNrX2Zvcl9zdXNwZW5kZWRfY2hhbm5lbHNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9jaGlsZF9ub2RlX2F1dG9fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9kZWZlcl9hZG1vZHVsZV9vbl9hZHZlcnRpc2VyX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfZmVhdHVyZXNfZm9yX3N1cGV4XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbGVnYWN5X2Rlc2t0b3BfcmVtb3RlX3F1ZXVlXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbWR4X2Nvbm5lY3Rpb25faW5fbWR4X21vZHVsZV9mb3JfbXVzaWNfd2ViXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbmV3X3BhdXNlX3N0YXRlM1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3BhY2ZfbG9nZ2luZ19mb3JfbWVtb3J5X2xpbWl0ZWRfdHZcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9yb3VuZGluZ19hZF9ub3RpZnlcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zaW1wbGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfc3NkYWlfb25fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGFiYmluZ19iZWZvcmVfZmx5b3V0X2FkX2VsZW1lbnRzX2FwcGVhclx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3RodW1ibmFpbF9wcmVsb2FkaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc19kaXNhYmxlX3Byb2dyZXNzX2Jhcl9jb250ZXh0X21lbnVfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2VuYWJsZV9hbGxvd193YXRjaF9hZ2Fpbl9lbmRzY3JlZW5fZm9yX2VsaWdpYmxlX3Nob3J0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfdmVfY29udmVyc2lvbl9wYXJhbV9yZW5hbWluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9hdXRvcGxheV9ub3Rfc3VwcG9ydGVkX2xvZ2dpbmdfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2N1ZV92aWRlb191bnBsYXlhYmxlX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9ob3VzZV9icmFuZF9hbmRfeXRfY29leGlzdGVuY2VcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9hZF9wbGF5ZXJfZnJvbV9wYWdlX3Nob3dcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nX3NwbGF5X2FzX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvZ2dpbmdfZXZlbnRfaGFuZGxlcnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX21vYmlsZV9kdHRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX25ld19jb250ZXh0X21lbnVfdHJpZ2dlcmluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wYXVzZV9vdmVybGF5X3duX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZW1fZG9tYWluX2ZpeF9mb3JfYWRfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGZwX3VuYnJhbmRlZF9lbF9kZXByZWNhdGlvblx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9yY2F0X2FsbG93bGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9yZXBsYWNlX3VubG9hZF93X3BhZ2VoaWRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3NjcmlwdGVkX3BsYXliYWNrX2Jsb2NrZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfdmVfY29udmVyc2lvbl9sb2dnaW5nX3RyYWNraW5nX25vX2FsbG93X2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9oaWRlX3VuZmlsbGVkX21vcmVfdmlkZW9zX3N1Z2dlc3Rpb25zXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfbGl0ZV9tb2RlXHUwMDNkMVx1MDAyNmVtYmVkc193ZWJfbndsX2Rpc2FibGVfbm9jb29raWVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zaG9wcGluZ19vdmVybGF5X25vX3dhaXRfZm9yX3BhaWRfY29udGVudF9vdmVybGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfc3ludGhfY2hfaGVhZGVyc19iYW5uZWRfdXJsc19yZWdleFx1MDAzZFx1MDAyNmVuYWJsZV9hYl9ycF9pbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FkX2Nwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9hcHBfcHJvbW9fZW5kY2FwX2VtbF9vbl90YWJsZXRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Nhc3RfZm9yX3dlYl91bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Nhc3Rfb25fbXVzaWNfd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jbGllbnRfcGFnZV9pZF9oZWFkZXJfZm9yX2ZpcnN0X3BhcnR5X3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jbGllbnRfc2xpX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Rpc2NyZXRlX2xpdmVfcHJlY2lzZV9lbWJhcmdvc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkX3dlYl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkX3dlYl9jbGllbnRfY2hlY2tcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkc19pY29uX3dlYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXZpY3Rpb25fcHJvdGVjdGlvbl9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZ2VsX2xvZ19jb21tYW5kc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfaDVfaW5zdHJlYW1fd2F0Y2hfbmV4dF9wYXJhbXNfb2FybGliXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV92aWRlb19hZHNfb2FybGliXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oYW5kbGVzX2FjY291bnRfbWVudV9zd2l0Y2hlclx1MDAzZHRydWVcdTAwMjZlbmFibGVfa2FidWtpX2NvbW1lbnRzX29uX3Nob3J0c1x1MDAzZGRpc2FibGVkXHUwMDI2ZW5hYmxlX2xpdmVfcHJlbWllcmVfd2ViX3BsYXllcl9pbmRpY2F0b3JcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2xyX2hvbWVfaW5mZWVkX2Fkc19pbmxpbmVfcGxheWJhY2tfcHJvZ3Jlc3NfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX21peGVkX2RpcmVjdGlvbl9mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbXdlYl9saXZlc3RyZWFtX3VpX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbmFibGVfbmV3X3BhaWRfcHJvZHVjdF9wbGFjZW1lbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2Zfc2xvdF9hc2RlX3BsYXllcl9ieXRlX2g1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZfZm9yX3BhZ2VfdG9wX2Zvcm1hdHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95c2ZlX3R2XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYXNzX3NkY19nZXRfYWNjb3VudHNfbGlzdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGxfcl9jXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2ZpeF9vbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2luX3R2aHRtbDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NlcnZlcl9zdGl0Y2hlZF9kYWlcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Nob3J0c19wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NraXBfYWRfZ3VpZGFuY2VfcHJvbXB0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwcGFibGVfYWRzX2Zvcl91bnBsdWdnZWRfYWRfcG9kXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90ZWN0b25pY19hZF91eF9mb3JfaGFsZnRpbWVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RoaXJkX3BhcnR5X2luZm9cdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RvcHNvaWxfd3RhX2Zvcl9oYWxmdGltZV9saXZlX2luZnJhXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfbWVkaWFfc2Vzc2lvbl9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3dlYl9zY2hlZHVsZXJfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfeXRfYXRhX2lmcmFtZV9hdXRodXNlclx1MDAzZHRydWVcdTAwMjZlcnJvcl9tZXNzYWdlX2Zvcl9nc3VpdGVfbmV0d29ya19yZXN0cmljdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZXhwb3J0X25ldHdvcmtsZXNzX29wdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZXh0ZXJuYWxfZnVsbHNjcmVlbl93aXRoX2VkdVx1MDAzZHRydWVcdTAwMjZmYXN0X2F1dG9uYXZfaW5fYmFja2dyb3VuZFx1MDAzZHRydWVcdTAwMjZmZXRjaF9hdHRfaW5kZXBlbmRlbnRseVx1MDAzZHRydWVcdTAwMjZmaWxsX3NpbmdsZV92aWRlb193aXRoX25vdGlmeV90b19sYXNyXHUwMDNkdHJ1ZVx1MDAyNmZpbHRlcl92cDlfZm9yX2NzZGFpXHUwMDNkdHJ1ZVx1MDAyNmZpeF9hZHNfdHJhY2tpbmdfZm9yX3N3Zl9jb25maWdfZGVwcmVjYXRpb25fbXdlYlx1MDAzZHRydWVcdTAwMjZnY2ZfY29uZmlnX3N0b3JlX2VuYWJsZWRcdTAwM2R0cnVlXHUwMDI2Z2VsX3F1ZXVlX3RpbWVvdXRfbWF4X21zXHUwMDNkMzAwMDAwXHUwMDI2Z3BhX3NwYXJrbGVzX3Rlbl9wZXJjZW50X2xheWVyXHUwMDNkdHJ1ZVx1MDAyNmd2aV9jaGFubmVsX2NsaWVudF9zY3JlZW5cdTAwM2R0cnVlXHUwMDI2aDVfY29tcGFuaW9uX2VuYWJsZV9hZGNwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmg1X2VuYWJsZV9nZW5lcmljX2Vycm9yX2xvZ2dpbmdfZXZlbnRcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX3VuaWZpZWRfY3NpX3ByZXJvbGxcdTAwM2R0cnVlXHUwMDI2aDVfaW5wbGF5ZXJfZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfcmVzZXRfY2FjaGVfYW5kX2ZpbHRlcl9iZWZvcmVfdXBkYXRlX21hc3RoZWFkXHUwMDNkdHJ1ZVx1MDAyNmhlYXRzZWVrZXJfZGVjb3JhdGlvbl90aHJlc2hvbGRcdTAwM2QwLjBcdTAwMjZoZnJfZHJvcHBlZF9mcmFtZXJhdGVfZmFsbGJhY2tfdGhyZXNob2xkXHUwMDNkMFx1MDAyNmhpZGVfZW5kcG9pbnRfb3ZlcmZsb3dfb25feXRkX2Rpc3BsYXlfYWRfcmVuZGVyZXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWRfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZodG1sNV9hZHNfcHJlcm9sbF9sb2NrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QxNTAwMFx1MDAyNmh0bWw1X2FsbG93X2Rpc2NvbnRpZ3VvdXNfc2xpY2VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2FsbG93X3ZpZGVvX2tleWZyYW1lX3dpdGhvdXRfYXVkaW9cdTAwM2R0cnVlXHUwMDI2aHRtbDVfYXR0YWNoX251bV9yYW5kb21fYnl0ZXNfdG9fYmFuZGFpZFx1MDAzZDBcdTAwMjZodG1sNV9hdHRhY2hfcG9fdG9rZW5fdG9fYmFuZGFpZFx1MDAzZHRydWVcdTAwMjZodG1sNV9hdXRvbmF2X2NhcF9pZGxlX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfYXV0b25hdl9xdWFsaXR5X2NhcFx1MDAzZDcyMFx1MDAyNmh0bWw1X2F1dG9wbGF5X2RlZmF1bHRfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfYmxvY2tfcGlwX3NhZmFyaV9kZWxheVx1MDAzZDBcdTAwMjZodG1sNV9ibWZmX25ld19mb3VyY2NfY2hlY2tcdTAwM2R0cnVlXHUwMDI2aHRtbDVfY29iYWx0X2RlZmF1bHRfYnVmZmVyX3NpemVfaW5fYnl0ZXNcdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X21heF9zaXplX2Zvcl9pbW1lZF9qb2JcdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X21pbl9wcm9jZXNzb3JfY250X3RvX29mZmxvYWRfYWxnb1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfb3ZlcnJpZGVfcXVpY1x1MDAzZDBcdTAwMjZodG1sNV9jb25zdW1lX21lZGlhX2J5dGVzX3NsaWNlX2luZm9zXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlX2R1cGVfY29udGVudF92aWRlb19sb2Fkc19pbl9saWZlY3ljbGVfYXBpXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlYnVnX2RhdGFfbG9nX3Byb2JhYmlsaXR5XHUwMDNkMC4xXHUwMDI2aHRtbDVfZGVjb2RlX3RvX3RleHR1cmVfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlZmF1bHRfYWRfZ2Fpblx1MDAzZDAuNVx1MDAyNmh0bWw1X2RlZmF1bHRfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfYWRfbW9kdWxlX21zXHUwMDNkMFx1MDAyNmh0bWw1X2RlZmVyX2ZldGNoX2F0dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9kZWZlcl9tb2R1bGVzX2RlbGF5X3RpbWVfbWlsbGlzXHUwMDNkMFx1MDAyNmh0bWw1X2RlbGF5ZWRfcmV0cnlfY291bnRcdTAwM2QxXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9kZWxheV9tc1x1MDAzZDUwMDBcdTAwMjZodG1sNV9kZXByZWNhdGVfdmlkZW9fdGFnX3Bvb2xcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVza3RvcF92cjE4MF9hbGxvd19wYW5uaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RmX2Rvd25ncmFkZV90aHJlc2hcdTAwM2QwLjJcdTAwMjZodG1sNV9kaXNhYmxlX2NzaV9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNhYmxlX21vdmVfcHNzaF90b19tb292XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbm9uX2NvbnRpZ3VvdXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzcGxheWVkX2ZyYW1lX3JhdGVfZG93bmdyYWRlX3RocmVzaG9sZFx1MDAzZDQ1XHUwMDI2aHRtbDVfZHJtX2NoZWNrX2FsbF9rZXlfZXJyb3Jfc3RhdGVzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RybV9jcGlfbGljZW5zZV9rZXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2FjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWRzX2NsaWVudF9tb25pdG9yaW5nX2xvZ190dlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2FwdGlvbl9jaGFuZ2VzX2Zvcl9tb3NhaWNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NsaWVudF9oaW50c19vdmVycmlkZVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY29tcG9zaXRlX2VtYmFyZ29cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2VhYzNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2VtYmVkZGVkX3BsYXllcl92aXNpYmlsaXR5X3NpZ25hbHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX25ld19odmNfZW5jXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9ub25fbm90aWZ5X2NvbXBvc2l0ZV92b2RfbHNhcl9wYWNmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9zaW5nbGVfdmlkZW9fdm9kX2l2YXJfb25fcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19kYXNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV90dm9zX2VuY3J5cHRlZF92cDlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3dpZGV2aW5lX2Zvcl9hbGNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3dpZGV2aW5lX2Zvcl9mYXN0X2xpbmVhclx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmNvdXJhZ2VfYXJyYXlfY29hbGVzY2luZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9nYXBsZXNzX2VuZGVkX3RyYW5zaXRpb25fYnVmZmVyX21zXHUwMDNkMjAwXHUwMDI2aHRtbDVfZ2VuZXJhdGVfc2Vzc2lvbl9wb190b2tlblx1MDAzZHRydWVcdTAwMjZodG1sNV9nbF9mcHNfdGhyZXNob2xkXHUwMDNkMFx1MDAyNmh0bWw1X2hkY3BfcHJvYmluZ19zdHJlYW1fdXJsXHUwMDNkXHUwMDI2aHRtbDVfaGZyX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2hpZ2hfcmVzX2xvZ2dpbmdfcGVyY2VudFx1MDAzZDEuMFx1MDAyNmh0bWw1X2lkbGVfcmF0ZV9saW1pdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9pbm5lcnR1YmVfaGVhcnRiZWF0c19mb3JfZmFpcnBsYXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3BsYXlyZWFkeVx1MDAzZHRydWVcdTAwMjZodG1sNV9pbm5lcnR1YmVfaGVhcnRiZWF0c19mb3Jfd2lkZXZpbmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW9zNF9zZWVrX2Fib3ZlX3plcm9cdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW9zN19mb3JjZV9wbGF5X29uX3N0YWxsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvc19mb3JjZV9zZWVrX3RvX3plcm9fb25fc3RvcFx1MDAzZHRydWVcdTAwMjZodG1sNV9qdW1ib19tb2JpbGVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMy4wXHUwMDI2aHRtbDVfanVtYm9fdWxsX25vbnN0cmVhbWluZ19tZmZhX21zXHUwMDNkNDAwMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRcdTAwM2QxLjNcdTAwMjZodG1sNV9saWNlbnNlX2NvbnN0cmFpbnRfZGVsYXlcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfbGl2ZV9hYnJfaGVhZF9taXNzX2ZyYWN0aW9uXHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9hYnJfcmVwcmVkaWN0X2ZyYWN0aW9uXHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9ieXRlcmF0ZV9mYWN0b3JfZm9yX3JlYWRhaGVhZFx1MDAzZDEuM1x1MDAyNmh0bWw1X2xpdmVfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfbWV0YWRhdGFfZml4XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xpdmVfbm9ybWFsX2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfbGl2ZV91bHRyYV9sb3dfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbG9nX2F1ZGlvX2Ficlx1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfZXhwZXJpbWVudF9pZF9mcm9tX3BsYXllcl9yZXNwb25zZV90b19jdG1wXHUwMDNkXHUwMDI2aHRtbDVfbG9nX2ZpcnN0X3NzZGFpX3JlcXVlc3RzX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX3JlYnVmZmVyX2V2ZW50c1x1MDAzZDVcdTAwMjZodG1sNV9sb2dfc3NkYWlfZmFsbGJhY2tfYWRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ190cmlnZ2VyX2V2ZW50c193aXRoX2RlYnVnX2RhdGFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl9qaWdnbGVfY210X2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfbmV3X2VsZW1fc2hvcnRzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfdGhyZXNob2xkX21zXHUwMDNkMzAwMDBcdTAwMjZodG1sNV9tYW5pZmVzdGxlc3Nfc2VnX2RyaWZ0X2xpbWl0X3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3VucGx1Z2dlZFx1MDAzZHRydWVcdTAwMjZodG1sNV9tYW5pZmVzdGxlc3NfdnA5X290Zlx1MDAzZHRydWVcdTAwMjZodG1sNV9tYXhfZHJpZnRfcGVyX3RyYWNrX3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9tYXhfaGVhZG1fZm9yX3N0cmVhbWluZ194aHJcdTAwM2QwXHUwMDI2aHRtbDVfbWF4X2xpdmVfZHZyX3dpbmRvd19wbHVzX21hcmdpbl9zZWNzXHUwMDNkNDY4MDAuMFx1MDAyNmh0bWw1X21heF9yZWFkYmVoaW5kX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfbWF4X3JlZGlyZWN0X3Jlc3BvbnNlX2xlbmd0aFx1MDAzZDgxOTJcdTAwMjZodG1sNV9tYXhfc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWF4X3NvdXJjZV9idWZmZXJfYXBwZW5kX3NpemVfaW5fYnl0ZXNcdTAwM2QwXHUwMDI2aHRtbDVfbWF4aW11bV9yZWFkYWhlYWRfc2Vjb25kc1x1MDAzZDAuMFx1MDAyNmh0bWw1X21lZGlhX2Z1bGxzY3JlZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWZsX2V4dGVuZF9tYXhfcmVxdWVzdF90aW1lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21pbl9yZWFkYmVoaW5kX2NhcF9zZWNzXHUwMDNkNjBcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21pbl9zZWxlY3RhYmxlX3F1YWxpdHlfb3JkaW5hbFx1MDAzZDBcdTAwMjZodG1sNV9taW5fc3RhcnR1cF9idWZmZXJlZF9hZF9tZWRpYV9kdXJhdGlvbl9zZWNzXHUwMDNkMS4yXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbmltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9ub19wbGFjZWhvbGRlcl9yb2xsYmFja3NcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbm9uX25ldHdvcmtfcmVidWZmZXJfZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfbm9uX29uZXNpZV9hdHRhY2hfcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfbm90X3JlZ2lzdGVyX2Rpc3Bvc2FibGVzX3doZW5fY29yZV9saXN0ZW5zXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29mZmxpbmVfZmFpbHVyZV9yZXRyeV9saW1pdFx1MDAzZDJcdTAwMjZodG1sNV9vbmVzaWVfZGVmZXJfY29udGVudF9sb2FkZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2hvc3RfcmFjaW5nX2NhcF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfaWdub3JlX2lubmVydHViZV9hcGlfa2V5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9saXZlX3R0bF9zZWNzXHUwMDNkOFx1MDAyNmh0bWw1X29uZXNpZV9ub256ZXJvX3BsYXliYWNrX3N0YXJ0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9ub3RpZnlfY3VlcG9pbnRfbWFuYWdlcl9vbl9jb21wbGV0aW9uXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9wcmV3YXJtX2Nvb2xkb3duX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9wcmV3YXJtX2ludGVydmFsX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9wcmV3YXJtX21heF9sYWN0X21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX3JlZGlyZWN0b3JfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVxdWVzdF90aW1lb3V0X21zXHUwMDNkMTAwMFx1MDAyNmh0bWw1X29uZXNpZV9zdGlja3lfc2VydmVyX3NpZGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGF1c2Vfb25fbm9uZm9yZWdyb3VuZF9wbGF0Zm9ybV9lcnJvcnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVha19zaGF2ZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wZXJmX2NhcF9vdmVycmlkZV9zdGlja3lcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZm9ybWFuY2VfY2FwX2Zsb29yXHUwMDNkMzYwXHUwMDI2aHRtbDVfcGVyZm9ybWFuY2VfaW1wYWN0X3Byb2ZpbGluZ190aW1lcl9tc1x1MDAzZDBcdTAwMjZodG1sNV9wZXJzZXJ2ZV9hdjFfcGVyZl9jYXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxhdGZvcm1fYmFja3ByZXNzdXJlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX21pbmltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9wbGF5ZXJfYXV0b25hdl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXllcl9keW5hbWljX2JvdHRvbV9ncmFkaWVudFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfbWluX2J1aWxkX2NsXHUwMDNkLTFcdTAwMjZodG1sNV9wbGF5ZXJfcHJlbG9hZF9hZF9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcG9zdF9pbnRlcnJ1cHRfcmVhZGFoZWFkXHUwMDNkMjBcdTAwMjZodG1sNV9wcmVmZXJfc2VydmVyX2J3ZTNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcHJlbG9hZF93YWl0X3RpbWVfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Byb2JlX3ByaW1hcnlfZGVsYXlfYmFzZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9wcm9jZXNzX2FsbF9lbmNyeXB0ZWRfZXZlbnRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3FvZV9saF9tYXhfcmVwb3J0X2NvdW50XHUwMDNkMFx1MDAyNmh0bWw1X3FvZV9saF9taW5fZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfcXVlcnlfc3dfc2VjdXJlX2NyeXB0b19mb3JfYW5kcm9pZFx1MDAzZHRydWVcdTAwMjZodG1sNV9yYW5kb21fcGxheWJhY2tfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X3JlY29nbml6ZV9wcmVkaWN0X3N0YXJ0X2N1ZV9wb2ludFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfY29tbWFuZF90cmlnZ2VyZWRfY29tcGFuaW9uc1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfbm90X3NlcnZhYmxlX2NoZWNrX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVuYW1lX2FwYnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X2ZhdGFsX2RybV9yZXN0cmljdGVkX2Vycm9yX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X3Nsb3dfYWRzX2FzX2Vycm9yXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfb25seV9oZHJfb3Jfc2RyX2tleXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVxdWVzdF9zaXppbmdfbXVsdGlwbGllclx1MDAzZDAuOFx1MDAyNmh0bWw1X3Jlc2V0X21lZGlhX3N0cmVhbV9vbl91bnJlc3VtYWJsZV9zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVzb3VyY2VfYmFkX3N0YXR1c19kZWxheV9zY2FsaW5nXHUwMDNkMS41XHUwMDI2aHRtbDVfcmVzdHJpY3Rfc3RyZWFtaW5nX3hocl9vbl9zcWxlc3NfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2FmYXJpX2Rlc2t0b3BfZW1lX21pbl92ZXJzaW9uXHUwMDNkMFx1MDAyNmh0bWw1X3NhbXN1bmdfa2FudF9saW1pdF9tYXhfYml0cmF0ZVx1MDAzZDBcdTAwMjZodG1sNV9zZWVrX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2Q4MDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9kZWxheV9tc1x1MDAzZDEyMDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfYnVmZmVyX3JhbmdlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX3Zyc19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2NmbFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfc2V0X2NtdF9kZWxheV9tc1x1MDAzZDIwMDBcdTAwMjZodG1sNV9zZWVrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NlcnZlcl9zdGl0Y2hlZF9kYWlfZGVjb3JhdGVkX3VybF9yZXRyeV9saW1pdFx1MDAzZDVcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2dyb3VwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Nlc3Npb25fcG9fdG9rZW5faW50ZXJ2YWxfdGltZV9tc1x1MDAzZDkwMDAwMFx1MDAyNmh0bWw1X3NraXBfb29iX3N0YXJ0X3NlY29uZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2tpcF9zbG93X2FkX2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9za2lwX3N1Yl9xdWFudHVtX2Rpc2NvbnRpbnVpdHlfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfbm9fbWVkaWFfc291cmNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfdGltZW91dF9kZWxheV9tc1x1MDAzZDIwMDAwXHUwMDI2aHRtbDVfc3NkYWlfYWRmZXRjaF9keW5hbWljX3RpbWVvdXRfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfc3NkYWlfZW5hYmxlX25ld19zZWVrX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N0YXRlZnVsX2F1ZGlvX21pbl9hZGp1c3RtZW50X3ZhbHVlXHUwMDNkMFx1MDAyNmh0bWw1X3N0YXRpY19hYnJfcmVzb2x1dGlvbl9zaGVsZlx1MDAzZDBcdTAwMjZodG1sNV9zdG9yZV94aHJfaGVhZGVyc19yZWFkYWJsZVx1MDAzZHRydWVcdTAwMjZodG1sNV9zdHJlYW1pbmdfeGhyX2V4cGFuZF9yZXF1ZXN0X3NpemVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbG9hZF9zcGVlZF9jaGVja19pbnRlcnZhbFx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjI1XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc19vbl90aW1lb3V0XHUwMDNkMC4xXHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2xvYWRfc3BlZWRcdTAwM2QxLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9zZWVrX2xhdGVuY3lfZnVkZ2VcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRfYnVmZmVyX2hlYWx0aF9zZWNzXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGltZW91dF9zZWNzXHUwMDNkMi4wXHUwMDI2aHRtbDVfdWdjX2xpdmVfYXVkaW9fNTFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdWdjX3ZvZF9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91bnJlcG9ydGVkX3NlZWtfcmVzZWVrX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3VucmVzdHJpY3RlZF9sYXllcl9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QwLjBcdTAwMjZodG1sNV91cmxfcGFkZGluZ19sZW5ndGhcdTAwM2QwXHUwMDI2aHRtbDVfdXJsX3NpZ25hdHVyZV9leHBpcnlfdGltZV9ob3Vyc1x1MDAzZDBcdTAwMjZodG1sNV91c2VfcG9zdF9mb3JfbWVkaWFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdXNlX3VtcFx1MDAzZHRydWVcdTAwMjZodG1sNV92aWRlb190YmRfbWluX2tiXHUwMDNkMFx1MDAyNmh0bWw1X3ZpZXdwb3J0X3VuZGVyc2VuZF9tYXhpbXVtXHUwMDNkMC4wXHUwMDI2aHRtbDVfdm9sdW1lX3NsaWRlcl90b29sdGlwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYl9lbmFibGVfaGFsZnRpbWVfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZodG1sNV93ZWJwb19pZGxlX3ByaW9yaXR5X2pvYlx1MDAzZHRydWVcdTAwMjZodG1sNV93b2ZmbGVfcmVzdW1lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvcmthcm91bmRfZGVsYXlfdHJpZ2dlclx1MDAzZHRydWVcdTAwMjZodG1sNV95dHZscl9lbmFibGVfc2luZ2xlX3NlbGVjdF9zdXJ2ZXlcdTAwM2R0cnVlXHUwMDI2aWdub3JlX292ZXJsYXBwaW5nX2N1ZV9wb2ludHNfb25fZW5kZW1pY19saXZlX2h0bWw1XHUwMDNkdHJ1ZVx1MDAyNmlsX3VzZV92aWV3X21vZGVsX2xvZ2dpbmdfY29udGV4dFx1MDAzZHRydWVcdTAwMjZpbml0aWFsX2dlbF9iYXRjaF90aW1lb3V0XHUwMDNkMjAwMFx1MDAyNmluamVjdGVkX2xpY2Vuc2VfaGFuZGxlcl9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNmluamVjdGVkX2xpY2Vuc2VfaGFuZGxlcl9saWNlbnNlX3N0YXR1c1x1MDAzZDBcdTAwMjZpdGRybV9pbmplY3RlZF9saWNlbnNlX3NlcnZpY2VfZXJyb3JfY29kZVx1MDAzZDBcdTAwMjZpdGRybV93aWRldmluZV9oYXJkZW5lZF92bXBfbW9kZVx1MDAzZGxvZ1x1MDAyNmpzb25fY29uZGVuc2VkX3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9jb21tYW5kX2hhbmRsZXJfY29tbWFuZF9iYW5saXN0XHUwMDNkW11cdTAwMjZrZXZsYXJfZHJvcGRvd25fZml4XHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9nZWxfZXJyb3Jfcm91dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllclx1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllcl9leHBhbmRfdG9wXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX3BsYXlfcGF1c2Vfb25fc2NyaW1cdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3BsYXliYWNrX2Fzc29jaWF0ZWRfcXVldWVcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3F1ZXVlX3VzZV91cGRhdGVfYXBpXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zaW1wX3Nob3J0c19yZXNldF9zY3JvbGxcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NtYXJ0X2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzX3NldHRpbmdcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3ZpbWlvX3VzZV9zaGFyZWRfbW9uaXRvclx1MDAzZHRydWVcdTAwMjZsaXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZsaXZlX2ZyZXNjYV92Mlx1MDAzZHRydWVcdTAwMjZsb2dfZXJyb3JzX3Rocm91Z2hfbndsX29uX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19nZWxfY29tcHJlc3Npb25fbGF0ZW5jeVx1MDAzZHRydWVcdTAwMjZsb2dfaGVhcnRiZWF0X3dpdGhfbGlmZWN5Y2xlc1x1MDAzZHRydWVcdTAwMjZsb2dfd2ViX2VuZHBvaW50X3RvX2xheWVyXHUwMDNkdHJ1ZVx1MDAyNmxvZ193aW5kb3dfb25lcnJvcl9mcmFjdGlvblx1MDAzZDAuMVx1MDAyNm1hbmlmZXN0bGVzc19wb3N0X2xpdmVcdTAwM2R0cnVlXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZV91ZnBoXHUwMDNkdHJ1ZVx1MDAyNm1heF9ib2R5X3NpemVfdG9fY29tcHJlc3NcdTAwM2Q1MDAwMDBcdTAwMjZtYXhfcHJlZmV0Y2hfd2luZG93X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb25cdTAwM2QwXHUwMDI2bWF4X3Jlc29sdXRpb25fZm9yX3doaXRlX25vaXNlXHUwMDNkMzYwXHUwMDI2bWR4X2VuYWJsZV9wcml2YWN5X2Rpc2Nsb3N1cmVfdWlcdTAwM2R0cnVlXHUwMDI2bWR4X2xvYWRfY2FzdF9hcGlfYm9vdHN0cmFwX3NjcmlwdFx1MDAzZHRydWVcdTAwMjZtaWdyYXRlX2V2ZW50c190b190c1x1MDAzZHRydWVcdTAwMjZtaW5fcHJlZmV0Y2hfb2Zmc2V0X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb25cdTAwM2QxMFx1MDAyNm11c2ljX2VuYWJsZV9zaGFyZWRfYXVkaW9fdGllcl9sb2dpY1x1MDAzZHRydWVcdTAwMjZtd2ViX2MzX2VuZHNjcmVlblx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9jdXN0b21fY29udHJvbF9zaGFyZWRcdTAwM2R0cnVlXHUwMDI2bXdlYl9lbmFibGVfc2tpcHBhYmxlc19vbl9qaW9fcGhvbmVcdTAwM2R0cnVlXHUwMDI2bXdlYl9tdXRlZF9hdXRvcGxheV9hbmltYXRpb25cdTAwM2RzaHJpbmtcdTAwMjZtd2ViX25hdGl2ZV9jb250cm9sX2luX2ZhdXhfZnVsbHNjcmVlbl9zaGFyZWRcdTAwM2R0cnVlXHUwMDI2bmV0d29ya19wb2xsaW5nX2ludGVydmFsXHUwMDNkMzAwMDBcdTAwMjZuZXR3b3JrbGVzc19nZWxcdTAwM2R0cnVlXHUwMDI2bmV0d29ya2xlc3NfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZuZXdfY29kZWNzX3N0cmluZ19hcGlfdXNlc19sZWdhY3lfc3R5bGVcdTAwM2R0cnVlXHUwMDI2bndsX3NlbmRfZmFzdF9vbl91bmxvYWRcdTAwM2R0cnVlXHUwMDI2bndsX3NlbmRfZnJvbV9tZW1vcnlfd2hlbl9vbmxpbmVcdTAwM2R0cnVlXHUwMDI2b2ZmbGluZV9lcnJvcl9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZwYWNmX2xvZ2dpbmdfZGVsYXlfbWlsbGlzZWNvbmRzX3Rocm91Z2hfeWJmZV90dlx1MDAzZDMwMDAwXHUwMDI2cGFnZWlkX2FzX2hlYWRlcl93ZWJcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Fkc19zZXRfYWRmb3JtYXRfb25fY2xpZW50XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9hbGxvd19hdXRvbmF2X2FmdGVyX3BsYXlsaXN0XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9ib290c3RyYXBfbWV0aG9kXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9kZWZlcl9jYXB0aW9uX2Rpc3BsYXlcdTAwM2QxMDAwXHUwMDI2cGxheWVyX2Rlc3Ryb3lfb2xkX3ZlcnNpb25cdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RvdWJsZXRhcF90b19zZWVrXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9lbmFibGVfcGxheWJhY2tfcGxheWxpc3RfY2hhbmdlXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9lbmRzY3JlZW5fZWxsaXBzaXNfZml4XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl91bmRlcmxheV9taW5fcGxheWVyX3dpZHRoXHUwMDNkNzY4LjBcdTAwMjZwbGF5ZXJfdW5kZXJsYXlfdmlkZW9fd2lkdGhfZnJhY3Rpb25cdTAwM2QwLjZcdTAwMjZwbGF5ZXJfd2ViX2NhbmFyeV9zdGFnZVx1MDAzZDBcdTAwMjZwbGF5cmVhZHlfZmlyc3RfcGxheV9leHBpcmF0aW9uXHUwMDNkLTFcdTAwMjZwb2x5bWVyX2JhZF9idWlsZF9sYWJlbHNcdTAwM2R0cnVlXHUwMDI2cG9seW1lcl9sb2dfcHJvcF9jaGFuZ2Vfb2JzZXJ2ZXJfcGVyY2VudFx1MDAzZDBcdTAwMjZwb2x5bWVyX3ZlcmlmaXlfYXBwX3N0YXRlXHUwMDNkdHJ1ZVx1MDAyNnByZXNraXBfYnV0dG9uX3N0eWxlX2Fkc19iYWNrZW5kXHUwMDNkY291bnRkb3duX25leHRfdG9fdGh1bWJuYWlsXHUwMDI2cW9lX253bF9kb3dubG9hZHNcdTAwM2R0cnVlXHUwMDI2cW9lX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnJlY29yZF9hcHBfY3Jhc2hlZF93ZWJcdTAwM2R0cnVlXHUwMDI2cmVwbGFjZV9wbGF5YWJpbGl0eV9yZXRyaWV2ZXJfaW5fd2F0Y2hcdTAwM2R0cnVlXHUwMDI2c2NoZWR1bGVyX3VzZV9yYWZfYnlfZGVmYXVsdFx1MDAzZHRydWVcdTAwMjZzZWxmX3BvZGRpbmdfaGVhZGVyX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19pbnRlcnN0aXRpYWxfbWVzc2FnZVx1MDAyNnNlbGZfcG9kZGluZ19oaWdobGlnaHRfbm9uX2RlZmF1bHRfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZV9zdHJpbmdfdGVtcGxhdGVcdTAwM2RzZWxmX3BvZGRpbmdfbWlkcm9sbF9jaG9pY2VcdTAwMjZzZW5kX2NvbmZpZ19oYXNoX3RpbWVyXHUwMDNkMFx1MDAyNnNldF9pbnRlcnN0aXRpYWxfYWR2ZXJ0aXNlcnNfcXVlc3Rpb25fdGV4dFx1MDAzZHRydWVcdTAwMjZzaG9ydF9zdGFydF90aW1lX3ByZWZlcl9wdWJsaXNoX2luX3dhdGNoX2xvZ1x1MDAzZHRydWVcdTAwMjZzaG9ydHNfbW9kZV90b19wbGF5ZXJfYXBpXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19ub19zdG9wX3ZpZGVvX2NhbGxcdTAwM2R0cnVlXHUwMDI2c2hvdWxkX2NsZWFyX3ZpZGVvX2RhdGFfb25fcGxheWVyX2N1ZWRfdW5zdGFydGVkXHUwMDNkdHJ1ZVx1MDAyNnNpbXBseV9lbWJlZGRlZF9lbmFibGVfYm90Z3VhcmRcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbmxpbmVfbXV0ZWRfbGljZW5zZV9zZXJ2aWNlX2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNnNraXBfaW52YWxpZF95dGNzaV90aWNrc1x1MDAzZHRydWVcdTAwMjZza2lwX2xzX2dlbF9yZXRyeVx1MDAzZHRydWVcdTAwMjZza2lwX3NldHRpbmdfaW5mb19pbl9jc2lfZGF0YV9vYmplY3RcdTAwM2R0cnVlXHUwMDI2c2xvd19jb21wcmVzc2lvbnNfYmVmb3JlX2FiYW5kb25fY291bnRcdTAwM2Q0XHUwMDI2c3BlZWRtYXN0ZXJfY2FuY2VsbGF0aW9uX21vdmVtZW50X2RwXHUwMDNkMFx1MDAyNnNwZWVkbWFzdGVyX3BsYXliYWNrX3JhdGVcdTAwM2QwLjBcdTAwMjZzcGVlZG1hc3Rlcl90b3VjaF9hY3RpdmF0aW9uX21zXHUwMDNkMFx1MDAyNnN0YXJ0X2NsaWVudF9nY2ZcdTAwM2R0cnVlXHUwMDI2c3RhcnRfY2xpZW50X2djZl9mb3JfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNnN0YXJ0X3NlbmRpbmdfY29uZmlnX2hhc2hcdTAwM2R0cnVlXHUwMDI2c3RyZWFtaW5nX2RhdGFfZW1lcmdlbmN5X2l0YWdfYmxhY2tsaXN0XHUwMDNkW11cdTAwMjZzdXBwcmVzc19lcnJvcl8yMDRfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZ0cmFuc3BvcnRfdXNlX3NjaGVkdWxlclx1MDAzZHRydWVcdTAwMjZ0dl9wYWNmX2xvZ2dpbmdfc2FtcGxlX3JhdGVcdTAwM2QwLjAxXHUwMDI2dHZodG1sNV91bnBsdWdnZWRfcHJlbG9hZF9jYWNoZV9zaXplXHUwMDNkNVx1MDAyNnVuY292ZXJfYWRfYmFkZ2Vfb25fUlRMX3Rpbnlfd2luZG93XHUwMDNkdHJ1ZVx1MDAyNnVucGx1Z2dlZF9kYWlfbGl2ZV9jaHVua19yZWFkYWhlYWRcdTAwM2QzXHUwMDI2dW5wbHVnZ2VkX3R2aHRtbDVfdmlkZW9fcHJlbG9hZF9vbl9mb2N1c19kZWxheV9tc1x1MDAzZDBcdTAwMjZ1cGRhdGVfbG9nX2V2ZW50X2NvbmZpZ1x1MDAzZHRydWVcdTAwMjZ1c2VfYWNjZXNzaWJpbGl0eV9kYXRhX29uX2Rlc2t0b3BfcGxheWVyX2J1dHRvblx1MDAzZHRydWVcdTAwMjZ1c2VfY29yZV9zbVx1MDAzZHRydWVcdTAwMjZ1c2VfaW5saW5lZF9wbGF5ZXJfcnBjXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfY21sXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfaW5fbWVtb3J5X3N0b3JhZ2VcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfaW5pdGlhbGl6YXRpb25cdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc2F3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3N0d1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF93dHNcdTAwM2R0cnVlXHUwMDI2dXNlX3BsYXllcl9hYnVzZV9iZ19saWJyYXJ5XHUwMDNkdHJ1ZVx1MDAyNnVzZV9wcm9maWxlcGFnZV9ldmVudF9sYWJlbF9pbl9jYXJvdXNlbF9wbGF5YmFja3NcdTAwM2R0cnVlXHUwMDI2dXNlX3JlcXVlc3RfdGltZV9tc19oZWFkZXJcdTAwM2R0cnVlXHUwMDI2dXNlX3Nlc3Npb25fYmFzZWRfc2FtcGxpbmdcdTAwM2R0cnVlXHUwMDI2dXNlX3RzX3Zpc2liaWxpdHlsb2dnZXJcdTAwM2R0cnVlXHUwMDI2dmFyaWFibGVfYnVmZmVyX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2dmVyaWZ5X2Fkc19pdGFnX2Vhcmx5XHUwMDNkdHJ1ZVx1MDAyNnZwOV9kcm1fbGl2ZVx1MDAzZHRydWVcdTAwMjZ2c3NfZmluYWxfcGluZ19zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZ2c3NfcGluZ3NfdXNpbmdfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2dnNzX3BsYXliYWNrX3VzZV9zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfYXBpX3VybFx1MDAzZHRydWVcdTAwMjZ3ZWJfYXN5bmNfY29udGV4dF9wcm9jZXNzb3JfaW1wbFx1MDAzZHN0YW5kYWxvbmVcdTAwMjZ3ZWJfY2luZW1hdGljX3dhdGNoX3NldHRpbmdzXHUwMDNkdHJ1ZVx1MDAyNndlYl9jbGllbnRfdmVyc2lvbl9vdmVycmlkZVx1MDAzZFx1MDAyNndlYl9kZWR1cGVfdmVfZ3JhZnRpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX2RlcHJlY2F0ZV9zZXJ2aWNlX2FqYXhfbWFwX2RlcGVuZGVuY3lcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV9lcnJvcl8yMDRcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV9pbnN0cmVhbV9hZHNfbGlua19kZWZpbml0aW9uX2ExMXlfYnVnZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfdm96X2F1ZGlvX2ZlZWRiYWNrXHUwMDNkdHJ1ZVx1MDAyNndlYl9maXhfZmluZV9zY3J1YmJpbmdfZHJhZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZm9yZWdyb3VuZF9oZWFydGJlYXRfaW50ZXJ2YWxfbXNcdTAwM2QyODAwMFx1MDAyNndlYl9mb3J3YXJkX2NvbW1hbmRfb25fcGJqXHUwMDNkdHJ1ZVx1MDAyNndlYl9nZWxfZGVib3VuY2VfbXNcdTAwM2Q2MDAwMFx1MDAyNndlYl9nZWxfdGltZW91dF9jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX2lubGluZV9wbGF5ZXJfbm9fcGxheWJhY2tfdWlfY2xpY2tfaGFuZGxlclx1MDAzZHRydWVcdTAwMjZ3ZWJfa2V5X21vbWVudHNfbWFya2Vyc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nX21lbW9yeV90b3RhbF9rYnl0ZXNcdTAwM2R0cnVlXHUwMDI2d2ViX2xvZ2dpbmdfbWF4X2JhdGNoXHUwMDNkMTUwXHUwMDI2d2ViX21vZGVybl9hZHNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fYnV0dG9uc19ibF9zdXJ2ZXlcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zY3J1YmJlclx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3N1YnNjcmliZVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3N1YnNjcmliZV9zdHlsZVx1MDAzZGZpbGxlZFx1MDAyNndlYl9uZXdfYXV0b25hdl9jb3VudGRvd25cdTAwM2R0cnVlXHUwMDI2d2ViX29uZV9wbGF0Zm9ybV9lcnJvcl9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfb3Bfc2lnbmFsX3R5cGVfYmFubGlzdFx1MDAzZFtdXHUwMDI2d2ViX3BhdXNlZF9vbmx5X21pbmlwbGF5ZXJfc2hvcnRjdXRfZXhwYW5kXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5YmFja19hc3NvY2lhdGVkX2xvZ19jdHRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfdmVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hZGRfdmVfY29udmVyc2lvbl9sb2dnaW5nX3RvX291dGJvdW5kX2xpbmtzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYWx3YXlzX2VuYWJsZV9hdXRvX3RyYW5zbGF0aW9uXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXBpX2xvZ2dpbmdfZnJhY3Rpb25cdTAwM2QwLjAxXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X2VtcHR5X3N1Z2dlc3Rpb25zX2ZpeFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdG9nZ2xlX2Fsd2F5c19saXN0ZW5cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X3VzZV9zZXJ2ZXJfcHJvdmlkZWRfc3RhdGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9jYXB0aW9uX2xhbmd1YWdlX3ByZWZlcmVuY2Vfc3RpY2tpbmVzc19kdXJhdGlvblx1MDAzZDMwXHUwMDI2d2ViX3BsYXllcl9kZWNvdXBsZV9hdXRvbmF2XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZGlzYWJsZV9pbmxpbmVfc2NydWJiaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX2Vhcmx5X3dhcm5pbmdfc25hY2tiYXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZmVhdHVyZWRfcHJvZHVjdF9iYW5uZXJfb25fZGVza3RvcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9pbl9oNV9hcGlcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfcHJlbWl1bV9oYnJfcGxheWJhY2tfY2FwXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaW5uZXJ0dWJlX3BsYXlsaXN0X3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2lwcF9jYW5hcnlfdHlwZV9mb3JfbG9nZ2luZ1x1MDAzZFx1MDAyNndlYl9wbGF5ZXJfbGl2ZV9tb25pdG9yX2Vudlx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2xvZ19jbGlja19iZWZvcmVfZ2VuZXJhdGluZ192ZV9jb252ZXJzaW9uX3BhcmFtc1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX21vdmVfYXV0b25hdl90b2dnbGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9tdXNpY192aXN1YWxpemVyX3RyZWF0bWVudFx1MDAzZGZha2VcdTAwMjZ3ZWJfcGxheWVyX211dGFibGVfZXZlbnRfbGFiZWxcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9uaXRyYXRlX3Byb21vX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9vZmZsaW5lX3BsYXlsaXN0X2F1dG9fcmVmcmVzaFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Jlc3BvbnNlX3BsYXliYWNrX3RyYWNraW5nX3BhcnNpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZWVrX2NoYXB0ZXJzX2J5X3Nob3J0Y3V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2VudGluZWxfaXNfdW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2hvdWxkX2hvbm9yX2luY2x1ZGVfYXNyX3NldHRpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG93X211c2ljX2luX3RoaXNfdmlkZW9fZ3JhcGhpY1x1MDAzZHZpZGVvX3RodW1ibmFpbFx1MDAyNndlYl9wbGF5ZXJfc21hbGxfaGJwX3NldHRpbmdzX21lbnVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zc19kYWlfYWRfZmV0Y2hpbmdfdGltZW91dF9tc1x1MDAzZDE1MDAwXHUwMDI2d2ViX3BsYXllcl9zc19tZWRpYV90aW1lX29mZnNldFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RvcGlmeV9zdWJ0aXRsZXNfZm9yX3Nob3J0c1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RvdWNoX21vZGVfaW1wcm92ZW1lbnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdHJhbnNmZXJfdGltZW91dF90aHJlc2hvbGRfbXNcdTAwM2QxMDgwMDAwMFx1MDAyNndlYl9wbGF5ZXJfdW5zZXRfZGVmYXVsdF9jc25fa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3VzZV9uZXdfYXBpX2Zvcl9xdWFsaXR5X3B1bGxiYWNrXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdmVfY29udmVyc2lvbl9maXhlc19mb3JfY2hhbm5lbF9pbmZvXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3dhdGNoX25leHRfcmVzcG9uc2VfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcHJlZmV0Y2hfcHJlbG9hZF92aWRlb1x1MDAzZHRydWVcdTAwMjZ3ZWJfcm91bmRlZF90aHVtYm5haWxzXHUwMDNkdHJ1ZVx1MDAyNndlYl9zZXR0aW5nc19tZW51X2ljb25zXHUwMDNkdHJ1ZVx1MDAyNndlYl9zbW9vdGhuZXNzX3Rlc3RfZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9tZXRob2RcdTAwM2QwXHUwMDI2d2ViX3l0X2NvbmZpZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNndpbF9pY29uX3JlbmRlcl93aGVuX2lkbGVcdTAwM2R0cnVlXHUwMDI2d29mZmxlX2NsZWFuX3VwX2FmdGVyX2VudGl0eV9taWdyYXRpb25cdTAwM2R0cnVlXHUwMDI2d29mZmxlX2VuYWJsZV9kb3dubG9hZF9zdGF0dXNcdTAwM2R0cnVlXHUwMDI2d29mZmxlX3BsYXlsaXN0X29wdGltaXphdGlvblx1MDAzZHRydWVcdTAwMjZ5dGlkYl9jbGVhcl9lbWJlZGRlZF9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2eXRpZGJfZmV0Y2hfZGF0YXN5bmNfaWRzX2Zvcl9kYXRhX2NsZWFudXBcdTAwM2R0cnVlXHUwMDI2eXRpZGJfcmVtYWtlX2RiX3JldHJpZXNcdTAwM2QxXHUwMDI2eXRpZGJfcmVvcGVuX2RiX3JldHJpZXNcdTAwM2QwXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdFx1MDAzZDAuMDJcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0X3Nlc3Npb25cdTAwM2QwLjJcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0X3RyYW5zYWN0aW9uXHUwMDNkMC4xIiwiaGlkZUluZm8iOnRydWUsInN0YXJ0TXV0ZWQiOnRydWUsImVuYWJsZU11dGVkQXV0b3BsYXkiOnRydWUsImNzcE5vbmNlIjoiaGFFb1loak96WUdqQngyNENYUkJ5USIsImNhbmFyeVN0YXRlIjoibm9uZSIsImVuYWJsZUNzaUxvZ2dpbmciOnRydWUsImNzaVBhZ2VUeXBlIjoiY2hhbm5lbHMiLCJkYXRhc3luY0lkIjoiVmVhMzA3OWZifHwifSwiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfU0hPUlRTIjp7InJvb3RFbGVtZW50SWQiOiJzaG9ydHMtcGxheWVyIiwianNVcmwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvcGxheWVyX2lhcy52ZmxzZXQvZnJfRlIvYmFzZS5qcyIsImNzc1VybCI6Ii9zL3BsYXllci9iMTI4ZGRhMC93d3ctcGxheWVyLmNzcyIsImNvbnRleHRJZCI6IldFQl9QTEFZRVJfQ09OVEVYVF9DT05GSUdfSURfS0VWTEFSX1NIT1JUUyIsImV2ZW50TGFiZWwiOiJzaG9ydHNwYWdlIiwiY29udGVudFJlZ2lvbiI6IkZSIiwiaGwiOiJmcl9GUiIsImhvc3RMYW5ndWFnZSI6ImZyIiwicGxheWVyU3R5bGUiOiJkZXNrdG9wLXBvbHltZXIiLCJpbm5lcnR1YmVBcGlLZXkiOiJBSXphU3lBT19GSjJTbHFVOFE0U1RFSExHQ2lsd19ZOV8xMXFjVzgiLCJpbm5lcnR1YmVBcGlWZXJzaW9uIjoidjEiLCJpbm5lcnR1YmVDb250ZXh0Q2xpZW50VmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJjb250cm9sc1R5cGUiOjAsImRpc2FibGVLZXlib2FyZENvbnRyb2xzIjp0cnVlLCJkaXNhYmxlUmVsYXRlZFZpZGVvcyI6dHJ1ZSwiYW5ub3RhdGlvbnNMb2FkUG9saWN5IjozLCJkZXZpY2UiOnsiYnJhbmQiOiIiLCJtb2RlbCI6IiIsInBsYXRmb3JtIjoiREVTS1RPUCIsImludGVyZmFjZU5hbWUiOiJXRUIiLCJpbnRlcmZhY2VWZXJzaW9uIjoiMi4yMDIzMDYwNy4wNi4wMCJ9LCJzZXJpYWxpemVkRXhwZXJpbWVudElkcyI6IjIzODU4MDU3LDIzOTgzMjk2LDIzOTg2MDMzLDI0MDA0NjQ0LDI0MDA3MjQ2LDI0MDgwNzM4LDI0MTM1MzEwLDI0MzYyNjg1LDI0MzYyNjg4LDI0MzYzMTE0LDI0MzY0Nzg5LDI0MzY2OTE3LDI0MzcwODk4LDI0Mzc3MzQ2LDI0NDE1ODY0LDI0NDMzNjc5LDI0NDM3NTc3LDI0NDM5MzYxLDI0NDkyNTQ3LDI0NTMyODU1LDI0NTUwNDU4LDI0NTUwOTUxLDI0NTU4NjQxLDI0NTU5MzI2LDI0Njk5ODk5LDM5MzIzMDc0Iiwic2VyaWFsaXplZEV4cGVyaW1lbnRGbGFncyI6Ikg1X2FzeW5jX2xvZ2dpbmdfZGVsYXlfbXNcdTAwM2QzMDAwMC4wXHUwMDI2SDVfZW5hYmxlX2Z1bGxfcGFjZl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNkg1X3VzZV9hc3luY19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmFjdGlvbl9jb21wYW5pb25fY2VudGVyX2FsaWduX2Rlc2NyaXB0aW9uXHUwMDNkdHJ1ZVx1MDAyNmFkX3BvZF9kaXNhYmxlX2NvbXBhbmlvbl9wZXJzaXN0X2Fkc19xdWFsaXR5XHUwMDNkdHJ1ZVx1MDAyNmFkZHRvX2FqYXhfbG9nX3dhcm5pbmdfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZhbGlnbl9hZF90b192aWRlb19wbGF5ZXJfbGlmZWN5Y2xlX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X2xpdmVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2YWxsb3dfcG9sdGVyZ3VzdF9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19za2lwX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNmF1dG9wbGF5X3RpbWVcdTAwM2Q4MDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfZnVsbHNjcmVlblx1MDAzZDMwMDBcdTAwMjZhdXRvcGxheV90aW1lX2Zvcl9tdXNpY19jb250ZW50XHUwMDNkMzAwMFx1MDAyNmJnX3ZtX3JlaW5pdF90aHJlc2hvbGRcdTAwM2Q3MjAwMDAwXHUwMDI2YmxvY2tlZF9wYWNrYWdlc19mb3Jfc3BzXHUwMDNkW11cdTAwMjZib3RndWFyZF9hc3luY19zbmFwc2hvdF90aW1lb3V0X21zXHUwMDNkMzAwMFx1MDAyNmNoZWNrX2FkX3VpX3N0YXR1c19mb3JfbXdlYl9zYWZhcmlcdTAwM2R0cnVlXHUwMDI2Y2hlY2tfbmF2aWdhdG9yX2FjY3VyYWN5X3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2Y2xlYXJfdXNlcl9wYXJ0aXRpb25lZF9sc1x1MDAzZHRydWVcdTAwMjZjbGllbnRfcmVzcGVjdF9hdXRvcGxheV9zd2l0Y2hfYnV0dG9uX3JlbmRlcmVyXHUwMDNkdHJ1ZVx1MDAyNmNvbXByZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZjb21wcmVzc2lvbl9kaXNhYmxlX3BvaW50XHUwMDNkMTBcdTAwMjZjb21wcmVzc2lvbl9wZXJmb3JtYW5jZV90aHJlc2hvbGRcdTAwM2QyNTBcdTAwMjZjc2lfb25fZ2VsXHUwMDNkdHJ1ZVx1MDAyNmRhc2hfbWFuaWZlc3RfdmVyc2lvblx1MDAzZDVcdTAwMjZkZWJ1Z19iYW5kYWlkX2hvc3RuYW1lXHUwMDNkXHUwMDI2ZGVidWdfc2hlcmxvZ191c2VybmFtZVx1MDAzZFx1MDAyNmRlbGF5X2Fkc19ndmlfY2FsbF9vbl9idWxsZWl0X2xpdmluZ19yb29tX21zXHUwMDNkMFx1MDAyNmRlcHJlY2F0ZV9jc2lfaGFzX2luZm9cdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3BhaXJfc2VydmxldF9lbmFibGVkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfY2hpbGRcdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19wYXJlbnRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9pbWFnZV9jdGFfbm9fYmFja2dyb3VuZFx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX2xvZ19pbWdfY2xpY2tfbG9jYXRpb25cdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9zcGFya2xlc19saWdodF9jdGFfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfY2hhbm5lbF9pZF9jaGVja19mb3Jfc3VzcGVuZGVkX2NoYW5uZWxzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfY2hpbGRfbm9kZV9hdXRvX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfZGVmZXJfYWRtb2R1bGVfb25fYWR2ZXJ0aXNlcl92aWRlb1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2ZlYXR1cmVzX2Zvcl9zdXBleFx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2xlZ2FjeV9kZXNrdG9wX3JlbW90ZV9xdWV1ZVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX21keF9jb25uZWN0aW9uX2luX21keF9tb2R1bGVfZm9yX211c2ljX3dlYlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX25ld19wYXVzZV9zdGF0ZTNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9wYWNmX2xvZ2dpbmdfZm9yX21lbW9yeV9saW1pdGVkX3R2XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcm91bmRpbmdfYWRfbm90aWZ5XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfc2ltcGxlX21peGVkX2RpcmVjdGlvbl9mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NzZGFpX29uX2Vycm9yc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3RhYmJpbmdfYmVmb3JlX2ZseW91dF9hZF9lbGVtZW50c19hcHBlYXJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90aHVtYm5haWxfcHJlbG9hZGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZGlzYWJsZV9wcm9ncmVzc19iYXJfY29udGV4dF9tZW51X2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc19lbmFibGVfYWxsb3dfd2F0Y2hfYWdhaW5fZW5kc2NyZWVuX2Zvcl9lbGlnaWJsZV9zaG9ydHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3ZlX2NvbnZlcnNpb25fcGFyYW1fcmVuYW1pbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfYXV0b3BsYXlfbm90X3N1cHBvcnRlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9jdWVfdmlkZW9fdW5wbGF5YWJsZV9maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfaG91c2VfYnJhbmRfYW5kX3l0X2NvZXhpc3RlbmNlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvYWRfcGxheWVyX2Zyb21fcGFnZV9zaG93XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvZ19zcGxheV9hc19hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dnaW5nX2V2ZW50X2hhbmRsZXJzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX21vYmlsZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfZHR0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9uZXdfY29udGV4dF9tZW51X3RyaWdnZXJpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGF1c2Vfb3ZlcmxheV93bl91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGVtX2RvbWFpbl9maXhfZm9yX2FkX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BmcF91bmJyYW5kZWRfZWxfZGVwcmVjYXRpb25cdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcmNhdF9hbGxvd2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcmVwbGFjZV91bmxvYWRfd19wYWdlaGlkZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9zY3JpcHRlZF9wbGF5YmFja19ibG9ja2VkX2xvZ2dpbmdfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3ZlX2NvbnZlcnNpb25fbG9nZ2luZ190cmFja2luZ19ub19hbGxvd19saXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfaGlkZV91bmZpbGxlZF9tb3JlX3ZpZGVvc19zdWdnZXN0aW9uc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2xpdGVfbW9kZVx1MDAzZDFcdTAwMjZlbWJlZHNfd2ViX253bF9kaXNhYmxlX25vY29va2llXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfc2hvcHBpbmdfb3ZlcmxheV9ub193YWl0X2Zvcl9wYWlkX2NvbnRlbnRfb3ZlcmxheVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3N5bnRoX2NoX2hlYWRlcnNfYmFubmVkX3VybHNfcmVnZXhcdTAwM2RcdTAwMjZlbmFibGVfYWJfcnBfaW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9hZF9jcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfYXBwX3Byb21vX2VuZGNhcF9lbWxfb25fdGFibGV0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jYXN0X2Zvcl93ZWJfdW5wbHVnZ2VkXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jYXN0X29uX211c2ljX3dlYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2xpZW50X3BhZ2VfaWRfaGVhZGVyX2Zvcl9maXJzdF9wYXJ0eV9waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfY2xpZW50X3NsaV9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9kaXNjcmV0ZV9saXZlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZF93ZWJfY2xpZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZF93ZWJfY2xpZW50X2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZHNfaWNvbl93ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2V2aWN0aW9uX3Byb3RlY3Rpb25fZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2dlbF9sb2dfY29tbWFuZHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X2luc3RyZWFtX3dhdGNoX25leHRfcGFyYW1zX29hcmxpYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfaDVfdmlkZW9fYWRzX29hcmxpYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfaGFuZGxlc19hY2NvdW50X21lbnVfc3dpdGNoZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2thYnVraV9jb21tZW50c19vbl9zaG9ydHNcdTAwM2RkaXNhYmxlZFx1MDAyNmVuYWJsZV9saXZlX3ByZW1pZXJlX3dlYl9wbGF5ZXJfaW5kaWNhdG9yXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9scl9ob21lX2luZmVlZF9hZHNfaW5saW5lX3BsYXliYWNrX3Byb2dyZXNzX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX213ZWJfbGl2ZXN0cmVhbV91aV91cGRhdGVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX25ld19wYWlkX3Byb2R1Y3RfcGxhY2VtZW50XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Nsb3RfYXNkZV9wbGF5ZXJfYnl0ZV9oNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2X2Zvcl9wYWdlX3RvcF9mb3JtYXRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeXNmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFzc19zZGNfZ2V0X2FjY291bnRzX2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BsX3JfY1x1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9maXhfb25fdHZodG1sNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcG9zdF9hZF9wZXJjZXB0aW9uX3N1cnZleV9pbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zZXJ2ZXJfc3RpdGNoZWRfZGFpXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9zaG9ydHNfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwX2FkX2d1aWRhbmNlX3Byb21wdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2tpcHBhYmxlX2Fkc19mb3JfdW5wbHVnZ2VkX2FkX3BvZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfdGVjdG9uaWNfYWRfdXhfZm9yX2hhbGZ0aW1lXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90aGlyZF9wYXJ0eV9pbmZvXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90b3Bzb2lsX3d0YV9mb3JfaGFsZnRpbWVfbGl2ZV9pbmZyYVx1MDAzZHRydWVcdTAwMjZlbmFibGVfd2ViX21lZGlhX3Nlc3Npb25fbWV0YWRhdGFfZml4XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfc2NoZWR1bGVyX3NpZ25hbHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3l0X2F0YV9pZnJhbWVfYXV0aHVzZXJcdTAwM2R0cnVlXHUwMDI2ZXJyb3JfbWVzc2FnZV9mb3JfZ3N1aXRlX25ldHdvcmtfcmVzdHJpY3Rpb25zXHUwMDNkdHJ1ZVx1MDAyNmV4cG9ydF9uZXR3b3JrbGVzc19vcHRpb25zXHUwMDNkdHJ1ZVx1MDAyNmV4dGVybmFsX2Z1bGxzY3JlZW5fd2l0aF9lZHVcdTAwM2R0cnVlXHUwMDI2ZmFzdF9hdXRvbmF2X2luX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZmV0Y2hfYXR0X2luZGVwZW5kZW50bHlcdTAwM2R0cnVlXHUwMDI2ZmlsbF9zaW5nbGVfdmlkZW9fd2l0aF9ub3RpZnlfdG9fbGFzclx1MDAzZHRydWVcdTAwMjZmaWx0ZXJfdnA5X2Zvcl9jc2RhaVx1MDAzZHRydWVcdTAwMjZmaXhfYWRzX3RyYWNraW5nX2Zvcl9zd2ZfY29uZmlnX2RlcHJlY2F0aW9uX213ZWJcdTAwM2R0cnVlXHUwMDI2Z2NmX2NvbmZpZ19zdG9yZV9lbmFibGVkXHUwMDNkdHJ1ZVx1MDAyNmdlbF9xdWV1ZV90aW1lb3V0X21heF9tc1x1MDAzZDMwMDAwMFx1MDAyNmdwYV9zcGFya2xlc190ZW5fcGVyY2VudF9sYXllclx1MDAzZHRydWVcdTAwMjZndmlfY2hhbm5lbF9jbGllbnRfc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmg1X2NvbXBhbmlvbl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfZ2VuZXJpY19lcnJvcl9sb2dnaW5nX2V2ZW50XHUwMDNkdHJ1ZVx1MDAyNmg1X2VuYWJsZV91bmlmaWVkX2NzaV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmg1X2lucGxheWVyX2VuYWJsZV9hZGNwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmg1X3Jlc2V0X2NhY2hlX2FuZF9maWx0ZXJfYmVmb3JlX3VwZGF0ZV9tYXN0aGVhZFx1MDAzZHRydWVcdTAwMjZoZWF0c2Vla2VyX2RlY29yYXRpb25fdGhyZXNob2xkXHUwMDNkMC4wXHUwMDI2aGZyX2Ryb3BwZWRfZnJhbWVyYXRlX2ZhbGxiYWNrX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZoaWRlX2VuZHBvaW50X292ZXJmbG93X29uX3l0ZF9kaXNwbGF5X2FkX3JlbmRlcmVyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2FkX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfYWRzX3ByZXJvbGxfbG9ja190aW1lb3V0X2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9hbGxvd19kaXNjb250aWd1b3VzX3NsaWNlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9hbGxvd192aWRlb19rZXlmcmFtZV93aXRob3V0X2F1ZGlvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F0dGFjaF9udW1fcmFuZG9tX2J5dGVzX3RvX2JhbmRhaWRcdTAwM2QwXHUwMDI2aHRtbDVfYXR0YWNoX3BvX3Rva2VuX3RvX2JhbmRhaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYXV0b25hdl9jYXBfaWRsZV9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X2F1dG9uYXZfcXVhbGl0eV9jYXBcdTAwM2Q3MjBcdTAwMjZodG1sNV9hdXRvcGxheV9kZWZhdWx0X3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2Jsb2NrX3BpcF9zYWZhcmlfZGVsYXlcdTAwM2QwXHUwMDI2aHRtbDVfYm1mZl9uZXdfZm91cmNjX2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2NvYmFsdF9kZWZhdWx0X2J1ZmZlcl9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9tYXhfc2l6ZV9mb3JfaW1tZWRfam9iXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9taW5fcHJvY2Vzc29yX2NudF90b19vZmZsb2FkX2FsZ29cdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X292ZXJyaWRlX3F1aWNcdTAwM2QwXHUwMDI2aHRtbDVfY29uc3VtZV9tZWRpYV9ieXRlc19zbGljZV9pbmZvc1x1MDAzZHRydWVcdTAwMjZodG1sNV9kZV9kdXBlX2NvbnRlbnRfdmlkZW9fbG9hZHNfaW5fbGlmZWN5Y2xlX2FwaVx1MDAzZHRydWVcdTAwMjZodG1sNV9kZWJ1Z19kYXRhX2xvZ19wcm9iYWJpbGl0eVx1MDAzZDAuMVx1MDAyNmh0bWw1X2RlY29kZV90b190ZXh0dXJlX2NhcFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZWZhdWx0X2FkX2dhaW5cdTAwM2QwLjVcdTAwMjZodG1sNV9kZWZhdWx0X3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2RlZmVyX2FkX21vZHVsZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9mZXRjaF9hdHRfbXNcdTAwM2QxMDAwXHUwMDI2aHRtbDVfZGVmZXJfbW9kdWxlc19kZWxheV90aW1lX21pbGxpc1x1MDAzZDBcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2NvdW50XHUwMDNkMVx1MDAyNmh0bWw1X2RlbGF5ZWRfcmV0cnlfZGVsYXlfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfZGVwcmVjYXRlX3ZpZGVvX3RhZ19wb29sXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rlc2t0b3BfdnIxODBfYWxsb3dfcGFubmluZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9kZl9kb3duZ3JhZGVfdGhyZXNoXHUwMDNkMC4yXHUwMDI2aHRtbDVfZGlzYWJsZV9jc2lfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9tb3ZlX3Bzc2hfdG9fbW9vdlx1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNhYmxlX25vbl9jb250aWd1b3VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc3BsYXllZF9mcmFtZV9yYXRlX2Rvd25ncmFkZV90aHJlc2hvbGRcdTAwM2Q0NVx1MDAyNmh0bWw1X2RybV9jaGVja19hbGxfa2V5X2Vycm9yX3N0YXRlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9kcm1fY3BpX2xpY2Vuc2Vfa2V5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hYzNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2Fkc19jbGllbnRfbW9uaXRvcmluZ19sb2dfdHZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NhcHRpb25fY2hhbmdlc19mb3JfbW9zYWljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jbGllbnRfaGludHNfb3ZlcnJpZGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NvbXBvc2l0ZV9lbWJhcmdvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9lYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9lbWJlZGRlZF9wbGF5ZXJfdmlzaWJpbGl0eV9zaWduYWxzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9uZXdfaHZjX2VuY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbm9uX25vdGlmeV9jb21wb3NpdGVfdm9kX2xzYXJfcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfc2luZ2xlX3ZpZGVvX3ZvZF9pdmFyX29uX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZGFzaFx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19lbmNyeXB0ZWRfdnA5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfYWxjXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV93aWRldmluZV9mb3JfZmFzdF9saW5lYXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5jb3VyYWdlX2FycmF5X2NvYWxlc2NpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2FwbGVzc19lbmRlZF90cmFuc2l0aW9uX2J1ZmZlcl9tc1x1MDAzZDIwMFx1MDAyNmh0bWw1X2dlbmVyYXRlX3Nlc3Npb25fcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZ2xfZnBzX3RocmVzaG9sZFx1MDAzZDBcdTAwMjZodG1sNV9oZGNwX3Byb2Jpbmdfc3RyZWFtX3VybFx1MDAzZFx1MDAyNmh0bWw1X2hmcl9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QxLjBcdTAwMjZodG1sNV9pZGxlX3JhdGVfbGltaXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX2ZhaXJwbGF5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9wbGF5cmVhZHlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3dpZGV2aW5lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczRfc2Vla19hYm92ZV96ZXJvXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvczdfZm9yY2VfcGxheV9vbl9zdGFsbFx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3NfZm9yY2Vfc2Vla190b196ZXJvX29uX3N0b3BcdTAwM2R0cnVlXHUwMDI2aHRtbDVfanVtYm9fbW9iaWxlX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDMuMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9ub25zdHJlYW1pbmdfbWZmYV9tc1x1MDAzZDQwMDBcdTAwMjZodG1sNV9qdW1ib191bGxfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMS4zXHUwMDI2aHRtbDVfbGljZW5zZV9jb25zdHJhaW50X2RlbGF5XHUwMDNkNTAwMFx1MDAyNmh0bWw1X2xpdmVfYWJyX2hlYWRfbWlzc19mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYWJyX3JlcHJlZGljdF9mcmFjdGlvblx1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfYnl0ZXJhdGVfZmFjdG9yX2Zvcl9yZWFkYWhlYWRcdTAwM2QxLjNcdTAwMjZodG1sNV9saXZlX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9saXZlX25vcm1hbF9sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2xpdmVfdWx0cmFfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xvZ19hdWRpb19hYnJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX2V4cGVyaW1lbnRfaWRfZnJvbV9wbGF5ZXJfcmVzcG9uc2VfdG9fY3RtcFx1MDAzZFx1MDAyNmh0bWw1X2xvZ19maXJzdF9zc2RhaV9yZXF1ZXN0c19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19yZWJ1ZmZlcl9ldmVudHNcdTAwM2Q1XHUwMDI2aHRtbDVfbG9nX3NzZGFpX2ZhbGxiYWNrX2Fkc1x1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfdHJpZ2dlcl9ldmVudHNfd2l0aF9kZWJ1Z19kYXRhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX3RocmVzaG9sZF9tc1x1MDAzZDMwMDAwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3NlZ19kcmlmdF9saW1pdF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc191bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3ZwOV9vdGZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWF4X2RyaWZ0X3Blcl90cmFja19zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWF4X2hlYWRtX2Zvcl9zdHJlYW1pbmdfeGhyXHUwMDNkMFx1MDAyNmh0bWw1X21heF9saXZlX2R2cl93aW5kb3dfcGx1c19tYXJnaW5fc2Vjc1x1MDAzZDQ2ODAwLjBcdTAwMjZodG1sNV9tYXhfcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21heF9yZWRpcmVjdF9yZXNwb25zZV9sZW5ndGhcdTAwM2Q4MTkyXHUwMDI2aHRtbDVfbWF4X3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21heF9zb3VyY2VfYnVmZmVyX2FwcGVuZF9zaXplX2luX2J5dGVzXHUwMDNkMFx1MDAyNmh0bWw1X21heGltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9tZWRpYV9mdWxsc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21mbF9leHRlbmRfbWF4X3JlcXVlc3RfdGltZVx1MDAzZHRydWVcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9jYXBfc2Vjc1x1MDAzZDYwXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9taW5fc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfYWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbm9fcGxhY2Vob2xkZXJfcm9sbGJhY2tzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vbl9uZXR3b3JrX3JlYnVmZmVyX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X25vbl9vbmVzaWVfYXR0YWNoX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X25vdF9yZWdpc3Rlcl9kaXNwb3NhYmxlc193aGVuX2NvcmVfbGlzdGVuc1x1MDAzZHRydWVcdTAwMjZodG1sNV9vZmZsaW5lX2ZhaWx1cmVfcmV0cnlfbGltaXRcdTAwM2QyXHUwMDI2aHRtbDVfb25lc2llX2RlZmVyX2NvbnRlbnRfbG9hZGVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9ob3N0X3JhY2luZ19jYXBfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2lnbm9yZV9pbm5lcnR1YmVfYXBpX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbGl2ZV90dGxfc2Vjc1x1MDAzZDhcdTAwMjZodG1sNV9vbmVzaWVfbm9uemVyb19wbGF5YmFja19zdGFydFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfbm90aWZ5X2N1ZXBvaW50X21hbmFnZXJfb25fY29tcGxldGlvblx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9jb29sZG93bl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9pbnRlcnZhbF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcHJld2FybV9tYXhfbGFjdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlcXVlc3RfdGltZW91dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9vbmVzaWVfc3RpY2t5X3NlcnZlcl9zaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BhdXNlX29uX25vbmZvcmVncm91bmRfcGxhdGZvcm1fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlYWtfc2hhdmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZl9jYXBfb3ZlcnJpZGVfc3RpY2t5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2NhcF9mbG9vclx1MDAzZDM2MFx1MDAyNmh0bWw1X3BlcmZvcm1hbmNlX2ltcGFjdF9wcm9maWxpbmdfdGltZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcGVyc2VydmVfYXYxX3BlcmZfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX2JhY2twcmVzc3VyZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF0Zm9ybV9taW5pbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfcGxheWVyX2F1dG9uYXZfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfZHluYW1pY19ib3R0b21fZ3JhZGllbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxheWVyX21pbl9idWlsZF9jbFx1MDAzZC0xXHUwMDI2aHRtbDVfcGxheWVyX3ByZWxvYWRfYWRfZml4XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Bvc3RfaW50ZXJydXB0X3JlYWRhaGVhZFx1MDAzZDIwXHUwMDI2aHRtbDVfcHJlZmVyX3NlcnZlcl9id2UzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ByZWxvYWRfd2FpdF90aW1lX3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9wcm9iZV9wcmltYXJ5X2RlbGF5X2Jhc2VfbXNcdTAwM2QwXHUwMDI2aHRtbDVfcHJvY2Vzc19hbGxfZW5jcnlwdGVkX2V2ZW50c1x1MDAzZHRydWVcdTAwMjZodG1sNV9xb2VfbGhfbWF4X3JlcG9ydF9jb3VudFx1MDAzZDBcdTAwMjZodG1sNV9xb2VfbGhfbWluX2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNmh0bWw1X3F1ZXJ5X3N3X3NlY3VyZV9jcnlwdG9fZm9yX2FuZHJvaWRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmFuZG9tX3BsYXliYWNrX2NhcFx1MDAzZDBcdTAwMjZodG1sNV9yZWNvZ25pemVfcHJlZGljdF9zdGFydF9jdWVfcG9pbnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX2NvbW1hbmRfdHJpZ2dlcmVkX2NvbXBhbmlvbnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVtb3ZlX25vdF9zZXJ2YWJsZV9jaGVja19raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbmFtZV9hcGJzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9mYXRhbF9kcm1fcmVzdHJpY3RlZF9lcnJvcl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcG9ydF9zbG93X2Fkc19hc19lcnJvclx1MDAzZHRydWVcdTAwMjZodG1sNV9yZXF1ZXN0X29ubHlfaGRyX29yX3Nkcl9rZXlzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfc2l6aW5nX211bHRpcGxpZXJcdTAwM2QwLjhcdTAwMjZodG1sNV9yZXNldF9tZWRpYV9zdHJlYW1fb25fdW5yZXN1bWFibGVfc2xpY2VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Jlc291cmNlX2JhZF9zdGF0dXNfZGVsYXlfc2NhbGluZ1x1MDAzZDEuNVx1MDAyNmh0bWw1X3Jlc3RyaWN0X3N0cmVhbWluZ194aHJfb25fc3FsZXNzX3JlcXVlc3RzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NhZmFyaV9kZXNrdG9wX2VtZV9taW5fdmVyc2lvblx1MDAzZDBcdTAwMjZodG1sNV9zYW1zdW5nX2thbnRfbGltaXRfbWF4X2JpdHJhdGVcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19qaWdnbGVfY210X2RlbGF5X21zXHUwMDNkODAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fZGVsYXlfbXNcdTAwM2QxMjAwMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2J1ZmZlcl9yYW5nZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c192cnNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9jZmxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2Vla19uZXdfbWVkaWFfc291cmNlX3Nob3J0c19yZXVzZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX3NldF9jbXRfZGVsYXlfbXNcdTAwM2QyMDAwXHUwMDI2aHRtbDVfc2Vla190aW1lb3V0X2RlbGF5X21zXHUwMDNkMjAwMDBcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2RlY29yYXRlZF91cmxfcmV0cnlfbGltaXRcdTAwM2Q1XHUwMDI2aHRtbDVfc2VydmVyX3N0aXRjaGVkX2RhaV9ncm91cFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZXNzaW9uX3BvX3Rva2VuX2ludGVydmFsX3RpbWVfbXNcdTAwM2Q5MDAwMDBcdTAwMjZodG1sNV9za2lwX29vYl9zdGFydF9zZWNvbmRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NraXBfc2xvd19hZF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfc2tpcF9zdWJfcXVhbnR1bV9kaXNjb250aW51aXR5X3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X25vX21lZGlhX3NvdXJjZV9kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zbG93X3N0YXJ0X3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NzZGFpX2FkZmV0Y2hfZHluYW1pY190aW1lb3V0X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X3NzZGFpX2VuYWJsZV9uZXdfc2Vla19sb2dpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9zdGF0ZWZ1bF9hdWRpb19taW5fYWRqdXN0bWVudF92YWx1ZVx1MDAzZDBcdTAwMjZodG1sNV9zdGF0aWNfYWJyX3Jlc29sdXRpb25fc2hlbGZcdTAwM2QwXHUwMDI2aHRtbDVfc3RvcmVfeGhyX2hlYWRlcnNfcmVhZGFibGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3RyZWFtaW5nX3hocl9leHBhbmRfcmVxdWVzdF9zaXplXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX2xvYWRfc3BlZWRfY2hlY2tfaW50ZXJ2YWxcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzXHUwMDNkMC4yNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9idWZmZXJfaGVhbHRoX3NlY3Nfb25fdGltZW91dFx1MDAzZDAuMVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9sb2FkX3NwZWVkXHUwMDNkMS41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfc2Vla19sYXRlbmN5X2Z1ZGdlXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0X2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RpbWVvdXRfc2Vjc1x1MDAzZDIuMFx1MDAyNmh0bWw1X3VnY19saXZlX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VnY192b2RfYXVkaW9fNTFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdW5yZXBvcnRlZF9zZWVrX3Jlc2Vla19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV91bnJlc3RyaWN0ZWRfbGF5ZXJfaGlnaF9yZXNfbG9nZ2luZ19wZXJjZW50XHUwMDNkMC4wXHUwMDI2aHRtbDVfdXJsX3BhZGRpbmdfbGVuZ3RoXHUwMDNkMFx1MDAyNmh0bWw1X3VybF9zaWduYXR1cmVfZXhwaXJ5X3RpbWVfaG91cnNcdTAwM2QwXHUwMDI2aHRtbDVfdXNlX3Bvc3RfZm9yX21lZGlhXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VzZV91bXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdmlkZW9fdGJkX21pbl9rYlx1MDAzZDBcdTAwMjZodG1sNV92aWV3cG9ydF91bmRlcnNlbmRfbWF4aW11bVx1MDAzZDAuMFx1MDAyNmh0bWw1X3ZvbHVtZV9zbGlkZXJfdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZodG1sNV93ZWJfZW5hYmxlX2hhbGZ0aW1lX3ByZXJvbGxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2VicG9faWRsZV9wcmlvcml0eV9qb2JcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29mZmxlX3Jlc3VtZVx1MDAzZHRydWVcdTAwMjZodG1sNV93b3JrYXJvdW5kX2RlbGF5X3RyaWdnZXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfeXR2bHJfZW5hYmxlX3NpbmdsZV9zZWxlY3Rfc3VydmV5XHUwMDNkdHJ1ZVx1MDAyNmlnbm9yZV9vdmVybGFwcGluZ19jdWVfcG9pbnRzX29uX2VuZGVtaWNfbGl2ZV9odG1sNVx1MDAzZHRydWVcdTAwMjZpbF91c2Vfdmlld19tb2RlbF9sb2dnaW5nX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2aW5pdGlhbF9nZWxfYmF0Y2hfdGltZW91dFx1MDAzZDIwMDBcdTAwMjZpbmplY3RlZF9saWNlbnNlX2hhbmRsZXJfZXJyb3JfY29kZVx1MDAzZDBcdTAwMjZpbmplY3RlZF9saWNlbnNlX2hhbmRsZXJfbGljZW5zZV9zdGF0dXNcdTAwM2QwXHUwMDI2aXRkcm1faW5qZWN0ZWRfbGljZW5zZV9zZXJ2aWNlX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aXRkcm1fd2lkZXZpbmVfaGFyZGVuZWRfdm1wX21vZGVcdTAwM2Rsb2dcdTAwMjZqc29uX2NvbmRlbnNlZF9yZXNwb25zZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfY29tbWFuZF9oYW5kbGVyX2NvbW1hbmRfYmFubGlzdFx1MDAzZFtdXHUwMDI2a2V2bGFyX2Ryb3Bkb3duX2ZpeFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfZ2VsX2Vycm9yX3JvdXRpbmdcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfZXhwYW5kX3RvcFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllcl9wbGF5X3BhdXNlX29uX3NjcmltXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9wbGF5YmFja19hc3NvY2lhdGVkX3F1ZXVlXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9xdWV1ZV91c2VfdXBkYXRlX2FwaVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc2ltcF9zaG9ydHNfcmVzZXRfc2Nyb2xsXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NtYXJ0X2Rvd25sb2Fkc19zZXR0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl92aW1pb191c2Vfc2hhcmVkX21vbml0b3JcdTAwM2R0cnVlXHUwMDI2bGl2ZV9jaHVua19yZWFkYWhlYWRcdTAwM2QzXHUwMDI2bGl2ZV9mcmVzY2FfdjJcdTAwM2R0cnVlXHUwMDI2bG9nX2Vycm9yc190aHJvdWdoX253bF9vbl9yZXRyeVx1MDAzZHRydWVcdTAwMjZsb2dfZ2VsX2NvbXByZXNzaW9uX2xhdGVuY3lcdTAwM2R0cnVlXHUwMDI2bG9nX2hlYXJ0YmVhdF93aXRoX2xpZmVjeWNsZXNcdTAwM2R0cnVlXHUwMDI2bG9nX3dlYl9lbmRwb2ludF90b19sYXllclx1MDAzZHRydWVcdTAwMjZsb2dfd2luZG93X29uZXJyb3JfZnJhY3Rpb25cdTAwM2QwLjFcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlXHUwMDNkdHJ1ZVx1MDAyNm1hbmlmZXN0bGVzc19wb3N0X2xpdmVfdWZwaFx1MDAzZHRydWVcdTAwMjZtYXhfYm9keV9zaXplX3RvX2NvbXByZXNzXHUwMDNkNTAwMDAwXHUwMDI2bWF4X3ByZWZldGNoX3dpbmRvd19zZWNfZm9yX2xpdmVzdHJlYW1fb3B0aW1pemF0aW9uXHUwMDNkMFx1MDAyNm1heF9yZXNvbHV0aW9uX2Zvcl93aGl0ZV9ub2lzZVx1MDAzZDM2MFx1MDAyNm1keF9lbmFibGVfcHJpdmFjeV9kaXNjbG9zdXJlX3VpXHUwMDNkdHJ1ZVx1MDAyNm1keF9sb2FkX2Nhc3RfYXBpX2Jvb3RzdHJhcF9zY3JpcHRcdTAwM2R0cnVlXHUwMDI2bWlncmF0ZV9ldmVudHNfdG9fdHNcdTAwM2R0cnVlXHUwMDI2bWluX3ByZWZldGNoX29mZnNldF9zZWNfZm9yX2xpdmVzdHJlYW1fb3B0aW1pemF0aW9uXHUwMDNkMTBcdTAwMjZtdXNpY19lbmFibGVfc2hhcmVkX2F1ZGlvX3RpZXJfbG9naWNcdTAwM2R0cnVlXHUwMDI2bXdlYl9jM19lbmRzY3JlZW5cdTAwM2R0cnVlXHUwMDI2bXdlYl9lbmFibGVfY3VzdG9tX2NvbnRyb2xfc2hhcmVkXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX3NraXBwYWJsZXNfb25famlvX3Bob25lXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfbXV0ZWRfYXV0b3BsYXlfYW5pbWF0aW9uXHUwMDNkc2hyaW5rXHUwMDI2bXdlYl9uYXRpdmVfY29udHJvbF9pbl9mYXV4X2Z1bGxzY3JlZW5fc2hhcmVkXHUwMDNkdHJ1ZVx1MDAyNm5ldHdvcmtfcG9sbGluZ19pbnRlcnZhbFx1MDAzZDMwMDAwXHUwMDI2bmV0d29ya2xlc3NfZ2VsXHUwMDNkdHJ1ZVx1MDAyNm5ldHdvcmtsZXNzX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2bmV3X2NvZGVjc19zdHJpbmdfYXBpX3VzZXNfbGVnYWN5X3N0eWxlXHUwMDNkdHJ1ZVx1MDAyNm53bF9zZW5kX2Zhc3Rfb25fdW5sb2FkXHUwMDNkdHJ1ZVx1MDAyNm53bF9zZW5kX2Zyb21fbWVtb3J5X3doZW5fb25saW5lXHUwMDNkdHJ1ZVx1MDAyNm9mZmxpbmVfZXJyb3JfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2cGFjZl9sb2dnaW5nX2RlbGF5X21pbGxpc2Vjb25kc190aHJvdWdoX3liZmVfdHZcdTAwM2QzMDAwMFx1MDAyNnBhZ2VpZF9hc19oZWFkZXJfd2ViXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9hZHNfc2V0X2FkZm9ybWF0X29uX2NsaWVudFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWxsb3dfYXV0b25hdl9hZnRlcl9wbGF5bGlzdFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYm9vdHN0cmFwX21ldGhvZFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZGVmZXJfY2FwdGlvbl9kaXNwbGF5XHUwMDNkMTAwMFx1MDAyNnBsYXllcl9kZXN0cm95X29sZF92ZXJzaW9uXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9kb3VibGV0YXBfdG9fc2Vla1x1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZW5hYmxlX3BsYXliYWNrX3BsYXlsaXN0X2NoYW5nZVx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZW5kc2NyZWVuX2VsbGlwc2lzX2ZpeFx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfdW5kZXJsYXlfbWluX3BsYXllcl93aWR0aFx1MDAzZDc2OC4wXHUwMDI2cGxheWVyX3VuZGVybGF5X3ZpZGVvX3dpZHRoX2ZyYWN0aW9uXHUwMDNkMC42XHUwMDI2cGxheWVyX3dlYl9jYW5hcnlfc3RhZ2VcdTAwM2QwXHUwMDI2cGxheXJlYWR5X2ZpcnN0X3BsYXlfZXhwaXJhdGlvblx1MDAzZC0xXHUwMDI2cG9seW1lcl9iYWRfYnVpbGRfbGFiZWxzXHUwMDNkdHJ1ZVx1MDAyNnBvbHltZXJfbG9nX3Byb3BfY2hhbmdlX29ic2VydmVyX3BlcmNlbnRcdTAwM2QwXHUwMDI2cG9seW1lcl92ZXJpZml5X2FwcF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZwcmVza2lwX2J1dHRvbl9zdHlsZV9hZHNfYmFja2VuZFx1MDAzZGNvdW50ZG93bl9uZXh0X3RvX3RodW1ibmFpbFx1MDAyNnFvZV9ud2xfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNnFvZV9zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZyZWNvcmRfYXBwX2NyYXNoZWRfd2ViXHUwMDNkdHJ1ZVx1MDAyNnJlcGxhY2VfcGxheWFiaWxpdHlfcmV0cmlldmVyX2luX3dhdGNoXHUwMDNkdHJ1ZVx1MDAyNnNjaGVkdWxlcl91c2VfcmFmX2J5X2RlZmF1bHRcdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX2hlYWRlcl9zdHJpbmdfdGVtcGxhdGVcdTAwM2RzZWxmX3BvZGRpbmdfaW50ZXJzdGl0aWFsX21lc3NhZ2VcdTAwMjZzZWxmX3BvZGRpbmdfaGlnaGxpZ2h0X25vbl9kZWZhdWx0X2J1dHRvblx1MDAzZHRydWVcdTAwMjZzZWxmX3BvZGRpbmdfbWlkcm9sbF9jaG9pY2Vfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlXHUwMDI2c2VuZF9jb25maWdfaGFzaF90aW1lclx1MDAzZDBcdTAwMjZzZXRfaW50ZXJzdGl0aWFsX2FkdmVydGlzZXJzX3F1ZXN0aW9uX3RleHRcdTAwM2R0cnVlXHUwMDI2c2hvcnRfc3RhcnRfdGltZV9wcmVmZXJfcHVibGlzaF9pbl93YXRjaF9sb2dcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX21vZGVfdG9fcGxheWVyX2FwaVx1MDAzZHRydWVcdTAwMjZzaG9ydHNfbm9fc3RvcF92aWRlb19jYWxsXHUwMDNkdHJ1ZVx1MDAyNnNob3VsZF9jbGVhcl92aWRlb19kYXRhX29uX3BsYXllcl9jdWVkX3Vuc3RhcnRlZFx1MDAzZHRydWVcdTAwMjZzaW1wbHlfZW1iZWRkZWRfZW5hYmxlX2JvdGd1YXJkXHUwMDNkdHJ1ZVx1MDAyNnNraXBfaW5saW5lX211dGVkX2xpY2Vuc2Vfc2VydmljZV9jaGVja1x1MDAzZHRydWVcdTAwMjZza2lwX2ludmFsaWRfeXRjc2lfdGlja3NcdTAwM2R0cnVlXHUwMDI2c2tpcF9sc19nZWxfcmV0cnlcdTAwM2R0cnVlXHUwMDI2c2tpcF9zZXR0aW5nX2luZm9faW5fY3NpX2RhdGFfb2JqZWN0XHUwMDNkdHJ1ZVx1MDAyNnNsb3dfY29tcHJlc3Npb25zX2JlZm9yZV9hYmFuZG9uX2NvdW50XHUwMDNkNFx1MDAyNnNwZWVkbWFzdGVyX2NhbmNlbGxhdGlvbl9tb3ZlbWVudF9kcFx1MDAzZDBcdTAwMjZzcGVlZG1hc3Rlcl9wbGF5YmFja19yYXRlXHUwMDNkMC4wXHUwMDI2c3BlZWRtYXN0ZXJfdG91Y2hfYWN0aXZhdGlvbl9tc1x1MDAzZDBcdTAwMjZzdGFydF9jbGllbnRfZ2NmXHUwMDNkdHJ1ZVx1MDAyNnN0YXJ0X2NsaWVudF9nY2ZfZm9yX3BsYXllclx1MDAzZHRydWVcdTAwMjZzdGFydF9zZW5kaW5nX2NvbmZpZ19oYXNoXHUwMDNkdHJ1ZVx1MDAyNnN0cmVhbWluZ19kYXRhX2VtZXJnZW5jeV9pdGFnX2JsYWNrbGlzdFx1MDAzZFtdXHUwMDI2c3VwcHJlc3NfZXJyb3JfMjA0X2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2dHJhbnNwb3J0X3VzZV9zY2hlZHVsZXJcdTAwM2R0cnVlXHUwMDI2dHZfcGFjZl9sb2dnaW5nX3NhbXBsZV9yYXRlXHUwMDNkMC4wMVx1MDAyNnR2aHRtbDVfdW5wbHVnZ2VkX3ByZWxvYWRfY2FjaGVfc2l6ZVx1MDAzZDVcdTAwMjZ1bmNvdmVyX2FkX2JhZGdlX29uX1JUTF90aW55X3dpbmRvd1x1MDAzZHRydWVcdTAwMjZ1bnBsdWdnZWRfZGFpX2xpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNnVucGx1Z2dlZF90dmh0bWw1X3ZpZGVvX3ByZWxvYWRfb25fZm9jdXNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2dXBkYXRlX2xvZ19ldmVudF9jb25maWdcdTAwM2R0cnVlXHUwMDI2dXNlX2FjY2Vzc2liaWxpdHlfZGF0YV9vbl9kZXNrdG9wX3BsYXllcl9idXR0b25cdTAwM2R0cnVlXHUwMDI2dXNlX2NvcmVfc21cdTAwM2R0cnVlXHUwMDI2dXNlX2lubGluZWRfcGxheWVyX3JwY1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X2NtbFx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X2luX21lbW9yeV9zdG9yYWdlXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX2luaXRpYWxpemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3Nhd1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zdHdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfd3RzXHUwMDNkdHJ1ZVx1MDAyNnVzZV9wbGF5ZXJfYWJ1c2VfYmdfbGlicmFyeVx1MDAzZHRydWVcdTAwMjZ1c2VfcHJvZmlsZXBhZ2VfZXZlbnRfbGFiZWxfaW5fY2Fyb3VzZWxfcGxheWJhY2tzXHUwMDNkdHJ1ZVx1MDAyNnVzZV9yZXF1ZXN0X3RpbWVfbXNfaGVhZGVyXHUwMDNkdHJ1ZVx1MDAyNnVzZV9zZXNzaW9uX2Jhc2VkX3NhbXBsaW5nXHUwMDNkdHJ1ZVx1MDAyNnVzZV90c192aXNpYmlsaXR5bG9nZ2VyXHUwMDNkdHJ1ZVx1MDAyNnZhcmlhYmxlX2J1ZmZlcl90aW1lb3V0X21zXHUwMDNkMFx1MDAyNnZlcmlmeV9hZHNfaXRhZ19lYXJseVx1MDAzZHRydWVcdTAwMjZ2cDlfZHJtX2xpdmVcdTAwM2R0cnVlXHUwMDI2dnNzX2ZpbmFsX3Bpbmdfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2dnNzX3BpbmdzX3VzaW5nX25ldHdvcmtsZXNzXHUwMDNkdHJ1ZVx1MDAyNnZzc19wbGF5YmFja191c2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2d2ViX2FwaV91cmxcdTAwM2R0cnVlXHUwMDI2d2ViX2FzeW5jX2NvbnRleHRfcHJvY2Vzc29yX2ltcGxcdTAwM2RzdGFuZGFsb25lXHUwMDI2d2ViX2NpbmVtYXRpY193YXRjaF9zZXR0aW5nc1x1MDAzZHRydWVcdTAwMjZ3ZWJfY2xpZW50X3ZlcnNpb25fb3ZlcnJpZGVcdTAwM2RcdTAwMjZ3ZWJfZGVkdXBlX3ZlX2dyYWZ0aW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9kZXByZWNhdGVfc2VydmljZV9hamF4X21hcF9kZXBlbmRlbmN5XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfZXJyb3JfMjA0XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfaW5zdHJlYW1fYWRzX2xpbmtfZGVmaW5pdGlvbl9hMTF5X2J1Z2ZpeFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX3Zvel9hdWRpb19mZWVkYmFja1x1MDAzZHRydWVcdTAwMjZ3ZWJfZml4X2ZpbmVfc2NydWJiaW5nX2RyYWdcdTAwM2R0cnVlXHUwMDI2d2ViX2ZvcmVncm91bmRfaGVhcnRiZWF0X2ludGVydmFsX21zXHUwMDNkMjgwMDBcdTAwMjZ3ZWJfZm9yd2FyZF9jb21tYW5kX29uX3Bialx1MDAzZHRydWVcdTAwMjZ3ZWJfZ2VsX2RlYm91bmNlX21zXHUwMDNkNjAwMDBcdTAwMjZ3ZWJfZ2VsX3RpbWVvdXRfY2FwXHUwMDNkdHJ1ZVx1MDAyNndlYl9pbmxpbmVfcGxheWVyX25vX3BsYXliYWNrX3VpX2NsaWNrX2hhbmRsZXJcdTAwM2R0cnVlXHUwMDI2d2ViX2tleV9tb21lbnRzX21hcmtlcnNcdTAwM2R0cnVlXHUwMDI2d2ViX2xvZ19tZW1vcnlfdG90YWxfa2J5dGVzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dnaW5nX21heF9iYXRjaFx1MDAzZDE1MFx1MDAyNndlYl9tb2Rlcm5fYWRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fYnV0dG9uc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNfYmxfc3VydmV5XHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc2NydWJiZXJcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zdWJzY3JpYmVcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zdWJzY3JpYmVfc3R5bGVcdTAwM2RmaWxsZWRcdTAwMjZ3ZWJfbmV3X2F1dG9uYXZfY291bnRkb3duXHUwMDNkdHJ1ZVx1MDAyNndlYl9vbmVfcGxhdGZvcm1fZXJyb3JfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX29wX3NpZ25hbF90eXBlX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNndlYl9wYXVzZWRfb25seV9taW5pcGxheWVyX3Nob3J0Y3V0X2V4cGFuZFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF9sb2dfY3R0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5YmFja19hc3NvY2lhdGVkX3ZlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYWRkX3ZlX2NvbnZlcnNpb25fbG9nZ2luZ190b19vdXRib3VuZF9saW5rc1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2Fsd2F5c19lbmFibGVfYXV0b190cmFuc2xhdGlvblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FwaV9sb2dnaW5nX2ZyYWN0aW9uXHUwMDNkMC4wMVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl9lbXB0eV9zdWdnZXN0aW9uc19maXhcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X3RvZ2dsZV9hbHdheXNfbGlzdGVuXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl91c2Vfc2VydmVyX3Byb3ZpZGVkX3N0YXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfY2FwdGlvbl9sYW5ndWFnZV9wcmVmZXJlbmNlX3N0aWNraW5lc3NfZHVyYXRpb25cdTAwM2QzMFx1MDAyNndlYl9wbGF5ZXJfZGVjb3VwbGVfYXV0b25hdlx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2Rpc2FibGVfaW5saW5lX3NjcnViYmluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9lYXJseV93YXJuaW5nX3NuYWNrYmFyXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX2ZlYXR1cmVkX3Byb2R1Y3RfYmFubmVyX29uX2Rlc2t0b3BcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfcHJlbWl1bV9oYnJfaW5faDVfYXBpXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX3BsYXliYWNrX2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2lubmVydHViZV9wbGF5bGlzdF91cGRhdGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pcHBfY2FuYXJ5X3R5cGVfZm9yX2xvZ2dpbmdcdTAwM2RcdTAwMjZ3ZWJfcGxheWVyX2xpdmVfbW9uaXRvcl9lbnZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9sb2dfY2xpY2tfYmVmb3JlX2dlbmVyYXRpbmdfdmVfY29udmVyc2lvbl9wYXJhbXNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9tb3ZlX2F1dG9uYXZfdG9nZ2xlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbXVzaWNfdmlzdWFsaXplcl90cmVhdG1lbnRcdTAwM2RmYWtlXHUwMDI2d2ViX3BsYXllcl9tdXRhYmxlX2V2ZW50X2xhYmVsXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbml0cmF0ZV9wcm9tb190b29sdGlwXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfb2ZmbGluZV9wbGF5bGlzdF9hdXRvX3JlZnJlc2hcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9yZXNwb25zZV9wbGF5YmFja190cmFja2luZ19wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2Vla19jaGFwdGVyc19ieV9zaG9ydGN1dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlbnRpbmVsX2lzX3VuaXBsYXllclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3VsZF9ob25vcl9pbmNsdWRlX2Fzcl9zZXR0aW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2hvd19tdXNpY19pbl90aGlzX3ZpZGVvX2dyYXBoaWNcdTAwM2R2aWRlb190aHVtYm5haWxcdTAwMjZ3ZWJfcGxheWVyX3NtYWxsX2hicF9zZXR0aW5nc19tZW51XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc3NfZGFpX2FkX2ZldGNoaW5nX3RpbWVvdXRfbXNcdTAwM2QxNTAwMFx1MDAyNndlYl9wbGF5ZXJfc3NfbWVkaWFfdGltZV9vZmZzZXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90b3BpZnlfc3VidGl0bGVzX2Zvcl9zaG9ydHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90b3VjaF9tb2RlX2ltcHJvdmVtZW50c1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RyYW5zZmVyX3RpbWVvdXRfdGhyZXNob2xkX21zXHUwMDNkMTA4MDAwMDBcdTAwMjZ3ZWJfcGxheWVyX3Vuc2V0X2RlZmF1bHRfY3NuX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl91c2VfbmV3X2FwaV9mb3JfcXVhbGl0eV9wdWxsYmFja1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3ZlX2NvbnZlcnNpb25fZml4ZXNfZm9yX2NoYW5uZWxfaW5mb1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3dhdGNoX25leHRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlX3BhcnNpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3ByZWZldGNoX3ByZWxvYWRfdmlkZW9cdTAwM2R0cnVlXHUwMDI2d2ViX3JvdW5kZWRfdGh1bWJuYWlsc1x1MDAzZHRydWVcdTAwMjZ3ZWJfc2V0dGluZ3NfbWVudV9pY29uc1x1MDAzZHRydWVcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X2R1cmF0aW9uX21zXHUwMDNkMFx1MDAyNndlYl9zbW9vdGhuZXNzX3Rlc3RfbWV0aG9kXHUwMDNkMFx1MDAyNndlYl95dF9jb25maWdfY29udGV4dFx1MDAzZHRydWVcdTAwMjZ3aWxfaWNvbl9yZW5kZXJfd2hlbl9pZGxlXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9jbGVhbl91cF9hZnRlcl9lbnRpdHlfbWlncmF0aW9uXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9lbmFibGVfZG93bmxvYWRfc3RhdHVzXHUwMDNkdHJ1ZVx1MDAyNndvZmZsZV9wbGF5bGlzdF9vcHRpbWl6YXRpb25cdTAwM2R0cnVlXHUwMDI2eXRpZGJfY2xlYXJfZW1iZWRkZWRfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2ZldGNoX2RhdGFzeW5jX2lkc19mb3JfZGF0YV9jbGVhbnVwXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX3JlbWFrZV9kYl9yZXRyaWVzXHUwMDNkMVx1MDAyNnl0aWRiX3Jlb3Blbl9kYl9yZXRyaWVzXHUwMDNkMFx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRcdTAwM2QwLjAyXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdF9zZXNzaW9uXHUwMDNkMC4yXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdF90cmFuc2FjdGlvblx1MDAzZDAuMSIsImhpZGVJbmZvIjp0cnVlLCJkaXNhYmxlRnVsbHNjcmVlbiI6dHJ1ZSwiY3NwTm9uY2UiOiJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIiwiY2FuYXJ5U3RhdGUiOiJub25lIiwiZW5hYmxlQ3NpTG9nZ2luZyI6dHJ1ZSwiZGF0YXN5bmNJZCI6IlZlYTMwNzlmYnx8Iiwic3RvcmVVc2VyVm9sdW1lIjp0cnVlLCJkaXNhYmxlU2VlayI6dHJ1ZSwiZGlzYWJsZVBhaWRDb250ZW50T3ZlcmxheSI6dHJ1ZSwicHJlZmVyR2FwbGVzcyI6dHJ1ZX0sIldFQl9QTEFZRVJfQ09OVEVYVF9DT05GSUdfSURfS0VWTEFSX1NQT05TT1JTSElQU19PRkZFUiI6eyJyb290RWxlbWVudElkIjoieXRkLXNwb25zb3JzaGlwcy1vZmZlci13aXRoLXZpZGVvLXJlbmRlcmVyIiwianNVcmwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvcGxheWVyX2lhcy52ZmxzZXQvZnJfRlIvYmFzZS5qcyIsImNzc1VybCI6Ii9zL3BsYXllci9iMTI4ZGRhMC93d3ctcGxheWVyLmNzcyIsImNvbnRleHRJZCI6IldFQl9QTEFZRVJfQ09OVEVYVF9DT05GSUdfSURfS0VWTEFSX1NQT05TT1JTSElQU19PRkZFUiIsImV2ZW50TGFiZWwiOiJzcG9uc29yc2hpcHNvZmZlciIsImNvbnRlbnRSZWdpb24iOiJGUiIsImhsIjoiZnJfRlIiLCJob3N0TGFuZ3VhZ2UiOiJmciIsInBsYXllclN0eWxlIjoiZGVza3RvcC1wb2x5bWVyIiwiaW5uZXJ0dWJlQXBpS2V5IjoiQUl6YVN5QU9fRkoyU2xxVThRNFNURUhMR0NpbHdfWTlfMTFxY1c4IiwiaW5uZXJ0dWJlQXBpVmVyc2lvbiI6InYxIiwiaW5uZXJ0dWJlQ29udGV4dENsaWVudFZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIiwiZGlzYWJsZVJlbGF0ZWRWaWRlb3MiOnRydWUsImFubm90YXRpb25zTG9hZFBvbGljeSI6MywiZGV2aWNlIjp7ImJyYW5kIjoiIiwibW9kZWwiOiIiLCJwbGF0Zm9ybSI6IkRFU0tUT1AiLCJpbnRlcmZhY2VOYW1lIjoiV0VCIiwiaW50ZXJmYWNlVmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAifSwic2VyaWFsaXplZEV4cGVyaW1lbnRJZHMiOiIyMzg1ODA1NywyMzk4MzI5NiwyMzk4NjAzMywyNDAwNDY0NCwyNDAwNzI0NiwyNDA4MDczOCwyNDEzNTMxMCwyNDM2MjY4NSwyNDM2MjY4OCwyNDM2MzExNCwyNDM2NDc4OSwyNDM2NjkxNywyNDM3MDg5OCwyNDM3NzM0NiwyNDQxNTg2NCwyNDQzMzY3OSwyNDQzNzU3NywyNDQzOTM2MSwyNDQ5MjU0NywyNDUzMjg1NSwyNDU1MDQ1OCwyNDU1MDk1MSwyNDU1ODY0MSwyNDU1OTMyNiwyNDY5OTg5OSwzOTMyMzA3NCIsInNlcmlhbGl6ZWRFeHBlcmltZW50RmxhZ3MiOiJINV9hc3luY19sb2dnaW5nX2RlbGF5X21zXHUwMDNkMzAwMDAuMFx1MDAyNkg1X2VuYWJsZV9mdWxsX3BhY2ZfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZINV91c2VfYXN5bmNfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZhY3Rpb25fY29tcGFuaW9uX2NlbnRlcl9hbGlnbl9kZXNjcmlwdGlvblx1MDAzZHRydWVcdTAwMjZhZF9wb2RfZGlzYWJsZV9jb21wYW5pb25fcGVyc2lzdF9hZHNfcXVhbGl0eVx1MDAzZHRydWVcdTAwMjZhZGR0b19hamF4X2xvZ193YXJuaW5nX2ZyYWN0aW9uXHUwMDNkMC4xXHUwMDI2YWxpZ25fYWRfdG9fdmlkZW9fcGxheWVyX2xpZmVjeWNsZV9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZhbGxvd19saXZlX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X3BvbHRlcmd1c3RfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2YWxsb3dfc2tpcF9uZXR3b3JrbGVzc1x1MDAzZHRydWVcdTAwMjZhdXRvcGxheV90aW1lXHUwMDNkODAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX2Z1bGxzY3JlZW5cdTAwM2QzMDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfbXVzaWNfY29udGVudFx1MDAzZDMwMDBcdTAwMjZiZ192bV9yZWluaXRfdGhyZXNob2xkXHUwMDNkNzIwMDAwMFx1MDAyNmJsb2NrZWRfcGFja2FnZXNfZm9yX3Nwc1x1MDAzZFtdXHUwMDI2Ym90Z3VhcmRfYXN5bmNfc25hcHNob3RfdGltZW91dF9tc1x1MDAzZDMwMDBcdTAwMjZjaGVja19hZF91aV9zdGF0dXNfZm9yX213ZWJfc2FmYXJpXHUwMDNkdHJ1ZVx1MDAyNmNoZWNrX25hdmlnYXRvcl9hY2N1cmFjeV90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmNsZWFyX3VzZXJfcGFydGl0aW9uZWRfbHNcdTAwM2R0cnVlXHUwMDI2Y2xpZW50X3Jlc3BlY3RfYXV0b3BsYXlfc3dpdGNoX2J1dHRvbl9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZjb21wcmVzc19nZWxcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3Npb25fZGlzYWJsZV9wb2ludFx1MDAzZDEwXHUwMDI2Y29tcHJlc3Npb25fcGVyZm9ybWFuY2VfdGhyZXNob2xkXHUwMDNkMjUwXHUwMDI2Y3NpX29uX2dlbFx1MDAzZHRydWVcdTAwMjZkYXNoX21hbmlmZXN0X3ZlcnNpb25cdTAwM2Q1XHUwMDI2ZGVidWdfYmFuZGFpZF9ob3N0bmFtZVx1MDAzZFx1MDAyNmRlYnVnX3NoZXJsb2dfdXNlcm5hbWVcdTAwM2RcdTAwMjZkZWxheV9hZHNfZ3ZpX2NhbGxfb25fYnVsbGVpdF9saXZpbmdfcm9vbV9tc1x1MDAzZDBcdTAwMjZkZXByZWNhdGVfY3NpX2hhc19pbmZvXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV9wYWlyX3NlcnZsZXRfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX2NoaWxkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfcGFyZW50XHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfaW1hZ2VfY3RhX25vX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9sb2dfaW1nX2NsaWNrX2xvY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3Bfc3BhcmtsZXNfbGlnaHRfY3RhX2J1dHRvblx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoYW5uZWxfaWRfY2hlY2tfZm9yX3N1c3BlbmRlZF9jaGFubmVsc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoaWxkX25vZGVfYXV0b19mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2RlZmVyX2FkbW9kdWxlX29uX2FkdmVydGlzZXJfdmlkZW9cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9mZWF0dXJlc19mb3Jfc3VwZXhcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9sZWdhY3lfZGVza3RvcF9yZW1vdGVfcXVldWVcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9tZHhfY29ubmVjdGlvbl9pbl9tZHhfbW9kdWxlX2Zvcl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9uZXdfcGF1c2Vfc3RhdGUzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcGFjZl9sb2dnaW5nX2Zvcl9tZW1vcnlfbGltaXRlZF90dlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3JvdW5kaW5nX2FkX25vdGlmeVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NpbXBsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zc2RhaV9vbl9lcnJvcnNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90YWJiaW5nX2JlZm9yZV9mbHlvdXRfYWRfZWxlbWVudHNfYXBwZWFyXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGh1bWJuYWlsX3ByZWxvYWRpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2Rpc2FibGVfcHJvZ3Jlc3NfYmFyX2NvbnRleHRfbWVudV9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZW5hYmxlX2FsbG93X3dhdGNoX2FnYWluX2VuZHNjcmVlbl9mb3JfZWxpZ2libGVfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc192ZV9jb252ZXJzaW9uX3BhcmFtX3JlbmFtaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2F1dG9wbGF5X25vdF9zdXBwb3J0ZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfY3VlX3ZpZGVvX3VucGxheWFibGVfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2hvdXNlX2JyYW5kX2FuZF95dF9jb2V4aXN0ZW5jZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2FkX3BsYXllcl9mcm9tX3BhZ2Vfc2hvd1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dfc3BsYXlfYXNfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nZ2luZ19ldmVudF9oYW5kbGVyc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2R0dHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbmV3X2NvbnRleHRfbWVudV90cmlnZ2VyaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BhdXNlX292ZXJsYXlfd25fdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BlbV9kb21haW5fZml4X2Zvcl9hZF9yZXF1ZXN0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZnBfdW5icmFuZGVkX2VsX2RlcHJlY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JjYXRfYWxsb3dsaXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JlcGxhY2VfdW5sb2FkX3dfcGFnZWhpZGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfc2NyaXB0ZWRfcGxheWJhY2tfYmxvY2tlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdHJhY2tpbmdfbm9fYWxsb3dfbGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2hpZGVfdW5maWxsZWRfbW9yZV92aWRlb3Nfc3VnZ2VzdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9saXRlX21vZGVcdTAwM2QxXHUwMDI2ZW1iZWRzX3dlYl9ud2xfZGlzYWJsZV9ub2Nvb2tpZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3Nob3BwaW5nX292ZXJsYXlfbm9fd2FpdF9mb3JfcGFpZF9jb250ZW50X292ZXJsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zeW50aF9jaF9oZWFkZXJzX2Jhbm5lZF91cmxzX3JlZ2V4XHUwMDNkXHUwMDI2ZW5hYmxlX2FiX3JwX2ludFx1MDAzZHRydWVcdTAwMjZlbmFibGVfYWRfY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FwcF9wcm9tb19lbmRjYXBfZW1sX29uX3RhYmxldFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9mb3Jfd2ViX3VucGx1Z2dlZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9vbl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9wYWdlX2lkX2hlYWRlcl9mb3JfZmlyc3RfcGFydHlfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9zbGlfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZGlzY3JldGVfbGl2ZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudF9jaGVja1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRzX2ljb25fd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9ldmljdGlvbl9wcm90ZWN0aW9uX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9nZWxfbG9nX2NvbW1hbmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV9pbnN0cmVhbV93YXRjaF9uZXh0X3BhcmFtc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X3ZpZGVvX2Fkc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2hhbmRsZXNfYWNjb3VudF9tZW51X3N3aXRjaGVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9rYWJ1a2lfY29tbWVudHNfb25fc2hvcnRzXHUwMDNkZGlzYWJsZWRcdTAwMjZlbmFibGVfbGl2ZV9wcmVtaWVyZV93ZWJfcGxheWVyX2luZGljYXRvclx1MDAzZHRydWVcdTAwMjZlbmFibGVfbHJfaG9tZV9pbmZlZWRfYWRzX2lubGluZV9wbGF5YmFja19wcm9ncmVzc19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9td2ViX2xpdmVzdHJlYW1fdWlfdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9uZXdfcGFpZF9wcm9kdWN0X3BsYWNlbWVudFx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl9zbG90X2FzZGVfcGxheWVyX2J5dGVfaDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90dl9mb3JfcGFnZV90b3BfZm9ybWF0c1x1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3lzZmVfdHZcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Bhc3Nfc2RjX2dldF9hY2NvdW50c19saXN0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wbF9yX2NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Bvc3RfYWRfcGVyY2VwdGlvbl9zdXJ2ZXlfZml4X29uX3R2aHRtbDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Bvc3RfYWRfcGVyY2VwdGlvbl9zdXJ2ZXlfaW5fdHZodG1sNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcHJlY2lzZV9lbWJhcmdvc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfc2VydmVyX3N0aXRjaGVkX2RhaVx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2hvcnRzX3BsYXllclx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2tpcF9hZF9ndWlkYW5jZV9wcm9tcHRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NraXBwYWJsZV9hZHNfZm9yX3VucGx1Z2dlZF9hZF9wb2RcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RlY3RvbmljX2FkX3V4X2Zvcl9oYWxmdGltZVx1MDAzZHRydWVcdTAwMjZlbmFibGVfdGhpcmRfcGFydHlfaW5mb1x1MDAzZHRydWVcdTAwMjZlbmFibGVfdG9wc29pbF93dGFfZm9yX2hhbGZ0aW1lX2xpdmVfaW5mcmFcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3dlYl9tZWRpYV9zZXNzaW9uX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZlbmFibGVfd2ViX3NjaGVkdWxlcl9zaWduYWxzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV95dF9hdGFfaWZyYW1lX2F1dGh1c2VyXHUwMDNkdHJ1ZVx1MDAyNmVycm9yX21lc3NhZ2VfZm9yX2dzdWl0ZV9uZXR3b3JrX3Jlc3RyaWN0aW9uc1x1MDAzZHRydWVcdTAwMjZleHBvcnRfbmV0d29ya2xlc3Nfb3B0aW9uc1x1MDAzZHRydWVcdTAwMjZleHRlcm5hbF9mdWxsc2NyZWVuX3dpdGhfZWR1XHUwMDNkdHJ1ZVx1MDAyNmZhc3RfYXV0b25hdl9pbl9iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmZldGNoX2F0dF9pbmRlcGVuZGVudGx5XHUwMDNkdHJ1ZVx1MDAyNmZpbGxfc2luZ2xlX3ZpZGVvX3dpdGhfbm90aWZ5X3RvX2xhc3JcdTAwM2R0cnVlXHUwMDI2ZmlsdGVyX3ZwOV9mb3JfY3NkYWlcdTAwM2R0cnVlXHUwMDI2Zml4X2Fkc190cmFja2luZ19mb3Jfc3dmX2NvbmZpZ19kZXByZWNhdGlvbl9td2ViXHUwMDNkdHJ1ZVx1MDAyNmdjZl9jb25maWdfc3RvcmVfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZnZWxfcXVldWVfdGltZW91dF9tYXhfbXNcdTAwM2QzMDAwMDBcdTAwMjZncGFfc3BhcmtsZXNfdGVuX3BlcmNlbnRfbGF5ZXJcdTAwM2R0cnVlXHUwMDI2Z3ZpX2NoYW5uZWxfY2xpZW50X3NjcmVlblx1MDAzZHRydWVcdTAwMjZoNV9jb21wYW5pb25fZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX2dlbmVyaWNfZXJyb3JfbG9nZ2luZ19ldmVudFx1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfdW5pZmllZF9jc2lfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZoNV9pbnBsYXllcl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9yZXNldF9jYWNoZV9hbmRfZmlsdGVyX2JlZm9yZV91cGRhdGVfbWFzdGhlYWRcdTAwM2R0cnVlXHUwMDI2aGVhdHNlZWtlcl9kZWNvcmF0aW9uX3RocmVzaG9sZFx1MDAzZDAuMFx1MDAyNmhmcl9kcm9wcGVkX2ZyYW1lcmF0ZV9mYWxsYmFja190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aGlkZV9lbmRwb2ludF9vdmVyZmxvd19vbl95dGRfZGlzcGxheV9hZF9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZodG1sNV9hZF90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2Fkc19wcmVyb2xsX2xvY2tfdGltZW91dF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfYWxsb3dfZGlzY29udGlndW91c19zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWxsb3dfdmlkZW9fa2V5ZnJhbWVfd2l0aG91dF9hdWRpb1x1MDAzZHRydWVcdTAwMjZodG1sNV9hdHRhY2hfbnVtX3JhbmRvbV9ieXRlc190b19iYW5kYWlkXHUwMDNkMFx1MDAyNmh0bWw1X2F0dGFjaF9wb190b2tlbl90b19iYW5kYWlkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F1dG9uYXZfY2FwX2lkbGVfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9hdXRvbmF2X3F1YWxpdHlfY2FwXHUwMDNkNzIwXHUwMDI2aHRtbDVfYXV0b3BsYXlfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9ibG9ja19waXBfc2FmYXJpX2RlbGF5XHUwMDNkMFx1MDAyNmh0bWw1X2JtZmZfbmV3X2ZvdXJjY19jaGVja1x1MDAzZHRydWVcdTAwMjZodG1sNV9jb2JhbHRfZGVmYXVsdF9idWZmZXJfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWF4X3NpemVfZm9yX2ltbWVkX2pvYlx1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWluX3Byb2Nlc3Nvcl9jbnRfdG9fb2ZmbG9hZF9hbGdvXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9vdmVycmlkZV9xdWljXHUwMDNkMFx1MDAyNmh0bWw1X2NvbnN1bWVfbWVkaWFfYnl0ZXNfc2xpY2VfaW5mb3NcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVfZHVwZV9jb250ZW50X3ZpZGVvX2xvYWRzX2luX2xpZmVjeWNsZV9hcGlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVidWdfZGF0YV9sb2dfcHJvYmFiaWxpdHlcdTAwM2QwLjFcdTAwMjZodG1sNV9kZWNvZGVfdG9fdGV4dHVyZV9jYXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVmYXVsdF9hZF9nYWluXHUwMDNkMC41XHUwMDI2aHRtbDVfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9hZF9tb2R1bGVfbXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfZmV0Y2hfYXR0X21zXHUwMDNkMTAwMFx1MDAyNmh0bWw1X2RlZmVyX21vZHVsZXNfZGVsYXlfdGltZV9taWxsaXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9jb3VudFx1MDAzZDFcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2RlbGF5X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X2RlcHJlY2F0ZV92aWRlb190YWdfcG9vbFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZXNrdG9wX3ZyMTgwX2FsbG93X3Bhbm5pbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGZfZG93bmdyYWRlX3RocmVzaFx1MDAzZDAuMlx1MDAyNmh0bWw1X2Rpc2FibGVfY3NpX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbW92ZV9wc3NoX3RvX21vb3ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9ub25fY29udGlndW91c1x1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNwbGF5ZWRfZnJhbWVfcmF0ZV9kb3duZ3JhZGVfdGhyZXNob2xkXHUwMDNkNDVcdTAwMjZodG1sNV9kcm1fY2hlY2tfYWxsX2tleV9lcnJvcl9zdGF0ZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZHJtX2NwaV9saWNlbnNlX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hZHNfY2xpZW50X21vbml0b3JpbmdfbG9nX3R2XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jYXB0aW9uX2NoYW5nZXNfZm9yX21vc2FpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2xpZW50X2hpbnRzX292ZXJyaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jb21wb3NpdGVfZW1iYXJnb1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZWFjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZW1iZWRkZWRfcGxheWVyX3Zpc2liaWxpdHlfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbmV3X2h2Y19lbmNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX25vbl9ub3RpZnlfY29tcG9zaXRlX3ZvZF9sc2FyX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3NpbmdsZV92aWRlb192b2RfaXZhcl9vbl9wYWNmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV90dm9zX2Rhc2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZW5jcnlwdGVkX3ZwOVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfd2lkZXZpbmVfZm9yX2FsY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfd2lkZXZpbmVfZm9yX2Zhc3RfbGluZWFyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuY291cmFnZV9hcnJheV9jb2FsZXNjaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2dhcGxlc3NfZW5kZWRfdHJhbnNpdGlvbl9idWZmZXJfbXNcdTAwM2QyMDBcdTAwMjZodG1sNV9nZW5lcmF0ZV9zZXNzaW9uX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2dsX2Zwc190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aHRtbDVfaGRjcF9wcm9iaW5nX3N0cmVhbV91cmxcdTAwM2RcdTAwMjZodG1sNV9oZnJfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfaGlnaF9yZXNfbG9nZ2luZ19wZXJjZW50XHUwMDNkMS4wXHUwMDI2aHRtbDVfaWRsZV9yYXRlX2xpbWl0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9mYWlycGxheVx1MDAzZHRydWVcdTAwMjZodG1sNV9pbm5lcnR1YmVfaGVhcnRiZWF0c19mb3JfcGxheXJlYWR5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl93aWRldmluZVx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3M0X3NlZWtfYWJvdmVfemVyb1x1MDAzZHRydWVcdTAwMjZodG1sNV9pb3M3X2ZvcmNlX3BsYXlfb25fc3RhbGxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW9zX2ZvcmNlX3NlZWtfdG9femVyb19vbl9zdG9wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2p1bWJvX21vYmlsZV9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRcdTAwM2QzLjBcdTAwMjZodG1sNV9qdW1ib191bGxfbm9uc3RyZWFtaW5nX21mZmFfbXNcdTAwM2Q0MDAwXHUwMDI2aHRtbDVfanVtYm9fdWxsX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDEuM1x1MDAyNmh0bWw1X2xpY2Vuc2VfY29uc3RyYWludF9kZWxheVx1MDAzZDUwMDBcdTAwMjZodG1sNV9saXZlX2Ficl9oZWFkX21pc3NfZnJhY3Rpb25cdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX2Ficl9yZXByZWRpY3RfZnJhY3Rpb25cdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX2J5dGVyYXRlX2ZhY3Rvcl9mb3JfcmVhZGFoZWFkXHUwMDNkMS4zXHUwMDI2aHRtbDVfbGl2ZV9sb3dfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbGl2ZV9ub3JtYWxfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9saXZlX3VsdHJhX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9sb2dfYXVkaW9fYWJyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19leHBlcmltZW50X2lkX2Zyb21fcGxheWVyX3Jlc3BvbnNlX3RvX2N0bXBcdTAwM2RcdTAwMjZodG1sNV9sb2dfZmlyc3Rfc3NkYWlfcmVxdWVzdHNfa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfcmVidWZmZXJfZXZlbnRzXHUwMDNkNVx1MDAyNmh0bWw1X2xvZ19zc2RhaV9mYWxsYmFja19hZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX3RyaWdnZXJfZXZlbnRzX3dpdGhfZGVidWdfZGF0YVx1MDAzZHRydWVcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl9uZXdfZWxlbV9zaG9ydHNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl90aHJlc2hvbGRfbXNcdTAwM2QzMDAwMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc19zZWdfZHJpZnRfbGltaXRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9tYW5pZmVzdGxlc3NfdW5wbHVnZ2VkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc192cDlfb3RmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21heF9kcmlmdF9wZXJfdHJhY2tfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X21heF9oZWFkbV9mb3Jfc3RyZWFtaW5nX3hoclx1MDAzZDBcdTAwMjZodG1sNV9tYXhfbGl2ZV9kdnJfd2luZG93X3BsdXNfbWFyZ2luX3NlY3NcdTAwM2Q0NjgwMC4wXHUwMDI2aHRtbDVfbWF4X3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9tYXhfcmVkaXJlY3RfcmVzcG9uc2VfbGVuZ3RoXHUwMDNkODE5Mlx1MDAyNmh0bWw1X21heF9zZWxlY3RhYmxlX3F1YWxpdHlfb3JkaW5hbFx1MDAzZDBcdTAwMjZodG1sNV9tYXhfc291cmNlX2J1ZmZlcl9hcHBlbmRfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9tYXhpbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWVkaWFfZnVsbHNjcmVlblx1MDAzZHRydWVcdTAwMjZodG1sNV9tZmxfZXh0ZW5kX21heF9yZXF1ZXN0X3RpbWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfY2FwX3NlY3NcdTAwM2Q2MFx1MDAyNmh0bWw1X21pbl9yZWFkYmVoaW5kX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX2FkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5fc3RhcnR1cF9idWZmZXJlZF9tZWRpYV9kdXJhdGlvbl9zZWNzXHUwMDNkMS4yXHUwMDI2aHRtbDVfbWluaW11bV9yZWFkYWhlYWRfc2Vjb25kc1x1MDAzZDAuMFx1MDAyNmh0bWw1X25vX3BsYWNlaG9sZGVyX3JvbGxiYWNrc1x1MDAzZHRydWVcdTAwMjZodG1sNV9ub25fbmV0d29ya19yZWJ1ZmZlcl9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZodG1sNV9ub25fb25lc2llX2F0dGFjaF9wb190b2tlblx1MDAzZHRydWVcdTAwMjZodG1sNV9ub3RfcmVnaXN0ZXJfZGlzcG9zYWJsZXNfd2hlbl9jb3JlX2xpc3RlbnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb2ZmbGluZV9mYWlsdXJlX3JldHJ5X2xpbWl0XHUwMDNkMlx1MDAyNmh0bWw1X29uZXNpZV9kZWZlcl9jb250ZW50X2xvYWRlcl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfaG9zdF9yYWNpbmdfY2FwX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9pZ25vcmVfaW5uZXJ0dWJlX2FwaV9rZXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX2xpdmVfdHRsX3NlY3NcdTAwM2Q4XHUwMDI2aHRtbDVfb25lc2llX25vbnplcm9fcGxheWJhY2tfc3RhcnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX25vdGlmeV9jdWVwb2ludF9tYW5hZ2VyX29uX2NvbXBsZXRpb25cdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1fY29vbGRvd25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1faW50ZXJ2YWxfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1fbWF4X2xhY3RfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlZGlyZWN0b3JfdGltZW91dFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9yZXF1ZXN0X3RpbWVvdXRfbXNcdTAwM2QxMDAwXHUwMDI2aHRtbDVfb25lc2llX3N0aWNreV9zZXJ2ZXJfc2lkZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wYXVzZV9vbl9ub25mb3JlZ3JvdW5kX3BsYXRmb3JtX2Vycm9yc1x1MDAzZHRydWVcdTAwMjZodG1sNV9wZWFrX3NoYXZlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZfY2FwX292ZXJyaWRlX3N0aWNreVx1MDAzZHRydWVcdTAwMjZodG1sNV9wZXJmb3JtYW5jZV9jYXBfZmxvb3JcdTAwM2QzNjBcdTAwMjZodG1sNV9wZXJmb3JtYW5jZV9pbXBhY3RfcHJvZmlsaW5nX3RpbWVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X3BlcnNlcnZlX2F2MV9wZXJmX2NhcFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF0Zm9ybV9iYWNrcHJlc3N1cmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxhdGZvcm1fbWluaW11bV9yZWFkYWhlYWRfc2Vjb25kc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3BsYXllcl9hdXRvbmF2X2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxheWVyX2R5bmFtaWNfYm90dG9tX2dyYWRpZW50XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXllcl9taW5fYnVpbGRfY2xcdTAwM2QtMVx1MDAyNmh0bWw1X3BsYXllcl9wcmVsb2FkX2FkX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9wb3N0X2ludGVycnVwdF9yZWFkYWhlYWRcdTAwM2QyMFx1MDAyNmh0bWw1X3ByZWZlcl9zZXJ2ZXJfYndlM1x1MDAzZHRydWVcdTAwMjZodG1sNV9wcmVsb2FkX3dhaXRfdGltZV9zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfcHJvYmVfcHJpbWFyeV9kZWxheV9iYXNlX21zXHUwMDNkMFx1MDAyNmh0bWw1X3Byb2Nlc3NfYWxsX2VuY3J5cHRlZF9ldmVudHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcW9lX2xoX21heF9yZXBvcnRfY291bnRcdTAwM2QwXHUwMDI2aHRtbDVfcW9lX2xoX21pbl9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZodG1sNV9xdWVyeV9zd19zZWN1cmVfY3J5cHRvX2Zvcl9hbmRyb2lkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JhbmRvbV9wbGF5YmFja19jYXBcdTAwM2QwXHUwMDI2aHRtbDVfcmVjb2duaXplX3ByZWRpY3Rfc3RhcnRfY3VlX3BvaW50XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbW92ZV9jb21tYW5kX3RyaWdnZXJlZF9jb21wYW5pb25zXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbW92ZV9ub3Rfc2VydmFibGVfY2hlY2tfa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZW5hbWVfYXBic1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZXBvcnRfZmF0YWxfZHJtX3Jlc3RyaWN0ZWRfZXJyb3Jfa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZXBvcnRfc2xvd19hZHNfYXNfZXJyb3JcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVxdWVzdF9vbmx5X2hkcl9vcl9zZHJfa2V5c1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZXF1ZXN0X3NpemluZ19tdWx0aXBsaWVyXHUwMDNkMC44XHUwMDI2aHRtbDVfcmVzZXRfbWVkaWFfc3RyZWFtX29uX3VucmVzdW1hYmxlX3NsaWNlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZXNvdXJjZV9iYWRfc3RhdHVzX2RlbGF5X3NjYWxpbmdcdTAwM2QxLjVcdTAwMjZodG1sNV9yZXN0cmljdF9zdHJlYW1pbmdfeGhyX29uX3NxbGVzc19yZXF1ZXN0c1x1MDAzZHRydWVcdTAwMjZodG1sNV9zYWZhcmlfZGVza3RvcF9lbWVfbWluX3ZlcnNpb25cdTAwM2QwXHUwMDI2aHRtbDVfc2Ftc3VuZ19rYW50X2xpbWl0X21heF9iaXRyYXRlXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDgwMDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX2RlbGF5X21zXHUwMDNkMTIwMDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c19idWZmZXJfcmFuZ2VfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfdnJzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X21lZGlhX3NvdXJjZV9zaG9ydHNfcmV1c2VfY2ZsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NlZWtfbmV3X21lZGlhX3NvdXJjZV9zaG9ydHNfcmV1c2VfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19zZXRfY210X2RlbGF5X21zXHUwMDNkMjAwMFx1MDAyNmh0bWw1X3NlZWtfdGltZW91dF9kZWxheV9tc1x1MDAzZDIwMDAwXHUwMDI2aHRtbDVfc2VydmVyX3N0aXRjaGVkX2RhaV9kZWNvcmF0ZWRfdXJsX3JldHJ5X2xpbWl0XHUwMDNkNVx1MDAyNmh0bWw1X3NlcnZlcl9zdGl0Y2hlZF9kYWlfZ3JvdXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2Vzc2lvbl9wb190b2tlbl9pbnRlcnZhbF90aW1lX21zXHUwMDNkOTAwMDAwXHUwMDI2aHRtbDVfc2tpcF9vb2Jfc3RhcnRfc2Vjb25kc1x1MDAzZHRydWVcdTAwMjZodG1sNV9za2lwX3Nsb3dfYWRfZGVsYXlfbXNcdTAwM2QxNTAwMFx1MDAyNmh0bWw1X3NraXBfc3ViX3F1YW50dW1fZGlzY29udGludWl0eV9zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfc2xvd19zdGFydF9ub19tZWRpYV9zb3VyY2VfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2xvd19zdGFydF90aW1lb3V0X2RlbGF5X21zXHUwMDNkMjAwMDBcdTAwMjZodG1sNV9zc2RhaV9hZGZldGNoX2R5bmFtaWNfdGltZW91dF9tc1x1MDAzZDUwMDBcdTAwMjZodG1sNV9zc2RhaV9lbmFibGVfbmV3X3NlZWtfbG9naWNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3RhdGVmdWxfYXVkaW9fbWluX2FkanVzdG1lbnRfdmFsdWVcdTAwM2QwXHUwMDI2aHRtbDVfc3RhdGljX2Ficl9yZXNvbHV0aW9uX3NoZWxmXHUwMDNkMFx1MDAyNmh0bWw1X3N0b3JlX3hocl9oZWFkZXJzX3JlYWRhYmxlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N0cmVhbWluZ194aHJfZXhwYW5kX3JlcXVlc3Rfc2l6ZVx1MDAzZHRydWVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9sb2FkX3NwZWVkX2NoZWNrX2ludGVydmFsXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuMjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzX29uX3RpbWVvdXRcdTAwM2QwLjFcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fbG9hZF9zcGVlZFx1MDAzZDEuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3NlZWtfbGF0ZW5jeV9mdWRnZVx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldF9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90aW1lb3V0X3NlY3NcdTAwM2QyLjBcdTAwMjZodG1sNV91Z2NfbGl2ZV9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91Z2Nfdm9kX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VucmVwb3J0ZWRfc2Vla19yZXNlZWtfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfdW5yZXN0cmljdGVkX2xheWVyX2hpZ2hfcmVzX2xvZ2dpbmdfcGVyY2VudFx1MDAzZDAuMFx1MDAyNmh0bWw1X3VybF9wYWRkaW5nX2xlbmd0aFx1MDAzZDBcdTAwMjZodG1sNV91cmxfc2lnbmF0dXJlX2V4cGlyeV90aW1lX2hvdXJzXHUwMDNkMFx1MDAyNmh0bWw1X3VzZV9wb3N0X2Zvcl9tZWRpYVx1MDAzZHRydWVcdTAwMjZodG1sNV91c2VfdW1wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ZpZGVvX3RiZF9taW5fa2JcdTAwM2QwXHUwMDI2aHRtbDVfdmlld3BvcnRfdW5kZXJzZW5kX21heGltdW1cdTAwM2QwLjBcdTAwMjZodG1sNV92b2x1bWVfc2xpZGVyX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2ViX2VuYWJsZV9oYWxmdGltZV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYnBvX2lkbGVfcHJpb3JpdHlfam9iXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvZmZsZV9yZXN1bWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29ya2Fyb3VuZF9kZWxheV90cmlnZ2VyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3l0dmxyX2VuYWJsZV9zaW5nbGVfc2VsZWN0X3N1cnZleVx1MDAzZHRydWVcdTAwMjZpZ25vcmVfb3ZlcmxhcHBpbmdfY3VlX3BvaW50c19vbl9lbmRlbWljX2xpdmVfaHRtbDVcdTAwM2R0cnVlXHUwMDI2aWxfdXNlX3ZpZXdfbW9kZWxfbG9nZ2luZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNmluaXRpYWxfZ2VsX2JhdGNoX3RpbWVvdXRcdTAwM2QyMDAwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2xpY2Vuc2Vfc3RhdHVzXHUwMDNkMFx1MDAyNml0ZHJtX2luamVjdGVkX2xpY2Vuc2Vfc2VydmljZV9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNml0ZHJtX3dpZGV2aW5lX2hhcmRlbmVkX3ZtcF9tb2RlXHUwMDNkbG9nXHUwMDI2anNvbl9jb25kZW5zZWRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2NvbW1hbmRfaGFuZGxlcl9jb21tYW5kX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNmtldmxhcl9kcm9wZG93bl9maXhcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2dlbF9lcnJvcl9yb3V0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX2V4cGFuZF90b3BcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfcGxheV9wYXVzZV9vbl9zY3JpbVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcGxheWJhY2tfYXNzb2NpYXRlZF9xdWV1ZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcXVldWVfdXNlX3VwZGF0ZV9hcGlcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NpbXBfc2hvcnRzX3Jlc2V0X3Njcm9sbFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfdmltaW9fdXNlX3NoYXJlZF9tb25pdG9yXHUwMDNkdHJ1ZVx1MDAyNmxpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNmxpdmVfZnJlc2NhX3YyXHUwMDNkdHJ1ZVx1MDAyNmxvZ19lcnJvcnNfdGhyb3VnaF9ud2xfb25fcmV0cnlcdTAwM2R0cnVlXHUwMDI2bG9nX2dlbF9jb21wcmVzc2lvbl9sYXRlbmN5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19oZWFydGJlYXRfd2l0aF9saWZlY3ljbGVzXHUwMDNkdHJ1ZVx1MDAyNmxvZ193ZWJfZW5kcG9pbnRfdG9fbGF5ZXJcdTAwM2R0cnVlXHUwMDI2bG9nX3dpbmRvd19vbmVycm9yX2ZyYWN0aW9uXHUwMDNkMC4xXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZVx1MDAzZHRydWVcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlX3VmcGhcdTAwM2R0cnVlXHUwMDI2bWF4X2JvZHlfc2l6ZV90b19jb21wcmVzc1x1MDAzZDUwMDAwMFx1MDAyNm1heF9wcmVmZXRjaF93aW5kb3dfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDBcdTAwMjZtYXhfcmVzb2x1dGlvbl9mb3Jfd2hpdGVfbm9pc2VcdTAwM2QzNjBcdTAwMjZtZHhfZW5hYmxlX3ByaXZhY3lfZGlzY2xvc3VyZV91aVx1MDAzZHRydWVcdTAwMjZtZHhfbG9hZF9jYXN0X2FwaV9ib290c3RyYXBfc2NyaXB0XHUwMDNkdHJ1ZVx1MDAyNm1pZ3JhdGVfZXZlbnRzX3RvX3RzXHUwMDNkdHJ1ZVx1MDAyNm1pbl9wcmVmZXRjaF9vZmZzZXRfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDEwXHUwMDI2bXVzaWNfZW5hYmxlX3NoYXJlZF9hdWRpb190aWVyX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfYzNfZW5kc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX2N1c3RvbV9jb250cm9sX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9za2lwcGFibGVzX29uX2ppb19waG9uZVx1MDAzZHRydWVcdTAwMjZtd2ViX211dGVkX2F1dG9wbGF5X2FuaW1hdGlvblx1MDAzZHNocmlua1x1MDAyNm13ZWJfbmF0aXZlX2NvbnRyb2xfaW5fZmF1eF9mdWxsc2NyZWVuX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrX3BvbGxpbmdfaW50ZXJ2YWxcdTAwM2QzMDAwMFx1MDAyNm5ldHdvcmtsZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrbGVzc19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNm5ld19jb2RlY3Nfc3RyaW5nX2FwaV91c2VzX2xlZ2FjeV9zdHlsZVx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mYXN0X29uX3VubG9hZFx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mcm9tX21lbW9yeV93aGVuX29ubGluZVx1MDAzZHRydWVcdTAwMjZvZmZsaW5lX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNnBhY2ZfbG9nZ2luZ19kZWxheV9taWxsaXNlY29uZHNfdGhyb3VnaF95YmZlX3R2XHUwMDNkMzAwMDBcdTAwMjZwYWdlaWRfYXNfaGVhZGVyX3dlYlx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWRzX3NldF9hZGZvcm1hdF9vbl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2FsbG93X2F1dG9uYXZfYWZ0ZXJfcGxheWxpc3RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Jvb3RzdHJhcF9tZXRob2RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RlZmVyX2NhcHRpb25fZGlzcGxheVx1MDAzZDEwMDBcdTAwMjZwbGF5ZXJfZGVzdHJveV9vbGRfdmVyc2lvblx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZG91YmxldGFwX3RvX3NlZWtcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuYWJsZV9wbGF5YmFja19wbGF5bGlzdF9jaGFuZ2VcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuZHNjcmVlbl9lbGxpcHNpc19maXhcdTAwM2R0cnVlXHUwMDI2cGxheWVyX3VuZGVybGF5X21pbl9wbGF5ZXJfd2lkdGhcdTAwM2Q3NjguMFx1MDAyNnBsYXllcl91bmRlcmxheV92aWRlb193aWR0aF9mcmFjdGlvblx1MDAzZDAuNlx1MDAyNnBsYXllcl93ZWJfY2FuYXJ5X3N0YWdlXHUwMDNkMFx1MDAyNnBsYXlyZWFkeV9maXJzdF9wbGF5X2V4cGlyYXRpb25cdTAwM2QtMVx1MDAyNnBvbHltZXJfYmFkX2J1aWxkX2xhYmVsc1x1MDAzZHRydWVcdTAwMjZwb2x5bWVyX2xvZ19wcm9wX2NoYW5nZV9vYnNlcnZlcl9wZXJjZW50XHUwMDNkMFx1MDAyNnBvbHltZXJfdmVyaWZpeV9hcHBfc3RhdGVcdTAwM2R0cnVlXHUwMDI2cHJlc2tpcF9idXR0b25fc3R5bGVfYWRzX2JhY2tlbmRcdTAwM2Rjb3VudGRvd25fbmV4dF90b190aHVtYm5haWxcdTAwMjZxb2VfbndsX2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZxb2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2cmVjb3JkX2FwcF9jcmFzaGVkX3dlYlx1MDAzZHRydWVcdTAwMjZyZXBsYWNlX3BsYXlhYmlsaXR5X3JldHJpZXZlcl9pbl93YXRjaFx1MDAzZHRydWVcdTAwMjZzY2hlZHVsZXJfdXNlX3JhZl9ieV9kZWZhdWx0XHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19oZWFkZXJfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX2ludGVyc3RpdGlhbF9tZXNzYWdlXHUwMDI2c2VsZl9wb2RkaW5nX2hpZ2hsaWdodF9ub25fZGVmYXVsdF9idXR0b25cdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZVx1MDAyNnNlbmRfY29uZmlnX2hhc2hfdGltZXJcdTAwM2QwXHUwMDI2c2V0X2ludGVyc3RpdGlhbF9hZHZlcnRpc2Vyc19xdWVzdGlvbl90ZXh0XHUwMDNkdHJ1ZVx1MDAyNnNob3J0X3N0YXJ0X3RpbWVfcHJlZmVyX3B1Ymxpc2hfaW5fd2F0Y2hfbG9nXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19tb2RlX3RvX3BsYXllcl9hcGlcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX25vX3N0b3BfdmlkZW9fY2FsbFx1MDAzZHRydWVcdTAwMjZzaG91bGRfY2xlYXJfdmlkZW9fZGF0YV9vbl9wbGF5ZXJfY3VlZF91bnN0YXJ0ZWRcdTAwM2R0cnVlXHUwMDI2c2ltcGx5X2VtYmVkZGVkX2VuYWJsZV9ib3RndWFyZFx1MDAzZHRydWVcdTAwMjZza2lwX2lubGluZV9tdXRlZF9saWNlbnNlX3NlcnZpY2VfY2hlY2tcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbnZhbGlkX3l0Y3NpX3RpY2tzXHUwMDNkdHJ1ZVx1MDAyNnNraXBfbHNfZ2VsX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNnNraXBfc2V0dGluZ19pbmZvX2luX2NzaV9kYXRhX29iamVjdFx1MDAzZHRydWVcdTAwMjZzbG93X2NvbXByZXNzaW9uc19iZWZvcmVfYWJhbmRvbl9jb3VudFx1MDAzZDRcdTAwMjZzcGVlZG1hc3Rlcl9jYW5jZWxsYXRpb25fbW92ZW1lbnRfZHBcdTAwM2QwXHUwMDI2c3BlZWRtYXN0ZXJfcGxheWJhY2tfcmF0ZVx1MDAzZDAuMFx1MDAyNnNwZWVkbWFzdGVyX3RvdWNoX2FjdGl2YXRpb25fbXNcdTAwM2QwXHUwMDI2c3RhcnRfY2xpZW50X2djZlx1MDAzZHRydWVcdTAwMjZzdGFydF9jbGllbnRfZ2NmX2Zvcl9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2c3RhcnRfc2VuZGluZ19jb25maWdfaGFzaFx1MDAzZHRydWVcdTAwMjZzdHJlYW1pbmdfZGF0YV9lbWVyZ2VuY3lfaXRhZ19ibGFja2xpc3RcdTAwM2RbXVx1MDAyNnN1cHByZXNzX2Vycm9yXzIwNF9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNnRyYW5zcG9ydF91c2Vfc2NoZWR1bGVyXHUwMDNkdHJ1ZVx1MDAyNnR2X3BhY2ZfbG9nZ2luZ19zYW1wbGVfcmF0ZVx1MDAzZDAuMDFcdTAwMjZ0dmh0bWw1X3VucGx1Z2dlZF9wcmVsb2FkX2NhY2hlX3NpemVcdTAwM2Q1XHUwMDI2dW5jb3Zlcl9hZF9iYWRnZV9vbl9SVExfdGlueV93aW5kb3dcdTAwM2R0cnVlXHUwMDI2dW5wbHVnZ2VkX2RhaV9saXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZ1bnBsdWdnZWRfdHZodG1sNV92aWRlb19wcmVsb2FkX29uX2ZvY3VzX2RlbGF5X21zXHUwMDNkMFx1MDAyNnVwZGF0ZV9sb2dfZXZlbnRfY29uZmlnXHUwMDNkdHJ1ZVx1MDAyNnVzZV9hY2Nlc3NpYmlsaXR5X2RhdGFfb25fZGVza3RvcF9wbGF5ZXJfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9jb3JlX3NtXHUwMDNkdHJ1ZVx1MDAyNnVzZV9pbmxpbmVkX3BsYXllcl9ycGNcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19jbWxcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19pbl9tZW1vcnlfc3RvcmFnZVx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9pbml0aWFsaXphdGlvblx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zYXdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc3R3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3d0c1x1MDAzZHRydWVcdTAwMjZ1c2VfcGxheWVyX2FidXNlX2JnX2xpYnJhcnlcdTAwM2R0cnVlXHUwMDI2dXNlX3Byb2ZpbGVwYWdlX2V2ZW50X2xhYmVsX2luX2Nhcm91c2VsX3BsYXliYWNrc1x1MDAzZHRydWVcdTAwMjZ1c2VfcmVxdWVzdF90aW1lX21zX2hlYWRlclx1MDAzZHRydWVcdTAwMjZ1c2Vfc2Vzc2lvbl9iYXNlZF9zYW1wbGluZ1x1MDAzZHRydWVcdTAwMjZ1c2VfdHNfdmlzaWJpbGl0eWxvZ2dlclx1MDAzZHRydWVcdTAwMjZ2YXJpYWJsZV9idWZmZXJfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZ2ZXJpZnlfYWRzX2l0YWdfZWFybHlcdTAwM2R0cnVlXHUwMDI2dnA5X2RybV9saXZlXHUwMDNkdHJ1ZVx1MDAyNnZzc19maW5hbF9waW5nX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnZzc19waW5nc191c2luZ19uZXR3b3JrbGVzc1x1MDAzZHRydWVcdTAwMjZ2c3NfcGxheWJhY2tfdXNlX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9hcGlfdXJsXHUwMDNkdHJ1ZVx1MDAyNndlYl9hc3luY19jb250ZXh0X3Byb2Nlc3Nvcl9pbXBsXHUwMDNkc3RhbmRhbG9uZVx1MDAyNndlYl9jaW5lbWF0aWNfd2F0Y2hfc2V0dGluZ3NcdTAwM2R0cnVlXHUwMDI2d2ViX2NsaWVudF92ZXJzaW9uX292ZXJyaWRlXHUwMDNkXHUwMDI2d2ViX2RlZHVwZV92ZV9ncmFmdGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZGVwcmVjYXRlX3NlcnZpY2VfYWpheF9tYXBfZGVwZW5kZW5jeVx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2Vycm9yXzIwNFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2luc3RyZWFtX2Fkc19saW5rX2RlZmluaXRpb25fYTExeV9idWdmaXhcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV92b3pfYXVkaW9fZmVlZGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX2ZpeF9maW5lX3NjcnViYmluZ19kcmFnXHUwMDNkdHJ1ZVx1MDAyNndlYl9mb3JlZ3JvdW5kX2hlYXJ0YmVhdF9pbnRlcnZhbF9tc1x1MDAzZDI4MDAwXHUwMDI2d2ViX2ZvcndhcmRfY29tbWFuZF9vbl9wYmpcdTAwM2R0cnVlXHUwMDI2d2ViX2dlbF9kZWJvdW5jZV9tc1x1MDAzZDYwMDAwXHUwMDI2d2ViX2dlbF90aW1lb3V0X2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfaW5saW5lX3BsYXllcl9ub19wbGF5YmFja191aV9jbGlja19oYW5kbGVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9rZXlfbW9tZW50c19tYXJrZXJzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dfbWVtb3J5X3RvdGFsX2tieXRlc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nZ2luZ19tYXhfYmF0Y2hcdTAwM2QxNTBcdTAwMjZ3ZWJfbW9kZXJuX2Fkc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zX2JsX3N1cnZleVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3NjcnViYmVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlX3N0eWxlXHUwMDNkZmlsbGVkXHUwMDI2d2ViX25ld19hdXRvbmF2X2NvdW50ZG93blx1MDAzZHRydWVcdTAwMjZ3ZWJfb25lX3BsYXRmb3JtX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9vcF9zaWduYWxfdHlwZV9iYW5saXN0XHUwMDNkW11cdTAwMjZ3ZWJfcGF1c2VkX29ubHlfbWluaXBsYXllcl9zaG9ydGN1dF9leHBhbmRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfbG9nX2N0dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF92ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FkZF92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdG9fb3V0Ym91bmRfbGlua3NcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hbHdheXNfZW5hYmxlX2F1dG9fdHJhbnNsYXRpb25cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hcGlfbG9nZ2luZ19mcmFjdGlvblx1MDAzZDAuMDFcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfZW1wdHlfc3VnZ2VzdGlvbnNfZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl90b2dnbGVfYWx3YXlzX2xpc3Rlblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdXNlX3NlcnZlcl9wcm92aWRlZF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2NhcHRpb25fbGFuZ3VhZ2VfcHJlZmVyZW5jZV9zdGlja2luZXNzX2R1cmF0aW9uXHUwMDNkMzBcdTAwMjZ3ZWJfcGxheWVyX2RlY291cGxlX2F1dG9uYXZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9kaXNhYmxlX2lubGluZV9zY3J1YmJpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZWFybHlfd2FybmluZ19zbmFja2Jhclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9mZWF0dXJlZF9wcm9kdWN0X2Jhbm5lcl9vbl9kZXNrdG9wXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX2luX2g1X2FwaVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9wbGF5YmFja19jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pbm5lcnR1YmVfcGxheWxpc3RfdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaXBwX2NhbmFyeV90eXBlX2Zvcl9sb2dnaW5nXHUwMDNkXHUwMDI2d2ViX3BsYXllcl9saXZlX21vbml0b3JfZW52XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbG9nX2NsaWNrX2JlZm9yZV9nZW5lcmF0aW5nX3ZlX2NvbnZlcnNpb25fcGFyYW1zXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbW92ZV9hdXRvbmF2X3RvZ2dsZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX211c2ljX3Zpc3VhbGl6ZXJfdHJlYXRtZW50XHUwMDNkZmFrZVx1MDAyNndlYl9wbGF5ZXJfbXV0YWJsZV9ldmVudF9sYWJlbFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX25pdHJhdGVfcHJvbW9fdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX29mZmxpbmVfcGxheWxpc3RfYXV0b19yZWZyZXNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfcmVzcG9uc2VfcGxheWJhY2tfdHJhY2tpbmdfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlZWtfY2hhcHRlcnNfYnlfc2hvcnRjdXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZW50aW5lbF9pc191bmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG91bGRfaG9ub3JfaW5jbHVkZV9hc3Jfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3dfbXVzaWNfaW5fdGhpc192aWRlb19ncmFwaGljXHUwMDNkdmlkZW9fdGh1bWJuYWlsXHUwMDI2d2ViX3BsYXllcl9zbWFsbF9oYnBfc2V0dGluZ3NfbWVudVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NzX2RhaV9hZF9mZXRjaGluZ190aW1lb3V0X21zXHUwMDNkMTUwMDBcdTAwMjZ3ZWJfcGxheWVyX3NzX21lZGlhX3RpbWVfb2Zmc2V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG9waWZ5X3N1YnRpdGxlc19mb3Jfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG91Y2hfbW9kZV9pbXByb3ZlbWVudHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90cmFuc2Zlcl90aW1lb3V0X3RocmVzaG9sZF9tc1x1MDAzZDEwODAwMDAwXHUwMDI2d2ViX3BsYXllcl91bnNldF9kZWZhdWx0X2Nzbl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdXNlX25ld19hcGlfZm9yX3F1YWxpdHlfcHVsbGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl92ZV9jb252ZXJzaW9uX2ZpeGVzX2Zvcl9jaGFubmVsX2luZm9cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZV9wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wcmVmZXRjaF9wcmVsb2FkX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNndlYl9yb3VuZGVkX3RodW1ibmFpbHNcdTAwM2R0cnVlXHUwMDI2d2ViX3NldHRpbmdzX21lbnVfaWNvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X21ldGhvZFx1MDAzZDBcdTAwMjZ3ZWJfeXRfY29uZmlnX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2d2lsX2ljb25fcmVuZGVyX3doZW5faWRsZVx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfY2xlYW5fdXBfYWZ0ZXJfZW50aXR5X21pZ3JhdGlvblx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfZW5hYmxlX2Rvd25sb2FkX3N0YXR1c1x1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfcGxheWxpc3Rfb3B0aW1pemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2NsZWFyX2VtYmVkZGVkX3BsYXllclx1MDAzZHRydWVcdTAwMjZ5dGlkYl9mZXRjaF9kYXRhc3luY19pZHNfZm9yX2RhdGFfY2xlYW51cFx1MDAzZHRydWVcdTAwMjZ5dGlkYl9yZW1ha2VfZGJfcmV0cmllc1x1MDAzZDFcdTAwMjZ5dGlkYl9yZW9wZW5fZGJfcmV0cmllc1x1MDAzZDBcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0XHUwMDNkMC4wMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfc2Vzc2lvblx1MDAzZDAuMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfdHJhbnNhY3Rpb25cdTAwM2QwLjEiLCJkaXNhYmxlRnVsbHNjcmVlbiI6dHJ1ZSwiY3NwTm9uY2UiOiJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIiwiY2FuYXJ5U3RhdGUiOiJub25lIiwiZGF0YXN5bmNJZCI6IlZlYTMwNzlmYnx8In0sIldFQl9QTEFZRVJfQ09OVEVYVF9DT05GSUdfSURfS0VWTEFSX0lOTElORV9QUkVWSUVXIjp7InJvb3RFbGVtZW50SWQiOiJpbmxpbmUtcHJldmlldy1wbGF5ZXIiLCJqc1VybCI6Ii9zL3BsYXllci9iMTI4ZGRhMC9wbGF5ZXJfaWFzLnZmbHNldC9mcl9GUi9iYXNlLmpzIiwiY3NzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3d3dy1wbGF5ZXIuY3NzIiwiY29udGV4dElkIjoiV0VCX1BMQVlFUl9DT05URVhUX0NPTkZJR19JRF9LRVZMQVJfSU5MSU5FX1BSRVZJRVciLCJldmVudExhYmVsIjoiZGV0YWlscGFnZSIsImNvbnRlbnRSZWdpb24iOiJGUiIsImhsIjoiZnJfRlIiLCJob3N0TGFuZ3VhZ2UiOiJmciIsInBsYXllclN0eWxlIjoiZGVza3RvcC1wb2x5bWVyIiwiaW5uZXJ0dWJlQXBpS2V5IjoiQUl6YVN5QU9fRkoyU2xxVThRNFNURUhMR0NpbHdfWTlfMTFxY1c4IiwiaW5uZXJ0dWJlQXBpVmVyc2lvbiI6InYxIiwiaW5uZXJ0dWJlQ29udGV4dENsaWVudFZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIiwiZGlzYWJsZUtleWJvYXJkQ29udHJvbHMiOnRydWUsImRldmljZSI6eyJicmFuZCI6IiIsIm1vZGVsIjoiIiwicGxhdGZvcm0iOiJERVNLVE9QIiwiaW50ZXJmYWNlTmFtZSI6IldFQiIsImludGVyZmFjZVZlcnNpb24iOiIyLjIwMjMwNjA3LjA2LjAwIn0sInNlcmlhbGl6ZWRFeHBlcmltZW50SWRzIjoiMjM4NTgwNTcsMjM5ODMyOTYsMjM5ODYwMzMsMjQwMDQ2NDQsMjQwMDcyNDYsMjQwODA3MzgsMjQxMzUzMTAsMjQzNjI2ODUsMjQzNjI2ODgsMjQzNjMxMTQsMjQzNjQ3ODksMjQzNjY5MTcsMjQzNzA4OTgsMjQzNzczNDYsMjQ0MTU4NjQsMjQ0MzM2NzksMjQ0Mzc1NzcsMjQ0MzkzNjEsMjQ0OTI1NDcsMjQ1MzI4NTUsMjQ1NTA0NTgsMjQ1NTA5NTEsMjQ1NTg2NDEsMjQ1NTkzMjYsMjQ2OTk4OTksMzkzMjMwNzQiLCJzZXJpYWxpemVkRXhwZXJpbWVudEZsYWdzIjoiSDVfYXN5bmNfbG9nZ2luZ19kZWxheV9tc1x1MDAzZDMwMDAwLjBcdTAwMjZINV9lbmFibGVfZnVsbF9wYWNmX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2SDVfdXNlX2FzeW5jX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2YWN0aW9uX2NvbXBhbmlvbl9jZW50ZXJfYWxpZ25fZGVzY3JpcHRpb25cdTAwM2R0cnVlXHUwMDI2YWRfcG9kX2Rpc2FibGVfY29tcGFuaW9uX3BlcnNpc3RfYWRzX3F1YWxpdHlcdTAwM2R0cnVlXHUwMDI2YWRkdG9fYWpheF9sb2dfd2FybmluZ19mcmFjdGlvblx1MDAzZDAuMVx1MDAyNmFsaWduX2FkX3RvX3ZpZGVvX3BsYXllcl9saWZlY3ljbGVfZm9yX2J1bGxlaXRcdTAwM2R0cnVlXHUwMDI2YWxsb3dfbGl2ZV9hdXRvcGxheVx1MDAzZHRydWVcdTAwMjZhbGxvd19wb2x0ZXJndXN0X2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X3NraXBfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2YXV0b3BsYXlfdGltZVx1MDAzZDgwMDBcdTAwMjZhdXRvcGxheV90aW1lX2Zvcl9mdWxsc2NyZWVuXHUwMDNkMzAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX211c2ljX2NvbnRlbnRcdTAwM2QzMDAwXHUwMDI2Ymdfdm1fcmVpbml0X3RocmVzaG9sZFx1MDAzZDcyMDAwMDBcdTAwMjZibG9ja2VkX3BhY2thZ2VzX2Zvcl9zcHNcdTAwM2RbXVx1MDAyNmJvdGd1YXJkX2FzeW5jX3NuYXBzaG90X3RpbWVvdXRfbXNcdTAwM2QzMDAwXHUwMDI2Y2hlY2tfYWRfdWlfc3RhdHVzX2Zvcl9td2ViX3NhZmFyaVx1MDAzZHRydWVcdTAwMjZjaGVja19uYXZpZ2F0b3JfYWNjdXJhY3lfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZjbGVhcl91c2VyX3BhcnRpdGlvbmVkX2xzXHUwMDNkdHJ1ZVx1MDAyNmNsaWVudF9yZXNwZWN0X2F1dG9wbGF5X3N3aXRjaF9idXR0b25fcmVuZGVyZXJcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3NfZ2VsXHUwMDNkdHJ1ZVx1MDAyNmNvbXByZXNzaW9uX2Rpc2FibGVfcG9pbnRcdTAwM2QxMFx1MDAyNmNvbXByZXNzaW9uX3BlcmZvcm1hbmNlX3RocmVzaG9sZFx1MDAzZDI1MFx1MDAyNmNzaV9vbl9nZWxcdTAwM2R0cnVlXHUwMDI2ZGFzaF9tYW5pZmVzdF92ZXJzaW9uXHUwMDNkNVx1MDAyNmRlYnVnX2JhbmRhaWRfaG9zdG5hbWVcdTAwM2RcdTAwMjZkZWJ1Z19zaGVybG9nX3VzZXJuYW1lXHUwMDNkXHUwMDI2ZGVsYXlfYWRzX2d2aV9jYWxsX29uX2J1bGxlaXRfbGl2aW5nX3Jvb21fbXNcdTAwM2QwXHUwMDI2ZGVwcmVjYXRlX2NzaV9oYXNfaW5mb1x1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfcGFpcl9zZXJ2bGV0X2VuYWJsZWRcdTAwM2R0cnVlXHUwMDI2ZGVwcmVjYXRlX3R3b193YXlfYmluZGluZ19jaGlsZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX3BhcmVudFx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX2ltYWdlX2N0YV9ub19iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfbG9nX2ltZ19jbGlja19sb2NhdGlvblx1MDAzZHRydWVcdTAwMjZkZXNrdG9wX3NwYXJrbGVzX2xpZ2h0X2N0YV9idXR0b25cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9jaGFubmVsX2lkX2NoZWNrX2Zvcl9zdXNwZW5kZWRfY2hhbm5lbHNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9jaGlsZF9ub2RlX2F1dG9fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9kZWZlcl9hZG1vZHVsZV9vbl9hZHZlcnRpc2VyX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfZmVhdHVyZXNfZm9yX3N1cGV4XHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbGVnYWN5X2Rlc2t0b3BfcmVtb3RlX3F1ZXVlXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbWR4X2Nvbm5lY3Rpb25faW5fbWR4X21vZHVsZV9mb3JfbXVzaWNfd2ViXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfbmV3X3BhdXNlX3N0YXRlM1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3BhY2ZfbG9nZ2luZ19mb3JfbWVtb3J5X2xpbWl0ZWRfdHZcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9yb3VuZGluZ19hZF9ub3RpZnlcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zaW1wbGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfc3NkYWlfb25fZXJyb3JzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGFiYmluZ19iZWZvcmVfZmx5b3V0X2FkX2VsZW1lbnRzX2FwcGVhclx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3RodW1ibmFpbF9wcmVsb2FkaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc19kaXNhYmxlX3Byb2dyZXNzX2Jhcl9jb250ZXh0X21lbnVfaGFuZGxpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2VuYWJsZV9hbGxvd193YXRjaF9hZ2Fpbl9lbmRzY3JlZW5fZm9yX2VsaWdpYmxlX3Nob3J0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfdmVfY29udmVyc2lvbl9wYXJhbV9yZW5hbWluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9hdXRvcGxheV9ub3Rfc3VwcG9ydGVkX2xvZ2dpbmdfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2N1ZV92aWRlb191bnBsYXlhYmxlX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9ob3VzZV9icmFuZF9hbmRfeXRfY29leGlzdGVuY2VcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9hZF9wbGF5ZXJfZnJvbV9wYWdlX3Nob3dcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nX3NwbGF5X2FzX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2xvZ2dpbmdfZXZlbnRfaGFuZGxlcnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX21vYmlsZV9kdHRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX25ld19jb250ZXh0X21lbnVfdHJpZ2dlcmluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wYXVzZV9vdmVybGF5X3duX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZW1fZG9tYWluX2ZpeF9mb3JfYWRfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfcGZwX3VuYnJhbmRlZF9lbF9kZXByZWNhdGlvblx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9yY2F0X2FsbG93bGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9yZXBsYWNlX3VubG9hZF93X3BhZ2VoaWRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3NjcmlwdGVkX3BsYXliYWNrX2Jsb2NrZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfdmVfY29udmVyc2lvbl9sb2dnaW5nX3RyYWNraW5nX25vX2FsbG93X2xpc3RcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9oaWRlX3VuZmlsbGVkX21vcmVfdmlkZW9zX3N1Z2dlc3Rpb25zXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfbGl0ZV9tb2RlXHUwMDNkMVx1MDAyNmVtYmVkc193ZWJfbndsX2Rpc2FibGVfbm9jb29raWVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zaG9wcGluZ19vdmVybGF5X25vX3dhaXRfZm9yX3BhaWRfY29udGVudF9vdmVybGF5XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfc3ludGhfY2hfaGVhZGVyc19iYW5uZWRfdXJsc19yZWdleFx1MDAzZFx1MDAyNmVuYWJsZV9hYl9ycF9pbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FkX2Nwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9hcHBfcHJvbW9fZW5kY2FwX2VtbF9vbl90YWJsZXRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Nhc3RfZm9yX3dlYl91bnBsdWdnZWRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Nhc3Rfb25fbXVzaWNfd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jbGllbnRfcGFnZV9pZF9oZWFkZXJfZm9yX2ZpcnN0X3BhcnR5X3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9jbGllbnRfc2xpX2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Rpc2NyZXRlX2xpdmVfcHJlY2lzZV9lbWJhcmdvc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkX3dlYl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkX3dlYl9jbGllbnRfY2hlY2tcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2Vycm9yX2NvcnJlY3Rpb25zX2luZm9jYXJkc19pY29uX3dlYlx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXZpY3Rpb25fcHJvdGVjdGlvbl9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZ2VsX2xvZ19jb21tYW5kc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfaDVfaW5zdHJlYW1fd2F0Y2hfbmV4dF9wYXJhbXNfb2FybGliXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV92aWRlb19hZHNfb2FybGliXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oYW5kbGVzX2FjY291bnRfbWVudV9zd2l0Y2hlclx1MDAzZHRydWVcdTAwMjZlbmFibGVfa2FidWtpX2NvbW1lbnRzX29uX3Nob3J0c1x1MDAzZGRpc2FibGVkXHUwMDI2ZW5hYmxlX2xpdmVfcHJlbWllcmVfd2ViX3BsYXllcl9pbmRpY2F0b3JcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2xyX2hvbWVfaW5mZWVkX2Fkc19pbmxpbmVfcGxheWJhY2tfcHJvZ3Jlc3NfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX21peGVkX2RpcmVjdGlvbl9mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbXdlYl9saXZlc3RyZWFtX3VpX3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZlbmFibGVfbmV3X3BhaWRfcHJvZHVjdF9wbGFjZW1lbnRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2Zfc2xvdF9hc2RlX3BsYXllcl9ieXRlX2g1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90dlx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3liZmVfdHZfZm9yX3BhZ2VfdG9wX2Zvcm1hdHNcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95c2ZlX3R2XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYXNzX3NkY19nZXRfYWNjb3VudHNfbGlzdFx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGxfcl9jXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2ZpeF9vbl90dmh0bWw1XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wb3N0X2FkX3BlcmNlcHRpb25fc3VydmV5X2luX3R2aHRtbDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3ByZWNpc2VfZW1iYXJnb3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NlcnZlcl9zdGl0Y2hlZF9kYWlcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Nob3J0c19wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NraXBfYWRfZ3VpZGFuY2VfcHJvbXB0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9za2lwcGFibGVfYWRzX2Zvcl91bnBsdWdnZWRfYWRfcG9kXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV90ZWN0b25pY19hZF91eF9mb3JfaGFsZnRpbWVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RoaXJkX3BhcnR5X2luZm9cdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RvcHNvaWxfd3RhX2Zvcl9oYWxmdGltZV9saXZlX2luZnJhXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV93ZWJfbWVkaWFfc2Vzc2lvbl9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3dlYl9zY2hlZHVsZXJfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfeXRfYXRhX2lmcmFtZV9hdXRodXNlclx1MDAzZHRydWVcdTAwMjZlcnJvcl9tZXNzYWdlX2Zvcl9nc3VpdGVfbmV0d29ya19yZXN0cmljdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZXhwb3J0X25ldHdvcmtsZXNzX29wdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZXh0ZXJuYWxfZnVsbHNjcmVlbl93aXRoX2VkdVx1MDAzZHRydWVcdTAwMjZmYXN0X2F1dG9uYXZfaW5fYmFja2dyb3VuZFx1MDAzZHRydWVcdTAwMjZmZXRjaF9hdHRfaW5kZXBlbmRlbnRseVx1MDAzZHRydWVcdTAwMjZmaWxsX3NpbmdsZV92aWRlb193aXRoX25vdGlmeV90b19sYXNyXHUwMDNkdHJ1ZVx1MDAyNmZpbHRlcl92cDlfZm9yX2NzZGFpXHUwMDNkdHJ1ZVx1MDAyNmZpeF9hZHNfdHJhY2tpbmdfZm9yX3N3Zl9jb25maWdfZGVwcmVjYXRpb25fbXdlYlx1MDAzZHRydWVcdTAwMjZnY2ZfY29uZmlnX3N0b3JlX2VuYWJsZWRcdTAwM2R0cnVlXHUwMDI2Z2VsX3F1ZXVlX3RpbWVvdXRfbWF4X21zXHUwMDNkMzAwMDAwXHUwMDI2Z3BhX3NwYXJrbGVzX3Rlbl9wZXJjZW50X2xheWVyXHUwMDNkdHJ1ZVx1MDAyNmd2aV9jaGFubmVsX2NsaWVudF9zY3JlZW5cdTAwM2R0cnVlXHUwMDI2aDVfY29tcGFuaW9uX2VuYWJsZV9hZGNwbl9tYWNyb19zdWJzdGl0dXRpb25fZm9yX2NsaWNrX3BpbmdzXHUwMDNkdHJ1ZVx1MDAyNmg1X2VuYWJsZV9nZW5lcmljX2Vycm9yX2xvZ2dpbmdfZXZlbnRcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX3VuaWZpZWRfY3NpX3ByZXJvbGxcdTAwM2R0cnVlXHUwMDI2aDVfaW5wbGF5ZXJfZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfcmVzZXRfY2FjaGVfYW5kX2ZpbHRlcl9iZWZvcmVfdXBkYXRlX21hc3RoZWFkXHUwMDNkdHJ1ZVx1MDAyNmhlYXRzZWVrZXJfZGVjb3JhdGlvbl90aHJlc2hvbGRcdTAwM2QwLjBcdTAwMjZoZnJfZHJvcHBlZF9mcmFtZXJhdGVfZmFsbGJhY2tfdGhyZXNob2xkXHUwMDNkMFx1MDAyNmhpZGVfZW5kcG9pbnRfb3ZlcmZsb3dfb25feXRkX2Rpc3BsYXlfYWRfcmVuZGVyZXJcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWRfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZodG1sNV9hZHNfcHJlcm9sbF9sb2NrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QxNTAwMFx1MDAyNmh0bWw1X2FsbG93X2Rpc2NvbnRpZ3VvdXNfc2xpY2VzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2FsbG93X3ZpZGVvX2tleWZyYW1lX3dpdGhvdXRfYXVkaW9cdTAwM2R0cnVlXHUwMDI2aHRtbDVfYXR0YWNoX251bV9yYW5kb21fYnl0ZXNfdG9fYmFuZGFpZFx1MDAzZDBcdTAwMjZodG1sNV9hdHRhY2hfcG9fdG9rZW5fdG9fYmFuZGFpZFx1MDAzZHRydWVcdTAwMjZodG1sNV9hdXRvbmF2X2NhcF9pZGxlX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfYXV0b25hdl9xdWFsaXR5X2NhcFx1MDAzZDcyMFx1MDAyNmh0bWw1X2F1dG9wbGF5X2RlZmF1bHRfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfYmxvY2tfcGlwX3NhZmFyaV9kZWxheVx1MDAzZDBcdTAwMjZodG1sNV9ibWZmX25ld19mb3VyY2NfY2hlY2tcdTAwM2R0cnVlXHUwMDI2aHRtbDVfY29iYWx0X2RlZmF1bHRfYnVmZmVyX3NpemVfaW5fYnl0ZXNcdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X21heF9zaXplX2Zvcl9pbW1lZF9qb2JcdTAwM2QwXHUwMDI2aHRtbDVfY29iYWx0X21pbl9wcm9jZXNzb3JfY250X3RvX29mZmxvYWRfYWxnb1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfb3ZlcnJpZGVfcXVpY1x1MDAzZDBcdTAwMjZodG1sNV9jb25zdW1lX21lZGlhX2J5dGVzX3NsaWNlX2luZm9zXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlX2R1cGVfY29udGVudF92aWRlb19sb2Fkc19pbl9saWZlY3ljbGVfYXBpXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlYnVnX2RhdGFfbG9nX3Byb2JhYmlsaXR5XHUwMDNkMC4xXHUwMDI2aHRtbDVfZGVjb2RlX3RvX3RleHR1cmVfY2FwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RlZmF1bHRfYWRfZ2Fpblx1MDAzZDAuNVx1MDAyNmh0bWw1X2RlZmF1bHRfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfYWRfbW9kdWxlX21zXHUwMDNkMFx1MDAyNmh0bWw1X2RlZmVyX2ZldGNoX2F0dF9tc1x1MDAzZDEwMDBcdTAwMjZodG1sNV9kZWZlcl9tb2R1bGVzX2RlbGF5X3RpbWVfbWlsbGlzXHUwMDNkMFx1MDAyNmh0bWw1X2RlbGF5ZWRfcmV0cnlfY291bnRcdTAwM2QxXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9kZWxheV9tc1x1MDAzZDUwMDBcdTAwMjZodG1sNV9kZXByZWNhdGVfdmlkZW9fdGFnX3Bvb2xcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVza3RvcF92cjE4MF9hbGxvd19wYW5uaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RmX2Rvd25ncmFkZV90aHJlc2hcdTAwM2QwLjJcdTAwMjZodG1sNV9kaXNhYmxlX2NzaV9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNhYmxlX21vdmVfcHNzaF90b19tb292XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbm9uX2NvbnRpZ3VvdXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzcGxheWVkX2ZyYW1lX3JhdGVfZG93bmdyYWRlX3RocmVzaG9sZFx1MDAzZDQ1XHUwMDI2aHRtbDVfZHJtX2NoZWNrX2FsbF9rZXlfZXJyb3Jfc3RhdGVzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2RybV9jcGlfbGljZW5zZV9rZXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2FjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWRzX2NsaWVudF9tb25pdG9yaW5nX2xvZ190dlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2FwdGlvbl9jaGFuZ2VzX2Zvcl9tb3NhaWNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2NsaWVudF9oaW50c19vdmVycmlkZVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY29tcG9zaXRlX2VtYmFyZ29cdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2VhYzNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX2VtYmVkZGVkX3BsYXllcl92aXNpYmlsaXR5X3NpZ25hbHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX25ld19odmNfZW5jXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9ub25fbm90aWZ5X2NvbXBvc2l0ZV92b2RfbHNhcl9wYWNmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9zaW5nbGVfdmlkZW9fdm9kX2l2YXJfb25fcGFjZlx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfdHZvc19kYXNoXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV90dm9zX2VuY3J5cHRlZF92cDlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3dpZGV2aW5lX2Zvcl9hbGNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3dpZGV2aW5lX2Zvcl9mYXN0X2xpbmVhclx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmNvdXJhZ2VfYXJyYXlfY29hbGVzY2luZ1x1MDAzZHRydWVcdTAwMjZodG1sNV9nYXBsZXNzX2VuZGVkX3RyYW5zaXRpb25fYnVmZmVyX21zXHUwMDNkMjAwXHUwMDI2aHRtbDVfZ2VuZXJhdGVfc2Vzc2lvbl9wb190b2tlblx1MDAzZHRydWVcdTAwMjZodG1sNV9nbF9mcHNfdGhyZXNob2xkXHUwMDNkMFx1MDAyNmh0bWw1X2hkY3BfcHJvYmluZ19zdHJlYW1fdXJsXHUwMDNkXHUwMDI2aHRtbDVfaGZyX3F1YWxpdHlfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X2hpZ2hfcmVzX2xvZ2dpbmdfcGVyY2VudFx1MDAzZDEuMFx1MDAyNmh0bWw1X2lkbGVfcmF0ZV9saW1pdF9tc1x1MDAzZDBcdTAwMjZodG1sNV9pbm5lcnR1YmVfaGVhcnRiZWF0c19mb3JfZmFpcnBsYXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW5uZXJ0dWJlX2hlYXJ0YmVhdHNfZm9yX3BsYXlyZWFkeVx1MDAzZHRydWVcdTAwMjZodG1sNV9pbm5lcnR1YmVfaGVhcnRiZWF0c19mb3Jfd2lkZXZpbmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW9zNF9zZWVrX2Fib3ZlX3plcm9cdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW9zN19mb3JjZV9wbGF5X29uX3N0YWxsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lvc19mb3JjZV9zZWVrX3RvX3plcm9fb25fc3RvcFx1MDAzZHRydWVcdTAwMjZodG1sNV9qdW1ib19tb2JpbGVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGFyZ2V0XHUwMDNkMy4wXHUwMDI2aHRtbDVfanVtYm9fdWxsX25vbnN0cmVhbWluZ19tZmZhX21zXHUwMDNkNDAwMFx1MDAyNmh0bWw1X2p1bWJvX3VsbF9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRcdTAwM2QxLjNcdTAwMjZodG1sNV9saWNlbnNlX2NvbnN0cmFpbnRfZGVsYXlcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfbGl2ZV9hYnJfaGVhZF9taXNzX2ZyYWN0aW9uXHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9hYnJfcmVwcmVkaWN0X2ZyYWN0aW9uXHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9ieXRlcmF0ZV9mYWN0b3JfZm9yX3JlYWRhaGVhZFx1MDAzZDEuM1x1MDAyNmh0bWw1X2xpdmVfbG93X2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfbWV0YWRhdGFfZml4XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xpdmVfbm9ybWFsX2xhdGVuY3lfYmFuZHdpZHRoX3dpbmRvd1x1MDAzZDAuMFx1MDAyNmh0bWw1X2xpdmVfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfbGl2ZV91bHRyYV9sb3dfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbG9nX2F1ZGlvX2Ficlx1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfZXhwZXJpbWVudF9pZF9mcm9tX3BsYXllcl9yZXNwb25zZV90b19jdG1wXHUwMDNkXHUwMDI2aHRtbDVfbG9nX2ZpcnN0X3NzZGFpX3JlcXVlc3RzX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX3JlYnVmZmVyX2V2ZW50c1x1MDAzZDVcdTAwMjZodG1sNV9sb2dfc3NkYWlfZmFsbGJhY2tfYWRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ190cmlnZ2VyX2V2ZW50c193aXRoX2RlYnVnX2RhdGFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl9qaWdnbGVfY210X2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfbmV3X2VsZW1fc2hvcnRzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X2xvbmdfcmVidWZmZXJfdGhyZXNob2xkX21zXHUwMDNkMzAwMDBcdTAwMjZodG1sNV9tYW5pZmVzdGxlc3Nfc2VnX2RyaWZ0X2xpbWl0X3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfbWFuaWZlc3RsZXNzX3VucGx1Z2dlZFx1MDAzZHRydWVcdTAwMjZodG1sNV9tYW5pZmVzdGxlc3NfdnA5X290Zlx1MDAzZHRydWVcdTAwMjZodG1sNV9tYXhfZHJpZnRfcGVyX3RyYWNrX3NlY3NcdTAwM2QwLjBcdTAwMjZodG1sNV9tYXhfaGVhZG1fZm9yX3N0cmVhbWluZ194aHJcdTAwM2QwXHUwMDI2aHRtbDVfbWF4X2xpdmVfZHZyX3dpbmRvd19wbHVzX21hcmdpbl9zZWNzXHUwMDNkNDY4MDAuMFx1MDAyNmh0bWw1X21heF9yZWFkYmVoaW5kX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfbWF4X3JlZGlyZWN0X3Jlc3BvbnNlX2xlbmd0aFx1MDAzZDgxOTJcdTAwMjZodG1sNV9tYXhfc2VsZWN0YWJsZV9xdWFsaXR5X29yZGluYWxcdTAwM2QwXHUwMDI2aHRtbDVfbWF4X3NvdXJjZV9idWZmZXJfYXBwZW5kX3NpemVfaW5fYnl0ZXNcdTAwM2QwXHUwMDI2aHRtbDVfbWF4aW11bV9yZWFkYWhlYWRfc2Vjb25kc1x1MDAzZDAuMFx1MDAyNmh0bWw1X21lZGlhX2Z1bGxzY3JlZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWZsX2V4dGVuZF9tYXhfcmVxdWVzdF90aW1lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21pbl9yZWFkYmVoaW5kX2NhcF9zZWNzXHUwMDNkNjBcdTAwMjZodG1sNV9taW5fcmVhZGJlaGluZF9zZWNzXHUwMDNkMFx1MDAyNmh0bWw1X21pbl9zZWxlY3RhYmxlX3F1YWxpdHlfb3JkaW5hbFx1MDAzZDBcdTAwMjZodG1sNV9taW5fc3RhcnR1cF9idWZmZXJlZF9hZF9tZWRpYV9kdXJhdGlvbl9zZWNzXHUwMDNkMS4yXHUwMDI2aHRtbDVfbWluX3N0YXJ0dXBfYnVmZmVyZWRfbWVkaWFfZHVyYXRpb25fc2Vjc1x1MDAzZDEuMlx1MDAyNmh0bWw1X21pbmltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9ub19wbGFjZWhvbGRlcl9yb2xsYmFja3NcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbm9uX25ldHdvcmtfcmVidWZmZXJfZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfbm9uX29uZXNpZV9hdHRhY2hfcG9fdG9rZW5cdTAwM2R0cnVlXHUwMDI2aHRtbDVfbm90X3JlZ2lzdGVyX2Rpc3Bvc2FibGVzX3doZW5fY29yZV9saXN0ZW5zXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29mZmxpbmVfZmFpbHVyZV9yZXRyeV9saW1pdFx1MDAzZDJcdTAwMjZodG1sNV9vbmVzaWVfZGVmZXJfY29udGVudF9sb2FkZXJfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX2hvc3RfcmFjaW5nX2NhcF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfaWdub3JlX2lubmVydHViZV9hcGlfa2V5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9saXZlX3R0bF9zZWNzXHUwMDNkOFx1MDAyNmh0bWw1X29uZXNpZV9ub256ZXJvX3BsYXliYWNrX3N0YXJ0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9ub3RpZnlfY3VlcG9pbnRfbWFuYWdlcl9vbl9jb21wbGV0aW9uXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X29uZXNpZV9wcmV3YXJtX2Nvb2xkb3duX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9wcmV3YXJtX2ludGVydmFsX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9wcmV3YXJtX21heF9sYWN0X21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9yZWRpcmVjdG9yX3RpbWVvdXRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX3JlZGlyZWN0b3JfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfcmVxdWVzdF90aW1lb3V0X21zXHUwMDNkMTAwMFx1MDAyNmh0bWw1X29uZXNpZV9zdGlja3lfc2VydmVyX3NpZGVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGF1c2Vfb25fbm9uZm9yZWdyb3VuZF9wbGF0Zm9ybV9lcnJvcnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVha19zaGF2ZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wZXJmX2NhcF9vdmVycmlkZV9zdGlja3lcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGVyZm9ybWFuY2VfY2FwX2Zsb29yXHUwMDNkMzYwXHUwMDI2aHRtbDVfcGVyZm9ybWFuY2VfaW1wYWN0X3Byb2ZpbGluZ190aW1lcl9tc1x1MDAzZDBcdTAwMjZodG1sNV9wZXJzZXJ2ZV9hdjFfcGVyZl9jYXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxhdGZvcm1fYmFja3ByZXNzdXJlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXRmb3JtX21pbmltdW1fcmVhZGFoZWFkX3NlY29uZHNcdTAwM2QwLjBcdTAwMjZodG1sNV9wbGF5ZXJfYXV0b25hdl9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXllcl9keW5hbWljX2JvdHRvbV9ncmFkaWVudFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF5ZXJfbWluX2J1aWxkX2NsXHUwMDNkLTFcdTAwMjZodG1sNV9wbGF5ZXJfcHJlbG9hZF9hZF9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcG9zdF9pbnRlcnJ1cHRfcmVhZGFoZWFkXHUwMDNkMjBcdTAwMjZodG1sNV9wcmVmZXJfc2VydmVyX2J3ZTNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcHJlbG9hZF93YWl0X3RpbWVfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Byb2JlX3ByaW1hcnlfZGVsYXlfYmFzZV9tc1x1MDAzZDBcdTAwMjZodG1sNV9wcm9jZXNzX2FsbF9lbmNyeXB0ZWRfZXZlbnRzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3FvZV9saF9tYXhfcmVwb3J0X2NvdW50XHUwMDNkMFx1MDAyNmh0bWw1X3FvZV9saF9taW5fZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfcXVlcnlfc3dfc2VjdXJlX2NyeXB0b19mb3JfYW5kcm9pZFx1MDAzZHRydWVcdTAwMjZodG1sNV9yYW5kb21fcGxheWJhY2tfY2FwXHUwMDNkMFx1MDAyNmh0bWw1X3JlY29nbml6ZV9wcmVkaWN0X3N0YXJ0X2N1ZV9wb2ludFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfY29tbWFuZF90cmlnZ2VyZWRfY29tcGFuaW9uc1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZW1vdmVfbm90X3NlcnZhYmxlX2NoZWNrX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVuYW1lX2FwYnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X2ZhdGFsX2RybV9yZXN0cmljdGVkX2Vycm9yX2tpbGxzd2l0Y2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVwb3J0X3Nsb3dfYWRzX2FzX2Vycm9yXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlcXVlc3Rfb25seV9oZHJfb3Jfc2RyX2tleXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVxdWVzdF9zaXppbmdfbXVsdGlwbGllclx1MDAzZDAuOFx1MDAyNmh0bWw1X3Jlc2V0X21lZGlhX3N0cmVhbV9vbl91bnJlc3VtYWJsZV9zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVzb3VyY2VfYmFkX3N0YXR1c19kZWxheV9zY2FsaW5nXHUwMDNkMS41XHUwMDI2aHRtbDVfcmVzdHJpY3Rfc3RyZWFtaW5nX3hocl9vbl9zcWxlc3NfcmVxdWVzdHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2FmYXJpX2Rlc2t0b3BfZW1lX21pbl92ZXJzaW9uXHUwMDNkMFx1MDAyNmh0bWw1X3NhbXN1bmdfa2FudF9saW1pdF9tYXhfYml0cmF0ZVx1MDAzZDBcdTAwMjZodG1sNV9zZWVrX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2Q4MDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9kZWxheV9tc1x1MDAzZDEyMDAwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfYnVmZmVyX3JhbmdlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X2VsZW1fc2hvcnRzX3Zyc19kZWxheV9tc1x1MDAzZDBcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2NmbFx1MDAzZHRydWVcdTAwMjZodG1sNV9zZWVrX25ld19tZWRpYV9zb3VyY2Vfc2hvcnRzX3JldXNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfc2V0X2NtdF9kZWxheV9tc1x1MDAzZDIwMDBcdTAwMjZodG1sNV9zZWVrX3RpbWVvdXRfZGVsYXlfbXNcdTAwM2QyMDAwMFx1MDAyNmh0bWw1X3NlcnZlcl9zdGl0Y2hlZF9kYWlfZGVjb3JhdGVkX3VybF9yZXRyeV9saW1pdFx1MDAzZDVcdTAwMjZodG1sNV9zZXJ2ZXJfc3RpdGNoZWRfZGFpX2dyb3VwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3Nlc3Npb25fcG9fdG9rZW5faW50ZXJ2YWxfdGltZV9tc1x1MDAzZDkwMDAwMFx1MDAyNmh0bWw1X3NraXBfb29iX3N0YXJ0X3NlY29uZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2tpcF9zbG93X2FkX2RlbGF5X21zXHUwMDNkMTUwMDBcdTAwMjZodG1sNV9za2lwX3N1Yl9xdWFudHVtX2Rpc2NvbnRpbnVpdHlfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfbm9fbWVkaWFfc291cmNlX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3Nsb3dfc3RhcnRfdGltZW91dF9kZWxheV9tc1x1MDAzZDIwMDAwXHUwMDI2aHRtbDVfc3NkYWlfYWRmZXRjaF9keW5hbWljX3RpbWVvdXRfbXNcdTAwM2Q1MDAwXHUwMDI2aHRtbDVfc3NkYWlfZW5hYmxlX25ld19zZWVrX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N0YXRlZnVsX2F1ZGlvX21pbl9hZGp1c3RtZW50X3ZhbHVlXHUwMDNkMFx1MDAyNmh0bWw1X3N0YXRpY19hYnJfcmVzb2x1dGlvbl9zaGVsZlx1MDAzZDBcdTAwMjZodG1sNV9zdG9yZV94aHJfaGVhZGVyc19yZWFkYWJsZVx1MDAzZHRydWVcdTAwMjZodG1sNV9zdHJlYW1pbmdfeGhyX2V4cGFuZF9yZXF1ZXN0X3NpemVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbG9hZF9zcGVlZF9jaGVja19pbnRlcnZhbFx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX21pbl9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjI1XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc19vbl90aW1lb3V0XHUwMDNkMC4xXHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2xvYWRfc3BlZWRcdTAwM2QxLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9zZWVrX2xhdGVuY3lfZnVkZ2VcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRfYnVmZmVyX2hlYWx0aF9zZWNzXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfdGltZW91dF9zZWNzXHUwMDNkMi4wXHUwMDI2aHRtbDVfdWdjX2xpdmVfYXVkaW9fNTFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdWdjX3ZvZF9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91bnJlcG9ydGVkX3NlZWtfcmVzZWVrX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3VucmVzdHJpY3RlZF9sYXllcl9oaWdoX3Jlc19sb2dnaW5nX3BlcmNlbnRcdTAwM2QwLjBcdTAwMjZodG1sNV91cmxfcGFkZGluZ19sZW5ndGhcdTAwM2QwXHUwMDI2aHRtbDVfdXJsX3NpZ25hdHVyZV9leHBpcnlfdGltZV9ob3Vyc1x1MDAzZDBcdTAwMjZodG1sNV91c2VfcG9zdF9mb3JfbWVkaWFcdTAwM2R0cnVlXHUwMDI2aHRtbDVfdXNlX3VtcFx1MDAzZHRydWVcdTAwMjZodG1sNV92aWRlb190YmRfbWluX2tiXHUwMDNkMFx1MDAyNmh0bWw1X3ZpZXdwb3J0X3VuZGVyc2VuZF9tYXhpbXVtXHUwMDNkMC4wXHUwMDI2aHRtbDVfdm9sdW1lX3NsaWRlcl90b29sdGlwXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYl9lbmFibGVfaGFsZnRpbWVfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZodG1sNV93ZWJwb19pZGxlX3ByaW9yaXR5X2pvYlx1MDAzZHRydWVcdTAwMjZodG1sNV93b2ZmbGVfcmVzdW1lXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvcmthcm91bmRfZGVsYXlfdHJpZ2dlclx1MDAzZHRydWVcdTAwMjZodG1sNV95dHZscl9lbmFibGVfc2luZ2xlX3NlbGVjdF9zdXJ2ZXlcdTAwM2R0cnVlXHUwMDI2aWdub3JlX292ZXJsYXBwaW5nX2N1ZV9wb2ludHNfb25fZW5kZW1pY19saXZlX2h0bWw1XHUwMDNkdHJ1ZVx1MDAyNmlsX3VzZV92aWV3X21vZGVsX2xvZ2dpbmdfY29udGV4dFx1MDAzZHRydWVcdTAwMjZpbml0aWFsX2dlbF9iYXRjaF90aW1lb3V0XHUwMDNkMjAwMFx1MDAyNmluamVjdGVkX2xpY2Vuc2VfaGFuZGxlcl9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNmluamVjdGVkX2xpY2Vuc2VfaGFuZGxlcl9saWNlbnNlX3N0YXR1c1x1MDAzZDBcdTAwMjZpdGRybV9pbmplY3RlZF9saWNlbnNlX3NlcnZpY2VfZXJyb3JfY29kZVx1MDAzZDBcdTAwMjZpdGRybV93aWRldmluZV9oYXJkZW5lZF92bXBfbW9kZVx1MDAzZGxvZ1x1MDAyNmpzb25fY29uZGVuc2VkX3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9jb21tYW5kX2hhbmRsZXJfY29tbWFuZF9iYW5saXN0XHUwMDNkW11cdTAwMjZrZXZsYXJfZHJvcGRvd25fZml4XHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9nZWxfZXJyb3Jfcm91dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllclx1MDAzZHRydWVcdTAwMjZrZXZsYXJfbWluaXBsYXllcl9leHBhbmRfdG9wXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX3BsYXlfcGF1c2Vfb25fc2NyaW1cdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3BsYXliYWNrX2Fzc29jaWF0ZWRfcXVldWVcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3F1ZXVlX3VzZV91cGRhdGVfYXBpXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zaW1wX3Nob3J0c19yZXNldF9zY3JvbGxcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NtYXJ0X2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzX3NldHRpbmdcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3ZpbWlvX3VzZV9zaGFyZWRfbW9uaXRvclx1MDAzZHRydWVcdTAwMjZsaXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZsaXZlX2ZyZXNjYV92Mlx1MDAzZHRydWVcdTAwMjZsb2dfZXJyb3JzX3Rocm91Z2hfbndsX29uX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19nZWxfY29tcHJlc3Npb25fbGF0ZW5jeVx1MDAzZHRydWVcdTAwMjZsb2dfaGVhcnRiZWF0X3dpdGhfbGlmZWN5Y2xlc1x1MDAzZHRydWVcdTAwMjZsb2dfd2ViX2VuZHBvaW50X3RvX2xheWVyXHUwMDNkdHJ1ZVx1MDAyNmxvZ193aW5kb3dfb25lcnJvcl9mcmFjdGlvblx1MDAzZDAuMVx1MDAyNm1hbmlmZXN0bGVzc19wb3N0X2xpdmVcdTAwM2R0cnVlXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZV91ZnBoXHUwMDNkdHJ1ZVx1MDAyNm1heF9ib2R5X3NpemVfdG9fY29tcHJlc3NcdTAwM2Q1MDAwMDBcdTAwMjZtYXhfcHJlZmV0Y2hfd2luZG93X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb25cdTAwM2QwXHUwMDI2bWF4X3Jlc29sdXRpb25fZm9yX3doaXRlX25vaXNlXHUwMDNkMzYwXHUwMDI2bWR4X2VuYWJsZV9wcml2YWN5X2Rpc2Nsb3N1cmVfdWlcdTAwM2R0cnVlXHUwMDI2bWR4X2xvYWRfY2FzdF9hcGlfYm9vdHN0cmFwX3NjcmlwdFx1MDAzZHRydWVcdTAwMjZtaWdyYXRlX2V2ZW50c190b190c1x1MDAzZHRydWVcdTAwMjZtaW5fcHJlZmV0Y2hfb2Zmc2V0X3NlY19mb3JfbGl2ZXN0cmVhbV9vcHRpbWl6YXRpb25cdTAwM2QxMFx1MDAyNm11c2ljX2VuYWJsZV9zaGFyZWRfYXVkaW9fdGllcl9sb2dpY1x1MDAzZHRydWVcdTAwMjZtd2ViX2MzX2VuZHNjcmVlblx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9jdXN0b21fY29udHJvbF9zaGFyZWRcdTAwM2R0cnVlXHUwMDI2bXdlYl9lbmFibGVfc2tpcHBhYmxlc19vbl9qaW9fcGhvbmVcdTAwM2R0cnVlXHUwMDI2bXdlYl9tdXRlZF9hdXRvcGxheV9hbmltYXRpb25cdTAwM2RzaHJpbmtcdTAwMjZtd2ViX25hdGl2ZV9jb250cm9sX2luX2ZhdXhfZnVsbHNjcmVlbl9zaGFyZWRcdTAwM2R0cnVlXHUwMDI2bmV0d29ya19wb2xsaW5nX2ludGVydmFsXHUwMDNkMzAwMDBcdTAwMjZuZXR3b3JrbGVzc19nZWxcdTAwM2R0cnVlXHUwMDI2bmV0d29ya2xlc3NfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZuZXdfY29kZWNzX3N0cmluZ19hcGlfdXNlc19sZWdhY3lfc3R5bGVcdTAwM2R0cnVlXHUwMDI2bndsX3NlbmRfZmFzdF9vbl91bmxvYWRcdTAwM2R0cnVlXHUwMDI2bndsX3NlbmRfZnJvbV9tZW1vcnlfd2hlbl9vbmxpbmVcdTAwM2R0cnVlXHUwMDI2b2ZmbGluZV9lcnJvcl9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZwYWNmX2xvZ2dpbmdfZGVsYXlfbWlsbGlzZWNvbmRzX3Rocm91Z2hfeWJmZV90dlx1MDAzZDMwMDAwXHUwMDI2cGFnZWlkX2FzX2hlYWRlcl93ZWJcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Fkc19zZXRfYWRmb3JtYXRfb25fY2xpZW50XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9hbGxvd19hdXRvbmF2X2FmdGVyX3BsYXlsaXN0XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9ib290c3RyYXBfbWV0aG9kXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9kZWZlcl9jYXB0aW9uX2Rpc3BsYXlcdTAwM2QxMDAwXHUwMDI2cGxheWVyX2Rlc3Ryb3lfb2xkX3ZlcnNpb25cdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RvdWJsZXRhcF90b19zZWVrXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9lbmFibGVfcGxheWJhY2tfcGxheWxpc3RfY2hhbmdlXHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl9lbmRzY3JlZW5fZWxsaXBzaXNfZml4XHUwMDNkdHJ1ZVx1MDAyNnBsYXllcl91bmRlcmxheV9taW5fcGxheWVyX3dpZHRoXHUwMDNkNzY4LjBcdTAwMjZwbGF5ZXJfdW5kZXJsYXlfdmlkZW9fd2lkdGhfZnJhY3Rpb25cdTAwM2QwLjZcdTAwMjZwbGF5ZXJfd2ViX2NhbmFyeV9zdGFnZVx1MDAzZDBcdTAwMjZwbGF5cmVhZHlfZmlyc3RfcGxheV9leHBpcmF0aW9uXHUwMDNkLTFcdTAwMjZwb2x5bWVyX2JhZF9idWlsZF9sYWJlbHNcdTAwM2R0cnVlXHUwMDI2cG9seW1lcl9sb2dfcHJvcF9jaGFuZ2Vfb2JzZXJ2ZXJfcGVyY2VudFx1MDAzZDBcdTAwMjZwb2x5bWVyX3ZlcmlmaXlfYXBwX3N0YXRlXHUwMDNkdHJ1ZVx1MDAyNnByZXNraXBfYnV0dG9uX3N0eWxlX2Fkc19iYWNrZW5kXHUwMDNkY291bnRkb3duX25leHRfdG9fdGh1bWJuYWlsXHUwMDI2cW9lX253bF9kb3dubG9hZHNcdTAwM2R0cnVlXHUwMDI2cW9lX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnJlY29yZF9hcHBfY3Jhc2hlZF93ZWJcdTAwM2R0cnVlXHUwMDI2cmVwbGFjZV9wbGF5YWJpbGl0eV9yZXRyaWV2ZXJfaW5fd2F0Y2hcdTAwM2R0cnVlXHUwMDI2c2NoZWR1bGVyX3VzZV9yYWZfYnlfZGVmYXVsdFx1MDAzZHRydWVcdTAwMjZzZWxmX3BvZGRpbmdfaGVhZGVyX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19pbnRlcnN0aXRpYWxfbWVzc2FnZVx1MDAyNnNlbGZfcG9kZGluZ19oaWdobGlnaHRfbm9uX2RlZmF1bHRfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZV9zdHJpbmdfdGVtcGxhdGVcdTAwM2RzZWxmX3BvZGRpbmdfbWlkcm9sbF9jaG9pY2VcdTAwMjZzZW5kX2NvbmZpZ19oYXNoX3RpbWVyXHUwMDNkMFx1MDAyNnNldF9pbnRlcnN0aXRpYWxfYWR2ZXJ0aXNlcnNfcXVlc3Rpb25fdGV4dFx1MDAzZHRydWVcdTAwMjZzaG9ydF9zdGFydF90aW1lX3ByZWZlcl9wdWJsaXNoX2luX3dhdGNoX2xvZ1x1MDAzZHRydWVcdTAwMjZzaG9ydHNfbW9kZV90b19wbGF5ZXJfYXBpXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19ub19zdG9wX3ZpZGVvX2NhbGxcdTAwM2R0cnVlXHUwMDI2c2hvdWxkX2NsZWFyX3ZpZGVvX2RhdGFfb25fcGxheWVyX2N1ZWRfdW5zdGFydGVkXHUwMDNkdHJ1ZVx1MDAyNnNpbXBseV9lbWJlZGRlZF9lbmFibGVfYm90Z3VhcmRcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbmxpbmVfbXV0ZWRfbGljZW5zZV9zZXJ2aWNlX2NoZWNrXHUwMDNkdHJ1ZVx1MDAyNnNraXBfaW52YWxpZF95dGNzaV90aWNrc1x1MDAzZHRydWVcdTAwMjZza2lwX2xzX2dlbF9yZXRyeVx1MDAzZHRydWVcdTAwMjZza2lwX3NldHRpbmdfaW5mb19pbl9jc2lfZGF0YV9vYmplY3RcdTAwM2R0cnVlXHUwMDI2c2xvd19jb21wcmVzc2lvbnNfYmVmb3JlX2FiYW5kb25fY291bnRcdTAwM2Q0XHUwMDI2c3BlZWRtYXN0ZXJfY2FuY2VsbGF0aW9uX21vdmVtZW50X2RwXHUwMDNkMFx1MDAyNnNwZWVkbWFzdGVyX3BsYXliYWNrX3JhdGVcdTAwM2QwLjBcdTAwMjZzcGVlZG1hc3Rlcl90b3VjaF9hY3RpdmF0aW9uX21zXHUwMDNkMFx1MDAyNnN0YXJ0X2NsaWVudF9nY2ZcdTAwM2R0cnVlXHUwMDI2c3RhcnRfY2xpZW50X2djZl9mb3JfcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNnN0YXJ0X3NlbmRpbmdfY29uZmlnX2hhc2hcdTAwM2R0cnVlXHUwMDI2c3RyZWFtaW5nX2RhdGFfZW1lcmdlbmN5X2l0YWdfYmxhY2tsaXN0XHUwMDNkW11cdTAwMjZzdXBwcmVzc19lcnJvcl8yMDRfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZ0cmFuc3BvcnRfdXNlX3NjaGVkdWxlclx1MDAzZHRydWVcdTAwMjZ0dl9wYWNmX2xvZ2dpbmdfc2FtcGxlX3JhdGVcdTAwM2QwLjAxXHUwMDI2dHZodG1sNV91bnBsdWdnZWRfcHJlbG9hZF9jYWNoZV9zaXplXHUwMDNkNVx1MDAyNnVuY292ZXJfYWRfYmFkZ2Vfb25fUlRMX3Rpbnlfd2luZG93XHUwMDNkdHJ1ZVx1MDAyNnVucGx1Z2dlZF9kYWlfbGl2ZV9jaHVua19yZWFkYWhlYWRcdTAwM2QzXHUwMDI2dW5wbHVnZ2VkX3R2aHRtbDVfdmlkZW9fcHJlbG9hZF9vbl9mb2N1c19kZWxheV9tc1x1MDAzZDBcdTAwMjZ1cGRhdGVfbG9nX2V2ZW50X2NvbmZpZ1x1MDAzZHRydWVcdTAwMjZ1c2VfYWNjZXNzaWJpbGl0eV9kYXRhX29uX2Rlc2t0b3BfcGxheWVyX2J1dHRvblx1MDAzZHRydWVcdTAwMjZ1c2VfY29yZV9zbVx1MDAzZHRydWVcdTAwMjZ1c2VfaW5saW5lZF9wbGF5ZXJfcnBjXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfY21sXHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfaW5fbWVtb3J5X3N0b3JhZ2VcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfaW5pdGlhbGl6YXRpb25cdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc2F3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3N0d1x1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF93dHNcdTAwM2R0cnVlXHUwMDI2dXNlX3BsYXllcl9hYnVzZV9iZ19saWJyYXJ5XHUwMDNkdHJ1ZVx1MDAyNnVzZV9wcm9maWxlcGFnZV9ldmVudF9sYWJlbF9pbl9jYXJvdXNlbF9wbGF5YmFja3NcdTAwM2R0cnVlXHUwMDI2dXNlX3JlcXVlc3RfdGltZV9tc19oZWFkZXJcdTAwM2R0cnVlXHUwMDI2dXNlX3Nlc3Npb25fYmFzZWRfc2FtcGxpbmdcdTAwM2R0cnVlXHUwMDI2dXNlX3RzX3Zpc2liaWxpdHlsb2dnZXJcdTAwM2R0cnVlXHUwMDI2dmFyaWFibGVfYnVmZmVyX3RpbWVvdXRfbXNcdTAwM2QwXHUwMDI2dmVyaWZ5X2Fkc19pdGFnX2Vhcmx5XHUwMDNkdHJ1ZVx1MDAyNnZwOV9kcm1fbGl2ZVx1MDAzZHRydWVcdTAwMjZ2c3NfZmluYWxfcGluZ19zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZ2c3NfcGluZ3NfdXNpbmdfbmV0d29ya2xlc3NcdTAwM2R0cnVlXHUwMDI2dnNzX3BsYXliYWNrX3VzZV9zZW5kX2FuZF93cml0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfYXBpX3VybFx1MDAzZHRydWVcdTAwMjZ3ZWJfYXN5bmNfY29udGV4dF9wcm9jZXNzb3JfaW1wbFx1MDAzZHN0YW5kYWxvbmVcdTAwMjZ3ZWJfY2luZW1hdGljX3dhdGNoX3NldHRpbmdzXHUwMDNkdHJ1ZVx1MDAyNndlYl9jbGllbnRfdmVyc2lvbl9vdmVycmlkZVx1MDAzZFx1MDAyNndlYl9kZWR1cGVfdmVfZ3JhZnRpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX2RlcHJlY2F0ZV9zZXJ2aWNlX2FqYXhfbWFwX2RlcGVuZGVuY3lcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV9lcnJvcl8yMDRcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV9pbnN0cmVhbV9hZHNfbGlua19kZWZpbml0aW9uX2ExMXlfYnVnZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9lbmFibGVfdm96X2F1ZGlvX2ZlZWRiYWNrXHUwMDNkdHJ1ZVx1MDAyNndlYl9maXhfZmluZV9zY3J1YmJpbmdfZHJhZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZm9yZWdyb3VuZF9oZWFydGJlYXRfaW50ZXJ2YWxfbXNcdTAwM2QyODAwMFx1MDAyNndlYl9mb3J3YXJkX2NvbW1hbmRfb25fcGJqXHUwMDNkdHJ1ZVx1MDAyNndlYl9nZWxfZGVib3VuY2VfbXNcdTAwM2Q2MDAwMFx1MDAyNndlYl9nZWxfdGltZW91dF9jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX2lubGluZV9wbGF5ZXJfbm9fcGxheWJhY2tfdWlfY2xpY2tfaGFuZGxlclx1MDAzZHRydWVcdTAwMjZ3ZWJfa2V5X21vbWVudHNfbWFya2Vyc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nX21lbW9yeV90b3RhbF9rYnl0ZXNcdTAwM2R0cnVlXHUwMDI2d2ViX2xvZ2dpbmdfbWF4X2JhdGNoXHUwMDNkMTUwXHUwMDI2d2ViX21vZGVybl9hZHNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fYnV0dG9uc19ibF9zdXJ2ZXlcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9zY3J1YmJlclx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3N1YnNjcmliZVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3N1YnNjcmliZV9zdHlsZVx1MDAzZGZpbGxlZFx1MDAyNndlYl9uZXdfYXV0b25hdl9jb3VudGRvd25cdTAwM2R0cnVlXHUwMDI2d2ViX29uZV9wbGF0Zm9ybV9lcnJvcl9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfb3Bfc2lnbmFsX3R5cGVfYmFubGlzdFx1MDAzZFtdXHUwMDI2d2ViX3BhdXNlZF9vbmx5X21pbmlwbGF5ZXJfc2hvcnRjdXRfZXhwYW5kXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5YmFja19hc3NvY2lhdGVkX2xvZ19jdHRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfdmVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hZGRfdmVfY29udmVyc2lvbl9sb2dnaW5nX3RvX291dGJvdW5kX2xpbmtzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYWx3YXlzX2VuYWJsZV9hdXRvX3RyYW5zbGF0aW9uXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXBpX2xvZ2dpbmdfZnJhY3Rpb25cdTAwM2QwLjAxXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X2VtcHR5X3N1Z2dlc3Rpb25zX2ZpeFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdG9nZ2xlX2Fsd2F5c19saXN0ZW5cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hdXRvbmF2X3VzZV9zZXJ2ZXJfcHJvdmlkZWRfc3RhdGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9jYXB0aW9uX2xhbmd1YWdlX3ByZWZlcmVuY2Vfc3RpY2tpbmVzc19kdXJhdGlvblx1MDAzZDMwXHUwMDI2d2ViX3BsYXllcl9kZWNvdXBsZV9hdXRvbmF2XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZGlzYWJsZV9pbmxpbmVfc2NydWJiaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX2Vhcmx5X3dhcm5pbmdfc25hY2tiYXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZmVhdHVyZWRfcHJvZHVjdF9iYW5uZXJfb25fZGVza3RvcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9pbl9oNV9hcGlcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfcHJlbWl1bV9oYnJfcGxheWJhY2tfY2FwXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaW5uZXJ0dWJlX3BsYXlsaXN0X3VwZGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2lwcF9jYW5hcnlfdHlwZV9mb3JfbG9nZ2luZ1x1MDAzZFx1MDAyNndlYl9wbGF5ZXJfbGl2ZV9tb25pdG9yX2Vudlx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2xvZ19jbGlja19iZWZvcmVfZ2VuZXJhdGluZ192ZV9jb252ZXJzaW9uX3BhcmFtc1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX21vdmVfYXV0b25hdl90b2dnbGVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9tdXNpY192aXN1YWxpemVyX3RyZWF0bWVudFx1MDAzZGZha2VcdTAwMjZ3ZWJfcGxheWVyX211dGFibGVfZXZlbnRfbGFiZWxcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9uaXRyYXRlX3Byb21vX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9vZmZsaW5lX3BsYXlsaXN0X2F1dG9fcmVmcmVzaFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Jlc3BvbnNlX3BsYXliYWNrX3RyYWNraW5nX3BhcnNpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZWVrX2NoYXB0ZXJzX2J5X3Nob3J0Y3V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2VudGluZWxfaXNfdW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfc2hvdWxkX2hvbm9yX2luY2x1ZGVfYXNyX3NldHRpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG93X211c2ljX2luX3RoaXNfdmlkZW9fZ3JhcGhpY1x1MDAzZHZpZGVvX3RodW1ibmFpbFx1MDAyNndlYl9wbGF5ZXJfc21hbGxfaGJwX3NldHRpbmdzX21lbnVcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zc19kYWlfYWRfZmV0Y2hpbmdfdGltZW91dF9tc1x1MDAzZDE1MDAwXHUwMDI2d2ViX3BsYXllcl9zc19tZWRpYV90aW1lX29mZnNldFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RvcGlmeV9zdWJ0aXRsZXNfZm9yX3Nob3J0c1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3RvdWNoX21vZGVfaW1wcm92ZW1lbnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdHJhbnNmZXJfdGltZW91dF90aHJlc2hvbGRfbXNcdTAwM2QxMDgwMDAwMFx1MDAyNndlYl9wbGF5ZXJfdW5zZXRfZGVmYXVsdF9jc25fa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3VzZV9uZXdfYXBpX2Zvcl9xdWFsaXR5X3B1bGxiYWNrXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdmVfY29udmVyc2lvbl9maXhlc19mb3JfY2hhbm5lbF9pbmZvXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3dhdGNoX25leHRfcmVzcG9uc2VfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcHJlZmV0Y2hfcHJlbG9hZF92aWRlb1x1MDAzZHRydWVcdTAwMjZ3ZWJfcm91bmRlZF90aHVtYm5haWxzXHUwMDNkdHJ1ZVx1MDAyNndlYl9zZXR0aW5nc19tZW51X2ljb25zXHUwMDNkdHJ1ZVx1MDAyNndlYl9zbW9vdGhuZXNzX3Rlc3RfZHVyYXRpb25fbXNcdTAwM2QwXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9tZXRob2RcdTAwM2QwXHUwMDI2d2ViX3l0X2NvbmZpZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNndpbF9pY29uX3JlbmRlcl93aGVuX2lkbGVcdTAwM2R0cnVlXHUwMDI2d29mZmxlX2NsZWFuX3VwX2FmdGVyX2VudGl0eV9taWdyYXRpb25cdTAwM2R0cnVlXHUwMDI2d29mZmxlX2VuYWJsZV9kb3dubG9hZF9zdGF0dXNcdTAwM2R0cnVlXHUwMDI2d29mZmxlX3BsYXlsaXN0X29wdGltaXphdGlvblx1MDAzZHRydWVcdTAwMjZ5dGlkYl9jbGVhcl9lbWJlZGRlZF9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2eXRpZGJfZmV0Y2hfZGF0YXN5bmNfaWRzX2Zvcl9kYXRhX2NsZWFudXBcdTAwM2R0cnVlXHUwMDI2eXRpZGJfcmVtYWtlX2RiX3JldHJpZXNcdTAwM2QxXHUwMDI2eXRpZGJfcmVvcGVuX2RiX3JldHJpZXNcdTAwM2QwXHUwMDI2eXRpZGJfdHJhbnNhY3Rpb25fZW5kZWRfZXZlbnRfcmF0ZV9saW1pdFx1MDAzZDAuMDJcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0X3Nlc3Npb25cdTAwM2QwLjJcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0X3RyYW5zYWN0aW9uXHUwMDNkMC4xIiwiZGlzYWJsZUZ1bGxzY3JlZW4iOnRydWUsImNzcE5vbmNlIjoiaGFFb1loak96WUdqQngyNENYUkJ5USIsImNhbmFyeVN0YXRlIjoibm9uZSIsImVuYWJsZUNzaUxvZ2dpbmciOnRydWUsImNzaVBhZ2VUeXBlIjoid2F0Y2giLCJkaXNhYmxlTWR4Q2FzdCI6dHJ1ZSwiZGF0YXN5bmNJZCI6IlZlYTMwNzlmYnx8Iiwic2hvd0lubGluZVByZXZpZXdVaSI6dHJ1ZX0sIldFQl9QTEFZRVJfQ09OVEVYVF9DT05GSUdfSURfSEFORExFU19DTEFJTUlORyI6eyJyb290RWxlbWVudElkIjoieXRkLWhhbmRsZXMtY2xhaW1pbmctdmlkZW8taXRlbS1yZW5kZXJlciIsImpzVXJsIjoiL3MvcGxheWVyL2IxMjhkZGEwL3BsYXllcl9pYXMudmZsc2V0L2ZyX0ZSL2Jhc2UuanMiLCJjc3NVcmwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvd3d3LXBsYXllci5jc3MiLCJjb250ZXh0SWQiOiJXRUJfUExBWUVSX0NPTlRFWFRfQ09ORklHX0lEX0hBTkRMRVNfQ0xBSU1JTkciLCJldmVudExhYmVsIjoiaGFuZGxlc2NsYWltaW5nIiwiY29udGVudFJlZ2lvbiI6IkZSIiwiaGwiOiJmcl9GUiIsImhvc3RMYW5ndWFnZSI6ImZyIiwicGxheWVyU3R5bGUiOiJkZXNrdG9wLXBvbHltZXIiLCJpbm5lcnR1YmVBcGlLZXkiOiJBSXphU3lBT19GSjJTbHFVOFE0U1RFSExHQ2lsd19ZOV8xMXFjVzgiLCJpbm5lcnR1YmVBcGlWZXJzaW9uIjoidjEiLCJpbm5lcnR1YmVDb250ZXh0Q2xpZW50VmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAiLCJkaXNhYmxlUmVsYXRlZFZpZGVvcyI6dHJ1ZSwiZGV2aWNlIjp7ImJyYW5kIjoiIiwibW9kZWwiOiIiLCJwbGF0Zm9ybSI6IkRFU0tUT1AiLCJpbnRlcmZhY2VOYW1lIjoiV0VCIiwiaW50ZXJmYWNlVmVyc2lvbiI6IjIuMjAyMzA2MDcuMDYuMDAifSwic2VyaWFsaXplZEV4cGVyaW1lbnRJZHMiOiIyMzg1ODA1NywyMzk4MzI5NiwyMzk4NjAzMywyNDAwNDY0NCwyNDAwNzI0NiwyNDA4MDczOCwyNDEzNTMxMCwyNDM2MjY4NSwyNDM2MjY4OCwyNDM2MzExNCwyNDM2NDc4OSwyNDM2NjkxNywyNDM3MDg5OCwyNDM3NzM0NiwyNDQxNTg2NCwyNDQzMzY3OSwyNDQzNzU3NywyNDQzOTM2MSwyNDQ5MjU0NywyNDUzMjg1NSwyNDU1MDQ1OCwyNDU1MDk1MSwyNDU1ODY0MSwyNDU1OTMyNiwyNDY5OTg5OSwzOTMyMzA3NCIsInNlcmlhbGl6ZWRFeHBlcmltZW50RmxhZ3MiOiJINV9hc3luY19sb2dnaW5nX2RlbGF5X21zXHUwMDNkMzAwMDAuMFx1MDAyNkg1X2VuYWJsZV9mdWxsX3BhY2ZfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZINV91c2VfYXN5bmNfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZhY3Rpb25fY29tcGFuaW9uX2NlbnRlcl9hbGlnbl9kZXNjcmlwdGlvblx1MDAzZHRydWVcdTAwMjZhZF9wb2RfZGlzYWJsZV9jb21wYW5pb25fcGVyc2lzdF9hZHNfcXVhbGl0eVx1MDAzZHRydWVcdTAwMjZhZGR0b19hamF4X2xvZ193YXJuaW5nX2ZyYWN0aW9uXHUwMDNkMC4xXHUwMDI2YWxpZ25fYWRfdG9fdmlkZW9fcGxheWVyX2xpZmVjeWNsZV9mb3JfYnVsbGVpdFx1MDAzZHRydWVcdTAwMjZhbGxvd19saXZlX2F1dG9wbGF5XHUwMDNkdHJ1ZVx1MDAyNmFsbG93X3BvbHRlcmd1c3RfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2YWxsb3dfc2tpcF9uZXR3b3JrbGVzc1x1MDAzZHRydWVcdTAwMjZhdXRvcGxheV90aW1lXHUwMDNkODAwMFx1MDAyNmF1dG9wbGF5X3RpbWVfZm9yX2Z1bGxzY3JlZW5cdTAwM2QzMDAwXHUwMDI2YXV0b3BsYXlfdGltZV9mb3JfbXVzaWNfY29udGVudFx1MDAzZDMwMDBcdTAwMjZiZ192bV9yZWluaXRfdGhyZXNob2xkXHUwMDNkNzIwMDAwMFx1MDAyNmJsb2NrZWRfcGFja2FnZXNfZm9yX3Nwc1x1MDAzZFtdXHUwMDI2Ym90Z3VhcmRfYXN5bmNfc25hcHNob3RfdGltZW91dF9tc1x1MDAzZDMwMDBcdTAwMjZjaGVja19hZF91aV9zdGF0dXNfZm9yX213ZWJfc2FmYXJpXHUwMDNkdHJ1ZVx1MDAyNmNoZWNrX25hdmlnYXRvcl9hY2N1cmFjeV90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmNsZWFyX3VzZXJfcGFydGl0aW9uZWRfbHNcdTAwM2R0cnVlXHUwMDI2Y2xpZW50X3Jlc3BlY3RfYXV0b3BsYXlfc3dpdGNoX2J1dHRvbl9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZjb21wcmVzc19nZWxcdTAwM2R0cnVlXHUwMDI2Y29tcHJlc3Npb25fZGlzYWJsZV9wb2ludFx1MDAzZDEwXHUwMDI2Y29tcHJlc3Npb25fcGVyZm9ybWFuY2VfdGhyZXNob2xkXHUwMDNkMjUwXHUwMDI2Y3NpX29uX2dlbFx1MDAzZHRydWVcdTAwMjZkYXNoX21hbmlmZXN0X3ZlcnNpb25cdTAwM2Q1XHUwMDI2ZGVidWdfYmFuZGFpZF9ob3N0bmFtZVx1MDAzZFx1MDAyNmRlYnVnX3NoZXJsb2dfdXNlcm5hbWVcdTAwM2RcdTAwMjZkZWxheV9hZHNfZ3ZpX2NhbGxfb25fYnVsbGVpdF9saXZpbmdfcm9vbV9tc1x1MDAzZDBcdTAwMjZkZXByZWNhdGVfY3NpX2hhc19pbmZvXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV9wYWlyX3NlcnZsZXRfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZkZXByZWNhdGVfdHdvX3dheV9iaW5kaW5nX2NoaWxkXHUwMDNkdHJ1ZVx1MDAyNmRlcHJlY2F0ZV90d29fd2F5X2JpbmRpbmdfcGFyZW50XHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3BfaW1hZ2VfY3RhX25vX2JhY2tncm91bmRcdTAwM2R0cnVlXHUwMDI2ZGVza3RvcF9sb2dfaW1nX2NsaWNrX2xvY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmRlc2t0b3Bfc3BhcmtsZXNfbGlnaHRfY3RhX2J1dHRvblx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoYW5uZWxfaWRfY2hlY2tfZm9yX3N1c3BlbmRlZF9jaGFubmVsc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2NoaWxkX25vZGVfYXV0b19mb3JtYXR0ZWRfc3RyaW5nc1x1MDAzZHRydWVcdTAwMjZkaXNhYmxlX2RlZmVyX2FkbW9kdWxlX29uX2FkdmVydGlzZXJfdmlkZW9cdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9mZWF0dXJlc19mb3Jfc3VwZXhcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9sZWdhY3lfZGVza3RvcF9yZW1vdGVfcXVldWVcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9tZHhfY29ubmVjdGlvbl9pbl9tZHhfbW9kdWxlX2Zvcl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9uZXdfcGF1c2Vfc3RhdGUzXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfcGFjZl9sb2dnaW5nX2Zvcl9tZW1vcnlfbGltaXRlZF90dlx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3JvdW5kaW5nX2FkX25vdGlmeVx1MDAzZHRydWVcdTAwMjZkaXNhYmxlX3NpbXBsZV9taXhlZF9kaXJlY3Rpb25fZm9ybWF0dGVkX3N0cmluZ3NcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV9zc2RhaV9vbl9lcnJvcnNcdTAwM2R0cnVlXHUwMDI2ZGlzYWJsZV90YWJiaW5nX2JlZm9yZV9mbHlvdXRfYWRfZWxlbWVudHNfYXBwZWFyXHUwMDNkdHJ1ZVx1MDAyNmRpc2FibGVfdGh1bWJuYWlsX3ByZWxvYWRpbmdcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX2Rpc2FibGVfcHJvZ3Jlc3NfYmFyX2NvbnRleHRfbWVudV9oYW5kbGluZ1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfZW5hYmxlX2FsbG93X3dhdGNoX2FnYWluX2VuZHNjcmVlbl9mb3JfZWxpZ2libGVfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc192ZV9jb252ZXJzaW9uX3BhcmFtX3JlbmFtaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2F1dG9wbGF5X25vdF9zdXBwb3J0ZWRfbG9nZ2luZ19maXhcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfY3VlX3ZpZGVvX3VucGxheWFibGVfZml4XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX2hvdXNlX2JyYW5kX2FuZF95dF9jb2V4aXN0ZW5jZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2FkX3BsYXllcl9mcm9tX3BhZ2Vfc2hvd1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9sb2dfc3BsYXlfYXNfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbG9nZ2luZ19ldmVudF9oYW5kbGVyc1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9tb2JpbGVfYXV0b3BsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbW9iaWxlX2R0dHNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfbmV3X2NvbnRleHRfbWVudV90cmlnZ2VyaW5nXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BhdXNlX292ZXJsYXlfd25fdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3BlbV9kb21haW5fZml4X2Zvcl9hZF9yZXF1ZXN0c1x1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV9wZnBfdW5icmFuZGVkX2VsX2RlcHJlY2F0aW9uXHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JjYXRfYWxsb3dsaXN0XHUwMDNkdHJ1ZVx1MDAyNmVtYmVkc193ZWJfZW5hYmxlX3JlcGxhY2VfdW5sb2FkX3dfcGFnZWhpZGVcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9lbmFibGVfc2NyaXB0ZWRfcGxheWJhY2tfYmxvY2tlZF9sb2dnaW5nX2ZpeFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2VuYWJsZV92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdHJhY2tpbmdfbm9fYWxsb3dfbGlzdFx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX2hpZGVfdW5maWxsZWRfbW9yZV92aWRlb3Nfc3VnZ2VzdGlvbnNcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9saXRlX21vZGVcdTAwM2QxXHUwMDI2ZW1iZWRzX3dlYl9ud2xfZGlzYWJsZV9ub2Nvb2tpZVx1MDAzZHRydWVcdTAwMjZlbWJlZHNfd2ViX3Nob3BwaW5nX292ZXJsYXlfbm9fd2FpdF9mb3JfcGFpZF9jb250ZW50X292ZXJsYXlcdTAwM2R0cnVlXHUwMDI2ZW1iZWRzX3dlYl9zeW50aF9jaF9oZWFkZXJzX2Jhbm5lZF91cmxzX3JlZ2V4XHUwMDNkXHUwMDI2ZW5hYmxlX2FiX3JwX2ludFx1MDAzZHRydWVcdTAwMjZlbmFibGVfYWRfY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2FwcF9wcm9tb19lbmRjYXBfZW1sX29uX3RhYmxldFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9mb3Jfd2ViX3VucGx1Z2dlZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfY2FzdF9vbl9tdXNpY193ZWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9wYWdlX2lkX2hlYWRlcl9mb3JfZmlyc3RfcGFydHlfcGluZ3NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2NsaWVudF9zbGlfbG9nZ2luZ1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZGlzY3JldGVfbGl2ZV9wcmVjaXNlX2VtYmFyZ29zXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9lcnJvcl9jb3JyZWN0aW9uc19pbmZvY2FyZFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudFx1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRfd2ViX2NsaWVudF9jaGVja1x1MDAzZHRydWVcdTAwMjZlbmFibGVfZXJyb3JfY29ycmVjdGlvbnNfaW5mb2NhcmRzX2ljb25fd2ViXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9ldmljdGlvbl9wcm90ZWN0aW9uX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9nZWxfbG9nX2NvbW1hbmRzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9oNV9pbnN0cmVhbV93YXRjaF9uZXh0X3BhcmFtc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2g1X3ZpZGVvX2Fkc19vYXJsaWJcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX2hhbmRsZXNfYWNjb3VudF9tZW51X3N3aXRjaGVyXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9rYWJ1a2lfY29tbWVudHNfb25fc2hvcnRzXHUwMDNkZGlzYWJsZWRcdTAwMjZlbmFibGVfbGl2ZV9wcmVtaWVyZV93ZWJfcGxheWVyX2luZGljYXRvclx1MDAzZHRydWVcdTAwMjZlbmFibGVfbHJfaG9tZV9pbmZlZWRfYWRzX2lubGluZV9wbGF5YmFja19wcm9ncmVzc19waW5nc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfbWl4ZWRfZGlyZWN0aW9uX2Zvcm1hdHRlZF9zdHJpbmdzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9td2ViX2xpdmVzdHJlYW1fdWlfdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9uZXdfcGFpZF9wcm9kdWN0X3BsYWNlbWVudFx1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl9zbG90X2FzZGVfcGxheWVyX2J5dGVfaDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3BhY2ZfdGhyb3VnaF95YmZlX3R2XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wYWNmX3Rocm91Z2hfeWJmZV90dl9mb3JfcGFnZV90b3BfZm9ybWF0c1x1MDAzZHRydWVcdTAwMjZlbmFibGVfcGFjZl90aHJvdWdoX3lzZmVfdHZcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Bhc3Nfc2RjX2dldF9hY2NvdW50c19saXN0XHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV9wbF9yX2NcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Bvc3RfYWRfcGVyY2VwdGlvbl9zdXJ2ZXlfZml4X29uX3R2aHRtbDVcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3Bvc3RfYWRfcGVyY2VwdGlvbl9zdXJ2ZXlfaW5fdHZodG1sNVx1MDAzZHRydWVcdTAwMjZlbmFibGVfcHJlY2lzZV9lbWJhcmdvc1x1MDAzZHRydWVcdTAwMjZlbmFibGVfc2VydmVyX3N0aXRjaGVkX2RhaVx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2hvcnRzX3BsYXllclx1MDAzZHRydWVcdTAwMjZlbmFibGVfc2tpcF9hZF9ndWlkYW5jZV9wcm9tcHRcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3NraXBwYWJsZV9hZHNfZm9yX3VucGx1Z2dlZF9hZF9wb2RcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3RlY3RvbmljX2FkX3V4X2Zvcl9oYWxmdGltZVx1MDAzZHRydWVcdTAwMjZlbmFibGVfdGhpcmRfcGFydHlfaW5mb1x1MDAzZHRydWVcdTAwMjZlbmFibGVfdG9wc29pbF93dGFfZm9yX2hhbGZ0aW1lX2xpdmVfaW5mcmFcdTAwM2R0cnVlXHUwMDI2ZW5hYmxlX3dlYl9tZWRpYV9zZXNzaW9uX21ldGFkYXRhX2ZpeFx1MDAzZHRydWVcdTAwMjZlbmFibGVfd2ViX3NjaGVkdWxlcl9zaWduYWxzXHUwMDNkdHJ1ZVx1MDAyNmVuYWJsZV95dF9hdGFfaWZyYW1lX2F1dGh1c2VyXHUwMDNkdHJ1ZVx1MDAyNmVycm9yX21lc3NhZ2VfZm9yX2dzdWl0ZV9uZXR3b3JrX3Jlc3RyaWN0aW9uc1x1MDAzZHRydWVcdTAwMjZleHBvcnRfbmV0d29ya2xlc3Nfb3B0aW9uc1x1MDAzZHRydWVcdTAwMjZleHRlcm5hbF9mdWxsc2NyZWVuX3dpdGhfZWR1XHUwMDNkdHJ1ZVx1MDAyNmZhc3RfYXV0b25hdl9pbl9iYWNrZ3JvdW5kXHUwMDNkdHJ1ZVx1MDAyNmZldGNoX2F0dF9pbmRlcGVuZGVudGx5XHUwMDNkdHJ1ZVx1MDAyNmZpbGxfc2luZ2xlX3ZpZGVvX3dpdGhfbm90aWZ5X3RvX2xhc3JcdTAwM2R0cnVlXHUwMDI2ZmlsdGVyX3ZwOV9mb3JfY3NkYWlcdTAwM2R0cnVlXHUwMDI2Zml4X2Fkc190cmFja2luZ19mb3Jfc3dmX2NvbmZpZ19kZXByZWNhdGlvbl9td2ViXHUwMDNkdHJ1ZVx1MDAyNmdjZl9jb25maWdfc3RvcmVfZW5hYmxlZFx1MDAzZHRydWVcdTAwMjZnZWxfcXVldWVfdGltZW91dF9tYXhfbXNcdTAwM2QzMDAwMDBcdTAwMjZncGFfc3BhcmtsZXNfdGVuX3BlcmNlbnRfbGF5ZXJcdTAwM2R0cnVlXHUwMDI2Z3ZpX2NoYW5uZWxfY2xpZW50X3NjcmVlblx1MDAzZHRydWVcdTAwMjZoNV9jb21wYW5pb25fZW5hYmxlX2FkY3BuX21hY3JvX3N1YnN0aXR1dGlvbl9mb3JfY2xpY2tfcGluZ3NcdTAwM2R0cnVlXHUwMDI2aDVfZW5hYmxlX2dlbmVyaWNfZXJyb3JfbG9nZ2luZ19ldmVudFx1MDAzZHRydWVcdTAwMjZoNV9lbmFibGVfdW5pZmllZF9jc2lfcHJlcm9sbFx1MDAzZHRydWVcdTAwMjZoNV9pbnBsYXllcl9lbmFibGVfYWRjcG5fbWFjcm9fc3Vic3RpdHV0aW9uX2Zvcl9jbGlja19waW5nc1x1MDAzZHRydWVcdTAwMjZoNV9yZXNldF9jYWNoZV9hbmRfZmlsdGVyX2JlZm9yZV91cGRhdGVfbWFzdGhlYWRcdTAwM2R0cnVlXHUwMDI2aGVhdHNlZWtlcl9kZWNvcmF0aW9uX3RocmVzaG9sZFx1MDAzZDAuMFx1MDAyNmhmcl9kcm9wcGVkX2ZyYW1lcmF0ZV9mYWxsYmFja190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aGlkZV9lbmRwb2ludF9vdmVyZmxvd19vbl95dGRfZGlzcGxheV9hZF9yZW5kZXJlclx1MDAzZHRydWVcdTAwMjZodG1sNV9hZF90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2Fkc19wcmVyb2xsX2xvY2tfdGltZW91dF9kZWxheV9tc1x1MDAzZDE1MDAwXHUwMDI2aHRtbDVfYWxsb3dfZGlzY29udGlndW91c19zbGljZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfYWxsb3dfdmlkZW9fa2V5ZnJhbWVfd2l0aG91dF9hdWRpb1x1MDAzZHRydWVcdTAwMjZodG1sNV9hdHRhY2hfbnVtX3JhbmRvbV9ieXRlc190b19iYW5kYWlkXHUwMDNkMFx1MDAyNmh0bWw1X2F0dGFjaF9wb190b2tlbl90b19iYW5kYWlkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2F1dG9uYXZfY2FwX2lkbGVfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9hdXRvbmF2X3F1YWxpdHlfY2FwXHUwMDNkNzIwXHUwMDI2aHRtbDVfYXV0b3BsYXlfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9ibG9ja19waXBfc2FmYXJpX2RlbGF5XHUwMDNkMFx1MDAyNmh0bWw1X2JtZmZfbmV3X2ZvdXJjY19jaGVja1x1MDAzZHRydWVcdTAwMjZodG1sNV9jb2JhbHRfZGVmYXVsdF9idWZmZXJfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWF4X3NpemVfZm9yX2ltbWVkX2pvYlx1MDAzZDBcdTAwMjZodG1sNV9jb2JhbHRfbWluX3Byb2Nlc3Nvcl9jbnRfdG9fb2ZmbG9hZF9hbGdvXHUwMDNkMFx1MDAyNmh0bWw1X2NvYmFsdF9vdmVycmlkZV9xdWljXHUwMDNkMFx1MDAyNmh0bWw1X2NvbnN1bWVfbWVkaWFfYnl0ZXNfc2xpY2VfaW5mb3NcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVfZHVwZV9jb250ZW50X3ZpZGVvX2xvYWRzX2luX2xpZmVjeWNsZV9hcGlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVidWdfZGF0YV9sb2dfcHJvYmFiaWxpdHlcdTAwM2QwLjFcdTAwMjZodG1sNV9kZWNvZGVfdG9fdGV4dHVyZV9jYXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGVmYXVsdF9hZF9nYWluXHUwMDNkMC41XHUwMDI2aHRtbDVfZGVmYXVsdF9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9kZWZlcl9hZF9tb2R1bGVfbXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVmZXJfZmV0Y2hfYXR0X21zXHUwMDNkMTAwMFx1MDAyNmh0bWw1X2RlZmVyX21vZHVsZXNfZGVsYXlfdGltZV9taWxsaXNcdTAwM2QwXHUwMDI2aHRtbDVfZGVsYXllZF9yZXRyeV9jb3VudFx1MDAzZDFcdTAwMjZodG1sNV9kZWxheWVkX3JldHJ5X2RlbGF5X21zXHUwMDNkNTAwMFx1MDAyNmh0bWw1X2RlcHJlY2F0ZV92aWRlb190YWdfcG9vbFx1MDAzZHRydWVcdTAwMjZodG1sNV9kZXNrdG9wX3ZyMTgwX2FsbG93X3Bhbm5pbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGZfZG93bmdyYWRlX3RocmVzaFx1MDAzZDAuMlx1MDAyNmh0bWw1X2Rpc2FibGVfY3NpX2Zvcl9idWxsZWl0XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2Rpc2FibGVfbW92ZV9wc3NoX3RvX21vb3ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZGlzYWJsZV9ub25fY29udGlndW91c1x1MDAzZHRydWVcdTAwMjZodG1sNV9kaXNwbGF5ZWRfZnJhbWVfcmF0ZV9kb3duZ3JhZGVfdGhyZXNob2xkXHUwMDNkNDVcdTAwMjZodG1sNV9kcm1fY2hlY2tfYWxsX2tleV9lcnJvcl9zdGF0ZXNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZHJtX2NwaV9saWNlbnNlX2tleVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfYWMzXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9hZHNfY2xpZW50X21vbml0b3JpbmdfbG9nX3R2XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jYXB0aW9uX2NoYW5nZXNfZm9yX21vc2FpY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfY2xpZW50X2hpbnRzX292ZXJyaWRlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV9jb21wb3NpdGVfZW1iYXJnb1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZWFjM1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfZW1iZWRkZWRfcGxheWVyX3Zpc2liaWxpdHlfc2lnbmFsc1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfbmV3X2h2Y19lbmNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX25vbl9ub3RpZnlfY29tcG9zaXRlX3ZvZF9sc2FyX3BhY2ZcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3NpbmdsZV92aWRlb192b2RfaXZhcl9vbl9wYWNmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuYWJsZV90dm9zX2Rhc2hcdTAwM2R0cnVlXHUwMDI2aHRtbDVfZW5hYmxlX3R2b3NfZW5jcnlwdGVkX3ZwOVx1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfd2lkZXZpbmVfZm9yX2FsY1x1MDAzZHRydWVcdTAwMjZodG1sNV9lbmFibGVfd2lkZXZpbmVfZm9yX2Zhc3RfbGluZWFyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2VuY291cmFnZV9hcnJheV9jb2FsZXNjaW5nXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2dhcGxlc3NfZW5kZWRfdHJhbnNpdGlvbl9idWZmZXJfbXNcdTAwM2QyMDBcdTAwMjZodG1sNV9nZW5lcmF0ZV9zZXNzaW9uX3BvX3Rva2VuXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2dsX2Zwc190aHJlc2hvbGRcdTAwM2QwXHUwMDI2aHRtbDVfaGRjcF9wcm9iaW5nX3N0cmVhbV91cmxcdTAwM2RcdTAwMjZodG1sNV9oZnJfcXVhbGl0eV9jYXBcdTAwM2QwXHUwMDI2aHRtbDVfaGlnaF9yZXNfbG9nZ2luZ19wZXJjZW50XHUwMDNkMS4wXHUwMDI2aHRtbDVfaWRsZV9yYXRlX2xpbWl0X21zXHUwMDNkMFx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl9mYWlycGxheVx1MDAzZHRydWVcdTAwMjZodG1sNV9pbm5lcnR1YmVfaGVhcnRiZWF0c19mb3JfcGxheXJlYWR5XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2lubmVydHViZV9oZWFydGJlYXRzX2Zvcl93aWRldmluZVx1MDAzZHRydWVcdTAwMjZodG1sNV9pb3M0X3NlZWtfYWJvdmVfemVyb1x1MDAzZHRydWVcdTAwMjZodG1sNV9pb3M3X2ZvcmNlX3BsYXlfb25fc3RhbGxcdTAwM2R0cnVlXHUwMDI2aHRtbDVfaW9zX2ZvcmNlX3NlZWtfdG9femVyb19vbl9zdG9wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2p1bWJvX21vYmlsZV9zdWJzZWdtZW50X3JlYWRhaGVhZF90YXJnZXRcdTAwM2QzLjBcdTAwMjZodG1sNV9qdW1ib191bGxfbm9uc3RyZWFtaW5nX21mZmFfbXNcdTAwM2Q0MDAwXHUwMDI2aHRtbDVfanVtYm9fdWxsX3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldFx1MDAzZDEuM1x1MDAyNmh0bWw1X2xpY2Vuc2VfY29uc3RyYWludF9kZWxheVx1MDAzZDUwMDBcdTAwMjZodG1sNV9saXZlX2Ficl9oZWFkX21pc3NfZnJhY3Rpb25cdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX2Ficl9yZXByZWRpY3RfZnJhY3Rpb25cdTAwM2QwLjBcdTAwMjZodG1sNV9saXZlX2J5dGVyYXRlX2ZhY3Rvcl9mb3JfcmVhZGFoZWFkXHUwMDNkMS4zXHUwMDI2aHRtbDVfbGl2ZV9sb3dfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9tZXRhZGF0YV9maXhcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbGl2ZV9ub3JtYWxfbGF0ZW5jeV9iYW5kd2lkdGhfd2luZG93XHUwMDNkMC4wXHUwMDI2aHRtbDVfbGl2ZV9xdWFsaXR5X2NhcFx1MDAzZDBcdTAwMjZodG1sNV9saXZlX3VsdHJhX2xvd19sYXRlbmN5X2JhbmR3aWR0aF93aW5kb3dcdTAwM2QwLjBcdTAwMjZodG1sNV9sb2dfYXVkaW9fYWJyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X2xvZ19leHBlcmltZW50X2lkX2Zyb21fcGxheWVyX3Jlc3BvbnNlX3RvX2N0bXBcdTAwM2RcdTAwMjZodG1sNV9sb2dfZmlyc3Rfc3NkYWlfcmVxdWVzdHNfa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZodG1sNV9sb2dfcmVidWZmZXJfZXZlbnRzXHUwMDNkNVx1MDAyNmh0bWw1X2xvZ19zc2RhaV9mYWxsYmFja19hZHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbG9nX3RyaWdnZXJfZXZlbnRzX3dpdGhfZGVidWdfZGF0YVx1MDAzZHRydWVcdTAwMjZodG1sNV9sb25nX3JlYnVmZmVyX2ppZ2dsZV9jbXRfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl9uZXdfZWxlbV9zaG9ydHNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfbG9uZ19yZWJ1ZmZlcl90aHJlc2hvbGRfbXNcdTAwM2QzMDAwMFx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc19zZWdfZHJpZnRfbGltaXRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9tYW5pZmVzdGxlc3NfdW5wbHVnZ2VkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21hbmlmZXN0bGVzc192cDlfb3RmXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X21heF9kcmlmdF9wZXJfdHJhY2tfc2Vjc1x1MDAzZDAuMFx1MDAyNmh0bWw1X21heF9oZWFkbV9mb3Jfc3RyZWFtaW5nX3hoclx1MDAzZDBcdTAwMjZodG1sNV9tYXhfbGl2ZV9kdnJfd2luZG93X3BsdXNfbWFyZ2luX3NlY3NcdTAwM2Q0NjgwMC4wXHUwMDI2aHRtbDVfbWF4X3JlYWRiZWhpbmRfc2Vjc1x1MDAzZDBcdTAwMjZodG1sNV9tYXhfcmVkaXJlY3RfcmVzcG9uc2VfbGVuZ3RoXHUwMDNkODE5Mlx1MDAyNmh0bWw1X21heF9zZWxlY3RhYmxlX3F1YWxpdHlfb3JkaW5hbFx1MDAzZDBcdTAwMjZodG1sNV9tYXhfc291cmNlX2J1ZmZlcl9hcHBlbmRfc2l6ZV9pbl9ieXRlc1x1MDAzZDBcdTAwMjZodG1sNV9tYXhpbXVtX3JlYWRhaGVhZF9zZWNvbmRzXHUwMDNkMC4wXHUwMDI2aHRtbDVfbWVkaWFfZnVsbHNjcmVlblx1MDAzZHRydWVcdTAwMjZodG1sNV9tZmxfZXh0ZW5kX21heF9yZXF1ZXN0X3RpbWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfbWluX3JlYWRiZWhpbmRfY2FwX3NlY3NcdTAwM2Q2MFx1MDAyNmh0bWw1X21pbl9yZWFkYmVoaW5kX3NlY3NcdTAwM2QwXHUwMDI2aHRtbDVfbWluX3NlbGVjdGFibGVfcXVhbGl0eV9vcmRpbmFsXHUwMDNkMFx1MDAyNmh0bWw1X21pbl9zdGFydHVwX2J1ZmZlcmVkX2FkX21lZGlhX2R1cmF0aW9uX3NlY3NcdTAwM2QxLjJcdTAwMjZodG1sNV9taW5fc3RhcnR1cF9idWZmZXJlZF9tZWRpYV9kdXJhdGlvbl9zZWNzXHUwMDNkMS4yXHUwMDI2aHRtbDVfbWluaW11bV9yZWFkYWhlYWRfc2Vjb25kc1x1MDAzZDAuMFx1MDAyNmh0bWw1X25vX3BsYWNlaG9sZGVyX3JvbGxiYWNrc1x1MDAzZHRydWVcdTAwMjZodG1sNV9ub25fbmV0d29ya19yZWJ1ZmZlcl9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZodG1sNV9ub25fb25lc2llX2F0dGFjaF9wb190b2tlblx1MDAzZHRydWVcdTAwMjZodG1sNV9ub3RfcmVnaXN0ZXJfZGlzcG9zYWJsZXNfd2hlbl9jb3JlX2xpc3RlbnNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb2ZmbGluZV9mYWlsdXJlX3JldHJ5X2xpbWl0XHUwMDNkMlx1MDAyNmh0bWw1X29uZXNpZV9kZWZlcl9jb250ZW50X2xvYWRlcl9tc1x1MDAzZDBcdTAwMjZodG1sNV9vbmVzaWVfaG9zdF9yYWNpbmdfY2FwX21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9pZ25vcmVfaW5uZXJ0dWJlX2FwaV9rZXlcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX2xpdmVfdHRsX3NlY3NcdTAwM2Q4XHUwMDI2aHRtbDVfb25lc2llX25vbnplcm9fcGxheWJhY2tfc3RhcnRcdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX25vdGlmeV9jdWVwb2ludF9tYW5hZ2VyX29uX2NvbXBsZXRpb25cdTAwM2R0cnVlXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1fY29vbGRvd25fbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1faW50ZXJ2YWxfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3ByZXdhcm1fbWF4X2xhY3RfbXNcdTAwM2QwXHUwMDI2aHRtbDVfb25lc2llX3JlZGlyZWN0b3JfdGltZW91dFx1MDAzZHRydWVcdTAwMjZodG1sNV9vbmVzaWVfcmVkaXJlY3Rvcl90aW1lb3V0X21zXHUwMDNkMFx1MDAyNmh0bWw1X29uZXNpZV9yZXF1ZXN0X3RpbWVvdXRfbXNcdTAwM2QxMDAwXHUwMDI2aHRtbDVfb25lc2llX3N0aWNreV9zZXJ2ZXJfc2lkZVx1MDAzZHRydWVcdTAwMjZodG1sNV9wYXVzZV9vbl9ub25mb3JlZ3JvdW5kX3BsYXRmb3JtX2Vycm9yc1x1MDAzZHRydWVcdTAwMjZodG1sNV9wZWFrX3NoYXZlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BlcmZfY2FwX292ZXJyaWRlX3N0aWNreVx1MDAzZHRydWVcdTAwMjZodG1sNV9wZXJmb3JtYW5jZV9jYXBfZmxvb3JcdTAwM2QzNjBcdTAwMjZodG1sNV9wZXJmb3JtYW5jZV9pbXBhY3RfcHJvZmlsaW5nX3RpbWVyX21zXHUwMDNkMFx1MDAyNmh0bWw1X3BlcnNlcnZlX2F2MV9wZXJmX2NhcFx1MDAzZHRydWVcdTAwMjZodG1sNV9wbGF0Zm9ybV9iYWNrcHJlc3N1cmVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxhdGZvcm1fbWluaW11bV9yZWFkYWhlYWRfc2Vjb25kc1x1MDAzZDAuMFx1MDAyNmh0bWw1X3BsYXllcl9hdXRvbmF2X2xvZ2dpbmdcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcGxheWVyX2R5bmFtaWNfYm90dG9tX2dyYWRpZW50XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3BsYXllcl9taW5fYnVpbGRfY2xcdTAwM2QtMVx1MDAyNmh0bWw1X3BsYXllcl9wcmVsb2FkX2FkX2ZpeFx1MDAzZHRydWVcdTAwMjZodG1sNV9wb3N0X2ludGVycnVwdF9yZWFkYWhlYWRcdTAwM2QyMFx1MDAyNmh0bWw1X3ByZWZlcl9zZXJ2ZXJfYndlM1x1MDAzZHRydWVcdTAwMjZodG1sNV9wcmVsb2FkX3dhaXRfdGltZV9zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfcHJvYmVfcHJpbWFyeV9kZWxheV9iYXNlX21zXHUwMDNkMFx1MDAyNmh0bWw1X3Byb2Nlc3NfYWxsX2VuY3J5cHRlZF9ldmVudHNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcW9lX2xoX21heF9yZXBvcnRfY291bnRcdTAwM2QwXHUwMDI2aHRtbDVfcW9lX2xoX21pbl9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZodG1sNV9xdWVyeV9zd19zZWN1cmVfY3J5cHRvX2Zvcl9hbmRyb2lkXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JhbmRvbV9wbGF5YmFja19jYXBcdTAwM2QwXHUwMDI2aHRtbDVfcmVjb2duaXplX3ByZWRpY3Rfc3RhcnRfY3VlX3BvaW50XHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbW92ZV9jb21tYW5kX3RyaWdnZXJlZF9jb21wYW5pb25zXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3JlbW92ZV9ub3Rfc2VydmFibGVfY2hlY2tfa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZW5hbWVfYXBic1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZXBvcnRfZmF0YWxfZHJtX3Jlc3RyaWN0ZWRfZXJyb3Jfa2lsbHN3aXRjaFx1MDAzZHRydWVcdTAwMjZodG1sNV9yZXBvcnRfc2xvd19hZHNfYXNfZXJyb3JcdTAwM2R0cnVlXHUwMDI2aHRtbDVfcmVxdWVzdF9vbmx5X2hkcl9vcl9zZHJfa2V5c1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZXF1ZXN0X3NpemluZ19tdWx0aXBsaWVyXHUwMDNkMC44XHUwMDI2aHRtbDVfcmVzZXRfbWVkaWFfc3RyZWFtX29uX3VucmVzdW1hYmxlX3NsaWNlc1x1MDAzZHRydWVcdTAwMjZodG1sNV9yZXNvdXJjZV9iYWRfc3RhdHVzX2RlbGF5X3NjYWxpbmdcdTAwM2QxLjVcdTAwMjZodG1sNV9yZXN0cmljdF9zdHJlYW1pbmdfeGhyX29uX3NxbGVzc19yZXF1ZXN0c1x1MDAzZHRydWVcdTAwMjZodG1sNV9zYWZhcmlfZGVza3RvcF9lbWVfbWluX3ZlcnNpb25cdTAwM2QwXHUwMDI2aHRtbDVfc2Ftc3VuZ19rYW50X2xpbWl0X21heF9iaXRyYXRlXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfamlnZ2xlX2NtdF9kZWxheV9tc1x1MDAzZDgwMDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX2RlbGF5X21zXHUwMDNkMTIwMDBcdTAwMjZodG1sNV9zZWVrX25ld19lbGVtX3Nob3J0c19idWZmZXJfcmFuZ2VfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19uZXdfZWxlbV9zaG9ydHNfdnJzX2RlbGF5X21zXHUwMDNkMFx1MDAyNmh0bWw1X3NlZWtfbmV3X21lZGlhX3NvdXJjZV9zaG9ydHNfcmV1c2VfY2ZsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3NlZWtfbmV3X21lZGlhX3NvdXJjZV9zaG9ydHNfcmV1c2VfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2Vla19zZXRfY210X2RlbGF5X21zXHUwMDNkMjAwMFx1MDAyNmh0bWw1X3NlZWtfdGltZW91dF9kZWxheV9tc1x1MDAzZDIwMDAwXHUwMDI2aHRtbDVfc2VydmVyX3N0aXRjaGVkX2RhaV9kZWNvcmF0ZWRfdXJsX3JldHJ5X2xpbWl0XHUwMDNkNVx1MDAyNmh0bWw1X3NlcnZlcl9zdGl0Y2hlZF9kYWlfZ3JvdXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc2Vzc2lvbl9wb190b2tlbl9pbnRlcnZhbF90aW1lX21zXHUwMDNkOTAwMDAwXHUwMDI2aHRtbDVfc2tpcF9vb2Jfc3RhcnRfc2Vjb25kc1x1MDAzZHRydWVcdTAwMjZodG1sNV9za2lwX3Nsb3dfYWRfZGVsYXlfbXNcdTAwM2QxNTAwMFx1MDAyNmh0bWw1X3NraXBfc3ViX3F1YW50dW1fZGlzY29udGludWl0eV9zZWNzXHUwMDNkMC4wXHUwMDI2aHRtbDVfc2xvd19zdGFydF9ub19tZWRpYV9zb3VyY2VfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfc2xvd19zdGFydF90aW1lb3V0X2RlbGF5X21zXHUwMDNkMjAwMDBcdTAwMjZodG1sNV9zc2RhaV9hZGZldGNoX2R5bmFtaWNfdGltZW91dF9tc1x1MDAzZDUwMDBcdTAwMjZodG1sNV9zc2RhaV9lbmFibGVfbmV3X3NlZWtfbG9naWNcdTAwM2R0cnVlXHUwMDI2aHRtbDVfc3RhdGVmdWxfYXVkaW9fbWluX2FkanVzdG1lbnRfdmFsdWVcdTAwM2QwXHUwMDI2aHRtbDVfc3RhdGljX2Ficl9yZXNvbHV0aW9uX3NoZWxmXHUwMDNkMFx1MDAyNmh0bWw1X3N0b3JlX3hocl9oZWFkZXJzX3JlYWRhYmxlXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3N0cmVhbWluZ194aHJfZXhwYW5kX3JlcXVlc3Rfc2l6ZVx1MDAzZHRydWVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9sb2FkX3NwZWVkX2NoZWNrX2ludGVydmFsXHUwMDNkMC41XHUwMDI2aHRtbDVfc3Vic2VnbWVudF9yZWFkYWhlYWRfbWluX2J1ZmZlcl9oZWFsdGhfc2Vjc1x1MDAzZDAuMjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fYnVmZmVyX2hlYWx0aF9zZWNzX29uX3RpbWVvdXRcdTAwM2QwLjFcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF9taW5fbG9hZF9zcGVlZFx1MDAzZDEuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3NlZWtfbGF0ZW5jeV9mdWRnZVx1MDAzZDAuNVx1MDAyNmh0bWw1X3N1YnNlZ21lbnRfcmVhZGFoZWFkX3RhcmdldF9idWZmZXJfaGVhbHRoX3NlY3NcdTAwM2QwLjVcdTAwMjZodG1sNV9zdWJzZWdtZW50X3JlYWRhaGVhZF90aW1lb3V0X3NlY3NcdTAwM2QyLjBcdTAwMjZodG1sNV91Z2NfbGl2ZV9hdWRpb181MVx1MDAzZHRydWVcdTAwMjZodG1sNV91Z2Nfdm9kX2F1ZGlvXzUxXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3VucmVwb3J0ZWRfc2Vla19yZXNlZWtfZGVsYXlfbXNcdTAwM2QwXHUwMDI2aHRtbDVfdW5yZXN0cmljdGVkX2xheWVyX2hpZ2hfcmVzX2xvZ2dpbmdfcGVyY2VudFx1MDAzZDAuMFx1MDAyNmh0bWw1X3VybF9wYWRkaW5nX2xlbmd0aFx1MDAzZDBcdTAwMjZodG1sNV91cmxfc2lnbmF0dXJlX2V4cGlyeV90aW1lX2hvdXJzXHUwMDNkMFx1MDAyNmh0bWw1X3VzZV9wb3N0X2Zvcl9tZWRpYVx1MDAzZHRydWVcdTAwMjZodG1sNV91c2VfdW1wXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3ZpZGVvX3RiZF9taW5fa2JcdTAwM2QwXHUwMDI2aHRtbDVfdmlld3BvcnRfdW5kZXJzZW5kX21heGltdW1cdTAwM2QwLjBcdTAwMjZodG1sNV92b2x1bWVfc2xpZGVyX3Rvb2x0aXBcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd2ViX2VuYWJsZV9oYWxmdGltZV9wcmVyb2xsXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dlYnBvX2lkbGVfcHJpb3JpdHlfam9iXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3dvZmZsZV9yZXN1bWVcdTAwM2R0cnVlXHUwMDI2aHRtbDVfd29ya2Fyb3VuZF9kZWxheV90cmlnZ2VyXHUwMDNkdHJ1ZVx1MDAyNmh0bWw1X3l0dmxyX2VuYWJsZV9zaW5nbGVfc2VsZWN0X3N1cnZleVx1MDAzZHRydWVcdTAwMjZpZ25vcmVfb3ZlcmxhcHBpbmdfY3VlX3BvaW50c19vbl9lbmRlbWljX2xpdmVfaHRtbDVcdTAwM2R0cnVlXHUwMDI2aWxfdXNlX3ZpZXdfbW9kZWxfbG9nZ2luZ19jb250ZXh0XHUwMDNkdHJ1ZVx1MDAyNmluaXRpYWxfZ2VsX2JhdGNoX3RpbWVvdXRcdTAwM2QyMDAwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2Vycm9yX2NvZGVcdTAwM2QwXHUwMDI2aW5qZWN0ZWRfbGljZW5zZV9oYW5kbGVyX2xpY2Vuc2Vfc3RhdHVzXHUwMDNkMFx1MDAyNml0ZHJtX2luamVjdGVkX2xpY2Vuc2Vfc2VydmljZV9lcnJvcl9jb2RlXHUwMDNkMFx1MDAyNml0ZHJtX3dpZGV2aW5lX2hhcmRlbmVkX3ZtcF9tb2RlXHUwMDNkbG9nXHUwMDI2anNvbl9jb25kZW5zZWRfcmVzcG9uc2VcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2NvbW1hbmRfaGFuZGxlcl9jb21tYW5kX2Jhbmxpc3RcdTAwM2RbXVx1MDAyNmtldmxhcl9kcm9wZG93bl9maXhcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX2dlbF9lcnJvcl9yb3V0aW5nXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9taW5pcGxheWVyX2V4cGFuZF90b3BcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX21pbmlwbGF5ZXJfcGxheV9wYXVzZV9vbl9zY3JpbVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcGxheWJhY2tfYXNzb2NpYXRlZF9xdWV1ZVx1MDAzZHRydWVcdTAwMjZrZXZsYXJfcXVldWVfdXNlX3VwZGF0ZV9hcGlcdTAwM2R0cnVlXHUwMDI2a2V2bGFyX3NpbXBfc2hvcnRzX3Jlc2V0X3Njcm9sbFx1MDAzZHRydWVcdTAwMjZrZXZsYXJfc21hcnRfZG93bmxvYWRzXHUwMDNkdHJ1ZVx1MDAyNmtldmxhcl9zbWFydF9kb3dubG9hZHNfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZrZXZsYXJfdmltaW9fdXNlX3NoYXJlZF9tb25pdG9yXHUwMDNkdHJ1ZVx1MDAyNmxpdmVfY2h1bmtfcmVhZGFoZWFkXHUwMDNkM1x1MDAyNmxpdmVfZnJlc2NhX3YyXHUwMDNkdHJ1ZVx1MDAyNmxvZ19lcnJvcnNfdGhyb3VnaF9ud2xfb25fcmV0cnlcdTAwM2R0cnVlXHUwMDI2bG9nX2dlbF9jb21wcmVzc2lvbl9sYXRlbmN5XHUwMDNkdHJ1ZVx1MDAyNmxvZ19oZWFydGJlYXRfd2l0aF9saWZlY3ljbGVzXHUwMDNkdHJ1ZVx1MDAyNmxvZ193ZWJfZW5kcG9pbnRfdG9fbGF5ZXJcdTAwM2R0cnVlXHUwMDI2bG9nX3dpbmRvd19vbmVycm9yX2ZyYWN0aW9uXHUwMDNkMC4xXHUwMDI2bWFuaWZlc3RsZXNzX3Bvc3RfbGl2ZVx1MDAzZHRydWVcdTAwMjZtYW5pZmVzdGxlc3NfcG9zdF9saXZlX3VmcGhcdTAwM2R0cnVlXHUwMDI2bWF4X2JvZHlfc2l6ZV90b19jb21wcmVzc1x1MDAzZDUwMDAwMFx1MDAyNm1heF9wcmVmZXRjaF93aW5kb3dfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDBcdTAwMjZtYXhfcmVzb2x1dGlvbl9mb3Jfd2hpdGVfbm9pc2VcdTAwM2QzNjBcdTAwMjZtZHhfZW5hYmxlX3ByaXZhY3lfZGlzY2xvc3VyZV91aVx1MDAzZHRydWVcdTAwMjZtZHhfbG9hZF9jYXN0X2FwaV9ib290c3RyYXBfc2NyaXB0XHUwMDNkdHJ1ZVx1MDAyNm1pZ3JhdGVfZXZlbnRzX3RvX3RzXHUwMDNkdHJ1ZVx1MDAyNm1pbl9wcmVmZXRjaF9vZmZzZXRfc2VjX2Zvcl9saXZlc3RyZWFtX29wdGltaXphdGlvblx1MDAzZDEwXHUwMDI2bXVzaWNfZW5hYmxlX3NoYXJlZF9hdWRpb190aWVyX2xvZ2ljXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfYzNfZW5kc2NyZWVuXHUwMDNkdHJ1ZVx1MDAyNm13ZWJfZW5hYmxlX2N1c3RvbV9jb250cm9sX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZtd2ViX2VuYWJsZV9za2lwcGFibGVzX29uX2ppb19waG9uZVx1MDAzZHRydWVcdTAwMjZtd2ViX211dGVkX2F1dG9wbGF5X2FuaW1hdGlvblx1MDAzZHNocmlua1x1MDAyNm13ZWJfbmF0aXZlX2NvbnRyb2xfaW5fZmF1eF9mdWxsc2NyZWVuX3NoYXJlZFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrX3BvbGxpbmdfaW50ZXJ2YWxcdTAwM2QzMDAwMFx1MDAyNm5ldHdvcmtsZXNzX2dlbFx1MDAzZHRydWVcdTAwMjZuZXR3b3JrbGVzc19sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNm5ld19jb2RlY3Nfc3RyaW5nX2FwaV91c2VzX2xlZ2FjeV9zdHlsZVx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mYXN0X29uX3VubG9hZFx1MDAzZHRydWVcdTAwMjZud2xfc2VuZF9mcm9tX21lbW9yeV93aGVuX29ubGluZVx1MDAzZHRydWVcdTAwMjZvZmZsaW5lX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNnBhY2ZfbG9nZ2luZ19kZWxheV9taWxsaXNlY29uZHNfdGhyb3VnaF95YmZlX3R2XHUwMDNkMzAwMDBcdTAwMjZwYWdlaWRfYXNfaGVhZGVyX3dlYlx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfYWRzX3NldF9hZGZvcm1hdF9vbl9jbGllbnRcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2FsbG93X2F1dG9uYXZfYWZ0ZXJfcGxheWxpc3RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2Jvb3RzdHJhcF9tZXRob2RcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2RlZmVyX2NhcHRpb25fZGlzcGxheVx1MDAzZDEwMDBcdTAwMjZwbGF5ZXJfZGVzdHJveV9vbGRfdmVyc2lvblx1MDAzZHRydWVcdTAwMjZwbGF5ZXJfZG91YmxldGFwX3RvX3NlZWtcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuYWJsZV9wbGF5YmFja19wbGF5bGlzdF9jaGFuZ2VcdTAwM2R0cnVlXHUwMDI2cGxheWVyX2VuZHNjcmVlbl9lbGxpcHNpc19maXhcdTAwM2R0cnVlXHUwMDI2cGxheWVyX3VuZGVybGF5X21pbl9wbGF5ZXJfd2lkdGhcdTAwM2Q3NjguMFx1MDAyNnBsYXllcl91bmRlcmxheV92aWRlb193aWR0aF9mcmFjdGlvblx1MDAzZDAuNlx1MDAyNnBsYXllcl93ZWJfY2FuYXJ5X3N0YWdlXHUwMDNkMFx1MDAyNnBsYXlyZWFkeV9maXJzdF9wbGF5X2V4cGlyYXRpb25cdTAwM2QtMVx1MDAyNnBvbHltZXJfYmFkX2J1aWxkX2xhYmVsc1x1MDAzZHRydWVcdTAwMjZwb2x5bWVyX2xvZ19wcm9wX2NoYW5nZV9vYnNlcnZlcl9wZXJjZW50XHUwMDNkMFx1MDAyNnBvbHltZXJfdmVyaWZpeV9hcHBfc3RhdGVcdTAwM2R0cnVlXHUwMDI2cHJlc2tpcF9idXR0b25fc3R5bGVfYWRzX2JhY2tlbmRcdTAwM2Rjb3VudGRvd25fbmV4dF90b190aHVtYm5haWxcdTAwMjZxb2VfbndsX2Rvd25sb2Fkc1x1MDAzZHRydWVcdTAwMjZxb2Vfc2VuZF9hbmRfd3JpdGVcdTAwM2R0cnVlXHUwMDI2cmVjb3JkX2FwcF9jcmFzaGVkX3dlYlx1MDAzZHRydWVcdTAwMjZyZXBsYWNlX3BsYXlhYmlsaXR5X3JldHJpZXZlcl9pbl93YXRjaFx1MDAzZHRydWVcdTAwMjZzY2hlZHVsZXJfdXNlX3JhZl9ieV9kZWZhdWx0XHUwMDNkdHJ1ZVx1MDAyNnNlbGZfcG9kZGluZ19oZWFkZXJfc3RyaW5nX3RlbXBsYXRlXHUwMDNkc2VsZl9wb2RkaW5nX2ludGVyc3RpdGlhbF9tZXNzYWdlXHUwMDI2c2VsZl9wb2RkaW5nX2hpZ2hsaWdodF9ub25fZGVmYXVsdF9idXR0b25cdTAwM2R0cnVlXHUwMDI2c2VsZl9wb2RkaW5nX21pZHJvbGxfY2hvaWNlX3N0cmluZ190ZW1wbGF0ZVx1MDAzZHNlbGZfcG9kZGluZ19taWRyb2xsX2Nob2ljZVx1MDAyNnNlbmRfY29uZmlnX2hhc2hfdGltZXJcdTAwM2QwXHUwMDI2c2V0X2ludGVyc3RpdGlhbF9hZHZlcnRpc2Vyc19xdWVzdGlvbl90ZXh0XHUwMDNkdHJ1ZVx1MDAyNnNob3J0X3N0YXJ0X3RpbWVfcHJlZmVyX3B1Ymxpc2hfaW5fd2F0Y2hfbG9nXHUwMDNkdHJ1ZVx1MDAyNnNob3J0c19tb2RlX3RvX3BsYXllcl9hcGlcdTAwM2R0cnVlXHUwMDI2c2hvcnRzX25vX3N0b3BfdmlkZW9fY2FsbFx1MDAzZHRydWVcdTAwMjZzaG91bGRfY2xlYXJfdmlkZW9fZGF0YV9vbl9wbGF5ZXJfY3VlZF91bnN0YXJ0ZWRcdTAwM2R0cnVlXHUwMDI2c2ltcGx5X2VtYmVkZGVkX2VuYWJsZV9ib3RndWFyZFx1MDAzZHRydWVcdTAwMjZza2lwX2lubGluZV9tdXRlZF9saWNlbnNlX3NlcnZpY2VfY2hlY2tcdTAwM2R0cnVlXHUwMDI2c2tpcF9pbnZhbGlkX3l0Y3NpX3RpY2tzXHUwMDNkdHJ1ZVx1MDAyNnNraXBfbHNfZ2VsX3JldHJ5XHUwMDNkdHJ1ZVx1MDAyNnNraXBfc2V0dGluZ19pbmZvX2luX2NzaV9kYXRhX29iamVjdFx1MDAzZHRydWVcdTAwMjZzbG93X2NvbXByZXNzaW9uc19iZWZvcmVfYWJhbmRvbl9jb3VudFx1MDAzZDRcdTAwMjZzcGVlZG1hc3Rlcl9jYW5jZWxsYXRpb25fbW92ZW1lbnRfZHBcdTAwM2QwXHUwMDI2c3BlZWRtYXN0ZXJfcGxheWJhY2tfcmF0ZVx1MDAzZDAuMFx1MDAyNnNwZWVkbWFzdGVyX3RvdWNoX2FjdGl2YXRpb25fbXNcdTAwM2QwXHUwMDI2c3RhcnRfY2xpZW50X2djZlx1MDAzZHRydWVcdTAwMjZzdGFydF9jbGllbnRfZ2NmX2Zvcl9wbGF5ZXJcdTAwM2R0cnVlXHUwMDI2c3RhcnRfc2VuZGluZ19jb25maWdfaGFzaFx1MDAzZHRydWVcdTAwMjZzdHJlYW1pbmdfZGF0YV9lbWVyZ2VuY3lfaXRhZ19ibGFja2xpc3RcdTAwM2RbXVx1MDAyNnN1cHByZXNzX2Vycm9yXzIwNF9sb2dnaW5nXHUwMDNkdHJ1ZVx1MDAyNnRyYW5zcG9ydF91c2Vfc2NoZWR1bGVyXHUwMDNkdHJ1ZVx1MDAyNnR2X3BhY2ZfbG9nZ2luZ19zYW1wbGVfcmF0ZVx1MDAzZDAuMDFcdTAwMjZ0dmh0bWw1X3VucGx1Z2dlZF9wcmVsb2FkX2NhY2hlX3NpemVcdTAwM2Q1XHUwMDI2dW5jb3Zlcl9hZF9iYWRnZV9vbl9SVExfdGlueV93aW5kb3dcdTAwM2R0cnVlXHUwMDI2dW5wbHVnZ2VkX2RhaV9saXZlX2NodW5rX3JlYWRhaGVhZFx1MDAzZDNcdTAwMjZ1bnBsdWdnZWRfdHZodG1sNV92aWRlb19wcmVsb2FkX29uX2ZvY3VzX2RlbGF5X21zXHUwMDNkMFx1MDAyNnVwZGF0ZV9sb2dfZXZlbnRfY29uZmlnXHUwMDNkdHJ1ZVx1MDAyNnVzZV9hY2Nlc3NpYmlsaXR5X2RhdGFfb25fZGVza3RvcF9wbGF5ZXJfYnV0dG9uXHUwMDNkdHJ1ZVx1MDAyNnVzZV9jb3JlX3NtXHUwMDNkdHJ1ZVx1MDAyNnVzZV9pbmxpbmVkX3BsYXllcl9ycGNcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19jbWxcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19pbl9tZW1vcnlfc3RvcmFnZVx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9pbml0aWFsaXphdGlvblx1MDAzZHRydWVcdTAwMjZ1c2VfbmV3X253bF9zYXdcdTAwM2R0cnVlXHUwMDI2dXNlX25ld19ud2xfc3R3XHUwMDNkdHJ1ZVx1MDAyNnVzZV9uZXdfbndsX3d0c1x1MDAzZHRydWVcdTAwMjZ1c2VfcGxheWVyX2FidXNlX2JnX2xpYnJhcnlcdTAwM2R0cnVlXHUwMDI2dXNlX3Byb2ZpbGVwYWdlX2V2ZW50X2xhYmVsX2luX2Nhcm91c2VsX3BsYXliYWNrc1x1MDAzZHRydWVcdTAwMjZ1c2VfcmVxdWVzdF90aW1lX21zX2hlYWRlclx1MDAzZHRydWVcdTAwMjZ1c2Vfc2Vzc2lvbl9iYXNlZF9zYW1wbGluZ1x1MDAzZHRydWVcdTAwMjZ1c2VfdHNfdmlzaWJpbGl0eWxvZ2dlclx1MDAzZHRydWVcdTAwMjZ2YXJpYWJsZV9idWZmZXJfdGltZW91dF9tc1x1MDAzZDBcdTAwMjZ2ZXJpZnlfYWRzX2l0YWdfZWFybHlcdTAwM2R0cnVlXHUwMDI2dnA5X2RybV9saXZlXHUwMDNkdHJ1ZVx1MDAyNnZzc19maW5hbF9waW5nX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNnZzc19waW5nc191c2luZ19uZXR3b3JrbGVzc1x1MDAzZHRydWVcdTAwMjZ2c3NfcGxheWJhY2tfdXNlX3NlbmRfYW5kX3dyaXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9hcGlfdXJsXHUwMDNkdHJ1ZVx1MDAyNndlYl9hc3luY19jb250ZXh0X3Byb2Nlc3Nvcl9pbXBsXHUwMDNkc3RhbmRhbG9uZVx1MDAyNndlYl9jaW5lbWF0aWNfd2F0Y2hfc2V0dGluZ3NcdTAwM2R0cnVlXHUwMDI2d2ViX2NsaWVudF92ZXJzaW9uX292ZXJyaWRlXHUwMDNkXHUwMDI2d2ViX2RlZHVwZV92ZV9ncmFmdGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfZGVwcmVjYXRlX3NlcnZpY2VfYWpheF9tYXBfZGVwZW5kZW5jeVx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2Vycm9yXzIwNFx1MDAzZHRydWVcdTAwMjZ3ZWJfZW5hYmxlX2luc3RyZWFtX2Fkc19saW5rX2RlZmluaXRpb25fYTExeV9idWdmaXhcdTAwM2R0cnVlXHUwMDI2d2ViX2VuYWJsZV92b3pfYXVkaW9fZmVlZGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX2ZpeF9maW5lX3NjcnViYmluZ19kcmFnXHUwMDNkdHJ1ZVx1MDAyNndlYl9mb3JlZ3JvdW5kX2hlYXJ0YmVhdF9pbnRlcnZhbF9tc1x1MDAzZDI4MDAwXHUwMDI2d2ViX2ZvcndhcmRfY29tbWFuZF9vbl9wYmpcdTAwM2R0cnVlXHUwMDI2d2ViX2dlbF9kZWJvdW5jZV9tc1x1MDAzZDYwMDAwXHUwMDI2d2ViX2dlbF90aW1lb3V0X2NhcFx1MDAzZHRydWVcdTAwMjZ3ZWJfaW5saW5lX3BsYXllcl9ub19wbGF5YmFja191aV9jbGlja19oYW5kbGVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9rZXlfbW9tZW50c19tYXJrZXJzXHUwMDNkdHJ1ZVx1MDAyNndlYl9sb2dfbWVtb3J5X3RvdGFsX2tieXRlc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbG9nZ2luZ19tYXhfYmF0Y2hcdTAwM2QxNTBcdTAwMjZ3ZWJfbW9kZXJuX2Fkc1x1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX2J1dHRvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX21vZGVybl9idXR0b25zX2JsX3N1cnZleVx1MDAzZHRydWVcdTAwMjZ3ZWJfbW9kZXJuX3NjcnViYmVyXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlXHUwMDNkdHJ1ZVx1MDAyNndlYl9tb2Rlcm5fc3Vic2NyaWJlX3N0eWxlXHUwMDNkZmlsbGVkXHUwMDI2d2ViX25ld19hdXRvbmF2X2NvdW50ZG93blx1MDAzZHRydWVcdTAwMjZ3ZWJfb25lX3BsYXRmb3JtX2Vycm9yX2hhbmRsaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9vcF9zaWduYWxfdHlwZV9iYW5saXN0XHUwMDNkW11cdTAwMjZ3ZWJfcGF1c2VkX29ubHlfbWluaXBsYXllcl9zaG9ydGN1dF9leHBhbmRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXliYWNrX2Fzc29jaWF0ZWRfbG9nX2N0dFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWJhY2tfYXNzb2NpYXRlZF92ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2FkZF92ZV9jb252ZXJzaW9uX2xvZ2dpbmdfdG9fb3V0Ym91bmRfbGlua3NcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hbHdheXNfZW5hYmxlX2F1dG9fdHJhbnNsYXRpb25cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9hcGlfbG9nZ2luZ19mcmFjdGlvblx1MDAzZDAuMDFcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfZW1wdHlfc3VnZ2VzdGlvbnNfZml4XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfYXV0b25hdl90b2dnbGVfYWx3YXlzX2xpc3Rlblx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2F1dG9uYXZfdXNlX3NlcnZlcl9wcm92aWRlZF9zdGF0ZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2NhcHRpb25fbGFuZ3VhZ2VfcHJlZmVyZW5jZV9zdGlja2luZXNzX2R1cmF0aW9uXHUwMDNkMzBcdTAwMjZ3ZWJfcGxheWVyX2RlY291cGxlX2F1dG9uYXZcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9kaXNhYmxlX2lubGluZV9zY3J1YmJpbmdcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9lbmFibGVfZWFybHlfd2FybmluZ19zbmFja2Jhclx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9mZWF0dXJlZF9wcm9kdWN0X2Jhbm5lcl9vbl9kZXNrdG9wXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfZW5hYmxlX3ByZW1pdW1faGJyX2luX2g1X2FwaVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX2VuYWJsZV9wcmVtaXVtX2hicl9wbGF5YmFja19jYXBcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9pbm5lcnR1YmVfcGxheWxpc3RfdXBkYXRlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfaXBwX2NhbmFyeV90eXBlX2Zvcl9sb2dnaW5nXHUwMDNkXHUwMDI2d2ViX3BsYXllcl9saXZlX21vbml0b3JfZW52XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbG9nX2NsaWNrX2JlZm9yZV9nZW5lcmF0aW5nX3ZlX2NvbnZlcnNpb25fcGFyYW1zXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfbW92ZV9hdXRvbmF2X3RvZ2dsZVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX211c2ljX3Zpc3VhbGl6ZXJfdHJlYXRtZW50XHUwMDNkZmFrZVx1MDAyNndlYl9wbGF5ZXJfbXV0YWJsZV9ldmVudF9sYWJlbFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX25pdHJhdGVfcHJvbW9fdG9vbHRpcFx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX29mZmxpbmVfcGxheWxpc3RfYXV0b19yZWZyZXNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfcmVzcG9uc2VfcGxheWJhY2tfdHJhY2tpbmdfcGFyc2luZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NlZWtfY2hhcHRlcnNfYnlfc2hvcnRjdXRcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zZW50aW5lbF9pc191bmlwbGF5ZXJcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl9zaG91bGRfaG9ub3JfaW5jbHVkZV9hc3Jfc2V0dGluZ1x1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3Nob3dfbXVzaWNfaW5fdGhpc192aWRlb19ncmFwaGljXHUwMDNkdmlkZW9fdGh1bWJuYWlsXHUwMDI2d2ViX3BsYXllcl9zbWFsbF9oYnBfc2V0dGluZ3NfbWVudVx1MDAzZHRydWVcdTAwMjZ3ZWJfcGxheWVyX3NzX2RhaV9hZF9mZXRjaGluZ190aW1lb3V0X21zXHUwMDNkMTUwMDBcdTAwMjZ3ZWJfcGxheWVyX3NzX21lZGlhX3RpbWVfb2Zmc2V0XHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG9waWZ5X3N1YnRpdGxlc19mb3Jfc2hvcnRzXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdG91Y2hfbW9kZV9pbXByb3ZlbWVudHNcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl90cmFuc2Zlcl90aW1lb3V0X3RocmVzaG9sZF9tc1x1MDAzZDEwODAwMDAwXHUwMDI2d2ViX3BsYXllcl91bnNldF9kZWZhdWx0X2Nzbl9raWxsc3dpdGNoXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfdXNlX25ld19hcGlfZm9yX3F1YWxpdHlfcHVsbGJhY2tcdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl92ZV9jb252ZXJzaW9uX2ZpeGVzX2Zvcl9jaGFubmVsX2luZm9cdTAwM2R0cnVlXHUwMDI2d2ViX3BsYXllcl93YXRjaF9uZXh0X3Jlc3BvbnNlXHUwMDNkdHJ1ZVx1MDAyNndlYl9wbGF5ZXJfd2F0Y2hfbmV4dF9yZXNwb25zZV9wYXJzaW5nXHUwMDNkdHJ1ZVx1MDAyNndlYl9wcmVmZXRjaF9wcmVsb2FkX3ZpZGVvXHUwMDNkdHJ1ZVx1MDAyNndlYl9yb3VuZGVkX3RodW1ibmFpbHNcdTAwM2R0cnVlXHUwMDI2d2ViX3NldHRpbmdzX21lbnVfaWNvbnNcdTAwM2R0cnVlXHUwMDI2d2ViX3Ntb290aG5lc3NfdGVzdF9kdXJhdGlvbl9tc1x1MDAzZDBcdTAwMjZ3ZWJfc21vb3RobmVzc190ZXN0X21ldGhvZFx1MDAzZDBcdTAwMjZ3ZWJfeXRfY29uZmlnX2NvbnRleHRcdTAwM2R0cnVlXHUwMDI2d2lsX2ljb25fcmVuZGVyX3doZW5faWRsZVx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfY2xlYW5fdXBfYWZ0ZXJfZW50aXR5X21pZ3JhdGlvblx1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfZW5hYmxlX2Rvd25sb2FkX3N0YXR1c1x1MDAzZHRydWVcdTAwMjZ3b2ZmbGVfcGxheWxpc3Rfb3B0aW1pemF0aW9uXHUwMDNkdHJ1ZVx1MDAyNnl0aWRiX2NsZWFyX2VtYmVkZGVkX3BsYXllclx1MDAzZHRydWVcdTAwMjZ5dGlkYl9mZXRjaF9kYXRhc3luY19pZHNfZm9yX2RhdGFfY2xlYW51cFx1MDAzZHRydWVcdTAwMjZ5dGlkYl9yZW1ha2VfZGJfcmV0cmllc1x1MDAzZDFcdTAwMjZ5dGlkYl9yZW9wZW5fZGJfcmV0cmllc1x1MDAzZDBcdTAwMjZ5dGlkYl90cmFuc2FjdGlvbl9lbmRlZF9ldmVudF9yYXRlX2xpbWl0XHUwMDNkMC4wMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfc2Vzc2lvblx1MDAzZDAuMlx1MDAyNnl0aWRiX3RyYW5zYWN0aW9uX2VuZGVkX2V2ZW50X3JhdGVfbGltaXRfdHJhbnNhY3Rpb25cdTAwM2QwLjEiLCJjc3BOb25jZSI6ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiLCJjYW5hcnlTdGF0ZSI6Im5vbmUiLCJkYXRhc3luY0lkIjoiVmVhMzA3OWZifHwifX0sIlhTUkZfRklFTERfTkFNRSI6InNlc3Npb25fdG9rZW4iLCJYU1JGX1RPS0VOIjoiUVVGRkxVaHFiRkZXYW5kSGVrMHROR05xVld4UU5sVm9kVTVyTVRGRE1FZHZVWHhCUTNKdGMwdHRTbU5JUTJ4eFZWcHNkblZpVW10UGVsUmFhV00wTWtOQk5VeDJTMk5MUW0xVGNWVnNOemR6WkZoaVYyZDNhMGR6TTJZMlZGWkxPVGhGVjFKWWFVWkRNMEpMWTIxU1lYcEZUM1JOZGxkS2JucFdRbkJYWkZZd01IbGZlRmhwYnpoa2NFWkdXREI0ZFdob1VVMUJTbFZSTkFcdTAwM2RcdTAwM2QiLCJZUENfTUJfVVJMIjoiaHR0cHM6Ly9wYXltZW50cy55b3V0dWJlLmNvbS9wYXltZW50cy92NC9qcy9pbnRlZ3JhdG9yLmpzP3NzXHUwMDNkbWQiLCJZVFJfRkFNSUxZX0NSRUFUSU9OX1VSTCI6Imh0dHBzOi8vZmFtaWxpZXMuZ29vZ2xlLmNvbS93ZWJjcmVhdGlvbj91c2VnYXBpXHUwMDNkMSIsIlNFUlZFUl9WRVJTSU9OIjoicHJvZCIsIlJFVVNFX0NPTVBPTkVOVFMiOnRydWUsIlNUQU1QRVJfU1RBQkxFX0xJU1QiOnRydWUsIkRBVEFTWU5DX0lEIjoiVmVhMzA3OWZifHwiLCJTRVJJQUxJWkVEX0NMSUVOVF9DT05GSUdfREFUQSI6IkNKYS1pS1FHRU15M19oSVF5N3l2QlJELXRhOEZFTlNocndVUTg2aXZCUkQ0dGE4RkVNemZyZ1VRckxldkJSQ2xtYThGRU82aXJ3VVFqNk92QlJDMjRLNEZFTHEwcndVUW91eXVCUkREdF80U0VLcXlfaElRNUxQLUVoQzl0cTRGRU9DbnJ3VVE1X2V1QlJEYnI2OEZFS2lfcndVUWdwMnZCUkRNcnY0U0VPTFVyZ1VRX3U2dUJSQzRpNjRGRUtPMHJ3VVFpZWl1QlJEVnRxOEZFS1hDX2hJUW1OSC1FZyUzRCUzRCIsIkxJVkVfQ0hBVF9CQVNFX1RBTkdPX0NPTkZJRyI6eyJhcGlLZXkiOiJBSXphU3lEWk5reUMtQXRST3dNQnBMZmV2SXZxWWstR2ZpOFpPZW8iLCJjaGFubmVsVXJpIjoiaHR0cHM6Ly9jbGllbnQtY2hhbm5lbC5nb29nbGUuY29tL2NsaWVudC1jaGFubmVsL2NsaWVudCIsImNsaWVudE5hbWUiOiJ5dC1saXZlLWNvbW1lbnRzIiwicmVxdWlyZXNBdXRoVG9rZW4iOnRydWUsInNlbmRlclVyaSI6Imh0dHBzOi8vY2xpZW50czQuZ29vZ2xlLmNvbS9pbnZhbGlkYXRpb24vbGNzL2NsaWVudCIsInVzZU5ld1RhbmdvIjp0cnVlfSwiRkVYUF9FWFBFUklNRU5UUyI6WzIzODU4MDU3LDIzOTgzMjk2LDIzOTg2MDMzLDI0MDA0NjQ0LDI0MDA3MjQ2LDI0MDgwNzM4LDI0MTM1MzEwLDI0MzYyNjg1LDI0MzYyNjg4LDI0MzYzMTE0LDI0MzY0Nzg5LDI0MzY2OTE3LDI0MzcwODk4LDI0Mzc3MzQ2LDI0NDE1ODY0LDI0NDMzNjc5LDI0NDM3NTc3LDI0NDM5MzYxLDI0NDkyNTQ3LDI0NTMyODU1LDI0NTUwNDU4LDI0NTUwOTUxLDI0NTU4NjQxLDI0NTU5MzI2LDI0Njk5ODk5LDM5MzIzMDc0XSwiTElWRV9DSEFUX1NFTkRfTUVTU0FHRV9BQ1RJT04iOiJsaXZlX2NoYXQvd2F0Y2hfcGFnZS9zZW5kIiwiUk9PVF9WRV9UWVBFIjozNjExLCJDTElFTlRfUFJPVE9DT0wiOiJIVFRQLzEuMSIsIkNMSUVOVF9UUkFOU1BPUlQiOiJ0Y3AiLCJFT01fVklTSVRPUl9EQVRBIjoiQ2d0c1pXNVNWazVsYmtOV1NTaVd2b2lrQmclM0QlM0QiLCJUSU1FX0NSRUFURURfTVMiOjE2ODYyNDkyMzgwMjEsIkJVVFRPTl9SRVdPUksiOnRydWUsIlZBTElEX1NFU1NJT05fVEVNUERBVEFfRE9NQUlOUyI6WyJ5b3V0dWJlLmNvbSIsInd3dy55b3V0dWJlLmNvbSIsIndlYi1ncmVlbi1xYS55b3V0dWJlLmNvbSIsIndlYi1yZWxlYXNlLXFhLnlvdXR1YmUuY29tIiwid2ViLWludGVncmF0aW9uLXFhLnlvdXR1YmUuY29tIiwibS55b3V0dWJlLmNvbSIsIm13ZWItZ3JlZW4tcWEueW91dHViZS5jb20iLCJtd2ViLXJlbGVhc2UtcWEueW91dHViZS5jb20iLCJtd2ViLWludGVncmF0aW9uLXFhLnlvdXR1YmUuY29tIiwic3R1ZGlvLnlvdXR1YmUuY29tIiwic3R1ZGlvLWdyZWVuLXFhLnlvdXR1YmUuY29tIiwic3R1ZGlvLWludGVncmF0aW9uLXFhLnlvdXR1YmUuY29tIl0sIldPUktFUl9QRVJGT1JNQU5DRV9VUkwiOnsicHJpdmF0ZURvTm90QWNjZXNzT3JFbHNlVHJ1c3RlZFJlc291cmNlVXJsV3JhcHBlZFZhbHVlIjoiL3MvZGVza3RvcC8zNzRmYWFkNS9qc2Jpbi93b3JrZXItcGVyZm9ybWFuY2UudmZsc2V0L3dvcmtlci1wZXJmb3JtYW5jZS5qcyJ9LCJSQVdfQ09MRF9DT05GSUdfR1JPVVAiOnsiY29uZmlnRGF0YSI6IkNKYS1pS1FHRU9xZHJRVVE4THF0QlJDTThxMEZFUGVJcmdVUXVJdXVCUkRGbXE0RkVLZWRyZ1VRaWJHdUJSQ0N0YTRGRUlhMXJnVVF2YmF1QlJDZ3VhNEZFT2JOcmdVUTR0U3VCUkRrMXE0RkVNemZyZ1VRNXVDdUJSRG40YTRGRUlub3JnVVF0LW11QlJDaTdLNEZFUDd1cmdVUTVfZXVCUkR2LXE0RkVQUDZyZ1VROWZxdUJSQ0ZqYThGRUlXUnJ3VVF4NU92QlJEZmxLOEZFT2lWcndVUXBabXZCUkNDbmE4RkVPbWVyd1VRd3AtdkJSRFVvYThGRU82aXJ3VVFqNk92QlJEUm82OEZFTS1scndVUXQ2YXZCUkRncDY4RkVPaW9yd1VRODZpdkJSQ1pxNjhGRUxDc3J3VVEyNi12QlJDS3NxOEZFS08wcndVUXVyU3ZCUkRNdEs4RkVQYTByd1VRLUxXdkJSRC10YThGRU5XMnJ3VVFfN2F2QlJDc3Q2OEZFUHE0cndVUXE3bXZCUkNtdXE4RkVPRzZyd1VReTd5dkJSRGp2cThGRUtpX3J3VWFNa0ZKU2s1SWFFZFlVa1l5U1VKb2VtZEVkSEl0YkUxR2NHTkxUbkZsVmkweVRsOWxPUzFSYUhaQ1ZFbDJiM2R3UmtOM0lqSkJTVXBPU0doSFdGSkdNa2xDYUhwblJIUnlMV3hOUm5CalMwNXhaVll0TWs1ZlpUa3RVV2gyUWxSSmRtOTNjRVpEZHlvMFEwRk5VMGxuTUV0bmNHRnZRWFEwUlRaQ1pXWkNTVGhUWkdoVlZ6RjBOMGxFVFZOelFVMDRhWG8zVFVWcFUyVlFkVkZSUFElM0QlM0QiLCJtYWluQXBwQ29sZENvbmZpZyI6eyJpb3NTc29TYWZhcmlGc2lQcm9tb0VuYWJsZWQiOnRydWUsImlvc1RvZGF5V2lkZ2V0RW5hYmxlZCI6ZmFsc2UsImlvc0VuYWJsZUR5bmFtaWNGb250U2l6aW5nIjpmYWxzZSwiZW5hYmxlTW9iaWxlQXV0b09mZmxpbmUiOmZhbHNlLCJhbmRyb2lkRW5hYmxlUGlwIjpmYWxzZSwicG9zdHNWMiI6ZmFsc2UsImVuYWJsZURldGFpbGVkTmV0d29ya1N0YXR1c1JlcG9ydGluZyI6ZmFsc2UsImhvdXJUb1JlcG9ydE5ldHdvcmtTdGF0dXMiOjAsIm5ldHdvcmtTdGF0dXNSZXBvcnRpbmdXaW5kb3dTZWNzIjowLCJpb3NTZWFyY2h2aWV3UmVmYWN0b3J5RW5hYmxlZCI6ZmFsc2UsIm5nd0ZsZXh5RW5hYmxlZCI6ZmFsc2UsImlvc1dhdGNoRXhwYW5kVHJhbnNpdGlvbldpdGhvdXRTbmFwc2hvdCI6ZmFsc2UsImFuZHJvaWROZ3dVaUVuYWJsZWQiOmZhbHNlLCJhbmRyb2lkVGh1bWJuYWlsTW9uaXRvckVuYWJsZWQiOmZhbHNlLCJhbmRyb2lkVGh1bWJuYWlsTW9uaXRvckNvdW50IjowLCJhbmRyb2lkVGh1bWJuYWlsTW9uaXRvck1pbmltdW1XaWR0aCI6MCwiZW5hYmxlR2hvc3RDYXJkcyI6ZmFsc2UsImVuYWJsZUlubGluZU11dGVkIjpmYWxzZSwibmd3RmxleHlNYXhDcm9wUmF0aW8iOjEuMCwiYW5kcm9pZFJlc3RvcmVCcm93c2VDb250ZW50c0Zyb21CYWNrU3RhY2siOmZhbHNlLCJzZWFyY2hIaW50RXhwIjoic2VhcmNoX3lvdXR1YmUifSwiZXhwZXJpbWVudEZsYWdzIjp7IjQ1MzUyMTgwIjp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM3NTU2NSI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDU0MTMwODEiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1Mzc0MzA2Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2NjI2NyI6eyJpbnRGbGFnVmFsdWUiOjF9LCI0NTQwNzMzMCI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNjQ5OTMiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzcyODE0Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2ODc4NyI6eyJpbnRGbGFnVmFsdWUiOjIwMH0sIjQ1Mzg4NzQyIjp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2ODM4NiI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzODczMzIiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzY2MjY4Ijp7ImRvdWJsZUZsYWdWYWx1ZSI6MS4wfSwiNDUzNjg0OTgiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzgxNDc4Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2Nzk4NyI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNzQ4NjAiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1Mzc5ODU1Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM3MDk2MSI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNzU1NjQiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzY2MjY2Ijp7ImludEZsYWdWYWx1ZSI6NjAwMDB9LCI0NTM1MzM5NyI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNTgxNDUiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX19fSwiUkFXX0hPVF9DT05GSUdfR1JPVVAiOnsibWFpbkFwcEhvdENvbmZpZyI6eyJpb3NXYXRjaEV4cGFuZFRyYW5zaXRpb24iOmZhbHNlLCJpb3NFYXJseVNldFdhdGNoVHJhbnNpdGlvbiI6ZmFsc2UsImV4cG9zZUNvbmZpZ1JlZnJlc2hTZXR0aW5nIjpmYWxzZSwiaW9zRW5hYmxlU2VhcmNoQnV0dG9uT25QbGF5ZXJPdmVybGF5IjpmYWxzZSwiaW9zTWluaW11bVRvb2x0aXBEdXJhdGlvbk1zZWNzIjoxMDAwLCJpb3NGcmVzaEhvbWVJbnRlcnZhbFNlY3MiOjAsImlvc0ZyZXNoU3Vic2NyaXB0aW9uc0ludGVydmFsU2VjcyI6MCwiaW9zVG9kYXlXaWRnZXRSZWZyZXNoSW50ZXJ2YWxTZWNzIjoyODgwMCwiaW9zRnJlc2hOb3RpZmljYXRpb25zSW5ib3hJbnRlcnZhbFNlY3MiOjAsInNpZ25lZE91dE5vdGlmaWNhdGlvbnNJb3NQcm9tcHQiOnRydWUsImlvc0ZyZXNoRnVsbFJlZnJlc2giOmZhbHNlfSwibG9nZ2luZ0hvdENvbmZpZyI6eyJldmVudExvZ2dpbmdDb25maWciOnsiZW5hYmxlZCI6dHJ1ZSwibWF4QWdlSG91cnMiOjcyMCwicmVxdWVzdFJldHJ5RW5hYmxlZCI6dHJ1ZSwicmV0cnlDb25maWciOnsiZml4ZWRCYXRjaFJldHJ5RW5hYmxlZCI6ZmFsc2V9LCJzaG91bGRGb3JjZVNldEFsbFBheWxvYWRzVG9JbW1lZGlhdGVUaWVyIjpmYWxzZX19LCJleHBlcmltZW50RmxhZ3MiOnsiNDUzNjIyOTciOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzU1Mzc4Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2MDg2NCI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNzkxNjkiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1Mzc3NzM3Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2NTg0MyI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNjY5NDMiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzY5NTUyIjp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2NzI4OSI6eyJkb3VibGVGbGFnVmFsdWUiOjIuMH0sIjQ1MzUzMzM4Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM3NzA4MSI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNzEyODciOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1Mzc1NDQ1Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM2ODAxMSI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNjg5NDkiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzU2OTc5Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM4MjE0MiI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNjgxMzIiOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1Mzc1MjkyIjp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM1Njk1NCI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfSwiNDUzNjUxMzciOnsiYm9vbGVhbkZsYWdWYWx1ZSI6dHJ1ZX0sIjQ1MzYyMzg2Ijp7ImJvb2xlYW5GbGFnVmFsdWUiOnRydWV9LCI0NTM4OTA0MyI6eyJib29sZWFuRmxhZ1ZhbHVlIjp0cnVlfX19LCJTRVJJQUxJWkVEX0hPVF9IQVNIX0RBVEEiOiJDSmEtaUtRR0VoTTVPVGcwT0RrNU16azBNVGMwT1RBME1UY3lHSmEtaUtRR0tKVGtfQklvbnZfOEVpamJrXzBTS09Hc19SSW95NjM5RWlqR3N2MFNLS3EwX1JJb3pzRDlFaWlaeHYwU0tLWFFfUklvZ1BQOUVpakotZjBTS09pQ19oSW95WVQtRWlqS2hfNFNLTi1JX2hJbzc0bi1FaWp4aWY0U0tQaUxfaElvclpELUVpaWVrZjRTS05XZ19oSW9ncUwtRWlqNHFmNFNLSnF0X2hJb3pLNy1FaWp3c1A0U0tLcXlfaElvNUxQLUVpalp0djRTS09pMl9oSW93N2YtRWlqTXRfNFNLSTI2X2hJb3dMci1FaWp0dV80U0tNdV9faElvdDhILUVpaWx3djRTS01yQ19oSW80TWYtRWlpVnlQNFNLTWJJX2hJb2tNbi1FaWlDeV80U0tNSExfaElvb2RELUVpaW4wUDRTS0pqUl9oSXlNa0ZKU2s1SWFFZFlVa1l5U1VKb2VtZEVkSEl0YkUxR2NHTkxUbkZsVmkweVRsOWxPUzFSYUhaQ1ZFbDJiM2R3UmtOM09qSkJTVXBPU0doSFdGSkdNa2xDYUhwblJIUnlMV3hOUm5CalMwNXhaVll0TWs1ZlpUa3RVV2gyUWxSSmRtOTNjRVpEZDBJd1EwRk5VMGxCTUV4dmRHWTJSbUkwWDNsblEwOU9jVWxMUmxKbVpIbzRTVTF4U25ORGFTMDBRbkoxWjB4M1QyTkUiLCJTRVJJQUxJWkVEX0NPTERfSEFTSF9EQVRBIjoiQ0phLWlLUUdFaFF4TWpZMU5EY3pOVEl5TURVM01qZzNPRFEwTWhpV3ZvaWtCakl5UVVsS1RraG9SMWhTUmpKSlFtaDZaMFIwY2kxc1RVWndZMHRPY1dWV0xUSk9YMlU1TFZGb2RrSlVTWFp2ZDNCR1EzYzZNa0ZKU2s1SWFFZFlVa1l5U1VKb2VtZEVkSEl0YkUxR2NHTkxUbkZsVmkweVRsOWxPUzFSYUhaQ1ZFbDJiM2R3UmtOM1FqUkRRVTFUU1djd1MyZHdZVzlCZERSRk5rSmxaa0pKT0ZOa2FGVlhNWFEzU1VSTlUzTkJUVGhwZWpkTlJXbFRaVkIxVVZFOSIsIlBFUlNJU1RfSURFTlRJVFlfSUZSQU1FX1VSTCI6eyJwcml2YXRlRG9Ob3RBY2Nlc3NPckVsc2VUcnVzdGVkUmVzb3VyY2VVcmxXcmFwcGVkVmFsdWUiOiJodHRwczovL3N0dWRpby55b3V0dWJlLmNvbS9wZXJzaXN0X2lkZW50aXR5In0sIlZJU0lCSUxJVFlfVElNRV9CRVRXRUVOX0pPQlNfTVMiOjEwMCwiU1RBUlRfSU5fVEhFQVRFUl9NT0RFIjpmYWxzZSwiU1RBUlRfSU5fRlVMTF9XSU5ET1dfTU9ERSI6ZmFsc2UsIlNFUlZJQ0VfV09SS0VSX1BST01QVF9OT1RJRklDQVRJT05TIjp0cnVlLCJTQk9YX0xBQkVMUyI6eyJTVUdHRVNUSU9OX0RJU01JU1NfTEFCRUwiOiJTdXBwcmltZXIiLCJTVUdHRVNUSU9OX0RJU01JU1NFRF9MQUJFTCI6IlN1Z2dlc3Rpb24gc3VwcHJpbcOpZSJ9LCJPTkVfUElDS19VUkwiOiIiLCJOT19FTVBUWV9EQVRBX0lNRyI6dHJ1ZSwiTUVOVElPTlNfRURVX0hFTFBfTElOSyI6Imh0dHBzOi8vc3VwcG9ydC5nb29nbGUuY29tL3lvdXR1YmUvP3BcdTAwM2RjcmVhdG9yX2NvbW11bml0eSIsIkRFRkVSUkVEX0RFVEFDSCI6dHJ1ZSwiUkVDQVBUQ0hBX1YzX1NJVEVLRVkiOiI2TGVkb09jVUFBQUFBSEE0Q0ZHOXpScGFDTmpZajMzU1lqelE5Y1R5IiwiUExBWUVSX0pTX1VSTCI6Ii9zL3BsYXllci9iMTI4ZGRhMC9wbGF5ZXJfaWFzLnZmbHNldC9mcl9GUi9iYXNlLmpzIiwiUExBWUVSX0NTU19VUkwiOiIvcy9wbGF5ZXIvYjEyOGRkYTAvd3d3LXBsYXllci5jc3MiLCJMSU5LX0dBTF9ET01BSU4iOiJodHRwczovL2FjY291bnRsaW5raW5nLXBhLWNsaWVudHM2LnlvdXR1YmUuY29tIiwiTElOS19PSVNfRE9NQUlOIjoib2F1dGhpbnRlZ3JhdGlvbnMtY2xpZW50czYueW91dHViZS5jb20iLCJJU19UQUJMRVQiOmZhbHNlLCJMSU5LX0FQSV9LRVkiOiJBSXphU3lEb3BoQVF1eXlpQnI4aDBueXBFd1hVS296SC1CRXN3RDAiLCJESVNBQkxFX1dBUk1fTE9BRFMiOmZhbHNlLCJWT1pfQVBJX0tFWSI6IkFJemFTeUJVMnhFX0pIdkI2d2FnM3RNZmh4WHBnMlFfVzh4bk0tSSIsIlNUUyI6MTk1MTMsIlNCT1hfU0VUVElOR1MiOnsiSEFTX09OX1NDUkVFTl9LRVlCT0FSRCI6ZmFsc2UsIklTX0ZVU0lPTiI6ZmFsc2UsIklTX1BPTFlNRVIiOnRydWUsIlJFUVVFU1RfRE9NQUlOIjoiZnIiLCJSRVFVRVNUX0xBTkdVQUdFIjoiZnIiLCJTRU5EX1ZJU0lUT1JfREFUQSI6dHJ1ZSwiU0VBUkNIQk9YX0JFSEFWSU9SX0VYUEVSSU1FTlQiOiJ6ZXJvLXByZWZpeCIsIlNFQVJDSEJPWF9FTkFCTEVfUkVGSU5FTUVOVF9TVUdHRVNUIjp0cnVlLCJTRUFSQ0hCT1hfVEFQX1RBUkdFVF9FWFBFUklNRU5UIjowLCJTRUFSQ0hCT1hfWkVST19UWVBJTkdfU1VHR0VTVF9VU0VfUkVHVUxBUl9TVUdHRVNUIjoiYWx3YXlzIiwiU1VHR19FWFBfSUQiOiJ1cWFwMTNubW5lcmUseXRwby5iby5tZVx1MDAzZDEseXRwb3NvLmJvLm1lXHUwMDNkMSx5dHBvLmJvLnJvLm1pXHUwMDNkMjQzNzI5NjcseXRwb3NvLmJvLnJvLm1pXHUwMDNkMjQzNzI5NjcsY2Zyb1x1MDAzZDEseXRwby5iby5tZVx1MDAzZDAseXRwb3NvLmJvLm1lXHUwMDNkMCx5dHBvLmJvLnJvLm1pXHUwMDNkMjQ1NTc1NjYseXRwb3NvLmJvLnJvLm1pXHUwMDNkMjQ1NTc1NjYiLCJWSVNJVE9SX0RBVEEiOiJDZ3RzWlc1U1ZrNWxia05XU1NpV3ZvaWtCZyUzRCUzRCIsIlNFQVJDSEJPWF9IT1NUX09WRVJSSURFIjoic3VnZ2VzdHF1ZXJpZXMtY2xpZW50czYueW91dHViZS5jb20iLCJISURFX1JFTU9WRV9MSU5LIjpmYWxzZX0sIlNCT1hfSlNfVVJMIjoiaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL3d3dy1zZWFyY2hib3gudmZsc2V0L3d3dy1zZWFyY2hib3guanMifSk7IHdpbmRvdy55dGNmZy5vYmZ1c2NhdGVkRGF0YV8gPSBbXTt2YXIgc2V0TWVzc2FnZT1mdW5jdGlvbihtc2cpe2lmKHdpbmRvdy55dCYmeXQuc2V0TXNnKXl0LnNldE1zZyhtc2cpO2Vsc2V7d2luZG93Lnl0Y2ZnPXdpbmRvdy55dGNmZ3x8e307eXRjZmcubXNncz1tc2d9fTsKc2V0TWVzc2FnZSh7IkFEREVEX1RPX1FVRVVFIjoiQWpvdXTDqWUgw6AgbGEgZmlsZSBkXHUwMDI3YXR0ZW50ZSIsIkFERF9UT19EUk9QRE9XTl9MQUJFTCI6IkVucmVnaXN0cmVyIGRhbnMuLi4iLCJBRF9CQURHRV9URVhUIjoiQW5ub25jZSIsIkFEX1RJVExFIjoiQW5ub25jZcKgOiAkdGl0bGUuIiwiQkFDS19BTFRfTEFCRUwiOiJSZXRvdXIiLCJCQUNLX09OTElORSI6IkRlIG5vdXZlYXUgY29ubmVjdMOpIMOgIEludGVybmV0IiwiQ0FOQ0VMIjoiQW5udWxlciIsIkNBUFRJT05fT0ZGX1RPQVNUIjoiU291cy10aXRyZXMgZMOpc2FjdGl2w6lzIiwiQ0FQVElPTl9PTl9UT0FTVCI6IlNvdXMtdGl0cmVzIGFjdGl2w6lzIiwiQ0hFQ0tfQ09OTkVDVElPTl9PUl9ET1dOTE9BRFMiOiJWZXVpbGxleiB2w6lyaWZpZXIgdm90cmUgY29ubmV4aW9uIG91IHJlZ2FyZGVyIHZvcyB2aWTDqW9zIHTDqWzDqWNoYXJnw6llcy4iLCJDTEVBUiI6IlN1cHByaW1lciIsIkNMT1NFIjoiRmVybWVyIiwiQ0xPU0VEX0NBUFRJT05TX0RJU0FCTEVEIjoiUGFzIGRlIHNvdXMtdGl0cmVzIGRpc3BvbmlibGVzIHBvdXIgY2V0dGUgdmlkw6lvLiIsIkNPTU1FTlRfTEFCRUwiOiJDb21tZW50ZXIiLCJDT05ORUNUX1RPX1RIRV9JTlRFUk5FVCI6IkNvbm5lY3Rlei12b3VzIMOgIEludGVybmV0IiwiQ09OVElOVUVfV0FUQ0hJTkciOiJDb250aW51ZXIgw6AgcmVnYXJkZXIiLCJERUxFVEUiOiJTdXBwcmltZXIiLCJERUxFVEVEX1BMQVlMSVNUIjoiUGxheWxpc3Qgc3VwcHJpbcOpZSBkZXMgdMOpbMOpY2hhcmdlbWVudHMuIiwiREVMRVRFRF9WSURFTyI6IlZpZMOpbyBzdXBwcmltw6llIGRlcyB0w6lsw6ljaGFyZ2VtZW50cy4iLCJERUxFVEVfQUxMX0RPV05MT0FEU19QUk9NUFQiOiJTdXBwcmltZXIgdG91cyBsZXMgdMOpbMOpY2hhcmdlbWVudHPCoD8iLCJERUxFVEVfRlJPTV9ET1dOTE9BRFMiOiJTdXBwcmltZXIgZGVzIHTDqWzDqWNoYXJnZW1lbnRzIiwiREVMRVRJTkdfQUxMIjoiU3VwcHJlc3Npb24gZGVzIHTDqWzDqWNoYXJnZW1lbnRz4oCmIiwiRElTTElLRV9MQUJFTCI6IkplIG5cdTAwMjdhaW1lIHBhcyIsIkRJU01JU1MiOiJJZ25vcmVyIiwiRE1BX0NPTlNFTlRfQ09ORklSTUFUSU9OIjoiVm90cmUgY2hvaXggcHJlbmRyYSBlZmZldCBsZSA2wqBtYXJzwqAyMDI0LiBWb3VzIHBvdXZleiBtb2RpZmllciB2b3Mgb3B0aW9ucyDDoCB0b3V0IG1vbWVudCBkYW5zIHZvdHJlIGNvbXB0ZcKgR29vZ2xlLiIsIkRNQV9DT05TRU5UX0dFTkVSQUxfRVJST1IiOiJVbmUgZXJyZXVyIHNcdTAwMjdlc3QgcHJvZHVpdGUgbG9ycyBkdSBjaGFyZ2VtZW50IiwiRE1BX0NPTlNFTlRfUkVDT1JEX0VSUk9SIjoiVW5lIGVycmV1ciBhIGVtcMOqY2jDqSBsXHUwMDI3ZW5yZWdpc3RyZW1lbnQgZGUgdm9zIGNob2l4IiwiRE9XTkxPQUQiOiJUw6lsw6ljaGFyZ2VyIiwiRE9XTkxPQURFRCI6IlTDqWzDqWNoYXJnw6llIiwiRE9XTkxPQURJTkciOiJUw6lsw6ljaGFyZ2VtZW50IiwiRE9XTkxPQURJTkdfUEVSQ0VOVCI6IlTDqWzDqWNoYXJnZW1lbnTigKYgJHBlcmNlbnQlIiwiRE9XTkxPQURTIjoiVMOpbMOpY2hhcmdlbWVudHMiLCJET1dOTE9BRFNfQVZBSUxBQklMSVRZIjoiTGVzIHTDqWzDqWNoYXJnZW1lbnRzIHJlc3RlbnQgZGlzcG9uaWJsZXMgdGFudCBxdWUgdm90cmUgYXBwYXJlaWwgc2UgY29ubmVjdGUgw6AgSW50ZXJuZXQgYXUgbW9pbnMgdW5lIGZvaXMgdG91cyBsZXMgMzDCoGpvdXJzLiIsIkRPV05MT0FEU19TRVRUSU5HUyI6IlBhcmFtw6h0cmVzIGRlcyB0w6lsw6ljaGFyZ2VtZW50cyIsIkRPV05MT0FEX0VYUElSRUQiOiJUw6lsw6ljaGFyZ2VtZW50IGV4cGlyw6kiLCJET1dOTE9BRF9QQVVTRUQiOiJUw6lsw6ljaGFyZ2VtZW50IG1pcyBlbiBwYXVzZSIsIkRPV05MT0FEX1FVQUxJVFkiOiJRdWFsaXTDqSBkZSB0w6lsw6ljaGFyZ2VtZW50IiwiRE9fTk9UX0hBVkVfRE9XTkxPQURTIjoiVm91cyBuXHUwMDI3YXZleiB0w6lsw6ljaGFyZ8OpIGF1Y3VuZSB2aWTDqW8iLCJFRElUX0FWQVRBUl9MQUJFTCI6Ik1vZGlmaWVyIGxhIHBob3RvIGRlIHByb2ZpbCIsIkVEVV9HT1RfSVQiOiJPSyIsIkVORF9PRl9QTEFZTElTVCI6IkZpbiBkZSBsYSBwbGF5bGlzdCIsIkVOVEVSX0RBVEVfT1JfRUFSTElFUiI6IlNhaXNpc3NleiAkYWxsb3dlZF9kYXRlIG91IHVuZSBkYXRlIGFudMOpcmlldXJlIiwiRU5URVJfREFURV9PUl9MQVRFUiI6IlNhaXNpc3NleiAkYWxsb3dlZF9kYXRlIG91IHVuZSBkYXRlIHVsdMOpcmlldXJlIiwiRlJFRUJJRV9KT0lOX01FTUJFUlNISVBfRURVX1RFWFQiOiJDZXR0ZSBjaGHDrm5lIHByb3Bvc2UgdW5lIG9mZnJlIGRlIHNvdXNjcmlwdGlvbi4gQXZlYyBZb3VUdWJlwqBQcmVtaXVtLCB2b3VzIHBvdXZleiB2b3VzIHkgaW5zY3JpcmUgZ3JhdHVpdGVtZW50LiIsIkdFVF9QUkVNSVVNIjoiT2J0ZW5pciBQcmVtaXVtIiwiR09fVE9fRE9XTkxPQURTIjoiVm9pciBsZXMgdMOpbMOpY2hhcmdlbWVudHMiLCJHVUlERV9BTFRfTEFCRUwiOiJHdWlkZSIsIkhPUklaT05UQUxfTElTVF9ORVhUX0xBQkVMIjoiU3VpdmFudCIsIkhPUklaT05UQUxfTElTVF9QUkVWSU9VU19MQUJFTCI6IlByw6ljw6lkZW50IiwiSU1BR0VfSE9SSVpPTlRBTF9QT1NJVElPTl9MQUJFTCI6IkxlIGNlbnRyZSBkZSBsXHUwMDI3YXBlcsOndSBzZSB0cm91dmUgw6AgJHhfcGVyY2VudMKgJSBkdSBib3JkIGdhdWNoZSBldCDDoCAkeV9wZXJjZW50wqAlIGR1IGJvcmQgZHJvaXQgZGUgbFx1MDAyN2ltYWdlLiIsIklNQUdFX1ZFUlRJQ0FMX1BPU0lUSU9OX0xBQkVMIjoiTGUgY2VudHJlIGRlIGxcdTAwMjdhcGVyw6d1IHNlIHRyb3V2ZSDDoCAkeF9wZXJjZW50wqAlIGR1IGhhdXQgZXQgw6AgJHlfcGVyY2VudMKgJSBkdSBiYXMgZGUgbFx1MDAyN2ltYWdlLiIsIklOVkFMSURfREFURV9FUlJPUiI6IkRhdGUgaW5jb3JyZWN0ZSIsIkpPSU5fTUVNQkVSU0hJUF9FRFVfVEVYVCI6IkLDqW7DqWZpY2lleiBkXHUwMDI3YXZhbnRhZ2VzIGV4Y2x1c2lmcyBlbiBzb3VzY3JpdmFudCDDoCBjZXR0ZSBjaGHDrm5lLiIsIkpPSU5fTUVNQkVSU0hJUF9FRFVfVElUTEUiOiJTb3VzY3JpcHRpb24iLCJLRUVQX09QRU4iOiJHYXJkZXogbGEgZmVuw6p0cmUgb3V2ZXJ0ZSBwb3VyIGNvbnRpbnVlciIsIkxJQlJBUllfR1VJREVfSVRFTV9FRFVfVEVYVCI6IlZvdXMgeSB0cm91dmVyZXogdm90cmUgaGlzdG9yaXF1ZSwgdm9zIHBsYXlsaXN0cywgdm9zIGFjaGF0cyBldCBwbHVzIGVuY29yZS4iLCJMSUJSQVJZX0dVSURFX0lURU1fRURVX1RJVExFIjoiRMOpY291dnJleiB2b3RyZSBub3V2ZWxsZSBiaWJsaW90aMOocXVlIiwiTElLRV9MQUJFTCI6IkpcdTAwMjdhaW1lIiwiTE9DQUxfVElNRV9MQUJFTCI6IkhldXJlIGxvY2FsZSIsIkxPR09fQUxUX0xBQkVMIjoiQWNjdWVpbCBZb3VUdWJlIiwiTUFJTl9BUFBfV0VCX0NPTU1FTlRfVEVBU0VSX1RPT0xUSVAiOiJDbGlxdWV6IGljaSBwb3VyIGxpcmUgbGVzIGNvbW1lbnRhaXJlcyB0b3V0IGVuIHJlZ2FyZGFudCBsYSB2aWTDqW8uIiwiTUFOQUdFX01FTUJFUlNISVBfRURVX1RFWFQiOiJBY2PDqWRleiDDoCB2b3MgYXZhbnRhZ2VzIGV0IGfDqXJleiB2b3RyZSBzb3VzY3JpcHRpb24uIiwiTUVOVElPTlNfRURVX1RFWFQiOiJDb25zdWx0ZXogbGUgY2VudHJlIGRcdTAwMjdhaWRlIHBvdXIgZW4gc2F2b2lyIHBsdXMgc3VyIGxlIGZvbmN0aW9ubmVtZW50IGRlcyBtZW50aW9ucyBzdXIgWW91VHViZS4iLCJNRU5USU9OU19FRFVfVElUTEUiOiJFbiBzYXZvaXIgcGx1cyIsIk1JTklQTEFZRVJfQ0xPU0UiOiJGZXJtZXIgbGUgbGVjdGV1ciIsIk1JTklQTEFZRVJfQ09MTEFQU0VfTEFCRUwiOiJSw6lkdWlyZSIsIk1JTklQTEFZRVJfRVhQQU5EX0xBQkVMIjoiRMOpdmVsb3BwZXIiLCJORVhUX1ZJREVPX0xBQkVMIjoiVmlkw6lvIHN1aXZhbnRlIiwiTk9fQU5HTEVfQlJBQ0tFVF9MQUJFTCI6IkxlIHRpdHJlIGRlIGxhIHBsYXlsaXN0IG5lIHBldXQgcGFzIGNvbnRlbmlyIFx1MDAzYyBvdSBcdTAwM2UiLCJOT19ET1dOTE9BRFMiOiJBdWN1biB0w6lsw6ljaGFyZ2VtZW50IiwiTk9fSU5URVJORVRfQ09OTkVDVElPTiI6IkF1Y3VuZSBjb25uZXhpb24gSW50ZXJuZXQiLCJPRkZMSU5FX0NIRUNLX0NPTk5FQ1RJT04iOiJWb3VzIG5cdTAwMjfDqnRlcyBwYXMgY29ubmVjdMOpLiBWw6lyaWZpZXogdm90cmUgY29ubmV4aW9uLiIsIlBBVVNFX0RPV05MT0FESU5HIjoiTWV0dHJlIGVuIHBhdXNlIGxlIHTDqWzDqWNoYXJnZW1lbnQiLCJQTEFZRVJfTEFCRUxfTVVURSI6IkNvdXBlciBsZSBzb27CoChtKSIsIlBMQVlFUl9MQUJFTF9QQVVTRSI6IlBhdXNlwqAoaykiLCJQTEFZRVJfTEFCRUxfUExBWSI6IkxlY3R1cmXCoChrKSIsIlBMQVlFUl9MQUJFTF9VTk1VVEUiOiJSw6lhY3RpdmVyIGxlIHNvbsKgKG0pIiwiUExBWUxJU1RfTkVYVF9WSURFT19USVRMRSI6IsOAIHN1aXZyZcKgOiAkdmlkZW9fdGl0bGUiLCJQTEFZX0FMTCI6IlRvdXQgbGlyZSIsIlBSRVBBUklOR19UT19ET1dOTE9BRCI6IlByw6lwYXJhdGlvbiBkdSB0w6lsw6ljaGFyZ2VtZW504oCmIiwiUFJFVklPVVNfVklERU9fTEFCRUwiOiJWaWTDqW8gcHLDqWPDqWRlbnRlIiwiUVVFVUUiOiJGaWxlIGRcdTAwMjdhdHRlbnRlIiwiUVVFVUVfQ0xFQVJFRCI6Intjb3VudCxwbHVyYWwsIFx1MDAzZDF7McKgdmlkw6lvIHN1cHByaW3DqWUgZGUgbGEgZmlsZSBkXHUwMDI3YXR0ZW50ZX1vbmV7IyB2aWRlb3MgaW4gdGhlIHF1ZXVlIHJlbW92ZWR9b3RoZXJ7I8Kgdmlkw6lvcyBzdXBwcmltw6llcyBkZSBsYSBmaWxlIGRcdTAwMjdhdHRlbnRlfX0iLCJRVUVVRV9DTEVBUkVEX1VOUExVUkFMSVpFRCI6IkZpbGUgZFx1MDAyN2F0dGVudGUgZWZmYWPDqWUiLCJRVUVVRV9DTE9TRV9NSU5JUExBWUVSX0NPTkZJUk1fQk9EWV9URVhUIjoiVm91bGV6LXZvdXMgdnJhaW1lbnQgZmVybWVyIGxlIGxlY3RldXLCoD8iLCJRVUVVRV9DTE9TRV9NSU5JUExBWUVSX0NPTkZJUk1fVElUTEUiOiJMYSBmaWxlIGRcdTAwMjdhdHRlbnRlIHNlcmEgZWZmYWPDqWUiLCJRVUVVRV9SRUNPVkVSX0JVVFRPTiI6IlJlc3RhdXJlciIsIlFVRVVFX1JFQ09WRVJfTUVTU0FHRSI6IlLDqWN1cMOpcmVyIGxhIGZpbGUgZFx1MDAyN2F0dGVudGUiLCJSRUFDSF9CT1RUT01fT0ZfSU1BR0VfVEVYVCI6IlZvdXMgYXZleiBhdHRlaW50IGxlIGJhcyBkZSBsXHUwMDI3aW1hZ2UiLCJSRUFDSF9MRUZUX09GX0lNQUdFX1RFWFQiOiJWb3VzIGF2ZXogYXR0ZWludCBsZSBib3JkIGdhdWNoZSBkZSBsXHUwMDI3aW1hZ2UiLCJSRUFDSF9SSUdIVF9PRl9JTUFHRV9URVhUIjoiVm91cyBhdmV6IGF0dGVpbnQgbGUgYm9yZCBkcm9pdCBkZSBsXHUwMDI3aW1hZ2UiLCJSRUFDSF9UT1BfT0ZfSU1BR0VfVEVYVCI6IlZvdXMgYXZleiBhdHRlaW50IGxlIGhhdXQgZGUgbFx1MDAyN2ltYWdlIiwiUkVNRU1CRVJfTVlfU0VUVElOR1MiOiJFbnJlZ2lzdHJlciBtZXMgcGFyYW3DqHRyZXMiLCJSRU1FTUJFUl9NWV9TRVRUSU5HU19OX0RBWVMiOiJFbnJlZ2lzdHJlciBtZXMgcGFyYW3DqHRyZXMgcGVuZGFudCAkZGF5c190aWxsX2V4cGlyZWTCoGpvdXJzIiwiUkVQT1NJVElPTl9JTUFHRV9IT1JJWk9OVEFMTFlfTEFCRUwiOiJVdGlsaXNleiBsZXMgdG91Y2hlcyBmbMOpY2jDqWVzIGdhdWNoZSBldCBkcm9pdGUgcG91ciByZXBvc2l0aW9ubmVyIGxcdTAwMjdhcGVyw6d1IiwiUkVQT1NJVElPTl9JTUFHRV9WRVJUSUNBTExZX0xBQkVMIjoiVXRpbGlzZXogbGVzIHRvdWNoZXMgZmzDqWNow6llcyB2ZXJzIGxlIGhhdXQgb3UgdmVycyBsZSBiYXMgcG91ciByZXBvc2l0aW9ubmVyIGxcdTAwMjdhcGVyw6d1IiwiUkVRVUlSRURfTEFCRUwiOiJPYmxpZ2F0b2lyZSIsIlJFU1VNRV9ET1dOTE9BRCI6IlJlcHJlbmRyZSBsZSB0w6lsw6ljaGFyZ2VtZW50IiwiUkVUUlkiOiJSw6llc3NheWVyIiwiU0JPWF9JTkFQUFJPUFJJQVRFX0FERElUSU9OQUwiOiJJbmRpcXVleiBkZXMgZMOpdGFpbHMgc3VwcGzDqW1lbnRhaXJlcyAoZmFjdWx0YXRpZikiLCJTQk9YX0lOQVBQUk9QUklBVEVfQ0FOQ0VMIjoiQW5udWxlciIsIlNCT1hfSU5BUFBST1BSSUFURV9DQVRFR09SWSI6IkxlcyBwcsOpZGljdGlvbnMgc8OpbGVjdGlvbm7DqWVzIHByw6lzZW50ZW50IGxlIHByb2Jsw6htZSBzdWl2YW50wqA6IiwiU0JPWF9JTkFQUFJPUFJJQVRFX0RBTkdFUk9VUyI6IkNhcmFjdMOocmUgZGFuZ2VyZXV4IiwiU0JPWF9JTkFQUFJPUFJJQVRFX0VYUExJQ0lUIjoiQ2FyYWN0w6hyZSBzZXh1ZWwgZXhwbGljaXRlIiwiU0JPWF9JTkFQUFJPUFJJQVRFX0hBVEVGVUwiOiJJbmNpdGF0aW9uIMOgIGxhIGhhaW5lIiwiU0JPWF9JTkFQUFJPUFJJQVRFX09USEVSIjoiQXV0cmUiLCJTQk9YX0lOQVBQUk9QUklBVEVfUFJPTVBUIjoiU2lnbmFsZXIgZGVzIHByw6lkaWN0aW9ucyBkZSByZWNoZXJjaGUiLCJTQk9YX0lOQVBQUk9QUklBVEVfUkVBU09OIjoiTW90aWYgKG9ibGlnYXRvaXJlKSIsIlNCT1hfSU5BUFBST1BSSUFURV9SRVBPUlQiOiJTaWduYWxlciIsIlNCT1hfSU5BUFBST1BSSUFURV9TVUJNSVQiOiJFbnZveWVyIiwiU0JPWF9JTkFQUFJPUFJJQVRFX1NVR0dFU1RJT05TIjoiU8OpbGVjdGlvbm5leiBsZXMgcHLDqWRpY3Rpb25zIHF1ZSB2b3VzIHNvdWhhaXRleiBzaWduYWxlcsKgOiIsIlNCT1hfSU5BUFBST1BSSUFURV9USVRMRSI6IlNpZ25hbGVyIGRlcyBwcsOpZGljdGlvbnMgZGUgcmVjaGVyY2hlIiwiU0JPWF9JTkFQUFJPUFJJQVRFX1RPQVNUIjoiTWVyY2kgcG91ciB2b3MgY29tbWVudGFpcmVzwqAhIiwiU0JPWF9JTkFQUFJPUFJJQVRFX1ZJT0xFTlQiOiJWaW9sZW5jZSIsIlNCT1hfUExBQ0VIT0xERVIiOiJSZWNoZXJjaGVyIiwiU0JPWF9WT0lDRV9PVkVSTEFZX1BMQUNFSE9MREVSIjoiw4ljb3V0ZeKApiIsIlNIQVJFX0xBQkVMIjoiUGFydGFnZXIiLCJTSEFSRV9QT1NUX0VEVV9URVhUIjoiVm91cyBwb3V2ZXogZMOpc29ybWFpcyBwYXJ0YWdlciBkZXMgcG9zdHMgc3VyIFlvdVR1YmUiLCJTSE9XX0xFU1MiOiJNb2lucyIsIlNIT1dfTU9SRSI6IlBsdXMiLCJTSUdOX0lOX0xBQkVMIjoiQ29ubmV4aW9uIiwiU01BUlRfRE9XTkxPQURTIjoiVMOpbMOpY2hhcmdlbWVudHMgaW50ZWxsaWdlbnRzIiwiU1RPUkFHRV9GVUxMIjoiTcOpbW9pcmUgcGxlaW5lIiwiU1VCU0NSSUJFX0xBQkVMIjoiU1x1MDAyN2Fib25uZXIiLCJTVUJTX0ZJTFRFUl9FRFVfQ0hBTk5FTF9URVhUIjoiQWZmaWNoYWdlIGRlcyBub3V2ZWxsZXMgdmlkw6lvcyBkZSBjZXR0ZSBjaGHDrm5lLiIsIlNVQlNfRklMVEVSX0VEVV9URVhUIjoiQ29uc3VsdGVyIGxlcyBub3V2ZWxsZXMgdmlkw6lvcyBkZSBjaGFxdWUgY2hhw65uZSIsIlNVQlNfR1VJREVfSVRFTV9FRFVfVEVYVCI6IkNvbnN1bHRlciBsZXMgbm91dmVsbGVzIHZpZMOpb3MgZGUgdG91cyB2b3MgYWJvbm5lbWVudHMiLCJUSU1FWk9ORV9GT1JNQVQiOiIoJHV0Y19vZmZzZXRfdGV4dCkgJGNpdHlfbmFtZSIsIlRSQU5TRkVSX0ZBSUxFRCI6IsOJY2hlYyBkdSB0w6lsw6ljaGFyZ2VtZW50IiwiVFJZX0FHQUlOX0xBVEVSIjoiVW4gcHJvYmzDqG1lIGVzdCBzdXJ2ZW51LiBWZXVpbGxleiByw6llc3NheWVyIHBsdXMgdGFyZC4iLCJUVVJOX09GRiI6IkTDqXNhY3RpdmVyIiwiVFVSTl9PTiI6IkFjdGl2ZXIiLCJVTkFWQUlMQUJMRV9PRkZMSU5FIjoiSW5kaXNwb25pYmxlIGhvcnMgY29ubmV4aW9uIiwiVU5ETyI6IkFubnVsZXIiLCJVTkRPX0FDVElPTiI6IkFubnVsZXIiLCJVUERBVEVEX1RJTUUiOiJNaXNlIMOgIGpvdXLCoDogJHJlbGF0aXZlX3RpbWUiLCJVUERBVEVfU01BUlRfRE9XTkxPQURTX05PVyI6Ik1ldHRyZSDDoCBqb3VyIiwiVVBEQVRJTkciOiJNaXNlIMOgIGpvdXLigKYiLCJVVENfT0ZGU0VUX0ZPUk1BVCI6IkdNVCR1dGNfb2Zmc2V0IiwiVklERU9TX0RPV05MT0FESU5HIjp7ImNhc2UxIjoiVMOpbMOpY2hhcmdlbWVudCBkZSAxwqB2aWTDqW/igKYiLCJvbmUiOiJUw6lsw6ljaGFyZ2VtZW50IGRlICPCoHZpZMOpb+KApiIsIm90aGVyIjoiVMOpbMOpY2hhcmdlbWVudCBkZSAjwqB2aWTDqW9z4oCmIn0sIlZJREVPU19ET1dOTE9BRElOR19SQVRJTyI6IlTDqWzDqWNoYXJnZW1lbnTigKYgJGRvd25sb2FkZWQvJHRvdGFsIiwiVklERU9fQUNUSU9OX01FTlUiOiJNZW51IGRcdTAwMjdhY3Rpb25zIiwiVklFV19ET1dOTE9BRFMiOiJBZmZpY2hlciIsIlZJRVdfRlVMTF9QTEFZTElTVCI6IkFmZmljaGVyIGxhIHBsYXlsaXN0IGNvbXBsw6h0ZSIsIldBSVRJTkdfRk9SX0lOVEVSTkVUIjoiRW4gYXR0ZW50ZSBkZSBsYSBjb25uZXhpb24gSW50ZXJuZXTigKYiLCJXQUlUSU5HX1RPX0RPV05MT0FEIjoiRW4gYXR0ZW50ZSBkZSB0w6lsw6ljaGFyZ2VtZW504oCmIiwiWU9VX0FSRV9PRkZMSU5FIjoiVm91cyDDqnRlcyBob3JzIGNvbm5leGlvbiIsIl9fbGFuZ19fIjoiZnIifSk7fSkoKTt5dGNmZy5zZXQoImluaXRpYWxJbm5lcldpZHRoIix3aW5kb3cuaW5uZXJXaWR0aCk7eXRjZmcuc2V0KCJpbml0aWFsSW5uZXJIZWlnaHQiLHdpbmRvdy5pbm5lckhlaWdodCk7Cjwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnbHBjZicsIG51bGwsICcnKTt9PC9zY3JpcHQ+PHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9qc2Jpbi9zY2hlZHVsZXIudmZsc2V0L3NjaGVkdWxlci5qcyIgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPjwvc2NyaXB0PjxzY3JpcHQgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9zL2Rlc2t0b3AvMzc0ZmFhZDUvanNiaW4vd3d3LWkxOG4tY29uc3RhbnRzLWZyX0ZSLnZmbHNldC93d3ctaTE4bi1jb25zdGFudHMuanMiIG5vbmNlPSJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIj48L3NjcmlwdD48c2NyaXB0IHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL3d3dy10YW1wZXJpbmcudmZsc2V0L3d3dy10YW1wZXJpbmcuanMiIG5vbmNlPSJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIj48L3NjcmlwdD48c2NyaXB0IHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL3NwZi52ZmxzZXQvc3BmLmpzIiBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+PC9zY3JpcHQ+PHNjcmlwdCBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+aWYod2luZG93WyJfc3BmX3N0YXRlIl0pd2luZG93WyJfc3BmX3N0YXRlIl0uY29uZmlnPXsiYXNzdW1lLWFsbC1qc29uLXJlcXVlc3RzLWNodW5rZWQiOnRydWV9Owo8L3NjcmlwdD48c2NyaXB0IHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL25ldHdvcmsudmZsc2V0L25ldHdvcmsuanMiIG5vbmNlPSJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIj48L3NjcmlwdD48c2NyaXB0IG5vbmNlPSJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIj5pZiAod2luZG93Lnl0Y3NpKSB7d2luZG93Lnl0Y3NpLnRpY2soJ2NzbCcsIG51bGwsICcnKTt9PC9zY3JpcHQ+PGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSIvL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2NzczI/ZmFtaWx5PVJvYm90bzp3Z2h0QDMwMDs0MDA7NTAwOzcwMCZmYW1pbHk9WW91VHViZStTYW5zOndnaHRAMzAwLi45MDAmZGlzcGxheT1zd2FwIiBub25jZT0iTV9FT0JuVlNBdEV4eERxYlE0VTJKZyI+PHNjcmlwdCBuYW1lPSJ3d3ctcm9ib3RvIiBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+aWYgKGRvY3VtZW50LmZvbnRzICYmIGRvY3VtZW50LmZvbnRzLmxvYWQpIHtkb2N1bWVudC5mb250cy5sb2FkKCI0MDAgMTBwdCBSb2JvdG8iLCAiIik7IGRvY3VtZW50LmZvbnRzLmxvYWQoIjUwMCAxMHB0IFJvYm90byIsICIiKTt9PC9zY3JpcHQ+PGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9zL2Rlc2t0b3AvMzc0ZmFhZDUvY3NzYmluL3d3dy1vbmVwaWNrLmNzcyIgbm9uY2U9Ik1fRU9CblZTQXRFeHhEcWJRNFUySmciPjxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9fL3l0bWFpbmFwcHdlYi9fL3NzL2s9eXRtYWluYXBwd2ViLmtldmxhcl9iYXNlLjNla2RIMDIza1NZLkwuWC5PL2FtPUFBVS9kPTAvcnM9QUdLTXl3R0hpZVdLVnBEc0NtYnAwSUVPRklCQnNmdmtmUSIgbm9uY2U9Ik1fRU9CblZTQXRFeHhEcWJRNFUySmciPjxzdHlsZSBjbGFzcz0iZ2xvYmFsX3N0eWxlcyIgbm9uY2U9Ik1fRU9CblZTQXRFeHhEcWJRNFUySmciPmJvZHl7cGFkZGluZzowO21hcmdpbjowO292ZXJmbG93LXk6c2Nyb2xsfWJvZHkuYXV0b3Njcm9sbHtvdmVyZmxvdy15OmF1dG99Ym9keS5uby1zY3JvbGx7b3ZlcmZsb3c6aGlkZGVufWJvZHkubm8teS1zY3JvbGx7b3ZlcmZsb3cteTpoaWRkZW59LmhpZGRlbntkaXNwbGF5Om5vbmV9dGV4dGFyZWF7LS1wYXBlci1pbnB1dC1jb250YWluZXItaW5wdXRfLV93aGl0ZS1zcGFjZTpwcmUtd3JhcH0uZ3JlY2FwdGNoYS1iYWRnZXt2aXNpYmlsaXR5OmhpZGRlbn08L3N0eWxlPjxzdHlsZSBjbGFzcz0ibWFzdGhlYWRfc2hlbGwiIG5vbmNlPSJNX0VPQm5WU0F0RXh4RHFiUTRVMkpnIj55dGQtbWFzdGhlYWQuc2hlbGx7YmFja2dyb3VuZC1jb2xvcjojZmZmIWltcG9ydGFudDtwb3NpdGlvbjpmaXhlZDt0b3A6MDtyaWdodDowO2xlZnQ6MDtkaXNwbGF5Oi1tcy1mbGV4O2Rpc3BsYXk6LXdlYmtpdC1mbGV4O2Rpc3BsYXk6LXdlYmtpdC1ib3g7ZGlzcGxheTotbW96LWJveDtkaXNwbGF5Oi1tcy1mbGV4Ym94O2Rpc3BsYXk6ZmxleDtoZWlnaHQ6NTZweDstbXMtZmxleC1hbGlnbjpjZW50ZXI7LXdlYmtpdC1hbGlnbi1pdGVtczpjZW50ZXI7LXdlYmtpdC1ib3gtYWxpZ246Y2VudGVyOy1tb3otYm94LWFsaWduOmNlbnRlcjthbGlnbi1pdGVtczpjZW50ZXJ9eXRkLW1hc3RoZWFkLnNoZWxsICNtZW51LWljb257bWFyZ2luLWxlZnQ6MTZweH15dGQtYXBwPnl0ZC1tYXN0aGVhZC5jaHVua2Vke3Bvc2l0aW9uOmZpeGVkO3RvcDowO3dpZHRoOjEwMCV9eXRkLW1hc3RoZWFkLnNoZWxsLmRhcmsseXRkLW1hc3RoZWFkLnNoZWxsLnRoZWF0ZXJ7YmFja2dyb3VuZC1jb2xvcjojMGYwZjBmIWltcG9ydGFudH15dGQtbWFzdGhlYWQuc2hlbGwuZnVsbC13aW5kb3ctbW9kZXtiYWNrZ3JvdW5kLWNvbG9yOiMwZjBmMGYhaW1wb3J0YW50O29wYWNpdHk6MDstd2Via2l0LXRyYW5zZm9ybTp0cmFuc2xhdGVZKGNhbGMoLTEwMCUgLSA1cHgpKTt0cmFuc2Zvcm06dHJhbnNsYXRlWShjYWxjKC0xMDAlIC0gNXB4KSl9eXRkLW1hc3RoZWFkLnNoZWxsPjpmaXJzdC1jaGlsZHtwYWRkaW5nLWxlZnQ6MTZweH15dGQtbWFzdGhlYWQuc2hlbGw+Omxhc3QtY2hpbGR7cGFkZGluZy1yaWdodDoxNnB4fXl0ZC1tYXN0aGVhZCAjbWFzdGhlYWQtbG9nb3tkaXNwbGF5Oi1tcy1mbGV4O2Rpc3BsYXk6LXdlYmtpdC1mbGV4O2Rpc3BsYXk6LXdlYmtpdC1ib3g7ZGlzcGxheTotbW96LWJveDtkaXNwbGF5Oi1tcy1mbGV4Ym94O2Rpc3BsYXk6ZmxleH15dGQtbWFzdGhlYWQgI21hc3RoZWFkLWxvZ28gI2NvdW50cnktY29kZXttYXJnaW4tcmlnaHQ6MnB4fXl0ZC1tYXN0aGVhZC5zaGVsbCAjeXQtbG9nby1yZWQtc3ZnLHl0ZC1tYXN0aGVhZC5zaGVsbCAjeXQtbG9nby1yZWQtdXBkYXRlZC1zdmcseXRkLW1hc3RoZWFkLnNoZWxsICN5dC1sb2dvLXN2Zyx5dGQtbWFzdGhlYWQuc2hlbGwgI3l0LWxvZ28tdXBkYXRlZC1zdmd7LXdlYmtpdC1hbGlnbi1zZWxmOmNlbnRlcjstbXMtZmxleC1pdGVtLWFsaWduOmNlbnRlcjthbGlnbi1zZWxmOmNlbnRlcjttYXJnaW4tbGVmdDo4cHg7cGFkZGluZzowO2NvbG9yOiMwMDB9eXRkLW1hc3RoZWFkLnNoZWxsICNhMTF5LXNraXAtbmF2e2Rpc3BsYXk6bm9uZX15dGQtbWFzdGhlYWQuc2hlbGwgc3Zne3dpZHRoOjQwcHg7aGVpZ2h0OjQwcHg7cGFkZGluZzo4cHg7bWFyZ2luLXJpZ2h0OjhweDstbW96LWJveC1zaXppbmc6Ym9yZGVyLWJveDtib3gtc2l6aW5nOmJvcmRlci1ib3g7Y29sb3I6IzYwNjA2MDtmaWxsOmN1cnJlbnRDb2xvcn15dGQtbWFzdGhlYWQgLmV4dGVybmFsLWljb257d2lkdGg6MjRweDtoZWlnaHQ6MjRweH15dGQtbWFzdGhlYWQgLnl0LWljb25zLWV4dHtmaWxsOmN1cnJlbnRDb2xvcjtjb2xvcjojNjA2MDYwfXl0ZC1tYXN0aGVhZC5zaGVsbC5kYXJrIC55dC1pY29ucy1leHQgeXRkLW1hc3RoZWFkLnNoZWxsLnRoZWF0ZXIgLnl0LWljb25zLWV4dHtmaWxsOiNmZmZ9eXRkLW1hc3RoZWFkIHN2ZyN5dC1sb2dvLXN2Z3t3aWR0aDo4MHB4fXl0ZC1tYXN0aGVhZCBzdmcjeXQtbG9nby1yZWQtc3Zne3dpZHRoOjEwNi40cHh9eXRkLW1hc3RoZWFkIHN2ZyN5dC1sb2dvLXVwZGF0ZWQtc3Zne3dpZHRoOjkwcHh9eXRkLW1hc3RoZWFkIHN2ZyN5dC1sb2dvLXJlZC11cGRhdGVkLXN2Z3t3aWR0aDo5N3B4fUBtZWRpYSAobWF4LXdpZHRoOjY1NnB4KXt5dGQtbWFzdGhlYWQuc2hlbGw+OmZpcnN0LWNoaWxke3BhZGRpbmctbGVmdDo4cHh9eXRkLW1hc3RoZWFkLnNoZWxsPjpsYXN0LWNoaWxke3BhZGRpbmctcmlnaHQ6OHB4fXl0ZC1tYXN0aGVhZC5zaGVsbCBzdmd7bWFyZ2luLXJpZ2h0OjB9eXRkLW1hc3RoZWFkICNtYXN0aGVhZC1sb2dvey1tcy1mbGV4OjEgMSAwLjAwMDAwMDAwMXB4Oy13ZWJraXQtZmxleDoxOy13ZWJraXQtYm94LWZsZXg6MTstbW96LWJveC1mbGV4OjE7ZmxleDoxOy13ZWJraXQtZmxleC1iYXNpczowLjAwMDAwMDAwMXB4Oy1tcy1mbGV4LXByZWZlcnJlZC1zaXplOjAuMDAwMDAwMDAxcHg7ZmxleC1iYXNpczowLjAwMDAwMDAwMXB4fXl0ZC1tYXN0aGVhZC5zaGVsbCAjeXQtbG9nby1yZWQtc3ZnLHl0ZC1tYXN0aGVhZC5zaGVsbCAjeXQtbG9nby1zdmd7bWFyZ2luLWxlZnQ6NHB4fX1AbWVkaWEgKG1pbi13aWR0aDo4NzZweCl7eXRkLW1hc3RoZWFkICNtYXN0aGVhZC1sb2dve3dpZHRoOjEyOXB4fX0jbWFzdGhlYWQtc2tlbGV0b24taWNvbnN7ZGlzcGxheTotd2Via2l0LWJveDtkaXNwbGF5Oi13ZWJraXQtZmxleDtkaXNwbGF5Oi1tb3otYm94O2Rpc3BsYXk6LW1zLWZsZXhib3g7ZGlzcGxheTpmbGV4Oy13ZWJraXQtYm94LWZsZXg6MTstd2Via2l0LWZsZXg6MTstbW96LWJveC1mbGV4OjE7LW1zLWZsZXg6MTtmbGV4OjE7LXdlYmtpdC1ib3gtb3JpZW50Omhvcml6b250YWw7LXdlYmtpdC1ib3gtZGlyZWN0aW9uOm5vcm1hbDstd2Via2l0LWZsZXgtZGlyZWN0aW9uOnJvdzstbW96LWJveC1vcmllbnQ6aG9yaXpvbnRhbDstbW96LWJveC1kaXJlY3Rpb246bm9ybWFsOy1tcy1mbGV4LWRpcmVjdGlvbjpyb3c7ZmxleC1kaXJlY3Rpb246cm93Oy13ZWJraXQtYm94LXBhY2s6ZW5kOy13ZWJraXQtanVzdGlmeS1jb250ZW50OmZsZXgtZW5kOy1tb3otYm94LXBhY2s6ZW5kOy1tcy1mbGV4LXBhY2s6ZW5kO2p1c3RpZnktY29udGVudDpmbGV4LWVuZH15dGQtbWFzdGhlYWQubWFzdGhlYWQtZmluaXNoICNtYXN0aGVhZC1za2VsZXRvbi1pY29uc3tkaXNwbGF5Om5vbmV9Lm1hc3RoZWFkLXNrZWxldG9uLWljb257Ym9yZGVyLXJhZGl1czo1MCU7aGVpZ2h0OjMycHg7d2lkdGg6MzJweDttYXJnaW46MCA4cHg7YmFja2dyb3VuZC1jb2xvcjojZTNlM2UzfXl0ZC1tYXN0aGVhZC5kYXJrIC5tYXN0aGVhZC1za2VsZXRvbi1pY29ue2JhY2tncm91bmQtY29sb3I6IzI5MjkyOX08L3N0eWxlPjxzdHlsZSBjbGFzcz0ibWFzdGhlYWRfY3VzdG9tX3N0eWxlcyIgaXM9ImN1c3RvbS1zdHlsZSIgaWQ9ImV4dC1zdHlsZXMiIG5vbmNlPSJNX0VPQm5WU0F0RXh4RHFiUTRVMkpnIj46LXN0di1zZXQtZWxzZXdoZXJley0teXQtc3BlYy1pY29uLWFjdGl2ZS1vdGhlcjppbml0aWFsfXl0ZC1tYXN0aGVhZCAueXQtaWNvbnMtZXh0e2NvbG9yOnZhcigtLXl0LXNwZWMtaWNvbi1hY3RpdmUtb3RoZXIpfXl0ZC1tYXN0aGVhZCBzdmcjeXQtbG9nby1yZWQtc3ZnICN5b3V0dWJlLXJlZC1wYXRocyBwYXRoLHl0ZC1tYXN0aGVhZCBzdmcjeXQtbG9nby1yZWQtdXBkYXRlZC1zdmcgI3lvdXR1YmUtcmVkLXBhdGhzIHBhdGgseXRkLW1hc3RoZWFkIHN2ZyN5dC1sb2dvLXN2ZyAjeW91dHViZS1wYXRocyBwYXRoLHl0ZC1tYXN0aGVhZCBzdmcjeXQtbG9nby11cGRhdGVkLXN2ZyAjeW91dHViZS1wYXRocyBwYXRoe2ZpbGw6IzI4MjgyOH15dGQtbWFzdGhlYWQuZGFyayBzdmcjeXQtbG9nby1yZWQtc3ZnICN5b3V0dWJlLXJlZC1wYXRocyBwYXRoLHl0ZC1tYXN0aGVhZC5kYXJrIHN2ZyN5dC1sb2dvLXJlZC11cGRhdGVkLXN2ZyAjeW91dHViZS1yZWQtcGF0aHMgcGF0aCx5dGQtbWFzdGhlYWQuZGFyayBzdmcjeXQtbG9nby1zdmcgI3lvdXR1YmUtcGF0aHMgcGF0aCx5dGQtbWFzdGhlYWQuZGFyayBzdmcjeXQtbG9nby11cGRhdGVkLXN2ZyAjeW91dHViZS1wYXRocyBwYXRoLHl0ZC1tYXN0aGVhZC50aGVhdGVyIHN2ZyN5dC1sb2dvLXJlZC1zdmcgI3lvdXR1YmUtcmVkLXBhdGhzIHBhdGgseXRkLW1hc3RoZWFkLnRoZWF0ZXIgc3ZnI3l0LWxvZ28tc3ZnICN5b3V0dWJlLXBhdGhzIHBhdGh7ZmlsbDojZmZmfTwvc3R5bGU+PHN0eWxlIGNsYXNzPSJzZWFyY2hib3giIG5vbmNlPSJNX0VPQm5WU0F0RXh4RHFiUTRVMkpnIj4jc2VhcmNoLWlucHV0Lnl0ZC1zZWFyY2hib3gtc3B0IGlucHV0ey13ZWJraXQtYXBwZWFyYW5jZTpub25lOy13ZWJraXQtZm9udC1zbW9vdGhpbmc6YW50aWFsaWFzZWQ7YmFja2dyb3VuZC1jb2xvcjp0cmFuc3BhcmVudDtib3JkZXI6bm9uZTtib3gtc2hhZG93Om5vbmU7Y29sb3I6aW5oZXJpdDtmb250LWZhbWlseTpSb2JvdG8sTm90byxzYW5zLXNlcmlmO2ZvbnQtc2l6ZToxNnB4O2ZvbnQtd2VpZ2h0OjQwMDtsaW5lLWhlaWdodDoyNHB4O21hcmdpbi1sZWZ0OjRweDttYXgtd2lkdGg6MTAwJTtvdXRsaW5lOm5vbmU7dGV4dC1hbGlnbjppbmhlcml0O3dpZHRoOjEwMCU7LW1zLWZsZXg6MSAxIDAuMDAwMDAwMDAxcHg7LXdlYmtpdC1mbGV4OjE7LXdlYmtpdC1ib3gtZmxleDoxOy1tb3otYm94LWZsZXg6MTtmbGV4OjE7LXdlYmtpdC1mbGV4LWJhc2lzOjAuMDAwMDAwMDAxcHg7LW1zLWZsZXgtcHJlZmVycmVkLXNpemU6MC4wMDAwMDAwMDFweDtmbGV4LWJhc2lzOjAuMDAwMDAwMDAxcHh9I3NlYXJjaC1jb250YWluZXIueXRkLXNlYXJjaGJveC1zcHR7cG9pbnRlci1ldmVudHM6bm9uZTtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtyaWdodDowO2JvdHRvbTowO2xlZnQ6MH0jc2VhcmNoLWlucHV0Lnl0ZC1zZWFyY2hib3gtc3B0ICNzZWFyY2g6Oi13ZWJraXQtaW5wdXQtcGxhY2Vob2xkZXJ7Y29sb3I6Izg4OH0jc2VhcmNoLWlucHV0Lnl0ZC1zZWFyY2hib3gtc3B0ICNzZWFyY2g6Oi1tb3otaW5wdXQtcGxhY2Vob2xkZXJ7Y29sb3I6Izg4OH0jc2VhcmNoLWlucHV0Lnl0ZC1zZWFyY2hib3gtc3B0ICNzZWFyY2g6LW1zLWlucHV0LXBsYWNlaG9sZGVye2NvbG9yOiM4ODh9PC9zdHlsZT48c3R5bGUgY2xhc3M9Imtldmxhcl9nbG9iYWxfc3R5bGVzIiBub25jZT0iTV9FT0JuVlNBdEV4eERxYlE0VTJKZyI+aHRtbHtiYWNrZ3JvdW5kLWNvbG9yOiNmZmYhaW1wb3J0YW50Oy13ZWJraXQtdGV4dC1zaXplLWFkanVzdDpub25lfWh0bWxbZGFya117YmFja2dyb3VuZC1jb2xvcjojMGYwZjBmIWltcG9ydGFudH0jbG9nby1yZWQtaWNvbi1jb250YWluZXIueXRkLXRvcGJhci1sb2dvLXJlbmRlcmVye3dpZHRoOjg2cHh9PC9zdHlsZT48bWV0YSBuYW1lPSJ0aGVtZS1jb2xvciIgY29udGVudD0icmdiYSgyNTUsIDI1NSwgMjU1LCAwLjk4KSI+PGxpbmsgcmVsPSJzZWFyY2giIHR5cGU9ImFwcGxpY2F0aW9uL29wZW5zZWFyY2hkZXNjcmlwdGlvbit4bWwiIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL29wZW5zZWFyY2g/bG9jYWxlPWZyX0ZSIiB0aXRsZT0iWW91VHViZSI+PGxpbmsgcmVsPSJtYW5pZmVzdCIgaHJlZj0iL21hbmlmZXN0LndlYm1hbmlmZXN0IiBjcm9zc29yaWdpbj0idXNlLWNyZWRlbnRpYWxzIj48L2hlYWQ+PGJvZHkgZGlyPSJsdHIiPjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnYnMnLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPnl0Y2ZnLnNldCgnaW5pdGlhbEJvZHlDbGllbnRXaWR0aCcsIGRvY3VtZW50LmJvZHkuY2xpZW50V2lkdGgpOzwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnYWknLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxpZnJhbWUgbmFtZT0icGFzc2l2ZV9zaWduaW4iIHNyYz0iaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tL1NlcnZpY2VMb2dpbj9zZXJ2aWNlPXlvdXR1YmUmYW1wO3VpbGVsPTMmYW1wO3Bhc3NpdmU9dHJ1ZSZhbXA7Y29udGludWU9aHR0cHMlM0ElMkYlMkZ3d3cueW91dHViZS5jb20lMkZzaWduaW4lM0ZhY3Rpb25faGFuZGxlX3NpZ25pbiUzRHRydWUlMjZhcHAlM0RkZXNrdG9wJTI2aGwlM0RmciUyNm5leHQlM0QlMjUyRnNpZ25pbl9wYXNzaXZlJTI2ZmVhdHVyZSUzRHBhc3NpdmUmYW1wO2hsPWZyIiBzdHlsZT0iZGlzcGxheTogbm9uZSI+PC9pZnJhbWU+PHl0ZC1hcHA+PHl0ZC1tYXN0aGVhZCBpZD0ibWFzdGhlYWQiIGxvZ28tdHlwZT0iWU9VVFVCRV9MT0dPIiBzbG90PSJtYXN0aGVhZCIgY2xhc3M9InNoZWxsICI+PGRpdiBpZD0ic2VhcmNoLWNvbnRhaW5lciIgY2xhc3M9Inl0ZC1zZWFyY2hib3gtc3B0IiBzbG90PSJzZWFyY2gtY29udGFpbmVyIj48L2Rpdj48ZGl2IGlkPSJzZWFyY2gtaW5wdXQiIGNsYXNzPSJ5dGQtc2VhcmNoYm94LXNwdCIgc2xvdD0ic2VhcmNoLWlucHV0Ij48aW5wdXQgaWQ9InNlYXJjaCIgYXV0b2NhcGl0YWxpemU9Im5vbmUiIGF1dG9jb21wbGV0ZT0ib2ZmIiBhdXRvY29ycmVjdD0ib2ZmIiBoaWRkZW4gbmFtZT0ic2VhcmNoX3F1ZXJ5IiB0YWJpbmRleD0iMCIgdHlwZT0idGV4dCIgc3BlbGxjaGVjaz0iZmFsc2UiPjwvZGl2PjxzdmcgaWQ9Im1lbnUtaWNvbiIgY2xhc3M9ImV4dGVybmFsLWljb24iIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiPjxnIGlkPSJtZW51IiBjbGFzcz0ieXQtaWNvbnMtZXh0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik0yMSw2SDNWNWgxOFY2eiBNMjEsMTFIM3YxaDE4VjExeiBNMjEsMTdIM3YxaDE4VjE3eiIvPjwvZz48L3N2Zz48ZGl2IGlkPSJtYXN0aGVhZC1sb2dvIiBzbG90PSJtYXN0aGVhZC1sb2dvIj48YSBzdHlsZT0iZGlzcGxheTogbm9uZTsiIGhyZWY9Ii8iIHRpdGxlPSJZb3VUdWJlIj48c3ZnIGlkPSJ5dC1sb2dvLXVwZGF0ZWQtc3ZnIiBjbGFzcz0iZXh0ZXJuYWwtaWNvbiIgdmlld0JveD0iMCAwIDkwIDIwIj48ZyBpZD0ieXQtbG9nby11cGRhdGVkIiB2aWV3Qm94PSIwIDAgOTAgMjAiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiPjxnPjxwYXRoIGQ9Ik0yNy45NzI3IDMuMTIzMjRDMjcuNjQzNSAxLjg5MzIzIDI2LjY3NjggMC45MjY2MjMgMjUuNDQ2OCAwLjU5NzM2NkMyMy4yMTk3IDIuMjQyODhlLTA3IDE0LjI4NSAwIDE0LjI4NSAwQzE0LjI4NSAwIDUuMzUwNDIgMi4yNDI4OGUtMDcgMy4xMjMyMyAwLjU5NzM2NkMxLjg5MzIzIDAuOTI2NjIzIDAuOTI2NjIzIDEuODkzMjMgMC41OTczNjYgMy4xMjMyNEMyLjI0Mjg4ZS0wNyA1LjM1MDQyIDAgMTAgMCAxMEMwIDEwIDIuMjQyODhlLTA3IDE0LjY0OTYgMC41OTczNjYgMTYuODc2OEMwLjkyNjYyMyAxOC4xMDY4IDEuODkzMjMgMTkuMDczNCAzLjEyMzIzIDE5LjQwMjZDNS4zNTA0MiAyMCAxNC4yODUgMjAgMTQuMjg1IDIwQzE0LjI4NSAyMCAyMy4yMTk3IDIwIDI1LjQ0NjggMTkuNDAyNkMyNi42NzY4IDE5LjA3MzQgMjcuNjQzNSAxOC4xMDY4IDI3Ljk3MjcgMTYuODc2OEMyOC41NzAxIDE0LjY0OTYgMjguNTcwMSAxMCAyOC41NzAxIDEwQzI4LjU3MDEgMTAgMjguNTY3NyA1LjM1MDQyIDI3Ljk3MjcgMy4xMjMyNFoiIGZpbGw9IiNGRjAwMDAiLz48cGF0aCBkPSJNMTEuNDI1MyAxNC4yODU0TDE4Ljg0NzcgMTAuMDAwNEwxMS40MjUzIDUuNzE1MzNWMTQuMjg1NFoiIGZpbGw9IndoaXRlIi8+PC9nPjxnPjxnIGlkPSJ5b3V0dWJlLXBhdGhzIj48cGF0aCBkPSJNMzQuNjAyNCAxMy4wMDM2TDMxLjM5NDUgMS40MTg0NkgzNC4xOTMyTDM1LjMxNzQgNi42NzAxQzM1LjYwNDMgNy45NjM2MSAzNS44MTM2IDkuMDY2NjIgMzUuOTUgOS45NzkxM0gzNi4wMzIzQzM2LjEyNjQgOS4zMjUzMiAzNi4zMzgxIDguMjI5MzcgMzYuNjY1IDYuNjg4OTJMMzcuODI5MSAxLjQxODQ2SDQwLjYyNzhMMzcuMzc5OSAxMy4wMDM2VjE4LjU2MUgzNC42MDAxVjEzLjAwMzZIMzQuNjAyNFoiLz48cGF0aCBkPSJNNDEuNDY5NyAxOC4xOTM3QzQwLjkwNTMgMTcuODEyNyA0MC41MDMxIDE3LjIyIDQwLjI2MzIgMTYuNDE1N0M0MC4wMjU3IDE1LjYxMTQgMzkuOTA1OCAxNC41NDM3IDM5LjkwNTggMTMuMjA3OFYxMS4zODk4QzM5LjkwNTggMTAuMDQyMiA0MC4wNDIyIDguOTU4MDUgNDAuMzE1IDguMTQxOTZDNDAuNTg3OCA3LjMyNTg4IDQxLjAxMzUgNi43Mjg1MSA0MS41OTIgNi4zNTQ1N0M0Mi4xNzA2IDUuOTgwNjMgNDIuOTMwMiA1Ljc5MjQ4IDQzLjg3MSA1Ljc5MjQ4QzQ0Ljc5NzYgNS43OTI0OCA0NS41Mzg0IDUuOTgyOTggNDYuMDk4MSA2LjM2Mzk4QzQ2LjY1NTUgNi43NDQ5NyA0Ny4wNjQ3IDcuMzQyMzQgNDcuMzIzNCA4LjE1MTM3QzQ3LjU4MjEgOC45NjI3NSA0Ny43MTE1IDEwLjA0MjIgNDcuNzExNSAxMS4zODk4VjEzLjIwNzhDNDcuNzExNSAxNC41NDM3IDQ3LjU4NDUgMTUuNjE2MSA0Ny4zMzI5IDE2LjQyNTFDNDcuMDgxMiAxNy4yMzY1IDQ2LjY3MiAxNy44MjkyIDQ2LjEwNzUgMTguMjAzMUM0NS41NDMxIDE4LjU3NzEgNDQuNzc2NCAxOC43NjUyIDQzLjgwOTggMTguNzY1MkM0Mi44MTI2IDE4Ljc2NzUgNDIuMDM0MiAxOC41NzQ3IDQxLjQ2OTcgMTguMTkzN1pNNDQuNjM1MyAxNi4yMzIzQzQ0Ljc5MDUgMTUuODIzMSA0NC44NzA1IDE1LjE1NzUgNDQuODcwNSAxNC4yMzA5VjEwLjMyOTJDNDQuODcwNSA5LjQzMDc3IDQ0Ljc5MjkgOC43NzIyNSA0NC42MzUzIDguMzU4MzNDNDQuNDc3NyA3Ljk0MjA2IDQ0LjIwMjYgNy43MzUxIDQzLjgwNzQgNy43MzUxQzQzLjQyNjUgNy43MzUxIDQzLjE1NiA3Ljk0MjA2IDQzLjAwMDggOC4zNTgzM0M0Mi44NDMyIDguNzc0NjEgNDIuNzY1NiA5LjQzMDc3IDQyLjc2NTYgMTAuMzI5MlYxNC4yMzA5QzQyLjc2NTYgMTUuMTU3NSA0Mi44NDA4IDE1LjgyNTQgNDIuOTkxNCAxNi4yMzIzQzQzLjE0MTkgMTYuNjQxNSA0My40MTIzIDE2Ljg0NjEgNDMuODA3NCAxNi44NDYxQzQ0LjIwMjYgMTYuODQ2MSA0NC40Nzc3IDE2LjY0MTUgNDQuNjM1MyAxNi4yMzIzWiIvPjxwYXRoIGQ9Ik01Ni44MTU0IDE4LjU2MzRINTQuNjA5NEw1NC4zNjQ4IDE3LjAzSDU0LjMwMzdDNTMuNzAzOSAxOC4xODcxIDUyLjgwNTUgMTguNzY1NiA1MS42MDYxIDE4Ljc2NTZDNTAuNzc1OSAxOC43NjU2IDUwLjE2MjEgMTguNDkyOCA0OS43NjcgMTcuOTQ5NkM0OS4zNzE5IDE3LjQwMzkgNDkuMTc0MyAxNi41NTI2IDQ5LjE3NDMgMTUuMzk1NVY2LjAzNzUxSDUxLjk5NDJWMTUuMjMwOEM1MS45OTQyIDE1Ljc5MDYgNTIuMDU1MyAxNi4xODggNTIuMTc3NiAxNi40MjU2QzUyLjI5OTkgMTYuNjYzMSA1Mi41MDQ1IDE2Ljc4MyA1Mi43OTE0IDE2Ljc4M0M1My4wMzYgMTYuNzgzIDUzLjI3MTIgMTYuNzA3OCA1My40OTcgMTYuNTU3M0M1My43MjI4IDE2LjQwNjcgNTMuODg3NCAxNi4yMTYyIDUzLjk5NzkgMTUuOTg1OFY2LjAzNTE2SDU2LjgxNTRWMTguNTYzNFoiLz48cGF0aCBkPSJNNjQuNDc1NSAzLjY4NzU4SDYxLjY3NjhWMTguNTYyOUg1OC45MTgxVjMuNjg3NThINTYuMTE5NFYxLjQyMDQxSDY0LjQ3NTVWMy42ODc1OFoiLz48cGF0aCBkPSJNNzEuMjc2OCAxOC41NjM0SDY5LjA3MDhMNjguODI2MiAxNy4wM0g2OC43NjUxQzY4LjE2NTQgMTguMTg3MSA2Ny4yNjcgMTguNzY1NiA2Ni4wNjc1IDE4Ljc2NTZDNjUuMjM3MyAxOC43NjU2IDY0LjYyMzUgMTguNDkyOCA2NC4yMjg0IDE3Ljk0OTZDNjMuODMzMyAxNy40MDM5IDYzLjYzNTcgMTYuNTUyNiA2My42MzU3IDE1LjM5NTVWNi4wMzc1MUg2Ni40NTU2VjE1LjIzMDhDNjYuNDU1NiAxNS43OTA2IDY2LjUxNjcgMTYuMTg4IDY2LjYzOSAxNi40MjU2QzY2Ljc2MTMgMTYuNjYzMSA2Ni45NjU5IDE2Ljc4MyA2Ny4yNTI5IDE2Ljc4M0M2Ny40OTc0IDE2Ljc4MyA2Ny43MzI2IDE2LjcwNzggNjcuOTU4NCAxNi41NTczQzY4LjE4NDIgMTYuNDA2NyA2OC4zNDg4IDE2LjIxNjIgNjguNDU5MyAxNS45ODU4VjYuMDM1MTZINzEuMjc2OFYxOC41NjM0WiIvPjxwYXRoIGQ9Ik04MC42MDkgOC4wMzg3QzgwLjQzNzMgNy4yNDg0OSA4MC4xNjIxIDYuNjc2OTkgNzkuNzgxMiA2LjMyMTg2Qzc5LjQwMDIgNS45NjY3NCA3OC44NzU3IDUuNzkwMzUgNzguMjA3OCA1Ljc5MDM1Qzc3LjY5MDQgNS43OTAzNSA3Ny4yMDU5IDUuOTM2MTYgNzYuNzU2NyA2LjIzMDE0Qzc2LjMwNzUgNi41MjQxMiA3NS45NTk0IDYuOTA3NDcgNzUuNzE0OCA3LjM4NDg5SDc1LjY5MzdWMC43ODU2NDVINzIuOTc3M1YxOC41NjA4SDc1LjMwNTZMNzUuNTkyNSAxNy4zNzU1SDc1LjY1MzdDNzUuODcyNCAxNy43OTg4IDc2LjE5OTMgMTguMTMwNCA3Ni42MzQ0IDE4LjM3NzRDNzcuMDY5NSAxOC42MjIgNzcuNTU0IDE4Ljc0NDMgNzguMDg1NSAxOC43NDQzQzc5LjAzOCAxOC43NDQzIDc5Ljc0MTIgMTguMzA0NSA4MC4xOTA0IDE3LjQyNzJDODAuNjM5NiAxNi41NDc2IDgwLjg2NTMgMTUuMTc2NSA4MC44NjUzIDEzLjMwOTJWMTEuMzI2NkM4MC44NjUzIDkuOTI3MjIgODAuNzc4MyA4LjgyODkyIDgwLjYwOSA4LjAzODdaTTc4LjAyNDMgMTMuMTQ5MkM3OC4wMjQzIDE0LjA2MTcgNzcuOTg2NyAxNC43NzY3IDc3LjkxMTQgMTUuMjk0MUM3Ny44MzYyIDE1LjgxMTUgNzcuNzExNSAxNi4xODA4IDc3LjUzMjggMTYuMzk3MUM3Ny4zNTY0IDE2LjYxNTggNzcuMTE2NSAxNi43MjQgNzYuODE3OCAxNi43MjRDNzYuNTg1IDE2LjcyNCA3Ni4zNzEgMTYuNjY5OSA3Ni4xNzM0IDE2LjU1OTRDNzUuOTc1OSAxNi40NTEyIDc1LjgxNiAxNi4yODY2IDc1LjY5MzcgMTYuMDcwMlY4Ljk2MDYyQzc1Ljc4NzcgOC42MTk2IDc1Ljk1MjQgOC4zNDIwOSA3Ni4xODUyIDguMTIzMzdDNzYuNDE1NyA3LjkwNDY1IDc2LjY2OTcgNy43OTY0NiA3Ni45NDAxIDcuNzk2NDZDNzcuMjI3MSA3Ljc5NjQ2IDc3LjQ0ODEgNy45MDkzNSA3Ny42MDM0IDguMTMyNzhDNzcuNzYwOSA4LjM1ODU1IDc3Ljg2OTEgOC43MzQ4NSA3Ny45MzAzIDkuMjY2MzZDNzcuOTkxNCA5Ljc5Nzg3IDc4LjAyMiAxMC41NTI4IDc4LjAyMiAxMS41MzM1VjEzLjE0OTJINzguMDI0M1oiLz48cGF0aCBkPSJNODQuODY1NyAxMy44NzEyQzg0Ljg2NTcgMTQuNjc1NSA4NC44ODkyIDE1LjI3NzYgODQuOTM2MyAxNS42Nzk4Qzg0Ljk4MzMgMTYuMDgxOSA4NS4wODIxIDE2LjM3MzYgODUuMjMyNiAxNi41NTk0Qzg1LjM4MzEgMTYuNzQyOCA4NS42MTM2IDE2LjgzNDUgODUuOTI2NCAxNi44MzQ1Qzg2LjM0NzQgMTYuODM0NSA4Ni42MzkgMTYuNjY5OSA4Ni43OTQyIDE2LjM0M0M4Ni45NTE4IDE2LjAxNjEgODcuMDM2NSAxNS40NzA1IDg3LjA1MDYgMTQuNzA4NUw4OS40ODI0IDE0Ljg1MTlDODkuNDk2NSAxNC45NjAxIDg5LjUwMzUgMTUuMTEwNiA4OS41MDM1IDE1LjMwMTFDODkuNTAzNSAxNi40NTgyIDg5LjE4NiAxNy4zMjM3IDg4LjU1MzQgMTcuODk1MkM4Ny45MjA4IDE4LjQ2NjcgODcuMDI0NyAxOC43NTM2IDg1Ljg2NzYgMTguNzUzNkM4NC40Nzc3IDE4Ljc1MzYgODMuNTA0IDE4LjMxODUgODIuOTQ2NiAxNy40NDZDODIuMzg2OSAxNi41NzM1IDgyLjEwOTQgMTUuMjI1OSA4Mi4xMDk0IDEzLjQwMDhWMTEuMjEzNkM4Mi4xMDk0IDkuMzM0NTIgODIuMzk4NyA3Ljk2MTA1IDgyLjk3NzIgNy4wOTU1OEM4My41NTU4IDYuMjMwMSA4NC41NDU5IDUuNzk3MzYgODUuOTQ5OSA1Ljc5NzM2Qzg2LjkxNjUgNS43OTczNiA4Ny42NTk3IDUuOTczNzUgODguMTc3MSA2LjMyODg4Qzg4LjY5NDUgNi42ODQgODkuMDU5IDcuMjM0MzMgODkuMjcwNyA3Ljk4NDU3Qzg5LjQ4MjQgOC43MzQ4IDg5LjU4ODIgOS43Njk2MSA4OS41ODgyIDExLjA5MTNWMTMuMjM2Mkg4NC44NjU3VjEzLjg3MTJaTTg1LjIyMzIgNy45NjgxMUM4NS4wNzk3IDguMTQ0NDkgODQuOTg1NyA4LjQzMzc3IDg0LjkzNjMgOC44MzU5M0M4NC44ODkyIDkuMjM4MSA4NC44NjU3IDkuODQ3MjIgODQuODY1NyAxMC42NjU3VjExLjU2NDFIODYuOTI4M1YxMC42NjU3Qzg2LjkyODMgOS44NjEzMyA4Ni45MDAxIDkuMjUyMjEgODYuODQ2IDguODM1OTNDODYuNzkxOSA4LjQxOTY2IDg2LjY5MzEgOC4xMjgwMyA4Ni41NDk2IDcuOTU2MzVDODYuNDA2MiA3Ljc4NzAyIDg2LjE4NTEgNy43IDg1Ljg4NjQgNy43Qzg1LjU4NTQgNy43MDIzNSA4NS4zNjQzIDcuNzkxNzIgODUuMjIzMiA3Ljk2ODExWiIvPjwvZz48L2c+PC9nPjwvc3ZnPjwvYT48YSBzdHlsZT0iZGlzcGxheTogbm9uZTsiIGhyZWY9Ii8iIHRpdGxlPSJZb3VUdWJlIj48c3ZnIGlkPSJ5dC1sb2dvLXJlZC11cGRhdGVkLXN2ZyIgY2xhc3M9ImV4dGVybmFsLWljb24iIHZpZXdCb3g9IjAgMCA5NyAyMCIgc3R5bGU9IndpZHRoOiA5N3B4OyI+PGcgaWQ9Inl0LWxvZ28tcmVkLXVwZGF0ZWQiIHZpZXdCb3g9IjAgMCA5NyAyMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQgbWVldCI+PGc+PHBhdGggZD0iTTI3Ljk3MDQgMy4xMjMyNEMyNy42NDExIDEuODkzMjMgMjYuNjc0NSAwLjkyNjYyMyAyNS40NDQ1IDAuNTk3MzY2QzIzLjIxNzMgMi4yNDI4OGUtMDcgMTQuMjgyNyAwIDE0LjI4MjcgMEMxNC4yODI3IDAgNS4zNDgwNyAyLjI0Mjg4ZS0wNyAzLjEyMDg4IDAuNTk3MzY2QzEuODkzMjMgMC45MjY2MjMgMC45MjQyNzEgMS44OTMyMyAwLjU5NTAxNCAzLjEyMzI0Qy0yLjgwMzZlLTA3IDUuMzUwNDIgMCAxMCAwIDEwQzAgMTAgLTEuNTcwMDJlLTA2IDE0LjY0OTYgMC41OTczNjQgMTYuODc2OEMwLjkyNjYyMSAxOC4xMDY4IDEuODkzMjMgMTkuMDczNCAzLjEyMzI0IDE5LjQwMjZDNS4zNTA0MiAyMCAxNC4yODUgMjAgMTQuMjg1IDIwQzE0LjI4NSAyMCAyMy4yMTk3IDIwIDI1LjQ0NjggMTkuNDAyNkMyNi42NzY5IDE5LjA3MzQgMjcuNjQzNSAxOC4xMDY4IDI3Ljk3MjcgMTYuODc2OEMyOC41NzAxIDE0LjY0OTYgMjguNTcwMSAxMCAyOC41NzAxIDEwQzI4LjU3MDEgMTAgMjguNTY3NyA1LjM1MDQyIDI3Ljk3MDQgMy4xMjMyNFoiIGZpbGw9IiNGRjAwMDAiLz48cGF0aCBkPSJNMTEuNDI3NSAxNC4yODU0TDE4Ljg0NzUgMTAuMDAwNEwxMS40Mjc1IDUuNzE1MzNWMTQuMjg1NFoiIGZpbGw9IndoaXRlIi8+PC9nPjxnIGlkPSJ5b3V0dWJlLXJlZC1wYXRocyI+PHBhdGggZD0iTTQwLjA1NjYgNi4zNDUyNFY3LjAzNjY4QzQwLjA1NjYgMTAuNDkxNSAzOC41MjU1IDEyLjUxMTggMzUuMTc0MiAxMi41MTE4SDM0LjY2MzhWMTguNTU4M0gzMS45MjYzVjEuNDIyODVIMzUuNDE0QzM4LjYwNzggMS40MjI4NSA0MC4wNTY2IDIuNzcyOCA0MC4wNTY2IDYuMzQ1MjRaTTM3LjE3NzkgNi41OTIxOEMzNy4xNzc5IDQuMDk5MjQgMzYuNzI4NyAzLjUwNjU4IDM1LjE3NjUgMy41MDY1OEgzNC42NjYyVjEwLjQ3MjdIMzUuMTM2NUMzNi42MDY0IDEwLjQ3MjcgMzcuMTgwMyA5LjQwOTY4IDM3LjE4MDMgNy4xMDI1M0wzNy4xNzc5IDYuNTkyMThaIi8+PHBhdGggZD0iTTQ2LjUzMzYgNS44MzQ1TDQ2LjM5MDEgOS4wODIzOEM0NS4yMjU5IDguODM3NzkgNDQuMjY0IDkuMDIxMjMgNDMuODM2IDkuNzczODJWMTguNTU3OUg0MS4xMTk2VjYuMDM5MUg0My4yODU3TDQzLjUzMDMgOC43NTMxMkg0My42MzM3QzQzLjkxODMgNi43NzI4OCA0NC44Mzc5IDUuNzcxIDQ2LjAyMzIgNS43NzFDNDYuMTk0OSA1Ljc3NTcgNDYuMzY2NiA1Ljc5Njg3IDQ2LjUzMzYgNS44MzQ1WiIvPjxwYXRoIGQ9Ik00OS42NTY3IDEzLjI0NTZWMTMuODc4MkM0OS42NTY3IDE2LjA4NDIgNDkuNzc5IDE2Ljg0MTUgNTAuNzE5OCAxNi44NDE1QzUxLjYxODIgMTYuODQxNSA1MS44MjI4IDE2LjE1MDEgNTEuODQzOSAxNC43MTc4TDU0LjI3MzQgMTQuODYxM0M1NC40NTY4IDE3LjU1NjUgNTMuMDQ4MSAxOC43NjMgNTAuNjU4NiAxOC43NjNDNDcuNzU4OCAxOC43NjMgNDYuOTAwNCAxNi44NjI3IDQ2LjkwMDQgMTMuNDEyNlYxMS4yMjNDNDYuOTAwNCA3LjU4NzA3IDQ3Ljg1OTkgNS44MDkwOCA1MC43NDA5IDUuODA5MDhDNTMuNjQwNyA1LjgwOTA4IDU0LjM3NjkgNy4zMjEzMSA1NC4zNzY5IDExLjA5ODRWMTMuMjQ1Nkg0OS42NTY3Wk00OS42NTY3IDEwLjY3MDNWMTEuNTY4N0g1MS43MTkzVjEwLjY3NUM1MS43MTkzIDguMzcyNTggNTEuNTU0NyA3LjcxMTcyIDUwLjY4MjEgNy43MTE3MkM0OS44MDk2IDcuNzExNzIgNDkuNjU2NyA4LjM4NjY5IDQ5LjY1NjcgMTAuNjc1VjEwLjY3MDNaIi8+PHBhdGggZD0iTTY4LjQxMDMgOS4wOTkwMlYxOC41NTU3SDY1LjU5MjhWOS4zMDgzNEM2NS41OTI4IDguMjg3NjQgNjUuMzI3IDcuNzc3MjkgNjQuNzEzMiA3Ljc3NzI5QzY0LjIyMTYgNy43NzcyOSA2My43NzI0IDguMDYxODYgNjMuNDY2NyA4LjU5MzM4QzYzLjQ4MzIgOC43NjI3MSA2My40OTAyIDguOTM0MzkgNjMuNDg3OSA5LjEwMzczVjE4LjU2MDVINjAuNjY4VjkuMzA4MzRDNjAuNjY4IDguMjg3NjQgNjAuNDAyMiA3Ljc3NzI5IDU5Ljc4ODQgNy43NzcyOUM1OS4yOTY5IDcuNzc3MjkgNTguODY2NSA4LjA2MTg2IDU4LjU2MzEgOC41NzQ1NlYxOC41NjI4SDU1Ljc0NTZWNi4wMzkyOUg1Ny45NzI4TDU4LjIyMjEgNy42MzM4M0g1OC4yNjIxQzU4Ljg5NDcgNi40Mjk2OSA1OS45MTc4IDUuNzc1ODggNjEuMTIxOSA1Ljc3NTg4QzYyLjMwNzIgNS43NzU4OCA2Mi45Nzk5IDYuMzY4NTQgNjMuMjg4IDcuNDMxNTdDNjMuOTQxOCA2LjM0OTczIDY0LjkyMjUgNS43NzU4OCA2Ni4wNDQzIDUuNzc1ODhDNjcuNzU2NCA1Ljc3NTg4IDY4LjQxMDMgNy4wMDExOSA2OC40MTAzIDkuMDk5MDJaIi8+PHBhdGggZD0iTTY5LjgxOTEgMi44MzM4QzY5LjgxOTEgMS40ODYyIDcwLjMxMDYgMS4wOTgxNCA3MS4zNTAxIDEuMDk4MTRDNzIuNDEzMiAxLjA5ODE0IDcyLjg4MTIgMS41NDczNCA3Mi44ODEyIDIuODMzOEM3Mi44ODEyIDQuMjIzNzMgNzIuNDEwOCA0LjU3MTgxIDcxLjM1MDEgNC41NzE4MUM3MC4zMTA2IDQuNTY5NDUgNjkuODE5MSA0LjIyMTM4IDY5LjgxOTEgMi44MzM4Wk02OS45ODM3IDYuMDM5MzVINzIuNjc4OVYxOC41NjI5SDY5Ljk4MzdWNi4wMzkzNVoiLz48cGF0aCBkPSJNODEuODkxIDYuMDM5NTVWMTguNTYzMUg3OS42ODQ5TDc5LjQ0MDMgMTcuMDMySDc5LjM3OTJDNzguNzQ2NiAxOC4yNTczIDc3LjgyNyAxOC43Njc3IDc2LjY4NCAxOC43Njc3Qzc1LjAwOTUgMTguNzY3NyA3NC4yNTIyIDE3LjcwNDYgNzQuMjUyMiAxNS4zOTc1VjYuMDQxOUg3Ny4wNjk3VjE1LjIzNTJDNzcuMDY5NyAxNi4zMzgyIDc3LjMwMDIgMTYuNzg3NCA3Ny44NjcgMTYuNzg3NEM3OC4zODQ0IDE2Ljc2NjMgNzguODQ3NyAxNi40NTgyIDc5LjA2ODggMTUuOTkwMlY2LjA0MTlIODEuODkxVjYuMDM5NTVaIi8+PHBhdGggZD0iTTk2LjE5MDEgOS4wOTg5M1YxOC41NTU3SDkzLjM3MjZWOS4zMDgyNUM5My4zNzI2IDguMjg3NTUgOTMuMTA2OCA3Ljc3NzIgOTIuNDkzIDcuNzc3MkM5Mi4wMDE1IDcuNzc3MiA5MS41NTIzIDguMDYxNzcgOTEuMjQ2NSA4LjU5MzI5QzkxLjI2MyA4Ljc2MDI3IDkxLjI3MDEgOC45Mjk2IDkxLjI2NzcgOS4wOTg5M1YxOC41NTU3SDg4LjQ1MDJWOS4zMDgyNUM4OC40NTAyIDguMjg3NTUgODguMTg0NSA3Ljc3NzIgODcuNTcwNiA3Ljc3NzJDODcuMDc5MSA3Ljc3NzIgODYuNjQ4NyA4LjA2MTc3IDg2LjM0NTMgOC41NzQ0N1YxOC41NjI3SDgzLjUyNzhWNi4wMzkySDg1Ljc1MjdMODUuOTk3MyA3LjYzMTM5SDg2LjAzNzJDODYuNjY5OSA2LjQyNzI1IDg3LjY5MjkgNS43NzM0NCA4OC44OTcxIDUuNzczNDRDOTAuMDgyNCA1Ljc3MzQ0IDkwLjc1NSA2LjM2NjEgOTEuMDYzMSA3LjQyOTEzQzkxLjcxNjkgNi4zNDcyOSA5Mi42OTc2IDUuNzczNDQgOTMuODE5NCA1Ljc3MzQ0Qzk1LjU0MSA1Ljc3NTc5IDk2LjE5MDEgNy4wMDExIDk2LjE5MDEgOS4wOTg5M1oiLz48cGF0aCBkPSJNNDAuMDU2NiA2LjM0NTI0VjcuMDM2NjhDNDAuMDU2NiAxMC40OTE1IDM4LjUyNTUgMTIuNTExOCAzNS4xNzQyIDEyLjUxMThIMzQuNjYzOFYxOC41NTgzSDMxLjkyNjNWMS40MjI4NUgzNS40MTRDMzguNjA3OCAxLjQyMjg1IDQwLjA1NjYgMi43NzI4IDQwLjA1NjYgNi4zNDUyNFpNMzcuMTc3OSA2LjU5MjE4QzM3LjE3NzkgNC4wOTkyNCAzNi43Mjg3IDMuNTA2NTggMzUuMTc2NSAzLjUwNjU4SDM0LjY2NjJWMTAuNDcyN0gzNS4xMzY1QzM2LjYwNjQgMTAuNDcyNyAzNy4xODAzIDkuNDA5NjggMzcuMTgwMyA3LjEwMjUzTDM3LjE3NzkgNi41OTIxOFoiLz48L2c+PC9nPjwvc3ZnPjwvYT48c3BhbiBpZD0iY291bnRyeS1jb2RlIj48L3NwYW4+PC9kaXY+PGRpdiBpZD0ibWFzdGhlYWQtc2tlbGV0b24taWNvbnMiIHNsb3Q9Im1hc3RoZWFkLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJtYXN0aGVhZC1za2VsZXRvbi1pY29uIj48L2Rpdj48ZGl2IGNsYXNzPSJtYXN0aGVhZC1za2VsZXRvbi1pY29uIj48L2Rpdj48ZGl2IGNsYXNzPSJtYXN0aGVhZC1za2VsZXRvbi1pY29uIj48L2Rpdj48ZGl2IGNsYXNzPSJtYXN0aGVhZC1za2VsZXRvbi1pY29uIj48L2Rpdj48L2Rpdj48L3l0ZC1tYXN0aGVhZD48YSBzbG90PSJndWlkZS1saW5rcy1wcmltYXJ5IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9hYm91dC8iIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+UHLDqXNlbnRhdGlvbjwvYT48YSBzbG90PSJndWlkZS1saW5rcy1wcmltYXJ5IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9hYm91dC9wcmVzcy8iIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+UHJlc3NlPC9hPjxhIHNsb3Q9Imd1aWRlLWxpbmtzLXByaW1hcnkiIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2Fib3V0L2NvcHlyaWdodC8iIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+RHJvaXRzIGQmIzM5O2F1dGV1cjwvYT48YSBzbG90PSJndWlkZS1saW5rcy1wcmltYXJ5IiBocmVmPSIvdC9jb250YWN0X3VzLyIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij5Ob3VzIGNvbnRhY3RlcjwvYT48YSBzbG90PSJndWlkZS1saW5rcy1wcmltYXJ5IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jcmVhdG9ycy8iIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+Q3LDqWF0ZXVyczwvYT48YSBzbG90PSJndWlkZS1saW5rcy1wcmltYXJ5IiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9hZHMvIiBzdHlsZT0iZGlzcGxheTogbm9uZTsiPlB1YmxpY2l0w6k8L2E+PGEgc2xvdD0iZ3VpZGUtbGlua3MtcHJpbWFyeSIgaHJlZj0iaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20veW91dHViZSIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij5Ew6l2ZWxvcHBldXJzPC9hPjxhIHNsb3Q9Imd1aWRlLWxpbmtzLXByaW1hcnkiIGhyZWY9Imh0dHBzOi8vc3VwcG9ydC5nb29nbGUuY29tL3lvdXR1YmUvY29udGFjdC9GUl9Db21wbGFpbnRzIiBzdHlsZT0iZGlzcGxheTogbm9uZTsiPlNpZ25hbGV6IHVuIGNvbnRlbnUgaGFpbmV1eCBjb25mb3Jtw6ltZW50IMOgIGxhIExDRU48L2E+PGEgc2xvdD0iZ3VpZGUtbGlua3Mtc2Vjb25kYXJ5IiBocmVmPSIvdC90ZXJtcyIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij5Db25kaXRpb25zIGQmIzM5O3V0aWxpc2F0aW9uPC9hPjxhIHNsb3Q9Imd1aWRlLWxpbmtzLXNlY29uZGFyeSIgaHJlZj0iL3QvcHJpdmFjeSIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij5Db25maWRlbnRpYWxpdMOpPC9hPjxhIHNsb3Q9Imd1aWRlLWxpbmtzLXNlY29uZGFyeSIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vYWJvdXQvcG9saWNpZXMvIiBzdHlsZT0iZGlzcGxheTogbm9uZTsiPlLDqGdsZXMgZXQgc8OpY3VyaXTDqTwvYT48YSBzbG90PSJndWlkZS1saW5rcy1zZWNvbmRhcnkiIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2hvd3lvdXR1YmV3b3Jrcz91dG1fY2FtcGFpZ249eXRnZW4mYW1wO3V0bV9zb3VyY2U9eXRocCZhbXA7dXRtX21lZGl1bT1MZWZ0TmF2JmFtcDt1dG1fY29udGVudD10eHQmYW1wO3U9aHR0cHMlM0ElMkYlMkZ3d3cueW91dHViZS5jb20lMkZob3d5b3V0dWJld29ya3MlM0Z1dG1fc291cmNlJTNEeXRocCUyNnV0bV9tZWRpdW0lM0RMZWZ0TmF2JTI2dXRtX2NhbXBhaWduJTNEeXRnZW4iIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+UHJlbWllcnMgcGFzIHN1ciBZb3VUdWJlPC9hPjxhIHNsb3Q9Imd1aWRlLWxpbmtzLXNlY29uZGFyeSIgaHJlZj0iL25ldyIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij5UZXN0ZXIgZGUgbm91dmVsbGVzIGZvbmN0aW9ubmFsaXTDqXM8L2E+PGRpdiBpZD0iY29weXJpZ2h0IiBzbG90PSJjb3B5cmlnaHQiIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+PGRpdiBkaXI9Imx0ciIgc3R5bGU9ImRpc3BsYXk6aW5saW5lIj4mY29weTsgMjAyMyBHb29nbGUgTExDPC9kaXY+PC9kaXY+PC95dGQtYXBwPjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnbmNfcGonLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygncnNiZV9kcGonLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnanNfbGQnLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgaWQ9ImJhc2UtanMiIHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vcy9kZXNrdG9wLzM3NGZhYWQ1L2pzYmluL2Rlc2t0b3BfcG9seW1lcl9lbmFibGVfd2lsX2ljb25zLnZmbHNldC9kZXNrdG9wX3BvbHltZXJfZW5hYmxlX3dpbF9pY29ucy5qcyIgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPjwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygncnNlZl9kcGonLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygncnNhZV9kcGonLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygnanNfcicsIG51bGwsICcnKTt9PC9zY3JpcHQ+PHNjcmlwdCBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+aWYgKHdpbmRvdy55dGNzaSkge3dpbmRvdy55dGNzaS50aWNrKCdhYycsIG51bGwsICcnKTt9PC9zY3JpcHQ+PHNjcmlwdCBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+dmFyIG9uUG9seW1lclJlYWR5ID0gZnVuY3Rpb24oZSkge3dpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JpcHQtbG9hZC1kcGonLCBvblBvbHltZXJSZWFkeSk7aWYgKHdpbmRvdy55dGNzaSkge3dpbmRvdy55dGNzaS50aWNrKCdhcHInLCBudWxsLCAnJyk7fX07IGlmICh3aW5kb3cuUG9seW1lciAmJiBQb2x5bWVyLlJlbmRlclN0YXR1cykge29uUG9seW1lclJlYWR5KCk7fSBlbHNlIHt3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignc2NyaXB0LWxvYWQtZHBqJywgb25Qb2x5bWVyUmVhZHkpO308L3NjcmlwdD48bGluayByZWw9ImNhbm9uaWNhbCIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiPjxsaW5rIHJlbD0iYWx0ZXJuYXRlIiBtZWRpYT0iaGFuZGhlbGQiIGhyZWY9Imh0dHBzOi8vbS55b3V0dWJlLmNvbS9AY29uZnJlYWtzIj48bGluayByZWw9ImFsdGVybmF0ZSIgbWVkaWE9Im9ubHkgc2NyZWVuIGFuZCAobWF4LXdpZHRoOiA2NDBweCkiIGhyZWY9Imh0dHBzOi8vbS55b3V0dWJlLmNvbS9AY29uZnJlYWtzIj48dGl0bGU+Q29uZnJlYWtzIC0gWW91VHViZTwvdGl0bGU+PG1ldGEgbmFtZT0iZGVzY3JpcHRpb24iIGNvbnRlbnQ9IlZpZGVvcyByZWNvcmRlZCBhbmQvb3IgaG9zdGVkIGJ5IENvbmZyZWFrcywgZ2VuZXJhbGx5IGluIHRoZSB0ZWNobm9sb2d5IHNwYWNlLiI+PG1ldGEgbmFtZT0ia2V5d29yZHMiIGNvbnRlbnQ9InJ1YnkgamF2YXNjcmlwdCBjbG9qdXJlIHRlY2hub2xvZ3kgJnF1b3Q7cHJvZ3JhbW1pbmcgbGFuZ3VhZ2UmcXVvdDsgZWxpeGlyIGVtYmVyIHJ1c3QgcmFpbHMgJnF1b3Q7Y29tcHV0ZXIgc2NpZW5jZSZxdW90OyBwcm9ncmFtbWluZyAmcXVvdDt0ZWNoIGNvbmZlcmVuY2UmcXVvdDsgcHl0aG9uIGRldm9wcyBkZXZvcHNkYXlzIHIuLi4iPjxsaW5rIHJlbD0iYWx0ZXJuYXRlIiB0eXBlPSJhcHBsaWNhdGlvbi9yc3MreG1sIiB0aXRsZT0iUlNTIiBocmVmPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9mZWVkcy92aWRlb3MueG1sP2NoYW5uZWxfaWQ9VUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIj48bWV0YSBwcm9wZXJ0eT0ib2c6dGl0bGUiIGNvbnRlbnQ9IkNvbmZyZWFrcyI+PGxpbmsgcmVsPSJpbWFnZV9zcmMiIGhyZWY9Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS95dGMvQUdJS2dxTm5BZlE0a1I4aVo5YXVvMVI3Z2l0bWVIYjdhNWhiOEZSaG45YWpyZz1zOTAwLWMtay1jMHgwMGZmZmZmZi1uby1yaiI+PG1ldGEgcHJvcGVydHk9Im9nOnNpdGVfbmFtZSIgY29udGVudD0iWW91VHViZSI+PG1ldGEgcHJvcGVydHk9Im9nOnVybCIgY29udGVudD0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiPjxtZXRhIHByb3BlcnR5PSJvZzppbWFnZSIgY29udGVudD0iaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3l0Yy9BR0lLZ3FObkFmUTRrUjhpWjlhdW8xUjdnaXRtZUhiN2E1aGI4RlJobjlhanJnPXM5MDAtYy1rLWMweDAwZmZmZmZmLW5vLXJqIj48bWV0YSBwcm9wZXJ0eT0ib2c6aW1hZ2U6d2lkdGgiIGNvbnRlbnQ9IjkwMCI+PG1ldGEgcHJvcGVydHk9Im9nOmltYWdlOmhlaWdodCIgY29udGVudD0iOTAwIj48bWV0YSBwcm9wZXJ0eT0ib2c6ZGVzY3JpcHRpb24iIGNvbnRlbnQ9IlZpZGVvcyByZWNvcmRlZCBhbmQvb3IgaG9zdGVkIGJ5IENvbmZyZWFrcywgZ2VuZXJhbGx5IGluIHRoZSB0ZWNobm9sb2d5IHNwYWNlLiI+PG1ldGEgcHJvcGVydHk9ImFsOmlvczphcHBfc3RvcmVfaWQiIGNvbnRlbnQ9IjU0NDAwNzY2NCI+PG1ldGEgcHJvcGVydHk9ImFsOmlvczphcHBfbmFtZSIgY29udGVudD0iWW91VHViZSI+PG1ldGEgcHJvcGVydHk9ImFsOmlvczp1cmwiIGNvbnRlbnQ9InZuZC55b3V0dWJlOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIj48bWV0YSBwcm9wZXJ0eT0iYWw6YW5kcm9pZDp1cmwiIGNvbnRlbnQ9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRP2ZlYXR1cmU9YXBwbGlua3MiPjxtZXRhIHByb3BlcnR5PSJhbDphbmRyb2lkOmFwcF9uYW1lIiBjb250ZW50PSJZb3VUdWJlIj48bWV0YSBwcm9wZXJ0eT0iYWw6YW5kcm9pZDpwYWNrYWdlIiBjb250ZW50PSJjb20uZ29vZ2xlLmFuZHJvaWQueW91dHViZSI+PG1ldGEgcHJvcGVydHk9ImFsOndlYjp1cmwiIGNvbnRlbnQ9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRP2ZlYXR1cmU9YXBwbGlua3MiPjxtZXRhIHByb3BlcnR5PSJvZzp0eXBlIiBjb250ZW50PSJwcm9maWxlIj48bWV0YSBwcm9wZXJ0eT0ib2c6dmlkZW86dGFnIiBjb250ZW50PSJydWJ5Ij48bWV0YSBwcm9wZXJ0eT0ib2c6dmlkZW86dGFnIiBjb250ZW50PSJqYXZhc2NyaXB0Ij48bWV0YSBwcm9wZXJ0eT0ib2c6dmlkZW86dGFnIiBjb250ZW50PSJjbG9qdXJlIj48bWV0YSBwcm9wZXJ0eT0ib2c6dmlkZW86dGFnIiBjb250ZW50PSJ0ZWNobm9sb2d5Ij48bWV0YSBwcm9wZXJ0eT0ib2c6dmlkZW86dGFnIiBjb250ZW50PSJwcm9ncmFtbWluZyBsYW5ndWFnZSI+PG1ldGEgcHJvcGVydHk9Im9nOnZpZGVvOnRhZyIgY29udGVudD0iZWxpeGlyIj48bWV0YSBwcm9wZXJ0eT0ib2c6dmlkZW86dGFnIiBjb250ZW50PSJlbWJlciI+PG1ldGEgcHJvcGVydHk9Im9nOnZpZGVvOnRhZyIgY29udGVudD0icnVzdCI+PG1ldGEgcHJvcGVydHk9Im9nOnZpZGVvOnRhZyIgY29udGVudD0icmFpbHMiPjxtZXRhIHByb3BlcnR5PSJvZzp2aWRlbzp0YWciIGNvbnRlbnQ9ImNvbXB1dGVyIHNjaWVuY2UiPjxtZXRhIHByb3BlcnR5PSJvZzp2aWRlbzp0YWciIGNvbnRlbnQ9InByb2dyYW1taW5nIj48bWV0YSBwcm9wZXJ0eT0ib2c6dmlkZW86dGFnIiBjb250ZW50PSJ0ZWNoIGNvbmZlcmVuY2UiPjxtZXRhIHByb3BlcnR5PSJvZzp2aWRlbzp0YWciIGNvbnRlbnQ9InB5dGhvbiI+PG1ldGEgcHJvcGVydHk9Im9nOnZpZGVvOnRhZyIgY29udGVudD0iZGV2b3BzIj48bWV0YSBwcm9wZXJ0eT0ib2c6dmlkZW86dGFnIiBjb250ZW50PSJkZXZvcHNkYXlzIj48bWV0YSBwcm9wZXJ0eT0ib2c6dmlkZW86dGFnIiBjb250ZW50PSJyZWFjdCI+PG1ldGEgcHJvcGVydHk9Im9nOnZpZGVvOnRhZyIgY29udGVudD0icG9zdGdyZXMiPjxtZXRhIHByb3BlcnR5PSJvZzp2aWRlbzp0YWciIGNvbnRlbnQ9IkdOVVJhZGlvIj48bWV0YSBwcm9wZXJ0eT0iZmI6YXBwX2lkIiBjb250ZW50PSI4Nzc0MTEyNDMwNSI+PG1ldGEgcHJvcGVydHk9ImZiOnByb2ZpbGVfaWQiIGNvbnRlbnQ9ImNvbmZyZWFrcyI+PG1ldGEgbmFtZT0idHdpdHRlcjpjYXJkIiBjb250ZW50PSJzdW1tYXJ5Ij48bWV0YSBuYW1lPSJ0d2l0dGVyOnNpdGUiIGNvbnRlbnQ9IkB5b3V0dWJlIj48bWV0YSBuYW1lPSJ0d2l0dGVyOnVybCIgY29udGVudD0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiPjxtZXRhIG5hbWU9InR3aXR0ZXI6dGl0bGUiIGNvbnRlbnQ9IkNvbmZyZWFrcyI+PG1ldGEgbmFtZT0idHdpdHRlcjpkZXNjcmlwdGlvbiIgY29udGVudD0iVmlkZW9zIHJlY29yZGVkIGFuZC9vciBob3N0ZWQgYnkgQ29uZnJlYWtzLCBnZW5lcmFsbHkgaW4gdGhlIHRlY2hub2xvZ3kgc3BhY2UuIj48bWV0YSBuYW1lPSJ0d2l0dGVyOmltYWdlIiBjb250ZW50PSJodHRwczovL3l0My5nb29nbGV1c2VyY29udGVudC5jb20veXRjL0FHSUtncU5uQWZRNGtSOGlaOWF1bzFSN2dpdG1lSGI3YTVoYjhGUmhuOWFqcmc9czkwMC1jLWstYzB4MDBmZmZmZmYtbm8tcmoiPjxtZXRhIG5hbWU9InR3aXR0ZXI6YXBwOm5hbWU6aXBob25lIiBjb250ZW50PSJZb3VUdWJlIj48bWV0YSBuYW1lPSJ0d2l0dGVyOmFwcDppZDppcGhvbmUiIGNvbnRlbnQ9IjU0NDAwNzY2NCI+PG1ldGEgbmFtZT0idHdpdHRlcjphcHA6bmFtZTppcGFkIiBjb250ZW50PSJZb3VUdWJlIj48bWV0YSBuYW1lPSJ0d2l0dGVyOmFwcDppZDppcGFkIiBjb250ZW50PSI1NDQwMDc2NjQiPjxtZXRhIG5hbWU9InR3aXR0ZXI6YXBwOnVybDppcGhvbmUiIGNvbnRlbnQ9InZuZC55b3V0dWJlOi8vd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIj48bWV0YSBuYW1lPSJ0d2l0dGVyOmFwcDp1cmw6aXBhZCIgY29udGVudD0idm5kLnlvdXR1YmU6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiPjxtZXRhIG5hbWU9InR3aXR0ZXI6YXBwOm5hbWU6Z29vZ2xlcGxheSIgY29udGVudD0iWW91VHViZSI+PG1ldGEgbmFtZT0idHdpdHRlcjphcHA6aWQ6Z29vZ2xlcGxheSIgY29udGVudD0iY29tLmdvb2dsZS5hbmRyb2lkLnlvdXR1YmUiPjxtZXRhIG5hbWU9InR3aXR0ZXI6YXBwOnVybDpnb29nbGVwbGF5IiBjb250ZW50PSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDV25Qam1xdmxqY2FmQTB6MlUxZndLUSI+PGxpbmsgaXRlbXByb3A9InVybCIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiPjxtZXRhIGl0ZW1wcm9wPSJuYW1lIiBjb250ZW50PSJDb25mcmVha3MiPjxtZXRhIGl0ZW1wcm9wPSJkZXNjcmlwdGlvbiIgY29udGVudD0iVmlkZW9zIHJlY29yZGVkIGFuZC9vciBob3N0ZWQgYnkgQ29uZnJlYWtzLCBnZW5lcmFsbHkgaW4gdGhlIHRlY2hub2xvZ3kgc3BhY2UuIj48bWV0YSBpdGVtcHJvcD0icmVxdWlyZXNTdWJzY3JpcHRpb24iIGNvbnRlbnQ9IkZhbHNlIj48bWV0YSBpdGVtcHJvcD0iaWRlbnRpZmllciIgY29udGVudD0iVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIj48c3BhbiBpdGVtcHJvcD0iYXV0aG9yIiBpdGVtc2NvcGUgaXRlbXR5cGU9Imh0dHA6Ly9zY2hlbWEub3JnL1BlcnNvbiI+PGxpbmsgaXRlbXByb3A9InVybCIgaHJlZj0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiPjxsaW5rIGl0ZW1wcm9wPSJuYW1lIiBjb250ZW50PSJDb25mcmVha3MiPjwvc3Bhbj48c2NyaXB0IHR5cGU9ImFwcGxpY2F0aW9uL2xkK2pzb24iIG5vbmNlPSJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIj57IkBjb250ZXh0IjogImh0dHA6Ly9zY2hlbWEub3JnIiwgIkB0eXBlIjogIkJyZWFkY3J1bWJMaXN0IiwgIml0ZW1MaXN0RWxlbWVudCI6IFt7IkB0eXBlIjogIkxpc3RJdGVtIiwgInBvc2l0aW9uIjogMSwgIml0ZW0iOiB7IkBpZCI6ICJodHRwczpcL1wvd3d3LnlvdXR1YmUuY29tXC9jaGFubmVsXC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCAibmFtZSI6ICJDb25mcmVha3MifX1dfTwvc2NyaXB0PjxsaW5rIGl0ZW1wcm9wPSJ0aHVtYm5haWxVcmwiIGhyZWY9Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS95dGMvQUdJS2dxTm5BZlE0a1I4aVo5YXVvMVI3Z2l0bWVIYjdhNWhiOEZSaG45YWpyZz1zOTAwLWMtay1jMHgwMGZmZmZmZi1uby1yaiI+PHNwYW4gaXRlbXByb3A9InRodW1ibmFpbCIgaXRlbXNjb3BlIGl0ZW10eXBlPSJodHRwOi8vc2NoZW1hLm9yZy9JbWFnZU9iamVjdCI+PGxpbmsgaXRlbXByb3A9InVybCIgaHJlZj0iaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3l0Yy9BR0lLZ3FObkFmUTRrUjhpWjlhdW8xUjdnaXRtZUhiN2E1aGI4RlJobjlhanJnPXM5MDAtYy1rLWMweDAwZmZmZmZmLW5vLXJqIj48bWV0YSBpdGVtcHJvcD0id2lkdGgiIGNvbnRlbnQ9IjkwMCI+PG1ldGEgaXRlbXByb3A9ImhlaWdodCIgY29udGVudD0iOTAwIj48L3NwYW4+PG1ldGEgaXRlbXByb3A9ImlzRmFtaWx5RnJpZW5kbHkiIGNvbnRlbnQ9InRydWUiPjxtZXRhIGl0ZW1wcm9wPSJyZWdpb25zQWxsb3dlZCIgY29udGVudD0iTUgsVU0sUlUsR1EsVFosR1IsTkUsS1IsREssR1MsRUMsVFYsVFQsSU4sUUEsU1MsS1AsU0ssU1YsQ1IsR00sTUwsTUYsQU8sSU0sSVMsVkEsWlcsQUQsVFIsTVAsRkosQUcsTEIsVE0sQUUsU0ksTVUsQ0gsUFQsQ0ksUk8sQU0sR0YsS00sQlIsVlUsQlcsUFcsSkUsQk0sWVQsTUUsTkwsTkEsRVMsS0UsR1QsTFYsU1osRUgsQVMsQ0EsQlYsQVUsTVYsTUcsVkcsTVIsQ1YsRVQsU0IsREosVUEsQ04sUFIsQ0QsSE4sTUEsQ1csTUssVEQsVVksQlMsS1csQ0ssTU0sS04sQ0wsQkksUEwsTVosVVMsUlMsU08sREUsRE0sTkYsU1QsTkksQ00sQVgsUEEsWUUsSk0sV1MsQVIsQkcsQlQsR0csVEosUFMsR0ksQUYsQkIsTVEsR0IsTUMsTVMsQkEsQ1osSE0sR1ksQ0YsU0MsRUUsUEYsSVEsTlAsRlIsVE8sSU8sQ1ksTk8sUEssTFIsVE4sUkUsU1gsRVIsTlosU0osTU8sS0csQVEsQkYsS1ksTEksU00sQlosUE0sS1osTkMsRk8sQVQsRE8sR0wsRk0sUE4sSk8sWkEsU0gsQkgsU04sTFQsSUQsR0gsSUUsR1UsU0UsTFksVFcsUEcsTVQsUEUsU0EsRkksTFUsTkcsVkksR1AsVEwsQkUsTlIsU1ksS0ksVUcsVEYsTUQsSEssU1IsU0csR0EsTVcsQ08sUEgsUlcsVEMsR0UsSFQsTVgsV0YsVk4sVEcsSFIsQkosTFMsVEgsRUcsU0QsSUwsQUwsQVcsU0wsQkQsSVIsRFosQ0csTEEsQk4sSVQsQ1UsSlAsQ1gsTVksR0QsT00sVEssR1csVVosRkssVkUsTlUsQlksQUksSFUsQVosQkwsQ0MsTEssR04sVkMsTU4sUFksQk8sQlEsS0gsWk0sTEMiPjxsaW5rIHJlbD0iYWx0ZXJuYXRlIiBocmVmPSJhbmRyb2lkLWFwcDovL2NvbS5nb29nbGUuYW5kcm9pZC55b3V0dWJlL2h0dHAvd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIj48bGluayByZWw9ImFsdGVybmF0ZSIgaHJlZj0iaW9zLWFwcDovLzU0NDAwNzY2NC92bmQueW91dHViZS93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiPjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kudGljaygncGRjJywgbnVsbCwgJycpO308L3NjcmlwdD48c2NyaXB0IG5vbmNlPSJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIj52YXIgeXRJbml0aWFsRGF0YSA9IHsicmVzcG9uc2VDb250ZXh0Ijp7InNlcnZpY2VUcmFja2luZ1BhcmFtcyI6W3sic2VydmljZSI6IkdGRUVEQkFDSyIsInBhcmFtcyI6W3sia2V5Ijoicm91dGUiLCJ2YWx1ZSI6ImNoYW5uZWwuIn0seyJrZXkiOiJpc19jYXN1YWwiLCJ2YWx1ZSI6ImZhbHNlIn0seyJrZXkiOiJpc19vd25lciIsInZhbHVlIjoiZmFsc2UifSx7ImtleSI6ImlzX21vbmV0aXphdGlvbl9lbmFibGVkIiwidmFsdWUiOiJ0cnVlIn0seyJrZXkiOiJudW1fc2hlbHZlcyIsInZhbHVlIjoiMCJ9LHsia2V5IjoiaXNfYWxjX3N1cmZhY2UiLCJ2YWx1ZSI6ImZhbHNlIn0seyJrZXkiOiJicm93c2VfaWQiLCJ2YWx1ZSI6IlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSJ9LHsia2V5IjoiYnJvd3NlX2lkX3ByZWZpeCIsInZhbHVlIjoiIn0seyJrZXkiOiJsb2dnZWRfaW4iLCJ2YWx1ZSI6IjAifSx7ImtleSI6ImUiLCJ2YWx1ZSI6IjIzODA0MjgxLDIzODU4MDU3LDIzOTE4NTk3LDIzOTQ2NDIwLDIzOTY2MjA4LDIzOTgzMjk2LDIzOTg2MDMzLDIzOTk4MDU2LDI0MDA0NjQ0LDI0MDA3MjQ2LDI0MDM0MTY4LDI0MDM2OTQ4LDI0MDc3MjQxLDI0MDgwNzM4LDI0MTA4NDQ3LDI0MTIwODIwLDI0MTM1MzEwLDI0MTQwMjQ3LDI0MTY2ODY3LDI0MTgxMTc0LDI0MTg3MDQzLDI0MTg3Mzc3LDI0MjExMTc4LDI0MjE5NzEzLDI0MjQxMzc4LDI0MjU1NTQzLDI0MjU1NTQ1LDI0MjYyMzQ2LDI0Mjg4NjY0LDI0MjkwOTcxLDI0MjkxODU3LDI0MzYwODk0LDI0MzYxMTg2LDI0MzYxNjY4LDI0MzYyMDk5LDI0MzYyNTU4LDI0MzYyNjg1LDI0MzYyNjg4LDI0MzYzMTE0LDI0MzY0NzU1LDI0MzY0Nzg5LDI0MzY1MzAxLDI0MzY1NTc2LDI0MzY2MDczLDI0MzY2MDg0LDI0MzY2OTE3LDI0MzY3Njg2LDI0MzY3ODI2LDI0MzY4MzAyLDI0MzY4MzEyLDI0MzY4NzQ5LDI0MzY5ODU3LDI0MzcwNTEwLDI0MzcwNTE1LDI0MzcwODk4LDI0MzcwOTgyLDI0MzcyMTAxLDI0MzcyMTEwLDI0MzcyMzY0LDI0Mzc0MzEzLDI0Mzc0NTkyLDI0Mzc1NTMxLDI0Mzc1NTc0LDI0Mzc2MDUxLDI0Mzc3MzQ2LDI0Mzc5MTMzLDI0Mzc5MzU0LDI0Mzc5NTMzLDI0Mzc5NTQyLDI0Mzc5NjUxLDI0MzgxNjg4LDI0MzkwNjc1LDI0NDA0NjQwLDI0NDA0OTEwLDI0NDA3MTkxLDI0NDA5NDE3LDI0NDE1ODY0LDI0NDI4Nzg5LDI0NDMzNjc5LDI0NDM3NTc3LDI0NDM5MzYxLDI0NDQwMTMyLDI0NDQ1NDk5LDI0NDUxMzE5LDI0NDUzOTg5LDI0NDU3Mzg0LDI0NDU3ODU0LDI0NDU4MzE3LDI0NDU4MzI0LDI0NDU4MzI5LDI0NDU4ODM5LDI0NDU5NDM1LDI0NDY1MDExLDI0NDY2MzcxLDI0NDY4NzI0LDI0NDg0NjgwLDI0NDg1MjM5LDI0NDg1NDIxLDI0NDg4MTg4LDI0NDkyNTQ3LDI0NDk1MDYwLDI0NDk4MzAwLDI0NTEzNDA5LDI0NTE1MzY2LDI0NTE1NDIzLDI0NTE4NDUyLDI0NTE5MTAyLDI0NTE5Njg3LDI0NTMxMjIyLDI0NTMyODU1LDI0NTM1ODk4LDI0NTM3MjAwLDI0NTUwNDU4LDI0NTUwOTUxLDI0NTUxMTMwLDI0NTUyNTc0LDI0NTUyNjA2LDI0NTUzNDM0LDI0NTU0MTM5LDI0NTU4MTYwLDI0NTU4NjQxLDI0NTU5MzI2LDI0NjkwNDk3LDI0NjkxMzM0LDI0Njk0ODQzLDI0Njk1NTE1LDI0Njk3MDk4LDI0Njk4NDE3LDI0Njk4NDUzLDI0Njk4ODgwLDI0Njk5NTk4LDI0Njk5ODYwLDI0Njk5ODk5LDM5MzIzMDc0LDM5MzIzMzM4LDM5MzIzODcyIn1dfSx7InNlcnZpY2UiOiJHT09HTEVfSEVMUCIsInBhcmFtcyI6W3sia2V5IjoiYnJvd3NlX2lkIiwidmFsdWUiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EifSx7ImtleSI6ImJyb3dzZV9pZF9wcmVmaXgiLCJ2YWx1ZSI6IiJ9XX0seyJzZXJ2aWNlIjoiQ1NJIiwicGFyYW1zIjpbeyJrZXkiOiJjIiwidmFsdWUiOiJXRUIifSx7ImtleSI6ImN2ZXIiLCJ2YWx1ZSI6IjIuMjAyMzA2MDcuMDYuMDAifSx7ImtleSI6Inl0X2xpIiwidmFsdWUiOiIwIn0seyJrZXkiOiJHZXRDaGFubmVsUGFnZV9yaWQiLCJ2YWx1ZSI6IjB4MmQwMTUwN2U4YTVhZjM0YiJ9XX0seyJzZXJ2aWNlIjoiR1VJREVEX0hFTFAiLCJwYXJhbXMiOlt7ImtleSI6ImxvZ2dlZF9pbiIsInZhbHVlIjoiMCJ9XX0seyJzZXJ2aWNlIjoiRUNBVENIRVIiLCJwYXJhbXMiOlt7ImtleSI6ImNsaWVudC52ZXJzaW9uIiwidmFsdWUiOiIyLjIwMjMwNjA3In0seyJrZXkiOiJjbGllbnQubmFtZSIsInZhbHVlIjoiV0VCIn0seyJrZXkiOiJjbGllbnQuZmV4cCIsInZhbHVlIjoiMjQ1MTkxMDIsMjQzNzA1MTAsMjM4MDQyODEsMjQzNzk1NDIsMjQ0MzkzNjEsMjQ2OTQ4NDMsMjQ0MzM2NzksMjQzNzkxMzMsMjQzNzA4OTgsMjQzOTA2NzUsMjQzNjYwNzMsMjQ1MzU4OTgsMjQyMTExNzgsMjQ0NTgzMTcsMjQzNzk2NTEsMjQ0NTgzMjQsMjQ1MzI4NTUsMjQzNzIxMDEsMjQxMzUzMTAsMjQ1MTU0MjMsMjQwMzQxNjgsMjQyNjIzNDYsMjQ0Mzc1NzcsMjQzNzU1MzEsMjQyMTk3MTMsMjQ0Njg3MjQsMjQ0OTgzMDAsMjQ1NTI1NzQsMjM5ODMyOTYsMjQzNzU1NzQsMjQ0NTM5ODksMjQ2OTEzMzQsMjQ1MTUzNjYsMjQzNjU1NzYsMjQzNjgzMDIsMjQ0MDQ2NDAsMjQ0MDk0MTcsMjQ0ODgxODgsMjQyOTE4NTcsMjQ0OTI1NDcsMjQzNzk1MzMsMjQ1NTkzMjYsMjQzNzQzMTMsMjQ0MTU4NjQsMjM4NTgwNTcsMjQ0NDAxMzIsMjQ1MzEyMjIsMjQzNzIzNjQsMjQzNjc2ODYsMjQzNzkzNTQsMjQ1MTk2ODcsMjQzNjI2ODgsMjQyNTU1NDMsMjQ2OTk1OTgsMjQzNjIwOTksMjM5MTg1OTcsMjQ1NTExMzAsMjQ1NTA5NTEsMjQzNjg3NDksMjQ0ODU0MjEsMjQ0NTEzMTksMjQzNjk4NTcsMjQ1MTg0NTIsMjQ0NTgzMjksMjQ0ODQ2ODAsMjQ2OTg0NTMsMjQzNjI1NTgsMjQxODcwNDMsMjQ2OTg0MTcsMjQ2OTk4OTksMjQzNjE2NjgsMjQ2OTg4ODAsMjQ0NTg4MzksMjQwMzY5NDgsMjQzNzQ1OTIsMjQ0MDQ5MTAsMjQ0NTc4NTQsMjQzNzYwNTEsMjQ1NTM0MzQsMjQzNjExODYsMzkzMjMwNzQsMjQzNjYwODQsMjM5ODYwMzMsMjQyNTU1NDUsMjQyNDEzNzgsMjQ1NTg2NDEsMjQzNjMxMTQsMjQ1NTQxMzksMjQ0NDU0OTksMjQzNzczNDYsMjQ2OTU1MTUsMjQzNjgzMTIsMjM5OTgwNTYsMjQ1NTI2MDYsMjQzNjY5MTcsMzkzMjM4NzIsMjM5NjYyMDgsMjQzNjQ3ODksMjQ1NTgxNjAsMjQxNjY4NjcsMjQ0NTk0MzUsMjQwODA3MzgsMjQ0ODUyMzksMjQzODE2ODgsMjQxODExNzQsMjQzNzA1MTUsMjQ1MTM0MDksMjQyODg2NjQsMjQzNjc4MjYsMjQ2OTk4NjAsMjQzNjI2ODUsMjQ2OTA0OTcsMjQwMDcyNDYsMjQxMDg0NDcsMjQ0OTUwNjAsMjQxNDAyNDcsMjQ0NTczODQsMjQ0NjUwMTEsMjQzNjQ3NTUsMjQzNzIxMTAsMjQ0Mjg3ODksMjQxMjA4MjAsMjQwMDQ2NDQsMzkzMjMzMzgsMjQ2OTcwOTgsMjQzNjA4OTQsMjQ0NjYzNzEsMjQ1MzcyMDAsMjQyOTA5NzEsMjQ0MDcxOTEsMjQ1NTA0NTgsMjQxODczNzcsMjQzNzA5ODIsMjQzNjUzMDEsMjQwNzcyNDEsMjM5NDY0MjAifV19XSwibWF4QWdlU2Vjb25kcyI6MzAwLCJtYWluQXBwV2ViUmVzcG9uc2VDb250ZXh0Ijp7ImxvZ2dlZE91dCI6dHJ1ZSwidHJhY2tpbmdQYXJhbSI6Imt4X2ZtUHhob1BaUmpRdEdVMGZPekthZ0hpZktQX3ZveVd5X2o3a1hIMEQ2My13UmdrdXN3bUlCd09jQ0U1OVREdHNsTEtQUS1TUyJ9LCJ3ZWJSZXNwb25zZUNvbnRleHRFeHRlbnNpb25EYXRhIjp7Inl0Q29uZmlnRGF0YSI6eyJ2aXNpdG9yRGF0YSI6IkNndHNaVzVTVms1bGJrTldTU2lXdm9pa0JnJTNEJTNEIiwicm9vdFZpc3VhbEVsZW1lbnRUeXBlIjozNjExfSwiaGFzRGVjb3JhdGVkIjp0cnVlfX0sImNvbnRlbnRzIjp7InR3b0NvbHVtbkJyb3dzZVJlc3VsdHNSZW5kZXJlciI6eyJ0YWJzIjpbeyJ0YWJSZW5kZXJlciI6eyJlbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0JZUThKTUJHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL0BDb25mcmVha3MvZmVhdHVyZWQiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJwYXJhbXMiOiJFZ2htWldGMGRYSmxaUElHQkFvQ01nQSUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQENvbmZyZWFrcyJ9fSwidGl0bGUiOiJBY2N1ZWlsIiwic2VsZWN0ZWQiOnRydWUsImNvbnRlbnQiOnsic2VjdGlvbkxpc3RSZW5kZXJlciI6eyJjb250ZW50cyI6W3siaXRlbVNlY3Rpb25SZW5kZXJlciI6eyJjb250ZW50cyI6W3siY2hhbm5lbFZpZGVvUGxheWVyUmVuZGVyZXIiOnsidmlkZW9JZCI6Ikx4ZGt0WjRKS25RIiwidGl0bGUiOnsicnVucyI6W3sidGV4dCI6IkNvbmZyZWFrcyBQcm9tbyBWaWRlbyIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ1BvQkVMc3ZHQUFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9THhka3RaNEpLblEiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiTHhka3RaNEpLblEiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnI0LS0tc24tMjVnZTduenIuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTJmMTc2NGI1OWUwOTJhNzRcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9Mzc1MDAwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX19XSwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkNvbmZyZWFrcyBQcm9tbyBWaWRlbyBkZSBDb25mcmVha3MgaWwgeSBhIDQgYW5zIDU1wqBzZWNvbmRlcyA14oCvODQ0wqB2dWVzIn19fSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiNeKArzg0NMKgdnVlcyJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiaWwgeSBhIDQgYW5zIn1dfSwicmVhZE1vcmVUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJMaXJlIGxhIHN1aXRlIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDUG9CRUxzdkdBQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1MeGRrdFo0SktuUSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJMeGRrdFo0SktuUSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjQtLS1zbi0yNWdlN256ci5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9MmYxNzY0YjU5ZTA5MmE3NFx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz0zNzUwMDBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fX1dfX19XSwidHJhY2tpbmdQYXJhbXMiOiJDUG9CRUxzdkdBQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsiaXRlbVNlY3Rpb25SZW5kZXJlciI6eyJjb250ZW50cyI6W3sic2hlbGZSZW5kZXJlciI6eyJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiUGxheWxpc3RzIGNyw6nDqWVzIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTjRCRU53Y0dBQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQENvbmZyZWFrcy9wbGF5bGlzdHM/dmlldz0xXHUwMDI2c29ydD1kZFx1MDAyNnNoZWxmX2lkPTAiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJwYXJhbXMiOiJFZ2x3YkdGNWJHbHpkSE1ZQXlBQmNBRHlCZ2tLQjBJQW9nRUNDQUUlM0QiLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BDb25mcmVha3MifX19XX0sImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTjRCRU53Y0dBQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQENvbmZyZWFrcy9wbGF5bGlzdHM/dmlldz0xXHUwMDI2c29ydD1kZFx1MDAyNnNoZWxmX2lkPTAiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJwYXJhbXMiOiJFZ2x3YkdGNWJHbHpkSE1ZQXlBQmNBRHlCZ2tLQjBJQW9nRUNDQUUlM0QiLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BDb25mcmVha3MifX0sImNvbnRlbnQiOnsiaG9yaXpvbnRhbExpc3RSZW5kZXJlciI6eyJpdGVtcyI6W3siZ3JpZFBsYXlsaXN0UmVuZGVyZXIiOnsicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeWFORGZiME1NazlJd2RKb0dtcnlRS2ciLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS82Y0NDeWlKZlU5Zy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZR2lCbEtGc3dEdz09XHUwMDI2cnM9QU9uNENMQy1DWGlOTzJKWUpPVzVnZnlDVjd4b1hwYTR4USIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjIyLCJncmVlbiI6ODksImJsdWUiOjgwfX0sInRpdGxlIjp7InJ1bnMiOlt7InRleHQiOiIhIUNvbiAyMDIyIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDUGdCRUpZMUdBQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PTZjQ0N5aUpmVTlnXHUwMDI2bGlzdD1QTEU3dFFVZFJLY3lhTkRmYjBNTWs5SXdkSm9HbXJ5UUtnXHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiI2Y0NDeWlKZlU5ZyIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3lhTkRmYjBNTWs5SXdkSm9HbXJ5UUtnIiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xoVGtSbVlqQk5UV3M1U1hka1NtOUhiWEo1VVV0biJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMS0tLXNuLTI1Z2xlbmxrLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1lOWMwODJjYTIyNWY1M2Q4XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTY0ODc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19fV19LCJ2aWRlb0NvdW50VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiMTAifSx7InRleHQiOiLCoHZpZMOpb3MifV19LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNQZ0JFSlkxR0FBaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lCbWN0YUdsbmFGb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9NmNDQ3lpSmZVOWdcdTAwMjZsaXN0PVBMRTd0UVVkUktjeWFORGZiME1NazlJd2RKb0dtcnlRS2dcdTAwMjZwcD1pQVFCIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IjZjQ0N5aUpmVTlnIiwicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeWFORGZiME1NazlJd2RKb0dtcnlRS2ciLCJwYXJhbXMiOiJPQUklM0QiLCJwbGF5ZXJQYXJhbXMiOiJpQVFCIiwibG9nZ2luZ0NvbnRleHQiOnsidnNzTG9nZ2luZ0NvbnRleHQiOnsic2VyaWFsaXplZENvbnRleHREYXRhIjoiR2lKUVRFVTNkRkZWWkZKTFkzbGhUa1JtWWpCTlRXczVTWGRrU205SGJYSjVVVXRuIn19LCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIxLS0tc24tMjVnbGVubGsuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWU5YzA4MmNhMjI1ZjUzZDhcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjQ4NzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInZpZGVvQ291bnRTaG9ydFRleHQiOnsic2ltcGxlVGV4dCI6IjEwIn0sInRyYWNraW5nUGFyYW1zIjoiQ1BnQkVKWTFHQUFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNpZGViYXJUaHVtYm5haWxzIjpbeyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1MwRXllYXQwZW1JL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ1pJR1VvV2pBUFx1MDAyNnJzPUFPbjRDTENNLXJWUy1WWnlQelNjR01VWjhTVEROQUZ6RUEiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL21Bd1ZqcjQ5V0FnL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV3pBUFx1MDAyNnJzPUFPbjRDTERna1Jlc0R2VUswNGMxei1RdGFhNE8ybnNuaXciLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0owZVFYaGU3OFZjL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV3pBUFx1MDAyNnJzPUFPbjRDTENHeUhldC1fZEV0VWJIZVBvb1ZCRFdNSWRHTFEiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzNBV1ROc0pFQV9JL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV3pBUFx1MDAyNnJzPUFPbjRDTEQxSEVpbTNoNlJwVkpSOGJMNEZvVmVQZzEyN0EiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX1dLCJ0aHVtYm5haWxUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiIxMCIsImJvbGQiOnRydWV9LHsidGV4dCI6IsKgdmlkw6lvcyJ9XX0sInRodW1ibmFpbFJlbmRlcmVyIjp7InBsYXlsaXN0VmlkZW9UaHVtYm5haWxSZW5kZXJlciI6eyJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS82Y0NDeWlKZlU5Zy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZR2lCbEtGc3dEdz09XHUwMDI2cnM9QU9uNENMQy1DWGlOTzJKWUpPVzVnZnlDVjd4b1hwYTR4USIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjIyLCJncmVlbiI6ODksImJsdWUiOjgwfX0sInRyYWNraW5nUGFyYW1zIjoiQ1BrQkVNdnNDU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSJ9fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlCb3R0b21QYW5lbFJlbmRlcmVyIjp7InRleHQiOnsic2ltcGxlVGV4dCI6IjEwwqB2aWTDqW9zIn0sImljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVFMifX19LHsidGh1bWJuYWlsT3ZlcmxheUhvdmVyVGV4dFJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlRvdXQgbGlyZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJQTEFZX0FMTCJ9fX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dLCJ2aWV3UGxheWxpc3RUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBZmZpY2hlciBsYSBwbGF5bGlzdCBjb21wbMOodGUiLCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNQZ0JFSlkxR0FBaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lCbWN0YUdsbmFBPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9wbGF5bGlzdD9saXN0PVBMRTd0UVVkUktjeWFORGZiME1NazlJd2RKb0dtcnlRS2ciLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfUExBWUxJU1QiLCJyb290VmUiOjU3NTQsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVkxQTEU3dFFVZFJLY3lhTkRmYjBNTWs5SXdkSm9HbXJ5UUtnIn19fV19fX0seyJncmlkUGxheWxpc3RSZW5kZXJlciI6eyJwbGF5bGlzdElkIjoiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLy1FeFBPLUZDS1FBL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0V4Q09BREVJNENTRnJ5cTRxcEF5TUlBUlVBQUloQ0dBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlFeUF4S0g4d0R3PT1cdTAwMjZycz1BT240Q0xBTV9jN3Y2b1BVUGtLZU9kdUNjckhaYV93MzRBIiwid2lkdGgiOjQ4MCwiaGVpZ2h0IjoyNzB9XSwic2FtcGxlZFRodW1ibmFpbENvbG9yIjp7InJlZCI6MTcsImdyZWVuIjo0NCwiYmx1ZSI6MTE0fX0sInRpdGxlIjp7InJ1bnMiOlt7InRleHQiOiJSdWJ5Q29uZiAyMDIyOiBNaW5pIGFuZCBIb3VzdG9uIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDUFlCRUpZMUdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PS1FeFBPLUZDS1FBXHUwMDI2bGlzdD1QTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrXHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiItRXhQTy1GQ0tRQSIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xhV1hvd1R6TmtPVnBFWkc4d0xVSnJUMWRvY2xOciJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNS0tLXNuLTI1Z2U3bnpzLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1mODRjNGYzYmUxNDIyOTAwXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYzMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19fV19LCJ2aWRlb0NvdW50VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiNzkifSx7InRleHQiOiLCoHZpZMOpb3MifV19LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNQWUJFSlkxR0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lCbWN0YUdsbmFGb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9LUV4UE8tRkNLUUFcdTAwMjZsaXN0PVBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2tcdTAwMjZwcD1pQVFCIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6Ii1FeFBPLUZDS1FBIiwicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLCJwYXJhbXMiOiJPQUklM0QiLCJwbGF5ZXJQYXJhbXMiOiJpQVFCIiwibG9nZ2luZ0NvbnRleHQiOnsidnNzTG9nZ2luZ0NvbnRleHQiOnsic2VyaWFsaXplZENvbnRleHREYXRhIjoiR2lKUVRFVTNkRkZWWkZKTFkzbGFXWG93VHpOa09WcEVaRzh3TFVKclQxZG9jbE5yIn19LCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnI1LS0tc24tMjVnZTduenMuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWY4NGM0ZjNiZTE0MjI5MDBcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjMzNzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInZpZGVvQ291bnRTaG9ydFRleHQiOnsic2ltcGxlVGV4dCI6Ijc5In0sInRyYWNraW5nUGFyYW1zIjoiQ1BZQkVKWTFHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNpZGViYXJUaHVtYm5haWxzIjpbeyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLy1kejlLR1lNVDI0L2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSaF9JQ2tvRXpBUFx1MDAyNnJzPUFPbjRDTERBbUltLUFoZ2t0aS1zNndsNE8zalZpMmdTb3ciLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzFmSVB2LXZPU2owL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSaEpJRFlvZnpBUFx1MDAyNnJzPUFPbjRDTEFyekdYVkRrR1RJM0d6SFc1dExDNkxsaW5XVHciLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzM3RGtNaW1MRzRBL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSaEVJRE1vZnpBUFx1MDAyNnJzPUFPbjRDTERlbWxBay14MXBQU0h4Zk1KM3l2RGR4Rjc1TVEiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0hvRzJUMGFKdmZZL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSaGxJR0VvVWpBUFx1MDAyNnJzPUFPbjRDTERhSllUbXZnRHk3S1ZWQ3M2Xy1TU3NJaDlZR1EiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX1dLCJ0aHVtYm5haWxUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiI3OSIsImJvbGQiOnRydWV9LHsidGV4dCI6IsKgdmlkw6lvcyJ9XX0sInRodW1ibmFpbFJlbmRlcmVyIjp7InBsYXlsaXN0VmlkZW9UaHVtYm5haWxSZW5kZXJlciI6eyJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8tRXhQTy1GQ0tRQS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZRXlBeEtIOHdEdz09XHUwMDI2cnM9QU9uNENMQU1fYzd2Nm9QVVBrS2VPZHVDY3JIWmFfdzM0QSIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjE3LCJncmVlbiI6NDQsImJsdWUiOjExNH19LCJ0cmFja2luZ1BhcmFtcyI6IkNQY0JFTXZzQ1NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0ifX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5Qm90dG9tUGFuZWxSZW5kZXJlciI6eyJ0ZXh0Ijp7InNpbXBsZVRleHQiOiI3OcKgdmlkw6lvcyJ9LCJpY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RTIn19fSx7InRodW1ibmFpbE92ZXJsYXlIb3ZlclRleHRSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJUb3V0IGxpcmUifV19LCJpY29uIjp7Imljb25UeXBlIjoiUExBWV9BTEwifX19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XSwidmlld1BsYXlsaXN0VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWZmaWNoZXIgbGEgcGxheWxpc3QgY29tcGzDqHRlIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDUFlCRUpZMUdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvcGxheWxpc3Q/bGlzdD1QTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1BMQVlMSVNUIiwicm9vdFZlIjo1NzU0LCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlZMUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayJ9fX1dfX19LHsiZ3JpZFBsYXlsaXN0UmVuZGVyZXIiOnsicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeVpjdFJYejYyUjdPLXRIbDVydkdrRjciLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS85RVlBdHNuMGU5WS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZSFNBbktIOHdEdz09XHUwMDI2cnM9QU9uNENMRG9mNUNwb3NKY3NwMTA5bGNhdlZiS3NUZFNGdyIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjI2LCJncmVlbiI6MzUsImJsdWUiOjExNH19LCJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiRGV2T3BzRGF5cyBCb3N0b24gMjAyMiIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ1BRQkVKWTFHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUJtY3RhR2xuYUZvWVZVTlhibEJxYlhGMmJHcGpZV1pCTUhveVZURm1kMHRSbWdFRkVQSTRHR2c9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj05RVlBdHNuMGU5WVx1MDAyNmxpc3Q9UExFN3RRVWRSS2N5WmN0Ulh6NjJSN08tdEhsNXJ2R2tGN1x1MDAyNnBwPWlBUUIiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiOUVZQXRzbjBlOVkiLCJwbGF5bGlzdElkIjoiUExFN3RRVWRSS2N5WmN0Ulh6NjJSN08tdEhsNXJ2R2tGNyIsInBhcmFtcyI6Ik9BSSUzRCIsInBsYXllclBhcmFtcyI6ImlBUUIiLCJsb2dnaW5nQ29udGV4dCI6eyJ2c3NMb2dnaW5nQ29udGV4dCI6eyJzZXJpYWxpemVkQ29udGV4dERhdGEiOiJHaUpRVEVVM2RGRlZaRkpMWTNsYVkzUlNXSG8yTWxJM1R5MTBTR3cxY25aSGEwWTMifX0sIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjMtLS1zbi0yNWdsZW5sei5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9ZjQ0NjAwYjZjOWY0N2JkNlx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MzM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fX1dfSwidmlkZW9Db3VudFRleHQiOnsicnVucyI6W3sidGV4dCI6IjEwIn0seyJ0ZXh0IjoiwqB2aWTDqW9zIn1dfSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDUFFCRUpZMUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PTlFWUF0c24wZTlZXHUwMDI2bGlzdD1QTEU3dFFVZFJLY3laY3RSWHo2MlI3Ty10SGw1cnZHa0Y3XHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiI5RVlBdHNuMGU5WSIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3laY3RSWHo2MlI3Ty10SGw1cnZHa0Y3IiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xhWTNSU1dIbzJNbEkzVHkxMFNHdzFjblpIYTBZMyJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMy0tLXNuLTI1Z2xlbmx6Lmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1mNDQ2MDBiNmM5ZjQ3YmQ2XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYzMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ2aWRlb0NvdW50U2hvcnRUZXh0Ijp7InNpbXBsZVRleHQiOiIxMCJ9LCJ0cmFja2luZ1BhcmFtcyI6IkNQUUJFSlkxR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJzaWRlYmFyVGh1bWJuYWlscyI6W3sidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9RSno2YmhkdGN5dy9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhISUdVb1pUQVBcdTAwMjZycz1BT240Q0xCVmMwNjFCNDhOVjMwb3dGX0pxT29jM3JDWVVRIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9DRjg0WHB4MGlCSS9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhUSUdNb1pUQVBcdTAwMjZycz1BT240Q0xBdTZGX3R3T2puREF3Qlg3R3l3T3NHSHVaVGR3Iiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8yNTNlSnBMNGNwdy9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhSSUdJb1pUQVBcdTAwMjZycz1BT240Q0xEek5vcUo4WXEycWFVbDNiR0c1eUNlekY0TS1RIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9oU2JsOW9hT2ZWVS9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhXSUdRb1pUQVBcdTAwMjZycz1BT240Q0xDUmR3aFUwUTdsenFlb2NzckJaQTMtUXE5cUxRIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19XSwidGh1bWJuYWlsVGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiMTAiLCJib2xkIjp0cnVlfSx7InRleHQiOiLCoHZpZMOpb3MifV19LCJ0aHVtYm5haWxSZW5kZXJlciI6eyJwbGF5bGlzdFZpZGVvVGh1bWJuYWlsUmVuZGVyZXIiOnsidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvOUVZQXRzbjBlOVkvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RXhDT0FERUk0Q1NGcnlxNHFwQXlNSUFSVUFBSWhDR0FId0FRSDRBZjRKZ0FMUUJZb0NEQWdBRUFFWUhTQW5LSDh3RHc9PVx1MDAyNnJzPUFPbjRDTERvZjVDcG9zSmNzcDEwOWxjYXZWYktzVGRTRnciLCJ3aWR0aCI6NDgwLCJoZWlnaHQiOjI3MH1dLCJzYW1wbGVkVGh1bWJuYWlsQ29sb3IiOnsicmVkIjoyNiwiZ3JlZW4iOjM1LCJibHVlIjoxMTR9fSwidHJhY2tpbmdQYXJhbXMiOiJDUFVCRU12c0NTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09In19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheUJvdHRvbVBhbmVsUmVuZGVyZXIiOnsidGV4dCI6eyJzaW1wbGVUZXh0IjoiMTDCoHZpZMOpb3MifSwiaWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUUyJ9fX0seyJ0aHVtYm5haWxPdmVybGF5SG92ZXJUZXh0UmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiVG91dCBsaXJlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlBMQVlfQUxMIn19fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV0sInZpZXdQbGF5bGlzdFRleHQiOnsicnVucyI6W3sidGV4dCI6IkFmZmljaGVyIGxhIHBsYXlsaXN0IGNvbXBsw6h0ZSIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ1BRQkVKWTFHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUJtY3RhR2xuYUE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3BsYXlsaXN0P2xpc3Q9UExFN3RRVWRSS2N5WmN0Ulh6NjJSN08tdEhsNXJ2R2tGNyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9QTEFZTElTVCIsInJvb3RWZSI6NTc1NCwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJWTFBMRTd0UVVkUktjeVpjdFJYejYyUjdPLXRIbDVydkdrRjcifX19XX19fSx7ImdyaWRQbGF5bGlzdFJlbmRlcmVyIjp7InBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3liMk1qdGQxUkJqZVAzSnQ5UnVrVTdHIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvcXFURm0yWnRSSGcvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RXhDT0FERUk0Q1NGcnlxNHFwQXlNSUFSVUFBSWhDR0FId0FRSDRBZjRKZ0FMUUJZb0NEQWdBRUFFWWNpQlNLQ2d3RHc9PVx1MDAyNnJzPUFPbjRDTEFMQjlQZW93alJ2WldkY1dzVDRMV0x0MUNrUkEiLCJ3aWR0aCI6NDgwLCJoZWlnaHQiOjI3MH1dLCJzYW1wbGVkVGh1bWJuYWlsQ29sb3IiOnsicmVkIjoxMDEsImdyZWVuIjo3MywiYmx1ZSI6MzZ9fSwidGl0bGUiOnsicnVucyI6W3sidGV4dCI6IlJhaWxzQ29uZiAyMDIyIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDUElCRUpZMUdBTWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PXFxVEZtMlp0UkhnXHUwMDI2bGlzdD1QTEU3dFFVZFJLY3liMk1qdGQxUkJqZVAzSnQ5UnVrVTdHXHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJxcVRGbTJadFJIZyIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3liMk1qdGQxUkJqZVAzSnQ5UnVrVTdHIiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xpTWsxcWRHUXhVa0pxWlZBelNuUTVVblZyVlRkSCJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMy0tLXNuLTI1Z2xlbmxkLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1hYWE0YzU5YjY2NmQ0NDc4XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYzMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19fV19LCJ2aWRlb0NvdW50VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiNjcifSx7InRleHQiOiLCoHZpZMOpb3MifV19LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNQSUJFSlkxR0FNaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lCbWN0YUdsbmFGb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9cXFURm0yWnRSSGdcdTAwMjZsaXN0PVBMRTd0UVVkUktjeWIyTWp0ZDFSQmplUDNKdDlSdWtVN0dcdTAwMjZwcD1pQVFCIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6InFxVEZtMlp0UkhnIiwicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeWIyTWp0ZDFSQmplUDNKdDlSdWtVN0ciLCJwYXJhbXMiOiJPQUklM0QiLCJwbGF5ZXJQYXJhbXMiOiJpQVFCIiwibG9nZ2luZ0NvbnRleHQiOnsidnNzTG9nZ2luZ0NvbnRleHQiOnsic2VyaWFsaXplZENvbnRleHREYXRhIjoiR2lKUVRFVTNkRkZWWkZKTFkzbGlNazFxZEdReFVrSnFaVkF6U25RNVVuVnJWVGRIIn19LCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIzLS0tc24tMjVnbGVubGQuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWFhYTRjNTliNjY2ZDQ0NzhcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjMzNzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInZpZGVvQ291bnRTaG9ydFRleHQiOnsic2ltcGxlVGV4dCI6IjY3In0sInRyYWNraW5nUGFyYW1zIjoiQ1BJQkVKWTFHQU1pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNpZGViYXJUaHVtYm5haWxzIjpbeyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzU3QXNRcnhqTEVzL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSaF9JRE1vTHpBUFx1MDAyNnJzPUFPbjRDTERfUU44WEpLUTVwT3hlMzR3aDBLRlhjc2J2aVEiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0xNbUtFZmpXNDY4L2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSaF9JQzhvTFRBUFx1MDAyNnJzPUFPbjRDTEEyZlpRaUd3SlZCdkpQZWE0UGxMeGp2eGVQbkEiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1NTN0xvSktrbVlzL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSaGxJR1VvWlRBUFx1MDAyNnJzPUFPbjRDTENHelFhUm9YOVRiZEdIOFdkMWdBUGMyLXJtQkEiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2ZobnBhRlJaNEt3L2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZzhJRmNvY2pBUFx1MDAyNnJzPUFPbjRDTEJ3X0FhOXN3RmdiNGphd2tBcHdBanF2SU9GbXciLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX1dLCJ0aHVtYm5haWxUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiI2NyIsImJvbGQiOnRydWV9LHsidGV4dCI6IsKgdmlkw6lvcyJ9XX0sInRodW1ibmFpbFJlbmRlcmVyIjp7InBsYXlsaXN0VmlkZW9UaHVtYm5haWxSZW5kZXJlciI6eyJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xcVRGbTJadFJIZy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZY2lCU0tDZ3dEdz09XHUwMDI2cnM9QU9uNENMQUxCOVBlb3dqUnZaV2RjV3NUNExXTHQxQ2tSQSIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjEwMSwiZ3JlZW4iOjczLCJibHVlIjozNn19LCJ0cmFja2luZ1BhcmFtcyI6IkNQTUJFTXZzQ1NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0ifX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5Qm90dG9tUGFuZWxSZW5kZXJlciI6eyJ0ZXh0Ijp7InNpbXBsZVRleHQiOiI2N8Kgdmlkw6lvcyJ9LCJpY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RTIn19fSx7InRodW1ibmFpbE92ZXJsYXlIb3ZlclRleHRSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJUb3V0IGxpcmUifV19LCJpY29uIjp7Imljb25UeXBlIjoiUExBWV9BTEwifX19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XSwidmlld1BsYXlsaXN0VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWZmaWNoZXIgbGEgcGxheWxpc3QgY29tcGzDqHRlIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDUElCRUpZMUdBTWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvcGxheWxpc3Q/bGlzdD1QTEU3dFFVZFJLY3liMk1qdGQxUkJqZVAzSnQ5UnVrVTdHIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1BMQVlMSVNUIiwicm9vdFZlIjo1NzU0LCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlZMUExFN3RRVWRSS2N5YjJNanRkMVJCamVQM0p0OVJ1a1U3RyJ9fX1dfX19LHsiZ3JpZFBsYXlsaXN0UmVuZGVyZXIiOnsicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeWFieDdTTVFyeXQwT2lTTVg5N0kwR2EiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9sSHF5QzlSZE55WS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZRXlBVEtIOHdEdz09XHUwMDI2cnM9QU9uNENMQXUzWUtvQ2tSUHUzTVFqVV9UTDR1dkpjZHZ1USIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjE3LCJncmVlbiI6MTcsImJsdWUiOjExNH19LCJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiUG93ZXJTaGVsbCArIERldk9wcyBHbG9iYWwgU3VtbWl0IDIwMjIiLCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNQQUJFSlkxR0FRaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lCbWN0YUdsbmFGb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9bEhxeUM5UmROeVlcdTAwMjZsaXN0PVBMRTd0UVVkUktjeWFieDdTTVFyeXQwT2lTTVg5N0kwR2FcdTAwMjZwcD1pQVFCIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6ImxIcXlDOVJkTnlZIiwicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeWFieDdTTVFyeXQwT2lTTVg5N0kwR2EiLCJwYXJhbXMiOiJPQUklM0QiLCJwbGF5ZXJQYXJhbXMiOiJpQVFCIiwibG9nZ2luZ0NvbnRleHQiOnsidnNzTG9nZ2luZ0NvbnRleHQiOnsic2VyaWFsaXplZENvbnRleHREYXRhIjoiR2lKUVRFVTNkRkZWWkZKTFkzbGhZbmczVTAxUmNubDBNRTlwVTAxWU9UZEpNRWRoIn19LCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnI0LS0tc24tMjVnbGVubGQuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTk0N2FiMjBiZDQ1ZDM3MjZcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjIzNzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX19XX0sInZpZGVvQ291bnRUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiI1NSJ9LHsidGV4dCI6IsKgdmlkw6lvcyJ9XX0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ1BBQkVKWTFHQVFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUJtY3RhR2xuYUZvWVZVTlhibEJxYlhGMmJHcGpZV1pCTUhveVZURm1kMHRSbWdFRkVQSTRHR2c9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1sSHF5QzlSZE55WVx1MDAyNmxpc3Q9UExFN3RRVWRSS2N5YWJ4N1NNUXJ5dDBPaVNNWDk3STBHYVx1MDAyNnBwPWlBUUIiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoibEhxeUM5UmROeVkiLCJwbGF5bGlzdElkIjoiUExFN3RRVWRSS2N5YWJ4N1NNUXJ5dDBPaVNNWDk3STBHYSIsInBhcmFtcyI6Ik9BSSUzRCIsInBsYXllclBhcmFtcyI6ImlBUUIiLCJsb2dnaW5nQ29udGV4dCI6eyJ2c3NMb2dnaW5nQ29udGV4dCI6eyJzZXJpYWxpemVkQ29udGV4dERhdGEiOiJHaUpRVEVVM2RGRlZaRkpMWTNsaFluZzNVMDFSY25sME1FOXBVMDFZT1RkSk1FZGgifX0sIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjQtLS1zbi0yNWdsZW5sZC5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9OTQ3YWIyMGJkNDVkMzcyNlx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MjM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidmlkZW9Db3VudFNob3J0VGV4dCI6eyJzaW1wbGVUZXh0IjoiNTUifSwidHJhY2tpbmdQYXJhbXMiOiJDUEFCRUpZMUdBUWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2lkZWJhclRodW1ibmFpbHMiOlt7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvY0w0eXV2WmkzN3MvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJobElHUW9UREFQXHUwMDI2cnM9QU9uNENMQU1LUzFJNndfSVN0ZV9QUXZfSkVVRGdId2VwZyIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfSx7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvX0FDSHFTS0YtYTQvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJnVElGTW9mekFQXHUwMDI2cnM9QU9uNENMRGxTTmNacTBXRXVxWWNtN2h4c25WaEt1TlpIUSIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfSx7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvSmZLaGxoV0p1WjgvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJobElGOG9WVEFQXHUwMDI2cnM9QU9uNENMQ1dkTFVOMmU1TW5aRllBV2JMc1NIMVdjcGhaUSIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfSx7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvb3NKSmN2Q2RDU0kvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJobElGMG9VekFQXHUwMDI2cnM9QU9uNENMRG5PSm5VQlktVzZlVWZKTTl1a3ljcktETHprZyIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfV0sInRodW1ibmFpbFRleHQiOnsicnVucyI6W3sidGV4dCI6IjU1IiwiYm9sZCI6dHJ1ZX0seyJ0ZXh0IjoiwqB2aWTDqW9zIn1dfSwidGh1bWJuYWlsUmVuZGVyZXIiOnsicGxheWxpc3RWaWRlb1RodW1ibmFpbFJlbmRlcmVyIjp7InRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2xIcXlDOVJkTnlZL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0V4Q09BREVJNENTRnJ5cTRxcEF5TUlBUlVBQUloQ0dBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlFeUFUS0g4d0R3PT1cdTAwMjZycz1BT240Q0xBdTNZS29Da1JQdTNNUWpVX1RMNHV2SmNkdnVRIiwid2lkdGgiOjQ4MCwiaGVpZ2h0IjoyNzB9XSwic2FtcGxlZFRodW1ibmFpbENvbG9yIjp7InJlZCI6MTcsImdyZWVuIjoxNywiYmx1ZSI6MTE0fX0sInRyYWNraW5nUGFyYW1zIjoiQ1BFQkVNdnNDU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSJ9fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlCb3R0b21QYW5lbFJlbmRlcmVyIjp7InRleHQiOnsic2ltcGxlVGV4dCI6IjU1wqB2aWTDqW9zIn0sImljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVFMifX19LHsidGh1bWJuYWlsT3ZlcmxheUhvdmVyVGV4dFJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlRvdXQgbGlyZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJQTEFZX0FMTCJ9fX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dLCJ2aWV3UGxheWxpc3RUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBZmZpY2hlciBsYSBwbGF5bGlzdCBjb21wbMOodGUiLCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNQQUJFSlkxR0FRaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lCbWN0YUdsbmFBPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9wbGF5bGlzdD9saXN0PVBMRTd0UVVkUktjeWFieDdTTVFyeXQwT2lTTVg5N0kwR2EiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfUExBWUxJU1QiLCJyb290VmUiOjU3NTQsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVkxQTEU3dFFVZFJLY3lhYng3U01Rcnl0ME9pU01YOTdJMEdhIn19fV19fX0seyJncmlkUGxheWxpc3RSZW5kZXJlciI6eyJwbGF5bGlzdElkIjoiUExFN3RRVWRSS2N5YWVSaDA4dkRuYVVXSHRyb2VwQ2pJUyIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzRyeVFnX19RVjA0L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0V4Q09BREVJNENTRnJ5cTRxcEF5TUlBUlVBQUloQ0dBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlaU0JkS0Uwd0R3PT1cdTAwMjZycz1BT240Q0xBdnFWcUNYN19nQmo1SVVqSmhxazlFdVV6ZWJBIiwid2lkdGgiOjQ4MCwiaGVpZ2h0IjoyNzB9XSwic2FtcGxlZFRodW1ibmFpbENvbG9yIjp7InJlZCI6ODksImdyZWVuIjo4MiwiYmx1ZSI6Njd9fSwidGl0bGUiOnsicnVucyI6W3sidGV4dCI6IlBHQ29uZiBOWUMgMjAyMSIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ080QkVKWTFHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUJtY3RhR2xuYUZvWVZVTlhibEJxYlhGMmJHcGpZV1pCTUhveVZURm1kMHRSbWdFRkVQSTRHR2c9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj00cnlRZ19fUVYwNFx1MDAyNmxpc3Q9UExFN3RRVWRSS2N5YWVSaDA4dkRuYVVXSHRyb2VwQ2pJU1x1MDAyNnBwPWlBUUIiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiNHJ5UWdfX1FWMDQiLCJwbGF5bGlzdElkIjoiUExFN3RRVWRSS2N5YWVSaDA4dkRuYVVXSHRyb2VwQ2pJUyIsInBhcmFtcyI6Ik9BSSUzRCIsInBsYXllclBhcmFtcyI6ImlBUUIiLCJsb2dnaW5nQ29udGV4dCI6eyJ2c3NMb2dnaW5nQ29udGV4dCI6eyJzZXJpYWxpemVkQ29udGV4dERhdGEiOiJHaUpRVEVVM2RGRlZaRkpMWTNsaFpWSm9NRGgyUkc1aFZWZElkSEp2WlhCRGFrbFQifX0sIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjItLS1zbi0yNWdsZW5lei5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9ZTJiYzkwODNmZmQwNTc0ZVx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MzM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fX1dfSwidmlkZW9Db3VudFRleHQiOnsicnVucyI6W3sidGV4dCI6IjM2In0seyJ0ZXh0IjoiwqB2aWTDqW9zIn1dfSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTzRCRUpZMUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PTRyeVFnX19RVjA0XHUwMDI2bGlzdD1QTEU3dFFVZFJLY3lhZVJoMDh2RG5hVVdIdHJvZXBDaklTXHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiI0cnlRZ19fUVYwNCIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3lhZVJoMDh2RG5hVVdIdHJvZXBDaklTIiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xoWlZKb01EaDJSRzVoVlZkSWRISnZaWEJEYWtsVCJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMi0tLXNuLTI1Z2xlbmV6Lmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1lMmJjOTA4M2ZmZDA1NzRlXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYzMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ2aWRlb0NvdW50U2hvcnRUZXh0Ijp7InNpbXBsZVRleHQiOiIzNiJ9LCJ0cmFja2luZ1BhcmFtcyI6IkNPNEJFSlkxR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJzaWRlYmFyVGh1bWJuYWlscyI6W3sidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9SQk5aMGY0UzRJMC9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhfSUZNb0V6QVBcdTAwMjZycz1BT240Q0xDOS1fVFgzQ0N0WEZScUV3Zm9IWTY1TWtWNmFBIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8yaWJ4WVdKbk93MC9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhfSUYwb0ZEQVBcdTAwMjZycz1BT240Q0xEZTdkRC0wWVRJMGVGdWgxMjJZSFBoN2pqTEJ3Iiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9pWVZ4V3B5YUdwQS9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhsSUdFb1REQVBcdTAwMjZycz1BT240Q0xBRW9WRmk3NGtwQ2lPdEtOQ2VPQ1N5VFAybkpRIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9IUEpQbng1ZEpMQS9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhsSUY4b1VUQVBcdTAwMjZycz1BT240Q0xCaGt6d1JzbHRrS2ZwRC1ySFBEN2UtT2RzMUp3Iiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19XSwidGh1bWJuYWlsVGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiMzYiLCJib2xkIjp0cnVlfSx7InRleHQiOiLCoHZpZMOpb3MifV19LCJ0aHVtYm5haWxSZW5kZXJlciI6eyJwbGF5bGlzdFZpZGVvVGh1bWJuYWlsUmVuZGVyZXIiOnsidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNHJ5UWdfX1FWMDQvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RXhDT0FERUk0Q1NGcnlxNHFwQXlNSUFSVUFBSWhDR0FId0FRSDRBZjRKZ0FMUUJZb0NEQWdBRUFFWVpTQmRLRTB3RHc9PVx1MDAyNnJzPUFPbjRDTEF2cVZxQ1g3X2dCajVJVWpKaHFrOUV1VXplYkEiLCJ3aWR0aCI6NDgwLCJoZWlnaHQiOjI3MH1dLCJzYW1wbGVkVGh1bWJuYWlsQ29sb3IiOnsicmVkIjo4OSwiZ3JlZW4iOjgyLCJibHVlIjo2N319LCJ0cmFja2luZ1BhcmFtcyI6IkNPOEJFTXZzQ1NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0ifX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5Qm90dG9tUGFuZWxSZW5kZXJlciI6eyJ0ZXh0Ijp7InNpbXBsZVRleHQiOiIzNsKgdmlkw6lvcyJ9LCJpY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RTIn19fSx7InRodW1ibmFpbE92ZXJsYXlIb3ZlclRleHRSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJUb3V0IGxpcmUifV19LCJpY29uIjp7Imljb25UeXBlIjoiUExBWV9BTEwifX19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XSwidmlld1BsYXlsaXN0VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWZmaWNoZXIgbGEgcGxheWxpc3QgY29tcGzDqHRlIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTzRCRUpZMUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvcGxheWxpc3Q/bGlzdD1QTEU3dFFVZFJLY3lhZVJoMDh2RG5hVVdIdHJvZXBDaklTIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1BMQVlMSVNUIiwicm9vdFZlIjo1NzU0LCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlZMUExFN3RRVWRSS2N5YWVSaDA4dkRuYVVXSHRyb2VwQ2pJUyJ9fX1dfX19LHsiZ3JpZFBsYXlsaXN0UmVuZGVyZXIiOnsicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeWFTMVhlbWFJUTRkN05mZ2xMVTBMUmwiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9KeFpQaDBzVnVwdy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZRHlCbEtGRXdEdz09XHUwMDI2cnM9QU9uNENMREJnQk9DaFc1RkhFODMtTzhIVzZYdXpHU3RTZyIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjEzLCJncmVlbiI6ODksImJsdWUiOjcxfX0sInRpdGxlIjp7InJ1bnMiOlt7InRleHQiOiJFbWJlckNvbmYgMjAyMSIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ093QkVKWTFHQVlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUJtY3RhR2xuYUZvWVZVTlhibEJxYlhGMmJHcGpZV1pCTUhveVZURm1kMHRSbWdFRkVQSTRHR2c9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1KeFpQaDBzVnVwd1x1MDAyNmxpc3Q9UExFN3RRVWRSS2N5YVMxWGVtYUlRNGQ3TmZnbExVMExSbFx1MDAyNnBwPWlBUUIiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiSnhaUGgwc1Z1cHciLCJwbGF5bGlzdElkIjoiUExFN3RRVWRSS2N5YVMxWGVtYUlRNGQ3TmZnbExVMExSbCIsInBhcmFtcyI6Ik9BSSUzRCIsInBsYXllclBhcmFtcyI6ImlBUUIiLCJsb2dnaW5nQ29udGV4dCI6eyJ2c3NMb2dnaW5nQ29udGV4dCI6eyJzZXJpYWxpemVkQ29udGV4dERhdGEiOiJHaUpRVEVVM2RGRlZaRkpMWTNsaFV6RllaVzFoU1ZFMFpEZE9abWRzVEZVd1RGSnMifX0sIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjQtLS1zbi0yNWdsZW5sei5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9MjcxNjRmODc0YjE1YmE5Y1x1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MjM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fX1dfSwidmlkZW9Db3VudFRleHQiOnsicnVucyI6W3sidGV4dCI6IjIzIn0seyJ0ZXh0IjoiwqB2aWTDqW9zIn1dfSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDT3dCRUpZMUdBWWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PUp4WlBoMHNWdXB3XHUwMDI2bGlzdD1QTEU3dFFVZFJLY3lhUzFYZW1hSVE0ZDdOZmdsTFUwTFJsXHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJKeFpQaDBzVnVwdyIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3lhUzFYZW1hSVE0ZDdOZmdsTFUwTFJsIiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xoVXpGWVpXMWhTVkUwWkRkT1ptZHNURlV3VEZKcyJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNC0tLXNuLTI1Z2xlbmx6Lmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD0yNzE2NGY4NzRiMTViYTljXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYyMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ2aWRlb0NvdW50U2hvcnRUZXh0Ijp7InNpbXBsZVRleHQiOiIyMyJ9LCJ0cmFja2luZ1BhcmFtcyI6IkNPd0JFSlkxR0FZaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJzaWRlYmFyVGh1bWJuYWlscyI6W3sidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9VTURkd2RmX3doRS9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhJSUYwb1pUQVBcdTAwMjZycz1BT240Q0xERmdObmE4VUcwVU9LMko2dlhYMWlpa0k1amV3Iiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9WN25ueThuOW5qby9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhsSUdVb1pUQVBcdTAwMjZycz1BT240Q0xEOFc3MV9SVk84OXQ4R0gzMHFyNU9NVF8tQ2NBIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9kVm00aWVsMUFacy9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhsSUZzb1R6QVBcdTAwMjZycz1BT240Q0xEVHZYUkRDNk1JTXpCVVNxdmltb0N6bHdvRzhnIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS80VUUxYmJZMUN5RS9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmhsSUVRb1F6QVBcdTAwMjZycz1BT240Q0xBWTNLVjkyMEg0OTNxTWhlMFI4OU9QbUdmU3ZBIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19XSwidGh1bWJuYWlsVGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiMjMiLCJib2xkIjp0cnVlfSx7InRleHQiOiLCoHZpZMOpb3MifV19LCJ0aHVtYm5haWxSZW5kZXJlciI6eyJwbGF5bGlzdFZpZGVvVGh1bWJuYWlsUmVuZGVyZXIiOnsidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvSnhaUGgwc1Z1cHcvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RXhDT0FERUk0Q1NGcnlxNHFwQXlNSUFSVUFBSWhDR0FId0FRSDRBZjRKZ0FMUUJZb0NEQWdBRUFFWUR5QmxLRkV3RHc9PVx1MDAyNnJzPUFPbjRDTERCZ0JPQ2hXNUZIRTgzLU84SFc2WHV6R1N0U2ciLCJ3aWR0aCI6NDgwLCJoZWlnaHQiOjI3MH1dLCJzYW1wbGVkVGh1bWJuYWlsQ29sb3IiOnsicmVkIjoxMywiZ3JlZW4iOjg5LCJibHVlIjo3MX19LCJ0cmFja2luZ1BhcmFtcyI6IkNPMEJFTXZzQ1NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0ifX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5Qm90dG9tUGFuZWxSZW5kZXJlciI6eyJ0ZXh0Ijp7InNpbXBsZVRleHQiOiIyM8Kgdmlkw6lvcyJ9LCJpY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RTIn19fSx7InRodW1ibmFpbE92ZXJsYXlIb3ZlclRleHRSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJUb3V0IGxpcmUifV19LCJpY29uIjp7Imljb25UeXBlIjoiUExBWV9BTEwifX19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XSwidmlld1BsYXlsaXN0VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWZmaWNoZXIgbGEgcGxheWxpc3QgY29tcGzDqHRlIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDT3dCRUpZMUdBWWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvcGxheWxpc3Q/bGlzdD1QTEU3dFFVZFJLY3lhUzFYZW1hSVE0ZDdOZmdsTFUwTFJsIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1BMQVlMSVNUIiwicm9vdFZlIjo1NzU0LCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlZMUExFN3RRVWRSS2N5YVMxWGVtYUlRNGQ3TmZnbExVMExSbCJ9fX1dfX19LHsiZ3JpZFBsYXlsaXN0UmVuZGVyZXIiOnsicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeWFuM2lzVVBnQl9mRVI0ZU05SnM2cEEiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9UTkZsamhjb0h2US9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZWlNCaEtGZ3dEdz09XHUwMDI2cnM9QU9uNENMQzhmbFJEc091MHdJcll1SkdTLWxPQWV6TXdzdyIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjg5LCJncmVlbiI6ODUsImJsdWUiOjc3fX0sInRpdGxlIjp7InJ1bnMiOlt7InRleHQiOiJSYWlsc0NvbmYgMjAyMSIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ09vQkVKWTFHQWNpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUJtY3RhR2xuYUZvWVZVTlhibEJxYlhGMmJHcGpZV1pCTUhveVZURm1kMHRSbWdFRkVQSTRHR2c9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1UTkZsamhjb0h2UVx1MDAyNmxpc3Q9UExFN3RRVWRSS2N5YW4zaXNVUGdCX2ZFUjRlTTlKczZwQVx1MDAyNnBwPWlBUUIiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiVE5GbGpoY29IdlEiLCJwbGF5bGlzdElkIjoiUExFN3RRVWRSS2N5YW4zaXNVUGdCX2ZFUjRlTTlKczZwQSIsInBhcmFtcyI6Ik9BSSUzRCIsInBsYXllclBhcmFtcyI6ImlBUUIiLCJsb2dnaW5nQ29udGV4dCI6eyJ2c3NMb2dnaW5nQ29udGV4dCI6eyJzZXJpYWxpemVkQ29udGV4dERhdGEiOiJHaUpRVEVVM2RGRlZaRkpMWTNsaGJqTnBjMVZRWjBKZlprVlNOR1ZOT1Vwek5uQkIifX0sIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjktLS1zbi00Z3h4LTI1Z2U3Lmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD00Y2QxNjU4ZTE3MjgxZWY0XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTM5MTI1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19fV19LCJ2aWRlb0NvdW50VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiNzIifSx7InRleHQiOiLCoHZpZMOpb3MifV19LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNPb0JFSlkxR0FjaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lCbWN0YUdsbmFGb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9VE5GbGpoY29IdlFcdTAwMjZsaXN0PVBMRTd0UVVkUktjeWFuM2lzVVBnQl9mRVI0ZU05SnM2cEFcdTAwMjZwcD1pQVFCIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IlRORmxqaGNvSHZRIiwicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeWFuM2lzVVBnQl9mRVI0ZU05SnM2cEEiLCJwYXJhbXMiOiJPQUklM0QiLCJwbGF5ZXJQYXJhbXMiOiJpQVFCIiwibG9nZ2luZ0NvbnRleHQiOnsidnNzTG9nZ2luZ0NvbnRleHQiOnsic2VyaWFsaXplZENvbnRleHREYXRhIjoiR2lKUVRFVTNkRkZWWkZKTFkzbGhiak5wYzFWUVowSmZaa1ZTTkdWTk9VcHpObkJCIn19LCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnI5LS0tc24tNGd4eC0yNWdlNy5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9NGNkMTY1OGUxNzI4MWVmNFx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz0zOTEyNTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidmlkZW9Db3VudFNob3J0VGV4dCI6eyJzaW1wbGVUZXh0IjoiNzIifSwidHJhY2tpbmdQYXJhbXMiOiJDT29CRUpZMUdBY2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2lkZWJhclRodW1ibmFpbHMiOlt7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvRnpLMGlIeVFSMGsvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJobElFOG9SakFQXHUwMDI2cnM9QU9uNENMRFBic3BQYkdtYnY0dXdabEdmaW9wSGpYNGFQUSIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfSx7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNWJXRTZHcE45MzgvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJnZElHVW9ZREFQXHUwMDI2cnM9QU9uNENMQ3NDcjVDZVF2X21id3F3QVlITDVpa1k4elJ5QSIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfSx7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvalNFOWZYZ2lxaWcvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJobElHVW9aVEFQXHUwMDI2cnM9QU9uNENMQ2NqaVBWUjlWcGtvZDVOT1NpVHBBN3BYVV9JZyIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfSx7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvdkQwOHFUTllPOWMvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJobElHVW9aVEFQXHUwMDI2cnM9QU9uNENMQy0tSHpVVFJUTDd5T0V0c2s1V0QtSXExMGpnUSIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfV0sInRodW1ibmFpbFRleHQiOnsicnVucyI6W3sidGV4dCI6IjcyIiwiYm9sZCI6dHJ1ZX0seyJ0ZXh0IjoiwqB2aWTDqW9zIn1dfSwidGh1bWJuYWlsUmVuZGVyZXIiOnsicGxheWxpc3RWaWRlb1RodW1ibmFpbFJlbmRlcmVyIjp7InRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1RORmxqaGNvSHZRL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0V4Q09BREVJNENTRnJ5cTRxcEF5TUlBUlVBQUloQ0dBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlaU0JoS0Znd0R3PT1cdTAwMjZycz1BT240Q0xDOGZsUkRzT3Uwd0lyWXVKR1MtbE9BZXpNd3N3Iiwid2lkdGgiOjQ4MCwiaGVpZ2h0IjoyNzB9XSwic2FtcGxlZFRodW1ibmFpbENvbG9yIjp7InJlZCI6ODksImdyZWVuIjo4NSwiYmx1ZSI6Nzd9fSwidHJhY2tpbmdQYXJhbXMiOiJDT3NCRU12c0NTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09In19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheUJvdHRvbVBhbmVsUmVuZGVyZXIiOnsidGV4dCI6eyJzaW1wbGVUZXh0IjoiNzLCoHZpZMOpb3MifSwiaWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUUyJ9fX0seyJ0aHVtYm5haWxPdmVybGF5SG92ZXJUZXh0UmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiVG91dCBsaXJlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlBMQVlfQUxMIn19fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV0sInZpZXdQbGF5bGlzdFRleHQiOnsicnVucyI6W3sidGV4dCI6IkFmZmljaGVyIGxhIHBsYXlsaXN0IGNvbXBsw6h0ZSIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ09vQkVKWTFHQWNpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUJtY3RhR2xuYUE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3BsYXlsaXN0P2xpc3Q9UExFN3RRVWRSS2N5YW4zaXNVUGdCX2ZFUjRlTTlKczZwQSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9QTEFZTElTVCIsInJvb3RWZSI6NTc1NCwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJWTFBMRTd0UVVkUktjeWFuM2lzVVBnQl9mRVI0ZU05SnM2cEEifX19XX19fSx7ImdyaWRQbGF5bGlzdFJlbmRlcmVyIjp7InBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3laaFRWMnFhVkk1Uk82Q0s5LS1tY0Z3IiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvT2V3ajlKTTdvOUUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RXhDT0FERUk0Q1NGcnlxNHFwQXlNSUFSVUFBSWhDR0FId0FRSDRBZjRPZ0FLNENJb0NEQWdBRUFFWVpTQkhLRWN3RHc9PVx1MDAyNnJzPUFPbjRDTEFlY180Q0VDTFFpN0ZhWWFBWkhwUzNWbkFlYXciLCJ3aWR0aCI6NDgwLCJoZWlnaHQiOjI3MH1dLCJzYW1wbGVkVGh1bWJuYWlsQ29sb3IiOnsicmVkIjo4OSwiZ3JlZW4iOjYyLCJibHVlIjo2Mn19LCJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiR1JDb24gMjAyMSIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ09nQkVKWTFHQWdpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUJtY3RhR2xuYUZvWVZVTlhibEJxYlhGMmJHcGpZV1pCTUhveVZURm1kMHRSbWdFRkVQSTRHR2c9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1PZXdqOUpNN285RVx1MDAyNmxpc3Q9UExFN3RRVWRSS2N5WmhUVjJxYVZJNVJPNkNLOS0tbWNGd1x1MDAyNnBwPWlBUUIiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiT2V3ajlKTTdvOUUiLCJwbGF5bGlzdElkIjoiUExFN3RRVWRSS2N5WmhUVjJxYVZJNVJPNkNLOS0tbWNGdyIsInBhcmFtcyI6Ik9BSSUzRCIsInBsYXllclBhcmFtcyI6ImlBUUIiLCJsb2dnaW5nQ29udGV4dCI6eyJ2c3NMb2dnaW5nQ29udGV4dCI6eyJzZXJpYWxpemVkQ29udGV4dERhdGEiOiJHaUpRVEVVM2RGRlZaRkpMWTNsYWFGUldNbkZoVmtrMVVrODJRMHM1TFMxdFkwWjMifX0sIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjItLS1zbi0yNWdsZW5lcy5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9MzllYzIzZjQ5MzNiYTNkMVx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MzM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fX1dfSwidmlkZW9Db3VudFRleHQiOnsicnVucyI6W3sidGV4dCI6IjY3In0seyJ0ZXh0IjoiwqB2aWTDqW9zIn1dfSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDT2dCRUpZMUdBZ2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PU9ld2o5Sk03bzlFXHUwMDI2bGlzdD1QTEU3dFFVZFJLY3laaFRWMnFhVkk1Uk82Q0s5LS1tY0Z3XHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJPZXdqOUpNN285RSIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3laaFRWMnFhVkk1Uk82Q0s5LS1tY0Z3IiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xhYUZSV01uRmhWa2sxVWs4MlEwczVMUzF0WTBaMyJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMi0tLXNuLTI1Z2xlbmVzLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD0zOWVjMjNmNDkzM2JhM2QxXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYzMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ2aWRlb0NvdW50U2hvcnRUZXh0Ijp7InNpbXBsZVRleHQiOiI2NyJ9LCJ0cmFja2luZ1BhcmFtcyI6IkNPZ0JFSlkxR0FnaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJzaWRlYmFyVGh1bWJuYWlscyI6W3sidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8wa0NScmhlR0NXQS9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nNkFBcmdJaWdJTUNBQVFBUmhfSUVRb0d6QVBcdTAwMjZycz1BT240Q0xDMk9yeHl6Q3FPdVRrLWFYX3JxMEl5WG9XRll3Iiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xbWlPT1ZxRDYzQS9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nNkFBcmdJaWdJTUNBQVFBUmhfSURvb0pqQVBcdTAwMjZycz1BT240Q0xDTmhDS2pyVXhEdHNDa2pITV9ONFRWYkZRSlJBIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9ucEpOWHhmdlEtTS9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nNkFBcmdJaWdJTUNBQVFBUmhfSURrb0lUQVBcdTAwMjZycz1BT240Q0xEbmx5OENpck5uVGtlRzA5cngzLWlUQUcwLUlnIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19LHsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS94T3ZtMGpWR3I3dy9kZWZhdWx0LmpwZz9zcXA9LW9heW13RWtDSGdRV3ZLcmlxa0RHdkFCQWZnQl9nNkFBcmdJaWdJTUNBQVFBUmhfSURvb0lqQVBcdTAwMjZycz1BT240Q0xDTlpHRlpBeTUyWUxqMi1WckxOTHpYOWtUalhRIiwid2lkdGgiOjQzLCJoZWlnaHQiOjIwfV19XSwidGh1bWJuYWlsVGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiNjciLCJib2xkIjp0cnVlfSx7InRleHQiOiLCoHZpZMOpb3MifV19LCJ0aHVtYm5haWxSZW5kZXJlciI6eyJwbGF5bGlzdFZpZGVvVGh1bWJuYWlsUmVuZGVyZXIiOnsidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvT2V3ajlKTTdvOUUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RXhDT0FERUk0Q1NGcnlxNHFwQXlNSUFSVUFBSWhDR0FId0FRSDRBZjRPZ0FLNENJb0NEQWdBRUFFWVpTQkhLRWN3RHc9PVx1MDAyNnJzPUFPbjRDTEFlY180Q0VDTFFpN0ZhWWFBWkhwUzNWbkFlYXciLCJ3aWR0aCI6NDgwLCJoZWlnaHQiOjI3MH1dLCJzYW1wbGVkVGh1bWJuYWlsQ29sb3IiOnsicmVkIjo4OSwiZ3JlZW4iOjYyLCJibHVlIjo2Mn19LCJ0cmFja2luZ1BhcmFtcyI6IkNPa0JFTXZzQ1NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0ifX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5Qm90dG9tUGFuZWxSZW5kZXJlciI6eyJ0ZXh0Ijp7InNpbXBsZVRleHQiOiI2N8Kgdmlkw6lvcyJ9LCJpY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RTIn19fSx7InRodW1ibmFpbE92ZXJsYXlIb3ZlclRleHRSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJUb3V0IGxpcmUifV19LCJpY29uIjp7Imljb25UeXBlIjoiUExBWV9BTEwifX19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XSwidmlld1BsYXlsaXN0VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWZmaWNoZXIgbGEgcGxheWxpc3QgY29tcGzDqHRlIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDT2dCRUpZMUdBZ2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvcGxheWxpc3Q/bGlzdD1QTEU3dFFVZFJLY3laaFRWMnFhVkk1Uk82Q0s5LS1tY0Z3Iiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1BMQVlMSVNUIiwicm9vdFZlIjo1NzU0LCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlZMUExFN3RRVWRSS2N5WmhUVjJxYVZJNVJPNkNLOS0tbWNGdyJ9fX1dfX19LHsiZ3JpZFBsYXlsaXN0UmVuZGVyZXIiOnsicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeWFCeUQza25LMHhwbjN1M2NyTHEwSjMiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9USk1IT2xEcktOWS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFkUUdnQUxnQTRvQ0RBZ0FFQUVZWnlCbktHY3dEdz09XHUwMDI2cnM9QU9uNENMQUpZLVNxTndlc1VNWWpXaUx1bTBrYzZvWFJhUSIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjkxLCJncmVlbiI6OTEsImJsdWUiOjkxfX0sInRpdGxlIjp7InJ1bnMiOlt7InRleHQiOiJHUkNvbiAyMDIwIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDT1lCRUpZMUdBa2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PVRKTUhPbERyS05ZXHUwMDI2bGlzdD1QTEU3dFFVZFJLY3lhQnlEM2tuSzB4cG4zdTNjckxxMEozXHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJUSk1IT2xEcktOWSIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3lhQnlEM2tuSzB4cG4zdTNjckxxMEozIiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xoUW5sRU0ydHVTekI0Y0c0emRUTmpja3h4TUVveiJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMi0tLXNuLTI1Z2xlbmxkLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD00YzkzMDczYTUwZWIyOGQ2XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTY0ODc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19fV19LCJ2aWRlb0NvdW50VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiMzIifSx7InRleHQiOiLCoHZpZMOpb3MifV19LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNPWUJFSlkxR0FraUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lCbWN0YUdsbmFGb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9VEpNSE9sRHJLTllcdTAwMjZsaXN0PVBMRTd0UVVkUktjeWFCeUQza25LMHhwbjN1M2NyTHEwSjNcdTAwMjZwcD1pQVFCIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IlRKTUhPbERyS05ZIiwicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeWFCeUQza25LMHhwbjN1M2NyTHEwSjMiLCJwYXJhbXMiOiJPQUklM0QiLCJwbGF5ZXJQYXJhbXMiOiJpQVFCIiwibG9nZ2luZ0NvbnRleHQiOnsidnNzTG9nZ2luZ0NvbnRleHQiOnsic2VyaWFsaXplZENvbnRleHREYXRhIjoiR2lKUVRFVTNkRkZWWkZKTFkzbGhRbmxFTTJ0dVN6QjRjRzR6ZFROamNreHhNRW96In19LCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIyLS0tc24tMjVnbGVubGQuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTRjOTMwNzNhNTBlYjI4ZDZcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjQ4NzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInZpZGVvQ291bnRTaG9ydFRleHQiOnsic2ltcGxlVGV4dCI6IjMyIn0sInRyYWNraW5nUGFyYW1zIjoiQ09ZQkVKWTFHQWtpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNpZGViYXJUaHVtYm5haWxzIjpbeyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzY0aUI0LVdxaEs4L2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCMUFhQUF1QURpZ0lNQ0FBUUFSaHNJR3dvYkRBUFx1MDAyNnJzPUFPbjRDTEFJSW0ydDF6NWg5VXVral9DWHhUQWNFckdQRkEiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1Nyb09Kd3FZOXNBL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCMUFhQUF1QURpZ0lNQ0FBUUFSaGxJR1VvWlRBUFx1MDAyNnJzPUFPbjRDTEFnYmlLWU45MFRBZnFJLTFBLVlJU3pyREZVaFEiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1JFY0hfaUhzdVowL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCMUFhQUF1QURpZ0lNQ0FBUUFSaHNJR3dvYkRBUFx1MDAyNnJzPUFPbjRDTEFYdGV6ak1ic0FYN215bkRiTzAyUUJ6YlBBMGciLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzNSUk1HaXREWGgwL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCMUFhQUF1QURpZ0lNQ0FBUUFSaGxJRjBvUnpBUFx1MDAyNnJzPUFPbjRDTEJoOHc1NDBzX3NzMkVkbm1PaFZYdVlzMGlkZGciLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX1dLCJ0aHVtYm5haWxUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiIzMiIsImJvbGQiOnRydWV9LHsidGV4dCI6IsKgdmlkw6lvcyJ9XX0sInRodW1ibmFpbFJlbmRlcmVyIjp7InBsYXlsaXN0VmlkZW9UaHVtYm5haWxSZW5kZXJlciI6eyJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9USk1IT2xEcktOWS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFkUUdnQUxnQTRvQ0RBZ0FFQUVZWnlCbktHY3dEdz09XHUwMDI2cnM9QU9uNENMQUpZLVNxTndlc1VNWWpXaUx1bTBrYzZvWFJhUSIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjkxLCJncmVlbiI6OTEsImJsdWUiOjkxfX0sInRyYWNraW5nUGFyYW1zIjoiQ09jQkVNdnNDU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSJ9fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlCb3R0b21QYW5lbFJlbmRlcmVyIjp7InRleHQiOnsic2ltcGxlVGV4dCI6IjMywqB2aWTDqW9zIn0sImljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVFMifX19LHsidGh1bWJuYWlsT3ZlcmxheUhvdmVyVGV4dFJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlRvdXQgbGlyZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJQTEFZX0FMTCJ9fX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dLCJ2aWV3UGxheWxpc3RUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBZmZpY2hlciBsYSBwbGF5bGlzdCBjb21wbMOodGUiLCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNPWUJFSlkxR0FraUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lCbWN0YUdsbmFBPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9wbGF5bGlzdD9saXN0PVBMRTd0UVVkUktjeWFCeUQza25LMHhwbjN1M2NyTHEwSjMiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfUExBWUxJU1QiLCJyb290VmUiOjU3NTQsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVkxQTEU3dFFVZFJLY3lhQnlEM2tuSzB4cG4zdTNjckxxMEozIn19fV19fX0seyJncmlkUGxheWxpc3RSZW5kZXJlciI6eyJwbGF5bGlzdElkIjoiUExFN3RRVWRSS2N5WkFOWXhsODlGOEI5bndDSjI1amhheSIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0FPSDJhRzlBRUZ3L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0V4Q09BREVJNENTRnJ5cTRxcEF5TUlBUlVBQUloQ0dBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlKeUJGS0g4d0R3PT1cdTAwMjZycz1BT240Q0xBc0NzdlFvblM2ZDF3dW9ZY083MTJ2YThUMWlnIiwid2lkdGgiOjQ4MCwiaGVpZ2h0IjoyNzB9XSwic2FtcGxlZFRodW1ibmFpbENvbG9yIjp7InJlZCI6MzUsImdyZWVuIjo2MiwiYmx1ZSI6MTE0fX0sInRpdGxlIjp7InJ1bnMiOlt7InRleHQiOiJSRWRlcGxveSAyMDE5IiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDT1FCRUpZMUdBb2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PUFPSDJhRzlBRUZ3XHUwMDI2bGlzdD1QTEU3dFFVZFJLY3laQU5ZeGw4OUY4Qjlud0NKMjVqaGF5XHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJBT0gyYUc5QUVGdyIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3laQU5ZeGw4OUY4Qjlud0NKMjVqaGF5IiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xhUVU1WmVHdzRPVVk0UWpsdWQwTktNalZxYUdGNSJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNS0tLXNuLTI1Z2xlbmx6Lmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD0wMGUxZjY2ODZmNDAxMDVjXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYyMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19fV19LCJ2aWRlb0NvdW50VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiMTYifSx7InRleHQiOiLCoHZpZMOpb3MifV19LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNPUUJFSlkxR0FvaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lCbWN0YUdsbmFGb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dnPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9QU9IMmFHOUFFRndcdTAwMjZsaXN0PVBMRTd0UVVkUktjeVpBTll4bDg5RjhCOW53Q0oyNWpoYXlcdTAwMjZwcD1pQVFCIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IkFPSDJhRzlBRUZ3IiwicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeVpBTll4bDg5RjhCOW53Q0oyNWpoYXkiLCJwYXJhbXMiOiJPQUklM0QiLCJwbGF5ZXJQYXJhbXMiOiJpQVFCIiwibG9nZ2luZ0NvbnRleHQiOnsidnNzTG9nZ2luZ0NvbnRleHQiOnsic2VyaWFsaXplZENvbnRleHREYXRhIjoiR2lKUVRFVTNkRkZWWkZKTFkzbGFRVTVaZUd3NE9VWTRRamx1ZDBOS01qVnFhR0Y1In19LCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnI1LS0tc24tMjVnbGVubHouZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTAwZTFmNjY4NmY0MDEwNWNcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjIzNzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInZpZGVvQ291bnRTaG9ydFRleHQiOnsic2ltcGxlVGV4dCI6IjE2In0sInRyYWNraW5nUGFyYW1zIjoiQ09RQkVKWTFHQW9pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNpZGViYXJUaHVtYm5haWxzIjpbeyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2lFM3FTWTgyRklZL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ3BJRWdvZnpBUFx1MDAyNnJzPUFPbjRDTEI2QTJfeDl0bkFTZ3MxWFprWDZUWTBwbzZVaVEiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzA3WUNOMkljQkNjL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ25JRVVvZnpBUFx1MDAyNnJzPUFPbjRDTEFuRUNxSmllT01nZHR0WUt4VDFyYlNKZFZ3MnciLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLy1lck1GUlVVVUVBL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ29JRVFvZnpBUFx1MDAyNnJzPUFPbjRDTENIV18tc1lUU3lZc0N2NnF1YjJvWmpmWGtwS1EiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX0seyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0R4bFd4QXlmbUFBL2RlZmF1bHQuanBnP3NxcD0tb2F5bXdFa0NIZ1FXdktyaXFrREd2QUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ29JRVlvZnpBUFx1MDAyNnJzPUFPbjRDTEJhdkdWdlJ1N2Q3aXZ5MWltS3N5SWo2dFl3cVEiLCJ3aWR0aCI6NDMsImhlaWdodCI6MjB9XX1dLCJ0aHVtYm5haWxUZXh0Ijp7InJ1bnMiOlt7InRleHQiOiIxNiIsImJvbGQiOnRydWV9LHsidGV4dCI6IsKgdmlkw6lvcyJ9XX0sInRodW1ibmFpbFJlbmRlcmVyIjp7InBsYXlsaXN0VmlkZW9UaHVtYm5haWxSZW5kZXJlciI6eyJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9BT0gyYUc5QUVGdy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZSnlCRktIOHdEdz09XHUwMDI2cnM9QU9uNENMQXNDc3ZRb25TNmQxd3VvWWNPNzEydmE4VDFpZyIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjM1LCJncmVlbiI6NjIsImJsdWUiOjExNH19LCJ0cmFja2luZ1BhcmFtcyI6IkNPVUJFTXZzQ1NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0ifX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5Qm90dG9tUGFuZWxSZW5kZXJlciI6eyJ0ZXh0Ijp7InNpbXBsZVRleHQiOiIxNsKgdmlkw6lvcyJ9LCJpY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RTIn19fSx7InRodW1ibmFpbE92ZXJsYXlIb3ZlclRleHRSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJUb3V0IGxpcmUifV19LCJpY29uIjp7Imljb25UeXBlIjoiUExBWV9BTEwifX19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XSwidmlld1BsYXlsaXN0VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWZmaWNoZXIgbGEgcGxheWxpc3QgY29tcGzDqHRlIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDT1FCRUpZMUdBb2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvcGxheWxpc3Q/bGlzdD1QTEU3dFFVZFJLY3laQU5ZeGw4OUY4Qjlud0NKMjVqaGF5Iiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1BMQVlMSVNUIiwicm9vdFZlIjo1NzU0LCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlZMUExFN3RRVWRSS2N5WkFOWXhsODlGOEI5bndDSjI1amhheSJ9fX1dfX19LHsiZ3JpZFBsYXlsaXN0UmVuZGVyZXIiOnsicGxheWxpc3RJZCI6IlBMRTd0UVVkUktjeVlWbldoRFFrNFJDUFZsTVc0MEk2czUiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9zQXU4VVVuVmNfWS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZWlNCbEtHVXdEdz09XHUwMDI2cnM9QU9uNENMQXQ4ck9Da21VeWVTQ09rNjVzcVhkSU9Nakc4USIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjg5LCJncmVlbiI6ODksImJsdWUiOjg5fX0sInRpdGxlIjp7InJ1bnMiOlt7InRleHQiOiJSdWJ5Q29uZiAyMDIxIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDT0lCRUpZMUdBc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PXNBdThVVW5WY19ZXHUwMDI2bGlzdD1QTEU3dFFVZFJLY3lZVm5XaERRazRSQ1BWbE1XNDBJNnM1XHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJzQXU4VVVuVmNfWSIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3lZVm5XaERRazRSQ1BWbE1XNDBJNnM1IiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xaVm01WGFFUlJhelJTUTFCV2JFMVhOREJKTm5NMSJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMTAtLS1zbi00Z3h4LTI1Z2VlLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1iMDBiYmM1MTQ5ZDU3M2Y2XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTQ1NzUwMFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19fV19LCJ2aWRlb0NvdW50VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiMTAyIn0seyJ0ZXh0IjoiwqB2aWTDqW9zIn1dfSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDT0lCRUpZMUdBc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hRm9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHZz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PXNBdThVVW5WY19ZXHUwMDI2bGlzdD1QTEU3dFFVZFJLY3lZVm5XaERRazRSQ1BWbE1XNDBJNnM1XHUwMDI2cHA9aUFRQiIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJzQXU4VVVuVmNfWSIsInBsYXlsaXN0SWQiOiJQTEU3dFFVZFJLY3lZVm5XaERRazRSQ1BWbE1XNDBJNnM1IiwicGFyYW1zIjoiT0FJJTNEIiwicGxheWVyUGFyYW1zIjoiaUFRQiIsImxvZ2dpbmdDb250ZXh0Ijp7InZzc0xvZ2dpbmdDb250ZXh0Ijp7InNlcmlhbGl6ZWRDb250ZXh0RGF0YSI6IkdpSlFURVUzZEZGVlpGSkxZM2xaVm01WGFFUlJhelJTUTFCV2JFMVhOREJKTm5NMSJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMTAtLS1zbi00Z3h4LTI1Z2VlLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1iMDBiYmM1MTQ5ZDU3M2Y2XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTQ1NzUwMFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ2aWRlb0NvdW50U2hvcnRUZXh0Ijp7InNpbXBsZVRleHQiOiIxMDIifSwidHJhY2tpbmdQYXJhbXMiOiJDT0lCRUpZMUdBc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2lkZWJhclRodW1ibmFpbHMiOlt7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNHZEZmVncmpVdFEvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJoeUlFY29LREFQXHUwMDI2cnM9QU9uNENMQkxrRklHLW5zRE5RS0ZVcnE3QWRQcmU1SnF6USIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfSx7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvRzVaZGxxcWhZRU0vZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJoUklEd29mekFQXHUwMDI2cnM9QU9uNENMQmkyZi1jOVE3QkFsS0ptdHdQWkNsNVRIM3laZyIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfSx7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvcGR4V1k1RWJtMmsvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJobElHTW9VekFQXHUwMDI2cnM9QU9uNENMRE05RlE5ajhraU5CaGpKYzAtRnFMZjZhdFlCUSIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfSx7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvdkxRRXNHNU1NOEUvZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VrQ0hnUVd2S3JpcWtER3ZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJoX0lGOG9GakFQXHUwMDI2cnM9QU9uNENMQ0ViaGFMNWR2WnZMSWNoajlBaW5kcEdsSS13QSIsIndpZHRoIjo0MywiaGVpZ2h0IjoyMH1dfV0sInRodW1ibmFpbFRleHQiOnsicnVucyI6W3sidGV4dCI6IjEwMiIsImJvbGQiOnRydWV9LHsidGV4dCI6IsKgdmlkw6lvcyJ9XX0sInRodW1ibmFpbFJlbmRlcmVyIjp7InBsYXlsaXN0VmlkZW9UaHVtYm5haWxSZW5kZXJlciI6eyJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9zQXU4VVVuVmNfWS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFeENPQURFSTRDU0ZyeXE0cXBBeU1JQVJVQUFJaENHQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZWlNCbEtHVXdEdz09XHUwMDI2cnM9QU9uNENMQXQ4ck9Da21VeWVTQ09rNjVzcVhkSU9Nakc4USIsIndpZHRoIjo0ODAsImhlaWdodCI6MjcwfV0sInNhbXBsZWRUaHVtYm5haWxDb2xvciI6eyJyZWQiOjg5LCJncmVlbiI6ODksImJsdWUiOjg5fX0sInRyYWNraW5nUGFyYW1zIjoiQ09NQkVNdnNDU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSJ9fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlCb3R0b21QYW5lbFJlbmRlcmVyIjp7InRleHQiOnsic2ltcGxlVGV4dCI6IjEwMsKgdmlkw6lvcyJ9LCJpY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RTIn19fSx7InRodW1ibmFpbE92ZXJsYXlIb3ZlclRleHRSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJUb3V0IGxpcmUifV19LCJpY29uIjp7Imljb25UeXBlIjoiUExBWV9BTEwifX19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XSwidmlld1BsYXlsaXN0VGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWZmaWNoZXIgbGEgcGxheWxpc3QgY29tcGzDqHRlIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDT0lCRUpZMUdBc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Qm1jdGFHbG5hQT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvcGxheWxpc3Q/bGlzdD1QTEU3dFFVZFJLY3lZVm5XaERRazRSQ1BWbE1XNDBJNnM1Iiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1BMQVlMSVNUIiwicm9vdFZlIjo1NzU0LCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlZMUExFN3RRVWRSS2N5WVZuV2hEUWs0UkNQVmxNVzQwSTZzNSJ9fX1dfX19XSwidHJhY2tpbmdQYXJhbXMiOiJDTjhCRU1ZNUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJ2aXNpYmxlSXRlbUNvdW50Ijo0LCJuZXh0QnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfREVGQVVMVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwiaWNvbiI6eyJpY29uVHlwZSI6IkNIRVZST05fUklHSFQifSwiYWNjZXNzaWJpbGl0eSI6eyJsYWJlbCI6IlN1aXZhbnQifSwidHJhY2tpbmdQYXJhbXMiOiJDT0VCRVBCYkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0sInByZXZpb3VzQnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfREVGQVVMVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwiaWNvbiI6eyJpY29uVHlwZSI6IkNIRVZST05fTEVGVCJ9LCJhY2Nlc3NpYmlsaXR5Ijp7ImxhYmVsIjoiUHLDqWPDqWRlbnRlIn0sInRyYWNraW5nUGFyYW1zIjoiQ09BQkVQQmJJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19fX0sInRyYWNraW5nUGFyYW1zIjoiQ040QkVOd2NHQUFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fV0sInRyYWNraW5nUGFyYW1zIjoiQ04wQkVMc3ZHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7Iml0ZW1TZWN0aW9uUmVuZGVyZXIiOnsiY29udGVudHMiOlt7InNoZWxmUmVuZGVyZXIiOnsidGl0bGUiOnsicnVucyI6W3sidGV4dCI6IlZpZMOpb3MiLCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKd0JFTndjR0FBaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AQ29uZnJlYWtzL3ZpZGVvcz92aWV3PTBcdTAwMjZzb3J0PWRkXHUwMDI2c2hlbGZfaWQ9MCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9DSEFOTkVMIiwicm9vdFZlIjozNjExLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsInBhcmFtcyI6IkVnWjJhV1JsYjNNWUF5QUFjQUR5QmdzS0NUb0NDQUdpQVFJSUFRJTNEJTNEIiwiY2Fub25pY2FsQmFzZVVybCI6Ii9AQ29uZnJlYWtzIn19fV19LCJlbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0p3QkVOd2NHQUFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL0BDb25mcmVha3MvdmlkZW9zP3ZpZXc9MFx1MDAyNnNvcnQ9ZGRcdTAwMjZzaGVsZl9pZD0wIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwicGFyYW1zIjoiRWdaMmFXUmxiM01ZQXlBQWNBRHlCZ3NLQ1RvQ0NBR2lBUUlJQVElM0QlM0QiLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BDb25mcmVha3MifX0sImNvbnRlbnQiOnsiaG9yaXpvbnRhbExpc3RSZW5kZXJlciI6eyJpdGVtcyI6W3siZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6InpPeklsc0RLZ2UwIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvek96SWxzREtnZTAvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDS2dCRUY1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV2pBUFx1MDAyNnJzPUFPbjRDTEF5OFFXdDlrVkRBNlp4ajRyeWE5WXhlamhUS1EiLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvek96SWxzREtnZTAvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDTVFCRUc1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV2pBUFx1MDAyNnJzPUFPbjRDTEMzMU5DbHhNbnprUk9JRHByV1dkNmhfQl96THciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3pPeklsc0RLZ2UwL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U5Q1BZQkVJb0JTRnJ5cTRxcEF5OElBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZR2lCbEtGb3dEdz09XHUwMDI2cnM9QU9uNENMQWdhX3VuUVFFTnJtOXhaS3N6cW9BSWN0a0h6USIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvek96SWxzREtnZTAvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RTlDTkFDRUx3QlNGcnlxNHFwQXk4SUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlHaUJsS0Zvd0R3PT1cdTAwMjZycz1BT240Q0xCTjh6U3BrZlR5SjBSTHVDMDAtcXAwMUl0QXFRIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIhIUNvbiAyMDIyIC0gU2hoaCwgTWVldCBNZSBhdCBNaWRuaWdodCEhISAoQXVkaW8gU3RlZ2Fub2dyYXBoeSBpbiBQeXRob24pIGJ5IE1hcmxlbmUgTWhhbmdhbWkgZGUgQ29uZnJlYWtzIGlsIHkgYSAyIG1vaXMgMTAgbWludXRlcyBldCAxOcKgc2Vjb25kZXMgMTA2wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiISFDb24gMjAyMiAtIFNoaGgsIE1lZXQgTWUgYXQgTWlkbmlnaHQhISEgKEF1ZGlvIFN0ZWdhbm9ncmFwaHkgaW4gUHl0aG9uKSBieSBNYXJsZW5lIE1oYW5nYW1pIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgMiBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjEwNsKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOZ0JFSlExR0FBaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lDbWN0YUdsbmFDMWpjblphR0ZWRFYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVWm9CQlJEeU9CaG1xZ0VhVlZWTVJsZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj16T3pJbHNES2dlMCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJ6T3pJbHNES2dlMCIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjEtLS1zbi0yNWdsZW5sci5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9Y2NlY2M4OTZjMGNhODFlZFx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02NDg3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDTmdCRUpRMUdBQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGxBN1lPcWh1eVNzdmJNQWFvQkdsVlZURVpYYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0UiIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTA2wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTA2wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ053QkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ053QkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiek96SWxzREtnZTAiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ053QkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbInpPeklsc0RLZ2UwIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiek96SWxzREtnZTAiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNOd0JFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOZ0JFSlExR0FBaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3Q2VDNwSmJITkVTMmRsTUElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOZ0JFSlExR0FBaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNOc0JFSTVpSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNOZ0JFSlExR0FBaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ05nQkVKUTFHQUFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxMCBtaW51dGVzIGV0IDE5wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjEwOjE5In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ05vQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiek96SWxzREtnZTAiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOb0JFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6InpPeklsc0RLZ2UwIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ05vQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTmtCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTmtCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJ6T3pJbHNES2dlMCIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTmtCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiek96SWxzREtnZTAiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJ6T3pJbHNES2dlMCJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNOa0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiZkg2eWp3X1BsRVUiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9mSDZ5andfUGxFVS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFOENLZ0JFRjVJV3ZLcmlxa0RMd2dCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QWZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJnYUlHVW9XekFQXHUwMDI2cnM9QU9uNENMQnF3dGFaY3NMVkw5bnNXakhoOUlZclUtX2EzQSIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9mSDZ5andfUGxFVS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFOENNUUJFRzVJV3ZLcmlxa0RMd2dCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QWZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJnYUlHVW9XekFQXHUwMDI2cnM9QU9uNENMQXVfWFZ3V0JlMnJuWTJaMDYwemtuU1FNQU5vdyIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvZkg2eWp3X1BsRVUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RTlDUFlCRUlvQlNGcnlxNHFwQXk4SUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlHaUJsS0Zzd0R3PT1cdTAwMjZycz1BT240Q0xDY1hlMHJZQ2xCbXEzWk5MaHJUMXZndXpBelpRIiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9mSDZ5andfUGxFVS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFOUNOQUNFTHdCU0ZyeXE0cXBBeThJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFId0FRSDRBZjRKZ0FMUUJZb0NEQWdBRUFFWUdpQmxLRnN3RHc9PVx1MDAyNnJzPUFPbjRDTEFXbFRXTXFPVWdDbGdsWnJQMWhqN2wyU0E2VHciLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IiEhQ29uIDIwMjIgLSBIb3cgdG8gbG9vayBmb3Igb25lIGltYWdlIGluc2lkZSBhbm90aGVyIGltYWdlLCBmYXN0ISBieSBPbWFyIFJpendhbiBkZSBDb25mcmVha3MgaWwgeSBhIDIgbW9pcyA5IG1pbnV0ZXMgZXQgMzTCoHNlY29uZGVzIDEyOcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IiEhQ29uIDIwMjIgLSBIb3cgdG8gbG9vayBmb3Igb25lIGltYWdlIGluc2lkZSBhbm90aGVyIGltYWdlLCBmYXN0ISBieSBPbWFyIFJpendhbiJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDIgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIxMjnCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTk1CRUpRMUdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Q21jdGFHbG5hQzFqY25aYUdGVkRWMjVRYW0xeGRteHFZMkZtUVRCNk1sVXhabmRMVVpvQkJSRHlPQmhtcWdFYVZWVk1SbGR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFFPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9Zkg2eWp3X1BsRVUiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiZkg2eWp3X1BsRVUiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIxLS0tc24tMjVnZTduenouZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTdjN2ViMjhmMGZjZjk0NDVcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjA1MDAwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ05NQkVKUTFHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBsQXhhaS1fdkRSckw5OHFnRWFWVlZNUmxkdVVHcHRjWFpzYW1OaFprRXdlakpWTVdaM1MxRT0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjEyOcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjEyOcKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOY0JFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOY0JFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6ImZINnlqd19QbEVVIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOY0JFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJmSDZ5andfUGxFVSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbImZINnlqd19QbEVVIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTmNCRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTk1CRUpRMUdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0bVNEWjVhbmRmVUd4RlZRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTk1CRUpRMUdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDTllCRUk1aUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTk1CRUpRMUdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNOTUJFSlExR0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiOSBtaW51dGVzIGV0IDM0wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6Ijk6MzQifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTlVCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJmSDZ5andfUGxFVSIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ05VQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiZkg2eWp3X1BsRVUifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDTlVCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOUUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOUUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6ImZINnlqd19QbEVVIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOUUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJmSDZ5andfUGxFVSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbImZINnlqd19QbEVVIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ05RQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJtQXdWanI0OVdBZyIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL21Bd1ZqcjQ5V0FnL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U4Q0tnQkVGNUlXdktyaXFrREx3Z0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBZkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmdhSUdVb1d6QVBcdTAwMjZycz1BT240Q0xENHlLbzR5aEtWUVlYQkdEX1VnZlZkaTk4ejdRIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL21Bd1ZqcjQ5V0FnL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U4Q01RQkVHNUlXdktyaXFrREx3Z0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBZkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmdhSUdVb1d6QVBcdTAwMjZycz1BT240Q0xENUZsX2hRcnBWMVJUdlZoQWlBbW1RUjBPdzFnIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9tQXdWanI0OVdBZy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFOUNQWUJFSW9CU0ZyeXE0cXBBeThJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFId0FRSDRBZjRKZ0FMUUJZb0NEQWdBRUFFWUdpQmxLRnN3RHc9PVx1MDAyNnJzPUFPbjRDTENwOG9FejdDNnZRc21XVjVHdzNHVERheVRpVnciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL21Bd1ZqcjQ5V0FnL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U5Q05BQ0VMd0JTRnJ5cTRxcEF5OElBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZR2lCbEtGc3dEdz09XHUwMDI2cnM9QU9uNENMRGowbGxTUURxb2VRMlNmY0xGV3VZQnc1eDEwdyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiISFDb24gMjAyMiAtIExhLUxhLUxhbWJkYSBDYWxjdWx1czogQSBGdW5jdGlvbmFsIE11c2ljYWwgSm91cm5leSEgYnkgQW5qYW5hIFZha2lsIGRlIENvbmZyZWFrcyBpbCB5IGEgMiBtb2lzIDEyIG1pbnV0ZXMgZXQgMTDCoHNlY29uZGVzIDE1OMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IiEhQ29uIDIwMjIgLSBMYS1MYS1MYW1iZGEgQ2FsY3VsdXM6IEEgRnVuY3Rpb25hbCBNdXNpY2FsIEpvdXJuZXkhIGJ5IEFuamFuYSBWYWtpbCJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDIgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIxNTjCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTTRCRUpRMUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Q21jdGFHbG5hQzFqY25aYUdGVkRWMjVRYW0xeGRteHFZMkZtUVRCNk1sVXhabmRMVVpvQkJSRHlPQmhtcWdFYVZWVk1SbGR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFFPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9bUF3VmpyNDlXQWciLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoibUF3VmpyNDlXQWciLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnI0LS0tc24tMjVnZTduenMuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTk4MGMxNThlYmUzZDU4MDhcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjQ4NzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ000QkVKUTFHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBsQWlMRDE4ZXV4aFlhWUFhb0JHbFZWVEVaWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFIiLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjE1OMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjE1OMKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOSUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOSUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6Im1Bd1ZqcjQ5V0FnIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOSUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJtQXdWanI0OVdBZyJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIm1Bd1ZqcjQ5V0FnIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTklCRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTTRCRUpRMUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0dFFYZFdhbkkwT1ZkQlp3JTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTTRCRUpRMUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDTkVCRUk1aUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTTRCRUpRMUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNNNEJFSlExR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTIgbWludXRlcyBldCAxMMKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIxMjoxMCJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNOQUJFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6Im1Bd1ZqcjQ5V0FnIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTkFCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJtQXdWanI0OVdBZyJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNOQUJFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ004QkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ004QkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoibUF3VmpyNDlXQWciLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ004QkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIm1Bd1ZqcjQ5V0FnIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsibUF3VmpyNDlXQWciXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDTThCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6IkdtS2EyWTFfQkZFIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvR21LYTJZMV9CRkUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDS2dCRUY1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV3pBUFx1MDAyNnJzPUFPbjRDTEFRTVJsRUJhNVQ4Nko4S0tDYnU5T3JwdTFRbkEiLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvR21LYTJZMV9CRkUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDTVFCRUc1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV3pBUFx1MDAyNnJzPUFPbjRDTEQtNnVJN0JLVWx5b1A4SXZjbXNzcGhWbGxidmciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0dtS2EyWTFfQkZFL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U5Q1BZQkVJb0JTRnJ5cTRxcEF5OElBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZR2lCbEtGc3dEdz09XHUwMDI2cnM9QU9uNENMQWxQc3dEVWUtdWx0MElYcnZ2d015S29ldHNIZyIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvR21LYTJZMV9CRkUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RTlDTkFDRUx3QlNGcnlxNHFwQXk4SUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlHaUJsS0Zzd0R3PT1cdTAwMjZycz1BT240Q0xDSUJiaUZDaVdOY3RYZjdWbWNNQ09EWFhadFBnIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIhIUNvbiAyMDIyIENvbWVkeSBSb3V0aW5lIGJ5IFN1bWFuYSBIYXJpaGFyZXN3YXJhIGRlIENvbmZyZWFrcyBpbCB5IGEgMiBtb2lzIDIyIG1pbnV0ZXMgNDfCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIhIUNvbiAyMDIyIENvbWVkeSBSb3V0aW5lIGJ5IFN1bWFuYSBIYXJpaGFyZXN3YXJhIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgMiBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjQ3wqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ01rQkVKUTFHQU1pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUNtY3RhR2xuYUMxamNuWmFHRlZEVjI1UWFtMXhkbXhxWTJGbVFUQjZNbFV4Wm5kTFVab0JCUkR5T0JobXFnRWFWVlZNUmxkdVVHcHRjWFpzYW1OaFprRXdlakpWTVdaM1MxRT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PUdtS2EyWTFfQkZFIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IkdtS2EyWTFfQkZFIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNC0tLXNuLTI1Z2xlbmVzLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD0xYTYyOWFkOThkN2YwNDUxXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYzMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNNa0JFSlExR0FNaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwbEEwWWo4NjVqYnByRWFxZ0VhVlZWTVJsZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9Iiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI0N8KgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjQ3wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ00wQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ00wQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiR21LYTJZMV9CRkUiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ00wQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIkdtS2EyWTFfQkZFIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiR21LYTJZMV9CRkUiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNNMEJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNa0JFSlExR0FNaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RIYlV0aE1sa3hYMEpHUlElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNa0JFSlExR0FNaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNNd0JFSTVpSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNNa0JFSlExR0FNaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ01rQkVKUTFHQU1pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIyMiBtaW51dGVzIGV0IDU3wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjIyOjU3In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ01zQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiR21LYTJZMV9CRkUiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNc0JFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IkdtS2EyWTFfQkZFIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ01zQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTW9CRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTW9CRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJHbUthMlkxX0JGRSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTW9CRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiR21LYTJZMV9CRkUiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJHbUthMlkxX0JGRSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNNb0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiUFp5NjJYXy1TX2siLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9QWnk2MlhfLVNfay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFOENLZ0JFRjVJV3ZLcmlxa0RMd2dCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QWZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJnYUlHVW9XekFQXHUwMDI2cnM9QU9uNENMRDN6U2lHY0YyZXdWU1d4VEpBbWhTZEZTcGdxUSIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9QWnk2MlhfLVNfay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFOENNUUJFRzVJV3ZLcmlxa0RMd2dCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QWZBQkFmZ0JfZ21BQXRBRmlnSU1DQUFRQVJnYUlHVW9XekFQXHUwMDI2cnM9QU9uNENMQTVMNTR6bjMxZC1lZUVfZ2JxbzJPa1l1OG5EUSIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvUFp5NjJYXy1TX2svaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RTlDUFlCRUlvQlNGcnlxNHFwQXk4SUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlHaUJsS0Zzd0R3PT1cdTAwMjZycz1BT240Q0xBcnMzWFRpTE8zU1RnQlA5a3hBLUZjNkJEa05RIiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9QWnk2MlhfLVNfay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFOUNOQUNFTHdCU0ZyeXE0cXBBeThJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFId0FRSDRBZjRKZ0FMUUJZb0NEQWdBRUFFWUdpQmxLRnN3RHc9PVx1MDAyNnJzPUFPbjRDTERwNHRhTkIxN3d2SE9LbHRiSm5LLVJvLUp1T3ciLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IiEhQ29uIDIwMjIgLSBZb3UgS2lzcyBZb3VyIENvbXB1dGVyIFdpdGggVGhhdCBNb3V0aD8hIGJ5IE5pY29sZSBIZSBkZSBDb25mcmVha3MgaWwgeSBhIDIgbW9pcyAxMSBtaW51dGVzIGV0IDIzwqBzZWNvbmRlcyA2OcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IiEhQ29uIDIwMjIgLSBZb3UgS2lzcyBZb3VyIENvbXB1dGVyIFdpdGggVGhhdCBNb3V0aD8hIGJ5IE5pY29sZSBIZSJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDIgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiI2OcKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNUUJFSlExR0FRaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lDbWN0YUdsbmFDMWpjblphR0ZWRFYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVWm9CQlJEeU9CaG1xZ0VhVlZWTVJsZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1QWnk2MlhfLVNfayIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJQWnk2MlhfLVNfayIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjEtLS1zbi0yNWdlN25zZC5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9M2Q5Y2JhZDk3ZmZlNGJmOVx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MjM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDTVFCRUpRMUdBUWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGxBLVpmNV81ZmJyczQ5cWdFYVZWVk1SbGR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFFPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNjnCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiI2OcKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNZ0JFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNZ0JFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IlBaeTYyWF8tU19rIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNZ0JFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJQWnk2MlhfLVNfayJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIlBaeTYyWF8tU19rIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTWdCRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTVFCRUpRMUdBUWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0UVduazJNbGhmTFZOZmF3JTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTVFCRUpRMUdBUWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDTWNCRUk1aUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTVFCRUpRMUdBUWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNNUUJFSlExR0FRaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTEgbWludXRlcyBldCAyM8Kgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIxMToyMyJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNWUJFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6IlBaeTYyWF8tU19rIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTVlCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJQWnk2MlhfLVNfayJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNNWUJFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ01VQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ01VQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiUFp5NjJYXy1TX2siLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ01VQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIlBaeTYyWF8tU19rIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiUFp5NjJYXy1TX2siXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDTVVCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6IlMwRXllYXQwZW1JIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvUzBFeWVhdDBlbUkvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDS2dCRUY1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ1pJR1VvV2pBUFx1MDAyNnJzPUFPbjRDTER0ZXFXRDVWT1kwQy1wUzYzMXU0d2FHOHI5Z3ciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvUzBFeWVhdDBlbUkvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDTVFCRUc1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ1pJR1VvV2pBUFx1MDAyNnJzPUFPbjRDTERBV1BlVnF0eG8tcXlJOG5pV2pxa2M0cFRtZUEiLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1MwRXllYXQwZW1JL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U5Q1BZQkVJb0JTRnJ5cTRxcEF5OElBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZR1NCbEtGb3dEdz09XHUwMDI2cnM9QU9uNENMQTAxVlpBbjJEOF9TN1lRWmxKTl9aSXdYczN0USIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvUzBFeWVhdDBlbUkvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RTlDTkFDRUx3QlNGcnlxNHFwQXk4SUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlHU0JsS0Zvd0R3PT1cdTAwMjZycz1BT240Q0xDUERqZGZfelZkOFd1SGlZcmw2djVVU1JySlJRIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIhIUNvbiAyMDIyIC0gQnVpbGRpbmcgQSBCZXR0ZXIgVGVjaCBGdXR1cmUhISBieSBBbml5aWEgV2lsbGlhbXMgZGUgQ29uZnJlYWtzIGlsIHkgYSAyIG1vaXMgNiBtaW51dGVzIGV0IDE0wqBzZWNvbmRlcyAzNcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IiEhQ29uIDIwMjIgLSBCdWlsZGluZyBBIEJldHRlciBUZWNoIEZ1dHVyZSEhIGJ5IEFuaXlpYSBXaWxsaWFtcyJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDIgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIzNcKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMOEJFSlExR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lDbWN0YUdsbmFDMWpjblphR0ZWRFYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVWm9CQlJEeU9CaG1xZ0VhVlZWTVJsZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1TMEV5ZWF0MGVtSSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJTMEV5ZWF0MGVtSSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjUtLS1zbi0yNWdlN25zZC5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9NGI0MTMyNzlhYjc0N2E2Mlx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz0zNjUwMDBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDTDhCRUpRMUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGxBNHZUUjI1clB6S0JMcWdFYVZWVk1SbGR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFFPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMzXCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIzNcKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNTUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNTUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IlMwRXllYXQwZW1JIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNTUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJTMEV5ZWF0MGVtSSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIlMwRXllYXQwZW1JIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTU1CRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTDhCRUpRMUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0VE1FVjVaV0YwTUdWdFNRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTDhCRUpRMUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDTUlCRUk1aUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTDhCRUpRMUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNMOEJFSlExR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNiBtaW51dGVzIGV0IDE0wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjY6MTQifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTUVCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJTMEV5ZWF0MGVtSSIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ01FQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiUzBFeWVhdDBlbUkifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDTUVCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNQUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNQUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IlMwRXllYXQwZW1JIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNNQUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJTMEV5ZWF0MGVtSSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIlMwRXllYXQwZW1JIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ01BQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJKMGVRWGhlNzhWYyIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0owZVFYaGU3OFZjL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U4Q0tnQkVGNUlXdktyaXFrREx3Z0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBZkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmdhSUdVb1d6QVBcdTAwMjZycz1BT240Q0xEMDAxX1pjNXZ5VFM5LWRDaV8zczFkYUFHWmdnIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0owZVFYaGU3OFZjL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U4Q01RQkVHNUlXdktyaXFrREx3Z0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBZkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmdhSUdVb1d6QVBcdTAwMjZycz1BT240Q0xEVndsOXBEdjNCd1RGODVlT2xxOFk2Ynp4UFZnIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9KMGVRWGhlNzhWYy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFOUNQWUJFSW9CU0ZyeXE0cXBBeThJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFId0FRSDRBZjRKZ0FMUUJZb0NEQWdBRUFFWUdpQmxLRnN3RHc9PVx1MDAyNnJzPUFPbjRDTERFOUN4Mng0WDczV1R4VlIyanV4SVNpMWpYQ1EiLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0owZVFYaGU3OFZjL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U5Q05BQ0VMd0JTRnJ5cTRxcEF5OElBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZR2lCbEtGc3dEdz09XHUwMDI2cnM9QU9uNENMQnBUb2hQRmJPLWVpd0thMGx2UnVZczBmZVVOQSIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiISFDb24gMjAyMiAtIExldOKAmXMgY29kZSBpbiBvdXIgbW90aGVyIHRvbmd1ZSEgYnkgQW51bG9sdXdhcG8gS2Fyb3Vud2kgZGUgQ29uZnJlYWtzIGlsIHkgYSAyIG1vaXMgMTAgbWludXRlcyBldCA0M8Kgc2Vjb25kZXMgMzbCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIhIUNvbiAyMDIyIC0gTGV04oCZcyBjb2RlIGluIG91ciBtb3RoZXIgdG9uZ3VlISBieSBBbnVsb2x1d2FwbyBLYXJvdW53aSJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDIgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIzNsKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMb0JFSlExR0FZaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lDbWN0YUdsbmFDMWpjblphR0ZWRFYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVWm9CQlJEeU9CaG1xZ0VhVlZWTVJsZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1KMGVRWGhlNzhWYyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJKMGVRWGhlNzhWYyIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjUtLS1zbi0yNWdsZW5sci5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9Mjc0NzkwNWUxN2JiZjE1N1x1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MzM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDTG9CRUpRMUdBWWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGxBMS1MdnZlR0w1S01ucWdFYVZWVk1SbGR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFFPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMzbCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIzNsKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMNEJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMNEJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IkowZVFYaGU3OFZjIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMNEJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJKMGVRWGhlNzhWYyJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIkowZVFYaGU3OFZjIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTDRCRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTG9CRUpRMUdBWWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0S01HVlJXR2hsTnpoV1l3JTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTG9CRUpRMUdBWWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDTDBCRUk1aUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTG9CRUpRMUdBWWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNMb0JFSlExR0FZaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTAgbWludXRlcyBldCA0M8Kgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIxMDo0MyJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMd0JFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6IkowZVFYaGU3OFZjIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTHdCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJKMGVRWGhlNzhWYyJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNMd0JFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xzQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xzQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiSjBlUVhoZTc4VmMiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xzQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIkowZVFYaGU3OFZjIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiSjBlUVhoZTc4VmMiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDTHNCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6IjZjQ0N5aUpmVTlnIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNmNDQ3lpSmZVOWcvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDS2dCRUY1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV3pBUFx1MDAyNnJzPUFPbjRDTEJnUkF3UXFQVkpkQkxVWWp3Y3BNbk1XcTFfWkEiLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNmNDQ3lpSmZVOWcvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDTVFCRUc1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV3pBUFx1MDAyNnJzPUFPbjRDTEJzakZTTFdTeHh3dlp3TVdadmxXcGJOVkxzbmciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzZjQ0N5aUpmVTlnL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U5Q1BZQkVJb0JTRnJ5cTRxcEF5OElBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZR2lCbEtGc3dEdz09XHUwMDI2cnM9QU9uNENMQmltc1NMQ0J6eTY3QjlKLUcweTdFOHBEcUJZUSIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNmNDQ3lpSmZVOWcvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RTlDTkFDRUx3QlNGcnlxNHFwQXk4SUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlHaUJsS0Zzd0R3PT1cdTAwMjZycz1BT240Q0xBbC1zT3VCdXZjNk1pMVZ3aC1hcjRFS2pQaU93Iiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIhIUNvbiAyMDIyIC0gVGFwZXJpcHBlciBvciwgT29wcyEgQWxsIFNDU0khIGJ5IEFraSBWYW4gTmVzcyBkZSBDb25mcmVha3MgaWwgeSBhIDIgbW9pcyA5IG1pbnV0ZXMgZXQgNTDCoHNlY29uZGVzIDEwNcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IiEhQ29uIDIwMjIgLSBUYXBlcmlwcGVyIG9yLCBPb3BzISBBbGwgU0NTSSEgYnkgQWtpIFZhbiBOZXNzIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgMiBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjEwNcKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMVUJFSlExR0FjaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lDbWN0YUdsbmFDMWpjblphR0ZWRFYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVWm9CQlJEeU9CaG1xZ0VhVlZWTVJsZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj02Y0NDeWlKZlU5ZyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiI2Y0NDeWlKZlU5ZyIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjEtLS1zbi0yNWdsZW5say5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9ZTljMDgyY2EyMjVmNTNkOFx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02NDg3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDTFVCRUpRMUdBY2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGxBMktmOWtxTFpvT0RwQWFvQkdsVlZURVpYYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0UiIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTA1wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTA1wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xrQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xrQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiNmNDQ3lpSmZVOWciLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xrQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjZjQ0N5aUpmVTlnIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiNmNDQ3lpSmZVOWciXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNMa0JFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMVUJFSlExR0FjaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3MyWTBORGVXbEtabFU1WnclM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMVUJFSlExR0FjaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNMZ0JFSTVpSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNMVUJFSlExR0FjaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0xVQkVKUTFHQWNpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI5IG1pbnV0ZXMgZXQgNTDCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiOTo1MCJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMY0JFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6IjZjQ0N5aUpmVTlnIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTGNCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiI2Y0NDeWlKZlU5ZyJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNMY0JFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xZQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xZQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiNmNDQ3lpSmZVOWciLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xZQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjZjQ0N5aUpmVTlnIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiNmNDQ3lpSmZVOWciXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDTFlCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6IjNBV1ROc0pFQV9JIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvM0FXVE5zSkVBX0kvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDS2dCRUY1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV3pBUFx1MDAyNnJzPUFPbjRDTEQyUkE1SldMZkF1a1dTdzFPam4tc0hDWFlCbkEiLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvM0FXVE5zSkVBX0kvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDTVFCRUc1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ2FJR1VvV3pBUFx1MDAyNnJzPUFPbjRDTEFUNjdCbnAyYTJ4eUZQcDJiS0kyeEpsYTM4VWciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzNBV1ROc0pFQV9JL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U5Q1BZQkVJb0JTRnJ5cTRxcEF5OElBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZR2lCbEtGc3dEdz09XHUwMDI2cnM9QU9uNENMRG5vM1ZDYWVEaXRaclY2em11UmFGbVIxN193ZyIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvM0FXVE5zSkVBX0kvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RTlDTkFDRUx3QlNGcnlxNHFwQXk4SUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlHaUJsS0Zzd0R3PT1cdTAwMjZycz1BT240Q0xCT0Z2V3BNeTQxYmxfSzJEblc1VGxUWFl6R2hnIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIhIUNvbiAyMDIyIC0gQ29kZSByZWFkYWJpbGl0eSBpc27igJl0IGp1c3QgYWJvdXQgcGVyc29uYWwgcHJlZmVyZW5jZSEgYnkgQXNobGVlIEJveWVyIGRlIENvbmZyZWFrcyBpbCB5IGEgMiBtb2lzIDEwIG1pbnV0ZXMgZXQgNDDCoHNlY29uZGVzIDE0NMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IiEhQ29uIDIwMjIgLSBDb2RlIHJlYWRhYmlsaXR5IGlzbuKAmXQganVzdCBhYm91dCBwZXJzb25hbCBwcmVmZXJlbmNlISBieSBBc2hsZWUgQm95ZXIifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSAyIG1vaXMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMTQ0wqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xBQkVKUTFHQWdpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUNtY3RhR2xuYUMxamNuWmFHRlZEVjI1UWFtMXhkbXhxWTJGbVFUQjZNbFV4Wm5kTFVab0JCUkR5T0JobXFnRWFWVlZNUmxkdVVHcHRjWFpzYW1OaFprRXdlakpWTVdaM1MxRT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PTNBV1ROc0pFQV9JIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IjNBV1ROc0pFQV9JIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMi0tLXNuLTRneHgtMjVnZTcuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWRjMDU5MzM2YzI0NDAzZjJcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9MzkxMjUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0xBQkVKUTFHQWdpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBsQThvZVFrdXptNUlMY0Fhb0JHbFZWVEVaWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFIiLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjE0NMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjE0NMKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMUUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMUUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IjNBV1ROc0pFQV9JIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMUUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyIzQVdUTnNKRUFfSSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIjNBV1ROc0pFQV9JIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTFFCRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTEFCRUpRMUdBZ2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2dzelFWZFVUbk5LUlVGZlNRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTEFCRUpRMUdBZ2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDTE1CRUk1aUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDTEFCRUpRMUdBZ2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNMQUJFSlExR0FnaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTAgbWludXRlcyBldCA0MMKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIxMDo0MCJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNMSUJFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6IjNBV1ROc0pFQV9JIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDTElCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiIzQVdUTnNKRUFfSSJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNMSUJFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xFQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xFQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiM0FXVE5zSkVBX0kiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0xFQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjNBV1ROc0pFQV9JIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiM0FXVE5zSkVBX0kiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDTEVCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6IjFwQWNLMnpnVmUwIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvMXBBY0syemdWZTAvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDS2dCRUY1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ1RJRkVvZnpBUFx1MDAyNnJzPUFPbjRDTEFJLU10dTlqSVUxLUU0Q3Eyc01aMHJqMlFQMHciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvMXBBY0syemdWZTAvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RThDTVFCRUc1SVd2S3JpcWtETHdnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFmQUJBZmdCX2dtQUF0QUZpZ0lNQ0FBUUFSZ1RJRkVvZnpBUFx1MDAyNnJzPUFPbjRDTENaX3JXaHFES25kdVkwMHAtMk16dXhoTUYweXciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzFwQWNLMnpnVmUwL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U5Q1BZQkVJb0JTRnJ5cTRxcEF5OElBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZRXlCUktIOHdEdz09XHUwMDI2cnM9QU9uNENMQk5TTmk5dWlfMEZQOUFGM2l1NGF3M1NERHFhQSIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvMXBBY0syemdWZTAvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RTlDTkFDRUx3QlNGcnlxNHFwQXk4SUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBSHdBUUg0QWY0SmdBTFFCWW9DREFnQUVBRVlFeUJSS0g4d0R3PT1cdTAwMjZycz1BT240Q0xBWXVKSVBxalV6WDJxQnpPTlZSSF9ONGN0TUtRIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIhIUNvbiAyMDIyIC0gQ3VzdG9taXphYmxlIEljb25zIFdpdGggRm9udCBUZWNobm9sb2dpZXMhIGJ5IFdlbnRpbmcgWmhhbmcgZGUgQ29uZnJlYWtzIGlsIHkgYSAyIG1vaXMgOSBtaW51dGVzIGV0IDQ4wqBzZWNvbmRlcyAzOcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IiEhQ29uIDIwMjIgLSBDdXN0b21pemFibGUgSWNvbnMgV2l0aCBGb250IFRlY2hub2xvZ2llcyEgYnkgV2VudGluZyBaaGFuZyJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDIgbW9pcyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIzOcKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLc0JFSlExR0FraUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lDbWN0YUdsbmFDMWpjblphR0ZWRFYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVWm9CQlJEeU9CaG1xZ0VhVlZWTVJsZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj0xcEFjSzJ6Z1ZlMCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiIxcEFjSzJ6Z1ZlMCIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjMtLS1zbi0yNWdlN25zay5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9ZDY5MDFjMmI2Y2UwNTVlZFx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MzM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDS3NCRUpRMUdBa2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGxBN2F1QjU3YUZoOGpXQWFvQkdsVlZURVpYYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0UiIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMznCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIzOcKgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLOEJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLOEJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IjFwQWNLMnpnVmUwIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLOEJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyIxcEFjSzJ6Z1ZlMCJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIjFwQWNLMnpnVmUwIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDSzhCRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDS3NCRUpRMUdBa2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2dzeGNFRmpTeko2WjFabE1BJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDS3NCRUpRMUdBa2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDSzRCRUk1aUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDS3NCRUpRMUdBa2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNLc0JFSlExR0FraUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiOSBtaW51dGVzIGV0IDQ4wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6Ijk6NDgifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSzBCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiIxcEFjSzJ6Z1ZlMCIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0swQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiMXBBY0syemdWZTAifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDSzBCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLd0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLd0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IjFwQWNLMnpnVmUwIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLd0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyIxcEFjSzJ6Z1ZlMCJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIjFwQWNLMnpnVmUwIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0t3QkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJ6TFg5b19jRWVuNCIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3pMWDlvX2NFZW40L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U4Q0tnQkVGNUlXdktyaXFrREx3Z0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBZkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmdxSUQ4b2Z6QVBcdTAwMjZycz1BT240Q0xBYnM1TWExOE5ZRm9UaXhqMmZXS2VLVl84b1NBIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3pMWDlvX2NFZW40L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U4Q01RQkVHNUlXdktyaXFrREx3Z0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBZkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmdxSUQ4b2Z6QVBcdTAwMjZycz1BT240Q0xDazM1eVl2U1RKdVlwMkd0MDNQODJyYjhuY1RRIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96TFg5b19jRWVuNC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFOUNQWUJFSW9CU0ZyeXE0cXBBeThJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFId0FRSDRBZjRKZ0FMUUJZb0NEQWdBRUFFWUtpQV9LSDh3RHc9PVx1MDAyNnJzPUFPbjRDTEM2V1BFNGRqUzRwNDZudGxHOTVxdWFXQUlmd0EiLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3pMWDlvX2NFZW40L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U5Q05BQ0VMd0JTRnJ5cTRxcEF5OElBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZS2lBX0tIOHdEdz09XHUwMDI2cnM9QU9uNENMREJQbktVcmpST1BBSGt5TjNNeU9RWW1DYUEzQSIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiUnVieUNvbmYgMjAyMjogVXNpbmcgSlJ1Ynk6IFdoYXQsIFdoZW4sIEhvdywgYW5kIFdoeSBieSBDaGFybGVzIE51dHRlciBkZSBDb25mcmVha3MgaWwgeSBhIDMgbW9pcyAzMCBtaW51dGVzIDQzOMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IlJ1YnlDb25mIDIwMjI6IFVzaW5nIEpSdWJ5OiBXaGF0LCBXaGVuLCBIb3csIGFuZCBXaHkgYnkgQ2hhcmxlcyBOdXR0ZXIifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSAzIG1vaXMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiNDM4wqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0tZQkVKUTFHQW9pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUNtY3RhR2xuYUMxamNuWmFHRlZEVjI1UWFtMXhkbXhxWTJGbVFUQjZNbFV4Wm5kTFVab0JCUkR5T0JobXFnRWFWVlZNUmxkdVVHcHRjWFpzYW1OaFprRXdlakpWTVdaM1MxRT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PXpMWDlvX2NFZW40Iiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6InpMWDlvX2NFZW40Iiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMTEtLS1zbi00Z3h4LTI1Z2VsLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1jY2I1ZmRhM2Y3MDQ3YTdlXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTQ1NzUwMFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNLWUJFSlExR0FvaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwbEFfdlNSdUwtMF85ck1BYW9CR2xWVlRFWlhibEJxYlhGMmJHcGpZV1pCTUhveVZURm1kMHRSIiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI0MzjCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiI0MzjCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDS29CRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDS29CRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJ6TFg5b19jRWVuNCIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDS29CRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiekxYOW9fY0VlbjQiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJ6TFg5b19jRWVuNCJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0tvQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0tZQkVKUTFHQW9pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndDZURmc1YjE5alJXVnVOQSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0tZQkVKUTFHQW9pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0trQkVJNWlJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0tZQkVKUTFHQW9pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDS1lCRUpRMUdBb2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjMwIG1pbnV0ZXMgZXQgMjPCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiMzA6MjMifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDS2dCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJ6TFg5b19jRWVuNCIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0tnQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiekxYOW9fY0VlbjQifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDS2dCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLY0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLY0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6InpMWDlvX2NFZW40IiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLY0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJ6TFg5b19jRWVuNCJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbInpMWDlvX2NFZW40Il19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0tjQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJwU0NNZ2N0dFc0YyIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3BTQ01nY3R0VzRjL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U4Q0tnQkVGNUlXdktyaXFrREx3Z0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBZkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmdvSUQ0b2Z6QVBcdTAwMjZycz1BT240Q0xEWDRMbXdvd1BRdUV1MEtXeEl5Ry1JUnhvQVlRIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3BTQ01nY3R0VzRjL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U4Q01RQkVHNUlXdktyaXFrREx3Z0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBZkFCQWZnQl9nbUFBdEFGaWdJTUNBQVFBUmdvSUQ0b2Z6QVBcdTAwMjZycz1BT240Q0xEbVQ4d2hSNWVYUnU2V3psdDA4bUF5S2ZWUkdBIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wU0NNZ2N0dFc0Yy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFOUNQWUJFSW9CU0ZyeXE0cXBBeThJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFId0FRSDRBZjRKZ0FMUUJZb0NEQWdBRUFFWUtDQS1LSDh3RHc9PVx1MDAyNnJzPUFPbjRDTENtMHRYWFlSdF9ZZ09fd1lfRnFQMzdiVU1XTGciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3BTQ01nY3R0VzRjL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0U5Q05BQ0VMd0JTRnJ5cTRxcEF5OElBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUh3QVFINEFmNEpnQUxRQllvQ0RBZ0FFQUVZS0NBLUtIOHdEdz09XHUwMDI2cnM9QU9uNENMQVRYYjlLa1k1aEo5YVpnd1hqbm94V2lEX2RiZyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiUnVieUNvbmYgMjAyMjogQW5hbHl6aW5nIGFuIGFuYWx5emVyIC0gQSBkaXZlIGludG8gaG93IFJ1Ym9Db3Agd29ya3MgYnkgS3lsZSBkJ09saXZlaXJhIGRlIENvbmZyZWFrcyBpbCB5IGEgMyBtb2lzIDI5IG1pbnV0ZXMgMjIxwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiUnVieUNvbmYgMjAyMjogQW5hbHl6aW5nIGFuIGFuYWx5emVyIC0gQSBkaXZlIGludG8gaG93IFJ1Ym9Db3Agd29ya3MgYnkgS3lsZSBkJ09saXZlaXJhIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgMyBtb2lzIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjIyMcKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLRUJFSlExR0FzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lDbWN0YUdsbmFDMWpjblphR0ZWRFYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVWm9CQlJEeU9CaG1xZ0VhVlZWTVJsZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1wU0NNZ2N0dFc0YyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJwU0NNZ2N0dFc0YyIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjEtLS1zbi00Z3h4LTI1Z2VsLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1hNTIwOGM4MWNiNmQ1Yjg3XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTQ1NzUwMFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNLRUJFSlExR0FzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwbEFoN2UxMjV5UW81Q2xBYW9CR2xWVlRFWlhibEJxYlhGMmJHcGpZV1pCTUhveVZURm1kMHRSIiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIyMjHCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIyMjHCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDS1VCRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDS1VCRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJwU0NNZ2N0dFc0YyIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDS1VCRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsicFNDTWdjdHRXNGMiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJwU0NNZ2N0dFc0YyJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0tVQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0tFQkVKUTFHQXNpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndHdVME5OWjJOMGRGYzBZdyUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0tFQkVKUTFHQXNpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0tRQkVJNWlJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0tFQkVKUTFHQXNpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDS0VCRUpRMUdBc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjI5IG1pbnV0ZXMgZXQgMTLCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiMjk6MTIifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDS01CRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJwU0NNZ2N0dFc0YyIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0tNQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoicFNDTWdjdHRXNGMifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDS01CRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLSUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLSUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6InBTQ01nY3R0VzRjIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNLSUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJwU0NNZ2N0dFc0YyJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbInBTQ01nY3R0VzRjIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0tJQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fV0sInRyYWNraW5nUGFyYW1zIjoiQ0o0QkVNWTVJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwidmlzaWJsZUl0ZW1Db3VudCI6NCwibmV4dEJ1dHRvbiI6eyJidXR0b25SZW5kZXJlciI6eyJzdHlsZSI6IlNUWUxFX0RFRkFVTFQiLCJzaXplIjoiU0laRV9ERUZBVUxUIiwiaXNEaXNhYmxlZCI6ZmFsc2UsImljb24iOnsiaWNvblR5cGUiOiJDSEVWUk9OX1JJR0hUIn0sImFjY2Vzc2liaWxpdHkiOnsibGFiZWwiOiJTdWl2YW50In0sInRyYWNraW5nUGFyYW1zIjoiQ0tBQkVQQmJJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LCJwcmV2aW91c0J1dHRvbiI6eyJidXR0b25SZW5kZXJlciI6eyJzdHlsZSI6IlNUWUxFX0RFRkFVTFQiLCJzaXplIjoiU0laRV9ERUZBVUxUIiwiaXNEaXNhYmxlZCI6ZmFsc2UsImljb24iOnsiaWNvblR5cGUiOiJDSEVWUk9OX0xFRlQifSwiYWNjZXNzaWJpbGl0eSI6eyJsYWJlbCI6IlByw6ljw6lkZW50ZSJ9LCJ0cmFja2luZ1BhcmFtcyI6IkNKOEJFUEJiSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNKd0JFTndjR0FBaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJwbGF5QWxsQnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfVEVYVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiVG91dCBsaXJlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlBMQVlfQUxMIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0owQkVQQmJJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj16T3pJbHNES2dlMFx1MDAyNmxpc3Q9VVVMRlduUGptcXZsamNhZkEwejJVMWZ3S1EiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiek96SWxzREtnZTAiLCJwbGF5bGlzdElkIjoiVVVMRlduUGptcXZsamNhZkEwejJVMWZ3S1EiLCJsb2dnaW5nQ29udGV4dCI6eyJ2c3NMb2dnaW5nQ29udGV4dCI6eyJzZXJpYWxpemVkQ29udGV4dERhdGEiOiJHaHBWVlV4R1YyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVUSUzRCUzRCJ9fSwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMS0tLXNuLTI1Z2xlbmxyLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1jY2VjYzg5NmMwY2E4MWVkXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTY0ODc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNKMEJFUEJiSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fX19XSwidHJhY2tpbmdQYXJhbXMiOiJDSnNCRUxzdkdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsiaXRlbVNlY3Rpb25SZW5kZXJlciI6eyJjb250ZW50cyI6W3sic2hlbGZSZW5kZXJlciI6eyJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiVmlkw6lvcyBwb3B1bGFpcmVzIiwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRm9RM0J3WUFDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQENvbmZyZWFrcy92aWRlb3M/dmlldz0wXHUwMDI2c29ydD1wXHUwMDI2c2hlbGZfaWQ9MCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9DSEFOTkVMIiwicm9vdFZlIjozNjExLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsInBhcmFtcyI6IkVnWjJhV1JsYjNNWUFTQUFjQUR5QmdzS0NUb0NDQUtpQVFJSUFRJTNEJTNEIiwiY2Fub25pY2FsQmFzZVVybCI6Ii9AQ29uZnJlYWtzIn19fV19LCJlbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZvUTNCd1lBQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL0BDb25mcmVha3MvdmlkZW9zP3ZpZXc9MFx1MDAyNnNvcnQ9cFx1MDAyNnNoZWxmX2lkPTAiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJwYXJhbXMiOiJFZ1oyYVdSbGIzTVlBU0FBY0FEeUJnc0tDVG9DQ0FLaUFRSUlBUSUzRCUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQENvbmZyZWFrcyJ9fSwiY29udGVudCI6eyJob3Jpem9udGFsTGlzdFJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoickk4dE5Nc296bzAiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9ySTh0Tk1zb3pvMC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTENsSlZ4X0x0cnIwZXk4d01GamYxWkg4TnFVcWciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvckk4dE5Nc296bzAvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xDX19nY0hvYVhaUVJENkIzUjhXbWg1OTZEdkNBIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9ySTh0Tk1zb3pvMC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEJ0UmZIMHVLd3FCczZfNlBIbDlhRmFlbWdWREEiLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3JJOHROTXNvem8wL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQTFnQ1BfY3NPT1Mxa2tacGZ1bERCTHFjenRSZyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiUmFpbHMgQ29uZiAyMDEyIEtleW5vdGU6IFNpbXBsaWNpdHkgTWF0dGVycyBieSBSaWNoIEhpY2tleSBkZSBDb25mcmVha3MgaWwgeSBhIDExIGFucyAzNiBtaW51dGVzIDE5M+KArzQzMcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IlJhaWxzIENvbmYgMjAxMiBLZXlub3RlOiBTaW1wbGljaXR5IE1hdHRlcnMgYnkgUmljaCBIaWNrZXkifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSAxMSBhbnMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMTkz4oCvNDMxwqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pZQkVKUTFHQUFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUNtY3RhR2xuYUMxamNIWmFHRlZEVjI1UWFtMXhkbXhxWTJGbVFUQjZNbFV4Wm5kTFVab0JCUkR5T0JobHFnRWFWVlZNVUZkdVVHcHRjWFpzYW1OaFprRXdlakpWTVdaM1MxRT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PXJJOHROTXNvem8wIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6InJJOHROTXNvem8wIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNC0tLXNuLTI1Z2U3bnpyLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1hYzhmMmQzNGNiMjhjZThkXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYyMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNKWUJFSlExR0FBaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwbEFqWjJqMmN5bXk4ZXNBYW9CR2xWVlRGQlhibEJxYlhGMmJHcGpZV1pCTUhveVZURm1kMHRSIiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxOTMgbWlsbGXCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIxOTPCoGvCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSm9CRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSm9CRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJySTh0Tk1zb3pvMCIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSm9CRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsickk4dE5Nc296bzAiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJySTh0Tk1zb3pvMCJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0pvQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pZQkVKUTFHQUFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndHlTVGgwVGsxemIzcHZNQSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pZQkVKUTFHQUFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0prQkVJNWlJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0pZQkVKUTFHQUFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDSllCRUpRMUdBQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjM2IG1pbnV0ZXMgZXQgNTPCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiMzY6NTMifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSmdCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJySTh0Tk1zb3pvMCIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pnQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoickk4dE5Nc296bzAifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDSmdCRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKY0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKY0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6InJJOHROTXNvem8wIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKY0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJySTh0Tk1zb3pvMCJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbInJJOHROTXNvem8wIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0pjQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJXcGtETjc4UDg4NCIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1dwa0RONzhQODg0L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQkgwZVE1NU8yZ2xCemN0bjdhVjJIQkU1elVvUSIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9XcGtETjc4UDg4NC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEN3Y2dfbnpkUUYxSXQ2bGZ2TE4zV1dRT1o5OHciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1dwa0RONzhQODg0L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQUhCU0tVa2lSQjhiM1BCa3B5YXJzWExSaXBWZyIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvV3BrRE43OFA4ODQvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xEX3JMbXNfc1l1Ul9OVnJWZkRCMEdDc1N3R3hnIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJSdWJ5IE1pZHdlc3QgMjAxMSAtIEtleW5vdGU6IEFyY2hpdGVjdHVyZSB0aGUgTG9zdCBZZWFycyBieSBSb2JlcnQgTWFydGluIGRlIENvbmZyZWFrcyBpbCB5IGEgMTEgYW5zIDHCoGhldXJlIGV0IDYgbWludXRlcyAxNjTigK83NDfCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJSdWJ5IE1pZHdlc3QgMjAxMSAtIEtleW5vdGU6IEFyY2hpdGVjdHVyZSB0aGUgTG9zdCBZZWFycyBieSBSb2JlcnQgTWFydGluIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgMTEgYW5zIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjE2NOKArzc0N8KgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKRUJFSlExR0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lDbWN0YUdsbmFDMWpjSFphR0ZWRFYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVWm9CQlJEeU9CaGxxZ0VhVlZWTVVGZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1XcGtETjc4UDg4NCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJXcGtETjc4UDg4NCIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjItLS1zbi0yNWdsZW5sZC5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9NWE5OTAzMzdiZjBmZjNjZVx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MzM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDSkVCRUpRMUdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGxBenVlXy1Qdm13TXhhcWdFYVZWVk1VRmR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFFPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTY0IG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTY0wqBrwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pVQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pVQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiV3BrRE43OFA4ODQiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pVQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIldwa0RONzhQODg0Il0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiV3BrRE43OFA4ODQiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNKVUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKRUJFSlExR0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RYY0d0RVRqYzRVRGc0TkElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKRUJFSlExR0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNKUUJFSTVpSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNKRUJFSlExR0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0pFQkVKUTFHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxwqBoZXVyZSwgNiBtaW51dGVzIGV0IDM5wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjE6MDY6MzkifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSk1CRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJXcGtETjc4UDg4NCIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pNQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiV3BrRE43OFA4ODQifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDSk1CRVBubkF4Z0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKSUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKSUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6Ildwa0RONzhQODg0IiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNKSUJFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJXcGtETjc4UDg4NCJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIldwa0RONzhQODg0Il19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0pJQkVNZnNCQmdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiI4YlpoNUxNYVNtRSIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzhiWmg1TE1hU21FL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQnJkdkJsWENwdVUwUXlZTVAwVll6YjVtMXdCZyIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS84YlpoNUxNYVNtRS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEFzeWd4R1J4Qk9YZTBIZnFXU0pGX1RlODZEY2ciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzhiWmg1TE1hU21FL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ1pCYTNkX2ZheDJKQ2dXWFZCcWloME9JcVNXdyIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvOGJaaDVMTWFTbUUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xBQkNlZGhtRndlV0xGX1lGbEdIOHNaS0ppWUJnIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJSYWlsc0NvbmYgMjAxNCAtIEFsbCB0aGUgTGl0dGxlIFRoaW5ncyBieSBTYW5kaSBNZXR6IGRlIENvbmZyZWFrcyBpbCB5IGEgOSBhbnMgMzggbWludXRlcyAxNTfigK8yNTjCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJSYWlsc0NvbmYgMjAxNCAtIEFsbCB0aGUgTGl0dGxlIFRoaW5ncyBieSBTYW5kaSBNZXR6In0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgOSBhbnMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMTU34oCvMjU4wqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0l3QkVKUTFHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBreUNtY3RhR2xuYUMxamNIWmFHRlZEVjI1UWFtMXhkbXhxWTJGbVFUQjZNbFV4Wm5kTFVab0JCUkR5T0JobHFnRWFWVlZNVUZkdVVHcHRjWFpzYW1OaFprRXdlakpWTVdaM1MxRT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PThiWmg1TE1hU21FIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IjhiWmg1TE1hU21FIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNS0tLXNuLTI1Z2U3bno2Lmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1mMWI2NjFlNGIzMWE0YTYxXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYzMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJiYWRnZXMiOlt7Im1ldGFkYXRhQmFkZ2VSZW5kZXJlciI6eyJzdHlsZSI6IkJBREdFX1NUWUxFX1RZUEVfU0lNUExFIiwibGFiZWwiOiJTb3VzLXRpdHJlcyIsInRyYWNraW5nUGFyYW1zIjoiQ0l3QkVKUTFHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiU291cy10aXRyZXMifX19XSwidHJhY2tpbmdQYXJhbXMiOiJDSXdCRUpRMUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGxBNFpUcG1NdThtTnZ4QWFvQkdsVlZURkJYYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0UiIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTU3IG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTU3wqBrwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pBQkVQNllCQmdHSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pBQkVQNllCQmdHSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiOGJaaDVMTWFTbUUiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0pBQkVQNllCQmdHSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjhiWmg1TE1hU21FIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiOGJaaDVMTWFTbUUiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNKQUJFUDZZQkJnR0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJd0JFSlExR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3M0WWxwb05VeE5ZVk50UlElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJd0JFSlExR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNJOEJFSTVpSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNJd0JFSlExR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0l3QkVKUTFHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIzOCBtaW51dGVzIGV0IDQ3wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjM4OjQ3In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0k0QkVQbm5BeGdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiOGJaaDVMTWFTbUUiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJNEJFUG5uQXhnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IjhiWmg1TE1hU21FIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0k0QkVQbm5BeGdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSTBCRU1mc0JCZ0RJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSTBCRU1mc0JCZ0RJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiI4YlpoNUxNYVNtRSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSTBCRU1mc0JCZ0RJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiOGJaaDVMTWFTbUUiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyI4YlpoNUxNYVNtRSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNJMEJFTWZzQkJnREloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiYmtRSmRhR0dWTTgiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9ia1FKZGFHR1ZNOC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTENTVHBWa09sNUNocVNTNkdLX3hDRFJjZHlfZHciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvYmtRSmRhR0dWTTgvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xEN2lQRU5NZmtjRkFpcFZEczl4OGdVbnZXYnl3Iiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9ia1FKZGFHR1ZNOC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEFURHJMY1JMOWdBemdrQUdHenBRRFZFUGpLMEEiLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2JrUUpkYUdHVk04L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ3BhcmJ3enoxa2ZFaFFEeXdkSUdReVQwVmVydyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiISFDb24gMjAxNzogSERSIFBob3RvZ3JhcGh5IGluIE1pY3Jvc29mdCBFeGNlbD8hIGJ5IEtldmluIENoZW4gZGUgQ29uZnJlYWtzIGlsIHkgYSA2IGFucyAxMSBtaW51dGVzIGV0IDQ3wqBzZWNvbmRlcyAxMTbigK80MjTCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIhIUNvbiAyMDE3OiBIRFIgUGhvdG9ncmFwaHkgaW4gTWljcm9zb2Z0IEV4Y2VsPyEgYnkgS2V2aW4gQ2hlbiJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDYgYW5zIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjExNuKArzQyNMKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJY0JFSlExR0FNaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwa3lDbWN0YUdsbmFDMWpjSFphR0ZWRFYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVWm9CQlJEeU9CaGxxZ0VhVlZWTVVGZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1ia1FKZGFHR1ZNOCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJia1FKZGFHR1ZNOCIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjItLS1zbi0yNWdlN256ZC5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9NmU0NDA5NzVhMTg2NTRjZlx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MDUwMDBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDSWNCRUpRMUdBTWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGxBejZtWmpOcXVncUp1cWdFYVZWVk1VRmR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFFPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTE2IG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTE2wqBrwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lzQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lzQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiYmtRSmRhR0dWTTgiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lzQkVQNllCQmdGSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbImJrUUpkYUdHVk04Il0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiYmtRSmRhR0dWTTgiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNJc0JFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJY0JFSlExR0FNaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RpYTFGS1pHRkhSMVpOT0ElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJY0JFSlExR0FNaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNJb0JFSTVpSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNJY0JFSlExR0FNaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0ljQkVKUTFHQU1pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxMSBtaW51dGVzIGV0IDQ3wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjExOjQ3In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lrQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiYmtRSmRhR0dWTTgiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJa0JFUG5uQXhnQkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6ImJrUUpkYUdHVk04In1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0lrQkVQbm5BeGdCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSWdCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSWdCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJia1FKZGFHR1ZNOCIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSWdCRU1mc0JCZ0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiYmtRSmRhR0dWTTgiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJia1FKZGFHR1ZNOCJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNJZ0JFTWZzQkJnQ0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiOUxmbXJreVA4MU0iLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS85TGZtcmt5UDgxTS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEFhTV9od1ZLRl9uY09JN2Yzc2tmbnNtOTI2U3ciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvOUxmbXJreVA4MU0vaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xBVFdTb0xjY1VwZXJSVE4xR1oxdXduM0VwSU9BIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS85TGZtcmt5UDgxTS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEF0ZnF6NEVUbXpVUXl0cjFITkVUdEJDVUJBYkEiLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzlMZm1ya3lQODFNL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMRFBrbC00SUJCdXhnckV5em9jRUxtY2FNS2doQSIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiUmFpbHNDb25mIDIwMTQgLSBLZXlub3RlOiBXcml0aW5nIFNvZnR3YXJlIGJ5IERhdmlkIEhlaW5lbWVpZXIgSGFuc3NvbiBkZSBDb25mcmVha3MgaWwgeSBhIDkgYW5zIDHCoGhldXJlIGV0IDEgbWludXRlIDExM+KArzQ3M8KgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IlJhaWxzQ29uZiAyMDE0IC0gS2V5bm90ZTogV3JpdGluZyBTb2Z0d2FyZSBieSBEYXZpZCBIZWluZW1laWVyIEhhbnNzb24ifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSA5IGFucyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIxMTPigK80NzPCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSUlCRUpRMUdBUWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGt5Q21jdGFHbG5hQzFqY0haYUdGVkRWMjVRYW0xeGRteHFZMkZtUVRCNk1sVXhabmRMVVpvQkJSRHlPQmhscWdFYVZWVk1VRmR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFFPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9OUxmbXJreVA4MU0iLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiOUxmbXJreVA4MU0iLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIxLS0tc24tNGd4eC0yNWdlbC5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9ZjRiN2U2YWU0YzhmZjM1M1x1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz00NTc1MDBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwiYmFkZ2VzIjpbeyJtZXRhZGF0YUJhZGdlUmVuZGVyZXIiOnsic3R5bGUiOiJCQURHRV9TVFlMRV9UWVBFX1NJTVBMRSIsImxhYmVsIjoiU291cy10aXRyZXMiLCJ0cmFja2luZ1BhcmFtcyI6IkNJSUJFSlExR0FRaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IlNvdXMtdGl0cmVzIn19fV0sInRyYWNraW5nUGFyYW1zIjoiQ0lJQkVKUTFHQVFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBsQTAtYV81T1RWLWR2MEFhb0JHbFZWVEZCWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFIiLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjExMyBtaWxsZcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjExM8Kga8KgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJWUJFUDZZQkJnR0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJWUJFUDZZQkJnR0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IjlMZm1ya3lQODFNIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJWUJFUDZZQkJnR0loTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyI5TGZtcmt5UDgxTSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIjlMZm1ya3lQODFNIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDSVlCRVA2WUJCZ0dJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSUlCRUpRMUdBUWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2dzNVRHWnRjbXQ1VURneFRRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSUlCRUpRMUdBUWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDSVVCRUk1aUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDSUlCRUpRMUdBUWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNJSUJFSlExR0FRaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMcKgaGV1cmUsIDEgbWludXRlIGV0IDE3wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjE6MDE6MTcifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSVFCRVBubkF4Z0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiI5TGZtcmt5UDgxTSIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0lRQkVQbm5BeGdDSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiOUxmbXJreVA4MU0ifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDSVFCRVBubkF4Z0NJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJTUJFTWZzQkJnREloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJTUJFTWZzQkJnREloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IjlMZm1ya3lQODFNIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJTUJFTWZzQkJnREloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyI5TGZtcmt5UDgxTSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIjlMZm1ya3lQODFNIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0lNQkVNZnNCQmdESWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJVUlNXWXZ5YzQyTSIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1VSU1dZdnljNDJNL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQU5VQmVhS1c0Tk1hMFJ3anFmZ01PQTY5ZnFydyIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9VUlNXWXZ5YzQyTS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEFiTHppdmd1X3UxOFZENGZPM1B1LW55S0dmdkEiLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1VSU1dZdnljNDJNL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQW54Q2VRTVgzd3otbFZXVi11N29EOHJjUHkyQSIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvVVJTV1l2eWM0Mk0vaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xCLVhCclZBakRfOExDNWpZbUJuclVMYkZ5TzB3Iiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJSYWlscyBDb25mIDIwMTMgVGhlIE1hZ2ljIFRyaWNrcyBvZiBUZXN0aW5nIGJ5IFNhbmRpIE1ldHogZGUgQ29uZnJlYWtzIGlsIHkgYSAxMCBhbnMgMzIgbWludXRlcyAxMDjigK8wMzDCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJSYWlscyBDb25mIDIwMTMgVGhlIE1hZ2ljIFRyaWNrcyBvZiBUZXN0aW5nIGJ5IFNhbmRpIE1ldHoifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSAxMCBhbnMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMTA44oCvMDMwwqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0gwUWxEVVlCU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVRJS1p5MW9hV2RvTFdOd2Rsb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dXcUFScFZWVXhRVjI1UWFtMXhkbXhxWTJGbVFUQjZNbFV4Wm5kTFVRPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PVVSU1dZdnljNDJNIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IlVSU1dZdnljNDJNIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyOS0tLXNuLTRneHgtMjVnZWwuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTUxMTQ5NjYyZmM5Y2UzNjNcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NDU3NTAwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0gwUWxEVVlCU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVVEanh2UGtyOHlsaWxHcUFScFZWVXhRVjI1UWFtMXhkbXhxWTJGbVFUQjZNbFV4Wm5kTFVRPT0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjEwOCBtaWxsZcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjEwOMKga8KgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJRUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJRUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IlVSU1dZdnljNDJNIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNJRUJFUDZZQkJnRkloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJVUlNXWXZ5YzQyTSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIlVSU1dZdnljNDJNIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDSUVCRVA2WUJCZ0ZJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSDBRbERVWUJTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0VlVsTlhXWFo1WXpReVRRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSDBRbERVWUJTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDSUFCRUk1aUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDSDBRbERVWUJTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNIMFFsRFVZQlNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMzIgbWludXRlcyBldCAyM8Kgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIzMjoyMyJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIOFEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6IlVSU1dZdnljNDJNIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSDhRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJVUlNXWXZ5YzQyTSJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNIOFEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0g0UXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0g0UXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiVVJTV1l2eWM0Mk0iLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0g0UXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIlVSU1dZdnljNDJNIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiVVJTV1l2eWM0Mk0iXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDSDRReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6Ii1QWDBCVjloR1pZIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvLVBYMEJWOWhHWlkvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xBVldZaVlwZHZBYWh6ZklGa2RQand0Rkh3NXlBIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLy1QWDBCVjloR1pZL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQ3B6MUVzNXh1X3g1UGtpV2ZWVnd2Q1dQQTczUSIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvLVBYMEJWOWhHWlkvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xCdlRKSldZWWlLd0NQZzh5TzhOUFJ5NzJZUnRBIiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8tUFgwQlY5aEdaWS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEJxSDV1U0xXVEVtdmxMWnh0OEZFOUp6T05lS1EiLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IiEhQ29uIDIwMTktIFRhaWwgQ2FsbCBPcHRpbWl6YXRpb246IFRoZSBNdXNpY2FsISEgYnkgQW5qYW5hIFZha2lsIFx1MDAyNiBOYXRhbGlhIE1hcmdvbGlzIGRlIENvbmZyZWFrcyBpbCB5IGEgNCBhbnMgMTEgbWludXRlcyBldCAyOMKgc2Vjb25kZXMgODjigK8xNDfCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIhIUNvbiAyMDE5LSBUYWlsIENhbGwgT3B0aW1pemF0aW9uOiBUaGUgTXVzaWNhbCEhIGJ5IEFuamFuYSBWYWtpbCBcdTAwMjYgTmF0YWxpYSBNYXJnb2xpcyJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDQgYW5zIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6Ijg44oCvMTQ3wqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hnUWxEVVlCaUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVRJS1p5MW9hV2RvTFdOd2Rsb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dXcUFScFZWVXhRVjI1UWFtMXhkbXhxWTJGbVFUQjZNbFV4Wm5kTFVRPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PS1QWDBCVjloR1pZIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6Ii1QWDBCVjloR1pZIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMy0tLXNuLTI1Z2xlbmw2Lmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1mOGY1ZjQwNTVmNjExOTk2XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTY0ODc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNIZ1FsRFVZQmlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21VQ1dzNFQ3MVlEOS12Z0JxZ0VhVlZWTVVGZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUU9Iiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI4OCBtaWxsZcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6Ijg4wqBrwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0h3UV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0h3UV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiLVBYMEJWOWhHWlkiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0h3UV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIi1QWDBCVjloR1pZIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiLVBYMEJWOWhHWlkiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNId1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIZ1FsRFVZQmlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3N0VUZnd1FsWTVhRWRhV1ElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIZ1FsRFVZQmlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNIc1FqbUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNIZ1FsRFVZQmlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0hnUWxEVVlCaUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxMSBtaW51dGVzIGV0IDI4wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjExOjI4In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hvUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiLVBYMEJWOWhHWlkiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIb1EtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6Ii1QWDBCVjloR1pZIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0hvUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSGtReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSGtReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiItUFgwQlY5aEdaWSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSGtReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiLVBYMEJWOWhHWlkiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyItUFgwQlY5aEdaWSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNIa1F4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiREMtcFFQcTBhY3MiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9EQy1wUVBxMGFjcy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTENRQWt6NWUwcFpHT2RodkN3aE5KVDdTTlBrWlEiLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvREMtcFFQcTBhY3MvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xDb2dwck1RQkRIazFucDN0SGdPcFNVaS13Wl9nIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9EQy1wUVBxMGFjcy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTENrTnE4QTh2eTBMY2k1eVJFX2VYaVpHcFM0RGciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0RDLXBRUHEwYWNzL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQzRSd2o1OS1lOUM4SWVkMHhmR2FEM0ExczhHQSIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWxvaGEgUnVieSBDb25mIDIwMTIgUmVmYWN0b3JpbmcgZnJvbSBHb29kIHRvIEdyZWF0IGJ5IEJlbiBPcmVuc3RlaW4gZGUgQ29uZnJlYWtzIGlsIHkgYSAxMCBhbnMgNDQgbWludXRlcyA4N+KArzAzM8KgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IkFsb2hhIFJ1YnkgQ29uZiAyMDEyIFJlZmFjdG9yaW5nIGZyb20gR29vZCB0byBHcmVhdCBieSBCZW4gT3JlbnN0ZWluIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgMTAgYW5zIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6Ijg34oCvMDMzwqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hNUWxEVVlCeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVRJS1p5MW9hV2RvTFdOd2Rsb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dXcUFScFZWVXhRVjI1UWFtMXhkbXhxWTJGbVFUQjZNbFV4Wm5kTFVRPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PURDLXBRUHEwYWNzIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IkRDLXBRUHEwYWNzIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMi0tLXNuLTI1Z2xlbmxkLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD0wYzJmYTk0MGZhYjQ2OWNiXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYyMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNITVFsRFVZQnlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21VREwwOUhWajZqcWx3eXFBUnBWVlV4UVYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVUT09Iiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI4NyBtaWxsZcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6Ijg3wqBrwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hjUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hjUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiREMtcFFQcTBhY3MiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hjUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIkRDLXBRUHEwYWNzIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiREMtcFFQcTBhY3MiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNIY1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNITVFsRFVZQnlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RFUXkxd1VWQnhNR0ZqY3clM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNITVFsRFVZQnlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNIWVFqbUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNITVFsRFVZQnlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0hNUWxEVVlCeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI0NCBtaW51dGVzIGV0IDE5wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjQ0OjE5In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0hVUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiREMtcFFQcTBhY3MiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIVVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IkRDLXBRUHEwYWNzIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0hVUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSFFReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSFFReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJEQy1wUVBxMGFjcyIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSFFReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiREMtcFFQcTBhY3MiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJEQy1wUVBxMGFjcyJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNIUVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiYjFxeDVobThIYkEiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9iMXF4NWhtOEhiQS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEJYeWZ1WjcxV0ZhN1pVMHZaSkgzc08wVFlmS0EiLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvYjFxeDVobThIYkEvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xBbEVkSXRWQ01MaGdwTnZSaWJrX0FBMUZ2QTF3Iiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9iMXF4NWhtOEhiQS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTENFYmNvRm1kdHQ1ZUhFY3d5bzhYdFRlMlZLZ0EiLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2IxcXg1aG04SGJBL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQV9kQzdUbTZOTzd1VGNEc0lmeXBYUFRTZHlzQSIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWFkaXNvbiBSdWJ5IDIwMTIgLSBDbHlkZSBTdHViYmxlZmllbGQgZGUgQ29uZnJlYWtzIGlsIHkgYSA3IGFucyA0MCBtaW51dGVzIDc54oCvMDY0wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiTWFkaXNvbiBSdWJ5IDIwMTIgLSBDbHlkZSBTdHViYmxlZmllbGQifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSA3IGFucyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiI3OeKArzA2NMKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHNFFsRFVZQ0NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21USUtaeTFvYVdkb0xXTndkbG9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHV3FBUnBWVlV4UVYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVUT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1iMXF4NWhtOEhiQSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJiMXF4NWhtOEhiQSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjItLS1zbi0yNWdsZW5lcy5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9NmY1YWIxZTYxOWJjMWRiMFx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MjM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDRzRRbERVWUNDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtVUN3dV9ETjRieXNyVy1xQVJwVlZVeFFWMjVRYW0xeGRteHFZMkZtUVRCNk1sVXhabmRMVVE9PSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNzkgbWlsbGXCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiI3OcKga8KgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNISVFfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNISVFfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6ImIxcXg1aG04SGJBIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNISVFfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJiMXF4NWhtOEhiQSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbImIxcXg1aG04SGJBIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDSElRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRzRRbERVWUNDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0aU1YRjROV2h0T0VoaVFRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRzRRbERVWUNDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDSEVRam1JaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRzRRbERVWUNDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNHNFFsRFVZQ0NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNDAgbWludXRlcyBldCA0M8Kgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiI0MDo0MyJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNIQVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6ImIxcXg1aG04SGJBIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDSEFRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJiMXF4NWhtOEhiQSJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNIQVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0c4UXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0c4UXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiYjFxeDVobThIYkEiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0c4UXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbImIxcXg1aG04SGJBIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiYjFxeDVobThIYkEiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRzhReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6InYtMnlGTXp4cXdVIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvdi0yeUZNenhxd1UvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xDUU1NaDVKTW8zcXFwbzFBa3EzLVl6X3ZzdEhRIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3YtMnlGTXp4cXdVL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQU1BRDlrYzZYVDVaS0oxNzlGaGxaMUliSVZ2ZyIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvdi0yeUZNenhxd1UvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xEM1ZBNVpRdUd3dk12VzZjNTdQWHE5Y2w0cFdRIiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92LTJ5Rk16eHF3VS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTERCbGttdlNNZ3JxaG9uTEplclBTUmlKVGN0RHciLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkdPUlVDTyAyMDA5IC0gU09MSUQgT2JqZWN0LU9yaWVudGVkIERlc2lnbiBieSBTYW5kaSBNZXR6IGRlIENvbmZyZWFrcyBpbCB5IGEgOCBhbnMgNDcgbWludXRlcyA3NeKArzgxMcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IkdPUlVDTyAyMDA5IC0gU09MSUQgT2JqZWN0LU9yaWVudGVkIERlc2lnbiBieSBTYW5kaSBNZXR6In0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJpbCB5IGEgOCBhbnMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiNzXigK84MTHCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR2tRbERVWUNTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtVElLWnkxb2FXZG9MV053ZGxvWVZVTlhibEJxYlhGMmJHcGpZV1pCTUhveVZURm1kMHRSbWdFRkVQSTRHR1dxQVJwVlZVeFFWMjVRYW0xeGRteHFZMkZtUVRCNk1sVXhabmRMVVE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9di0yeUZNenhxd1UiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoidi0yeUZNenhxd1UiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnI1LS0tc24tMjVnZTduemQuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWJmZWRiMjE0Y2NmMWFiMDVcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjIzNzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0drUWxEVVlDU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVVDRjFzYm56TUxzOXI4QnFnRWFWVlZNVUZkdVVHcHRjWFpzYW1OaFprRXdlakpWTVdaM1MxRT0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ijc1IG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiNzXCoGvCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRzBRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRzBRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJ2LTJ5Rk16eHF3VSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRzBRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsidi0yeUZNenhxd1UiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJ2LTJ5Rk16eHF3VSJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0cwUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0drUWxEVVlDU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndDJMVEo1UmsxNmVIRjNWUSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0drUWxEVVlDU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0d3UWptSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0drUWxEVVlDU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDR2tRbERVWUNTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjQ3IG1pbnV0ZXMgZXQgMTLCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiNDc6MTIifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR3NRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJ2LTJ5Rk16eHF3VSIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0dzUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoidi0yeUZNenhxd1UifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDR3NRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHb1F4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHb1F4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6InYtMnlGTXp4cXdVIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHb1F4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJ2LTJ5Rk16eHF3VSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbInYtMnlGTXp4cXdVIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0dvUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJPTVBmRVhJbFRWRSIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL09NUGZFWElsVFZFL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQVI5WEVCN29Jd2xQTk9sekdFb1I4VzVtWDdhZyIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PTVBmRVhJbFRWRS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTERRRnY4M3BJZEIyVG1UUzQtR053Q3U3LTZOUXciLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL09NUGZFWElsVFZFL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQnlzRGlhaXdmOThXOC01Vno4bDFZQ3p5ZjBwUSIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvT01QZkVYSWxUVkUvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xCd1NQbXJRcmhDTDBnNzRPNkdjTlhQaWIwSllBIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJSYWlsc0NvbmYgMjAxNSAtIE5vdGhpbmcgaXMgU29tZXRoaW5nIGRlIENvbmZyZWFrcyBpbCB5IGEgOCBhbnMgMzUgbWludXRlcyA2OOKArzg3McKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IlJhaWxzQ29uZiAyMDE1IC0gTm90aGluZyBpcyBTb21ldGhpbmcifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6ImlsIHkgYSA4IGFucyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiI2OOKArzg3McKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHUVFsRFVZQ2lJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21USUtaeTFvYVdkb0xXTndkbG9ZVlVOWGJsQnFiWEYyYkdwallXWkJNSG95VlRGbWQwdFJtZ0VGRVBJNEdHV3FBUnBWVlV4UVYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVUT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1PTVBmRVhJbFRWRSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJPTVBmRVhJbFRWRSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjQtLS1zbi0yNWdlN256ei5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9MzhjM2RmMTE3MjI1NGQ1MVx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MDUwMDBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDR1FRbERVWUNpSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtVURSbXBXUmwtTDM0VGlxQVJwVlZVeFFWMjVRYW0xeGRteHFZMkZtUVRCNk1sVXhabmRMVVE9PSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNjggbWlsbGXCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiI2OMKga8KgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHZ1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHZ1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6Ik9NUGZFWElsVFZFIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHZ1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJPTVBmRVhJbFRWRSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIk9NUGZFWElsVFZFIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDR2dRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR1FRbERVWUNpSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0UFRWQm1SVmhKYkZSV1JRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR1FRbERVWUNpSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDR2NRam1JaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDR1FRbERVWUNpSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNHUVFsRFVZQ2lJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMzUgbWludXRlcyBldCA1M8Kgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiIzNTo1MyJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHWVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6Ik9NUGZFWElsVFZFIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR1lRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJPTVBmRVhJbFRWRSJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNHWVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0dVUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0dVUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiT01QZkVYSWxUVkUiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0dVUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIk9NUGZFWElsVFZFIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiT01QZkVYSWxUVkUiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDR1VReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6IlRTMWxwS0JNa2dnIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvVFMxbHBLQk1rZ2cvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xBcEVxdDMzUTV5Y1VmWVRTNXNYR2JCUGdMbm5RIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1RTMWxwS0JNa2dnL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQVhlc19VTzMzRGxJV3BNVk0zd1o5UTNfdElIQSIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvVFMxbHBLQk1rZ2cvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xDYTl4UjhuWk5EX3g1Vm03ZzVwa3VmMTdPckZnIiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9UUzFscEtCTWtnZy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTERYN0pheWZzcmlrbGJiU0xvdUl2R3VDZ1I3MGciLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IlBhY2lmaWMgTm9ydGh3ZXN0IFNjYWxhIDIwMTMgV2UncmUgRG9pbmcgSXQgQWxsIFdyb25nIGJ5IFBhdWwgUGhpbGxpcHMgZGUgQ29uZnJlYWtzIGlsIHkgYSA5IGFucyA1MCBtaW51dGVzIDYz4oCvMDQwwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiUGFjaWZpYyBOb3J0aHdlc3QgU2NhbGEgMjAxMyBXZSdyZSBEb2luZyBJdCBBbGwgV3JvbmcgYnkgUGF1bCBQaGlsbGlwcyJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiaWwgeSBhIDkgYW5zIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjYz4oCvMDQwwqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0Y4UWxEVVlDeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVRJS1p5MW9hV2RvTFdOd2Rsb1lWVU5YYmxCcWJYRjJiR3BqWVdaQk1Ib3lWVEZtZDB0Um1nRUZFUEk0R0dXcUFScFZWVXhRVjI1UWFtMXhkbXhxWTJGbVFUQjZNbFV4Wm5kTFVRPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PVRTMWxwS0JNa2dnIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IlRTMWxwS0JNa2dnIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMy0tLXNuLTI1Z2xlbmU2Lmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD00ZDJkNjVhNGEwNGM5MjA4XHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYwNTAwMFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNGOFFsRFVZQ3lJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21VQ0lwTEtDeXJUWmxrMnFBUnBWVlV4UVYyNVFhbTF4ZG14cVkyRm1RVEI2TWxVeFpuZExVUT09Iiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI2MyBtaWxsZcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjYzwqBrwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0dNUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0dNUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiVFMxbHBLQk1rZ2ciLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0dNUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIlRTMWxwS0JNa2dnIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiVFMxbHBLQk1rZ2ciXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNHTVFfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGOFFsRFVZQ3lJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RVVXpGc2NFdENUV3RuWnclM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGOFFsRFVZQ3lJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNHSVFqbUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNGOFFsRFVZQ3lJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0Y4UWxEVVlDeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI1MCBtaW51dGVzIGV0IDQzwqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjUwOjQzIn0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0dFUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiVFMxbHBLQk1rZ2ciLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNHRVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IlRTMWxwS0JNa2dnIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0dFUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR0FReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR0FReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJUUzFscEtCTWtnZyIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDR0FReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiVFMxbHBLQk1rZ2ciXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJUUzFscEtCTWtnZyJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNHQVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNGd1F4amtpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInZpc2libGVJdGVtQ291bnQiOjQsIm5leHRCdXR0b24iOnsiYnV0dG9uUmVuZGVyZXIiOnsic3R5bGUiOiJTVFlMRV9ERUZBVUxUIiwic2l6ZSI6IlNJWkVfREVGQVVMVCIsImlzRGlzYWJsZWQiOmZhbHNlLCJpY29uIjp7Imljb25UeXBlIjoiQ0hFVlJPTl9SSUdIVCJ9LCJhY2Nlc3NpYmlsaXR5Ijp7ImxhYmVsIjoiU3VpdmFudCJ9LCJ0cmFja2luZ1BhcmFtcyI6IkNGNFE4RnNpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSwicHJldmlvdXNCdXR0b24iOnsiYnV0dG9uUmVuZGVyZXIiOnsic3R5bGUiOiJTVFlMRV9ERUZBVUxUIiwic2l6ZSI6IlNJWkVfREVGQVVMVCIsImlzRGlzYWJsZWQiOmZhbHNlLCJpY29uIjp7Imljb25UeXBlIjoiQ0hFVlJPTl9MRUZUIn0sImFjY2Vzc2liaWxpdHkiOnsibGFiZWwiOiJQcsOpY8OpZGVudGUifSwidHJhY2tpbmdQYXJhbXMiOiJDRjBROEZzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX19fSwidHJhY2tpbmdQYXJhbXMiOiJDRm9RM0J3WUFDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwicGxheUFsbEJ1dHRvbiI6eyJidXR0b25SZW5kZXJlciI6eyJzdHlsZSI6IlNUWUxFX1RFWFQiLCJzaXplIjoiU0laRV9ERUZBVUxUIiwiaXNEaXNhYmxlZCI6ZmFsc2UsInRleHQiOnsicnVucyI6W3sidGV4dCI6IlRvdXQgbGlyZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJQTEFZX0FMTCJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGc1E4RnNpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9ckk4dE5Nc296bzBcdTAwMjZsaXN0PVVVTFBXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6InJJOHROTXNvem8wIiwicGxheWxpc3RJZCI6IlVVTFBXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwibG9nZ2luZ0NvbnRleHQiOnsidnNzTG9nZ2luZ0NvbnRleHQiOnsic2VyaWFsaXplZENvbnRleHREYXRhIjoiR2hwVlZVeFFWMjVRYW0xeGRteHFZMkZtUVRCNk1sVXhabmRMVVElM0QlM0QifX0sIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjQtLS1zbi0yNWdlN256ci5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9YWM4ZjJkMzRjYjI4Y2U4ZFx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MjM3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDRnNROEZzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX19fV0sInRyYWNraW5nUGFyYW1zIjoiQ0ZrUXV5OFlBeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSJ9fSx7Iml0ZW1TZWN0aW9uUmVuZGVyZXIiOnsiY29udGVudHMiOlt7InNoZWxmUmVuZGVyZXIiOnsidGl0bGUiOnsicnVucyI6W3sidGV4dCI6IkRpZmZ1c2lvbnMgZW4gZGlyZWN0IHRlcm1pbsOpZXMiLCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNCa1EzQndZQUNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AQ29uZnJlYWtzL3ZpZGVvcz92aWV3PTJcdTAwMjZzb3J0PWRkXHUwMDI2bGl2ZV92aWV3PTUwM1x1MDAyNnNoZWxmX2lkPTAiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJwYXJhbXMiOiJFZ1oyYVdSbGIzTVlBeUFDT0FSd0FQSUdDUW9IZWdDaUFRSUlBUSUzRCUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQENvbmZyZWFrcyJ9fX1dfSwiZW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNCa1EzQndZQUNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AQ29uZnJlYWtzL3ZpZGVvcz92aWV3PTJcdTAwMjZzb3J0PWRkXHUwMDI2bGl2ZV92aWV3PTUwM1x1MDAyNnNoZWxmX2lkPTAiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJwYXJhbXMiOiJFZ1oyYVdSbGIzTVlBeUFDT0FSd0FQSUdDUW9IZWdDaUFRSUlBUSUzRCUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQENvbmZyZWFrcyJ9fSwiY29udGVudCI6eyJob3Jpem9udGFsTGlzdFJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoia1JWVUVZUHVhNEEiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rUlZVRVlQdWE0QS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEF2UE9WRGdhMWdyTXhMQU5ZRldocFRzdGZ2anciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkva1JWVUVZUHVhNEEvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xENDNMX25IV0hhMnNLRlhPUDc0dEJuVWJkRHF3Iiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rUlZVRVlQdWE0QS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTERpdElJbEZJVXZFcnppZGVQZjNtbDhGMGZrdUEiLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2tSVlVFWVB1YTRBL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQlo1RUJYWXpWS09BODFDb2lNRTliZTV1aUczQSIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiRGV2T3BzRGF5cyBCb3N0b24gZGUgQ29uZnJlYWtzIERpZmZ1c8OpIGlsIHkgYSA4IG1vaXMgNMKgaGV1cmVzIGV0IDM4IG1pbnV0ZXMgOTgzwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiRGV2T3BzRGF5cyBCb3N0b24ifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6IkRpZmZ1c8OpIGlsIHkgYSA4IG1vaXMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiOTgzwqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZRUWxEVVlBQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVRJR1p5MW9hV2RvV2hoVlExZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUdhQVFVUThqZ1liZz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1rUlZVRVlQdWE0QSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJrUlZVRVlQdWE0QSIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjUtLS1zbi0yNWdlN256Ni5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9OTExNTU0MTE4M2VlNmI4MFx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02NDg3NTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDRlFRbERVWUFDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtVUNBMTdtZm1JTFZpcEVCIiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI5ODPCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiI5ODPCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRmdRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRmdRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJrUlZVRVlQdWE0QSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRmdRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsia1JWVUVZUHVhNEEiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJrUlZVRVlQdWE0QSJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0ZnUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZRUWxEVVlBQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndHJVbFpWUlZsUWRXRTBRUSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZRUWxEVVlBQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0ZjUWptSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0ZRUWxEVVlBQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDRlFRbERVWUFDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjTCoGhldXJlcywgMzggbWludXRlcyBldCAzNcKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiI0OjM4OjM1In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZZUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoia1JWVUVZUHVhNEEiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGWVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6ImtSVlVFWVB1YTRBIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0ZZUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRlVReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRlVReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJrUlZVRVlQdWE0QSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRlVReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsia1JWVUVZUHVhNEEiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJrUlZVRVlQdWE0QSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNGVVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoidkZnYXlEbG5vNUEiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92RmdheURsbm81QS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEQ2MVhHNnAtNkhEVDNZYy1PMlNZZGlWck5Kc2ciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvdkZnYXlEbG5vNUEvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xCVEs2cjVYemx5dVhrMEstdDBqN0RMVG5LLWh3Iiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92RmdheURsbm81QS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTENXZDl4TVRtdWtGNy1PSktQU3lWcUR5S1ZHY2ciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3ZGZ2F5RGxubzVBL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQVd0MWNUQTExNlZmQklXM1BQU0MyUnNJajlRUSIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiRW1iZXJDb25mIDIwMjIgLSBNb25kYXkncyBCb251cyBDb250ZW50IGRlIENvbmZyZWFrcyBEaWZmdXPDqSBpbCB5IGEgMSBhbiAywqBoZXVyZXMgZXQgMjQgbWludXRlcyA1MDjCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJFbWJlckNvbmYgMjAyMiAtIE1vbmRheSdzIEJvbnVzIENvbnRlbnQifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6IkRpZmZ1c8OpIGlsIHkgYSAxIGFuIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjUwOMKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFOFFsRFVZQVNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21USUdaeTFvYVdkb1doaFZRMWR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFHYUFRVVE4amdZYmc9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9dkZnYXlEbG5vNUEiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoidkZnYXlEbG5vNUEiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIyLS0tc24tMjVnbGVubGsuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWJjNTgxYWM4Mzk2N2EzOTBcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjMzNzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0U4UWxEVVlBU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVVDUXg1N0xnOW1Hckx3QiIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNTA4wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiNTA4wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZNUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZNUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoidkZnYXlEbG5vNUEiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZNUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbInZGZ2F5RGxubzVBIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsidkZnYXlEbG5vNUEiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNGTVFfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFOFFsRFVZQVNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3QyUm1kaGVVUnNibTgxUVElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFOFFsRFVZQVNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNGSVFqbUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNFOFFsRFVZQVNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0U4UWxEVVlBU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIywqBoZXVyZXMsIDI0IG1pbnV0ZXMgZXQgNTDCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiMjoyNDo1MCJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNGRVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6InZGZ2F5RGxubzVBIiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRkVRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJ2RmdheURsbm81QSJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNGRVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZBUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZBUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoidkZnYXlEbG5vNUEiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0ZBUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbInZGZ2F5RGxubzVBIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsidkZnYXlEbG5vNUEiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRkFReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6Im9hU3hxbFY1N0xjIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvb2FTeHFsVjU3TGMvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xDS2FydTM0Tk14dklockJLZDlMa2pXaFJjaE1BIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL29hU3hxbFY1N0xjL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQXZ0a0oyeVAxRTV4NG9YZEdpV213aERiR3NuUSIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvb2FTeHFsVjU3TGMvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xBRG14NVZCWElrQWhiOHl1Y1pFN0NCdkxzMnp3Iiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9vYVN4cWxWNTdMYy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEFncEN6by1uZEx1RU5YVFVzNU1HNmRmdXFlbnciLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkVtYmVyQ29uZiAyMDIyIC0gRnJpZGF5J3MgYm9udXMgY29udGVudCBkZSBDb25mcmVha3MgRGlmZnVzw6kgaWwgeSBhIDEgYW4gMcKgaGV1cmUgZXQgMTAgbWludXRlcyA0MDbCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJFbWJlckNvbmYgMjAyMiAtIEZyaWRheSdzIGJvbnVzIGNvbnRlbnQifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6IkRpZmZ1c8OpIGlsIHkgYSAxIGFuIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjQwNsKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFb1FsRFVZQWlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21USUdaeTFvYVdkb1doaFZRMWR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFHYUFRVVE4amdZYmc9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9b2FTeHFsVjU3TGMiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoib2FTeHFsVjU3TGMiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIyLS0tc24tMjVnbGVuZXMuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWExYTRiMWFhNTU3OWVjYjdcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjQ4NzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0VvUWxEVVlBaUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVVDMzJlZXJwYldzMHFFQiIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNDA2wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiNDA2wqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0U0UV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0U0UV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoib2FTeHFsVjU3TGMiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0U0UV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIm9hU3hxbFY1N0xjIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsib2FTeHFsVjU3TGMiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNFNFFfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFb1FsRFVZQWlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3R2WVZONGNXeFdOVGRNWXclM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFb1FsRFVZQWlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNFMFFqbUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNFb1FsRFVZQWlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0VvUWxEVVlBaUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxwqBoZXVyZSwgMTAgbWludXRlcyBldCA0wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjE6MTA6MDQifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRXdRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJvYVN4cWxWNTdMYyIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0V3US1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoib2FTeHFsVjU3TGMifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRXdRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFc1F4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFc1F4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6Im9hU3hxbFY1N0xjIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFc1F4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJvYVN4cWxWNTdMYyJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIm9hU3hxbFY1N0xjIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0VzUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJwTGRDY29sUXN4QSIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3BMZENjb2xRc3hBL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQWYtZlBPYnJNcFo1WHctbjVBdGN1aTdYS213USIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wTGRDY29sUXN4QS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEQyZWtJeVhfS21lOTlxcDF1S0dQUDBSOE9GZkEiLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3BMZENjb2xRc3hBL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQlU0N1ZoS0FZaVpqMnJMSTlod1pQX1dTSWFQZyIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvcExkQ2NvbFFzeEEvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xEdlVVbjh6bk1URkdPWnRKZGtNSlRtODI5cndBIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJSdXN0Q29uZiAyMDIxIGRlIENvbmZyZWFrcyBEaWZmdXPDqSBpbCB5IGEgMSBhbiA4wqBoZXVyZXMgZXQgNyBtaW51dGVzIDEx4oCvMDkwwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiUnVzdENvbmYgMjAyMSJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiRGlmZnVzw6kgaWwgeSBhIDEgYW4ifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMTHigK8wOTDCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRVVRbERVWUF5SVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtVElHWnkxb2FXZG9XaGhWUTFkdVVHcHRjWFpzYW1OaFprRXdlakpWTVdaM1MxR2FBUVVROGpnWWJnPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PXBMZENjb2xRc3hBIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6InBMZENjb2xRc3hBIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyMy0tLXNuLTI1Z2xlbmxkLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD1hNGI3NDI3Mjg5NTBiMzEwXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYyMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNFVVFsRFVZQXlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21VQ1E1c0xLcU03UTI2UUIiLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjExIG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTHCoGvCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRWtRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRWtRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJwTGRDY29sUXN4QSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRWtRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsicExkQ2NvbFFzeEEiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJwTGRDY29sUXN4QSJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0VrUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VVUWxEVVlBeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndHdUR1JEWTI5c1VYTjRRUSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VVUWxEVVlBeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0VnUWptSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0VVUWxEVVlBeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDRVVRbERVWUF5SVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjjCoGhldXJlcywgNyBtaW51dGVzIGV0IDQ3wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6Ijg6MDc6NDcifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRWNRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJwTGRDY29sUXN4QSIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VjUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoicExkQ2NvbFFzeEEifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRWNRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFWVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFWVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6InBMZENjb2xRc3hBIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFWVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJwTGRDY29sUXN4QSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbInBMZENjb2xRc3hBIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0VZUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJSRDhhMlNyamllTSIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1JEOGEyU3JqaWVNL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQVI4NUlmOThjTVBoVnZvT3Y4V2Z3QWRlSzRfZyIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9SRDhhMlNyamllTS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEJpUFlTNG5uYVk5NFlraXN0YkRwMzllQ0FqUFEiLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1JEOGEyU3JqaWVNL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ0x2YXJ2a2I4R3UzZy1neUM4RHc5cU5NbEJKZyIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvUkQ4YTJTcmppZU0vaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xCNXhqNlRvc0NxeDlQSlhsWDYtald0RlNXLUtRIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJFbWJlckNvbmYgMjAyMSBUdWVzZGF5IE1hcmNoIDMwdGggZGUgQ29uZnJlYWtzIERpZmZ1c8OpIGlsIHkgYSAyIGFucyA5wqBoZXVyZXMgZXQgMTUgbWludXRlcyAz4oCvMDg5wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiRW1iZXJDb25mIDIwMjEgVHVlc2RheSBNYXJjaCAzMHRoIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJEaWZmdXPDqSBpbCB5IGEgMiBhbnMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiM+KArzA4OcKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFQVFsRFVZQkNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21USUdaeTFvYVdkb1doaFZRMWR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFHYUFRVVE4amdZYmc9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9UkQ4YTJTcmppZU0iLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiUkQ4YTJTcmppZU0iLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIyLS0tc24tMjVnbGVuZXouZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTQ0M2YxYWQ5MmFlMzg5ZTNcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjIzNzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0VBUWxEVVlCQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVVEams0N1hrdHZHbjBRPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMyBtaWxsZcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjPCoGvCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRVFRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRVFRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJSRDhhMlNyamllTSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRVFRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiUkQ4YTJTcmppZU0iXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJSRDhhMlNyamllTSJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0VRUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VBUWxEVVlCQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndFNSRGhoTWxOeWFtbGxUUSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VBUWxEVVlCQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0VNUWptSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0VBUWxEVVlCQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDRUFRbERVWUJDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjnCoGhldXJlcywgMTUgbWludXRlcyBldCA5wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6Ijk6MTU6MDkifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRUlRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJSRDhhMlNyamllTSIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0VJUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiUkQ4YTJTcmppZU0ifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRUlRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFRVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFRVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IlJEOGEyU3JqaWVNIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNFRVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJSRDhhMlNyamllTSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIlJEOGEyU3JqaWVNIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0VFUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiI2bzNXQjFPUWM4dyIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzZvM1dCMU9RYzh3L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQzFjbkRWUGw0YlN1NnlTQ3otTExmaTFfSnRLZyIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS82bzNXQjFPUWM4dy9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEJkamw4SjA2bzVpdjJzWGJIZTBabm40YnE5elEiLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpLzZvM1dCMU9RYzh3L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQVhtdTFFSGluTm16cExKMHZQeExPQTFSb25wQSIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvNm8zV0IxT1FjOHcvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xEdkpnSkgxbGZjMF9mV3ZmbHMxa1FVMXVPNzBnIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJFbWJlckNvbmYgMjAyMSBNb25kYXkgTWFyY2ggMjl0aCBkZSBDb25mcmVha3MgRGlmZnVzw6kgaWwgeSBhIDIgYW5zIDPCoGhldXJlcyBldCAzMSBtaW51dGVzIDLigK8zNzXCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJFbWJlckNvbmYgMjAyMSBNb25kYXkgTWFyY2ggMjl0aCJ9LCJwdWJsaXNoZWRUaW1lVGV4dCI6eyJzaW1wbGVUZXh0IjoiRGlmZnVzw6kgaWwgeSBhIDIgYW5zIn0sInZpZXdDb3VudFRleHQiOnsic2ltcGxlVGV4dCI6IjLigK8zNzXCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRHNRbERVWUJTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtVElHWnkxb2FXZG9XaGhWUTFkdVVHcHRjWFpzYW1OaFprRXdlakpWTVdaM1MxR2FBUVVROGpnWWJnPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PTZvM1dCMU9RYzh3Iiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IjZvM1dCMU9RYzh3Iiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNy0tLXNuLTRneHgtMjVnZTcuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPWVhOGRkNjA3NTM5MDczY2NcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9MzkxMjUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0RzUWxEVVlCU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVVETTU4R2M5Y0QxeHVvQiIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMiwzIG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMiwzwqBrwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0Q4UV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0Q4UV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiNm8zV0IxT1FjOHciLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0Q4UV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjZvM1dCMU9RYzh3Il0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiNm8zV0IxT1FjOHciXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNEOFFfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEc1FsRFVZQlNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3MyYnpOWFFqRlBVV000ZHclM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEc1FsRFVZQlNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNENFFqbUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNEc1FsRFVZQlNJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0RzUWxEVVlCU0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIzwqBoZXVyZXMsIDMxIG1pbnV0ZXMgZXQgNDXCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiMzozMTo0NSJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEMFEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6IjZvM1dCMU9RYzh3IiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRDBRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiI2bzNXQjFPUWM4dyJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNEMFEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0R3UXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0R3UXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoiNm8zV0IxT1FjOHciLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0R3UXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbIjZvM1dCMU9RYzh3Il0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsiNm8zV0IxT1FjOHciXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRHdReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6IkVTWE1nOU96V3JRIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvRVNYTWc5T3pXclEvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xDalpMcXBZTE55NmZTdE83YmFPNklhajBDS0p3Iiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0VTWE1nOU96V3JRL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQXEtM3d3c1NHMk53cVY3TW5ueWRsUmN2RjN4dyIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvRVNYTWc5T3pXclEvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xBekZTNHZSQWxiT2p4Nzg4MGhXZzZIaGNQc0hRIiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FU1hNZzlPeldyUS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTENGb21iNkpQcjUwa3hyRC1hRUhUOGR0MVpVLXciLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IlJ1c3RDb25mIDIwMjAgbGl2ZSBzdHJlYW0gZGUgQ29uZnJlYWtzIERpZmZ1c8OpIGlsIHkgYSAyIGFucyA3wqBoZXVyZXMgZXQgNDggbWludXRlcyAxNOKArzIwMcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IlJ1c3RDb25mIDIwMjAgbGl2ZSBzdHJlYW0ifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6IkRpZmZ1c8OpIGlsIHkgYSAyIGFucyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIxNOKArzIwMcKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEWVFsRFVZQmlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21USUdaeTFvYVdkb1doaFZRMWR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFHYUFRVVE4amdZYmc9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9RVNYTWc5T3pXclEiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiRVNYTWc5T3pXclEiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIzLS0tc24tMjVnbGVubHouZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTExMjVjYzgzZDNiMzVhYjRcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjQ4NzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0RZUWxEVVlCaUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVVDMHRjMmR2WkR6a2hFPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMTQgbWlsbGXCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIxNMKga8KgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEb1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEb1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IkVTWE1nOU96V3JRIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEb1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJFU1hNZzlPeldyUSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIkVTWE1nOU96V3JRIl19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRG9RX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRFlRbERVWUJpSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0RlUxaE5aemxQZWxkeVVRJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRFlRbERVWUJpSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDRGtRam1JaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDRFlRbERVWUJpSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNEWVFsRFVZQmlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiN8KgaGV1cmVzLCA0OCBtaW51dGVzIGV0IDM5wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6Ijc6NDg6MzkifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRGdRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJFU1hNZzlPeldyUSIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RnUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiRVNYTWc5T3pXclEifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDRGdRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEY1F4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEY1F4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IkVTWE1nOU96V3JRIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNEY1F4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJFU1hNZzlPeldyUSJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIkVTWE1nOU96V3JRIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0RjUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJFUmVvVnBiOUxKbyIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0VSZW9WcGI5TEpvL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMQW9hUTVMX1FBZEZkTjFCMFlnM3F4S0VlOWpJZyIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FUmVvVnBiOUxKby9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEJRYTZxT25BQ1VvWGFKRWNPWHZzTDNXRVBOMUEiLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0VSZW9WcGI5TEpvL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQm4wRTgwQld1U1hmaDg3Tkh4eW9ENFNzOGJhQSIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvRVJlb1ZwYjlMSm8vaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xDaXo0Ml90clZwUHZRRkhycFRMUk1zUVhHZWZBIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIhIUNvbiAtIFN1bmRheSBNYXkgMTAsIDIwMjAgZGUgQ29uZnJlYWtzIERpZmZ1c8OpIGlsIHkgYSAzIGFucyA2wqBoZXVyZXMgZXQgMjYgbWludXRlcyA24oCvMDcywqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiISFDb24gLSBTdW5kYXkgTWF5IDEwLCAyMDIwIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJEaWZmdXPDqSBpbCB5IGEgMyBhbnMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiNuKArzA3MsKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNERVFsRFVZQnlJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21USUdaeTFvYVdkb1doaFZRMWR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFHYUFRVVE4amdZYmc9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9RVJlb1ZwYjlMSm8iLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoiRVJlb1ZwYjlMSm8iLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIyLS0tc24tMjVnbGVubGsuZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTExMTdhODU2OTZmZDJjOWFcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjQ4NzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0RFUWxEVVlCeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVVDYTJmUzM2WXJxaXhFPSIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNiBtaWxsZcKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IjbCoGvCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRFVRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRFVRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJFUmVvVnBiOUxKbyIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRFVRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiRVJlb1ZwYjlMSm8iXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJFUmVvVnBiOUxKbyJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0RVUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RFUWxEVVlCeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndEZVbVZ2Vm5CaU9VeEtidyUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RFUWxEVVlCeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0RRUWptSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0RFUWxEVVlCeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDREVRbERVWUJ5SVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjbCoGhldXJlcywgMjYgbWludXRlcyBldCA0MMKgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiI2OjI2OjQwIn0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0RNUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiRVJlb1ZwYjlMSm8iLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNETVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IkVSZW9WcGI5TEpvIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0RNUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRElReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRElReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJFUmVvVnBiOUxKbyIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDRElReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiRVJlb1ZwYjlMSm8iXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJFUmVvVnBiOUxKbyJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNESVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiUUVaME4wcnJiTDAiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9RRVowTjBycmJMMC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTENicVpJSHVrcFRyLUhvSlF3YWVzbVRxaV9GNGciLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvUUVaME4wcnJiTDAvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xDX291RGo3U2hwODc1cHUtU0l2c1JpejM5NDd3Iiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9RRVowTjBycmJMMC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEQxWXJXeklzN3FwR1d3a2lsNVlRbEJ1eVVfMHciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL1FFWjBOMHJyYkwwL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQkNLS1BNR2x2bldheEV0ME9jd1NyOXJwR0Z3dyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiISFDb24gLSBTYXR1cmRheSBNYXkgOSwgMjAyMCBkZSBDb25mcmVha3MgRGlmZnVzw6kgaWwgeSBhIDMgYW5zIDfCoGhldXJlcyBldCA0IG1pbnV0ZXMgMTDigK8yMTLCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIhIUNvbiAtIFNhdHVyZGF5IE1heSA5LCAyMDIwIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJEaWZmdXPDqSBpbCB5IGEgMyBhbnMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMTDigK8yMTLCoHZ1ZXMifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ3dRbERVWUNDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtVElHWnkxb2FXZG9XaGhWUTFkdVVHcHRjWFpzYW1OaFprRXdlakpWTVdaM1MxR2FBUVVROGpnWWJnPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii93YXRjaD92PVFFWjBOMHJyYkwwIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1dBVENIIiwicm9vdFZlIjozODMyfX0sIndhdGNoRW5kcG9pbnQiOnsidmlkZW9JZCI6IlFFWjBOMHJyYkwwIiwid2F0Y2hFbmRwb2ludFN1cHBvcnRlZE9uZXNpZUNvbmZpZyI6eyJodG1sNVBsYXliYWNrT25lc2llQ29uZmlnIjp7ImNvbW1vbkNvbmZpZyI6eyJ1cmwiOiJodHRwczovL3JyNS0tLXNuLTI1Z2U3bnpkLmdvb2dsZXZpZGVvLmNvbS9pbml0cGxheWJhY2s/c291cmNlPXlvdXR1YmVcdTAwMjZvZWlzPTFcdTAwMjZjPVdFQlx1MDAyNm9hZD0zMjAwXHUwMDI2b3ZkPTMyMDBcdTAwMjZvYWFkPTExMDAwXHUwMDI2b2F2ZD0xMTAwMFx1MDAyNm9jcz03MDBcdTAwMjZvZXdpcz0xXHUwMDI2b3B1dGM9MVx1MDAyNm9mcGNjPTFcdTAwMjZtc3A9MVx1MDAyNm9kZXB2PTFcdTAwMjZpZD00MDQ2NzQzNzRhZWI2Y2JkXHUwMDI2aXA9MzcuMTcxLjIwMC41OVx1MDAyNmluaXRjd25kYnBzPTYzMzc1MFx1MDAyNm10PTE2ODYyNDg3MTVcdTAwMjZvd2V1Yz1cdTAwMjZweHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOd1x1MDAyNnJ4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53JTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPQSUyQ0NnNEtBblI0RWdneU5EUTNNalF5T1ElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TWclMkNDZzRLQW5SNEVnZ3lORFEzTWpRek13In19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNDd1FsRFVZQ0NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21VQzkyYTNYOUlhZG8wQT0iLCJzaG9ydFZpZXdDb3VudFRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjEwIG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMTDCoGvCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDREFRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDREFRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJRRVowTjBycmJMMCIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDREFRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiUUVaME4wcnJiTDAiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJRRVowTjBycmJMMCJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0RBUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0N3UWxEVVlDQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndFJSVm93VGpCeWNtSk1NQSUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0N3UWxEVVlDQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0M4UWptSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0N3UWxEVVlDQ0lUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDQ3dRbERVWUNDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjfCoGhldXJlcywgNCBtaW51dGVzIGV0IDUxwqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6Ijc6MDQ6NTEifSwic3R5bGUiOiJERUZBVUxUIn19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7ImlzVG9nZ2xlZCI6ZmFsc2UsInVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJXQVRDSF9MQVRFUiJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkNIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQzRRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhZGRlZFZpZGVvSWQiOiJRRVowTjBycmJMMCIsImFjdGlvbiI6IkFDVElPTl9BRERfVklERU8ifV19fSwidG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0M0US1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWN0aW9uIjoiQUNUSU9OX1JFTU9WRV9WSURFT19CWV9WSURFT19JRCIsInJlbW92ZWRWaWRlb0lkIjoiUUVaME4wcnJiTDAifV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDQzRRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheVRvZ2dsZUJ1dHRvblJlbmRlcmVyIjp7InVudG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJ0b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IlBMQVlMSVNUX0FERF9DSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDMFF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDMFF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6IlFFWjBOMHJyYkwwIiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDMFF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJRRVowTjBycmJMMCJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbIlFFWjBOMHJyYkwwIl19fV19fSwidW50b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0MwUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlOb3dQbGF5aW5nUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiRW4gY291cnMgZGUgbGVjdHVyZSJ9XX19fV19fSx7ImdyaWRWaWRlb1JlbmRlcmVyIjp7InZpZGVvSWQiOiJ2T2JvZ3ljaTdtOCIsInRodW1ibmFpbCI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3ZPYm9neWNpN204L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ0tnQkVGNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMRFNla3BndTJSQXBUWlUySURPa3lDdGdUMlRoUSIsIndpZHRoIjoxNjgsImhlaWdodCI6OTR9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92T2JvZ3ljaTdtOC9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNNUUJFRzVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTEM5Rk9PcUgwZnE1RVZhb1VxQTY5RXVlV0gwOVEiLCJ3aWR0aCI6MTk2LCJoZWlnaHQiOjExMH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL3ZPYm9neWNpN204L2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ1BZQkVJb0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMQ1JFRkpWd2hkTjRTdnhzZzlHZE1ybUlpR09odyIsIndpZHRoIjoyNDYsImhlaWdodCI6MTM4fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvdk9ib2d5Y2k3bTgvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDTkFDRUx3QlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xBb0k2X05FT2tXX1FvTk5DREhDSFhSR2o1em9nIiwid2lkdGgiOjMzNiwiaGVpZ2h0IjoxODh9XX0sInRpdGxlIjp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJFbWJlckNvbmYgMjAyMCAtIFdlZG5lc2RheSBNYXJjaCAxOHRoIFBhcnQgMiBkZSBDb25mcmVha3MgRGlmZnVzw6kgaWwgeSBhIDMgYW5zIDfCoGhldXJlcyBldCA3IG1pbnV0ZXMgMuKArzAzOMKgdnVlcyJ9fSwic2ltcGxlVGV4dCI6IkVtYmVyQ29uZiAyMDIwIC0gV2VkbmVzZGF5IE1hcmNoIDE4dGggUGFydCAyIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJEaWZmdXPDqSBpbCB5IGEgMyBhbnMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMuKArzAzOMKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDY1FsRFVZQ1NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21USUdaeTFvYVdkb1doaFZRMWR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFHYUFRVVE4amdZYmc9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9dk9ib2d5Y2k3bTgiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoidk9ib2d5Y2k3bTgiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIxMy0tLXNuLTRneHgtMjVneS5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9YmNlNmU4ODMyNzIyZWU2Zlx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz0zOTEyNTBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDQ2NRbERVWUNTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtVUR2M0l1NXNwQzY4N3dCIiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIyIG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMsKga8KgdnVlcyJ9LCJtZW51Ijp7Im1lbnVSZW5kZXJlciI6eyJpdGVtcyI6W3sibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBRERfVE9fUVVFVUVfVEFJTCJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDc1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDc1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJhZGRUb1BsYXlsaXN0Q29tbWFuZCI6eyJvcGVuTWluaXBsYXllciI6dHJ1ZSwidmlkZW9JZCI6InZPYm9neWNpN204IiwibGlzdFR5cGUiOiJQTEFZTElTVF9FRElUX0xJU1RfVFlQRV9RVUVVRSIsIm9uQ3JlYXRlTGlzdENvbW1hbmQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDc1FfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvcGxheWxpc3QvY3JlYXRlIn19LCJjcmVhdGVQbGF5bGlzdFNlcnZpY2VFbmRwb2ludCI6eyJ2aWRlb0lkcyI6WyJ2T2JvZ3ljaTdtOCJdLCJwYXJhbXMiOiJDQVElM0QifX0sInZpZGVvSWRzIjpbInZPYm9neWNpN204Il19fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDQ3NRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsibWVudVNlcnZpY2VJdGVtUmVuZGVyZXIiOnsidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFydGFnZXIifV19LCJpY29uIjp7Imljb25UeXBlIjoiU0hBUkUifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ2NRbERVWUNTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3NoYXJlL2dldF9zaGFyZV9wYW5lbCJ9fSwic2hhcmVFbnRpdHlTZXJ2aWNlRW5kcG9pbnQiOnsic2VyaWFsaXplZFNoYXJlRW50aXR5IjoiQ2d0MlQySnZaM2xqYVRkdE9BJTNEJTNEIiwiY29tbWFuZHMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ2NRbERVWUNTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7InVuaWZpZWRTaGFyZVBhbmVsUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDQ29Ram1JaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJzaG93TG9hZGluZ1NwaW5uZXIiOnRydWV9fSwicG9wdXBUeXBlIjoiRElBTE9HIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDQ2NRbERVWUNTSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiaGFzU2VwYXJhdG9yIjp0cnVlfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNDY1FsRFVZQ1NJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiTWVudSBkJ2FjdGlvbnMifX19fSwidGh1bWJuYWlsT3ZlcmxheXMiOlt7InRodW1ibmFpbE92ZXJsYXlUaW1lU3RhdHVzUmVuZGVyZXIiOnsidGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiN8KgaGV1cmVzLCA3IG1pbnV0ZXMgZXQgNDXCoHNlY29uZGVzIn19LCJzaW1wbGVUZXh0IjoiNzowNzo0NSJ9LCJzdHlsZSI6IkRFRkFVTFQifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsiaXNUb2dnbGVkIjpmYWxzZSwidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IldBVENIX0xBVEVSIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IsOAIHJlZ2FyZGVyIHBsdXMgdGFyZCIsInRvZ2dsZWRUb29sdGlwIjoiQWpvdXTDqWUiLCJ1bnRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDa1EtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFkZGVkVmlkZW9JZCI6InZPYm9neWNpN204IiwiYWN0aW9uIjoiQUNUSU9OX0FERF9WSURFTyJ9XX19LCJ0b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ2tRLWVjREdBRWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZS9lZGl0X3BsYXlsaXN0In19LCJwbGF5bGlzdEVkaXRFbmRwb2ludCI6eyJwbGF5bGlzdElkIjoiV0wiLCJhY3Rpb25zIjpbeyJhY3Rpb24iOiJBQ1RJT05fUkVNT1ZFX1ZJREVPX0JZX1ZJREVPX0lEIiwicmVtb3ZlZFZpZGVvSWQiOiJ2T2JvZ3ljaTdtOCJ9XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNDa1EtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5VG9nZ2xlQnV0dG9uUmVuZGVyZXIiOnsidW50b2dnbGVkSWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiUExBWUxJU1RfQUREX0NIRUNLIn0sInVudG9nZ2xlZFRvb2x0aXAiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NnUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NnUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoidk9ib2d5Y2k3bTgiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NnUXgtd0VHQUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbInZPYm9neWNpN204Il0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsidk9ib2d5Y2k3bTgiXX19XX19LCJ1bnRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXRlciDDoCBsYSBmaWxlIGQnYXR0ZW50ZSJ9fSwidG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dMOpZSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDQ2dReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsidGh1bWJuYWlsT3ZlcmxheU5vd1BsYXlpbmdSZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJFbiBjb3VycyBkZSBsZWN0dXJlIn1dfX19XX19LHsiZ3JpZFZpZGVvUmVuZGVyZXIiOnsidmlkZW9JZCI6Imt3YmFQUzZwSXBZIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkva3diYVBTNnBJcFkvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDS2dCRUY1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xBTGRNVllraUxzb1hORUoyeVRCVHlmV3NJc1VBIiwid2lkdGgiOjE2OCwiaGVpZ2h0Ijo5NH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL2t3YmFQUzZwSXBZL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VpQ01RQkVHNUlXdktyaXFrREZRZ0JGUUFBQUFBWUFTVUFBTWhDUFFDQW9rTjRBUT09XHUwMDI2cnM9QU9uNENMRDE5VG9qeEZVbGx2NVd6UWp1V1djYVdFbG1aZyIsIndpZHRoIjoxOTYsImhlaWdodCI6MTEwfSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkva3diYVBTNnBJcFkvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWpDUFlCRUlvQlNGcnlxNHFwQXhVSUFSVUFBQUFBR0FFbEFBRElRajBBZ0tKRGVBRT1cdTAwMjZycz1BT240Q0xCX2FOU0NtUWwxb2NpSExWUDRpdXgxVUVqTmtRIiwid2lkdGgiOjI0NiwiaGVpZ2h0IjoxMzh9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rd2JhUFM2cElwWS9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNOQUNFTHdCU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEJPcjcwZnp5NE13c2FHMVl1TU1TX2ZTVnZDTFEiLCJ3aWR0aCI6MzM2LCJoZWlnaHQiOjE4OH1dfSwidGl0bGUiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkVtYmVyQ29uZiAyMDIwIC0gV2VkbmVzZGF5IE1hcmNoIDE4dGggZGUgQ29uZnJlYWtzIERpZmZ1c8OpIGlsIHkgYSAzIGFucyA0OSBtaW51dGVzIDHigK8zMjTCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiJFbWJlckNvbmYgMjAyMCAtIFdlZG5lc2RheSBNYXJjaCAxOHRoIn0sInB1Ymxpc2hlZFRpbWVUZXh0Ijp7InNpbXBsZVRleHQiOiJEaWZmdXPDqSBpbCB5IGEgMyBhbnMifSwidmlld0NvdW50VGV4dCI6eyJzaW1wbGVUZXh0IjoiMeKArzMyNMKgdnVlcyJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDSVFsRFVZQ2lJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21USUdaeTFvYVdkb1doaFZRMWR1VUdwdGNYWnNhbU5oWmtFd2VqSlZNV1ozUzFHYUFRVVE4amdZYmc9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3dhdGNoP3Y9a3diYVBTNnBJcFkiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfV0FUQ0giLCJyb290VmUiOjM4MzJ9fSwid2F0Y2hFbmRwb2ludCI6eyJ2aWRlb0lkIjoia3diYVBTNnBJcFkiLCJ3YXRjaEVuZHBvaW50U3VwcG9ydGVkT25lc2llQ29uZmlnIjp7Imh0bWw1UGxheWJhY2tPbmVzaWVDb25maWciOnsiY29tbW9uQ29uZmlnIjp7InVybCI6Imh0dHBzOi8vcnIzLS0tc24tMjVnbGVuZXouZ29vZ2xldmlkZW8uY29tL2luaXRwbGF5YmFjaz9zb3VyY2U9eW91dHViZVx1MDAyNm9laXM9MVx1MDAyNmM9V0VCXHUwMDI2b2FkPTMyMDBcdTAwMjZvdmQ9MzIwMFx1MDAyNm9hYWQ9MTEwMDBcdTAwMjZvYXZkPTExMDAwXHUwMDI2b2NzPTcwMFx1MDAyNm9ld2lzPTFcdTAwMjZvcHV0Yz0xXHUwMDI2b2ZwY2M9MVx1MDAyNm1zcD0xXHUwMDI2b2RlcHY9MVx1MDAyNmlkPTkzMDZkYTNkMmVhOTIyOTZcdTAwMjZpcD0zNy4xNzEuMjAwLjU5XHUwMDI2aW5pdGN3bmRicHM9NjIzNzUwXHUwMDI2bXQ9MTY4NjI0ODcxNVx1MDAyNm93ZXVjPVx1MDAyNnB4dGFncz1DZzRLQW5SNEVnZ3lORFEzTWpReU53XHUwMDI2cnh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TnclMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9BJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXlPUSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TUElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNZyUyQ0NnNEtBblI0RWdneU5EUTNNalF6TXcifX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0NJUWxEVVlDaUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVVDV3hhVDEwc2UyZzVNQiIsInNob3J0Vmlld0NvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiMSwzIG1pbGxlwqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiMSwzwqBrwqB2dWVzIn0sIm1lbnUiOnsibWVudVJlbmRlcmVyIjp7Iml0ZW1zIjpbeyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IkFERF9UT19RVUVVRV9UQUlMIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NZUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWV9fSwic2lnbmFsU2VydmljZUVuZHBvaW50Ijp7InNpZ25hbCI6IkNMSUVOVF9TSUdOQUwiLCJhY3Rpb25zIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NZUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImFkZFRvUGxheWxpc3RDb21tYW5kIjp7Im9wZW5NaW5pcGxheWVyIjp0cnVlLCJ2aWRlb0lkIjoia3diYVBTNnBJcFkiLCJsaXN0VHlwZSI6IlBMQVlMSVNUX0VESVRfTElTVF9UWVBFX1FVRVVFIiwib25DcmVhdGVMaXN0Q29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NZUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9wbGF5bGlzdC9jcmVhdGUifX0sImNyZWF0ZVBsYXlsaXN0U2VydmljZUVuZHBvaW50Ijp7InZpZGVvSWRzIjpbImt3YmFQUzZwSXBZIl0sInBhcmFtcyI6IkNBUSUzRCJ9fSwidmlkZW9JZHMiOlsia3diYVBTNnBJcFkiXX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNDWVFfcGdFR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJtZW51U2VydmljZUl0ZW1SZW5kZXJlciI6eyJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJQYXJ0YWdlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJTSEFSRSJ9LCJzZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDSVFsRFVZQ2lJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvc2hhcmUvZ2V0X3NoYXJlX3BhbmVsIn19LCJzaGFyZUVudGl0eVNlcnZpY2VFbmRwb2ludCI6eyJzZXJpYWxpemVkU2hhcmVFbnRpdHkiOiJDZ3RyZDJKaFVGTTJjRWx3V1ElM0QlM0QiLCJjb21tYW5kcyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDSVFsRFVZQ2lJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJvcGVuUG9wdXBBY3Rpb24iOnsicG9wdXAiOnsidW5pZmllZFNoYXJlUGFuZWxSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNDVVFqbUlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInNob3dMb2FkaW5nU3Bpbm5lciI6dHJ1ZX19LCJwb3B1cFR5cGUiOiJESUFMT0ciLCJiZVJldXNlZCI6dHJ1ZX19XX19LCJ0cmFja2luZ1BhcmFtcyI6IkNDSVFsRFVZQ2lJVENJamMxX2FudFA4Q0ZkeENUd1Fkei1jQ21RPT0iLCJoYXNTZXBhcmF0b3IiOnRydWV9fV0sInRyYWNraW5nUGFyYW1zIjoiQ0NJUWxEVVlDaUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJNZW51IGQnYWN0aW9ucyJ9fX19LCJ0aHVtYm5haWxPdmVybGF5cyI6W3sidGh1bWJuYWlsT3ZlcmxheVRpbWVTdGF0dXNSZW5kZXJlciI6eyJ0ZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiI0OSBtaW51dGVzIGV0IDQ1wqBzZWNvbmRlcyJ9fSwic2ltcGxlVGV4dCI6IjQ5OjQ1In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0NRUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoia3diYVBTNnBJcFkiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNDUVEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6Imt3YmFQUzZwSXBZIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0NRUS1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ01ReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ01ReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJrd2JhUFM2cElwWSIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ01ReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsia3diYVBTNnBJcFkiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJrd2JhUFM2cElwWSJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNDTVF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX0seyJncmlkVmlkZW9SZW5kZXJlciI6eyJ2aWRlb0lkIjoiRC1hdlkzZEcyWmsiLCJ0aHVtYm5haWwiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9ELWF2WTNkRzJaay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFaUNLZ0JFRjVJV3ZLcmlxa0RGUWdCRlFBQUFBQVlBU1VBQU1oQ1BRQ0Fva040QVE9PVx1MDAyNnJzPUFPbjRDTER5VUJ6ZDNtekxhUm8zY29KUVhJc2NDQ0JMZUEiLCJ3aWR0aCI6MTY4LCJoZWlnaHQiOjk0fSx7InVybCI6Imh0dHBzOi8vaS55dGltZy5jb20vdmkvRC1hdlkzZEcyWmsvaHFkZWZhdWx0LmpwZz9zcXA9LW9heW13RWlDTVFCRUc1SVd2S3JpcWtERlFnQkZRQUFBQUFZQVNVQUFNaENQUUNBb2tONEFRPT1cdTAwMjZycz1BT240Q0xCb20yNkFsNy1iSUdrVWhxSldCTkJQY0tWM1lBIiwid2lkdGgiOjE5NiwiaGVpZ2h0IjoxMTB9LHsidXJsIjoiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9ELWF2WTNkRzJaay9ocWRlZmF1bHQuanBnP3NxcD0tb2F5bXdFakNQWUJFSW9CU0ZyeXE0cXBBeFVJQVJVQUFBQUFHQUVsQUFESVFqMEFnS0pEZUFFPVx1MDAyNnJzPUFPbjRDTEQ0dURheGs0SUhEX1RfNVVyU3JXTWVIN0VQU3ciLCJ3aWR0aCI6MjQ2LCJoZWlnaHQiOjEzOH0seyJ1cmwiOiJodHRwczovL2kueXRpbWcuY29tL3ZpL0QtYXZZM2RHMlprL2hxZGVmYXVsdC5qcGc/c3FwPS1vYXltd0VqQ05BQ0VMd0JTRnJ5cTRxcEF4VUlBUlVBQUFBQUdBRWxBQURJUWowQWdLSkRlQUU9XHUwMDI2cnM9QU9uNENMRFZvX0ZoMWZab0VjUTE0LU8td2dSNTFoUG5yZyIsIndpZHRoIjozMzYsImhlaWdodCI6MTg4fV19LCJ0aXRsZSI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiRW1iZXJDb25mIDIwMjAgLSBUdWVzZGF5IE1hcmNoIDE3dGggLSBQYXJ0IDIgZGUgQ29uZnJlYWtzIERpZmZ1c8OpIGlsIHkgYSAzIGFucyA0wqBoZXVyZXMgZXQgNDAgbWludXRlcyAx4oCvODQ5wqB2dWVzIn19LCJzaW1wbGVUZXh0IjoiRW1iZXJDb25mIDIwMjAgLSBUdWVzZGF5IE1hcmNoIDE3dGggLSBQYXJ0IDIifSwicHVibGlzaGVkVGltZVRleHQiOnsic2ltcGxlVGV4dCI6IkRpZmZ1c8OpIGlsIHkgYSAzIGFucyJ9LCJ2aWV3Q291bnRUZXh0Ijp7InNpbXBsZVRleHQiOiIx4oCvODQ5wqB2dWVzIn0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0IwUWxEVVlDeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVRJR1p5MW9hV2RvV2hoVlExZHVVR3B0Y1hac2FtTmhaa0V3ZWpKVk1XWjNTMUdhQVFVUThqZ1liZz09IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvd2F0Y2g/dj1ELWF2WTNkRzJaayIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9XQVRDSCIsInJvb3RWZSI6MzgzMn19LCJ3YXRjaEVuZHBvaW50Ijp7InZpZGVvSWQiOiJELWF2WTNkRzJaayIsIndhdGNoRW5kcG9pbnRTdXBwb3J0ZWRPbmVzaWVDb25maWciOnsiaHRtbDVQbGF5YmFja09uZXNpZUNvbmZpZyI6eyJjb21tb25Db25maWciOnsidXJsIjoiaHR0cHM6Ly9ycjItLS1zbi0yNWdlN256ay5nb29nbGV2aWRlby5jb20vaW5pdHBsYXliYWNrP3NvdXJjZT15b3V0dWJlXHUwMDI2b2Vpcz0xXHUwMDI2Yz1XRUJcdTAwMjZvYWQ9MzIwMFx1MDAyNm92ZD0zMjAwXHUwMDI2b2FhZD0xMTAwMFx1MDAyNm9hdmQ9MTEwMDBcdTAwMjZvY3M9NzAwXHUwMDI2b2V3aXM9MVx1MDAyNm9wdXRjPTFcdTAwMjZvZnBjYz0xXHUwMDI2bXNwPTFcdTAwMjZvZGVwdj0xXHUwMDI2aWQ9MGZlNmFmNjM3NzQ2ZDk5OVx1MDAyNmlwPTM3LjE3MS4yMDAuNTlcdTAwMjZpbml0Y3duZGJwcz02MDUwMDBcdTAwMjZtdD0xNjg2MjQ4NzE1XHUwMDI2b3dldWM9XHUwMDI2cHh0YWdzPUNnNEtBblI0RWdneU5EUTNNalF5TndcdTAwMjZyeHRhZ3M9Q2c0S0FuUjRFZ2d5TkRRM01qUXlOdyUyQ0NnNEtBblI0RWdneU5EUTNNalF5T0ElMkNDZzRLQW5SNEVnZ3lORFEzTWpReU9RJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNQSUyQ0NnNEtBblI0RWdneU5EUTNNalF6TVElMkNDZzRLQW5SNEVnZ3lORFEzTWpRek1nJTJDQ2c0S0FuUjRFZ2d5TkRRM01qUXpNdyJ9fX19fSwidHJhY2tpbmdQYXJhbXMiOiJDQjBRbERVWUN5SVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtVUNaczV1NnQteXI4dzg9Iiwic2hvcnRWaWV3Q291bnRUZXh0Ijp7ImFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiIxLDggbWlsbGXCoHZ1ZXMifX0sInNpbXBsZVRleHQiOiIxLDjCoGvCoHZ1ZXMifSwibWVudSI6eyJtZW51UmVuZGVyZXIiOnsiaXRlbXMiOlt7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUifV19LCJpY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwic2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ0VRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ0VRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJELWF2WTNkRzJaayIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQ0VRX3BnRUdBVWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiRC1hdlkzZEcyWmsiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJELWF2WTNkRzJaayJdfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0NFUV9wZ0VHQVVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7Im1lbnVTZXJ2aWNlSXRlbVJlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IlBhcnRhZ2VyIn1dfSwiaWNvbiI6eyJpY29uVHlwZSI6IlNIQVJFIn0sInNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0IwUWxEVVlDeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9zaGFyZS9nZXRfc2hhcmVfcGFuZWwifX0sInNoYXJlRW50aXR5U2VydmljZUVuZHBvaW50Ijp7InNlcmlhbGl6ZWRTaGFyZUVudGl0eSI6IkNndEVMV0YyV1ROa1J6SmFhdyUzRCUzRCIsImNvbW1hbmRzIjpbeyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0IwUWxEVVlDeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsIm9wZW5Qb3B1cEFjdGlvbiI6eyJwb3B1cCI6eyJ1bmlmaWVkU2hhcmVQYW5lbFJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0NBUWptSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRJQUxPRyIsImJlUmV1c2VkIjp0cnVlfX1dfX0sInRyYWNraW5nUGFyYW1zIjoiQ0IwUWxEVVlDeUlUQ0lqYzFfYW50UDhDRmR4Q1R3UWR6LWNDbVE9PSIsImhhc1NlcGFyYXRvciI6dHJ1ZX19XSwidHJhY2tpbmdQYXJhbXMiOiJDQjBRbERVWUN5SVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1lbnUgZCdhY3Rpb25zIn19fX0sInRodW1ibmFpbE92ZXJsYXlzIjpbeyJ0aHVtYm5haWxPdmVybGF5VGltZVN0YXR1c1JlbmRlcmVyIjp7InRleHQiOnsiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IjTCoGhldXJlcywgNDAgbWludXRlcyBldCAzN8Kgc2Vjb25kZXMifX0sInNpbXBsZVRleHQiOiI0OjQwOjM3In0sInN0eWxlIjoiREVGQVVMVCJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJpc1RvZ2dsZWQiOmZhbHNlLCJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiV0FUQ0hfTEFURVIifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJDSEVDSyJ9LCJ1bnRvZ2dsZWRUb29sdGlwIjoiw4AgcmVnYXJkZXIgcGx1cyB0YXJkIiwidG9nZ2xlZFRvb2x0aXAiOiJBam91dMOpZSIsInVudG9nZ2xlZFNlcnZpY2VFbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0I4US1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsic2VuZFBvc3QiOnRydWUsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UvZWRpdF9wbGF5bGlzdCJ9fSwicGxheWxpc3RFZGl0RW5kcG9pbnQiOnsicGxheWxpc3RJZCI6IldMIiwiYWN0aW9ucyI6W3siYWRkZWRWaWRlb0lkIjoiRC1hdlkzZEcyWmsiLCJhY3Rpb24iOiJBQ1RJT05fQUREX1ZJREVPIn1dfX0sInRvZ2dsZWRTZXJ2aWNlRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNCOFEtZWNER0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlL2VkaXRfcGxheWxpc3QifX0sInBsYXlsaXN0RWRpdEVuZHBvaW50Ijp7InBsYXlsaXN0SWQiOiJXTCIsImFjdGlvbnMiOlt7ImFjdGlvbiI6IkFDVElPTl9SRU1PVkVfVklERU9fQllfVklERU9fSUQiLCJyZW1vdmVkVmlkZW9JZCI6IkQtYXZZM2RHMlprIn1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiLDgCByZWdhcmRlciBwbHVzIHRhcmQifX0sInRvZ2dsZWRBY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQWpvdXTDqWUifX0sInRyYWNraW5nUGFyYW1zIjoiQ0I4US1lY0RHQUVpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRodW1ibmFpbE92ZXJsYXlUb2dnbGVCdXR0b25SZW5kZXJlciI6eyJ1bnRvZ2dsZWRJY29uIjp7Imljb25UeXBlIjoiQUREX1RPX1FVRVVFX1RBSUwifSwidG9nZ2xlZEljb24iOnsiaWNvblR5cGUiOiJQTEFZTElTVF9BRERfQ0hFQ0sifSwidW50b2dnbGVkVG9vbHRpcCI6IkFqb3V0ZXIgw6AgbGEgZmlsZSBkJ2F0dGVudGUiLCJ0b2dnbGVkVG9vbHRpcCI6IkFqb3V0w6llIiwidW50b2dnbGVkU2VydmljZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQjRReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQjRReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWRkVG9QbGF5bGlzdENvbW1hbmQiOnsib3Blbk1pbmlwbGF5ZXIiOnRydWUsInZpZGVvSWQiOiJELWF2WTNkRzJaayIsImxpc3RUeXBlIjoiUExBWUxJU1RfRURJVF9MSVNUX1RZUEVfUVVFVUUiLCJvbkNyZWF0ZUxpc3RDb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQjRReC13RUdBSWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL3BsYXlsaXN0L2NyZWF0ZSJ9fSwiY3JlYXRlUGxheWxpc3RTZXJ2aWNlRW5kcG9pbnQiOnsidmlkZW9JZHMiOlsiRC1hdlkzZEcyWmsiXSwicGFyYW1zIjoiQ0FRJTNEIn19LCJ2aWRlb0lkcyI6WyJELWF2WTNkRzJaayJdfX1dfX0sInVudG9nZ2xlZEFjY2Vzc2liaWxpdHkiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJBam91dGVyIMOgIGxhIGZpbGUgZCdhdHRlbnRlIn19LCJ0b2dnbGVkQWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkFqb3V0w6llIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNCNFF4LXdFR0FJaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0aHVtYm5haWxPdmVybGF5Tm93UGxheWluZ1JlbmRlcmVyIjp7InRleHQiOnsicnVucyI6W3sidGV4dCI6IkVuIGNvdXJzIGRlIGxlY3R1cmUifV19fX1dfX1dLCJ0cmFja2luZ1BhcmFtcyI6IkNCb1F4amtpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsInZpc2libGVJdGVtQ291bnQiOjQsIm5leHRCdXR0b24iOnsiYnV0dG9uUmVuZGVyZXIiOnsic3R5bGUiOiJTVFlMRV9ERUZBVUxUIiwic2l6ZSI6IlNJWkVfREVGQVVMVCIsImlzRGlzYWJsZWQiOmZhbHNlLCJpY29uIjp7Imljb25UeXBlIjoiQ0hFVlJPTl9SSUdIVCJ9LCJhY2Nlc3NpYmlsaXR5Ijp7ImxhYmVsIjoiU3VpdmFudCJ9LCJ0cmFja2luZ1BhcmFtcyI6IkNCd1E4RnNpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSwicHJldmlvdXNCdXR0b24iOnsiYnV0dG9uUmVuZGVyZXIiOnsic3R5bGUiOiJTVFlMRV9ERUZBVUxUIiwic2l6ZSI6IlNJWkVfREVGQVVMVCIsImlzRGlzYWJsZWQiOmZhbHNlLCJpY29uIjp7Imljb25UeXBlIjoiQ0hFVlJPTl9MRUZUIn0sImFjY2Vzc2liaWxpdHkiOnsibGFiZWwiOiJQcsOpY8OpZGVudGUifSwidHJhY2tpbmdQYXJhbXMiOiJDQnNROEZzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX19fSwidHJhY2tpbmdQYXJhbXMiOiJDQmtRM0J3WUFDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09In19XSwidHJhY2tpbmdQYXJhbXMiOiJDQmdRdXk4WUJDSVRDSWpjMV9hbnRQOENGZHhDVHdRZHotY0NtUT09In19XSwidHJhY2tpbmdQYXJhbXMiOiJDQmNRdWk4aUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJ0YXJnZXRJZCI6ImJyb3dzZS1mZWVkVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRZmVhdHVyZWQiLCJkaXNhYmxlUHVsbFRvUmVmcmVzaCI6dHJ1ZX19LCJ0cmFja2luZ1BhcmFtcyI6IkNCWVE4Sk1CR0FVaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0YWJSZW5kZXJlciI6eyJlbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0JVUThKTUJHQVlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL0BDb25mcmVha3MvdmlkZW9zIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwicGFyYW1zIjoiRWdaMmFXUmxiM1B5QmdRS0Fqb0EiLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BDb25mcmVha3MifX0sInRpdGxlIjoiVmlkw6lvcyIsInRyYWNraW5nUGFyYW1zIjoiQ0JVUThKTUJHQVlpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRhYlJlbmRlcmVyIjp7ImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQlFROEpNQkdBY2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQENvbmZyZWFrcy9zdHJlYW1zIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwicGFyYW1zIjoiRWdkemRISmxZVzF6OGdZRUNnSjZBQSUzRCUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQENvbmZyZWFrcyJ9fSwidGl0bGUiOiJFbiBkaXJlY3QiLCJ0cmFja2luZ1BhcmFtcyI6IkNCUVE4Sk1CR0FjaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0YWJSZW5kZXJlciI6eyJlbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0JNUThKTUJHQWdpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL0BDb25mcmVha3MvcGxheWxpc3RzIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwicGFyYW1zIjoiRWdsd2JHRjViR2x6ZEhQeUJnUUtBa0lBIiwiY2Fub25pY2FsQmFzZVVybCI6Ii9AQ29uZnJlYWtzIn19LCJ0aXRsZSI6IlBsYXlsaXN0cyIsInRyYWNraW5nUGFyYW1zIjoiQ0JNUThKTUJHQWdpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRhYlJlbmRlcmVyIjp7ImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQklROEpNQkdBa2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQENvbmZyZWFrcy9jb21tdW5pdHkiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJwYXJhbXMiOiJFZ2xqYjIxdGRXNXBkSG55QmdRS0Frb0EiLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BDb25mcmVha3MifX0sInRpdGxlIjoiQ29tbXVuYXV0w6kiLCJ0cmFja2luZ1BhcmFtcyI6IkNCSVE4Sk1CR0FraUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0seyJ0YWJSZW5kZXJlciI6eyJlbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0JFUThKTUJHQW9pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL0BDb25mcmVha3MvY2hhbm5lbHMiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJwYXJhbXMiOiJFZ2hqYUdGdWJtVnNjX0lHQkFvQ1VnQSUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQENvbmZyZWFrcyJ9fSwidGl0bGUiOiJDaGHDrm5lcyIsInRyYWNraW5nUGFyYW1zIjoiQ0JFUThKTUJHQW9pRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSx7InRhYlJlbmRlcmVyIjp7ImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQkFROEpNQkdBc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQENvbmZyZWFrcy9hYm91dCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9DSEFOTkVMIiwicm9vdFZlIjozNjExLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsInBhcmFtcyI6IkVnVmhZbTkxZFBJR0JBb0NFZ0ElM0QiLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BDb25mcmVha3MifX0sInRpdGxlIjoiw4AgcHJvcG9zIiwidHJhY2tpbmdQYXJhbXMiOiJDQkFROEpNQkdBc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9In19LHsiZXhwYW5kYWJsZVRhYlJlbmRlcmVyIjp7ImVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQUFRaEdjaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AQ29uZnJlYWtzL3NlYXJjaCIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9DSEFOTkVMIiwicm9vdFZlIjozNjExLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsInBhcmFtcyI6IkVnWnpaV0Z5WTJqeUJnUUtBbG9BIiwiY2Fub25pY2FsQmFzZVVybCI6Ii9AQ29uZnJlYWtzIn19LCJ0aXRsZSI6IlJlY2hlcmNoZSIsInNlbGVjdGVkIjpmYWxzZX19XX19LCJoZWFkZXIiOnsiYzRUYWJiZWRIZWFkZXJSZW5kZXJlciI6eyJjaGFubmVsSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJ0aXRsZSI6IkNvbmZyZWFrcyIsIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0EwUThEc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiIvQENvbmZyZWFrcyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9DSEFOTkVMIiwicm9vdFZlIjozNjExLCJhcGlVcmwiOiIveW91dHViZWkvdjEvYnJvd3NlIn19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQENvbmZyZWFrcyJ9fSwiYXZhdGFyIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS95dGMvQUdJS2dxTm5BZlE0a1I4aVo5YXVvMVI3Z2l0bWVIYjdhNWhiOEZSaG45YWpyZz1zNDgtYy1rLWMweDAwZmZmZmZmLW5vLXJqIiwid2lkdGgiOjQ4LCJoZWlnaHQiOjQ4fSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS95dGMvQUdJS2dxTm5BZlE0a1I4aVo5YXVvMVI3Z2l0bWVIYjdhNWhiOEZSaG45YWpyZz1zODgtYy1rLWMweDAwZmZmZmZmLW5vLXJqIiwid2lkdGgiOjg4LCJoZWlnaHQiOjg4fSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS95dGMvQUdJS2dxTm5BZlE0a1I4aVo5YXVvMVI3Z2l0bWVIYjdhNWhiOEZSaG45YWpyZz1zMTc2LWMtay1jMHgwMGZmZmZmZi1uby1yaiIsIndpZHRoIjoxNzYsImhlaWdodCI6MTc2fV19LCJiYW5uZXIiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2tONHRSVGlVTVhiQU5IS1BHbnpiLUNLamJLem9Zd0haV3d3bEx1bEd2UC1sX1FWTDNkS0JZYWFpN2xnb2hKYzItOEdwZG91UT13MTA2MC1mY3JvcDY0PTEsMDAwMDVhNTdmZmZmYTVhOC1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjEwNjAsImhlaWdodCI6MTc1fSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9rTjR0UlRpVU1YYkFOSEtQR256Yi1DS2piS3pvWXdIWld3d2xMdWxHdlAtbF9RVkwzZEtCWWFhaTdsZ29oSmMyLThHcGRvdVE9dzExMzgtZmNyb3A2ND0xLDAwMDA1YTU3ZmZmZmE1YTgtay1jMHhmZmZmZmZmZi1uby1uZC1yaiIsIndpZHRoIjoxMTM4LCJoZWlnaHQiOjE4OH0seyJ1cmwiOiJodHRwczovL3l0My5nb29nbGV1c2VyY29udGVudC5jb20va040dFJUaVVNWGJBTkhLUEduemItQ0tqYkt6b1l3SFpXd3dsTHVsR3ZQLWxfUVZMM2RLQllhYWk3bGdvaEpjMi04R3Bkb3VRPXcxNzA3LWZjcm9wNjQ9MSwwMDAwNWE1N2ZmZmZhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MTcwNywiaGVpZ2h0IjoyODN9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2tONHRSVGlVTVhiQU5IS1BHbnpiLUNLamJLem9Zd0haV3d3bEx1bEd2UC1sX1FWTDNkS0JZYWFpN2xnb2hKYzItOEdwZG91UT13MjEyMC1mY3JvcDY0PTEsMDAwMDVhNTdmZmZmYTVhOC1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjIxMjAsImhlaWdodCI6MzUxfSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9rTjR0UlRpVU1YYkFOSEtQR256Yi1DS2piS3pvWXdIWld3d2xMdWxHdlAtbF9RVkwzZEtCWWFhaTdsZ29oSmMyLThHcGRvdVE9dzIyNzYtZmNyb3A2ND0xLDAwMDA1YTU3ZmZmZmE1YTgtay1jMHhmZmZmZmZmZi1uby1uZC1yaiIsIndpZHRoIjoyMjc2LCJoZWlnaHQiOjM3N30seyJ1cmwiOiJodHRwczovL3l0My5nb29nbGV1c2VyY29udGVudC5jb20va040dFJUaVVNWGJBTkhLUEduemItQ0tqYkt6b1l3SFpXd3dsTHVsR3ZQLWxfUVZMM2RLQllhYWk3bGdvaEpjMi04R3Bkb3VRPXcyNTYwLWZjcm9wNjQ9MSwwMDAwNWE1N2ZmZmZhNWE4LWstYzB4ZmZmZmZmZmYtbm8tbmQtcmoiLCJ3aWR0aCI6MjU2MCwiaGVpZ2h0Ijo0MjR9XX0sImhlYWRlckxpbmtzIjp7ImNoYW5uZWxIZWFkZXJMaW5rc1JlbmRlcmVyIjp7InByaW1hcnlMaW5rcyI6W3sibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQTBROERzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3JlZGlyZWN0P2V2ZW50PWNoYW5uZWxfYmFubmVyXHUwMDI2cmVkaXJfdG9rZW49UVVGRkxVaHFibEZ2WW5seVFuQmZMVjkzTWpsQ2VTMWZkVkpyY1dSaVNXaGZRWHhCUTNKdGMwdHJSbTVNV0hOeGNtMXZPR1U0WlU1VFNHOW1RMk56TWxOa2JrdzNXbEZzZWtKQ1NVaE1UVkY1ZVY5b1ZqTXpVekJDYzJKRVMwVllVSGhzVUZnMGJTMTNjWEp3UkRkSVQzUXhkRUo1WjJ4cmNWUXRhMVZ0YlZkVGFtTm9Ta0ZpVWxoRWQweGpVR3BNY1ZaSWQxRm1iRGd6UlFcdTAwMjZxPWh0dHAlM0ElMkYlMkZjb25mcmVha3MuY29tIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX1VOS05PV04iLCJyb290VmUiOjgzNzY5fX0sInVybEVuZHBvaW50Ijp7InVybCI6Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3JlZGlyZWN0P2V2ZW50PWNoYW5uZWxfYmFubmVyXHUwMDI2cmVkaXJfdG9rZW49UVVGRkxVaHFibEZ2WW5seVFuQmZMVjkzTWpsQ2VTMWZkVkpyY1dSaVNXaGZRWHhCUTNKdGMwdHJSbTVNV0hOeGNtMXZPR1U0WlU1VFNHOW1RMk56TWxOa2JrdzNXbEZzZWtKQ1NVaE1UVkY1ZVY5b1ZqTXpVekJDYzJKRVMwVllVSGhzVUZnMGJTMTNjWEp3UkRkSVQzUXhkRUo1WjJ4cmNWUXRhMVZ0YlZkVGFtTm9Ta0ZpVWxoRWQweGpVR3BNY1ZaSWQxRm1iRGd6UlFcdTAwMjZxPWh0dHAlM0ElMkYlMkZjb25mcmVha3MuY29tIiwidGFyZ2V0IjoiVEFSR0VUX05FV19XSU5ET1ciLCJub2ZvbGxvdyI6dHJ1ZX19LCJpY29uIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vZW5jcnlwdGVkLXRibjIuZ3N0YXRpYy5jb20vZmF2aWNvbi10Ym4/cT10Ym46QU5kOUdjUUF1NzM3N2lmRVZoQlBKNmEtWU9SRGNHN0QzYTJ6WnFMZEtmaEJrc21vZFpVT1ctVTk1NEJXZGF1S0c1U3llMlJ1TkN2NVFZMnhQTXRzY3F0X3hWOUJXMHZQWDR0aVZVdl9kYWRDRFNSWmtwNCJ9XX0sInRpdGxlIjp7InNpbXBsZVRleHQiOiJjb25mcmVha3MuY29tIn19XSwic2Vjb25kYXJ5TGlua3MiOlt7Im5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0EwUThEc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiJodHRwczovL3d3dy55b3V0dWJlLmNvbS9yZWRpcmVjdD9ldmVudD1jaGFubmVsX2Jhbm5lclx1MDAyNnJlZGlyX3Rva2VuPVFVRkZMVWhxYldVd1JrMVdZM1pUZDB4dGNrMXNjVUZ6ZEZZMGFrNTVRbVJuZDN4QlEzSnRjMHR1VGtjNE5XeGpkMmgxV21aQ1ozWmpjRkZqWWpWRVZpMVlXa1JGU25JMFVUQkRha0V5UnpCVlJsSlNZbmc1ZVZkS2FHSTJlRXcyWkdKa1gzWndhWFZSTUVWWGVtNUtXa3RrWVhGU1FXNVRRa0pqV25sVWRWbzNORXBvTjNoSFkwRm1iR0ZVYW1jNFRTMUhjSEJDVFVsdGR3XHUwMDI2cT1odHRwJTNBJTJGJTJGdHdpdHRlci5jb20lMkZjb25mcmVha3MiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfVU5LTk9XTiIsInJvb3RWZSI6ODM3Njl9fSwidXJsRW5kcG9pbnQiOnsidXJsIjoiaHR0cHM6Ly93d3cueW91dHViZS5jb20vcmVkaXJlY3Q/ZXZlbnQ9Y2hhbm5lbF9iYW5uZXJcdTAwMjZyZWRpcl90b2tlbj1RVUZGTFVocWJXVXdSazFXWTNaVGQweHRjazFzY1VGemRGWTBhazU1UW1SbmQzeEJRM0p0YzB0dVRrYzROV3hqZDJoMVdtWkNaM1pqY0ZGallqVkVWaTFZV2tSRlNuSTBVVEJEYWtFeVJ6QlZSbEpTWW5nNWVWZEthR0kyZUV3MlpHSmtYM1p3YVhWUk1FVlhlbTVLV2t0a1lYRlNRVzVUUWtKaldubFVkVm8zTkVwb04zaEhZMEZtYkdGVWFtYzRUUzFIY0hCQ1RVbHRkd1x1MDAyNnE9aHR0cCUzQSUyRiUyRnR3aXR0ZXIuY29tJTJGY29uZnJlYWtzIiwidGFyZ2V0IjoiVEFSR0VUX05FV19XSU5ET1ciLCJub2ZvbGxvdyI6dHJ1ZX19LCJpY29uIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8vZW5jcnlwdGVkLXRibjEuZ3N0YXRpYy5jb20vZmF2aWNvbi10Ym4/cT10Ym46QU5kOUdjU2pBZkZFZXV3eDBJY0J6eU5aMVFjeFhnUVF1YUhNT3h3MllYcnBNOGFLQnQxLWE0MkNadXNlLXZrYTI1NENIRkJLOHRlS3BEdW9qVzZidmF3dGFRX3lGMUJGSlc1YUd2SnFMbFp4bGh5bCJ9XX0sInRpdGxlIjp7InNpbXBsZVRleHQiOiJUd2l0dGVyIn19LHsibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQTBROERzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3JlZGlyZWN0P2V2ZW50PWNoYW5uZWxfYmFubmVyXHUwMDI2cmVkaXJfdG9rZW49UVVGRkxVaHFiVE53WmxFMlJTMHlNVTlzTTBwcWJYa3RUMWR3WWsxdE5XTklkM3hCUTNKdGMwdHRVSGhNZFVselZEVTNPSGQxVG1wVmNXRnJYM1V0VDFKV1NrNVVia3BUUVRkNk4wcFBjV05zTTBab2FVRnRVeTB0UVRoQlFuTkZXWGd4YmxaR1NEUkZTVk5WTFdGdlZVcFFRa0ZJZDFGb00xSm9SR3c1YjJGNGREbHJTRE5QWm5ZMWRWZG9WbVZzVm1Vd2VUTXRXWGR1ZHdcdTAwMjZxPWh0dHAlM0ElMkYlMkZmYWNlYm9vay5jb20lMkZjb25mcmVha3MiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfVU5LTk9XTiIsInJvb3RWZSI6ODM3Njl9fSwidXJsRW5kcG9pbnQiOnsidXJsIjoiaHR0cHM6Ly93d3cueW91dHViZS5jb20vcmVkaXJlY3Q/ZXZlbnQ9Y2hhbm5lbF9iYW5uZXJcdTAwMjZyZWRpcl90b2tlbj1RVUZGTFVocWJUTndabEUyUlMweU1VOXNNMHBxYlhrdFQxZHdZazF0TldOSWQzeEJRM0p0YzB0dFVIaE1kVWx6VkRVM09IZDFUbXBWY1dGclgzVXRUMUpXU2s1VWJrcFRRVGQ2TjBwUGNXTnNNMFpvYVVGdFV5MHRRVGhCUW5ORldYZ3hibFpHU0RSRlNWTlZMV0Z2VlVwUVFrRklkMUZvTTFKb1JHdzViMkY0ZERsclNETlBablkxZFZkb1ZtVnNWbVV3ZVRNdFdYZHVkd1x1MDAyNnE9aHR0cCUzQSUyRiUyRmZhY2Vib29rLmNvbSUyRmNvbmZyZWFrcyIsInRhcmdldCI6IlRBUkdFVF9ORVdfV0lORE9XIiwibm9mb2xsb3ciOnRydWV9fSwiaWNvbiI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL2VuY3J5cHRlZC10Ym4yLmdzdGF0aWMuY29tL2Zhdmljb24tdGJuP3E9dGJuOkFOZDlHY1E0VHJOU3Q5SXZDM2FCSnpuWWFLc2phT2MtT0RyYm53eWNSemI4SnhONkt4dkVWb2hrd3h4ZFptdE9CVjF3VGhlcFpYT1NjRWI3TExTQmtkRTkzSmlYakpvQXd4RVpwTVdXWG4zcHNDdW9MdyJ9XX0sInRpdGxlIjp7InNpbXBsZVRleHQiOiJGYWNlYm9vayJ9fV19fSwic3Vic2NyaWJlQnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfREVTVFJVQ1RJVkUiLCJzaXplIjoiU0laRV9ERUZBVUxUIiwiaXNEaXNhYmxlZCI6ZmFsc2UsInRleHQiOnsicnVucyI6W3sidGV4dCI6IlMnYWJvbm5lciJ9XX0sIm5hdmlnYXRpb25FbmRwb2ludCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0E0UThGc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJpZ25vcmVOYXZpZ2F0aW9uIjp0cnVlfX0sIm1vZGFsRW5kcG9pbnQiOnsibW9kYWwiOnsibW9kYWxXaXRoVGl0bGVBbmRCdXR0b25SZW5kZXJlciI6eyJ0aXRsZSI6eyJzaW1wbGVUZXh0IjoiVm91bGV6LXZvdXMgdm91cyBhYm9ubmVyIMOgIGNldHRlIGNoYcOubmXCoD8ifSwiY29udGVudCI6eyJzaW1wbGVUZXh0IjoiQ29ubmVjdGV6LXZvdXMgcG91ciB2b3VzIGFib25uZXIgw6AgY2V0dGUgY2hhw65uZS4ifSwiYnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfQkxVRV9URVhUIiwic2l6ZSI6IlNJWkVfREVGQVVMVCIsImlzRGlzYWJsZWQiOmZhbHNlLCJ0ZXh0Ijp7InNpbXBsZVRleHQiOiJTZSBjb25uZWN0ZXIifSwibmF2aWdhdGlvbkVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQThRX1lZRUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1pNZ2x6ZFdKelkzSnBZbVU9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJ1cmwiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vU2VydmljZUxvZ2luP3NlcnZpY2U9eW91dHViZVx1MDAyNnVpbGVsPTNcdTAwMjZwYXNzaXZlPXRydWVcdTAwMjZjb250aW51ZT1odHRwcyUzQSUyRiUyRnd3dy55b3V0dWJlLmNvbSUyRnNpZ25pbiUzRmFjdGlvbl9oYW5kbGVfc2lnbmluJTNEdHJ1ZSUyNmFwcCUzRGRlc2t0b3AlMjZobCUzRGZyJTI2bmV4dCUzRCUyNTJGJTI1NDBDb25mcmVha3MlMjZjb250aW51ZV9hY3Rpb24lM0RRVUZGTFVocWJqTldjeTAwZW05aVEwODFWMHQzUzA4d2RWTXlOVmhGY2xkaWQzeEJRM0p0YzB0c1NVSlhaVXhXYmxjeVJXNVNkM0Z5Vm1oWFF6ZHpZVWt5UWt3NFMzVTBWbk5sUTBSaVJVVlVjRWhyUm1WWWQySjJSRkpvYVVkU2NHSlhZV0ppUlhKdFJ6WkNNekJMTFZaWlJ6bGpWalZhUXpKUFVXOXBjV05YTUhsalpFcEdWakJxZUZoeGNucGpXSGhaWTNkU1UwTmhVRlpMYkVreE9VeHZWMGhSWDNod1IzaDBWa3RJUVV0TExXTTNWWGN3YkRScmVDMUNZbVpKYldoUVJtTnJWbk5zVlc1bk5GSldWVXBvTVdwWGQyWTRYM0ZWT0hGZmNWQm9RVzFtZGxkMVZuWnZkekJQZW5rXHUwMDI2aGw9ZnJcdTAwMjZlYz02NjQyOSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9VTktOT1dOIiwicm9vdFZlIjo4Mzc2OX19LCJzaWduSW5FbmRwb2ludCI6eyJuZXh0RW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBOFFfWVlFSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL0BDb25mcmVha3MiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfQ0hBTk5FTCIsInJvb3RWZSI6MzYxMSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2Jyb3dzZSJ9fSwiYnJvd3NlRW5kcG9pbnQiOnsiYnJvd3NlSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJwYXJhbXMiOiJFZ0ElM0QiLCJjYW5vbmljYWxCYXNlVXJsIjoiL0BDb25mcmVha3MifX0sImNvbnRpbnVlQWN0aW9uIjoiUVVGRkxVaHFiak5XY3kwMGVtOWlRMDgxVjB0M1MwOHdkVk15TlZoRmNsZGlkM3hCUTNKdGMwdHNTVUpYWlV4V2JsY3lSVzVTZDNGeVZtaFhRemR6WVVreVFrdzRTM1UwVm5ObFEwUmlSVVZVY0VoclJtVllkMkoyUkZKb2FVZFNjR0pYWVdKaVJYSnRSelpDTXpCTExWWlpSemxqVmpWYVF6SlBVVzlwY1dOWE1IbGpaRXBHVmpCcWVGaHhjbnBqV0hoWlkzZFNVME5oVUZaTGJFa3hPVXh2VjBoUlgzaHdSM2gwVmt0SVFVdExMV00zVlhjd2JEUnJlQzFDWW1aSmJXaFFSbU5yVm5Oc1ZXNW5ORkpXVlVwb01XcFhkMlk0WDNGVk9IRmZjVkJvUVcxbWRsZDFWblp2ZHpCUGVuayIsImlkYW1UYWciOiI2NjQyOSJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDQThRX1lZRUloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oifX19fX19LCJ0cmFja2luZ1BhcmFtcyI6IkNBNFE4RnNpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSJ9fSwic3Vic2NyaWJlckNvdW50VGV4dCI6eyJhY2Nlc3NpYmlsaXR5Ijp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiNDEsNyBtaWxsZcKgYWJvbm7DqXMifX0sInNpbXBsZVRleHQiOiI0MSw3wqBrwqBhYm9ubsOpcyJ9LCJ0dkJhbm5lciI6eyJ0aHVtYm5haWxzIjpbeyJ1cmwiOiJodHRwczovL3l0My5nb29nbGV1c2VyY29udGVudC5jb20va040dFJUaVVNWGJBTkhLUEduemItQ0tqYkt6b1l3SFpXd3dsTHVsR3ZQLWxfUVZMM2RLQllhYWk3bGdvaEpjMi04R3Bkb3VRPXczMjAtZmNyb3A2ND0xLDAwMDAwMDAwZmZmZmZmZmYtay1jMHhmZmZmZmZmZi1uby1uZC1yaiIsIndpZHRoIjozMjAsImhlaWdodCI6MTgwfSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9rTjR0UlRpVU1YYkFOSEtQR256Yi1DS2piS3pvWXdIWld3d2xMdWxHdlAtbF9RVkwzZEtCWWFhaTdsZ29oSmMyLThHcGRvdVE9dzg1NC1mY3JvcDY0PTEsMDAwMDAwMDBmZmZmZmZmZi1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjg1NCwiaGVpZ2h0Ijo0ODB9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2tONHRSVGlVTVhiQU5IS1BHbnpiLUNLamJLem9Zd0haV3d3bEx1bEd2UC1sX1FWTDNkS0JZYWFpN2xnb2hKYzItOEdwZG91UT13MTI4MC1mY3JvcDY0PTEsMDAwMDAwMDBmZmZmZmZmZi1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjEyODAsImhlaWdodCI6NzIwfSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9rTjR0UlRpVU1YYkFOSEtQR256Yi1DS2piS3pvWXdIWld3d2xMdWxHdlAtbF9RVkwzZEtCWWFhaTdsZ29oSmMyLThHcGRvdVE9dzE5MjAtZmNyb3A2ND0xLDAwMDAwMDAwZmZmZmZmZmYtay1jMHhmZmZmZmZmZi1uby1uZC1yaiIsIndpZHRoIjoxOTIwLCJoZWlnaHQiOjEwODB9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2tONHRSVGlVTVhiQU5IS1BHbnpiLUNLamJLem9Zd0haV3d3bEx1bEd2UC1sX1FWTDNkS0JZYWFpN2xnb2hKYzItOEdwZG91UT13MjEyMC1mY3JvcDY0PTEsMDAwMDAwMDBmZmZmZmZmZi1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjIxMjAsImhlaWdodCI6MTE5Mn1dfSwibW9iaWxlQmFubmVyIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9rTjR0UlRpVU1YYkFOSEtQR256Yi1DS2piS3pvWXdIWld3d2xMdWxHdlAtbF9RVkwzZEtCWWFhaTdsZ29oSmMyLThHcGRvdVE9dzMyMC1mY3JvcDY0PTEsMzJiNzVhNTdjZDQ4YTVhOC1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjMyMCwiaGVpZ2h0Ijo4OH0seyJ1cmwiOiJodHRwczovL3l0My5nb29nbGV1c2VyY29udGVudC5jb20va040dFJUaVVNWGJBTkhLUEduemItQ0tqYkt6b1l3SFpXd3dsTHVsR3ZQLWxfUVZMM2RLQllhYWk3bGdvaEpjMi04R3Bkb3VRPXc2NDAtZmNyb3A2ND0xLDMyYjc1YTU3Y2Q0OGE1YTgtay1jMHhmZmZmZmZmZi1uby1uZC1yaiIsIndpZHRoIjo2NDAsImhlaWdodCI6MTc1fSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9rTjR0UlRpVU1YYkFOSEtQR256Yi1DS2piS3pvWXdIWld3d2xMdWxHdlAtbF9RVkwzZEtCWWFhaTdsZ29oSmMyLThHcGRvdVE9dzk2MC1mY3JvcDY0PTEsMzJiNzVhNTdjZDQ4YTVhOC1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjk2MCwiaGVpZ2h0IjoyNjN9LHsidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2tONHRSVGlVTVhiQU5IS1BHbnpiLUNLamJLem9Zd0haV3d3bEx1bEd2UC1sX1FWTDNkS0JZYWFpN2xnb2hKYzItOEdwZG91UT13MTI4MC1mY3JvcDY0PTEsMzJiNzVhNTdjZDQ4YTVhOC1rLWMweGZmZmZmZmZmLW5vLW5kLXJqIiwid2lkdGgiOjEyODAsImhlaWdodCI6MzUxfSx7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9rTjR0UlRpVU1YYkFOSEtQR256Yi1DS2piS3pvWXdIWld3d2xMdWxHdlAtbF9RVkwzZEtCWWFhaTdsZ29oSmMyLThHcGRvdVE9dzE0NDAtZmNyb3A2ND0xLDMyYjc1YTU3Y2Q0OGE1YTgtay1jMHhmZmZmZmZmZi1uby1uZC1yaiIsIndpZHRoIjoxNDQwLCJoZWlnaHQiOjM5NX1dfSwidHJhY2tpbmdQYXJhbXMiOiJDQTBROERzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjaGFubmVsSGFuZGxlVGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQENvbmZyZWFrcyJ9XX0sInN0eWxlIjoiQzRfVEFCQkVEX0hFQURFUl9SRU5ERVJFUl9TVFlMRV9NT0RFUk4iLCJ2aWRlb3NDb3VudFRleHQiOnsicnVucyI6W3sidGV4dCI6IjUsOMKgayJ9LHsidGV4dCI6IsKgdmlkw6lvcyJ9XX0sInRhZ2xpbmUiOnsiY2hhbm5lbFRhZ2xpbmVSZW5kZXJlciI6eyJjb250ZW50IjoiVmlkZW9zIHJlY29yZGVkIGFuZC9vciBob3N0ZWQgYnkgQ29uZnJlYWtzLCBnZW5lcmFsbHkgaW4gdGhlIHRlY2hub2xvZ3kgc3BhY2UuIiwibWF4TGluZXMiOjEsIm1vcmVMYWJlbCI6Ii4uLiBhZmZpY2hlciBwbHVzIiwibW9yZUVuZHBvaW50Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQTBROERzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AQ29uZnJlYWtzL2Fib3V0Iiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwicGFyYW1zIjoiRWdWaFltOTFkUElHQkFvQ0VnQSUzRCIsImNhbm9uaWNhbEJhc2VVcmwiOiIvQENvbmZyZWFrcyJ9fSwibW9yZUljb24iOnsiaWNvblR5cGUiOiJDSEVWUk9OX1JJR0hUIn19fX19LCJtZXRhZGF0YSI6eyJjaGFubmVsTWV0YWRhdGFSZW5kZXJlciI6eyJ0aXRsZSI6IkNvbmZyZWFrcyIsImRlc2NyaXB0aW9uIjoiVmlkZW9zIHJlY29yZGVkIGFuZC9vciBob3N0ZWQgYnkgQ29uZnJlYWtzLCBnZW5lcmFsbHkgaW4gdGhlIHRlY2hub2xvZ3kgc3BhY2UuIiwicnNzVXJsIjoiaHR0cHM6Ly93d3cueW91dHViZS5jb20vZmVlZHMvdmlkZW9zLnhtbD9jaGFubmVsX2lkPVVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsImV4dGVybmFsSWQiOiJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJrZXl3b3JkcyI6InJ1YnkgamF2YXNjcmlwdCBjbG9qdXJlIHRlY2hub2xvZ3kgXCJwcm9ncmFtbWluZyBsYW5ndWFnZVwiIGVsaXhpciBlbWJlciBydXN0IHJhaWxzIFwiY29tcHV0ZXIgc2NpZW5jZVwiIHByb2dyYW1taW5nIFwidGVjaCBjb25mZXJlbmNlXCIgcHl0aG9uIGRldm9wcyBkZXZvcHNkYXlzIHJlYWN0IHBvc3RncmVzIEdOVVJhZGlvIiwib3duZXJVcmxzIjpbImh0dHA6Ly93d3cueW91dHViZS5jb20vQENvbmZyZWFrcyJdLCJhdmF0YXIiOnsidGh1bWJuYWlscyI6W3sidXJsIjoiaHR0cHM6Ly95dDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL3l0Yy9BR0lLZ3FObkFmUTRrUjhpWjlhdW8xUjdnaXRtZUhiN2E1aGI4RlJobjlhanJnPXM5MDAtYy1rLWMweDAwZmZmZmZmLW5vLXJqIiwid2lkdGgiOjkwMCwiaGVpZ2h0Ijo5MDB9XX0sImNoYW5uZWxVcmwiOiJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsImlzRmFtaWx5U2FmZSI6dHJ1ZSwiZmFjZWJvb2tQcm9maWxlSWQiOiJjb25mcmVha3MiLCJhdmFpbGFibGVDb3VudHJ5Q29kZXMiOlsiTUgiLCJVTSIsIlJVIiwiR1EiLCJUWiIsIkdSIiwiTkUiLCJLUiIsIkRLIiwiR1MiLCJFQyIsIlRWIiwiVFQiLCJJTiIsIlFBIiwiU1MiLCJLUCIsIlNLIiwiU1YiLCJDUiIsIkdNIiwiTUwiLCJNRiIsIkFPIiwiSU0iLCJJUyIsIlZBIiwiWlciLCJBRCIsIlRSIiwiTVAiLCJGSiIsIkFHIiwiTEIiLCJUTSIsIkFFIiwiU0kiLCJNVSIsIkNIIiwiUFQiLCJDSSIsIlJPIiwiQU0iLCJHRiIsIktNIiwiQlIiLCJWVSIsIkJXIiwiUFciLCJKRSIsIkJNIiwiWVQiLCJNRSIsIk5MIiwiTkEiLCJFUyIsIktFIiwiR1QiLCJMViIsIlNaIiwiRUgiLCJBUyIsIkNBIiwiQlYiLCJBVSIsIk1WIiwiTUciLCJWRyIsIk1SIiwiQ1YiLCJFVCIsIlNCIiwiREoiLCJVQSIsIkNOIiwiUFIiLCJDRCIsIkhOIiwiTUEiLCJDVyIsIk1LIiwiVEQiLCJVWSIsIkJTIiwiS1ciLCJDSyIsIk1NIiwiS04iLCJDTCIsIkJJIiwiUEwiLCJNWiIsIlVTIiwiUlMiLCJTTyIsIkRFIiwiRE0iLCJORiIsIlNUIiwiTkkiLCJDTSIsIkFYIiwiUEEiLCJZRSIsIkpNIiwiV1MiLCJBUiIsIkJHIiwiQlQiLCJHRyIsIlRKIiwiUFMiLCJHSSIsIkFGIiwiQkIiLCJNUSIsIkdCIiwiTUMiLCJNUyIsIkJBIiwiQ1oiLCJITSIsIkdZIiwiQ0YiLCJTQyIsIkVFIiwiUEYiLCJJUSIsIk5QIiwiRlIiLCJUTyIsIklPIiwiQ1kiLCJOTyIsIlBLIiwiTFIiLCJUTiIsIlJFIiwiU1giLCJFUiIsIk5aIiwiU0oiLCJNTyIsIktHIiwiQVEiLCJCRiIsIktZIiwiTEkiLCJTTSIsIkJaIiwiUE0iLCJLWiIsIk5DIiwiRk8iLCJBVCIsIkRPIiwiR0wiLCJGTSIsIlBOIiwiSk8iLCJaQSIsIlNIIiwiQkgiLCJTTiIsIkxUIiwiSUQiLCJHSCIsIklFIiwiR1UiLCJTRSIsIkxZIiwiVFciLCJQRyIsIk1UIiwiUEUiLCJTQSIsIkZJIiwiTFUiLCJORyIsIlZJIiwiR1AiLCJUTCIsIkJFIiwiTlIiLCJTWSIsIktJIiwiVUciLCJURiIsIk1EIiwiSEsiLCJTUiIsIlNHIiwiR0EiLCJNVyIsIkNPIiwiUEgiLCJSVyIsIlRDIiwiR0UiLCJIVCIsIk1YIiwiV0YiLCJWTiIsIlRHIiwiSFIiLCJCSiIsIkxTIiwiVEgiLCJFRyIsIlNEIiwiSUwiLCJBTCIsIkFXIiwiU0wiLCJCRCIsIklSIiwiRFoiLCJDRyIsIkxBIiwiQk4iLCJJVCIsIkNVIiwiSlAiLCJDWCIsIk1ZIiwiR0QiLCJPTSIsIlRLIiwiR1ciLCJVWiIsIkZLIiwiVkUiLCJOVSIsIkJZIiwiQUkiLCJIVSIsIkFaIiwiQkwiLCJDQyIsIkxLIiwiR04iLCJWQyIsIk1OIiwiUFkiLCJCTyIsIkJRIiwiS0giLCJaTSIsIkxDIl0sImFuZHJvaWREZWVwTGluayI6ImFuZHJvaWQtYXBwOi8vY29tLmdvb2dsZS5hbmRyb2lkLnlvdXR1YmUvaHR0cC93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJhbmRyb2lkQXBwaW5kZXhpbmdMaW5rIjoiYW5kcm9pZC1hcHA6Ly9jb20uZ29vZ2xlLmFuZHJvaWQueW91dHViZS9odHRwL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsImlvc0FwcGluZGV4aW5nTGluayI6Imlvcy1hcHA6Ly81NDQwMDc2NjQvdm5kLnlvdXR1YmUvd3d3LnlvdXR1YmUuY29tL2NoYW5uZWwvVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwidmFuaXR5Q2hhbm5lbFVybCI6Imh0dHA6Ly93d3cueW91dHViZS5jb20vQENvbmZyZWFrcyJ9fSwidHJhY2tpbmdQYXJhbXMiOiJDQUFRaEdjaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJ0b3BiYXIiOnsiZGVza3RvcFRvcGJhclJlbmRlcmVyIjp7ImxvZ28iOnsidG9wYmFyTG9nb1JlbmRlcmVyIjp7Imljb25JbWFnZSI6eyJpY29uVHlwZSI6IllPVVRVQkVfTE9HTyJ9LCJ0b29sdGlwVGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWNjdWVpbCBZb3VUdWJlIn1dfSwiZW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBd1FzVjRpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiLyIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9CUk9XU0UiLCJyb290VmUiOjM4NTQsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifX0sImJyb3dzZUVuZHBvaW50Ijp7ImJyb3dzZUlkIjoiRkV3aGF0X3RvX3dhdGNoIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNBd1FzVjRpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsIm92ZXJyaWRlRW50aXR5S2V5IjoiRWdaMGIzQmlZWElnOVFFb0FRJTNEJTNEIn19LCJzZWFyY2hib3giOnsiZnVzaW9uU2VhcmNoYm94UmVuZGVyZXIiOnsiaWNvbiI6eyJpY29uVHlwZSI6IlNFQVJDSCJ9LCJwbGFjZWhvbGRlclRleHQiOnsicnVucyI6W3sidGV4dCI6IlJlY2hlcmNoZXIifV19LCJjb25maWciOnsid2ViU2VhcmNoYm94Q29uZmlnIjp7InJlcXVlc3RMYW5ndWFnZSI6ImZyIiwicmVxdWVzdERvbWFpbiI6ImZyIiwiaGFzT25zY3JlZW5LZXlib2FyZCI6ZmFsc2UsImZvY3VzU2VhcmNoYm94Ijp0cnVlfX0sInRyYWNraW5nUGFyYW1zIjoiQ0FvUTdWQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwic2VhcmNoRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBb1E3VkFpRXdpSTNOZjJwN1RfQWhYY1FrOEVIY19uQXBrPSIsImNvbW1hbmRNZXRhZGF0YSI6eyJ3ZWJDb21tYW5kTWV0YWRhdGEiOnsidXJsIjoiL3Jlc3VsdHM/c2VhcmNoX3F1ZXJ5PSIsIndlYlBhZ2VUeXBlIjoiV0VCX1BBR0VfVFlQRV9TRUFSQ0giLCJyb290VmUiOjQ3MjR9fSwic2VhcmNoRW5kcG9pbnQiOnsicXVlcnkiOiIifX0sImNsZWFyQnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfREVGQVVMVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwiaWNvbiI6eyJpY29uVHlwZSI6IkNMT1NFIn0sInRyYWNraW5nUGFyYW1zIjoiQ0FzUThGc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWNjZXNzaWJpbGl0eURhdGEiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJFZmZhY2VyIGxhIHJlcXXDqnRlIGRlIHJlY2hlcmNoZSJ9fX19fX0sInRyYWNraW5nUGFyYW1zIjoiQ0FFUXE2d0JJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY291bnRyeUNvZGUiOiJGUiIsInRvcGJhckJ1dHRvbnMiOlt7InRvcGJhck1lbnVCdXR0b25SZW5kZXJlciI6eyJpY29uIjp7Imljb25UeXBlIjoiTU9SRV9WRVJUIn0sIm1lbnVSZXF1ZXN0Ijp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQWdRX3FzQkdBQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZSwiYXBpVXJsIjoiL3lvdXR1YmVpL3YxL2FjY291bnQvYWNjb3VudF9tZW51In19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiR0VUX0FDQ09VTlRfTUVOVSIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQWdRX3FzQkdBQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9Iiwib3BlblBvcHVwQWN0aW9uIjp7InBvcHVwIjp7Im11bHRpUGFnZU1lbnVSZW5kZXJlciI6eyJ0cmFja2luZ1BhcmFtcyI6IkNBa1FfNnNCSWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsInN0eWxlIjoiTVVMVElfUEFHRV9NRU5VX1NUWUxFX1RZUEVfU1lTVEVNIiwic2hvd0xvYWRpbmdTcGlubmVyIjp0cnVlfX0sInBvcHVwVHlwZSI6IkRST1BET1dOIiwiYmVSZXVzZWQiOnRydWV9fV19fSwidHJhY2tpbmdQYXJhbXMiOiJDQWdRX3FzQkdBQWlFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiYWNjZXNzaWJpbGl0eSI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IlBhcmFtw6h0cmVzIn19LCJ0b29sdGlwIjoiUGFyYW3DqHRyZXMiLCJzdHlsZSI6IlNUWUxFX0RFRkFVTFQifX0seyJidXR0b25SZW5kZXJlciI6eyJzdHlsZSI6IlNUWUxFX1NVR0dFU1RJVkUiLCJzaXplIjoiU0laRV9TTUFMTCIsInRleHQiOnsicnVucyI6W3sidGV4dCI6IlNlIGNvbm5lY3RlciJ9XX0sImljb24iOnsiaWNvblR5cGUiOiJBVkFUQVJfTE9HR0VEX09VVCJ9LCJuYXZpZ2F0aW9uRW5kcG9pbnQiOnsiY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBY1ExSUFFR0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9TZXJ2aWNlTG9naW4/c2VydmljZT15b3V0dWJlXHUwMDI2dWlsZWw9M1x1MDAyNnBhc3NpdmU9dHJ1ZVx1MDAyNmNvbnRpbnVlPWh0dHBzJTNBJTJGJTJGd3d3LnlvdXR1YmUuY29tJTJGc2lnbmluJTNGYWN0aW9uX2hhbmRsZV9zaWduaW4lM0R0cnVlJTI2YXBwJTNEZGVza3RvcCUyNmhsJTNEZnIlMjZuZXh0JTNEaHR0cHMlMjUzQSUyNTJGJTI1MkZ3d3cueW91dHViZS5jb20lMjUyRiUyNTQwY29uZnJlYWtzJTI1M0ZjYnJkJTI1M0QxJTI1MjZ1Y2JjYiUyNTNEMVx1MDAyNmhsPWZyXHUwMDI2ZWM9NjU2MjAiLCJ3ZWJQYWdlVHlwZSI6IldFQl9QQUdFX1RZUEVfVU5LTk9XTiIsInJvb3RWZSI6ODM3Njl9fSwic2lnbkluRW5kcG9pbnQiOnsiaWRhbVRhZyI6IjY1NjIwIn19LCJ0cmFja2luZ1BhcmFtcyI6IkNBY1ExSUFFR0FFaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJ0YXJnZXRJZCI6InRvcGJhci1zaWduaW4ifX1dLCJob3RrZXlEaWFsb2ciOnsiaG90a2V5RGlhbG9nUmVuZGVyZXIiOnsidGl0bGUiOnsicnVucyI6W3sidGV4dCI6IlJhY2NvdXJjaXMgY2xhdmllciJ9XX0sInNlY3Rpb25zIjpbeyJob3RrZXlEaWFsb2dTZWN0aW9uUmVuZGVyZXIiOnsidGl0bGUiOnsicnVucyI6W3sidGV4dCI6IkxlY3R1cmUifV19LCJvcHRpb25zIjpbeyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkxlY3R1cmUvUGF1c2UifV19LCJob3RrZXkiOiJrIn19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJSZXZlbmlyIGVuIGFycmnDqHJlIGRlIDEwwqBzZWNvbmRlcyJ9XX0sImhvdGtleSI6ImoifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkF2YW5jZXIgZGUgMTDCoHNlY29uZGVzIn1dfSwiaG90a2V5IjoibCJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiVmlkw6lvIHByw6ljw6lkZW50ZSJ9XX0sImhvdGtleSI6IlAgKE1BSsKgKyBwKSJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiVmlkw6lvIHN1aXZhbnRlIn1dfSwiaG90a2V5IjoiTiAoTUFKwqArIG4pIn19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJJbWFnZSBwcsOpY8OpZGVudGUgKGVuIHBhdXNlKSJ9XX0sImhvdGtleSI6IiwiLCJob3RrZXlBY2Nlc3NpYmlsaXR5TGFiZWwiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJWaXJndWxlIn19fX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkltYWdlIHN1aXZhbnRlIChlbiBwYXVzZSkifV19LCJob3RrZXkiOiIuIiwiaG90a2V5QWNjZXNzaWJpbGl0eUxhYmVsIjp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiUG9pbnQifX19fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiRGltaW51ZXIgbGEgdml0ZXNzZSBkZSBsZWN0dXJlIn1dfSwiaG90a2V5IjoiXHUwMDNjIChTSElGVCssKSIsImhvdGtleUFjY2Vzc2liaWxpdHlMYWJlbCI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6IkNhcmFjdMOocmUgaW5mw6lyaWV1ciBvdSBNYWogKyB2aXJndWxlIn19fX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkF1Z21lbnRlciBsYSB2aXRlc3NlIGRlIGxlY3R1cmUifV19LCJob3RrZXkiOiJcdTAwM2UgKFNISUZUKy4pIiwiaG90a2V5QWNjZXNzaWJpbGl0eUxhYmVsIjp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQ2FyYWN0w6hyZSBzdXDDqXJpZXVyIG91IE1hasKgKyBwb2ludCJ9fX19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJBdHRlaW5kcmUgdW4gbW9tZW50IHNww6ljaWZpcXVlIGRlIGxhIHZpZMOpbyAoNyBjb3JyZXNwb25kIMOgIDcwwqAlIGRlIGxhIGR1csOpZSkifV19LCJob3RrZXkiOiIwLi45In19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJBY2PDqWRlciBhdSBjaGFwaXRyZSBwcsOpY8OpZGVudCJ9XX0sImhvdGtleSI6IkNPTlRSw5RMRcKgKyDihpAifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkFjY8OpZGVyIGF1IGNoYXBpdHJlIHN1aXZhbnQifV19LCJob3RrZXkiOiJDT05UUsOUTEXCoCsg4oaSIn19XX19LHsiaG90a2V5RGlhbG9nU2VjdGlvblJlbmRlcmVyIjp7InRpdGxlIjp7InJ1bnMiOlt7InRleHQiOiJHw6luw6lyYWwifV19LCJvcHRpb25zIjpbeyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkFjdGl2ZXIvZMOpc2FjdGl2ZXIgbGUgbW9kZSBwbGVpbiDDqWNyYW4ifV19LCJob3RrZXkiOiJmIn19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJBY3RpdmVyL0TDqXNhY3RpdmVyIGxlIG1vZGUgY2luw6ltYSJ9XX0sImhvdGtleSI6InQifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkFjdGl2ZXIvRMOpc2FjdGl2ZXIgbGUgbGVjdGV1ciByw6lkdWl0In1dfSwiaG90a2V5IjoiaSJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiRmVybWVyIGxlIGxlY3RldXIgcsOpZHVpdCBvdSBsYSBib8OudGUgZGUgZGlhbG9ndWUgYWN0dWVsbGUifV19LCJob3RrZXkiOiLDiUNIQVAifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkFjdGl2ZXIvRMOpc2FjdGl2ZXIgbGUgc29uIn1dfSwiaG90a2V5IjoibSJ9fV19fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25SZW5kZXJlciI6eyJ0aXRsZSI6eyJydW5zIjpbeyJ0ZXh0IjoiU291cy10aXRyZXMifV19LCJvcHRpb25zIjpbeyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IlNpIGxhIHZpZMOpbyBlc3QgY29tcGF0aWJsZSBhdmVjIGxlcyBzb3VzLXRpdHJlcywgbGVzIGFjdGl2ZXIgb3UgbGVzIGTDqXNhY3RpdmVyIn1dfSwiaG90a2V5IjoiYyJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiQWx0ZXJuZXIgZW50cmUgbGVzIGRpZmbDqXJlbnRzIG5pdmVhdXggZCdvcGFjaXTDqSBkdSB0ZXh0ZSJ9XX0sImhvdGtleSI6Im8ifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkFsdGVybmVyIGVudHJlIGxlcyBkaWZmw6lyZW50cyBuaXZlYXV4IGQnb3BhY2l0w6kgZGUgbGEgZmVuw6p0cmUifV19LCJob3RrZXkiOiJ3In19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJBbHRlcm5lciBlbnRyZSBsZXMgdGFpbGxlcyBkZSBwb2xpY2UgKGF1Z21lbnRhdGlvbikifV19LCJob3RrZXkiOiIrIn19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJBbHRlcm5lciBlbnRyZSBsZXMgdGFpbGxlcyBkZSBwb2xpY2UgKGRpbWludXRpb24pIn1dfSwiaG90a2V5IjoiLSIsImhvdGtleUFjY2Vzc2liaWxpdHlMYWJlbCI6eyJhY2Nlc3NpYmlsaXR5RGF0YSI6eyJsYWJlbCI6Ik1vaW5zIn19fX1dfX0seyJob3RrZXlEaWFsb2dTZWN0aW9uUmVuZGVyZXIiOnsidGl0bGUiOnsicnVucyI6W3sidGV4dCI6IlZpZMOpb3Mgc3Bow6lyaXF1ZXMifV19LCJvcHRpb25zIjpbeyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkTDqXBsYWNlciB2ZXJzIGxlIGhhdXQifV19LCJob3RrZXkiOiJ3In19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJQYW5vcmFtaXF1ZSB2ZXJzIGxhIGdhdWNoZSJ9XX0sImhvdGtleSI6ImEifX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IlBhbm9yYW1pcXVlIHZlcnMgbGUgYmFzIn1dfSwiaG90a2V5IjoicyJ9fSx7ImhvdGtleURpYWxvZ1NlY3Rpb25PcHRpb25SZW5kZXJlciI6eyJsYWJlbCI6eyJydW5zIjpbeyJ0ZXh0IjoiUGFub3JhbWlxdWUgdmVycyBsYSBkcm9pdGUifV19LCJob3RrZXkiOiJkIn19LHsiaG90a2V5RGlhbG9nU2VjdGlvbk9wdGlvblJlbmRlcmVyIjp7ImxhYmVsIjp7InJ1bnMiOlt7InRleHQiOiJGYWlyZSB1biB6b29tIGF2YW50In1dfSwiaG90a2V5IjoiKyBzdXIgbGUgcGF2w6kgbnVtw6lyaXF1ZSBvdSBdIiwiaG90a2V5QWNjZXNzaWJpbGl0eUxhYmVsIjp7ImFjY2Vzc2liaWxpdHlEYXRhIjp7ImxhYmVsIjoiQ2FyYWN0w6hyZSBwbHVzIHN1ciBsZSBjbGF2aWVyIG51bcOpcmlxdWUgb3UgY3JvY2hldCBmZXJtYW50In19fX0seyJob3RrZXlEaWFsb2dTZWN0aW9uT3B0aW9uUmVuZGVyZXIiOnsibGFiZWwiOnsicnVucyI6W3sidGV4dCI6IkZhaXJlIHVuIHpvb20gYXJyacOocmUifV19LCJob3RrZXkiOiItIHN1ciBsZSBwYXbDqSBudW3DqXJpcXVlIG91IFsiLCJob3RrZXlBY2Nlc3NpYmlsaXR5TGFiZWwiOnsiYWNjZXNzaWJpbGl0eURhdGEiOnsibGFiZWwiOiJDYXJhY3TDqHJlIG1vaW5zIHN1ciBsZSBjbGF2aWVyIG51bcOpcmlxdWUgb3UgY3JvY2hldCBvdXZyYW50In19fX1dfX1dLCJkaXNtaXNzQnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfQkxVRV9URVhUIiwic2l6ZSI6IlNJWkVfREVGQVVMVCIsImlzRGlzYWJsZWQiOmZhbHNlLCJ0ZXh0Ijp7InJ1bnMiOlt7InRleHQiOiJJZ25vcmVyIn1dfSwidHJhY2tpbmdQYXJhbXMiOiJDQVlROEZzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0ifX0sInRyYWNraW5nUGFyYW1zIjoiQ0FVUXRlWURJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIn19LCJiYWNrQnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InRyYWNraW5nUGFyYW1zIjoiQ0FRUXZJWURJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0FRUXZJWURJaE1JaU56WDlxZTBfd0lWM0VKUEJCM1A1d0taIiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQVFRdklZREloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJzaWduYWxBY3Rpb24iOnsic2lnbmFsIjoiSElTVE9SWV9CQUNLIn19XX19fX0sImZvcndhcmRCdXR0b24iOnsiYnV0dG9uUmVuZGVyZXIiOnsidHJhY2tpbmdQYXJhbXMiOiJDQU1RdllZREloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kIjp7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQU1RdllZREloTUlpTnpYOXFlMF93SVYzRUpQQkIzUDV3S1oiLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InNlbmRQb3N0Ijp0cnVlfX0sInNpZ25hbFNlcnZpY2VFbmRwb2ludCI6eyJzaWduYWwiOiJDTElFTlRfU0lHTkFMIiwiYWN0aW9ucyI6W3siY2xpY2tUcmFja2luZ1BhcmFtcyI6IkNBTVF2WVlESWhNSWlOelg5cWUwX3dJVjNFSlBCQjNQNXdLWiIsInNpZ25hbEFjdGlvbiI6eyJzaWduYWwiOiJISVNUT1JZX0ZPUldBUkQifX1dfX19fSwiYTExeVNraXBOYXZpZ2F0aW9uQnV0dG9uIjp7ImJ1dHRvblJlbmRlcmVyIjp7InN0eWxlIjoiU1RZTEVfREVGQVVMVCIsInNpemUiOiJTSVpFX0RFRkFVTFQiLCJpc0Rpc2FibGVkIjpmYWxzZSwidGV4dCI6eyJydW5zIjpbeyJ0ZXh0IjoiSWdub3JlciBsZXMgbGllbnMgZGUgbmF2aWdhdGlvbiJ9XX0sInRyYWNraW5nUGFyYW1zIjoiQ0FJUThGc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZCI6eyJjbGlja1RyYWNraW5nUGFyYW1zIjoiQ0FJUThGc2lFd2lJM05mMnA3VF9BaFhjUWs4RUhjX25BcGs9IiwiY29tbWFuZE1ldGFkYXRhIjp7IndlYkNvbW1hbmRNZXRhZGF0YSI6eyJzZW5kUG9zdCI6dHJ1ZX19LCJzaWduYWxTZXJ2aWNlRW5kcG9pbnQiOnsic2lnbmFsIjoiQ0xJRU5UX1NJR05BTCIsImFjdGlvbnMiOlt7ImNsaWNrVHJhY2tpbmdQYXJhbXMiOiJDQUlROEZzaUV3aUkzTmYycDdUX0FoWGNRazhFSGNfbkFwaz0iLCJzaWduYWxBY3Rpb24iOnsic2lnbmFsIjoiU0tJUF9OQVZJR0FUSU9OIn19XX19fX19fSwibWljcm9mb3JtYXQiOnsibWljcm9mb3JtYXREYXRhUmVuZGVyZXIiOnsidXJsQ2Fub25pY2FsIjoiaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLCJ0aXRsZSI6IkNvbmZyZWFrcyIsImRlc2NyaXB0aW9uIjoiVmlkZW9zIHJlY29yZGVkIGFuZC9vciBob3N0ZWQgYnkgQ29uZnJlYWtzLCBnZW5lcmFsbHkgaW4gdGhlIHRlY2hub2xvZ3kgc3BhY2UuIiwidGh1bWJuYWlsIjp7InRodW1ibmFpbHMiOlt7InVybCI6Imh0dHBzOi8veXQzLmdvb2dsZXVzZXJjb250ZW50LmNvbS95dGMvQUdJS2dxTm5BZlE0a1I4aVo5YXVvMVI3Z2l0bWVIYjdhNWhiOEZSaG45YWpyZz1zMjAwLWMtay1jMHgwMGZmZmZmZi1uby1yaj9kYXlzX3NpbmNlX2Vwb2NoPTE5NTE2Iiwid2lkdGgiOjIwMCwiaGVpZ2h0IjoyMDB9XX0sInNpdGVOYW1lIjoiWW91VHViZSIsImFwcE5hbWUiOiJZb3VUdWJlIiwiYW5kcm9pZFBhY2thZ2UiOiJjb20uZ29vZ2xlLmFuZHJvaWQueW91dHViZSIsImlvc0FwcFN0b3JlSWQiOiI1NDQwMDc2NjQiLCJpb3NBcHBBcmd1bWVudHMiOiJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsIm9nVHlwZSI6Inl0LWZiLWFwcDpjaGFubmVsIiwidXJsQXBwbGlua3NXZWIiOiJodHRwczovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDV25Qam1xdmxqY2FmQTB6MlUxZndLUT9mZWF0dXJlPWFwcGxpbmtzIiwidXJsQXBwbGlua3NJb3MiOiJ2bmQueW91dHViZTovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDV25Qam1xdmxqY2FmQTB6MlUxZndLUT9mZWF0dXJlPWFwcGxpbmtzIiwidXJsQXBwbGlua3NBbmRyb2lkIjoidm5kLnlvdXR1YmU6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1E/ZmVhdHVyZT1hcHBsaW5rcyIsInVybFR3aXR0ZXJJb3MiOiJ2bmQueW91dHViZTovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDV25Qam1xdmxqY2FmQTB6MlUxZndLUT9mZWF0dXJlPXR3aXR0ZXItZGVlcC1saW5rIiwidXJsVHdpdHRlckFuZHJvaWQiOiJ2bmQueW91dHViZTovL3d3dy55b3V0dWJlLmNvbS9jaGFubmVsL1VDV25Qam1xdmxqY2FmQTB6MlUxZndLUT9mZWF0dXJlPXR3aXR0ZXItZGVlcC1saW5rIiwidHdpdHRlckNhcmRUeXBlIjoic3VtbWFyeSIsInR3aXR0ZXJTaXRlSGFuZGxlIjoiQFlvdVR1YmUiLCJzY2hlbWFEb3RPcmdUeXBlIjoiaHR0cDovL3NjaGVtYS5vcmcvaHR0cDovL3NjaGVtYS5vcmcvWW91dHViZUNoYW5uZWxWMiIsIm5vaW5kZXgiOmZhbHNlLCJ1bmxpc3RlZCI6ZmFsc2UsImZhbWlseVNhZmUiOnRydWUsInRhZ3MiOlsicnVieSIsImphdmFzY3JpcHQiLCJjbG9qdXJlIiwidGVjaG5vbG9neSIsInByb2dyYW1taW5nIGxhbmd1YWdlIiwiZWxpeGlyIiwiZW1iZXIiLCJydXN0IiwicmFpbHMiLCJjb21wdXRlciBzY2llbmNlIiwicHJvZ3JhbW1pbmciLCJ0ZWNoIGNvbmZlcmVuY2UiLCJweXRob24iLCJkZXZvcHMiLCJkZXZvcHNkYXlzIiwicmVhY3QiLCJwb3N0Z3JlcyIsIkdOVVJhZGlvIl0sImF2YWlsYWJsZUNvdW50cmllcyI6WyJNSCIsIlVNIiwiUlUiLCJHUSIsIlRaIiwiR1IiLCJORSIsIktSIiwiREsiLCJHUyIsIkVDIiwiVFYiLCJUVCIsIklOIiwiUUEiLCJTUyIsIktQIiwiU0siLCJTViIsIkNSIiwiR00iLCJNTCIsIk1GIiwiQU8iLCJJTSIsIklTIiwiVkEiLCJaVyIsIkFEIiwiVFIiLCJNUCIsIkZKIiwiQUciLCJMQiIsIlRNIiwiQUUiLCJTSSIsIk1VIiwiQ0giLCJQVCIsIkNJIiwiUk8iLCJBTSIsIkdGIiwiS00iLCJCUiIsIlZVIiwiQlciLCJQVyIsIkpFIiwiQk0iLCJZVCIsIk1FIiwiTkwiLCJOQSIsIkVTIiwiS0UiLCJHVCIsIkxWIiwiU1oiLCJFSCIsIkFTIiwiQ0EiLCJCViIsIkFVIiwiTVYiLCJNRyIsIlZHIiwiTVIiLCJDViIsIkVUIiwiU0IiLCJESiIsIlVBIiwiQ04iLCJQUiIsIkNEIiwiSE4iLCJNQSIsIkNXIiwiTUsiLCJURCIsIlVZIiwiQlMiLCJLVyIsIkNLIiwiTU0iLCJLTiIsIkNMIiwiQkkiLCJQTCIsIk1aIiwiVVMiLCJSUyIsIlNPIiwiREUiLCJETSIsIk5GIiwiU1QiLCJOSSIsIkNNIiwiQVgiLCJQQSIsIllFIiwiSk0iLCJXUyIsIkFSIiwiQkciLCJCVCIsIkdHIiwiVEoiLCJQUyIsIkdJIiwiQUYiLCJCQiIsIk1RIiwiR0IiLCJNQyIsIk1TIiwiQkEiLCJDWiIsIkhNIiwiR1kiLCJDRiIsIlNDIiwiRUUiLCJQRiIsIklRIiwiTlAiLCJGUiIsIlRPIiwiSU8iLCJDWSIsIk5PIiwiUEsiLCJMUiIsIlROIiwiUkUiLCJTWCIsIkVSIiwiTloiLCJTSiIsIk1PIiwiS0ciLCJBUSIsIkJGIiwiS1kiLCJMSSIsIlNNIiwiQloiLCJQTSIsIktaIiwiTkMiLCJGTyIsIkFUIiwiRE8iLCJHTCIsIkZNIiwiUE4iLCJKTyIsIlpBIiwiU0giLCJCSCIsIlNOIiwiTFQiLCJJRCIsIkdIIiwiSUUiLCJHVSIsIlNFIiwiTFkiLCJUVyIsIlBHIiwiTVQiLCJQRSIsIlNBIiwiRkkiLCJMVSIsIk5HIiwiVkkiLCJHUCIsIlRMIiwiQkUiLCJOUiIsIlNZIiwiS0kiLCJVRyIsIlRGIiwiTUQiLCJISyIsIlNSIiwiU0ciLCJHQSIsIk1XIiwiQ08iLCJQSCIsIlJXIiwiVEMiLCJHRSIsIkhUIiwiTVgiLCJXRiIsIlZOIiwiVEciLCJIUiIsIkJKIiwiTFMiLCJUSCIsIkVHIiwiU0QiLCJJTCIsIkFMIiwiQVciLCJTTCIsIkJEIiwiSVIiLCJEWiIsIkNHIiwiTEEiLCJCTiIsIklUIiwiQ1UiLCJKUCIsIkNYIiwiTVkiLCJHRCIsIk9NIiwiVEsiLCJHVyIsIlVaIiwiRksiLCJWRSIsIk5VIiwiQlkiLCJBSSIsIkhVIiwiQVoiLCJCTCIsIkNDIiwiTEsiLCJHTiIsIlZDIiwiTU4iLCJQWSIsIkJPIiwiQlEiLCJLSCIsIlpNIiwiTEMiXSwibGlua0FsdGVybmF0ZXMiOlt7ImhyZWZVcmwiOiJodHRwczovL20ueW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EifSx7ImhyZWZVcmwiOiJhbmRyb2lkLWFwcDovL2NvbS5nb29nbGUuYW5kcm9pZC55b3V0dWJlL2h0dHAveW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EifSx7ImhyZWZVcmwiOiJpb3MtYXBwOi8vNTQ0MDA3NjY0L2h0dHAveW91dHViZS5jb20vY2hhbm5lbC9VQ1duUGptcXZsamNhZkEwejJVMWZ3S1EifV19fX07PC9zY3JpcHQ+PHNjcmlwdCBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+aWYgKHdpbmRvdy55dGNzaSkge3dpbmRvdy55dGNzaS50aWNrKCdwZHInLCBudWxsLCAnJyk7fTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPihmdW5jdGlvbiBzZXJ2ZXJDb250cmFjdCgpIHt3aW5kb3dbJ3l0UGFnZVR5cGUnXSA9ICJjaGFubmVsIjt3aW5kb3dbJ3l0Q29tbWFuZCddID0geyJjbGlja1RyYWNraW5nUGFyYW1zIjoiSWhNSWticlc5cWUwX3dJVnlWQlBCQjJDT2dFVk1naGxlSFJsY201aGJBPT0iLCJjb21tYW5kTWV0YWRhdGEiOnsid2ViQ29tbWFuZE1ldGFkYXRhIjp7InVybCI6Ii9AY29uZnJlYWtzIiwid2ViUGFnZVR5cGUiOiJXRUJfUEFHRV9UWVBFX0NIQU5ORUwiLCJyb290VmUiOjM2MTEsImFwaVVybCI6Ii95b3V0dWJlaS92MS9icm93c2UifSwicmVzb2x2ZVVybENvbW1hbmRNZXRhZGF0YSI6eyJpc1Zhbml0eVVybCI6dHJ1ZX19LCJicm93c2VFbmRwb2ludCI6eyJicm93c2VJZCI6IlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsInBhcmFtcyI6IkVnQzRBUUNTQXdEeUJnUUtBaklBIn19O3dpbmRvd1sneXRVcmwnXSA9ICdcL0Bjb25mcmVha3M/Y2JyZFx4M2QxXHgyNnVjYmNiXHgzZDEnO3ZhciBhPXdpbmRvdzsoZnVuY3Rpb24oZSl7dmFyIGM9d2luZG93O2MuZ2V0SW5pdGlhbENvbW1hbmQ9ZnVuY3Rpb24oKXtyZXR1cm4gZX07Yy5sb2FkSW5pdGlhbENvbW1hbmQmJmMubG9hZEluaXRpYWxDb21tYW5kKGMuZ2V0SW5pdGlhbENvbW1hbmQoKSl9KShhLnl0Q29tbWFuZCk7CihmdW5jdGlvbihlLGMsbCxmLGcsaCxrKXt2YXIgZD13aW5kb3c7ZC5nZXRJbml0aWFsRGF0YT1mdW5jdGlvbigpe3ZhciBiPXdpbmRvdztiLnl0Y3NpJiZiLnl0Y3NpLnRpY2soInByIixudWxsLCIiKTtiPXtwYWdlOmUsZW5kcG9pbnQ6YyxyZXNwb25zZTpsfTtmJiYoYi5wbGF5ZXJSZXNwb25zZT1mKTtnJiYoYi5yZWVsV2F0Y2hTZXF1ZW5jZVJlc3BvbnNlPWcpO2smJihiLnVybD1rKTtoJiYoYi5wcmV2aW91c0Nzbj1oKTtyZXR1cm4gYn07ZC5sb2FkSW5pdGlhbERhdGEmJmQubG9hZEluaXRpYWxEYXRhKGQuZ2V0SW5pdGlhbERhdGEoKSl9KShhLnl0UGFnZVR5cGUsYS55dENvbW1hbmQsYS55dEluaXRpYWxEYXRhLGEueXRJbml0aWFsUGxheWVyUmVzcG9uc2UsYS55dEluaXRpYWxSZWVsV2F0Y2hTZXF1ZW5jZVJlc3BvbnNlLGEueXRQcmV2aW91c0NzbixhLnl0VXJsKTsKfSkoKTs8L3NjcmlwdD48bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3MvZGVza3RvcC8zNzRmYWFkNS9jc3NiaW4vd3d3LW1haW4tZGVza3RvcC13YXRjaC1wYWdlLXNrZWxldG9uLmNzcyIgbmFtZT0id3d3LW1haW4tZGVza3RvcC13YXRjaC1wYWdlLXNrZWxldG9uIiBub25jZT0iTV9FT0JuVlNBdEV4eERxYlE0VTJKZyI+PGRpdiBpZD0id2F0Y2gtcGFnZS1za2VsZXRvbiIgY2xhc3M9IndhdGNoLXNrZWxldG9uICBoaWRkZW4iPjxkaXYgaWQ9ImNvbnRhaW5lciI+PGRpdiBpZD0icmVsYXRlZCI+PGRpdiBjbGFzcz0iYXV0b3BsYXkgc2tlbGV0b24tbGlnaHQtYm9yZGVyLWJvdHRvbSI+PGRpdiBpZD0idXBuZXh0IiBjbGFzcz0ic2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9InZpZGVvLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJ2aWRlby1kZXRhaWxzIj48ZGl2IGNsYXNzPSJ0aHVtYm5haWwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImRldGFpbHMgZmxleC0xIj48ZGl2IGNsYXNzPSJ2aWRlby10aXRsZSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1tZXRhIHRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InZpZGVvLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJ2aWRlby1kZXRhaWxzIj48ZGl2IGNsYXNzPSJ0aHVtYm5haWwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImRldGFpbHMgZmxleC0xIj48ZGl2IGNsYXNzPSJ2aWRlby10aXRsZSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1tZXRhIHRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InZpZGVvLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJ2aWRlby1kZXRhaWxzIj48ZGl2IGNsYXNzPSJ0aHVtYm5haWwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImRldGFpbHMgZmxleC0xIj48ZGl2IGNsYXNzPSJ2aWRlby10aXRsZSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1tZXRhIHRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InZpZGVvLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJ2aWRlby1kZXRhaWxzIj48ZGl2IGNsYXNzPSJ0aHVtYm5haWwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImRldGFpbHMgZmxleC0xIj48ZGl2IGNsYXNzPSJ2aWRlby10aXRsZSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1tZXRhIHRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InZpZGVvLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJ2aWRlby1kZXRhaWxzIj48ZGl2IGNsYXNzPSJ0aHVtYm5haWwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImRldGFpbHMgZmxleC0xIj48ZGl2IGNsYXNzPSJ2aWRlby10aXRsZSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1tZXRhIHRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InZpZGVvLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJ2aWRlby1kZXRhaWxzIj48ZGl2IGNsYXNzPSJ0aHVtYm5haWwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImRldGFpbHMgZmxleC0xIj48ZGl2IGNsYXNzPSJ2aWRlby10aXRsZSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1tZXRhIHRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InZpZGVvLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJ2aWRlby1kZXRhaWxzIj48ZGl2IGNsYXNzPSJ0aHVtYm5haWwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImRldGFpbHMgZmxleC0xIj48ZGl2IGNsYXNzPSJ2aWRlby10aXRsZSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1tZXRhIHRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InZpZGVvLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJ2aWRlby1kZXRhaWxzIj48ZGl2IGNsYXNzPSJ0aHVtYm5haWwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImRldGFpbHMgZmxleC0xIj48ZGl2IGNsYXNzPSJ2aWRlby10aXRsZSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1tZXRhIHRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InZpZGVvLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJ2aWRlby1kZXRhaWxzIj48ZGl2IGNsYXNzPSJ0aHVtYm5haWwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImRldGFpbHMgZmxleC0xIj48ZGl2IGNsYXNzPSJ2aWRlby10aXRsZSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1tZXRhIHRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9InZpZGVvLXNrZWxldG9uIj48ZGl2IGNsYXNzPSJ2aWRlby1kZXRhaWxzIj48ZGl2IGNsYXNzPSJ0aHVtYm5haWwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9ImRldGFpbHMgZmxleC0xIj48ZGl2IGNsYXNzPSJ2aWRlby10aXRsZSB0ZXh0LXNoZWxsIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJ2aWRlby1tZXRhIHRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgaWQ9ImluZm8tY29udGFpbmVyIj48ZGl2IGlkPSJwcmltYXJ5LWluZm8iIGNsYXNzPSJza2VsZXRvbi1saWdodC1ib3JkZXItYm90dG9tIj48ZGl2IGlkPSJ0aXRsZSIgY2xhc3M9InRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgaWQ9ImluZm8iPjxkaXYgaWQ9ImNvdW50IiBjbGFzcz0idGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0iZmxleC0xIj48L2Rpdj48ZGl2IGlkPSJtZW51Ij48ZGl2IGNsYXNzPSJtZW51LWJ1dHRvbiBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0ibWVudS1idXR0b24gc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgY2xhc3M9Im1lbnUtYnV0dG9uIHNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGNsYXNzPSJtZW51LWJ1dHRvbiBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PGRpdiBjbGFzcz0ibWVudS1idXR0b24gc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjwvZGl2PjwvZGl2PjwvZGl2PjxkaXYgaWQ9InNlY29uZGFyeS1pbmZvIiBjbGFzcz0ic2tlbGV0b24tbGlnaHQtYm9yZGVyLWJvdHRvbSI+PGRpdiBpZD0idG9wLXJvdyI+PGRpdiBpZD0idmlkZW8tb3duZXIiIGNsYXNzPSJmbGV4LTEiPjxkaXYgaWQ9ImNoYW5uZWwtaWNvbiIgY2xhc3M9InNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48ZGl2IGlkPSJ1cGxvYWQtaW5mbyIgY2xhc3M9ImZsZXgtMSI+PGRpdiBpZD0ib3duZXItbmFtZSIgY2xhc3M9InRleHQtc2hlbGwgc2tlbGV0b24tYmctY29sb3IiPjwvZGl2PjxkaXYgaWQ9InB1Ymxpc2hlZC1kYXRlIiBjbGFzcz0idGV4dC1zaGVsbCBza2VsZXRvbi1iZy1jb2xvciI+PC9kaXY+PC9kaXY+PC9kaXY+PGRpdiBpZD0ic3Vic2NyaWJlLWJ1dHRvbiIgY2xhc3M9InNrZWxldG9uLWJnLWNvbG9yIj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48L2Rpdj48c2NyaXB0IG5vbmNlPSJoYUVvWWhqT3pZR2pCeDI0Q1hSQnlRIj5pZiAod2luZG93Lnl0Y3NpKSB7d2luZG93Lnl0Y3NpLnRpY2soJ2djYycsIG51bGwsICcnKTt9PC9zY3JpcHQ+PHNjcmlwdCBub25jZT0iaGFFb1loak96WUdqQngyNENYUkJ5USI+eXRjZmcuc2V0KHsiQ1NJX1NFUlZJQ0VfTkFNRSI6ICd5b3V0dWJlJywgIlRJTUlOR19JTkZPIjoge319KTwvc2NyaXB0PjxzY3JpcHQgbm9uY2U9ImhhRW9ZaGpPellHakJ4MjRDWFJCeVEiPmlmICh3aW5kb3cueXRjc2kpIHt3aW5kb3cueXRjc2kuaW5mbygnc3QnLCAgMTg2LjAgLCAnJyk7fTwvc2NyaXB0PjwvYm9keT48L2h0bWw+\n    recorded_at: Thu, 08 Jun 2023 18:33:58 GMT\nrecorded_with: VCR 6.1.0\n"
  },
  {
    "path": "test/vcr_cassettes/youtube/playlist_items/all.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: get\n    uri: https://youtube.googleapis.com/youtube/v3/playlistItems?key=REDACTED_YOUTUBE_API_KEY&maxResults=50&part=snippet,contentDetails&playlistId=PLE7tQUdRKcyZYz0O3d9ZDdo0-BkOWhrSk\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Tue, 06 Jun 2023 08:23:15 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      Cache-Control:\n      - private\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: !binary |-\n        ewogICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtTGlzdFJlc3BvbnNlIiwKICAiZXRhZyI6ICJVb1lnN3JsUDhpbUYyLU1TeVdoRk9xdWFnY2MiLAogICJuZXh0UGFnZVRva2VuIjogIkVBQWFCbEJVT2tORVNRIiwKICAiaXRlbXMiOiBbCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiOTlXdC15QXFMcGIzNlJfTGxWTHBHX0p6bW5BIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0MU5rSTBORVkyUkRFd05UVTNRME0yIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogV2VhdmluZyBhbmQgc2VhbWluZyBtb2NrcyBieSBWbGFkaW1pciBEZW1lbnR5ZXYiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJUbyBtb2NrIG9yIG5vdCBtb2NrIGlzIGFuIGltcG9ydGFudCBxdWVzdGlvbiwgYnV0IGxldCdzIGxlYXZlIGl0IGFwYXJ0IGFuZCBhZG1pdCB0aGF0IHdlLCBSdWJ5aXN0cywgdXNlIG1vY2tzIGluIG91ciB0ZXN0cy5cblxuTW9ja2luZyBpcyBhIHBvd2VyZnVsIHRlY2huaXF1ZSwgYnV0IGV2ZW4gd2hlbiB1c2VkIHJlc3BvbnNpYmx5LCBpdCBjb3VsZCBsZWFkIHRvIGZhbHNlIHBvc2l0aXZlcyBpbiBvdXIgdGVzdHMgKHRodXMsIGJ1Z3MgbGVha2luZyB0byBwcm9kdWN0aW9uKTogZmFrZSBvYmplY3RzIGNvdWxkIGRpdmVyZ2UgZnJvbSB0aGVpciByZWFsIGNvdW50ZXJwYXJ0cy5cblxuSW4gdGhpcyB0YWxrLCBJJ2QgbGlrZSB0byBkaXNjdXNzIHZhcmlvdXMgYXBwcm9hY2hlcyB0byBrZWVwaW5nIG1vY2tzIGluIGxpbmUgd2l0aCB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIGFuZCBwcmVzZW50IGEgYnJhbmQgbmV3IGlkZWEgYmFzZWQgb24gbW9jayBmaXh0dXJlcyBhbmQgY29udHJhY3RzLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLy1FeFBPLUZDS1FBL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvLUV4UE8tRkNLUUEvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvLUV4UE8tRkNLUUEvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLy1FeFBPLUZDS1FBL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvLUV4UE8tRkNLUUEvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMCwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiLUV4UE8tRkNLUUEiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIi1FeFBPLUZDS1FBIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjAwWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJGN0FuZ2t5UkFfNmYyUjd1c3UycThVdmdEck0iLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTR5T0RsR05FRTBOa1JHTUVFek1FUXkiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBGcm9tIFN0YXJ0IHRvIFB1Ymxpc2hlZCwgQ3JlYXRlIGEgZ2FtZSB3aXRoIFJ1YnkhIGJ5IENhbWVyb24gR29zZSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIldlJ2xsIGJlIGJ1aWxkaW5nIGEgZ2FtZSBpbiBSdWJ5IGZyb20gc3RhcnQgdG8gZmluaXNoIHVzaW5nIHRoZSBEcmFnb25SdWJ5IEdhbWVUb29sa2l0LiBGaW5hbGx5IHdlJ2xsIHB1Ymxpc2ggaXQgc28gdGhhdCB5b3VyIG5ldyBjcmVhdGlvbiBjYW4gYmUgc2hhcmVkLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLy1kejlLR1lNVDI0L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvLWR6OUtHWU1UMjQvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvLWR6OUtHWU1UMjQvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLy1kejlLR1lNVDI0L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvLWR6OUtHWU1UMjQvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMSwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiLWR6OUtHWU1UMjQiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIi1kejlLR1lNVDI0IiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjAwWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICIzZW1lWUlBTlZfbVRQVjVReWZ4YjUzaUs3T0UiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTR3TVRjeU1EaEdRVUU0TlRJek0wWTUiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBBbnlvbmUgQ2FuIFBsYXkgR3VpdGFyIChXaXRoIFJ1YnkpIGJ5IEtldmluIE11cnBoeSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkkndmUgZ290IHRoZSBibHVlcy4gSSd2ZSBiZWVuIGxvb2tpbmcgZm9yIHRoZSBwZXJmZWN0IGd1aXRhciB0b25lLCBidXQgaGF2ZW4ndCBmb3VuZCBpdC4gVG8gYW1wIHVwIG15IG1vb2QsIGxldCdzIHRlYWNoIGEgY29tcHV0ZXIgdG8gcGxheSB0aGUgZ3VpdGFyIHRocm91Z2ggYW4gYW1wbGlmaWVyLlxuXG5MZXQncyBzdHJpbmcgdG9nZXRoZXIgb2JqZWN0LW9yaWVudGVkIHByaW5jaXBsZXMgdG8gb3JjaGVzdHJhdGUgYSBibHVlcyBzaHVmZmxlLiBXZSdsbCBtb2RlbCBvdXIgZG9tYWluIHdpdGggdGhlIGhlbHAgb2YgaW5oZXJpdGFuY2UsIGNvbXBvc2l0aW9uLCBhbmQgZGVwZW5kZW5jeSBpbmplY3Rpb24uIFRoaXMgdGFsayB3aWxsIHN0cmlrZSBhIGNob3JkIHdpdGggeW91LCB3aGV0aGVyIHlvdSd2ZSBzdHJ1bW1lZCBhIGd1aXRhciBiZWZvcmUgb3Igbm90LiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzFmSVB2LXZPU2owL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMWZJUHYtdk9TajAvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMWZJUHYtdk9TajAvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzFmSVB2LXZPU2owL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMWZJUHYtdk9TajAvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMiwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiMWZJUHYtdk9TajAiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIjFmSVB2LXZPU2owIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjAwWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJHUk9NZGhHQlI1eTFJdXZIR1NTbGZEdkNHeWciLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQxTWpFMU1rSTBPVFEyUXpKR056TkciLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBSdWJ5IE9mZmljZSBIb3VycyB3aXRoIFNob3BpZnkgRW5naW5lZXJpbmcgYnkgUm9zZSBXaWVnbGV5LCBVZnVrIEtheXNlcmlsaW9nbHUiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJDdXJpb3VzIGFib3V0IFNob3BpZnnigJlzIHJlbGF0aW9uc2hpcCB3aXRoIFJ1Ynk/IEdvdCBxdWVzdGlvbnMgb24gcHJvamVjdHMgU2hvcGlmeSBSdWJ5IG9uIFJhaWxzIEVuZ2luZWVycyBhcmUgY3VycmVudGx5IHdvcmtpbmcgb24/IEpvaW4gUm9zZSBXaWVnbGV5IChTciBTdGFmZiBEZXZlbG9wZXIpLCBVZnVrIEtheXNlcmlsaW9nbHUgKFByb2R1Y3Rpb24gRW5naW5lZXJpbmcgTWFuYWdlciksIGFuZCBvdGhlciBTaG9waWZ5IEVuZ2luZWVycyBmb3IgYSAzMC1taW51dGUgb2ZmaWNlIGhvdXJzIHNlc3Npb24gZGVkaWNhdGVkIHRvIGFuc3dlcmluZyB5b3VyIHF1ZXN0aW9ucyBvbiBSdWJ5LCBTaG9waWZ54oCZcyByZWxhdGlvbnNoaXAgd2l0aCBSdWJ5LCBhbmQgbGlmZSBhdCBTaG9waWZ5ISIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzM3RGtNaW1MRzRBL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMzdEa01pbUxHNEEvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMzdEa01pbUxHNEEvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzM3RGtNaW1MRzRBL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMzdEa01pbUxHNEEvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMywKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiMzdEa01pbUxHNEEiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIjM3RGtNaW1MRzRBIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjAzWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJBZ0ZQazBHM2FlVk44dnVST3JXUVhzMklrMWciLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTR3T1RBM09UWkJOelZFTVRVek9UTXkiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBLZXlub3RlOiBMZWFybmluZyBETlMgYnkgSnVsaWEgRXZhbnMiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Ib0cyVDBhSnZmWS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0hvRzJUMGFKdmZZL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0hvRzJUMGFKdmZZL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Ib0cyVDBhSnZmWS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0hvRzJUMGFKdmZZL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDQsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIkhvRzJUMGFKdmZZIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJIb0cyVDBhSnZmWSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDoxNFoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAidDhsZEl1NVJfeFQwRUlEYnRlT1JlZVE5aFlBIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0eE1rVkdRak5DTVVNMU4wUkZORVV4IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogWmVuIGFuZCB0aGUgQXJ0IG9mIEluY3JlbWVudGFsIEF1dG9tYXRpb24gYnkgQWppIFNsYXRlciIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkF1dG9tYXRpb24gZG9lc27igJl0IGhhdmUgdG8gYmUgYWxsIG9yIG5vdGhpbmcuIEF1dG9tYXRpbmcgbWFudWFsIHByb2Nlc3NlcyBpcyBhIHByYWN0aWNlIHRoYXQgb25lIGNhbiBlbXBsb3kgdmlhIHNpbXBsZSBwcmluY2lwbGVzLiBCcm9hZCBlbm91Z2ggdG8gYmUgYXBwbGllZCB0byBhIHJhbmdlIG9mIHdvcmtmbG93cywgZmxleGlibGUgZW5vdWdoIHRvIGJlIHRhaWxvcmVkIHRvIGFuIGluZGl2aWR1YWzigJlzIHBlcnNvbmFsIGRldmVsb3BtZW50IHJvdXRpbmVzOyB0aGVzZSBwcmluY2lwbGVzIGFyZSBub3QgaW4gdGhlbXNlbHZlcyBjb21wbGV4LCBhbmQgY2FuIGJlIHBlcmZvcm1lZCByZWd1bGFybHkgaW4gdGhlIGRheSB0byBkYXkgb2Ygd29ya2luZyBpbiBhIGNvZGViYXNlLlxuTGVhcm4gaG93IHRvIGN1bHRpdmF0ZSBoYWJpdHMgYW5kIGEgY3VsdHVyZSBvZiBpbmNyZW1lbnRhbCBhdXRvbWF0aW9uIHNvIGV2ZW4gaWYgdGhlIGdvYWwgaXMgbm90IGEgZnVsbCBzZWxmLXNlcnZpY2Ugc3VpdGUgb2YgYXV0b21hdGVkIHRvb2xzLCB5b3VyIHRlYW0gY2FuIGJlZ2luIGEgam91cm5leSBhd2F5IGZyb20gZnJpY3Rpb24gYW5kIG1hbnVhbCB0YXNrcy4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9JMmIxaDFnVk9mUS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0kyYjFoMWdWT2ZRL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0kyYjFoMWdWT2ZRL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9JMmIxaDFnVk9mUS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0kyYjFoMWdWT2ZRL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDUsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIkkyYjFoMWdWT2ZRIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJJMmIxaDFnVk9mUSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDowOFoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiZGRKaXF1U19HdVdpN1pULVdlc09zcHRRN2tFIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0MU16SkNRakJDTkRJeVJrSkROMFZEIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogU3ludGF4IFRyZWUgYnkgS2V2aW4gTmV3dG9uIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiU3ludGF4IFRyZWUgaXMgYSBuZXcgdG9vbGtpdCBmb3IgaW50ZXJhY3Rpbmcgd2l0aCB0aGUgUnVieSBwYXJzZSB0cmVlLiBJdCBjYW4gYmUgdXNlZCB0byBhbmFseXplLCBpbnNwZWN0LCBkZWJ1ZywgYW5kIGZvcm1hdCB5b3VyIFJ1YnkgY29kZS4gSW4gdGhpcyB0YWxrIHdlJ2xsIHdhbGsgdGhyb3VnaCBob3cgaXQgd29ya3MsIGhvdyB0byB1c2UgaXQgaW4geW91ciBvd24gYXBwbGljYXRpb25zLCBhbmQgdGhlIGV4Y2l0aW5nIGZ1dHVyZSBwb3NzaWJpbGl0aWVzIGVuYWJsZWQgYnkgU3ludGF4IFRyZWUuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSWVxNlNLdFlKRDQvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9JZXE2U0t0WUpENC9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9JZXE2U0t0WUpENC9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSWVxNlNLdFlKRDQvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9JZXE2U0t0WUpENC9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA2LAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJJZXE2U0t0WUpENCIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiSWVxNlNLdFlKRDQiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDFUMTY6MDA6MThaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIlo5VkpVWlBWak5kSjFQX1RuenRrU3RHdXlPNCIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NURRVU5FUkRRMk5rSXpSVVF4TlRZMSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAyLTI4VDIwOjI5OjQ4WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiBNaW5pIDIwMjI6IExpZ2h0bmluZyBUYWxrcyIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0lmek9feXlpWW13L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSWZ6T195eWlZbXcvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSWZ6T195eWlZbXcvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0lmek9feXlpWW13L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSWZ6T195eWlZbXcvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNywKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiSWZ6T195eWlZbXciCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIklmek9feXlpWW13IiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjE4WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJHLVItb2R5eWEyWXdPSUhSVHczbkZtNEtYbTAiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQ1TkRrMVJFWkVOemhFTXpVNU1EUXoiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBXaG8gV2FudHMgdG8gYmUgYSBSdWJ5IEVuZ2luZWVyPyBieSBEcmV3IEJyYWdnIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiV2VsY29tZSB0byB0aGUgUnVieSBnYW1lIHNob3cgd2hlcmUgb25lIGx1Y2t5IGNvbnRlc3RhbnQgdHJpZXMgdG8gZ3Vlc3MgdGhlIG91dHB1dCBvZiBhIHNtYWxsIGJpdCBvZiBSdWJ5IGNvZGUuIFNvdW5kIGVhc3k/IEhlcmUncyB0aGUgY2hhbGxlbmdlOiB0aGUgc25pcHBldHMgY29tZSBmcm9tIHNvbWUgb2YgdGhlIHdlaXJkZXN0IHBhcnRzIG9mIHRoZSBSdWJ5IGxhbmd1YWdlLiAgVGhlIHF1ZXN0aW9ucyBhcmVuJ3QgZWFzeS4gR2V0IGVub3VnaCByaWdodCB0byBiZSBjcm93bmVkIGEgKHNvbWUgc29ydCBvZiBzb21ldGhpbmcpIFJ1YnkgRW5naW5lZXIgYW5kIHdpbiBhIGZhYnVsb3VzLCBteXN0ZXJpb3VzIHByaXplLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0pvWm85dUd1WFF3L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSm9abzl1R3VYUXcvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSm9abzl1R3VYUXcvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0pvWm85dUd1WFF3L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSm9abzl1R3VYUXcvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogOCwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiSm9abzl1R3VYUXciCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIkpvWm85dUd1WFF3IiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjE4WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJ4OXkzT2U3dFJMdjUzQ29wem1EdDhxY2NqVmsiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTVHTmpORFJEUkVNRFF4T1RoQ01EUTIiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBLZXlub3RlIGJ5IEJhcmJhcmEgVGFubmVuYmF1bSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0pwaW1Kc3BtZXNzL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSnBpbUpzcG1lc3MvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSnBpbUpzcG1lc3MvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0pwaW1Kc3BtZXNzL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSnBpbUpzcG1lc3MvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogOSwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiSnBpbUpzcG1lc3MiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIkpwaW1Kc3BtZXNzIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjE4WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJvVHNyUlVXYS1yNk1KTEh0OE8tTUxFQkprSVUiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQwTnpaQ01FUkRNalZFTjBSRlJUaEIiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBTb2xvOiBCdWlsZGluZyBTdWNjZXNzZnVsIFdlYiBBcHBzIEJ5IFlvdXIgTG9uZXNvbWUgYnkgSmVyZW15IFNtaXRoIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiV2hldGhlciBieSBjaG9pY2Ugb3IgYnkgY2lyY3Vtc3RhbmNlLCB5b3UgbWF5IGZpbmQgeW91cnNlbGYgZGV2ZWxvcGluZyBhIHdlYiBhcHBsaWNhdGlvbiBhbG9uZS4gQ29uZ3JhdHVsYXRpb25zISBZb3UndmUgZ290IHRoZSBob3VzZSB0byB5b3Vyc2VsZiBhbmQgbm8gb25lIHRlbGxpbmcgeW91IHdoYXQgdG8gZG8uIEJ1dCBhdCB0aGUgc2FtZSB0aW1lLCB0aGVyZSdzIG5vIG9uZSB0byBzaGFyZSB0aGUgYnVyZGVuIG9yIG1ha2UgdXAgZm9yIHlvdXIgc2hvcnRjb21pbmdzLiBIb3cgZG8geW91IGJ1aWxkIHdlbGwgYW5kIGVuc3VyZSBwcm9qZWN0IHN1Y2Nlc3M/IFdlJ2xsIGxvb2sgYXQgdGhlIHByb3MgYW5kIGNvbnMgb2Ygd29ya2luZyBhbG9uZSwgd2hhdCBraW5kcyBvZiBwcm9qZWN0cyBhcmUgd2VsbC1zdWl0ZWQgdG8gc29sbyBkZXZlbG9wbWVudCwgc3RyYXRlZ2llcyBmb3IgcHJvZmVzc2lvbmFsIGdyb3d0aCwgYW5kIGRldmVsb3BtZW50IGFuZCBvcGVyYXRpb25hbCBwcm9jZXNzZXMgdGhhdCB3aWxsIHNhdmUgeW91IHRpbWUgYW5kIGhlbHAgeW91IHNsZWVwIGJldHRlciBhdCBuaWdodC4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Scjg3MXZtVjRZTS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JyODcxdm1WNFlNL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JyODcxdm1WNFlNL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Scjg3MXZtVjRZTS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JyODcxdm1WNFlNL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDEwLAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJScjg3MXZtVjRZTSIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiUnI4NzF2bVY0WU0iLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDFUMTY6MDA6MjZaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogImd4UTVZOWZzUTJLNVBFNEp0aGczT1ZhRVNHZyIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NUVNRUV3UlVZNU0wUkRSVFUzTkRKQyIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAyLTI4VDIwOjI5OjQ4WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiBNaW5pIDIwMjI6IEVtcGF0aGV0aWMgUGFpciBQcm9ncmFtbWluZyB3aXRoIE5vbnZpb2xlbnQgQ29tbXVuaWNhdGlvbiBieSBTdGVwaGFuaWUgTWlubiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlBhaXIgcHJvZ3JhbW1pbmcgaXMgaW50aW1hdGUuIEl04oCZcyB0aGUgY2xvc2VzdCBjb2xsYWJvcmF0aW9uIHdlIGRvIGFzIHNvZnR3YXJlIGRldmVsb3BlcnMuIFdoZW4gaXQgZ29lcyB3ZWxsLCBpdCBmZWVscyBncmVhdCEgQnV0IHdoZW4gaXQgZG9lc27igJl0LCB5b3UgbWlnaHQgYmUgbGVmdCBmZWVsaW5nIGZydXN0cmF0ZWQsIGRpc2NvdXJhZ2VkLCBvciB3aXRoZHJhd24uXG5cblRvIG5hdmlnYXRlIHRoZSB2dWxuZXJhYmlsaXR5IG9mIHNoYXJpbmcgb3VyIGtleWJvYXJkIGFuZCBjb2RlLCBsZXTigJlzIGxlYXJuIGFib3V0IG5vbnZpb2xlbnQgY29tbXVuaWNhdGlvbiAoTlZDKSwgYW4gZXN0YWJsaXNoZWQgcHJhY3RpY2Ugb2YgZGVlcCBsaXN0ZW5pbmcgdG8gb3Vyc2VsdmVzIGFuZCBvdGhlcnMuIFdl4oCZbGwgY292ZXIgcmVhbC1saWZlIGV4YW1wbGVzIGFuZCBob3cgdG8gYXBwbHkgdGhlIGZvdXIgdGVuZXRzIG9mIE5WQ+KAkyBvYnNlcnZhdGlvbnMsIGZlZWxpbmdzLCBuZWVkcywgYW5kIHJlcXVlc3Rz4oCTIHRvIGJyaW5nIG1vcmUgam95IGFuZCBmdWxmaWxsbWVudCB0aGUgbmV4dCB0aW1lIHlvdSBwYWlyLlxuRmVhdHVyZWQgcGxheWxpc3QiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Uemx5cnJhMDBaMC9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1R6bHlycmEwMFowL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1R6bHlycmEwMFowL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Uemx5cnJhMDBaMC9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1R6bHlycmEwMFowL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDExLAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJUemx5cnJhMDBaMCIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiVHpseXJyYTAwWjAiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDFUMTY6MDA6MTdaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIjBEUmZ6SkdweGp2V2NKYnV1TFFZZHBkRGQ3TSIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NDVPRFJETlRnMFFqQTROa0ZCTmtReSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAyLTI4VDIwOjI5OjQ4WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiBNaW5pIDIwMjI6IFRERCBvbiB0aGUgU2hvdWxkZXJzIG9mIEdpYW50cyBieSBKYXJlZCBOb3JtYW4iLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJHZXR0aW5nIHN0YXJ0ZWQgd2l0aCBUREQgaXMgaGFyZCBlbm91Z2ggd2l0aG91dCBoYXZpbmcgdG8gYWxzbyBuYXZpZ2F0ZSBhIHByb2dyYW1taW5nIGxhbmd1YWdlIGJhcnJpZXIuIE1hbnkgb2YgdGhlIGJlc3QgYm9va3Mgb24gdGVzdGluZyBmb2N1cyBvbiB2ZXJ5IGRpZmZlcmVudCBsYW5ndWFnZXMgbGlrZSBKYXZhLCBtYWtpbmcgaXQgdHJpY2t5IHRvIGFwcGx5IHRoZWlyIGFkdmljZSBpbiBSdWJ5LCBlc3BlY2lhbGx5IGlmIHlvdSdyZSBuZXcgdG8gdGVzdGluZy4gSSdsbCBnbyB0aHJvdWdoIHRoZSBtb3N0IGltcG9ydGFudCBwcmFjdGljZXMgYW5kIHRlY2huaXF1ZXMgdGhhdCB3ZSBjYW4gcHVsbCBmcm9tIHRoZSB0ZXN0aW5nIGxpdGVyYXR1cmUgYW5kIHNob3cgaG93IHRoZXkgY2FuIGJlIGFwcGxpZWQgaW4geW91ciBkYXktdG8tZGF5IFJ1YnkgZGV2ZWxvcG1lbnQuIFlvdSdsbCBsZWFybiBob3cgdG8gbWFrZSB0aGUgbW9zdCBvZiB0ZXN0aW5nIGluIFJ1YnkgdXNpbmcgdGhlIHBhdHRlcm5zLCBwcmFjdGljZXMsIGFuZCB0ZWNobmlxdWVzIHRoYXQgcG9wdWxhcml6ZWQgVEREIGluIHRoZSBmaXJzdCBwbGFjZS4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9WOFN4OGg3S1paUS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1Y4U3g4aDdLWlpRL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1Y4U3g4aDdLWlpRL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9WOFN4OGg3S1paUS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1Y4U3g4aDdLWlpRL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDEyLAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJWOFN4OGg3S1paUSIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiVjhTeDhoN0taWlEiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDFUMTY6MDA6MTlaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogInZxb3lrZE9vUV9iYXFrNFdjUE1ScmtyaVgzcyIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NHpNRGc1TWtRNU1FVkRNRU0xTlRnMiIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAyLTI4VDIwOjI5OjQ4WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiBNaW5pIDIwMjI6IENyeXN0YWwgZm9yIFJ1Ynlpc3RzIGJ5IEtpcmsgSGFpbmVzIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiQ3J5c3RhbCBpcyBhIFJ1YnktbGlrZSBjb21waWxlZCBsYW5ndWFnZSB0aGF0IHdhcyBvcmlnaW5hbGx5IGJ1aWx0IHVzaW5nIFJ1YnkuIEl0cyBzeW50YXggaXMgcmVtYXJrYWJseSBzaW1pbGFyIHRvIFJ1Ynkncywgd2hpY2ggZ2VuZXJhbGx5IG1ha2VzIGl0IHN0cmFpZ2h0Zm9yd2FyZCBmb3IgYSBSdWJ5IHByb2dyYW1tZXIgdG8gc3RhcnQgdXNpbmcgQ3J5c3RhbC4gVGhlcmUgYXJlIHNvbWUgbm90YWJsZSwgYW5kIGludGVyZXN0aW5nIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIGxhbmd1YWdlcywgaG93ZXZlci4gSW4gdGhpcyB3b3Jrc2hvcCwgbGV0J3MgbGVhcm4gc29tZSBDcnlzdGFsIHdoaWxlIHdlIGxlYXJuIGEgbGl0dGxlIGFib3V0IHRoZSBzaW1pbGFyaXRpZXMgYW5kIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSB0d28gbGFuZ3VhZ2VzLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1ltc1NtcDR5ak9jL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWW1zU21wNHlqT2MvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWW1zU21wNHlqT2MvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1ltc1NtcDR5ak9jL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWW1zU21wNHlqT2MvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMTMsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIlltc1NtcDR5ak9jIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJZbXNTbXA0eWpPYyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDoyMFoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiSEs2Zkp5NHp2c2FkcVhCMHdWdVdjM2Y1YmxjIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0MU16azJRVEF4TVRrek5EazRNRGhGIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogUnVieUdlbXMub3JnIE1GQTogVGhlIFBhc3QsIFByZXNlbnQgYW5kIEZ1dHVyZSBieSBKZW5ueSBTaGVuIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiV2hhdCBkbyBSdWJ54oCZcyByZXN0LWNsaWVudCwgUHl0aG9u4oCZcyBjdHgsIGFuZCBucG3igJlzIHVhLXBhcnNlci1qcyBoYXZlIGluIGNvbW1vbj8gXG5cblRoZXkgYWxsIHN1ZmZlcmVkIGFjY291bnQgdGFrZW92ZXJzIHRoYXQgd2VyZSBwcmV2ZW50YWJsZS4gQXR0YWNrZXJzIGFpbSB0byB0YWtlIGNvbnRyb2wgb2YgYSBsZWdpdGltYXRlIFJ1YnlHZW1zLm9yZyB1c2VyIGFjY291bnQgYW5kIHRoZW4gdXNlIGl0IHRvIHVwbG9hZCBtYWxpY2lvdXMgY29kZS4gSXQgbWlnaHQgZGlhbCBob21lLiBJdCBtaWdodCBzdGVhbCB5b3VyIGtleXMuIFBlcmhhcHMgaXQgd2lsbCBlbmNyeXB0IHlvdXIgZGlzay4gT3IgYWxsIG9mIHRoZSBhYm92ZSEgRG9u4oCZdCB5b3Ugd2lzaCBpdCBjb3VsZG7igJl0IGhhcHBlbj9cblxuTUZBIHByZXZlbnRzIDk5LjklIG9mIGFjY291bnQgdGFrZW92ZXIgYXR0YWNrcy4gQ29tZSBsZWFybiBhYm91dCBNRkEsIHRoZSBoaXN0b3J5IG9mIFJ1YnlHZW1zLm9yZyBNRkEgc3VwcG9ydCwgdGhlIG5ldyBNRkEgcG9saWN5IGZvciB0b3AgZ2VtcywgYW5kIHdoYXTigJlzIG9uIHRoZSBob3Jpem9uLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1l4VkdNdndKc0hRL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWXhWR012d0pzSFEvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWXhWR012d0pzSFEvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1l4VkdNdndKc0hRL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWXhWR012d0pzSFEvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMTQsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIll4VkdNdndKc0hRIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJZeFZHTXZ3SnNIUSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDoxNloiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiWHZyaXc5MDJfc1FadzdLYzNwMFdsOGRMVUE0IiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk1RVFVRTFOVEZEUmpjd01EZzBORU16IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogVGhlIENhc2UgT2YgVGhlIFZhbmlzaGVkIFZhcmlhYmxlIC0gQSBSdWJ5IE15c3RlcnkgU3RvcnkgYnkgTmFkaWEgT2R1bmF5byIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkFmdGVyIGEgc3RyZXNzZnVsIGNvdXBsZSBvZiBkYXlzIGF0IHdvcmssIERlaXJkcmUgQnVnIGlzIGxvb2tpbmcgZm9yd2FyZCB0byBhIHF1aWV0IGV2ZW5pbmcgaW4uIEJ1dCBoZXIgcGxhbnMgYXJlIHRod2FydGVkIHdoZW4gdGhlIHBob25lIHJpbmdzLiDigJxJIGtub3cgSeKAmW0gdGhlIGxhc3QgcGVyc29uIHlvdSB3YW50IHRvIGhlYXIgZnJvbeKApmJ1dC4uLkkgbmVlZCB5b3VyIGhlbHAh4oCdIEZvbGxvdyBEZWlyZHJlIGFzIHNoZSBlbWJhcmtzIG9uIGFuIGFkdmVudHVyZSB0aGF0IGZlYXR1cmVzIGEgbG9vbWluZyBEZW1vIERheSB3aXRoIHNlcmlvdXMgcHJpemUgbW9uZXkgdXAgZm9yIGdyYWJzLCBhIHRyaXAgaW5zaWRlIHRoZSB3YWxscyBvZiBvbmUgb2YgdGhlIFJ1YnkgY29tbXVuaXR54oCZcyBtb3N0IHJldmVyZWQgaW5zdGl0dXRpb25zLCBhbmQgc29tZSBicm9rZW4gY29kZSB0aGF0IGFwcGVhcnMgdG8gYmUgbXVjaCBtb3JlIHNpbXBsZSB0aGFuIG1lZXRzIHRoZSBleWUuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYTYzYVN2SHUxOGMvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9hNjNhU3ZIdTE4Yy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9hNjNhU3ZIdTE4Yy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYTYzYVN2SHUxOGMvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9hNjNhU3ZIdTE4Yy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiAxNSwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiYTYzYVN2SHUxOGMiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogImE2M2FTdkh1MThjIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjAwWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJHdGFycGxTV3V2TWw2clplS2VsWUlZc0dYdkEiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQxUVRZMVEwVXhNVFZDT0Rjek5UaEUiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBTcGxpdHdpc2UgU3BvbnNvciBTZXNzaW9uOiBEZWNsYXJlIFZpY3Rvcnkgd2l0aCBDbGFzcyBNYWNyb3MgYnkgSmVzcyBIb3R0ZW5zdGVpbiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkhvdyBjYW4gd2Ugd3JpdGUgY2xhc3NlcyB0aGF0IGFyZSBlYXN5IHRvIHVuZGVyc3RhbmQ/IEhvdyBjYW4gd2Ugd3JpdGUgUnVieSBpbiBhIGRlY2xhcmF0aXZlIHdheT8gSG93IGNhbiB3ZSB1c2UgbWV0YXByb2dyYW1taW5nIHdpdGhvdXQgaW50cm9kdWNpbmcgY2hhb3M/XG5cbkNvbWUgbGVhcm4gdGhlIG1hZ2ljIGJlaGluZCB0aGUgZmlyc3QgYml0IG9mIG1ldGFwcm9ncmFtbWluZyB3ZSBhbGwgZW5jb3VudGVyIHdpdGggUnVieSAtIGF0dHJfcmVhZGVyLiBGcm9tIHRoZXJlLCB3ZSBjYW4gbGVhcm4gaG93IGRpZmZlcmVudCBnZW1zIHVzZSBjbGFzcyBtYWNyb3MgdG8gc2ltcGxpZnkgb3VyIGNvZGUuIEZpbmFsbHksIHdl4oCZbGwgZXhwbG9yZSBtdWx0aXBsZSB3YXlzIHdlIGNhbiBtYWtlIG91ciBvd24gY2xhc3MgbWFjcm9zIHRvIG1ha2Ugb3VyIGNvZGViYXNlIGVhc2llciB0byByZWFkIGFuZCBleHRlbmQuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYU1mSHFhaml4ZU0vZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9hTWZIcWFqaXhlTS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9hTWZIcWFqaXhlTS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYU1mSHFhaml4ZU0vc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9hTWZIcWFqaXhlTS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiAxNiwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiYU1mSHFhaml4ZU0iCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogImFNZkhxYWppeGVNIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjAxWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICIyNFl5bllTNjlwN3hSajYzNjVaOENWU0JMeG8iLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTR5TVVReVFUUXpNalJETnpNeVFUTXkiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBLZXlub3RlIGJ5IFJvc2UgV2llZ2xleSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2NfSGhmZWhNQkhFL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvY19IaGZlaE1CSEUvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvY19IaGZlaE1CSEUvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2NfSGhmZWhNQkhFL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvY19IaGZlaE1CSEUvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMTcsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogImNfSGhmZWhNQkhFIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJjX0hoZmVoTUJIRSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDoyMloiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiY2ozX0JQVEZGdFZGd1dnYkFPcy16YUN0SVNZIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0NVJUZ3hORFJCTXpVd1JqUTBNRGhDIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mTWluaSAyMDIyOiBUaGUgVGhyZWUtRW5jb2RpbmcgUHJvYmxlbSBieSBLZXZpbiBNZW5hcmQiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJZb3XigJl2ZSBwcm9iYWJseSBoZWFyZCBvZiBVVEYtOCBhbmQga25vdyBhYm91dCBzdHJpbmdzLCBidXQgZGlkIHlvdSBrbm93IHRoYXQgUnVieSBzdXBwb3J0cyBtb3JlIHRoYW4gMTAwIG90aGVyIGVuY29kaW5ncz8gSW4gZmFjdCwgeW91ciBhcHBsaWNhdGlvbiBwcm9iYWJseSB1c2VzIHRocmVlIGVuY29kaW5ncyB3aXRob3V0IHlvdSByZWFsaXppbmcgaXQuIE1vcmVvdmVyLCBlbmNvZGluZ3MgYXBwbHkgdG8gbW9yZSB0aGFuIGp1c3Qgc3RyaW5ncy4gSW4gdGhpcyB0YWxrLCB3ZeKAmWxsIHRha2UgYSBsb29rIGF0IFJ1YnnigJlzIGZhaXJseSB1bmlxdWUgYXBwcm9hY2ggdG8gZW5jb2RpbmdzIGFuZCBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUgaW1wYWN0IHRoZXkgaGF2ZSBvbiB0aGUgY29ycmVjdG5lc3MgYW5kIHBlcmZvcm1hbmNlIG9mIG91ciBhcHBsaWNhdGlvbnMuIFdl4oCZbGwgdGFrZSBhIGxvb2sgYXQgdGhlIHJpY2ggZW5jb2RpbmcgQVBJcyBSdWJ5IHByb3ZpZGVzIGFuZCBieSB0aGUgZW5kIG9mIHRoZSB0YWxrLCB5b3Ugd29u4oCZdCBqdXN0IHJlYWNoIGZvciBmb3JjZV9lbmNvZGluZyB3aGVuIHlvdSBzZWUgYW4gZW5jb2RpbmcgZXhjZXB0aW9uLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2VvRDBNc0JwRFhrL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZW9EME1zQnBEWGsvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZW9EME1zQnBEWGsvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2VvRDBNc0JwRFhrL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZW9EME1zQnBEWGsvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMTgsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogImVvRDBNc0JwRFhrIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJlb0QwTXNCcERYayIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDoyMFoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAibWxLOUhCbFd3VjhMa0NjQVV6ZXM3WmJLMHBFIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk1RU5EVTRRME00UkRFeE56TTFNamN5IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogU3BvbnNvciBQYW5lbCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2V4eFV6OWswM3M0L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZXh4VXo5azAzczQvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZXh4VXo5azAzczQvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2V4eFV6OWswM3M0L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZXh4VXo5azAzczQvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMTksCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogImV4eFV6OWswM3M0IgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJleHhVejlrMDNzNCIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDoyMloiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAia2hSQ20yVkR2ZnBFQ2hCc1psUlRYWjZUV1o0IiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0eU1EaEJNa05CTmpSRE1qUXhRVGcxIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogSGVyZSBCZSBEcmFnb25zOiBUaGUgSGlkZGVuIEdlbXMgb2YgVGVjaCBEZWJ0IGJ5IEVybmVzdG8gVGFnd2Vya2VyIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiSG93IGRvIHlvdSBmaW5kIHRoZSBtb3N0IHVubWFpbnRhaW5hYmxlIGNvZGUgaW4geW91ciBjb2RlYmFzZT8gV2hhdCB3aWxsIHlvdSBwcmlvcml0aXplIGluIHlvdXIgbmV4dCB0ZWNobmljYWwgZGVidCBzcGlrZSwgYW5kIHdoeT8gXG5cbkluIHRoaXMgdGFsayB5b3Ugd2lsbCBsZWFybiBob3cgeW91IGNhbiB1c2UgUnVieUNyaXRpYywgU2ltcGxlQ292LCBGbG9nLCBSZWVrLCBhbmQgU2t1bmsgdG8gc2xheSBkcmFnb25zIGluIHlvdXIgbmV4dCByZWZhY3RvcmluZyBhZHZlbnR1cmUhIEZpbmQgb3V0IGhvdyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gY2h1cm4sIGNvbXBsZXhpdHksIGFuZCBjb2RlIGNvdmVyYWdlIGNhbiBnaXZlIHlvdSBhIGNvbW1vbiBsYW5ndWFnZSB0byB0YWxrIGFib3V0IGNvZGUgcXVhbGl0eSBhbmQgaW5jcmVhc2UgdHJ1c3QgaW4geW91ciBjb2RlLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2ZsLWdib2dfd3RjL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZmwtZ2JvZ193dGMvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZmwtZ2JvZ193dGMvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2ZsLWdib2dfd3RjL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZmwtZ2JvZ193dGMvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMjAsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogImZsLWdib2dfd3RjIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJmbC1nYm9nX3d0YyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDozMVoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAidEVtTk43czF1OTIyQW9PTFhQMUVaVU5VdmtvIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk1R00wUTNNME16TXpZNU5USkZOVGRFIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogUG9kY2FzdCBQYW5lbCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2dPcTdQSi0wbmdBL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZ09xN1BKLTBuZ0EvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZ09xN1BKLTBuZ0EvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2dPcTdQSi0wbmdBL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZ09xN1BKLTBuZ0EvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMjEsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogImdPcTdQSi0wbmdBIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJnT3E3UEotMG5nQSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDoyNloiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiTTFDaFJtMG1ZZUtmcE1FUmxFVjA1bFpEMmxJIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0elJqTTBNa1ZDUlRnME1rWXlRVE0wIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogTG9va2luZyBJbnRvIFBlZXBob2xlIE9wdGltaXphdGlvbnMgYnkgTWFwbGUgT25nIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiRGlkIHlvdSBrbm93IFJ1Ynkgb3B0aW1pemVzIHlvdXIgY29kZSBiZWZvcmUgZXhlY3V0aW5nIGl0PyBJZiBzbywgZXZlciB3b25kZXIgaG93IHRoYXQgd29ya3M/IFRoZSBSdWJ5IFZNIHBlcmZvcm1zIHZhcmlvdXMgb3B0aW1pemF0aW9ucyBvbiBieXRlY29kZSBiZWZvcmUgZXhlY3V0aW5nIHRoZW0sIG9uZSBvZiB0aGVtIGNhbGxlZCBwZWVwaG9sZSBvcHRpbWl6YXRpb25zLiBMZXTigJlzIGxlYXJuIGFib3V0IGhvdyBzb21lIHBlZXBob2xlIG9wdGltaXphdGlvbnMgd29yayBhbmQgaG93IHRoZXNlIHNtYWxsIGNoYW5nZXMgaW1wYWN0IHRoZSBleGVjdXRpb24gb2YgUnVieeKAmXMgYnl0ZWNvZGUuIERvIHRoZXNlIHNtYWxsIGNoYW5nZXMgbWFrZSBhbnkgaW1wYWN0IG9uIHRoZSBmaW5hbCBydW50aW1lPyBMZXQncyBmaW5kIG91dCAtIGV4cGVyaWVuY2UgcmVhZGluZyBieXRlY29kZSBpcyBub3QgbmVlZGVkISIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2wwWWVSS2tVVTZjL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbDBZZVJLa1VVNmMvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbDBZZVJLa1VVNmMvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2wwWWVSS2tVVTZjL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbDBZZVJLa1VVNmMvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMjIsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogImwwWWVSS2tVVTZjIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJsMFllUktrVVU2YyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDoyNVoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAib1g2N21mcWVZMWR1S0lEWmtxdkd4R2hVR2xJIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0NU56VXdRa0kxTTBVeE5UaEJNa1UwIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmk6IEhvdyBXZSBJbXBsZW1lbnRlZCBTYWxhcnkgVHJhbnNwYXJlbmN5IChBbmQgV2h5IEl0IE1hdHRlcnMpIGJ5IEhpbGFyeSBTdG9ocyBLcmF1c2UiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJEZXBlbmRpbmcgb24gd2hlcmUgeW91IGxpdmUsIG1vbmV5IGNhbiBiZSBhIHByaWNrbHkgdG9waWMgaW4gdGhlIHdvcmtwbGFjZTsgaG93ZXZlciwgc3VydmV5IGFmdGVyIHN1cnZleSBzaG93cyBpdOKAmXMgYWxzbyBhIGNvbnZlcnNhdGlvbiBtYW55IGVtcGxveWVlcyBhY3RpdmVseSB3YW50IHN0YXJ0ZWQuIERhdGEgYWxzbyBzaG93cyB0aGF0IHRyYW5zcGFyZW5jeSBhcm91bmQgd2FnZXMgaW5jcmVhc2VzIHRydXN0IGFuZCBqb2Igc2F0aXNmYWN0aW9uIGFuZCBpbXByb3ZlcyBnZW5kZXIgYW5kIHJhY2lhbCBzYWxhcnkgZXF1aXR5LlxuXG5Ib3dldmVyLCBqdXN0IGJlY2F1c2UgZm9sa3Mgd2FudCBzb21ldGhpbmcgZG9lc27igJl0IG1lYW4gZ2V0dGluZyB0aGVyZSB3aWxsIGJlIHNtb290aCBzYWlsaW5nIChhcyB3ZSBkaXNjb3ZlcmVkIHdoZW4gd2UgaW5zdGl0dXRlZCB3YWdlIHRyYW5zcGFyZW5jeSB0aHJlZSB5ZWFycyBhZ28pLiBJbiB0aGlzIHRhbGssIHdl4oCZbGwgZGlzY3VzcyB3aHkgc2FsYXJ5IHRyYW5zcGFyZW5jeSBtYXR0ZXJzLCB3YXlzIGl0IGNhbiBtYW5pZmVzdCwgYW5kIGhvdyB0byBwaXRjaCBpdCB0byB0aGUgcmVzdCBvZiB5b3VyIGNvbXBhbnkuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbFRpVmx5bEp4U1kvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9sVGlWbHlsSnhTWS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9sVGlWbHlsSnhTWS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbFRpVmx5bEp4U1kvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9sVGlWbHlsSnhTWS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiAyMywKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAibFRpVmx5bEp4U1kiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogImxUaVZseWxKeFNZIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjI2WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJjUzRCMm9QdnBKVEZTQXRQZzk2dXpmRlNCWlEiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTVETnpFMVJqWkVNVVpDTWpBMFJEQkIiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBTdGFydCBhIFJ1YnkgSW50ZXJuc2hpcCBieSBDaGVsc2VhIEthdWZtYW4gYW5kIEFkYW0gQ3VwcHkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJTdGFydGluZyBhbiBpbnRlcm5zaGlwIGRvZXNu4oCZdCBoYXZlIHRvIHJlZHVjZSB5b3VyIHRlYW0ncyBwcm9ncmVzcy4gT24gdGhlIGNvbnRyYXJ5LCBhIHF1YWxpdHkgaW50ZXJuc2hpcCBjYW4gYmVuZWZpdCBpbnRlcm5zIGFuZCBzZW5pb3IgZm9sa3MuIEFuZCwgaXQgZG9lc24ndCB0YWtlIG11Y2ggdG8gc2V0IHVwIGFuZCBzdGFydC4gV2UndmUgZG9uZSBvdmVyIDEwMCFcblxuWW914oCZbGwgdXNlIG91ciBlc3RhYmxpc2hlZCBibHVlcHJpbnQgdG8gZHJhZnQgYSBzdWNjZXNzZnVsIGludGVybnNoaXAgcHJvZ3JhbSB0aHJvdWdob3V0IHRoaXMgd29ya3Nob3AuIFdlJ2xsIHdhbGsgdGhyb3VnaCBhbGwgdGhlIHBsYW5uaW5nIHBoYXNlcyBhbmQgaGVscCB5b3Ugc2V0IHVwIHRoZSB0ZW1wbGF0ZXMgc28geW91J3JlIHJlYWR5IHRvIG1ha2UgaXQgYSB3aW4gZm9yIGFsbCBpbnZvbHZlZCBhbmQgXCJzZWxsIGl0XCIgdG8gbWFuYWdlbWVudC4gQnkgdGhlIGVuZCwgeW91ciBpbnRlcm5zaGlwIHByb2dyYW0gd2lsbCBiZSBwcmVwYXJlZCB0byBoaXQgdGhlIGdyb3VuZCBydW5uaW5nLCBzbyB5b3VyIGludGVybnMgd2lsbCBiZSBwcm9kdWN0aXZlIG9uIGRheSBvbmUuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbTBWTHJsY215a3MvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9tMFZMcmxjbXlrcy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9tMFZMcmxjbXlrcy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbTBWTHJsY215a3Mvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9tMFZMcmxjbXlrcy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiAyNCwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAibTBWTHJsY215a3MiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIm0wVkxybGNteWtzIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjIzWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJDcUVNdzh3eTd3X1dyZDVwWFRmZlAzVl9ZUlUiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQzTVRJMU5ESXdPVE13UWpJeE16TkciLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBLbm93aW5nIFdoZW4gVG8gV2FsayBBd2F5IGJ5IExpbmRzYXkgS2VsbHkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJQaWN0dXJlIHRoaXM6IHRoZSBqb2IgeW91J3ZlIGFsd2F5cyB3YW50ZWQuIERvaW5nIGV4YWN0bHkgdGhlIGtpbmQgb2Ygd29yayB5b3Ugd2FudC4gSGF2aW5nIGdyZWF0IGNvd29ya2VycyBhbmQgbWFuYWdlbWVudC4gQnV0IHRoZW4gc29tZXRoaW5nIHNoaWZ0cywgYW5kIHRoZSBkcmVhbSBiZWNvbWVzIGNsb3NlciB0byBhIG5pZ2h0bWFyZS4gSG93IGRvIHlvdSBpZGVudGlmeSB0aGVzZSB0aGluZ3MgaGFwcGVuaW5nPyBIb3cgZG8geW91IHJhaXNlIGNvbmNlcm5zIGluIGFuIGFwcHJvcHJpYXRlIHdheT8gQW5kIGFzIGEgbGFzdCByZXNvcnQsIGhvdyBkbyB5b3Uga25vdyB3aGVuIGl0J3MgdGhlIHJpZ2h0IGNob2ljZSB0byB3YWxrIGF3YXk/IiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvcWszME1xdENJTWMvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xazMwTXF0Q0lNYy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xazMwTXF0Q0lNYy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvcWszME1xdENJTWMvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xazMwTXF0Q0lNYy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiAyNSwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAicWszME1xdENJTWMiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogInFrMzBNcXRDSU1jIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjI1WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICItZDkxX1BTYkVVVGpNUFdKQ2pvQmJOdjZHemciLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTVEUTBNeVEwWTRNemcwTTBWR09FWXciLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBGdW5jdGlvbmFsIHByb2dyYW1taW5nIGZvciBmdW4gYW5kIHByb2ZpdCEhIGJ5IEplbm55IFNoaWgiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJGdW5jdGlvbmFsIHByb2dyYW1taW5nIGJyaW5ncyB5b3Ugbm90IGp1c3QgZnVuLCBidXQgYWxzbyBwcm9maXQhIFxuXG5IYXZlIHlvdSBldmVyIGZlbHQgY3VyaW91cyB0b3dhcmRzIGZ1bmN0aW9uYWwgcHJvZ3JhbW1pbmcgKEZQKT8gV2VyZSB5b3UsIHNvb24gYWZ0ZXJ3YXJkcywgaW50aW1pZGF0ZWQgYnkgdGhlIG15c3RpYyB0ZXJtcyBsaWtlIG1vbmFkcyBhbmQgZnVuY3RvcnM/IERvIHlvdSB0aGluayBGUCBpcyBub3QgcmVsYXRlZCB0byB5b3VyIFJ1Ynkgd29yayBhbmQgdGh1cywgdXNlbGVzcz8gR3Vlc3Mgd2hhdOKAk3lvdSBjYW4gYWN0dWFsbHkgYXBwbHkgRlAgdG8geW91ciBSdWJ5IHByb2plY3RzIGFuZCByZWFwIGJlbmVmaXRzIGZyb20gaXQgYmVmb3JlIGZ1bGx5IHVuZGVyc3RhbmRpbmcgd2hhdCBhIG1vbmFkIGlzIVxuXG5UaGlzIHRhbGsgd2lsbCB3YWxrIHlvdSB0aHJvdWdoIHRoZSBwb3dlcmZ1bCBtZW50YWwgbW9kZWxzIGFuZCB0b29scyB0aGF0IEZQIGdpdmVzIHVzLCBhbmQgaG93IHdlIGNhbiByZWFkaWx5IHVzZSB0aGVtIHRvIGltcHJvdmUgb3VyIGFwcHMgaW4gYSBsYW5ndWFnZSB0aGF0IHdlIGFsbCBsb3ZlIGFuZCB1bmRlcnN0YW5kLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3RRUG1GUVNJMGxvL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdFFQbUZRU0kwbG8vbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdFFQbUZRU0kwbG8vaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3RRUG1GUVNJMGxvL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdFFQbUZRU0kwbG8vbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMjYsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogInRRUG1GUVNJMGxvIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJ0UVBtRlFTSTBsbyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDozNVoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiQVYwd01UM1ZEekltaUo4THdxbFF6aGx3ZVVvIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0eVFVRTJRMEpFTVRrNE5UTTNSVFpDIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogVGVhY2hpbmcgUnVieSB0byBDb3VudCBieSBKb8OrbCBRdWVubmV2aWxsZSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlJ1YnkgaGFzIHNvbWUgb2YgdGhlIGJlc3QgdG9vbGluZyBpbiB0aGUgYnVzaW5lc3MgZm9yIHdvcmtpbmcgd2l0aCBpdGVyYXRpb24gYW5kIGRhdGEgc2VyaWVzLiBCeSBsZXZlcmFnaW5nIGl0cyBmdWxsIHBvd2VyLCB5b3UgY2FuIGJ1aWxkIGRlbGlnaHRmdWwgaW50ZXJmYWNlcyBmb3IgeW91ciBvYmplY3RzLlxuXG5JbiB0aGlzIGNhc2Utc3R1ZHkgYmFzZWQgcHJlc2VudGF0aW9uLCB3ZeKAmWxsIGV4cGxvcmUgYSB2YXJpZXR5IG9mIHByb2JsZW1zIHN1Y2ggYXMgY29tcG9zaW5nIEVudW1lcmFibGUgbWV0aG9kcywgZ2VuZXJhdGluZyBhIHNlcmllcyBvZiBjdXN0b20gb2JqZWN0cywgYW5kIGhvdyB0byBwcm92aWRlIGEgY2xlYW4gaW50ZXJmYWNlIGZvciBhIGNvbGxlY3Rpb24gd2l0aCBtdWx0aXBsZSB2YWxpZCB0cmF2ZXJzYWwgb3JkZXJzLiBCZXlvbmQganVzdCB0aGUgYmVsb3ZlZCBFbnVtZXJhYmxlIG1vZHVsZSwgdGhpcyB0YWxrIHdpbGwgdGFrZSB5b3UgaW50byB0aGUgd29ybGQgb2YgRW51bWVyYXRvcnMgYW5kIFJhbmdlcyBhbmQgZXF1aXAgeW91IHRvIHdyaXRlIG9iamVjdHMgdGhhdCBicmluZyBqb3kgdG8geW91ciB0ZWFtbWF0ZXMuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkveUNpR01ZemhsZXcvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS95Q2lHTVl6aGxldy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS95Q2lHTVl6aGxldy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkveUNpR01ZemhsZXcvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS95Q2lHTVl6aGxldy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiAyNywKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAieUNpR01ZemhsZXciCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogInlDaUdNWXpobGV3IiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTAxVDE2OjAwOjQyWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJoanVLQ1pqaVB4eGxhRF9FcEN0aGhpaDRqVGciLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTVETWtVNE5UWTFRVUZHUVRZd01ERTMiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQyMDoyOTo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgTWluaSAyMDIyOiBBIEJyZXdlcuKAmXMgR3VpZGUgdG8gRmlsdGVyaW5nIG91dCBDb21wbGV4aXR5IGFuZCBDaHVybiBieSBGaXRvIHZvbiBaYXN0cm93IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiQWxhbiBSaWRsZWhvb3ZlciwgRml0byB2b24gWmFzdHJvd1xuXG5NZWNoYW5pY2FsIGNvZmZlZSBtYWNoaW5lcyBhcmUgYW1hemluZyEgWW91IGRyb3AgaW4gYSBjb2luLCBsaXN0ZW4gZm9yIHRoZSBjbGluaywgbWFrZSBhIHNlbGVjdGlvbiwgYW5kIHRoZSBtYWNoaW5lIHNwcmluZ3MgdG8gbGlmZSwgaGlzc2luZywgY2xpY2tpbmcsIGFuZCB3aGlycmluZy4gVGhlbiB0aGUgY29tcGxleCBtZWNoYW5pY2FsIGJhbGxldCBlbmRzLCBzcGxhc2hpbmcgdGhhdCBnbG9yaW91cywgYXJvbWF0aWMgbGlxdWlkIGludG8gdGhlIGN1cC4gQWghIEPigJllc3QgbWFnbmlmaXF1ZSFcblxuVGhlcmXigJlzIGp1c3Qgb25lIHByb2JsZW0uIE91ciBjdXN0b21lcnMgYWxzbyB3YW50IHNvdXAhIEFuZCwgb3VyIG1hY2hpbmUgaXMgbm90IGV4dGVuc2libGUuIFNvLCB3ZSBoYXZlIGEgY2hvaWNlOiB3ZSBjYW4gYWRkIHRvIHRoZSBjb21wbGV4aXR5IG9mIG91ciBtYWNoaW5lIGJ5IGphbW1pbmcgaW4gYSBuZXcgZGlzcGVuc2VyIHdpdGggZWFjaCBuZXcgcmVxdWVzdDsgb3IsIHdlIGNhbiBwYXVzZSB0byBtYWtlIG91ciBtYWNoaW5lIG1vcmUgZXh0ZW5zaWJsZSBiZWZvcmUgZGV2ZWxvcG1lbnQgc2xvd3MgdG8gYSBoYWx0LiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3pISzFsWWg0bi1zL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvekhLMWxZaDRuLXMvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvekhLMWxZaDRuLXMvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3pISzFsWWg0bi1zL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvekhLMWxZaDRuLXMvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMjgsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogInpISzFsWWg0bi1zIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJ6SEsxbFloNG4tcyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wMVQxNjowMDozOVoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiNzk0T0FQQ01vOEZpRUI1ZG1QdUdZMFlJMGdnIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0NE1qYzVSRUZCUlVFMk1UZEZSRFUwIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDItMjhUMjA6Mjk6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIE1pbmkgMjAyMjogV2UgTmVlZCBTb21lb25lIFRlY2huaWNhbCBvbiB0aGUgQ2FsbCBieSBCcml0dGFueSBNYXJ0aW4iLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJBIERNLiBUaGUgZHJlYWRlZCBtZXNzYWdlLiDigJxUaGV5IHdhbnQgc29tZW9uZSB0ZWNobmljYWwgb24gdGhlIGNhbGwu4oCdXG5cbklmIHRoYXQgc3RhdGVtZW50IGlzIHRlcnJpZnlpbmcsIG5ldmVyIGZlYXIuIEJlaW5nIGVmZmVjdGl2ZSBhdCB0aGVzZSBpbnRlcmFjdGlvbnMgY2FuIGJlIGEgYmlnIG9wcG9ydHVuaXR5IGZvciB5b3VyIGNhcmVlci4gTGVhcm4gdGFjdGljcyBvbiB3aGVuIHRvIGNvbW1pdCB0byBjYWxscyBhbmQgaG93IHRvIGV4ZWN1dGUgdGhlbSB3aGlsZSBlbXBvd2VyaW5nIHlvdXIgdGVhbSwgY29uc2VydmluZyB5b3VyIHRpbWUgYW5kIGFjaW5nIHRoZSBmb2xsb3cgdGhyb3VnaC4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96T05SRWhOOXdRZy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3pPTlJFaE45d1FnL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3pPTlJFaE45d1FnL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96T05SRWhOOXdRZy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3pPTlJFaE45d1FnL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDI5LAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJ6T05SRWhOOXdRZyIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiek9OUkVoTjl3UWciLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDFUMTY6MDA6MzlaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIm1HbFQ4cGlXYWlaZVdvLUkzLUJYWFhGOV9sQSIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NDNORGhGUlRnd09UUkVSVFU0UmpnMyIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAyLTI4VDIwOjI5OjQ4WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiBNaW5pIDIwMjI6IE1ha2luZyAuaXNfYT8gRmFzdCBieSBKb2huIEhhd3Rob3JuIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiVW50aWwgUnVieSAzLjIgdGhlIGBpc19hP2AgbWV0aG9kIGNhbiBiZSBhIHN1cnByaXNpbmcgcGVyZm9ybWFuY2UgYm90dGxlbmVjay4gSXQgYmUgY2FsbGVkIGRpcmVjdGx5IG9yIHRocm91Z2ggaXRzIHZhcmlvdXMgc3lub255bXMgbGlrZSBjYXNlIHN0YXRlbWVudHMsIHJlc2N1ZSBzdGF0ZW1lbnRzLCBwcm90ZWN0ZWQgbWV0aG9kcywgYE1vZHVsZSM9PT1gIGFuZCBtb3JlISBSZWNlbnRseSBgaXNfYT9gIGFuZCBpdHMgdmFyaW91cyBmbGF2b3VycyBoYXZlIGJlZW4gb3B0aW1pemVkIGFuZCBpdCdzIG5vdyBmYXN0ZXIgYW5kIHJ1bnMgaW4gY29uc3RhbnQgdGltZS4gSm9pbiBtZSBpbiB0aGUgam91cm5leSBvZiBpZGVudGlmeWluZyBpdCBhcyBhIGJvdHRsZW5lY2sgaW4gcHJvZHVjdGlvbiwgaW1wbGVtZW50aW5nIHRoZSBvcHRpbWl6YXRpb24sIHNxdWFzaGluZyBidWdzLCBhbmQgZmluYWxseSB0dXJuaW5nIGl0IGludG8gYXNzZW1ibHkgbGFuZ3VhZ2UgaW4gWUpJVC4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96Y0tiV1h6b3BDVS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3pjS2JXWHpvcENVL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3pjS2JXWHpvcENVL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96Y0tiV1h6b3BDVS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3pjS2JXWHpvcENVL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDMwLAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJ6Y0tiV1h6b3BDVSIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiemNLYldYem9wQ1UiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDFUMTY6MDA6MjhaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogImNicG01WUtRbXk3YzNkYUUySWJ1aDF3c0NJcyIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NDFRVVpHUVRZNU9URTRRVFJFUVVVNCIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDE5OjIyOjU0WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBMaWdodG5pbmcgVGFsa3MiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8tRk1fX0d5VDU3WS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLy1GTV9fR3lUNTdZL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLy1GTV9fR3lUNTdZL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8tRk1fX0d5VDU3WS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLy1GTV9fR3lUNTdZL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDMxLAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICItRk1fX0d5VDU3WSIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiLUZNX19HeVQ1N1kiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MDBaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIjcwdmpBcER6eXc3MWNVLWExa2p6YmZmTHAxTSIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NHpSREJET0VaRE9VTTBNRFk1TkVFeiIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDE5OjIyOjU0WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBSdWJ5IENlbnRyYWwgUGFuZWwiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8wSXRXY0JLN3BUay9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzBJdFdjQks3cFRrL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzBJdFdjQks3cFRrL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8wSXRXY0JLN3BUay9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzBJdFdjQks3cFRrL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDMyLAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICIwSXRXY0JLN3BUayIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiMEl0V2NCSzdwVGsiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MDBaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIkZwWWlVN0lrUUJ3bWc1am96eW5SYmJTYTE0ZyIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NUNNRVEyTWprNU5UYzNORFpGUlVOQiIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDE5OjIyOjU0WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBFeGl0KGluZykgVGhyb3VnaCB0aGUgWUpJVCBieSBFaWxlZW4gTSBVY2hpdGVsbGUiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJXaGVuIG9wdGltaXppbmcgY29kZSBmb3IgdGhlIFlKSVQgY29tcGlsZXIgaXQgY2FuIGJlIGRpZmZpY3VsdCB0byBmaWd1cmUgb3V0IHdoYXQgY29kZSBpcyBleGl0aW5nIGFuZCB3aHkuIFdoaWxlIHdvcmtpbmcgb24gdHJhY2luZyBleGl0cyBpbiBhIFJ1YnkgY29kZWJhc2UsIEkgZm91bmQgbXlzZWxmIHdpc2hpbmcgd2UgaGFkIGEgdG9vbCB0byByZXZlYWwgdGhlIGV4YWN0IGxpbmUgdGhhdCB3YXMgY2F1c2luZyBleGl0cyB0byBvY2N1ci4gV2Ugc2V0IHRvIHdvcmsgb24gYnVpbGRpbmcgdGhhdCBmdW5jdGlvbmFsaXR5IGludG8gUnVieSBhbmQgbm93IHdlIGFyZSBhYmxlIHRvIHNlZSBldmVyeSBzaWRlLWV4aXQgYW5kIHdoeS4gSW4gdGhpcyB0YWxrIHdl4oCZbGwgbGVhcm4gYWJvdXQgc2lkZS1leGl0cyBhbmQgaG93IHdlIGJ1aWx0IGEgdHJhY2VyIGZvciB0aGVtLiBXZeKAmWxsIGV4cGxvcmUgdGhlIG9yaWdpbmFsIGltcGxlbWVudGF0aW9uLCBob3cgd2UgcmV3cm90ZSBpdCBpbiBSdXN0LCBhbmQgbGFzdGx5IHdoeSBpdOKAmXMgc28gaW1wb3J0YW50IHRvIGFsd2F5cyBhc2sgXCJjYW4gSSBtYWtlIHdoYXQgSSBidWlsdCBldmVuIGJldHRlcj9cIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0VaRUVsNjFiV1N3L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRVpFRWw2MWJXU3cvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRVpFRWw2MWJXU3cvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0VaRUVsNjFiV1N3L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRVpFRWw2MWJXU3cvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMzMsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIkVaRUVsNjFiV1N3IgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJFWkVFbDYxYldTdyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDowNVoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAibmtTVi1jN0FwdnktTVRuLTBNelFobUQxcTlvIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0Mk1USTROamMyUWpNMVJqVTFNamxHIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMTk6MjI6NTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IENyb2NoZXRpbmcgJiBDb2Rpbmc6IHRoZXkncmUgbW9yZSBzaW1pbGFyIHRoYW4geW91IHRoaW5rISBieSBUb3JpIE1hY2hlbiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIk1hbnkgb2YgdXMgaGF2ZSBob2JiaWVzIHRoYXQgd2UgZW5qb3kgb3V0c2lkZSBvZiBvdXIgY2FyZWVycyBpbiB0ZWNoLiBGb3IgbWUsIHRoYXQgaXMgYW1pZ3VydW1pLCB0aGUgYXJ0IG9mIGNyb2NoZXRpbmcgc3R1ZmZlZCBjcmVhdHVyZXMuIFdoYXQgaWYgSSB0b2xkIHlvdSB0aGF0IGFtaWd1cnVtaSBpcyBleHRyZW1lbHkgc2ltaWxhciB0byBzb2Z0d2FyZSBkZXZlbG9wbWVudD8gSm9pbiBtZSBpbiBleHBsb3JpbmcgdGhlIGludGVyc2VjdGlvbiBiZXR3ZWVuIGNyb2NoZXRpbmcgYW1pZ3VydW1pIGFuZCBkZXZlbG9waW5nIHNvZnR3YXJlLiBXZeKAmWxsIGxvb2sgYXQgdGhlIGtleSBzaW1pbGFyaXRpZXMgYmV0d2VlbiB0aGVzZSB0d28gY3JhZnRzLCBhbmQgSeKAmWxsIHNoYXJlIGhvdyBjcm9jaGV0aW5nIGhhcyBoZWxwZWQgbWUgYmVjb21lIGEgYmV0dGVyIHNvZnR3YXJlIGRldmVsb3Blci4gWW914oCZbGwgd2FsayBhd2F5IGluc3BpcmVkIHRvIGNvbm5lY3QgeW91ciBvd24gaG9iYmllcyB0byB5b3VyIHJvbGUgaW4gdGVjaCBvciBmaW5kIGEgbmV3IGNyZWF0aXZlIGhvYmJ5IChsaWtlIGNyb2NoZXQpISIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0dPbldfNTg2VGlVL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvR09uV181ODZUaVUvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvR09uV181ODZUaVUvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0dPbldfNTg2VGlVL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvR09uV181ODZUaVUvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMzQsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIkdPbldfNTg2VGlVIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJHT25XXzU4NlRpVSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDowOFoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiNlctRGVqQ0ZwU2ZPMGNaWHRGS2xGSmRDa1VZIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0NVJqTkZNRGhHUTBRMlJrRkNRVGMxIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMTk6MjI6NTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IEtleW5vdGU6IFRoZSBDYXNlIE9mIFRoZSBWYW5pc2hlZCBWYXJpYWJsZSAtIEEgUnVieSBNeXN0ZXJ5IFN0b3J5IGJ5IE5hZGlhIE9kdW5heW8iLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJBZnRlciBhIHN0cmVzc2Z1bCBjb3VwbGUgb2YgZGF5cyBhdCB3b3JrLCBEZWlyZHJlIEJ1ZyBpcyBsb29raW5nIGZvcndhcmQgdG8gYSBxdWlldCBldmVuaW5nIGluLiBCdXQgaGVyIHBsYW5zIGFyZSB0aHdhcnRlZCB3aGVuIHRoZSBwaG9uZSByaW5ncy4g4oCcSSBrbm93IEnigJltIHRoZSBsYXN0IHBlcnNvbiB5b3Ugd2FudCB0byBoZWFyIGZyb23igKZidXQuLi5JIG5lZWQgeW91ciBoZWxwIeKAnSBGb2xsb3cgRGVpcmRyZSBhcyBzaGUgZW1iYXJrcyBvbiBhbiBhZHZlbnR1cmUgdGhhdCBmZWF0dXJlcyBhIGxvb21pbmcgRGVtbyBEYXkgd2l0aCBzZXJpb3VzIHByaXplIG1vbmV5IHVwIGZvciBncmFicywgYSB0cmlwIGluc2lkZSB0aGUgd2FsbHMgb2Ygb25lIG9mIHRoZSBSdWJ5IGNvbW11bml0eeKAmXMgbW9zdCByZXZlcmVkIGluc3RpdHV0aW9ucywgYW5kIHNvbWUgYnJva2VuIGNvZGUgdGhhdCBhcHBlYXJzIHRvIGJlIG11Y2ggbW9yZSBzaW1wbGUgdGhhbiBtZWV0cyB0aGUgZXllLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0hTZ1k5bzRnSVBFL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSFNnWTlvNGdJUEUvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSFNnWTlvNGdJUEUvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0hTZ1k5bzRnSVBFL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSFNnWTlvNGdJUEUvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMzUsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIkhTZ1k5bzRnSVBFIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJIU2dZOW80Z0lQRSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDoxMloiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiclo5Nlp4aTJwckxNbEs3SGZVSVRTOExJQURVIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0MFFUQTNOVFUyUmtNMVF6bENNell4IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMTk6MjI6NTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IEVjbGVjdGljcyBVbml0ZTogTGV2ZXJhZ2UgWW91ciBEaXZlcnNlIEJhY2tncm91bmQgYnkgU2lqaWEgV3UiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJJbiBhZGRpdGlvbiB0byB3cml0aW5nIFJ1YnkgZm9yIHdvcmssIEkgYW0gYWxzbyBhbiBhY2FkZW1pYyB0cmFuc2xhdG9yLCBhIHNub3dib2FyZCBpbnN0cnVjdG9yLCBhbmQgYSBkcnVtbWVyIGluIGEgcm9jayBiYW5kLiBJIGFtIGNvbnNpc3RlbnRseSBhbWF6ZWQgYW5kIGluc3BpcmVkIGJ5IHRoZSBzaW1pbGFyaXRpZXMgYW5kIGNvbm5lY3Rpb25zIGJldHdlZW4gc29mdHdhcmUgZGV2ZWxvcG1lbnQgYW5kIG15IHNlZW1pbmdseSB1bnJlbGF0ZWQgZXhwZXJpZW5jZXMuIFdoYXQgZG9lcyB0cmFuc2xhdGluZyBzY2llbmNlIGFydGljbGVzIHRlYWNoIG1lIGFib3V0IGVmZmVjdGl2ZWx5IHVzaW5nIGNvZGluZyByZXNvdXJjZXM/IEhvdyBpcyBwbGF5aW5nIGRydW1zIGluIGEgcmVoZWFyc2FsIHNpbWlsYXIgdG8gdGVzdC1kcml2ZW4gZGV2ZWxvcG1lbnQ/IEhvdyBkbyBJIGFwcGx5IHNub3dib2FyZCB0ZWFjaGluZyBwcmluY2lwbGVzIHRvIHBhaXIgcHJvZ3JhbW1pbmc/IEpvaW4gbWUgYXMgSSBzaGFyZSBteSBvd24gc3RvcnkgYW5kIGV4cGxvcmUgd2F5cyB5b3UgY2FuIGxldmVyYWdlIHlvdXIgZGl2ZXJzZSBiYWNrZ3JvdW5kLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL05HUXpCakRXby1BL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvTkdRekJqRFdvLUEvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvTkdRekJqRFdvLUEvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL05HUXpCakRXby1BL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvTkdRekJqRFdvLUEvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMzYsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIk5HUXpCakRXby1BIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJOR1F6QmpEV28tQSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDoxMloiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiOUgwSF9mOVhHWWxZeEhURExFWFk3U3VBLUhBIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk1QlJqSkRPRGs1UkVNME5qa3pNVUl5IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMTk6MjI6NTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IEtleW5vdGUgYnkgU3V6YW4gQm9uZCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlN1emFuIEJvbmQgaXMgYSBmb3JtZXIgQ09PIG9mIFRyYXZpcyBDSSwgbGVhZGVyc2hpcCBjb25zdWx0YW50IGFuZCBleGVjdXRpdmUgY29hY2guIEhlciBzcGVjaWFsdHkgaXMgbGVhZGVycyBhdCBzY2FsaW5nIHN0YXJ0dXBzLiBTaGUncyBzcGVudCBtb3JlIHRoYW4gMTUgeWVhcnMgaW4gdGVjaG5vbG9neS4gSGVyIGVkdWNhdGlvbiBiYWNrZ3JvdW5kIGluY2x1ZGVzIHBzeWNob2xvZ3ksIG9yZ2FuaXphdGlvbiBkZXZlbG9wbWVudCwgbGVhZGVyc2hpcCBhbmQgY29tbXVuaXR5IG9yZ2FuaXppbmcuIFN1emFuIGZhY2lsaXRhdGVzIHdvcmtzaG9wcyBhbmQgaXMgaG9zdCBvZiBMZWFkRGV2J3MgQm9va21hcmtlZCBzZXJpZXMuIFNoZSdzIHNwb2tlbiBhdCBudW1lcm91cyBldmVudHMsIGlzIGEgY29udHJpYnV0b3IgdG8gRmFzdCBDb21wYW55J3MgV29yayBMaWZlIHNlY3Rpb24gYW5kIHdyaXRlcyB0aGUgU3V6YW4ncyBGaWVsZG5vdGVzIG5ld3NsZXR0ZXIuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvT3FwQnhTcC00RkkvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PcXBCeFNwLTRGSS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PcXBCeFNwLTRGSS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvT3FwQnhTcC00Rkkvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PcXBCeFNwLTRGSS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiAzNywKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiT3FwQnhTcC00RkkiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIk9xcEJ4U3AtNEZJIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjE4WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJuQ3BfNUNia0dtSEVndXRpSEVwRWlBZ3F2amMiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTR4T1RFelF6aEJRelUzTURORE5qY3oiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQxOToyMjo1NFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogSG93IG11c2ljIHdvcmtzLCB1c2luZyBSdWJ5IFRoaWpzIENhZGllciIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoYXQgc3RyYW5nZSBwaGVub21lbm9uIHdoZXJlIGFpciBtb2xlY3VsZXMgYm91bmNlIGFnYWluc3QgZWFjaCBvdGhlciBpbiBhIHdheSB0aGF0IHNvbWVob3cgY29tZm9ydHMgeW91LCBtYWtlcyB5b3UgY3J5LCBvciBtYWtlcyB5b3UgZGFuY2UgYWxsIG5pZ2h0OiBtdXNpYy4gU2luY2UgdGhlIGFkdmVudCBvZiByZWNvcmRlZCBhdWRpbywgYSBtdXNpY2lhbiBkb2Vzbid0IGV2ZW4gbmVlZCB0byBiZSBwcmVzZW50IGFueW1vcmUgZm9yIHRoaXMgdG8gaGFwcGVuICh3aGljaCBtYWtlcyBwdXR0aW5nIFwiSSB3aWxsIGFsd2F5cyBsb3ZlIHlvdVwiIG9uIHJlcGVhdCBhIGxpdHRsZSBsZXNzIGF3a3dhcmQpLiBNdXNpY2lhbnMgYW5kIHNvdW5kIGVuZ2luZWVycyBoYXZlIGZvdW5kIG1hbnkgd2F5cyBvZiBjcmVhdGluZyBtdXNpYywgYW5kIG1ha2luZyBpdCBzb3VuZCBnb29kLiBTb21lIG9mIHRoZWlyIG1ldGhvZHMgaGF2ZSBiZWNvbWUgaW5kdXN0cnkgc3RhcGxlcyB1c2VkIG9uIGV2ZXJ5IHJlY29yZGluZyByZWxlYXNlZCB0b2RheS4gTGV0J3MgbG9vayBhdCB3aGF0IHRoZXkgZG8gYW5kIHJlcHJvZHVjZSBzb21lIG9mIHRoZWlyIG1ldGhvZHMgaW4gUnVieSEiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9SQXREUEZzazNoYy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JBdERQRnNrM2hjL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JBdERQRnNrM2hjL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9SQXREUEZzazNoYy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JBdERQRnNrM2hjL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDM4LAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJSQXREUEZzazNoYyIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiUkF0RFBGc2szaGMiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MTdaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIjhpN2ZzOHdVMTlaUVNkMENlYXJoY18zUmFJMCIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NUdORGcxTmpjMVF6WkVSamxGUmpFNSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDE5OjIyOjU0WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJ1YnlDb25mIDIwMjI6IFRoZSBNYWduaXR1ZGUgOS4xIE1lbHRkb3duIGF0IEZ1a3VzaGltYSBieSBOaWNrb2xhcyBNZWFucyIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkl0IHdhcyBtaWQtYWZ0ZXJub29uIG9uIEZyaWRheSwgTWFyY2ggMTEsIDIwMTEgd2hlbiB0aGUgZ3JvdW5kIGluIFTFjWhva3UgYmVnYW4gdG8gc2hha2UuIEF0IEZ1a3VzaGltYSBEYWlpY2hpIG51Y2xlYXIgcG93ZXIgcGxhbnQsIGl0IHNlZW1lZCBsaWtlIHRoZSBzaGFraW5nIHdvdWxkIG5ldmVyIHN0b3AuIE9uY2UgaXQgZGlkLCB0aGUgcmVhY3RvcnMgaGFkIGF1dG9tYXRpY2FsbHkgc2h1dCBkb3duLCBiYWNrdXAgcG93ZXIgaGFkIGNvbWUgb25saW5lLCBhbmQgdGhlIG9wZXJhdG9ycyB3ZXJlIHdlbGwgb24gdGhlaXIgd2F5IHRvIGhhdmluZyBldmVyeXRoaW5nIHVuZGVyIGNvbnRyb2wuIEFuZCB0aGVuIHRoZSB0c3VuYW1pIHN0cnVjay4gVGhleSBmb3VuZCB0aGVtc2VsdmVzIGZhY2luZyBzb21ldGhpbmcgYmV5b25kIGFueSB3b3JzZS1jYXNlIHNjZW5hcmlvIHRoZXkgaW1hZ2luZWQsIGFuZCB0aGVpciByZXNwb25zZSBpcyBhIHN0dWR5IGluIGNvbnRyYXN0cy4gV2UgY2FuIGxlYXJuIGEgbG90IGZyb20gdGhlIGV4dHJlbWVzIHRoZXkgZXhwZXJpZW5jZWQgYWJvdXQgZmluZGluZyBoYXBwaW5lc3MgYW5kIHNhdGlzZmFjdGlvbiBhdCB3b3JrLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JHUzBqQk1uaWFnL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUkdTMGpCTW5pYWcvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUkdTMGpCTW5pYWcvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JHUzBqQk1uaWFnL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUkdTMGpCTW5pYWcvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogMzksCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIlJHUzBqQk1uaWFnIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJSR1MwakJNbmlhZyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDoxM1oiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiT0RNQVdlNldZMnhIU1pSMFVJR1BvaEtiZ1JRIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0elF6RkJOMFJHTnpORlJFRkNNakJFIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMTk6MjI6NTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IERvbid0IEAgbWUhIEZhc3RlciBJbnN0YW5jZSBWYXJpYWJsZXMgd2l0aCBPYmplY3QgU2hhcGVzIGJ5IEFhcm9uIFBhdHRlcnNvbiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkluc3RhbmNlIHZhcmlhYmxlcyBhcmUgYSBwb3B1bGFyIGZlYXR1cmUgb2YgdGhlIFJ1YnkgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UsIGFuZCBtYW55IHBlb3BsZSBlbmpveSB1c2luZyB0aGVtLiBUaGV5IGFyZSBzbyBwb3B1bGFyIHRoYXQgdGhlIFJ1YnkgY29yZSB0ZWFtIGhhcyBkb25lIGxvdHMgb2Ygd29yayB0byBzcGVlZCB0aGVtIHVwLiBCdXQgd2UgY2FuIGRvIGV2ZW4gYmV0dGVyIHRvIHNwZWVkIHRoZW0gdXAgYnkgdXNpbmcgYSB0ZWNobmlxdWUgY2FsbGVkIFwiT2JqZWN0IFNoYXBlc1wiLiBJbiB0aGlzIHByZXNlbnRhdGlvbiB3ZSdsbCBsZWFybiBhYm91dCB3aGF0IG9iamVjdCBzaGFwZXMgYXJlLCBob3cgdGhleSBhcmUgaW1wbGVtZW50ZWQsIGhvdyBob3cgdGhleSBjYW4gYmUgdXNlZCB0byBzcGVlZCB1cCBnZXR0aW5nIGFuZCBzZXR0aW5nIGluc3RhbmNlIHZhcmlhYmxlcy4gV2UnbGwgbWFrZSBzdXJlIHRvIHNxdWFyZSB1cCBSdWJ5IGluc3RhbmNlIHZhcmlhYmxlIGltcGxlbWVudGF0aW9uIGRldGFpbHMgc28gdGhhdCB5b3UgY2FuIGJlY29tZSBhIG1vcmUgd2VsbCByb3VuZGVkIGRldmVsb3BlciEiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9aYUhkNU1ESlJCdy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1phSGQ1TURKUkJ3L21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1phSGQ1TURKUkJ3L2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9aYUhkNU1ESlJCdy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1phSGQ1TURKUkJ3L21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDQwLAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJaYUhkNU1ESlJCdyIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiWmFIZDVNREpSQnciLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MjBaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogInV1ZFA0OTQ4MnpoVjVRZmMxT09FNHgyOFVRdyIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NDVOa1ZFTlRreFJEZENRVUZCTURZNCIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDE5OjIyOjU0WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBzY2lwLXJ1YnkgLSBBIFJ1YnkgaW5kZXhlciBidWlsdCB3aXRoIFNvcmJldCBieSBWYXJ1biBHYW5kaGkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJzY2lwLXJ1YnkgaXMgYW4gb3BlbiBzb3VyY2UgaW5kZXhlciB0aGF0IGxldHMgeW91IGJyb3dzZSBSdWJ5IGNvZGUgb25saW5lLCB3aXRoIElERSBmdW5jdGlvbmFsaXR5IGxpa2Ug4oCcR28gdG8gZGVmaW5pdGlvbuKAnSBhbmQg4oCcRmluZCB1c2FnZXPigJ0uIFdlIG9yaWdpbmFsbHkgYnVpbHQgc2NpcC1ydWJ5IHRvIGltcHJvdmUgUnVieSBzdXBwb3J0IGluIFNvdXJjZWdyYXBoLCBhIGNvZGUgaW50ZWxsaWdlbmNlIHBsYXRmb3JtLiBJbiB0aGlzIHRhbGssIHlvdSB3aWxsIGxlYXJuIGhvdyB3ZSBidWlsdCBzY2lwLXJ1Ynkgb24gdG9wIG9mIFNvcmJldCwgYSBSdWJ5IHR5cGVjaGVja2VyLCBhbmQgaG93IHNjaXAtcnVieSBjb21wYXJlcyB0byBJREVzIGFuZCBvdGhlciBvbmxpbmUgY29kZSBuYXZpZ2F0aW9uIHRvb2xzLiBBbG9uZyB0aGUgd2F5LCB3ZSB3aWxsIGRpc2N1c3MgaG93IHF1aW50ZXNzZW50aWFsIGlkZWFzIGxpa2UgbGF5ZXJpbmcgY29kZSBpbnRvIGEgZnVuY3Rpb25hbCBjb3JlIGFuZCBhbiBpbXBlcmF0aXZlIHNoZWxsIGFwcGx5IHRvIGRldmVsb3BlciB0b29scywgYW5kIGVuYWJsZSBlYXNpZXIgdGVzdGluZy4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9jZmNlVkhfMUgzUS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2NmY2VWSF8xSDNRL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2NmY2VWSF8xSDNRL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9jZmNlVkhfMUgzUS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2NmY2VWSF8xSDNRL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDQxLAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJjZmNlVkhfMUgzUSIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiY2ZjZVZIXzFIM1EiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MTlaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogImROOGVjUTlqVXRXbFNiSV83NzJNNnRHaWxoSSIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NUROa013UlVJMk1rSTRRa0k0TkRGRyIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDE5OjIyOjU0WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBCdWlsZGluZyBhbiBlZHVjYXRpb24gc2F2aW5ncyBwbGF0Zm9ybSwgd2l0aCBSdWJ5ISBieSBUeWxlciBBY2tlcm1hbiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIldlYWx0aHNpbXBsZSBGb3VuZGF0aW9uIGlzIGEgQ2FuYWRpYW4gY2hhcml0eSB3b3JraW5nIHRvIGVuYWJsZSBhIGJyaWdodGVyIGZ1dHVyZSBmb3IgZXZlcnlvbmUgaW4gQ2FuYWRhIHRocm91Z2ggYWNjZXNzIHRvIHBvc3Qtc2Vjb25kYXJ5IGVkdWNhdGlvbi4gVGhlIEZvdW5kYXRpb24gaXMgc3VwcG9ydGVkIGJ5IFdlYWx0aHNpbXBsZSwgd2hpY2ggYnVpbGRzIGEgdmFyaWV0eSBvZiBkaWdpdGFsIGZpbmFuY2lhbCB0b29scyB0cnVzdGVkIGJ5IG92ZXIgMi41IG1pbGxpb24gQ2FuYWRpYW5zLiBJbiB0aGlzIHRhbGsgd2UnbGwgZ28gb3ZlcjogLSBIb3cgYW4gb3JnYW5pemF0aW9uIHN1cHBvcnRpbmcgZm9yLXByb2ZpdCBhbmQgbm9uLXByb2ZpdCBhY3Rpdml0aWVzIGlzIHN0cnVjdHVyZWQgKGFuZCB0aGUgZXRoaWNhbCBjb25zaWRlcmF0aW9ucyB0aGF0IGNhbiBhcmlzZSBmcm9tIHRoYXQpIC0gUmVzcG9uc2liaWxpdGllcyBvZiBlbmdpbmVlcnMgd29ya2luZyBpbiBhIG5vbi1wcm9maXQgc3BhY2UgLSBPcHBvcnR1bml0aWVzIGFuZCBjaGFsbGVuZ2VzIG9mIGRpZ2l0YWwgcHJvZHVjdHMgYWRkcmVzc2luZyBzeXN0ZW1hdGljIGluZXF1YWxpdGllcyIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2NtWkt1LWt5eWlvL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvY21aS3Uta3l5aW8vbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvY21aS3Uta3l5aW8vaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2NtWkt1LWt5eWlvL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvY21aS3Uta3l5aW8vbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNDIsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogImNtWkt1LWt5eWlvIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJjbVpLdS1reXlpbyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDozMVoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiOVFYZTdoMzVUZkFSc2Q2a0owUF9aeWJreDQ4IiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk1RFJVUXdPRE14UXpVeVJUbEdSa1kzIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMTk6MjI6NTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IFN0YXRpYyB0eXBpbmcgd2l0aCBSQlMgaW4gUnVieSBieSBHYXVyYXYgS3VtYXIgU2luZ2giLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJJbiB0aGlzIHRhbGssIHdlJ2xsIGdlbmVyYWxseSBleHBsb3JlIHRoZSBzdGF0aWMgdHlwZSBlY28gc3lzdGVtIGluIFJ1YnkuIFJ1YnkgaGFzIHR3byBtYWluIHR5cGUgY2hlY2tlcnMgU29yYmV0IGFuZCBSQlMuIFNvcmJldCB3YXMgY3JlYXRlZCBieSB0aGUgU3RyaXBlIGFuZCBSQlMgaXMgc3VwcG9ydGVkIGJ5IHJ1YnkuIFNvcmJldCBpcyBhbiBhbm5vdGF0aW9uIGJhc2UgdHlwZSBjaGVja2luZyBzeXN0ZW0gd2hpbGUgUkJTIGlzIGEgZGVmaW5pdGlvbiBmaWxlLWJhc2VkIHR5cGUgc3lzdGVtLiBXZSdsbCBhZGQgdHlwZSBhbm5vdGF0aW9uIGZvciBhIHBvcHVsYXIgZ2VtIHVzaW5nIHNvcmJldCBhbmQgUkJTIGFuZCB0aGVuIGNvbXBhcmUgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gdGhlIHR3byBzeXN0ZW1zLiBUaGVyZSBpcyBsb3Qgb2YgaW50ZXJvcGVyYWJpbGl0eSBhbm5vdW5jZWQgYmV0d2VlbiBTb3JiZXQgYW5kIFJCUyBhbmQgd2UnbGwgZXhwbG9yZSBpZiBpdCdzIHByYWN0aWNhbGx5IHBvc3NpYmxlIHRvIGNvbnZlcnQgYSBzb3JiZXQgYW5ub3RhdGVkIHByb2plY3QgdG8gUkJTLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2lLSmVLeGYzTmNrL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvaUtKZUt4ZjNOY2svbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvaUtKZUt4ZjNOY2svaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2lLSmVLeGYzTmNrL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvaUtKZUt4ZjNOY2svbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNDMsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogImlLSmVLeGYzTmNrIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJpS0plS3hmM05jayIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDozMVoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiQUdiMHBSNzJUTzQ3Tk1qOGI2VjhpWXJoUnNFIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0MU16WTRNemN3T1VGRlJVVTNRekV4IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMTk6MjI6NTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IEhlbHBpbmcgUmVkaXN0cmljdCBDYWxpZm9ybmlhIHdpdGggUnVieSBieSBKZXJlbXkgRXZhbnMiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJFdmVyeSAxMCB5ZWFycywgYWZ0ZXIgdGhlIGZlZGVyYWwgY2Vuc3VzLCBDYWxpZm9ybmlhIGFuZCBtb3N0IG90aGVyIHN0YXRlcyByZWRyYXcgdGhlIGxpbmVzIG9mIHZhcmlvdXMgZWxlY3RvcmFsIGRpc3RyaWN0cyB0byBhdHRlbXB0IHRvIGVuc3VyZSB0aGUgZGlzdHJpY3RzIGFyZSBmYWlyIGFuZCBoYXZlIHJvdWdobHkgZXF1YWwgcG9wdWxhdGlvbi4gQ2FsaWZvcm5pYSB1c2VzIGEgc3lzdGVtIHdyaXR0ZW4gaW4gUnVieSBmb3IgY2l0aXplbnMgdG8gYXBwbHkgdG8gYmVjb21lIHJlZGlzdHJpY3RpbmcgY29tbWlzc2lvbmVycywgYW5kIGZvciByZXZpZXcgb2YgdGhlIHN1Ym1pdHRlZCBhcHBsaWNhdGlvbnMuIENvbWUgbGVhcm4gYWJvdXQgcmVkaXN0cmljdGluZyBhbmQgdGhlIHVuaXF1ZSBkZXNpZ24gb2YgdGhlIENhbGlmb3JuaWEgcmVkaXN0cmljdGluZyBjb21taXNzaW9uZXIgYXBwbGljYXRpb24gc3lzdGVtLCB3aXRoIDEyIHNlcGFyYXRlIHdlYiBzZXJ2ZXIgcHJvY2VzcyB0eXBlcywgaXNvbGF0ZWQgbmV0d29ya3MsIDMtZmFjdG9yIGF1dGhlbnRpY2F0aW9uLCBhbmQgb3RoZXIgc2VjdXJpdHkgZmVhdHVyZXMuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvcTVua2U1OUl1QXMvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xNW5rZTU5SXVBcy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xNW5rZTU5SXVBcy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvcTVua2U1OUl1QXMvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xNW5rZTU5SXVBcy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA0NCwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAicTVua2U1OUl1QXMiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogInE1bmtlNTlJdUFzIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjI2WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJoZjl4SjZlT000eGlYWnB1T1pFc0ppNEg3QmsiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTR5UVVKRk5VVkNNelZETmpjeFJUbEYiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQxOToyMjo1NFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogU29saWRhcml0eSBub3QgQ2hhcml0eSBhbmQgQ29sbGVjdGl2ZSBMaWJlcmF0aW9uIGJ5IE1hZSBCZWFsZSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIldvbmRlcmluZyBob3cgdG8gZ2V0IGludm9sdmVkIGluIHN1cHBvcnRpbmcgeW91ciBjb21tdW5pdGllcz8gSGVhciBmcm9tIHNvbWVvbmUgd2hvIGhhcyBzcHVuIHVwIChhbmQgZG93bikgbXVsdGlwbGUgdm9sdW50ZWVyIGFuZCBzZXJ2aWNlIHByb2plY3RzLiBNYXkgaXQgc3BhcmsgeW91ciBpbWFnaW5hdGlvbiAtLSBhbmQgeW91ciBoZWFydCAtLSB0byBqb2luIG9yIHN0YXJ0IGhlbHBpbmcgb3V0IGJvdGggdGhpcyB3aWxkIHdvcmxkIGFuZCB5b3Vyc2VsZi4gTmV3IG11dHVhbCBhaWQgZ3JvdXBzIGZvcm1lZCBhcm91bmQgdGhlIHdvcmxkIGluIDIwMjAuIFRoZSB0b29scyB3ZXJlIG5vdCBpZGVhbCBhbmQgdGhlIHZvbHVtZSBvdmVyd2hlbG1lZCB2b2x1bnRlZXJzLiBBIGhhbmRmdWwgb2Ygb2YgdGVjaCBmb2x4IGJ1aWx0IGEgZml0LXRvLXN1aXQgYXBwIHRvIG1hbmFnZSBpbW1lZGlhdGUgbmVlZHMgYW5kIG1heGltaXplIGltcGFjdCBvZiBwYXJ0bmVyIG11dHVhbCBhaWQgZ3JvdXBzLiBXaW5zIHdlcmUgYWNoaWV2ZWQuIExlc3NvbnMgd2VyZSBsZWFybmVkLiBBbmQgdGhlIGludGVyY29ubmVjdGVkbmVzcyBvZiBhbGwgdGhpbmdzIHdhcyBmZWx0LiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3NhUFowSmgzVVUwL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvc2FQWjBKaDNVVTAvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvc2FQWjBKaDNVVTAvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3NhUFowSmgzVVUwL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvc2FQWjBKaDNVVTAvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNDUsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogInNhUFowSmgzVVUwIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJzYVBaMEpoM1VVMCIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDozNFoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiaGJicGxMY09xR0laWXpDLW9hbV9Jb2oxejZnIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0MFF6UkRPRVUwUVVZd05VSXhOME0xIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMTk6MjI6NTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IFdoYXQgZG9lcyBcImhpZ2ggcHJpb3JpdHlcIiBtZWFuPyBUaGUgc2VjcmV0IHRvIGhhcHB5IHF1ZXVlcyBieSBEYW5pZWwgTWFnbGlvbGEiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJMaWtlIG1vc3Qgd2ViIGFwcGxpY2F0aW9ucywgeW91IHJ1biBpbXBvcnRhbnQgam9icyBpbiB0aGUgYmFja2dyb3VuZC4gQW5kIHRvZGF5LCBzb21lIG9mIHlvdXIgdXJnZW50IGpvYnMgYXJlIHJ1bm5pbmcgbGF0ZS4gQWdhaW4uIE5vIG1hdHRlciBob3cgbWFueSBjaGFuZ2VzIHlvdSBtYWtlIHRvIGhvdyB5b3UgZW5xdWV1ZSBhbmQgcnVuIHlvdXIgam9icywgdGhlIHByb2JsZW0ga2VlcHMgaGFwcGVuaW5nLiBUaGUgZ29vZCBuZXdzIGlzIHlvdSdyZSBub3QgYWxvbmUuIE1vc3QgdGVhbXMgc3RydWdnbGUgd2l0aCB0aGlzIHByb2JsZW0sIHRyeSBtb3JlIG9yIGxlc3MgdGhlIHNhbWUgc29sdXRpb25zLCBhbmQgaGF2ZSByb3VnaGx5IHRoZSBzYW1lIHJlc3VsdC4gSW4gdGhlIGVuZCwgaXQgYWxsIGJvaWxzIGRvd24gdG8gb25lIHRoaW5nOiBrZWVwaW5nIGxhdGVuY3kgbG93LiBJbiB0aGlzIHRhbGsgSSB3aWxsIHByZXNlbnQgYSBsYXRlbmN5LWZvY3VzZWQgYXBwcm9hY2ggdG8gbWFuYWdpbmcgeW91ciBxdWV1ZXMgcmVsaWFibHksIGtlZXBpbmcgeW91ciBqb2JzIGZsb3dpbmcgYW5kIHlvdXIgdXNlcnMgaGFwcHkuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdzBCbC01VERDQzQvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93MEJsLTVURENDNC9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93MEJsLTVURENDNC9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdzBCbC01VERDQzQvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93MEJsLTVURENDNC9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA0NiwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAidzBCbC01VERDQzQiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIncwQmwtNVREQ0M0IiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjM0WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJSM0UyWkoybUh3eUVzekRrVEV5RzczQkFia3ciLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQxUlROQlJFWXdNa0k1UXpVM1JrWTIiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDoxMTo1MFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogUlNwZWM6IFRoZSBCYWQgUGFydHMgYnkgQ2FsZWIgSGVhcnRoIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiUlNwZWMgaXMgZ29vZCwgYnV0IGl04oCZcyBldmVuIGJldHRlciB3aXRoIGxlc3Mgb2YgaXQuIExvb2tpbmcgYXQgYSByZWFsaXN0aWMgZXhhbXBsZSBzcGVjLCB3ZeKAmWxsIGxlYXJuIHdoeSBwYXJ0cyBvZiBSU3BlYyBsaWtlIGxldCwgc3ViamVjdCwgc2hhcmVkX2V4YW1wbGVzLCBiZWhhdmVzIGxpa2UsIGFuZCBiZWZvcmUgY2FuIG1ha2UgeW91ciB0ZXN0cyBoYXJkIHRvIHJlYWQsIGRpZmZpY3VsdCB0byBuYXZpZ2F0ZSwgYW5kIG1vcmUgY29tcGxleC4gV2UnbGwgZGlzY3VzcyB3aGVuIERSWSBpcyBub3Qgd29ydGggdGhlIHByaWNlIGFuZCBob3cgd2UgY2FuIGF2b2lkIHJlcGV0aXRpb24gd2l0aG91dCB1c2luZyBSU3BlYydzIGJ1aWx0LWluIERTTCBtZXRob2RzLiBJbiB0aGUgZW5kLCB3ZSdsbCBsb29rIGF0IHdoYXQncyBsZWZ0LiBSU3BlYzogVGhlIEdvb2QgUGFydHMuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvX1VGRTB0MlNnYXcvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9fVUZFMHQyU2dhdy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9fVUZFMHQyU2dhdy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvX1VGRTB0MlNnYXcvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9fVUZFMHQyU2dhdy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA0NywKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiX1VGRTB0MlNnYXciCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIl9VRkUwdDJTZ2F3IiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjI2WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJIWkhHVXA1anVmNVFPbENBVGNrUUQ3Q2FveXciLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTVFTmpJMVFVSTBNREk1TkVRek9ERkUiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDoxMzowOVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogRGF0YSBpbmRleGluZyB3aXRoIFJHQiAoUnVieSwgR3JhcGhzIGFuZCBCaXRtYXBzKSBieSBCZW5qYW1pbiBMZXdpcyIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkluIHRoaXMgdGFsaywgd2Ugd2lsbCBnbyBvbiBhIGpvdXJuZXkgdGhyb3VnaCBaYXBwaeKAmXMgZGF0YSBoaXN0b3J5IGFuZCBob3cgd2UgYXJlIHVzaW5nIFJ1YnksIGEgZ3JhcGggZGF0YWJhc2UsIGFuZCBhIGJpdG1hcCBzdG9yZSB0byBidWlsZCBhIHVuaXF1ZSBkYXRhIGVuZ2luZS4gQSBqb3VybmV5IHRoYXQgc3RhcnRzIHdpdGggdGhlIHByb2JsZW0gb2YgYSBkaXNjb25uZWN0ZWQgZGF0YSBzZXQgYW5kIHNlcmlhbGlzZWQgZGF0YSBmcmFtZXMsIGFuZCBlbmRzIHdpdGggdGhlIHNvbHV0aW9uIG9mIGFuIGluLW1lbW9yeSBpbmRleC4gV2Ugd2lsbCBleHBsb3JlIGhvdyB3ZSB1c2VkIFJlZGlzR3JhcGggdG8gbW9kZWwgdGhlIHJlbGF0aW9uc2hpcHMgaW4gb3VyIGRhdGEsIGNvbm5lY3Rpbmcgc2VtYW50aWNhbGx5IGVxdWFsIG5vZGVzLiBUaGVuIGRlbHZlIGludG8gaG93IGEgcXVlcnkgbGF5ZXIgd2FzIHVzZWQgdG8gaW5kZXggYSBiaXRtYXAgc3RvcmUgYW5kLCBpbiB0dXJuLCBsZWQgdG8gdXMgYmVpbmcgYWJsZSB0byBpbnRlcnJvZ2F0ZSBvdXIgZW50aXJlIGRhdGFzZXQgb3JkZXJzIG9mIG1hZ25pdHVkZSBmYXN0ZXIgdGhhbiBiZWZvcmUuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRndCUm94ckhhQlUvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Gd0JSb3hySGFCVS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Gd0JSb3hySGFCVS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRndCUm94ckhhQlUvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Gd0JSb3hySGFCVS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA0OCwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiRndCUm94ckhhQlUiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIkZ3QlJveHJIYUJVIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjE3WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJNaFhwUlNOZWpZbk5SaW91V21LN09pQ2RpSjQiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQ0UXpWR1FVVTJRakUyTkRneE0wTTQiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDoxNDoxNFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogQmVuZGluZyBUaW1lIHdpdGggQ3J5c3RhbDogNiBob3VycyB0byAxNSBtaW51dGVzIGJ5IFBhdWwgSG9mZmVyIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiSW4gc29mdHdhcmUsIHdlIG9mdGVuIGVuY291bnRlciBwcm9ibGVtcyB0aGF0IHdlIGFjY2VwdCBhcyBcImp1c3QgaG93IHRoaW5ncyBhcmUuXCIgQnV0IHNvbWV0aW1lcywgdGhhdCBjcmVhdGVzIG9wcG9ydHVuaXRpZXMgdG8gaWRlbnRpZnkgY3JlYXRpdmUsIG91dCBvZiB0aGUgYm94IHNvbHV0aW9ucy4gT25lIGlkZWEgY2FuIGJlIGNvbWJpbmluZyB0aGUgcG93ZXIgb2YgQ3J5c3RhbCB3aXRoIG91ciBleGlzdGluZyBSdWJ5IGtub3dsZWRnZSwgdG8gY3JlYXRlIGVmZmVjdGl2ZSB0b29scyB3aXRoIG1pbmltYWwgbGVhcm5pbmcgY3VydmUgYW5kIGNvZ25pdGl2ZSBvdmVyaGVhZC4gSSdsbCBkZW1vbnN0cmF0ZSBob3cgZWFzaWx5IFJ1YnkgY29kZSBjYW4gYmUgcG9ydGVkIHRvIENyeXN0YWwsIGhvdyBpdCBjYW4gYmVuZWZpdCB1cywgYW5kIGhvdyB0byBpZGVudGlmeSB0aGVzZSBvcHBvcnR1bml0aWVzLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzZNcFhTcmdCVnd3L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvNk1wWFNyZ0JWd3cvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvNk1wWFNyZ0JWd3cvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzZNcFhTcmdCVnd3L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvNk1wWFNyZ0JWd3cvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNDksCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIjZNcFhTcmdCVnd3IgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICI2TXBYU3JnQlZ3dyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDowNloiCiAgICAgIH0KICAgIH0KICBdLAogICJwYWdlSW5mbyI6IHsKICAgICJ0b3RhbFJlc3VsdHMiOiA3OSwKICAgICJyZXN1bHRzUGVyUGFnZSI6IDUwCiAgfQp9Cg==\n  recorded_at: Tue, 06 Jun 2023 08:23:15 GMT\n- request:\n    method: get\n    uri: https://youtube.googleapis.com/youtube/v3/playlistItems?key=REDACTED_YOUTUBE_API_KEY&maxResults=50&pageToken=EAAaBlBUOkNESQ&part=snippet,contentDetails&playlistId=PLE7tQUdRKcyZYz0O3d9ZDdo0-BkOWhrSk\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Tue, 06 Jun 2023 08:23:15 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      Cache-Control:\n      - private\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: !binary |-\n        ewogICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtTGlzdFJlc3BvbnNlIiwKICAiZXRhZyI6ICI0TjdvLTBFOWZhaEVRWmhjdEt1TnpORTYwUGciLAogICJwcmV2UGFnZVRva2VuIjogIkVBRWFCbEJVT2tORVNRIiwKICAiaXRlbXMiOiBbCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAick16MWpRanIwSi1obVk3bFJOb0tTb1JvQTVJIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0eE16Z3dNekJFUmpRNE5qRXpOVUU1IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMjA6MTY6MDJaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IFNwbGl0dGluZzogdGhlIENydWNpYWwgT3B0aW1pemF0aW9uIGZvciBSdWJ5IEJsb2NrcyBieSBCZW5vaXQgRGFsb3plIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiQmxvY2tzIGFyZSBvbmUgb2YgdGhlIG1vc3QgZXhwcmVzc2l2ZSBwYXJ0cyBvZiB0aGUgUnVieSBzeW50YXguIE1hbnkgUnVieSBtZXRob2RzIHRha2UgYSBibG9jay4gV2hlbiBhIG1ldGhvZCBpcyBnaXZlbiBkaWZmZXJlbnQgYmxvY2tzLCB0aGVyZSBpcyBhIGNydWNpYWwgb3B0aW1pemF0aW9uIG5lY2Vzc2FyeSB0byB1bmxvY2sgdGhlIGJlc3QgcGVyZm9ybWFuY2UuIFRoaXMgb3B0aW1pemF0aW9uIGRhdGVzIGJhY2sgdG8gdGhlIGVhcmx5IGRheXMgb2YgcmVzZWFyY2ggb24gZHluYW1pYyBsYW5ndWFnZXMsIHlldCBpdCBzZWVtcyBvbmx5IGEgc2luZ2xlIFJ1YnkgaW1wbGVtZW50YXRpb24gY3VycmVudGx5IHVzZXMgaXQuIFRoaXMgb3B0aW1pemF0aW9uIGlzIGNhbGxlZCBzcGxpdHRpbmcgYW5kIHdoYXQgaXQgZG9lcyBpcyB1c2luZyBkaWZmZXJlbnQgY29waWVzIG9mIGEgbWV0aG9kIGFuZCBzcGVjaWFsaXplIHRoZW0gdG8gdGhlIGJsb2NrIGdpdmVuIGF0IGRpZmZlcmVudCBjYWxsIHNpdGVzLiBUaGlzIGVuYWJsZXMgY29tcGlsaW5nIHRoZSBtZXRob2QgYW5kIHRoZSBibG9jayB0b2dldGhlciBmb3IgdGhlIGJlc3QgcGVyZm9ybWFuY2UuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUGpVcGNSNVVQSEkvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9QalVwY1I1VVBISS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9QalVwY1I1VVBISS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUGpVcGNSNVVQSEkvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9QalVwY1I1VVBISS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA1MCwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiUGpVcGNSNVVQSEkiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIlBqVXBjUjVVUEhJIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjIzWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJwMTMxSzhzVWxDUUFoUTBIZGpETE1CenpXY1kiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTR6TUVRMU1FSXlSVEZHTnpoRFF6RkIiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDoxNzo0MVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogQnVpbGRpbmcgU3RyZWFtIFByb2Nlc3NpbmcgQXBwbGljYXRpb25zIHdpdGggUnVieSAmIE1lcm94YSBieSBBbGkgSGFtaWRpIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiQXMgdGhlIHdvcmxkIG1vdmVzIHRvd2FyZHMgcmVhbC10aW1lIHRoZXJl4oCZcyBhIGdyb3dpbmcgZGVtYW5kIGZvciBidWlsZGluZyBzb3BoaXN0aWNhdGVkIHN0cmVhbSBwcm9jZXNzaW5nIGFwcGxpY2F0aW9ucy4gVHJhZGl0aW9uYWxseSBidWlsZGluZyB0aGVzZSBhcHBzIGhhcyBpbnZvbHZlZCBzcGlubmluZyB1cCBzZXBhcmF0ZSB0YXNrLXNwZWNpZmljIHRvb2xpbmcsIGxlYXJuaW5nIG5ldyBhbmQgdW5mYW1pbGlhciBwYXJhZGlnbXMsIGFzIHdlbGwgYXMgZGVwbG95aW5nIGFuZCBvcGVyYXRpbmcgYSBjb25zdGVsbGF0aW9uIG9mIGNvbXBsZXggc2VydmljZXMuIEluIHRoaXMgdGFsaywgd2XigJlsbCB0YWtlIGEgbG9vayBhdCBob3cgdG8gdXNlIHRoZSBUdXJiaW5lIGZyYW1ld29yayAodHVyYmluZS5yYikgdG8gYnVpbGQgYW5kIGRlcGxveSByZWFsLXRpbWUgc3RyZWFtIHByb2Nlc3NpbmcgYXBwbGljYXRpb25zIHVzaW5nIFJ1YnkuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvNmJIWlF5MFRpX2MvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS82YkhaUXkwVGlfYy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS82YkhaUXkwVGlfYy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvNmJIWlF5MFRpX2Mvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS82YkhaUXkwVGlfYy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA1MSwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiNmJIWlF5MFRpX2MiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIjZiSFpReTBUaV9jIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjA2WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJqbXRxZWFRMTJDcnJfTy0tcHFONk53R244bk0iLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQyUXprNU1rRXpRalZGUWpZd1JEQTQiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDoyMjo1NloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogQm9vdCB0aGUgYmFja2xvZzogT3B0aW1pemluZyB5b3VyIHdvcmtmbG93IGZvciBkZXYgaGFwcGluZXNzIGJ5IFN0YWNleSBNY0tuaWdodCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIldoYXQgd291bGQgaGFwcGVuIGlmIHlvdXIgdGVhbSBkcm9wcGVkIHRoYXQgc3RhbmRpbmcgTW9uZGF5IG1vcm5pbmcgcmVmaW5lbWVudCBtZWV0aW5nPyBDaGFvcz8gV2Ugb2Z0ZW4gZm9sbG93IHdvcmsgcHJvY2Vzc2VzIGJlY2F1c2UgdGhleeKAmXJlIOKAnHRoZSB3YXkgdGhpbmdzIGFyZSBkb25l4oCdLCBidXQgY2x1bmt5LCB1bmV4YW1pbmVkIHByb2Nlc3NlcyBzbG93IGRvd24gZXZlbiB0YWxlbnRlZCB0ZWFtcy4gTmV2ZXIgZW5kaW5nIGJhY2tsb2dzIG1ha2UgaXQgaGFyZCB0byBmZWVsIGxpa2UgeW914oCZcmUgbWFraW5nIHByb2dyZXNzLiBGcmVxdWVudCBtZWV0aW5ncyBicmVhayB1cCBmb2N1cy4gSWYgc29tZXRoaW5nIGFib3V0IHRoZSB3YXkgd2Ugd29yayBkb2VzbuKAmXQgaGVscCB1cyBtb3ZlIG1vcmUgcXVpY2tseSBvciBlZmZlY3RpdmVseSwgaXTigJlzIHRpbWUgdG8gcmV0aGluayBpdC4gU2Vla2luZyBhIGJldHRlciB3YXkgdG8gY29vcmRpbmF0ZSB3b3JrIGFjcm9zcyAzIGNvbnRpbmVudHMsIHRoZSBXb3JrZm9yY2UuY29tIGRldiB0ZWFtIGFkb3B0ZWQgdGhlIFNoYXBlIFVwIGFwcHJvYWNoIHRvIHByb2plY3QgbWFuYWdlbWVudC4gVGhpcyB0YWxrIGV4cGxvcmVzIHRoZSBjb3JlIGVsZW1lbnRzIG9mIHRoYXQgYXBwcm9hY2ggYW5kIHdheXMgdG8gb3B0aW1pemUgZGV2ZWxvcGVyIGhhcHBpbmVzcyB3aGlsZSBkZWxpdmVyaW5nIG1vcmUgdmFsdWUgZm9yIHVzZXJzLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0JCX0dqVUlBMDZjL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvQkJfR2pVSUEwNmMvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvQkJfR2pVSUEwNmMvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0JCX0dqVUlBMDZjL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvQkJfR2pVSUEwNmMvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNTIsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIkJCX0dqVUlBMDZjIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJCQl9HalVJQTA2YyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDoxMVoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiY3RGdWhSNGEtbVZONF83TVQ2c2MxbHpIdDZVIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0MU5UWkVPVGhCTlRoRk9VVkdRa1ZCIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMjA6MjQ6MTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IEJ1c2luZXNzIGluIHRoZSBGcm9udCwgUGFydHkgaW4gdGhlIEJhY2sgKE9mZmljZSkgYnkgS2V2aW4gV2hpbm5lcnkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJJZiB5b3UgaGF2ZSBldmVyIGJ1aWx0IGEgd2ViIGFwcGxpY2F0aW9uLCBjaGFuY2VzIGFyZSB0aGF0IHlvdSBoYXZlIGFsc28gaGFkIHRvIGRlYWwgd2l0aCBcInRoZSBiYWNrIG9mZmljZVwiIC0gdGhlIGNob3JlcyBhbmQgb25lLW9mZiB0YXNrcyByZXF1aXJlZCB0byBvcGVyYXRlIHlvdXIgc29mdHdhcmUgaW4gcHJvZHVjdGlvbi4gV29ya2Zsb3dzIHRoYXQgYXJlbid0IHVzZXItZmFjaW5nLCBsaWtlIGNyZWF0aW5nIHByb21vIGNvZGVzLCBtb2RlcmF0aW5nIGNvbnRlbnQsIG9yIHJ1bm5pbmcgcmVwb3J0cywgYXJlIG9mdGVuIGEgamFua3kgY29tYmluYXRpb24gb2YgYWRtaW4gc2NyaXB0cyBhbmQgc3ByZWFkc2hlZXRzLiBSZXRvb2wgaGVscHMgZGV2ZWxvcGVycyBxdWlja2x5IGFuZCBlYXNpbHkgc29sdmUgdGhlc2UgcHJvYmxlbXMgd2l0aCBzb2Z0d2FyZSBpbnN0ZWFkLiBJbiB0aGlzIHNlc3Npb24sIHdlJ2xsIHNob3cgaG93IHRvIGJ1aWxkIGEgYmFjayBvZmZpY2UgaW50ZXJmYWNlIGZvciBhIFJ1Ynkgb24gUmFpbHMgYXBwbGljYXRpb24gdXNpbmcgUG9zdGdyZXMgYW5kIHNldmVyYWwgY29tbW9uIEFQSSBzZXJ2aWNlcywgc28geW91IGNhbiBrZWVwIHlvdXIgZm9jdXMgb24gdGhlIGJ1c2luZXNzIGluIHRoZSBmcm9udCwgYW5kIGxldCBSZXRvb2wgaGVscCB0aHJvdyB0aGUgcGFydHkgaW4gdGhlIGJhY2sgKG9mZmljZSkuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvR1NCaFZWV3ljdlUvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9HU0JoVlZXeWN2VS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9HU0JoVlZXeWN2VS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvR1NCaFZWV3ljdlUvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9HU0JoVlZXeWN2VS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA1MywKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiR1NCaFZWV3ljdlUiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIkdTQmhWVld5Y3ZVIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjA3WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJiNlVITm1qY0FrdWtSRkp2NzAxZkRNQzBWVDgiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQzTkVSQ01ESXpRekZCTUVSQ01FRTMiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDoyNjoxNFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogQW5hbHl6aW5nIGFuIGFuYWx5emVyIC0gQSBkaXZlIGludG8gaG93IFJ1Ym9Db3Agd29ya3MgYnkgS3lsZSBkJ09saXZlaXJhIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiVG8gaGVscCB1cyB3aXRoIGFzcGVjdHMgbGlrZSBsaW50aW5nLCBzZWN1cml0eSBvciBzdHlsZSwgbWFueSBvZiB1cyBoYXZlIFJ1Ym9jb3AgYW5hbHl6aW5nIG91ciBjb2RlLiBJdCdzIGEgdmVyeSB1c2VmdWwgdG9vbCB0aGF0IGlzIHdpZGVseSB1c2VkLCBlYXN5IHRvIHNldCB1cCBhbmQgY29uZmlndXJlLiBSdWJvY29wIGNhbiBldmVuIGF1dG9tYXRpY2FsbHkgYXV0by1jb3JyZWN0IHlvdXIgc291cmNlIGNvZGUgYXMgbmVlZGVkLiBIb3cgaXMgdGhpcyBldmVuIHBvc3NpYmxlPyBJdCB0dXJucyBvdXQgdGhhdCBSdWJ5IGlzIHJlYWxseSBnb29kIGF0IHRha2luZyBSdWJ5IGNvZGUgYXMgaW5wdXQgYW5kIGRvaW5nIHZhcmlvdXMgdGhpbmdzIGJhc2VkIG9uIHRoYXQgaW5wdXQuIEluIHRoaXMgdGFsaywgSSB3aWxsIGdvIHRocm91Z2ggc29tZSBvZiB0aGUgaW50ZXJuYWxzIG9mIFJ1Ym9jb3AgdG8gc2hvdyBob3cgaXQgYW5hbHl6ZXMgYW5kIG1ha2VzIGNoYW5nZXMgdG8geW91ciBzb3VyY2UgY29kZS4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wU0NNZ2N0dFc0Yy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3BTQ01nY3R0VzRjL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3BTQ01nY3R0VzRjL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wU0NNZ2N0dFc0Yy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3BTQ01nY3R0VzRjL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDU0LAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJwU0NNZ2N0dFc0YyIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAicFNDTWdjdHRXNGMiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MzRaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIm8yc29GVUxlMmdSR0FVMl9MNk5JTERMdEdCWSIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NUdOakF3TjBZMFFURkdPVFZETUVNeSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDIwOjI3OjM3WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBSdWJ5IEFyY2hhZW9sb2d5OiBGb3Jnb3R0ZW4gd2ViIGZyYW1ld29ya3MgYnkgTmljayBTY2h3YWRlcmVyIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiSW4gdGhlIDIwMDAncyBldmVyeW9uZSB3YXMgd3JpdGluZyBhIFJ1Ynkgd2ViIGZyYW1ld29yayAqKlRvZGF5LCBpdCBzZWVtcywgd2UgYXJlIGFsbCB0b28gY29udGVudCB0byBmb2N1cyBvdXIgZW5lcmd5IG9uIGEgc21hbGwgbnVtYmVyIG9mIGxhcmdlIFJ1Ynkgd2ViIHByb2plY3RzKiouIFdoYXQgaGFwcGVuZWQgdG8gb3VyIGNyZWF0aXZlIHNwaXJpdD8gSW4gdGhpcyB0YWxrIHdlIGZvY3VzIG9uIFJ1Ynkgd2ViIGZyYW1ld29ya3MgdGhhdCBoYXZlIGxvbmcgZ29uZSBieSB0aGUgd2F5c2lkZS4gSSB3b24ndCBzcG9pbCB0aGVtIGhlcmUsIGJ1dCBJIGNhbiB0ZWxsIHlvdSB3aGF0IHdlIHdvbid0IGJlIGNvdmVyaW5nOiBcbiogU2luYXRyYSBcbiogSGFuYW1pIFxuKiByb2RhIFxuKiBtZXJiIFxuXG5XZSB3aWxsIGFuc3dlciBxdWVzdGlvbnMgbGlrZTogXG4qIFdoeSBhcmUgZmV3ZXIgcGVvcGxlIGV4cGVyaW1lbnRpbmcgd2l0aCB0aGVpciBvd24gZnJhbWV3b3JrcyB0b2RheT8gXG4qIFdoYXQgZmVhdHVyZXMsIGlkaW9tcyBhbmQgaWRlYXMgYXJlIHdvcnRoIGV4cGxvcmluZz8gXG4qIEFyZSBhbnkgb2YgdGhlc2UgZnJhbWV3b3JrcyB3b3J0aCByZXZpdmluZyBvciBjb3B5aW5nPyIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL29YSGdOaDZEY1NJL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvb1hIZ05oNkRjU0kvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvb1hIZ05oNkRjU0kvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL29YSGdOaDZEY1NJL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvb1hIZ05oNkRjU0kvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNTUsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIm9YSGdOaDZEY1NJIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJvWEhnTmg2RGNTSSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDozMFoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiQlV6a2N3WlhPMGdhaGw1a1QzVFR5ZE9xSTBNIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk1Q1FrRXdSREEwTURrd05VTTJNRFkxIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMjA6MzY6MTBaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IFJ1YnnigJlzIENvcmUgR2VtIGJ5IENocmlzIFNlYXRvbiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlJ1YnkgaGFzIGEgY29yZSBsaWJyYXJ5IHRoYXQgaXMgcGFydCBvZiB0aGUgaW50ZXJwcmV0ZXIgYW5kIGFsd2F5cyBhdmFpbGFibGUuIEl04oCZcyBjbGFzc2VzIGxpa2UgU3RyaW5nIGFuZCBUaW1lLiBCdXQgd2hhdCB3b3VsZCBpdCBiZSBsaWtlIGlmIHdlIHJlLWltcGxlbWVudGVkIHRoZSBjb3JlIGxpYnJhcnksIHdyaXRpbmcgaXQgaW4gUnVieSBpdHNlbGYsIGFuZCBtYWRlIGl0IGF2YWlsYWJsZSBhcyBhIGdlbT8gV291bGQgaXQgYmUgZmFzdGVyIG9yIHNsb3dlcj8gV291bGQgaXQgYmUgZWFzaWVyIHRvIHVuZGVyc3RhbmQgYW5kIGRlYnVnPyBXaGF0IG90aGVyIGJlbmVmaXRzIGNvdWxkIHRoZXJlIGJlPyBJdCB3YXMgb3JpZ2luYWxseSBSdWJpbml1cyB0aGF0IGltcGxlbWVudGVkIFJ1YnnigJlzIGNvcmUgaW4gUnVieSwgYW5kIGl0IGhhcyBiZWVuIHRha2VuIHVwIGFuZCBtYWludGFpbmVkIGJ5IHRoZSBUcnVmZmxlUnVieSB0ZWFtLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzhtcURJSGVyMUc0L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOG1xRElIZXIxRzQvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOG1xRElIZXIxRzQvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzhtcURJSGVyMUc0L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOG1xRElIZXIxRzQvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNTYsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIjhtcURJSGVyMUc0IgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICI4bXFESUhlcjFHNCIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDowNVoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiX1MzaG9PTzh6cXhUdUZEVWw3aFZnUTlpTmljIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0d05FVTFNVEk0TmtaRU16VkJOMEpGIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMjA6Mzc6MTdaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IEknbSBpbiBsb3ZlIHdpdGggTWVybWFpZCBieSBDYXJvbHluIENvbGUiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJFdmVyeW9uZSBzYXlzIHRoYXQgYSBwaWN0dXJlIGlzIHdvcnRoIGEgdGhvdXNhbmQgd29yZHMuLi4gVGhlIGlzc3VlIGluIHRoZSBwYXN0IGlzIHRoYXQgdGhvc2UgcGljdHVyZXMgaGF2ZSBiZWVuIGhhcmQgdG8gY3JlYXRlIGxldCBhbG9uZSBtYWludGFpbi4gV2VsY29tZSBNZXJtYWlkIChodHRwczovL21lcm1haWQtanMuZ2l0aHViLmlvL21lcm1haWQvIy8pISBNZXJtYWlkIGlzIGEgbWFyayBkb3duIGNvbXBhdGlibGUgZ3JhcGhpbmcgdG9vbCB0aGF0IGFsbG93cyB5b3UgdG8gYWRkIGRpYWdyYW1zIGRpcmVjdGx5IHRvIHlvdXIgbWFya2Rvd24gaW4gZ2l0aHViLiBJIGhhdmUgYmVlbiB1c2luZyBpdCBmb3IgYSBhIHllYXIgYW5kIGp1c3QgbG92ZSBpdC4gSSBiZWxpZXZlIHRoYXQgeW91IHdpbGwgbG92ZSBpdCB0b28gb25jZSB5b3Ugam9pbiBteSBzZXNzaW9uLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2lGWG9teDNRTE00L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvaUZYb214M1FMTTQvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvaUZYb214M1FMTTQvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2lGWG9teDNRTE00L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvaUZYb214M1FMTTQvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNTcsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogImlGWG9teDNRTE00IgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJpRlhvbXgzUUxNNCIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDoxOFoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiUFI2YnZpeV9hUkttUUtfOHZBeXkzNVhsXzBZIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0d01UWXhRelZCUkRJMU5FVkRRVVpFIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMjA6Mzg6MzZaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IERpc2NvdmVyIE1hY2hpbmUgTGVhcm5pbmcgaW4gUnVieSBieSBKdXN0aW4gQm93ZW4iLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJXZSBjYW4gdXNlIFJ1YnkgdG8gZG8gYW55dGhpbmcgd2UgYXMgYSBjb21tdW5pdHkgd2FudC4gVG9kYXkgd2XigJlsbCBleHBsb3JlIHRoZSB3b3JrIG9mIGEgaGlkZGVuIGdlbSBvZiBhIGNvbnRyaWJ1dG9yIGluIG91ciBjb21tdW5pdHksIEFuZHJldyBLYW5lLCBhbmQgdGhlaXIgUnVieSBnZW1zIGZvciBNYWNoaW5lIExlYXJuaW5nLiBXZSB3aWxsIHNlZSBob3cgY29udGVtcG9yYXJ5IGNvbXB1dGVyIHZpc2lvbiBuZXVyYWwgbmV0d29ya3MgY2FuIHJ1biB3aXRoIFJ1YnkuIFJ1YnkgaXMgYWxsIGFib3V0IGRldmVsb3BlciBoYXBwaW5lc3MuIENvbXB1dGVyIFZpc2lvbiBpcyBzb21ldGhpbmcgdGhhdCBicmluZ3MgbWUgZ3JlYXQgam95IGFzIGl0IGRlbGl2ZXJzIHNhdGlzZnlpbmcgdmlzdWFsIGZlZWRiYWNrIGFuZCBjb25uZWN0cyBvdXIgY29kZSB3aXRoIHRoZSByZWFsIHdvcmxkIHRocm91Z2ggaW1hZ2VzIGFuZCB2aWRlb3MgaW4gYSB3YXkgdGhhdCB3YXNu4oCZdCBhY2Nlc3NpYmxlIHVudGlsIHRoZSBsYXN0IGRlY2FkZSBvciBzby4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9IUGJpek5nY3lGay9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0hQYml6TmdjeUZrL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0hQYml6TmdjeUZrL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9IUGJpek5nY3lGay9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0hQYml6TmdjeUZrL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDU4LAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJIUGJpek5nY3lGayIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiSFBiaXpOZ2N5RmsiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MDhaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIkgyR3poYWRHc29mNlJsc2FwMmtrcTkwRnhxYyIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NHpNVUV5TWtRd09UazBOVGc0TURndyIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDIwOjQwOjI2WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBTdGFmZiBFbmdpbmVlcjog4oCcSGVyZSBiZSBkcmFnb25z4oCdIGJ5IEFsZXhhbmRyZSBUZXJyYXNhIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAi4oCcSGVyZSBiZSBkcmFnb25z4oCdOiB0aGlzIGlzIGhvdyB1bmNoYXJ0ZWQgYXJlYXMgb2YgbWFwcyB3ZXJlIG1hcmtlZCBpbiBtZWRpZXZhbCB0aW1lcy4gVG9kYXksIHdoaWxlIHRoZSBqb3VybmV5IHRvIGJlY29tZSBhIFNlbmlvciBFbmdpbmVlciBpcyBrbm93biB0ZXJyaXRvcnksIGJlaW5nIGEgU3RhZmYgRW5naW5lZXIgYXBwZWFycyBmdWxsIG9mIGRyYWdvbnMuIFRvZ2V0aGVyLCBsZXTigJlzIGRlbXlzdGlmeSB3aGF0IGxlYWRpbmcgYmV5b25kIHRoZSBtYW5hZ2VtZW50IHRyYWNrIHJlYWxseSBtZWFucy4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9fN0RPU29YSUNNby9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL183RE9Tb1hJQ01vL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL183RE9Tb1hJQ01vL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9fN0RPU29YSUNNby9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL183RE9Tb1hJQ01vL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDU5LAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJfN0RPU29YSUNNbyIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiXzdET1NvWElDTW8iLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MTdaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIjNXZU1GMWFsM0FnaTlycjZOdWZVeDliR2x3ZyIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NDJRemRCTXpsQlF6UXpSalEwUWtReSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDIwOjQxOjQwWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBXb3JraW5nIFRvZ2V0aGVyOiBQYWlyaW5nIGFzIFNlbmlvciBhbmQgSnVuaW9yIERldmVsb3BlcnMgYnkgS2VsbHkgUnlhbiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlBhaXJpbmcgd2l0aCBhIHNlbmlvciBkZXZlbG9wZXIgaXMgYSBkYWlseSBuZWNlc3NpdHkgZm9yIGEgcHJvZ3JhbW1lciBqdXN0IHN0YXJ0aW5nIG91dC4gQnV0IGhvdyBzaG91bGQgeW91IGFzIGEganVuaW9yIGRldmVsb3BlciBhcHByb2FjaCBwYWlyaW5nIHRvIGdldCB0aGUgbW9zdCBvdXQgb2YgdGhlIGludGVyYWN0aW9uPyBIb3cgY2FuIHlvdSBub3Qgb25seSBmaW5kIGEgc29sdXRpb24gdG8gYSBjdXJyZW50IHByb2JsZW0sIGJ1dCBhbHNvIGJ1aWxkIHJlbGF0aW9uc2hpcHMgYW5kIGxlYXJuIHNraWxscyBmb3IgZnV0dXJlIHByb2JsZW1zPyBJbiB0aGlzIHRhbGssIHlvdSB3aWxsIGxlYXJuIGJlc3QgcHJhY3RpY2VzIGZvciBnZXR0aW5nIHRoZSBtb3N0IG91dCBvZiB0aW1lIHdpdGggYSBtZW50b3IuIEkgd2lsbCByZWNvbW1lbmQgcHJhY3RpY2FsIHRpcHMgYW5kIHBvc2l0aXZlIGhhYml0cywgYXMgd2VsbCBhcyB3YXlzIG9mIHRoaW5raW5nIHRoYXQgY2FuIGltcHJvdmUgeW91ciBleHBlcmllbmNlIHBhaXJpbmcgYW5kIGhlbHAgeW91IGJlY29tZSBhIGJldHRlciBkZXZlbG9wZXIuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvcHZsMUhQRnFSZGsvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wdmwxSFBGcVJkay9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wdmwxSFBGcVJkay9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvcHZsMUhQRnFSZGsvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wdmwxSFBGcVJkay9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA2MCwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAicHZsMUhQRnFSZGsiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogInB2bDFIUEZxUmRrIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjI2WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICIxcXFweGZuRVgyd3NLbElDV0xGQm04TlJXZ1EiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQxT1VSRU5EYzJORU0xTURJNU1qa3kiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDo0MzoxMloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogRnJvbSBiZWdpbm5lciB0byBleHBlcnQsIGFuZCBiYWNrIGFnYWluIGJ5IE1pY2hhZWwgVG9wcGEiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJcIkluIHRoZSBiZWdpbm5lcidzIG1pbmQgdGhlcmUgYXJlIG1hbnkgcG9zc2liaWxpdGllcywgaW4gdGhlIGV4cGVydCdzIG1pbmQgdGhlcmUgYXJlIGZldy5cIiAtIFNodW5yeXUgU3V6dWtpLCBmcm9tIFwiWmVuIE1pbmQsIEJlZ2lubmVyJ3MgTWluZFwiIFRoZSBKYXBhbmVzZSBaZW4gdGVybSBzaG9zaGluIHRyYW5zbGF0ZXMgYXMg4oCcYmVnaW5uZXLigJlzIG1pbmTigJ0gYW5kIHJlZmVycyB0byBhIHBhcmFkb3g6IHRoZSBtb3JlIHlvdSBrbm93IGFib3V0IGEgc3ViamVjdCwgdGhlIG1vcmUgbGlrZWx5IHlvdSBhcmUgdG8gY2xvc2UgeW91ciBtaW5kIHRvIGZ1cnRoZXIgbGVhcm5pbmcuIEluIGNvbnRyYXN0LCB0aGUgYmVnaW5uZXLigJlzIHN0YXRlIG9mIG1pbmQgaXMganVkZ21lbnQgZnJlZS4gSXTigJlzIG9wZW4sIGN1cmlvdXMsIGF2YWlsYWJsZSwgYW5kIHByZXNlbnQuIFdl4oCZbGwgZHJhdyBvbiBleGFtcGxlcyBvZiB0aGVzZSBtaW5kc2V0cyBmcm9tIGZpZWxkcyBhcyB2YXJpZWQgYXMgYXZpYXRpb24gYW5kIGdlb2xvZ3ksIGFuZCBkaXNjb3ZlciBsZXNzb25zIHdlIGNhbiBhcHBseSB0byB0aGUgd29ybGQgb2Ygc29mdHdhcmUgZGV2ZWxvcG1lbnQuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVWNGQnRCT28wZGsvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9VY0ZCdEJPbzBkay9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9VY0ZCdEJPbzBkay9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVWNGQnRCT28wZGsvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9VY0ZCdEJPbzBkay9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA2MSwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiVWNGQnRCT28wZGsiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIlVjRkJ0Qk9vMGRrIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjI1WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJwNnJmYkx5dWdTc2txdjhSeUkwUVBNRmJDeWsiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTR3UmpoRk0wTXhNVFUxTUVVelEwVkIiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDo0NDoyMVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogQ2hhbmdlIHRoZSBDbGltYXRlIEJlZm9yZSBDaGFuZ2luZyB0aGUgV2VhdGhlciBieSBCZW4gR3JlZW5iZXJnIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiVW5sZXNzIHlvdSdyZSBzZWxmLWVtcGxveWVkIHlvdSB3b3JrIGZvciBhIHN5c3RlbS4gVGhhdCBzeXN0ZW0gaXMgY29tcHJpc2VkIG9mIGl0cyBvd24gY3VsdHVyZSBpbiBkZWNpc2lvbiBtYWtpbmcsIGluY2x1c2l2aXR5LCBhbmQgYSBsb3QgbW9yZS4gQXMgb25lIHBlcnNvbiBpbiBhIHN5c3RlbSBob3cgY2FuIHlvdSBtYWtlIGFuIGltcGFjdCBvbiBpdD8gU29tZXRpbWVzIHlvdSBjYW7igJl0IGNoYW5nZSB0aGUgd2VhdGhlciwgYnV0IHlvdSBjYW4gY2hhbmdlIHRoZSBjbGltYXRlIGluIHlvdXIgb3duIHJvb20uIFlvdSBtYXkgZXZlbiBmaW5kIHRoYXQgaWYgeW91IGNoYW5nZSB0aGUgdGVtcGVyYXR1cmUgaW4gZW5vdWdoIHJvb21zLCBzdXJwcmlzaW5nbHksIHlvdSBlbmQgdXAgY2hhbmdpbmcgdGhlIHdlYXRoZXIuIEluIHRoaXMgdGFsaywgd2XigJlsbCBkaXNjdXNzIGEgcHJvY2VzcyBvZiBzeXN0ZW1zIGNoYW5nZSB0aGF0IGlzIGdyb3VuZCB1cCwgZ29pbmcgZnJvbSB0aGUgbWljcm8gdG8gdGhlIG1hY3JvLiBZb3XigJlsbCBsZWF2ZSBtb3JlIGVtcG93ZXJlZCB0byBzdGFydCBjaGFuZ2luZyB0aGUgY2xpbWF0ZSBpbiB5b3VyIG93biB3b3JrcGxhY2UuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvT2lkbVQyTGhPZEEvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PaWRtVDJMaE9kQS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PaWRtVDJMaE9kQS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvT2lkbVQyTGhPZEEvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PaWRtVDJMaE9kQS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA2MiwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiT2lkbVQyTGhPZEEiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIk9pZG1UMkxoT2RBIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjExWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJaSTVaNng3eUw1NXhqcVVGeUpvaXpENFhPdXMiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTVDTlRaRk9UTkdRelpFT0RnMVJVUXgiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDo0NTozOVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogU2ltdWxhdGVkIEFubmVhbGluZzogVGhlIE1vc3QgTWV0YWwgQWxnb3JpdGhtIEV2ZXIg8J+kmCBieSBDaHJpcyBCbG9vbSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlNpbXVsYXRlZCBhbm5lYWxpbmcgaXMgYSBmYXNjaW5hdGluZyBhbGdvcml0aG0gdGhhdCdzIGRlc2lnbmVkIHRvIGhlbHAgZmluZCBhIHBhcnRpY3VsYXIgdHlwZSBvZiBzb2x1dGlvbiAobmVhci1vcHRpbWFsLCBha2EgXCJnb29kIGVub3VnaFwiKSB0byBhIHBhcnRpY3VsYXIgdHlwZSBvZiBwcm9ibGVtIChjb25zdHJhaW5lZCBvcHRpbWl6YXRpb24pLiBJdCdzIGluc3BpcmVkIGJ5IHRoZSBzY2llbmNlIG9mIG1ldGFsbHVyZ3ksIGFuZCBiZWNhdXNlIGl0J3MgZ3JvdW5kZWQgaW4gYSByZWFsLXdvcmxkIHByb2Nlc3MgSSBmaW5kIGl0IGluY3JlZGlibHkgYXBwcm9hY2hhYmxlLiBJbiB0aGlzIHRhbGsgSSdsbCBleHBsYWluIGluIHBsYWluIHRlcm1zIGFib3V0IHdoYXQgc2ltdWxhdGVkIGFubmVhbGluZyBpcywgd2hhdCBhIGNvbnN0cmFpbmVkIG9wdGltaXphdGlvbiBwcm9ibGVtIGlzLCB3aHkgeW91IG1pZ2h0IHdhbnQgYSBcImdvb2QgZW5vdWdoXCIgc29sdXRpb24sIGFuZCBob3cgd2UgY2FuIHVzZSB0aGUgQW5uZWFsaW5nIGdlbSB0byBhZGQgc2ltdWxhdGVkIGFubmVhbGluZyB0byBvdXIgUnVieSBhcHBzLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JFTXdVX2RaMG93L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUkVNd1VfZFowb3cvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUkVNd1VfZFowb3cvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JFTXdVX2RaMG93L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUkVNd1VfZFowb3cvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNjMsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIlJFTXdVX2RaMG93IgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJSRU13VV9kWjBvdyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDoxM1oiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAieDRGbDl2cmg4NzdsakZMZXRYVUdHOWc4eWpjIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk1Q05UY3hNRFEwTlRoQk56TXhPRFl6IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMjA6NDc6NDJaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IFJ1YnkgTGFtYmRhcyBieSBLZWl0aCBCZW5uZXR0IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiT2JqZWN0IE9yaWVudGVkIERlc2lnbiBpcyBwb3dlcmZ1bCBmb3Igb3JnYW5pemluZyBzb2Z0d2FyZSBiZWhhdmlvciwgYnV0IHdpdGhvdXQgdGhlIGJlbmVmaXQgb2YgbGFtYmRhcycgY29kZS1hcy1kYXRhIGZsZXhpYmlsaXR5LCBpdCBvZnRlbiBmYWlscyB0byByZWR1Y2Ugc29sdXRpb25zIHRvIHRoZWlyIHNpbXBsZXN0IGZvcm0uIEFsdGhvdWdoIFJ1YnkncyBFbnVtZXJhYmxlIGZ1bmN0aW9uYWxpdHkgaXMgd2lkZWx5IGFwcHJlY2lhdGVkLCBpdHMgbGFtYmRhcyBnZW5lcmFsbHkgYXJlIG5vdC4gVGhpcyBwcmVzZW50YXRpb24gaW50cm9kdWNlcyB0aGUgZGV2ZWxvcGVyIHRvIGxhbWJkYXMsIGFuZCBzaG93cyBob3cgdGhleSBjYW4gYmUgdXNlZCB0byB3cml0ZSBzb2Z0d2FyZSB0aGF0IGlzIGNsZWFuZXIsIHNpbXBsZXIsIGFuZCBtb3JlIGZsZXhpYmxlLiBXZSdsbCBnbyB0aHJvdWdoIGxvdHMgb2YgY29kZSBmcmFnbWVudHMsIGV4cGxvcmluZyBkaXZlcnNlIHdheXMgb2YgZXhwbG9pdGluZyB0aGVpciBwb3dlciBhbmQgaWRlbnRpZnlpbmcgcmV1c2FibGUgZnVuY3Rpb25hbCBkZXNpZ24gcGF0dGVybnMgYWxvbmcgdGhlIHdheS4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9seFNvcWpKU2QzOC9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2x4U29xakpTZDM4L21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2x4U29xakpTZDM4L2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9seFNvcWpKU2QzOC9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2x4U29xakpTZDM4L21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDY0LAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJseFNvcWpKU2QzOCIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAibHhTb3FqSlNkMzgiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MjNaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIjVlYkx4cWZQQVhUckIybjNTOFFKclEwSFdZOCIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NUVSa1V5UVRNME16RXdRalpDTVRZNSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDIwOjQ5OjI3WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBCdWlsZGluZyBOYXRpdmUgR1VJIEFwcHMgaW4gUnVieSBieSBBbmR5IE1hbGVoIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiUnVieSBpcyBhbiBleGNlbGxlbnQgY2hvaWNlIGZvciBidWlsZGluZyBkZXNrdG9wIGFwcHMgd2l0aCBhIG5hdGl2ZSBHVUkgKEdyYXBoaWNhbCBVc2VyIEludGVyZmFjZSkgdGhhdCBsb29rcyBmYW1pbGlhciBvbiBNYWMsIFdpbmRvd3MsIGFuZCBMaW51eC4gSW4gZmFjdCwgUnVieSBwdXNoZXMgdGhlIGJvdW5kYXJpZXMgb2YgZGV2ZWxvcGluZyBzdWNoIGFwcHMgaW4gYnJhbmQgbmV3IHdheXMgbm90IHNlZW4gaW4gd2ViIGRldmVsb3BtZW50IGJ5IHN1cHBvcnRpbmcgdmVyeSBsaWdodHdlaWdodCBhbmQgZGVjbGFyYXRpdmUgR1VJIHN5bnRheCBpbmNsdWRpbmcgYmlkaXJlY3Rpb25hbCBkYXRhLWJpbmRpbmcsIHRoYW5rcyB0byBHbGltbWVyIERTTCBmb3IgTGliVUksIGEgZ2VtIHRoYXQgd29uIGEgRnVrdW9rYSBSdWJ5IDIwMjIgU3BlY2lhbCBBd2FyZC4gSW4gdGhpcyB0YWxrLCBJIHdpbGwgY292ZXIgY29uY2VwdHMgbGlrZSB0aGUgR1VJIERTTCwgZGF0YS1iaW5kaW5nLCBjdXN0b20gY29udHJvbHMsIGFyZWEgZ3JhcGhpY3MsIGRyYWcgJiBkcm9wLCBNVkMvTVZQIHBhdHRlcm4sIGFuZCBzY2FmZm9sZGluZywgd2l0aCBzYW1wbGUgZGVtb3MuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdzN0T3JIRGJiRkEvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93M3RPckhEYmJGQS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93M3RPckhEYmJGQS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdzN0T3JIRGJiRkEvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93M3RPckhEYmJGQS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA2NSwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAidzN0T3JIRGJiRkEiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogInczdE9ySERiYkZBIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjI4WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJxb3U5Q190cEtuZlpVQ0ZpUXZuWFFZUUtfVmsiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTR4TTBZeU0wUkROREU0UkVRMU5EQTAiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDo1MDo1MVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogSW4gRGVmZW5zZSBvZiBSdWJ5IE1ldGFwcm9ncmFtbWluZyBCeSBOb2VsIFJhcHBpbiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIklmIHlvdeKAmXZlIGxlYXJuZWQgUnVieSByZWNlbnRseSwgeW914oCZdmUgbGlrZWx5IGJlZW4gdG9sZCB0byBhdm9pZCB1c2luZyBSdWJ54oCZcyBtZXRhcHJvZ3JhbW1pbmcgZmVhdHVyZXMgYmVjYXVzZSB0aGV5IGFyZSDigJxkYW5nZXJvdXPigJ0uIEhlcmUgYXQgUnVieUNvbmYsIHdlIGxhdWdoIGF0IGRhbmdlci4gT3IgYXQgbGVhc3QgY2h1Y2tsZSBuZXJ2b3VzbHkgYXQgaXQuIFJ1YnnigJlzIGZsZXhpYmlsaXR5IGlzIG9uZSBvZiB0aGUgZmVhdHVyZXMgdGhhdCBtYWtlcyBSdWJ5IHBvd2VyZnVsLCBhbmQgaWdub3JpbmcgaXQgbGltaXRzIHdoYXQgeW91IGNhbiBkbyB3aXRoIHRoZSBsYW5ndWFnZS4gUGx1cywgbWV0YXByb2dyYW1taW5nIGlzIGZ1bi4gTGV04oCZcyB0YWxrIGFib3V0IHdoZW4gaXQgbWFrZXMgc2Vuc2UgdG8gbWV0YXByb2dyYW0sIHdoYXQgcGFydHMgb2YgUnVieSB0byB1c2UsIGFuZCBob3cgdG8gZG8gaXQgc2FmZWx5LiBZb3XigJlsbCBsZWF2ZSB3aXRoIHRoZSB0b29scyB0byBlZmZlY3RpdmVseSBtZXRhcHJvZ3JhbSBpbiB5b3VyIGNvZGUuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbzFYdmdKb0hfdEUvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9vMVh2Z0pvSF90RS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9vMVh2Z0pvSF90RS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbzFYdmdKb0hfdEUvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9vMVh2Z0pvSF90RS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA2NiwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAibzFYdmdKb0hfdEUiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIm8xWHZnSm9IX3RFIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjI1WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJqOW5lMlRWZzVZZVU2NXN1d1U3Tjh5RS1TemMiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQyTWpZek1UTXlRakEwUVVSQ04wSkYiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDo1MjoxN1oiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogUHVzaGluZyB0byBtYXN0ZXIgLSBhZG9wdGluZyB0cnVuayBiYXNlZCBkZXZlbG9wbWVudCBieSBEeWxhbiBCbGFrZW1vcmUiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJUcnVuayBiYXNlZCBkZXZlbG9wbWVudCBpcyBhIHNjYXJ5IHByYWN0aWNlIHRvIGFkb3B0IGZvciBlbmdpbmVlcnMgdXNlZCB0byBnaXQgZmxvdyBvciBnaXRodWIgZmxvdy4gQnV0IHRoZXJlIGlzIGFtcGxlIGV2aWRlbmNlIHRvIHNob3cgdGhhdCBpdCBsZWFkcyB0byBoaWdoZXIgcXVhbGl0eSBjb2RlIGFuZCBmYXN0ZXIgZGVsaXZlcnkuIFNvIHdoeSBhcmUgc28gbWFueSByZXNpc3RhbnQgdG8gcHVzaGluZyB0byBtYXN0ZXI/IEluIHRoaXMgdGFsaywgd2UnbGwgZ28gb3ZlciB3aHkgVEJEIGNhbiBiZSBzY2FyeSwgd2hhdCBjaGFsbGVuZ2VzIGFyZSBpbnZvbHZlZCBpbiBwdXNoaW5nIGZvciB0ZWFtIGFuZCBjb21wYW55IGFkb3B0aW9uLCBhbmQgaG93IHRvIG92ZXJjb21lIHRob3NlIGNoYWxsZW5nZXMiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8xc0tGa1YxOVhBYy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzFzS0ZrVjE5WEFjL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzFzS0ZrVjE5WEFjL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8xc0tGa1YxOVhBYy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzFzS0ZrVjE5WEFjL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDY3LAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICIxc0tGa1YxOVhBYyIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiMXNLRmtWMTlYQWMiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MDFaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogImJWWlViWl9NbXgxUlV0N1lhbTBNenVIZUtONCIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NDBNRE5FTXpBMFFUQkZSVGhGTXpCRSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDIwOjUzOjI4WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBJbXByb3ZpbmcgdGhlIGRldmVsb3BtZW50IGV4cGVyaWVuY2Ugd2l0aCBsYW5ndWFnZSBzZXJ2ZXJzIGJ5IFZpbmljaXVzIFN0b2NrIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiUHJvdmlkaW5nIGEgc3RhdGUgb2YgdGhlIGFydCBkZXZlbG9wbWVudCBleHBlcmllbmNlIGdyZWF0bHkgY29udHJpYnV0ZXMgdG8gUnVieeKAmXMgZ29hbCBvZiBtYWtpbmcgZGV2ZWxvcGVycyBoYXBweS4gQSBjb21wbGV0ZSBzZXQgb2YgZWRpdG9yIGZlYXR1cmVzIGNhbiBtYWtlIGEgYmlnIGRpZmZlcmVuY2UgaW4gaGVscGluZyBuYXZpZ2F0ZSBhbmQgdW5kZXJzdGFuZCBvdXIgUnVieSBjb2RlLiBMZXTigJlzIGV4cGxvcmUgYSBtb2Rlcm4gd2F5IG9mIGVuaGFuY2luZyBlZGl0b3IgZnVuY3Rpb25hbGl0eTogdGhlIGxhbmd1YWdlIHNlcnZlciBwcm90b2NvbCAoTFNQKS4gV2hhdCBpdCBpcywgaG93IHRvIGltcGxlbWVudCBpdCBhbmQgaG93IGFuIExTUCBzZXJ2ZXIgbGlrZSB0aGUgUnVieSBMU1AgY2FuIG1ha2Ugd3JpdGluZyBSdWJ5IGV2ZW4gYmV0dGVyLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3p4ZGIteENjSGRFL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvenhkYi14Q2NIZEUvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvenhkYi14Q2NIZEUvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3p4ZGIteENjSGRFL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvenhkYi14Q2NIZEUvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNjgsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogInp4ZGIteENjSGRFIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJ6eGRiLXhDY0hkRSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDoyOFoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiMllfQklrY3ZXUTBGYW1pNmMxWW5obVFUUXJRIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0MlJUTkNPRU14UkVJM1EwVkRNalUyIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMjA6NTQ6MzNaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IEEgVGFsZSBvZiBUd28gRmxhbWVncmFwaHM6IENvbnRpbnVvdXMgUHJvZmlsaW5nIGluIFJ1YnkgYnkgUnlhbiBQZXJyeSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoaXMgdGFsayB3aWxsIGRpdmUgZGVlcCBpbnRvIHRoZSBpbnRlcm5hbHMgb2Ygb25lIG9mIHRoZSBmYXN0ZXN0IGdyb3dpbmcgcHJvZmlsaW5nIGdlbXM6IFB5cm9zY29wZS4gUHlyb3Njb3BlIGlzIHVuaXF1ZSBiZWNhdXNlIGl0IGlzIGFjdHVhbGx5IGEgcnVieSBnZW0gb2YgYW5vdGhlciBydWJ5IGdlbSB3cml0dGVuIGluIHJ1c3Q7IFB5cm9zY29wZSBleHRlbmRzIHRoZSBwb3B1bGFyIHJic3B5IHByb2plY3QgYXMgYSBmb3VuZGF0aW9uIHRvIG5vdCBvbmx5IGNvbGxlY3QgcHJvZmlsaW5nIGRhdGEsIGJ1dCBhbHNvIHRvIHRhZyBhbmQgYW5hbHl6ZSB0aGF0IGRhdGEgYXMgd2VsbC4gWW91IGNhbiB0aGluayBvZiBQeXJvc2NvcGUgYXMgd2hhdCB5b3Ugd291bGQgZ2V0IGlmIHJic3B5IGFuZCBzcGVlZHNjb3BlIGhhZCBhIGJhYnkuIFdl4oCZbGwgc3RhcnQgd2l0aCB0aGUgaW50ZXJuYWxzIGFuZCBlbmQgd2l0aCBhbiBleGFtcGxlIG9mIGhvdyB0d28gZmxhbWVncmFwaHMgY2FuIGJlIHVzZWQgdG8gdGVsbCBhIHN0b3J5IGFib3V0IHlvdXIgYXBwbGljYXRpb25zIHBlcmZvcm1hbmNlLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzhuaU5Da2lGMlhvL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOG5pTkNraUYyWG8vbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOG5pTkNraUYyWG8vaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzhuaU5Da2lGMlhvL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOG5pTkNraUYyWG8vbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNjksCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIjhuaU5Da2lGMlhvIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICI4bmlOQ2tpRjJYbyIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDowM1oiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiLVA1MmlOTTQ2SnIxYXlTWVh5UVhka1NDWjhFIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0M1F6TkNOa1pFTnpJeU1EWTJNalpCIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMjA6NTU6NDFaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IEV2ZXJ5dGhpbmcgYSBNaWNyb3NlcnZpY2U6IFRoZSBXb3JzdCBQb3NzaWJsZSBJbnRybyB0byBkUnVieSBieSBLZXZpbiBLdWNodGEiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJNaWNyb3NlcnZpY2VzIGFyZSBncmVhdCwgYnV0IEkgdGhpbmsgd2UgY2FuIGFsbCBhZ3JlZTogd2UgbmVlZCBtb3JlIG9mIHRoZW0gYW5kIHRoZXkgc2hvdWxkIGJlIG1pY3JvLWVyLiBXaGF0J3MgdGhlIGxvZ2ljYWwgbGltaXQgaGVyZT8gV2hhdCBpZiBldmVyeSBvYmplY3Qgd2FzIHJlbW90ZSBpbiBhIGxhbmd1YWdlIHdoZXJlIGV2ZXJ5dGhpbmcncyBhbiBvYmplY3Q/IExldCdzIHRha2UgYSBsb29rIGF0IGRSdWJ5LCB0aGUgZGlzdHJpYnV0ZWQgcHJvZ3JhbW1pbmcgbW9kdWxlIHlvdSd2ZSBuZXZlciBoZWFyZCBvZiwgYW5kIHVzZSBpdCB0byBhY2hpZXZlIHRoYXQgZGVyYW5nZWQgZ29hbCEgWW91J2xsIGxlYXJuIGFib3V0IGEgbmlmdHkgbGl0dGxlIGNvcm5lciBvZiB0aGUgc3RhbmRhcmQgbGlicmFyeSB3aGlsZSB3ZSBhdHRlbXB0IHRvIHJlYWNoIHRoZSBpbGxvZ2ljYWwgY29uY2x1c2lvbiBvZiB0b2RheSdzIGhvdHRlc3QgYXJjaGl0ZWN0dXJlIHRyZW5kLiBCZSB3YXJuZWQ6IHRob3NlIHNpdHRpbmcgaW4gdGhlIGZpcnN0IGZldyByb3dzIG1heSBnZXQgcG9vcmx5LW1hcnNoYWxlZCBkYXRhIG9uIHRoZW0uIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbnJKUDlRcjJBWFEvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9uckpQOVFyMkFYUS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9uckpQOVFyMkFYUS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbnJKUDlRcjJBWFEvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9uckpQOVFyMkFYUS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA3MCwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAibnJKUDlRcjJBWFEiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIm5ySlA5UXIyQVhRIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjIzWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJ1QW0zQXdxcTJDXzFDWWlfYWs3Skp3LVV4bGsiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTVFUWtFM1JUSkNRVEpFUWtGQlFUY3oiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDo1Njo0NVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogMS41IGlzIHRoZSBNaWRwb2ludCBCZXR3ZWVuIDAgYW5kIEluZmluaXR5IGJ5IFBldGVyIFpodSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIldoYXTigJlzIHRoZSBtaWRwb2ludCBiZXR3ZWVuIDAgYW5kIGluZmluaXR5PyBXZWxsLCB0aGUgYW5zd2VyIGRpZmZlcnMgZGVwZW5kaW5nIG9uIHdoZXRoZXIgeW91IGFyZSBhc2tpbmcgYSBtYXRoZW1hdGljaWFuLCBwaGlsb3NvcGhlciwgb3IgYSBSdWJ5IGRldmVsb3Blci4gSeKAmW0gbm90IGEgbWF0aGVtYXRpY2lhbiBvciBhIHBoaWxvc29waGVyLCBidXQgSSBhbSBhIFJ1YnkgZGV2ZWxvcGVyLCBzbyBJIGNhbiB0ZWxsIHlvdSB0aGF0IDEuNSBpcyB0aGUgbWlkcG9pbnQgYmV0d2VlbiAwIGFuZCBpbmZpbml0eS4gSW4gdGhpcyB0YWxrLCB3ZSdsbCBkaXNjdXNzIHRoZSBiaW5hcnkgc2VhcmNoIGFsZ29yaXRobSwgSUVFRSA3NTQgZmxvYXRpbmctcG9pbnQgbnVtYmVycywgYW5kIGEgY2xldmVyIHRyaWNrIFJ1YnkgdXNlcyB0byBwZXJmb3JtIGJpbmFyeSBzZWFyY2ggb24gZmxvYXRpbmctcG9pbnQgcmFuZ2VzLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JRc0g1NEdLODVNL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUlFzSDU0R0s4NU0vbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUlFzSDU0R0s4NU0vaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JRc0g1NEdLODVNL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUlFzSDU0R0s4NU0vbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNzEsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIlJRc0g1NEdLODVNIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJSUXNINTRHSzg1TSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDoxNVoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAic1ZzaGJ3V25pNEl2WUxxTjFxUnlqR3IxVl9RIiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0eVF6azRRVEE1UWprek1URkZPRUkxIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMjA6NTc6NTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IFVzaW5nIEpSdWJ5OiBXaGF0LCBXaGVuLCBIb3csIGFuZCBXaHkgYnkgQ2hhcmxlcyBOdXR0ZXIiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJKUnVieSBoYXMganVzdCBiZWVuIHVwZGF0ZWQgZm9yIFJ1YnkgMy4xIHN1cHBvcnQsIGJyaW5naW5nIGNvbXBhdGliaWxpdHkgdXAgdG8gZGF0ZSBmb3IgdGhlIG1vc3Qgd2lkZWx5LWRlcGxveWVkIGFsdGVybmF0aXZlIFJ1YnkgaW1wbGVtZW50YXRpb24hIFRoaXMgdGFsayB3aWxsIHRlYWNoIHlvdSBhbGwgYWJvdXQgSlJ1Ynk6IHdoYXQgaXMgaXQsIHdoZW4gc2hvdWxkIHlvdSB1c2UgaXQsIGhvdyB0byBnZXQgc3RhcnRlZCBhbmQgd2h5IGl0IG1hdHRlcnMuIExlYXJuIHdoeSBSdWJ5IHNob3BzIGFyb3VuZCB0aGUgd29ybGQgY2hvb3NlIEpSdWJ5IGZvciB3b3JsZC1jbGFzcyBjb25jdXJyZW5jeSwgR0MsIEpJVCwgYW5kIGNyb3NzLXBsYXRmb3JtIHN1cHBvcnQuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvekxYOW9fY0VlbjQvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96TFg5b19jRWVuNC9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96TFg5b19jRWVuNC9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvekxYOW9fY0VlbjQvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96TFg5b19jRWVuNC9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA3MiwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiekxYOW9fY0VlbjQiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogInpMWDlvX2NFZW40IiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjM5WiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICI2SHpRbzJSbG4xMk9aejdpa3ktLWJFVkQ4ak0iLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTQ1TkRsRFFVRkZPVGhETVRBeFFqVXciLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMDo1OTowM1oiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogQnVpbGRpbmcgYSBDb21tZXJjaWFsIEdhbWUgRW5naW5lIHVzaW5nIG1SdWJ5IGFuZCBTREwgYnkgQW1pciBSYWphbiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIldoYXQgZG9lcyBpdCB0YWtlIHRvIGJ1aWxkIGEgY3Jvc3MgcGxhdGZvcm0gZ2FtZSBlbmdpbmUgaW4gUnVieT8gSG93IGRvIHlvdSByZW5kZXIgdG8gdGhlIHNjcmVlbj8gSG93IGlzIHRoZSBzaW11bGF0aW9uIGFuZCByZW5kZXJpbmcgcGlwZWxpbmUgb3JjaGVzdHJhdGVkPyBXaHkgaXMgUnVieSBhIHZpYWJsZSBvcHRpb24gaXMgdG8gYmVnaW4gd2l0aD8gVGhlc2UgcXVlc3Rpb25zIGFuZCBtb3JlIHdpbGwgYmUgYW5zd2VyZWQgYnkgQW1pci4gQmUgYSBwYXJ0IG9mIHRoaXMgcmVuYWlzc2FuY2UgYW5kIHNlZSBob3cgUnVieSBjYW4gYmUgdXNlZCBmb3Igc28gbXVjaCBtb3JlIHRoYW4gc2VydmVyIHNpZGUgd2ViIGRldmVsb3BtZW50LiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1lWY2wxT3k2UUZNL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWVZjbDFPeTZRRk0vbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWVZjbDFPeTZRRk0vaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1lWY2wxT3k2UUZNL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWVZjbDFPeTZRRk0vbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInBsYXlsaXN0SWQiOiAiUExFN3RRVWRSS2N5Wll6ME8zZDlaRGRvMC1Ca09XaHJTayIsCiAgICAgICAgInBvc2l0aW9uIjogNzMsCiAgICAgICAgInJlc291cmNlSWQiOiB7CiAgICAgICAgICAia2luZCI6ICJ5b3V0dWJlI3ZpZGVvIiwKICAgICAgICAgICJ2aWRlb0lkIjogIllWY2wxT3k2UUZNIgogICAgICAgIH0sCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiCiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAidmlkZW9JZCI6ICJZVmNsMU95NlFGTSIsCiAgICAgICAgInZpZGVvUHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wN1QxNjowMDoyOFoiCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RJdGVtIiwKICAgICAgImV0YWciOiAiU054ZXY4bUd1ci1QeVRqT01rU3laSDRlU0F3IiwKICAgICAgImlkIjogIlVFeEZOM1JSVldSU1MyTjVXbGw2TUU4elpEbGFSR1J2TUMxQ2EwOVhhSEpUYXk0eE4wWTJRalZCT0VJMk16UTVPVU01IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDZUMjE6MDA6MzVaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IFdyaXRpbmcgUnVieSwganVzdCBub3QgaW4gRW5nbGlzaCEgYnkgUmF0bmFkZWVwIERlc2htYW5lIChydGRwKSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIk15IHRhbGsgc2hvd3MgaG93IHRvIHdyaXRlIFJ1YnkgaW4gYSBub24tRW5nbGlzaCBsYW5ndWFnZSBhbmQgdGhlIGJlbmVmaXRzIG9mIGRvaW5nIHNvLiBUaGlzIHdpbGwgY2VydGFpbmx5IGJlIGEgZ3JlYXQgaGVscCBmb3IgcGVvcGxlIHdobyBkb27igJl0IHNwZWFrIEVuZ2xpc2guIEl0IGFsc28gaGVscHMgZ2V0IGEgYmV0dGVyIHByb2dyYW1taW5nIHBlcnNwZWN0aXZlIGZvciBzZWFzb25lZCBkZXZlbG9wZXJzIHdobyBkb27igJl0IGhhdmUgRW5nbGlzaCBhcyB0aGVpciBmaXJzdCBsYW5ndWFnZS4gSSB3aWxsIGFsc28gZGVtbyB0aGUgdG9vbGluZyB0aGF0IEkgaGF2ZSBkZXZlbG9wZWQsIHVzaW5nIHdoaWNoIG9uZSBjYW4gcXVpY2tseSBjcmVhdGUgYSBuZXcgc3Bva2VuIGxhbmd1YWdlIHZhcmlhbnQgb2YgUnVieSBhbmQgc3RhcnQgcHJvZ3JhbW1pbmcgaW4gU3BhbmlzaCwgUG9ydHVndWVzZSBldGMuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZzhQZ001V0d5aFEvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9nOFBnTTVXR3loUS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9nOFBnTTVXR3loUS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZzhQZ001V0d5aFEvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9nOFBnTTVXR3loUS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA3NCwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiZzhQZ001V0d5aFEiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogImc4UGdNNVdHeWhRIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjMzWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJrMDhTRFB0ZlJLX1kxcjRpMlM0SWNkX1RDUVUiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTVGUVVZMlF6azRSVUZETjBaRlJrWkYiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMTowMTo0N1oiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogVGhpcyBPbGQgQXBwIGJ5IExvcmkgTSBPbHNvbiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIldoYXQgY291bGQgcmVub3ZhdGluZyBhbiBvbGQgaG91c2UgaGF2ZSBpbiBjb21tb24gd2l0aCB1cGdyYWRpbmcgYW4gb2xkIGFwcD8gKkV2ZXJ5dGhpbmchKiBMZXQgbWUgc2hvdyB5b3UgaG93IHRoaXMgb2xkIGhvdXNlIHJlbm92YXRpb24gcHJvamVjdCBwcm9jZWVkcywgZnJvbSBwbGFubmluZyB0byBzY2hlZHVsaW5nLCBkZW1vbGl0aW9uIHRvIGZpbmlzaGluZywgYW5kIGhvdyBldmVyeSBzdGFnZSBkaXJlY3RseSByZWxhdGVzIHRoZSBsZXNzb25zIGxlYXJuZWQgZnJvbSBhcHAgdXBncmFkZXMgb3ZlciB0aGUgY291cnNlIG9mIG15IGNhcmVlci4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8tcTliNXdsWHIwYy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLy1xOWI1d2xYcjBjL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLy1xOWI1d2xYcjBjL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8tcTliNXdsWHIwYy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLy1xOWI1d2xYcjBjL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDc1LAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICItcTliNXdsWHIwYyIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiLXE5YjV3bFhyMGMiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MDBaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIml2azhjaDNpQU1MSlFieVNRc3BNb3Z6VTdwMCIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NUNNRVZCUlVKRVJrVXlOVEJFTlRreiIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDIxOjAyOjQ4WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBOZXZlciBhZ2FpbiB3aXRob3V0IGEgY29udHJhY3Q6IGRyeS12YWxpZGF0aW9uIGJ5IEVzcGFydGFjbyBQYWxtYSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoZSBzYW1lIGFzIHlvdSBzaG91bGRuJ3Qgd29yayB3aXRob3V0IGEgY29udHJhY3QsIG91ciBzeXN0ZW1zIHNob3VsZCBhY2NlcHQgZXh0ZXJuYWwgaW5wdXRzIHdpdGhvdXQgb25lLCBhIHdyaXR0ZW4sIGNsZWFyIGFuZCBlbmZvcmNlYWJsZSBvbmUuIERlZmluZSB0aGUgc3RydWN0dXJlICYgZXhwZWN0ZWQgcGF5bG9hZCBiZWluZyBhd2FyZSBvZiB0aGVpciBzY2hlbWEsIHN0cnVjdHVyZSAmIHR5cGVzLiBVc2luZyBkcnktc2NoZW1hIG9yIGRyeS12YWxpZGF0aW9uIHRoaXMgcGFydCBpcyBhIG1hdHRlciBvZiBhIGZldyBsaW5lcyBvZiBjb2RlcyBjb3ZlcmluZyBtb3N0IG9mIHRoZSBjYXNlcyB5b3UgbWF5IGZpbmQgd2l0aCB0aGUgY2hlcnJ5LW9uLXRvcDogZXJyb3IgaGFuZGxpbmcgb3V0LW9mLXRoZS1ib3ggYW5kIGlmIHRoaXMgbm90IGVub3VnaCB3aXRoIG9wdGlvbmFsIHBhdHRlcm4gbWF0Y2hpbmcgZm9yIHJlc3VsdHMuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvX2xNdzdndXJhZ2MvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9fbE13N2d1cmFnYy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9fbE13N2d1cmFnYy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvX2xNdzdndXJhZ2Mvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9fbE13N2d1cmFnYy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA3NiwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAiX2xNdzdndXJhZ2MiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogIl9sTXc3Z3VyYWdjIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjIxWiIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdEl0ZW0iLAogICAgICAiZXRhZyI6ICJGcHd6a2s0UmtPSllxT2lGU1FZZDRQemJIQWsiLAogICAgICAiaWQiOiAiVUV4Rk4zUlJWV1JTUzJONVdsbDZNRTh6WkRsYVJHUnZNQzFDYTA5WGFISlRheTR4TmpJeU5FRTBNREV5UkRsQ01qQkUiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMy0wNlQyMTowMzo1MloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogQm91dGlxdWUgbWFjaGluZSBnZW5lcmF0ZWQgZ2VtcyBieSBDSiBBdmlsbGEiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJXaGF0IGlmIHdyaXRpbmcgYm9pbGVycGxhdGUgZm9yIFJ1YnkgZ2VtcyB3ZXJlIGF1dG9tYXRlZCB1c2luZyBmYW1pbGlhciBVSSBidWlsZGluZyBibG9ja3M/IE1hbnkgUnVieWlzdHMgYXJlIGZhbWlsaWFyIHdpdGggY29tcG9uZW50cyBmb3IgZ2VuZXJhdGluZyBjbGVhbiBIVE1MIHdpdGggaGlnaGVyLWxldmVsIGZyYW1ld29ya3MuIFVuZm9ydHVuYXRlbHksIG1hbnkgZGV2ZWxvcGVycyBhcmUgdW5hd2FyZSB0aGV5IGNhbiBnZW5lcmF0ZSBjbGVhbiBSdWJ5IGNvZGUgdGhhdCBpcyBhcyBiZWF1dGlmdWwgYXMgdGhlaXIgVUlzLiBUaGlzIHRhbGsgd2lsbCBleHBsb3JlIGhvdyB3ZSBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQgYSBnZW5lcmF0b3IgdG8gcHJvZHVjZSBoaWdoLXF1YWxpdHkgcnVieSBhbmQgZG9jcyBmb3IgYSBwb3B1bGFyIGdlbS4gSSdsbCBzaG93IGhvdyB0byB1c2UgdGhpcyBhcHByb2FjaCB0byBrZWVwIGdlbXMgdXAtdG8tZGF0ZSB3aXRoIGZhc3QtbW92aW5nIEFQSXMsIHJlbGVhc2UgbmV3IHZlcnNpb25zIGZyZXF1ZW50bHksIGFuZCBwcm92aWRlIGFuIGV4Y2VsbGVudCBkZXZlbG9wZXIgZXhwZXJpZW5jZS4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9hVjFvYnN1RG1qVS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2FWMW9ic3VEbWpVL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2FWMW9ic3VEbWpVL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9hVjFvYnN1RG1qVS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2FWMW9ic3VEbWpVL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJwbGF5bGlzdElkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAgICJwb3NpdGlvbiI6IDc3LAogICAgICAgICJyZXNvdXJjZUlkIjogewogICAgICAgICAgImtpbmQiOiAieW91dHViZSN2aWRlbyIsCiAgICAgICAgICAidmlkZW9JZCI6ICJhVjFvYnN1RG1qVSIKICAgICAgICB9LAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgInZpZGVvT3duZXJDaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIgogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgInZpZGVvSWQiOiAiYVYxb2JzdURtalUiLAogICAgICAgICJ2aWRlb1B1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMDdUMTY6MDA6MDFaIgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0SXRlbSIsCiAgICAgICJldGFnIjogIjJKR0VZTGM3dEI2STJtcUlwNFpfWE5aUER0TSIsCiAgICAgICJpZCI6ICJVRXhGTjNSUlZXUlNTMk41V2xsNk1FOHpaRGxhUkdSdk1DMUNhMDlYYUhKVGF5NDRRVFkyTUVFek56QkZRVUpDTVVRMiIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA2VDIxOjA2OjIyWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDIyOiBUaGUgUG93ZXIgb2YgJ05vJyBieSBHbGVubiBIYXJtb24iLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJIYXZlIHlvdSBldmVyIGF0dGVuZGVkIGEgbWVldGluZyB0aGF0IHlvdSB3aXNoIHlvdSBoYWRu4oCZdD8gSGF2ZSB5b3UgZXZlciBiZWVuIGhhcHB5IHRoYXQgcGxhbnMgd2VyZSBjYW5jZWxlZCBiZWNhdXNlIHlvdSBuZXZlciByZWFsbHkgd2FudGVkIHRvIGdvIGluIHRoZSBmaXJzdCBwbGFjZT8gU2F5aW5nIG5vIGlzIGhhcmQgYW5kIGNhbiBiZSB0cnVseSBjaGFsbGVuZ2luZyB3aGVuIGZhY2VkIHdpdGggdGhlIHByb3NwZWN0IG9mIGZlZWxpbmcgbGlrZSBtYXliZSB5b3XigJlsbCBsZXQgc29tZW9uZSBkb3duLiBBbm90aGVyIHJlYXNvbiBzYXlpbmcgbm8gaXMgaGFyZCBpcyB0aGUgZmVlbGluZyBvciBGT01PLCBvciB0aGUgRmVhciBPZiBNaXNzaW5nIE91dC4gQWxsIG9mIHRoZXNlIGFyZSBldmVuIGhhcmRlciBpZiB5b3UncmUgYSBwZXJzb24gb2YgY29sb3IuIEJ1dCBpcyB0aGF0ICdZZXMnIHdvcnRoIHlvdXIgcGVhY2Ugb2YgbWluZD8gVGhpcyB0YWxrIGlzIGFib3V0IGhvdyBrbm93aW5nIHdoZW4gdG8gc2F5IG5vIGFuZCBob3cgdG8gZG8gc28uIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvcTlFb281aTZobWsvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xOUVvbzVpNmhtay9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xOUVvbzVpNmhtay9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvcTlFb281aTZobWsvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xOUVvbzVpNmhtay9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAicGxheWxpc3RJZCI6ICJQTEU3dFFVZFJLY3laWXowTzNkOVpEZG8wLUJrT1doclNrIiwKICAgICAgICAicG9zaXRpb24iOiA3OCwKICAgICAgICAicmVzb3VyY2VJZCI6IHsKICAgICAgICAgICJraW5kIjogInlvdXR1YmUjdmlkZW8iLAogICAgICAgICAgInZpZGVvSWQiOiAicTlFb281aTZobWsiCiAgICAgICAgfSwKICAgICAgICAidmlkZW9Pd25lckNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJ2aWRlb093bmVyQ2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIKICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJ2aWRlb0lkIjogInE5RW9vNWk2aG1rIiwKICAgICAgICAidmlkZW9QdWJsaXNoZWRBdCI6ICIyMDIzLTAzLTA3VDE2OjAwOjI3WiIKICAgICAgfQogICAgfQogIF0sCiAgInBhZ2VJbmZvIjogewogICAgInRvdGFsUmVzdWx0cyI6IDc5LAogICAgInJlc3VsdHNQZXJQYWdlIjogNTAKICB9Cn0K\n  recorded_at: Tue, 06 Jun 2023 08:23:15 GMT\nrecorded_with: VCR 6.1.0\n"
  },
  {
    "path": "test/vcr_cassettes/youtube/playlists/all.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: get\n    uri: https://youtube.googleapis.com/youtube/v3/playlists?channelId=UCWnPjmqvljcafA0z2U1fwKQ&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&part=snippet,contentDetails\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Thu, 08 Jun 2023 18:32:24 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      Cache-Control:\n      - private\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: !binary |-\n        ewogICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RMaXN0UmVzcG9uc2UiLAogICJldGFnIjogInVRM3RteS05NUlSZkpIUTZSVV8tQVV2cDMwOCIsCiAgIm5leHRQYWdlVG9rZW4iOiAiQ0RJUUFBIiwKICAicGFnZUluZm8iOiB7CiAgICAidG90YWxSZXN1bHRzIjogMzE4LAogICAgInJlc3VsdHNQZXJQYWdlIjogNTAKICB9LAogICJpdGVtcyI6IFsKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogImd6aWQyeW5aTHUtbkxETVZJMjlSc1g5VUhVWSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lhTkRmYjBNTWs5SXdkSm9HbXJ5UUtnIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjMtMDMtMjhUMjE6NDM6NDJaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIiEhQ29uIDIwMjIiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIhIUNvbiBpcyBhIGNvbmZlcmVuY2Ugb2YgdGVuLW1pbnV0ZSB0YWxrcyBhYm91dCB0aGUgam95LCBleGNpdGVtZW50LCBhbmQgc3VycHJpc2Ugb2YgY29tcHV0aW5nISEiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS82Y0NDeWlKZlU5Zy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzZjQ0N5aUpmVTlnL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzZjQ0N5aUpmVTlnL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS82Y0NDeWlKZlU5Zy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzZjQ0N5aUpmVTlnL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiISFDb24gMjAyMiIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiISFDb24gaXMgYSBjb25mZXJlbmNlIG9mIHRlbi1taW51dGUgdGFsa3MgYWJvdXQgdGhlIGpveSwgZXhjaXRlbWVudCwgYW5kIHN1cnByaXNlIG9mIGNvbXB1dGluZyEhIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxMAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiaXVhWHh4NUZBcWtLTnRpdWFvUHJ3VW5SdFNvIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVpZejBPM2Q5WkRkbzAtQmtPV2hyU2siLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMy0wMi0yOFQxNjowNToyNloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAyMjogTWluaSBhbmQgSG91c3RvbiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlJ1YnlDb25mIE1pbmkgaGVsZCBpbiBQcm92aWRlbmNlLCBSSSBhbmQgUnVieUNvbmYgSG91c3RvbiAyMDIyIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvLUV4UE8tRkNLUUEvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8tRXhQTy1GQ0tRQS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8tRXhQTy1GQ0tRQS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvLUV4UE8tRkNLUUEvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8tRXhQTy1GQ0tRQS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjI6IE1pbmkgYW5kIEhvdXN0b24iLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIlJ1YnlDb25mIE1pbmkgaGVsZCBpbiBQcm92aWRlbmNlLCBSSSBhbmQgUnVieUNvbmYgSG91c3RvbiAyMDIyIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA3OQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiTkVyRWg0SUZTMmNPQnk1NWNtZkMtOWNMYmVBIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVpjdFJYejYyUjdPLXRIbDVydkdrRjciLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMi0xMi0wNVQxNTowNDoyNFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBCb3N0b24gMjAyMiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkRldm9wc2RheXMgaXMgYSB3b3JsZHdpZGUgY29tbXVuaXR5IGNvbmZlcmVuY2Ugc2VyaWVzIGZvciBhbnlvbmUgaW50ZXJlc3RlZCBpbiBJVCBpbXByb3ZlbWVudC4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS85RVlBdHNuMGU5WS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzlFWUF0c24wZTlZL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzlFWUF0c24wZTlZL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS85RVlBdHNuMGU5WS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzlFWUF0c24wZTlZL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBCb3N0b24gMjAyMiIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRGV2b3BzZGF5cyBpcyBhIHdvcmxkd2lkZSBjb21tdW5pdHkgY29uZmVyZW5jZSBzZXJpZXMgZm9yIGFueW9uZSBpbnRlcmVzdGVkIGluIElUIGltcHJvdmVtZW50LiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTAKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogInBfc1VubHRxa2J2X0ZuMnhLZ1RHWXJpU1ZhRSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3liMk1qdGQxUkJqZVAzSnQ5UnVrVTdHIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjItMTEtMDlUMTg6MDc6MThaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJhaWxzQ29uZiAyMDIyIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiUmFpbHNDb25mLCBob3N0ZWQgYnkgUnVieSBDZW50cmFsLCBpcyB0aGUgd29ybGTigJlzIGxhcmdlc3QgYW5kIGxvbmdlc3QtcnVubmluZyBnYXRoZXJpbmcgb2YgUnVieSBvbiBSYWlscyBlbnRodXNpYXN0cywgcHJhY3RpdGlvbmVycywgYW5kIGNvbXBhbmllcy4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xcVRGbTJadFJIZy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3FxVEZtMlp0UkhnL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3FxVEZtMlp0UkhnL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9xcVRGbTJadFJIZy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3FxVEZtMlp0UkhnL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiUmFpbHNDb25mIDIwMjIiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIlJhaWxzQ29uZiwgaG9zdGVkIGJ5IFJ1YnkgQ2VudHJhbCwgaXMgdGhlIHdvcmxk4oCZcyBsYXJnZXN0IGFuZCBsb25nZXN0LXJ1bm5pbmcgZ2F0aGVyaW5nIG9mIFJ1Ynkgb24gUmFpbHMgZW50aHVzaWFzdHMsIHByYWN0aXRpb25lcnMsIGFuZCBjb21wYW5pZXMuIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA2NwogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiOWhxMlBSN3JnZk5wdjRyVjhsd0JnMkNZQ1NVIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWFieDdTTVFyeXQwT2lTTVg5N0kwR2EiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMi0xMC0xM1QyMToxNzozMloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUG93ZXJTaGVsbCArIERldk9wcyBHbG9iYWwgU3VtbWl0IDIwMjIiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJQb3dlclNoZWxsICsgRGV2T3BzIEdsb2JhbCBTdW1taXQgaXMgdGhlIGdhdGhlcmluZyBvZiBQb3dlclNoZWxsICsgRGV2T3BzIHByb2Zlc3Npb25hbHMgYW5kIGVudGh1c2lhc3RzLiBNb3JlIHRoYW4ganVzdCBhIGNvbmZlcmVuY2UsIGl04oCZcyBhIHRydWUgaW4tcGVyc29uIGdhdGhlcmluZyBvZiBhIHZpYnJhbnQgY29tbXVuaXR5IOKAkyB3ZSBsZWFybiBmcm9tIGVhY2ggb3RoZXIsIHdlIGRldmVsb3AgcHJhY3RpY2VzIGFuZCBzdGFuZGFyZHMsIHdlIHNoYXJlIGNoYWxsZW5nZXMgYW5kIHNvbHV0aW9ucywgYW5kIHdlIGRyaXZlIG91ciBpbmR1c3RyeSBmb3J3YXJkLiBJZiB5b3UgYXJlIHdvcmtpbmcgd2l0aCBQb3dlclNoZWxsLCBEZXNpcmVkIFN0YXRlIENvbmZpZ3VyYXRpb24sIFB5dGhvbiwgR0lULCBhbmQgcmVsYXRlZCB0ZWNobm9sb2dpZXMsIGFuZCBlc3BlY2lhbGx5IGlmIHlvdeKAmXJlIG1vdmluZyB5b3VyIG9yZ2FuaXphdGlvbiB0b3dhcmQgYSBEZXZPcHMgZm9vdGluZywgdGhlbiB0aGlzIGlzIHRoZSA0MDArIGxldmVsIGV2ZW50IHlvdeKAmXZlIGJlZW4gbG9va2luZyBmb3IuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbEhxeUM5UmROeVkvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9sSHF5QzlSZE55WS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9sSHF5QzlSZE55WS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbEhxeUM5UmROeVkvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9sSHF5QzlSZE55WS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIlBvd2VyU2hlbGwgKyBEZXZPcHMgR2xvYmFsIFN1bW1pdCAyMDIyIiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJQb3dlclNoZWxsICsgRGV2T3BzIEdsb2JhbCBTdW1taXQgaXMgdGhlIGdhdGhlcmluZyBvZiBQb3dlclNoZWxsICsgRGV2T3BzIHByb2Zlc3Npb25hbHMgYW5kIGVudGh1c2lhc3RzLiBNb3JlIHRoYW4ganVzdCBhIGNvbmZlcmVuY2UsIGl04oCZcyBhIHRydWUgaW4tcGVyc29uIGdhdGhlcmluZyBvZiBhIHZpYnJhbnQgY29tbXVuaXR5IOKAkyB3ZSBsZWFybiBmcm9tIGVhY2ggb3RoZXIsIHdlIGRldmVsb3AgcHJhY3RpY2VzIGFuZCBzdGFuZGFyZHMsIHdlIHNoYXJlIGNoYWxsZW5nZXMgYW5kIHNvbHV0aW9ucywgYW5kIHdlIGRyaXZlIG91ciBpbmR1c3RyeSBmb3J3YXJkLiBJZiB5b3UgYXJlIHdvcmtpbmcgd2l0aCBQb3dlclNoZWxsLCBEZXNpcmVkIFN0YXRlIENvbmZpZ3VyYXRpb24sIFB5dGhvbiwgR0lULCBhbmQgcmVsYXRlZCB0ZWNobm9sb2dpZXMsIGFuZCBlc3BlY2lhbGx5IGlmIHlvdeKAmXJlIG1vdmluZyB5b3VyIG9yZ2FuaXphdGlvbiB0b3dhcmQgYSBEZXZPcHMgZm9vdGluZywgdGhlbiB0aGlzIGlzIHRoZSA0MDArIGxldmVsIGV2ZW50IHlvdeKAmXZlIGJlZW4gbG9va2luZyBmb3IuIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA1NQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAieHpBWFhqU0ZNRXlJMFVPNF9PMjc5TXpBeDNnIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWFlUmgwOHZEbmFVV0h0cm9lcENqSVMiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMi0xMC0wNlQxOTowNDo0NVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUEdDb25mIE5ZQyAyMDIxIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiUEdDb25mIE5ZQyBpcyBhIG5vbuKAk3Byb2ZpdCwgY29tbXVuaXR54oCTcnVuIGNvbmZlcmVuY2Ugc2VyaWVzIGluIHRoZSBVbml0ZWQgU3RhdGVzIGZvY3VzZWQgb24gYnVzaW5lc3MgdXNlcnMsIGRhdGFiYXNlIHByb2Zlc3Npb25hbHMgYW5kIGRldmVsb3BlcnMgb2YgUG9zdGdyZVNRTCwgdGhlIHdvcmxkJ3MgbW9zdCBhZHZhbmNlZCBvcGVuIHNvdXJjZSBkYXRhYmFzZS5cblxuV2UgdGFyZ2V0IGVudHJlcHJlbmV1cnMsIHRlY2hub2xvZ2lzdHMgYW5kIGRlY2lzaW9u4oCTbWFrZXJzIG9uIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgZGF0YSBtYW5hZ2VtZW50LCBvcGVuIHNvdXJjZSBkYXRhYmFzZSBpbm5vdmF0aW9uIGFuZCBkaXNydXB0aW9uIG9mIHRoZSBkYXRhYmFzZSBpbmR1c3RyeS4gUEdDb25mIE5ZQyBwcm9tb3RlcyB0aGUgYnVzaW5lc3Mgb2YgUG9zdGdyZVNRTCBhcyB3ZWxsIGFzIGl0cyB1c2UgYW5kIGRldmVsb3BtZW50LiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzRyeVFnX19RVjA0L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvNHJ5UWdfX1FWMDQvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvNHJ5UWdfX1FWMDQvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzRyeVFnX19RVjA0L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvNHJ5UWdfX1FWMDQvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJQR0NvbmYgTllDIDIwMjEiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIlBHQ29uZiBOWUMgaXMgYSBub27igJNwcm9maXQsIGNvbW11bml0eeKAk3J1biBjb25mZXJlbmNlIHNlcmllcyBpbiB0aGUgVW5pdGVkIFN0YXRlcyBmb2N1c2VkIG9uIGJ1c2luZXNzIHVzZXJzLCBkYXRhYmFzZSBwcm9mZXNzaW9uYWxzIGFuZCBkZXZlbG9wZXJzIG9mIFBvc3RncmVTUUwsIHRoZSB3b3JsZCdzIG1vc3QgYWR2YW5jZWQgb3BlbiBzb3VyY2UgZGF0YWJhc2UuXG5cbldlIHRhcmdldCBlbnRyZXByZW5ldXJzLCB0ZWNobm9sb2dpc3RzIGFuZCBkZWNpc2lvbuKAk21ha2VycyBvbiB0aGUgbGVhZGluZyBlZGdlIG9mIGRhdGEgbWFuYWdlbWVudCwgb3BlbiBzb3VyY2UgZGF0YWJhc2UgaW5ub3ZhdGlvbiBhbmQgZGlzcnVwdGlvbiBvZiB0aGUgZGF0YWJhc2UgaW5kdXN0cnkuIFBHQ29uZiBOWUMgcHJvbW90ZXMgdGhlIGJ1c2luZXNzIG9mIFBvc3RncmVTUUwgYXMgd2VsbCBhcyBpdHMgdXNlIGFuZCBkZXZlbG9wbWVudC4iCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDM2CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJLc1FRaV8zUkJtcV9sRnBoVmZpSW5OaFFkelUiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YVMxWGVtYUlRNGQ3TmZnbExVMExSbCIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIyLTEwLTA0VDE0OjM2OjMxWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJFbWJlckNvbmYgMjAyMSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlZpcnR1YWwgRW1iZXJDb25mIDIwMjEgTWFyY2ggMjl0aCBhbmQgMzB0aFxuXG5FbWJlckNvbmYgaXMgdGhlIGJlc3QgcGxhY2UgdG8gbWVldCB0aGUgZm9sa3MgYmVoaW5kIHRoZSBtYWdpYy5cblxuWW914oCZbGwgaGVhciBmcm9tIG1lbWJlcnMgb2YgdGhlIEVtYmVyIENvcmUgVGVhbSwgdG9wIGNvbW11bml0eSBjb250cmlidXRvcnMgYW5kIHVzZXJzLCBhbmQgaGVscCBzaGFwZSB0aGUgZnV0dXJlIG9mIEVtYmVyLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0p4WlBoMHNWdXB3L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSnhaUGgwc1Z1cHcvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSnhaUGgwc1Z1cHcvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0p4WlBoMHNWdXB3L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSnhaUGgwc1Z1cHcvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJFbWJlckNvbmYgMjAyMSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiVmlydHVhbCBFbWJlckNvbmYgMjAyMSBNYXJjaCAyOXRoIGFuZCAzMHRoXG5cbkVtYmVyQ29uZiBpcyB0aGUgYmVzdCBwbGFjZSB0byBtZWV0IHRoZSBmb2xrcyBiZWhpbmQgdGhlIG1hZ2ljLlxuXG5Zb3XigJlsbCBoZWFyIGZyb20gbWVtYmVycyBvZiB0aGUgRW1iZXIgQ29yZSBUZWFtLCB0b3AgY29tbXVuaXR5IGNvbnRyaWJ1dG9ycyBhbmQgdXNlcnMsIGFuZCBoZWxwIHNoYXBlIHRoZSBmdXR1cmUgb2YgRW1iZXIuIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAyMwogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiZDY4ZTVrOUd6bmxzS3F1OXVSRzRfVDRneVV3IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWFuM2lzVVBnQl9mRVI0ZU05SnM2cEEiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMi0wOS0yN1QyMjo1MzoxOFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUmFpbHNDb25mIDIwMjEiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9UTkZsamhjb0h2US9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1RORmxqaGNvSHZRL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1RORmxqaGNvSHZRL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9UTkZsamhjb0h2US9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1RORmxqaGNvSHZRL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiUmFpbHNDb25mIDIwMjEiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogNzIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogImczdnlnV0dRWk1LY2NWWDJQOHM4bkI4bnZPNCIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3laaFRWMnFhVkk1Uk82Q0s5LS1tY0Z3IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjItMDgtMzBUMjA6NDE6MThaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkdSQ29uIDIwMjEiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PZXdqOUpNN285RS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL09ld2o5Sk03bzlFL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL09ld2o5Sk03bzlFL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PZXdqOUpNN285RS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL09ld2o5Sk03bzlFL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiR1JDb24gMjAyMSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA2NwogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiOEx1YkJ2aDNQYUxHelVQaUtQM0NSOENOTXVBIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWFCeUQza25LMHhwbjN1M2NyTHEwSjMiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMi0wOC0zMFQxODo0NjowOFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiR1JDb24gMjAyMCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1RKTUhPbERyS05ZL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVEpNSE9sRHJLTlkvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVEpNSE9sRHJLTlkvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1RKTUhPbERyS05ZL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVEpNSE9sRHJLTlkvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJHUkNvbiAyMDIwIiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDMyCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICI2TGFlOVVyZG5NLUJUXzl2blNqNFdSZWVBRDgiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WkFOWXhsODlGOEI5bndDSjI1amhheSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIyLTA4LTI1VDE5OjM1OjMwWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSRWRlcGxveSAyMDE5IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiVGhlIFJlc2lsaWVudCBTb2Npby1UZWNobmljYWwgU3lzdGVtcyBDb25mZXJlbmNlIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvQU9IMmFHOUFFRncvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9BT0gyYUc5QUVGdy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9BT0gyYUc5QUVGdy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvQU9IMmFHOUFFRncvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9BT0gyYUc5QUVGdy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIlJFZGVwbG95IDIwMTkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIlRoZSBSZXNpbGllbnQgU29jaW8tVGVjaG5pY2FsIFN5c3RlbXMgQ29uZmVyZW5jZSIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTYKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIk1jQnoxWTFQS0pDY1ozNVZubUl0ejQ0RW94USIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZVm5XaERRazRSQ1BWbE1XNDBJNnM1IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjItMDgtMDlUMTY6NTk6MjJaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjEiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJGb2N1c2VkIG9uIGZvc3RlcmluZyB0aGUgUnVieSBwcm9ncmFtbWluZyBsYW5ndWFnZSBhbmQgdGhlIHJvYnVzdCBjb21tdW5pdHkgdGhhdCBoYXMgc3BydW5nIHVwIGFyb3VuZCBpdCwgUnVieUNvbmYgYnJpbmdzIHRvZ2V0aGVyIFJ1Ynlpc3RzIGJvdGggZXN0YWJsaXNoZWQgYW5kIG5ldyB0byBkaXNjdXNzIGVtZXJnaW5nIGlkZWFzLCBjb2xsYWJvcmF0ZSwgYW5kIHNvY2lhbGl6ZSBpbiBzb21lIG9mIHRoZSBiZXN0IGxvY2F0aW9ucyBpbiB0aGUgVVMuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvc0F1OFVVblZjX1kvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9zQXU4VVVuVmNfWS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9zQXU4VVVuVmNfWS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvc0F1OFVVblZjX1kvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9zQXU4VVVuVmNfWS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMjEiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIkZvY3VzZWQgb24gZm9zdGVyaW5nIHRoZSBSdWJ5IHByb2dyYW1taW5nIGxhbmd1YWdlIGFuZCB0aGUgcm9idXN0IGNvbW11bml0eSB0aGF0IGhhcyBzcHJ1bmcgdXAgYXJvdW5kIGl0LCBSdWJ5Q29uZiBicmluZ3MgdG9nZXRoZXIgUnVieWlzdHMgYm90aCBlc3RhYmxpc2hlZCBhbmQgbmV3IHRvIGRpc2N1c3MgZW1lcmdpbmcgaWRlYXMsIGNvbGxhYm9yYXRlLCBhbmQgc29jaWFsaXplIGluIHNvbWUgb2YgdGhlIGJlc3QgbG9jYXRpb25zIGluIHRoZSBVUy4iCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDEwMgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiWXRLZVk5blVZT25zNkJQTG9kWEZtNVh2T1VFIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWJkd2dvdHlYV19XSzdTRFFKakJxNWsiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMi0wOC0wOVQxNjoxNDoxM1oiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVzdENvbmYgMjAyMiIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlJ1c3RDb25mIGdhdGhlcnMgUnVzdCBkZXZlbG9wZXJzIGZyb20gYXJvdW5kIHRoZSB3b3JsZCB0byBsZWFybiBhbmQgc2hhcmUgd2l0aCBvbmUgYW5vdGhlci4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS83TmhSYXVRZDEwZy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzdOaFJhdVFkMTBnL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzdOaFJhdVFkMTBnL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS83TmhSYXVRZDEwZy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzdOaFJhdVFkMTBnL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiUnVzdENvbmYgMjAyMiIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiUnVzdENvbmYgZ2F0aGVycyBSdXN0IGRldmVsb3BlcnMgZnJvbSBhcm91bmQgdGhlIHdvcmxkIHRvIGxlYXJuIGFuZCBzaGFyZSB3aXRoIG9uZSBhbm90aGVyLiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTAKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogImVzQkg0b2FrYU9YdTBTcW1nMjRsTjdtQld0byIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZSlg0WERaMmhVdHBJSXdXUlpvdmRpIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjItMDctMDVUMTk6MzQ6MjJaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIiEhQ29uIFdlc3QgMjAxOSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiEhQ29uIChwcm9ub3VuY2VkIOKAnGJhbmcgYmFuZyBjb27igJ0pIFdlc3QgaXMgYSB0d28tZGF5IGNvbmZlcmVuY2Ugb2YgdGVuLW1pbnV0ZSB0YWxrcyBhYm91dCB0aGUgam95LCBleGNpdGVtZW50LCBhbmQgc3VycHJpc2Ugb2YgY29tcHV0aW5nLCBhbmQgdGhlIHdlc3QtY29hc3Qgc3VjY2Vzc29yIHRvICEhQ29uISBJdCBpcyBoZWxkIGluIFNhbnRhIENydXosIENhbGlmb3JuaWEsIG9uIHRoZSBjYW1wdXMgb2YgVUMgU2FudGEgQ3J1eiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2JlVWlmVU5mX1hnL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYmVVaWZVTmZfWGcvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYmVVaWZVTmZfWGcvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2JlVWlmVU5mX1hnL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYmVVaWZVTmZfWGcvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICIhIUNvbiBXZXN0IDIwMTkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiEhQ29uIChwcm9ub3VuY2VkIOKAnGJhbmcgYmFuZyBjb27igJ0pIFdlc3QgaXMgYSB0d28tZGF5IGNvbmZlcmVuY2Ugb2YgdGVuLW1pbnV0ZSB0YWxrcyBhYm91dCB0aGUgam95LCBleGNpdGVtZW50LCBhbmQgc3VycHJpc2Ugb2YgY29tcHV0aW5nLCBhbmQgdGhlIHdlc3QtY29hc3Qgc3VjY2Vzc29yIHRvICEhQ29uISBJdCBpcyBoZWxkIGluIFNhbnRhIENydXosIENhbGlmb3JuaWEsIG9uIHRoZSBjYW1wdXMgb2YgVUMgU2FudGEgQ3J1eiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMzIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIkg1Y0dHRWRKZ2MtYkY4WHBmS3E4eVM0V0FuTSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZaWZCaTlabXdhLVJ4UnVyZ0dfNGZPIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjItMDctMDVUMTU6Mjk6MThaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkRldk9wc0RheXMgUGhpbGFkZWxwaGlhIDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9zM1RpbEJHT2c0TS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3MzVGlsQkdPZzRNL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3MzVGlsQkdPZzRNL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9zM1RpbEJHT2c0TS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3MzVGlsQkdPZzRNL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBQaGlsYWRlbHBoaWEgMjAxOSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxNQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiWUNUQzRQaENtLVFMeEZteGh2RFJEVVFSM3JjIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWE3clBlajlLa0R3VXBCa1FYVDdMdzUiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMi0wNC0xNVQyMTo0MDoxM1oiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRW1iZXJDb25mIDIwMjIiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJFTUJFUkNPTkYgaXMgdGhlIGZsYWdzaGlwIGRpZ2l0YWwgZXZlbnQgb2YgdGhlIEVtYmVyLmpzIGNvbW11bml0eS4gSXQncyB5b3VyIGNoYW5jZSB0byBoZWFyIGZyb20gbWVtYmVycyBvZiB0aGUgRW1iZXIgQ29yZSBUZWFtIGFsb25nIHdpdGggdG9wIGNvbnRyaWJ1dG9ycyBhbmQgdXNlcnMuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvM0JqNEVFb3p0azQvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8zQmo0RUVvenRrNC9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8zQmo0RUVvenRrNC9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvM0JqNEVFb3p0azQvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8zQmo0RUVvenRrNC9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkVtYmVyQ29uZiAyMDIyIiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJFTUJFUkNPTkYgaXMgdGhlIGZsYWdzaGlwIGRpZ2l0YWwgZXZlbnQgb2YgdGhlIEVtYmVyLmpzIGNvbW11bml0eS4gSXQncyB5b3VyIGNoYW5jZSB0byBoZWFyIGZyb20gbWVtYmVycyBvZiB0aGUgRW1iZXIgQ29yZSBUZWFtIGFsb25nIHdpdGggdG9wIGNvbnRyaWJ1dG9ycyBhbmQgdXNlcnMuIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxNgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAicHB0VFByNy05MndERWoxWXFvYTg2azVkVklZIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVliX19wR3RrQThZVm16cVlnZXNwRjIiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMi0wMS0xNFQxNjowMDowOFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBTaWxpY29uIFZhbGxleSAyMDE4IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiV2hldGhlciB5b3UncmUgaW4gZ292ZXJubWVudCwgYWNhZGVtaWEsIG9yIHRoZSBwcml2YXRlIHNlY3RvciwgZGV2b3BzZGF5cyBpcyBmb3IgeW91LiBXaGV0aGVyIHlvdSdyZSBpbiBvcGVyYXRpb25zLCBkZXZlbG9wbWVudCwgUUEsIHNlY3VyaXR5LCBvciBhbnkgb3RoZXIgZGVwYXJ0bWVudCwgZGV2b3BzZGF5cyBpcyBmb3IgeW91LiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0lHVkJRalp2TVFBL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSUdWQlFqWnZNUUEvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSUdWQlFqWnZNUUEvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0lHVkJRalp2TVFBL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSUdWQlFqWnZNUUEvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJEZXZPcHNEYXlzIFNpbGljb24gVmFsbGV5IDIwMTgiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIldoZXRoZXIgeW91J3JlIGluIGdvdmVybm1lbnQsIGFjYWRlbWlhLCBvciB0aGUgcHJpdmF0ZSBzZWN0b3IsIGRldm9wc2RheXMgaXMgZm9yIHlvdS4gV2hldGhlciB5b3UncmUgaW4gb3BlcmF0aW9ucywgZGV2ZWxvcG1lbnQsIFFBLCBzZWN1cml0eSwgb3IgYW55IG90aGVyIGRlcGFydG1lbnQsIGRldm9wc2RheXMgaXMgZm9yIHlvdS4iCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDI1CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJNR2JNTGlIM3AzOWwyU0JDSDRNNVpRa0F6ZE0iLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WTJwNF9BdkF4VHVGVk5oeUlTdkhQZyIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIxLTA5LTE1VDE3OjI0OjAzWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdXN0Q29uZiAyMDIxIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvejlOdnZ5UWxtaEEvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96OU52dnlRbG1oQS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96OU52dnlRbG1oQS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvejlOdnZ5UWxtaEEvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96OU52dnlRbG1oQS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIlJ1c3RDb25mIDIwMjEiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTMKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogImFDRnpwZkR0Q3lrWGV2ZE9iWmpzM0I3Q0FwbyIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3liUFREYktXVnpOMmdoZE5IQUR6Wko3IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjEtMDctMDZUMTg6NDI6MTVaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIiEhQ29uIDIwMjEiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIhIUNvbiAocHJvbm91bmNlZCDigJxiYW5nIGJhbmcgY29u4oCdKSAyMDIxIHdhcyBhIHdlZWsgb2YgdGVuLW1pbnV0ZSB0YWxrcyAod2l0aCBsb3RzIG9mIGJyZWFrcywgb2YgY291cnNlISkgdG8gY2VsZWJyYXRlIHRoZSBqb3lvdXMsIGV4Y2l0aW5nLCBhbmQgc3VycHJpc2luZyBtb21lbnRzIGluIGNvbXB1dGluZy4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9MT0FuNFhJNGgyVS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0xPQW40WEk0aDJVL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0xPQW40WEk0aDJVL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9MT0FuNFhJNGgyVS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0xPQW40WEk0aDJVL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiISFDb24gMjAyMSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiISFDb24gKHByb25vdW5jZWQg4oCcYmFuZyBiYW5nIGNvbuKAnSkgMjAyMSB3YXMgYSB3ZWVrIG9mIHRlbi1taW51dGUgdGFsa3MgKHdpdGggbG90cyBvZiBicmVha3MsIG9mIGNvdXJzZSEpIHRvIGNlbGVicmF0ZSB0aGUgam95b3VzLCBleGNpdGluZywgYW5kIHN1cnByaXNpbmcgbW9tZW50cyBpbiBjb21wdXRpbmcuIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAzOQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiT0t1bWg0b3J6bnlLWHM0bmlIdzk4eW5oY0RNIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVpFSnU4ZXljUEtUUnd6alpweW1BVm8iLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMS0wNC0xOVQxNDo0MDoyOVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVzdENvbmYgMjAyMCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1d6QzdIODNhRFpjL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvV3pDN0g4M2FEWmMvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvV3pDN0g4M2FEWmMvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1d6QzdIODNhRFpjL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvV3pDN0g4M2FEWmMvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJSdXN0Q29uZiAyMDIwIiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDEwCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICItYTdCYTVBanNmMy1LQnlKQlN3NkUwRng3UzgiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WTI4eEVyMFhQclJQTXNMTzgzVV9UaSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTA1LTI4VDE2OjM4OjU4WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICIhIUNvbiAyMDIwIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiISFDb24gKHByb25vdW5jZWQg4oCcYmFuZyBiYW5nIGNvbuKAnSkgMjAyMCB3YXMgdHdvIGRheXMgb2YgdGVuLW1pbnV0ZSB0YWxrcyAod2l0aCBsb3RzIG9mIGJyZWFrcywgb2YgY291cnNlISkgdG8gY2VsZWJyYXRlIHRoZSBqb3lvdXMsIGV4Y2l0aW5nLCBhbmQgc3VycHJpc2luZyBtb21lbnRzIGluIGNvbXB1dGluZy4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8zdkxXbGdtN25UMC9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzN2TFdsZ203blQwL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzN2TFdsZ203blQwL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8zdkxXbGdtN25UMC9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzN2TFdsZ203blQwL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiISFDb24gMjAyMCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiISFDb24gKHByb25vdW5jZWQg4oCcYmFuZyBiYW5nIGNvbuKAnSkgMjAyMCB3YXMgdHdvIGRheXMgb2YgdGVuLW1pbnV0ZSB0YWxrcyAod2l0aCBsb3RzIG9mIGJyZWFrcywgb2YgY291cnNlISkgdG8gY2VsZWJyYXRlIHRoZSBqb3lvdXMsIGV4Y2l0aW5nLCBhbmQgc3VycHJpc2luZyBtb21lbnRzIGluIGNvbXB1dGluZy4iCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDI5CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJzR3VTMmNQS0RpNDAtSGcxWTAtWEhodjFtUWsiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5Wi1UenhseGRMdmg2dERVZlpIcW03NiIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTA0LTI0VDE0OjMyOjI3WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSYWlsc0NvbmYgMjAyMCBDRSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlJhaWxzQ29uZiAyMDIwLjJcbkNPVUNIIEVESVRJT05cbkJyaW5naW5nIHNvbWUgb2YgUmFpbHNDb25mIDIwMjAgdG8geW91ciBjb3VjaCIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL09sdENyOEFXcFd3L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvT2x0Q3I4QVdwV3cvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvT2x0Q3I4QVdwV3cvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL09sdENyOEFXcFd3L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvT2x0Q3I4QVdwV3cvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJSYWlsc0NvbmYgMjAyMCBDRSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiUmFpbHNDb25mIDIwMjAuMlxuQ09VQ0ggRURJVElPTlxuQnJpbmdpbmcgc29tZSBvZiBSYWlsc0NvbmYgMjAyMCB0byB5b3VyIGNvdWNoIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAzMgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiblhORGdveVN3U3FmdjhLZWUwUlhKZ2Z3emhNIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVl1WEtFTzdRZ0pqNzhXdC1SWFNJWVkiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMy0zMFQwNToyMzowM1oiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBOWUMgMjAyMCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkRldm9wc2RheXMgaXMgYSB3b3JsZHdpZGUgc2VyaWVzIG9mIHRlY2huaWNhbCBjb25mZXJlbmNlcyBjb3ZlcmluZyB0b3BpY3Mgb2Ygc29mdHdhcmUgZGV2ZWxvcG1lbnQsIElUIGluZnJhc3RydWN0dXJlIG9wZXJhdGlvbnMsIGFuZCB0aGUgaW50ZXJzZWN0aW9uIGJldHdlZW4gdGhlbS4gRWFjaCBldmVudCBpcyBydW4gYnkgdm9sdW50ZWVycyBmcm9tIHRoZSBsb2NhbCBhcmVhLlxuXG5Nb3N0IGRldm9wc2RheXMgZXZlbnRzIGZlYXR1cmUgYSBjb21iaW5hdGlvbiBvZiBjdXJhdGVkIHRhbGtzIChzZWUgb3BlbiBDYWxscyBmb3IgUHJvcG9zYWxzKSBhbmQgc2VsZiBvcmdhbml6ZWQgb3BlbiBzcGFjZSBjb250ZW50LiBUb3BpY3Mgb2Z0ZW4gaW5jbHVkZSBhdXRvbWF0aW9uLCB0ZXN0aW5nLCBzZWN1cml0eSwgYW5kIG9yZ2FuaXphdGlvbmFsIGN1bHR1cmUuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdURwcDYwSkFnS0UvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91RHBwNjBKQWdLRS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91RHBwNjBKQWdLRS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdURwcDYwSkFnS0Uvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91RHBwNjBKQWdLRS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkRldk9wc0RheXMgTllDIDIwMjAiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRldm9wc2RheXMgaXMgYSB3b3JsZHdpZGUgc2VyaWVzIG9mIHRlY2huaWNhbCBjb25mZXJlbmNlcyBjb3ZlcmluZyB0b3BpY3Mgb2Ygc29mdHdhcmUgZGV2ZWxvcG1lbnQsIElUIGluZnJhc3RydWN0dXJlIG9wZXJhdGlvbnMsIGFuZCB0aGUgaW50ZXJzZWN0aW9uIGJldHdlZW4gdGhlbS4gRWFjaCBldmVudCBpcyBydW4gYnkgdm9sdW50ZWVycyBmcm9tIHRoZSBsb2NhbCBhcmVhLlxuXG5Nb3N0IGRldm9wc2RheXMgZXZlbnRzIGZlYXR1cmUgYSBjb21iaW5hdGlvbiBvZiBjdXJhdGVkIHRhbGtzIChzZWUgb3BlbiBDYWxscyBmb3IgUHJvcG9zYWxzKSBhbmQgc2VsZiBvcmdhbml6ZWQgb3BlbiBzcGFjZSBjb250ZW50LiBUb3BpY3Mgb2Z0ZW4gaW5jbHVkZSBhdXRvbWF0aW9uLCB0ZXN0aW5nLCBzZWN1cml0eSwgYW5kIG9yZ2FuaXphdGlvbmFsIGN1bHR1cmUuIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAyNQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAickJ6cnlTQklTRWJaWjM4ZnVlM0F5VGZlZlZNIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVoweTJETG9pXzJXSGNITzVnQVR5TXgiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMy0yNlQxOToxNjo0MFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRW1iZXJDb25mIDIwMjAiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJFbWJlckNvbmYgaXMgdGhlIGJlc3QgcGxhY2UgdG8gbWVldCB0aGUgZm9sa3MgYmVoaW5kIHRoZSBtYWdpYy5cblxuWW914oCZbGwgaGVhciBmcm9tIG1lbWJlcnMgb2YgdGhlIEVtYmVyIENvcmUgVGVhbSwgdG9wIGNvbW11bml0eSBjb250cmlidXRvcnMgYW5kIHVzZXJzLCBhbmQgaGVscCBzaGFwZSB0aGUgZnV0dXJlIG9mIEVtYmVyLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1VXNE10b0V4c1lnL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVVc0TXRvRXhzWWcvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVVc0TXRvRXhzWWcvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1VXNE10b0V4c1lnL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVVc0TXRvRXhzWWcvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJFbWJlckNvbmYgMjAyMCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRW1iZXJDb25mIGlzIHRoZSBiZXN0IHBsYWNlIHRvIG1lZXQgdGhlIGZvbGtzIGJlaGluZCB0aGUgbWFnaWMuXG5cbllvdeKAmWxsIGhlYXIgZnJvbSBtZW1iZXJzIG9mIHRoZSBFbWJlciBDb3JlIFRlYW0sIHRvcCBjb21tdW5pdHkgY29udHJpYnV0b3JzIGFuZCB1c2VycywgYW5kIGhlbHAgc2hhcGUgdGhlIGZ1dHVyZSBvZiBFbWJlci4iCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDI2CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICIzRWVFcHhiYnltbXdRS21aX2xJRklFa0lzTzgiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WWdCVWtYWmwzU1BNdkhteXdUR3Z3ayIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTAzLTIzVDE1OjU1OjE4WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICIhIUNvbiBXZXN0IDIwMjAiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9QaFlPRERSOEJzZy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1BoWU9ERFI4QnNnL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1BoWU9ERFI4QnNnL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9QaFlPRERSOEJzZy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1BoWU9ERFI4QnNnL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiISFDb24gV2VzdCAyMDIwIiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDMwCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJJWXdJZ3hoSmhQLUNNYmE3bzZsdzlNN3JSZWMiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WUMybFp6d1R2RWVKWGdobTRZbTRaWCIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTAyLTE5VDE3OjI4OjQyWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJCaXJtaW5naGFtIG9uIFJhaWxzIDIwMjAiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJCaXJtaW5naGFtIG9uIFJhaWxzIDIwMjAhIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRXlwUlNMZkt2YWsvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FeXBSU0xmS3Zhay9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FeXBSU0xmS3Zhay9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRXlwUlNMZkt2YWsvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FeXBSU0xmS3Zhay9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkJpcm1pbmdoYW0gb24gUmFpbHMgMjAyMCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiQmlybWluZ2hhbSBvbiBSYWlscyAyMDIwISIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogOAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAieFNObnV3QklXTldKVTJsQkxUZVNtY0ZoYzlJIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWFkZVRGSDY3ODRWY2x2YWNvLUhDSUIiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yOVQxNzo1ODozMloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiTVdSQyAyMDA3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRHZSU0xVa3RvZzQvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9EdlJTTFVrdG9nNC9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9EdlJTTFVrdG9nNC9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRHZSU0xVa3RvZzQvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiTVdSQyAyMDA3IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDEyCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJvZnZTUHY0QjF3aERDanVndF9FbWt1cDZuUjQiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YlFFWThrWmVqazhnTmZ2WXI4NUhxNyIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTAxLTI5VDE3OjQxOjUzWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJKUnVieSAyMDA5IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkva2hnUjNmTFVuM1EvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9raGdSM2ZMVW4zUS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9raGdSM2ZMVW4zUS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkva2hnUjNmTFVuM1Evc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9raGdSM2ZMVW4zUS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkpSdWJ5IDIwMDkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiQXdOVERRaWxvOU1HblJLd0pvMng4ckhOUkI4IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWJ1M0ttYzFXVmttdmFHeWZ5SDVYbWoiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yOVQxNzozNzo1OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiTEEgUnVieUNvbmYgMjAxMCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2hxSzRvN09JQTU0L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvaHFLNG83T0lBNTQvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvaHFLNG83T0lBNTQvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2hxSzRvN09JQTU0L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvaHFLNG83T0lBNTQvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJMQSBSdWJ5Q29uZiAyMDEwIiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDUKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogInpJT1E1cVQ4R2RQM0F4bFkxQmdVbWdwQmtkZyIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lhX0RZdEdTbkowS3RDcEk3RTc1OEFyIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjAtMDEtMjlUMTY6MjE6NTFaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIk1hZGlzb24gUnVieSAyMDExIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOGxhVGZGSm83czAvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS84bGFUZkZKbzdzMC9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS84bGFUZkZKbzdzMC9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOGxhVGZGSm83czAvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS84bGFUZkZKbzdzMC9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIk1hZGlzb24gUnVieSAyMDExIiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDYKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIk90ZkhFWWhIUk10V1FpOGppVTdrLXZMSHV1SSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3laRXRIMDdyUmZ3WTJJYUFfSjViLUVxIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjAtMDEtMjhUMjA6MzM6MjFaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkFsb2hhIFJ1YnlDb25mIDIwMTIiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rdWZYaE5rbTVXVS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2t1ZlhoTmttNVdVL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2t1ZlhoTmttNVdVL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rdWZYaE5rbTVXVS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2t1ZlhoTmttNVdVL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiQWxvaGEgUnVieUNvbmYgMjAxMiIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAyNQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAibDVJbnVXRDk2WTlTOWw3aTJvLVhwOXVMYUVzIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVk4ZXRieVFDS3dCUkRLOHRHOFM5bnkiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yOFQxOTozOTowNloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiSFRNTCA1LnR4IDIwMTMiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9IMDBfQkdSa0JSTS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0gwMF9CR1JrQlJNL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0gwMF9CR1JrQlJNL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9IMDBfQkdSa0JSTS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0gwMF9CR1JrQlJNL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiSFRNTCA1LnR4IDIwMTMiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTgKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogInlsLVlKRmx0TGNhNDdyR3J0S0xXX05nUXhNcyIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lhSEVkckd2cjQ3NVZ3YzJZQ0RIaXI4IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjAtMDEtMjhUMTk6MjE6NDdaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkJpZyBSdWJ5IDIwMTMiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92SUhkaGFGMlIydy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3ZJSGRoYUYyUjJ3L21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3ZJSGRoYUYyUjJ3L2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92SUhkaGFGMlIydy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3ZJSGRoYUYyUjJ3L21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiQmlnIFJ1YnkgMjAxMyIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxNAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAib0VfWHRKWF9VMXJwOHM2RFNhNTRFaG1EZkZjIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVkwalBKT2VCT3JGNlBteTBQNUJpODEiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yOFQxOTowOToyNloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVieSBvbiBBbGVzIDIwMTMiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9LZ0Jxc3dQZUpRVS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0tnQnFzd1BlSlFVL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0tnQnFzd1BlSlFVL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9LZ0Jxc3dQZUpRVS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0tnQnFzd1BlSlFVL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiUnVieSBvbiBBbGVzIDIwMTMiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTUKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIlpVQnlXM1g2TXBfaXBsSExlVGRzdWNRSmRDRSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lhenZjNEliLVRSeUdpcndpMXoxeXdjIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjAtMDEtMjhUMTg6NDY6MTZaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIk1XUkMgMjAxMyIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2Rpc2pGajRydUhnL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZGlzakZqNHJ1SGcvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZGlzakZqNHJ1SGcvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2Rpc2pGajRydUhnL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZGlzakZqNHJ1SGcvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJNV1JDIDIwMTMiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMzAKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIlZzTmRIUkRzTmZfVWxNZGp6MnBwQ0txUkc5NCIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZdmplNFB2cDhsUERsOFFkMVZDdDBWIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjAtMDEtMjhUMTg6MzU6NDlaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkZhcm1ob3VzZSBDb25mIDQiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS84eXJMSzJaam54TS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzh5ckxLMlpqbnhNL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzh5ckxLMlpqbnhNL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS84eXJMSzJaam54TS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzh5ckxLMlpqbnhNL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiRmFybWhvdXNlIENvbmYgNCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA5CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJJaWxwM29zcXBzYnc0NDh1TXVZaVJfekdQWGsiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5Ym5PeE9iTmJUYng2UHl5V3JUR0pQOSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTAxLTI4VDE2OjU1OjA5WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJMb25lIFN0YXIgUnVieSBDb25mIDIwMTMiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FOFlJN2hVVVN5cy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0U4WUk3aFVVU3lzL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0U4WUk3aFVVU3lzL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FOFlJN2hVVVN5cy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0U4WUk3aFVVU3lzL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiTG9uZSBTdGFyIFJ1YnkgQ29uZiAyMDEzIiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDI3CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJ3UU1iOVpfSTJjNXBjNzdPcmVuRFpZMURlbjgiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WlJIOVc0M0NRYVp5Xzlxa2c2QmppSSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTAxLTI4VDE2OjM5OjQ5WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJNYWRpc29uIFJ1YnkgMjAxMyIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzh0cDZJdWdIV3BzL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOHRwNkl1Z0hXcHMvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOHRwNkl1Z0hXcHMvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzh0cDZJdWdIV3BzL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvOHRwNkl1Z0hXcHMvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJNYWRpc29uIFJ1YnkgMjAxMyIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxOAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiSXFBU3NlUUZnMUk5alRFWVI3eFk3cUp2ckw4IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVpBNUE3UEoxX0s5VWc1eWRndHhkLXEiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yN1QxODo1MjowOVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUm9ja3kgTW91bnRhaW4gUnVieSAyMDEzIiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkva0xMd0p3czFuZncvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rTEx3SndzMW5mdy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rTEx3SndzMW5mdy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkva0xMd0p3czFuZncvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9rTEx3SndzMW5mdy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIlJvY2t5IE1vdW50YWluIFJ1YnkgMjAxMyIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAyNQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiTnllWmZFNTMtQ2Yxc1FuZnFPMmtLb01hdnk0IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVpEeVNCQjVXbUZPUzhld29aME9KODIiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yN1QxODozNjozNloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUGFjaWZpYyBOb3J0aHdlc3QgU2NhbGEgMjAxMyIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1RTMWxwS0JNa2dnL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVFMxbHBLQk1rZ2cvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVFMxbHBLQk1rZ2cvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1RTMWxwS0JNa2dnL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVFMxbHBLQk1rZ2cvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJQYWNpZmljIE5vcnRod2VzdCBTY2FsYSAyMDEzIiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDEwCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJBS3ZUcHBhdnRLNW01cnlOcEFONVA0VEg0c1kiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YWp6RHVUUl9CajdYcUw0TU9wRktfZCIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTAxLTI3VDE3OjU3OjM3WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJGYXJtaG91c2UgQ29uZiA1IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYk9USmVvdU1MRGsvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9iT1RKZW91TUxEay9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9iT1RKZW91TUxEay9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYk9USmVvdU1MRGsvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9iT1RKZW91TUxEay9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkZhcm1ob3VzZSBDb25mIDUiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMjEKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIlY0WDhhZnAzQ3VzY2pmRWJPUXFYSWQ1UmtlRSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZQ3NNdkNjc2tlQmU5RGtTU3Qwb1IyIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjAtMDEtMjdUMTY6NTA6MDJaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlDb25mIDIwMTMiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS80cE9iY2VnYk1SRS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzRwT2JjZWdiTVJFL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzRwT2JjZWdiTVJFL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS80cE9iY2VnYk1SRS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzRwT2JjZWdiTVJFL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAxMyIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA0OAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAicFU1TFRCTmFmMjktMW9XekVIZ2pDUHQzN1ljIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWJsUFVSdEpvMThId0VZRGF5QmlKSi0iLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yNFQxODo0NDozOVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiR2FyZGVuIENpdHkgUnVieSAyMDE0IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvNExNV3NGYmo2anMvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS80TE1Xc0ZiajZqcy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS80TE1Xc0ZiajZqcy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvNExNV3NGYmo2anMvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS80TE1Xc0ZiajZqcy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkdhcmRlbiBDaXR5IFJ1YnkgMjAxNCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxNwogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiWXJ0c1h5NVdCYi1saF9RVjRERndPeGhmU0VnIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVlpZE5oM201N2h5RGpqS0dDOS1yYmoiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yNFQxNjo1Mzo1NVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiTEEgUnVieUNvbmYgMjAxNCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL180ajBCaC1RdHJjL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvXzRqMEJoLVF0cmMvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvXzRqMEJoLVF0cmMvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL180ajBCaC1RdHJjL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvXzRqMEJoLVF0cmMvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJMQSBSdWJ5Q29uZiAyMDE0IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDkKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIk1IemlkVmtLejBMNi1ZbFBvbWF0T0MzbWM5byIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3liRFFzZEhQMWU3bXNHRWFsVVBhVjA2IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjAtMDEtMjRUMTY6NDA6MjNaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkJpZyBSdWJ5IDIwMTQiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS85UExZNFRXbzdmMC9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzlQTFk0VFdvN2YwL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzlQTFk0VFdvN2YwL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS85UExZNFRXbzdmMC9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzlQTFk0VFdvN2YwL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiQmlnIFJ1YnkgMjAxNCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxOAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiWUtWMFpDOXZRR2hZQUluWmtibzZVQW5VV004IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVlhUnhZMld5Q1hZcDU4VUl6T0xlaEsiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yNFQxNjoyMjo1NVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiS29kLmlvIDIwMTQiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93dmU2MmxZcng0OC9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3d2ZTYybFlyeDQ4L21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3d2ZTYybFlyeDQ4L2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93dmU2MmxZcng0OC9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3d2ZTYybFlyeDQ4L21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiS29kLmlvIDIwMTQiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTgKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIk03YzFZLVYtb250R2xqenBtd2JWV0RrZlVUZyIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZME0yZWJyX3JDelBiS1M1bml2Q3lpIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjAtMDEtMjRUMTY6MTA6MzNaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIk1vdW50YWluV2VzdCBKYXZhU2NyaXB0IDIwMTQiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9oM0trc0g4Z2ZjUS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2gzS2tzSDhnZmNRL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2gzS2tzSDhnZmNRL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9oM0trc0g4Z2ZjUS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2gzS2tzSDhnZmNRL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiTW91bnRhaW5XZXN0IEphdmFTY3JpcHQgMjAxNCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxOQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiWU9tRlI5RWFzMGc5UDdRTDUyMjVJUTVSdTc4IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVpzRVhUYnJtSWwxdm1sVkVxS2xOclEiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yNFQxNjowMjo1N1oiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiTW91bnRhaW5XZXN0IERldk9wcyAyMDE0IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVHRKNlE0b2dqV3cvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9UdEo2UTRvZ2pXdy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9UdEo2UTRvZ2pXdy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVHRKNlE0b2dqV3cvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9UdEo2UTRvZ2pXdy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIk1vdW50YWluV2VzdCBEZXZPcHMgMjAxNCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxMAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAidndtMW9vdjR4eG1uSkcwcWY3OVZRdzE1YngwIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWJ3dS1OQnlOb2VPckR1QkJ4SERaLXEiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yNFQxNTo1MToxOVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiTVdSQyAyMDE0IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvcElDMzV0c2ZVbXcvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wSUMzNXRzZlVtdy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wSUMzNXRzZlVtdy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvcElDMzV0c2ZVbXcvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9wSUMzNXRzZlVtdy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIk1XUkMgMjAxNCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAyMAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiRGg2T0lvMGwtNTR3cUJsaURrc2xNTVZ0aUhJIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVpKYThybk5HX0JHNVVhTmFSVjBDTEgiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yM1QxOTozNDoxMFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiSlMuR2VvIDIwMTQiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8ySDlnMkRCSXVMQS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzJIOWcyREJJdUxBL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzJIOWcyREJJdUxBL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8ySDlnMkRCSXVMQS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzJIOWcyREJJdUxBL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiSlMuR2VvIDIwMTQiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogOQogICAgICB9CiAgICB9CiAgXQp9Cg==\n  recorded_at: Thu, 08 Jun 2023 18:32:24 GMT\n- request:\n    method: get\n    uri: https://youtube.googleapis.com/youtube/v3/playlists?channelId=UCWnPjmqvljcafA0z2U1fwKQ&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&pageToken=CDIQAA&part=snippet,contentDetails\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Thu, 08 Jun 2023 18:32:24 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      Cache-Control:\n      - private\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: !binary |-\n        ewogICJraW5kIjogInlvdXR1YmUjcGxheWxpc3RMaXN0UmVzcG9uc2UiLAogICJldGFnIjogInNmQlVoRXI5V1dKTFZOa2tMTVNLbkx1VDA3OCIsCiAgIm5leHRQYWdlVG9rZW4iOiAiQ0dRUUFBIiwKICAicHJldlBhZ2VUb2tlbiI6ICJDRElRQVEiLAogICJwYWdlSW5mbyI6IHsKICAgICJ0b3RhbFJlc3VsdHMiOiAzMTgsCiAgICAicmVzdWx0c1BlclBhZ2UiOiA1MAogIH0sCiAgIml0ZW1zIjogWwogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAicUVvTDBwS185UjJGcDd3NS1Sdjh6cU81dS13IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWJmenVsc1JURVBhZU45X2lUbWVKUFIiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yM1QxOToyMDoyN1oiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiR29HYVJ1Q28gMjAxNCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2VpX3RhbnUzVXlRL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZWlfdGFudTNVeVEvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZWlfdGFudTNVeVEvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2VpX3RhbnUzVXlRL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZWlfdGFudTNVeVEvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJHb0dhUnVDbyAyMDE0IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDE3CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJmbVRRWlhNVllvWmxxeWc5aDAwaW15ZC1tbFUiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WXc2cGJ3N2JJc2Z4cUpLNkQyei03RyIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTAxLTIzVDE3OjU5OjEzWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJHYXJkZW4gQ2l0eSBSdWJ5IDIwMTUiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9kSGlFNmVnSlBqWS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2RIaUU2ZWdKUGpZL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2RIaUU2ZWdKUGpZL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9kSGlFNmVnSlBqWS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2RIaUU2ZWdKUGpZL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiR2FyZGVuIENpdHkgUnVieSAyMDE1IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDEwCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJWdmlsR2E1M2tCZ2xITnBoeVpueG5CVDhWTnMiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5Yk1QcHJsSXhVSndScWZ0My13eHFFRyIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTAxLTIzVDE3OjM3OjQ5WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJKVUMgVS5TIEVhc3QgMjAxNSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3RGSzk3NjRFakZzL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdEZLOTc2NEVqRnMvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdEZLOTc2NEVqRnMvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3RGSzk3NjRFakZzL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdEZLOTc2NEVqRnMvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJKVUMgVS5TIEVhc3QgMjAxNSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAzMQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiNHRLVGJSR2hvcEp1YVMzLVp3UjVRSW0zTVRZIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWI2TVU2SDhQcmF0TWhWNGJXVUw4YnYiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAyMC0wMS0yM1QxNzoyNjozMFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiR09SVUNPIDIwMTUiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9hSEpFekl6aGJmOC9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2FISkV6SXpoYmY4L21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2FISkV6SXpoYmY4L2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9hSEpFekl6aGJmOC9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2FISkV6SXpoYmY4L21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiR09SVUNPIDIwMTUiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTMKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIl83bnNVR3NxMW5GZ0c3LVZuVEtiRXE5VE9yWSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZVHdVQVFGd1BEMkdSYkg4OUFKVXlHIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMjAtMDEtMjNUMTY6NDk6NTNaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkFsdGVyQ29uZiBEZXRyb2l0IDIwMTUiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9VcFNLQ1JLYi0tRS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1VwU0tDUktiLS1FL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1VwU0tDUktiLS1FL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9VcFNLQ1JLYi0tRS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1VwU0tDUktiLS1FL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiQWx0ZXJDb25mIERldHJvaXQgMjAxNSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA1CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJhVVNZS3R4TVdXNy1kUmpfaGJUX1FaX2hrcE0iLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YVlVODlBWENrWjRTQzIyQUUtVTd1SSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDIwLTAxLTIyVDE4OjAxOjQ0WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSZWREb3RSdWJ5IDIwMTciLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8zTlJUelRjY29JMC9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzNOUlR6VGNjb0kwL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzNOUlR6VGNjb0kwL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8zTlJUelRjY29JMC9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzNOUlR6VGNjb0kwL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiUmVkRG90UnVieSAyMDE3IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDIwCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJuNFlYd1F2SW5hLXF2dmRXYUFyeFhXdnBjdW8iLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YUpLS091bEFteWktejMyM09QWTVtVyIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTEyLTA2VDAxOjA3OjA1WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJTb2xpZHVzQ29uZiAyMDE5IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiTGVhcm4uIFNoYXJlLiBOZXR3b3JrLlxuXG5Tb2xpZHVzIENvbmYgaXMgYSBjb25mZXJlbmNlIGhlbGQgZm9yIFNvbGlkdXMgcHJvZ3JhbW1lcnMsIFJhaWxzIHVzZXJzLCBSdWJ5IGxvdmVycywgYW5kIGVDb21tZXJjZSBkZXZlbG9wZXJzLiBBdCBTb2xpZHVzIENvbmYgMjAxOSwgd2Ugd2lsbCBiZSBjb250aW51aW5nIHRoZSB0cmFkaXRpb24gb2Ygc2hhcmluZyBrbm93bGVkZ2UgYW5kIGdvYWxzIGZvciB0aGUgU29saWR1cyBjb21tdW5pdHkgYW5kIGhlYXJpbmcgZnJvbSBzb21lIGV4dGVybmFsIHNwZWFrZXJzIGFib3V0IHJlbGV2YW50IGVDb21tZXJjZSBhbmQgZW5naW5lZXJpbmcgY2hhbGxlbmdlcy4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9pdHYtWXQtZVA3cy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2l0di1ZdC1lUDdzL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2l0di1ZdC1lUDdzL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9pdHYtWXQtZVA3cy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2l0di1ZdC1lUDdzL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiU29saWR1c0NvbmYgMjAxOSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiTGVhcm4uIFNoYXJlLiBOZXR3b3JrLlxuXG5Tb2xpZHVzIENvbmYgaXMgYSBjb25mZXJlbmNlIGhlbGQgZm9yIFNvbGlkdXMgcHJvZ3JhbW1lcnMsIFJhaWxzIHVzZXJzLCBSdWJ5IGxvdmVycywgYW5kIGVDb21tZXJjZSBkZXZlbG9wZXJzLiBBdCBTb2xpZHVzIENvbmYgMjAxOSwgd2Ugd2lsbCBiZSBjb250aW51aW5nIHRoZSB0cmFkaXRpb24gb2Ygc2hhcmluZyBrbm93bGVkZ2UgYW5kIGdvYWxzIGZvciB0aGUgU29saWR1cyBjb21tdW5pdHkgYW5kIGhlYXJpbmcgZnJvbSBzb21lIGV4dGVybmFsIHNwZWFrZXJzIGFib3V0IHJlbGV2YW50IGVDb21tZXJjZSBhbmQgZW5naW5lZXJpbmcgY2hhbGxlbmdlcy4iCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDEzCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJaOW9vVG9uOGpPZVdkQ0haMkhlM2NuTnpHUlUiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WkRFOG5GckthcWtwZC1YSzRodXlnVSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTExLTI2VDIwOjA5OjI5WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdWJ5Q29uZiAyMDE5IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiRm9jdXNlZCBvbiBmb3N0ZXJpbmcgdGhlIFJ1YnkgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgYW5kIHRoZSByb2J1c3QgY29tbXVuaXR5IHRoYXQgaGFzIHNwcnVuZyB1cCBhcm91bmQgaXQsIFJ1YnlDb25mIGJyaW5ncyB0b2dldGhlciBSdWJ5aXN0cyBib3RoIGVzdGFibGlzaGVkIGFuZCBuZXcgdG8gZGlzY3VzcyBlbWVyZ2luZyBpZGVhcywgY29sbGFib3JhdGUsIGFuZCBzb2NpYWxpemUgaW4gc29tZSBvZiB0aGUgYmVzdCBsb2NhdGlvbnMgaW4gdGhlIFVTLiBDb21lIGpvaW4gdXMgaW4gTG9zIEFuZ2VsZXMgZm9yIHdoYXQgd2lsbCBzdXJlbHkgYmUgdGhlIGJlc3QgUnVieUNvbmYgeWV0IVxuXG5PbmUgb2Ygb3VyIGtleSBnb2FscyBmb3IgUnVieUNvbmYgaXMgdG8gcHJvdmlkZSBhbiBpbmNsdXNpdmUgYW5kIHdlbGNvbWluZyBleHBlcmllbmNlIGZvciBhbGwgcGFydGljaXBhbnRzLiBUbyB0aGF0IGVuZCwgd2UgaGF2ZSBhbiBhbnRpLWhhcmFzc21lbnQgcG9saWN5IHRoYXQgd2UgcmVxdWlyZSBBTEwgYXR0ZW5kZWVzLCBzcGVha2Vycywgc3BvbnNvcnMsIHZvbHVudGVlcnMsIGFuZCBzdGFmZiB0byBjb21wbHkgd2l0aCDigJQgbm8gZXhjZXB0aW9ucy4iLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8yZzlSN1BVQ0VYby9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzJnOVI3UFVDRVhvL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzJnOVI3UFVDRVhvL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8yZzlSN1BVQ0VYby9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzJnOVI3UFVDRVhvL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiUnVieUNvbmYgMjAxOSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRm9jdXNlZCBvbiBmb3N0ZXJpbmcgdGhlIFJ1YnkgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgYW5kIHRoZSByb2J1c3QgY29tbXVuaXR5IHRoYXQgaGFzIHNwcnVuZyB1cCBhcm91bmQgaXQsIFJ1YnlDb25mIGJyaW5ncyB0b2dldGhlciBSdWJ5aXN0cyBib3RoIGVzdGFibGlzaGVkIGFuZCBuZXcgdG8gZGlzY3VzcyBlbWVyZ2luZyBpZGVhcywgY29sbGFib3JhdGUsIGFuZCBzb2NpYWxpemUgaW4gc29tZSBvZiB0aGUgYmVzdCBsb2NhdGlvbnMgaW4gdGhlIFVTLiBDb21lIGpvaW4gdXMgaW4gTG9zIEFuZ2VsZXMgZm9yIHdoYXQgd2lsbCBzdXJlbHkgYmUgdGhlIGJlc3QgUnVieUNvbmYgeWV0IVxuXG5PbmUgb2Ygb3VyIGtleSBnb2FscyBmb3IgUnVieUNvbmYgaXMgdG8gcHJvdmlkZSBhbiBpbmNsdXNpdmUgYW5kIHdlbGNvbWluZyBleHBlcmllbmNlIGZvciBhbGwgcGFydGljaXBhbnRzLiBUbyB0aGF0IGVuZCwgd2UgaGF2ZSBhbiBhbnRpLWhhcmFzc21lbnQgcG9saWN5IHRoYXQgd2UgcmVxdWlyZSBBTEwgYXR0ZW5kZWVzLCBzcGVha2Vycywgc3BvbnNvcnMsIHZvbHVudGVlcnMsIGFuZCBzdGFmZiB0byBjb21wbHkgd2l0aCDigJQgbm8gZXhjZXB0aW9ucy4iCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDY5CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICItVzZXaHNxOVB2V2RiWDZoMTVNeGhtbmlzaUUiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YWFGMXBtMU1mUW1fZzFURjJDUDFKWiIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTExLTA1VDA0OjQ2OjA2WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJHUkNvbiAyMDE5IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiR1JDb24gaXMgdGhlIGFubnVhbCBjb25mZXJlbmNlIGZvciB0aGUgR05VIFJhZGlvIHByb2plY3QgJiBjb21tdW5pdHksIGFuZCBoYXMgZXN0YWJsaXNoZWQgaXRzZWxmIGFzIG9uZSBvZiB0aGUgcHJlbWllciBpbmR1c3RyeSBldmVudHMgZm9yIFNvZnR3YXJlIFJhZGlvLiBJdCBpcyBhIHdlZWstbG9uZyBjb25mZXJlbmNlIHRoYXQgaW5jbHVkZXMgaGlnaC1xdWFsaXR5IHRlY2huaWNhbCBjb250ZW50IGFuZCB2YWx1YWJsZSBuZXR3b3JraW5nIG9wcG9ydHVuaXRpZXMuIEdSQ29uIGlzIGEgdmVudWUgdGhhdCBoaWdobGlnaHRzIGRlc2lnbiwgaW1wbGVtZW50YXRpb24sIGFuZCB0aGVvcnkgdGhhdCBoYXMgYmVlbiBwcmFjdGljYWxseSBhcHBsaWVkIGluIGEgdXNlZnVsIHdheS4gR1JDb24gYXR0ZW5kZWVzIGNvbWUgZnJvbSBhIGxhcmdlIHZhcmlldHkgb2YgYmFja2dyb3VuZHMsIGluY2x1ZGluZyBpbmR1c3RyeSwgYWNhZGVtaWEsIGdvdmVybm1lbnQsIGFuZCBob2JieWlzdHMuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdjJVX2QwTHExTWMvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92MlVfZDBMcTFNYy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92MlVfZDBMcTFNYy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdjJVX2QwTHExTWMvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS92MlVfZDBMcTFNYy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkdSQ29uIDIwMTkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIkdSQ29uIGlzIHRoZSBhbm51YWwgY29uZmVyZW5jZSBmb3IgdGhlIEdOVSBSYWRpbyBwcm9qZWN0ICYgY29tbXVuaXR5LCBhbmQgaGFzIGVzdGFibGlzaGVkIGl0c2VsZiBhcyBvbmUgb2YgdGhlIHByZW1pZXIgaW5kdXN0cnkgZXZlbnRzIGZvciBTb2Z0d2FyZSBSYWRpby4gSXQgaXMgYSB3ZWVrLWxvbmcgY29uZmVyZW5jZSB0aGF0IGluY2x1ZGVzIGhpZ2gtcXVhbGl0eSB0ZWNobmljYWwgY29udGVudCBhbmQgdmFsdWFibGUgbmV0d29ya2luZyBvcHBvcnR1bml0aWVzLiBHUkNvbiBpcyBhIHZlbnVlIHRoYXQgaGlnaGxpZ2h0cyBkZXNpZ24sIGltcGxlbWVudGF0aW9uLCBhbmQgdGhlb3J5IHRoYXQgaGFzIGJlZW4gcHJhY3RpY2FsbHkgYXBwbGllZCBpbiBhIHVzZWZ1bCB3YXkuIEdSQ29uIGF0dGVuZGVlcyBjb21lIGZyb20gYSBsYXJnZSB2YXJpZXR5IG9mIGJhY2tncm91bmRzLCBpbmNsdWRpbmcgaW5kdXN0cnksIGFjYWRlbWlhLCBnb3Zlcm5tZW50LCBhbmQgaG9iYnlpc3RzLiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogNDQKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogImRaRHdCbkFvWG9uanJwRDlDWS1jNU90djZkdyIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3laaFBiWnpCOExCTy1wUXdhUTVOS0NUIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMTEtMDNUMDI6MzQ6MDdaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkRldk9wc0RheXMgUGhpbGFkZWxwaGlhIDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Va096Y1JSRTVUWS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1VrT3pjUlJFNVRZL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1VrT3pjUlJFNVRZL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9Va096Y1JSRTVUWS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1VrT3pjUlJFNVRZL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBQaGlsYWRlbHBoaWEgMjAxOSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxNQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiUE9VdUFMNGp4Qmo4bEhOeFpjX2lDMlZNT1RZIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWJoV2doOEpQVWE4d2Vfa1lnbEVhbjciLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0xMC0yMlQxODowNTo1NVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRGphbmdvQ29uIFVTIDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9kOUJBVUJFeUZnTS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2Q5QkFVQkV5RmdNL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2Q5QkFVQkV5RmdNL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9kOUJBVUJFeUZnTS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2Q5QkFVQkV5RmdNL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiRGphbmdvQ29uIFVTIDIwMTkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogNDMKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIkE3NHZrMW10MldoYzV4aFZzQmNObk81WHdpTSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3laMTZPT040aHVTUlBpYUc4VnVvUjExIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMTAtMjJUMTc6NTk6MTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlB5Q29sb3JhZG8gMjAxOSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1p0Y01GMmZfNWpjL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWnRjTUYyZl81amMvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWnRjTUYyZl81amMvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1p0Y01GMmZfNWpjL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWnRjTUYyZl81amMvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJQeUNvbG9yYWRvIDIwMTkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMjIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIllodkVUdnhKaDNKVXkwTl9sSk5xUjNsRXA3ayIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3laaHp2cnZWY3NjN01ZanJSalRNT2JkIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMTAtMTFUMDI6MTk6NTNaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkRldk9wc0RheXMgQm9zdG9uIDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9RUGNrcG9udXhBcy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1FQY2twb251eEFzL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1FQY2twb251eEFzL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9RUGNrcG9udXhBcy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1FQY2twb251eEFzL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBCb3N0b24gMjAxOSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAzMgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiM0x2NFJpY1lXaldJOTRTaTFyaWh0VGFIWUs4IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWJlaE9xVXV6NHRWdC1PN2ZDSVBXcHEiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wOS0xOVQxNjowMjo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUnVzdENvbmYgMjAxOSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1NwdXgwaEx0VVNvL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvU3B1eDBoTHRVU28vbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvU3B1eDBoTHRVU28vaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1NwdXgwaEx0VVNvL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvU3B1eDBoTHRVU28vbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJSdXN0Q29uZiAyMDE5IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDE4CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJwV2trbHFnVVBYQXNvWUJaeGNBYkVLbTlEXzgiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5Wl9qdEl5RzF2RkNkVHR6WDNpaGs2UCIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTA5LTE5VDE1OjQ2OjIwWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJKU0NvbmYgVVMgMjAxOSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkpTQ29uZiBVUyBpcyB0aGUgb25seSBjb25mZXJlbmNlIHdoZXJlIHlvdSBjYW4gbGVhcm4gaG93IHRvIHB1c2ggeW91ciBmYXZvcml0ZSBsYW5ndWFnZSBiZXlvbmQgdGhlIGNvbmZpbmVzIG9mIHRoZSBicm93c2VyIGFuZCBpbnRvIHJvYm90cywgYW5kIHZpZGVvIGdhbWVzLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1p3X3FBNWM1dzZJL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWndfcUE1YzV3NkkvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWndfcUE1YzV3NkkvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1p3X3FBNWM1dzZJL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvWndfcUE1YzV3NkkvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJKU0NvbmYgVVMgMjAxOSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiSlNDb25mIFVTIGlzIHRoZSBvbmx5IGNvbmZlcmVuY2Ugd2hlcmUgeW91IGNhbiBsZWFybiBob3cgdG8gcHVzaCB5b3VyIGZhdm9yaXRlIGxhbmd1YWdlIGJleW9uZCB0aGUgY29uZmluZXMgb2YgdGhlIGJyb3dzZXIgYW5kIGludG8gcm9ib3RzLCBhbmQgdmlkZW8gZ2FtZXMuIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAzOAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiYkpFVldDbHhOVDE5aU1lXzdxZXRxUmVFenpFIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWFWUE04TzY3UnRLWnNmbzJXTnlTUG8iLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wOS0wOFQxNDowMzoxOVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBDaGljYWdvIDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9fcFk3aDFtMXV4MC9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL19wWTdoMW0xdXgwL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL19wWTdoMW0xdXgwL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9fcFk3aDFtMXV4MC9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL19wWTdoMW0xdXgwL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBDaGljYWdvIDIwMTkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMjQKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIkVxaG1hZHNoMGhnQWpCd3ZPbjNsd2otUXZ5SSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lhNlZ5cklMRjBiSEhodzVuajRnUGYwIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDgtMTlUMTU6NDY6MzBaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkRpbm9zYXVySlMgMjAxOSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIkRpbm9zYXVySlMgaXMgYSBub24tcHJvZml0LCBjb21tdW5pdHktZHJpdmVuIEphdmFTY3JpcHQgYW5kIE9wZW4gV2ViIGNvbmZlcmVuY2UgaW4gRGVudmVyLCBDb2xvcmFkbyIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2o5bWNoQnVTbWxrL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvajltY2hCdVNtbGsvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvajltY2hCdVNtbGsvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2o5bWNoQnVTbWxrL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvajltY2hCdVNtbGsvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJEaW5vc2F1ckpTIDIwMTkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIkRpbm9zYXVySlMgaXMgYSBub24tcHJvZml0LCBjb21tdW5pdHktZHJpdmVuIEphdmFTY3JpcHQgYW5kIE9wZW4gV2ViIGNvbmZlcmVuY2UgaW4gRGVudmVyLCBDb2xvcmFkbyIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTAKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIk9RWk1GSnAxUW1UcF93ZjJBeTU5SFhidHNMMCIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZQV9sNFZvLU9RaTZ5eXh0VG13MU9TIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDgtMDZUMTY6MTg6NDFaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkNoYWluIFJlYWN0IDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJDaGFpbiBSZWFjdCBpcyB0aGUgVS5TLiBSZWFjdCBOYXRpdmUgY29uZmVyZW5jZSB3aGVyZSBodW5kcmVkcyBnYXRoZXIgdG8gaGVhciBzcGVha2VycyBmcm9tIGFsbCBvdmVyIHRoZSB3b3JsZCBzaGFyZSBrbm93bGVkZ2Ugb24gd3JpdGluZyBSZWFjdCBOYXRpdmUgYXBwcyBvbiBpT1MvQW5kcm9pZC9XaW5kb3dzIGFuZCBvdGhlciBwbGF0Zm9ybXMuIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvekVqcURXcWVEZGcvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96RWpxRFdxZURkZy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS96RWpxRFdxZURkZy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJDaGFpbiBSZWFjdCAyMDE5IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJDaGFpbiBSZWFjdCBpcyB0aGUgVS5TLiBSZWFjdCBOYXRpdmUgY29uZmVyZW5jZSB3aGVyZSBodW5kcmVkcyBnYXRoZXIgdG8gaGVhciBzcGVha2VycyBmcm9tIGFsbCBvdmVyIHRoZSB3b3JsZCBzaGFyZSBrbm93bGVkZ2Ugb24gd3JpdGluZyBSZWFjdCBOYXRpdmUgYXBwcyBvbiBpT1MvQW5kcm9pZC9XaW5kb3dzIGFuZCBvdGhlciBwbGF0Zm9ybXMuIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAyMgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAibXhUeE1UWVVrNnpKc1doMmxQS2NGcmE5b0xFIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVk4alJ4NWtoWmYydUdXMm51QnczR1EiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wNi0wMVQwMTozNjo0OFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiISFDb24gMjAxOSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2VQdVRGTmFTYVlNL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZVB1VEZOYVNhWU0vbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZVB1VEZOYVNhWU0vaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2VQdVRGTmFTYVlNL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvZVB1VEZOYVNhWU0vbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICIhIUNvbiAyMDE5IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDMyCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJHLXdnOTlXZ09IUnNrMFllYW1SbzhDTmxxbkEiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WWJIQzlYZW5tdzNSM0xld0tCbTQydCIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTA1LTIzVDE1OjMyOjQ3WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJTVVNFQ09OIDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9SVlV3VDdoUGlYdy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JWVXdUN2hQaVh3L21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JWVXdUN2hQaVh3L2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9SVlV3VDdoUGlYdy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1JWVXdUN2hQaVh3L21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiU1VTRUNPTiAyMDE5IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDEzOQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiUUY3dTVSRmpndXIzeXRCYU1qTWNOTmhvMl8wIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWFPcTNIbFJtOWhfUV9XaFdLcW01eGMiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wNS0yMFQyMDozMjo1NloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiUmFpbHNDb25mIDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9WQndXYkZwa2x0Zy9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1ZCd1diRnBrbHRnL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1ZCd1diRnBrbHRnL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9WQndXYkZwa2x0Zy9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1ZCd1diRnBrbHRnL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiUmFpbHNDb25mIDIwMTkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogODYKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogInh5SDhEa1ZDWGt2YnppTW5EZWdtVlZGY1lVOCIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lhSklGd0ljbVZrZG5sb2Z0bHRhY3d4IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDUtMThUMTU6MTU6MTZaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlBvd2VyU2hlbGwgKyBEZXZPcHMgR2xvYmFsIFN1bW1pdCAyMDE5IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMUdvMjNPdFlaWEkvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8xR28yM090WVpYSS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8xR28yM090WVpYSS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMUdvMjNPdFlaWEkvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8xR28yM090WVpYSS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIlBvd2VyU2hlbGwgKyBEZXZPcHMgR2xvYmFsIFN1bW1pdCAyMDE5IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDYxCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJ4aUZRa0h0RmtvT2tDdWVCLWd0THFVNFFKWW8iLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5Yi1NSXNiMHBTZ2Y4WkktcXpfaFRoNCIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTA1LTE1VDE4OjEzOjM1WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJEZXZPcHNEYXlzIEJhbHRpbW9yZSAyMDE5IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvd0tFWmhJMFpUQWMvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93S0VaaEkwWlRBYy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93S0VaaEkwWlRBYy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvd0tFWmhJMFpUQWMvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS93S0VaaEkwWlRBYy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkRldk9wc0RheXMgQmFsdGltb3JlIDIwMTkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTgKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogInRfRXV0WjE0MnUxSHljVTVPdXVTTFFxdUhpSSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZcVFFRXB3Z3R2dUVCODgzTkVHbjlTIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDUtMDlUMTY6MjU6MzFaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlBBWU1FTlRTZm4gMjAxOSIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3V6RmFSbmhWM0VnL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdXpGYVJuaFYzRWcvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdXpGYVJuaFYzRWcvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL3V6RmFSbmhWM0VnL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdXpGYVJuaFYzRWcvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJQQVlNRU5UU2ZuIDIwMTkiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMjYKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIkxSbE1HYy1fdkN1VTVJSTdZMDZPSWRHX2dmOCIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZb0xKRmU4WTZUTWdaZ1VrcWxTUXpOIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDQtMTFUMjI6MTc6NTFaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIlJ1YnlIYWNrIDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9jbU90OUhoc3pDSS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2NtT3Q5SGhzekNJL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2NtT3Q5SGhzekNJL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9jbU90OUhoc3pDSS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL2NtT3Q5SGhzekNJL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiUnVieUhhY2sgMjAxOSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxNAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiRnF1UmgyeEVSZ0JLVUppN01uNDlBQTVyYnRVIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVlXTFdySGdtV3N2enNRQlNXQ0xIWUwiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wNC0wNFQxOTo1NTo0MFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRW1iZXJDb25mIDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJFbWJlckNvbmYgaXMgdGhlIGJlc3QgcGxhY2UgdG8gbWVldCB0aGUgZm9sa3MgYmVoaW5kIHRoZSBtYWdpYy4gWW914oCZbGwgaGVhciBmcm9tIG1lbWJlcnMgb2YgdGhlIEVtYmVyIENvcmUgVGVhbSwgdG9wIGNvbW11bml0eSBjb250cmlidXRvcnMgYW5kIHVzZXJzLCBhbmQgaGVscCBzaGFwZSB0aGUgZnV0dXJlIG9mIEVtYmVyLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0pGakxXN1dvaVE0L2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSkZqTFc3V29pUTQvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSkZqTFc3V29pUTQvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0pGakxXN1dvaVE0L3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSkZqTFc3V29pUTQvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJFbWJlckNvbmYgMjAxOSIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiRW1iZXJDb25mIGlzIHRoZSBiZXN0IHBsYWNlIHRvIG1lZXQgdGhlIGZvbGtzIGJlaGluZCB0aGUgbWFnaWMuIFlvdeKAmWxsIGhlYXIgZnJvbSBtZW1iZXJzIG9mIHRoZSBFbWJlciBDb3JlIFRlYW0sIHRvcCBjb21tdW5pdHkgY29udHJpYnV0b3JzIGFuZCB1c2VycywgYW5kIGhlbHAgc2hhcGUgdGhlIGZ1dHVyZSBvZiBFbWJlci4iCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDI5CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJ2VHExOGVjVHJEeGYtNEt6RUwxbkdBTDVTTFkiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WjZlS1pqcHhKXzlveTZIQXdPbVNfQiIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTAzLTI4VDE2OjIzOjIwWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJUcmF2ZXJzYWxDb25mIDIwMTkiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9KOWg2bUFIQU01RS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0o5aDZtQUhBTTVFL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0o5aDZtQUhBTTVFL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9KOWg2bUFIQU01RS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0o5aDZtQUhBTTVFL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiVHJhdmVyc2FsQ29uZiAyMDE5IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDkKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIk1ZV2ZOcFNQSXVTWmVJQWNyN1cyVDQ4UFRUWSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3liZ25nM3dQdmJTWWczeVl0MVdWbXNMIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDItMDdUMTY6MTk6MjNaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkVtYmVyQ29uZiAyMDE4IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvTmh0cFhzMFp0VWMvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OaHRwWHMwWnRVYy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OaHRwWHMwWnRVYy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvTmh0cFhzMFp0VWMvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9OaHRwWHMwWnRVYy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkVtYmVyQ29uZiAyMDE4IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDI3CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJ3eExLdUhDbEdOU1piWURDTEp0T0pKZWFwMWciLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WnBQZTlfTUpkNmdCNU1URE8xUjdrRSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTAyLTA3VDE2OjEwOjMxWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJQb3dlclNoZWxsICsgRGV2T3BzIEdsb2JhbCBTdW1taXQgMjAxOCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIlBvd2VyU2hlbGwgKyBEZXZPcHMgR2xvYmFsIFN1bW1pdCBpcyB0aGUgZ2F0aGVyaW5nIG9mIFBvd2VyU2hlbGwgKyBEZXZPcHMgcHJvZmVzc2lvbmFscyBhbmQgZW50aHVzaWFzdHMuIE1vcmUgdGhhbiBqdXN0IGEgY29uZmVyZW5jZSwgaXTigJlzIGEgdHJ1ZSBpbi1wZXJzb24gZ2F0aGVyaW5nIG9mIGEgdmlicmFudCBjb21tdWl0eSAtIHdlIGxlYXJuIGZyb20gZWFjaCBvdGhlciwgd2UgZGV2ZWxvcCBwcmFjdGljZXMgYW5kIHN0YW5kYXJkcywgd2Ugc2hhcmUgY2hhbGxlbmdlcyBhbmQgc29sdXRpb25zLCBhbmQgd2UgZHJpdmUgb3VyIGluZHVzdHJ5IGZvcndhcmQuIElmIHlvdeKAmXJlIHdvcmtpbmcgd2l0aCBQb3dlclNoZWxsLCBEZXNpcmVkIFN0YXRlIENvbmZpZ3VyYXRpb24sIGFuZCByZWxhdGVkIHRlY2hub2xvZ2llcywgYW5kIGVzcGVjaWFsbHkgaWYgeW914oCZcmUgbW92aW5nIHlvdXIgb3JnYW5pemF0aW9uIHRvd2FyZCBhIERldk9wcyBmb290aW5nLCB0aGVuIHRoaXMgaXMgdGhlIDQwMCsgbGV2ZWwgZXZlbnQgeW914oCZdmUgYmVlbiBsb29raW5nIGZvci4gQmUgc3VyZSB0byBncmFiIG91ciBldmVudCBhcHAgZm9yIHlvdXIgaU9TIG9yIEFuZHJvaWQgZGV2aWNlISIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL252UGZST1k2ZUlzL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbnZQZlJPWTZlSXMvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbnZQZlJPWTZlSXMvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL252UGZST1k2ZUlzL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvbnZQZlJPWTZlSXMvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJQb3dlclNoZWxsICsgRGV2T3BzIEdsb2JhbCBTdW1taXQgMjAxOCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiUG93ZXJTaGVsbCArIERldk9wcyBHbG9iYWwgU3VtbWl0IGlzIHRoZSBnYXRoZXJpbmcgb2YgUG93ZXJTaGVsbCArIERldk9wcyBwcm9mZXNzaW9uYWxzIGFuZCBlbnRodXNpYXN0cy4gTW9yZSB0aGFuIGp1c3QgYSBjb25mZXJlbmNlLCBpdOKAmXMgYSB0cnVlIGluLXBlcnNvbiBnYXRoZXJpbmcgb2YgYSB2aWJyYW50IGNvbW11aXR5IC0gd2UgbGVhcm4gZnJvbSBlYWNoIG90aGVyLCB3ZSBkZXZlbG9wIHByYWN0aWNlcyBhbmQgc3RhbmRhcmRzLCB3ZSBzaGFyZSBjaGFsbGVuZ2VzIGFuZCBzb2x1dGlvbnMsIGFuZCB3ZSBkcml2ZSBvdXIgaW5kdXN0cnkgZm9yd2FyZC4gSWYgeW914oCZcmUgd29ya2luZyB3aXRoIFBvd2VyU2hlbGwsIERlc2lyZWQgU3RhdGUgQ29uZmlndXJhdGlvbiwgYW5kIHJlbGF0ZWQgdGVjaG5vbG9naWVzLCBhbmQgZXNwZWNpYWxseSBpZiB5b3XigJlyZSBtb3ZpbmcgeW91ciBvcmdhbml6YXRpb24gdG93YXJkIGEgRGV2T3BzIGZvb3RpbmcsIHRoZW4gdGhpcyBpcyB0aGUgNDAwKyBsZXZlbCBldmVudCB5b3XigJl2ZSBiZWVuIGxvb2tpbmcgZm9yLiBCZSBzdXJlIHRvIGdyYWIgb3VyIGV2ZW50IGFwcCBmb3IgeW91ciBpT1Mgb3IgQW5kcm9pZCBkZXZpY2UhIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA1OQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiOWNoLTNCQ1k0MDJOektHdEZYLVNBRU1neXN3IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVpybGtaUjdRbTRtT0FrX21HQTUyeUoiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wMi0wN1QxNjowNjozOFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiTWFkaXNvbisgUnVieSAyMDE4IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdTFNRXNNRTZTMEkvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91MU1Fc01FNlMwSS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91MU1Fc01FNlMwSS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdTFNRXNNRTZTMEkvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91MU1Fc01FNlMwSS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIk1hZGlzb24rIFJ1YnkgMjAxOCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxNgogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiN2toVXk1YnlQa1VDQVhVbEFqQmlYX0ZEa0l3IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWFMUndtUlhWZ1kzMDNaSDVLS2ZpMHUiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wMi0wN1QxNTo1Mzo0MVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRGphbmdvQ29uIFVTIDIwMTgiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICJEamFuZ29Db24gVVMgaGFzIHNvbWV0aGluZyBmb3IgZXZlcnlvbmUsIGZyb20gdGhlIHBlcnNvbiB3aG8gZGV2ZWxvcHMgRGphbmdvIGFwcGxpY2F0aW9ucyBmb3IgYSBsaXZpbmcgdG8gdGhlIHBlcnNvbiB3aG8ganVzdCB0aW5rZXJzIGluIHRoZWlyIHNwYXJlIHRpbWUuIFlvdSdsbCBkaXNjb3ZlciBkZXRhaWxzIGFib3V0IGEgcmFuZ2Ugb2YgZGl2ZXJzZSBhcHBsaWNhdGlvbnMgdGhhdCBwZW9wbGUgZnJvbSBhbGwgb3ZlciB0aGUgd29ybGQgYXJlIGJ1aWxkaW5nIHdpdGggRGphbmdvLCBnZXQgYSBkZWVwZXIgdW5kZXJzdGFuZGluZyBvZiBjb25jZXB0cyB5b3XigJlyZSBhbHJlYWR5IGZhbWlsaWFyIHdpdGggYW5kIGRpc2NvdmVyIG5ldyB3YXlzIHRvIHVzZSB0aGVtLCBhbmQgaGF2ZSBhIGxvdCBvZiBmdW4hIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdWpydVBqMTV2NUkvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91anJ1UGoxNXY1SS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91anJ1UGoxNXY1SS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdWpydVBqMTV2NUkvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91anJ1UGoxNXY1SS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkRqYW5nb0NvbiBVUyAyMDE4IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICJEamFuZ29Db24gVVMgaGFzIHNvbWV0aGluZyBmb3IgZXZlcnlvbmUsIGZyb20gdGhlIHBlcnNvbiB3aG8gZGV2ZWxvcHMgRGphbmdvIGFwcGxpY2F0aW9ucyBmb3IgYSBsaXZpbmcgdG8gdGhlIHBlcnNvbiB3aG8ganVzdCB0aW5rZXJzIGluIHRoZWlyIHNwYXJlIHRpbWUuIFlvdSdsbCBkaXNjb3ZlciBkZXRhaWxzIGFib3V0IGEgcmFuZ2Ugb2YgZGl2ZXJzZSBhcHBsaWNhdGlvbnMgdGhhdCBwZW9wbGUgZnJvbSBhbGwgb3ZlciB0aGUgd29ybGQgYXJlIGJ1aWxkaW5nIHdpdGggRGphbmdvLCBnZXQgYSBkZWVwZXIgdW5kZXJzdGFuZGluZyBvZiBjb25jZXB0cyB5b3XigJlyZSBhbHJlYWR5IGZhbWlsaWFyIHdpdGggYW5kIGRpc2NvdmVyIG5ldyB3YXlzIHRvIHVzZSB0aGVtLCBhbmQgaGF2ZSBhIGxvdCBvZiBmdW4hIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA1MAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiRzZUOHItcVEwTlVHTk9lRTlQcFFORUp3T1ZRIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVoydC1yOWNlVlBWeTdjYTJfS0FWRHkiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wMi0wN1QxNTo1MDowOFoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBQaGlsYWRlbHBoaWEgMjAxOCIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1BQWGJEVlZIbUQwL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUFBYYkRWVkhtRDAvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUFBYYkRWVkhtRDAvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1BQWGJEVlZIbUQwL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvUFBYYkRWVkhtRDAvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJEZXZPcHNEYXlzIFBoaWxhZGVscGhpYSAyMDE4IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDE2CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJISU5YR0hnY3Z5OS1jRzlha2lCMUJmWXpObjgiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YWZhdkxGbTF0UjRFZ2lGYU93TGdhOCIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTAyLTA3VDE1OjM0OjU2WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJEaW5vc2F1ckpTIDIwMTciLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8xTGRsQ2I5STlHUS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzFMZGxDYjlJOUdRL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzFMZGxDYjlJOUdRL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8xTGRsQ2I5STlHUS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpLzFMZGxDYjlJOUdRL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiRGlub3NhdXJKUyAyMDE3IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDExCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJfUVQ2RWsxVDRiLTEtaGtaOTJ6TlBIcFRFdFkiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YnVweGNJd2NiS0dDZkQ3MGg1NUV6eiIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTAyLTA2VDIzOjI1OjAyWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJDaGFpbiBSZWFjdCAyMDE3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvY3o1Qnp3Z0FUcGMvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9jejVCendnQVRwYy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9jejVCendnQVRwYy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvY3o1Qnp3Z0FUcGMvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9jejVCendnQVRwYy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkNoYWluIFJlYWN0IDIwMTciLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMjAKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogInJVNTdSbHUtWWZhTEhYTE53bkZMUGpMS0tGdyIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lhdk1Wa1ItWFFnSUZoWF9memxETmVUIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDItMDZUMjM6MTQ6NDhaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkRqYW5nb0NvbiBVUyAyMDE3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdWpHQ045TU9yUmsvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91akdDTjlNT3JSay9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91akdDTjlNT3JSay9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvdWpHQ045TU9yUmsvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS91akdDTjlNT3JSay9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkRqYW5nb0NvbiBVUyAyMDE3IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDQ3CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJqRnZscTc3QVlDdS1aMHlhOUh2ZV9nY2lVVEkiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YnNnVi1ZSmlqaUc4X1k1T0VzUXc0NSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTAyLTA2VDIzOjExOjM1WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJSdXN0Q29uZiAyMDE3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvQ09ybDg1MWdNVFkvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9DT3JsODUxZ01UWS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9DT3JsODUxZ01UWS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvQ09ybDg1MWdNVFkvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9DT3JsODUxZ01UWS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIlJ1c3RDb25mIDIwMTciLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogOQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiX2lfR1N4a21GMzhzYkNvdzd1cFJ2TFF0N09RIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVl5NnRPeGpMbkt0dU1hNjJyRXh2WmQiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wMi0wNlQyMzowODo0MloiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiQWx0ZXJDb25mIE5ZQyAyMDE3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYlZFOVc3M1F2emsvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9iVkU5VzczUXZ6ay9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9iVkU5VzczUXZ6ay9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvYlZFOVc3M1F2emsvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9iVkU5VzczUXZ6ay9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkFsdGVyQ29uZiBOWUMgMjAxNyIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxMAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAiRlRBeHhsdHJFY2xHYmtaaFJuUXdkT05pODc4IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWFGWEcwQ0M1WmNrdzVOMFNpSjdUYk8iLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wMi0wNlQyMzowNDoyN1oiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiQWx0ZXJDb25mIE1lbGJvdXJuZSAyMDE3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMjZsSzFnVHVqUHcvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8yNmxLMWdUdWpQdy9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8yNmxLMWdUdWpQdy9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMjZsSzFnVHVqUHcvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8yNmxLMWdUdWpQdy9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkFsdGVyQ29uZiBNZWxib3VybmUgMjAxNyIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA4CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJBcFNsOXV0d0xHOWd4R255blo4Yk9Nd3k5RkUiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YlMzOGVQZlQ0dmw5cDUtWWtFdDdZayIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTAyLTA2VDIyOjU1OjIwWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJEZXZPcHNEYXlzIFBoaWxhZGVscGhpYSAyMDE3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSWRaYUZ6dU9QVVEvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9JZFphRnp1T1BVUS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9JZFphRnp1T1BVUS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSWRaYUZ6dU9QVVEvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9JZFphRnp1T1BVUS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkRldk9wc0RheXMgUGhpbGFkZWxwaGlhIDIwMTciLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMjEKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIkJLSGExa01Yb1pfMEdjU1d1eHJUaVEwbTR1byIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3ladmdEbHZ5Z2p1eVN1MDJIbF8yMVBqIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDItMDZUMjI6NDk6NDZaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkFsdGVyQ29uZiBQb3J0bGFuZCAyMDE3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRW5qYVFEdk9veVEvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FbmphUUR2T295US9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FbmphUUR2T295US9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvRW5qYVFEdk9veVEvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9FbmphUUR2T295US9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkFsdGVyQ29uZiBQb3J0bGFuZCAyMDE3IiwKICAgICAgICAgICJkZXNjcmlwdGlvbiI6ICIiCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDEwCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJRR3E3MHhsdVI3MUpkQTBBaE1GTjF1RlYxSzAiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WVNrb01SbkRzUUVIbkxiYWY2bTFNNCIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTAyLTA2VDIyOjMxOjMzWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJBbHRlckNvbmYgU2FuIEZyYW5jaXNjbyAyMDE3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVjBiOUFBZTdPUG8vZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9WMGI5QUFlN09Qby9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9WMGI5QUFlN09Qby9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVjBiOUFBZTdPUG8vc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9WMGI5QUFlN09Qby9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkFsdGVyQ29uZiBTYW4gRnJhbmNpc2NvIDIwMTciLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTEKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIm9VbVVHSHA0VGdBSTNwTXR3T3RZaG1kYjY0OCIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3liYWhYZ0ZwdXlSUFdvS3pkWTRVY1pFIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDItMDZUMjE6NTM6MTBaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkRldk9wc0RheXMgTllDIDIwMTgiLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PdDRHdk90cTVYWS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL090NEd2T3RxNVhZL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL090NEd2T3RxNVhZL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PdDRHdk90cTVYWS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL090NEd2T3RxNVhZL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiRGV2T3BzRGF5cyBOWUMgMjAxOCIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAyMQogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAibDF2QlZjdmhSVXdadWNXMmRmWVBKUm0yaExzIiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeWJCX0RmRzNOVkFVZHcza2lWLWVHSFoiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wMi0wNlQyMTo1MDo0MVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiRW1wZXggTEEgQ29uZiAyMDE4IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiV2l0aCB0aGUgZW1lcmdlbmNlIG9mIHRoZSBjb25jdXJyZW50IEVsaXhpciBwcm9ncmFtbWluZyBsYW5ndWFnZSwgd2UgYmVsaWV2ZSB0aGF0IGFsbCB3ZWIgYXBwbGljYXRpb25zIHNob3VsZCBoYXZlIFJlYWx0aW1lIGludGVyZmFjZXMuIFdlJ3JlIGJyaW5naW5nIHRvZ2V0aGVyIGxlYWRpbmcgZGVzaWduZXJzLCBlbmdpbmVlcnMsIHByb2R1Y3QgbWFuYWdlcnMsIGFuZCBkYXRhYmFzZSBzcGVjaWFsaXN0cyB0byBleHBsb3JlIGRlc2lnbiBwYXR0ZXJucywgY29uc2lkZXJhdGlvbnMsIGFuZCBwb3NzaWJpbGl0aWVzIGluIHRoaXMgZXhjaXRpbmcgbmV3IHdvcmxkLiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0drN2JXQzR4dzlZL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvR2s3YldDNHh3OVkvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvR2s3YldDNHh3OVkvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0drN2JXQzR4dzlZL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvR2s3YldDNHh3OVkvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJFbXBleCBMQSBDb25mIDIwMTgiLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIldpdGggdGhlIGVtZXJnZW5jZSBvZiB0aGUgY29uY3VycmVudCBFbGl4aXIgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UsIHdlIGJlbGlldmUgdGhhdCBhbGwgd2ViIGFwcGxpY2F0aW9ucyBzaG91bGQgaGF2ZSBSZWFsdGltZSBpbnRlcmZhY2VzLiBXZSdyZSBicmluZ2luZyB0b2dldGhlciBsZWFkaW5nIGRlc2lnbmVycywgZW5naW5lZXJzLCBwcm9kdWN0IG1hbmFnZXJzLCBhbmQgZGF0YWJhc2Ugc3BlY2lhbGlzdHMgdG8gZXhwbG9yZSBkZXNpZ24gcGF0dGVybnMsIGNvbnNpZGVyYXRpb25zLCBhbmQgcG9zc2liaWxpdGllcyBpbiB0aGlzIGV4Y2l0aW5nIG5ldyB3b3JsZC4iCiAgICAgICAgfQogICAgICB9LAogICAgICAiY29udGVudERldGFpbHMiOiB7CiAgICAgICAgIml0ZW1Db3VudCI6IDExCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJ6UVZ2eDRCbG44OEg1ZjdacDNKb3JqTWI3OGciLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5YmNtbjNoYVNOaW82cDdyS3JkTnFURiIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTAyLTA2VDE5OjUyOjIwWiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJFbWJlckNvbmYgMjAxNyIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL1RFdVk0R3F3clVFL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVEV1WTRHcXdyVUUvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvVEV1WTRHcXdyVUUvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiRW1iZXJDb25mIDIwMTciLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMzEKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogImcxQ2dPaVQtSmNEX3VVVll2U2htbWpNOU1YNCIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lic2tkN2ZfSE1KWS1LclRIVG5pX0RuIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDItMDZUMTk6NDU6NTNaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkFsdGVyQ29uZiBMb25kb24gMjAxNyIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0s2NFQtZlBPdzBNL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSzY0VC1mUE93ME0vbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSzY0VC1mUE93ME0vaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0s2NFQtZlBPdzBNL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvSzY0VC1mUE93ME0vbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJBbHRlckNvbmYgTG9uZG9uIDIwMTciLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTEKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogImtTVkl6N19lMDc3bWRFUzY1SFZkdmtCRzgwSSIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZcmFkS29JLThUUDdXZy1oUmxYQXRNIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDItMDVUMjM6MDY6MjRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkFsdGVyQ29uZiBTZWF0dGxlIDIwMTciLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PX0VJQjZpVlo5TS9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL09fRUlCNmlWWjlNL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL09fRUlCNmlWWjlNL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9PX0VJQjZpVlo5TS9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL09fRUlCNmlWWjlNL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiQWx0ZXJDb25mIFNlYXR0bGUgMjAxNyIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxMAogICAgICB9CiAgICB9LAogICAgewogICAgICAia2luZCI6ICJ5b3V0dWJlI3BsYXlsaXN0IiwKICAgICAgImV0YWciOiAia3FQODVFb0NlcFdhbkxhTXRfWVNJTWIyczU0IiwKICAgICAgImlkIjogIlBMRTd0UVVkUktjeVp5UWU3N3ctWWd1cEdBdHJ0RHMxdmEiLAogICAgICAic25pcHBldCI6IHsKICAgICAgICAicHVibGlzaGVkQXQiOiAiMjAxOS0wMi0wNVQyMjoyNDozNVoiLAogICAgICAgICJjaGFubmVsSWQiOiAiVUNXblBqbXF2bGpjYWZBMHoyVTFmd0tRIiwKICAgICAgICAidGl0bGUiOiAiQWx0ZXJDb25mIEJlcmxpbiAyMDE3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvQkszS1FTRHBNMk0vZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9CSzNLUVNEcE0yTS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9CSzNLUVNEcE0yTS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvQkszS1FTRHBNMk0vc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9CSzNLUVNEcE0yTS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIkFsdGVyQ29uZiBCZXJsaW4gMjAxNyIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiA5CiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJraW5kIjogInlvdXR1YmUjcGxheWxpc3QiLAogICAgICAiZXRhZyI6ICJ0Z0l6bkY0UThQUzVpNWdNcVJ0LU1CZlpLaXMiLAogICAgICAiaWQiOiAiUExFN3RRVWRSS2N5WmVNbXRBbW5DeXk2d0VyOXNXUjdzbSIsCiAgICAgICJzbmlwcGV0IjogewogICAgICAgICJwdWJsaXNoZWRBdCI6ICIyMDE5LTAyLTA1VDIyOjE4OjE0WiIsCiAgICAgICAgImNoYW5uZWxJZCI6ICJVQ1duUGptcXZsamNhZkEwejJVMWZ3S1EiLAogICAgICAgICJ0aXRsZSI6ICJXcml0ZSBUaGUgRG9jcyAyMDE3IiwKICAgICAgICAiZGVzY3JpcHRpb24iOiAiIiwKICAgICAgICAidGh1bWJuYWlscyI6IHsKICAgICAgICAgICJkZWZhdWx0IjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMkxUc3FKZFVLaUkvZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiA5MAogICAgICAgICAgfSwKICAgICAgICAgICJtZWRpdW0iOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8yTFRzcUpkVUtpSS9tcWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMzIwLAogICAgICAgICAgICAiaGVpZ2h0IjogMTgwCiAgICAgICAgICB9LAogICAgICAgICAgImhpZ2giOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8yTFRzcUpkVUtpSS9ocWRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNDgwLAogICAgICAgICAgICAiaGVpZ2h0IjogMzYwCiAgICAgICAgICB9LAogICAgICAgICAgInN0YW5kYXJkIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvMkxUc3FKZFVLaUkvc2RkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDY0MCwKICAgICAgICAgICAgImhlaWdodCI6IDQ4MAogICAgICAgICAgfSwKICAgICAgICAgICJtYXhyZXMiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS8yTFRzcUpkVUtpSS9tYXhyZXNkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyODAsCiAgICAgICAgICAgICJoZWlnaHQiOiA3MjAKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgICJjaGFubmVsVGl0bGUiOiAiQ29uZnJlYWtzIiwKICAgICAgICAibG9jYWxpemVkIjogewogICAgICAgICAgInRpdGxlIjogIldyaXRlIFRoZSBEb2NzIDIwMTciLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTkKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIjVDZGlSSEo0bFhnWlNYRy1NNTUxY09DeHN2ayIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lZUzFNaVpYOXIybXQxc2RnaWoxdERWIiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDItMDVUMjI6MDI6MTRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkRldk9wc0RheXMgU2FsdCBMYWtlIENpdHkgMjAxNyIsCiAgICAgICAgImRlc2NyaXB0aW9uIjogIiIsCiAgICAgICAgInRodW1ibmFpbHMiOiB7CiAgICAgICAgICAiZGVmYXVsdCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0tlNDRicHFBazJZL2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTIwLAogICAgICAgICAgICAiaGVpZ2h0IjogOTAKICAgICAgICAgIH0sCiAgICAgICAgICAibWVkaXVtIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvS2U0NGJwcUFrMlkvbXFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDMyMCwKICAgICAgICAgICAgImhlaWdodCI6IDE4MAogICAgICAgICAgfSwKICAgICAgICAgICJoaWdoIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvS2U0NGJwcUFrMlkvaHFkZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDQ4MCwKICAgICAgICAgICAgImhlaWdodCI6IDM2MAogICAgICAgICAgfSwKICAgICAgICAgICJzdGFuZGFyZCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0tlNDRicHFBazJZL3NkZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA2NDAsCiAgICAgICAgICAgICJoZWlnaHQiOiA0ODAKICAgICAgICAgIH0sCiAgICAgICAgICAibWF4cmVzIjogewogICAgICAgICAgICAidXJsIjogImh0dHBzOi8vaS55dGltZy5jb20vdmkvS2U0NGJwcUFrMlkvbWF4cmVzZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAxMjgwLAogICAgICAgICAgICAiaGVpZ2h0IjogNzIwCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICAiY2hhbm5lbFRpdGxlIjogIkNvbmZyZWFrcyIsCiAgICAgICAgImxvY2FsaXplZCI6IHsKICAgICAgICAgICJ0aXRsZSI6ICJEZXZPcHNEYXlzIFNhbHQgTGFrZSBDaXR5IDIwMTciLAogICAgICAgICAgImRlc2NyaXB0aW9uIjogIiIKICAgICAgICB9CiAgICAgIH0sCiAgICAgICJjb250ZW50RGV0YWlscyI6IHsKICAgICAgICAiaXRlbUNvdW50IjogMTEKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImtpbmQiOiAieW91dHViZSNwbGF5bGlzdCIsCiAgICAgICJldGFnIjogIldPR1N0NUlPbVRUNUF1VEk2VGFVeHUzOFV3USIsCiAgICAgICJpZCI6ICJQTEU3dFFVZFJLY3lhd1JOX2xJVkRsZXBKVVo1dFJJZEd5IiwKICAgICAgInNuaXBwZXQiOiB7CiAgICAgICAgInB1Ymxpc2hlZEF0IjogIjIwMTktMDItMDVUMjE6NTY6MjRaIiwKICAgICAgICAiY2hhbm5lbElkIjogIlVDV25Qam1xdmxqY2FmQTB6MlUxZndLUSIsCiAgICAgICAgInRpdGxlIjogIkFsdGVyQ29uZiBDaGljYWdvIDIwMTciLAogICAgICAgICJkZXNjcmlwdGlvbiI6ICIiLAogICAgICAgICJ0aHVtYm5haWxzIjogewogICAgICAgICAgImRlZmF1bHQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9KZ3U1eG5qWW5Ray9kZWZhdWx0LmpwZyIsCiAgICAgICAgICAgICJ3aWR0aCI6IDEyMCwKICAgICAgICAgICAgImhlaWdodCI6IDkwCiAgICAgICAgICB9LAogICAgICAgICAgIm1lZGl1bSI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0pndTV4bmpZblFrL21xZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiAzMjAsCiAgICAgICAgICAgICJoZWlnaHQiOiAxODAKICAgICAgICAgIH0sCiAgICAgICAgICAiaGlnaCI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0pndTV4bmpZblFrL2hxZGVmYXVsdC5qcGciLAogICAgICAgICAgICAid2lkdGgiOiA0ODAsCiAgICAgICAgICAgICJoZWlnaHQiOiAzNjAKICAgICAgICAgIH0sCiAgICAgICAgICAic3RhbmRhcmQiOiB7CiAgICAgICAgICAgICJ1cmwiOiAiaHR0cHM6Ly9pLnl0aW1nLmNvbS92aS9KZ3U1eG5qWW5Ray9zZGRlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogNjQwLAogICAgICAgICAgICAiaGVpZ2h0IjogNDgwCiAgICAgICAgICB9LAogICAgICAgICAgIm1heHJlcyI6IHsKICAgICAgICAgICAgInVybCI6ICJodHRwczovL2kueXRpbWcuY29tL3ZpL0pndTV4bmpZblFrL21heHJlc2RlZmF1bHQuanBnIiwKICAgICAgICAgICAgIndpZHRoIjogMTI4MCwKICAgICAgICAgICAgImhlaWdodCI6IDcyMAogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImNoYW5uZWxUaXRsZSI6ICJDb25mcmVha3MiLAogICAgICAgICJsb2NhbGl6ZWQiOiB7CiAgICAgICAgICAidGl0bGUiOiAiQWx0ZXJDb25mIENoaWNhZ28gMjAxNyIsCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiIgogICAgICAgIH0KICAgICAgfSwKICAgICAgImNvbnRlbnREZXRhaWxzIjogewogICAgICAgICJpdGVtQ291bnQiOiAxMQogICAgICB9CiAgICB9CiAgXQp9Cg==\n  recorded_at: Thu, 08 Jun 2023 18:32:24 GMT\n- request:\n    method: get\n    uri: https://youtube.googleapis.com/youtube/v3/playlists?channelId=UCWnPjmqvljcafA0z2U1fwKQ&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&pageToken=CGQQAA&part=snippet,contentDetails\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Thu, 08 Jun 2023 18:32:25 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      Cache-Control:\n      - private\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: |\n        {\n          \"kind\": \"youtube#playlistListResponse\",\n          \"etag\": \"67-n3Y0WB0-ex_Klms4N58_o6aQ\",\n          \"nextPageToken\": \"CJYBEAA\",\n          \"prevPageToken\": \"CGQQAQ\",\n          \"pageInfo\": {\n            \"totalResults\": 318,\n            \"resultsPerPage\": 50\n          },\n          \"items\": [\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"EplzrzwhviA8miJogA5Y3vcoL8E\",\n              \"id\": \"PLE7tQUdRKcyZ2CyVcp2EZ6tZGoSWkw5Co\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-05T21:51:24Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf Portland 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/_j9pf5DabwM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/_j9pf5DabwM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/_j9pf5DabwM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/_j9pf5DabwM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/_j9pf5DabwM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf Portland 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 11\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"8JQus9xnW9CSozZ7_tWI1fm8Lu4\",\n              \"id\": \"PLE7tQUdRKcyZDnWzYAMQH-TUfU0pIjv8l\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-05T21:48:20Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf NYC 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/lZQeY0uiHc4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/lZQeY0uiHc4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/lZQeY0uiHc4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/lZQeY0uiHc4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/lZQeY0uiHc4/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf NYC 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"_4VArCLIbGKSR9Mu8XLCYvUpEXw\",\n              \"id\": \"PLE7tQUdRKcyYYJRbVE0AFgb8OJlh_vJeE\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-05T18:45:37Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Salt Lake City 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/YPImHSjvLJI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/YPImHSjvLJI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/YPImHSjvLJI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/YPImHSjvLJI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/YPImHSjvLJI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Salt Lake City 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"b7ZH020OGEaTOtUQmzDls8SBr2Q\",\n              \"id\": \"PLE7tQUdRKcyZNknh0wA44b5IEIxQ37vL7\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-05T18:27:11Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DjangoCon US 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/j7BpbidWW_o/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/j7BpbidWW_o/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/j7BpbidWW_o/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/j7BpbidWW_o/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/j7BpbidWW_o/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DjangoCon US 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 52\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"aKvht4cYNwxPRp4H2bLd1pTSHjM\",\n              \"id\": \"PLE7tQUdRKcyYBCKvkYgCg9zW2NBCsAr08\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-05T18:20:56Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"npmCamp 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/QfE2cB3JLeU/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/QfE2cB3JLeU/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/QfE2cB3JLeU/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/QfE2cB3JLeU/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/QfE2cB3JLeU/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"npmCamp 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"-qwJqWVox3Cj65diC6KKLs9oEMA\",\n              \"id\": \"PLE7tQUdRKcyZ9IWECsxGyxvKGpchuGMOz\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-05T18:17:28Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf Dublin 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/OxyQSJMvWBo/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/OxyQSJMvWBo/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/OxyQSJMvWBo/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/OxyQSJMvWBo/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/OxyQSJMvWBo/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf Dublin 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 10\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"izlVDgprGIVe6eCCemI1tFJ_rJ4\",\n              \"id\": \"PLE7tQUdRKcyajeA9inp6inSTmwbJjNe9F\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-05T18:13:06Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Boston 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/wFEXrE8A8EI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/wFEXrE8A8EI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/wFEXrE8A8EI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/wFEXrE8A8EI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/wFEXrE8A8EI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Boston 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"pr1CXvednDggFaBk_8R2DRDOoAk\",\n              \"id\": \"PLE7tQUdRKcyZ7BoAToTLmvZMOAF6Ln0EF\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-05T18:04:56Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf Washington 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ppqggxQhPnQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ppqggxQhPnQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ppqggxQhPnQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ppqggxQhPnQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ppqggxQhPnQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf Washington 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"PiR45giRDnGMkYPn2l2sovuftOk\",\n              \"id\": \"PLE7tQUdRKcyYzUUTUJ4LwayKH8p5spYvv\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-01T18:44:15Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"EmberConf 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/OInJBwS8VDQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/OInJBwS8VDQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/OInJBwS8VDQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/OInJBwS8VDQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"EmberConf 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 37\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"sCbShNxUOL3-C9aRCJVxdj9fJwI\",\n              \"id\": \"PLE7tQUdRKcyYi73nmQ7ICfmnAx-hJU1r8\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-01T18:38:20Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf Minneapolis 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/h3rGbhT1TGY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/h3rGbhT1TGY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/h3rGbhT1TGY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/h3rGbhT1TGY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/h3rGbhT1TGY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf Minneapolis 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ZzW7Fq7kV6INnJfFB5PUOET51RU\",\n              \"id\": \"PLE7tQUdRKcybV2xe-k_aIjrDZ7XXlAP9D\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-01T18:27:26Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf San Francisco 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/46uSeTO3Epw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/46uSeTO3Epw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/46uSeTO3Epw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/46uSeTO3Epw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/46uSeTO3Epw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf San Francisco 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"CXMFt4b01oHAQuXoygI1DhvYeqM\",\n              \"id\": \"PLE7tQUdRKcyaQ73YOzI-DxJFzuHqysSin\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-01T18:22:24Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf Detroit 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/UpSKCRKb--E/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/UpSKCRKb--E/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/UpSKCRKb--E/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/UpSKCRKb--E/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/UpSKCRKb--E/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf Detroit 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 5\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"vI_vo2RkIgTt2zD7HQm3Z93pLTo\",\n              \"id\": \"PLE7tQUdRKcyZPZRnqU2JhjMiTl1x3REc5\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-02-01T18:13:14Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf Los Angeles 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/w3FuimYyoxw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/w3FuimYyoxw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/w3FuimYyoxw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/w3FuimYyoxw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/w3FuimYyoxw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf Los Angeles 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 5\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Pnaxsx-GtDjPVQeK_Dnf6EA9GRU\",\n              \"id\": \"PLE7tQUdRKcyYq9LoMcaV2TaT47M2_A8B9\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-31T23:45:33Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Nebraska JS 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/Xve7QCNNeMs/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/Xve7QCNNeMs/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/Xve7QCNNeMs/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/Xve7QCNNeMs/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/Xve7QCNNeMs/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Nebraska JS 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"0RdCBzkuD6kS9bml97NAhKsl19w\",\n              \"id\": \"PLE7tQUdRKcybhQu9cYjrgPdP4Kp1Lq3u5\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-31T23:18:56Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Jenkins User Conference West 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/6BPDFjhd_Bg/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/6BPDFjhd_Bg/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/6BPDFjhd_Bg/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/6BPDFjhd_Bg/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/6BPDFjhd_Bg/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Jenkins User Conference West 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 32\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"1Qu8Ew-Mn3pj1jv8Sn1L0C_GPiI\",\n              \"id\": \"PLE7tQUdRKcyaVafyrNCKBCAK6ftp0IhSE\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-31T23:11:13Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf Seattle 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/3o7jOWf4tJo/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/3o7jOWf4tJo/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/3o7jOWf4tJo/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/3o7jOWf4tJo/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/3o7jOWf4tJo/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf Seattle 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"rv2X5TpXcDqkxzEJ-yqJ6Td2hAE\",\n              \"id\": \"PLE7tQUdRKcyYTh_4de7cCj43C3c0jtoHL\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-31T22:11:00Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Open Source Bridge 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/J3Djb1VyzkM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/J3Djb1VyzkM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/J3Djb1VyzkM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/J3Djb1VyzkM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/J3Djb1VyzkM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Open Source Bridge 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 95\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"DSjtvvrDEuwX19qo5jjSS6n-FTg\",\n              \"id\": \"PLE7tQUdRKcyZtAg7ZYj-VbhBJVCLUuKIe\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-31T21:57:04Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Jenkins User Conference London 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/OutYmufMavY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/OutYmufMavY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/OutYmufMavY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/OutYmufMavY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/OutYmufMavY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Jenkins User Conference London 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 34\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"TTn2fW85dFed-0unxC6GLsAMrck\",\n              \"id\": \"PLE7tQUdRKcyYftsQnmv6SZnC46zIRsSIM\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-31T21:43:09Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf Portland 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/dYlVZC0zJFQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/dYlVZC0zJFQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/dYlVZC0zJFQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/dYlVZC0zJFQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf Portland 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 10\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"9VnrzvVn840y2luRfVaWH_jLKfs\",\n              \"id\": \"PLE7tQUdRKcyaHv-fjf1XHvt8fsBUpJXG7\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-31T21:33:53Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Jenkins User Conference San Francisco 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/TZrtioKwaGY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/TZrtioKwaGY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/TZrtioKwaGY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/TZrtioKwaGY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/TZrtioKwaGY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Jenkins User Conference San Francisco 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 22\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"vX6ka7W_JqAFLF79lV5D1afGzeI\",\n              \"id\": \"PLE7tQUdRKcybotcO4wdQgFOYzNjNtBivE\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-30T22:53:16Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"JSConf EU 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/SmZ9XcTpMS4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/SmZ9XcTpMS4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/SmZ9XcTpMS4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/SmZ9XcTpMS4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/SmZ9XcTpMS4/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"JSConf EU 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 53\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"iuX4_vz0SbhkL3fNLcO6Mk7ArXg\",\n              \"id\": \"PLE7tQUdRKcyYIYgAh89k_iXjEREz2z5in\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-30T22:40:57Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Rails Pacific 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/9TkdXkkhP_4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/9TkdXkkhP_4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/9TkdXkkhP_4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/9TkdXkkhP_4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/9TkdXkkhP_4/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Rails Pacific 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 11\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"SykphEARv2fLScUvJHmdUCI4a3o\",\n              \"id\": \"PLE7tQUdRKcyYhE9P_jmZsSpYGc5uRE8aw\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-30T22:28:15Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Jenkins User Conference 2014 Boston\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/JRQbLG0xAkw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/JRQbLG0xAkw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/JRQbLG0xAkw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/JRQbLG0xAkw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/JRQbLG0xAkw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Jenkins User Conference 2014 Boston\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"GzURYHh8AozLDwSPobKmMSojMio\",\n              \"id\": \"PLE7tQUdRKcybBkS80zeWfc6q2KF0EO4pg\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-30T22:13:04Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Jenkins User Conference 2014 Berlin\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/4S5a2zhCTDU/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/4S5a2zhCTDU/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/4S5a2zhCTDU/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/4S5a2zhCTDU/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/4S5a2zhCTDU/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Jenkins User Conference 2014 Berlin\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"EQE5hfKdebTzcWplh82TcCvXblg\",\n              \"id\": \"PLE7tQUdRKcyZh-nK9cb-wBAotMUMFnwwQ\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-30T21:31:32Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Jenkins User Conference 2013 Palo Alto\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/FaMoiVpKUvQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/FaMoiVpKUvQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/FaMoiVpKUvQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/FaMoiVpKUvQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/FaMoiVpKUvQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Jenkins User Conference 2013 Palo Alto\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"WTtWSUuAgq7TyJk7lRjIiZVARwk\",\n              \"id\": \"PLE7tQUdRKcyaCuYEcCn6GmcB4XfhbV5GO\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-30T20:40:28Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"OpenStack Summit Portland 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/e0dbavbx05c/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/e0dbavbx05c/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/e0dbavbx05c/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/e0dbavbx05c/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/e0dbavbx05c/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"OpenStack Summit Portland 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 13\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"mTNHdIJUToaT7xA41EPJJhXHlg8\",\n              \"id\": \"PLE7tQUdRKcyb8R9rWt9faOUu_Dwgm9Axi\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-30T20:24:38Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Jenkins User Conference San Francisco 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/sjdzlGJvGX0/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/sjdzlGJvGX0/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/sjdzlGJvGX0/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/sjdzlGJvGX0/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/sjdzlGJvGX0/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Jenkins User Conference San Francisco 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 16\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"K3b7oeWiN3yRCu222uKGoo4YylA\",\n              \"id\": \"PLE7tQUdRKcyZ_7EwbIZw3sUmIzXnf7pd-\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-25T20:15:19Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ChefConf 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/eeZBGDmCnkA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/eeZBGDmCnkA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/eeZBGDmCnkA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/eeZBGDmCnkA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/eeZBGDmCnkA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ChefConf 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 47\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"7CQcuPIXEN9c-_vETDW5hnwyz2s\",\n              \"id\": \"PLE7tQUdRKcybq8uK3C3JqQKgAiMQwGu11\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-25T19:48:21Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ChefConf 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/08nJ9ZF5WO0/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/08nJ9ZF5WO0/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/08nJ9ZF5WO0/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/08nJ9ZF5WO0/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/08nJ9ZF5WO0/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ChefConf 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 34\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"XNw-r9DvhQE9tIo-yo_klwpFWEU\",\n              \"id\": \"PLE7tQUdRKcybzPULTWmXF4WJrPveVc0lZ\",\n              \"snippet\": {\n                \"publishedAt\": \"2019-01-25T18:37:31Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ChefConf 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/9_41kUVJMYw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/9_41kUVJMYw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/9_41kUVJMYw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/9_41kUVJMYw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/9_41kUVJMYw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ChefConf 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 33\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"R5Jxs5V0RGjjm19w9FQYXzajkPE\",\n              \"id\": \"PLE7tQUdRKcyZH15iznpPb5O8zjs9Vxqmc\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-12-21T22:21:56Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"!!Con West 2019\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/-fpnf2nOigQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/-fpnf2nOigQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/-fpnf2nOigQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/-fpnf2nOigQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/-fpnf2nOigQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"!!Con West 2019\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 32\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"VYBM9rT5cOe4y6igae6eOb417kE\",\n              \"id\": \"PLE7tQUdRKcyZEjH3kIyvIN0eZ4tuVEkBD\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-11-28T20:02:52Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyConf 2018\",\n                \"description\": \"RubyConf has been the main annual gathering of Rubyists from around the world since 2001.\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/datDkio1AXM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/datDkio1AXM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/datDkio1AXM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/datDkio1AXM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/datDkio1AXM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyConf 2018\",\n                  \"description\": \"RubyConf has been the main annual gathering of Rubyists from around the world since 2001.\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 70\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"VjSMF1wHfQlTJ49A_f06zgobpoE\",\n              \"id\": \"PLE7tQUdRKcyaxIbXihF5bRdMumqVtGrT4\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-11-28T17:31:56Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Keep Ruby Weird 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/wDrmvmhABcg/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/wDrmvmhABcg/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/wDrmvmhABcg/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/wDrmvmhABcg/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/wDrmvmhABcg/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Keep Ruby Weird 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"x3xu5139tFf9PZ7hDfjmoO4WCUk\",\n              \"id\": \"PLE7tQUdRKcybNXGjyWZBrE_tV2i_F1uc2\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-10-17T14:55:30Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Boston 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/WF5JN_N1SQ4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/WF5JN_N1SQ4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/WF5JN_N1SQ4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/WF5JN_N1SQ4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/WF5JN_N1SQ4/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Boston 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 24\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"IKNu6KXaGorWg41OxL4wFcKd48o\",\n              \"id\": \"PLE7tQUdRKcya77WUBhEs4puE-CjzOo2AH\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-09-06T19:20:40Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RustConf 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/P9u8x13W7UE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/P9u8x13W7UE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/P9u8x13W7UE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/P9u8x13W7UE/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/P9u8x13W7UE/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RustConf 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 15\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"WoiAc8WhBYf2W-62rig9NMrWk-M\",\n              \"id\": \"PLE7tQUdRKcyb_82P95i6eKPwq-DhK1TjN\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T20:22:44Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays NYC 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/Ot4GvOtq5XY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/Ot4GvOtq5XY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/Ot4GvOtq5XY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/Ot4GvOtq5XY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/Ot4GvOtq5XY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays NYC 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 21\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"cQmfZtc8Tcszl5c33d9dPtTntBM\",\n              \"id\": \"PLE7tQUdRKcyb-waTU7CjPVlrCAWkHP2Me\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T17:39:49Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Philly 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/IdZaFzuOPUQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/IdZaFzuOPUQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/IdZaFzuOPUQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/IdZaFzuOPUQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/IdZaFzuOPUQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Philly 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 21\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"-XXumcEiklX7p5qbUeThc4jTxr0\",\n              \"id\": \"PLE7tQUdRKcyZbTag-xWB3_v_yAxU8ujeG\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T17:36:05Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Philly 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/w3_qn2qjHzs/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/w3_qn2qjHzs/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/w3_qn2qjHzs/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/w3_qn2qjHzs/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/w3_qn2qjHzs/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Philly 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"fnJrmpVKP7socIUGLzjK2Se5u5Y\",\n              \"id\": \"PLE7tQUdRKcyZfjEfs6RiUfW1xsOC3SLtc\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T17:20:32Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"PowerShell + DevOps Global Summit 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/sN7xw_jq_64/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/sN7xw_jq_64/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/sN7xw_jq_64/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/sN7xw_jq_64/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/sN7xw_jq_64/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"PowerShell + DevOps Global Summit 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 59\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"5Yikn9jF4pCObWW7rlJkG13KCnQ\",\n              \"id\": \"PLE7tQUdRKcyaRUa0Ifh7EfAQ2N-URdFe_\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T17:13:54Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Write the Docs Portland 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/2LTsqJdUKiI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/2LTsqJdUKiI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/2LTsqJdUKiI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/2LTsqJdUKiI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/2LTsqJdUKiI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Write the Docs Portland 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 20\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"kNFqC5qjFfKfyniDIwvEQ4SXXCQ\",\n              \"id\": \"PLE7tQUdRKcyZtFricNYsgD5P3obHvz9hW\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T17:02:36Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"EmberConf 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/NhtpXs0ZtUc/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/NhtpXs0ZtUc/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/NhtpXs0ZtUc/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/NhtpXs0ZtUc/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/NhtpXs0ZtUc/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"EmberConf 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 27\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"rBCYBmBwOsobcSdCCyaoUwk4J_o\",\n              \"id\": \"PLE7tQUdRKcyZZ42aAds6YgZQl-QwFHzTU\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T16:50:06Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"EmberConf 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/TEuY4GqwrUE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/TEuY4GqwrUE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/TEuY4GqwrUE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"EmberConf 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 31\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"LCrlztW5AnBMHN9nEqaCHwCN_fY\",\n              \"id\": \"PLE7tQUdRKcybaA0P3ijMX9cJ71nl2VktQ\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T16:20:03Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"EmberConf 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/OInJBwS8VDQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/OInJBwS8VDQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/OInJBwS8VDQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/OInJBwS8VDQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"EmberConf 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 37\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ci-6lF02rC5PMLmfLwtRWY3IeuA\",\n              \"id\": \"PLE7tQUdRKcyYzUMw3AVB_WLIAT-2zBEF8\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T16:12:13Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"npmCamp 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/QfE2cB3JLeU/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/QfE2cB3JLeU/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/QfE2cB3JLeU/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/QfE2cB3JLeU/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/QfE2cB3JLeU/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"npmCamp 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"td7wtD001nkLV6m18iCbDhT3ni8\",\n              \"id\": \"PLE7tQUdRKcyaFq5b7JGlq7wHfbxVM1X-R\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T15:59:51Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DinosaurJS 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/1LdlCb9I9GQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/1LdlCb9I9GQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/1LdlCb9I9GQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/1LdlCb9I9GQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/1LdlCb9I9GQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DinosaurJS 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 11\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"NI16Rkn9pt4kqBY_NutwV4tCHCE\",\n              \"id\": \"PLE7tQUdRKcyb6qNopxYKYTZJQ8ItP5s7T\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T15:54:27Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Dinosaurjs 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/2Yf8hRltNxU/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/2Yf8hRltNxU/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/2Yf8hRltNxU/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/2Yf8hRltNxU/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/2Yf8hRltNxU/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Dinosaurjs 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"mbTUjofMztqBSohLWFicAJG3liw\",\n              \"id\": \"PLE7tQUdRKcyYKw0Kq4FgyZwfEpS5qaBrj\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T15:28:46Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DjangoCon US 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/j7BpbidWW_o/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/j7BpbidWW_o/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/j7BpbidWW_o/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/j7BpbidWW_o/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/j7BpbidWW_o/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DjangoCon US 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 52\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"9v-vSKbHBS45hEHE9s9NlugqfQk\",\n              \"id\": \"PLE7tQUdRKcyYmQkTgNn6SZD_0pcRDwMgW\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-15T15:11:40Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DjangoCon US 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ujGCN9MOrRk/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ujGCN9MOrRk/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ujGCN9MOrRk/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ujGCN9MOrRk/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ujGCN9MOrRk/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DjangoCon US 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 47\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"cV37m6dZFvdVnYji_6-MHfhU034\",\n              \"id\": \"PLE7tQUdRKcyYQ9WtmiBc2yxlgDxyaU52s\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-10T00:07:20Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Madison+ Ruby 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/u1MEsME6S0I/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/u1MEsME6S0I/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/u1MEsME6S0I/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/u1MEsME6S0I/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/u1MEsME6S0I/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Madison+ Ruby 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 16\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"cSJCRiId6FkwL-c3suyB1uCVMJc\",\n              \"id\": \"PLE7tQUdRKcyaFx855xLMq39nrkxmXJfJ3\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-08-10T00:03:10Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ChainReact 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/dtBwMF3znKc/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/dtBwMF3znKc/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/dtBwMF3znKc/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/dtBwMF3znKc/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/dtBwMF3znKc/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ChainReact 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 22\n              }\n            }\n          ]\n        }\n  recorded_at: Thu, 08 Jun 2023 18:32:25 GMT\n- request:\n    method: get\n    uri: https://youtube.googleapis.com/youtube/v3/playlists?channelId=UCWnPjmqvljcafA0z2U1fwKQ&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&pageToken=CJYBEAA&part=snippet,contentDetails\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Thu, 08 Jun 2023 18:32:25 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      Cache-Control:\n      - private\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: |\n        {\n          \"kind\": \"youtube#playlistListResponse\",\n          \"etag\": \"LtkVzGJmbVeLmrolt2-HpWVKx_Y\",\n          \"nextPageToken\": \"CMgBEAA\",\n          \"prevPageToken\": \"CJYBEAE\",\n          \"pageInfo\": {\n            \"totalResults\": 318,\n            \"resultsPerPage\": 50\n          },\n          \"items\": [\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"0g3drzLY7QaMXX8QxILILU1Z4ns\",\n              \"id\": \"PLE7tQUdRKcyYGj1lGFMzEMRgFPPvJaPIl\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-07-05T19:11:13Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyHACK 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/EZkBDAx1lsk/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/EZkBDAx1lsk/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/EZkBDAx1lsk/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/EZkBDAx1lsk/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/EZkBDAx1lsk/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyHACK 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"gpY2u9m-KVTZALkIlCVVQZVOWhU\",\n              \"id\": \"PLE7tQUdRKcya2z3Q5AiwNqjV968p2TvHu\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-06-29T15:27:31Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GORUCO 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/m76jMaIxJEY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/m76jMaIxJEY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/m76jMaIxJEY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/m76jMaIxJEY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/m76jMaIxJEY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GORUCO 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"nDqST26NxBwjR_0UhlHE42_ScnM\",\n              \"id\": \"PLE7tQUdRKcyZHjxfHBYINIHHfFQXOj3xH\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-06-16T12:34:17Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"PAYMENTSfn 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/3rtMXao9As0/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/3rtMXao9As0/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/3rtMXao9As0/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/3rtMXao9As0/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/3rtMXao9As0/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"PAYMENTSfn 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 22\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"8ENeWtT6NZ1VQ9OJi5SNc2Em6yQ\",\n              \"id\": \"PLE7tQUdRKcyYK5q1bw_YlrnqOFv6_EOF-\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-05-30T13:36:23Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"!!Con 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/zYpXdtWj7BY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/zYpXdtWj7BY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/zYpXdtWj7BY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/zYpXdtWj7BY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/zYpXdtWj7BY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"!!Con 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 32\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"YvQYNBi3ftWJouYUOpg8i1MSdVg\",\n              \"id\": \"PLE7tQUdRKcyak-yFKj5IN3tDYOh5omMrH\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-05-15T14:49:53Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RailsConf 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/zKyv-IGvgGE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/zKyv-IGvgGE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/zKyv-IGvgGE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/zKyv-IGvgGE/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/zKyv-IGvgGE/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RailsConf 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 88\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"L0alO27ZeR0jKl1IydRnnP_61es\",\n              \"id\": \"PLE7tQUdRKcyZZhQVK1UhqKrVHsQ1d0I7J\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-04-11T16:47:18Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Baltimore 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/N6kPvckHXFc/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/N6kPvckHXFc/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/N6kPvckHXFc/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/N6kPvckHXFc/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/N6kPvckHXFc/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Baltimore 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 19\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"jnU-B2HibfHwR-0DSL3gJrgtBmE\",\n              \"id\": \"PLE7tQUdRKcyYH_aU7H-ExE2jrA-60qxH3\",\n              \"snippet\": {\n                \"publishedAt\": \"2018-03-14T15:28:17Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ElixirDaze 2018\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/cwEXyOxbuJ0/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/cwEXyOxbuJ0/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/cwEXyOxbuJ0/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/cwEXyOxbuJ0/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/cwEXyOxbuJ0/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ElixirDaze 2018\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 16\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"4As7XWUnupheTrdjuZwBN679W2g\",\n              \"id\": \"PLE7tQUdRKcyayGHjjxZOmVEGsxX-rczZt\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-11-28T14:54:53Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyConf 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/1-A9eRzCBL0/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/1-A9eRzCBL0/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/1-A9eRzCBL0/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/1-A9eRzCBL0/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/1-A9eRzCBL0/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyConf 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 68\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"5o6T50sL-IatL2UHGIv57p8mW7A\",\n              \"id\": \"PLE7tQUdRKcyZKXWskBTFAYckSviprYreg\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-11-09T18:20:23Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsdays Philly 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/yZ9_A7KlZqM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/yZ9_A7KlZqM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/yZ9_A7KlZqM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/yZ9_A7KlZqM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/yZ9_A7KlZqM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsdays Philly 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 21\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ZCG5ejLEzebBLb7jMccvrnrMIvo\",\n              \"id\": \"PLE7tQUdRKcyb-ZR4SwWQ8Vu3PZxwpFHbG\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-11-03T14:38:01Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Keep Ruby Weird 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/LCH2re51p7g/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/LCH2re51p7g/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/LCH2re51p7g/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/LCH2re51p7g/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/LCH2re51p7g/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Keep Ruby Weird 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 8\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Ln0IDNogXRWXidNbqPNOjs5TUn4\",\n              \"id\": \"PLE7tQUdRKcyarqMQpy-cE0wcSDVTD79IZ\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-10-23T21:06:21Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyConf 2008\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/2YIyf6POs2A/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/2YIyf6POs2A/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/2YIyf6POs2A/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/2YIyf6POs2A/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyConf 2008\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 1\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"buY-oY1EU_c6-m1_9eS6QYtTLYk\",\n              \"id\": \"PLE7tQUdRKcyZfwse2URwQjCI7-qeURNxt\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-10-20T14:42:05Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Boston 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/woSoQq3UkAc/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/woSoQq3UkAc/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/woSoQq3UkAc/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/woSoQq3UkAc/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/woSoQq3UkAc/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Boston 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"nWzokifrnJwMYEcf9g9Z6skf1rc\",\n              \"id\": \"PLE7tQUdRKcybY7O3XEVqxUeeXQeXqiVpH\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-10-12T14:29:01Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Rocky Mountain Ruby 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/8_UoDmJi7U8/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/8_UoDmJi7U8/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/8_UoDmJi7U8/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/8_UoDmJi7U8/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/8_UoDmJi7U8/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Rocky Mountain Ruby 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 10\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"QOdS71uTSH-XlAh_oLf9GvaMyX0\",\n              \"id\": \"PLE7tQUdRKcyZoTZFWWJz4BwBrk3yy0Rr2\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-09-26T14:27:09Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Chicago 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/EJ-CCj1gVTQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/EJ-CCj1gVTQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/EJ-CCj1gVTQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/EJ-CCj1gVTQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/EJ-CCj1gVTQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Chicago 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 23\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"K-9fjgQaYDcCQXBpBCCpKaQVAHk\",\n              \"id\": \"PLE7tQUdRKcyZkGfNhCO77BCxnTf0CpoGn\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-09-01T15:30:10Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RustConf 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/cayNXrTVHMY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/cayNXrTVHMY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/cayNXrTVHMY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/cayNXrTVHMY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/cayNXrTVHMY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RustConf 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"-jmMvqp4UANbsotu3KAu7FO7lKY\",\n              \"id\": \"PLE7tQUdRKcybxOnh9S9Hk-RDRXZRkrWwR\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-06-29T14:26:28Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GORUCO 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/CrqsXO_4Za8/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/CrqsXO_4Za8/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/CrqsXO_4Za8/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/CrqsXO_4Za8/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/CrqsXO_4Za8/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GORUCO 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"jvs4jOHSQr1RngAW0grdPIEh4FI\",\n              \"id\": \"PLE7tQUdRKcybtDB8Z1KbriKaMiup6rypX\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-05-17T23:58:49Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"!!Con 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/z2R97v9n4pI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/z2R97v9n4pI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/z2R97v9n4pI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/z2R97v9n4pI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/z2R97v9n4pI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"!!Con 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 31\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"v4oPC3W66IVAObfGt7Y795ePKz4\",\n              \"id\": \"PLE7tQUdRKcyarr-2jYCnnlb7wl-aEz4xt\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-05-05T14:50:44Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RailsConf 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/Cx6aGMC6MjU/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/Cx6aGMC6MjU/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/Cx6aGMC6MjU/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/Cx6aGMC6MjU/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/Cx6aGMC6MjU/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RailsConf 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 86\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"HrQrWB6Y1tlGCTWrUe8JWwjRHcY\",\n              \"id\": \"PLE7tQUdRKcyZJqN9CA1j9_uyHSqRI6Kpk\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-05-04T20:13:16Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Seattle 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/zF0ftIzxCsw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/zF0ftIzxCsw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/zF0ftIzxCsw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/zF0ftIzxCsw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/zF0ftIzxCsw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Seattle 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 20\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"7y9znCAoA4-WgS1XCLws7JnBYVM\",\n              \"id\": \"PLE7tQUdRKcyacQV3Ymx1jVO08KOizwF5d\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-04-21T14:34:23Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Rockies 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/VgJmY90Djkc/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/VgJmY90Djkc/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/VgJmY90Djkc/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/VgJmY90Djkc/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/VgJmY90Djkc/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Rockies 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 19\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"qoPgXkvCLA52kcqlVp2hcia6mGU\",\n              \"id\": \"PLE7tQUdRKcyZV6tCYvrBLOGoyxUf7s9RT\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-03-16T14:24:46Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ElixirDaze 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/fTYkbPBOt1o/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/fTYkbPBOt1o/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/fTYkbPBOt1o/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/fTYkbPBOt1o/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/fTYkbPBOt1o/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ElixirDaze 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 18\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"z2ATh2sIHI6_bYxH8stMkhP_11s\",\n              \"id\": \"PLE7tQUdRKcyaMEekS1T32hUw19UxzqBEo\",\n              \"snippet\": {\n                \"publishedAt\": \"2017-02-28T15:24:01Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Lonestar Elixir 2017\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/MlqgjoRzhPA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/MlqgjoRzhPA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/MlqgjoRzhPA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/MlqgjoRzhPA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/MlqgjoRzhPA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Lonestar Elixir 2017\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"SX84-SpPs9BnMqzzoFKVbWyJAAw\",\n              \"id\": \"PLE7tQUdRKcybxaRCcMzdMNeQ2GsJRBTOS\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-11-18T15:38:42Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Philly 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Philly 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Q92v2uC-tN8hp3Napedpw-k8Utc\",\n              \"id\": \"PLE7tQUdRKcyaMUYwB6tTX5p2Z6fOCdGRE\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-11-17T20:04:12Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyConf 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/1l3U1X3z0CE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/1l3U1X3z0CE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/1l3U1X3z0CE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/1l3U1X3z0CE/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/1l3U1X3z0CE/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyConf 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 66\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"nlkaZhAcNKsTuFSfdZ1g_eG88jA\",\n              \"id\": \"PLE7tQUdRKcyarDeXmyB9caus1O_g7YiJI\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-11-04T17:16:34Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Keep Ruby Weird 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/SKlIQLb7U00/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/SKlIQLb7U00/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/SKlIQLb7U00/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/SKlIQLb7U00/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/SKlIQLb7U00/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Keep Ruby Weird 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 7\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"8tOw7yeI5Kd0mmugkce-kEsvGiA\",\n              \"id\": \"PLE7tQUdRKcybhZsL8yLODmpwBmerptnqu\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-11-04T15:30:01Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Kansas City 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/jUYfAW2p_SE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/jUYfAW2p_SE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/jUYfAW2p_SE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/jUYfAW2p_SE/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/jUYfAW2p_SE/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Kansas City 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 21\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"MZfpWPNtrme9TeqC8P_KJ5t6J8U\",\n              \"id\": \"PLE7tQUdRKcyY4MP8kRcq05xd8orQI9iKo\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-10-24T15:41:27Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays NYC 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/wAjlUuoE39s/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/wAjlUuoE39s/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/wAjlUuoE39s/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/wAjlUuoE39s/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/wAjlUuoE39s/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays NYC 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 16\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"k8yogT1V4zKDC2elmfAKsiQZU70\",\n              \"id\": \"PLE7tQUdRKcybyoywtp2XxiPaBDnKgD5gk\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-10-19T23:53:54Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Rocky Mountain Ruby 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/bCSOCodWjt0/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/bCSOCodWjt0/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/bCSOCodWjt0/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/bCSOCodWjt0/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/bCSOCodWjt0/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Rocky Mountain Ruby 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"7_ViaqorcPEHafX7CQL87V6xdD0\",\n              \"id\": \"PLE7tQUdRKcyYuRAEjbN3kEKV5UyM3dQJa\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-10-19T15:40:22Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Codedaze 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ENnKqeOj1PM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ENnKqeOj1PM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ENnKqeOj1PM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ENnKqeOj1PM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ENnKqeOj1PM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Codedaze 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 18\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"2qrNjMA1rore96DUuZ_ifQEUzdo\",\n              \"id\": \"PLE7tQUdRKcyZG-gC-_2tDvTXZLoCnjFYW\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-10-06T14:46:38Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Chicago 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/emGKB8TABvI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/emGKB8TABvI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/emGKB8TABvI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/emGKB8TABvI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/emGKB8TABvI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Chicago 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"1ceIEk1ukvR7PTMuAKaZNXY-MJg\",\n              \"id\": \"PLE7tQUdRKcybLShxegjn0xyTTDJeYwEkI\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-10-04T17:28:02Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RustConf 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/pTQxHIzGqFI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/pTQxHIzGqFI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/pTQxHIzGqFI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/pTQxHIzGqFI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/pTQxHIzGqFI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RustConf 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"FEwgl024fkE5KshPC9vl71DWb3M\",\n              \"id\": \"PLE7tQUdRKcyYoiEKWny0Jj72iu564bVFD\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-09-22T16:26:40Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ElixirConf 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/_O-bLuVhcCA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/_O-bLuVhcCA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/_O-bLuVhcCA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/_O-bLuVhcCA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/_O-bLuVhcCA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ElixirConf 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 33\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"62hx8GCtrTtCmULReOZTK_L37a0\",\n              \"id\": \"PLE7tQUdRKcyYB5FVxdKPdUcONVc8jK1Fw\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-08-18T20:13:47Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"OSFeels 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/OdHH5KWGTNo/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/OdHH5KWGTNo/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/OdHH5KWGTNo/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/OdHH5KWGTNo/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/OdHH5KWGTNo/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"OSFeels 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"xlJqZ7DbQ9LRxXa6ufIaroDQBnk\",\n              \"id\": \"PLE7tQUdRKcybaE0Xm_yOK8-a-WAcltv1q\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-07-08T15:09:03Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GORUCO 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ThB2cpPsb1o/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ThB2cpPsb1o/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ThB2cpPsb1o/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ThB2cpPsb1o/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ThB2cpPsb1o/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GORUCO 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"eTihhYqeM7oHZT2n3IO314Pf_-E\",\n              \"id\": \"PLE7tQUdRKcyZbXgQvJTAu3umj90yGWyZb\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-06-09T15:00:09Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Rails Pacific 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/cAeIBMtNQY0/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/cAeIBMtNQY0/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/cAeIBMtNQY0/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/cAeIBMtNQY0/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/cAeIBMtNQY0/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Rails Pacific 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"KZ0WRZGChYOZhgTvxkll6rMA3ow\",\n              \"id\": \"PLE7tQUdRKcyYPrQMmeYDti-yOmt4IJnpI\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-06-02T19:14:58Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Seattle 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/avauW5FAWCw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/avauW5FAWCw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/avauW5FAWCw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/avauW5FAWCw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/avauW5FAWCw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Seattle 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"o8U9fCP3-4QIvKbIt-E0E6Jl0vE\",\n              \"id\": \"PLE7tQUdRKcyZA9auwL8iQffB7efC1Lycz\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-05-30T19:03:30Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"!!Con 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/izq_9s6nkO4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/izq_9s6nkO4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/izq_9s6nkO4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/izq_9s6nkO4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/izq_9s6nkO4/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"!!Con 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 28\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"jRnbPum0P4R2jurPu9WLX4z7Row\",\n              \"id\": \"PLE7tQUdRKcyZGYLfj6oRQWPxB6ijg1YsC\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-05-11T20:59:21Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RailsConf 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/nUVsZ4vS1Y8/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/nUVsZ4vS1Y8/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/nUVsZ4vS1Y8/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/nUVsZ4vS1Y8/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/nUVsZ4vS1Y8/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RailsConf 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 95\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"3xpI0cwqDa9Vu_FGOXcuSQ2pHp0\",\n              \"id\": \"PLE7tQUdRKcyYfmGANUATLpez2Qlf2wV36\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-05-04T19:13:45Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Rockies 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/HmM4V33ReCw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/HmM4V33ReCw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/HmM4V33ReCw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/HmM4V33ReCw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/HmM4V33ReCw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Rockies 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 20\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"GBXUVMRj3t8Pk299-4mspwL7yOE\",\n              \"id\": \"PLE7tQUdRKcyb0PFcp3rGqDb7xnM6c531Z\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-04-21T14:35:10Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby On Ales 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/JXVHvqbfsNI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/JXVHvqbfsNI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/JXVHvqbfsNI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/JXVHvqbfsNI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby On Ales 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 13\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"o37Vt9EYmMEwRcBYQP9Oy_sX0Js\",\n              \"id\": \"PLE7tQUdRKcybjaXiRW_mjOuw1JGrWsCdt\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-04-12T15:50:51Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Mountain West Ruby 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/DQTBmYI_XEE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/DQTBmYI_XEE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/DQTBmYI_XEE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/DQTBmYI_XEE/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/DQTBmYI_XEE/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Mountain West Ruby 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ucyPVUDAhpvv4K78ve9bWg4muig\",\n              \"id\": \"PLE7tQUdRKcya7KMrkWwbRvGfTcI5bQJn0\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-03-25T20:00:06Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"BathRuby 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/b77V0rkr5rk/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/b77V0rkr5rk/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/b77V0rkr5rk/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/b77V0rkr5rk/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/b77V0rkr5rk/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"BathRuby 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"8Loyt_MAxR-OKaugVhcqzW1QYQ8\",\n              \"id\": \"PLE7tQUdRKcya6djUzNtQQYiMdP4_juhHH\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-03-16T12:42:28Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ElixirDaze 2016\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/sr5I5ncg0kU/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/sr5I5ncg0kU/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/sr5I5ncg0kU/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/sr5I5ncg0kU/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/sr5I5ncg0kU/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ElixirDaze 2016\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"UsltGBdDJSuXrb64nn11uMuGszQ\",\n              \"id\": \"PLE7tQUdRKcyafyFUlfIwxn9Gn2vclrrqH\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-01-14T22:28:15Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby|Web Conference 2010\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/lXZQK_7soxg/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/lXZQK_7soxg/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/lXZQK_7soxg/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/lXZQK_7soxg/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/lXZQK_7soxg/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby|Web Conference 2010\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 13\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"0cQ5M9vaqhviYy1wKVuhQANgAA4\",\n              \"id\": \"PLE7tQUdRKcyZM1eJkywHUxhKNYcAV0EXG\",\n              \"snippet\": {\n                \"publishedAt\": \"2016-01-14T22:27:54Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby|Web Conference\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby|Web Conference\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 0\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"50jV8YpudYbBFLOkUARfn2JxJjo\",\n              \"id\": \"PLE7tQUdRKcybh21_zOg8_y4f2oMKDHpUS\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-12-30T01:13:34Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"LambdaConf 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/JxC1ExlLjgw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/JxC1ExlLjgw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/JxC1ExlLjgw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/JxC1ExlLjgw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/JxC1ExlLjgw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"LambdaConf 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 59\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"z6IMmOL81fGEYak6c93gbEDJJnA\",\n              \"id\": \"PLE7tQUdRKcya1ZncJ8Ou7zI0xzggyBRtW\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-12-02T18:39:01Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ArrrrCamp 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/gr45bkXv-JQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/gr45bkXv-JQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/gr45bkXv-JQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/gr45bkXv-JQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/gr45bkXv-JQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ArrrrCamp 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"LfKvAQf2MVWmvnz-iYckkHhGslw\",\n              \"id\": \"PLE7tQUdRKcyYqT3LHMg4iH270kfyENCpp\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-11-20T15:57:47Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyConf 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/zhW1E6_YpC4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/zhW1E6_YpC4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/zhW1E6_YpC4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/zhW1E6_YpC4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/zhW1E6_YpC4/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyConf 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 67\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"oW2wiJzZxYo-RY1r-F72VVdSBn0\",\n              \"id\": \"PLE7tQUdRKcybMGuZ9QIjkXulQE8ddcVx0\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-11-02T16:04:33Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Keep Ruby Weird 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZCfoVQ5_WPE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZCfoVQ5_WPE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZCfoVQ5_WPE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZCfoVQ5_WPE/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZCfoVQ5_WPE/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Keep Ruby Weird 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"mwb8aeur-UljL4H1g6byauFLjF8\",\n              \"id\": \"PLE7tQUdRKcya1YRmHi2CLsk6D4J3PhSw8\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-10-29T20:12:50Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"LA Rubyconf 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/nyx6YF4XSpE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/nyx6YF4XSpE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/nyx6YF4XSpE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/nyx6YF4XSpE/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/nyx6YF4XSpE/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"LA Rubyconf 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            }\n          ]\n        }\n  recorded_at: Thu, 08 Jun 2023 18:32:25 GMT\n- request:\n    method: get\n    uri: https://youtube.googleapis.com/youtube/v3/playlists?channelId=UCWnPjmqvljcafA0z2U1fwKQ&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&pageToken=CMgBEAA&part=snippet,contentDetails\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Thu, 08 Jun 2023 18:32:26 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      Cache-Control:\n      - private\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: |\n        {\n          \"kind\": \"youtube#playlistListResponse\",\n          \"etag\": \"k82GYy0-z_7T8zmoUSN4Ck3ThNE\",\n          \"nextPageToken\": \"CPoBEAA\",\n          \"prevPageToken\": \"CMgBEAE\",\n          \"pageInfo\": {\n            \"totalResults\": 318,\n            \"resultsPerPage\": 50\n          },\n          \"items\": [\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"-EjPBFgddE-tXftbGeccQ6LTSJI\",\n              \"id\": \"PLE7tQUdRKcyZb7L66A9JvYWu_ItURk8qJ\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-10-13T16:38:16Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ElixirConf 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/X8rWK-g8kCQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/X8rWK-g8kCQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/X8rWK-g8kCQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/X8rWK-g8kCQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/X8rWK-g8kCQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ElixirConf 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 19\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"YZ__PkOoqrP1QY-9cQ1bnNgGAtA\",\n              \"id\": \"PLE7tQUdRKcyaj-yF7SCHpd1b45-LXcvft\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-10-12T19:19:24Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Open Source & Feelings 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/EqcuzSwySR4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/EqcuzSwySR4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/EqcuzSwySR4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/EqcuzSwySR4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Open Source & Feelings 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"FRr33AGTd6zK1Vhktf5NKjSQWTg\",\n              \"id\": \"PLE7tQUdRKcyYl3Sn0wM-kC5iN8ziCeg5Q\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-10-08T14:39:25Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"e4e developers conference 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/tWhWZ4RvQG4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/tWhWZ4RvQG4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/tWhWZ4RvQG4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/tWhWZ4RvQG4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"e4e developers conference 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 15\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"TY-5A1V3lYtd1aQhnmcGnjoDOeg\",\n              \"id\": \"PLE7tQUdRKcyaiBPK0LLwNDlLOm_RKS20c\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-09-30T14:13:20Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Rocky Mountain Ruby 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/88mVXnnmWrI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/88mVXnnmWrI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/88mVXnnmWrI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/88mVXnnmWrI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Rocky Mountain Ruby 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 18\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"mY1C4QQLWVP07iVRqMit5lxEPLo\",\n              \"id\": \"PLE7tQUdRKcyYBz6MFMQdRGPXMg3iO6Hpa\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-09-17T14:40:37Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"alterconf Portland 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/Zwsx-9MQqqw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/Zwsx-9MQqqw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/Zwsx-9MQqqw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/Zwsx-9MQqqw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/Zwsx-9MQqqw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"alterconf Portland 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 11\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"6dW1pRf2m8HtqwGrAFYV4Q6LGDU\",\n              \"id\": \"PLE7tQUdRKcyaRCK5zIQFW-5XcPZOE-y9t\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-09-16T14:33:06Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DjangoCon 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/dBeXS5aFLNc/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/dBeXS5aFLNc/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/dBeXS5aFLNc/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/dBeXS5aFLNc/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/dBeXS5aFLNc/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DjangoCon 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 47\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"-0jjCt9dhuMUVjQ4TR21WwBe-bo\",\n              \"id\": \"PLE7tQUdRKcyY5u5CZhGajnXYe9O5uSQwh\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-09-05T13:39:31Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DevOpsDays Chicago 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/319wIaAiaHM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/319wIaAiaHM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/319wIaAiaHM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/319wIaAiaHM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/319wIaAiaHM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DevOpsDays Chicago 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 18\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"7SRu3_xcAZ1kK22NCLPFx3TBGqg\",\n              \"id\": \"PLE7tQUdRKcya2zddMpyXWes7na5YXte4J\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-09-01T15:25:17Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Alterconf Seattle 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/TIgGoxEc-_8/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/TIgGoxEc-_8/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/TIgGoxEc-_8/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/TIgGoxEc-_8/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/TIgGoxEc-_8/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Alterconf Seattle 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 8\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"IQeQ3OwpHKEQdT7AdBG9DjC1wyo\",\n              \"id\": \"PLE7tQUdRKcyY_prUE739kR31k9bzY07zW\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-08-28T18:12:55Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"LoneStarRuby 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/sLAvSgcrgZM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/sLAvSgcrgZM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/sLAvSgcrgZM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/sLAvSgcrgZM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/sLAvSgcrgZM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"LoneStarRuby 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ovoRhZDjabdcdsi2rN7h-NkLvfc\",\n              \"id\": \"PLE7tQUdRKcybdIw61JpCoo89i4pWU5f_t\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-08-14T14:17:07Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RustCamp 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/0qIAk5sTwEo/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/0qIAk5sTwEo/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/0qIAk5sTwEo/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/0qIAk5sTwEo/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/0qIAk5sTwEo/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RustCamp 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 10\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"vPCe5dPzjAkPqtDtRSncMdeJTYA\",\n              \"id\": \"PLE7tQUdRKcyaywLIEdbRSXYPa0hCvaVm_\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-08-13T20:18:19Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"eurucamp 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/RfF6wFK_eFY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/RfF6wFK_eFY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/RfF6wFK_eFY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/RfF6wFK_eFY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/RfF6wFK_eFY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"eurucamp 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 23\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"RC3U4V7Srmi1jWRJsWBg4eIvMV0\",\n              \"id\": \"PLE7tQUdRKcyY8lLkCbIiseqXy_liFzX2F\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-08-08T16:29:03Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"JRuby EU 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/QNeqna_ToPM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/QNeqna_ToPM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/QNeqna_ToPM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/QNeqna_ToPM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/QNeqna_ToPM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"JRuby EU 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ib70jn_LAym0kx-El39WAR7FGvc\",\n              \"id\": \"PLE7tQUdRKcybsEAqkwDahsj05YyIcXXW4\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-07-30T21:35:02Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"JSChannel 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/PNS2bDUXcCM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/PNS2bDUXcCM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/PNS2bDUXcCM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/PNS2bDUXcCM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/PNS2bDUXcCM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"JSChannel 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 13\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"tgxRd3-uuU4nmUd9o672U3eB36o\",\n              \"id\": \"PLE7tQUdRKcyYxzKu9epp2UZqE_WGerCRX\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-07-30T20:21:20Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"farmhouse Conf 2011\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/IgD3Yhv5XoA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/IgD3Yhv5XoA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/IgD3Yhv5XoA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/IgD3Yhv5XoA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/IgD3Yhv5XoA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"farmhouse Conf 2011\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"RkLsKd1-X_aFWi7Cnm0QYJiAYIM\",\n              \"id\": \"PLE7tQUdRKcyZW9ODrWonDfHx1JiUsk3u2\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-07-30T20:21:04Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Farmhouse Conf 2011\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Farmhouse Conf 2011\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 0\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"rBROYT4a2Jg7ZISEvBEdxiizkxM\",\n              \"id\": \"PLE7tQUdRKcyZXUgD1Rn8-8ui3p35xgTPZ\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-07-30T19:59:22Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"HTML5TX 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/wzUcUhjCbIE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/wzUcUhjCbIE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/wzUcUhjCbIE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/wzUcUhjCbIE/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/wzUcUhjCbIE/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"HTML5TX 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 8\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"dSUIo2bKhUm0JDaV_N5PRyHs8E8\",\n              \"id\": \"PLE7tQUdRKcyb1MTWZFk7C2AckCseCQMpB\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-07-14T16:09:14Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"gogaruco 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/WDD_WoXAnQ4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/WDD_WoXAnQ4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/WDD_WoXAnQ4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/WDD_WoXAnQ4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/WDD_WoXAnQ4/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"gogaruco 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Wrh4Y0oRzMH5hZb0detXu_CV1LY\",\n              \"id\": \"PLE7tQUdRKcyaG1xOBeXbz0dlh7LZkFdyH\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-07-03T14:29:41Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Wicked Good Ember 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/IaFjXFuG7OY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/IaFjXFuG7OY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/IaFjXFuG7OY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/IaFjXFuG7OY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/IaFjXFuG7OY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Wicked Good Ember 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"t-e4OtXgn2hHUwC-Han5skrl4WI\",\n              \"id\": \"PLE7tQUdRKcyZQfQPSdtYhxWcHoRqfAESb\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-06-19T12:04:43Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf Atlanta 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/CddCcofWAng/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/CddCcofWAng/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/CddCcofWAng/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/CddCcofWAng/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/CddCcofWAng/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf Atlanta 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"euhnMd_9mmrKI21NtXIcw3g7TO0\",\n              \"id\": \"PLE7tQUdRKcybovPhFaZFGkyPasSAYazMA\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-06-11T18:08:58Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ELCamp 2010\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ELqxCb93Mhs/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ELqxCb93Mhs/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ELqxCb93Mhs/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ELqxCb93Mhs/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ELqxCb93Mhs/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ELCamp 2010\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 6\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"pijvFp4xcJVxrB1qPMTsHklTzWI\",\n              \"id\": \"PLE7tQUdRKcyZdMYKatu_nics8Pkjxl3-F\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-06-10T15:55:58Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RedDotRuby 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/bqWBB8-iEac/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/bqWBB8-iEac/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/bqWBB8-iEac/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/bqWBB8-iEac/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/bqWBB8-iEac/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RedDotRuby 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 25\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"gS0ADQP8woZfPtsMTHpsa2bYwCo\",\n              \"id\": \"PLE7tQUdRKcyalMESCrbAQ8pq-WXNilaTp\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-06-02T17:00:59Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Clojure Conf 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/q3kyx5CXRPU/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/q3kyx5CXRPU/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/q3kyx5CXRPU/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/q3kyx5CXRPU/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/q3kyx5CXRPU/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Clojure Conf 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 21\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"rl23vrbeNREUoJjhbCucA-HnDr0\",\n              \"id\": \"PLE7tQUdRKcyZixHw-ivbA2bzu_TrTE8BZ\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-06-02T15:57:39Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"LA RubyConf 2010\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/fFIQqsII3dM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/fFIQqsII3dM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/fFIQqsII3dM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/fFIQqsII3dM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/fFIQqsII3dM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"LA RubyConf 2010\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 5\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"KkW34aOxkmBcBdPPSBJglfccAVA\",\n              \"id\": \"PLE7tQUdRKcyYViXqN6EPNpX4_H6xQXGXM\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-06-02T15:41:53Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"JRuby 2009\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/qeOxxF08q2o/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/qeOxxF08q2o/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/qeOxxF08q2o/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/qeOxxF08q2o/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/qeOxxF08q2o/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"JRuby 2009\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 2\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"DOfdT6qxj01Q0rqvJNP8mFXUzYI\",\n              \"id\": \"PLE7tQUdRKcyZP7MRrHSiNtmjYtKc_Cc0B\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-06-02T15:18:43Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"LA RubyConf 2009\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/l780SYuz9DI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/l780SYuz9DI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/l780SYuz9DI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/l780SYuz9DI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/l780SYuz9DI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"LA RubyConf 2009\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Oy7sc5j7Q2f5MItQ45FFKOWMvBg\",\n              \"id\": \"PLE7tQUdRKcyYO09VB7mW0xGnzR5qwghxH\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-05-29T16:29:38Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AlterConf San Francisco 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/0c4qCjH4BOk/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/0c4qCjH4BOk/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/0c4qCjH4BOk/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/0c4qCjH4BOk/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/0c4qCjH4BOk/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AlterConf San Francisco 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"O6oTxhT5L0QQbUU_Bis5dio8Hpk\",\n              \"id\": \"PLE7tQUdRKcybcNF-8LsS9dyw3d1WNT6l9\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-05-19T16:09:27Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Scotland Ruby 2011\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/0fMTKqfzz1U/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/0fMTKqfzz1U/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/0fMTKqfzz1U/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/0fMTKqfzz1U/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/0fMTKqfzz1U/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Scotland Ruby 2011\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 34\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"BL6ZJP_126W6BDpZN7A7WLaRW30\",\n              \"id\": \"PLE7tQUdRKcybf82pLlMnPZjAMMMV5DJsK\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-28T18:41:34Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RailsConf 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/aApmOZwdPqA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/aApmOZwdPqA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/aApmOZwdPqA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/aApmOZwdPqA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/aApmOZwdPqA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RailsConf 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 101\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"blOzXgNIYHdi0cvUuTDFyg8g8xs\",\n              \"id\": \"PLE7tQUdRKcybMA_ncEV_0UYwollGNzopO\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-14T21:48:43Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Lone Star Ruby Conference 2008\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/U3ByT_9OZgw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/U3ByT_9OZgw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/U3ByT_9OZgw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/U3ByT_9OZgw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Lone Star Ruby Conference 2008\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 26\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"XeT6tJvJFn8A1i5dei-00nwBCmY\",\n              \"id\": \"PLE7tQUdRKcyaLkdalB5pBAaDEFTFKQfXk\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-14T21:03:49Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Lone star Ruby Conference 2009\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/MwnVwqt0UwE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/MwnVwqt0UwE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/MwnVwqt0UwE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/MwnVwqt0UwE/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Lone star Ruby Conference 2009\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 18\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"R8nm9-JwZyCBbDA2hOIcDUu-BsA\",\n              \"id\": \"PLE7tQUdRKcyaiuoarnSXghr7uWvcynGjv\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-14T19:50:23Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"MountainWest RubyConf 2008\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/HEKIIHfp_MM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/HEKIIHfp_MM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/HEKIIHfp_MM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/HEKIIHfp_MM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"MountainWest RubyConf 2008\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 15\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Hzc2Hefd9fnkQC6aJYzVCtjQDX4\",\n              \"id\": \"PLE7tQUdRKcybYRpsKvf6AQg9DpfzGfLL4\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-14T17:38:17Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Hoedown 2008\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/BPk15rfYRQI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/BPk15rfYRQI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/BPk15rfYRQI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/BPk15rfYRQI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Hoedown 2008\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 15\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"edleD3zjb77fO_hKAS9QcJD_Zhw\",\n              \"id\": \"PLE7tQUdRKcybAVQBEU6tgKiIsfpTw4Bb2\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-14T16:18:30Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AgileRoots2009\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/-_IQw4fI_xo/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/-_IQw4fI_xo/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/-_IQw4fI_xo/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/-_IQw4fI_xo/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/-_IQw4fI_xo/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AgileRoots2009\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 25\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ZwzdhdVS65etvy9H74bP8n0Ukbg\",\n              \"id\": \"PLE7tQUdRKcyYo1VtPcjHhtPxQ0cTzq5Tn\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-08T19:16:45Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"BathRuby 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/8tmOAx4MWuw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/8tmOAx4MWuw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/8tmOAx4MWuw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/8tmOAx4MWuw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/8tmOAx4MWuw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"BathRuby 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"8tj7PI8tmQdzTBcFp76Ejgp1sew\",\n              \"id\": \"PLE7tQUdRKcybZLrVKlDUMgcMEchVqrpl5\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-07T19:02:58Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GoGaRuCo 2010\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/bPPGuecH1QM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/bPPGuecH1QM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/bPPGuecH1QM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/bPPGuecH1QM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/bPPGuecH1QM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GoGaRuCo 2010\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 18\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Jly3rMpUpTL-ykeS447v9J2zUtI\",\n              \"id\": \"PLE7tQUdRKcyak7l7QRTq8GHUc6aDCyIVn\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-07T17:47:49Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby on Ales 2011\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/nXDKF_zxWkQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/nXDKF_zxWkQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/nXDKF_zxWkQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/nXDKF_zxWkQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/nXDKF_zxWkQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby on Ales 2011\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 13\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ZQiB5k_EO7LjS4hbSki68c2GFxI\",\n              \"id\": \"PLE7tQUdRKcybz6z9E0IIppIFIwatM29Us\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-07T16:55:17Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"rocky Mountain Ruby 2011\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/UVqMN3xIFl8/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/UVqMN3xIFl8/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/UVqMN3xIFl8/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/UVqMN3xIFl8/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/UVqMN3xIFl8/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"rocky Mountain Ruby 2011\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 26\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"6GcbdsnCPlqSRwR_zDRyqWNqdEs\",\n              \"id\": \"PLE7tQUdRKcyYAOs4EJPp-a0M2vA20lvhm\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-02T20:22:46Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyConf 2010\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/nwG1Z_uh0sI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/nwG1Z_uh0sI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/nwG1Z_uh0sI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/nwG1Z_uh0sI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/nwG1Z_uh0sI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyConf 2010\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 57\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"rKznjHMqDBO1EuUnA6xmXjhQhPg\",\n              \"id\": \"PLE7tQUdRKcyZ2_s4QaNiap_OVJivkiRSy\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-04-02T16:54:19Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyConf 2009\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/wtShbyuSKKQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/wtShbyuSKKQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/wtShbyuSKKQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/wtShbyuSKKQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/wtShbyuSKKQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyConf 2009\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 41\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"QbvfXzdl9SwYeEd7iMvIw3KHha8\",\n              \"id\": \"PLE7tQUdRKcybKenrGRnvqtCIsniljlpIp\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-03-29T15:17:58Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"MWRC 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/2Yx1x8Tl1KM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/2Yx1x8Tl1KM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/2Yx1x8Tl1KM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/2Yx1x8Tl1KM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/2Yx1x8Tl1KM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"MWRC 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 20\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"v0Xs-uOqC7CaFBbkyo1gHpYjY4U\",\n              \"id\": \"PLE7tQUdRKcyYfIGU_Zm5saQWw6BzPvD_h\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-03-27T12:08:39Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"MWJS 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/hbuLw4sauCw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/hbuLw4sauCw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/hbuLw4sauCw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/hbuLw4sauCw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/hbuLw4sauCw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"MWJS 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 20\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"YklA0imkgocz1J3xHRcD1PX1Yqs\",\n              \"id\": \"PLE7tQUdRKcyZ4mt3S72tofVbSk3SRWrtz\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-03-24T20:47:48Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Cascadia 2011\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/_MiDSdT5TFo/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/_MiDSdT5TFo/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/_MiDSdT5TFo/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/_MiDSdT5TFo/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/_MiDSdT5TFo/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Cascadia 2011\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 16\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"k4SrZ1DJJweDc4-zeOYn6AYSvuc\",\n              \"id\": \"PLE7tQUdRKcyYk-_BMaCwBWgBzAuNcwMGZ\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-03-24T20:11:10Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GoRuCo 2009\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/_I4hIdjO5vk/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/_I4hIdjO5vk/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/_I4hIdjO5vk/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/_I4hIdjO5vk/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/_I4hIdjO5vk/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GoRuCo 2009\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 8\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ZKA2rPOwsgmomm6WWDFYl1CaBq4\",\n              \"id\": \"PLE7tQUdRKcyaUIjpEKMLTKc32kr4vseg9\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-03-13T14:41:20Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby on Ales 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/l1AGge1lcTw/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/l1AGge1lcTw/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/l1AGge1lcTw/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/l1AGge1lcTw/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/l1AGge1lcTw/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby on Ales 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 18\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"4NdZ2cPc8zjLPzhdArOdOHkBcgg\",\n              \"id\": \"PLE7tQUdRKcyZ4-RqZpp5lKVG5GPGWyJVG\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-03-09T08:42:54Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby on Ales 2015 - Live Stream\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/U_2eeJndd3c/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/U_2eeJndd3c/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/U_2eeJndd3c/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/U_2eeJndd3c/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/U_2eeJndd3c/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby on Ales 2015 - Live Stream\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 3\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"b8_iqQHApfEi4usRsUl1D7p-zGs\",\n              \"id\": \"PLE7tQUdRKcyacwiUPs0CjPYt6tJub4xXU\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-03-06T19:51:17Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"EmberConf 2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/o12-90Dm-Qs/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/o12-90Dm-Qs/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/o12-90Dm-Qs/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/o12-90Dm-Qs/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/o12-90Dm-Qs/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"EmberConf 2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 23\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"DcjR8XYL9RneudYhozeLBoGChXM\",\n              \"id\": \"PLE7tQUdRKcya5OgHPof3Jrq0VNmvxMEWX\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-02-17T19:34:40Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"MWRC 2011\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/C6y4YkpaT_I/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/C6y4YkpaT_I/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/C6y4YkpaT_I/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/C6y4YkpaT_I/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/C6y4YkpaT_I/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"MWRC 2011\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 20\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"5J6k-wiARLBEZCjGIXZJBmOa7Xg\",\n              \"id\": \"PLE7tQUdRKcyaIA3Do7AXp2ak7yBD_fLL8\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-02-12T19:48:31Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Conference 2008\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/9cN05h8z-OI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/9cN05h8z-OI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/9cN05h8z-OI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/9cN05h8z-OI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Conference 2008\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 32\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"QWb9DvNP1h8aBFZvSs26Uy4-e0A\",\n              \"id\": \"PLE7tQUdRKcyaYj1a11_bIFDHHrRs8_y6b\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-02-12T16:31:42Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"AgileRoots2010\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/IShfP-loms8/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/IShfP-loms8/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/IShfP-loms8/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/IShfP-loms8/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/IShfP-loms8/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"AgileRoots2010\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 27\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"YDfPHBuLkBsiDmqBgTLGvFLvbUo\",\n              \"id\": \"PLE7tQUdRKcyYk99N95TtGtLoeZJQwbWEc\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-02-11T23:59:36Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Mountain West Ruby 2010\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/_mN4HJIhpYo/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/_mN4HJIhpYo/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/_mN4HJIhpYo/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/_mN4HJIhpYo/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/_mN4HJIhpYo/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Mountain West Ruby 2010\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 20\n              }\n            }\n          ]\n        }\n  recorded_at: Thu, 08 Jun 2023 18:32:26 GMT\n- request:\n    method: get\n    uri: https://youtube.googleapis.com/youtube/v3/playlists?channelId=UCWnPjmqvljcafA0z2U1fwKQ&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&pageToken=CPoBEAA&part=snippet,contentDetails\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Thu, 08 Jun 2023 18:32:26 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      Cache-Control:\n      - private\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: |\n        {\n          \"kind\": \"youtube#playlistListResponse\",\n          \"etag\": \"UxQkdpKFnVChz8PIvqlsSA4XPaY\",\n          \"nextPageToken\": \"CKwCEAA\",\n          \"prevPageToken\": \"CPoBEAE\",\n          \"pageInfo\": {\n            \"totalResults\": 318,\n            \"resultsPerPage\": 50\n          },\n          \"items\": [\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"oQoYPZz19E5Q-6urC0-5OID4glE\",\n              \"id\": \"PLE7tQUdRKcyYdUzBfRi0kwi2NAG1fVQDQ\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-02-04T14:19:08Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GCRC2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/yTkaq26YgDU/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/yTkaq26YgDU/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/yTkaq26YgDU/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/yTkaq26YgDU/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/yTkaq26YgDU/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GCRC2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 5\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"795uUv45LSb9p98dthOGspWV8oI\",\n              \"id\": \"PLE7tQUdRKcyZJzBSD57BjH9PcO-2Uipb3\",\n              \"snippet\": {\n                \"publishedAt\": \"2015-01-07T18:05:19Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"PDXRB2015\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/tIdC7nS5kWI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/tIdC7nS5kWI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/tIdC7nS5kWI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/tIdC7nS5kWI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/tIdC7nS5kWI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"PDXRB2015\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 2\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"JVv9gARjlAiw0Xr0Ynq-gePBnyQ\",\n              \"id\": \"PLE7tQUdRKcyZMOlaJmolqtOyD-T8TUAPI\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-12-12T16:34:40Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"PNWS 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/J8FPrcsfqeY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/J8FPrcsfqeY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/J8FPrcsfqeY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/J8FPrcsfqeY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/J8FPrcsfqeY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"PNWS 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 16\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"I1OqUweZYAVOCaK8FLIT3Bb8tFg\",\n              \"id\": \"PLE7tQUdRKcyZN30T1pcmNeO_hvCgYhnXY\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-12-02T20:43:49Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Keep Ruby Weird 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/pnnFJiQsp8k/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/pnnFJiQsp8k/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/pnnFJiQsp8k/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/pnnFJiQsp8k/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/pnnFJiQsp8k/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Keep Ruby Weird 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"tpEX8j6goqGGaftVw_6awGTrcWY\",\n              \"id\": \"PLE7tQUdRKcyYajZ5aZlJf1g2u5Boq-jic\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-12-02T17:03:14Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyConf 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/teTpPCwdh7g/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/teTpPCwdh7g/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/teTpPCwdh7g/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/teTpPCwdh7g/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/teTpPCwdh7g/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyConf 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 66\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"_JXNtPeYT-Wd3ux1mSHfwXJeo44\",\n              \"id\": \"PLE7tQUdRKcybZxtUSa7AhU5lamKrLZtBr\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-11-20T21:36:02Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyConf 2014 Live Stream\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/img/no_thumbnail.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyConf 2014 Live Stream\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 0\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"0MzdNKcLoeufR2GqB0v75M4XXB8\",\n              \"id\": \"PLE7tQUdRKcybnl3Ql5v9_p_vH7ypfe46H\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-11-13T18:45:58Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ArrrrCamp 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/c6rtwWy5V8w/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/c6rtwWy5V8w/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/c6rtwWy5V8w/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/c6rtwWy5V8w/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/c6rtwWy5V8w/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ArrrrCamp 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"EvS6z6is3on37uk1dWUV2FopFSM\",\n              \"id\": \"PLE7tQUdRKcybbJ1kUMUR8iaQpOBWofMvl\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-10-24T17:33:13Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Nickel City Ruby 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/rOE9ydzHQ88/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/rOE9ydzHQ88/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/rOE9ydzHQ88/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/rOE9ydzHQ88/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/rOE9ydzHQ88/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Nickel City Ruby 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 15\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"0vT-2fmKkTulqWU2AkwI2Wkpxlg\",\n              \"id\": \"PLE7tQUdRKcyYcpjBPDgGW03ZpA9gk0AnR\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-10-18T05:56:28Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Rocky Mountain Ruby 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/CXdULnPpMsc/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/CXdULnPpMsc/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/CXdULnPpMsc/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/CXdULnPpMsc/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/CXdULnPpMsc/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Rocky Mountain Ruby 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 16\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"4Rtw9AUY0TWLs6QqVElmHVPhttQ\",\n              \"id\": \"PLE7tQUdRKcyZyfGTPHfnylib0CqfZn-3Y\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-10-02T15:33:59Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GoGaRuCo2014-\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ei_tanu3UyQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ei_tanu3UyQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ei_tanu3UyQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ei_tanu3UyQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ei_tanu3UyQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GoGaRuCo2014-\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"qnBxV_xMixlykMDvf1JqHlKen68\",\n              \"id\": \"PLE7tQUdRKcyYEg0ODqr1axNRncizpHjKp\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-09-29T14:43:32Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"JS.Geo\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/2H9g2DBIuLA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/2H9g2DBIuLA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/2H9g2DBIuLA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/2H9g2DBIuLA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/2H9g2DBIuLA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"JS.Geo\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"wCUD1lFTwKx-9jqT29uiLSw8TYA\",\n              \"id\": \"PLE7tQUdRKcyY88yOR9ALZU_2t1HniBhvz\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-09-22T12:37:14Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"e4e Developers Conference 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/HeWiZvltQKI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/HeWiZvltQKI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/HeWiZvltQKI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/HeWiZvltQKI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/HeWiZvltQKI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"e4e Developers Conference 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"J9XU5uYvQXT8ax7wYp6wUA36pyw\",\n              \"id\": \"PLE7tQUdRKcyZQ5hO_VRRk7qxuaTV8TMq8\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-09-16T13:51:38Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Los Angeles Ruby Conf 2011\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/sru_ywjC2oo/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/sru_ywjC2oo/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/sru_ywjC2oo/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/sru_ywjC2oo/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/sru_ywjC2oo/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Los Angeles Ruby Conf 2011\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 11\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"n2YL4q-bcrOGKtCFuzreE2ZXSkc\",\n              \"id\": \"PLE7tQUdRKcybbNiuhLcc3h6WzmZGVBMr3\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-09-10T20:04:16Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"DjangoCon 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/cqP758k1BaQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/cqP758k1BaQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/cqP758k1BaQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/cqP758k1BaQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/cqP758k1BaQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"DjangoCon 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 45\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"0DCtKR7lf85SCqygBNztsxvzJeY\",\n              \"id\": \"PLE7tQUdRKcyaL7R9d_WR760gIcu_qxYLD\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-08-18T20:05:21Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Cascadia Ruby 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/A3vR9GIC_MA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/A3vR9GIC_MA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/A3vR9GIC_MA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/A3vR9GIC_MA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/A3vR9GIC_MA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Cascadia Ruby 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 16\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ZYLLQIPLIHHqOtsWICYXnMHZ-e8\",\n              \"id\": \"PLE7tQUdRKcyakbmyFcmznq2iNtL80mCsT\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-08-07T13:42:59Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ElixirConf 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/rt8h_xeESLg/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/rt8h_xeESLg/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/rt8h_xeESLg/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/rt8h_xeESLg/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/rt8h_xeESLg/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ElixirConf 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 16\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"6EJgV_nnhaIo9-12swjJiUap4x0\",\n              \"id\": \"PLE7tQUdRKcyZ7quxtkav1TYj8zOMqQQQV\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-07-21T20:54:01Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RedDotRuby 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/bp7CKPsJJJ0/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/bp7CKPsJJJ0/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/bp7CKPsJJJ0/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/bp7CKPsJJJ0/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/bp7CKPsJJJ0/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RedDotRuby 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 26\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Zp3PNroEgEHeiN7MU8I9_1G2tGU\",\n              \"id\": \"PLE7tQUdRKcyZj4qdxsQKW4-8KnlpoGfgf\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-07-15T14:09:12Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GoRuCo 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/sB9_hVO9Cik/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/sB9_hVO9Cik/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/sB9_hVO9Cik/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/sB9_hVO9Cik/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/sB9_hVO9Cik/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GoRuCo 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"CHjeu6lcS8BRy99iJCYvp10c59M\",\n              \"id\": \"PLE7tQUdRKcyb5nDA1Uzg74kQaCocnIrJD\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-06-19T17:14:31Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Inspect 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/28WqGMNddFk/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/28WqGMNddFk/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/28WqGMNddFk/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/28WqGMNddFk/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/28WqGMNddFk/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Inspect 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"U4aYDh8YzZrJXVvtnk4vuwVHh60\",\n              \"id\": \"PLE7tQUdRKcya3NQjvo-I_HFKEzx0SFymY\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-05-19T02:26:35Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"OpenStack On Ales 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/KeTWBoZzgCA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/KeTWBoZzgCA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/KeTWBoZzgCA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/KeTWBoZzgCA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/KeTWBoZzgCA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"OpenStack On Ales 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 10\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"BcehMmKPfDBj-zidaa8VuIqUlIo\",\n              \"id\": \"PLE7tQUdRKcyaYIfZHcUSrofGARLL7-BfW\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-05-15T00:10:55Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ignite Buffalo 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/b8B6TiOc7_o/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/b8B6TiOc7_o/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/b8B6TiOc7_o/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/b8B6TiOc7_o/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/b8B6TiOc7_o/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ignite Buffalo 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 11\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"_krfaAhR3RuAoVR4CYa9thi_GUY\",\n              \"id\": \"PLE7tQUdRKcyYYHU2QwS8gQzkQkaOn_lHr\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-05-09T14:11:54Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby on Ales 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/zkaeziqQs2I/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/zkaeziqQs2I/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/zkaeziqQs2I/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/zkaeziqQs2I/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/zkaeziqQs2I/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby on Ales 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"27t4RcvKl40QsP4wfE_fIPvNljE\",\n              \"id\": \"PLE7tQUdRKcyZ5jfnbS_osIoWzK_FrwKz5\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-05-05T16:25:32Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RailsConf 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/9LfmrkyP81M/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/9LfmrkyP81M/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/9LfmrkyP81M/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/9LfmrkyP81M/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/9LfmrkyP81M/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RailsConf 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 99\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"49giUaMDpR1I2lxZtmYpLu7FBes\",\n              \"id\": \"PLE7tQUdRKcyb-k4TMNm2K59-sVlUJumw7\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-05-05T13:59:43Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GopherCon 2014\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/VoS7DsT1rdM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/VoS7DsT1rdM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/VoS7DsT1rdM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/VoS7DsT1rdM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/VoS7DsT1rdM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GopherCon 2014\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 23\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"jXNxUih6Ab1NvUHqZQC9kClfnf4\",\n              \"id\": \"PLE7tQUdRKcyaOyfBnAndJxQ9PNVmKva0d\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-04-22T02:17:23Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"EmberConf 2014\",\n                \"description\": \"EmberConf 2014 took place at The Nines in Portland Oregon on March 25 and 26, 2014.\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/cp1Jk92ve2s/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/cp1Jk92ve2s/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/cp1Jk92ve2s/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/cp1Jk92ve2s/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/cp1Jk92ve2s/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"EmberConf 2014\",\n                  \"description\": \"EmberConf 2014 took place at The Nines in Portland Oregon on March 25 and 26, 2014.\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 23\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"HNk7AgOeexIvdBcjoVQ-xDmdx_Y\",\n              \"id\": \"PLE7tQUdRKcyYOPhZMxw2h84PpO8CIjqsK\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-01-13T03:50:14Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Wicked Good Ruby 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/BeyTsdkItg4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/BeyTsdkItg4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/BeyTsdkItg4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/BeyTsdkItg4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/BeyTsdkItg4/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Wicked Good Ruby 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 26\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"0LuyZShnJeKv3Y_PdfvQ_6BX3Wc\",\n              \"id\": \"PLE7tQUdRKcyYL7sAL9Hy0DxXyUr-9hn5n\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-01-13T03:20:38Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Cascadia Ruby 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/qAEn3pzOWIQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/qAEn3pzOWIQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/qAEn3pzOWIQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/qAEn3pzOWIQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/qAEn3pzOWIQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Cascadia Ruby 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 19\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"AKcjpgbPAPLoVCmqG9xD08Jje9s\",\n              \"id\": \"PLE7tQUdRKcyb5I7Bk1POYW4udtHMUMkK7\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-01-13T02:53:28Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Conf 2013 - Miami Beach, FL\",\n                \"description\": \"Ruby Conf 2013 - Held in Miami Beach Florida on November 6,7, and 8, 2013.\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/gJOkpP__dY4/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/gJOkpP__dY4/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/gJOkpP__dY4/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/gJOkpP__dY4/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/gJOkpP__dY4/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Conf 2013 - Miami Beach, FL\",\n                  \"description\": \"Ruby Conf 2013 - Held in Miami Beach Florida on November 6,7, and 8, 2013.\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 50\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"1Jdl6pjZl7N1lhgEsL0z7L5bEt4\",\n              \"id\": \"PLE7tQUdRKcyZsYwv3RdGxt0_TOvbyhspX\",\n              \"snippet\": {\n                \"publishedAt\": \"2014-01-13T02:52:42Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"ArrrrCamp 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/zSX-SsWe-0M/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/zSX-SsWe-0M/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/zSX-SsWe-0M/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/zSX-SsWe-0M/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/zSX-SsWe-0M/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"ArrrrCamp 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 22\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"cpYgGpyhoL53p2uDW1rp1uO9h1o\",\n              \"id\": \"PLE7tQUdRKcyar0ThQuWKh9XiT8MPUCZHn\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-11-29T17:13:57Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Nickel City Ruby 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/hfsC5Hj6qVI/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/hfsC5Hj6qVI/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/hfsC5Hj6qVI/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/hfsC5Hj6qVI/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/hfsC5Hj6qVI/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Nickel City Ruby 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"mg7OcQgjfe7lKRyCRZqnNx08MXc\",\n              \"id\": \"PLE7tQUdRKcyYqVZi0LIbAsfwv_Jr-rrua\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-11-28T21:00:38Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Cascadia Ruby 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/MkoTmq3I4DM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/MkoTmq3I4DM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/MkoTmq3I4DM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/MkoTmq3I4DM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/MkoTmq3I4DM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Cascadia Ruby 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 8\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Gw6Cz1iomwVteSUIGWC3uBSHjk4\",\n              \"id\": \"PLE7tQUdRKcyZ4RsnTOCdqgWPXtm1h_Ale\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-10-17T23:36:55Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GoRuCo 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/7ml8t6uw8ho/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/7ml8t6uw8ho/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/7ml8t6uw8ho/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/7ml8t6uw8ho/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/7ml8t6uw8ho/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GoRuCo 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 14\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"6JpsOt7gBnsSYj7lw9E3KMQtfjk\",\n              \"id\": \"PLE7tQUdRKcyb03P3xsIBPGoPycg03fEJ1\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-10-17T23:36:14Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Burlington Ruby Conf 2013\",\n                \"description\": \"A single track two day conference about Ruby held in Burlington, Vermont.\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/3P3UTKeJYxY/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/3P3UTKeJYxY/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/3P3UTKeJYxY/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/3P3UTKeJYxY/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/3P3UTKeJYxY/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Burlington Ruby Conf 2013\",\n                  \"description\": \"A single track two day conference about Ruby held in Burlington, Vermont.\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"-RwExkIGiyXO6VyO7NXi-kA9NtQ\",\n              \"id\": \"PLE7tQUdRKcyYAoKgLbr6Ug_OX1WfrtuPq\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-10-17T23:34:12Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GoGaRuCo 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/RPxvx9OkNic/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/RPxvx9OkNic/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/RPxvx9OkNic/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/RPxvx9OkNic/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/RPxvx9OkNic/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GoGaRuCo 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 24\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"ZfEdaS8xB36Q9sGbfc5P5oNAWCw\",\n              \"id\": \"PLE7tQUdRKcybxgqVTwuOA12wr5Gn2M2Pp\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-06-25T15:16:20Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Rails Conf 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/TslkdT3PfKc/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/TslkdT3PfKc/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/TslkdT3PfKc/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/TslkdT3PfKc/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/TslkdT3PfKc/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Rails Conf 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 70\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Z27LNmQCGuDX3kA_rvysM0LsuWU\",\n              \"id\": \"PLE7tQUdRKcyaUov1d_26VGMXVkjT2Fz00\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-05-28T05:46:11Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Lone Star Ruby Conference 2011\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/oTb1kutEEa8/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/oTb1kutEEa8/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/oTb1kutEEa8/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/oTb1kutEEa8/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/oTb1kutEEa8/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Lone Star Ruby Conference 2011\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 28\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Zvlrdyt0tu0dABdNsad7SMitwIc\",\n              \"id\": \"PLE7tQUdRKcyZ09J3-EXxzX2yCgl4a5qUk\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-04-28T03:04:39Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Los Angeles Ruby Conf 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/gB-JSh1EVME/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/gB-JSh1EVME/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/gB-JSh1EVME/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/gB-JSh1EVME/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/gB-JSh1EVME/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Los Angeles Ruby Conf 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 16\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"6ITmeSTcmKJmRCtj6rjTV7rCcf0\",\n              \"id\": \"PLE7tQUdRKcyZwIqysBb4BVWZ5hzWPPylr\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-04-28T03:03:33Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Midwest 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZLFeqmh7Dec/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZLFeqmh7Dec/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZLFeqmh7Dec/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZLFeqmh7Dec/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZLFeqmh7Dec/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Midwest 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 20\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"jlYQGkU55vjOXzN01Cyem-lUu-c\",\n              \"id\": \"PLE7tQUdRKcyYgGVJqolUSSpaKDBiVx1-5\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-04-28T03:03:03Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Mountain West Ruby 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/sOJaGIP03As/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/sOJaGIP03As/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/sOJaGIP03As/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/sOJaGIP03As/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/sOJaGIP03As/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Mountain West Ruby 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 32\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"dn0JuAK_vKxSZXHbbF7x44IAc3s\",\n              \"id\": \"PLE7tQUdRKcyYFWVTnMJswHvCJNcnatTXI\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-04-28T03:01:53Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Farm House Conf 3\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/BNP_FGm_Vlg/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/BNP_FGm_Vlg/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/BNP_FGm_Vlg/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/BNP_FGm_Vlg/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/BNP_FGm_Vlg/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Farm House Conf 3\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 10\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"iDBpkgYHAyiBgqEhErXd-B6w4oQ\",\n              \"id\": \"PLE7tQUdRKcyYWUJr4Dg7lcChFg6RSpEU2\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-04-16T15:11:52Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Erlang DC 2013\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/8fnPVTewLEc/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/8fnPVTewLEc/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/8fnPVTewLEc/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/8fnPVTewLEc/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/8fnPVTewLEc/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Erlang DC 2013\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 10\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"FC1Jae3oXytnwS3jrlWpetIs_88\",\n              \"id\": \"PLE7tQUdRKcyY_DtwggfJCsRyZPSs-rmUh\",\n              \"snippet\": {\n                \"publishedAt\": \"2013-04-14T00:22:10Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Conference 2007\",\n                \"description\": \"This was the first Ruby Conference recorded by Confreaks, in 2007.\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/QAThcdbrbVg/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/QAThcdbrbVg/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/QAThcdbrbVg/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/QAThcdbrbVg/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Conference 2007\",\n                  \"description\": \"This was the first Ruby Conference recorded by Confreaks, in 2007.\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 32\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"xSYLKohR5HGdtpoLbx0-LooCjZA\",\n              \"id\": \"PLE7tQUdRKcyb2J9YQH65NIEcVpmK6Rgct\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-11-16T18:52:17Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Conference 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/Wh0BHJ7fUoc/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/Wh0BHJ7fUoc/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/Wh0BHJ7fUoc/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/Wh0BHJ7fUoc/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/Wh0BHJ7fUoc/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Conference 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 50\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"yhAAABS39keww0UR4hnkOgVxPjw\",\n              \"id\": \"PLE7tQUdRKcybiRW_A4bTAHGKT1R91wJuC\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-11-11T11:19:30Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Hoedown 2007\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/uzONDRUKIMs/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/uzONDRUKIMs/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/uzONDRUKIMs/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/uzONDRUKIMs/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Hoedown 2007\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 9\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Zawl6U0OSZ9azI0kuiG17_cQuP0\",\n              \"id\": \"PLE7tQUdRKcyYeOuoaep10DIdtaBuAWa4V\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-11-11T07:16:40Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Manor 2\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/xPDLOM_I910/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/xPDLOM_I910/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/xPDLOM_I910/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/xPDLOM_I910/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Manor 2\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 8\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"7tuLHarGoP_CxAEAR5JrUslCWaU\",\n              \"id\": \"PLE7tQUdRKcyZdr1V8Nwygse2G1s084-66\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-11-10T23:52:37Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Manor 3\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/VUhlNx_-wYk/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/VUhlNx_-wYk/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/VUhlNx_-wYk/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/VUhlNx_-wYk/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Manor 3\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 8\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"LjPrIqdHj9Ps-Bv7dAplRWkEdVY\",\n              \"id\": \"PLE7tQUdRKcyYHiVRVRu5-fKpdRszKyi12\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-10-26T08:15:19Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Rocky Mountain Ruby 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/o0Zci00Y3ak/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/o0Zci00Y3ak/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/o0Zci00Y3ak/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/o0Zci00Y3ak/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/o0Zci00Y3ak/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Rocky Mountain Ruby 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 24\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"2FVDUusZCc7PE6FYjEsNzD6UmD4\",\n              \"id\": \"PLE7tQUdRKcyb2zm3xjrG4_Ot98HIXObZv\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-10-02T18:23:43Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby on Ales 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/0GNilQImFZ8/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/0GNilQImFZ8/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/0GNilQImFZ8/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/0GNilQImFZ8/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/0GNilQImFZ8/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby on Ales 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 6\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"j2EK2aQ0XmuEUoTvOfauhL8sXNI\",\n              \"id\": \"PLE7tQUdRKcyZ0cXIcLlmsFfhjAzg5uP0b\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-09-18T06:56:04Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"MWRC 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/r4lE4bxMJmk/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/r4lE4bxMJmk/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/r4lE4bxMJmk/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/r4lE4bxMJmk/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/r4lE4bxMJmk/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"MWRC 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 7\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"P3HdKY1dn9vfHFWtOoiDh-R742w\",\n              \"id\": \"PLE7tQUdRKcyYuXoQpnzNLewBH_7LgamP_\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-09-18T06:55:29Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Golden Gate Ruby Conference 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/Rvxcc46fox0/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/Rvxcc46fox0/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/Rvxcc46fox0/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/Rvxcc46fox0/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/Rvxcc46fox0/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Golden Gate Ruby Conference 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 4\n              }\n            }\n          ]\n        }\n  recorded_at: Thu, 08 Jun 2023 18:32:26 GMT\n- request:\n    method: get\n    uri: https://youtube.googleapis.com/youtube/v3/playlists?channelId=UCWnPjmqvljcafA0z2U1fwKQ&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&pageToken=CKwCEAA&part=snippet,contentDetails\n    body:\n      encoding: US-ASCII\n      string: ''\n    headers:\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Thu, 08 Jun 2023 18:32:27 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      Cache-Control:\n      - private\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: |\n        {\n          \"kind\": \"youtube#playlistListResponse\",\n          \"etag\": \"gb9Co0J_bTkGmvLNVKw7S0H1Shg\",\n          \"prevPageToken\": \"CKwCEAE\",\n          \"pageInfo\": {\n            \"totalResults\": 318,\n            \"resultsPerPage\": 50\n          },\n          \"items\": [\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"1pTAJyF20uDxwPSSvCXBEVEiGF0\",\n              \"id\": \"PLE7tQUdRKcyaYfWFMPex97EXoYt7uKq9-\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-09-15T06:02:47Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Madison Ruby 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/Z0yVI1O4h9I/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/Z0yVI1O4h9I/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/Z0yVI1O4h9I/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/Z0yVI1O4h9I/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/Z0yVI1O4h9I/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Madison Ruby 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 26\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"tR72CAxVODHLROpNcRe9EE2LJEE\",\n              \"id\": \"PLE7tQUdRKcybjG39O8JVkgnWSNNPwL2PA\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-09-09T21:26:42Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Acts as Conference 2009\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ad9790QJHQA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ad9790QJHQA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ad9790QJHQA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ad9790QJHQA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ad9790QJHQA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Acts as Conference 2009\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 36\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"KBVAkN7xGOZxNcVW1kKuuV4Ks1A\",\n              \"id\": \"PLE7tQUdRKcyY6qiiM02iD1Rl5xm8Yfa3A\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-09-09T21:25:31Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"MWRC 2008\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/HWeQYcAc-eM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/HWeQYcAc-eM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/HWeQYcAc-eM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/HWeQYcAc-eM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"MWRC 2008\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"yPdndxDXi6gpgZv01VuoRF8TwjY\",\n              \"id\": \"PL5FDB952E58A82293\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-08-23T17:58:24Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"jQuery Conference 2012 - San Francisco\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/fEeQEZL_AdA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/fEeQEZL_AdA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/fEeQEZL_AdA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/fEeQEZL_AdA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/fEeQEZL_AdA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"jQuery Conference 2012 - San Francisco\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 23\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"dwZxFmR3VPezRaqQh2PpP4AHaiw\",\n              \"id\": \"PL4AE036FF039338BD\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-08-21T16:08:54Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Cascadia Ruby 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZUMku_T97fM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZUMku_T97fM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZUMku_T97fM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZUMku_T97fM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ZUMku_T97fM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Cascadia Ruby 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"0GunMZ68ucy1XbKPoenpM6z1X1A\",\n              \"id\": \"PLE36109149D271880\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-08-16T08:52:52Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"MWRC 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/6hBghQ-Ic_o/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/6hBghQ-Ic_o/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/6hBghQ-Ic_o/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/6hBghQ-Ic_o/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/6hBghQ-Ic_o/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"MWRC 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 6\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"TKXQPKye_2FIsDe4yCgckLtrork\",\n              \"id\": \"PLB3ABD9A8B27F76D8\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-08-07T03:09:06Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"MWRC 2009\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/HUOWKqeoFxQ/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/HUOWKqeoFxQ/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/HUOWKqeoFxQ/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/HUOWKqeoFxQ/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/HUOWKqeoFxQ/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"MWRC 2009\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 7\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"jF9jFmrBBsuXRL8H3Sf-AANob7o\",\n              \"id\": \"PLFE5C32B5513E0555\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-07-01T18:32:26Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GORUCO 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/KaEqZtulOus/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/KaEqZtulOus/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/KaEqZtulOus/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/KaEqZtulOus/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/KaEqZtulOus/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GORUCO 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 13\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"-Fc8NZMf_3w9X8g1DrQb6U38xGk\",\n              \"id\": \"PL2558915D1551E897\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-05-24T03:40:06Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Farmhouse Conf 2\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ASRk9tcrero/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ASRk9tcrero/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ASRk9tcrero/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ASRk9tcrero/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/ASRk9tcrero/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Farmhouse Conf 2\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 11\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"eN4oTDK1t0v890tGq_Qys6h8k0s\",\n              \"id\": \"PL50D7368F56665FAE\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-05-14T18:16:07Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"RubyConf India 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/ntIzf9onRqA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/ntIzf9onRqA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/ntIzf9onRqA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/ntIzf9onRqA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"RubyConf India 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 17\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"17QV4I1y6HniHGjhJSm4nE07nTk\",\n              \"id\": \"PLF16D2F3A8469021E\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-05-01T20:49:16Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Rails Conf 2012\",\n                \"description\": \"Rails Conf 2012 was held in Austin, Texas on April 23 - 25, 2012.\\r\\n\\r\\nIt brought over 1200 developers from all of the world to discuss topics related to software development utilizing Ruby and the web framework Rails, as well as related and surrounding technologies and practices.  The organizers had the event recorded by Confreaks and the presenters agreed to release the videos of the presentations under a Creative Commons license.  If you enjoy these videos be sure and let the presenters and the folks at Ruby Central know.\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/VOFTop3AMZ8/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/VOFTop3AMZ8/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/VOFTop3AMZ8/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/VOFTop3AMZ8/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/VOFTop3AMZ8/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Rails Conf 2012\",\n                  \"description\": \"Rails Conf 2012 was held in Austin, Texas on April 23 - 25, 2012.\\r\\n\\r\\nIt brought over 1200 developers from all of the world to discuss topics related to software development utilizing Ruby and the web framework Rails, as well as related and surrounding technologies and practices.  The organizers had the event recorded by Confreaks and the presenters agreed to release the videos of the presentations under a Creative Commons license.  If you enjoy these videos be sure and let the presenters and the folks at Ruby Central know.\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 54\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"BcB-cNvjZ5vEfklx_xzYB77ULKY\",\n              \"id\": \"PL12686083008C28A5\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-04-18T07:49:42Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"GORUCO 2008\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/W7TGK7f_IDM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/W7TGK7f_IDM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/W7TGK7f_IDM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/W7TGK7f_IDM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"GORUCO 2008\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 7\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"qCQmwbv5y_fFCYS8LscrcdEFe3w\",\n              \"id\": \"PL5BDBA11D68D73050\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-03-14T15:29:05Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Los Angeles Ruby Conference 2012\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/tVmZHqf7yPE/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/tVmZHqf7yPE/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/tVmZHqf7yPE/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/tVmZHqf7yPE/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/tVmZHqf7yPE/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Los Angeles Ruby Conference 2012\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 12\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"bs2ef5kDI-YNB1Xyg6tPxPEFyL4\",\n              \"id\": \"PL805CD26C4836FCF7\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-03-14T15:28:50Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Madison Ruby Conference 2011\",\n                \"description\": \"\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/AoRkqMgX-4Q/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/AoRkqMgX-4Q/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/AoRkqMgX-4Q/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/AoRkqMgX-4Q/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/AoRkqMgX-4Q/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Madison Ruby Conference 2011\",\n                  \"description\": \"\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 3\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"1j5MsWmcYl_L-RrHVi6YDeq-JJ0\",\n              \"id\": \"PL9FC44445FC94749F\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-01-19T04:42:22Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Golden Gate Ruby Conference 2011\",\n                \"description\": \"Golden Gate Ruby Conference held in San Francisco, California\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/7rakLz2p50Q/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/7rakLz2p50Q/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/7rakLz2p50Q/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/7rakLz2p50Q/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/7rakLz2p50Q/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Golden Gate Ruby Conference 2011\",\n                  \"description\": \"Golden Gate Ruby Conference held in San Francisco, California\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 18\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"CMcgEYR2TfX1W0ycNBpwX-6nub0\",\n              \"id\": \"PL708EC50565A7C4DE\",\n              \"snippet\": {\n                \"publishedAt\": \"2012-01-18T22:50:19Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Midwest 2011\",\n                \"description\": \"Ruby Midwest - Regional Ruby Conference\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/XUOhTIkj6YA/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/XUOhTIkj6YA/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/XUOhTIkj6YA/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/XUOhTIkj6YA/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/XUOhTIkj6YA/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Midwest 2011\",\n                  \"description\": \"Ruby Midwest - Regional Ruby Conference\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 41\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"Im0jWcdifEoNhtrl04O4xBaQ9qg\",\n              \"id\": \"PL1BC12596233ACAFB\",\n              \"snippet\": {\n                \"publishedAt\": \"2011-12-12T19:35:41Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Lone Star Ruby Conference 2010\",\n                \"description\": \"Lone Star Ruby Conference is held annually in Austin, TX\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/NP9AIUT9nos/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/NP9AIUT9nos/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/NP9AIUT9nos/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/NP9AIUT9nos/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/NP9AIUT9nos/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Lone Star Ruby Conference 2010\",\n                  \"description\": \"Lone Star Ruby Conference is held annually in Austin, TX\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 29\n              }\n            },\n            {\n              \"kind\": \"youtube#playlist\",\n              \"etag\": \"xJOBqMUTSBg3Si3Nv0L-n7xE9Bc\",\n              \"id\": \"PL12D99636F40AE59B\",\n              \"snippet\": {\n                \"publishedAt\": \"2011-10-21T06:10:43Z\",\n                \"channelId\": \"UCWnPjmqvljcafA0z2U1fwKQ\",\n                \"title\": \"Ruby Conference 2011\",\n                \"description\": \"Videos from the International Ruby Conference held in:\\r\\n  2011 - New Orleans, LA\\r\\n  2010 - New Orleans, LA\\r\\n  2009 - San Francisco, CA\\r\\n  2008 - Orlando, FL\\r\\n  2007 - Charlotte, NC\\r\\n  2006 - Denver, CO\\r\\n  2005 - San Diego, CA\\r\\n  2004 - Chantilly, VA\\r\\n  2003 - Austin, TX\\r\\n  2002 - Seattle, WA\\r\\n  2001 - Tampa, FL\",\n                \"thumbnails\": {\n                  \"default\": {\n                    \"url\": \"https://i.ytimg.com/vi/roZkVMcUHVM/default.jpg\",\n                    \"width\": 120,\n                    \"height\": 90\n                  },\n                  \"medium\": {\n                    \"url\": \"https://i.ytimg.com/vi/roZkVMcUHVM/mqdefault.jpg\",\n                    \"width\": 320,\n                    \"height\": 180\n                  },\n                  \"high\": {\n                    \"url\": \"https://i.ytimg.com/vi/roZkVMcUHVM/hqdefault.jpg\",\n                    \"width\": 480,\n                    \"height\": 360\n                  },\n                  \"standard\": {\n                    \"url\": \"https://i.ytimg.com/vi/roZkVMcUHVM/sddefault.jpg\",\n                    \"width\": 640,\n                    \"height\": 480\n                  },\n                  \"maxres\": {\n                    \"url\": \"https://i.ytimg.com/vi/roZkVMcUHVM/maxresdefault.jpg\",\n                    \"width\": 1280,\n                    \"height\": 720\n                  }\n                },\n                \"channelTitle\": \"Confreaks\",\n                \"localized\": {\n                  \"title\": \"Ruby Conference 2011\",\n                  \"description\": \"Videos from the International Ruby Conference held in:\\r\\n  2011 - New Orleans, LA\\r\\n  2010 - New Orleans, LA\\r\\n  2009 - San Francisco, CA\\r\\n  2008 - Orlando, FL\\r\\n  2007 - Charlotte, NC\\r\\n  2006 - Denver, CO\\r\\n  2005 - San Diego, CA\\r\\n  2004 - Chantilly, VA\\r\\n  2003 - Austin, TX\\r\\n  2002 - Seattle, WA\\r\\n  2001 - Tampa, FL\"\n                }\n              },\n              \"contentDetails\": {\n                \"itemCount\": 59\n              }\n            }\n          ]\n        }\n  recorded_at: Thu, 08 Jun 2023 18:32:27 GMT\nrecorded_with: VCR 6.1.0\n"
  },
  {
    "path": "test/vcr_cassettes/youtube/transcript.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: post\n    uri: https://www.youtube.com/youtubei/v1/get_transcript\n    body:\n      encoding: UTF-8\n      string: '{\"context\":{\"client\":{\"clientName\":\"WEB\",\"clientVersion\":\"2.20240313\"}},\"params\":\"CgtGNzVrNE9jNmc5URIMQ2dOaGMzSVNBbVZ1\"}'\n    headers:\n      Content-Type:\n      - application/json\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Sun, 19 Jan 2025 19:47:07 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: |\n        {\n          \"responseContext\": {\n            \"visitorData\": \"CgtEZHUyelR4NEVUayi7rbW8BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgHA%3D%3D\",\n            \"serviceTrackingParams\": [\n              {\n                \"service\": \"CSI\",\n                \"params\": [\n                  {\n                    \"key\": \"c\",\n                    \"value\": \"WEB\"\n                  },\n                  {\n                    \"key\": \"cver\",\n                    \"value\": \"2.20240313\"\n                  },\n                  {\n                    \"key\": \"yt_li\",\n                    \"value\": \"0\"\n                  },\n                  {\n                    \"key\": \"GetVideoTranscript_rid\",\n                    \"value\": \"0x4a179f43b737be61\"\n                  }\n                ]\n              },\n              {\n                \"service\": \"GFEEDBACK\",\n                \"params\": [\n                  {\n                    \"key\": \"logged_in\",\n                    \"value\": \"0\"\n                  },\n                  {\n                    \"key\": \"e\",\n                    \"value\": \"23804281,23974157,23986027,24004644,24077241,24108448,24166867,24181174,24241378,24290153,24425063,24439361,24453989,24499532,24548629,24566687,24699899,39325854,39326986,39328397,51010235,51017346,51020570,51025415,51037344,51037349,51050361,51053689,51063643,51072748,51091058,51095478,51098299,51105630,51111738,51115184,51124104,51141472,51151423,51152050,51157411,51176511,51178320,51178333,51178355,51183909,51184990,51194137,51204329,51213888,51217504,51222382,51222973,51227037,51227776,51228850,51230478,51237842,51239093,51241028,51242448,51248734,51255676,51256074,51256084,51263449,51272458,51274583,51276557,51276565,51281227,51285052,51285717,51287196,51292055,51294322,51296439,51298020,51299237,51299710,51299724,51300176,51300241,51303432,51303667,51303669,51303789,51304155,51305839,51306256,51310742,51311025,51311038,51313109,51313767,51313802,51314158,51316749,51318845,51322669,51326932,51327140,51327161,51327184,51327613,51327636,51330194,51331481,51331500,51331516,51331535,51331538,51331545,51331552,51331563,51332801,51332896,51333879,51334604,51335366,51335392,51335594,51335644,51335928,51337186,51338524,51339193,51340613,51340662,51341214,51341228,51341975,51342857,51343368,51344342,51345230,51345629,51346046,51346793,51346808,51346831,51346844,51346857,51346870,51346881,51346902,51347325,51347584,51349880,51349913,51350812,51351446,51353231,51353393,51353453,51353498,51354114,51354569,51355199,51355262,51355275,51355291,51355305,51355318,51355339,51355344,51355417,51355679,51355802,51355912,51357204,51357477,51359169,51360104,51360115,51360140,51360212,51360215,51361727,51361830,51362040,51362455,51362643,51362674,51362857,51363729,51363732,51363745,51363752,51363763,51363772,51365459,51365462,51365987,51366423,51366620,51366864,51367489,51367993,51369589,51369905,51370274,51370738,51371001,51371010,51371043,51371294,51371521,51374438,51374491,51375168,51375719,51376330,51376516,51379274,51380152,51380374,51380385,51380392,51380763,51380766,51380783,51380790,51380805,51380818,51380825,51380894,51381275,51381795,51381817,51381857,51381972,51381974,51382899,51383428,51384306,51384347,51384461,51384839,51384887,51385023,51385277,51385539,51386143,51386158\"\n                  },\n                  {\n                    \"key\": \"visitor_data\",\n                    \"value\": \"CgtEZHUyelR4NEVUayi7rbW8BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgHA%3D%3D\"\n                  }\n                ]\n              },\n              {\n                \"service\": \"GUIDED_HELP\",\n                \"params\": [\n                  {\n                    \"key\": \"logged_in\",\n                    \"value\": \"0\"\n                  }\n                ]\n              },\n              {\n                \"service\": \"ECATCHER\",\n                \"params\": [\n                  {\n                    \"key\": \"client.version\",\n                    \"value\": \"2.20240530\"\n                  },\n                  {\n                    \"key\": \"client.name\",\n                    \"value\": \"WEB\"\n                  }\n                ]\n              }\n            ],\n            \"mainAppWebResponseContext\": {\n              \"loggedOut\": true,\n              \"trackingParam\": \"kx_fmPxhoPZRarS5wjEqzLGjc4Bj4n40gh3t4G9ZkFQq45Eass0cwhLBwOcCE59TDtslLKPQ-SS\"\n            },\n            \"webResponseContextExtensionData\": {\n              \"hasDecorated\": true\n            }\n          },\n          \"actions\": [\n            {\n              \"clickTrackingParams\": \"CAAQw7wCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n              \"updateEngagementPanelAction\": {\n                \"targetId\": \"engagement-panel-searchable-transcript\",\n                \"content\": {\n                  \"transcriptRenderer\": {\n                    \"trackingParams\": \"CAEQ8bsCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                    \"content\": {\n                      \"transcriptSearchPanelRenderer\": {\n                        \"header\": {\n                          \"transcriptSearchBoxRenderer\": {\n                            \"formattedPlaceholder\": {\n                              \"runs\": [\n                                {\n                                  \"text\": \"Search in video\"\n                                }\n                              ]\n                            },\n                            \"accessibility\": {\n                              \"accessibilityData\": {\n                                \"label\": \"Search in video\"\n                              }\n                            },\n                            \"clearButton\": {\n                              \"buttonRenderer\": {\n                                \"icon\": {\n                                  \"iconType\": \"CLOSE\"\n                                },\n                                \"trackingParams\": \"CKkCEMngByITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                \"accessibilityData\": {\n                                  \"accessibilityData\": {\n                                    \"label\": \"Clear search query\"\n                                  }\n                                }\n                              }\n                            },\n                            \"onTextChangeCommand\": {\n                              \"clickTrackingParams\": \"CKcCEKvaByITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                              \"commandMetadata\": {\n                                \"webCommandMetadata\": {\n                                  \"sendPost\": true,\n                                  \"apiUrl\": \"/youtubei/v1/get_transcript\"\n                                }\n                              },\n                              \"getTranscriptEndpoint\": {\n                                \"params\": \"CgtGNzVrNE9jNmc5URIMQ2dOaGMzSVNBbVZ1GAEqM2VuZ2FnZW1lbnQtcGFuZWwtc2VhcmNoYWJsZS10cmFuc2NyaXB0LXNlYXJjaC1wYW5lbDAAOABAAA%3D%3D\"\n                              }\n                            },\n                            \"trackingParams\": \"CKcCEKvaByITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                            \"searchButton\": {\n                              \"buttonRenderer\": {\n                                \"trackingParams\": \"CKgCEIKDCCITCLKDqMXGgosDFbDxTwgdTCQGWQ==\"\n                              }\n                            }\n                          }\n                        },\n                        \"body\": {\n                          \"transcriptSegmentListRenderer\": {\n                            \"initialSegments\": [\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"4330\",\n                                  \"endMs\": \"14480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"[Music]\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:04\"\n                                  },\n                                  \"trackingParams\": \"CKYCENP2BxgAIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 seconds [Music]\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.4330.14480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"15280\",\n                                  \"endMs\": \"21320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so nice to be here with you thank you all for coming so uh my name is uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:15\"\n                                  },\n                                  \"trackingParams\": \"CKUCENP2BxgBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 seconds so nice to be here with you thank you all for coming so uh my name is uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.15280.21320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"21320\",\n                                  \"endMs\": \"27800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yaroslav I'm from Ukraine you might know me from my blog or from my super Al\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:21\"\n                                  },\n                                  \"trackingParams\": \"CKQCENP2BxgCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 seconds yaroslav I'm from Ukraine you might know me from my blog or from my super Al\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.21320.27800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"27800\",\n                                  \"endMs\": \"34399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"YouTube channel where I post a lot of stuff about trby and especially about hot fire so I originate from Ukraine\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:27\"\n                                  },\n                                  \"trackingParams\": \"CKMCENP2BxgDIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 seconds YouTube channel where I post a lot of stuff about trby and especially about hot fire so I originate from Ukraine\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.27800.34399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"34399\",\n                                  \"endMs\": \"40239\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"from the north of Ukraine so right now it is liberated so that is Kev Chernobyl\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:34\"\n                                  },\n                                  \"trackingParams\": \"CKICENP2BxgEIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 seconds from the north of Ukraine so right now it is liberated so that is Kev Chernobyl\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.34399.40239\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"40239\",\n                                  \"endMs\": \"45920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and chern so I used to live 80 kmers away from Chernobyl great\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:40\"\n                                  },\n                                  \"trackingParams\": \"CKECENP2BxgFIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 seconds and chern so I used to live 80 kmers away from Chernobyl great\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.40239.45920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"45920\",\n                                  \"endMs\": \"52680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"place yeah and uh that is my family's home so it got boned in one of the first\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:45\"\n                                  },\n                                  \"trackingParams\": \"CKACENP2BxgGIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 seconds place yeah and uh that is my family's home so it got boned in one of the first\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.45920.52680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"52680\",\n                                  \"endMs\": \"60000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"days of war that is my godfather he went to defend Ukraine and uh I mean we are\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:52\"\n                                  },\n                                  \"trackingParams\": \"CJ8CENP2BxgHIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 seconds days of war that is my godfather he went to defend Ukraine and uh I mean we are\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.52680.60000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"60000\",\n                                  \"endMs\": \"65799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"he has such a beautiful venue but there is the war going on and like just today\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00\"\n                                  },\n                                  \"trackingParams\": \"CJ4CENP2BxgIIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute he has such a beautiful venue but there is the war going on and like just today\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.60000.65799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"65799\",\n                                  \"endMs\": \"73159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the city of har was randomly boned by the Russians and there are many Ruby\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:05\"\n                                  },\n                                  \"trackingParams\": \"CJ0CENP2BxgJIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 5 seconds the city of har was randomly boned by the Russians and there are many Ruby\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.65799.73159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"73159\",\n                                  \"endMs\": \"79520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"rails people from Ukraine some of them are actually fighting this is verok he contributed to Ruby and he is actually\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:13\"\n                                  },\n                                  \"trackingParams\": \"CJwCENP2BxgKIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 13 seconds rails people from Ukraine some of them are actually fighting this is verok he contributed to Ruby and he is actually\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.73159.79520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"79520\",\n                                  \"endMs\": \"86439\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"defending Ukraine right now but on a positive note I just recently became a father\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:19\"\n                                  },\n                                  \"trackingParams\": \"CJsCENP2BxgLIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 19 seconds defending Ukraine right now but on a positive note I just recently became a father\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.79520.86439\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"87960\",\n                                  \"endMs\": \"95000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so yeah um it is uh just 2 and a half months ago in uh France and uh today we\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:27\"\n                                  },\n                                  \"trackingParams\": \"CJoCENP2BxgMIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 27 seconds so yeah um it is uh just 2 and a half months ago in uh France and uh today we\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.87960.95000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"95000\",\n                                  \"endMs\": \"100520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"are going to talk about hot fire so uh we already had a nice talk by Jorge\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:35\"\n                                  },\n                                  \"trackingParams\": \"CJkCENP2BxgNIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 35 seconds are going to talk about hot fire so uh we already had a nice talk by Jorge\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.95000.100520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"100520\",\n                                  \"endMs\": \"108520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"about turbo 8 so he was talking about the future we had Marco who was talking about these uh so many Tools in their\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:40\"\n                                  },\n                                  \"trackingParams\": \"CJgCENP2BxgOIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 40 seconds about turbo 8 so he was talking about the future we had Marco who was talking about these uh so many Tools in their\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.100520.108520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"108520\",\n                                  \"endMs\": \"115600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"hot wire ecosystem and I really imagine Marco as uh like yeah he's kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:48\"\n                                  },\n                                  \"trackingParams\": \"CJcCENP2BxgPIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 48 seconds hot wire ecosystem and I really imagine Marco as uh like yeah he's kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.108520.115600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"115600\",\n                                  \"endMs\": \"123640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"bringing all the stuff to the table and uh I'm doing the cooking so yeah therefore the hot wire cookbook\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:55\"\n                                  },\n                                  \"trackingParams\": \"CJYCENP2BxgQIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 55 seconds bringing all the stuff to the table and uh I'm doing the cooking so yeah therefore the hot wire cookbook\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.115600.123640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"123640\",\n                                  \"endMs\": \"130959\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I've actually got a cookbook um yeah last week I was in Romania and I was given this beautiful cookbook and I Was\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:03\"\n                                  },\n                                  \"trackingParams\": \"CJUCENP2BxgRIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 3 seconds I've actually got a cookbook um yeah last week I was in Romania and I was given this beautiful cookbook and I Was\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.123640.130959\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"130959\",\n                                  \"endMs\": \"137440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"preparing the hot cookbook presentation mostly while being in Romania so yeah a Hotwire\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:10\"\n                                  },\n                                  \"trackingParams\": \"CJQCENP2BxgSIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 10 seconds preparing the hot cookbook presentation mostly while being in Romania so yeah a Hotwire\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.130959.137440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"137440\",\n                                  \"endMs\": \"142519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"cookbook yeah and uh I've done a lot of videos about different parts of Hotwire\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:17\"\n                                  },\n                                  \"trackingParams\": \"CJMCENP2BxgTIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 17 seconds cookbook yeah and uh I've done a lot of videos about different parts of Hotwire\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.137440.142519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"142519\",\n                                  \"endMs\": \"149480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"stimulus uh uh to frames to streams feel free to check them out on the YouTube channel there is the just enough hot W\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:22\"\n                                  },\n                                  \"trackingParams\": \"CJICENP2BxgUIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 22 seconds stimulus uh uh to frames to streams feel free to check them out on the YouTube channel there is the just enough hot W\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.142519.149480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"149480\",\n                                  \"endMs\": \"155040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"rails developers uh series actually just enough of something for developers seems\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:29\"\n                                  },\n                                  \"trackingParams\": \"CJECENP2BxgVIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 29 seconds rails developers uh series actually just enough of something for developers seems\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.149480.155040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"155040\",\n                                  \"endMs\": \"160120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"to be a buzz word these days I think Jo MTI also has like just enough turbo\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:35\"\n                                  },\n                                  \"trackingParams\": \"CJACENP2BxgWIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 35 seconds to be a buzz word these days I think Jo MTI also has like just enough turbo\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.155040.160120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"160120\",\n                                  \"endMs\": \"166400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"native and so it goes so yeah the hot fire cookbook I'm going to teach you or\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:40\"\n                                  },\n                                  \"trackingParams\": \"CI8CENP2BxgXIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 40 seconds native and so it goes so yeah the hot fire cookbook I'm going to teach you or\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.160120.166400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"166400\",\n                                  \"endMs\": \"172959\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like show you a few common recipes the most simple things you can build with different parts of hot fire so we're\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:46\"\n                                  },\n                                  \"trackingParams\": \"CI4CENP2BxgYIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 46 seconds like show you a few common recipes the most simple things you can build with different parts of hot fire so we're\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.166400.172959\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"172959\",\n                                  \"endMs\": \"181159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"going to talk about too drive too frames too streams and uh stimulus now uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:52\"\n                                  },\n                                  \"trackingParams\": \"CI0CENP2BxgZIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 52 seconds going to talk about too drive too frames too streams and uh stimulus now uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.172959.181159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"181159\",\n                                  \"endMs\": \"188280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"while talking to many people in the lobby a few people well many people were saying oh I identify as a backend\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:01\"\n                                  },\n                                  \"trackingParams\": \"CIwCENP2BxgaIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 1 second while talking to many people in the lobby a few people well many people were saying oh I identify as a backend\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.181159.188280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"188280\",\n                                  \"endMs\": \"196200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"developer like I'm a rails backend developer and uh many people seem to have heard about hotfire and uh some\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:08\"\n                                  },\n                                  \"trackingParams\": \"CIsCENP2BxgbIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 8 seconds developer like I'm a rails backend developer and uh many people seem to have heard about hotfire and uh some\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.188280.196200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"196200\",\n                                  \"endMs\": \"201480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"have tried it so can you please see the hands of those who have not tried hot\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:16\"\n                                  },\n                                  \"trackingParams\": \"CIoCENP2BxgcIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 16 seconds have tried it so can you please see the hands of those who have not tried hot\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.196200.201480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"201480\",\n                                  \"endMs\": \"207440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"fire yet okay so I think I will be primarily\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:21\"\n                                  },\n                                  \"trackingParams\": \"CIkCENP2BxgdIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 21 seconds fire yet okay so I think I will be primarily\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.201480.207440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"207440\",\n                                  \"endMs\": \"212799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"targeting you with these very simple recipes and uh I'll try to make it quite\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:27\"\n                                  },\n                                  \"trackingParams\": \"CIgCENP2BxgeIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 27 seconds targeting you with these very simple recipes and uh I'll try to make it quite\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.207440.212799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"212799\",\n                                  \"endMs\": \"218080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"smooth and uh help you understand how to do basic things with hot fire so we're\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:32\"\n                                  },\n                                  \"trackingParams\": \"CIcCENP2BxgfIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 32 seconds smooth and uh help you understand how to do basic things with hot fire so we're\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.212799.218080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"218080\",\n                                  \"endMs\": \"224159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"going to start with turbo drive now uh they said that turbo links is dead but\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:38\"\n                                  },\n                                  \"trackingParams\": \"CIYCENP2BxggIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 38 seconds going to start with turbo drive now uh they said that turbo links is dead but\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.218080.224159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"224159\",\n                                  \"endMs\": \"233079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"really for me I imagine turbo drive as the combination of Turbo links and rails ugs so uh for many years I just had the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:44\"\n                                  },\n                                  \"trackingParams\": \"CIUCENP2BxghIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 44 seconds really for me I imagine turbo drive as the combination of Turbo links and rails ugs so uh for many years I just had the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.224159.233079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"233079\",\n                                  \"endMs\": \"239360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"gem turbo links uh in my gem file often I would disable it uh I had rail zgs I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:53\"\n                                  },\n                                  \"trackingParams\": \"CIQCENP2BxgiIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 53 seconds gem turbo links uh in my gem file often I would disable it uh I had rail zgs I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.233079.239360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"239360\",\n                                  \"endMs\": \"244519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"never thought of why do I have it in the gem file but I kept it there and now we\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:59\"\n                                  },\n                                  \"trackingParams\": \"CIMCENP2BxgjIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 59 seconds never thought of why do I have it in the gem file but I kept it there and now we\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.239360.244519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"244519\",\n                                  \"endMs\": \"249599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"don't need those two gems we have just gem turbo rails that does a lot of different stuff so uh what does turbo\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:04\"\n                                  },\n                                  \"trackingParams\": \"CIICENP2BxgkIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 4 seconds don't need those two gems we have just gem turbo rails that does a lot of different stuff so uh what does turbo\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.244519.249599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"249599\",\n                                  \"endMs\": \"255439\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"drive do and what uh features can you explicitly use with turbo drive so um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:09\"\n                                  },\n                                  \"trackingParams\": \"CIECENP2BxglIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 9 seconds drive do and what uh features can you explicitly use with turbo drive so um\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.249599.255439\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"255439\",\n                                  \"endMs\": \"260600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"previously on rail 6 and previous versions you could make link two with a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:15\"\n                                  },\n                                  \"trackingParams\": \"CIACENP2BxgmIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 15 seconds previously on rail 6 and previous versions you could make link two with a\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.255439.260600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"260600\",\n                                  \"endMs\": \"266960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"non get request uh then uh Ra zjs was uh depreciated so it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:20\"\n                                  },\n                                  \"trackingParams\": \"CP8BENP2BxgnIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 20 seconds non get request uh then uh Ra zjs was uh depreciated so it\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.260600.266960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"266960\",\n                                  \"endMs\": \"274120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"isn't like anymore in the default stack you couldn't do it but uh now you can use Link to with data tubo method delete\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:26\"\n                                  },\n                                  \"trackingParams\": \"CP4BENP2BxgoIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 26 seconds isn't like anymore in the default stack you couldn't do it but uh now you can use Link to with data tubo method delete\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.266960.274120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"274120\",\n                                  \"endMs\": \"281479\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so turbo does it and you can uh still use Link to but get slightly different method to make non-g get requests and uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:34\"\n                                  },\n                                  \"trackingParams\": \"CP0BENP2BxgpIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 34 seconds so turbo does it and you can uh still use Link to but get slightly different method to make non-g get requests and uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.274120.281479\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"281479\",\n                                  \"endMs\": \"288840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"again always I would suggest using a button to if it's not a get request uh then there is toook confirm\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:41\"\n                                  },\n                                  \"trackingParams\": \"CPwBENP2BxgqIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 41 seconds again always I would suggest using a button to if it's not a get request uh then there is toook confirm\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.281479.288840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"288840\",\n                                  \"endMs\": \"295960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so uh previously in the versions uh that use ra GS you could do this like are you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:48\"\n                                  },\n                                  \"trackingParams\": \"CPsBENP2BxgrIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 48 seconds so uh previously in the versions uh that use ra GS you could do this like are you\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.288840.295960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"295960\",\n                                  \"endMs\": \"301039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"sure or another browser message then you click some button so previously you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:55\"\n                                  },\n                                  \"trackingParams\": \"CPoBENP2BxgsIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 55 seconds sure or another browser message then you click some button so previously you\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.295960.301039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"301039\",\n                                  \"endMs\": \"306759\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"would do it with data confirm now you would do it with data tuo confirm so it is an easy migration from previous\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:01\"\n                                  },\n                                  \"trackingParams\": \"CPkBENP2BxgtIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 1 second would do it with data confirm now you would do it with data tuo confirm so it is an easy migration from previous\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.301039.306759\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"306759\",\n                                  \"endMs\": \"312800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"versions of rub on Rails if you want to move to rail 7 from previous versions um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:06\"\n                                  },\n                                  \"trackingParams\": \"CPgBENP2BxguIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 6 seconds versions of rub on Rails if you want to move to rail 7 from previous versions um\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.306759.312800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"312800\",\n                                  \"endMs\": \"319400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"also you had this uh thing that disable on submit so you see I clicked submit and I not cannot click it again here is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:12\"\n                                  },\n                                  \"trackingParams\": \"CPcBENP2BxgvIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 12 seconds also you had this uh thing that disable on submit so you see I clicked submit and I not cannot click it again here is\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.312800.319400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"319400\",\n                                  \"endMs\": \"326319\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a bigger version so that you can see it and previously you would do it with disable with now you do it with turbo\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:19\"\n                                  },\n                                  \"trackingParams\": \"CPYBENP2BxgwIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 19 seconds a bigger version so that you can see it and previously you would do it with disable with now you do it with turbo\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.319400.326319\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"326319\",\n                                  \"endMs\": \"332720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"submits with and another one of my favorite features of turbo drive is sticker El\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:26\"\n                                  },\n                                  \"trackingParams\": \"CPUBENP2BxgxIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 26 seconds submits with and another one of my favorite features of turbo drive is sticker El\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.326319.332720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"332720\",\n                                  \"endMs\": \"338240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"elements cross pages so here in this demo\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:32\"\n                                  },\n                                  \"trackingParams\": \"CPQBENP2BxgyIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 32 seconds elements cross pages so here in this demo\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.332720.338240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"338240\",\n                                  \"endMs\": \"345120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um in this demo I click a video I click an audio I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:38\"\n                                  },\n                                  \"trackingParams\": \"CPMBENP2BxgzIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 38 seconds um in this demo I click a video I click an audio I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.338240.345120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"345120\",\n                                  \"endMs\": \"351319\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"go from one page to another and these elements are persisted across the pages so it is done with just a tiny bit of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:45\"\n                                  },\n                                  \"trackingParams\": \"CPIBENP2Bxg0IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 45 seconds go from one page to another and these elements are persisted across the pages so it is done with just a tiny bit of\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.345120.351319\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"351319\",\n                                  \"endMs\": \"358000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"code each uh element that should be permanent should have a unique ID and you should add data to be permanent true\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:51\"\n                                  },\n                                  \"trackingParams\": \"CPEBENP2Bxg1IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 51 seconds code each uh element that should be permanent should have a unique ID and you should add data to be permanent true\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.351319.358000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"358000\",\n                                  \"endMs\": \"366120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and it works like magic uh if you go to different podcasts or if you go to uh different like Spotify like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:58\"\n                                  },\n                                  \"trackingParams\": \"CPABENP2Bxg2IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 58 seconds and it works like magic uh if you go to different podcasts or if you go to uh different like Spotify like\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.358000.366120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"366120\",\n                                  \"endMs\": \"372759\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"apps you will see similar behaviors so here for example on the 37 signals podcast I click play I navigate\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:06\"\n                                  },\n                                  \"trackingParams\": \"CO8BENP2Bxg3IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 6 seconds apps you will see similar behaviors so here for example on the 37 signals podcast I click play I navigate\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.366120.372759\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"372759\",\n                                  \"endMs\": \"379160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"different pages and you see that the player keeps playing and they are also using data Tu permanent under the hood\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:12\"\n                                  },\n                                  \"trackingParams\": \"CO4BENP2Bxg4IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 12 seconds different pages and you see that the player keeps playing and they are also using data Tu permanent under the hood\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.372759.379160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"379160\",\n                                  \"endMs\": \"385160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so you can just go to the uh uh inspector and see how it works uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:19\"\n                                  },\n                                  \"trackingParams\": \"CO0BENP2Bxg5IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 19 seconds so you can just go to the uh uh inspector and see how it works uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.379160.385160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"385160\",\n                                  \"endMs\": \"391919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"another example of using data Tu permanent would be on my Super's website where I have search so I've got a model\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:25\"\n                                  },\n                                  \"trackingParams\": \"COwBENP2Bxg6IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 25 seconds another example of using data Tu permanent would be on my Super's website where I have search so I've got a model\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.385160.391919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"391919\",\n                                  \"endMs\": \"398199\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I search for something I go to a next page and if you open the model again the previous results will saved they're not\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:31\"\n                                  },\n                                  \"trackingParams\": \"COsBENP2Bxg7IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 31 seconds I search for something I go to a next page and if you open the model again the previous results will saved they're not\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.391919.398199\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"398199\",\n                                  \"endMs\": \"403440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"saved anywhere except the HTML so sometimes HTML is all you need to save\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:38\"\n                                  },\n                                  \"trackingParams\": \"COoBENP2Bxg8IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 38 seconds saved anywhere except the HTML so sometimes HTML is all you need to save\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.398199.403440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"403440\",\n                                  \"endMs\": \"413199\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"some results um sometimes you still would need to disable U turbo\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:43\"\n                                  },\n                                  \"trackingParams\": \"COkBENP2Bxg9IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 43 seconds some results um sometimes you still would need to disable U turbo\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.403440.413199\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"413199\",\n                                  \"endMs\": \"419199\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh so previously when the device was not yet compatible with the uh turbo you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:53\"\n                                  },\n                                  \"trackingParams\": \"COgBENP2Bxg-IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 53 seconds uh so previously when the device was not yet compatible with the uh turbo you\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.413199.419199\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"419199\",\n                                  \"endMs\": \"424800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"would add the like data turbo FS to device in some cases when you make a a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:59\"\n                                  },\n                                  \"trackingParams\": \"COcBENP2Bxg_IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 59 seconds would add the like data turbo FS to device in some cases when you make a a\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.419199.424800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"424800\",\n                                  \"endMs\": \"430039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"post request and afterwards from the controller you would be redirecting or on a sign out link you would also\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:04\"\n                                  },\n                                  \"trackingParams\": \"COYBENP2BxhAIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 4 seconds post request and afterwards from the controller you would be redirecting or on a sign out link you would also\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.424800.430039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"430039\",\n                                  \"endMs\": \"437280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"sometimes need to use turbo F so don't think that it is hacky in some particular cases it is what you need\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:10\"\n                                  },\n                                  \"trackingParams\": \"COUBENP2BxhBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 10 seconds sometimes need to use turbo F so don't think that it is hacky in some particular cases it is what you need\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.430039.437280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"437280\",\n                                  \"endMs\": \"442360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"next we're going to talk about turbo frames so uh for me turbo frames have\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:17\"\n                                  },\n                                  \"trackingParams\": \"COQBENP2BxhCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 17 seconds next we're going to talk about turbo frames so uh for me turbo frames have\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.437280.442360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"442360\",\n                                  \"endMs\": \"448680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"two main features first of all L loading and selfcontained the page elements we're going to talk about each of them\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:22\"\n                                  },\n                                  \"trackingParams\": \"COMBENP2BxhDIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 22 seconds two main features first of all L loading and selfcontained the page elements we're going to talk about each of them\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.442360.448680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"448680\",\n                                  \"endMs\": \"453800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so uh laser loading here I have a collection of employee records so I just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:28\"\n                                  },\n                                  \"trackingParams\": \"COIBENP2BxhEIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 28 seconds so uh laser loading here I have a collection of employee records so I just\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.448680.453800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"453800\",\n                                  \"endMs\": \"459160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"open the employee page and the records keep loading and as I scroll lower new\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:33\"\n                                  },\n                                  \"trackingParams\": \"COEBENP2BxhFIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 33 seconds open the employee page and the records keep loading and as I scroll lower new\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.453800.459160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"459160\",\n                                  \"endMs\": \"464199\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"records keep getting loaded so this can uh really increase the speed of your\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:39\"\n                                  },\n                                  \"trackingParams\": \"COABENP2BxhGIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 39 seconds records keep getting loaded so this can uh really increase the speed of your\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.459160.464199\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"464199\",\n                                  \"endMs\": \"470919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"initial page load and under the hood it works like this so it is a default scaffold and I have a tu frame tag\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:44\"\n                                  },\n                                  \"trackingParams\": \"CN8BENP2BxhHIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 44 seconds initial page load and under the hood it works like this so it is a default scaffold and I have a tu frame tag\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.464199.470919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"470919\",\n                                  \"endMs\": \"478080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"around each record I add loading lazy and if you add loading lazy an element will be loaded only when it becomes\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:50\"\n                                  },\n                                  \"trackingParams\": \"CN4BENP2BxhIIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 50 seconds around each record I add loading lazy and if you add loading lazy an element will be loaded only when it becomes\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.470919.478080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"478080\",\n                                  \"endMs\": \"483360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"visible on the page and it makes a request to the show page and in the show\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:58\"\n                                  },\n                                  \"trackingParams\": \"CN0BENP2BxhJIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 58 seconds visible on the page and it makes a request to the show page and in the show\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.478080.483360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"483360\",\n                                  \"endMs\": \"489479\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"page I have a tubo frame with the same ID as this so it loads that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:03\"\n                                  },\n                                  \"trackingParams\": \"CNwBENP2BxhKIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 3 seconds page I have a tubo frame with the same ID as this so it loads that\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.483360.489479\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"489479\",\n                                  \"endMs\": \"496039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"element uh another example of Lady Lady load lazy loading would be for example\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:09\"\n                                  },\n                                  \"trackingParams\": \"CNsBENP2BxhLIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 9 seconds element uh another example of Lady Lady load lazy loading would be for example\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.489479.496039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"496039\",\n                                  \"endMs\": \"501840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"on Base Cam website so I click on my avatar and you see it actually makes a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:16\"\n                                  },\n                                  \"trackingParams\": \"CNoBENP2BxhMIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 16 seconds on Base Cam website so I click on my avatar and you see it actually makes a\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.496039.501840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"501840\",\n                                  \"endMs\": \"507479\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"request and here it is so it wasn't uh initially loaded it loads only when I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:21\"\n                                  },\n                                  \"trackingParams\": \"CNkBENP2BxhNIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 21 seconds request and here it is so it wasn't uh initially loaded it loads only when I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.501840.507479\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"507479\",\n                                  \"endMs\": \"512800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"need to load it so I would say it is like load on click so an element becomes\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:27\"\n                                  },\n                                  \"trackingParams\": \"CNgBENP2BxhOIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 27 seconds need to load it so I would say it is like load on click so an element becomes\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.507479.512800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"512800\",\n                                  \"endMs\": \"520000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"visible and then you load it uh here is a simplified example I have a list of employee names and I would like to load\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:32\"\n                                  },\n                                  \"trackingParams\": \"CNcBENP2BxhPIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 32 seconds visible and then you load it uh here is a simplified example I have a list of employee names and I would like to load\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.512800.520000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"520000\",\n                                  \"endMs\": \"525519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"details of each of the employees when I click on the name so if it work like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:40\"\n                                  },\n                                  \"trackingParams\": \"CNYBENP2BxhQIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 40 seconds details of each of the employees when I click on the name so if it work like\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.520000.525519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"525519\",\n                                  \"endMs\": \"532080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this I click on the employee you see I make requests and uh these records get\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:45\"\n                                  },\n                                  \"trackingParams\": \"CNUBENP2BxhRIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 45 seconds this I click on the employee you see I make requests and uh these records get\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.525519.532080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"532080\",\n                                  \"endMs\": \"539240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"loaded so if you have a lot of uh data on the page you might want to use this kind of laser loading it works uh in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:52\"\n                                  },\n                                  \"trackingParams\": \"CNQBENP2BxhSIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 52 seconds loaded so if you have a lot of uh data on the page you might want to use this kind of laser loading it works uh in\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.532080.539240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"539240\",\n                                  \"endMs\": \"544720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"very similar uh manner as the previous example but here I have the HTML details\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:59\"\n                                  },\n                                  \"trackingParams\": \"CNMBENP2BxhTIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 59 seconds very similar uh manner as the previous example but here I have the HTML details\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.539240.544720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"544720\",\n                                  \"endMs\": \"550079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"tag so when uh I unhide the element the loading lazy occurs and I make the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:04\"\n                                  },\n                                  \"trackingParams\": \"CNIBENP2BxhUIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 4 seconds tag so when uh I unhide the element the loading lazy occurs and I make the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.544720.550079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"550079\",\n                                  \"endMs\": \"555920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"request to the show action and render the page uh another example is hover\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:10\"\n                                  },\n                                  \"trackingParams\": \"CNEBENP2BxhVIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 10 seconds request to the show action and render the page uh another example is hover\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.550079.555920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"555920\",\n                                  \"endMs\": \"562040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"card so on Twitter for example I hover on a profile and I can see the profile details and you don't want to load all\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:15\"\n                                  },\n                                  \"trackingParams\": \"CNABENP2BxhWIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 15 seconds card so on Twitter for example I hover on a profile and I can see the profile details and you don't want to load all\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.555920.562040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"562040\",\n                                  \"endMs\": \"568079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the profiles because it could uh well consume some uh memory so another\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:22\"\n                                  },\n                                  \"trackingParams\": \"CM8BENP2BxhXIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 22 seconds the profiles because it could uh well consume some uh memory so another\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.562040.568079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"568079\",\n                                  \"endMs\": \"575000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"example would be on the GitHub uh again hover cards and here's an example on a new rails app so I would\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:28\"\n                                  },\n                                  \"trackingParams\": \"CM4BENP2BxhYIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 28 seconds example would be on the GitHub uh again hover cards and here's an example on a new rails app so I would\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.568079.575000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"575000\",\n                                  \"endMs\": \"583040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"just h on the details and you see it makes a request and loads the details for each record and the way to do it is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:35\"\n                                  },\n                                  \"trackingParams\": \"CM0BENP2BxhZIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 35 seconds just h on the details and you see it makes a request and loads the details for each record and the way to do it is\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.575000.583040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"583040\",\n                                  \"endMs\": \"590399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"very similar but here to unhide the elements I'm just using some uh CSS and you see in some cases you don't need the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:43\"\n                                  },\n                                  \"trackingParams\": \"CMwBENP2BxhaIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 43 seconds very similar but here to unhide the elements I'm just using some uh CSS and you see in some cases you don't need the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.583040.590399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"590399\",\n                                  \"endMs\": \"596240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh JavaScript you can just do a tiny bit of CSS to unhide an element on\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:50\"\n                                  },\n                                  \"trackingParams\": \"CMsBENP2BxhbIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 50 seconds uh JavaScript you can just do a tiny bit of CSS to unhide an element on\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.590399.596240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"596240\",\n                                  \"endMs\": \"601440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Hare uh another important feature of to frames is uh self-contained page\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:56\"\n                                  },\n                                  \"trackingParams\": \"CMoBENP2BxhcIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 56 seconds Hare uh another important feature of to frames is uh self-contained page\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.596240.601440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"601440\",\n                                  \"endMs\": \"608399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"elements so one of the best examples in my opinion is uh uh searching and filtering a table this is usually quite\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:01\"\n                                  },\n                                  \"trackingParams\": \"CMkBENP2BxhdIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 1 second elements so one of the best examples in my opinion is uh uh searching and filtering a table this is usually quite\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.601440.608399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"608399\",\n                                  \"endMs\": \"615200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a complex uh thing to do so here I have a search field I start typing and you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:08\"\n                                  },\n                                  \"trackingParams\": \"CMgBENP2BxheIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 8 seconds a complex uh thing to do so here I have a search field I start typing and you\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.608399.615200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"615200\",\n                                  \"endMs\": \"621279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"see with each uh thing I type I make a new request and I refresh the table that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:15\"\n                                  },\n                                  \"trackingParams\": \"CMcBENP2BxhfIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 15 seconds see with each uh thing I type I make a new request and I refresh the table that\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.615200.621279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"621279\",\n                                  \"endMs\": \"626480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"is visible and you see the URL also gets updated how does it work so uh I just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:21\"\n                                  },\n                                  \"trackingParams\": \"CMYBENP2BxhgIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 21 seconds is visible and you see the URL also gets updated how does it work so uh I just\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.621279.626480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"626480\",\n                                  \"endMs\": \"633640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"installed RC for the search and uh I did the regular search you would do uh without turbo so usually would have like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:26\"\n                                  },\n                                  \"trackingParams\": \"CMUBENP2BxhhIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 26 seconds installed RC for the search and uh I did the regular search you would do uh without turbo so usually would have like\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.626480.633640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"633640\",\n                                  \"endMs\": \"639120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a search field and a submit button uh but in my case I added a tu frame\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:33\"\n                                  },\n                                  \"trackingParams\": \"CMQBENP2BxhiIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 33 seconds a search field and a submit button uh but in my case I added a tu frame\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.633640.639120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"639120\",\n                                  \"endMs\": \"644399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"employees list to the search form and I wrapped the table into the tuba frame\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:39\"\n                                  },\n                                  \"trackingParams\": \"CMMBENP2BxhjIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 39 seconds employees list to the search form and I wrapped the table into the tuba frame\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.639120.644399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"644399\",\n                                  \"endMs\": \"651720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"tag so I'm making the request of the index action but the controller knows that it should update only uh this to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:44\"\n                                  },\n                                  \"trackingParams\": \"CMIBENP2BxhkIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 44 seconds tag so I'm making the request of the index action but the controller knows that it should update only uh this to\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.644399.651720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"651720\",\n                                  \"endMs\": \"658040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"frame tag if it finds it on the page and I'm also using tuo action advance to update the URL\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:51\"\n                                  },\n                                  \"trackingParams\": \"CMEBENP2BxhlIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 51 seconds frame tag if it finds it on the page and I'm also using tuo action advance to update the URL\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.651720.658040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"658040\",\n                                  \"endMs\": \"664560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"automatically um also you might have noticed that uh I have syntax highlighting of the results and it is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:58\"\n                                  },\n                                  \"trackingParams\": \"CMABENP2BxhmIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 58 seconds automatically um also you might have noticed that uh I have syntax highlighting of the results and it is\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.658040.664560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"664560\",\n                                  \"endMs\": \"670000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"done very easily but I think that has existed for many years in rails by the Highlight\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:04\"\n                                  },\n                                  \"trackingParams\": \"CL8BENP2BxhnIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 4 seconds done very easily but I think that has existed for many years in rails by the Highlight\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.664560.670000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"670000\",\n                                  \"endMs\": \"677880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"tag um yeah so let's go further we've done uh search now let's do sort so uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:10\"\n                                  },\n                                  \"trackingParams\": \"CL4BENP2BxhoIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 10 seconds tag um yeah so let's go further we've done uh search now let's do sort so uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.670000.677880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"677880\",\n                                  \"endMs\": \"684240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"here I added again the RX sort links and uh I can sort but you see now when I'm\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:17\"\n                                  },\n                                  \"trackingParams\": \"CL0BENP2BxhpIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 17 seconds here I added again the RX sort links and uh I can sort but you see now when I'm\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.677880.684240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"684240\",\n                                  \"endMs\": \"690399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"sorting the URL doesn't get updated to update the URL then also sort I will uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:24\"\n                                  },\n                                  \"trackingParams\": \"CLwBENP2BxhqIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 24 seconds sorting the URL doesn't get updated to update the URL then also sort I will uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.684240.690399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"690399\",\n                                  \"endMs\": \"696560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"add the tubo action Advance inside this tubo frame so whenever I do some kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:30\"\n                                  },\n                                  \"trackingParams\": \"CLsBENP2BxhrIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 30 seconds add the tubo action Advance inside this tubo frame so whenever I do some kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.690399.696560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"696560\",\n                                  \"endMs\": \"703480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh uh redirect some kind of request a get request from inside the tuba frame it is going to update the URL\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:36\"\n                                  },\n                                  \"trackingParams\": \"CLoBENP2BxhsIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 36 seconds uh uh redirect some kind of request a get request from inside the tuba frame it is going to update the URL\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.696560.703480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"703480\",\n                                  \"endMs\": \"709000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"accordingly um yeah so Tu action Advance uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:43\"\n                                  },\n                                  \"trackingParams\": \"CLkBENP2BxhtIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 43 seconds accordingly um yeah so Tu action Advance uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.703480.709000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"709000\",\n                                  \"endMs\": \"715839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"now let's see I will try to navigate outside of the frame so uh I will try to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:49\"\n                                  },\n                                  \"trackingParams\": \"CLgBENP2BxhuIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 49 seconds now let's see I will try to navigate outside of the frame so uh I will try to\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.709000.715839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"715839\",\n                                  \"endMs\": \"722240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"click the show on one of the employees and it doesn't work you see we got this content missing thing why do we get it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:55\"\n                                  },\n                                  \"trackingParams\": \"CLcBENP2BxhvIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 55 seconds click the show on one of the employees and it doesn't work you see we got this content missing thing why do we get it\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.715839.722240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"722240\",\n                                  \"endMs\": \"729079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"let's go to the browser console so you see uh I make the show request and uh in the network tab we see that we actually\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:02\"\n                                  },\n                                  \"trackingParams\": \"CLYBENP2BxhwIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 2 seconds let's go to the browser console so you see uh I make the show request and uh in the network tab we see that we actually\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.722240.729079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"729079\",\n                                  \"endMs\": \"734279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"had a successful response but for some reason we didn't update the page and if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:09\"\n                                  },\n                                  \"trackingParams\": \"CLUBENP2BxhxIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 9 seconds had a successful response but for some reason we didn't update the page and if\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.729079.734279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"734279\",\n                                  \"endMs\": \"741800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we go to the consult tab we see that we made a request to the employee uh show page but the show page did not have a tu\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:14\"\n                                  },\n                                  \"trackingParams\": \"CLQBENP2BxhyIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 14 seconds we go to the consult tab we see that we made a request to the employee uh show page but the show page did not have a tu\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.734279.741800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"741800\",\n                                  \"endMs\": \"749639\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"frame with employees list so in this case we will want to add Target top on this to frame and uh this way all the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:21\"\n                                  },\n                                  \"trackingParams\": \"CLMBENP2BxhzIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 21 seconds frame with employees list so in this case we will want to add Target top on this to frame and uh this way all the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.741800.749639\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"749639\",\n                                  \"endMs\": \"756760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"requests that are going outside of uh the page would be a full page to redirect so now I click show and it does\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:29\"\n                                  },\n                                  \"trackingParams\": \"CLIBENP2Bxh0IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 29 seconds requests that are going outside of uh the page would be a full page to redirect so now I click show and it does\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.749639.756760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"756760\",\n                                  \"endMs\": \"762360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a full page toir that's adding this target top uh next I really love this example\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:36\"\n                                  },\n                                  \"trackingParams\": \"CLEBENP2Bxh1IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 36 seconds a full page toir that's adding this target top uh next I really love this example\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.756760.762360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"762360\",\n                                  \"endMs\": \"769120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in line editing so I have a Jo list of employees imagine you're building something like an Excel uh table in your\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:42\"\n                                  },\n                                  \"trackingParams\": \"CLABENP2Bxh2IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 42 seconds in line editing so I have a Jo list of employees imagine you're building something like an Excel uh table in your\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.762360.769120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"769120\",\n                                  \"endMs\": \"776880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"application and you click on the name or surname or any attribute and you can update it in line so you see I go and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:49\"\n                                  },\n                                  \"trackingParams\": \"CK8BENP2Bxh3IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 49 seconds application and you click on the name or surname or any attribute and you can update it in line so you see I go and\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.769120.776880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"776880\",\n                                  \"endMs\": \"782680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"make a request to the edit page I make make a request to update it and the data\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:56\"\n                                  },\n                                  \"trackingParams\": \"CK4BENP2Bxh4IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 56 seconds make a request to the edit page I make make a request to update it and the data\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.776880.782680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"782680\",\n                                  \"endMs\": \"788600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"gets updated how does it work it's a bit more complex so I won't be going very\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:02\"\n                                  },\n                                  \"trackingParams\": \"CK0BENP2Bxh5IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 2 seconds gets updated how does it work it's a bit more complex so I won't be going very\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.782680.788600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"788600\",\n                                  \"endMs\": \"794680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"deep but basically I'm wrapping each uh attribute into a separate uh tubo frame\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:08\"\n                                  },\n                                  \"trackingParams\": \"CKwBENP2Bxh6IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 8 seconds deep but basically I'm wrapping each uh attribute into a separate uh tubo frame\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.788600.794680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"794680\",\n                                  \"endMs\": \"800240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"tag and it makes a request to the edit page and it updates only the attribute\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:14\"\n                                  },\n                                  \"trackingParams\": \"CKsBENP2Bxh7IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 14 seconds tag and it makes a request to the edit page and it updates only the attribute\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.794680.800240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"800240\",\n                                  \"endMs\": \"806760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that is wrapped so you see each uh yeah the form is wrapped in a tuba frame and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:20\"\n                                  },\n                                  \"trackingParams\": \"CKoBENP2Bxh8IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 20 seconds that is wrapped so you see each uh yeah the form is wrapped in a tuba frame and\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.800240.806760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"806760\",\n                                  \"endMs\": \"812800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I render only the attribute that uh is the one in the request progams yeah when\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:26\"\n                                  },\n                                  \"trackingParams\": \"CKkBENP2Bxh9IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 26 seconds I render only the attribute that uh is the one in the request progams yeah when\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.806760.812800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"812800\",\n                                  \"endMs\": \"817920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I was approximately this slide I thought okay it's like going to deep this should\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:32\"\n                                  },\n                                  \"trackingParams\": \"CKgBENP2Bxh-IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 32 seconds I was approximately this slide I thought okay it's like going to deep this should\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.812800.817920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"817920\",\n                                  \"endMs\": \"823440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"have been a workshop you are actually you can just go to my uh GitHub and go\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:37\"\n                                  },\n                                  \"trackingParams\": \"CKcBENP2Bxh_IhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 37 seconds have been a workshop you are actually you can just go to my uh GitHub and go\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.817920.823440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"823440\",\n                                  \"endMs\": \"831000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"to hot cookbook and you'll see a bunch of these examples that you can uh try on your local machine or try to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:43\"\n                                  },\n                                  \"trackingParams\": \"CKYBENP2BxiAASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 43 seconds to hot cookbook and you'll see a bunch of these examples that you can uh try on your local machine or try to\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.823440.831000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"831000\",\n                                  \"endMs\": \"838399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"reproduce uh another beautiful example is chain select like you select country then State then city um a few years ago\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:51\"\n                                  },\n                                  \"trackingParams\": \"CKUBENP2BxiBASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 51 seconds reproduce uh another beautiful example is chain select like you select country then State then city um a few years ago\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.831000.838399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"838399\",\n                                  \"endMs\": \"846360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I worked at a company and when I joined they were using react just for like chain select so they had like bootstrap\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:58\"\n                                  },\n                                  \"trackingParams\": \"CKQBENP2BxiCASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 58 seconds I worked at a company and when I joined they were using react just for like chain select so they had like bootstrap\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.838399.846360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"846360\",\n                                  \"endMs\": \"853279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"some stimulus but they were using rect just for a page with chain select and nowadays you can easily do it with uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:06\"\n                                  },\n                                  \"trackingParams\": \"CKMBENP2BxiDASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 6 seconds some stimulus but they were using rect just for a page with chain select and nowadays you can easily do it with uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.846360.853279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"853279\",\n                                  \"endMs\": \"862839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"just using Tu of frames the trick here is that uh I uh submit the form without\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:13\"\n                                  },\n                                  \"trackingParams\": \"CKIBENP2BxiEASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 13 seconds just using Tu of frames the trick here is that uh I uh submit the form without\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.853279.862839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"862839\",\n                                  \"endMs\": \"869440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh to a different URL so you see I have a form button that uh uh submit uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:22\"\n                                  },\n                                  \"trackingParams\": \"CKEBENP2BxiFASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 22 seconds uh to a different URL so you see I have a form button that uh uh submit uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.862839.869440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"869440\",\n                                  \"endMs\": \"874680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"without uh doing the update action and I just refresh the form with the submitted\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:29\"\n                                  },\n                                  \"trackingParams\": \"CKABENP2BxiGASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 29 seconds without uh doing the update action and I just refresh the form with the submitted\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.869440.874680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"874680\",\n                                  \"endMs\": \"880680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"prams so there are a few tricks and you can learn more about these specific details again on the C's YouTube channel\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:34\"\n                                  },\n                                  \"trackingParams\": \"CJ8BENP2BxiHASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 34 seconds prams so there are a few tricks and you can learn more about these specific details again on the C's YouTube channel\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.874680.880680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"880680\",\n                                  \"endMs\": \"886759\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"where there are videos about each of these uh approaches um yeah another beautiful\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:40\"\n                                  },\n                                  \"trackingParams\": \"CJ4BENP2BxiIASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 40 seconds where there are videos about each of these uh approaches um yeah another beautiful\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.880680.886759\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"886759\",\n                                  \"endMs\": \"893880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"example is models so in this case we want to edit an employee you see I click new employee I can get the errors\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:46\"\n                                  },\n                                  \"trackingParams\": \"CJ0BENP2BxiJASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 46 seconds example is models so in this case we want to edit an employee you see I click new employee I can get the errors\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.886759.893880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"893880\",\n                                  \"endMs\": \"899320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"rendered I can go and try to edit one of the employees and see his uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:53\"\n                                  },\n                                  \"trackingParams\": \"CJwBENP2BxiKASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 53 seconds rendered I can go and try to edit one of the employees and see his uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.893880.899320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"899320\",\n                                  \"endMs\": \"905839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"attributes there so in the case of the models most importantly on the link to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:59\"\n                                  },\n                                  \"trackingParams\": \"CJsBENP2BxiLASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 59 seconds attributes there so in the case of the models most importantly on the link to\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.899320.905839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"905839\",\n                                  \"endMs\": \"911720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"for example new emplo I add data tubo frame model so it would go to the new\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:05\"\n                                  },\n                                  \"trackingParams\": \"CJoBENP2BxiMASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 5 seconds for example new emplo I add data tubo frame model so it would go to the new\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.905839.911720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"911720\",\n                                  \"endMs\": \"917040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"action uh here I have the new action it is wrapped into the TU frame model and I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:11\"\n                                  },\n                                  \"trackingParams\": \"CJkBENP2BxiNASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 11 seconds action uh here I have the new action it is wrapped into the TU frame model and I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.911720.917040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"917040\",\n                                  \"endMs\": \"924120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"also have the tuboff frame tag model in my application layout so that there is a placeholder like an element with an ID\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:17\"\n                                  },\n                                  \"trackingParams\": \"CJgBENP2BxiOASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 17 seconds also have the tuboff frame tag model in my application layout so that there is a placeholder like an element with an ID\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.917040.924120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"924120\",\n                                  \"endMs\": \"931279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that can always be replaced and well what what kind of model is it without a tiny bit of styling and just in case\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:24\"\n                                  },\n                                  \"trackingParams\": \"CJcBENP2BxiPASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 24 seconds that can always be replaced and well what what kind of model is it without a tiny bit of styling and just in case\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.924120.931279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"931279\",\n                                  \"endMs\": \"938040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"when using models another thing I really like to do is add the like a redirect to back or somewhere if it is not a tu of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:31\"\n                                  },\n                                  \"trackingParams\": \"CJYBENP2BxiQASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 31 seconds when using models another thing I really like to do is add the like a redirect to back or somewhere if it is not a tu of\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.931279.938040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"938040\",\n                                  \"endMs\": \"944040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"frame request otherwise you will try to go to the employees new page and the model will be rendered and everything\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:38\"\n                                  },\n                                  \"trackingParams\": \"CJUBENP2BxiRASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 38 seconds frame request otherwise you will try to go to the employees new page and the model will be rendered and everything\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.938040.944040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"944040\",\n                                  \"endMs\": \"949560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"else will be empty and it won't look great and uh yeah going back to TU\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:44\"\n                                  },\n                                  \"trackingParams\": \"CJQBENP2BxiSASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 44 seconds else will be empty and it won't look great and uh yeah going back to TU\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.944040.949560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"949560\",\n                                  \"endMs\": \"955800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"frames really when I was starting to prepare the talk I was thinking okay tub frames really feels that like the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:49\"\n                                  },\n                                  \"trackingParams\": \"CJMBENP2BxiTASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 49 seconds frames really when I was starting to prepare the talk I was thinking okay tub frames really feels that like the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.949560.955800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"955800\",\n                                  \"endMs\": \"963720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"hardest thing like it's the hardest to make examples for and the hardest to wrap my hand my hand my head uh around\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:55\"\n                                  },\n                                  \"trackingParams\": \"CJIBENP2BxiUASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 55 seconds hardest thing like it's the hardest to make examples for and the hardest to wrap my hand my hand my head uh around\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.955800.963720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"963720\",\n                                  \"endMs\": \"969399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"but there are quite a lot of things you can do with it so um a few things I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:03\"\n                                  },\n                                  \"trackingParams\": \"CJEBENP2BxiVASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 3 seconds but there are quite a lot of things you can do with it so um a few things I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.963720.969399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"969399\",\n                                  \"endMs\": \"977759\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"would suggest if you like identify yourself as a backend developer and you want to uh learn some hot VM turbo so uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:09\"\n                                  },\n                                  \"trackingParams\": \"CJABENP2BxiWASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 9 seconds would suggest if you like identify yourself as a backend developer and you want to uh learn some hot VM turbo so uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.969399.977759\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"977759\",\n                                  \"endMs\": \"984000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you will start using the browser network tab to see the turbo requests that are in coming you will sometimes have to use\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:17\"\n                                  },\n                                  \"trackingParams\": \"CI8BENP2BxiXASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 17 seconds you will start using the browser network tab to see the turbo requests that are in coming you will sometimes have to use\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.977759.984000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"984000\",\n                                  \"endMs\": \"990839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the console tab for stimulus and for debugging uh d so you will need to give\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:24\"\n                                  },\n                                  \"trackingParams\": \"CI4BENP2BxiYASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 24 seconds the console tab for stimulus and for debugging uh d so you will need to give\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.984000.990839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"990839\",\n                                  \"endMs\": \"996440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"IDs to the parts of the page or the records that you want to replace you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:30\"\n                                  },\n                                  \"trackingParams\": \"CI0BENP2BxiZASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 30 seconds IDs to the parts of the page or the records that you want to replace you\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.990839.996440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"996440\",\n                                  \"endMs\": \"1002240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"will start using data attributes different stuff like on change on click and another thing I really recommend is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:36\"\n                                  },\n                                  \"trackingParams\": \"CIwBENP2BxiaASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 36 seconds will start using data attributes different stuff like on change on click and another thing I really recommend is\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.996440.1002240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1002240\",\n                                  \"endMs\": \"1008279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"better understanding how forms are uh how HTML forms work so like you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:42\"\n                                  },\n                                  \"trackingParams\": \"CIsBENP2BxibASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 42 seconds better understanding how forms are uh how HTML forms work so like you\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1002240.1008279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1008279\",\n                                  \"endMs\": \"1015880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"can have different submit buttons within one form you can have attributes that are not within the form in HTML but\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:48\"\n                                  },\n                                  \"trackingParams\": \"CIoBENP2BxicASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 48 seconds can have different submit buttons within one form you can have attributes that are not within the form in HTML but\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1008279.1015880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1015880\",\n                                  \"endMs\": \"1022519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"submit to a specific form so it will also help you a lot and go next to TBO streams so this I think might be one of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:55\"\n                                  },\n                                  \"trackingParams\": \"CIkBENP2BxidASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 55 seconds submit to a specific form so it will also help you a lot and go next to TBO streams so this I think might be one of\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1015880.1022519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1022519\",\n                                  \"endMs\": \"1028000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the easiest things for so for me tobo streams is basically rebranded js.\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:02\"\n                                  },\n                                  \"trackingParams\": \"CIgBENP2BxieASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 2 seconds the easiest things for so for me tobo streams is basically rebranded js.\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1022519.1028000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1028000\",\n                                  \"endMs\": \"1033480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Erb uh yeah remember like previously we had this format JS and in like ajs Erb\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:08\"\n                                  },\n                                  \"trackingParams\": \"CIcBENP2BxifASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 8 seconds Erb uh yeah remember like previously we had this format JS and in like ajs Erb\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1028000.1033480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1033480\",\n                                  \"endMs\": \"1039400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"file we would find an element with an ID and replace it with a partial or with\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:13\"\n                                  },\n                                  \"trackingParams\": \"CIYBENP2BxigASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 13 seconds file we would find an element with an ID and replace it with a partial or with\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1033480.1039400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1039400\",\n                                  \"endMs\": \"1045240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"some HTML or with something else and uh with the tuba streams again instead of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:19\"\n                                  },\n                                  \"trackingParams\": \"CIUBENP2BxihASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 19 seconds some HTML or with something else and uh with the tuba streams again instead of\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1039400.1045240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1045240\",\n                                  \"endMs\": \"1052840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"format JS we have format tuba stream and we have a few actions so update you place add on top add on the bottom and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:25\"\n                                  },\n                                  \"trackingParams\": \"CIQBENP2BxiiASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 25 seconds format JS we have format tuba stream and we have a few actions so update you place add on top add on the bottom and\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1045240.1052840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1052840\",\n                                  \"endMs\": \"1058039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"remove an element and an example would be uh again with models so previously\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:32\"\n                                  },\n                                  \"trackingParams\": \"CIMBENP2BxijASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 32 seconds remove an element and an example would be uh again with models so previously\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1052840.1058039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1058039\",\n                                  \"endMs\": \"1064160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"with to of frames we were rendering models rendering errors but now we want to also update the list of employees so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:38\"\n                                  },\n                                  \"trackingParams\": \"CIIBENP2BxikASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 38 seconds with to of frames we were rendering models rendering errors but now we want to also update the list of employees so\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1058039.1064160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1064160\",\n                                  \"endMs\": \"1070000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I'm going to try to uh submit the record and you see the employee has been added to the list I'm going to rename the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:44\"\n                                  },\n                                  \"trackingParams\": \"CIEBENP2BxilASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 44 seconds I'm going to try to uh submit the record and you see the employee has been added to the list I'm going to rename the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1064160.1070000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1070000\",\n                                  \"endMs\": \"1076480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"employee and you see again there was a request to update this record and it would look something like this so in the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:50\"\n                                  },\n                                  \"trackingParams\": \"CIABENP2BximASITCLKDqMXGgosDFbDxTwgdTCQGWQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 50 seconds employee and you see again there was a request to update this record and it would look something like this so in the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1070000.1076480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1076480\",\n                                  \"endMs\": \"1082640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"update uh and create action I would add for tuba stream so that the controller knows that we are going to try to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:56\"\n                                  },\n                                  \"trackingParams\": \"CH8Q0_YHGKcBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 56 seconds update uh and create action I would add for tuba stream so that the controller knows that we are going to try to\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1076480.1082640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1082640\",\n                                  \"endMs\": \"1090720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"respond with tuba stream and I created that create tuba stream and update to stream templates where I will prepend so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:02\"\n                                  },\n                                  \"trackingParams\": \"CH4Q0_YHGKgBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 2 seconds respond with tuba stream and I created that create tuba stream and update to stream templates where I will prepend so\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1082640.1090720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1090720\",\n                                  \"endMs\": \"1096480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"add on top of the list or in case of updating I'm going to replace the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:10\"\n                                  },\n                                  \"trackingParams\": \"CH0Q0_YHGKkBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 10 seconds add on top of the list or in case of updating I'm going to replace the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1090720.1096480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1096480\",\n                                  \"endMs\": \"1104960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"element with the ID like employee 17 with a refreshed option of it um another example just removing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:16\"\n                                  },\n                                  \"trackingParams\": \"CHwQ0_YHGKoBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 16 seconds element with the ID like employee 17 with a refreshed option of it um another example just removing\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1096480.1104960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1104960\",\n                                  \"endMs\": \"1110000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"elements from a list so here I'm just clicking delete and you see I have a request and the employee disappears from\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:24\"\n                                  },\n                                  \"trackingParams\": \"CHsQ0_YHGKsBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 24 seconds elements from a list so here I'm just clicking delete and you see I have a request and the employee disappears from\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1104960.1110000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1110000\",\n                                  \"endMs\": \"1117760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the list so again absolutely the same approach but here I'm using to stream remove employee and by remove employee\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:30\"\n                                  },\n                                  \"trackingParams\": \"CHoQ0_YHGKwBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 30 seconds the list so again absolutely the same approach but here I'm using to stream remove employee and by remove employee\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1110000.1117760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1117760\",\n                                  \"endMs\": \"1124840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it is looking for an element with the employee underscore 17 or whatever the ID of the employee is so you should uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:37\"\n                                  },\n                                  \"trackingParams\": \"CHkQ0_YHGK0BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 37 seconds it is looking for an element with the employee underscore 17 or whatever the ID of the employee is so you should uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1117760.1124840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1124840\",\n                                  \"endMs\": \"1132799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"be sure to wrap these elements that you display on your index page uh each of them into a div with the ID of this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:44\"\n                                  },\n                                  \"trackingParams\": \"CHgQ0_YHGK4BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 44 seconds be sure to wrap these elements that you display on your index page uh each of them into a div with the ID of this\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1124840.1132799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1132799\",\n                                  \"endMs\": \"1138799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"element uh another example is sending a few tubo streams so here you see I'm removing the element from the list and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:52\"\n                                  },\n                                  \"trackingParams\": \"CHcQ0_YHGK8BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 52 seconds element uh another example is sending a few tubo streams so here you see I'm removing the element from the list and\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1132799.1138799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1138799\",\n                                  \"endMs\": \"1147480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"also updating the count of employees and you see I I'm also looking at the network Tab and uh yeah in the response\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:58\"\n                                  },\n                                  \"trackingParams\": \"CHYQ0_YHGLABIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 58 seconds also updating the count of employees and you see I I'm also looking at the network Tab and uh yeah in the response\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1138799.1147480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1147480\",\n                                  \"endMs\": \"1152520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you can see that there were two tubo stream actions so you see I'm adding two\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:07\"\n                                  },\n                                  \"trackingParams\": \"CHUQ0_YHGLEBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 7 seconds you can see that there were two tubo stream actions so you see I'm adding two\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1147480.1152520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1152520\",\n                                  \"endMs\": \"1157760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"tub streams in that destroy Tu stream IB one to remove the employee the second to update the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:12\"\n                                  },\n                                  \"trackingParams\": \"CHQQ0_YHGLIBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 12 seconds tub streams in that destroy Tu stream IB one to remove the employee the second to update the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1152520.1157760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1157760\",\n                                  \"endMs\": \"1162919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"counter uh another common thing would be to just like update flash in this case\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:17\"\n                                  },\n                                  \"trackingParams\": \"CHMQ0_YHGLMBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 17 seconds counter uh another common thing would be to just like update flash in this case\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1157760.1162919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1162919\",\n                                  \"endMs\": \"1168360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I'm not replacing the flash message but I'm adding multiple flash messages on\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:22\"\n                                  },\n                                  \"trackingParams\": \"CHIQ0_YHGLQBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 22 seconds I'm not replacing the flash message but I'm adding multiple flash messages on\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1162919.1168360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1168360\",\n                                  \"endMs\": \"1174600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the page and uh a cool thing actually I learned this just recently so for common\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:28\"\n                                  },\n                                  \"trackingParams\": \"CHEQ0_YHGLUBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 28 seconds the page and uh a cool thing actually I learned this just recently so for common\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1168360.1174600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1174600\",\n                                  \"endMs\": \"1182440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"stuff that you might have on many pages instead of adding the to stream app and Flash inside the uh destroy template for\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:34\"\n                                  },\n                                  \"trackingParams\": \"CHAQ0_YHGLYBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 34 seconds stuff that you might have on many pages instead of adding the to stream app and Flash inside the uh destroy template for\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1174600.1182440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1182440\",\n                                  \"endMs\": \"1187559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"example or inside the controller you can just have application to stream Erb where you would be always replacing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:42\"\n                                  },\n                                  \"trackingParams\": \"CG8Q0_YHGLcBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 42 seconds example or inside the controller you can just have application to stream Erb where you would be always replacing\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1182440.1187559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1187559\",\n                                  \"endMs\": \"1193919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Flash and uh you would not have to duplicate this like update flash in each of your controller\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:47\"\n                                  },\n                                  \"trackingParams\": \"CG4Q0_YHGLgBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 47 seconds Flash and uh you would not have to duplicate this like update flash in each of your controller\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1187559.1193919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1193919\",\n                                  \"endMs\": \"1199000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"actions uh another example they you would use both Duo streams and to frames\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:53\"\n                                  },\n                                  \"trackingParams\": \"CG0Q0_YHGLkBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 53 seconds actions uh another example they you would use both Duo streams and to frames\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1193919.1199000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1199000\",\n                                  \"endMs\": \"1205960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"together is infinite pagination so here is an example of uh my Instagram where I'm uh scrolling down and you see I have\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:59\"\n                                  },\n                                  \"trackingParams\": \"CGwQ0_YHGLoBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 59 seconds together is infinite pagination so here is an example of uh my Instagram where I'm uh scrolling down and you see I have\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1199000.1205960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1205960\",\n                                  \"endMs\": \"1211880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"new network requests and I get next pages of the results and uh here in the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:05\"\n                                  },\n                                  \"trackingParams\": \"CGsQ0_YHGLsBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 5 seconds new network requests and I get next pages of the results and uh here in the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1205960.1211880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1211880\",\n                                  \"endMs\": \"1217120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"index page when it is loaded I have a tuba frame and an empty div with a list\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:11\"\n                                  },\n                                  \"trackingParams\": \"CGoQ0_YHGLwBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 11 seconds index page when it is loaded I have a tuba frame and an empty div with a list\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1211880.1217120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1217120\",\n                                  \"endMs\": \"1222559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of posts and uh so I'm trying to respond with foral tuba stream again the index\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:17\"\n                                  },\n                                  \"trackingParams\": \"CGkQ0_YHGL0BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 17 seconds of posts and uh so I'm trying to respond with foral tuba stream again the index\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1217120.1222559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1222559\",\n                                  \"endMs\": \"1229080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"page and in format tuba stream I am uh showing a list of posts and replacing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:22\"\n                                  },\n                                  \"trackingParams\": \"CGgQ0_YHGL4BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 22 seconds page and in format tuba stream I am uh showing a list of posts and replacing\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1222559.1229080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1229080\",\n                                  \"endMs\": \"1234880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this tuba frame so uh uh this is a very interesting example of how you can\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:29\"\n                                  },\n                                  \"trackingParams\": \"CGcQ0_YHGL8BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 29 seconds this tuba frame so uh uh this is a very interesting example of how you can\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1229080.1234880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1234880\",\n                                  \"endMs\": \"1241440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"combine tuba streams and frames and Achieve much much more uh next Toba stream broadcast so I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:34\"\n                                  },\n                                  \"trackingParams\": \"CGYQ0_YHGMABIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 34 seconds combine tuba streams and frames and Achieve much much more uh next Toba stream broadcast so I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1234880.1241440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1241440\",\n                                  \"endMs\": \"1249640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"really try to differentiate Toba streams and to stream broadcast the ones that are via just HTTP you send a request you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:41\"\n                                  },\n                                  \"trackingParams\": \"CGUQ0_YHGMEBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 41 seconds really try to differentiate Toba streams and to stream broadcast the ones that are via just HTTP you send a request you\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1241440.1249640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1249640\",\n                                  \"endMs\": \"1255240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"receive a response and the one with uh like uh changes that can happen without\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:49\"\n                                  },\n                                  \"trackingParams\": \"CGQQ0_YHGMIBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 49 seconds receive a response and the one with uh like uh changes that can happen without\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1249640.1255240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1255240\",\n                                  \"endMs\": \"1263039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"your uh specific action so so uh I would say that uh well to stream broadcast use\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:55\"\n                                  },\n                                  \"trackingParams\": \"CGMQ0_YHGMMBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 55 seconds your uh specific action so so uh I would say that uh well to stream broadcast use\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1255240.1263039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1263039\",\n                                  \"endMs\": \"1270919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"web sockets use action cable I think you was just seing the action cable talk and JS Erb the rebranded JS Erb so you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:03\"\n                                  },\n                                  \"trackingParams\": \"CGIQ0_YHGMQBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 3 seconds web sockets use action cable I think you was just seing the action cable talk and JS Erb the rebranded JS Erb so you\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1263039.1270919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1270919\",\n                                  \"endMs\": \"1277960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"listen to some changes and you add on on top or replace or remove or something so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:10\"\n                                  },\n                                  \"trackingParams\": \"CGEQ0_YHGMUBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 10 seconds listen to some changes and you add on on top or replace or remove or something so\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1270919.1277960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1277960\",\n                                  \"endMs\": \"1285279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um a simple example of something you could build with to stream broadcast is like a live chat as on YouTube or live\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:17\"\n                                  },\n                                  \"trackingParams\": \"CGAQ0_YHGMYBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 17 seconds um a simple example of something you could build with to stream broadcast is like a live chat as on YouTube or live\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1277960.1285279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1285279\",\n                                  \"endMs\": \"1291919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"messages so here I have like two message windows in Facebook and I can be messaging in both of them at the same\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:25\"\n                                  },\n                                  \"trackingParams\": \"CF8Q0_YHGMcBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 25 seconds messages so here I have like two message windows in Facebook and I can be messaging in both of them at the same\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1285279.1291919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1291919\",\n                                  \"endMs\": \"1296960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"time and I don't need any page Refreshers uh here's a simple example I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:31\"\n                                  },\n                                  \"trackingParams\": \"CF4Q0_YHGMgBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 31 seconds time and I don't need any page Refreshers uh here's a simple example I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1291919.1296960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1296960\",\n                                  \"endMs\": \"1303679\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"have two browser tabs open and uh you see I have this tuba stream channel is streaming from Global Channel and in my\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:36\"\n                                  },\n                                  \"trackingParams\": \"CF0Q0_YHGMkBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 36 seconds have two browser tabs open and uh you see I have this tuba stream channel is streaming from Global Channel and in my\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1296960.1303679\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1303679\",\n                                  \"endMs\": \"1309559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"console I'm going to uh make a few tuo stream requests so you see I'm making a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:43\"\n                                  },\n                                  \"trackingParams\": \"CFwQ0_YHGMoBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 43 seconds console I'm going to uh make a few tuo stream requests so you see I'm making a\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1303679.1309559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1309559\",\n                                  \"endMs\": \"1317200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"request to uh to the global Channel and both windows will listen to this Global Channel and uh I'm saying to update the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:49\"\n                                  },\n                                  \"trackingParams\": \"CFsQ0_YHGMsBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 49 seconds request to uh to the global Channel and both windows will listen to this Global Channel and uh I'm saying to update the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1309559.1317200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1317200\",\n                                  \"endMs\": \"1324080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it with time zone now and in both windows I'm not refreshing them but the time gets uh updated and I'm using this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:57\"\n                                  },\n                                  \"trackingParams\": \"CFoQ0_YHGMwBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 57 seconds it with time zone now and in both windows I'm not refreshing them but the time gets uh updated and I'm using this\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1317200.1324080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1324080\",\n                                  \"endMs\": \"1329919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh command so I have a stream from Global Channel I have an A div with ID\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:04\"\n                                  },\n                                  \"trackingParams\": \"CFkQ0_YHGM0BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 4 seconds uh command so I have a stream from Global Channel I have an A div with ID\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1324080.1329919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1329919\",\n                                  \"endMs\": \"1337120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"my element and I'm just replacing the HTML within this div with time zone now uh other things you can build with\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:09\"\n                                  },\n                                  \"trackingParams\": \"CFgQ0_YHGM4BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 9 seconds my element and I'm just replacing the HTML within this div with time zone now uh other things you can build with\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1329919.1337120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1337120\",\n                                  \"endMs\": \"1343559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like tuo stream broadcast very simple ones are like how many people are there visiting the website at the moment how\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:17\"\n                                  },\n                                  \"trackingParams\": \"CFcQ0_YHGM8BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 17 seconds like tuo stream broadcast very simple ones are like how many people are there visiting the website at the moment how\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1337120.1343559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1343559\",\n                                  \"endMs\": \"1351080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"many people are at this specific page you can see the behaviors at booking at the Google Docs at uh YouTube and here's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:23\"\n                                  },\n                                  \"trackingParams\": \"CFYQ0_YHGNABIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 23 seconds many people are at this specific page you can see the behaviors at booking at the Google Docs at uh YouTube and here's\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1343559.1351080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1351080\",\n                                  \"endMs\": \"1357039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"an example doing it in a brand new rails app so uh here I have one browser and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:31\"\n                                  },\n                                  \"trackingParams\": \"CFUQ0_YHGNEBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 31 seconds an example doing it in a brand new rails app so uh here I have one browser and\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1351080.1357039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1357039\",\n                                  \"endMs\": \"1362600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"here another you see I have two visitors in the app I go to the same room as this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:37\"\n                                  },\n                                  \"trackingParams\": \"CFQQ0_YHGNIBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 37 seconds here another you see I have two visitors in the app I go to the same room as this\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1357039.1362600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1362600\",\n                                  \"endMs\": \"1367880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"room and uh there are two people I close the tab and there is again one person in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:42\"\n                                  },\n                                  \"trackingParams\": \"CFMQ0_YHGNMBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 42 seconds room and uh there are two people I close the tab and there is again one person in\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1362600.1367880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1367880\",\n                                  \"endMs\": \"1373720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh the app so it works and it's really easy to do and a few like most common\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:47\"\n                                  },\n                                  \"trackingParams\": \"CFIQ0_YHGNQBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 47 seconds uh the app so it works and it's really easy to do and a few like most common\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1367880.1373720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1373720\",\n                                  \"endMs\": \"1381080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"broadcast uh uh listeners that I would uh Define and that I add to most of my apps is stream from current user in the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:53\"\n                                  },\n                                  \"trackingParams\": \"CFEQ0_YHGNUBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 53 seconds broadcast uh uh listeners that I would uh Define and that I add to most of my apps is stream from current user in the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1373720.1381080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1381080\",\n                                  \"endMs\": \"1387799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"application file so whenever you want to send a specific update to the user no matter what page he is in you would send\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:01\"\n                                  },\n                                  \"trackingParams\": \"CFAQ0_YHGNYBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 1 second application file so whenever you want to send a specific update to the user no matter what page he is in you would send\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1381080.1387799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1387799\",\n                                  \"endMs\": \"1392919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it to like the specific user then like Global notifications uh like some kind\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:07\"\n                                  },\n                                  \"trackingParams\": \"CE8Q0_YHGNcBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 7 seconds it to like the specific user then like Global notifications uh like some kind\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1387799.1392919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1392919\",\n                                  \"endMs\": \"1398960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of update for example you go to agency of learning rails World website you get these like live updates that you have a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:12\"\n                                  },\n                                  \"trackingParams\": \"CE4Q0_YHGNgBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 12 seconds of update for example you go to agency of learning rails World website you get these like live updates that you have a\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1392919.1398960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1398960\",\n                                  \"endMs\": \"1405840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"new session coming I think they're using Tu stream broadcast for that and uh specific like to a chat room or chat\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:18\"\n                                  },\n                                  \"trackingParams\": \"CE0Q0_YHGNkBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 18 seconds new session coming I think they're using Tu stream broadcast for that and uh specific like to a chat room or chat\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1398960.1405840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1405840\",\n                                  \"endMs\": \"1414200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"room and current user if you want to be even more specific like only this person in this chat room and uh in many examples for how to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:25\"\n                                  },\n                                  \"trackingParams\": \"CEwQ0_YHGNoBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 25 seconds room and current user if you want to be even more specific like only this person in this chat room and uh in many examples for how to\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1405840.1414200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1414200\",\n                                  \"endMs\": \"1421480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"use to stream broadcast you would see like broadcasting from a model so here are a few in each of this example like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:34\"\n                                  },\n                                  \"trackingParams\": \"CEsQ0_YHGNsBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 34 seconds use to stream broadcast you would see like broadcasting from a model so here are a few in each of this example like\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1414200.1421480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1421480\",\n                                  \"endMs\": \"1429880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it is less and less abstraction so this is what you would see in like the most basic tutorials and here I try to like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:41\"\n                                  },\n                                  \"trackingParams\": \"CEoQ0_YHGNwBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 41 seconds it is less and less abstraction so this is what you would see in like the most basic tutorials and here I try to like\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1421480.1429880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1429880\",\n                                  \"endMs\": \"1437320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"go and decompose it a bit more and a bit more so I really don't like this I don't like uh using this kind of callbacks I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:49\"\n                                  },\n                                  \"trackingParams\": \"CEkQ0_YHGN0BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 49 seconds go and decompose it a bit more and a bit more so I really don't like this I don't like uh using this kind of callbacks I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1429880.1437320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1437320\",\n                                  \"endMs\": \"1443200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like to be more explicit from my controllers and I always prefer using tuo channels broadcast update to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:57\"\n                                  },\n                                  \"trackingParams\": \"CEgQ0_YHGN4BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 57 seconds like to be more explicit from my controllers and I always prefer using tuo channels broadcast update to\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1437320.1443200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1443200\",\n                                  \"endMs\": \"1449919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"whenever I can instead of doing it from the model so going to the last part stimulus\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:03\"\n                                  },\n                                  \"trackingParams\": \"CEcQ0_YHGN8BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 3 seconds whenever I can instead of doing it from the model so going to the last part stimulus\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1443200.1449919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1449919\",\n                                  \"endMs\": \"1456600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um actually like stimulus a lot I uh always identified as a ruby rails\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:09\"\n                                  },\n                                  \"trackingParams\": \"CEYQ0_YHGOABIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 9 seconds um actually like stimulus a lot I uh always identified as a ruby rails\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1449919.1456600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1456600\",\n                                  \"endMs\": \"1461880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"developer not as a JavaScript person I always hated the gquery I tried to stay\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:16\"\n                                  },\n                                  \"trackingParams\": \"CEUQ0_YHGOEBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 16 seconds developer not as a JavaScript person I always hated the gquery I tried to stay\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1456600.1461880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1461880\",\n                                  \"endMs\": \"1470039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"away from react and stimulus just like fit uh my head uh my mindset well so uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:21\"\n                                  },\n                                  \"trackingParams\": \"CEQQ0_YHGOIBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 21 seconds away from react and stimulus just like fit uh my head uh my mindset well so uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1461880.1470039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1470039\",\n                                  \"endMs\": \"1475760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"thanks to stimulus we don't need to disable turbo or Turbo links when loading JavaScript anymore we don't need\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:30\"\n                                  },\n                                  \"trackingParams\": \"CEMQ0_YHGOMBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 30 seconds thanks to stimulus we don't need to disable turbo or Turbo links when loading JavaScript anymore we don't need\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1470039.1475760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1475760\",\n                                  \"endMs\": \"1482279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"to use J Fury I've actually worked on projects where I am removing J Fury and replacing it with stimulus and it works\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:35\"\n                                  },\n                                  \"trackingParams\": \"CEIQ0_YHGOQBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 35 seconds to use J Fury I've actually worked on projects where I am removing J Fury and replacing it with stimulus and it works\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1475760.1482279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1482279\",\n                                  \"endMs\": \"1490440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"perfectly you don't need to have inline scripts a much better approach is to have stimulus and uh yeah let's see a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:42\"\n                                  },\n                                  \"trackingParams\": \"CEEQ0_YHGOUBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 42 seconds perfectly you don't need to have inline scripts a much better approach is to have stimulus and uh yeah let's see a\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1482279.1490440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1490440\",\n                                  \"endMs\": \"1496640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"few examples so talking of stimulus yesterday dhh and I think also hor have\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:50\"\n                                  },\n                                  \"trackingParams\": \"CEAQ0_YHGOYBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 50 seconds few examples so talking of stimulus yesterday dhh and I think also hor have\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1490440.1496640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1496640\",\n                                  \"endMs\": \"1502039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"both shown that a base camp can ban as different examples of live interactions\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:56\"\n                                  },\n                                  \"trackingParams\": \"CD8Q0_YHGOcBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 56 seconds both shown that a base camp can ban as different examples of live interactions\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1496640.1502039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1502039\",\n                                  \"endMs\": \"1509880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you can do and how you can use hotfire and uh when I saw this I thought okay they must have seen my video about like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:02\"\n                                  },\n                                  \"trackingParams\": \"CD4Q0_YHGOgBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 2 seconds you can do and how you can use hotfire and uh when I saw this I thought okay they must have seen my video about like\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1502039.1509880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1509880\",\n                                  \"endMs\": \"1518039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"how to add Dragon drop so cool basic comp watches my videos and they create good products yeah so here's an example\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:09\"\n                                  },\n                                  \"trackingParams\": \"CD0Q0_YHGOkBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 9 seconds how to add Dragon drop so cool basic comp watches my videos and they create good products yeah so here's an example\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1509880.1518039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1518039\",\n                                  \"endMs\": \"1523320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of doing like the same can board if you want to recreate base camp with a new\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:18\"\n                                  },\n                                  \"trackingParams\": \"CDwQ0_YHGOoBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 18 seconds of doing like the same can board if you want to recreate base camp with a new\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1518039.1523320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1523320\",\n                                  \"endMs\": \"1528520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"rails application here I have a list a list of lists and tasks with in the list\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:23\"\n                                  },\n                                  \"trackingParams\": \"CDsQ0_YHGOsBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 23 seconds rails application here I have a list a list of lists and tasks with in the list\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1523320.1528520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1528520\",\n                                  \"endMs\": \"1533760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so I will be moving one task from another for this you can just use a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:28\"\n                                  },\n                                  \"trackingParams\": \"CDoQ0_YHGOwBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 28 seconds so I will be moving one task from another for this you can just use a\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1528520.1533760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1533760\",\n                                  \"endMs\": \"1541679\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"library like sortable JS but the whole trick the main trick is in actually updating the records in your database so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:33\"\n                                  },\n                                  \"trackingParams\": \"CDkQ0_YHGO0BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 33 seconds library like sortable JS but the whole trick the main trick is in actually updating the records in your database so\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1533760.1541679\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1541679\",\n                                  \"endMs\": \"1547120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh here I'm using sortable JS as you see and also I'm using request JS so request\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:41\"\n                                  },\n                                  \"trackingParams\": \"CDgQ0_YHGO4BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 41 seconds uh here I'm using sortable JS as you see and also I'm using request JS so request\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1541679.1547120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1547120\",\n                                  \"endMs\": \"1553159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"JS is a perfect tool to make request to your controller actions from inside your\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:47\"\n                                  },\n                                  \"trackingParams\": \"CDcQ0_YHGO8BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 47 seconds JS is a perfect tool to make request to your controller actions from inside your\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1547120.1553159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1553159\",\n                                  \"endMs\": \"1560440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"stimulus controllers so here I'm using sortable to be able to sort and then I'm making a request using request GS to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:53\"\n                                  },\n                                  \"trackingParams\": \"CDYQ0_YHGPABIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 53 seconds stimulus controllers so here I'm using sortable to be able to sort and then I'm making a request using request GS to\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1553159.1560440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1560440\",\n                                  \"endMs\": \"1566799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"update the record in the database so that when I refresh the page it all my V doesn't go uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:00\"\n                                  },\n                                  \"trackingParams\": \"CDUQ0_YHGPEBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes update the record in the database so that when I refresh the page it all my V doesn't go uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1560440.1566799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1566799\",\n                                  \"endMs\": \"1572360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"unnoticed another example would be uh again uh data tables so previously we\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:06\"\n                                  },\n                                  \"trackingParams\": \"CDQQ0_YHGPIBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 6 seconds unnoticed another example would be uh again uh data tables so previously we\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1566799.1572360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1572360\",\n                                  \"endMs\": \"1579240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"did data tables with the sending request to the server uh again and uh again but\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:12\"\n                                  },\n                                  \"trackingParams\": \"CDMQ0_YHGPMBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 12 seconds did data tables with the sending request to the server uh again and uh again but\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1572360.1579240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1579240\",\n                                  \"endMs\": \"1585440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh if you have just one page of results sometimes you might uh not need to actually add\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:19\"\n                                  },\n                                  \"trackingParams\": \"CDIQ0_YHGPQBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 19 seconds uh if you have just one page of results sometimes you might uh not need to actually add\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1579240.1585440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1585440\",\n                                  \"endMs\": \"1591159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the uh to frames to make requests on the server you can just do it like uh with\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:25\"\n                                  },\n                                  \"trackingParams\": \"CDEQ0_YHGPUBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 25 seconds the uh to frames to make requests on the server you can just do it like uh with\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1585440.1591159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1591159\",\n                                  \"endMs\": \"1596960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"JavaScript like uh many of you would by default so here is an example of doing with the JavaScript I just added a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:31\"\n                                  },\n                                  \"trackingParams\": \"CDAQ0_YHGPYBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 31 seconds JavaScript like uh many of you would by default so here is an example of doing with the JavaScript I just added a\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1591159.1596960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1596960\",\n                                  \"endMs\": \"1604640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"stimulus controller uh this is what I came up with for searching and for sorting and here I just uh plug in the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:36\"\n                                  },\n                                  \"trackingParams\": \"CC8Q0_YHGPcBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 36 seconds stimulus controller uh this is what I came up with for searching and for sorting and here I just uh plug in the\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1596960.1604640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1604640\",\n                                  \"endMs\": \"1610159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"controller I uh say that I want to sort by first name and last name and uh uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:44\"\n                                  },\n                                  \"trackingParams\": \"CC4Q0_YHGPgBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 44 seconds controller I uh say that I want to sort by first name and last name and uh uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1604640.1610159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1610159\",\n                                  \"endMs\": \"1617080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"search by first name and last name and uh it works so I would say if you have one page of results it kind of makes\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:50\"\n                                  },\n                                  \"trackingParams\": \"CC0Q0_YHGPkBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 50 seconds search by first name and last name and uh it works so I would say if you have one page of results it kind of makes\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1610159.1617080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1617080\",\n                                  \"endMs\": \"1623640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"sense to use uh stimulus regular JavaScript if you have multiple pages of results and you need to make request to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:57\"\n                                  },\n                                  \"trackingParams\": \"CCwQ0_YHGPoBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 57 seconds sense to use uh stimulus regular JavaScript if you have multiple pages of results and you need to make request to\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1617080.1623640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1623640\",\n                                  \"endMs\": \"1629240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the server obviously Toba frames uh another example of using tubo\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:03\"\n                                  },\n                                  \"trackingParams\": \"CCsQ0_YHGPsBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 3 seconds the server obviously Toba frames uh another example of using tubo\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1623640.1629240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1629240\",\n                                  \"endMs\": \"1635000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"tubo stimulus JS would be to import external libraries so as an example\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:09\"\n                                  },\n                                  \"trackingParams\": \"CCoQ0_YHGPwBIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 9 seconds tubo stimulus JS would be to import external libraries so as an example\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1629240.1635000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1635000\",\n                                  \"endMs\": \"1641440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we're going to import slim uh select that uh allows you to select multiple\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:15\"\n                                  },\n                                  \"trackingParams\": \"CCkQ0_YHGP0BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 15 seconds we're going to import slim uh select that uh allows you to select multiple\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1635000.1641440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1641440\",\n                                  \"endMs\": \"1647640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh uh options or search within your select box and this Library uses both Js\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:21\"\n                                  },\n                                  \"trackingParams\": \"CCgQ0_YHGP4BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 21 seconds uh uh options or search within your select box and this Library uses both Js\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1641440.1647640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1647640\",\n                                  \"endMs\": \"1653000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and CSS so first of all I'm going to input map pin slim select I'm going to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:27\"\n                                  },\n                                  \"trackingParams\": \"CCcQ0_YHGP8BIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 27 seconds and CSS so first of all I'm going to input map pin slim select I'm going to\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1647640.1653000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1653000\",\n                                  \"endMs\": \"1661399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"create a slim controller in the slim controller I'm going to uh initialize slim select I'm going to uh add it to my\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:33\"\n                                  },\n                                  \"trackingParams\": \"CCYQ0_YHGIACIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 33 seconds create a slim controller in the slim controller I'm going to uh initialize slim select I'm going to uh add it to my\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1653000.1661399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1661399\",\n                                  \"endMs\": \"1668039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"form element so you see data controller slim and I don't need to define a Target in this case because I'm saying this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:41\"\n                                  },\n                                  \"trackingParams\": \"CCUQ0_YHGIECIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 41 seconds form element so you see data controller slim and I don't need to define a Target in this case because I'm saying this\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1661399.1668039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1668039\",\n                                  \"endMs\": \"1675000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"element and this element is the form select so it will work and for the JavaScript so if you're using input Maps\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:48\"\n                                  },\n                                  \"trackingParams\": \"CCQQ0_YHGIICIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 48 seconds element and this element is the form select so it will work and for the JavaScript so if you're using input Maps\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1668039.1675000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1675000\",\n                                  \"endMs\": \"1680960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"maybe the easiest way would be just to inut the URL to the CDN in application\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:55\"\n                                  },\n                                  \"trackingParams\": \"CCMQ0_YHGIMCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 55 seconds maybe the easiest way would be just to inut the URL to the CDN in application\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1675000.1680960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1680960\",\n                                  \"endMs\": \"1686000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"CSS and uh here is how it would work with uh this code that I just provided\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:00\"\n                                  },\n                                  \"trackingParams\": \"CCIQ0_YHGIQCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes CSS and uh here is how it would work with uh this code that I just provided\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1680960.1686000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1686000\",\n                                  \"endMs\": \"1691840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so you see I have this country search I can select multiple oh one of the options I can start uh typing and it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:06\"\n                                  },\n                                  \"trackingParams\": \"CCEQ0_YHGIUCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 6 seconds so you see I have this country search I can select multiple oh one of the options I can start uh typing and it\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1686000.1691840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1691840\",\n                                  \"endMs\": \"1697760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"will autofill the country I want to select uh yeah another example maybe one\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:11\"\n                                  },\n                                  \"trackingParams\": \"CCAQ0_YHGIYCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 11 seconds will autofill the country I want to select uh yeah another example maybe one\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1691840.1697760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1697760\",\n                                  \"endMs\": \"1703120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of the first things I want to do when I add device is like uh hide this flash\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:17\"\n                                  },\n                                  \"trackingParams\": \"CB8Q0_YHGIcCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 17 seconds of the first things I want to do when I add device is like uh hide this flash\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1697760.1703120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1703120\",\n                                  \"endMs\": \"1709640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like I don't want this flash to be just heading on my page so uh I would want Auto hide it and this is an example of a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:23\"\n                                  },\n                                  \"trackingParams\": \"CB4Q0_YHGIgCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 23 seconds like I don't want this flash to be just heading on my page so uh I would want Auto hide it and this is an example of a\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1703120.1709640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1709640\",\n                                  \"endMs\": \"1716120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"stimulus control that I would be adding to all my apps where I can hide a flash message by either clicking on the flash\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:29\"\n                                  },\n                                  \"trackingParams\": \"CB0Q0_YHGIkCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 29 seconds stimulus control that I would be adding to all my apps where I can hide a flash message by either clicking on the flash\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1709640.1716120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1716120\",\n                                  \"endMs\": \"1722799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"message or on AC Cross or automatically hide it after a certain period of time here on the Super's website you see I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:36\"\n                                  },\n                                  \"trackingParams\": \"CBwQ0_YHGIoCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 36 seconds message or on AC Cross or automatically hide it after a certain period of time here on the Super's website you see I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1716120.1722799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1722799\",\n                                  \"endMs\": \"1728960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"also have some fancy animation where the flash disappears either when I click X\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:42\"\n                                  },\n                                  \"trackingParams\": \"CBsQ0_YHGIsCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 42 seconds also have some fancy animation where the flash disappears either when I click X\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1722799.1728960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1728960\",\n                                  \"endMs\": \"1734840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"or when the animation is over then again uh remember on the very\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:48\"\n                                  },\n                                  \"trackingParams\": \"CBoQ0_YHGIwCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 48 seconds or when the animation is over then again uh remember on the very\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1728960.1734840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1734840\",\n                                  \"endMs\": \"1741559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"beginning with too frames each time when we add added the one element to our search query in the data tables we were\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:54\"\n                                  },\n                                  \"trackingParams\": \"CBkQ0_YHGI0CIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 54 seconds beginning with too frames each time when we add added the one element to our search query in the data tables we were\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1734840.1741559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1741559\",\n                                  \"endMs\": \"1748840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"making a request to the server well that's not the best approach because like when you ass searching just with one element uh like one letter it will\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:01\"\n                                  },\n                                  \"trackingParams\": \"CBgQ0_YHGI4CIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 1 second making a request to the server well that's not the best approach because like when you ass searching just with one element uh like one letter it will\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1741559.1748840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1748840\",\n                                  \"endMs\": \"1754080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"not give you a good search result so I would add some kind of debouncing activities so like search after a few\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:08\"\n                                  },\n                                  \"trackingParams\": \"CBcQ0_YHGI8CIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 8 seconds not give you a good search result so I would add some kind of debouncing activities so like search after a few\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1748840.1754080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1754080\",\n                                  \"endMs\": \"1761120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"seconds since you started typing or search after a few seconds after you stopped typing so again in this case you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:14\"\n                                  },\n                                  \"trackingParams\": \"CBYQ0_YHGJACIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 14 seconds seconds since you started typing or search after a few seconds after you stopped typing so again in this case you\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1754080.1761120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1761120\",\n                                  \"endMs\": \"1768120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"don't always need to import a like de bounc in library you can just add a set timeout in a stimulus controller and can\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:21\"\n                                  },\n                                  \"trackingParams\": \"CBUQ0_YHGJECIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 21 seconds don't always need to import a like de bounc in library you can just add a set timeout in a stimulus controller and can\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1761120.1768120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1768120\",\n                                  \"endMs\": \"1773440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"be enough for your use casee um yeah so here is an example where I added this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:28\"\n                                  },\n                                  \"trackingParams\": \"CBQQ0_YHGJICIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 28 seconds be enough for your use casee um yeah so here is an example where I added this\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1768120.1773440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1773440\",\n                                  \"endMs\": \"1779120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"debounce controller and when I start typing nothing happens but uh uh 500\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:33\"\n                                  },\n                                  \"trackingParams\": \"CBMQ0_YHGJMCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 33 seconds debounce controller and when I start typing nothing happens but uh uh 500\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1773440.1779120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1779120\",\n                                  \"endMs\": \"1785559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"milliseconds after I stop typing the request is submitted uh yeah another example would\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:39\"\n                                  },\n                                  \"trackingParams\": \"CBIQ0_YHGJQCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 39 seconds milliseconds after I stop typing the request is submitted uh yeah another example would\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1779120.1785559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1785559\",\n                                  \"endMs\": \"1792480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"be resetting a form so here is a kind of buggy looking Behavior where you see I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:45\"\n                                  },\n                                  \"trackingParams\": \"CBEQ0_YHGJUCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 45 seconds be resetting a form so here is a kind of buggy looking Behavior where you see I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1785559.1792480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1792480\",\n                                  \"endMs\": \"1798840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"put something in into a search form and when I click refresh the page you see the form gets get like repopulated once\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:52\"\n                                  },\n                                  \"trackingParams\": \"CBAQ0_YHGJYCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 52 seconds put something in into a search form and when I click refresh the page you see the form gets get like repopulated once\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1792480.1798840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1798840\",\n                                  \"endMs\": \"1805480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"again so I would add this uh uh stimulus controller to reset the form uh other\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:58\"\n                                  },\n                                  \"trackingParams\": \"CA8Q0_YHGJcCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 58 seconds again so I would add this uh uh stimulus controller to reset the form uh other\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1798840.1805480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1805480\",\n                                  \"endMs\": \"1813039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"examples would be like for select all checkboxes so or like for adding tabs so here like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:05\"\n                                  },\n                                  \"trackingParams\": \"CA4Q0_YHGJgCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 5 seconds examples would be like for select all checkboxes so or like for adding tabs so here like\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1805480.1813039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1813039\",\n                                  \"endMs\": \"1819960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"tabs uh another example would be for hot keys so like click control K to open search or something else and July could\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:13\"\n                                  },\n                                  \"trackingParams\": \"CA0Q0_YHGJkCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 13 seconds tabs uh another example would be for hot keys so like click control K to open search or something else and July could\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1813039.1819960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1819960\",\n                                  \"endMs\": \"1826600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"keep going on but I really encourage you to try hot fire it's really a very satisfying developer experience and it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:19\"\n                                  },\n                                  \"trackingParams\": \"CAwQ0_YHGJoCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 19 seconds keep going on but I really encourage you to try hot fire it's really a very satisfying developer experience and it\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1819960.1826600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1826600\",\n                                  \"endMs\": \"1833279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"fixs perfectly well into the mindset of a backand ruby developer and uh feel\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:26\"\n                                  },\n                                  \"trackingParams\": \"CAsQ0_YHGJsCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 26 seconds fixs perfectly well into the mindset of a backand ruby developer and uh feel\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1826600.1833279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1833279\",\n                                  \"endMs\": \"1841360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"free to check out the videos they will help you go through uh and code Al each of the examples I just mentioned but I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:33\"\n                                  },\n                                  \"trackingParams\": \"CAoQ0_YHGJwCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 33 seconds free to check out the videos they will help you go through uh and code Al each of the examples I just mentioned but I\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1833279.1841360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1841360\",\n                                  \"endMs\": \"1847039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"mean who knows maybe you don't need hot wire some people say you don't you can just use Jake\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:41\"\n                                  },\n                                  \"trackingParams\": \"CAkQ0_YHGJ0CIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 41 seconds mean who knows maybe you don't need hot wire some people say you don't you can just use Jake\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1841360.1847039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1847039\",\n                                  \"endMs\": \"1853120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Fury yeah I'm done thanks allot for being with me and uh let's uh talk\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:47\"\n                                  },\n                                  \"trackingParams\": \"CAgQ0_YHGJ4CIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 47 seconds Fury yeah I'm done thanks allot for being with me and uh let's uh talk\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1847039.1853120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1853120\",\n                                  \"endMs\": \"1858750\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"[Applause] later\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:53\"\n                                  },\n                                  \"trackingParams\": \"CAcQ0_YHGJ8CIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 53 seconds [Applause] later\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1853120.1858750\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1858750\",\n                                  \"endMs\": \"1863780\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"[Music]\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:58\"\n                                  },\n                                  \"trackingParams\": \"CAYQ0_YHGKACIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 58 seconds [Music]\"\n                                    }\n                                  },\n                                  \"targetId\": \"F75k4Oc6g9Q.CgNhc3ISAmVu.1858750.1863780\"\n                                }\n                              }\n                            ],\n                            \"noResultLabel\": {\n                              \"runs\": [\n                                {\n                                  \"text\": \"No results found\"\n                                }\n                              ]\n                            },\n                            \"retryLabel\": {\n                              \"runs\": [\n                                {\n                                  \"text\": \"TAP TO RETRY\"\n                                }\n                              ]\n                            },\n                            \"touchCaptionsEnabled\": false\n                          }\n                        },\n                        \"footer\": {\n                          \"transcriptFooterRenderer\": {\n                            \"languageMenu\": {\n                              \"sortFilterSubMenuRenderer\": {\n                                \"subMenuItems\": [\n                                  {\n                                    \"title\": \"English (auto-generated)\",\n                                    \"selected\": true,\n                                    \"continuation\": {\n                                      \"reloadContinuationData\": {\n                                        \"continuation\": \"CgtGNzVrNE9jNmc5URISQ2dOaGMzSVNBbVZ1R2dBJTNEGAEqM2VuZ2FnZW1lbnQtcGFuZWwtc2VhcmNoYWJsZS10cmFuc2NyaXB0LXNlYXJjaC1wYW5lbDAAOABAAA%3D%3D\",\n                                        \"clickTrackingParams\": \"CAUQxqYCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\"\n                                      }\n                                    },\n                                    \"trackingParams\": \"CAQQ48AHGAAiEwiyg6jFxoKLAxWw8U8IHUwkBlk=\"\n                                  }\n                                ],\n                                \"trackingParams\": \"CAMQgdoEIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\"\n                              }\n                            }\n                          }\n                        },\n                        \"trackingParams\": \"CAIQ8bsCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\",\n                        \"targetId\": \"engagement-panel-searchable-transcript-search-panel\"\n                      }\n                    }\n                  }\n                }\n              }\n            }\n          ],\n          \"trackingParams\": \"CAAQw7wCIhMIsoOoxcaCiwMVsPFPCB1MJAZZ\"\n        }\n  recorded_at: Sun, 19 Jan 2025 19:47:07 GMT\nrecorded_with: VCR 6.3.1\n"
  },
  {
    "path": "test/vcr_cassettes/youtube/transcript_not_available.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: post\n    uri: https://www.youtube.com/youtubei/v1/get_transcript\n    body:\n      encoding: UTF-8\n      string: '{\"context\":{\"client\":{\"clientName\":\"WEB\",\"clientVersion\":\"2.20240313\"}},\"params\":\"CgtNZDkwY3dubUdjOBIMQ2dOaGMzSVNBbVZ1\"}'\n    headers:\n      Content-Type:\n      - application/json\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Sun, 19 Jan 2025 19:41:26 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: |\n        {\n          \"responseContext\": {\n            \"visitorData\": \"CgtGZnYyQzZpS0UzWSjmqrW8BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgPw%3D%3D\",\n            \"serviceTrackingParams\": [\n              {\n                \"service\": \"CSI\",\n                \"params\": [\n                  {\n                    \"key\": \"c\",\n                    \"value\": \"WEB\"\n                  },\n                  {\n                    \"key\": \"cver\",\n                    \"value\": \"2.20240313\"\n                  },\n                  {\n                    \"key\": \"yt_li\",\n                    \"value\": \"0\"\n                  },\n                  {\n                    \"key\": \"GetVideoTranscript_rid\",\n                    \"value\": \"0x9ebabb1a81028683\"\n                  }\n                ]\n              },\n              {\n                \"service\": \"GFEEDBACK\",\n                \"params\": [\n                  {\n                    \"key\": \"logged_in\",\n                    \"value\": \"0\"\n                  },\n                  {\n                    \"key\": \"e\",\n                    \"value\": \"23804281,23986031,24004644,24077241,24166867,24181174,24241378,24290153,24439361,24453989,24499534,24548629,24566687,24699899,39325854,39326986,39328397,51010235,51017346,51020570,51025415,51037344,51037351,51050361,51053689,51063643,51072748,51091058,51095478,51098299,51111738,51115184,51124104,51141472,51151423,51152050,51157411,51176511,51178316,51178335,51178348,51178355,51183909,51184990,51194137,51204329,51217504,51222382,51222973,51227037,51227774,51228850,51230478,51237842,51239093,51241028,51242448,51248734,51255676,51256074,51256084,51263449,51272458,51274583,51276557,51276565,51281227,51285052,51285717,51287196,51292055,51293343,51294322,51296439,51298020,51299710,51299724,51300176,51300241,51303432,51303667,51303669,51303789,51304155,51305031,51305496,51305839,51306259,51310742,51311027,51311038,51313109,51313767,51313802,51314158,51316748,51318845,51322669,51326932,51327138,51327178,51327613,51327636,51329144,51330194,51331481,51331500,51331531,51331542,51331549,51331552,51331559,51332801,51332896,51333879,51334605,51335366,51335392,51335594,51335646,51335928,51337186,51338524,51340611,51340662,51341214,51341228,51341975,51342857,51343368,51344674,51345629,51346046,51346799,51346806,51346819,51346836,51346851,51346870,51346891,51346902,51347325,51349440,51349880,51351446,51353004,51353231,51353393,51353454,51353498,51353997,51354114,51354569,51355266,51355275,51355291,51355303,51355316,51355335,51355346,51355417,51355679,51355912,51357477,51359169,51360104,51360121,51360134,51360208,51360219,51361727,51361828,51362038,51362071,51362455,51362643,51362674,51362857,51363729,51363734,51363743,51363756,51363765,51363772,51364291,51365460,51365461,51365597,51365987,51366423,51366620,51366864,51366998,51367101,51367487,51367993,51370274,51370738,51370999,51371006,51371270,51371294,51371521,51374438,51375168,51375719,51376330,51376516,51376815,51379274,51380378,51380387,51380394,51380761,51380774,51380785,51380792,51380799,51380810,51380829,51380894,51381276,51381818,51381857,51381972,51381974,51383427,51384304,51384347,51384461,51385023,51385539,51387193\"\n                  },\n                  {\n                    \"key\": \"visitor_data\",\n                    \"value\": \"CgtGZnYyQzZpS0UzWSjmqrW8BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgPw%3D%3D\"\n                  }\n                ]\n              },\n              {\n                \"service\": \"GUIDED_HELP\",\n                \"params\": [\n                  {\n                    \"key\": \"logged_in\",\n                    \"value\": \"0\"\n                  }\n                ]\n              },\n              {\n                \"service\": \"ECATCHER\",\n                \"params\": [\n                  {\n                    \"key\": \"client.version\",\n                    \"value\": \"2.20240530\"\n                  },\n                  {\n                    \"key\": \"client.name\",\n                    \"value\": \"WEB\"\n                  }\n                ]\n              }\n            ],\n            \"mainAppWebResponseContext\": {\n              \"loggedOut\": true,\n              \"trackingParam\": \"kx_fmPxhoPZR-9LxAFFC3bJBEE9CQw4Gkx6LA_6foVTq45Eass0cwhLBwOcCE59TDtslLKPQ-SS\"\n            },\n            \"webResponseContextExtensionData\": {\n              \"hasDecorated\": true\n            }\n          },\n          \"actions\": [\n            {\n              \"clickTrackingParams\": \"CAAQw7wCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n              \"updateEngagementPanelAction\": {\n                \"targetId\": \"engagement-panel-searchable-transcript\",\n                \"content\": {\n                  \"transcriptRenderer\": {\n                    \"trackingParams\": \"CAEQ8bsCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                    \"content\": {\n                      \"transcriptSearchPanelRenderer\": {\n                        \"header\": {\n                          \"transcriptSearchBoxRenderer\": {\n                            \"formattedPlaceholder\": {\n                              \"runs\": [\n                                {\n                                  \"text\": \"Search in video\"\n                                }\n                              ]\n                            },\n                            \"accessibility\": {\n                              \"accessibilityData\": {\n                                \"label\": \"Search in video\"\n                              }\n                            },\n                            \"clearButton\": {\n                              \"buttonRenderer\": {\n                                \"icon\": {\n                                  \"iconType\": \"CLOSE\"\n                                },\n                                \"trackingParams\": \"CPkDEMngByITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                \"accessibilityData\": {\n                                  \"accessibilityData\": {\n                                    \"label\": \"Clear search query\"\n                                  }\n                                }\n                              }\n                            },\n                            \"onTextChangeCommand\": {\n                              \"clickTrackingParams\": \"CPcDEKvaByITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                              \"commandMetadata\": {\n                                \"webCommandMetadata\": {\n                                  \"sendPost\": true,\n                                  \"apiUrl\": \"/youtubei/v1/get_transcript\"\n                                }\n                              },\n                              \"getTranscriptEndpoint\": {\n                                \"params\": \"CgtNZDkwY3dubUdjOBIMQ2dOaGMzSVNBbVZ1GAEqM2VuZ2FnZW1lbnQtcGFuZWwtc2VhcmNoYWJsZS10cmFuc2NyaXB0LXNlYXJjaC1wYW5lbDAAOABAAA%3D%3D\"\n                              }\n                            },\n                            \"trackingParams\": \"CPcDEKvaByITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                            \"searchButton\": {\n                              \"buttonRenderer\": {\n                                \"trackingParams\": \"CPgDEIKDCCITCLPBgKPFgosDFZzMTwgdHJkwSg==\"\n                              }\n                            }\n                          }\n                        },\n                        \"body\": {\n                          \"transcriptSegmentListRenderer\": {\n                            \"initialSegments\": [\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"160\",\n                                  \"endMs\": \"6520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"doing it okay cool everybody yeah Casper um let's see where we want to start here I figured we'd just keep it fairly loose\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:00\"\n                                  },\n                                  \"trackingParams\": \"CPYDENP2BxgAIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"0 seconds doing it okay cool everybody yeah Casper um let's see where we want to start here I figured we'd just keep it fairly loose\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.160.6520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"6520\",\n                                  \"endMs\": \"13200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and informal since it's a little bit of a smaller it yeah exactly I like what you did with it to it is just let's just uh see kind of we get to it and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:06\"\n                                  },\n                                  \"trackingParams\": \"CPUDENP2BxgBIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 seconds and informal since it's a little bit of a smaller it yeah exactly I like what you did with it to it is just let's just uh see kind of we get to it and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.6520.13200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"13200\",\n                                  \"endMs\": \"18880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we'll sort of figure it out as we go um so I think it was interesting because I didn't know what R was going to talk\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:13\"\n                                  },\n                                  \"trackingParams\": \"CPQDENP2BxgCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 seconds we'll sort of figure it out as we go um so I think it was interesting because I didn't know what R was going to talk\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.13200.18880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"18880\",\n                                  \"endMs\": \"25560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"about at first but it seems like it might actually segue quite a lot with what it is I'm talking about so that was kind of interesting um but basically\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:18\"\n                                  },\n                                  \"trackingParams\": \"CPMDENP2BxgDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 seconds about at first but it seems like it might actually segue quite a lot with what it is I'm talking about so that was kind of interesting um but basically\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.18880.25560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"25560\",\n                                  \"endMs\": \"33079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what I've been exploring is something similar to what R was talking about with finding some potentially missing parts in rails or just exploring some ideas\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:25\"\n                                  },\n                                  \"trackingParams\": \"CPIDENP2BxgEIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 seconds what I've been exploring is something similar to what R was talking about with finding some potentially missing parts in rails or just exploring some ideas\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.25560.33079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"33079\",\n                                  \"endMs\": \"38399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and putting them into gems so I got two things we're going to try to look at today one is a little bit larger that's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:33\"\n                                  },\n                                  \"trackingParams\": \"CPEDENP2BxgFIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 seconds and putting them into gems so I got two things we're going to try to look at today one is a little bit larger that's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.33079.38399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"38399\",\n                                  \"endMs\": \"43920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a little bit for later um and then some use cases that people are starting to use it and applying it a little bit so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:38\"\n                                  },\n                                  \"trackingParams\": \"CPADENP2BxgGIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 seconds a little bit for later um and then some use cases that people are starting to use it and applying it a little bit so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.38399.43920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"43920\",\n                                  \"endMs\": \"50120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that's sort of the overall gist of it cool okay yeah okay all right cool um so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:43\"\n                                  },\n                                  \"trackingParams\": \"CO8DENP2BxgHIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 seconds that's sort of the overall gist of it cool okay yeah okay all right cool um so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.43920.50120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"50120\",\n                                  \"endMs\": \"56359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the first one is called act Associated object let's see is this is this fun okay let's maybe we should do this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:50\"\n                                  },\n                                  \"trackingParams\": \"CO4DENP2BxgIIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 seconds the first one is called act Associated object let's see is this is this fun okay let's maybe we should do this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.50120.56359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"56359\",\n                                  \"endMs\": \"64119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"actually and then bump it up a little bit little better okay cool um so usually when people are\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:56\"\n                                  },\n                                  \"trackingParams\": \"CO0DENP2BxgJIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"56 seconds actually and then bump it up a little bit little better okay cool um so usually when people are\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.56359.64119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"64119\",\n                                  \"endMs\": \"69600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"trying to organize the real apps it's either like doing a bunch of service objects and I'm not necessarily saying\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:04\"\n                                  },\n                                  \"trackingParams\": \"COwDENP2BxgKIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 4 seconds trying to organize the real apps it's either like doing a bunch of service objects and I'm not necessarily saying\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.64119.69600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"69600\",\n                                  \"endMs\": \"77479\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that this is a replacement for any of that it's kind of a complimentary thing um but I had this idea to we're going to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:09\"\n                                  },\n                                  \"trackingParams\": \"COsDENP2BxgLIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 9 seconds that this is a replacement for any of that it's kind of a complimentary thing um but I had this idea to we're going to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.69600.77479\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"77479\",\n                                  \"endMs\": \"83200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"help some code at some point let's see when we want to do that um but basically\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:17\"\n                                  },\n                                  \"trackingParams\": \"COoDENP2BxgMIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 17 seconds help some code at some point let's see when we want to do that um but basically\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.77479.83200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"83200\",\n                                  \"endMs\": \"88640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the idea was to see if there's a gap where because I feel like there's so much talk about what server servies are\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:23\"\n                                  },\n                                  \"trackingParams\": \"COkDENP2BxgNIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 23 seconds the idea was to see if there's a gap where because I feel like there's so much talk about what server servies are\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.83200.88640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"88640\",\n                                  \"endMs\": \"95040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and what they look like and so forth and I I just felt like there was a need for well I had an idea that I wanted to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:28\"\n                                  },\n                                  \"trackingParams\": \"COgDENP2BxgOIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 28 seconds and what they look like and so forth and I I just felt like there was a need for well I had an idea that I wanted to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.88640.95040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"95040\",\n                                  \"endMs\": \"100280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"see if I could do something a little bit different that I hadn't seen quite before and it's still complimentary um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:35\"\n                                  },\n                                  \"trackingParams\": \"COcDENP2BxgPIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 35 seconds see if I could do something a little bit different that I hadn't seen quite before and it's still complimentary um\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.95040.100280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"100280\",\n                                  \"endMs\": \"106240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"basically the idea was to to to sort of find some language that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:40\"\n                                  },\n                                  \"trackingParams\": \"COYDENP2BxgQIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 40 seconds basically the idea was to to to sort of find some language that\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.100280.106240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"106240\",\n                                  \"endMs\": \"111399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"would make it easier for people to sort of spot collaborator Optics within their active records so so all the logic\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:46\"\n                                  },\n                                  \"trackingParams\": \"COUDENP2BxgRIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 46 seconds would make it easier for people to sort of spot collaborator Optics within their active records so so all the logic\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.106240.111399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"111399\",\n                                  \"endMs\": \"117079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"wouldn't just pull there so for instance Garrett uh who's working on flipper he's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:51\"\n                                  },\n                                  \"trackingParams\": \"COQDENP2BxgSIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 51 seconds wouldn't just pull there so for instance Garrett uh who's working on flipper he's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.111399.117079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"117079\",\n                                  \"endMs\": \"122159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"been using this uh theyve just rebuilt their like um they did a whole billing update let's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:57\"\n                                  },\n                                  \"trackingParams\": \"COMDENP2BxgTIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 57 seconds been using this uh theyve just rebuilt their like um they did a whole billing update let's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.117079.122159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"122159\",\n                                  \"endMs\": \"128039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"see oh this maybe also needs to be bumped up a little bit okay um but\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:02\"\n                                  },\n                                  \"trackingParams\": \"COIDENP2BxgUIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 2 seconds see oh this maybe also needs to be bumped up a little bit okay um but\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.122159.128039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"128039\",\n                                  \"endMs\": \"133239\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"basically so he's quoting here to re me that I'm sort of talking about uh where typically rail applications get end up\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:08\"\n                                  },\n                                  \"trackingParams\": \"COEDENP2BxgVIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 8 seconds basically so he's quoting here to re me that I'm sort of talking about uh where typically rail applications get end up\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.128039.133239\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"133239\",\n                                  \"endMs\": \"139080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"with models that get way too big and so far the response has been sort of service object solely but sometimes then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:13\"\n                                  },\n                                  \"trackingParams\": \"COADENP2BxgWIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 13 seconds with models that get way too big and so far the response has been sort of service object solely but sometimes then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.133239.139080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"139080\",\n                                  \"endMs\": \"146000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you can have an app services and and it can also turn into another junk drawer that doesn't necessarily help you build and make concepts for a domain model so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:19\"\n                                  },\n                                  \"trackingParams\": \"CN8DENP2BxgXIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 19 seconds you can have an app services and and it can also turn into another junk drawer that doesn't necessarily help you build and make concepts for a domain model so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.139080.146000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"146000\",\n                                  \"endMs\": \"152800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in this Library I'm trying to take that part head on where these Associated objects are kind of a new domain concept\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:26\"\n                                  },\n                                  \"trackingParams\": \"CN4DENP2BxgYIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 26 seconds in this Library I'm trying to take that part head on where these Associated objects are kind of a new domain concept\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.146000.152800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"152800\",\n                                  \"endMs\": \"159239\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's kind of a context object similar to what R was showing with both the form objects and so forth and career objects and all that stuff um and it's sort of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:32\"\n                                  },\n                                  \"trackingParams\": \"CN0DENP2BxgZIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 32 seconds it's kind of a context object similar to what R was showing with both the form objects and so forth and career objects and all that stuff um and it's sort of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.152800.159239\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"159239\",\n                                  \"endMs\": \"164599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"meant to help you tease out these collaborator objects so-called um so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:39\"\n                                  },\n                                  \"trackingParams\": \"CNwDENP2BxgaIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 39 seconds meant to help you tease out these collaborator objects so-called um so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.159239.164599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"164599\",\n                                  \"endMs\": \"170760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"fliver has been using it for their they're doing this like prse and then they rewrote their whole billing engine and whatnot so it's kind of easier to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:44\"\n                                  },\n                                  \"trackingParams\": \"CNsDENP2BxgbIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 44 seconds fliver has been using it for their they're doing this like prse and then they rewrote their whole billing engine and whatnot so it's kind of easier to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.164599.170760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"170760\",\n                                  \"endMs\": \"175879\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"see once we yeah Garrett has a whole bunch of uh videos forward it is so he was actually doing something kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:50\"\n                                  },\n                                  \"trackingParams\": \"CNoDENP2BxgcIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 50 seconds see once we yeah Garrett has a whole bunch of uh videos forward it is so he was actually doing something kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.170760.175879\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"175879\",\n                                  \"endMs\": \"181200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"similar to what the library ends up cleaning up a little bit where he would have you know an account model and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:55\"\n                                  },\n                                  \"trackingParams\": \"CNkDENP2BxgdIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 55 seconds similar to what the library ends up cleaning up a little bit where he would have you know an account model and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.175879.181200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"181200\",\n                                  \"endMs\": \"188080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it would have these poros essentially that he would then inject self into so the account would be passed in and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:01\"\n                                  },\n                                  \"trackingParams\": \"CNgDENP2BxgeIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 1 second it would have these poros essentially that he would then inject self into so the account would be passed in and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.181200.188080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"188080\",\n                                  \"endMs\": \"194480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you would have a nested record in here as well and then you would take the account and you can do stuff with that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:08\"\n                                  },\n                                  \"trackingParams\": \"CNcDENP2BxgfIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 8 seconds you would have a nested record in here as well and then you would take the account and you can do stuff with that\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.188080.194480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"194480\",\n                                  \"endMs\": \"201120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"essentially for for calculating some related to seats in this case for their building stuff um and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:14\"\n                                  },\n                                  \"trackingParams\": \"CNYDENP2BxggIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 14 seconds essentially for for calculating some related to seats in this case for their building stuff um and\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.194480.201120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"201120\",\n                                  \"endMs\": \"207360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so my gem was sort of something I did like two years ago um but it kind of mirrors some of this stuff where instead\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:21\"\n                                  },\n                                  \"trackingParams\": \"CNUDENP2BxghIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 21 seconds so my gem was sort of something I did like two years ago um but it kind of mirrors some of this stuff where instead\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.201120.207360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"207360\",\n                                  \"endMs\": \"215400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"now you can have an an like a has object declaration and you just inherit from this act Associated object um and so the idea is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:27\"\n                                  },\n                                  \"trackingParams\": \"CNQDENP2BxgiIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 27 seconds now you can have an an like a has object declaration and you just inherit from this act Associated object um and so the idea is\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.207360.215400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"215400\",\n                                  \"endMs\": \"220959\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that you're starting to have a new name once you start knowing what these things\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:35\"\n                                  },\n                                  \"trackingParams\": \"CNMDENP2BxgjIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 35 seconds that you're starting to have a new name once you start knowing what these things\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.215400.220959\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"220959\",\n                                  \"endMs\": \"227640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"kind of look and feel like suddenly it becomes easier for you to decompose new features when you know what this does uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:40\"\n                                  },\n                                  \"trackingParams\": \"CNIDENP2BxgkIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 40 seconds kind of look and feel like suddenly it becomes easier for you to decompose new features when you know what this does uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.220959.227640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"227640\",\n                                  \"endMs\": \"233799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"let's see it a little bit more so it's ultimately it's meant to feel rails likee so it's like almost feel like it's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:47\"\n                                  },\n                                  \"trackingParams\": \"CNEDENP2BxglIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 47 seconds let's see it a little bit more so it's ultimately it's meant to feel rails likee so it's like almost feel like it's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.227640.233799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"233799\",\n                                  \"endMs\": \"240200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"built in already and mirrors a little bit of what has one and has many does where you just have this extra way to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:53\"\n                                  },\n                                  \"trackingParams\": \"CNADENP2BxgmIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 53 seconds built in already and mirrors a little bit of what has one and has many does where you just have this extra way to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.233799.240200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"240200\",\n                                  \"endMs\": \"247239\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like side car or or extract certain logic so it's not all grouped into the same model\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:00\"\n                                  },\n                                  \"trackingParams\": \"CM8DENP2BxgnIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes like side car or or extract certain logic so it's not all grouped into the same model\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.240200.247239\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"247239\",\n                                  \"endMs\": \"253239\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um cool let's see I want to jump into a little bit more and then it's a bunch of automatic stuff but that's see so once\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:07\"\n                                  },\n                                  \"trackingParams\": \"CM4DENP2BxgoIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 7 seconds um cool let's see I want to jump into a little bit more and then it's a bunch of automatic stuff but that's see so once\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.247239.253239\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"253239\",\n                                  \"endMs\": \"259040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we get into what the code looks like I just wanted to show Yeah so basically Garrett used to have stuff like this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:13\"\n                                  },\n                                  \"trackingParams\": \"CM0DENP2BxgpIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 13 seconds we get into what the code looks like I just wanted to show Yeah so basically Garrett used to have stuff like this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.253239.259040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"259040\",\n                                  \"endMs\": \"265000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"where they have these trial expired and so forth but now you can group it around a specific model or basically just porro\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:19\"\n                                  },\n                                  \"trackingParams\": \"CMwDENP2BxgqIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 19 seconds where they have these trial expired and so forth but now you can group it around a specific model or basically just porro\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.259040.265000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"265000\",\n                                  \"endMs\": \"271000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"object that can in group some of that functionality let's see I think he's showing a little bit what it actually looks like same thing with these seats\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:25\"\n                                  },\n                                  \"trackingParams\": \"CMsDENP2BxgrIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 25 seconds object that can in group some of that functionality let's see I think he's showing a little bit what it actually looks like same thing with these seats\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.265000.271000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"271000\",\n                                  \"endMs\": \"276560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"again again all this pricing stuff they also had a bunch of stuff that's that's now grouped into one object instead of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:31\"\n                                  },\n                                  \"trackingParams\": \"CMoDENP2BxgsIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 31 seconds again again all this pricing stuff they also had a bunch of stuff that's that's now grouped into one object instead of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.271000.276560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"276560\",\n                                  \"endMs\": \"282880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"being all on the account uh let's see he's finding okay I don't think it was in here then but I'll\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:36\"\n                                  },\n                                  \"trackingParams\": \"CMkDENP2BxgtIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 36 seconds being all on the account uh let's see he's finding okay I don't think it was in here then but I'll\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.276560.282880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"282880\",\n                                  \"endMs\": \"288800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"show some other stuff then let's see do I want to go to this or this okay let's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:42\"\n                                  },\n                                  \"trackingParams\": \"CMgDENP2BxguIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 42 seconds show some other stuff then let's see do I want to go to this or this okay let's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.282880.288800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"288800\",\n                                  \"endMs\": \"294479\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"go to some of the source code where I've written some stuff so basically what I'm trying to show here\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:48\"\n                                  },\n                                  \"trackingParams\": \"CMcDENP2BxgvIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 48 seconds go to some of the source code where I've written some stuff so basically what I'm trying to show here\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.288800.294479\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"294479\",\n                                  \"endMs\": \"300160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"is the idea I had was since you can do let's do the J Code part actually let's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:54\"\n                                  },\n                                  \"trackingParams\": \"CMYDENP2BxgwIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 54 seconds is the idea I had was since you can do let's do the J Code part actually let's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.294479.300160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"300160\",\n                                  \"endMs\": \"307120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"jump am I oh it's because it's yeah okay uh do that and then do this I think\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:00\"\n                                  },\n                                  \"trackingParams\": \"CMUDENP2BxgxIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes jump am I oh it's because it's yeah okay uh do that and then do this I think\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.300160.307120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"307120\",\n                                  \"endMs\": \"312280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so basically what I was thinking of when I was writing this was since you can do this kind of stuff with actor record\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:07\"\n                                  },\n                                  \"trackingParams\": \"CMQDENP2BxgyIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 7 seconds so basically what I was thinking of when I was writing this was since you can do this kind of stuff with actor record\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.307120.312280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"312280\",\n                                  \"endMs\": \"318880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"where you can then do post. fine with an ID and then get a post back I was kind of thinking what if you could do like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:12\"\n                                  },\n                                  \"trackingParams\": \"CMMDENP2BxgzIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 12 seconds where you can then do post. fine with an ID and then get a post back I was kind of thinking what if you could do like\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.312280.318880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"318880\",\n                                  \"endMs\": \"325479\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"something like this where you then put in a porro instead so this is like a this would just be an object that's not\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:18\"\n                                  },\n                                  \"trackingParams\": \"CMIDENP2Bxg0IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 18 seconds something like this where you then put in a porro instead so this is like a this would just be an object that's not\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.318880.325479\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"325479\",\n                                  \"endMs\": \"330560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"stored in a database but because it's nested within this act record name space\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:25\"\n                                  },\n                                  \"trackingParams\": \"CMEDENP2Bxg1IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 25 seconds stored in a database but because it's nested within this act record name space\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.325479.330560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"330560\",\n                                  \"endMs\": \"337880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you could actually find it in a database um and then you could do some interesting stuff with that so for instance when you do something like a an\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:30\"\n                                  },\n                                  \"trackingParams\": \"CMADENP2Bxg2IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 30 seconds you could actually find it in a database um and then you could do some interesting stuff with that so for instance when you do something like a an\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.330560.337880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"337880\",\n                                  \"endMs\": \"344720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"active job thing where you then put in the post what it'll do in the background is actually call to Global ID and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:37\"\n                                  },\n                                  \"trackingParams\": \"CL8DENP2Bxg3IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 37 seconds active job thing where you then put in the post what it'll do in the background is actually call to Global ID and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.337880.344720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"344720\",\n                                  \"endMs\": \"350199\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that will serialize into I think it looks sort of like this where it has a an app something and then a post and it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:44\"\n                                  },\n                                  \"trackingParams\": \"CL4DENP2Bxg4IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 44 seconds that will serialize into I think it looks sort of like this where it has a an app something and then a post and it\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.344720.350199\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"350199\",\n                                  \"endMs\": \"355240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"has the ID but then this post publisher\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:50\"\n                                  },\n                                  \"trackingParams\": \"CL0DENP2Bxg5IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 50 seconds has the ID but then this post publisher\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.350199.355240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"355240\",\n                                  \"endMs\": \"362360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"poro could actually do similar where we could just do the same namespace and then it could\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:55\"\n                                  },\n                                  \"trackingParams\": \"CLwDENP2Bxg6IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 55 seconds poro could actually do similar where we could just do the same namespace and then it could\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.355240.362360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"362360\",\n                                  \"endMs\": \"368639\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"also be found so we could pass a porro directly to a job for instance so that was sort of the de initial G of the idea\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:02\"\n                                  },\n                                  \"trackingParams\": \"CLsDENP2Bxg7IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 2 seconds also be found so we could pass a porro directly to a job for instance so that was sort of the de initial G of the idea\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.362360.368639\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"368639\",\n                                  \"endMs\": \"374280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"just to see if that would make sense and what that may unlock later down the line\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:08\"\n                                  },\n                                  \"trackingParams\": \"CLoDENP2Bxg8IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 8 seconds just to see if that would make sense and what that may unlock later down the line\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.368639.374280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"374280\",\n                                  \"endMs\": \"381120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so yeah so so the primary thing was that name spacing so you get a little bit more organization out of the box um and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:14\"\n                                  },\n                                  \"trackingParams\": \"CLkDENP2Bxg9IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 14 seconds so yeah so so the primary thing was that name spacing so you get a little bit more organization out of the box um and\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.374280.381120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"381120\",\n                                  \"endMs\": \"386800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then some of these extra features kind of to to see what that would look like let see do we want to jump into the I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:21\"\n                                  },\n                                  \"trackingParams\": \"CLgDENP2Bxg-IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 21 seconds then some of these extra features kind of to to see what that would look like let see do we want to jump into the I\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.381120.386800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"386800\",\n                                  \"endMs\": \"393919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"think I kind of like it more in the browser hold on where we at uh here so yeah you make that has object\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:26\"\n                                  },\n                                  \"trackingParams\": \"CLcDENP2Bxg_IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 26 seconds think I kind of like it more in the browser hold on where we at uh here so yeah you make that has object\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.386800.393919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"393919\",\n                                  \"endMs\": \"401919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"declaration and then you can you must namespace it so just would be app models post SL publisher um and then there's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:33\"\n                                  },\n                                  \"trackingParams\": \"CLYDENP2BxhAIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 33 seconds declaration and then you can you must namespace it so just would be app models post SL publisher um and then there's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.393919.401919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"401919\",\n                                  \"endMs\": \"407599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"some some tricky bits internally for how it actually is like set up because there's modern versions of Ruby has this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:41\"\n                                  },\n                                  \"trackingParams\": \"CLUDENP2BxhBIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 41 seconds some some tricky bits internally for how it actually is like set up because there's modern versions of Ruby has this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.401919.407599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"407599\",\n                                  \"endMs\": \"412840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"thing called object shapes which is some when you initialize an instance variable\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:47\"\n                                  },\n                                  \"trackingParams\": \"CLQDENP2BxhCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 47 seconds thing called object shapes which is some when you initialize an instance variable\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.407599.412840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"412840\",\n                                  \"endMs\": \"417919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in a different order you create a new object shape internally so it ends up consuming more memory so you have to be\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:52\"\n                                  },\n                                  \"trackingParams\": \"CLMDENP2BxhDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 52 seconds in a different order you create a new object shape internally so it ends up consuming more memory so you have to be\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.412840.417919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"417919\",\n                                  \"endMs\": \"423759\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"careful now when you assign a new instance variable because they're order dependent so we we're doing this thing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:57\"\n                                  },\n                                  \"trackingParams\": \"CLIDENP2BxhEIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 57 seconds careful now when you assign a new instance variable because they're order dependent so we we're doing this thing\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.417919.423759\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"423759\",\n                                  \"endMs\": \"431080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"where we basically have a hash internal that we didn't set somewhere so that's the reason for that um let's see what\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:03\"\n                                  },\n                                  \"trackingParams\": \"CLEDENP2BxhFIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 3 seconds where we basically have a hash internal that we didn't set somewhere so that's the reason for that um let's see what\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.423759.431080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"431080\",\n                                  \"endMs\": \"436360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"else and then once you have to use Optics you can also there's some light syntactic Sher involved where you can\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:11\"\n                                  },\n                                  \"trackingParams\": \"CLADENP2BxhGIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 11 seconds else and then once you have to use Optics you can also there's some light syntactic Sher involved where you can\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.431080.436360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"436360\",\n                                  \"endMs\": \"441479\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then do a transaction but that just delegates to the post but so in this case because we're nesting with on the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:16\"\n                                  },\n                                  \"trackingParams\": \"CK8DENP2BxhHIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 16 seconds then do a transaction but that just delegates to the post but so in this case because we're nesting with on the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.436360.441479\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"441479\",\n                                  \"endMs\": \"446879\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"post we have access to a local post method essentially so you can then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:21\"\n                                  },\n                                  \"trackingParams\": \"CK4DENP2BxhIIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 21 seconds post we have access to a local post method essentially so you can then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.441479.446879\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"446879\",\n                                  \"endMs\": \"454360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"interact with the object and hopefully that clarifies how this extra more scoped uh domain concept is interacting\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:26\"\n                                  },\n                                  \"trackingParams\": \"CK0DENP2BxhJIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 26 seconds interact with the object and hopefully that clarifies how this extra more scoped uh domain concept is interacting\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.446879.454360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"454360\",\n                                  \"endMs\": \"460599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"with the parent model essentially um let's see and then again I'm mentioning flipper here this is the article we just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:34\"\n                                  },\n                                  \"trackingParams\": \"CKwDENP2BxhKIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 34 seconds with the parent model essentially um let's see and then again I'm mentioning flipper here this is the article we just\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.454360.460599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"460599\",\n                                  \"endMs\": \"466879\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"looked at and they have another one for that stuff uh have our generator as well here's some more Advance stuff where I'm\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:40\"\n                                  },\n                                  \"trackingParams\": \"CKsDENP2BxhLIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 40 seconds looked at and they have another one for that stuff uh have our generator as well here's some more Advance stuff where I'm\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.460599.466879\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"466879\",\n                                  \"endMs\": \"474639\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"not necessarily making a comment on whether other people should use callbacks or not it was just like this is fairly easy to to relay callbacks\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:46\"\n                                  },\n                                  \"trackingParams\": \"CKoDENP2BxhMIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 46 seconds not necessarily making a comment on whether other people should use callbacks or not it was just like this is fairly easy to to relay callbacks\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.466879.474639\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"474639\",\n                                  \"endMs\": \"480199\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"onto this optic where you could then interact more basically and I thought that was kind of interesting same let's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:54\"\n                                  },\n                                  \"trackingParams\": \"CKkDENP2BxhNIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 54 seconds onto this optic where you could then interact more basically and I thought that was kind of interesting same let's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.474639.480199\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"480199\",\n                                  \"endMs\": \"487080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"see uh See active record so another feature I was curious to explore was you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:00\"\n                                  },\n                                  \"trackingParams\": \"CKgDENP2BxhOIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes see uh See active record so another feature I was curious to explore was you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.480199.487080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"487080\",\n                                  \"endMs\": \"492199\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"see in this a lot in rails apps at least in some apps where you're making this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:07\"\n                                  },\n                                  \"trackingParams\": \"CKcDENP2BxhPIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 7 seconds see in this a lot in rails apps at least in some apps where you're making this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.487080.492199\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"492199\",\n                                  \"endMs\": \"497360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"concern that you didn't include and you do a bunch of this integration stuff\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:12\"\n                                  },\n                                  \"trackingParams\": \"CKYDENP2BxhQIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 12 seconds concern that you didn't include and you do a bunch of this integration stuff\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.492199.497360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"497360\",\n                                  \"endMs\": \"503199\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"where you have you could still have the Declaration in here but maybe you'd want\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:17\"\n                                  },\n                                  \"trackingParams\": \"CKUDENP2BxhRIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 17 seconds where you have you could still have the Declaration in here but maybe you'd want\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.497360.503199\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"503199\",\n                                  \"endMs\": \"510319\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"some extra methods that interact with that but you want to keep all that scoped into one concern for instance so it's sort of con nested there but if you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:23\"\n                                  },\n                                  \"trackingParams\": \"CKQDENP2BxhSIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 23 seconds some extra methods that interact with that but you want to keep all that scoped into one concern for instance so it's sort of con nested there but if you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.503199.510319\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"510319\",\n                                  \"endMs\": \"517320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"start using these Associated objects suddenly you got the logic split out from both in the concern the wrapping concern and in the associated object\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:30\"\n                                  },\n                                  \"trackingParams\": \"CKMDENP2BxhTIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 30 seconds start using these Associated objects suddenly you got the logic split out from both in the concern the wrapping concern and in the associated object\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.510319.517320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"517320\",\n                                  \"endMs\": \"523200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"which in some ways it's nicer because you you get some of the logic stracted out so it's not just all mingled in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:37\"\n                                  },\n                                  \"trackingParams\": \"CKIDENP2BxhUIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 37 seconds which in some ways it's nicer because you you get some of the logic stracted out so it's not just all mingled in\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.517320.523200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"523200\",\n                                  \"endMs\": \"528240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"together in that one concern so that's not like a huge mess essentially but what we've been trying to explore is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:43\"\n                                  },\n                                  \"trackingParams\": \"CKEDENP2BxhVIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 43 seconds together in that one concern so that's not like a huge mess essentially but what we've been trying to explore is\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.523200.528240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"528240\",\n                                  \"endMs\": \"535440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then what if we then now move the integration part into this class as well so you still just have one file and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:48\"\n                                  },\n                                  \"trackingParams\": \"CKADENP2BxhWIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 48 seconds then what if we then now move the integration part into this class as well so you still just have one file and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.528240.535440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"535440\",\n                                  \"endMs\": \"541720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"when you do where was like when you do this kind of has optic we'll go in background and load this the class\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:55\"\n                                  },\n                                  \"trackingParams\": \"CJ8DENP2BxhXIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 55 seconds when you do where was like when you do this kind of has optic we'll go in background and load this the class\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.535440.541720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"541720\",\n                                  \"endMs\": \"551040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"immediately so we fire this uh block where we can then extend the object itself um so the piece here is kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:01\"\n                                  },\n                                  \"trackingParams\": \"CJ4DENP2BxhYIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 1 second immediately so we fire this uh block where we can then extend the object itself um so the piece here is kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.541720.551040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"551040\",\n                                  \"endMs\": \"558279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this was kind of easy enough to write like this is just a delegation around post. class Evol so it was not super\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:11\"\n                                  },\n                                  \"trackingParams\": \"CJ0DENP2BxhZIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 11 seconds this was kind of easy enough to write like this is just a delegation around post. class Evol so it was not super\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.551040.558279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"558279\",\n                                  \"endMs\": \"563760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"difficult to add this kind of feature and then it's kind of up to people whether or not they want to use it or what not oh yeah I'm also saying it here\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:18\"\n                                  },\n                                  \"trackingParams\": \"CJwDENP2BxhaIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 18 seconds difficult to add this kind of feature and then it's kind of up to people whether or not they want to use it or what not oh yeah I'm also saying it here\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.558279.563760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"563760\",\n                                  \"endMs\": \"569560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"actually I'm calling it out um that it's class Evol so forth so let's see see\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:23\"\n                                  },\n                                  \"trackingParams\": \"CJsDENP2BxhbIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 23 seconds actually I'm calling it out um that it's class Evol so forth so let's see see\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.563760.569560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"569560\",\n                                  \"endMs\": \"575480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what else you want to yeah and then I'm just yeah just mentioning you don't have to know all this stuff of like how to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:29\"\n                                  },\n                                  \"trackingParams\": \"CJoDENP2BxhcIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 29 seconds what else you want to yeah and then I'm just yeah just mentioning you don't have to know all this stuff of like how to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.569560.575480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"575480\",\n                                  \"endMs\": \"582120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"use class methods and like this included to and you have to extend the stuff with with the other verse you can kind of just do it in one go because it's just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:35\"\n                                  },\n                                  \"trackingParams\": \"CJkDENP2BxhdIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 35 seconds use class methods and like this included to and you have to extend the stuff with with the other verse you can kind of just do it in one go because it's just\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.575480.582120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"582120\",\n                                  \"endMs\": \"589079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in the class itself that it's evaluated which makes sense for if you have concerns that are just for one model um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:42\"\n                                  },\n                                  \"trackingParams\": \"CJgDENP2BxheIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 42 seconds in the class itself that it's evaluated which makes sense for if you have concerns that are just for one model um\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.582120.589079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"589079\",\n                                  \"endMs\": \"595279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's a little bit different you want to share between them but so let's see anything else I want to show this read\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:49\"\n                                  },\n                                  \"trackingParams\": \"CJcDENP2BxhfIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 49 seconds it's a little bit different you want to share between them but so let's see anything else I want to show this read\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.589079.595279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"595279\",\n                                  \"endMs\": \"601880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"me here some people that have been using it h let's see testing it and testing can also be split out into the separate\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:55\"\n                                  },\n                                  \"trackingParams\": \"CJYDENP2BxhgIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 55 seconds me here some people that have been using it h let's see testing it and testing can also be split out into the separate\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.595279.601880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"601880\",\n                                  \"endMs\": \"608839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"file then where you're then still relying on that parad actor record but then you can still get at this like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:01\"\n                                  },\n                                  \"trackingParams\": \"CJUDENP2BxhhIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 1 second file then where you're then still relying on that parad actor record but then you can still get at this like\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.601880.608839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"608839\",\n                                  \"endMs\": \"614200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Associated object essentially and here's the uh what I was talking about with the um Global ID integration which is how\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:08\"\n                                  },\n                                  \"trackingParams\": \"CJQDENP2BxhiIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 8 seconds Associated object essentially and here's the uh what I was talking about with the um Global ID integration which is how\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.608839.614200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"614200\",\n                                  \"endMs\": \"621399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"active job both serializes objects and finds them again for jobs and then we can pass in a por essentially because\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:14\"\n                                  },\n                                  \"trackingParams\": \"CJMDENP2BxhjIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 14 seconds active job both serializes objects and finds them again for jobs and then we can pass in a por essentially because\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.614200.621399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"621399\",\n                                  \"endMs\": \"628200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's not stored in a database it's just connected to that via that namespace and reusing the same ID essentially to be\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:21\"\n                                  },\n                                  \"trackingParams\": \"CJIDENP2BxhkIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 21 seconds it's not stored in a database it's just connected to that via that namespace and reusing the same ID essentially to be\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.621399.628200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"628200\",\n                                  \"endMs\": \"633920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"considered unique um let's see what else do you want to show here and there's some more stuff\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:28\"\n                                  },\n                                  \"trackingParams\": \"CJEDENP2BxhlIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 28 seconds considered unique um let's see what else do you want to show here and there's some more stuff\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.628200.633920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"633920\",\n                                  \"endMs\": \"640160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"but that's kind of for later spare some writing and then I'm I'm kind of using the same thing to get an extra basically\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:33\"\n                                  },\n                                  \"trackingParams\": \"CJADENP2BxhmIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 33 seconds but that's kind of for later spare some writing and then I'm I'm kind of using the same thing to get an extra basically\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.633920.640160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"640160\",\n                                  \"endMs\": \"645839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what I'm trying to do with this stuff too is also once you start following this pattern I want I kind of want to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:40\"\n                                  },\n                                  \"trackingParams\": \"CI8DENP2BxhnIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 40 seconds what I'm trying to do with this stuff too is also once you start following this pattern I want I kind of want to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.640160.645839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"645839\",\n                                  \"endMs\": \"651560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"have more bang for my buck if I'm if I'm using a pattern where then by just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:45\"\n                                  },\n                                  \"trackingParams\": \"CI4DENP2BxhoIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 45 seconds have more bang for my buck if I'm if I'm using a pattern where then by just\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.645839.651560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"651560\",\n                                  \"endMs\": \"657440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"following this kind of convention suddenly I get some extra features out of the box which in this case could be something like credis here which credit\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:51\"\n                                  },\n                                  \"trackingParams\": \"CI0DENP2BxhpIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 51 seconds following this kind of convention suddenly I get some extra features out of the box which in this case could be something like credis here which credit\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.651560.657440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"657440\",\n                                  \"endMs\": \"663120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"was a thing I wrote um extracted from a job I had where we're using reddis to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:57\"\n                                  },\n                                  \"trackingParams\": \"CIwDENP2BxhqIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 57 seconds was a thing I wrote um extracted from a job I had where we're using reddis to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.657440.663120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"663120\",\n                                  \"endMs\": \"669519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"store some some kind of Emeral data in a way and then there's some logic that started to show up where that was kind\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:03\"\n                                  },\n                                  \"trackingParams\": \"CIsDENP2BxhrIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 3 seconds store some some kind of Emeral data in a way and then there's some logic that started to show up where that was kind\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.663120.669519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"669519\",\n                                  \"endMs\": \"677279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of uh coming together in a way that was like these specific types in there uh but then this works credit Works off of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:09\"\n                                  },\n                                  \"trackingParams\": \"CIoDENP2BxhsIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 9 seconds of uh coming together in a way that was like these specific types in there uh but then this works credit Works off of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.669519.677279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"677279\",\n                                  \"endMs\": \"683000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"also some keys essentially so I'm kind of using the same ID trick to also\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:17\"\n                                  },\n                                  \"trackingParams\": \"CIkDENP2BxhtIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 17 seconds also some keys essentially so I'm kind of using the same ID trick to also\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.677279.683000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"683000\",\n                                  \"endMs\": \"688079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"support this out of the box so you can have like automatic support for for credits because it has a bunch of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:23\"\n                                  },\n                                  \"trackingParams\": \"CIgDENP2BxhuIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 23 seconds support this out of the box so you can have like automatic support for for credits because it has a bunch of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.683000.688079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"688079\",\n                                  \"endMs\": \"694360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"different types you can then sort data with again if you want to use it um let's see names space models okay and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:28\"\n                                  },\n                                  \"trackingParams\": \"CIcDENP2BxhvIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 28 seconds different types you can then sort data with again if you want to use it um let's see names space models okay and\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.688079.694360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"694360\",\n                                  \"endMs\": \"699800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then how do we do that okay fair enough cool Let's do let's try to dive into the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:34\"\n                                  },\n                                  \"trackingParams\": \"CIYDENP2BxhwIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 34 seconds then how do we do that okay fair enough cool Let's do let's try to dive into the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.694360.699800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"699800\",\n                                  \"endMs\": \"706760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"code itself because it's actually not too bad I don't think see just click into the lip folder we have a generator\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:39\"\n                                  },\n                                  \"trackingParams\": \"CIUDENP2BxhxIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 39 seconds code itself because it's actually not too bad I don't think see just click into the lip folder we have a generator\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.699800.706760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"706760\",\n                                  \"endMs\": \"712240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"on here that makes it a little bit easier to get set up so you can do rails generate Associated and you pass it the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:46\"\n                                  },\n                                  \"trackingParams\": \"CIQDENP2BxhyIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 46 seconds on here that makes it a little bit easier to get set up so you can do rails generate Associated and you pass it the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.706760.712240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"712240\",\n                                  \"endMs\": \"717639\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"name um let's see and then we're just here just actor record and then when an\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:52\"\n                                  },\n                                  \"trackingParams\": \"CIMDENP2BxhzIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 52 seconds name um let's see and then we're just here just actor record and then when an\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.712240.717639\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"717639\",\n                                  \"endMs\": \"725320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Associated object we got so it's not too bad but there is some meta programming in here um basically what I'm doing is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:57\"\n                                  },\n                                  \"trackingParams\": \"CIIDENP2Bxh0IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 57 seconds Associated object we got so it's not too bad but there is some meta programming in here um basically what I'm doing is\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.717639.725320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"725320\",\n                                  \"endMs\": \"731959\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"when you this is a ruby built-in hook where when you inherit from this act record Associated object I we set up a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:05\"\n                                  },\n                                  \"trackingParams\": \"CIEDENP2Bxh1IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 5 seconds when you this is a ruby built-in hook where when you inherit from this act record Associated object I we set up a\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.725320.731959\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"731959\",\n                                  \"endMs\": \"737160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"whole bunch of this like extra logic where you're we I'm both requiring that you're\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:11\"\n                                  },\n                                  \"trackingParams\": \"CIADENP2Bxh2IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 11 seconds whole bunch of this like extra logic where you're we I'm both requiring that you're\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.731959.737160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"737160\",\n                                  \"endMs\": \"742760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"inheriting that you're an active record you're associating with um and then we're doing some other tricks to kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:17\"\n                                  },\n                                  \"trackingParams\": \"CP8CENP2Bxh3IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 17 seconds inheriting that you're an active record you're associating with um and then we're doing some other tricks to kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.737160.742760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"742760\",\n                                  \"endMs\": \"748959\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"both figure out what's the attribute name so in that case where you had the post publisher it would publisher underscore you know it would just be\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:22\"\n                                  },\n                                  \"trackingParams\": \"CP4CENP2Bxh4IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 22 seconds both figure out what's the attribute name so in that case where you had the post publisher it would publisher underscore you know it would just be\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.742760.748959\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"748959\",\n                                  \"endMs\": \"754600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"lower case and uh record class would be the post and so forth um and here's the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:28\"\n                                  },\n                                  \"trackingParams\": \"CP0CENP2Bxh5IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 28 seconds lower case and uh record class would be the post and so forth um and here's the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.748959.754600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"754600\",\n                                  \"endMs\": \"760160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the part I was talking about with that extension that it's just to wrap around this a classy V essentially um and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:34\"\n                                  },\n                                  \"trackingParams\": \"CPwCENP2Bxh6IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 34 seconds the part I was talking about with that extension that it's just to wrap around this a classy V essentially um and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.754600.760160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"760160\",\n                                  \"endMs\": \"766519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I'm using this is maybe where again some of this was two years ago and it's kind of maybe I shouldn't have used method\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:40\"\n                                  },\n                                  \"trackingParams\": \"CPsCENP2Bxh7IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 40 seconds I'm using this is maybe where again some of this was two years ago and it's kind of maybe I shouldn't have used method\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.760160.766519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"766519\",\n                                  \"endMs\": \"774600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"missing to do some of this but it kind of worked so I just sort of went with it but basically the gist of this is this is how we're supporting Global ID where\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:46\"\n                                  },\n                                  \"trackingParams\": \"CPoCENP2Bxh8IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 46 seconds missing to do some of this but it kind of worked so I just sort of went with it but basically the gist of this is this is how we're supporting Global ID where\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.766519.774600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"774600\",\n                                  \"endMs\": \"780880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we got both wear support and find support which is what's required to make that work\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:54\"\n                                  },\n                                  \"trackingParams\": \"CPkCENP2Bxh9IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 54 seconds we got both wear support and find support which is what's required to make that work\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.774600.780880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"780880\",\n                                  \"endMs\": \"785959\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um yeah where and I'm supering in here to sort of kick back up if we don't if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:00\"\n                                  },\n                                  \"trackingParams\": \"CPgCENP2Bxh-IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes um yeah where and I'm supering in here to sort of kick back up if we don't if\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.780880.785959\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"785959\",\n                                  \"endMs\": \"792360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"our record class don't we can't forward so this could be wear for instance so I'm also technically\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:05\"\n                                  },\n                                  \"trackingParams\": \"CPcCENP2Bxh_IhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 5 seconds our record class don't we can't forward so this could be wear for instance so I'm also technically\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.785959.792360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"792360\",\n                                  \"endMs\": \"798120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"supporting postp publisher. wear for Global IDs that seem to work um and so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:12\"\n                                  },\n                                  \"trackingParams\": \"CPYCENP2BxiAASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 12 seconds supporting postp publisher. wear for Global IDs that seem to work um and so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.792360.798120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"798120\",\n                                  \"endMs\": \"803279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what we do is we then forward that method to the post and then we extract\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:18\"\n                                  },\n                                  \"trackingParams\": \"CPUCENP2BxiBASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 18 seconds what we do is we then forward that method to the post and then we extract\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.798120.803279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"803279\",\n                                  \"endMs\": \"808320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the publisher from that essentially that's kind of what this logic is doing if it's if it's an array we just Loop\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:23\"\n                                  },\n                                  \"trackingParams\": \"CPQCENP2BxiCASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 23 seconds the publisher from that essentially that's kind of what this logic is doing if it's if it's an array we just Loop\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.803279.808320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"808320\",\n                                  \"endMs\": \"813839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"over it and extract do them because you could find multiple for instance um or we just send it directly to the one\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:28\"\n                                  },\n                                  \"trackingParams\": \"CPMCENP2BxiDASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 28 seconds over it and extract do them because you could find multiple for instance um or we just send it directly to the one\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.808320.813839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"813839\",\n                                  \"endMs\": \"819240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"version so that's kind of what's going on and then internally we're also\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:33\"\n                                  },\n                                  \"trackingParams\": \"CPICENP2BxiEASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 33 seconds version so that's kind of what's going on and then internally we're also\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.813839.819240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"819240\",\n                                  \"endMs\": \"827079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"doing I'm just using a gener named record um which means that I can write\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:39\"\n                                  },\n                                  \"trackingParams\": \"CPECENP2BxiFASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 39 seconds doing I'm just using a gener named record um which means that I can write\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.819240.827079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"827079\",\n                                  \"endMs\": \"834079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"code on my end that just refers to record if I need to in in my implementation but then up here we're\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:47\"\n                                  },\n                                  \"trackingParams\": \"CPACENP2BxiGASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 47 seconds code on my end that just refers to record if I need to in in my implementation but then up here we're\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.827079.834079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"834079\",\n                                  \"endMs\": \"839680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"doing this Alias method which is how you get that post Alias um so just aliasing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:54\"\n                                  },\n                                  \"trackingParams\": \"CO8CENP2BxiHASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 54 seconds doing this Alias method which is how you get that post Alias um so just aliasing\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.834079.839680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"839680\",\n                                  \"endMs\": \"844720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that record so it makes it easier so I don't have to generate a bunch of extra code but it can just be one Alias method\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:59\"\n                                  },\n                                  \"trackingParams\": \"CO4CENP2BxiIASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 59 seconds that record so it makes it easier so I don't have to generate a bunch of extra code but it can just be one Alias method\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.839680.844720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"844720\",\n                                  \"endMs\": \"850800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"call so it works on a client side when they're inheriting from it um cool makes\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:04\"\n                                  },\n                                  \"trackingParams\": \"CO0CENP2BxiJASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 4 seconds call so it works on a client side when they're inheriting from it um cool makes\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.844720.850800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"850800\",\n                                  \"endMs\": \"857680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"sense so far I don't know if I'm going too fast cool okay let's see and then we do an equal check here for a reason I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:10\"\n                                  },\n                                  \"trackingParams\": \"COwCENP2BxiKASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 10 seconds sense so far I don't know if I'm going too fast cool okay let's see and then we do an equal check here for a reason I\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.850800.857680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"857680\",\n                                  \"endMs\": \"865880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"don't remember why I implemented that but um so where so you're delegating post\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:17\"\n                                  },\n                                  \"trackingParams\": \"COsCENP2BxiLASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 17 seconds don't remember why I implemented that but um so where so you're delegating post\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.857680.865880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"865880\",\n                                  \"endMs\": \"873320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"published for example yes and but you only extracting the values that to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:25\"\n                                  },\n                                  \"trackingParams\": \"COoCENP2BxiMASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 25 seconds published for example yes and but you only extracting the values that to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.865880.873320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"873320\",\n                                  \"endMs\": \"878440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the yeah yeah so it's It's Tricky it's sort of embedded in here uh let's see\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:33\"\n                                  },\n                                  \"trackingParams\": \"COkCENP2BxiNASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 33 seconds the yeah yeah so it's It's Tricky it's sort of embedded in here uh let's see\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.873320.878440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"878440\",\n                                  \"endMs\": \"885519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"maybe we should take and translate this let's see if we do this and then where was the code at uh here and then let me\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:38\"\n                                  },\n                                  \"trackingParams\": \"COgCENP2BxiOASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 38 seconds maybe we should take and translate this let's see if we do this and then where was the code at uh here and then let me\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.878440.885519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"885519\",\n                                  \"endMs\": \"892519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"do this uh we'll go back and show this H alignment here cool so the record class\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:45\"\n                                  },\n                                  \"trackingParams\": \"COcCENP2BxiPASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 45 seconds do this uh we'll go back and show this H alignment here cool so the record class\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.885519.892519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"892519\",\n                                  \"endMs\": \"898600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that's just a post and Method here let's say well I'm just going to do it here\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:52\"\n                                  },\n                                  \"trackingParams\": \"COYCENP2BxiQASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 52 seconds that's just a post and Method here let's say well I'm just going to do it here\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.892519.898600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"898600\",\n                                  \"endMs\": \"904759\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"anything else oh okay where for instance and then so if the post doesn't respond to where\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:58\"\n                                  },\n                                  \"trackingParams\": \"COUCENP2BxiRASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 58 seconds anything else oh okay where for instance and then so if the post doesn't respond to where\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.898600.904759\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"904759\",\n                                  \"endMs\": \"910480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"which it does otherwise we' super but this could be you know it could be a different method that it doesn't respond\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:04\"\n                                  },\n                                  \"trackingParams\": \"COQCENP2BxiSASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 4 seconds which it does otherwise we' super but this could be you know it could be a different method that it doesn't respond\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.904759.910480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"910480\",\n                                  \"endMs\": \"917320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"to or whatnot um just so the method missing isn't too scatter shot because that's usually the issue where you miss\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:10\"\n                                  },\n                                  \"trackingParams\": \"COMCENP2BxiTASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 10 seconds to or whatnot um just so the method missing isn't too scatter shot because that's usually the issue where you miss\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.910480.917320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"917320\",\n                                  \"endMs\": \"925360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"something and then suddenly you get a bunch of weird errors so that's what the check is for but in this case it would so we try it then send where to it and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:17\"\n                                  },\n                                  \"trackingParams\": \"COICENP2BxiUASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 17 seconds something and then suddenly you get a bunch of weird errors so that's what the check is for but in this case it would so we try it then send where to it and\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.917320.925360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"925360\",\n                                  \"endMs\": \"933240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then we'd grab the value from that and then we'd send this attribute name which is the publisher oh hit here and so I'm\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:25\"\n                                  },\n                                  \"trackingParams\": \"COECENP2BxiVASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 25 seconds then we'd grab the value from that and then we'd send this attribute name which is the publisher oh hit here and so I'm\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.925360.933240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"933240\",\n                                  \"endMs\": \"940079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"trying to guard against because this could also be fined which then will return a single element so I'm trying to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:33\"\n                                  },\n                                  \"trackingParams\": \"COACENP2BxiWASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 33 seconds trying to guard against because this could also be fined which then will return a single element so I'm trying to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.933240.940079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"940079\",\n                                  \"endMs\": \"947360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"guard against both which is like if you return something response to each which where will do then I'm just going to map\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:40\"\n                                  },\n                                  \"trackingParams\": \"CN8CENP2BxiXASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 40 seconds guard against both which is like if you return something response to each which where will do then I'm just going to map\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.940079.947360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"947360\",\n                                  \"endMs\": \"953720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"over that collection and grab all of them out of it because you can do with global ID you can basically find many or\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:47\"\n                                  },\n                                  \"trackingParams\": \"CN4CENP2BxiYASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 47 seconds over that collection and grab all of them out of it because you can do with global ID you can basically find many or\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.947360.953720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"953720\",\n                                  \"endMs\": \"961120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"locate Min I think it's called and this can also in this way you also work with call let's say you have visible you can\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:53\"\n                                  },\n                                  \"trackingParams\": \"CN0CENP2BxiZASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 53 seconds locate Min I think it's called and this can also in this way you also work with call let's say you have visible you can\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.953720.961120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"961120\",\n                                  \"endMs\": \"966519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"say post publisher visible yeah I think I think that's also sort of do well I think I don't know if I support it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:01\"\n                                  },\n                                  \"trackingParams\": \"CNwCENP2BxiaASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 1 second say post publisher visible yeah I think I think that's also sort of do well I think I don't know if I support it\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.961120.966519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"966519\",\n                                  \"endMs\": \"971600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"because I think that's going to try to extract it immediately but I didn't add full support for that because I just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:06\"\n                                  },\n                                  \"trackingParams\": \"CNsCENP2BxibASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 6 seconds because I think that's going to try to extract it immediately but I didn't add full support for that because I just\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.966519.971600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"971600\",\n                                  \"endMs\": \"978560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"wanted to wear but I think that was the idea to work because like the record will still respond to visible the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:11\"\n                                  },\n                                  \"trackingParams\": \"CNoCENP2BxicASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 11 seconds wanted to wear but I think that was the idea to work because like the record will still respond to visible the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.971600.978560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"978560\",\n                                  \"endMs\": \"986480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"visible would be yeah exactly yeah um I can't remember if I worked on on trying that yeah um but yeah the reason I'm\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:18\"\n                                  },\n                                  \"trackingParams\": \"CNkCENP2BxidASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 18 seconds visible would be yeah exactly yeah um I can't remember if I worked on on trying that yeah um but yeah the reason I'm\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.978560.986480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"986480\",\n                                  \"endMs\": \"992680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"supporting wear is because you can also do this locate Mini so you could serialize these pors again into Global\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:26\"\n                                  },\n                                  \"trackingParams\": \"CNgCENP2BxieASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 26 seconds supporting wear is because you can also do this locate Mini so you could serialize these pors again into Global\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.986480.992680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"992680\",\n                                  \"endMs\": \"998399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"IDs and then pull them back out for somewhere if you want to put them somewhere else or whatever\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:32\"\n                                  },\n                                  \"trackingParams\": \"CNcCENP2BxifASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 32 seconds IDs and then pull them back out for somewhere if you want to put them somewhere else or whatever\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.992680.998399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"998399\",\n                                  \"endMs\": \"1005680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um okay also I think many actually uses like f with array because in the same\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:38\"\n                                  },\n                                  \"trackingParams\": \"CNYCENP2BxigASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 38 seconds um okay also I think many actually uses like f with array because in the same\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.998399.1005680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1005680\",\n                                  \"endMs\": \"1010920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"order so it would also yeah there's also something with that yeah yeah so that's it used to use where I think there's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:45\"\n                                  },\n                                  \"trackingParams\": \"CNUCENP2BxihASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 45 seconds order so it would also yeah there's also something with that yeah yeah so that's it used to use where I think there's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1005680.1010920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1010920\",\n                                  \"endMs\": \"1016040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"something where you can do like ignore missing where you pass this and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:50\"\n                                  },\n                                  \"trackingParams\": \"CNQCENP2BxiiASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 50 seconds something where you can do like ignore missing where you pass this and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1010920.1016040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1016040\",\n                                  \"endMs\": \"1022360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we'll use where but if you don't it'll use find and then it'll raise if it can't something like that I don't\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:56\"\n                                  },\n                                  \"trackingParams\": \"CNMCENP2BxijASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 56 seconds we'll use where but if you don't it'll use find and then it'll raise if it can't something like that I don't\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1016040.1022360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1022360\",\n                                  \"endMs\": \"1029120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"remember like I think yeah because it always returns them in the same order yeah because that sometimes can be\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:02\"\n                                  },\n                                  \"trackingParams\": \"CNICENP2BxikASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 2 seconds remember like I think yeah because it always returns them in the same order yeah because that sometimes can be\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1022360.1029120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1029120\",\n                                  \"endMs\": \"1035918\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"important yeah yeah for sure yeah and D would handle that case because even if you do find finding array yes yeah yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:09\"\n                                  },\n                                  \"trackingParams\": \"CNECENP2BxilASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 9 seconds important yeah yeah for sure yeah and D would handle that case because even if you do find finding array yes yeah yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1029120.1035918\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1035919\",\n                                  \"endMs\": \"1043600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and then we'll just yeah return the array and then we can just Loop over what's in the that order yeah maybe this map can be a bit dangerous if you if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:15\"\n                                  },\n                                  \"trackingParams\": \"CNACENP2BximASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 15 seconds and then we'll just yeah return the array and then we can just Loop over what's in the that order yeah maybe this map can be a bit dangerous if you if\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1035919.1043600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1043600\",\n                                  \"endMs\": \"1049679\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"your scope is like yeah yeah for sure yeah yeah you have to be careful with that so that's why it's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:23\"\n                                  },\n                                  \"trackingParams\": \"CM8CENP2BxinASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 23 seconds your scope is like yeah yeah for sure yeah yeah you have to be careful with that so that's why it's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1043600.1049679\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1049679\",\n                                  \"endMs\": \"1055000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"not people aren't necessarily using it this way because this is more an integration part for for just passing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:29\"\n                                  },\n                                  \"trackingParams\": \"CM4CENP2BxioASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 29 seconds not people aren't necessarily using it this way because this is more an integration part for for just passing\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1049679.1055000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1055000\",\n                                  \"endMs\": \"1061280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"them into jobs and so forth but I want it to have some indicator of potentially being able to use it like that publisher\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:35\"\n                                  },\n                                  \"trackingParams\": \"CM0CENP2BxipASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 35 seconds them into jobs and so forth but I want it to have some indicator of potentially being able to use it like that publisher\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1055000.1061280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1061280\",\n                                  \"endMs\": \"1068000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"will be this publisher object yeah yeah so in in this case in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:41\"\n                                  },\n                                  \"trackingParams\": \"CMwCENP2BxiqASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 41 seconds will be this publisher object yeah yeah so in in this case in\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1061280.1068000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1068000\",\n                                  \"endMs\": \"1073919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this method missing would be on this publisher like an in no it actually be on the class so I guess you do what is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:48\"\n                                  },\n                                  \"trackingParams\": \"CMsCENP2BxirASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 48 seconds this method missing would be on this publisher like an in no it actually be on the class so I guess you do what is\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1068000.1073919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1073919\",\n                                  \"endMs\": \"1079360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it you could do like a publisher like you could Define it like that but yeah um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:53\"\n                                  },\n                                  \"trackingParams\": \"CMoCENP2BxisASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 53 seconds it you could do like a publisher like you could Define it like that but yeah um\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1073919.1079360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1079360\",\n                                  \"endMs\": \"1085240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah yeah so it's a little tricky some of this integrational work but but it sets up all of this conventional stuff\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:59\"\n                                  },\n                                  \"trackingParams\": \"CMkCENP2BxitASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 59 seconds yeah yeah so it's a little tricky some of this integrational work but but it sets up all of this conventional stuff\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1079360.1085240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1085240\",\n                                  \"endMs\": \"1091039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so it's easier to just sort of works you just have to inherit from an object you just have to name space and then you're\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:05\"\n                                  },\n                                  \"trackingParams\": \"CMgCENP2BxiuASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 5 seconds so it's easier to just sort of works you just have to inherit from an object you just have to name space and then you're\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1085240.1091039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1091039\",\n                                  \"endMs\": \"1098320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"kind of done and you get these extra features out of it um maybe like performance problem oh yeah sure\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:11\"\n                                  },\n                                  \"trackingParams\": \"CMcCENP2BxivASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 11 seconds kind of done and you get these extra features out of it um maybe like performance problem oh yeah sure\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1091039.1098320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1098320\",\n                                  \"endMs\": \"1103640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah yeah you could do something like that yeah yeah yeah um but I don't know if people are going to be using it I so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:18\"\n                                  },\n                                  \"trackingParams\": \"CMYCENP2BxiwASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 18 seconds yeah yeah you could do something like that yeah yeah yeah um but I don't know if people are going to be using it I so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1098320.1103640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1103640\",\n                                  \"endMs\": \"1109360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I haven't implemented that yet for sure right now I just wanted it to work but could yeah you're right could\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:23\"\n                                  },\n                                  \"trackingParams\": \"CMUCENP2BxixASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 23 seconds I haven't implemented that yet for sure right now I just wanted it to work but could yeah you're right could\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1103640.1109360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1109360\",\n                                  \"endMs\": \"1116520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um and then the other side of it is then having this uh let's see here we have this has object declaration so one other\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:29\"\n                                  },\n                                  \"trackingParams\": \"CMQCENP2BxiyASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 29 seconds um and then the other side of it is then having this uh let's see here we have this has object declaration so one other\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1109360.1116520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1116520\",\n                                  \"endMs\": \"1122480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"thing I tend to do when I'm writing gems I just try to imple play around with new Ruby features well refinements is not a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:36\"\n                                  },\n                                  \"trackingParams\": \"CMMCENP2BxizASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 36 seconds thing I tend to do when I'm writing gems I just try to imple play around with new Ruby features well refinements is not a\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1116520.1122480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1122480\",\n                                  \"endMs\": \"1127640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"ruby new Ruby feature but I haven't really used them before so I'm just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:42\"\n                                  },\n                                  \"trackingParams\": \"CMICENP2Bxi0ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 42 seconds ruby new Ruby feature but I haven't really used them before so I'm just\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1122480.1127640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1127640\",\n                                  \"endMs\": \"1135120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"trying to figure out like playing around with different syntax gady we talked about this earlier right was it uh Alexander that was like a I think\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:47\"\n                                  },\n                                  \"trackingParams\": \"CMECENP2Bxi1ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 47 seconds trying to figure out like playing around with different syntax gady we talked about this earlier right was it uh Alexander that was like a I think\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1127640.1135120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1135120\",\n                                  \"endMs\": \"1142200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Association of the yeah exactly yeah yeah because would actually not work if we do oh uh if we do do end because then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:55\"\n                                  },\n                                  \"trackingParams\": \"CMACENP2Bxi2ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 55 seconds Association of the yeah exactly yeah yeah because would actually not work if we do oh uh if we do do end because then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1135120.1142200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1142200\",\n                                  \"endMs\": \"1148080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the block Associates with using but then if you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:02\"\n                                  },\n                                  \"trackingParams\": \"CL8CENP2Bxi3ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 2 seconds the block Associates with using but then if you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1142200.1148080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1148080\",\n                                  \"endMs\": \"1153640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"use yeah but if you use the curly braces it'll associate to module. new so it's a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:08\"\n                                  },\n                                  \"trackingParams\": \"CL4CENP2Bxi4ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 8 seconds use yeah but if you use the curly braces it'll associate to module. new so it's a\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1148080.1153640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1153640\",\n                                  \"endMs\": \"1160400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"trick to do it on like one line so I like this kind of weird stuff uh just like oh this works now and then we'll\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:13\"\n                                  },\n                                  \"trackingParams\": \"CL0CENP2Bxi5ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 13 seconds trick to do it on like one line so I like this kind of weird stuff uh just like oh this works now and then we'll\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1153640.1160400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1160400\",\n                                  \"endMs\": \"1167480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"just if not then El on same line I just put extend self after the mod modu\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:20\"\n                                  },\n                                  \"trackingParams\": \"CLwCENP2Bxi6ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 20 seconds just if not then El on same line I just put extend self after the mod modu\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1160400.1167480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1167480\",\n                                  \"endMs\": \"1175440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"definition which so you mean where like this was this what you mean yeah that yeah that's also kind of weird but it's just fun to do I also oh yeah but also\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:27\"\n                                  },\n                                  \"trackingParams\": \"CLsCENP2Bxi7ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 27 seconds definition which so you mean where like this was this what you mean yeah that yeah that's also kind of weird but it's just fun to do I also oh yeah but also\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1167480.1175440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1175440\",\n                                  \"endMs\": \"1181240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"been really been liking using um like the endless method definitions at first I really didn't like them but I've just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:35\"\n                                  },\n                                  \"trackingParams\": \"CLoCENP2Bxi8ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 35 seconds been really been liking using um like the endless method definitions at first I really didn't like them but I've just\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1175440.1181240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1181240\",\n                                  \"endMs\": \"1188200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"been forcing myself to use them more and more to see what it feels like and I'm kind of starting to really like them so um just to play around it and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:41\"\n                                  },\n                                  \"trackingParams\": \"CLkCENP2Bxi9ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 41 seconds been forcing myself to use them more and more to see what it feels like and I'm kind of starting to really like them so um just to play around it and\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1181240.1188200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1188200\",\n                                  \"endMs\": \"1194200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"see how it feels essentially uh let's see what else and so this is I mean this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:48\"\n                                  },\n                                  \"trackingParams\": \"CLgCENP2Bxi-ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 48 seconds see how it feels essentially uh let's see what else and so this is I mean this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1188200.1194200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1194200\",\n                                  \"endMs\": \"1201480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"is kind of Overkill to to Define like an extra method on to like I'm both yeah so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:54\"\n                                  },\n                                  \"trackingParams\": \"CLcCENP2Bxi_ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 54 seconds is kind of Overkill to to Define like an extra method on to like I'm both yeah so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1194200.1201480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1201480\",\n                                  \"endMs\": \"1207400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a lot of stuff is happening here um but it was just I just wanted it um but basically what it is is we can insert\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:01\"\n                                  },\n                                  \"trackingParams\": \"CLYCENP2BxjAASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 1 second a lot of stuff is happening here um but it was just I just wanted it um but basically what it is is we can insert\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1201480.1207400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1207400\",\n                                  \"endMs\": \"1214120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"these names so what that would be is like you have has object what was it like could be publisher it could be like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:07\"\n                                  },\n                                  \"trackingParams\": \"CLUCENP2BxjBASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 7 seconds these names so what that would be is like you have has object what was it like could be publisher it could be like\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1207400.1214120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1214120\",\n                                  \"endMs\": \"1221120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"seat so you have multiple and you Loop over each of these symbols in here and for each of them you you yield to this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:14\"\n                                  },\n                                  \"trackingParams\": \"CLQCENP2BxjCASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 14 seconds seat so you have multiple and you Loop over each of these symbols in here and for each of them you you yield to this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1214120.1221120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1221120\",\n                                  \"endMs\": \"1227400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"block where you then Define return a string that then gets concatenated and then you do so that's what's happening\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:21\"\n                                  },\n                                  \"trackingParams\": \"CLMCENP2BxjDASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 21 seconds block where you then Define return a string that then gets concatenated and then you do so that's what's happening\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1221120.1227400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1227400\",\n                                  \"endMs\": \"1233559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"up here so another thing first I have to grab the the location so you can point back to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:27\"\n                                  },\n                                  \"trackingParams\": \"CLICENP2BxjEASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 27 seconds up here so another thing first I have to grab the the location so you can point back to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1227400.1233559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1233559\",\n                                  \"endMs\": \"1239039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"where the method is defined this is also some triggery that you're not used to if you're just writing apps but in library\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:33\"\n                                  },\n                                  \"trackingParams\": \"CLECENP2BxjFASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 33 seconds where the method is defined this is also some triggery that you're not used to if you're just writing apps but in library\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1233559.1239039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1239039\",\n                                  \"endMs\": \"1246320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"code I want to if you do so what is it like if you do post. instance method\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:39\"\n                                  },\n                                  \"trackingParams\": \"CLACENP2BxjGASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 39 seconds code I want to if you do so what is it like if you do post. instance method\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1239039.1246320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1246320\",\n                                  \"endMs\": \"1255240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"publisher and then do Source loc oh source location I wanted to point back to where that has optic call was in the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:46\"\n                                  },\n                                  \"trackingParams\": \"CK8CENP2BxjHASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 46 seconds publisher and then do Source loc oh source location I wanted to point back to where that has optic call was in the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1246320.1255240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1255240\",\n                                  \"endMs\": \"1261240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"post so it's easy to find where it's actually coming from so that's a trick I'm doing here which is where Ruby has\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:55\"\n                                  },\n                                  \"trackingParams\": \"CK4CENP2BxjIASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 55 seconds post so it's easy to find where it's actually coming from so that's a trick I'm doing here which is where Ruby has\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1255240.1261240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1261240\",\n                                  \"endMs\": \"1267520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this capability of getting all the the stack you're in where each method call you just put a new frame on the stack\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:01\"\n                                  },\n                                  \"trackingParams\": \"CK0CENP2BxjJASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 1 second this capability of getting all the the stack you're in where each method call you just put a new frame on the stack\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1261240.1267520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1267520\",\n                                  \"endMs\": \"1273720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and so forth that's what happens when you throw an exception you have this whole that shows everywhere you've been and so forth so what we're doing here is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:07\"\n                                  },\n                                  \"trackingParams\": \"CKwCENP2BxjKASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 7 seconds and so forth that's what happens when you throw an exception you have this whole that shows everywhere you've been and so forth so what we're doing here is\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1267520.1273720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1273720\",\n                                  \"endMs\": \"1280039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we're telling Ruby 2 I want the frame before we were called and then I just want one frame and then it returns an\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:13\"\n                                  },\n                                  \"trackingParams\": \"CKsCENP2BxjLASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 13 seconds we're telling Ruby 2 I want the frame before we were called and then I just want one frame and then it returns an\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1273720.1280039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1280039\",\n                                  \"endMs\": \"1287360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"array so we have to call first so It'll point back to where it will actually point to here where has optic was called\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:20\"\n                                  },\n                                  \"trackingParams\": \"CKoCENP2BxjMASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 20 seconds array so we have to call first so It'll point back to where it will actually point to here where has optic was called\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1280039.1287360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1287360\",\n                                  \"endMs\": \"1294200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so that's the trick for it and then for each of these I'm just calling them chunks for each of these names I want to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:27\"\n                                  },\n                                  \"trackingParams\": \"CKkCENP2BxjNASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 27 seconds so that's the trick for it and then for each of these I'm just calling them chunks for each of these names I want to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1287360.1294200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1294200\",\n                                  \"endMs\": \"1300159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then convert them into an array case there's just you only pass one which would happen if you do this uh I mean if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:34\"\n                                  },\n                                  \"trackingParams\": \"CKgCENP2BxjOASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 34 seconds then convert them into an array case there's just you only pass one which would happen if you do this uh I mean if\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1294200.1300159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1300159\",\n                                  \"endMs\": \"1307360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you just do that I think no that will probably maybe I could actually skip the array because I'm doing a star anyway um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:40\"\n                                  },\n                                  \"trackingParams\": \"CKcCENP2BxjPASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 40 seconds you just do that I think no that will probably maybe I could actually skip the array because I'm doing a star anyway um\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1300159.1307360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1307360\",\n                                  \"endMs\": \"1313880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and then I'm concatenating everything into just one array of strings because we're yielding to this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:47\"\n                                  },\n                                  \"trackingParams\": \"CKYCENP2BxjQASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 47 seconds and then I'm concatenating everything into just one array of strings because we're yielding to this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1307360.1313880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1313880\",\n                                  \"endMs\": \"1319480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"block so we get all these strings returned but it just becomes one array of strings\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:53\"\n                                  },\n                                  \"trackingParams\": \"CKUCENP2BxjRASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 53 seconds block so we get all these strings returned but it just becomes one array of strings\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1313880.1319480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1319480\",\n                                  \"endMs\": \"1325159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and then from these Source trunks we now have we can then join them in with like some I'm just like putting some new\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:59\"\n                                  },\n                                  \"trackingParams\": \"CKQCENP2BxjSASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 59 seconds and then from these Source trunks we now have we can then join them in with like some I'm just like putting some new\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1319480.1325159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1325159\",\n                                  \"endMs\": \"1331640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"lines in as well and we're pointing back to the file and the line number which will be that line so again a lot of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:05\"\n                                  },\n                                  \"trackingParams\": \"CKMCENP2BxjTASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 5 seconds lines in as well and we're pointing back to the file and the line number which will be that line so again a lot of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1325159.1331640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1331640\",\n                                  \"endMs\": \"1338120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"stuff is going on in here and you can pass it into classy ball so you also that's how you get uh so if you pass multiple in you just get those meth\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:11\"\n                                  },\n                                  \"trackingParams\": \"CKICENP2BxjUASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 11 seconds stuff is going on in here and you can pass it into classy ball so you also that's how you get uh so if you pass multiple in you just get those meth\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1331640.1338120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1338120\",\n                                  \"endMs\": \"1343240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"definition kind of in one so a bunch of stuff is going on there and then let's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:18\"\n                                  },\n                                  \"trackingParams\": \"CKECENP2BxjVASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 18 seconds definition kind of in one so a bunch of stuff is going on there and then let's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1338120.1343240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1343240\",\n                                  \"endMs\": \"1349520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"see what else we can do uh let's do yeah so this is the the kind of like the tricky code we have to do this for\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:23\"\n                                  },\n                                  \"trackingParams\": \"CKACENP2BxjWASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 23 seconds see what else we can do uh let's do yeah so this is the the kind of like the tricky code we have to do this for\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1343240.1349520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1349520\",\n                                  \"endMs\": \"1354880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"object shapes to assign a hash and then put it in a key and yada yada um is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:29\"\n                                  },\n                                  \"trackingParams\": \"CJ8CENP2BxjXASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 29 seconds object shapes to assign a hash and then put it in a key and yada yada um is\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1349520.1354880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1354880\",\n                                  \"endMs\": \"1361039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"there a way because with the object shapes again if nobody calls the publisher me this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:34\"\n                                  },\n                                  \"trackingParams\": \"CJ4CENP2BxjYASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 34 seconds there a way because with the object shapes again if nobody calls the publisher me this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1354880.1361039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1361039\",\n                                  \"endMs\": \"1366480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"array would never be called destroy the shape anyway can and again the hash is a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:41\"\n                                  },\n                                  \"trackingParams\": \"CJ0CENP2BxjZASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 41 seconds array would never be called destroy the shape anyway can and again the hash is a\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1361039.1366480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1366480\",\n                                  \"endMs\": \"1373120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"great thing because we can always add to it way to inject the hash the moment the ACT well so what we do is we actually do\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:46\"\n                                  },\n                                  \"trackingParams\": \"CJwCENP2BxjaASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 46 seconds great thing because we can always add to it way to inject the hash the moment the ACT well so what we do is we actually do\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1366480.1373120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1373120\",\n                                  \"endMs\": \"1379120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this here we're overriding this internal actually we're going recall this when you ini\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:53\"\n                                  },\n                                  \"trackingParams\": \"CJsCENP2BxjbASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 53 seconds this here we're overriding this internal actually we're going recall this when you ini\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1373120.1379120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1379120\",\n                                  \"endMs\": \"1386000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so just we're trying to preserve so it's always in the same order okay and you it to because want to take\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:59\"\n                                  },\n                                  \"trackingParams\": \"CJoCENP2BxjcASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 59 seconds so just we're trying to preserve so it's always in the same order okay and you it to because want to take\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1379120.1386000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1386000\",\n                                  \"endMs\": \"1394120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the but you we have to declare yeah yeah so you have to declare the object shape\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:06\"\n                                  },\n                                  \"trackingParams\": \"CJkCENP2BxjdASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 6 seconds the but you we have to declare yeah yeah so you have to declare the object shape\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1386000.1394120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1394120\",\n                                  \"endMs\": \"1401400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"first yeah yeah it's an internal method so that's one tricky bit in this stuff um but you know so but it's an\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:14\"\n                                  },\n                                  \"trackingParams\": \"CJgCENP2BxjeASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 14 seconds first yeah yeah it's an internal method so that's one tricky bit in this stuff um but you know so but it's an\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1394120.1401400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1401400\",\n                                  \"endMs\": \"1407159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"optimization thing essentially so and then actual record sets a whole bunch of instance meth instance variables in its\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:21\"\n                                  },\n                                  \"trackingParams\": \"CJcCENP2BxjfASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 21 seconds optimization thing essentially so and then actual record sets a whole bunch of instance meth instance variables in its\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1401400.1407159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1407159\",\n                                  \"endMs\": \"1413360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"internals as well when it goes calls this um so that's the trick we have to do for that memory optimization essenti\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:27\"\n                                  },\n                                  \"trackingParams\": \"CJYCENP2BxjgASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 27 seconds internals as well when it goes calls this um so that's the trick we have to do for that memory optimization essenti\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1407159.1413360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1413360\",\n                                  \"endMs\": \"1418720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so you don't like because act records can have a whole bunch of different you know instance variables all kinds of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:33\"\n                                  },\n                                  \"trackingParams\": \"CJUCENP2BxjhASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 33 seconds so you don't like because act records can have a whole bunch of different you know instance variables all kinds of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1413360.1418720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1418720\",\n                                  \"endMs\": \"1425000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"stuff so we're trying to reduce the amount of object shapes that it has so and even if the associated object is not\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:38\"\n                                  },\n                                  \"trackingParams\": \"CJQCENP2BxjiASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 38 seconds stuff so we're trying to reduce the amount of object shapes that it has so and even if the associated object is not\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1418720.1425000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1425000\",\n                                  \"endMs\": \"1431240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the shape of the object is still the same you can when it's called you make it as a cash so if you don't ever call\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:45\"\n                                  },\n                                  \"trackingParams\": \"CJMCENP2BxjjASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 45 seconds the shape of the object is still the same you can when it's called you make it as a cash so if you don't ever call\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1425000.1431240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1431240\",\n                                  \"endMs\": \"1436840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it actually you make almost no price yes exactly yeah exactly that's that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:51\"\n                                  },\n                                  \"trackingParams\": \"CJICENP2BxjkASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 51 seconds it actually you make almost no price yes exactly yeah exactly that's that\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1431240.1436840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1436840\",\n                                  \"endMs\": \"1442000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"hopefully and then I'm using this extend Source from again passing in the same\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:56\"\n                                  },\n                                  \"trackingParams\": \"CJECENP2BxjlASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 56 seconds hopefully and then I'm using this extend Source from again passing in the same\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1436840.1442000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1442000\",\n                                  \"endMs\": \"1449640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"names but now I'm trying to do that this is what I talking about when you before those call backs because you can also pass them in as this options has hash\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:02\"\n                                  },\n                                  \"trackingParams\": \"CJACENP2BxjmASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 2 seconds names but now I'm trying to do that this is what I talking about when you before those call backs because you can also pass them in as this options has hash\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1442000.1449640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1449640\",\n                                  \"endMs\": \"1454919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"where you have was it in a read me do I have that somewhere was it after save what do I call it oh it's this whole\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:09\"\n                                  },\n                                  \"trackingParams\": \"CI8CENP2BxjnASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 9 seconds where you have was it in a read me do I have that somewhere was it after save what do I call it oh it's this whole\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1449640.1454919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1454919\",\n                                  \"endMs\": \"1461120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"thing so you pass it something like after touch I'm just saying oh you want to call after touch on this publisher\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:14\"\n                                  },\n                                  \"trackingParams\": \"CI4CENP2BxjoASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 14 seconds thing so you pass it something like after touch I'm just saying oh you want to call after touch on this publisher\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1454919.1461120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1461120\",\n                                  \"endMs\": \"1466679\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and for. call back on or if you want to call something else where you didn't or you want to hijack in here and prevent\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:21\"\n                                  },\n                                  \"trackingParams\": \"CI0CENP2BxjpASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 21 seconds and for. call back on or if you want to call something else where you didn't or you want to hijack in here and prevent\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1461120.1466679\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1466679\",\n                                  \"endMs\": \"1472000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"something so it's it's a it's a into writing these three lines essentially not saying people should use it but I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:26\"\n                                  },\n                                  \"trackingParams\": \"CIwCENP2BxjqASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 26 seconds something so it's it's a it's a into writing these three lines essentially not saying people should use it but I\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1466679.1472000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1472000\",\n                                  \"endMs\": \"1478039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"just thought this is kind of interesting to see what that would look like again in the the idea with this is to find\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:32\"\n                                  },\n                                  \"trackingParams\": \"CIsCENP2BxjrASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 32 seconds just thought this is kind of interesting to see what that would look like again in the the idea with this is to find\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1472000.1478039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1478039\",\n                                  \"endMs\": \"1483880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"these collaborator objects so you want to have a sense of what the life cycle is like but one this might be very\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:38\"\n                                  },\n                                  \"trackingParams\": \"CIoCENP2BxjsASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 38 seconds these collaborator objects so you want to have a sense of what the life cycle is like but one this might be very\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1478039.1483880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1483880\",\n                                  \"endMs\": \"1490559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"useful for example if you say let's say I have like a sorting object that's for like I make my object sortable and I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:43\"\n                                  },\n                                  \"trackingParams\": \"CIkCENP2BxjtASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 43 seconds useful for example if you say let's say I have like a sorting object that's for like I make my object sortable and I\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1483880.1490559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1490559\",\n                                  \"endMs\": \"1495919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"want to delegate okay I'm creating this before create so you set the number of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:50\"\n                                  },\n                                  \"trackingParams\": \"CIgCENP2BxjuASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 50 seconds want to delegate okay I'm creating this before create so you set the number of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1490559.1495919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1495919\",\n                                  \"endMs\": \"1502399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the object like oh that's you position 0 five so we can is there any reason why\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:55\"\n                                  },\n                                  \"trackingParams\": \"CIcCENP2BxjvASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 55 seconds the object like oh that's you position 0 five so we can is there any reason why\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1495919.1502399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1502399\",\n                                  \"endMs\": \"1507640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we have two Calles of the extend Source why yeah because I wanted to to separate\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:02\"\n                                  },\n                                  \"trackingParams\": \"CIYCENP2BxjwASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 2 seconds we have two Calles of the extend Source why yeah because I wanted to to separate\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1502399.1507640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1507640\",\n                                  \"endMs\": \"1514440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"them out what we're doing with them okay so it's like yeah so something blows up you want to yeah it's just it's like a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:07\"\n                                  },\n                                  \"trackingParams\": \"CIUCENP2BxjxASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 7 seconds them out what we're doing with them okay so it's like yeah so something blows up you want to yeah it's just it's like a\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1507640.1514440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1514440\",\n                                  \"endMs\": \"1520240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"here we're doing um we're doing we're defining all the methods first and then later on I'm defining all the callbacks\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:14\"\n                                  },\n                                  \"trackingParams\": \"CIQCENP2BxjyASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 14 seconds here we're doing um we're doing we're defining all the methods first and then later on I'm defining all the callbacks\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1514440.1520240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1520240\",\n                                  \"endMs\": \"1525960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"because otherwise we'd have to do extend Source from and then Loop over uh what we need to do the callbacks in I guess\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:20\"\n                                  },\n                                  \"trackingParams\": \"CIMCENP2BxjzASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 20 seconds because otherwise we'd have to do extend Source from and then Loop over uh what we need to do the callbacks in I guess\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1520240.1525960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1525960\",\n                                  \"endMs\": \"1532640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"or something it just seemed a little bit cleaner to repeat it kind of yeah otherwise you have to just combine yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:25\"\n                                  },\n                                  \"trackingParams\": \"CIICENP2Bxj0ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 25 seconds or something it just seemed a little bit cleaner to repeat it kind of yeah otherwise you have to just combine yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1525960.1532640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1532640\",\n                                  \"endMs\": \"1538399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah I guess so what would that look like yeah we'd have to do maybe we'd have to do a begin around us and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:32\"\n                                  },\n                                  \"trackingParams\": \"CIECENP2Bxj1ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 32 seconds yeah I guess so what would that look like yeah we'd have to do maybe we'd have to do a begin around us and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1532640.1538399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1538399\",\n                                  \"endMs\": \"1545159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"map them like Str which says and you just or I think you'd have to pass in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:38\"\n                                  },\n                                  \"trackingParams\": \"CIACENP2Bxj2ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 38 seconds map them like Str which says and you just or I think you'd have to pass in\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1538399.1545159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1545159\",\n                                  \"endMs\": \"1552039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like a result or something and then you'd have to do like result and then a pen back and forth it just seem cleaner\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:45\"\n                                  },\n                                  \"trackingParams\": \"CP8BENP2Bxj3ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 45 seconds like a result or something and then you'd have to do like result and then a pen back and forth it just seem cleaner\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1545159.1552039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1552039\",\n                                  \"endMs\": \"1557360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"to just I it makes sense but it's kind of Library code let's see me clean this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:52\"\n                                  },\n                                  \"trackingParams\": \"CP4BENP2Bxj4ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 52 seconds to just I it makes sense but it's kind of Library code let's see me clean this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1552039.1557360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1557360\",\n                                  \"endMs\": \"1565240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"out uh and yeah that's where we're looping through so if it's true we're just saying oh you just want to pass the same call back on uh and so for and this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:57\"\n                                  },\n                                  \"trackingParams\": \"CP0BENP2Bxj5ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 57 seconds out uh and yeah that's where we're looping through so if it's true we're just saying oh you just want to pass the same call back on uh and so for and this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1557360.1565240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1565240\",\n                                  \"endMs\": \"1570279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"is looks kind of weird but it's just defining what is it like after save uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:05\"\n                                  },\n                                  \"trackingParams\": \"CPwBENP2Bxj6ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 5 seconds is looks kind of weird but it's just defining what is it like after save uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1565240.1570279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1570279\",\n                                  \"endMs\": \"1575799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and then passing in the block so we do publisher dot what is it like after touch I fer call but this is kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:10\"\n                                  },\n                                  \"trackingParams\": \"CPsBENP2Bxj7ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 10 seconds and then passing in the block so we do publisher dot what is it like after touch I fer call but this is kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1570279.1575799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1575799\",\n                                  \"endMs\": \"1582720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what it's doing so that's why it looked weird but it works because we're passing it into classy so what is it classy V\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:15\"\n                                  },\n                                  \"trackingParams\": \"CPoBENP2Bxj8ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 15 seconds what it's doing so that's why it looked weird but it works because we're passing it into classy so what is it classy V\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1575799.1582720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1582720\",\n                                  \"endMs\": \"1589279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like basically just is kind of what it's doing and it works um weirdly enough\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:22\"\n                                  },\n                                  \"trackingParams\": \"CPkBENP2Bxj9ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 22 seconds like basically just is kind of what it's doing and it works um weirdly enough\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1582720.1589279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1589279\",\n                                  \"endMs\": \"1594799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"cool so that's sort of it for what this thing does\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:29\"\n                                  },\n                                  \"trackingParams\": \"CPgBENP2Bxj-ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 29 seconds cool so that's sort of it for what this thing does\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1589279.1594799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1594799\",\n                                  \"endMs\": \"1600320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um yeah that's that's this part how long we doing okay we doing okay any\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:34\"\n                                  },\n                                  \"trackingParams\": \"CPcBENP2Bxj_ASITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 34 seconds um yeah that's that's this part how long we doing okay we doing okay any\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1594799.1600320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1600320\",\n                                  \"endMs\": \"1606679\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"questions so far or what's so it's meant to just be complimentary it's meant to be a fairly lightweight convention that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:40\"\n                                  },\n                                  \"trackingParams\": \"CPYBENP2BxiAAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 40 seconds questions so far or what's so it's meant to just be complimentary it's meant to be a fairly lightweight convention that\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1600320.1606679\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1606679\",\n                                  \"endMs\": \"1611960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"if you want to put them in there you can do it I actually I should show you I was just playing around with this the other day\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:46\"\n                                  },\n                                  \"trackingParams\": \"CPUBENP2BxiBAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 46 seconds if you want to put them in there you can do it I actually I should show you I was just playing around with this the other day\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1606679.1611960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1611960\",\n                                  \"endMs\": \"1617840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"where uh where was it oh that's Ron here here it was so on Ruby video if you've\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:51\"\n                                  },\n                                  \"trackingParams\": \"CPQBENP2BxiCAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 51 seconds where uh where was it oh that's Ron here here it was so on Ruby video if you've\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1611960.1617840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1617840\",\n                                  \"endMs\": \"1623360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"seen that where uh both uh Adrian who's writing in here is trying to Adrian and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:57\"\n                                  },\n                                  \"trackingParams\": \"CPMBENP2BxiDAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 57 seconds seen that where uh both uh Adrian who's writing in here is trying to Adrian and\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1617840.1623360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1623360\",\n                                  \"endMs\": \"1628760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Marco are trying to like index a whole bunch of R from all kinds\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:03\"\n                                  },\n                                  \"trackingParams\": \"CPIBENP2BxiEAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 3 seconds Marco are trying to like index a whole bunch of R from all kinds\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1623360.1628760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1628760\",\n                                  \"endMs\": \"1637600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of yeah yeah they're doing a ton of different stuff to but I think they do very good\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:08\"\n                                  },\n                                  \"trackingParams\": \"CPEBENP2BxiFAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 8 seconds of yeah yeah they're doing a ton of different stuff to but I think they do very good\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1628760.1637600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1637600\",\n                                  \"endMs\": \"1644880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah yeah and yeah yeah Marco added it and I yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:17\"\n                                  },\n                                  \"trackingParams\": \"CPABENP2BxiGAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 17 seconds yeah yeah and yeah yeah Marco added it and I yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1637600.1644880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1644880\",\n                                  \"endMs\": \"1650240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh so let's see here so what's this oh here so um Adrian is playing around with\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:24\"\n                                  },\n                                  \"trackingParams\": \"CO8BENP2BxiHAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 24 seconds uh so let's see here so what's this oh here so um Adrian is playing around with\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1644880.1650240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1650240\",\n                                  \"endMs\": \"1655720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this because he's also using another we I don't think we have time to go into this other one but I have another gym that's also interacting with all this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:30\"\n                                  },\n                                  \"trackingParams\": \"CO4BENP2BxiIAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 30 seconds this because he's also using another we I don't think we have time to go into this other one but I have another gym that's also interacting with all this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1650240.1655720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1655720\",\n                                  \"endMs\": \"1662760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like because of the conventions that are being set up where you can pass this poral into a job I can have some extra\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:35\"\n                                  },\n                                  \"trackingParams\": \"CO0BENP2BxiJAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 35 seconds like because of the conventions that are being set up where you can pass this poral into a job I can have some extra\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1655720.1662760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1662760\",\n                                  \"endMs\": \"1670200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"gem that can then condense some other logic where generating jobs but that's a whole other thing uh but he was playing around with this where he had a what was\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:42\"\n                                  },\n                                  \"trackingParams\": \"COwBENP2BxiKAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 42 seconds gem that can then condense some other logic where generating jobs but that's a whole other thing uh but he was playing around with this where he had a what was\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1662760.1670200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1670200\",\n                                  \"endMs\": \"1676240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"he doing before he was just calling a job directly and then uh what was he\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:50\"\n                                  },\n                                  \"trackingParams\": \"COsBENP2BxiLAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 50 seconds he doing before he was just calling a job directly and then uh what was he\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1670200.1676240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1676240\",\n                                  \"endMs\": \"1681840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"doing they calling it again here and and it sort of fetch this blue sky metadata\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:56\"\n                                  },\n                                  \"trackingParams\": \"COoBENP2BxiMAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 56 seconds doing they calling it again here and and it sort of fetch this blue sky metadata\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1676240.1681840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1681840\",\n                                  \"endMs\": \"1687960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"internally but then he swapped it over to using this Associated optic of like have an idea for a profile in hand so I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:01\"\n                                  },\n                                  \"trackingParams\": \"COkBENP2BxiNAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 1 second internally but then he swapped it over to using this Associated optic of like have an idea for a profile in hand so I\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1681840.1687960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1687960\",\n                                  \"endMs\": \"1693679\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"could then do stuff with it so oh wait I should probably boost the font size a little bit\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:07\"\n                                  },\n                                  \"trackingParams\": \"COgBENP2BxiOAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 7 seconds could then do stuff with it so oh wait I should probably boost the font size a little bit\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1687960.1693679\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1693679\",\n                                  \"endMs\": \"1698760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah let's see and so he's replacing it with this essentially where this is the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:13\"\n                                  },\n                                  \"trackingParams\": \"COcBENP2BxiPAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 13 seconds yeah let's see and so he's replacing it with this essentially where this is the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1693679.1698760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1698760\",\n                                  \"endMs\": \"1705279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"perform stuff that we don't this is another gy but we don't it's just generating a job essentially um fig out it like that and so now the lottery is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:18\"\n                                  },\n                                  \"trackingParams\": \"COYBENP2BxiQAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 18 seconds perform stuff that we don't this is another gy but we don't it's just generating a job essentially um fig out it like that and so now the lottery is\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1698760.1705279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1705279\",\n                                  \"endMs\": \"1710960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"collected a little bit more in one place it's not quite on on embedded in the whole speaker but it's kind of a little\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:25\"\n                                  },\n                                  \"trackingParams\": \"COUBENP2BxiRAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 25 seconds collected a little bit more in one place it's not quite on on embedded in the whole speaker but it's kind of a little\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1705279.1710960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1710960\",\n                                  \"endMs\": \"1716320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"bit easier to interact with because now you can both call this directly if you want to or it could have a job that just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:30\"\n                                  },\n                                  \"trackingParams\": \"COQBENP2BxiSAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 30 seconds bit easier to interact with because now you can both call this directly if you want to or it could have a job that just\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1710960.1716320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1716320\",\n                                  \"endMs\": \"1723519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this is what this does it generates a enhance all later method so you can just have it done in a job for you um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:36\"\n                                  },\n                                  \"trackingParams\": \"COMBENP2BxiTAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 36 seconds this is what this does it generates a enhance all later method so you can just have it done in a job for you um\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1716320.1723519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1723519\",\n                                  \"endMs\": \"1729039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so yeah so Adrian is doing this and then I was playing around with extending or\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:43\"\n                                  },\n                                  \"trackingParams\": \"COIBENP2BxiUAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 43 seconds so yeah so Adrian is doing this and then I was playing around with extending or\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1723519.1729039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1729039\",\n                                  \"endMs\": \"1736120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"playing around a little bit what it would look like if we do some extra things let's see what I I do uh so we step two. commits maybe we\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:49\"\n                                  },\n                                  \"trackingParams\": \"COEBENP2BxiVAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 49 seconds playing around a little bit what it would look like if we do some extra things let's see what I I do uh so we step two. commits maybe we\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1729039.1736120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1736120\",\n                                  \"endMs\": \"1743000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"should DPI a little bit removed the the banks because I didn't feel like I did a whole bunch and I tried to split it up\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:56\"\n                                  },\n                                  \"trackingParams\": \"COABENP2BxiWAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 56 seconds should DPI a little bit removed the the banks because I didn't feel like I did a whole bunch and I tried to split it up\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1736120.1743000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1743000\",\n                                  \"endMs\": \"1748760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so we have several jobs as supposed to one oh this is also super small font set let's see what happens can I bump this a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:03\"\n                                  },\n                                  \"trackingParams\": \"CN8BENP2BxiXAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 3 seconds so we have several jobs as supposed to one oh this is also super small font set let's see what happens can I bump this a\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1743000.1748760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1748760\",\n                                  \"endMs\": \"1755200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"little bit tried to play around with a different name if we just thought of this as like having a general profile subject and do because it's it's trying\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:08\"\n                                  },\n                                  \"trackingParams\": \"CN4BENP2BxiYAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 8 seconds little bit tried to play around with a different name if we just thought of this as like having a general profile subject and do because it's it's trying\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1748760.1755200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1755200\",\n                                  \"endMs\": \"1761360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"to pull data from like GitHub or blue sky for these speaker Pages essentially\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:15\"\n                                  },\n                                  \"trackingParams\": \"CN0BENP2BxiZAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 15 seconds to pull data from like GitHub or blue sky for these speaker Pages essentially\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1755200.1761360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1761360\",\n                                  \"endMs\": \"1767440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um yeah it's playing around with naming so it's not doing a bunch and I think I had some things I forgot because I kind\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:21\"\n                                  },\n                                  \"trackingParams\": \"CNwBENP2BxiaAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 21 seconds um yeah it's playing around with naming so it's not doing a bunch and I think I had some things I forgot because I kind\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1761360.1767440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1767440\",\n                                  \"endMs\": \"1773080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of t this yeah that was one error thing uh let's see also got to remember\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:27\"\n                                  },\n                                  \"trackingParams\": \"CNsBENP2BxibAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 27 seconds of t this yeah that was one error thing uh let's see also got to remember\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1767440.1773080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1773080\",\n                                  \"endMs\": \"1778120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"to rename it so what else are we doing okay wa this so this is a whole other\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:33\"\n                                  },\n                                  \"trackingParams\": \"CNoBENP2BxicAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 33 seconds to rename it so what else are we doing okay wa this so this is a whole other\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1773080.1778120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1778120\",\n                                  \"endMs\": \"1783200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"thing I was playing around with like a a wrapper around they're using mini sky\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:38\"\n                                  },\n                                  \"trackingParams\": \"CNkBENP2BxidAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 38 seconds thing I was playing around with like a a wrapper around they're using mini sky\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1778120.1783200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1783200\",\n                                  \"endMs\": \"1788360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and so I'm playing around with a lightweight wrapper for it so you can then add some extra domain methods to it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:43\"\n                                  },\n                                  \"trackingParams\": \"CNgBENP2BxieAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 43 seconds and so I'm playing around with a lightweight wrapper for it so you can then add some extra domain methods to it\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1783200.1788360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1788360\",\n                                  \"endMs\": \"1794799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so this is also kind of weird but it just simplified some stuff in the yeah you can see we're leaking less data in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:48\"\n                                  },\n                                  \"trackingParams\": \"CNcBENP2BxifAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 48 seconds so this is also kind of weird but it just simplified some stuff in the yeah you can see we're leaking less data in\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1788360.1794799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1794799\",\n                                  \"endMs\": \"1800159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the speaker op itself so now we can do like have this blue sky profile metadata\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:54\"\n                                  },\n                                  \"trackingParams\": \"CNYBENP2BxigAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 54 seconds the speaker op itself so now we can do like have this blue sky profile metadata\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1794799.1800159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1800159\",\n                                  \"endMs\": \"1806640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"using the blue sky this this external wer for the yeah so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:00\"\n                                  },\n                                  \"trackingParams\": \"CNUBENP2BxihAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes using the blue sky this this external wer for the yeah so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1800159.1806640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1806640\",\n                                  \"endMs\": \"1814279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"now I'm calling I'm I'm read sorry what is that the yeah blue sky here so it's being set\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:06\"\n                                  },\n                                  \"trackingParams\": \"CNQBENP2BxiiAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 6 seconds now I'm calling I'm I'm read sorry what is that the yeah blue sky here so it's being set\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1806640.1814279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1814279\",\n                                  \"endMs\": \"1819519\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"up here let's see oh there's a bunch of comments can I them yeah so I'm assigning it here and then I'm doing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:14\"\n                                  },\n                                  \"trackingParams\": \"CNMBENP2BxijAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 14 seconds up here let's see oh there's a bunch of comments can I them yeah so I'm assigning it here and then I'm doing\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1814279.1819519\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1819519\",\n                                  \"endMs\": \"1825320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"another Ruby thing I don't think we have time to go it but uh so um and doing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:19\"\n                                  },\n                                  \"trackingParams\": \"CNIBENP2BxikAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 19 seconds another Ruby thing I don't think we have time to go it but uh so um and doing\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1819519.1825320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1825320\",\n                                  \"endMs\": \"1831120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"some extra things around this but it's basically just to get and we're assigning it to an\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:25\"\n                                  },\n                                  \"trackingParams\": \"CNEBENP2BxilAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 25 seconds some extra things around this but it's basically just to get and we're assigning it to an\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1825320.1831120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1831120\",\n                                  \"endMs\": \"1837240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"instance of this delegate class as well so it's a whole lot of safety yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:31\"\n                                  },\n                                  \"trackingParams\": \"CNABENP2BximAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 31 seconds instance of this delegate class as well so it's a whole lot of safety yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1831120.1837240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1837240\",\n                                  \"endMs\": \"1844320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"exactly yeah yeah uh it's kind of it's kind of funny because reminder of it's kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:37\"\n                                  },\n                                  \"trackingParams\": \"CM8BENP2BxinAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 37 seconds exactly yeah yeah uh it's kind of it's kind of funny because reminder of it's kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1837240.1844320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1844320\",\n                                  \"endMs\": \"1849880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh similar to what you're doing with extend self because I'm assigning it to an instance of the class I'm defining in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:44\"\n                                  },\n                                  \"trackingParams\": \"CM4BENP2BxioAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 44 seconds uh similar to what you're doing with extend self because I'm assigning it to an instance of the class I'm defining in\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1844320.1849880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1849880\",\n                                  \"endMs\": \"1855600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the block so again I like this sort of weird stuff maybe it's a little bit too much but I just wanted to see what they\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:49\"\n                                  },\n                                  \"trackingParams\": \"CM0BENP2BxipAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 49 seconds the block so again I like this sort of weird stuff maybe it's a little bit too much but I just wanted to see what they\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1849880.1855600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1855600\",\n                                  \"endMs\": \"1862080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"thought about it and then there might be some issue with reloading and stuff so I haven't gone back to that yet but okay\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:55\"\n                                  },\n                                  \"trackingParams\": \"CMwBENP2BxiqAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 55 seconds thought about it and then there might be some issue with reloading and stuff so I haven't gone back to that yet but okay\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1855600.1862080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1862080\",\n                                  \"endMs\": \"1869279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um yeah and then you can still the idea with having delegating these two methods\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:02\"\n                                  },\n                                  \"trackingParams\": \"CMsBENP2BxirAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 2 seconds um yeah and then you can still the idea with having delegating these two methods\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1862080.1869279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1869279\",\n                                  \"endMs\": \"1876399\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"back to the the class instances that you can have because we're Sig signing it to an instance so if you delegate back to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:09\"\n                                  },\n                                  \"trackingParams\": \"CMoBENP2BxisAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 9 seconds back to the the class instances that you can have because we're Sig signing it to an instance so if you delegate back to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1869279.1876399\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1876399\",\n                                  \"endMs\": \"1882639\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the class you can then still generate other clients off of this but you can still have a nicer API where you can just call it on this constant so you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:16\"\n                                  },\n                                  \"trackingParams\": \"CMkBENP2BxitAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 16 seconds the class you can then still generate other clients off of this but you can still have a nicer API where you can just call it on this constant so you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1876399.1882639\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1882639\",\n                                  \"endMs\": \"1889120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"have the general CL like client I hope that makes sense but uh yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:22\"\n                                  },\n                                  \"trackingParams\": \"CMgBENP2BxiuAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 22 seconds have the general CL like client I hope that makes sense but uh yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1882639.1889120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1889120\",\n                                  \"endMs\": \"1895720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"online deleted oh that's the uh yeah it was deleted cool okay so that was a whole\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:29\"\n                                  },\n                                  \"trackingParams\": \"CMcBENP2BxivAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 29 seconds online deleted oh that's the uh yeah it was deleted cool okay so that was a whole\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1889120.1895720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1895720\",\n                                  \"endMs\": \"1901320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"lot of tangent uh let's see what is there anything else we want to show in here load\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:35\"\n                                  },\n                                  \"trackingParams\": \"CMYBENP2BxiwAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 35 seconds lot of tangent uh let's see what is there anything else we want to show in here load\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1895720.1901320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1901320\",\n                                  \"endMs\": \"1907919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"please oh and then there's a testing re written and then I was fiddling around I didn't think I'd push that let's see\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:41\"\n                                  },\n                                  \"trackingParams\": \"CMUBENP2BxixAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 41 seconds please oh and then there's a testing re written and then I was fiddling around I didn't think I'd push that let's see\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1901320.1907919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1907919\",\n                                  \"endMs\": \"1915279\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah I was playing around some other stuff too this is a whole lot of but now this is now we're going deep into T I don't think there's anymore uh let's see\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:47\"\n                                  },\n                                  \"trackingParams\": \"CMQBENP2BxiyAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 47 seconds yeah I was playing around some other stuff too this is a whole lot of but now this is now we're going deep into T I don't think there's anymore uh let's see\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1907919.1915279\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1915279\",\n                                  \"endMs\": \"1920799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh anything else so we in the last one that was the last one okay let's let's skip this part for now um this is the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:55\"\n                                  },\n                                  \"trackingParams\": \"CMMBENP2BxizAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 55 seconds uh anything else so we in the last one that was the last one okay let's let's skip this part for now um this is the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1915279.1920799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1920799\",\n                                  \"endMs\": \"1926639\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"other part okay so do we want to go to I think we want to go okay so let's wrap\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:00\"\n                                  },\n                                  \"trackingParams\": \"CMIBENP2Bxi0AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes other part okay so do we want to go to I think we want to go okay so let's wrap\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1920799.1926639\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1926639\",\n                                  \"endMs\": \"1931679\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"up this part now and then I want to go to another one yeah so I just thought it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:06\"\n                                  },\n                                  \"trackingParams\": \"CMEBENP2Bxi1AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 6 seconds up this part now and then I want to go to another one yeah so I just thought it\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1926639.1931679\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1931679\",\n                                  \"endMs\": \"1937039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"was interesting Adrian was like oh I kind of like what this looks like when you're using it and so far so take it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:11\"\n                                  },\n                                  \"trackingParams\": \"CMABENP2Bxi2AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 11 seconds was interesting Adrian was like oh I kind of like what this looks like when you're using it and so far so take it\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1931679.1937039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1937039\",\n                                  \"endMs\": \"1944799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"for it it's worth um let's see so another thing I've been playing around with is this thing called Oaken where in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:17\"\n                                  },\n                                  \"trackingParams\": \"CL8BENP2Bxi3AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 17 seconds for it it's worth um let's see so another thing I've been playing around with is this thing called Oaken where in\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1937039.1944799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1944799\",\n                                  \"endMs\": \"1951799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"rail saps typically when people trying to set up their test data they're usually either using fixtures or factory poot and I've worked on systems to use\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:24\"\n                                  },\n                                  \"trackingParams\": \"CL4BENP2Bxi4AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 24 seconds rail saps typically when people trying to set up their test data they're usually either using fixtures or factory poot and I've worked on systems to use\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1944799.1951799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1951799\",\n                                  \"endMs\": \"1958360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"kind of one or the other where factories will kind of optimize for isolation in a way so that's kind of nice when you start out and everything but you end up\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:31\"\n                                  },\n                                  \"trackingParams\": \"CL0BENP2Bxi5AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 31 seconds kind of one or the other where factories will kind of optimize for isolation in a way so that's kind of nice when you start out and everything but you end up\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1951799.1958360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1958360\",\n                                  \"endMs\": \"1965039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"rebuilding the entire world and I found it difficult to work with over time because it's like oh I'm putting these five factories together and I can make\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:38\"\n                                  },\n                                  \"trackingParams\": \"CLwBENP2Bxi6AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 38 seconds rebuilding the entire world and I found it difficult to work with over time because it's like oh I'm putting these five factories together and I can make\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1958360.1965039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1965039\",\n                                  \"endMs\": \"1970320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the test pass but I don't know what's happening because everything is kind of anonymous and regenerated but then on\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:45\"\n                                  },\n                                  \"trackingParams\": \"CLsBENP2Bxi7AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 45 seconds the test pass but I don't know what's happening because everything is kind of anonymous and regenerated but then on\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1965039.1970320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1970320\",\n                                  \"endMs\": \"1975880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the fixture side you end up with I should show this to you in the code exact because I've actually set it up in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:50\"\n                                  },\n                                  \"trackingParams\": \"CLoBENP2Bxi8AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 50 seconds the fixture side you end up with I should show this to you in the code exact because I've actually set it up in\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1970320.1975880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1975880\",\n                                  \"endMs\": \"1981080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"here okay there's a little bit context to work on here let's see where is it in the test\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:55\"\n                                  },\n                                  \"trackingParams\": \"CLkBENP2Bxi9AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 55 seconds here okay there's a little bit context to work on here let's see where is it in the test\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1975880.1981080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1981080\",\n                                  \"endMs\": \"1986840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"ony uh where is it and test fixtures yeah so what happens where if you use\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:01\"\n                                  },\n                                  \"trackingParams\": \"CLgBENP2Bxi-AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 1 second ony uh where is it and test fixtures yeah so what happens where if you use\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1981080.1986840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1986840\",\n                                  \"endMs\": \"1993240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"fixtures you have to do like one one uh file per table so you have an account\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:06\"\n                                  },\n                                  \"trackingParams\": \"CLcBENP2Bxi_AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 6 seconds fixtures you have to do like one one uh file per table so you have an account\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1986840.1993240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1993240\",\n                                  \"endMs\": \"1999240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"table you do one file forat and start building up like an object graph essentially so then you can have things\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:13\"\n                                  },\n                                  \"trackingParams\": \"CLYBENP2BxjAAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 13 seconds table you do one file forat and start building up like an object graph essentially so then you can have things\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1993240.1999240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1999240\",\n                                  \"endMs\": \"2005799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that interact on this like users where you can have a specific user and then it's going pointing back to the account\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:19\"\n                                  },\n                                  \"trackingParams\": \"CLUBENP2BxjBAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 19 seconds that interact on this like users where you can have a specific user and then it's going pointing back to the account\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.1999240.2005799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2005799\",\n                                  \"endMs\": \"2010919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and so you see over here on the I can't make this can I make this side lger I don't know why I can't do that but you'd\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:25\"\n                                  },\n                                  \"trackingParams\": \"CLQBENP2BxjCAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 25 seconds and so you see over here on the I can't make this can I make this side lger I don't know why I can't do that but you'd\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2005799.2010919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2010919\",\n                                  \"endMs\": \"2017120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"have to like go through all these different files for these there isn't really a ton of associations in here but\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:30\"\n                                  },\n                                  \"trackingParams\": \"CLMBENP2BxjDAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 30 seconds have to like go through all these different files for these there isn't really a ton of associations in here but\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2010919.2017120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2017120\",\n                                  \"endMs\": \"2023000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you still have to throw through a whole bunch of them to see what's going on in here um and that's just for five or six\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:37\"\n                                  },\n                                  \"trackingParams\": \"CLIBENP2BxjEAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 37 seconds you still have to throw through a whole bunch of them to see what's going on in here um and that's just for five or six\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2017120.2023000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2023000\",\n                                  \"endMs\": \"2031159\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"different associations but in a relap it's going to be a lot larger so it's kind of difficult to figure out what's going on but what I find that's kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:43\"\n                                  },\n                                  \"trackingParams\": \"CLEBENP2BxjFAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 43 seconds different associations but in a relap it's going to be a lot larger so it's kind of difficult to figure out what's going on but what I find that's kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2023000.2031159\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2031159\",\n                                  \"endMs\": \"2036240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what I like about fixtures is that there's an attempt to do a little bit more of a storytelling aspect so you can\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:51\"\n                                  },\n                                  \"trackingParams\": \"CLABENP2BxjGAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 51 seconds what I like about fixtures is that there's an attempt to do a little bit more of a storytelling aspect so you can\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2031159.2036240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2036240\",\n                                  \"endMs\": \"2042200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"kind of see what the object graph is the only problem is you have to construct it yourself and going through all these\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:56\"\n                                  },\n                                  \"trackingParams\": \"CK8BENP2BxjHAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 56 seconds kind of see what the object graph is the only problem is you have to construct it yourself and going through all these\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2036240.2042200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2042200\",\n                                  \"endMs\": \"2050358\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"files so it's like kind of aror prone so I was curious to see what that would look like to change that up so have I I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:02\"\n                                  },\n                                  \"trackingParams\": \"CK4BENP2BxjIAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 2 seconds files so it's like kind of aror prone so I was curious to see what that would look like to change that up so have I I\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2042200.2050358\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2050359\",\n                                  \"endMs\": \"2056398\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"put that in a rem me let's see okay that's kind of big let's see so here's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:10\"\n                                  },\n                                  \"trackingParams\": \"CK0BENP2BxjJAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 10 seconds put that in a rem me let's see okay that's kind of big let's see so here's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2050359.2056398\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2056399\",\n                                  \"endMs\": \"2063200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the alternative that I'm trying to do I'm actually trying to start out from seeds as well so you can kind of set up\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:16\"\n                                  },\n                                  \"trackingParams\": \"CKwBENP2BxjKAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 16 seconds the alternative that I'm trying to do I'm actually trying to start out from seeds as well so you can kind of set up\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2056399.2063200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2063200\",\n                                  \"endMs\": \"2069320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"your development data and then you reuse that in test so you're sharing the same data across to hopefully the idea is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:23\"\n                                  },\n                                  \"trackingParams\": \"CKsBENP2BxjLAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 23 seconds your development data and then you reuse that in test so you're sharing the same data across to hopefully the idea is\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2063200.2069320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2069320\",\n                                  \"endMs\": \"2074638\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that then the data you see in your browser is then the same data you test with so that it's easier for newcomers\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:29\"\n                                  },\n                                  \"trackingParams\": \"CKoBENP2BxjMAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 29 seconds that then the data you see in your browser is then the same data you test with so that it's easier for newcomers\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2069320.2074638\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2074639\",\n                                  \"endMs\": \"2080560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"to figure out what's going on in an app and you can kind of see how the optic graph is built up you can see the root\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:34\"\n                                  },\n                                  \"trackingParams\": \"CKkBENP2BxjNAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 34 seconds to figure out what's going on in an app and you can kind of see how the optic graph is built up you can see the root\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2074639.2080560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2080560\",\n                                  \"endMs\": \"2086398\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"level model like an account for instance and then what starts being built on top of that the next level ones like users\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:40\"\n                                  },\n                                  \"trackingParams\": \"CKgBENP2BxjOAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 40 seconds level model like an account for instance and then what starts being built on top of that the next level ones like users\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2080560.2086398\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2086399\",\n                                  \"endMs\": \"2093398\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"they're attached to uh the account here you can have users on multiple accounts and how I sketch this up um and from\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:46\"\n                                  },\n                                  \"trackingParams\": \"CKcBENP2BxjPAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 46 seconds they're attached to uh the account here you can have users on multiple accounts and how I sketch this up um and from\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2086399.2093398\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2093399\",\n                                  \"endMs\": \"2098400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then on you could start setting up the next level models from that where you didn't oh now I have Main just you know\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:53\"\n                                  },\n                                  \"trackingParams\": \"CKYBENP2BxjQAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 53 seconds then on you could start setting up the next level models from that where you didn't oh now I have Main just you know\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2093399.2098400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2098400\",\n                                  \"endMs\": \"2104040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a bogus one of like running a donut shop or whatever so then you have a menu and you have menu items where you can then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:58\"\n                                  },\n                                  \"trackingParams\": \"CKUBENP2BxjRAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 58 seconds a bogus one of like running a donut shop or whatever so then you have a menu and you have menu items where you can then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2098400.2104040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2104040\",\n                                  \"endMs\": \"2109480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"put a price on it and so forth and you create some ex users that then build orders on that so you keep building it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:04\"\n                                  },\n                                  \"trackingParams\": \"CKQBENP2BxjSAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 4 seconds put a price on it and so forth and you create some ex users that then build orders on that so you keep building it\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2104040.2109480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2109480\",\n                                  \"endMs\": \"2115560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"up bit by bit and so you could have this file that's meant to be more like almost\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:09\"\n                                  },\n                                  \"trackingParams\": \"CKMBENP2BxjTAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 9 seconds up bit by bit and so you could have this file that's meant to be more like almost\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2109480.2115560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2115560\",\n                                  \"endMs\": \"2121440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like the routes file is which just going longer vertically um and that's kind of okay\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:15\"\n                                  },\n                                  \"trackingParams\": \"CKIBENP2BxjUAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 15 seconds like the routes file is which just going longer vertically um and that's kind of okay\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2115560.2121440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2121440\",\n                                  \"endMs\": \"2128119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"because you're trying to tell a bit of a story of how things are built up so that's sort of the idea um let's see\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:21\"\n                                  },\n                                  \"trackingParams\": \"CKEBENP2BxjVAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 21 seconds because you're trying to tell a bit of a story of how things are built up so that's sort of the idea um let's see\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2121440.2128119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2128119\",\n                                  \"endMs\": \"2134040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"else I want to do and then there's bunch of stuff I'm trying to figure out with like default attributes so you could have them kind of globally where you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:28\"\n                                  },\n                                  \"trackingParams\": \"CKABENP2BxjWAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 28 seconds else I want to do and then there's bunch of stuff I'm trying to figure out with like default attributes so you could have them kind of globally where you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2128119.2134040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2134040\",\n                                  \"endMs\": \"2140960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"could then set some like default so any here would be that any object that has a name would automatically pull from this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:34\"\n                                  },\n                                  \"trackingParams\": \"CJ8BENP2BxjXAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 34 seconds could then set some like default so any here would be that any object that has a name would automatically pull from this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2134040.2140960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2140960\",\n                                  \"endMs\": \"2146000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so you don't have to put in values that you don't care about within these seats\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:40\"\n                                  },\n                                  \"trackingParams\": \"CJ4BENP2BxjYAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 40 seconds so you don't have to put in values that you don't care about within these seats\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2140960.2146000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2146000\",\n                                  \"endMs\": \"2153680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you slim it down a little bit um that's the idea and then you can also scope them to a specific table essentially um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:46\"\n                                  },\n                                  \"trackingParams\": \"CJ0BENP2BxjZAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 46 seconds you slim it down a little bit um that's the idea and then you can also scope them to a specific table essentially um\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2146000.2153680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2153680\",\n                                  \"endMs\": \"2160599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"let's see and then you can set up you can reuse the same data in your tests essentially so you can have what's the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:53\"\n                                  },\n                                  \"trackingParams\": \"CJwBENP2BxjaAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 53 seconds let's see and then you can set up you can reuse the same data in your tests essentially so you can have what's the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2153680.2160599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2160599\",\n                                  \"endMs\": \"2166440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"other thing we're doing do I mention the rspec as well okay uh let's see fixure converter installation that's the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:00\"\n                                  },\n                                  \"trackingParams\": \"CJsBENP2BxjbAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes other thing we're doing do I mention the rspec as well okay uh let's see fixure converter installation that's the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2160599.2166440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2166440\",\n                                  \"endMs\": \"2174319\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"development part what is I want to look for um let's see let's see uh oh yeah and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:06\"\n                                  },\n                                  \"trackingParams\": \"CJoBENP2BxjcAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 6 seconds development part what is I want to look for um let's see let's see uh oh yeah and\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2166440.2174319\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2174319\",\n                                  \"endMs\": \"2180079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then this stuff works with out of the box with DBC and DBC replant where you then truncate the whole what's all the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:14\"\n                                  },\n                                  \"trackingParams\": \"CJkBENP2BxjdAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 14 seconds then this stuff works with out of the box with DBC and DBC replant where you then truncate the whole what's all the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2174319.2180079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2180079\",\n                                  \"endMs\": \"2187680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"data that's in there and rerun seats essentially uh let's see\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:20\"\n                                  },\n                                  \"trackingParams\": \"CJgBENP2BxjeAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 20 seconds data that's in there and rerun seats essentially uh let's see\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2180079.2187680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2187680\",\n                                  \"endMs\": \"2193720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"set up some data there what is I was looking for I let's track out what it was\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:27\"\n                                  },\n                                  \"trackingParams\": \"CJcBENP2BxjfAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 27 seconds set up some data there what is I was looking for I let's track out what it was\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2187680.2193720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2194160\",\n                                  \"endMs\": \"2201160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um oh I think was like the final conventions where you can then have I mentioned it somewhere yeah here's where\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:34\"\n                                  },\n                                  \"trackingParams\": \"CJYBENP2BxjgAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 34 seconds um oh I think was like the final conventions where you can then have I mentioned it somewhere yeah here's where\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2194160.2201160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2201160\",\n                                  \"endMs\": \"2206400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it is so we'd look up in basically you'd start out setting this up o up in DB\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:41\"\n                                  },\n                                  \"trackingParams\": \"CJUBENP2BxjhAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 41 seconds it is so we'd look up in basically you'd start out setting this up o up in DB\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2201160.2206400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2206400\",\n                                  \"endMs\": \"2213880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"seeds instead you run this prepare block and you tell it what kind of things to seed so here Oak would look for it would\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:46\"\n                                  },\n                                  \"trackingParams\": \"CJQBENP2BxjiAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 46 seconds seeds instead you run this prepare block and you tell it what kind of things to seed so here Oak would look for it would\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2206400.2213880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2213880\",\n                                  \"endMs\": \"2220000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"start looking in DB seeds and then for what's in the current environment as well so you can have seats that are used\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:53\"\n                                  },\n                                  \"trackingParams\": \"CJMBENP2BxjjAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 53 seconds start looking in DB seeds and then for what's in the current environment as well so you can have seats that are used\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2213880.2220000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2220000\",\n                                  \"endMs\": \"2227560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"across every environment kind of and then also just for like just for test or just for development so you can split them up um so you're this one would be\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:00\"\n                                  },\n                                  \"trackingParams\": \"CJIBENP2BxjkAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes across every environment kind of and then also just for like just for test or just for development so you can split them up um so you're this one would be\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2220000.2227560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2227560\",\n                                  \"endMs\": \"2232920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"share between local and test and there's a little bit like do you want to run some of this in production potentially I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:07\"\n                                  },\n                                  \"trackingParams\": \"CJEBENP2BxjlAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 7 seconds share between local and test and there's a little bit like do you want to run some of this in production potentially I\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2227560.2232920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2232920\",\n                                  \"endMs\": \"2238280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"know some people run some seeds in produ so I still haven't figured that story out um but there's potentially where\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:12\"\n                                  },\n                                  \"trackingParams\": \"CJABENP2BxjmAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 12 seconds know some people run some seeds in produ so I still haven't figured that story out um but there's potentially where\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2232920.2238280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2238280\",\n                                  \"endMs\": \"2244920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that could some of that could maybe work um it's a little bit more experimental right now so uh let's see what's the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:18\"\n                                  },\n                                  \"trackingParams\": \"CI8BENP2BxjnAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 18 seconds that could some of that could maybe work um it's a little bit more experimental right now so uh let's see what's the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2238280.2244920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2244920\",\n                                  \"endMs\": \"2251800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"time we got uh should we try might have look through some of the code H uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:24\"\n                                  },\n                                  \"trackingParams\": \"CI4BENP2BxjoAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 24 seconds time we got uh should we try might have look through some of the code H uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2244920.2251800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2251800\",\n                                  \"endMs\": \"2257920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"maybe I wonder if this might be a little bit uh anything\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:31\"\n                                  },\n                                  \"trackingParams\": \"CI0BENP2BxjpAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 31 seconds maybe I wonder if this might be a little bit uh anything\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2251800.2257920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2258200\",\n                                  \"endMs\": \"2264680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"else oh yeah sorry yeah good good point yeah good point uh let's see that I think where did I put that test pictures\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:38\"\n                                  },\n                                  \"trackingParams\": \"CIwBENP2BxjqAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 38 seconds else oh yeah sorry yeah good good point yeah good point uh let's see that I think where did I put that test pictures\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2258200.2264680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2264680\",\n                                  \"endMs\": \"2269880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"let's close no we don't want the no here uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:44\"\n                                  },\n                                  \"trackingParams\": \"CIsBENP2BxjrAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 44 seconds let's close no we don't want the no here uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2264680.2269880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2269880\",\n                                  \"endMs\": \"2276520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"models uh yeah so basically what it is when you do what is it here so when you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:49\"\n                                  },\n                                  \"trackingParams\": \"CIoBENP2BxjsAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 49 seconds models uh yeah so basically what it is when you do what is it here so when you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2269880.2276520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2276520\",\n                                  \"endMs\": \"2283400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"do something like this where you pass in a symbol that means you're exposing on the on the on the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:56\"\n                                  },\n                                  \"trackingParams\": \"CIkBENP2BxjtAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 56 seconds do something like this where you pass in a symbol that means you're exposing on the on the on the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2276520.2283400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2283400\",\n                                  \"endMs\": \"2290800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"testing side you can do accounts. casers donuts for instance so that's what this is doing here you refer back to them you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:03\"\n                                  },\n                                  \"trackingParams\": \"CIgBENP2BxjuAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 3 seconds testing side you can do accounts. casers donuts for instance so that's what this is doing here you refer back to them you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2283400.2290800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2290800\",\n                                  \"endMs\": \"2296280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"get them as method objects and I think will'll raise as well if you haven't defined that so you'll start throwing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:10\"\n                                  },\n                                  \"trackingParams\": \"CIcBENP2BxjvAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 10 seconds get them as method objects and I think will'll raise as well if you haven't defined that so you'll start throwing\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2290800.2296280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2296280\",\n                                  \"endMs\": \"2303880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"errors if you missed the the data object you expect somewhere um and then there's some other just other test in here yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:16\"\n                                  },\n                                  \"trackingParams\": \"CIYBENP2BxjwAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 16 seconds errors if you missed the the data object you expect somewhere um and then there's some other just other test in here yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2296280.2303880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2303880\",\n                                  \"endMs\": \"2311440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"showing you access and everything and how you can access your object and something else respond to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:23\"\n                                  },\n                                  \"trackingParams\": \"CIUBENP2BxjxAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 23 seconds showing you access and everything and how you can access your object and something else respond to\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2303880.2311440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2311440\",\n                                  \"endMs\": \"2316920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that they created in advance right s they actually created ad hoc so we're\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:31\"\n                                  },\n                                  \"trackingParams\": \"CIQBENP2BxjyAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 31 seconds that they created in advance right s they actually created ad hoc so we're\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2311440.2316920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2316920\",\n                                  \"endMs\": \"2322119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"kind of mapping them La yeah it's kind of lazy yeah can you overr some of the B\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:36\"\n                                  },\n                                  \"trackingParams\": \"CIMBENP2BxjzAiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 36 seconds kind of mapping them La yeah it's kind of lazy yeah can you overr some of the B\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2316920.2322119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2322119\",\n                                  \"endMs\": \"2329240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"which which one can you overr some of the DAT uh yeah I want to specific name\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:42\"\n                                  },\n                                  \"trackingParams\": \"CIIBENP2Bxj0AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 42 seconds which which one can you overr some of the DAT uh yeah I want to specific name\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2322119.2329240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2329240\",\n                                  \"endMs\": \"2336480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"specif yes let's see uh if I understand it correctly let's see if I have a test for that uh oh this is again the stuff I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:49\"\n                                  },\n                                  \"trackingParams\": \"CIEBENP2Bxj1AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 49 seconds specif yes let's see uh if I understand it correctly let's see if I have a test for that uh oh this is again the stuff I\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2329240.2336480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2336480\",\n                                  \"endMs\": \"2341760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"was talking about the other G where you want to point the source location back to where it was coming from so you don't\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:56\"\n                                  },\n                                  \"trackingParams\": \"CIABENP2Bxj2AiITCLPBgKPFgosDFZzMTwgdHJkwSg==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 56 seconds was talking about the other G where you want to point the source location back to where it was coming from so you don't\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2336480.2341760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2341760\",\n                                  \"endMs\": \"2347599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"end up pointing into my library but I want to show you where something was defined uh let's see what you were\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:01\"\n                                  },\n                                  \"trackingParams\": \"CH8Q0_YHGPcCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 1 second end up pointing into my library but I want to show you where something was defined uh let's see what you were\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2341760.2347599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2347599\",\n                                  \"endMs\": \"2351760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"saying let's see is this what you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:07\"\n                                  },\n                                  \"trackingParams\": \"CH4Q0_YHGPgCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 7 seconds saying let's see is this what you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2347599.2351760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2352760\",\n                                  \"endMs\": \"2359359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"mean dat qu now yeah yeah and so we're relying on so so just make clear so if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:12\"\n                                  },\n                                  \"trackingParams\": \"CH0Q0_YHGPkCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 12 seconds mean dat qu now yeah yeah and so we're relying on so so just make clear so if\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2352760.2359359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2359359\",\n                                  \"endMs\": \"2364839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you call users Casper yeah this is doing the insert no that's already been done\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:19\"\n                                  },\n                                  \"trackingParams\": \"CHwQ0_YHGPoCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 19 seconds you call users Casper yeah this is doing the insert no that's already been done\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2359359.2364839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2364839\",\n                                  \"endMs\": \"2370400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"because that's been run so basically when testing we run these the shared seeds\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:24\"\n                                  },\n                                  \"trackingParams\": \"CHsQ0_YHGPsCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 24 seconds because that's been run so basically when testing we run these the shared seeds\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2364839.2370400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2370400\",\n                                  \"endMs\": \"2376880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"before so it's run once exactly yes I forgot to mention that datase so you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:30\"\n                                  },\n                                  \"trackingParams\": \"CHoQ0_YHGPwCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 30 seconds before so it's run once exactly yes I forgot to mention that datase so you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2370400.2376880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2376880\",\n                                  \"endMs\": \"2383359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"always have yes so you're working off that consistent set of data essentially so that's loaded ahead of time and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:36\"\n                                  },\n                                  \"trackingParams\": \"CHkQ0_YHGP0CIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 36 seconds always have yes so you're working off that consistent set of data essentially so that's loaded ahead of time and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2376880.2383359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2383359\",\n                                  \"endMs\": \"2388920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"also it works with parallel testing so for each of those test databases you do we also see that so you have the same\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:43\"\n                                  },\n                                  \"trackingParams\": \"CHgQ0_YHGP4CIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 43 seconds also it works with parallel testing so for each of those test databases you do we also see that so you have the same\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2383359.2388920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2388920\",\n                                  \"endMs\": \"2393960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"data the shared data but then you can this is also relying on rail is having\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:48\"\n                                  },\n                                  \"trackingParams\": \"CHcQ0_YHGP8CIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 48 seconds data the shared data but then you can this is also relying on rail is having\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2388920.2393960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2393960\",\n                                  \"endMs\": \"2399880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"having you know transactions around test so you can still update data if you need to internally but then it doesn't it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:53\"\n                                  },\n                                  \"trackingParams\": \"CHYQ0_YHGIADIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 53 seconds having you know transactions around test so you can still update data if you need to internally but then it doesn't it\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2393960.2399880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2399880\",\n                                  \"endMs\": \"2406359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"gets rolled back afterwards yeah um I completely forgot to mention that okay glad you mentioned that there's a lot\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:59\"\n                                  },\n                                  \"trackingParams\": \"CHUQ0_YHGIEDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 59 seconds gets rolled back afterwards yeah um I completely forgot to mention that okay glad you mentioned that there's a lot\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2399880.2406359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2406359\",\n                                  \"endMs\": \"2414440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"there's a lot of tricky Parts all this stuff um but yeah I think that's kind of the the gist of it um at least what I'm\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:06\"\n                                  },\n                                  \"trackingParams\": \"CHQQ0_YHGIIDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 6 seconds there's a lot of tricky Parts all this stuff um but yeah I think that's kind of the the gist of it um at least what I'm\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2406359.2414440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2414440\",\n                                  \"endMs\": \"2420040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"trying to do um to sort of yeah go Ahad are you using this in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:14\"\n                                  },\n                                  \"trackingParams\": \"CHMQ0_YHGIMDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 14 seconds trying to do um to sort of yeah go Ahad are you using this in\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2414440.2420040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2420040\",\n                                  \"endMs\": \"2425119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"production so technically I don't have it right now but there's a few people that I know that are using it uh like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:20\"\n                                  },\n                                  \"trackingParams\": \"CHIQ0_YHGIQDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 20 seconds production so technically I don't have it right now but there's a few people that I know that are using it uh like\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2420040.2425119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2425119\",\n                                  \"endMs\": \"2433440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"there's a uh because I'm very interested to actually about some of the experience people who T that yeah so uh full\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:25\"\n                                  },\n                                  \"trackingParams\": \"CHEQ0_YHGIUDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 25 seconds there's a uh because I'm very interested to actually about some of the experience people who T that yeah so uh full\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2425119.2433440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2433440\",\n                                  \"endMs\": \"2440599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"disclaimer Thomas is a friend of mine but he's wait we should show this on the read Meer that's a little bit closer the way to render it but Thomas is really uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:33\"\n                                  },\n                                  \"trackingParams\": \"CHAQ0_YHGIYDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 33 seconds disclaimer Thomas is a friend of mine but he's wait we should show this on the read Meer that's a little bit closer the way to render it but Thomas is really uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2433440.2440599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2440599\",\n                                  \"endMs\": \"2446160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"glad about this uh he's he's really happy with it um so he swears by it for\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:40\"\n                                  },\n                                  \"trackingParams\": \"CG8Q0_YHGIcDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 40 seconds glad about this uh he's he's really happy with it um so he swears by it for\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2440599.2446160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2446160\",\n                                  \"endMs\": \"2453079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"all kinds of different stuff that he's doing with it um and he's introduced it on a client project he worked with as well where they also liked it um flipper\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:46\"\n                                  },\n                                  \"trackingParams\": \"CG4Q0_YHGIgDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 46 seconds all kinds of different stuff that he's doing with it um and he's introduced it on a client project he worked with as well where they also liked it um flipper\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2446160.2453079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2453079\",\n                                  \"endMs\": \"2458640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"was also thinking about maybe using it weirdly enough uh I got like three pool\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:53\"\n                                  },\n                                  \"trackingParams\": \"CG0Q0_YHGIkDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 53 seconds was also thinking about maybe using it weirdly enough uh I got like three pool\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2453079.2458640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2458640\",\n                                  \"endMs\": \"2465520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"requests in the past two days which hasn't really happened you can see here no it's been the past two days I have got almost no pull request on this thing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:58\"\n                                  },\n                                  \"trackingParams\": \"CGwQ0_YHGIoDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 58 seconds requests in the past two days which hasn't really happened you can see here no it's been the past two days I have got almost no pull request on this thing\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2458640.2465520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2465520\",\n                                  \"endMs\": \"2471400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and then within the the like one day before having to talk about it um I started receiving some so more people\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:05\"\n                                  },\n                                  \"trackingParams\": \"CGsQ0_YHGIsDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 5 seconds and then within the the like one day before having to talk about it um I started receiving some so more people\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2465520.2471400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2471400\",\n                                  \"endMs\": \"2477240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"are starting to use it um there's also I haven't linked it in a read me but there's you can find it on Ruby video\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:11\"\n                                  },\n                                  \"trackingParams\": \"CGoQ0_YHGIwDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 11 seconds are starting to use it um there's also I haven't linked it in a read me but there's you can find it on Ruby video\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2471400.2477240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2477240\",\n                                  \"endMs\": \"2485480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"maybe you should find that uh while we're here what was it contribute yeah let's see can I find him here\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:17\"\n                                  },\n                                  \"trackingParams\": \"CGkQ0_YHGI0DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 17 seconds maybe you should find that uh while we're here what was it contribute yeah let's see can I find him here\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2477240.2485480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2485480\",\n                                  \"endMs\": \"2491680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Julian uh oh is it not doing do I need to do the uh wait how do we find that uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:25\"\n                                  },\n                                  \"trackingParams\": \"CGgQ0_YHGI4DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 25 seconds Julian uh oh is it not doing do I need to do the uh wait how do we find that uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2485480.2491680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2491680\",\n                                  \"endMs\": \"2497079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Australia Ruby yeah Ruby uh what if we do\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:31\"\n                                  },\n                                  \"trackingParams\": \"CGcQ0_YHGI8DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 31 seconds Australia Ruby yeah Ruby uh what if we do\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2491680.2497079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2497079\",\n                                  \"endMs\": \"2502440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"open oh that's me from I did a similar one for like uh about the stuff a turkey\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:37\"\n                                  },\n                                  \"trackingParams\": \"CGYQ0_YHGJADIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 37 seconds open oh that's me from I did a similar one for like uh about the stuff a turkey\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2497079.2502440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2502440\",\n                                  \"endMs\": \"2507839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Ruby Meetup uh where was the other one there's a um there was an Australian\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:42\"\n                                  },\n                                  \"trackingParams\": \"CGUQ0_YHGJEDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 42 seconds Ruby Meetup uh where was the other one there's a um there was an Australian\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2502440.2507839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2507839\",\n                                  \"endMs\": \"2516520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Ruby Meetup where uh julan uh was was talking about this sorry oh oh yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:47\"\n                                  },\n                                  \"trackingParams\": \"CGQQ0_YHGJIDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 47 seconds Ruby Meetup where uh julan uh was was talking about this sorry oh oh yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2507839.2516520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2516520\",\n                                  \"endMs\": \"2522880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that's probably right s is that Sydney RB is it Sydney it's not Sydney right no\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:56\"\n                                  },\n                                  \"trackingParams\": \"CGMQ0_YHGJMDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 56 seconds that's probably right s is that Sydney RB is it Sydney it's not Sydney right no\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2516520.2522880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2522880\",\n                                  \"endMs\": \"2529040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's Sydney okay ah where is it I know I posted about it somewhere but um okay\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:02\"\n                                  },\n                                  \"trackingParams\": \"CGIQ0_YHGJQDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 2 seconds it's Sydney okay ah where is it I know I posted about it somewhere but um okay\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2522880.2529040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2529040\",\n                                  \"endMs\": \"2536480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"shoot speakers let's see can find it on a day let's see we can find I think we can je not found\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:09\"\n                                  },\n                                  \"trackingParams\": \"CGEQ0_YHGJUDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 9 seconds shoot speakers let's see can find it on a day let's see we can find I think we can je not found\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2529040.2536480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2536480\",\n                                  \"endMs\": \"2542200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what H we just now we're just hunting for okay what is oh we need to load ah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:16\"\n                                  },\n                                  \"trackingParams\": \"CGAQ0_YHGJYDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 16 seconds what H we just now we're just hunting for okay what is oh we need to load ah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2536480.2542200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2542200\",\n                                  \"endMs\": \"2548040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's it's lacy loader there we go okay uh where are we not there there there Julian\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:22\"\n                                  },\n                                  \"trackingParams\": \"CF8Q0_YHGJcDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 22 seconds it's it's lacy loader there we go okay uh where are we not there there there Julian\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2542200.2548040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2548040\",\n                                  \"endMs\": \"2553240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"where is it is it not on here I feel like I saw it on here somewhere there we\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:28\"\n                                  },\n                                  \"trackingParams\": \"CF4Q0_YHGJgDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 28 seconds where is it is it not on here I feel like I saw it on here somewhere there we\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2548040.2553240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2553240\",\n                                  \"endMs\": \"2559280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"go okay it's not there but Julian did a talk at the uh at an Australian Ruby\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:33\"\n                                  },\n                                  \"trackingParams\": \"CF0Q0_YHGJkDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 33 seconds go okay it's not there but Julian did a talk at the uh at an Australian Ruby\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2553240.2559280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2559280\",\n                                  \"endMs\": \"2566040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Meetup um on this as well where he was looking through it and trying to experiment with it as well um yeah and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:39\"\n                                  },\n                                  \"trackingParams\": \"CFwQ0_YHGJoDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 39 seconds Meetup um on this as well where he was looking through it and trying to experiment with it as well um yeah and\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2559280.2566040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2566040\",\n                                  \"endMs\": \"2573040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"weirdly enough like uh the download number starts shooting up after this so that was very nice um so more people are trying it out um but yeah it's still\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:46\"\n                                  },\n                                  \"trackingParams\": \"CFsQ0_YHGJsDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 46 seconds weirdly enough like uh the download number starts shooting up after this so that was very nice um so more people are trying it out um but yeah it's still\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2566040.2573040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2573040\",\n                                  \"endMs\": \"2578240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"early days because it's kind of doing a lot of things slightly differently so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:53\"\n                                  },\n                                  \"trackingParams\": \"CFoQ0_YHGJwDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 53 seconds early days because it's kind of doing a lot of things slightly differently so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2573040.2578240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2578240\",\n                                  \"endMs\": \"2586200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah I'm still I'm still kind of curious for more people to try to use it and it's a little bit more ambitious than the other stuff um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:58\"\n                                  },\n                                  \"trackingParams\": \"CFkQ0_YHGJ0DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 58 seconds yeah I'm still I'm still kind of curious for more people to try to use it and it's a little bit more ambitious than the other stuff um\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2578240.2586200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2586200\",\n                                  \"endMs\": \"2592280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah I think is that kind of What's the timing I don't remember I think we have been going for almost 40 minutes so any\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:06\"\n                                  },\n                                  \"trackingParams\": \"CFgQ0_YHGJ4DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 6 seconds yeah I think is that kind of What's the timing I don't remember I think we have been going for almost 40 minutes so any\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2586200.2592280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2592280\",\n                                  \"endMs\": \"2599119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"other questions I know I kind of went fast on some of these things but um I don't think we have time to go through the code maybe it's interesting because\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:12\"\n                                  },\n                                  \"trackingParams\": \"CFcQ0_YHGJ8DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 12 seconds other questions I know I kind of went fast on some of these things but um I don't think we have time to go through the code maybe it's interesting because\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2592280.2599119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2599119\",\n                                  \"endMs\": \"2606119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the they already SE from the test and yeah that sometimes can interfere with the T yeah that's also true so that's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:19\"\n                                  },\n                                  \"trackingParams\": \"CFYQ0_YHGKADIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 19 seconds the they already SE from the test and yeah that sometimes can interfere with the T yeah that's also true so that's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2599119.2606119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2606119\",\n                                  \"endMs\": \"2613400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that's is that you get yeah it's it's it's a hard problem\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:26\"\n                                  },\n                                  \"trackingParams\": \"CFUQ0_YHGKEDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 26 seconds that's is that you get yeah it's it's it's a hard problem\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2606119.2613400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2613400\",\n                                  \"endMs\": \"2620319\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"even if you're just using fixures that was the issue that was tough with them where that line between where you are oh that's another\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:33\"\n                                  },\n                                  \"trackingParams\": \"CFQQ0_YHGKIDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 33 seconds even if you're just using fixures that was the issue that was tough with them where that line between where you are oh that's another\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2613400.2620319\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2620319\",\n                                  \"endMs\": \"2628079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"thing I should probably show with that that's kind of wild with the stuff um but uh I trainer F but yeah that's I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:40\"\n                                  },\n                                  \"trackingParams\": \"CFMQ0_YHGKMDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 40 seconds thing I should probably show with that that's kind of wild with the stuff um but uh I trainer F but yeah that's I\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2620319.2628079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2628079\",\n                                  \"endMs\": \"2633480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"don't know how to have like convences around that yet because it's kind of a tricky problem and it's different for\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:48\"\n                                  },\n                                  \"trackingParams\": \"CFIQ0_YHGKQDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 48 seconds don't know how to have like convences around that yet because it's kind of a tricky problem and it's different for\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2628079.2633480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2633480\",\n                                  \"endMs\": \"2640000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"every app for how much do they want to share and how much do they want to like leave up to separate tests and whatnot\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:53\"\n                                  },\n                                  \"trackingParams\": \"CFEQ0_YHGKUDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 53 seconds every app for how much do they want to share and how much do they want to like leave up to separate tests and whatnot\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2633480.2640000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2640000\",\n                                  \"endMs\": \"2645599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um I was talking to someone else about this she was pointing out that it might be nice to have some of this set up for\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:00\"\n                                  },\n                                  \"trackingParams\": \"CFAQ0_YHGKYDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes um I was talking to someone else about this she was pointing out that it might be nice to have some of this set up for\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2640000.2645599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2645599\",\n                                  \"endMs\": \"2651599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"integration test where then you don't have to care about it I just I'm just signing in as this user and then I know I have some basic things set up so I can\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:05\"\n                                  },\n                                  \"trackingParams\": \"CE8Q0_YHGKcDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 5 seconds integration test where then you don't have to care about it I just I'm just signing in as this user and then I know I have some basic things set up so I can\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2645599.2651599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2651599\",\n                                  \"endMs\": \"2657079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"just run through my test there but then in unit tests you'd still want to use something like Factory but or whatever\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:11\"\n                                  },\n                                  \"trackingParams\": \"CE4Q0_YHGKgDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 11 seconds just run through my test there but then in unit tests you'd still want to use something like Factory but or whatever\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2651599.2657079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2657079\",\n                                  \"endMs\": \"2662319\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"to then build it up and I completely forgot this too because was with\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:17\"\n                                  },\n                                  \"trackingParams\": \"CE0Q0_YHGKkDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 17 seconds to then build it up and I completely forgot this too because was with\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2657079.2662319\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2662319\",\n                                  \"endMs\": \"2668119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"somebody what they were thinking and was you use pictures to make like skeleton\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:22\"\n                                  },\n                                  \"trackingParams\": \"CEwQ0_YHGKoDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 22 seconds somebody what they were thinking and was you use pictures to make like skeleton\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2662319.2668119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2668119\",\n                                  \"endMs\": \"2675359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"accounts like account with projects with tasks with PR PR Tri Tri whatever and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:28\"\n                                  },\n                                  \"trackingParams\": \"CEsQ0_YHGKsDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 28 seconds accounts like account with projects with tasks with PR PR Tri Tri whatever and\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2668119.2675359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2675359\",\n                                  \"endMs\": \"2681960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then you still use Factory B to just populate the specific domains you care about yeah because one of issue with the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:35\"\n                                  },\n                                  \"trackingParams\": \"CEoQ0_YHGKwDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 35 seconds then you still use Factory B to just populate the specific domains you care about yeah because one of issue with the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2675359.2681960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2681960\",\n                                  \"endMs\": \"2687760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"fixtures is you create let's say a task and it create a user it creates a project it creates an account it creates\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:41\"\n                                  },\n                                  \"trackingParams\": \"CEkQ0_YHGK0DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 41 seconds fixtures is you create let's say a task and it create a user it creates a project it creates an account it creates\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2681960.2687760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2687760\",\n                                  \"endMs\": \"2694920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like a building and basically the whole tree blows up you just want to say I want uncomplete the task exactly yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:47\"\n                                  },\n                                  \"trackingParams\": \"CEgQ0_YHGK4DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 47 seconds like a building and basically the whole tree blows up you just want to say I want uncomplete the task exactly yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2687760.2694920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2694920\",\n                                  \"endMs\": \"2701040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah that's that's the difficult part where and that's be different for every domain that's what I'm kind of hoping with having this like structure that's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:54\"\n                                  },\n                                  \"trackingParams\": \"CEcQ0_YHGK8DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 54 seconds yeah that's that's the difficult part where and that's be different for every domain that's what I'm kind of hoping with having this like structure that's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2694920.2701040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2701040\",\n                                  \"endMs\": \"2708280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"laid out makes it a little bit clearer of when things are added so it's like hopefully a little bit easier to not balloon that but you know it's like here\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:01\"\n                                  },\n                                  \"trackingParams\": \"CEYQ0_YHGLADIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 1 second laid out makes it a little bit clearer of when things are added so it's like hopefully a little bit easier to not balloon that but you know it's like here\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2701040.2708280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2708280\",\n                                  \"endMs\": \"2714720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you can say I have like free account paid account expire like and you have just all set up you have a users John\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:08\"\n                                  },\n                                  \"trackingParams\": \"CEUQ0_YHGLEDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 8 seconds you can say I have like free account paid account expire like and you have just all set up you have a users John\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2708280.2714720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2714720\",\n                                  \"endMs\": \"2722599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Jan what whatever and then in the test you can still use like factories to okay now TW a task for a project and I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:14\"\n                                  },\n                                  \"trackingParams\": \"CEQQ0_YHGLIDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 14 seconds Jan what whatever and then in the test you can still use like factories to okay now TW a task for a project and I\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2714720.2722599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2722599\",\n                                  \"endMs\": \"2730000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"already know there was like a project for yeah yeah exactly yeah uh what was I just before it was another was it c yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:22\"\n                                  },\n                                  \"trackingParams\": \"CEMQ0_YHGLMDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 22 seconds already know there was like a project for yeah yeah exactly yeah uh what was I just before it was another was it c yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2722599.2730000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2730000\",\n                                  \"endMs\": \"2736000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so here's another thing that's on I'm trying to blend fixures and factories a little bit together so this is kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:30\"\n                                  },\n                                  \"trackingParams\": \"CEIQ0_YHGLQDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 30 seconds so here's another thing that's on I'm trying to blend fixures and factories a little bit together so this is kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2730000.2736000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2736000\",\n                                  \"endMs\": \"2741160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"nuts too there's in Ruby there's uh you could do what is it like you do object\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:36\"\n                                  },\n                                  \"trackingParams\": \"CEEQ0_YHGLUDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 36 seconds nuts too there's in Ruby there's uh you could do what is it like you do object\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2736000.2741160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2741160\",\n                                  \"endMs\": \"2749720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and then you could do oh let's do object. new and then you could do dot uh something and then you can say\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:41\"\n                                  },\n                                  \"trackingParams\": \"CEAQ0_YHGLYDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 41 seconds and then you could do oh let's do object. new and then you could do dot uh something and then you can say\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2741160.2749720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2749720\",\n                                  \"endMs\": \"2755079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like equal to true and then it'll only be on that instance of of this object\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:49\"\n                                  },\n                                  \"trackingParams\": \"CD8Q0_YHGLcDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 49 seconds like equal to true and then it'll only be on that instance of of this object\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2749720.2755079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2755079\",\n                                  \"endMs\": \"2762640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and so that's kind of what's Happening Here where I'm grabbing since I have a reference that is like users object I can Define extra methods\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:55\"\n                                  },\n                                  \"trackingParams\": \"CD4Q0_YHGLgDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 55 seconds and so that's kind of what's Happening Here where I'm grabbing since I have a reference that is like users object I can Define extra methods\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2755079.2762640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2762640\",\n                                  \"endMs\": \"2768280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"on it and when you do this you can actually use super to go back into it so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:02\"\n                                  },\n                                  \"trackingParams\": \"CD0Q0_YHGLkDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 2 seconds on it and when you do this you can actually use super to go back into it so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2762640.2768280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2768280\",\n                                  \"endMs\": \"2775040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I'm so I'm doing and again endless method definition as well uh it's just to see whether or another works and you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:08\"\n                                  },\n                                  \"trackingParams\": \"CDwQ0_YHGLoDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 8 seconds I'm so I'm doing and again endless method definition as well uh it's just to see whether or another works and you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2768280.2775040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2775040\",\n                                  \"endMs\": \"2780240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"can make some extra helpers as well so so these are actually available within\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:15\"\n                                  },\n                                  \"trackingParams\": \"CDsQ0_YHGLsDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 15 seconds can make some extra helpers as well so so these are actually available within\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2775040.2780240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2780240\",\n                                  \"endMs\": \"2787160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"tests as well uh exposed in there so it's again a way of trying to blend it a little bit more um I'm not sure how how\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:20\"\n                                  },\n                                  \"trackingParams\": \"CDoQ0_YHGLwDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 20 seconds tests as well uh exposed in there so it's again a way of trying to blend it a little bit more um I'm not sure how how\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2780240.2787160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2787160\",\n                                  \"endMs\": \"2792640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"much I like it but it's just interesting that it kind of It kind of just worked and I don't have really to add any extra\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:27\"\n                                  },\n                                  \"trackingParams\": \"CDkQ0_YHGL0DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 27 seconds much I like it but it's just interesting that it kind of It kind of just worked and I don't have really to add any extra\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2787160.2792640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2792640\",\n                                  \"endMs\": \"2799359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"methods to it and it's called it's called Singleton methods um so you can so this is kind of the pattern it's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:32\"\n                                  },\n                                  \"trackingParams\": \"CDgQ0_YHGL4DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 32 seconds methods to it and it's called it's called Singleton methods um so you can so this is kind of the pattern it's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2792640.2799359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2799359\",\n                                  \"endMs\": \"2805440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"different from the the Singleton pattern but this is what they're called these these methods because it's on the signal\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:39\"\n                                  },\n                                  \"trackingParams\": \"CDcQ0_YHGL8DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 39 seconds different from the the Singleton pattern but this is what they're called these these methods because it's on the signal\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2799359.2805440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2805440\",\n                                  \"endMs\": \"2811359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"ton or something like that um yeah let's see what else I kind of want to show you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:45\"\n                                  },\n                                  \"trackingParams\": \"CDYQ0_YHGMADIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 45 seconds ton or something like that um yeah let's see what else I kind of want to show you\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2805440.2811359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2811359\",\n                                  \"endMs\": \"2817359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the one thing I kind of want to show I kind of want to show you just the section part here another thing I've been trying to explore is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:51\"\n                                  },\n                                  \"trackingParams\": \"CDUQ0_YHGMEDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 51 seconds the one thing I kind of want to show I kind of want to show you just the section part here another thing I've been trying to explore is\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2811359.2817359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2817359\",\n                                  \"endMs\": \"2825240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this method is purely decorative all it does is just uh it's meant to just help you carve out um like a file like this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:57\"\n                                  },\n                                  \"trackingParams\": \"CDQQ0_YHGMIDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 57 seconds this method is purely decorative all it does is just uh it's meant to just help you carve out um like a file like this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2817359.2825240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2825240\",\n                                  \"endMs\": \"2830559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"to help explain a little bit more instead of doing it in comments because lot people trying to do that with comments but it just gets lost at least\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:05\"\n                                  },\n                                  \"trackingParams\": \"CDMQ0_YHGMMDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 5 seconds to help explain a little bit more instead of doing it in comments because lot people trying to do that with comments but it just gets lost at least\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2825240.2830559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2830559\",\n                                  \"endMs\": \"2837040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"for me so this is actually not too difficult this is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:10\"\n                                  },\n                                  \"trackingParams\": \"CDIQ0_YHGMQDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 10 seconds for me so this is actually not too difficult this is\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2830559.2837040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2837040\",\n                                  \"endMs\": \"2843359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it um I'm just using all of Ruby's built-in method sytax to help do it and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:17\"\n                                  },\n                                  \"trackingParams\": \"CDEQ0_YHGMUDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 17 seconds it um I'm just using all of Ruby's built-in method sytax to help do it and\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2837040.2843359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2843359\",\n                                  \"endMs\": \"2849000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then it sort of just works so it's just meant to be purely decorative essentially but because there's so much\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:23\"\n                                  },\n                                  \"trackingParams\": \"CDAQ0_YHGMYDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 23 seconds then it sort of just works so it's just meant to be purely decorative essentially but because there's so much\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2843359.2849000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2849000\",\n                                  \"endMs\": \"2854760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"flexibility in rubies uh method signatures you can kind of get away with doing something kind of Bonkers like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:29\"\n                                  },\n                                  \"trackingParams\": \"CC8Q0_YHGMcDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 29 seconds flexibility in rubies uh method signatures you can kind of get away with doing something kind of Bonkers like\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2849000.2854760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2854760\",\n                                  \"endMs\": \"2860400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this it just sort of works so you can do your own setup for what you want like uh what is it like yeah I'm showing these\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:34\"\n                                  },\n                                  \"trackingParams\": \"CC4Q0_YHGMgDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 34 seconds this it just sort of works so you can do your own setup for what you want like uh what is it like yeah I'm showing these\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2854760.2860400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2860400\",\n                                  \"endMs\": \"2867119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"off uh like you can pass in symbols you could pass in like a keyword argument as well or whatnot for your own organization where you can just have it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:40\"\n                                  },\n                                  \"trackingParams\": \"CC0Q0_YHGMkDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 40 seconds off uh like you can pass in symbols you could pass in like a keyword argument as well or whatnot for your own organization where you can just have it\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2860400.2867119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2867119\",\n                                  \"endMs\": \"2874000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"take a block and you could Nest it deeply too because it just keeps yielding but it's still in the same scope as well um so I was kind of like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:47\"\n                                  },\n                                  \"trackingParams\": \"CCwQ0_YHGMoDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 47 seconds take a block and you could Nest it deeply too because it just keeps yielding but it's still in the same scope as well um so I was kind of like\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2867119.2874000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2874000\",\n                                  \"endMs\": \"2879960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"oh that's kind of cool that just works um but uh again don't know if I super if it's a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:54\"\n                                  },\n                                  \"trackingParams\": \"CCsQ0_YHGMsDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 54 seconds oh that's kind of cool that just works um but uh again don't know if I super if it's a\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2874000.2879960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2879960\",\n                                  \"endMs\": \"2885680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"good idea but I just thought it was cool to leverage all of that flexibility Ruby gives you out of the box and just seeing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:59\"\n                                  },\n                                  \"trackingParams\": \"CCoQ0_YHGMwDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 59 seconds good idea but I just thought it was cool to leverage all of that flexibility Ruby gives you out of the box and just seeing\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2879960.2885680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2885680\",\n                                  \"endMs\": \"2891920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what that looks like so for me it's a lot about exploring and trying to write it out first and then seeing if I like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:05\"\n                                  },\n                                  \"trackingParams\": \"CCkQ0_YHGM0DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 5 seconds what that looks like so for me it's a lot about exploring and trying to write it out first and then seeing if I like\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2885680.2891920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2891920\",\n                                  \"endMs\": \"2897440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it or not that's kind of the the point cool I think that's kind of what I had\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:11\"\n                                  },\n                                  \"trackingParams\": \"CCgQ0_YHGM4DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 11 seconds it or not that's kind of the the point cool I think that's kind of what I had\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2891920.2897440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2897440\",\n                                  \"endMs\": \"2902000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh just uh running through it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:17\"\n                                  },\n                                  \"trackingParams\": \"CCcQ0_YHGM8DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 17 seconds uh just uh running through it\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2897440.2902000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2902760\",\n                                  \"endMs\": \"2912200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"cool any other questions oh again I meod missing great uh yeah mhm well it's off topic I guess but\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:22\"\n                                  },\n                                  \"trackingParams\": \"CCYQ0_YHGNADIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 22 seconds cool any other questions oh again I meod missing great uh yeah mhm well it's off topic I guess but\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2902760.2912200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2912200\",\n                                  \"endMs\": \"2921599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"uh what happened with the comments did you just hide them and show them oh where feat F because we we saw the same\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:32\"\n                                  },\n                                  \"trackingParams\": \"CCUQ0_YHGNEDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 32 seconds uh what happened with the comments did you just hide them and show them oh where feat F because we we saw the same\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2912200.2921599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2921599\",\n                                  \"endMs\": \"2926760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"but without the comments oh did we did I did I hit that or what not I don't\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:41\"\n                                  },\n                                  \"trackingParams\": \"CCQQ0_YHGNIDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 41 seconds but without the comments oh did we did I did I hit that or what not I don't\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2921599.2926760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2926760\",\n                                  \"endMs\": \"2932880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"remember what that where it was I think I scroll up before yeah yeah I just scrolled up yeah actually one question\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:46\"\n                                  },\n                                  \"trackingParams\": \"CCMQ0_YHGNMDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 46 seconds remember what that where it was I think I scroll up before yeah yeah I just scrolled up yeah actually one question\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2926760.2932880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2932880\",\n                                  \"endMs\": \"2939160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"for the associated object yeah is there a way to have associated object that's not following the naming convention like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:52\"\n                                  },\n                                  \"trackingParams\": \"CCIQ0_YHGNQDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 52 seconds for the associated object yeah is there a way to have associated object that's not following the naming convention like\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2932880.2939160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2939160\",\n                                  \"endMs\": \"2945680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"my idea is I want to have a object which is let's say so called softer and this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:59\"\n                                  },\n                                  \"trackingParams\": \"CCEQ0_YHGNUDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 59 seconds my idea is I want to have a object which is let's say so called softer and this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2939160.2945680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2945680\",\n                                  \"endMs\": \"2951200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"is an Associated object to M it can be Associated to many classes because for\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:05\"\n                                  },\n                                  \"trackingParams\": \"CCAQ0_YHGNYDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 5 seconds is an Associated object to M it can be Associated to many classes because for\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2945680.2951200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2951200\",\n                                  \"endMs\": \"2956680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"example it deals with softing records positioning CRI like that is there a way\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:11\"\n                                  },\n                                  \"trackingParams\": \"CB8Q0_YHGNcDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 11 seconds example it deals with softing records positioning CRI like that is there a way\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2951200.2956680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2956680\",\n                                  \"endMs\": \"2962079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"because a lot of the extension logic kind of depends on the name exactly yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:16\"\n                                  },\n                                  \"trackingParams\": \"CB4Q0_YHGNgDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 16 seconds because a lot of the extension logic kind of depends on the name exactly yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2956680.2962079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2962079\",\n                                  \"endMs\": \"2967599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um I talked about it a little bit and I've tried to explore it a few times but it's kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:22\"\n                                  },\n                                  \"trackingParams\": \"CB0Q0_YHGNkDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 22 seconds um I talked about it a little bit and I've tried to explore it a few times but it's kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2962079.2967599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2967599\",\n                                  \"endMs\": \"2974200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in a way the irony is I really want the name space to be there so that to get some of that organization fraps but so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:27\"\n                                  },\n                                  \"trackingParams\": \"CBwQ0_YHGNoDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 27 seconds in a way the irony is I really want the name space to be there so that to get some of that organization fraps but so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2967599.2974200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2974200\",\n                                  \"endMs\": \"2981240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's kind of a little bit tricky yeah because there is a lot of potential for those being like organizing things\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:34\"\n                                  },\n                                  \"trackingParams\": \"CBsQ0_YHGNsDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 34 seconds it's kind of a little bit tricky yeah because there is a lot of potential for those being like organizing things\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2974200.2981240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2981240\",\n                                  \"endMs\": \"2987559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"because for example has one basically is one of these things yeah but it's not going to be like again one hack you can\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:41\"\n                                  },\n                                  \"trackingParams\": \"CBoQ0_YHGNwDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 41 seconds because for example has one basically is one of these things yeah but it's not going to be like again one hack you can\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2981240.2987559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2987559\",\n                                  \"endMs\": \"2993839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"do is you can just create like a s object and just inherit it yeah yeah yeah well It's tricky because the the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:47\"\n                                  },\n                                  \"trackingParams\": \"CBkQ0_YHGN0DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 47 seconds do is you can just create like a s object and just inherit it yeah yeah yeah well It's tricky because the the\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2987559.2993839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2993839\",\n                                  \"endMs\": \"3001400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the way I'm defining it on what is like these I'm using inherited to like you can say publisher just includeed and or\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:53\"\n                                  },\n                                  \"trackingParams\": \"CBgQ0_YHGN4DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 53 seconds the way I'm defining it on what is like these I'm using inherited to like you can say publisher just includeed and or\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.2993839.3001400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3001400\",\n                                  \"endMs\": \"3007799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you can say what you you can do some you can your object yeah that was one thing we were\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:01\"\n                                  },\n                                  \"trackingParams\": \"CBcQ0_YHGN8DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 1 second you can say what you you can do some you can your object yeah that was one thing we were\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3001400.3007799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3007799\",\n                                  \"endMs\": \"3013040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"talking about so what you were talking about was doing well I'm just going to keep using the use said sort of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:07\"\n                                  },\n                                  \"trackingParams\": \"CBYQ0_YHGOADIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 7 seconds talking about so what you were talking about was doing well I'm just going to keep using the use said sort of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3007799.3013040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3013040\",\n                                  \"endMs\": \"3018520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"publisher yeah you could try to do no actually it would be it would probably be like module publisher or something\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:13\"\n                                  },\n                                  \"trackingParams\": \"CBUQ0_YHGOEDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 13 seconds publisher yeah you could try to do no actually it would be it would probably be like module publisher or something\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3013040.3018520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3018520\",\n                                  \"endMs\": \"3024119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and then maybe that's a concern or what not and then your and then you have for each of the objects you want to actually\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:18\"\n                                  },\n                                  \"trackingParams\": \"CBQQ0_YHGOIDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 18 seconds and then maybe that's a concern or what not and then your and then you have for each of the objects you want to actually\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3018520.3024119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3024119\",\n                                  \"endMs\": \"3030799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"support you have to do that and then do include the top level version yeah it's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:24\"\n                                  },\n                                  \"trackingParams\": \"CBMQ0_YHGOMDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 24 seconds support you have to do that and then do include the top level version yeah it's\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3024119.3030799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3030799\",\n                                  \"endMs\": \"3040000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a little bit tricky yeah or maybe you do like associate object like maybe you do like post publisher equal to Associated\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:30\"\n                                  },\n                                  \"trackingParams\": \"CBIQ0_YHGOQDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 30 seconds a little bit tricky yeah or maybe you do like associate object like maybe you do like post publisher equal to Associated\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3030799.3040000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3040000\",\n                                  \"endMs\": \"3047000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"object from right right yeah yeah yeah yeah maybe something like that yeah that like Library stuff like it can be very\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:40\"\n                                  },\n                                  \"trackingParams\": \"CBEQ0_YHGOUDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 40 seconds object from right right yeah yeah yeah yeah maybe something like that yeah that like Library stuff like it can be very\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3040000.3047000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3047000\",\n                                  \"endMs\": \"3052920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"useful to kind of replace something on somewere yeah because with the extensions you can and the call you can\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:47\"\n                                  },\n                                  \"trackingParams\": \"CBAQ0_YHGOYDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 47 seconds useful to kind of replace something on somewere yeah because with the extensions you can and the call you can\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3047000.3052920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3052920\",\n                                  \"endMs\": \"3058400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"do a lot of like okay I want something to like to publish in or trashing or\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:52\"\n                                  },\n                                  \"trackingParams\": \"CA8Q0_YHGOcDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 52 seconds do a lot of like okay I want something to like to publish in or trashing or\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3052920.3058400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3058400\",\n                                  \"endMs\": \"3063799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah yeah for sure yeah yeah that's interesting I'll have to think about that yeah yeah I like the idea of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:58\"\n                                  },\n                                  \"trackingParams\": \"CA4Q0_YHGOgDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 58 seconds yeah yeah for sure yeah yeah that's interesting I'll have to think about that yeah yeah I like the idea of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3058400.3063799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3063799\",\n                                  \"endMs\": \"3070400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"assigning that okay um was any else wanted to show with this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:03\"\n                                  },\n                                  \"trackingParams\": \"CA0Q0_YHGOkDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 3 seconds assigning that okay um was any else wanted to show with this\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3063799.3070400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3070400\",\n                                  \"endMs\": \"3075520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"um yeah but that's some of the stuff I've been exploring and I yeah I kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:10\"\n                                  },\n                                  \"trackingParams\": \"CAwQ0_YHGOoDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 10 seconds um yeah but that's some of the stuff I've been exploring and I yeah I kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3070400.3075520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3075520\",\n                                  \"endMs\": \"3083359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like where some of this heading and now people are starting to pick it up a little bit so that's interesting to see what they think about it um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:15\"\n                                  },\n                                  \"trackingParams\": \"CAsQ0_YHGOsDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 15 seconds like where some of this heading and now people are starting to pick it up a little bit so that's interesting to see what they think about it um\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3075520.3083359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3083359\",\n                                  \"endMs\": \"3089640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah cool I think that's kind of on a hat any other\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:23\"\n                                  },\n                                  \"trackingParams\": \"CAoQ0_YHGOwDIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 23 seconds yeah cool I think that's kind of on a hat any other\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3083359.3089640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3089960\",\n                                  \"endMs\": \"3098079\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"questions cool perfect hope it wasn't too overwhelming I kind of like just like diving in and like uh I I kind of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:29\"\n                                  },\n                                  \"trackingParams\": \"CAkQ0_YHGO0DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 29 seconds questions cool perfect hope it wasn't too overwhelming I kind of like just like diving in and like uh I I kind of\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3089960.3098079\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3098079\",\n                                  \"endMs\": \"3103640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like throwing people into the deep end and then once you get used to being blasted with source files it's like oh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:38\"\n                                  },\n                                  \"trackingParams\": \"CAgQ0_YHGO4DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 38 seconds like throwing people into the deep end and then once you get used to being blasted with source files it's like oh\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3098079.3103640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3103640\",\n                                  \"endMs\": \"3111280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this is not too bad and like well I mean you're not going to understand everything at first go but just uh comes a lot easier so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:43\"\n                                  },\n                                  \"trackingParams\": \"CAcQ0_YHGO8DIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 43 seconds this is not too bad and like well I mean you're not going to understand everything at first go but just uh comes a lot easier so\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3103640.3111280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3111280\",\n                                  \"endMs\": \"3115280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah cool\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:51\"\n                                  },\n                                  \"trackingParams\": \"CAYQ0_YHGPADIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 51 seconds yeah cool\"\n                                    }\n                                  },\n                                  \"targetId\": \"Md90cwnmGc8.CgNhc3ISAmVu.3111280.3115280\"\n                                }\n                              }\n                            ],\n                            \"noResultLabel\": {\n                              \"runs\": [\n                                {\n                                  \"text\": \"No results found\"\n                                }\n                              ]\n                            },\n                            \"retryLabel\": {\n                              \"runs\": [\n                                {\n                                  \"text\": \"TAP TO RETRY\"\n                                }\n                              ]\n                            },\n                            \"touchCaptionsEnabled\": false\n                          }\n                        },\n                        \"footer\": {\n                          \"transcriptFooterRenderer\": {\n                            \"languageMenu\": {\n                              \"sortFilterSubMenuRenderer\": {\n                                \"subMenuItems\": [\n                                  {\n                                    \"title\": \"English (auto-generated)\",\n                                    \"selected\": true,\n                                    \"continuation\": {\n                                      \"reloadContinuationData\": {\n                                        \"continuation\": \"CgtNZDkwY3dubUdjOBISQ2dOaGMzSVNBbVZ1R2dBJTNEGAEqM2VuZ2FnZW1lbnQtcGFuZWwtc2VhcmNoYWJsZS10cmFuc2NyaXB0LXNlYXJjaC1wYW5lbDAAOABAAA%3D%3D\",\n                                        \"clickTrackingParams\": \"CAUQxqYCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\"\n                                      }\n                                    },\n                                    \"trackingParams\": \"CAQQ48AHGAAiEwizwYCjxYKLAxWczE8IHRyZMEo=\"\n                                  }\n                                ],\n                                \"trackingParams\": \"CAMQgdoEIhMIs8GAo8WCiwMVnMxPCB0cmTBK\"\n                              }\n                            }\n                          }\n                        },\n                        \"trackingParams\": \"CAIQ8bsCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\",\n                        \"targetId\": \"engagement-panel-searchable-transcript-search-panel\"\n                      }\n                    }\n                  }\n                }\n              }\n            }\n          ],\n          \"trackingParams\": \"CAAQw7wCIhMIs8GAo8WCiwMVnMxPCB0cmTBK\"\n        }\n  recorded_at: Sun, 19 Jan 2025 19:41:26 GMT\nrecorded_with: VCR 6.3.1\n"
  },
  {
    "path": "test/vcr_cassettes/youtube_duration.yml",
    "content": "---\nhttp_interactions:\n  - request:\n      method: get\n      uri: https://youtube.googleapis.com/youtube/v3/videos?id=9LfmrkyP81M&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&part=contentDetails\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 200\n        message: OK\n      headers:\n        Content-Type:\n          - application/json; charset=UTF-8\n        Vary:\n          - Origin\n          - Referer\n          - X-Origin\n        Date:\n          - Thu, 28 Aug 2025 21:03:02 GMT\n        Server:\n          - scaffolding on HTTPServer2\n        X-Xss-Protection:\n          - \"0\"\n        X-Frame-Options:\n          - SAMEORIGIN\n        X-Content-Type-Options:\n          - nosniff\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n        Transfer-Encoding:\n          - chunked\n      body:\n        encoding: ASCII-8BIT\n        string: |\n          {\n            \"kind\": \"youtube#videoListResponse\",\n            \"etag\": \"k4Tckuzp6iqi-TbYt9gLMfjwars\",\n            \"items\": [\n              {\n                \"kind\": \"youtube#video\",\n                \"etag\": \"sb9PwS-6NnHvqRCQzbV2Yy8NjAA\",\n                \"id\": \"9LfmrkyP81M\",\n                \"contentDetails\": {\n                  \"duration\": \"PT1H1M17S\",\n                  \"dimension\": \"2d\",\n                  \"definition\": \"hd\",\n                  \"caption\": \"true\",\n                  \"licensedContent\": true,\n                  \"contentRating\": {},\n                  \"projection\": \"rectangular\"\n                }\n              }\n            ],\n            \"pageInfo\": {\n              \"totalResults\": 1,\n              \"resultsPerPage\": 1\n            }\n          }\n    recorded_at: Thu, 28 Aug 2025 21:03:02 GMT\nrecorded_with: VCR 6.3.1\n"
  },
  {
    "path": "test/vcr_cassettes/youtube_statistics.yml",
    "content": "---\nhttp_interactions:\n  - request:\n      method: get\n      uri: https://youtube.googleapis.com/youtube/v3/videos?id=9LfmrkyP81M&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&part=statistics\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 200\n        message: OK\n      headers:\n        Content-Type:\n          - application/json; charset=UTF-8\n        Vary:\n          - Origin\n          - Referer\n          - X-Origin\n        Date:\n          - Mon, 26 Jun 2023 21:12:38 GMT\n        Server:\n          - scaffolding on HTTPServer2\n        Cache-Control:\n          - private\n        X-Xss-Protection:\n          - \"0\"\n        X-Frame-Options:\n          - SAMEORIGIN\n        X-Content-Type-Options:\n          - nosniff\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n        Transfer-Encoding:\n          - chunked\n      body:\n        encoding: ASCII-8BIT\n        string: |\n          {\n            \"kind\": \"youtube#videoListResponse\",\n            \"etag\": \"loxveJrTQG9IDJQjJDNWVptwhwU\",\n            \"items\": [\n              {\n                \"kind\": \"youtube#video\",\n                \"etag\": \"qKunn-Fuyq9NejK7nyf1n6Au4wg\",\n                \"id\": \"9LfmrkyP81M\",\n                \"statistics\": {\n                  \"viewCount\": \"113620\",\n                  \"likeCount\": \"1948\",\n                  \"favoriteCount\": \"0\",\n                  \"commentCount\": \"114\"\n                }\n              }\n            ],\n            \"pageInfo\": {\n              \"totalResults\": 1,\n              \"resultsPerPage\": 1\n            }\n          }\n    recorded_at: Mon, 26 Jun 2023 21:12:38 GMT\nrecorded_with: VCR 6.1.0\n"
  },
  {
    "path": "test/vcr_cassettes/youtube_statistics_invalid.yml",
    "content": "---\nhttp_interactions:\n  - request:\n      method: get\n      uri: https://youtube.googleapis.com/youtube/v3/videos?id=invalid_video_id&key=REDACTED_YOUTUBE_API_KEY&maxResults=50&part=statistics\n      body:\n        encoding: US-ASCII\n        string: \"\"\n      headers:\n        Accept-Encoding:\n          - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n        Accept:\n          - \"*/*\"\n        User-Agent:\n          - Ruby\n    response:\n      status:\n        code: 200\n        message: OK\n      headers:\n        Content-Type:\n          - application/json; charset=UTF-8\n        Vary:\n          - Origin\n          - Referer\n          - X-Origin\n        Date:\n          - Mon, 26 Jun 2023 21:14:19 GMT\n        Server:\n          - scaffolding on HTTPServer2\n        Cache-Control:\n          - private\n        X-Xss-Protection:\n          - \"0\"\n        X-Frame-Options:\n          - SAMEORIGIN\n        X-Content-Type-Options:\n          - nosniff\n        Alt-Svc:\n          - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n        Transfer-Encoding:\n          - chunked\n      body:\n        encoding: ASCII-8BIT\n        string: |\n          {\n            \"kind\": \"youtube#videoListResponse\",\n            \"etag\": \"YIUPVpqNjppyCWOZfL-19bLb7uk\",\n            \"items\": [],\n            \"pageInfo\": {\n              \"totalResults\": 0,\n              \"resultsPerPage\": 0\n            }\n          }\n    recorded_at: Mon, 26 Jun 2023 21:14:18 GMT\nrecorded_with: VCR 6.1.0\n"
  },
  {
    "path": "test/vcr_cassettes/youtube_video_transcript.yml",
    "content": "---\nhttp_interactions:\n- request:\n    method: post\n    uri: https://www.youtube.com/youtubei/v1/get_transcript\n    body:\n      encoding: UTF-8\n      string: '{\"context\":{\"client\":{\"clientName\":\"WEB\",\"clientVersion\":\"2.20240313\"}},\"params\":\"Cgs5TGZtcmt5UDgxTRIMQ2dOaGMzSVNBbVZ1\"}'\n    headers:\n      Content-Type:\n      - application/json\n      Accept-Encoding:\n      - gzip;q=1.0,deflate;q=0.6,identity;q=0.3\n      Accept:\n      - \"*/*\"\n      User-Agent:\n      - Ruby\n  response:\n    status:\n      code: 200\n      message: OK\n    headers:\n      Content-Type:\n      - application/json; charset=UTF-8\n      Vary:\n      - Origin\n      - Referer\n      - X-Origin\n      Date:\n      - Sat, 06 Jul 2024 22:17:46 GMT\n      Server:\n      - scaffolding on HTTPServer2\n      Cache-Control:\n      - private\n      X-Xss-Protection:\n      - '0'\n      X-Frame-Options:\n      - SAMEORIGIN\n      X-Content-Type-Options:\n      - nosniff\n      Alt-Svc:\n      - h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\n      Transfer-Encoding:\n      - chunked\n    body:\n      encoding: ASCII-8BIT\n      string: |\n        {\n          \"responseContext\": {\n            \"visitorData\": \"CgtTSklwaFVMRmRxWSiJhae0BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgSA%3D%3D\",\n            \"serviceTrackingParams\": [\n              {\n                \"service\": \"CSI\",\n                \"params\": [\n                  {\n                    \"key\": \"c\",\n                    \"value\": \"WEB\"\n                  },\n                  {\n                    \"key\": \"cver\",\n                    \"value\": \"2.20240313\"\n                  },\n                  {\n                    \"key\": \"yt_li\",\n                    \"value\": \"0\"\n                  },\n                  {\n                    \"key\": \"GetVideoTranscript_rid\",\n                    \"value\": \"0x0a5195843ca96856\"\n                  }\n                ]\n              },\n              {\n                \"service\": \"GFEEDBACK\",\n                \"params\": [\n                  {\n                    \"key\": \"logged_in\",\n                    \"value\": \"0\"\n                  },\n                  {\n                    \"key\": \"e\",\n                    \"value\": \"23804281,23946420,23966208,23986016,23998056,24004644,24077241,24166867,24181174,24241378,24290971,24407444,24439361,24453989,24456089,24459435,24468724,24502053,24542367,24548627,24548629,24550458,24552798,24566687,24699899,39325854,39326848,51009781,51010235,51016856,51017346,51020077,51020570,51025415,51030101,51033765,51037330,51037342,51037353,51041512,51048489,51050361,51053689,51057844,51057851,51060353,51063643,51064835,51072748,51073088,51091058,51091331,51095478,51098297,51098299,51102410,51106995,51111738,51113658,51113663,51115184,51116067,51118058,51118932,51124104,51129209,51133103,51134507,51138613,51139379,51148688,51148869,51148974,51148981,51149607,51152050,51157411,51157430,51157432,51157838,51158470,51158514,51160545,51162170,51163641,51165467,51165568,51169131,51170249,51172670,51172688,51172695,51172698,51172709,51172716,51172721,51172728,51175606,51175732,51176511,51176563,51177818,51178312,51178327,51178340,51178355,51178705,51178982,51183910,51184021,51184990,51186528,51186670,51187241,51188415,51189511,51189514,51189826,51190057,51190075,51190078,51190089,51190200,51190211,51190216,51190231,51190652,51191752,51193488,51193963,51195231,51196180,51196772,51197685,51197694,51197701,51197708,51197960,51199193,51199595,51200020,51200253,51200256,51200293,51200300,51200569,51201352,51201367,51201370,51201383,51201426,51201433,51201440,51201449,51201814,51202231,51202416,51203199,51204329,51207180,51207193,51207200,51207211,51211461,51212142,51212464,51212555,51212567,51213732,51213808,51216387,51217504,51217582,51217769,51218324,51219242,51219303,51220799,51221011,51221148,51221348,51222969,51223961,51224655,51224748,51224921,51225437,51226683,51226709,51227772,51228695,51228769,51228776,51228787,51228800,51228809,51228818,51229607,51230123,51230478,51231814,51232222\"\n                  }\n                ]\n              },\n              {\n                \"service\": \"GUIDED_HELP\",\n                \"params\": [\n                  {\n                    \"key\": \"logged_in\",\n                    \"value\": \"0\"\n                  }\n                ]\n              },\n              {\n                \"service\": \"ECATCHER\",\n                \"params\": [\n                  {\n                    \"key\": \"client.version\",\n                    \"value\": \"2.20240530\"\n                  },\n                  {\n                    \"key\": \"client.name\",\n                    \"value\": \"WEB\"\n                  }\n                ]\n              }\n            ],\n            \"mainAppWebResponseContext\": {\n              \"loggedOut\": true,\n              \"trackingParam\": \"kx_fmPxhoPZRSrBh0PD2TCAbIz-qAT4noNxr0iIywVFU45Eass0cwhLBwOcCE59TDtslLKPQ-SS\"\n            },\n            \"webResponseContextExtensionData\": {\n              \"hasDecorated\": true\n            }\n          },\n          \"actions\": [\n            {\n              \"clickTrackingParams\": \"CAAQw7wCIhMIipCx5biThwMVAtpJBx29UAN9\",\n              \"updateEngagementPanelAction\": {\n                \"targetId\": \"engagement-panel-searchable-transcript\",\n                \"content\": {\n                  \"transcriptRenderer\": {\n                    \"trackingParams\": \"CAEQ8bsCIhMIipCx5biThwMVAtpJBx29UAN9\",\n                    \"content\": {\n                      \"transcriptSearchPanelRenderer\": {\n                        \"header\": {\n                          \"transcriptSearchBoxRenderer\": {\n                            \"formattedPlaceholder\": {\n                              \"runs\": [\n                                {\n                                  \"text\": \"Search in video\"\n                                }\n                              ]\n                            },\n                            \"accessibility\": {\n                              \"accessibilityData\": {\n                                \"label\": \"Search in video\"\n                              }\n                            },\n                            \"clearButton\": {\n                              \"buttonRenderer\": {\n                                \"icon\": {\n                                  \"iconType\": \"CLOSE\"\n                                },\n                                \"trackingParams\": \"CMsEEMngByITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                \"accessibilityData\": {\n                                  \"accessibilityData\": {\n                                    \"label\": \"Clear search query\"\n                                  }\n                                }\n                              }\n                            },\n                            \"onTextChangeCommand\": {\n                              \"clickTrackingParams\": \"CMkEEKvaByITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                              \"commandMetadata\": {\n                                \"webCommandMetadata\": {\n                                  \"sendPost\": true,\n                                  \"apiUrl\": \"/youtubei/v1/get_transcript\"\n                                }\n                              },\n                              \"getTranscriptEndpoint\": {\n                                \"params\": \"Cgs5TGZtcmt5UDgxTRIMQ2dOaGMzSVNBbVZ1GAEqM2VuZ2FnZW1lbnQtcGFuZWwtc2VhcmNoYWJsZS10cmFuc2NyaXB0LXNlYXJjaC1wYW5lbDAAOABAAA%3D%3D\"\n                              }\n                            },\n                            \"trackingParams\": \"CMkEEKvaByITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                            \"searchButton\": {\n                              \"buttonRenderer\": {\n                                \"trackingParams\": \"CMoEEIKDCCITCIqQseW4k4cDFQLaSQcdvVADfQ==\"\n                              }\n                            }\n                          }\n                        },\n                        \"body\": {\n                          \"transcriptSegmentListRenderer\": {\n                            \"initialSegments\": [\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1760\",\n                                  \"endMs\": \"17849\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"[Music]\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:01\"\n                                  },\n                                  \"trackingParams\": \"CMgEENP2BxgAIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 second [Music]\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1760.17849\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"17849\",\n                                  \"endMs\": \"24310\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that any better oh there we go whoo software is hard as you can see hardware\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:17\"\n                                  },\n                                  \"trackingParams\": \"CMcEENP2BxgBIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 seconds that any better oh there we go whoo software is hard as you can see hardware\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.17849.24310\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"24310\",\n                                  \"endMs\": \"31710\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"- so last year I had the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:24\"\n                                  },\n                                  \"trackingParams\": \"CMYEENP2BxgCIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 seconds - so last year I had the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.24310.31710\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"31710\",\n                                  \"endMs\": \"36820\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"personal pleasure of celebrating ten years of working with Ruby and ten years\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:31\"\n                                  },\n                                  \"trackingParams\": \"CMUEENP2BxgDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 seconds personal pleasure of celebrating ten years of working with Ruby and ten years\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.31710.36820\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"36820\",\n                                  \"endMs\": \"42360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of working with rails but this year I have a much more interesting\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:36\"\n                                  },\n                                  \"trackingParams\": \"CMQEENP2BxgEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 seconds of working with rails but this year I have a much more interesting\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.36820.42360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"42360\",\n                                  \"endMs\": \"48370\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"anniversary which is ten years of sharing Ruby on Rails with all of you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:42\"\n                                  },\n                                  \"trackingParams\": \"CMMEENP2BxgFIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 seconds anniversary which is ten years of sharing Ruby on Rails with all of you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.42360.48370\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"48370\",\n                                  \"endMs\": \"54030\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and everyone who've been using it over the past decade\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:48\"\n                                  },\n                                  \"trackingParams\": \"CMIEENP2BxgGIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 seconds and everyone who've been using it over the past decade\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.48370.54030\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"54030\",\n                                  \"endMs\": \"60610\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the picture the background is actually from almost exactly this time where I gave the very first presentation on Ruby\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"0:54\"\n                                  },\n                                  \"trackingParams\": \"CMEEENP2BxgHIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"54 seconds the picture the background is actually from almost exactly this time where I gave the very first presentation on Ruby\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.54030.60610\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"60610\",\n                                  \"endMs\": \"67840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"on Rails at a Danish University ten years ago ten years ago I had to talk a lot about\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00\"\n                                  },\n                                  \"trackingParams\": \"CMAEENP2BxgIIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute on Rails at a Danish University ten years ago ten years ago I had to talk a lot about\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.60610.67840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"67840\",\n                                  \"endMs\": \"73479\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what is MVC for example today not so much there's a lot of the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:07\"\n                                  },\n                                  \"trackingParams\": \"CL8EENP2BxgJIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 7 seconds what is MVC for example today not so much there's a lot of the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.67840.73479\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"73479\",\n                                  \"endMs\": \"80920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"things that over the past ten years things we worried about in the beginning sort of levelling up as a community and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:13\"\n                                  },\n                                  \"trackingParams\": \"CL4EENP2BxgKIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 13 seconds things that over the past ten years things we worried about in the beginning sort of levelling up as a community and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.73479.80920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"80920\",\n                                  \"endMs\": \"86799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"as programmers that just aren't relevant anymore we're just taking all that stuff for granted which is awesome we get to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:20\"\n                                  },\n                                  \"trackingParams\": \"CL0EENP2BxgLIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 20 seconds as programmers that just aren't relevant anymore we're just taking all that stuff for granted which is awesome we get to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.80920.86799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"86799\",\n                                  \"endMs\": \"92110\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"care about a lot of other stuff but as I look back over the past ten\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:26\"\n                                  },\n                                  \"trackingParams\": \"CLwEENP2BxgMIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 26 seconds care about a lot of other stuff but as I look back over the past ten\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.86799.92110\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"92110\",\n                                  \"endMs\": \"97119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"years which is pretty much the majority of my adult life I've been\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:32\"\n                                  },\n                                  \"trackingParams\": \"CLsEENP2BxgNIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 32 seconds years which is pretty much the majority of my adult life I've been\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.92110.97119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"97119\",\n                                  \"endMs\": \"105119\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"working on Ruby on Rails it's fun to look back even further I think there's a common\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:37\"\n                                  },\n                                  \"trackingParams\": \"CLoEENP2BxgOIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 37 seconds working on Ruby on Rails it's fun to look back even further I think there's a common\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.97119.105119\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"105119\",\n                                  \"endMs\": \"112930\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"misconception that anybody winds up creating something like rails or doing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:45\"\n                                  },\n                                  \"trackingParams\": \"CLkEENP2BxgPIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 45 seconds misconception that anybody winds up creating something like rails or doing\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.105119.112930\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"112930\",\n                                  \"endMs\": \"119409\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"something else within software development or computer science well they must have been programming since they were five years old right\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:52\"\n                                  },\n                                  \"trackingParams\": \"CLgEENP2BxgQIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 52 seconds something else within software development or computer science well they must have been programming since they were five years old right\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.112930.119409\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"119409\",\n                                  \"endMs\": \"125110\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like the whole notion of a hacker is somebody who sort of got their first\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:59\"\n                                  },\n                                  \"trackingParams\": \"CLcEENP2BxgRIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 minute, 59 seconds like the whole notion of a hacker is somebody who sort of got their first\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.119409.125110\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"125110\",\n                                  \"endMs\": \"130920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"computer 20 years ago and it was just programming the entire time well\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:05\"\n                                  },\n                                  \"trackingParams\": \"CLYEENP2BxgSIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 5 seconds computer 20 years ago and it was just programming the entire time well\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.125110.130920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"130920\",\n                                  \"endMs\": \"137800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that wasn't me I did not learn to program when I was five years old I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:10\"\n                                  },\n                                  \"trackingParams\": \"CLUEENP2BxgTIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 10 seconds that wasn't me I did not learn to program when I was five years old I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.130920.137800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"137800\",\n                                  \"endMs\": \"144209\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"didn't learn to program until I was closer to 20 I'd been interested in computers for a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:17\"\n                                  },\n                                  \"trackingParams\": \"CLQEENP2BxgUIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 17 seconds didn't learn to program until I was closer to 20 I'd been interested in computers for a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.137800.144209\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"144209\",\n                                  \"endMs\": \"150689\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"long time but it wasn't really until the late 90s early 2000 that I dove into\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:24\"\n                                  },\n                                  \"trackingParams\": \"CLMEENP2BxgVIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 24 seconds long time but it wasn't really until the late 90s early 2000 that I dove into\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.144209.150689\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"150689\",\n                                  \"endMs\": \"158730\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"computer programming as something that I was going to do a lot of friends who were doing it I knew a lot of programmers but somehow it it sort of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:30\"\n                                  },\n                                  \"trackingParams\": \"CLIEENP2BxgWIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 30 seconds computer programming as something that I was going to do a lot of friends who were doing it I knew a lot of programmers but somehow it it sort of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.150689.158730\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"158730\",\n                                  \"endMs\": \"165349\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"never never caught on before I started writing software that I needed for myself and before I found\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:38\"\n                                  },\n                                  \"trackingParams\": \"CLEEENP2BxgXIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 38 seconds never never caught on before I started writing software that I needed for myself and before I found\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.158730.165349\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"165349\",\n                                  \"endMs\": \"173609\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"sort of a place in the software world for that to happen and the reason I say that is I've seen a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:45\"\n                                  },\n                                  \"trackingParams\": \"CLAEENP2BxgYIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 45 seconds sort of a place in the software world for that to happen and the reason I say that is I've seen a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.165349.173609\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"173609\",\n                                  \"endMs\": \"179450\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"number of essay sounds like what is a true hacker and and that's a true hacker\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:53\"\n                                  },\n                                  \"trackingParams\": \"CK8EENP2BxgZIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 53 seconds number of essay sounds like what is a true hacker and and that's a true hacker\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.173609.179450\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"179450\",\n                                  \"endMs\": \"186060\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"one of the things that keeps being thrown out is those ten years right you should have been programming for ten years already otherwise you're way\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"2:59\"\n                                  },\n                                  \"trackingParams\": \"CK4EENP2BxgaIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"2 minutes, 59 seconds one of the things that keeps being thrown out is those ten years right you should have been programming for ten years already otherwise you're way\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.179450.186060\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"186060\",\n                                  \"endMs\": \"192480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"behind well I learned to program about three years before I released Ruby on\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:06\"\n                                  },\n                                  \"trackingParams\": \"CK0EENP2BxgbIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 6 seconds behind well I learned to program about three years before I released Ruby on\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.186060.192480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"192480\",\n                                  \"endMs\": \"197540\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Rails turned out fine\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:12\"\n                                  },\n                                  \"trackingParams\": \"CKwEENP2BxgcIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 12 seconds Rails turned out fine\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.192480.197540\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"199310\",\n                                  \"endMs\": \"205049\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and I don't say that it's like it was because I grew up on a farm and didn't\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:19\"\n                                  },\n                                  \"trackingParams\": \"CKsEENP2BxgdIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 19 seconds and I don't say that it's like it was because I grew up on a farm and didn't\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.199310.205049\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"205049\",\n                                  \"endMs\": \"211799\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"know what a computer was this is me in in the center there with\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:25\"\n                                  },\n                                  \"trackingParams\": \"CKoEENP2BxgeIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 25 seconds know what a computer was this is me in in the center there with\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.205049.211799\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"211799\",\n                                  \"endMs\": \"219299\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the stick and the blue shirt in 1985 these are the kits that were living\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:31\"\n                                  },\n                                  \"trackingParams\": \"CKkEENP2BxgfIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 31 seconds the stick and the blue shirt in 1985 these are the kits that were living\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.211799.219299\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"219299\",\n                                  \"endMs\": \"224690\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in my neighborhood then in 1985 are going to introduce to my my first computer and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:39\"\n                                  },\n                                  \"trackingParams\": \"CKgEENP2BxggIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 39 seconds in my neighborhood then in 1985 are going to introduce to my my first computer and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.219299.224690\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"224690\",\n                                  \"endMs\": \"231810\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I was about five years old and I got introduced to computers through\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:44\"\n                                  },\n                                  \"trackingParams\": \"CKcEENP2BxghIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 44 seconds I was about five years old and I got introduced to computers through\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.224690.231810\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"231810\",\n                                  \"endMs\": \"237660\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"gaming sort of we were playing ninjas in the streets around our houses and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:51\"\n                                  },\n                                  \"trackingParams\": \"CKYEENP2BxgiIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 51 seconds gaming sort of we were playing ninjas in the streets around our houses and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.231810.237660\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"237660\",\n                                  \"endMs\": \"243690\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we'd play ninjas on the box and I found a fascinating right from the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"3:57\"\n                                  },\n                                  \"trackingParams\": \"CKUEENP2BxgjIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"3 minutes, 57 seconds we'd play ninjas on the box and I found a fascinating right from the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.237660.243690\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"243690\",\n                                  \"endMs\": \"250260\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"get-go right computers really fascinating and games really captured my imagination early on\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:03\"\n                                  },\n                                  \"trackingParams\": \"CKQEENP2BxgkIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 3 seconds get-go right computers really fascinating and games really captured my imagination early on\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.243690.250260\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"250260\",\n                                  \"endMs\": \"256919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I remember at that time there were certainly lots of parents like well make sure you get out and play a lot because\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:10\"\n                                  },\n                                  \"trackingParams\": \"CKMEENP2BxglIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 10 seconds I remember at that time there were certainly lots of parents like well make sure you get out and play a lot because\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.250260.256919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"256919\",\n                                  \"endMs\": \"262049\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you don't want to spend you're a wasting your time that was the first word wasting your time in front of computers\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:16\"\n                                  },\n                                  \"trackingParams\": \"CKIEENP2BxgmIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 16 seconds you don't want to spend you're a wasting your time that was the first word wasting your time in front of computers\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.256919.262049\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"262049\",\n                                  \"endMs\": \"270389\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"inside right well I really did want to waste my time in front of computers and this was the computer to have in 1985 in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:22\"\n                                  },\n                                  \"trackingParams\": \"CKEEENP2BxgnIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 22 seconds inside right well I really did want to waste my time in front of computers and this was the computer to have in 1985 in\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.262049.270389\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"270389\",\n                                  \"endMs\": \"275729\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"our so neighborhood but we couldn't afford a computer like that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:30\"\n                                  },\n                                  \"trackingParams\": \"CKAEENP2BxgoIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 30 seconds our so neighborhood but we couldn't afford a computer like that\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.270389.275729\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"275729\",\n                                  \"endMs\": \"283470\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"there was only one guy in the whole neighborhood that had a computer like that so we all shared it and we all played yeeah kungfu in turn um but then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:35\"\n                                  },\n                                  \"trackingParams\": \"CJ8EENP2BxgpIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 35 seconds there was only one guy in the whole neighborhood that had a computer like that so we all shared it and we all played yeeah kungfu in turn um but then\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.275729.283470\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"283470\",\n                                  \"endMs\": \"289729\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the next year so i I couldn't afford this computer but\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:43\"\n                                  },\n                                  \"trackingParams\": \"CJ4EENP2BxgqIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 43 seconds the next year so i I couldn't afford this computer but\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.283470.289729\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"289729\",\n                                  \"endMs\": \"297270\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"my dad somehow he was fixing TVs and stereos he traded a stereo with this guy\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:49\"\n                                  },\n                                  \"trackingParams\": \"CJ0EENP2BxgrIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 49 seconds my dad somehow he was fixing TVs and stereos he traded a stereo with this guy\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.289729.297270\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"297270\",\n                                  \"endMs\": \"303289\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"for this other weird computer which was an Amstrad 646 and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"4:57\"\n                                  },\n                                  \"trackingParams\": \"CJwEENP2BxgsIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"4 minutes, 57 seconds for this other weird computer which was an Amstrad 646 and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.297270.303289\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"303289\",\n                                  \"endMs\": \"308849\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I was really excited it didn't actually play yeaa confer I was a little disappointed about that but it had some\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:03\"\n                                  },\n                                  \"trackingParams\": \"CJsEENP2BxgtIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 3 seconds I was really excited it didn't actually play yeaa confer I was a little disappointed about that but it had some\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.303289.308849\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"308849\",\n                                  \"endMs\": \"314729\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"other crappier games anyway it was in pewter and I was sort of my first introduction to to computer six years\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:08\"\n                                  },\n                                  \"trackingParams\": \"CJoEENP2BxguIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 8 seconds other crappier games anyway it was in pewter and I was sort of my first introduction to to computer six years\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.308849.314729\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"314729\",\n                                  \"endMs\": \"321090\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"old and an ex tried to learn programming I got a magazine and at the back of these\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:14\"\n                                  },\n                                  \"trackingParams\": \"CJkEENP2BxgvIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 14 seconds old and an ex tried to learn programming I got a magazine and at the back of these\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.314729.321090\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"321090\",\n                                  \"endMs\": \"326610\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"magazines back then there were programs you could type in that's like wow this is this is amazing I can control this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:21\"\n                                  },\n                                  \"trackingParams\": \"CJgEENP2BxgwIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 21 seconds magazines back then there were programs you could type in that's like wow this is this is amazing I can control this\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.321090.326610\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"326610\",\n                                  \"endMs\": \"333500\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"computer so I built my first information technology system it was\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:26\"\n                                  },\n                                  \"trackingParams\": \"CJcEENP2BxgxIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 26 seconds computer so I built my first information technology system it was\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.326610.333500\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"333530\",\n                                  \"endMs\": \"338580\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"messages to my mom of where I went where I had this clever system that I really\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:33\"\n                                  },\n                                  \"trackingParams\": \"CJYEENP2BxgyIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 33 seconds messages to my mom of where I went where I had this clever system that I really\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.333530.338580\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"338580\",\n                                  \"endMs\": \"344729\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"optimized the fact that writing a message of where I went and when I was going to be home it was too complicated\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:38\"\n                                  },\n                                  \"trackingParams\": \"CJUEENP2BxgzIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 38 seconds optimized the fact that writing a message of where I went and when I was going to be home it was too complicated\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.338580.344729\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"344729\",\n                                  \"endMs\": \"350880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"would be much easier if I just wrote a little note where I gave her the location on the tape that she had to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:44\"\n                                  },\n                                  \"trackingParams\": \"CJQEENP2Bxg0IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 44 seconds would be much easier if I just wrote a little note where I gave her the location on the tape that she had to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.344729.350880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"350880\",\n                                  \"endMs\": \"358169\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"fast forward to and then she could read where it was I thought man this is so clever I just have to write down to 28\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:50\"\n                                  },\n                                  \"trackingParams\": \"CJMEENP2Bxg1IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 50 seconds fast forward to and then she could read where it was I thought man this is so clever I just have to write down to 28\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.350880.358169\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"358169\",\n                                  \"endMs\": \"366110\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and then I could pre-programmed that note and she'll know I was over at Peter's house playing year come foo um\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"5:58\"\n                                  },\n                                  \"trackingParams\": \"CJIEENP2Bxg2IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"5 minutes, 58 seconds and then I could pre-programmed that note and she'll know I was over at Peter's house playing year come foo um\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.358169.366110\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"366409\",\n                                  \"endMs\": \"372990\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that really wasn't programming right I just typed some stuff in I didn't know what the hell I was doing I just somehow\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:06\"\n                                  },\n                                  \"trackingParams\": \"CJEEENP2Bxg3IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 6 seconds that really wasn't programming right I just typed some stuff in I didn't know what the hell I was doing I just somehow\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.366409.372990\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"372990\",\n                                  \"endMs\": \"378599\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"figured out print okay that put stuff up on the screen that was that was the extent of it right but it was my first\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:12\"\n                                  },\n                                  \"trackingParams\": \"CJAEENP2Bxg4IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 12 seconds figured out print okay that put stuff up on the screen that was that was the extent of it right but it was my first\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.372990.378599\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"378599\",\n                                  \"endMs\": \"384090\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"step at programming and and I it kind of failed like that was the extent of my my\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:18\"\n                                  },\n                                  \"trackingParams\": \"CI8EENP2Bxg5IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 18 seconds step at programming and and I it kind of failed like that was the extent of my my\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.378599.384090\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"384090\",\n                                  \"endMs\": \"393030\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"program that I knew how to fast forward to a pre-recorded message not that great so a couple years later\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:24\"\n                                  },\n                                  \"trackingParams\": \"CI4EENP2Bxg6IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 24 seconds program that I knew how to fast forward to a pre-recorded message not that great so a couple years later\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.384090.393030\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"393030\",\n                                  \"endMs\": \"399270\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"late 80s I saw at this game for the first time battle squadron and I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:33\"\n                                  },\n                                  \"trackingParams\": \"CI0EENP2Bxg7IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 33 seconds late 80s I saw at this game for the first time battle squadron and I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.393030.399270\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"399270\",\n                                  \"endMs\": \"404440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"remember thinking holy these graphics are amazing how they make this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:39\"\n                                  },\n                                  \"trackingParams\": \"CIwEENP2Bxg8IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 39 seconds remember thinking holy these graphics are amazing how they make this\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.399270.404440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"404440\",\n                                  \"endMs\": \"410680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this looks so good when you were used to our Commodore 64 the the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:44\"\n                                  },\n                                  \"trackingParams\": \"CIsEENP2Bxg9IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 44 seconds this looks so good when you were used to our Commodore 64 the the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.404440.410680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"410680\",\n                                  \"endMs\": \"416860\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"graphics of the Amiga 500 which is mind-blowing right and once again that felt this like wow wouldn't it be\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:50\"\n                                  },\n                                  \"trackingParams\": \"CIoEENP2Bxg-IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 50 seconds graphics of the Amiga 500 which is mind-blowing right and once again that felt this like wow wouldn't it be\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.410680.416860\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"416860\",\n                                  \"endMs\": \"422400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"amazing to be part of that to be able to create something like that I'd love to make games\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"6:56\"\n                                  },\n                                  \"trackingParams\": \"CIkEENP2Bxg_IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"6 minutes, 56 seconds amazing to be part of that to be able to create something like that I'd love to make games\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.416860.422400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"422400\",\n                                  \"endMs\": \"428500\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so I sort of started looking around and I found this thing called Amos I know if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:02\"\n                                  },\n                                  \"trackingParams\": \"CIgEENP2BxhAIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 2 seconds so I sort of started looking around and I found this thing called Amos I know if\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.422400.428500\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"428500\",\n                                  \"endMs\": \"434500\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"anybody here ever programmed an Amos not a single hand okay but have been a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:08\"\n                                  },\n                                  \"trackingParams\": \"CIcEENP2BxhBIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 8 seconds anybody here ever programmed an Amos not a single hand okay but have been a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.428500.434500\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"434500\",\n                                  \"endMs\": \"440800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"very European thing but it was sort of a real programming environment and and I got the box and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:14\"\n                                  },\n                                  \"trackingParams\": \"CIYEENP2BxhCIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 14 seconds very European thing but it was sort of a real programming environment and and I got the box and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.434500.440800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"440800\",\n                                  \"endMs\": \"446500\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"sort of my English was a little not that great so I was sort of just reading through it and trying to fight the code\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:20\"\n                                  },\n                                  \"trackingParams\": \"CIUEENP2BxhDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 20 seconds sort of my English was a little not that great so I was sort of just reading through it and trying to fight the code\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.440800.446500\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"446500\",\n                                  \"endMs\": \"451930\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and it was all about sprites and vectors and ifs and variables and it didn't make\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:26\"\n                                  },\n                                  \"trackingParams\": \"CIQEENP2BxhEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 26 seconds and it was all about sprites and vectors and ifs and variables and it didn't make\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.446500.451930\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"451930\",\n                                  \"endMs\": \"458530\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"any sense to me at all so that is a little bit too hard thankfully there was something called easy Amos right oh wow\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:31\"\n                                  },\n                                  \"trackingParams\": \"CIMEENP2BxhFIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 31 seconds any sense to me at all so that is a little bit too hard thankfully there was something called easy Amos right oh wow\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.451930.458530\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"458530\",\n                                  \"endMs\": \"465760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that's going to be great this other one was too hard now I just have to do the easy one unfortunately in ICI Amos it was still\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:38\"\n                                  },\n                                  \"trackingParams\": \"CIIEENP2BxhGIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 38 seconds that's going to be great this other one was too hard now I just have to do the easy one unfortunately in ICI Amos it was still\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.458530.465760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"465760\",\n                                  \"endMs\": \"471130\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"programming and it still had conditionals and variables and all these other things I just did not understand I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:45\"\n                                  },\n                                  \"trackingParams\": \"CIEEENP2BxhHIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 45 seconds programming and it still had conditionals and variables and all these other things I just did not understand I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.465760.471130\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"471130\",\n                                  \"endMs\": \"477490\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's so funny because once you learn something you can sometimes be hard to go back and think like how was it before\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:51\"\n                                  },\n                                  \"trackingParams\": \"CIAEENP2BxhIIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 51 seconds it's so funny because once you learn something you can sometimes be hard to go back and think like how was it before\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.471130.477490\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"477490\",\n                                  \"endMs\": \"484810\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I knew how to do this but I distinctly remember why would you have a variable like if you just assign something once\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"7:57\"\n                                  },\n                                  \"trackingParams\": \"CP8DENP2BxhJIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"7 minutes, 57 seconds I knew how to do this but I distinctly remember why would you have a variable like if you just assign something once\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.477490.484810\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"484810\",\n                                  \"endMs\": \"490510\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"why would you ever sort of want to change that why does it have to be a space where I can't just be the thing like I did not get the concept of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:04\"\n                                  },\n                                  \"trackingParams\": \"CP4DENP2BxhKIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 4 seconds why would you ever sort of want to change that why does it have to be a space where I can't just be the thing like I did not get the concept of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.484810.490510\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"490510\",\n                                  \"endMs\": \"496240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"variables and this is that I don't know H 10 or whatever so still not getting\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:10\"\n                                  },\n                                  \"trackingParams\": \"CP0DENP2BxhLIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 10 seconds variables and this is that I don't know H 10 or whatever so still not getting\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.490510.496240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"496240\",\n                                  \"endMs\": \"501400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"programming it's still not making any sense to me so I gave up in that too\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:16\"\n                                  },\n                                  \"trackingParams\": \"CPwDENP2BxhMIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 16 seconds programming it's still not making any sense to me so I gave up in that too\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.496240.501400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"501400\",\n                                  \"endMs\": \"508539\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"[Music] then in 1993 I went to something called\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:21\"\n                                  },\n                                  \"trackingParams\": \"CPsDENP2BxhNIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 21 seconds [Music] then in 1993 I went to something called\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.501400.508539\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"508539\",\n                                  \"endMs\": \"516070\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the gathering the gathering 3 which was a big demo party in Denmark where people\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:28\"\n                                  },\n                                  \"trackingParams\": \"CPoDENP2BxhOIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 28 seconds the gathering the gathering 3 which was a big demo party in Denmark where people\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.508539.516070\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"516070\",\n                                  \"endMs\": \"522909\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"from all over Europe maybe some from the US as well would gather to to show off their skills of creating these demos and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:36\"\n                                  },\n                                  \"trackingParams\": \"CPkDENP2BxhPIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 36 seconds from all over Europe maybe some from the US as well would gather to to show off their skills of creating these demos and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.516070.522909\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"522909\",\n                                  \"endMs\": \"528250\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"demos were basically just like little music videos with computer graphics and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:42\"\n                                  },\n                                  \"trackingParams\": \"CPgDENP2BxhQIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 42 seconds demos were basically just like little music videos with computer graphics and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.522909.528250\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"528250\",\n                                  \"endMs\": \"535540\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I thought that was really awesome and again I got this sensation of wow that's amazing people creating these sequences\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:48\"\n                                  },\n                                  \"trackingParams\": \"CPcDENP2BxhRIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 48 seconds I thought that was really awesome and again I got this sensation of wow that's amazing people creating these sequences\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.528250.535540\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"535540\",\n                                  \"endMs\": \"543580\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"they look really good this is this is awesome I'd love to be a part of that this is 93 some 14 at this demo party\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"8:55\"\n                                  },\n                                  \"trackingParams\": \"CPYDENP2BxhSIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"8 minutes, 55 seconds they look really good this is this is awesome I'd love to be a part of that this is 93 some 14 at this demo party\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.535540.543580\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"543580\",\n                                  \"endMs\": \"548620\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then I met pretty much everybody I knew for the next 10 years in computer\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:03\"\n                                  },\n                                  \"trackingParams\": \"CPUDENP2BxhTIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 3 seconds then I met pretty much everybody I knew for the next 10 years in computer\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.543580.548620\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"548620\",\n                                  \"endMs\": \"554080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"software including Allen of textmate Fame I was 14 and he was part of one of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:08\"\n                                  },\n                                  \"trackingParams\": \"CPQDENP2BxhUIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 8 seconds software including Allen of textmate Fame I was 14 and he was part of one of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.548620.554080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"554080\",\n                                  \"endMs\": \"559890\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"these demo groups and we got talking and then 10 years later\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:14\"\n                                  },\n                                  \"trackingParams\": \"CPMDENP2BxhVIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 14 seconds these demo groups and we got talking and then 10 years later\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.554080.559890\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"559890\",\n                                  \"endMs\": \"566110\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I'd help him release text made and this is now 20 years ago anyway I still\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:19\"\n                                  },\n                                  \"trackingParams\": \"CPIDENP2BxhWIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 19 seconds I'd help him release text made and this is now 20 years ago anyway I still\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.559890.566110\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"566110\",\n                                  \"endMs\": \"572220\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"didn't get the concept right like it was all it was assembler so it was even harder and weirder to figure out then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:26\"\n                                  },\n                                  \"trackingParams\": \"CPEDENP2BxhXIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 26 seconds didn't get the concept right like it was all it was assembler so it was even harder and weirder to figure out then\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.566110.572220\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"572220\",\n                                  \"endMs\": \"580089\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"then Amos was it was vectors it was math it was it was just really hard so once\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:32\"\n                                  },\n                                  \"trackingParams\": \"CPADENP2BxhYIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 32 seconds then Amos was it was vectors it was math it was it was just really hard so once\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.572220.580089\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"580089\",\n                                  \"endMs\": \"586270\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"again this is the third time I try to sort of figure out program because I want to build stuff and the third time\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:40\"\n                                  },\n                                  \"trackingParams\": \"CO8DENP2BxhZIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 40 seconds again this is the third time I try to sort of figure out program because I want to build stuff and the third time\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.580089.586270\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"586270\",\n                                  \"endMs\": \"592779\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it failed so I ended up building another information system at that time there's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:46\"\n                                  },\n                                  \"trackingParams\": \"CO4DENP2BxhaIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 46 seconds it failed so I ended up building another information system at that time there's\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.586270.592779\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"592779\",\n                                  \"endMs\": \"597910\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"something called BBS's so a pre-internet you dialed up to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:52\"\n                                  },\n                                  \"trackingParams\": \"CO0DENP2BxhbIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 52 seconds something called BBS's so a pre-internet you dialed up to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.592779.597910\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"597910\",\n                                  \"endMs\": \"603330\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"basically every website individually through a modem and I ran one of those things\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"9:57\"\n                                  },\n                                  \"trackingParams\": \"COwDENP2BxhcIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"9 minutes, 57 seconds basically every website individually through a modem and I ran one of those things\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.597910.603330\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"603330\",\n                                  \"endMs\": \"609640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"at that time it was it was called the where's BBS which was where we traded all the illegal software that we\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:03\"\n                                  },\n                                  \"trackingParams\": \"COsDENP2BxhdIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 3 seconds at that time it was it was called the where's BBS which was where we traded all the illegal software that we\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.603330.609640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"609640\",\n                                  \"endMs\": \"615310\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"couldn't afford and games and demos and I had a lot of fun doing that I was 15\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:09\"\n                                  },\n                                  \"trackingParams\": \"COoDENP2BxheIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 9 seconds couldn't afford and games and demos and I had a lot of fun doing that I was 15\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.609640.615310\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"615310\",\n                                  \"endMs\": \"621779\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and I was working at a grocery store and I spent all my money buying modems and phone lines\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:15\"\n                                  },\n                                  \"trackingParams\": \"COkDENP2BxhfIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 15 seconds and I was working at a grocery store and I spent all my money buying modems and phone lines\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.615310.621779\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"621779\",\n                                  \"endMs\": \"627850\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"but sort of the long of the short of this is that I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:21\"\n                                  },\n                                  \"trackingParams\": \"COgDENP2BxhgIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 21 seconds but sort of the long of the short of this is that I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.621779.627850\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"627850\",\n                                  \"endMs\": \"635430\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"failed to identify with programming under the computer science paradigm computer science in itself\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:27\"\n                                  },\n                                  \"trackingParams\": \"COcDENP2BxhhIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 27 seconds failed to identify with programming under the computer science paradigm computer science in itself\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.627850.635430\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"635430\",\n                                  \"endMs\": \"642540\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"just didn't really appeal to me it didn't make sense to me learning programming through\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:35\"\n                                  },\n                                  \"trackingParams\": \"COYDENP2BxhiIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 35 seconds just didn't really appeal to me it didn't make sense to me learning programming through\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.635430.642540\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"642540\",\n                                  \"endMs\": \"649240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"sort of the lens the prism of heart science just it didn't really it just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:42\"\n                                  },\n                                  \"trackingParams\": \"COUDENP2BxhjIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 42 seconds sort of the lens the prism of heart science just it didn't really it just\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.642540.649240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"649240\",\n                                  \"endMs\": \"655870\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"didn't click and I was actually pretty disappointed for a while I got tried to learn programming three or four times\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:49\"\n                                  },\n                                  \"trackingParams\": \"COQDENP2BxhkIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 49 seconds didn't click and I was actually pretty disappointed for a while I got tried to learn programming three or four times\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.649240.655870\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"655870\",\n                                  \"endMs\": \"661980\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"over the past ten years of my my life and it just it wasn't clicking\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"10:55\"\n                                  },\n                                  \"trackingParams\": \"COMDENP2BxhlIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"10 minutes, 55 seconds over the past ten years of my my life and it just it wasn't clicking\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.655870.661980\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"661980\",\n                                  \"endMs\": \"668500\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"no surprise to sort of my teachers this is my high\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:01\"\n                                  },\n                                  \"trackingParams\": \"COIDENP2BxhmIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 1 second no surprise to sort of my teachers this is my high\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.661980.668500\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"668500\",\n                                  \"endMs\": \"674390\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"school diploma part of it and it says math final exam F and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:08\"\n                                  },\n                                  \"trackingParams\": \"COEDENP2BxhnIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 8 seconds school diploma part of it and it says math final exam F and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.668500.674390\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"674390\",\n                                  \"endMs\": \"681180\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"an English I got an A but math which is never my thing physics never was never\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:14\"\n                                  },\n                                  \"trackingParams\": \"COADENP2BxhoIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 14 seconds an English I got an A but math which is never my thing physics never was never\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.674390.681180\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"681180\",\n                                  \"endMs\": \"686550\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"my thing any of the heart sciences which is never my thing and you say oh well\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:21\"\n                                  },\n                                  \"trackingParams\": \"CN8DENP2BxhpIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 21 seconds my thing any of the heart sciences which is never my thing and you say oh well\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.681180.686550\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"686550\",\n                                  \"endMs\": \"694590\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that explains a lot that's why where else is so slow but it's true it just never appealed to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:26\"\n                                  },\n                                  \"trackingParams\": \"CN4DENP2BxhqIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 26 seconds that explains a lot that's why where else is so slow but it's true it just never appealed to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.686550.694590\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"694590\",\n                                  \"endMs\": \"699780\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"me but I think it also inoculated me with something really\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:34\"\n                                  },\n                                  \"trackingParams\": \"CN0DENP2BxhrIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 34 seconds me but I think it also inoculated me with something really\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.694590.699780\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"699780\",\n                                  \"endMs\": \"706740\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"early on which was disabuse me of the thinking that I was a computer scientist that I was ever going to come up with an\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:39\"\n                                  },\n                                  \"trackingParams\": \"CNwDENP2BxhsIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 39 seconds early on which was disabuse me of the thinking that I was a computer scientist that I was ever going to come up with an\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.699780.706740\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"706740\",\n                                  \"endMs\": \"712340\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"algorithm that I was ever going to make any groundbreaking\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:46\"\n                                  },\n                                  \"trackingParams\": \"CNsDENP2BxhtIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 46 seconds algorithm that I was ever going to make any groundbreaking\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.706740.712340\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"712340\",\n                                  \"endMs\": \"718790\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"discoveries at the low level of computer science and that was actually really a relief\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:52\"\n                                  },\n                                  \"trackingParams\": \"CNoDENP2BxhuIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 52 seconds discoveries at the low level of computer science and that was actually really a relief\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.712340.718790\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"718790\",\n                                  \"endMs\": \"724620\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"because when I finally got into programming I knew that that was just not what I was going to do that was\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"11:58\"\n                                  },\n                                  \"trackingParams\": \"CNkDENP2BxhvIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"11 minutes, 58 seconds because when I finally got into programming I knew that that was just not what I was going to do that was\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.718790.724620\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"724620\",\n                                  \"endMs\": \"729900\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"never it was my aisle it was not what I was chasing I wanted to build\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:04\"\n                                  },\n                                  \"trackingParams\": \"CNgDENP2BxhwIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 4 seconds never it was my aisle it was not what I was chasing I wanted to build\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.724620.729900\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"729900\",\n                                  \"endMs\": \"735480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"information systems like all these attempts I had over the years they were all about information systems they were\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:09\"\n                                  },\n                                  \"trackingParams\": \"CNcDENP2BxhxIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 9 seconds information systems like all these attempts I had over the years they were all about information systems they were\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.729900.735480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"735480\",\n                                  \"endMs\": \"741710\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"about using the computer to build something else that really didn't have much to do with the underlying things\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:15\"\n                                  },\n                                  \"trackingParams\": \"CNYDENP2BxhyIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 15 seconds about using the computer to build something else that really didn't have much to do with the underlying things\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.735480.741710\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"741710\",\n                                  \"endMs\": \"749430\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that there were people smart people who had come up with algorithms underneath to make it all work wonderful I'm not\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:21\"\n                                  },\n                                  \"trackingParams\": \"CNUDENP2BxhzIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 21 seconds that there were people smart people who had come up with algorithms underneath to make it all work wonderful I'm not\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.741710.749430\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"749430\",\n                                  \"endMs\": \"754880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"one of them and that's fine I think as\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:29\"\n                                  },\n                                  \"trackingParams\": \"CNQDENP2Bxh0IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 29 seconds one of them and that's fine I think as\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.749430.754880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"754880\",\n                                  \"endMs\": \"762840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"an industry very few people have gotten to that realization even if it is the day on a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:34\"\n                                  },\n                                  \"trackingParams\": \"CNMDENP2Bxh1IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 34 seconds an industry very few people have gotten to that realization even if it is the day on a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.754880.762840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"762840\",\n                                  \"endMs\": \"769620\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"daily basis build information system even if it is that they're working on yet another social network for sock\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:42\"\n                                  },\n                                  \"trackingParams\": \"CNIDENP2Bxh2IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 42 seconds daily basis build information system even if it is that they're working on yet another social network for sock\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.762840.769620\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"769620\",\n                                  \"endMs\": \"774830\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"puppets or horror in my case yet another to-do list\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:49\"\n                                  },\n                                  \"trackingParams\": \"CNEDENP2Bxh3IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 49 seconds puppets or horror in my case yet another to-do list\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.769620.774830\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"774830\",\n                                  \"endMs\": \"781220\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the aspiration of the whole industry everyone in it is that we're all programmers\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"12:54\"\n                                  },\n                                  \"trackingParams\": \"CNADENP2Bxh4IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"12 minutes, 54 seconds the aspiration of the whole industry everyone in it is that we're all programmers\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.774830.781220\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"781220\",\n                                  \"endMs\": \"786740\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"right no we're not I am nothing like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:01\"\n                                  },\n                                  \"trackingParams\": \"CM8DENP2Bxh5IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 1 second right no we're not I am nothing like\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.781220.786740\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"786740\",\n                                  \"endMs\": \"792570\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"clintus right he's actually a real computer scientist to figure out how to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:06\"\n                                  },\n                                  \"trackingParams\": \"CM4DENP2Bxh6IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 6 seconds clintus right he's actually a real computer scientist to figure out how to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.786740.792570\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"792570\",\n                                  \"endMs\": \"803089\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I don't know improve the scheduler into kernel no clue no interest all good I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:12\"\n                                  },\n                                  \"trackingParams\": \"CM0DENP2Bxh7IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 12 seconds I don't know improve the scheduler into kernel no clue no interest all good I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.792570.803089\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"803089\",\n                                  \"endMs\": \"808649\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"every debt that there are people like that out there who can do this stuff so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:23\"\n                                  },\n                                  \"trackingParams\": \"CMwDENP2Bxh8IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 23 seconds every debt that there are people like that out there who can do this stuff so\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.803089.808649\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"808649\",\n                                  \"endMs\": \"815069\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I don't have to do it so I can focus on something else but I think most programmers think that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:28\"\n                                  },\n                                  \"trackingParams\": \"CMsDENP2Bxh9IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 28 seconds I don't have to do it so I can focus on something else but I think most programmers think that\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.808649.815069\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"815069\",\n                                  \"endMs\": \"821009\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"oh yeah that's that's what I do yeah I work in information systems but like we're kind of colleagues right me and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:35\"\n                                  },\n                                  \"trackingParams\": \"CMoDENP2Bxh-IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 35 seconds oh yeah that's that's what I do yeah I work in information systems but like we're kind of colleagues right me and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.815069.821009\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"821009\",\n                                  \"endMs\": \"826800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Linus here um I'm pretty sure that he would tell you you we're nothing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:41\"\n                                  },\n                                  \"trackingParams\": \"CMkDENP2Bxh_IhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 41 seconds Linus here um I'm pretty sure that he would tell you you we're nothing\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.821009.826800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"826800\",\n                                  \"endMs\": \"832709\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"alike we are not a colles what you do is making another to-do list I'm\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:46\"\n                                  },\n                                  \"trackingParams\": \"CMgDENP2BxiAASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 46 seconds alike we are not a colles what you do is making another to-do list I'm\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.826800.832709\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"832709\",\n                                  \"endMs\": \"838889\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"improving the kernel of Linux far more important work he would\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:52\"\n                                  },\n                                  \"trackingParams\": \"CMcDENP2BxiBASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 52 seconds improving the kernel of Linux far more important work he would\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.832709.838889\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"838889\",\n                                  \"endMs\": \"844128\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"disappear of your delusions of grandeur real quick\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"13:58\"\n                                  },\n                                  \"trackingParams\": \"CMYDENP2BxiCASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"13 minutes, 58 seconds disappear of your delusions of grandeur real quick\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.838889.844128\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"844670\",\n                                  \"endMs\": \"850970\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and I think that's a real shame I think it's a real shame that if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:04\"\n                                  },\n                                  \"trackingParams\": \"CMUDENP2BxiDASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 4 seconds and I think that's a real shame I think it's a real shame that if\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.844670.850970\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"850970\",\n                                  \"endMs\": \"856319\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you sort of pick your heroes in such a impossible fashion that they're actually\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:10\"\n                                  },\n                                  \"trackingParams\": \"CMQDENP2BxiEASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 10 seconds you sort of pick your heroes in such a impossible fashion that they're actually\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.850970.856319\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"856319\",\n                                  \"endMs\": \"863420\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"nothing like you and you will be nothing like them you're going to set yourself up for a bad time for the whole ride\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:16\"\n                                  },\n                                  \"trackingParams\": \"CMMDENP2BxiFASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 16 seconds nothing like you and you will be nothing like them you're going to set yourself up for a bad time for the whole ride\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.856319.863420\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"864620\",\n                                  \"endMs\": \"871579\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the tourism matter is that most information system development has very little to do with science\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:24\"\n                                  },\n                                  \"trackingParams\": \"CMIDENP2BxiGASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 24 seconds the tourism matter is that most information system development has very little to do with science\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.864620.871579\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"871579\",\n                                  \"endMs\": \"877259\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yes it's all built on top of computer science yes computer science is what\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:31\"\n                                  },\n                                  \"trackingParams\": \"CMEDENP2BxiHASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 31 seconds yes it's all built on top of computer science yes computer science is what\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.871579.877259\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"877259\",\n                                  \"endMs\": \"884670\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"makes it possible for us to do what it is that we do but it doesn't define what we do and I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:37\"\n                                  },\n                                  \"trackingParams\": \"CMADENP2BxiIASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 37 seconds makes it possible for us to do what it is that we do but it doesn't define what we do and I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.877259.884670\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"884670\",\n                                  \"endMs\": \"889949\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"think in many ways that prism of computer science is harmful to the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:44\"\n                                  },\n                                  \"trackingParams\": \"CL8DENP2BxiJASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 44 seconds think in many ways that prism of computer science is harmful to the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.884670.889949\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"889949\",\n                                  \"endMs\": \"895410\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"development of information systems it's actually not a good view on the world to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:49\"\n                                  },\n                                  \"trackingParams\": \"CL4DENP2BxiKASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 49 seconds development of information systems it's actually not a good view on the world to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.889949.895410\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"895410\",\n                                  \"endMs\": \"902100\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"have just because you can make your Steinway & Sons and you can make the best piano in the world that doesn't\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"14:55\"\n                                  },\n                                  \"trackingParams\": \"CL0DENP2BxiLASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"14 minutes, 55 seconds have just because you can make your Steinway & Sons and you can make the best piano in the world that doesn't\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.895410.902100\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"902100\",\n                                  \"endMs\": \"908990\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"make you a great pianist doesn't mean you can play wonderful tune just because you can create the foundations of which\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:02\"\n                                  },\n                                  \"trackingParams\": \"CLwDENP2BxiMASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 2 seconds make you a great pianist doesn't mean you can play wonderful tune just because you can create the foundations of which\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.902100.908990\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"908990\",\n                                  \"endMs\": \"916199\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"other people can build upon just because you're a great computer scientist doesn't mean you're a great software\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:08\"\n                                  },\n                                  \"trackingParams\": \"CLsDENP2BxiNASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 8 seconds other people can build upon just because you're a great computer scientist doesn't mean you're a great software\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.908990.916199\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"916199\",\n                                  \"endMs\": \"922769\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"writer doesn't mean you're a great programmer of information systems and most of all\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:16\"\n                                  },\n                                  \"trackingParams\": \"CLoDENP2BxiOASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 16 seconds writer doesn't mean you're a great programmer of information systems and most of all\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.916199.922769\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"922769\",\n                                  \"endMs\": \"929220\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"if you are committed to building information system I and I'm wholly committed to building information system\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:22\"\n                                  },\n                                  \"trackingParams\": \"CLkDENP2BxiPASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 22 seconds if you are committed to building information system I and I'm wholly committed to building information system\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.922769.929220\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"929220\",\n                                  \"endMs\": \"934960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I have given up the notion long ago that I was going to get into games programming or vector programming or\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:29\"\n                                  },\n                                  \"trackingParams\": \"CLgDENP2BxiQASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 29 seconds I have given up the notion long ago that I was going to get into games programming or vector programming or\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.929220.934960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"934960\",\n                                  \"endMs\": \"940380\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"anything else that sounds like hard science and is hard I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:34\"\n                                  },\n                                  \"trackingParams\": \"CLcDENP2BxiRASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 34 seconds anything else that sounds like hard science and is hard I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.934960.940380\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"940380\",\n                                  \"endMs\": \"946690\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"think you're going to be much better off but I think it's also really tough because I think most of the paths the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:40\"\n                                  },\n                                  \"trackingParams\": \"CLYDENP2BxiSASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 40 seconds think you're going to be much better off but I think it's also really tough because I think most of the paths the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.940380.946690\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"946690\",\n                                  \"endMs\": \"953860\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"celebrated paths into programming go through caught courses called computer science so you're sort of taught right\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:46\"\n                                  },\n                                  \"trackingParams\": \"CLUDENP2BxiTASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 46 seconds celebrated paths into programming go through caught courses called computer science so you're sort of taught right\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.946690.953860\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"953860\",\n                                  \"endMs\": \"960190\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"from the get-go that computer science like that is the ultimate ideal and what\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"15:53\"\n                                  },\n                                  \"trackingParams\": \"CLQDENP2BxiUASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"15 minutes, 53 seconds from the get-go that computer science like that is the ultimate ideal and what\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.953860.960190\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"960190\",\n                                  \"endMs\": \"965400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you're doing here is just sort of piddling along until you can get to this top of the mountain\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:00\"\n                                  },\n                                  \"trackingParams\": \"CLMDENP2BxiVASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes you're doing here is just sort of piddling along until you can get to this top of the mountain\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.960190.965400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"965400\",\n                                  \"endMs\": \"971490\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"even worse if you actually have a degree in computer science right and now you're\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:05\"\n                                  },\n                                  \"trackingParams\": \"CLIDENP2BxiWASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 5 seconds even worse if you actually have a degree in computer science right and now you're\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.965400.971490\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"971490\",\n                                  \"endMs\": \"978310\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"slumming it with that yet another social network or yet another to-do list I mean that's a recipe for\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:11\"\n                                  },\n                                  \"trackingParams\": \"CLEDENP2BxiXASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 11 seconds slumming it with that yet another social network or yet another to-do list I mean that's a recipe for\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.971490.978310\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"978310\",\n                                  \"endMs\": \"985030\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"self-loathing if I have a new one but as I say this is mostly about the prism of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:18\"\n                                  },\n                                  \"trackingParams\": \"CLADENP2BxiYASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 18 seconds self-loathing if I have a new one but as I say this is mostly about the prism of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.978310.985030\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"985030\",\n                                  \"endMs\": \"991960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"how you're looking at programming what is programming what is writing software what is it that we do every day when we\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:25\"\n                                  },\n                                  \"trackingParams\": \"CK8DENP2BxiZASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 25 seconds how you're looking at programming what is programming what is writing software what is it that we do every day when we\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.985030.991960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"991960\",\n                                  \"endMs\": \"997270\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"create information systems and if you look at it from this prism of the hard\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:31\"\n                                  },\n                                  \"trackingParams\": \"CK4DENP2BxiaASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 31 seconds create information systems and if you look at it from this prism of the hard\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.991960.997270\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"997270\",\n                                  \"endMs\": \"1004170\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"sciences um you think well law of thermo-dynamics physics this is this is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:37\"\n                                  },\n                                  \"trackingParams\": \"CK0DENP2BxibASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 37 seconds sciences um you think well law of thermo-dynamics physics this is this is\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.997270.1004170\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1004170\",\n                                  \"endMs\": \"1009930\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the real serious hard stuff right you will laugh French poetry ha ha ha\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:44\"\n                                  },\n                                  \"trackingParams\": \"CKwDENP2BxicASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 44 seconds the real serious hard stuff right you will laugh French poetry ha ha ha\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1004170.1009930\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1009930\",\n                                  \"endMs\": \"1017250\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"they're all just what analyzing with some schmuck in the 1710 and there's a thousand different interpretations of of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:49\"\n                                  },\n                                  \"trackingParams\": \"CKsDENP2BxidASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 49 seconds they're all just what analyzing with some schmuck in the 1710 and there's a thousand different interpretations of of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1009930.1017250\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1017250\",\n                                  \"endMs\": \"1024150\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what that person actually wrote and what does that actually mean that's pathetic right you can't arrive at any ultimate\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"16:57\"\n                                  },\n                                  \"trackingParams\": \"CKoDENP2BxieASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"16 minutes, 57 seconds what that person actually wrote and what does that actually mean that's pathetic right you can't arrive at any ultimate\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1017250.1024150\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1024150\",\n                                  \"endMs\": \"1031350\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"clear universal truth math there's a truth there's a final result physics\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:04\"\n                                  },\n                                  \"trackingParams\": \"CKkDENP2BxifASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 4 seconds clear universal truth math there's a truth there's a final result physics\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1024150.1031350\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1031350\",\n                                  \"endMs\": \"1038939\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"there's a truth we're knowing more about the natural world in a way where we can be completely confident\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:11\"\n                                  },\n                                  \"trackingParams\": \"CKgDENP2BxigASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 11 seconds there's a truth we're knowing more about the natural world in a way where we can be completely confident\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1031350.1038939\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1038940\",\n                                  \"endMs\": \"1044430\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"mostly in what we know certainly in math right if you carry that over into\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:18\"\n                                  },\n                                  \"trackingParams\": \"CKcDENP2BxihASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 18 seconds mostly in what we know certainly in math right if you carry that over into\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1038940.1044430\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1044430\",\n                                  \"endMs\": \"1050240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"programming you end up with like this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:24\"\n                                  },\n                                  \"trackingParams\": \"CKYDENP2BxiiASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 24 seconds programming you end up with like this\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1044430.1050240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1050240\",\n                                  \"endMs\": \"1056540\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"law of Demeter practices and principles\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:30\"\n                                  },\n                                  \"trackingParams\": \"CKUDENP2BxijASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 30 seconds law of Demeter practices and principles\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1050240.1056540\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1056540\",\n                                  \"endMs\": \"1063870\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"who sort of project that their universal truths about the natural world that this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:36\"\n                                  },\n                                  \"trackingParams\": \"CKQDENP2BxikASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 36 seconds who sort of project that their universal truths about the natural world that this\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1056540.1063870\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1063870\",\n                                  \"endMs\": \"1069000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"is how good programs are made and this is not argument the only argument is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:43\"\n                                  },\n                                  \"trackingParams\": \"CKMDENP2BxilASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 43 seconds is how good programs are made and this is not argument the only argument is\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1063870.1069000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1069000\",\n                                  \"endMs\": \"1075950\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"whether you're professional and following the laws or you're an amateur and you're breaking them\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:49\"\n                                  },\n                                  \"trackingParams\": \"CKIDENP2BximASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 49 seconds whether you're professional and following the laws or you're an amateur and you're breaking them\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1069000.1075950\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1077090\",\n                                  \"endMs\": \"1083160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"when I look at computer program when I reach most read most programs I'm not\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"17:57\"\n                                  },\n                                  \"trackingParams\": \"CKEDENP2BxinASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"17 minutes, 57 seconds when I look at computer program when I reach most read most programs I'm not\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1077090.1083160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1083160\",\n                                  \"endMs\": \"1090690\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"reading hard sciences it is much more like studying 17th century French poetry what the did this guy mean like I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:03\"\n                                  },\n                                  \"trackingParams\": \"CKADENP2BxioASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 3 seconds reading hard sciences it is much more like studying 17th century French poetry what the did this guy mean like I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1083160.1090690\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1090690\",\n                                  \"endMs\": \"1098040\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"can't follow this at all like is this some weird reference to some place somewhere what's going on here it's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:10\"\n                                  },\n                                  \"trackingParams\": \"CJ8DENP2BxipASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 10 seconds can't follow this at all like is this some weird reference to some place somewhere what's going on here it's\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1090690.1098040\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1098040\",\n                                  \"endMs\": \"1104970\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"actually more like forensics it's more like analysis it's much more subjective like what is actually going on what were\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:18\"\n                                  },\n                                  \"trackingParams\": \"CJ4DENP2BxiqASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 18 seconds actually more like forensics it's more like analysis it's much more subjective like what is actually going on what were\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1098040.1104970\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1104970\",\n                                  \"endMs\": \"1112380\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"they trying to communicate whatever what's just going on here right so I just I find it so funny that the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:24\"\n                                  },\n                                  \"trackingParams\": \"CJ0DENP2BxirASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 24 seconds they trying to communicate whatever what's just going on here right so I just I find it so funny that the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1104970.1112380\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1112380\",\n                                  \"endMs\": \"1118340\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"programmers who work in programming and they laugh of all these subjective\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:32\"\n                                  },\n                                  \"trackingParams\": \"CJwDENP2BxisASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 32 seconds programmers who work in programming and they laugh of all these subjective\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1112380.1118340\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1118340\",\n                                  \"endMs\": \"1124800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"fields of endeavor when that is what they do every day they just no one doing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:38\"\n                                  },\n                                  \"trackingParams\": \"CJsDENP2BxitASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 38 seconds fields of endeavor when that is what they do every day they just no one doing\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1118340.1124800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1124800\",\n                                  \"endMs\": \"1129930\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"is computer science this is empirical truth bla bla bla we have lost bla bla\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:44\"\n                                  },\n                                  \"trackingParams\": \"CJoDENP2BxiuASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 44 seconds is computer science this is empirical truth bla bla bla we have lost bla bla\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1124800.1129930\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1129930\",\n                                  \"endMs\": \"1135840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"bla I think be the bottom line of that is when you go in with that notion when you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:49\"\n                                  },\n                                  \"trackingParams\": \"CJkDENP2BxivASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 49 seconds bla I think be the bottom line of that is when you go in with that notion when you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1129930.1135840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1135840\",\n                                  \"endMs\": \"1142800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"go in with the notion that we can actually discover laws of programming like law of demeter of how we should be\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"18:55\"\n                                  },\n                                  \"trackingParams\": \"CJgDENP2BxiwASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"18 minutes, 55 seconds go in with the notion that we can actually discover laws of programming like law of demeter of how we should be\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1135840.1142800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1142800\",\n                                  \"endMs\": \"1149460\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"creating our programs you load yourself into this belief that there are some\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:02\"\n                                  },\n                                  \"trackingParams\": \"CJcDENP2BxixASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 2 seconds creating our programs you load yourself into this belief that there are some\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1142800.1149460\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1149460\",\n                                  \"endMs\": \"1155660\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"practices that are just true they're not up for debate not up for discussion\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:09\"\n                                  },\n                                  \"trackingParams\": \"CJYDENP2BxiyASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 9 seconds practices that are just true they're not up for debate not up for discussion\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1149460.1155660\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1155660\",\n                                  \"endMs\": \"1164120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"there's science that what we do is science well I think there's another word for sort of those delusions\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:15\"\n                                  },\n                                  \"trackingParams\": \"CJUDENP2BxizASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 15 seconds there's science that what we do is science well I think there's another word for sort of those delusions\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1155660.1164120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1164120\",\n                                  \"endMs\": \"1169190\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"pseudoscience when people think they're doing science and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:24\"\n                                  },\n                                  \"trackingParams\": \"CJQDENP2Bxi0ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 24 seconds pseudoscience when people think they're doing science and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1164120.1169190\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1169190\",\n                                  \"endMs\": \"1175020\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"they're not actually doing science that's pseudoscience I think a lot of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:29\"\n                                  },\n                                  \"trackingParams\": \"CJMDENP2Bxi1ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 29 seconds they're not actually doing science that's pseudoscience I think a lot of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1169190.1175020\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1175020\",\n                                  \"endMs\": \"1182610\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what's going on in software methodology practices pseudoscience which would be fine if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:35\"\n                                  },\n                                  \"trackingParams\": \"CJIDENP2Bxi2ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 35 seconds what's going on in software methodology practices pseudoscience which would be fine if\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1175020.1182610\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1182610\",\n                                  \"endMs\": \"1188460\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"people would accept that and say yes what I'm doing pseudoscience like I'm not finding any grand truth sir but\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:42\"\n                                  },\n                                  \"trackingParams\": \"CJEDENP2Bxi3ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 42 seconds people would accept that and say yes what I'm doing pseudoscience like I'm not finding any grand truth sir but\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1182610.1188460\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1188460\",\n                                  \"endMs\": \"1195650\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"they're not right they're expounding and that this is this is the truth well here's another pseudoscience uh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:48\"\n                                  },\n                                  \"trackingParams\": \"CJADENP2Bxi4ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 48 seconds they're not right they're expounding and that this is this is the truth well here's another pseudoscience uh\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1188460.1195650\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1195650\",\n                                  \"endMs\": \"1202050\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"diet schemes I think diets are actually incredibly\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"19:55\"\n                                  },\n                                  \"trackingParams\": \"CI8DENP2Bxi5ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"19 minutes, 55 seconds diet schemes I think diets are actually incredibly\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1195650.1202050\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1202050\",\n                                  \"endMs\": \"1210480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"similar to most software methodology approaches they all sort of exposed that I have the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:02\"\n                                  },\n                                  \"trackingParams\": \"CI4DENP2Bxi6ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 2 seconds similar to most software methodology approaches they all sort of exposed that I have the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1202050.1210480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1210480\",\n                                  \"endMs\": \"1215880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"truth what you need to get slim and healthy is the ten day green smoothie\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:10\"\n                                  },\n                                  \"trackingParams\": \"CI0DENP2Bxi7ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 10 seconds truth what you need to get slim and healthy is the ten day green smoothie\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1210480.1215880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1215880\",\n                                  \"endMs\": \"1222870\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"cleanse that is to sooth that's how you get it right and then you loop it so that that's okay smoothies sounds that's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:15\"\n                                  },\n                                  \"trackingParams\": \"CIwDENP2Bxi8ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 15 seconds cleanse that is to sooth that's how you get it right and then you loop it so that that's okay smoothies sounds that's\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1215880.1222870\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1222870\",\n                                  \"endMs\": \"1229500\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"good but what about this super shred diet like I lose 20 pounds in four weeks that's certainly better than ten pounds\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:22\"\n                                  },\n                                  \"trackingParams\": \"CIsDENP2Bxi9ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 22 seconds good but what about this super shred diet like I lose 20 pounds in four weeks that's certainly better than ten pounds\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1222870.1229500\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1229500\",\n                                  \"endMs\": \"1235980\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and I don't know ten weeks or whatever that hungry diet girl is promising I'll go with that super shred guy like he's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:29\"\n                                  },\n                                  \"trackingParams\": \"CIoDENP2Bxi-ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 29 seconds and I don't know ten weeks or whatever that hungry diet girl is promising I'll go with that super shred guy like he's\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1229500.1235980\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1235980\",\n                                  \"endMs\": \"1242160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"got to have the truth right and it's so funny if you read any diet books a diet books are incredibly popular if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:35\"\n                                  },\n                                  \"trackingParams\": \"CIkDENP2Bxi_ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 35 seconds got to have the truth right and it's so funny if you read any diet books a diet books are incredibly popular if\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1235980.1242160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1242160\",\n                                  \"endMs\": \"1249380\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you look at the most popular book on Amazon the top 100 list a lot of them are diet books people want to be told\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:42\"\n                                  },\n                                  \"trackingParams\": \"CIgDENP2BxjAASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 42 seconds you look at the most popular book on Amazon the top 100 list a lot of them are diet books people want to be told\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1242160.1249380\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1249380\",\n                                  \"endMs\": \"1257250\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"how they can cheat the basics I think software development is exactly like that I think software developers are\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:49\"\n                                  },\n                                  \"trackingParams\": \"CIcDENP2BxjBASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 49 seconds how they can cheat the basics I think software development is exactly like that I think software developers are\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1249380.1257250\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1257250\",\n                                  \"endMs\": \"1264030\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"exactly like people trying to lose ten pounds and thinking you know what all these\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"20:57\"\n                                  },\n                                  \"trackingParams\": \"CIYDENP2BxjCASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"20 minutes, 57 seconds exactly like people trying to lose ten pounds and thinking you know what all these\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1257250.1264030\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1264030\",\n                                  \"endMs\": \"1270360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"exercising just eating healthier that's a little too hard let's let's listen to this super shred guy he's got to have\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:04\"\n                                  },\n                                  \"trackingParams\": \"CIUDENP2BxjDASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 4 seconds exercising just eating healthier that's a little too hard let's let's listen to this super shred guy he's got to have\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1264030.1270360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1270360\",\n                                  \"endMs\": \"1276960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the answer an answer that's less painful less simple and basic there's got to be some\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:10\"\n                                  },\n                                  \"trackingParams\": \"CIQDENP2BxjEASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 10 seconds the answer an answer that's less painful less simple and basic there's got to be some\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1270360.1276960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1276960\",\n                                  \"endMs\": \"1282660\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"grand secret I just don't know yet if I can just learn the secret then everything is going to be great right\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:16\"\n                                  },\n                                  \"trackingParams\": \"CIMDENP2BxjFASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 16 seconds grand secret I just don't know yet if I can just learn the secret then everything is going to be great right\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1276960.1282660\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1282660\",\n                                  \"endMs\": \"1290540\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"but it's pseudoscience most diets are based on anecdotes they're based on one guy\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:22\"\n                                  },\n                                  \"trackingParams\": \"CIIDENP2BxjGASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 22 seconds but it's pseudoscience most diets are based on anecdotes they're based on one guy\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1282660.1290540\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1290540\",\n                                  \"endMs\": \"1295770\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"trying something or looking at a few people a tiny sample size it's just pew\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:30\"\n                                  },\n                                  \"trackingParams\": \"CIEDENP2BxjHASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 30 seconds trying something or looking at a few people a tiny sample size it's just pew\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1290540.1295770\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1295770\",\n                                  \"endMs\": \"1302370\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"pour pure poor science external variables could uncontrolled\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:35\"\n                                  },\n                                  \"trackingParams\": \"CIADENP2BxjIASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 35 seconds pour pure poor science external variables could uncontrolled\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1295770.1302370\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1302370\",\n                                  \"endMs\": \"1307560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"experience that run for too long you can't derive any absolute truth from it but people keep arriving at absolute\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:42\"\n                                  },\n                                  \"trackingParams\": \"CP8CENP2BxjJASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 42 seconds experience that run for too long you can't derive any absolute truth from it but people keep arriving at absolute\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1302370.1307560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1307560\",\n                                  \"endMs\": \"1314120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"truths and just like feeling a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:47\"\n                                  },\n                                  \"trackingParams\": \"CP4CENP2BxjKASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 47 seconds truths and just like feeling a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1307560.1314120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1314120\",\n                                  \"endMs\": \"1320370\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"little overweight and most people do at some point in their life everybody wants to lose whatever it is they want to feel\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"21:54\"\n                                  },\n                                  \"trackingParams\": \"CP0CENP2BxjLASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"21 minutes, 54 seconds little overweight and most people do at some point in their life everybody wants to lose whatever it is they want to feel\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1314120.1320370\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1320370\",\n                                  \"endMs\": \"1326420\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"healthier even if they are their correct weight they want to be in better shape all our code bases are exactly like that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:00\"\n                                  },\n                                  \"trackingParams\": \"CPwCENP2BxjMASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes healthier even if they are their correct weight they want to be in better shape all our code bases are exactly like that\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1320370.1326420\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1326420\",\n                                  \"endMs\": \"1333720\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"everyone has like oh I'd love that this part of the code base is not that clean right so we have that a feeling of being\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:06\"\n                                  },\n                                  \"trackingParams\": \"CPsCENP2BxjNASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 6 seconds everyone has like oh I'd love that this part of the code base is not that clean right so we have that a feeling of being\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1326420.1333720\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1333720\",\n                                  \"endMs\": \"1339510\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a little insecure about our quote code quality just like most people\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:13\"\n                                  },\n                                  \"trackingParams\": \"CPoCENP2BxjOASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 13 seconds a little insecure about our quote code quality just like most people\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1333720.1339510\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1339510\",\n                                  \"endMs\": \"1346950\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"are a little insecure at least at certain times of their life about their body right so we're ripe for somebody to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:19\"\n                                  },\n                                  \"trackingParams\": \"CPkCENP2BxjPASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 19 seconds are a little insecure at least at certain times of their life about their body right so we're ripe for somebody to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1339510.1346950\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1346950\",\n                                  \"endMs\": \"1354270\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"come in and tell us what's wrong to fix it for us by just saying oh no no you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:26\"\n                                  },\n                                  \"trackingParams\": \"CPgCENP2BxjQASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 26 seconds come in and tell us what's wrong to fix it for us by just saying oh no no you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1346950.1354270\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1354270\",\n                                  \"endMs\": \"1361380\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"don't have to do any of the hard stuff writing good code do you know what that's about about this one practice there's one secret that they don't want\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:34\"\n                                  },\n                                  \"trackingParams\": \"CPcCENP2BxjRASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 34 seconds don't have to do any of the hard stuff writing good code do you know what that's about about this one practice there's one secret that they don't want\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1354270.1361380\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1361380\",\n                                  \"endMs\": \"1367110\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you to know if I teach you that then all your code is going to be wonderful but\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:41\"\n                                  },\n                                  \"trackingParams\": \"CPYCENP2BxjSASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 41 seconds you to know if I teach you that then all your code is going to be wonderful but\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1361380.1367110\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1367110\",\n                                  \"endMs\": \"1372240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"right now you're not a professional you're an amateur you're writing dirty\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:47\"\n                                  },\n                                  \"trackingParams\": \"CPUCENP2BxjTASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 47 seconds right now you're not a professional you're an amateur you're writing dirty\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1367110.1372240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1372240\",\n                                  \"endMs\": \"1379860\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"code you should feel really bad about that you have sinned but I will give you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:52\"\n                                  },\n                                  \"trackingParams\": \"CPQCENP2BxjUASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 52 seconds code you should feel really bad about that you have sinned but I will give you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1372240.1379860\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1379860\",\n                                  \"endMs\": \"1385730\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"absolution I have the pathway to clean code\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"22:59\"\n                                  },\n                                  \"trackingParams\": \"CPMCENP2BxjVASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"22 minutes, 59 seconds absolution I have the pathway to clean code\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1379860.1385730\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1385730\",\n                                  \"endMs\": \"1390930\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and it hits a lot of people ride in the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:05\"\n                                  },\n                                  \"trackingParams\": \"CPICENP2BxjWASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 5 seconds and it hits a lot of people ride in the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1385730.1390930\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1390930\",\n                                  \"endMs\": \"1397290\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"imposter plexus like oh you sang my coat is dirty yeah guess it is a little dirty\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:10\"\n                                  },\n                                  \"trackingParams\": \"CPECENP2BxjXASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 10 seconds imposter plexus like oh you sang my coat is dirty yeah guess it is a little dirty\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1390930.1397290\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1397290\",\n                                  \"endMs\": \"1403260\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"there's this one part that's like maybe I'm not really a computer scientist maybe it doesn't really I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:17\"\n                                  },\n                                  \"trackingParams\": \"CPACENP2BxjYASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 17 seconds there's this one part that's like maybe I'm not really a computer scientist maybe it doesn't really I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1397290.1403260\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1403260\",\n                                  \"endMs\": \"1408600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"don't really belong here amongst the programmers can you please tell me how\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:23\"\n                                  },\n                                  \"trackingParams\": \"CO8CENP2BxjZASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 23 seconds don't really belong here amongst the programmers can you please tell me how\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1403260.1408600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1408600\",\n                                  \"endMs\": \"1414740\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"do I get to be a computer scientist how can I get to belong\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:28\"\n                                  },\n                                  \"trackingParams\": \"CO4CENP2BxjaASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 28 seconds do I get to be a computer scientist how can I get to belong\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1408600.1414740\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1414740\",\n                                  \"endMs\": \"1420150\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"amongst these deemed professional programmers can you tell me how and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:34\"\n                                  },\n                                  \"trackingParams\": \"CO0CENP2BxjbASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 34 seconds amongst these deemed professional programmers can you tell me how and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1414740.1420150\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1420150\",\n                                  \"endMs\": \"1425340\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"there are lots of people willing to tell you how that the salvation will come\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:40\"\n                                  },\n                                  \"trackingParams\": \"COwCENP2BxjcASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 40 seconds there are lots of people willing to tell you how that the salvation will come\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1420150.1425340\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1425340\",\n                                  \"endMs\": \"1432180\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"through these patterns and practices and as long as you follow these ten commandments of good code all shall be\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:45\"\n                                  },\n                                  \"trackingParams\": \"COsCENP2BxjdASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 45 seconds through these patterns and practices and as long as you follow these ten commandments of good code all shall be\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1425340.1432180\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1432180\",\n                                  \"endMs\": \"1439950\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"well okay I think the most popular commandment I'm\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:52\"\n                                  },\n                                  \"trackingParams\": \"COoCENP2BxjeASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 52 seconds well okay I think the most popular commandment I'm\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1432180.1439950\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1439950\",\n                                  \"endMs\": \"1446190\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"going to spend some time on that the most popular practice the most popular pattern for making people feel shitty\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"23:59\"\n                                  },\n                                  \"trackingParams\": \"COkCENP2BxjfASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"23 minutes, 59 seconds going to spend some time on that the most popular practice the most popular pattern for making people feel shitty\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1439950.1446190\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1446190\",\n                                  \"endMs\": \"1453470\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"about their code and shitty about themselves as shitty about their path through programming\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:06\"\n                                  },\n                                  \"trackingParams\": \"COgCENP2BxjgASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 6 seconds about their code and shitty about themselves as shitty about their path through programming\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1446190.1453470\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1454140\",\n                                  \"endMs\": \"1462180\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"is TDD [Applause] TDD is the most successful software diet\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:14\"\n                                  },\n                                  \"trackingParams\": \"COcCENP2BxjhASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 14 seconds is TDD [Applause] TDD is the most successful software diet\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1454140.1462180\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1462180\",\n                                  \"endMs\": \"1467540\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of all times [Applause]\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:22\"\n                                  },\n                                  \"trackingParams\": \"COYCENP2BxjiASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 22 seconds of all times [Applause]\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1462180.1467540\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1467540\",\n                                  \"endMs\": \"1474030\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's so alluring it has such an appeal in its basic principles that everyone\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:27\"\n                                  },\n                                  \"trackingParams\": \"COUCENP2BxjjASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 27 seconds it's so alluring it has such an appeal in its basic principles that everyone\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1467540.1474030\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1474030\",\n                                  \"endMs\": \"1479400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"gets wrapped up in it I got wrapped up in it for quite a while I got wrapped up\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:34\"\n                                  },\n                                  \"trackingParams\": \"COQCENP2BxjkASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 34 seconds gets wrapped up in it I got wrapped up in it for quite a while I got wrapped up\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1474030.1479400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1479400\",\n                                  \"endMs\": \"1485400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in the storytelling that all software before TDD was and unprofessional\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:39\"\n                                  },\n                                  \"trackingParams\": \"COMCENP2BxjlASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 39 seconds in the storytelling that all software before TDD was and unprofessional\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1479400.1485400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1485400\",\n                                  \"endMs\": \"1493170\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and at the only way to arrive at clean code was to follow the principles of TDD\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:45\"\n                                  },\n                                  \"trackingParams\": \"COICENP2BxjmASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 45 seconds and at the only way to arrive at clean code was to follow the principles of TDD\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1485400.1493170\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1493170\",\n                                  \"endMs\": \"1499740\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and the principles of TDD mind you or not about the tests it's about test\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:53\"\n                                  },\n                                  \"trackingParams\": \"COECENP2BxjnASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 53 seconds and the principles of TDD mind you or not about the tests it's about test\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1493170.1499740\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1499740\",\n                                  \"endMs\": \"1507180\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"first it's about test-driven design right then we have tests afterwards\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"24:59\"\n                                  },\n                                  \"trackingParams\": \"COACENP2BxjoASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"24 minutes, 59 seconds first it's about test-driven design right then we have tests afterwards\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1499740.1507180\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1507180\",\n                                  \"endMs\": \"1512460\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that's just an accidental side-effect a benefit if you will after\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:07\"\n                                  },\n                                  \"trackingParams\": \"CN8CENP2BxjpASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 7 seconds that's just an accidental side-effect a benefit if you will after\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1507180.1512460\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1512460\",\n                                  \"endMs\": \"1520020\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the fact and it's the perfect diet I tried multiple times but usually how it goes\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:12\"\n                                  },\n                                  \"trackingParams\": \"CN4CENP2BxjqASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 12 seconds the fact and it's the perfect diet I tried multiple times but usually how it goes\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1512460.1520020\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1520020\",\n                                  \"endMs\": \"1525240\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"who dies you try one and doesn't really work and we fall off the whack and then\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:20\"\n                                  },\n                                  \"trackingParams\": \"CN0CENP2BxjrASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 20 seconds who dies you try one and doesn't really work and we fall off the whack and then\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1520020.1525240\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1525240\",\n                                  \"endMs\": \"1531600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a few months later you try again and you feel bad about it the whole time and that's how I felt about TDD for a long time I felt like TDD was what I was\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:25\"\n                                  },\n                                  \"trackingParams\": \"CNwCENP2BxjsASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 25 seconds a few months later you try again and you feel bad about it the whole time and that's how I felt about TDD for a long time I felt like TDD was what I was\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1525240.1531600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1531600\",\n                                  \"endMs\": \"1537330\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"supposed to do I was supposed to write all my tests first and then I would be\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:31\"\n                                  },\n                                  \"trackingParams\": \"CNsCENP2BxjtASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 31 seconds supposed to do I was supposed to write all my tests first and then I would be\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1531600.1537330\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1537330\",\n                                  \"endMs\": \"1544770\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"allowed to write my code and it just didn't work I kept just feeling like this is not I'm\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:37\"\n                                  },\n                                  \"trackingParams\": \"CNoCENP2BxjuASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 37 seconds allowed to write my code and it just didn't work I kept just feeling like this is not I'm\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1537330.1544770\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1544770\",\n                                  \"endMs\": \"1552410\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"not arriving at something better here when I'm driving my design by writing my test first the code I look at afterwards\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:44\"\n                                  },\n                                  \"trackingParams\": \"CNkCENP2BxjvASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 44 seconds not arriving at something better here when I'm driving my design by writing my test first the code I look at afterwards\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1544770.1552410\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1552410\",\n                                  \"endMs\": \"1559260\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's not better it's not clear the dirty code I wrote without being\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:52\"\n                                  },\n                                  \"trackingParams\": \"CNgCENP2BxjwASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 52 seconds it's not better it's not clear the dirty code I wrote without being\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1552410.1559260\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1559260\",\n                                  \"endMs\": \"1566280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"test for in first yah-tchi looks better but so successful as TDD been that for\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"25:59\"\n                                  },\n                                  \"trackingParams\": \"CNcCENP2BxjxASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"25 minutes, 59 seconds test for in first yah-tchi looks better but so successful as TDD been that for\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1559260.1566280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1566280\",\n                                  \"endMs\": \"1572330\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the longest time until actually fairly recently I just thought well I'm the wrong doom I'm the one doing it wrong\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:06\"\n                                  },\n                                  \"trackingParams\": \"CNYCENP2BxjyASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 6 seconds the longest time until actually fairly recently I just thought well I'm the wrong doom I'm the one doing it wrong\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1566280.1572330\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1572330\",\n                                  \"endMs\": \"1578550\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"TDD is not a fault right just because everybody's doing TDD wrong doesn't mean\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:12\"\n                                  },\n                                  \"trackingParams\": \"CNUCENP2BxjzASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 12 seconds TDD is not a fault right just because everybody's doing TDD wrong doesn't mean\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1572330.1578550\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1578550\",\n                                  \"endMs\": \"1584310\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that there's no anything wrong with TDD it's just something wrong with all of you that's the problem if you would just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:18\"\n                                  },\n                                  \"trackingParams\": \"CNQCENP2Bxj0ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 18 seconds that there's no anything wrong with TDD it's just something wrong with all of you that's the problem if you would just\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1578550.1584310\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1584310\",\n                                  \"endMs\": \"1589510\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"be more faithful to the practices everything would be great and that's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:24\"\n                                  },\n                                  \"trackingParams\": \"CNMCENP2Bxj1ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 24 seconds be more faithful to the practices everything would be great and that's\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1584310.1589510\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1589510\",\n                                  \"endMs\": \"1594900\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what makes it such a great diet that it keeps people in the perpetual state of feeling inadequate\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:29\"\n                                  },\n                                  \"trackingParams\": \"CNICENP2Bxj2ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 29 seconds what makes it such a great diet that it keeps people in the perpetual state of feeling inadequate\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1589510.1594900\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1594900\",\n                                  \"endMs\": \"1601960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so you keep having to buy more books and attend more conference talks and attend\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:34\"\n                                  },\n                                  \"trackingParams\": \"CNECENP2Bxj3ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 34 seconds so you keep having to buy more books and attend more conference talks and attend\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1594900.1601960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1601960\",\n                                  \"endMs\": \"1608010\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"more workshops and hire more consultants to teach you to be tour to the religion of TDD\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:41\"\n                                  },\n                                  \"trackingParams\": \"CNACENP2Bxj4ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 41 seconds more workshops and hire more consultants to teach you to be tour to the religion of TDD\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1601960.1608010\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1608010\",\n                                  \"endMs\": \"1613630\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"hogwash let's look at some code so here's a very\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:48\"\n                                  },\n                                  \"trackingParams\": \"CM8CENP2Bxj5ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 48 seconds hogwash let's look at some code so here's a very\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1608010.1613630\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1613630\",\n                                  \"endMs\": \"1619210\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"simple piece of code person has an age method that calculates\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:53\"\n                                  },\n                                  \"trackingParams\": \"CM4CENP2Bxj6ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 53 seconds simple piece of code person has an age method that calculates\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1613630.1619210\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1619210\",\n                                  \"endMs\": \"1624910\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"how old some somebody is I'm we have a test for it this piece of code depends\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"26:59\"\n                                  },\n                                  \"trackingParams\": \"CM0CENP2Bxj7ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"26 minutes, 59 seconds how old some somebody is I'm we have a test for it this piece of code depends\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1619210.1624910\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1624910\",\n                                  \"endMs\": \"1631929\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"on the world it directly refers to date today it's an explicit dependency you cannot change it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:04\"\n                                  },\n                                  \"trackingParams\": \"CMwCENP2Bxj8ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 4 seconds on the world it directly refers to date today it's an explicit dependency you cannot change it\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1624910.1631929\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1631929\",\n                                  \"endMs\": \"1637690\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in there well in a lot of languages that's a problem like how are you actually going to test this if you can't\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:11\"\n                                  },\n                                  \"trackingParams\": \"CMsCENP2Bxj9ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 11 seconds in there well in a lot of languages that's a problem like how are you actually going to test this if you can't\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1631929.1637690\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1637690\",\n                                  \"endMs\": \"1645190\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"somehow figure out how to change the date of today like every time you run your test it might be a different day and it might be broken well in Ruby it's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:17\"\n                                  },\n                                  \"trackingParams\": \"CMoCENP2Bxj-ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 17 seconds somehow figure out how to change the date of today like every time you run your test it might be a different day and it might be broken well in Ruby it's\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1637690.1645190\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1645190\",\n                                  \"endMs\": \"1651840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"really easy we just stop that constant and make it work that's what the travel to method is about right\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:25\"\n                                  },\n                                  \"trackingParams\": \"CMkCENP2Bxj_ASITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 25 seconds really easy we just stop that constant and make it work that's what the travel to method is about right\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1645190.1651840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1651840\",\n                                  \"endMs\": \"1657300\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"proponents of TDD will look at that code and say dirty dirty code\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:31\"\n                                  },\n                                  \"trackingParams\": \"CMgCENP2BxiAAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 31 seconds proponents of TDD will look at that code and say dirty dirty code\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1651840.1657300\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1657300\",\n                                  \"endMs\": \"1662890\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"explicit dependencies hidden inside you're mocking a global object what the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:37\"\n                                  },\n                                  \"trackingParams\": \"CMcCENP2BxiBAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 37 seconds explicit dependencies hidden inside you're mocking a global object what the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1657300.1662890\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1662890\",\n                                  \"endMs\": \"1669670\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \" you need to shape up here's the shaped up version we inject\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:42\"\n                                  },\n                                  \"trackingParams\": \"CMYCENP2BxiCAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 42 seconds  you need to shape up here's the shaped up version we inject\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1662890.1669670\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1669670\",\n                                  \"endMs\": \"1676000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"our dependency so we have a default of date today but we can put in our own in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:49\"\n                                  },\n                                  \"trackingParams\": \"CMUCENP2BxiDAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 49 seconds our dependency so we have a default of date today but we can put in our own in\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1669670.1676000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1676000\",\n                                  \"endMs\": \"1681070\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the test we can put in our own date right this is much cleaner like no great\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"27:56\"\n                                  },\n                                  \"trackingParams\": \"CMQCENP2BxiEAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"27 minutes, 56 seconds the test we can put in our own date right this is much cleaner like no great\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1676000.1681070\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1681070\",\n                                  \"endMs\": \"1687730\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we improved our code base did we is this a better code base is this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:01\"\n                                  },\n                                  \"trackingParams\": \"CMMCENP2BxiFAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 1 second we improved our code base did we is this a better code base is this\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1681070.1687730\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1687730\",\n                                  \"endMs\": \"1695309\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"method better than what we just had there is it simpler is it clearer no it's easier to test\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:07\"\n                                  },\n                                  \"trackingParams\": \"CMICENP2BxiGAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 7 seconds method better than what we just had there is it simpler is it clearer no it's easier to test\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1687730.1695309\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1695309\",\n                                  \"endMs\": \"1700809\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and that's the important point right that's the important point in all these debates it's just is it easier to test\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:15\"\n                                  },\n                                  \"trackingParams\": \"CMECENP2BxiHAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 15 seconds and that's the important point right that's the important point in all these debates it's just is it easier to test\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1695309.1700809\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1700809\",\n                                  \"endMs\": \"1707710\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that's the measure of success I think that's a shitty measure of success I think they're a much higher ideal than\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:20\"\n                                  },\n                                  \"trackingParams\": \"CMACENP2BxiIAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 20 seconds that's the measure of success I think that's a shitty measure of success I think they're a much higher ideal than\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1700809.1707710\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1707710\",\n                                  \"endMs\": \"1713190\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"just whether something is easy to test but it gets worse\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:27\"\n                                  },\n                                  \"trackingParams\": \"CL8CENP2BxiJAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 27 seconds just whether something is easy to test but it gets worse\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1707710.1713190\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1713190\",\n                                  \"endMs\": \"1719290\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"here's another example if you actually have a method that depends on another method where you have to inject the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:33\"\n                                  },\n                                  \"trackingParams\": \"CL4CENP2BxiKAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 33 seconds here's another example if you actually have a method that depends on another method where you have to inject the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1713190.1719290\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1719290\",\n                                  \"endMs\": \"1726500\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"dependency all the way down now you're really muddying things up and now the code is really starting to get nasty and this is such a simple example\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:39\"\n                                  },\n                                  \"trackingParams\": \"CL0CENP2BxiLAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 39 seconds dependency all the way down now you're really muddying things up and now the code is really starting to get nasty and this is such a simple example\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1719290.1726500\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1726500\",\n                                  \"endMs\": \"1734090\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I'm actually posted this example on line 4 and had arguments with TDD proponents about that and yes this is a movie like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:46\"\n                                  },\n                                  \"trackingParams\": \"CLwCENP2BxiMAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 46 seconds I'm actually posted this example on line 4 and had arguments with TDD proponents about that and yes this is a movie like\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1726500.1734090\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1734090\",\n                                  \"endMs\": \"1741290\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Oh what doesn't matter you're just injecting one dependency what does it matter it's not that big of deal right yes it is because this is exactly the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"28:54\"\n                                  },\n                                  \"trackingParams\": \"CLsCENP2BxiNAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"28 minutes, 54 seconds Oh what doesn't matter you're just injecting one dependency what does it matter it's not that big of deal right yes it is because this is exactly the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1734090.1741290\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1741290\",\n                                  \"endMs\": \"1746750\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"type of thinking that leads you down a really nasty path let's look at another\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:01\"\n                                  },\n                                  \"trackingParams\": \"CLoCENP2BxiOAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 1 second type of thinking that leads you down a really nasty path let's look at another\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1741290.1746750\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1746750\",\n                                  \"endMs\": \"1752840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"example here's the standard rails controller it has reliance in the world it relies\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:06\"\n                                  },\n                                  \"trackingParams\": \"CLkCENP2BxiPAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 6 seconds example here's the standard rails controller it has reliance in the world it relies\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1746750.1752840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1752840\",\n                                  \"endMs\": \"1759320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"on a before action that ensures permissions it sets up a new object and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:12\"\n                                  },\n                                  \"trackingParams\": \"CLgCENP2BxiQAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 12 seconds on a before action that ensures permissions it sets up a new object and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1752840.1759320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1759320\",\n                                  \"endMs\": \"1766190\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"sends out an email and then it responds to something right the whole purpose of the controller and rails is to sort of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:19\"\n                                  },\n                                  \"trackingParams\": \"CLcCENP2BxiRAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 19 seconds sends out an email and then it responds to something right the whole purpose of the controller and rails is to sort of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1759320.1766190\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1766190\",\n                                  \"endMs\": \"1772970\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"direct the world it's to interact with the world but how do you unit test that right that's really hard it's relying on\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:26\"\n                                  },\n                                  \"trackingParams\": \"CLYCENP2BxiSAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 26 seconds direct the world it's to interact with the world but how do you unit test that right that's really hard it's relying on\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1766190.1772970\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1772970\",\n                                  \"endMs\": \"1778970\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the entire world if we're following this scientific approach of unit testing where we are isolating all variables\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:32\"\n                                  },\n                                  \"trackingParams\": \"CLUCENP2BxiTAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 32 seconds the entire world if we're following this scientific approach of unit testing where we are isolating all variables\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1772970.1778970\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1778970\",\n                                  \"endMs\": \"1785860\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"holding everything else constant except for these two things what goes in what comes out this is bad\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:38\"\n                                  },\n                                  \"trackingParams\": \"CLQCENP2BxiUAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 38 seconds holding everything else constant except for these two things what goes in what comes out this is bad\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1778970.1785860\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1785860\",\n                                  \"endMs\": \"1791870\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"right if we instead put in something like a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:45\"\n                                  },\n                                  \"trackingParams\": \"CLMCENP2BxiVAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 45 seconds right if we instead put in something like a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1785860.1791870\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1791870\",\n                                  \"endMs\": \"1797000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"person creation command and hide away all the actual doing up the controller\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:51\"\n                                  },\n                                  \"trackingParams\": \"CLICENP2BxiWAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 51 seconds person creation command and hide away all the actual doing up the controller\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1791870.1797000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1797000\",\n                                  \"endMs\": \"1803080\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and then we inject all the stuff that it depends on we can test person creation command really well\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"29:57\"\n                                  },\n                                  \"trackingParams\": \"CLECENP2BxiXAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"29 minutes, 57 seconds and then we inject all the stuff that it depends on we can test person creation command really well\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1797000.1803080\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1803080\",\n                                  \"endMs\": \"1809090\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"is that code better is that code simpler is it clearer would you rather look at\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:03\"\n                                  },\n                                  \"trackingParams\": \"CLACENP2BxiYAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 3 seconds is that code better is that code simpler is it clearer would you rather look at\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1803080.1809090\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1809090\",\n                                  \"endMs\": \"1817250\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this and then understand what the system does so would you rather look at this and try to figure out where this this thing go and even that's the consequence\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:09\"\n                                  },\n                                  \"trackingParams\": \"CK8CENP2BxiZAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 9 seconds this and then understand what the system does so would you rather look at this and try to figure out where this this thing go and even that's the consequence\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1809090.1817250\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1817250\",\n                                  \"endMs\": \"1824350\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of this chase of test first it leads it down a path where the gospel of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:17\"\n                                  },\n                                  \"trackingParams\": \"CK4CENP2BxiaAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 17 seconds of this chase of test first it leads it down a path where the gospel of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1817250.1824350\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1824350\",\n                                  \"endMs\": \"1830150\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"test-driven design is that anything that's easier to test is better that's\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:24\"\n                                  },\n                                  \"trackingParams\": \"CK0CENP2BxibAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 24 seconds test-driven design is that anything that's easier to test is better that's\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1824350.1830150\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1830150\",\n                                  \"endMs\": \"1836120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it that's the measure of quality if you can test it easily it's better if you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:30\"\n                                  },\n                                  \"trackingParams\": \"CKwCENP2BxicAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 30 seconds it that's the measure of quality if you can test it easily it's better if you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1830150.1836120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1836120\",\n                                  \"endMs\": \"1841990\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"can't test it easily it's worse boo exactly right boo\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:36\"\n                                  },\n                                  \"trackingParams\": \"CKsCENP2BxidAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 36 seconds can't test it easily it's worse boo exactly right boo\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1836120.1841990\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1841990\",\n                                  \"endMs\": \"1849440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's not better and we're losing sight of what we're actually trying to do tasks were supposed to support us they\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:41\"\n                                  },\n                                  \"trackingParams\": \"CKoCENP2BxieAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 41 seconds it's not better and we're losing sight of what we're actually trying to do tasks were supposed to support us they\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1841990.1849440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1849440\",\n                                  \"endMs\": \"1856299\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"weren't supposed to be the main thing and this is leading to a lot of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:49\"\n                                  },\n                                  \"trackingParams\": \"CKkCENP2BxifAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 49 seconds weren't supposed to be the main thing and this is leading to a lot of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1849440.1856299\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1856299\",\n                                  \"endMs\": \"1862460\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"zombie astronautics architectures things that I thought we moved past long ago if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"30:56\"\n                                  },\n                                  \"trackingParams\": \"CKgCENP2BxigAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"30 minutes, 56 seconds zombie astronautics architectures things that I thought we moved past long ago if\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1856299.1862460\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1862460\",\n                                  \"endMs\": \"1868700\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you look at at this person crate command that reminds me very much about stretch\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:02\"\n                                  },\n                                  \"trackingParams\": \"CKcCENP2BxihAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 2 seconds you look at at this person crate command that reminds me very much about stretch\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1862460.1868700\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1868700\",\n                                  \"endMs\": \"1874700\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"1.2 and how they had every action as their own object and never so great because there was easy to test and it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:08\"\n                                  },\n                                  \"trackingParams\": \"CKYCENP2BxiiAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 8 seconds 1.2 and how they had every action as their own object and never so great because there was easy to test and it\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1868700.1874700\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1874700\",\n                                  \"endMs\": \"1879980\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"was when you were trying to put a whole architecture together because you had all these create commands and all of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:14\"\n                                  },\n                                  \"trackingParams\": \"CKUCENP2BxijAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 14 seconds was when you were trying to put a whole architecture together because you had all these create commands and all of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1874700.1879980\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1879980\",\n                                  \"endMs\": \"1885370\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a sudden you had a million objects yes they were easier to test but the system was much harder to reason about\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:19\"\n                                  },\n                                  \"trackingParams\": \"CKQCENP2BxikAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 19 seconds a sudden you had a million objects yes they were easier to test but the system was much harder to reason about\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1879980.1885370\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1885370\",\n                                  \"endMs\": \"1891860\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you see the same thing around active record for example you see well active record should just be data access\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:25\"\n                                  },\n                                  \"trackingParams\": \"CKMCENP2BxilAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 25 seconds you see the same thing around active record for example you see well active record should just be data access\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1885370.1891860\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1891860\",\n                                  \"endMs\": \"1897830\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"objects they shouldn't actually have any logic they should just be about interfacing with the database because then we can split out everything else\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:31\"\n                                  },\n                                  \"trackingParams\": \"CKICENP2BximAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 31 seconds objects they shouldn't actually have any logic they should just be about interfacing with the database because then we can split out everything else\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1891860.1897830\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1897830\",\n                                  \"endMs\": \"1903650\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"out domain logic since that it doesn't have to touch the database such that our tests can be simple since that our tests\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:37\"\n                                  },\n                                  \"trackingParams\": \"CKECENP2BxinAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 37 seconds out domain logic since that it doesn't have to touch the database such that our tests can be simple since that our tests\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1897830.1903650\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1903650\",\n                                  \"endMs\": \"1911860\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"can be fast right again order a priority test test fast oh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:43\"\n                                  },\n                                  \"trackingParams\": \"CKACENP2BxioAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 43 seconds can be fast right again order a priority test test fast oh\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1903650.1911860\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1911860\",\n                                  \"endMs\": \"1917919\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"your architecture valid I'll just fall from that right I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:51\"\n                                  },\n                                  \"trackingParams\": \"CJ8CENP2BxipAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 51 seconds your architecture valid I'll just fall from that right I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1911860.1917919\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1917919\",\n                                  \"endMs\": \"1924320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"recently read James Cullen has a great white paper out call why most unit\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"31:57\"\n                                  },\n                                  \"trackingParams\": \"CJ4CENP2BxiqAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"31 minutes, 57 seconds recently read James Cullen has a great white paper out call why most unit\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1917919.1924320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1924320\",\n                                  \"endMs\": \"1930409\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"testing is waste and for me this is the money quote splitting up functions to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:04\"\n                                  },\n                                  \"trackingParams\": \"CJ0CENP2BxirAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 4 seconds testing is waste and for me this is the money quote splitting up functions to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1924320.1930409\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1930409\",\n                                  \"endMs\": \"1937760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"support the testing process destroys your system architecture and code comprehension along with it test at a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:10\"\n                                  },\n                                  \"trackingParams\": \"CJwCENP2BxisAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 10 seconds support the testing process destroys your system architecture and code comprehension along with it test at a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1930409.1937760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1937760\",\n                                  \"endMs\": \"1944500\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"course of level of granularity [Applause]\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:17\"\n                                  },\n                                  \"trackingParams\": \"CJsCENP2BxitAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 17 seconds course of level of granularity [Applause]\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1937760.1944500\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1944500\",\n                                  \"endMs\": \"1950570\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"TDD is focused on the unit the unit is the sacred piece because that's the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:24\"\n                                  },\n                                  \"trackingParams\": \"CJoCENP2BxiuAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 24 seconds TDD is focused on the unit the unit is the sacred piece because that's the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1944500.1950570\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1950570\",\n                                  \"endMs\": \"1956330\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"science piece that's what we can control all of the variables we're just looking at these few pieces right what James is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:30\"\n                                  },\n                                  \"trackingParams\": \"CJkCENP2BxivAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 30 seconds science piece that's what we can control all of the variables we're just looking at these few pieces right what James is\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1950570.1956330\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1956330\",\n                                  \"endMs\": \"1962929\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"saying is maybe that's not the right level maybe testing the role it should have\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:36\"\n                                  },\n                                  \"trackingParams\": \"CJgCENP2BxiwAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 36 seconds saying is maybe that's not the right level maybe testing the role it should have\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1956330.1962929\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1962929\",\n                                  \"endMs\": \"1968960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"shouldn't be about the unit most of the time and I showed alluded to this a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:42\"\n                                  },\n                                  \"trackingParams\": \"CJcCENP2BxixAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 42 seconds shouldn't be about the unit most of the time and I showed alluded to this a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1962929.1968960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1968960\",\n                                  \"endMs\": \"1974659\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"while back I wrote a post called testing like the TSA and the main thing about\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:48\"\n                                  },\n                                  \"trackingParams\": \"CJYCENP2BxiyAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 48 seconds while back I wrote a post called testing like the TSA and the main thing about\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1968960.1974659\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1974659\",\n                                  \"endMs\": \"1981650\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that was about over testing and sort of this testing theater that goes on but I hadn't really made the switch that it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"32:54\"\n                                  },\n                                  \"trackingParams\": \"CJUCENP2BxizAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"32 minutes, 54 seconds that was about over testing and sort of this testing theater that goes on but I hadn't really made the switch that it\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1974659.1981650\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1981650\",\n                                  \"endMs\": \"1987850\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the problem is that we're trying to test it the wrong not testing itself testing is great I'm not advocating that we\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:01\"\n                                  },\n                                  \"trackingParams\": \"CJQCENP2Bxi0AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 1 second the problem is that we're trying to test it the wrong not testing itself testing is great I'm not advocating that we\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1981650.1987850\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1987850\",\n                                  \"endMs\": \"1993610\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"shouldn't have tests I'm advocating that driving your design from unit tests is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:07\"\n                                  },\n                                  \"trackingParams\": \"CJMCENP2Bxi1AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 7 seconds shouldn't have tests I'm advocating that driving your design from unit tests is\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1987850.1993610\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1993610\",\n                                  \"endMs\": \"1999490\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"actually not a good idea that you actually end up destroying your system architecture and your code comprehension\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:13\"\n                                  },\n                                  \"trackingParams\": \"CJICENP2Bxi2AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 13 seconds actually not a good idea that you actually end up destroying your system architecture and your code comprehension\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1993610.1999490\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"1999490\",\n                                  \"endMs\": \"2005850\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"along with it so if unit tests aren't the thing what\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:19\"\n                                  },\n                                  \"trackingParams\": \"CJECENP2Bxi3AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 19 seconds along with it so if unit tests aren't the thing what\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.1999490.2005850\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2005850\",\n                                  \"endMs\": \"2011790\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"can we do instead well I think there are higher levels of testing we've already sort of moved to that in rails it's no\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:25\"\n                                  },\n                                  \"trackingParams\": \"CJACENP2Bxi4AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 25 seconds can we do instead well I think there are higher levels of testing we've already sort of moved to that in rails it's no\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2005850.2011790\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2011790\",\n                                  \"endMs\": \"2018420\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"longer called test unit where you place your your tests it's called test models that's already one step up that sort of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:31\"\n                                  },\n                                  \"trackingParams\": \"CI8CENP2Bxi5AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 31 seconds longer called test unit where you place your your tests it's called test models that's already one step up that sort of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2011790.2018420\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2018420\",\n                                  \"endMs\": \"2023970\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"frees you from feeling bad about the fact that your your model tests actually touch the data base that that's not a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:38\"\n                                  },\n                                  \"trackingParams\": \"CI4CENP2Bxi6AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 38 seconds frees you from feeling bad about the fact that your your model tests actually touch the data base that that's not a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2018420.2023970\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2023970\",\n                                  \"endMs\": \"2029390\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"bad thing yes they run slower but they also test more things you can make anything fast if it doesn't have to work\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:43\"\n                                  },\n                                  \"trackingParams\": \"CI0CENP2Bxi7AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 43 seconds bad thing yes they run slower but they also test more things you can make anything fast if it doesn't have to work\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2023970.2029390\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2029390\",\n                                  \"endMs\": \"2035190\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and I think that's the problem with testing a lot of cases we recently had a really\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:49\"\n                                  },\n                                  \"trackingParams\": \"CIwCENP2Bxi8AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 49 seconds and I think that's the problem with testing a lot of cases we recently had a really\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2029390.2035190\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2035190\",\n                                  \"endMs\": \"2040320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"bad bug on base camp where we actually lost some data for real customers and it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"33:55\"\n                                  },\n                                  \"trackingParams\": \"CIsCENP2Bxi9AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"33 minutes, 55 seconds bad bug on base camp where we actually lost some data for real customers and it\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2035190.2040320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2040320\",\n                                  \"endMs\": \"2046710\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"was incredibly well tested at the unit level and all the tests passed and still\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:00\"\n                                  },\n                                  \"trackingParams\": \"CIoCENP2Bxi-AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes was incredibly well tested at the unit level and all the tests passed and still\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2040320.2046710\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2046710\",\n                                  \"endMs\": \"2052800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we lost data how the did that happened it happened because we were so focused on driving our design from the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:06\"\n                                  },\n                                  \"trackingParams\": \"CIkCENP2Bxi_AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 6 seconds we lost data how the did that happened it happened because we were so focused on driving our design from the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2046710.2052800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2052800\",\n                                  \"endMs\": \"2058440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"unit test level we didn't have any system tests for that particular thing it was a really simple thing it was like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:12\"\n                                  },\n                                  \"trackingParams\": \"CIgCENP2BxjAAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 12 seconds unit test level we didn't have any system tests for that particular thing it was a really simple thing it was like\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2052800.2058440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2058440\",\n                                  \"endMs\": \"2064350\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"if you were editing an object and you were editing the attachments you could loose an attachment and we lost some\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:18\"\n                                  },\n                                  \"trackingParams\": \"CIcCENP2BxjBAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 18 seconds if you were editing an object and you were editing the attachments you could loose an attachment and we lost some\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2058440.2064350\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2064350\",\n                                  \"endMs\": \"2069540\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"attachments and it was a terrible thing and after that sort of thought wait a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:24\"\n                                  },\n                                  \"trackingParams\": \"CIYCENP2BxjCAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 24 seconds attachments and it was a terrible thing and after that sort of thought wait a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2064350.2069540\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2069540\",\n                                  \"endMs\": \"2075929\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"minute all these unit tests are just focusing on these or objects in the system these individual unit pieces it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:29\"\n                                  },\n                                  \"trackingParams\": \"CIUCENP2BxjDAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 29 seconds minute all these unit tests are just focusing on these or objects in the system these individual unit pieces it\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2069540.2075929\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2075929\",\n                                  \"endMs\": \"2083460\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"doesn't say anything about whether the whole system works most TDD proponents I find are much more focused on the unit\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:35\"\n                                  },\n                                  \"trackingParams\": \"CIQCENP2BxjEAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 35 seconds doesn't say anything about whether the whole system works most TDD proponents I find are much more focused on the unit\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2075929.2083460\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2083460\",\n                                  \"endMs\": \"2089610\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"level because that's where they're driving their design and they're not very much focused on the system level ball which is what people actually give\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:43\"\n                                  },\n                                  \"trackingParams\": \"CIMCENP2BxjFAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 43 seconds level because that's where they're driving their design and they're not very much focused on the system level ball which is what people actually give\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2083460.2089610\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2089610\",\n                                  \"endMs\": \"2095879\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"a about does the system work I don't care about whether your units work that's the whole thing work that's what\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:49\"\n                                  },\n                                  \"trackingParams\": \"CIICENP2BxjGAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 49 seconds a about does the system work I don't care about whether your units work that's the whole thing work that's what\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2089610.2095879\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2095880\",\n                                  \"endMs\": \"2101090\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"matters so that kind of freed my mind up a little bit\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"34:55\"\n                                  },\n                                  \"trackingParams\": \"CIECENP2BxjHAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"34 minutes, 55 seconds matters so that kind of freed my mind up a little bit\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2095880.2101090\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2101090\",\n                                  \"endMs\": \"2106410\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that if we give up this need for hard science experience where we have to control all the variables and boil\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:01\"\n                                  },\n                                  \"trackingParams\": \"CIACENP2BxjIAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 1 second that if we give up this need for hard science experience where we have to control all the variables and boil\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2101090.2106410\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2106410\",\n                                  \"endMs\": \"2112520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"everything down to a single unit that can be tested we can float freely with the world awesome\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:06\"\n                                  },\n                                  \"trackingParams\": \"CP8BENP2BxjJAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 6 seconds everything down to a single unit that can be tested we can float freely with the world awesome\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2106410.2112520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2112520\",\n                                  \"endMs\": \"2118310\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this realization I came to realize was why people hate\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:12\"\n                                  },\n                                  \"trackingParams\": \"CP4BENP2BxjKAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 12 seconds this realization I came to realize was why people hate\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2112520.2118310\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2118310\",\n                                  \"endMs\": \"2125120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"fixtures so fixtures in in rails is about spinning up a world it's about\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:18\"\n                                  },\n                                  \"trackingParams\": \"CP0BENP2BxjLAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 18 seconds fixtures so fixtures in in rails is about spinning up a world it's about\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2118310.2125120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2125120\",\n                                  \"endMs\": \"2132130\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"setting up sort of small sized version of the whole world\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:25\"\n                                  },\n                                  \"trackingParams\": \"CPwBENP2BxjMAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 25 seconds setting up sort of small sized version of the whole world\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2125120.2132130\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2132130\",\n                                  \"endMs\": \"2137840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"where most test approaches they focus on just on the unit I don't want to have an\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:32\"\n                                  },\n                                  \"trackingParams\": \"CPsBENP2BxjNAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 32 seconds where most test approaches they focus on just on the unit I don't want to have an\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2132130.2137840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2137840\",\n                                  \"endMs\": \"2143570\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"account in here and a project in here if I'm just testing my message I just want to test on this one single day right and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:37\"\n                                  },\n                                  \"trackingParams\": \"CPoBENP2BxjOAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 37 seconds account in here and a project in here if I'm just testing my message I just want to test on this one single day right and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2137840.2143570\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2143570\",\n                                  \"endMs\": \"2150770\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"if you're doing that yeah pictures probably not a good thing it doesn't really work for that it works really well when you're not concerned about the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:43\"\n                                  },\n                                  \"trackingParams\": \"CPkBENP2BxjPAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 43 seconds if you're doing that yeah pictures probably not a good thing it doesn't really work for that it works really well when you're not concerned about the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2143570.2150770\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2150770\",\n                                  \"endMs\": \"2157400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"hard science focus on a new test it works really well when you focus on a larger level when\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:50\"\n                                  },\n                                  \"trackingParams\": \"CPgBENP2BxjQAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 50 seconds hard science focus on a new test it works really well when you focus on a larger level when\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2150770.2157400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2157400\",\n                                  \"endMs\": \"2163270\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you focus on models when you focus on controllers and most importantly when you're focused on systems\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"35:57\"\n                                  },\n                                  \"trackingParams\": \"CPcBENP2BxjRAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"35 minutes, 57 seconds you focus on models when you focus on controllers and most importantly when you're focused on systems\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2157400.2163270\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2163270\",\n                                  \"endMs\": \"2170600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"but all that is sort of usually swept away by the Holy Trinity\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:03\"\n                                  },\n                                  \"trackingParams\": \"CPYBENP2BxjSAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 3 seconds but all that is sort of usually swept away by the Holy Trinity\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2163270.2170600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2170600\",\n                                  \"endMs\": \"2176320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of test metrics coverage ratio and speed\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:10\"\n                                  },\n                                  \"trackingParams\": \"CPUBENP2BxjTAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 10 seconds of test metrics coverage ratio and speed\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2170600.2176320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2176320\",\n                                  \"endMs\": \"2182830\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I've been in a lot of internet arguments lately\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:16\"\n                                  },\n                                  \"trackingParams\": \"CPQBENP2BxjUAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 16 seconds I've been in a lot of internet arguments lately\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2176320.2182830\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2182830\",\n                                  \"endMs\": \"2189980\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in such esteemed establishments as hacker news and an elsewhere and I find\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:22\"\n                                  },\n                                  \"trackingParams\": \"CPMBENP2BxjVAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 22 seconds in such esteemed establishments as hacker news and an elsewhere and I find\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2182830.2189980\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2189980\",\n                                  \"endMs\": \"2196640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it really interesting because each individual argument will make me rage but then the larger set of all arguments\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:29\"\n                                  },\n                                  \"trackingParams\": \"CPIBENP2BxjWAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 29 seconds it really interesting because each individual argument will make me rage but then the larger set of all arguments\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2189980.2196640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2196640\",\n                                  \"endMs\": \"2202160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like a meta-study actually reveals really interesting things about what people care about what they value and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:36\"\n                                  },\n                                  \"trackingParams\": \"CPEBENP2BxjXAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 36 seconds like a meta-study actually reveals really interesting things about what people care about what they value and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2196640.2202160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2202160\",\n                                  \"endMs\": \"2209000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what I find is in most discussions about design especially around rails what people care about these things and these\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:42\"\n                                  },\n                                  \"trackingParams\": \"CPABENP2BxjYAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 42 seconds what I find is in most discussions about design especially around rails what people care about these things and these\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2202160.2209000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2209000\",\n                                  \"endMs\": \"2216290\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"things only it's about the test coverage it's about the test ratio and it's about how fast your tests run like that's the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:49\"\n                                  },\n                                  \"trackingParams\": \"CO8BENP2BxjZAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 49 seconds things only it's about the test coverage it's about the test ratio and it's about how fast your tests run like that's the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2209000.2216290\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2216290\",\n                                  \"endMs\": \"2222920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"pedestal that's the Holy Grail what actually happens underneath how the design of the rest of the application is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"36:56\"\n                                  },\n                                  \"trackingParams\": \"CO4BENP2BxjaAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"36 minutes, 56 seconds pedestal that's the Holy Grail what actually happens underneath how the design of the rest of the application is\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2216290.2222920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2222920\",\n                                  \"endMs\": \"2229130\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah doesn't really matter and thus a lot of people come to celebrate\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:02\"\n                                  },\n                                  \"trackingParams\": \"CO0BENP2BxjbAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 2 seconds yeah doesn't really matter and thus a lot of people come to celebrate\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2222920.2229130\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2229130\",\n                                  \"endMs\": \"2234710\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"oh I have a 1 to 4 test ratio for every line of production code I have 4 lines\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:09\"\n                                  },\n                                  \"trackingParams\": \"COwBENP2BxjcAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 9 seconds oh I have a 1 to 4 test ratio for every line of production code I have 4 lines\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2229130.2234710\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2234710\",\n                                  \"endMs\": \"2240160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of test oh yeah and they say that with pride and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:14\"\n                                  },\n                                  \"trackingParams\": \"COsBENP2BxjdAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 14 seconds of test oh yeah and they say that with pride and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2234710.2240160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2240160\",\n                                  \"endMs\": \"2245840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I'm like what so you're saying for every line of production code you write you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:20\"\n                                  },\n                                  \"trackingParams\": \"COoBENP2BxjeAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 20 seconds I'm like what so you're saying for every line of production code you write you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2240160.2245840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2245840\",\n                                  \"endMs\": \"2252440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"have to write four lines of code and that somehow makes your hero how does that work so your system is now\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:25\"\n                                  },\n                                  \"trackingParams\": \"COkBENP2BxjfAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 25 seconds have to write four lines of code and that somehow makes your hero how does that work so your system is now\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2245840.2252440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2252440\",\n                                  \"endMs\": \"2257959\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"five times as large reasoning about the whole system is now five times as complex and you're proud of this why\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:32\"\n                                  },\n                                  \"trackingParams\": \"COgBENP2BxjgAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 32 seconds five times as large reasoning about the whole system is now five times as complex and you're proud of this why\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2252440.2257959\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2257959\",\n                                  \"endMs\": \"2263180\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"well of course cuz I got all one percent coverage my five thousand test run\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:37\"\n                                  },\n                                  \"trackingParams\": \"COcBENP2BxjhAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 37 seconds well of course cuz I got all one percent coverage my five thousand test run\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2257959.2263180\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2263180\",\n                                  \"endMs\": \"2269539\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"incredibly fast because they never actually test very much they certainly do not test the system they test all\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:43\"\n                                  },\n                                  \"trackingParams\": \"COYBENP2BxjiAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 43 seconds incredibly fast because they never actually test very much they certainly do not test the system they test all\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2263180.2269539\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2269539\",\n                                  \"endMs\": \"2274999\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"these little slices of unit wonderful not wonderful you have anemic\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:49\"\n                                  },\n                                  \"trackingParams\": \"COUBENP2BxjjAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 49 seconds these little slices of unit wonderful not wonderful you have anemic\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2269539.2274999\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2274999\",\n                                  \"endMs\": \"2280339\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \" tests they don't prove you're gonna have the same bug that we have on Basecamp and the system is not\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"37:54\"\n                                  },\n                                  \"trackingParams\": \"COQBENP2BxjkAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"37 minutes, 54 seconds  tests they don't prove you're gonna have the same bug that we have on Basecamp and the system is not\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2274999.2280339\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2280339\",\n                                  \"endMs\": \"2286660\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"going to work even though you proudly proclaim though all your units are working well what did he do\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:00\"\n                                  },\n                                  \"trackingParams\": \"COMBENP2BxjlAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes going to work even though you proudly proclaim though all your units are working well what did he do\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2280339.2286660\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2286660\",\n                                  \"endMs\": \"2292640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this decoupling is not free people think that oh this is like that saying like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:06\"\n                                  },\n                                  \"trackingParams\": \"COIBENP2BxjmAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 6 seconds this decoupling is not free people think that oh this is like that saying like\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2286660.2292640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2292640\",\n                                  \"endMs\": \"2300130\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"quality is free right testing is free not when you're doing it like this it's not free and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:12\"\n                                  },\n                                  \"trackingParams\": \"COEBENP2BxjnAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 12 seconds quality is free right testing is free not when you're doing it like this it's not free and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2292640.2300130\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2300130\",\n                                  \"endMs\": \"2305499\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"most important it's not free not so much in time but in conceptual overhead\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:20\"\n                                  },\n                                  \"trackingParams\": \"COABENP2BxjoAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 20 seconds most important it's not free not so much in time but in conceptual overhead\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2300130.2305499\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2305499\",\n                                  \"endMs\": \"2311329\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"understanding a system that has been test-driven designed from the unit\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:25\"\n                                  },\n                                  \"trackingParams\": \"CN8BENP2BxjpAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 25 seconds understanding a system that has been test-driven designed from the unit\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2305499.2311329\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2311329\",\n                                  \"endMs\": \"2317660\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"perspective is really hard because you have all these levels of indirection you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:31\"\n                                  },\n                                  \"trackingParams\": \"CN4BENP2BxjqAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 31 seconds perspective is really hard because you have all these levels of indirection you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2311329.2317660\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2317660\",\n                                  \"endMs\": \"2323150\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"have all these level of intermediation to separate the tests from slow things\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:37\"\n                                  },\n                                  \"trackingParams\": \"CN0BENP2BxjrAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 37 seconds have all these level of intermediation to separate the tests from slow things\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2317660.2323150\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2323150\",\n                                  \"endMs\": \"2328670\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like HTML or the database or and if you other parts of the system that actually\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:43\"\n                                  },\n                                  \"trackingParams\": \"CNwBENP2BxjsAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 43 seconds like HTML or the database or and if you other parts of the system that actually\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2323150.2328670\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2328670\",\n                                  \"endMs\": \"2335749\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"makes up your system and they focus just on that one thing so they can be very fast if they don't\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:48\"\n                                  },\n                                  \"trackingParams\": \"CNsBENP2BxjtAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 48 seconds makes up your system and they focus just on that one thing so they can be very fast if they don't\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2328670.2335749\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2335749\",\n                                  \"endMs\": \"2341900\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"have to work they don't actually to test your system so that's sort of two charges at once it's the charge first\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"38:55\"\n                                  },\n                                  \"trackingParams\": \"CNoBENP2BxjuAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"38 minutes, 55 seconds have to work they don't actually to test your system so that's sort of two charges at once it's the charge first\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2335749.2341900\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2341900\",\n                                  \"endMs\": \"2347299\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that your design is not going to improve your design is going to deteriorate by\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:01\"\n                                  },\n                                  \"trackingParams\": \"CNkBENP2BxjvAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 1 second that your design is not going to improve your design is going to deteriorate by\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2341900.2347299\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2347299\",\n                                  \"endMs\": \"2352839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"gluing tests first programming because you're going to construct your units of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:07\"\n                                  },\n                                  \"trackingParams\": \"CNgBENP2BxjwAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 7 seconds gluing tests first programming because you're going to construct your units of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2347299.2352839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2352839\",\n                                  \"endMs\": \"2358430\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"testing your methods in a different way like we saw with the H example you're going to checked all your dependencies\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:12\"\n                                  },\n                                  \"trackingParams\": \"CNcBENP2BxjxAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 12 seconds testing your methods in a different way like we saw with the H example you're going to checked all your dependencies\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2352839.2358430\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2358430\",\n                                  \"endMs\": \"2365779\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in a way that does not approve things ah and second of all you're not going to get the benefit of great coverage you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:18\"\n                                  },\n                                  \"trackingParams\": \"CNYBENP2BxjyAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 18 seconds in a way that does not approve things ah and second of all you're not going to get the benefit of great coverage you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2358430.2365779\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2365779\",\n                                  \"endMs\": \"2372440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"might have a lot of tests but they don't test your system it doesn't include increase your confidence and actually\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:25\"\n                                  },\n                                  \"trackingParams\": \"CNUBENP2BxjzAiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 25 seconds might have a lot of tests but they don't test your system it doesn't include increase your confidence and actually\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2365779.2372440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2372440\",\n                                  \"endMs\": \"2378009\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the whole thing working and then what good is it well\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:32\"\n                                  },\n                                  \"trackingParams\": \"CNQBENP2Bxj0AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 32 seconds the whole thing working and then what good is it well\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2372440.2378009\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2379060\",\n                                  \"endMs\": \"2385390\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I thought about this for a long time in tiling this is not really this doesn't seem\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:39\"\n                                  },\n                                  \"trackingParams\": \"CNMBENP2Bxj1AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 39 seconds I thought about this for a long time in tiling this is not really this doesn't seem\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2379060.2385390\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2385390\",\n                                  \"endMs\": \"2391630\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like that great of a revelation why why do I keep having these arguments over and over again why are people focus so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:45\"\n                                  },\n                                  \"trackingParams\": \"CNIBENP2Bxj2AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 45 seconds like that great of a revelation why why do I keep having these arguments over and over again why are people focus so\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2385390.2391630\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2391630\",\n                                  \"endMs\": \"2398680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"hard and so intensely on this Trinity of test metrics how did that come to be the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:51\"\n                                  },\n                                  \"trackingParams\": \"CNEBENP2Bxj3AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 51 seconds hard and so intensely on this Trinity of test metrics how did that come to be the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2391630.2398680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2398680\",\n                                  \"endMs\": \"2404950\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"main thing that people arguing about how did that come to be the main decider of what's good design and what's bad design\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"39:58\"\n                                  },\n                                  \"trackingParams\": \"CNABENP2Bxj4AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"39 minutes, 58 seconds main thing that people arguing about how did that come to be the main decider of what's good design and what's bad design\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2398680.2404950\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2404950\",\n                                  \"endMs\": \"2410200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"really couldn't really figure it out until I started thinking back of like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:04\"\n                                  },\n                                  \"trackingParams\": \"CM8BENP2Bxj5AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 4 seconds really couldn't really figure it out until I started thinking back of like\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2404950.2410200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2410200\",\n                                  \"endMs\": \"2416520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what is this person we're looking through we're looking through it computer science engineering\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:10\"\n                                  },\n                                  \"trackingParams\": \"CM4BENP2Bxj6AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 10 seconds what is this person we're looking through we're looking through it computer science engineering\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2410200.2416520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2416520\",\n                                  \"endMs\": \"2422170\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"professionalism James Harrington wrote a bunch of books on quality of engineering\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:16\"\n                                  },\n                                  \"trackingParams\": \"CM0BENP2Bxj7AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 16 seconds professionalism James Harrington wrote a bunch of books on quality of engineering\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2416520.2422170\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2422170\",\n                                  \"endMs\": \"2427930\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and he has a great quote here if you can't measure something you can't understand it if you can't understand it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:22\"\n                                  },\n                                  \"trackingParams\": \"CMwBENP2Bxj8AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 22 seconds and he has a great quote here if you can't measure something you can't understand it if you can't understand it\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2422170.2427930\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2427930\",\n                                  \"endMs\": \"2434200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you can't control it if you can't control it you can't improve it that makes a lot sense I was like oh yeah\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:27\"\n                                  },\n                                  \"trackingParams\": \"CMsBENP2Bxj9AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 27 seconds you can't control it if you can't control it you can't improve it that makes a lot sense I was like oh yeah\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2427930.2434200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2434200\",\n                                  \"endMs\": \"2440440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah that makes sense so that's gonna be why then I got another good great quote just because\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:34\"\n                                  },\n                                  \"trackingParams\": \"CMoBENP2Bxj-AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 34 seconds yeah that makes sense so that's gonna be why then I got another good great quote just because\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2434200.2440440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2440440\",\n                                  \"endMs\": \"2445930\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you can just because something is easy to measure doesn't mean it's important that's I think is exactly what's going\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:40\"\n                                  },\n                                  \"trackingParams\": \"CMkBENP2Bxj_AiITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 40 seconds you can just because something is easy to measure doesn't mean it's important that's I think is exactly what's going\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2440440.2445930\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2445930\",\n                                  \"endMs\": \"2452200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"on here programming of information systems is a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:45\"\n                                  },\n                                  \"trackingParams\": \"CMgBENP2BxiAAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 45 seconds on here programming of information systems is a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2445930.2452200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2452200\",\n                                  \"endMs\": \"2458530\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"lot more like French poetry than it is like physics but programmers grow up thinking that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:52\"\n                                  },\n                                  \"trackingParams\": \"CMcBENP2BxiBAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 52 seconds lot more like French poetry than it is like physics but programmers grow up thinking that\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2452200.2458530\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2458530\",\n                                  \"endMs\": \"2464860\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"they're computer scientists so they wanted really badly to be like physics they wanted really badly to be a hard\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"40:58\"\n                                  },\n                                  \"trackingParams\": \"CMYBENP2BxiCAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"40 minutes, 58 seconds they're computer scientists so they wanted really badly to be like physics they wanted really badly to be a hard\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2458530.2464860\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2464860\",\n                                  \"endMs\": \"2473290\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"professional science and coverage ratio and speed you can get\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:04\"\n                                  },\n                                  \"trackingParams\": \"CMUBENP2BxiDAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 4 seconds professional science and coverage ratio and speed you can get\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2464860.2473290\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2473290\",\n                                  \"endMs\": \"2479410\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that thing down to six decimals like that I can be so precise about how\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:13\"\n                                  },\n                                  \"trackingParams\": \"CMQBENP2BxiEAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 13 seconds that thing down to six decimals like that I can be so precise about how\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2473290.2479410\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2479410\",\n                                  \"endMs\": \"2485220\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"fast my test run time with eighty four point seven percent coverage boom got it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:19\"\n                                  },\n                                  \"trackingParams\": \"CMMBENP2BxiFAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 19 seconds fast my test run time with eighty four point seven percent coverage boom got it\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2479410.2485220\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2485220\",\n                                  \"endMs\": \"2490930\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"doesn't say anything about whether that's actually important doesn't say anything about whether that's actually\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:25\"\n                                  },\n                                  \"trackingParams\": \"CMIBENP2BxiGAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 25 seconds doesn't say anything about whether that's actually important doesn't say anything about whether that's actually\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2485220.2490930\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2490930\",\n                                  \"endMs\": \"2496090\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"producing a good system doesn't say anything about whether the person after you or you yourself three months from\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:30\"\n                                  },\n                                  \"trackingParams\": \"CMEBENP2BxiHAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 30 seconds producing a good system doesn't say anything about whether the person after you or you yourself three months from\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2490930.2496090\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2496090\",\n                                  \"endMs\": \"2502630\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"now can understand what the hell is going on in this code base you haven't necessarily made anything any\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:36\"\n                                  },\n                                  \"trackingParams\": \"CMABENP2BxiIAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 36 seconds now can understand what the hell is going on in this code base you haven't necessarily made anything any\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2496090.2502630\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2502630\",\n                                  \"endMs\": \"2508210\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"clearer you've made it very easy to produce metrics and if there's one thing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:42\"\n                                  },\n                                  \"trackingParams\": \"CL8BENP2BxiJAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 42 seconds clearer you've made it very easy to produce metrics and if there's one thing\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2502630.2508210\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2508210\",\n                                  \"endMs\": \"2517299\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we love with with science it's clear concise jected truth and coverage and ratio and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:48\"\n                                  },\n                                  \"trackingParams\": \"CL4BENP2BxiKAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 48 seconds we love with with science it's clear concise jected truth and coverage and ratio and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2508210.2517299\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2517299\",\n                                  \"endMs\": \"2522549\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"speed fit that bill so we adopted them with open arms even though they were not\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"41:57\"\n                                  },\n                                  \"trackingParams\": \"CL0BENP2BxiLAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"41 minutes, 57 seconds speed fit that bill so we adopted them with open arms even though they were not\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2517299.2522549\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2522549\",\n                                  \"endMs\": \"2529569\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that important second part of it cost is not value a lot of people have invested\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:02\"\n                                  },\n                                  \"trackingParams\": \"CLwBENP2BxiMAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 2 seconds that important second part of it cost is not value a lot of people have invested\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2522549.2529569\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2529569\",\n                                  \"endMs\": \"2537190\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so much in building up their expertise third time they're four to one ratio and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:09\"\n                                  },\n                                  \"trackingParams\": \"CLsBENP2BxiNAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 9 seconds so much in building up their expertise third time they're four to one ratio and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2529569.2537190\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2537190\",\n                                  \"endMs\": \"2542529\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"test the investment is massive well of course they're going to be defensive\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:17\"\n                                  },\n                                  \"trackingParams\": \"CLoBENP2BxiOAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 17 seconds test the investment is massive well of course they're going to be defensive\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2537190.2542529\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2542529\",\n                                  \"endMs\": \"2548349\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"about it like you've invested so much of your ego and your time and your\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:22\"\n                                  },\n                                  \"trackingParams\": \"CLkBENP2BxiPAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 22 seconds about it like you've invested so much of your ego and your time and your\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2542529.2548349\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2548349\",\n                                  \"endMs\": \"2554920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"resources on this project into testing so of course it must be valuable of course it must be important that's not\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:28\"\n                                  },\n                                  \"trackingParams\": \"CLgBENP2BxiQAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 28 seconds resources on this project into testing so of course it must be valuable of course it must be important that's not\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2548349.2554920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2554920\",\n                                  \"endMs\": \"2560109\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"how it works just because something is really expensive just because something takes a lot of your time doesn't mean\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:34\"\n                                  },\n                                  \"trackingParams\": \"CLcBENP2BxiRAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 34 seconds how it works just because something is really expensive just because something takes a lot of your time doesn't mean\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2554920.2560109\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2560109\",\n                                  \"endMs\": \"2564630\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's valuable doesn't mean it's important\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:40\"\n                                  },\n                                  \"trackingParams\": \"CLYBENP2BxiSAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 40 seconds it's valuable doesn't mean it's important\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2560109.2564630\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2566640\",\n                                  \"endMs\": \"2573160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so I'm sort of giving a brief description of this talk yesterday\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:46\"\n                                  },\n                                  \"trackingParams\": \"CLUBENP2BxiTAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 46 seconds so I'm sort of giving a brief description of this talk yesterday\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2566640.2573160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2573160\",\n                                  \"endMs\": \"2580990\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"at dinner with Aaron Patterson and he told me write back and say oh TL DR\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"42:53\"\n                                  },\n                                  \"trackingParams\": \"CLQBENP2BxiUAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"42 minutes, 53 seconds at dinner with Aaron Patterson and he told me write back and say oh TL DR\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2573160.2580990\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2580990\",\n                                  \"endMs\": \"2588480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"just don't test right like that's what I'm supposed to get out of this no no\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:00\"\n                                  },\n                                  \"trackingParams\": \"CLMBENP2BxiVAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes just don't test right like that's what I'm supposed to get out of this no no\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2580990.2588480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2588480\",\n                                  \"endMs\": \"2593640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"testing absolutely has value regression testing absolutely has value\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:08\"\n                                  },\n                                  \"trackingParams\": \"CLIBENP2BxiWAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 8 seconds testing absolutely has value regression testing absolutely has value\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2588480.2593640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2593640\",\n                                  \"endMs\": \"2600779\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"driving your design through tests first in my mind rarely has value\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:13\"\n                                  },\n                                  \"trackingParams\": \"CLEBENP2BxiXAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 13 seconds driving your design through tests first in my mind rarely has value\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2593640.2600779\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2600779\",\n                                  \"endMs\": \"2608740\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"not never there are times where I'll write my test first usually when it's something like a a translator of some\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:20\"\n                                  },\n                                  \"trackingParams\": \"CLABENP2BxiYAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 20 seconds not never there are times where I'll write my test first usually when it's something like a a translator of some\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2600779.2608740\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2608740\",\n                                  \"endMs\": \"2616000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"kind where I know exactly what's going in and I know exactly what I want out that could be a good case to start the test first most information system\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:28\"\n                                  },\n                                  \"trackingParams\": \"CK8BENP2BxiZAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 28 seconds kind where I know exactly what's going in and I know exactly what I want out that could be a good case to start the test first most information system\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2608740.2616000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2616000\",\n                                  \"endMs\": \"2623200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"design is not like that I'm trying to figure out still what the system is supposed to do what I want to arrive at is the test\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:36\"\n                                  },\n                                  \"trackingParams\": \"CK4BENP2BxiaAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 36 seconds design is not like that I'm trying to figure out still what the system is supposed to do what I want to arrive at is the test\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2616000.2623200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2623200\",\n                                  \"endMs\": \"2628299\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's the set of tests it's a set of regression tests that make me feel good about that after the fact that I can\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:43\"\n                                  },\n                                  \"trackingParams\": \"CK0BENP2BxibAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 43 seconds it's the set of tests it's a set of regression tests that make me feel good about that after the fact that I can\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2623200.2628299\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2628299\",\n                                  \"endMs\": \"2633180\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"still change my system and not break it right\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:48\"\n                                  },\n                                  \"trackingParams\": \"CKwBENP2BxicAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 48 seconds still change my system and not break it right\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2628299.2633180\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2635279\",\n                                  \"endMs\": \"2640110\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so tdd\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"43:55\"\n                                  },\n                                  \"trackingParams\": \"CKsBENP2BxidAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"43 minutes, 55 seconds so tdd\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2635279.2640110\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2641220\",\n                                  \"endMs\": \"2647860\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"kent beck main proponent behind TDD has a very sensible quote that goes exactly\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:01\"\n                                  },\n                                  \"trackingParams\": \"CKoBENP2BxieAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 1 second kent beck main proponent behind TDD has a very sensible quote that goes exactly\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2641220.2647860\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2647860\",\n                                  \"endMs\": \"2653740\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"along these lines I get paid for code that works not for tests so my\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:07\"\n                                  },\n                                  \"trackingParams\": \"CKkBENP2BxifAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 7 seconds along these lines I get paid for code that works not for tests so my\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2647860.2653740\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2653740\",\n                                  \"endMs\": \"2659940\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"philosophy is to test as little as possible to reach a given level of confidence\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:13\"\n                                  },\n                                  \"trackingParams\": \"CKgBENP2BxigAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 13 seconds philosophy is to test as little as possible to reach a given level of confidence\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2653740.2659940\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2659940\",\n                                  \"endMs\": \"2665560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"immensely sensible and I find that that's actually often the case with\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:19\"\n                                  },\n                                  \"trackingParams\": \"CKcBENP2BxihAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 19 seconds immensely sensible and I find that that's actually often the case with\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2659940.2665560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2665560\",\n                                  \"endMs\": \"2674100\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"these things that get taken too far TDD started out as a pretty sensible thing Kent has an even more sensible\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:25\"\n                                  },\n                                  \"trackingParams\": \"CKYBENP2BxiiAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 25 seconds these things that get taken too far TDD started out as a pretty sensible thing Kent has an even more sensible\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2665560.2674100\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2674100\",\n                                  \"endMs\": \"2680220\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"perception of it now I think than when he wrote the test room book originally\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:34\"\n                                  },\n                                  \"trackingParams\": \"CKUBENP2BxijAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 34 seconds perception of it now I think than when he wrote the test room book originally\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2674100.2680220\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2680220\",\n                                  \"endMs\": \"2685930\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"but that's not what most people take away that's not what most people run with if they wanted to build a career\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:40\"\n                                  },\n                                  \"trackingParams\": \"CKQBENP2BxikAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 40 seconds but that's not what most people take away that's not what most people run with if they wanted to build a career\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2680220.2685930\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2685930\",\n                                  \"endMs\": \"2692320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and making people feel shitty about their code bases and their dirty dirty code they take a much more extremist\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:45\"\n                                  },\n                                  \"trackingParams\": \"CKMBENP2BxilAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 45 seconds and making people feel shitty about their code bases and their dirty dirty code they take a much more extremist\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2685930.2692320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2692320\",\n                                  \"endMs\": \"2698220\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"approach that unless you're doing tests first you are not a professional\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:52\"\n                                  },\n                                  \"trackingParams\": \"CKIBENP2BximAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 52 seconds approach that unless you're doing tests first you are not a professional\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2692320.2698220\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2698220\",\n                                  \"endMs\": \"2704109\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"certain not what can I say okay so for\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"44:58\"\n                                  },\n                                  \"trackingParams\": \"CKEBENP2BxinAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"44 minutes, 58 seconds certain not what can I say okay so for\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2698220.2704109\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2704109\",\n                                  \"endMs\": \"2711390\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"me this really boils down to we're right we're trying to wear the wrong hat the majority of the time\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:04\"\n                                  },\n                                  \"trackingParams\": \"CKABENP2BxioAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 4 seconds me this really boils down to we're right we're trying to wear the wrong hat the majority of the time\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2704109.2711390\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2711390\",\n                                  \"endMs\": \"2718600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"thinking of yourself as a software engineer will lead you down the path of coverage\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:11\"\n                                  },\n                                  \"trackingParams\": \"CJ8BENP2BxipAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 11 seconds thinking of yourself as a software engineer will lead you down the path of coverage\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2711390.2718600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2718600\",\n                                  \"endMs\": \"2724450\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"speed metrics hard sciences all these things we can\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:18\"\n                                  },\n                                  \"trackingParams\": \"CJ4BENP2BxiqAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 18 seconds speed metrics hard sciences all these things we can\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2718600.2724450\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2724450\",\n                                  \"endMs\": \"2729930\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"measure and it leave you laughing at like\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:24\"\n                                  },\n                                  \"trackingParams\": \"CJ0BENP2BxirAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 24 seconds measure and it leave you laughing at like\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2724450.2729930\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2729930\",\n                                  \"endMs\": \"2735490\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"interpretation of French poetry of subjective evaluations of a design in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:29\"\n                                  },\n                                  \"trackingParams\": \"CJwBENP2BxisAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 29 seconds interpretation of French poetry of subjective evaluations of a design in\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2729930.2735490\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2735490\",\n                                  \"endMs\": \"2740640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the system even though those are the only tools that we have so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:35\"\n                                  },\n                                  \"trackingParams\": \"CJsBENP2BxitAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 35 seconds the system even though those are the only tools that we have so\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2735490.2740640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2740640\",\n                                  \"endMs\": \"2746109\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this has taken me a while to arrive at this conclusion I've hated the word software engineer for quite a while\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:40\"\n                                  },\n                                  \"trackingParams\": \"CJoBENP2BxiuAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 40 seconds this has taken me a while to arrive at this conclusion I've hated the word software engineer for quite a while\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2740640.2746109\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2746109\",\n                                  \"endMs\": \"2753640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"because I never felt it fit me I never thought of myself as a software engineer I kind of tried to be one a few times\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:46\"\n                                  },\n                                  \"trackingParams\": \"CJkBENP2BxivAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 46 seconds because I never felt it fit me I never thought of myself as a software engineer I kind of tried to be one a few times\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2746109.2753640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2753640\",\n                                  \"endMs\": \"2759790\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"and I failed all the time and by the time I finally arrived at programming as something that I wanted to do is sure\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:53\"\n                                  },\n                                  \"trackingParams\": \"CJgBENP2BxiwAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 53 seconds and I failed all the time and by the time I finally arrived at programming as something that I wanted to do is sure\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2753640.2759790\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2759790\",\n                                  \"endMs\": \"2764800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \" wasn't software engineering yes it's a hard hat that I wear\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"45:59\"\n                                  },\n                                  \"trackingParams\": \"CJcBENP2BxixAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"45 minutes, 59 seconds  wasn't software engineering yes it's a hard hat that I wear\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2759790.2764800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2764800\",\n                                  \"endMs\": \"2770530\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"occasionally when I do performance optimization that's hard science you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:04\"\n                                  },\n                                  \"trackingParams\": \"CJYBENP2BxiyAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 4 seconds occasionally when I do performance optimization that's hard science you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2764800.2770530\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2770530\",\n                                  \"endMs\": \"2776609\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"make a change you measure it was it an improvement if not revert if yes deploy\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:10\"\n                                  },\n                                  \"trackingParams\": \"CJUBENP2BxizAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 10 seconds make a change you measure it was it an improvement if not revert if yes deploy\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2770530.2776609\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2776609\",\n                                  \"endMs\": \"2784540\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"very scientific very good great to wear the hardhat when that fits is what that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:16\"\n                                  },\n                                  \"trackingParams\": \"CJQBENP2Bxi0AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 16 seconds very scientific very good great to wear the hardhat when that fits is what that\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2776609.2784540\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2784540\",\n                                  \"endMs\": \"2789940\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what I do the majority of the time is that how I think of myself when I write most of the things that I write when I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:24\"\n                                  },\n                                  \"trackingParams\": \"CJMBENP2Bxi1AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 24 seconds what I do the majority of the time is that how I think of myself when I write most of the things that I write when I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2784540.2789940\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2789940\",\n                                  \"endMs\": \"2796869\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"add a new feature to Basecamp or do forensics to figure out how a bug came about or what somebody meant when they\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:29\"\n                                  },\n                                  \"trackingParams\": \"CJIBENP2Bxi2AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 29 seconds add a new feature to Basecamp or do forensics to figure out how a bug came about or what somebody meant when they\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2789940.2796869\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2796869\",\n                                  \"endMs\": \"2803700\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"wrote a plug-in or something no that's not what I do so I don't try to think myself as a software engineer\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:36\"\n                                  },\n                                  \"trackingParams\": \"CJEBENP2Bxi3AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 36 seconds wrote a plug-in or something no that's not what I do so I don't try to think myself as a software engineer\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2796869.2803700\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2803700\",\n                                  \"endMs\": \"2809619\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"okay if we route software engineers most of the time when we make information\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:43\"\n                                  },\n                                  \"trackingParams\": \"CJABENP2Bxi4AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 43 seconds okay if we route software engineers most of the time when we make information\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2803700.2809619\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2809619\",\n                                  \"endMs\": \"2814810\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"systems what are we then what other hat should we try to wear\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:49\"\n                                  },\n                                  \"trackingParams\": \"CI8BENP2Bxi5AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 49 seconds systems what are we then what other hat should we try to wear\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2809619.2814810\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2814810\",\n                                  \"endMs\": \"2820630\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what other identity should we try to aspire to I think we had it all along I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"46:54\"\n                                  },\n                                  \"trackingParams\": \"CI4BENP2Bxi6AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"46 minutes, 54 seconds what other identity should we try to aspire to I think we had it all along I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2814810.2820630\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2820630\",\n                                  \"endMs\": \"2826200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"think we had it in language all along we're suffer writers\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:00\"\n                                  },\n                                  \"trackingParams\": \"CI0BENP2Bxi7AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes think we had it in language all along we're suffer writers\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2820630.2826200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2826200\",\n                                  \"endMs\": \"2832090\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"writing is a much more apt metaphor for what we do most of the time than\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:06\"\n                                  },\n                                  \"trackingParams\": \"CIwBENP2Bxi8AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 6 seconds writing is a much more apt metaphor for what we do most of the time than\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2826200.2832090\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2832090\",\n                                  \"endMs\": \"2838530\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"engineering is writing is about clarity\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:12\"\n                                  },\n                                  \"trackingParams\": \"CIsBENP2Bxi9AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 12 seconds engineering is writing is about clarity\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2832090.2838530\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2838530\",\n                                  \"endMs\": \"2844690\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it's about presenting information and motivations\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:18\"\n                                  },\n                                  \"trackingParams\": \"CIoBENP2Bxi-AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 18 seconds it's about presenting information and motivations\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2838530.2844690\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2844690\",\n                                  \"endMs\": \"2851890\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"in a clear to follow manner such that anybody can understand it there are not bonus points for making\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:24\"\n                                  },\n                                  \"trackingParams\": \"CIkBENP2Bxi_AyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 24 seconds in a clear to follow manner such that anybody can understand it there are not bonus points for making\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2844690.2851890\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2851890\",\n                                  \"endMs\": \"2857140\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"something convoluted Esther often is with engineering and with tests first\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:31\"\n                                  },\n                                  \"trackingParams\": \"CIgBENP2BxjAAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 31 seconds something convoluted Esther often is with engineering and with tests first\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2851890.2857140\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2857140\",\n                                  \"endMs\": \"2864520\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"design making things more convoluted give you the benefits of perhaps easier to test they don't give you clarity so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:37\"\n                                  },\n                                  \"trackingParams\": \"CIcBENP2BxjBAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 37 seconds design making things more convoluted give you the benefits of perhaps easier to test they don't give you clarity so\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2857140.2864520\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2864520\",\n                                  \"endMs\": \"2870580\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"those things are often in our position clarity is all about being succinct\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:44\"\n                                  },\n                                  \"trackingParams\": \"CIYBENP2BxjCAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 44 seconds those things are often in our position clarity is all about being succinct\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2864520.2870580\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2870580\",\n                                  \"endMs\": \"2876840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"without being tears we can write things using a small word since we know how\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:50\"\n                                  },\n                                  \"trackingParams\": \"CIUBENP2BxjDAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 50 seconds without being tears we can write things using a small word since we know how\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2870580.2876840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2876840\",\n                                  \"endMs\": \"2882940\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"using as little complication as we know how using as little conceptual overhead\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"47:56\"\n                                  },\n                                  \"trackingParams\": \"CIQBENP2BxjEAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"47 minutes, 56 seconds using as little complication as we know how using as little conceptual overhead\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2876840.2882940\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2882940\",\n                                  \"endMs\": \"2889900\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"as we know how to get the job done that's a much better approach and I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:02\"\n                                  },\n                                  \"trackingParams\": \"CIMBENP2BxjFAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 2 seconds as we know how to get the job done that's a much better approach and I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2882940.2889900\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2889900\",\n                                  \"endMs\": \"2895840\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"think it comes very easy if you think of software development as writing if you look at a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:09\"\n                                  },\n                                  \"trackingParams\": \"CIIBENP2BxjGAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 9 seconds think it comes very easy if you think of software development as writing if you look at a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2889900.2895840\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2895840\",\n                                  \"endMs\": \"2901000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"piece of writing that somebody has written and it's kind of convoluted can't really follow the argument and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:15\"\n                                  },\n                                  \"trackingParams\": \"CIEBENP2BxjHAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 15 seconds piece of writing that somebody has written and it's kind of convoluted can't really follow the argument and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2895840.2901000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2901000\",\n                                  \"endMs\": \"2908280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"paragraphs are not broken up neatly is the first thing you're going to say do you know what the problem with this is you're not using big enough words if\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:21\"\n                                  },\n                                  \"trackingParams\": \"CIABENP2BxjIAyITCIqQseW4k4cDFQLaSQcdvVADfQ==\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 21 seconds paragraphs are not broken up neatly is the first thing you're going to say do you know what the problem with this is you're not using big enough words if\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2901000.2908280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2908280\",\n                                  \"endMs\": \"2913910\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we just shove some bigger words into this text it's gonna be there that's good oh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:28\"\n                                  },\n                                  \"trackingParams\": \"CH8Q0_YHGMkDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 28 seconds we just shove some bigger words into this text it's gonna be there that's good oh\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2908280.2913910\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2913910\",\n                                  \"endMs\": \"2922110\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the problem here is like like your sentences are too clear if you just insert a sentence in the middle that'd\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:33\"\n                                  },\n                                  \"trackingParams\": \"CH4Q0_YHGMoDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 33 seconds the problem here is like like your sentences are too clear if you just insert a sentence in the middle that'd\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2913910.2922110\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2922110\",\n                                  \"endMs\": \"2928800\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"be great oh do you know what this needs more semicolons that's what this needs if this has more similar colons boom\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:42\"\n                                  },\n                                  \"trackingParams\": \"CH0Q0_YHGMsDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 42 seconds be great oh do you know what this needs more semicolons that's what this needs if this has more similar colons boom\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2922110.2928800\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2928800\",\n                                  \"endMs\": \"2933990\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you've got clarity no more in Direction more third-person these are not the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:48\"\n                                  },\n                                  \"trackingParams\": \"CHwQ0_YHGMwDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 48 seconds you've got clarity no more in Direction more third-person these are not the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2928800.2933990\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2933990\",\n                                  \"endMs\": \"2940170\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"things that make for great clear writing and that's obvious when we talk about things like writing so if we talk about\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"48:53\"\n                                  },\n                                  \"trackingParams\": \"CHsQ0_YHGM0DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"48 minutes, 53 seconds things that make for great clear writing and that's obvious when we talk about things like writing so if we talk about\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2933990.2940170\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2940170\",\n                                  \"endMs\": \"2945900\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"software development is writing I think it'll be obvious - I think if we\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:00\"\n                                  },\n                                  \"trackingParams\": \"CHoQ0_YHGM4DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes software development is writing I think it'll be obvious - I think if we\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2940170.2945900\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2945900\",\n                                  \"endMs\": \"2952230\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"supplant the high ideal of what matters for design is how easy it is to test how\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:05\"\n                                  },\n                                  \"trackingParams\": \"CHkQ0_YHGM8DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 5 seconds supplant the high ideal of what matters for design is how easy it is to test how\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2945900.2952230\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2952230\",\n                                  \"endMs\": \"2957480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"easy it is to make engineering driven and put clarity of the code base above\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:12\"\n                                  },\n                                  \"trackingParams\": \"CHgQ0_YHGNADIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 12 seconds easy it is to make engineering driven and put clarity of the code base above\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2952230.2957480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2957480\",\n                                  \"endMs\": \"2963330\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"all else we're going to be much better off and arguments are going to be settled much\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:17\"\n                                  },\n                                  \"trackingParams\": \"CHcQ0_YHGNEDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 17 seconds all else we're going to be much better off and arguments are going to be settled much\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2957480.2963330\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2963330\",\n                                  \"endMs\": \"2969390\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"easier and it's going to be much easier to read the code you wrote three months ago because you had that in mind\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:23\"\n                                  },\n                                  \"trackingParams\": \"CHYQ0_YHGNIDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 23 seconds easier and it's going to be much easier to read the code you wrote three months ago because you had that in mind\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2963330.2969390\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2969390\",\n                                  \"endMs\": \"2974510\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that was your motivation that was what you were going for so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:29\"\n                                  },\n                                  \"trackingParams\": \"CHUQ0_YHGNMDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 29 seconds that was your motivation that was what you were going for so\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2969390.2974510\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2975080\",\n                                  \"endMs\": \"2980550\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what is clarity how do you figure that out right that's really easy to say just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:35\"\n                                  },\n                                  \"trackingParams\": \"CHQQ0_YHGNQDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 35 seconds what is clarity how do you figure that out right that's really easy to say just\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2975080.2980550\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2980550\",\n                                  \"endMs\": \"2987300\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"clarity boom it's open to interpretation right it's not as clear it's just saying\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:40\"\n                                  },\n                                  \"trackingParams\": \"CHMQ0_YHGNUDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 40 seconds clarity boom it's open to interpretation right it's not as clear it's just saying\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2980550.2987300\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2987300\",\n                                  \"endMs\": \"2992460\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"or if you can just get your code coverage above 85% then you're gold right clarity doesn't work like that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:47\"\n                                  },\n                                  \"trackingParams\": \"CHIQ0_YHGNYDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 47 seconds or if you can just get your code coverage above 85% then you're gold right clarity doesn't work like that\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2987300.2992460\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"2992460\",\n                                  \"endMs\": \"3000100\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"there's not a metric we can just apply because again it's not hard science clarity of writing is not hard science\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"49:52\"\n                                  },\n                                  \"trackingParams\": \"CHEQ0_YHGNcDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"49 minutes, 52 seconds there's not a metric we can just apply because again it's not hard science clarity of writing is not hard science\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.2992460.3000100\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3000100\",\n                                  \"endMs\": \"3005390\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so the easy answer is I know it when I see\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:00\"\n                                  },\n                                  \"trackingParams\": \"CHAQ0_YHGNgDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes so the easy answer is I know it when I see\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3000100.3005390\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3005390\",\n                                  \"endMs\": \"3011330\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"it right there's not just going to be a list of principles and practices that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:05\"\n                                  },\n                                  \"trackingParams\": \"CG8Q0_YHGNkDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 5 seconds it right there's not just going to be a list of principles and practices that\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3005390.3011330\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3011330\",\n                                  \"endMs\": \"3018650\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"somebody can be taught and then they will automatically produce clear writing every time right if you want to be a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:11\"\n                                  },\n                                  \"trackingParams\": \"CG4Q0_YHGNoDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 11 seconds somebody can be taught and then they will automatically produce clear writing every time right if you want to be a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3011330.3018650\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3018650\",\n                                  \"endMs\": \"3025760\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"good writer is it enough just to sit and memorize the dictionary no just knowing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:18\"\n                                  },\n                                  \"trackingParams\": \"CG0Q0_YHGNsDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 18 seconds good writer is it enough just to sit and memorize the dictionary no just knowing\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3018650.3025760\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3025760\",\n                                  \"endMs\": \"3034540\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the words available to you knowing the patterns or stuff with development it's not that make you a good developer you have to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:25\"\n                                  },\n                                  \"trackingParams\": \"CGwQ0_YHGNwDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 25 seconds the words available to you knowing the patterns or stuff with development it's not that make you a good developer you have to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3025760.3034540\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3034540\",\n                                  \"endMs\": \"3039990\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"develop an eye you have to develop an eye for clarity which means first of all\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:34\"\n                                  },\n                                  \"trackingParams\": \"CGsQ0_YHGN0DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 34 seconds develop an eye you have to develop an eye for clarity which means first of all\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3034540.3039990\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3039990\",\n                                  \"endMs\": \"3045660\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you have to decide that that's important to you so that's the first step if you're still stuck in the most important\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:39\"\n                                  },\n                                  \"trackingParams\": \"CGoQ0_YHGN4DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 39 seconds you have to decide that that's important to you so that's the first step if you're still stuck in the most important\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3039990.3045660\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3045660\",\n                                  \"endMs\": \"3051990\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"thing about my system is how fast my tests run and how many of them I have well forget about it you're not going to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:45\"\n                                  },\n                                  \"trackingParams\": \"CGkQ0_YHGN8DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 45 seconds thing about my system is how fast my tests run and how many of them I have well forget about it you're not going to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3045660.3051990\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3051990\",\n                                  \"endMs\": \"3057560\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"get to this point you have to decide that the most important thing for your system is clarity\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:51\"\n                                  },\n                                  \"trackingParams\": \"CGgQ0_YHGOADIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 51 seconds get to this point you have to decide that the most important thing for your system is clarity\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3051990.3057560\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3057560\",\n                                  \"endMs\": \"3065070\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"when you do decide that you can start developing and I I started getting into photography maybe\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"50:57\"\n                                  },\n                                  \"trackingParams\": \"CGcQ0_YHGOEDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"50 minutes, 57 seconds when you do decide that you can start developing and I I started getting into photography maybe\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3057560.3065070\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3065070\",\n                                  \"endMs\": \"3070320\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"six years ago when I first got into photography like I would look at a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:05\"\n                                  },\n                                  \"trackingParams\": \"CGYQ0_YHGOIDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 5 seconds six years ago when I first got into photography like I would look at a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3065070.3070320\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3070320\",\n                                  \"endMs\": \"3076200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"picture looks like a good picture now I've been looking at thousands of pictures I've been taking thousands of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:10\"\n                                  },\n                                  \"trackingParams\": \"CGUQ0_YHGOMDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 10 seconds picture looks like a good picture now I've been looking at thousands of pictures I've been taking thousands of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3070320.3076200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3076200\",\n                                  \"endMs\": \"3083030\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"pictures and I've developed an eye I can see when the white balance is off I can see oh this has a blue tint oh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:16\"\n                                  },\n                                  \"trackingParams\": \"CGQQ0_YHGOQDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 16 seconds pictures and I've developed an eye I can see when the white balance is off I can see oh this has a blue tint oh\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3076200.3083030\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3083030\",\n                                  \"endMs\": \"3089310\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this actually if we crop it just a little bit more only the subjects we want to have in focus on focus oh this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:23\"\n                                  },\n                                  \"trackingParams\": \"CGMQ0_YHGOUDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 23 seconds this actually if we crop it just a little bit more only the subjects we want to have in focus on focus oh this\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3083030.3089310\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3089310\",\n                                  \"endMs\": \"3094710\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"would actually be better in black and white that I just came from doing it a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:29\"\n                                  },\n                                  \"trackingParams\": \"CGIQ0_YHGOYDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 29 seconds would actually be better in black and white that I just came from doing it a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3089310.3094710\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3094710\",\n                                  \"endMs\": \"3102450\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"lot it didn't come from just sitting down and reading a lot of photography books and I think it's the same thing\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:34\"\n                                  },\n                                  \"trackingParams\": \"CGEQ0_YHGOcDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 34 seconds lot it didn't come from just sitting down and reading a lot of photography books and I think it's the same thing\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3094710.3102450\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3102450\",\n                                  \"endMs\": \"3108120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"with code a lot of programmers coming added from a software engineering angle\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:42\"\n                                  },\n                                  \"trackingParams\": \"CGAQ0_YHGOgDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 42 seconds with code a lot of programmers coming added from a software engineering angle\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3102450.3108120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3108120\",\n                                  \"endMs\": \"3113570\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"think that just all they have to do is learn the practices learn the patterns\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:48\"\n                                  },\n                                  \"trackingParams\": \"CF8Q0_YHGOkDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 48 seconds think that just all they have to do is learn the practices learn the patterns\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3108120.3113570\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3113570\",\n                                  \"endMs\": \"3120000\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"memorize them all and then they will be good programmers no they won't the only\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"51:53\"\n                                  },\n                                  \"trackingParams\": \"CF4Q0_YHGOoDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"51 minutes, 53 seconds memorize them all and then they will be good programmers no they won't the only\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3113570.3120000\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3120000\",\n                                  \"endMs\": \"3126060\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"way to become a good programmer where by definition I define good program is somebody who program who writes software\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"52:00\"\n                                  },\n                                  \"trackingParams\": \"CF0Q0_YHGOsDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 minutes way to become a good programmer where by definition I define good program is somebody who program who writes software\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3120000.3126060\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3126060\",\n                                  \"endMs\": \"3132570\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"with clarity is to read a lot of software write a lot of software just\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"52:06\"\n                                  },\n                                  \"trackingParams\": \"CFwQ0_YHGOwDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 minutes, 6 seconds with clarity is to read a lot of software write a lot of software just\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3126060.3132570\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3132570\",\n                                  \"endMs\": \"3139280\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"like how do you become a good photographer you take a lot of pictures and you look at them and you practice and you practice and you practice\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"52:12\"\n                                  },\n                                  \"trackingParams\": \"CFsQ0_YHGO0DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 minutes, 12 seconds like how do you become a good photographer you take a lot of pictures and you look at them and you practice and you practice and you practice\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3132570.3139280\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3139280\",\n                                  \"endMs\": \"3144480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that's actually quite similar to the problem with diets right the fundamental\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"52:19\"\n                                  },\n                                  \"trackingParams\": \"CFoQ0_YHGO4DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 minutes, 19 seconds that's actually quite similar to the problem with diets right the fundamental\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3139280.3144480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3144480\",\n                                  \"endMs\": \"3150290\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"truth with diets is to be healthy you won't you should probably exercise regularly you should probably\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"52:24\"\n                                  },\n                                  \"trackingParams\": \"CFkQ0_YHGO8DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 minutes, 24 seconds truth with diets is to be healthy you won't you should probably exercise regularly you should probably\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3144480.3150290\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3150290\",\n                                  \"endMs\": \"3156060\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"eat a reasonable amount and it should be good stuff like that's three things\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"52:30\"\n                                  },\n                                  \"trackingParams\": \"CFgQ0_YHGPADIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 minutes, 30 seconds eat a reasonable amount and it should be good stuff like that's three things\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3150290.3156060\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3156060\",\n                                  \"endMs\": \"3162440\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"incredibly hard to do most people do not do that right figuring out how to write good software\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"52:36\"\n                                  },\n                                  \"trackingParams\": \"CFcQ0_YHGPEDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 minutes, 36 seconds incredibly hard to do most people do not do that right figuring out how to write good software\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3156060.3162440\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3162440\",\n                                  \"endMs\": \"3169890\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"read a lot of software write a lot of software aim for clarity it sounds too simple why\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"52:42\"\n                                  },\n                                  \"trackingParams\": \"CFYQ0_YHGPIDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 minutes, 42 seconds read a lot of software write a lot of software aim for clarity it sounds too simple why\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3162440.3169890\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3169890\",\n                                  \"endMs\": \"3177120\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"is it simple because there's not just a quit there's not just one answer somebody can give you the only way you can get there is by\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"52:49\"\n                                  },\n                                  \"trackingParams\": \"CFUQ0_YHGPMDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 minutes, 49 seconds is it simple because there's not just a quit there's not just one answer somebody can give you the only way you can get there is by\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3169890.3177120\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3177120\",\n                                  \"endMs\": \"3186390\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"doing it so when I first started developing rails I read a ton of software I read\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"52:57\"\n                                  },\n                                  \"trackingParams\": \"CFQQ0_YHGPQDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"52 minutes, 57 seconds doing it so when I first started developing rails I read a ton of software I read\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3177120.3186390\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3186390\",\n                                  \"endMs\": \"3192570\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the entire Ruby standard library partly because documentation of Ruby at that time was pretty poor and the only\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"53:06\"\n                                  },\n                                  \"trackingParams\": \"CFMQ0_YHGPUDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"53 minutes, 6 seconds the entire Ruby standard library partly because documentation of Ruby at that time was pretty poor and the only\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3186390.3192570\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3192570\",\n                                  \"endMs\": \"3197600\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"way to figure out how it worked was to actually look at code but that was also where I learned so much\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"53:12\"\n                                  },\n                                  \"trackingParams\": \"CFIQ0_YHGPYDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"53 minutes, 12 seconds way to figure out how it worked was to actually look at code but that was also where I learned so much\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3192570.3197600\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3197600\",\n                                  \"endMs\": \"3203820\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"today we have it so much easier bundle open name of any gem and it'll\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"53:17\"\n                                  },\n                                  \"trackingParams\": \"CFEQ0_YHGPcDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"53 minutes, 17 seconds today we have it so much easier bundle open name of any gem and it'll\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3197600.3203820\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3203820\",\n                                  \"endMs\": \"3210660\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"open boom right up in your text editor you can look at any code how many of you have read through a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"53:23\"\n                                  },\n                                  \"trackingParams\": \"CFAQ0_YHGPgDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"53 minutes, 23 seconds open boom right up in your text editor you can look at any code how many of you have read through a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3203820.3210660\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3210660\",\n                                  \"endMs\": \"3218010\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"complete gem recently something you did not write awesome that's actually really\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"53:30\"\n                                  },\n                                  \"trackingParams\": \"CE8Q0_YHGPkDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"53 minutes, 30 seconds complete gem recently something you did not write awesome that's actually really\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3210660.3218010\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3218010\",\n                                  \"endMs\": \"3223980\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"encouraging I thought it'd be much less I think that is exactly the path you need to take you need to read a ton\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"53:38\"\n                                  },\n                                  \"trackingParams\": \"CE4Q0_YHGPoDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"53 minutes, 38 seconds encouraging I thought it'd be much less I think that is exactly the path you need to take you need to read a ton\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3218010.3223980\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3223980\",\n                                  \"endMs\": \"3231900\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"of code and it's not so much just because you read this code and then oh that's all great stuff just as important as it is to to develop\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"53:43\"\n                                  },\n                                  \"trackingParams\": \"CE0Q0_YHGPsDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"53 minutes, 43 seconds of code and it's not so much just because you read this code and then oh that's all great stuff just as important as it is to to develop\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3223980.3231900\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3231900\",\n                                  \"endMs\": \"3237750\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"your since writing by reading a lot of  writing so is it with code and I\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"53:51\"\n                                  },\n                                  \"trackingParams\": \"CEwQ0_YHGPwDIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"53 minutes, 51 seconds your since writing by reading a lot of  writing so is it with code and I\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3231900.3237750\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3237750\",\n                                  \"endMs\": \"3246170\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"think you will find that that is actually very easy because a lot of things you'll do button will open on will follow sturgeons revelation\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"53:57\"\n                                  },\n                                  \"trackingParams\": \"CEsQ0_YHGP0DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"53 minutes, 57 seconds think you will find that that is actually very easy because a lot of things you'll do button will open on will follow sturgeons revelation\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3237750.3246170\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3246170\",\n                                  \"endMs\": \"3252810\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"90% of everything is crack umm well at least you know you have company\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"54:06\"\n                                  },\n                                  \"trackingParams\": \"CEoQ0_YHGP4DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"54 minutes, 6 seconds 90% of everything is crack umm well at least you know you have company\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3246170.3252810\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3252810\",\n                                  \"endMs\": \"3259260\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"if you write crap software in I certainly do from done time um and that's a great way to learn I actually\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"54:12\"\n                                  },\n                                  \"trackingParams\": \"CEkQ0_YHGP8DIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"54 minutes, 12 seconds if you write crap software in I certainly do from done time um and that's a great way to learn I actually\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3252810.3259260\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3259260\",\n                                  \"endMs\": \"3264510\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"find that I learned the most about software and learned the most about what matters to me I learned the most about\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"54:19\"\n                                  },\n                                  \"trackingParams\": \"CEgQ0_YHGIAEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"54 minutes, 19 seconds find that I learned the most about software and learned the most about what matters to me I learned the most about\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3259260.3264510\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3264510\",\n                                  \"endMs\": \"3270060\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"what clarity is when I read poor software because what I do is I take a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"54:24\"\n                                  },\n                                  \"trackingParams\": \"CEcQ0_YHGIEEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"54 minutes, 24 seconds what clarity is when I read poor software because what I do is I take a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3264510.3270060\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3270060\",\n                                  \"endMs\": \"3276870\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"piece of software I take a class or method and then I look at I'll go this book here like this is I think this is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"54:30\"\n                                  },\n                                  \"trackingParams\": \"CEYQ0_YHGIIEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"54 minutes, 30 seconds piece of software I take a class or method and then I look at I'll go this book here like this is I think this is\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3270060.3276870\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3276870\",\n                                  \"endMs\": \"3282990\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"poorly written I think this smells I can i rewrite it so by just sitting down and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"54:36\"\n                                  },\n                                  \"trackingParams\": \"CEUQ0_YHGIMEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"54 minutes, 36 seconds poorly written I think this smells I can i rewrite it so by just sitting down and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3276870.3282990\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3282990\",\n                                  \"endMs\": \"3289110\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"going through that exercise and rewriting it I find I learn a whole lot about what I care about so that's what\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"54:42\"\n                                  },\n                                  \"trackingParams\": \"CEQQ0_YHGIQEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"54 minutes, 42 seconds going through that exercise and rewriting it I find I learn a whole lot about what I care about so that's what\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3282990.3289110\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3289110\",\n                                  \"endMs\": \"3295650\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I've been doing lately engaging in a lot of these internet arguments somebody will submit a piece of code and usually\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"54:49\"\n                                  },\n                                  \"trackingParams\": \"CEMQ0_YHGIUEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"54 minutes, 49 seconds I've been doing lately engaging in a lot of these internet arguments somebody will submit a piece of code and usually\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3289110.3295650\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3295650\",\n                                  \"endMs\": \"3301200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the submission will come along with the proposed solution to it I had to shoot a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"54:55\"\n                                  },\n                                  \"trackingParams\": \"CEIQ0_YHGIYEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"54 minutes, 55 seconds the submission will come along with the proposed solution to it I had to shoot a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3295650.3301200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3301200\",\n                                  \"endMs\": \"3308870\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"piece of code then I learned about these three patterns and now full and what I have found every single time and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"55:01\"\n                                  },\n                                  \"trackingParams\": \"CEEQ0_YHGIcEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"55 minutes, 1 second piece of code then I learned about these three patterns and now full and what I have found every single time and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3301200.3308870\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3308870\",\n                                  \"endMs\": \"3314420\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"I've only done this maybe a handful of time maybe a little more is that every single time you just took the shitty\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"55:08\"\n                                  },\n                                  \"trackingParams\": \"CEAQ0_YHGIgEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"55 minutes, 8 seconds I've only done this maybe a handful of time maybe a little more is that every single time you just took the shitty\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3308870.3314420\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3314420\",\n                                  \"endMs\": \"3321590\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"code and you stuck it into some different boxes like it didn't actually improve I plied the pattern to it did not improve the underlying clarity of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"55:14\"\n                                  },\n                                  \"trackingParams\": \"CD8Q0_YHGIkEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"55 minutes, 14 seconds code and you stuck it into some different boxes like it didn't actually improve I plied the pattern to it did not improve the underlying clarity of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3314420.3321590\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3321590\",\n                                  \"endMs\": \"3328940\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"the code because you just wrote it poorly like the problem with the code was not that it was missing patterns the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"55:21\"\n                                  },\n                                  \"trackingParams\": \"CD4Q0_YHGIoEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"55 minutes, 21 seconds the code because you just wrote it poorly like the problem with the code was not that it was missing patterns the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3321590.3328940\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3328940\",\n                                  \"endMs\": \"3335590\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"problem with the code was that it was crap that he just had to be rewritten now\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"55:28\"\n                                  },\n                                  \"trackingParams\": \"CD0Q0_YHGIsEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"55 minutes, 28 seconds problem with the code was that it was crap that he just had to be rewritten now\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3328940.3335590\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3335590\",\n                                  \"endMs\": \"3339400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that leads us to sort of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"55:35\"\n                                  },\n                                  \"trackingParams\": \"CDwQ0_YHGIwEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"55 minutes, 35 seconds that leads us to sort of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3335590.3339400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3341200\",\n                                  \"endMs\": \"3346910\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"mission in some ways from what rails is and what Ruby is and it leads also to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"55:41\"\n                                  },\n                                  \"trackingParams\": \"CDsQ0_YHGI0EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"55 minutes, 41 seconds mission in some ways from what rails is and what Ruby is and it leads also to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3341200.3346910\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3346910\",\n                                  \"endMs\": \"3353390\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"clarify some of the arguments we've had in the rails community for a while readability is incredibly important to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"55:46\"\n                                  },\n                                  \"trackingParams\": \"CDoQ0_YHGI4EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"55 minutes, 46 seconds clarify some of the arguments we've had in the rails community for a while readability is incredibly important to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3346910.3353390\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3353390\",\n                                  \"endMs\": \"3359360\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"Ruby we have a lot of duplicated methods that do exactly the same thing just so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"55:53\"\n                                  },\n                                  \"trackingParams\": \"CDkQ0_YHGI8EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"55 minutes, 53 seconds Ruby we have a lot of duplicated methods that do exactly the same thing just so\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3353390.3359360\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3359360\",\n                                  \"endMs\": \"3366680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we can improve readability I remember the first time I saw unless when I was learning about Ruby that was\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"55:59\"\n                                  },\n                                  \"trackingParams\": \"CDgQ0_YHGJAEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"55 minutes, 59 seconds we can improve readability I remember the first time I saw unless when I was learning about Ruby that was\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3359360.3366680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3366680\",\n                                  \"endMs\": \"3372790\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"one of those light bulb moments like wait a minute unless it's exactly the same as if not\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"56:06\"\n                                  },\n                                  \"trackingParams\": \"CDcQ0_YHGJEEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"56 minutes, 6 seconds one of those light bulb moments like wait a minute unless it's exactly the same as if not\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3366680.3372790\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3372790\",\n                                  \"endMs\": \"3378190\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"but it's a different keyword ha\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"56:12\"\n                                  },\n                                  \"trackingParams\": \"CDYQ0_YHGJIEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"56 minutes, 12 seconds but it's a different keyword ha\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3372790.3378190\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3378190\",\n                                  \"endMs\": \"3386090\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"right it was not just about making the mostess efficient compact language it was about\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"56:18\"\n                                  },\n                                  \"trackingParams\": \"CDUQ0_YHGJMEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"56 minutes, 18 seconds right it was not just about making the mostess efficient compact language it was about\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3378190.3386090\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3386090\",\n                                  \"endMs\": \"3392290\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"readability mind-blown and\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"56:26\"\n                                  },\n                                  \"trackingParams\": \"CDQQ0_YHGJQEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"56 minutes, 26 seconds readability mind-blown and\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3386090.3392290\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3392290\",\n                                  \"endMs\": \"3397640\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"decade long love affair would Ruby established and I think this is what\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"56:32\"\n                                  },\n                                  \"trackingParams\": \"CDMQ0_YHGJUEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"56 minutes, 32 seconds decade long love affair would Ruby established and I think this is what\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3392290.3397640\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3397640\",\n                                  \"endMs\": \"3402680\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"we're trying to achieve constantly in rails as well a lot of\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"56:37\"\n                                  },\n                                  \"trackingParams\": \"CDIQ0_YHGJYEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"56 minutes, 37 seconds we're trying to achieve constantly in rails as well a lot of\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3397640.3402680\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3402680\",\n                                  \"endMs\": \"3409370\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"people will gripe about Oh active record is too big or something is too bigger have too many methods or the surface\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"56:42\"\n                                  },\n                                  \"trackingParams\": \"CDEQ0_YHGJcEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"56 minutes, 42 seconds people will gripe about Oh active record is too big or something is too bigger have too many methods or the surface\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3402680.3409370\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3409370\",\n                                  \"endMs\": \"3414410\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"areas through Baker lose whatever it is right like oops his ship is it more\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"56:49\"\n                                  },\n                                  \"trackingParams\": \"CDAQ0_YHGJgEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"56 minutes, 49 seconds areas through Baker lose whatever it is right like oops his ship is it more\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3409370.3414410\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3414410\",\n                                  \"endMs\": \"3420500\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"readable is it more clear that's the only thing that matters what do I care whether the surface area of a method is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"56:54\"\n                                  },\n                                  \"trackingParams\": \"CC8Q0_YHGJkEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"56 minutes, 54 seconds readable is it more clear that's the only thing that matters what do I care whether the surface area of a method is\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3414410.3420500\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3420500\",\n                                  \"endMs\": \"3426650\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"100 methods or it's 200 methods I don't give a about that the only thing I gave a about is whether it's the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"57:00\"\n                                  },\n                                  \"trackingParams\": \"CC4Q0_YHGJoEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"57 minutes 100 methods or it's 200 methods I don't give a about that the only thing I gave a about is whether it's the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3420500.3426650\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3426650\",\n                                  \"endMs\": \"3432200\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"code I'm actually reading is the system I'm trying to understand is that more clear when you put clarity as your\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"57:06\"\n                                  },\n                                  \"trackingParams\": \"CC0Q0_YHGJsEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"57 minutes, 6 seconds code I'm actually reading is the system I'm trying to understand is that more clear when you put clarity as your\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3426650.3432200\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3432200\",\n                                  \"endMs\": \"3439990\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"number one mission a lot of concerns just fall by the wayside it is just as matter anymore and it's liberating\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"57:12\"\n                                  },\n                                  \"trackingParams\": \"CCwQ0_YHGJwEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"57 minutes, 12 seconds number one mission a lot of concerns just fall by the wayside it is just as matter anymore and it's liberating\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3432200.3439990\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3440919\",\n                                  \"endMs\": \"3447769\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"so I think this actually comes from sort of the same route I didn't have time to write a short letter so I wrote a long\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"57:20\"\n                                  },\n                                  \"trackingParams\": \"CCsQ0_YHGJ0EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"57 minutes, 20 seconds so I think this actually comes from sort of the same route I didn't have time to write a short letter so I wrote a long\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3440919.3447769\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3447769\",\n                                  \"endMs\": \"3454549\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"one instead I think that describes about 80% of all that 90% of shitty code most\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"57:27\"\n                                  },\n                                  \"trackingParams\": \"CCoQ0_YHGJ4EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"57 minutes, 27 seconds one instead I think that describes about 80% of all that 90% of shitty code most\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3447769.3454549\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3454549\",\n                                  \"endMs\": \"3460849\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"people did not take the time to write a short piece of code so they wrote a long\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"57:34\"\n                                  },\n                                  \"trackingParams\": \"CCkQ0_YHGJ8EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"57 minutes, 34 seconds people did not take the time to write a short piece of code so they wrote a long\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3454549.3460849\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3460849\",\n                                  \"endMs\": \"3466429\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"one instead and then they wrote that long one piece of code and they like pulled out their suspenders and like oh\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"57:40\"\n                                  },\n                                  \"trackingParams\": \"CCgQ0_YHGKAEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"57 minutes, 40 seconds one instead and then they wrote that long one piece of code and they like pulled out their suspenders and like oh\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3460849.3466429\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3466429\",\n                                  \"endMs\": \"3472880\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"yeah I'm done my test pass boom right or they look at in zygous oh this is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"57:46\"\n                                  },\n                                  \"trackingParams\": \"CCcQ0_YHGKEEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"57 minutes, 46 seconds yeah I'm done my test pass boom right or they look at in zygous oh this is\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3466429.3472880\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3472880\",\n                                  \"endMs\": \"3478359\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"too long I must be missing some patterns I just sprinkle some patterns over this\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"57:52\"\n                                  },\n                                  \"trackingParams\": \"CCYQ0_YHGKIEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"57 minutes, 52 seconds too long I must be missing some patterns I just sprinkle some patterns over this\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3472880.3478359\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3478359\",\n                                  \"endMs\": \"3484929\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"wonders right know what you wrote was a draft\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"57:58\"\n                                  },\n                                  \"trackingParams\": \"CCUQ0_YHGKMEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"57 minutes, 58 seconds wonders right know what you wrote was a draft\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3478359.3484929\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3484929\",\n                                  \"endMs\": \"3490069\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"this was just the first draft right any piece of code you write down it's just a\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"58:04\"\n                                  },\n                                  \"trackingParams\": \"CCQQ0_YHGKQEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"58 minutes, 4 seconds this was just the first draft right any piece of code you write down it's just a\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3484929.3490069\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3490069\",\n                                  \"endMs\": \"3497989\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"draft um Mark Twain actually had the hard job right he wrote in ink if you had to\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"58:10\"\n                                  },\n                                  \"trackingParams\": \"CCMQ0_YHGKUEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"58 minutes, 10 seconds draft um Mark Twain actually had the hard job right he wrote in ink if you had to\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3490069.3497989\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3497989\",\n                                  \"endMs\": \"3505400\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"change that I was kind of hard right so his drafts were a lot more complicated ours we have it so easy a text editor\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"58:17\"\n                                  },\n                                  \"trackingParams\": \"CCIQ0_YHGKYEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"58 minutes, 17 seconds change that I was kind of hard right so his drafts were a lot more complicated ours we have it so easy a text editor\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3497989.3505400\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3505400\",\n                                  \"endMs\": \"3510619\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you just delete stuff you don't need any of this little stuff that you you fill over the page and you spill it\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"58:25\"\n                                  },\n                                  \"trackingParams\": \"CCEQ0_YHGKcEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"58 minutes, 25 seconds you just delete stuff you don't need any of this little stuff that you you fill over the page and you spill it\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3505400.3510619\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3510619\",\n                                  \"endMs\": \"3515869\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"everywhere and so forth eraser um you can just delete stuff like that's my\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"58:30\"\n                                  },\n                                  \"trackingParams\": \"CCAQ0_YHGKgEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"58 minutes, 30 seconds everywhere and so forth eraser um you can just delete stuff like that's my\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3510619.3515869\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3515869\",\n                                  \"endMs\": \"3522249\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"favorite key did the lead key it's the number one tool for improving code\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"58:35\"\n                                  },\n                                  \"trackingParams\": \"CB8Q0_YHGKkEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"58 minutes, 35 seconds favorite key did the lead key it's the number one tool for improving code\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3515869.3522249\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3522249\",\n                                  \"endMs\": \"3529390\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"delete key so\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"58:42\"\n                                  },\n                                  \"trackingParams\": \"CB4Q0_YHGKoEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"58 minutes, 42 seconds delete key so\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3522249.3529390\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3529390\",\n                                  \"endMs\": \"3536659\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"when I was in high school I submitted a bunch of first drafts as essays and they\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"58:49\"\n                                  },\n                                  \"trackingParams\": \"CB0Q0_YHGKsEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"58 minutes, 49 seconds when I was in high school I submitted a bunch of first drafts as essays and they\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3529390.3536659\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3536659\",\n                                  \"endMs\": \"3542539\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"were really shitty and of course they weren't they were the first draft and my teacher at the time said all right all\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"58:56\"\n                                  },\n                                  \"trackingParams\": \"CBwQ0_YHGKwEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"58 minutes, 56 seconds were really shitty and of course they weren't they were the first draft and my teacher at the time said all right all\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3536659.3542539\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3542539\",\n                                  \"endMs\": \"3547939\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"right this is dissection or bad you just only did step one if you have something on your mind you should write it down\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"59:02\"\n                                  },\n                                  \"trackingParams\": \"CBsQ0_YHGK0EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"59 minutes, 2 seconds right this is dissection or bad you just only did step one if you have something on your mind you should write it down\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3542539.3547939\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3547939\",\n                                  \"endMs\": \"3553039\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that's what I did I wrote it down and then I hand it in oh if you have written\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"59:07\"\n                                  },\n                                  \"trackingParams\": \"CBoQ0_YHGK4EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"59 minutes, 7 seconds that's what I did I wrote it down and then I hand it in oh if you have written\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3547939.3553039\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3553039\",\n                                  \"endMs\": \"3558619\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"something down you should rewrite it oh that was the step I missed and I think\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"59:13\"\n                                  },\n                                  \"trackingParams\": \"CBkQ0_YHGK8EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"59 minutes, 13 seconds something down you should rewrite it oh that was the step I missed and I think\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3553039.3558619\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3558619\",\n                                  \"endMs\": \"3564589\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"that's the step most people miss when they write down code because they're focused on all these other things they're not focused on the clarity\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"59:18\"\n                                  },\n                                  \"trackingParams\": \"CBgQ0_YHGLAEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"59 minutes, 18 seconds that's the step most people miss when they write down code because they're focused on all these other things they're not focused on the clarity\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3558619.3564589\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3564589\",\n                                  \"endMs\": \"3570920\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"because when you are focused on the clarity you will realize that all your first drafts are terrible\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"59:24\"\n                                  },\n                                  \"trackingParams\": \"CBcQ0_YHGLEEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"59 minutes, 24 seconds because when you are focused on the clarity you will realize that all your first drafts are terrible\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3564589.3570920\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3570920\",\n                                  \"endMs\": \"3578480\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"first drafts are terrible all my first attempts at writing a good class are poor they're too long they're not at the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"59:30\"\n                                  },\n                                  \"trackingParams\": \"CBYQ0_YHGLIEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"59 minutes, 30 seconds first drafts are terrible all my first attempts at writing a good class are poor they're too long they're not at the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3570920.3578480\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3578480\",\n                                  \"endMs\": \"3584180\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"same level of abstraction they're not clear and that's okay I wrote something down I was trying to figure out what the\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"59:38\"\n                                  },\n                                  \"trackingParams\": \"CBUQ0_YHGLMEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"59 minutes, 38 seconds same level of abstraction they're not clear and that's okay I wrote something down I was trying to figure out what the\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3578480.3584180\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3584180\",\n                                  \"endMs\": \"3590150\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"system was supposed to do that's hard work and oftentimes you don't get perfect code out of that when\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"59:44\"\n                                  },\n                                  \"trackingParams\": \"CBQQ0_YHGLQEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"59 minutes, 44 seconds system was supposed to do that's hard work and oftentimes you don't get perfect code out of that when\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3584180.3590150\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3590150\",\n                                  \"endMs\": \"3595160\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you're still trying to figure out what it is that you're writing but once you've written it down you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"59:50\"\n                                  },\n                                  \"trackingParams\": \"CBMQ0_YHGLUEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"59 minutes, 50 seconds you're still trying to figure out what it is that you're writing but once you've written it down you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3590150.3595160\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3595160\",\n                                  \"endMs\": \"3602859\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"should rewrite it and I think the key part of rewriting is\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"59:55\"\n                                  },\n                                  \"trackingParams\": \"CBIQ0_YHGLYEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"59 minutes, 55 seconds should rewrite it and I think the key part of rewriting is\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3595160.3602859\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3602859\",\n                                  \"endMs\": \"3608470\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"omitting needless words when it comes to regular writing when it comes to programming its\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00:02\"\n                                  },\n                                  \"trackingParams\": \"CBEQ0_YHGLcEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 hour, 2 seconds omitting needless words when it comes to regular writing when it comes to programming its\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3602859.3608470\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3608470\",\n                                  \"endMs\": \"3614839\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"omitting needless concepts its submitting needless patterns it's submitting needless practices its\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00:08\"\n                                  },\n                                  \"trackingParams\": \"CBAQ0_YHGLgEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 hour, 8 seconds omitting needless concepts its submitting needless patterns it's submitting needless practices its\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3608470.3614839\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3614839\",\n                                  \"endMs\": \"3620559\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"submitting needless classes its submitting all these extra things that\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00:14\"\n                                  },\n                                  \"trackingParams\": \"CA8Q0_YHGLkEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 hour, 14 seconds submitting needless classes its submitting all these extra things that\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3614839.3620559\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3620559\",\n                                  \"endMs\": \"3626510\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"aren't getting you closer to clarity right how do you know you develop an eye\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00:20\"\n                                  },\n                                  \"trackingParams\": \"CA4Q0_YHGLoEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 hour, 20 seconds aren't getting you closer to clarity right how do you know you develop an eye\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3620559.3626510\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3626510\",\n                                  \"endMs\": \"3632960\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"for it how do you develop an eye you read a lot of code you write a lot of code you rewrite a lot of code and you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00:26\"\n                                  },\n                                  \"trackingParams\": \"CA0Q0_YHGLsEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 hour, 26 seconds for it how do you develop an eye you read a lot of code you write a lot of code you rewrite a lot of code and you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3626510.3632960\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3632960\",\n                                  \"endMs\": \"3640190\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"forget about patterns for a while you forget about TDD for a while and you focus on just what's in\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00:32\"\n                                  },\n                                  \"trackingParams\": \"CAwQ0_YHGLwEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 hour, 32 seconds forget about patterns for a while you forget about TDD for a while and you focus on just what's in\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3632960.3640190\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3640190\",\n                                  \"endMs\": \"3648970\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"front of you the piece of code how can I write it's simpler write software well thank you very much\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00:40\"\n                                  },\n                                  \"trackingParams\": \"CAsQ0_YHGL0EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 hour, 40 seconds front of you the piece of code how can I write it's simpler write software well thank you very much\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3640190.3648970\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3648970\",\n                                  \"endMs\": \"3655750\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"[Applause]\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00:48\"\n                                  },\n                                  \"trackingParams\": \"CAoQ0_YHGL4EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 hour, 48 seconds [Applause]\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3648970.3655750\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3655750\",\n                                  \"endMs\": \"3671569\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"[Music]\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:00:55\"\n                                  },\n                                  \"trackingParams\": \"CAkQ0_YHGL8EIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 hour, 55 seconds [Music]\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3655750.3671569\"\n                                }\n                              },\n                              {\n                                \"transcriptSegmentRenderer\": {\n                                  \"startMs\": \"3671569\",\n                                  \"endMs\": \"3673630\",\n                                  \"snippet\": {\n                                    \"runs\": [\n                                      {\n                                        \"text\": \"you\"\n                                      }\n                                    ]\n                                  },\n                                  \"startTimeText\": {\n                                    \"simpleText\": \"1:01:11\"\n                                  },\n                                  \"trackingParams\": \"CAgQ0_YHGMAEIhMIipCx5biThwMVAtpJBx29UAN9\",\n                                  \"accessibility\": {\n                                    \"accessibilityData\": {\n                                      \"label\": \"1 hour, 1 minute, 11 seconds you\"\n                                    }\n                                  },\n                                  \"targetId\": \"9LfmrkyP81M.CgNhc3ISAmVu.3671569.3673630\"\n                                }\n                              }\n                            ],\n                            \"noResultLabel\": {\n                              \"runs\": [\n                                {\n                                  \"text\": \"No results found\"\n                                }\n                              ]\n                            },\n                            \"retryLabel\": {\n                              \"runs\": [\n                                {\n                                  \"text\": \"TAP TO RETRY\"\n                                }\n                              ]\n                            },\n                            \"touchCaptionsEnabled\": false\n                          }\n                        },\n                        \"footer\": {\n                          \"transcriptFooterRenderer\": {\n                            \"languageMenu\": {\n                              \"sortFilterSubMenuRenderer\": {\n                                \"subMenuItems\": [\n                                  {\n                                    \"title\": \"English\",\n                                    \"selected\": false,\n                                    \"continuation\": {\n                                      \"reloadContinuationData\": {\n                                        \"continuation\": \"Cgs5TGZtcmt5UDgxTRIOQ2dBU0FtVnVHZ0ElM0QYASozZW5nYWdlbWVudC1wYW5lbC1zZWFyY2hhYmxlLXRyYW5zY3JpcHQtc2VhcmNoLXBhbmVsMAA4AEAA\",\n                                        \"clickTrackingParams\": \"CAcQxqYCIhMIipCx5biThwMVAtpJBx29UAN9\"\n                                      }\n                                    },\n                                    \"trackingParams\": \"CAYQ48AHGAAiEwiKkLHluJOHAxUC2kkHHb1QA30=\"\n                                  },\n                                  {\n                                    \"title\": \"English (auto-generated)\",\n                                    \"selected\": true,\n                                    \"continuation\": {\n                                      \"reloadContinuationData\": {\n                                        \"continuation\": \"Cgs5TGZtcmt5UDgxTRISQ2dOaGMzSVNBbVZ1R2dBJTNEGAEqM2VuZ2FnZW1lbnQtcGFuZWwtc2VhcmNoYWJsZS10cmFuc2NyaXB0LXNlYXJjaC1wYW5lbDAAOABAAA%3D%3D\",\n                                        \"clickTrackingParams\": \"CAUQxqYCIhMIipCx5biThwMVAtpJBx29UAN9\"\n                                      }\n                                    },\n                                    \"trackingParams\": \"CAQQ48AHGAEiEwiKkLHluJOHAxUC2kkHHb1QA30=\"\n                                  }\n                                ],\n                                \"trackingParams\": \"CAMQgdoEIhMIipCx5biThwMVAtpJBx29UAN9\"\n                              }\n                            }\n                          }\n                        },\n                        \"trackingParams\": \"CAIQ8bsCIhMIipCx5biThwMVAtpJBx29UAN9\",\n                        \"targetId\": \"engagement-panel-searchable-transcript-search-panel\"\n                      }\n                    }\n                  }\n                }\n              }\n            }\n          ],\n          \"trackingParams\": \"CAAQw7wCIhMIipCx5biThwMVAtpJBx29UAN9\"\n        }\n  recorded_at: Sat, 06 Jul 2024 22:17:46 GMT\nrecorded_with: VCR 6.2.0\n"
  },
  {
    "path": "tmp/.keep",
    "content": ""
  },
  {
    "path": "vendor/.keep",
    "content": ""
  },
  {
    "path": "vite.config.mjs",
    "content": "import { defineConfig } from 'vite'\nimport ViteRails from 'vite-plugin-rails'\n\nexport default defineConfig({\n  plugins: [\n    ViteRails({\n      fullReload: {\n        additionalPaths: [\n          'config/routes.rb',\n          'app/views/**/*',\n          'app/controllers/**/*',\n          'app/models/**/*',\n          'tmp/vite-reload'\n        ]\n      }\n    })\n  ],\n  server: {\n    watch: {\n      ignored: ['**/data/**']\n    }\n  }\n})\n"
  },
  {
    "path": "yaml/enforce_strings.mjs",
    "content": "import fs from 'fs'\nimport { Formatter } from './formatter.mjs'\n\nconst files = []\nconst paths = []\nif (process.argv.length > 2) {\n  process.argv.slice(2).forEach((path) => {\n    paths.push(path)\n  })\n} else {\n  paths.push('./data')\n}\n\npaths.forEach((path) => {\n  if (path.endsWith('/')) {\n    path = path.slice(0, -1)\n  }\n  if (fs.existsSync(path)) {\n    if (fs.lstatSync(path).isDirectory()) {\n      fs.readdirSync(path, { recursive: true })\n        .filter((file) => file.endsWith('.yml'))\n        .forEach((file) => files.push(`${path}/${file}`))\n    } else if (path.endsWith('.yml')) {\n      files.push(path)\n    } else {\n      console.log(`Ignoring ${path} as it's not yaml`)\n    }\n  } else {\n    console.log(`Ignoring ${path} as it doesn't exist`)\n  }\n})\n\nfiles.forEach((file) => {\n  console.log(`Enforcing Strings: ${file}`)\n  const formatter = new Formatter(file)\n  formatter.format()\n})\n"
  },
  {
    "path": "yaml/formatter.mjs",
    "content": "import fs from 'fs'\nimport YAML, { parseDocument } from 'yaml'\n\nexport class Formatter {\n  constructor (path) {\n    this.path = path\n  }\n\n  format () {\n    const file = fs.readFileSync(this.path, 'utf8')\n    const document = parseDocument(file)\n\n    const options = {\n      indent: 2,\n      lineWidth: 180,\n      simpleKeys: true,\n      singleQuote: false,\n      collectionStyle: 'block',\n      blockQuote: 'literal',\n      defaultStringType: 'QUOTE_DOUBLE',\n      directives: true,\n      doubleQuotedMinMultiLineLength: 80\n    }\n\n    YAML.visit(document, {\n      Pair (_, pair) {\n        const { key, value } = pair\n\n        const isValueString = typeof value.value === 'string'\n        const isValuePlain = value.type === 'PLAIN'\n        const isDescription = key.value === 'description'\n\n        if (isValueString && isValuePlain) {\n          pair.value.type = 'QUOTE_DOUBLE'\n        }\n\n        if (isDescription && isValueString) {\n          pair.value.type = 'BLOCK_LITERAL'\n        }\n      }\n    })\n\n    if (document.errors.length > 0) {\n      console.log(document.errors)\n    }\n\n    fs.writeFileSync(this.path, document.toString(options))\n  }\n}\n"
  }
]